diff -druN linux-2.6.39-libre/arch/alpha/include/asm/gpio.h linux-3.0-rc7-libre/arch/alpha/include/asm/gpio.h
--- linux-2.6.39-libre/arch/alpha/include/asm/gpio.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/alpha/include/asm/gpio.h	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,55 @@
+/*
+ * Generic GPIO API implementation for Alpha.
+ *
+ * A stright copy of that for PowerPC which was:
+ *
+ * Copyright (c) 2007-2008  MontaVista Software, Inc.
+ *
+ * Author: Anton Vorontsov <avorontsov@ru.mvista.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#ifndef _ASM_ALPHA_GPIO_H
+#define _ASM_ALPHA_GPIO_H
+
+#include <linux/errno.h>
+#include <asm-generic/gpio.h>
+
+#ifdef CONFIG_GPIOLIB
+
+/*
+ * We don't (yet) implement inlined/rapid versions for on-chip gpios.
+ * Just call gpiolib.
+ */
+static inline int gpio_get_value(unsigned int gpio)
+{
+	return __gpio_get_value(gpio);
+}
+
+static inline void gpio_set_value(unsigned int gpio, int value)
+{
+	__gpio_set_value(gpio, value);
+}
+
+static inline int gpio_cansleep(unsigned int gpio)
+{
+	return __gpio_cansleep(gpio);
+}
+
+static inline int gpio_to_irq(unsigned int gpio)
+{
+	return __gpio_to_irq(gpio);
+}
+
+static inline int irq_to_gpio(unsigned int irq)
+{
+	return -EINVAL;
+}
+
+#endif /* CONFIG_GPIOLIB */
+
+#endif /* _ASM_ALPHA_GPIO_H */
diff -druN linux-2.6.39-libre/arch/alpha/include/asm/mmzone.h linux-3.0-rc7-libre/arch/alpha/include/asm/mmzone.h
--- linux-2.6.39-libre/arch/alpha/include/asm/mmzone.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/alpha/include/asm/mmzone.h	2011-07-11 19:51:52.000000000 -0400
@@ -56,7 +56,6 @@
  * Given a kernel address, find the home node of the underlying memory.
  */
 #define kvaddr_to_nid(kaddr)	pa_to_nid(__pa(kaddr))
-#define node_start_pfn(nid)	(NODE_DATA(nid)->node_start_pfn)
 
 /*
  * Given a kaddr, LOCAL_BASE_ADDR finds the owning node of the memory
diff -druN linux-2.6.39-libre/arch/alpha/include/asm/smp.h linux-3.0-rc7-libre/arch/alpha/include/asm/smp.h
--- linux-2.6.39-libre/arch/alpha/include/asm/smp.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/alpha/include/asm/smp.h	2011-07-11 19:51:52.000000000 -0400
@@ -39,8 +39,6 @@
 
 extern struct cpuinfo_alpha cpu_data[NR_CPUS];
 
-#define PROC_CHANGE_PENALTY     20
-
 #define hard_smp_processor_id()	__hard_smp_processor_id()
 #define raw_smp_processor_id()	(current_thread_info()->cpu)
 
diff -druN linux-2.6.39-libre/arch/alpha/include/asm/unistd.h linux-3.0-rc7-libre/arch/alpha/include/asm/unistd.h
--- linux-2.6.39-libre/arch/alpha/include/asm/unistd.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/alpha/include/asm/unistd.h	2011-07-11 19:51:52.000000000 -0400
@@ -456,10 +456,11 @@
 #define __NR_open_by_handle_at		498
 #define __NR_clock_adjtime		499
 #define __NR_syncfs			500
+#define __NR_setns			501
 
 #ifdef __KERNEL__
 
-#define NR_SYSCALLS			501
+#define NR_SYSCALLS			502
 
 #define __ARCH_WANT_IPC_PARSE_VERSION
 #define __ARCH_WANT_OLD_READDIR
diff -druN linux-2.6.39-libre/arch/alpha/Kconfig linux-3.0-rc7-libre/arch/alpha/Kconfig
--- linux-2.6.39-libre/arch/alpha/Kconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/alpha/Kconfig	2011-07-11 19:51:52.000000000 -0400
@@ -12,6 +12,7 @@
 	select GENERIC_IRQ_PROBE
 	select AUTO_IRQ_AFFINITY if SMP
 	select GENERIC_IRQ_SHOW
+	select ARCH_WANT_OPTIONAL_GPIOLIB
 	help
 	  The Alpha is a 64-bit general-purpose processor designed and
 	  marketed by the Digital Equipment Corporation of blessed memory,
@@ -40,10 +41,6 @@
 	bool
 	default n
 
-config GENERIC_FIND_NEXT_BIT
-	bool
-	default y
-
 config GENERIC_CALIBRATE_DELAY
 	bool
 	default y
@@ -51,6 +48,9 @@
 config GENERIC_CMOS_UPDATE
         def_bool y
 
+config GENERIC_GPIO
+	def_bool y
+
 config ZONE_DMA
 	bool
 	default y
diff -druN linux-2.6.39-libre/arch/alpha/kernel/osf_sys.c linux-3.0-rc7-libre/arch/alpha/kernel/osf_sys.c
--- linux-2.6.39-libre/arch/alpha/kernel/osf_sys.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/alpha/kernel/osf_sys.c	2011-07-11 19:51:52.000000000 -0400
@@ -409,7 +409,7 @@
 		return -EFAULT;
 
 	len = namelen;
-	if (namelen > 32)
+	if (len > 32)
 		len = 32;
 
 	down_read(&uts_sem);
@@ -594,7 +594,7 @@
 	down_read(&uts_sem);
 	res = sysinfo_table[offset];
 	len = strlen(res)+1;
-	if (len > count)
+	if ((unsigned long)len > (unsigned long)count)
 		len = count;
 	if (copy_to_user(buf, res, len))
 		err = -EFAULT;
@@ -649,7 +649,7 @@
 		return 1;
 
 	case GSI_GET_HWRPB:
-		if (nbytes < sizeof(*hwrpb))
+		if (nbytes > sizeof(*hwrpb))
 			return -EINVAL;
 		if (copy_to_user(buffer, hwrpb, nbytes) != 0)
 			return -EFAULT;
@@ -1008,6 +1008,7 @@
 {
 	struct rusage r;
 	long ret, err;
+	unsigned int status = 0;
 	mm_segment_t old_fs;
 
 	if (!ur)
@@ -1016,13 +1017,15 @@
 	old_fs = get_fs();
 		
 	set_fs (KERNEL_DS);
-	ret = sys_wait4(pid, ustatus, options, (struct rusage __user *) &r);
+	ret = sys_wait4(pid, (unsigned int __user *) &status, options,
+			(struct rusage __user *) &r);
 	set_fs (old_fs);
 
 	if (!access_ok(VERIFY_WRITE, ur, sizeof(*ur)))
 		return -EFAULT;
 
 	err = 0;
+	err |= put_user(status, ustatus);
 	err |= __put_user(r.ru_utime.tv_sec, &ur->ru_utime.tv_sec);
 	err |= __put_user(r.ru_utime.tv_usec, &ur->ru_utime.tv_usec);
 	err |= __put_user(r.ru_stime.tv_sec, &ur->ru_stime.tv_sec);
diff -druN linux-2.6.39-libre/arch/alpha/kernel/process.c linux-3.0-rc7-libre/arch/alpha/kernel/process.c
--- linux-2.6.39-libre/arch/alpha/kernel/process.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/alpha/kernel/process.c	2011-07-11 19:51:52.000000000 -0400
@@ -121,7 +121,7 @@
 	/* Wait for the secondaries to halt. */
 	set_cpu_present(boot_cpuid, false);
 	set_cpu_possible(boot_cpuid, false);
-	while (cpus_weight(cpu_present_map))
+	while (cpumask_weight(cpu_present_mask))
 		barrier();
 #endif
 
diff -druN linux-2.6.39-libre/arch/alpha/kernel/setup.c linux-3.0-rc7-libre/arch/alpha/kernel/setup.c
--- linux-2.6.39-libre/arch/alpha/kernel/setup.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/alpha/kernel/setup.c	2011-07-11 19:51:52.000000000 -0400
@@ -1257,7 +1257,7 @@
 #ifdef CONFIG_SMP
 	seq_printf(f, "cpus active\t\t: %u\n"
 		      "cpu active mask\t\t: %016lx\n",
-		       num_online_cpus(), cpus_addr(cpu_possible_map)[0]);
+		       num_online_cpus(), cpumask_bits(cpu_possible_mask)[0]);
 #endif
 
 	show_cache_size (f, "L1 Icache", alpha_l1i_cacheshape);
diff -druN linux-2.6.39-libre/arch/alpha/kernel/smp.c linux-3.0-rc7-libre/arch/alpha/kernel/smp.c
--- linux-2.6.39-libre/arch/alpha/kernel/smp.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/alpha/kernel/smp.c	2011-07-11 19:51:52.000000000 -0400
@@ -451,7 +451,7 @@
 	}
 
 	printk(KERN_INFO "SMP: %d CPUs probed -- cpu_present_map = %lx\n",
-	       smp_num_probed, cpu_present_map.bits[0]);
+	       smp_num_probed, cpumask_bits(cpu_present_mask)[0]);
 }
 
 /*
@@ -585,8 +585,7 @@
 
 		switch (which) {
 		case IPI_RESCHEDULE:
-			/* Reschedule callback.  Everything to be done
-			   is done by the interrupt return path.  */
+			scheduler_ipi();
 			break;
 
 		case IPI_CALL_FUNC:
@@ -630,8 +629,9 @@
 void
 smp_send_stop(void)
 {
-	cpumask_t to_whom = cpu_possible_map;
-	cpu_clear(smp_processor_id(), to_whom);
+	cpumask_t to_whom;
+	cpumask_copy(&to_whom, cpu_possible_mask);
+	cpumask_clear_cpu(smp_processor_id(), &to_whom);
 #ifdef DEBUG_IPI_MSG
 	if (hard_smp_processor_id() != boot_cpu_id)
 		printk(KERN_WARNING "smp_send_stop: Not on boot cpu.\n");
diff -druN linux-2.6.39-libre/arch/alpha/kernel/sys_dp264.c linux-3.0-rc7-libre/arch/alpha/kernel/sys_dp264.c
--- linux-2.6.39-libre/arch/alpha/kernel/sys_dp264.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/alpha/kernel/sys_dp264.c	2011-07-11 19:51:52.000000000 -0400
@@ -140,7 +140,7 @@
 
 	for (cpu = 0; cpu < 4; cpu++) {
 		unsigned long aff = cpu_irq_affinity[cpu];
-		if (cpu_isset(cpu, affinity))
+		if (cpumask_test_cpu(cpu, &affinity))
 			aff |= 1UL << irq;
 		else
 			aff &= ~(1UL << irq);
diff -druN linux-2.6.39-libre/arch/alpha/kernel/systbls.S linux-3.0-rc7-libre/arch/alpha/kernel/systbls.S
--- linux-2.6.39-libre/arch/alpha/kernel/systbls.S	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/alpha/kernel/systbls.S	2011-07-11 19:51:52.000000000 -0400
@@ -519,6 +519,7 @@
 	.quad sys_open_by_handle_at
 	.quad sys_clock_adjtime
 	.quad sys_syncfs			/* 500 */
+	.quad sys_setns
 
 	.size sys_call_table, . - sys_call_table
 	.type sys_call_table, @object
diff -druN linux-2.6.39-libre/arch/alpha/kernel/sys_titan.c linux-3.0-rc7-libre/arch/alpha/kernel/sys_titan.c
--- linux-2.6.39-libre/arch/alpha/kernel/sys_titan.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/alpha/kernel/sys_titan.c	2011-07-11 19:51:52.000000000 -0400
@@ -65,10 +65,11 @@
 	register int bcpu = boot_cpuid;
 
 #ifdef CONFIG_SMP
-	cpumask_t cpm = cpu_present_map;
+	cpumask_t cpm;
 	volatile unsigned long *dim0, *dim1, *dim2, *dim3;
 	unsigned long mask0, mask1, mask2, mask3, dummy;
 
+	cpumask_copy(&cpm, cpu_present_mask);
 	mask &= ~isa_enable;
 	mask0 = mask & titan_cpu_irq_affinity[0];
 	mask1 = mask & titan_cpu_irq_affinity[1];
@@ -84,10 +85,10 @@
 	dim1 = &cchip->dim1.csr;
 	dim2 = &cchip->dim2.csr;
 	dim3 = &cchip->dim3.csr;
-	if (!cpu_isset(0, cpm)) dim0 = &dummy;
-	if (!cpu_isset(1, cpm)) dim1 = &dummy;
-	if (!cpu_isset(2, cpm)) dim2 = &dummy;
-	if (!cpu_isset(3, cpm)) dim3 = &dummy;
+	if (!cpumask_test_cpu(0, &cpm)) dim0 = &dummy;
+	if (!cpumask_test_cpu(1, &cpm)) dim1 = &dummy;
+	if (!cpumask_test_cpu(2, &cpm)) dim2 = &dummy;
+	if (!cpumask_test_cpu(3, &cpm)) dim3 = &dummy;
 
 	*dim0 = mask0;
 	*dim1 = mask1;
@@ -137,7 +138,7 @@
 	int cpu;
 
 	for (cpu = 0; cpu < 4; cpu++) {
-		if (cpu_isset(cpu, affinity))
+		if (cpumask_test_cpu(cpu, &affinity))
 			titan_cpu_irq_affinity[cpu] |= 1UL << irq;
 		else
 			titan_cpu_irq_affinity[cpu] &= ~(1UL << irq);
diff -druN linux-2.6.39-libre/arch/alpha/kernel/vmlinux.lds.S linux-3.0-rc7-libre/arch/alpha/kernel/vmlinux.lds.S
--- linux-2.6.39-libre/arch/alpha/kernel/vmlinux.lds.S	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/alpha/kernel/vmlinux.lds.S	2011-07-11 19:51:52.000000000 -0400
@@ -39,13 +39,14 @@
 	__init_begin = ALIGN(PAGE_SIZE);
 	INIT_TEXT_SECTION(PAGE_SIZE)
 	INIT_DATA_SECTION(16)
-	PERCPU(L1_CACHE_BYTES, PAGE_SIZE)
+	PERCPU_SECTION(L1_CACHE_BYTES)
 	/* Align to THREAD_SIZE rather than PAGE_SIZE here so any padding page
 	   needed for the THREAD_SIZE aligned init_task gets freed after init */
 	. = ALIGN(THREAD_SIZE);
 	__init_end = .;
 	/* Freed after init ends here */
 
+	_sdata = .;	/* Start of rw data section */
 	_data = .;
 	RW_DATA_SECTION(L1_CACHE_BYTES, PAGE_SIZE, THREAD_SIZE)
 
diff -druN linux-2.6.39-libre/arch/alpha/mm/init.c linux-3.0-rc7-libre/arch/alpha/mm/init.c
--- linux-2.6.39-libre/arch/alpha/mm/init.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/alpha/mm/init.c	2011-07-11 19:51:52.000000000 -0400
@@ -32,8 +32,6 @@
 #include <asm/console.h>
 #include <asm/tlb.h>
 
-DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
-
 extern void die_if_kernel(char *,struct pt_regs *,long);
 
 static struct pcb_struct original_pcb;
diff -druN linux-2.6.39-libre/arch/alpha/mm/numa.c linux-3.0-rc7-libre/arch/alpha/mm/numa.c
--- linux-2.6.39-libre/arch/alpha/mm/numa.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/alpha/mm/numa.c	2011-07-11 19:51:52.000000000 -0400
@@ -313,6 +313,7 @@
 			zones_size[ZONE_DMA] = dma_local_pfn;
 			zones_size[ZONE_NORMAL] = (end_pfn - start_pfn) - dma_local_pfn;
 		}
+		node_set_state(nid, N_NORMAL_MEMORY);
 		free_area_init_node(nid, zones_size, start_pfn, NULL);
 	}
 
diff -druN linux-2.6.39-libre/arch/arm/boot/compressed/decompress.c linux-3.0-rc7-libre/arch/arm/boot/compressed/decompress.c
--- linux-2.6.39-libre/arch/arm/boot/compressed/decompress.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/boot/compressed/decompress.c	2011-07-11 19:51:52.000000000 -0400
@@ -44,7 +44,7 @@
 #include "../../../../lib/decompress_unlzma.c"
 #endif
 
-void do_decompress(u8 *input, int len, u8 *output, void (*error)(char *x))
+int do_decompress(u8 *input, int len, u8 *output, void (*error)(char *x))
 {
-	decompress(input, len, NULL, NULL, output, NULL, error);
+	return decompress(input, len, NULL, NULL, output, NULL, error);
 }
diff -druN linux-2.6.39-libre/arch/arm/boot/compressed/head.S linux-3.0-rc7-libre/arch/arm/boot/compressed/head.S
--- linux-2.6.39-libre/arch/arm/boot/compressed/head.S	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/boot/compressed/head.S	2011-07-11 19:51:52.000000000 -0400
@@ -179,7 +179,7 @@
 		bl	cache_on
 
 restart:	adr	r0, LC0
-		ldmia	r0, {r1, r2, r3, r6, r9, r11, r12}
+		ldmia	r0, {r1, r2, r3, r6, r10, r11, r12}
 		ldr	sp, [r0, #28]
 
 		/*
@@ -188,6 +188,20 @@
 		 */
 		sub	r0, r0, r1		@ calculate the delta offset
 		add	r6, r6, r0		@ _edata
+		add	r10, r10, r0		@ inflated kernel size location
+
+		/*
+		 * The kernel build system appends the size of the
+		 * decompressed kernel at the end of the compressed data
+		 * in little-endian form.
+		 */
+		ldrb	r9, [r10, #0]
+		ldrb	lr, [r10, #1]
+		orr	r9, r9, lr, lsl #8
+		ldrb	lr, [r10, #2]
+		ldrb	r10, [r10, #3]
+		orr	r9, r9, lr, lsl #16
+		orr	r9, r9, r10, lsl #24
 
 #ifndef CONFIG_ZBOOT_ROM
 		/* malloc space is above the relocated stack (64k max) */
@@ -347,10 +361,10 @@
 		.word	__bss_start		@ r2
 		.word	_end			@ r3
 		.word	_edata			@ r6
-		.word	_image_size		@ r9
+		.word	input_data_end - 4	@ r10 (inflated size location)
 		.word	_got_start		@ r11
 		.word	_got_end		@ ip
-		.word	user_stack_end		@ sp
+		.word	.L_user_stack_end	@ sp
 		.size	LC0, . - LC0
 
 #ifdef CONFIG_ARCH_RPC
@@ -459,7 +473,11 @@
 		orr	r1, r1, #3 << 10
 		add	r2, r3, #16384
 1:		cmp	r1, r9			@ if virt > start of RAM
+#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
+		orrhs	r1, r1, #0x08		@ set cacheable
+#else
 		orrhs	r1, r1, #0x0c		@ set cacheable, bufferable
+#endif
 		cmp	r1, r10			@ if virt > end of RAM
 		bichs	r1, r1, #0x0c		@ clear cacheable, bufferable
 		str	r1, [r0], #4		@ 1:1 mapping
@@ -484,6 +502,12 @@
 		mov	pc, lr
 ENDPROC(__setup_mmu)
 
+__arm926ejs_mmu_cache_on:
+#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
+		mov	r0, #4			@ put dcache in WT mode
+		mcr	p15, 7, r0, c15, c0, 0
+#endif
+
 __armv4_mmu_cache_on:
 		mov	r12, lr
 #ifdef CONFIG_MMU
@@ -573,6 +597,8 @@
 		sub	pc, lr, r0, lsr #32	@ properly flush pipeline
 #endif
 
+#define PROC_ENTRY_SIZE (4*5)
+
 /*
  * Here follow the relocatable cache support functions for the
  * various processors.  This is a generic hook for locating an
@@ -600,7 +626,7 @@
  ARM(		addeq	pc, r12, r3		) @ call cache function
  THUMB(		addeq	r12, r3			)
  THUMB(		moveq	pc, r12			) @ call cache function
-		add	r12, r12, #4*5
+		add	r12, r12, #PROC_ENTRY_SIZE
 		b	1b
 
 /*
@@ -665,6 +691,12 @@
 		W(b)	__armv4_mpu_cache_off
 		W(b)	__armv4_mpu_cache_flush
 
+		.word	0x41069260		@ ARM926EJ-S (v5TEJ)
+		.word	0xff0ffff0
+		W(b)	__arm926ejs_mmu_cache_on
+		W(b)	__armv4_mmu_cache_off
+		W(b)	__armv5tej_mmu_cache_flush
+
 		.word	0x00007000		@ ARM7 IDs
 		.word	0x0000f000
 		mov	pc, lr
@@ -747,12 +779,6 @@
 		W(b)	__armv4_mmu_cache_off
 		W(b)	__armv6_mmu_cache_flush
 
-		.word	0x560f5810		@ Marvell PJ4 ARMv6
-		.word	0xff0ffff0
-		W(b)	__armv4_mmu_cache_on
-		W(b)	__armv4_mmu_cache_off
-		W(b)	__armv6_mmu_cache_flush
-
 		.word	0x000f0000		@ new CPU Id
 		.word	0x000f0000
 		W(b)	__armv7_mmu_cache_on
@@ -770,6 +796,16 @@
 
 		.size	proc_types, . - proc_types
 
+		/*
+		 * If you get a "non-constant expression in ".if" statement"
+		 * error from the assembler on this line, check that you have
+		 * not accidentally written a "b" instruction where you should
+		 * have written W(b).
+		 */
+		.if (. - proc_types) % PROC_ENTRY_SIZE != 0
+		.error "The size of one or more proc_types entries is wrong."
+		.endif
+
 /*
  * Turn off the Cache and MMU.  ARMv3 does not support
  * reading the control register, but ARMv4 does.
@@ -1078,5 +1114,5 @@
 
 		.align
 		.section ".stack", "aw", %nobits
-user_stack:	.space	4096
-user_stack_end:
+.L_user_stack:	.space	4096
+.L_user_stack_end:
diff -druN linux-2.6.39-libre/arch/arm/boot/compressed/Makefile linux-3.0-rc7-libre/arch/arm/boot/compressed/Makefile
--- linux-2.6.39-libre/arch/arm/boot/compressed/Makefile	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/boot/compressed/Makefile	2011-07-11 19:51:52.000000000 -0400
@@ -98,8 +98,6 @@
 ccflags-y := -fpic -fno-builtin
 asflags-y := -Wa,-march=all
 
-# Provide size of uncompressed kernel to the decompressor via a linker symbol.
-LDFLAGS_vmlinux = --defsym _image_size=$(shell stat -c "%s" $(obj)/../Image)
 # Supply ZRELADDR to the decompressor via a linker symbol.
 ifneq ($(CONFIG_AUTO_ZRELADDR),y)
 LDFLAGS_vmlinux += --defsym zreladdr=$(ZRELADDR)
@@ -122,10 +120,23 @@
 $(obj)/lib1funcs.S: $(srctree)/arch/$(SRCARCH)/lib/lib1funcs.S FORCE
 	$(call cmd,shipped)
 
+# We need to prevent any GOTOFF relocs being used with references
+# to symbols in the .bss section since we cannot relocate them
+# independently from the rest at run time.  This can be achieved by
+# ensuring that no private .bss symbols exist, as global symbols
+# always have a GOT entry which is what we need.
+# The .data section is already discarded by the linker script so no need
+# to bother about it here.
+check_for_bad_syms = \
+bad_syms=$$($(CROSS_COMPILE)nm $@ | sed -n 's/^.\{8\} [bc] \(.*\)/\1/p') && \
+[ -z "$$bad_syms" ] || \
+  ( echo "following symbols must have non local/private scope:" >&2; \
+    echo "$$bad_syms" >&2; rm -f $@; false )
+
 $(obj)/vmlinux: $(obj)/vmlinux.lds $(obj)/$(HEAD) $(obj)/piggy.$(suffix_y).o \
 	 	$(addprefix $(obj)/, $(OBJS)) $(lib1funcs) FORCE
 	$(call if_changed,ld)
-	@:
+	@$(check_for_bad_syms)
 
 $(obj)/piggy.$(suffix_y): $(obj)/../Image FORCE
 	$(call if_changed,$(suffix_y))
diff -druN linux-2.6.39-libre/arch/arm/boot/compressed/misc.c linux-3.0-rc7-libre/arch/arm/boot/compressed/misc.c
--- linux-2.6.39-libre/arch/arm/boot/compressed/misc.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/boot/compressed/misc.c	2011-07-11 19:51:52.000000000 -0400
@@ -26,8 +26,6 @@
 #include <linux/linkage.h>
 #include <asm/string.h>
 
-#include <asm/unaligned.h>
-
 
 static void putstr(const char *ptr);
 extern void error(char *x);
@@ -139,13 +137,12 @@
 }
 
 /*
- * gzip delarations
+ * gzip declarations
  */
 extern char input_data[];
 extern char input_data_end[];
 
 unsigned char *output_data;
-unsigned long output_ptr;
 
 unsigned long free_mem_ptr;
 unsigned long free_mem_end_ptr;
@@ -170,15 +167,15 @@
 	error("Attempting division by 0!");
 }
 
-extern void do_decompress(u8 *input, int len, u8 *output, void (*error)(char *x));
+extern int do_decompress(u8 *input, int len, u8 *output, void (*error)(char *x));
 
 
-unsigned long
+void
 decompress_kernel(unsigned long output_start, unsigned long free_mem_ptr_p,
 		unsigned long free_mem_ptr_end_p,
 		int arch_id)
 {
-	unsigned char *tmp;
+	int ret;
 
 	output_data		= (unsigned char *)output_start;
 	free_mem_ptr		= free_mem_ptr_p;
@@ -187,12 +184,11 @@
 
 	arch_decomp_setup();
 
-	tmp = (unsigned char *) (((unsigned long)input_data_end) - 4);
-	output_ptr = get_unaligned_le32(tmp);
-
 	putstr("Uncompressing Linux...");
-	do_decompress(input_data, input_data_end - input_data,
-			output_data, error);
-	putstr(" done, booting the kernel.\n");
-	return output_ptr;
+	ret = do_decompress(input_data, input_data_end - input_data,
+			    output_data, error);
+	if (ret)
+		error("decompressor returned an error");
+	else
+		putstr(" done, booting the kernel.\n");
 }
diff -druN linux-2.6.39-libre/arch/arm/common/dmabounce.c linux-3.0-rc7-libre/arch/arm/common/dmabounce.c
--- linux-2.6.39-libre/arch/arm/common/dmabounce.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/common/dmabounce.c	2011-07-11 19:51:52.000000000 -0400
@@ -255,7 +255,7 @@
 		if (buf == 0) {
 			dev_err(dev, "%s: unable to map unsafe buffer %p!\n",
 			       __func__, ptr);
-			return 0;
+			return ~0;
 		}
 
 		dev_dbg(dev,
diff -druN linux-2.6.39-libre/arch/arm/common/gic.c linux-3.0-rc7-libre/arch/arm/common/gic.c
--- linux-2.6.39-libre/arch/arm/common/gic.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/common/gic.c	2011-07-11 19:51:52.000000000 -0400
@@ -49,7 +49,7 @@
  * Default make them NULL.
  */
 struct irq_chip gic_arch_extn = {
-	.irq_ack	= NULL,
+	.irq_eoi	= NULL,
 	.irq_mask	= NULL,
 	.irq_unmask	= NULL,
 	.irq_retrigger	= NULL,
@@ -84,21 +84,12 @@
 /*
  * Routines to acknowledge, disable and enable interrupts
  */
-static void gic_ack_irq(struct irq_data *d)
-{
-	spin_lock(&irq_controller_lock);
-	if (gic_arch_extn.irq_ack)
-		gic_arch_extn.irq_ack(d);
-	writel(gic_irq(d), gic_cpu_base(d) + GIC_CPU_EOI);
-	spin_unlock(&irq_controller_lock);
-}
-
 static void gic_mask_irq(struct irq_data *d)
 {
 	u32 mask = 1 << (d->irq % 32);
 
 	spin_lock(&irq_controller_lock);
-	writel(mask, gic_dist_base(d) + GIC_DIST_ENABLE_CLEAR + (gic_irq(d) / 32) * 4);
+	writel_relaxed(mask, gic_dist_base(d) + GIC_DIST_ENABLE_CLEAR + (gic_irq(d) / 32) * 4);
 	if (gic_arch_extn.irq_mask)
 		gic_arch_extn.irq_mask(d);
 	spin_unlock(&irq_controller_lock);
@@ -111,10 +102,21 @@
 	spin_lock(&irq_controller_lock);
 	if (gic_arch_extn.irq_unmask)
 		gic_arch_extn.irq_unmask(d);
-	writel(mask, gic_dist_base(d) + GIC_DIST_ENABLE_SET + (gic_irq(d) / 32) * 4);
+	writel_relaxed(mask, gic_dist_base(d) + GIC_DIST_ENABLE_SET + (gic_irq(d) / 32) * 4);
 	spin_unlock(&irq_controller_lock);
 }
 
+static void gic_eoi_irq(struct irq_data *d)
+{
+	if (gic_arch_extn.irq_eoi) {
+		spin_lock(&irq_controller_lock);
+		gic_arch_extn.irq_eoi(d);
+		spin_unlock(&irq_controller_lock);
+	}
+
+	writel_relaxed(gic_irq(d), gic_cpu_base(d) + GIC_CPU_EOI);
+}
+
 static int gic_set_type(struct irq_data *d, unsigned int type)
 {
 	void __iomem *base = gic_dist_base(d);
@@ -138,7 +140,7 @@
 	if (gic_arch_extn.irq_set_type)
 		gic_arch_extn.irq_set_type(d, type);
 
-	val = readl(base + GIC_DIST_CONFIG + confoff);
+	val = readl_relaxed(base + GIC_DIST_CONFIG + confoff);
 	if (type == IRQ_TYPE_LEVEL_HIGH)
 		val &= ~confmask;
 	else if (type == IRQ_TYPE_EDGE_RISING)
@@ -148,15 +150,15 @@
 	 * As recommended by the spec, disable the interrupt before changing
 	 * the configuration
 	 */
-	if (readl(base + GIC_DIST_ENABLE_SET + enableoff) & enablemask) {
-		writel(enablemask, base + GIC_DIST_ENABLE_CLEAR + enableoff);
+	if (readl_relaxed(base + GIC_DIST_ENABLE_SET + enableoff) & enablemask) {
+		writel_relaxed(enablemask, base + GIC_DIST_ENABLE_CLEAR + enableoff);
 		enabled = true;
 	}
 
-	writel(val, base + GIC_DIST_CONFIG + confoff);
+	writel_relaxed(val, base + GIC_DIST_CONFIG + confoff);
 
 	if (enabled)
-		writel(enablemask, base + GIC_DIST_ENABLE_SET + enableoff);
+		writel_relaxed(enablemask, base + GIC_DIST_ENABLE_SET + enableoff);
 
 	spin_unlock(&irq_controller_lock);
 
@@ -188,8 +190,8 @@
 
 	spin_lock(&irq_controller_lock);
 	d->node = cpu;
-	val = readl(reg) & ~mask;
-	writel(val | bit, reg);
+	val = readl_relaxed(reg) & ~mask;
+	writel_relaxed(val | bit, reg);
 	spin_unlock(&irq_controller_lock);
 
 	return 0;
@@ -218,11 +220,10 @@
 	unsigned int cascade_irq, gic_irq;
 	unsigned long status;
 
-	/* primary controller ack'ing */
-	chip->irq_ack(&desc->irq_data);
+	chained_irq_enter(chip, desc);
 
 	spin_lock(&irq_controller_lock);
-	status = readl(chip_data->cpu_base + GIC_CPU_INTACK);
+	status = readl_relaxed(chip_data->cpu_base + GIC_CPU_INTACK);
 	spin_unlock(&irq_controller_lock);
 
 	gic_irq = (status & 0x3ff);
@@ -236,15 +237,14 @@
 		generic_handle_irq(cascade_irq);
 
  out:
-	/* primary controller unmasking */
-	chip->irq_unmask(&desc->irq_data);
+	chained_irq_exit(chip, desc);
 }
 
 static struct irq_chip gic_chip = {
 	.name			= "GIC",
-	.irq_ack		= gic_ack_irq,
 	.irq_mask		= gic_mask_irq,
 	.irq_unmask		= gic_unmask_irq,
+	.irq_eoi		= gic_eoi_irq,
 	.irq_set_type		= gic_set_type,
 	.irq_retrigger		= gic_retrigger,
 #ifdef CONFIG_SMP
@@ -272,13 +272,13 @@
 	cpumask |= cpumask << 8;
 	cpumask |= cpumask << 16;
 
-	writel(0, base + GIC_DIST_CTRL);
+	writel_relaxed(0, base + GIC_DIST_CTRL);
 
 	/*
 	 * Find out how many interrupts are supported.
 	 * The GIC only supports up to 1020 interrupt sources.
 	 */
-	gic_irqs = readl(base + GIC_DIST_CTR) & 0x1f;
+	gic_irqs = readl_relaxed(base + GIC_DIST_CTR) & 0x1f;
 	gic_irqs = (gic_irqs + 1) * 32;
 	if (gic_irqs > 1020)
 		gic_irqs = 1020;
@@ -287,26 +287,26 @@
 	 * Set all global interrupts to be level triggered, active low.
 	 */
 	for (i = 32; i < gic_irqs; i += 16)
-		writel(0, base + GIC_DIST_CONFIG + i * 4 / 16);
+		writel_relaxed(0, base + GIC_DIST_CONFIG + i * 4 / 16);
 
 	/*
 	 * Set all global interrupts to this CPU only.
 	 */
 	for (i = 32; i < gic_irqs; i += 4)
-		writel(cpumask, base + GIC_DIST_TARGET + i * 4 / 4);
+		writel_relaxed(cpumask, base + GIC_DIST_TARGET + i * 4 / 4);
 
 	/*
 	 * Set priority on all global interrupts.
 	 */
 	for (i = 32; i < gic_irqs; i += 4)
-		writel(0xa0a0a0a0, base + GIC_DIST_PRI + i * 4 / 4);
+		writel_relaxed(0xa0a0a0a0, base + GIC_DIST_PRI + i * 4 / 4);
 
 	/*
 	 * Disable all interrupts.  Leave the PPI and SGIs alone
 	 * as these enables are banked registers.
 	 */
 	for (i = 32; i < gic_irqs; i += 32)
-		writel(0xffffffff, base + GIC_DIST_ENABLE_CLEAR + i * 4 / 32);
+		writel_relaxed(0xffffffff, base + GIC_DIST_ENABLE_CLEAR + i * 4 / 32);
 
 	/*
 	 * Limit number of interrupts registered to the platform maximum
@@ -319,12 +319,12 @@
 	 * Setup the Linux IRQ subsystem.
 	 */
 	for (i = irq_start; i < irq_limit; i++) {
-		irq_set_chip_and_handler(i, &gic_chip, handle_level_irq);
+		irq_set_chip_and_handler(i, &gic_chip, handle_fasteoi_irq);
 		irq_set_chip_data(i, gic);
 		set_irq_flags(i, IRQF_VALID | IRQF_PROBE);
 	}
 
-	writel(1, base + GIC_DIST_CTRL);
+	writel_relaxed(1, base + GIC_DIST_CTRL);
 }
 
 static void __cpuinit gic_cpu_init(struct gic_chip_data *gic)
@@ -337,17 +337,17 @@
 	 * Deal with the banked PPI and SGI interrupts - disable all
 	 * PPI interrupts, ensure all SGI interrupts are enabled.
 	 */
-	writel(0xffff0000, dist_base + GIC_DIST_ENABLE_CLEAR);
-	writel(0x0000ffff, dist_base + GIC_DIST_ENABLE_SET);
+	writel_relaxed(0xffff0000, dist_base + GIC_DIST_ENABLE_CLEAR);
+	writel_relaxed(0x0000ffff, dist_base + GIC_DIST_ENABLE_SET);
 
 	/*
 	 * Set priority on PPI and SGI interrupts
 	 */
 	for (i = 0; i < 32; i += 4)
-		writel(0xa0a0a0a0, dist_base + GIC_DIST_PRI + i * 4 / 4);
+		writel_relaxed(0xa0a0a0a0, dist_base + GIC_DIST_PRI + i * 4 / 4);
 
-	writel(0xf0, base + GIC_CPU_PRIMASK);
-	writel(1, base + GIC_CPU_CTRL);
+	writel_relaxed(0xf0, base + GIC_CPU_PRIMASK);
+	writel_relaxed(1, base + GIC_CPU_CTRL);
 }
 
 void __init gic_init(unsigned int gic_nr, unsigned int irq_start,
@@ -391,7 +391,13 @@
 {
 	unsigned long map = *cpus_addr(*mask);
 
+	/*
+	 * Ensure that stores to Normal memory are visible to the
+	 * other CPUs before issuing the IPI.
+	 */
+	dsb();
+
 	/* this always happens on GIC0 */
-	writel(map << 16 | irq, gic_data[0].dist_base + GIC_DIST_SOFTINT);
+	writel_relaxed(map << 16 | irq, gic_data[0].dist_base + GIC_DIST_SOFTINT);
 }
 #endif
diff -druN linux-2.6.39-libre/arch/arm/common/Kconfig linux-3.0-rc7-libre/arch/arm/common/Kconfig
--- linux-2.6.39-libre/arch/arm/common/Kconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/common/Kconfig	2011-07-11 19:51:52.000000000 -0400
@@ -7,7 +7,7 @@
 config ARM_VIC_NR
 	int
 	default 4 if ARCH_S5PV210
-	default 3 if ARCH_S5P6442 || ARCH_S5PC100
+	default 3 if ARCH_S5PC100
 	default 2
 	depends on ARM_VIC
 	help
diff -druN linux-2.6.39-libre/arch/arm/common/sa1111.c linux-3.0-rc7-libre/arch/arm/common/sa1111.c
--- linux-2.6.39-libre/arch/arm/common/sa1111.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/common/sa1111.c	2011-07-11 19:51:52.000000000 -0400
@@ -185,14 +185,6 @@
 	},
 };
 
-void __init sa1111_adjust_zones(unsigned long *size, unsigned long *holes)
-{
-	unsigned int sz = SZ_1M >> PAGE_SHIFT;
-
-	size[1] = size[0] - sz;
-	size[0] = sz;
-}
-
 /*
  * SA1111 interrupt support.  Since clearing an IRQ while there are
  * active IRQs causes the interrupt output to pulse, the upper levels
diff -druN linux-2.6.39-libre/arch/arm/common/timer-sp.c linux-3.0-rc7-libre/arch/arm/common/timer-sp.c
--- linux-2.6.39-libre/arch/arm/common/timer-sp.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/common/timer-sp.c	2011-07-11 19:51:52.000000000 -0400
@@ -18,53 +18,67 @@
  * 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/clk.h>
 #include <linux/clocksource.h>
 #include <linux/clockchips.h>
+#include <linux/err.h>
 #include <linux/interrupt.h>
 #include <linux/irq.h>
 #include <linux/io.h>
 
 #include <asm/hardware/arm_timer.h>
 
-/*
- * These timers are currently always setup to be clocked at 1MHz.
- */
-#define TIMER_FREQ_KHZ	(1000)
-#define TIMER_RELOAD	(TIMER_FREQ_KHZ * 1000 / HZ)
+static long __init sp804_get_clock_rate(const char *name)
+{
+	struct clk *clk;
+	long rate;
+	int err;
 
-static void __iomem *clksrc_base;
+	clk = clk_get_sys("sp804", name);
+	if (IS_ERR(clk)) {
+		pr_err("sp804: %s clock not found: %d\n", name,
+			(int)PTR_ERR(clk));
+		return PTR_ERR(clk);
+	}
 
-static cycle_t sp804_read(struct clocksource *cs)
-{
-	return ~readl(clksrc_base + TIMER_VALUE);
-}
+	err = clk_enable(clk);
+	if (err) {
+		pr_err("sp804: %s clock failed to enable: %d\n", name, err);
+		clk_put(clk);
+		return err;
+	}
 
-static struct clocksource clocksource_sp804 = {
-	.name		= "timer3",
-	.rating		= 200,
-	.read		= sp804_read,
-	.mask		= CLOCKSOURCE_MASK(32),
-	.flags		= CLOCK_SOURCE_IS_CONTINUOUS,
-};
+	rate = clk_get_rate(clk);
+	if (rate < 0) {
+		pr_err("sp804: %s clock failed to get rate: %ld\n", name, rate);
+		clk_disable(clk);
+		clk_put(clk);
+	}
 
-void __init sp804_clocksource_init(void __iomem *base)
+	return rate;
+}
+
+void __init sp804_clocksource_init(void __iomem *base, const char *name)
 {
-	struct clocksource *cs = &clocksource_sp804;
+	long rate = sp804_get_clock_rate(name);
 
-	clksrc_base = base;
+	if (rate < 0)
+		return;
 
 	/* setup timer 0 as free-running clocksource */
-	writel(0, clksrc_base + TIMER_CTRL);
-	writel(0xffffffff, clksrc_base + TIMER_LOAD);
-	writel(0xffffffff, clksrc_base + TIMER_VALUE);
+	writel(0, base + TIMER_CTRL);
+	writel(0xffffffff, base + TIMER_LOAD);
+	writel(0xffffffff, base + TIMER_VALUE);
 	writel(TIMER_CTRL_32BIT | TIMER_CTRL_ENABLE | TIMER_CTRL_PERIODIC,
-		clksrc_base + TIMER_CTRL);
+		base + TIMER_CTRL);
 
-	clocksource_register_khz(cs, TIMER_FREQ_KHZ);
+	clocksource_mmio_init(base + TIMER_VALUE, name,
+		rate, 200, 32, clocksource_mmio_readl_down);
 }
 
 
 static void __iomem *clkevt_base;
+static unsigned long clkevt_reload;
 
 /*
  * IRQ handler for the timer
@@ -90,7 +104,7 @@
 
 	switch (mode) {
 	case CLOCK_EVT_MODE_PERIODIC:
-		writel(TIMER_RELOAD, clkevt_base + TIMER_LOAD);
+		writel(clkevt_reload, clkevt_base + TIMER_LOAD);
 		ctrl |= TIMER_CTRL_PERIODIC | TIMER_CTRL_ENABLE;
 		break;
 
@@ -120,7 +134,6 @@
 }
 
 static struct clock_event_device sp804_clockevent = {
-	.name		= "timer0",
 	.shift		= 32,
 	.features       = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
 	.set_mode	= sp804_set_mode,
@@ -136,17 +149,24 @@
 	.dev_id		= &sp804_clockevent,
 };
 
-void __init sp804_clockevents_init(void __iomem *base, unsigned int timer_irq)
+void __init sp804_clockevents_init(void __iomem *base, unsigned int irq,
+	const char *name)
 {
 	struct clock_event_device *evt = &sp804_clockevent;
+	long rate = sp804_get_clock_rate(name);
+
+	if (rate < 0)
+		return;
 
 	clkevt_base = base;
+	clkevt_reload = DIV_ROUND_CLOSEST(rate, HZ);
 
-	evt->irq = timer_irq;
-	evt->mult = div_sc(TIMER_FREQ_KHZ, NSEC_PER_MSEC, evt->shift);
+	evt->name = name;
+	evt->irq = irq;
+	evt->mult = div_sc(rate, NSEC_PER_SEC, evt->shift);
 	evt->max_delta_ns = clockevent_delta2ns(0xffffffff, evt);
 	evt->min_delta_ns = clockevent_delta2ns(0xf, evt);
 
-	setup_irq(timer_irq, &sp804_timer_irq);
+	setup_irq(irq, &sp804_timer_irq);
 	clockevents_register_device(evt);
 }
diff -druN linux-2.6.39-libre/arch/arm/common/vic.c linux-3.0-rc7-libre/arch/arm/common/vic.c
--- linux-2.6.39-libre/arch/arm/common/vic.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/common/vic.c	2011-07-11 19:51:52.000000000 -0400
@@ -22,17 +22,16 @@
 #include <linux/init.h>
 #include <linux/list.h>
 #include <linux/io.h>
-#include <linux/sysdev.h>
+#include <linux/syscore_ops.h>
 #include <linux/device.h>
 #include <linux/amba/bus.h>
 
 #include <asm/mach/irq.h>
 #include <asm/hardware/vic.h>
 
-#if defined(CONFIG_PM)
+#ifdef CONFIG_PM
 /**
  * struct vic_device - VIC PM device
- * @sysdev: The system device which is registered.
  * @irq: The IRQ number for the base of the VIC.
  * @base: The register base for the VIC.
  * @resume_sources: A bitmask of interrupts for resume.
@@ -43,8 +42,6 @@
  * @protect: Save for VIC_PROTECT.
  */
 struct vic_device {
-	struct sys_device sysdev;
-
 	void __iomem	*base;
 	int		irq;
 	u32		resume_sources;
@@ -59,11 +56,6 @@
 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 */
 
 /**
@@ -85,10 +77,9 @@
 	writel(32, base + VIC_PL190_DEF_VECT_ADDR);
 }
 
-#if defined(CONFIG_PM)
-static int vic_class_resume(struct sys_device *dev)
+#ifdef CONFIG_PM
+static void resume_one_vic(struct vic_device *vic)
 {
-	struct vic_device *vic = to_vic(dev);
 	void __iomem *base = vic->base;
 
 	printk(KERN_DEBUG "%s: resuming vic at %p\n", __func__, base);
@@ -107,13 +98,18 @@
 
 	writel(vic->soft_int, base + VIC_INT_SOFT);
 	writel(~vic->soft_int, base + VIC_INT_SOFT_CLEAR);
+}
 
-	return 0;
+static void vic_resume(void)
+{
+	int id;
+
+	for (id = vic_id - 1; id >= 0; id--)
+		resume_one_vic(vic_devices + id);
 }
 
-static int vic_class_suspend(struct sys_device *dev, pm_message_t state)
+static void suspend_one_vic(struct vic_device *vic)
 {
-	struct vic_device *vic = to_vic(dev);
 	void __iomem *base = vic->base;
 
 	printk(KERN_DEBUG "%s: suspending vic at %p\n", __func__, base);
@@ -128,14 +124,21 @@
 
 	writel(vic->resume_irqs, base + VIC_INT_ENABLE);
 	writel(~vic->resume_irqs, base + VIC_INT_ENABLE_CLEAR);
+}
+
+static int vic_suspend(void)
+{
+	int id;
+
+	for (id = 0; id < vic_id; id++)
+		suspend_one_vic(vic_devices + id);
 
 	return 0;
 }
 
-struct sysdev_class vic_class = {
-	.name		= "vic",
-	.suspend	= vic_class_suspend,
-	.resume		= vic_class_resume,
+struct syscore_ops vic_syscore_ops = {
+	.suspend	= vic_suspend,
+	.resume		= vic_resume,
 };
 
 /**
@@ -147,30 +150,8 @@
 */
 static int __init vic_pm_init(void)
 {
-	struct vic_device *dev = vic_devices;
-	int err;
-	int id;
-
-	if (vic_id == 0)
-		return 0;
-
-	err = sysdev_class_register(&vic_class);
-	if (err) {
-		printk(KERN_ERR "%s: cannot register class\n", __func__);
-		return err;
-	}
-
-	for (id = 0; id < vic_id; id++, dev++) {
-		dev->sysdev.id = id;
-		dev->sysdev.cls = &vic_class;
-
-		err = sysdev_register(&dev->sysdev);
-		if (err) {
-			printk(KERN_ERR "%s: failed to register device\n",
-			       __func__);
-			return err;
-		}
-	}
+	if (vic_id > 0)
+		register_syscore_ops(&vic_syscore_ops);
 
 	return 0;
 }
diff -druN linux-2.6.39-libre/arch/arm/configs/at572d940hfek_defconfig linux-3.0-rc7-libre/arch/arm/configs/at572d940hfek_defconfig
--- linux-2.6.39-libre/arch/arm/configs/at572d940hfek_defconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/configs/at572d940hfek_defconfig	1969-12-31 19:00:00.000000000 -0500
@@ -1,358 +0,0 @@
-CONFIG_EXPERIMENTAL=y
-CONFIG_LOCALVERSION="-AT572D940HF"
-# CONFIG_LOCALVERSION_AUTO is not set
-CONFIG_SYSVIPC=y
-CONFIG_POSIX_MQUEUE=y
-CONFIG_BSD_PROCESS_ACCT=y
-CONFIG_BSD_PROCESS_ACCT_V3=y
-CONFIG_TASKSTATS=y
-CONFIG_TASK_XACCT=y
-CONFIG_TASK_IO_ACCOUNTING=y
-CONFIG_AUDIT=y
-CONFIG_CGROUPS=y
-CONFIG_CGROUP_CPUACCT=y
-CONFIG_CGROUP_SCHED=y
-CONFIG_RT_GROUP_SCHED=y
-CONFIG_SYSFS_DEPRECATED_V2=y
-CONFIG_RELAY=y
-CONFIG_BLK_DEV_INITRD=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
-CONFIG_EXPERT=y
-CONFIG_SLAB=y
-CONFIG_PROFILING=y
-CONFIG_OPROFILE=m
-CONFIG_KPROBES=y
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-CONFIG_MODVERSIONS=y
-CONFIG_MODULE_SRCVERSION_ALL=y
-# CONFIG_BLK_DEV_BSG is not set
-CONFIG_ARCH_AT91=y
-CONFIG_ARCH_AT572D940HF=y
-CONFIG_MACH_AT572D940HFEB=y
-CONFIG_AT91_PROGRAMMABLE_CLOCKS=y
-CONFIG_NO_HZ=y
-CONFIG_HIGH_RES_TIMERS=y
-CONFIG_PREEMPT=y
-CONFIG_CMDLINE="mem=48M console=ttyS0 initrd=0x21100000,3145728 root=/dev/ram0 rw ip=172.16.1.181"
-CONFIG_KEXEC=y
-CONFIG_FPE_NWFPE=y
-CONFIG_FPE_NWFPE_XP=y
-CONFIG_NET=y
-CONFIG_PACKET=m
-CONFIG_UNIX=y
-CONFIG_INET=y
-# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
-# CONFIG_INET_XFRM_MODE_TUNNEL is not set
-# CONFIG_INET_XFRM_MODE_BEET is not set
-# CONFIG_INET_LRO is not set
-# CONFIG_INET_DIAG is not set
-# CONFIG_IPV6 is not set
-CONFIG_NET_PKTGEN=m
-CONFIG_NET_TCPPROBE=m
-CONFIG_CAN=m
-CONFIG_CAN_RAW=m
-CONFIG_CAN_BCM=m
-CONFIG_CAN_VCAN=m
-CONFIG_CAN_DEBUG_DEVICES=y
-CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
-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_CHAR=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
-CONFIG_MTD_CFI=m
-CONFIG_MTD_JEDECPROBE=m
-CONFIG_MTD_CFI_INTELEXT=m
-CONFIG_MTD_CFI_AMDSTD=m
-CONFIG_MTD_CFI_STAA=m
-CONFIG_MTD_ROM=m
-CONFIG_MTD_ABSENT=m
-CONFIG_MTD_COMPLEX_MAPPINGS=y
-CONFIG_MTD_PHYSMAP=m
-CONFIG_MTD_PLATRAM=m
-CONFIG_MTD_DATAFLASH=m
-CONFIG_MTD_M25P80=m
-CONFIG_MTD_SLRAM=m
-CONFIG_MTD_PHRAM=m
-CONFIG_MTD_MTDRAM=m
-CONFIG_MTD_BLOCK2MTD=m
-CONFIG_MTD_NAND=m
-CONFIG_MTD_NAND_VERIFY_WRITE=y
-CONFIG_MTD_NAND_DISKONCHIP=m
-CONFIG_MTD_NAND_NANDSIM=m
-CONFIG_MTD_NAND_PLATFORM=m
-CONFIG_MTD_ALAUDA=m
-CONFIG_MTD_UBI=m
-CONFIG_MTD_UBI_GLUEBI=m
-CONFIG_BLK_DEV_LOOP=y
-CONFIG_BLK_DEV_CRYPTOLOOP=m
-CONFIG_BLK_DEV_NBD=m
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_SIZE=65536
-CONFIG_ATMEL_TCLIB=y
-CONFIG_ATMEL_SSC=m
-CONFIG_SENSORS_TSL2550=m
-CONFIG_DS1682=m
-CONFIG_RAID_ATTRS=m
-CONFIG_SCSI=m
-CONFIG_SCSI_TGT=m
-# CONFIG_SCSI_PROC_FS is not set
-CONFIG_BLK_DEV_SD=m
-CONFIG_BLK_DEV_SR=m
-CONFIG_CHR_DEV_SG=m
-CONFIG_CHR_DEV_SCH=m
-CONFIG_SCSI_MULTI_LUN=y
-CONFIG_SCSI_CONSTANTS=y
-CONFIG_SCSI_LOGGING=y
-CONFIG_SCSI_SCAN_ASYNC=y
-CONFIG_SCSI_ISCSI_ATTRS=m
-CONFIG_NETDEVICES=y
-CONFIG_DUMMY=m
-CONFIG_BONDING=m
-CONFIG_MACVLAN=m
-CONFIG_EQUALIZER=m
-CONFIG_TUN=m
-CONFIG_VETH=m
-CONFIG_PHYLIB=y
-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_MDIO_BITBANG=m
-CONFIG_NET_ETHERNET=y
-# CONFIG_NETDEV_1000 is not set
-# CONFIG_NETDEV_10000 is not set
-CONFIG_USB_ZD1201=m
-CONFIG_HOSTAP=m
-CONFIG_HOSTAP_FIRMWARE=y
-CONFIG_HOSTAP_FIRMWARE_NVRAM=y
-CONFIG_USB_CATC=m
-CONFIG_USB_KAWETH=m
-CONFIG_USB_PEGASUS=m
-CONFIG_USB_RTL8150=m
-CONFIG_USB_USBNET=m
-CONFIG_USB_NET_DM9601=m
-CONFIG_USB_NET_GL620A=m
-CONFIG_USB_NET_PLUSB=m
-CONFIG_USB_NET_MCS7830=m
-CONFIG_USB_NET_RNDIS_HOST=m
-CONFIG_USB_ALI_M5632=y
-CONFIG_USB_AN2720=y
-CONFIG_USB_EPSON2888=y
-CONFIG_USB_KC2190=y
-# CONFIG_USB_NET_ZAURUS is not set
-CONFIG_INPUT_MOUSEDEV=m
-CONFIG_INPUT_EVDEV=m
-CONFIG_INPUT_EVBUG=m
-CONFIG_KEYBOARD_LKKBD=m
-CONFIG_KEYBOARD_GPIO=m
-CONFIG_KEYBOARD_NEWTON=m
-CONFIG_KEYBOARD_STOWAWAY=m
-CONFIG_KEYBOARD_SUNKBD=m
-CONFIG_KEYBOARD_XTKBD=m
-CONFIG_MOUSE_PS2=m
-CONFIG_MOUSE_SERIAL=m
-CONFIG_MOUSE_APPLETOUCH=m
-CONFIG_MOUSE_VSXXXAA=m
-CONFIG_MOUSE_GPIO=m
-CONFIG_INPUT_MISC=y
-CONFIG_INPUT_UINPUT=m
-CONFIG_SERIO_SERPORT=m
-CONFIG_SERIO_RAW=m
-CONFIG_VT_HW_CONSOLE_BINDING=y
-CONFIG_SERIAL_NONSTANDARD=y
-CONFIG_N_HDLC=m
-CONFIG_SPECIALIX=m
-CONFIG_STALDRV=y
-CONFIG_SERIAL_ATMEL=y
-CONFIG_SERIAL_ATMEL_CONSOLE=y
-CONFIG_IPMI_HANDLER=m
-CONFIG_IPMI_DEVICE_INTERFACE=m
-CONFIG_IPMI_SI=m
-CONFIG_IPMI_WATCHDOG=m
-CONFIG_IPMI_POWEROFF=m
-CONFIG_HW_RANDOM=y
-CONFIG_R3964=m
-CONFIG_RAW_DRIVER=m
-CONFIG_TCG_TPM=m
-CONFIG_TCG_NSC=m
-CONFIG_TCG_ATMEL=m
-CONFIG_I2C=m
-CONFIG_I2C_CHARDEV=m
-CONFIG_SPI=y
-CONFIG_SPI_ATMEL=y
-CONFIG_SPI_BITBANG=m
-CONFIG_SPI_SPIDEV=m
-# CONFIG_HWMON is not set
-# CONFIG_VGA_CONSOLE is not set
-CONFIG_SOUND=m
-CONFIG_SND=m
-CONFIG_SND_SEQUENCER=m
-CONFIG_SND_SEQ_DUMMY=m
-CONFIG_SND_MIXER_OSS=m
-CONFIG_SND_PCM_OSS=m
-# CONFIG_SND_PCM_OSS_PLUGINS is not set
-CONFIG_SND_SEQUENCER_OSS=y
-CONFIG_SND_DYNAMIC_MINORS=y
-# CONFIG_SND_VERBOSE_PROCFS is not set
-CONFIG_SND_DUMMY=m
-CONFIG_SND_VIRMIDI=m
-CONFIG_SND_USB_AUDIO=m
-CONFIG_SND_USB_CAIAQ=m
-CONFIG_SND_USB_CAIAQ_INPUT=y
-CONFIG_HID=m
-CONFIG_HIDRAW=y
-CONFIG_USB_HID=m
-CONFIG_USB_HIDDEV=y
-CONFIG_USB_KBD=m
-CONFIG_USB_MOUSE=m
-CONFIG_HID_A4TECH=m
-CONFIG_HID_APPLE=m
-CONFIG_HID_BELKIN=m
-CONFIG_HID_CHERRY=m
-CONFIG_HID_CHICONY=m
-CONFIG_HID_CYPRESS=m
-CONFIG_HID_EZKEY=m
-CONFIG_HID_GYRATION=m
-CONFIG_HID_LOGITECH=m
-CONFIG_HID_MICROSOFT=m
-CONFIG_HID_MONTEREY=m
-CONFIG_HID_PANTHERLORD=m
-CONFIG_HID_PETALYNX=m
-CONFIG_HID_SAMSUNG=m
-CONFIG_HID_SONY=m
-CONFIG_HID_SUNPLUS=m
-CONFIG_USB=y
-CONFIG_USB_DEVICEFS=y
-# CONFIG_USB_DEVICE_CLASS is not set
-CONFIG_USB_DYNAMIC_MINORS=y
-CONFIG_USB_MON=y
-CONFIG_USB_OHCI_HCD=y
-CONFIG_USB_STORAGE=m
-CONFIG_USB_STORAGE_DATAFAB=m
-CONFIG_USB_STORAGE_FREECOM=m
-CONFIG_USB_STORAGE_ISD200=m
-CONFIG_USB_STORAGE_USBAT=m
-CONFIG_USB_STORAGE_SDDR09=m
-CONFIG_USB_STORAGE_SDDR55=m
-CONFIG_USB_STORAGE_JUMPSHOT=m
-CONFIG_USB_STORAGE_ALAUDA=m
-CONFIG_USB_STORAGE_KARMA=m
-CONFIG_USB_LIBUSUAL=y
-CONFIG_USB_SERIAL=m
-CONFIG_USB_EZUSB=y
-CONFIG_USB_SERIAL_GENERIC=y
-CONFIG_USB_SERIAL_PL2303=m
-CONFIG_USB_SERIAL_SPCP8X5=m
-CONFIG_USB_SERIAL_DEBUG=m
-CONFIG_USB_EMI62=m
-CONFIG_USB_EMI26=m
-CONFIG_USB_ADUTUX=m
-CONFIG_USB_TEST=m
-CONFIG_USB_GADGET=m
-CONFIG_USB_GADGET_DEBUG_FILES=y
-CONFIG_USB_GADGET_DEBUG_FS=y
-CONFIG_USB_ZERO=m
-CONFIG_USB_ETH=m
-CONFIG_USB_GADGETFS=m
-CONFIG_USB_FILE_STORAGE=m
-CONFIG_USB_G_SERIAL=m
-CONFIG_USB_MIDI_GADGET=m
-CONFIG_MMC=y
-CONFIG_SDIO_UART=m
-CONFIG_MMC_AT91=m
-CONFIG_MMC_SPI=m
-CONFIG_NEW_LEDS=y
-CONFIG_LEDS_CLASS=m
-CONFIG_LEDS_GPIO=m
-CONFIG_LEDS_TRIGGERS=y
-CONFIG_LEDS_TRIGGER_TIMER=m
-CONFIG_LEDS_TRIGGER_HEARTBEAT=m
-CONFIG_RTC_CLASS=y
-CONFIG_RTC_INTF_DEV_UIE_EMUL=y
-CONFIG_RTC_DRV_DS1307=m
-CONFIG_RTC_DRV_DS1305=y
-CONFIG_EXT2_FS=y
-CONFIG_EXT2_FS_XATTR=y
-CONFIG_EXT2_FS_POSIX_ACL=y
-CONFIG_EXT2_FS_SECURITY=y
-CONFIG_EXT3_FS=y
-CONFIG_EXT3_FS_POSIX_ACL=y
-CONFIG_EXT3_FS_SECURITY=y
-CONFIG_JBD_DEBUG=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_INOTIFY=y
-CONFIG_FUSE_FS=m
-CONFIG_MSDOS_FS=m
-CONFIG_VFAT_FS=y
-CONFIG_NTFS_FS=m
-CONFIG_NTFS_RW=y
-CONFIG_TMPFS=y
-CONFIG_TMPFS_POSIX_ACL=y
-CONFIG_JFFS2_FS=m
-CONFIG_JFFS2_COMPRESSION_OPTIONS=y
-CONFIG_JFFS2_LZO=y
-CONFIG_JFFS2_CMODE_FAVOURLZO=y
-CONFIG_CRAMFS=m
-CONFIG_NFS_FS=m
-CONFIG_NFS_V3=y
-CONFIG_NFS_V3_ACL=y
-CONFIG_NFS_V4=y
-CONFIG_NFSD=m
-CONFIG_NFSD_V3_ACL=y
-CONFIG_NFSD_V4=y
-CONFIG_CIFS=m
-CONFIG_CIFS_WEAK_PW_HASH=y
-CONFIG_PARTITION_ADVANCED=y
-CONFIG_MAC_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_SUN_PARTITION=y
-CONFIG_NLS_DEFAULT="cp437"
-CONFIG_NLS_CODEPAGE_437=y
-CONFIG_NLS_CODEPAGE_850=m
-CONFIG_NLS_ASCII=y
-CONFIG_NLS_ISO8859_1=y
-CONFIG_NLS_UTF8=m
-CONFIG_DLM=m
-CONFIG_PRINTK_TIME=y
-CONFIG_MAGIC_SYSRQ=y
-CONFIG_UNUSED_SYMBOLS=y
-CONFIG_DEBUG_FS=y
-# CONFIG_RCU_CPU_STALL_DETECTOR is not set
-CONFIG_SYSCTL_SYSCALL_CHECK=y
-CONFIG_CRYPTO=y
-CONFIG_CRYPTO_GF128MUL=m
-CONFIG_CRYPTO_HMAC=y
-CONFIG_CRYPTO_MD5=y
-# CONFIG_CRYPTO_ANSI_CPRNG is not set
-# CONFIG_CRYPTO_HW is not set
-CONFIG_CRC_CCITT=m
-CONFIG_CRC16=m
diff -druN linux-2.6.39-libre/arch/arm/configs/at91sam9261_defconfig linux-3.0-rc7-libre/arch/arm/configs/at91sam9261_defconfig
--- linux-2.6.39-libre/arch/arm/configs/at91sam9261_defconfig	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/arm/configs/at91sam9261_defconfig	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,158 @@
+CONFIG_EXPERIMENTAL=y
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_KERNEL_LZMA=y
+# CONFIG_SWAP is not set
+CONFIG_SYSVIPC=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_NAMESPACES=y
+CONFIG_EMBEDDED=y
+CONFIG_SLAB=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_IOSCHED_DEADLINE is not set
+# CONFIG_IOSCHED_CFQ is not set
+CONFIG_ARCH_AT91=y
+CONFIG_ARCH_AT91SAM9261=y
+CONFIG_MACH_AT91SAM9261EK=y
+CONFIG_AT91_PROGRAMMABLE_CLOCKS=y
+# CONFIG_ARM_THUMB is not set
+CONFIG_AEABI=y
+# CONFIG_OABI_COMPAT is not set
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="mem=64M console=ttyS0,115200 initrd=0x21100000,3145728 root=/dev/ram0 rw"
+CONFIG_AUTO_ZRELADDR=y
+CONFIG_VFP=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_INET_LRO is not set
+# CONFIG_IPV6 is not set
+CONFIG_CFG80211=y
+CONFIG_LIB80211=y
+CONFIG_MAC80211=y
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_MTD=y
+CONFIG_MTD_PARTITIONS=y
+CONFIG_MTD_CMDLINE_PARTS=y
+CONFIG_MTD_BLOCK=y
+CONFIG_MTD_NAND=y
+CONFIG_MTD_NAND_ATMEL=y
+CONFIG_MTD_UBI=y
+CONFIG_MTD_UBI_GLUEBI=y
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=8192
+CONFIG_MISC_DEVICES=y
+CONFIG_ATMEL_TCLIB=y
+CONFIG_ATMEL_SSC=y
+CONFIG_SCSI=y
+CONFIG_BLK_DEV_SD=y
+CONFIG_SCSI_MULTI_LUN=y
+CONFIG_NETDEVICES=y
+CONFIG_NET_ETHERNET=y
+CONFIG_DM9000=y
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+CONFIG_USB_ZD1201=m
+CONFIG_RTL8187=m
+CONFIG_LIBERTAS=m
+CONFIG_LIBERTAS_USB=m
+CONFIG_LIBERTAS_SDIO=m
+CONFIG_LIBERTAS_SPI=m
+CONFIG_RT2X00=m
+CONFIG_RT2500USB=m
+CONFIG_RT73USB=m
+CONFIG_ZD1211RW=m
+CONFIG_INPUT_POLLDEV=m
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=240
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=320
+CONFIG_INPUT_EVDEV=y
+# CONFIG_KEYBOARD_ATKBD is not set
+CONFIG_KEYBOARD_GPIO=y
+# CONFIG_INPUT_MOUSE is not set
+CONFIG_INPUT_TOUCHSCREEN=y
+CONFIG_TOUCHSCREEN_ADS7846=y
+CONFIG_DEVPTS_MULTIPLE_INSTANCES=y
+CONFIG_SERIAL_ATMEL=y
+CONFIG_SERIAL_ATMEL_CONSOLE=y
+CONFIG_HW_RANDOM=y
+CONFIG_I2C=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_GPIO=y
+CONFIG_SPI=y
+CONFIG_SPI_ATMEL=y
+# CONFIG_HWMON is not set
+CONFIG_WATCHDOG=y
+CONFIG_WATCHDOG_NOWAYOUT=y
+CONFIG_AT91SAM9X_WATCHDOG=y
+CONFIG_FB=y
+CONFIG_FB_ATMEL=y
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+# CONFIG_LCD_CLASS_DEVICE is not set
+CONFIG_BACKLIGHT_CLASS_DEVICE=y
+CONFIG_BACKLIGHT_ATMEL_LCDC=y
+# CONFIG_BACKLIGHT_GENERIC is not set
+CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y
+CONFIG_LOGO=y
+CONFIG_SOUND=y
+CONFIG_SND=y
+CONFIG_SND_SEQUENCER=y
+CONFIG_SND_MIXER_OSS=y
+CONFIG_SND_PCM_OSS=y
+# CONFIG_SND_SUPPORT_OLD_API is not set
+# CONFIG_SND_VERBOSE_PROCFS is not set
+# CONFIG_SND_DRIVERS is not set
+# CONFIG_SND_ARM is not set
+CONFIG_SND_AT73C213=y
+CONFIG_SND_USB_AUDIO=m
+# CONFIG_USB_HID is not set
+CONFIG_USB=y
+CONFIG_USB_DEVICEFS=y
+CONFIG_USB_OHCI_HCD=y
+CONFIG_USB_STORAGE=y
+CONFIG_USB_GADGET=y
+CONFIG_USB_ZERO=m
+CONFIG_USB_ETH=m
+CONFIG_USB_GADGETFS=m
+CONFIG_USB_FILE_STORAGE=m
+CONFIG_USB_G_SERIAL=m
+CONFIG_MMC=y
+CONFIG_MMC_AT91=m
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+CONFIG_LEDS_GPIO=y
+CONFIG_LEDS_TRIGGERS=y
+CONFIG_LEDS_TRIGGER_TIMER=y
+CONFIG_LEDS_TRIGGER_HEARTBEAT=y
+CONFIG_LEDS_TRIGGER_GPIO=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_AT91SAM9=y
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_TMPFS=y
+CONFIG_UBIFS_FS=y
+CONFIG_UBIFS_FS_ADVANCED_COMPR=y
+CONFIG_SQUASHFS=y
+CONFIG_SQUASHFS_LZO=y
+CONFIG_SQUASHFS_XZ=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+CONFIG_ROOT_NFS=y
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_CODEPAGE_850=y
+CONFIG_NLS_ISO8859_1=y
+CONFIG_NLS_ISO8859_15=y
+CONFIG_NLS_UTF8=y
+CONFIG_FTRACE=y
+CONFIG_CRC_CCITT=m
diff -druN linux-2.6.39-libre/arch/arm/configs/at91sam9261ek_defconfig linux-3.0-rc7-libre/arch/arm/configs/at91sam9261ek_defconfig
--- linux-2.6.39-libre/arch/arm/configs/at91sam9261ek_defconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/configs/at91sam9261ek_defconfig	1969-12-31 19:00:00.000000000 -0500
@@ -1,95 +0,0 @@
-CONFIG_EXPERIMENTAL=y
-# CONFIG_LOCALVERSION_AUTO is not set
-# CONFIG_SWAP is not set
-CONFIG_SYSVIPC=y
-CONFIG_LOG_BUF_SHIFT=14
-CONFIG_BLK_DEV_INITRD=y
-CONFIG_SLAB=y
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-# CONFIG_BLK_DEV_BSG is not set
-# CONFIG_IOSCHED_DEADLINE is not set
-# CONFIG_IOSCHED_CFQ is not set
-CONFIG_ARCH_AT91=y
-CONFIG_ARCH_AT91SAM9261=y
-CONFIG_MACH_AT91SAM9261EK=y
-CONFIG_AT91_PROGRAMMABLE_CLOCKS=y
-# CONFIG_ARM_THUMB is not set
-CONFIG_ZBOOT_ROM_TEXT=0x0
-CONFIG_ZBOOT_ROM_BSS=0x0
-CONFIG_CMDLINE="mem=64M console=ttyS0,115200 initrd=0x21100000,3145728 root=/dev/ram0 rw"
-CONFIG_FPE_NWFPE=y
-CONFIG_NET=y
-CONFIG_PACKET=y
-CONFIG_UNIX=y
-CONFIG_INET=y
-CONFIG_IP_PNP=y
-CONFIG_IP_PNP_BOOTP=y
-# CONFIG_INET_LRO is not set
-# CONFIG_IPV6 is not set
-CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
-CONFIG_MTD=y
-CONFIG_MTD_PARTITIONS=y
-CONFIG_MTD_CMDLINE_PARTS=y
-CONFIG_MTD_BLOCK=y
-CONFIG_MTD_NAND=y
-CONFIG_MTD_NAND_ATMEL=y
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_SIZE=8192
-CONFIG_ATMEL_SSC=y
-CONFIG_SCSI=y
-CONFIG_BLK_DEV_SD=y
-CONFIG_SCSI_MULTI_LUN=y
-CONFIG_NETDEVICES=y
-CONFIG_NET_ETHERNET=y
-CONFIG_DM9000=y
-# CONFIG_NETDEV_1000 is not set
-# CONFIG_NETDEV_10000 is not set
-# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
-# CONFIG_KEYBOARD_ATKBD is not set
-CONFIG_KEYBOARD_GPIO=y
-# CONFIG_INPUT_MOUSE is not set
-CONFIG_INPUT_TOUCHSCREEN=y
-CONFIG_TOUCHSCREEN_ADS7846=y
-CONFIG_SERIAL_ATMEL=y
-CONFIG_SERIAL_ATMEL_CONSOLE=y
-CONFIG_HW_RANDOM=y
-CONFIG_I2C=y
-CONFIG_I2C_CHARDEV=y
-CONFIG_I2C_GPIO=y
-CONFIG_SPI=y
-CONFIG_SPI_ATMEL=y
-# CONFIG_HWMON is not set
-CONFIG_WATCHDOG=y
-CONFIG_WATCHDOG_NOWAYOUT=y
-CONFIG_AT91SAM9X_WATCHDOG=y
-CONFIG_FB=y
-CONFIG_FB_ATMEL=y
-# CONFIG_VGA_CONSOLE is not set
-# CONFIG_USB_HID is not set
-CONFIG_USB=y
-CONFIG_USB_DEVICEFS=y
-CONFIG_USB_MON=y
-CONFIG_USB_OHCI_HCD=y
-CONFIG_USB_STORAGE=y
-CONFIG_USB_STORAGE_DEBUG=y
-CONFIG_USB_GADGET=y
-CONFIG_USB_ZERO=m
-CONFIG_USB_GADGETFS=m
-CONFIG_USB_FILE_STORAGE=m
-CONFIG_USB_G_SERIAL=m
-CONFIG_MMC=y
-CONFIG_MMC_AT91=m
-CONFIG_RTC_CLASS=y
-CONFIG_RTC_DRV_AT91SAM9=y
-CONFIG_EXT2_FS=y
-CONFIG_INOTIFY=y
-CONFIG_VFAT_FS=y
-CONFIG_TMPFS=y
-CONFIG_CRAMFS=y
-CONFIG_NLS_CODEPAGE_437=y
-CONFIG_NLS_CODEPAGE_850=y
-CONFIG_NLS_ISO8859_1=y
-CONFIG_DEBUG_KERNEL=y
-CONFIG_DEBUG_USER=y
-CONFIG_DEBUG_LL=y
diff -druN linux-2.6.39-libre/arch/arm/configs/at91sam9263_defconfig linux-3.0-rc7-libre/arch/arm/configs/at91sam9263_defconfig
--- linux-2.6.39-libre/arch/arm/configs/at91sam9263_defconfig	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/arm/configs/at91sam9263_defconfig	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,168 @@
+CONFIG_EXPERIMENTAL=y
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_KERNEL_LZMA=y
+# CONFIG_SWAP is not set
+CONFIG_SYSVIPC=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=14
+CONFIG_NAMESPACES=y
+CONFIG_EMBEDDED=y
+CONFIG_SLAB=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_IOSCHED_DEADLINE is not set
+# CONFIG_IOSCHED_CFQ is not set
+CONFIG_ARCH_AT91=y
+CONFIG_ARCH_AT91SAM9263=y
+CONFIG_MACH_AT91SAM9263EK=y
+CONFIG_MACH_USB_A9263=y
+CONFIG_MACH_NEOCORE926=y
+CONFIG_MTD_AT91_DATAFLASH_CARD=y
+# CONFIG_ARM_THUMB is not set
+CONFIG_AEABI=y
+# CONFIG_OABI_COMPAT is not set
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="mem=64M console=ttyS0,115200 initrd=0x21100000,3145728 root=/dev/ram0 rw"
+CONFIG_AUTO_ZRELADDR=y
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_NET_KEY=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_ADVANCED_ROUTER=y
+CONFIG_IP_ROUTE_VERBOSE=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+CONFIG_IP_PNP_RARP=y
+CONFIG_NET_IPIP=y
+CONFIG_IP_MROUTE=y
+CONFIG_IP_PIMSM_V1=y
+CONFIG_IP_PIMSM_V2=y
+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
+# CONFIG_INET_LRO is not set
+# CONFIG_INET_DIAG is not set
+CONFIG_IPV6=y
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_MTD=y
+CONFIG_MTD_PARTITIONS=y
+CONFIG_MTD_CMDLINE_PARTS=y
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+CONFIG_NFTL=y
+CONFIG_NFTL_RW=y
+CONFIG_MTD_DATAFLASH=y
+CONFIG_MTD_BLOCK2MTD=y
+CONFIG_MTD_NAND=y
+CONFIG_MTD_NAND_ATMEL=y
+CONFIG_MTD_NAND_ATMEL_ECC_SOFT=y
+CONFIG_MTD_UBI=y
+CONFIG_MTD_UBI_GLUEBI=y
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=8192
+CONFIG_MISC_DEVICES=y
+CONFIG_ATMEL_PWM=y
+CONFIG_ATMEL_TCLIB=y
+CONFIG_SCSI=y
+CONFIG_BLK_DEV_SD=y
+CONFIG_SCSI_MULTI_LUN=y
+CONFIG_NETDEVICES=y
+CONFIG_MII=y
+CONFIG_SMSC_PHY=y
+CONFIG_NET_ETHERNET=y
+CONFIG_MACB=y
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+CONFIG_USB_ZD1201=m
+CONFIG_INPUT_POLLDEV=m
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=240
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=320
+CONFIG_INPUT_EVDEV=y
+# CONFIG_KEYBOARD_ATKBD is not set
+CONFIG_KEYBOARD_GPIO=y
+# CONFIG_INPUT_MOUSE is not set
+CONFIG_INPUT_TOUCHSCREEN=y
+CONFIG_TOUCHSCREEN_ADS7846=y
+CONFIG_LEGACY_PTY_COUNT=4
+CONFIG_SERIAL_ATMEL=y
+CONFIG_SERIAL_ATMEL_CONSOLE=y
+CONFIG_HW_RANDOM=y
+CONFIG_I2C=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_GPIO=y
+CONFIG_SPI=y
+CONFIG_SPI_ATMEL=y
+# CONFIG_HWMON is not set
+CONFIG_WATCHDOG=y
+CONFIG_WATCHDOG_NOWAYOUT=y
+CONFIG_AT91SAM9X_WATCHDOG=y
+CONFIG_FB=y
+CONFIG_FB_ATMEL=y
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+CONFIG_LCD_CLASS_DEVICE=y
+CONFIG_BACKLIGHT_CLASS_DEVICE=y
+CONFIG_BACKLIGHT_ATMEL_LCDC=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y
+CONFIG_LOGO=y
+CONFIG_SOUND=y
+CONFIG_SND=y
+CONFIG_SND_SEQUENCER=y
+CONFIG_SND_MIXER_OSS=y
+CONFIG_SND_PCM_OSS=y
+# CONFIG_SND_SUPPORT_OLD_API is not set
+# CONFIG_SND_VERBOSE_PROCFS is not set
+# CONFIG_SND_DRIVERS is not set
+# CONFIG_SND_ARM is not set
+CONFIG_SND_ATMEL_AC97C=y
+# CONFIG_SND_SPI is not set
+CONFIG_SND_USB_AUDIO=m
+CONFIG_USB=y
+CONFIG_USB_DEVICEFS=y
+CONFIG_USB_MON=y
+CONFIG_USB_OHCI_HCD=y
+CONFIG_USB_STORAGE=y
+CONFIG_USB_GADGET=y
+CONFIG_USB_ZERO=m
+CONFIG_USB_ETH=m
+CONFIG_USB_GADGETFS=m
+CONFIG_USB_FILE_STORAGE=m
+CONFIG_USB_G_SERIAL=m
+CONFIG_MMC=y
+CONFIG_SDIO_UART=m
+CONFIG_MMC_AT91=m
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+CONFIG_LEDS_ATMEL_PWM=y
+CONFIG_LEDS_GPIO=y
+CONFIG_LEDS_TRIGGERS=y
+CONFIG_LEDS_TRIGGER_HEARTBEAT=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_AT91SAM9=y
+CONFIG_EXT2_FS=y
+CONFIG_FUSE_FS=m
+CONFIG_VFAT_FS=y
+CONFIG_TMPFS=y
+CONFIG_JFFS2_FS=y
+CONFIG_UBIFS_FS=y
+CONFIG_UBIFS_FS_ADVANCED_COMPR=y
+CONFIG_CRAMFS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+CONFIG_NFS_V3_ACL=y
+CONFIG_NFS_V4=y
+CONFIG_ROOT_NFS=y
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_CODEPAGE_850=y
+CONFIG_NLS_ISO8859_1=y
+CONFIG_FTRACE=y
+CONFIG_DEBUG_USER=y
+CONFIG_XZ_DEC=y
diff -druN linux-2.6.39-libre/arch/arm/configs/at91sam9263ek_defconfig linux-3.0-rc7-libre/arch/arm/configs/at91sam9263ek_defconfig
--- linux-2.6.39-libre/arch/arm/configs/at91sam9263ek_defconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/configs/at91sam9263ek_defconfig	1969-12-31 19:00:00.000000000 -0500
@@ -1,106 +0,0 @@
-CONFIG_EXPERIMENTAL=y
-# CONFIG_LOCALVERSION_AUTO is not set
-# CONFIG_SWAP is not set
-CONFIG_SYSVIPC=y
-CONFIG_LOG_BUF_SHIFT=14
-CONFIG_BLK_DEV_INITRD=y
-CONFIG_SLAB=y
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-# CONFIG_BLK_DEV_BSG is not set
-# CONFIG_IOSCHED_DEADLINE is not set
-# CONFIG_IOSCHED_CFQ is not set
-CONFIG_ARCH_AT91=y
-CONFIG_ARCH_AT91SAM9263=y
-CONFIG_MACH_AT91SAM9263EK=y
-CONFIG_MTD_AT91_DATAFLASH_CARD=y
-# CONFIG_ARM_THUMB is not set
-CONFIG_ZBOOT_ROM_TEXT=0x0
-CONFIG_ZBOOT_ROM_BSS=0x0
-CONFIG_CMDLINE="mem=64M console=ttyS0,115200 initrd=0x21100000,3145728 root=/dev/ram0 rw"
-CONFIG_FPE_NWFPE=y
-CONFIG_NET=y
-CONFIG_PACKET=y
-CONFIG_UNIX=y
-CONFIG_INET=y
-CONFIG_IP_PNP=y
-CONFIG_IP_PNP_BOOTP=y
-CONFIG_IP_PNP_RARP=y
-# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
-# CONFIG_INET_XFRM_MODE_TUNNEL is not set
-# CONFIG_INET_XFRM_MODE_BEET is not set
-# CONFIG_INET_LRO is not set
-# CONFIG_INET_DIAG is not set
-# CONFIG_IPV6 is not set
-CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
-CONFIG_MTD=y
-CONFIG_MTD_PARTITIONS=y
-CONFIG_MTD_CMDLINE_PARTS=y
-CONFIG_MTD_CHAR=y
-CONFIG_MTD_BLOCK=y
-CONFIG_MTD_DATAFLASH=y
-CONFIG_MTD_NAND=y
-CONFIG_MTD_NAND_ATMEL=y
-CONFIG_BLK_DEV_LOOP=y
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_SIZE=8192
-CONFIG_ATMEL_SSC=y
-CONFIG_SCSI=y
-CONFIG_BLK_DEV_SD=y
-CONFIG_SCSI_MULTI_LUN=y
-CONFIG_NETDEVICES=y
-CONFIG_NET_ETHERNET=y
-CONFIG_MII=y
-CONFIG_MACB=y
-# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
-CONFIG_INPUT_EVDEV=y
-# CONFIG_KEYBOARD_ATKBD is not set
-CONFIG_KEYBOARD_GPIO=y
-# CONFIG_INPUT_MOUSE is not set
-CONFIG_INPUT_TOUCHSCREEN=y
-CONFIG_TOUCHSCREEN_ADS7846=y
-# CONFIG_SERIO is not set
-CONFIG_SERIAL_ATMEL=y
-CONFIG_SERIAL_ATMEL_CONSOLE=y
-CONFIG_HW_RANDOM=y
-CONFIG_I2C=y
-CONFIG_I2C_CHARDEV=y
-CONFIG_I2C_GPIO=y
-CONFIG_SPI=y
-CONFIG_SPI_ATMEL=y
-# CONFIG_HWMON is not set
-CONFIG_WATCHDOG=y
-CONFIG_WATCHDOG_NOWAYOUT=y
-CONFIG_AT91SAM9X_WATCHDOG=y
-CONFIG_FB=y
-CONFIG_FB_ATMEL=y
-# CONFIG_VGA_CONSOLE is not set
-# CONFIG_USB_HID is not set
-CONFIG_USB=y
-CONFIG_USB_DEVICEFS=y
-CONFIG_USB_MON=y
-CONFIG_USB_OHCI_HCD=y
-CONFIG_USB_STORAGE=y
-CONFIG_USB_GADGET=y
-CONFIG_USB_ZERO=m
-CONFIG_USB_GADGETFS=m
-CONFIG_USB_FILE_STORAGE=m
-CONFIG_USB_G_SERIAL=m
-CONFIG_MMC=y
-CONFIG_MMC_AT91=m
-CONFIG_RTC_CLASS=y
-CONFIG_RTC_DRV_AT91SAM9=y
-CONFIG_EXT2_FS=y
-CONFIG_INOTIFY=y
-CONFIG_VFAT_FS=y
-CONFIG_TMPFS=y
-CONFIG_JFFS2_FS=y
-CONFIG_CRAMFS=y
-CONFIG_NFS_FS=y
-CONFIG_ROOT_NFS=y
-CONFIG_NLS_CODEPAGE_437=y
-CONFIG_NLS_CODEPAGE_850=y
-CONFIG_NLS_ISO8859_1=y
-CONFIG_DEBUG_KERNEL=y
-CONFIG_DEBUG_USER=y
-CONFIG_DEBUG_LL=y
diff -druN linux-2.6.39-libre/arch/arm/configs/davinci_all_defconfig linux-3.0-rc7-libre/arch/arm/configs/davinci_all_defconfig
--- linux-2.6.39-libre/arch/arm/configs/davinci_all_defconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/configs/davinci_all_defconfig	2011-07-11 19:51:52.000000000 -0400
@@ -157,7 +157,7 @@
 CONFIG_LEDS_TRIGGERS=y
 CONFIG_LEDS_TRIGGER_TIMER=m
 CONFIG_LEDS_TRIGGER_HEARTBEAT=m
-CONFIG_RTC_CLASS=m
+CONFIG_RTC_CLASS=y
 CONFIG_EXT2_FS=y
 CONFIG_EXT3_FS=y
 CONFIG_XFS_FS=m
diff -druN linux-2.6.39-libre/arch/arm/configs/dove_defconfig linux-3.0-rc7-libre/arch/arm/configs/dove_defconfig
--- linux-2.6.39-libre/arch/arm/configs/dove_defconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/configs/dove_defconfig	2011-07-11 19:51:52.000000000 -0400
@@ -8,8 +8,6 @@
 # CONFIG_BLK_DEV_BSG is not set
 CONFIG_ARCH_DOVE=y
 CONFIG_MACH_DOVE_DB=y
-CONFIG_CPU_V6=y
-CONFIG_CPU_32v6K=y
 CONFIG_NO_HZ=y
 CONFIG_HIGH_RES_TIMERS=y
 CONFIG_AEABI=y
@@ -44,7 +42,6 @@
 CONFIG_BLK_DEV_LOOP=y
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_COUNT=1
-# CONFIG_MISC_DEVICES is not set
 # CONFIG_SCSI_PROC_FS is not set
 CONFIG_BLK_DEV_SD=y
 # CONFIG_SCSI_LOWLEVEL is not set
@@ -59,12 +56,12 @@
 # CONFIG_KEYBOARD_ATKBD is not set
 # CONFIG_MOUSE_PS2 is not set
 # CONFIG_SERIO is not set
+CONFIG_LEGACY_PTY_COUNT=16
 # CONFIG_DEVKMEM is not set
 CONFIG_SERIAL_8250=y
 CONFIG_SERIAL_8250_CONSOLE=y
 # CONFIG_SERIAL_8250_PCI is not set
 CONFIG_SERIAL_8250_RUNTIME_UARTS=2
-CONFIG_LEGACY_PTY_COUNT=16
 # CONFIG_HW_RANDOM is not set
 CONFIG_I2C=y
 CONFIG_I2C_CHARDEV=y
@@ -72,12 +69,10 @@
 CONFIG_SPI=y
 CONFIG_SPI_ORION=y
 # CONFIG_HWMON is not set
-# CONFIG_VGA_CONSOLE is not set
 CONFIG_USB=y
 CONFIG_USB_DEVICEFS=y
 CONFIG_USB_EHCI_HCD=y
 CONFIG_USB_EHCI_ROOT_HUB_TT=y
-CONFIG_USB_EHCI_TT_NEWSCHED=y
 CONFIG_USB_STORAGE=y
 CONFIG_RTC_CLASS=y
 CONFIG_RTC_DRV_MV=y
@@ -86,7 +81,6 @@
 CONFIG_EXT2_FS=y
 CONFIG_EXT3_FS=y
 # CONFIG_EXT3_FS_XATTR is not set
-CONFIG_INOTIFY=y
 CONFIG_ISO9660_FS=y
 CONFIG_JOLIET=y
 CONFIG_UDF_FS=m
@@ -110,23 +104,19 @@
 CONFIG_TIMER_STATS=y
 # CONFIG_DEBUG_BUGVERBOSE is not set
 CONFIG_DEBUG_INFO=y
-# CONFIG_RCU_CPU_STALL_DETECTOR is not set
 CONFIG_SYSCTL_SYSCALL_CHECK=y
 CONFIG_DEBUG_USER=y
 CONFIG_DEBUG_ERRORS=y
 CONFIG_CRYPTO_NULL=y
-CONFIG_CRYPTO_CBC=y
 CONFIG_CRYPTO_ECB=m
 CONFIG_CRYPTO_PCBC=m
 CONFIG_CRYPTO_HMAC=y
 CONFIG_CRYPTO_MD4=y
-CONFIG_CRYPTO_MD5=y
 CONFIG_CRYPTO_SHA1=y
 CONFIG_CRYPTO_SHA256=y
 CONFIG_CRYPTO_SHA512=y
 CONFIG_CRYPTO_AES=y
 CONFIG_CRYPTO_BLOWFISH=y
-CONFIG_CRYPTO_DES=y
 CONFIG_CRYPTO_TEA=y
 CONFIG_CRYPTO_TWOFISH=y
 CONFIG_CRYPTO_DEFLATE=y
diff -druN linux-2.6.39-libre/arch/arm/configs/exynos4_defconfig linux-3.0-rc7-libre/arch/arm/configs/exynos4_defconfig
--- linux-2.6.39-libre/arch/arm/configs/exynos4_defconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/configs/exynos4_defconfig	2011-07-11 19:51:52.000000000 -0400
@@ -8,7 +8,9 @@
 CONFIG_S3C_LOWLEVEL_UART_PORT=1
 CONFIG_MACH_SMDKC210=y
 CONFIG_MACH_SMDKV310=y
+CONFIG_MACH_ARMLEX4210=y
 CONFIG_MACH_UNIVERSAL_C210=y
+CONFIG_MACH_NURI=y
 CONFIG_NO_HZ=y
 CONFIG_HIGH_RES_TIMERS=y
 CONFIG_SMP=y
diff -druN linux-2.6.39-libre/arch/arm/configs/mx1_defconfig linux-3.0-rc7-libre/arch/arm/configs/mx1_defconfig
--- linux-2.6.39-libre/arch/arm/configs/mx1_defconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/configs/mx1_defconfig	2011-07-11 19:51:52.000000000 -0400
@@ -15,6 +15,7 @@
 CONFIG_ARCH_MX1=y
 CONFIG_ARCH_MX1ADS=y
 CONFIG_MACH_SCB9328=y
+CONFIG_MACH_APF9328=y
 CONFIG_MXC_IRQ_PRIOR=y
 CONFIG_NO_HZ=y
 CONFIG_HIGH_RES_TIMERS=y
diff -druN linux-2.6.39-libre/arch/arm/configs/mx51_defconfig linux-3.0-rc7-libre/arch/arm/configs/mx51_defconfig
--- linux-2.6.39-libre/arch/arm/configs/mx51_defconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/configs/mx51_defconfig	2011-07-11 19:51:52.000000000 -0400
@@ -13,7 +13,7 @@
 # CONFIG_LBDAF is not set
 # CONFIG_BLK_DEV_BSG is not set
 CONFIG_ARCH_MXC=y
-CONFIG_ARCH_MX5=y
+CONFIG_ARCH_MX51=y
 CONFIG_MACH_MX51_BABBAGE=y
 CONFIG_MACH_MX51_3DS=y
 CONFIG_MACH_EUKREA_CPUIMX51=y
diff -druN linux-2.6.39-libre/arch/arm/configs/mxs_defconfig linux-3.0-rc7-libre/arch/arm/configs/mxs_defconfig
--- linux-2.6.39-libre/arch/arm/configs/mxs_defconfig	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/arm/configs/mxs_defconfig	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,129 @@
+CONFIG_EXPERIMENTAL=y
+CONFIG_SYSVIPC=y
+CONFIG_TASKSTATS=y
+CONFIG_TASK_DELAY_ACCT=y
+CONFIG_TASK_XACCT=y
+CONFIG_TASK_IO_ACCOUNTING=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=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_PERF_EVENTS=y
+# CONFIG_COMPAT_BRK is not set
+CONFIG_MODULES=y
+CONFIG_MODULE_FORCE_LOAD=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODULE_FORCE_UNLOAD=y
+CONFIG_MODVERSIONS=y
+CONFIG_BLK_DEV_INTEGRITY=y
+# CONFIG_IOSCHED_DEADLINE is not set
+# CONFIG_IOSCHED_CFQ is not set
+CONFIG_ARCH_MXS=y
+CONFIG_MACH_STMP378X_DEVB=y
+CONFIG_MACH_TX28=y
+# CONFIG_ARM_THUMB is not set
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_PREEMPT_VOLUNTARY=y
+CONFIG_AEABI=y
+CONFIG_DEFAULT_MMAP_MIN_ADDR=65536
+CONFIG_AUTO_ZRELADDR=y
+CONFIG_FPE_NWFPE=y
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_SYN_COOKIES=y
+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
+# CONFIG_INET_LRO is not set
+# CONFIG_INET_DIAG is not set
+# CONFIG_IPV6 is not set
+CONFIG_CAN=m
+CONFIG_CAN_RAW=m
+CONFIG_CAN_BCM=m
+CONFIG_CAN_DEV=m
+CONFIG_CAN_FLEXCAN=m
+# CONFIG_WIRELESS is not set
+CONFIG_DEVTMPFS=y
+# CONFIG_FIRMWARE_IN_KERNEL is not set
+# CONFIG_BLK_DEV is not set
+CONFIG_NETDEVICES=y
+CONFIG_NET_ETHERNET=y
+CONFIG_ENC28J60=y
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+# CONFIG_WLAN is not set
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+CONFIG_INPUT_EVDEV=m
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+CONFIG_INPUT_TOUCHSCREEN=y
+CONFIG_TOUCHSCREEN_TSC2007=m
+# CONFIG_SERIO is not set
+CONFIG_VT_HW_CONSOLE_BINDING=y
+CONFIG_DEVPTS_MULTIPLE_INSTANCES=y
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_DEVKMEM is not set
+CONFIG_SERIAL_AMBA_PL011=y
+CONFIG_SERIAL_AMBA_PL011_CONSOLE=y
+# CONFIG_HW_RANDOM is not set
+CONFIG_I2C=m
+# CONFIG_I2C_COMPAT is not set
+CONFIG_I2C_CHARDEV=m
+CONFIG_I2C_MXS=m
+CONFIG_SPI=y
+CONFIG_SPI_GPIO=m
+CONFIG_DEBUG_GPIO=y
+CONFIG_GPIO_SYSFS=y
+# CONFIG_HWMON is not set
+# CONFIG_MFD_SUPPORT is not set
+CONFIG_DISPLAY_SUPPORT=m
+# CONFIG_HID_SUPPORT is not set
+# CONFIG_USB_SUPPORT is not set
+CONFIG_MMC=y
+CONFIG_MMC_MXS=y
+CONFIG_RTC_CLASS=m
+CONFIG_RTC_DRV_DS1307=m
+CONFIG_DMADEVICES=y
+CONFIG_MXS_DMA=y
+CONFIG_EXT3_FS=y
+# CONFIG_DNOTIFY is not set
+CONFIG_FSCACHE=m
+CONFIG_FSCACHE_STATS=y
+CONFIG_CACHEFILES=m
+CONFIG_TMPFS=y
+CONFIG_TMPFS_POSIX_ACL=y
+# CONFIG_MISC_FILESYSTEMS is not set
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+CONFIG_NFS_V3_ACL=y
+CONFIG_NFS_V4=y
+CONFIG_ROOT_NFS=y
+CONFIG_PRINTK_TIME=y
+CONFIG_FRAME_WARN=2048
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_UNUSED_SYMBOLS=y
+CONFIG_DEBUG_KERNEL=y
+CONFIG_LOCKUP_DETECTOR=y
+CONFIG_DETECT_HUNG_TASK=y
+CONFIG_TIMER_STATS=y
+CONFIG_PROVE_LOCKING=y
+CONFIG_DEBUG_SPINLOCK_SLEEP=y
+CONFIG_DEBUG_INFO=y
+CONFIG_SYSCTL_SYSCALL_CHECK=y
+CONFIG_BLK_DEV_IO_TRACE=y
+CONFIG_STRICT_DEVMEM=y
+CONFIG_DEBUG_USER=y
+CONFIG_CRYPTO=y
+CONFIG_CRYPTO_CRC32C=m
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+# CONFIG_CRYPTO_HW is not set
+CONFIG_CRC_ITU_T=m
+CONFIG_CRC7=m
diff -druN linux-2.6.39-libre/arch/arm/configs/neocore926_defconfig linux-3.0-rc7-libre/arch/arm/configs/neocore926_defconfig
--- linux-2.6.39-libre/arch/arm/configs/neocore926_defconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/configs/neocore926_defconfig	1969-12-31 19:00:00.000000000 -0500
@@ -1,104 +0,0 @@
-CONFIG_EXPERIMENTAL=y
-# CONFIG_LOCALVERSION_AUTO is not set
-# CONFIG_SWAP is not set
-CONFIG_SYSVIPC=y
-CONFIG_BLK_DEV_INITRD=y
-# CONFIG_COMPAT_BRK is not set
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-# CONFIG_BLK_DEV_BSG is not set
-# CONFIG_IOSCHED_DEADLINE is not set
-# CONFIG_IOSCHED_CFQ is not set
-CONFIG_ARCH_AT91=y
-CONFIG_ARCH_AT91SAM9263=y
-CONFIG_MACH_NEOCORE926=y
-CONFIG_MTD_AT91_DATAFLASH_CARD=y
-CONFIG_ZBOOT_ROM_TEXT=0x0
-CONFIG_ZBOOT_ROM_BSS=0x0
-CONFIG_FPE_NWFPE=y
-CONFIG_NET=y
-CONFIG_PACKET=y
-CONFIG_UNIX=y
-CONFIG_NET_KEY=y
-CONFIG_INET=y
-CONFIG_IP_PNP=y
-CONFIG_IP_PNP_DHCP=y
-CONFIG_IP_PNP_BOOTP=y
-CONFIG_IP_PNP_RARP=y
-CONFIG_NET_IPIP=y
-# CONFIG_INET_LRO is not set
-CONFIG_IPV6=y
-CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
-# CONFIG_PREVENT_FIRMWARE_BUILD is not set
-CONFIG_MTD=y
-CONFIG_MTD_PARTITIONS=y
-CONFIG_MTD_CHAR=y
-CONFIG_MTD_BLOCK=y
-CONFIG_NFTL=y
-CONFIG_NFTL_RW=y
-CONFIG_MTD_BLOCK2MTD=y
-CONFIG_MTD_NAND=y
-CONFIG_MTD_NAND_ECC_SMC=y
-CONFIG_MTD_NAND_VERIFY_WRITE=y
-CONFIG_MTD_NAND_ATMEL=y
-CONFIG_MTD_NAND_PLATFORM=y
-CONFIG_BLK_DEV_LOOP=y
-CONFIG_BLK_DEV_NBD=y
-CONFIG_ATMEL_PWM=y
-CONFIG_ATMEL_TCLIB=y
-CONFIG_SCSI=y
-CONFIG_CHR_DEV_SG=y
-CONFIG_NETDEVICES=y
-CONFIG_SMSC_PHY=y
-CONFIG_NET_ETHERNET=y
-CONFIG_MACB=y
-# CONFIG_NETDEV_1000 is not set
-# CONFIG_NETDEV_10000 is not set
-# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
-CONFIG_INPUT_EVDEV=y
-CONFIG_INPUT_TOUCHSCREEN=y
-CONFIG_TOUCHSCREEN_ADS7846=y
-CONFIG_VT_HW_CONSOLE_BINDING=y
-# CONFIG_DEVKMEM is not set
-CONFIG_SERIAL_NONSTANDARD=y
-CONFIG_SERIAL_ATMEL=y
-CONFIG_SERIAL_ATMEL_CONSOLE=y
-# CONFIG_SERIAL_ATMEL_PDC is not set
-# CONFIG_HW_RANDOM is not set
-CONFIG_I2C=y
-CONFIG_I2C_CHARDEV=y
-CONFIG_SPI=y
-CONFIG_SPI_ATMEL=y
-# CONFIG_HWMON is not set
-CONFIG_VIDEO_OUTPUT_CONTROL=y
-CONFIG_FB=y
-CONFIG_FB_ATMEL=y
-CONFIG_BACKLIGHT_LCD_SUPPORT=y
-CONFIG_LCD_CLASS_DEVICE=y
-CONFIG_BACKLIGHT_CLASS_DEVICE=y
-CONFIG_BACKLIGHT_ATMEL_LCDC=y
-# CONFIG_VGA_CONSOLE is not set
-CONFIG_FRAMEBUFFER_CONSOLE=y
-CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y
-CONFIG_LOGO=y
-CONFIG_USB=y
-CONFIG_USB_DEVICEFS=y
-CONFIG_USB_MON=y
-CONFIG_USB_OHCI_HCD=y
-CONFIG_USB_STORAGE=y
-CONFIG_MMC=y
-CONFIG_SDIO_UART=y
-CONFIG_MMC_AT91=m
-CONFIG_EXT2_FS=y
-# CONFIG_DNOTIFY is not set
-CONFIG_AUTOFS_FS=y
-CONFIG_VFAT_FS=y
-CONFIG_TMPFS=y
-CONFIG_JFFS2_FS=y
-CONFIG_JFFS2_FS_WBUF_VERIFY=y
-CONFIG_NFS_FS=y
-CONFIG_ROOT_NFS=y
-# CONFIG_ENABLE_WARN_DEPRECATED is not set
-# CONFIG_ENABLE_MUST_CHECK is not set
-CONFIG_SYSCTL_SYSCALL_CHECK=y
-# CONFIG_CRYPTO_HW is not set
diff -druN linux-2.6.39-libre/arch/arm/configs/netx_defconfig linux-3.0-rc7-libre/arch/arm/configs/netx_defconfig
--- linux-2.6.39-libre/arch/arm/configs/netx_defconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/configs/netx_defconfig	2011-07-11 19:51:52.000000000 -0400
@@ -60,7 +60,7 @@
 # CONFIG_VGA_CONSOLE is not set
 CONFIG_FRAMEBUFFER_CONSOLE=y
 CONFIG_LOGO=y
-CONFIG_RTC_CLASS=m
+CONFIG_RTC_CLASS=y
 CONFIG_INOTIFY=y
 CONFIG_TMPFS=y
 CONFIG_JFFS2_FS=y
diff -druN linux-2.6.39-libre/arch/arm/configs/ns9xxx_defconfig linux-3.0-rc7-libre/arch/arm/configs/ns9xxx_defconfig
--- linux-2.6.39-libre/arch/arm/configs/ns9xxx_defconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/configs/ns9xxx_defconfig	1969-12-31 19:00:00.000000000 -0500
@@ -1,56 +0,0 @@
-CONFIG_IKCONFIG=y
-CONFIG_IKCONFIG_PROC=y
-CONFIG_BLK_DEV_INITRD=y
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-# CONFIG_IOSCHED_DEADLINE is not set
-# CONFIG_IOSCHED_CFQ is not set
-CONFIG_ARCH_NS9XXX=y
-CONFIG_MACH_CC9P9360DEV=y
-CONFIG_MACH_CC9P9360JS=y
-CONFIG_NO_HZ=y
-CONFIG_HIGH_RES_TIMERS=y
-CONFIG_FPE_NWFPE=y
-CONFIG_NET=y
-CONFIG_PACKET=m
-CONFIG_INET=y
-CONFIG_IP_PNP=y
-CONFIG_SYN_COOKIES=y
-CONFIG_MTD=m
-CONFIG_MTD_CONCAT=m
-CONFIG_MTD_CHAR=m
-CONFIG_MTD_BLOCK=m
-CONFIG_MTD_CFI=m
-CONFIG_MTD_JEDECPROBE=m
-CONFIG_MTD_CFI_AMDSTD=m
-CONFIG_MTD_PHYSMAP=m
-CONFIG_BLK_DEV_LOOP=m
-CONFIG_NETDEVICES=y
-CONFIG_NET_ETHERNET=y
-# CONFIG_SERIO_SERPORT is not set
-CONFIG_SERIAL_8250=y
-CONFIG_SERIAL_8250_CONSOLE=y
-# CONFIG_LEGACY_PTYS is not set
-# CONFIG_HW_RANDOM is not set
-CONFIG_I2C=m
-CONFIG_I2C_GPIO=m
-# CONFIG_HWMON is not set
-# CONFIG_VGA_CONSOLE is not set
-# CONFIG_USB_SUPPORT is not set
-CONFIG_NEW_LEDS=y
-CONFIG_LEDS_CLASS=m
-CONFIG_LEDS_GPIO=m
-CONFIG_LEDS_TRIGGERS=y
-CONFIG_LEDS_TRIGGER_TIMER=m
-CONFIG_LEDS_TRIGGER_HEARTBEAT=m
-CONFIG_RTC_CLASS=m
-CONFIG_EXT2_FS=m
-CONFIG_TMPFS=y
-CONFIG_JFFS2_FS=m
-CONFIG_NFS_FS=y
-CONFIG_ROOT_NFS=y
-# CONFIG_ENABLE_MUST_CHECK is not set
-CONFIG_DEBUG_KERNEL=y
-CONFIG_DEBUG_INFO=y
-CONFIG_DEBUG_USER=y
-CONFIG_DEBUG_ERRORS=y
diff -druN linux-2.6.39-libre/arch/arm/configs/omap2plus_defconfig linux-3.0-rc7-libre/arch/arm/configs/omap2plus_defconfig
--- linux-2.6.39-libre/arch/arm/configs/omap2plus_defconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/configs/omap2plus_defconfig	2011-07-11 19:51:52.000000000 -0400
@@ -21,58 +21,22 @@
 CONFIG_MODULE_SRCVERSION_ALL=y
 # CONFIG_BLK_DEV_BSG is not set
 CONFIG_ARCH_OMAP=y
-CONFIG_ARCH_OMAP2=y
-CONFIG_ARCH_OMAP3=y
-CONFIG_ARCH_OMAP4=y
 CONFIG_OMAP_RESET_CLOCKS=y
 CONFIG_OMAP_MUX_DEBUG=y
-CONFIG_OMAP_32K_TIMER=y
-CONFIG_MACH_OMAP_GENERIC=y
-CONFIG_ARCH_OMAP2420=y
-CONFIG_ARCH_OMAP2430=y
-CONFIG_ARCH_OMAP3430=y
-CONFIG_MACH_OMAP_H4=y
-CONFIG_MACH_OMAP_APOLLON=y
-CONFIG_MACH_OMAP_2430SDP=y
-CONFIG_MACH_OMAP3_BEAGLE=y
-CONFIG_MACH_DEVKIT8000=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_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_SBC3530=y
-CONFIG_MACH_OMAP_3630SDP=y
-CONFIG_MACH_OMAP_4430SDP=y
 CONFIG_ARM_THUMBEE=y
-CONFIG_ARM_L1_CACHE_SHIFT=5
 CONFIG_ARM_ERRATA_411920=y
 CONFIG_NO_HZ=y
 CONFIG_HIGH_RES_TIMERS=y
 CONFIG_SMP=y
 CONFIG_NR_CPUS=2
-# CONFIG_LOCAL_TIMERS is not set
-CONFIG_AEABI=y
 CONFIG_LEDS=y
 CONFIG_ZBOOT_ROM_TEXT=0x0
 CONFIG_ZBOOT_ROM_BSS=0x0
 CONFIG_CMDLINE="root=/dev/mmcblk0p2 rootwait console=ttyO2,115200"
 CONFIG_KEXEC=y
 CONFIG_FPE_NWFPE=y
-CONFIG_VFP=y
-CONFIG_NEON=y
 CONFIG_BINFMT_MISC=y
-CONFIG_PM=y
 CONFIG_PM_DEBUG=y
-CONFIG_PM_RUNTIME=y
 CONFIG_NET=y
 CONFIG_PACKET=y
 CONFIG_UNIX=y
@@ -89,14 +53,6 @@
 # CONFIG_IPV6 is not set
 CONFIG_NETFILTER=y
 CONFIG_BT=m
-CONFIG_BT_L2CAP=m
-CONFIG_BT_SCO=m
-CONFIG_BT_RFCOMM=y
-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
 CONFIG_BT_HCIUART=m
 CONFIG_BT_HCIUART_H4=y
 CONFIG_BT_HCIUART_BCSP=y
@@ -107,11 +63,9 @@
 CONFIG_MAC80211=m
 CONFIG_MAC80211_RC_PID=y
 CONFIG_MAC80211_RC_DEFAULT_PID=y
-CONFIG_MAC80211_LEDS=y
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 CONFIG_CONNECTOR=y
 CONFIG_MTD=y
-CONFIG_MTD_CONCAT=y
 CONFIG_MTD_CMDLINE_PARTS=y
 CONFIG_MTD_CHAR=y
 CONFIG_MTD_BLOCK=y
@@ -127,7 +81,6 @@
 CONFIG_BLK_DEV_LOOP=y
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_SIZE=16384
-CONFIG_EEPROM_LEGACY=y
 CONFIG_SCSI=y
 CONFIG_BLK_DEV_SD=y
 CONFIG_SCSI_MULTI_LUN=y
@@ -158,19 +111,15 @@
 CONFIG_INPUT_MISC=y
 CONFIG_INPUT_TWL4030_PWRBUTTON=y
 CONFIG_VT_HW_CONSOLE_BINDING=y
-CONFIG_SERIAL_8250=y
-CONFIG_SERIAL_8250_CONSOLE=y
+# CONFIG_LEGACY_PTYS is not set
 CONFIG_SERIAL_8250_NR_UARTS=32
 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
-# CONFIG_LEGACY_PTYS is not set
 CONFIG_HW_RANDOM=y
-CONFIG_I2C=y
 CONFIG_I2C_CHARDEV=y
-CONFIG_I2C_OMAP=y
 CONFIG_SPI=y
 CONFIG_SPI_OMAP24XX=y
 CONFIG_DEBUG_GPIO=y
@@ -181,10 +130,6 @@
 CONFIG_WATCHDOG=y
 CONFIG_OMAP_WATCHDOG=y
 CONFIG_TWL4030_WATCHDOG=y
-CONFIG_MENELAUS=y
-CONFIG_TWL4030_CORE=y
-CONFIG_TWL4030_POWER=y
-CONFIG_REGULATOR=y
 CONFIG_REGULATOR_TWL4030=y
 CONFIG_REGULATOR_TPS65023=y
 CONFIG_REGULATOR_TPS6507X=y
@@ -208,7 +153,6 @@
 CONFIG_LCD_CLASS_DEVICE=y
 CONFIG_LCD_PLATFORM=y
 CONFIG_DISPLAY_SUPPORT=y
-# CONFIG_VGA_CONSOLE is not set
 CONFIG_FRAMEBUFFER_CONSOLE=y
 CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y
 CONFIG_FONTS=y
@@ -217,25 +161,20 @@
 CONFIG_LOGO=y
 CONFIG_SOUND=m
 CONFIG_SND=m
-CONFIG_SND_MIXER_OSS=y
-CONFIG_SND_PCM_OSS=y
+CONFIG_SND_MIXER_OSS=m
+CONFIG_SND_PCM_OSS=m
 CONFIG_SND_VERBOSE_PRINTK=y
 CONFIG_SND_DEBUG=y
-CONFIG_SND_USB_AUDIO=y
-CONFIG_SND_SOC=y
-CONFIG_SND_OMAP_SOC=y
-CONFIG_SND_OMAP_SOC_OMAP3_PANDORA=y
+CONFIG_SND_USB_AUDIO=m
+CONFIG_SND_SOC=m
+CONFIG_SND_OMAP_SOC=m
+CONFIG_SND_OMAP_SOC_OMAP3_PANDORA=m
 CONFIG_USB=y
 CONFIG_USB_DEBUG=y
 CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
 CONFIG_USB_DEVICEFS=y
 CONFIG_USB_SUSPEND=y
-# CONFIG_USB_OTG_WHITELIST is not set
 CONFIG_USB_MON=y
-# CONFIG_USB_MUSB_HDRC is not set
-# CONFIG_USB_MUSB_OTG is not set
-# CONFIG_USB_GADGET_MUSB_HDRC is not set
-CONFIG_USB_MUSB_DEBUG=y
 CONFIG_USB_WDM=y
 CONFIG_USB_STORAGE=y
 CONFIG_USB_LIBUSUAL=y
@@ -250,18 +189,12 @@
 CONFIG_SDIO_UART=y
 CONFIG_MMC_OMAP=y
 CONFIG_MMC_OMAP_HS=y
-CONFIG_LEDS_CLASS=y
-CONFIG_LEDS_GPIO=y
-CONFIG_LEDS_TRIGGER_TIMER=y
-CONFIG_LEDS_TRIGGER_HEARTBEAT=y
-CONFIG_LEDS_TRIGGER_DEFAULT_ON=y
 CONFIG_RTC_CLASS=y
 CONFIG_RTC_DRV_TWL92330=y
 CONFIG_RTC_DRV_TWL4030=y
 CONFIG_EXT2_FS=y
 CONFIG_EXT3_FS=y
 # CONFIG_EXT3_FS_XATTR is not set
-CONFIG_INOTIFY=y
 CONFIG_QUOTA=y
 CONFIG_QFMT_V2=y
 CONFIG_MSDOS_FS=y
@@ -285,12 +218,10 @@
 CONFIG_NLS_ISO8859_1=y
 CONFIG_PRINTK_TIME=y
 CONFIG_MAGIC_SYSRQ=y
-CONFIG_DEBUG_FS=y
 CONFIG_DEBUG_KERNEL=y
 CONFIG_SCHEDSTATS=y
 CONFIG_TIMER_STATS=y
 CONFIG_PROVE_LOCKING=y
-# CONFIG_LOCK_STAT is not set
 CONFIG_DEBUG_SPINLOCK_SLEEP=y
 # CONFIG_DEBUG_BUGVERBOSE is not set
 CONFIG_DEBUG_INFO=y
diff -druN linux-2.6.39-libre/arch/arm/configs/realview_defconfig linux-3.0-rc7-libre/arch/arm/configs/realview_defconfig
--- linux-2.6.39-libre/arch/arm/configs/realview_defconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/configs/realview_defconfig	2011-07-11 19:51:52.000000000 -0400
@@ -37,7 +37,7 @@
 CONFIG_MTD_CFI=y
 CONFIG_MTD_CFI_INTELEXT=y
 CONFIG_MTD_CFI_AMDSTD=y
-CONFIG_MTD_ARM_INTEGRATOR=y
+CONFIG_MTD_PHYSMAP=y
 CONFIG_ARM_CHARLCD=y
 CONFIG_NETDEVICES=y
 CONFIG_SMSC_PHY=y
diff -druN linux-2.6.39-libre/arch/arm/configs/realview-smp_defconfig linux-3.0-rc7-libre/arch/arm/configs/realview-smp_defconfig
--- linux-2.6.39-libre/arch/arm/configs/realview-smp_defconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/configs/realview-smp_defconfig	2011-07-11 19:51:52.000000000 -0400
@@ -38,7 +38,7 @@
 CONFIG_MTD_CFI=y
 CONFIG_MTD_CFI_INTELEXT=y
 CONFIG_MTD_CFI_AMDSTD=y
-CONFIG_MTD_ARM_INTEGRATOR=y
+CONFIG_MTD_PHYSMAP=y
 CONFIG_ARM_CHARLCD=y
 CONFIG_NETDEVICES=y
 CONFIG_SMSC_PHY=y
diff -druN linux-2.6.39-libre/arch/arm/configs/s5p6442_defconfig linux-3.0-rc7-libre/arch/arm/configs/s5p6442_defconfig
--- linux-2.6.39-libre/arch/arm/configs/s5p6442_defconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/configs/s5p6442_defconfig	1969-12-31 19:00:00.000000000 -0500
@@ -1,65 +0,0 @@
-CONFIG_EXPERIMENTAL=y
-CONFIG_SYSFS_DEPRECATED_V2=y
-CONFIG_BLK_DEV_INITRD=y
-CONFIG_KALLSYMS_ALL=y
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-# CONFIG_BLK_DEV_BSG is not set
-CONFIG_ARCH_S5P6442=y
-CONFIG_S3C_LOWLEVEL_UART_PORT=1
-CONFIG_MACH_SMDK6442=y
-CONFIG_CPU_32v6K=y
-CONFIG_AEABI=y
-CONFIG_CMDLINE="root=/dev/ram0 rw ramdisk=8192 initrd=0x20800000,8M console=ttySAC1,115200 init=/linuxrc"
-CONFIG_FPE_NWFPE=y
-CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
-# CONFIG_PREVENT_FIRMWARE_BUILD is not set
-CONFIG_BLK_DEV_LOOP=y
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_SIZE=8192
-# CONFIG_MISC_DEVICES is not set
-CONFIG_SCSI=y
-CONFIG_BLK_DEV_SD=y
-CONFIG_CHR_DEV_SG=y
-CONFIG_INPUT_EVDEV=y
-# CONFIG_INPUT_KEYBOARD is not set
-# CONFIG_INPUT_MOUSE is not set
-CONFIG_INPUT_TOUCHSCREEN=y
-CONFIG_SERIAL_8250=y
-CONFIG_SERIAL_8250_NR_UARTS=3
-CONFIG_SERIAL_SAMSUNG=y
-CONFIG_SERIAL_SAMSUNG_CONSOLE=y
-CONFIG_HW_RANDOM=y
-# CONFIG_HWMON is not set
-# CONFIG_VGA_CONSOLE is not set
-# CONFIG_HID_SUPPORT is not set
-# CONFIG_USB_SUPPORT is not set
-CONFIG_EXT2_FS=y
-CONFIG_INOTIFY=y
-CONFIG_MSDOS_FS=y
-CONFIG_VFAT_FS=y
-CONFIG_TMPFS=y
-CONFIG_TMPFS_POSIX_ACL=y
-CONFIG_CRAMFS=y
-CONFIG_ROMFS_FS=y
-CONFIG_PARTITION_ADVANCED=y
-CONFIG_BSD_DISKLABEL=y
-CONFIG_SOLARIS_X86_PARTITION=y
-CONFIG_NLS_CODEPAGE_437=y
-CONFIG_NLS_ASCII=y
-CONFIG_NLS_ISO8859_1=y
-CONFIG_MAGIC_SYSRQ=y
-CONFIG_DEBUG_KERNEL=y
-CONFIG_DEBUG_RT_MUTEXES=y
-CONFIG_DEBUG_SPINLOCK=y
-CONFIG_DEBUG_MUTEXES=y
-CONFIG_DEBUG_SPINLOCK_SLEEP=y
-CONFIG_DEBUG_INFO=y
-# CONFIG_RCU_CPU_STALL_DETECTOR is not set
-CONFIG_SYSCTL_SYSCALL_CHECK=y
-# CONFIG_ARM_UNWIND is not set
-CONFIG_DEBUG_USER=y
-CONFIG_DEBUG_ERRORS=y
-CONFIG_DEBUG_LL=y
-CONFIG_DEBUG_S3C_UART=1
-CONFIG_CRC_CCITT=y
diff -druN linux-2.6.39-libre/arch/arm/configs/spear300_defconfig linux-3.0-rc7-libre/arch/arm/configs/spear300_defconfig
--- linux-2.6.39-libre/arch/arm/configs/spear300_defconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/configs/spear300_defconfig	1969-12-31 19:00:00.000000000 -0500
@@ -1,51 +0,0 @@
-CONFIG_EXPERIMENTAL=y
-CONFIG_SYSVIPC=y
-CONFIG_BSD_PROCESS_ACCT=y
-CONFIG_BLK_DEV_INITRD=y
-CONFIG_KALLSYMS_EXTRA_PASS=y
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-CONFIG_MODVERSIONS=y
-CONFIG_PLAT_SPEAR=y
-CONFIG_BINFMT_MISC=y
-CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_SIZE=16384
-CONFIG_INPUT_FF_MEMLESS=y
-# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
-# CONFIG_INPUT_KEYBOARD is not set
-# CONFIG_INPUT_MOUSE is not set
-CONFIG_SERIAL_AMBA_PL011=y
-CONFIG_SERIAL_AMBA_PL011_CONSOLE=y
-# CONFIG_LEGACY_PTYS is not set
-# CONFIG_HW_RANDOM is not set
-CONFIG_RAW_DRIVER=y
-CONFIG_MAX_RAW_DEVS=8192
-CONFIG_GPIO_SYSFS=y
-CONFIG_GPIO_PL061=y
-# CONFIG_HWMON is not set
-# CONFIG_VGA_CONSOLE is not set
-# CONFIG_HID_SUPPORT is not set
-# CONFIG_USB_SUPPORT is not set
-CONFIG_EXT2_FS=y
-CONFIG_EXT2_FS_XATTR=y
-CONFIG_EXT2_FS_SECURITY=y
-CONFIG_EXT3_FS=y
-CONFIG_EXT3_FS_SECURITY=y
-CONFIG_AUTOFS4_FS=m
-CONFIG_MSDOS_FS=m
-CONFIG_VFAT_FS=m
-CONFIG_FAT_DEFAULT_IOCHARSET="ascii"
-CONFIG_TMPFS=y
-CONFIG_PARTITION_ADVANCED=y
-CONFIG_NLS=y
-CONFIG_NLS_DEFAULT="utf8"
-CONFIG_NLS_CODEPAGE_437=y
-CONFIG_NLS_ASCII=m
-CONFIG_MAGIC_SYSRQ=y
-CONFIG_DEBUG_FS=y
-CONFIG_DEBUG_KERNEL=y
-CONFIG_DEBUG_SPINLOCK=y
-CONFIG_DEBUG_SPINLOCK_SLEEP=y
-CONFIG_DEBUG_INFO=y
-# CONFIG_CRC32 is not set
diff -druN linux-2.6.39-libre/arch/arm/configs/spear310_defconfig linux-3.0-rc7-libre/arch/arm/configs/spear310_defconfig
--- linux-2.6.39-libre/arch/arm/configs/spear310_defconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/configs/spear310_defconfig	1969-12-31 19:00:00.000000000 -0500
@@ -1,52 +0,0 @@
-CONFIG_EXPERIMENTAL=y
-CONFIG_SYSVIPC=y
-CONFIG_BSD_PROCESS_ACCT=y
-CONFIG_BLK_DEV_INITRD=y
-CONFIG_KALLSYMS_EXTRA_PASS=y
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-CONFIG_MODVERSIONS=y
-CONFIG_PLAT_SPEAR=y
-CONFIG_MACH_SPEAR310=y
-CONFIG_BINFMT_MISC=y
-CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_SIZE=16384
-CONFIG_INPUT_FF_MEMLESS=y
-# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
-# CONFIG_INPUT_KEYBOARD is not set
-# CONFIG_INPUT_MOUSE is not set
-CONFIG_SERIAL_AMBA_PL011=y
-CONFIG_SERIAL_AMBA_PL011_CONSOLE=y
-# CONFIG_LEGACY_PTYS is not set
-# CONFIG_HW_RANDOM is not set
-CONFIG_RAW_DRIVER=y
-CONFIG_MAX_RAW_DEVS=8192
-CONFIG_GPIO_SYSFS=y
-CONFIG_GPIO_PL061=y
-# CONFIG_HWMON is not set
-# CONFIG_VGA_CONSOLE is not set
-# CONFIG_HID_SUPPORT is not set
-# CONFIG_USB_SUPPORT is not set
-CONFIG_EXT2_FS=y
-CONFIG_EXT2_FS_XATTR=y
-CONFIG_EXT2_FS_SECURITY=y
-CONFIG_EXT3_FS=y
-CONFIG_EXT3_FS_SECURITY=y
-CONFIG_AUTOFS4_FS=m
-CONFIG_MSDOS_FS=m
-CONFIG_VFAT_FS=m
-CONFIG_FAT_DEFAULT_IOCHARSET="ascii"
-CONFIG_TMPFS=y
-CONFIG_PARTITION_ADVANCED=y
-CONFIG_NLS=y
-CONFIG_NLS_DEFAULT="utf8"
-CONFIG_NLS_CODEPAGE_437=y
-CONFIG_NLS_ASCII=m
-CONFIG_MAGIC_SYSRQ=y
-CONFIG_DEBUG_FS=y
-CONFIG_DEBUG_KERNEL=y
-CONFIG_DEBUG_SPINLOCK=y
-CONFIG_DEBUG_SPINLOCK_SLEEP=y
-CONFIG_DEBUG_INFO=y
-# CONFIG_CRC32 is not set
diff -druN linux-2.6.39-libre/arch/arm/configs/spear320_defconfig linux-3.0-rc7-libre/arch/arm/configs/spear320_defconfig
--- linux-2.6.39-libre/arch/arm/configs/spear320_defconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/configs/spear320_defconfig	1969-12-31 19:00:00.000000000 -0500
@@ -1,52 +0,0 @@
-CONFIG_EXPERIMENTAL=y
-CONFIG_SYSVIPC=y
-CONFIG_BSD_PROCESS_ACCT=y
-CONFIG_BLK_DEV_INITRD=y
-CONFIG_KALLSYMS_EXTRA_PASS=y
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-CONFIG_MODVERSIONS=y
-CONFIG_PLAT_SPEAR=y
-CONFIG_MACH_SPEAR320=y
-CONFIG_BINFMT_MISC=y
-CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_SIZE=16384
-CONFIG_INPUT_FF_MEMLESS=y
-# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
-# CONFIG_INPUT_KEYBOARD is not set
-# CONFIG_INPUT_MOUSE is not set
-CONFIG_SERIAL_AMBA_PL011=y
-CONFIG_SERIAL_AMBA_PL011_CONSOLE=y
-# CONFIG_LEGACY_PTYS is not set
-# CONFIG_HW_RANDOM is not set
-CONFIG_RAW_DRIVER=y
-CONFIG_MAX_RAW_DEVS=8192
-CONFIG_GPIO_SYSFS=y
-CONFIG_GPIO_PL061=y
-# CONFIG_HWMON is not set
-# CONFIG_VGA_CONSOLE is not set
-# CONFIG_HID_SUPPORT is not set
-# CONFIG_USB_SUPPORT is not set
-CONFIG_EXT2_FS=y
-CONFIG_EXT2_FS_XATTR=y
-CONFIG_EXT2_FS_SECURITY=y
-CONFIG_EXT3_FS=y
-CONFIG_EXT3_FS_SECURITY=y
-CONFIG_AUTOFS4_FS=m
-CONFIG_MSDOS_FS=m
-CONFIG_VFAT_FS=m
-CONFIG_FAT_DEFAULT_IOCHARSET="ascii"
-CONFIG_TMPFS=y
-CONFIG_PARTITION_ADVANCED=y
-CONFIG_NLS=y
-CONFIG_NLS_DEFAULT="utf8"
-CONFIG_NLS_CODEPAGE_437=y
-CONFIG_NLS_ASCII=m
-CONFIG_MAGIC_SYSRQ=y
-CONFIG_DEBUG_FS=y
-CONFIG_DEBUG_KERNEL=y
-CONFIG_DEBUG_SPINLOCK=y
-CONFIG_DEBUG_SPINLOCK_SLEEP=y
-CONFIG_DEBUG_INFO=y
-# CONFIG_CRC32 is not set
diff -druN linux-2.6.39-libre/arch/arm/configs/spear3xx_defconfig linux-3.0-rc7-libre/arch/arm/configs/spear3xx_defconfig
--- linux-2.6.39-libre/arch/arm/configs/spear3xx_defconfig	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/arm/configs/spear3xx_defconfig	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,53 @@
+CONFIG_EXPERIMENTAL=y
+CONFIG_SYSVIPC=y
+CONFIG_BSD_PROCESS_ACCT=y
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_KALLSYMS_EXTRA_PASS=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODVERSIONS=y
+CONFIG_PLAT_SPEAR=y
+CONFIG_BOARD_SPEAR300_EVB=y
+CONFIG_BOARD_SPEAR310_EVB=y
+CONFIG_BOARD_SPEAR320_EVB=y
+CONFIG_BINFMT_MISC=y
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=16384
+CONFIG_INPUT_FF_MEMLESS=y
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+CONFIG_SERIAL_AMBA_PL011=y
+CONFIG_SERIAL_AMBA_PL011_CONSOLE=y
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_HW_RANDOM is not set
+CONFIG_RAW_DRIVER=y
+CONFIG_MAX_RAW_DEVS=8192
+CONFIG_GPIO_SYSFS=y
+CONFIG_GPIO_PL061=y
+# CONFIG_HWMON is not set
+# CONFIG_HID_SUPPORT is not set
+# CONFIG_USB_SUPPORT is not set
+CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XATTR=y
+CONFIG_EXT2_FS_SECURITY=y
+CONFIG_EXT3_FS=y
+CONFIG_EXT3_FS_SECURITY=y
+CONFIG_AUTOFS4_FS=m
+CONFIG_MSDOS_FS=m
+CONFIG_VFAT_FS=m
+CONFIG_FAT_DEFAULT_IOCHARSET="ascii"
+CONFIG_TMPFS=y
+CONFIG_PARTITION_ADVANCED=y
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="utf8"
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_ASCII=m
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_DEBUG_FS=y
+CONFIG_DEBUG_KERNEL=y
+CONFIG_DEBUG_SPINLOCK=y
+CONFIG_DEBUG_SPINLOCK_SLEEP=y
+CONFIG_DEBUG_INFO=y
+# CONFIG_CRC32 is not set
diff -druN linux-2.6.39-libre/arch/arm/configs/spear600_defconfig linux-3.0-rc7-libre/arch/arm/configs/spear600_defconfig
--- linux-2.6.39-libre/arch/arm/configs/spear600_defconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/configs/spear600_defconfig	1969-12-31 19:00:00.000000000 -0500
@@ -1,49 +0,0 @@
-CONFIG_EXPERIMENTAL=y
-CONFIG_SYSVIPC=y
-CONFIG_BSD_PROCESS_ACCT=y
-CONFIG_BLK_DEV_INITRD=y
-CONFIG_KALLSYMS_EXTRA_PASS=y
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-CONFIG_MODVERSIONS=y
-CONFIG_PLAT_SPEAR=y
-CONFIG_ARCH_SPEAR6XX=y
-CONFIG_BINFMT_MISC=y
-CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_SIZE=16384
-CONFIG_INPUT_FF_MEMLESS=y
-# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
-CONFIG_SERIAL_AMBA_PL011=y
-CONFIG_SERIAL_AMBA_PL011_CONSOLE=y
-# CONFIG_LEGACY_PTYS is not set
-CONFIG_RAW_DRIVER=y
-CONFIG_MAX_RAW_DEVS=8192
-CONFIG_GPIO_SYSFS=y
-CONFIG_GPIO_PL061=y
-# CONFIG_HWMON is not set
-# CONFIG_VGA_CONSOLE is not set
-# CONFIG_HID_SUPPORT is not set
-# CONFIG_USB_SUPPORT is not set
-CONFIG_EXT2_FS=y
-CONFIG_EXT2_FS_XATTR=y
-CONFIG_EXT2_FS_SECURITY=y
-CONFIG_EXT3_FS=y
-CONFIG_EXT3_FS_SECURITY=y
-CONFIG_AUTOFS4_FS=m
-CONFIG_MSDOS_FS=m
-CONFIG_VFAT_FS=m
-CONFIG_FAT_DEFAULT_IOCHARSET="ascii"
-CONFIG_TMPFS=y
-CONFIG_PARTITION_ADVANCED=y
-CONFIG_NLS=y
-CONFIG_NLS_DEFAULT="utf8"
-CONFIG_NLS_CODEPAGE_437=y
-CONFIG_NLS_ASCII=m
-CONFIG_MAGIC_SYSRQ=y
-CONFIG_DEBUG_FS=y
-CONFIG_DEBUG_KERNEL=y
-CONFIG_DEBUG_SPINLOCK=y
-CONFIG_DEBUG_SPINLOCK_SLEEP=y
-CONFIG_DEBUG_INFO=y
-# CONFIG_CRC32 is not set
diff -druN linux-2.6.39-libre/arch/arm/configs/spear6xx_defconfig linux-3.0-rc7-libre/arch/arm/configs/spear6xx_defconfig
--- linux-2.6.39-libre/arch/arm/configs/spear6xx_defconfig	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/arm/configs/spear6xx_defconfig	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,49 @@
+CONFIG_EXPERIMENTAL=y
+CONFIG_SYSVIPC=y
+CONFIG_BSD_PROCESS_ACCT=y
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_KALLSYMS_EXTRA_PASS=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODVERSIONS=y
+CONFIG_PLAT_SPEAR=y
+CONFIG_ARCH_SPEAR6XX=y
+CONFIG_BOARD_SPEAR600_EVB=y
+CONFIG_BINFMT_MISC=y
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=16384
+CONFIG_INPUT_FF_MEMLESS=y
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+CONFIG_SERIAL_AMBA_PL011=y
+CONFIG_SERIAL_AMBA_PL011_CONSOLE=y
+# CONFIG_LEGACY_PTYS is not set
+CONFIG_RAW_DRIVER=y
+CONFIG_MAX_RAW_DEVS=8192
+CONFIG_GPIO_SYSFS=y
+CONFIG_GPIO_PL061=y
+# CONFIG_HWMON is not set
+# CONFIG_HID_SUPPORT is not set
+# CONFIG_USB_SUPPORT is not set
+CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XATTR=y
+CONFIG_EXT2_FS_SECURITY=y
+CONFIG_EXT3_FS=y
+CONFIG_EXT3_FS_SECURITY=y
+CONFIG_AUTOFS4_FS=m
+CONFIG_MSDOS_FS=m
+CONFIG_VFAT_FS=m
+CONFIG_FAT_DEFAULT_IOCHARSET="ascii"
+CONFIG_TMPFS=y
+CONFIG_PARTITION_ADVANCED=y
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="utf8"
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_ASCII=m
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_DEBUG_FS=y
+CONFIG_DEBUG_KERNEL=y
+CONFIG_DEBUG_SPINLOCK=y
+CONFIG_DEBUG_SPINLOCK_SLEEP=y
+CONFIG_DEBUG_INFO=y
+# CONFIG_CRC32 is not set
diff -druN linux-2.6.39-libre/arch/arm/configs/stmp378x_defconfig linux-3.0-rc7-libre/arch/arm/configs/stmp378x_defconfig
--- linux-2.6.39-libre/arch/arm/configs/stmp378x_defconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/configs/stmp378x_defconfig	1969-12-31 19:00:00.000000000 -0500
@@ -1,128 +0,0 @@
-CONFIG_EXPERIMENTAL=y
-CONFIG_LOCALVERSION="-default"
-CONFIG_SYSVIPC=y
-CONFIG_POSIX_MQUEUE=y
-CONFIG_BSD_PROCESS_ACCT=y
-CONFIG_SYSFS_DEPRECATED_V2=y
-CONFIG_BLK_DEV_INITRD=y
-CONFIG_EXPERT=y
-CONFIG_SLAB=y
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-CONFIG_MODULE_FORCE_UNLOAD=y
-CONFIG_MODVERSIONS=y
-CONFIG_MODULE_SRCVERSION_ALL=y
-# CONFIG_BLK_DEV_BSG is not set
-CONFIG_ARCH_STMP3XXX=y
-CONFIG_ARCH_STMP378X=y
-CONFIG_NO_HZ=y
-CONFIG_HIGH_RES_TIMERS=y
-CONFIG_PREEMPT=y
-CONFIG_AEABI=y
-CONFIG_HIGHMEM=y
-CONFIG_ZBOOT_ROM_TEXT=0x0
-CONFIG_ZBOOT_ROM_BSS=0x0
-CONFIG_CMDLINE="console=ttySDBG0,115200 mem=32M"
-CONFIG_NET=y
-CONFIG_PACKET=y
-CONFIG_UNIX=y
-CONFIG_INET=y
-CONFIG_IP_MULTICAST=y
-CONFIG_IP_ADVANCED_ROUTER=y
-CONFIG_IP_MULTIPLE_TABLES=y
-CONFIG_IP_ROUTE_MULTIPATH=y
-CONFIG_IP_ROUTE_VERBOSE=y
-CONFIG_IP_PNP=y
-CONFIG_IP_PNP_DHCP=y
-CONFIG_IP_PNP_BOOTP=y
-CONFIG_IP_MROUTE=y
-CONFIG_IP_PIMSM_V1=y
-CONFIG_IP_PIMSM_V2=y
-CONFIG_SYN_COOKIES=y
-# CONFIG_INET_LRO is not set
-# CONFIG_IPV6 is not set
-CONFIG_NET_SCHED=y
-# CONFIG_WIRELESS is not set
-CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
-# CONFIG_STANDALONE is not set
-CONFIG_MTD=y
-CONFIG_MTD_CHAR=y
-CONFIG_MTD_NAND=y
-CONFIG_MTD_UBI=y
-CONFIG_MTD_UBI_GLUEBI=y
-CONFIG_BLK_DEV_LOOP=y
-CONFIG_BLK_DEV_CRYPTOLOOP=y
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_COUNT=4
-CONFIG_BLK_DEV_RAM_SIZE=6144
-# CONFIG_MISC_DEVICES is not set
-CONFIG_SCSI=y
-CONFIG_BLK_DEV_SD=y
-CONFIG_CHR_DEV_SG=y
-# CONFIG_SCSI_LOWLEVEL is not set
-CONFIG_INPUT_POLLDEV=y
-CONFIG_INPUT_MOUSEDEV_SCREEN_X=320
-CONFIG_INPUT_MOUSEDEV_SCREEN_Y=240
-CONFIG_INPUT_EVDEV=y
-# CONFIG_KEYBOARD_ATKBD is not set
-# CONFIG_INPUT_MOUSE is not set
-CONFIG_INPUT_TOUCHSCREEN=y
-CONFIG_INPUT_MISC=y
-# CONFIG_SERIO_SERPORT is not set
-CONFIG_VT_HW_CONSOLE_BINDING=y
-# CONFIG_LEGACY_PTYS is not set
-CONFIG_HW_RANDOM=y
-CONFIG_DEBUG_GPIO=y
-CONFIG_GPIO_SYSFS=y
-# CONFIG_HWMON is not set
-CONFIG_FB=y
-CONFIG_BACKLIGHT_LCD_SUPPORT=y
-CONFIG_LCD_CLASS_DEVICE=y
-CONFIG_BACKLIGHT_CLASS_DEVICE=y
-# CONFIG_VGA_CONSOLE is not set
-CONFIG_FRAMEBUFFER_CONSOLE=y
-CONFIG_LOGO=y
-# CONFIG_HID_SUPPORT is not set
-# CONFIG_USB_SUPPORT is not set
-# CONFIG_DNOTIFY is not set
-CONFIG_TMPFS=y
-CONFIG_CONFIGFS_FS=m
-# CONFIG_MISC_FILESYSTEMS is not set
-# CONFIG_NETWORK_FILESYSTEMS is not set
-# CONFIG_ENABLE_MUST_CHECK is not set
-CONFIG_STRIP_ASM_SYMS=y
-CONFIG_DEBUG_KERNEL=y
-CONFIG_DEBUG_SHIRQ=y
-# CONFIG_SCHED_DEBUG is not set
-CONFIG_DEBUG_OBJECTS=y
-CONFIG_DEBUG_OBJECTS_SELFTEST=y
-CONFIG_DEBUG_OBJECTS_FREE=y
-CONFIG_DEBUG_OBJECTS_TIMERS=y
-CONFIG_DEBUG_SLAB=y
-CONFIG_DEBUG_SLAB_LEAK=y
-CONFIG_DEBUG_RT_MUTEXES=y
-CONFIG_PROVE_LOCKING=y
-CONFIG_DEBUG_SPINLOCK_SLEEP=y
-CONFIG_DEBUG_KOBJECT=y
-# CONFIG_DEBUG_BUGVERBOSE is not set
-CONFIG_DEBUG_INFO=y
-# CONFIG_RCU_CPU_STALL_DETECTOR is not set
-CONFIG_SYSCTL_SYSCALL_CHECK=y
-CONFIG_BOOT_TRACER=y
-CONFIG_STACK_TRACER=y
-CONFIG_BLK_DEV_IO_TRACE=y
-CONFIG_KEYS=y
-CONFIG_KEYS_DEBUG_PROC_KEYS=y
-CONFIG_SECURITY=y
-CONFIG_CRYPTO_TEST=m
-CONFIG_CRYPTO_ECB=y
-CONFIG_CRYPTO_HMAC=y
-CONFIG_CRYPTO_MD5=y
-CONFIG_CRYPTO_SHA1=m
-CONFIG_CRYPTO_AES=m
-CONFIG_CRYPTO_DES=y
-CONFIG_CRYPTO_DEFLATE=y
-CONFIG_CRYPTO_LZO=y
-# CONFIG_CRYPTO_ANSI_CPRNG is not set
-CONFIG_CRC_CCITT=m
-CONFIG_CRC16=y
diff -druN linux-2.6.39-libre/arch/arm/configs/stmp37xx_defconfig linux-3.0-rc7-libre/arch/arm/configs/stmp37xx_defconfig
--- linux-2.6.39-libre/arch/arm/configs/stmp37xx_defconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/configs/stmp37xx_defconfig	1969-12-31 19:00:00.000000000 -0500
@@ -1,108 +0,0 @@
-CONFIG_EXPERIMENTAL=y
-CONFIG_LOCALVERSION="-default"
-CONFIG_SYSVIPC=y
-CONFIG_POSIX_MQUEUE=y
-CONFIG_BSD_PROCESS_ACCT=y
-CONFIG_SYSFS_DEPRECATED_V2=y
-CONFIG_BLK_DEV_INITRD=y
-CONFIG_EXPERT=y
-CONFIG_SLAB=y
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-CONFIG_MODULE_FORCE_UNLOAD=y
-CONFIG_MODVERSIONS=y
-CONFIG_MODULE_SRCVERSION_ALL=y
-# CONFIG_BLK_DEV_BSG is not set
-CONFIG_ARCH_STMP3XXX=y
-CONFIG_NO_HZ=y
-CONFIG_HIGH_RES_TIMERS=y
-CONFIG_PREEMPT=y
-CONFIG_AEABI=y
-CONFIG_ZBOOT_ROM_TEXT=0x0
-CONFIG_ZBOOT_ROM_BSS=0x0
-CONFIG_CMDLINE="console=ttySDBG0,115200 mem=32M lcd_panel=lms350 rdinit=/bin/sh ignore_loglevel"
-CONFIG_NET=y
-CONFIG_PACKET=y
-CONFIG_UNIX=y
-CONFIG_INET=y
-CONFIG_IP_MULTICAST=y
-CONFIG_IP_ADVANCED_ROUTER=y
-CONFIG_IP_MULTIPLE_TABLES=y
-CONFIG_IP_ROUTE_MULTIPATH=y
-CONFIG_IP_ROUTE_VERBOSE=y
-CONFIG_IP_PNP=y
-CONFIG_IP_PNP_DHCP=y
-CONFIG_IP_PNP_BOOTP=y
-CONFIG_IP_MROUTE=y
-CONFIG_IP_PIMSM_V1=y
-CONFIG_IP_PIMSM_V2=y
-CONFIG_SYN_COOKIES=y
-# CONFIG_INET_LRO is not set
-# CONFIG_IPV6 is not set
-CONFIG_NET_SCHED=y
-# CONFIG_WIRELESS is not set
-CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
-# CONFIG_STANDALONE is not set
-CONFIG_BLK_DEV_LOOP=y
-CONFIG_BLK_DEV_CRYPTOLOOP=y
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_COUNT=4
-CONFIG_BLK_DEV_RAM_SIZE=6144
-# CONFIG_MISC_DEVICES is not set
-CONFIG_SCSI=y
-CONFIG_BLK_DEV_SD=y
-CONFIG_CHR_DEV_SG=y
-# CONFIG_SCSI_LOWLEVEL is not set
-CONFIG_INPUT_POLLDEV=y
-CONFIG_INPUT_MOUSEDEV_SCREEN_X=320
-CONFIG_INPUT_MOUSEDEV_SCREEN_Y=240
-CONFIG_INPUT_EVDEV=y
-# CONFIG_KEYBOARD_ATKBD is not set
-# CONFIG_INPUT_MOUSE is not set
-CONFIG_INPUT_TOUCHSCREEN=y
-CONFIG_INPUT_MISC=y
-# CONFIG_SERIO_SERPORT is not set
-CONFIG_VT_HW_CONSOLE_BINDING=y
-# CONFIG_LEGACY_PTYS is not set
-CONFIG_HW_RANDOM=y
-CONFIG_DEBUG_GPIO=y
-CONFIG_GPIO_SYSFS=y
-# CONFIG_HWMON is not set
-CONFIG_FB=y
-CONFIG_BACKLIGHT_LCD_SUPPORT=y
-CONFIG_LCD_CLASS_DEVICE=y
-CONFIG_BACKLIGHT_CLASS_DEVICE=y
-# CONFIG_VGA_CONSOLE is not set
-CONFIG_FRAMEBUFFER_CONSOLE=y
-CONFIG_LOGO=y
-# CONFIG_HID_SUPPORT is not set
-# CONFIG_USB_SUPPORT is not set
-# CONFIG_DNOTIFY is not set
-CONFIG_TMPFS=y
-CONFIG_CONFIGFS_FS=m
-# CONFIG_MISC_FILESYSTEMS is not set
-# CONFIG_NETWORK_FILESYSTEMS is not set
-# CONFIG_ENABLE_MUST_CHECK is not set
-CONFIG_DEBUG_KERNEL=y
-# CONFIG_DEBUG_BUGVERBOSE is not set
-# CONFIG_RCU_CPU_STALL_DETECTOR is not set
-CONFIG_SYSCTL_SYSCALL_CHECK=y
-CONFIG_BOOT_TRACER=y
-CONFIG_STACK_TRACER=y
-CONFIG_BLK_DEV_IO_TRACE=y
-CONFIG_DEBUG_LL=y
-CONFIG_KEYS=y
-CONFIG_KEYS_DEBUG_PROC_KEYS=y
-CONFIG_SECURITY=y
-CONFIG_CRYPTO_TEST=m
-CONFIG_CRYPTO_ECB=y
-CONFIG_CRYPTO_HMAC=y
-CONFIG_CRYPTO_MD5=y
-CONFIG_CRYPTO_SHA1=m
-CONFIG_CRYPTO_AES=m
-CONFIG_CRYPTO_DES=y
-CONFIG_CRYPTO_DEFLATE=y
-CONFIG_CRYPTO_LZO=y
-# CONFIG_CRYPTO_ANSI_CPRNG is not set
-CONFIG_CRC_CCITT=m
-CONFIG_CRC16=y
diff -druN linux-2.6.39-libre/arch/arm/configs/usb-a9263_defconfig linux-3.0-rc7-libre/arch/arm/configs/usb-a9263_defconfig
--- linux-2.6.39-libre/arch/arm/configs/usb-a9263_defconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/configs/usb-a9263_defconfig	1969-12-31 19:00:00.000000000 -0500
@@ -1,106 +0,0 @@
-CONFIG_EXPERIMENTAL=y
-# CONFIG_LOCALVERSION_AUTO is not set
-# CONFIG_SWAP is not set
-CONFIG_SYSVIPC=y
-CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
-CONFIG_SLAB=y
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-# CONFIG_BLK_DEV_BSG is not set
-# CONFIG_IOSCHED_DEADLINE is not set
-# CONFIG_IOSCHED_CFQ is not set
-CONFIG_ARCH_AT91=y
-CONFIG_ARCH_AT91SAM9263=y
-CONFIG_MACH_USB_A9263=y
-CONFIG_AT91_SLOW_CLOCK=y
-# CONFIG_ARM_THUMB is not set
-CONFIG_AEABI=y
-CONFIG_ZBOOT_ROM_TEXT=0x0
-CONFIG_ZBOOT_ROM_BSS=0x0
-CONFIG_CMDLINE="mem=64M console=ttyS0,115200"
-CONFIG_FPE_NWFPE=y
-CONFIG_PM=y
-CONFIG_NET=y
-CONFIG_PACKET=y
-CONFIG_UNIX=y
-CONFIG_INET=y
-CONFIG_IP_MULTICAST=y
-CONFIG_IP_ADVANCED_ROUTER=y
-CONFIG_IP_ROUTE_VERBOSE=y
-CONFIG_IP_PNP=y
-CONFIG_IP_PNP_BOOTP=y
-CONFIG_IP_PNP_RARP=y
-CONFIG_IP_MROUTE=y
-CONFIG_IP_PIMSM_V1=y
-CONFIG_IP_PIMSM_V2=y
-# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
-# CONFIG_INET_XFRM_MODE_TUNNEL is not set
-# CONFIG_INET_XFRM_MODE_BEET is not set
-# CONFIG_INET_LRO is not set
-# CONFIG_INET_DIAG is not set
-# CONFIG_IPV6 is not set
-CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
-CONFIG_MTD=y
-CONFIG_MTD_PARTITIONS=y
-CONFIG_MTD_CMDLINE_PARTS=y
-CONFIG_MTD_CHAR=y
-CONFIG_MTD_BLOCK=y
-CONFIG_MTD_DATAFLASH=y
-CONFIG_MTD_NAND=y
-CONFIG_MTD_NAND_ATMEL=y
-CONFIG_MTD_NAND_ATMEL_ECC_SOFT=y
-CONFIG_BLK_DEV_LOOP=y
-# CONFIG_MISC_DEVICES is not set
-CONFIG_SCSI=y
-CONFIG_BLK_DEV_SD=y
-CONFIG_SCSI_MULTI_LUN=y
-CONFIG_NETDEVICES=y
-CONFIG_NET_ETHERNET=y
-CONFIG_MII=y
-CONFIG_MACB=y
-# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
-CONFIG_INPUT_EVDEV=y
-CONFIG_INPUT_EVBUG=y
-# CONFIG_KEYBOARD_ATKBD is not set
-CONFIG_KEYBOARD_GPIO=y
-# CONFIG_INPUT_MOUSE is not set
-# CONFIG_SERIO is not set
-CONFIG_SERIAL_ATMEL=y
-CONFIG_SERIAL_ATMEL_CONSOLE=y
-CONFIG_HW_RANDOM=y
-CONFIG_SPI=y
-CONFIG_SPI_ATMEL=y
-# CONFIG_HWMON is not set
-# CONFIG_VGA_CONSOLE is not set
-# CONFIG_USB_HID is not set
-CONFIG_USB=y
-CONFIG_USB_DEVICEFS=y
-CONFIG_USB_MON=y
-CONFIG_USB_OHCI_HCD=y
-CONFIG_USB_STORAGE=y
-CONFIG_USB_GADGET=y
-CONFIG_USB_ETH=m
-CONFIG_NEW_LEDS=y
-CONFIG_LEDS_CLASS=y
-CONFIG_LEDS_GPIO=y
-CONFIG_LEDS_TRIGGERS=y
-CONFIG_LEDS_TRIGGER_HEARTBEAT=y
-CONFIG_EXT2_FS=y
-CONFIG_INOTIFY=y
-CONFIG_FUSE_FS=m
-CONFIG_VFAT_FS=y
-CONFIG_TMPFS=y
-CONFIG_JFFS2_FS=y
-CONFIG_NFS_FS=y
-CONFIG_NFS_V3=y
-CONFIG_NFS_V3_ACL=y
-CONFIG_NFS_V4=y
-CONFIG_ROOT_NFS=y
-CONFIG_NLS_CODEPAGE_437=y
-CONFIG_NLS_CODEPAGE_850=y
-CONFIG_NLS_ISO8859_1=y
-CONFIG_DEBUG_KERNEL=y
-CONFIG_DEBUG_USER=y
-CONFIG_DEBUG_LL=y
-# CONFIG_CRYPTO_HW is not set
diff -druN linux-2.6.39-libre/arch/arm/configs/versatile_defconfig linux-3.0-rc7-libre/arch/arm/configs/versatile_defconfig
--- linux-2.6.39-libre/arch/arm/configs/versatile_defconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/configs/versatile_defconfig	2011-07-11 19:51:52.000000000 -0400
@@ -32,7 +32,7 @@
 CONFIG_MTD_CFI=y
 CONFIG_MTD_CFI_ADV_OPTIONS=y
 CONFIG_MTD_CFI_INTELEXT=y
-CONFIG_MTD_ARM_INTEGRATOR=y
+CONFIG_MTD_PHYSMAP=y
 CONFIG_BLK_DEV_RAM=y
 CONFIG_EEPROM_LEGACY=m
 CONFIG_NETDEVICES=y
diff -druN linux-2.6.39-libre/arch/arm/configs/viper_defconfig linux-3.0-rc7-libre/arch/arm/configs/viper_defconfig
--- linux-2.6.39-libre/arch/arm/configs/viper_defconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/configs/viper_defconfig	2011-07-11 19:51:52.000000000 -0400
@@ -142,7 +142,7 @@
 CONFIG_USB_FILE_STORAGE=m
 CONFIG_USB_G_SERIAL=m
 CONFIG_USB_G_PRINTER=m
-CONFIG_RTC_CLASS=m
+CONFIG_RTC_CLASS=y
 CONFIG_RTC_DRV_DS1307=m
 CONFIG_RTC_DRV_SA1100=m
 CONFIG_EXT2_FS=m
diff -druN linux-2.6.39-libre/arch/arm/configs/xcep_defconfig linux-3.0-rc7-libre/arch/arm/configs/xcep_defconfig
--- linux-2.6.39-libre/arch/arm/configs/xcep_defconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/configs/xcep_defconfig	2011-07-11 19:51:52.000000000 -0400
@@ -73,7 +73,7 @@
 # CONFIG_VGA_CONSOLE is not set
 # CONFIG_HID_SUPPORT is not set
 # CONFIG_USB_SUPPORT is not set
-CONFIG_RTC_CLASS=m
+CONFIG_RTC_CLASS=y
 CONFIG_RTC_DRV_SA1100=m
 CONFIG_DMADEVICES=y
 # CONFIG_DNOTIFY is not set
diff -druN linux-2.6.39-libre/arch/arm/configs/zeus_defconfig linux-3.0-rc7-libre/arch/arm/configs/zeus_defconfig
--- linux-2.6.39-libre/arch/arm/configs/zeus_defconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/configs/zeus_defconfig	2011-07-11 19:51:52.000000000 -0400
@@ -158,7 +158,7 @@
 CONFIG_LEDS_TRIGGER_BACKLIGHT=m
 CONFIG_LEDS_TRIGGER_GPIO=m
 CONFIG_LEDS_TRIGGER_DEFAULT_ON=m
-CONFIG_RTC_CLASS=m
+CONFIG_RTC_CLASS=y
 CONFIG_RTC_DRV_ISL1208=m
 CONFIG_RTC_DRV_PXA=m
 CONFIG_EXT2_FS=y
diff -druN linux-2.6.39-libre/arch/arm/include/asm/assembler.h linux-3.0-rc7-libre/arch/arm/include/asm/assembler.h
--- linux-2.6.39-libre/arch/arm/include/asm/assembler.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/include/asm/assembler.h	2011-07-11 19:51:52.000000000 -0400
@@ -13,6 +13,9 @@
  *  Do not include any C declarations in this file - it is included by
  *  assembler source.
  */
+#ifndef __ASM_ASSEMBLER_H__
+#define __ASM_ASSEMBLER_H__
+
 #ifndef __ASSEMBLY__
 #error "Only include this from assembly code"
 #endif
@@ -290,3 +293,4 @@
 	.macro	ldrusr, reg, ptr, inc, cond=al, rept=1, abort=9001f
 	usracc	ldr, \reg, \ptr, \inc, \cond, \rept, \abort
 	.endm
+#endif /* __ASM_ASSEMBLER_H__ */
diff -druN linux-2.6.39-libre/arch/arm/include/asm/bitops.h linux-3.0-rc7-libre/arch/arm/include/asm/bitops.h
--- linux-2.6.39-libre/arch/arm/include/asm/bitops.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/include/asm/bitops.h	2011-07-11 19:51:52.000000000 -0400
@@ -203,8 +203,6 @@
 #define find_first_bit(p,sz)		_find_first_bit_le(p,sz)
 #define find_next_bit(p,sz,off)		_find_next_bit_le(p,sz,off)
 
-#define WORD_BITOFF_TO_LE(x)		((x))
-
 #else
 /*
  * These are the big endian, atomic definitions.
@@ -214,8 +212,6 @@
 #define find_first_bit(p,sz)		_find_first_bit_be(p,sz)
 #define find_next_bit(p,sz,off)		_find_next_bit_be(p,sz,off)
 
-#define WORD_BITOFF_TO_LE(x)		((x) ^ 0x18)
-
 #endif
 
 #if __LINUX_ARM_ARCH__ < 5
@@ -287,55 +283,29 @@
 #include <asm-generic/bitops/hweight.h>
 #include <asm-generic/bitops/lock.h>
 
-static inline void __set_bit_le(int nr, void *addr)
-{
-	__set_bit(WORD_BITOFF_TO_LE(nr), addr);
-}
-
-static inline void __clear_bit_le(int nr, void *addr)
-{
-	__clear_bit(WORD_BITOFF_TO_LE(nr), addr);
-}
-
-static inline int __test_and_set_bit_le(int nr, void *addr)
-{
-	return __test_and_set_bit(WORD_BITOFF_TO_LE(nr), addr);
-}
-
-static inline int test_and_set_bit_le(int nr, void *addr)
-{
-	return test_and_set_bit(WORD_BITOFF_TO_LE(nr), addr);
-}
-
-static inline int __test_and_clear_bit_le(int nr, void *addr)
-{
-	return __test_and_clear_bit(WORD_BITOFF_TO_LE(nr), addr);
-}
-
-static inline int test_and_clear_bit_le(int nr, void *addr)
-{
-	return test_and_clear_bit(WORD_BITOFF_TO_LE(nr), addr);
-}
-
-static inline int test_bit_le(int nr, const void *addr)
-{
-	return test_bit(WORD_BITOFF_TO_LE(nr), addr);
-}
+#ifdef __ARMEB__
 
 static inline int find_first_zero_bit_le(const void *p, unsigned size)
 {
 	return _find_first_zero_bit_le(p, size);
 }
+#define find_first_zero_bit_le find_first_zero_bit_le
 
 static inline int find_next_zero_bit_le(const void *p, int size, int offset)
 {
 	return _find_next_zero_bit_le(p, size, offset);
 }
+#define find_next_zero_bit_le find_next_zero_bit_le
 
 static inline int find_next_bit_le(const void *p, int size, int offset)
 {
 	return _find_next_bit_le(p, size, offset);
 }
+#define find_next_bit_le find_next_bit_le
+
+#endif
+
+#include <asm-generic/bitops/le.h>
 
 /*
  * Ext2 is defined to use little-endian byte ordering.
diff -druN linux-2.6.39-libre/arch/arm/include/asm/dma.h linux-3.0-rc7-libre/arch/arm/include/asm/dma.h
--- linux-2.6.39-libre/arch/arm/include/asm/dma.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/include/asm/dma.h	2011-07-11 19:51:52.000000000 -0400
@@ -6,8 +6,10 @@
 /*
  * This is the maximum virtual address which can be DMA'd from.
  */
-#ifndef MAX_DMA_ADDRESS
+#ifndef ARM_DMA_ZONE_SIZE
 #define MAX_DMA_ADDRESS	0xffffffff
+#else
+#define MAX_DMA_ADDRESS	(PAGE_OFFSET + ARM_DMA_ZONE_SIZE)
 #endif
 
 #ifdef CONFIG_ISA_DMA_API
diff -druN linux-2.6.39-libre/arch/arm/include/asm/elf.h linux-3.0-rc7-libre/arch/arm/include/asm/elf.h
--- linux-2.6.39-libre/arch/arm/include/asm/elf.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/include/asm/elf.h	2011-07-11 19:51:52.000000000 -0400
@@ -108,6 +108,7 @@
 int dump_task_regs(struct task_struct *t, elf_gregset_t *elfregs);
 #define ELF_CORE_COPY_TASK_REGS dump_task_regs
 
+#define CORE_DUMP_USE_REGSET
 #define ELF_EXEC_PAGESIZE	4096
 
 /* This is the location that an ET_DYN program is loaded if exec'ed.  Typical
diff -druN linux-2.6.39-libre/arch/arm/include/asm/entry-macro-multi.S linux-3.0-rc7-libre/arch/arm/include/asm/entry-macro-multi.S
--- linux-2.6.39-libre/arch/arm/include/asm/entry-macro-multi.S	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/include/asm/entry-macro-multi.S	2011-07-11 19:51:52.000000000 -0400
@@ -1,3 +1,5 @@
+#include <asm/assembler.h>
+
 /*
  * Interrupt handling.  Preserves r7, r8, r9
  */
diff -druN linux-2.6.39-libre/arch/arm/include/asm/fiq.h linux-3.0-rc7-libre/arch/arm/include/asm/fiq.h
--- linux-2.6.39-libre/arch/arm/include/asm/fiq.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/include/asm/fiq.h	2011-07-11 19:51:52.000000000 -0400
@@ -4,6 +4,13 @@
  * Support for FIQ on ARM architectures.
  * Written by Philip Blundell <philb@gnu.org>, 1998
  * Re-written by Russell King
+ *
+ * NOTE: The FIQ mode registers are not magically preserved across
+ * suspend/resume.
+ *
+ * Drivers which require these registers to be preserved across power
+ * management operations must implement appropriate suspend/resume handlers to
+ * save and restore them.
  */
 
 #ifndef __ASM_FIQ_H
@@ -29,9 +36,21 @@
 extern int claim_fiq(struct fiq_handler *f);
 extern void release_fiq(struct fiq_handler *f);
 extern void set_fiq_handler(void *start, unsigned int length);
-extern void set_fiq_regs(struct pt_regs *regs);
-extern void get_fiq_regs(struct pt_regs *regs);
 extern void enable_fiq(int fiq);
 extern void disable_fiq(int fiq);
 
+/* helpers defined in fiqasm.S: */
+extern void __set_fiq_regs(unsigned long const *regs);
+extern void __get_fiq_regs(unsigned long *regs);
+
+static inline void set_fiq_regs(struct pt_regs const *regs)
+{
+	__set_fiq_regs(&regs->ARM_r8);
+}
+
+static inline void get_fiq_regs(struct pt_regs *regs)
+{
+	__get_fiq_regs(&regs->ARM_r8);
+}
+
 #endif
diff -druN linux-2.6.39-libre/arch/arm/include/asm/futex.h linux-3.0-rc7-libre/arch/arm/include/asm/futex.h
--- linux-2.6.39-libre/arch/arm/include/asm/futex.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/include/asm/futex.h	2011-07-11 19:51:52.000000000 -0400
@@ -3,16 +3,74 @@
 
 #ifdef __KERNEL__
 
+#if defined(CONFIG_CPU_USE_DOMAINS) && defined(CONFIG_SMP)
+/* ARM doesn't provide unprivileged exclusive memory accessors */
+#include <asm-generic/futex.h>
+#else
+
+#include <linux/futex.h>
+#include <linux/uaccess.h>
+#include <asm/errno.h>
+
+#define __futex_atomic_ex_table(err_reg)			\
+	"3:\n"							\
+	"	.pushsection __ex_table,\"a\"\n"		\
+	"	.align	3\n"					\
+	"	.long	1b, 4f, 2b, 4f\n"			\
+	"	.popsection\n"					\
+	"	.pushsection .fixup,\"ax\"\n"			\
+	"4:	mov	%0, " err_reg "\n"			\
+	"	b	3b\n"					\
+	"	.popsection"
+
 #ifdef CONFIG_SMP
 
-#include <asm-generic/futex.h>
+#define __futex_atomic_op(insn, ret, oldval, uaddr, oparg)	\
+	smp_mb();						\
+	__asm__ __volatile__(					\
+	"1:	ldrex	%1, [%2]\n"				\
+	"	" insn "\n"					\
+	"2:	strex	%1, %0, [%2]\n"				\
+	"	teq	%1, #0\n"				\
+	"	bne	1b\n"					\
+	"	mov	%0, #0\n"				\
+	__futex_atomic_ex_table("%4")				\
+	: "=&r" (ret), "=&r" (oldval)				\
+	: "r" (uaddr), "r" (oparg), "Ir" (-EFAULT)		\
+	: "cc", "memory")
+
+static inline int
+futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr,
+			      u32 oldval, u32 newval)
+{
+	int ret;
+	u32 val;
+
+	if (!access_ok(VERIFY_WRITE, uaddr, sizeof(u32)))
+		return -EFAULT;
+
+	smp_mb();
+	__asm__ __volatile__("@futex_atomic_cmpxchg_inatomic\n"
+	"1:	ldrex	%1, [%4]\n"
+	"	teq	%1, %2\n"
+	"	ite	eq	@ explicit IT needed for the 2b label\n"
+	"2:	strexeq	%0, %3, [%4]\n"
+	"	movne	%0, #0\n"
+	"	teq	%0, #0\n"
+	"	bne	1b\n"
+	__futex_atomic_ex_table("%5")
+	: "=&r" (ret), "=&r" (val)
+	: "r" (oldval), "r" (newval), "r" (uaddr), "Ir" (-EFAULT)
+	: "cc", "memory");
+	smp_mb();
+
+	*uval = val;
+	return ret;
+}
 
 #else /* !SMP, we can work around lack of atomic ops by disabling preemption */
 
-#include <linux/futex.h>
 #include <linux/preempt.h>
-#include <linux/uaccess.h>
-#include <asm/errno.h>
 #include <asm/domain.h>
 
 #define __futex_atomic_op(insn, ret, oldval, uaddr, oparg)	\
@@ -21,20 +79,38 @@
 	"	" insn "\n"					\
 	"2:	" T(str) "	%0, [%2]\n"			\
 	"	mov	%0, #0\n"				\
-	"3:\n"							\
-	"	.pushsection __ex_table,\"a\"\n"		\
-	"	.align	3\n"					\
-	"	.long	1b, 4f, 2b, 4f\n"			\
-	"	.popsection\n"					\
-	"	.pushsection .fixup,\"ax\"\n"			\
-	"4:	mov	%0, %4\n"				\
-	"	b	3b\n"					\
-	"	.popsection"					\
+	__futex_atomic_ex_table("%4")				\
 	: "=&r" (ret), "=&r" (oldval)				\
 	: "r" (uaddr), "r" (oparg), "Ir" (-EFAULT)		\
 	: "cc", "memory")
 
 static inline int
+futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr,
+			      u32 oldval, u32 newval)
+{
+	int ret = 0;
+	u32 val;
+
+	if (!access_ok(VERIFY_WRITE, uaddr, sizeof(u32)))
+		return -EFAULT;
+
+	__asm__ __volatile__("@futex_atomic_cmpxchg_inatomic\n"
+	"1:	" T(ldr) "	%1, [%4]\n"
+	"	teq	%1, %2\n"
+	"	it	eq	@ explicit IT needed for the 2b label\n"
+	"2:	" T(streq) "	%3, [%4]\n"
+	__futex_atomic_ex_table("%5")
+	: "+r" (ret), "=&r" (val)
+	: "r" (oldval), "r" (newval), "r" (uaddr), "Ir" (-EFAULT)
+	: "cc", "memory");
+
+	*uval = val;
+	return ret;
+}
+
+#endif /* !SMP */
+
+static inline int
 futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr)
 {
 	int op = (encoded_op >> 28) & 7;
@@ -87,39 +163,6 @@
 	return ret;
 }
 
-static inline int
-futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr,
-			      u32 oldval, u32 newval)
-{
-	int ret = 0;
-	u32 val;
-
-	if (!access_ok(VERIFY_WRITE, uaddr, sizeof(u32)))
-		return -EFAULT;
-
-	__asm__ __volatile__("@futex_atomic_cmpxchg_inatomic\n"
-	"1:	" T(ldr) "	%1, [%4]\n"
-	"	teq	%1, %2\n"
-	"	it	eq	@ explicit IT needed for the 2b label\n"
-	"2:	" T(streq) "	%3, [%4]\n"
-	"3:\n"
-	"	.pushsection __ex_table,\"a\"\n"
-	"	.align	3\n"
-	"	.long	1b, 4f, 2b, 4f\n"
-	"	.popsection\n"
-	"	.pushsection .fixup,\"ax\"\n"
-	"4:	mov	%0, %5\n"
-	"	b	3b\n"
-	"	.popsection"
-	: "+r" (ret), "=&r" (val)
-	: "r" (oldval), "r" (newval), "r" (uaddr), "Ir" (-EFAULT)
-	: "cc", "memory");
-
-	*uval = val;
-	return ret;
-}
-
-#endif /* !SMP */
-
+#endif /* !(CPU_USE_DOMAINS && SMP) */
 #endif /* __KERNEL__ */
 #endif /* _ASM_ARM_FUTEX_H */
diff -druN linux-2.6.39-libre/arch/arm/include/asm/hardware/timer-sp.h linux-3.0-rc7-libre/arch/arm/include/asm/hardware/timer-sp.h
--- linux-2.6.39-libre/arch/arm/include/asm/hardware/timer-sp.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/include/asm/hardware/timer-sp.h	2011-07-11 19:51:52.000000000 -0400
@@ -1,2 +1,2 @@
-void sp804_clocksource_init(void __iomem *);
-void sp804_clockevents_init(void __iomem *, unsigned int);
+void sp804_clocksource_init(void __iomem *, const char *);
+void sp804_clockevents_init(void __iomem *, unsigned int, const char *);
diff -druN linux-2.6.39-libre/arch/arm/include/asm/i8253.h linux-3.0-rc7-libre/arch/arm/include/asm/i8253.h
--- linux-2.6.39-libre/arch/arm/include/asm/i8253.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/arm/include/asm/i8253.h	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,15 @@
+#ifndef __ASMARM_I8253_H
+#define __ASMARM_I8253_H
+
+/* i8253A PIT registers */
+#define PIT_MODE	0x43
+#define PIT_CH0		0x40
+
+#define PIT_LATCH	((PIT_TICK_RATE + HZ / 2) / HZ)
+
+extern raw_spinlock_t i8253_lock;
+
+#define outb_pit	outb_p
+#define inb_pit		inb_p
+
+#endif
diff -druN linux-2.6.39-libre/arch/arm/include/asm/mach/arch.h linux-3.0-rc7-libre/arch/arm/include/asm/mach/arch.h
--- linux-2.6.39-libre/arch/arm/include/asm/mach/arch.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/include/asm/mach/arch.h	2011-07-11 19:51:52.000000000 -0400
@@ -18,6 +18,8 @@
 	unsigned int		nr;		/* architecture number	*/
 	const char		*name;		/* architecture name	*/
 	unsigned long		boot_params;	/* tagged list		*/
+	const char		**dt_compat;	/* array of device tree
+						 * 'compatible' strings	*/
 
 	unsigned int		nr_irqs;	/* number of IRQs */
 
@@ -48,6 +50,13 @@
 extern struct machine_desc *machine_desc;
 
 /*
+ * Machine type table - also only accessible during boot
+ */
+extern struct machine_desc __arch_info_begin[], __arch_info_end[];
+#define for_each_machine_desc(p)			\
+	for (p = __arch_info_begin; p < __arch_info_end; p++)
+
+/*
  * Set of macros to define architecture features.  This is built into
  * a table by the linker.
  */
diff -druN linux-2.6.39-libre/arch/arm/include/asm/mach/time.h linux-3.0-rc7-libre/arch/arm/include/asm/mach/time.h
--- linux-2.6.39-libre/arch/arm/include/asm/mach/time.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/include/asm/mach/time.h	2011-07-11 19:51:52.000000000 -0400
@@ -34,7 +34,6 @@
  *   timer interrupt which may be pending.
  */
 struct sys_timer {
-	struct sys_device	dev;
 	void			(*init)(void);
 	void			(*suspend)(void);
 	void			(*resume)(void);
diff -druN linux-2.6.39-libre/arch/arm/include/asm/memory.h linux-3.0-rc7-libre/arch/arm/include/asm/memory.h
--- linux-2.6.39-libre/arch/arm/include/asm/memory.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/include/asm/memory.h	2011-07-11 19:51:52.000000000 -0400
@@ -209,14 +209,10 @@
  * allocations.  This must be the smallest DMA mask in the system,
  * so a successful GFP_DMA allocation will always satisfy this.
  */
-#ifndef ISA_DMA_THRESHOLD
+#ifndef ARM_DMA_ZONE_SIZE
 #define ISA_DMA_THRESHOLD	(0xffffffffULL)
-#endif
-
-#ifndef arch_adjust_zones
-#define arch_adjust_zones(size,holes) do { } while (0)
-#elif !defined(CONFIG_ZONE_DMA)
-#error "custom arch_adjust_zones() requires CONFIG_ZONE_DMA"
+#else
+#define ISA_DMA_THRESHOLD	(PHYS_OFFSET + ARM_DMA_ZONE_SIZE - 1)
 #endif
 
 /*
diff -druN linux-2.6.39-libre/arch/arm/include/asm/page.h linux-3.0-rc7-libre/arch/arm/include/asm/page.h
--- linux-2.6.39-libre/arch/arm/include/asm/page.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/include/asm/page.h	2011-07-11 19:51:52.000000000 -0400
@@ -197,7 +197,7 @@
 
 typedef struct page *pgtable_t;
 
-#ifndef CONFIG_SPARSEMEM
+#ifdef CONFIG_HAVE_ARCH_PFN_VALID
 extern int pfn_valid(unsigned long);
 #endif
 
diff -druN linux-2.6.39-libre/arch/arm/include/asm/prom.h linux-3.0-rc7-libre/arch/arm/include/asm/prom.h
--- linux-2.6.39-libre/arch/arm/include/asm/prom.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/arm/include/asm/prom.h	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,37 @@
+/*
+ *  arch/arm/include/asm/prom.h
+ *
+ *  Copyright (C) 2009 Canonical Ltd. <jeremy.kerr@canonical.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+#ifndef __ASMARM_PROM_H
+#define __ASMARM_PROM_H
+
+#ifdef CONFIG_OF
+
+#include <asm/setup.h>
+#include <asm/irq.h>
+
+static inline void irq_dispose_mapping(unsigned int virq)
+{
+	return;
+}
+
+extern struct machine_desc *setup_machine_fdt(unsigned int dt_phys);
+extern void arm_dt_memblock_reserve(void);
+
+#else /* CONFIG_OF */
+
+static inline struct machine_desc *setup_machine_fdt(unsigned int dt_phys)
+{
+	return NULL;
+}
+
+static inline void arm_dt_memblock_reserve(void) { }
+
+#endif /* CONFIG_OF */
+#endif /* ASMARM_PROM_H */
diff -druN linux-2.6.39-libre/arch/arm/include/asm/ptrace.h linux-3.0-rc7-libre/arch/arm/include/asm/ptrace.h
--- linux-2.6.39-libre/arch/arm/include/asm/ptrace.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/include/asm/ptrace.h	2011-07-11 19:51:52.000000000 -0400
@@ -128,6 +128,12 @@
 #define ARM_r0		uregs[0]
 #define ARM_ORIG_r0	uregs[17]
 
+/*
+ * The size of the user-visible VFP state as seen by PTRACE_GET/SETVFPREGS
+ * and core dumps.
+ */
+#define ARM_VFPREGS_SIZE ( 32 * 8 /*fpregs*/ + 4 /*fpscr*/ )
+
 #ifdef __KERNEL__
 
 #define user_mode(regs)	\
diff -druN linux-2.6.39-libre/arch/arm/include/asm/setup.h linux-3.0-rc7-libre/arch/arm/include/asm/setup.h
--- linux-2.6.39-libre/arch/arm/include/asm/setup.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/include/asm/setup.h	2011-07-11 19:51:52.000000000 -0400
@@ -217,6 +217,10 @@
 #define bank_phys_end(bank)	((bank)->start + (bank)->size)
 #define bank_phys_size(bank)	(bank)->size
 
+extern int arm_add_memory(phys_addr_t start, unsigned long size);
+extern void early_print(const char *str, ...);
+extern void dump_machine_table(void);
+
 #endif  /*  __KERNEL__  */
 
 #endif
diff -druN linux-2.6.39-libre/arch/arm/include/asm/sizes.h linux-3.0-rc7-libre/arch/arm/include/asm/sizes.h
--- linux-2.6.39-libre/arch/arm/include/asm/sizes.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/include/asm/sizes.h	2011-07-11 19:51:52.000000000 -0400
@@ -16,44 +16,6 @@
 /*  Size definitions
  *  Copyright (C) ARM Limited 1998. All rights reserved.
  */
+#include <asm-generic/sizes.h>
 
-#ifndef __sizes_h
-#define __sizes_h                       1
-
-/* handy sizes */
-#define SZ_16				0x00000010
-#define SZ_32				0x00000020
-#define SZ_64				0x00000040
-#define SZ_128				0x00000080
-#define SZ_256				0x00000100
-#define SZ_512				0x00000200
-
-#define SZ_1K                           0x00000400
-#define SZ_2K                           0x00000800
-#define SZ_4K                           0x00001000
-#define SZ_8K                           0x00002000
-#define SZ_16K                          0x00004000
-#define SZ_32K                          0x00008000
-#define SZ_64K                          0x00010000
-#define SZ_128K                         0x00020000
-#define SZ_256K                         0x00040000
-#define SZ_512K                         0x00080000
-
-#define SZ_1M                           0x00100000
-#define SZ_2M                           0x00200000
-#define SZ_4M                           0x00400000
-#define SZ_8M                           0x00800000
-#define SZ_16M                          0x01000000
-#define SZ_32M                          0x02000000
-#define SZ_48M                          0x03000000
-#define SZ_64M                          0x04000000
-#define SZ_128M                         0x08000000
-#define SZ_256M                         0x10000000
-#define SZ_512M                         0x20000000
-
-#define SZ_1G                           0x40000000
-#define SZ_2G                           0x80000000
-
-#endif
-
-/*         END */
+#define SZ_48M	(SZ_32M + SZ_16M)
diff -druN linux-2.6.39-libre/arch/arm/include/asm/smp.h linux-3.0-rc7-libre/arch/arm/include/asm/smp.h
--- linux-2.6.39-libre/arch/arm/include/asm/smp.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/include/asm/smp.h	2011-07-11 19:51:52.000000000 -0400
@@ -14,20 +14,12 @@
 #include <linux/cpumask.h>
 #include <linux/thread_info.h>
 
-#include <mach/smp.h>
-
 #ifndef CONFIG_SMP
 # error "<asm/smp.h> included in non-SMP build"
 #endif
 
 #define raw_smp_processor_id() (current_thread_info()->cpu)
 
-/*
- * at the moment, there's not a big penalty for changing CPUs
- * (the >big< penalty is running SMP in the first place)
- */
-#define PROC_CHANGE_PENALTY		15
-
 struct seq_file;
 
 /*
@@ -47,9 +39,9 @@
 
 
 /*
- * Raise an IPI cross call on CPUs in callmap.
+ * Provide a function to raise an IPI cross call on CPUs in callmap.
  */
-extern void smp_cross_call(const struct cpumask *mask, int ipi);
+extern void set_smp_cross_call(void (*)(const struct cpumask *, unsigned int));
 
 /*
  * Boot a secondary CPU, and assign it the specified idle task.
@@ -78,6 +70,7 @@
  */
 struct secondary_data {
 	unsigned long pgdir;
+	unsigned long swapper_pg_dir;
 	void *stack;
 };
 extern struct secondary_data secondary_data;
diff -druN linux-2.6.39-libre/arch/arm/include/asm/spinlock.h linux-3.0-rc7-libre/arch/arm/include/asm/spinlock.h
--- linux-2.6.39-libre/arch/arm/include/asm/spinlock.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/include/asm/spinlock.h	2011-07-11 19:51:52.000000000 -0400
@@ -5,6 +5,8 @@
 #error SMP not supported on pre-ARMv6 CPUs
 #endif
 
+#include <asm/processor.h>
+
 /*
  * sev and wfe are ARMv6K extensions.  Uniprocessor ARMv6 may not have the K
  * extensions, so when running on UP, we have to patch these instructions away.
diff -druN linux-2.6.39-libre/arch/arm/include/asm/tlb.h linux-3.0-rc7-libre/arch/arm/include/asm/tlb.h
--- linux-2.6.39-libre/arch/arm/include/asm/tlb.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/include/asm/tlb.h	2011-07-11 19:51:52.000000000 -0400
@@ -41,12 +41,12 @@
  */
 #if defined(CONFIG_SMP) || defined(CONFIG_CPU_32v7)
 #define tlb_fast_mode(tlb)	0
-#define FREE_PTE_NR		500
 #else
 #define tlb_fast_mode(tlb)	1
-#define FREE_PTE_NR		0
 #endif
 
+#define MMU_GATHER_BUNDLE	8
+
 /*
  * TLB handling.  This allows us to remove pages from the page
  * tables, and efficiently handle the TLB issues.
@@ -58,7 +58,9 @@
 	unsigned long		range_start;
 	unsigned long		range_end;
 	unsigned int		nr;
-	struct page		*pages[FREE_PTE_NR];
+	unsigned int		max;
+	struct page		**pages;
+	struct page		*local[MMU_GATHER_BUNDLE];
 };
 
 DECLARE_PER_CPU(struct mmu_gather, mmu_gathers);
@@ -97,26 +99,37 @@
 	}
 }
 
+static inline void __tlb_alloc_page(struct mmu_gather *tlb)
+{
+	unsigned long addr = __get_free_pages(GFP_NOWAIT | __GFP_NOWARN, 0);
+
+	if (addr) {
+		tlb->pages = (void *)addr;
+		tlb->max = PAGE_SIZE / sizeof(struct page *);
+	}
+}
+
 static inline void tlb_flush_mmu(struct mmu_gather *tlb)
 {
 	tlb_flush(tlb);
 	if (!tlb_fast_mode(tlb)) {
 		free_pages_and_swap_cache(tlb->pages, tlb->nr);
 		tlb->nr = 0;
+		if (tlb->pages == tlb->local)
+			__tlb_alloc_page(tlb);
 	}
 }
 
-static inline struct mmu_gather *
-tlb_gather_mmu(struct mm_struct *mm, unsigned int full_mm_flush)
+static inline void
+tlb_gather_mmu(struct mmu_gather *tlb, struct mm_struct *mm, unsigned int fullmm)
 {
-	struct mmu_gather *tlb = &get_cpu_var(mmu_gathers);
-
 	tlb->mm = mm;
-	tlb->fullmm = full_mm_flush;
+	tlb->fullmm = fullmm;
 	tlb->vma = NULL;
+	tlb->max = ARRAY_SIZE(tlb->local);
+	tlb->pages = tlb->local;
 	tlb->nr = 0;
-
-	return tlb;
+	__tlb_alloc_page(tlb);
 }
 
 static inline void
@@ -127,7 +140,8 @@
 	/* keep the page table cache within bounds */
 	check_pgt_cache();
 
-	put_cpu_var(mmu_gathers);
+	if (tlb->pages != tlb->local)
+		free_pages((unsigned long)tlb->pages, 0);
 }
 
 /*
@@ -162,15 +176,22 @@
 		tlb_flush(tlb);
 }
 
-static inline void tlb_remove_page(struct mmu_gather *tlb, struct page *page)
+static inline int __tlb_remove_page(struct mmu_gather *tlb, struct page *page)
 {
 	if (tlb_fast_mode(tlb)) {
 		free_page_and_swap_cache(page);
-	} else {
-		tlb->pages[tlb->nr++] = page;
-		if (tlb->nr >= FREE_PTE_NR)
-			tlb_flush_mmu(tlb);
+		return 1; /* avoid calling tlb_flush_mmu */
 	}
+
+	tlb->pages[tlb->nr++] = page;
+	VM_BUG_ON(tlb->nr > tlb->max);
+	return tlb->max - tlb->nr;
+}
+
+static inline void tlb_remove_page(struct mmu_gather *tlb, struct page *page)
+{
+	if (!__tlb_remove_page(tlb, page))
+		tlb_flush_mmu(tlb);
 }
 
 static inline void __pte_free_tlb(struct mmu_gather *tlb, pgtable_t pte,
diff -druN linux-2.6.39-libre/arch/arm/include/asm/unistd.h linux-3.0-rc7-libre/arch/arm/include/asm/unistd.h
--- linux-2.6.39-libre/arch/arm/include/asm/unistd.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/include/asm/unistd.h	2011-07-11 19:51:52.000000000 -0400
@@ -400,6 +400,8 @@
 #define __NR_open_by_handle_at		(__NR_SYSCALL_BASE+371)
 #define __NR_clock_adjtime		(__NR_SYSCALL_BASE+372)
 #define __NR_syncfs			(__NR_SYSCALL_BASE+373)
+#define __NR_sendmmsg			(__NR_SYSCALL_BASE+374)
+#define __NR_setns			(__NR_SYSCALL_BASE+375)
 
 /*
  * The following SWIs are ARM private.
diff -druN linux-2.6.39-libre/arch/arm/Kconfig linux-3.0-rc7-libre/arch/arm/Kconfig
--- linux-2.6.39-libre/arch/arm/Kconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/Kconfig	2011-07-11 19:51:52.000000000 -0400
@@ -197,15 +197,21 @@
 	depends on !XIP_KERNEL && MMU
 	depends on !ARCH_REALVIEW || !SPARSEMEM
 	help
-	  Patch phys-to-virt translation functions at runtime according to
-	  the position of the kernel in system memory.
+	  Patch phys-to-virt and virt-to-phys translation functions at
+	  boot and module load time according to the position of the
+	  kernel in system memory.
 
-	  This can only be used with non-XIP with MMU kernels where
-	  the base of physical memory is at a 16MB boundary.
+	  This can only be used with non-XIP MMU kernels where the base
+	  of physical memory is at a 16MB boundary, or theoretically 64K
+	  for the MSM machine class.
 
 config ARM_PATCH_PHYS_VIRT_16BIT
 	def_bool y
 	depends on ARM_PATCH_PHYS_VIRT && ARCH_MSM
+	help
+	  This option extends the physical to virtual translation patching
+	  to allow physical memory down to a theoretical minimum of 64K
+	  boundaries.
 
 source "init/Kconfig"
 
@@ -288,6 +294,8 @@
 	bool "Atmel AT91"
 	select ARCH_REQUIRE_GPIOLIB
 	select HAVE_CLK
+	select CLKDEV_LOOKUP
+	select ARM_PATCH_PHYS_VIRT if MMU
 	help
 	  This enables support for systems based on the Atmel AT91RM9200,
 	  AT91SAM9 and AT91CAP9 processors.
@@ -297,6 +305,7 @@
 	depends on MMU
 	select CPU_V6
 	select ARM_AMBA
+	select ARM_TIMER_SP804
 	select CLKDEV_LOOKUP
 	select GENERIC_CLOCKEVENTS
 	select ARCH_WANT_OPTIONAL_GPIOLIB
@@ -366,6 +375,7 @@
 	select GENERIC_CLOCKEVENTS
 	select ARCH_REQUIRE_GPIOLIB
 	select CLKDEV_LOOKUP
+	select CLKSRC_MMIO
 	select HAVE_SCHED_CLOCK
 	help
 	  Support for Freescale MXC/iMX-based family of processors
@@ -375,21 +385,13 @@
 	select GENERIC_CLOCKEVENTS
 	select ARCH_REQUIRE_GPIOLIB
 	select CLKDEV_LOOKUP
+	select CLKSRC_MMIO
 	help
 	  Support for Freescale MXS-based family of processors
 
-config ARCH_STMP3XXX
-	bool "Freescale STMP3xxx"
-	select CPU_ARM926T
-	select CLKDEV_LOOKUP
-	select ARCH_REQUIRE_GPIOLIB
-	select GENERIC_CLOCKEVENTS
-	select USB_ARCH_HAS_EHCI
-	help
-	  Support for systems based on the Freescale 3xxx CPUs.
-
 config ARCH_NETX
 	bool "Hilscher NetX based"
+	select CLKSRC_MMIO
 	select CPU_ARM926T
 	select ARM_VIC
 	select GENERIC_CLOCKEVENTS
@@ -457,6 +459,7 @@
 config ARCH_IXP4XX
 	bool "IXP4xx-based"
 	depends on MMU
+	select CLKSRC_MMIO
 	select CPU_XSCALE
 	select GENERIC_GPIO
 	select GENERIC_CLOCKEVENTS
@@ -468,7 +471,7 @@
 
 config ARCH_DOVE
 	bool "Marvell Dove"
-	select CPU_V6K
+	select CPU_V7
 	select PCI
 	select ARCH_REQUIRE_GPIOLIB
 	select GENERIC_CLOCKEVENTS
@@ -497,6 +500,7 @@
 
 config ARCH_LPC32XX
 	bool "NXP LPC32XX"
+	select CLKSRC_MMIO
 	select CPU_ARM926T
 	select ARCH_REQUIRE_GPIOLIB
 	select HAVE_IDE
@@ -554,23 +558,12 @@
 	  Support for Micrel/Kendin KS8695 "Centaur" (ARM922T) based
 	  System-on-Chip devices.
 
-config ARCH_NS9XXX
-	bool "NetSilicon NS9xxx"
-	select CPU_ARM926T
-	select GENERIC_GPIO
-	select GENERIC_CLOCKEVENTS
-	select HAVE_CLK
-	help
-	  Say Y here if you intend to run this kernel on a NetSilicon NS9xxx
-	  System.
-
-	  <http://www.digi.com/products/microprocessors/index.jsp>
-
 config ARCH_W90X900
 	bool "Nuvoton W90X900 CPU"
 	select CPU_ARM926T
 	select ARCH_REQUIRE_GPIOLIB
 	select CLKDEV_LOOKUP
+	select CLKSRC_MMIO
 	select GENERIC_CLOCKEVENTS
 	help
 	  Support for Nuvoton (Winbond logic dept.) ARM9 processor,
@@ -592,6 +585,7 @@
 config ARCH_TEGRA
 	bool "NVIDIA Tegra"
 	select CLKDEV_LOOKUP
+	select CLKSRC_MMIO
 	select GENERIC_TIME
 	select GENERIC_CLOCKEVENTS
 	select GENERIC_GPIO
@@ -617,6 +611,7 @@
 	select ARCH_MTD_XIP
 	select ARCH_HAS_CPUFREQ
 	select CLKDEV_LOOKUP
+	select CLKSRC_MMIO
 	select ARCH_REQUIRE_GPIOLIB
 	select GENERIC_CLOCKEVENTS
 	select HAVE_SCHED_CLOCK
@@ -667,6 +662,7 @@
 
 config ARCH_SA1100
 	bool "SA1100-based"
+	select CLKSRC_MMIO
 	select CPU_SA1100
 	select ISA
 	select ARCH_SPARSEMEM_ENABLE
@@ -736,16 +732,6 @@
 	  Samsung S5P64X0 CPU based systems, such as the Samsung SMDK6440,
 	  SMDK6450.
 
-config ARCH_S5P6442
-	bool "Samsung S5P6442"
-	select CPU_V6
-	select GENERIC_GPIO
-	select HAVE_CLK
-	select ARCH_USES_GETTIMEOFFSET
-	select HAVE_S3C2410_WATCHDOG if WATCHDOG
-	help
-	  Samsung S5P6442 CPU based systems
-
 config ARCH_S5PC100
 	bool "Samsung S5PC100"
 	select GENERIC_GPIO
@@ -803,6 +789,7 @@
 
 config ARCH_TCC_926
 	bool "Telechips TCC ARM926-based systems"
+	select CLKSRC_MMIO
 	select CPU_ARM926T
 	select HAVE_CLK
 	select CLKDEV_LOOKUP
@@ -813,6 +800,7 @@
 config ARCH_U300
 	bool "ST-Ericsson U300 Series"
 	depends on MMU
+	select CLKSRC_MMIO
 	select CPU_ARM926T
 	select HAVE_SCHED_CLOCK
 	select HAVE_TCM
@@ -854,6 +842,7 @@
 	select HAVE_IDE
 	select CLKDEV_LOOKUP
 	select GENERIC_ALLOCATOR
+	select GENERIC_IRQ_CHIP
 	select ARCH_HAS_HOLES_MEMORYMODEL
 	help
 	  Support for TI's DaVinci platform.
@@ -874,6 +863,7 @@
 	select ARM_AMBA
 	select ARCH_REQUIRE_GPIOLIB
 	select CLKDEV_LOOKUP
+	select CLKSRC_MMIO
 	select GENERIC_CLOCKEVENTS
 	select HAVE_CLK
 	help
@@ -951,8 +941,6 @@
 source "arch/arm/mach-nomadik/Kconfig"
 source "arch/arm/plat-nomadik/Kconfig"
 
-source "arch/arm/mach-ns9xxx/Kconfig"
-
 source "arch/arm/mach-nuc93x/Kconfig"
 
 source "arch/arm/plat-omap/Kconfig"
@@ -995,8 +983,6 @@
 
 source "arch/arm/mach-s5p64x0/Kconfig"
 
-source "arch/arm/mach-s5p6442/Kconfig"
-
 source "arch/arm/mach-s5pc100/Kconfig"
 
 source "arch/arm/mach-s5pv210/Kconfig"
@@ -1005,8 +991,6 @@
 
 source "arch/arm/mach-shmobile/Kconfig"
 
-source "arch/arm/plat-stmp3xxx/Kconfig"
-
 source "arch/arm/mach-tegra/Kconfig"
 
 source "arch/arm/mach-u300/Kconfig"
@@ -1033,6 +1017,8 @@
 
 config PLAT_ORION
 	bool
+	select CLKSRC_MMIO
+	select GENERIC_IRQ_CHIP
 	select HAVE_SCHED_CLOCK
 
 config PLAT_PXA
@@ -1043,6 +1029,7 @@
 
 config ARM_TIMER_SP804
 	bool
+	select CLKSRC_MMIO
 
 source arch/arm/mm/Kconfig
 
@@ -1318,8 +1305,7 @@
 source "kernel/time/Kconfig"
 
 config SMP
-	bool "Symmetric Multi-Processing (EXPERIMENTAL)"
-	depends on EXPERIMENTAL
+	bool "Symmetric Multi-Processing"
 	depends on CPU_V6K || CPU_V7
 	depends on GENERIC_CLOCKEVENTS
 	depends on REALVIEW_EB_ARM11MP || REALVIEW_EB_A9MP || \
@@ -1403,7 +1389,6 @@
 config HOTPLUG_CPU
 	bool "Support for hot-pluggable CPUs (EXPERIMENTAL)"
 	depends on SMP && HOTPLUG && EXPERIMENTAL
-	depends on !ARCH_MSM
 	help
 	  Say Y here to experiment with turning CPUs off and on.  CPUs
 	  can be controlled through /sys/devices/system/cpu.
@@ -1424,7 +1409,7 @@
 config HZ
 	int
 	default 200 if ARCH_EBSA110 || ARCH_S3C2410 || ARCH_S5P64X0 || \
-		ARCH_S5P6442 || ARCH_S5PV210 || ARCH_EXYNOS4
+		ARCH_S5PV210 || ARCH_EXYNOS4
 	default OMAP_32K_TIMER_HZ if ARCH_OMAP && OMAP_32K_TIMER
 	default AT91_TIMER_HZ if ARCH_AT91
 	default SHMOBILE_TIMER_HZ if ARCH_SHMOBILE
@@ -1520,9 +1505,12 @@
 config ARCH_SELECT_MEMORY_MODEL
 	def_bool ARCH_SPARSEMEM_ENABLE
 
+config HAVE_ARCH_PFN_VALID
+	def_bool ARCH_HAS_HOLES_MEMORYMODEL || !SPARSEMEM
+
 config HIGHMEM
-	bool "High Memory Support (EXPERIMENTAL)"
-	depends on MMU && EXPERIMENTAL
+	bool "High Memory Support"
+	depends on MMU
 	help
 	  The address space of ARM processors is only 4 Gigabytes large
 	  and it has to accommodate user address space, kernel address
@@ -1687,6 +1675,13 @@
 
 menu "Boot options"
 
+config USE_OF
+	bool "Flattened Device Tree support"
+	select OF
+	select OF_EARLY_FLATTREE
+	help
+	  Include support for flattened device tree machine descriptions.
+
 # Compressed boot loader in ROM.  Yes, we really want to ask about
 # TEXT and BSS so we preserve their values in the config files.
 config ZBOOT_ROM_TEXT
@@ -1742,16 +1737,31 @@
 	  time by entering them here. As a minimum, you should specify the
 	  memory size and the root device (e.g., mem=64M root=/dev/nfs).
 
+choice
+	prompt "Kernel command line type" if CMDLINE != ""
+	default CMDLINE_FROM_BOOTLOADER
+
+config CMDLINE_FROM_BOOTLOADER
+	bool "Use bootloader kernel arguments if available"
+	help
+	  Uses the command-line options passed by the boot loader. If
+	  the boot loader doesn't provide any, the default kernel command
+	  string provided in CMDLINE will be used.
+
+config CMDLINE_EXTEND
+	bool "Extend bootloader kernel arguments"
+	help
+	  The command-line arguments provided by the boot loader will be
+	  appended to the default kernel command string.
+
 config CMDLINE_FORCE
 	bool "Always use the default kernel command string"
-	depends on CMDLINE != ""
 	help
 	  Always use the default kernel command string, even if the boot
 	  loader passes other arguments to the kernel.
 	  This is useful if you cannot or don't want to change the
 	  command-line options your boot loader passes to the kernel.
-
-	  If unsure, say N.
+endchoice
 
 config XIP_KERNEL
 	bool "Kernel Execute-In-Place from ROM"
@@ -2010,7 +2020,7 @@
 source "kernel/power/Kconfig"
 
 config ARCH_SUSPEND_POSSIBLE
-	depends on !ARCH_S5P64X0 && !ARCH_S5P6442
+	depends on !ARCH_S5P64X0 && !ARCH_S5PC100
 	depends on CPU_ARM920T || CPU_ARM926T || CPU_SA1100 || \
 		CPU_V6 || CPU_V6K || CPU_V7 || CPU_XSC3 || CPU_XSCALE
 	def_bool y
diff -druN linux-2.6.39-libre/arch/arm/Kconfig.debug linux-3.0-rc7-libre/arch/arm/Kconfig.debug
--- linux-2.6.39-libre/arch/arm/Kconfig.debug	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/Kconfig.debug	2011-07-11 19:51:52.000000000 -0400
@@ -63,13 +63,6 @@
 	      8 - SIGSEGV faults
 	     16 - SIGBUS faults
 
-config DEBUG_STACK_USAGE
-	bool "Enable stack utilization instrumentation"
-	depends on DEBUG_KERNEL
-	help
-	  Enables the display of the minimum amount of free stack which each
-	  task has ever had available in the sysrq-T output.
-
 # These options are only for real kernel hackers who want to get their hands dirty.
 config DEBUG_LL
 	bool "Kernel low-level debugging functions"
diff -druN linux-2.6.39-libre/arch/arm/kernel/calls.S linux-3.0-rc7-libre/arch/arm/kernel/calls.S
--- linux-2.6.39-libre/arch/arm/kernel/calls.S	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/kernel/calls.S	2011-07-11 19:51:52.000000000 -0400
@@ -383,6 +383,8 @@
 		CALL(sys_open_by_handle_at)
 		CALL(sys_clock_adjtime)
 		CALL(sys_syncfs)
+		CALL(sys_sendmmsg)
+/* 375 */	CALL(sys_setns)
 #ifndef syscalls_counted
 .equ syscalls_padding, ((NR_syscalls + 3) & ~3) - NR_syscalls
 #define syscalls_counted
diff -druN linux-2.6.39-libre/arch/arm/kernel/devtree.c linux-3.0-rc7-libre/arch/arm/kernel/devtree.c
--- linux-2.6.39-libre/arch/arm/kernel/devtree.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/arm/kernel/devtree.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,148 @@
+/*
+ *  linux/arch/arm/kernel/devtree.c
+ *
+ *  Copyright (C) 2009 Canonical Ltd. <jeremy.kerr@canonical.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/errno.h>
+#include <linux/types.h>
+#include <linux/bootmem.h>
+#include <linux/memblock.h>
+#include <linux/of.h>
+#include <linux/of_fdt.h>
+#include <linux/of_irq.h>
+#include <linux/of_platform.h>
+
+#include <asm/setup.h>
+#include <asm/page.h>
+#include <asm/mach/arch.h>
+#include <asm/mach-types.h>
+
+void __init early_init_dt_add_memory_arch(u64 base, u64 size)
+{
+	arm_add_memory(base, size);
+}
+
+void * __init early_init_dt_alloc_memory_arch(u64 size, u64 align)
+{
+	return alloc_bootmem_align(size, align);
+}
+
+void __init arm_dt_memblock_reserve(void)
+{
+	u64 *reserve_map, base, size;
+
+	if (!initial_boot_params)
+		return;
+
+	/* Reserve the dtb region */
+	memblock_reserve(virt_to_phys(initial_boot_params),
+			 be32_to_cpu(initial_boot_params->totalsize));
+
+	/*
+	 * Process the reserve map.  This will probably overlap the initrd
+	 * and dtb locations which are already reserved, but overlaping
+	 * doesn't hurt anything
+	 */
+	reserve_map = ((void*)initial_boot_params) +
+			be32_to_cpu(initial_boot_params->off_mem_rsvmap);
+	while (1) {
+		base = be64_to_cpup(reserve_map++);
+		size = be64_to_cpup(reserve_map++);
+		if (!size)
+			break;
+		memblock_reserve(base, size);
+	}
+}
+
+/**
+ * setup_machine_fdt - Machine setup when an dtb was passed to the kernel
+ * @dt_phys: physical address of dt blob
+ *
+ * If a dtb was passed to the kernel in r2, then use it to choose the
+ * correct machine_desc and to setup the system.
+ */
+struct machine_desc * __init setup_machine_fdt(unsigned int dt_phys)
+{
+	struct boot_param_header *devtree;
+	struct machine_desc *mdesc, *mdesc_best = NULL;
+	unsigned int score, mdesc_score = ~1;
+	unsigned long dt_root;
+	const char *model;
+
+	if (!dt_phys)
+		return NULL;
+
+	devtree = phys_to_virt(dt_phys);
+
+	/* check device tree validity */
+	if (be32_to_cpu(devtree->magic) != OF_DT_HEADER)
+		return NULL;
+
+	/* Search the mdescs for the 'best' compatible value match */
+	initial_boot_params = devtree;
+	dt_root = of_get_flat_dt_root();
+	for_each_machine_desc(mdesc) {
+		score = of_flat_dt_match(dt_root, mdesc->dt_compat);
+		if (score > 0 && score < mdesc_score) {
+			mdesc_best = mdesc;
+			mdesc_score = score;
+		}
+	}
+	if (!mdesc_best) {
+		const char *prop;
+		long size;
+
+		early_print("\nError: unrecognized/unsupported "
+			    "device tree compatible list:\n[ ");
+
+		prop = of_get_flat_dt_prop(dt_root, "compatible", &size);
+		while (size > 0) {
+			early_print("'%s' ", prop);
+			size -= strlen(prop) + 1;
+			prop += strlen(prop) + 1;
+		}
+		early_print("]\n\n");
+
+		dump_machine_table(); /* does not return */
+	}
+
+	model = of_get_flat_dt_prop(dt_root, "model", NULL);
+	if (!model)
+		model = of_get_flat_dt_prop(dt_root, "compatible", NULL);
+	if (!model)
+		model = "<unknown>";
+	pr_info("Machine: %s, model: %s\n", mdesc_best->name, model);
+
+	/* Retrieve various information from the /chosen node */
+	of_scan_flat_dt(early_init_dt_scan_chosen, boot_command_line);
+	/* Initialize {size,address}-cells info */
+	of_scan_flat_dt(early_init_dt_scan_root, NULL);
+	/* Setup memory, calling early_init_dt_add_memory_arch */
+	of_scan_flat_dt(early_init_dt_scan_memory, NULL);
+
+	/* Change machine number to match the mdesc we're using */
+	__machine_arch_type = mdesc_best->nr;
+
+	return mdesc_best;
+}
+
+/**
+ * irq_create_of_mapping - Hook to resolve OF irq specifier into a Linux irq#
+ *
+ * Currently the mapping mechanism is trivial; simple flat hwirq numbers are
+ * mapped 1:1 onto Linux irq numbers.  Cascaded irq controllers are not
+ * supported.
+ */
+unsigned int irq_create_of_mapping(struct device_node *controller,
+				   const u32 *intspec, unsigned int intsize)
+{
+	return intspec[0];
+}
+EXPORT_SYMBOL_GPL(irq_create_of_mapping);
diff -druN linux-2.6.39-libre/arch/arm/kernel/entry-armv.S linux-3.0-rc7-libre/arch/arm/kernel/entry-armv.S
--- linux-2.6.39-libre/arch/arm/kernel/entry-armv.S	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/kernel/entry-armv.S	2011-07-11 19:51:52.000000000 -0400
@@ -435,6 +435,10 @@
 	usr_entry
 	kuser_cmpxchg_check
 
+#ifdef CONFIG_IRQSOFF_TRACER
+	bl	trace_hardirqs_off
+#endif
+
 	get_thread_info tsk
 #ifdef CONFIG_PREEMPT
 	ldr	r8, [tsk, #TI_PREEMPT]		@ get preempt count
@@ -453,7 +457,7 @@
 #endif
 
 	mov	why, #0
-	b	ret_to_user
+	b	ret_to_user_from_irq
  UNWIND(.fnend		)
 ENDPROC(__irq_usr)
 
diff -druN linux-2.6.39-libre/arch/arm/kernel/entry-common.S linux-3.0-rc7-libre/arch/arm/kernel/entry-common.S
--- linux-2.6.39-libre/arch/arm/kernel/entry-common.S	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/kernel/entry-common.S	2011-07-11 19:51:52.000000000 -0400
@@ -64,6 +64,7 @@
 ENTRY(ret_to_user)
 ret_slow_syscall:
 	disable_irq				@ disable interrupts
+ENTRY(ret_to_user_from_irq)
 	ldr	r1, [tsk, #TI_FLAGS]
 	tst	r1, #_TIF_WORK_MASK
 	bne	work_pending
@@ -75,6 +76,7 @@
 	arch_ret_to_user r1, lr
 
 	restore_user_regs fast = 0, offset = 0
+ENDPROC(ret_to_user_from_irq)
 ENDPROC(ret_to_user)
 
 /*
diff -druN linux-2.6.39-libre/arch/arm/kernel/fiqasm.S linux-3.0-rc7-libre/arch/arm/kernel/fiqasm.S
--- linux-2.6.39-libre/arch/arm/kernel/fiqasm.S	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/arm/kernel/fiqasm.S	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,49 @@
+/*
+ *  linux/arch/arm/kernel/fiqasm.S
+ *
+ *  Derived from code originally in linux/arch/arm/kernel/fiq.c:
+ *
+ *  Copyright (C) 1998 Russell King
+ *  Copyright (C) 1998, 1999 Phil Blundell
+ *  Copyright (C) 2011, Linaro Limited
+ *
+ *  FIQ support written by Philip Blundell <philb@gnu.org>, 1998.
+ *
+ *  FIQ support re-written by Russell King to be more generic
+ *
+ *  v7/Thumb-2 compatibility modifications by Linaro Limited, 2011.
+ */
+
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+
+/*
+ * Taking an interrupt in FIQ mode is death, so both these functions
+ * disable irqs for the duration.
+ */
+
+ENTRY(__set_fiq_regs)
+	mov	r2, #PSR_I_BIT | PSR_F_BIT | FIQ_MODE
+	mrs	r1, cpsr
+	msr	cpsr_c, r2	@ select FIQ mode
+	mov	r0, r0		@ avoid hazard prior to ARMv4
+	ldmia	r0!, {r8 - r12}
+	ldr	sp, [r0], #4
+	ldr	lr, [r0]
+	msr	cpsr_c, r1	@ return to SVC mode
+	mov	r0, r0		@ avoid hazard prior to ARMv4
+	mov	pc, lr
+ENDPROC(__set_fiq_regs)
+
+ENTRY(__get_fiq_regs)
+	mov	r2, #PSR_I_BIT | PSR_F_BIT | FIQ_MODE
+	mrs	r1, cpsr
+	msr	cpsr_c, r2	@ select FIQ mode
+	mov	r0, r0		@ avoid hazard prior to ARMv4
+	stmia	r0!, {r8 - r12}
+	str	sp, [r0], #4
+	str	lr, [r0]
+	msr	cpsr_c, r1	@ return to SVC mode
+	mov	r0, r0		@ avoid hazard prior to ARMv4
+	mov	pc, lr
+ENDPROC(__get_fiq_regs)
diff -druN linux-2.6.39-libre/arch/arm/kernel/fiq.c linux-3.0-rc7-libre/arch/arm/kernel/fiq.c
--- linux-2.6.39-libre/arch/arm/kernel/fiq.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/kernel/fiq.c	2011-07-11 19:51:52.000000000 -0400
@@ -89,47 +89,6 @@
 		flush_icache_range(0x1c, 0x1c + length);
 }
 
-/*
- * Taking an interrupt in FIQ mode is death, so both these functions
- * disable irqs for the duration.  Note - these functions are almost
- * entirely coded in assembly.
- */
-void __naked set_fiq_regs(struct pt_regs *regs)
-{
-	register unsigned long tmp;
-	asm volatile (
-	"mov	ip, sp\n\
-	stmfd	sp!, {fp, ip, lr, pc}\n\
-	sub	fp, ip, #4\n\
-	mrs	%0, cpsr\n\
-	msr	cpsr_c, %2	@ select FIQ mode\n\
-	mov	r0, r0\n\
-	ldmia	%1, {r8 - r14}\n\
-	msr	cpsr_c, %0	@ return to SVC mode\n\
-	mov	r0, r0\n\
-	ldmfd	sp, {fp, sp, pc}"
-	: "=&r" (tmp)
-	: "r" (&regs->ARM_r8), "I" (PSR_I_BIT | PSR_F_BIT | FIQ_MODE));
-}
-
-void __naked get_fiq_regs(struct pt_regs *regs)
-{
-	register unsigned long tmp;
-	asm volatile (
-	"mov	ip, sp\n\
-	stmfd	sp!, {fp, ip, lr, pc}\n\
-	sub	fp, ip, #4\n\
-	mrs	%0, cpsr\n\
-	msr	cpsr_c, %2	@ select FIQ mode\n\
-	mov	r0, r0\n\
-	stmia	%1, {r8 - r14}\n\
-	msr	cpsr_c, %0	@ return to SVC mode\n\
-	mov	r0, r0\n\
-	ldmfd	sp, {fp, sp, pc}"
-	: "=&r" (tmp)
-	: "r" (&regs->ARM_r8), "I" (PSR_I_BIT | PSR_F_BIT | FIQ_MODE));
-}
-
 int claim_fiq(struct fiq_handler *f)
 {
 	int ret = 0;
@@ -174,8 +133,8 @@
 }
 
 EXPORT_SYMBOL(set_fiq_handler);
-EXPORT_SYMBOL(set_fiq_regs);
-EXPORT_SYMBOL(get_fiq_regs);
+EXPORT_SYMBOL(__set_fiq_regs);	/* defined in fiqasm.S */
+EXPORT_SYMBOL(__get_fiq_regs);	/* defined in fiqasm.S */
 EXPORT_SYMBOL(claim_fiq);
 EXPORT_SYMBOL(release_fiq);
 EXPORT_SYMBOL(enable_fiq);
diff -druN linux-2.6.39-libre/arch/arm/kernel/head-common.S linux-3.0-rc7-libre/arch/arm/kernel/head-common.S
--- linux-2.6.39-libre/arch/arm/kernel/head-common.S	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/kernel/head-common.S	2011-07-11 19:51:52.000000000 -0400
@@ -15,6 +15,12 @@
 #define ATAG_CORE_SIZE ((2*4 + 3*4) >> 2)
 #define ATAG_CORE_SIZE_EMPTY ((2*4) >> 2)
 
+#ifdef CONFIG_CPU_BIG_ENDIAN
+#define OF_DT_MAGIC 0xd00dfeed
+#else
+#define OF_DT_MAGIC 0xedfe0dd0 /* 0xd00dfeed in big-endian */
+#endif
+
 /*
  * Exception handling.  Something went wrong and we can't proceed.  We
  * ought to tell the user, but since we don't have any guarantee that
@@ -28,20 +34,26 @@
 
 /* Determine validity of the r2 atags pointer.  The heuristic requires
  * that the pointer be aligned, in the first 16k of physical RAM and
- * that the ATAG_CORE marker is first and present.  Future revisions
+ * that the ATAG_CORE marker is first and present.  If CONFIG_OF_FLATTREE
+ * is selected, then it will also accept a dtb pointer.  Future revisions
  * of this function may be more lenient with the physical address and
  * may also be able to move the ATAGS block if necessary.
  *
  * Returns:
- *  r2 either valid atags pointer, or zero
+ *  r2 either valid atags pointer, valid dtb pointer, or zero
  *  r5, r6 corrupted
  */
 __vet_atags:
 	tst	r2, #0x3			@ aligned?
 	bne	1f
 
-	ldr	r5, [r2, #0]			@ is first tag ATAG_CORE?
-	cmp	r5, #ATAG_CORE_SIZE
+	ldr	r5, [r2, #0]
+#ifdef CONFIG_OF_FLATTREE
+	ldr	r6, =OF_DT_MAGIC		@ is it a DTB?
+	cmp	r5, r6
+	beq	2f
+#endif
+	cmp	r5, #ATAG_CORE_SIZE		@ is first tag ATAG_CORE?
 	cmpne	r5, #ATAG_CORE_SIZE_EMPTY
 	bne	1f
 	ldr	r5, [r2, #4]
@@ -49,7 +61,7 @@
 	cmp	r5, r6
 	bne	1f
 
-	mov	pc, lr				@ atag pointer is ok
+2:	mov	pc, lr				@ atag/dtb pointer is ok
 
 1:	mov	r2, #0
 	mov	pc, lr
@@ -61,7 +73,7 @@
  *
  *  r0  = cp#15 control register
  *  r1  = machine ID
- *  r2  = atags pointer
+ *  r2  = atags/dtb pointer
  *  r9  = processor ID
  */
 	__INIT
diff -druN linux-2.6.39-libre/arch/arm/kernel/head.S linux-3.0-rc7-libre/arch/arm/kernel/head.S
--- linux-2.6.39-libre/arch/arm/kernel/head.S	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/kernel/head.S	2011-07-11 19:51:52.000000000 -0400
@@ -59,7 +59,7 @@
  *
  * This is normally called from the decompressor code.  The requirements
  * are: MMU = off, D-cache = off, I-cache = dont care, r0 = 0,
- * r1 = machine nr, r2 = atags pointer.
+ * r1 = machine nr, r2 = atags or dtb pointer.
  *
  * This code is mostly position independent, so if you link the kernel at
  * 0xc0008000, you call this at __pa(0xc0008000).
@@ -91,7 +91,7 @@
 #endif
 
 	/*
-	 * r1 = machine no, r2 = atags,
+	 * r1 = machine no, r2 = atags or dtb,
 	 * r8 = phys_offset, r9 = cpuid, r10 = procinfo
 	 */
 	bl	__vet_atags
@@ -113,6 +113,7 @@
 	ldr	r13, =__mmap_switched		@ address to jump to after
 						@ mmu has been enabled
 	adr	lr, BSYM(1f)			@ return (PIC) address
+	mov	r8, r4				@ set TTBR1 to swapper_pg_dir
  ARM(	add	pc, r10, #PROCINFO_INITFUNC	)
  THUMB(	add	r12, r10, #PROCINFO_INITFUNC	)
  THUMB(	mov	pc, r12				)
@@ -302,8 +303,10 @@
 	 */
 	adr	r4, __secondary_data
 	ldmia	r4, {r5, r7, r12}		@ address to jump to after
-	sub	r4, r4, r5			@ mmu has been enabled
-	ldr	r4, [r7, r4]			@ get secondary_data.pgdir
+	sub	lr, r4, r5			@ mmu has been enabled
+	ldr	r4, [r7, lr]			@ get secondary_data.pgdir
+	add	r7, r7, #4
+	ldr	r8, [r7, lr]			@ get secondary_data.swapper_pg_dir
 	adr	lr, BSYM(__enable_mmu)		@ return address
 	mov	r13, r12			@ __secondary_switched address
  ARM(	add	pc, r10, #PROCINFO_INITFUNC	) @ initialise processor
@@ -339,7 +342,7 @@
  *
  *  r0  = cp#15 control register
  *  r1  = machine ID
- *  r2  = atags pointer
+ *  r2  = atags or dtb pointer
  *  r4  = page table pointer
  *  r9  = processor ID
  *  r13 = *virtual* address to jump to upon completion
@@ -376,7 +379,7 @@
  *
  *  r0  = cp#15 control register
  *  r1  = machine ID
- *  r2  = atags pointer
+ *  r2  = atags or dtb pointer
  *  r9  = processor ID
  *  r13 = *virtual* address to jump to upon completion
  *
diff -druN linux-2.6.39-libre/arch/arm/kernel/leds.c linux-3.0-rc7-libre/arch/arm/kernel/leds.c
--- linux-2.6.39-libre/arch/arm/kernel/leds.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/kernel/leds.c	2011-07-11 19:51:52.000000000 -0400
@@ -10,6 +10,7 @@
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/sysdev.h>
+#include <linux/syscore_ops.h>
 
 #include <asm/leds.h>
 
@@ -69,36 +70,37 @@
 
 static SYSDEV_ATTR(event, 0200, NULL, leds_store);
 
-static int leds_suspend(struct sys_device *dev, pm_message_t state)
+static struct sysdev_class leds_sysclass = {
+	.name		= "leds",
+};
+
+static struct sys_device leds_device = {
+	.id		= 0,
+	.cls		= &leds_sysclass,
+};
+
+static int leds_suspend(void)
 {
 	leds_event(led_stop);
 	return 0;
 }
 
-static int leds_resume(struct sys_device *dev)
+static void leds_resume(void)
 {
 	leds_event(led_start);
-	return 0;
 }
 
-static int leds_shutdown(struct sys_device *dev)
+static void leds_shutdown(void)
 {
 	leds_event(led_halted);
-	return 0;
 }
 
-static struct sysdev_class leds_sysclass = {
-	.name		= "leds",
+static struct syscore_ops leds_syscore_ops = {
 	.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;
@@ -107,6 +109,8 @@
 		ret = sysdev_register(&leds_device);
 	if (ret == 0)
 		ret = sysdev_create_file(&leds_device, &attr_event);
+	if (ret == 0)
+		register_syscore_ops(&leds_syscore_ops);
 	return ret;
 }
 
diff -druN linux-2.6.39-libre/arch/arm/kernel/Makefile linux-3.0-rc7-libre/arch/arm/kernel/Makefile
--- linux-2.6.39-libre/arch/arm/kernel/Makefile	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/kernel/Makefile	2011-07-11 19:51:52.000000000 -0400
@@ -24,7 +24,7 @@
 
 obj-$(CONFIG_ISA_DMA_API)	+= dma.o
 obj-$(CONFIG_ARCH_ACORN)	+= ecard.o 
-obj-$(CONFIG_FIQ)		+= fiq.o
+obj-$(CONFIG_FIQ)		+= fiq.o fiqasm.o
 obj-$(CONFIG_MODULES)		+= armksyms.o module.o
 obj-$(CONFIG_ARTHUR)		+= arthur.o
 obj-$(CONFIG_ISA_DMA)		+= dma-isa.o
@@ -44,6 +44,7 @@
 obj-$(CONFIG_KGDB)		+= kgdb.o
 obj-$(CONFIG_ARM_UNWIND)	+= unwind.o
 obj-$(CONFIG_HAVE_TCM)		+= tcm.o
+obj-$(CONFIG_OF)		+= devtree.o
 obj-$(CONFIG_CRASH_DUMP)	+= crash_dump.o
 obj-$(CONFIG_SWP_EMULATE)	+= swp_emulate.o
 CFLAGS_swp_emulate.o		:= -Wa,-march=armv7-a
diff -druN linux-2.6.39-libre/arch/arm/kernel/module.c linux-3.0-rc7-libre/arch/arm/kernel/module.c
--- linux-2.6.39-libre/arch/arm/kernel/module.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/kernel/module.c	2011-07-11 19:51:52.000000000 -0400
@@ -193,8 +193,17 @@
 				offset -= 0x02000000;
 			offset += sym->st_value - loc;
 
-			/* only Thumb addresses allowed (no interworking) */
-			if (!(offset & 1) ||
+			/*
+			 * For function symbols, only Thumb addresses are
+			 * allowed (no interworking).
+			 *
+			 * For non-function symbols, the destination
+			 * has no specific ARM/Thumb disposition, so
+			 * the branch is resolved under the assumption
+			 * that interworking is not required.
+			 */
+			if ((ELF32_ST_TYPE(sym->st_info) == STT_FUNC &&
+				!(offset & 1)) ||
 			    offset <= (s32)0xff000000 ||
 			    offset >= (s32)0x01000000) {
 				pr_err("%s: section %u reloc %u sym '%s': relocation %u out of range (%#lx -> %#x)\n",
diff -druN linux-2.6.39-libre/arch/arm/kernel/perf_event.c linux-3.0-rc7-libre/arch/arm/kernel/perf_event.c
--- linux-2.6.39-libre/arch/arm/kernel/perf_event.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/kernel/perf_event.c	2011-07-11 19:51:52.000000000 -0400
@@ -560,11 +560,6 @@
 	event->destroy = hw_perf_event_destroy;
 
 	if (!atomic_inc_not_zero(&active_events)) {
-		if (atomic_read(&active_events) > armpmu->num_events) {
-			atomic_dec(&active_events);
-			return -ENOSPC;
-		}
-
 		mutex_lock(&pmu_reserve_mutex);
 		if (atomic_read(&active_events) == 0) {
 			err = armpmu_reserve_hardware();
@@ -588,7 +583,7 @@
 static void armpmu_enable(struct pmu *pmu)
 {
 	/* Enable all of the perf events on hardware. */
-	int idx;
+	int idx, enabled = 0;
 	struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
 
 	if (!armpmu)
@@ -601,9 +596,11 @@
 			continue;
 
 		armpmu->enable(&event->hw, idx);
+		enabled = 1;
 	}
 
-	armpmu->start();
+	if (enabled)
+		armpmu->start();
 }
 
 static void armpmu_disable(struct pmu *pmu)
diff -druN linux-2.6.39-libre/arch/arm/kernel/ptrace.c linux-3.0-rc7-libre/arch/arm/kernel/ptrace.c
--- linux-2.6.39-libre/arch/arm/kernel/ptrace.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/kernel/ptrace.c	2011-07-11 19:51:52.000000000 -0400
@@ -21,6 +21,7 @@
 #include <linux/uaccess.h>
 #include <linux/perf_event.h>
 #include <linux/hw_breakpoint.h>
+#include <linux/regset.h>
 
 #include <asm/pgtable.h>
 #include <asm/system.h>
@@ -308,58 +309,6 @@
 	return put_user_reg(tsk, off >> 2, val);
 }
 
-/*
- * Get all user integer registers.
- */
-static int ptrace_getregs(struct task_struct *tsk, void __user *uregs)
-{
-	struct pt_regs *regs = task_pt_regs(tsk);
-
-	return copy_to_user(uregs, regs, sizeof(struct pt_regs)) ? -EFAULT : 0;
-}
-
-/*
- * Set all user integer registers.
- */
-static int ptrace_setregs(struct task_struct *tsk, void __user *uregs)
-{
-	struct pt_regs newregs;
-	int ret;
-
-	ret = -EFAULT;
-	if (copy_from_user(&newregs, uregs, sizeof(struct pt_regs)) == 0) {
-		struct pt_regs *regs = task_pt_regs(tsk);
-
-		ret = -EINVAL;
-		if (valid_user_regs(&newregs)) {
-			*regs = newregs;
-			ret = 0;
-		}
-	}
-
-	return ret;
-}
-
-/*
- * Get the child FPU state.
- */
-static int ptrace_getfpregs(struct task_struct *tsk, void __user *ufp)
-{
-	return copy_to_user(ufp, &task_thread_info(tsk)->fpstate,
-			    sizeof(struct user_fp)) ? -EFAULT : 0;
-}
-
-/*
- * Set the child FPU state.
- */
-static int ptrace_setfpregs(struct task_struct *tsk, void __user *ufp)
-{
-	struct thread_info *thread = task_thread_info(tsk);
-	thread->used_cp[1] = thread->used_cp[2] = 1;
-	return copy_from_user(&thread->fpstate, ufp,
-			      sizeof(struct user_fp)) ? -EFAULT : 0;
-}
-
 #ifdef CONFIG_IWMMXT
 
 /*
@@ -418,56 +367,6 @@
 }
 #endif
 
-#ifdef CONFIG_VFP
-/*
- * Get the child VFP state.
- */
-static int ptrace_getvfpregs(struct task_struct *tsk, void __user *data)
-{
-	struct thread_info *thread = task_thread_info(tsk);
-	union vfp_state *vfp = &thread->vfpstate;
-	struct user_vfp __user *ufp = data;
-
-	vfp_sync_hwstate(thread);
-
-	/* copy the floating point registers */
-	if (copy_to_user(&ufp->fpregs, &vfp->hard.fpregs,
-			 sizeof(vfp->hard.fpregs)))
-		return -EFAULT;
-
-	/* copy the status and control register */
-	if (put_user(vfp->hard.fpscr, &ufp->fpscr))
-		return -EFAULT;
-
-	return 0;
-}
-
-/*
- * Set the child VFP state.
- */
-static int ptrace_setvfpregs(struct task_struct *tsk, void __user *data)
-{
-	struct thread_info *thread = task_thread_info(tsk);
-	union vfp_state *vfp = &thread->vfpstate;
-	struct user_vfp __user *ufp = data;
-
-	vfp_sync_hwstate(thread);
-
-	/* copy the floating point registers */
-	if (copy_from_user(&vfp->hard.fpregs, &ufp->fpregs,
-			   sizeof(vfp->hard.fpregs)))
-		return -EFAULT;
-
-	/* copy the status and control register */
-	if (get_user(vfp->hard.fpscr, &ufp->fpscr))
-		return -EFAULT;
-
-	vfp_flush_hwstate(thread);
-
-	return 0;
-}
-#endif
-
 #ifdef CONFIG_HAVE_HW_BREAKPOINT
 /*
  * Convert a virtual register number into an index for a thread_info
@@ -694,6 +593,219 @@
 }
 #endif
 
+/* regset get/set implementations */
+
+static int gpr_get(struct task_struct *target,
+		   const struct user_regset *regset,
+		   unsigned int pos, unsigned int count,
+		   void *kbuf, void __user *ubuf)
+{
+	struct pt_regs *regs = task_pt_regs(target);
+
+	return user_regset_copyout(&pos, &count, &kbuf, &ubuf,
+				   regs,
+				   0, sizeof(*regs));
+}
+
+static int gpr_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 pt_regs newregs;
+
+	ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
+				 &newregs,
+				 0, sizeof(newregs));
+	if (ret)
+		return ret;
+
+	if (!valid_user_regs(&newregs))
+		return -EINVAL;
+
+	*task_pt_regs(target) = newregs;
+	return 0;
+}
+
+static int fpa_get(struct task_struct *target,
+		   const struct user_regset *regset,
+		   unsigned int pos, unsigned int count,
+		   void *kbuf, void __user *ubuf)
+{
+	return user_regset_copyout(&pos, &count, &kbuf, &ubuf,
+				   &task_thread_info(target)->fpstate,
+				   0, sizeof(struct user_fp));
+}
+
+static int fpa_set(struct task_struct *target,
+		   const struct user_regset *regset,
+		   unsigned int pos, unsigned int count,
+		   const void *kbuf, const void __user *ubuf)
+{
+	struct thread_info *thread = task_thread_info(target);
+
+	thread->used_cp[1] = thread->used_cp[2] = 1;
+
+	return user_regset_copyin(&pos, &count, &kbuf, &ubuf,
+		&thread->fpstate,
+		0, sizeof(struct user_fp));
+}
+
+#ifdef CONFIG_VFP
+/*
+ * VFP register get/set implementations.
+ *
+ * With respect to the kernel, struct user_fp is divided into three chunks:
+ * 16 or 32 real VFP registers (d0-d15 or d0-31)
+ *	These are transferred to/from the real registers in the task's
+ *	vfp_hard_struct.  The number of registers depends on the kernel
+ *	configuration.
+ *
+ * 16 or 0 fake VFP registers (d16-d31 or empty)
+ *	i.e., the user_vfp structure has space for 32 registers even if
+ *	the kernel doesn't have them all.
+ *
+ *	vfp_get() reads this chunk as zero where applicable
+ *	vfp_set() ignores this chunk
+ *
+ * 1 word for the FPSCR
+ *
+ * The bounds-checking logic built into user_regset_copyout and friends
+ * means that we can make a simple sequence of calls to map the relevant data
+ * to/from the specified slice of the user regset structure.
+ */
+static int vfp_get(struct task_struct *target,
+		   const struct user_regset *regset,
+		   unsigned int pos, unsigned int count,
+		   void *kbuf, void __user *ubuf)
+{
+	int ret;
+	struct thread_info *thread = task_thread_info(target);
+	struct vfp_hard_struct const *vfp = &thread->vfpstate.hard;
+	const size_t user_fpregs_offset = offsetof(struct user_vfp, fpregs);
+	const size_t user_fpscr_offset = offsetof(struct user_vfp, fpscr);
+
+	vfp_sync_hwstate(thread);
+
+	ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
+				  &vfp->fpregs,
+				  user_fpregs_offset,
+				  user_fpregs_offset + sizeof(vfp->fpregs));
+	if (ret)
+		return ret;
+
+	ret = user_regset_copyout_zero(&pos, &count, &kbuf, &ubuf,
+				       user_fpregs_offset + sizeof(vfp->fpregs),
+				       user_fpscr_offset);
+	if (ret)
+		return ret;
+
+	return user_regset_copyout(&pos, &count, &kbuf, &ubuf,
+				   &vfp->fpscr,
+				   user_fpscr_offset,
+				   user_fpscr_offset + sizeof(vfp->fpscr));
+}
+
+/*
+ * For vfp_set() a read-modify-write is done on the VFP registers,
+ * in order to avoid writing back a half-modified set of registers on
+ * failure.
+ */
+static int vfp_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 thread_info *thread = task_thread_info(target);
+	struct vfp_hard_struct new_vfp = thread->vfpstate.hard;
+	const size_t user_fpregs_offset = offsetof(struct user_vfp, fpregs);
+	const size_t user_fpscr_offset = offsetof(struct user_vfp, fpscr);
+
+	ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
+				  &new_vfp.fpregs,
+				  user_fpregs_offset,
+				  user_fpregs_offset + sizeof(new_vfp.fpregs));
+	if (ret)
+		return ret;
+
+	ret = user_regset_copyin_ignore(&pos, &count, &kbuf, &ubuf,
+				user_fpregs_offset + sizeof(new_vfp.fpregs),
+				user_fpscr_offset);
+	if (ret)
+		return ret;
+
+	ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
+				 &new_vfp.fpscr,
+				 user_fpscr_offset,
+				 user_fpscr_offset + sizeof(new_vfp.fpscr));
+	if (ret)
+		return ret;
+
+	vfp_sync_hwstate(thread);
+	thread->vfpstate.hard = new_vfp;
+	vfp_flush_hwstate(thread);
+
+	return 0;
+}
+#endif /* CONFIG_VFP */
+
+enum arm_regset {
+	REGSET_GPR,
+	REGSET_FPR,
+#ifdef CONFIG_VFP
+	REGSET_VFP,
+#endif
+};
+
+static const struct user_regset arm_regsets[] = {
+	[REGSET_GPR] = {
+		.core_note_type = NT_PRSTATUS,
+		.n = ELF_NGREG,
+		.size = sizeof(u32),
+		.align = sizeof(u32),
+		.get = gpr_get,
+		.set = gpr_set
+	},
+	[REGSET_FPR] = {
+		/*
+		 * For the FPA regs in fpstate, the real fields are a mixture
+		 * of sizes, so pretend that the registers are word-sized:
+		 */
+		.core_note_type = NT_PRFPREG,
+		.n = sizeof(struct user_fp) / sizeof(u32),
+		.size = sizeof(u32),
+		.align = sizeof(u32),
+		.get = fpa_get,
+		.set = fpa_set
+	},
+#ifdef CONFIG_VFP
+	[REGSET_VFP] = {
+		/*
+		 * Pretend that the VFP regs are word-sized, since the FPSCR is
+		 * a single word dangling at the end of struct user_vfp:
+		 */
+		.core_note_type = NT_ARM_VFP,
+		.n = ARM_VFPREGS_SIZE / sizeof(u32),
+		.size = sizeof(u32),
+		.align = sizeof(u32),
+		.get = vfp_get,
+		.set = vfp_set
+	},
+#endif /* CONFIG_VFP */
+};
+
+static const struct user_regset_view user_arm_view = {
+	.name = "arm", .e_machine = ELF_ARCH, .ei_osabi = ELF_OSABI,
+	.regsets = arm_regsets, .n = ARRAY_SIZE(arm_regsets)
+};
+
+const struct user_regset_view *task_user_regset_view(struct task_struct *task)
+{
+	return &user_arm_view;
+}
+
 long arch_ptrace(struct task_struct *child, long request,
 		 unsigned long addr, unsigned long data)
 {
@@ -710,19 +822,31 @@
 			break;
 
 		case PTRACE_GETREGS:
-			ret = ptrace_getregs(child, datap);
+			ret = copy_regset_to_user(child,
+						  &user_arm_view, REGSET_GPR,
+						  0, sizeof(struct pt_regs),
+						  datap);
 			break;
 
 		case PTRACE_SETREGS:
-			ret = ptrace_setregs(child, datap);
+			ret = copy_regset_from_user(child,
+						    &user_arm_view, REGSET_GPR,
+						    0, sizeof(struct pt_regs),
+						    datap);
 			break;
 
 		case PTRACE_GETFPREGS:
-			ret = ptrace_getfpregs(child, datap);
+			ret = copy_regset_to_user(child,
+						  &user_arm_view, REGSET_FPR,
+						  0, sizeof(union fp_state),
+						  datap);
 			break;
-		
+
 		case PTRACE_SETFPREGS:
-			ret = ptrace_setfpregs(child, datap);
+			ret = copy_regset_from_user(child,
+						    &user_arm_view, REGSET_FPR,
+						    0, sizeof(union fp_state),
+						    datap);
 			break;
 
 #ifdef CONFIG_IWMMXT
@@ -757,11 +881,17 @@
 
 #ifdef CONFIG_VFP
 		case PTRACE_GETVFPREGS:
-			ret = ptrace_getvfpregs(child, datap);
+			ret = copy_regset_to_user(child,
+						  &user_arm_view, REGSET_VFP,
+						  0, ARM_VFPREGS_SIZE,
+						  datap);
 			break;
 
 		case PTRACE_SETVFPREGS:
-			ret = ptrace_setvfpregs(child, datap);
+			ret = copy_regset_from_user(child,
+						    &user_arm_view, REGSET_VFP,
+						    0, ARM_VFPREGS_SIZE,
+						    datap);
 			break;
 #endif
 
diff -druN linux-2.6.39-libre/arch/arm/kernel/setup.c linux-3.0-rc7-libre/arch/arm/kernel/setup.c
--- linux-2.6.39-libre/arch/arm/kernel/setup.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/kernel/setup.c	2011-07-11 19:51:52.000000000 -0400
@@ -20,6 +20,7 @@
 #include <linux/screen_info.h>
 #include <linux/init.h>
 #include <linux/kexec.h>
+#include <linux/of_fdt.h>
 #include <linux/crash_dump.h>
 #include <linux/root_dev.h>
 #include <linux/cpu.h>
@@ -42,6 +43,7 @@
 #include <asm/cachetype.h>
 #include <asm/tlbflush.h>
 
+#include <asm/prom.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/irq.h>
 #include <asm/mach/time.h>
@@ -71,6 +73,7 @@
 #endif
 
 extern void paging_init(struct machine_desc *desc);
+extern void sanity_check_meminfo(void);
 extern void reboot_setup(char *str);
 
 unsigned int processor_id;
@@ -309,7 +312,7 @@
  */
 extern struct proc_info_list *lookup_processor_type(unsigned int);
 
-static void __init early_print(const char *str, ...)
+void __init early_print(const char *str, ...)
 {
 	extern void printascii(const char *);
 	char buf[256];
@@ -439,25 +442,12 @@
 	    : "r14");
 }
 
-static struct machine_desc * __init setup_machine(unsigned int nr)
+void __init dump_machine_table(void)
 {
-	extern struct machine_desc __arch_info_begin[], __arch_info_end[];
 	struct machine_desc *p;
 
-	/*
-	 * locate machine in the list of supported machines.
-	 */
-	for (p = __arch_info_begin; p < __arch_info_end; p++)
-		if (nr == p->nr) {
-			printk("Machine: %s\n", p->name);
-			return p;
-		}
-
-	early_print("\n"
-		"Error: unrecognized/unsupported machine ID (r1 = 0x%08x).\n\n"
-		"Available machine support:\n\nID (hex)\tNAME\n", nr);
-
-	for (p = __arch_info_begin; p < __arch_info_end; p++)
+	early_print("Available machine support:\n\nID (hex)\tNAME\n");
+	for_each_machine_desc(p)
 		early_print("%08x\t%s\n", p->nr, p->name);
 
 	early_print("\nPlease check your kernel config and/or bootloader.\n");
@@ -466,7 +456,7 @@
 		/* can't use cpu_relax() here as it may require MMU setup */;
 }
 
-static int __init arm_add_memory(phys_addr_t start, unsigned long size)
+int __init arm_add_memory(phys_addr_t start, unsigned long size)
 {
 	struct membank *bank = &meminfo.bank[meminfo.nr_banks];
 
@@ -672,11 +662,16 @@
 
 static int __init parse_tag_cmdline(const struct tag *tag)
 {
-#ifndef CONFIG_CMDLINE_FORCE
-	strlcpy(default_command_line, tag->u.cmdline.cmdline, COMMAND_LINE_SIZE);
-#else
+#if defined(CONFIG_CMDLINE_EXTEND)
+	strlcat(default_command_line, " ", COMMAND_LINE_SIZE);
+	strlcat(default_command_line, tag->u.cmdline.cmdline,
+		COMMAND_LINE_SIZE);
+#elif defined(CONFIG_CMDLINE_FORCE)
 	pr_warning("Ignoring tag cmdline (using the default kernel command line)\n");
-#endif /* CONFIG_CMDLINE_FORCE */
+#else
+	strlcpy(default_command_line, tag->u.cmdline.cmdline,
+		COMMAND_LINE_SIZE);
+#endif
 	return 0;
 }
 
@@ -796,23 +791,29 @@
 			tag->hdr.tag = ATAG_NONE;
 }
 
-void __init setup_arch(char **cmdline_p)
+static struct machine_desc * __init setup_machine_tags(unsigned int nr)
 {
 	struct tag *tags = (struct tag *)&init_tags;
-	struct machine_desc *mdesc;
+	struct machine_desc *mdesc = NULL, *p;
 	char *from = default_command_line;
 
 	init_tags.mem.start = PHYS_OFFSET;
 
-	unwind_init();
-
-	setup_processor();
-	mdesc = setup_machine(machine_arch_type);
-	machine_desc = mdesc;
-	machine_name = mdesc->name;
+	/*
+	 * locate machine in the list of supported machines.
+	 */
+	for_each_machine_desc(p)
+		if (nr == p->nr) {
+			printk("Machine: %s\n", p->name);
+			mdesc = p;
+			break;
+		}
 
-	if (mdesc->soft_reboot)
-		reboot_setup("s");
+	if (!mdesc) {
+		early_print("\nError: unrecognized/unsupported machine ID"
+			" (r1 = 0x%08x).\n\n", nr);
+		dump_machine_table(); /* does not return */
+	}
 
 	if (__atags_pointer)
 		tags = phys_to_virt(__atags_pointer);
@@ -844,8 +845,17 @@
 	if (tags->hdr.tag != ATAG_CORE)
 		convert_to_tag_list(tags);
 #endif
-	if (tags->hdr.tag != ATAG_CORE)
+
+	if (tags->hdr.tag != ATAG_CORE) {
+#if defined(CONFIG_OF)
+		/*
+		 * If CONFIG_OF is set, then assume this is a reasonably
+		 * modern system that should pass boot parameters
+		 */
+		early_print("Warning: Neither atags nor dtb found\n");
+#endif
 		tags = (struct tag *)&init_tags;
+	}
 
 	if (mdesc->fixup)
 		mdesc->fixup(mdesc, tags, &from, &meminfo);
@@ -857,25 +867,48 @@
 		parse_tags(tags);
 	}
 
+	/* parse_early_param needs a boot_command_line */
+	strlcpy(boot_command_line, from, COMMAND_LINE_SIZE);
+
+	return mdesc;
+}
+
+
+void __init setup_arch(char **cmdline_p)
+{
+	struct machine_desc *mdesc;
+
+	unwind_init();
+
+	setup_processor();
+	mdesc = setup_machine_fdt(__atags_pointer);
+	if (!mdesc)
+		mdesc = setup_machine_tags(machine_arch_type);
+	machine_desc = mdesc;
+	machine_name = mdesc->name;
+
+	if (mdesc->soft_reboot)
+		reboot_setup("s");
+
 	init_mm.start_code = (unsigned long) _text;
 	init_mm.end_code   = (unsigned long) _etext;
 	init_mm.end_data   = (unsigned long) _edata;
 	init_mm.brk	   = (unsigned long) _end;
 
-	/* 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();
 
+	sanity_check_meminfo();
 	arm_memblock_init(&meminfo, mdesc);
 
 	paging_init(mdesc);
 	request_standard_resources(mdesc);
 
+	unflatten_device_tree();
+
 #ifdef CONFIG_SMP
 	if (is_smp())
 		smp_init_cpus();
diff -druN linux-2.6.39-libre/arch/arm/kernel/smp.c linux-3.0-rc7-libre/arch/arm/kernel/smp.c
--- linux-2.6.39-libre/arch/arm/kernel/smp.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/kernel/smp.c	2011-07-11 19:51:52.000000000 -0400
@@ -105,6 +105,7 @@
 	 */
 	secondary_data.stack = task_stack_page(idle) + THREAD_START_SP;
 	secondary_data.pgdir = virt_to_phys(pgd);
+	secondary_data.swapper_pg_dir = virt_to_phys(swapper_pg_dir);
 	__cpuc_flush_dcache_area(&secondary_data, sizeof(secondary_data));
 	outer_clean_range(__pa(&secondary_data), __pa(&secondary_data + 1));
 
@@ -317,9 +318,13 @@
 	smp_store_cpu_info(cpu);
 
 	/*
-	 * OK, now it's safe to let the boot CPU continue
+	 * OK, now it's safe to let the boot CPU continue.  Wait for
+	 * the CPU migration code to notice that the CPU is online
+	 * before we continue.
 	 */
 	set_cpu_online(cpu, true);
+	while (!cpu_active(cpu))
+		cpu_relax();
 
 	/*
 	 * OK, it's off to the idle thread for us
@@ -376,6 +381,13 @@
 	}
 }
 
+static void (*smp_cross_call)(const struct cpumask *, unsigned int);
+
+void __init set_smp_cross_call(void (*fn)(const struct cpumask *, unsigned int))
+{
+	smp_cross_call = fn;
+}
+
 void arch_send_call_function_ipi_mask(const struct cpumask *mask)
 {
 	smp_cross_call(mask, IPI_CALL_FUNC);
@@ -560,10 +572,7 @@
 		break;
 
 	case IPI_RESCHEDULE:
-		/*
-		 * nothing more to do - eveything is
-		 * done on the interrupt return path
-		 */
+		scheduler_ipi();
 		break;
 
 	case IPI_CALL_FUNC:
diff -druN linux-2.6.39-libre/arch/arm/kernel/smp_twd.c linux-3.0-rc7-libre/arch/arm/kernel/smp_twd.c
--- linux-2.6.39-libre/arch/arm/kernel/smp_twd.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/kernel/smp_twd.c	2011-07-11 19:51:52.000000000 -0400
@@ -115,7 +115,7 @@
 		twd_timer_rate = (0xFFFFFFFFU - count) * (HZ / 5);
 
 		printk("%lu.%02luMHz.\n", twd_timer_rate / 1000000,
-			(twd_timer_rate / 1000000) % 100);
+			(twd_timer_rate / 10000) % 100);
 	}
 }
 
diff -druN linux-2.6.39-libre/arch/arm/kernel/time.c linux-3.0-rc7-libre/arch/arm/kernel/time.c
--- linux-2.6.39-libre/arch/arm/kernel/time.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/kernel/time.c	2011-07-11 19:51:52.000000000 -0400
@@ -21,7 +21,7 @@
 #include <linux/timex.h>
 #include <linux/errno.h>
 #include <linux/profile.h>
-#include <linux/sysdev.h>
+#include <linux/syscore_ops.h>
 #include <linux/timer.h>
 #include <linux/irq.h>
 
@@ -115,48 +115,37 @@
 #endif
 
 #if defined(CONFIG_PM) && !defined(CONFIG_GENERIC_CLOCKEVENTS)
-static int timer_suspend(struct sys_device *dev, pm_message_t state)
+static int timer_suspend(void)
 {
-	struct sys_timer *timer = container_of(dev, struct sys_timer, dev);
-
-	if (timer->suspend != NULL)
-		timer->suspend();
+	if (system_timer->suspend)
+		system_timer->suspend();
 
 	return 0;
 }
 
-static int timer_resume(struct sys_device *dev)
+static void timer_resume(void)
 {
-	struct sys_timer *timer = container_of(dev, struct sys_timer, dev);
-
-	if (timer->resume != NULL)
-		timer->resume();
-
-	return 0;
+	if (system_timer->resume)
+		system_timer->resume();
 }
 #else
 #define timer_suspend NULL
 #define timer_resume NULL
 #endif
 
-static struct sysdev_class timer_sysclass = {
-	.name		= "timer",
+static struct syscore_ops timer_syscore_ops = {
 	.suspend	= timer_suspend,
 	.resume		= timer_resume,
 };
 
-static int __init timer_init_sysfs(void)
+static int __init timer_init_syscore_ops(void)
 {
-	int ret = sysdev_class_register(&timer_sysclass);
-	if (ret == 0) {
-		system_timer->dev.cls = &timer_sysclass;
-		ret = sysdev_register(&system_timer->dev);
-	}
+	register_syscore_ops(&timer_syscore_ops);
 
-	return ret;
+	return 0;
 }
 
-device_initcall(timer_init_sysfs);
+device_initcall(timer_init_syscore_ops);
 
 void __init time_init(void)
 {
diff -druN linux-2.6.39-libre/arch/arm/kernel/traps.c linux-3.0-rc7-libre/arch/arm/kernel/traps.c
--- linux-2.6.39-libre/arch/arm/kernel/traps.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/kernel/traps.c	2011-07-11 19:51:52.000000000 -0400
@@ -139,7 +139,7 @@
 	fs = get_fs();
 	set_fs(KERNEL_DS);
 
-	for (i = -4; i < 1; i++) {
+	for (i = -4; i < 1 + !!thumb; i++) {
 		unsigned int val, bad;
 
 		if (thumb)
@@ -234,7 +234,6 @@
 
 	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);
@@ -564,7 +563,7 @@
 		if (!pmd_present(*pmd))
 			goto bad_access;
 		pte = pte_offset_map_lock(mm, pmd, addr, &ptl);
-		if (!pte_present(*pte) || !pte_dirty(*pte)) {
+		if (!pte_present(*pte) || !pte_write(*pte) || !pte_dirty(*pte)) {
 			pte_unmap_unlock(pte, ptl);
 			goto bad_access;
 		}
diff -druN linux-2.6.39-libre/arch/arm/kernel/vmlinux.lds.S linux-3.0-rc7-libre/arch/arm/kernel/vmlinux.lds.S
--- linux-2.6.39-libre/arch/arm/kernel/vmlinux.lds.S	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/kernel/vmlinux.lds.S	2011-07-11 19:51:52.000000000 -0400
@@ -82,7 +82,7 @@
 #endif
 	}
 
-	PERCPU(32, PAGE_SIZE)
+	PERCPU_SECTION(32)
 
 #ifndef CONFIG_XIP_KERNEL
 	. = ALIGN(PAGE_SIZE);
diff -druN linux-2.6.39-libre/arch/arm/lib/lib1funcs.S linux-3.0-rc7-libre/arch/arm/lib/lib1funcs.S
--- linux-2.6.39-libre/arch/arm/lib/lib1funcs.S	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/lib/lib1funcs.S	2011-07-11 19:51:52.000000000 -0400
@@ -35,7 +35,7 @@
 
 #include <linux/linkage.h>
 #include <asm/assembler.h>
-
+#include <asm/unwind.h>
 
 .macro ARM_DIV_BODY dividend, divisor, result, curbit
 
@@ -207,6 +207,7 @@
 
 ENTRY(__udivsi3)
 ENTRY(__aeabi_uidiv)
+UNWIND(.fnstart)
 
 	subs	r2, r1, #1
 	moveq	pc, lr
@@ -230,10 +231,12 @@
 	mov	r0, r0, lsr r2
 	mov	pc, lr
 
+UNWIND(.fnend)
 ENDPROC(__udivsi3)
 ENDPROC(__aeabi_uidiv)
 
 ENTRY(__umodsi3)
+UNWIND(.fnstart)
 
 	subs	r2, r1, #1			@ compare divisor with 1
 	bcc	Ldiv0
@@ -247,10 +250,12 @@
 
 	mov	pc, lr
 
+UNWIND(.fnend)
 ENDPROC(__umodsi3)
 
 ENTRY(__divsi3)
 ENTRY(__aeabi_idiv)
+UNWIND(.fnstart)
 
 	cmp	r1, #0
 	eor	ip, r0, r1			@ save the sign of the result.
@@ -287,10 +292,12 @@
 	rsbmi	r0, r0, #0
 	mov	pc, lr
 
+UNWIND(.fnend)
 ENDPROC(__divsi3)
 ENDPROC(__aeabi_idiv)
 
 ENTRY(__modsi3)
+UNWIND(.fnstart)
 
 	cmp	r1, #0
 	beq	Ldiv0
@@ -310,11 +317,14 @@
 	rsbmi	r0, r0, #0
 	mov	pc, lr
 
+UNWIND(.fnend)
 ENDPROC(__modsi3)
 
 #ifdef CONFIG_AEABI
 
 ENTRY(__aeabi_uidivmod)
+UNWIND(.fnstart)
+UNWIND(.save {r0, r1, ip, lr}	)
 
 	stmfd	sp!, {r0, r1, ip, lr}
 	bl	__aeabi_uidiv
@@ -323,10 +333,12 @@
 	sub	r1, r1, r3
 	mov	pc, lr
 
+UNWIND(.fnend)
 ENDPROC(__aeabi_uidivmod)
 
 ENTRY(__aeabi_idivmod)
-
+UNWIND(.fnstart)
+UNWIND(.save {r0, r1, ip, lr}	)
 	stmfd	sp!, {r0, r1, ip, lr}
 	bl	__aeabi_idiv
 	ldmfd	sp!, {r1, r2, ip, lr}
@@ -334,15 +346,18 @@
 	sub	r1, r1, r3
 	mov	pc, lr
 
+UNWIND(.fnend)
 ENDPROC(__aeabi_idivmod)
 
 #endif
 
 Ldiv0:
-
+UNWIND(.fnstart)
+UNWIND(.pad #4)
+UNWIND(.save {lr})
 	str	lr, [sp, #-8]!
 	bl	__div0
 	mov	r0, #0			@ About as wrong as it could be.
 	ldr	pc, [sp], #8
-
-
+UNWIND(.fnend)
+ENDPROC(Ldiv0)
diff -druN linux-2.6.39-libre/arch/arm/mach-at91/at572d940hf.c linux-3.0-rc7-libre/arch/arm/mach-at91/at572d940hf.c
--- linux-2.6.39-libre/arch/arm/mach-at91/at572d940hf.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-at91/at572d940hf.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,377 +0,0 @@
-/*
- * 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 -druN linux-2.6.39-libre/arch/arm/mach-at91/at572d940hf_devices.c linux-3.0-rc7-libre/arch/arm/mach-at91/at572d940hf_devices.c
--- linux-2.6.39-libre/arch/arm/mach-at91/at572d940hf_devices.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-at91/at572d940hf_devices.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,970 +0,0 @@
-/*
- * 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 -druN linux-2.6.39-libre/arch/arm/mach-at91/at91cap9.c linux-3.0-rc7-libre/arch/arm/mach-at91/at91cap9.c
--- linux-2.6.39-libre/arch/arm/mach-at91/at91cap9.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-at91/at91cap9.c	2011-07-11 19:51:52.000000000 -0400
@@ -222,6 +222,25 @@
 	// irq0 .. irq1
 };
 
+static struct clk_lookup periph_clocks_lookups[] = {
+	CLKDEV_CON_DEV_ID("hclk", "atmel_usba_udc", &utmi_clk),
+	CLKDEV_CON_DEV_ID("pclk", "atmel_usba_udc", &udphs_clk),
+	CLKDEV_CON_DEV_ID("mci_clk", "at91_mci.0", &mmc0_clk),
+	CLKDEV_CON_DEV_ID("mci_clk", "at91_mci.1", &mmc1_clk),
+	CLKDEV_CON_DEV_ID("spi_clk", "atmel_spi.0", &spi0_clk),
+	CLKDEV_CON_DEV_ID("spi_clk", "atmel_spi.1", &spi1_clk),
+	CLKDEV_CON_DEV_ID("t0_clk", "atmel_tcb.0", &tcb_clk),
+	CLKDEV_CON_DEV_ID("pclk", "ssc.0", &ssc0_clk),
+	CLKDEV_CON_DEV_ID("pclk", "ssc.1", &ssc1_clk),
+};
+
+static struct clk_lookup usart_clocks_lookups[] = {
+	CLKDEV_CON_DEV_ID("usart", "atmel_usart.0", &mck),
+	CLKDEV_CON_DEV_ID("usart", "atmel_usart.1", &usart0_clk),
+	CLKDEV_CON_DEV_ID("usart", "atmel_usart.2", &usart1_clk),
+	CLKDEV_CON_DEV_ID("usart", "atmel_usart.3", &usart2_clk),
+};
+
 /*
  * The four programmable clocks.
  * You must configure pin multiplexing to bring these signals out.
@@ -258,12 +277,29 @@
 	for (i = 0; i < ARRAY_SIZE(periph_clocks); i++)
 		clk_register(periph_clocks[i]);
 
+	clkdev_add_table(periph_clocks_lookups,
+			 ARRAY_SIZE(periph_clocks_lookups));
+	clkdev_add_table(usart_clocks_lookups,
+			 ARRAY_SIZE(usart_clocks_lookups));
+
 	clk_register(&pck0);
 	clk_register(&pck1);
 	clk_register(&pck2);
 	clk_register(&pck3);
 }
 
+static struct clk_lookup console_clock_lookup;
+
+void __init at91cap9_set_console_clock(int id)
+{
+	if (id >= ARRAY_SIZE(usart_clocks_lookups))
+		return;
+
+	console_clock_lookup.con_id = "usart";
+	console_clock_lookup.clk = usart_clocks_lookups[id].clk;
+	clkdev_add(&console_clock_lookup);
+}
+
 /* --------------------------------------------------------------------
  *  GPIO
  * -------------------------------------------------------------------- */
@@ -303,11 +339,14 @@
  *  AT91CAP9 processor initialization
  * -------------------------------------------------------------------- */
 
-void __init at91cap9_initialize(unsigned long main_clock)
+void __init at91cap9_map_io(void)
 {
 	/* Map peripherals */
 	iotable_init(at91cap9_io_desc, ARRAY_SIZE(at91cap9_io_desc));
+}
 
+void __init at91cap9_initialize(unsigned long main_clock)
+{
 	at91_arch_reset = at91cap9_reset;
 	pm_power_off = at91cap9_poweroff;
 	at91_extern_irq = (1 << AT91CAP9_ID_IRQ0) | (1 << AT91CAP9_ID_IRQ1);
diff -druN linux-2.6.39-libre/arch/arm/mach-at91/at91cap9_devices.c linux-3.0-rc7-libre/arch/arm/mach-at91/at91cap9_devices.c
--- linux-2.6.39-libre/arch/arm/mach-at91/at91cap9_devices.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-at91/at91cap9_devices.c	2011-07-11 19:51:52.000000000 -0400
@@ -171,7 +171,7 @@
 	 */
 	usba_udc_data.pdata.vbus_pin = -EINVAL;
 	usba_udc_data.pdata.num_ep = ARRAY_SIZE(usba_udc_ep);
-	memcpy(usba_udc_data.ep, usba_udc_ep, sizeof(usba_udc_ep));;
+	memcpy(usba_udc_data.ep, usba_udc_ep, sizeof(usba_udc_ep));
 
 	if (data && data->vbus_pin > 0) {
 		at91_set_gpio_input(data->vbus_pin, 0);
@@ -181,10 +181,6 @@
 
 	/* Pullup pin is handled internally by USB device peripheral */
 
-	/* Clocks */
-	at91_clock_associate("utmi_clk", &at91_usba_udc_device.dev, "hclk");
-	at91_clock_associate("udphs_clk", &at91_usba_udc_device.dev, "pclk");
-
 	platform_device_register(&at91_usba_udc_device);
 }
 #else
@@ -355,7 +351,6 @@
 		}
 
 		mmc0_data = *data;
-		at91_clock_associate("mci0_clk", &at91cap9_mmc0_device.dev, "mci_clk");
 		platform_device_register(&at91cap9_mmc0_device);
 	} else {			/* MCI1 */
 		/* CLK */
@@ -373,7 +368,6 @@
 		}
 
 		mmc1_data = *data;
-		at91_clock_associate("mci1_clk", &at91cap9_mmc1_device.dev, "mci_clk");
 		platform_device_register(&at91cap9_mmc1_device);
 	}
 }
@@ -614,7 +608,6 @@
 		at91_set_B_periph(AT91_PIN_PA1, 0);	/* SPI0_MOSI */
 		at91_set_B_periph(AT91_PIN_PA2, 0);	/* SPI0_SPCK */
 
-		at91_clock_associate("spi0_clk", &at91cap9_spi0_device.dev, "spi_clk");
 		platform_device_register(&at91cap9_spi0_device);
 	}
 	if (enable_spi1) {
@@ -622,7 +615,6 @@
 		at91_set_A_periph(AT91_PIN_PB13, 0);	/* SPI1_MOSI */
 		at91_set_A_periph(AT91_PIN_PB14, 0);	/* SPI1_SPCK */
 
-		at91_clock_associate("spi1_clk", &at91cap9_spi1_device.dev, "spi_clk");
 		platform_device_register(&at91cap9_spi1_device);
 	}
 }
@@ -659,8 +651,6 @@
 
 static void __init at91_add_device_tc(void)
 {
-	/* this chip has one clock and irq for all three TC channels */
-	at91_clock_associate("tcb_clk", &at91cap9_tcb_device.dev, "t0_clk");
 	platform_device_register(&at91cap9_tcb_device);
 }
 #else
@@ -1001,12 +991,10 @@
 	case AT91CAP9_ID_SSC0:
 		pdev = &at91cap9_ssc0_device;
 		configure_ssc0_pins(pins);
-		at91_clock_associate("ssc0_clk", &pdev->dev, "ssc");
 		break;
 	case AT91CAP9_ID_SSC1:
 		pdev = &at91cap9_ssc1_device;
 		configure_ssc1_pins(pins);
-		at91_clock_associate("ssc1_clk", &pdev->dev, "ssc");
 		break;
 	default:
 		return;
@@ -1199,32 +1187,30 @@
 void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins)
 {
 	struct platform_device *pdev;
+	struct atmel_uart_data *pdata;
 
 	switch (id) {
 		case 0:		/* DBGU */
 			pdev = &at91cap9_dbgu_device;
 			configure_dbgu_pins();
-			at91_clock_associate("mck", &pdev->dev, "usart");
 			break;
 		case AT91CAP9_ID_US0:
 			pdev = &at91cap9_uart0_device;
 			configure_usart0_pins(pins);
-			at91_clock_associate("usart0_clk", &pdev->dev, "usart");
 			break;
 		case AT91CAP9_ID_US1:
 			pdev = &at91cap9_uart1_device;
 			configure_usart1_pins(pins);
-			at91_clock_associate("usart1_clk", &pdev->dev, "usart");
 			break;
 		case AT91CAP9_ID_US2:
 			pdev = &at91cap9_uart2_device;
 			configure_usart2_pins(pins);
-			at91_clock_associate("usart2_clk", &pdev->dev, "usart");
 			break;
 		default:
 			return;
 	}
-	pdev->id = portnr;		/* update to mapped ID */
+	pdata = pdev->dev.platform_data;
+	pdata->num = portnr;		/* update to mapped ID */
 
 	if (portnr < ATMEL_MAX_UART)
 		at91_uarts[portnr] = pdev;
@@ -1232,8 +1218,10 @@
 
 void __init at91_set_serial_console(unsigned portnr)
 {
-	if (portnr < ATMEL_MAX_UART)
+	if (portnr < ATMEL_MAX_UART) {
 		atmel_default_console_device = at91_uarts[portnr];
+		at91cap9_set_console_clock(at91_uarts[portnr]->id);
+	}
 }
 
 void __init at91_add_device_serial(void)
diff -druN linux-2.6.39-libre/arch/arm/mach-at91/at91rm9200.c linux-3.0-rc7-libre/arch/arm/mach-at91/at91rm9200.c
--- linux-2.6.39-libre/arch/arm/mach-at91/at91rm9200.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-at91/at91rm9200.c	2011-07-11 19:51:52.000000000 -0400
@@ -18,6 +18,7 @@
 #include <mach/at91rm9200.h>
 #include <mach/at91_pmc.h>
 #include <mach/at91_st.h>
+#include <mach/cpu.h>
 
 #include "generic.h"
 #include "clock.h"
@@ -191,6 +192,26 @@
 	// irq0 .. irq6
 };
 
+static struct clk_lookup periph_clocks_lookups[] = {
+	CLKDEV_CON_DEV_ID("t0_clk", "atmel_tcb.0", &tc0_clk),
+	CLKDEV_CON_DEV_ID("t1_clk", "atmel_tcb.0", &tc1_clk),
+	CLKDEV_CON_DEV_ID("t2_clk", "atmel_tcb.0", &tc2_clk),
+	CLKDEV_CON_DEV_ID("t0_clk", "atmel_tcb.1", &tc3_clk),
+	CLKDEV_CON_DEV_ID("t1_clk", "atmel_tcb.1", &tc4_clk),
+	CLKDEV_CON_DEV_ID("t2_clk", "atmel_tcb.1", &tc5_clk),
+	CLKDEV_CON_DEV_ID("pclk", "ssc.0", &ssc0_clk),
+	CLKDEV_CON_DEV_ID("pclk", "ssc.1", &ssc1_clk),
+	CLKDEV_CON_DEV_ID("pclk", "ssc.2", &ssc2_clk),
+};
+
+static struct clk_lookup usart_clocks_lookups[] = {
+	CLKDEV_CON_DEV_ID("usart", "atmel_usart.0", &mck),
+	CLKDEV_CON_DEV_ID("usart", "atmel_usart.1", &usart0_clk),
+	CLKDEV_CON_DEV_ID("usart", "atmel_usart.2", &usart1_clk),
+	CLKDEV_CON_DEV_ID("usart", "atmel_usart.3", &usart2_clk),
+	CLKDEV_CON_DEV_ID("usart", "atmel_usart.4", &usart3_clk),
+};
+
 /*
  * The four programmable clocks.
  * You must configure pin multiplexing to bring these signals out.
@@ -227,12 +248,29 @@
 	for (i = 0; i < ARRAY_SIZE(periph_clocks); i++)
 		clk_register(periph_clocks[i]);
 
+	clkdev_add_table(periph_clocks_lookups,
+			 ARRAY_SIZE(periph_clocks_lookups));
+	clkdev_add_table(usart_clocks_lookups,
+			 ARRAY_SIZE(usart_clocks_lookups));
+
 	clk_register(&pck0);
 	clk_register(&pck1);
 	clk_register(&pck2);
 	clk_register(&pck3);
 }
 
+static struct clk_lookup console_clock_lookup;
+
+void __init at91rm9200_set_console_clock(int id)
+{
+	if (id >= ARRAY_SIZE(usart_clocks_lookups))
+		return;
+
+	console_clock_lookup.con_id = "usart";
+	console_clock_lookup.clk = usart_clocks_lookups[id].clk;
+	clkdev_add(&console_clock_lookup);
+}
+
 /* --------------------------------------------------------------------
  *  GPIO
  * -------------------------------------------------------------------- */
@@ -266,15 +304,25 @@
 	at91_sys_write(AT91_ST_CR, AT91_ST_WDRST);
 }
 
+int rm9200_type;
+EXPORT_SYMBOL(rm9200_type);
+
+void __init at91rm9200_set_type(int type)
+{
+	rm9200_type = type;
+}
 
 /* --------------------------------------------------------------------
  *  AT91RM9200 processor initialization
  * -------------------------------------------------------------------- */
-void __init at91rm9200_initialize(unsigned long main_clock, unsigned short banks)
+void __init at91rm9200_map_io(void)
 {
 	/* Map peripherals */
 	iotable_init(at91rm9200_io_desc, ARRAY_SIZE(at91rm9200_io_desc));
+}
 
+void __init at91rm9200_initialize(unsigned long main_clock)
+{
 	at91_arch_reset = at91rm9200_reset;
 	at91_extern_irq = (1 << AT91RM9200_ID_IRQ0) | (1 << AT91RM9200_ID_IRQ1)
 			| (1 << AT91RM9200_ID_IRQ2) | (1 << AT91RM9200_ID_IRQ3)
@@ -288,7 +336,8 @@
 	at91rm9200_register_clocks();
 
 	/* Initialize GPIO subsystem */
-	at91_gpio_init(at91rm9200_gpio, banks);
+	at91_gpio_init(at91rm9200_gpio,
+		cpu_is_at91rm9200_bga() ? AT91RM9200_BGA : AT91RM9200_PQFP);
 }
 
 
diff -druN linux-2.6.39-libre/arch/arm/mach-at91/at91rm9200_devices.c linux-3.0-rc7-libre/arch/arm/mach-at91/at91rm9200_devices.c
--- linux-2.6.39-libre/arch/arm/mach-at91/at91rm9200_devices.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-at91/at91rm9200_devices.c	2011-07-11 19:51:52.000000000 -0400
@@ -644,15 +644,7 @@
 
 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", &at91rm9200_tcb0_device.dev, "t0_clk");
-	at91_clock_associate("tc1_clk", &at91rm9200_tcb0_device.dev, "t1_clk");
-	at91_clock_associate("tc2_clk", &at91rm9200_tcb0_device.dev, "t2_clk");
 	platform_device_register(&at91rm9200_tcb0_device);
-
-	at91_clock_associate("tc3_clk", &at91rm9200_tcb1_device.dev, "t0_clk");
-	at91_clock_associate("tc4_clk", &at91rm9200_tcb1_device.dev, "t1_clk");
-	at91_clock_associate("tc5_clk", &at91rm9200_tcb1_device.dev, "t2_clk");
 	platform_device_register(&at91rm9200_tcb1_device);
 }
 #else
@@ -849,17 +841,14 @@
 	case AT91RM9200_ID_SSC0:
 		pdev = &at91rm9200_ssc0_device;
 		configure_ssc0_pins(pins);
-		at91_clock_associate("ssc0_clk", &pdev->dev, "ssc");
 		break;
 	case AT91RM9200_ID_SSC1:
 		pdev = &at91rm9200_ssc1_device;
 		configure_ssc1_pins(pins);
-		at91_clock_associate("ssc1_clk", &pdev->dev, "ssc");
 		break;
 	case AT91RM9200_ID_SSC2:
 		pdev = &at91rm9200_ssc2_device;
 		configure_ssc2_pins(pins);
-		at91_clock_associate("ssc2_clk", &pdev->dev, "ssc");
 		break;
 	default:
 		return;
@@ -1109,37 +1098,34 @@
 void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins)
 {
 	struct platform_device *pdev;
+	struct atmel_uart_data *pdata;
 
 	switch (id) {
 		case 0:		/* DBGU */
 			pdev = &at91rm9200_dbgu_device;
 			configure_dbgu_pins();
-			at91_clock_associate("mck", &pdev->dev, "usart");
 			break;
 		case AT91RM9200_ID_US0:
 			pdev = &at91rm9200_uart0_device;
 			configure_usart0_pins(pins);
-			at91_clock_associate("usart0_clk", &pdev->dev, "usart");
 			break;
 		case AT91RM9200_ID_US1:
 			pdev = &at91rm9200_uart1_device;
 			configure_usart1_pins(pins);
-			at91_clock_associate("usart1_clk", &pdev->dev, "usart");
 			break;
 		case AT91RM9200_ID_US2:
 			pdev = &at91rm9200_uart2_device;
 			configure_usart2_pins(pins);
-			at91_clock_associate("usart2_clk", &pdev->dev, "usart");
 			break;
 		case AT91RM9200_ID_US3:
 			pdev = &at91rm9200_uart3_device;
 			configure_usart3_pins(pins);
-			at91_clock_associate("usart3_clk", &pdev->dev, "usart");
 			break;
 		default:
 			return;
 	}
-	pdev->id = portnr;		/* update to mapped ID */
+	pdata = pdev->dev.platform_data;
+	pdata->num = portnr;		/* update to mapped ID */
 
 	if (portnr < ATMEL_MAX_UART)
 		at91_uarts[portnr] = pdev;
@@ -1147,8 +1133,10 @@
 
 void __init at91_set_serial_console(unsigned portnr)
 {
-	if (portnr < ATMEL_MAX_UART)
+	if (portnr < ATMEL_MAX_UART) {
 		atmel_default_console_device = at91_uarts[portnr];
+		at91rm9200_set_console_clock(at91_uarts[portnr]->id);
+	}
 }
 
 void __init at91_add_device_serial(void)
diff -druN linux-2.6.39-libre/arch/arm/mach-at91/at91sam9260.c linux-3.0-rc7-libre/arch/arm/mach-at91/at91sam9260.c
--- linux-2.6.39-libre/arch/arm/mach-at91/at91sam9260.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-at91/at91sam9260.c	2011-07-11 19:51:52.000000000 -0400
@@ -231,6 +231,28 @@
 	// irq0 .. irq2
 };
 
+static struct clk_lookup periph_clocks_lookups[] = {
+	CLKDEV_CON_DEV_ID("spi_clk", "atmel_spi.0", &spi0_clk),
+	CLKDEV_CON_DEV_ID("spi_clk", "atmel_spi.1", &spi1_clk),
+	CLKDEV_CON_DEV_ID("t0_clk", "atmel_tcb.0", &tc0_clk),
+	CLKDEV_CON_DEV_ID("t1_clk", "atmel_tcb.0", &tc1_clk),
+	CLKDEV_CON_DEV_ID("t2_clk", "atmel_tcb.0", &tc2_clk),
+	CLKDEV_CON_DEV_ID("t3_clk", "atmel_tcb.1", &tc3_clk),
+	CLKDEV_CON_DEV_ID("t4_clk", "atmel_tcb.1", &tc4_clk),
+	CLKDEV_CON_DEV_ID("t5_clk", "atmel_tcb.1", &tc5_clk),
+	CLKDEV_CON_DEV_ID("pclk", "ssc.0", &ssc_clk),
+};
+
+static struct clk_lookup usart_clocks_lookups[] = {
+	CLKDEV_CON_DEV_ID("usart", "atmel_usart.0", &mck),
+	CLKDEV_CON_DEV_ID("usart", "atmel_usart.1", &usart0_clk),
+	CLKDEV_CON_DEV_ID("usart", "atmel_usart.2", &usart1_clk),
+	CLKDEV_CON_DEV_ID("usart", "atmel_usart.3", &usart2_clk),
+	CLKDEV_CON_DEV_ID("usart", "atmel_usart.4", &usart3_clk),
+	CLKDEV_CON_DEV_ID("usart", "atmel_usart.5", &usart4_clk),
+	CLKDEV_CON_DEV_ID("usart", "atmel_usart.6", &usart5_clk),
+};
+
 /*
  * The two programmable clocks.
  * You must configure pin multiplexing to bring these signals out.
@@ -255,10 +277,27 @@
 	for (i = 0; i < ARRAY_SIZE(periph_clocks); i++)
 		clk_register(periph_clocks[i]);
 
+	clkdev_add_table(periph_clocks_lookups,
+			 ARRAY_SIZE(periph_clocks_lookups));
+	clkdev_add_table(usart_clocks_lookups,
+			 ARRAY_SIZE(usart_clocks_lookups));
+
 	clk_register(&pck0);
 	clk_register(&pck1);
 }
 
+static struct clk_lookup console_clock_lookup;
+
+void __init at91sam9260_set_console_clock(int id)
+{
+	if (id >= ARRAY_SIZE(usart_clocks_lookups))
+		return;
+
+	console_clock_lookup.con_id = "usart";
+	console_clock_lookup.clk = usart_clocks_lookups[id].clk;
+	clkdev_add(&console_clock_lookup);
+}
+
 /* --------------------------------------------------------------------
  *  GPIO
  * -------------------------------------------------------------------- */
@@ -289,7 +328,7 @@
  *  AT91SAM9260 processor initialization
  * -------------------------------------------------------------------- */
 
-static void __init at91sam9xe_initialize(void)
+static void __init at91sam9xe_map_io(void)
 {
 	unsigned long cidr, sram_size;
 
@@ -310,18 +349,21 @@
 	iotable_init(at91sam9xe_sram_desc, ARRAY_SIZE(at91sam9xe_sram_desc));
 }
 
-void __init at91sam9260_initialize(unsigned long main_clock)
+void __init at91sam9260_map_io(void)
 {
 	/* Map peripherals */
 	iotable_init(at91sam9260_io_desc, ARRAY_SIZE(at91sam9260_io_desc));
 
 	if (cpu_is_at91sam9xe())
-		at91sam9xe_initialize();
+		at91sam9xe_map_io();
 	else if (cpu_is_at91sam9g20())
 		iotable_init(at91sam9g20_sram_desc, ARRAY_SIZE(at91sam9g20_sram_desc));
 	else
 		iotable_init(at91sam9260_sram_desc, ARRAY_SIZE(at91sam9260_sram_desc));
+}
 
+void __init at91sam9260_initialize(unsigned long main_clock)
+{
 	at91_arch_reset = at91sam9_alt_reset;
 	pm_power_off = at91sam9260_poweroff;
 	at91_extern_irq = (1 << AT91SAM9260_ID_IRQ0) | (1 << AT91SAM9260_ID_IRQ1)
diff -druN linux-2.6.39-libre/arch/arm/mach-at91/at91sam9260_devices.c linux-3.0-rc7-libre/arch/arm/mach-at91/at91sam9260_devices.c
--- linux-2.6.39-libre/arch/arm/mach-at91/at91sam9260_devices.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-at91/at91sam9260_devices.c	2011-07-11 19:51:52.000000000 -0400
@@ -609,7 +609,6 @@
 		at91_set_A_periph(AT91_PIN_PA1, 0);	/* SPI0_MOSI */
 		at91_set_A_periph(AT91_PIN_PA2, 0);	/* SPI1_SPCK */
 
-		at91_clock_associate("spi0_clk", &at91sam9260_spi0_device.dev, "spi_clk");
 		platform_device_register(&at91sam9260_spi0_device);
 	}
 	if (enable_spi1) {
@@ -617,7 +616,6 @@
 		at91_set_A_periph(AT91_PIN_PB1, 0);	/* SPI1_MOSI */
 		at91_set_A_periph(AT91_PIN_PB2, 0);	/* SPI1_SPCK */
 
-		at91_clock_associate("spi1_clk", &at91sam9260_spi1_device.dev, "spi_clk");
 		platform_device_register(&at91sam9260_spi1_device);
 	}
 }
@@ -694,15 +692,7 @@
 
 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", &at91sam9260_tcb0_device.dev, "t0_clk");
-	at91_clock_associate("tc1_clk", &at91sam9260_tcb0_device.dev, "t1_clk");
-	at91_clock_associate("tc2_clk", &at91sam9260_tcb0_device.dev, "t2_clk");
 	platform_device_register(&at91sam9260_tcb0_device);
-
-	at91_clock_associate("tc3_clk", &at91sam9260_tcb1_device.dev, "t0_clk");
-	at91_clock_associate("tc4_clk", &at91sam9260_tcb1_device.dev, "t1_clk");
-	at91_clock_associate("tc5_clk", &at91sam9260_tcb1_device.dev, "t2_clk");
 	platform_device_register(&at91sam9260_tcb1_device);
 }
 #else
@@ -820,7 +810,6 @@
 	case AT91SAM9260_ID_SSC:
 		pdev = &at91sam9260_ssc_device;
 		configure_ssc_pins(pins);
-		at91_clock_associate("ssc_clk", &pdev->dev, "pclk");
 		break;
 	default:
 		return;
@@ -1139,47 +1128,42 @@
 void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins)
 {
 	struct platform_device *pdev;
+	struct atmel_uart_data *pdata;
 
 	switch (id) {
 		case 0:		/* DBGU */
 			pdev = &at91sam9260_dbgu_device;
 			configure_dbgu_pins();
-			at91_clock_associate("mck", &pdev->dev, "usart");
 			break;
 		case AT91SAM9260_ID_US0:
 			pdev = &at91sam9260_uart0_device;
 			configure_usart0_pins(pins);
-			at91_clock_associate("usart0_clk", &pdev->dev, "usart");
 			break;
 		case AT91SAM9260_ID_US1:
 			pdev = &at91sam9260_uart1_device;
 			configure_usart1_pins(pins);
-			at91_clock_associate("usart1_clk", &pdev->dev, "usart");
 			break;
 		case AT91SAM9260_ID_US2:
 			pdev = &at91sam9260_uart2_device;
 			configure_usart2_pins(pins);
-			at91_clock_associate("usart2_clk", &pdev->dev, "usart");
 			break;
 		case AT91SAM9260_ID_US3:
 			pdev = &at91sam9260_uart3_device;
 			configure_usart3_pins(pins);
-			at91_clock_associate("usart3_clk", &pdev->dev, "usart");
 			break;
 		case AT91SAM9260_ID_US4:
 			pdev = &at91sam9260_uart4_device;
 			configure_usart4_pins();
-			at91_clock_associate("usart4_clk", &pdev->dev, "usart");
 			break;
 		case AT91SAM9260_ID_US5:
 			pdev = &at91sam9260_uart5_device;
 			configure_usart5_pins();
-			at91_clock_associate("usart5_clk", &pdev->dev, "usart");
 			break;
 		default:
 			return;
 	}
-	pdev->id = portnr;		/* update to mapped ID */
+	pdata = pdev->dev.platform_data;
+	pdata->num = portnr;		/* update to mapped ID */
 
 	if (portnr < ATMEL_MAX_UART)
 		at91_uarts[portnr] = pdev;
@@ -1187,8 +1171,10 @@
 
 void __init at91_set_serial_console(unsigned portnr)
 {
-	if (portnr < ATMEL_MAX_UART)
+	if (portnr < ATMEL_MAX_UART) {
 		atmel_default_console_device = at91_uarts[portnr];
+		at91sam9260_set_console_clock(at91_uarts[portnr]->id);
+	}
 }
 
 void __init at91_add_device_serial(void)
diff -druN linux-2.6.39-libre/arch/arm/mach-at91/at91sam9261.c linux-3.0-rc7-libre/arch/arm/mach-at91/at91sam9261.c
--- linux-2.6.39-libre/arch/arm/mach-at91/at91sam9261.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-at91/at91sam9261.c	2011-07-11 19:51:52.000000000 -0400
@@ -178,6 +178,24 @@
 	// irq0 .. irq2
 };
 
+static struct clk_lookup periph_clocks_lookups[] = {
+	CLKDEV_CON_DEV_ID("spi_clk", "atmel_spi.0", &spi0_clk),
+	CLKDEV_CON_DEV_ID("spi_clk", "atmel_spi.1", &spi1_clk),
+	CLKDEV_CON_DEV_ID("t0_clk", "atmel_tcb.0", &tc0_clk),
+	CLKDEV_CON_DEV_ID("t1_clk", "atmel_tcb.0", &tc1_clk),
+	CLKDEV_CON_DEV_ID("t2_clk", "atmel_tcb.0", &tc1_clk),
+	CLKDEV_CON_DEV_ID("pclk", "ssc.0", &ssc0_clk),
+	CLKDEV_CON_DEV_ID("pclk", "ssc.1", &ssc1_clk),
+	CLKDEV_CON_DEV_ID("pclk", "ssc.2", &ssc2_clk),
+};
+
+static struct clk_lookup usart_clocks_lookups[] = {
+	CLKDEV_CON_DEV_ID("usart", "atmel_usart.0", &mck),
+	CLKDEV_CON_DEV_ID("usart", "atmel_usart.1", &usart0_clk),
+	CLKDEV_CON_DEV_ID("usart", "atmel_usart.2", &usart1_clk),
+	CLKDEV_CON_DEV_ID("usart", "atmel_usart.3", &usart2_clk),
+};
+
 /*
  * The four programmable clocks.
  * You must configure pin multiplexing to bring these signals out.
@@ -228,6 +246,11 @@
 	for (i = 0; i < ARRAY_SIZE(periph_clocks); i++)
 		clk_register(periph_clocks[i]);
 
+	clkdev_add_table(periph_clocks_lookups,
+			 ARRAY_SIZE(periph_clocks_lookups));
+	clkdev_add_table(usart_clocks_lookups,
+			 ARRAY_SIZE(usart_clocks_lookups));
+
 	clk_register(&pck0);
 	clk_register(&pck1);
 	clk_register(&pck2);
@@ -237,6 +260,18 @@
 	clk_register(&hck1);
 }
 
+static struct clk_lookup console_clock_lookup;
+
+void __init at91sam9261_set_console_clock(int id)
+{
+	if (id >= ARRAY_SIZE(usart_clocks_lookups))
+		return;
+
+	console_clock_lookup.con_id = "usart";
+	console_clock_lookup.clk = usart_clocks_lookups[id].clk;
+	clkdev_add(&console_clock_lookup);
+}
+
 /* --------------------------------------------------------------------
  *  GPIO
  * -------------------------------------------------------------------- */
@@ -267,7 +302,7 @@
  *  AT91SAM9261 processor initialization
  * -------------------------------------------------------------------- */
 
-void __init at91sam9261_initialize(unsigned long main_clock)
+void __init at91sam9261_map_io(void)
 {
 	/* Map peripherals */
 	iotable_init(at91sam9261_io_desc, ARRAY_SIZE(at91sam9261_io_desc));
@@ -276,8 +311,10 @@
 		iotable_init(at91sam9g10_sram_desc, ARRAY_SIZE(at91sam9g10_sram_desc));
 	else
 		iotable_init(at91sam9261_sram_desc, ARRAY_SIZE(at91sam9261_sram_desc));
+}
 
-
+void __init at91sam9261_initialize(unsigned long main_clock)
+{
 	at91_arch_reset = at91sam9_alt_reset;
 	pm_power_off = at91sam9261_poweroff;
 	at91_extern_irq = (1 << AT91SAM9261_ID_IRQ0) | (1 << AT91SAM9261_ID_IRQ1)
diff -druN linux-2.6.39-libre/arch/arm/mach-at91/at91sam9261_devices.c linux-3.0-rc7-libre/arch/arm/mach-at91/at91sam9261_devices.c
--- linux-2.6.39-libre/arch/arm/mach-at91/at91sam9261_devices.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-at91/at91sam9261_devices.c	2011-07-11 19:51:52.000000000 -0400
@@ -426,7 +426,6 @@
 		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", &at91sam9261_spi0_device.dev, "spi_clk");
 		platform_device_register(&at91sam9261_spi0_device);
 	}
 	if (enable_spi1) {
@@ -434,7 +433,6 @@
 		at91_set_A_periph(AT91_PIN_PB31, 0);	/* SPI1_MOSI */
 		at91_set_A_periph(AT91_PIN_PB29, 0);	/* SPI1_SPCK */
 
-		at91_clock_associate("spi1_clk", &at91sam9261_spi1_device.dev, "spi_clk");
 		platform_device_register(&at91sam9261_spi1_device);
 	}
 }
@@ -581,10 +579,6 @@
 
 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", &at91sam9261_tcb_device.dev, "t0_clk");
-	at91_clock_associate("tc1_clk", &at91sam9261_tcb_device.dev, "t1_clk");
-	at91_clock_associate("tc2_clk", &at91sam9261_tcb_device.dev, "t2_clk");
 	platform_device_register(&at91sam9261_tcb_device);
 }
 #else
@@ -786,17 +780,14 @@
 	case AT91SAM9261_ID_SSC0:
 		pdev = &at91sam9261_ssc0_device;
 		configure_ssc0_pins(pins);
-		at91_clock_associate("ssc0_clk", &pdev->dev, "pclk");
 		break;
 	case AT91SAM9261_ID_SSC1:
 		pdev = &at91sam9261_ssc1_device;
 		configure_ssc1_pins(pins);
-		at91_clock_associate("ssc1_clk", &pdev->dev, "pclk");
 		break;
 	case AT91SAM9261_ID_SSC2:
 		pdev = &at91sam9261_ssc2_device;
 		configure_ssc2_pins(pins);
-		at91_clock_associate("ssc2_clk", &pdev->dev, "pclk");
 		break;
 	default:
 		return;
@@ -989,32 +980,30 @@
 void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins)
 {
 	struct platform_device *pdev;
+	struct atmel_uart_data *pdata;
 
 	switch (id) {
 		case 0:		/* DBGU */
 			pdev = &at91sam9261_dbgu_device;
 			configure_dbgu_pins();
-			at91_clock_associate("mck", &pdev->dev, "usart");
 			break;
 		case AT91SAM9261_ID_US0:
 			pdev = &at91sam9261_uart0_device;
 			configure_usart0_pins(pins);
-			at91_clock_associate("usart0_clk", &pdev->dev, "usart");
 			break;
 		case AT91SAM9261_ID_US1:
 			pdev = &at91sam9261_uart1_device;
 			configure_usart1_pins(pins);
-			at91_clock_associate("usart1_clk", &pdev->dev, "usart");
 			break;
 		case AT91SAM9261_ID_US2:
 			pdev = &at91sam9261_uart2_device;
 			configure_usart2_pins(pins);
-			at91_clock_associate("usart2_clk", &pdev->dev, "usart");
 			break;
 		default:
 			return;
 	}
-	pdev->id = portnr;		/* update to mapped ID */
+	pdata = pdev->dev.platform_data;
+	pdata->num = portnr;		/* update to mapped ID */
 
 	if (portnr < ATMEL_MAX_UART)
 		at91_uarts[portnr] = pdev;
@@ -1022,8 +1011,10 @@
 
 void __init at91_set_serial_console(unsigned portnr)
 {
-	if (portnr < ATMEL_MAX_UART)
+	if (portnr < ATMEL_MAX_UART) {
 		atmel_default_console_device = at91_uarts[portnr];
+		at91sam9261_set_console_clock(at91_uarts[portnr]->id);
+	}
 }
 
 void __init at91_add_device_serial(void)
diff -druN linux-2.6.39-libre/arch/arm/mach-at91/at91sam9263.c linux-3.0-rc7-libre/arch/arm/mach-at91/at91sam9263.c
--- linux-2.6.39-libre/arch/arm/mach-at91/at91sam9263.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-at91/at91sam9263.c	2011-07-11 19:51:52.000000000 -0400
@@ -199,6 +199,23 @@
 	// irq0 .. irq1
 };
 
+static struct clk_lookup periph_clocks_lookups[] = {
+	CLKDEV_CON_DEV_ID("pclk", "ssc.0", &ssc0_clk),
+	CLKDEV_CON_DEV_ID("pclk", "ssc.1", &ssc1_clk),
+	CLKDEV_CON_DEV_ID("mci_clk", "at91_mci.0", &mmc0_clk),
+	CLKDEV_CON_DEV_ID("mci_clk", "at91_mci.1", &mmc1_clk),
+	CLKDEV_CON_DEV_ID("spi_clk", "atmel_spi.0", &spi0_clk),
+	CLKDEV_CON_DEV_ID("spi_clk", "atmel_spi.1", &spi1_clk),
+	CLKDEV_CON_DEV_ID("t0_clk", "atmel_tcb.0", &tcb_clk),
+};
+
+static struct clk_lookup usart_clocks_lookups[] = {
+	CLKDEV_CON_DEV_ID("usart", "atmel_usart.0", &mck),
+	CLKDEV_CON_DEV_ID("usart", "atmel_usart.1", &usart0_clk),
+	CLKDEV_CON_DEV_ID("usart", "atmel_usart.2", &usart1_clk),
+	CLKDEV_CON_DEV_ID("usart", "atmel_usart.3", &usart2_clk),
+};
+
 /*
  * The four programmable clocks.
  * You must configure pin multiplexing to bring these signals out.
@@ -235,12 +252,29 @@
 	for (i = 0; i < ARRAY_SIZE(periph_clocks); i++)
 		clk_register(periph_clocks[i]);
 
+	clkdev_add_table(periph_clocks_lookups,
+			 ARRAY_SIZE(periph_clocks_lookups));
+	clkdev_add_table(usart_clocks_lookups,
+			 ARRAY_SIZE(usart_clocks_lookups));
+
 	clk_register(&pck0);
 	clk_register(&pck1);
 	clk_register(&pck2);
 	clk_register(&pck3);
 }
 
+static struct clk_lookup console_clock_lookup;
+
+void __init at91sam9263_set_console_clock(int id)
+{
+	if (id >= ARRAY_SIZE(usart_clocks_lookups))
+		return;
+
+	console_clock_lookup.con_id = "usart";
+	console_clock_lookup.clk = usart_clocks_lookups[id].clk;
+	clkdev_add(&console_clock_lookup);
+}
+
 /* --------------------------------------------------------------------
  *  GPIO
  * -------------------------------------------------------------------- */
@@ -279,11 +313,14 @@
  *  AT91SAM9263 processor initialization
  * -------------------------------------------------------------------- */
 
-void __init at91sam9263_initialize(unsigned long main_clock)
+void __init at91sam9263_map_io(void)
 {
 	/* Map peripherals */
 	iotable_init(at91sam9263_io_desc, ARRAY_SIZE(at91sam9263_io_desc));
+}
 
+void __init at91sam9263_initialize(unsigned long main_clock)
+{
 	at91_arch_reset = at91sam9_alt_reset;
 	pm_power_off = at91sam9263_poweroff;
 	at91_extern_irq = (1 << AT91SAM9263_ID_IRQ0) | (1 << AT91SAM9263_ID_IRQ1);
diff -druN linux-2.6.39-libre/arch/arm/mach-at91/at91sam9263_devices.c linux-3.0-rc7-libre/arch/arm/mach-at91/at91sam9263_devices.c
--- linux-2.6.39-libre/arch/arm/mach-at91/at91sam9263_devices.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-at91/at91sam9263_devices.c	2011-07-11 19:51:52.000000000 -0400
@@ -308,7 +308,6 @@
 		}
 
 		mmc0_data = *data;
-		at91_clock_associate("mci0_clk", &at91sam9263_mmc0_device.dev, "mci_clk");
 		platform_device_register(&at91sam9263_mmc0_device);
 	} else {			/* MCI1 */
 		/* CLK */
@@ -339,7 +338,6 @@
 		}
 
 		mmc1_data = *data;
-		at91_clock_associate("mci1_clk", &at91sam9263_mmc1_device.dev, "mci_clk");
 		platform_device_register(&at91sam9263_mmc1_device);
 	}
 }
@@ -686,7 +684,6 @@
 		at91_set_B_periph(AT91_PIN_PA1, 0);	/* SPI0_MOSI */
 		at91_set_B_periph(AT91_PIN_PA2, 0);	/* SPI0_SPCK */
 
-		at91_clock_associate("spi0_clk", &at91sam9263_spi0_device.dev, "spi_clk");
 		platform_device_register(&at91sam9263_spi0_device);
 	}
 	if (enable_spi1) {
@@ -694,7 +691,6 @@
 		at91_set_A_periph(AT91_PIN_PB13, 0);	/* SPI1_MOSI */
 		at91_set_A_periph(AT91_PIN_PB14, 0);	/* SPI1_SPCK */
 
-		at91_clock_associate("spi1_clk", &at91sam9263_spi1_device.dev, "spi_clk");
 		platform_device_register(&at91sam9263_spi1_device);
 	}
 }
@@ -941,8 +937,6 @@
 
 static void __init at91_add_device_tc(void)
 {
-	/* this chip has one clock and irq for all three TC channels */
-	at91_clock_associate("tcb_clk", &at91sam9263_tcb_device.dev, "t0_clk");
 	platform_device_register(&at91sam9263_tcb_device);
 }
 #else
@@ -1171,12 +1165,10 @@
 	case AT91SAM9263_ID_SSC0:
 		pdev = &at91sam9263_ssc0_device;
 		configure_ssc0_pins(pins);
-		at91_clock_associate("ssc0_clk", &pdev->dev, "pclk");
 		break;
 	case AT91SAM9263_ID_SSC1:
 		pdev = &at91sam9263_ssc1_device;
 		configure_ssc1_pins(pins);
-		at91_clock_associate("ssc1_clk", &pdev->dev, "pclk");
 		break;
 	default:
 		return;
@@ -1370,32 +1362,30 @@
 void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins)
 {
 	struct platform_device *pdev;
+	struct atmel_uart_data *pdata;
 
 	switch (id) {
 		case 0:		/* DBGU */
 			pdev = &at91sam9263_dbgu_device;
 			configure_dbgu_pins();
-			at91_clock_associate("mck", &pdev->dev, "usart");
 			break;
 		case AT91SAM9263_ID_US0:
 			pdev = &at91sam9263_uart0_device;
 			configure_usart0_pins(pins);
-			at91_clock_associate("usart0_clk", &pdev->dev, "usart");
 			break;
 		case AT91SAM9263_ID_US1:
 			pdev = &at91sam9263_uart1_device;
 			configure_usart1_pins(pins);
-			at91_clock_associate("usart1_clk", &pdev->dev, "usart");
 			break;
 		case AT91SAM9263_ID_US2:
 			pdev = &at91sam9263_uart2_device;
 			configure_usart2_pins(pins);
-			at91_clock_associate("usart2_clk", &pdev->dev, "usart");
 			break;
 		default:
 			return;
 	}
-	pdev->id = portnr;		/* update to mapped ID */
+	pdata = pdev->dev.platform_data;
+	pdata->num = portnr;		/* update to mapped ID */
 
 	if (portnr < ATMEL_MAX_UART)
 		at91_uarts[portnr] = pdev;
@@ -1403,8 +1393,10 @@
 
 void __init at91_set_serial_console(unsigned portnr)
 {
-	if (portnr < ATMEL_MAX_UART)
+	if (portnr < ATMEL_MAX_UART) {
 		atmel_default_console_device = at91_uarts[portnr];
+		at91sam9263_set_console_clock(at91_uarts[portnr]->id);
+	}
 }
 
 void __init at91_add_device_serial(void)
diff -druN linux-2.6.39-libre/arch/arm/mach-at91/at91sam9g45.c linux-3.0-rc7-libre/arch/arm/mach-at91/at91sam9g45.c
--- linux-2.6.39-libre/arch/arm/mach-at91/at91sam9g45.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-at91/at91sam9g45.c	2011-07-11 19:51:52.000000000 -0400
@@ -184,22 +184,6 @@
 	.type		= CLK_TYPE_PERIPHERAL,
 };
 
-/* One additional fake clock for ohci */
-static struct clk ohci_clk = {
-	.name		= "ohci_clk",
-	.pmc_mask	= 0,
-	.type		= CLK_TYPE_PERIPHERAL,
-	.parent		= &uhphs_clk,
-};
-
-/* One additional fake clock for second TC block */
-static struct clk tcb1_clk = {
-	.name		= "tcb1_clk",
-	.pmc_mask	= 0,
-	.type		= CLK_TYPE_PERIPHERAL,
-	.parent		= &tcb0_clk,
-};
-
 static struct clk *periph_clocks[] __initdata = {
 	&pioA_clk,
 	&pioB_clk,
@@ -228,8 +212,30 @@
 	&udphs_clk,
 	&mmc1_clk,
 	// irq0
-	&ohci_clk,
-	&tcb1_clk,
+};
+
+static struct clk_lookup periph_clocks_lookups[] = {
+	/* One additional fake clock for ohci */
+	CLKDEV_CON_ID("ohci_clk", &uhphs_clk),
+	CLKDEV_CON_DEV_ID("ehci_clk", "atmel-ehci", &uhphs_clk),
+	CLKDEV_CON_DEV_ID("hclk", "atmel_usba_udc", &utmi_clk),
+	CLKDEV_CON_DEV_ID("pclk", "atmel_usba_udc", &udphs_clk),
+	CLKDEV_CON_DEV_ID("mci_clk", "atmel_mci.0", &mmc0_clk),
+	CLKDEV_CON_DEV_ID("mci_clk", "atmel_mci.1", &mmc1_clk),
+	CLKDEV_CON_DEV_ID("spi_clk", "atmel_spi.0", &spi0_clk),
+	CLKDEV_CON_DEV_ID("spi_clk", "atmel_spi.1", &spi1_clk),
+	CLKDEV_CON_DEV_ID("t0_clk", "atmel_tcb.0", &tcb0_clk),
+	CLKDEV_CON_DEV_ID("t0_clk", "atmel_tcb.1", &tcb0_clk),
+	CLKDEV_CON_DEV_ID("pclk", "ssc.0", &ssc0_clk),
+	CLKDEV_CON_DEV_ID("pclk", "ssc.1", &ssc1_clk),
+};
+
+static struct clk_lookup usart_clocks_lookups[] = {
+	CLKDEV_CON_DEV_ID("usart", "atmel_usart.0", &mck),
+	CLKDEV_CON_DEV_ID("usart", "atmel_usart.1", &usart0_clk),
+	CLKDEV_CON_DEV_ID("usart", "atmel_usart.2", &usart1_clk),
+	CLKDEV_CON_DEV_ID("usart", "atmel_usart.3", &usart2_clk),
+	CLKDEV_CON_DEV_ID("usart", "atmel_usart.4", &usart3_clk),
 };
 
 /*
@@ -256,6 +262,11 @@
 	for (i = 0; i < ARRAY_SIZE(periph_clocks); i++)
 		clk_register(periph_clocks[i]);
 
+	clkdev_add_table(periph_clocks_lookups,
+			 ARRAY_SIZE(periph_clocks_lookups));
+	clkdev_add_table(usart_clocks_lookups,
+			 ARRAY_SIZE(usart_clocks_lookups));
+
 	if (cpu_is_at91sam9m10() || cpu_is_at91sam9m11())
 		clk_register(&vdec_clk);
 
@@ -263,6 +274,18 @@
 	clk_register(&pck1);
 }
 
+static struct clk_lookup console_clock_lookup;
+
+void __init at91sam9g45_set_console_clock(int id)
+{
+	if (id >= ARRAY_SIZE(usart_clocks_lookups))
+		return;
+
+	console_clock_lookup.con_id = "usart";
+	console_clock_lookup.clk = usart_clocks_lookups[id].clk;
+	clkdev_add(&console_clock_lookup);
+}
+
 /* --------------------------------------------------------------------
  *  GPIO
  * -------------------------------------------------------------------- */
@@ -306,11 +329,14 @@
  *  AT91SAM9G45 processor initialization
  * -------------------------------------------------------------------- */
 
-void __init at91sam9g45_initialize(unsigned long main_clock)
+void __init at91sam9g45_map_io(void)
 {
 	/* Map peripherals */
 	iotable_init(at91sam9g45_io_desc, ARRAY_SIZE(at91sam9g45_io_desc));
+}
 
+void __init at91sam9g45_initialize(unsigned long main_clock)
+{
 	at91_arch_reset = at91sam9g45_reset;
 	pm_power_off = at91sam9g45_poweroff;
 	at91_extern_irq = (1 << AT91SAM9G45_ID_IRQ0);
diff -druN linux-2.6.39-libre/arch/arm/mach-at91/at91sam9g45_devices.c linux-3.0-rc7-libre/arch/arm/mach-at91/at91sam9g45_devices.c
--- linux-2.6.39-libre/arch/arm/mach-at91/at91sam9g45_devices.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-at91/at91sam9g45_devices.c	2011-07-11 19:51:52.000000000 -0400
@@ -180,7 +180,6 @@
 	}
 
 	usbh_ehci_data = *data;
-	at91_clock_associate("uhphs_clk", &at91_usbh_ehci_device.dev, "ehci_clk");
 	platform_device_register(&at91_usbh_ehci_device);
 }
 #else
@@ -256,7 +255,7 @@
 {
 	usba_udc_data.pdata.vbus_pin = -EINVAL;
 	usba_udc_data.pdata.num_ep = ARRAY_SIZE(usba_udc_ep);
-	memcpy(usba_udc_data.ep, usba_udc_ep, sizeof(usba_udc_ep));;
+	memcpy(usba_udc_data.ep, usba_udc_ep, sizeof(usba_udc_ep));
 
 	if (data && data->vbus_pin > 0) {
 		at91_set_gpio_input(data->vbus_pin, 0);
@@ -266,10 +265,6 @@
 
 	/* Pullup pin is handled internally by USB device peripheral */
 
-	/* Clocks */
-	at91_clock_associate("utmi_clk", &at91_usba_udc_device.dev, "hclk");
-	at91_clock_associate("udphs_clk", &at91_usba_udc_device.dev, "pclk");
-
 	platform_device_register(&at91_usba_udc_device);
 }
 #else
@@ -478,7 +473,6 @@
 		}
 
 		mmc0_data = *data;
-		at91_clock_associate("mci0_clk", &at91sam9g45_mmc0_device.dev, "mci_clk");
 		platform_device_register(&at91sam9g45_mmc0_device);
 
 	} else {			/* MCI1 */
@@ -504,7 +498,6 @@
 		}
 
 		mmc1_data = *data;
-		at91_clock_associate("mci1_clk", &at91sam9g45_mmc1_device.dev, "mci_clk");
 		platform_device_register(&at91sam9g45_mmc1_device);
 
 	}
@@ -801,7 +794,6 @@
 		at91_set_A_periph(AT91_PIN_PB1, 0);	/* SPI0_MOSI */
 		at91_set_A_periph(AT91_PIN_PB2, 0);	/* SPI0_SPCK */
 
-		at91_clock_associate("spi0_clk", &at91sam9g45_spi0_device.dev, "spi_clk");
 		platform_device_register(&at91sam9g45_spi0_device);
 	}
 	if (enable_spi1) {
@@ -809,7 +801,6 @@
 		at91_set_A_periph(AT91_PIN_PB15, 0);	/* SPI1_MOSI */
 		at91_set_A_periph(AT91_PIN_PB16, 0);	/* SPI1_SPCK */
 
-		at91_clock_associate("spi1_clk", &at91sam9g45_spi1_device.dev, "spi_clk");
 		platform_device_register(&at91sam9g45_spi1_device);
 	}
 }
@@ -999,10 +990,7 @@
 
 static void __init at91_add_device_tc(void)
 {
-	/* this chip has one clock and irq for all six TC channels */
-	at91_clock_associate("tcb0_clk", &at91sam9g45_tcb0_device.dev, "t0_clk");
 	platform_device_register(&at91sam9g45_tcb0_device);
-	at91_clock_associate("tcb1_clk", &at91sam9g45_tcb1_device.dev, "t0_clk");
 	platform_device_register(&at91sam9g45_tcb1_device);
 }
 #else
@@ -1286,12 +1274,10 @@
 	case AT91SAM9G45_ID_SSC0:
 		pdev = &at91sam9g45_ssc0_device;
 		configure_ssc0_pins(pins);
-		at91_clock_associate("ssc0_clk", &pdev->dev, "pclk");
 		break;
 	case AT91SAM9G45_ID_SSC1:
 		pdev = &at91sam9g45_ssc1_device;
 		configure_ssc1_pins(pins);
-		at91_clock_associate("ssc1_clk", &pdev->dev, "pclk");
 		break;
 	default:
 		return;
@@ -1527,37 +1513,34 @@
 void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins)
 {
 	struct platform_device *pdev;
+	struct atmel_uart_data *pdata;
 
 	switch (id) {
 		case 0:		/* DBGU */
 			pdev = &at91sam9g45_dbgu_device;
 			configure_dbgu_pins();
-			at91_clock_associate("mck", &pdev->dev, "usart");
 			break;
 		case AT91SAM9G45_ID_US0:
 			pdev = &at91sam9g45_uart0_device;
 			configure_usart0_pins(pins);
-			at91_clock_associate("usart0_clk", &pdev->dev, "usart");
 			break;
 		case AT91SAM9G45_ID_US1:
 			pdev = &at91sam9g45_uart1_device;
 			configure_usart1_pins(pins);
-			at91_clock_associate("usart1_clk", &pdev->dev, "usart");
 			break;
 		case AT91SAM9G45_ID_US2:
 			pdev = &at91sam9g45_uart2_device;
 			configure_usart2_pins(pins);
-			at91_clock_associate("usart2_clk", &pdev->dev, "usart");
 			break;
 		case AT91SAM9G45_ID_US3:
 			pdev = &at91sam9g45_uart3_device;
 			configure_usart3_pins(pins);
-			at91_clock_associate("usart3_clk", &pdev->dev, "usart");
 			break;
 		default:
 			return;
 	}
-	pdev->id = portnr;		/* update to mapped ID */
+	pdata = pdev->dev.platform_data;
+	pdata->num = portnr;		/* update to mapped ID */
 
 	if (portnr < ATMEL_MAX_UART)
 		at91_uarts[portnr] = pdev;
@@ -1565,8 +1548,10 @@
 
 void __init at91_set_serial_console(unsigned portnr)
 {
-	if (portnr < ATMEL_MAX_UART)
+	if (portnr < ATMEL_MAX_UART) {
 		atmel_default_console_device = at91_uarts[portnr];
+		at91sam9g45_set_console_clock(at91_uarts[portnr]->id);
+	}
 }
 
 void __init at91_add_device_serial(void)
diff -druN linux-2.6.39-libre/arch/arm/mach-at91/at91sam9rl.c linux-3.0-rc7-libre/arch/arm/mach-at91/at91sam9rl.c
--- linux-2.6.39-libre/arch/arm/mach-at91/at91sam9rl.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-at91/at91sam9rl.c	2011-07-11 19:51:52.000000000 -0400
@@ -190,6 +190,24 @@
 	// irq0
 };
 
+static struct clk_lookup periph_clocks_lookups[] = {
+	CLKDEV_CON_DEV_ID("hclk", "atmel_usba_udc", &utmi_clk),
+	CLKDEV_CON_DEV_ID("pclk", "atmel_usba_udc", &udphs_clk),
+	CLKDEV_CON_DEV_ID("t0_clk", "atmel_tcb.0", &tc0_clk),
+	CLKDEV_CON_DEV_ID("t1_clk", "atmel_tcb.0", &tc1_clk),
+	CLKDEV_CON_DEV_ID("t2_clk", "atmel_tcb.0", &tc2_clk),
+	CLKDEV_CON_DEV_ID("pclk", "ssc.0", &ssc0_clk),
+	CLKDEV_CON_DEV_ID("pclk", "ssc.1", &ssc1_clk),
+};
+
+static struct clk_lookup usart_clocks_lookups[] = {
+	CLKDEV_CON_DEV_ID("usart", "atmel_usart.0", &mck),
+	CLKDEV_CON_DEV_ID("usart", "atmel_usart.1", &usart0_clk),
+	CLKDEV_CON_DEV_ID("usart", "atmel_usart.2", &usart1_clk),
+	CLKDEV_CON_DEV_ID("usart", "atmel_usart.3", &usart2_clk),
+	CLKDEV_CON_DEV_ID("usart", "atmel_usart.4", &usart3_clk),
+};
+
 /*
  * The two programmable clocks.
  * You must configure pin multiplexing to bring these signals out.
@@ -214,10 +232,27 @@
 	for (i = 0; i < ARRAY_SIZE(periph_clocks); i++)
 		clk_register(periph_clocks[i]);
 
+	clkdev_add_table(periph_clocks_lookups,
+			 ARRAY_SIZE(periph_clocks_lookups));
+	clkdev_add_table(usart_clocks_lookups,
+			 ARRAY_SIZE(usart_clocks_lookups));
+
 	clk_register(&pck0);
 	clk_register(&pck1);
 }
 
+static struct clk_lookup console_clock_lookup;
+
+void __init at91sam9rl_set_console_clock(int id)
+{
+	if (id >= ARRAY_SIZE(usart_clocks_lookups))
+		return;
+
+	console_clock_lookup.con_id = "usart";
+	console_clock_lookup.clk = usart_clocks_lookups[id].clk;
+	clkdev_add(&console_clock_lookup);
+}
+
 /* --------------------------------------------------------------------
  *  GPIO
  * -------------------------------------------------------------------- */
@@ -252,7 +287,7 @@
  *  AT91SAM9RL processor initialization
  * -------------------------------------------------------------------- */
 
-void __init at91sam9rl_initialize(unsigned long main_clock)
+void __init at91sam9rl_map_io(void)
 {
 	unsigned long cidr, sram_size;
 
@@ -275,7 +310,10 @@
 
 	/* Map SRAM */
 	iotable_init(at91sam9rl_sram_desc, ARRAY_SIZE(at91sam9rl_sram_desc));
+}
 
+void __init at91sam9rl_initialize(unsigned long main_clock)
+{
 	at91_arch_reset = at91sam9_alt_reset;
 	pm_power_off = at91sam9rl_poweroff;
 	at91_extern_irq = (1 << AT91SAM9RL_ID_IRQ0);
diff -druN linux-2.6.39-libre/arch/arm/mach-at91/at91sam9rl_devices.c linux-3.0-rc7-libre/arch/arm/mach-at91/at91sam9rl_devices.c
--- linux-2.6.39-libre/arch/arm/mach-at91/at91sam9rl_devices.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-at91/at91sam9rl_devices.c	2011-07-11 19:51:52.000000000 -0400
@@ -145,7 +145,7 @@
 	 */
 	usba_udc_data.pdata.vbus_pin = -EINVAL;
 	usba_udc_data.pdata.num_ep = ARRAY_SIZE(usba_udc_ep);
-	memcpy(usba_udc_data.ep, usba_udc_ep, sizeof(usba_udc_ep));;
+	memcpy(usba_udc_data.ep, usba_udc_ep, sizeof(usba_udc_ep));
 
 	if (data && data->vbus_pin > 0) {
 		at91_set_gpio_input(data->vbus_pin, 0);
@@ -155,10 +155,6 @@
 
 	/* Pullup pin is handled internally by USB device peripheral */
 
-	/* Clocks */
-	at91_clock_associate("utmi_clk", &at91_usba_udc_device.dev, "hclk");
-	at91_clock_associate("udphs_clk", &at91_usba_udc_device.dev, "pclk");
-
 	platform_device_register(&at91_usba_udc_device);
 }
 #else
@@ -605,10 +601,6 @@
 
 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", &at91sam9rl_tcb_device.dev, "t0_clk");
-	at91_clock_associate("tc1_clk", &at91sam9rl_tcb_device.dev, "t1_clk");
-	at91_clock_associate("tc2_clk", &at91sam9rl_tcb_device.dev, "t2_clk");
 	platform_device_register(&at91sam9rl_tcb_device);
 }
 #else
@@ -892,12 +884,10 @@
 	case AT91SAM9RL_ID_SSC0:
 		pdev = &at91sam9rl_ssc0_device;
 		configure_ssc0_pins(pins);
-		at91_clock_associate("ssc0_clk", &pdev->dev, "pclk");
 		break;
 	case AT91SAM9RL_ID_SSC1:
 		pdev = &at91sam9rl_ssc1_device;
 		configure_ssc1_pins(pins);
-		at91_clock_associate("ssc1_clk", &pdev->dev, "pclk");
 		break;
 	default:
 		return;
@@ -1141,37 +1131,34 @@
 void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins)
 {
 	struct platform_device *pdev;
+	struct atmel_uart_data *pdata;
 
 	switch (id) {
 		case 0:		/* DBGU */
 			pdev = &at91sam9rl_dbgu_device;
 			configure_dbgu_pins();
-			at91_clock_associate("mck", &pdev->dev, "usart");
 			break;
 		case AT91SAM9RL_ID_US0:
 			pdev = &at91sam9rl_uart0_device;
 			configure_usart0_pins(pins);
-			at91_clock_associate("usart0_clk", &pdev->dev, "usart");
 			break;
 		case AT91SAM9RL_ID_US1:
 			pdev = &at91sam9rl_uart1_device;
 			configure_usart1_pins(pins);
-			at91_clock_associate("usart1_clk", &pdev->dev, "usart");
 			break;
 		case AT91SAM9RL_ID_US2:
 			pdev = &at91sam9rl_uart2_device;
 			configure_usart2_pins(pins);
-			at91_clock_associate("usart2_clk", &pdev->dev, "usart");
 			break;
 		case AT91SAM9RL_ID_US3:
 			pdev = &at91sam9rl_uart3_device;
 			configure_usart3_pins(pins);
-			at91_clock_associate("usart3_clk", &pdev->dev, "usart");
 			break;
 		default:
 			return;
 	}
-	pdev->id = portnr;		/* update to mapped ID */
+	pdata = pdev->dev.platform_data;
+	pdata->num = portnr;		/* update to mapped ID */
 
 	if (portnr < ATMEL_MAX_UART)
 		at91_uarts[portnr] = pdev;
@@ -1179,8 +1166,10 @@
 
 void __init at91_set_serial_console(unsigned portnr)
 {
-	if (portnr < ATMEL_MAX_UART)
+	if (portnr < ATMEL_MAX_UART) {
 		atmel_default_console_device = at91_uarts[portnr];
+		at91sam9rl_set_console_clock(at91_uarts[portnr]->id);
+	}
 }
 
 void __init at91_add_device_serial(void)
diff -druN linux-2.6.39-libre/arch/arm/mach-at91/at91x40.c linux-3.0-rc7-libre/arch/arm/mach-at91/at91x40.c
--- linux-2.6.39-libre/arch/arm/mach-at91/at91x40.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-at91/at91x40.c	2011-07-11 19:51:52.000000000 -0400
@@ -37,11 +37,6 @@
 	return AT91X40_MASTER_CLOCK;
 }
 
-struct clk *clk_get(struct device *dev, const char *id)
-{
-	return NULL;
-}
-
 void __init at91x40_initialize(unsigned long main_clock)
 {
 	at91_extern_irq = (1 << AT91X40_ID_IRQ0) | (1 << AT91X40_ID_IRQ1)
diff -druN linux-2.6.39-libre/arch/arm/mach-at91/board-1arm.c linux-3.0-rc7-libre/arch/arm/mach-at91/board-1arm.c
--- linux-2.6.39-libre/arch/arm/mach-at91/board-1arm.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-at91/board-1arm.c	2011-07-11 19:51:52.000000000 -0400
@@ -35,14 +35,18 @@
 
 #include <mach/board.h>
 #include <mach/gpio.h>
+#include <mach/cpu.h>
 
 #include "generic.h"
 
 
-static void __init onearm_map_io(void)
+static void __init onearm_init_early(void)
 {
+	/* Set cpu type: PQFP */
+	at91rm9200_set_type(ARCH_REVISON_9200_PQFP);
+
 	/* Initialize processor: 18.432 MHz crystal */
-	at91rm9200_initialize(18432000, AT91RM9200_PQFP);
+	at91rm9200_initialize(18432000);
 
 	/* DBGU on ttyS0. (Rx & Tx only) */
 	at91_register_uart(0, 0, 0);
@@ -92,9 +96,9 @@
 
 MACHINE_START(ONEARM, "Ajeco 1ARM single board computer")
 	/* Maintainer: Lennert Buytenhek <buytenh@wantstofly.org> */
-	.boot_params	= AT91_SDRAM_BASE + 0x100,
 	.timer		= &at91rm9200_timer,
-	.map_io		= onearm_map_io,
+	.map_io		= at91rm9200_map_io,
+	.init_early	= onearm_init_early,
 	.init_irq	= onearm_init_irq,
 	.init_machine	= onearm_board_init,
 MACHINE_END
diff -druN linux-2.6.39-libre/arch/arm/mach-at91/board-afeb-9260v1.c linux-3.0-rc7-libre/arch/arm/mach-at91/board-afeb-9260v1.c
--- linux-2.6.39-libre/arch/arm/mach-at91/board-afeb-9260v1.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-at91/board-afeb-9260v1.c	2011-07-11 19:51:52.000000000 -0400
@@ -48,7 +48,7 @@
 #include "generic.h"
 
 
-static void __init afeb9260_map_io(void)
+static void __init afeb9260_init_early(void)
 {
 	/* Initialize processor: 18.432 MHz crystal */
 	at91sam9260_initialize(18432000);
@@ -218,9 +218,9 @@
 
 MACHINE_START(AFEB9260, "Custom afeb9260 board")
 	/* Maintainer: Sergey Lapin <slapin@ossfans.org> */
-	.boot_params	= AT91_SDRAM_BASE + 0x100,
 	.timer		= &at91sam926x_timer,
-	.map_io		= afeb9260_map_io,
+	.map_io		= at91sam9260_map_io,
+	.init_early	= afeb9260_init_early,
 	.init_irq	= afeb9260_init_irq,
 	.init_machine	= afeb9260_board_init,
 MACHINE_END
diff -druN linux-2.6.39-libre/arch/arm/mach-at91/board-at572d940hf_ek.c linux-3.0-rc7-libre/arch/arm/mach-at91/board-at572d940hf_ek.c
--- linux-2.6.39-libre/arch/arm/mach-at91/board-at572d940hf_ek.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-at91/board-at572d940hf_ek.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,326 +0,0 @@
-/*
- * 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_ATMEL_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> */
-	.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 -druN linux-2.6.39-libre/arch/arm/mach-at91/board-cam60.c linux-3.0-rc7-libre/arch/arm/mach-at91/board-cam60.c
--- linux-2.6.39-libre/arch/arm/mach-at91/board-cam60.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-at91/board-cam60.c	2011-07-11 19:51:52.000000000 -0400
@@ -45,7 +45,7 @@
 #include "generic.h"
 
 
-static void __init cam60_map_io(void)
+static void __init cam60_init_early(void)
 {
 	/* Initialize processor: 10 MHz crystal */
 	at91sam9260_initialize(10000000);
@@ -198,9 +198,9 @@
 
 MACHINE_START(CAM60, "KwikByte CAM60")
 	/* Maintainer: KwikByte */
-	.boot_params	= AT91_SDRAM_BASE + 0x100,
 	.timer		= &at91sam926x_timer,
-	.map_io		= cam60_map_io,
+	.map_io		= at91sam9260_map_io,
+	.init_early	= cam60_init_early,
 	.init_irq	= cam60_init_irq,
 	.init_machine	= cam60_board_init,
 MACHINE_END
diff -druN linux-2.6.39-libre/arch/arm/mach-at91/board-cap9adk.c linux-3.0-rc7-libre/arch/arm/mach-at91/board-cap9adk.c
--- linux-2.6.39-libre/arch/arm/mach-at91/board-cap9adk.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-at91/board-cap9adk.c	2011-07-11 19:51:52.000000000 -0400
@@ -44,12 +44,13 @@
 #include <mach/gpio.h>
 #include <mach/at91cap9_matrix.h>
 #include <mach/at91sam9_smc.h>
+#include <mach/system_rev.h>
 
 #include "sam9_smc.h"
 #include "generic.h"
 
 
-static void __init cap9adk_map_io(void)
+static void __init cap9adk_init_early(void)
 {
 	/* Initialize processor: 12 MHz crystal */
 	at91cap9_initialize(12000000);
@@ -187,11 +188,6 @@
 //	.rdy_pin	= ... not connected
 	.enable_pin	= AT91_PIN_PD15,
 	.partition_info	= nand_partitions,
-#if defined(CONFIG_MTD_NAND_ATMEL_BUSWIDTH_16)
-	.bus_width_16	= 1,
-#else
-	.bus_width_16	= 0,
-#endif
 };
 
 static struct sam9_smc_config __initdata cap9adk_nand_smc_config = {
@@ -219,6 +215,7 @@
 	csa = at91_sys_read(AT91_MATRIX_EBICSA);
 	at91_sys_write(AT91_MATRIX_EBICSA, csa | AT91_MATRIX_EBI_VDDIOMSEL_3_3V);
 
+	cap9adk_nand_data.bus_width_16 = board_have_nand_16bit();
 	/* setup bus-width (8 or 16) */
 	if (cap9adk_nand_data.bus_width_16)
 		cap9adk_nand_smc_config.mode |= AT91_SMC_DBW_16;
@@ -399,9 +396,9 @@
 
 MACHINE_START(AT91CAP9ADK, "Atmel AT91CAP9A-DK")
 	/* Maintainer: Stelian Pop <stelian.pop@leadtechdesign.com> */
-	.boot_params	= AT91_SDRAM_BASE + 0x100,
 	.timer		= &at91sam926x_timer,
-	.map_io		= cap9adk_map_io,
+	.map_io		= at91cap9_map_io,
+	.init_early	= cap9adk_init_early,
 	.init_irq	= cap9adk_init_irq,
 	.init_machine	= cap9adk_board_init,
 MACHINE_END
diff -druN linux-2.6.39-libre/arch/arm/mach-at91/board-carmeva.c linux-3.0-rc7-libre/arch/arm/mach-at91/board-carmeva.c
--- linux-2.6.39-libre/arch/arm/mach-at91/board-carmeva.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-at91/board-carmeva.c	2011-07-11 19:51:52.000000000 -0400
@@ -40,10 +40,10 @@
 #include "generic.h"
 
 
-static void __init carmeva_map_io(void)
+static void __init carmeva_init_early(void)
 {
 	/* Initialize processor: 20.000 MHz crystal */
-	at91rm9200_initialize(20000000, AT91RM9200_BGA);
+	at91rm9200_initialize(20000000);
 
 	/* DBGU on ttyS0. (Rx & Tx only) */
 	at91_register_uart(0, 0, 0);
@@ -162,9 +162,9 @@
 
 MACHINE_START(CARMEVA, "Carmeva")
 	/* Maintainer: Conitec Datasystems */
-	.boot_params	= AT91_SDRAM_BASE + 0x100,
 	.timer		= &at91rm9200_timer,
-	.map_io		= carmeva_map_io,
+	.map_io		= at91rm9200_map_io,
+	.init_early	= carmeva_init_early,
 	.init_irq	= carmeva_init_irq,
 	.init_machine	= carmeva_board_init,
 MACHINE_END
diff -druN linux-2.6.39-libre/arch/arm/mach-at91/board-cpu9krea.c linux-3.0-rc7-libre/arch/arm/mach-at91/board-cpu9krea.c
--- linux-2.6.39-libre/arch/arm/mach-at91/board-cpu9krea.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-at91/board-cpu9krea.c	2011-07-11 19:51:52.000000000 -0400
@@ -47,7 +47,7 @@
 #include "sam9_smc.h"
 #include "generic.h"
 
-static void __init cpu9krea_map_io(void)
+static void __init cpu9krea_init_early(void)
 {
 	/* Initialize processor: 18.432 MHz crystal */
 	at91sam9260_initialize(18432000);
@@ -375,9 +375,9 @@
 MACHINE_START(CPUAT9G20, "Eukrea CPU9G20")
 #endif
 	/* Maintainer: Eric Benard - EUKREA Electromatique */
-	.boot_params	= AT91_SDRAM_BASE + 0x100,
 	.timer		= &at91sam926x_timer,
-	.map_io		= cpu9krea_map_io,
+	.map_io		= at91sam9260_map_io,
+	.init_early	= cpu9krea_init_early,
 	.init_irq	= cpu9krea_init_irq,
 	.init_machine	= cpu9krea_board_init,
 MACHINE_END
diff -druN linux-2.6.39-libre/arch/arm/mach-at91/board-cpuat91.c linux-3.0-rc7-libre/arch/arm/mach-at91/board-cpuat91.c
--- linux-2.6.39-libre/arch/arm/mach-at91/board-cpuat91.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-at91/board-cpuat91.c	2011-07-11 19:51:52.000000000 -0400
@@ -38,6 +38,7 @@
 #include <mach/board.h>
 #include <mach/gpio.h>
 #include <mach/at91rm9200_mc.h>
+#include <mach/cpu.h>
 
 #include "generic.h"
 
@@ -50,10 +51,13 @@
 	},
 };
 
-static void __init cpuat91_map_io(void)
+static void __init cpuat91_init_early(void)
 {
+	/* Set cpu type: PQFP */
+	at91rm9200_set_type(ARCH_REVISON_9200_PQFP);
+
 	/* Initialize processor: 18.432 MHz crystal */
-	at91rm9200_initialize(18432000, AT91RM9200_PQFP);
+	at91rm9200_initialize(18432000);
 
 	/* DBGU on ttyS0. (Rx & Tx only) */
 	at91_register_uart(0, 0, 0);
@@ -175,9 +179,9 @@
 
 MACHINE_START(CPUAT91, "Eukrea")
 	/* Maintainer: Eric Benard - EUKREA Electromatique */
-	.boot_params	= AT91_SDRAM_BASE + 0x100,
 	.timer		= &at91rm9200_timer,
-	.map_io		= cpuat91_map_io,
+	.map_io		= at91rm9200_map_io,
+	.init_early	= cpuat91_init_early,
 	.init_irq	= cpuat91_init_irq,
 	.init_machine	= cpuat91_board_init,
 MACHINE_END
diff -druN linux-2.6.39-libre/arch/arm/mach-at91/board-csb337.c linux-3.0-rc7-libre/arch/arm/mach-at91/board-csb337.c
--- linux-2.6.39-libre/arch/arm/mach-at91/board-csb337.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-at91/board-csb337.c	2011-07-11 19:51:52.000000000 -0400
@@ -43,10 +43,10 @@
 #include "generic.h"
 
 
-static void __init csb337_map_io(void)
+static void __init csb337_init_early(void)
 {
 	/* Initialize processor: 3.6864 MHz crystal */
-	at91rm9200_initialize(3686400, AT91RM9200_BGA);
+	at91rm9200_initialize(3686400);
 
 	/* Setup the LEDs */
 	at91_init_leds(AT91_PIN_PB0, AT91_PIN_PB1);
@@ -257,9 +257,9 @@
 
 MACHINE_START(CSB337, "Cogent CSB337")
 	/* Maintainer: Bill Gatliff */
-	.boot_params	= AT91_SDRAM_BASE + 0x100,
 	.timer		= &at91rm9200_timer,
-	.map_io		= csb337_map_io,
+	.map_io		= at91rm9200_map_io,
+	.init_early	= csb337_init_early,
 	.init_irq	= csb337_init_irq,
 	.init_machine	= csb337_board_init,
 MACHINE_END
diff -druN linux-2.6.39-libre/arch/arm/mach-at91/board-csb637.c linux-3.0-rc7-libre/arch/arm/mach-at91/board-csb637.c
--- linux-2.6.39-libre/arch/arm/mach-at91/board-csb637.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-at91/board-csb637.c	2011-07-11 19:51:52.000000000 -0400
@@ -40,10 +40,10 @@
 #include "generic.h"
 
 
-static void __init csb637_map_io(void)
+static void __init csb637_init_early(void)
 {
 	/* Initialize processor: 3.6864 MHz crystal */
-	at91rm9200_initialize(3686400, AT91RM9200_BGA);
+	at91rm9200_initialize(3686400);
 
 	/* DBGU on ttyS0. (Rx & Tx only) */
 	at91_register_uart(0, 0, 0);
@@ -138,9 +138,9 @@
 
 MACHINE_START(CSB637, "Cogent CSB637")
 	/* Maintainer: Bill Gatliff */
-	.boot_params	= AT91_SDRAM_BASE + 0x100,
 	.timer		= &at91rm9200_timer,
-	.map_io		= csb637_map_io,
+	.map_io		= at91rm9200_map_io,
+	.init_early	= csb637_init_early,
 	.init_irq	= csb637_init_irq,
 	.init_machine	= csb637_board_init,
 MACHINE_END
diff -druN linux-2.6.39-libre/arch/arm/mach-at91/board-eb01.c linux-3.0-rc7-libre/arch/arm/mach-at91/board-eb01.c
--- linux-2.6.39-libre/arch/arm/mach-at91/board-eb01.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-at91/board-eb01.c	2011-07-11 19:51:52.000000000 -0400
@@ -35,7 +35,7 @@
 	at91x40_init_interrupts(NULL);
 }
 
-static void __init at91eb01_map_io(void)
+static void __init at91eb01_init_early(void)
 {
 	at91x40_initialize(40000000);
 }
@@ -43,7 +43,7 @@
 MACHINE_START(AT91EB01, "Atmel AT91 EB01")
 	/* Maintainer: Greg Ungerer <gerg@snapgear.com> */
 	.timer		= &at91x40_timer,
+	.init_early	= at91eb01_init_early,
 	.init_irq	= at91eb01_init_irq,
-	.map_io		= at91eb01_map_io,
 MACHINE_END
 
diff -druN linux-2.6.39-libre/arch/arm/mach-at91/board-eb9200.c linux-3.0-rc7-libre/arch/arm/mach-at91/board-eb9200.c
--- linux-2.6.39-libre/arch/arm/mach-at91/board-eb9200.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-at91/board-eb9200.c	2011-07-11 19:51:52.000000000 -0400
@@ -40,10 +40,10 @@
 #include "generic.h"
 
 
-static void __init eb9200_map_io(void)
+static void __init eb9200_init_early(void)
 {
 	/* Initialize processor: 18.432 MHz crystal */
-	at91rm9200_initialize(18432000, AT91RM9200_BGA);
+	at91rm9200_initialize(18432000);
 
 	/* DBGU on ttyS0. (Rx & Tx only) */
 	at91_register_uart(0, 0, 0);
@@ -120,9 +120,9 @@
 }
 
 MACHINE_START(ATEB9200, "Embest ATEB9200")
-	.boot_params	= AT91_SDRAM_BASE + 0x100,
 	.timer		= &at91rm9200_timer,
-	.map_io		= eb9200_map_io,
+	.map_io		= at91rm9200_map_io,
+	.init_early	= eb9200_init_early,
 	.init_irq	= eb9200_init_irq,
 	.init_machine	= eb9200_board_init,
 MACHINE_END
diff -druN linux-2.6.39-libre/arch/arm/mach-at91/board-ecbat91.c linux-3.0-rc7-libre/arch/arm/mach-at91/board-ecbat91.c
--- linux-2.6.39-libre/arch/arm/mach-at91/board-ecbat91.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-at91/board-ecbat91.c	2011-07-11 19:51:52.000000000 -0400
@@ -38,14 +38,18 @@
 
 #include <mach/board.h>
 #include <mach/gpio.h>
+#include <mach/cpu.h>
 
 #include "generic.h"
 
 
-static void __init ecb_at91map_io(void)
+static void __init ecb_at91init_early(void)
 {
+	/* Set cpu type: PQFP */
+	at91rm9200_set_type(ARCH_REVISON_9200_PQFP);
+
 	/* Initialize processor: 18.432 MHz crystal */
-	at91rm9200_initialize(18432000, AT91RM9200_PQFP);
+	at91rm9200_initialize(18432000);
 
 	/* Setup the LEDs */
 	at91_init_leds(AT91_PIN_PC7, AT91_PIN_PC7);
@@ -168,9 +172,9 @@
 
 MACHINE_START(ECBAT91, "emQbit's ECB_AT91")
 	/* Maintainer: emQbit.com */
-	.boot_params	= AT91_SDRAM_BASE + 0x100,
 	.timer		= &at91rm9200_timer,
-	.map_io		= ecb_at91map_io,
+	.map_io		= at91rm9200_map_io,
+	.init_early	= ecb_at91init_early,
 	.init_irq	= ecb_at91init_irq,
 	.init_machine	= ecb_at91board_init,
 MACHINE_END
diff -druN linux-2.6.39-libre/arch/arm/mach-at91/board-eco920.c linux-3.0-rc7-libre/arch/arm/mach-at91/board-eco920.c
--- linux-2.6.39-libre/arch/arm/mach-at91/board-eco920.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-at91/board-eco920.c	2011-07-11 19:51:52.000000000 -0400
@@ -26,11 +26,16 @@
 
 #include <mach/board.h>
 #include <mach/at91rm9200_mc.h>
+#include <mach/cpu.h>
+
 #include "generic.h"
 
-static void __init eco920_map_io(void)
+static void __init eco920_init_early(void)
 {
-	at91rm9200_initialize(18432000, AT91RM9200_PQFP);
+	/* Set cpu type: PQFP */
+	at91rm9200_set_type(ARCH_REVISON_9200_PQFP);
+
+	at91rm9200_initialize(18432000);
 
 	/* Setup the LEDs */
 	at91_init_leds(AT91_PIN_PB0, AT91_PIN_PB1);
@@ -86,21 +91,6 @@
 	.num_resources  = 1,
 };
 
-static struct resource at91_beeper_resources[] = {
-	[0] = {
-		.start          = AT91RM9200_BASE_TC3,
-		.end            = AT91RM9200_BASE_TC3 + 0x39,
-		.flags          = IORESOURCE_MEM,
-	},
-};
-
-static struct platform_device at91_beeper = {
-	.name           = "at91_beeper",
-	.id             = 0,
-	.resource       = at91_beeper_resources,
-	.num_resources  = ARRAY_SIZE(at91_beeper_resources),
-};
-
 static struct spi_board_info eco920_spi_devices[] = {
 	{	/* CAN controller */
 		.modalias	= "tlv5638",
@@ -139,18 +129,14 @@
 		AT91_SMC_TDF_(1)	/* float time */
 	);
 
-	at91_clock_associate("tc3_clk", &at91_beeper.dev, "at91_beeper");
-	at91_set_B_periph(AT91_PIN_PB6, 0);
-	platform_device_register(&at91_beeper);
-
 	at91_add_device_spi(eco920_spi_devices, ARRAY_SIZE(eco920_spi_devices));
 }
 
 MACHINE_START(ECO920, "eco920")
 	/* Maintainer: Sascha Hauer */
-	.boot_params	= AT91_SDRAM_BASE + 0x100,
 	.timer		= &at91rm9200_timer,
-	.map_io		= eco920_map_io,
+	.map_io		= at91rm9200_map_io,
+	.init_early	= eco920_init_early,
 	.init_irq	= eco920_init_irq,
 	.init_machine	= eco920_board_init,
 MACHINE_END
diff -druN linux-2.6.39-libre/arch/arm/mach-at91/board-flexibity.c linux-3.0-rc7-libre/arch/arm/mach-at91/board-flexibity.c
--- linux-2.6.39-libre/arch/arm/mach-at91/board-flexibity.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-at91/board-flexibity.c	2011-07-11 19:51:52.000000000 -0400
@@ -37,7 +37,7 @@
 
 #include "generic.h"
 
-static void __init flexibity_map_io(void)
+static void __init flexibity_init_early(void)
 {
 	/* Initialize processor: 18.432 MHz crystal */
 	at91sam9260_initialize(18432000);
@@ -154,9 +154,9 @@
 
 MACHINE_START(FLEXIBITY, "Flexibity Connect")
 	/* Maintainer: Maxim Osipov */
-	.boot_params	= AT91_SDRAM_BASE + 0x100,
 	.timer		= &at91sam926x_timer,
-	.map_io		= flexibity_map_io,
+	.map_io		= at91sam9260_map_io,
+	.init_early	= flexibity_init_early,
 	.init_irq	= flexibity_init_irq,
 	.init_machine	= flexibity_board_init,
 MACHINE_END
diff -druN linux-2.6.39-libre/arch/arm/mach-at91/board-foxg20.c linux-3.0-rc7-libre/arch/arm/mach-at91/board-foxg20.c
--- linux-2.6.39-libre/arch/arm/mach-at91/board-foxg20.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-at91/board-foxg20.c	2011-07-11 19:51:52.000000000 -0400
@@ -57,7 +57,7 @@
  */
 
 
-static void __init foxg20_map_io(void)
+static void __init foxg20_init_early(void)
 {
 	/* Initialize processor: 18.432 MHz crystal */
 	at91sam9260_initialize(18432000);
@@ -266,9 +266,9 @@
 
 MACHINE_START(ACMENETUSFOXG20, "Acme Systems srl FOX Board G20")
 	/* Maintainer: Sergio Tanzilli */
-	.boot_params	= AT91_SDRAM_BASE + 0x100,
 	.timer		= &at91sam926x_timer,
-	.map_io		= foxg20_map_io,
+	.map_io		= at91sam9260_map_io,
+	.init_early	= foxg20_init_early,
 	.init_irq	= foxg20_init_irq,
 	.init_machine	= foxg20_board_init,
 MACHINE_END
diff -druN linux-2.6.39-libre/arch/arm/mach-at91/board-gsia18s.c linux-3.0-rc7-libre/arch/arm/mach-at91/board-gsia18s.c
--- linux-2.6.39-libre/arch/arm/mach-at91/board-gsia18s.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-at91/board-gsia18s.c	2011-07-11 19:51:52.000000000 -0400
@@ -38,9 +38,9 @@
 #include "sam9_smc.h"
 #include "generic.h"
 
-static void __init gsia18s_map_io(void)
+static void __init gsia18s_init_early(void)
 {
-	stamp9g20_map_io();
+	stamp9g20_init_early();
 
 	/*
 	 * USART0 on ttyS1 (Rx, Tx, CTS, RTS, DTR, DSR, DCD, RI).
@@ -576,9 +576,9 @@
 }
 
 MACHINE_START(GSIA18S, "GS_IA18_S")
-	.boot_params	= AT91_SDRAM_BASE + 0x100,
 	.timer		= &at91sam926x_timer,
-	.map_io		= gsia18s_map_io,
+	.map_io		= at91sam9260_map_io,
+	.init_early	= gsia18s_init_early,
 	.init_irq	= init_irq,
 	.init_machine	= gsia18s_board_init,
 MACHINE_END
diff -druN linux-2.6.39-libre/arch/arm/mach-at91/board-kafa.c linux-3.0-rc7-libre/arch/arm/mach-at91/board-kafa.c
--- linux-2.6.39-libre/arch/arm/mach-at91/board-kafa.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-at91/board-kafa.c	2011-07-11 19:51:52.000000000 -0400
@@ -35,14 +35,18 @@
 
 #include <mach/board.h>
 #include <mach/gpio.h>
+#include <mach/cpu.h>
 
 #include "generic.h"
 
 
-static void __init kafa_map_io(void)
+static void __init kafa_init_early(void)
 {
+	/* Set cpu type: PQFP */
+	at91rm9200_set_type(ARCH_REVISON_9200_PQFP);
+
 	/* Initialize processor: 18.432 MHz crystal */
-	at91rm9200_initialize(18432000, AT91RM9200_PQFP);
+	at91rm9200_initialize(18432000);
 
 	/* Set up the LEDs */
 	at91_init_leds(AT91_PIN_PB4, AT91_PIN_PB4);
@@ -94,9 +98,9 @@
 
 MACHINE_START(KAFA, "Sperry-Sun KAFA")
 	/* Maintainer: Sergei Sharonov */
-	.boot_params	= AT91_SDRAM_BASE + 0x100,
 	.timer		= &at91rm9200_timer,
-	.map_io		= kafa_map_io,
+	.map_io		= at91rm9200_map_io,
+	.init_early	= kafa_init_early,
 	.init_irq	= kafa_init_irq,
 	.init_machine	= kafa_board_init,
 MACHINE_END
diff -druN linux-2.6.39-libre/arch/arm/mach-at91/board-kb9202.c linux-3.0-rc7-libre/arch/arm/mach-at91/board-kb9202.c
--- linux-2.6.39-libre/arch/arm/mach-at91/board-kb9202.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-at91/board-kb9202.c	2011-07-11 19:51:52.000000000 -0400
@@ -36,16 +36,19 @@
 
 #include <mach/board.h>
 #include <mach/gpio.h>
-
+#include <mach/cpu.h>
 #include <mach/at91rm9200_mc.h>
 
 #include "generic.h"
 
 
-static void __init kb9202_map_io(void)
+static void __init kb9202_init_early(void)
 {
+	/* Set cpu type: PQFP */
+	at91rm9200_set_type(ARCH_REVISON_9200_PQFP);
+
 	/* Initialize processor: 10 MHz crystal */
-	at91rm9200_initialize(10000000, AT91RM9200_PQFP);
+	at91rm9200_initialize(10000000);
 
 	/* Set up the LEDs */
 	at91_init_leds(AT91_PIN_PC19, AT91_PIN_PC18);
@@ -136,9 +139,9 @@
 
 MACHINE_START(KB9200, "KB920x")
 	/* Maintainer: KwikByte, Inc. */
-	.boot_params	= AT91_SDRAM_BASE + 0x100,
 	.timer		= &at91rm9200_timer,
-	.map_io		= kb9202_map_io,
+	.map_io		= at91rm9200_map_io,
+	.init_early	= kb9202_init_early,
 	.init_irq	= kb9202_init_irq,
 	.init_machine	= kb9202_board_init,
 MACHINE_END
diff -druN linux-2.6.39-libre/arch/arm/mach-at91/board-neocore926.c linux-3.0-rc7-libre/arch/arm/mach-at91/board-neocore926.c
--- linux-2.6.39-libre/arch/arm/mach-at91/board-neocore926.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-at91/board-neocore926.c	2011-07-11 19:51:52.000000000 -0400
@@ -51,7 +51,7 @@
 #include "generic.h"
 
 
-static void __init neocore926_map_io(void)
+static void __init neocore926_init_early(void)
 {
 	/* Initialize processor: 20 MHz crystal */
 	at91sam9263_initialize(20000000);
@@ -387,9 +387,9 @@
 
 MACHINE_START(NEOCORE926, "ADENEO NEOCORE 926")
 	/* Maintainer: ADENEO */
-	.boot_params	= AT91_SDRAM_BASE + 0x100,
 	.timer		= &at91sam926x_timer,
-	.map_io		= neocore926_map_io,
+	.map_io		= at91sam9263_map_io,
+	.init_early	= neocore926_init_early,
 	.init_irq	= neocore926_init_irq,
 	.init_machine	= neocore926_board_init,
 MACHINE_END
diff -druN linux-2.6.39-libre/arch/arm/mach-at91/board-pcontrol-g20.c linux-3.0-rc7-libre/arch/arm/mach-at91/board-pcontrol-g20.c
--- linux-2.6.39-libre/arch/arm/mach-at91/board-pcontrol-g20.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-at91/board-pcontrol-g20.c	2011-07-11 19:51:52.000000000 -0400
@@ -37,9 +37,9 @@
 #include "generic.h"
 
 
-static void __init pcontrol_g20_map_io(void)
+static void __init pcontrol_g20_init_early(void)
 {
-	stamp9g20_map_io();
+	stamp9g20_init_early();
 
 	/* USART0 on ttyS1. (Rx, Tx, CTS, RTS) piggyback  A2 */
 	at91_register_uart(AT91SAM9260_ID_US0, 1, ATMEL_UART_CTS
@@ -222,9 +222,9 @@
 
 MACHINE_START(PCONTROL_G20, "PControl G20")
 	/* Maintainer: pgsellmann@portner-elektronik.at */
-	.boot_params	= AT91_SDRAM_BASE + 0x100,
 	.timer		= &at91sam926x_timer,
-	.map_io		= pcontrol_g20_map_io,
+	.map_io		= at91sam9260_map_io,
+	.init_early	= pcontrol_g20_init_early,
 	.init_irq	= init_irq,
 	.init_machine	= pcontrol_g20_board_init,
 MACHINE_END
diff -druN linux-2.6.39-libre/arch/arm/mach-at91/board-picotux200.c linux-3.0-rc7-libre/arch/arm/mach-at91/board-picotux200.c
--- linux-2.6.39-libre/arch/arm/mach-at91/board-picotux200.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-at91/board-picotux200.c	2011-07-11 19:51:52.000000000 -0400
@@ -43,10 +43,10 @@
 #include "generic.h"
 
 
-static void __init picotux200_map_io(void)
+static void __init picotux200_init_early(void)
 {
 	/* Initialize processor: 18.432 MHz crystal */
-	at91rm9200_initialize(18432000, AT91RM9200_BGA);
+	at91rm9200_initialize(18432000);
 
 	/* DBGU on ttyS0. (Rx & Tx only) */
 	at91_register_uart(0, 0, 0);
@@ -123,9 +123,9 @@
 
 MACHINE_START(PICOTUX2XX, "picotux 200")
 	/* Maintainer: Kleinhenz Elektronik GmbH */
-	.boot_params	= AT91_SDRAM_BASE + 0x100,
 	.timer		= &at91rm9200_timer,
-	.map_io		= picotux200_map_io,
+	.map_io		= at91rm9200_map_io,
+	.init_early	= picotux200_init_early,
 	.init_irq	= picotux200_init_irq,
 	.init_machine	= picotux200_board_init,
 MACHINE_END
diff -druN linux-2.6.39-libre/arch/arm/mach-at91/board-qil-a9260.c linux-3.0-rc7-libre/arch/arm/mach-at91/board-qil-a9260.c
--- linux-2.6.39-libre/arch/arm/mach-at91/board-qil-a9260.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-at91/board-qil-a9260.c	2011-07-11 19:51:52.000000000 -0400
@@ -48,7 +48,7 @@
 #include "generic.h"
 
 
-static void __init ek_map_io(void)
+static void __init ek_init_early(void)
 {
 	/* Initialize processor: 12.000 MHz crystal */
 	at91sam9260_initialize(12000000);
@@ -268,9 +268,9 @@
 
 MACHINE_START(QIL_A9260, "CALAO QIL_A9260")
 	/* Maintainer: calao-systems */
-	.boot_params	= AT91_SDRAM_BASE + 0x100,
 	.timer		= &at91sam926x_timer,
-	.map_io		= ek_map_io,
+	.map_io		= at91sam9260_map_io,
+	.init_early	= ek_init_early,
 	.init_irq	= ek_init_irq,
 	.init_machine	= ek_board_init,
 MACHINE_END
diff -druN linux-2.6.39-libre/arch/arm/mach-at91/board-rm9200dk.c linux-3.0-rc7-libre/arch/arm/mach-at91/board-rm9200dk.c
--- linux-2.6.39-libre/arch/arm/mach-at91/board-rm9200dk.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-at91/board-rm9200dk.c	2011-07-11 19:51:52.000000000 -0400
@@ -45,10 +45,10 @@
 #include "generic.h"
 
 
-static void __init dk_map_io(void)
+static void __init dk_init_early(void)
 {
 	/* Initialize processor: 18.432 MHz crystal */
-	at91rm9200_initialize(18432000, AT91RM9200_BGA);
+	at91rm9200_initialize(18432000);
 
 	/* Setup the LEDs */
 	at91_init_leds(AT91_PIN_PB2, AT91_PIN_PB2);
@@ -227,9 +227,9 @@
 
 MACHINE_START(AT91RM9200DK, "Atmel AT91RM9200-DK")
 	/* Maintainer: SAN People/Atmel */
-	.boot_params	= AT91_SDRAM_BASE + 0x100,
 	.timer		= &at91rm9200_timer,
-	.map_io		= dk_map_io,
+	.map_io		= at91rm9200_map_io,
+	.init_early	= dk_init_early,
 	.init_irq	= dk_init_irq,
 	.init_machine	= dk_board_init,
 MACHINE_END
diff -druN linux-2.6.39-libre/arch/arm/mach-at91/board-rm9200ek.c linux-3.0-rc7-libre/arch/arm/mach-at91/board-rm9200ek.c
--- linux-2.6.39-libre/arch/arm/mach-at91/board-rm9200ek.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-at91/board-rm9200ek.c	2011-07-11 19:51:52.000000000 -0400
@@ -45,10 +45,10 @@
 #include "generic.h"
 
 
-static void __init ek_map_io(void)
+static void __init ek_init_early(void)
 {
 	/* Initialize processor: 18.432 MHz crystal */
-	at91rm9200_initialize(18432000, AT91RM9200_BGA);
+	at91rm9200_initialize(18432000);
 
 	/* Setup the LEDs */
 	at91_init_leds(AT91_PIN_PB1, AT91_PIN_PB2);
@@ -193,9 +193,9 @@
 
 MACHINE_START(AT91RM9200EK, "Atmel AT91RM9200-EK")
 	/* Maintainer: SAN People/Atmel */
-	.boot_params	= AT91_SDRAM_BASE + 0x100,
 	.timer		= &at91rm9200_timer,
-	.map_io		= ek_map_io,
+	.map_io		= at91rm9200_map_io,
+	.init_early	= ek_init_early,
 	.init_irq	= ek_init_irq,
 	.init_machine	= ek_board_init,
 MACHINE_END
diff -druN linux-2.6.39-libre/arch/arm/mach-at91/board-sam9260ek.c linux-3.0-rc7-libre/arch/arm/mach-at91/board-sam9260ek.c
--- linux-2.6.39-libre/arch/arm/mach-at91/board-sam9260ek.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-at91/board-sam9260ek.c	2011-07-11 19:51:52.000000000 -0400
@@ -44,12 +44,13 @@
 #include <mach/gpio.h>
 #include <mach/at91sam9_smc.h>
 #include <mach/at91_shdwc.h>
+#include <mach/system_rev.h>
 
 #include "sam9_smc.h"
 #include "generic.h"
 
 
-static void __init ek_map_io(void)
+static void __init ek_init_early(void)
 {
 	/* Initialize processor: 18.432 MHz crystal */
 	at91sam9260_initialize(18432000);
@@ -191,11 +192,6 @@
 	.rdy_pin	= AT91_PIN_PC13,
 	.enable_pin	= AT91_PIN_PC14,
 	.partition_info	= nand_partitions,
-#if defined(CONFIG_MTD_NAND_ATMEL_BUSWIDTH_16)
-	.bus_width_16	= 1,
-#else
-	.bus_width_16	= 0,
-#endif
 };
 
 static struct sam9_smc_config __initdata ek_nand_smc_config = {
@@ -218,6 +214,7 @@
 
 static void __init ek_add_device_nand(void)
 {
+	ek_nand_data.bus_width_16 = board_have_nand_16bit();
 	/* setup bus-width (8 or 16) */
 	if (ek_nand_data.bus_width_16)
 		ek_nand_smc_config.mode |= AT91_SMC_DBW_16;
@@ -356,9 +353,9 @@
 
 MACHINE_START(AT91SAM9260EK, "Atmel AT91SAM9260-EK")
 	/* Maintainer: Atmel */
-	.boot_params	= AT91_SDRAM_BASE + 0x100,
 	.timer		= &at91sam926x_timer,
-	.map_io		= ek_map_io,
+	.map_io		= at91sam9260_map_io,
+	.init_early	= ek_init_early,
 	.init_irq	= ek_init_irq,
 	.init_machine	= ek_board_init,
 MACHINE_END
diff -druN linux-2.6.39-libre/arch/arm/mach-at91/board-sam9261ek.c linux-3.0-rc7-libre/arch/arm/mach-at91/board-sam9261ek.c
--- linux-2.6.39-libre/arch/arm/mach-at91/board-sam9261ek.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-at91/board-sam9261ek.c	2011-07-11 19:51:52.000000000 -0400
@@ -48,12 +48,13 @@
 #include <mach/gpio.h>
 #include <mach/at91sam9_smc.h>
 #include <mach/at91_shdwc.h>
+#include <mach/system_rev.h>
 
 #include "sam9_smc.h"
 #include "generic.h"
 
 
-static void __init ek_map_io(void)
+static void __init ek_init_early(void)
 {
 	/* Initialize processor: 18.432 MHz crystal */
 	at91sam9261_initialize(18432000);
@@ -197,11 +198,6 @@
 	.rdy_pin	= AT91_PIN_PC15,
 	.enable_pin	= AT91_PIN_PC14,
 	.partition_info	= nand_partitions,
-#if defined(CONFIG_MTD_NAND_ATMEL_BUSWIDTH_16)
-	.bus_width_16	= 1,
-#else
-	.bus_width_16	= 0,
-#endif
 };
 
 static struct sam9_smc_config __initdata ek_nand_smc_config = {
@@ -224,6 +220,7 @@
 
 static void __init ek_add_device_nand(void)
 {
+	ek_nand_data.bus_width_16 = board_have_nand_16bit();
 	/* setup bus-width (8 or 16) */
 	if (ek_nand_data.bus_width_16)
 		ek_nand_smc_config.mode |= AT91_SMC_DBW_16;
@@ -623,9 +620,9 @@
 MACHINE_START(AT91SAM9G10EK, "Atmel AT91SAM9G10-EK")
 #endif
 	/* Maintainer: Atmel */
-	.boot_params	= AT91_SDRAM_BASE + 0x100,
 	.timer		= &at91sam926x_timer,
-	.map_io		= ek_map_io,
+	.map_io		= at91sam9261_map_io,
+	.init_early	= ek_init_early,
 	.init_irq	= ek_init_irq,
 	.init_machine	= ek_board_init,
 MACHINE_END
diff -druN linux-2.6.39-libre/arch/arm/mach-at91/board-sam9263ek.c linux-3.0-rc7-libre/arch/arm/mach-at91/board-sam9263ek.c
--- linux-2.6.39-libre/arch/arm/mach-at91/board-sam9263ek.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-at91/board-sam9263ek.c	2011-07-11 19:51:52.000000000 -0400
@@ -47,12 +47,13 @@
 #include <mach/gpio.h>
 #include <mach/at91sam9_smc.h>
 #include <mach/at91_shdwc.h>
+#include <mach/system_rev.h>
 
 #include "sam9_smc.h"
 #include "generic.h"
 
 
-static void __init ek_map_io(void)
+static void __init ek_init_early(void)
 {
 	/* Initialize processor: 16.367 MHz crystal */
 	at91sam9263_initialize(16367660);
@@ -198,11 +199,6 @@
 	.rdy_pin	= AT91_PIN_PA22,
 	.enable_pin	= AT91_PIN_PD15,
 	.partition_info	= nand_partitions,
-#if defined(CONFIG_MTD_NAND_ATMEL_BUSWIDTH_16)
-	.bus_width_16	= 1,
-#else
-	.bus_width_16	= 0,
-#endif
 };
 
 static struct sam9_smc_config __initdata ek_nand_smc_config = {
@@ -225,6 +221,7 @@
 
 static void __init ek_add_device_nand(void)
 {
+	ek_nand_data.bus_width_16 = board_have_nand_16bit();
 	/* setup bus-width (8 or 16) */
 	if (ek_nand_data.bus_width_16)
 		ek_nand_smc_config.mode |= AT91_SMC_DBW_16;
@@ -454,9 +451,9 @@
 
 MACHINE_START(AT91SAM9263EK, "Atmel AT91SAM9263-EK")
 	/* Maintainer: Atmel */
-	.boot_params	= AT91_SDRAM_BASE + 0x100,
 	.timer		= &at91sam926x_timer,
-	.map_io		= ek_map_io,
+	.map_io		= at91sam9263_map_io,
+	.init_early	= ek_init_early,
 	.init_irq	= ek_init_irq,
 	.init_machine	= ek_board_init,
 MACHINE_END
diff -druN linux-2.6.39-libre/arch/arm/mach-at91/board-sam9g20ek.c linux-3.0-rc7-libre/arch/arm/mach-at91/board-sam9g20ek.c
--- linux-2.6.39-libre/arch/arm/mach-at91/board-sam9g20ek.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-at91/board-sam9g20ek.c	2011-07-11 19:51:52.000000000 -0400
@@ -43,6 +43,7 @@
 #include <mach/board.h>
 #include <mach/gpio.h>
 #include <mach/at91sam9_smc.h>
+#include <mach/system_rev.h>
 
 #include "sam9_smc.h"
 #include "generic.h"
@@ -60,7 +61,7 @@
 }
 
 
-static void __init ek_map_io(void)
+static void __init ek_init_early(void)
 {
 	/* Initialize processor: 18.432 MHz crystal */
 	at91sam9260_initialize(18432000);
@@ -175,11 +176,6 @@
 	.rdy_pin	= AT91_PIN_PC13,
 	.enable_pin	= AT91_PIN_PC14,
 	.partition_info	= nand_partitions,
-#if defined(CONFIG_MTD_NAND_ATMEL_BUSWIDTH_16)
-	.bus_width_16	= 1,
-#else
-	.bus_width_16	= 0,
-#endif
 };
 
 static struct sam9_smc_config __initdata ek_nand_smc_config = {
@@ -202,6 +198,7 @@
 
 static void __init ek_add_device_nand(void)
 {
+	ek_nand_data.bus_width_16 = board_have_nand_16bit();
 	/* setup bus-width (8 or 16) */
 	if (ek_nand_data.bus_width_16)
 		ek_nand_smc_config.mode |= AT91_SMC_DBW_16;
@@ -406,18 +403,18 @@
 
 MACHINE_START(AT91SAM9G20EK, "Atmel AT91SAM9G20-EK")
 	/* Maintainer: Atmel */
-	.boot_params	= AT91_SDRAM_BASE + 0x100,
 	.timer		= &at91sam926x_timer,
-	.map_io		= ek_map_io,
+	.map_io		= at91sam9260_map_io,
+	.init_early	= ek_init_early,
 	.init_irq	= ek_init_irq,
 	.init_machine	= ek_board_init,
 MACHINE_END
 
 MACHINE_START(AT91SAM9G20EK_2MMC, "Atmel AT91SAM9G20-EK 2 MMC Slot Mod")
 	/* Maintainer: Atmel */
-	.boot_params	= AT91_SDRAM_BASE + 0x100,
 	.timer		= &at91sam926x_timer,
-	.map_io		= ek_map_io,
+	.map_io		= at91sam9260_map_io,
+	.init_early	= ek_init_early,
 	.init_irq	= ek_init_irq,
 	.init_machine	= ek_board_init,
 MACHINE_END
diff -druN linux-2.6.39-libre/arch/arm/mach-at91/board-sam9-l9260.c linux-3.0-rc7-libre/arch/arm/mach-at91/board-sam9-l9260.c
--- linux-2.6.39-libre/arch/arm/mach-at91/board-sam9-l9260.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-at91/board-sam9-l9260.c	2011-07-11 19:51:52.000000000 -0400
@@ -44,7 +44,7 @@
 #include "generic.h"
 
 
-static void __init ek_map_io(void)
+static void __init ek_init_early(void)
 {
 	/* Initialize processor: 18.432 MHz crystal */
 	at91sam9260_initialize(18432000);
@@ -212,9 +212,9 @@
 
 MACHINE_START(SAM9_L9260, "Olimex SAM9-L9260")
 	/* Maintainer: Olimex */
-	.boot_params	= AT91_SDRAM_BASE + 0x100,
 	.timer		= &at91sam926x_timer,
-	.map_io		= ek_map_io,
+	.map_io		= at91sam9260_map_io,
+	.init_early	= ek_init_early,
 	.init_irq	= ek_init_irq,
 	.init_machine	= ek_board_init,
 MACHINE_END
diff -druN linux-2.6.39-libre/arch/arm/mach-at91/board-sam9m10g45ek.c linux-3.0-rc7-libre/arch/arm/mach-at91/board-sam9m10g45ek.c
--- linux-2.6.39-libre/arch/arm/mach-at91/board-sam9m10g45ek.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-at91/board-sam9m10g45ek.c	2011-07-11 19:51:52.000000000 -0400
@@ -41,12 +41,13 @@
 #include <mach/gpio.h>
 #include <mach/at91sam9_smc.h>
 #include <mach/at91_shdwc.h>
+#include <mach/system_rev.h>
 
 #include "sam9_smc.h"
 #include "generic.h"
 
 
-static void __init ek_map_io(void)
+static void __init ek_init_early(void)
 {
 	/* Initialize processor: 12.000 MHz crystal */
 	at91sam9g45_initialize(12000000);
@@ -155,11 +156,6 @@
 	.rdy_pin	= AT91_PIN_PC8,
 	.enable_pin	= AT91_PIN_PC14,
 	.partition_info	= nand_partitions,
-#if defined(CONFIG_MTD_NAND_ATMEL_BUSWIDTH_16)
-	.bus_width_16	= 1,
-#else
-	.bus_width_16	= 0,
-#endif
 };
 
 static struct sam9_smc_config __initdata ek_nand_smc_config = {
@@ -182,6 +178,7 @@
 
 static void __init ek_add_device_nand(void)
 {
+	ek_nand_data.bus_width_16 = board_have_nand_16bit();
 	/* setup bus-width (8 or 16) */
 	if (ek_nand_data.bus_width_16)
 		ek_nand_smc_config.mode |= AT91_SMC_DBW_16;
@@ -424,9 +421,9 @@
 
 MACHINE_START(AT91SAM9M10G45EK, "Atmel AT91SAM9M10G45-EK")
 	/* Maintainer: Atmel */
-	.boot_params	= AT91_SDRAM_BASE + 0x100,
 	.timer		= &at91sam926x_timer,
-	.map_io		= ek_map_io,
+	.map_io		= at91sam9g45_map_io,
+	.init_early	= ek_init_early,
 	.init_irq	= ek_init_irq,
 	.init_machine	= ek_board_init,
 MACHINE_END
diff -druN linux-2.6.39-libre/arch/arm/mach-at91/board-sam9rlek.c linux-3.0-rc7-libre/arch/arm/mach-at91/board-sam9rlek.c
--- linux-2.6.39-libre/arch/arm/mach-at91/board-sam9rlek.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-at91/board-sam9rlek.c	2011-07-11 19:51:52.000000000 -0400
@@ -38,7 +38,7 @@
 #include "generic.h"
 
 
-static void __init ek_map_io(void)
+static void __init ek_init_early(void)
 {
 	/* Initialize processor: 12.000 MHz crystal */
 	at91sam9rl_initialize(12000000);
@@ -329,9 +329,9 @@
 
 MACHINE_START(AT91SAM9RLEK, "Atmel AT91SAM9RL-EK")
 	/* Maintainer: Atmel */
-	.boot_params	= AT91_SDRAM_BASE + 0x100,
 	.timer		= &at91sam926x_timer,
-	.map_io		= ek_map_io,
+	.map_io		= at91sam9rl_map_io,
+	.init_early	= ek_init_early,
 	.init_irq	= ek_init_irq,
 	.init_machine	= ek_board_init,
 MACHINE_END
diff -druN linux-2.6.39-libre/arch/arm/mach-at91/board-snapper9260.c linux-3.0-rc7-libre/arch/arm/mach-at91/board-snapper9260.c
--- linux-2.6.39-libre/arch/arm/mach-at91/board-snapper9260.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-at91/board-snapper9260.c	2011-07-11 19:51:52.000000000 -0400
@@ -40,7 +40,7 @@
 
 #define SNAPPER9260_IO_EXP_GPIO(x)	(NR_BUILTIN_GPIO + (x))
 
-static void __init snapper9260_map_io(void)
+static void __init snapper9260_init_early(void)
 {
 	at91sam9260_initialize(18432000);
 
@@ -178,9 +178,9 @@
 }
 
 MACHINE_START(SNAPPER_9260, "Bluewater Systems Snapper 9260/9G20 module")
-	.boot_params	= AT91_SDRAM_BASE + 0x100,
 	.timer		= &at91sam926x_timer,
-	.map_io		= snapper9260_map_io,
+	.map_io		= at91sam9260_map_io,
+	.init_early	= snapper9260_init_early,
 	.init_irq	= snapper9260_init_irq,
 	.init_machine	= snapper9260_board_init,
 MACHINE_END
diff -druN linux-2.6.39-libre/arch/arm/mach-at91/board-stamp9g20.c linux-3.0-rc7-libre/arch/arm/mach-at91/board-stamp9g20.c
--- linux-2.6.39-libre/arch/arm/mach-at91/board-stamp9g20.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-at91/board-stamp9g20.c	2011-07-11 19:51:52.000000000 -0400
@@ -32,7 +32,7 @@
 #include "generic.h"
 
 
-void __init stamp9g20_map_io(void)
+void __init stamp9g20_init_early(void)
 {
 	/* Initialize processor: 18.432 MHz crystal */
 	at91sam9260_initialize(18432000);
@@ -44,9 +44,9 @@
 	at91_set_serial_console(0);
 }
 
-static void __init stamp9g20evb_map_io(void)
+static void __init stamp9g20evb_init_early(void)
 {
-	stamp9g20_map_io();
+	stamp9g20_init_early();
 
 	/* USART0 on ttyS1. (Rx, Tx, CTS, RTS, DTR, DSR, DCD, RI) */
 	at91_register_uart(AT91SAM9260_ID_US0, 1, ATMEL_UART_CTS | ATMEL_UART_RTS
@@ -54,9 +54,9 @@
 						| ATMEL_UART_DCD | ATMEL_UART_RI);
 }
 
-static void __init portuxg20_map_io(void)
+static void __init portuxg20_init_early(void)
 {
-	stamp9g20_map_io();
+	stamp9g20_init_early();
 
 	/* USART0 on ttyS1. (Rx, Tx, CTS, RTS, DTR, DSR, DCD, RI) */
 	at91_register_uart(AT91SAM9260_ID_US0, 1, ATMEL_UART_CTS | ATMEL_UART_RTS
@@ -298,18 +298,18 @@
 
 MACHINE_START(PORTUXG20, "taskit PortuxG20")
 	/* Maintainer: taskit GmbH */
-	.boot_params	= AT91_SDRAM_BASE + 0x100,
 	.timer		= &at91sam926x_timer,
-	.map_io		= portuxg20_map_io,
+	.map_io		= at91sam9260_map_io,
+	.init_early	= portuxg20_init_early,
 	.init_irq	= init_irq,
 	.init_machine	= portuxg20_board_init,
 MACHINE_END
 
 MACHINE_START(STAMP9G20, "taskit Stamp9G20")
 	/* Maintainer: taskit GmbH */
-	.boot_params	= AT91_SDRAM_BASE + 0x100,
 	.timer		= &at91sam926x_timer,
-	.map_io		= stamp9g20evb_map_io,
+	.map_io		= at91sam9260_map_io,
+	.init_early	= stamp9g20evb_init_early,
 	.init_irq	= init_irq,
 	.init_machine	= stamp9g20evb_board_init,
 MACHINE_END
diff -druN linux-2.6.39-libre/arch/arm/mach-at91/board-usb-a9260.c linux-3.0-rc7-libre/arch/arm/mach-at91/board-usb-a9260.c
--- linux-2.6.39-libre/arch/arm/mach-at91/board-usb-a9260.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-at91/board-usb-a9260.c	2011-07-11 19:51:52.000000000 -0400
@@ -48,7 +48,7 @@
 #include "generic.h"
 
 
-static void __init ek_map_io(void)
+static void __init ek_init_early(void)
 {
 	/* Initialize processor: 12.000 MHz crystal */
 	at91sam9260_initialize(12000000);
@@ -228,9 +228,9 @@
 
 MACHINE_START(USB_A9260, "CALAO USB_A9260")
 	/* Maintainer: calao-systems */
-	.boot_params	= AT91_SDRAM_BASE + 0x100,
 	.timer		= &at91sam926x_timer,
-	.map_io		= ek_map_io,
+	.map_io		= at91sam9260_map_io,
+	.init_early	= ek_init_early,
 	.init_irq	= ek_init_irq,
 	.init_machine	= ek_board_init,
 MACHINE_END
diff -druN linux-2.6.39-libre/arch/arm/mach-at91/board-usb-a9263.c linux-3.0-rc7-libre/arch/arm/mach-at91/board-usb-a9263.c
--- linux-2.6.39-libre/arch/arm/mach-at91/board-usb-a9263.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-at91/board-usb-a9263.c	2011-07-11 19:51:52.000000000 -0400
@@ -47,7 +47,7 @@
 #include "generic.h"
 
 
-static void __init ek_map_io(void)
+static void __init ek_init_early(void)
 {
 	/* Initialize processor: 12.00 MHz crystal */
 	at91sam9263_initialize(12000000);
@@ -244,9 +244,9 @@
 
 MACHINE_START(USB_A9263, "CALAO USB_A9263")
 	/* Maintainer: calao-systems */
-	.boot_params	= AT91_SDRAM_BASE + 0x100,
 	.timer		= &at91sam926x_timer,
-	.map_io		= ek_map_io,
+	.map_io		= at91sam9263_map_io,
+	.init_early	= ek_init_early,
 	.init_irq	= ek_init_irq,
 	.init_machine	= ek_board_init,
 MACHINE_END
diff -druN linux-2.6.39-libre/arch/arm/mach-at91/board-yl-9200.c linux-3.0-rc7-libre/arch/arm/mach-at91/board-yl-9200.c
--- linux-2.6.39-libre/arch/arm/mach-at91/board-yl-9200.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-at91/board-yl-9200.c	2011-07-11 19:51:52.000000000 -0400
@@ -45,14 +45,18 @@
 #include <mach/board.h>
 #include <mach/gpio.h>
 #include <mach/at91rm9200_mc.h>
+#include <mach/cpu.h>
 
 #include "generic.h"
 
 
-static void __init yl9200_map_io(void)
+static void __init yl9200_init_early(void)
 {
+	/* Set cpu type: PQFP */
+	at91rm9200_set_type(ARCH_REVISON_9200_PQFP);
+
 	/* Initialize processor: 18.432 MHz crystal */
-	at91rm9200_initialize(18432000, AT91RM9200_PQFP);
+	at91rm9200_initialize(18432000);
 
 	/* Setup the LEDs D2=PB17 (timer), D3=PB16 (cpu) */
 	at91_init_leds(AT91_PIN_PB16, AT91_PIN_PB17);
@@ -594,9 +598,9 @@
 
 MACHINE_START(YL9200, "uCdragon YL-9200")
 	/* Maintainer: S.Birtles */
-	.boot_params	= AT91_SDRAM_BASE + 0x100,
 	.timer		= &at91rm9200_timer,
-	.map_io		= yl9200_map_io,
+	.map_io		= at91rm9200_map_io,
+	.init_early	= yl9200_init_early,
 	.init_irq	= yl9200_init_irq,
 	.init_machine	= yl9200_board_init,
 MACHINE_END
diff -druN linux-2.6.39-libre/arch/arm/mach-at91/clock.c linux-3.0-rc7-libre/arch/arm/mach-at91/clock.c
--- linux-2.6.39-libre/arch/arm/mach-at91/clock.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-at91/clock.c	2011-07-11 19:51:52.000000000 -0400
@@ -163,7 +163,7 @@
 	.parent		= &pllb,
 	.mode		= pmc_sys_mode,
 };
-static struct clk utmi_clk = {
+struct clk utmi_clk = {
 	.name		= "utmi_clk",
 	.parent		= &main_clk,
 	.pmc_mask	= AT91_PMC_UPLLEN,	/* in CKGR_UCKR */
@@ -182,7 +182,7 @@
  * memory, interfaces to on-chip peripherals, the AIC, and sometimes more
  * (e.g baud rate generation).  It's sourced from one of the primary clocks.
  */
-static struct clk mck = {
+struct clk mck = {
 	.name		= "mck",
 	.pmc_mask	= AT91_PMC_MCKRDY,	/* in PMC_SR */
 };
@@ -215,43 +215,6 @@
 	return NULL;
 }
 
-/*
- * Associate a particular clock with a function (eg, "uart") and device.
- * The drivers can then request the same 'function' with several different
- * devices and not care about which clock name to use.
- */
-void __init at91_clock_associate(const char *id, struct device *dev, const char *func)
-{
-	struct clk *clk = clk_get(NULL, id);
-
-	if (!dev || !clk || !IS_ERR(clk_get(dev, func)))
-		return;
-
-	clk->function = func;
-	clk->dev = dev;
-}
-
-/* clocks cannot be de-registered no refcounting necessary */
-struct clk *clk_get(struct device *dev, const char *id)
-{
-	struct clk *clk;
-
-	list_for_each_entry(clk, &clocks, node) {
-		if (strcmp(id, clk->name) == 0)
-			return clk;
-		if (clk->function && (dev == clk->dev) && strcmp(id, clk->function) == 0)
-			return clk;
-	}
-
-	return ERR_PTR(-ENOENT);
-}
-EXPORT_SYMBOL(clk_get);
-
-void clk_put(struct clk *clk)
-{
-}
-EXPORT_SYMBOL(clk_put);
-
 static void __clk_enable(struct clk *clk)
 {
 	if (clk->parent)
@@ -498,32 +461,38 @@
 /*------------------------------------------------------------------------*/
 
 /* Register a new clock */
+static void __init at91_clk_add(struct clk *clk)
+{
+	list_add_tail(&clk->node, &clocks);
+
+	clk->cl.con_id = clk->name;
+	clk->cl.clk = clk;
+	clkdev_add(&clk->cl);
+}
+
 int __init clk_register(struct clk *clk)
 {
 	if (clk_is_peripheral(clk)) {
 		if (!clk->parent)
 			clk->parent = &mck;
 		clk->mode = pmc_periph_mode;
-		list_add_tail(&clk->node, &clocks);
 	}
 	else if (clk_is_sys(clk)) {
 		clk->parent = &mck;
 		clk->mode = pmc_sys_mode;
-
-		list_add_tail(&clk->node, &clocks);
 	}
 #ifdef CONFIG_AT91_PROGRAMMABLE_CLOCKS
 	else if (clk_is_programmable(clk)) {
 		clk->mode = pmc_sys_mode;
 		init_programmable_clock(clk);
-		list_add_tail(&clk->node, &clocks);
 	}
 #endif
 
+	at91_clk_add(clk);
+
 	return 0;
 }
 
-
 /*------------------------------------------------------------------------*/
 
 static u32 __init at91_pll_rate(struct clk *pll, u32 freq, u32 reg)
@@ -630,7 +599,7 @@
 		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_at572d940hf()) {
+		   cpu_is_at91sam9g10()) {
 		uhpck.pmc_mask = AT91SAM926x_PMC_UHP;
 		udpck.pmc_mask = AT91SAM926x_PMC_UDP;
 	} else if (cpu_is_at91cap9()) {
@@ -754,19 +723,19 @@
 
 	/* Register the PMC's standard clocks */
 	for (i = 0; i < ARRAY_SIZE(standard_pmc_clocks); i++)
-		list_add_tail(&standard_pmc_clocks[i]->node, &clocks);
+		at91_clk_add(standard_pmc_clocks[i]);
 
 	if (cpu_has_pllb())
-		list_add_tail(&pllb.node, &clocks);
+		at91_clk_add(&pllb);
 
 	if (cpu_has_uhp())
-		list_add_tail(&uhpck.node, &clocks);
+		at91_clk_add(&uhpck);
 
 	if (cpu_has_udpfs())
-		list_add_tail(&udpck.node, &clocks);
+		at91_clk_add(&udpck);
 
 	if (cpu_has_utmi())
-		list_add_tail(&utmi_clk.node, &clocks);
+		at91_clk_add(&utmi_clk);
 
 	/* MCK and CPU clock are "always on" */
 	clk_enable(&mck);
diff -druN linux-2.6.39-libre/arch/arm/mach-at91/clock.h linux-3.0-rc7-libre/arch/arm/mach-at91/clock.h
--- linux-2.6.39-libre/arch/arm/mach-at91/clock.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-at91/clock.h	2011-07-11 19:51:52.000000000 -0400
@@ -6,6 +6,8 @@
  * published by the Free Software Foundation.
  */
 
+#include <linux/clkdev.h>
+
 #define CLK_TYPE_PRIMARY	0x1
 #define CLK_TYPE_PLL		0x2
 #define CLK_TYPE_PROGRAMMABLE	0x4
@@ -16,8 +18,7 @@
 struct clk {
 	struct list_head node;
 	const char	*name;		/* unique clock name */
-	const char	*function;	/* function of the clock */
-	struct device	*dev;		/* device associated with function */
+	struct clk_lookup cl;
 	unsigned long	rate_hz;
 	struct clk	*parent;
 	u32		pmc_mask;
@@ -29,3 +30,18 @@
 
 
 extern int __init clk_register(struct clk *clk);
+extern struct clk mck;
+extern struct clk utmi_clk;
+
+#define CLKDEV_CON_ID(_id, _clk)			\
+	{						\
+		.con_id = _id,				\
+		.clk = _clk,				\
+	}
+
+#define CLKDEV_CON_DEV_ID(_con_id, _dev_id, _clk)	\
+	{						\
+		.con_id = _con_id,			\
+		.dev_id = _dev_id,			\
+		.clk = _clk,				\
+	}
diff -druN linux-2.6.39-libre/arch/arm/mach-at91/generic.h linux-3.0-rc7-libre/arch/arm/mach-at91/generic.h
--- linux-2.6.39-libre/arch/arm/mach-at91/generic.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-at91/generic.h	2011-07-11 19:51:52.000000000 -0400
@@ -8,8 +8,21 @@
  * published by the Free Software Foundation.
  */
 
+#include <linux/clkdev.h>
+
+ /* Map io */
+extern void __init at91rm9200_map_io(void);
+extern void __init at91sam9260_map_io(void);
+extern void __init at91sam9261_map_io(void);
+extern void __init at91sam9263_map_io(void);
+extern void __init at91sam9rl_map_io(void);
+extern void __init at91sam9g45_map_io(void);
+extern void __init at91x40_map_io(void);
+extern void __init at91cap9_map_io(void);
+
  /* Processors */
-extern void __init at91rm9200_initialize(unsigned long main_clock, unsigned short banks);
+extern void __init at91rm9200_set_type(int type);
+extern void __init at91rm9200_initialize(unsigned long main_clock);
 extern void __init at91sam9260_initialize(unsigned long main_clock);
 extern void __init at91sam9261_initialize(unsigned long main_clock);
 extern void __init at91sam9263_initialize(unsigned long main_clock);
@@ -17,7 +30,6 @@
 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[]);
@@ -28,7 +40,6 @@
 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 */
@@ -39,8 +50,19 @@
 
  /* Clocks */
 extern int __init at91_clock_init(unsigned long main_clock);
+/*
+ * function to specify the clock of the default console. As we do not
+ * use the device/driver bus, the dev_name is not intialize. So we need
+ * to link the clock to a specific con_id only "usart"
+ */
+extern void __init at91rm9200_set_console_clock(int id);
+extern void __init at91sam9260_set_console_clock(int id);
+extern void __init at91sam9261_set_console_clock(int id);
+extern void __init at91sam9263_set_console_clock(int id);
+extern void __init at91sam9rl_set_console_clock(int id);
+extern void __init at91sam9g45_set_console_clock(int id);
+extern void __init at91cap9_set_console_clock(int id);
 struct device;
-extern void __init at91_clock_associate(const char *id, struct device *dev, const char *func);
 
  /* Power Management */
 extern void at91_irq_suspend(void);
diff -druN linux-2.6.39-libre/arch/arm/mach-at91/include/mach/at572d940hf.h linux-3.0-rc7-libre/arch/arm/mach-at91/include/mach/at572d940hf.h
--- linux-2.6.39-libre/arch/arm/mach-at91/include/mach/at572d940hf.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-at91/include/mach/at572d940hf.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,123 +0,0 @@
-/*
- * 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_SDRAMC0	(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 -druN linux-2.6.39-libre/arch/arm/mach-at91/include/mach/at572d940hf_matrix.h linux-3.0-rc7-libre/arch/arm/mach-at91/include/mach/at572d940hf_matrix.h
--- linux-2.6.39-libre/arch/arm/mach-at91/include/mach/at572d940hf_matrix.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-at91/include/mach/at572d940hf_matrix.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,123 +0,0 @@
-/*
- * 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 -druN linux-2.6.39-libre/arch/arm/mach-at91/include/mach/at91cap9.h linux-3.0-rc7-libre/arch/arm/mach-at91/include/mach/at91cap9.h
--- linux-2.6.39-libre/arch/arm/mach-at91/include/mach/at91cap9.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-at91/include/mach/at91cap9.h	2011-07-11 19:51:52.000000000 -0400
@@ -20,8 +20,6 @@
 /*
  * Peripheral identifiers/interrupts.
  */
-#define AT91_ID_FIQ		0	/* Advanced Interrupt Controller (FIQ) */
-#define AT91_ID_SYS		1	/* System Peripherals */
 #define AT91CAP9_ID_PIOABCD	2	/* Parallel IO Controller A, B, C and D */
 #define AT91CAP9_ID_MPB0	3	/* MP Block Peripheral 0 */
 #define AT91CAP9_ID_MPB1	4	/* MP Block Peripheral 1 */
@@ -123,6 +121,4 @@
 #define AT91CAP9_UDPHS_FIFO	0x00600000	/* USB High Speed Device Port */
 #define AT91CAP9_UHP_BASE	0x00700000	/* USB Host controller */
 
-#define CONFIG_DRAM_BASE	AT91_CHIPSELECT_6
-
 #endif
diff -druN linux-2.6.39-libre/arch/arm/mach-at91/include/mach/at91rm9200.h linux-3.0-rc7-libre/arch/arm/mach-at91/include/mach/at91rm9200.h
--- linux-2.6.39-libre/arch/arm/mach-at91/include/mach/at91rm9200.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-at91/include/mach/at91rm9200.h	2011-07-11 19:51:52.000000000 -0400
@@ -19,8 +19,6 @@
 /*
  * Peripheral identifiers/interrupts.
  */
-#define AT91_ID_FIQ		0	/* Advanced Interrupt Controller (FIQ) */
-#define AT91_ID_SYS		1	/* System Peripheral */
 #define AT91RM9200_ID_PIOA	2	/* Parallel IO Controller A */
 #define AT91RM9200_ID_PIOB	3	/* Parallel IO Controller B */
 #define AT91RM9200_ID_PIOC	4	/* Parallel IO Controller C */
diff -druN linux-2.6.39-libre/arch/arm/mach-at91/include/mach/at91sam9260.h linux-3.0-rc7-libre/arch/arm/mach-at91/include/mach/at91sam9260.h
--- linux-2.6.39-libre/arch/arm/mach-at91/include/mach/at91sam9260.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-at91/include/mach/at91sam9260.h	2011-07-11 19:51:52.000000000 -0400
@@ -20,8 +20,6 @@
 /*
  * Peripheral identifiers/interrupts.
  */
-#define AT91_ID_FIQ		0	/* Advanced Interrupt Controller (FIQ) */
-#define AT91_ID_SYS		1	/* System Peripherals */
 #define AT91SAM9260_ID_PIOA	2	/* Parallel IO Controller A */
 #define AT91SAM9260_ID_PIOB	3	/* Parallel IO Controller B */
 #define AT91SAM9260_ID_PIOC	4	/* Parallel IO Controller C */
diff -druN linux-2.6.39-libre/arch/arm/mach-at91/include/mach/at91sam9261.h linux-3.0-rc7-libre/arch/arm/mach-at91/include/mach/at91sam9261.h
--- linux-2.6.39-libre/arch/arm/mach-at91/include/mach/at91sam9261.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-at91/include/mach/at91sam9261.h	2011-07-11 19:51:52.000000000 -0400
@@ -18,8 +18,6 @@
 /*
  * Peripheral identifiers/interrupts.
  */
-#define AT91_ID_FIQ		0	/* Advanced Interrupt Controller (FIQ) */
-#define AT91_ID_SYS		1	/* System Peripherals */
 #define AT91SAM9261_ID_PIOA	2	/* Parallel IO Controller A */
 #define AT91SAM9261_ID_PIOB	3	/* Parallel IO Controller B */
 #define AT91SAM9261_ID_PIOC	4	/* Parallel IO Controller C */
diff -druN linux-2.6.39-libre/arch/arm/mach-at91/include/mach/at91sam9263.h linux-3.0-rc7-libre/arch/arm/mach-at91/include/mach/at91sam9263.h
--- linux-2.6.39-libre/arch/arm/mach-at91/include/mach/at91sam9263.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-at91/include/mach/at91sam9263.h	2011-07-11 19:51:52.000000000 -0400
@@ -18,8 +18,6 @@
 /*
  * Peripheral identifiers/interrupts.
  */
-#define AT91_ID_FIQ		0	/* Advanced Interrupt Controller (FIQ) */
-#define AT91_ID_SYS		1	/* System Peripherals */
 #define AT91SAM9263_ID_PIOA	2	/* Parallel IO Controller A */
 #define AT91SAM9263_ID_PIOB	3	/* Parallel IO Controller B */
 #define AT91SAM9263_ID_PIOCDE	4	/* Parallel IO Controller C, D and E */
diff -druN linux-2.6.39-libre/arch/arm/mach-at91/include/mach/at91sam9g45.h linux-3.0-rc7-libre/arch/arm/mach-at91/include/mach/at91sam9g45.h
--- linux-2.6.39-libre/arch/arm/mach-at91/include/mach/at91sam9g45.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-at91/include/mach/at91sam9g45.h	2011-07-11 19:51:52.000000000 -0400
@@ -18,8 +18,6 @@
 /*
  * Peripheral identifiers/interrupts.
  */
-#define AT91_ID_FIQ		0	/* Advanced Interrupt Controller (FIQ) */
-#define AT91_ID_SYS		1	/* System Controller Interrupt */
 #define AT91SAM9G45_ID_PIOA	2	/* Parallel I/O Controller A */
 #define AT91SAM9G45_ID_PIOB	3	/* Parallel I/O Controller B */
 #define AT91SAM9G45_ID_PIOC	4	/* Parallel I/O Controller C */
@@ -131,8 +129,6 @@
 #define AT91SAM9G45_EHCI_BASE	0x00800000	/* USB Host controller (EHCI) */
 #define AT91SAM9G45_VDEC_BASE	0x00900000	/* Video Decoder Controller */
 
-#define CONFIG_DRAM_BASE	AT91_CHIPSELECT_6
-
 #define CONSISTENT_DMA_SIZE	SZ_4M
 
 /*
diff -druN linux-2.6.39-libre/arch/arm/mach-at91/include/mach/at91sam9rl.h linux-3.0-rc7-libre/arch/arm/mach-at91/include/mach/at91sam9rl.h
--- linux-2.6.39-libre/arch/arm/mach-at91/include/mach/at91sam9rl.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-at91/include/mach/at91sam9rl.h	2011-07-11 19:51:52.000000000 -0400
@@ -17,8 +17,6 @@
 /*
  * Peripheral identifiers/interrupts.
  */
-#define AT91_ID_FIQ		0	/* Advanced Interrupt Controller (FIQ) */
-#define AT91_ID_SYS		1	/* System Controller */
 #define AT91SAM9RL_ID_PIOA	2	/* Parallel IO Controller A */
 #define AT91SAM9RL_ID_PIOB	3	/* Parallel IO Controller B */
 #define AT91SAM9RL_ID_PIOC	4	/* Parallel IO Controller C */
diff -druN linux-2.6.39-libre/arch/arm/mach-at91/include/mach/at91x40.h linux-3.0-rc7-libre/arch/arm/mach-at91/include/mach/at91x40.h
--- linux-2.6.39-libre/arch/arm/mach-at91/include/mach/at91x40.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-at91/include/mach/at91x40.h	2011-07-11 19:51:52.000000000 -0400
@@ -15,8 +15,6 @@
 /*
  *	IRQ list.
  */
-#define AT91_ID_FIQ		0	/* FIQ */
-#define AT91_ID_SYS		1	/* System Peripheral */
 #define AT91X40_ID_USART0	2	/* USART port 0 */
 #define AT91X40_ID_USART1	3	/* USART port 1 */
 #define AT91X40_ID_TC0		4	/* Timer/Counter 0 */
diff -druN linux-2.6.39-libre/arch/arm/mach-at91/include/mach/board.h linux-3.0-rc7-libre/arch/arm/mach-at91/include/mach/board.h
--- linux-2.6.39-libre/arch/arm/mach-at91/include/mach/board.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-at91/include/mach/board.h	2011-07-11 19:51:52.000000000 -0400
@@ -90,7 +90,7 @@
 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_AT572D940HF)
+	|| defined(CONFIG_ARCH_AT91SAM9G45)
 #define eth_platform_data	at91_eth_data
 #endif
 
@@ -140,6 +140,7 @@
 extern struct platform_device *atmel_default_console_device;
 
 struct atmel_uart_data {
+	int			num;		/* port num */
 	short			use_dma_tx;	/* use transmit DMA? */
 	short			use_dma_rx;	/* use receive DMA? */
 	void __iomem		*regs;		/* virt. base address, if any */
@@ -203,9 +204,6 @@
 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 -druN linux-2.6.39-libre/arch/arm/mach-at91/include/mach/clkdev.h linux-3.0-rc7-libre/arch/arm/mach-at91/include/mach/clkdev.h
--- linux-2.6.39-libre/arch/arm/mach-at91/include/mach/clkdev.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/arm/mach-at91/include/mach/clkdev.h	2011-07-11 19:51:52.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 -druN linux-2.6.39-libre/arch/arm/mach-at91/include/mach/cpu.h linux-3.0-rc7-libre/arch/arm/mach-at91/include/mach/cpu.h
--- linux-2.6.39-libre/arch/arm/mach-at91/include/mach/cpu.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-at91/include/mach/cpu.h	2011-07-11 19:51:52.000000000 -0400
@@ -34,8 +34,6 @@
 #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
@@ -90,9 +88,16 @@
 #endif
 
 #ifdef CONFIG_ARCH_AT91RM9200
+extern int rm9200_type;
+#define ARCH_REVISON_9200_BGA	(0 << 0)
+#define ARCH_REVISON_9200_PQFP	(1 << 0)
 #define cpu_is_at91rm9200()	(at91_cpu_identify() == ARCH_ID_AT91RM9200)
+#define cpu_is_at91rm9200_bga()	(!cpu_is_at91rm9200_pqfp())
+#define cpu_is_at91rm9200_pqfp() (cpu_is_at91rm9200() && rm9200_type & ARCH_REVISON_9200_PQFP)
 #else
 #define cpu_is_at91rm9200()	(0)
+#define cpu_is_at91rm9200_bga()	(0)
+#define cpu_is_at91rm9200_pqfp() (0)
 #endif
 
 #ifdef CONFIG_ARCH_AT91SAM9260
@@ -181,12 +186,6 @@
 #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 -druN linux-2.6.39-libre/arch/arm/mach-at91/include/mach/hardware.h linux-3.0-rc7-libre/arch/arm/mach-at91/include/mach/hardware.h
--- linux-2.6.39-libre/arch/arm/mach-at91/include/mach/hardware.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-at91/include/mach/hardware.h	2011-07-11 19:51:52.000000000 -0400
@@ -32,13 +32,17 @@
 #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
 
 
+/*
+ * Peripheral identifiers/interrupts.
+ */
+#define AT91_ID_FIQ		0	/* Advanced Interrupt Controller (FIQ) */
+#define AT91_ID_SYS		1	/* System Peripherals */
+
 #ifdef CONFIG_MMU
 /*
  * Remap the peripherals from address 0xFFF78000 .. 0xFFFFFFFF
@@ -82,13 +86,6 @@
 #define AT91_CHIPSELECT_6	0x70000000
 #define AT91_CHIPSELECT_7	0x80000000
 
-/* SDRAM */
-#ifdef CONFIG_DRAM_BASE
-#define AT91_SDRAM_BASE		CONFIG_DRAM_BASE
-#else
-#define AT91_SDRAM_BASE		AT91_CHIPSELECT_1
-#endif
-
 /* Clocks */
 #define AT91_SLOW_CLOCK		32768		/* slow clock */
 
diff -druN linux-2.6.39-libre/arch/arm/mach-at91/include/mach/memory.h linux-3.0-rc7-libre/arch/arm/mach-at91/include/mach/memory.h
--- linux-2.6.39-libre/arch/arm/mach-at91/include/mach/memory.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-at91/include/mach/memory.h	2011-07-11 19:51:52.000000000 -0400
@@ -23,6 +23,4 @@
 
 #include <mach/hardware.h>
 
-#define PLAT_PHYS_OFFSET	(AT91_SDRAM_BASE)
-
 #endif
diff -druN linux-2.6.39-libre/arch/arm/mach-at91/include/mach/stamp9g20.h linux-3.0-rc7-libre/arch/arm/mach-at91/include/mach/stamp9g20.h
--- linux-2.6.39-libre/arch/arm/mach-at91/include/mach/stamp9g20.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-at91/include/mach/stamp9g20.h	2011-07-11 19:51:52.000000000 -0400
@@ -1,7 +1,7 @@
 #ifndef __MACH_STAMP9G20_H
 #define __MACH_STAMP9G20_H
 
-void stamp9g20_map_io(void);
+void stamp9g20_init_early(void);
 void stamp9g20_board_init(void);
 
 #endif
diff -druN linux-2.6.39-libre/arch/arm/mach-at91/include/mach/system_rev.h linux-3.0-rc7-libre/arch/arm/mach-at91/include/mach/system_rev.h
--- linux-2.6.39-libre/arch/arm/mach-at91/include/mach/system_rev.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/arm/mach-at91/include/mach/system_rev.h	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2011 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
+ *
+ * Under GPLv2 only
+ */
+
+#ifndef __ARCH_SYSTEM_REV_H__
+#define __ARCH_SYSTEM_REV_H__
+
+/*
+ * board revision encoding
+ * mach specific
+ * the 16-31 bit are reserved for at91 generic information
+ *
+ * bit 31:
+ *	0 => nand 8 bit
+ *	1 => nand 16 bit
+ */
+#define BOARD_HAVE_NAND_16BIT	(1 << 31)
+static inline int board_have_nand_16bit(void)
+{
+	return system_rev & BOARD_HAVE_NAND_16BIT;
+}
+
+#endif /* __ARCH_SYSTEM_REV_H__ */
diff -druN linux-2.6.39-libre/arch/arm/mach-at91/include/mach/timex.h linux-3.0-rc7-libre/arch/arm/mach-at91/include/mach/timex.h
--- linux-2.6.39-libre/arch/arm/mach-at91/include/mach/timex.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-at91/include/mach/timex.h	2011-07-11 19:51:52.000000000 -0400
@@ -82,11 +82,6 @@
 #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 -druN linux-2.6.39-libre/arch/arm/mach-at91/Kconfig linux-3.0-rc7-libre/arch/arm/mach-at91/Kconfig
--- linux-2.6.39-libre/arch/arm/mach-at91/Kconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-at91/Kconfig	2011-07-11 19:51:52.000000000 -0400
@@ -3,9 +3,6 @@
 config HAVE_AT91_DATAFLASH_CARD
 	bool
 
-config HAVE_NAND_ATMEL_BUSWIDTH_16
-	bool
-
 config HAVE_AT91_USART3
 	bool
 
@@ -85,11 +82,6 @@
 	select HAVE_FB_ATMEL
 	select HAVE_NET_MACB
 
-config ARCH_AT572D940HF
-	bool "AT572D940HF"
-	select CPU_ARM926T
-	select GENERIC_CLOCKEVENTS
-
 config ARCH_AT91X40
 	bool "AT91x40"
 	select ARCH_USES_GETTIMEOFFSET
@@ -209,7 +201,6 @@
 config MACH_AT91SAM9260EK
 	bool "Atmel AT91SAM9260-EK / AT91SAM9XE Evaluation Kit"
 	select HAVE_AT91_DATAFLASH_CARD
-	select HAVE_NAND_ATMEL_BUSWIDTH_16
 	help
 	  Select this if you are using Atmel's AT91SAM9260-EK or AT91SAM9XE Evaluation Kit
 	  <http://www.atmel.com/dyn/products/tools_card.asp?tool_id=3933>
@@ -270,7 +261,6 @@
 config MACH_AT91SAM9261EK
 	bool "Atmel AT91SAM9261-EK Evaluation Kit"
 	select HAVE_AT91_DATAFLASH_CARD
-	select HAVE_NAND_ATMEL_BUSWIDTH_16
 	help
 	  Select this if you are using Atmel's AT91SAM9261-EK Evaluation Kit.
 	  <http://www.atmel.com/dyn/products/tools_card.asp?tool_id=3820>
@@ -286,7 +276,6 @@
 config MACH_AT91SAM9G10EK
 	bool "Atmel AT91SAM9G10-EK Evaluation Kit"
 	select HAVE_AT91_DATAFLASH_CARD
-	select HAVE_NAND_ATMEL_BUSWIDTH_16
 	help
 	  Select this if you are using Atmel's AT91SAM9G10-EK Evaluation Kit.
 	  <http://www.atmel.com/dyn/products/tools_card.asp?tool_id=4588>
@@ -302,7 +291,6 @@
 config MACH_AT91SAM9263EK
 	bool "Atmel AT91SAM9263-EK Evaluation Kit"
 	select HAVE_AT91_DATAFLASH_CARD
-	select HAVE_NAND_ATMEL_BUSWIDTH_16
 	help
 	  Select this if you are using Atmel's AT91SAM9263-EK Evaluation Kit.
 	  <http://www.atmel.com/dyn/products/tools_card.asp?tool_id=4057>
@@ -343,7 +331,6 @@
 config MACH_AT91SAM9G20EK
 	bool "Atmel AT91SAM9G20-EK Evaluation Kit"
 	select HAVE_AT91_DATAFLASH_CARD
-	select HAVE_NAND_ATMEL_BUSWIDTH_16
 	help
 	  Select this if you are using Atmel's AT91SAM9G20-EK Evaluation Kit
 	  that embeds only one SD/MMC slot.
@@ -351,7 +338,6 @@
 config MACH_AT91SAM9G20EK_2MMC
 	depends on MACH_AT91SAM9G20EK
 	bool "Atmel AT91SAM9G20-EK Evaluation Kit with 2 SD/MMC Slots"
-	select HAVE_NAND_ATMEL_BUSWIDTH_16
 	help
 	  Select this if you are using an Atmel AT91SAM9G20-EK Evaluation Kit
 	  with 2 SD/MMC Slots. This is the case for AT91SAM9G20-EK rev. C and
@@ -416,7 +402,6 @@
 
 config MACH_AT91SAM9M10G45EK
 	bool "Atmel AT91SAM9M10G45-EK Evaluation Kits"
-	select HAVE_NAND_ATMEL_BUSWIDTH_16
 	help
 	  Select this if you are using Atmel's AT91SAM9G45-EKES Evaluation Kit.
 	  "ES" at the end of the name means that this board is an
@@ -433,7 +418,6 @@
 config MACH_AT91CAP9ADK
 	bool "Atmel AT91CAP9A-DK Evaluation Kit"
 	select HAVE_AT91_DATAFLASH_CARD
-	select HAVE_NAND_ATMEL_BUSWIDTH_16
 	help
 	  Select this if you are using Atmel's AT91CAP9A-DK Evaluation Kit.
 	  <http://www.atmel.com/dyn/products/tools_card.asp?tool_id=4138>
@@ -442,23 +426,6 @@
 
 # ----------------------------------------------------------
 
-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
 
 comment "AT91X40 Board Type"
@@ -483,13 +450,6 @@
 	help
 	  Enable support for the DataFlash card.
 
-config MTD_NAND_ATMEL_BUSWIDTH_16
-	bool "Enable 16-bit data bus interface to NAND flash"
-	depends on HAVE_NAND_ATMEL_BUSWIDTH_16
-	help
-	  On AT91SAM926x boards both types of NAND flash can be present
-	  (8 and 16 bit data bus width).
-
 # ----------------------------------------------------------
 
 comment "AT91 Feature Selections"
diff -druN linux-2.6.39-libre/arch/arm/mach-at91/Makefile linux-3.0-rc7-libre/arch/arm/mach-at91/Makefile
--- linux-2.6.39-libre/arch/arm/mach-at91/Makefile	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-at91/Makefile	2011-07-11 19:51:52.000000000 -0400
@@ -19,7 +19,6 @@
 obj-$(CONFIG_ARCH_AT91SAM9G20)	+= at91sam9260.o at91sam926x_time.o at91sam9260_devices.o sam9_smc.o at91sam9_alt_reset.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
@@ -78,9 +77,6 @@
 # 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 -druN linux-2.6.39-libre/arch/arm/mach-bcmring/arch.c linux-3.0-rc7-libre/arch/arm/mach-bcmring/arch.c
--- linux-2.6.39-libre/arch/arm/mach-bcmring/arch.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-bcmring/arch.c	2011-07-11 19:51:52.000000000 -0400
@@ -169,6 +169,7 @@
 	/* Maintainer: Broadcom Corporation */
 	.fixup = bcmring_fixup,
 	.map_io = bcmring_map_io,
+	.init_early = bcmring_init_early,
 	.init_irq = bcmring_init_irq,
 	.timer = &bcmring_timer,
 	.init_machine = bcmring_init_machine
diff -druN linux-2.6.39-libre/arch/arm/mach-bcmring/core.c linux-3.0-rc7-libre/arch/arm/mach-bcmring/core.c
--- linux-2.6.39-libre/arch/arm/mach-bcmring/core.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-bcmring/core.c	2011-07-11 19:51:52.000000000 -0400
@@ -28,8 +28,6 @@
 #include <linux/sysdev.h>
 #include <linux/interrupt.h>
 #include <linux/amba/bus.h>
-#include <linux/clocksource.h>
-#include <linux/clockchips.h>
 #include <linux/clkdev.h>
 
 #include <mach/csp/mm_addr.h>
@@ -37,6 +35,7 @@
 #include <linux/io.h>
 #include <asm/irq.h>
 #include <asm/hardware/arm_timer.h>
+#include <asm/hardware/timer-sp.h>
 #include <asm/mach-types.h>
 
 #include <asm/mach/arch.h>
@@ -97,6 +96,35 @@
 	.mode = CLK_MODE_XTAL,
 };
 
+/* Timer 0 - 25 MHz, Timer3 at bus clock rate, typically  150-166 MHz */
+#if defined(CONFIG_ARCH_FPGA11107)
+/* fpga cpu/bus are currently 30 times slower so scale frequency as well to */
+/* slow down Linux's sense of time */
+#define TIMER0_FREQUENCY_MHZ  (tmrHw_LOW_FREQUENCY_MHZ * 30)
+#define TIMER1_FREQUENCY_MHZ  (tmrHw_LOW_FREQUENCY_MHZ * 30)
+#define TIMER3_FREQUENCY_MHZ  (tmrHw_HIGH_FREQUENCY_MHZ * 30)
+#define TIMER3_FREQUENCY_KHZ   (tmrHw_HIGH_FREQUENCY_HZ / 1000 * 30)
+#else
+#define TIMER0_FREQUENCY_MHZ  tmrHw_LOW_FREQUENCY_MHZ
+#define TIMER1_FREQUENCY_MHZ  tmrHw_LOW_FREQUENCY_MHZ
+#define TIMER3_FREQUENCY_MHZ  tmrHw_HIGH_FREQUENCY_MHZ
+#define TIMER3_FREQUENCY_KHZ  (tmrHw_HIGH_FREQUENCY_HZ / 1000)
+#endif
+
+static struct clk sp804_timer012_clk = {
+	.name = "sp804-timer-0,1,2",
+	.type = CLK_TYPE_PRIMARY,
+	.mode = CLK_MODE_XTAL,
+	.rate_hz = TIMER1_FREQUENCY_MHZ * 1000000,
+};
+
+static struct clk sp804_timer3_clk = {
+	.name = "sp804-timer-3",
+	.type = CLK_TYPE_PRIMARY,
+	.mode = CLK_MODE_XTAL,
+	.rate_hz = TIMER3_FREQUENCY_KHZ * 1000,
+};
+
 static struct clk_lookup lookups[] = {
 	{			/* Bus clock */
 		.con_id = "apb_pclk",
@@ -107,6 +135,18 @@
 	}, {			/* UART1 */
 		.dev_id = "uartb",
 		.clk = &uart_clk,
+	}, {			/* SP804 timer 0 */
+		.dev_id = "sp804",
+		.con_id = "timer0",
+		.clk = &sp804_timer012_clk,
+	}, {			/* SP804 timer 1 */
+		.dev_id = "sp804",
+		.con_id = "timer1",
+		.clk = &sp804_timer012_clk,
+	}, {			/* SP804 timer 3 */
+		.dev_id = "sp804",
+		.con_id = "timer3",
+		.clk = &sp804_timer3_clk,
 	}
 };
 
@@ -151,8 +191,6 @@
 
 	chipcHw_busInterfaceClockEnable(bus_clock);
 
-	clkdev_add_table(lookups, ARRAY_SIZE(lookups));
-
 	for (i = 0; i < ARRAY_SIZE(amba_devs); i++) {
 		struct amba_device *d = amba_devs[i];
 		amba_device_register(d, &iomem_resource);
@@ -162,170 +200,18 @@
 /*
  * Where is the timer (VA)?
  */
-#define TIMER0_VA_BASE		 MM_IO_BASE_TMR
-#define TIMER1_VA_BASE		(MM_IO_BASE_TMR + 0x20)
-#define TIMER2_VA_BASE		(MM_IO_BASE_TMR + 0x40)
-#define TIMER3_VA_BASE          (MM_IO_BASE_TMR + 0x60)
-
-/* Timer 0 - 25 MHz, Timer3 at bus clock rate, typically  150-166 MHz */
-#if defined(CONFIG_ARCH_FPGA11107)
-/* fpga cpu/bus are currently 30 times slower so scale frequency as well to */
-/* slow down Linux's sense of time */
-#define TIMER0_FREQUENCY_MHZ  (tmrHw_LOW_FREQUENCY_MHZ * 30)
-#define TIMER1_FREQUENCY_MHZ  (tmrHw_LOW_FREQUENCY_MHZ * 30)
-#define TIMER3_FREQUENCY_MHZ  (tmrHw_HIGH_FREQUENCY_MHZ * 30)
-#define TIMER3_FREQUENCY_KHZ   (tmrHw_HIGH_FREQUENCY_HZ / 1000 * 30)
-#else
-#define TIMER0_FREQUENCY_MHZ  tmrHw_LOW_FREQUENCY_MHZ
-#define TIMER1_FREQUENCY_MHZ  tmrHw_LOW_FREQUENCY_MHZ
-#define TIMER3_FREQUENCY_MHZ  tmrHw_HIGH_FREQUENCY_MHZ
-#define TIMER3_FREQUENCY_KHZ  (tmrHw_HIGH_FREQUENCY_HZ / 1000)
-#endif
-
-#define TICKS_PER_uSEC     TIMER0_FREQUENCY_MHZ
-
-/*
- *  These are useconds NOT ticks.
- *
- */
-#define mSEC_1                          1000
-#define mSEC_5                          (mSEC_1 * 5)
-#define mSEC_10                         (mSEC_1 * 10)
-#define mSEC_25                         (mSEC_1 * 25)
-#define SEC_1                           (mSEC_1 * 1000)
-
-/*
- * How long is the timer interval?
- */
-#define TIMER_INTERVAL	(TICKS_PER_uSEC * mSEC_10)
-#if TIMER_INTERVAL >= 0x100000
-#define TIMER_RELOAD	(TIMER_INTERVAL >> 8)
-#define TIMER_DIVISOR	(TIMER_CTRL_DIV256)
-#define TICKS2USECS(x)	(256 * (x) / TICKS_PER_uSEC)
-#elif TIMER_INTERVAL >= 0x10000
-#define TIMER_RELOAD	(TIMER_INTERVAL >> 4)	/* Divide by 16 */
-#define TIMER_DIVISOR	(TIMER_CTRL_DIV16)
-#define TICKS2USECS(x)	(16 * (x) / TICKS_PER_uSEC)
-#else
-#define TIMER_RELOAD	(TIMER_INTERVAL)
-#define TIMER_DIVISOR	(TIMER_CTRL_DIV1)
-#define TICKS2USECS(x)	((x) / TICKS_PER_uSEC)
-#endif
-
-static void timer_set_mode(enum clock_event_mode mode,
-			   struct clock_event_device *clk)
-{
-	unsigned long ctrl;
-
-	switch (mode) {
-	case CLOCK_EVT_MODE_PERIODIC:
-		writel(TIMER_RELOAD, TIMER0_VA_BASE + TIMER_LOAD);
-
-		ctrl = TIMER_CTRL_PERIODIC;
-		ctrl |=
-		    TIMER_DIVISOR | TIMER_CTRL_32BIT | TIMER_CTRL_IE |
-		    TIMER_CTRL_ENABLE;
-		break;
-	case CLOCK_EVT_MODE_ONESHOT:
-		/* period set, and timer enabled in 'next_event' hook */
-		ctrl = TIMER_CTRL_ONESHOT;
-		ctrl |= TIMER_DIVISOR | TIMER_CTRL_32BIT | TIMER_CTRL_IE;
-		break;
-	case CLOCK_EVT_MODE_UNUSED:
-	case CLOCK_EVT_MODE_SHUTDOWN:
-	default:
-		ctrl = 0;
-	}
-
-	writel(ctrl, TIMER0_VA_BASE + TIMER_CTRL);
-}
-
-static int timer_set_next_event(unsigned long evt,
-				struct clock_event_device *unused)
-{
-	unsigned long ctrl = readl(TIMER0_VA_BASE + TIMER_CTRL);
-
-	writel(evt, TIMER0_VA_BASE + TIMER_LOAD);
-	writel(ctrl | TIMER_CTRL_ENABLE, TIMER0_VA_BASE + TIMER_CTRL);
-
-	return 0;
-}
-
-static struct clock_event_device timer0_clockevent = {
-	.name = "timer0",
-	.shift = 32,
-	.features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
-	.set_mode = timer_set_mode,
-	.set_next_event = timer_set_next_event,
-};
-
-/*
- * IRQ handler for the timer
- */
-static irqreturn_t bcmring_timer_interrupt(int irq, void *dev_id)
-{
-	struct clock_event_device *evt = &timer0_clockevent;
-
-	writel(1, TIMER0_VA_BASE + TIMER_INTCLR);
-
-	evt->event_handler(evt);
-
-	return IRQ_HANDLED;
-}
-
-static struct irqaction bcmring_timer_irq = {
-	.name = "bcmring Timer Tick",
-	.flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
-	.handler = bcmring_timer_interrupt,
-};
-
-static cycle_t bcmring_get_cycles_timer1(struct clocksource *cs)
-{
-	return ~readl(TIMER1_VA_BASE + TIMER_VALUE);
-}
-
-static cycle_t bcmring_get_cycles_timer3(struct clocksource *cs)
-{
-	return ~readl(TIMER3_VA_BASE + TIMER_VALUE);
-}
-
-static struct clocksource clocksource_bcmring_timer1 = {
-	.name = "timer1",
-	.rating = 200,
-	.read = bcmring_get_cycles_timer1,
-	.mask = CLOCKSOURCE_MASK(32),
-	.flags = CLOCK_SOURCE_IS_CONTINUOUS,
-};
-
-static struct clocksource clocksource_bcmring_timer3 = {
-	.name = "timer3",
-	.rating = 100,
-	.read = bcmring_get_cycles_timer3,
-	.mask = CLOCKSOURCE_MASK(32),
-	.flags = CLOCK_SOURCE_IS_CONTINUOUS,
-};
+#define TIMER0_VA_BASE		((void __iomem *)MM_IO_BASE_TMR)
+#define TIMER1_VA_BASE		((void __iomem *)(MM_IO_BASE_TMR + 0x20))
+#define TIMER2_VA_BASE		((void __iomem *)(MM_IO_BASE_TMR + 0x40))
+#define TIMER3_VA_BASE          ((void __iomem *)(MM_IO_BASE_TMR + 0x60))
 
 static int __init bcmring_clocksource_init(void)
 {
 	/* setup timer1 as free-running clocksource */
-	writel(0, TIMER1_VA_BASE + TIMER_CTRL);
-	writel(0xffffffff, TIMER1_VA_BASE + TIMER_LOAD);
-	writel(0xffffffff, TIMER1_VA_BASE + TIMER_VALUE);
-	writel(TIMER_CTRL_32BIT | TIMER_CTRL_ENABLE | TIMER_CTRL_PERIODIC,
-	       TIMER1_VA_BASE + TIMER_CTRL);
-
-	clocksource_register_khz(&clocksource_bcmring_timer1,
-				 TIMER1_FREQUENCY_MHZ * 1000);
+	sp804_clocksource_init(TIMER1_VA_BASE, "timer1");
 
 	/* setup timer3 as free-running clocksource */
-	writel(0, TIMER3_VA_BASE + TIMER_CTRL);
-	writel(0xffffffff, TIMER3_VA_BASE + TIMER_LOAD);
-	writel(0xffffffff, TIMER3_VA_BASE + TIMER_VALUE);
-	writel(TIMER_CTRL_32BIT | TIMER_CTRL_ENABLE | TIMER_CTRL_PERIODIC,
-	       TIMER3_VA_BASE + TIMER_CTRL);
-
-	clocksource_register_khz(&clocksource_bcmring_timer3,
-				 TIMER3_FREQUENCY_KHZ);
+	sp804_clocksource_init(TIMER3_VA_BASE, "timer3");
 
 	return 0;
 }
@@ -347,21 +233,16 @@
 	/*
 	 * Make irqs happen for the system timer
 	 */
-	setup_irq(IRQ_TIMER0, &bcmring_timer_irq);
-
 	bcmring_clocksource_init();
 
-	timer0_clockevent.mult =
-	    div_sc(1000000, NSEC_PER_SEC, timer0_clockevent.shift);
-	timer0_clockevent.max_delta_ns =
-	    clockevent_delta2ns(0xffffffff, &timer0_clockevent);
-	timer0_clockevent.min_delta_ns =
-	    clockevent_delta2ns(0xf, &timer0_clockevent);
-
-	timer0_clockevent.cpumask = cpumask_of(0);
-	clockevents_register_device(&timer0_clockevent);
+	sp804_clockevents_register(TIMER0_VA_BASE, IRQ_TIMER0, "timer0");
 }
 
 struct sys_timer bcmring_timer = {
 	.init = bcmring_init_timer,
 };
+
+void __init bcmring_init_early(void)
+{
+	clkdev_add_table(lookups, ARRAY_SIZE(lookups));
+}
diff -druN linux-2.6.39-libre/arch/arm/mach-bcmring/core.h linux-3.0-rc7-libre/arch/arm/mach-bcmring/core.h
--- linux-2.6.39-libre/arch/arm/mach-bcmring/core.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-bcmring/core.h	2011-07-11 19:51:52.000000000 -0400
@@ -25,6 +25,7 @@
 void __init bcmring_amba_init(void);
 void __init bcmring_map_io(void);
 void __init bcmring_init_irq(void);
+void __init bcmring_init_early(void);
 
 extern struct sys_timer bcmring_timer;
 #endif
diff -druN linux-2.6.39-libre/arch/arm/mach-davinci/cpufreq.c linux-3.0-rc7-libre/arch/arm/mach-davinci/cpufreq.c
--- linux-2.6.39-libre/arch/arm/mach-davinci/cpufreq.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-davinci/cpufreq.c	2011-07-11 19:51:52.000000000 -0400
@@ -94,9 +94,7 @@
 	if (freqs.old == freqs.new)
 		return ret;
 
-	cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER,
-			dev_driver_string(cpufreq.dev),
-			"transition: %u --> %u\n", freqs.old, freqs.new);
+	dev_dbg(&cpufreq.dev, "transition: %u --> %u\n", freqs.old, freqs.new);
 
 	ret = cpufreq_frequency_table_target(policy, pdata->freq_table,
 						freqs.new, relation, &idx);
diff -druN linux-2.6.39-libre/arch/arm/mach-davinci/da850.c linux-3.0-rc7-libre/arch/arm/mach-davinci/da850.c
--- linux-2.6.39-libre/arch/arm/mach-davinci/da850.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-davinci/da850.c	2011-07-11 19:51:52.000000000 -0400
@@ -1055,7 +1055,7 @@
 	if (!pdata->cpupll_reg_base)
 		return -ENOMEM;
 
-	pdata->ddrpll_reg_base = ioremap(DA8XX_PLL1_BASE, SZ_4K);
+	pdata->ddrpll_reg_base = ioremap(DA850_PLL1_BASE, SZ_4K);
 	if (!pdata->ddrpll_reg_base) {
 		ret = -ENOMEM;
 		goto no_ddrpll_mem;
diff -druN linux-2.6.39-libre/arch/arm/mach-davinci/devices.c linux-3.0-rc7-libre/arch/arm/mach-davinci/devices.c
--- linux-2.6.39-libre/arch/arm/mach-davinci/devices.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-davinci/devices.c	2011-07-11 19:51:52.000000000 -0400
@@ -33,6 +33,9 @@
 #define DM365_MMCSD0_BASE	     0x01D11000
 #define DM365_MMCSD1_BASE	     0x01D00000
 
+/* System control register offsets */
+#define DM64XX_VDD3P3V_PWDN	0x48
+
 static struct resource i2c_resources[] = {
 	{
 		.start		= DAVINCI_I2C_BASE,
@@ -295,7 +298,7 @@
 
 /*-------------------------------------------------------------------------*/
 
-struct platform_device davinci_pcm_device = {
+static struct platform_device davinci_pcm_device = {
 	.name		= "davinci-pcm-audio",
 	.id		= -1,
 };
diff -druN linux-2.6.39-libre/arch/arm/mach-davinci/devices-da8xx.c linux-3.0-rc7-libre/arch/arm/mach-davinci/devices-da8xx.c
--- linux-2.6.39-libre/arch/arm/mach-davinci/devices-da8xx.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-davinci/devices-da8xx.c	2011-07-11 19:51:52.000000000 -0400
@@ -24,23 +24,25 @@
 #include "clock.h"
 
 #define DA8XX_TPCC_BASE			0x01c00000
-#define DA850_MMCSD1_BASE		0x01e1b000
-#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
+#define DA8XX_RTC_BASE			0x01c23000
+#define DA8XX_MMCSD0_BASE		0x01c40000
+#define DA8XX_SPI0_BASE			0x01c41000
+#define DA830_SPI1_BASE			0x01e12000
+#define DA8XX_LCD_CNTRL_BASE		0x01e13000
+#define DA850_MMCSD1_BASE		0x01e1b000
 #define DA8XX_EMAC_CPPI_PORT_BASE	0x01e20000
 #define DA8XX_EMAC_CPGMACSS_BASE	0x01e22000
 #define DA8XX_EMAC_CPGMAC_BASE		0x01e23000
 #define DA8XX_EMAC_MDIO_BASE		0x01e24000
-#define DA8XX_GPIO_BASE			0x01e26000
 #define DA8XX_I2C1_BASE			0x01e28000
-#define DA8XX_SPI0_BASE			0x01c41000
-#define DA830_SPI1_BASE			0x01e12000
+#define DA850_TPCC1_BASE		0x01e30000
+#define DA850_TPTC2_BASE		0x01e38000
 #define DA850_SPI1_BASE			0x01f0e000
+#define DA8XX_DDR2_CTL_BASE		0xb0000000
 
 #define DA8XX_EMAC_CTRL_REG_OFFSET	0x3000
 #define DA8XX_EMAC_MOD_REG_OFFSET	0x2000
@@ -492,7 +494,7 @@
 	.resource	= da850_mcasp_resources,
 };
 
-struct platform_device davinci_pcm_device = {
+static struct platform_device davinci_pcm_device = {
 	.name	= "davinci-pcm-audio",
 	.id	= -1,
 };
diff -druN linux-2.6.39-libre/arch/arm/mach-davinci/gpio.c linux-3.0-rc7-libre/arch/arm/mach-davinci/gpio.c
--- linux-2.6.39-libre/arch/arm/mach-davinci/gpio.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-davinci/gpio.c	2011-07-11 19:51:52.000000000 -0400
@@ -252,9 +252,11 @@
 static void
 gpio_irq_handler(unsigned irq, struct irq_desc *desc)
 {
-	struct davinci_gpio_regs __iomem *g = irq2regs(irq);
+	struct davinci_gpio_regs __iomem *g;
 	u32 mask = 0xffff;
 
+	g = (__force struct davinci_gpio_regs __iomem *) irq_desc_get_handler_data(desc);
+
 	/* we only care about one bank */
 	if (irq & 1)
 		mask <<= 16;
@@ -422,8 +424,7 @@
 
 		/* set up all irqs in this bank */
 		irq_set_chained_handler(bank_irq, gpio_irq_handler);
-		irq_set_chip_data(bank_irq, (__force void *)g);
-		irq_set_handler_data(bank_irq, (void *)irq);
+		irq_set_handler_data(bank_irq, (__force void *)g);
 
 		for (i = 0; i < 16 && gpio < ngpio; i++, irq++, gpio++) {
 			irq_set_chip(irq, &gpio_irqchip);
diff -druN linux-2.6.39-libre/arch/arm/mach-davinci/include/mach/da8xx.h linux-3.0-rc7-libre/arch/arm/mach-davinci/include/mach/da8xx.h
--- linux-2.6.39-libre/arch/arm/mach-davinci/include/mach/da8xx.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-davinci/include/mach/da8xx.h	2011-07-11 19:51:52.000000000 -0400
@@ -64,13 +64,9 @@
 #define DA8XX_TIMER64P1_BASE	0x01c21000
 #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
 
 void __init da830_init(void);
diff -druN linux-2.6.39-libre/arch/arm/mach-davinci/include/mach/hardware.h linux-3.0-rc7-libre/arch/arm/mach-davinci/include/mach/hardware.h
--- linux-2.6.39-libre/arch/arm/mach-davinci/include/mach/hardware.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-davinci/include/mach/hardware.h	2011-07-11 19:51:52.000000000 -0400
@@ -21,9 +21,6 @@
  */
 #define DAVINCI_SYSTEM_MODULE_BASE        0x01C40000
 
-/* System control register offsets */
-#define DM64XX_VDD3P3V_PWDN	0x48
-
 /*
  * I/O mapping
  */
diff -druN linux-2.6.39-libre/arch/arm/mach-davinci/include/mach/memory.h linux-3.0-rc7-libre/arch/arm/mach-davinci/include/mach/memory.h
--- linux-2.6.39-libre/arch/arm/mach-davinci/include/mach/memory.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-davinci/include/mach/memory.h	2011-07-11 19:51:52.000000000 -0400
@@ -41,27 +41,11 @@
  */
 #define CONSISTENT_DMA_SIZE (14<<20)
 
-#ifndef __ASSEMBLY__
 /*
  * Restrict DMA-able region to workaround silicon bug.  The bug
  * restricts buffers available for DMA to video hardware to be
  * below 128M
  */
-static inline void
-__arch_adjust_zones(unsigned long *size, unsigned long *holes)
-{
-	unsigned int sz = (128<<20) >> PAGE_SHIFT;
-
-	size[1] = size[0] - sz;
-	size[0] = sz;
-}
-
-#define arch_adjust_zones(zone_size, holes) \
-        if ((meminfo.bank[0].size >> 20) > 128) __arch_adjust_zones(zone_size, holes)
-
-#define ISA_DMA_THRESHOLD	(PHYS_OFFSET + (128<<20) - 1)
-#define MAX_DMA_ADDRESS		(PAGE_OFFSET + (128<<20))
-
-#endif
+#define ARM_DMA_ZONE_SIZE	SZ_128M
 
 #endif /* __ASM_ARCH_MEMORY_H */
diff -druN linux-2.6.39-libre/arch/arm/mach-davinci/include/mach/uncompress.h linux-3.0-rc7-libre/arch/arm/mach-davinci/include/mach/uncompress.h
--- linux-2.6.39-libre/arch/arm/mach-davinci/include/mach/uncompress.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-davinci/include/mach/uncompress.h	2011-07-11 19:51:52.000000000 -0400
@@ -25,8 +25,7 @@
 
 #include <mach/serial.h>
 
-static u32 *uart;
-static u32 *uart_info = (u32 *)(DAVINCI_UART_INFO);
+u32 *uart;
 
 /* PORT_16C550A, in polled non-fifo mode */
 static void putc(char c)
@@ -44,6 +43,8 @@
 
 static inline void set_uart_info(u32 phys, void * __iomem virt)
 {
+	u32 *uart_info = (u32 *)(DAVINCI_UART_INFO);
+
 	uart = (u32 *)phys;
 	uart_info[0] = phys;
 	uart_info[1] = (u32)virt;
diff -druN linux-2.6.39-libre/arch/arm/mach-davinci/irq.c linux-3.0-rc7-libre/arch/arm/mach-davinci/irq.c
--- linux-2.6.39-libre/arch/arm/mach-davinci/irq.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-davinci/irq.c	2011-07-11 19:51:52.000000000 -0400
@@ -29,8 +29,6 @@
 #include <mach/common.h>
 #include <asm/mach/irq.h>
 
-#define IRQ_BIT(irq)		((irq) & 0x1f)
-
 #define FIQ_REG0_OFFSET		0x0000
 #define FIQ_REG1_OFFSET		0x0004
 #define IRQ_REG0_OFFSET		0x0008
@@ -42,78 +40,33 @@
 #define IRQ_INTPRI0_REG_OFFSET	0x0030
 #define IRQ_INTPRI7_REG_OFFSET	0x004C
 
-static inline unsigned int davinci_irq_readl(int offset)
-{
-	return __raw_readl(davinci_intc_base + offset);
-}
-
 static inline void davinci_irq_writel(unsigned long value, int offset)
 {
 	__raw_writel(value, davinci_intc_base + offset);
 }
 
-/* Disable interrupt */
-static void davinci_mask_irq(struct irq_data *d)
-{
-	unsigned int mask;
-	u32 l;
-
-	mask = 1 << IRQ_BIT(d->irq);
-
-	if (d->irq > 31) {
-		l = davinci_irq_readl(IRQ_ENT_REG1_OFFSET);
-		l &= ~mask;
-		davinci_irq_writel(l, IRQ_ENT_REG1_OFFSET);
-	} else {
-		l = davinci_irq_readl(IRQ_ENT_REG0_OFFSET);
-		l &= ~mask;
-		davinci_irq_writel(l, IRQ_ENT_REG0_OFFSET);
-	}
-}
-
-/* Enable interrupt */
-static void davinci_unmask_irq(struct irq_data *d)
-{
-	unsigned int mask;
-	u32 l;
-
-	mask = 1 << IRQ_BIT(d->irq);
-
-	if (d->irq > 31) {
-		l = davinci_irq_readl(IRQ_ENT_REG1_OFFSET);
-		l |= mask;
-		davinci_irq_writel(l, IRQ_ENT_REG1_OFFSET);
-	} else {
-		l = davinci_irq_readl(IRQ_ENT_REG0_OFFSET);
-		l |= mask;
-		davinci_irq_writel(l, IRQ_ENT_REG0_OFFSET);
-	}
-}
-
-/* EOI interrupt */
-static void davinci_ack_irq(struct irq_data *d)
+static __init void
+davinci_alloc_gc(void __iomem *base, unsigned int irq_start, unsigned int num)
 {
-	unsigned int mask;
+	struct irq_chip_generic *gc;
+	struct irq_chip_type *ct;
 
-	mask = 1 << IRQ_BIT(d->irq);
+	gc = irq_alloc_generic_chip("AINTC", 1, irq_start, base, handle_edge_irq);
+	ct = gc->chip_types;
+	ct->chip.irq_ack = irq_gc_ack;
+	ct->chip.irq_mask = irq_gc_mask_clr_bit;
+	ct->chip.irq_unmask = irq_gc_mask_set_bit;
 
-	if (d->irq > 31)
-		davinci_irq_writel(mask, IRQ_REG1_OFFSET);
-	else
-		davinci_irq_writel(mask, IRQ_REG0_OFFSET);
+	ct->regs.ack = IRQ_REG0_OFFSET;
+	ct->regs.mask = IRQ_ENT_REG0_OFFSET;
+	irq_setup_generic_chip(gc, IRQ_MSK(num), IRQ_GC_INIT_MASK_CACHE,
+			       IRQ_NOREQUEST | IRQ_NOPROBE, 0);
 }
 
-static struct irq_chip davinci_irq_chip_0 = {
-	.name		= "AINTC",
-	.irq_ack	= davinci_ack_irq,
-	.irq_mask	= davinci_mask_irq,
-	.irq_unmask	= davinci_unmask_irq,
-};
-
 /* ARM Interrupt Controller Initialization */
 void __init davinci_irq_init(void)
 {
-	unsigned i;
+	unsigned i, j;
 	const u8 *davinci_def_priorities = davinci_soc_info.intc_irq_prios;
 
 	davinci_intc_type = DAVINCI_INTC_TYPE_AINTC;
@@ -144,7 +97,6 @@
 	davinci_irq_writel(~0x0, IRQ_REG1_OFFSET);
 
 	for (i = IRQ_INTPRI0_REG_OFFSET; i <= IRQ_INTPRI7_REG_OFFSET; i += 4) {
-		unsigned	j;
 		u32		pri;
 
 		for (j = 0, pri = 0; j < 32; j += 4, davinci_def_priorities++)
@@ -152,13 +104,8 @@
 		davinci_irq_writel(pri, i);
 	}
 
-	/* set up genirq dispatch for ARM INTC */
-	for (i = 0; i < davinci_soc_info.intc_irq_num; i++) {
-		irq_set_chip(i, &davinci_irq_chip_0);
-		set_irq_flags(i, IRQF_VALID | IRQF_PROBE);
-		if (i != IRQ_TINT1_TINT34)
-			irq_set_handler(i, handle_edge_irq);
-		else
-			irq_set_handler(i, handle_level_irq);
-	}
+	for (i = 0, j = 0; i < davinci_soc_info.intc_irq_num; i += 32, j += 0x04)
+		davinci_alloc_gc(davinci_intc_base + j, i, 32);
+
+	irq_set_handler(IRQ_TINT1_TINT34, handle_level_irq);
 }
diff -druN linux-2.6.39-libre/arch/arm/mach-dove/common.c linux-3.0-rc7-libre/arch/arm/mach-dove/common.c
--- linux-2.6.39-libre/arch/arm/mach-dove/common.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-dove/common.c	2011-07-11 19:51:52.000000000 -0400
@@ -16,10 +16,8 @@
 #include <linux/serial_8250.h>
 #include <linux/clk.h>
 #include <linux/mbus.h>
-#include <linux/mv643xx_eth.h>
-#include <linux/mv643xx_i2c.h>
 #include <linux/ata_platform.h>
-#include <linux/spi/orion_spi.h>
+#include <linux/serial_8250.h>
 #include <linux/gpio.h>
 #include <asm/page.h>
 #include <asm/setup.h>
@@ -32,11 +30,12 @@
 #include <mach/bridge-regs.h>
 #include <asm/mach/arch.h>
 #include <linux/irq.h>
-#include <plat/mv_xor.h>
-#include <plat/ehci-orion.h>
 #include <plat/time.h>
+#include <plat/common.h>
 #include "common.h"
 
+static int get_tclk(void);
+
 /*****************************************************************************
  * I/O Address Mapping
  ****************************************************************************/
@@ -70,463 +69,106 @@
 }
 
 /*****************************************************************************
- * EHCI
- ****************************************************************************/
-static struct orion_ehci_data dove_ehci_data = {
-	.dram		= &dove_mbus_dram_info,
-	.phy_version	= EHCI_PHY_NA,
-};
-
-static u64 ehci_dmamask = DMA_BIT_MASK(32);
-
-/*****************************************************************************
  * EHCI0
  ****************************************************************************/
-static struct resource dove_ehci0_resources[] = {
-	{
-		.start	= DOVE_USB0_PHYS_BASE,
-		.end	= DOVE_USB0_PHYS_BASE + SZ_4K - 1,
-		.flags	= IORESOURCE_MEM,
-	}, {
-		.start	= IRQ_DOVE_USB0,
-		.end	= IRQ_DOVE_USB0,
-		.flags	= IORESOURCE_IRQ,
-	},
-};
-
-static struct platform_device dove_ehci0 = {
-	.name		= "orion-ehci",
-	.id		= 0,
-	.dev		= {
-		.dma_mask		= &ehci_dmamask,
-		.coherent_dma_mask	= DMA_BIT_MASK(32),
-		.platform_data		= &dove_ehci_data,
-	},
-	.resource	= dove_ehci0_resources,
-	.num_resources	= ARRAY_SIZE(dove_ehci0_resources),
-};
-
 void __init dove_ehci0_init(void)
 {
-	platform_device_register(&dove_ehci0);
+	orion_ehci_init(&dove_mbus_dram_info,
+			DOVE_USB0_PHYS_BASE, IRQ_DOVE_USB0);
 }
 
 /*****************************************************************************
  * EHCI1
  ****************************************************************************/
-static struct resource dove_ehci1_resources[] = {
-	{
-		.start	= DOVE_USB1_PHYS_BASE,
-		.end	= DOVE_USB1_PHYS_BASE + SZ_4K - 1,
-		.flags	= IORESOURCE_MEM,
-	}, {
-		.start	= IRQ_DOVE_USB1,
-		.end	= IRQ_DOVE_USB1,
-		.flags	= IORESOURCE_IRQ,
-	},
-};
-
-static struct platform_device dove_ehci1 = {
-	.name		= "orion-ehci",
-	.id		= 1,
-	.dev		= {
-		.dma_mask		= &ehci_dmamask,
-		.coherent_dma_mask	= DMA_BIT_MASK(32),
-		.platform_data		= &dove_ehci_data,
-	},
-	.resource	= dove_ehci1_resources,
-	.num_resources	= ARRAY_SIZE(dove_ehci1_resources),
-};
-
 void __init dove_ehci1_init(void)
 {
-	platform_device_register(&dove_ehci1);
+	orion_ehci_1_init(&dove_mbus_dram_info,
+			  DOVE_USB1_PHYS_BASE, IRQ_DOVE_USB1);
 }
 
 /*****************************************************************************
  * GE00
  ****************************************************************************/
-struct mv643xx_eth_shared_platform_data dove_ge00_shared_data = {
-	.t_clk		= 0,
-	.dram		= &dove_mbus_dram_info,
-};
-
-static struct resource dove_ge00_shared_resources[] = {
-	{
-		.name	= "ge00 base",
-		.start	= DOVE_GE00_PHYS_BASE + 0x2000,
-		.end	= DOVE_GE00_PHYS_BASE + SZ_16K - 1,
-		.flags	= IORESOURCE_MEM,
-	},
-};
-
-static struct platform_device dove_ge00_shared = {
-	.name		= MV643XX_ETH_SHARED_NAME,
-	.id		= 0,
-	.dev		= {
-		.platform_data	= &dove_ge00_shared_data,
-	},
-	.num_resources	= 1,
-	.resource	= dove_ge00_shared_resources,
-};
-
-static struct resource dove_ge00_resources[] = {
-	{
-		.name	= "ge00 irq",
-		.start	= IRQ_DOVE_GE00_SUM,
-		.end	= IRQ_DOVE_GE00_SUM,
-		.flags	= IORESOURCE_IRQ,
-	},
-};
-
-static struct platform_device dove_ge00 = {
-	.name		= MV643XX_ETH_NAME,
-	.id		= 0,
-	.num_resources	= 1,
-	.resource	= dove_ge00_resources,
-	.dev		= {
-		.coherent_dma_mask	= 0xffffffff,
-	},
-};
-
 void __init dove_ge00_init(struct mv643xx_eth_platform_data *eth_data)
 {
-	eth_data->shared = &dove_ge00_shared;
-	dove_ge00.dev.platform_data = eth_data;
-
-	platform_device_register(&dove_ge00_shared);
-	platform_device_register(&dove_ge00);
+	orion_ge00_init(eth_data, &dove_mbus_dram_info,
+			DOVE_GE00_PHYS_BASE, IRQ_DOVE_GE00_SUM,
+			0, get_tclk());
 }
 
 /*****************************************************************************
  * SoC RTC
  ****************************************************************************/
-static struct resource dove_rtc_resource[] = {
-	{
-		.start	= DOVE_RTC_PHYS_BASE,
-		.end	= DOVE_RTC_PHYS_BASE + 32 - 1,
-		.flags	= IORESOURCE_MEM,
-	}, {
-		.start	= IRQ_DOVE_RTC,
-		.flags	= IORESOURCE_IRQ,
-	}
-};
-
 void __init dove_rtc_init(void)
 {
-	platform_device_register_simple("rtc-mv", -1, dove_rtc_resource, 2);
+	orion_rtc_init(DOVE_RTC_PHYS_BASE, IRQ_DOVE_RTC);
 }
 
 /*****************************************************************************
  * SATA
  ****************************************************************************/
-static struct resource dove_sata_resources[] = {
-	{
-		.name	= "sata base",
-		.start	= DOVE_SATA_PHYS_BASE,
-		.end	= DOVE_SATA_PHYS_BASE + 0x5000 - 1,
-		.flags	= IORESOURCE_MEM,
-	}, {
-		.name	= "sata irq",
-		.start	= IRQ_DOVE_SATA,
-		.end	= IRQ_DOVE_SATA,
-		.flags	= IORESOURCE_IRQ,
-	},
-};
-
-static struct platform_device dove_sata = {
-	.name		= "sata_mv",
-	.id		= 0,
-	.dev		= {
-		.coherent_dma_mask	= DMA_BIT_MASK(32),
-	},
-	.num_resources	= ARRAY_SIZE(dove_sata_resources),
-	.resource	= dove_sata_resources,
-};
-
 void __init dove_sata_init(struct mv_sata_platform_data *sata_data)
 {
-	sata_data->dram = &dove_mbus_dram_info;
-	dove_sata.dev.platform_data = sata_data;
-	platform_device_register(&dove_sata);
+	orion_sata_init(sata_data, &dove_mbus_dram_info,
+			DOVE_SATA_PHYS_BASE, IRQ_DOVE_SATA);
+
 }
 
 /*****************************************************************************
  * UART0
  ****************************************************************************/
-static struct plat_serial8250_port dove_uart0_data[] = {
-	{
-		.mapbase	= DOVE_UART0_PHYS_BASE,
-		.membase	= (char *)DOVE_UART0_VIRT_BASE,
-		.irq		= IRQ_DOVE_UART_0,
-		.flags		= UPF_SKIP_TEST | UPF_BOOT_AUTOCONF,
-		.iotype		= UPIO_MEM,
-		.regshift	= 2,
-		.uartclk	= 0,
-	}, {
-	},
-};
-
-static struct resource dove_uart0_resources[] = {
-	{
-		.start		= DOVE_UART0_PHYS_BASE,
-		.end		= DOVE_UART0_PHYS_BASE + SZ_256 - 1,
-		.flags		= IORESOURCE_MEM,
-	}, {
-		.start		= IRQ_DOVE_UART_0,
-		.end		= IRQ_DOVE_UART_0,
-		.flags		= IORESOURCE_IRQ,
-	},
-};
-
-static struct platform_device dove_uart0 = {
-	.name			= "serial8250",
-	.id			= 0,
-	.dev			= {
-		.platform_data	= dove_uart0_data,
-	},
-	.resource		= dove_uart0_resources,
-	.num_resources		= ARRAY_SIZE(dove_uart0_resources),
-};
-
 void __init dove_uart0_init(void)
 {
-	platform_device_register(&dove_uart0);
+	orion_uart0_init(DOVE_UART0_VIRT_BASE, DOVE_UART0_PHYS_BASE,
+			 IRQ_DOVE_UART_0, get_tclk());
 }
 
 /*****************************************************************************
  * UART1
  ****************************************************************************/
-static struct plat_serial8250_port dove_uart1_data[] = {
-	{
-		.mapbase	= DOVE_UART1_PHYS_BASE,
-		.membase	= (char *)DOVE_UART1_VIRT_BASE,
-		.irq		= IRQ_DOVE_UART_1,
-		.flags		= UPF_SKIP_TEST | UPF_BOOT_AUTOCONF,
-		.iotype		= UPIO_MEM,
-		.regshift	= 2,
-		.uartclk	= 0,
-	}, {
-	},
-};
-
-static struct resource dove_uart1_resources[] = {
-	{
-		.start		= DOVE_UART1_PHYS_BASE,
-		.end		= DOVE_UART1_PHYS_BASE + SZ_256 - 1,
-		.flags		= IORESOURCE_MEM,
-	}, {
-		.start		= IRQ_DOVE_UART_1,
-		.end		= IRQ_DOVE_UART_1,
-		.flags		= IORESOURCE_IRQ,
-	},
-};
-
-static struct platform_device dove_uart1 = {
-	.name			= "serial8250",
-	.id			= 1,
-	.dev			= {
-		.platform_data	= dove_uart1_data,
-	},
-	.resource		= dove_uart1_resources,
-	.num_resources		= ARRAY_SIZE(dove_uart1_resources),
-};
-
 void __init dove_uart1_init(void)
 {
-	platform_device_register(&dove_uart1);
+	orion_uart1_init(DOVE_UART1_VIRT_BASE, DOVE_UART1_PHYS_BASE,
+			 IRQ_DOVE_UART_1, get_tclk());
 }
 
 /*****************************************************************************
  * UART2
  ****************************************************************************/
-static struct plat_serial8250_port dove_uart2_data[] = {
-	{
-		.mapbase	= DOVE_UART2_PHYS_BASE,
-		.membase	= (char *)DOVE_UART2_VIRT_BASE,
-		.irq		= IRQ_DOVE_UART_2,
-		.flags		= UPF_SKIP_TEST | UPF_BOOT_AUTOCONF,
-		.iotype		= UPIO_MEM,
-		.regshift	= 2,
-		.uartclk	= 0,
-	}, {
-	},
-};
-
-static struct resource dove_uart2_resources[] = {
-	{
-		.start		= DOVE_UART2_PHYS_BASE,
-		.end		= DOVE_UART2_PHYS_BASE + SZ_256 - 1,
-		.flags		= IORESOURCE_MEM,
-	}, {
-		.start		= IRQ_DOVE_UART_2,
-		.end		= IRQ_DOVE_UART_2,
-		.flags		= IORESOURCE_IRQ,
-	},
-};
-
-static struct platform_device dove_uart2 = {
-	.name			= "serial8250",
-	.id			= 2,
-	.dev			= {
-		.platform_data	= dove_uart2_data,
-	},
-	.resource		= dove_uart2_resources,
-	.num_resources		= ARRAY_SIZE(dove_uart2_resources),
-};
-
 void __init dove_uart2_init(void)
 {
-	platform_device_register(&dove_uart2);
+	orion_uart2_init(DOVE_UART2_VIRT_BASE, DOVE_UART2_PHYS_BASE,
+			 IRQ_DOVE_UART_2, get_tclk());
 }
 
 /*****************************************************************************
  * UART3
  ****************************************************************************/
-static struct plat_serial8250_port dove_uart3_data[] = {
-	{
-		.mapbase	= DOVE_UART3_PHYS_BASE,
-		.membase	= (char *)DOVE_UART3_VIRT_BASE,
-		.irq		= IRQ_DOVE_UART_3,
-		.flags		= UPF_SKIP_TEST | UPF_BOOT_AUTOCONF,
-		.iotype		= UPIO_MEM,
-		.regshift	= 2,
-		.uartclk	= 0,
-	}, {
-	},
-};
-
-static struct resource dove_uart3_resources[] = {
-	{
-		.start		= DOVE_UART3_PHYS_BASE,
-		.end		= DOVE_UART3_PHYS_BASE + SZ_256 - 1,
-		.flags		= IORESOURCE_MEM,
-	}, {
-		.start		= IRQ_DOVE_UART_3,
-		.end		= IRQ_DOVE_UART_3,
-		.flags		= IORESOURCE_IRQ,
-	},
-};
-
-static struct platform_device dove_uart3 = {
-	.name			= "serial8250",
-	.id			= 3,
-	.dev			= {
-		.platform_data	= dove_uart3_data,
-	},
-	.resource		= dove_uart3_resources,
-	.num_resources		= ARRAY_SIZE(dove_uart3_resources),
-};
-
 void __init dove_uart3_init(void)
 {
-	platform_device_register(&dove_uart3);
+	orion_uart3_init(DOVE_UART3_VIRT_BASE, DOVE_UART3_PHYS_BASE,
+			 IRQ_DOVE_UART_3, get_tclk());
 }
 
 /*****************************************************************************
- * SPI0
+ * SPI
  ****************************************************************************/
-static struct orion_spi_info dove_spi0_data = {
-	.tclk		= 0,
-};
-
-static struct resource dove_spi0_resources[] = {
-	{
-		.start	= DOVE_SPI0_PHYS_BASE,
-		.end	= DOVE_SPI0_PHYS_BASE + SZ_512 - 1,
-		.flags	= IORESOURCE_MEM,
-	}, {
-		.start	= IRQ_DOVE_SPI0,
-		.end	= IRQ_DOVE_SPI0,
-		.flags	= IORESOURCE_IRQ,
-	},
-};
-
-static struct platform_device dove_spi0 = {
-	.name		= "orion_spi",
-	.id		= 0,
-	.resource	= dove_spi0_resources,
-	.dev		= {
-		.platform_data	= &dove_spi0_data,
-	},
-	.num_resources	= ARRAY_SIZE(dove_spi0_resources),
-};
-
 void __init dove_spi0_init(void)
 {
-	platform_device_register(&dove_spi0);
+	orion_spi_init(DOVE_SPI0_PHYS_BASE, get_tclk());
 }
 
-/*****************************************************************************
- * SPI1
- ****************************************************************************/
-static struct orion_spi_info dove_spi1_data = {
-	.tclk		= 0,
-};
-
-static struct resource dove_spi1_resources[] = {
-	{
-		.start	= DOVE_SPI1_PHYS_BASE,
-		.end	= DOVE_SPI1_PHYS_BASE + SZ_512 - 1,
-		.flags	= IORESOURCE_MEM,
-	}, {
-		.start	= IRQ_DOVE_SPI1,
-		.end	= IRQ_DOVE_SPI1,
-		.flags	= IORESOURCE_IRQ,
-	},
-};
-
-static struct platform_device dove_spi1 = {
-	.name		= "orion_spi",
-	.id		= 1,
-	.resource	= dove_spi1_resources,
-	.dev		= {
-		.platform_data	= &dove_spi1_data,
-	},
-	.num_resources	= ARRAY_SIZE(dove_spi1_resources),
-};
-
 void __init dove_spi1_init(void)
 {
-	platform_device_register(&dove_spi1);
+	orion_spi_init(DOVE_SPI1_PHYS_BASE, get_tclk());
 }
 
 /*****************************************************************************
  * I2C
  ****************************************************************************/
-static struct mv64xxx_i2c_pdata dove_i2c_data = {
-	.freq_m		= 10, /* assumes 166 MHz TCLK gets 94.3kHz */
-	.freq_n		= 3,
-	.timeout	= 1000, /* Default timeout of 1 second */
-};
-
-static struct resource dove_i2c_resources[] = {
-	{
-		.name	= "i2c base",
-		.start	= DOVE_I2C_PHYS_BASE,
-		.end	= DOVE_I2C_PHYS_BASE + 0x20 - 1,
-		.flags	= IORESOURCE_MEM,
-	}, {
-		.name	= "i2c irq",
-		.start	= IRQ_DOVE_I2C,
-		.end	= IRQ_DOVE_I2C,
-		.flags	= IORESOURCE_IRQ,
-	},
-};
-
-static struct platform_device dove_i2c = {
-	.name		= MV64XXX_I2C_CTLR_NAME,
-	.id		= 0,
-	.num_resources	= ARRAY_SIZE(dove_i2c_resources),
-	.resource	= dove_i2c_resources,
-	.dev		= {
-		.platform_data = &dove_i2c_data,
-	},
-};
-
 void __init dove_i2c_init(void)
 {
-	platform_device_register(&dove_i2c);
+	orion_i2c_init(DOVE_I2C_PHYS_BASE, IRQ_DOVE_I2C, 10);
 }
 
 /*****************************************************************************
@@ -554,208 +196,22 @@
 };
 
 /*****************************************************************************
- * XOR
- ****************************************************************************/
-static struct mv_xor_platform_shared_data dove_xor_shared_data = {
-	.dram		= &dove_mbus_dram_info,
-};
-
-/*****************************************************************************
  * XOR 0
  ****************************************************************************/
-static u64 dove_xor0_dmamask = DMA_BIT_MASK(32);
-
-static struct resource dove_xor0_shared_resources[] = {
-	{
-		.name	= "xor 0 low",
-		.start	= DOVE_XOR0_PHYS_BASE,
-		.end	= DOVE_XOR0_PHYS_BASE + 0xff,
-		.flags	= IORESOURCE_MEM,
-	}, {
-		.name	= "xor 0 high",
-		.start	= DOVE_XOR0_HIGH_PHYS_BASE,
-		.end	= DOVE_XOR0_HIGH_PHYS_BASE + 0xff,
-		.flags	= IORESOURCE_MEM,
-	},
-};
-
-static struct platform_device dove_xor0_shared = {
-	.name		= MV_XOR_SHARED_NAME,
-	.id		= 0,
-	.dev		= {
-		.platform_data = &dove_xor_shared_data,
-	},
-	.num_resources	= ARRAY_SIZE(dove_xor0_shared_resources),
-	.resource	= dove_xor0_shared_resources,
-};
-
-static struct resource dove_xor00_resources[] = {
-	[0] = {
-		.start	= IRQ_DOVE_XOR_00,
-		.end	= IRQ_DOVE_XOR_00,
-		.flags	= IORESOURCE_IRQ,
-	},
-};
-
-static struct mv_xor_platform_data dove_xor00_data = {
-	.shared		= &dove_xor0_shared,
-	.hw_id		= 0,
-	.pool_size	= PAGE_SIZE,
-};
-
-static struct platform_device dove_xor00_channel = {
-	.name		= MV_XOR_NAME,
-	.id		= 0,
-	.num_resources	= ARRAY_SIZE(dove_xor00_resources),
-	.resource	= dove_xor00_resources,
-	.dev		= {
-		.dma_mask		= &dove_xor0_dmamask,
-		.coherent_dma_mask	= DMA_BIT_MASK(64),
-		.platform_data		= &dove_xor00_data,
-	},
-};
-
-static struct resource dove_xor01_resources[] = {
-	[0] = {
-		.start	= IRQ_DOVE_XOR_01,
-		.end	= IRQ_DOVE_XOR_01,
-		.flags	= IORESOURCE_IRQ,
-	},
-};
-
-static struct mv_xor_platform_data dove_xor01_data = {
-	.shared		= &dove_xor0_shared,
-	.hw_id		= 1,
-	.pool_size	= PAGE_SIZE,
-};
-
-static struct platform_device dove_xor01_channel = {
-	.name		= MV_XOR_NAME,
-	.id		= 1,
-	.num_resources	= ARRAY_SIZE(dove_xor01_resources),
-	.resource	= dove_xor01_resources,
-	.dev		= {
-		.dma_mask		= &dove_xor0_dmamask,
-		.coherent_dma_mask	= DMA_BIT_MASK(64),
-		.platform_data		= &dove_xor01_data,
-	},
-};
-
 void __init dove_xor0_init(void)
 {
-	platform_device_register(&dove_xor0_shared);
-
-	/*
-	 * two engines can't do memset simultaneously, this limitation
-	 * satisfied by removing memset support from one of the engines.
-	 */
-	dma_cap_set(DMA_MEMCPY, dove_xor00_data.cap_mask);
-	dma_cap_set(DMA_XOR, dove_xor00_data.cap_mask);
-	platform_device_register(&dove_xor00_channel);
-
-	dma_cap_set(DMA_MEMCPY, dove_xor01_data.cap_mask);
-	dma_cap_set(DMA_MEMSET, dove_xor01_data.cap_mask);
-	dma_cap_set(DMA_XOR, dove_xor01_data.cap_mask);
-	platform_device_register(&dove_xor01_channel);
+	orion_xor0_init(&dove_mbus_dram_info,
+			DOVE_XOR0_PHYS_BASE, DOVE_XOR0_HIGH_PHYS_BASE,
+			IRQ_DOVE_XOR_00, IRQ_DOVE_XOR_01);
 }
 
 /*****************************************************************************
  * XOR 1
  ****************************************************************************/
-static u64 dove_xor1_dmamask = DMA_BIT_MASK(32);
-
-static struct resource dove_xor1_shared_resources[] = {
-	{
-		.name	= "xor 0 low",
-		.start	= DOVE_XOR1_PHYS_BASE,
-		.end	= DOVE_XOR1_PHYS_BASE + 0xff,
-		.flags	= IORESOURCE_MEM,
-	}, {
-		.name	= "xor 0 high",
-		.start	= DOVE_XOR1_HIGH_PHYS_BASE,
-		.end	= DOVE_XOR1_HIGH_PHYS_BASE + 0xff,
-		.flags	= IORESOURCE_MEM,
-	},
-};
-
-static struct platform_device dove_xor1_shared = {
-	.name		= MV_XOR_SHARED_NAME,
-	.id		= 1,
-	.dev		= {
-		.platform_data = &dove_xor_shared_data,
-	},
-	.num_resources	= ARRAY_SIZE(dove_xor1_shared_resources),
-	.resource	= dove_xor1_shared_resources,
-};
-
-static struct resource dove_xor10_resources[] = {
-	[0] = {
-		.start	= IRQ_DOVE_XOR_10,
-		.end	= IRQ_DOVE_XOR_10,
-		.flags	= IORESOURCE_IRQ,
-	},
-};
-
-static struct mv_xor_platform_data dove_xor10_data = {
-	.shared		= &dove_xor1_shared,
-	.hw_id		= 0,
-	.pool_size	= PAGE_SIZE,
-};
-
-static struct platform_device dove_xor10_channel = {
-	.name		= MV_XOR_NAME,
-	.id		= 2,
-	.num_resources	= ARRAY_SIZE(dove_xor10_resources),
-	.resource	= dove_xor10_resources,
-	.dev		= {
-		.dma_mask		= &dove_xor1_dmamask,
-		.coherent_dma_mask	= DMA_BIT_MASK(64),
-		.platform_data		= &dove_xor10_data,
-	},
-};
-
-static struct resource dove_xor11_resources[] = {
-	[0] = {
-		.start	= IRQ_DOVE_XOR_11,
-		.end	= IRQ_DOVE_XOR_11,
-		.flags	= IORESOURCE_IRQ,
-	},
-};
-
-static struct mv_xor_platform_data dove_xor11_data = {
-	.shared		= &dove_xor1_shared,
-	.hw_id		= 1,
-	.pool_size	= PAGE_SIZE,
-};
-
-static struct platform_device dove_xor11_channel = {
-	.name		= MV_XOR_NAME,
-	.id		= 3,
-	.num_resources	= ARRAY_SIZE(dove_xor11_resources),
-	.resource	= dove_xor11_resources,
-	.dev		= {
-		.dma_mask		= &dove_xor1_dmamask,
-		.coherent_dma_mask	= DMA_BIT_MASK(64),
-		.platform_data		= &dove_xor11_data,
-	},
-};
-
 void __init dove_xor1_init(void)
 {
-	platform_device_register(&dove_xor1_shared);
-
-	/*
-	 * two engines can't do memset simultaneously, this limitation
-	 * satisfied by removing memset support from one of the engines.
-	 */
-	dma_cap_set(DMA_MEMCPY, dove_xor10_data.cap_mask);
-	dma_cap_set(DMA_XOR, dove_xor10_data.cap_mask);
-	platform_device_register(&dove_xor10_channel);
-
-	dma_cap_set(DMA_MEMCPY, dove_xor11_data.cap_mask);
-	dma_cap_set(DMA_MEMSET, dove_xor11_data.cap_mask);
-	dma_cap_set(DMA_XOR, dove_xor11_data.cap_mask);
-	platform_device_register(&dove_xor11_channel);
+	orion_xor1_init(DOVE_XOR1_PHYS_BASE, DOVE_XOR1_HIGH_PHYS_BASE,
+			IRQ_DOVE_XOR_10, IRQ_DOVE_XOR_11);
 }
 
 /*****************************************************************************
@@ -833,14 +289,6 @@
 #endif
 	dove_setup_cpu_mbus();
 
-	dove_ge00_shared_data.t_clk = tclk;
-	dove_uart0_data[0].uartclk = tclk;
-	dove_uart1_data[0].uartclk = tclk;
-	dove_uart2_data[0].uartclk = tclk;
-	dove_uart3_data[0].uartclk = tclk;
-	dove_spi0_data.tclk = tclk;
-	dove_spi1_data.tclk = tclk;
-
 	/* internal devices that every board has */
 	dove_rtc_init();
 	dove_xor0_init();
diff -druN linux-2.6.39-libre/arch/arm/mach-dove/mpp.c linux-3.0-rc7-libre/arch/arm/mach-dove/mpp.c
--- linux-2.6.39-libre/arch/arm/mach-dove/mpp.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-dove/mpp.c	2011-07-11 19:51:52.000000000 -0400
@@ -11,24 +11,17 @@
 #include <linux/kernel.h>
 #include <linux/gpio.h>
 #include <linux/io.h>
-
+#include <plat/mpp.h>
 #include <mach/dove.h>
-
 #include "mpp.h"
 
-#define MPP_NR_REGS 4
-#define MPP_CTRL(i)	((i) == 3 ?				\
-			 DOVE_MPP_CTRL4_VIRT_BASE :		\
-			 DOVE_MPP_VIRT_BASE + (i) * 4)
-#define PMU_SIG_REGS 2
-#define PMU_SIG_CTRL(i)	(DOVE_PMU_SIG_CTRL + (i) * 4)
-
 struct dove_mpp_grp {
 	int start;
 	int end;
 };
 
-static struct dove_mpp_grp dove_mpp_grp[] = {
+/* Map a group to a range of GPIO pins in that group */
+static const struct dove_mpp_grp dove_mpp_grp[] = {
 	[MPP_24_39] = {
 		.start	= 24,
 		.end	= 39,
@@ -38,8 +31,8 @@
 		.end	= 45,
 	},
 	[MPP_46_51] = {
-		.start	= 40,
-		.end	= 45,
+		.start	= 46,
+		.end	= 51,
 	},
 	[MPP_58_61] = {
 		.start	= 58,
@@ -51,6 +44,8 @@
 	},
 };
 
+/* Enable gpio for a range of pins. mode should be a combination of
+   GPIO_OUTPUT_OK | GPIO_INPUT_OK */
 static void dove_mpp_gpio_mode(int start, int end, int gpio_mode)
 {
 	int i;
@@ -59,24 +54,17 @@
 		orion_gpio_set_valid(i, gpio_mode);
 }
 
+/* Dump all the extra MPP registers. The platform code will dump the
+   registers for pins 0-23. */
 static void dove_mpp_dump_regs(void)
 {
-#ifdef DEBUG
-	int i;
-
-	pr_debug("MPP_CTRL regs:");
-	for (i = 0; i < MPP_NR_REGS; i++)
-		printk(" %08x", readl(MPP_CTRL(i)));
-	printk("\n");
+	pr_debug("PMU_CTRL4_CTRL: %08x\n",
+		 readl(DOVE_MPP_CTRL4_VIRT_BASE));
 
-	pr_debug("PMU_SIG_CTRL regs:");
-	for (i = 0; i < PMU_SIG_REGS; i++)
-		printk(" %08x", readl(PMU_SIG_CTRL(i)));
-	printk("\n");
+	pr_debug("PMU_MPP_GENERAL_CTRL: %08x\n",
+		 readl(DOVE_PMU_MPP_GENERAL_CTRL));
 
-	pr_debug("PMU_MPP_GENERAL_CTRL: %08x\n", readl(DOVE_PMU_MPP_GENERAL_CTRL));
 	pr_debug("MPP_GENERAL: %08x\n", readl(DOVE_MPP_GENERAL_VIRT_BASE));
-#endif
 }
 
 static void dove_mpp_cfg_nfc(int sel)
@@ -92,7 +80,7 @@
 
 static void dove_mpp_cfg_au1(int sel)
 {
-	u32 mpp_ctrl4		= readl(DOVE_MPP_CTRL4_VIRT_BASE);
+	u32 mpp_ctrl4 = readl(DOVE_MPP_CTRL4_VIRT_BASE);
 	u32 ssp_ctrl1 = readl(DOVE_SSP_CTRL_STATUS_1);
 	u32 mpp_gen_ctrl = readl(DOVE_MPP_GENERAL_VIRT_BASE);
 	u32 global_cfg_2 = readl(DOVE_GLOBAL_CONFIG_2);
@@ -128,82 +116,46 @@
 	writel(global_cfg_2, DOVE_GLOBAL_CONFIG_2);
 }
 
-static void dove_mpp_conf_grp(int num, int sel, u32 *mpp_ctrl)
-{
-	int start = dove_mpp_grp[num].start;
-	int end = dove_mpp_grp[num].end;
-	int gpio_mode = sel ? GPIO_OUTPUT_OK | GPIO_INPUT_OK : 0;
-
-	*mpp_ctrl &= ~(0x1 << num);
-	*mpp_ctrl |= sel << num;
-
-	dove_mpp_gpio_mode(start, end, gpio_mode);
-}
-
-void __init dove_mpp_conf(unsigned int *mpp_list)
+/* Configure the group registers, enabling GPIO if sel indicates the
+   pin is to be used for GPIO */
+static void dove_mpp_conf_grp(unsigned int *mpp_grp_list)
 {
-	u32 mpp_ctrl[MPP_NR_REGS];
-	u32 pmu_mpp_ctrl = 0;
-	u32 pmu_sig_ctrl[PMU_SIG_REGS];
-	int i;
-
-	for (i = 0; i < MPP_NR_REGS; i++)
-		mpp_ctrl[i] = readl(MPP_CTRL(i));
-
-	for (i = 0; i < PMU_SIG_REGS; i++)
-		pmu_sig_ctrl[i] = readl(PMU_SIG_CTRL(i));
-
-	pmu_mpp_ctrl = readl(DOVE_PMU_MPP_GENERAL_CTRL);
-
-	dove_mpp_dump_regs();
-
-	for ( ; *mpp_list != MPP_END; mpp_list++) {
-		unsigned int num = MPP_NUM(*mpp_list);
-		unsigned int sel = MPP_SEL(*mpp_list);
-		int shift, gpio_mode;
-
-		if (num > MPP_MAX) {
-			pr_err("dove: invalid MPP number (%u)\n", num);
-			continue;
-		}
-
-		if (*mpp_list & MPP_NFC_MASK) {
-			dove_mpp_cfg_nfc(sel);
-			continue;
-		}
+	u32 mpp_ctrl4 = readl(DOVE_MPP_CTRL4_VIRT_BASE);
+	int gpio_mode;
 
-		if (*mpp_list & MPP_AU1_MASK) {
-			dove_mpp_cfg_au1(sel);
-			continue;
-		}
+	for ( ; *mpp_grp_list; mpp_grp_list++) {
+		unsigned int num = MPP_NUM(*mpp_grp_list);
+		unsigned int sel = MPP_SEL(*mpp_grp_list);
 
-		if (*mpp_list & MPP_GRP_MASK) {
-			dove_mpp_conf_grp(num, sel, &mpp_ctrl[3]);
+		if (num > MPP_GRP_MAX) {
+			pr_err("dove: invalid MPP GRP number (%u)\n", num);
 			continue;
 		}
 
-		shift = (num & 7) << 2;
-		if (*mpp_list & MPP_PMU_MASK) {
-			pmu_mpp_ctrl |= (0x1 << num);
-			pmu_sig_ctrl[num / 8] &= ~(0xf << shift);
-			pmu_sig_ctrl[num / 8] |= 0xf << shift;
-			gpio_mode = 0;
-		} else {
-			mpp_ctrl[num / 8] &= ~(0xf << shift);
-			mpp_ctrl[num / 8] |= sel << shift;
-			gpio_mode = GPIO_OUTPUT_OK | GPIO_INPUT_OK;
-		}
+		mpp_ctrl4 &= ~(0x1 << num);
+		mpp_ctrl4 |= sel << num;
 
-		orion_gpio_set_valid(num, gpio_mode);
+		gpio_mode = sel ? GPIO_OUTPUT_OK | GPIO_INPUT_OK : 0;
+		dove_mpp_gpio_mode(dove_mpp_grp[num].start,
+				   dove_mpp_grp[num].end, gpio_mode);
 	}
+	writel(mpp_ctrl4, DOVE_MPP_CTRL4_VIRT_BASE);
+}
 
-	for (i = 0; i < MPP_NR_REGS; i++)
-		writel(mpp_ctrl[i], MPP_CTRL(i));
+/* Configure the various MPP pins on Dove */
+void __init dove_mpp_conf(unsigned int *mpp_list,
+			  unsigned int *mpp_grp_list,
+			  unsigned int grp_au1_52_57,
+			  unsigned int grp_nfc_64_71)
+{
+	dove_mpp_dump_regs();
 
-	for (i = 0; i < PMU_SIG_REGS; i++)
-		writel(pmu_sig_ctrl[i], PMU_SIG_CTRL(i));
+	/* Use platform code for pins 0-23 */
+	orion_mpp_conf(mpp_list, 0, MPP_MAX, DOVE_MPP_VIRT_BASE);
 
-	writel(pmu_mpp_ctrl, DOVE_PMU_MPP_GENERAL_CTRL);
+	dove_mpp_conf_grp(mpp_grp_list);
+	dove_mpp_cfg_au1(grp_au1_52_57);
+	dove_mpp_cfg_nfc(grp_nfc_64_71);
 
 	dove_mpp_dump_regs();
 }
diff -druN linux-2.6.39-libre/arch/arm/mach-dove/mpp.h linux-3.0-rc7-libre/arch/arm/mach-dove/mpp.h
--- linux-2.6.39-libre/arch/arm/mach-dove/mpp.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-dove/mpp.h	2011-07-11 19:51:52.000000000 -0400
@@ -1,178 +1,150 @@
 #ifndef __ARCH_DOVE_MPP_CODED_H
 #define __ARCH_DOVE_MPP_CODED_H
 
-#define MPP(_num, _mode, _pmu, _grp, _au1, _nfc) (	\
-/* MPP/group number */		((_num) & 0xff) |		\
-/* MPP select value */		(((_mode) & 0xf) << 8) |	\
-/* MPP PMU */			((!!(_pmu)) << 12) |		\
-/* group flag */		((!!(_grp)) << 13) |		\
-/* AU1 flag */			((!!(_au1)) << 14) |		\
-/* NFCE flag */			((!!(_nfc)) << 15))
-
-#define MPP_MAX	71
-
-#define MPP_NUM(x)    ((x) & 0xff)
-#define MPP_SEL(x)    (((x) >> 8) & 0xf)
-
-#define MPP_PMU_MASK		MPP(0, 0x0, 1, 0, 0, 0)
-#define MPP_GRP_MASK		MPP(0, 0x0, 0, 1, 0, 0)
-#define MPP_AU1_MASK		MPP(0, 0x0, 0, 0, 1, 0)
-#define MPP_NFC_MASK		MPP(0, 0x0, 0, 0, 0, 1)
-
-#define MPP_END			MPP(0xff, 0xf, 1, 1, 1, 1)
+#define MPP(_num, _sel, _in, _out) ( \
+	/* MPP number */		((_num) & 0xff) | \
+	/* MPP select value */		(((_sel) & 0xf) << 8) | \
+	/* may be input signal */	((!!(_in)) << 12) | \
+	/* may be output signal */	((!!(_out)) << 13))
 
-#define MPP_PMU_DRIVE_0		0x1
-#define MPP_PMU_DRIVE_1		0x2
-#define MPP_PMU_SDI		0x3
-#define MPP_PMU_CPU_PWRDWN	0x4
-#define MPP_PMU_STBY_PWRDWN	0x5
-#define MPP_PMU_CORE_PWR_GOOD	0x8
-#define MPP_PMU_BAT_FAULT	0xa
-#define MPP_PMU_EXT0_WU		0xb
-#define MPP_PMU_EXT1_WU		0xc
-#define MPP_PMU_EXT2_WU		0xd
-#define MPP_PMU_BLINK		0xe
-#define MPP_PMU(_num, _mode)	MPP((_num), MPP_PMU_##_mode, 1, 0, 0, 0)
+#define MPP0_GPIO0		MPP(0, 0x0, 1, 1)
+#define MPP0_UA2_RTSn		MPP(0, 0x2, 0, 0)
+#define MPP0_SDIO0_CD		MPP(0, 0x3, 0, 0)
+#define MPP0_LCD0_PWM		MPP(0, 0xf, 0, 0)
 
-#define MPP_PIN(_num, _mode)	MPP((_num), (_mode), 0, 0, 0, 0)
-#define MPP_GRP(_grp, _mode)	MPP((_grp), (_mode), 0, 1, 0, 0)
-#define MPP_GRP_AU1(_mode)	MPP(0, (_mode), 0, 0, 1, 0)
-#define MPP_GRP_NFC(_mode)	MPP(0, (_mode), 0, 0, 0, 1)
+#define MPP1_GPIO1		MPP(1, 0x0, 1, 1)
+#define MPP1_UA2_CTSn		MPP(1, 0x2, 0, 0)
+#define MPP1_SDIO0_WP		MPP(1, 0x3, 0, 0)
+#define MPP1_LCD1_PWM		MPP(1, 0xf, 0, 0)
 
-#define MPP0_GPIO0		MPP_PIN(0, 0x0)
-#define MPP0_UA2_RTSn		MPP_PIN(0, 0x2)
-#define MPP0_SDIO0_CD		MPP_PIN(0, 0x3)
-#define MPP0_LCD0_PWM		MPP_PIN(0, 0xf)
+#define MPP2_GPIO2		MPP(2, 0x0, 1, 1)
+#define MPP2_SATA_PRESENT	MPP(2, 0x1, 0, 0)
+#define MPP2_UA2_TXD		MPP(2, 0x2, 0, 0)
+#define MPP2_SDIO0_BUS_POWER	MPP(2, 0x3, 0, 0)
+#define MPP2_UA_RTSn1		MPP(2, 0x4, 0, 0)
 
-#define MPP1_GPIO1		MPP_PIN(1, 0x0)
-#define MPP1_UA2_CTSn		MPP_PIN(1, 0x2)
-#define MPP1_SDIO0_WP		MPP_PIN(1, 0x3)
-#define MPP1_LCD1_PWM		MPP_PIN(1, 0xf)
+#define MPP3_GPIO3		MPP(3, 0x0, 1, 1)
+#define MPP3_SATA_ACT		MPP(3, 0x1, 0, 0)
+#define MPP3_UA2_RXD		MPP(3, 0x2, 0, 0)
+#define MPP3_SDIO0_LED_CTRL	MPP(3, 0x3, 0, 0)
+#define MPP3_UA_CTSn1		MPP(3, 0x4, 0, 0)
+#define MPP3_SPI_LCD_CS1	MPP(3, 0xf, 0, 0)
 
-#define MPP2_GPIO2		MPP_PIN(2, 0x0)
-#define MPP2_SATA_PRESENT	MPP_PIN(2, 0x1)
-#define MPP2_UA2_TXD		MPP_PIN(2, 0x2)
-#define MPP2_SDIO0_BUS_POWER	MPP_PIN(2, 0x3)
-#define MPP2_UA_RTSn1		MPP_PIN(2, 0x4)
+#define MPP4_GPIO4		MPP(4, 0x0, 1, 1)
+#define MPP4_UA3_RTSn		MPP(4, 0x2, 0, 0)
+#define MPP4_SDIO1_CD		MPP(4, 0x3, 0, 0)
+#define MPP4_SPI_1_MISO		MPP(4, 0x4, 0, 0)
 
-#define MPP3_GPIO3		MPP_PIN(3, 0x0)
-#define MPP3_SATA_ACT		MPP_PIN(3, 0x1)
-#define MPP3_UA2_RXD		MPP_PIN(3, 0x2)
-#define MPP3_SDIO0_LED_CTRL	MPP_PIN(3, 0x3)
-#define MPP3_UA_CTSn1		MPP_PIN(3, 0x4)
-#define MPP3_SPI_LCD_CS1	MPP_PIN(3, 0xf)
+#define MPP5_GPIO5		MPP(5, 0x0, 1, 1)
+#define MPP5_UA3_CTSn		MPP(5, 0x2, 0, 0)
+#define MPP5_SDIO1_WP		MPP(5, 0x3, 0, 0)
+#define MPP5_SPI_1_CS		MPP(5, 0x4, 0, 0)
 
-#define MPP4_GPIO4		MPP_PIN(4, 0x0)
-#define MPP4_UA3_RTSn		MPP_PIN(4, 0x2)
-#define MPP4_SDIO1_CD		MPP_PIN(4, 0x3)
-#define MPP4_SPI_1_MISO		MPP_PIN(4, 0x4)
+#define MPP6_GPIO6		MPP(6, 0x0, 1, 1)
+#define MPP6_UA3_TXD		MPP(6, 0x2, 0, 0)
+#define MPP6_SDIO1_BUS_POWER	MPP(6, 0x3, 0, 0)
+#define MPP6_SPI_1_MOSI		MPP(6, 0x4, 0, 0)
 
-#define MPP5_GPIO5		MPP_PIN(5, 0x0)
-#define MPP5_UA3_CTSn		MPP_PIN(5, 0x2)
-#define MPP5_SDIO1_WP		MPP_PIN(5, 0x3)
-#define MPP5_SPI_1_CS		MPP_PIN(5, 0x4)
+#define MPP7_GPIO7		MPP(7, 0x0, 1, 1)
+#define MPP7_UA3_RXD		MPP(7, 0x2, 0, 0)
+#define MPP7_SDIO1_LED_CTRL	MPP(7, 0x3, 0, 0)
+#define MPP7_SPI_1_SCK		MPP(7, 0x4, 0, 0)
 
-#define MPP6_GPIO6		MPP_PIN(6, 0x0)
-#define MPP6_UA3_TXD		MPP_PIN(6, 0x2)
-#define MPP6_SDIO1_BUS_POWER	MPP_PIN(6, 0x3)
-#define MPP6_SPI_1_MOSI		MPP_PIN(6, 0x4)
+#define MPP8_GPIO8		MPP(8, 0x0, 1, 1)
+#define MPP8_WD_RST_OUT		MPP(8, 0x1, 0, 0)
 
-#define MPP7_GPIO7		MPP_PIN(7, 0x0)
-#define MPP7_UA3_RXD		MPP_PIN(7, 0x2)
-#define MPP7_SDIO1_LED_CTRL	MPP_PIN(7, 0x3)
-#define MPP7_SPI_1_SCK		MPP_PIN(7, 0x4)
+#define MPP9_GPIO9		MPP(9, 0x0, 1, 1)
+#define MPP9_PEX1_CLKREQn	MPP(9, 0x5, 0, 0)
 
-#define MPP8_GPIO8		MPP_PIN(8, 0x0)
-#define MPP8_WD_RST_OUT		MPP_PIN(8, 0x1)
+#define MPP10_GPIO10		MPP(10, 0x0, 1, 1)
+#define MPP10_SSP_SCLK		MPP(10, 0x5, 0, 0)
 
-#define MPP9_GPIO9		MPP_PIN(9, 0x0)
-#define MPP9_PEX1_CLKREQn	MPP_PIN(9, 0x5)
+#define MPP11_GPIO11		MPP(11, 0x0, 1, 1)
+#define MPP11_SATA_PRESENT	MPP(11, 0x1, 0, 0)
+#define MPP11_SATA_ACT		MPP(11, 0x2, 0, 0)
+#define MPP11_SDIO0_LED_CTRL	MPP(11, 0x3, 0, 0)
+#define MPP11_SDIO1_LED_CTRL	MPP(11, 0x4, 0, 0)
+#define MPP11_PEX0_CLKREQn	MPP(11, 0x5, 0, 0)
 
-#define MPP10_GPIO10		MPP_PIN(10, 0x0)
-#define MPP10_SSP_SCLK		MPP_PIN(10, 0x5)
+#define MPP12_GPIO12		MPP(12, 0x0, 1, 1)
+#define MPP12_SATA_ACT		MPP(12, 0x1, 0, 0)
+#define MPP12_UA2_RTSn		MPP(12, 0x2, 0, 0)
+#define MPP12_AD0_I2S_EXT_MCLK	MPP(12, 0x3, 0, 0)
+#define MPP12_SDIO1_CD		MPP(12, 0x4, 0, 0)
 
-#define MPP11_GPIO11		MPP_PIN(11, 0x0)
-#define MPP11_SATA_PRESENT	MPP_PIN(11, 0x1)
-#define MPP11_SATA_ACT		MPP_PIN(11, 0x2)
-#define MPP11_SDIO0_LED_CTRL	MPP_PIN(11, 0x3)
-#define MPP11_SDIO1_LED_CTRL	MPP_PIN(11, 0x4)
-#define MPP11_PEX0_CLKREQn	MPP_PIN(11, 0x5)
+#define MPP13_GPIO13		MPP(13, 0x0, 1, 1)
+#define MPP13_UA2_CTSn		MPP(13, 0x2, 0, 0)
+#define MPP13_AD1_I2S_EXT_MCLK	MPP(13, 0x3, 0, 0)
+#define MPP13_SDIO1WP		MPP(13, 0x4, 0, 0)
+#define MPP13_SSP_EXTCLK	MPP(13, 0x5, 0, 0)
 
-#define MPP12_GPIO12		MPP_PIN(12, 0x0)
-#define MPP12_SATA_ACT		MPP_PIN(12, 0x1)
-#define MPP12_UA2_RTSn		MPP_PIN(12, 0x2)
-#define MPP12_AD0_I2S_EXT_MCLK	MPP_PIN(12, 0x3)
-#define MPP12_SDIO1_CD		MPP_PIN(12, 0x4)
+#define MPP14_GPIO14		MPP(14, 0x0, 1, 1)
+#define MPP14_UA2_TXD		MPP(14, 0x2, 0, 0)
+#define MPP14_SDIO1_BUS_POWER	MPP(14, 0x4, 0, 0)
+#define MPP14_SSP_RXD		MPP(14, 0x5, 0, 0)
 
-#define MPP13_GPIO13		MPP_PIN(13, 0x0)
-#define MPP13_UA2_CTSn		MPP_PIN(13, 0x2)
-#define MPP13_AD1_I2S_EXT_MCLK	MPP_PIN(13, 0x3)
-#define MPP13_SDIO1WP		MPP_PIN(13, 0x4)
-#define MPP13_SSP_EXTCLK	MPP_PIN(13, 0x5)
+#define MPP15_GPIO15		MPP(15, 0x0, 1, 1)
+#define MPP15_UA2_RXD		MPP(15, 0x2, 0, 0)
+#define MPP15_SDIO1_LED_CTRL	MPP(15, 0x4, 0, 0)
+#define MPP15_SSP_SFRM		MPP(15, 0x5, 0, 0)
 
-#define MPP14_GPIO14		MPP_PIN(14, 0x0)
-#define MPP14_UA2_TXD		MPP_PIN(14, 0x2)
-#define MPP14_SDIO1_BUS_POWER	MPP_PIN(14, 0x4)
-#define MPP14_SSP_RXD		MPP_PIN(14, 0x5)
+#define MPP16_GPIO16		MPP(16, 0x0, 1, 1)
+#define MPP16_UA3_RTSn		MPP(16, 0x2, 0, 0)
+#define MPP16_SDIO0_CD		MPP(16, 0x3, 0, 0)
+#define MPP16_SPI_LCD_CS1	MPP(16, 0x4, 0, 0)
+#define MPP16_AC97_SDATA_IN1	MPP(16, 0x5, 0, 0)
 
-#define MPP15_GPIO15		MPP_PIN(15, 0x0)
-#define MPP15_UA2_RXD		MPP_PIN(15, 0x2)
-#define MPP15_SDIO1_LED_CTRL	MPP_PIN(15, 0x4)
-#define MPP15_SSP_SFRM		MPP_PIN(15, 0x5)
+#define MPP17_GPIO17		MPP(17, 0x0, 1, 1)
+#define MPP17_AC97_SYSCLK_OUT	MPP(17, 0x1, 0, 0)
+#define MPP17_UA3_CTSn		MPP(17, 0x2, 0, 0)
+#define MPP17_SDIO0_WP		MPP(17, 0x3, 0, 0)
+#define MPP17_TW_SDA2		MPP(17, 0x4, 0, 0)
+#define MPP17_AC97_SDATA_IN2	MPP(17, 0x5, 0, 0)
 
-#define MPP16_GPIO16		MPP_PIN(16, 0x0)
-#define MPP16_UA3_RTSn		MPP_PIN(16, 0x2)
-#define MPP16_SDIO0_CD		MPP_PIN(16, 0x3)
-#define MPP16_SPI_LCD_CS1	MPP_PIN(16, 0x4)
-#define MPP16_AC97_SDATA_IN1	MPP_PIN(16, 0x5)
+#define MPP18_GPIO18		MPP(18, 0x0, 1, 1)
+#define MPP18_UA3_TXD		MPP(18, 0x2, 0, 0)
+#define MPP18_SDIO0_BUS_POWER	MPP(18, 0x3, 0, 0)
+#define MPP18_LCD0_PWM		MPP(18, 0x4, 0, 0)
+#define MPP18_AC_SDATA_IN3	MPP(18, 0x5, 0, 0)
 
-#define MPP17_GPIO17		MPP_PIN(17, 0x0)
-#define MPP17_AC97_SYSCLK_OUT	MPP_PIN(17, 0x1)
-#define MPP17_UA3_CTSn		MPP_PIN(17, 0x2)
-#define MPP17_SDIO0_WP		MPP_PIN(17, 0x3)
-#define MPP17_TW_SDA2		MPP_PIN(17, 0x4)
-#define MPP17_AC97_SDATA_IN2	MPP_PIN(17, 0x5)
+#define MPP19_GPIO19		MPP(19, 0x0, 1, 1)
+#define MPP19_UA3_RXD		MPP(19, 0x2, 0, 0)
+#define MPP19_SDIO0_LED_CTRL	MPP(19, 0x3, 0, 0)
+#define MPP19_TW_SCK2		MPP(19, 0x4, 0, 0)
 
-#define MPP18_GPIO18		MPP_PIN(18, 0x0)
-#define MPP18_UA3_TXD		MPP_PIN(18, 0x2)
-#define MPP18_SDIO0_BUS_POWER	MPP_PIN(18, 0x3)
-#define MPP18_LCD0_PWM		MPP_PIN(18, 0x4)
-#define MPP18_AC_SDATA_IN3	MPP_PIN(18, 0x5)
+#define MPP20_GPIO20		MPP(20, 0x0, 1, 1)
+#define MPP20_AC97_SYSCLK_OUT	MPP(20, 0x1, 0, 0)
+#define MPP20_SPI_LCD_MISO	MPP(20, 0x2, 0, 0)
+#define MPP20_SDIO1_CD		MPP(20, 0x3, 0, 0)
+#define MPP20_SDIO0_CD		MPP(20, 0x5, 0, 0)
+#define MPP20_SPI_1_MISO	MPP(20, 0x6, 0, 0)
 
-#define MPP19_GPIO19		MPP_PIN(19, 0x0)
-#define MPP19_UA3_RXD		MPP_PIN(19, 0x2)
-#define MPP19_SDIO0_LED_CTRL	MPP_PIN(19, 0x3)
-#define MPP19_TW_SCK2		MPP_PIN(19, 0x4)
+#define MPP21_GPIO21		MPP(21, 0x0, 1, 1)
+#define MPP21_UA1_RTSn		MPP(21, 0x1, 0, 0)
+#define MPP21_SPI_LCD_CS0	MPP(21, 0x2, 0, 0)
+#define MPP21_SDIO1_WP		MPP(21, 0x3, 0, 0)
+#define MPP21_SSP_SFRM		MPP(21, 0x4, 0, 0)
+#define MPP21_SDIO0_WP		MPP(21, 0x5, 0, 0)
+#define MPP21_SPI_1_CS		MPP(21, 0x6, 0, 0)
 
-#define MPP20_GPIO20		MPP_PIN(20, 0x0)
-#define MPP20_AC97_SYSCLK_OUT	MPP_PIN(20, 0x1)
-#define MPP20_SPI_LCD_MISO	MPP_PIN(20, 0x2)
-#define MPP20_SDIO1_CD		MPP_PIN(20, 0x3)
-#define MPP20_SDIO0_CD		MPP_PIN(20, 0x5)
-#define MPP20_SPI_1_MISO	MPP_PIN(20, 0x6)
+#define MPP22_GPIO22		MPP(22, 0x0, 1, 1)
+#define MPP22_UA1_CTSn		MPP(22, 0x1, 0, 0)
+#define MPP22_SPI_LCD_MOSI	MPP(22, 0x2, 0, 0)
+#define MPP22_SDIO1_BUS_POWER	MPP(22, 0x3, 0, 0)
+#define MPP22_SSP_TXD		MPP(22, 0x4, 0, 0)
+#define MPP22_SDIO0_BUS_POWER	MPP(22, 0x5, 0, 0)
+#define MPP22_SPI_1_MOSI	MPP(22, 0x6, 0, 0)
 
-#define MPP21_GPIO21		MPP_PIN(21, 0x0)
-#define MPP21_UA1_RTSn		MPP_PIN(21, 0x1)
-#define MPP21_SPI_LCD_CS0	MPP_PIN(21, 0x2)
-#define MPP21_SDIO1_WP		MPP_PIN(21, 0x3)
-#define MPP21_SSP_SFRM		MPP_PIN(21, 0x4)
-#define MPP21_SDIO0_WP		MPP_PIN(21, 0x5)
-#define MPP21_SPI_1_CS		MPP_PIN(21, 0x6)
+#define MPP23_GPIO23		MPP(23, 0x0, 1, 1)
+#define MPP23_SPI_LCD_SCK	MPP(23, 0x2, 0, 0)
+#define MPP23_SDIO1_LED_CTRL	MPP(23, 0x3, 0, 0)
+#define MPP23_SSP_SCLK		MPP(23, 0x4, 0, 0)
+#define MPP23_SDIO0_LED_CTRL	MPP(23, 0x5, 0, 0)
+#define MPP23_SPI_1_SCK		MPP(23, 0x6, 0, 0)
 
-#define MPP22_GPIO22		MPP_PIN(22, 0x0)
-#define MPP22_UA1_CTSn		MPP_PIN(22, 0x1)
-#define MPP22_SPI_LCD_MOSI	MPP_PIN(22, 0x2)
-#define MPP22_SDIO1_BUS_POWER	MPP_PIN(22, 0x3)
-#define MPP22_SSP_TXD		MPP_PIN(22, 0x4)
-#define MPP22_SDIO0_BUS_POWER	MPP_PIN(22, 0x5)
-#define MPP22_SPI_1_MOSI	MPP_PIN(22, 0x6)
+#define MPP_MAX			23
 
-#define MPP23_GPIO23		MPP_PIN(23, 0x0)
-#define MPP23_SPI_LCD_SCK	MPP_PIN(23, 0x2)
-#define MPP23_SDIO1_LED_CTRL	MPP_PIN(23, 0x3)
-#define MPP23_SSP_SCLK		MPP_PIN(23, 0x4)
-#define MPP23_SDIO0_LED_CTRL	MPP_PIN(23, 0x5)
-#define MPP23_SPI_1_SCK		MPP_PIN(23, 0x6)
+#define MPP_GRP(_grp, _mode)	MPP((_grp), (_mode), 0, 0)
 
 /* for MPP groups _num is a group index */
 enum dove_mpp_grp_idx {
@@ -181,40 +153,44 @@
 	MPP_46_51 = 1,
 	MPP_58_61 = 5,
 	MPP_62_63 = 4,
+	MPP_GRP_MAX = 5,
 };
 
-#define MPP24_39_GPIO		MPP_GRP(MPP_24_39, 0x1)
-#define MPP24_39_CAM		MPP_GRP(MPP_24_39, 0x0)
+#define MPP_GRP_24_39_GPIO		MPP_GRP(MPP_24_39, 0x1)
+#define MPP_GRP_24_39_CAM		MPP_GRP(MPP_24_39, 0x0)
 
-#define MPP40_45_GPIO		MPP_GRP(MPP_40_45, 0x1)
-#define MPP40_45_SD0		MPP_GRP(MPP_40_45, 0x0)
+#define MPP_GRP_40_45_GPIO		MPP_GRP(MPP_40_45, 0x1)
+#define MPP_GRP_40_45_SD0		MPP_GRP(MPP_40_45, 0x0)
 
-#define MPP46_51_GPIO		MPP_GRP(MPP_46_51, 0x1)
-#define MPP46_51_SD1		MPP_GRP(MPP_46_51, 0x0)
+#define MPP_GRP_46_51_GPIO		MPP_GRP(MPP_46_51, 0x1)
+#define MPP_GRP_46_51_SD1		MPP_GRP(MPP_46_51, 0x0)
 
-#define MPP58_61_GPIO		MPP_GRP(MPP_58_61, 0x1)
-#define MPP58_61_SPI		MPP_GRP(MPP_58_61, 0x0)
+#define MPP_GRP_58_61_GPIO		MPP_GRP(MPP_58_61, 0x1)
+#define MPP_GRP_58_61_SPI		MPP_GRP(MPP_58_61, 0x0)
 
-#define MPP62_63_GPIO		MPP_GRP(MPP_62_63, 0x1)
-#define MPP62_63_UA1		MPP_GRP(MPP_62_63, 0x0)
+#define MPP_GRP_62_63_GPIO		MPP_GRP(MPP_62_63, 0x1)
+#define MPP_GRP_62_63_UA1		MPP_GRP(MPP_62_63, 0x0)
 
 /* The MPP[64:71] control differs from other groups */
-#define MPP64_71_GPO		MPP_GRP_NFC(0x1)
-#define MPP64_71_NFC		MPP_GRP_NFC(0x0)
+#define MPP_GRP_NFC_64_71_GPO		0x1
+#define MPP_GRP_NFC_64_71_NFC		0x0
 
 /*
  * The MPP[52:57] functionality is encoded by 4 bits in different
  * registers. The _num field in this case encodes those bits in
  * correspodence with Table 135 of 88AP510 Functional specification
  */
-#define MPP52_57_AU1		MPP_GRP_AU1(0x0)
-#define MPP52_57_AU1_GPIO57	MPP_GRP_AU1(0x2)
-#define MPP52_57_GPIO		MPP_GRP_AU1(0xa)
-#define MPP52_57_TW_GPIO	MPP_GRP_AU1(0xb)
-#define MPP52_57_AU1_SSP	MPP_GRP_AU1(0xc)
-#define MPP52_57_SSP_GPIO	MPP_GRP_AU1(0xe)
-#define MPP52_57_SSP_TW		MPP_GRP_AU1(0xf)
+#define MPP_GRP_AU1_52_57_AU1		0x0
+#define MPP_GRP_AU1_52_57_AU1_GPIO57	0x2
+#define MPP_GRP_AU1_52_57_GPIO		0xa
+#define MPP_GRP_AU1_52_57_TW_GPIO	0xb
+#define MPP_GRP_AU1_52_57_AU1_SSP	0xc
+#define MPP_GRP_AU1_52_57_SSP_GPIO	0xe
+#define MPP_GRP_AU1_52_57_SSP_TW	0xf
 
-void dove_mpp_conf(unsigned int *mpp_list);
+void dove_mpp_conf(unsigned int *mpp_list,
+		   unsigned int *mpp_grp_list,
+		   unsigned int grp_au1_52_57,
+		   unsigned int grp_nfc_64_71);
 
 #endif	/* __ARCH_DOVE_MPP_CODED_H */
diff -druN linux-2.6.39-libre/arch/arm/mach-ep93xx/core.c linux-3.0-rc7-libre/arch/arm/mach-ep93xx/core.c
--- linux-2.6.39-libre/arch/arm/mach-ep93xx/core.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-ep93xx/core.c	2011-07-11 19:51:52.000000000 -0400
@@ -251,9 +251,9 @@
 	unsigned int mcr;
 
 	mcr = 0;
-	if (!(mctrl & TIOCM_RTS))
+	if (mctrl & TIOCM_RTS)
 		mcr |= 2;
-	if (!(mctrl & TIOCM_DTR))
+	if (mctrl & TIOCM_DTR)
 		mcr |= 1;
 
 	__raw_writel(mcr, base + EP93XX_UART_MCR_OFFSET);
@@ -402,11 +402,15 @@
 	}
 };
 
+static u64 ep93xx_eth_dma_mask = DMA_BIT_MASK(32);
+
 static struct platform_device ep93xx_eth_device = {
 	.name		= "ep93xx-eth",
 	.id		= -1,
 	.dev		= {
-		.platform_data	= &ep93xx_eth_data,
+		.platform_data		= &ep93xx_eth_data,
+		.coherent_dma_mask	= DMA_BIT_MASK(32),
+		.dma_mask		= &ep93xx_eth_dma_mask,
 	},
 	.num_resources	= ARRAY_SIZE(ep93xx_eth_resource),
 	.resource	= ep93xx_eth_resource,
diff -druN linux-2.6.39-libre/arch/arm/mach-ep93xx/gpio.c linux-3.0-rc7-libre/arch/arm/mach-ep93xx/gpio.c
--- linux-2.6.39-libre/arch/arm/mach-ep93xx/gpio.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-ep93xx/gpio.c	2011-07-11 19:51:52.000000000 -0400
@@ -356,29 +356,6 @@
 	return 0;
 }
 
-static void ep93xx_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip)
-{
-	struct ep93xx_gpio_chip *ep93xx_chip = to_ep93xx_gpio_chip(chip);
-	u8 data_reg, data_dir_reg;
-	int gpio, i;
-
-	data_reg = __raw_readb(ep93xx_chip->data_reg);
-	data_dir_reg = __raw_readb(ep93xx_chip->data_dir_reg);
-
-	gpio = ep93xx_chip->chip.base;
-	for (i = 0; i < chip->ngpio; i++, gpio++) {
-		int is_out = data_dir_reg & (1 << i);
-		int irq = gpio_to_irq(gpio);
-
-		seq_printf(s, " %s%d gpio-%-3d (%-12s) %s %s %s\n",
-				chip->label, i, gpio,
-				gpiochip_is_requested(chip, i) ? : "",
-				is_out ? "out" : "in ",
-				(data_reg & (1<<  i)) ? "hi" : "lo",
-				(!is_out && irq>= 0) ? "(interrupt)" : "");
-	}
-}
-
 #define EP93XX_GPIO_BANK(name, dr, ddr, base_gpio)			\
 	{								\
 		.chip = {						\
@@ -387,7 +364,6 @@
 			.direction_output = ep93xx_gpio_direction_output, \
 			.get		  = ep93xx_gpio_get,		\
 			.set		  = ep93xx_gpio_set,		\
-			.dbg_show	  = ep93xx_gpio_dbg_show,	\
 			.base		  = base_gpio,			\
 			.ngpio		  = 8,				\
 		},							\
diff -druN linux-2.6.39-libre/arch/arm/mach-exynos4/cpu.c linux-3.0-rc7-libre/arch/arm/mach-exynos4/cpu.c
--- linux-2.6.39-libre/arch/arm/mach-exynos4/cpu.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-exynos4/cpu.c	2011-07-11 19:51:52.000000000 -0400
@@ -23,6 +23,7 @@
 #include <plat/sdhci.h>
 #include <plat/devs.h>
 #include <plat/fimc-core.h>
+#include <plat/iic-core.h>
 
 #include <mach/regs-irq.h>
 
@@ -97,7 +98,12 @@
 		.pfn		= __phys_to_pfn(EXYNOS4_PA_SROMC),
 		.length		= SZ_4K,
 		.type		= MT_DEVICE,
-	},
+	}, {
+		.virtual	= (unsigned long)S3C_VA_USB_HSPHY,
+		.pfn		= __phys_to_pfn(EXYNOS4_PA_HSPHY),
+		.length		= SZ_4K,
+		.type		= MT_DEVICE,
+	}
 };
 
 static void exynos4_idle(void)
@@ -127,6 +133,11 @@
 	s3c_fimc_setname(1, "exynos4-fimc");
 	s3c_fimc_setname(2, "exynos4-fimc");
 	s3c_fimc_setname(3, "exynos4-fimc");
+
+	/* The I2C bus controllers are directly compatible with s3c2440 */
+	s3c_i2c0_setname("s3c2440-i2c");
+	s3c_i2c1_setname("s3c2440-i2c");
+	s3c_i2c2_setname("s3c2440-i2c");
 }
 
 void __init exynos4_init_clocks(int xtal)
diff -druN linux-2.6.39-libre/arch/arm/mach-exynos4/cpuidle.c linux-3.0-rc7-libre/arch/arm/mach-exynos4/cpuidle.c
--- linux-2.6.39-libre/arch/arm/mach-exynos4/cpuidle.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/arm/mach-exynos4/cpuidle.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,86 @@
+/* linux/arch/arm/mach-exynos4/cpuidle.c
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+ *		http://www.samsung.com
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/cpuidle.h>
+#include <linux/io.h>
+
+#include <asm/proc-fns.h>
+
+static int exynos4_enter_idle(struct cpuidle_device *dev,
+			      struct cpuidle_state *state);
+
+static struct cpuidle_state exynos4_cpuidle_set[] = {
+	[0] = {
+		.enter			= exynos4_enter_idle,
+		.exit_latency		= 1,
+		.target_residency	= 100000,
+		.flags			= CPUIDLE_FLAG_TIME_VALID,
+		.name			= "IDLE",
+		.desc			= "ARM clock gating(WFI)",
+	},
+};
+
+static DEFINE_PER_CPU(struct cpuidle_device, exynos4_cpuidle_device);
+
+static struct cpuidle_driver exynos4_idle_driver = {
+	.name		= "exynos4_idle",
+	.owner		= THIS_MODULE,
+};
+
+static int exynos4_enter_idle(struct cpuidle_device *dev,
+			      struct cpuidle_state *state)
+{
+	struct timeval before, after;
+	int idle_time;
+
+	local_irq_disable();
+	do_gettimeofday(&before);
+
+	cpu_do_idle();
+
+	do_gettimeofday(&after);
+	local_irq_enable();
+	idle_time = (after.tv_sec - before.tv_sec) * USEC_PER_SEC +
+		    (after.tv_usec - before.tv_usec);
+
+	return idle_time;
+}
+
+static int __init exynos4_init_cpuidle(void)
+{
+	int i, max_cpuidle_state, cpu_id;
+	struct cpuidle_device *device;
+
+	cpuidle_register_driver(&exynos4_idle_driver);
+
+	for_each_cpu(cpu_id, cpu_online_mask) {
+		device = &per_cpu(exynos4_cpuidle_device, cpu_id);
+		device->cpu = cpu_id;
+
+		device->state_count = (sizeof(exynos4_cpuidle_set) /
+					       sizeof(struct cpuidle_state));
+
+		max_cpuidle_state = device->state_count;
+
+		for (i = 0; i < max_cpuidle_state; i++) {
+			memcpy(&device->states[i], &exynos4_cpuidle_set[i],
+					sizeof(struct cpuidle_state));
+		}
+
+		if (cpuidle_register_device(device)) {
+			printk(KERN_ERR "CPUidle register device failed\n,");
+			return -EIO;
+		}
+	}
+	return 0;
+}
+device_initcall(exynos4_init_cpuidle);
diff -druN linux-2.6.39-libre/arch/arm/mach-exynos4/dev-audio.c linux-3.0-rc7-libre/arch/arm/mach-exynos4/dev-audio.c
--- linux-2.6.39-libre/arch/arm/mach-exynos4/dev-audio.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-exynos4/dev-audio.c	2011-07-11 19:51:52.000000000 -0400
@@ -330,7 +330,7 @@
 
 static int exynos4_spdif_cfg_gpio(struct platform_device *pdev)
 {
-	s3c_gpio_cfgpin_range(EXYNOS4_GPC1(0), 2, S3C_GPIO_SFN(3));
+	s3c_gpio_cfgpin_range(EXYNOS4_GPC1(0), 2, S3C_GPIO_SFN(4));
 
 	return 0;
 }
diff -druN linux-2.6.39-libre/arch/arm/mach-exynos4/gpiolib.c linux-3.0-rc7-libre/arch/arm/mach-exynos4/gpiolib.c
--- linux-2.6.39-libre/arch/arm/mach-exynos4/gpiolib.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-exynos4/gpiolib.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,365 +0,0 @@
-/* linux/arch/arm/mach-exynos4/gpiolib.c
- *
- * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
- *		http://www.samsung.com
- *
- * EXYNOS4 - GPIOlib support
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/kernel.h>
-#include <linux/irq.h>
-#include <linux/io.h>
-#include <linux/gpio.h>
-
-#include <mach/map.h>
-
-#include <plat/gpio-core.h>
-#include <plat/gpio-cfg.h>
-#include <plat/gpio-cfg-helpers.h>
-
-static struct s3c_gpio_cfg gpio_cfg = {
-	.set_config	= s3c_gpio_setcfg_s3c64xx_4bit,
-	.set_pull	= s3c_gpio_setpull_updown,
-	.get_pull	= s3c_gpio_getpull_updown,
-};
-
-static struct s3c_gpio_cfg gpio_cfg_noint = {
-	.set_config	= s3c_gpio_setcfg_s3c64xx_4bit,
-	.set_pull	= s3c_gpio_setpull_updown,
-	.get_pull	= s3c_gpio_getpull_updown,
-};
-
-/*
- * Following are the gpio banks in v310.
- *
- * The 'config' member when left to NULL, is initialized to the default
- * structure gpio_cfg in the init function below.
- *
- * The 'base' member is also initialized in the init function below.
- * Note: The initialization of 'base' member of s3c_gpio_chip structure
- * uses the above macro and depends on the banks being listed in order here.
- */
-static struct s3c_gpio_chip exynos4_gpio_part1_4bit[] = {
-	{
-		.chip	= {
-			.base	= EXYNOS4_GPA0(0),
-			.ngpio	= EXYNOS4_GPIO_A0_NR,
-			.label	= "GPA0",
-		},
-	}, {
-		.chip	= {
-			.base	= EXYNOS4_GPA1(0),
-			.ngpio	= EXYNOS4_GPIO_A1_NR,
-			.label	= "GPA1",
-		},
-	}, {
-		.chip	= {
-			.base	= EXYNOS4_GPB(0),
-			.ngpio	= EXYNOS4_GPIO_B_NR,
-			.label	= "GPB",
-		},
-	}, {
-		.chip	= {
-			.base	= EXYNOS4_GPC0(0),
-			.ngpio	= EXYNOS4_GPIO_C0_NR,
-			.label	= "GPC0",
-		},
-	}, {
-		.chip	= {
-			.base	= EXYNOS4_GPC1(0),
-			.ngpio	= EXYNOS4_GPIO_C1_NR,
-			.label	= "GPC1",
-		},
-	}, {
-		.chip	= {
-			.base	= EXYNOS4_GPD0(0),
-			.ngpio	= EXYNOS4_GPIO_D0_NR,
-			.label	= "GPD0",
-		},
-	}, {
-		.chip	= {
-			.base	= EXYNOS4_GPD1(0),
-			.ngpio	= EXYNOS4_GPIO_D1_NR,
-			.label	= "GPD1",
-		},
-	}, {
-		.chip	= {
-			.base	= EXYNOS4_GPE0(0),
-			.ngpio	= EXYNOS4_GPIO_E0_NR,
-			.label	= "GPE0",
-		},
-	}, {
-		.chip	= {
-			.base	= EXYNOS4_GPE1(0),
-			.ngpio	= EXYNOS4_GPIO_E1_NR,
-			.label	= "GPE1",
-		},
-	}, {
-		.chip	= {
-			.base	= EXYNOS4_GPE2(0),
-			.ngpio	= EXYNOS4_GPIO_E2_NR,
-			.label	= "GPE2",
-		},
-	}, {
-		.chip	= {
-			.base	= EXYNOS4_GPE3(0),
-			.ngpio	= EXYNOS4_GPIO_E3_NR,
-			.label	= "GPE3",
-		},
-	}, {
-		.chip	= {
-			.base	= EXYNOS4_GPE4(0),
-			.ngpio	= EXYNOS4_GPIO_E4_NR,
-			.label	= "GPE4",
-		},
-	}, {
-		.chip	= {
-			.base	= EXYNOS4_GPF0(0),
-			.ngpio	= EXYNOS4_GPIO_F0_NR,
-			.label	= "GPF0",
-		},
-	}, {
-		.chip	= {
-			.base	= EXYNOS4_GPF1(0),
-			.ngpio	= EXYNOS4_GPIO_F1_NR,
-			.label	= "GPF1",
-		},
-	}, {
-		.chip	= {
-			.base	= EXYNOS4_GPF2(0),
-			.ngpio	= EXYNOS4_GPIO_F2_NR,
-			.label	= "GPF2",
-		},
-	}, {
-		.chip	= {
-			.base	= EXYNOS4_GPF3(0),
-			.ngpio	= EXYNOS4_GPIO_F3_NR,
-			.label	= "GPF3",
-		},
-	},
-};
-
-static struct s3c_gpio_chip exynos4_gpio_part2_4bit[] = {
-	{
-		.chip	= {
-			.base	= EXYNOS4_GPJ0(0),
-			.ngpio	= EXYNOS4_GPIO_J0_NR,
-			.label	= "GPJ0",
-		},
-	}, {
-		.chip	= {
-			.base	= EXYNOS4_GPJ1(0),
-			.ngpio	= EXYNOS4_GPIO_J1_NR,
-			.label	= "GPJ1",
-		},
-	}, {
-		.chip	= {
-			.base	= EXYNOS4_GPK0(0),
-			.ngpio	= EXYNOS4_GPIO_K0_NR,
-			.label	= "GPK0",
-		},
-	}, {
-		.chip	= {
-			.base	= EXYNOS4_GPK1(0),
-			.ngpio	= EXYNOS4_GPIO_K1_NR,
-			.label	= "GPK1",
-		},
-	}, {
-		.chip	= {
-			.base	= EXYNOS4_GPK2(0),
-			.ngpio	= EXYNOS4_GPIO_K2_NR,
-			.label	= "GPK2",
-		},
-	}, {
-		.chip	= {
-			.base	= EXYNOS4_GPK3(0),
-			.ngpio	= EXYNOS4_GPIO_K3_NR,
-			.label	= "GPK3",
-		},
-	}, {
-		.chip	= {
-			.base	= EXYNOS4_GPL0(0),
-			.ngpio	= EXYNOS4_GPIO_L0_NR,
-			.label	= "GPL0",
-		},
-	}, {
-		.chip	= {
-			.base	= EXYNOS4_GPL1(0),
-			.ngpio	= EXYNOS4_GPIO_L1_NR,
-			.label	= "GPL1",
-		},
-	}, {
-		.chip	= {
-			.base	= EXYNOS4_GPL2(0),
-			.ngpio	= EXYNOS4_GPIO_L2_NR,
-			.label	= "GPL2",
-		},
-	}, {
-		.config	= &gpio_cfg_noint,
-		.chip	= {
-			.base	= EXYNOS4_GPY0(0),
-			.ngpio	= EXYNOS4_GPIO_Y0_NR,
-			.label	= "GPY0",
-		},
-	}, {
-		.config	= &gpio_cfg_noint,
-		.chip	= {
-			.base	= EXYNOS4_GPY1(0),
-			.ngpio	= EXYNOS4_GPIO_Y1_NR,
-			.label	= "GPY1",
-		},
-	}, {
-		.config	= &gpio_cfg_noint,
-		.chip	= {
-			.base	= EXYNOS4_GPY2(0),
-			.ngpio	= EXYNOS4_GPIO_Y2_NR,
-			.label	= "GPY2",
-		},
-	}, {
-		.config	= &gpio_cfg_noint,
-		.chip	= {
-			.base	= EXYNOS4_GPY3(0),
-			.ngpio	= EXYNOS4_GPIO_Y3_NR,
-			.label	= "GPY3",
-		},
-	}, {
-		.config	= &gpio_cfg_noint,
-		.chip	= {
-			.base	= EXYNOS4_GPY4(0),
-			.ngpio	= EXYNOS4_GPIO_Y4_NR,
-			.label	= "GPY4",
-		},
-	}, {
-		.config	= &gpio_cfg_noint,
-		.chip	= {
-			.base	= EXYNOS4_GPY5(0),
-			.ngpio	= EXYNOS4_GPIO_Y5_NR,
-			.label	= "GPY5",
-		},
-	}, {
-		.config	= &gpio_cfg_noint,
-		.chip	= {
-			.base	= EXYNOS4_GPY6(0),
-			.ngpio	= EXYNOS4_GPIO_Y6_NR,
-			.label	= "GPY6",
-		},
-	}, {
-		.base	= (S5P_VA_GPIO2 + 0xC00),
-		.config	= &gpio_cfg_noint,
-		.irq_base = IRQ_EINT(0),
-		.chip	= {
-			.base	= EXYNOS4_GPX0(0),
-			.ngpio	= EXYNOS4_GPIO_X0_NR,
-			.label	= "GPX0",
-			.to_irq	= samsung_gpiolib_to_irq,
-		},
-	}, {
-		.base	= (S5P_VA_GPIO2 + 0xC20),
-		.config	= &gpio_cfg_noint,
-		.irq_base = IRQ_EINT(8),
-		.chip	= {
-			.base	= EXYNOS4_GPX1(0),
-			.ngpio	= EXYNOS4_GPIO_X1_NR,
-			.label	= "GPX1",
-			.to_irq	= samsung_gpiolib_to_irq,
-		},
-	}, {
-		.base	= (S5P_VA_GPIO2 + 0xC40),
-		.config	= &gpio_cfg_noint,
-		.irq_base = IRQ_EINT(16),
-		.chip	= {
-			.base	= EXYNOS4_GPX2(0),
-			.ngpio	= EXYNOS4_GPIO_X2_NR,
-			.label	= "GPX2",
-			.to_irq	= samsung_gpiolib_to_irq,
-		},
-	}, {
-		.base	= (S5P_VA_GPIO2 + 0xC60),
-		.config	= &gpio_cfg_noint,
-		.irq_base = IRQ_EINT(24),
-		.chip	= {
-			.base	= EXYNOS4_GPX3(0),
-			.ngpio	= EXYNOS4_GPIO_X3_NR,
-			.label	= "GPX3",
-			.to_irq	= samsung_gpiolib_to_irq,
-		},
-	},
-};
-
-static struct s3c_gpio_chip exynos4_gpio_part3_4bit[] = {
-	{
-		.chip	= {
-			.base	= EXYNOS4_GPZ(0),
-			.ngpio	= EXYNOS4_GPIO_Z_NR,
-			.label	= "GPZ",
-		},
-	},
-};
-
-static __init int exynos4_gpiolib_init(void)
-{
-	struct s3c_gpio_chip *chip;
-	int i;
-	int group = 0;
-	int nr_chips;
-
-	/* GPIO part 1 */
-
-	chip = exynos4_gpio_part1_4bit;
-	nr_chips = ARRAY_SIZE(exynos4_gpio_part1_4bit);
-
-	for (i = 0; i < nr_chips; i++, chip++) {
-		if (chip->config == NULL) {
-			chip->config = &gpio_cfg;
-			/* Assign the GPIO interrupt group */
-			chip->group = group++;
-		}
-		if (chip->base == NULL)
-			chip->base = S5P_VA_GPIO1 + (i) * 0x20;
-	}
-
-	samsung_gpiolib_add_4bit_chips(exynos4_gpio_part1_4bit, nr_chips);
-
-	/* GPIO part 2 */
-
-	chip = exynos4_gpio_part2_4bit;
-	nr_chips = ARRAY_SIZE(exynos4_gpio_part2_4bit);
-
-	for (i = 0; i < nr_chips; i++, chip++) {
-		if (chip->config == NULL) {
-			chip->config = &gpio_cfg;
-			/* Assign the GPIO interrupt group */
-			chip->group = group++;
-		}
-		if (chip->base == NULL)
-			chip->base = S5P_VA_GPIO2 + (i) * 0x20;
-	}
-
-	samsung_gpiolib_add_4bit_chips(exynos4_gpio_part2_4bit, nr_chips);
-
-	/* GPIO part 3 */
-
-	chip = exynos4_gpio_part3_4bit;
-	nr_chips = ARRAY_SIZE(exynos4_gpio_part3_4bit);
-
-	for (i = 0; i < nr_chips; i++, chip++) {
-		if (chip->config == NULL) {
-			chip->config = &gpio_cfg;
-			/* Assign the GPIO interrupt group */
-			chip->group = group++;
-		}
-		if (chip->base == NULL)
-			chip->base = S5P_VA_GPIO3 + (i) * 0x20;
-	}
-
-	samsung_gpiolib_add_4bit_chips(exynos4_gpio_part3_4bit, nr_chips);
-	s5p_register_gpioint_bank(IRQ_GPIO_XA, 0, IRQ_GPIO1_NR_GROUPS);
-	s5p_register_gpioint_bank(IRQ_GPIO_XB, IRQ_GPIO1_NR_GROUPS, IRQ_GPIO2_NR_GROUPS);
-
-	return 0;
-}
-core_initcall(exynos4_gpiolib_init);
diff -druN linux-2.6.39-libre/arch/arm/mach-exynos4/headsmp.S linux-3.0-rc7-libre/arch/arm/mach-exynos4/headsmp.S
--- linux-2.6.39-libre/arch/arm/mach-exynos4/headsmp.S	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-exynos4/headsmp.S	2011-07-11 19:51:52.000000000 -0400
@@ -13,7 +13,7 @@
 #include <linux/linkage.h>
 #include <linux/init.h>
 
-	__INIT
+	__CPUINIT
 
 /*
  * exynos4 specific entry point for secondary CPUs.  This provides
diff -druN linux-2.6.39-libre/arch/arm/mach-exynos4/include/mach/map.h linux-3.0-rc7-libre/arch/arm/mach-exynos4/include/mach/map.h
--- linux-2.6.39-libre/arch/arm/mach-exynos4/include/mach/map.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-exynos4/include/mach/map.h	2011-07-11 19:51:52.000000000 -0400
@@ -101,6 +101,9 @@
 
 #define EXYNOS4_PA_SROMC		0x12570000
 
+#define EXYNOS4_PA_EHCI			0x12580000
+#define EXYNOS4_PA_HSPHY		0x125B0000
+
 #define EXYNOS4_PA_UART			0x13800000
 
 #define EXYNOS4_PA_IIC(x)		(0x13860000 + ((x) * 0x10000))
@@ -143,6 +146,7 @@
 #define S5P_PA_SROMC			EXYNOS4_PA_SROMC
 #define S5P_PA_SYSCON			EXYNOS4_PA_SYSCON
 #define S5P_PA_TIMER			EXYNOS4_PA_TIMER
+#define S5P_PA_EHCI			EXYNOS4_PA_EHCI
 
 #define SAMSUNG_PA_KEYPAD		EXYNOS4_PA_KEYPAD
 
diff -druN linux-2.6.39-libre/arch/arm/mach-exynos4/include/mach/regs-pmu.h linux-3.0-rc7-libre/arch/arm/mach-exynos4/include/mach/regs-pmu.h
--- linux-2.6.39-libre/arch/arm/mach-exynos4/include/mach/regs-pmu.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-exynos4/include/mach/regs-pmu.h	2011-07-11 19:51:52.000000000 -0400
@@ -33,6 +33,9 @@
 #define S5P_EINT_WAKEUP_MASK			S5P_PMUREG(0x0604)
 #define S5P_WAKEUP_MASK				S5P_PMUREG(0x0608)
 
+#define S5P_USBHOST_PHY_CONTROL			S5P_PMUREG(0x0708)
+#define S5P_USBHOST_PHY_ENABLE			(1 << 0)
+
 #define S5P_MIPI_DPHY_CONTROL(n)		S5P_PMUREG(0x0710 + (n) * 4)
 #define S5P_MIPI_DPHY_ENABLE			(1 << 0)
 #define S5P_MIPI_DPHY_SRESETN			(1 << 1)
diff -druN linux-2.6.39-libre/arch/arm/mach-exynos4/include/mach/regs-usb-phy.h linux-3.0-rc7-libre/arch/arm/mach-exynos4/include/mach/regs-usb-phy.h
--- linux-2.6.39-libre/arch/arm/mach-exynos4/include/mach/regs-usb-phy.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/arm/mach-exynos4/include/mach/regs-usb-phy.h	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2011 Samsung Electronics Co.Ltd
+ * Author: Joonyoung Shim <jy0922.shim@samsung.com>
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+#ifndef __PLAT_S5P_REGS_USB_PHY_H
+#define __PLAT_S5P_REGS_USB_PHY_H
+
+#define EXYNOS4_HSOTG_PHYREG(x)		((x) + S3C_VA_USB_HSPHY)
+
+#define EXYNOS4_PHYPWR			EXYNOS4_HSOTG_PHYREG(0x00)
+#define PHY1_HSIC_NORMAL_MASK		(0xf << 9)
+#define PHY1_HSIC1_SLEEP		(1 << 12)
+#define PHY1_HSIC1_FORCE_SUSPEND	(1 << 11)
+#define PHY1_HSIC0_SLEEP		(1 << 10)
+#define PHY1_HSIC0_FORCE_SUSPEND	(1 << 9)
+
+#define PHY1_STD_NORMAL_MASK		(0x7 << 6)
+#define PHY1_STD_SLEEP			(1 << 8)
+#define PHY1_STD_ANALOG_POWERDOWN	(1 << 7)
+#define PHY1_STD_FORCE_SUSPEND		(1 << 6)
+
+#define PHY0_NORMAL_MASK		(0x39 << 0)
+#define PHY0_SLEEP			(1 << 5)
+#define PHY0_OTG_DISABLE		(1 << 4)
+#define PHY0_ANALOG_POWERDOWN		(1 << 3)
+#define PHY0_FORCE_SUSPEND		(1 << 0)
+
+#define EXYNOS4_PHYCLK			EXYNOS4_HSOTG_PHYREG(0x04)
+#define PHY1_COMMON_ON_N		(1 << 7)
+#define PHY0_COMMON_ON_N		(1 << 4)
+#define PHY0_ID_PULLUP			(1 << 2)
+#define CLKSEL_MASK			(0x3 << 0)
+#define CLKSEL_SHIFT			(0)
+#define CLKSEL_48M			(0x0 << 0)
+#define CLKSEL_12M			(0x2 << 0)
+#define CLKSEL_24M			(0x3 << 0)
+
+#define EXYNOS4_RSTCON			EXYNOS4_HSOTG_PHYREG(0x08)
+#define HOST_LINK_PORT_SWRST_MASK	(0xf << 6)
+#define HOST_LINK_PORT2_SWRST		(1 << 9)
+#define HOST_LINK_PORT1_SWRST		(1 << 8)
+#define HOST_LINK_PORT0_SWRST		(1 << 7)
+#define HOST_LINK_ALL_SWRST		(1 << 6)
+
+#define PHY1_SWRST_MASK			(0x7 << 3)
+#define PHY1_HSIC_SWRST			(1 << 5)
+#define PHY1_STD_SWRST			(1 << 4)
+#define PHY1_ALL_SWRST			(1 << 3)
+
+#define PHY0_SWRST_MASK			(0x7 << 0)
+#define PHY0_PHYLINK_SWRST		(1 << 2)
+#define PHY0_HLINK_SWRST		(1 << 1)
+#define PHY0_SWRST			(1 << 0)
+
+#define EXYNOS4_PHY1CON			EXYNOS4_HSOTG_PHYREG(0x34)
+#define FPENABLEN			(1 << 0)
+
+#endif /* __PLAT_S5P_REGS_USB_PHY_H */
diff -druN linux-2.6.39-libre/arch/arm/mach-exynos4/include/mach/smp.h linux-3.0-rc7-libre/arch/arm/mach-exynos4/include/mach/smp.h
--- linux-2.6.39-libre/arch/arm/mach-exynos4/include/mach/smp.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-exynos4/include/mach/smp.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,19 +0,0 @@
-/* linux/arch/arm/mach-exynos4/include/mach/smp.h
- *
- * Cloned from arch/arm/mach-realview/include/mach/smp.h
-*/
-
-#ifndef ASM_ARCH_SMP_H
-#define ASM_ARCH_SMP_H __FILE__
-
-#include <asm/hardware/gic.h>
-
-/*
- * We use IRQ1 as the IPI
- */
-static inline void smp_cross_call(const struct cpumask *mask, int ipi)
-{
-	gic_raise_softirq(mask, ipi);
-}
-
-#endif
diff -druN linux-2.6.39-libre/arch/arm/mach-exynos4/init.c linux-3.0-rc7-libre/arch/arm/mach-exynos4/init.c
--- linux-2.6.39-libre/arch/arm/mach-exynos4/init.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-exynos4/init.c	2011-07-11 19:51:52.000000000 -0400
@@ -35,6 +35,7 @@
 			tcfg->clocks = exynos4_serial_clocks;
 			tcfg->clocks_size = ARRAY_SIZE(exynos4_serial_clocks);
 		}
+		tcfg->flags |= NO_NEED_CHECK_CLKSRC;
 	}
 
 	s3c24xx_init_uartdevs("s5pv210-uart", s5p_uart_resources, cfg, no);
diff -druN linux-2.6.39-libre/arch/arm/mach-exynos4/irq-combiner.c linux-3.0-rc7-libre/arch/arm/mach-exynos4/irq-combiner.c
--- linux-2.6.39-libre/arch/arm/mach-exynos4/irq-combiner.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-exynos4/irq-combiner.c	2011-07-11 19:51:52.000000000 -0400
@@ -59,8 +59,7 @@
 	unsigned int cascade_irq, combiner_irq;
 	unsigned long status;
 
-	/* primary controller ack'ing */
-	chip->irq_ack(&desc->irq_data);
+	chained_irq_enter(chip, desc);
 
 	spin_lock(&irq_controller_lock);
 	status = __raw_readl(chip_data->base + COMBINER_INT_STATUS);
@@ -79,8 +78,7 @@
 		generic_handle_irq(cascade_irq);
 
  out:
-	/* primary controller unmasking */
-	chip->irq_unmask(&desc->irq_data);
+	chained_irq_exit(chip, desc);
 }
 
 static struct irq_chip combiner_chip = {
diff -druN linux-2.6.39-libre/arch/arm/mach-exynos4/Kconfig linux-3.0-rc7-libre/arch/arm/mach-exynos4/Kconfig
--- linux-2.6.39-libre/arch/arm/mach-exynos4/Kconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-exynos4/Kconfig	2011-07-11 19:51:52.000000000 -0400
@@ -91,6 +91,11 @@
 	help
 	  Common setup code for the camera interfaces.
 
+config EXYNOS4_SETUP_USB_PHY
+	bool
+	help
+	  Common setup code for USB PHY controller
+
 # machine support
 
 menu "EXYNOS4 Machines"
@@ -169,10 +174,14 @@
 	select S3C_DEV_HSMMC2
 	select S3C_DEV_HSMMC3
 	select S3C_DEV_I2C1
+	select S3C_DEV_I2C3
 	select S3C_DEV_I2C5
+	select S5P_DEV_USB_EHCI
 	select EXYNOS4_SETUP_I2C1
+	select EXYNOS4_SETUP_I2C3
 	select EXYNOS4_SETUP_I2C5
 	select EXYNOS4_SETUP_SDHCI
+	select EXYNOS4_SETUP_USB_PHY
 	select SAMSUNG_DEV_PWM
 	help
 	  Machine support for Samsung Mobile NURI Board.
diff -druN linux-2.6.39-libre/arch/arm/mach-exynos4/mach-nuri.c linux-3.0-rc7-libre/arch/arm/mach-exynos4/mach-nuri.c
--- linux-2.6.39-libre/arch/arm/mach-exynos4/mach-nuri.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-exynos4/mach-nuri.c	2011-07-11 19:51:52.000000000 -0400
@@ -12,6 +12,7 @@
 #include <linux/serial_core.h>
 #include <linux/input.h>
 #include <linux/i2c.h>
+#include <linux/i2c/atmel_mxt_ts.h>
 #include <linux/gpio_keys.h>
 #include <linux/gpio.h>
 #include <linux/regulator/machine.h>
@@ -30,6 +31,10 @@
 #include <plat/cpu.h>
 #include <plat/devs.h>
 #include <plat/sdhci.h>
+#include <plat/ehci.h>
+#include <plat/clock.h>
+#include <plat/gpio-cfg.h>
+#include <plat/iic.h>
 
 #include <mach/map.h>
 
@@ -257,11 +262,103 @@
 	/* Gyro, To be updated */
 };
 
+/* TSP */
+static u8 mxt_init_vals[] = {
+	/* MXT_GEN_COMMAND(6) */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	/* MXT_GEN_POWER(7) */
+	0x20, 0xff, 0x32,
+	/* MXT_GEN_ACQUIRE(8) */
+	0x0a, 0x00, 0x05, 0x00, 0x00, 0x00, 0x09, 0x23,
+	/* MXT_TOUCH_MULTI(9) */
+	0x00, 0x00, 0x00, 0x13, 0x0b, 0x00, 0x00, 0x00, 0x02, 0x00,
+	0x00, 0x01, 0x01, 0x0e, 0x0a, 0x0a, 0x0a, 0x0a, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00,
+	/* MXT_TOUCH_KEYARRAY(15) */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
+	0x00,
+	/* MXT_SPT_GPIOPWM(19) */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	/* MXT_PROCI_GRIPFACE(20) */
+	0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x28, 0x04,
+	0x0f, 0x0a,
+	/* MXT_PROCG_NOISE(22) */
+	0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x23, 0x00,
+	0x00, 0x05, 0x0f, 0x19, 0x23, 0x2d, 0x03,
+	/* MXT_TOUCH_PROXIMITY(23) */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00,
+	/* MXT_PROCI_ONETOUCH(24) */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	/* MXT_SPT_SELFTEST(25) */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,
+	/* MXT_PROCI_TWOTOUCH(27) */
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	/* MXT_SPT_CTECONFIG(28) */
+	0x00, 0x00, 0x02, 0x08, 0x10, 0x00,
+};
+
+static struct mxt_platform_data mxt_platform_data = {
+	.config			= mxt_init_vals,
+	.config_length		= ARRAY_SIZE(mxt_init_vals),
+
+	.x_line			= 18,
+	.y_line			= 11,
+	.x_size			= 1024,
+	.y_size			= 600,
+	.blen			= 0x1,
+	.threshold		= 0x28,
+	.voltage		= 2800000,		/* 2.8V */
+	.orient			= MXT_DIAGONAL_COUNTER,
+	.irqflags		= IRQF_TRIGGER_FALLING,
+};
+
+static struct s3c2410_platform_i2c i2c3_data __initdata = {
+	.flags		= 0,
+	.bus_num	= 3,
+	.slave_addr	= 0x10,
+	.frequency	= 400 * 1000,
+	.sda_delay	= 100,
+};
+
+static struct i2c_board_info i2c3_devs[] __initdata = {
+	{
+		I2C_BOARD_INFO("atmel_mxt_ts", 0x4a),
+		.platform_data	= &mxt_platform_data,
+		.irq		= IRQ_EINT(4),
+	},
+};
+
+static void __init nuri_tsp_init(void)
+{
+	int gpio;
+
+	/* TOUCH_INT: XEINT_4 */
+	gpio = EXYNOS4_GPX0(4);
+	gpio_request(gpio, "TOUCH_INT");
+	s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(0xf));
+	s3c_gpio_setpull(gpio, S3C_GPIO_PULL_UP);
+}
+
 /* GPIO I2C 5 (PMIC) */
 static struct i2c_board_info i2c5_devs[] __initdata = {
 	/* max8997, To be updated */
 };
 
+/* USB EHCI */
+static struct s5p_ehci_platdata nuri_ehci_pdata;
+
+static void __init nuri_ehci_init(void)
+{
+	struct s5p_ehci_platdata *pdata = &nuri_ehci_pdata;
+
+	s5p_ehci_set_platdata(pdata);
+}
+
 static struct platform_device *nuri_devices[] __initdata = {
 	/* Samsung Platform Devices */
 	&emmc_fixed_voltage,
@@ -270,6 +367,8 @@
 	&s3c_device_hsmmc3,
 	&s3c_device_wdt,
 	&s3c_device_timer[0],
+	&s5p_device_ehci,
+	&s3c_device_i2c3,
 
 	/* NURI Devices */
 	&nuri_gpio_keys,
@@ -287,10 +386,16 @@
 static void __init nuri_machine_init(void)
 {
 	nuri_sdhci_init();
+	nuri_tsp_init();
 
 	i2c_register_board_info(1, i2c1_devs, ARRAY_SIZE(i2c1_devs));
+	s3c_i2c3_set_platdata(&i2c3_data);
+	i2c_register_board_info(3, i2c3_devs, ARRAY_SIZE(i2c3_devs));
 	i2c_register_board_info(5, i2c5_devs, ARRAY_SIZE(i2c5_devs));
 
+	nuri_ehci_init();
+	clk_xusbxti.rate = 24000000;
+
 	/* Last */
 	platform_add_devices(nuri_devices, ARRAY_SIZE(nuri_devices));
 }
diff -druN linux-2.6.39-libre/arch/arm/mach-exynos4/mach-smdkv310.c linux-3.0-rc7-libre/arch/arm/mach-exynos4/mach-smdkv310.c
--- linux-2.6.39-libre/arch/arm/mach-exynos4/mach-smdkv310.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-exynos4/mach-smdkv310.c	2011-07-11 19:51:52.000000000 -0400
@@ -78,9 +78,7 @@
 };
 
 static struct s3c_sdhci_platdata smdkv310_hsmmc0_pdata __initdata = {
-	.cd_type		= S3C_SDHCI_CD_GPIO,
-	.ext_cd_gpio		= EXYNOS4_GPK0(2),
-	.ext_cd_gpio_invert	= 1,
+	.cd_type		= S3C_SDHCI_CD_INTERNAL,
 	.clk_type		= S3C_SDHCI_CLK_DIV_EXTERNAL,
 #ifdef CONFIG_EXYNOS4_SDHCI_CH0_8BIT
 	.max_width		= 8,
@@ -96,9 +94,7 @@
 };
 
 static struct s3c_sdhci_platdata smdkv310_hsmmc2_pdata __initdata = {
-	.cd_type		= S3C_SDHCI_CD_GPIO,
-	.ext_cd_gpio		= EXYNOS4_GPK2(2),
-	.ext_cd_gpio_invert	= 1,
+	.cd_type		= S3C_SDHCI_CD_INTERNAL,
 	.clk_type		= S3C_SDHCI_CLK_DIV_EXTERNAL,
 #ifdef CONFIG_EXYNOS4_SDHCI_CH2_8BIT
 	.max_width		= 8,
diff -druN linux-2.6.39-libre/arch/arm/mach-exynos4/Makefile linux-3.0-rc7-libre/arch/arm/mach-exynos4/Makefile
--- linux-2.6.39-libre/arch/arm/mach-exynos4/Makefile	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-exynos4/Makefile	2011-07-11 19:51:52.000000000 -0400
@@ -13,9 +13,10 @@
 # Core support for EXYNOS4 system
 
 obj-$(CONFIG_CPU_EXYNOS4210)	+= cpu.o init.o clock.o irq-combiner.o
-obj-$(CONFIG_CPU_EXYNOS4210)	+= setup-i2c0.o gpiolib.o irq-eint.o dma.o
+obj-$(CONFIG_CPU_EXYNOS4210)	+= setup-i2c0.o irq-eint.o dma.o
 obj-$(CONFIG_PM)		+= pm.o sleep.o
 obj-$(CONFIG_CPU_FREQ)		+= cpufreq.o
+obj-$(CONFIG_CPU_IDLE)		+= cpuidle.o
 
 obj-$(CONFIG_SMP)		+= platsmp.o headsmp.o
 
@@ -54,3 +55,5 @@
 obj-$(CONFIG_EXYNOS4_SETUP_KEYPAD)	+= setup-keypad.o
 obj-$(CONFIG_EXYNOS4_SETUP_SDHCI)	+= setup-sdhci.o
 obj-$(CONFIG_EXYNOS4_SETUP_SDHCI_GPIO)	+= setup-sdhci-gpio.o
+
+obj-$(CONFIG_EXYNOS4_SETUP_USB_PHY)	+= setup-usb-phy.o
diff -druN linux-2.6.39-libre/arch/arm/mach-exynos4/platsmp.c linux-3.0-rc7-libre/arch/arm/mach-exynos4/platsmp.c
--- linux-2.6.39-libre/arch/arm/mach-exynos4/platsmp.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-exynos4/platsmp.c	2011-07-11 19:51:52.000000000 -0400
@@ -22,6 +22,7 @@
 #include <linux/io.h>
 
 #include <asm/cacheflush.h>
+#include <asm/hardware/gic.h>
 #include <asm/smp_scu.h>
 #include <asm/unified.h>
 
@@ -104,7 +105,7 @@
 	 * the boot monitor to read the system wide flags register,
 	 * and branch to the address found there.
 	 */
-	smp_cross_call(cpumask_of(cpu), 1);
+	gic_raise_softirq(cpumask_of(cpu), 1);
 
 	timeout = jiffies + (1 * HZ);
 	while (time_before(jiffies, timeout)) {
@@ -147,6 +148,8 @@
 
 	for (i = 0; i < ncores; i++)
 		set_cpu_possible(i, true);
+
+	set_smp_cross_call(gic_raise_softirq);
 }
 
 void __init platform_smp_prepare_cpus(unsigned int max_cpus)
diff -druN linux-2.6.39-libre/arch/arm/mach-exynos4/pm.c linux-3.0-rc7-libre/arch/arm/mach-exynos4/pm.c
--- linux-2.6.39-libre/arch/arm/mach-exynos4/pm.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-exynos4/pm.c	2011-07-11 19:51:52.000000000 -0400
@@ -16,6 +16,7 @@
 
 #include <linux/init.h>
 #include <linux/suspend.h>
+#include <linux/syscore_ops.h>
 #include <linux/io.h>
 
 #include <asm/cacheflush.h>
@@ -372,7 +373,27 @@
 	flush_cache_all();
 }
 
-static int exynos4_pm_resume(struct sys_device *dev)
+static struct sysdev_driver exynos4_pm_driver = {
+	.add		= exynos4_pm_add,
+};
+
+static __init int exynos4_pm_drvinit(void)
+{
+	unsigned int tmp;
+
+	s3c_pm_init();
+
+	/* All wakeup disable */
+
+	tmp = __raw_readl(S5P_WAKEUP_MASK);
+	tmp |= ((0xFF << 8) | (0x1F << 1));
+	__raw_writel(tmp, S5P_WAKEUP_MASK);
+
+	return sysdev_driver_register(&exynos4_sysclass, &exynos4_pm_driver);
+}
+arch_initcall(exynos4_pm_drvinit);
+
+static void exynos4_pm_resume(void)
 {
 	/* For release retention */
 
@@ -394,27 +415,15 @@
 	/* enable L2X0*/
 	writel_relaxed(1, S5P_VA_L2CC + L2X0_CTRL);
 #endif
-
-	return 0;
 }
 
-static struct sysdev_driver exynos4_pm_driver = {
-	.add		= exynos4_pm_add,
+static struct syscore_ops exynos4_pm_syscore_ops = {
 	.resume		= exynos4_pm_resume,
 };
 
-static __init int exynos4_pm_drvinit(void)
+static __init int exynos4_pm_syscore_init(void)
 {
-	unsigned int tmp;
-
-	s3c_pm_init();
-
-	/* All wakeup disable */
-
-	tmp = __raw_readl(S5P_WAKEUP_MASK);
-	tmp |= ((0xFF << 8) | (0x1F << 1));
-	__raw_writel(tmp, S5P_WAKEUP_MASK);
-
-	return sysdev_driver_register(&exynos4_sysclass, &exynos4_pm_driver);
+	register_syscore_ops(&exynos4_pm_syscore_ops);
+	return 0;
 }
-arch_initcall(exynos4_pm_drvinit);
+arch_initcall(exynos4_pm_syscore_init);
diff -druN linux-2.6.39-libre/arch/arm/mach-exynos4/setup-usb-phy.c linux-3.0-rc7-libre/arch/arm/mach-exynos4/setup-usb-phy.c
--- linux-2.6.39-libre/arch/arm/mach-exynos4/setup-usb-phy.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/arm/mach-exynos4/setup-usb-phy.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,136 @@
+/*
+ * Copyright (C) 2011 Samsung Electronics Co.Ltd
+ * Author: Joonyoung Shim <jy0922.shim@samsung.com>
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ */
+
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/platform_device.h>
+#include <mach/regs-pmu.h>
+#include <mach/regs-usb-phy.h>
+#include <plat/cpu.h>
+#include <plat/usb-phy.h>
+
+static int exynos4_usb_phy1_init(struct platform_device *pdev)
+{
+	struct clk *otg_clk;
+	struct clk *xusbxti_clk;
+	u32 phyclk;
+	u32 rstcon;
+	int err;
+
+	otg_clk = clk_get(&pdev->dev, "otg");
+	if (IS_ERR(otg_clk)) {
+		dev_err(&pdev->dev, "Failed to get otg clock\n");
+		return PTR_ERR(otg_clk);
+	}
+
+	err = clk_enable(otg_clk);
+	if (err) {
+		clk_put(otg_clk);
+		return err;
+	}
+
+	writel(readl(S5P_USBHOST_PHY_CONTROL) | S5P_USBHOST_PHY_ENABLE,
+			S5P_USBHOST_PHY_CONTROL);
+
+	/* set clock frequency for PLL */
+	phyclk = readl(EXYNOS4_PHYCLK) & ~CLKSEL_MASK;
+
+	xusbxti_clk = clk_get(&pdev->dev, "xusbxti");
+	if (xusbxti_clk && !IS_ERR(xusbxti_clk)) {
+		switch (clk_get_rate(xusbxti_clk)) {
+		case 12 * MHZ:
+			phyclk |= CLKSEL_12M;
+			break;
+		case 24 * MHZ:
+			phyclk |= CLKSEL_24M;
+			break;
+		default:
+		case 48 * MHZ:
+			/* default reference clock */
+			break;
+		}
+		clk_put(xusbxti_clk);
+	}
+
+	writel(phyclk, EXYNOS4_PHYCLK);
+
+	/* floating prevention logic: disable */
+	writel((readl(EXYNOS4_PHY1CON) | FPENABLEN), EXYNOS4_PHY1CON);
+
+	/* set to normal HSIC 0 and 1 of PHY1 */
+	writel((readl(EXYNOS4_PHYPWR) & ~PHY1_HSIC_NORMAL_MASK),
+			EXYNOS4_PHYPWR);
+
+	/* set to normal standard USB of PHY1 */
+	writel((readl(EXYNOS4_PHYPWR) & ~PHY1_STD_NORMAL_MASK), EXYNOS4_PHYPWR);
+
+	/* reset all ports of both PHY and Link */
+	rstcon = readl(EXYNOS4_RSTCON) | HOST_LINK_PORT_SWRST_MASK |
+		PHY1_SWRST_MASK;
+	writel(rstcon, EXYNOS4_RSTCON);
+	udelay(10);
+
+	rstcon &= ~(HOST_LINK_PORT_SWRST_MASK | PHY1_SWRST_MASK);
+	writel(rstcon, EXYNOS4_RSTCON);
+	udelay(50);
+
+	clk_disable(otg_clk);
+	clk_put(otg_clk);
+
+	return 0;
+}
+
+static int exynos4_usb_phy1_exit(struct platform_device *pdev)
+{
+	struct clk *otg_clk;
+	int err;
+
+	otg_clk = clk_get(&pdev->dev, "otg");
+	if (IS_ERR(otg_clk)) {
+		dev_err(&pdev->dev, "Failed to get otg clock\n");
+		return PTR_ERR(otg_clk);
+	}
+
+	err = clk_enable(otg_clk);
+	if (err) {
+		clk_put(otg_clk);
+		return err;
+	}
+
+	writel((readl(EXYNOS4_PHYPWR) | PHY1_STD_ANALOG_POWERDOWN),
+			EXYNOS4_PHYPWR);
+
+	writel(readl(S5P_USBHOST_PHY_CONTROL) & ~S5P_USBHOST_PHY_ENABLE,
+			S5P_USBHOST_PHY_CONTROL);
+
+	clk_disable(otg_clk);
+	clk_put(otg_clk);
+
+	return 0;
+}
+
+int s5p_usb_phy_init(struct platform_device *pdev, int type)
+{
+	if (type == S5P_USB_PHY_HOST)
+		return exynos4_usb_phy1_init(pdev);
+
+	return -EINVAL;
+}
+
+int s5p_usb_phy_exit(struct platform_device *pdev, int type)
+{
+	if (type == S5P_USB_PHY_HOST)
+		return exynos4_usb_phy1_exit(pdev);
+
+	return -EINVAL;
+}
diff -druN linux-2.6.39-libre/arch/arm/mach-exynos4/time.c linux-3.0-rc7-libre/arch/arm/mach-exynos4/time.c
--- linux-2.6.39-libre/arch/arm/mach-exynos4/time.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-exynos4/time.c	2011-07-11 19:51:52.000000000 -0400
@@ -206,6 +206,7 @@
 	return (cycle_t) ~__raw_readl(S3C_TIMERREG(0x40));
 }
 
+#ifdef CONFIG_PM
 static void exynos4_pwm4_resume(struct clocksource *cs)
 {
 	unsigned long pclk;
@@ -218,6 +219,7 @@
 	exynos4_pwm_init(4, ~0);
 	exynos4_pwm_start(4, 1);
 }
+#endif
 
 struct clocksource pwm_clocksource = {
 	.name		= "pwm_timer4",
diff -druN linux-2.6.39-libre/arch/arm/mach-footbridge/dc21285-timer.c linux-3.0-rc7-libre/arch/arm/mach-footbridge/dc21285-timer.c
--- linux-2.6.39-libre/arch/arm/mach-footbridge/dc21285-timer.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-footbridge/dc21285-timer.c	2011-07-11 19:51:52.000000000 -0400
@@ -103,6 +103,7 @@
 	clockevents_calc_mult_shift(ce, mem_fclk_21285, 5);
 	ce->max_delta_ns = clockevent_delta2ns(0xffffff, ce);
 	ce->min_delta_ns = clockevent_delta2ns(0x000004, ce);
+	ce->cpumask = cpumask_of(smp_processor_id());
 
 	clockevents_register_device(ce);
 }
diff -druN linux-2.6.39-libre/arch/arm/mach-footbridge/include/mach/debug-macro.S linux-3.0-rc7-libre/arch/arm/mach-footbridge/include/mach/debug-macro.S
--- linux-2.6.39-libre/arch/arm/mach-footbridge/include/mach/debug-macro.S	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-footbridge/include/mach/debug-macro.S	2011-07-11 19:51:52.000000000 -0400
@@ -26,6 +26,7 @@
 #include <asm/hardware/debug-8250.S>
 
 #else
+#include <mach/hardware.h>
 	/* For EBSA285 debugging */
 		.equ	dc21285_high, ARMCSR_BASE & 0xff000000
 		.equ	dc21285_low,  ARMCSR_BASE & 0x00ffffff
@@ -36,8 +37,8 @@
 		.else
 		mov	\rp, #0
 		.endif
-		orr	\rv, \rp, #0x42000000
-		orr	\rp, \rp, #dc21285_high
+		orr	\rv, \rp, #dc21285_high
+		orr	\rp, \rp, #0x42000000
 		.endm
 
 		.macro	senduart,rd,rx
diff -druN linux-2.6.39-libre/arch/arm/mach-footbridge/isa-timer.c linux-3.0-rc7-libre/arch/arm/mach-footbridge/isa-timer.c
--- linux-2.6.39-libre/arch/arm/mach-footbridge/isa-timer.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-footbridge/isa-timer.c	2011-07-11 19:51:52.000000000 -0400
@@ -10,53 +10,16 @@
 #include <linux/interrupt.h>
 #include <linux/irq.h>
 #include <linux/io.h>
+#include <linux/spinlock.h>
 #include <linux/timex.h>
 
 #include <asm/irq.h>
-
+#include <asm/i8253.h>
 #include <asm/mach/time.h>
 
 #include "common.h"
 
-#define PIT_MODE	0x43
-#define PIT_CH0		0x40
-
-#define PIT_LATCH	((PIT_TICK_RATE + HZ / 2) / HZ)
-
-static cycle_t pit_read(struct clocksource *cs)
-{
-	unsigned long flags;
-	static int old_count;
-	static u32 old_jifs;
-	int count;
-	u32 jifs;
-
-	raw_local_irq_save(flags);
-
-	jifs = jiffies;
-	outb_p(0x00, PIT_MODE);		/* latch the count */
-	count = inb_p(PIT_CH0);		/* read the latched count */
-	count |= inb_p(PIT_CH0) << 8;
-
-	if (count > old_count && jifs == old_jifs)
-		count = old_count;
-
-	old_count = count;
-	old_jifs = jifs;
-
-	raw_local_irq_restore(flags);
-
-	count = (PIT_LATCH - 1) - count;
-
-	return (cycle_t)(jifs * PIT_LATCH) + count;
-}
-
-static struct clocksource pit_cs = {
-	.name		= "pit",
-	.rating		= 110,
-	.read		= pit_read,
-	.mask		= CLOCKSOURCE_MASK(32),
-};
+DEFINE_RAW_SPINLOCK(i8253_lock);
 
 static void pit_set_mode(enum clock_event_mode mode,
 	struct clock_event_device *evt)
@@ -121,7 +84,7 @@
 	pit_ce.max_delta_ns = clockevent_delta2ns(0x7fff, &pit_ce);
 	pit_ce.min_delta_ns = clockevent_delta2ns(0x000f, &pit_ce);
 
-	clocksource_register_hz(&pit_cs, PIT_TICK_RATE);
+	clocksource_i8253_init();
 
 	setup_irq(pit_ce.irq, &pit_timer_irq);
 	clockevents_register_device(&pit_ce);
diff -druN linux-2.6.39-libre/arch/arm/mach-footbridge/Kconfig linux-3.0-rc7-libre/arch/arm/mach-footbridge/Kconfig
--- linux-2.6.39-libre/arch/arm/mach-footbridge/Kconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-footbridge/Kconfig	2011-07-11 19:51:52.000000000 -0400
@@ -4,6 +4,7 @@
 
 config ARCH_CATS
 	bool "CATS"
+	select CLKSRC_I8253
 	select FOOTBRIDGE_HOST
 	select ISA
 	select ISA_DMA
@@ -59,6 +60,7 @@
 
 config ARCH_NETWINDER
 	bool "NetWinder"
+	select CLKSRC_I8253
 	select FOOTBRIDGE_HOST
 	select ISA
 	select ISA_DMA
diff -druN linux-2.6.39-libre/arch/arm/mach-gemini/board-wbd111.c linux-3.0-rc7-libre/arch/arm/mach-gemini/board-wbd111.c
--- linux-2.6.39-libre/arch/arm/mach-gemini/board-wbd111.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-gemini/board-wbd111.c	2011-07-11 19:51:52.000000000 -0400
@@ -84,7 +84,6 @@
 	.init	= gemini_timer_init,
 };
 
-#ifdef CONFIG_MTD_PARTITIONS
 static struct mtd_partition wbd111_partitions[] = {
 	{
 		.name		= "RedBoot",
@@ -116,11 +115,7 @@
 		.mask_flags	= MTD_WRITEABLE,
 	}
 };
-#define wbd111_num_partitions	ARRAY_SIZE(wbd111_partitions)
-#else
-#define wbd111_partitions	NULL
-#define wbd111_num_partitions	0
-#endif /* CONFIG_MTD_PARTITIONS */
+#define wbd111_num_partitions  ARRAY_SIZE(wbd111_partitions)
 
 static void __init wbd111_init(void)
 {
diff -druN linux-2.6.39-libre/arch/arm/mach-gemini/board-wbd222.c linux-3.0-rc7-libre/arch/arm/mach-gemini/board-wbd222.c
--- linux-2.6.39-libre/arch/arm/mach-gemini/board-wbd222.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-gemini/board-wbd222.c	2011-07-11 19:51:52.000000000 -0400
@@ -84,7 +84,6 @@
 	.init	= gemini_timer_init,
 };
 
-#ifdef CONFIG_MTD_PARTITIONS
 static struct mtd_partition wbd222_partitions[] = {
 	{
 		.name		= "RedBoot",
@@ -116,11 +115,7 @@
 		.mask_flags	= MTD_WRITEABLE,
 	}
 };
-#define wbd222_num_partitions	ARRAY_SIZE(wbd222_partitions)
-#else
-#define wbd222_partitions	NULL
-#define wbd222_num_partitions	0
-#endif /* CONFIG_MTD_PARTITIONS */
+#define wbd222_num_partitions  ARRAY_SIZE(wbd222_partitions)
 
 static void __init wbd222_init(void)
 {
diff -druN linux-2.6.39-libre/arch/arm/mach-gemini/include/mach/uncompress.h linux-3.0-rc7-libre/arch/arm/mach-gemini/include/mach/uncompress.h
--- linux-2.6.39-libre/arch/arm/mach-gemini/include/mach/uncompress.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-gemini/include/mach/uncompress.h	2011-07-11 19:51:52.000000000 -0400
@@ -16,7 +16,7 @@
 #include <linux/serial_reg.h>
 #include <mach/hardware.h>
 
-static volatile unsigned long *UART = (unsigned long *)GEMINI_UART_BASE;
+static volatile unsigned long * const UART = (unsigned long *)GEMINI_UART_BASE;
 
 /*
  * The following code assumes the serial port has already been
diff -druN linux-2.6.39-libre/arch/arm/mach-h720x/include/mach/memory.h linux-3.0-rc7-libre/arch/arm/mach-h720x/include/mach/memory.h
--- linux-2.6.39-libre/arch/arm/mach-h720x/include/mach/memory.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-h720x/include/mach/memory.h	2011-07-11 19:51:52.000000000 -0400
@@ -13,7 +13,6 @@
  * There should not be more than (0xd0000000 - 0xc0000000)
  * bytes of RAM.
  */
-#define ISA_DMA_THRESHOLD	(PHYS_OFFSET + SZ_256M - 1)
-#define MAX_DMA_ADDRESS		(PAGE_OFFSET + SZ_256M)
+#define ARM_DMA_ZONE_SIZE	SZ_256M
 
 #endif
diff -druN linux-2.6.39-libre/arch/arm/mach-h720x/Kconfig linux-3.0-rc7-libre/arch/arm/mach-h720x/Kconfig
--- linux-2.6.39-libre/arch/arm/mach-h720x/Kconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-h720x/Kconfig	2011-07-11 19:51:52.000000000 -0400
@@ -6,12 +6,14 @@
 	bool "gms30c7201"
 	depends on ARCH_H720X
 	select CPU_H7201
+	select ZONE_DMA
 	help
 	  Say Y here if you are using the Hynix GMS30C7201 Reference Board
 
 config ARCH_H7202
 	bool "hms30c7202"
 	select CPU_H7202
+	select ZONE_DMA
 	depends on ARCH_H720X
 	help
 	  Say Y here if you are using the Hynix HMS30C7202 Reference Board
diff -druN linux-2.6.39-libre/arch/arm/mach-imx/cache-l2x0.c linux-3.0-rc7-libre/arch/arm/mach-imx/cache-l2x0.c
--- linux-2.6.39-libre/arch/arm/mach-imx/cache-l2x0.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/arm/mach-imx/cache-l2x0.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2009-2010 Pengutronix
+ * Sascha Hauer <s.hauer@pengutronix.de>
+ * Juergen Beisert <j.beisert@pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License version 2 as published by the
+ * Free Software Foundation.
+ */
+
+#include <linux/init.h>
+#include <linux/err.h>
+#include <linux/kernel.h>
+
+#include <asm/hardware/cache-l2x0.h>
+
+#include <mach/hardware.h>
+
+static int mxc_init_l2x0(void)
+{
+	void __iomem *l2x0_base;
+	void __iomem *clkctl_base;
+
+	if (!cpu_is_mx31() && !cpu_is_mx35())
+		return 0;
+
+/*
+ * First of all, we must repair broken chip settings. There are some
+ * i.MX35 CPUs in the wild, comming with bogus L2 cache settings. These
+ * misconfigured CPUs will run amok immediately when the L2 cache gets enabled.
+ * Workaraound is to setup the correct register setting prior enabling the
+ * L2 cache. This should not hurt already working CPUs, as they are using the
+ * same value.
+ */
+#define L2_MEM_VAL 0x10
+
+	clkctl_base = ioremap(MX35_CLKCTL_BASE_ADDR, 4096);
+	if (clkctl_base != NULL) {
+		writel(0x00000515, clkctl_base + L2_MEM_VAL);
+		iounmap(clkctl_base);
+	} else {
+		pr_err("L2 cache: Cannot fix timing. Trying to continue without\n");
+	}
+
+	l2x0_base = ioremap(MX3x_L2CC_BASE_ADDR, 4096);
+	if (IS_ERR(l2x0_base)) {
+		printk(KERN_ERR "remapping L2 cache area failed with %ld\n",
+				PTR_ERR(l2x0_base));
+		return 0;
+	}
+
+	l2x0_init(l2x0_base, 0x00030024, 0x00000000);
+
+	return 0;
+}
+arch_initcall(mxc_init_l2x0);
diff -druN linux-2.6.39-libre/arch/arm/mach-imx/clock-imx31.c linux-3.0-rc7-libre/arch/arm/mach-imx/clock-imx31.c
--- linux-2.6.39-libre/arch/arm/mach-imx/clock-imx31.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/arm/mach-imx/clock-imx31.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,629 @@
+/*
+ * 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 <linux/clkdev.h>
+
+#include <asm/div64.h>
+
+#include <mach/clock.h>
+#include <mach/hardware.h>
+#include <mach/mx31.h>
+#include <mach/common.h>
+
+#include "crmregs-imx31.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, NULL, &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("imx31-cspi.0", NULL, cspi1_clk)
+	_REGISTER_CLOCK("imx31-cspi.1", NULL, cspi2_clk)
+	_REGISTER_CLOCK("imx31-cspi.2", NULL, cspi3_clk)
+	_REGISTER_CLOCK(NULL, "gpt", gpt_clk)
+	_REGISTER_CLOCK(NULL, "pwm", pwm_clk)
+	_REGISTER_CLOCK("imx2-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("imx-sdma", NULL, 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() >= IMX_CHIP_REVISION_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 -druN linux-2.6.39-libre/arch/arm/mach-imx/clock-imx35.c linux-3.0-rc7-libre/arch/arm/mach-imx/clock-imx35.c
--- linux-2.6.39-libre/arch/arm/mach-imx/clock-imx35.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/arm/mach-imx/clock-imx35.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,549 @@
+/*
+ * Copyright (C) 2009 by Sascha Hauer, Pengutronix
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/list.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/clkdev.h>
+
+#include <mach/clock.h>
+#include <mach/hardware.h>
+#include <mach/common.h>
+
+#define CCM_BASE	MX35_IO_ADDRESS(MX35_CCM_BASE_ADDR)
+
+#define CCM_CCMR        0x00
+#define CCM_PDR0        0x04
+#define CCM_PDR1        0x08
+#define CCM_PDR2        0x0C
+#define CCM_PDR3        0x10
+#define CCM_PDR4        0x14
+#define CCM_RCSR        0x18
+#define CCM_MPCTL       0x1C
+#define CCM_PPCTL       0x20
+#define CCM_ACMR        0x24
+#define CCM_COSR        0x28
+#define CCM_CGR0        0x2C
+#define CCM_CGR1        0x30
+#define CCM_CGR2        0x34
+#define CCM_CGR3        0x38
+
+#ifdef HAVE_SET_RATE_SUPPORT
+static void calc_dividers(u32 div, u32 *pre, u32 *post, u32 maxpost)
+{
+	u32 min_pre, temp_pre, old_err, err;
+
+	min_pre = (div - 1) / maxpost + 1;
+	old_err = 8;
+
+	for (temp_pre = 8; temp_pre >= min_pre; temp_pre--) {
+		if (div > (temp_pre * maxpost))
+			break;
+
+		if (div < (temp_pre * temp_pre))
+			continue;
+
+		err = div % temp_pre;
+
+		if (err == 0) {
+			*pre = temp_pre;
+			break;
+		}
+
+		err = temp_pre - err;
+
+		if (err < old_err) {
+			old_err = err;
+			*pre = temp_pre;
+		}
+	}
+
+	*post = (div + *pre - 1) / *pre;
+}
+
+/* get the best values for a 3-bit divider combined with a 6-bit divider */
+static void calc_dividers_3_6(u32 div, u32 *pre, u32 *post)
+{
+	if (div >= 512) {
+		*pre = 8;
+		*post = 64;
+	} else if (div >= 64) {
+		calc_dividers(div, pre, post, 64);
+	} else if (div <= 8) {
+		*pre = div;
+		*post = 1;
+	} else {
+		*pre = 1;
+		*post = div;
+	}
+}
+
+/* get the best values for two cascaded 3-bit dividers */
+static void calc_dividers_3_3(u32 div, u32 *pre, u32 *post)
+{
+	if (div >= 64) {
+		*pre = *post = 8;
+	} else if (div > 8) {
+		calc_dividers(div, pre, post, 8);
+	} else {
+		*pre = 1;
+		*post = div;
+	}
+}
+#endif
+
+static unsigned long get_rate_mpll(void)
+{
+	ulong mpctl = __raw_readl(CCM_BASE + CCM_MPCTL);
+
+	return mxc_decode_pll(mpctl, 24000000);
+}
+
+static unsigned long get_rate_ppll(void)
+{
+	ulong ppctl = __raw_readl(CCM_BASE + CCM_PPCTL);
+
+	return mxc_decode_pll(ppctl, 24000000);
+}
+
+struct arm_ahb_div {
+	unsigned char arm, ahb, sel;
+};
+
+static struct arm_ahb_div clk_consumer[] = {
+	{ .arm = 1, .ahb = 4, .sel = 0},
+	{ .arm = 1, .ahb = 3, .sel = 1},
+	{ .arm = 2, .ahb = 2, .sel = 0},
+	{ .arm = 0, .ahb = 0, .sel = 0},
+	{ .arm = 0, .ahb = 0, .sel = 0},
+	{ .arm = 0, .ahb = 0, .sel = 0},
+	{ .arm = 4, .ahb = 1, .sel = 0},
+	{ .arm = 1, .ahb = 5, .sel = 0},
+	{ .arm = 1, .ahb = 8, .sel = 0},
+	{ .arm = 1, .ahb = 6, .sel = 1},
+	{ .arm = 2, .ahb = 4, .sel = 0},
+	{ .arm = 0, .ahb = 0, .sel = 0},
+	{ .arm = 0, .ahb = 0, .sel = 0},
+	{ .arm = 0, .ahb = 0, .sel = 0},
+	{ .arm = 4, .ahb = 2, .sel = 0},
+	{ .arm = 0, .ahb = 0, .sel = 0},
+};
+
+static unsigned long get_rate_arm(void)
+{
+	unsigned long pdr0 = __raw_readl(CCM_BASE + CCM_PDR0);
+	struct arm_ahb_div *aad;
+	unsigned long fref = get_rate_mpll();
+
+	aad = &clk_consumer[(pdr0 >> 16) & 0xf];
+	if (aad->sel)
+		fref = fref * 3 / 4;
+
+	return fref / aad->arm;
+}
+
+static unsigned long get_rate_ahb(struct clk *clk)
+{
+	unsigned long pdr0 = __raw_readl(CCM_BASE + CCM_PDR0);
+	struct arm_ahb_div *aad;
+	unsigned long fref = get_rate_arm();
+
+	aad = &clk_consumer[(pdr0 >> 16) & 0xf];
+
+	return fref / aad->ahb;
+}
+
+static unsigned long get_rate_ipg(struct clk *clk)
+{
+	return get_rate_ahb(NULL) >> 1;
+}
+
+static unsigned long get_rate_uart(struct clk *clk)
+{
+	unsigned long pdr3 = __raw_readl(CCM_BASE + CCM_PDR3);
+	unsigned long pdr4 = __raw_readl(CCM_BASE + CCM_PDR4);
+	unsigned long div = ((pdr4 >> 10) & 0x3f) + 1;
+
+	if (pdr3 & (1 << 14))
+		return get_rate_arm() / div;
+	else
+		return get_rate_ppll() / div;
+}
+
+static unsigned long get_rate_sdhc(struct clk *clk)
+{
+	unsigned long pdr3 = __raw_readl(CCM_BASE + CCM_PDR3);
+	unsigned long div, rate;
+
+	if (pdr3 & (1 << 6))
+		rate = get_rate_arm();
+	else
+		rate = get_rate_ppll();
+
+	switch (clk->id) {
+	default:
+	case 0:
+		div = pdr3 & 0x3f;
+		break;
+	case 1:
+		div = (pdr3 >> 8) & 0x3f;
+		break;
+	case 2:
+		div = (pdr3 >> 16) & 0x3f;
+		break;
+	}
+
+	return rate / (div + 1);
+}
+
+static unsigned long get_rate_mshc(struct clk *clk)
+{
+	unsigned long pdr1 = __raw_readl(CCM_BASE + CCM_PDR1);
+	unsigned long div1, div2, rate;
+
+	if (pdr1 & (1 << 7))
+		rate = get_rate_arm();
+	else
+		rate = get_rate_ppll();
+
+	div1 = (pdr1 >> 29) & 0x7;
+	div2 = (pdr1 >> 22) & 0x3f;
+
+	return rate / ((div1 + 1) * (div2 + 1));
+}
+
+static unsigned long get_rate_ssi(struct clk *clk)
+{
+	unsigned long pdr2 = __raw_readl(CCM_BASE + CCM_PDR2);
+	unsigned long div1, div2, rate;
+
+	if (pdr2 & (1 << 6))
+		rate = get_rate_arm();
+	else
+		rate = get_rate_ppll();
+
+	switch (clk->id) {
+	default:
+	case 0:
+		div1 = pdr2 & 0x3f;
+		div2 = (pdr2 >> 24) & 0x7;
+		break;
+	case 1:
+		div1 = (pdr2 >> 8) & 0x3f;
+		div2 = (pdr2 >> 27) & 0x7;
+		break;
+	}
+
+	return rate / ((div1 + 1) * (div2 + 1));
+}
+
+static unsigned long get_rate_csi(struct clk *clk)
+{
+	unsigned long pdr2 = __raw_readl(CCM_BASE + CCM_PDR2);
+	unsigned long rate;
+
+	if (pdr2 & (1 << 7))
+		rate = get_rate_arm();
+	else
+		rate = get_rate_ppll();
+
+	return rate / (((pdr2 >> 16) & 0x3f) + 1);
+}
+
+static unsigned long get_rate_otg(struct clk *clk)
+{
+	unsigned long pdr4 = __raw_readl(CCM_BASE + CCM_PDR4);
+	unsigned long rate;
+
+	if (pdr4 & (1 << 9))
+		rate = get_rate_arm();
+	else
+		rate = get_rate_ppll();
+
+	return rate / (((pdr4 >> 22) & 0x3f) + 1);
+}
+
+static unsigned long get_rate_ipg_per(struct clk *clk)
+{
+	unsigned long pdr0 = __raw_readl(CCM_BASE + CCM_PDR0);
+	unsigned long pdr4 = __raw_readl(CCM_BASE + CCM_PDR4);
+	unsigned long div;
+
+	if (pdr0 & (1 << 26)) {
+		div = (pdr4 >> 16) & 0x3f;
+		return get_rate_arm() / (div + 1);
+	} else {
+		div = (pdr0 >> 12) & 0x7;
+		return get_rate_ahb(NULL) / (div + 1);
+	}
+}
+
+static unsigned long get_rate_hsp(struct clk *clk)
+{
+	unsigned long hsp_podf = (__raw_readl(CCM_BASE + CCM_PDR0) >> 20) & 0x03;
+	unsigned long fref = get_rate_mpll();
+
+	if (fref > 400 * 1000 * 1000) {
+		switch (hsp_podf) {
+		case 0:
+			return fref >> 2;
+		case 1:
+			return fref >> 3;
+		case 2:
+			return fref / 3;
+		}
+	} else {
+		switch (hsp_podf) {
+		case 0:
+		case 2:
+			return fref / 3;
+		case 1:
+			return fref / 6;
+		}
+	}
+
+	return 0;
+}
+
+static int clk_cgr_enable(struct clk *clk)
+{
+	u32 reg;
+
+	reg = __raw_readl(clk->enable_reg);
+	reg |= 3 << clk->enable_shift;
+	__raw_writel(reg, clk->enable_reg);
+
+	return 0;
+}
+
+static void clk_cgr_disable(struct clk *clk)
+{
+	u32 reg;
+
+	reg = __raw_readl(clk->enable_reg);
+	reg &= ~(3 << clk->enable_shift);
+	__raw_writel(reg, clk->enable_reg);
+}
+
+#define DEFINE_CLOCK(name, i, er, es, gr, sr)		\
+	static struct clk name = {			\
+		.id		= i,			\
+		.enable_reg	= CCM_BASE + er,	\
+		.enable_shift	= es,			\
+		.get_rate	= gr,			\
+		.set_rate	= sr,			\
+		.enable		= clk_cgr_enable,	\
+		.disable	= clk_cgr_disable,	\
+	}
+
+DEFINE_CLOCK(asrc_clk,   0, CCM_CGR0,  0, NULL, NULL);
+DEFINE_CLOCK(ata_clk,    0, CCM_CGR0,  2, get_rate_ipg, NULL);
+/* DEFINE_CLOCK(audmux_clk, 0, CCM_CGR0,  4, NULL, NULL); */
+DEFINE_CLOCK(can1_clk,   0, CCM_CGR0,  6, get_rate_ipg, NULL);
+DEFINE_CLOCK(can2_clk,   1, CCM_CGR0,  8, get_rate_ipg, NULL);
+DEFINE_CLOCK(cspi1_clk,  0, CCM_CGR0, 10, get_rate_ipg, NULL);
+DEFINE_CLOCK(cspi2_clk,  1, CCM_CGR0, 12, get_rate_ipg, NULL);
+DEFINE_CLOCK(ect_clk,    0, CCM_CGR0, 14, get_rate_ipg, NULL);
+DEFINE_CLOCK(edio_clk,   0, CCM_CGR0, 16, NULL, NULL);
+DEFINE_CLOCK(emi_clk,    0, CCM_CGR0, 18, get_rate_ipg, NULL);
+DEFINE_CLOCK(epit1_clk,  0, CCM_CGR0, 20, get_rate_ipg, NULL);
+DEFINE_CLOCK(epit2_clk,  1, CCM_CGR0, 22, get_rate_ipg, NULL);
+DEFINE_CLOCK(esai_clk,   0, CCM_CGR0, 24, NULL, NULL);
+DEFINE_CLOCK(esdhc1_clk, 0, CCM_CGR0, 26, get_rate_sdhc, NULL);
+DEFINE_CLOCK(esdhc2_clk, 1, CCM_CGR0, 28, get_rate_sdhc, NULL);
+DEFINE_CLOCK(esdhc3_clk, 2, CCM_CGR0, 30, get_rate_sdhc, NULL);
+
+DEFINE_CLOCK(fec_clk,    0, CCM_CGR1,  0, get_rate_ipg, NULL);
+DEFINE_CLOCK(gpio1_clk,  0, CCM_CGR1,  2, NULL, NULL);
+DEFINE_CLOCK(gpio2_clk,  1, CCM_CGR1,  4, NULL, NULL);
+DEFINE_CLOCK(gpio3_clk,  2, CCM_CGR1,  6, NULL, NULL);
+DEFINE_CLOCK(gpt_clk,    0, CCM_CGR1,  8, get_rate_ipg, NULL);
+DEFINE_CLOCK(i2c1_clk,   0, CCM_CGR1, 10, get_rate_ipg_per, NULL);
+DEFINE_CLOCK(i2c2_clk,   1, CCM_CGR1, 12, get_rate_ipg_per, NULL);
+DEFINE_CLOCK(i2c3_clk,   2, CCM_CGR1, 14, get_rate_ipg_per, NULL);
+DEFINE_CLOCK(iomuxc_clk, 0, CCM_CGR1, 16, NULL, NULL);
+DEFINE_CLOCK(ipu_clk,    0, CCM_CGR1, 18, get_rate_hsp, NULL);
+DEFINE_CLOCK(kpp_clk,    0, CCM_CGR1, 20, get_rate_ipg, NULL);
+DEFINE_CLOCK(mlb_clk,    0, CCM_CGR1, 22, get_rate_ahb, NULL);
+DEFINE_CLOCK(mshc_clk,   0, CCM_CGR1, 24, get_rate_mshc, NULL);
+DEFINE_CLOCK(owire_clk,  0, CCM_CGR1, 26, get_rate_ipg_per, NULL);
+DEFINE_CLOCK(pwm_clk,    0, CCM_CGR1, 28, get_rate_ipg_per, NULL);
+DEFINE_CLOCK(rngc_clk,   0, CCM_CGR1, 30, get_rate_ipg, NULL);
+
+DEFINE_CLOCK(rtc_clk,    0, CCM_CGR2,  0, get_rate_ipg, NULL);
+DEFINE_CLOCK(rtic_clk,   0, CCM_CGR2,  2, get_rate_ahb, NULL);
+DEFINE_CLOCK(scc_clk,    0, CCM_CGR2,  4, get_rate_ipg, NULL);
+DEFINE_CLOCK(sdma_clk,   0, CCM_CGR2,  6, NULL, NULL);
+DEFINE_CLOCK(spba_clk,   0, CCM_CGR2,  8, get_rate_ipg, NULL);
+DEFINE_CLOCK(spdif_clk,  0, CCM_CGR2, 10, NULL, NULL);
+DEFINE_CLOCK(ssi1_clk,   0, CCM_CGR2, 12, get_rate_ssi, NULL);
+DEFINE_CLOCK(ssi2_clk,   1, CCM_CGR2, 14, get_rate_ssi, NULL);
+DEFINE_CLOCK(uart1_clk,  0, CCM_CGR2, 16, get_rate_uart, NULL);
+DEFINE_CLOCK(uart2_clk,  1, CCM_CGR2, 18, get_rate_uart, NULL);
+DEFINE_CLOCK(uart3_clk,  2, CCM_CGR2, 20, get_rate_uart, NULL);
+DEFINE_CLOCK(usbotg_clk, 0, CCM_CGR2, 22, get_rate_otg, NULL);
+DEFINE_CLOCK(wdog_clk,   0, CCM_CGR2, 24, NULL, NULL);
+DEFINE_CLOCK(max_clk,    0, CCM_CGR2, 26, NULL, NULL);
+DEFINE_CLOCK(audmux_clk, 0, CCM_CGR2, 30, NULL, NULL);
+
+DEFINE_CLOCK(csi_clk,    0, CCM_CGR3,  0, get_rate_csi, NULL);
+DEFINE_CLOCK(iim_clk,    0, CCM_CGR3,  2, NULL, NULL);
+DEFINE_CLOCK(gpu2d_clk,  0, CCM_CGR3,  4, NULL, NULL);
+
+DEFINE_CLOCK(usbahb_clk, 0, 0,         0, get_rate_ahb, NULL);
+
+static int clk_dummy_enable(struct clk *clk)
+{
+	return 0;
+}
+
+static void clk_dummy_disable(struct clk *clk)
+{
+}
+
+static unsigned long get_rate_nfc(struct clk *clk)
+{
+	unsigned long div1;
+
+	div1 = (__raw_readl(CCM_BASE + CCM_PDR4) >> 28) + 1;
+
+	return get_rate_ahb(NULL) / div1;
+}
+
+/* NAND Controller: It seems it can't be disabled */
+static struct clk nfc_clk = {
+	.id		= 0,
+	.enable_reg	= 0,
+	.enable_shift	= 0,
+	.get_rate	= get_rate_nfc,
+	.set_rate	= NULL, /* set_rate_nfc, */
+	.enable		= clk_dummy_enable,
+	.disable	= clk_dummy_disable
+};
+
+#define _REGISTER_CLOCK(d, n, c)	\
+	{				\
+		.dev_id = d,		\
+		.con_id = n,		\
+		.clk = &c,		\
+	},
+
+static struct clk_lookup lookups[] = {
+	_REGISTER_CLOCK(NULL, "asrc", asrc_clk)
+	_REGISTER_CLOCK(NULL, "ata", ata_clk)
+	_REGISTER_CLOCK("flexcan.0", NULL, can1_clk)
+	_REGISTER_CLOCK("flexcan.1", NULL, can2_clk)
+	_REGISTER_CLOCK("imx35-cspi.0", NULL, cspi1_clk)
+	_REGISTER_CLOCK("imx35-cspi.1", NULL, cspi2_clk)
+	_REGISTER_CLOCK(NULL, "ect", ect_clk)
+	_REGISTER_CLOCK(NULL, "edio", edio_clk)
+	_REGISTER_CLOCK(NULL, "emi", emi_clk)
+	_REGISTER_CLOCK("imx-epit.0", NULL, epit1_clk)
+	_REGISTER_CLOCK("imx-epit.1", NULL, epit2_clk)
+	_REGISTER_CLOCK(NULL, "esai", esai_clk)
+	_REGISTER_CLOCK("sdhci-esdhc-imx.0", NULL, esdhc1_clk)
+	_REGISTER_CLOCK("sdhci-esdhc-imx.1", NULL, esdhc2_clk)
+	_REGISTER_CLOCK("sdhci-esdhc-imx.2", NULL, esdhc3_clk)
+	_REGISTER_CLOCK("fec.0", NULL, fec_clk)
+	_REGISTER_CLOCK(NULL, "gpio", gpio1_clk)
+	_REGISTER_CLOCK(NULL, "gpio", gpio2_clk)
+	_REGISTER_CLOCK(NULL, "gpio", gpio3_clk)
+	_REGISTER_CLOCK("gpt.0", NULL, gpt_clk)
+	_REGISTER_CLOCK("imx-i2c.0", NULL, i2c1_clk)
+	_REGISTER_CLOCK("imx-i2c.1", NULL, i2c2_clk)
+	_REGISTER_CLOCK("imx-i2c.2", NULL, i2c3_clk)
+	_REGISTER_CLOCK(NULL, "iomuxc", iomuxc_clk)
+	_REGISTER_CLOCK("ipu-core", NULL, ipu_clk)
+	_REGISTER_CLOCK("mx3_sdc_fb", NULL, ipu_clk)
+	_REGISTER_CLOCK(NULL, "kpp", kpp_clk)
+	_REGISTER_CLOCK(NULL, "mlb", mlb_clk)
+	_REGISTER_CLOCK(NULL, "mshc", mshc_clk)
+	_REGISTER_CLOCK("mxc_w1", NULL, owire_clk)
+	_REGISTER_CLOCK(NULL, "pwm", pwm_clk)
+	_REGISTER_CLOCK(NULL, "rngc", rngc_clk)
+	_REGISTER_CLOCK(NULL, "rtc", rtc_clk)
+	_REGISTER_CLOCK(NULL, "rtic", rtic_clk)
+	_REGISTER_CLOCK(NULL, "scc", scc_clk)
+	_REGISTER_CLOCK("imx-sdma", NULL, sdma_clk)
+	_REGISTER_CLOCK(NULL, "spba", spba_clk)
+	_REGISTER_CLOCK(NULL, "spdif", spdif_clk)
+	_REGISTER_CLOCK("imx-ssi.0", NULL, ssi1_clk)
+	_REGISTER_CLOCK("imx-ssi.1", NULL, ssi2_clk)
+	_REGISTER_CLOCK("imx-uart.0", NULL, uart1_clk)
+	_REGISTER_CLOCK("imx-uart.1", NULL, uart2_clk)
+	_REGISTER_CLOCK("imx-uart.2", NULL, uart3_clk)
+	_REGISTER_CLOCK("mxc-ehci.0", "usb", usbotg_clk)
+	_REGISTER_CLOCK("mxc-ehci.1", "usb", usbotg_clk)
+	_REGISTER_CLOCK("mxc-ehci.2", "usb", usbotg_clk)
+	_REGISTER_CLOCK("fsl-usb2-udc", "usb", usbotg_clk)
+	_REGISTER_CLOCK("fsl-usb2-udc", "usb_ahb", usbahb_clk)
+	_REGISTER_CLOCK("imx2-wdt.0", NULL, wdog_clk)
+	_REGISTER_CLOCK(NULL, "max", max_clk)
+	_REGISTER_CLOCK(NULL, "audmux", audmux_clk)
+	_REGISTER_CLOCK(NULL, "csi", csi_clk)
+	_REGISTER_CLOCK(NULL, "iim", iim_clk)
+	_REGISTER_CLOCK(NULL, "gpu2d", gpu2d_clk)
+	_REGISTER_CLOCK("mxc_nand.0", NULL, nfc_clk)
+};
+
+int __init mx35_clocks_init()
+{
+	unsigned int cgr2 = 3 << 26, cgr3 = 0;
+
+#if defined(CONFIG_DEBUG_LL) && !defined(CONFIG_DEBUG_ICEDCC)
+	cgr2 |= 3 << 16;
+#endif
+
+	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
+	 */
+	__raw_writel((3 << 18), CCM_BASE + CCM_CGR0);
+	__raw_writel((3 << 2) | (3 << 4) | (3 << 6) | (3 << 8) | (3 << 16),
+			CCM_BASE + CCM_CGR1);
+
+	/*
+	 * Check if we came up in internal boot mode. If yes, we need some
+	 * extra clocks turned on, otherwise the MX35 boot ROM code will
+	 * hang after a watchdog reset.
+	 */
+	if (!(__raw_readl(CCM_BASE + CCM_RCSR) & (3 << 10))) {
+		/* Additionally turn on UART1, SCC, and IIM clocks */
+		cgr2 |= 3 << 16 | 3 << 4;
+		cgr3 |= 3 << 2;
+	}
+
+	__raw_writel(cgr2, CCM_BASE + CCM_CGR2);
+	__raw_writel(cgr3, CCM_BASE + CCM_CGR3);
+
+	clk_enable(&iim_clk);
+	mx35_read_cpu_rev();
+
+#ifdef CONFIG_MXC_USE_EPIT
+	epit_timer_init(&epit1_clk,
+			MX35_IO_ADDRESS(MX35_EPIT1_BASE_ADDR), MX35_INT_EPIT1);
+#else
+	mxc_timer_init(&gpt_clk,
+			MX35_IO_ADDRESS(MX35_GPT1_BASE_ADDR), MX35_INT_GPT);
+#endif
+
+	return 0;
+}
diff -druN linux-2.6.39-libre/arch/arm/mach-imx/cpu-imx31.c linux-3.0-rc7-libre/arch/arm/mach-imx/cpu-imx31.c
--- linux-2.6.39-libre/arch/arm/mach-imx/cpu-imx31.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/arm/mach-imx/cpu-imx31.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,57 @@
+/*
+ * MX31 CPU type detection
+ *
+ * Copyright (c) 2009 Daniel Mack <daniel@caiaq.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/module.h>
+#include <linux/io.h>
+#include <mach/hardware.h>
+#include <mach/iim.h>
+
+unsigned int mx31_cpu_rev;
+EXPORT_SYMBOL(mx31_cpu_rev);
+
+static struct {
+	u8 srev;
+	const char *name;
+	const char *v;
+	unsigned int rev;
+} mx31_cpu_type[] __initdata = {
+	{ .srev = 0x00, .name = "i.MX31(L)", .v = "1.0",  .rev = IMX_CHIP_REVISION_1_0	},
+	{ .srev = 0x10, .name = "i.MX31",    .v = "1.1",  .rev = IMX_CHIP_REVISION_1_1	},
+	{ .srev = 0x11, .name = "i.MX31L",   .v = "1.1",  .rev = IMX_CHIP_REVISION_1_1	},
+	{ .srev = 0x12, .name = "i.MX31",    .v = "1.15", .rev = IMX_CHIP_REVISION_1_1	},
+	{ .srev = 0x13, .name = "i.MX31L",   .v = "1.15", .rev = IMX_CHIP_REVISION_1_1	},
+	{ .srev = 0x14, .name = "i.MX31",    .v = "1.2",  .rev = IMX_CHIP_REVISION_1_2	},
+	{ .srev = 0x15, .name = "i.MX31L",   .v = "1.2",  .rev = IMX_CHIP_REVISION_1_2	},
+	{ .srev = 0x28, .name = "i.MX31",    .v = "2.0",  .rev = IMX_CHIP_REVISION_2_0	},
+	{ .srev = 0x29, .name = "i.MX31L",   .v = "2.0",  .rev = IMX_CHIP_REVISION_2_0	},
+};
+
+void __init mx31_read_cpu_rev(void)
+{
+	u32 i, srev;
+
+	/* read SREV register from IIM module */
+	srev = __raw_readl(MX31_IO_ADDRESS(MX31_IIM_BASE_ADDR + MXC_IIMSREV));
+
+	for (i = 0; i < ARRAY_SIZE(mx31_cpu_type); i++)
+		if (srev == mx31_cpu_type[i].srev) {
+			printk(KERN_INFO
+				"CPU identified as %s, silicon rev %s\n",
+				mx31_cpu_type[i].name, mx31_cpu_type[i].v);
+
+			mx31_cpu_rev = mx31_cpu_type[i].rev;
+			return;
+		}
+
+	mx31_cpu_rev = IMX_CHIP_REVISION_UNKNOWN;
+
+	printk(KERN_WARNING "Unknown CPU identifier. srev = %02x\n", srev);
+}
diff -druN linux-2.6.39-libre/arch/arm/mach-imx/cpu-imx35.c linux-3.0-rc7-libre/arch/arm/mach-imx/cpu-imx35.c
--- linux-2.6.39-libre/arch/arm/mach-imx/cpu-imx35.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/arm/mach-imx/cpu-imx35.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,44 @@
+/*
+ * MX35 CPU type detection
+ *
+ * Copyright (c) 2009 Daniel Mack <daniel@caiaq.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+#include <linux/module.h>
+#include <linux/io.h>
+#include <mach/hardware.h>
+#include <mach/iim.h>
+
+unsigned int mx35_cpu_rev;
+EXPORT_SYMBOL(mx35_cpu_rev);
+
+void __init mx35_read_cpu_rev(void)
+{
+	u32 rev;
+	char *srev;
+
+	rev = __raw_readl(MX35_IO_ADDRESS(MX35_IIM_BASE_ADDR + MXC_IIMSREV));
+	switch (rev) {
+	case 0x00:
+		mx35_cpu_rev = IMX_CHIP_REVISION_1_0;
+		srev = "1.0";
+		break;
+	case 0x10:
+		mx35_cpu_rev = IMX_CHIP_REVISION_2_0;
+		srev = "2.0";
+		break;
+	case 0x11:
+		mx35_cpu_rev = IMX_CHIP_REVISION_2_1;
+		srev = "2.1";
+		break;
+	default:
+		mx35_cpu_rev = IMX_CHIP_REVISION_UNKNOWN;
+		srev = "unknown";
+	}
+
+	printk(KERN_INFO "CPU identified as i.MX35, silicon rev %s\n", srev);
+}
diff -druN linux-2.6.39-libre/arch/arm/mach-imx/crmregs-imx31.h linux-3.0-rc7-libre/arch/arm/mach-imx/crmregs-imx31.h
--- linux-2.6.39-libre/arch/arm/mach-imx/crmregs-imx31.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/arm/mach-imx/crmregs-imx31.h	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,248 @@
+/*
+ * Copyright 2004-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.
+ */
+
+#ifndef __ARCH_ARM_MACH_MX3_CRM_REGS_H__
+#define __ARCH_ARM_MACH_MX3_CRM_REGS_H__
+
+#define CKIH_CLK_FREQ           26000000
+#define CKIH_CLK_FREQ_27MHZ     27000000
+#define CKIL_CLK_FREQ           32768
+
+#define MXC_CCM_BASE		MX31_IO_ADDRESS(MX31_CCM_BASE_ADDR)
+
+/* Register addresses */
+#define MXC_CCM_CCMR		(MXC_CCM_BASE + 0x00)
+#define MXC_CCM_PDR0		(MXC_CCM_BASE + 0x04)
+#define MXC_CCM_PDR1		(MXC_CCM_BASE + 0x08)
+#define MXC_CCM_RCSR		(MXC_CCM_BASE + 0x0C)
+#define MXC_CCM_MPCTL		(MXC_CCM_BASE + 0x10)
+#define MXC_CCM_UPCTL		(MXC_CCM_BASE + 0x14)
+#define MXC_CCM_SRPCTL		(MXC_CCM_BASE + 0x18)
+#define MXC_CCM_COSR		(MXC_CCM_BASE + 0x1C)
+#define MXC_CCM_CGR0		(MXC_CCM_BASE + 0x20)
+#define MXC_CCM_CGR1		(MXC_CCM_BASE + 0x24)
+#define MXC_CCM_CGR2		(MXC_CCM_BASE + 0x28)
+#define MXC_CCM_WIMR		(MXC_CCM_BASE + 0x2C)
+#define MXC_CCM_LDC		(MXC_CCM_BASE + 0x30)
+#define MXC_CCM_DCVR0		(MXC_CCM_BASE + 0x34)
+#define MXC_CCM_DCVR1		(MXC_CCM_BASE + 0x38)
+#define MXC_CCM_DCVR2		(MXC_CCM_BASE + 0x3C)
+#define MXC_CCM_DCVR3		(MXC_CCM_BASE + 0x40)
+#define MXC_CCM_LTR0		(MXC_CCM_BASE + 0x44)
+#define MXC_CCM_LTR1		(MXC_CCM_BASE + 0x48)
+#define MXC_CCM_LTR2		(MXC_CCM_BASE + 0x4C)
+#define MXC_CCM_LTR3		(MXC_CCM_BASE + 0x50)
+#define MXC_CCM_LTBR0		(MXC_CCM_BASE + 0x54)
+#define MXC_CCM_LTBR1		(MXC_CCM_BASE + 0x58)
+#define MXC_CCM_PMCR0		(MXC_CCM_BASE + 0x5C)
+#define MXC_CCM_PMCR1		(MXC_CCM_BASE + 0x60)
+#define MXC_CCM_PDR2		(MXC_CCM_BASE + 0x64)
+
+/* Register bit definitions */
+#define MXC_CCM_CCMR_WBEN                       (1 << 27)
+#define MXC_CCM_CCMR_CSCS                       (1 << 25)
+#define MXC_CCM_CCMR_PERCS                      (1 << 24)
+#define MXC_CCM_CCMR_SSI1S_OFFSET               18
+#define MXC_CCM_CCMR_SSI1S_MASK                 (0x3 << 18)
+#define MXC_CCM_CCMR_SSI2S_OFFSET               21
+#define MXC_CCM_CCMR_SSI2S_MASK                 (0x3 << 21)
+#define MXC_CCM_CCMR_LPM_OFFSET                 14
+#define MXC_CCM_CCMR_LPM_MASK                   (0x3 << 14)
+#define MXC_CCM_CCMR_FIRS_OFFSET                11
+#define MXC_CCM_CCMR_FIRS_MASK                  (0x3 << 11)
+#define MXC_CCM_CCMR_UPE                        (1 << 9)
+#define MXC_CCM_CCMR_SPE                        (1 << 8)
+#define MXC_CCM_CCMR_MDS                        (1 << 7)
+#define MXC_CCM_CCMR_SBYCS                      (1 << 4)
+#define MXC_CCM_CCMR_MPE                        (1 << 3)
+#define MXC_CCM_CCMR_PRCS_OFFSET                1
+#define MXC_CCM_CCMR_PRCS_MASK                  (0x3 << 1)
+
+#define MXC_CCM_PDR0_CSI_PODF_OFFSET            26
+#define MXC_CCM_PDR0_CSI_PODF_MASK              (0x3F << 26)
+#define MXC_CCM_PDR0_CSI_PRDF_OFFSET            23
+#define MXC_CCM_PDR0_CSI_PRDF_MASK              (0x7 << 23)
+#define MXC_CCM_PDR0_PER_PODF_OFFSET            16
+#define MXC_CCM_PDR0_PER_PODF_MASK              (0x1F << 16)
+#define MXC_CCM_PDR0_HSP_PODF_OFFSET            11
+#define MXC_CCM_PDR0_HSP_PODF_MASK              (0x7 << 11)
+#define MXC_CCM_PDR0_NFC_PODF_OFFSET            8
+#define MXC_CCM_PDR0_NFC_PODF_MASK              (0x7 << 8)
+#define MXC_CCM_PDR0_IPG_PODF_OFFSET            6
+#define MXC_CCM_PDR0_IPG_PODF_MASK              (0x3 << 6)
+#define MXC_CCM_PDR0_MAX_PODF_OFFSET            3
+#define MXC_CCM_PDR0_MAX_PODF_MASK              (0x7 << 3)
+#define MXC_CCM_PDR0_MCU_PODF_OFFSET            0
+#define MXC_CCM_PDR0_MCU_PODF_MASK              0x7
+
+#define MXC_CCM_PDR1_USB_PRDF_OFFSET            30
+#define MXC_CCM_PDR1_USB_PRDF_MASK              (0x3 << 30)
+#define MXC_CCM_PDR1_USB_PODF_OFFSET            27
+#define MXC_CCM_PDR1_USB_PODF_MASK              (0x7 << 27)
+#define MXC_CCM_PDR1_FIRI_PRE_PODF_OFFSET       24
+#define MXC_CCM_PDR1_FIRI_PRE_PODF_MASK         (0x7 << 24)
+#define MXC_CCM_PDR1_FIRI_PODF_OFFSET           18
+#define MXC_CCM_PDR1_FIRI_PODF_MASK             (0x3F << 18)
+#define MXC_CCM_PDR1_SSI2_PRE_PODF_OFFSET       15
+#define MXC_CCM_PDR1_SSI2_PRE_PODF_MASK         (0x7 << 15)
+#define MXC_CCM_PDR1_SSI2_PODF_OFFSET           9
+#define MXC_CCM_PDR1_SSI2_PODF_MASK             (0x3F << 9)
+#define MXC_CCM_PDR1_SSI1_PRE_PODF_OFFSET       6
+#define MXC_CCM_PDR1_SSI1_PRE_PODF_MASK         (0x7 << 6)
+#define MXC_CCM_PDR1_SSI1_PODF_OFFSET           0
+#define MXC_CCM_PDR1_SSI1_PODF_MASK             0x3F
+
+/* Bit definitions for RCSR */
+#define MXC_CCM_RCSR_NF16B			0x80000000
+
+/*
+ * LTR0 register offsets
+ */
+#define MXC_CCM_LTR0_DIV3CK_OFFSET              1
+#define MXC_CCM_LTR0_DIV3CK_MASK                (0x3 << 1)
+#define MXC_CCM_LTR0_DNTHR_OFFSET               16
+#define MXC_CCM_LTR0_DNTHR_MASK                 (0x3F << 16)
+#define MXC_CCM_LTR0_UPTHR_OFFSET               22
+#define MXC_CCM_LTR0_UPTHR_MASK                 (0x3F << 22)
+
+/*
+ * LTR1 register offsets
+ */
+#define MXC_CCM_LTR1_PNCTHR_OFFSET              0
+#define MXC_CCM_LTR1_PNCTHR_MASK                0x3F
+#define MXC_CCM_LTR1_UPCNT_OFFSET               6
+#define MXC_CCM_LTR1_UPCNT_MASK                 (0xFF << 6)
+#define MXC_CCM_LTR1_DNCNT_OFFSET               14
+#define MXC_CCM_LTR1_DNCNT_MASK                 (0xFF << 14)
+#define MXC_CCM_LTR1_LTBRSR_MASK                0x400000
+#define MXC_CCM_LTR1_LTBRSR_OFFSET              22
+#define MXC_CCM_LTR1_LTBRSR                     0x400000
+#define MXC_CCM_LTR1_LTBRSH                     0x800000
+
+/*
+ * LTR2 bit definitions. x ranges from 0 for WSW9 to 6 for WSW15
+ */
+#define MXC_CCM_LTR2_WSW_OFFSET(x)              (11 + (x) * 3)
+#define MXC_CCM_LTR2_WSW_MASK(x)                (0x7 << \
+					MXC_CCM_LTR2_WSW_OFFSET((x)))
+#define MXC_CCM_LTR2_EMAC_OFFSET                0
+#define MXC_CCM_LTR2_EMAC_MASK                  0x1FF
+
+/*
+ * LTR3 bit definitions. x ranges from 0 for WSW0 to 8 for WSW8
+ */
+#define MXC_CCM_LTR3_WSW_OFFSET(x)              (5 + (x) * 3)
+#define MXC_CCM_LTR3_WSW_MASK(x)                (0x7 << \
+					MXC_CCM_LTR3_WSW_OFFSET((x)))
+
+#define MXC_CCM_PMCR0_DFSUP1                    0x80000000
+#define MXC_CCM_PMCR0_DFSUP1_SPLL               (0 << 31)
+#define MXC_CCM_PMCR0_DFSUP1_MPLL               (1 << 31)
+#define MXC_CCM_PMCR0_DFSUP0                    0x40000000
+#define MXC_CCM_PMCR0_DFSUP0_PLL                (0 << 30)
+#define MXC_CCM_PMCR0_DFSUP0_PDR                (1 << 30)
+#define MXC_CCM_PMCR0_DFSUP_MASK                (0x3 << 30)
+
+#define DVSUP_TURBO				0
+#define DVSUP_HIGH				1
+#define DVSUP_MEDIUM				2
+#define DVSUP_LOW				3
+#define MXC_CCM_PMCR0_DVSUP_TURBO               (DVSUP_TURBO << 28)
+#define MXC_CCM_PMCR0_DVSUP_HIGH                (DVSUP_HIGH << 28)
+#define MXC_CCM_PMCR0_DVSUP_MEDIUM              (DVSUP_MEDIUM << 28)
+#define MXC_CCM_PMCR0_DVSUP_LOW                 (DVSUP_LOW << 28)
+#define MXC_CCM_PMCR0_DVSUP_OFFSET              28
+#define MXC_CCM_PMCR0_DVSUP_MASK                (0x3 << 28)
+#define MXC_CCM_PMCR0_UDSC                      0x08000000
+#define MXC_CCM_PMCR0_UDSC_MASK                 (1 << 27)
+#define MXC_CCM_PMCR0_UDSC_UP                   (1 << 27)
+#define MXC_CCM_PMCR0_UDSC_DOWN                 (0 << 27)
+
+#define MXC_CCM_PMCR0_VSCNT_1                   (0x0 << 24)
+#define MXC_CCM_PMCR0_VSCNT_2                   (0x1 << 24)
+#define MXC_CCM_PMCR0_VSCNT_3                   (0x2 << 24)
+#define MXC_CCM_PMCR0_VSCNT_4                   (0x3 << 24)
+#define MXC_CCM_PMCR0_VSCNT_5                   (0x4 << 24)
+#define MXC_CCM_PMCR0_VSCNT_6                   (0x5 << 24)
+#define MXC_CCM_PMCR0_VSCNT_7                   (0x6 << 24)
+#define MXC_CCM_PMCR0_VSCNT_8                   (0x7 << 24)
+#define MXC_CCM_PMCR0_VSCNT_OFFSET              24
+#define MXC_CCM_PMCR0_VSCNT_MASK                (0x7 << 24)
+#define MXC_CCM_PMCR0_DVFEV                     0x00800000
+#define MXC_CCM_PMCR0_DVFIS                     0x00400000
+#define MXC_CCM_PMCR0_LBMI                      0x00200000
+#define MXC_CCM_PMCR0_LBFL                      0x00100000
+#define MXC_CCM_PMCR0_LBCF_4                    (0x0 << 18)
+#define MXC_CCM_PMCR0_LBCF_8                    (0x1 << 18)
+#define MXC_CCM_PMCR0_LBCF_12                   (0x2 << 18)
+#define MXC_CCM_PMCR0_LBCF_16                   (0x3 << 18)
+#define MXC_CCM_PMCR0_LBCF_OFFSET               18
+#define MXC_CCM_PMCR0_LBCF_MASK                 (0x3 << 18)
+#define MXC_CCM_PMCR0_PTVIS                     0x00020000
+#define MXC_CCM_PMCR0_UPDTEN                    0x00010000
+#define MXC_CCM_PMCR0_UPDTEN_MASK               (0x1 << 16)
+#define MXC_CCM_PMCR0_FSVAIM                    0x00008000
+#define MXC_CCM_PMCR0_FSVAI_OFFSET              13
+#define MXC_CCM_PMCR0_FSVAI_MASK                (0x3 << 13)
+#define MXC_CCM_PMCR0_DPVCR                     0x00001000
+#define MXC_CCM_PMCR0_DPVV                      0x00000800
+#define MXC_CCM_PMCR0_WFIM                      0x00000400
+#define MXC_CCM_PMCR0_DRCE3                     0x00000200
+#define MXC_CCM_PMCR0_DRCE2                     0x00000100
+#define MXC_CCM_PMCR0_DRCE1                     0x00000080
+#define MXC_CCM_PMCR0_DRCE0                     0x00000040
+#define MXC_CCM_PMCR0_DCR                       0x00000020
+#define MXC_CCM_PMCR0_DVFEN                     0x00000010
+#define MXC_CCM_PMCR0_PTVAIM                    0x00000008
+#define MXC_CCM_PMCR0_PTVAI_OFFSET              1
+#define MXC_CCM_PMCR0_PTVAI_MASK                (0x3 << 1)
+#define MXC_CCM_PMCR0_DPTEN                     0x00000001
+
+#define MXC_CCM_PMCR1_DVGP_OFFSET               0
+#define MXC_CCM_PMCR1_DVGP_MASK                 (0xF)
+
+#define MXC_CCM_PMCR1_PLLRDIS                      (0x1 << 7)
+#define MXC_CCM_PMCR1_EMIRQ_EN                      (0x1 << 8)
+
+#define MXC_CCM_DCVR_ULV_MASK                   (0x3FF << 22)
+#define MXC_CCM_DCVR_ULV_OFFSET                 22
+#define MXC_CCM_DCVR_LLV_MASK                   (0x3FF << 12)
+#define MXC_CCM_DCVR_LLV_OFFSET                 12
+#define MXC_CCM_DCVR_ELV_MASK                   (0x3FF << 2)
+#define MXC_CCM_DCVR_ELV_OFFSET                 2
+
+#define MXC_CCM_PDR2_MST2_PDF_MASK              (0x3F << 7)
+#define MXC_CCM_PDR2_MST2_PDF_OFFSET            7
+#define MXC_CCM_PDR2_MST1_PDF_MASK              0x3F
+#define MXC_CCM_PDR2_MST1_PDF_OFFSET            0
+
+#define MXC_CCM_COSR_CLKOSEL_MASK               0x0F
+#define MXC_CCM_COSR_CLKOSEL_OFFSET             0
+#define MXC_CCM_COSR_CLKOUTDIV_MASK             (0x07 << 6)
+#define MXC_CCM_COSR_CLKOUTDIV_OFFSET           6
+#define MXC_CCM_COSR_CLKOEN                     (1 << 9)
+
+/*
+ * PMCR0 register offsets
+ */
+#define MXC_CCM_PMCR0_LBFL_OFFSET   20
+#define MXC_CCM_PMCR0_DFSUP0_OFFSET 30
+#define MXC_CCM_PMCR0_DFSUP1_OFFSET 31
+
+#endif				/* __ARCH_ARM_MACH_MX3_CRM_REGS_H__ */
diff -druN linux-2.6.39-libre/arch/arm/mach-imx/devices-imx1.h linux-3.0-rc7-libre/arch/arm/mach-imx/devices-imx1.h
--- linux-2.6.39-libre/arch/arm/mach-imx/devices-imx1.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-imx/devices-imx1.h	2011-07-11 19:51:52.000000000 -0400
@@ -9,21 +9,21 @@
 #include <mach/mx1.h>
 #include <mach/devices-common.h>
 
-extern const struct imx_imx_fb_data imx1_imx_fb_data __initconst;
+extern const struct imx_imx_fb_data imx1_imx_fb_data;
 #define imx1_add_imx_fb(pdata) \
     imx_add_imx_fb(&imx1_imx_fb_data, pdata)
 
-extern const struct imx_imx_i2c_data imx1_imx_i2c_data __initconst;
+extern const struct imx_imx_i2c_data imx1_imx_i2c_data;
 #define imx1_add_imx_i2c(pdata)		\
 	imx_add_imx_i2c(&imx1_imx_i2c_data, pdata)
 
-extern const struct imx_imx_uart_3irq_data imx1_imx_uart_data[] __initconst;
+extern const struct imx_imx_uart_3irq_data imx1_imx_uart_data[];
 #define imx1_add_imx_uart(id, pdata)	\
 	imx_add_imx_uart_3irq(&imx1_imx_uart_data[id], pdata)
 #define imx1_add_imx_uart0(pdata)	imx1_add_imx_uart(0, pdata)
 #define imx1_add_imx_uart1(pdata)	imx1_add_imx_uart(1, pdata)
 
-extern const struct imx_spi_imx_data imx1_cspi_data[] __initconst;
+extern const struct imx_spi_imx_data imx1_cspi_data[];
 #define imx1_add_cspi(id, pdata)   \
 	imx_add_spi_imx(&imx1_cspi_data[id], pdata)
 
diff -druN linux-2.6.39-libre/arch/arm/mach-imx/devices-imx21.h linux-3.0-rc7-libre/arch/arm/mach-imx/devices-imx21.h
--- linux-2.6.39-libre/arch/arm/mach-imx/devices-imx21.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-imx/devices-imx21.h	2011-07-11 19:51:52.000000000 -0400
@@ -9,31 +9,31 @@
 #include <mach/mx21.h>
 #include <mach/devices-common.h>
 
-extern const struct imx_imx21_hcd_data imx21_imx21_hcd_data __initconst;
+extern const struct imx_imx21_hcd_data imx21_imx21_hcd_data;
 #define imx21_add_imx21_hcd(pdata)	\
 	imx_add_imx21_hcd(&imx21_imx21_hcd_data, pdata)
 
-extern const struct imx_imx2_wdt_data imx21_imx2_wdt_data __initconst;
+extern const struct imx_imx2_wdt_data imx21_imx2_wdt_data;
 #define imx21_add_imx2_wdt(pdata)	\
 	imx_add_imx2_wdt(&imx21_imx2_wdt_data)
 
-extern const struct imx_imx_fb_data imx21_imx_fb_data __initconst;
+extern const struct imx_imx_fb_data imx21_imx_fb_data;
 #define imx21_add_imx_fb(pdata)	\
 	imx_add_imx_fb(&imx21_imx_fb_data, pdata)
 
-extern const struct imx_imx_i2c_data imx21_imx_i2c_data __initconst;
+extern const struct imx_imx_i2c_data imx21_imx_i2c_data;
 #define imx21_add_imx_i2c(pdata)	\
 	imx_add_imx_i2c(&imx21_imx_i2c_data, pdata)
 
-extern const struct imx_imx_keypad_data imx21_imx_keypad_data __initconst;
+extern const struct imx_imx_keypad_data imx21_imx_keypad_data;
 #define imx21_add_imx_keypad(pdata)	\
 	imx_add_imx_keypad(&imx21_imx_keypad_data, pdata)
 
-extern const struct imx_imx_ssi_data imx21_imx_ssi_data[] __initconst;
+extern const struct imx_imx_ssi_data imx21_imx_ssi_data[];
 #define imx21_add_imx_ssi(id, pdata)	\
 	imx_add_imx_ssi(&imx21_imx_ssi_data[id], pdata)
 
-extern const struct imx_imx_uart_1irq_data imx21_imx_uart_data[] __initconst;
+extern const struct imx_imx_uart_1irq_data imx21_imx_uart_data[];
 #define imx21_add_imx_uart(id, pdata)	\
 	imx_add_imx_uart_1irq(&imx21_imx_uart_data[id], pdata)
 #define imx21_add_imx_uart0(pdata)	imx21_add_imx_uart(0, pdata)
@@ -41,19 +41,19 @@
 #define imx21_add_imx_uart2(pdata)	imx21_add_imx_uart(2, pdata)
 #define imx21_add_imx_uart3(pdata)	imx21_add_imx_uart(3, pdata)
 
-extern const struct imx_mxc_mmc_data imx21_mxc_mmc_data[] __initconst;
+extern const struct imx_mxc_mmc_data imx21_mxc_mmc_data[];
 #define imx21_add_mxc_mmc(id, pdata)	\
 	imx_add_mxc_mmc(&imx21_mxc_mmc_data[id], pdata)
 
-extern const struct imx_mxc_nand_data imx21_mxc_nand_data __initconst;
+extern const struct imx_mxc_nand_data imx21_mxc_nand_data;
 #define imx21_add_mxc_nand(pdata)	\
 	imx_add_mxc_nand(&imx21_mxc_nand_data, pdata)
 
-extern const struct imx_mxc_w1_data imx21_mxc_w1_data __initconst;
+extern const struct imx_mxc_w1_data imx21_mxc_w1_data;
 #define imx21_add_mxc_w1(pdata)	\
 	imx_add_mxc_w1(&imx21_mxc_w1_data)
 
-extern const struct imx_spi_imx_data imx21_cspi_data[] __initconst;
+extern const struct imx_spi_imx_data imx21_cspi_data[];
 #define imx21_add_cspi(id, pdata)	\
 	imx_add_spi_imx(&imx21_cspi_data[id], pdata)
 #define imx21_add_spi_imx0(pdata)	imx21_add_cspi(0, pdata)
diff -druN linux-2.6.39-libre/arch/arm/mach-imx/devices-imx25.h linux-3.0-rc7-libre/arch/arm/mach-imx/devices-imx25.h
--- linux-2.6.39-libre/arch/arm/mach-imx/devices-imx25.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-imx/devices-imx25.h	2011-07-11 19:51:52.000000000 -0400
@@ -9,48 +9,48 @@
 #include <mach/mx25.h>
 #include <mach/devices-common.h>
 
-extern const struct imx_fec_data imx25_fec_data __initconst;
+extern const struct imx_fec_data imx25_fec_data;
 #define imx25_add_fec(pdata)	\
 	imx_add_fec(&imx25_fec_data, pdata)
 
-extern const struct imx_flexcan_data imx25_flexcan_data[] __initconst;
+extern const struct imx_flexcan_data imx25_flexcan_data[];
 #define imx25_add_flexcan(id, pdata)	\
 	imx_add_flexcan(&imx25_flexcan_data[id], pdata)
 #define imx25_add_flexcan0(pdata)	imx25_add_flexcan(0, pdata)
 #define imx25_add_flexcan1(pdata)	imx25_add_flexcan(1, pdata)
 
-extern const struct imx_fsl_usb2_udc_data imx25_fsl_usb2_udc_data __initconst;
+extern const struct imx_fsl_usb2_udc_data imx25_fsl_usb2_udc_data;
 #define imx25_add_fsl_usb2_udc(pdata)	\
 	imx_add_fsl_usb2_udc(&imx25_fsl_usb2_udc_data, pdata)
 
-extern struct imx_imxdi_rtc_data imx25_imxdi_rtc_data __initconst;
+extern struct imx_imxdi_rtc_data imx25_imxdi_rtc_data;
 #define imx25_add_imxdi_rtc(pdata)	\
 	imx_add_imxdi_rtc(&imx25_imxdi_rtc_data)
 
-extern const struct imx_imx2_wdt_data imx25_imx2_wdt_data __initconst;
+extern const struct imx_imx2_wdt_data imx25_imx2_wdt_data;
 #define imx25_add_imx2_wdt(pdata)	\
 	imx_add_imx2_wdt(&imx25_imx2_wdt_data)
 
-extern const struct imx_imx_fb_data imx25_imx_fb_data __initconst;
+extern const struct imx_imx_fb_data imx25_imx_fb_data;
 #define imx25_add_imx_fb(pdata)	\
 	imx_add_imx_fb(&imx25_imx_fb_data, pdata)
 
-extern const struct imx_imx_i2c_data imx25_imx_i2c_data[] __initconst;
+extern const struct imx_imx_i2c_data imx25_imx_i2c_data[];
 #define imx25_add_imx_i2c(id, pdata)	\
 	imx_add_imx_i2c(&imx25_imx_i2c_data[id], pdata)
 #define imx25_add_imx_i2c0(pdata)	imx25_add_imx_i2c(0, pdata)
 #define imx25_add_imx_i2c1(pdata)	imx25_add_imx_i2c(1, pdata)
 #define imx25_add_imx_i2c2(pdata)	imx25_add_imx_i2c(2, pdata)
 
-extern const struct imx_imx_keypad_data imx25_imx_keypad_data __initconst;
+extern const struct imx_imx_keypad_data imx25_imx_keypad_data;
 #define imx25_add_imx_keypad(pdata)	\
 	imx_add_imx_keypad(&imx25_imx_keypad_data, pdata)
 
-extern const struct imx_imx_ssi_data imx25_imx_ssi_data[] __initconst;
+extern const struct imx_imx_ssi_data imx25_imx_ssi_data[];
 #define imx25_add_imx_ssi(id, pdata)	\
 	imx_add_imx_ssi(&imx25_imx_ssi_data[id], pdata)
 
-extern const struct imx_imx_uart_1irq_data imx25_imx_uart_data[] __initconst;
+extern const struct imx_imx_uart_1irq_data imx25_imx_uart_data[];
 #define imx25_add_imx_uart(id, pdata)	\
 	imx_add_imx_uart_1irq(&imx25_imx_uart_data[id], pdata)
 #define imx25_add_imx_uart0(pdata)	imx25_add_imx_uart(0, pdata)
@@ -59,33 +59,32 @@
 #define imx25_add_imx_uart3(pdata)	imx25_add_imx_uart(3, pdata)
 #define imx25_add_imx_uart4(pdata)	imx25_add_imx_uart(4, pdata)
 
-extern const struct imx_mx2_camera_data imx25_mx2_camera_data __initconst;
+extern const struct imx_mx2_camera_data imx25_mx2_camera_data;
 #define imx25_add_mx2_camera(pdata)	\
 	imx_add_mx2_camera(&imx25_mx2_camera_data, pdata)
 
-extern const struct imx_mxc_ehci_data imx25_mxc_ehci_otg_data __initconst;
+extern const struct imx_mxc_ehci_data imx25_mxc_ehci_otg_data;
 #define imx25_add_mxc_ehci_otg(pdata)	\
 	imx_add_mxc_ehci(&imx25_mxc_ehci_otg_data, pdata)
-extern const struct imx_mxc_ehci_data imx25_mxc_ehci_hs_data __initconst;
+extern const struct imx_mxc_ehci_data imx25_mxc_ehci_hs_data;
 #define imx25_add_mxc_ehci_hs(pdata)	\
 	imx_add_mxc_ehci(&imx25_mxc_ehci_hs_data, pdata)
 
-extern const struct imx_mxc_nand_data imx25_mxc_nand_data __initconst;
+extern const struct imx_mxc_nand_data imx25_mxc_nand_data;
 #define imx25_add_mxc_nand(pdata)	\
 	imx_add_mxc_nand(&imx25_mxc_nand_data, pdata)
 
-extern const struct imx_sdhci_esdhc_imx_data
-imx25_sdhci_esdhc_imx_data[] __initconst;
+extern const struct imx_sdhci_esdhc_imx_data imx25_sdhci_esdhc_imx_data[];
 #define imx25_add_sdhci_esdhc_imx(id, pdata)	\
 	imx_add_sdhci_esdhc_imx(&imx25_sdhci_esdhc_imx_data[id], pdata)
 
-extern const struct imx_spi_imx_data imx25_cspi_data[] __initconst;
+extern const struct imx_spi_imx_data imx25_cspi_data[];
 #define imx25_add_spi_imx(id, pdata)	\
 	imx_add_spi_imx(&imx25_cspi_data[id], pdata)
 #define imx25_add_spi_imx0(pdata)	imx25_add_spi_imx(0, pdata)
 #define imx25_add_spi_imx1(pdata)	imx25_add_spi_imx(1, pdata)
 #define imx25_add_spi_imx2(pdata)	imx25_add_spi_imx(2, pdata)
 
-extern struct imx_mxc_pwm_data imx25_mxc_pwm_data[] __initconst;
+extern struct imx_mxc_pwm_data imx25_mxc_pwm_data[];
 #define imx25_add_mxc_pwm(id)	\
 	imx_add_mxc_pwm(&imx25_mxc_pwm_data[id])
diff -druN linux-2.6.39-libre/arch/arm/mach-imx/devices-imx27.h linux-3.0-rc7-libre/arch/arm/mach-imx/devices-imx27.h
--- linux-2.6.39-libre/arch/arm/mach-imx/devices-imx27.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-imx/devices-imx27.h	2011-07-11 19:51:52.000000000 -0400
@@ -9,35 +9,35 @@
 #include <mach/mx27.h>
 #include <mach/devices-common.h>
 
-extern const struct imx_fec_data imx27_fec_data __initconst;
+extern const struct imx_fec_data imx27_fec_data;
 #define imx27_add_fec(pdata)	\
 	imx_add_fec(&imx27_fec_data, pdata)
 
-extern const struct imx_fsl_usb2_udc_data imx27_fsl_usb2_udc_data __initconst;
+extern const struct imx_fsl_usb2_udc_data imx27_fsl_usb2_udc_data;
 #define imx27_add_fsl_usb2_udc(pdata)	\
 	imx_add_fsl_usb2_udc(&imx27_fsl_usb2_udc_data, pdata)
 
-extern const struct imx_imx2_wdt_data imx27_imx2_wdt_data __initconst;
+extern const struct imx_imx2_wdt_data imx27_imx2_wdt_data;
 #define imx27_add_imx2_wdt(pdata)	\
 	imx_add_imx2_wdt(&imx27_imx2_wdt_data)
 
-extern const struct imx_imx_fb_data imx27_imx_fb_data __initconst;
+extern const struct imx_imx_fb_data imx27_imx_fb_data;
 #define imx27_add_imx_fb(pdata)	\
 	imx_add_imx_fb(&imx27_imx_fb_data, pdata)
 
-extern const struct imx_imx_i2c_data imx27_imx_i2c_data[] __initconst;
+extern const struct imx_imx_i2c_data imx27_imx_i2c_data[];
 #define imx27_add_imx_i2c(id, pdata)	\
 	imx_add_imx_i2c(&imx27_imx_i2c_data[id], pdata)
 
-extern const struct imx_imx_keypad_data imx27_imx_keypad_data __initconst;
+extern const struct imx_imx_keypad_data imx27_imx_keypad_data;
 #define imx27_add_imx_keypad(pdata)	\
 	imx_add_imx_keypad(&imx27_imx_keypad_data, pdata)
 
-extern const struct imx_imx_ssi_data imx27_imx_ssi_data[] __initconst;
+extern const struct imx_imx_ssi_data imx27_imx_ssi_data[];
 #define imx27_add_imx_ssi(id, pdata)    \
 	imx_add_imx_ssi(&imx27_imx_ssi_data[id], pdata)
 
-extern const struct imx_imx_uart_1irq_data imx27_imx_uart_data[] __initconst;
+extern const struct imx_imx_uart_1irq_data imx27_imx_uart_data[];
 #define imx27_add_imx_uart(id, pdata)	\
 	imx_add_imx_uart_1irq(&imx27_imx_uart_data[id], pdata)
 #define imx27_add_imx_uart0(pdata)	imx27_add_imx_uart(0, pdata)
@@ -47,30 +47,30 @@
 #define imx27_add_imx_uart4(pdata)	imx27_add_imx_uart(4, pdata)
 #define imx27_add_imx_uart5(pdata)	imx27_add_imx_uart(5, pdata)
 
-extern const struct imx_mx2_camera_data imx27_mx2_camera_data __initconst;
+extern const struct imx_mx2_camera_data imx27_mx2_camera_data;
 #define imx27_add_mx2_camera(pdata)	\
 	imx_add_mx2_camera(&imx27_mx2_camera_data, pdata)
 
-extern const struct imx_mxc_ehci_data imx27_mxc_ehci_otg_data __initconst;
+extern const struct imx_mxc_ehci_data imx27_mxc_ehci_otg_data;
 #define imx27_add_mxc_ehci_otg(pdata)	\
 	imx_add_mxc_ehci(&imx27_mxc_ehci_otg_data, pdata)
-extern const struct imx_mxc_ehci_data imx27_mxc_ehci_hs_data[] __initconst;
+extern const struct imx_mxc_ehci_data imx27_mxc_ehci_hs_data[];
 #define imx27_add_mxc_ehci_hs(id, pdata)	\
 	imx_add_mxc_ehci(&imx27_mxc_ehci_hs_data[id - 1], pdata)
 
-extern const struct imx_mxc_mmc_data imx27_mxc_mmc_data[] __initconst;
+extern const struct imx_mxc_mmc_data imx27_mxc_mmc_data[];
 #define imx27_add_mxc_mmc(id, pdata)	\
 	imx_add_mxc_mmc(&imx27_mxc_mmc_data[id], pdata)
 
-extern const struct imx_mxc_nand_data imx27_mxc_nand_data __initconst;
+extern const struct imx_mxc_nand_data imx27_mxc_nand_data;
 #define imx27_add_mxc_nand(pdata)	\
 	imx_add_mxc_nand(&imx27_mxc_nand_data, pdata)
 
-extern const struct imx_mxc_w1_data imx27_mxc_w1_data __initconst;
+extern const struct imx_mxc_w1_data imx27_mxc_w1_data;
 #define imx27_add_mxc_w1(pdata)	\
 	imx_add_mxc_w1(&imx27_mxc_w1_data)
 
-extern const struct imx_spi_imx_data imx27_cspi_data[] __initconst;
+extern const struct imx_spi_imx_data imx27_cspi_data[];
 #define imx27_add_cspi(id, pdata)	\
 	imx_add_spi_imx(&imx27_cspi_data[id], pdata)
 #define imx27_add_spi_imx0(pdata)	imx27_add_cspi(0, pdata)
diff -druN linux-2.6.39-libre/arch/arm/mach-imx/devices-imx31.h linux-3.0-rc7-libre/arch/arm/mach-imx/devices-imx31.h
--- linux-2.6.39-libre/arch/arm/mach-imx/devices-imx31.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/arm/mach-imx/devices-imx31.h	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2010 Pengutronix
+ * Uwe Kleine-Koenig <u.kleine-koenig@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 <mach/mx31.h>
+#include <mach/devices-common.h>
+
+extern const struct imx_fsl_usb2_udc_data imx31_fsl_usb2_udc_data;
+#define imx31_add_fsl_usb2_udc(pdata)	\
+	imx_add_fsl_usb2_udc(&imx31_fsl_usb2_udc_data, pdata)
+
+extern const struct imx_imx2_wdt_data imx31_imx2_wdt_data;
+#define imx31_add_imx2_wdt(pdata)       \
+	imx_add_imx2_wdt(&imx31_imx2_wdt_data)
+
+extern const struct imx_imx_i2c_data imx31_imx_i2c_data[];
+#define imx31_add_imx_i2c(id, pdata)	\
+	imx_add_imx_i2c(&imx31_imx_i2c_data[id], pdata)
+#define imx31_add_imx_i2c0(pdata)	imx31_add_imx_i2c(0, pdata)
+#define imx31_add_imx_i2c1(pdata)	imx31_add_imx_i2c(1, pdata)
+#define imx31_add_imx_i2c2(pdata)	imx31_add_imx_i2c(2, pdata)
+
+extern const struct imx_imx_keypad_data imx31_imx_keypad_data;
+#define imx31_add_imx_keypad(pdata)	\
+	imx_add_imx_keypad(&imx31_imx_keypad_data, pdata)
+
+extern const struct imx_imx_ssi_data imx31_imx_ssi_data[];
+#define imx31_add_imx_ssi(id, pdata)    \
+	imx_add_imx_ssi(&imx31_imx_ssi_data[id], pdata)
+
+extern const struct imx_imx_uart_1irq_data imx31_imx_uart_data[];
+#define imx31_add_imx_uart(id, pdata)	\
+	imx_add_imx_uart_1irq(&imx31_imx_uart_data[id], pdata)
+#define imx31_add_imx_uart0(pdata)	imx31_add_imx_uart(0, pdata)
+#define imx31_add_imx_uart1(pdata)	imx31_add_imx_uart(1, pdata)
+#define imx31_add_imx_uart2(pdata)	imx31_add_imx_uart(2, pdata)
+#define imx31_add_imx_uart3(pdata)	imx31_add_imx_uart(3, pdata)
+#define imx31_add_imx_uart4(pdata)	imx31_add_imx_uart(4, pdata)
+
+extern const struct imx_ipu_core_data imx31_ipu_core_data;
+#define imx31_add_ipu_core(pdata)	\
+	imx_add_ipu_core(&imx31_ipu_core_data, pdata)
+#define imx31_alloc_mx3_camera(pdata)	\
+	imx_alloc_mx3_camera(&imx31_ipu_core_data, pdata)
+#define imx31_add_mx3_sdc_fb(pdata)	\
+	imx_add_mx3_sdc_fb(&imx31_ipu_core_data, pdata)
+
+extern const struct imx_mxc_ehci_data imx31_mxc_ehci_otg_data;
+#define imx31_add_mxc_ehci_otg(pdata)	\
+	imx_add_mxc_ehci(&imx31_mxc_ehci_otg_data, pdata)
+extern const struct imx_mxc_ehci_data imx31_mxc_ehci_hs_data[];
+#define imx31_add_mxc_ehci_hs(id, pdata)	\
+	imx_add_mxc_ehci(&imx31_mxc_ehci_hs_data[id - 1], pdata)
+
+extern const struct imx_mxc_mmc_data imx31_mxc_mmc_data[];
+#define imx31_add_mxc_mmc(id, pdata)	\
+	imx_add_mxc_mmc(&imx31_mxc_mmc_data[id], pdata)
+
+extern const struct imx_mxc_nand_data imx31_mxc_nand_data;
+#define imx31_add_mxc_nand(pdata)	\
+	imx_add_mxc_nand(&imx31_mxc_nand_data, pdata)
+
+extern const struct imx_mxc_rtc_data imx31_mxc_rtc_data;
+#define imx31_add_mxc_rtc(pdata)	\
+	imx_add_mxc_rtc(&imx31_mxc_rtc_data)
+
+extern const struct imx_mxc_w1_data imx31_mxc_w1_data;
+#define imx31_add_mxc_w1(pdata)	\
+	imx_add_mxc_w1(&imx31_mxc_w1_data)
+
+extern const struct imx_spi_imx_data imx31_cspi_data[];
+#define imx31_add_cspi(id, pdata)	\
+	imx_add_spi_imx(&imx31_cspi_data[id], pdata)
+#define imx31_add_spi_imx0(pdata)	imx31_add_cspi(0, pdata)
+#define imx31_add_spi_imx1(pdata)	imx31_add_cspi(1, pdata)
+#define imx31_add_spi_imx2(pdata)	imx31_add_cspi(2, pdata)
diff -druN linux-2.6.39-libre/arch/arm/mach-imx/devices-imx35.h linux-3.0-rc7-libre/arch/arm/mach-imx/devices-imx35.h
--- linux-2.6.39-libre/arch/arm/mach-imx/devices-imx35.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/arm/mach-imx/devices-imx35.h	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2010 Pengutronix
+ * Uwe Kleine-Koenig <u.kleine-koenig@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 <mach/mx35.h>
+#include <mach/devices-common.h>
+
+extern const struct imx_fec_data imx35_fec_data;
+#define imx35_add_fec(pdata)	\
+	imx_add_fec(&imx35_fec_data, pdata)
+
+extern const struct imx_fsl_usb2_udc_data imx35_fsl_usb2_udc_data;
+#define imx35_add_fsl_usb2_udc(pdata)	\
+	imx_add_fsl_usb2_udc(&imx35_fsl_usb2_udc_data, pdata)
+
+extern const struct imx_flexcan_data imx35_flexcan_data[];
+#define imx35_add_flexcan(id, pdata)	\
+	imx_add_flexcan(&imx35_flexcan_data[id], pdata)
+#define imx35_add_flexcan0(pdata)	imx35_add_flexcan(0, pdata)
+#define imx35_add_flexcan1(pdata)	imx35_add_flexcan(1, pdata)
+
+extern const struct imx_imx2_wdt_data imx35_imx2_wdt_data;
+#define imx35_add_imx2_wdt(pdata)       \
+	imx_add_imx2_wdt(&imx35_imx2_wdt_data)
+
+extern const struct imx_imx_i2c_data imx35_imx_i2c_data[];
+#define imx35_add_imx_i2c(id, pdata)	\
+	imx_add_imx_i2c(&imx35_imx_i2c_data[id], pdata)
+#define imx35_add_imx_i2c0(pdata)	imx35_add_imx_i2c(0, pdata)
+#define imx35_add_imx_i2c1(pdata)	imx35_add_imx_i2c(1, pdata)
+#define imx35_add_imx_i2c2(pdata)	imx35_add_imx_i2c(2, pdata)
+
+extern const struct imx_imx_keypad_data imx35_imx_keypad_data;
+#define imx35_add_imx_keypad(pdata)	\
+	imx_add_imx_keypad(&imx35_imx_keypad_data, pdata)
+
+extern const struct imx_imx_ssi_data imx35_imx_ssi_data[];
+#define imx35_add_imx_ssi(id, pdata)    \
+	imx_add_imx_ssi(&imx35_imx_ssi_data[id], pdata)
+
+extern const struct imx_imx_uart_1irq_data imx35_imx_uart_data[];
+#define imx35_add_imx_uart(id, pdata)	\
+	imx_add_imx_uart_1irq(&imx35_imx_uart_data[id], pdata)
+#define imx35_add_imx_uart0(pdata)	imx35_add_imx_uart(0, pdata)
+#define imx35_add_imx_uart1(pdata)	imx35_add_imx_uart(1, pdata)
+#define imx35_add_imx_uart2(pdata)	imx35_add_imx_uart(2, pdata)
+
+extern const struct imx_ipu_core_data imx35_ipu_core_data;
+#define imx35_add_ipu_core(pdata)	\
+	imx_add_ipu_core(&imx35_ipu_core_data, pdata)
+#define imx35_alloc_mx3_camera(pdata)	\
+	imx_alloc_mx3_camera(&imx35_ipu_core_data, pdata)
+#define imx35_add_mx3_sdc_fb(pdata)	\
+	imx_add_mx3_sdc_fb(&imx35_ipu_core_data, pdata)
+
+extern const struct imx_mxc_ehci_data imx35_mxc_ehci_otg_data;
+#define imx35_add_mxc_ehci_otg(pdata)	\
+	imx_add_mxc_ehci(&imx35_mxc_ehci_otg_data, pdata)
+extern const struct imx_mxc_ehci_data imx35_mxc_ehci_hs_data;
+#define imx35_add_mxc_ehci_hs(pdata)	\
+	imx_add_mxc_ehci(&imx35_mxc_ehci_hs_data, pdata)
+
+extern const struct imx_mxc_nand_data imx35_mxc_nand_data;
+#define imx35_add_mxc_nand(pdata)	\
+	imx_add_mxc_nand(&imx35_mxc_nand_data, pdata)
+
+extern const struct imx_mxc_w1_data imx35_mxc_w1_data;
+#define imx35_add_mxc_w1(pdata)	\
+	imx_add_mxc_w1(&imx35_mxc_w1_data)
+
+extern const struct imx_sdhci_esdhc_imx_data imx35_sdhci_esdhc_imx_data[];
+#define imx35_add_sdhci_esdhc_imx(id, pdata)	\
+	imx_add_sdhci_esdhc_imx(&imx35_sdhci_esdhc_imx_data[id], pdata)
+
+extern const struct imx_spi_imx_data imx35_cspi_data[];
+#define imx35_add_cspi(id, pdata)	\
+	imx_add_spi_imx(&imx35_cspi_data[id], pdata)
+#define imx35_add_spi_imx0(pdata)	imx35_add_cspi(0, pdata)
+#define imx35_add_spi_imx1(pdata)	imx35_add_cspi(1, pdata)
diff -druN linux-2.6.39-libre/arch/arm/mach-imx/ehci-imx31.c linux-3.0-rc7-libre/arch/arm/mach-imx/ehci-imx31.c
--- linux-2.6.39-libre/arch/arm/mach-imx/ehci-imx31.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/arm/mach-imx/ehci-imx31.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2009 Daniel Mack <daniel@caiaq.de>
+ * Copyright (C) 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.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ */
+
+#include <linux/platform_device.h>
+#include <linux/io.h>
+
+#include <mach/hardware.h>
+#include <mach/mxc_ehci.h>
+
+#define USBCTRL_OTGBASE_OFFSET	0x600
+
+#define MX31_OTG_SIC_SHIFT	29
+#define MX31_OTG_SIC_MASK	(0x3 << MX31_OTG_SIC_SHIFT)
+#define MX31_OTG_PM_BIT		(1 << 24)
+
+#define MX31_H2_SIC_SHIFT	21
+#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	(0x3 << MX31_H1_SIC_SHIFT)
+#define MX31_H1_PM_BIT		(1 << 8)
+#define MX31_H1_DT_BIT		(1 << 4)
+
+int mx31_initialize_usb_hw(int port, unsigned int flags)
+{
+	unsigned int v;
+
+	v = readl(MX31_IO_ADDRESS(MX31_USB_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, MX31_IO_ADDRESS(MX31_USB_BASE_ADDR + USBCTRL_OTGBASE_OFFSET));
+
+	return 0;
+}
diff -druN linux-2.6.39-libre/arch/arm/mach-imx/ehci-imx35.c linux-3.0-rc7-libre/arch/arm/mach-imx/ehci-imx35.c
--- linux-2.6.39-libre/arch/arm/mach-imx/ehci-imx35.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/arm/mach-imx/ehci-imx35.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2009 Daniel Mack <daniel@caiaq.de>
+ * Copyright (C) 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.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ */
+
+#include <linux/platform_device.h>
+#include <linux/io.h>
+
+#include <mach/hardware.h>
+#include <mach/mxc_ehci.h>
+
+#define USBCTRL_OTGBASE_OFFSET	0x600
+
+#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 mx35_initialize_usb_hw(int port, unsigned int flags)
+{
+	unsigned int v;
+
+	v = readl(MX35_IO_ADDRESS(MX35_USB_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_USB_BASE_ADDR + USBCTRL_OTGBASE_OFFSET));
+
+	return 0;
+}
diff -druN linux-2.6.39-libre/arch/arm/mach-imx/eukrea_mbimx27-baseboard.c linux-3.0-rc7-libre/arch/arm/mach-imx/eukrea_mbimx27-baseboard.c
--- linux-2.6.39-libre/arch/arm/mach-imx/eukrea_mbimx27-baseboard.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-imx/eukrea_mbimx27-baseboard.c	2011-07-11 19:51:52.000000000 -0400
@@ -32,7 +32,6 @@
 #include <mach/common.h>
 #include <mach/iomux-mx27.h>
 #include <mach/hardware.h>
-#include <mach/spi.h>
 #include <mach/audmux.h>
 
 #include "devices-imx27.h"
diff -druN linux-2.6.39-libre/arch/arm/mach-imx/eukrea_mbimxsd25-baseboard.c linux-3.0-rc7-libre/arch/arm/mach-imx/eukrea_mbimxsd25-baseboard.c
--- linux-2.6.39-libre/arch/arm/mach-imx/eukrea_mbimxsd25-baseboard.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-imx/eukrea_mbimxsd25-baseboard.c	2011-07-11 19:51:52.000000000 -0400
@@ -22,7 +22,6 @@
 #include <linux/gpio.h>
 #include <linux/leds.h>
 #include <linux/platform_device.h>
-#include <linux/gpio_keys.h>
 #include <linux/input.h>
 #include <video/platform_lcd.h>
 
@@ -32,9 +31,7 @@
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 #include <mach/mx25.h>
-#include <mach/imx-uart.h>
 #include <mach/audmux.h>
-#include <mach/esdhc.h>
 
 #include "devices-imx25.h"
 
@@ -208,23 +205,14 @@
 	},
 };
 
-static struct gpio_keys_platform_data eukrea_mbimxsd_button_data = {
+static const struct gpio_keys_platform_data
+		eukrea_mbimxsd_button_data __initconst = {
 	.buttons	= eukrea_mbimxsd_gpio_buttons,
 	.nbuttons	= ARRAY_SIZE(eukrea_mbimxsd_gpio_buttons),
 };
 
-static struct platform_device eukrea_mbimxsd_button_device = {
-	.name		= "gpio-keys",
-	.id		= -1,
-	.num_resources	= 0,
-	.dev		= {
-		.platform_data	= &eukrea_mbimxsd_button_data,
-	}
-};
-
 static struct platform_device *platform_devices[] __initdata = {
 	&eukrea_mbimxsd_leds_gpio,
-	&eukrea_mbimxsd_button_device,
 	&eukrea_mbimxsd_lcd_powerdev,
 };
 
@@ -299,4 +287,5 @@
 				ARRAY_SIZE(eukrea_mbimxsd_i2c_devices));
 
 	platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices));
+	imx_add_gpio_keys(&eukrea_mbimxsd_button_data);
 }
diff -druN linux-2.6.39-libre/arch/arm/mach-imx/eukrea_mbimxsd35-baseboard.c linux-3.0-rc7-libre/arch/arm/mach-imx/eukrea_mbimxsd35-baseboard.c
--- linux-2.6.39-libre/arch/arm/mach-imx/eukrea_mbimxsd35-baseboard.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/arm/mach-imx/eukrea_mbimxsd35-baseboard.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,303 @@
+/*
+ * Copyright (C) 2010 Eric Benard - eric@eukrea.com
+ *
+ * Based on pcm970-baseboard.c which is :
+ * 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/types.h>
+#include <linux/init.h>
+
+#include <linux/gpio.h>
+#include <linux/interrupt.h>
+#include <linux/leds.h>
+#include <linux/platform_device.h>
+#include <linux/input.h>
+#include <video/platform_lcd.h>
+#include <linux/i2c.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-mx35.h>
+#include <mach/audmux.h>
+
+#include "devices-imx35.h"
+
+static const struct fb_videomode fb_modedb[] = {
+	{
+		.name		= "CMO-QVGA",
+		.refresh	= 60,
+		.xres		= 320,
+		.yres		= 240,
+		.pixclock	= KHZ2PICOS(6500),
+		.left_margin	= 68,
+		.right_margin	= 20,
+		.upper_margin	= 15,
+		.lower_margin	= 4,
+		.hsync_len	= 30,
+		.vsync_len	= 3,
+		.sync		= 0,
+		.vmode		= FB_VMODE_NONINTERLACED,
+		.flag		= 0,
+	},
+	{
+		.name		= "DVI-VGA",
+		.refresh	= 60,
+		.xres		= 640,
+		.yres		= 480,
+		.pixclock	= 32000,
+		.left_margin	= 100,
+		.right_margin	= 100,
+		.upper_margin	= 7,
+		.lower_margin	= 100,
+		.hsync_len	= 7,
+		.vsync_len	= 7,
+		.sync		= FB_SYNC_VERT_HIGH_ACT | FB_SYNC_HOR_HIGH_ACT |
+				  FB_SYNC_OE_ACT_HIGH | FB_SYNC_CLK_INVERT,
+		.vmode		= FB_VMODE_NONINTERLACED,
+		.flag		= 0,
+	},
+	{
+		.name		= "DVI-SVGA",
+		.refresh	= 60,
+		.xres		= 800,
+		.yres		= 600,
+		.pixclock	= 25000,
+		.left_margin	= 75,
+		.right_margin	= 75,
+		.upper_margin	= 7,
+		.lower_margin	= 75,
+		.hsync_len	= 7,
+		.vsync_len	= 7,
+		.sync		= FB_SYNC_VERT_HIGH_ACT | FB_SYNC_HOR_HIGH_ACT |
+				  FB_SYNC_OE_ACT_HIGH | FB_SYNC_CLK_INVERT,
+		.vmode		= FB_VMODE_NONINTERLACED,
+		.flag		= 0,
+	},
+};
+
+static const struct ipu_platform_data mx3_ipu_data __initconst = {
+	.irq_base = MXC_IPU_IRQ_START,
+};
+
+static struct mx3fb_platform_data mx3fb_pdata __initdata = {
+	.name		= "CMO-QVGA",
+	.mode		= fb_modedb,
+	.num_modes	= ARRAY_SIZE(fb_modedb),
+};
+
+static iomux_v3_cfg_t eukrea_mbimxsd_pads[] = {
+	/* LCD */
+	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_D3_VSYNC__IPU_DISPB_D3_VSYNC,
+	/* Backlight */
+	MX35_PAD_CONTRAST__IPU_DISPB_CONTR,
+	/* LCD_PWR */
+	MX35_PAD_D3_CLS__GPIO1_4,
+	/* LED */
+	MX35_PAD_LD23__GPIO3_29,
+	/* SWITCH */
+	MX35_PAD_LD19__GPIO3_25,
+	/* UART2 */
+	MX35_PAD_CTS2__UART2_CTS,
+	MX35_PAD_RTS2__UART2_RTS,
+	MX35_PAD_TXD2__UART2_TXD_MUX,
+	MX35_PAD_RXD2__UART2_RXD_MUX,
+	/* I2S */
+	MX35_PAD_STXFS4__AUDMUX_AUD4_TXFS,
+	MX35_PAD_STXD4__AUDMUX_AUD4_TXD,
+	MX35_PAD_SRXD4__AUDMUX_AUD4_RXD,
+	MX35_PAD_SCK4__AUDMUX_AUD4_TXC,
+	/* CAN2 */
+	MX35_PAD_TX5_RX0__CAN2_TXCAN,
+	MX35_PAD_TX4_RX1__CAN2_RXCAN,
+	/* SDCARD */
+	MX35_PAD_SD1_CMD__ESDHC1_CMD,
+	MX35_PAD_SD1_CLK__ESDHC1_CLK,
+	MX35_PAD_SD1_DATA0__ESDHC1_DAT0,
+	MX35_PAD_SD1_DATA1__ESDHC1_DAT1,
+	MX35_PAD_SD1_DATA2__ESDHC1_DAT2,
+	MX35_PAD_SD1_DATA3__ESDHC1_DAT3,
+	/* SD1 CD */
+	MX35_PAD_LD18__GPIO3_24,
+};
+
+#define GPIO_LED1	IMX_GPIO_NR(3, 29)
+#define GPIO_SWITCH1	IMX_GPIO_NR(3, 25)
+#define GPIO_LCDPWR	IMX_GPIO_NR(1, 4)
+#define GPIO_SD1CD	IMX_GPIO_NR(3, 24)
+
+static void eukrea_mbimxsd_lcd_power_set(struct plat_lcd_data *pd,
+				   unsigned int power)
+{
+	if (power)
+		gpio_direction_output(GPIO_LCDPWR, 1);
+	else
+		gpio_direction_output(GPIO_LCDPWR, 0);
+}
+
+static struct plat_lcd_data eukrea_mbimxsd_lcd_power_data = {
+	.set_power		= eukrea_mbimxsd_lcd_power_set,
+};
+
+static struct platform_device eukrea_mbimxsd_lcd_powerdev = {
+	.name			= "platform-lcd",
+	.dev.platform_data	= &eukrea_mbimxsd_lcd_power_data,
+};
+
+static struct gpio_led eukrea_mbimxsd_leds[] = {
+	{
+		.name			= "led1",
+		.default_trigger	= "heartbeat",
+		.active_low		= 1,
+		.gpio			= GPIO_LED1,
+	},
+};
+
+static struct gpio_led_platform_data eukrea_mbimxsd_led_info = {
+	.leds		= eukrea_mbimxsd_leds,
+	.num_leds	= ARRAY_SIZE(eukrea_mbimxsd_leds),
+};
+
+static struct platform_device eukrea_mbimxsd_leds_gpio = {
+	.name	= "leds-gpio",
+	.id	= -1,
+	.dev	= {
+		.platform_data	= &eukrea_mbimxsd_led_info,
+	},
+};
+
+static struct gpio_keys_button eukrea_mbimxsd_gpio_buttons[] = {
+	{
+		.gpio		= GPIO_SWITCH1,
+		.code		= BTN_0,
+		.desc		= "BP1",
+		.active_low	= 1,
+		.wakeup		= 1,
+	},
+};
+
+static const struct gpio_keys_platform_data
+		eukrea_mbimxsd_button_data __initconst = {
+	.buttons	= eukrea_mbimxsd_gpio_buttons,
+	.nbuttons	= ARRAY_SIZE(eukrea_mbimxsd_gpio_buttons),
+};
+
+static struct platform_device *platform_devices[] __initdata = {
+	&eukrea_mbimxsd_leds_gpio,
+	&eukrea_mbimxsd_lcd_powerdev,
+};
+
+static const struct imxuart_platform_data uart_pdata __initconst = {
+	.flags = IMXUART_HAVE_RTSCTS,
+};
+
+static struct i2c_board_info eukrea_mbimxsd_i2c_devices[] = {
+	{
+		I2C_BOARD_INFO("tlv320aic23", 0x1a),
+	},
+};
+
+static const
+struct imx_ssi_platform_data eukrea_mbimxsd_ssi_pdata __initconst = {
+	.flags = IMX_SSI_SYN | IMX_SSI_NET | IMX_SSI_USE_I2S_SLAVE,
+};
+
+static struct esdhc_platform_data sd1_pdata = {
+	.cd_gpio = GPIO_SD1CD,
+	.wp_gpio = -EINVAL,
+};
+
+/*
+ * system init for baseboard usage. Will be called by cpuimx35 init.
+ *
+ * Add platform devices present on this baseboard and init
+ * them from CPU side as far as required to use them later on
+ */
+void __init eukrea_mbimxsd35_baseboard_init(void)
+{
+	if (mxc_iomux_v3_setup_multiple_pads(eukrea_mbimxsd_pads,
+			ARRAY_SIZE(eukrea_mbimxsd_pads)))
+		printk(KERN_ERR "error setting mbimxsd pads !\n");
+
+#if defined(CONFIG_SND_SOC_EUKREA_TLV320)
+	/* SSI unit master I2S codec connected to SSI_AUD4 */
+	mxc_audmux_v2_configure_port(0,
+			MXC_AUDMUX_V2_PTCR_SYN |
+			MXC_AUDMUX_V2_PTCR_TFSDIR |
+			MXC_AUDMUX_V2_PTCR_TFSEL(3) |
+			MXC_AUDMUX_V2_PTCR_TCLKDIR |
+			MXC_AUDMUX_V2_PTCR_TCSEL(3),
+			MXC_AUDMUX_V2_PDCR_RXDSEL(3)
+	);
+	mxc_audmux_v2_configure_port(3,
+			MXC_AUDMUX_V2_PTCR_SYN,
+			MXC_AUDMUX_V2_PDCR_RXDSEL(0)
+	);
+#endif
+
+	imx35_add_imx_uart1(&uart_pdata);
+	imx35_add_ipu_core(&mx3_ipu_data);
+	imx35_add_mx3_sdc_fb(&mx3fb_pdata);
+
+	imx35_add_imx_ssi(0, &eukrea_mbimxsd_ssi_pdata);
+
+	imx35_add_flexcan1(NULL);
+	imx35_add_sdhci_esdhc_imx(0, &sd1_pdata);
+
+	gpio_request(GPIO_LED1, "LED1");
+	gpio_direction_output(GPIO_LED1, 1);
+	gpio_free(GPIO_LED1);
+
+	gpio_request(GPIO_SWITCH1, "SWITCH1");
+	gpio_direction_input(GPIO_SWITCH1);
+	gpio_free(GPIO_SWITCH1);
+
+	gpio_request(GPIO_LCDPWR, "LCDPWR");
+	gpio_direction_output(GPIO_LCDPWR, 1);
+
+	i2c_register_board_info(0, eukrea_mbimxsd_i2c_devices,
+				ARRAY_SIZE(eukrea_mbimxsd_i2c_devices));
+
+	platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices));
+	imx_add_gpio_keys(&eukrea_mbimxsd_button_data);
+}
diff -druN linux-2.6.39-libre/arch/arm/mach-imx/iomux-imx31.c linux-3.0-rc7-libre/arch/arm/mach-imx/iomux-imx31.c
--- linux-2.6.39-libre/arch/arm/mach-imx/iomux-imx31.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/arm/mach-imx/iomux-imx31.c	2011-07-11 19:51:52.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(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(const unsigned int *pin_list, unsigned count,
+		const char *label)
+{
+	const 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(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(const unsigned int *pin_list, int count)
+{
+	const 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 -druN linux-2.6.39-libre/arch/arm/mach-imx/Kconfig linux-3.0-rc7-libre/arch/arm/mach-imx/Kconfig
--- linux-2.6.39-libre/arch/arm/mach-imx/Kconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-imx/Kconfig	2011-07-11 19:51:52.000000000 -0400
@@ -1,5 +1,15 @@
 config IMX_HAVE_DMA_V1
 	bool
+#
+# ARCH_MX31 and ARCH_MX35 are left for compatibility
+# Some usages assume that having one of them implies not having (e.g.) ARCH_MX2.
+# To easily distinguish good and reviewed from unreviewed usages new (and IMHO
+# more sensible) names are used: SOC_IMX31 and SOC_IMX35
+config ARCH_MX31
+	bool
+
+config ARCH_MX35
+	bool
 
 config SOC_IMX1
 	bool
@@ -31,6 +41,24 @@
 	select IMX_HAVE_IOMUX_V1
 	select MXC_AVIC
 
+config SOC_IMX31
+	bool
+	select CPU_V6
+	select IMX_HAVE_PLATFORM_MXC_RNGA
+	select ARCH_MXC_AUDMUX_V2
+	select ARCH_MX31
+	select MXC_AVIC
+
+config SOC_IMX35
+	bool
+	select CPU_V6
+	select ARCH_MXC_IOMUX_V3
+	select ARCH_MXC_AUDMUX_V2
+	select HAVE_EPIT
+	select ARCH_MX35
+	select MXC_AVIC
+
+
 if ARCH_MX1
 
 comment "MX1 platforms:"
@@ -40,6 +68,7 @@
 config ARCH_MX1ADS
 	bool "MX1ADS platform"
 	select MACH_MXLADS
+	select SOC_IMX1
 	select IMX_HAVE_PLATFORM_IMX_I2C
 	select IMX_HAVE_PLATFORM_IMX_UART
 	help
@@ -51,6 +80,13 @@
 	help
 	  Say Y here if you are using a Synertronixx scb9328 board
 
+config MACH_APF9328
+	bool "APF9328"
+	select SOC_IMX1
+	select IMX_HAVE_PLATFORM_IMX_UART
+	help
+	  Say Yes here if you are using the Armadeus APF9328 development board
+
 endif
 
 if ARCH_MX2
@@ -129,6 +165,7 @@
 
 config MACH_EUKREA_MBIMXSD25_BASEBOARD
 	bool "Eukrea MBIMXSD development board"
+	select IMX_HAVE_PLATFORM_GPIO_KEYS
 	select IMX_HAVE_PLATFORM_IMX_SSI
 	help
 	  This adds board specific devices that can be found on Eukrea's
@@ -254,6 +291,7 @@
 config MACH_IMX27_VISSTRIM_M10
 	bool "Vista Silicon i.MX27 Visstrim_m10"
 	select SOC_IMX27
+	select IMX_HAVE_PLATFORM_GPIO_KEYS
 	select IMX_HAVE_PLATFORM_IMX_I2C
 	select IMX_HAVE_PLATFORM_IMX_SSI
 	select IMX_HAVE_PLATFORM_IMX_UART
@@ -314,3 +352,251 @@
 	  configurations for the board and its peripherals.
 
 endif
+
+if ARCH_MX3
+
+comment "MX31 platforms:"
+
+config MACH_MX31ADS
+	bool "Support MX31ADS platforms"
+	select SOC_IMX31
+	select IMX_HAVE_PLATFORM_IMX_I2C
+	select IMX_HAVE_PLATFORM_IMX_SSI
+	select IMX_HAVE_PLATFORM_IMX_UART
+	default y
+	help
+	  Include support for MX31ADS platform. This includes specific
+	  configurations for the board and its peripherals.
+
+config MACH_MX31ADS_WM1133_EV1
+	bool "Support Wolfson Microelectronics 1133-EV1 module"
+	depends on MACH_MX31ADS
+	depends on MFD_WM8350_I2C
+	depends on REGULATOR_WM8350
+	select MFD_WM8350_CONFIG_MODE_0
+	select MFD_WM8352_CONFIG_MODE_0
+	help
+	  Include support for the Wolfson Microelectronics 1133-EV1 PMU
+	  and audio module for the MX31ADS platform.
+
+config MACH_MX31LILLY
+	bool "Support MX31 LILLY-1131 platforms (INCO startec)"
+	select SOC_IMX31
+	select IMX_HAVE_PLATFORM_IMX_UART
+	select IMX_HAVE_PLATFORM_IPU_CORE
+	select IMX_HAVE_PLATFORM_MXC_EHCI
+	select IMX_HAVE_PLATFORM_MXC_MMC
+	select IMX_HAVE_PLATFORM_SPI_IMX
+	select MXC_ULPI if USB_ULPI
+	help
+	  Include support for mx31 based LILLY1131 modules. This includes
+	  specific configurations for the board and its peripherals.
+
+config MACH_MX31LITE
+	bool "Support MX31 LITEKIT (LogicPD)"
+	select SOC_IMX31
+	select MXC_ULPI if USB_ULPI
+	select IMX_HAVE_PLATFORM_IMX2_WDT
+	select IMX_HAVE_PLATFORM_IMX_UART
+	select IMX_HAVE_PLATFORM_MXC_EHCI
+	select IMX_HAVE_PLATFORM_MXC_MMC
+	select IMX_HAVE_PLATFORM_MXC_NAND
+	select IMX_HAVE_PLATFORM_MXC_RTC
+	select IMX_HAVE_PLATFORM_SPI_IMX
+	help
+	  Include support for MX31 LITEKIT platform. This includes specific
+	  configurations for the board and its peripherals.
+
+config MACH_PCM037
+	bool "Support Phytec pcm037 (i.MX31) platforms"
+	select SOC_IMX31
+	select IMX_HAVE_PLATFORM_FSL_USB2_UDC
+	select IMX_HAVE_PLATFORM_IMX2_WDT
+	select IMX_HAVE_PLATFORM_IMX_I2C
+	select IMX_HAVE_PLATFORM_IMX_UART
+	select IMX_HAVE_PLATFORM_IPU_CORE
+	select IMX_HAVE_PLATFORM_MXC_EHCI
+	select IMX_HAVE_PLATFORM_MXC_MMC
+	select IMX_HAVE_PLATFORM_MXC_NAND
+	select IMX_HAVE_PLATFORM_MXC_W1
+	select MXC_ULPI if USB_ULPI
+	help
+	  Include support for Phytec pcm037 platform. This includes
+	  specific configurations for the board and its peripherals.
+
+config MACH_PCM037_EET
+	bool "Support pcm037 EET board extensions"
+	depends on MACH_PCM037
+	select IMX_HAVE_PLATFORM_GPIO_KEYS
+	select IMX_HAVE_PLATFORM_SPI_IMX
+	help
+	  Add support for PCM037 EET baseboard extensions. If you are using the
+	  OLED display with EET, use "video=mx3fb:CMEL-OLED" kernel
+	  command-line parameter.
+
+config MACH_MX31_3DS
+	bool "Support MX31PDK (3DS)"
+	select SOC_IMX31
+	select MXC_DEBUG_BOARD
+	select IMX_HAVE_PLATFORM_FSL_USB2_UDC
+	select IMX_HAVE_PLATFORM_IMX2_WDT
+	select IMX_HAVE_PLATFORM_IMX_I2C
+	select IMX_HAVE_PLATFORM_IMX_KEYPAD
+	select IMX_HAVE_PLATFORM_IMX_UART
+	select IMX_HAVE_PLATFORM_IPU_CORE
+	select IMX_HAVE_PLATFORM_MXC_EHCI
+	select IMX_HAVE_PLATFORM_MXC_NAND
+	select IMX_HAVE_PLATFORM_SPI_IMX
+	select MXC_ULPI if USB_ULPI
+	help
+	  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 SOC_IMX31
+	select IMX_HAVE_PLATFORM_FSL_USB2_UDC
+	select IMX_HAVE_PLATFORM_IMX_I2C
+	select IMX_HAVE_PLATFORM_IMX_UART
+	select IMX_HAVE_PLATFORM_IPU_CORE
+	select IMX_HAVE_PLATFORM_MXC_EHCI
+	select IMX_HAVE_PLATFORM_MXC_MMC
+	select IMX_HAVE_PLATFORM_SPI_IMX
+	select MXC_ULPI if USB_ULPI
+	help
+	  Include support for mx31moboard platform. This includes specific
+	  configurations for the board and its peripherals.
+
+config MACH_QONG
+	bool "Support Dave/DENX QongEVB-LITE platform"
+	select SOC_IMX31
+	select IMX_HAVE_PLATFORM_IMX_UART
+	help
+	  Include support for Dave/DENX QongEVB-LITE platform. This includes
+	  specific configurations for the board and its peripherals.
+
+config MACH_ARMADILLO5X0
+	bool "Support Atmark Armadillo-500 Development Base Board"
+	select SOC_IMX31
+	select IMX_HAVE_PLATFORM_GPIO_KEYS
+	select IMX_HAVE_PLATFORM_IMX_I2C
+	select IMX_HAVE_PLATFORM_IMX_UART
+	select IMX_HAVE_PLATFORM_IPU_CORE
+	select IMX_HAVE_PLATFORM_MXC_EHCI
+	select IMX_HAVE_PLATFORM_MXC_MMC
+	select IMX_HAVE_PLATFORM_MXC_NAND
+	select MXC_ULPI if USB_ULPI
+	help
+	  Include support for Atmark Armadillo-500 platform. This includes
+	  specific configurations for the board and its peripherals.
+
+config MACH_KZM_ARM11_01
+	bool "Support KZM-ARM11-01(Kyoto Microcomputer)"
+	select SOC_IMX31
+	select IMX_HAVE_PLATFORM_IMX_UART
+	help
+	  Include support for KZM-ARM11-01. This includes specific
+	  configurations for the board and its peripherals.
+
+config MACH_BUG
+	bool "Support Buglabs BUGBase platform"
+	select SOC_IMX31
+	select IMX_HAVE_PLATFORM_IMX_UART
+	default y
+	help
+	  Include support for BUGBase 1.3 platform. This includes specific
+	  configurations for the board and its peripherals.
+
+comment "MX35 platforms:"
+
+config MACH_PCM043
+	bool "Support Phytec pcm043 (i.MX35) platforms"
+	select SOC_IMX35
+	select IMX_HAVE_PLATFORM_FLEXCAN
+	select IMX_HAVE_PLATFORM_FSL_USB2_UDC
+	select IMX_HAVE_PLATFORM_IMX2_WDT
+	select IMX_HAVE_PLATFORM_IMX_I2C
+	select IMX_HAVE_PLATFORM_IMX_SSI
+	select IMX_HAVE_PLATFORM_IMX_UART
+	select IMX_HAVE_PLATFORM_IPU_CORE
+	select IMX_HAVE_PLATFORM_MXC_EHCI
+	select IMX_HAVE_PLATFORM_MXC_NAND
+	select IMX_HAVE_PLATFORM_SDHCI_ESDHC_IMX
+	select MXC_ULPI if USB_ULPI
+	help
+	  Include support for Phytec pcm043 platform. This includes
+	  specific configurations for the board and its peripherals.
+
+config MACH_MX35_3DS
+	bool "Support MX35PDK platform"
+	select SOC_IMX35
+	select MXC_DEBUG_BOARD
+	select IMX_HAVE_PLATFORM_FSL_USB2_UDC
+	select IMX_HAVE_PLATFORM_IMX2_WDT
+	select IMX_HAVE_PLATFORM_IMX_I2C
+	select IMX_HAVE_PLATFORM_IMX_UART
+	select IMX_HAVE_PLATFORM_MXC_EHCI
+	select IMX_HAVE_PLATFORM_MXC_NAND
+	select IMX_HAVE_PLATFORM_SDHCI_ESDHC_IMX
+	help
+	  Include support for MX35PDK platform. This includes specific
+	  configurations for the board and its peripherals.
+
+config MACH_EUKREA_CPUIMX35
+	bool "Support Eukrea CPUIMX35 Platform"
+	select SOC_IMX35
+	select IMX_HAVE_PLATFORM_FLEXCAN
+	select IMX_HAVE_PLATFORM_FSL_USB2_UDC
+	select IMX_HAVE_PLATFORM_IMX2_WDT
+	select IMX_HAVE_PLATFORM_IMX_I2C
+	select IMX_HAVE_PLATFORM_IMX_UART
+	select IMX_HAVE_PLATFORM_MXC_EHCI
+	select IMX_HAVE_PLATFORM_MXC_NAND
+	select IMX_HAVE_PLATFORM_SDHCI_ESDHC_IMX
+	select MXC_ULPI if USB_ULPI
+	help
+	  Include support for Eukrea CPUIMX35 platform. This includes
+	  specific configurations for the board and its peripherals.
+
+choice
+	prompt "Baseboard"
+	depends on MACH_EUKREA_CPUIMX35
+	default MACH_EUKREA_MBIMXSD35_BASEBOARD
+
+config MACH_EUKREA_MBIMXSD35_BASEBOARD
+	bool "Eukrea MBIMXSD development board"
+	select IMX_HAVE_PLATFORM_GPIO_KEYS
+	select IMX_HAVE_PLATFORM_IMX_SSI
+	select IMX_HAVE_PLATFORM_IPU_CORE
+	help
+	  This adds board specific devices that can be found on Eukrea's
+	  MBIMXSD evaluation board.
+
+endchoice
+
+config MACH_VPR200
+	bool "Support VPR200 platform"
+	select SOC_IMX35
+	select IMX_HAVE_PLATFORM_FSL_USB2_UDC
+	select IMX_HAVE_PLATFORM_GPIO_KEYS
+	select IMX_HAVE_PLATFORM_IMX2_WDT
+	select IMX_HAVE_PLATFORM_IMX_UART
+	select IMX_HAVE_PLATFORM_IMX_I2C
+	select IMX_HAVE_PLATFORM_IPU_CORE
+	select IMX_HAVE_PLATFORM_MXC_EHCI
+	select IMX_HAVE_PLATFORM_MXC_NAND
+	select IMX_HAVE_PLATFORM_SDHCI_ESDHC_IMX
+	help
+	  Include support for VPR200 platform. This includes specific
+	  configurations for the board and its peripherals.
+
+endif
diff -druN linux-2.6.39-libre/arch/arm/mach-imx/mach-apf9328.c linux-3.0-rc7-libre/arch/arm/mach-imx/mach-apf9328.c
--- linux-2.6.39-libre/arch/arm/mach-imx/mach-apf9328.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/arm/mach-imx/mach-apf9328.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,144 @@
+/*
+ * linux/arch/arm/mach-imx/mach-apf9328.c
+ *
+ * Copyright (c) 2005-2011 ARMadeus systems <support@armadeus.com>
+ *
+ * This work is based on mach-scb9328.c which is:
+ * 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/init.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/physmap.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/iomux-mx1.h>
+
+#include "devices-imx1.h"
+
+static const int apf9328_pins[] __initconst = {
+	/* 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,
+};
+
+/*
+ * The APF9328 can have up to 32MB NOR Flash
+ */
+static struct resource flash_resource = {
+	.start	= MX1_CS0_PHYS,
+	.end	= MX1_CS0_PHYS + SZ_32M - 1,
+	.flags	= IORESOURCE_MEM,
+};
+
+static struct physmap_flash_data apf9328_flash_data = {
+	.width  = 2,
+};
+
+static struct platform_device apf9328_flash_device = {
+	.name		= "physmap-flash",
+	.id		= 0,
+	.dev = {
+		.platform_data = &apf9328_flash_data,
+	},
+	.resource = &flash_resource,
+	.num_resources = 1,
+};
+
+/*
+ * APF9328 has a DM9000 Ethernet controller
+ */
+static struct dm9000_plat_data dm9000_setup = {
+	.flags          = DM9000_PLATF_16BITONLY
+};
+
+static struct resource dm9000_resources[] = {
+	{
+		.start  = MX1_CS4_PHYS + 0x00C00000,
+		.end    = MX1_CS4_PHYS + 0x00C00001,
+		.flags  = IORESOURCE_MEM,
+	}, {
+		.start  = MX1_CS4_PHYS + 0x00C00002,
+		.end    = MX1_CS4_PHYS + 0x00C00003,
+		.flags  = IORESOURCE_MEM,
+	}, {
+		.start  = IRQ_GPIOB(14),
+		.end    = IRQ_GPIOB(14),
+		.flags  = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWLEVEL,
+	},
+};
+
+static struct platform_device dm9000x_device = {
+	.name		= "dm9000",
+	.id		= 0,
+	.num_resources	= ARRAY_SIZE(dm9000_resources),
+	.resource	= dm9000_resources,
+	.dev		= {
+		.platform_data = &dm9000_setup,
+	}
+};
+
+/* --- SERIAL RESSOURCE --- */
+static const struct imxuart_platform_data uart0_pdata __initconst = {
+	.flags = 0,
+};
+
+static const struct imxuart_platform_data uart1_pdata __initconst = {
+	.flags = IMXUART_HAVE_RTSCTS,
+};
+
+static struct platform_device *devices[] __initdata = {
+	&apf9328_flash_device,
+	&dm9000x_device,
+};
+
+static void __init apf9328_init(void)
+{
+	mxc_gpio_setup_multiple_pins(apf9328_pins,
+			ARRAY_SIZE(apf9328_pins),
+			"APF9328");
+
+	imx1_add_imx_uart0(&uart0_pdata);
+	imx1_add_imx_uart1(&uart1_pdata);
+
+	platform_add_devices(devices, ARRAY_SIZE(devices));
+}
+
+static void __init apf9328_timer_init(void)
+{
+	mx1_clocks_init(32768);
+}
+
+static struct sys_timer apf9328_timer = {
+	.init	= apf9328_timer_init,
+};
+
+MACHINE_START(APF9328, "Armadeus APF9328")
+	/* Maintainer: Gwenhael Goavec-Merou, ARMadeus Systems */
+	.map_io       = mx1_map_io,
+	.init_early   = imx1_init_early,
+	.init_irq     = mx1_init_irq,
+	.timer        = &apf9328_timer,
+	.init_machine = apf9328_init,
+MACHINE_END
diff -druN linux-2.6.39-libre/arch/arm/mach-imx/mach-armadillo5x0.c linux-3.0-rc7-libre/arch/arm/mach-imx/mach-armadillo5x0.c
--- linux-2.6.39-libre/arch/arm/mach-imx/mach-armadillo5x0.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/arm/mach-imx/mach-armadillo5x0.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,565 @@
+/*
+ * 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/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/iomux-mx3.h>
+#include <mach/ulpi.h>
+
+#include "devices-imx31.h"
+#include "crmregs-imx31.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 */
+
+#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*/);
+	mdelay(10);
+
+	return mx31_initialize_usb_hw(pdev->id, MXC_EHCI_POWER_PINS_ENABLED |
+			MXC_EHCI_INTERFACE_DIFF_UNI);
+
+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*/);
+	mdelay(10);
+
+	return mx31_initialize_usb_hw(pdev->id, MXC_EHCI_POWER_PINS_ENABLED |
+			MXC_EHCI_INTERFACE_DIFF_UNI);
+
+h2_free_reset:
+	gpio_free(USBH2_RESET);
+h2_free_cs:
+	gpio_free(USBH2_CS);
+	return err;
+}
+
+static struct mxc_usbh_platform_data usbotg_pdata __initdata = {
+	.init	= usbotg_init,
+	.portsc	= MXC_EHCI_MODE_ULPI | MXC_EHCI_UTMI_8BIT,
+};
+
+static struct mxc_usbh_platform_data usbh2_pdata __initdata = {
+	.init	= usbh2_init,
+	.portsc	= MXC_EHCI_MODE_ULPI | MXC_EHCI_UTMI_8BIT,
+};
+
+/* 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 const struct gpio_keys_platform_data
+		armadillo5x0_button_data __initconst = {
+	.buttons	= armadillo5x0_buttons,
+	.nbuttons	= ARRAY_SIZE(armadillo5x0_buttons),
+};
+
+/*
+ * NAND Flash
+ */
+static const struct mxc_nand_platform_data
+armadillo5x0_nand_board_info __initconst = {
+	.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 const struct ipu_platform_data mx3_ipu_data __initconst = {
+	.irq_base = MXC_IPU_IRQ_START,
+};
+
+static struct mx3fb_platform_data mx3fb_pdata __initdata = {
+	.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 const struct imxmmc_platform_data sdhc_pdata __initconst = {
+	.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 const struct imxuart_platform_data uart_pdata __initconst = {
+	.flags = IMXUART_HAVE_RTSCTS,
+};
+
+static struct platform_device *devices[] __initdata = {
+	&armadillo5x0_smc911x_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));
+	imx_add_gpio_keys(&armadillo5x0_button_data);
+	imx31_add_imx_i2c1(NULL);
+
+	/* Register UART */
+	imx31_add_imx_uart0(&uart_pdata);
+	imx31_add_imx_uart1(&uart_pdata);
+
+	/* SMSC9118 IRQ pin */
+	gpio_direction_input(MX31_PIN_GPIO1_0);
+
+	/* Register SDHC */
+	imx31_add_mxc_mmc(0, &sdhc_pdata);
+
+	/* Register FB */
+	imx31_add_ipu_core(&mx3_ipu_data);
+	imx31_add_mx3_sdc_fb(&mx3fb_pdata);
+
+	/* Register NOR Flash */
+	mxc_register_device(&armadillo5x0_nor_flash,
+			    &armadillo5x0_nor_flash_pdata);
+
+	/* Register NAND Flash */
+	imx31_add_mxc_nand(&armadillo5x0_nand_board_info);
+
+	/* 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 */
+
+	usbotg_pdata.otg = imx_otg_ulpi_create(ULPI_OTG_DRVVBUS |
+			ULPI_OTG_DRVVBUS_EXT);
+	if (usbotg_pdata.otg)
+		imx31_add_mxc_ehci_otg(&usbotg_pdata);
+	usbh2_pdata.otg = imx_otg_ulpi_create(ULPI_OTG_DRVVBUS |
+			ULPI_OTG_DRVVBUS_EXT);
+	if (usbh2_pdata.otg)
+		imx31_add_mxc_ehci_hs(2, &usbh2_pdata);
+}
+
+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  */
+	.boot_params = MX3x_PHYS_OFFSET + 0x100,
+	.map_io = mx31_map_io,
+	.init_early = imx31_init_early,
+	.init_irq = mx31_init_irq,
+	.timer = &armadillo5x0_timer,
+	.init_machine = armadillo5x0_init,
+MACHINE_END
diff -druN linux-2.6.39-libre/arch/arm/mach-imx/mach-bug.c linux-3.0-rc7-libre/arch/arm/mach-imx/mach-bug.c
--- linux-2.6.39-libre/arch/arm/mach-imx/mach-bug.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/arm/mach-imx/mach-bug.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,65 @@
+/*
+ * 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 2011 Denis 'GNUtoo' Carikli <GNUtoo@no-log.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.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+
+#include <mach/iomux-mx3.h>
+#include <mach/hardware.h>
+#include <mach/common.h>
+
+#include <asm/mach/time.h>
+#include <asm/mach/arch.h>
+#include <asm/mach-types.h>
+
+#include "devices-imx31.h"
+
+static const struct imxuart_platform_data uart_pdata __initconst = {
+	.flags = IMXUART_HAVE_RTSCTS,
+};
+
+static const unsigned int bug_pins[] __initconst = {
+	MX31_PIN_PC_RST__CTS5,
+	MX31_PIN_PC_VS2__RTS5,
+	MX31_PIN_PC_BVD2__TXD5,
+	MX31_PIN_PC_BVD1__RXD5,
+};
+
+static void __init bug_board_init(void)
+{
+	mxc_iomux_setup_multiple_pins(bug_pins,
+				      ARRAY_SIZE(bug_pins), "uart-4");
+	imx31_add_imx_uart4(&uart_pdata);
+}
+
+static void __init bug_timer_init(void)
+{
+	mx31_clocks_init(26000000);
+}
+
+static struct sys_timer bug_timer = {
+	.init = bug_timer_init,
+};
+
+MACHINE_START(BUG, "BugLabs BUGBase")
+	.map_io = mx31_map_io,
+	.init_early = imx31_init_early,
+	.init_irq = mx31_init_irq,
+	.timer = &bug_timer,
+	.init_machine = bug_board_init,
+MACHINE_END
diff -druN linux-2.6.39-libre/arch/arm/mach-imx/mach-cpuimx27.c linux-3.0-rc7-libre/arch/arm/mach-imx/mach-cpuimx27.c
--- linux-2.6.39-libre/arch/arm/mach-imx/mach-cpuimx27.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-imx/mach-cpuimx27.c	2011-07-11 19:51:52.000000000 -0400
@@ -38,7 +38,6 @@
 #include <mach/common.h>
 #include <mach/hardware.h>
 #include <mach/iomux-mx27.h>
-#include <mach/mxc_nand.h>
 #include <mach/ulpi.h>
 
 #include "devices-imx27.h"
diff -druN linux-2.6.39-libre/arch/arm/mach-imx/mach-cpuimx35.c linux-3.0-rc7-libre/arch/arm/mach-imx/mach-cpuimx35.c
--- linux-2.6.39-libre/arch/arm/mach-imx/mach-cpuimx35.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/arm/mach-imx/mach-cpuimx35.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,201 @@
+/*
+ * Copyright (C) 2010 Eric Benard - eric@eukrea.com
+ * 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/memory.h>
+#include <linux/gpio.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <linux/i2c.h>
+#include <linux/i2c/tsc2007.h>
+#include <linux/usb/otg.h>
+#include <linux/usb/ulpi.h>
+#include <linux/i2c-gpio.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+#include <asm/mach/map.h>
+
+#include <mach/eukrea-baseboards.h>
+#include <mach/hardware.h>
+#include <mach/common.h>
+#include <mach/iomux-mx35.h>
+
+#include "devices-imx35.h"
+
+static const struct imxuart_platform_data uart_pdata __initconst = {
+	.flags = IMXUART_HAVE_RTSCTS,
+};
+
+static const struct imxi2c_platform_data
+		eukrea_cpuimx35_i2c0_data __initconst = {
+	.bitrate =		100000,
+};
+
+static struct tsc2007_platform_data tsc2007_info = {
+	.model			= 2007,
+	.x_plate_ohms		= 180,
+};
+
+#define TSC2007_IRQGPIO		IMX_GPIO_NR(3, 2)
+static struct i2c_board_info eukrea_cpuimx35_i2c_devices[] = {
+	{
+		I2C_BOARD_INFO("pcf8563", 0x51),
+	}, {
+		I2C_BOARD_INFO("tsc2007", 0x48),
+		.type		= "tsc2007",
+		.platform_data	= &tsc2007_info,
+		.irq		= gpio_to_irq(TSC2007_IRQGPIO),
+	},
+};
+
+static iomux_v3_cfg_t eukrea_cpuimx35_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,
+	/* I2C1 */
+	MX35_PAD_I2C1_CLK__I2C1_SCL,
+	MX35_PAD_I2C1_DAT__I2C1_SDA,
+	/* TSC2007 IRQ */
+	MX35_PAD_ATA_DA2__GPIO3_2,
+};
+
+static const struct mxc_nand_platform_data
+		eukrea_cpuimx35_nand_board_info __initconst = {
+	.width		= 1,
+	.hw_ecc		= 1,
+	.flash_bbt	= 1,
+};
+
+static int eukrea_cpuimx35_otg_init(struct platform_device *pdev)
+{
+	return mx35_initialize_usb_hw(pdev->id, MXC_EHCI_INTERFACE_DIFF_UNI);
+}
+
+static const struct mxc_usbh_platform_data otg_pdata __initconst = {
+	.init	= eukrea_cpuimx35_otg_init,
+	.portsc	= MXC_EHCI_MODE_UTMI,
+};
+
+static int eukrea_cpuimx35_usbh1_init(struct platform_device *pdev)
+{
+	return mx35_initialize_usb_hw(pdev->id, MXC_EHCI_INTERFACE_SINGLE_UNI |
+			MXC_EHCI_INTERNAL_PHY | MXC_EHCI_IPPUE_DOWN);
+}
+
+static const struct mxc_usbh_platform_data usbh1_pdata __initconst = {
+	.init	= eukrea_cpuimx35_usbh1_init,
+	.portsc	= MXC_EHCI_MODE_SERIAL,
+};
+
+static const struct fsl_usb2_platform_data otg_device_pdata __initconst = {
+	.operating_mode	= FSL_USB2_DR_DEVICE,
+	.phy_mode	= FSL_USB2_PHY_UTMI,
+	.workaround	= FLS_USB2_WORKAROUND_ENGCM09152,
+};
+
+static int otg_mode_host;
+
+static int __init eukrea_cpuimx35_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=", eukrea_cpuimx35_otg_mode);
+
+/*
+ * Board specific initialization.
+ */
+static void __init eukrea_cpuimx35_init(void)
+{
+	mxc_iomux_v3_setup_multiple_pads(eukrea_cpuimx35_pads,
+			ARRAY_SIZE(eukrea_cpuimx35_pads));
+
+	imx35_add_fec(NULL);
+	imx35_add_imx2_wdt(NULL);
+
+	imx35_add_imx_uart0(&uart_pdata);
+	imx35_add_mxc_nand(&eukrea_cpuimx35_nand_board_info);
+
+	i2c_register_board_info(0, eukrea_cpuimx35_i2c_devices,
+			ARRAY_SIZE(eukrea_cpuimx35_i2c_devices));
+	imx35_add_imx_i2c0(&eukrea_cpuimx35_i2c0_data);
+
+	if (otg_mode_host)
+		imx35_add_mxc_ehci_otg(&otg_pdata);
+	else
+		imx35_add_fsl_usb2_udc(&otg_device_pdata);
+
+	imx35_add_mxc_ehci_hs(&usbh1_pdata);
+
+#ifdef CONFIG_MACH_EUKREA_MBIMXSD35_BASEBOARD
+	eukrea_mbimxsd35_baseboard_init();
+#endif
+}
+
+static void __init eukrea_cpuimx35_timer_init(void)
+{
+	mx35_clocks_init();
+}
+
+struct sys_timer eukrea_cpuimx35_timer = {
+	.init	= eukrea_cpuimx35_timer_init,
+};
+
+MACHINE_START(EUKREA_CPUIMX35, "Eukrea CPUIMX35")
+	/* Maintainer: Eukrea Electromatique */
+	.boot_params = MX3x_PHYS_OFFSET + 0x100,
+	.map_io = mx35_map_io,
+	.init_early = imx35_init_early,
+	.init_irq = mx35_init_irq,
+	.timer = &eukrea_cpuimx35_timer,
+	.init_machine = eukrea_cpuimx35_init,
+MACHINE_END
diff -druN linux-2.6.39-libre/arch/arm/mach-imx/mach-eukrea_cpuimx25.c linux-3.0-rc7-libre/arch/arm/mach-imx/mach-eukrea_cpuimx25.c
--- linux-2.6.39-libre/arch/arm/mach-imx/mach-eukrea_cpuimx25.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-imx/mach-eukrea_cpuimx25.c	2011-07-11 19:51:52.000000000 -0400
@@ -36,8 +36,6 @@
 #include <asm/mach/map.h>
 #include <mach/common.h>
 #include <mach/mx25.h>
-#include <mach/mxc_nand.h>
-#include <mach/imxfb.h>
 #include <mach/iomux-mx25.h>
 
 #include "devices-imx25.h"
diff -druN linux-2.6.39-libre/arch/arm/mach-imx/mach-imx27_visstrim_m10.c linux-3.0-rc7-libre/arch/arm/mach-imx/mach-imx27_visstrim_m10.c
--- linux-2.6.39-libre/arch/arm/mach-imx/mach-imx27_visstrim_m10.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-imx/mach-imx27_visstrim_m10.c	2011-07-11 19:51:52.000000000 -0400
@@ -27,7 +27,6 @@
 #include <linux/mtd/physmap.h>
 #include <linux/i2c.h>
 #include <linux/i2c/pca953x.h>
-#include <linux/gpio_keys.h>
 #include <linux/input.h>
 #include <linux/gpio.h>
 #include <linux/delay.h>
@@ -130,19 +129,12 @@
 	}
 };
 
-static struct gpio_keys_platform_data visstrim_gpio_keys_platform_data = {
+static const struct gpio_keys_platform_data
+		visstrim_gpio_keys_platform_data __initconst = {
 	.buttons	= visstrim_gpio_keys,
 	.nbuttons	= ARRAY_SIZE(visstrim_gpio_keys),
 };
 
-static struct platform_device visstrim_gpio_keys_device = {
-	.name	= "gpio-keys",
-	.id	= -1,
-	.dev	= {
-		.platform_data	= &visstrim_gpio_keys_platform_data,
-	},
-};
-
 /* Visstrim_SM10 has a microSD slot connected to sdhc1 */
 static int visstrim_m10_sdhc1_init(struct device *dev,
 		irq_handler_t detect_irq, void *data)
@@ -186,7 +178,6 @@
 };
 
 static struct platform_device *platform_devices[] __initdata = {
-	&visstrim_gpio_keys_device,
 	&visstrim_m10_nor_mtd_device,
 };
 
@@ -255,6 +246,7 @@
 	imx27_add_mxc_mmc(0, &visstrim_m10_sdhc_pdata);
 	imx27_add_mxc_ehci_otg(&visstrim_m10_usbotg_pdata);
 	imx27_add_fec(NULL);
+	imx_add_gpio_keys(&visstrim_gpio_keys_platform_data);
 	platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices));
 }
 
diff -druN linux-2.6.39-libre/arch/arm/mach-imx/mach-kzm_arm11_01.c linux-3.0-rc7-libre/arch/arm/mach-imx/mach-kzm_arm11_01.c
--- linux-2.6.39-libre/arch/arm/mach-imx/mach-kzm_arm11_01.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/arm/mach-imx/mach-kzm_arm11_01.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,278 @@
+/*
+ * 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.
+ */
+
+#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/memory.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/clock.h>
+#include <mach/common.h>
+#include <mach/iomux-mx3.h>
+
+#include "devices-imx31.h"
+
+#define KZM_ARM11_IO_ADDRESS(x) (IOMEM(					\
+	IMX_IO_P2V_MODULE(x, MX31_CS4) ?:				\
+	IMX_IO_P2V_MODULE(x, MX31_CS5)) ?:				\
+	MX31_IO_ADDRESS(x))
+
+/*
+ *  KZM-ARM11-01 Board Control Registers on FPGA
+ */
+#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		(MX31_CS4_BASE_ADDR + 0x1050)
+
+#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 const struct imxuart_platform_data uart_pdata __initconst = {
+	.flags = IMXUART_HAVE_RTSCTS,
+};
+
+static void __init kzm_init_imx_uart(void)
+{
+	imx31_add_imx_uart0(&uart_pdata);
+	imx31_add_imx_uart1(&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,
+};
+
+MACHINE_START(KZM_ARM11_01, "Kyoto Microcomputer Co., Ltd. KZM-ARM11-01")
+	.boot_params = MX3x_PHYS_OFFSET + 0x100,
+	.map_io = kzm_map_io,
+	.init_early = imx31_init_early,
+	.init_irq = mx31_init_irq,
+	.timer = &kzm_timer,
+	.init_machine = kzm_board_init,
+MACHINE_END
diff -druN linux-2.6.39-libre/arch/arm/mach-imx/mach-mx1ads.c linux-3.0-rc7-libre/arch/arm/mach-imx/mach-mx1ads.c
--- linux-2.6.39-libre/arch/arm/mach-imx/mach-mx1ads.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-imx/mach-mx1ads.c	2011-07-11 19:51:52.000000000 -0400
@@ -25,7 +25,6 @@
 
 #include <mach/common.h>
 #include <mach/hardware.h>
-#include <mach/i2c.h>
 #include <mach/iomux-mx1.h>
 #include <mach/irqs.h>
 
diff -druN linux-2.6.39-libre/arch/arm/mach-imx/mach-mx21ads.c linux-3.0-rc7-libre/arch/arm/mach-imx/mach-mx21ads.c
--- linux-2.6.39-libre/arch/arm/mach-imx/mach-mx21ads.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-imx/mach-mx21ads.c	2011-07-11 19:51:52.000000000 -0400
@@ -25,7 +25,6 @@
 #include <asm/mach/time.h>
 #include <asm/mach/map.h>
 #include <mach/iomux-mx21.h>
-#include <mach/mxc_nand.h>
 
 #include "devices-imx21.h"
 
diff -druN linux-2.6.39-libre/arch/arm/mach-imx/mach-mx25_3ds.c linux-3.0-rc7-libre/arch/arm/mach-imx/mach-mx25_3ds.c
--- linux-2.6.39-libre/arch/arm/mach-imx/mach-mx25_3ds.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-imx/mach-mx25_3ds.c	2011-07-11 19:51:52.000000000 -0400
@@ -29,7 +29,6 @@
 #include <linux/irq.h>
 #include <linux/gpio.h>
 #include <linux/platform_device.h>
-#include <linux/input/matrix_keypad.h>
 #include <linux/usb/otg.h>
 
 #include <mach/hardware.h>
@@ -103,6 +102,8 @@
 	MX25_PAD_SD1_DATA1__SD1_DATA1,
 	MX25_PAD_SD1_DATA2__SD1_DATA2,
 	MX25_PAD_SD1_DATA3__SD1_DATA3,
+	MX25_PAD_A14__GPIO_2_0, /* WriteProtect */
+	MX25_PAD_A15__GPIO_2_1, /* CardDetect */
 
 	/* I2C1 */
 	MX25_PAD_I2C1_CLK__I2C1_CLK,
@@ -208,6 +209,14 @@
 	.bitrate = 100000,
 };
 
+#define SD1_GPIO_WP	IMX_GPIO_NR(2, 0)
+#define SD1_GPIO_CD	IMX_GPIO_NR(2, 1)
+
+static const struct esdhc_platform_data mx25pdk_esdhc_pdata __initconst = {
+	.wp_gpio = SD1_GPIO_WP,
+	.cd_gpio = SD1_GPIO_CD,
+};
+
 static void __init mx25pdk_init(void)
 {
 	mxc_iomux_v3_setup_multiple_pads(mx25pdk_pads,
@@ -225,7 +234,7 @@
 	imx25_add_fec(&mx25_fec_pdata);
 	imx25_add_imx_keypad(&mx25pdk_keymap_data);
 
-	imx25_add_sdhci_esdhc_imx(0, NULL);
+	imx25_add_sdhci_esdhc_imx(0, &mx25pdk_esdhc_pdata);
 	imx25_add_imx_i2c0(&mx25_3ds_i2c0_data);
 }
 
diff -druN linux-2.6.39-libre/arch/arm/mach-imx/mach-mx27ads.c linux-3.0-rc7-libre/arch/arm/mach-imx/mach-mx27ads.c
--- linux-2.6.39-libre/arch/arm/mach-imx/mach-mx27ads.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-imx/mach-mx27ads.c	2011-07-11 19:51:52.000000000 -0400
@@ -29,7 +29,6 @@
 #include <asm/mach/map.h>
 #include <mach/gpio.h>
 #include <mach/iomux-mx27.h>
-#include <mach/mxc_nand.h>
 
 #include "devices-imx27.h"
 
diff -druN linux-2.6.39-libre/arch/arm/mach-imx/mach-mx31_3ds.c linux-3.0-rc7-libre/arch/arm/mach-imx/mach-mx31_3ds.c
--- linux-2.6.39-libre/arch/arm/mach-imx/mach-mx31_3ds.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/arm/mach-imx/mach-mx31_3ds.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,771 @@
+/*
+ *  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.
+ */
+
+#include <linux/delay.h>
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/clk.h>
+#include <linux/irq.h>
+#include <linux/gpio.h>
+#include <linux/platform_device.h>
+#include <linux/mfd/mc13783.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/l4f00242t03.h>
+#include <linux/regulator/machine.h>
+#include <linux/usb/otg.h>
+#include <linux/usb/ulpi.h>
+#include <linux/memblock.h>
+
+#include <media/soc_camera.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/iomux-mx3.h>
+#include <mach/3ds_debugboard.h>
+#include <mach/ulpi.h>
+
+#include "devices-imx31.h"
+
+/* CPLD IRQ line for external uart, external ethernet etc */
+#define EXPIO_PARENT_INT	IOMUX_TO_IRQ(MX31_PIN_GPIO1_1)
+
+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),
+	/*SPI0*/
+	MX31_PIN_CSPI1_SCLK__SCLK,
+	MX31_PIN_CSPI1_MOSI__MOSI,
+	MX31_PIN_CSPI1_MISO__MISO,
+	MX31_PIN_CSPI1_SPI_RDY__SPI_RDY,
+	MX31_PIN_CSPI1_SS2__SS2, /* CS for LCD */
+	/* 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),
+	/* USB OTG reset */
+	IOMUX_MODE(MX31_PIN_USB_PWR, IOMUX_CONFIG_GPIO),
+	/* 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,
+	/*Keyboard*/
+	MX31_PIN_KEY_ROW0_KEY_ROW0,
+	MX31_PIN_KEY_ROW1_KEY_ROW1,
+	MX31_PIN_KEY_ROW2_KEY_ROW2,
+	MX31_PIN_KEY_COL0_KEY_COL0,
+	MX31_PIN_KEY_COL1_KEY_COL1,
+	MX31_PIN_KEY_COL2_KEY_COL2,
+	MX31_PIN_KEY_COL3_KEY_COL3,
+	/* 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_PC_VS2, IOMUX_CONFIG_ALT1),
+	IOMUX_MODE(MX31_PIN_PC_BVD1, IOMUX_CONFIG_ALT1),
+	IOMUX_MODE(MX31_PIN_PC_BVD2, IOMUX_CONFIG_ALT1),
+	IOMUX_MODE(MX31_PIN_PC_RST, IOMUX_CONFIG_ALT1),
+	IOMUX_MODE(MX31_PIN_IOIS16, IOMUX_CONFIG_ALT1),
+	IOMUX_MODE(MX31_PIN_PC_RW_B, IOMUX_CONFIG_ALT1),
+	/* USB Host2 reset */
+	IOMUX_MODE(MX31_PIN_USB_BYP, IOMUX_CONFIG_GPIO),
+	/* I2C1 */
+	MX31_PIN_I2C_CLK__I2C1_SCL,
+	MX31_PIN_I2C_DAT__I2C1_SDA,
+	/* 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_GPIO3_1__GPIO3_1, /* Card detect */
+	MX31_PIN_GPIO3_0__GPIO3_0, /* OE */
+	/* 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_CONTRAST__CONTRAST,
+	/* CSI */
+	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_CSI_D5__GPIO3_5, /* CMOS PWDN */
+	IOMUX_MODE(MX31_PIN_RI_DTE1, IOMUX_CONFIG_GPIO), /* CMOS reset */
+};
+
+/*
+ * Camera support
+ */
+static phys_addr_t mx3_camera_base __initdata;
+#define MX31_3DS_CAMERA_BUF_SIZE SZ_8M
+
+#define MX31_3DS_GPIO_CAMERA_PW IOMUX_TO_GPIO(MX31_PIN_CSI_D5)
+#define MX31_3DS_GPIO_CAMERA_RST IOMUX_TO_GPIO(MX31_PIN_RI_DTE1)
+
+static struct gpio mx31_3ds_camera_gpios[] = {
+	{ MX31_3DS_GPIO_CAMERA_PW, GPIOF_OUT_INIT_HIGH, "camera-power" },
+	{ MX31_3DS_GPIO_CAMERA_RST, GPIOF_OUT_INIT_HIGH, "camera-reset" },
+};
+
+static const struct mx3_camera_pdata mx31_3ds_camera_pdata __initconst = {
+	.flags = MX3_CAMERA_DATAWIDTH_10,
+	.mclk_10khz = 2600,
+};
+
+static int __init mx31_3ds_init_camera(void)
+{
+	int dma, ret = -ENOMEM;
+	struct platform_device *pdev =
+		imx31_alloc_mx3_camera(&mx31_3ds_camera_pdata);
+
+	if (IS_ERR(pdev))
+		return PTR_ERR(pdev);
+
+	if (!mx3_camera_base)
+		goto err;
+
+	dma = dma_declare_coherent_memory(&pdev->dev,
+					mx3_camera_base, mx3_camera_base,
+					MX31_3DS_CAMERA_BUF_SIZE,
+					DMA_MEMORY_MAP | DMA_MEMORY_EXCLUSIVE);
+
+	if (!(dma & DMA_MEMORY_MAP))
+		goto err;
+
+	ret = platform_device_add(pdev);
+	if (ret)
+err:
+		platform_device_put(pdev);
+
+	return ret;
+}
+
+static int mx31_3ds_camera_power(struct device *dev, int on)
+{
+	/* enable or disable the camera */
+	pr_debug("%s: %s the camera\n", __func__, on ? "ENABLE" : "DISABLE");
+	gpio_set_value(MX31_3DS_GPIO_CAMERA_PW, on ? 0 : 1);
+
+	if (!on)
+		goto out;
+
+	/* If enabled, give a reset impulse */
+	gpio_set_value(MX31_3DS_GPIO_CAMERA_RST, 0);
+	msleep(20);
+	gpio_set_value(MX31_3DS_GPIO_CAMERA_RST, 1);
+	msleep(100);
+
+out:
+	return 0;
+}
+
+static struct i2c_board_info mx31_3ds_i2c_camera = {
+	I2C_BOARD_INFO("ov2640", 0x30),
+};
+
+static struct regulator_bulk_data mx31_3ds_camera_regs[] = {
+	{ .supply = "cmos_vcore" },
+	{ .supply = "cmos_2v8" },
+};
+
+static struct soc_camera_link iclink_ov2640 = {
+	.bus_id		= 0,
+	.board_info	= &mx31_3ds_i2c_camera,
+	.i2c_adapter_id	= 0,
+	.power		= mx31_3ds_camera_power,
+	.regulators	= mx31_3ds_camera_regs,
+	.num_regulators	= ARRAY_SIZE(mx31_3ds_camera_regs),
+};
+
+static struct platform_device mx31_3ds_ov2640 = {
+	.name	= "soc-camera-pdrv",
+	.id	= 0,
+	.dev	= {
+		.platform_data = &iclink_ov2640,
+	},
+};
+
+/*
+ * FB support
+ */
+static const struct fb_videomode fb_modedb[] = {
+	{	/* 480x640 @ 60 Hz */
+		.name		= "Epson-VGA",
+		.refresh	= 60,
+		.xres		= 480,
+		.yres		= 640,
+		.pixclock	= 41701,
+		.left_margin	= 20,
+		.right_margin	= 41,
+		.upper_margin	= 10,
+		.lower_margin	= 5,
+		.hsync_len	= 20,
+		.vsync_len	= 10,
+		.sync		= FB_SYNC_OE_ACT_HIGH | FB_SYNC_CLK_INVERT,
+		.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 __initdata = {
+	.name		= "Epson-VGA",
+	.mode		= fb_modedb,
+	.num_modes	= ARRAY_SIZE(fb_modedb),
+};
+
+/* LCD */
+static struct l4f00242t03_pdata mx31_3ds_l4f00242t03_pdata = {
+	.reset_gpio		= IOMUX_TO_GPIO(MX31_PIN_LCS1),
+	.data_enable_gpio	= IOMUX_TO_GPIO(MX31_PIN_SER_RS),
+	.core_supply		= "lcd_2v8",
+	.io_supply		= "vdd_lcdio",
+};
+
+/*
+ * Support for SD card slot in personality board
+ */
+#define MX31_3DS_GPIO_SDHC1_CD IOMUX_TO_GPIO(MX31_PIN_GPIO3_1)
+#define MX31_3DS_GPIO_SDHC1_BE IOMUX_TO_GPIO(MX31_PIN_GPIO3_0)
+
+static struct gpio mx31_3ds_sdhc1_gpios[] = {
+	{ MX31_3DS_GPIO_SDHC1_CD, GPIOF_IN, "sdhc1-card-detect" },
+	{ MX31_3DS_GPIO_SDHC1_BE, GPIOF_OUT_INIT_LOW, "sdhc1-bus-en" },
+};
+
+static int mx31_3ds_sdhc1_init(struct device *dev,
+			       irq_handler_t detect_irq,
+			       void *data)
+{
+	int ret;
+
+	ret = gpio_request_array(mx31_3ds_sdhc1_gpios,
+				 ARRAY_SIZE(mx31_3ds_sdhc1_gpios));
+	if (ret) {
+		pr_warning("Unable to request the SD/MMC GPIOs.\n");
+		return ret;
+	}
+
+	ret = request_irq(IOMUX_TO_IRQ(MX31_PIN_GPIO3_1),
+			  detect_irq, IRQF_DISABLED |
+			  IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING,
+			  "sdhc1-detect", data);
+	if (ret) {
+		pr_warning("Unable to request the SD/MMC card-detect IRQ.\n");
+		goto gpio_free;
+	}
+
+	return 0;
+
+gpio_free:
+	gpio_free_array(mx31_3ds_sdhc1_gpios,
+			ARRAY_SIZE(mx31_3ds_sdhc1_gpios));
+	return ret;
+}
+
+static void mx31_3ds_sdhc1_exit(struct device *dev, void *data)
+{
+	free_irq(IOMUX_TO_IRQ(MX31_PIN_GPIO3_1), data);
+	gpio_free_array(mx31_3ds_sdhc1_gpios,
+			 ARRAY_SIZE(mx31_3ds_sdhc1_gpios));
+}
+
+static void mx31_3ds_sdhc1_setpower(struct device *dev, unsigned int vdd)
+{
+	/*
+	 * While the voltage stuff is done by the driver, activate the
+	 * Buffer Enable Pin only if there is a card in slot to fix the card
+	 * voltage issue caused by bi-directional chip TXB0108 on 3Stack.
+	 * Done here because at this stage we have for sure a debounced value
+	 * of the presence of the card, showed by the value of vdd.
+	 * 7 == ilog2(MMC_VDD_165_195)
+	 */
+	if (vdd > 7)
+		gpio_set_value(MX31_3DS_GPIO_SDHC1_BE, 1);
+	else
+		gpio_set_value(MX31_3DS_GPIO_SDHC1_BE, 0);
+}
+
+static struct imxmmc_platform_data sdhc1_pdata = {
+	.init		= mx31_3ds_sdhc1_init,
+	.exit		= mx31_3ds_sdhc1_exit,
+	.setpower	= mx31_3ds_sdhc1_setpower,
+};
+
+/*
+ * Matrix keyboard
+ */
+
+static const uint32_t mx31_3ds_keymap[] = {
+	KEY(0, 0, KEY_UP),
+	KEY(0, 1, KEY_DOWN),
+	KEY(1, 0, KEY_RIGHT),
+	KEY(1, 1, KEY_LEFT),
+	KEY(1, 2, KEY_ENTER),
+	KEY(2, 0, KEY_F6),
+	KEY(2, 1, KEY_F8),
+	KEY(2, 2, KEY_F9),
+	KEY(2, 3, KEY_F10),
+};
+
+static const struct matrix_keymap_data mx31_3ds_keymap_data __initconst = {
+	.keymap		= mx31_3ds_keymap,
+	.keymap_size	= ARRAY_SIZE(mx31_3ds_keymap),
+};
+
+/* Regulators */
+static struct regulator_init_data pwgtx_init = {
+	.constraints = {
+		.boot_on	= 1,
+		.always_on	= 1,
+	},
+};
+
+static struct regulator_init_data gpo_init = {
+	.constraints = {
+		.boot_on = 1,
+		.always_on = 1,
+	}
+};
+
+static struct regulator_consumer_supply vmmc2_consumers[] = {
+	REGULATOR_SUPPLY("vmmc", "mxc-mmc.0"),
+};
+
+static struct regulator_init_data vmmc2_init = {
+	.constraints = {
+		.min_uV = 3000000,
+		.max_uV = 3000000,
+		.valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+				  REGULATOR_CHANGE_STATUS,
+	},
+	.num_consumer_supplies = ARRAY_SIZE(vmmc2_consumers),
+	.consumer_supplies = vmmc2_consumers,
+};
+
+static struct regulator_consumer_supply vmmc1_consumers[] = {
+	REGULATOR_SUPPLY("lcd_2v8", NULL),
+	REGULATOR_SUPPLY("cmos_2v8", "soc-camera-pdrv.0"),
+};
+
+static struct regulator_init_data vmmc1_init = {
+	.constraints = {
+		.min_uV = 2800000,
+		.max_uV = 2800000,
+		.apply_uV = 1,
+		.valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+				  REGULATOR_CHANGE_STATUS,
+	},
+	.num_consumer_supplies = ARRAY_SIZE(vmmc1_consumers),
+	.consumer_supplies = vmmc1_consumers,
+};
+
+static struct regulator_consumer_supply vgen_consumers[] = {
+	REGULATOR_SUPPLY("vdd_lcdio", NULL),
+};
+
+static struct regulator_init_data vgen_init = {
+	.constraints = {
+		.min_uV = 1800000,
+		.max_uV = 1800000,
+		.apply_uV = 1,
+		.valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+				  REGULATOR_CHANGE_STATUS,
+	},
+	.num_consumer_supplies = ARRAY_SIZE(vgen_consumers),
+	.consumer_supplies = vgen_consumers,
+};
+
+static struct regulator_consumer_supply vvib_consumers[] = {
+	REGULATOR_SUPPLY("cmos_vcore", "soc-camera-pdrv.0"),
+};
+
+static struct regulator_init_data vvib_init = {
+	.constraints = {
+		.min_uV = 1300000,
+		.max_uV = 1300000,
+		.apply_uV = 1,
+		.valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+				  REGULATOR_CHANGE_STATUS,
+	},
+	.num_consumer_supplies = ARRAY_SIZE(vvib_consumers),
+	.consumer_supplies = vvib_consumers,
+};
+
+static struct mc13xxx_regulator_init_data mx31_3ds_regulators[] = {
+	{
+		.id = MC13783_REG_PWGT1SPI, /* Power Gate for ARM core. */
+		.init_data = &pwgtx_init,
+	}, {
+		.id = MC13783_REG_PWGT2SPI, /* Power Gate for L2 Cache. */
+		.init_data = &pwgtx_init,
+	}, {
+
+		.id = MC13783_REG_GPO1, /* Turn on 1.8V */
+		.init_data = &gpo_init,
+	}, {
+		.id = MC13783_REG_GPO3, /* Turn on 3.3V */
+		.init_data = &gpo_init,
+	}, {
+		.id = MC13783_REG_VMMC2, /* Power MMC/SD, WiFi/Bluetooth. */
+		.init_data = &vmmc2_init,
+	}, {
+		.id = MC13783_REG_VMMC1, /* Power LCD, CMOS, FM, GPS, Accel. */
+		.init_data = &vmmc1_init,
+	}, {
+		.id = MC13783_REG_VGEN,  /* Power LCD */
+		.init_data = &vgen_init,
+	}, {
+		.id = MC13783_REG_VVIB,  /* Power CMOS */
+		.init_data = &vvib_init,
+	},
+};
+
+/* MC13783 */
+static struct mc13xxx_platform_data mc13783_pdata = {
+	.regulators = {
+		.regulators = mx31_3ds_regulators,
+		.num_regulators = ARRAY_SIZE(mx31_3ds_regulators),
+	},
+	.flags  = MC13783_USE_REGULATOR | MC13783_USE_TOUCHSCREEN,
+};
+
+/* SPI */
+static int spi0_internal_chipselect[] = {
+	MXC_SPI_CS(2),
+};
+
+static const struct spi_imx_master spi0_pdata __initconst = {
+	.chipselect	= spi0_internal_chipselect,
+	.num_chipselect	= ARRAY_SIZE(spi0_internal_chipselect),
+};
+
+static int spi1_internal_chipselect[] = {
+	MXC_SPI_CS(0),
+	MXC_SPI_CS(2),
+};
+
+static const struct spi_imx_master spi1_pdata __initconst = {
+	.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,
+	}, {
+		.modalias	= "l4f00242t03",
+		.max_speed_hz	= 5000000,
+		.bus_num	= 0,
+		.chip_select	= 0, /* SS2 */
+		.platform_data	= &mx31_3ds_l4f00242t03_pdata,
+	},
+};
+
+/*
+ * NAND Flash
+ */
+static const struct mxc_nand_platform_data
+mx31_3ds_nand_board_info __initconst = {
+	.width		= 1,
+	.hw_ecc		= 1,
+#ifdef MACH_MX31_3DS_MXC_NAND_USE_BBT
+	.flash_bbt	= 1,
+#endif
+};
+
+/*
+ * USB OTG
+ */
+
+#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 USBOTG_RST_B IOMUX_TO_GPIO(MX31_PIN_USB_PWR)
+#define USBH2_RST_B IOMUX_TO_GPIO(MX31_PIN_USB_BYP)
+
+static int mx31_3ds_usbotg_init(void)
+{
+	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);
+
+	err = gpio_request(USBOTG_RST_B, "otgusb-reset");
+	if (err) {
+		pr_err("Failed to request the USB OTG reset gpio\n");
+		return err;
+	}
+
+	err = gpio_direction_output(USBOTG_RST_B, 0);
+	if (err) {
+		pr_err("Failed to drive the USB OTG reset gpio\n");
+		goto usbotg_free_reset;
+	}
+
+	mdelay(1);
+	gpio_set_value(USBOTG_RST_B, 1);
+	return 0;
+
+usbotg_free_reset:
+	gpio_free(USBOTG_RST_B);
+	return err;
+}
+
+static int mx31_3ds_otg_init(struct platform_device *pdev)
+{
+	return mx31_initialize_usb_hw(pdev->id, MXC_EHCI_POWER_PINS_ENABLED);
+}
+
+static int mx31_3ds_host2_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_PC_VS2, USB_PAD_CFG);
+	mxc_iomux_set_pad(MX31_PIN_PC_BVD1, USB_PAD_CFG);
+	mxc_iomux_set_pad(MX31_PIN_PC_BVD2, USB_PAD_CFG);
+	mxc_iomux_set_pad(MX31_PIN_PC_RST, USB_PAD_CFG);
+	mxc_iomux_set_pad(MX31_PIN_IOIS16, USB_PAD_CFG);
+	mxc_iomux_set_pad(MX31_PIN_PC_RW_B, USB_PAD_CFG);
+
+	err = gpio_request(USBH2_RST_B, "usbh2-reset");
+	if (err) {
+		pr_err("Failed to request the USB Host 2 reset gpio\n");
+		return err;
+	}
+
+	err = gpio_direction_output(USBH2_RST_B, 0);
+	if (err) {
+		pr_err("Failed to drive the USB Host 2 reset gpio\n");
+		goto usbotg_free_reset;
+	}
+
+	mdelay(1);
+	gpio_set_value(USBH2_RST_B, 1);
+
+	mdelay(10);
+
+	return mx31_initialize_usb_hw(pdev->id, MXC_EHCI_POWER_PINS_ENABLED);
+
+usbotg_free_reset:
+	gpio_free(USBH2_RST_B);
+	return err;
+}
+
+static struct mxc_usbh_platform_data otg_pdata __initdata = {
+	.init	= mx31_3ds_otg_init,
+	.portsc	= MXC_EHCI_MODE_ULPI,
+};
+
+static struct mxc_usbh_platform_data usbh2_pdata __initdata = {
+	.init = mx31_3ds_host2_init,
+	.portsc	= MXC_EHCI_MODE_ULPI,
+};
+
+static const struct fsl_usb2_platform_data usbotg_pdata __initconst = {
+	.operating_mode = FSL_USB2_DR_DEVICE,
+	.phy_mode	= FSL_USB2_PHY_ULPI,
+};
+
+static int otg_mode_host;
+
+static int __init mx31_3ds_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=", mx31_3ds_otg_mode);
+
+static const struct imxuart_platform_data uart_pdata __initconst = {
+	.flags = IMXUART_HAVE_RTSCTS,
+};
+
+static const struct imxi2c_platform_data mx31_3ds_i2c0_data __initconst = {
+	.bitrate = 100000,
+};
+
+static struct platform_device *devices[] __initdata = {
+	&mx31_3ds_ov2640,
+};
+
+static void __init mx31_3ds_init(void)
+{
+	int ret;
+
+	mxc_iomux_setup_multiple_pins(mx31_3ds_pins, ARRAY_SIZE(mx31_3ds_pins),
+				      "mx31_3ds");
+
+	imx31_add_imx_uart0(&uart_pdata);
+	imx31_add_mxc_nand(&mx31_3ds_nand_board_info);
+
+	imx31_add_spi_imx1(&spi1_pdata);
+	spi_register_board_info(mx31_3ds_spi_devs,
+						ARRAY_SIZE(mx31_3ds_spi_devs));
+
+	platform_add_devices(devices, ARRAY_SIZE(devices));
+
+	imx31_add_imx_keypad(&mx31_3ds_keymap_data);
+
+	mx31_3ds_usbotg_init();
+	if (otg_mode_host) {
+		otg_pdata.otg = imx_otg_ulpi_create(ULPI_OTG_DRVVBUS |
+				ULPI_OTG_DRVVBUS_EXT);
+		if (otg_pdata.otg)
+			imx31_add_mxc_ehci_otg(&otg_pdata);
+	}
+	usbh2_pdata.otg = imx_otg_ulpi_create(ULPI_OTG_DRVVBUS |
+			ULPI_OTG_DRVVBUS_EXT);
+	if (usbh2_pdata.otg)
+		imx31_add_mxc_ehci_hs(2, &usbh2_pdata);
+
+	if (!otg_mode_host)
+		imx31_add_fsl_usb2_udc(&usbotg_pdata);
+
+	if (mxc_expio_init(MX31_CS5_BASE_ADDR, EXPIO_PARENT_INT))
+		printk(KERN_WARNING "Init of the debug board failed, all "
+				    "devices on the debug board are unusable.\n");
+	imx31_add_imx2_wdt(NULL);
+	imx31_add_imx_i2c0(&mx31_3ds_i2c0_data);
+	imx31_add_mxc_mmc(0, &sdhc1_pdata);
+
+	imx31_add_spi_imx0(&spi0_pdata);
+	imx31_add_ipu_core(&mx3_ipu_data);
+	imx31_add_mx3_sdc_fb(&mx3fb_pdata);
+
+	/* CSI */
+	/* Camera power: default - off */
+	ret = gpio_request_array(mx31_3ds_camera_gpios,
+				 ARRAY_SIZE(mx31_3ds_camera_gpios));
+	if (ret) {
+		pr_err("Failed to request camera gpios");
+		iclink_ov2640.power = NULL;
+	}
+
+	mx31_3ds_init_camera();
+}
+
+static void __init mx31_3ds_timer_init(void)
+{
+	mx31_clocks_init(26000000);
+}
+
+static struct sys_timer mx31_3ds_timer = {
+	.init	= mx31_3ds_timer_init,
+};
+
+static void __init mx31_3ds_reserve(void)
+{
+	/* reserve MX31_3DS_CAMERA_BUF_SIZE bytes for mx3-camera */
+	mx3_camera_base = memblock_alloc(MX31_3DS_CAMERA_BUF_SIZE,
+					 MX31_3DS_CAMERA_BUF_SIZE);
+	memblock_free(mx3_camera_base, MX31_3DS_CAMERA_BUF_SIZE);
+	memblock_remove(mx3_camera_base, MX31_3DS_CAMERA_BUF_SIZE);
+}
+
+MACHINE_START(MX31_3DS, "Freescale MX31PDK (3DS)")
+	/* Maintainer: Freescale Semiconductor, Inc. */
+	.boot_params = MX3x_PHYS_OFFSET + 0x100,
+	.map_io = mx31_map_io,
+	.init_early = imx31_init_early,
+	.init_irq = mx31_init_irq,
+	.timer = &mx31_3ds_timer,
+	.init_machine = mx31_3ds_init,
+	.reserve = mx31_3ds_reserve,
+MACHINE_END
diff -druN linux-2.6.39-libre/arch/arm/mach-imx/mach-mx31ads.c linux-3.0-rc7-libre/arch/arm/mach-imx/mach-mx31ads.c
--- linux-2.6.39-libre/arch/arm/mach-imx/mach-mx31ads.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/arm/mach-imx/mach-mx31ads.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,542 @@
+/*
+ *  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.
+ */
+
+#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 <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/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-imx31.h"
+
+/* PBC Board interrupt status register */
+#define PBC_INTSTATUS           0x000016
+
+/* PBC Board interrupt current status register */
+#define PBC_INTCURR_STATUS      0x000018
+
+/* PBC Interrupt mask register set address */
+#define PBC_INTMASK_SET         0x00001A
+
+/* PBC Interrupt mask register clear address */
+#define PBC_INTMASK_CLEAR       0x00001C
+
+/* External UART A */
+#define PBC_SC16C652_UARTA      0x010000
+
+/* External UART B */
+#define PBC_SC16C652_UARTB      0x010010
+
+#define PBC_INTSTATUS_REG	(PBC_INTSTATUS + PBC_BASE_ADDRESS)
+#define PBC_INTMASK_SET_REG	(PBC_INTMASK_SET + PBC_BASE_ADDRESS)
+#define PBC_INTMASK_CLEAR_REG	(PBC_INTMASK_CLEAR + PBC_BASE_ADDRESS)
+#define EXPIO_PARENT_INT	IOMUX_TO_IRQ(MX31_PIN_GPIO1_4)
+
+#define MXC_IRQ_TO_EXPIO(irq)	((irq) - MXC_EXP_IO_BASE)
+
+#define EXPIO_INT_XUART_INTA	(MXC_EXP_IO_BASE + 10)
+#define EXPIO_INT_XUART_INTB	(MXC_EXP_IO_BASE + 11)
+
+#define MXC_MAX_EXP_IO_LINES	16
+
+/*
+ * 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);
+}
+
+static const struct imxuart_platform_data uart_pdata __initconst = {
+	.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");
+	imx31_add_imx_uart0(&uart_pdata);
+}
+
+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 d	an expio virtual irq description
+ */
+static void expio_mask_irq(struct irq_data *d)
+{
+	u32 expio = MXC_IRQ_TO_EXPIO(d->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 d	an expio virtual irq description
+ */
+static void expio_ack_irq(struct irq_data *d)
+{
+	u32 expio = MXC_IRQ_TO_EXPIO(d->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 d	an expio virtual irq description
+ */
+static void expio_unmask_irq(struct irq_data *d)
+{
+	u32 expio = MXC_IRQ_TO_EXPIO(d->irq);
+	/* unmask the interrupt */
+	__raw_writew(1 << expio, PBC_INTMASK_SET_REG);
+}
+
+static struct irq_chip expio_irq_chip = {
+	.name = "EXPIO(CPLD)",
+	.irq_ack = expio_ack_irq,
+	.irq_mask = expio_mask_irq,
+	.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++) {
+		irq_set_chip_and_handler(i, &expio_irq_chip, handle_level_irq);
+		set_irq_flags(i, IRQF_VALID);
+	}
+	irq_set_irq_type(EXPIO_PARENT_INT, IRQ_TYPE_LEVEL_HIGH);
+	irq_set_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
+
+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));
+
+	imx31_add_imx_i2c1(NULL);
+}
+
+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)
+{
+	imx31_add_imx_ssi(0, NULL);
+	mxc_iomux_setup_multiple_pins(ssi_pins, ARRAY_SIZE(ssi_pins), "ssi");
+}
+
+/* static mappings */
+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
+	},
+};
+
+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();
+}
+
+static void __init mx31ads_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,
+};
+
+MACHINE_START(MX31ADS, "Freescale MX31ADS")
+	/* Maintainer: Freescale Semiconductor, Inc. */
+	.boot_params = MX3x_PHYS_OFFSET + 0x100,
+	.map_io = mx31ads_map_io,
+	.init_early = imx31_init_early,
+	.init_irq = mx31ads_init_irq,
+	.timer = &mx31ads_timer,
+	.init_machine = mx31ads_init,
+MACHINE_END
diff -druN linux-2.6.39-libre/arch/arm/mach-imx/mach-mx31lilly.c linux-3.0-rc7-libre/arch/arm/mach-imx/mach-mx31lilly.c
--- linux-2.6.39-libre/arch/arm/mach-imx/mach-mx31lilly.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/arm/mach-imx/mach-mx31lilly.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,302 @@
+/*
+ *  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.
+ */
+
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/clk.h>
+#include <linux/gpio.h>
+#include <linux/delay.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 <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/hardware.h>
+#include <mach/common.h>
+#include <mach/iomux-mx3.h>
+#include <mach/board-mx31lilly.h>
+#include <mach/ulpi.h>
+
+#include "devices-imx31.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,
+};
+
+/* USB */
+
+#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 usbh1_init(struct platform_device *pdev)
+{
+	int pins[] = {
+		MX31_PIN_CSPI1_MOSI__USBH1_RXDM,
+		MX31_PIN_CSPI1_MISO__USBH1_RXDP,
+		MX31_PIN_CSPI1_SS0__USBH1_TXDM,
+		MX31_PIN_CSPI1_SS1__USBH1_TXDP,
+		MX31_PIN_CSPI1_SS2__USBH1_RCV,
+		MX31_PIN_CSPI1_SCLK__USBH1_OEB,
+		MX31_PIN_CSPI1_SPI_RDY__USBH1_FS,
+	};
+
+	mxc_iomux_setup_multiple_pins(pins, ARRAY_SIZE(pins), "USB H1");
+
+	mxc_iomux_set_pad(MX31_PIN_CSPI1_MOSI, USB_PAD_CFG);
+	mxc_iomux_set_pad(MX31_PIN_CSPI1_MISO, USB_PAD_CFG);
+	mxc_iomux_set_pad(MX31_PIN_CSPI1_SS0, USB_PAD_CFG);
+	mxc_iomux_set_pad(MX31_PIN_CSPI1_SS1, USB_PAD_CFG);
+	mxc_iomux_set_pad(MX31_PIN_CSPI1_SS2, USB_PAD_CFG);
+	mxc_iomux_set_pad(MX31_PIN_CSPI1_SCLK, USB_PAD_CFG);
+	mxc_iomux_set_pad(MX31_PIN_CSPI1_SPI_RDY, USB_PAD_CFG);
+
+	mxc_iomux_set_gpr(MUX_PGP_USB_SUSPEND, true);
+
+	mdelay(10);
+
+	return mx31_initialize_usb_hw(pdev->id, MXC_EHCI_POWER_PINS_ENABLED |
+			MXC_EHCI_INTERFACE_SINGLE_UNI);
+}
+
+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);
+
+	mdelay(10);
+
+	return mx31_initialize_usb_hw(pdev->id, MXC_EHCI_POWER_PINS_ENABLED);
+}
+
+static const struct mxc_usbh_platform_data usbh1_pdata __initconst = {
+	.init	= usbh1_init,
+	.portsc	= MXC_EHCI_MODE_UTMI | MXC_EHCI_SERIAL,
+};
+
+static struct mxc_usbh_platform_data usbh2_pdata __initdata = {
+	.init	= usbh2_init,
+	.portsc	= MXC_EHCI_MODE_ULPI | MXC_EHCI_UTMI_8BIT,
+};
+
+static void lilly1131_usb_init(void)
+{
+	imx31_add_mxc_ehci_hs(1, &usbh1_pdata);
+
+	usbh2_pdata.otg = imx_otg_ulpi_create(ULPI_OTG_DRVVBUS |
+			ULPI_OTG_DRVVBUS_EXT);
+	if (usbh2_pdata.otg)
+		imx31_add_mxc_ehci_hs(2, &usbh2_pdata);
+}
+
+/* SPI */
+
+static int spi_internal_chipselect[] = {
+	MXC_SPI_CS(0),
+	MXC_SPI_CS(1),
+	MXC_SPI_CS(2),
+};
+
+static const struct spi_imx_master spi0_pdata __initconst = {
+	.chipselect = spi_internal_chipselect,
+	.num_chipselect = ARRAY_SIZE(spi_internal_chipselect),
+};
+
+static const struct spi_imx_master spi1_pdata __initconst = {
+	.chipselect = spi_internal_chipselect,
+	.num_chipselect = ARRAY_SIZE(spi_internal_chipselect),
+};
+
+static struct mc13xxx_platform_data mc13783_pdata __initdata = {
+	.flags = MC13XXX_USE_RTC | MC13XXX_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,
+	.irq		= IOMUX_TO_IRQ(MX31_PIN_GPIO1_3),
+};
+
+static struct platform_device *devices[] __initdata = {
+	&smsc91x_device,
+	&physmap_flash_device,
+};
+
+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");
+
+	imx31_add_spi_imx0(&spi0_pdata);
+	imx31_add_spi_imx1(&spi1_pdata);
+	spi_register_board_info(&mc13783_dev, 1);
+
+	platform_add_devices(devices, ARRAY_SIZE(devices));
+
+	/* USB */
+	lilly1131_usb_init();
+}
+
+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")
+	.boot_params = MX3x_PHYS_OFFSET + 0x100,
+	.map_io = mx31_map_io,
+	.init_early = imx31_init_early,
+	.init_irq = mx31_init_irq,
+	.timer = &mx31lilly_timer,
+	.init_machine = mx31lilly_board_init,
+MACHINE_END
diff -druN linux-2.6.39-libre/arch/arm/mach-imx/mach-mx31lite.c linux-3.0-rc7-libre/arch/arm/mach-imx/mach-mx31lite.c
--- linux-2.6.39-libre/arch/arm/mach-imx/mach-mx31lite.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/arm/mach-imx/mach-mx31lite.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,287 @@
+/*
+ *  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.
+ */
+
+#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 <linux/delay.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/iomux-mx3.h>
+#include <mach/irqs.h>
+#include <mach/ulpi.h>
+
+#include "devices-imx31.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 const struct mxc_nand_platform_data
+mx31lite_nand_board_info __initconst  = {
+	.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 const struct spi_imx_master spi1_pdata __initconst = {
+	.chipselect	= spi_internal_chipselect,
+	.num_chipselect	= ARRAY_SIZE(spi_internal_chipselect),
+};
+
+static struct mc13xxx_platform_data mc13783_pdata __initdata = {
+	.flags  = MC13XXX_USE_RTC |
+		  MC13XXX_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
+ */
+
+#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);
+
+	mdelay(10);
+
+	return mx31_initialize_usb_hw(pdev->id, MXC_EHCI_POWER_PINS_ENABLED);
+}
+
+static struct mxc_usbh_platform_data usbh2_pdata __initdata = {
+	.init   = usbh2_init,
+	.portsc = MXC_EHCI_MODE_ULPI | MXC_EHCI_UTMI_8BIT,
+};
+
+/*
+ * 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 mx31lite_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);
+	imx31_add_mxc_nand(&mx31lite_nand_board_info);
+
+	imx31_add_spi_imx1(&spi1_pdata);
+	spi_register_board_info(&mc13783_spi_dev, 1);
+
+	/* USB */
+	usbh2_pdata.otg = imx_otg_ulpi_create(ULPI_OTG_DRVVBUS |
+			ULPI_OTG_DRVVBUS_EXT);
+	if (usbh2_pdata.otg)
+		imx31_add_mxc_ehci_hs(2, &usbh2_pdata);
+
+	/* 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. */
+	.boot_params = MX3x_PHYS_OFFSET + 0x100,
+	.map_io = mx31lite_map_io,
+	.init_early = imx31_init_early,
+	.init_irq = mx31_init_irq,
+	.timer = &mx31lite_timer,
+	.init_machine = mx31lite_init,
+MACHINE_END
diff -druN linux-2.6.39-libre/arch/arm/mach-imx/mach-mx31moboard.c linux-3.0-rc7-libre/arch/arm/mach-imx/mach-mx31moboard.c
--- linux-2.6.39-libre/arch/arm/mach-imx/mach-mx31moboard.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/arm/mach-imx/mach-mx31moboard.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,583 @@
+/*
+ *  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.
+ */
+
+#include <linux/delay.h>
+#include <linux/dma-mapping.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/memblock.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/iomux-mx3.h>
+#include <mach/ulpi.h>
+
+#include "devices-imx31.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)
+{
+	int ret = gpio_request(IOMUX_TO_GPIO(MX31_PIN_CTS1), "uart0-cts-hack");
+	if (ret)
+		return ret;
+
+	ret = gpio_direction_output(IOMUX_TO_GPIO(MX31_PIN_CTS1), 0);
+	if (ret)
+		gpio_free(IOMUX_TO_GPIO(MX31_PIN_CTS1));
+
+	return ret;
+}
+
+static void moboard_uart0_exit(struct platform_device *pdev)
+{
+	gpio_free(IOMUX_TO_GPIO(MX31_PIN_CTS1));
+}
+
+static const struct imxuart_platform_data uart0_pdata __initconst = {
+	.init = moboard_uart0_init,
+	.exit = moboard_uart0_exit,
+};
+
+static const struct imxuart_platform_data uart4_pdata __initconst = {
+	.flags = IMXUART_HAVE_RTSCTS,
+};
+
+static const struct imxi2c_platform_data moboard_i2c0_data __initconst = {
+	.bitrate = 400000,
+};
+
+static const struct imxi2c_platform_data moboard_i2c1_data __initconst = {
+	.bitrate = 100000,
+};
+
+static int moboard_spi1_cs[] = {
+	MXC_SPI_CS(0),
+	MXC_SPI_CS(2),
+};
+
+static const struct spi_imx_master moboard_spi1_pdata __initconst = {
+	.chipselect	= moboard_spi1_cs,
+	.num_chipselect	= ARRAY_SIZE(moboard_spi1_cs),
+};
+
+static struct regulator_consumer_supply sdhc_consumers[] = {
+	{
+		.dev_name = "mxc-mmc.0",
+		.supply	= "sdhc0_vcc",
+	},
+	{
+		.dev_name = "mxc-mmc.1",
+		.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_name = "mx3_camera.0",
+		.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 mc13xxx_regulator_init_data moboard_regulators[] = {
+	{
+		.id = MC13783_REG_VMMC1,
+		.init_data = &sdhc_vreg_data,
+	},
+	{
+		.id = MC13783_REG_VCAM,
+		.init_data = &cam_vreg_data,
+	},
+};
+
+static struct mc13783_led_platform_data moboard_led[] = {
+	{
+		.id = MC13783_LED_R1,
+		.name = "coreboard-led-4:red",
+		.max_current = 2,
+	},
+	{
+		.id = MC13783_LED_G1,
+		.name = "coreboard-led-4:green",
+		.max_current = 2,
+	},
+	{
+		.id = MC13783_LED_B1,
+		.name = "coreboard-led-4:blue",
+		.max_current = 2,
+	},
+	{
+		.id = MC13783_LED_R2,
+		.name = "coreboard-led-5:red",
+		.max_current = 3,
+	},
+	{
+		.id = MC13783_LED_G2,
+		.name = "coreboard-led-5:green",
+		.max_current = 3,
+	},
+	{
+		.id = MC13783_LED_B2,
+		.name = "coreboard-led-5:blue",
+		.max_current = 3,
+	},
+};
+
+static struct mc13783_leds_platform_data moboard_leds = {
+	.num_leds = ARRAY_SIZE(moboard_led),
+	.led = moboard_led,
+	.flags = MC13783_LED_SLEWLIMTC,
+	.abmode = MC13783_LED_AB_DISABLED,
+	.tc1_period = MC13783_LED_PERIOD_10MS,
+	.tc2_period = MC13783_LED_PERIOD_10MS,
+};
+
+static struct mc13xxx_platform_data moboard_pmic = {
+	.regulators = {
+		.regulators = moboard_regulators,
+		.num_regulators = ARRAY_SIZE(moboard_regulators),
+	},
+	.leds = &moboard_leds,
+	.flags = MC13XXX_USE_REGULATOR | MC13XXX_USE_RTC |
+		MC13XXX_USE_ADC | MC13XXX_USE_LED,
+};
+
+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 const struct spi_imx_master moboard_spi2_pdata __initconst = {
+	.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 const struct imxmmc_platform_data sdhc1_pdata __initconst = {
+	.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)
+#define USB_PAD_CFG (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST | PAD_CTL_HYS_CMOS | \
+		      PAD_CTL_ODE_CMOS)
+
+#define OTG_EN_B IOMUX_TO_GPIO(MX31_PIN_USB_OC)
+#define USBH2_EN_B IOMUX_TO_GPIO(MX31_PIN_SCK6)
+
+static void usb_xcvr_reset(void)
+{
+	mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA0, USB_PAD_CFG | PAD_CTL_100K_PD);
+	mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA1, USB_PAD_CFG | PAD_CTL_100K_PD);
+	mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA2, USB_PAD_CFG | PAD_CTL_100K_PD);
+	mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA3, USB_PAD_CFG | PAD_CTL_100K_PD);
+	mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA4, USB_PAD_CFG | PAD_CTL_100K_PD);
+	mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA5, USB_PAD_CFG | PAD_CTL_100K_PD);
+	mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA6, USB_PAD_CFG | PAD_CTL_100K_PD);
+	mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA7, USB_PAD_CFG | PAD_CTL_100K_PD);
+	mxc_iomux_set_pad(MX31_PIN_USBOTG_CLK, USB_PAD_CFG | PAD_CTL_100K_PU);
+	mxc_iomux_set_pad(MX31_PIN_USBOTG_DIR, USB_PAD_CFG | PAD_CTL_100K_PU);
+	mxc_iomux_set_pad(MX31_PIN_USBOTG_NXT, USB_PAD_CFG | PAD_CTL_100K_PU);
+	mxc_iomux_set_pad(MX31_PIN_USBOTG_STP, USB_PAD_CFG | PAD_CTL_100K_PU);
+
+	mxc_iomux_set_gpr(MUX_PGP_UH2, true);
+	mxc_iomux_set_pad(MX31_PIN_USBH2_CLK, USB_PAD_CFG | PAD_CTL_100K_PU);
+	mxc_iomux_set_pad(MX31_PIN_USBH2_DIR, USB_PAD_CFG | PAD_CTL_100K_PU);
+	mxc_iomux_set_pad(MX31_PIN_USBH2_NXT, USB_PAD_CFG | PAD_CTL_100K_PU);
+	mxc_iomux_set_pad(MX31_PIN_USBH2_STP, USB_PAD_CFG | PAD_CTL_100K_PU);
+	mxc_iomux_set_pad(MX31_PIN_USBH2_DATA0, USB_PAD_CFG | PAD_CTL_100K_PD);
+	mxc_iomux_set_pad(MX31_PIN_USBH2_DATA1, USB_PAD_CFG | PAD_CTL_100K_PD);
+	mxc_iomux_set_pad(MX31_PIN_SRXD6, USB_PAD_CFG | PAD_CTL_100K_PD);
+	mxc_iomux_set_pad(MX31_PIN_STXD6, USB_PAD_CFG | PAD_CTL_100K_PD);
+	mxc_iomux_set_pad(MX31_PIN_SFS3, USB_PAD_CFG | PAD_CTL_100K_PD);
+	mxc_iomux_set_pad(MX31_PIN_SCK3, USB_PAD_CFG | PAD_CTL_100K_PD);
+	mxc_iomux_set_pad(MX31_PIN_SRXD3, USB_PAD_CFG | PAD_CTL_100K_PD);
+	mxc_iomux_set_pad(MX31_PIN_STXD3, USB_PAD_CFG | PAD_CTL_100K_PD);
+
+	gpio_request(OTG_EN_B, "usb-udc-en");
+	gpio_direction_output(OTG_EN_B, 0);
+	gpio_request(USBH2_EN_B, "usbh2-en");
+	gpio_direction_output(USBH2_EN_B, 0);
+
+	gpio_request(USB_RESET_B, "usb-reset");
+	gpio_direction_output(USB_RESET_B, 0);
+	mdelay(1);
+	gpio_set_value(USB_RESET_B, 1);
+	mdelay(1);
+}
+
+static int moboard_usbh2_init_hw(struct platform_device *pdev)
+{
+	return mx31_initialize_usb_hw(pdev->id, MXC_EHCI_POWER_PINS_ENABLED);
+}
+
+static struct mxc_usbh_platform_data usbh2_pdata __initdata = {
+	.init	= moboard_usbh2_init_hw,
+	.portsc	= MXC_EHCI_MODE_ULPI | MXC_EHCI_UTMI_8BIT,
+};
+
+static int __init moboard_usbh2_init(void)
+{
+	struct platform_device *pdev;
+
+	usbh2_pdata.otg = imx_otg_ulpi_create(ULPI_OTG_DRVVBUS |
+			ULPI_OTG_DRVVBUS_EXT);
+	if (!usbh2_pdata.otg)
+		return -ENODEV;
+
+	pdev = imx31_add_mxc_ehci_hs(2, &usbh2_pdata);
+	if (IS_ERR(pdev))
+		return PTR_ERR(pdev);
+
+	return 0;
+}
+
+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 const struct ipu_platform_data mx3_ipu_data __initconst = {
+	.irq_base = MXC_IPU_IRQ_START,
+};
+
+static struct platform_device *devices[] __initdata = {
+	&mx31moboard_flash,
+	&mx31moboard_leds_device,
+};
+
+static struct mx3_camera_pdata camera_pdata __initdata = {
+	.flags		= MX3_CAMERA_DATAWIDTH_8 | MX3_CAMERA_DATAWIDTH_10,
+	.mclk_10khz	= 4800,
+};
+
+static phys_addr_t mx3_camera_base __initdata;
+#define MX3_CAMERA_BUF_SIZE SZ_4M
+
+static int __init mx31moboard_init_cam(void)
+{
+	int dma, ret = -ENOMEM;
+	struct platform_device *pdev;
+
+	imx31_add_ipu_core(&mx3_ipu_data);
+
+	pdev = imx31_alloc_mx3_camera(&camera_pdata);
+	if (IS_ERR(pdev))
+		return PTR_ERR(pdev);
+
+	dma = dma_declare_coherent_memory(&pdev->dev,
+					mx3_camera_base, mx3_camera_base,
+					MX3_CAMERA_BUF_SIZE,
+					DMA_MEMORY_MAP | DMA_MEMORY_EXCLUSIVE);
+	if (!(dma & DMA_MEMORY_MAP))
+		goto err;
+
+	ret = platform_device_add(pdev);
+	if (ret)
+err:
+		platform_device_put(pdev);
+
+	return ret;
+
+}
+
+static int mx31moboard_baseboard;
+core_param(mx31moboard_baseboard, mx31moboard_baseboard, int, 0444);
+
+/*
+ * Board specific initialization.
+ */
+static void __init mx31moboard_init(void)
+{
+	mxc_iomux_setup_multiple_pins(moboard_pins, ARRAY_SIZE(moboard_pins),
+		"moboard");
+
+	platform_add_devices(devices, ARRAY_SIZE(devices));
+
+	imx31_add_imx_uart0(&uart0_pdata);
+	imx31_add_imx_uart4(&uart4_pdata);
+
+	imx31_add_imx_i2c0(&moboard_i2c0_data);
+	imx31_add_imx_i2c1(&moboard_i2c1_data);
+
+	imx31_add_spi_imx1(&moboard_spi1_pdata);
+	imx31_add_spi_imx2(&moboard_spi2_pdata);
+
+	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));
+
+	imx31_add_mxc_mmc(0, &sdhc1_pdata);
+
+	mx31moboard_init_cam();
+
+	usb_xcvr_reset();
+
+	moboard_usbh2_init();
+
+	switch (mx31moboard_baseboard) {
+	case MX31NOBOARD:
+		break;
+	case MX31DEVBOARD:
+		mx31moboard_devboard_init();
+		break;
+	case MX31MARXBOT:
+		mx31moboard_marxbot_init();
+		break;
+	case MX31SMARTBOT:
+	case MX31EYEBOT:
+		mx31moboard_smartbot_init(mx31moboard_baseboard);
+		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,
+};
+
+static void __init mx31moboard_reserve(void)
+{
+	/* reserve 4 MiB for mx3-camera */
+	mx3_camera_base = memblock_alloc(MX3_CAMERA_BUF_SIZE,
+			MX3_CAMERA_BUF_SIZE);
+	memblock_free(mx3_camera_base, MX3_CAMERA_BUF_SIZE);
+	memblock_remove(mx3_camera_base, MX3_CAMERA_BUF_SIZE);
+}
+
+MACHINE_START(MX31MOBOARD, "EPFL Mobots mx31moboard")
+	/* Maintainer: Valentin Longchamp, EPFL Mobots group */
+	.boot_params = MX3x_PHYS_OFFSET + 0x100,
+	.reserve = mx31moboard_reserve,
+	.map_io = mx31_map_io,
+	.init_early = imx31_init_early,
+	.init_irq = mx31_init_irq,
+	.timer = &mx31moboard_timer,
+	.init_machine = mx31moboard_init,
+MACHINE_END
diff -druN linux-2.6.39-libre/arch/arm/mach-imx/mach-mx35_3ds.c linux-3.0-rc7-libre/arch/arm/mach-imx/mach-mx35_3ds.c
--- linux-2.6.39-libre/arch/arm/mach-imx/mach-mx35_3ds.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/arm/mach-imx/mach-mx35_3ds.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,224 @@
+/*
+ * Copyright 2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright (C) 2009 Marc Kleine-Budde, Pengutronix
+ *
+ * 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.
+ */
+
+/*
+ * This machine is known as:
+ *  - i.MX35 3-Stack Development System
+ *  - i.MX35 Platform Development Kit (i.MX35 PDK)
+ */
+
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/memory.h>
+#include <linux/gpio.h>
+#include <linux/usb/otg.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 <mach/hardware.h>
+#include <mach/common.h>
+#include <mach/iomux-mx35.h>
+#include <mach/irqs.h>
+#include <mach/3ds_debugboard.h>
+
+#include "devices-imx35.h"
+
+#define EXPIO_PARENT_INT	(MXC_INTERNAL_IRQS + GPIO_PORTA + 1)
+
+static const struct imxuart_platform_data uart_pdata __initconst = {
+	.flags = IMXUART_HAVE_RTSCTS,
+};
+
+static struct physmap_flash_data mx35pdk_flash_data = {
+	.width  = 2,
+};
+
+static struct resource mx35pdk_flash_resource = {
+	.start	= MX35_CS0_BASE_ADDR,
+	.end	= MX35_CS0_BASE_ADDR + SZ_64M - 1,
+	.flags	= IORESOURCE_MEM,
+};
+
+static struct platform_device mx35pdk_flash = {
+	.name	= "physmap-flash",
+	.id	= 0,
+	.dev	= {
+		.platform_data  = &mx35pdk_flash_data,
+	},
+	.resource = &mx35pdk_flash_resource,
+	.num_resources = 1,
+};
+
+static const struct mxc_nand_platform_data mx35pdk_nand_board_info __initconst = {
+	.width = 1,
+	.hw_ecc = 1,
+	.flash_bbt = 1,
+};
+
+static struct platform_device *devices[] __initdata = {
+	&mx35pdk_flash,
+};
+
+static iomux_v3_cfg_t 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,
+	/* USBH1 */
+	MX35_PAD_I2C2_CLK__USB_TOP_USBH2_PWR,
+	MX35_PAD_I2C2_DAT__USB_TOP_USBH2_OC,
+	/* SDCARD */
+	MX35_PAD_SD1_CMD__ESDHC1_CMD,
+	MX35_PAD_SD1_CLK__ESDHC1_CLK,
+	MX35_PAD_SD1_DATA0__ESDHC1_DAT0,
+	MX35_PAD_SD1_DATA1__ESDHC1_DAT1,
+	MX35_PAD_SD1_DATA2__ESDHC1_DAT2,
+	MX35_PAD_SD1_DATA3__ESDHC1_DAT3,
+	/* I2C1 */
+	MX35_PAD_I2C1_CLK__I2C1_SCL,
+	MX35_PAD_I2C1_DAT__I2C1_SDA,
+};
+
+static int mx35_3ds_otg_init(struct platform_device *pdev)
+{
+	return mx35_initialize_usb_hw(pdev->id, MXC_EHCI_INTERNAL_PHY);
+}
+
+/* OTG config */
+static const struct fsl_usb2_platform_data usb_otg_pdata __initconst = {
+	.operating_mode	= FSL_USB2_DR_DEVICE,
+	.phy_mode	= FSL_USB2_PHY_UTMI_WIDE,
+	.workaround	= FLS_USB2_WORKAROUND_ENGCM09152,
+/*
+ * ENGCM09152 also requires a hardware change.
+ * Please check the MX35 Chip Errata document for details.
+ */
+};
+
+static struct mxc_usbh_platform_data otg_pdata __initdata = {
+	.init	= mx35_3ds_otg_init,
+	.portsc	= MXC_EHCI_MODE_UTMI,
+};
+
+static int mx35_3ds_usbh_init(struct platform_device *pdev)
+{
+	return mx35_initialize_usb_hw(pdev->id, MXC_EHCI_INTERFACE_SINGLE_UNI |
+			  MXC_EHCI_INTERNAL_PHY);
+}
+
+/* USB HOST config */
+static const struct mxc_usbh_platform_data usb_host_pdata __initconst = {
+	.init		= mx35_3ds_usbh_init,
+	.portsc		= MXC_EHCI_MODE_SERIAL,
+};
+
+static int otg_mode_host;
+
+static int __init mx35_3ds_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=", mx35_3ds_otg_mode);
+
+static const struct imxi2c_platform_data mx35_3ds_i2c0_data __initconst = {
+	.bitrate = 100000,
+};
+
+/*
+ * Board specific initialization.
+ */
+static void __init mx35_3ds_init(void)
+{
+	mxc_iomux_v3_setup_multiple_pads(mx35pdk_pads, ARRAY_SIZE(mx35pdk_pads));
+
+	imx35_add_fec(NULL);
+	imx35_add_imx2_wdt(NULL);
+	platform_add_devices(devices, ARRAY_SIZE(devices));
+
+	imx35_add_imx_uart0(&uart_pdata);
+
+	if (otg_mode_host)
+		imx35_add_mxc_ehci_otg(&otg_pdata);
+
+	imx35_add_mxc_ehci_hs(&usb_host_pdata);
+
+	if (!otg_mode_host)
+		imx35_add_fsl_usb2_udc(&usb_otg_pdata);
+
+	imx35_add_mxc_nand(&mx35pdk_nand_board_info);
+	imx35_add_sdhci_esdhc_imx(0, NULL);
+
+	if (mxc_expio_init(MX35_CS5_BASE_ADDR, EXPIO_PARENT_INT))
+		pr_warn("Init of the debugboard failed, all "
+				"devices on the debugboard are unusable.\n");
+	imx35_add_imx_i2c0(&mx35_3ds_i2c0_data);
+}
+
+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 */
+	.boot_params = MX3x_PHYS_OFFSET + 0x100,
+	.map_io = mx35_map_io,
+	.init_early = imx35_init_early,
+	.init_irq = mx35_init_irq,
+	.timer = &mx35pdk_timer,
+	.init_machine = mx35_3ds_init,
+MACHINE_END
diff -druN linux-2.6.39-libre/arch/arm/mach-imx/mach-mxt_td60.c linux-3.0-rc7-libre/arch/arm/mach-imx/mach-mxt_td60.c
--- linux-2.6.39-libre/arch/arm/mach-imx/mach-mxt_td60.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-imx/mach-mxt_td60.c	2011-07-11 19:51:52.000000000 -0400
@@ -29,7 +29,6 @@
 #include <asm/mach/map.h>
 #include <linux/gpio.h>
 #include <mach/iomux-mx27.h>
-#include <mach/mxc_nand.h>
 #include <linux/i2c/pca953x.h>
 
 #include "devices-imx27.h"
diff -druN linux-2.6.39-libre/arch/arm/mach-imx/mach-pca100.c linux-3.0-rc7-libre/arch/arm/mach-imx/mach-pca100.c
--- linux-2.6.39-libre/arch/arm/mach-imx/mach-pca100.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-imx/mach-pca100.c	2011-07-11 19:51:52.000000000 -0400
@@ -37,7 +37,6 @@
 #include <mach/iomux-mx27.h>
 #include <asm/mach/time.h>
 #include <mach/audmux.h>
-#include <mach/mxc_nand.h>
 #include <mach/irqs.h>
 #include <mach/ulpi.h>
 
diff -druN linux-2.6.39-libre/arch/arm/mach-imx/mach-pcm037.c linux-3.0-rc7-libre/arch/arm/mach-imx/mach-pcm037.c
--- linux-2.6.39-libre/arch/arm/mach-imx/mach-pcm037.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/arm/mach-imx/mach-pcm037.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,696 @@
+/*
+ *  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.
+ */
+
+#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/can/platform/sja1000.h>
+#include <linux/usb/otg.h>
+#include <linux/usb/ulpi.h>
+#include <linux/gfp.h>
+#include <linux/memblock.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/common.h>
+#include <mach/hardware.h>
+#include <mach/iomux-mx3.h>
+#include <mach/ulpi.h>
+
+#include "devices-imx31.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 const struct imxuart_platform_data uart_pdata __initconst = {
+	.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 const struct mxc_nand_platform_data
+pcm037_nand_board_info __initconst = {
+	.width = 1,
+	.hw_ecc = 1,
+};
+
+static const struct imxi2c_platform_data pcm037_i2c1_data __initconst = {
+	.bitrate = 100000,
+};
+
+static const struct imxi2c_platform_data pcm037_i2c2_data __initconst = {
+	.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,
+};
+
+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,
+};
+
+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 const struct imxmmc_platform_data sdhc_pdata __initconst = {
+#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 __initdata = {
+	.flags		= MX3_CAMERA_DATAWIDTH_8 | MX3_CAMERA_DATAWIDTH_10,
+	.mclk_10khz	= 2000,
+};
+
+static phys_addr_t mx3_camera_base __initdata;
+#define MX3_CAMERA_BUF_SIZE SZ_4M
+
+static int __init pcm037_init_camera(void)
+{
+	int dma, ret = -ENOMEM;
+	struct platform_device *pdev = imx31_alloc_mx3_camera(&camera_pdata);
+
+	if (IS_ERR(pdev))
+		return PTR_ERR(pdev);
+
+	dma = dma_declare_coherent_memory(&pdev->dev,
+					mx3_camera_base, mx3_camera_base,
+					MX3_CAMERA_BUF_SIZE,
+					DMA_MEMORY_MAP | DMA_MEMORY_EXCLUSIVE);
+	if (!(dma & DMA_MEMORY_MAP))
+		goto err;
+
+	ret = platform_device_add(pdev);
+	if (ret)
+err:
+		platform_device_put(pdev);
+
+	return ret;
+}
+
+static struct platform_device *devices[] __initdata = {
+	&pcm037_flash,
+	&pcm037_sram_device,
+	&pcm037_mt9t031,
+	&pcm037_mt9v022,
+};
+
+static const struct ipu_platform_data mx3_ipu_data __initconst = {
+	.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 = {
+	.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 = {
+	.osc_freq	= 16000000,
+	.ocr		= OCR_TX1_PULLDOWN | OCR_TX0_PUSHPULL,
+	.cdr		= CDR_CBP,
+};
+
+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 int pcm037_otg_init(struct platform_device *pdev)
+{
+	return mx31_initialize_usb_hw(pdev->id, MXC_EHCI_INTERFACE_DIFF_UNI);
+}
+
+static struct mxc_usbh_platform_data otg_pdata __initdata = {
+	.init	= pcm037_otg_init,
+	.portsc	= MXC_EHCI_MODE_ULPI,
+};
+
+static int pcm037_usbh2_init(struct platform_device *pdev)
+{
+	return mx31_initialize_usb_hw(pdev->id, MXC_EHCI_INTERFACE_DIFF_UNI);
+}
+
+static struct mxc_usbh_platform_data usbh2_pdata __initdata = {
+	.init	= pcm037_usbh2_init,
+	.portsc	= MXC_EHCI_MODE_ULPI,
+};
+
+static const struct fsl_usb2_platform_data otg_device_pdata __initconst = {
+	.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 pcm037_init(void)
+{
+	int ret;
+
+	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));
+
+	imx31_add_imx2_wdt(NULL);
+	imx31_add_imx_uart0(&uart_pdata);
+	/* XXX: should't this have .flags = 0 (i.e. no RTSCTS) on PCM037_EET? */
+	imx31_add_imx_uart1(&uart_pdata);
+	imx31_add_imx_uart2(&uart_pdata);
+
+	imx31_add_mxc_w1(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));
+
+	imx31_add_imx_i2c1(&pcm037_i2c1_data);
+	imx31_add_imx_i2c2(&pcm037_i2c2_data);
+
+	imx31_add_mxc_nand(&pcm037_nand_board_info);
+	imx31_add_mxc_mmc(0, &sdhc_pdata);
+	imx31_add_ipu_core(&mx3_ipu_data);
+	imx31_add_mx3_sdc_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;
+
+	pcm037_init_camera();
+
+	platform_device_register(&pcm970_sja1000);
+
+	if (otg_mode_host) {
+		otg_pdata.otg = imx_otg_ulpi_create(ULPI_OTG_DRVVBUS |
+				ULPI_OTG_DRVVBUS_EXT);
+		if (otg_pdata.otg)
+			imx31_add_mxc_ehci_otg(&otg_pdata);
+	}
+
+	usbh2_pdata.otg = imx_otg_ulpi_create(ULPI_OTG_DRVVBUS |
+			ULPI_OTG_DRVVBUS_EXT);
+	if (usbh2_pdata.otg)
+		imx31_add_mxc_ehci_hs(2, &usbh2_pdata);
+
+	if (!otg_mode_host)
+		imx31_add_fsl_usb2_udc(&otg_device_pdata);
+
+}
+
+static void __init pcm037_timer_init(void)
+{
+	mx31_clocks_init(26000000);
+}
+
+struct sys_timer pcm037_timer = {
+	.init	= pcm037_timer_init,
+};
+
+static void __init pcm037_reserve(void)
+{
+	/* reserve 4 MiB for mx3-camera */
+	mx3_camera_base = memblock_alloc(MX3_CAMERA_BUF_SIZE,
+			MX3_CAMERA_BUF_SIZE);
+	memblock_free(mx3_camera_base, MX3_CAMERA_BUF_SIZE);
+	memblock_remove(mx3_camera_base, MX3_CAMERA_BUF_SIZE);
+}
+
+MACHINE_START(PCM037, "Phytec Phycore pcm037")
+	/* Maintainer: Pengutronix */
+	.boot_params = MX3x_PHYS_OFFSET + 0x100,
+	.reserve = pcm037_reserve,
+	.map_io = mx31_map_io,
+	.init_early = imx31_init_early,
+	.init_irq = mx31_init_irq,
+	.timer = &pcm037_timer,
+	.init_machine = pcm037_init,
+MACHINE_END
diff -druN linux-2.6.39-libre/arch/arm/mach-imx/mach-pcm037_eet.c linux-3.0-rc7-libre/arch/arm/mach-imx/mach-pcm037_eet.c
--- linux-2.6.39-libre/arch/arm/mach-imx/mach-pcm037_eet.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/arm/mach-imx/mach-pcm037_eet.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,179 @@
+/*
+ * 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/input.h>
+#include <linux/platform_device.h>
+#include <linux/spi/spi.h>
+
+#include <mach/common.h>
+#include <mach/iomux-mx3.h>
+
+#include <asm/mach-types.h>
+
+#include "pcm037.h"
+#include "devices-imx31.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 */
+static int pcm037_spi1_cs[] = {MXC_SPI_CS(1), IOMUX_TO_GPIO(MX31_PIN_KEY_COL7)};
+
+static const struct spi_imx_master pcm037_spi1_pdata __initconst = {
+	.chipselect = pcm037_spi1_cs,
+	.num_chipselect = ARRAY_SIZE(pcm037_spi1_cs),
+};
+
+/* 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 const struct gpio_keys_platform_data
+		pcm037_gpio_keys_platform_data __initconst = {
+	.buttons	= pcm037_gpio_keys,
+	.nbuttons	= ARRAY_SIZE(pcm037_gpio_keys),
+	.rep		= 0, /* No auto-repeat */
+};
+
+static int __init 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));
+	imx31_add_spi_imx0(&pcm037_spi1_pdata);
+
+	imx_add_gpio_keys(&pcm037_gpio_keys_platform_data);
+
+	return 0;
+}
+late_initcall(eet_init_devices);
diff -druN linux-2.6.39-libre/arch/arm/mach-imx/mach-pcm038.c linux-3.0-rc7-libre/arch/arm/mach-imx/mach-pcm038.c
--- linux-2.6.39-libre/arch/arm/mach-imx/mach-pcm038.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-imx/mach-pcm038.c	2011-07-11 19:51:52.000000000 -0400
@@ -36,7 +36,6 @@
 #include <mach/common.h>
 #include <mach/hardware.h>
 #include <mach/iomux-mx27.h>
-#include <mach/mxc_nand.h>
 #include <mach/ulpi.h>
 
 #include "devices-imx27.h"
diff -druN linux-2.6.39-libre/arch/arm/mach-imx/mach-pcm043.c linux-3.0-rc7-libre/arch/arm/mach-imx/mach-pcm043.c
--- linux-2.6.39-libre/arch/arm/mach-imx/mach-pcm043.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/arm/mach-imx/mach-pcm043.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,423 @@
+/*
+ *  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.
+ */
+
+#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 <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-mx35.h>
+#include <mach/ulpi.h>
+#include <mach/audmux.h>
+
+#include "devices-imx35.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 const struct ipu_platform_data mx3_ipu_data __initconst = {
+	.irq_base = MXC_IPU_IRQ_START,
+};
+
+static struct mx3fb_platform_data mx3fb_pdata __initdata = {
+	.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 const struct imxuart_platform_data uart_pdata __initconst = {
+	.flags = IMXUART_HAVE_RTSCTS,
+};
+
+static const struct imxi2c_platform_data pcm043_i2c0_data __initconst = {
+	.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),
+	},
+};
+
+static struct platform_device *devices[] __initdata = {
+	&pcm043_flash,
+};
+
+static iomux_v3_cfg_t 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,
+	/* CAN2 */
+	MX35_PAD_TX5_RX0__CAN2_TXCAN,
+	MX35_PAD_TX4_RX1__CAN2_RXCAN,
+	/* esdhc */
+	MX35_PAD_SD1_CMD__ESDHC1_CMD,
+	MX35_PAD_SD1_CLK__ESDHC1_CLK,
+	MX35_PAD_SD1_DATA0__ESDHC1_DAT0,
+	MX35_PAD_SD1_DATA1__ESDHC1_DAT1,
+	MX35_PAD_SD1_DATA2__ESDHC1_DAT2,
+	MX35_PAD_SD1_DATA3__ESDHC1_DAT3,
+	MX35_PAD_ATA_DATA10__GPIO2_23, /* WriteProtect */
+	MX35_PAD_ATA_DATA11__GPIO2_24, /* CardDetect */
+};
+
+#define AC97_GPIO_TXFS	IMX_GPIO_NR(2, 31)
+#define AC97_GPIO_TXD	IMX_GPIO_NR(2, 28)
+#define AC97_GPIO_RESET	IMX_GPIO_NR(2, 0)
+#define SD1_GPIO_WP	IMX_GPIO_NR(2, 23)
+#define SD1_GPIO_CD	IMX_GPIO_NR(2, 24)
+
+static void pcm043_ac97_warm_reset(struct snd_ac97 *ac97)
+{
+	iomux_v3_cfg_t txfs_gpio = MX35_PAD_STXFS4__GPIO2_31;
+	iomux_v3_cfg_t 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)
+{
+	iomux_v3_cfg_t txfs_gpio = MX35_PAD_STXFS4__GPIO2_31;
+	iomux_v3_cfg_t txfs = MX35_PAD_STXFS4__AUDMUX_AUD4_TXFS;
+	iomux_v3_cfg_t txd_gpio = MX35_PAD_STXD4__GPIO2_28;
+	iomux_v3_cfg_t txd = MX35_PAD_STXD4__AUDMUX_AUD4_TXD;
+	iomux_v3_cfg_t 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 const struct imx_ssi_platform_data pcm043_ssi_pdata __initconst = {
+	.ac97_reset = pcm043_ac97_cold_reset,
+	.ac97_warm_reset = pcm043_ac97_warm_reset,
+	.flags = IMX_SSI_USE_AC97,
+};
+
+static const struct mxc_nand_platform_data
+pcm037_nand_board_info __initconst = {
+	.width = 1,
+	.hw_ecc = 1,
+};
+
+static int pcm043_otg_init(struct platform_device *pdev)
+{
+	return mx35_initialize_usb_hw(pdev->id, MXC_EHCI_INTERFACE_DIFF_UNI);
+}
+
+static struct mxc_usbh_platform_data otg_pdata __initdata = {
+	.init	= pcm043_otg_init,
+	.portsc	= MXC_EHCI_MODE_UTMI,
+};
+
+static int pcm043_usbh1_init(struct platform_device *pdev)
+{
+	return mx35_initialize_usb_hw(pdev->id, MXC_EHCI_INTERFACE_SINGLE_UNI |
+			MXC_EHCI_INTERNAL_PHY | MXC_EHCI_IPPUE_DOWN);
+}
+
+static const struct mxc_usbh_platform_data usbh1_pdata __initconst = {
+	.init	= pcm043_usbh1_init,
+	.portsc	= MXC_EHCI_MODE_SERIAL,
+};
+
+static const struct fsl_usb2_platform_data otg_device_pdata __initconst = {
+	.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);
+
+static struct esdhc_platform_data sd1_pdata = {
+	.wp_gpio = SD1_GPIO_WP,
+	.cd_gpio = SD1_GPIO_CD,
+};
+
+/*
+ * Board specific initialization.
+ */
+static void __init pcm043_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));
+
+	imx35_add_fec(NULL);
+	platform_add_devices(devices, ARRAY_SIZE(devices));
+	imx35_add_imx2_wdt(NULL);
+
+	imx35_add_imx_uart0(&uart_pdata);
+	imx35_add_mxc_nand(&pcm037_nand_board_info);
+	imx35_add_imx_ssi(0, &pcm043_ssi_pdata);
+
+	imx35_add_imx_uart1(&uart_pdata);
+
+	i2c_register_board_info(0, pcm043_i2c_devices,
+			ARRAY_SIZE(pcm043_i2c_devices));
+
+	imx35_add_imx_i2c0(&pcm043_i2c0_data);
+
+	imx35_add_ipu_core(&mx3_ipu_data);
+	imx35_add_mx3_sdc_fb(&mx3fb_pdata);
+
+	if (otg_mode_host) {
+		otg_pdata.otg = imx_otg_ulpi_create(ULPI_OTG_DRVVBUS |
+				ULPI_OTG_DRVVBUS_EXT);
+		if (otg_pdata.otg)
+			imx35_add_mxc_ehci_otg(&otg_pdata);
+	}
+	imx35_add_mxc_ehci_hs(&usbh1_pdata);
+
+	if (!otg_mode_host)
+		imx35_add_fsl_usb2_udc(&otg_device_pdata);
+
+	imx35_add_flexcan1(NULL);
+	imx35_add_sdhci_esdhc_imx(0, &sd1_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 */
+	.boot_params = MX3x_PHYS_OFFSET + 0x100,
+	.map_io = mx35_map_io,
+	.init_early = imx35_init_early,
+	.init_irq = mx35_init_irq,
+	.timer = &pcm043_timer,
+	.init_machine = pcm043_init,
+MACHINE_END
diff -druN linux-2.6.39-libre/arch/arm/mach-imx/mach-qong.c linux-3.0-rc7-libre/arch/arm/mach-imx/mach-qong.c
--- linux-2.6.39-libre/arch/arm/mach-imx/mach-qong.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/arm/mach-imx/mach-qong.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,269 @@
+/*
+ *  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.
+ */
+
+#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/iomux-mx3.h>
+
+#include "devices-imx31.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)
+
+static const struct imxuart_platform_data uart_pdata __initconst = {
+	.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 __init mxc_init_imx_uart(void)
+{
+	mxc_iomux_setup_multiple_pins(uart_pins, ARRAY_SIZE(uart_pins),
+			"uart-0");
+	imx31_add_imx_uart0(&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 + SZ_128M - 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 = {
+		.nr_chips		= 1,
+		.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 qong_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,
+};
+
+MACHINE_START(QONG, "Dave/DENX QongEVB-LITE")
+	/* Maintainer: DENX Software Engineering GmbH */
+	.boot_params = MX3x_PHYS_OFFSET + 0x100,
+	.map_io = mx31_map_io,
+	.init_early = imx31_init_early,
+	.init_irq = mx31_init_irq,
+	.timer = &qong_timer,
+	.init_machine = qong_init,
+MACHINE_END
diff -druN linux-2.6.39-libre/arch/arm/mach-imx/mach-vpr200.c linux-3.0-rc7-libre/arch/arm/mach-imx/mach-vpr200.c
--- linux-2.6.39-libre/arch/arm/mach-imx/mach-vpr200.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/arm/mach-imx/mach-vpr200.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,322 @@
+/*
+ * Copyright 2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright (C) 2009 Marc Kleine-Budde, Pengutronix
+ * Copyright 2010 Creative Product Design
+ *
+ * Derived from mx35 3stack.
+ * Original 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.
+ */
+
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/physmap.h>
+#include <linux/memory.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/iomux-mx35.h>
+#include <mach/irqs.h>
+
+#include <linux/i2c.h>
+#include <linux/i2c/at24.h>
+#include <linux/mfd/mc13xxx.h>
+
+#include "devices-imx35.h"
+
+#define GPIO_LCDPWR	IMX_GPIO_NR(1, 2)
+#define GPIO_PMIC_INT	IMX_GPIO_NR(2, 0)
+
+#define GPIO_BUTTON1	IMX_GPIO_NR(1, 4)
+#define GPIO_BUTTON2	IMX_GPIO_NR(1, 5)
+#define GPIO_BUTTON3	IMX_GPIO_NR(1, 7)
+#define GPIO_BUTTON4	IMX_GPIO_NR(1, 8)
+#define GPIO_BUTTON5	IMX_GPIO_NR(1, 9)
+#define GPIO_BUTTON6	IMX_GPIO_NR(1, 10)
+#define GPIO_BUTTON7	IMX_GPIO_NR(1, 11)
+#define GPIO_BUTTON8	IMX_GPIO_NR(1, 12)
+
+static const struct fb_videomode fb_modedb[] = {
+	{
+		/* 800x480 @ 60 Hz */
+		.name		= "PT0708048",
+		.refresh	= 60,
+		.xres		= 800,
+		.yres		= 480,
+		.pixclock	= KHZ2PICOS(33260),
+		.left_margin	= 50,
+		.right_margin	= 156,
+		.upper_margin	= 10,
+		.lower_margin	= 10,
+		.hsync_len	= 1,	/* note: DE only display */
+		.vsync_len	= 1,	/* note: DE only display */
+		.sync		= FB_SYNC_CLK_IDLE_EN | FB_SYNC_OE_ACT_HIGH,
+		.vmode		= FB_VMODE_NONINTERLACED,
+		.flag		= 0,
+	}, {
+		/* 800x480 @ 60 Hz */
+		.name		= "CTP-CLAA070LC0ACW",
+		.refresh	= 60,
+		.xres		= 800,
+		.yres		= 480,
+		.pixclock	= KHZ2PICOS(27000),
+		.left_margin	= 50,
+		.right_margin	= 50,	/* whole line should have 900 clocks */
+		.upper_margin	= 10,
+		.lower_margin	= 10,	/* whole frame should have 500 lines */
+		.hsync_len	= 1,	/* note: DE only display */
+		.vsync_len	= 1,	/* note: DE only display */
+		.sync		= FB_SYNC_CLK_IDLE_EN | FB_SYNC_OE_ACT_HIGH,
+		.vmode		= FB_VMODE_NONINTERLACED,
+		.flag		= 0,
+	}
+};
+
+static const struct ipu_platform_data mx3_ipu_data __initconst = {
+	.irq_base = MXC_IPU_IRQ_START,
+};
+
+static struct mx3fb_platform_data mx3fb_pdata __initdata = {
+	.name		= "PT0708048",
+	.mode		= fb_modedb,
+	.num_modes	= ARRAY_SIZE(fb_modedb),
+};
+
+static struct physmap_flash_data vpr200_flash_data = {
+	.width  = 2,
+};
+
+static struct resource vpr200_flash_resource = {
+	.start	= MX35_CS0_BASE_ADDR,
+	.end	= MX35_CS0_BASE_ADDR + SZ_64M - 1,
+	.flags	= IORESOURCE_MEM,
+};
+
+static struct platform_device vpr200_flash = {
+	.name	= "physmap-flash",
+	.id	= 0,
+	.dev	= {
+		.platform_data  = &vpr200_flash_data,
+	},
+	.resource = &vpr200_flash_resource,
+	.num_resources = 1,
+};
+
+static const struct mxc_nand_platform_data
+		vpr200_nand_board_info __initconst = {
+	.width = 1,
+	.hw_ecc = 1,
+	.flash_bbt = 1,
+};
+
+#define VPR_KEY_DEBOUNCE	500
+static struct gpio_keys_button vpr200_gpio_keys_table[] = {
+	{KEY_F2, GPIO_BUTTON1, 1, "vpr-keys: F2", 0, VPR_KEY_DEBOUNCE},
+	{KEY_F3, GPIO_BUTTON2, 1, "vpr-keys: F3", 0, VPR_KEY_DEBOUNCE},
+	{KEY_F4, GPIO_BUTTON3, 1, "vpr-keys: F4", 0, VPR_KEY_DEBOUNCE},
+	{KEY_F5, GPIO_BUTTON4, 1, "vpr-keys: F5", 0, VPR_KEY_DEBOUNCE},
+	{KEY_F6, GPIO_BUTTON5, 1, "vpr-keys: F6", 0, VPR_KEY_DEBOUNCE},
+	{KEY_F7, GPIO_BUTTON6, 1, "vpr-keys: F7", 0, VPR_KEY_DEBOUNCE},
+	{KEY_F8, GPIO_BUTTON7, 1, "vpr-keys: F8", 1, VPR_KEY_DEBOUNCE},
+	{KEY_F9, GPIO_BUTTON8, 1, "vpr-keys: F9", 1, VPR_KEY_DEBOUNCE},
+};
+
+static const struct gpio_keys_platform_data
+		vpr200_gpio_keys_data __initconst = {
+	.buttons = vpr200_gpio_keys_table,
+	.nbuttons = ARRAY_SIZE(vpr200_gpio_keys_table),
+};
+
+static struct mc13xxx_platform_data vpr200_pmic = {
+	.flags = MC13XXX_USE_ADC | MC13XXX_USE_TOUCHSCREEN,
+};
+
+static const struct imxi2c_platform_data vpr200_i2c0_data __initconst = {
+	.bitrate = 50000,
+};
+
+static struct at24_platform_data vpr200_eeprom = {
+	.byte_len = 2048 / 8,
+	.page_size = 1,
+};
+
+static struct i2c_board_info vpr200_i2c_devices[] = {
+	{
+		I2C_BOARD_INFO("at24", 0x50), /* E0=0, E1=0, E2=0 */
+		.platform_data = &vpr200_eeprom,
+	}, {
+		I2C_BOARD_INFO("mc13892", 0x08),
+		.platform_data = &vpr200_pmic,
+		.irq = gpio_to_irq(GPIO_PMIC_INT),
+	}
+};
+
+static iomux_v3_cfg_t vpr200_pads[] = {
+	/* UART1 */
+	MX35_PAD_TXD1__UART1_TXD_MUX,
+	MX35_PAD_RXD1__UART1_RXD_MUX,
+	/* UART3 */
+	MX35_PAD_ATA_DATA10__UART3_RXD_MUX,
+	MX35_PAD_ATA_DATA11__UART3_TXD_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,
+	/* 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_FPSHIFT__IPU_DISPB_D3_CLK,
+	MX35_PAD_D3_DRDY__IPU_DISPB_D3_DRDY,
+	MX35_PAD_CONTRAST__IPU_DISPB_CONTR,
+	/* LCD Enable */
+	MX35_PAD_D3_VSYNC__GPIO1_2,
+	/* USBOTG */
+	MX35_PAD_USBOTG_PWR__USB_TOP_USBOTG_PWR,
+	MX35_PAD_USBOTG_OC__USB_TOP_USBOTG_OC,
+	/* SDCARD */
+	MX35_PAD_SD1_CMD__ESDHC1_CMD,
+	MX35_PAD_SD1_CLK__ESDHC1_CLK,
+	MX35_PAD_SD1_DATA0__ESDHC1_DAT0,
+	MX35_PAD_SD1_DATA1__ESDHC1_DAT1,
+	MX35_PAD_SD1_DATA2__ESDHC1_DAT2,
+	MX35_PAD_SD1_DATA3__ESDHC1_DAT3,
+	/* PMIC */
+	MX35_PAD_GPIO2_0__GPIO2_0,
+	/* GPIO keys */
+	MX35_PAD_SCKR__GPIO1_4,
+	MX35_PAD_COMPARE__GPIO1_5,
+	MX35_PAD_SCKT__GPIO1_7,
+	MX35_PAD_FST__GPIO1_8,
+	MX35_PAD_HCKT__GPIO1_9,
+	MX35_PAD_TX5_RX0__GPIO1_10,
+	MX35_PAD_TX4_RX1__GPIO1_11,
+	MX35_PAD_TX3_RX2__GPIO1_12,
+};
+
+/* USB Device config */
+static const struct fsl_usb2_platform_data otg_device_pdata __initconst = {
+	.operating_mode	= FSL_USB2_DR_DEVICE,
+	.phy_mode	= FSL_USB2_PHY_UTMI,
+	.workaround	= FLS_USB2_WORKAROUND_ENGCM09152,
+};
+
+static int vpr200_usbh_init(struct platform_device *pdev)
+{
+	return mx35_initialize_usb_hw(pdev->id,
+			MXC_EHCI_INTERFACE_SINGLE_UNI | MXC_EHCI_INTERNAL_PHY);
+}
+
+/* USB HOST config */
+static const struct mxc_usbh_platform_data usb_host_pdata __initconst = {
+	.init = vpr200_usbh_init,
+	.portsc = MXC_EHCI_MODE_SERIAL,
+};
+
+static struct platform_device *devices[] __initdata = {
+	&vpr200_flash,
+};
+
+/*
+ * Board specific initialization.
+ */
+static void __init vpr200_board_init(void)
+{
+	mxc_iomux_v3_setup_multiple_pads(vpr200_pads, ARRAY_SIZE(vpr200_pads));
+
+	imx35_add_fec(NULL);
+	imx35_add_imx2_wdt(NULL);
+	imx_add_gpio_keys(&vpr200_gpio_keys_data);
+
+	platform_add_devices(devices, ARRAY_SIZE(devices));
+
+	if (0 != gpio_request(GPIO_LCDPWR, "LCDPWR"))
+		printk(KERN_WARNING "vpr200: Couldn't get LCDPWR gpio\n");
+	else
+		gpio_direction_output(GPIO_LCDPWR, 0);
+
+	if (0 != gpio_request(GPIO_PMIC_INT, "PMIC_INT"))
+		printk(KERN_WARNING "vpr200: Couldn't get PMIC_INT gpio\n");
+	else
+		gpio_direction_input(GPIO_PMIC_INT);
+
+	imx35_add_imx_uart0(NULL);
+	imx35_add_imx_uart2(NULL);
+
+	imx35_add_ipu_core(&mx3_ipu_data);
+	imx35_add_mx3_sdc_fb(&mx3fb_pdata);
+
+	imx35_add_fsl_usb2_udc(&otg_device_pdata);
+	imx35_add_mxc_ehci_hs(&usb_host_pdata);
+
+	imx35_add_mxc_nand(&vpr200_nand_board_info);
+	imx35_add_sdhci_esdhc_imx(0, NULL);
+
+	i2c_register_board_info(0, vpr200_i2c_devices,
+			ARRAY_SIZE(vpr200_i2c_devices));
+
+	imx35_add_imx_i2c0(&vpr200_i2c0_data);
+}
+
+static void __init vpr200_timer_init(void)
+{
+	mx35_clocks_init();
+}
+
+struct sys_timer vpr200_timer = {
+	.init	= vpr200_timer_init,
+};
+
+MACHINE_START(VPR200, "VPR200")
+	/* Maintainer: Creative Product Design */
+	.map_io = mx35_map_io,
+	.init_early = imx35_init_early,
+	.init_irq = mx35_init_irq,
+	.timer = &vpr200_timer,
+	.init_machine = vpr200_board_init,
+MACHINE_END
diff -druN linux-2.6.39-libre/arch/arm/mach-imx/Makefile linux-3.0-rc7-libre/arch/arm/mach-imx/Makefile
--- linux-2.6.39-libre/arch/arm/mach-imx/Makefile	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-imx/Makefile	2011-07-11 19:51:52.000000000 -0400
@@ -1,9 +1,3 @@
-#
-# Makefile for the linux kernel.
-#
-
-# Object file lists.
-
 obj-$(CONFIG_IMX_HAVE_DMA_V1) += dma-v1.o
 
 obj-$(CONFIG_ARCH_MX1) += clock-imx1.o mm-imx1.o
@@ -14,18 +8,27 @@
 obj-$(CONFIG_MACH_MX27) += cpu-imx27.o pm-imx27.o
 obj-$(CONFIG_MACH_MX27) += clock-imx27.o mm-imx27.o ehci-imx27.o
 
+obj-$(CONFIG_SOC_IMX31) += mm-imx31.o cpu-imx31.o clock-imx31.o iomux-imx31.o ehci-imx31.o
+obj-$(CONFIG_SOC_IMX35) += mm-imx35.o cpu-imx35.o clock-imx35.o ehci-imx35.o
+obj-$(CONFIG_CACHE_L2X0) += cache-l2x0.o
+
 # Support for CMOS sensor interface
-obj-$(CONFIG_MX1_VIDEO)	+= mx1-camera-fiq.o mx1-camera-fiq-ksym.o
+obj-$(CONFIG_MX1_VIDEO) += mx1-camera-fiq.o mx1-camera-fiq-ksym.o
 
+# i.MX1 based machines
 obj-$(CONFIG_ARCH_MX1ADS) += mach-mx1ads.o
 obj-$(CONFIG_MACH_SCB9328) += mach-scb9328.o
+obj-$(CONFIG_MACH_APF9328) += mach-apf9328.o
 
+# i.MX21 based machines
 obj-$(CONFIG_MACH_MX21ADS) += mach-mx21ads.o
 
+# i.MX25 based machines
 obj-$(CONFIG_MACH_MX25_3DS) += mach-mx25_3ds.o
 obj-$(CONFIG_MACH_EUKREA_CPUIMX25) += mach-eukrea_cpuimx25.o
 obj-$(CONFIG_MACH_EUKREA_MBIMXSD25_BASEBOARD) += eukrea_mbimxsd25-baseboard.o
 
+# i.MX27 based machines
 obj-$(CONFIG_MACH_MX27ADS) += mach-mx27ads.o
 obj-$(CONFIG_MACH_PCM038) += mach-pcm038.o
 obj-$(CONFIG_MACH_PCM970_BASEBOARD) += pcm970-baseboard.o
@@ -37,3 +40,24 @@
 obj-$(CONFIG_MACH_PCA100) += mach-pca100.o
 obj-$(CONFIG_MACH_MXT_TD60) += mach-mxt_td60.o
 obj-$(CONFIG_MACH_IMX27IPCAM) += mach-imx27ipcam.o
+
+# i.MX31 based machines
+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
+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_ARMADILLO5X0) += mach-armadillo5x0.o
+obj-$(CONFIG_MACH_KZM_ARM11_01) += mach-kzm_arm11_01.o
+obj-$(CONFIG_MACH_BUG) += mach-bug.o
+
+# i.MX35 based machines
+obj-$(CONFIG_MACH_PCM043) += mach-pcm043.o
+obj-$(CONFIG_MACH_MX35_3DS) += mach-mx35_3ds.o
+obj-$(CONFIG_MACH_EUKREA_CPUIMX35) += mach-cpuimx35.o
+obj-$(CONFIG_MACH_EUKREA_MBIMXSD35_BASEBOARD) += eukrea_mbimxsd35-baseboard.o
+obj-$(CONFIG_MACH_VPR200) += mach-vpr200.o
diff -druN linux-2.6.39-libre/arch/arm/mach-imx/Makefile.boot linux-3.0-rc7-libre/arch/arm/mach-imx/Makefile.boot
--- linux-2.6.39-libre/arch/arm/mach-imx/Makefile.boot	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-imx/Makefile.boot	2011-07-11 19:51:52.000000000 -0400
@@ -13,3 +13,7 @@
 zreladdr-$(CONFIG_MACH_MX27)	:= 0xA0008000
 params_phys-$(CONFIG_MACH_MX27)	:= 0xA0000100
 initrd_phys-$(CONFIG_MACH_MX27)	:= 0xA0800000
+
+zreladdr-$(CONFIG_ARCH_MX3)	:= 0x80008000
+params_phys-$(CONFIG_ARCH_MX3)	:= 0x80000100
+initrd_phys-$(CONFIG_ARCH_MX3)	:= 0x80800000
diff -druN linux-2.6.39-libre/arch/arm/mach-imx/mm-imx31.c linux-3.0-rc7-libre/arch/arm/mach-imx/mm-imx31.c
--- linux-2.6.39-libre/arch/arm/mach-imx/mm-imx31.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/arm/mach-imx/mm-imx31.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,66 @@
+/*
+ *  Copyright (C) 1999,2000 Arm Limited
+ *  Copyright (C) 2000 Deep Blue Solutions Ltd
+ *  Copyright (C) 2002 Shane Nay (shane@minirl.com)
+ *  Copyright 2005-2007 Freescale Semiconductor, Inc. All Rights Reserved.
+ *    - add MX31 specific definitions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/mm.h>
+#include <linux/init.h>
+#include <linux/err.h>
+
+#include <asm/pgtable.h>
+#include <asm/mach/map.h>
+
+#include <mach/common.h>
+#include <mach/hardware.h>
+#include <mach/iomux-v3.h>
+#include <mach/gpio.h>
+#include <mach/irqs.h>
+
+static struct map_desc mx31_io_desc[] __initdata = {
+	imx_map_entry(MX31, X_MEMC, MT_DEVICE),
+	imx_map_entry(MX31, AVIC, MT_DEVICE_NONSHARED),
+	imx_map_entry(MX31, AIPS1, MT_DEVICE_NONSHARED),
+	imx_map_entry(MX31, AIPS2, MT_DEVICE_NONSHARED),
+	imx_map_entry(MX31, SPBA0, MT_DEVICE_NONSHARED),
+};
+
+/*
+ * 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 mx31_map_io(void)
+{
+	iotable_init(mx31_io_desc, ARRAY_SIZE(mx31_io_desc));
+}
+
+void __init imx31_init_early(void)
+{
+	mxc_set_cpu_type(MXC_CPU_MX31);
+	mxc_arch_reset_init(MX31_IO_ADDRESS(MX31_WDOG_BASE_ADDR));
+}
+
+static struct mxc_gpio_port imx31_gpio_ports[] = {
+	DEFINE_IMX_GPIO_PORT_IRQ(MX31, 0, 1, MX31_INT_GPIO1),
+	DEFINE_IMX_GPIO_PORT_IRQ(MX31, 1, 2, MX31_INT_GPIO2),
+	DEFINE_IMX_GPIO_PORT_IRQ(MX31, 2, 3, MX31_INT_GPIO3),
+};
+
+void __init mx31_init_irq(void)
+{
+	mxc_init_irq(MX31_IO_ADDRESS(MX31_AVIC_BASE_ADDR));
+	mxc_gpio_init(imx31_gpio_ports,	ARRAY_SIZE(imx31_gpio_ports));
+}
diff -druN linux-2.6.39-libre/arch/arm/mach-imx/mm-imx35.c linux-3.0-rc7-libre/arch/arm/mach-imx/mm-imx35.c
--- linux-2.6.39-libre/arch/arm/mach-imx/mm-imx35.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/arm/mach-imx/mm-imx35.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,63 @@
+/*
+ *  Copyright (C) 1999,2000 Arm Limited
+ *  Copyright (C) 2000 Deep Blue Solutions Ltd
+ *  Copyright (C) 2002 Shane Nay (shane@minirl.com)
+ *  Copyright 2005-2007 Freescale Semiconductor, Inc. All Rights Reserved.
+ *    - add MX31 specific definitions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/mm.h>
+#include <linux/init.h>
+#include <linux/err.h>
+
+#include <asm/pgtable.h>
+#include <asm/mach/map.h>
+#include <asm/hardware/cache-l2x0.h>
+
+#include <mach/common.h>
+#include <mach/hardware.h>
+#include <mach/iomux-v3.h>
+#include <mach/gpio.h>
+#include <mach/irqs.h>
+
+static struct map_desc mx35_io_desc[] __initdata = {
+	imx_map_entry(MX35, X_MEMC, MT_DEVICE),
+	imx_map_entry(MX35, AVIC, MT_DEVICE_NONSHARED),
+	imx_map_entry(MX35, AIPS1, MT_DEVICE_NONSHARED),
+	imx_map_entry(MX35, AIPS2, MT_DEVICE_NONSHARED),
+	imx_map_entry(MX35, SPBA0, MT_DEVICE_NONSHARED),
+};
+
+void __init mx35_map_io(void)
+{
+	iotable_init(mx35_io_desc, ARRAY_SIZE(mx35_io_desc));
+}
+
+void __init imx35_init_early(void)
+{
+	mxc_set_cpu_type(MXC_CPU_MX35);
+	mxc_iomux_v3_init(MX35_IO_ADDRESS(MX35_IOMUXC_BASE_ADDR));
+	mxc_arch_reset_init(MX35_IO_ADDRESS(MX35_WDOG_BASE_ADDR));
+}
+
+static struct mxc_gpio_port imx35_gpio_ports[] = {
+	DEFINE_IMX_GPIO_PORT_IRQ(MX35, 0, 1, MX35_INT_GPIO1),
+	DEFINE_IMX_GPIO_PORT_IRQ(MX35, 1, 2, MX35_INT_GPIO2),
+	DEFINE_IMX_GPIO_PORT_IRQ(MX35, 2, 3, MX35_INT_GPIO3),
+};
+
+void __init mx35_init_irq(void)
+{
+	mxc_init_irq(MX35_IO_ADDRESS(MX35_AVIC_BASE_ADDR));
+	mxc_gpio_init(imx35_gpio_ports,	ARRAY_SIZE(imx35_gpio_ports));
+}
diff -druN linux-2.6.39-libre/arch/arm/mach-imx/mx31lilly-db.c linux-3.0-rc7-libre/arch/arm/mach-imx/mx31lilly-db.c
--- linux-2.6.39-libre/arch/arm/mach-imx/mx31lilly-db.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/arm/mach-imx/mx31lilly-db.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,216 @@
+/*
+ *  LILLY-1131 development board support
+ *
+ *    Copyright (c) 2009 Daniel Mack <daniel@caiaq.de>
+ *
+ *  based on code for other MX31 boards,
+ *
+ *    Copyright 2005-2007 Freescale Semiconductor
+ *    Copyright (c) 2009 Alberto Panizzo <maramaopercheseimorto@gmail.com>
+ *    Copyright (C) 2009 Valentin Longchamp, EPFL Mobots group
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/gpio.h>
+#include <linux/platform_device.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include <mach/hardware.h>
+#include <mach/common.h>
+#include <mach/iomux-mx3.h>
+#include <mach/board-mx31lilly.h>
+
+#include "devices-imx31.h"
+
+/*
+ * This file contains board-specific initialization routines for the
+ * LILLY-1131 development board. If you design an own baseboard for the
+ * module, use this file as base for support code.
+ */
+
+static unsigned int lilly_db_board_pins[] __initdata = {
+	MX31_PIN_CTS1__CTS1,
+	MX31_PIN_RTS1__RTS1,
+	MX31_PIN_TXD1__TXD1,
+	MX31_PIN_RXD1__RXD1,
+	MX31_PIN_CTS2__CTS2,
+	MX31_PIN_RTS2__RTS2,
+	MX31_PIN_TXD2__TXD2,
+	MX31_PIN_RXD2__RXD2,
+	MX31_PIN_CSPI3_MOSI__RXD3,
+	MX31_PIN_CSPI3_MISO__TXD3,
+	MX31_PIN_CSPI3_SCLK__RTS3,
+	MX31_PIN_CSPI3_SPI_RDY__CTS3,
+	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_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_CONTRAST__CONTRAST,
+};
+
+/* UART */
+static const struct imxuart_platform_data uart_pdata __initconst = {
+	.flags = IMXUART_HAVE_RTSCTS,
+};
+
+/* MMC support */
+
+static int mxc_mmc1_get_ro(struct device *dev)
+{
+	return gpio_get_value(IOMUX_TO_GPIO(MX31_PIN_LCS0));
+}
+
+static int gpio_det, gpio_wp;
+
+#define MMC_PAD_CFG (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST | PAD_CTL_HYS_CMOS | \
+			PAD_CTL_ODE_CMOS | PAD_CTL_100K_PU)
+
+static int mxc_mmc1_init(struct device *dev,
+			 irq_handler_t detect_irq, void *data)
+{
+	int ret;
+
+	gpio_det = IOMUX_TO_GPIO(MX31_PIN_GPIO1_1);
+	gpio_wp = IOMUX_TO_GPIO(MX31_PIN_LCS0);
+
+	mxc_iomux_set_pad(MX31_PIN_SD1_DATA0, MMC_PAD_CFG);
+	mxc_iomux_set_pad(MX31_PIN_SD1_DATA1, MMC_PAD_CFG);
+	mxc_iomux_set_pad(MX31_PIN_SD1_DATA2, MMC_PAD_CFG);
+	mxc_iomux_set_pad(MX31_PIN_SD1_DATA3, MMC_PAD_CFG);
+	mxc_iomux_set_pad(MX31_PIN_SD1_CLK, MMC_PAD_CFG);
+	mxc_iomux_set_pad(MX31_PIN_SD1_CMD, MMC_PAD_CFG);
+
+	ret = gpio_request(gpio_det, "MMC detect");
+	if (ret)
+		return ret;
+
+	ret = gpio_request(gpio_wp, "MMC w/p");
+	if (ret)
+		goto exit_free_det;
+
+	gpio_direction_input(gpio_det);
+	gpio_direction_input(gpio_wp);
+
+	ret = request_irq(IOMUX_TO_IRQ(MX31_PIN_GPIO1_1), detect_irq,
+			  IRQF_DISABLED | IRQF_TRIGGER_FALLING,
+			  "MMC detect", data);
+	if (ret)
+		goto exit_free_wp;
+
+	return 0;
+
+exit_free_wp:
+	gpio_free(gpio_wp);
+
+exit_free_det:
+	gpio_free(gpio_det);
+
+	return ret;
+}
+
+static void mxc_mmc1_exit(struct device *dev, void *data)
+{
+	gpio_free(gpio_det);
+	gpio_free(gpio_wp);
+	free_irq(IOMUX_TO_IRQ(MX31_PIN_GPIO1_1), data);
+}
+
+static const struct imxmmc_platform_data mmc_pdata __initconst = {
+	.get_ro	= mxc_mmc1_get_ro,
+	.init	= mxc_mmc1_init,
+	.exit	= mxc_mmc1_exit,
+};
+
+/* Framebuffer support */
+static const struct ipu_platform_data ipu_data __initconst = {
+	.irq_base = MXC_IPU_IRQ_START,
+};
+
+static const struct fb_videomode fb_modedb = {
+	/* 640x480 TFT panel (IPS-056T) */
+	.name		= "CRT-VGA",
+	.refresh	= 64,
+	.xres		= 640,
+	.yres		= 480,
+	.pixclock	= 30000,
+	.left_margin	= 200,
+	.right_margin	= 2,
+	.upper_margin	= 2,
+	.lower_margin	= 2,
+	.hsync_len	= 3,
+	.vsync_len	= 1,
+	.sync		= FB_SYNC_VERT_HIGH_ACT | FB_SYNC_OE_ACT_HIGH,
+	.vmode		= FB_VMODE_NONINTERLACED,
+	.flag		= 0,
+};
+
+static struct mx3fb_platform_data fb_pdata __initdata = {
+	.name		= "CRT-VGA",
+	.mode		= &fb_modedb,
+	.num_modes	= 1,
+};
+
+#define LCD_VCC_EN_GPIO	 (7)
+
+static void __init mx31lilly_init_fb(void)
+{
+	if (gpio_request(LCD_VCC_EN_GPIO, "LCD enable") != 0) {
+		printk(KERN_WARNING "unable to request LCD_VCC_EN pin.\n");
+		return;
+	}
+
+	imx31_add_ipu_core(&ipu_data);
+	imx31_add_mx3_sdc_fb(&fb_pdata);
+	gpio_direction_output(LCD_VCC_EN_GPIO, 1);
+}
+
+void __init mx31lilly_db_init(void)
+{
+	mxc_iomux_setup_multiple_pins(lilly_db_board_pins,
+					ARRAY_SIZE(lilly_db_board_pins),
+					"development board pins");
+	imx31_add_imx_uart0(&uart_pdata);
+	imx31_add_imx_uart1(&uart_pdata);
+	imx31_add_imx_uart2(&uart_pdata);
+	imx31_add_mxc_mmc(0, &mmc_pdata);
+	mx31lilly_init_fb();
+}
diff -druN linux-2.6.39-libre/arch/arm/mach-imx/mx31lite-db.c linux-3.0-rc7-libre/arch/arm/mach-imx/mx31lite-db.c
--- linux-2.6.39-libre/arch/arm/mach-imx/mx31lite-db.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/arm/mach-imx/mx31lite-db.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,203 @@
+/*
+ *  LogicPD i.MX31 SOM-LV development board support
+ *
+ *    Copyright (c) 2009 Daniel Mack <daniel@caiaq.de>
+ *
+ *  based on code for other MX31 boards,
+ *
+ *    Copyright 2005-2007 Freescale Semiconductor
+ *    Copyright (c) 2009 Alberto Panizzo <maramaopercheseimorto@gmail.com>
+ *    Copyright (C) 2009 Valentin Longchamp, EPFL Mobots group
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/gpio.h>
+#include <linux/leds.h>
+#include <linux/platform_device.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+
+#include <mach/hardware.h>
+#include <mach/common.h>
+#include <mach/iomux-mx3.h>
+#include <mach/board-mx31lite.h>
+
+#include "devices-imx31.h"
+
+/*
+ * This file contains board-specific initialization routines for the
+ * LogicPD i.MX31 SOM-LV development board, aka 'LiteKit'.
+ * If you design an own baseboard for the module, use this file as base
+ * for support code.
+ */
+
+static unsigned int litekit_db_board_pins[] __initdata = {
+	/* UART1 */
+	MX31_PIN_CTS1__CTS1,
+	MX31_PIN_RTS1__RTS1,
+	MX31_PIN_TXD1__TXD1,
+	MX31_PIN_RXD1__RXD1,
+	/* SPI 0 */
+	MX31_PIN_CSPI1_SCLK__SCLK,
+	MX31_PIN_CSPI1_MOSI__MOSI,
+	MX31_PIN_CSPI1_MISO__MISO,
+	MX31_PIN_CSPI1_SPI_RDY__SPI_RDY,
+	MX31_PIN_CSPI1_SS0__SS0,
+	MX31_PIN_CSPI1_SS1__SS1,
+	MX31_PIN_CSPI1_SS2__SS2,
+	/* 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 */
+static const struct imxuart_platform_data uart_pdata __initconst = {
+	.flags = IMXUART_HAVE_RTSCTS,
+};
+
+/* MMC */
+
+static int gpio_det, gpio_wp;
+
+#define MMC_PAD_CFG (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST | PAD_CTL_HYS_CMOS | \
+		     PAD_CTL_ODE_CMOS)
+
+static int mxc_mmc1_get_ro(struct device *dev)
+{
+	return gpio_get_value(IOMUX_TO_GPIO(MX31_PIN_GPIO1_6));
+}
+
+static int mxc_mmc1_init(struct device *dev,
+			 irq_handler_t detect_irq, void *data)
+{
+	int ret;
+
+	gpio_det = IOMUX_TO_GPIO(MX31_PIN_DCD_DCE1);
+	gpio_wp = IOMUX_TO_GPIO(MX31_PIN_GPIO1_6);
+
+	mxc_iomux_set_pad(MX31_PIN_SD1_DATA0,
+			  MMC_PAD_CFG | 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);
+
+	ret = gpio_request(gpio_det, "MMC detect");
+	if (ret)
+		return ret;
+
+	ret = gpio_request(gpio_wp, "MMC w/p");
+	if (ret)
+		goto exit_free_det;
+
+	gpio_direction_input(gpio_det);
+	gpio_direction_input(gpio_wp);
+
+	ret = request_irq(IOMUX_TO_IRQ(MX31_PIN_DCD_DCE1), detect_irq,
+			  IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
+			  "MMC detect", data);
+	if (ret)
+		goto exit_free_wp;
+
+	return 0;
+
+exit_free_wp:
+	gpio_free(gpio_wp);
+
+exit_free_det:
+	gpio_free(gpio_det);
+
+	return ret;
+}
+
+static void mxc_mmc1_exit(struct device *dev, void *data)
+{
+	gpio_free(gpio_det);
+	gpio_free(gpio_wp);
+	free_irq(IOMUX_TO_IRQ(MX31_PIN_DCD_DCE1), data);
+}
+
+static const struct imxmmc_platform_data mmc_pdata __initconst = {
+	.get_ro	 = mxc_mmc1_get_ro,
+	.init	   = mxc_mmc1_init,
+	.exit	   = mxc_mmc1_exit,
+};
+
+/* SPI */
+
+static int spi_internal_chipselect[] = {
+	MXC_SPI_CS(0),
+	MXC_SPI_CS(1),
+	MXC_SPI_CS(2),
+};
+
+static const struct spi_imx_master spi0_pdata __initconst = {
+	.chipselect	= spi_internal_chipselect,
+	.num_chipselect	= ARRAY_SIZE(spi_internal_chipselect),
+};
+
+/* GPIO LEDs */
+
+static struct gpio_led litekit_leds[] = {
+	{
+		.name           = "GPIO0",
+		.gpio           = IOMUX_TO_GPIO(MX31_PIN_COMPARE),
+		.active_low     = 1,
+		.default_state  = LEDS_GPIO_DEFSTATE_OFF,
+	},
+	{
+		.name           = "GPIO1",
+		.gpio           = IOMUX_TO_GPIO(MX31_PIN_CAPTURE),
+		.active_low     = 1,
+		.default_state  = LEDS_GPIO_DEFSTATE_OFF,
+	}
+};
+
+static struct gpio_led_platform_data litekit_led_platform_data = {
+	.leds           = litekit_leds,
+	.num_leds       = ARRAY_SIZE(litekit_leds),
+};
+
+static struct platform_device litekit_led_device = {
+	.name   = "leds-gpio",
+	.id     = -1,
+	.dev    = {
+		.platform_data = &litekit_led_platform_data,
+	},
+};
+
+void __init mx31lite_db_init(void)
+{
+	mxc_iomux_setup_multiple_pins(litekit_db_board_pins,
+					ARRAY_SIZE(litekit_db_board_pins),
+					"development board pins");
+	imx31_add_imx_uart0(&uart_pdata);
+	imx31_add_mxc_mmc(0, &mmc_pdata);
+	imx31_add_spi_imx0(&spi0_pdata);
+	platform_device_register(&litekit_led_device);
+	imx31_add_imx2_wdt(NULL);
+	imx31_add_mxc_rtc(NULL);
+}
diff -druN linux-2.6.39-libre/arch/arm/mach-imx/mx31moboard-devboard.c linux-3.0-rc7-libre/arch/arm/mach-imx/mx31moboard-devboard.c
--- linux-2.6.39-libre/arch/arm/mach-imx/mx31moboard-devboard.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/arm/mach-imx/mx31moboard-devboard.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,242 @@
+/*
+ * 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.
+ */
+
+#include <linux/gpio.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/types.h>
+
+#include <linux/usb/otg.h>
+
+#include <mach/common.h>
+#include <mach/iomux-mx3.h>
+#include <mach/hardware.h>
+#include <mach/ulpi.h>
+
+#include "devices-imx31.h"
+
+static unsigned int devboard_pins[] = {
+	/* UART1 */
+	MX31_PIN_CTS2__CTS2, MX31_PIN_RTS2__RTS2,
+	MX31_PIN_TXD2__TXD2, MX31_PIN_RXD2__RXD2,
+	/* SDHC2 */
+	MX31_PIN_PC_PWRON__SD2_DATA3, MX31_PIN_PC_VS1__SD2_DATA2,
+	MX31_PIN_PC_READY__SD2_DATA1, MX31_PIN_PC_WAIT_B__SD2_DATA0,
+	MX31_PIN_PC_CD2_B__SD2_CLK, MX31_PIN_PC_CD1_B__SD2_CMD,
+	MX31_PIN_ATA_DIOR__GPIO3_28, MX31_PIN_ATA_DIOW__GPIO3_29,
+	/* USB H1 */
+	MX31_PIN_CSPI1_MISO__USBH1_RXDP, MX31_PIN_CSPI1_MOSI__USBH1_RXDM,
+	MX31_PIN_CSPI1_SS0__USBH1_TXDM, MX31_PIN_CSPI1_SS1__USBH1_TXDP,
+	MX31_PIN_CSPI1_SS2__USBH1_RCV, MX31_PIN_CSPI1_SCLK__USBH1_OEB,
+	MX31_PIN_CSPI1_SPI_RDY__USBH1_FS, MX31_PIN_SFS6__USBH1_SUSPEND,
+	MX31_PIN_NFRE_B__GPIO1_11, MX31_PIN_NFALE__GPIO1_12,
+	/* 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 const struct imxuart_platform_data uart_pdata __initconst = {
+	.flags = IMXUART_HAVE_RTSCTS,
+};
+
+#define SDHC2_CD IOMUX_TO_GPIO(MX31_PIN_ATA_DIOR)
+#define SDHC2_WP IOMUX_TO_GPIO(MX31_PIN_ATA_DIOW)
+
+static int devboard_sdhc2_get_ro(struct device *dev)
+{
+	return !gpio_get_value(SDHC2_WP);
+}
+
+static int devboard_sdhc2_init(struct device *dev, irq_handler_t detect_irq,
+		void *data)
+{
+	int ret;
+
+	ret = gpio_request(SDHC2_CD, "sdhc-detect");
+	if (ret)
+		return ret;
+
+	gpio_direction_input(SDHC2_CD);
+
+	ret = gpio_request(SDHC2_WP, "sdhc-wp");
+	if (ret)
+		goto err_gpio_free;
+	gpio_direction_input(SDHC2_WP);
+
+	ret = request_irq(gpio_to_irq(SDHC2_CD), detect_irq,
+		IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
+		"sdhc2-card-detect", data);
+	if (ret)
+		goto err_gpio_free_2;
+
+	return 0;
+
+err_gpio_free_2:
+	gpio_free(SDHC2_WP);
+err_gpio_free:
+	gpio_free(SDHC2_CD);
+
+	return ret;
+}
+
+static void devboard_sdhc2_exit(struct device *dev, void *data)
+{
+	free_irq(gpio_to_irq(SDHC2_CD), data);
+	gpio_free(SDHC2_WP);
+	gpio_free(SDHC2_CD);
+}
+
+static const struct imxmmc_platform_data sdhc2_pdata __initconst = {
+	.get_ro	= devboard_sdhc2_get_ro,
+	.init	= devboard_sdhc2_init,
+	.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)
+
+static int devboard_usbh1_hw_init(struct platform_device *pdev)
+{
+	mxc_iomux_set_gpr(MUX_PGP_USB_SUSPEND, true);
+
+	mxc_iomux_set_pad(MX31_PIN_CSPI1_MISO, USB_PAD_CFG);
+	mxc_iomux_set_pad(MX31_PIN_CSPI1_MOSI, USB_PAD_CFG);
+	mxc_iomux_set_pad(MX31_PIN_CSPI1_SS0, USB_PAD_CFG);
+	mxc_iomux_set_pad(MX31_PIN_CSPI1_SS1, USB_PAD_CFG);
+	mxc_iomux_set_pad(MX31_PIN_CSPI1_SS2, USB_PAD_CFG);
+	mxc_iomux_set_pad(MX31_PIN_CSPI1_SCLK, USB_PAD_CFG);
+	mxc_iomux_set_pad(MX31_PIN_CSPI1_SPI_RDY, USB_PAD_CFG);
+	mxc_iomux_set_pad(MX31_PIN_SFS6, USB_PAD_CFG);
+
+	mdelay(10);
+
+	return mx31_initialize_usb_hw(pdev->id, MXC_EHCI_POWER_PINS_ENABLED |
+			MXC_EHCI_INTERFACE_SINGLE_UNI);
+}
+
+#define USBH1_VBUSEN_B	IOMUX_TO_GPIO(MX31_PIN_NFRE_B)
+#define USBH1_MODE	IOMUX_TO_GPIO(MX31_PIN_NFALE)
+
+static int devboard_isp1105_init(struct otg_transceiver *otg)
+{
+	int ret = gpio_request(USBH1_MODE, "usbh1-mode");
+	if (ret)
+		return ret;
+	/* single ended */
+	gpio_direction_output(USBH1_MODE, 0);
+
+	ret = gpio_request(USBH1_VBUSEN_B, "usbh1-vbusen");
+	if (ret) {
+		gpio_free(USBH1_MODE);
+		return ret;
+	}
+	gpio_direction_output(USBH1_VBUSEN_B, 1);
+
+	return 0;
+}
+
+
+static int devboard_isp1105_set_vbus(struct otg_transceiver *otg, bool on)
+{
+	if (on)
+		gpio_set_value(USBH1_VBUSEN_B, 0);
+	else
+		gpio_set_value(USBH1_VBUSEN_B, 1);
+
+	return 0;
+}
+
+static struct mxc_usbh_platform_data usbh1_pdata __initdata = {
+	.init	= devboard_usbh1_hw_init,
+	.portsc	= MXC_EHCI_MODE_UTMI | MXC_EHCI_SERIAL,
+};
+
+static int __init devboard_usbh1_init(void)
+{
+	struct otg_transceiver *otg;
+	struct platform_device *pdev;
+
+	otg = kzalloc(sizeof(*otg), GFP_KERNEL);
+	if (!otg)
+		return -ENOMEM;
+
+	otg->label	= "ISP1105";
+	otg->init	= devboard_isp1105_init;
+	otg->set_vbus	= devboard_isp1105_set_vbus;
+
+	usbh1_pdata.otg = otg;
+
+	pdev = imx31_add_mxc_ehci_hs(1, &usbh1_pdata);
+	if (IS_ERR(pdev))
+		return PTR_ERR(pdev);
+
+	return 0;
+}
+
+
+static const struct fsl_usb2_platform_data usb_pdata __initconst = {
+	.operating_mode	= FSL_USB2_DR_DEVICE,
+	.phy_mode	= FSL_USB2_PHY_ULPI,
+};
+
+/*
+ * system init for baseboard usage. Will be called by mx31moboard init.
+ */
+void __init mx31moboard_devboard_init(void)
+{
+	printk(KERN_INFO "Initializing mx31devboard peripherals\n");
+
+	mxc_iomux_setup_multiple_pins(devboard_pins, ARRAY_SIZE(devboard_pins),
+		"devboard");
+
+	imx31_add_imx_uart1(&uart_pdata);
+
+	imx31_add_mxc_mmc(1, &sdhc2_pdata);
+
+	devboard_init_sel_gpios();
+
+	imx31_add_fsl_usb2_udc(&usb_pdata);
+
+	devboard_usbh1_init();
+}
diff -druN linux-2.6.39-libre/arch/arm/mach-imx/mx31moboard-marxbot.c linux-3.0-rc7-libre/arch/arm/mach-imx/mx31moboard-marxbot.c
--- linux-2.6.39-libre/arch/arm/mach-imx/mx31moboard-marxbot.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/arm/mach-imx/mx31moboard-marxbot.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,366 @@
+/*
+ * 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.
+ */
+
+#include <linux/delay.h>
+#include <linux/gpio.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/i2c.h>
+#include <linux/spi/spi.h>
+#include <linux/slab.h>
+#include <linux/platform_device.h>
+#include <linux/types.h>
+
+#include <linux/usb/otg.h>
+
+#include <mach/common.h>
+#include <mach/hardware.h>
+#include <mach/iomux-mx3.h>
+#include <mach/ulpi.h>
+
+#include <media/soc_camera.h>
+
+#include "devices-imx31.h"
+
+static unsigned int marxbot_pins[] = {
+	/* SDHC2 */
+	MX31_PIN_PC_PWRON__SD2_DATA3, MX31_PIN_PC_VS1__SD2_DATA2,
+	MX31_PIN_PC_READY__SD2_DATA1, MX31_PIN_PC_WAIT_B__SD2_DATA0,
+	MX31_PIN_PC_CD2_B__SD2_CLK, MX31_PIN_PC_CD1_B__SD2_CMD,
+	MX31_PIN_ATA_DIOR__GPIO3_28, MX31_PIN_ATA_DIOW__GPIO3_29,
+	/* CSI */
+	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_CSI_D4__GPIO3_4, MX31_PIN_CSI_D5__GPIO3_5,
+	MX31_PIN_GPIO3_0__GPIO3_0, MX31_PIN_GPIO3_1__GPIO3_1,
+	MX31_PIN_TXD2__GPIO1_28,
+	/* dsPIC resets */
+	MX31_PIN_STXD5__GPIO1_21, MX31_PIN_SRXD5__GPIO1_22,
+	/*battery detection */
+	MX31_PIN_LCS0__GPIO3_23,
+	/* USB H1 */
+	MX31_PIN_CSPI1_MISO__USBH1_RXDP, MX31_PIN_CSPI1_MOSI__USBH1_RXDM,
+	MX31_PIN_CSPI1_SS0__USBH1_TXDM, MX31_PIN_CSPI1_SS1__USBH1_TXDP,
+	MX31_PIN_CSPI1_SS2__USBH1_RCV, MX31_PIN_CSPI1_SCLK__USBH1_OEB,
+	MX31_PIN_CSPI1_SPI_RDY__USBH1_FS, MX31_PIN_SFS6__USBH1_SUSPEND,
+	MX31_PIN_NFRE_B__GPIO1_11, MX31_PIN_NFALE__GPIO1_12,
+	/* 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)
+#define SDHC2_WP IOMUX_TO_GPIO(MX31_PIN_ATA_DIOW)
+
+static int marxbot_sdhc2_get_ro(struct device *dev)
+{
+	return !gpio_get_value(SDHC2_WP);
+}
+
+static int marxbot_sdhc2_init(struct device *dev, irq_handler_t detect_irq,
+		void *data)
+{
+	int ret;
+
+	ret = gpio_request(SDHC2_CD, "sdhc-detect");
+	if (ret)
+		return ret;
+
+	gpio_direction_input(SDHC2_CD);
+
+	ret = gpio_request(SDHC2_WP, "sdhc-wp");
+	if (ret)
+		goto err_gpio_free;
+	gpio_direction_input(SDHC2_WP);
+
+	ret = request_irq(gpio_to_irq(SDHC2_CD), detect_irq,
+		IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
+		"sdhc2-card-detect", data);
+	if (ret)
+		goto err_gpio_free_2;
+
+	return 0;
+
+err_gpio_free_2:
+	gpio_free(SDHC2_WP);
+err_gpio_free:
+	gpio_free(SDHC2_CD);
+
+	return ret;
+}
+
+static void marxbot_sdhc2_exit(struct device *dev, void *data)
+{
+	free_irq(gpio_to_irq(SDHC2_CD), data);
+	gpio_free(SDHC2_WP);
+	gpio_free(SDHC2_CD);
+}
+
+static const struct imxmmc_platform_data sdhc2_pdata __initconst = {
+	.get_ro	= marxbot_sdhc2_get_ro,
+	.init	= marxbot_sdhc2_init,
+	.exit	= marxbot_sdhc2_exit,
+};
+
+#define TRSLAT_RST_B	IOMUX_TO_GPIO(MX31_PIN_STXD5)
+#define DSPICS_RST_B	IOMUX_TO_GPIO(MX31_PIN_SRXD5)
+
+static void dspics_resets_init(void)
+{
+	if (!gpio_request(TRSLAT_RST_B, "translator-rst")) {
+		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, 0);
+		gpio_export(DSPICS_RST_B, false);
+	}
+}
+
+static struct spi_board_info marxbot_spi_board_info[] __initdata = {
+	{
+		.modalias = "spidev",
+		.max_speed_hz = 300000,
+		.bus_num = 1,
+		.chip_select = 1, /* according spi1_cs[] ! */
+	},
+};
+
+#define TURRETCAM_POWER	IOMUX_TO_GPIO(MX31_PIN_GPIO3_1)
+#define BASECAM_POWER	IOMUX_TO_GPIO(MX31_PIN_CSI_D5)
+#define TURRETCAM_RST_B	IOMUX_TO_GPIO(MX31_PIN_GPIO3_0)
+#define BASECAM_RST_B	IOMUX_TO_GPIO(MX31_PIN_CSI_D4)
+#define CAM_CHOICE	IOMUX_TO_GPIO(MX31_PIN_TXD2)
+
+static int marxbot_basecam_power(struct device *dev, int on)
+{
+	gpio_set_value(BASECAM_POWER, !on);
+	return 0;
+}
+
+static int marxbot_basecam_reset(struct device *dev)
+{
+	gpio_set_value(BASECAM_RST_B, 0);
+	udelay(100);
+	gpio_set_value(BASECAM_RST_B, 1);
+	return 0;
+}
+
+static struct i2c_board_info marxbot_i2c_devices[] = {
+	{
+		I2C_BOARD_INFO("mt9t031", 0x5d),
+	},
+};
+
+static struct soc_camera_link base_iclink = {
+	.bus_id		= 0,		/* Must match with the camera ID */
+	.power		= marxbot_basecam_power,
+	.reset		= marxbot_basecam_reset,
+	.board_info	= &marxbot_i2c_devices[0],
+	.i2c_adapter_id	= 0,
+};
+
+static struct platform_device marxbot_camera[] = {
+	{
+		.name	= "soc-camera-pdrv",
+		.id	= 0,
+		.dev	= {
+			.platform_data = &base_iclink,
+		},
+	},
+};
+
+static struct platform_device *marxbot_cameras[] __initdata = {
+	&marxbot_camera[0],
+};
+
+static int __init marxbot_cam_init(void)
+{
+	int ret = gpio_request(CAM_CHOICE, "cam-choice");
+	if (ret)
+		return ret;
+	gpio_direction_output(CAM_CHOICE, 0);
+
+	ret = gpio_request(BASECAM_RST_B, "basecam-reset");
+	if (ret)
+		return ret;
+	gpio_direction_output(BASECAM_RST_B, 1);
+	ret = gpio_request(BASECAM_POWER, "basecam-standby");
+	if (ret)
+		return ret;
+	gpio_direction_output(BASECAM_POWER, 0);
+
+	ret = gpio_request(TURRETCAM_RST_B, "turretcam-reset");
+	if (ret)
+		return ret;
+	gpio_direction_output(TURRETCAM_RST_B, 1);
+	ret = gpio_request(TURRETCAM_POWER, "turretcam-standby");
+	if (ret)
+		return ret;
+	gpio_direction_output(TURRETCAM_POWER, 0);
+
+	return 0;
+}
+
+#define 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)
+
+static int marxbot_usbh1_hw_init(struct platform_device *pdev)
+{
+	mxc_iomux_set_gpr(MUX_PGP_USB_SUSPEND, true);
+
+	mxc_iomux_set_pad(MX31_PIN_CSPI1_MISO, USB_PAD_CFG);
+	mxc_iomux_set_pad(MX31_PIN_CSPI1_MOSI, USB_PAD_CFG);
+	mxc_iomux_set_pad(MX31_PIN_CSPI1_SS0, USB_PAD_CFG);
+	mxc_iomux_set_pad(MX31_PIN_CSPI1_SS1, USB_PAD_CFG);
+	mxc_iomux_set_pad(MX31_PIN_CSPI1_SS2, USB_PAD_CFG);
+	mxc_iomux_set_pad(MX31_PIN_CSPI1_SCLK, USB_PAD_CFG);
+	mxc_iomux_set_pad(MX31_PIN_CSPI1_SPI_RDY, USB_PAD_CFG);
+	mxc_iomux_set_pad(MX31_PIN_SFS6, USB_PAD_CFG);
+
+	mdelay(10);
+
+	return mx31_initialize_usb_hw(pdev->id, MXC_EHCI_POWER_PINS_ENABLED |
+			MXC_EHCI_INTERFACE_SINGLE_UNI);
+}
+
+#define USBH1_VBUSEN_B	IOMUX_TO_GPIO(MX31_PIN_NFRE_B)
+#define USBH1_MODE	IOMUX_TO_GPIO(MX31_PIN_NFALE)
+
+static int marxbot_isp1105_init(struct otg_transceiver *otg)
+{
+	int ret = gpio_request(USBH1_MODE, "usbh1-mode");
+	if (ret)
+		return ret;
+	/* single ended */
+	gpio_direction_output(USBH1_MODE, 0);
+
+	ret = gpio_request(USBH1_VBUSEN_B, "usbh1-vbusen");
+	if (ret) {
+		gpio_free(USBH1_MODE);
+		return ret;
+	}
+	gpio_direction_output(USBH1_VBUSEN_B, 1);
+
+	return 0;
+}
+
+
+static int marxbot_isp1105_set_vbus(struct otg_transceiver *otg, bool on)
+{
+	if (on)
+		gpio_set_value(USBH1_VBUSEN_B, 0);
+	else
+		gpio_set_value(USBH1_VBUSEN_B, 1);
+
+	return 0;
+}
+
+static struct mxc_usbh_platform_data usbh1_pdata __initdata = {
+	.init	= marxbot_usbh1_hw_init,
+	.portsc	= MXC_EHCI_MODE_UTMI | MXC_EHCI_SERIAL,
+};
+
+static int __init marxbot_usbh1_init(void)
+{
+	struct otg_transceiver *otg;
+	struct platform_device *pdev;
+
+	otg = kzalloc(sizeof(*otg), GFP_KERNEL);
+	if (!otg)
+		return -ENOMEM;
+
+	otg->label	= "ISP1105";
+	otg->init	= marxbot_isp1105_init;
+	otg->set_vbus	= marxbot_isp1105_set_vbus;
+
+	usbh1_pdata.otg = otg;
+
+	pdev = imx31_add_mxc_ehci_hs(1, &usbh1_pdata);
+	if (IS_ERR(pdev))
+		return PTR_ERR(pdev);
+
+	return 0;
+}
+
+static const struct fsl_usb2_platform_data usb_pdata __initconst = {
+	.operating_mode	= FSL_USB2_DR_DEVICE,
+	.phy_mode	= FSL_USB2_PHY_ULPI,
+};
+
+/*
+ * system init for baseboard usage. Will be called by mx31moboard init.
+ */
+void __init mx31moboard_marxbot_init(void)
+{
+	printk(KERN_INFO "Initializing mx31marxbot peripherals\n");
+
+	mxc_iomux_setup_multiple_pins(marxbot_pins, ARRAY_SIZE(marxbot_pins),
+		"marxbot");
+
+	marxbot_init_sel_gpios();
+
+	dspics_resets_init();
+
+	imx31_add_mxc_mmc(1, &sdhc2_pdata);
+
+	spi_register_board_info(marxbot_spi_board_info,
+		ARRAY_SIZE(marxbot_spi_board_info));
+
+	marxbot_cam_init();
+	platform_add_devices(marxbot_cameras, ARRAY_SIZE(marxbot_cameras));
+
+	/* battery present pin */
+	gpio_request(IOMUX_TO_GPIO(MX31_PIN_LCS0), "bat-present");
+	gpio_direction_input(IOMUX_TO_GPIO(MX31_PIN_LCS0));
+	gpio_export(IOMUX_TO_GPIO(MX31_PIN_LCS0), false);
+
+	imx31_add_fsl_usb2_udc(&usb_pdata);
+
+	marxbot_usbh1_init();
+}
diff -druN linux-2.6.39-libre/arch/arm/mach-imx/mx31moboard-smartbot.c linux-3.0-rc7-libre/arch/arm/mach-imx/mx31moboard-smartbot.c
--- linux-2.6.39-libre/arch/arm/mach-imx/mx31moboard-smartbot.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/arm/mach-imx/mx31moboard-smartbot.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,209 @@
+/*
+ * 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.
+ */
+
+#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 <linux/usb/otg.h>
+#include <linux/usb/ulpi.h>
+
+#include <mach/common.h>
+#include <mach/hardware.h>
+#include <mach/iomux-mx3.h>
+#include <mach/board-mx31moboard.h>
+#include <mach/ulpi.h>
+
+#include <media/soc_camera.h>
+
+#include "devices-imx31.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 const struct imxuart_platform_data uart_pdata __initconst = {
+	.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,
+};
+
+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;
+}
+
+static const struct fsl_usb2_platform_data usb_pdata __initconst = {
+	.operating_mode	= FSL_USB2_DR_DEVICE,
+	.phy_mode	= FSL_USB2_PHY_ULPI,
+};
+
+#if defined(CONFIG_USB_ULPI)
+
+static int smartbot_otg_init(struct platform_device *pdev)
+{
+	return mx31_initialize_usb_hw(pdev->id, MXC_EHCI_POWER_PINS_ENABLED);
+}
+
+static struct mxc_usbh_platform_data otg_host_pdata __initdata = {
+	.init	= smartbot_otg_init,
+	.portsc = MXC_EHCI_MODE_ULPI | MXC_EHCI_UTMI_8BIT,
+};
+
+static int __init smartbot_otg_host_init(void)
+{
+	struct platform_device *pdev;
+
+	otg_host_pdata.otg = imx_otg_ulpi_create(ULPI_OTG_DRVVBUS |
+		ULPI_OTG_DRVVBUS_EXT);
+	if (!otg_host_pdata.otg)
+		return -ENODEV;
+
+	pdev = imx31_add_mxc_ehci_otg(&otg_host_pdata);
+	if (IS_ERR(pdev))
+		return PTR_ERR(pdev);
+
+	return 0;
+}
+#else
+static inline int smartbot_otg_host_init(void) { return 0; }
+#endif
+
+#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 TRSLAT_SRC_CHOICE 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(TRSLAT_SRC_CHOICE, "translator-src-choice")) {
+		gpio_direction_output(TRSLAT_SRC_CHOICE, 0);
+		gpio_export(TRSLAT_SRC_CHOICE, false);
+	}
+}
+/*
+ * system init for baseboard usage. Will be called by mx31moboard init.
+ */
+void __init mx31moboard_smartbot_init(int board)
+{
+	printk(KERN_INFO "Initializing mx31smartbot peripherals\n");
+
+	mxc_iomux_setup_multiple_pins(smartbot_pins, ARRAY_SIZE(smartbot_pins),
+		"smartbot");
+
+	imx31_add_imx_uart1(&uart_pdata);
+
+	switch (board) {
+	case MX31SMARTBOT:
+		imx31_add_fsl_usb2_udc(&usb_pdata);
+		break;
+	case MX31EYEBOT:
+		smartbot_otg_host_init();
+		break;
+	default:
+		printk(KERN_WARNING "Unknown board %d, USB OTG not initialized",
+			board);
+	}
+
+	smartbot_resets_init();
+
+	smartbot_cam_init();
+	platform_add_devices(smartbot_cameras, ARRAY_SIZE(smartbot_cameras));
+}
diff -druN linux-2.6.39-libre/arch/arm/mach-imx/pcm037.h linux-3.0-rc7-libre/arch/arm/mach-imx/pcm037.h
--- linux-2.6.39-libre/arch/arm/mach-imx/pcm037.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/arm/mach-imx/pcm037.h	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,11 @@
+#ifndef __PCM037_H__
+#define __PCM037_H__
+
+enum pcm037_board_variant {
+	PCM037_PCM970,
+	PCM037_EET,
+};
+
+extern enum pcm037_board_variant pcm037_variant(void);
+
+#endif
diff -druN linux-2.6.39-libre/arch/arm/mach-integrator/integrator_ap.c linux-3.0-rc7-libre/arch/arm/mach-integrator/integrator_ap.c
--- linux-2.6.39-libre/arch/arm/mach-integrator/integrator_ap.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-integrator/integrator_ap.c	2011-07-11 19:51:52.000000000 -0400
@@ -24,13 +24,14 @@
 #include <linux/platform_device.h>
 #include <linux/slab.h>
 #include <linux/string.h>
-#include <linux/sysdev.h>
+#include <linux/syscore_ops.h>
 #include <linux/amba/bus.h>
 #include <linux/amba/kmi.h>
 #include <linux/clocksource.h>
 #include <linux/clockchips.h>
 #include <linux/interrupt.h>
 #include <linux/io.h>
+#include <linux/mtd/physmap.h>
 
 #include <mach/hardware.h>
 #include <mach/platform.h>
@@ -43,7 +44,6 @@
 #include <mach/lm.h>
 
 #include <asm/mach/arch.h>
-#include <asm/mach/flash.h>
 #include <asm/mach/irq.h>
 #include <asm/mach/map.h>
 #include <asm/mach/time.h>
@@ -180,13 +180,13 @@
 #ifdef CONFIG_PM
 static unsigned long ic_irq_enable;
 
-static int irq_suspend(struct sys_device *dev, pm_message_t state)
+static int irq_suspend(void)
 {
 	ic_irq_enable = readl(VA_IC_BASE + IRQ_ENABLE);
 	return 0;
 }
 
-static int irq_resume(struct sys_device *dev)
+static void irq_resume(void)
 {
 	/* disable all irq sources */
 	writel(-1, VA_CMIC_BASE + IRQ_ENABLE_CLEAR);
@@ -194,33 +194,25 @@
 	writel(-1, VA_IC_BASE + FIQ_ENABLE_CLEAR);
 
 	writel(ic_irq_enable, VA_IC_BASE + IRQ_ENABLE_SET);
-	return 0;
 }
 #else
 #define irq_suspend NULL
 #define irq_resume NULL
 #endif
 
-static struct sysdev_class irq_class = {
-	.name		= "irq",
+static struct syscore_ops irq_syscore_ops = {
 	.suspend	= irq_suspend,
 	.resume		= irq_resume,
 };
 
-static struct sys_device irq_device = {
-	.id	= 0,
-	.cls	= &irq_class,
-};
-
-static int __init irq_init_sysfs(void)
+static int __init irq_syscore_init(void)
 {
-	int ret = sysdev_class_register(&irq_class);
-	if (ret == 0)
-		ret = sysdev_register(&irq_device);
-	return ret;
+	register_syscore_ops(&irq_syscore_ops);
+
+	return 0;
 }
 
-device_initcall(irq_init_sysfs);
+device_initcall(irq_syscore_init);
 
 /*
  * Flash handling.
@@ -230,7 +222,7 @@
 #define EBI_CSR1 (VA_EBI_BASE + INTEGRATOR_EBI_CSR1_OFFSET)
 #define EBI_LOCK (VA_EBI_BASE + INTEGRATOR_EBI_LOCK_OFFSET)
 
-static int ap_flash_init(void)
+static int ap_flash_init(struct platform_device *dev)
 {
 	u32 tmp;
 
@@ -247,7 +239,7 @@
 	return 0;
 }
 
-static void ap_flash_exit(void)
+static void ap_flash_exit(struct platform_device *dev)
 {
 	u32 tmp;
 
@@ -263,15 +255,14 @@
 	}
 }
 
-static void ap_flash_set_vpp(int on)
+static void ap_flash_set_vpp(struct platform_device *pdev, int on)
 {
 	void __iomem *reg = on ? SC_CTRLS : SC_CTRLC;
 
 	writel(INTEGRATOR_SC_CTRL_nFLVPPEN, reg);
 }
 
-static struct flash_platform_data ap_flash_data = {
-	.map_name	= "cfi_probe",
+static struct physmap_flash_data ap_flash_data = {
 	.width		= 4,
 	.init		= ap_flash_init,
 	.exit		= ap_flash_exit,
@@ -285,7 +276,7 @@
 };
 
 static struct platform_device cfi_flash_device = {
-	.name		= "armflash",
+	.name		= "physmap-flash",
 	.id		= 0,
 	.dev		= {
 		.platform_data	= &ap_flash_data,
@@ -343,25 +334,9 @@
 
 static unsigned long timer_reload;
 
-static void __iomem * const clksrc_base = (void __iomem *)TIMER2_VA_BASE;
-
-static cycle_t timersp_read(struct clocksource *cs)
-{
-	return ~(readl(clksrc_base + TIMER_VALUE) & 0xffff);
-}
-
-static struct clocksource clocksource_timersp = {
-	.name		= "timer2",
-	.rating		= 200,
-	.read		= timersp_read,
-	.mask		= CLOCKSOURCE_MASK(16),
-	.flags		= CLOCK_SOURCE_IS_CONTINUOUS,
-};
-
 static void integrator_clocksource_init(u32 khz)
 {
-	struct clocksource *cs = &clocksource_timersp;
-	void __iomem *base = clksrc_base;
+	void __iomem *base = (void __iomem *)TIMER2_VA_BASE;
 	u32 ctrl = TIMER_CTRL_ENABLE;
 
 	if (khz >= 1500) {
@@ -372,7 +347,8 @@
 	writel(ctrl, base + TIMER_CTRL);
 	writel(0xffff, base + TIMER_LOAD);
 
-	clocksource_register_khz(cs, khz);
+	clocksource_mmio_init(base + TIMER_VALUE, "timer2",
+		khz * 1000, 200, 16, clocksource_mmio_readl_down);
 }
 
 static void __iomem * const clkevt_base = (void __iomem *)TIMER1_VA_BASE;
diff -druN linux-2.6.39-libre/arch/arm/mach-integrator/integrator_cp.c linux-3.0-rc7-libre/arch/arm/mach-integrator/integrator_cp.c
--- linux-2.6.39-libre/arch/arm/mach-integrator/integrator_cp.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-integrator/integrator_cp.c	2011-07-11 19:51:52.000000000 -0400
@@ -22,6 +22,7 @@
 #include <linux/io.h>
 #include <linux/gfp.h>
 #include <linux/clkdev.h>
+#include <linux/mtd/physmap.h>
 
 #include <mach/hardware.h>
 #include <mach/platform.h>
@@ -35,7 +36,6 @@
 #include <mach/lm.h>
 
 #include <asm/mach/arch.h>
-#include <asm/mach/flash.h>
 #include <asm/mach/irq.h>
 #include <asm/mach/map.h>
 #include <asm/mach/time.h>
@@ -229,17 +229,24 @@
 	.vcoreg	= CM_AUXOSC,
 };
 
+static struct clk sp804_clk = {
+	.rate	= 1000000,
+};
+
 static struct clk_lookup cp_lookups[] = {
 	{	/* CLCD */
 		.dev_id		= "mb:c0",
 		.clk		= &cp_auxclk,
+	}, {	/* SP804 timers */
+		.dev_id		= "sp804",
+		.clk		= &sp804_clk,
 	},
 };
 
 /*
  * Flash handling.
  */
-static int intcp_flash_init(void)
+static int intcp_flash_init(struct platform_device *dev)
 {
 	u32 val;
 
@@ -250,7 +257,7 @@
 	return 0;
 }
 
-static void intcp_flash_exit(void)
+static void intcp_flash_exit(struct platform_device *dev)
 {
 	u32 val;
 
@@ -259,7 +266,7 @@
 	writel(val, INTCP_VA_CTRL_BASE + INTCP_FLASHPROG);
 }
 
-static void intcp_flash_set_vpp(int on)
+static void intcp_flash_set_vpp(struct platform_device *pdev, int on)
 {
 	u32 val;
 
@@ -271,8 +278,7 @@
 	writel(val, INTCP_VA_CTRL_BASE + INTCP_FLASHPROG);
 }
 
-static struct flash_platform_data intcp_flash_data = {
-	.map_name	= "cfi_probe",
+static struct physmap_flash_data intcp_flash_data = {
 	.width		= 4,
 	.init		= intcp_flash_init,
 	.exit		= intcp_flash_exit,
@@ -286,7 +292,7 @@
 };
 
 static struct platform_device intcp_flash_device = {
-	.name		= "armflash",
+	.name		= "physmap-flash",
 	.id		= 0,
 	.dev		= {
 		.platform_data	= &intcp_flash_data,
@@ -476,8 +482,8 @@
 	writel(0, TIMER1_VA_BASE + TIMER_CTRL);
 	writel(0, TIMER2_VA_BASE + TIMER_CTRL);
 
-	sp804_clocksource_init(TIMER2_VA_BASE);
-	sp804_clockevents_init(TIMER1_VA_BASE, IRQ_TIMERINT1);
+	sp804_clocksource_init(TIMER2_VA_BASE, "timer2");
+	sp804_clockevents_init(TIMER1_VA_BASE, IRQ_TIMERINT1, "timer1");
 }
 
 static struct sys_timer cp_timer = {
diff -druN linux-2.6.39-libre/arch/arm/mach-integrator/Kconfig linux-3.0-rc7-libre/arch/arm/mach-integrator/Kconfig
--- linux-2.6.39-libre/arch/arm/mach-integrator/Kconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-integrator/Kconfig	2011-07-11 19:51:52.000000000 -0400
@@ -4,6 +4,7 @@
 
 config ARCH_INTEGRATOR_AP
 	bool "Support Integrator/AP and Integrator/PP2 platforms"
+	select CLKSRC_MMIO
 	select MIGHT_HAVE_PCI
 	help
 	  Include support for the ARM(R) Integrator/AP and
diff -druN linux-2.6.39-libre/arch/arm/mach-iop32x/include/mach/uncompress.h linux-3.0-rc7-libre/arch/arm/mach-iop32x/include/mach/uncompress.h
--- linux-2.6.39-libre/arch/arm/mach-iop32x/include/mach/uncompress.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-iop32x/include/mach/uncompress.h	2011-07-11 19:51:52.000000000 -0400
@@ -7,7 +7,7 @@
 #include <linux/serial_reg.h>
 #include <mach/hardware.h>
 
-static volatile u8 *uart_base;
+volatile u8 *uart_base;
 
 #define TX_DONE		(UART_LSR_TEMT | UART_LSR_THRE)
 
diff -druN linux-2.6.39-libre/arch/arm/mach-iop33x/include/mach/uncompress.h linux-3.0-rc7-libre/arch/arm/mach-iop33x/include/mach/uncompress.h
--- linux-2.6.39-libre/arch/arm/mach-iop33x/include/mach/uncompress.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-iop33x/include/mach/uncompress.h	2011-07-11 19:51:52.000000000 -0400
@@ -7,7 +7,7 @@
 #include <linux/serial_reg.h>
 #include <mach/hardware.h>
 
-static volatile u32 *uart_base;
+volatile u32 *uart_base;
 
 #define TX_DONE		(UART_LSR_TEMT | UART_LSR_THRE)
 
diff -druN linux-2.6.39-libre/arch/arm/mach-ixp4xx/common.c linux-3.0-rc7-libre/arch/arm/mach-ixp4xx/common.c
--- linux-2.6.39-libre/arch/arm/mach-ixp4xx/common.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-ixp4xx/common.c	2011-07-11 19:51:52.000000000 -0400
@@ -419,26 +419,14 @@
 /*
  * clocksource
  */
-static cycle_t ixp4xx_get_cycles(struct clocksource *cs)
-{
-	return *IXP4XX_OSTS;
-}
-
-static struct clocksource clocksource_ixp4xx = {
-	.name 		= "OSTS",
-	.rating		= 200,
-	.read		= ixp4xx_get_cycles,
-	.mask		= CLOCKSOURCE_MASK(32),
-	.flags		= CLOCK_SOURCE_IS_CONTINUOUS,
-};
-
 unsigned long ixp4xx_timer_freq = IXP4XX_TIMER_FREQ;
 EXPORT_SYMBOL(ixp4xx_timer_freq);
 static void __init ixp4xx_clocksource_init(void)
 {
 	init_sched_clock(&cd, ixp4xx_update_sched_clock, 32, ixp4xx_timer_freq);
 
-	clocksource_register_hz(&clocksource_ixp4xx, ixp4xx_timer_freq);
+	clocksource_mmio_init(&IXP4XX_OSTS, "OSTS", ixp4xx_timer_freq, 200, 32,
+			clocksource_mmio_readl_up);
 }
 
 /*
diff -druN linux-2.6.39-libre/arch/arm/mach-ixp4xx/common-pci.c linux-3.0-rc7-libre/arch/arm/mach-ixp4xx/common-pci.c
--- linux-2.6.39-libre/arch/arm/mach-ixp4xx/common-pci.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-ixp4xx/common-pci.c	2011-07-11 19:51:52.000000000 -0400
@@ -342,29 +342,6 @@
 	return (dev->bus == &pci_bus_type ) && ((dma_addr + size) >= SZ_64M);
 }
 
-/*
- * Only first 64MB of memory can be accessed via PCI.
- * We use GFP_DMA to allocate safe buffers to do map/unmap.
- * This is really ugly and we need a better way of specifying
- * DMA-capable regions of memory.
- */
-void __init ixp4xx_adjust_zones(unsigned long *zone_size,
-	unsigned long *zhole_size)
-{
-	unsigned int sz = SZ_64M >> PAGE_SHIFT;
-
-	/*
-	 * Only adjust if > 64M on current system
-	 */
-	if (zone_size[0] <= sz)
-		return;
-
-	zone_size[1] = zone_size[0] - sz;
-	zone_size[0] = sz;
-	zhole_size[1] = zhole_size[0];
-	zhole_size[0] = 0;
-}
-
 void __init ixp4xx_pci_preinit(void)
 {
 	unsigned long cpuid = read_cpuid_id();
diff -druN linux-2.6.39-libre/arch/arm/mach-ixp4xx/include/mach/ixp46x_ts.h linux-3.0-rc7-libre/arch/arm/mach-ixp4xx/include/mach/ixp46x_ts.h
--- linux-2.6.39-libre/arch/arm/mach-ixp4xx/include/mach/ixp46x_ts.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/arm/mach-ixp4xx/include/mach/ixp46x_ts.h	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,78 @@
+/*
+ * PTP 1588 clock using the IXP46X
+ *
+ * Copyright (C) 2010 OMICRON electronics GmbH
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the 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 _IXP46X_TS_H_
+#define _IXP46X_TS_H_
+
+#define DEFAULT_ADDEND 0xF0000029
+#define TICKS_NS_SHIFT 4
+
+struct ixp46x_channel_ctl {
+	u32 ch_control;  /* 0x40 Time Synchronization Channel Control */
+	u32 ch_event;    /* 0x44 Time Synchronization Channel Event */
+	u32 tx_snap_lo;  /* 0x48 Transmit Snapshot Low Register */
+	u32 tx_snap_hi;  /* 0x4C Transmit Snapshot High Register */
+	u32 rx_snap_lo;  /* 0x50 Receive Snapshot Low Register */
+	u32 rx_snap_hi;  /* 0x54 Receive Snapshot High Register */
+	u32 src_uuid_lo; /* 0x58 Source UUID0 Low Register */
+	u32 src_uuid_hi; /* 0x5C Sequence Identifier/Source UUID0 High */
+};
+
+struct ixp46x_ts_regs {
+	u32 control;     /* 0x00 Time Sync Control Register */
+	u32 event;       /* 0x04 Time Sync Event Register */
+	u32 addend;      /* 0x08 Time Sync Addend Register */
+	u32 accum;       /* 0x0C Time Sync Accumulator Register */
+	u32 test;        /* 0x10 Time Sync Test Register */
+	u32 unused;      /* 0x14 */
+	u32 rsystime_lo; /* 0x18 RawSystemTime_Low Register */
+	u32 rsystime_hi; /* 0x1C RawSystemTime_High Register */
+	u32 systime_lo;  /* 0x20 SystemTime_Low Register */
+	u32 systime_hi;  /* 0x24 SystemTime_High Register */
+	u32 trgt_lo;     /* 0x28 TargetTime_Low Register */
+	u32 trgt_hi;     /* 0x2C TargetTime_High Register */
+	u32 asms_lo;     /* 0x30 Auxiliary Slave Mode Snapshot Low  */
+	u32 asms_hi;     /* 0x34 Auxiliary Slave Mode Snapshot High */
+	u32 amms_lo;     /* 0x38 Auxiliary Master Mode Snapshot Low */
+	u32 amms_hi;     /* 0x3C Auxiliary Master Mode Snapshot High */
+
+	struct ixp46x_channel_ctl channel[3];
+};
+
+/* 0x00 Time Sync Control Register Bits */
+#define TSCR_AMM (1<<3)
+#define TSCR_ASM (1<<2)
+#define TSCR_TTM (1<<1)
+#define TSCR_RST (1<<0)
+
+/* 0x04 Time Sync Event Register Bits */
+#define TSER_SNM (1<<3)
+#define TSER_SNS (1<<2)
+#define TTIPEND  (1<<1)
+
+/* 0x40 Time Synchronization Channel Control Register Bits */
+#define MASTER_MODE   (1<<0)
+#define TIMESTAMP_ALL (1<<1)
+
+/* 0x44 Time Synchronization Channel Event Register Bits */
+#define TX_SNAPSHOT_LOCKED (1<<0)
+#define RX_SNAPSHOT_LOCKED (1<<1)
+
+#endif
diff -druN linux-2.6.39-libre/arch/arm/mach-ixp4xx/include/mach/memory.h linux-3.0-rc7-libre/arch/arm/mach-ixp4xx/include/mach/memory.h
--- linux-2.6.39-libre/arch/arm/mach-ixp4xx/include/mach/memory.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-ixp4xx/include/mach/memory.h	2011-07-11 19:51:52.000000000 -0400
@@ -14,16 +14,8 @@
  */
 #define PLAT_PHYS_OFFSET	UL(0x00000000)
 
-#if !defined(__ASSEMBLY__) && defined(CONFIG_PCI)
-
-void ixp4xx_adjust_zones(unsigned long *size, unsigned long *holes);
-
-#define arch_adjust_zones(size, holes) \
-	ixp4xx_adjust_zones(size, holes)
-
-#define ISA_DMA_THRESHOLD (SZ_64M - 1)
-#define MAX_DMA_ADDRESS		(PAGE_OFFSET + SZ_64M)
-
+#ifdef CONFIG_PCI
+#define ARM_DMA_ZONE_SIZE	SZ_64M
 #endif
 
 #endif
diff -druN linux-2.6.39-libre/arch/arm/mach-ixp4xx/include/mach/uncompress.h linux-3.0-rc7-libre/arch/arm/mach-ixp4xx/include/mach/uncompress.h
--- linux-2.6.39-libre/arch/arm/mach-ixp4xx/include/mach/uncompress.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-ixp4xx/include/mach/uncompress.h	2011-07-11 19:51:52.000000000 -0400
@@ -19,7 +19,7 @@
 
 #define TX_DONE (UART_LSR_TEMT|UART_LSR_THRE)
 
-static volatile u32* uart_base;
+volatile u32* uart_base;
 
 static inline void putc(int c)
 {
diff -druN linux-2.6.39-libre/arch/arm/mach-ixp4xx/ixdp425-setup.c linux-3.0-rc7-libre/arch/arm/mach-ixp4xx/ixdp425-setup.c
--- linux-2.6.39-libre/arch/arm/mach-ixp4xx/ixdp425-setup.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-ixp4xx/ixdp425-setup.c	2011-07-11 19:51:52.000000000 -0400
@@ -60,7 +60,6 @@
 #if defined(CONFIG_MTD_NAND_PLATFORM) || \
     defined(CONFIG_MTD_NAND_PLATFORM_MODULE)
 
-#ifdef CONFIG_MTD_PARTITIONS
 const char *part_probes[] = { "cmdlinepart", NULL };
 
 static struct mtd_partition ixdp425_partitions[] = {
@@ -74,7 +73,6 @@
 		.size	= MTDPART_SIZ_FULL
 	},
 };
-#endif
 
 static void
 ixdp425_flash_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl)
@@ -103,11 +101,9 @@
 		.nr_chips		= 1,
 		.chip_delay		= 30,
 		.options		= NAND_NO_AUTOINCR,
-#ifdef CONFIG_MTD_PARTITIONS
 		.part_probe_types 	= part_probes,
 		.partitions	 	= ixdp425_partitions,
 		.nr_partitions	 	= ARRAY_SIZE(ixdp425_partitions),
-#endif
 	},
 	.ctrl = {
 		.cmd_ctrl 		= ixdp425_flash_nand_cmd_ctrl
diff -druN linux-2.6.39-libre/arch/arm/mach-kirkwood/common.c linux-3.0-rc7-libre/arch/arm/mach-kirkwood/common.c
--- linux-2.6.39-libre/arch/arm/mach-kirkwood/common.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-kirkwood/common.c	2011-07-11 19:51:52.000000000 -0400
@@ -13,11 +13,9 @@
 #include <linux/platform_device.h>
 #include <linux/serial_8250.h>
 #include <linux/mbus.h>
-#include <linux/mv643xx_eth.h>
-#include <linux/mv643xx_i2c.h>
 #include <linux/ata_platform.h>
 #include <linux/mtd/nand.h>
-#include <linux/spi/orion_spi.h>
+#include <linux/dma-mapping.h>
 #include <net/dsa.h>
 #include <asm/page.h>
 #include <asm/timex.h>
@@ -28,11 +26,9 @@
 #include <mach/bridge-regs.h>
 #include <plat/audio.h>
 #include <plat/cache-feroceon-l2.h>
-#include <plat/ehci-orion.h>
 #include <plat/mvsdio.h>
-#include <plat/mv_xor.h>
 #include <plat/orion_nand.h>
-#include <plat/orion_wdt.h>
+#include <plat/common.h>
 #include <plat/time.h>
 #include "common.h"
 
@@ -69,210 +65,52 @@
  * registered.  Some reserved bits must be set to 1.
  */
 unsigned int kirkwood_clk_ctrl = CGC_DUNIT | CGC_RESERVED;
-	
-
-/*****************************************************************************
- * EHCI
- ****************************************************************************/
-static struct orion_ehci_data kirkwood_ehci_data = {
-	.dram		= &kirkwood_mbus_dram_info,
-	.phy_version	= EHCI_PHY_NA,
-};
-
-static u64 ehci_dmamask = 0xffffffffUL;
 
 
 /*****************************************************************************
  * EHCI0
  ****************************************************************************/
-static struct resource kirkwood_ehci_resources[] = {
-	{
-		.start	= USB_PHYS_BASE,
-		.end	= USB_PHYS_BASE + 0x0fff,
-		.flags	= IORESOURCE_MEM,
-	}, {
-		.start	= IRQ_KIRKWOOD_USB,
-		.end	= IRQ_KIRKWOOD_USB,
-		.flags	= IORESOURCE_IRQ,
-	},
-};
-
-static struct platform_device kirkwood_ehci = {
-	.name		= "orion-ehci",
-	.id		= 0,
-	.dev		= {
-		.dma_mask		= &ehci_dmamask,
-		.coherent_dma_mask	= 0xffffffff,
-		.platform_data		= &kirkwood_ehci_data,
-	},
-	.resource	= kirkwood_ehci_resources,
-	.num_resources	= ARRAY_SIZE(kirkwood_ehci_resources),
-};
-
 void __init kirkwood_ehci_init(void)
 {
 	kirkwood_clk_ctrl |= CGC_USB0;
-	platform_device_register(&kirkwood_ehci);
+	orion_ehci_init(&kirkwood_mbus_dram_info,
+			USB_PHYS_BASE, IRQ_KIRKWOOD_USB);
 }
 
 
 /*****************************************************************************
  * GE00
  ****************************************************************************/
-struct mv643xx_eth_shared_platform_data kirkwood_ge00_shared_data = {
-	.dram		= &kirkwood_mbus_dram_info,
-};
-
-static struct resource kirkwood_ge00_shared_resources[] = {
-	{
-		.name	= "ge00 base",
-		.start	= GE00_PHYS_BASE + 0x2000,
-		.end	= GE00_PHYS_BASE + 0x3fff,
-		.flags	= IORESOURCE_MEM,
-	}, {
-		.name	= "ge00 err irq",
-		.start	= IRQ_KIRKWOOD_GE00_ERR,
-		.end	= IRQ_KIRKWOOD_GE00_ERR,
-		.flags	= IORESOURCE_IRQ,
-	},
-};
-
-static struct platform_device kirkwood_ge00_shared = {
-	.name		= MV643XX_ETH_SHARED_NAME,
-	.id		= 0,
-	.dev		= {
-		.platform_data	= &kirkwood_ge00_shared_data,
-	},
-	.num_resources	= ARRAY_SIZE(kirkwood_ge00_shared_resources),
-	.resource	= kirkwood_ge00_shared_resources,
-};
-
-static struct resource kirkwood_ge00_resources[] = {
-	{
-		.name	= "ge00 irq",
-		.start	= IRQ_KIRKWOOD_GE00_SUM,
-		.end	= IRQ_KIRKWOOD_GE00_SUM,
-		.flags	= IORESOURCE_IRQ,
-	},
-};
-
-static struct platform_device kirkwood_ge00 = {
-	.name		= MV643XX_ETH_NAME,
-	.id		= 0,
-	.num_resources	= 1,
-	.resource	= kirkwood_ge00_resources,
-	.dev		= {
-		.coherent_dma_mask	= 0xffffffff,
-	},
-};
-
 void __init kirkwood_ge00_init(struct mv643xx_eth_platform_data *eth_data)
 {
 	kirkwood_clk_ctrl |= CGC_GE0;
-	eth_data->shared = &kirkwood_ge00_shared;
-	kirkwood_ge00.dev.platform_data = eth_data;
 
-	platform_device_register(&kirkwood_ge00_shared);
-	platform_device_register(&kirkwood_ge00);
+	orion_ge00_init(eth_data, &kirkwood_mbus_dram_info,
+			GE00_PHYS_BASE, IRQ_KIRKWOOD_GE00_SUM,
+			IRQ_KIRKWOOD_GE00_ERR, kirkwood_tclk);
 }
 
 
 /*****************************************************************************
  * GE01
  ****************************************************************************/
-struct mv643xx_eth_shared_platform_data kirkwood_ge01_shared_data = {
-	.dram		= &kirkwood_mbus_dram_info,
-	.shared_smi	= &kirkwood_ge00_shared,
-};
-
-static struct resource kirkwood_ge01_shared_resources[] = {
-	{
-		.name	= "ge01 base",
-		.start	= GE01_PHYS_BASE + 0x2000,
-		.end	= GE01_PHYS_BASE + 0x3fff,
-		.flags	= IORESOURCE_MEM,
-	}, {
-		.name	= "ge01 err irq",
-		.start	= IRQ_KIRKWOOD_GE01_ERR,
-		.end	= IRQ_KIRKWOOD_GE01_ERR,
-		.flags	= IORESOURCE_IRQ,
-	},
-};
-
-static struct platform_device kirkwood_ge01_shared = {
-	.name		= MV643XX_ETH_SHARED_NAME,
-	.id		= 1,
-	.dev		= {
-		.platform_data	= &kirkwood_ge01_shared_data,
-	},
-	.num_resources	= ARRAY_SIZE(kirkwood_ge01_shared_resources),
-	.resource	= kirkwood_ge01_shared_resources,
-};
-
-static struct resource kirkwood_ge01_resources[] = {
-	{
-		.name	= "ge01 irq",
-		.start	= IRQ_KIRKWOOD_GE01_SUM,
-		.end	= IRQ_KIRKWOOD_GE01_SUM,
-		.flags	= IORESOURCE_IRQ,
-	},
-};
-
-static struct platform_device kirkwood_ge01 = {
-	.name		= MV643XX_ETH_NAME,
-	.id		= 1,
-	.num_resources	= 1,
-	.resource	= kirkwood_ge01_resources,
-	.dev		= {
-		.coherent_dma_mask	= 0xffffffff,
-	},
-};
-
 void __init kirkwood_ge01_init(struct mv643xx_eth_platform_data *eth_data)
 {
+
 	kirkwood_clk_ctrl |= CGC_GE1;
-	eth_data->shared = &kirkwood_ge01_shared;
-	kirkwood_ge01.dev.platform_data = eth_data;
 
-	platform_device_register(&kirkwood_ge01_shared);
-	platform_device_register(&kirkwood_ge01);
+	orion_ge01_init(eth_data, &kirkwood_mbus_dram_info,
+			GE01_PHYS_BASE, IRQ_KIRKWOOD_GE01_SUM,
+			IRQ_KIRKWOOD_GE01_ERR, kirkwood_tclk);
 }
 
 
 /*****************************************************************************
  * Ethernet switch
  ****************************************************************************/
-static struct resource kirkwood_switch_resources[] = {
-	{
-		.start	= 0,
-		.end	= 0,
-		.flags	= IORESOURCE_IRQ,
-	},
-};
-
-static struct platform_device kirkwood_switch_device = {
-	.name		= "dsa",
-	.id		= 0,
-	.num_resources	= 0,
-	.resource	= kirkwood_switch_resources,
-};
-
 void __init kirkwood_ge00_switch_init(struct dsa_platform_data *d, int irq)
 {
-	int i;
-
-	if (irq != NO_IRQ) {
-		kirkwood_switch_resources[0].start = irq;
-		kirkwood_switch_resources[0].end = irq;
-		kirkwood_switch_device.num_resources = 1;
-	}
-
-	d->netdev = &kirkwood_ge00.dev;
-	for (i = 0; i < d->nr_chips; i++)
-		d->chip[i].mii_bus = &kirkwood_ge00_shared.dev;
-	kirkwood_switch_device.dev.platform_data = d;
-
-	platform_device_register(&kirkwood_switch_device);
+	orion_ge00_switch_init(d, irq);
 }
 
 
@@ -325,53 +163,23 @@
 /*****************************************************************************
  * SoC RTC
  ****************************************************************************/
-static struct resource kirkwood_rtc_resource = {
-	.start	= RTC_PHYS_BASE,
-	.end	= RTC_PHYS_BASE + SZ_16 - 1,
-	.flags	= IORESOURCE_MEM,
-};
-
 static void __init kirkwood_rtc_init(void)
 {
-	platform_device_register_simple("rtc-mv", -1, &kirkwood_rtc_resource, 1);
+	orion_rtc_init(RTC_PHYS_BASE, IRQ_KIRKWOOD_RTC);
 }
 
 
 /*****************************************************************************
  * SATA
  ****************************************************************************/
-static struct resource kirkwood_sata_resources[] = {
-	{
-		.name	= "sata base",
-		.start	= SATA_PHYS_BASE,
-		.end	= SATA_PHYS_BASE + 0x5000 - 1,
-		.flags	= IORESOURCE_MEM,
-	}, {
-		.name	= "sata irq",
-		.start	= IRQ_KIRKWOOD_SATA,
-		.end	= IRQ_KIRKWOOD_SATA,
-		.flags	= IORESOURCE_IRQ,
-	},
-};
-
-static struct platform_device kirkwood_sata = {
-	.name		= "sata_mv",
-	.id		= 0,
-	.dev		= {
-		.coherent_dma_mask	= 0xffffffff,
-	},
-	.num_resources	= ARRAY_SIZE(kirkwood_sata_resources),
-	.resource	= kirkwood_sata_resources,
-};
-
 void __init kirkwood_sata_init(struct mv_sata_platform_data *sata_data)
 {
 	kirkwood_clk_ctrl |= CGC_SATA0;
 	if (sata_data->n_ports > 1)
 		kirkwood_clk_ctrl |= CGC_SATA1;
-	sata_data->dram = &kirkwood_mbus_dram_info;
-	kirkwood_sata.dev.platform_data = sata_data;
-	platform_device_register(&kirkwood_sata);
+
+	orion_sata_init(sata_data, &kirkwood_mbus_dram_info,
+			SATA_PHYS_BASE, IRQ_KIRKWOOD_SATA);
 }
 
 
@@ -391,14 +199,14 @@
 	},
 };
 
-static u64 mvsdio_dmamask = 0xffffffffUL;
+static u64 mvsdio_dmamask = DMA_BIT_MASK(32);
 
 static struct platform_device kirkwood_sdio = {
 	.name		= "mvsdio",
 	.id		= -1,
 	.dev		= {
 		.dma_mask = &mvsdio_dmamask,
-		.coherent_dma_mask = 0xffffffff,
+		.coherent_dma_mask = DMA_BIT_MASK(32),
 	},
 	.num_resources	= ARRAY_SIZE(mvsdio_resources),
 	.resource	= mvsdio_resources,
@@ -423,424 +231,84 @@
 /*****************************************************************************
  * SPI
  ****************************************************************************/
-static struct orion_spi_info kirkwood_spi_plat_data = {
-};
-
-static struct resource kirkwood_spi_resources[] = {
-	{
-		.start	= SPI_PHYS_BASE,
-		.end	= SPI_PHYS_BASE + SZ_512 - 1,
-		.flags	= IORESOURCE_MEM,
-	},
-};
-
-static struct platform_device kirkwood_spi = {
-	.name		= "orion_spi",
-	.id		= 0,
-	.resource	= kirkwood_spi_resources,
-	.dev		= {
-		.platform_data	= &kirkwood_spi_plat_data,
-	},
-	.num_resources	= ARRAY_SIZE(kirkwood_spi_resources),
-};
-
 void __init kirkwood_spi_init()
 {
 	kirkwood_clk_ctrl |= CGC_RUNIT;
-	platform_device_register(&kirkwood_spi);
+	orion_spi_init(SPI_PHYS_BASE, kirkwood_tclk);
 }
 
 
 /*****************************************************************************
  * I2C
  ****************************************************************************/
-static struct mv64xxx_i2c_pdata kirkwood_i2c_pdata = {
-	.freq_m		= 8, /* assumes 166 MHz TCLK */
-	.freq_n		= 3,
-	.timeout	= 1000, /* Default timeout of 1 second */
-};
-
-static struct resource kirkwood_i2c_resources[] = {
-	{
-		.start	= I2C_PHYS_BASE,
-		.end	= I2C_PHYS_BASE + 0x1f,
-		.flags	= IORESOURCE_MEM,
-	}, {
-		.start	= IRQ_KIRKWOOD_TWSI,
-		.end	= IRQ_KIRKWOOD_TWSI,
-		.flags	= IORESOURCE_IRQ,
-	},
-};
-
-static struct platform_device kirkwood_i2c = {
-	.name		= MV64XXX_I2C_CTLR_NAME,
-	.id		= 0,
-	.num_resources	= ARRAY_SIZE(kirkwood_i2c_resources),
-	.resource	= kirkwood_i2c_resources,
-	.dev		= {
-		.platform_data	= &kirkwood_i2c_pdata,
-	},
-};
-
 void __init kirkwood_i2c_init(void)
 {
-	platform_device_register(&kirkwood_i2c);
+	orion_i2c_init(I2C_PHYS_BASE, IRQ_KIRKWOOD_TWSI, 8);
 }
 
 
 /*****************************************************************************
  * UART0
  ****************************************************************************/
-static struct plat_serial8250_port kirkwood_uart0_data[] = {
-	{
-		.mapbase	= UART0_PHYS_BASE,
-		.membase	= (char *)UART0_VIRT_BASE,
-		.irq		= IRQ_KIRKWOOD_UART_0,
-		.flags		= UPF_SKIP_TEST | UPF_BOOT_AUTOCONF,
-		.iotype		= UPIO_MEM,
-		.regshift	= 2,
-		.uartclk	= 0,
-	}, {
-	},
-};
-
-static struct resource kirkwood_uart0_resources[] = {
-	{
-		.start		= UART0_PHYS_BASE,
-		.end		= UART0_PHYS_BASE + 0xff,
-		.flags		= IORESOURCE_MEM,
-	}, {
-		.start		= IRQ_KIRKWOOD_UART_0,
-		.end		= IRQ_KIRKWOOD_UART_0,
-		.flags		= IORESOURCE_IRQ,
-	},
-};
-
-static struct platform_device kirkwood_uart0 = {
-	.name			= "serial8250",
-	.id			= 0,
-	.dev			= {
-		.platform_data	= kirkwood_uart0_data,
-	},
-	.resource		= kirkwood_uart0_resources,
-	.num_resources		= ARRAY_SIZE(kirkwood_uart0_resources),
-};
 
 void __init kirkwood_uart0_init(void)
 {
-	platform_device_register(&kirkwood_uart0);
+	orion_uart0_init(UART0_VIRT_BASE, UART0_PHYS_BASE,
+			 IRQ_KIRKWOOD_UART_0, kirkwood_tclk);
 }
 
 
 /*****************************************************************************
  * UART1
  ****************************************************************************/
-static struct plat_serial8250_port kirkwood_uart1_data[] = {
-	{
-		.mapbase	= UART1_PHYS_BASE,
-		.membase	= (char *)UART1_VIRT_BASE,
-		.irq		= IRQ_KIRKWOOD_UART_1,
-		.flags		= UPF_SKIP_TEST | UPF_BOOT_AUTOCONF,
-		.iotype		= UPIO_MEM,
-		.regshift	= 2,
-		.uartclk	= 0,
-	}, {
-	},
-};
-
-static struct resource kirkwood_uart1_resources[] = {
-	{
-		.start		= UART1_PHYS_BASE,
-		.end		= UART1_PHYS_BASE + 0xff,
-		.flags		= IORESOURCE_MEM,
-	}, {
-		.start		= IRQ_KIRKWOOD_UART_1,
-		.end		= IRQ_KIRKWOOD_UART_1,
-		.flags		= IORESOURCE_IRQ,
-	},
-};
-
-static struct platform_device kirkwood_uart1 = {
-	.name			= "serial8250",
-	.id			= 1,
-	.dev			= {
-		.platform_data	= kirkwood_uart1_data,
-	},
-	.resource		= kirkwood_uart1_resources,
-	.num_resources		= ARRAY_SIZE(kirkwood_uart1_resources),
-};
-
 void __init kirkwood_uart1_init(void)
 {
-	platform_device_register(&kirkwood_uart1);
+	orion_uart1_init(UART1_VIRT_BASE, UART1_PHYS_BASE,
+			 IRQ_KIRKWOOD_UART_1, kirkwood_tclk);
 }
 
-
 /*****************************************************************************
  * Cryptographic Engines and Security Accelerator (CESA)
  ****************************************************************************/
-
-static struct resource kirkwood_crypto_res[] = {
-	{
-		.name   = "regs",
-		.start  = CRYPTO_PHYS_BASE,
-		.end    = CRYPTO_PHYS_BASE + 0xffff,
-		.flags  = IORESOURCE_MEM,
-	}, {
-		.name   = "sram",
-		.start  = KIRKWOOD_SRAM_PHYS_BASE,
-		.end    = KIRKWOOD_SRAM_PHYS_BASE + KIRKWOOD_SRAM_SIZE - 1,
-		.flags  = IORESOURCE_MEM,
-	}, {
-		.name   = "crypto interrupt",
-		.start  = IRQ_KIRKWOOD_CRYPTO,
-		.end    = IRQ_KIRKWOOD_CRYPTO,
-		.flags  = IORESOURCE_IRQ,
-	},
-};
-
-static struct platform_device kirkwood_crypto_device = {
-	.name           = "mv_crypto",
-	.id             = -1,
-	.num_resources  = ARRAY_SIZE(kirkwood_crypto_res),
-	.resource       = kirkwood_crypto_res,
-};
-
 void __init kirkwood_crypto_init(void)
 {
 	kirkwood_clk_ctrl |= CGC_CRYPTO;
-	platform_device_register(&kirkwood_crypto_device);
+	orion_crypto_init(CRYPTO_PHYS_BASE, KIRKWOOD_SRAM_PHYS_BASE,
+			  KIRKWOOD_SRAM_SIZE, IRQ_KIRKWOOD_CRYPTO);
 }
 
 
 /*****************************************************************************
- * XOR
- ****************************************************************************/
-static struct mv_xor_platform_shared_data kirkwood_xor_shared_data = {
-	.dram		= &kirkwood_mbus_dram_info,
-};
-
-static u64 kirkwood_xor_dmamask = DMA_BIT_MASK(32);
-
-
-/*****************************************************************************
  * XOR0
  ****************************************************************************/
-static struct resource kirkwood_xor0_shared_resources[] = {
-	{
-		.name	= "xor 0 low",
-		.start	= XOR0_PHYS_BASE,
-		.end	= XOR0_PHYS_BASE + 0xff,
-		.flags	= IORESOURCE_MEM,
-	}, {
-		.name	= "xor 0 high",
-		.start	= XOR0_HIGH_PHYS_BASE,
-		.end	= XOR0_HIGH_PHYS_BASE + 0xff,
-		.flags	= IORESOURCE_MEM,
-	},
-};
-
-static struct platform_device kirkwood_xor0_shared = {
-	.name		= MV_XOR_SHARED_NAME,
-	.id		= 0,
-	.dev		= {
-		.platform_data = &kirkwood_xor_shared_data,
-	},
-	.num_resources	= ARRAY_SIZE(kirkwood_xor0_shared_resources),
-	.resource	= kirkwood_xor0_shared_resources,
-};
-
-static struct resource kirkwood_xor00_resources[] = {
-	[0] = {
-		.start	= IRQ_KIRKWOOD_XOR_00,
-		.end	= IRQ_KIRKWOOD_XOR_00,
-		.flags	= IORESOURCE_IRQ,
-	},
-};
-
-static struct mv_xor_platform_data kirkwood_xor00_data = {
-	.shared		= &kirkwood_xor0_shared,
-	.hw_id		= 0,
-	.pool_size	= PAGE_SIZE,
-};
-
-static struct platform_device kirkwood_xor00_channel = {
-	.name		= MV_XOR_NAME,
-	.id		= 0,
-	.num_resources	= ARRAY_SIZE(kirkwood_xor00_resources),
-	.resource	= kirkwood_xor00_resources,
-	.dev		= {
-		.dma_mask		= &kirkwood_xor_dmamask,
-		.coherent_dma_mask	= DMA_BIT_MASK(64),
-		.platform_data		= &kirkwood_xor00_data,
-	},
-};
-
-static struct resource kirkwood_xor01_resources[] = {
-	[0] = {
-		.start	= IRQ_KIRKWOOD_XOR_01,
-		.end	= IRQ_KIRKWOOD_XOR_01,
-		.flags	= IORESOURCE_IRQ,
-	},
-};
-
-static struct mv_xor_platform_data kirkwood_xor01_data = {
-	.shared		= &kirkwood_xor0_shared,
-	.hw_id		= 1,
-	.pool_size	= PAGE_SIZE,
-};
-
-static struct platform_device kirkwood_xor01_channel = {
-	.name		= MV_XOR_NAME,
-	.id		= 1,
-	.num_resources	= ARRAY_SIZE(kirkwood_xor01_resources),
-	.resource	= kirkwood_xor01_resources,
-	.dev		= {
-		.dma_mask		= &kirkwood_xor_dmamask,
-		.coherent_dma_mask	= DMA_BIT_MASK(64),
-		.platform_data		= &kirkwood_xor01_data,
-	},
-};
-
 static void __init kirkwood_xor0_init(void)
 {
 	kirkwood_clk_ctrl |= CGC_XOR0;
-	platform_device_register(&kirkwood_xor0_shared);
 
-	/*
-	 * two engines can't do memset simultaneously, this limitation
-	 * satisfied by removing memset support from one of the engines.
-	 */
-	dma_cap_set(DMA_MEMCPY, kirkwood_xor00_data.cap_mask);
-	dma_cap_set(DMA_XOR, kirkwood_xor00_data.cap_mask);
-	platform_device_register(&kirkwood_xor00_channel);
-
-	dma_cap_set(DMA_MEMCPY, kirkwood_xor01_data.cap_mask);
-	dma_cap_set(DMA_MEMSET, kirkwood_xor01_data.cap_mask);
-	dma_cap_set(DMA_XOR, kirkwood_xor01_data.cap_mask);
-	platform_device_register(&kirkwood_xor01_channel);
+	orion_xor0_init(&kirkwood_mbus_dram_info,
+			XOR0_PHYS_BASE, XOR0_HIGH_PHYS_BASE,
+			IRQ_KIRKWOOD_XOR_00, IRQ_KIRKWOOD_XOR_01);
 }
 
 
 /*****************************************************************************
  * XOR1
  ****************************************************************************/
-static struct resource kirkwood_xor1_shared_resources[] = {
-	{
-		.name	= "xor 1 low",
-		.start	= XOR1_PHYS_BASE,
-		.end	= XOR1_PHYS_BASE + 0xff,
-		.flags	= IORESOURCE_MEM,
-	}, {
-		.name	= "xor 1 high",
-		.start	= XOR1_HIGH_PHYS_BASE,
-		.end	= XOR1_HIGH_PHYS_BASE + 0xff,
-		.flags	= IORESOURCE_MEM,
-	},
-};
-
-static struct platform_device kirkwood_xor1_shared = {
-	.name		= MV_XOR_SHARED_NAME,
-	.id		= 1,
-	.dev		= {
-		.platform_data = &kirkwood_xor_shared_data,
-	},
-	.num_resources	= ARRAY_SIZE(kirkwood_xor1_shared_resources),
-	.resource	= kirkwood_xor1_shared_resources,
-};
-
-static struct resource kirkwood_xor10_resources[] = {
-	[0] = {
-		.start	= IRQ_KIRKWOOD_XOR_10,
-		.end	= IRQ_KIRKWOOD_XOR_10,
-		.flags	= IORESOURCE_IRQ,
-	},
-};
-
-static struct mv_xor_platform_data kirkwood_xor10_data = {
-	.shared		= &kirkwood_xor1_shared,
-	.hw_id		= 0,
-	.pool_size	= PAGE_SIZE,
-};
-
-static struct platform_device kirkwood_xor10_channel = {
-	.name		= MV_XOR_NAME,
-	.id		= 2,
-	.num_resources	= ARRAY_SIZE(kirkwood_xor10_resources),
-	.resource	= kirkwood_xor10_resources,
-	.dev		= {
-		.dma_mask		= &kirkwood_xor_dmamask,
-		.coherent_dma_mask	= DMA_BIT_MASK(64),
-		.platform_data		= &kirkwood_xor10_data,
-	},
-};
-
-static struct resource kirkwood_xor11_resources[] = {
-	[0] = {
-		.start	= IRQ_KIRKWOOD_XOR_11,
-		.end	= IRQ_KIRKWOOD_XOR_11,
-		.flags	= IORESOURCE_IRQ,
-	},
-};
-
-static struct mv_xor_platform_data kirkwood_xor11_data = {
-	.shared		= &kirkwood_xor1_shared,
-	.hw_id		= 1,
-	.pool_size	= PAGE_SIZE,
-};
-
-static struct platform_device kirkwood_xor11_channel = {
-	.name		= MV_XOR_NAME,
-	.id		= 3,
-	.num_resources	= ARRAY_SIZE(kirkwood_xor11_resources),
-	.resource	= kirkwood_xor11_resources,
-	.dev		= {
-		.dma_mask		= &kirkwood_xor_dmamask,
-		.coherent_dma_mask	= DMA_BIT_MASK(64),
-		.platform_data		= &kirkwood_xor11_data,
-	},
-};
-
 static void __init kirkwood_xor1_init(void)
 {
 	kirkwood_clk_ctrl |= CGC_XOR1;
-	platform_device_register(&kirkwood_xor1_shared);
-
-	/*
-	 * two engines can't do memset simultaneously, this limitation
-	 * satisfied by removing memset support from one of the engines.
-	 */
-	dma_cap_set(DMA_MEMCPY, kirkwood_xor10_data.cap_mask);
-	dma_cap_set(DMA_XOR, kirkwood_xor10_data.cap_mask);
-	platform_device_register(&kirkwood_xor10_channel);
 
-	dma_cap_set(DMA_MEMCPY, kirkwood_xor11_data.cap_mask);
-	dma_cap_set(DMA_MEMSET, kirkwood_xor11_data.cap_mask);
-	dma_cap_set(DMA_XOR, kirkwood_xor11_data.cap_mask);
-	platform_device_register(&kirkwood_xor11_channel);
+	orion_xor1_init(XOR1_PHYS_BASE, XOR1_HIGH_PHYS_BASE,
+			IRQ_KIRKWOOD_XOR_10, IRQ_KIRKWOOD_XOR_11);
 }
 
 
 /*****************************************************************************
  * Watchdog
  ****************************************************************************/
-static struct orion_wdt_platform_data kirkwood_wdt_data = {
-	.tclk		= 0,
-};
-
-static struct platform_device kirkwood_wdt_device = {
-	.name		= "orion_wdt",
-	.id		= -1,
-	.dev		= {
-		.platform_data	= &kirkwood_wdt_data,
-	},
-	.num_resources	= 0,
-};
-
 static void __init kirkwood_wdt_init(void)
 {
-	kirkwood_wdt_data.tclk = kirkwood_tclk;
-	platform_device_register(&kirkwood_wdt_device);
+	orion_wdt_init(kirkwood_tclk);
 }
 
 
@@ -984,11 +452,6 @@
 {
 	printk(KERN_INFO "Kirkwood: %s, TCLK=%d.\n",
 		kirkwood_id(), kirkwood_tclk);
-	kirkwood_ge00_shared_data.t_clk = kirkwood_tclk;
-	kirkwood_ge01_shared_data.t_clk = kirkwood_tclk;
-	kirkwood_spi_plat_data.tclk = kirkwood_tclk;
-	kirkwood_uart0_data[0].uartclk = kirkwood_tclk;
-	kirkwood_uart1_data[0].uartclk = kirkwood_tclk;
 	kirkwood_i2s_data.tclk = kirkwood_tclk;
 
 	/*
diff -druN linux-2.6.39-libre/arch/arm/mach-kirkwood/include/mach/irqs.h linux-3.0-rc7-libre/arch/arm/mach-kirkwood/include/mach/irqs.h
--- linux-2.6.39-libre/arch/arm/mach-kirkwood/include/mach/irqs.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-kirkwood/include/mach/irqs.h	2011-07-11 19:51:52.000000000 -0400
@@ -51,6 +51,7 @@
 #define IRQ_KIRKWOOD_GPIO_HIGH_16_23	41
 #define IRQ_KIRKWOOD_GE00_ERR	46
 #define IRQ_KIRKWOOD_GE01_ERR	47
+#define IRQ_KIRKWOOD_RTC        53
 
 /*
  * KIRKWOOD General Purpose Pins
diff -druN linux-2.6.39-libre/arch/arm/mach-kirkwood/mpp.c linux-3.0-rc7-libre/arch/arm/mach-kirkwood/mpp.c
--- linux-2.6.39-libre/arch/arm/mach-kirkwood/mpp.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-kirkwood/mpp.c	2011-07-11 19:51:52.000000000 -0400
@@ -14,6 +14,7 @@
 #include <linux/io.h>
 #include <asm/gpio.h>
 #include <mach/hardware.h>
+#include <plat/mpp.h>
 #include "common.h"
 #include "mpp.h"
 
@@ -36,61 +37,8 @@
 	return 0;
 }
 
-#define MPP_CTRL(i)	(DEV_BUS_VIRT_BASE + (i) * 4)
-#define MPP_NR_REGS	(1 + MPP_MAX/8)
-
 void __init kirkwood_mpp_conf(unsigned int *mpp_list)
 {
-	u32 mpp_ctrl[MPP_NR_REGS];
-	unsigned int variant_mask;
-	int i;
-
-	variant_mask = kirkwood_variant();
-	if (!variant_mask)
-		return;
-
-	printk(KERN_DEBUG "initial MPP regs:");
-	for (i = 0; i < MPP_NR_REGS; i++) {
-		mpp_ctrl[i] = readl(MPP_CTRL(i));
-		printk(" %08x", mpp_ctrl[i]);
-	}
-	printk("\n");
-
-	for ( ; *mpp_list; mpp_list++) {
-		unsigned int num = MPP_NUM(*mpp_list);
-		unsigned int sel = MPP_SEL(*mpp_list);
-		int shift, gpio_mode;
-
-		if (num > MPP_MAX) {
-			printk(KERN_ERR "kirkwood_mpp_conf: invalid MPP "
-					"number (%u)\n", num);
-			continue;
-		}
-		if (!(*mpp_list & variant_mask)) {
-			printk(KERN_WARNING
-			       "kirkwood_mpp_conf: requested MPP%u config "
-			       "unavailable on this hardware\n", num);
-			continue;
-		}
-
-		shift = (num & 7) << 2;
-		mpp_ctrl[num / 8] &= ~(0xf << shift);
-		mpp_ctrl[num / 8] |= sel << shift;
-
-		gpio_mode = 0;
-		if (*mpp_list & MPP_INPUT_MASK)
-			gpio_mode |= GPIO_INPUT_OK;
-		if (*mpp_list & MPP_OUTPUT_MASK)
-			gpio_mode |= GPIO_OUTPUT_OK;
-		if (sel != 0)
-			gpio_mode = 0;
-		orion_gpio_set_valid(num, gpio_mode);
-	}
-
-	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");
+	orion_mpp_conf(mpp_list, kirkwood_variant(),
+		       MPP_MAX, DEV_BUS_VIRT_BASE);
 }
diff -druN linux-2.6.39-libre/arch/arm/mach-kirkwood/mpp.h linux-3.0-rc7-libre/arch/arm/mach-kirkwood/mpp.h
--- linux-2.6.39-libre/arch/arm/mach-kirkwood/mpp.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-kirkwood/mpp.h	2011-07-11 19:51:52.000000000 -0400
@@ -22,14 +22,8 @@
 	/* available on F6281 */	((!!(_F6281)) << 17) | \
 	/* available on F6282 */	((!!(_F6282)) << 18))
 
-#define MPP_NUM(x)	((x) & 0xff)
-#define MPP_SEL(x)	(((x) >> 8) & 0xf)
-
 				/*   num sel  i  o  6180 6190 6192 6281 6282 */
 
-#define MPP_INPUT_MASK		MPP(  0, 0x0, 1, 0, 0,   0,   0,   0,   0 )
-#define MPP_OUTPUT_MASK		MPP(  0, 0x0, 0, 1, 0,   0,   0,   0,   0 )
-
 #define MPP_F6180_MASK		MPP(  0, 0x0, 0, 0, 1,   0,   0,   0,   0 )
 #define MPP_F6190_MASK		MPP(  0, 0x0, 0, 0, 0,   1,   0,   0,   0 )
 #define MPP_F6192_MASK		MPP(  0, 0x0, 0, 0, 0,   0,   1,   0,   0 )
diff -druN linux-2.6.39-libre/arch/arm/mach-loki/common.c linux-3.0-rc7-libre/arch/arm/mach-loki/common.c
--- linux-2.6.39-libre/arch/arm/mach-loki/common.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-loki/common.c	2011-07-11 19:51:52.000000000 -0400
@@ -13,7 +13,7 @@
 #include <linux/platform_device.h>
 #include <linux/serial_8250.h>
 #include <linux/mbus.h>
-#include <linux/mv643xx_eth.h>
+#include <linux/dma-mapping.h>
 #include <asm/page.h>
 #include <asm/timex.h>
 #include <asm/mach/map.h>
@@ -22,6 +22,7 @@
 #include <mach/loki.h>
 #include <plat/orion_nand.h>
 #include <plat/time.h>
+#include <plat/common.h>
 #include "common.h"
 
 /*****************************************************************************
@@ -43,116 +44,28 @@
 
 
 /*****************************************************************************
- * GE0
+ * GE00
  ****************************************************************************/
-struct mv643xx_eth_shared_platform_data loki_ge0_shared_data = {
-	.t_clk		= LOKI_TCLK,
-	.dram		= &loki_mbus_dram_info,
-};
-
-static struct resource loki_ge0_shared_resources[] = {
-	{
-		.name	= "ge0 base",
-		.start	= GE0_PHYS_BASE + 0x2000,
-		.end	= GE0_PHYS_BASE + 0x3fff,
-		.flags	= IORESOURCE_MEM,
-	},
-};
-
-static struct platform_device loki_ge0_shared = {
-	.name		= MV643XX_ETH_SHARED_NAME,
-	.id		= 0,
-	.dev		= {
-		.platform_data	= &loki_ge0_shared_data,
-	},
-	.num_resources	= 1,
-	.resource	= loki_ge0_shared_resources,
-};
-
-static struct resource loki_ge0_resources[] = {
-	{
-		.name	= "ge0 irq",
-		.start	= IRQ_LOKI_GBE_A_INT,
-		.end	= IRQ_LOKI_GBE_A_INT,
-		.flags	= IORESOURCE_IRQ,
-	},
-};
-
-static struct platform_device loki_ge0 = {
-	.name		= MV643XX_ETH_NAME,
-	.id		= 0,
-	.num_resources	= 1,
-	.resource	= loki_ge0_resources,
-	.dev		= {
-		.coherent_dma_mask	= 0xffffffff,
-	},
-};
-
 void __init loki_ge0_init(struct mv643xx_eth_platform_data *eth_data)
 {
-	eth_data->shared = &loki_ge0_shared;
-	loki_ge0.dev.platform_data = eth_data;
-
 	writel(0x00079220, GE0_VIRT_BASE + 0x20b0);
-	platform_device_register(&loki_ge0_shared);
-	platform_device_register(&loki_ge0);
+
+	orion_ge00_init(eth_data, &loki_mbus_dram_info,
+			GE0_PHYS_BASE, IRQ_LOKI_GBE_A_INT,
+			0, LOKI_TCLK);
 }
 
 
 /*****************************************************************************
- * GE1
+ * GE01
  ****************************************************************************/
-struct mv643xx_eth_shared_platform_data loki_ge1_shared_data = {
-	.t_clk		= LOKI_TCLK,
-	.dram		= &loki_mbus_dram_info,
-};
-
-static struct resource loki_ge1_shared_resources[] = {
-	{
-		.name	= "ge1 base",
-		.start	= GE1_PHYS_BASE + 0x2000,
-		.end	= GE1_PHYS_BASE + 0x3fff,
-		.flags	= IORESOURCE_MEM,
-	},
-};
-
-static struct platform_device loki_ge1_shared = {
-	.name		= MV643XX_ETH_SHARED_NAME,
-	.id		= 1,
-	.dev		= {
-		.platform_data	= &loki_ge1_shared_data,
-	},
-	.num_resources	= 1,
-	.resource	= loki_ge1_shared_resources,
-};
-
-static struct resource loki_ge1_resources[] = {
-	{
-		.name	= "ge1 irq",
-		.start	= IRQ_LOKI_GBE_B_INT,
-		.end	= IRQ_LOKI_GBE_B_INT,
-		.flags	= IORESOURCE_IRQ,
-	},
-};
-
-static struct platform_device loki_ge1 = {
-	.name		= MV643XX_ETH_NAME,
-	.id		= 1,
-	.num_resources	= 1,
-	.resource	= loki_ge1_resources,
-	.dev		= {
-		.coherent_dma_mask	= 0xffffffff,
-	},
-};
-
 void __init loki_ge1_init(struct mv643xx_eth_platform_data *eth_data)
 {
-	eth_data->shared = &loki_ge1_shared;
-	loki_ge1.dev.platform_data = eth_data;
-
 	writel(0x00079220, GE1_VIRT_BASE + 0x20b0);
-	platform_device_register(&loki_ge1_shared);
-	platform_device_register(&loki_ge1);
+
+	orion_ge01_init(eth_data, &loki_mbus_dram_info,
+			GE1_PHYS_BASE, IRQ_LOKI_GBE_B_INT,
+			0, LOKI_TCLK);
 }
 
 
@@ -187,7 +100,7 @@
 	.name		= "mvsas",
 	.id		= 0,
 	.dev		= {
-		.coherent_dma_mask	= 0xffffffff,
+		.coherent_dma_mask	= DMA_BIT_MASK(32),
 	},
 	.num_resources	= ARRAY_SIZE(loki_sas_resources),
 	.resource	= loki_sas_resources,
@@ -203,88 +116,19 @@
 /*****************************************************************************
  * UART0
  ****************************************************************************/
-static struct plat_serial8250_port loki_uart0_data[] = {
-	{
-		.mapbase	= UART0_PHYS_BASE,
-		.membase	= (char *)UART0_VIRT_BASE,
-		.irq		= IRQ_LOKI_UART0,
-		.flags		= UPF_SKIP_TEST | UPF_BOOT_AUTOCONF,
-		.iotype		= UPIO_MEM,
-		.regshift	= 2,
-		.uartclk	= LOKI_TCLK,
-	}, {
-	},
-};
-
-static struct resource loki_uart0_resources[] = {
-	{
-		.start		= UART0_PHYS_BASE,
-		.end		= UART0_PHYS_BASE + 0xff,
-		.flags		= IORESOURCE_MEM,
-	}, {
-		.start		= IRQ_LOKI_UART0,
-		.end		= IRQ_LOKI_UART0,
-		.flags		= IORESOURCE_IRQ,
-	},
-};
-
-static struct platform_device loki_uart0 = {
-	.name			= "serial8250",
-	.id			= 0,
-	.dev			= {
-		.platform_data	= loki_uart0_data,
-	},
-	.resource		= loki_uart0_resources,
-	.num_resources		= ARRAY_SIZE(loki_uart0_resources),
-};
-
 void __init loki_uart0_init(void)
 {
-	platform_device_register(&loki_uart0);
+	orion_uart0_init(UART0_VIRT_BASE, UART0_PHYS_BASE,
+			 IRQ_LOKI_UART0, LOKI_TCLK);
 }
 
-
 /*****************************************************************************
  * UART1
  ****************************************************************************/
-static struct plat_serial8250_port loki_uart1_data[] = {
-	{
-		.mapbase	= UART1_PHYS_BASE,
-		.membase	= (char *)UART1_VIRT_BASE,
-		.irq		= IRQ_LOKI_UART1,
-		.flags		= UPF_SKIP_TEST | UPF_BOOT_AUTOCONF,
-		.iotype		= UPIO_MEM,
-		.regshift	= 2,
-		.uartclk	= LOKI_TCLK,
-	}, {
-	},
-};
-
-static struct resource loki_uart1_resources[] = {
-	{
-		.start		= UART1_PHYS_BASE,
-		.end		= UART1_PHYS_BASE + 0xff,
-		.flags		= IORESOURCE_MEM,
-	}, {
-		.start		= IRQ_LOKI_UART1,
-		.end		= IRQ_LOKI_UART1,
-		.flags		= IORESOURCE_IRQ,
-	},
-};
-
-static struct platform_device loki_uart1 = {
-	.name			= "serial8250",
-	.id			= 1,
-	.dev			= {
-		.platform_data	= loki_uart1_data,
-	},
-	.resource		= loki_uart1_resources,
-	.num_resources		= ARRAY_SIZE(loki_uart1_resources),
-};
-
 void __init loki_uart1_init(void)
 {
-	platform_device_register(&loki_uart1);
+	orion_uart1_init(UART1_VIRT_BASE, UART1_PHYS_BASE,
+			 IRQ_LOKI_UART1, LOKI_TCLK);
 }
 
 
diff -druN linux-2.6.39-libre/arch/arm/mach-lpc32xx/timer.c linux-3.0-rc7-libre/arch/arm/mach-lpc32xx/timer.c
--- linux-2.6.39-libre/arch/arm/mach-lpc32xx/timer.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-lpc32xx/timer.c	2011-07-11 19:51:52.000000000 -0400
@@ -31,19 +31,6 @@
 #include <mach/platform.h>
 #include "common.h"
 
-static cycle_t lpc32xx_clksrc_read(struct clocksource *cs)
-{
-	return (cycle_t)__raw_readl(LCP32XX_TIMER_TC(LPC32XX_TIMER1_BASE));
-}
-
-static struct clocksource lpc32xx_clksrc = {
-	.name	= "lpc32xx_clksrc",
-	.rating	= 300,
-	.read	= lpc32xx_clksrc_read,
-	.mask	= CLOCKSOURCE_MASK(32),
-	.flags	= CLOCK_SOURCE_IS_CONTINUOUS,
-};
-
 static int lpc32xx_clkevt_next_event(unsigned long delta,
     struct clock_event_device *dev)
 {
@@ -170,7 +157,9 @@
 	__raw_writel(0, LCP32XX_TIMER_MCR(LPC32XX_TIMER1_BASE));
 	__raw_writel(LCP32XX_TIMER_CNTR_TCR_EN,
 		LCP32XX_TIMER_TCR(LPC32XX_TIMER1_BASE));
-	clocksource_register_hz(&lpc32xx_clksrc, clkrate);
+
+	clocksource_mmio_init(LCP32XX_TIMER_TC(LPC32XX_TIMER1_BASE),
+		"lpc32xx_clksrc", clkrate, 300, 32, clocksource_mmio_readl_up);
 }
 
 struct sys_timer lpc32xx_timer = {
diff -druN linux-2.6.39-libre/arch/arm/mach-mmp/include/mach/uncompress.h linux-3.0-rc7-libre/arch/arm/mach-mmp/include/mach/uncompress.h
--- linux-2.6.39-libre/arch/arm/mach-mmp/include/mach/uncompress.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-mmp/include/mach/uncompress.h	2011-07-11 19:51:52.000000000 -0400
@@ -14,7 +14,7 @@
 #define UART2_BASE	(APB_PHYS_BASE + 0x17000)
 #define UART3_BASE	(APB_PHYS_BASE + 0x18000)
 
-static volatile unsigned long *UART;
+volatile unsigned long *UART;
 
 static inline void putc(char c)
 {
diff -druN linux-2.6.39-libre/arch/arm/mach-msm/gpio-v2.c linux-3.0-rc7-libre/arch/arm/mach-msm/gpio-v2.c
--- linux-2.6.39-libre/arch/arm/mach-msm/gpio-v2.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-msm/gpio-v2.c	2011-07-11 19:51:52.000000000 -0400
@@ -27,6 +27,9 @@
 #include <linux/module.h>
 #include <linux/platform_device.h>
 #include <linux/spinlock.h>
+
+#include <asm/mach/irq.h>
+
 #include <mach/msm_iomap.h>
 #include "gpiomux.h"
 
@@ -309,8 +312,10 @@
  */
 static void msm_summary_irq_handler(unsigned int irq, struct irq_desc *desc)
 {
-	struct irq_data *data = irq_desc_get_irq_data(desc);
 	unsigned long i;
+	struct irq_chip *chip = irq_desc_get_chip(desc);
+
+	chained_irq_enter(chip, desc);
 
 	for (i = find_first_bit(msm_gpio.enabled_irqs, NR_GPIO_IRQS);
 	     i < NR_GPIO_IRQS;
@@ -319,7 +324,8 @@
 			generic_handle_irq(msm_gpio_to_irq(&msm_gpio.gpio_chip,
 							   i));
 	}
-	data->chip->irq_ack(data);
+
+	chained_irq_exit(chip, desc);
 }
 
 static int msm_gpio_irq_set_wake(struct irq_data *d, unsigned int on)
diff -druN linux-2.6.39-libre/arch/arm/mach-msm/include/mach/msm_iomap.h linux-3.0-rc7-libre/arch/arm/mach-msm/include/mach/msm_iomap.h
--- linux-2.6.39-libre/arch/arm/mach-msm/include/mach/msm_iomap.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-msm/include/mach/msm_iomap.h	2011-07-11 19:51:52.000000000 -0400
@@ -55,7 +55,7 @@
 
 #include "msm_iomap-8960.h"
 
-/* Virtual addressses shared across all MSM targets. */
+/* Virtual addresses shared across all MSM targets. */
 #define MSM_CSR_BASE		IOMEM(0xE0001000)
 #define MSM_QGIC_DIST_BASE	IOMEM(0xF0000000)
 #define MSM_QGIC_CPU_BASE	IOMEM(0xF0001000)
diff -druN linux-2.6.39-libre/arch/arm/mach-msm/include/mach/smp.h linux-3.0-rc7-libre/arch/arm/mach-msm/include/mach/smp.h
--- linux-2.6.39-libre/arch/arm/mach-msm/include/mach/smp.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-msm/include/mach/smp.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,23 +0,0 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 and
- * only version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- */
-
-#ifndef __ASM_ARCH_MSM_SMP_H
-#define __ASM_ARCH_MSM_SMP_H
-
-#include <asm/hardware/gic.h>
-
-static inline void smp_cross_call(const struct cpumask *mask, int ipi)
-{
-	gic_raise_softirq(mask, ipi);
-}
-
-#endif
diff -druN linux-2.6.39-libre/arch/arm/mach-msm/platsmp.c linux-3.0-rc7-libre/arch/arm/mach-msm/platsmp.c
--- linux-2.6.39-libre/arch/arm/mach-msm/platsmp.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-msm/platsmp.c	2011-07-11 19:51:52.000000000 -0400
@@ -119,7 +119,7 @@
 	 * the boot monitor to read the system wide flags register,
 	 * and branch to the address found there.
 	 */
-	smp_cross_call(cpumask_of(cpu), 1);
+	gic_raise_softirq(cpumask_of(cpu), 1);
 
 	timeout = jiffies + (1 * HZ);
 	while (time_before(jiffies, timeout)) {
@@ -151,6 +151,8 @@
 
 	for (i = 0; i < NR_CPUS; i++)
 		set_cpu_possible(i, true);
+
+        set_smp_cross_call(gic_raise_softirq);
 }
 
 void __init platform_smp_prepare_cpus(unsigned int max_cpus)
diff -druN linux-2.6.39-libre/arch/arm/mach-msm/timer.c linux-3.0-rc7-libre/arch/arm/mach-msm/timer.c
--- linux-2.6.39-libre/arch/arm/mach-msm/timer.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-msm/timer.c	2011-07-11 19:51:52.000000000 -0400
@@ -23,6 +23,8 @@
 #include <linux/io.h>
 
 #include <asm/mach/time.h>
+#include <asm/hardware/gic.h>
+
 #include <mach/msm_iomap.h>
 #include <mach/cpu.h>
 
@@ -55,10 +57,12 @@
 #if defined(CONFIG_ARCH_QSD8X50)
 #define DGT_HZ (19200000 / 4) /* 19.2 MHz / 4 by default */
 #define MSM_DGT_SHIFT (0)
-#elif defined(CONFIG_ARCH_MSM7X30) || defined(CONFIG_ARCH_MSM8X60) || \
-				      defined(CONFIG_ARCH_MSM8960)
+#elif defined(CONFIG_ARCH_MSM7X30)
 #define DGT_HZ (24576000 / 4) /* 24.576 MHz (LPXO) / 4 by default */
 #define MSM_DGT_SHIFT (0)
+#elif defined(CONFIG_ARCH_MSM8X60) || defined(CONFIG_ARCH_MSM8960)
+#define DGT_HZ (27000000 / 4) /* 27 MHz (PXO) / 4 by default */
+#define MSM_DGT_SHIFT (0)
 #else
 #define DGT_HZ 19200000 /* 19.2 MHz or 600 KHz after shift */
 #define MSM_DGT_SHIFT (5)
@@ -100,7 +104,11 @@
 {
 	struct msm_clock *clk = container_of(cs, struct msm_clock, clocksource);
 
-	return readl(clk->global_counter);
+	/*
+	 * Shift timer count down by a constant due to unreliable lower bits
+	 * on some targets.
+	 */
+	return readl(clk->global_counter) >> clk->shift;
 }
 
 static struct msm_clock *clockevent_to_clock(struct clock_event_device *evt)
diff -druN linux-2.6.39-libre/arch/arm/mach-mv78xx0/common.c linux-3.0-rc7-libre/arch/arm/mach-mv78xx0/common.c
--- linux-2.6.39-libre/arch/arm/mach-mv78xx0/common.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-mv78xx0/common.c	2011-07-11 19:51:52.000000000 -0400
@@ -13,8 +13,6 @@
 #include <linux/platform_device.h>
 #include <linux/serial_8250.h>
 #include <linux/mbus.h>
-#include <linux/mv643xx_eth.h>
-#include <linux/mv643xx_i2c.h>
 #include <linux/ata_platform.h>
 #include <linux/ethtool.h>
 #include <asm/mach/map.h>
@@ -22,11 +20,12 @@
 #include <mach/mv78xx0.h>
 #include <mach/bridge-regs.h>
 #include <plat/cache-feroceon-l2.h>
-#include <plat/ehci-orion.h>
 #include <plat/orion_nand.h>
 #include <plat/time.h>
+#include <plat/common.h>
 #include "common.h"
 
+static int get_tclk(void);
 
 /*****************************************************************************
  * Common bits
@@ -168,285 +167,62 @@
 /*****************************************************************************
  * EHCI
  ****************************************************************************/
-static struct orion_ehci_data mv78xx0_ehci_data = {
-	.dram		= &mv78xx0_mbus_dram_info,
-	.phy_version	= EHCI_PHY_NA,
-};
-
-static u64 ehci_dmamask = 0xffffffffUL;
-
-
-/*****************************************************************************
- * EHCI0
- ****************************************************************************/
-static struct resource mv78xx0_ehci0_resources[] = {
-	{
-		.start	= USB0_PHYS_BASE,
-		.end	= USB0_PHYS_BASE + 0x0fff,
-		.flags	= IORESOURCE_MEM,
-	}, {
-		.start	= IRQ_MV78XX0_USB_0,
-		.end	= IRQ_MV78XX0_USB_0,
-		.flags	= IORESOURCE_IRQ,
-	},
-};
-
-static struct platform_device mv78xx0_ehci0 = {
-	.name		= "orion-ehci",
-	.id		= 0,
-	.dev		= {
-		.dma_mask		= &ehci_dmamask,
-		.coherent_dma_mask	= 0xffffffff,
-		.platform_data		= &mv78xx0_ehci_data,
-	},
-	.resource	= mv78xx0_ehci0_resources,
-	.num_resources	= ARRAY_SIZE(mv78xx0_ehci0_resources),
-};
-
 void __init mv78xx0_ehci0_init(void)
 {
-	platform_device_register(&mv78xx0_ehci0);
+	orion_ehci_init(&mv78xx0_mbus_dram_info,
+			USB0_PHYS_BASE, IRQ_MV78XX0_USB_0);
 }
 
 
 /*****************************************************************************
  * EHCI1
  ****************************************************************************/
-static struct resource mv78xx0_ehci1_resources[] = {
-	{
-		.start	= USB1_PHYS_BASE,
-		.end	= USB1_PHYS_BASE + 0x0fff,
-		.flags	= IORESOURCE_MEM,
-	}, {
-		.start	= IRQ_MV78XX0_USB_1,
-		.end	= IRQ_MV78XX0_USB_1,
-		.flags	= IORESOURCE_IRQ,
-	},
-};
-
-static struct platform_device mv78xx0_ehci1 = {
-	.name		= "orion-ehci",
-	.id		= 1,
-	.dev		= {
-		.dma_mask		= &ehci_dmamask,
-		.coherent_dma_mask	= 0xffffffff,
-		.platform_data		= &mv78xx0_ehci_data,
-	},
-	.resource	= mv78xx0_ehci1_resources,
-	.num_resources	= ARRAY_SIZE(mv78xx0_ehci1_resources),
-};
-
 void __init mv78xx0_ehci1_init(void)
 {
-	platform_device_register(&mv78xx0_ehci1);
+	orion_ehci_1_init(&mv78xx0_mbus_dram_info,
+			  USB1_PHYS_BASE, IRQ_MV78XX0_USB_1);
 }
 
 
 /*****************************************************************************
  * EHCI2
  ****************************************************************************/
-static struct resource mv78xx0_ehci2_resources[] = {
-	{
-		.start	= USB2_PHYS_BASE,
-		.end	= USB2_PHYS_BASE + 0x0fff,
-		.flags	= IORESOURCE_MEM,
-	}, {
-		.start	= IRQ_MV78XX0_USB_2,
-		.end	= IRQ_MV78XX0_USB_2,
-		.flags	= IORESOURCE_IRQ,
-	},
-};
-
-static struct platform_device mv78xx0_ehci2 = {
-	.name		= "orion-ehci",
-	.id		= 2,
-	.dev		= {
-		.dma_mask		= &ehci_dmamask,
-		.coherent_dma_mask	= 0xffffffff,
-		.platform_data		= &mv78xx0_ehci_data,
-	},
-	.resource	= mv78xx0_ehci2_resources,
-	.num_resources	= ARRAY_SIZE(mv78xx0_ehci2_resources),
-};
-
 void __init mv78xx0_ehci2_init(void)
 {
-	platform_device_register(&mv78xx0_ehci2);
+	orion_ehci_2_init(&mv78xx0_mbus_dram_info,
+			  USB2_PHYS_BASE, IRQ_MV78XX0_USB_2);
 }
 
 
 /*****************************************************************************
  * GE00
  ****************************************************************************/
-struct mv643xx_eth_shared_platform_data mv78xx0_ge00_shared_data = {
-	.t_clk		= 0,
-	.dram		= &mv78xx0_mbus_dram_info,
-};
-
-static struct resource mv78xx0_ge00_shared_resources[] = {
-	{
-		.name	= "ge00 base",
-		.start	= GE00_PHYS_BASE + 0x2000,
-		.end	= GE00_PHYS_BASE + 0x3fff,
-		.flags	= IORESOURCE_MEM,
-	}, {
-		.name	= "ge err irq",
-		.start	= IRQ_MV78XX0_GE_ERR,
-		.end	= IRQ_MV78XX0_GE_ERR,
-		.flags	= IORESOURCE_IRQ,
-	},
-};
-
-static struct platform_device mv78xx0_ge00_shared = {
-	.name		= MV643XX_ETH_SHARED_NAME,
-	.id		= 0,
-	.dev		= {
-		.platform_data	= &mv78xx0_ge00_shared_data,
-	},
-	.num_resources	= ARRAY_SIZE(mv78xx0_ge00_shared_resources),
-	.resource	= mv78xx0_ge00_shared_resources,
-};
-
-static struct resource mv78xx0_ge00_resources[] = {
-	{
-		.name	= "ge00 irq",
-		.start	= IRQ_MV78XX0_GE00_SUM,
-		.end	= IRQ_MV78XX0_GE00_SUM,
-		.flags	= IORESOURCE_IRQ,
-	},
-};
-
-static struct platform_device mv78xx0_ge00 = {
-	.name		= MV643XX_ETH_NAME,
-	.id		= 0,
-	.num_resources	= 1,
-	.resource	= mv78xx0_ge00_resources,
-	.dev		= {
-		.coherent_dma_mask	= 0xffffffff,
-	},
-};
-
 void __init mv78xx0_ge00_init(struct mv643xx_eth_platform_data *eth_data)
 {
-	eth_data->shared = &mv78xx0_ge00_shared;
-	mv78xx0_ge00.dev.platform_data = eth_data;
-
-	platform_device_register(&mv78xx0_ge00_shared);
-	platform_device_register(&mv78xx0_ge00);
+	orion_ge00_init(eth_data, &mv78xx0_mbus_dram_info,
+			GE00_PHYS_BASE, IRQ_MV78XX0_GE00_SUM,
+			IRQ_MV78XX0_GE_ERR, get_tclk());
 }
 
 
 /*****************************************************************************
  * GE01
  ****************************************************************************/
-struct mv643xx_eth_shared_platform_data mv78xx0_ge01_shared_data = {
-	.t_clk		= 0,
-	.dram		= &mv78xx0_mbus_dram_info,
-	.shared_smi	= &mv78xx0_ge00_shared,
-};
-
-static struct resource mv78xx0_ge01_shared_resources[] = {
-	{
-		.name	= "ge01 base",
-		.start	= GE01_PHYS_BASE + 0x2000,
-		.end	= GE01_PHYS_BASE + 0x3fff,
-		.flags	= IORESOURCE_MEM,
-	},
-};
-
-static struct platform_device mv78xx0_ge01_shared = {
-	.name		= MV643XX_ETH_SHARED_NAME,
-	.id		= 1,
-	.dev		= {
-		.platform_data	= &mv78xx0_ge01_shared_data,
-	},
-	.num_resources	= 1,
-	.resource	= mv78xx0_ge01_shared_resources,
-};
-
-static struct resource mv78xx0_ge01_resources[] = {
-	{
-		.name	= "ge01 irq",
-		.start	= IRQ_MV78XX0_GE01_SUM,
-		.end	= IRQ_MV78XX0_GE01_SUM,
-		.flags	= IORESOURCE_IRQ,
-	},
-};
-
-static struct platform_device mv78xx0_ge01 = {
-	.name		= MV643XX_ETH_NAME,
-	.id		= 1,
-	.num_resources	= 1,
-	.resource	= mv78xx0_ge01_resources,
-	.dev		= {
-		.coherent_dma_mask	= 0xffffffff,
-	},
-};
-
 void __init mv78xx0_ge01_init(struct mv643xx_eth_platform_data *eth_data)
 {
-	eth_data->shared = &mv78xx0_ge01_shared;
-	mv78xx0_ge01.dev.platform_data = eth_data;
-
-	platform_device_register(&mv78xx0_ge01_shared);
-	platform_device_register(&mv78xx0_ge01);
+	orion_ge01_init(eth_data, &mv78xx0_mbus_dram_info,
+			GE01_PHYS_BASE, IRQ_MV78XX0_GE01_SUM,
+			NO_IRQ, get_tclk());
 }
 
 
 /*****************************************************************************
  * GE10
  ****************************************************************************/
-struct mv643xx_eth_shared_platform_data mv78xx0_ge10_shared_data = {
-	.t_clk		= 0,
-	.dram		= &mv78xx0_mbus_dram_info,
-	.shared_smi	= &mv78xx0_ge00_shared,
-};
-
-static struct resource mv78xx0_ge10_shared_resources[] = {
-	{
-		.name	= "ge10 base",
-		.start	= GE10_PHYS_BASE + 0x2000,
-		.end	= GE10_PHYS_BASE + 0x3fff,
-		.flags	= IORESOURCE_MEM,
-	},
-};
-
-static struct platform_device mv78xx0_ge10_shared = {
-	.name		= MV643XX_ETH_SHARED_NAME,
-	.id		= 2,
-	.dev		= {
-		.platform_data	= &mv78xx0_ge10_shared_data,
-	},
-	.num_resources	= 1,
-	.resource	= mv78xx0_ge10_shared_resources,
-};
-
-static struct resource mv78xx0_ge10_resources[] = {
-	{
-		.name	= "ge10 irq",
-		.start	= IRQ_MV78XX0_GE10_SUM,
-		.end	= IRQ_MV78XX0_GE10_SUM,
-		.flags	= IORESOURCE_IRQ,
-	},
-};
-
-static struct platform_device mv78xx0_ge10 = {
-	.name		= MV643XX_ETH_NAME,
-	.id		= 2,
-	.num_resources	= 1,
-	.resource	= mv78xx0_ge10_resources,
-	.dev		= {
-		.coherent_dma_mask	= 0xffffffff,
-	},
-};
-
 void __init mv78xx0_ge10_init(struct mv643xx_eth_platform_data *eth_data)
 {
 	u32 dev, rev;
 
-	eth_data->shared = &mv78xx0_ge10_shared;
-	mv78xx0_ge10.dev.platform_data = eth_data;
-
 	/*
 	 * On the Z0, ge10 and ge11 are internally connected back
 	 * to back, and not brought out.
@@ -458,65 +234,19 @@
 		eth_data->duplex = DUPLEX_FULL;
 	}
 
-	platform_device_register(&mv78xx0_ge10_shared);
-	platform_device_register(&mv78xx0_ge10);
+	orion_ge10_init(eth_data, &mv78xx0_mbus_dram_info,
+			GE10_PHYS_BASE, IRQ_MV78XX0_GE10_SUM,
+			NO_IRQ, get_tclk());
 }
 
 
 /*****************************************************************************
  * GE11
  ****************************************************************************/
-struct mv643xx_eth_shared_platform_data mv78xx0_ge11_shared_data = {
-	.t_clk		= 0,
-	.dram		= &mv78xx0_mbus_dram_info,
-	.shared_smi	= &mv78xx0_ge00_shared,
-};
-
-static struct resource mv78xx0_ge11_shared_resources[] = {
-	{
-		.name	= "ge11 base",
-		.start	= GE11_PHYS_BASE + 0x2000,
-		.end	= GE11_PHYS_BASE + 0x3fff,
-		.flags	= IORESOURCE_MEM,
-	},
-};
-
-static struct platform_device mv78xx0_ge11_shared = {
-	.name		= MV643XX_ETH_SHARED_NAME,
-	.id		= 3,
-	.dev		= {
-		.platform_data	= &mv78xx0_ge11_shared_data,
-	},
-	.num_resources	= 1,
-	.resource	= mv78xx0_ge11_shared_resources,
-};
-
-static struct resource mv78xx0_ge11_resources[] = {
-	{
-		.name	= "ge11 irq",
-		.start	= IRQ_MV78XX0_GE11_SUM,
-		.end	= IRQ_MV78XX0_GE11_SUM,
-		.flags	= IORESOURCE_IRQ,
-	},
-};
-
-static struct platform_device mv78xx0_ge11 = {
-	.name		= MV643XX_ETH_NAME,
-	.id		= 3,
-	.num_resources	= 1,
-	.resource	= mv78xx0_ge11_resources,
-	.dev		= {
-		.coherent_dma_mask	= 0xffffffff,
-	},
-};
-
 void __init mv78xx0_ge11_init(struct mv643xx_eth_platform_data *eth_data)
 {
 	u32 dev, rev;
 
-	eth_data->shared = &mv78xx0_ge11_shared;
-	mv78xx0_ge11.dev.platform_data = eth_data;
-
 	/*
 	 * On the Z0, ge10 and ge11 are internally connected back
 	 * to back, and not brought out.
@@ -528,293 +258,68 @@
 		eth_data->duplex = DUPLEX_FULL;
 	}
 
-	platform_device_register(&mv78xx0_ge11_shared);
-	platform_device_register(&mv78xx0_ge11);
+	orion_ge11_init(eth_data, &mv78xx0_mbus_dram_info,
+			GE11_PHYS_BASE, IRQ_MV78XX0_GE11_SUM,
+			NO_IRQ, get_tclk());
 }
 
 /*****************************************************************************
- * I2C bus 0
- ****************************************************************************/
-
-static struct mv64xxx_i2c_pdata mv78xx0_i2c_0_pdata = {
-	.freq_m		= 8, /* assumes 166 MHz TCLK */
-	.freq_n		= 3,
-	.timeout	= 1000, /* Default timeout of 1 second */
-};
-
-static struct resource mv78xx0_i2c_0_resources[] = {
-	{
-		.start  = I2C_0_PHYS_BASE,
-		.end    = I2C_0_PHYS_BASE + 0x1f,
-		.flags  = IORESOURCE_MEM,
-	}, {
-		.start  = IRQ_MV78XX0_I2C_0,
-		.end    = IRQ_MV78XX0_I2C_0,
-		.flags  = IORESOURCE_IRQ,
-	},
-};
-
-
-static struct platform_device mv78xx0_i2c_0 = {
-	.name		= MV64XXX_I2C_CTLR_NAME,
-	.id		= 0,
-	.num_resources	= ARRAY_SIZE(mv78xx0_i2c_0_resources),
-	.resource	= mv78xx0_i2c_0_resources,
-	.dev		= {
-		.platform_data	= &mv78xx0_i2c_0_pdata,
-	},
-};
-
-/*****************************************************************************
- * I2C bus 1
+ * I2C
  ****************************************************************************/
-
-static struct mv64xxx_i2c_pdata mv78xx0_i2c_1_pdata = {
-	.freq_m		= 8, /* assumes 166 MHz TCLK */
-	.freq_n		= 3,
-	.timeout	= 1000, /* Default timeout of 1 second */
-};
-
-static struct resource mv78xx0_i2c_1_resources[] = {
-	{
-		.start  = I2C_1_PHYS_BASE,
-		.end    = I2C_1_PHYS_BASE + 0x1f,
-		.flags  = IORESOURCE_MEM,
-	}, {
-		.start  = IRQ_MV78XX0_I2C_1,
-		.end    = IRQ_MV78XX0_I2C_1,
-		.flags  = IORESOURCE_IRQ,
-	},
-};
-
-
-static struct platform_device mv78xx0_i2c_1 = {
-	.name		= MV64XXX_I2C_CTLR_NAME,
-	.id		= 1,
-	.num_resources	= ARRAY_SIZE(mv78xx0_i2c_1_resources),
-	.resource	= mv78xx0_i2c_1_resources,
-	.dev		= {
-		.platform_data	= &mv78xx0_i2c_1_pdata,
-	},
-};
-
 void __init mv78xx0_i2c_init(void)
 {
-	platform_device_register(&mv78xx0_i2c_0);
-	platform_device_register(&mv78xx0_i2c_1);
+	orion_i2c_init(I2C_0_PHYS_BASE, IRQ_MV78XX0_I2C_0, 8);
+	orion_i2c_1_init(I2C_1_PHYS_BASE, IRQ_MV78XX0_I2C_1, 8);
 }
 
 /*****************************************************************************
  * SATA
  ****************************************************************************/
-static struct resource mv78xx0_sata_resources[] = {
-	{
-		.name	= "sata base",
-		.start	= SATA_PHYS_BASE,
-		.end	= SATA_PHYS_BASE + 0x5000 - 1,
-		.flags	= IORESOURCE_MEM,
-	}, {
-		.name	= "sata irq",
-		.start	= IRQ_MV78XX0_SATA,
-		.end	= IRQ_MV78XX0_SATA,
-		.flags	= IORESOURCE_IRQ,
-	},
-};
-
-static struct platform_device mv78xx0_sata = {
-	.name		= "sata_mv",
-	.id		= 0,
-	.dev		= {
-		.coherent_dma_mask	= 0xffffffff,
-	},
-	.num_resources	= ARRAY_SIZE(mv78xx0_sata_resources),
-	.resource	= mv78xx0_sata_resources,
-};
-
 void __init mv78xx0_sata_init(struct mv_sata_platform_data *sata_data)
 {
-	sata_data->dram = &mv78xx0_mbus_dram_info;
-	mv78xx0_sata.dev.platform_data = sata_data;
-	platform_device_register(&mv78xx0_sata);
+	orion_sata_init(sata_data, &mv78xx0_mbus_dram_info,
+			SATA_PHYS_BASE, IRQ_MV78XX0_SATA);
 }
 
 
 /*****************************************************************************
  * UART0
  ****************************************************************************/
-static struct plat_serial8250_port mv78xx0_uart0_data[] = {
-	{
-		.mapbase	= UART0_PHYS_BASE,
-		.membase	= (char *)UART0_VIRT_BASE,
-		.irq		= IRQ_MV78XX0_UART_0,
-		.flags		= UPF_SKIP_TEST | UPF_BOOT_AUTOCONF,
-		.iotype		= UPIO_MEM,
-		.regshift	= 2,
-		.uartclk	= 0,
-	}, {
-	},
-};
-
-static struct resource mv78xx0_uart0_resources[] = {
-	{
-		.start		= UART0_PHYS_BASE,
-		.end		= UART0_PHYS_BASE + 0xff,
-		.flags		= IORESOURCE_MEM,
-	}, {
-		.start		= IRQ_MV78XX0_UART_0,
-		.end		= IRQ_MV78XX0_UART_0,
-		.flags		= IORESOURCE_IRQ,
-	},
-};
-
-static struct platform_device mv78xx0_uart0 = {
-	.name			= "serial8250",
-	.id			= 0,
-	.dev			= {
-		.platform_data	= mv78xx0_uart0_data,
-	},
-	.resource		= mv78xx0_uart0_resources,
-	.num_resources		= ARRAY_SIZE(mv78xx0_uart0_resources),
-};
-
 void __init mv78xx0_uart0_init(void)
 {
-	platform_device_register(&mv78xx0_uart0);
+	orion_uart0_init(UART0_VIRT_BASE, UART0_PHYS_BASE,
+			 IRQ_MV78XX0_UART_0, get_tclk());
 }
 
 
 /*****************************************************************************
  * UART1
  ****************************************************************************/
-static struct plat_serial8250_port mv78xx0_uart1_data[] = {
-	{
-		.mapbase	= UART1_PHYS_BASE,
-		.membase	= (char *)UART1_VIRT_BASE,
-		.irq		= IRQ_MV78XX0_UART_1,
-		.flags		= UPF_SKIP_TEST | UPF_BOOT_AUTOCONF,
-		.iotype		= UPIO_MEM,
-		.regshift	= 2,
-		.uartclk	= 0,
-	}, {
-	},
-};
-
-static struct resource mv78xx0_uart1_resources[] = {
-	{
-		.start		= UART1_PHYS_BASE,
-		.end		= UART1_PHYS_BASE + 0xff,
-		.flags		= IORESOURCE_MEM,
-	}, {
-		.start		= IRQ_MV78XX0_UART_1,
-		.end		= IRQ_MV78XX0_UART_1,
-		.flags		= IORESOURCE_IRQ,
-	},
-};
-
-static struct platform_device mv78xx0_uart1 = {
-	.name			= "serial8250",
-	.id			= 1,
-	.dev			= {
-		.platform_data	= mv78xx0_uart1_data,
-	},
-	.resource		= mv78xx0_uart1_resources,
-	.num_resources		= ARRAY_SIZE(mv78xx0_uart1_resources),
-};
-
 void __init mv78xx0_uart1_init(void)
 {
-	platform_device_register(&mv78xx0_uart1);
+	orion_uart1_init(UART1_VIRT_BASE, UART1_PHYS_BASE,
+			 IRQ_MV78XX0_UART_1, get_tclk());
 }
 
 
 /*****************************************************************************
  * UART2
  ****************************************************************************/
-static struct plat_serial8250_port mv78xx0_uart2_data[] = {
-	{
-		.mapbase	= UART2_PHYS_BASE,
-		.membase	= (char *)UART2_VIRT_BASE,
-		.irq		= IRQ_MV78XX0_UART_2,
-		.flags		= UPF_SKIP_TEST | UPF_BOOT_AUTOCONF,
-		.iotype		= UPIO_MEM,
-		.regshift	= 2,
-		.uartclk	= 0,
-	}, {
-	},
-};
-
-static struct resource mv78xx0_uart2_resources[] = {
-	{
-		.start		= UART2_PHYS_BASE,
-		.end		= UART2_PHYS_BASE + 0xff,
-		.flags		= IORESOURCE_MEM,
-	}, {
-		.start		= IRQ_MV78XX0_UART_2,
-		.end		= IRQ_MV78XX0_UART_2,
-		.flags		= IORESOURCE_IRQ,
-	},
-};
-
-static struct platform_device mv78xx0_uart2 = {
-	.name			= "serial8250",
-	.id			= 2,
-	.dev			= {
-		.platform_data	= mv78xx0_uart2_data,
-	},
-	.resource		= mv78xx0_uart2_resources,
-	.num_resources		= ARRAY_SIZE(mv78xx0_uart2_resources),
-};
-
 void __init mv78xx0_uart2_init(void)
 {
-	platform_device_register(&mv78xx0_uart2);
+	orion_uart2_init(UART2_VIRT_BASE, UART2_PHYS_BASE,
+			 IRQ_MV78XX0_UART_2, get_tclk());
 }
 
-
 /*****************************************************************************
  * UART3
  ****************************************************************************/
-static struct plat_serial8250_port mv78xx0_uart3_data[] = {
-	{
-		.mapbase	= UART3_PHYS_BASE,
-		.membase	= (char *)UART3_VIRT_BASE,
-		.irq		= IRQ_MV78XX0_UART_3,
-		.flags		= UPF_SKIP_TEST | UPF_BOOT_AUTOCONF,
-		.iotype		= UPIO_MEM,
-		.regshift	= 2,
-		.uartclk	= 0,
-	}, {
-	},
-};
-
-static struct resource mv78xx0_uart3_resources[] = {
-	{
-		.start		= UART3_PHYS_BASE,
-		.end		= UART3_PHYS_BASE + 0xff,
-		.flags		= IORESOURCE_MEM,
-	}, {
-		.start		= IRQ_MV78XX0_UART_3,
-		.end		= IRQ_MV78XX0_UART_3,
-		.flags		= IORESOURCE_IRQ,
-	},
-};
-
-static struct platform_device mv78xx0_uart3 = {
-	.name			= "serial8250",
-	.id			= 3,
-	.dev			= {
-		.platform_data	= mv78xx0_uart3_data,
-	},
-	.resource		= mv78xx0_uart3_resources,
-	.num_resources		= ARRAY_SIZE(mv78xx0_uart3_resources),
-};
-
 void __init mv78xx0_uart3_init(void)
 {
-	platform_device_register(&mv78xx0_uart3);
+	orion_uart3_init(UART3_VIRT_BASE, UART3_PHYS_BASE,
+			 IRQ_MV78XX0_UART_3, get_tclk());
 }
 
-
 /*****************************************************************************
  * Time handling
  ****************************************************************************/
@@ -895,13 +400,4 @@
 #ifdef CONFIG_CACHE_FEROCEON_L2
 	feroceon_l2_init(is_l2_writethrough());
 #endif
-
-	mv78xx0_ge00_shared_data.t_clk = tclk;
-	mv78xx0_ge01_shared_data.t_clk = tclk;
-	mv78xx0_ge10_shared_data.t_clk = tclk;
-	mv78xx0_ge11_shared_data.t_clk = tclk;
-	mv78xx0_uart0_data[0].uartclk = tclk;
-	mv78xx0_uart1_data[0].uartclk = tclk;
-	mv78xx0_uart2_data[0].uartclk = tclk;
-	mv78xx0_uart3_data[0].uartclk = tclk;
 }
diff -druN linux-2.6.39-libre/arch/arm/mach-mv78xx0/mpp.c linux-3.0-rc7-libre/arch/arm/mach-mv78xx0/mpp.c
--- linux-2.6.39-libre/arch/arm/mach-mv78xx0/mpp.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-mv78xx0/mpp.c	2011-07-11 19:51:52.000000000 -0400
@@ -12,6 +12,7 @@
 #include <linux/init.h>
 #include <linux/mbus.h>
 #include <linux/io.h>
+#include <plat/mpp.h>
 #include <asm/gpio.h>
 #include <mach/hardware.h>
 #include "common.h"
@@ -31,61 +32,8 @@
 	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;
-
-	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");
-
-	for ( ; *mpp_list; 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);
-	}
-
-	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");
+	orion_mpp_conf(mpp_list, mv78xx0_variant(),
+		       MPP_MAX, DEV_BUS_VIRT_BASE);
 }
diff -druN linux-2.6.39-libre/arch/arm/mach-mv78xx0/mpp.h linux-3.0-rc7-libre/arch/arm/mach-mv78xx0/mpp.h
--- linux-2.6.39-libre/arch/arm/mach-mv78xx0/mpp.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-mv78xx0/mpp.h	2011-07-11 19:51:52.000000000 -0400
@@ -19,14 +19,8 @@
     /* 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)
diff -druN linux-2.6.39-libre/arch/arm/mach-mx3/clock-imx31.c linux-3.0-rc7-libre/arch/arm/mach-mx3/clock-imx31.c
--- linux-2.6.39-libre/arch/arm/mach-mx3/clock-imx31.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-mx3/clock-imx31.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,630 +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 <linux/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, NULL, &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("imx31-cspi.0", NULL, cspi1_clk)
-	_REGISTER_CLOCK("imx31-cspi.1", NULL, cspi2_clk)
-	_REGISTER_CLOCK("imx31-cspi.2", NULL, cspi3_clk)
-	_REGISTER_CLOCK(NULL, "gpt", gpt_clk)
-	_REGISTER_CLOCK(NULL, "pwm", pwm_clk)
-	_REGISTER_CLOCK("imx2-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("imx-sdma", NULL, 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() >= IMX_CHIP_REVISION_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 -druN linux-2.6.39-libre/arch/arm/mach-mx3/clock-imx35.c linux-3.0-rc7-libre/arch/arm/mach-mx3/clock-imx35.c
--- linux-2.6.39-libre/arch/arm/mach-mx3/clock-imx35.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-mx3/clock-imx35.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,550 +0,0 @@
-/*
- * Copyright (C) 2009 by Sascha Hauer, Pengutronix
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
- * MA 02110-1301, USA.
- */
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/list.h>
-#include <linux/clk.h>
-#include <linux/io.h>
-#include <linux/clkdev.h>
-
-#include <mach/clock.h>
-#include <mach/hardware.h>
-#include <mach/common.h>
-
-#define CCM_BASE	MX35_IO_ADDRESS(MX35_CCM_BASE_ADDR)
-
-#define CCM_CCMR        0x00
-#define CCM_PDR0        0x04
-#define CCM_PDR1        0x08
-#define CCM_PDR2        0x0C
-#define CCM_PDR3        0x10
-#define CCM_PDR4        0x14
-#define CCM_RCSR        0x18
-#define CCM_MPCTL       0x1C
-#define CCM_PPCTL       0x20
-#define CCM_ACMR        0x24
-#define CCM_COSR        0x28
-#define CCM_CGR0        0x2C
-#define CCM_CGR1        0x30
-#define CCM_CGR2        0x34
-#define CCM_CGR3        0x38
-
-#ifdef HAVE_SET_RATE_SUPPORT
-static void calc_dividers(u32 div, u32 *pre, u32 *post, u32 maxpost)
-{
-	u32 min_pre, temp_pre, old_err, err;
-
-	min_pre = (div - 1) / maxpost + 1;
-	old_err = 8;
-
-	for (temp_pre = 8; temp_pre >= min_pre; temp_pre--) {
-		if (div > (temp_pre * maxpost))
-			break;
-
-		if (div < (temp_pre * temp_pre))
-			continue;
-
-		err = div % temp_pre;
-
-		if (err == 0) {
-			*pre = temp_pre;
-			break;
-		}
-
-		err = temp_pre - err;
-
-		if (err < old_err) {
-			old_err = err;
-			*pre = temp_pre;
-		}
-	}
-
-	*post = (div + *pre - 1) / *pre;
-}
-
-/* get the best values for a 3-bit divider combined with a 6-bit divider */
-static void calc_dividers_3_6(u32 div, u32 *pre, u32 *post)
-{
-	if (div >= 512) {
-		*pre = 8;
-		*post = 64;
-	} else if (div >= 64) {
-		calc_dividers(div, pre, post, 64);
-	} else if (div <= 8) {
-		*pre = div;
-		*post = 1;
-	} else {
-		*pre = 1;
-		*post = div;
-	}
-}
-
-/* get the best values for two cascaded 3-bit dividers */
-static void calc_dividers_3_3(u32 div, u32 *pre, u32 *post)
-{
-	if (div >= 64) {
-		*pre = *post = 8;
-	} else if (div > 8) {
-		calc_dividers(div, pre, post, 8);
-	} else {
-		*pre = 1;
-		*post = div;
-	}
-}
-#endif
-
-static unsigned long get_rate_mpll(void)
-{
-	ulong mpctl = __raw_readl(CCM_BASE + CCM_MPCTL);
-
-	return mxc_decode_pll(mpctl, 24000000);
-}
-
-static unsigned long get_rate_ppll(void)
-{
-	ulong ppctl = __raw_readl(CCM_BASE + CCM_PPCTL);
-
-	return mxc_decode_pll(ppctl, 24000000);
-}
-
-struct arm_ahb_div {
-	unsigned char arm, ahb, sel;
-};
-
-static struct arm_ahb_div clk_consumer[] = {
-	{ .arm = 1, .ahb = 4, .sel = 0},
-	{ .arm = 1, .ahb = 3, .sel = 1},
-	{ .arm = 2, .ahb = 2, .sel = 0},
-	{ .arm = 0, .ahb = 0, .sel = 0},
-	{ .arm = 0, .ahb = 0, .sel = 0},
-	{ .arm = 0, .ahb = 0, .sel = 0},
-	{ .arm = 4, .ahb = 1, .sel = 0},
-	{ .arm = 1, .ahb = 5, .sel = 0},
-	{ .arm = 1, .ahb = 8, .sel = 0},
-	{ .arm = 1, .ahb = 6, .sel = 1},
-	{ .arm = 2, .ahb = 4, .sel = 0},
-	{ .arm = 0, .ahb = 0, .sel = 0},
-	{ .arm = 0, .ahb = 0, .sel = 0},
-	{ .arm = 0, .ahb = 0, .sel = 0},
-	{ .arm = 4, .ahb = 2, .sel = 0},
-	{ .arm = 0, .ahb = 0, .sel = 0},
-};
-
-static unsigned long get_rate_arm(void)
-{
-	unsigned long pdr0 = __raw_readl(CCM_BASE + CCM_PDR0);
-	struct arm_ahb_div *aad;
-	unsigned long fref = get_rate_mpll();
-
-	aad = &clk_consumer[(pdr0 >> 16) & 0xf];
-	if (aad->sel)
-		fref = fref * 3 / 4;
-
-	return fref / aad->arm;
-}
-
-static unsigned long get_rate_ahb(struct clk *clk)
-{
-	unsigned long pdr0 = __raw_readl(CCM_BASE + CCM_PDR0);
-	struct arm_ahb_div *aad;
-	unsigned long fref = get_rate_arm();
-
-	aad = &clk_consumer[(pdr0 >> 16) & 0xf];
-
-	return fref / aad->ahb;
-}
-
-static unsigned long get_rate_ipg(struct clk *clk)
-{
-	return get_rate_ahb(NULL) >> 1;
-}
-
-static unsigned long get_rate_uart(struct clk *clk)
-{
-	unsigned long pdr3 = __raw_readl(CCM_BASE + CCM_PDR3);
-	unsigned long pdr4 = __raw_readl(CCM_BASE + CCM_PDR4);
-	unsigned long div = ((pdr4 >> 10) & 0x3f) + 1;
-
-	if (pdr3 & (1 << 14))
-		return get_rate_arm() / div;
-	else
-		return get_rate_ppll() / div;
-}
-
-static unsigned long get_rate_sdhc(struct clk *clk)
-{
-	unsigned long pdr3 = __raw_readl(CCM_BASE + CCM_PDR3);
-	unsigned long div, rate;
-
-	if (pdr3 & (1 << 6))
-		rate = get_rate_arm();
-	else
-		rate = get_rate_ppll();
-
-	switch (clk->id) {
-	default:
-	case 0:
-		div = pdr3 & 0x3f;
-		break;
-	case 1:
-		div = (pdr3 >> 8) & 0x3f;
-		break;
-	case 2:
-		div = (pdr3 >> 16) & 0x3f;
-		break;
-	}
-
-	return rate / (div + 1);
-}
-
-static unsigned long get_rate_mshc(struct clk *clk)
-{
-	unsigned long pdr1 = __raw_readl(CCM_BASE + CCM_PDR1);
-	unsigned long div1, div2, rate;
-
-	if (pdr1 & (1 << 7))
-		rate = get_rate_arm();
-	else
-		rate = get_rate_ppll();
-
-	div1 = (pdr1 >> 29) & 0x7;
-	div2 = (pdr1 >> 22) & 0x3f;
-
-	return rate / ((div1 + 1) * (div2 + 1));
-}
-
-static unsigned long get_rate_ssi(struct clk *clk)
-{
-	unsigned long pdr2 = __raw_readl(CCM_BASE + CCM_PDR2);
-	unsigned long div1, div2, rate;
-
-	if (pdr2 & (1 << 6))
-		rate = get_rate_arm();
-	else
-		rate = get_rate_ppll();
-
-	switch (clk->id) {
-	default:
-	case 0:
-		div1 = pdr2 & 0x3f;
-		div2 = (pdr2 >> 24) & 0x7;
-		break;
-	case 1:
-		div1 = (pdr2 >> 8) & 0x3f;
-		div2 = (pdr2 >> 27) & 0x7;
-		break;
-	}
-
-	return rate / ((div1 + 1) * (div2 + 1));
-}
-
-static unsigned long get_rate_csi(struct clk *clk)
-{
-	unsigned long pdr2 = __raw_readl(CCM_BASE + CCM_PDR2);
-	unsigned long rate;
-
-	if (pdr2 & (1 << 7))
-		rate = get_rate_arm();
-	else
-		rate = get_rate_ppll();
-
-	return rate / (((pdr2 >> 16) & 0x3f) + 1);
-}
-
-static unsigned long get_rate_otg(struct clk *clk)
-{
-	unsigned long pdr4 = __raw_readl(CCM_BASE + CCM_PDR4);
-	unsigned long rate;
-
-	if (pdr4 & (1 << 9))
-		rate = get_rate_arm();
-	else
-		rate = get_rate_ppll();
-
-	return rate / (((pdr4 >> 22) & 0x3f) + 1);
-}
-
-static unsigned long get_rate_ipg_per(struct clk *clk)
-{
-	unsigned long pdr0 = __raw_readl(CCM_BASE + CCM_PDR0);
-	unsigned long pdr4 = __raw_readl(CCM_BASE + CCM_PDR4);
-	unsigned long div;
-
-	if (pdr0 & (1 << 26)) {
-		div = (pdr4 >> 16) & 0x3f;
-		return get_rate_arm() / (div + 1);
-	} else {
-		div = (pdr0 >> 12) & 0x7;
-		return get_rate_ahb(NULL) / (div + 1);
-	}
-}
-
-static unsigned long get_rate_hsp(struct clk *clk)
-{
-	unsigned long hsp_podf = (__raw_readl(CCM_BASE + CCM_PDR0) >> 20) & 0x03;
-	unsigned long fref = get_rate_mpll();
-
-	if (fref > 400 * 1000 * 1000) {
-		switch (hsp_podf) {
-		case 0:
-			return fref >> 2;
-		case 1:
-			return fref >> 3;
-		case 2:
-			return fref / 3;
-		}
-	} else {
-		switch (hsp_podf) {
-		case 0:
-		case 2:
-			return fref / 3;
-		case 1:
-			return fref / 6;
-		}
-	}
-
-	return 0;
-}
-
-static int clk_cgr_enable(struct clk *clk)
-{
-	u32 reg;
-
-	reg = __raw_readl(clk->enable_reg);
-	reg |= 3 << clk->enable_shift;
-	__raw_writel(reg, clk->enable_reg);
-
-	return 0;
-}
-
-static void clk_cgr_disable(struct clk *clk)
-{
-	u32 reg;
-
-	reg = __raw_readl(clk->enable_reg);
-	reg &= ~(3 << clk->enable_shift);
-	__raw_writel(reg, clk->enable_reg);
-}
-
-#define DEFINE_CLOCK(name, i, er, es, gr, sr)		\
-	static struct clk name = {			\
-		.id		= i,			\
-		.enable_reg	= CCM_BASE + er,	\
-		.enable_shift	= es,			\
-		.get_rate	= gr,			\
-		.set_rate	= sr,			\
-		.enable		= clk_cgr_enable,	\
-		.disable	= clk_cgr_disable,	\
-	}
-
-DEFINE_CLOCK(asrc_clk,   0, CCM_CGR0,  0, NULL, NULL);
-DEFINE_CLOCK(ata_clk,    0, CCM_CGR0,  2, get_rate_ipg, NULL);
-/* DEFINE_CLOCK(audmux_clk, 0, CCM_CGR0,  4, NULL, NULL); */
-DEFINE_CLOCK(can1_clk,   0, CCM_CGR0,  6, get_rate_ipg, NULL);
-DEFINE_CLOCK(can2_clk,   1, CCM_CGR0,  8, get_rate_ipg, NULL);
-DEFINE_CLOCK(cspi1_clk,  0, CCM_CGR0, 10, get_rate_ipg, NULL);
-DEFINE_CLOCK(cspi2_clk,  1, CCM_CGR0, 12, get_rate_ipg, NULL);
-DEFINE_CLOCK(ect_clk,    0, CCM_CGR0, 14, get_rate_ipg, NULL);
-DEFINE_CLOCK(edio_clk,   0, CCM_CGR0, 16, NULL, NULL);
-DEFINE_CLOCK(emi_clk,    0, CCM_CGR0, 18, get_rate_ipg, NULL);
-DEFINE_CLOCK(epit1_clk,  0, CCM_CGR0, 20, get_rate_ipg, NULL);
-DEFINE_CLOCK(epit2_clk,  1, CCM_CGR0, 22, get_rate_ipg, NULL);
-DEFINE_CLOCK(esai_clk,   0, CCM_CGR0, 24, NULL, NULL);
-DEFINE_CLOCK(esdhc1_clk, 0, CCM_CGR0, 26, get_rate_sdhc, NULL);
-DEFINE_CLOCK(esdhc2_clk, 1, CCM_CGR0, 28, get_rate_sdhc, NULL);
-DEFINE_CLOCK(esdhc3_clk, 2, CCM_CGR0, 30, get_rate_sdhc, NULL);
-
-DEFINE_CLOCK(fec_clk,    0, CCM_CGR1,  0, get_rate_ipg, NULL);
-DEFINE_CLOCK(gpio1_clk,  0, CCM_CGR1,  2, NULL, NULL);
-DEFINE_CLOCK(gpio2_clk,  1, CCM_CGR1,  4, NULL, NULL);
-DEFINE_CLOCK(gpio3_clk,  2, CCM_CGR1,  6, NULL, NULL);
-DEFINE_CLOCK(gpt_clk,    0, CCM_CGR1,  8, get_rate_ipg, NULL);
-DEFINE_CLOCK(i2c1_clk,   0, CCM_CGR1, 10, get_rate_ipg_per, NULL);
-DEFINE_CLOCK(i2c2_clk,   1, CCM_CGR1, 12, get_rate_ipg_per, NULL);
-DEFINE_CLOCK(i2c3_clk,   2, CCM_CGR1, 14, get_rate_ipg_per, NULL);
-DEFINE_CLOCK(iomuxc_clk, 0, CCM_CGR1, 16, NULL, NULL);
-DEFINE_CLOCK(ipu_clk,    0, CCM_CGR1, 18, get_rate_hsp, NULL);
-DEFINE_CLOCK(kpp_clk,    0, CCM_CGR1, 20, get_rate_ipg, NULL);
-DEFINE_CLOCK(mlb_clk,    0, CCM_CGR1, 22, get_rate_ahb, NULL);
-DEFINE_CLOCK(mshc_clk,   0, CCM_CGR1, 24, get_rate_mshc, NULL);
-DEFINE_CLOCK(owire_clk,  0, CCM_CGR1, 26, get_rate_ipg_per, NULL);
-DEFINE_CLOCK(pwm_clk,    0, CCM_CGR1, 28, get_rate_ipg_per, NULL);
-DEFINE_CLOCK(rngc_clk,   0, CCM_CGR1, 30, get_rate_ipg, NULL);
-
-DEFINE_CLOCK(rtc_clk,    0, CCM_CGR2,  0, get_rate_ipg, NULL);
-DEFINE_CLOCK(rtic_clk,   0, CCM_CGR2,  2, get_rate_ahb, NULL);
-DEFINE_CLOCK(scc_clk,    0, CCM_CGR2,  4, get_rate_ipg, NULL);
-DEFINE_CLOCK(sdma_clk,   0, CCM_CGR2,  6, NULL, NULL);
-DEFINE_CLOCK(spba_clk,   0, CCM_CGR2,  8, get_rate_ipg, NULL);
-DEFINE_CLOCK(spdif_clk,  0, CCM_CGR2, 10, NULL, NULL);
-DEFINE_CLOCK(ssi1_clk,   0, CCM_CGR2, 12, get_rate_ssi, NULL);
-DEFINE_CLOCK(ssi2_clk,   1, CCM_CGR2, 14, get_rate_ssi, NULL);
-DEFINE_CLOCK(uart1_clk,  0, CCM_CGR2, 16, get_rate_uart, NULL);
-DEFINE_CLOCK(uart2_clk,  1, CCM_CGR2, 18, get_rate_uart, NULL);
-DEFINE_CLOCK(uart3_clk,  2, CCM_CGR2, 20, get_rate_uart, NULL);
-DEFINE_CLOCK(usbotg_clk, 0, CCM_CGR2, 22, get_rate_otg, NULL);
-DEFINE_CLOCK(wdog_clk,   0, CCM_CGR2, 24, NULL, NULL);
-DEFINE_CLOCK(max_clk,    0, CCM_CGR2, 26, NULL, NULL);
-DEFINE_CLOCK(audmux_clk, 0, CCM_CGR2, 30, NULL, NULL);
-
-DEFINE_CLOCK(csi_clk,    0, CCM_CGR3,  0, get_rate_csi, NULL);
-DEFINE_CLOCK(iim_clk,    0, CCM_CGR3,  2, NULL, NULL);
-DEFINE_CLOCK(gpu2d_clk,  0, CCM_CGR3,  4, NULL, NULL);
-
-DEFINE_CLOCK(usbahb_clk, 0, 0,         0, get_rate_ahb, NULL);
-
-static int clk_dummy_enable(struct clk *clk)
-{
-	return 0;
-}
-
-static void clk_dummy_disable(struct clk *clk)
-{
-}
-
-static unsigned long get_rate_nfc(struct clk *clk)
-{
-	unsigned long div1;
-
-	div1 = (__raw_readl(CCM_BASE + CCM_PDR4) >> 28) + 1;
-
-	return get_rate_ahb(NULL) / div1;
-}
-
-/* NAND Controller: It seems it can't be disabled */
-static struct clk nfc_clk = {
-	.id		= 0,
-	.enable_reg	= 0,
-	.enable_shift	= 0,
-	.get_rate	= get_rate_nfc,
-	.set_rate	= NULL, /* set_rate_nfc, */
-	.enable		= clk_dummy_enable,
-	.disable	= clk_dummy_disable
-};
-
-#define _REGISTER_CLOCK(d, n, c)	\
-	{				\
-		.dev_id = d,		\
-		.con_id = n,		\
-		.clk = &c,		\
-	},
-
-static struct clk_lookup lookups[] = {
-	_REGISTER_CLOCK(NULL, "asrc", asrc_clk)
-	_REGISTER_CLOCK(NULL, "ata", ata_clk)
-	_REGISTER_CLOCK("flexcan.0", NULL, can1_clk)
-	_REGISTER_CLOCK("flexcan.1", NULL, can2_clk)
-	_REGISTER_CLOCK("imx35-cspi.0", NULL, cspi1_clk)
-	_REGISTER_CLOCK("imx35-cspi.1", NULL, cspi2_clk)
-	_REGISTER_CLOCK(NULL, "ect", ect_clk)
-	_REGISTER_CLOCK(NULL, "edio", edio_clk)
-	_REGISTER_CLOCK(NULL, "emi", emi_clk)
-	_REGISTER_CLOCK("imx-epit.0", NULL, epit1_clk)
-	_REGISTER_CLOCK("imx-epit.1", NULL, epit2_clk)
-	_REGISTER_CLOCK(NULL, "esai", esai_clk)
-	_REGISTER_CLOCK("sdhci-esdhc-imx.0", NULL, esdhc1_clk)
-	_REGISTER_CLOCK("sdhci-esdhc-imx.1", NULL, esdhc2_clk)
-	_REGISTER_CLOCK("sdhci-esdhc-imx.2", NULL, esdhc3_clk)
-	_REGISTER_CLOCK("fec.0", NULL, fec_clk)
-	_REGISTER_CLOCK(NULL, "gpio", gpio1_clk)
-	_REGISTER_CLOCK(NULL, "gpio", gpio2_clk)
-	_REGISTER_CLOCK(NULL, "gpio", gpio3_clk)
-	_REGISTER_CLOCK("gpt.0", NULL, gpt_clk)
-	_REGISTER_CLOCK("imx-i2c.0", NULL, i2c1_clk)
-	_REGISTER_CLOCK("imx-i2c.1", NULL, i2c2_clk)
-	_REGISTER_CLOCK("imx-i2c.2", NULL, i2c3_clk)
-	_REGISTER_CLOCK(NULL, "iomuxc", iomuxc_clk)
-	_REGISTER_CLOCK("ipu-core", NULL, ipu_clk)
-	_REGISTER_CLOCK("mx3_sdc_fb", NULL, ipu_clk)
-	_REGISTER_CLOCK(NULL, "kpp", kpp_clk)
-	_REGISTER_CLOCK(NULL, "mlb", mlb_clk)
-	_REGISTER_CLOCK(NULL, "mshc", mshc_clk)
-	_REGISTER_CLOCK("mxc_w1", NULL, owire_clk)
-	_REGISTER_CLOCK(NULL, "pwm", pwm_clk)
-	_REGISTER_CLOCK(NULL, "rngc", rngc_clk)
-	_REGISTER_CLOCK(NULL, "rtc", rtc_clk)
-	_REGISTER_CLOCK(NULL, "rtic", rtic_clk)
-	_REGISTER_CLOCK(NULL, "scc", scc_clk)
-	_REGISTER_CLOCK("imx-sdma", NULL, sdma_clk)
-	_REGISTER_CLOCK(NULL, "spba", spba_clk)
-	_REGISTER_CLOCK(NULL, "spdif", spdif_clk)
-	_REGISTER_CLOCK("imx-ssi.0", NULL, ssi1_clk)
-	_REGISTER_CLOCK("imx-ssi.1", NULL, ssi2_clk)
-	_REGISTER_CLOCK("imx-uart.0", NULL, uart1_clk)
-	_REGISTER_CLOCK("imx-uart.1", NULL, uart2_clk)
-	_REGISTER_CLOCK("imx-uart.2", NULL, uart3_clk)
-	_REGISTER_CLOCK("mxc-ehci.0", "usb", usbotg_clk)
-	_REGISTER_CLOCK("mxc-ehci.1", "usb", usbotg_clk)
-	_REGISTER_CLOCK("mxc-ehci.2", "usb", usbotg_clk)
-	_REGISTER_CLOCK("fsl-usb2-udc", "usb", usbotg_clk)
-	_REGISTER_CLOCK("fsl-usb2-udc", "usb_ahb", usbahb_clk)
-	_REGISTER_CLOCK("imx2-wdt.0", NULL, wdog_clk)
-	_REGISTER_CLOCK(NULL, "max", max_clk)
-	_REGISTER_CLOCK(NULL, "audmux", audmux_clk)
-	_REGISTER_CLOCK(NULL, "csi", csi_clk)
-	_REGISTER_CLOCK(NULL, "iim", iim_clk)
-	_REGISTER_CLOCK(NULL, "gpu2d", gpu2d_clk)
-	_REGISTER_CLOCK("mxc_nand.0", NULL, nfc_clk)
-};
-
-int __init mx35_clocks_init()
-{
-	unsigned int cgr2 = 3 << 26, cgr3 = 0;
-
-#if defined(CONFIG_DEBUG_LL) && !defined(CONFIG_DEBUG_ICEDCC)
-	cgr2 |= 3 << 16;
-#endif
-
-	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
-	 */
-	__raw_writel((3 << 18), CCM_BASE + CCM_CGR0);
-	__raw_writel((3 << 2) | (3 << 4) | (3 << 6) | (3 << 8) | (3 << 16),
-			CCM_BASE + CCM_CGR1);
-
-	/*
-	 * Check if we came up in internal boot mode. If yes, we need some
-	 * extra clocks turned on, otherwise the MX35 boot ROM code will
-	 * hang after a watchdog reset.
-	 */
-	if (!(__raw_readl(CCM_BASE + CCM_RCSR) & (3 << 10))) {
-		/* Additionally turn on UART1, SCC, and IIM clocks */
-		cgr2 |= 3 << 16 | 3 << 4;
-		cgr3 |= 3 << 2;
-	}
-
-	__raw_writel(cgr2, CCM_BASE + CCM_CGR2);
-	__raw_writel(cgr3, CCM_BASE + CCM_CGR3);
-
-	clk_enable(&iim_clk);
-	mx35_read_cpu_rev();
-
-#ifdef CONFIG_MXC_USE_EPIT
-	epit_timer_init(&epit1_clk,
-			MX35_IO_ADDRESS(MX35_EPIT1_BASE_ADDR), MX35_INT_EPIT1);
-#else
-	mxc_timer_init(&gpt_clk,
-			MX35_IO_ADDRESS(MX35_GPT1_BASE_ADDR), MX35_INT_GPT);
-#endif
-
-	return 0;
-}
-
diff -druN linux-2.6.39-libre/arch/arm/mach-mx3/cpu.c linux-3.0-rc7-libre/arch/arm/mach-mx3/cpu.c
--- linux-2.6.39-libre/arch/arm/mach-mx3/cpu.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-mx3/cpu.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,89 +0,0 @@
-/*
- * MX3 CPU type detection
- *
- * Copyright (c) 2009 Daniel Mack <daniel@caiaq.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
-
-#include <linux/module.h>
-#include <linux/io.h>
-#include <mach/hardware.h>
-#include <mach/iim.h>
-
-unsigned int mx31_cpu_rev;
-EXPORT_SYMBOL(mx31_cpu_rev);
-
-struct mx3_cpu_type {
-	u8 srev;
-	const char *name;
-	const char *v;
-	unsigned int rev;
-};
-
-static struct mx3_cpu_type mx31_cpu_type[] __initdata = {
-	{ .srev = 0x00, .name = "i.MX31(L)", .v = "1.0",  .rev = IMX_CHIP_REVISION_1_0	},
-	{ .srev = 0x10, .name = "i.MX31",    .v = "1.1",  .rev = IMX_CHIP_REVISION_1_1	},
-	{ .srev = 0x11, .name = "i.MX31L",   .v = "1.1",  .rev = IMX_CHIP_REVISION_1_1	},
-	{ .srev = 0x12, .name = "i.MX31",    .v = "1.15", .rev = IMX_CHIP_REVISION_1_1	},
-	{ .srev = 0x13, .name = "i.MX31L",   .v = "1.15", .rev = IMX_CHIP_REVISION_1_1	},
-	{ .srev = 0x14, .name = "i.MX31",    .v = "1.2",  .rev = IMX_CHIP_REVISION_1_2	},
-	{ .srev = 0x15, .name = "i.MX31L",   .v = "1.2",  .rev = IMX_CHIP_REVISION_1_2	},
-	{ .srev = 0x28, .name = "i.MX31",    .v = "2.0",  .rev = IMX_CHIP_REVISION_2_0	},
-	{ .srev = 0x29, .name = "i.MX31L",   .v = "2.0",  .rev = IMX_CHIP_REVISION_2_0	},
-};
-
-void __init mx31_read_cpu_rev(void)
-{
-	u32 i, srev;
-
-	/* read SREV register from IIM module */
-	srev = __raw_readl(MX31_IO_ADDRESS(MX31_IIM_BASE_ADDR + MXC_IIMSREV));
-
-	for (i = 0; i < ARRAY_SIZE(mx31_cpu_type); i++)
-		if (srev == mx31_cpu_type[i].srev) {
-			printk(KERN_INFO
-				"CPU identified as %s, silicon rev %s\n",
-				mx31_cpu_type[i].name, mx31_cpu_type[i].v);
-
-			mx31_cpu_rev = mx31_cpu_type[i].rev;
-			return;
-		}
-
-	mx31_cpu_rev = IMX_CHIP_REVISION_UNKNOWN;
-
-	printk(KERN_WARNING "Unknown CPU identifier. srev = %02x\n", srev);
-}
-
-unsigned int mx35_cpu_rev;
-EXPORT_SYMBOL(mx35_cpu_rev);
-
-void __init mx35_read_cpu_rev(void)
-{
-	u32 rev;
-	char *srev;
-
-	rev = __raw_readl(MX35_IO_ADDRESS(MX35_IIM_BASE_ADDR + MXC_IIMSREV));
-	switch (rev) {
-	case 0x00:
-		mx35_cpu_rev = IMX_CHIP_REVISION_1_0;
-		srev = "1.0";
-		break;
-	case 0x10:
-		mx35_cpu_rev = IMX_CHIP_REVISION_2_0;
-		srev = "2.0";
-		break;
-	case 0x11:
-		mx35_cpu_rev = IMX_CHIP_REVISION_2_1;
-		srev = "2.1";
-		break;
-	default:
-		mx35_cpu_rev = IMX_CHIP_REVISION_UNKNOWN;
-		srev = "unknown";
-	}
-
-	printk(KERN_INFO "CPU identified as i.MX35, silicon rev %s\n", srev);
-}
diff -druN linux-2.6.39-libre/arch/arm/mach-mx3/crm_regs.h linux-3.0-rc7-libre/arch/arm/mach-mx3/crm_regs.h
--- linux-2.6.39-libre/arch/arm/mach-mx3/crm_regs.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-mx3/crm_regs.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,248 +0,0 @@
-/*
- * Copyright 2004-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.
- */
-
-#ifndef __ARCH_ARM_MACH_MX3_CRM_REGS_H__
-#define __ARCH_ARM_MACH_MX3_CRM_REGS_H__
-
-#define CKIH_CLK_FREQ           26000000
-#define CKIH_CLK_FREQ_27MHZ     27000000
-#define CKIL_CLK_FREQ           32768
-
-#define MXC_CCM_BASE		MX31_IO_ADDRESS(MX31_CCM_BASE_ADDR)
-
-/* Register addresses */
-#define MXC_CCM_CCMR		(MXC_CCM_BASE + 0x00)
-#define MXC_CCM_PDR0		(MXC_CCM_BASE + 0x04)
-#define MXC_CCM_PDR1		(MXC_CCM_BASE + 0x08)
-#define MXC_CCM_RCSR		(MXC_CCM_BASE + 0x0C)
-#define MXC_CCM_MPCTL		(MXC_CCM_BASE + 0x10)
-#define MXC_CCM_UPCTL		(MXC_CCM_BASE + 0x14)
-#define MXC_CCM_SRPCTL		(MXC_CCM_BASE + 0x18)
-#define MXC_CCM_COSR		(MXC_CCM_BASE + 0x1C)
-#define MXC_CCM_CGR0		(MXC_CCM_BASE + 0x20)
-#define MXC_CCM_CGR1		(MXC_CCM_BASE + 0x24)
-#define MXC_CCM_CGR2		(MXC_CCM_BASE + 0x28)
-#define MXC_CCM_WIMR		(MXC_CCM_BASE + 0x2C)
-#define MXC_CCM_LDC		(MXC_CCM_BASE + 0x30)
-#define MXC_CCM_DCVR0		(MXC_CCM_BASE + 0x34)
-#define MXC_CCM_DCVR1		(MXC_CCM_BASE + 0x38)
-#define MXC_CCM_DCVR2		(MXC_CCM_BASE + 0x3C)
-#define MXC_CCM_DCVR3		(MXC_CCM_BASE + 0x40)
-#define MXC_CCM_LTR0		(MXC_CCM_BASE + 0x44)
-#define MXC_CCM_LTR1		(MXC_CCM_BASE + 0x48)
-#define MXC_CCM_LTR2		(MXC_CCM_BASE + 0x4C)
-#define MXC_CCM_LTR3		(MXC_CCM_BASE + 0x50)
-#define MXC_CCM_LTBR0		(MXC_CCM_BASE + 0x54)
-#define MXC_CCM_LTBR1		(MXC_CCM_BASE + 0x58)
-#define MXC_CCM_PMCR0		(MXC_CCM_BASE + 0x5C)
-#define MXC_CCM_PMCR1		(MXC_CCM_BASE + 0x60)
-#define MXC_CCM_PDR2		(MXC_CCM_BASE + 0x64)
-
-/* Register bit definitions */
-#define MXC_CCM_CCMR_WBEN                       (1 << 27)
-#define MXC_CCM_CCMR_CSCS                       (1 << 25)
-#define MXC_CCM_CCMR_PERCS                      (1 << 24)
-#define MXC_CCM_CCMR_SSI1S_OFFSET               18
-#define MXC_CCM_CCMR_SSI1S_MASK                 (0x3 << 18)
-#define MXC_CCM_CCMR_SSI2S_OFFSET               21
-#define MXC_CCM_CCMR_SSI2S_MASK                 (0x3 << 21)
-#define MXC_CCM_CCMR_LPM_OFFSET                 14
-#define MXC_CCM_CCMR_LPM_MASK                   (0x3 << 14)
-#define MXC_CCM_CCMR_FIRS_OFFSET                11
-#define MXC_CCM_CCMR_FIRS_MASK                  (0x3 << 11)
-#define MXC_CCM_CCMR_UPE                        (1 << 9)
-#define MXC_CCM_CCMR_SPE                        (1 << 8)
-#define MXC_CCM_CCMR_MDS                        (1 << 7)
-#define MXC_CCM_CCMR_SBYCS                      (1 << 4)
-#define MXC_CCM_CCMR_MPE                        (1 << 3)
-#define MXC_CCM_CCMR_PRCS_OFFSET                1
-#define MXC_CCM_CCMR_PRCS_MASK                  (0x3 << 1)
-
-#define MXC_CCM_PDR0_CSI_PODF_OFFSET            26
-#define MXC_CCM_PDR0_CSI_PODF_MASK              (0x3F << 26)
-#define MXC_CCM_PDR0_CSI_PRDF_OFFSET            23
-#define MXC_CCM_PDR0_CSI_PRDF_MASK              (0x7 << 23)
-#define MXC_CCM_PDR0_PER_PODF_OFFSET            16
-#define MXC_CCM_PDR0_PER_PODF_MASK              (0x1F << 16)
-#define MXC_CCM_PDR0_HSP_PODF_OFFSET            11
-#define MXC_CCM_PDR0_HSP_PODF_MASK              (0x7 << 11)
-#define MXC_CCM_PDR0_NFC_PODF_OFFSET            8
-#define MXC_CCM_PDR0_NFC_PODF_MASK              (0x7 << 8)
-#define MXC_CCM_PDR0_IPG_PODF_OFFSET            6
-#define MXC_CCM_PDR0_IPG_PODF_MASK              (0x3 << 6)
-#define MXC_CCM_PDR0_MAX_PODF_OFFSET            3
-#define MXC_CCM_PDR0_MAX_PODF_MASK              (0x7 << 3)
-#define MXC_CCM_PDR0_MCU_PODF_OFFSET            0
-#define MXC_CCM_PDR0_MCU_PODF_MASK              0x7
-
-#define MXC_CCM_PDR1_USB_PRDF_OFFSET            30
-#define MXC_CCM_PDR1_USB_PRDF_MASK              (0x3 << 30)
-#define MXC_CCM_PDR1_USB_PODF_OFFSET            27
-#define MXC_CCM_PDR1_USB_PODF_MASK              (0x7 << 27)
-#define MXC_CCM_PDR1_FIRI_PRE_PODF_OFFSET       24
-#define MXC_CCM_PDR1_FIRI_PRE_PODF_MASK         (0x7 << 24)
-#define MXC_CCM_PDR1_FIRI_PODF_OFFSET           18
-#define MXC_CCM_PDR1_FIRI_PODF_MASK             (0x3F << 18)
-#define MXC_CCM_PDR1_SSI2_PRE_PODF_OFFSET       15
-#define MXC_CCM_PDR1_SSI2_PRE_PODF_MASK         (0x7 << 15)
-#define MXC_CCM_PDR1_SSI2_PODF_OFFSET           9
-#define MXC_CCM_PDR1_SSI2_PODF_MASK             (0x3F << 9)
-#define MXC_CCM_PDR1_SSI1_PRE_PODF_OFFSET       6
-#define MXC_CCM_PDR1_SSI1_PRE_PODF_MASK         (0x7 << 6)
-#define MXC_CCM_PDR1_SSI1_PODF_OFFSET           0
-#define MXC_CCM_PDR1_SSI1_PODF_MASK             0x3F
-
-/* Bit definitions for RCSR */
-#define MXC_CCM_RCSR_NF16B			0x80000000
-
-/*
- * LTR0 register offsets
- */
-#define MXC_CCM_LTR0_DIV3CK_OFFSET              1
-#define MXC_CCM_LTR0_DIV3CK_MASK                (0x3 << 1)
-#define MXC_CCM_LTR0_DNTHR_OFFSET               16
-#define MXC_CCM_LTR0_DNTHR_MASK                 (0x3F << 16)
-#define MXC_CCM_LTR0_UPTHR_OFFSET               22
-#define MXC_CCM_LTR0_UPTHR_MASK                 (0x3F << 22)
-
-/*
- * LTR1 register offsets
- */
-#define MXC_CCM_LTR1_PNCTHR_OFFSET              0
-#define MXC_CCM_LTR1_PNCTHR_MASK                0x3F
-#define MXC_CCM_LTR1_UPCNT_OFFSET               6
-#define MXC_CCM_LTR1_UPCNT_MASK                 (0xFF << 6)
-#define MXC_CCM_LTR1_DNCNT_OFFSET               14
-#define MXC_CCM_LTR1_DNCNT_MASK                 (0xFF << 14)
-#define MXC_CCM_LTR1_LTBRSR_MASK                0x400000
-#define MXC_CCM_LTR1_LTBRSR_OFFSET              22
-#define MXC_CCM_LTR1_LTBRSR                     0x400000
-#define MXC_CCM_LTR1_LTBRSH                     0x800000
-
-/*
- * LTR2 bit definitions. x ranges from 0 for WSW9 to 6 for WSW15
- */
-#define MXC_CCM_LTR2_WSW_OFFSET(x)              (11 + (x) * 3)
-#define MXC_CCM_LTR2_WSW_MASK(x)                (0x7 << \
-					MXC_CCM_LTR2_WSW_OFFSET((x)))
-#define MXC_CCM_LTR2_EMAC_OFFSET                0
-#define MXC_CCM_LTR2_EMAC_MASK                  0x1FF
-
-/*
- * LTR3 bit definitions. x ranges from 0 for WSW0 to 8 for WSW8
- */
-#define MXC_CCM_LTR3_WSW_OFFSET(x)              (5 + (x) * 3)
-#define MXC_CCM_LTR3_WSW_MASK(x)                (0x7 << \
-					MXC_CCM_LTR3_WSW_OFFSET((x)))
-
-#define MXC_CCM_PMCR0_DFSUP1                    0x80000000
-#define MXC_CCM_PMCR0_DFSUP1_SPLL               (0 << 31)
-#define MXC_CCM_PMCR0_DFSUP1_MPLL               (1 << 31)
-#define MXC_CCM_PMCR0_DFSUP0                    0x40000000
-#define MXC_CCM_PMCR0_DFSUP0_PLL                (0 << 30)
-#define MXC_CCM_PMCR0_DFSUP0_PDR                (1 << 30)
-#define MXC_CCM_PMCR0_DFSUP_MASK                (0x3 << 30)
-
-#define DVSUP_TURBO				0
-#define DVSUP_HIGH				1
-#define DVSUP_MEDIUM				2
-#define DVSUP_LOW				3
-#define MXC_CCM_PMCR0_DVSUP_TURBO               (DVSUP_TURBO << 28)
-#define MXC_CCM_PMCR0_DVSUP_HIGH                (DVSUP_HIGH << 28)
-#define MXC_CCM_PMCR0_DVSUP_MEDIUM              (DVSUP_MEDIUM << 28)
-#define MXC_CCM_PMCR0_DVSUP_LOW                 (DVSUP_LOW << 28)
-#define MXC_CCM_PMCR0_DVSUP_OFFSET              28
-#define MXC_CCM_PMCR0_DVSUP_MASK                (0x3 << 28)
-#define MXC_CCM_PMCR0_UDSC                      0x08000000
-#define MXC_CCM_PMCR0_UDSC_MASK                 (1 << 27)
-#define MXC_CCM_PMCR0_UDSC_UP                   (1 << 27)
-#define MXC_CCM_PMCR0_UDSC_DOWN                 (0 << 27)
-
-#define MXC_CCM_PMCR0_VSCNT_1                   (0x0 << 24)
-#define MXC_CCM_PMCR0_VSCNT_2                   (0x1 << 24)
-#define MXC_CCM_PMCR0_VSCNT_3                   (0x2 << 24)
-#define MXC_CCM_PMCR0_VSCNT_4                   (0x3 << 24)
-#define MXC_CCM_PMCR0_VSCNT_5                   (0x4 << 24)
-#define MXC_CCM_PMCR0_VSCNT_6                   (0x5 << 24)
-#define MXC_CCM_PMCR0_VSCNT_7                   (0x6 << 24)
-#define MXC_CCM_PMCR0_VSCNT_8                   (0x7 << 24)
-#define MXC_CCM_PMCR0_VSCNT_OFFSET              24
-#define MXC_CCM_PMCR0_VSCNT_MASK                (0x7 << 24)
-#define MXC_CCM_PMCR0_DVFEV                     0x00800000
-#define MXC_CCM_PMCR0_DVFIS                     0x00400000
-#define MXC_CCM_PMCR0_LBMI                      0x00200000
-#define MXC_CCM_PMCR0_LBFL                      0x00100000
-#define MXC_CCM_PMCR0_LBCF_4                    (0x0 << 18)
-#define MXC_CCM_PMCR0_LBCF_8                    (0x1 << 18)
-#define MXC_CCM_PMCR0_LBCF_12                   (0x2 << 18)
-#define MXC_CCM_PMCR0_LBCF_16                   (0x3 << 18)
-#define MXC_CCM_PMCR0_LBCF_OFFSET               18
-#define MXC_CCM_PMCR0_LBCF_MASK                 (0x3 << 18)
-#define MXC_CCM_PMCR0_PTVIS                     0x00020000
-#define MXC_CCM_PMCR0_UPDTEN                    0x00010000
-#define MXC_CCM_PMCR0_UPDTEN_MASK               (0x1 << 16)
-#define MXC_CCM_PMCR0_FSVAIM                    0x00008000
-#define MXC_CCM_PMCR0_FSVAI_OFFSET              13
-#define MXC_CCM_PMCR0_FSVAI_MASK                (0x3 << 13)
-#define MXC_CCM_PMCR0_DPVCR                     0x00001000
-#define MXC_CCM_PMCR0_DPVV                      0x00000800
-#define MXC_CCM_PMCR0_WFIM                      0x00000400
-#define MXC_CCM_PMCR0_DRCE3                     0x00000200
-#define MXC_CCM_PMCR0_DRCE2                     0x00000100
-#define MXC_CCM_PMCR0_DRCE1                     0x00000080
-#define MXC_CCM_PMCR0_DRCE0                     0x00000040
-#define MXC_CCM_PMCR0_DCR                       0x00000020
-#define MXC_CCM_PMCR0_DVFEN                     0x00000010
-#define MXC_CCM_PMCR0_PTVAIM                    0x00000008
-#define MXC_CCM_PMCR0_PTVAI_OFFSET              1
-#define MXC_CCM_PMCR0_PTVAI_MASK                (0x3 << 1)
-#define MXC_CCM_PMCR0_DPTEN                     0x00000001
-
-#define MXC_CCM_PMCR1_DVGP_OFFSET               0
-#define MXC_CCM_PMCR1_DVGP_MASK                 (0xF)
-
-#define MXC_CCM_PMCR1_PLLRDIS                      (0x1 << 7)
-#define MXC_CCM_PMCR1_EMIRQ_EN                      (0x1 << 8)
-
-#define MXC_CCM_DCVR_ULV_MASK                   (0x3FF << 22)
-#define MXC_CCM_DCVR_ULV_OFFSET                 22
-#define MXC_CCM_DCVR_LLV_MASK                   (0x3FF << 12)
-#define MXC_CCM_DCVR_LLV_OFFSET                 12
-#define MXC_CCM_DCVR_ELV_MASK                   (0x3FF << 2)
-#define MXC_CCM_DCVR_ELV_OFFSET                 2
-
-#define MXC_CCM_PDR2_MST2_PDF_MASK              (0x3F << 7)
-#define MXC_CCM_PDR2_MST2_PDF_OFFSET            7
-#define MXC_CCM_PDR2_MST1_PDF_MASK              0x3F
-#define MXC_CCM_PDR2_MST1_PDF_OFFSET            0
-
-#define MXC_CCM_COSR_CLKOSEL_MASK               0x0F
-#define MXC_CCM_COSR_CLKOSEL_OFFSET             0
-#define MXC_CCM_COSR_CLKOUTDIV_MASK             (0x07 << 6)
-#define MXC_CCM_COSR_CLKOUTDIV_OFFSET           6
-#define MXC_CCM_COSR_CLKOEN                     (1 << 9)
-
-/*
- * PMCR0 register offsets
- */
-#define MXC_CCM_PMCR0_LBFL_OFFSET   20
-#define MXC_CCM_PMCR0_DFSUP0_OFFSET 30
-#define MXC_CCM_PMCR0_DFSUP1_OFFSET 31
-
-#endif				/* __ARCH_ARM_MACH_MX3_CRM_REGS_H__ */
diff -druN linux-2.6.39-libre/arch/arm/mach-mx3/devices.c linux-3.0-rc7-libre/arch/arm/mach-mx3/devices.c
--- linux-2.6.39-libre/arch/arm/mach-mx3/devices.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-mx3/devices.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,115 +0,0 @@
-/*
- * Copyright 2006-2007 Freescale Semiconductor, Inc. All Rights Reserved.
- * Copyright 2008 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/dma-mapping.h>
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <linux/serial.h>
-#include <linux/gpio.h>
-#include <mach/hardware.h>
-#include <mach/irqs.h>
-#include <mach/common.h>
-#include <mach/mx3_camera.h>
-
-#include "devices.h"
-
-/* i.MX31 Image Processing Unit */
-
-/* The resource order is important! */
-static struct resource mx3_ipu_rsrc[] = {
-	{
-		.start = MX3x_IPU_CTRL_BASE_ADDR,
-		.end = MX3x_IPU_CTRL_BASE_ADDR + 0x5F,
-		.flags = IORESOURCE_MEM,
-	}, {
-		.start = MX3x_IPU_CTRL_BASE_ADDR + 0x88,
-		.end = MX3x_IPU_CTRL_BASE_ADDR + 0xB3,
-		.flags = IORESOURCE_MEM,
-	}, {
-		.start = MX3x_INT_IPU_SYN,
-		.end = MX3x_INT_IPU_SYN,
-		.flags = IORESOURCE_IRQ,
-	}, {
-		.start = MX3x_INT_IPU_ERR,
-		.end = MX3x_INT_IPU_ERR,
-		.flags = IORESOURCE_IRQ,
-	},
-};
-
-struct platform_device mx3_ipu = {
-	.name = "ipu-core",
-	.id = -1,
-	.num_resources = ARRAY_SIZE(mx3_ipu_rsrc),
-	.resource = mx3_ipu_rsrc,
-};
-
-static struct resource fb_resources[] = {
-	{
-		.start	= MX3x_IPU_CTRL_BASE_ADDR + 0xB4,
-		.end	= MX3x_IPU_CTRL_BASE_ADDR + 0x1BF,
-		.flags	= IORESOURCE_MEM,
-	},
-};
-
-struct platform_device mx3_fb = {
-	.name		= "mx3_sdc_fb",
-	.id		= -1,
-	.num_resources	= ARRAY_SIZE(fb_resources),
-	.resource	= fb_resources,
-	.dev		= {
-		.coherent_dma_mask = DMA_BIT_MASK(32),
-       },
-};
-
-static struct resource camera_resources[] = {
-	{
-		.start	= MX3x_IPU_CTRL_BASE_ADDR + 0x60,
-		.end	= MX3x_IPU_CTRL_BASE_ADDR + 0x87,
-		.flags	= IORESOURCE_MEM,
-	},
-};
-
-struct platform_device mx3_camera = {
-	.name		= "mx3-camera",
-	.id		= 0,
-	.num_resources	= ARRAY_SIZE(camera_resources),
-	.resource	= camera_resources,
-	.dev		= {
-		.coherent_dma_mask = DMA_BIT_MASK(32),
-	},
-};
-
-static struct resource imx_rtc_resources[] = {
-	{
-		.start  = MX31_RTC_BASE_ADDR,
-		.end    = MX31_RTC_BASE_ADDR + 0x3fff,
-		.flags  = IORESOURCE_MEM,
-	},
-	{
-		.start  = MX31_INT_RTC,
-		.flags  = IORESOURCE_IRQ,
-	},
-};
-
-struct platform_device imx_rtc_device0 = {
-	.name           = "mxc_rtc",
-	.id             = -1,
-	.num_resources  = ARRAY_SIZE(imx_rtc_resources),
-	.resource       = imx_rtc_resources,
-};
diff -druN linux-2.6.39-libre/arch/arm/mach-mx3/devices.h linux-3.0-rc7-libre/arch/arm/mach-mx3/devices.h
--- linux-2.6.39-libre/arch/arm/mach-mx3/devices.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-mx3/devices.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,4 +0,0 @@
-extern struct platform_device mx3_ipu;
-extern struct platform_device mx3_fb;
-extern struct platform_device mx3_camera;
-extern struct platform_device imx_rtc_device0;
diff -druN linux-2.6.39-libre/arch/arm/mach-mx3/devices-imx31.h linux-3.0-rc7-libre/arch/arm/mach-mx3/devices-imx31.h
--- linux-2.6.39-libre/arch/arm/mach-mx3/devices-imx31.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-mx3/devices-imx31.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,68 +0,0 @@
-/*
- * Copyright (C) 2010 Pengutronix
- * Uwe Kleine-Koenig <u.kleine-koenig@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 <mach/mx31.h>
-#include <mach/devices-common.h>
-
-extern const struct imx_fsl_usb2_udc_data imx31_fsl_usb2_udc_data __initconst;
-#define imx31_add_fsl_usb2_udc(pdata)	\
-	imx_add_fsl_usb2_udc(&imx31_fsl_usb2_udc_data, pdata)
-
-extern const struct imx_imx2_wdt_data imx31_imx2_wdt_data __initconst;
-#define imx31_add_imx2_wdt(pdata)       \
-	imx_add_imx2_wdt(&imx31_imx2_wdt_data)
-
-extern const struct imx_imx_i2c_data imx31_imx_i2c_data[] __initconst;
-#define imx31_add_imx_i2c(id, pdata)	\
-	imx_add_imx_i2c(&imx31_imx_i2c_data[id], pdata)
-#define imx31_add_imx_i2c0(pdata)	imx31_add_imx_i2c(0, pdata)
-#define imx31_add_imx_i2c1(pdata)	imx31_add_imx_i2c(1, pdata)
-#define imx31_add_imx_i2c2(pdata)	imx31_add_imx_i2c(2, pdata)
-
-extern const struct imx_imx_keypad_data imx31_imx_keypad_data __initconst;
-#define imx31_add_imx_keypad(pdata)	\
-	imx_add_imx_keypad(&imx31_imx_keypad_data, pdata)
-
-extern const struct imx_imx_ssi_data imx31_imx_ssi_data[] __initconst;
-#define imx31_add_imx_ssi(id, pdata)    \
-	imx_add_imx_ssi(&imx31_imx_ssi_data[id], pdata)
-
-extern const struct imx_imx_uart_1irq_data imx31_imx_uart_data[] __initconst;
-#define imx31_add_imx_uart(id, pdata)	\
-	imx_add_imx_uart_1irq(&imx31_imx_uart_data[id], pdata)
-#define imx31_add_imx_uart0(pdata)	imx31_add_imx_uart(0, pdata)
-#define imx31_add_imx_uart1(pdata)	imx31_add_imx_uart(1, pdata)
-#define imx31_add_imx_uart2(pdata)	imx31_add_imx_uart(2, pdata)
-#define imx31_add_imx_uart3(pdata)	imx31_add_imx_uart(3, pdata)
-#define imx31_add_imx_uart4(pdata)	imx31_add_imx_uart(4, pdata)
-
-extern const struct imx_mxc_ehci_data imx31_mxc_ehci_otg_data __initconst;
-#define imx31_add_mxc_ehci_otg(pdata)	\
-	imx_add_mxc_ehci(&imx31_mxc_ehci_otg_data, pdata)
-extern const struct imx_mxc_ehci_data imx31_mxc_ehci_hs_data[] __initconst;
-#define imx31_add_mxc_ehci_hs(id, pdata)	\
-	imx_add_mxc_ehci(&imx31_mxc_ehci_hs_data[id - 1], pdata)
-
-extern const struct imx_mxc_mmc_data imx31_mxc_mmc_data[] __initconst;
-#define imx31_add_mxc_mmc(id, pdata)	\
-	imx_add_mxc_mmc(&imx31_mxc_mmc_data[id], pdata)
-
-extern const struct imx_mxc_nand_data imx31_mxc_nand_data __initconst;
-#define imx31_add_mxc_nand(pdata)	\
-	imx_add_mxc_nand(&imx31_mxc_nand_data, pdata)
-
-extern const struct imx_mxc_w1_data imx31_mxc_w1_data __initconst;
-#define imx31_add_mxc_w1(pdata)	\
-	imx_add_mxc_w1(&imx31_mxc_w1_data)
-
-extern const struct imx_spi_imx_data imx31_cspi_data[] __initconst;
-#define imx31_add_cspi(id, pdata)	\
-	imx_add_spi_imx(&imx31_cspi_data[id], pdata)
-#define imx31_add_spi_imx0(pdata)	imx31_add_cspi(0, pdata)
-#define imx31_add_spi_imx1(pdata)	imx31_add_cspi(1, pdata)
-#define imx31_add_spi_imx2(pdata)	imx31_add_cspi(2, pdata)
diff -druN linux-2.6.39-libre/arch/arm/mach-mx3/devices-imx35.h linux-3.0-rc7-libre/arch/arm/mach-mx3/devices-imx35.h
--- linux-2.6.39-libre/arch/arm/mach-mx3/devices-imx35.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-mx3/devices-imx35.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,76 +0,0 @@
-/*
- * Copyright (C) 2010 Pengutronix
- * Uwe Kleine-Koenig <u.kleine-koenig@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 <mach/mx35.h>
-#include <mach/devices-common.h>
-
-extern const struct imx_fec_data imx35_fec_data __initconst;
-#define imx35_add_fec(pdata)	\
-	imx_add_fec(&imx35_fec_data, pdata)
-
-extern const struct imx_fsl_usb2_udc_data imx35_fsl_usb2_udc_data __initconst;
-#define imx35_add_fsl_usb2_udc(pdata)	\
-	imx_add_fsl_usb2_udc(&imx35_fsl_usb2_udc_data, pdata)
-
-extern const struct imx_flexcan_data imx35_flexcan_data[] __initconst;
-#define imx35_add_flexcan(id, pdata)	\
-	imx_add_flexcan(&imx35_flexcan_data[id], pdata)
-#define imx35_add_flexcan0(pdata)	imx35_add_flexcan(0, pdata)
-#define imx35_add_flexcan1(pdata)	imx35_add_flexcan(1, pdata)
-
-extern const struct imx_imx2_wdt_data imx35_imx2_wdt_data __initconst;
-#define imx35_add_imx2_wdt(pdata)       \
-	imx_add_imx2_wdt(&imx35_imx2_wdt_data)
-
-extern const struct imx_imx_i2c_data imx35_imx_i2c_data[] __initconst;
-#define imx35_add_imx_i2c(id, pdata)	\
-	imx_add_imx_i2c(&imx35_imx_i2c_data[id], pdata)
-#define imx35_add_imx_i2c0(pdata)	imx35_add_imx_i2c(0, pdata)
-#define imx35_add_imx_i2c1(pdata)	imx35_add_imx_i2c(1, pdata)
-#define imx35_add_imx_i2c2(pdata)	imx35_add_imx_i2c(2, pdata)
-
-extern const struct imx_imx_keypad_data imx35_imx_keypad_data __initconst;
-#define imx35_add_imx_keypad(pdata)	\
-	imx_add_imx_keypad(&imx35_imx_keypad_data, pdata)
-
-extern const struct imx_imx_ssi_data imx35_imx_ssi_data[] __initconst;
-#define imx35_add_imx_ssi(id, pdata)    \
-	imx_add_imx_ssi(&imx35_imx_ssi_data[id], pdata)
-
-extern const struct imx_imx_uart_1irq_data imx35_imx_uart_data[] __initconst;
-#define imx35_add_imx_uart(id, pdata)	\
-	imx_add_imx_uart_1irq(&imx35_imx_uart_data[id], pdata)
-#define imx35_add_imx_uart0(pdata)	imx35_add_imx_uart(0, pdata)
-#define imx35_add_imx_uart1(pdata)	imx35_add_imx_uart(1, pdata)
-#define imx35_add_imx_uart2(pdata)	imx35_add_imx_uart(2, pdata)
-
-extern const struct imx_mxc_ehci_data imx35_mxc_ehci_otg_data __initconst;
-#define imx35_add_mxc_ehci_otg(pdata)	\
-	imx_add_mxc_ehci(&imx35_mxc_ehci_otg_data, pdata)
-extern const struct imx_mxc_ehci_data imx35_mxc_ehci_hs_data __initconst;
-#define imx35_add_mxc_ehci_hs(pdata)	\
-	imx_add_mxc_ehci(&imx35_mxc_ehci_hs_data, pdata)
-
-extern const struct imx_mxc_nand_data imx35_mxc_nand_data __initconst;
-#define imx35_add_mxc_nand(pdata)	\
-	imx_add_mxc_nand(&imx35_mxc_nand_data, pdata)
-
-extern const struct imx_mxc_w1_data imx35_mxc_w1_data __initconst;
-#define imx35_add_mxc_w1(pdata)	\
-	imx_add_mxc_w1(&imx35_mxc_w1_data)
-
-extern const struct imx_sdhci_esdhc_imx_data
-imx35_sdhci_esdhc_imx_data[] __initconst;
-#define imx35_add_sdhci_esdhc_imx(id, pdata)	\
-	imx_add_sdhci_esdhc_imx(&imx35_sdhci_esdhc_imx_data[id], pdata)
-
-extern const struct imx_spi_imx_data imx35_cspi_data[] __initconst;
-#define imx35_add_cspi(id, pdata)	\
-	imx_add_spi_imx(&imx35_cspi_data[id], pdata)
-#define imx35_add_spi_imx0(pdata)	imx35_add_cspi(0, pdata)
-#define imx35_add_spi_imx1(pdata)	imx35_add_cspi(1, pdata)
diff -druN linux-2.6.39-libre/arch/arm/mach-mx3/ehci-imx31.c linux-3.0-rc7-libre/arch/arm/mach-mx3/ehci-imx31.c
--- linux-2.6.39-libre/arch/arm/mach-mx3/ehci-imx31.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-mx3/ehci-imx31.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,83 +0,0 @@
-/*
- * Copyright (c) 2009 Daniel Mack <daniel@caiaq.de>
- * Copyright (C) 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.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * for more details.
- */
-
-#include <linux/platform_device.h>
-#include <linux/io.h>
-
-#include <mach/hardware.h>
-#include <mach/mxc_ehci.h>
-
-#define USBCTRL_OTGBASE_OFFSET	0x600
-
-#define MX31_OTG_SIC_SHIFT	29
-#define MX31_OTG_SIC_MASK	(0x3 << MX31_OTG_SIC_SHIFT)
-#define MX31_OTG_PM_BIT		(1 << 24)
-
-#define MX31_H2_SIC_SHIFT	21
-#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	(0x3 << MX31_H1_SIC_SHIFT)
-#define MX31_H1_PM_BIT		(1 << 8)
-#define MX31_H1_DT_BIT		(1 << 4)
-
-int mx31_initialize_usb_hw(int port, unsigned int flags)
-{
-	unsigned int v;
-
-	v = readl(MX31_IO_ADDRESS(MX31_USB_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, MX31_IO_ADDRESS(MX31_USB_BASE_ADDR + USBCTRL_OTGBASE_OFFSET));
-
-	return 0;
-}
-
diff -druN linux-2.6.39-libre/arch/arm/mach-mx3/ehci-imx35.c linux-3.0-rc7-libre/arch/arm/mach-mx3/ehci-imx35.c
--- linux-2.6.39-libre/arch/arm/mach-mx3/ehci-imx35.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-mx3/ehci-imx35.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,80 +0,0 @@
-/*
- * Copyright (c) 2009 Daniel Mack <daniel@caiaq.de>
- * Copyright (C) 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.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * for more details.
- */
-
-#include <linux/platform_device.h>
-#include <linux/io.h>
-
-#include <mach/hardware.h>
-#include <mach/mxc_ehci.h>
-
-#define USBCTRL_OTGBASE_OFFSET	0x600
-
-#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 mx35_initialize_usb_hw(int port, unsigned int flags)
-{
-	unsigned int v;
-
-	v = readl(MX35_IO_ADDRESS(MX35_USB_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_USB_BASE_ADDR + USBCTRL_OTGBASE_OFFSET));
-
-	return 0;
-}
-
diff -druN linux-2.6.39-libre/arch/arm/mach-mx3/eukrea_mbimxsd-baseboard.c linux-3.0-rc7-libre/arch/arm/mach-mx3/eukrea_mbimxsd-baseboard.c
--- linux-2.6.39-libre/arch/arm/mach-mx3/eukrea_mbimxsd-baseboard.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-mx3/eukrea_mbimxsd-baseboard.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,318 +0,0 @@
-/*
- * Copyright (C) 2010 Eric Benard - eric@eukrea.com
- *
- * Based on pcm970-baseboard.c which is :
- * 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/types.h>
-#include <linux/init.h>
-
-#include <linux/gpio.h>
-#include <linux/interrupt.h>
-#include <linux/leds.h>
-#include <linux/platform_device.h>
-#include <linux/gpio_keys.h>
-#include <linux/input.h>
-#include <video/platform_lcd.h>
-#include <linux/i2c.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 <mach/ipu.h>
-#include <mach/mx3fb.h>
-#include <mach/audmux.h>
-#include <mach/esdhc.h>
-
-#include "devices-imx35.h"
-#include "devices.h"
-
-static const struct fb_videomode fb_modedb[] = {
-	{
-		.name		= "CMO-QVGA",
-		.refresh	= 60,
-		.xres		= 320,
-		.yres		= 240,
-		.pixclock	= KHZ2PICOS(6500),
-		.left_margin	= 68,
-		.right_margin	= 20,
-		.upper_margin	= 15,
-		.lower_margin	= 4,
-		.hsync_len	= 30,
-		.vsync_len	= 3,
-		.sync		= 0,
-		.vmode		= FB_VMODE_NONINTERLACED,
-		.flag		= 0,
-	},
-	{
-		.name		= "DVI-VGA",
-		.refresh	= 60,
-		.xres		= 640,
-		.yres		= 480,
-		.pixclock	= 32000,
-		.left_margin	= 100,
-		.right_margin	= 100,
-		.upper_margin	= 7,
-		.lower_margin	= 100,
-		.hsync_len	= 7,
-		.vsync_len	= 7,
-		.sync		= FB_SYNC_VERT_HIGH_ACT | FB_SYNC_HOR_HIGH_ACT |
-				  FB_SYNC_OE_ACT_HIGH | FB_SYNC_CLK_INVERT,
-		.vmode		= FB_VMODE_NONINTERLACED,
-		.flag		= 0,
-	},
-	{
-		.name		= "DVI-SVGA",
-		.refresh	= 60,
-		.xres		= 800,
-		.yres		= 600,
-		.pixclock	= 25000,
-		.left_margin	= 75,
-		.right_margin	= 75,
-		.upper_margin	= 7,
-		.lower_margin	= 75,
-		.hsync_len	= 7,
-		.vsync_len	= 7,
-		.sync		= FB_SYNC_VERT_HIGH_ACT | FB_SYNC_HOR_HIGH_ACT |
-				  FB_SYNC_OE_ACT_HIGH | FB_SYNC_CLK_INVERT,
-		.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		= "CMO-QVGA",
-	.mode		= fb_modedb,
-	.num_modes	= ARRAY_SIZE(fb_modedb),
-};
-
-static iomux_v3_cfg_t eukrea_mbimxsd_pads[] = {
-	/* LCD */
-	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_D3_VSYNC__IPU_DISPB_D3_VSYNC,
-	/* Backlight */
-	MX35_PAD_CONTRAST__IPU_DISPB_CONTR,
-	/* LCD_PWR */
-	MX35_PAD_D3_CLS__GPIO1_4,
-	/* LED */
-	MX35_PAD_LD23__GPIO3_29,
-	/* SWITCH */
-	MX35_PAD_LD19__GPIO3_25,
-	/* UART2 */
-	MX35_PAD_CTS2__UART2_CTS,
-	MX35_PAD_RTS2__UART2_RTS,
-	MX35_PAD_TXD2__UART2_TXD_MUX,
-	MX35_PAD_RXD2__UART2_RXD_MUX,
-	/* I2S */
-	MX35_PAD_STXFS4__AUDMUX_AUD4_TXFS,
-	MX35_PAD_STXD4__AUDMUX_AUD4_TXD,
-	MX35_PAD_SRXD4__AUDMUX_AUD4_RXD,
-	MX35_PAD_SCK4__AUDMUX_AUD4_TXC,
-	/* CAN2 */
-	MX35_PAD_TX5_RX0__CAN2_TXCAN,
-	MX35_PAD_TX4_RX1__CAN2_RXCAN,
-	/* SDCARD */
-	MX35_PAD_SD1_CMD__ESDHC1_CMD,
-	MX35_PAD_SD1_CLK__ESDHC1_CLK,
-	MX35_PAD_SD1_DATA0__ESDHC1_DAT0,
-	MX35_PAD_SD1_DATA1__ESDHC1_DAT1,
-	MX35_PAD_SD1_DATA2__ESDHC1_DAT2,
-	MX35_PAD_SD1_DATA3__ESDHC1_DAT3,
-	/* SD1 CD */
-	MX35_PAD_LD18__GPIO3_24,
-};
-
-#define GPIO_LED1	IMX_GPIO_NR(3, 29)
-#define GPIO_SWITCH1	IMX_GPIO_NR(3, 25)
-#define GPIO_LCDPWR	IMX_GPIO_NR(1, 4)
-#define GPIO_SD1CD	IMX_GPIO_NR(3, 24)
-
-static void eukrea_mbimxsd_lcd_power_set(struct plat_lcd_data *pd,
-				   unsigned int power)
-{
-	if (power)
-		gpio_direction_output(GPIO_LCDPWR, 1);
-	else
-		gpio_direction_output(GPIO_LCDPWR, 0);
-}
-
-static struct plat_lcd_data eukrea_mbimxsd_lcd_power_data = {
-	.set_power		= eukrea_mbimxsd_lcd_power_set,
-};
-
-static struct platform_device eukrea_mbimxsd_lcd_powerdev = {
-	.name			= "platform-lcd",
-	.dev.platform_data	= &eukrea_mbimxsd_lcd_power_data,
-};
-
-static struct gpio_led eukrea_mbimxsd_leds[] = {
-	{
-		.name			= "led1",
-		.default_trigger	= "heartbeat",
-		.active_low		= 1,
-		.gpio			= GPIO_LED1,
-	},
-};
-
-static struct gpio_led_platform_data eukrea_mbimxsd_led_info = {
-	.leds		= eukrea_mbimxsd_leds,
-	.num_leds	= ARRAY_SIZE(eukrea_mbimxsd_leds),
-};
-
-static struct platform_device eukrea_mbimxsd_leds_gpio = {
-	.name	= "leds-gpio",
-	.id	= -1,
-	.dev	= {
-		.platform_data	= &eukrea_mbimxsd_led_info,
-	},
-};
-
-static struct gpio_keys_button eukrea_mbimxsd_gpio_buttons[] = {
-	{
-		.gpio		= GPIO_SWITCH1,
-		.code		= BTN_0,
-		.desc		= "BP1",
-		.active_low	= 1,
-		.wakeup		= 1,
-	},
-};
-
-static struct gpio_keys_platform_data eukrea_mbimxsd_button_data = {
-	.buttons	= eukrea_mbimxsd_gpio_buttons,
-	.nbuttons	= ARRAY_SIZE(eukrea_mbimxsd_gpio_buttons),
-};
-
-static struct platform_device eukrea_mbimxsd_button_device = {
-	.name		= "gpio-keys",
-	.id		= -1,
-	.num_resources	= 0,
-	.dev		= {
-		.platform_data	= &eukrea_mbimxsd_button_data,
-	}
-};
-
-static struct platform_device *platform_devices[] __initdata = {
-	&eukrea_mbimxsd_leds_gpio,
-	&eukrea_mbimxsd_button_device,
-	&eukrea_mbimxsd_lcd_powerdev,
-};
-
-static const struct imxuart_platform_data uart_pdata __initconst = {
-	.flags = IMXUART_HAVE_RTSCTS,
-};
-
-static struct i2c_board_info eukrea_mbimxsd_i2c_devices[] = {
-	{
-		I2C_BOARD_INFO("tlv320aic23", 0x1a),
-	},
-};
-
-static const
-struct imx_ssi_platform_data eukrea_mbimxsd_ssi_pdata __initconst = {
-	.flags = IMX_SSI_SYN | IMX_SSI_NET | IMX_SSI_USE_I2S_SLAVE,
-};
-
-static struct esdhc_platform_data sd1_pdata = {
-	.cd_gpio = GPIO_SD1CD,
-	.wp_gpio = -EINVAL,
-};
-
-/*
- * system init for baseboard usage. Will be called by cpuimx35 init.
- *
- * Add platform devices present on this baseboard and init
- * them from CPU side as far as required to use them later on
- */
-void __init eukrea_mbimxsd35_baseboard_init(void)
-{
-	if (mxc_iomux_v3_setup_multiple_pads(eukrea_mbimxsd_pads,
-			ARRAY_SIZE(eukrea_mbimxsd_pads)))
-		printk(KERN_ERR "error setting mbimxsd pads !\n");
-
-#if defined(CONFIG_SND_SOC_EUKREA_TLV320)
-	/* SSI unit master I2S codec connected to SSI_AUD4 */
-	mxc_audmux_v2_configure_port(0,
-			MXC_AUDMUX_V2_PTCR_SYN |
-			MXC_AUDMUX_V2_PTCR_TFSDIR |
-			MXC_AUDMUX_V2_PTCR_TFSEL(3) |
-			MXC_AUDMUX_V2_PTCR_TCLKDIR |
-			MXC_AUDMUX_V2_PTCR_TCSEL(3),
-			MXC_AUDMUX_V2_PDCR_RXDSEL(3)
-	);
-	mxc_audmux_v2_configure_port(3,
-			MXC_AUDMUX_V2_PTCR_SYN,
-			MXC_AUDMUX_V2_PDCR_RXDSEL(0)
-	);
-#endif
-
-	imx35_add_imx_uart1(&uart_pdata);
-	mxc_register_device(&mx3_ipu, &mx3_ipu_data);
-	mxc_register_device(&mx3_fb, &mx3fb_pdata);
-
-	imx35_add_imx_ssi(0, &eukrea_mbimxsd_ssi_pdata);
-
-	imx35_add_flexcan1(NULL);
-	imx35_add_sdhci_esdhc_imx(0, &sd1_pdata);
-
-	gpio_request(GPIO_LED1, "LED1");
-	gpio_direction_output(GPIO_LED1, 1);
-	gpio_free(GPIO_LED1);
-
-	gpio_request(GPIO_SWITCH1, "SWITCH1");
-	gpio_direction_input(GPIO_SWITCH1);
-	gpio_free(GPIO_SWITCH1);
-
-	gpio_request(GPIO_LCDPWR, "LCDPWR");
-	gpio_direction_output(GPIO_LCDPWR, 1);
-
-	i2c_register_board_info(0, eukrea_mbimxsd_i2c_devices,
-				ARRAY_SIZE(eukrea_mbimxsd_i2c_devices));
-
-	platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices));
-}
diff -druN linux-2.6.39-libre/arch/arm/mach-mx3/iomux-imx31.c linux-3.0-rc7-libre/arch/arm/mach-mx3/iomux-imx31.c
--- linux-2.6.39-libre/arch/arm/mach-mx3/iomux-imx31.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-mx3/iomux-imx31.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	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(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(const unsigned int *pin_list, unsigned count,
-		const char *label)
-{
-	const 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(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(const unsigned int *pin_list, int count)
-{
-	const 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 -druN linux-2.6.39-libre/arch/arm/mach-mx3/Kconfig linux-3.0-rc7-libre/arch/arm/mach-mx3/Kconfig
--- linux-2.6.39-libre/arch/arm/mach-mx3/Kconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-mx3/Kconfig	1969-12-31 19:00:00.000000000 -0500
@@ -1,257 +0,0 @@
-if ARCH_MX3
-
-# ARCH_MX31 and ARCH_MX35 are left for compatibility
-# Some usages assume that having one of them implies not having (e.g.) ARCH_MX2.
-# To easily distinguish good and reviewed from unreviewed usages new (and IMHO
-# more sensible) names are used: SOC_IMX31 and SOC_IMX35
-config ARCH_MX31
-	bool
-
-config ARCH_MX35
-	bool
-
-config SOC_IMX31
-	bool
-	select IMX_HAVE_PLATFORM_MXC_RNGA
-	select ARCH_MXC_AUDMUX_V2
-	select ARCH_MX31
-	select MXC_AVIC
-
-config SOC_IMX35
-	bool
-	select ARCH_MXC_IOMUX_V3
-	select ARCH_MXC_AUDMUX_V2
-	select HAVE_EPIT
-	select ARCH_MX35
-	select MXC_AVIC
-
-comment "MX3 platforms:"
-
-config MACH_MX31ADS
-	bool "Support MX31ADS platforms"
-	select SOC_IMX31
-	select IMX_HAVE_PLATFORM_IMX_I2C
-	select IMX_HAVE_PLATFORM_IMX_SSI
-	select IMX_HAVE_PLATFORM_IMX_UART
-	default y
-	help
-	  Include support for MX31ADS platform. This includes specific
-	  configurations for the board and its peripherals.
-
-config MACH_MX31ADS_WM1133_EV1
-	bool "Support Wolfson Microelectronics 1133-EV1 module"
-	depends on MACH_MX31ADS
-	depends on MFD_WM8350_I2C
-	depends on REGULATOR_WM8350
-	select MFD_WM8350_CONFIG_MODE_0
-	select MFD_WM8352_CONFIG_MODE_0
-	help
-	  Include support for the Wolfson Microelectronics 1133-EV1 PMU
-	  and audio module for the MX31ADS platform.
-
-config MACH_PCM037
-	bool "Support Phytec pcm037 (i.MX31) platforms"
-	select SOC_IMX31
-	select IMX_HAVE_PLATFORM_FSL_USB2_UDC
-	select IMX_HAVE_PLATFORM_IMX2_WDT
-	select IMX_HAVE_PLATFORM_IMX_I2C
-	select IMX_HAVE_PLATFORM_IMX_UART
-	select IMX_HAVE_PLATFORM_MXC_EHCI
-	select IMX_HAVE_PLATFORM_MXC_MMC
-	select IMX_HAVE_PLATFORM_MXC_NAND
-	select IMX_HAVE_PLATFORM_MXC_W1
-	select MXC_ULPI if USB_ULPI
-	help
-	  Include support for Phytec pcm037 platform. This includes
-	  specific configurations for the board and its peripherals.
-
-config MACH_PCM037_EET
-	bool "Support pcm037 EET board extensions"
-	depends on MACH_PCM037
-	select IMX_HAVE_PLATFORM_SPI_IMX
-	help
-	  Add support for PCM037 EET baseboard extensions. If you are using the
-	  OLED display with EET, use "video=mx3fb:CMEL-OLED" kernel
-	  command-line parameter.
-
-config MACH_MX31LITE
-	bool "Support MX31 LITEKIT (LogicPD)"
-	select SOC_IMX31
-	select MXC_ULPI if USB_ULPI
-	select IMX_HAVE_PLATFORM_IMX2_WDT
-	select IMX_HAVE_PLATFORM_IMX_UART
-	select IMX_HAVE_PLATFORM_MXC_EHCI
-	select IMX_HAVE_PLATFORM_MXC_MMC
-	select IMX_HAVE_PLATFORM_MXC_NAND
-	select IMX_HAVE_PLATFORM_SPI_IMX
-	help
-	  Include support for MX31 LITEKIT platform. This includes specific
-	  configurations for the board and its peripherals.
-
-config MACH_MX31_3DS
-	bool "Support MX31PDK (3DS)"
-	select SOC_IMX31
-	select MXC_DEBUG_BOARD
-	select IMX_HAVE_PLATFORM_FSL_USB2_UDC
-	select IMX_HAVE_PLATFORM_IMX2_WDT
-	select IMX_HAVE_PLATFORM_IMX_I2C
-	select IMX_HAVE_PLATFORM_IMX_KEYPAD
-	select IMX_HAVE_PLATFORM_IMX_UART
-	select IMX_HAVE_PLATFORM_MXC_EHCI
-	select IMX_HAVE_PLATFORM_MXC_NAND
-	select IMX_HAVE_PLATFORM_SPI_IMX
-	select MXC_ULPI if USB_ULPI
-	help
-	  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 SOC_IMX31
-	select IMX_HAVE_PLATFORM_FSL_USB2_UDC
-	select IMX_HAVE_PLATFORM_IMX_I2C
-	select IMX_HAVE_PLATFORM_IMX_UART
-	select IMX_HAVE_PLATFORM_MXC_EHCI
-	select IMX_HAVE_PLATFORM_MXC_MMC
-	select IMX_HAVE_PLATFORM_SPI_IMX
-	select MXC_ULPI if USB_ULPI
-	help
-	  Include support for mx31moboard platform. This includes specific
-	  configurations for the board and its peripherals.
-
-config MACH_MX31LILLY
-	bool "Support MX31 LILLY-1131 platforms (INCO startec)"
-	select SOC_IMX31
-	select IMX_HAVE_PLATFORM_IMX_UART
-	select IMX_HAVE_PLATFORM_MXC_EHCI
-	select IMX_HAVE_PLATFORM_MXC_MMC
-	select IMX_HAVE_PLATFORM_SPI_IMX
-	select MXC_ULPI if USB_ULPI
-	help
-	  Include support for mx31 based LILLY1131 modules. This includes
-	  specific configurations for the board and its peripherals.
-
-config MACH_QONG
-	bool "Support Dave/DENX QongEVB-LITE platform"
-	select SOC_IMX31
-	select IMX_HAVE_PLATFORM_IMX_UART
-	help
-	  Include support for Dave/DENX QongEVB-LITE platform. This includes
-	  specific configurations for the board and its peripherals.
-
-config MACH_PCM043
-	bool "Support Phytec pcm043 (i.MX35) platforms"
-	select SOC_IMX35
-	select IMX_HAVE_PLATFORM_FLEXCAN
-	select IMX_HAVE_PLATFORM_FSL_USB2_UDC
-	select IMX_HAVE_PLATFORM_IMX2_WDT
-	select IMX_HAVE_PLATFORM_IMX_I2C
-	select IMX_HAVE_PLATFORM_IMX_SSI
-	select IMX_HAVE_PLATFORM_IMX_UART
-	select IMX_HAVE_PLATFORM_MXC_EHCI
-	select IMX_HAVE_PLATFORM_MXC_NAND
-	select IMX_HAVE_PLATFORM_SDHCI_ESDHC_IMX
-	select MXC_ULPI if USB_ULPI
-	help
-	  Include support for Phytec pcm043 platform. This includes
-	  specific configurations for the board and its peripherals.
-
-config MACH_ARMADILLO5X0
-	bool "Support Atmark Armadillo-500 Development Base Board"
-	select SOC_IMX31
-	select IMX_HAVE_PLATFORM_IMX_I2C
-	select IMX_HAVE_PLATFORM_IMX_UART
-	select IMX_HAVE_PLATFORM_MXC_EHCI
-	select IMX_HAVE_PLATFORM_MXC_MMC
-	select IMX_HAVE_PLATFORM_MXC_NAND
-	select MXC_ULPI if USB_ULPI
-	help
-	  Include support for Atmark Armadillo-500 platform. This includes
-	  specific configurations for the board and its peripherals.
-
-config MACH_MX35_3DS
-	bool "Support MX35PDK platform"
-	select SOC_IMX35
-	select MXC_DEBUG_BOARD
-	select IMX_HAVE_PLATFORM_FSL_USB2_UDC
-	select IMX_HAVE_PLATFORM_IMX2_WDT
-	select IMX_HAVE_PLATFORM_IMX_I2C
-	select IMX_HAVE_PLATFORM_IMX_UART
-	select IMX_HAVE_PLATFORM_MXC_EHCI
-	select IMX_HAVE_PLATFORM_MXC_NAND
-	select IMX_HAVE_PLATFORM_SDHCI_ESDHC_IMX
-	help
-	  Include support for MX35PDK platform. This includes specific
-	  configurations for the board and its peripherals.
-
-config MACH_KZM_ARM11_01
-	bool "Support KZM-ARM11-01(Kyoto Microcomputer)"
-	select SOC_IMX31
-	select IMX_HAVE_PLATFORM_IMX_UART
-	help
-	  Include support for KZM-ARM11-01. This includes specific
-	  configurations for the board and its peripherals.
-
-config MACH_BUG
-	bool "Support Buglabs BUGBase platform"
-	select SOC_IMX31
-	select IMX_HAVE_PLATFORM_IMX_UART
-	default y
-	help
-	  Include support for BUGBase 1.3 platform. This includes specific
-	  configurations for the board and its peripherals.
-
-config MACH_EUKREA_CPUIMX35
-	bool "Support Eukrea CPUIMX35 Platform"
-	select SOC_IMX35
-	select IMX_HAVE_PLATFORM_FLEXCAN
-	select IMX_HAVE_PLATFORM_FSL_USB2_UDC
-	select IMX_HAVE_PLATFORM_IMX2_WDT
-	select IMX_HAVE_PLATFORM_IMX_I2C
-	select IMX_HAVE_PLATFORM_IMX_UART
-	select IMX_HAVE_PLATFORM_MXC_EHCI
-	select IMX_HAVE_PLATFORM_MXC_NAND
-	select IMX_HAVE_PLATFORM_SDHCI_ESDHC_IMX
-	select MXC_ULPI if USB_ULPI
-	help
-	  Include support for Eukrea CPUIMX35 platform. This includes
-	  specific configurations for the board and its peripherals.
-
-choice
-	prompt "Baseboard"
-	depends on MACH_EUKREA_CPUIMX35
-	default MACH_EUKREA_MBIMXSD35_BASEBOARD
-
-config MACH_EUKREA_MBIMXSD35_BASEBOARD
-	bool "Eukrea MBIMXSD development board"
-	select IMX_HAVE_PLATFORM_IMX_SSI
-	help
-	  This adds board specific devices that can be found on Eukrea's
-	  MBIMXSD evaluation board.
-
-endchoice
-
-config MACH_VPR200
-	bool "Support VPR200 platform"
-	select SOC_IMX35
-	select IMX_HAVE_PLATFORM_FSL_USB2_UDC
-	select IMX_HAVE_PLATFORM_IMX2_WDT
-	select IMX_HAVE_PLATFORM_IMX_UART
-	select IMX_HAVE_PLATFORM_IMX_I2C
-	select IMX_HAVE_PLATFORM_MXC_EHCI
-	select IMX_HAVE_PLATFORM_MXC_NAND
-	select IMX_HAVE_PLATFORM_SDHCI_ESDHC_IMX
-	help
-	  Include support for VPR200 platform. This includes specific
-	  configurations for the board and its peripherals.
-
-endif
diff -druN linux-2.6.39-libre/arch/arm/mach-mx3/mach-armadillo5x0.c linux-3.0-rc7-libre/arch/arm/mach-mx3/mach-armadillo5x0.c
--- linux-2.6.39-libre/arch/arm/mach-mx3/mach-armadillo5x0.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-mx3/mach-armadillo5x0.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,578 +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 <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/iomux-mx3.h>
-#include <mach/ipu.h>
-#include <mach/mx3fb.h>
-#include <mach/ulpi.h>
-
-#include "devices-imx31.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 */
-
-#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*/);
-	mdelay(10);
-
-	return mx31_initialize_usb_hw(pdev->id, MXC_EHCI_POWER_PINS_ENABLED |
-			MXC_EHCI_INTERFACE_DIFF_UNI);
-
-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*/);
-	mdelay(10);
-
-	return mx31_initialize_usb_hw(pdev->id, MXC_EHCI_POWER_PINS_ENABLED |
-			MXC_EHCI_INTERFACE_DIFF_UNI);
-
-h2_free_reset:
-	gpio_free(USBH2_RESET);
-h2_free_cs:
-	gpio_free(USBH2_CS);
-	return err;
-}
-
-static struct mxc_usbh_platform_data usbotg_pdata __initdata = {
-	.init	= usbotg_init,
-	.portsc	= MXC_EHCI_MODE_ULPI | MXC_EHCI_UTMI_8BIT,
-};
-
-static struct mxc_usbh_platform_data usbh2_pdata __initdata = {
-	.init	= usbh2_init,
-	.portsc	= MXC_EHCI_MODE_ULPI | MXC_EHCI_UTMI_8BIT,
-};
-
-/* 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 const struct mxc_nand_platform_data
-armadillo5x0_nand_board_info __initconst = {
-	.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 const struct imxmmc_platform_data sdhc_pdata __initconst = {
-	.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 const struct imxuart_platform_data uart_pdata __initconst = {
-	.flags = IMXUART_HAVE_RTSCTS,
-};
-
-static struct platform_device *devices[] __initdata = {
-	&armadillo5x0_smc911x_device,
-	&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));
-	imx31_add_imx_i2c1(NULL);
-
-	/* Register UART */
-	imx31_add_imx_uart0(&uart_pdata);
-	imx31_add_imx_uart1(&uart_pdata);
-
-	/* SMSC9118 IRQ pin */
-	gpio_direction_input(MX31_PIN_GPIO1_0);
-
-	/* Register SDHC */
-	imx31_add_mxc_mmc(0, &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 */
-	imx31_add_mxc_nand(&armadillo5x0_nand_board_info);
-
-	/* 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 */
-
-	usbotg_pdata.otg = imx_otg_ulpi_create(ULPI_OTG_DRVVBUS |
-			ULPI_OTG_DRVVBUS_EXT);
-	if (usbotg_pdata.otg)
-		imx31_add_mxc_ehci_otg(&usbotg_pdata);
-	usbh2_pdata.otg = imx_otg_ulpi_create(ULPI_OTG_DRVVBUS |
-			ULPI_OTG_DRVVBUS_EXT);
-	if (usbh2_pdata.otg)
-		imx31_add_mxc_ehci_hs(2, &usbh2_pdata);
-}
-
-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  */
-	.boot_params = MX3x_PHYS_OFFSET + 0x100,
-	.map_io = mx31_map_io,
-	.init_early = imx31_init_early,
-	.init_irq = mx31_init_irq,
-	.timer = &armadillo5x0_timer,
-	.init_machine = armadillo5x0_init,
-MACHINE_END
diff -druN linux-2.6.39-libre/arch/arm/mach-mx3/mach-bug.c linux-3.0-rc7-libre/arch/arm/mach-mx3/mach-bug.c
--- linux-2.6.39-libre/arch/arm/mach-mx3/mach-bug.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-mx3/mach-bug.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,66 +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 2011 Denis 'GNUtoo' Carikli <GNUtoo@no-log.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.
- */
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/platform_device.h>
-
-#include <mach/iomux-mx3.h>
-#include <mach/imx-uart.h>
-#include <mach/hardware.h>
-#include <mach/common.h>
-
-#include <asm/mach/time.h>
-#include <asm/mach/arch.h>
-#include <asm/mach-types.h>
-
-#include "devices-imx31.h"
-
-static const struct imxuart_platform_data uart_pdata __initconst = {
-	.flags = IMXUART_HAVE_RTSCTS,
-};
-
-static const unsigned int bug_pins[] __initconst = {
-	MX31_PIN_PC_RST__CTS5,
-	MX31_PIN_PC_VS2__RTS5,
-	MX31_PIN_PC_BVD2__TXD5,
-	MX31_PIN_PC_BVD1__RXD5,
-};
-
-static void __init bug_board_init(void)
-{
-	mxc_iomux_setup_multiple_pins(bug_pins,
-				      ARRAY_SIZE(bug_pins), "uart-4");
-	imx31_add_imx_uart4(&uart_pdata);
-}
-
-static void __init bug_timer_init(void)
-{
-	mx31_clocks_init(26000000);
-}
-
-static struct sys_timer bug_timer = {
-	.init = bug_timer_init,
-};
-
-MACHINE_START(BUG, "BugLabs BUGBase")
-	.map_io = mx31_map_io,
-	.init_early = imx31_init_early,
-	.init_irq = mx31_init_irq,
-	.timer = &bug_timer,
-	.init_machine = bug_board_init,
-MACHINE_END
diff -druN linux-2.6.39-libre/arch/arm/mach-mx3/mach-cpuimx35.c linux-3.0-rc7-libre/arch/arm/mach-mx3/mach-cpuimx35.c
--- linux-2.6.39-libre/arch/arm/mach-mx3/mach-cpuimx35.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-mx3/mach-cpuimx35.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,203 +0,0 @@
-/*
- * Copyright (C) 2010 Eric Benard - eric@eukrea.com
- * 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/memory.h>
-#include <linux/gpio.h>
-#include <linux/interrupt.h>
-#include <linux/delay.h>
-#include <linux/i2c.h>
-#include <linux/i2c/tsc2007.h>
-#include <linux/usb/otg.h>
-#include <linux/usb/ulpi.h>
-#include <linux/i2c-gpio.h>
-
-#include <asm/mach-types.h>
-#include <asm/mach/arch.h>
-#include <asm/mach/time.h>
-#include <asm/mach/map.h>
-
-#include <mach/eukrea-baseboards.h>
-#include <mach/hardware.h>
-#include <mach/common.h>
-#include <mach/iomux-mx35.h>
-#include <mach/mxc_nand.h>
-
-#include "devices-imx35.h"
-#include "devices.h"
-
-static const struct imxuart_platform_data uart_pdata __initconst = {
-	.flags = IMXUART_HAVE_RTSCTS,
-};
-
-static const struct imxi2c_platform_data
-		eukrea_cpuimx35_i2c0_data __initconst = {
-	.bitrate =		100000,
-};
-
-static struct tsc2007_platform_data tsc2007_info = {
-	.model			= 2007,
-	.x_plate_ohms		= 180,
-};
-
-#define TSC2007_IRQGPIO		IMX_GPIO_NR(3, 2)
-static struct i2c_board_info eukrea_cpuimx35_i2c_devices[] = {
-	{
-		I2C_BOARD_INFO("pcf8563", 0x51),
-	}, {
-		I2C_BOARD_INFO("tsc2007", 0x48),
-		.type		= "tsc2007",
-		.platform_data	= &tsc2007_info,
-		.irq		= gpio_to_irq(TSC2007_IRQGPIO),
-	},
-};
-
-static iomux_v3_cfg_t eukrea_cpuimx35_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,
-	/* I2C1 */
-	MX35_PAD_I2C1_CLK__I2C1_SCL,
-	MX35_PAD_I2C1_DAT__I2C1_SDA,
-	/* TSC2007 IRQ */
-	MX35_PAD_ATA_DA2__GPIO3_2,
-};
-
-static const struct mxc_nand_platform_data
-		eukrea_cpuimx35_nand_board_info __initconst = {
-	.width		= 1,
-	.hw_ecc		= 1,
-	.flash_bbt	= 1,
-};
-
-static int eukrea_cpuimx35_otg_init(struct platform_device *pdev)
-{
-	return mx35_initialize_usb_hw(pdev->id, MXC_EHCI_INTERFACE_DIFF_UNI);
-}
-
-static const struct mxc_usbh_platform_data otg_pdata __initconst = {
-	.init	= eukrea_cpuimx35_otg_init,
-	.portsc	= MXC_EHCI_MODE_UTMI,
-};
-
-static int eukrea_cpuimx35_usbh1_init(struct platform_device *pdev)
-{
-	return mx35_initialize_usb_hw(pdev->id, MXC_EHCI_INTERFACE_SINGLE_UNI |
-			MXC_EHCI_INTERNAL_PHY | MXC_EHCI_IPPUE_DOWN);
-}
-
-static const struct mxc_usbh_platform_data usbh1_pdata __initconst = {
-	.init	= eukrea_cpuimx35_usbh1_init,
-	.portsc	= MXC_EHCI_MODE_SERIAL,
-};
-
-static const struct fsl_usb2_platform_data otg_device_pdata __initconst = {
-	.operating_mode	= FSL_USB2_DR_DEVICE,
-	.phy_mode	= FSL_USB2_PHY_UTMI,
-	.workaround	= FLS_USB2_WORKAROUND_ENGCM09152,
-};
-
-static int otg_mode_host;
-
-static int __init eukrea_cpuimx35_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=", eukrea_cpuimx35_otg_mode);
-
-/*
- * Board specific initialization.
- */
-static void __init eukrea_cpuimx35_init(void)
-{
-	mxc_iomux_v3_setup_multiple_pads(eukrea_cpuimx35_pads,
-			ARRAY_SIZE(eukrea_cpuimx35_pads));
-
-	imx35_add_fec(NULL);
-	imx35_add_imx2_wdt(NULL);
-
-	imx35_add_imx_uart0(&uart_pdata);
-	imx35_add_mxc_nand(&eukrea_cpuimx35_nand_board_info);
-
-	i2c_register_board_info(0, eukrea_cpuimx35_i2c_devices,
-			ARRAY_SIZE(eukrea_cpuimx35_i2c_devices));
-	imx35_add_imx_i2c0(&eukrea_cpuimx35_i2c0_data);
-
-	if (otg_mode_host)
-		imx35_add_mxc_ehci_otg(&otg_pdata);
-	else
-		imx35_add_fsl_usb2_udc(&otg_device_pdata);
-
-	imx35_add_mxc_ehci_hs(&usbh1_pdata);
-
-#ifdef CONFIG_MACH_EUKREA_MBIMXSD35_BASEBOARD
-	eukrea_mbimxsd35_baseboard_init();
-#endif
-}
-
-static void __init eukrea_cpuimx35_timer_init(void)
-{
-	mx35_clocks_init();
-}
-
-struct sys_timer eukrea_cpuimx35_timer = {
-	.init	= eukrea_cpuimx35_timer_init,
-};
-
-MACHINE_START(EUKREA_CPUIMX35, "Eukrea CPUIMX35")
-	/* Maintainer: Eukrea Electromatique */
-	.boot_params = MX3x_PHYS_OFFSET + 0x100,
-	.map_io = mx35_map_io,
-	.init_early = imx35_init_early,
-	.init_irq = mx35_init_irq,
-	.timer = &eukrea_cpuimx35_timer,
-	.init_machine = eukrea_cpuimx35_init,
-MACHINE_END
diff -druN linux-2.6.39-libre/arch/arm/mach-mx3/mach-kzm_arm11_01.c linux-3.0-rc7-libre/arch/arm/mach-mx3/mach-kzm_arm11_01.c
--- linux-2.6.39-libre/arch/arm/mach-mx3/mach-kzm_arm11_01.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-mx3/mach-kzm_arm11_01.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,279 +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.
- */
-
-#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/memory.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/clock.h>
-#include <mach/common.h>
-#include <mach/iomux-mx3.h>
-
-#include "devices-imx31.h"
-#include "devices.h"
-
-#define KZM_ARM11_IO_ADDRESS(x) (IOMEM(					\
-	IMX_IO_P2V_MODULE(x, MX31_CS4) ?:				\
-	IMX_IO_P2V_MODULE(x, MX31_CS5)) ?:				\
-	MX31_IO_ADDRESS(x))
-
-/*
- *  KZM-ARM11-01 Board Control Registers on FPGA
- */
-#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		(MX31_CS4_BASE_ADDR + 0x1050)
-
-#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 const struct imxuart_platform_data uart_pdata __initconst = {
-	.flags = IMXUART_HAVE_RTSCTS,
-};
-
-static void __init kzm_init_imx_uart(void)
-{
-	imx31_add_imx_uart0(&uart_pdata);
-	imx31_add_imx_uart1(&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,
-};
-
-MACHINE_START(KZM_ARM11_01, "Kyoto Microcomputer Co., Ltd. KZM-ARM11-01")
-	.boot_params = MX3x_PHYS_OFFSET + 0x100,
-	.map_io = kzm_map_io,
-	.init_early = imx31_init_early,
-	.init_irq = mx31_init_irq,
-	.timer = &kzm_timer,
-	.init_machine = kzm_board_init,
-MACHINE_END
diff -druN linux-2.6.39-libre/arch/arm/mach-mx3/mach-mx31_3ds.c linux-3.0-rc7-libre/arch/arm/mach-mx3/mach-mx31_3ds.c
--- linux-2.6.39-libre/arch/arm/mach-mx3/mach-mx31_3ds.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-mx3/mach-mx31_3ds.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,771 +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.
- */
-
-#include <linux/delay.h>
-#include <linux/types.h>
-#include <linux/init.h>
-#include <linux/clk.h>
-#include <linux/irq.h>
-#include <linux/gpio.h>
-#include <linux/platform_device.h>
-#include <linux/mfd/mc13783.h>
-#include <linux/spi/spi.h>
-#include <linux/spi/l4f00242t03.h>
-#include <linux/regulator/machine.h>
-#include <linux/usb/otg.h>
-#include <linux/usb/ulpi.h>
-#include <linux/memblock.h>
-
-#include <media/soc_camera.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/iomux-mx3.h>
-#include <mach/3ds_debugboard.h>
-#include <mach/ulpi.h>
-#include <mach/mmc.h>
-#include <mach/ipu.h>
-#include <mach/mx3fb.h>
-#include <mach/mx3_camera.h>
-
-#include "devices-imx31.h"
-#include "devices.h"
-
-/* CPLD IRQ line for external uart, external ethernet etc */
-#define EXPIO_PARENT_INT	IOMUX_TO_IRQ(MX31_PIN_GPIO1_1)
-
-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),
-	/*SPI0*/
-	MX31_PIN_CSPI1_SCLK__SCLK,
-	MX31_PIN_CSPI1_MOSI__MOSI,
-	MX31_PIN_CSPI1_MISO__MISO,
-	MX31_PIN_CSPI1_SPI_RDY__SPI_RDY,
-	MX31_PIN_CSPI1_SS2__SS2, /* CS for LCD */
-	/* 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),
-	/* USB OTG reset */
-	IOMUX_MODE(MX31_PIN_USB_PWR, IOMUX_CONFIG_GPIO),
-	/* 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,
-	/*Keyboard*/
-	MX31_PIN_KEY_ROW0_KEY_ROW0,
-	MX31_PIN_KEY_ROW1_KEY_ROW1,
-	MX31_PIN_KEY_ROW2_KEY_ROW2,
-	MX31_PIN_KEY_COL0_KEY_COL0,
-	MX31_PIN_KEY_COL1_KEY_COL1,
-	MX31_PIN_KEY_COL2_KEY_COL2,
-	MX31_PIN_KEY_COL3_KEY_COL3,
-	/* 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_PC_VS2, IOMUX_CONFIG_ALT1),
-	IOMUX_MODE(MX31_PIN_PC_BVD1, IOMUX_CONFIG_ALT1),
-	IOMUX_MODE(MX31_PIN_PC_BVD2, IOMUX_CONFIG_ALT1),
-	IOMUX_MODE(MX31_PIN_PC_RST, IOMUX_CONFIG_ALT1),
-	IOMUX_MODE(MX31_PIN_IOIS16, IOMUX_CONFIG_ALT1),
-	IOMUX_MODE(MX31_PIN_PC_RW_B, IOMUX_CONFIG_ALT1),
-	/* USB Host2 reset */
-	IOMUX_MODE(MX31_PIN_USB_BYP, IOMUX_CONFIG_GPIO),
-	/* I2C1 */
-	MX31_PIN_I2C_CLK__I2C1_SCL,
-	MX31_PIN_I2C_DAT__I2C1_SDA,
-	/* 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_GPIO3_1__GPIO3_1, /* Card detect */
-	MX31_PIN_GPIO3_0__GPIO3_0, /* OE */
-	/* 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_CONTRAST__CONTRAST,
-	/* CSI */
-	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_CSI_D5__GPIO3_5, /* CMOS PWDN */
-	IOMUX_MODE(MX31_PIN_RI_DTE1, IOMUX_CONFIG_GPIO), /* CMOS reset */
-};
-
-/*
- * Camera support
- */
-static phys_addr_t mx3_camera_base __initdata;
-#define MX31_3DS_CAMERA_BUF_SIZE SZ_8M
-
-#define MX31_3DS_GPIO_CAMERA_PW IOMUX_TO_GPIO(MX31_PIN_CSI_D5)
-#define MX31_3DS_GPIO_CAMERA_RST IOMUX_TO_GPIO(MX31_PIN_RI_DTE1)
-
-static struct gpio mx31_3ds_camera_gpios[] = {
-	{ MX31_3DS_GPIO_CAMERA_PW, GPIOF_OUT_INIT_HIGH, "camera-power" },
-	{ MX31_3DS_GPIO_CAMERA_RST, GPIOF_OUT_INIT_HIGH, "camera-reset" },
-};
-
-static int __init mx31_3ds_camera_alloc_dma(void)
-{
-	int dma;
-
-	if (!mx3_camera_base)
-		return -ENOMEM;
-
-	dma = dma_declare_coherent_memory(&mx3_camera.dev,
-					mx3_camera_base, mx3_camera_base,
-					MX31_3DS_CAMERA_BUF_SIZE,
-					DMA_MEMORY_MAP | DMA_MEMORY_EXCLUSIVE);
-
-	if (!(dma & DMA_MEMORY_MAP))
-		return -ENOMEM;
-
-	return 0;
-}
-
-static int mx31_3ds_camera_power(struct device *dev, int on)
-{
-	/* enable or disable the camera */
-	pr_debug("%s: %s the camera\n", __func__, on ? "ENABLE" : "DISABLE");
-	gpio_set_value(MX31_3DS_GPIO_CAMERA_PW, on ? 0 : 1);
-
-	if (!on)
-		goto out;
-
-	/* If enabled, give a reset impulse */
-	gpio_set_value(MX31_3DS_GPIO_CAMERA_RST, 0);
-	msleep(20);
-	gpio_set_value(MX31_3DS_GPIO_CAMERA_RST, 1);
-	msleep(100);
-
-out:
-	return 0;
-}
-
-static struct i2c_board_info mx31_3ds_i2c_camera = {
-	I2C_BOARD_INFO("ov2640", 0x30),
-};
-
-static struct regulator_bulk_data mx31_3ds_camera_regs[] = {
-	{ .supply = "cmos_vcore" },
-	{ .supply = "cmos_2v8" },
-};
-
-static struct soc_camera_link iclink_ov2640 = {
-	.bus_id		= 0,
-	.board_info	= &mx31_3ds_i2c_camera,
-	.i2c_adapter_id	= 0,
-	.power		= mx31_3ds_camera_power,
-	.regulators	= mx31_3ds_camera_regs,
-	.num_regulators	= ARRAY_SIZE(mx31_3ds_camera_regs),
-};
-
-static struct platform_device mx31_3ds_ov2640 = {
-	.name	= "soc-camera-pdrv",
-	.id	= 0,
-	.dev	= {
-		.platform_data = &iclink_ov2640,
-	},
-};
-
-struct mx3_camera_pdata mx31_3ds_camera_pdata = {
-	.dma_dev	= &mx3_ipu.dev,
-	.flags		= MX3_CAMERA_DATAWIDTH_10,
-	.mclk_10khz	= 2600,
-};
-
-/*
- * FB support
- */
-static const struct fb_videomode fb_modedb[] = {
-	{	/* 480x640 @ 60 Hz */
-		.name		= "Epson-VGA",
-		.refresh	= 60,
-		.xres		= 480,
-		.yres		= 640,
-		.pixclock	= 41701,
-		.left_margin	= 20,
-		.right_margin	= 41,
-		.upper_margin	= 10,
-		.lower_margin	= 5,
-		.hsync_len	= 20,
-		.vsync_len	= 10,
-		.sync		= FB_SYNC_OE_ACT_HIGH | FB_SYNC_CLK_INVERT,
-		.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		= "Epson-VGA",
-	.mode		= fb_modedb,
-	.num_modes	= ARRAY_SIZE(fb_modedb),
-};
-
-/* LCD */
-static struct l4f00242t03_pdata mx31_3ds_l4f00242t03_pdata = {
-	.reset_gpio		= IOMUX_TO_GPIO(MX31_PIN_LCS1),
-	.data_enable_gpio	= IOMUX_TO_GPIO(MX31_PIN_SER_RS),
-	.core_supply		= "lcd_2v8",
-	.io_supply		= "vdd_lcdio",
-};
-
-/*
- * Support for SD card slot in personality board
- */
-#define MX31_3DS_GPIO_SDHC1_CD IOMUX_TO_GPIO(MX31_PIN_GPIO3_1)
-#define MX31_3DS_GPIO_SDHC1_BE IOMUX_TO_GPIO(MX31_PIN_GPIO3_0)
-
-static struct gpio mx31_3ds_sdhc1_gpios[] = {
-	{ MX31_3DS_GPIO_SDHC1_CD, GPIOF_IN, "sdhc1-card-detect" },
-	{ MX31_3DS_GPIO_SDHC1_BE, GPIOF_OUT_INIT_LOW, "sdhc1-bus-en" },
-};
-
-static int mx31_3ds_sdhc1_init(struct device *dev,
-			       irq_handler_t detect_irq,
-			       void *data)
-{
-	int ret;
-
-	ret = gpio_request_array(mx31_3ds_sdhc1_gpios,
-				 ARRAY_SIZE(mx31_3ds_sdhc1_gpios));
-	if (ret) {
-		pr_warning("Unable to request the SD/MMC GPIOs.\n");
-		return ret;
-	}
-
-	ret = request_irq(IOMUX_TO_IRQ(MX31_PIN_GPIO3_1),
-			  detect_irq, IRQF_DISABLED |
-			  IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING,
-			  "sdhc1-detect", data);
-	if (ret) {
-		pr_warning("Unable to request the SD/MMC card-detect IRQ.\n");
-		goto gpio_free;
-	}
-
-	return 0;
-
-gpio_free:
-	gpio_free_array(mx31_3ds_sdhc1_gpios,
-			ARRAY_SIZE(mx31_3ds_sdhc1_gpios));
-	return ret;
-}
-
-static void mx31_3ds_sdhc1_exit(struct device *dev, void *data)
-{
-	free_irq(IOMUX_TO_IRQ(MX31_PIN_GPIO3_1), data);
-	gpio_free_array(mx31_3ds_sdhc1_gpios,
-			 ARRAY_SIZE(mx31_3ds_sdhc1_gpios));
-}
-
-static void mx31_3ds_sdhc1_setpower(struct device *dev, unsigned int vdd)
-{
-	/*
-	 * While the voltage stuff is done by the driver, activate the
-	 * Buffer Enable Pin only if there is a card in slot to fix the card
-	 * voltage issue caused by bi-directional chip TXB0108 on 3Stack.
-	 * Done here because at this stage we have for sure a debounced value
-	 * of the presence of the card, showed by the value of vdd.
-	 * 7 == ilog2(MMC_VDD_165_195)
-	 */
-	if (vdd > 7)
-		gpio_set_value(MX31_3DS_GPIO_SDHC1_BE, 1);
-	else
-		gpio_set_value(MX31_3DS_GPIO_SDHC1_BE, 0);
-}
-
-static struct imxmmc_platform_data sdhc1_pdata = {
-	.init		= mx31_3ds_sdhc1_init,
-	.exit		= mx31_3ds_sdhc1_exit,
-	.setpower	= mx31_3ds_sdhc1_setpower,
-};
-
-/*
- * Matrix keyboard
- */
-
-static const uint32_t mx31_3ds_keymap[] = {
-	KEY(0, 0, KEY_UP),
-	KEY(0, 1, KEY_DOWN),
-	KEY(1, 0, KEY_RIGHT),
-	KEY(1, 1, KEY_LEFT),
-	KEY(1, 2, KEY_ENTER),
-	KEY(2, 0, KEY_F6),
-	KEY(2, 1, KEY_F8),
-	KEY(2, 2, KEY_F9),
-	KEY(2, 3, KEY_F10),
-};
-
-static const struct matrix_keymap_data mx31_3ds_keymap_data __initconst = {
-	.keymap		= mx31_3ds_keymap,
-	.keymap_size	= ARRAY_SIZE(mx31_3ds_keymap),
-};
-
-/* Regulators */
-static struct regulator_init_data pwgtx_init = {
-	.constraints = {
-		.boot_on	= 1,
-		.always_on	= 1,
-	},
-};
-
-static struct regulator_init_data gpo_init = {
-	.constraints = {
-		.boot_on = 1,
-		.always_on = 1,
-	}
-};
-
-static struct regulator_consumer_supply vmmc2_consumers[] = {
-	REGULATOR_SUPPLY("vmmc", "mxc-mmc.0"),
-};
-
-static struct regulator_init_data vmmc2_init = {
-	.constraints = {
-		.min_uV = 3000000,
-		.max_uV = 3000000,
-		.valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
-				  REGULATOR_CHANGE_STATUS,
-	},
-	.num_consumer_supplies = ARRAY_SIZE(vmmc2_consumers),
-	.consumer_supplies = vmmc2_consumers,
-};
-
-static struct regulator_consumer_supply vmmc1_consumers[] = {
-	REGULATOR_SUPPLY("lcd_2v8", NULL),
-	REGULATOR_SUPPLY("cmos_2v8", "soc-camera-pdrv.0"),
-};
-
-static struct regulator_init_data vmmc1_init = {
-	.constraints = {
-		.min_uV = 2800000,
-		.max_uV = 2800000,
-		.apply_uV = 1,
-		.valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
-				  REGULATOR_CHANGE_STATUS,
-	},
-	.num_consumer_supplies = ARRAY_SIZE(vmmc1_consumers),
-	.consumer_supplies = vmmc1_consumers,
-};
-
-static struct regulator_consumer_supply vgen_consumers[] = {
-	REGULATOR_SUPPLY("vdd_lcdio", NULL),
-};
-
-static struct regulator_init_data vgen_init = {
-	.constraints = {
-		.min_uV = 1800000,
-		.max_uV = 1800000,
-		.apply_uV = 1,
-		.valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
-				  REGULATOR_CHANGE_STATUS,
-	},
-	.num_consumer_supplies = ARRAY_SIZE(vgen_consumers),
-	.consumer_supplies = vgen_consumers,
-};
-
-static struct regulator_consumer_supply vvib_consumers[] = {
-	REGULATOR_SUPPLY("cmos_vcore", "soc-camera-pdrv.0"),
-};
-
-static struct regulator_init_data vvib_init = {
-	.constraints = {
-		.min_uV = 1300000,
-		.max_uV = 1300000,
-		.apply_uV = 1,
-		.valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
-				  REGULATOR_CHANGE_STATUS,
-	},
-	.num_consumer_supplies = ARRAY_SIZE(vvib_consumers),
-	.consumer_supplies = vvib_consumers,
-};
-
-static struct mc13xxx_regulator_init_data mx31_3ds_regulators[] = {
-	{
-		.id = MC13783_REG_PWGT1SPI, /* Power Gate for ARM core. */
-		.init_data = &pwgtx_init,
-	}, {
-		.id = MC13783_REG_PWGT2SPI, /* Power Gate for L2 Cache. */
-		.init_data = &pwgtx_init,
-	}, {
-
-		.id = MC13783_REG_GPO1, /* Turn on 1.8V */
-		.init_data = &gpo_init,
-	}, {
-		.id = MC13783_REG_GPO3, /* Turn on 3.3V */
-		.init_data = &gpo_init,
-	}, {
-		.id = MC13783_REG_VMMC2, /* Power MMC/SD, WiFi/Bluetooth. */
-		.init_data = &vmmc2_init,
-	}, {
-		.id = MC13783_REG_VMMC1, /* Power LCD, CMOS, FM, GPS, Accel. */
-		.init_data = &vmmc1_init,
-	}, {
-		.id = MC13783_REG_VGEN,  /* Power LCD */
-		.init_data = &vgen_init,
-	}, {
-		.id = MC13783_REG_VVIB,  /* Power CMOS */
-		.init_data = &vvib_init,
-	},
-};
-
-/* MC13783 */
-static struct mc13xxx_platform_data mc13783_pdata = {
-	.regulators = {
-		.regulators = mx31_3ds_regulators,
-		.num_regulators = ARRAY_SIZE(mx31_3ds_regulators),
-	},
-	.flags  = MC13783_USE_REGULATOR | MC13783_USE_TOUCHSCREEN,
-};
-
-/* SPI */
-static int spi0_internal_chipselect[] = {
-	MXC_SPI_CS(2),
-};
-
-static const struct spi_imx_master spi0_pdata __initconst = {
-	.chipselect	= spi0_internal_chipselect,
-	.num_chipselect	= ARRAY_SIZE(spi0_internal_chipselect),
-};
-
-static int spi1_internal_chipselect[] = {
-	MXC_SPI_CS(0),
-	MXC_SPI_CS(2),
-};
-
-static const struct spi_imx_master spi1_pdata __initconst = {
-	.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,
-	}, {
-		.modalias	= "l4f00242t03",
-		.max_speed_hz	= 5000000,
-		.bus_num	= 0,
-		.chip_select	= 0, /* SS2 */
-		.platform_data	= &mx31_3ds_l4f00242t03_pdata,
-	},
-};
-
-/*
- * NAND Flash
- */
-static const struct mxc_nand_platform_data
-mx31_3ds_nand_board_info __initconst = {
-	.width		= 1,
-	.hw_ecc		= 1,
-#ifdef MACH_MX31_3DS_MXC_NAND_USE_BBT
-	.flash_bbt	= 1,
-#endif
-};
-
-/*
- * USB OTG
- */
-
-#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 USBOTG_RST_B IOMUX_TO_GPIO(MX31_PIN_USB_PWR)
-#define USBH2_RST_B IOMUX_TO_GPIO(MX31_PIN_USB_BYP)
-
-static int mx31_3ds_usbotg_init(void)
-{
-	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);
-
-	err = gpio_request(USBOTG_RST_B, "otgusb-reset");
-	if (err) {
-		pr_err("Failed to request the USB OTG reset gpio\n");
-		return err;
-	}
-
-	err = gpio_direction_output(USBOTG_RST_B, 0);
-	if (err) {
-		pr_err("Failed to drive the USB OTG reset gpio\n");
-		goto usbotg_free_reset;
-	}
-
-	mdelay(1);
-	gpio_set_value(USBOTG_RST_B, 1);
-	return 0;
-
-usbotg_free_reset:
-	gpio_free(USBOTG_RST_B);
-	return err;
-}
-
-static int mx31_3ds_otg_init(struct platform_device *pdev)
-{
-	return mx31_initialize_usb_hw(pdev->id, MXC_EHCI_POWER_PINS_ENABLED);
-}
-
-static int mx31_3ds_host2_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_PC_VS2, USB_PAD_CFG);
-	mxc_iomux_set_pad(MX31_PIN_PC_BVD1, USB_PAD_CFG);
-	mxc_iomux_set_pad(MX31_PIN_PC_BVD2, USB_PAD_CFG);
-	mxc_iomux_set_pad(MX31_PIN_PC_RST, USB_PAD_CFG);
-	mxc_iomux_set_pad(MX31_PIN_IOIS16, USB_PAD_CFG);
-	mxc_iomux_set_pad(MX31_PIN_PC_RW_B, USB_PAD_CFG);
-
-	err = gpio_request(USBH2_RST_B, "usbh2-reset");
-	if (err) {
-		pr_err("Failed to request the USB Host 2 reset gpio\n");
-		return err;
-	}
-
-	err = gpio_direction_output(USBH2_RST_B, 0);
-	if (err) {
-		pr_err("Failed to drive the USB Host 2 reset gpio\n");
-		goto usbotg_free_reset;
-	}
-
-	mdelay(1);
-	gpio_set_value(USBH2_RST_B, 1);
-
-	mdelay(10);
-
-	return mx31_initialize_usb_hw(pdev->id, MXC_EHCI_POWER_PINS_ENABLED);
-
-usbotg_free_reset:
-	gpio_free(USBH2_RST_B);
-	return err;
-}
-
-static struct mxc_usbh_platform_data otg_pdata __initdata = {
-	.init	= mx31_3ds_otg_init,
-	.portsc	= MXC_EHCI_MODE_ULPI,
-};
-
-static struct mxc_usbh_platform_data usbh2_pdata __initdata = {
-	.init = mx31_3ds_host2_init,
-	.portsc	= MXC_EHCI_MODE_ULPI,
-};
-
-static const struct fsl_usb2_platform_data usbotg_pdata __initconst = {
-	.operating_mode = FSL_USB2_DR_DEVICE,
-	.phy_mode	= FSL_USB2_PHY_ULPI,
-};
-
-static int otg_mode_host;
-
-static int __init mx31_3ds_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=", mx31_3ds_otg_mode);
-
-static const struct imxuart_platform_data uart_pdata __initconst = {
-	.flags = IMXUART_HAVE_RTSCTS,
-};
-
-static const struct imxi2c_platform_data mx31_3ds_i2c0_data __initconst = {
-	.bitrate = 100000,
-};
-
-static struct platform_device *devices[] __initdata = {
-	&mx31_3ds_ov2640,
-};
-
-static void __init mx31_3ds_init(void)
-{
-	int ret;
-
-	mxc_iomux_setup_multiple_pins(mx31_3ds_pins, ARRAY_SIZE(mx31_3ds_pins),
-				      "mx31_3ds");
-
-	imx31_add_imx_uart0(&uart_pdata);
-	imx31_add_mxc_nand(&mx31_3ds_nand_board_info);
-
-	imx31_add_spi_imx1(&spi1_pdata);
-	spi_register_board_info(mx31_3ds_spi_devs,
-						ARRAY_SIZE(mx31_3ds_spi_devs));
-
-	platform_add_devices(devices, ARRAY_SIZE(devices));
-
-	imx31_add_imx_keypad(&mx31_3ds_keymap_data);
-
-	mx31_3ds_usbotg_init();
-	if (otg_mode_host) {
-		otg_pdata.otg = imx_otg_ulpi_create(ULPI_OTG_DRVVBUS |
-				ULPI_OTG_DRVVBUS_EXT);
-		if (otg_pdata.otg)
-			imx31_add_mxc_ehci_otg(&otg_pdata);
-	}
-	usbh2_pdata.otg = imx_otg_ulpi_create(ULPI_OTG_DRVVBUS |
-			ULPI_OTG_DRVVBUS_EXT);
-	if (usbh2_pdata.otg)
-		imx31_add_mxc_ehci_hs(2, &usbh2_pdata);
-
-	if (!otg_mode_host)
-		imx31_add_fsl_usb2_udc(&usbotg_pdata);
-
-	if (mxc_expio_init(MX31_CS5_BASE_ADDR, EXPIO_PARENT_INT))
-		printk(KERN_WARNING "Init of the debug board failed, all "
-				    "devices on the debug board are unusable.\n");
-	imx31_add_imx2_wdt(NULL);
-	imx31_add_imx_i2c0(&mx31_3ds_i2c0_data);
-	imx31_add_mxc_mmc(0, &sdhc1_pdata);
-
-	imx31_add_spi_imx0(&spi0_pdata);
-	mxc_register_device(&mx3_ipu, &mx3_ipu_data);
-	mxc_register_device(&mx3_fb, &mx3fb_pdata);
-
-	/* CSI */
-	/* Camera power: default - off */
-	ret = gpio_request_array(mx31_3ds_camera_gpios,
-				 ARRAY_SIZE(mx31_3ds_camera_gpios));
-	if (ret) {
-		pr_err("Failed to request camera gpios");
-		iclink_ov2640.power = NULL;
-	}
-
-	if (!mx31_3ds_camera_alloc_dma())
-		mxc_register_device(&mx3_camera, &mx31_3ds_camera_pdata);
-	else
-		pr_err("Failed to allocate dma memory for camera");
-}
-
-static void __init mx31_3ds_timer_init(void)
-{
-	mx31_clocks_init(26000000);
-}
-
-static struct sys_timer mx31_3ds_timer = {
-	.init	= mx31_3ds_timer_init,
-};
-
-static void __init mx31_3ds_reserve(void)
-{
-	/* reserve MX31_3DS_CAMERA_BUF_SIZE bytes for mx3-camera */
-	mx3_camera_base = memblock_alloc(MX31_3DS_CAMERA_BUF_SIZE,
-					 MX31_3DS_CAMERA_BUF_SIZE);
-	memblock_free(mx3_camera_base, MX31_3DS_CAMERA_BUF_SIZE);
-	memblock_remove(mx3_camera_base, MX31_3DS_CAMERA_BUF_SIZE);
-}
-
-MACHINE_START(MX31_3DS, "Freescale MX31PDK (3DS)")
-	/* Maintainer: Freescale Semiconductor, Inc. */
-	.boot_params = MX3x_PHYS_OFFSET + 0x100,
-	.map_io = mx31_map_io,
-	.init_early = imx31_init_early,
-	.init_irq = mx31_init_irq,
-	.timer = &mx31_3ds_timer,
-	.init_machine = mx31_3ds_init,
-	.reserve = mx31_3ds_reserve,
-MACHINE_END
diff -druN linux-2.6.39-libre/arch/arm/mach-mx3/mach-mx31ads.c linux-3.0-rc7-libre/arch/arm/mach-mx3/mach-mx31ads.c
--- linux-2.6.39-libre/arch/arm/mach-mx3/mach-mx31ads.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-mx3/mach-mx31ads.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,543 +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.
- */
-
-#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 <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/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-imx31.h"
-#include "devices.h"
-
-/* PBC Board interrupt status register */
-#define PBC_INTSTATUS           0x000016
-
-/* PBC Board interrupt current status register */
-#define PBC_INTCURR_STATUS      0x000018
-
-/* PBC Interrupt mask register set address */
-#define PBC_INTMASK_SET         0x00001A
-
-/* PBC Interrupt mask register clear address */
-#define PBC_INTMASK_CLEAR       0x00001C
-
-/* External UART A */
-#define PBC_SC16C652_UARTA      0x010000
-
-/* External UART B */
-#define PBC_SC16C652_UARTB      0x010010
-
-#define PBC_INTSTATUS_REG	(PBC_INTSTATUS + PBC_BASE_ADDRESS)
-#define PBC_INTMASK_SET_REG	(PBC_INTMASK_SET + PBC_BASE_ADDRESS)
-#define PBC_INTMASK_CLEAR_REG	(PBC_INTMASK_CLEAR + PBC_BASE_ADDRESS)
-#define EXPIO_PARENT_INT	IOMUX_TO_IRQ(MX31_PIN_GPIO1_4)
-
-#define MXC_IRQ_TO_EXPIO(irq)	((irq) - MXC_EXP_IO_BASE)
-
-#define EXPIO_INT_XUART_INTA	(MXC_EXP_IO_BASE + 10)
-#define EXPIO_INT_XUART_INTB	(MXC_EXP_IO_BASE + 11)
-
-#define MXC_MAX_EXP_IO_LINES	16
-
-/*
- * 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);
-}
-
-static const struct imxuart_platform_data uart_pdata __initconst = {
-	.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");
-	imx31_add_imx_uart0(&uart_pdata);
-}
-
-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 d	an expio virtual irq description
- */
-static void expio_mask_irq(struct irq_data *d)
-{
-	u32 expio = MXC_IRQ_TO_EXPIO(d->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 d	an expio virtual irq description
- */
-static void expio_ack_irq(struct irq_data *d)
-{
-	u32 expio = MXC_IRQ_TO_EXPIO(d->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 d	an expio virtual irq description
- */
-static void expio_unmask_irq(struct irq_data *d)
-{
-	u32 expio = MXC_IRQ_TO_EXPIO(d->irq);
-	/* unmask the interrupt */
-	__raw_writew(1 << expio, PBC_INTMASK_SET_REG);
-}
-
-static struct irq_chip expio_irq_chip = {
-	.name = "EXPIO(CPLD)",
-	.irq_ack = expio_ack_irq,
-	.irq_mask = expio_mask_irq,
-	.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++) {
-		irq_set_chip_and_handler(i, &expio_irq_chip, handle_level_irq);
-		set_irq_flags(i, IRQF_VALID);
-	}
-	irq_set_irq_type(EXPIO_PARENT_INT, IRQ_TYPE_LEVEL_HIGH);
-	irq_set_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
-
-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));
-
-	imx31_add_imx_i2c1(NULL);
-}
-
-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)
-{
-	imx31_add_imx_ssi(0, NULL);
-	mxc_iomux_setup_multiple_pins(ssi_pins, ARRAY_SIZE(ssi_pins), "ssi");
-}
-
-/* static mappings */
-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
-	},
-};
-
-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();
-}
-
-static void __init mx31ads_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,
-};
-
-MACHINE_START(MX31ADS, "Freescale MX31ADS")
-	/* Maintainer: Freescale Semiconductor, Inc. */
-	.boot_params = MX3x_PHYS_OFFSET + 0x100,
-	.map_io = mx31ads_map_io,
-	.init_early = imx31_init_early,
-	.init_irq = mx31ads_init_irq,
-	.timer = &mx31ads_timer,
-	.init_machine = mx31ads_init,
-MACHINE_END
diff -druN linux-2.6.39-libre/arch/arm/mach-mx3/mach-mx31lilly.c linux-3.0-rc7-libre/arch/arm/mach-mx3/mach-mx31lilly.c
--- linux-2.6.39-libre/arch/arm/mach-mx3/mach-mx31lilly.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-mx3/mach-mx31lilly.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,303 +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.
- */
-
-#include <linux/types.h>
-#include <linux/init.h>
-#include <linux/clk.h>
-#include <linux/gpio.h>
-#include <linux/delay.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 <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/hardware.h>
-#include <mach/common.h>
-#include <mach/iomux-mx3.h>
-#include <mach/board-mx31lilly.h>
-#include <mach/ulpi.h>
-
-#include "devices-imx31.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,
-};
-
-/* USB */
-
-#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 usbh1_init(struct platform_device *pdev)
-{
-	int pins[] = {
-		MX31_PIN_CSPI1_MOSI__USBH1_RXDM,
-		MX31_PIN_CSPI1_MISO__USBH1_RXDP,
-		MX31_PIN_CSPI1_SS0__USBH1_TXDM,
-		MX31_PIN_CSPI1_SS1__USBH1_TXDP,
-		MX31_PIN_CSPI1_SS2__USBH1_RCV,
-		MX31_PIN_CSPI1_SCLK__USBH1_OEB,
-		MX31_PIN_CSPI1_SPI_RDY__USBH1_FS,
-	};
-
-	mxc_iomux_setup_multiple_pins(pins, ARRAY_SIZE(pins), "USB H1");
-
-	mxc_iomux_set_pad(MX31_PIN_CSPI1_MOSI, USB_PAD_CFG);
-	mxc_iomux_set_pad(MX31_PIN_CSPI1_MISO, USB_PAD_CFG);
-	mxc_iomux_set_pad(MX31_PIN_CSPI1_SS0, USB_PAD_CFG);
-	mxc_iomux_set_pad(MX31_PIN_CSPI1_SS1, USB_PAD_CFG);
-	mxc_iomux_set_pad(MX31_PIN_CSPI1_SS2, USB_PAD_CFG);
-	mxc_iomux_set_pad(MX31_PIN_CSPI1_SCLK, USB_PAD_CFG);
-	mxc_iomux_set_pad(MX31_PIN_CSPI1_SPI_RDY, USB_PAD_CFG);
-
-	mxc_iomux_set_gpr(MUX_PGP_USB_SUSPEND, true);
-
-	mdelay(10);
-
-	return mx31_initialize_usb_hw(pdev->id, MXC_EHCI_POWER_PINS_ENABLED |
-			MXC_EHCI_INTERFACE_SINGLE_UNI);
-}
-
-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);
-
-	mdelay(10);
-
-	return mx31_initialize_usb_hw(pdev->id, MXC_EHCI_POWER_PINS_ENABLED);
-}
-
-static const struct mxc_usbh_platform_data usbh1_pdata __initconst = {
-	.init	= usbh1_init,
-	.portsc	= MXC_EHCI_MODE_UTMI | MXC_EHCI_SERIAL,
-};
-
-static struct mxc_usbh_platform_data usbh2_pdata __initdata = {
-	.init	= usbh2_init,
-	.portsc	= MXC_EHCI_MODE_ULPI | MXC_EHCI_UTMI_8BIT,
-};
-
-static void lilly1131_usb_init(void)
-{
-	imx31_add_mxc_ehci_hs(1, &usbh1_pdata);
-
-	usbh2_pdata.otg = imx_otg_ulpi_create(ULPI_OTG_DRVVBUS |
-			ULPI_OTG_DRVVBUS_EXT);
-	if (usbh2_pdata.otg)
-		imx31_add_mxc_ehci_hs(2, &usbh2_pdata);
-}
-
-/* SPI */
-
-static int spi_internal_chipselect[] = {
-	MXC_SPI_CS(0),
-	MXC_SPI_CS(1),
-	MXC_SPI_CS(2),
-};
-
-static const struct spi_imx_master spi0_pdata __initconst = {
-	.chipselect = spi_internal_chipselect,
-	.num_chipselect = ARRAY_SIZE(spi_internal_chipselect),
-};
-
-static const struct spi_imx_master spi1_pdata __initconst = {
-	.chipselect = spi_internal_chipselect,
-	.num_chipselect = ARRAY_SIZE(spi_internal_chipselect),
-};
-
-static struct mc13xxx_platform_data mc13783_pdata __initdata = {
-	.flags = MC13XXX_USE_RTC | MC13XXX_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,
-	.irq		= IOMUX_TO_IRQ(MX31_PIN_GPIO1_3),
-};
-
-static struct platform_device *devices[] __initdata = {
-	&smsc91x_device,
-	&physmap_flash_device,
-};
-
-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");
-
-	imx31_add_spi_imx0(&spi0_pdata);
-	imx31_add_spi_imx1(&spi1_pdata);
-	spi_register_board_info(&mc13783_dev, 1);
-
-	platform_add_devices(devices, ARRAY_SIZE(devices));
-
-	/* USB */
-	lilly1131_usb_init();
-}
-
-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")
-	.boot_params = MX3x_PHYS_OFFSET + 0x100,
-	.map_io = mx31_map_io,
-	.init_early = imx31_init_early,
-	.init_irq = mx31_init_irq,
-	.timer = &mx31lilly_timer,
-	.init_machine = mx31lilly_board_init,
-MACHINE_END
diff -druN linux-2.6.39-libre/arch/arm/mach-mx3/mach-mx31lite.c linux-3.0-rc7-libre/arch/arm/mach-mx3/mach-mx31lite.c
--- linux-2.6.39-libre/arch/arm/mach-mx3/mach-mx31lite.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-mx3/mach-mx31lite.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,288 +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.
- */
-
-#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 <linux/delay.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/iomux-mx3.h>
-#include <mach/irqs.h>
-#include <mach/ulpi.h>
-
-#include "devices-imx31.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 const struct mxc_nand_platform_data
-mx31lite_nand_board_info __initconst  = {
-	.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 const struct spi_imx_master spi1_pdata __initconst = {
-	.chipselect	= spi_internal_chipselect,
-	.num_chipselect	= ARRAY_SIZE(spi_internal_chipselect),
-};
-
-static struct mc13xxx_platform_data mc13783_pdata __initdata = {
-	.flags  = MC13XXX_USE_RTC |
-		  MC13XXX_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
- */
-
-#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);
-
-	mdelay(10);
-
-	return mx31_initialize_usb_hw(pdev->id, MXC_EHCI_POWER_PINS_ENABLED);
-}
-
-static struct mxc_usbh_platform_data usbh2_pdata __initdata = {
-	.init   = usbh2_init,
-	.portsc = MXC_EHCI_MODE_ULPI | MXC_EHCI_UTMI_8BIT,
-};
-
-/*
- * 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 mx31lite_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);
-	imx31_add_mxc_nand(&mx31lite_nand_board_info);
-
-	imx31_add_spi_imx1(&spi1_pdata);
-	spi_register_board_info(&mc13783_spi_dev, 1);
-
-	/* USB */
-	usbh2_pdata.otg = imx_otg_ulpi_create(ULPI_OTG_DRVVBUS |
-			ULPI_OTG_DRVVBUS_EXT);
-	if (usbh2_pdata.otg)
-		imx31_add_mxc_ehci_hs(2, &usbh2_pdata);
-
-	/* 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. */
-	.boot_params = MX3x_PHYS_OFFSET + 0x100,
-	.map_io = mx31lite_map_io,
-	.init_early = imx31_init_early,
-	.init_irq = mx31_init_irq,
-	.timer = &mx31lite_timer,
-	.init_machine = mx31lite_init,
-MACHINE_END
diff -druN linux-2.6.39-libre/arch/arm/mach-mx3/mach-mx31moboard.c linux-3.0-rc7-libre/arch/arm/mach-mx3/mach-mx31moboard.c
--- linux-2.6.39-libre/arch/arm/mach-mx3/mach-mx31moboard.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-mx3/mach-mx31moboard.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,576 +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.
- */
-
-#include <linux/delay.h>
-#include <linux/dma-mapping.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/iomux-mx3.h>
-#include <mach/ipu.h>
-#include <mach/mx3_camera.h>
-#include <mach/spi.h>
-#include <mach/ulpi.h>
-
-#include "devices-imx31.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)
-{
-	int ret = gpio_request(IOMUX_TO_GPIO(MX31_PIN_CTS1), "uart0-cts-hack");
-	if (ret)
-		return ret;
-
-	ret = gpio_direction_output(IOMUX_TO_GPIO(MX31_PIN_CTS1), 0);
-	if (ret)
-		gpio_free(IOMUX_TO_GPIO(MX31_PIN_CTS1));
-
-	return ret;
-}
-
-static void moboard_uart0_exit(struct platform_device *pdev)
-{
-	gpio_free(IOMUX_TO_GPIO(MX31_PIN_CTS1));
-}
-
-static const struct imxuart_platform_data uart0_pdata __initconst = {
-	.init = moboard_uart0_init,
-	.exit = moboard_uart0_exit,
-};
-
-static const struct imxuart_platform_data uart4_pdata __initconst = {
-	.flags = IMXUART_HAVE_RTSCTS,
-};
-
-static const struct imxi2c_platform_data moboard_i2c0_data __initconst = {
-	.bitrate = 400000,
-};
-
-static const struct imxi2c_platform_data moboard_i2c1_data __initconst = {
-	.bitrate = 100000,
-};
-
-static int moboard_spi1_cs[] = {
-	MXC_SPI_CS(0),
-	MXC_SPI_CS(2),
-};
-
-static const struct spi_imx_master moboard_spi1_pdata __initconst = {
-	.chipselect	= moboard_spi1_cs,
-	.num_chipselect	= ARRAY_SIZE(moboard_spi1_cs),
-};
-
-static struct regulator_consumer_supply sdhc_consumers[] = {
-	{
-		.dev_name = "mxc-mmc.0",
-		.supply	= "sdhc0_vcc",
-	},
-	{
-		.dev_name = "mxc-mmc.1",
-		.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 mc13xxx_regulator_init_data moboard_regulators[] = {
-	{
-		.id = MC13783_REG_VMMC1,
-		.init_data = &sdhc_vreg_data,
-	},
-	{
-		.id = MC13783_REG_VCAM,
-		.init_data = &cam_vreg_data,
-	},
-};
-
-static struct mc13783_led_platform_data moboard_led[] = {
-	{
-		.id = MC13783_LED_R1,
-		.name = "coreboard-led-4:red",
-		.max_current = 2,
-	},
-	{
-		.id = MC13783_LED_G1,
-		.name = "coreboard-led-4:green",
-		.max_current = 2,
-	},
-	{
-		.id = MC13783_LED_B1,
-		.name = "coreboard-led-4:blue",
-		.max_current = 2,
-	},
-	{
-		.id = MC13783_LED_R2,
-		.name = "coreboard-led-5:red",
-		.max_current = 3,
-	},
-	{
-		.id = MC13783_LED_G2,
-		.name = "coreboard-led-5:green",
-		.max_current = 3,
-	},
-	{
-		.id = MC13783_LED_B2,
-		.name = "coreboard-led-5:blue",
-		.max_current = 3,
-	},
-};
-
-static struct mc13783_leds_platform_data moboard_leds = {
-	.num_leds = ARRAY_SIZE(moboard_led),
-	.led = moboard_led,
-	.flags = MC13783_LED_SLEWLIMTC,
-	.abmode = MC13783_LED_AB_DISABLED,
-	.tc1_period = MC13783_LED_PERIOD_10MS,
-	.tc2_period = MC13783_LED_PERIOD_10MS,
-};
-
-static struct mc13xxx_platform_data moboard_pmic = {
-	.regulators = {
-		.regulators = moboard_regulators,
-		.num_regulators = ARRAY_SIZE(moboard_regulators),
-	},
-	.leds = &moboard_leds,
-	.flags = MC13XXX_USE_REGULATOR | MC13XXX_USE_RTC |
-		MC13XXX_USE_ADC | MC13XXX_USE_LED,
-};
-
-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 const struct spi_imx_master moboard_spi2_pdata __initconst = {
-	.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 const struct imxmmc_platform_data sdhc1_pdata __initconst = {
-	.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)
-#define USB_PAD_CFG (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST | PAD_CTL_HYS_CMOS | \
-		      PAD_CTL_ODE_CMOS)
-
-#define OTG_EN_B IOMUX_TO_GPIO(MX31_PIN_USB_OC)
-#define USBH2_EN_B IOMUX_TO_GPIO(MX31_PIN_SCK6)
-
-static void usb_xcvr_reset(void)
-{
-	mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA0, USB_PAD_CFG | PAD_CTL_100K_PD);
-	mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA1, USB_PAD_CFG | PAD_CTL_100K_PD);
-	mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA2, USB_PAD_CFG | PAD_CTL_100K_PD);
-	mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA3, USB_PAD_CFG | PAD_CTL_100K_PD);
-	mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA4, USB_PAD_CFG | PAD_CTL_100K_PD);
-	mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA5, USB_PAD_CFG | PAD_CTL_100K_PD);
-	mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA6, USB_PAD_CFG | PAD_CTL_100K_PD);
-	mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA7, USB_PAD_CFG | PAD_CTL_100K_PD);
-	mxc_iomux_set_pad(MX31_PIN_USBOTG_CLK, USB_PAD_CFG | PAD_CTL_100K_PU);
-	mxc_iomux_set_pad(MX31_PIN_USBOTG_DIR, USB_PAD_CFG | PAD_CTL_100K_PU);
-	mxc_iomux_set_pad(MX31_PIN_USBOTG_NXT, USB_PAD_CFG | PAD_CTL_100K_PU);
-	mxc_iomux_set_pad(MX31_PIN_USBOTG_STP, USB_PAD_CFG | PAD_CTL_100K_PU);
-
-	mxc_iomux_set_gpr(MUX_PGP_UH2, true);
-	mxc_iomux_set_pad(MX31_PIN_USBH2_CLK, USB_PAD_CFG | PAD_CTL_100K_PU);
-	mxc_iomux_set_pad(MX31_PIN_USBH2_DIR, USB_PAD_CFG | PAD_CTL_100K_PU);
-	mxc_iomux_set_pad(MX31_PIN_USBH2_NXT, USB_PAD_CFG | PAD_CTL_100K_PU);
-	mxc_iomux_set_pad(MX31_PIN_USBH2_STP, USB_PAD_CFG | PAD_CTL_100K_PU);
-	mxc_iomux_set_pad(MX31_PIN_USBH2_DATA0, USB_PAD_CFG | PAD_CTL_100K_PD);
-	mxc_iomux_set_pad(MX31_PIN_USBH2_DATA1, USB_PAD_CFG | PAD_CTL_100K_PD);
-	mxc_iomux_set_pad(MX31_PIN_SRXD6, USB_PAD_CFG | PAD_CTL_100K_PD);
-	mxc_iomux_set_pad(MX31_PIN_STXD6, USB_PAD_CFG | PAD_CTL_100K_PD);
-	mxc_iomux_set_pad(MX31_PIN_SFS3, USB_PAD_CFG | PAD_CTL_100K_PD);
-	mxc_iomux_set_pad(MX31_PIN_SCK3, USB_PAD_CFG | PAD_CTL_100K_PD);
-	mxc_iomux_set_pad(MX31_PIN_SRXD3, USB_PAD_CFG | PAD_CTL_100K_PD);
-	mxc_iomux_set_pad(MX31_PIN_STXD3, USB_PAD_CFG | PAD_CTL_100K_PD);
-
-	gpio_request(OTG_EN_B, "usb-udc-en");
-	gpio_direction_output(OTG_EN_B, 0);
-	gpio_request(USBH2_EN_B, "usbh2-en");
-	gpio_direction_output(USBH2_EN_B, 0);
-
-	gpio_request(USB_RESET_B, "usb-reset");
-	gpio_direction_output(USB_RESET_B, 0);
-	mdelay(1);
-	gpio_set_value(USB_RESET_B, 1);
-	mdelay(1);
-}
-
-static int moboard_usbh2_init_hw(struct platform_device *pdev)
-{
-	return mx31_initialize_usb_hw(pdev->id, MXC_EHCI_POWER_PINS_ENABLED);
-}
-
-static struct mxc_usbh_platform_data usbh2_pdata __initdata = {
-	.init	= moboard_usbh2_init_hw,
-	.portsc	= MXC_EHCI_MODE_ULPI | MXC_EHCI_UTMI_8BIT,
-};
-
-static int __init moboard_usbh2_init(void)
-{
-	struct platform_device *pdev;
-
-	usbh2_pdata.otg = imx_otg_ulpi_create(ULPI_OTG_DRVVBUS |
-			ULPI_OTG_DRVVBUS_EXT);
-	if (!usbh2_pdata.otg)
-		return -ENODEV;
-
-	pdev = imx31_add_mxc_ehci_hs(2, &usbh2_pdata);
-	if (IS_ERR(pdev))
-		return PTR_ERR(pdev);
-
-	return 0;
-}
-
-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 mx31moboard_init(void)
-{
-	mxc_iomux_setup_multiple_pins(moboard_pins, ARRAY_SIZE(moboard_pins),
-		"moboard");
-
-	platform_add_devices(devices, ARRAY_SIZE(devices));
-
-	imx31_add_imx_uart0(&uart0_pdata);
-	imx31_add_imx_uart4(&uart4_pdata);
-
-	imx31_add_imx_i2c0(&moboard_i2c0_data);
-	imx31_add_imx_i2c1(&moboard_i2c1_data);
-
-	imx31_add_spi_imx1(&moboard_spi1_pdata);
-	imx31_add_spi_imx2(&moboard_spi2_pdata);
-
-	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));
-
-	imx31_add_mxc_mmc(0, &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_usbh2_init();
-
-	switch (mx31moboard_baseboard) {
-	case MX31NOBOARD:
-		break;
-	case MX31DEVBOARD:
-		mx31moboard_devboard_init();
-		break;
-	case MX31MARXBOT:
-		mx31moboard_marxbot_init();
-		break;
-	case MX31SMARTBOT:
-	case MX31EYEBOT:
-		mx31moboard_smartbot_init(mx31moboard_baseboard);
-		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 */
-	.boot_params = MX3x_PHYS_OFFSET + 0x100,
-	.map_io = mx31_map_io,
-	.init_early = imx31_init_early,
-	.init_irq = mx31_init_irq,
-	.timer = &mx31moboard_timer,
-	.init_machine = mx31moboard_init,
-MACHINE_END
diff -druN linux-2.6.39-libre/arch/arm/mach-mx3/mach-mx35_3ds.c linux-3.0-rc7-libre/arch/arm/mach-mx3/mach-mx35_3ds.c
--- linux-2.6.39-libre/arch/arm/mach-mx3/mach-mx35_3ds.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-mx3/mach-mx35_3ds.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,225 +0,0 @@
-/*
- * Copyright 2009 Freescale Semiconductor, Inc. All Rights Reserved.
- * Copyright (C) 2009 Marc Kleine-Budde, Pengutronix
- *
- * 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.
- */
-
-/*
- * This machine is known as:
- *  - i.MX35 3-Stack Development System
- *  - i.MX35 Platform Development Kit (i.MX35 PDK)
- */
-
-#include <linux/types.h>
-#include <linux/init.h>
-#include <linux/platform_device.h>
-#include <linux/memory.h>
-#include <linux/gpio.h>
-#include <linux/usb/otg.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 <mach/hardware.h>
-#include <mach/common.h>
-#include <mach/iomux-mx35.h>
-#include <mach/irqs.h>
-#include <mach/3ds_debugboard.h>
-
-#include "devices-imx35.h"
-#include "devices.h"
-
-#define EXPIO_PARENT_INT	(MXC_INTERNAL_IRQS + GPIO_PORTA + 1)
-
-static const struct imxuart_platform_data uart_pdata __initconst = {
-	.flags = IMXUART_HAVE_RTSCTS,
-};
-
-static struct physmap_flash_data mx35pdk_flash_data = {
-	.width  = 2,
-};
-
-static struct resource mx35pdk_flash_resource = {
-	.start	= MX35_CS0_BASE_ADDR,
-	.end	= MX35_CS0_BASE_ADDR + SZ_64M - 1,
-	.flags	= IORESOURCE_MEM,
-};
-
-static struct platform_device mx35pdk_flash = {
-	.name	= "physmap-flash",
-	.id	= 0,
-	.dev	= {
-		.platform_data  = &mx35pdk_flash_data,
-	},
-	.resource = &mx35pdk_flash_resource,
-	.num_resources = 1,
-};
-
-static const struct mxc_nand_platform_data mx35pdk_nand_board_info __initconst = {
-	.width = 1,
-	.hw_ecc = 1,
-	.flash_bbt = 1,
-};
-
-static struct platform_device *devices[] __initdata = {
-	&mx35pdk_flash,
-};
-
-static iomux_v3_cfg_t 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,
-	/* USBH1 */
-	MX35_PAD_I2C2_CLK__USB_TOP_USBH2_PWR,
-	MX35_PAD_I2C2_DAT__USB_TOP_USBH2_OC,
-	/* SDCARD */
-	MX35_PAD_SD1_CMD__ESDHC1_CMD,
-	MX35_PAD_SD1_CLK__ESDHC1_CLK,
-	MX35_PAD_SD1_DATA0__ESDHC1_DAT0,
-	MX35_PAD_SD1_DATA1__ESDHC1_DAT1,
-	MX35_PAD_SD1_DATA2__ESDHC1_DAT2,
-	MX35_PAD_SD1_DATA3__ESDHC1_DAT3,
-	/* I2C1 */
-	MX35_PAD_I2C1_CLK__I2C1_SCL,
-	MX35_PAD_I2C1_DAT__I2C1_SDA,
-};
-
-static int mx35_3ds_otg_init(struct platform_device *pdev)
-{
-	return mx35_initialize_usb_hw(pdev->id, MXC_EHCI_INTERNAL_PHY);
-}
-
-/* OTG config */
-static const struct fsl_usb2_platform_data usb_otg_pdata __initconst = {
-	.operating_mode	= FSL_USB2_DR_DEVICE,
-	.phy_mode	= FSL_USB2_PHY_UTMI_WIDE,
-	.workaround	= FLS_USB2_WORKAROUND_ENGCM09152,
-/*
- * ENGCM09152 also requires a hardware change.
- * Please check the MX35 Chip Errata document for details.
- */
-};
-
-static struct mxc_usbh_platform_data otg_pdata __initdata = {
-	.init	= mx35_3ds_otg_init,
-	.portsc	= MXC_EHCI_MODE_UTMI,
-};
-
-static int mx35_3ds_usbh_init(struct platform_device *pdev)
-{
-	return mx35_initialize_usb_hw(pdev->id, MXC_EHCI_INTERFACE_SINGLE_UNI |
-			  MXC_EHCI_INTERNAL_PHY);
-}
-
-/* USB HOST config */
-static const struct mxc_usbh_platform_data usb_host_pdata __initconst = {
-	.init		= mx35_3ds_usbh_init,
-	.portsc		= MXC_EHCI_MODE_SERIAL,
-};
-
-static int otg_mode_host;
-
-static int __init mx35_3ds_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=", mx35_3ds_otg_mode);
-
-static const struct imxi2c_platform_data mx35_3ds_i2c0_data __initconst = {
-	.bitrate = 100000,
-};
-
-/*
- * Board specific initialization.
- */
-static void __init mx35_3ds_init(void)
-{
-	mxc_iomux_v3_setup_multiple_pads(mx35pdk_pads, ARRAY_SIZE(mx35pdk_pads));
-
-	imx35_add_fec(NULL);
-	imx35_add_imx2_wdt(NULL);
-	platform_add_devices(devices, ARRAY_SIZE(devices));
-
-	imx35_add_imx_uart0(&uart_pdata);
-
-	if (otg_mode_host)
-		imx35_add_mxc_ehci_otg(&otg_pdata);
-
-	imx35_add_mxc_ehci_hs(&usb_host_pdata);
-
-	if (!otg_mode_host)
-		imx35_add_fsl_usb2_udc(&usb_otg_pdata);
-
-	imx35_add_mxc_nand(&mx35pdk_nand_board_info);
-	imx35_add_sdhci_esdhc_imx(0, NULL);
-
-	if (mxc_expio_init(MX35_CS5_BASE_ADDR, EXPIO_PARENT_INT))
-		pr_warn("Init of the debugboard failed, all "
-				"devices on the debugboard are unusable.\n");
-	imx35_add_imx_i2c0(&mx35_3ds_i2c0_data);
-}
-
-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 */
-	.boot_params = MX3x_PHYS_OFFSET + 0x100,
-	.map_io = mx35_map_io,
-	.init_early = imx35_init_early,
-	.init_irq = mx35_init_irq,
-	.timer = &mx35pdk_timer,
-	.init_machine = mx35_3ds_init,
-MACHINE_END
diff -druN linux-2.6.39-libre/arch/arm/mach-mx3/mach-pcm037.c linux-3.0-rc7-libre/arch/arm/mach-mx3/mach-pcm037.c
--- linux-2.6.39-libre/arch/arm/mach-mx3/mach-pcm037.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-mx3/mach-pcm037.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,691 +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.
- */
-
-#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/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/common.h>
-#include <mach/hardware.h>
-#include <mach/iomux-mx3.h>
-#include <mach/ipu.h>
-#include <mach/mx3_camera.h>
-#include <mach/mx3fb.h>
-#include <mach/ulpi.h>
-
-#include "devices-imx31.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 const struct imxuart_platform_data uart_pdata __initconst = {
-	.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 const struct mxc_nand_platform_data
-pcm037_nand_board_info __initconst = {
-	.width = 1,
-	.hw_ecc = 1,
-};
-
-static const struct imxi2c_platform_data pcm037_i2c1_data __initconst = {
-	.bitrate = 100000,
-};
-
-static const struct imxi2c_platform_data pcm037_i2c2_data __initconst = {
-	.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,
-};
-
-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,
-};
-
-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 const struct imxmmc_platform_data sdhc_pdata __initconst = {
-#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 = {
-	.osc_freq	= 16000000,
-	.ocr		= OCR_TX1_PULLDOWN | OCR_TX0_PUSHPULL,
-	.cdr		= CDR_CBP,
-};
-
-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 int pcm037_otg_init(struct platform_device *pdev)
-{
-	return mx31_initialize_usb_hw(pdev->id, MXC_EHCI_INTERFACE_DIFF_UNI);
-}
-
-static struct mxc_usbh_platform_data otg_pdata __initdata = {
-	.init	= pcm037_otg_init,
-	.portsc	= MXC_EHCI_MODE_ULPI,
-};
-
-static int pcm037_usbh2_init(struct platform_device *pdev)
-{
-	return mx31_initialize_usb_hw(pdev->id, MXC_EHCI_INTERFACE_DIFF_UNI);
-}
-
-static struct mxc_usbh_platform_data usbh2_pdata __initdata = {
-	.init	= pcm037_usbh2_init,
-	.portsc	= MXC_EHCI_MODE_ULPI,
-};
-
-static const struct fsl_usb2_platform_data otg_device_pdata __initconst = {
-	.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 pcm037_init(void)
-{
-	int ret;
-
-	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));
-
-	imx31_add_imx2_wdt(NULL);
-	imx31_add_imx_uart0(&uart_pdata);
-	/* XXX: should't this have .flags = 0 (i.e. no RTSCTS) on PCM037_EET? */
-	imx31_add_imx_uart1(&uart_pdata);
-	imx31_add_imx_uart2(&uart_pdata);
-
-	imx31_add_mxc_w1(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));
-
-	imx31_add_imx_i2c1(&pcm037_i2c1_data);
-	imx31_add_imx_i2c2(&pcm037_i2c2_data);
-
-	imx31_add_mxc_nand(&pcm037_nand_board_info);
-	imx31_add_mxc_mmc(0, &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 (otg_mode_host) {
-		otg_pdata.otg = imx_otg_ulpi_create(ULPI_OTG_DRVVBUS |
-				ULPI_OTG_DRVVBUS_EXT);
-		if (otg_pdata.otg)
-			imx31_add_mxc_ehci_otg(&otg_pdata);
-	}
-
-	usbh2_pdata.otg = imx_otg_ulpi_create(ULPI_OTG_DRVVBUS |
-			ULPI_OTG_DRVVBUS_EXT);
-	if (usbh2_pdata.otg)
-		imx31_add_mxc_ehci_hs(2, &usbh2_pdata);
-
-	if (!otg_mode_host)
-		imx31_add_fsl_usb2_udc(&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 */
-	.boot_params = MX3x_PHYS_OFFSET + 0x100,
-	.map_io = mx31_map_io,
-	.init_early = imx31_init_early,
-	.init_irq = mx31_init_irq,
-	.timer = &pcm037_timer,
-	.init_machine = pcm037_init,
-MACHINE_END
diff -druN linux-2.6.39-libre/arch/arm/mach-mx3/mach-pcm037_eet.c linux-3.0-rc7-libre/arch/arm/mach-mx3/mach-pcm037_eet.c
--- linux-2.6.39-libre/arch/arm/mach-mx3/mach-pcm037_eet.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-mx3/mach-pcm037_eet.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,190 +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>
-#include <mach/iomux-mx3.h>
-#include <mach/spi.h>
-
-#include <asm/mach-types.h>
-
-#include "pcm037.h"
-#include "devices.h"
-#include "devices-imx31.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 */
-static int pcm037_spi1_cs[] = {MXC_SPI_CS(1), IOMUX_TO_GPIO(MX31_PIN_KEY_COL7)};
-
-static const struct spi_imx_master pcm037_spi1_pdata __initconst = {
-	.chipselect = pcm037_spi1_cs,
-	.num_chipselect = ARRAY_SIZE(pcm037_spi1_cs),
-};
-
-/* 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 __init 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));
-	imx31_add_spi_imx0(&pcm037_spi1_pdata);
-
-	platform_device_register(&pcm037_gpio_keys_device);
-
-	return 0;
-}
-
-late_initcall(eet_init_devices);
diff -druN linux-2.6.39-libre/arch/arm/mach-mx3/mach-pcm043.c linux-3.0-rc7-libre/arch/arm/mach-mx3/mach-pcm043.c
--- linux-2.6.39-libre/arch/arm/mach-mx3/mach-pcm043.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-mx3/mach-pcm043.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,428 +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.
- */
-
-#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 <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-mx35.h>
-#include <mach/ipu.h>
-#include <mach/mx3fb.h>
-#include <mach/ulpi.h>
-#include <mach/audmux.h>
-#include <mach/esdhc.h>
-
-#include "devices-imx35.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 const struct imxuart_platform_data uart_pdata __initconst = {
-	.flags = IMXUART_HAVE_RTSCTS,
-};
-
-static const struct imxi2c_platform_data pcm043_i2c0_data __initconst = {
-	.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),
-	}
-};
-
-static struct platform_device *devices[] __initdata = {
-	&pcm043_flash,
-};
-
-static iomux_v3_cfg_t 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,
-	/* CAN2 */
-	MX35_PAD_TX5_RX0__CAN2_TXCAN,
-	MX35_PAD_TX4_RX1__CAN2_RXCAN,
-	/* esdhc */
-	MX35_PAD_SD1_CMD__ESDHC1_CMD,
-	MX35_PAD_SD1_CLK__ESDHC1_CLK,
-	MX35_PAD_SD1_DATA0__ESDHC1_DAT0,
-	MX35_PAD_SD1_DATA1__ESDHC1_DAT1,
-	MX35_PAD_SD1_DATA2__ESDHC1_DAT2,
-	MX35_PAD_SD1_DATA3__ESDHC1_DAT3,
-	MX35_PAD_ATA_DATA10__GPIO2_23, /* WriteProtect */
-	MX35_PAD_ATA_DATA11__GPIO2_24, /* CardDetect */
-};
-
-#define AC97_GPIO_TXFS	IMX_GPIO_NR(2, 31)
-#define AC97_GPIO_TXD	IMX_GPIO_NR(2, 28)
-#define AC97_GPIO_RESET	IMX_GPIO_NR(2, 0)
-#define SD1_GPIO_WP	IMX_GPIO_NR(2, 23)
-#define SD1_GPIO_CD	IMX_GPIO_NR(2, 24)
-
-static void pcm043_ac97_warm_reset(struct snd_ac97 *ac97)
-{
-	iomux_v3_cfg_t txfs_gpio = MX35_PAD_STXFS4__GPIO2_31;
-	iomux_v3_cfg_t 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)
-{
-	iomux_v3_cfg_t txfs_gpio = MX35_PAD_STXFS4__GPIO2_31;
-	iomux_v3_cfg_t txfs = MX35_PAD_STXFS4__AUDMUX_AUD4_TXFS;
-	iomux_v3_cfg_t txd_gpio = MX35_PAD_STXD4__GPIO2_28;
-	iomux_v3_cfg_t txd = MX35_PAD_STXD4__AUDMUX_AUD4_TXD;
-	iomux_v3_cfg_t 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 const struct imx_ssi_platform_data pcm043_ssi_pdata __initconst = {
-	.ac97_reset = pcm043_ac97_cold_reset,
-	.ac97_warm_reset = pcm043_ac97_warm_reset,
-	.flags = IMX_SSI_USE_AC97,
-};
-
-static const struct mxc_nand_platform_data
-pcm037_nand_board_info __initconst = {
-	.width = 1,
-	.hw_ecc = 1,
-};
-
-static int pcm043_otg_init(struct platform_device *pdev)
-{
-	return mx35_initialize_usb_hw(pdev->id, MXC_EHCI_INTERFACE_DIFF_UNI);
-}
-
-static struct mxc_usbh_platform_data otg_pdata __initdata = {
-	.init	= pcm043_otg_init,
-	.portsc	= MXC_EHCI_MODE_UTMI,
-};
-
-static int pcm043_usbh1_init(struct platform_device *pdev)
-{
-	return mx35_initialize_usb_hw(pdev->id, MXC_EHCI_INTERFACE_SINGLE_UNI |
-			MXC_EHCI_INTERNAL_PHY | MXC_EHCI_IPPUE_DOWN);
-}
-
-static const struct mxc_usbh_platform_data usbh1_pdata __initconst = {
-	.init	= pcm043_usbh1_init,
-	.portsc	= MXC_EHCI_MODE_SERIAL,
-};
-
-static const struct fsl_usb2_platform_data otg_device_pdata __initconst = {
-	.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);
-
-static struct esdhc_platform_data sd1_pdata = {
-	.wp_gpio = SD1_GPIO_WP,
-	.cd_gpio = SD1_GPIO_CD,
-};
-
-/*
- * Board specific initialization.
- */
-static void __init pcm043_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));
-
-	imx35_add_fec(NULL);
-	platform_add_devices(devices, ARRAY_SIZE(devices));
-	imx35_add_imx2_wdt(NULL);
-
-	imx35_add_imx_uart0(&uart_pdata);
-	imx35_add_mxc_nand(&pcm037_nand_board_info);
-	imx35_add_imx_ssi(0, &pcm043_ssi_pdata);
-
-	imx35_add_imx_uart1(&uart_pdata);
-
-	i2c_register_board_info(0, pcm043_i2c_devices,
-			ARRAY_SIZE(pcm043_i2c_devices));
-
-	imx35_add_imx_i2c0(&pcm043_i2c0_data);
-
-	mxc_register_device(&mx3_ipu, &mx3_ipu_data);
-	mxc_register_device(&mx3_fb, &mx3fb_pdata);
-
-	if (otg_mode_host) {
-		otg_pdata.otg = imx_otg_ulpi_create(ULPI_OTG_DRVVBUS |
-				ULPI_OTG_DRVVBUS_EXT);
-		if (otg_pdata.otg)
-			imx35_add_mxc_ehci_otg(&otg_pdata);
-	}
-	imx35_add_mxc_ehci_hs(&usbh1_pdata);
-
-	if (!otg_mode_host)
-		imx35_add_fsl_usb2_udc(&otg_device_pdata);
-
-	imx35_add_flexcan1(NULL);
-	imx35_add_sdhci_esdhc_imx(0, &sd1_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 */
-	.boot_params = MX3x_PHYS_OFFSET + 0x100,
-	.map_io = mx35_map_io,
-	.init_early = imx35_init_early,
-	.init_irq = mx35_init_irq,
-	.timer = &pcm043_timer,
-	.init_machine = pcm043_init,
-MACHINE_END
diff -druN linux-2.6.39-libre/arch/arm/mach-mx3/mach-qong.c linux-3.0-rc7-libre/arch/arm/mach-mx3/mach-qong.c
--- linux-2.6.39-libre/arch/arm/mach-mx3/mach-qong.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-mx3/mach-qong.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,270 +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.
- */
-
-#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/iomux-mx3.h>
-
-#include "devices-imx31.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)
-
-static const struct imxuart_platform_data uart_pdata __initconst = {
-	.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 __init mxc_init_imx_uart(void)
-{
-	mxc_iomux_setup_multiple_pins(uart_pins, ARRAY_SIZE(uart_pins),
-			"uart-0");
-	imx31_add_imx_uart0(&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 + SZ_128M - 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 = {
-		.nr_chips		= 1,
-		.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 qong_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,
-};
-
-MACHINE_START(QONG, "Dave/DENX QongEVB-LITE")
-	/* Maintainer: DENX Software Engineering GmbH */
-	.boot_params = MX3x_PHYS_OFFSET + 0x100,
-	.map_io = mx31_map_io,
-	.init_early = imx31_init_early,
-	.init_irq = mx31_init_irq,
-	.timer = &qong_timer,
-	.init_machine = qong_init,
-MACHINE_END
diff -druN linux-2.6.39-libre/arch/arm/mach-mx3/mach-vpr200.c linux-3.0-rc7-libre/arch/arm/mach-mx3/mach-vpr200.c
--- linux-2.6.39-libre/arch/arm/mach-mx3/mach-vpr200.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-mx3/mach-vpr200.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,333 +0,0 @@
-/*
- * Copyright 2009 Freescale Semiconductor, Inc. All Rights Reserved.
- * Copyright (C) 2009 Marc Kleine-Budde, Pengutronix
- * Copyright 2010 Creative Product Design
- *
- * Derived from mx35 3stack.
- * Original 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.
- */
-
-#include <linux/types.h>
-#include <linux/init.h>
-#include <linux/platform_device.h>
-#include <linux/mtd/physmap.h>
-#include <linux/memory.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/iomux-mx35.h>
-#include <mach/irqs.h>
-#include <mach/ipu.h>
-#include <mach/mx3fb.h>
-
-#include <linux/i2c.h>
-#include <linux/i2c/at24.h>
-#include <linux/mfd/mc13xxx.h>
-#include <linux/gpio_keys.h>
-
-#include "devices-imx35.h"
-#include "devices.h"
-
-#define GPIO_LCDPWR	IMX_GPIO_NR(1, 2)
-#define GPIO_PMIC_INT	IMX_GPIO_NR(2, 0)
-
-#define GPIO_BUTTON1	IMX_GPIO_NR(1, 4)
-#define GPIO_BUTTON2	IMX_GPIO_NR(1, 5)
-#define GPIO_BUTTON3	IMX_GPIO_NR(1, 7)
-#define GPIO_BUTTON4	IMX_GPIO_NR(1, 8)
-#define GPIO_BUTTON5	IMX_GPIO_NR(1, 9)
-#define GPIO_BUTTON6	IMX_GPIO_NR(1, 10)
-#define GPIO_BUTTON7	IMX_GPIO_NR(1, 11)
-#define GPIO_BUTTON8	IMX_GPIO_NR(1, 12)
-
-static const struct fb_videomode fb_modedb[] = {
-	{
-		/* 800x480 @ 60 Hz */
-		.name		= "PT0708048",
-		.refresh	= 60,
-		.xres		= 800,
-		.yres		= 480,
-		.pixclock	= KHZ2PICOS(33260),
-		.left_margin	= 50,
-		.right_margin	= 156,
-		.upper_margin	= 10,
-		.lower_margin	= 10,
-		.hsync_len	= 1,	/* note: DE only display */
-		.vsync_len	= 1,	/* note: DE only display */
-		.sync		= FB_SYNC_CLK_IDLE_EN | FB_SYNC_OE_ACT_HIGH,
-		.vmode		= FB_VMODE_NONINTERLACED,
-		.flag		= 0,
-	}, {
-		/* 800x480 @ 60 Hz */
-		.name		= "CTP-CLAA070LC0ACW",
-		.refresh	= 60,
-		.xres		= 800,
-		.yres		= 480,
-		.pixclock	= KHZ2PICOS(27000),
-		.left_margin	= 50,
-		.right_margin	= 50,	/* whole line should have 900 clocks */
-		.upper_margin	= 10,
-		.lower_margin	= 10,	/* whole frame should have 500 lines */
-		.hsync_len	= 1,	/* note: DE only display */
-		.vsync_len	= 1,	/* note: DE only display */
-		.sync		= FB_SYNC_CLK_IDLE_EN | 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		= "PT0708048",
-	.mode		= fb_modedb,
-	.num_modes	= ARRAY_SIZE(fb_modedb),
-};
-
-static struct physmap_flash_data vpr200_flash_data = {
-	.width  = 2,
-};
-
-static struct resource vpr200_flash_resource = {
-	.start	= MX35_CS0_BASE_ADDR,
-	.end	= MX35_CS0_BASE_ADDR + SZ_64M - 1,
-	.flags	= IORESOURCE_MEM,
-};
-
-static struct platform_device vpr200_flash = {
-	.name	= "physmap-flash",
-	.id	= 0,
-	.dev	= {
-		.platform_data  = &vpr200_flash_data,
-	},
-	.resource = &vpr200_flash_resource,
-	.num_resources = 1,
-};
-
-static const struct mxc_nand_platform_data
-		vpr200_nand_board_info __initconst = {
-	.width = 1,
-	.hw_ecc = 1,
-	.flash_bbt = 1,
-};
-
-#define VPR_KEY_DEBOUNCE	500
-static struct gpio_keys_button vpr200_gpio_keys_table[] = {
-	{KEY_F2, GPIO_BUTTON1, 1, "vpr-keys: F2", 0, VPR_KEY_DEBOUNCE},
-	{KEY_F3, GPIO_BUTTON2, 1, "vpr-keys: F3", 0, VPR_KEY_DEBOUNCE},
-	{KEY_F4, GPIO_BUTTON3, 1, "vpr-keys: F4", 0, VPR_KEY_DEBOUNCE},
-	{KEY_F5, GPIO_BUTTON4, 1, "vpr-keys: F5", 0, VPR_KEY_DEBOUNCE},
-	{KEY_F6, GPIO_BUTTON5, 1, "vpr-keys: F6", 0, VPR_KEY_DEBOUNCE},
-	{KEY_F7, GPIO_BUTTON6, 1, "vpr-keys: F7", 0, VPR_KEY_DEBOUNCE},
-	{KEY_F8, GPIO_BUTTON7, 1, "vpr-keys: F8", 1, VPR_KEY_DEBOUNCE},
-	{KEY_F9, GPIO_BUTTON8, 1, "vpr-keys: F9", 1, VPR_KEY_DEBOUNCE},
-};
-
-static struct gpio_keys_platform_data vpr200_gpio_keys_data = {
-	.buttons = vpr200_gpio_keys_table,
-	.nbuttons = ARRAY_SIZE(vpr200_gpio_keys_table),
-};
-
-static struct platform_device vpr200_device_gpiokeys = {
-	.name = "gpio-keys",
-	.dev = {
-		.platform_data = &vpr200_gpio_keys_data,
-	}
-};
-
-static struct mc13xxx_platform_data vpr200_pmic = {
-	.flags = MC13XXX_USE_ADC | MC13XXX_USE_TOUCHSCREEN,
-};
-
-static const struct imxi2c_platform_data vpr200_i2c0_data __initconst = {
-	.bitrate = 50000,
-};
-
-static struct at24_platform_data vpr200_eeprom = {
-	.byte_len = 2048 / 8,
-	.page_size = 1,
-};
-
-static struct i2c_board_info vpr200_i2c_devices[] = {
-	{
-		I2C_BOARD_INFO("at24", 0x50), /* E0=0, E1=0, E2=0 */
-		.platform_data = &vpr200_eeprom,
-	}, {
-		I2C_BOARD_INFO("mc13892", 0x08),
-		.platform_data = &vpr200_pmic,
-		.irq = gpio_to_irq(GPIO_PMIC_INT),
-	}
-};
-
-static iomux_v3_cfg_t vpr200_pads[] = {
-	/* UART1 */
-	MX35_PAD_TXD1__UART1_TXD_MUX,
-	MX35_PAD_RXD1__UART1_RXD_MUX,
-	/* UART3 */
-	MX35_PAD_ATA_DATA10__UART3_RXD_MUX,
-	MX35_PAD_ATA_DATA11__UART3_TXD_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,
-	/* 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_FPSHIFT__IPU_DISPB_D3_CLK,
-	MX35_PAD_D3_DRDY__IPU_DISPB_D3_DRDY,
-	MX35_PAD_CONTRAST__IPU_DISPB_CONTR,
-	/* LCD Enable */
-	MX35_PAD_D3_VSYNC__GPIO1_2,
-	/* USBOTG */
-	MX35_PAD_USBOTG_PWR__USB_TOP_USBOTG_PWR,
-	MX35_PAD_USBOTG_OC__USB_TOP_USBOTG_OC,
-	/* SDCARD */
-	MX35_PAD_SD1_CMD__ESDHC1_CMD,
-	MX35_PAD_SD1_CLK__ESDHC1_CLK,
-	MX35_PAD_SD1_DATA0__ESDHC1_DAT0,
-	MX35_PAD_SD1_DATA1__ESDHC1_DAT1,
-	MX35_PAD_SD1_DATA2__ESDHC1_DAT2,
-	MX35_PAD_SD1_DATA3__ESDHC1_DAT3,
-	/* PMIC */
-	MX35_PAD_GPIO2_0__GPIO2_0,
-	/* GPIO keys */
-	MX35_PAD_SCKR__GPIO1_4,
-	MX35_PAD_COMPARE__GPIO1_5,
-	MX35_PAD_SCKT__GPIO1_7,
-	MX35_PAD_FST__GPIO1_8,
-	MX35_PAD_HCKT__GPIO1_9,
-	MX35_PAD_TX5_RX0__GPIO1_10,
-	MX35_PAD_TX4_RX1__GPIO1_11,
-	MX35_PAD_TX3_RX2__GPIO1_12,
-};
-
-/* USB Device config */
-static const struct fsl_usb2_platform_data otg_device_pdata __initconst = {
-	.operating_mode	= FSL_USB2_DR_DEVICE,
-	.phy_mode	= FSL_USB2_PHY_UTMI,
-	.workaround	= FLS_USB2_WORKAROUND_ENGCM09152,
-};
-
-static int vpr200_usbh_init(struct platform_device *pdev)
-{
-	return mx35_initialize_usb_hw(pdev->id,
-			MXC_EHCI_INTERFACE_SINGLE_UNI | MXC_EHCI_INTERNAL_PHY);
-}
-
-/* USB HOST config */
-static const struct mxc_usbh_platform_data usb_host_pdata __initconst = {
-	.init = vpr200_usbh_init,
-	.portsc = MXC_EHCI_MODE_SERIAL,
-};
-
-static struct platform_device *devices[] __initdata = {
-	&vpr200_flash,
-	&vpr200_device_gpiokeys,
-};
-
-/*
- * Board specific initialization.
- */
-static void __init vpr200_board_init(void)
-{
-	mxc_iomux_v3_setup_multiple_pads(vpr200_pads, ARRAY_SIZE(vpr200_pads));
-
-	imx35_add_fec(NULL);
-	imx35_add_imx2_wdt(NULL);
-
-	platform_add_devices(devices, ARRAY_SIZE(devices));
-
-	if (0 != gpio_request(GPIO_LCDPWR, "LCDPWR"))
-		printk(KERN_WARNING "vpr200: Couldn't get LCDPWR gpio\n");
-	else
-		gpio_direction_output(GPIO_LCDPWR, 0);
-
-	if (0 != gpio_request(GPIO_PMIC_INT, "PMIC_INT"))
-		printk(KERN_WARNING "vpr200: Couldn't get PMIC_INT gpio\n");
-	else
-		gpio_direction_input(GPIO_PMIC_INT);
-
-	imx35_add_imx_uart0(NULL);
-	imx35_add_imx_uart2(NULL);
-
-	mxc_register_device(&mx3_ipu, &mx3_ipu_data);
-	mxc_register_device(&mx3_fb, &mx3fb_pdata);
-
-	imx35_add_fsl_usb2_udc(&otg_device_pdata);
-	imx35_add_mxc_ehci_hs(&usb_host_pdata);
-
-	imx35_add_mxc_nand(&vpr200_nand_board_info);
-	imx35_add_sdhci_esdhc_imx(0, NULL);
-
-	i2c_register_board_info(0, vpr200_i2c_devices,
-			ARRAY_SIZE(vpr200_i2c_devices));
-
-	imx35_add_imx_i2c0(&vpr200_i2c0_data);
-}
-
-static void __init vpr200_timer_init(void)
-{
-	mx35_clocks_init();
-}
-
-struct sys_timer vpr200_timer = {
-	.init	= vpr200_timer_init,
-};
-
-MACHINE_START(VPR200, "VPR200")
-	/* Maintainer: Creative Product Design */
-	.map_io = mx35_map_io,
-	.init_early = imx35_init_early,
-	.init_irq = mx35_init_irq,
-	.timer = &vpr200_timer,
-	.init_machine = vpr200_board_init,
-MACHINE_END
diff -druN linux-2.6.39-libre/arch/arm/mach-mx3/Makefile linux-3.0-rc7-libre/arch/arm/mach-mx3/Makefile
--- linux-2.6.39-libre/arch/arm/mach-mx3/Makefile	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-mx3/Makefile	1969-12-31 19:00:00.000000000 -0500
@@ -1,26 +0,0 @@
-#
-# Makefile for the linux kernel.
-#
-
-# Object file lists.
-
-obj-y				:= mm.o devices.o cpu.o
-obj-$(CONFIG_SOC_IMX31)		+= clock-imx31.o iomux-imx31.o ehci-imx31.o
-obj-$(CONFIG_SOC_IMX35)		+= clock-imx35.o ehci-imx35.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
-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-mx35_3ds.o
-obj-$(CONFIG_MACH_KZM_ARM11_01)	+= mach-kzm_arm11_01.o
-obj-$(CONFIG_MACH_BUG)		+= mach-bug.o
-obj-$(CONFIG_MACH_EUKREA_CPUIMX35)	+= mach-cpuimx35.o
-obj-$(CONFIG_MACH_EUKREA_MBIMXSD35_BASEBOARD)	+= eukrea_mbimxsd-baseboard.o
-obj-$(CONFIG_MACH_VPR200)	+= mach-vpr200.o
diff -druN linux-2.6.39-libre/arch/arm/mach-mx3/Makefile.boot linux-3.0-rc7-libre/arch/arm/mach-mx3/Makefile.boot
--- linux-2.6.39-libre/arch/arm/mach-mx3/Makefile.boot	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-mx3/Makefile.boot	1969-12-31 19:00:00.000000000 -0500
@@ -1,3 +0,0 @@
-   zreladdr-y	:= 0x80008000
-params_phys-y	:= 0x80000100
-initrd_phys-y	:= 0x80800000
diff -druN linux-2.6.39-libre/arch/arm/mach-mx3/mm.c linux-3.0-rc7-libre/arch/arm/mach-mx3/mm.c
--- linux-2.6.39-libre/arch/arm/mach-mx3/mm.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-mx3/mm.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,141 +0,0 @@
-/*
- *  Copyright (C) 1999,2000 Arm Limited
- *  Copyright (C) 2000 Deep Blue Solutions Ltd
- *  Copyright (C) 2002 Shane Nay (shane@minirl.com)
- *  Copyright 2005-2007 Freescale Semiconductor, Inc. All Rights Reserved.
- *    - add MX31 specific definitions
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- */
-
-#include <linux/mm.h>
-#include <linux/init.h>
-#include <linux/err.h>
-
-#include <asm/pgtable.h>
-#include <asm/mach/map.h>
-#include <asm/hardware/cache-l2x0.h>
-
-#include <mach/common.h>
-#include <mach/hardware.h>
-#include <mach/iomux-v3.h>
-#include <mach/gpio.h>
-#include <mach/irqs.h>
-
-#ifdef CONFIG_SOC_IMX31
-static struct map_desc mx31_io_desc[] __initdata = {
-	imx_map_entry(MX31, X_MEMC, MT_DEVICE),
-	imx_map_entry(MX31, AVIC, MT_DEVICE_NONSHARED),
-	imx_map_entry(MX31, AIPS1, MT_DEVICE_NONSHARED),
-	imx_map_entry(MX31, AIPS2, MT_DEVICE_NONSHARED),
-	imx_map_entry(MX31, SPBA0, MT_DEVICE_NONSHARED),
-};
-
-/*
- * 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 mx31_map_io(void)
-{
-	iotable_init(mx31_io_desc, ARRAY_SIZE(mx31_io_desc));
-}
-
-void __init imx31_init_early(void)
-{
-	mxc_set_cpu_type(MXC_CPU_MX31);
-	mxc_arch_reset_init(MX31_IO_ADDRESS(MX31_WDOG_BASE_ADDR));
-}
-
-static struct mxc_gpio_port imx31_gpio_ports[] = {
-	DEFINE_IMX_GPIO_PORT_IRQ(MX31, 0, 1, MX31_INT_GPIO1),
-	DEFINE_IMX_GPIO_PORT_IRQ(MX31, 1, 2, MX31_INT_GPIO2),
-	DEFINE_IMX_GPIO_PORT_IRQ(MX31, 2, 3, MX31_INT_GPIO3),
-};
-
-void __init mx31_init_irq(void)
-{
-	mxc_init_irq(MX31_IO_ADDRESS(MX31_AVIC_BASE_ADDR));
-	mxc_gpio_init(imx31_gpio_ports,	ARRAY_SIZE(imx31_gpio_ports));
-}
-#endif /* ifdef CONFIG_SOC_IMX31 */
-
-#ifdef CONFIG_SOC_IMX35
-static struct map_desc mx35_io_desc[] __initdata = {
-	imx_map_entry(MX35, X_MEMC, MT_DEVICE),
-	imx_map_entry(MX35, AVIC, MT_DEVICE_NONSHARED),
-	imx_map_entry(MX35, AIPS1, MT_DEVICE_NONSHARED),
-	imx_map_entry(MX35, AIPS2, MT_DEVICE_NONSHARED),
-	imx_map_entry(MX35, SPBA0, MT_DEVICE_NONSHARED),
-};
-
-void __init mx35_map_io(void)
-{
-	iotable_init(mx35_io_desc, ARRAY_SIZE(mx35_io_desc));
-}
-
-void __init imx35_init_early(void)
-{
-	mxc_set_cpu_type(MXC_CPU_MX35);
-	mxc_iomux_v3_init(MX35_IO_ADDRESS(MX35_IOMUXC_BASE_ADDR));
-	mxc_arch_reset_init(MX35_IO_ADDRESS(MX35_WDOG_BASE_ADDR));
-}
-
-static struct mxc_gpio_port imx35_gpio_ports[] = {
-	DEFINE_IMX_GPIO_PORT_IRQ(MX35, 0, 1, MX35_INT_GPIO1),
-	DEFINE_IMX_GPIO_PORT_IRQ(MX35, 1, 2, MX35_INT_GPIO2),
-	DEFINE_IMX_GPIO_PORT_IRQ(MX35, 2, 3, MX35_INT_GPIO3),
-};
-
-void __init mx35_init_irq(void)
-{
-	mxc_init_irq(MX35_IO_ADDRESS(MX35_AVIC_BASE_ADDR));
-	mxc_gpio_init(imx35_gpio_ports,	ARRAY_SIZE(imx35_gpio_ports));
-}
-#endif /* ifdef CONFIG_SOC_IMX35 */
-
-#ifdef CONFIG_CACHE_L2X0
-static int mxc_init_l2x0(void)
-{
-	void __iomem *l2x0_base;
-	void __iomem *clkctl_base;
-/*
- * First of all, we must repair broken chip settings. There are some
- * i.MX35 CPUs in the wild, comming with bogus L2 cache settings. These
- * misconfigured CPUs will run amok immediately when the L2 cache gets enabled.
- * Workaraound is to setup the correct register setting prior enabling the
- * L2 cache. This should not hurt already working CPUs, as they are using the
- * same value
- */
-#define L2_MEM_VAL 0x10
-
-	clkctl_base = ioremap(MX35_CLKCTL_BASE_ADDR, 4096);
-	if (clkctl_base != NULL) {
-		writel(0x00000515, clkctl_base + L2_MEM_VAL);
-		iounmap(clkctl_base);
-	} else {
-		pr_err("L2 cache: Cannot fix timing. Trying to continue without\n");
-	}
-
-	l2x0_base = ioremap(MX3x_L2CC_BASE_ADDR, 4096);
-	if (IS_ERR(l2x0_base)) {
-		printk(KERN_ERR "remapping L2 cache area failed with %ld\n",
-				PTR_ERR(l2x0_base));
-		return 0;
-	}
-
-	l2x0_init(l2x0_base, 0x00030024, 0x00000000);
-
-	return 0;
-}
-
-arch_initcall(mxc_init_l2x0);
-#endif
diff -druN linux-2.6.39-libre/arch/arm/mach-mx3/mx31lilly-db.c linux-3.0-rc7-libre/arch/arm/mach-mx3/mx31lilly-db.c
--- linux-2.6.39-libre/arch/arm/mach-mx3/mx31lilly-db.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-mx3/mx31lilly-db.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,221 +0,0 @@
-/*
- *  LILLY-1131 development board support
- *
- *    Copyright (c) 2009 Daniel Mack <daniel@caiaq.de>
- *
- *  based on code for other MX31 boards,
- *
- *    Copyright 2005-2007 Freescale Semiconductor
- *    Copyright (c) 2009 Alberto Panizzo <maramaopercheseimorto@gmail.com>
- *    Copyright (C) 2009 Valentin Longchamp, EPFL Mobots group
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- */
-
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/init.h>
-#include <linux/gpio.h>
-#include <linux/platform_device.h>
-
-#include <asm/mach-types.h>
-#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-
-#include <mach/hardware.h>
-#include <mach/common.h>
-#include <mach/iomux-mx3.h>
-#include <mach/board-mx31lilly.h>
-#include <mach/mx3fb.h>
-#include <mach/ipu.h>
-
-#include "devices-imx31.h"
-#include "devices.h"
-
-/*
- * This file contains board-specific initialization routines for the
- * LILLY-1131 development board. If you design an own baseboard for the
- * module, use this file as base for support code.
- */
-
-static unsigned int lilly_db_board_pins[] __initdata = {
-	MX31_PIN_CTS1__CTS1,
-	MX31_PIN_RTS1__RTS1,
-	MX31_PIN_TXD1__TXD1,
-	MX31_PIN_RXD1__RXD1,
-	MX31_PIN_CTS2__CTS2,
-	MX31_PIN_RTS2__RTS2,
-	MX31_PIN_TXD2__TXD2,
-	MX31_PIN_RXD2__RXD2,
-	MX31_PIN_CSPI3_MOSI__RXD3,
-	MX31_PIN_CSPI3_MISO__TXD3,
-	MX31_PIN_CSPI3_SCLK__RTS3,
-	MX31_PIN_CSPI3_SPI_RDY__CTS3,
-	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_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_CONTRAST__CONTRAST,
-};
-
-/* UART */
-static const struct imxuart_platform_data uart_pdata __initconst = {
-	.flags = IMXUART_HAVE_RTSCTS,
-};
-
-/* MMC support */
-
-static int mxc_mmc1_get_ro(struct device *dev)
-{
-	return gpio_get_value(IOMUX_TO_GPIO(MX31_PIN_LCS0));
-}
-
-static int gpio_det, gpio_wp;
-
-#define MMC_PAD_CFG (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST | PAD_CTL_HYS_CMOS | \
-			PAD_CTL_ODE_CMOS | PAD_CTL_100K_PU)
-
-static int mxc_mmc1_init(struct device *dev,
-			 irq_handler_t detect_irq, void *data)
-{
-	int ret;
-
-	gpio_det = IOMUX_TO_GPIO(MX31_PIN_GPIO1_1);
-	gpio_wp = IOMUX_TO_GPIO(MX31_PIN_LCS0);
-
-	mxc_iomux_set_pad(MX31_PIN_SD1_DATA0, MMC_PAD_CFG);
-	mxc_iomux_set_pad(MX31_PIN_SD1_DATA1, MMC_PAD_CFG);
-	mxc_iomux_set_pad(MX31_PIN_SD1_DATA2, MMC_PAD_CFG);
-	mxc_iomux_set_pad(MX31_PIN_SD1_DATA3, MMC_PAD_CFG);
-	mxc_iomux_set_pad(MX31_PIN_SD1_CLK, MMC_PAD_CFG);
-	mxc_iomux_set_pad(MX31_PIN_SD1_CMD, MMC_PAD_CFG);
-
-	ret = gpio_request(gpio_det, "MMC detect");
-	if (ret)
-		return ret;
-
-	ret = gpio_request(gpio_wp, "MMC w/p");
-	if (ret)
-		goto exit_free_det;
-
-	gpio_direction_input(gpio_det);
-	gpio_direction_input(gpio_wp);
-
-	ret = request_irq(IOMUX_TO_IRQ(MX31_PIN_GPIO1_1), detect_irq,
-			  IRQF_DISABLED | IRQF_TRIGGER_FALLING,
-			  "MMC detect", data);
-	if (ret)
-		goto exit_free_wp;
-
-	return 0;
-
-exit_free_wp:
-	gpio_free(gpio_wp);
-
-exit_free_det:
-	gpio_free(gpio_det);
-
-	return ret;
-}
-
-static void mxc_mmc1_exit(struct device *dev, void *data)
-{
-	gpio_free(gpio_det);
-	gpio_free(gpio_wp);
-	free_irq(IOMUX_TO_IRQ(MX31_PIN_GPIO1_1), data);
-}
-
-static const struct imxmmc_platform_data mmc_pdata __initconst = {
-	.get_ro	= mxc_mmc1_get_ro,
-	.init	= mxc_mmc1_init,
-	.exit	= mxc_mmc1_exit,
-};
-
-/* Framebuffer support */
-static struct ipu_platform_data ipu_data __initdata = {
-	.irq_base = MXC_IPU_IRQ_START,
-};
-
-static const struct fb_videomode fb_modedb = {
-	/* 640x480 TFT panel (IPS-056T) */
-	.name	   	= "CRT-VGA",
-	.refresh	= 64,
-	.xres		= 640,
-	.yres		= 480,
-	.pixclock	= 30000,
-	.left_margin	= 200,
-	.right_margin	= 2,
-	.upper_margin	= 2,
-	.lower_margin	= 2,
-	.hsync_len	= 3,
-	.vsync_len	= 1,
-	.sync		= FB_SYNC_VERT_HIGH_ACT | FB_SYNC_OE_ACT_HIGH,
-	.vmode		= FB_VMODE_NONINTERLACED,
-	.flag		= 0,
-};
-
-static struct mx3fb_platform_data fb_pdata __initdata = {
-	.dma_dev	= &mx3_ipu.dev,
-	.name		= "CRT-VGA",
-	.mode		= &fb_modedb,
-	.num_modes	= 1,
-};
-
-#define LCD_VCC_EN_GPIO	 (7)
-
-static void __init mx31lilly_init_fb(void)
-{
-	if (gpio_request(LCD_VCC_EN_GPIO, "LCD enable") != 0) {
-		printk(KERN_WARNING "unable to request LCD_VCC_EN pin.\n");
-		return;
-	}
-
-	mxc_register_device(&mx3_ipu, &ipu_data);
-	mxc_register_device(&mx3_fb, &fb_pdata);
-	gpio_direction_output(LCD_VCC_EN_GPIO, 1);
-}
-
-void __init mx31lilly_db_init(void)
-{
-	mxc_iomux_setup_multiple_pins(lilly_db_board_pins,
-					ARRAY_SIZE(lilly_db_board_pins),
-					"development board pins");
-	imx31_add_imx_uart0(&uart_pdata);
-	imx31_add_imx_uart1(&uart_pdata);
-	imx31_add_imx_uart2(&uart_pdata);
-	imx31_add_mxc_mmc(0, &mmc_pdata);
-	mx31lilly_init_fb();
-}
-
diff -druN linux-2.6.39-libre/arch/arm/mach-mx3/mx31lite-db.c linux-3.0-rc7-libre/arch/arm/mach-mx3/mx31lite-db.c
--- linux-2.6.39-libre/arch/arm/mach-mx3/mx31lite-db.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-mx3/mx31lite-db.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,204 +0,0 @@
-/*
- *  LogicPD i.MX31 SOM-LV development board support
- *
- *    Copyright (c) 2009 Daniel Mack <daniel@caiaq.de>
- *
- *  based on code for other MX31 boards,
- *
- *    Copyright 2005-2007 Freescale Semiconductor
- *    Copyright (c) 2009 Alberto Panizzo <maramaopercheseimorto@gmail.com>
- *    Copyright (C) 2009 Valentin Longchamp, EPFL Mobots group
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- */
-
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/init.h>
-#include <linux/gpio.h>
-#include <linux/leds.h>
-#include <linux/platform_device.h>
-
-#include <asm/mach-types.h>
-#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-
-#include <mach/hardware.h>
-#include <mach/common.h>
-#include <mach/iomux-mx3.h>
-#include <mach/board-mx31lite.h>
-
-#include "devices-imx31.h"
-#include "devices.h"
-
-/*
- * This file contains board-specific initialization routines for the
- * LogicPD i.MX31 SOM-LV development board, aka 'LiteKit'.
- * If you design an own baseboard for the module, use this file as base
- * for support code.
- */
-
-static unsigned int litekit_db_board_pins[] __initdata = {
-	/* UART1 */
-	MX31_PIN_CTS1__CTS1,
-	MX31_PIN_RTS1__RTS1,
-	MX31_PIN_TXD1__TXD1,
-	MX31_PIN_RXD1__RXD1,
-	/* SPI 0 */
-	MX31_PIN_CSPI1_SCLK__SCLK,
-	MX31_PIN_CSPI1_MOSI__MOSI,
-	MX31_PIN_CSPI1_MISO__MISO,
-	MX31_PIN_CSPI1_SPI_RDY__SPI_RDY,
-	MX31_PIN_CSPI1_SS0__SS0,
-	MX31_PIN_CSPI1_SS1__SS1,
-	MX31_PIN_CSPI1_SS2__SS2,
-	/* 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 */
-static const struct imxuart_platform_data uart_pdata __initconst = {
-	.flags = IMXUART_HAVE_RTSCTS,
-};
-
-/* MMC */
-
-static int gpio_det, gpio_wp;
-
-#define MMC_PAD_CFG (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST | PAD_CTL_HYS_CMOS | \
-		     PAD_CTL_ODE_CMOS)
-
-static int mxc_mmc1_get_ro(struct device *dev)
-{
-	return gpio_get_value(IOMUX_TO_GPIO(MX31_PIN_GPIO1_6));
-}
-
-static int mxc_mmc1_init(struct device *dev,
-			 irq_handler_t detect_irq, void *data)
-{
-	int ret;
-
-	gpio_det = IOMUX_TO_GPIO(MX31_PIN_DCD_DCE1);
-	gpio_wp = IOMUX_TO_GPIO(MX31_PIN_GPIO1_6);
-
-	mxc_iomux_set_pad(MX31_PIN_SD1_DATA0,
-			  MMC_PAD_CFG | 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);
-
-	ret = gpio_request(gpio_det, "MMC detect");
-	if (ret)
-		return ret;
-
-	ret = gpio_request(gpio_wp, "MMC w/p");
-	if (ret)
-		goto exit_free_det;
-
-	gpio_direction_input(gpio_det);
-	gpio_direction_input(gpio_wp);
-
-	ret = request_irq(IOMUX_TO_IRQ(MX31_PIN_DCD_DCE1), detect_irq,
-			  IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
-			  "MMC detect", data);
-	if (ret)
-		goto exit_free_wp;
-
-	return 0;
-
-exit_free_wp:
-	gpio_free(gpio_wp);
-
-exit_free_det:
-	gpio_free(gpio_det);
-
-	return ret;
-}
-
-static void mxc_mmc1_exit(struct device *dev, void *data)
-{
-	gpio_free(gpio_det);
-	gpio_free(gpio_wp);
-	free_irq(IOMUX_TO_IRQ(MX31_PIN_DCD_DCE1), data);
-}
-
-static const struct imxmmc_platform_data mmc_pdata __initconst = {
-	.get_ro	 = mxc_mmc1_get_ro,
-	.init	   = mxc_mmc1_init,
-	.exit	   = mxc_mmc1_exit,
-};
-
-/* SPI */
-
-static int spi_internal_chipselect[] = {
-	MXC_SPI_CS(0),
-	MXC_SPI_CS(1),
-	MXC_SPI_CS(2),
-};
-
-static const struct spi_imx_master spi0_pdata __initconst = {
-	.chipselect	= spi_internal_chipselect,
-	.num_chipselect	= ARRAY_SIZE(spi_internal_chipselect),
-};
-
-/* GPIO LEDs */
-
-static struct gpio_led litekit_leds[] = {
-	{
-		.name           = "GPIO0",
-		.gpio           = IOMUX_TO_GPIO(MX31_PIN_COMPARE),
-		.active_low     = 1,
-		.default_state  = LEDS_GPIO_DEFSTATE_OFF,
-	},
-	{
-		.name           = "GPIO1",
-		.gpio           = IOMUX_TO_GPIO(MX31_PIN_CAPTURE),
-		.active_low     = 1,
-		.default_state  = LEDS_GPIO_DEFSTATE_OFF,
-	}
-};
-
-static struct gpio_led_platform_data litekit_led_platform_data = {
-	.leds           = litekit_leds,
-	.num_leds       = ARRAY_SIZE(litekit_leds),
-};
-
-static struct platform_device litekit_led_device = {
-	.name   = "leds-gpio",
-	.id     = -1,
-	.dev    = {
-		.platform_data = &litekit_led_platform_data,
-	},
-};
-
-void __init mx31lite_db_init(void)
-{
-	mxc_iomux_setup_multiple_pins(litekit_db_board_pins,
-					ARRAY_SIZE(litekit_db_board_pins),
-					"development board pins");
-	imx31_add_imx_uart0(&uart_pdata);
-	imx31_add_mxc_mmc(0, &mmc_pdata);
-	imx31_add_spi_imx0(&spi0_pdata);
-	platform_device_register(&litekit_led_device);
-	imx31_add_imx2_wdt(NULL);
-	mxc_register_device(&imx_rtc_device0, NULL);
-}
diff -druN linux-2.6.39-libre/arch/arm/mach-mx3/mx31moboard-devboard.c linux-3.0-rc7-libre/arch/arm/mach-mx3/mx31moboard-devboard.c
--- linux-2.6.39-libre/arch/arm/mach-mx3/mx31moboard-devboard.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-mx3/mx31moboard-devboard.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,243 +0,0 @@
-/*
- * 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.
- */
-
-#include <linux/gpio.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/delay.h>
-#include <linux/platform_device.h>
-#include <linux/slab.h>
-#include <linux/types.h>
-
-#include <linux/usb/otg.h>
-
-#include <mach/common.h>
-#include <mach/iomux-mx3.h>
-#include <mach/hardware.h>
-#include <mach/ulpi.h>
-
-#include "devices-imx31.h"
-#include "devices.h"
-
-static unsigned int devboard_pins[] = {
-	/* UART1 */
-	MX31_PIN_CTS2__CTS2, MX31_PIN_RTS2__RTS2,
-	MX31_PIN_TXD2__TXD2, MX31_PIN_RXD2__RXD2,
-	/* SDHC2 */
-	MX31_PIN_PC_PWRON__SD2_DATA3, MX31_PIN_PC_VS1__SD2_DATA2,
-	MX31_PIN_PC_READY__SD2_DATA1, MX31_PIN_PC_WAIT_B__SD2_DATA0,
-	MX31_PIN_PC_CD2_B__SD2_CLK, MX31_PIN_PC_CD1_B__SD2_CMD,
-	MX31_PIN_ATA_DIOR__GPIO3_28, MX31_PIN_ATA_DIOW__GPIO3_29,
-	/* USB H1 */
-	MX31_PIN_CSPI1_MISO__USBH1_RXDP, MX31_PIN_CSPI1_MOSI__USBH1_RXDM,
-	MX31_PIN_CSPI1_SS0__USBH1_TXDM, MX31_PIN_CSPI1_SS1__USBH1_TXDP,
-	MX31_PIN_CSPI1_SS2__USBH1_RCV, MX31_PIN_CSPI1_SCLK__USBH1_OEB,
-	MX31_PIN_CSPI1_SPI_RDY__USBH1_FS, MX31_PIN_SFS6__USBH1_SUSPEND,
-	MX31_PIN_NFRE_B__GPIO1_11, MX31_PIN_NFALE__GPIO1_12,
-	/* 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 const struct imxuart_platform_data uart_pdata __initconst = {
-	.flags = IMXUART_HAVE_RTSCTS,
-};
-
-#define SDHC2_CD IOMUX_TO_GPIO(MX31_PIN_ATA_DIOR)
-#define SDHC2_WP IOMUX_TO_GPIO(MX31_PIN_ATA_DIOW)
-
-static int devboard_sdhc2_get_ro(struct device *dev)
-{
-	return !gpio_get_value(SDHC2_WP);
-}
-
-static int devboard_sdhc2_init(struct device *dev, irq_handler_t detect_irq,
-		void *data)
-{
-	int ret;
-
-	ret = gpio_request(SDHC2_CD, "sdhc-detect");
-	if (ret)
-		return ret;
-
-	gpio_direction_input(SDHC2_CD);
-
-	ret = gpio_request(SDHC2_WP, "sdhc-wp");
-	if (ret)
-		goto err_gpio_free;
-	gpio_direction_input(SDHC2_WP);
-
-	ret = request_irq(gpio_to_irq(SDHC2_CD), detect_irq,
-		IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
-		"sdhc2-card-detect", data);
-	if (ret)
-		goto err_gpio_free_2;
-
-	return 0;
-
-err_gpio_free_2:
-	gpio_free(SDHC2_WP);
-err_gpio_free:
-	gpio_free(SDHC2_CD);
-
-	return ret;
-}
-
-static void devboard_sdhc2_exit(struct device *dev, void *data)
-{
-	free_irq(gpio_to_irq(SDHC2_CD), data);
-	gpio_free(SDHC2_WP);
-	gpio_free(SDHC2_CD);
-}
-
-static const struct imxmmc_platform_data sdhc2_pdata __initconst = {
-	.get_ro	= devboard_sdhc2_get_ro,
-	.init	= devboard_sdhc2_init,
-	.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)
-
-static int devboard_usbh1_hw_init(struct platform_device *pdev)
-{
-	mxc_iomux_set_gpr(MUX_PGP_USB_SUSPEND, true);
-
-	mxc_iomux_set_pad(MX31_PIN_CSPI1_MISO, USB_PAD_CFG);
-	mxc_iomux_set_pad(MX31_PIN_CSPI1_MOSI, USB_PAD_CFG);
-	mxc_iomux_set_pad(MX31_PIN_CSPI1_SS0, USB_PAD_CFG);
-	mxc_iomux_set_pad(MX31_PIN_CSPI1_SS1, USB_PAD_CFG);
-	mxc_iomux_set_pad(MX31_PIN_CSPI1_SS2, USB_PAD_CFG);
-	mxc_iomux_set_pad(MX31_PIN_CSPI1_SCLK, USB_PAD_CFG);
-	mxc_iomux_set_pad(MX31_PIN_CSPI1_SPI_RDY, USB_PAD_CFG);
-	mxc_iomux_set_pad(MX31_PIN_SFS6, USB_PAD_CFG);
-
-	mdelay(10);
-
-	return mx31_initialize_usb_hw(pdev->id, MXC_EHCI_POWER_PINS_ENABLED |
-			MXC_EHCI_INTERFACE_SINGLE_UNI);
-}
-
-#define USBH1_VBUSEN_B	IOMUX_TO_GPIO(MX31_PIN_NFRE_B)
-#define USBH1_MODE	IOMUX_TO_GPIO(MX31_PIN_NFALE)
-
-static int devboard_isp1105_init(struct otg_transceiver *otg)
-{
-	int ret = gpio_request(USBH1_MODE, "usbh1-mode");
-	if (ret)
-		return ret;
-	/* single ended */
-	gpio_direction_output(USBH1_MODE, 0);
-
-	ret = gpio_request(USBH1_VBUSEN_B, "usbh1-vbusen");
-	if (ret) {
-		gpio_free(USBH1_MODE);
-		return ret;
-	}
-	gpio_direction_output(USBH1_VBUSEN_B, 1);
-
-	return 0;
-}
-
-
-static int devboard_isp1105_set_vbus(struct otg_transceiver *otg, bool on)
-{
-	if (on)
-		gpio_set_value(USBH1_VBUSEN_B, 0);
-	else
-		gpio_set_value(USBH1_VBUSEN_B, 1);
-
-	return 0;
-}
-
-static struct mxc_usbh_platform_data usbh1_pdata __initdata = {
-	.init	= devboard_usbh1_hw_init,
-	.portsc	= MXC_EHCI_MODE_UTMI | MXC_EHCI_SERIAL,
-};
-
-static int __init devboard_usbh1_init(void)
-{
-	struct otg_transceiver *otg;
-	struct platform_device *pdev;
-
-	otg = kzalloc(sizeof(*otg), GFP_KERNEL);
-	if (!otg)
-		return -ENOMEM;
-
-	otg->label	= "ISP1105";
-	otg->init	= devboard_isp1105_init;
-	otg->set_vbus	= devboard_isp1105_set_vbus;
-
-	usbh1_pdata.otg = otg;
-
-	pdev = imx31_add_mxc_ehci_hs(1, &usbh1_pdata);
-	if (IS_ERR(pdev))
-		return PTR_ERR(pdev);
-
-	return 0;
-}
-
-
-static const struct fsl_usb2_platform_data usb_pdata __initconst = {
-	.operating_mode	= FSL_USB2_DR_DEVICE,
-	.phy_mode	= FSL_USB2_PHY_ULPI,
-};
-
-/*
- * system init for baseboard usage. Will be called by mx31moboard init.
- */
-void __init mx31moboard_devboard_init(void)
-{
-	printk(KERN_INFO "Initializing mx31devboard peripherals\n");
-
-	mxc_iomux_setup_multiple_pins(devboard_pins, ARRAY_SIZE(devboard_pins),
-		"devboard");
-
-	imx31_add_imx_uart1(&uart_pdata);
-
-	imx31_add_mxc_mmc(1, &sdhc2_pdata);
-
-	devboard_init_sel_gpios();
-
-	imx31_add_fsl_usb2_udc(&usb_pdata);
-
-	devboard_usbh1_init();
-}
diff -druN linux-2.6.39-libre/arch/arm/mach-mx3/mx31moboard-marxbot.c linux-3.0-rc7-libre/arch/arm/mach-mx3/mx31moboard-marxbot.c
--- linux-2.6.39-libre/arch/arm/mach-mx3/mx31moboard-marxbot.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-mx3/mx31moboard-marxbot.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,368 +0,0 @@
-/*
- * 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.
- */
-
-#include <linux/delay.h>
-#include <linux/gpio.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/i2c.h>
-#include <linux/spi/spi.h>
-#include <linux/slab.h>
-#include <linux/platform_device.h>
-#include <linux/types.h>
-
-#include <linux/usb/otg.h>
-
-#include <mach/common.h>
-#include <mach/hardware.h>
-#include <mach/imx-uart.h>
-#include <mach/iomux-mx3.h>
-#include <mach/ulpi.h>
-
-#include <media/soc_camera.h>
-
-#include "devices-imx31.h"
-#include "devices.h"
-
-static unsigned int marxbot_pins[] = {
-	/* SDHC2 */
-	MX31_PIN_PC_PWRON__SD2_DATA3, MX31_PIN_PC_VS1__SD2_DATA2,
-	MX31_PIN_PC_READY__SD2_DATA1, MX31_PIN_PC_WAIT_B__SD2_DATA0,
-	MX31_PIN_PC_CD2_B__SD2_CLK, MX31_PIN_PC_CD1_B__SD2_CMD,
-	MX31_PIN_ATA_DIOR__GPIO3_28, MX31_PIN_ATA_DIOW__GPIO3_29,
-	/* CSI */
-	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_CSI_D4__GPIO3_4, MX31_PIN_CSI_D5__GPIO3_5,
-	MX31_PIN_GPIO3_0__GPIO3_0, MX31_PIN_GPIO3_1__GPIO3_1,
-	MX31_PIN_TXD2__GPIO1_28,
-	/* dsPIC resets */
-	MX31_PIN_STXD5__GPIO1_21, MX31_PIN_SRXD5__GPIO1_22,
-	/*battery detection */
-	MX31_PIN_LCS0__GPIO3_23,
-	/* USB H1 */
-	MX31_PIN_CSPI1_MISO__USBH1_RXDP, MX31_PIN_CSPI1_MOSI__USBH1_RXDM,
-	MX31_PIN_CSPI1_SS0__USBH1_TXDM, MX31_PIN_CSPI1_SS1__USBH1_TXDP,
-	MX31_PIN_CSPI1_SS2__USBH1_RCV, MX31_PIN_CSPI1_SCLK__USBH1_OEB,
-	MX31_PIN_CSPI1_SPI_RDY__USBH1_FS, MX31_PIN_SFS6__USBH1_SUSPEND,
-	MX31_PIN_NFRE_B__GPIO1_11, MX31_PIN_NFALE__GPIO1_12,
-	/* 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)
-#define SDHC2_WP IOMUX_TO_GPIO(MX31_PIN_ATA_DIOW)
-
-static int marxbot_sdhc2_get_ro(struct device *dev)
-{
-	return !gpio_get_value(SDHC2_WP);
-}
-
-static int marxbot_sdhc2_init(struct device *dev, irq_handler_t detect_irq,
-		void *data)
-{
-	int ret;
-
-	ret = gpio_request(SDHC2_CD, "sdhc-detect");
-	if (ret)
-		return ret;
-
-	gpio_direction_input(SDHC2_CD);
-
-	ret = gpio_request(SDHC2_WP, "sdhc-wp");
-	if (ret)
-		goto err_gpio_free;
-	gpio_direction_input(SDHC2_WP);
-
-	ret = request_irq(gpio_to_irq(SDHC2_CD), detect_irq,
-		IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
-		"sdhc2-card-detect", data);
-	if (ret)
-		goto err_gpio_free_2;
-
-	return 0;
-
-err_gpio_free_2:
-	gpio_free(SDHC2_WP);
-err_gpio_free:
-	gpio_free(SDHC2_CD);
-
-	return ret;
-}
-
-static void marxbot_sdhc2_exit(struct device *dev, void *data)
-{
-	free_irq(gpio_to_irq(SDHC2_CD), data);
-	gpio_free(SDHC2_WP);
-	gpio_free(SDHC2_CD);
-}
-
-static const struct imxmmc_platform_data sdhc2_pdata __initconst = {
-	.get_ro	= marxbot_sdhc2_get_ro,
-	.init	= marxbot_sdhc2_init,
-	.exit	= marxbot_sdhc2_exit,
-};
-
-#define TRSLAT_RST_B	IOMUX_TO_GPIO(MX31_PIN_STXD5)
-#define DSPICS_RST_B	IOMUX_TO_GPIO(MX31_PIN_SRXD5)
-
-static void dspics_resets_init(void)
-{
-	if (!gpio_request(TRSLAT_RST_B, "translator-rst")) {
-		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, 0);
-		gpio_export(DSPICS_RST_B, false);
-	}
-}
-
-static struct spi_board_info marxbot_spi_board_info[] __initdata = {
-	{
-		.modalias = "spidev",
-		.max_speed_hz = 300000,
-		.bus_num = 1,
-		.chip_select = 1, /* according spi1_cs[] ! */
-	},
-};
-
-#define TURRETCAM_POWER	IOMUX_TO_GPIO(MX31_PIN_GPIO3_1)
-#define BASECAM_POWER	IOMUX_TO_GPIO(MX31_PIN_CSI_D5)
-#define TURRETCAM_RST_B	IOMUX_TO_GPIO(MX31_PIN_GPIO3_0)
-#define BASECAM_RST_B	IOMUX_TO_GPIO(MX31_PIN_CSI_D4)
-#define CAM_CHOICE	IOMUX_TO_GPIO(MX31_PIN_TXD2)
-
-static int marxbot_basecam_power(struct device *dev, int on)
-{
-	gpio_set_value(BASECAM_POWER, !on);
-	return 0;
-}
-
-static int marxbot_basecam_reset(struct device *dev)
-{
-	gpio_set_value(BASECAM_RST_B, 0);
-	udelay(100);
-	gpio_set_value(BASECAM_RST_B, 1);
-	return 0;
-}
-
-static struct i2c_board_info marxbot_i2c_devices[] = {
-	{
-		I2C_BOARD_INFO("mt9t031", 0x5d),
-	},
-};
-
-static struct soc_camera_link base_iclink = {
-	.bus_id		= 0,		/* Must match with the camera ID */
-	.power		= marxbot_basecam_power,
-	.reset		= marxbot_basecam_reset,
-	.board_info	= &marxbot_i2c_devices[0],
-	.i2c_adapter_id	= 0,
-};
-
-static struct platform_device marxbot_camera[] = {
-	{
-		.name	= "soc-camera-pdrv",
-		.id	= 0,
-		.dev	= {
-			.platform_data = &base_iclink,
-		},
-	},
-};
-
-static struct platform_device *marxbot_cameras[] __initdata = {
-	&marxbot_camera[0],
-};
-
-static int __init marxbot_cam_init(void)
-{
-	int ret = gpio_request(CAM_CHOICE, "cam-choice");
-	if (ret)
-		return ret;
-	gpio_direction_output(CAM_CHOICE, 0);
-
-	ret = gpio_request(BASECAM_RST_B, "basecam-reset");
-	if (ret)
-		return ret;
-	gpio_direction_output(BASECAM_RST_B, 1);
-	ret = gpio_request(BASECAM_POWER, "basecam-standby");
-	if (ret)
-		return ret;
-	gpio_direction_output(BASECAM_POWER, 0);
-
-	ret = gpio_request(TURRETCAM_RST_B, "turretcam-reset");
-	if (ret)
-		return ret;
-	gpio_direction_output(TURRETCAM_RST_B, 1);
-	ret = gpio_request(TURRETCAM_POWER, "turretcam-standby");
-	if (ret)
-		return ret;
-	gpio_direction_output(TURRETCAM_POWER, 0);
-
-	return 0;
-}
-
-#define 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)
-
-static int marxbot_usbh1_hw_init(struct platform_device *pdev)
-{
-	mxc_iomux_set_gpr(MUX_PGP_USB_SUSPEND, true);
-
-	mxc_iomux_set_pad(MX31_PIN_CSPI1_MISO, USB_PAD_CFG);
-	mxc_iomux_set_pad(MX31_PIN_CSPI1_MOSI, USB_PAD_CFG);
-	mxc_iomux_set_pad(MX31_PIN_CSPI1_SS0, USB_PAD_CFG);
-	mxc_iomux_set_pad(MX31_PIN_CSPI1_SS1, USB_PAD_CFG);
-	mxc_iomux_set_pad(MX31_PIN_CSPI1_SS2, USB_PAD_CFG);
-	mxc_iomux_set_pad(MX31_PIN_CSPI1_SCLK, USB_PAD_CFG);
-	mxc_iomux_set_pad(MX31_PIN_CSPI1_SPI_RDY, USB_PAD_CFG);
-	mxc_iomux_set_pad(MX31_PIN_SFS6, USB_PAD_CFG);
-
-	mdelay(10);
-
-	return mx31_initialize_usb_hw(pdev->id, MXC_EHCI_POWER_PINS_ENABLED |
-			MXC_EHCI_INTERFACE_SINGLE_UNI);
-}
-
-#define USBH1_VBUSEN_B	IOMUX_TO_GPIO(MX31_PIN_NFRE_B)
-#define USBH1_MODE	IOMUX_TO_GPIO(MX31_PIN_NFALE)
-
-static int marxbot_isp1105_init(struct otg_transceiver *otg)
-{
-	int ret = gpio_request(USBH1_MODE, "usbh1-mode");
-	if (ret)
-		return ret;
-	/* single ended */
-	gpio_direction_output(USBH1_MODE, 0);
-
-	ret = gpio_request(USBH1_VBUSEN_B, "usbh1-vbusen");
-	if (ret) {
-		gpio_free(USBH1_MODE);
-		return ret;
-	}
-	gpio_direction_output(USBH1_VBUSEN_B, 1);
-
-	return 0;
-}
-
-
-static int marxbot_isp1105_set_vbus(struct otg_transceiver *otg, bool on)
-{
-	if (on)
-		gpio_set_value(USBH1_VBUSEN_B, 0);
-	else
-		gpio_set_value(USBH1_VBUSEN_B, 1);
-
-	return 0;
-}
-
-static struct mxc_usbh_platform_data usbh1_pdata __initdata = {
-	.init	= marxbot_usbh1_hw_init,
-	.portsc	= MXC_EHCI_MODE_UTMI | MXC_EHCI_SERIAL,
-};
-
-static int __init marxbot_usbh1_init(void)
-{
-	struct otg_transceiver *otg;
-	struct platform_device *pdev;
-
-	otg = kzalloc(sizeof(*otg), GFP_KERNEL);
-	if (!otg)
-		return -ENOMEM;
-
-	otg->label	= "ISP1105";
-	otg->init	= marxbot_isp1105_init;
-	otg->set_vbus	= marxbot_isp1105_set_vbus;
-
-	usbh1_pdata.otg = otg;
-
-	pdev = imx31_add_mxc_ehci_hs(1, &usbh1_pdata);
-	if (IS_ERR(pdev))
-		return PTR_ERR(pdev);
-
-	return 0;
-}
-
-static const struct fsl_usb2_platform_data usb_pdata __initconst = {
-	.operating_mode	= FSL_USB2_DR_DEVICE,
-	.phy_mode	= FSL_USB2_PHY_ULPI,
-};
-
-/*
- * system init for baseboard usage. Will be called by mx31moboard init.
- */
-void __init mx31moboard_marxbot_init(void)
-{
-	printk(KERN_INFO "Initializing mx31marxbot peripherals\n");
-
-	mxc_iomux_setup_multiple_pins(marxbot_pins, ARRAY_SIZE(marxbot_pins),
-		"marxbot");
-
-	marxbot_init_sel_gpios();
-
-	dspics_resets_init();
-
-	imx31_add_mxc_mmc(1, &sdhc2_pdata);
-
-	spi_register_board_info(marxbot_spi_board_info,
-		ARRAY_SIZE(marxbot_spi_board_info));
-
-	marxbot_cam_init();
-	platform_add_devices(marxbot_cameras, ARRAY_SIZE(marxbot_cameras));
-
-	/* battery present pin */
-	gpio_request(IOMUX_TO_GPIO(MX31_PIN_LCS0), "bat-present");
-	gpio_direction_input(IOMUX_TO_GPIO(MX31_PIN_LCS0));
-	gpio_export(IOMUX_TO_GPIO(MX31_PIN_LCS0), false);
-
-	imx31_add_fsl_usb2_udc(&usb_pdata);
-
-	marxbot_usbh1_init();
-}
diff -druN linux-2.6.39-libre/arch/arm/mach-mx3/mx31moboard-smartbot.c linux-3.0-rc7-libre/arch/arm/mach-mx3/mx31moboard-smartbot.c
--- linux-2.6.39-libre/arch/arm/mach-mx3/mx31moboard-smartbot.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-mx3/mx31moboard-smartbot.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,210 +0,0 @@
-/*
- * 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.
- */
-
-#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 <linux/usb/otg.h>
-#include <linux/usb/ulpi.h>
-
-#include <mach/common.h>
-#include <mach/hardware.h>
-#include <mach/iomux-mx3.h>
-#include <mach/board-mx31moboard.h>
-#include <mach/ulpi.h>
-
-#include <media/soc_camera.h>
-
-#include "devices-imx31.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 const struct imxuart_platform_data uart_pdata __initconst = {
-	.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,
-};
-
-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;
-}
-
-static const struct fsl_usb2_platform_data usb_pdata __initconst = {
-	.operating_mode	= FSL_USB2_DR_DEVICE,
-	.phy_mode	= FSL_USB2_PHY_ULPI,
-};
-
-#if defined(CONFIG_USB_ULPI)
-
-static int smartbot_otg_init(struct platform_device *pdev)
-{
-	return mx31_initialize_usb_hw(pdev->id, MXC_EHCI_POWER_PINS_ENABLED);
-}
-
-static struct mxc_usbh_platform_data otg_host_pdata __initdata = {
-	.init	= smartbot_otg_init,
-	.portsc = MXC_EHCI_MODE_ULPI | MXC_EHCI_UTMI_8BIT,
-};
-
-static int __init smartbot_otg_host_init(void)
-{
-	struct platform_device *pdev;
-
-	otg_host_pdata.otg = imx_otg_ulpi_create(ULPI_OTG_DRVVBUS |
-		ULPI_OTG_DRVVBUS_EXT);
-	if (!otg_host_pdata.otg)
-		return -ENODEV;
-
-	pdev = imx31_add_mxc_ehci_otg(&otg_host_pdata);
-	if (IS_ERR(pdev))
-		return PTR_ERR(pdev);
-
-	return 0;
-}
-#else
-static inline int smartbot_otg_host_init(void) { return 0; }
-#endif
-
-#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 TRSLAT_SRC_CHOICE 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(TRSLAT_SRC_CHOICE, "translator-src-choice")) {
-		gpio_direction_output(TRSLAT_SRC_CHOICE, 0);
-		gpio_export(TRSLAT_SRC_CHOICE, false);
-	}
-}
-/*
- * system init for baseboard usage. Will be called by mx31moboard init.
- */
-void __init mx31moboard_smartbot_init(int board)
-{
-	printk(KERN_INFO "Initializing mx31smartbot peripherals\n");
-
-	mxc_iomux_setup_multiple_pins(smartbot_pins, ARRAY_SIZE(smartbot_pins),
-		"smartbot");
-
-	imx31_add_imx_uart1(&uart_pdata);
-
-	switch (board) {
-	case MX31SMARTBOT:
-		imx31_add_fsl_usb2_udc(&usb_pdata);
-		break;
-	case MX31EYEBOT:
-		smartbot_otg_host_init();
-		break;
-	default:
-		printk(KERN_WARNING "Unknown board %d, USB OTG not initialized",
-			board);
-	}
-
-	smartbot_resets_init();
-
-	smartbot_cam_init();
-	platform_add_devices(smartbot_cameras, ARRAY_SIZE(smartbot_cameras));
-}
diff -druN linux-2.6.39-libre/arch/arm/mach-mx3/pcm037.h linux-3.0-rc7-libre/arch/arm/mach-mx3/pcm037.h
--- linux-2.6.39-libre/arch/arm/mach-mx3/pcm037.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-mx3/pcm037.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,11 +0,0 @@
-#ifndef __PCM037_H__
-#define __PCM037_H__
-
-enum pcm037_board_variant {
-	PCM037_PCM970,
-	PCM037_EET,
-};
-
-extern enum pcm037_board_variant pcm037_variant(void);
-
-#endif
diff -druN linux-2.6.39-libre/arch/arm/mach-mx5/board-cpuimx51.c linux-3.0-rc7-libre/arch/arm/mach-mx5/board-cpuimx51.c
--- linux-2.6.39-libre/arch/arm/mach-mx5/board-cpuimx51.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-mx5/board-cpuimx51.c	2011-07-11 19:51:52.000000000 -0400
@@ -23,13 +23,11 @@
 #include <linux/io.h>
 #include <linux/interrupt.h>
 #include <linux/irq.h>
-#include <linux/fsl_devices.h>
 
 #include <mach/eukrea-baseboards.h>
 #include <mach/common.h>
 #include <mach/hardware.h>
 #include <mach/iomux-mx51.h>
-#include <mach/mxc_ehci.h>
 
 #include <asm/irq.h>
 #include <asm/setup.h>
diff -druN linux-2.6.39-libre/arch/arm/mach-mx5/board-cpuimx51sd.c linux-3.0-rc7-libre/arch/arm/mach-mx5/board-cpuimx51sd.c
--- linux-2.6.39-libre/arch/arm/mach-mx5/board-cpuimx51sd.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-mx5/board-cpuimx51sd.c	2011-07-11 19:51:52.000000000 -0400
@@ -23,7 +23,6 @@
 #include <linux/io.h>
 #include <linux/interrupt.h>
 #include <linux/irq.h>
-#include <linux/fsl_devices.h>
 #include <linux/i2c-gpio.h>
 #include <linux/spi/spi.h>
 #include <linux/can/platform/mcp251x.h>
@@ -32,7 +31,6 @@
 #include <mach/common.h>
 #include <mach/hardware.h>
 #include <mach/iomux-mx51.h>
-#include <mach/mxc_ehci.h>
 
 #include <asm/irq.h>
 #include <asm/setup.h>
diff -druN linux-2.6.39-libre/arch/arm/mach-mx5/board-mx50_rdp.c linux-3.0-rc7-libre/arch/arm/mach-mx5/board-mx50_rdp.c
--- linux-2.6.39-libre/arch/arm/mach-mx5/board-mx50_rdp.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-mx5/board-mx50_rdp.c	2011-07-11 19:51:52.000000000 -0400
@@ -23,7 +23,6 @@
 #include <linux/gpio.h>
 #include <linux/delay.h>
 #include <linux/io.h>
-#include <linux/fsl_devices.h>
 
 #include <mach/common.h>
 #include <mach/hardware.h>
diff -druN linux-2.6.39-libre/arch/arm/mach-mx5/board-mx51_babbage.c linux-3.0-rc7-libre/arch/arm/mach-mx5/board-mx51_babbage.c
--- linux-2.6.39-libre/arch/arm/mach-mx5/board-mx51_babbage.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-mx5/board-mx51_babbage.c	2011-07-11 19:51:52.000000000 -0400
@@ -16,9 +16,6 @@
 #include <linux/gpio.h>
 #include <linux/delay.h>
 #include <linux/io.h>
-#include <linux/fsl_devices.h>
-#include <linux/fec.h>
-#include <linux/gpio_keys.h>
 #include <linux/input.h>
 #include <linux/spi/flash.h>
 #include <linux/spi/spi.h>
@@ -26,7 +23,6 @@
 #include <mach/common.h>
 #include <mach/hardware.h>
 #include <mach/iomux-mx51.h>
-#include <mach/mxc_ehci.h>
 
 #include <asm/irq.h>
 #include <asm/setup.h>
@@ -208,18 +204,16 @@
 {
 	int ret;
 
-	/* Bring USB hub out of reset */
-	ret = gpio_request(BABBAGE_USB_HUB_RESET, "GPIO1_7");
+	/* Reset USB hub */
+	ret = gpio_request_one(BABBAGE_USB_HUB_RESET,
+					GPIOF_OUT_INIT_LOW, "GPIO1_7");
 	if (ret) {
 		printk(KERN_ERR"failed to get GPIO_USB_HUB_RESET: %d\n", ret);
 		return;
 	}
-	gpio_direction_output(BABBAGE_USB_HUB_RESET, 0);
 
-	/* USB HUB RESET - De-assert USB HUB RESET_N */
-	msleep(1);
-	gpio_set_value(BABBAGE_USB_HUB_RESET, 0);
-	msleep(1);
+	msleep(2);
+	/* Deassert reset */
 	gpio_set_value(BABBAGE_USB_HUB_RESET, 1);
 }
 
@@ -361,7 +355,7 @@
 
 	/* Set the PAD settings for the pwr key. */
 	mxc_iomux_v3_setup_pad(power_key);
-	imx51_add_gpio_keys(&imx_button_data);
+	imx_add_gpio_keys(&imx_button_data);
 
 	imx51_add_imx_i2c(0, &babbage_i2c_data);
 	imx51_add_imx_i2c(1, &babbage_i2c_data);
diff -druN linux-2.6.39-libre/arch/arm/mach-mx5/board-mx51_efikamx.c linux-3.0-rc7-libre/arch/arm/mach-mx5/board-mx51_efikamx.c
--- linux-2.6.39-libre/arch/arm/mach-mx5/board-mx51_efikamx.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-mx5/board-mx51_efikamx.c	2011-07-11 19:51:52.000000000 -0400
@@ -22,7 +22,6 @@
 #include <linux/input.h>
 #include <linux/delay.h>
 #include <linux/io.h>
-#include <linux/fsl_devices.h>
 #include <linux/spi/flash.h>
 #include <linux/spi/spi.h>
 #include <linux/mfd/mc13892.h>
@@ -32,8 +31,6 @@
 #include <mach/common.h>
 #include <mach/hardware.h>
 #include <mach/iomux-mx51.h>
-#include <mach/i2c.h>
-#include <mach/mxc_ehci.h>
 
 #include <asm/irq.h>
 #include <asm/setup.h>
@@ -252,7 +249,7 @@
 	}
 
 	platform_device_register(&mx51_efikamx_leds_device);
-	imx51_add_gpio_keys(&mx51_efikamx_powerkey_data);
+	imx_add_gpio_keys(&mx51_efikamx_powerkey_data);
 
 	if (system_rev == 0x11) {
 		gpio_request(EFIKAMX_RESET1_1, "reset");
diff -druN linux-2.6.39-libre/arch/arm/mach-mx5/board-mx51_efikasb.c linux-3.0-rc7-libre/arch/arm/mach-mx5/board-mx51_efikasb.c
--- linux-2.6.39-libre/arch/arm/mach-mx5/board-mx51_efikasb.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-mx5/board-mx51_efikasb.c	2011-07-11 19:51:52.000000000 -0400
@@ -22,7 +22,6 @@
 #include <linux/input.h>
 #include <linux/delay.h>
 #include <linux/io.h>
-#include <linux/fsl_devices.h>
 #include <linux/spi/flash.h>
 #include <linux/spi/spi.h>
 #include <linux/mfd/mc13892.h>
@@ -35,8 +34,6 @@
 #include <mach/common.h>
 #include <mach/hardware.h>
 #include <mach/iomux-mx51.h>
-#include <mach/i2c.h>
-#include <mach/mxc_ehci.h>
 
 #include <asm/irq.h>
 #include <asm/setup.h>
@@ -260,7 +257,7 @@
 	imx51_add_sdhci_esdhc_imx(1, NULL);
 
 	platform_device_register(&mx51_efikasb_leds_device);
-	imx51_add_gpio_keys(&mx51_efikasb_keys_data);
+	imx_add_gpio_keys(&mx51_efikasb_keys_data);
 
 }
 
diff -druN linux-2.6.39-libre/arch/arm/mach-mx5/board-mx53_evk.c linux-3.0-rc7-libre/arch/arm/mach-mx5/board-mx53_evk.c
--- linux-2.6.39-libre/arch/arm/mach-mx5/board-mx53_evk.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-mx5/board-mx53_evk.c	2011-07-11 19:51:52.000000000 -0400
@@ -21,7 +21,6 @@
 
 #include <linux/init.h>
 #include <linux/clk.h>
-#include <linux/fec.h>
 #include <linux/delay.h>
 #include <linux/gpio.h>
 #include <linux/spi/flash.h>
@@ -31,7 +30,6 @@
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/time.h>
-#include <mach/imx-uart.h>
 #include <mach/iomux-mx53.h>
 
 #define MX53_EVK_FEC_PHY_RST	IMX_GPIO_NR(7, 6)
diff -druN linux-2.6.39-libre/arch/arm/mach-mx5/board-mx53_loco.c linux-3.0-rc7-libre/arch/arm/mach-mx5/board-mx53_loco.c
--- linux-2.6.39-libre/arch/arm/mach-mx5/board-mx53_loco.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-mx5/board-mx53_loco.c	2011-07-11 19:51:52.000000000 -0400
@@ -20,13 +20,11 @@
 
 #include <linux/init.h>
 #include <linux/clk.h>
-#include <linux/fec.h>
 #include <linux/delay.h>
 #include <linux/gpio.h>
 
 #include <mach/common.h>
 #include <mach/hardware.h>
-#include <mach/imx-uart.h>
 #include <mach/iomux-mx53.h>
 
 #include <asm/mach-types.h>
diff -druN linux-2.6.39-libre/arch/arm/mach-mx5/board-mx53_smd.c linux-3.0-rc7-libre/arch/arm/mach-mx5/board-mx53_smd.c
--- linux-2.6.39-libre/arch/arm/mach-mx5/board-mx53_smd.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-mx5/board-mx53_smd.c	2011-07-11 19:51:52.000000000 -0400
@@ -20,13 +20,11 @@
 
 #include <linux/init.h>
 #include <linux/clk.h>
-#include <linux/fec.h>
 #include <linux/delay.h>
 #include <linux/gpio.h>
 
 #include <mach/common.h>
 #include <mach/hardware.h>
-#include <mach/imx-uart.h>
 #include <mach/iomux-mx53.h>
 
 #include <asm/mach-types.h>
@@ -52,6 +50,31 @@
 	/* I2C1 */
 	MX53_PAD_CSI0_DAT8__I2C1_SDA,
 	MX53_PAD_CSI0_DAT9__I2C1_SCL,
+	/* SD1 */
+	MX53_PAD_SD1_CMD__ESDHC1_CMD,
+	MX53_PAD_SD1_CLK__ESDHC1_CLK,
+	MX53_PAD_SD1_DATA0__ESDHC1_DAT0,
+	MX53_PAD_SD1_DATA1__ESDHC1_DAT1,
+	MX53_PAD_SD1_DATA2__ESDHC1_DAT2,
+	MX53_PAD_SD1_DATA3__ESDHC1_DAT3,
+	/* SD2 */
+	MX53_PAD_SD2_CMD__ESDHC2_CMD,
+	MX53_PAD_SD2_CLK__ESDHC2_CLK,
+	MX53_PAD_SD2_DATA0__ESDHC2_DAT0,
+	MX53_PAD_SD2_DATA1__ESDHC2_DAT1,
+	MX53_PAD_SD2_DATA2__ESDHC2_DAT2,
+	MX53_PAD_SD2_DATA3__ESDHC2_DAT3,
+	/* SD3 */
+	MX53_PAD_PATA_DATA8__ESDHC3_DAT0,
+	MX53_PAD_PATA_DATA9__ESDHC3_DAT1,
+	MX53_PAD_PATA_DATA10__ESDHC3_DAT2,
+	MX53_PAD_PATA_DATA11__ESDHC3_DAT3,
+	MX53_PAD_PATA_DATA0__ESDHC3_DAT4,
+	MX53_PAD_PATA_DATA1__ESDHC3_DAT5,
+	MX53_PAD_PATA_DATA2__ESDHC3_DAT6,
+	MX53_PAD_PATA_DATA3__ESDHC3_DAT7,
+	MX53_PAD_PATA_IORDY__ESDHC3_CLK,
+	MX53_PAD_PATA_RESET_B__ESDHC3_CMD,
 };
 
 static const struct imxuart_platform_data mx53_smd_uart_data __initconst = {
@@ -97,6 +120,9 @@
 	imx53_add_fec(&mx53_smd_fec_data);
 	imx53_add_imx2_wdt(0, NULL);
 	imx53_add_imx_i2c(0, &mx53_smd_i2c_data);
+	imx53_add_sdhci_esdhc_imx(0, NULL);
+	imx53_add_sdhci_esdhc_imx(1, NULL);
+	imx53_add_sdhci_esdhc_imx(2, NULL);
 }
 
 static void __init mx53_smd_timer_init(void)
diff -druN linux-2.6.39-libre/arch/arm/mach-mx5/clock-mx51-mx53.c linux-3.0-rc7-libre/arch/arm/mach-mx5/clock-mx51-mx53.c
--- linux-2.6.39-libre/arch/arm/mach-mx5/clock-mx51-mx53.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-mx5/clock-mx51-mx53.c	2011-07-11 19:51:52.000000000 -0400
@@ -1563,6 +1563,7 @@
 	clk_enable(&iim_clk);
 	mx53_revision();
 	clk_disable(&iim_clk);
+	mx53_display_revision();
 
 	/* Set SDHC parents to be PLL2 */
 	clk_set_parent(&esdhc1_clk, &pll2_sw_clk);
diff -druN linux-2.6.39-libre/arch/arm/mach-mx5/cpu.c linux-3.0-rc7-libre/arch/arm/mach-mx5/cpu.c
--- linux-2.6.39-libre/arch/arm/mach-mx5/cpu.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-mx5/cpu.c	2011-07-11 19:51:52.000000000 -0400
@@ -166,6 +166,29 @@
 }
 EXPORT_SYMBOL(mx50_revision);
 
+void mx53_display_revision(void)
+{
+	int rev;
+	char *srev;
+	rev = mx53_revision();
+
+	switch (rev) {
+	case IMX_CHIP_REVISION_1_0:
+		srev = IMX_CHIP_REVISION_1_0_STRING;
+		break;
+	case IMX_CHIP_REVISION_2_0:
+		srev = IMX_CHIP_REVISION_2_0_STRING;
+		break;
+	case IMX_CHIP_REVISION_2_1:
+		srev = IMX_CHIP_REVISION_2_1_STRING;
+		break;
+	default:
+		srev = IMX_CHIP_REVISION_UNKNOWN_STRING;
+	}
+	printk(KERN_INFO "CPU identified as i.MX53, silicon rev %s\n", srev);
+}
+EXPORT_SYMBOL(mx53_display_revision);
+
 static int __init post_cpu_init(void)
 {
 	unsigned int reg;
diff -druN linux-2.6.39-libre/arch/arm/mach-mx5/devices-imx50.h linux-3.0-rc7-libre/arch/arm/mach-mx5/devices-imx50.h
--- linux-2.6.39-libre/arch/arm/mach-mx5/devices-imx50.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-mx5/devices-imx50.h	2011-07-11 19:51:52.000000000 -0400
@@ -21,14 +21,14 @@
 #include <mach/mx50.h>
 #include <mach/devices-common.h>
 
-extern const struct imx_imx_uart_1irq_data imx50_imx_uart_data[] __initconst;
+extern const struct imx_imx_uart_1irq_data imx50_imx_uart_data[];
 #define imx50_add_imx_uart(id, pdata)	\
 	imx_add_imx_uart_1irq(&imx50_imx_uart_data[id], pdata)
 
-extern const struct imx_fec_data imx50_fec_data __initconst;
+extern const struct imx_fec_data imx50_fec_data;
 #define imx50_add_fec(pdata)	\
 	imx_add_fec(&imx50_fec_data, pdata)
 
-extern const struct imx_imx_i2c_data imx50_imx_i2c_data[] __initconst;
+extern const struct imx_imx_i2c_data imx50_imx_i2c_data[];
 #define imx50_add_imx_i2c(id, pdata)	\
 	imx_add_imx_i2c(&imx50_imx_i2c_data[id], pdata)
diff -druN linux-2.6.39-libre/arch/arm/mach-mx5/devices-imx51.h linux-3.0-rc7-libre/arch/arm/mach-mx5/devices-imx51.h
--- linux-2.6.39-libre/arch/arm/mach-mx5/devices-imx51.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-mx5/devices-imx51.h	2011-07-11 19:51:52.000000000 -0400
@@ -9,49 +9,46 @@
 #include <mach/mx51.h>
 #include <mach/devices-common.h>
 
-extern const struct imx_fec_data imx51_fec_data __initconst;
+extern const struct imx_fec_data imx51_fec_data;
 #define imx51_add_fec(pdata)	\
 	imx_add_fec(&imx51_fec_data, pdata)
 
-#define imx51_add_gpio_keys(pdata) imx_add_gpio_keys(pdata)
-
-extern const struct imx_imx_i2c_data imx51_imx_i2c_data[] __initconst;
+extern const struct imx_imx_i2c_data imx51_imx_i2c_data[];
 #define imx51_add_imx_i2c(id, pdata)	\
 	imx_add_imx_i2c(&imx51_imx_i2c_data[id], pdata)
 
-extern const struct imx_imx_ssi_data imx51_imx_ssi_data[] __initconst;
+extern const struct imx_imx_ssi_data imx51_imx_ssi_data[];
 #define imx51_add_imx_ssi(id, pdata)	\
 	imx_add_imx_ssi(&imx51_imx_ssi_data[id], pdata)
 
-extern const struct imx_imx_uart_1irq_data imx51_imx_uart_data[] __initconst;
+extern const struct imx_imx_uart_1irq_data imx51_imx_uart_data[];
 #define imx51_add_imx_uart(id, pdata)	\
 	imx_add_imx_uart_1irq(&imx51_imx_uart_data[id], pdata)
 
-extern const struct imx_mxc_nand_data imx51_mxc_nand_data __initconst;
+extern const struct imx_mxc_nand_data imx51_mxc_nand_data;
 #define imx51_add_mxc_nand(pdata)	\
 	imx_add_mxc_nand(&imx51_mxc_nand_data, pdata)
 
-extern const struct imx_sdhci_esdhc_imx_data
-imx51_sdhci_esdhc_imx_data[] __initconst;
+extern const struct imx_sdhci_esdhc_imx_data imx51_sdhci_esdhc_imx_data[];
 #define imx51_add_sdhci_esdhc_imx(id, pdata)	\
 	imx_add_sdhci_esdhc_imx(&imx51_sdhci_esdhc_imx_data[id], pdata)
 
-extern const struct imx_spi_imx_data imx51_cspi_data __initconst;
+extern const struct imx_spi_imx_data imx51_cspi_data;
 #define imx51_add_cspi(pdata)	\
 	imx_add_spi_imx(&imx51_cspi_data, pdata)
 
-extern const struct imx_spi_imx_data imx51_ecspi_data[] __initconst;
+extern const struct imx_spi_imx_data imx51_ecspi_data[];
 #define imx51_add_ecspi(id, pdata)	\
 	imx_add_spi_imx(&imx51_ecspi_data[id], pdata)
 
-extern const struct imx_imx2_wdt_data imx51_imx2_wdt_data[] __initconst;
+extern const struct imx_imx2_wdt_data imx51_imx2_wdt_data[];
 #define imx51_add_imx2_wdt(id, pdata)	\
 	imx_add_imx2_wdt(&imx51_imx2_wdt_data[id])
 
-extern const struct imx_mxc_pwm_data imx51_mxc_pwm_data[] __initconst;
+extern const struct imx_mxc_pwm_data imx51_mxc_pwm_data[];
 #define imx51_add_mxc_pwm(id)	\
 	imx_add_mxc_pwm(&imx51_mxc_pwm_data[id])
 
-extern const struct imx_imx_keypad_data imx51_imx_keypad_data __initconst;
+extern const struct imx_imx_keypad_data imx51_imx_keypad_data;
 #define imx51_add_imx_keypad(pdata)	\
 	imx_add_imx_keypad(&imx51_imx_keypad_data, pdata)
diff -druN linux-2.6.39-libre/arch/arm/mach-mx5/devices-imx53.h linux-3.0-rc7-libre/arch/arm/mach-mx5/devices-imx53.h
--- linux-2.6.39-libre/arch/arm/mach-mx5/devices-imx53.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-mx5/devices-imx53.h	2011-07-11 19:51:52.000000000 -0400
@@ -8,28 +8,27 @@
 #include <mach/mx53.h>
 #include <mach/devices-common.h>
 
-extern const struct imx_fec_data imx53_fec_data __initconst;
+extern const struct imx_fec_data imx53_fec_data;
 #define imx53_add_fec(pdata)   \
 	imx_add_fec(&imx53_fec_data, pdata)
 
-extern const struct imx_imx_uart_1irq_data imx53_imx_uart_data[] __initconst;
+extern const struct imx_imx_uart_1irq_data imx53_imx_uart_data[];
 #define imx53_add_imx_uart(id, pdata)	\
 	imx_add_imx_uart_1irq(&imx53_imx_uart_data[id], pdata)
 
 
-extern const struct imx_imx_i2c_data imx53_imx_i2c_data[] __initconst;
+extern const struct imx_imx_i2c_data imx53_imx_i2c_data[];
 #define imx53_add_imx_i2c(id, pdata)	\
 	imx_add_imx_i2c(&imx53_imx_i2c_data[id], pdata)
 
-extern const struct imx_sdhci_esdhc_imx_data
-imx53_sdhci_esdhc_imx_data[] __initconst;
+extern const struct imx_sdhci_esdhc_imx_data imx53_sdhci_esdhc_imx_data[];
 #define imx53_add_sdhci_esdhc_imx(id, pdata)	\
 	imx_add_sdhci_esdhc_imx(&imx53_sdhci_esdhc_imx_data[id], pdata)
 
-extern const struct imx_spi_imx_data imx53_ecspi_data[] __initconst;
+extern const struct imx_spi_imx_data imx53_ecspi_data[];
 #define imx53_add_ecspi(id, pdata)	\
 	imx_add_spi_imx(&imx53_ecspi_data[id], pdata)
 
-extern const struct imx_imx2_wdt_data imx53_imx2_wdt_data[] __initconst;
+extern const struct imx_imx2_wdt_data imx53_imx2_wdt_data[];
 #define imx53_add_imx2_wdt(id, pdata)	\
 	imx_add_imx2_wdt(&imx53_imx2_wdt_data[id])
diff -druN linux-2.6.39-libre/arch/arm/mach-mx5/eukrea_mbimx51-baseboard.c linux-3.0-rc7-libre/arch/arm/mach-mx5/eukrea_mbimx51-baseboard.c
--- linux-2.6.39-libre/arch/arm/mach-mx5/eukrea_mbimx51-baseboard.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-mx5/eukrea_mbimx51-baseboard.c	2011-07-11 19:51:52.000000000 -0400
@@ -18,13 +18,11 @@
 #include <linux/io.h>
 #include <linux/interrupt.h>
 #include <linux/irq.h>
-#include <linux/fsl_devices.h>
 #include <linux/i2c/tsc2007.h>
 #include <linux/leds.h>
 
 #include <mach/common.h>
 #include <mach/hardware.h>
-#include <mach/imx-uart.h>
 #include <mach/iomux-mx51.h>
 
 #include <asm/mach/arch.h>
diff -druN linux-2.6.39-libre/arch/arm/mach-mx5/eukrea_mbimxsd-baseboard.c linux-3.0-rc7-libre/arch/arm/mach-mx5/eukrea_mbimxsd-baseboard.c
--- linux-2.6.39-libre/arch/arm/mach-mx5/eukrea_mbimxsd-baseboard.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-mx5/eukrea_mbimxsd-baseboard.c	2011-07-11 19:51:52.000000000 -0400
@@ -27,7 +27,6 @@
 #include <linux/irq.h>
 #include <linux/leds.h>
 #include <linux/platform_device.h>
-#include <linux/gpio_keys.h>
 #include <linux/input.h>
 #include <linux/i2c.h>
 
@@ -38,7 +37,6 @@
 
 #include <mach/hardware.h>
 #include <mach/common.h>
-#include <mach/imx-uart.h>
 #include <mach/iomux-mx51.h>
 #include <mach/audmux.h>
 
@@ -108,23 +106,14 @@
 	},
 };
 
-static struct gpio_keys_platform_data eukrea_mbimxsd_button_data = {
+static const struct gpio_keys_platform_data
+		eukrea_mbimxsd_button_data __initconst = {
 	.buttons	= eukrea_mbimxsd_gpio_buttons,
 	.nbuttons	= ARRAY_SIZE(eukrea_mbimxsd_gpio_buttons),
 };
 
-static struct platform_device eukrea_mbimxsd_button_device = {
-	.name		= "gpio-keys",
-	.id		= -1,
-	.num_resources	= 0,
-	.dev		= {
-		.platform_data	= &eukrea_mbimxsd_button_data,
-	}
-};
-
 static struct platform_device *platform_devices[] __initdata = {
 	&eukrea_mbimxsd_leds_gpio,
-	&eukrea_mbimxsd_button_device,
 };
 
 static const struct imxuart_platform_data uart_pdata __initconst = {
@@ -166,4 +155,5 @@
 				ARRAY_SIZE(eukrea_mbimxsd_i2c_devices));
 
 	platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices));
+	imx_add_gpio_keys(&eukrea_mbimxsd_button_data);
 }
diff -druN linux-2.6.39-libre/arch/arm/mach-mx5/Kconfig linux-3.0-rc7-libre/arch/arm/mach-mx5/Kconfig
--- linux-2.6.39-libre/arch/arm/mach-mx5/Kconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-mx5/Kconfig	2011-07-11 19:51:52.000000000 -0400
@@ -1,11 +1,11 @@
-if ARCH_MX5
-# ARCH_MX50/51/53 are left to mark places where prevent multi-soc in single
+if ARCH_MX503 || ARCH_MX51
+# ARCH_MX5/50/53 are left to mark places where prevent multi-soc in single
 # image. So for most time, SOC_IMX50/51/53 should be used.
 
-config ARCH_MX50
+config ARCH_MX5
 	bool
 
-config ARCH_MX51
+config ARCH_MX50
 	bool
 
 config ARCH_MX53
@@ -13,27 +13,54 @@
 
 config SOC_IMX50
 	bool
+	select CPU_V7
+	select ARM_L1_CACHE_SHIFT_6
 	select MXC_TZIC
 	select ARCH_MXC_IOMUX_V3
 	select ARCH_MXC_AUDMUX_V2
 	select ARCH_HAS_CPUFREQ
+	select ARCH_MX5
 	select ARCH_MX50
 
 config	SOC_IMX51
 	bool
+	select CPU_V7
+	select ARM_L1_CACHE_SHIFT_6
 	select MXC_TZIC
 	select ARCH_MXC_IOMUX_V3
 	select ARCH_MXC_AUDMUX_V2
 	select ARCH_HAS_CPUFREQ
-	select ARCH_MX51
+	select ARCH_MX5
 
 config	SOC_IMX53
 	bool
+	select CPU_V7
+	select ARM_L1_CACHE_SHIFT_6
 	select MXC_TZIC
 	select ARCH_MXC_IOMUX_V3
+	select ARCH_MX5
 	select ARCH_MX53
 
-comment "MX5 platforms:"
+if ARCH_MX50_SUPPORTED
+#comment "i.MX50 machines:"
+
+config MACH_MX50_RDP
+	bool "Support MX50 reference design platform"
+	depends on BROKEN
+	select SOC_IMX50
+	select IMX_HAVE_PLATFORM_IMX_I2C
+	select IMX_HAVE_PLATFORM_IMX_UART
+	select IMX_HAVE_PLATFORM_SDHCI_ESDHC_IMX
+	select IMX_HAVE_PLATFORM_SPI_IMX
+	select IMX_HAVE_PLATFORM_FEC
+	help
+	  Include support for MX50 reference design platform (RDP) board. This
+	  includes specific configurations for the board and its peripherals.
+
+endif # ARCH_MX50_SUPPORTED
+
+if ARCH_MX51
+comment "i.MX51 machines:"
 
 config MACH_MX51_BABBAGE
 	bool "Support MX51 BABBAGE platforms"
@@ -136,6 +163,11 @@
 	  Include support for Genesi Efika Smartbook. This includes specific
 	  configurations for the board and its peripherals.
 
+endif # ARCH_MX51
+
+if ARCH_MX53_SUPPORTED
+comment "i.MX53 machines:"
+
 config MACH_MX53_EVK
 	bool "Support MX53 EVK platforms"
 	select SOC_IMX53
@@ -154,6 +186,7 @@
 	select IMX_HAVE_PLATFORM_IMX2_WDT
 	select IMX_HAVE_PLATFORM_IMX_I2C
 	select IMX_HAVE_PLATFORM_IMX_UART
+	select IMX_HAVE_PLATFORM_SDHCI_ESDHC_IMX
 	help
 	  Include support for MX53 SMD platform. This includes specific
 	  configurations for the board and its peripherals.
@@ -170,17 +203,6 @@
 	  Include support for MX53 LOCO platform. This includes specific
 	  configurations for the board and its peripherals.
 
-config MACH_MX50_RDP
-	bool "Support MX50 reference design platform"
-	depends on BROKEN
-	select SOC_IMX50
-	select IMX_HAVE_PLATFORM_IMX_I2C
-	select IMX_HAVE_PLATFORM_IMX_UART
-	select IMX_HAVE_PLATFORM_SDHCI_ESDHC_IMX
-	select IMX_HAVE_PLATFORM_SPI_IMX
-	select IMX_HAVE_PLATFORM_FEC
-	help
-	  Include support for MX50 reference design platform (RDP) board. This
-	  includes specific configurations for the board and its peripherals.
+endif # ARCH_MX53_SUPPORTED
 
 endif
diff -druN linux-2.6.39-libre/arch/arm/mach-mx5/mx51_efika.c linux-3.0-rc7-libre/arch/arm/mach-mx5/mx51_efika.c
--- linux-2.6.39-libre/arch/arm/mach-mx5/mx51_efika.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-mx5/mx51_efika.c	2011-07-11 19:51:52.000000000 -0400
@@ -20,7 +20,6 @@
 #include <linux/input.h>
 #include <linux/delay.h>
 #include <linux/io.h>
-#include <linux/fsl_devices.h>
 #include <linux/spi/flash.h>
 #include <linux/spi/spi.h>
 #include <linux/mfd/mc13892.h>
@@ -30,8 +29,6 @@
 #include <mach/common.h>
 #include <mach/hardware.h>
 #include <mach/iomux-mx51.h>
-#include <mach/i2c.h>
-#include <mach/mxc_ehci.h>
 
 #include <linux/usb/otg.h>
 #include <linux/usb/ulpi.h>
diff -druN linux-2.6.39-libre/arch/arm/mach-mxc91231/clock.c linux-3.0-rc7-libre/arch/arm/mach-mxc91231/clock.c
--- linux-2.6.39-libre/arch/arm/mach-mxc91231/clock.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-mxc91231/clock.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,640 +0,0 @@
-#include <linux/clk.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/io.h>
-#include <linux/clkdev.h>
-
-#include <mach/clock.h>
-#include <mach/hardware.h>
-#include <mach/common.h>
-
-#include <asm/bug.h>
-#include <asm/div64.h>
-
-#include "crm_regs.h"
-
-#define CRM_SMALL_DIVIDER(base, name) \
-	crm_small_divider(base, \
-			  base ## _ ## name ## _OFFSET, \
-			  base ## _ ## name ## _MASK)
-#define CRM_1DIVIDER(base, name) \
-	crm_divider(base, \
-		    base ## _ ## name ## _OFFSET, \
-		    base ## _ ## name ## _MASK, 1)
-#define CRM_16DIVIDER(base, name) \
-	crm_divider(base, \
-		    base ## _ ## name ## _OFFSET, \
-		    base ## _ ## name ## _MASK, 16)
-
-static u32 crm_small_divider(void __iomem *reg, u8 offset, u32 mask)
-{
-	static const u32 crm_small_dividers[] = {
-		2, 3, 4, 5, 6, 8, 10, 12
-	};
-	u8 idx;
-
-	idx = (__raw_readl(reg) & mask) >> offset;
-	if (idx > 7)
-		return 1;
-
-	return crm_small_dividers[idx];
-}
-
-static u32 crm_divider(void __iomem *reg, u8 offset, u32 mask, u32 z)
-{
-	u32 div;
-	div = (__raw_readl(reg) & mask) >> offset;
-	return div ? div : z;
-}
-
-static int _clk_1bit_enable(struct clk *clk)
-{
-	u32 reg;
-
-	reg = __raw_readl(clk->enable_reg);
-	reg |= 1 << clk->enable_shift;
-	__raw_writel(reg, clk->enable_reg);
-
-	return 0;
-}
-
-static void _clk_1bit_disable(struct clk *clk)
-{
-	u32 reg;
-
-	reg = __raw_readl(clk->enable_reg);
-	reg &= ~(1 << clk->enable_shift);
-	__raw_writel(reg, clk->enable_reg);
-}
-
-static int _clk_3bit_enable(struct clk *clk)
-{
-	u32 reg;
-
-	reg = __raw_readl(clk->enable_reg);
-	reg |= 0x7 << clk->enable_shift;
-	__raw_writel(reg, clk->enable_reg);
-
-	return 0;
-}
-
-static void _clk_3bit_disable(struct clk *clk)
-{
-	u32 reg;
-
-	reg = __raw_readl(clk->enable_reg);
-	reg &= ~(0x7 << clk->enable_shift);
-	__raw_writel(reg, clk->enable_reg);
-}
-
-static unsigned long ckih_rate;
-
-static unsigned long clk_ckih_get_rate(struct clk *clk)
-{
-	return ckih_rate;
-}
-
-static struct clk ckih_clk = {
-	.get_rate = clk_ckih_get_rate,
-};
-
-static unsigned long clk_ckih_x2_get_rate(struct clk *clk)
-{
-	return 2 * clk_get_rate(clk->parent);
-}
-
-static struct clk ckih_x2_clk = {
-	.parent = &ckih_clk,
-	.get_rate = clk_ckih_x2_get_rate,
-};
-
-static unsigned long clk_ckil_get_rate(struct clk *clk)
-{
-	return CKIL_CLK_FREQ;
-}
-
-static struct clk ckil_clk = {
-	.get_rate = clk_ckil_get_rate,
-};
-
-/* plls stuff */
-static struct clk mcu_pll_clk;
-static struct clk dsp_pll_clk;
-static struct clk usb_pll_clk;
-
-static struct clk *pll_clk(u8 sel)
-{
-	switch (sel) {
-	case 0:
-		return &mcu_pll_clk;
-	case 1:
-		return &dsp_pll_clk;
-	case 2:
-		return &usb_pll_clk;
-	}
-	BUG();
-}
-
-static void __iomem *pll_base(struct clk *clk)
-{
-	if (clk == &mcu_pll_clk)
-		return MXC_PLL0_BASE;
-	else if (clk == &dsp_pll_clk)
-		return MXC_PLL1_BASE;
-	else if (clk == &usb_pll_clk)
-		return MXC_PLL2_BASE;
-	BUG();
-}
-
-static unsigned long clk_pll_get_rate(struct clk *clk)
-{
-	const void __iomem *pllbase;
-	unsigned long dp_op, dp_mfd, dp_mfn, pll_hfsm, ref_clk, mfi;
-	long mfn, mfn_abs, mfd, pdf;
-	s64 temp;
-	pllbase = pll_base(clk);
-
-	pll_hfsm = __raw_readl(pllbase + MXC_PLL_DP_CTL) & MXC_PLL_DP_CTL_HFSM;
-	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_OFFSET) & MXC_PLL_DP_OP_PDF_MASK;
-	mfi = (mfi <= 5) ? 5 : mfi;
-	mfd = dp_mfd & MXC_PLL_DP_MFD_MASK;
-	mfn = dp_mfn & MXC_PLL_DP_MFN_MASK;
-	mfn = (mfn <= 0x4000000) ? mfn : (mfn - 0x10000000);
-
-	if (mfn < 0)
-		mfn_abs = -mfn;
-	else
-		mfn_abs = mfn;
-
-/* XXX: actually this asumes that ckih is fed to pll, but spec says
- * that ckih_x2 is also possible. need to check this out.
- */
-	ref_clk = clk_get_rate(&ckih_clk);
-
-	ref_clk *= 2;
-	ref_clk /= pdf + 1;
-
-	temp = (u64) ref_clk * mfn_abs;
-	do_div(temp, mfd);
-	if (mfn < 0)
-		temp = -temp;
-	temp += ref_clk * mfi;
-
-	return temp;
-}
-
-static int clk_pll_enable(struct clk *clk)
-{
-	void __iomem *ctl;
-	u32 reg;
-
-	ctl = pll_base(clk);
-	reg = __raw_readl(ctl);
-	reg |= (MXC_PLL_DP_CTL_RST | MXC_PLL_DP_CTL_UPEN);
-	__raw_writel(reg, ctl);
-	do {
-		reg = __raw_readl(ctl);
-	} while ((reg & MXC_PLL_DP_CTL_LRF) != MXC_PLL_DP_CTL_LRF);
-	return 0;
-}
-
-static void clk_pll_disable(struct clk *clk)
-{
-	void __iomem *ctl;
-	u32 reg;
-
-	ctl = pll_base(clk);
-	reg = __raw_readl(ctl);
-	reg &= ~(MXC_PLL_DP_CTL_RST | MXC_PLL_DP_CTL_UPEN);
-	__raw_writel(reg, ctl);
-}
-
-static struct clk mcu_pll_clk = {
-	.parent = &ckih_clk,
-	.get_rate = clk_pll_get_rate,
-	.enable = clk_pll_enable,
-	.disable = clk_pll_disable,
-};
-
-static struct clk dsp_pll_clk = {
-	.parent = &ckih_clk,
-	.get_rate = clk_pll_get_rate,
-	.enable = clk_pll_enable,
-	.disable = clk_pll_disable,
-};
-
-static struct clk usb_pll_clk = {
-	.parent = &ckih_clk,
-	.get_rate = clk_pll_get_rate,
-	.enable = clk_pll_enable,
-	.disable = clk_pll_disable,
-};
-/* plls stuff end */
-
-/* ap_ref_clk stuff */
-static struct clk ap_ref_clk;
-
-static unsigned long clk_ap_ref_get_rate(struct clk *clk)
-{
-	u32 ascsr, acsr;
-	u8 ap_pat_ref_div_2, ap_isel, acs, ads;
-
-	ascsr = __raw_readl(MXC_CRMAP_ASCSR);
-	acsr = __raw_readl(MXC_CRMAP_ACSR);
-
-	/* 0 for ckih, 1 for ckih*2 */
-	ap_isel = ascsr & MXC_CRMAP_ASCSR_APISEL;
-	/* reg divider */
-	ap_pat_ref_div_2 = (ascsr >> MXC_CRMAP_ASCSR_AP_PATDIV2_OFFSET) & 0x1;
-	/* undocumented, 1 for disabling divider */
-	ads = (acsr >> MXC_CRMAP_ACSR_ADS_OFFSET) & 0x1;
-	/* 0 for pat_ref, 1 for divider out */
-	acs = acsr & MXC_CRMAP_ACSR_ACS;
-
-	if (acs & !ads)
-		/* use divided clock */
-		return clk_get_rate(clk->parent) / (ap_pat_ref_div_2 ? 2 : 1);
-
-	return clk_get_rate(clk->parent) * (ap_isel ? 2 : 1);
-}
-
-static struct clk ap_ref_clk = {
-	.parent = &ckih_clk,
-	.get_rate = clk_ap_ref_get_rate,
-};
-/* ap_ref_clk stuff end */
-
-/* ap_pre_dfs_clk stuff */
-static struct clk ap_pre_dfs_clk;
-
-static unsigned long clk_ap_pre_dfs_get_rate(struct clk *clk)
-{
-	u32 acsr, ascsr;
-
-	acsr = __raw_readl(MXC_CRMAP_ACSR);
-	ascsr = __raw_readl(MXC_CRMAP_ASCSR);
-
-	if (acsr & MXC_CRMAP_ACSR_ACS) {
-		u8 sel;
-		sel = (ascsr & MXC_CRMAP_ASCSR_APSEL_MASK) >>
-			MXC_CRMAP_ASCSR_APSEL_OFFSET;
-		return clk_get_rate(pll_clk(sel)) /
-			CRM_SMALL_DIVIDER(MXC_CRMAP_ACDR, ARMDIV);
-	}
-	return clk_get_rate(&ap_ref_clk);
-}
-
-static struct clk ap_pre_dfs_clk = {
-	.get_rate = clk_ap_pre_dfs_get_rate,
-};
-/* ap_pre_dfs_clk stuff end */
-
-/* usb_clk stuff */
-static struct clk usb_clk;
-
-static struct clk *clk_usb_parent(struct clk *clk)
-{
-	u32 acsr, ascsr;
-
-	acsr = __raw_readl(MXC_CRMAP_ACSR);
-	ascsr = __raw_readl(MXC_CRMAP_ASCSR);
-
-	if (acsr & MXC_CRMAP_ACSR_ACS) {
-		u8 sel;
-		sel = (ascsr & MXC_CRMAP_ASCSR_USBSEL_MASK) >>
-			MXC_CRMAP_ASCSR_USBSEL_OFFSET;
-		return pll_clk(sel);
-	}
-	return &ap_ref_clk;
-}
-
-static unsigned long clk_usb_get_rate(struct clk *clk)
-{
-	return clk_get_rate(clk->parent) /
-		CRM_SMALL_DIVIDER(MXC_CRMAP_ACDER2, USBDIV);
-}
-
-static struct clk usb_clk = {
-	.enable_reg = MXC_CRMAP_ACDER2,
-	.enable_shift = MXC_CRMAP_ACDER2_USBEN_OFFSET,
-	.get_rate = clk_usb_get_rate,
-	.enable = _clk_1bit_enable,
-	.disable = _clk_1bit_disable,
-};
-/* usb_clk stuff end */
-
-static unsigned long clk_ipg_get_rate(struct clk *clk)
-{
-	return clk_get_rate(clk->parent) / CRM_16DIVIDER(MXC_CRMAP_ACDR, IPDIV);
-}
-
-static unsigned long clk_ahb_get_rate(struct clk *clk)
-{
-	return clk_get_rate(clk->parent) /
-		CRM_16DIVIDER(MXC_CRMAP_ACDR, AHBDIV);
-}
-
-static struct clk ipg_clk = {
-	.parent = &ap_pre_dfs_clk,
-	.get_rate = clk_ipg_get_rate,
-};
-
-static struct clk ahb_clk = {
-	.parent = &ap_pre_dfs_clk,
-	.get_rate = clk_ahb_get_rate,
-};
-
-/* perclk_clk stuff */
-static struct clk perclk_clk;
-
-static unsigned long clk_perclk_get_rate(struct clk *clk)
-{
-	u32 acder2;
-
-	acder2 = __raw_readl(MXC_CRMAP_ACDER2);
-	if (acder2 & MXC_CRMAP_ACDER2_BAUD_ISEL_MASK)
-		return 2 * clk_get_rate(clk->parent);
-
-	return clk_get_rate(clk->parent);
-}
-
-static struct clk perclk_clk = {
-	.parent = &ckih_clk,
-	.get_rate = clk_perclk_get_rate,
-};
-/* perclk_clk stuff end */
-
-/* uart_clk stuff */
-static struct clk uart_clk[];
-
-static unsigned long clk_uart_get_rate(struct clk *clk)
-{
-	u32 div;
-
-	switch (clk->id) {
-	case 0:
-	case 1:
-		div = CRM_SMALL_DIVIDER(MXC_CRMAP_ACDER2, BAUDDIV);
-		break;
-	case 2:
-		div = CRM_SMALL_DIVIDER(MXC_CRMAP_APRA, UART3DIV);
-		break;
-	default:
-		BUG();
-	}
-	return clk_get_rate(clk->parent) / div;
-}
-
-static struct clk uart_clk[] = {
-	{
-		.id = 0,
-		.parent = &perclk_clk,
-		.enable_reg = MXC_CRMAP_APRA,
-		.enable_shift = MXC_CRMAP_APRA_UART1EN_OFFSET,
-		.get_rate = clk_uart_get_rate,
-		.enable = _clk_1bit_enable,
-		.disable = _clk_1bit_disable,
-	}, {
-		.id = 1,
-		.parent = &perclk_clk,
-		.enable_reg = MXC_CRMAP_APRA,
-		.enable_shift = MXC_CRMAP_APRA_UART2EN_OFFSET,
-		.get_rate = clk_uart_get_rate,
-		.enable = _clk_1bit_enable,
-		.disable = _clk_1bit_disable,
-	}, {
-		.id = 2,
-		.parent = &perclk_clk,
-		.enable_reg = MXC_CRMAP_APRA,
-		.enable_shift = MXC_CRMAP_APRA_UART3EN_OFFSET,
-		.get_rate = clk_uart_get_rate,
-		.enable = _clk_1bit_enable,
-		.disable = _clk_1bit_disable,
-	},
-};
-/* uart_clk stuff end */
-
-/* sdhc_clk stuff */
-static struct clk nfc_clk;
-
-static unsigned long clk_nfc_get_rate(struct clk *clk)
-{
-	return clk_get_rate(clk->parent) /
-		CRM_1DIVIDER(MXC_CRMAP_ACDER2, NFCDIV);
-}
-
-static struct clk nfc_clk = {
-	.parent = &ahb_clk,
-	.enable_reg = MXC_CRMAP_ACDER2,
-	.enable_shift = MXC_CRMAP_ACDER2_NFCEN_OFFSET,
-	.get_rate = clk_nfc_get_rate,
-	.enable = _clk_1bit_enable,
-	.disable = _clk_1bit_disable,
-};
-/* sdhc_clk stuff end */
-
-/* sdhc_clk stuff */
-static struct clk sdhc_clk[];
-
-static struct clk *clk_sdhc_parent(struct clk *clk)
-{
-	u32 aprb;
-	u8 sel;
-	u32 mask;
-	int offset;
-
-	aprb = __raw_readl(MXC_CRMAP_APRB);
-
-	switch (clk->id) {
-	case 0:
-		mask = MXC_CRMAP_APRB_SDHC1_ISEL_MASK;
-		offset = MXC_CRMAP_APRB_SDHC1_ISEL_OFFSET;
-		break;
-	case 1:
-		mask = MXC_CRMAP_APRB_SDHC2_ISEL_MASK;
-		offset = MXC_CRMAP_APRB_SDHC2_ISEL_OFFSET;
-		break;
-	default:
-		BUG();
-	}
-	sel = (aprb & mask) >> offset;
-
-	switch (sel) {
-	case 0:
-		return &ckih_clk;
-	case 1:
-		return &ckih_x2_clk;
-	}
-	return &usb_clk;
-}
-
-static unsigned long clk_sdhc_get_rate(struct clk *clk)
-{
-	u32 div;
-
-	switch (clk->id) {
-	case 0:
-		div = CRM_SMALL_DIVIDER(MXC_CRMAP_APRB, SDHC1_DIV);
-		break;
-	case 1:
-		div = CRM_SMALL_DIVIDER(MXC_CRMAP_APRB, SDHC2_DIV);
-		break;
-	default:
-		BUG();
-	}
-
-	return clk_get_rate(clk->parent) / div;
-}
-
-static int clk_sdhc_enable(struct clk *clk)
-{
-	u32 amlpmre1, aprb;
-
-	amlpmre1 = __raw_readl(MXC_CRMAP_AMLPMRE1);
-	aprb = __raw_readl(MXC_CRMAP_APRB);
-	switch (clk->id) {
-	case 0:
-		amlpmre1 |= (0x7 << MXC_CRMAP_AMLPMRE1_MLPME4_OFFSET);
-		aprb |= (0x1 << MXC_CRMAP_APRB_SDHC1EN_OFFSET);
-		break;
-	case 1:
-		amlpmre1 |= (0x7 << MXC_CRMAP_AMLPMRE1_MLPME5_OFFSET);
-		aprb |= (0x1 << MXC_CRMAP_APRB_SDHC2EN_OFFSET);
-		break;
-	}
-	__raw_writel(amlpmre1, MXC_CRMAP_AMLPMRE1);
-	__raw_writel(aprb, MXC_CRMAP_APRB);
-	return 0;
-}
-
-static void clk_sdhc_disable(struct clk *clk)
-{
-	u32 amlpmre1, aprb;
-
-	amlpmre1 = __raw_readl(MXC_CRMAP_AMLPMRE1);
-	aprb = __raw_readl(MXC_CRMAP_APRB);
-	switch (clk->id) {
-	case 0:
-		amlpmre1 &= ~(0x7 << MXC_CRMAP_AMLPMRE1_MLPME4_OFFSET);
-		aprb &= ~(0x1 << MXC_CRMAP_APRB_SDHC1EN_OFFSET);
-		break;
-	case 1:
-		amlpmre1 &= ~(0x7 << MXC_CRMAP_AMLPMRE1_MLPME5_OFFSET);
-		aprb &= ~(0x1 << MXC_CRMAP_APRB_SDHC2EN_OFFSET);
-		break;
-	}
-	__raw_writel(amlpmre1, MXC_CRMAP_AMLPMRE1);
-	__raw_writel(aprb, MXC_CRMAP_APRB);
-}
-
-static struct clk sdhc_clk[] = {
-	{
-		.id = 0,
-		.get_rate = clk_sdhc_get_rate,
-		.enable = clk_sdhc_enable,
-		.disable = clk_sdhc_disable,
-	}, {
-		.id = 1,
-		.get_rate = clk_sdhc_get_rate,
-		.enable = clk_sdhc_enable,
-		.disable = clk_sdhc_disable,
-	},
-};
-/* sdhc_clk stuff end */
-
-/* wdog_clk stuff */
-static struct clk wdog_clk[] = {
-	{
-		.id = 0,
-		.parent = &ipg_clk,
-		.enable_reg = MXC_CRMAP_AMLPMRD,
-		.enable_shift = MXC_CRMAP_AMLPMRD_MLPMD7_OFFSET,
-		.enable = _clk_3bit_enable,
-		.disable = _clk_3bit_disable,
-	}, {
-		.id = 1,
-		.parent = &ipg_clk,
-		.enable_reg = MXC_CRMAP_AMLPMRD,
-		.enable_shift = MXC_CRMAP_AMLPMRD_MLPMD3_OFFSET,
-		.enable = _clk_3bit_enable,
-		.disable = _clk_3bit_disable,
-	},
-};
-/* wdog_clk stuff end */
-
-/* gpt_clk stuff */
-static struct clk gpt_clk = {
-	.parent = &ipg_clk,
-	.enable_reg = MXC_CRMAP_AMLPMRC,
-	.enable_shift = MXC_CRMAP_AMLPMRC_MLPMC4_OFFSET,
-	.enable = _clk_3bit_enable,
-	.disable = _clk_3bit_disable,
-};
-/* gpt_clk stuff end */
-
-/* cspi_clk stuff */
-static struct clk cspi_clk[] = {
-	{
-		.id = 0,
-		.parent = &ipg_clk,
-		.enable_reg = MXC_CRMAP_AMLPMRE2,
-		.enable_shift = MXC_CRMAP_AMLPMRE2_MLPME0_OFFSET,
-		.enable = _clk_3bit_enable,
-		.disable = _clk_3bit_disable,
-	}, {
-		.id = 1,
-		.parent = &ipg_clk,
-		.enable_reg = MXC_CRMAP_AMLPMRE1,
-		.enable_shift = MXC_CRMAP_AMLPMRE1_MLPME6_OFFSET,
-		.enable = _clk_3bit_enable,
-		.disable = _clk_3bit_disable,
-	},
-};
-/* cspi_clk stuff end */
-
-#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, uart_clk[0])
-	_REGISTER_CLOCK("imx-uart.1", NULL, uart_clk[1])
-	_REGISTER_CLOCK("imx-uart.2", NULL, uart_clk[2])
-	_REGISTER_CLOCK("mxc-mmc.0", NULL, sdhc_clk[0])
-	_REGISTER_CLOCK("mxc-mmc.1", NULL, sdhc_clk[1])
-	_REGISTER_CLOCK("mxc-wdt.0", NULL, wdog_clk[0])
-	_REGISTER_CLOCK("spi_imx.0", NULL, cspi_clk[0])
-	_REGISTER_CLOCK("spi_imx.1", NULL, cspi_clk[1])
-};
-
-int __init mxc91231_clocks_init(unsigned long fref)
-{
-	void __iomem *gpt_base;
-
-	ckih_rate = fref;
-
-	usb_clk.parent = clk_usb_parent(&usb_clk);
-	sdhc_clk[0].parent = clk_sdhc_parent(&sdhc_clk[0]);
-	sdhc_clk[1].parent = clk_sdhc_parent(&sdhc_clk[1]);
-
-	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);
-
-	return 0;
-}
diff -druN linux-2.6.39-libre/arch/arm/mach-mxc91231/crm_regs.h linux-3.0-rc7-libre/arch/arm/mach-mxc91231/crm_regs.h
--- linux-2.6.39-libre/arch/arm/mach-mxc91231/crm_regs.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-mxc91231/crm_regs.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,394 +0,0 @@
-/*
- * Copyright 2006 Freescale Semiconductor, Inc.
- * Copyright 2006-2007 Motorola, 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.
- */
-
-#ifndef _ARCH_ARM_MACH_MXC91231_CRM_REGS_H_
-#define _ARCH_ARM_MACH_MXC91231_CRM_REGS_H_
-
-#define CKIL_CLK_FREQ			32768
-
-#define MXC_CRM_AP_BASE			MXC91231_IO_ADDRESS(MXC91231_CRM_AP_BASE_ADDR)
-#define MXC_CRM_COM_BASE		MXC91231_IO_ADDRESS(MXC91231_CRM_COM_BASE_ADDR)
-#define MXC_DSM_BASE			MXC91231_IO_ADDRESS(MXC91231_DSM_BASE_ADDR)
-#define MXC_PLL0_BASE			MXC91231_IO_ADDRESS(MXC91231_PLL0_BASE_ADDR)
-#define MXC_PLL1_BASE			MXC91231_IO_ADDRESS(MXC91231_PLL1_BASE_ADDR)
-#define MXC_PLL2_BASE			MXC91231_IO_ADDRESS(MXC91231_PLL2_BASE_ADDR)
-#define MXC_CLKCTL_BASE			MXC91231_IO_ADDRESS(MXC91231_CLKCTL_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_HFS_OP		0x1C
-#define MXC_PLL_DP_HFS_MFD		0x20
-#define MXC_PLL_DP_HFS_MFN		0x24
-
-/* PLL Register Bit definitions */
-#define MXC_PLL_DP_CTL_DPDCK0_2_EN	0x1000
-#define MXC_PLL_DP_CTL_ADE		0x800
-#define MXC_PLL_DP_CTL_REF_CLK_DIV	0x400
-#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_OP_MFI_OFFSET	4
-#define MXC_PLL_DP_OP_MFI_MASK		0xF
-#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		0x7FFFFFF
-
-#define MXC_PLL_DP_MFN_OFFSET		0
-#define MXC_PLL_DP_MFN_MASK		0x7FFFFFF
-
-/* CRM AP Register Offsets */
-#define MXC_CRMAP_ASCSR			(MXC_CRM_AP_BASE + 0x00)
-#define MXC_CRMAP_ACDR			(MXC_CRM_AP_BASE + 0x04)
-#define MXC_CRMAP_ACDER1		(MXC_CRM_AP_BASE + 0x08)
-#define MXC_CRMAP_ACDER2		(MXC_CRM_AP_BASE + 0x0C)
-#define MXC_CRMAP_ACGCR			(MXC_CRM_AP_BASE + 0x10)
-#define MXC_CRMAP_ACCGCR		(MXC_CRM_AP_BASE + 0x14)
-#define MXC_CRMAP_AMLPMRA		(MXC_CRM_AP_BASE + 0x18)
-#define MXC_CRMAP_AMLPMRB		(MXC_CRM_AP_BASE + 0x1C)
-#define MXC_CRMAP_AMLPMRC		(MXC_CRM_AP_BASE + 0x20)
-#define MXC_CRMAP_AMLPMRD		(MXC_CRM_AP_BASE + 0x24)
-#define MXC_CRMAP_AMLPMRE1		(MXC_CRM_AP_BASE + 0x28)
-#define MXC_CRMAP_AMLPMRE2		(MXC_CRM_AP_BASE + 0x2C)
-#define MXC_CRMAP_AMLPMRF		(MXC_CRM_AP_BASE + 0x30)
-#define MXC_CRMAP_AMLPMRG		(MXC_CRM_AP_BASE + 0x34)
-#define MXC_CRMAP_APGCR			(MXC_CRM_AP_BASE + 0x38)
-#define MXC_CRMAP_ACSR			(MXC_CRM_AP_BASE + 0x3C)
-#define MXC_CRMAP_ADCR			(MXC_CRM_AP_BASE + 0x40)
-#define MXC_CRMAP_ACR			(MXC_CRM_AP_BASE + 0x44)
-#define MXC_CRMAP_AMCR			(MXC_CRM_AP_BASE + 0x48)
-#define MXC_CRMAP_APCR			(MXC_CRM_AP_BASE + 0x4C)
-#define MXC_CRMAP_AMORA			(MXC_CRM_AP_BASE + 0x50)
-#define MXC_CRMAP_AMORB			(MXC_CRM_AP_BASE + 0x54)
-#define MXC_CRMAP_AGPR			(MXC_CRM_AP_BASE + 0x58)
-#define MXC_CRMAP_APRA			(MXC_CRM_AP_BASE + 0x5C)
-#define MXC_CRMAP_APRB			(MXC_CRM_AP_BASE + 0x60)
-#define MXC_CRMAP_APOR			(MXC_CRM_AP_BASE + 0x64)
-#define MXC_CRMAP_ADFMR			(MXC_CRM_AP_BASE + 0x68)
-
-/* CRM AP Register Bit definitions */
-#define MXC_CRMAP_ASCSR_CRS			0x10000
-#define MXC_CRMAP_ASCSR_AP_PATDIV2_OFFSET	15
-#define MXC_CRMAP_ASCSR_AP_PATREF_DIV2		0x8000
-#define MXC_CRMAP_ASCSR_USBSEL_OFFSET		13
-#define MXC_CRMAP_ASCSR_USBSEL_MASK		(0x3 << 13)
-#define MXC_CRMAP_ASCSR_CSISEL_OFFSET		11
-#define MXC_CRMAP_ASCSR_CSISEL_MASK		(0x3 << 11)
-#define MXC_CRMAP_ASCSR_SSI2SEL_OFFSET		7
-#define MXC_CRMAP_ASCSR_SSI2SEL_MASK		(0x3 << 7)
-#define MXC_CRMAP_ASCSR_SSI1SEL_OFFSET		5
-#define MXC_CRMAP_ASCSR_SSI1SEL_MASK		(0x3 << 5)
-#define MXC_CRMAP_ASCSR_APSEL_OFFSET		3
-#define MXC_CRMAP_ASCSR_APSEL_MASK		(0x3 << 3)
-#define MXC_CRMAP_ASCSR_AP_PATDIV1_OFFSET	2
-#define MXC_CRMAP_ASCSR_AP_PATREF_DIV1		0x4
-#define MXC_CRMAP_ASCSR_APISEL			0x1
-
-#define MXC_CRMAP_ACDR_ARMDIV_OFFSET		8
-#define MXC_CRMAP_ACDR_ARMDIV_MASK		(0xF << 8)
-#define MXC_CRMAP_ACDR_AHBDIV_OFFSET		4
-#define MXC_CRMAP_ACDR_AHBDIV_MASK		(0xF << 4)
-#define MXC_CRMAP_ACDR_IPDIV_OFFSET		0
-#define MXC_CRMAP_ACDR_IPDIV_MASK		0xF
-
-#define MXC_CRMAP_ACDER1_CSIEN_OFFSET		30
-#define MXC_CRMAP_ACDER1_CSIDIV_OFFSET		24
-#define MXC_CRMAP_ACDER1_CSIDIV_MASK		(0x3F << 24)
-#define MXC_CRMAP_ACDER1_SSI2EN_OFFSET		14
-#define MXC_CRMAP_ACDER1_SSI2DIV_OFFSET		8
-#define MXC_CRMAP_ACDER1_SSI2DIV_MASK		(0x3F << 8)
-#define MXC_CRMAP_ACDER1_SSI1EN_OFFSET		6
-#define MXC_CRMAP_ACDER1_SSI1DIV_OFFSET		0
-#define MXC_CRMAP_ACDER1_SSI1DIV_MASK		0x3F
-
-#define MXC_CRMAP_ACDER2_CRCT_CLK_DIV_OFFSET	24
-#define MXC_CRMAP_ACDER2_CRCT_CLK_DIV_MASK	(0x7 << 24)
-#define MXC_CRMAP_ACDER2_NFCEN_OFFSET		20
-#define MXC_CRMAP_ACDER2_NFCDIV_OFFSET		16
-#define MXC_CRMAP_ACDER2_NFCDIV_MASK		(0xF << 16)
-#define MXC_CRMAP_ACDER2_USBEN_OFFSET		12
-#define MXC_CRMAP_ACDER2_USBDIV_OFFSET		8
-#define MXC_CRMAP_ACDER2_USBDIV_MASK		(0xF << 8)
-#define MXC_CRMAP_ACDER2_BAUD_ISEL_OFFSET	5
-#define MXC_CRMAP_ACDER2_BAUD_ISEL_MASK		(0x3 << 5)
-#define MXC_CRMAP_ACDER2_BAUDDIV_OFFSET		0
-#define MXC_CRMAP_ACDER2_BAUDDIV_MASK		0xF
-
-#define MXC_CRMAP_AMLPMRA_MLPMA7_OFFSET		22
-#define MXC_CRMAP_AMLPMRA_MLPMA7_MASK		(0x7 << 22)
-#define MXC_CRMAP_AMLPMRA_MLPMA6_OFFSET		19
-#define MXC_CRMAP_AMLPMRA_MLPMA6_MASK		(0x7 << 19)
-#define MXC_CRMAP_AMLPMRA_MLPMA4_OFFSET		12
-#define MXC_CRMAP_AMLPMRA_MLPMA4_MASK		(0x7 << 12)
-#define MXC_CRMAP_AMLPMRA_MLPMA3_OFFSET		9
-#define MXC_CRMAP_AMLPMRA_MLPMA3_MASK		(0x7 << 9)
-#define MXC_CRMAP_AMLPMRA_MLPMA2_OFFSET		6
-#define MXC_CRMAP_AMLPMRA_MLPMA2_MASK		(0x7 << 6)
-#define MXC_CRMAP_AMLPMRA_MLPMA1_OFFSET		3
-#define MXC_CRMAP_AMLPMRA_MLPMA1_MASK		(0x7 << 3)
-
-#define MXC_CRMAP_AMLPMRB_MLPMB0_OFFSET		0
-#define MXC_CRMAP_AMLPMRB_MLPMB0_MASK		0x7
-
-#define MXC_CRMAP_AMLPMRC_MLPMC9_OFFSET		28
-#define MXC_CRMAP_AMLPMRC_MLPMC9_MASK		(0x7 << 28)
-#define MXC_CRMAP_AMLPMRC_MLPMC7_OFFSET		22
-#define MXC_CRMAP_AMLPMRC_MLPMC7_MASK		(0x7 << 22)
-#define MXC_CRMAP_AMLPMRC_MLPMC5_OFFSET		16
-#define MXC_CRMAP_AMLPMRC_MLPMC5_MASK		(0x7 << 16)
-#define MXC_CRMAP_AMLPMRC_MLPMC4_OFFSET		12
-#define MXC_CRMAP_AMLPMRC_MLPMC4_MASK		(0x7 << 12)
-#define MXC_CRMAP_AMLPMRC_MLPMC3_OFFSET		9
-#define MXC_CRMAP_AMLPMRC_MLPMC3_MASK		(0x7 << 9)
-#define MXC_CRMAP_AMLPMRC_MLPMC2_OFFSET		6
-#define MXC_CRMAP_AMLPMRC_MLPMC2_MASK		(0x7 << 6)
-#define MXC_CRMAP_AMLPMRC_MLPMC1_OFFSET		3
-#define MXC_CRMAP_AMLPMRC_MLPMC1_MASK		(0x7 << 3)
-#define MXC_CRMAP_AMLPMRC_MLPMC0_OFFSET		0
-#define MXC_CRMAP_AMLPMRC_MLPMC0_MASK		0x7
-
-#define MXC_CRMAP_AMLPMRD_MLPMD7_OFFSET		22
-#define MXC_CRMAP_AMLPMRD_MLPMD7_MASK		(0x7 << 22)
-#define MXC_CRMAP_AMLPMRD_MLPMD4_OFFSET		12
-#define MXC_CRMAP_AMLPMRD_MLPMD4_MASK		(0x7 << 12)
-#define MXC_CRMAP_AMLPMRD_MLPMD3_OFFSET		9
-#define MXC_CRMAP_AMLPMRD_MLPMD3_MASK		(0x7 << 9)
-#define MXC_CRMAP_AMLPMRD_MLPMD2_OFFSET		6
-#define MXC_CRMAP_AMLPMRD_MLPMD2_MASK		(0x7 << 6)
-#define MXC_CRMAP_AMLPMRD_MLPMD0_OFFSET		0
-#define MXC_CRMAP_AMLPMRD_MLPMD0_MASK		0x7
-
-#define MXC_CRMAP_AMLPMRE1_MLPME9_OFFSET	28
-#define MXC_CRMAP_AMLPMRE1_MLPME9_MASK		(0x7 << 28)
-#define MXC_CRMAP_AMLPMRE1_MLPME8_OFFSET	25
-#define MXC_CRMAP_AMLPMRE1_MLPME8_MASK		(0x7 << 25)
-#define MXC_CRMAP_AMLPMRE1_MLPME7_OFFSET	22
-#define MXC_CRMAP_AMLPMRE1_MLPME7_MASK		(0x7 << 22)
-#define MXC_CRMAP_AMLPMRE1_MLPME6_OFFSET	19
-#define MXC_CRMAP_AMLPMRE1_MLPME6_MASK		(0x7 << 19)
-#define MXC_CRMAP_AMLPMRE1_MLPME5_OFFSET	16
-#define MXC_CRMAP_AMLPMRE1_MLPME5_MASK		(0x7 << 16)
-#define MXC_CRMAP_AMLPMRE1_MLPME4_OFFSET	12
-#define MXC_CRMAP_AMLPMRE1_MLPME4_MASK		(0x7 << 12)
-#define MXC_CRMAP_AMLPMRE1_MLPME3_OFFSET	9
-#define MXC_CRMAP_AMLPMRE1_MLPME3_MASK		(0x7 << 9)
-#define MXC_CRMAP_AMLPMRE1_MLPME2_OFFSET	6
-#define MXC_CRMAP_AMLPMRE1_MLPME2_MASK		(0x7 << 6)
-#define MXC_CRMAP_AMLPMRE1_MLPME1_OFFSET	3
-#define MXC_CRMAP_AMLPMRE1_MLPME1_MASK		(0x7 << 3)
-#define MXC_CRMAP_AMLPMRE1_MLPME0_OFFSET	0
-#define MXC_CRMAP_AMLPMRE1_MLPME0_MASK		0x7
-
-#define MXC_CRMAP_AMLPMRE2_MLPME0_OFFSET	0
-#define MXC_CRMAP_AMLPMRE2_MLPME0_MASK		0x7
-
-#define MXC_CRMAP_AMLPMRF_MLPMF6_OFFSET		19
-#define MXC_CRMAP_AMLPMRF_MLPMF6_MASK		(0x7 << 19)
-#define MXC_CRMAP_AMLPMRF_MLPMF5_OFFSET		16
-#define MXC_CRMAP_AMLPMRF_MLPMF5_MASK		(0x7 << 16)
-#define MXC_CRMAP_AMLPMRF_MLPMF3_OFFSET		9
-#define MXC_CRMAP_AMLPMRF_MLPMF3_MASK		(0x7 << 9)
-#define MXC_CRMAP_AMLPMRF_MLPMF2_OFFSET		6
-#define MXC_CRMAP_AMLPMRF_MLPMF2_MASK		(0x7 << 6)
-#define MXC_CRMAP_AMLPMRF_MLPMF1_OFFSET		3
-#define MXC_CRMAP_AMLPMRF_MLPMF1_MASK		(0x7 << 3)
-#define MXC_CRMAP_AMLPMRF_MLPMF0_OFFSET		0
-#define MXC_CRMAP_AMLPMRF_MLPMF0_MASK		(0x7 << 0)
-
-#define MXC_CRMAP_AMLPMRG_MLPMG9_OFFSET		28
-#define MXC_CRMAP_AMLPMRG_MLPMG9_MASK		(0x7 << 28)
-#define MXC_CRMAP_AMLPMRG_MLPMG7_OFFSET		22
-#define MXC_CRMAP_AMLPMRG_MLPMG7_MASK		(0x7 << 22)
-#define MXC_CRMAP_AMLPMRG_MLPMG6_OFFSET		19
-#define MXC_CRMAP_AMLPMRG_MLPMG6_MASK		(0x7 << 19)
-#define MXC_CRMAP_AMLPMRG_MLPMG5_OFFSET		16
-#define MXC_CRMAP_AMLPMRG_MLPMG5_MASK		(0x7 << 16)
-#define MXC_CRMAP_AMLPMRG_MLPMG4_OFFSET		12
-#define MXC_CRMAP_AMLPMRG_MLPMG4_MASK		(0x7 << 12)
-#define MXC_CRMAP_AMLPMRG_MLPMG3_OFFSET		9
-#define MXC_CRMAP_AMLPMRG_MLPMG3_MASK		(0x7 << 9)
-#define MXC_CRMAP_AMLPMRG_MLPMG2_OFFSET		6
-#define MXC_CRMAP_AMLPMRG_MLPMG2_MASK		(0x7 << 6)
-#define MXC_CRMAP_AMLPMRG_MLPMG1_OFFSET		3
-#define MXC_CRMAP_AMLPMRG_MLPMG1_MASK		(0x7 << 3)
-#define MXC_CRMAP_AMLPMRG_MLPMG0_OFFSET		0
-#define MXC_CRMAP_AMLPMRG_MLPMG0_MASK		0x7
-
-#define MXC_CRMAP_AGPR_IPUPAD_OFFSET		20
-#define MXC_CRMAP_AGPR_IPUPAD_MASK		(0x7 << 20)
-
-#define MXC_CRMAP_APRA_EL1TEN_OFFSET		29
-#define MXC_CRMAP_APRA_SIMEN_OFFSET		24
-#define MXC_CRMAP_APRA_UART3DIV_OFFSET		17
-#define MXC_CRMAP_APRA_UART3DIV_MASK		(0xF << 17)
-#define MXC_CRMAP_APRA_UART3EN_OFFSET		16
-#define MXC_CRMAP_APRA_SAHARA_DIV2_CLKEN_OFFSET	14
-#define MXC_CRMAP_APRA_MQSPIEN_OFFSET		13
-#define MXC_CRMAP_APRA_UART2EN_OFFSET		8
-#define MXC_CRMAP_APRA_UART1EN_OFFSET		0
-
-#define MXC_CRMAP_APRB_SDHC2_ISEL_OFFSET	13
-#define MXC_CRMAP_APRB_SDHC2_ISEL_MASK		(0x7 << 13)
-#define MXC_CRMAP_APRB_SDHC2_DIV_OFFSET		9
-#define MXC_CRMAP_APRB_SDHC2_DIV_MASK		(0xF << 9)
-#define MXC_CRMAP_APRB_SDHC2EN_OFFSET		8
-#define MXC_CRMAP_APRB_SDHC1_ISEL_OFFSET	5
-#define MXC_CRMAP_APRB_SDHC1_ISEL_MASK		(0x7 << 5)
-#define MXC_CRMAP_APRB_SDHC1_DIV_OFFSET		1
-#define MXC_CRMAP_APRB_SDHC1_DIV_MASK		(0xF << 1)
-#define MXC_CRMAP_APRB_SDHC1EN_OFFSET		0
-
-#define MXC_CRMAP_ACSR_ADS_OFFSET		8
-#define MXC_CRMAP_ACSR_ADS			(0x1 << 8)
-#define MXC_CRMAP_ACSR_ACS			0x1
-
-#define MXC_CRMAP_ADCR_LFDF_0			(0x0 << 8)
-#define MXC_CRMAP_ADCR_LFDF_2			(0x1 << 8)
-#define MXC_CRMAP_ADCR_LFDF_4			(0x2 << 8)
-#define MXC_CRMAP_ADCR_LFDF_8			(0x3 << 8)
-#define MXC_CRMAP_ADCR_LFDF_OFFSET		8
-#define MXC_CRMAP_ADCR_LFDF_MASK		(0x3 << 8)
-#define MXC_CRMAP_ADCR_ALT_PLL			0x80
-#define MXC_CRMAP_ADCR_DFS_DIVEN		0x20
-#define MXC_CRMAP_ADCR_DIV_BYP			0x2
-#define MXC_CRMAP_ADCR_VSTAT			0x8
-#define MXC_CRMAP_ADCR_TSTAT			0x10
-#define MXC_CRMAP_ADCR_DVFS_VCTRL		0x10
-#define MXC_CRMAP_ADCR_CLK_ON			0x40
-
-#define MXC_CRMAP_ADFMR_FC_OFFSET		16
-#define MXC_CRMAP_ADFMR_FC_MASK			(0x1F << 16)
-#define MXC_CRMAP_ADFMR_MF_OFFSET		1
-#define MXC_CRMAP_ADFMR_MF_MASK			(0x3FF << 1)
-#define MXC_CRMAP_ADFMR_DFM_CLK_READY		0x1
-#define MXC_CRMAP_ADFMR_DFM_PWR_DOWN		0x8000
-
-#define MXC_CRMAP_ACR_CKOHS_HIGH		(1 << 18)
-#define MXC_CRMAP_ACR_CKOS_HIGH			(1 << 16)
-#define MXC_CRMAP_ACR_CKOHS_MASK		(0x7 << 12)
-#define MXC_CRMAP_ACR_CKOHD			(1 << 11)
-#define MXC_CRMAP_ACR_CKOHDIV_MASK		(0xF << 8)
-#define MXC_CRMAP_ACR_CKOHDIV_OFFSET		8
-#define MXC_CRMAP_ACR_CKOD			(1 << 7)
-#define MXC_CRMAP_ACR_CKOS_MASK			(0x7 << 4)
-
-/* AP Warm reset */
-#define MXC_CRMAP_AMCR_SW_AP			(1 << 14)
-
-/* Bit definitions of ACGCR in CRM_AP for tree level clock gating */
-#define MXC_CRMAP_ACGCR_ACG0_STOP_WAIT		0x00000001
-#define MXC_CRMAP_ACGCR_ACG0_STOP		0x00000003
-#define MXC_CRMAP_ACGCR_ACG0_RUN		0x00000007
-#define MXC_CRMAP_ACGCR_ACG0_DISABLED		0x00000000
-
-#define MXC_CRMAP_ACGCR_ACG1_STOP_WAIT		0x00000008
-#define MXC_CRMAP_ACGCR_ACG1_STOP		0x00000018
-#define MXC_CRMAP_ACGCR_ACG1_RUN		0x00000038
-#define MXC_CRMAP_ACGCR_ACG1_DISABLED		0x00000000
-
-#define MXC_CRMAP_ACGCR_ACG2_STOP_WAIT		0x00000040
-#define MXC_CRMAP_ACGCR_ACG2_STOP		0x000000C0
-#define MXC_CRMAP_ACGCR_ACG2_RUN		0x000001C0
-#define MXC_CRMAP_ACGCR_ACG2_DISABLED		0x00000000
-
-#define MXC_CRMAP_ACGCR_ACG3_STOP_WAIT		0x00000200
-#define MXC_CRMAP_ACGCR_ACG3_STOP		0x00000600
-#define MXC_CRMAP_ACGCR_ACG3_RUN		0x00000E00
-#define MXC_CRMAP_ACGCR_ACG3_DISABLED		0x00000000
-
-#define MXC_CRMAP_ACGCR_ACG4_STOP_WAIT		0x00001000
-#define MXC_CRMAP_ACGCR_ACG4_STOP		0x00003000
-#define MXC_CRMAP_ACGCR_ACG4_RUN		0x00007000
-#define MXC_CRMAP_ACGCR_ACG4_DISABLED		0x00000000
-
-#define MXC_CRMAP_ACGCR_ACG5_STOP_WAIT		0x00010000
-#define MXC_CRMAP_ACGCR_ACG5_STOP		0x00030000
-#define MXC_CRMAP_ACGCR_ACG5_RUN		0x00070000
-#define MXC_CRMAP_ACGCR_ACG5_DISABLED		0x00000000
-
-#define MXC_CRMAP_ACGCR_ACG6_STOP_WAIT		0x00080000
-#define MXC_CRMAP_ACGCR_ACG6_STOP		0x00180000
-#define MXC_CRMAP_ACGCR_ACG6_RUN		0x00380000
-#define MXC_CRMAP_ACGCR_ACG6_DISABLED		0x00000000
-
-#define NUM_GATE_CTRL				6
-
-/* CRM COM Register Offsets */
-#define MXC_CRMCOM_CSCR				(MXC_CRM_COM_BASE + 0x0C)
-#define MXC_CRMCOM_CCCR				(MXC_CRM_COM_BASE + 0x10)
-
-/* CRM COM Bit Definitions */
-#define MXC_CRMCOM_CSCR_PPD1			0x08000000
-#define MXC_CRMCOM_CSCR_CKOHSEL			(1 << 18)
-#define MXC_CRMCOM_CSCR_CKOSEL			(1 << 17)
-#define MXC_CRMCOM_CCCR_CC_DIV_OFFSET		8
-#define MXC_CRMCOM_CCCR_CC_DIV_MASK		(0x1F << 8)
-#define MXC_CRMCOM_CCCR_CC_SEL_OFFSET		0
-#define MXC_CRMCOM_CCCR_CC_SEL_MASK		0x3
-
-/* DSM Register Offsets */
-#define MXC_DSM_SLEEP_TIME			(MXC_DSM_BASE + 0x0c)
-#define MXC_DSM_CONTROL0			(MXC_DSM_BASE + 0x20)
-#define MXC_DSM_CONTROL1			(MXC_DSM_BASE + 0x24)
-#define MXC_DSM_CTREN				(MXC_DSM_BASE + 0x28)
-#define MXC_DSM_WARM_PER			(MXC_DSM_BASE + 0x40)
-#define MXC_DSM_LOCK_PER			(MXC_DSM_BASE + 0x44)
-#define MXC_DSM_MGPER				(MXC_DSM_BASE + 0x4c)
-#define MXC_DSM_CRM_CONTROL			(MXC_DSM_BASE + 0x50)
-
-/* Bit definitions of various registers in DSM */
-#define MXC_DSM_CRM_CTRL_DVFS_BYP		0x00000008
-#define MXC_DSM_CRM_CTRL_DVFS_VCTRL		0x00000004
-#define MXC_DSM_CRM_CTRL_LPMD1			0x00000002
-#define MXC_DSM_CRM_CTRL_LPMD0			0x00000001
-#define MXC_DSM_CRM_CTRL_LPMD_STOP_MODE		0x00000000
-#define MXC_DSM_CRM_CTRL_LPMD_WAIT_MODE		0x00000001
-#define MXC_DSM_CRM_CTRL_LPMD_RUN_MODE		0x00000003
-#define MXC_DSM_CONTROL0_STBY_COMMIT_EN		0x00000200
-#define MXC_DSM_CONTROL0_MSTR_EN		0x00000001
-#define MXC_DSM_CONTROL0_RESTART		0x00000010
-/* Counter Block reset */
-#define MXC_DSM_CONTROL1_CB_RST			0x00000002
-/* State Machine reset */
-#define MXC_DSM_CONTROL1_SM_RST			0x00000004
-/* Bit needed to reset counter block */
-#define MXC_CONTROL1_RST_CNT32			0x00000008
-#define MXC_DSM_CONTROL1_RST_CNT32_EN		0x00000800
-#define MXC_DSM_CONTROL1_SLEEP			0x00000100
-#define MXC_DSM_CONTROL1_WAKEUP_DISABLE		0x00004000
-#define MXC_DSM_CTREN_CNT32			0x00000001
-
-/* Magic Fix enable bit */
-#define MXC_DSM_MGPER_EN_MGFX			0x80000000
-#define MXC_DSM_MGPER_PER_MASK			0x000003FF
-#define MXC_DSM_MGPER_PER(n)			(MXC_DSM_MGPER_PER_MASK & n)
-
-/* Address offsets of the CLKCTL registers */
-#define MXC_CLKCTL_GP_CTRL	(MXC_CLKCTL_BASE + 0x00)
-#define MXC_CLKCTL_GP_SER	(MXC_CLKCTL_BASE + 0x04)
-#define MXC_CLKCTL_GP_CER	(MXC_CLKCTL_BASE + 0x08)
-
-#endif /* _ARCH_ARM_MACH_MXC91231_CRM_REGS_H_ */
diff -druN linux-2.6.39-libre/arch/arm/mach-mxc91231/devices.c linux-3.0-rc7-libre/arch/arm/mach-mxc91231/devices.c
--- linux-2.6.39-libre/arch/arm/mach-mxc91231/devices.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-mxc91231/devices.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,251 +0,0 @@
-/*
- * Copyright 2006-2007 Freescale Semiconductor, Inc. All Rights Reserved.
- * Copyright 2008 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/platform_device.h>
-#include <linux/serial.h>
-#include <linux/gpio.h>
-#include <mach/hardware.h>
-#include <mach/irqs.h>
-#include <mach/imx-uart.h>
-
-static struct resource uart0[] = {
-	{
-		.start = MXC91231_UART1_BASE_ADDR,
-		.end = MXC91231_UART1_BASE_ADDR + 0x0B5,
-		.flags = IORESOURCE_MEM,
-	}, {
-		.start = MXC91231_INT_UART1_RX,
-		.end = MXC91231_INT_UART1_RX,
-		.flags = IORESOURCE_IRQ,
-	}, {
-		.start = MXC91231_INT_UART1_TX,
-		.end = MXC91231_INT_UART1_TX,
-		.flags = IORESOURCE_IRQ,
-	}, {
-		.start = MXC91231_INT_UART1_MINT,
-		.end = MXC91231_INT_UART1_MINT,
-		.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 = MXC91231_UART2_BASE_ADDR,
-		.end = MXC91231_UART2_BASE_ADDR + 0x0B5,
-		.flags = IORESOURCE_MEM,
-	}, {
-		.start = MXC91231_INT_UART2_RX,
-		.end = MXC91231_INT_UART2_RX,
-		.flags = IORESOURCE_IRQ,
-	}, {
-		.start = MXC91231_INT_UART2_TX,
-		.end = MXC91231_INT_UART2_TX,
-		.flags = IORESOURCE_IRQ,
-	}, {
-		.start = MXC91231_INT_UART2_MINT,
-		.end = MXC91231_INT_UART2_MINT,
-		.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 = MXC91231_UART3_BASE_ADDR,
-		.end = MXC91231_UART3_BASE_ADDR + 0x0B5,
-		.flags = IORESOURCE_MEM,
-	}, {
-		.start = MXC91231_INT_UART3_RX,
-		.end = MXC91231_INT_UART3_RX,
-		.flags = IORESOURCE_IRQ,
-	}, {
-		.start = MXC91231_INT_UART3_TX,
-		.end = MXC91231_INT_UART3_TX,
-		.flags = IORESOURCE_IRQ,
-	}, {
-		.start = MXC91231_INT_UART3_MINT,
-		.end = MXC91231_INT_UART3_MINT,
-		.flags = IORESOURCE_IRQ,
-
-	},
-};
-
-struct platform_device mxc_uart_device2 = {
-	.name = "imx-uart",
-	.id = 2,
-	.resource = uart2,
-	.num_resources = ARRAY_SIZE(uart2),
-};
-
-/* GPIO port description */
-static struct mxc_gpio_port mxc_gpio_ports[] = {
-	[0] = {
-		.chip.label = "gpio-0",
-		.base = MXC91231_IO_ADDRESS(MXC91231_GPIO1_AP_BASE_ADDR),
-		.irq = MXC91231_INT_GPIO1,
-		.virtual_irq_start = MXC_GPIO_IRQ_START,
-	},
-	[1] = {
-		.chip.label = "gpio-1",
-		.base = MXC91231_IO_ADDRESS(MXC91231_GPIO2_AP_BASE_ADDR),
-		.irq = MXC91231_INT_GPIO2,
-		.virtual_irq_start = MXC_GPIO_IRQ_START + 32,
-	},
-	[2] = {
-		.chip.label = "gpio-2",
-		.base = MXC91231_IO_ADDRESS(MXC91231_GPIO3_AP_BASE_ADDR),
-		.irq = MXC91231_INT_GPIO3,
-		.virtual_irq_start = MXC_GPIO_IRQ_START + 64,
-	},
-	[3] = {
-		.chip.label = "gpio-3",
-		.base = MXC91231_IO_ADDRESS(MXC91231_GPIO4_SH_BASE_ADDR),
-		.irq = MXC91231_INT_GPIO4,
-		.virtual_irq_start = MXC_GPIO_IRQ_START + 96,
-	},
-};
-
-int __init mxc91231_register_gpios(void)
-{
-	return mxc_gpio_init(mxc_gpio_ports, ARRAY_SIZE(mxc_gpio_ports));
-}
-
-static struct resource mxc_nand_resources[] = {
-	{
-		.start	= MXC91231_NFC_BASE_ADDR,
-		.end	= MXC91231_NFC_BASE_ADDR + 0xfff,
-		.flags	= IORESOURCE_MEM
-	}, {
-		.start	= MXC91231_INT_NANDFC,
-		.end	= MXC91231_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 mxc_sdhc0_resources[] = {
-	{
-		.start = MXC91231_MMC_SDHC1_BASE_ADDR,
-		.end = MXC91231_MMC_SDHC1_BASE_ADDR + SZ_16K - 1,
-		.flags = IORESOURCE_MEM,
-	}, {
-		.start = MXC91231_INT_MMC_SDHC1,
-		.end = MXC91231_INT_MMC_SDHC1,
-		.flags = IORESOURCE_IRQ,
-	},
-};
-
-static struct resource mxc_sdhc1_resources[] = {
-	{
-		.start = MXC91231_MMC_SDHC2_BASE_ADDR,
-		.end = MXC91231_MMC_SDHC2_BASE_ADDR + SZ_16K - 1,
-		.flags = IORESOURCE_MEM,
-	}, {
-		.start = MXC91231_INT_MMC_SDHC2,
-		.end = MXC91231_INT_MMC_SDHC2,
-		.flags = IORESOURCE_IRQ,
-	},
-};
-
-struct platform_device mxc_sdhc_device0 = {
-	.name = "mxc-mmc",
-	.id = 0,
-	.num_resources = ARRAY_SIZE(mxc_sdhc0_resources),
-	.resource = mxc_sdhc0_resources,
-};
-
-struct platform_device mxc_sdhc_device1 = {
-	.name = "mxc-mmc",
-	.id = 1,
-	.num_resources = ARRAY_SIZE(mxc_sdhc1_resources),
-	.resource = mxc_sdhc1_resources,
-};
-
-static struct resource mxc_cspi0_resources[] = {
-	{
-		.start = MXC91231_CSPI1_BASE_ADDR,
-		.end = MXC91231_CSPI1_BASE_ADDR + 0x20,
-		.flags = IORESOURCE_MEM,
-	}, {
-		.start = MXC91231_INT_CSPI1,
-		.end = MXC91231_INT_CSPI1,
-		.flags = IORESOURCE_IRQ,
-	},
-};
-
-struct platform_device mxc_cspi_device0 = {
-	.name = "spi_imx",
-	.id = 0,
-	.num_resources = ARRAY_SIZE(mxc_cspi0_resources),
-	.resource = mxc_cspi0_resources,
-};
-
-static struct resource mxc_cspi1_resources[] = {
-	{
-		.start = MXC91231_CSPI2_BASE_ADDR,
-		.end = MXC91231_CSPI2_BASE_ADDR + 0x20,
-		.flags = IORESOURCE_MEM,
-	}, {
-		.start = MXC91231_INT_CSPI2,
-		.end = MXC91231_INT_CSPI2,
-		.flags = IORESOURCE_IRQ,
-	},
-};
-
-struct platform_device mxc_cspi_device1 = {
-	.name = "spi_imx",
-	.id = 1,
-	.num_resources = ARRAY_SIZE(mxc_cspi1_resources),
-	.resource = mxc_cspi1_resources,
-};
-
-static struct resource mxc_wdog0_resources[] = {
-	{
-		.start = MXC91231_WDOG1_BASE_ADDR,
-		.end = MXC91231_WDOG1_BASE_ADDR + 0x10,
-		.flags = IORESOURCE_MEM,
-	},
-};
-
-struct platform_device mxc_wdog_device0 = {
-	.name = "mxc-wdt",
-	.id = 0,
-	.num_resources = ARRAY_SIZE(mxc_wdog0_resources),
-	.resource = mxc_wdog0_resources,
-};
diff -druN linux-2.6.39-libre/arch/arm/mach-mxc91231/devices.h linux-3.0-rc7-libre/arch/arm/mach-mxc91231/devices.h
--- linux-2.6.39-libre/arch/arm/mach-mxc91231/devices.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-mxc91231/devices.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,13 +0,0 @@
-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_nand_device;
-
-extern struct platform_device mxc_sdhc_device0;
-extern struct platform_device mxc_sdhc_device1;
-
-extern struct platform_device mxc_cspi_device0;
-extern struct platform_device mxc_cspi_device1;
-
-extern struct platform_device mxc_wdog_device0;
diff -druN linux-2.6.39-libre/arch/arm/mach-mxc91231/iomux.c linux-3.0-rc7-libre/arch/arm/mach-mxc91231/iomux.c
--- linux-2.6.39-libre/arch/arm/mach-mxc91231/iomux.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-mxc91231/iomux.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,177 +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-mxc91231.h>
-
-/*
- * IOMUX register (base) addresses
- */
-#define IOMUX_AP_BASE		MXC91231_IO_ADDRESS(MXC91231_IOMUX_AP_BASE_ADDR)
-#define IOMUX_COM_BASE		MXC91231_IO_ADDRESS(MXC91231_IOMUX_COM_BASE_ADDR)
-#define IOMUXSW_AP_MUX_CTL	(IOMUX_AP_BASE + 0x000)
-#define IOMUXSW_SP_MUX_CTL	(IOMUX_COM_BASE + 0x000)
-#define IOMUXSW_PAD_CTL		(IOMUX_COM_BASE + 0x200)
-
-#define IOMUXINT_OBS1		(IOMUX_AP_BASE + 0x600)
-#define IOMUXINT_OBS2		(IOMUX_AP_BASE + 0x004)
-
-static DEFINE_SPINLOCK(gpio_mux_lock);
-
-#define NB_PORTS			((PIN_MAX + 32) / 32)
-#define PIN_GLOBAL_NUM(pin) \
-	(((pin & MUX_SIDE_MASK) >> MUX_SIDE_SHIFT)*PIN_AP_MAX +	\
-	 ((pin & MUX_REG_MASK) >> MUX_REG_SHIFT)*4 +		\
-	 ((pin & MUX_FIELD_MASK) >> MUX_FIELD_SHIFT))
-
-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 side, field, l, mode, ret = 0;
-	void __iomem *reg;
-
-	side = (pin_mode & MUX_SIDE_MASK) >> MUX_SIDE_SHIFT;
-	switch (side) {
-	case MUX_SIDE_AP:
-		reg = IOMUXSW_AP_MUX_CTL;
-		break;
-	case MUX_SIDE_SP:
-		reg = IOMUXSW_SP_MUX_CTL;
-		break;
-	default:
-		return -EINVAL;
-	}
-	reg += ((pin_mode & MUX_REG_MASK) >> MUX_REG_SHIFT) * 4;
-	field = (pin_mode & MUX_FIELD_MASK) >> MUX_FIELD_SHIFT;
-	mode = (pin_mode & MUX_MODE_MASK) >> MUX_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 padgrp, field, l;
-	void __iomem *reg;
-
-	padgrp = (pin & MUX_PADGRP_MASK) >> MUX_PADGRP_SHIFT;
-	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(unsigned int pin_mode, const char *label)
-{
-	unsigned pad = PIN_GLOBAL_NUM(pin_mode);
-	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_mode);
-
-	return 0;
-}
-EXPORT_SYMBOL(mxc_iomux_alloc_pin);
-
-int mxc_iomux_setup_multiple_pins(const unsigned int *pin_list, unsigned count,
-		const char *label)
-{
-	const 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(unsigned int pin_mode)
-{
-	unsigned pad = PIN_GLOBAL_NUM(pin_mode);
-
-	if (pad < (PIN_MAX + 1))
-		clear_bit(pad, mxc_pin_alloc_map);
-}
-EXPORT_SYMBOL(mxc_iomux_release_pin);
-
-void mxc_iomux_release_multiple_pins(const unsigned int *pin_list, int count)
-{
-	const 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);
diff -druN linux-2.6.39-libre/arch/arm/mach-mxc91231/Kconfig linux-3.0-rc7-libre/arch/arm/mach-mxc91231/Kconfig
--- linux-2.6.39-libre/arch/arm/mach-mxc91231/Kconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-mxc91231/Kconfig	1969-12-31 19:00:00.000000000 -0500
@@ -1,11 +0,0 @@
-if ARCH_MXC91231
-
-comment "MXC91231 platforms:"
-
-config MACH_MAGX_ZN5
-	bool "Support Motorola Zn5 GSM phone"
-	default n
-	help
-	  Include support for Motorola Zn5 GSM phone.
-
-endif
diff -druN linux-2.6.39-libre/arch/arm/mach-mxc91231/magx-zn5.c linux-3.0-rc7-libre/arch/arm/mach-mxc91231/magx-zn5.c
--- linux-2.6.39-libre/arch/arm/mach-mxc91231/magx-zn5.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-mxc91231/magx-zn5.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,62 +0,0 @@
-/*
- * Copyright 2009 Dmitriy Taychenachev <dimichxp@gmail.com>
- *
- * This file is released under the GPLv2 or later.
- */
-
-#include <linux/irq.h>
-#include <linux/init.h>
-#include <linux/device.h>
-
-#include <asm/mach-types.h>
-#include <asm/mach/time.h>
-#include <asm/mach/arch.h>
-
-#include <mach/common.h>
-#include <mach/hardware.h>
-#include <mach/iomux-mxc91231.h>
-#include <mach/mmc.h>
-#include <mach/imx-uart.h>
-
-#include "devices.h"
-
-static struct imxuart_platform_data uart_pdata = {
-};
-
-static struct imxmmc_platform_data sdhc_pdata = {
-};
-
-static void __init zn5_init(void)
-{
-	pm_power_off = mxc91231_power_off;
-
-	mxc_iomux_alloc_pin(MXC91231_PIN_SP_USB_DAT_VP__RXD2, "uart2-rx");
-	mxc_iomux_alloc_pin(MXC91231_PIN_SP_USB_SE0_VM__TXD2, "uart2-tx");
-
-	mxc_register_device(&mxc_uart_device1, &uart_pdata);
-	mxc_register_device(&mxc_uart_device0, &uart_pdata);
-
-	mxc_register_device(&mxc_sdhc_device0, &sdhc_pdata);
-
-	mxc_register_device(&mxc_wdog_device0, NULL);
-
-	return;
-}
-
-static void __init zn5_timer_init(void)
-{
-	mxc91231_clocks_init(26000000); /* 26mhz ckih */
-}
-
-struct sys_timer zn5_timer = {
-	.init = zn5_timer_init,
-};
-
-MACHINE_START(MAGX_ZN5, "Motorola Zn5")
-	.boot_params = MXC91231_PHYS_OFFSET + 0x100,
-	.map_io = mxc91231_map_io,
-	.init_early = mxc91231_init_early,
-	.init_irq = mxc91231_init_irq,
-	.timer = &zn5_timer,
-	.init_machine = zn5_init,
-MACHINE_END
diff -druN linux-2.6.39-libre/arch/arm/mach-mxc91231/Makefile linux-3.0-rc7-libre/arch/arm/mach-mxc91231/Makefile
--- linux-2.6.39-libre/arch/arm/mach-mxc91231/Makefile	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-mxc91231/Makefile	1969-12-31 19:00:00.000000000 -0500
@@ -1,2 +0,0 @@
-obj-y	:= mm.o clock.o devices.o system.o iomux.o
-obj-$(CONFIG_MACH_MAGX_ZN5) += magx-zn5.o
diff -druN linux-2.6.39-libre/arch/arm/mach-mxc91231/Makefile.boot linux-3.0-rc7-libre/arch/arm/mach-mxc91231/Makefile.boot
--- linux-2.6.39-libre/arch/arm/mach-mxc91231/Makefile.boot	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-mxc91231/Makefile.boot	1969-12-31 19:00:00.000000000 -0500
@@ -1,3 +0,0 @@
-   zreladdr-y	:= 0x90008000
-params_phys-y	:= 0x90000100
-initrd_phys-y	:= 0x90800000
diff -druN linux-2.6.39-libre/arch/arm/mach-mxc91231/mm.c linux-3.0-rc7-libre/arch/arm/mach-mxc91231/mm.c
--- linux-2.6.39-libre/arch/arm/mach-mxc91231/mm.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-mxc91231/mm.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,62 +0,0 @@
-/*
- *  Copyright (C) 1999,2000 Arm Limited
- *  Copyright (C) 2000 Deep Blue Solutions Ltd
- *  Copyright (C) 2002 Shane Nay (shane@minirl.com)
- *  Copyright 2004-2005 Freescale Semiconductor, Inc. All Rights Reserved.
- *    - add MXC specific definitions
- *  Copyright 2006 Motorola, 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.
- */
-
-#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>
-
-/*
- * This structure defines the MXC memory map.
- */
-static struct map_desc mxc91231_io_desc[] __initdata = {
-	imx_map_entry(MXC91231, L2CC, MT_DEVICE),
-	imx_map_entry(MXC91231, X_MEMC, MT_DEVICE),
-	imx_map_entry(MXC91231, ROMP, MT_DEVICE),
-	imx_map_entry(MXC91231, AVIC, MT_DEVICE),
-	imx_map_entry(MXC91231, AIPS1, MT_DEVICE),
-	imx_map_entry(MXC91231, SPBA0, MT_DEVICE),
-	imx_map_entry(MXC91231, SPBA1, MT_DEVICE),
-	imx_map_entry(MXC91231, AIPS2, MT_DEVICE),
-};
-
-/*
- * This function initializes the memory map. It is called during the
- * system startup to create static physical to virtual memory map for
- * the IO modules.
- */
-void __init mxc91231_map_io(void)
-{
-	iotable_init(mxc91231_io_desc, ARRAY_SIZE(mxc91231_io_desc));
-}
-
-void __init mxc91231_init_early(void)
-{
-	mxc_set_cpu_type(MXC_CPU_MXC91231);
-}
-
-int mxc91231_register_gpios(void);
-
-void __init mxc91231_init_irq(void)
-{
-	mxc91231_register_gpios();
-	mxc_init_irq(MXC91231_IO_ADDRESS(MXC91231_AVIC_BASE_ADDR));
-}
diff -druN linux-2.6.39-libre/arch/arm/mach-mxc91231/system.c linux-3.0-rc7-libre/arch/arm/mach-mxc91231/system.c
--- linux-2.6.39-libre/arch/arm/mach-mxc91231/system.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-mxc91231/system.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,51 +0,0 @@
-/*
- * Copyright 2009 Dmitriy Taychenachev <dimichxp@gmail.com>
- *
- * This file is released under the GPLv2 or later.
- */
-
-#include <linux/delay.h>
-#include <linux/io.h>
-
-#include <asm/proc-fns.h>
-#include <mach/hardware.h>
-
-#include "crm_regs.h"
-
-#define WDOG_WCR		MXC91231_IO_ADDRESS(MXC91231_WDOG1_BASE_ADDR)
-#define WDOG_WCR_OUT_ENABLE	(1 << 6)
-#define WDOG_WCR_ASSERT		(1 << 5)
-
-void mxc91231_power_off(void)
-{
-	u16 wcr;
-
-	wcr = __raw_readw(WDOG_WCR);
-	wcr |= WDOG_WCR_OUT_ENABLE;
-	wcr &= ~WDOG_WCR_ASSERT;
-	__raw_writew(wcr, WDOG_WCR);
-}
-
-void mxc91231_arch_reset(char mode, const char *cmd)
-{
-	u32 amcr;
-
-	/* Reset the AP using CRM */
-	amcr = __raw_readl(MXC_CRMAP_AMCR);
-	amcr &= ~MXC_CRMAP_AMCR_SW_AP;
-	__raw_writel(amcr, MXC_CRMAP_AMCR);
-
-	mdelay(10);
-	cpu_reset(0);
-}
-
-void mxc91231_prepare_idle(void)
-{
-	u32 crm_ctl;
-
-	/* Go to WAIT mode after WFI */
-	crm_ctl = __raw_readl(MXC_DSM_CRM_CONTROL);
-	crm_ctl &= ~(MXC_DSM_CRM_CTRL_LPMD0 | MXC_DSM_CRM_CTRL_LPMD1);
-	crm_ctl |=  MXC_DSM_CRM_CTRL_LPMD_WAIT_MODE;
-	__raw_writel(crm_ctl, MXC_DSM_CRM_CONTROL);
-}
diff -druN linux-2.6.39-libre/arch/arm/mach-mxs/clock-mx23.c linux-3.0-rc7-libre/arch/arm/mach-mxs/clock-mx23.c
--- linux-2.6.39-libre/arch/arm/mach-mxs/clock-mx23.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-mxs/clock-mx23.c	2011-07-11 19:51:52.000000000 -0400
@@ -446,6 +446,8 @@
 	_REGISTER_CLOCK("rtc", NULL, rtc_clk)
 	_REGISTER_CLOCK("mxs-dma-apbh", NULL, hbus_clk)
 	_REGISTER_CLOCK("mxs-dma-apbx", NULL, xbus_clk)
+	_REGISTER_CLOCK("mxs-mmc.0", NULL, ssp_clk)
+	_REGISTER_CLOCK("mxs-mmc.1", NULL, ssp_clk)
 	_REGISTER_CLOCK(NULL, "usb", usb_clk)
 	_REGISTER_CLOCK(NULL, "audio", audio_clk)
 	_REGISTER_CLOCK("mxs-pwm.0", NULL, pwm_clk)
diff -druN linux-2.6.39-libre/arch/arm/mach-mxs/devices/platform-mxs-i2c.c linux-3.0-rc7-libre/arch/arm/mach-mxs/devices/platform-mxs-i2c.c
--- linux-2.6.39-libre/arch/arm/mach-mxs/devices/platform-mxs-i2c.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-mxs/devices/platform-mxs-i2c.c	2011-07-11 19:51:52.000000000 -0400
@@ -22,13 +22,14 @@
 	[_id] = mxs_i2c_data_entry_single(soc, _id)
 
 #ifdef CONFIG_SOC_IMX28
-const struct mxs_i2c_data mx28_mxs_i2c_data[] __initconst = {
+const struct mxs_mxs_i2c_data mx28_mxs_i2c_data[] __initconst = {
 	mxs_i2c_data_entry(MX28, 0),
 	mxs_i2c_data_entry(MX28, 1),
 };
 #endif
 
-struct platform_device *__init mxs_add_mxs_i2c(const struct mxs_i2c_data *data)
+struct platform_device *__init mxs_add_mxs_i2c(
+		const struct mxs_mxs_i2c_data *data)
 {
 	struct resource res[] = {
 		{
diff -druN linux-2.6.39-libre/arch/arm/mach-mxs/devices-mx28.h linux-3.0-rc7-libre/arch/arm/mach-mxs/devices-mx28.h
--- linux-2.6.39-libre/arch/arm/mach-mxs/devices-mx28.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-mxs/devices-mx28.h	2011-07-11 19:51:52.000000000 -0400
@@ -34,7 +34,7 @@
 #define mx28_add_flexcan0(pdata)	mx28_add_flexcan(0, pdata)
 #define mx28_add_flexcan1(pdata)	mx28_add_flexcan(1, pdata)
 
-extern const struct mxs_i2c_data mx28_mxs_i2c_data[] __initconst;
+extern const struct mxs_mxs_i2c_data mx28_mxs_i2c_data[] __initconst;
 #define mx28_add_mxs_i2c(id)		mxs_add_mxs_i2c(&mx28_mxs_i2c_data[id])
 
 extern const struct mxs_mxs_mmc_data mx28_mxs_mmc_data[] __initconst;
diff -druN linux-2.6.39-libre/arch/arm/mach-mxs/include/mach/devices-common.h linux-3.0-rc7-libre/arch/arm/mach-mxs/include/mach/devices-common.h
--- linux-2.6.39-libre/arch/arm/mach-mxs/include/mach/devices-common.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-mxs/include/mach/devices-common.h	2011-07-11 19:51:52.000000000 -0400
@@ -65,13 +65,14 @@
 		const struct flexcan_platform_data *pdata);
 
 /* i2c */
-struct mxs_i2c_data {
+struct mxs_mxs_i2c_data {
 	int id;
 	resource_size_t iobase;
 	resource_size_t errirq;
 	resource_size_t dmairq;
 };
-struct platform_device * __init mxs_add_mxs_i2c(const struct mxs_i2c_data *data);
+struct platform_device * __init mxs_add_mxs_i2c(
+		const struct mxs_mxs_i2c_data *data);
 
 /* mmc */
 #include <mach/mmc.h>
diff -druN linux-2.6.39-libre/arch/arm/mach-mxs/include/mach/mx23.h linux-3.0-rc7-libre/arch/arm/mach-mxs/include/mach/mx23.h
--- linux-2.6.39-libre/arch/arm/mach-mxs/include/mach/mx23.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-mxs/include/mach/mx23.h	2011-07-11 19:51:52.000000000 -0400
@@ -57,7 +57,7 @@
 #define MX23_AUDIOIN_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x04c000)
 #define MX23_LRADC_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x050000)
 #define MX23_SPDIF_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x054000)
-#define MX23_I2C0_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x058000)
+#define MX23_I2C_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x058000)
 #define MX23_RTC_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x05c000)
 #define MX23_PWM_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x064000)
 #define MX23_TIMROT_BASE_ADDR		(MX23_IO_BASE_ADDR + 0x068000)
diff -druN linux-2.6.39-libre/arch/arm/mach-mxs/include/mach/uncompress.h linux-3.0-rc7-libre/arch/arm/mach-mxs/include/mach/uncompress.h
--- linux-2.6.39-libre/arch/arm/mach-mxs/include/mach/uncompress.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-mxs/include/mach/uncompress.h	2011-07-11 19:51:52.000000000 -0400
@@ -20,7 +20,7 @@
 
 #include <asm/mach-types.h>
 
-static unsigned long mxs_duart_base;
+unsigned long mxs_duart_base;
 
 #define MXS_DUART(x)	(*(volatile unsigned long *)(mxs_duart_base + (x)))
 
diff -druN linux-2.6.39-libre/arch/arm/mach-mxs/Kconfig linux-3.0-rc7-libre/arch/arm/mach-mxs/Kconfig
--- linux-2.6.39-libre/arch/arm/mach-mxs/Kconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-mxs/Kconfig	2011-07-11 19:51:52.000000000 -0400
@@ -17,6 +17,16 @@
 
 comment "MXS platforms:"
 
+config MACH_STMP378X_DEVB
+	bool "Support STMP378x_devb Platform"
+	select SOC_IMX23
+	select MXS_HAVE_AMBA_DUART
+	select MXS_HAVE_PLATFORM_AUART
+	select MXS_HAVE_PLATFORM_MXS_MMC
+	help
+	  Include support for STMP378x-devb platform. This includes specific
+	  configurations for the board and its peripherals.
+
 config MACH_MX23EVK
 	bool "Support MX23EVK Platform"
 	select SOC_IMX23
@@ -24,7 +34,6 @@
 	select MXS_HAVE_PLATFORM_AUART
 	select MXS_HAVE_PLATFORM_MXS_MMC
 	select MXS_HAVE_PLATFORM_MXSFB
-	default y
 	help
 	  Include support for MX23EVK platform. This includes specific
 	  configurations for the board and its peripherals.
@@ -39,7 +48,6 @@
 	select MXS_HAVE_PLATFORM_MXS_MMC
 	select MXS_HAVE_PLATFORM_MXSFB
 	select MXS_OCOTP
-	default y
 	help
 	  Include support for MX28EVK platform. This includes specific
 	  configurations for the board and its peripherals.
diff -druN linux-2.6.39-libre/arch/arm/mach-mxs/mach-mx23evk.c linux-3.0-rc7-libre/arch/arm/mach-mxs/mach-mx23evk.c
--- linux-2.6.39-libre/arch/arm/mach-mxs/mach-mx23evk.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-mxs/mach-mx23evk.c	2011-07-11 19:51:52.000000000 -0400
@@ -148,7 +148,7 @@
 	mx23_add_auart0();
 
 	/* power on mmc slot by writing 0 to the gpio */
-	ret = gpio_request_one(MX23EVK_MMC0_SLOT_POWER, GPIOF_DIR_OUT,
+	ret = gpio_request_one(MX23EVK_MMC0_SLOT_POWER, GPIOF_OUT_INIT_LOW,
 			       "mmc0-slot-power");
 	if (ret)
 		pr_warn("failed to request gpio mmc0-slot-power: %d\n", ret);
diff -druN linux-2.6.39-libre/arch/arm/mach-mxs/mach-mx28evk.c linux-3.0-rc7-libre/arch/arm/mach-mxs/mach-mx28evk.c
--- linux-2.6.39-libre/arch/arm/mach-mxs/mach-mx28evk.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-mxs/mach-mx28evk.c	2011-07-11 19:51:52.000000000 -0400
@@ -375,13 +375,13 @@
 	mx28_add_mxsfb(&mx28evk_mxsfb_pdata);
 
 	/* power on mmc slot by writing 0 to the gpio */
-	ret = gpio_request_one(MX28EVK_MMC0_SLOT_POWER, GPIOF_DIR_OUT,
+	ret = gpio_request_one(MX28EVK_MMC0_SLOT_POWER, GPIOF_OUT_INIT_LOW,
 			       "mmc0-slot-power");
 	if (ret)
 		pr_warn("failed to request gpio mmc0-slot-power: %d\n", ret);
 	mx28_add_mxs_mmc(0, &mx28evk_mmc_pdata[0]);
 
-	ret = gpio_request_one(MX28EVK_MMC1_SLOT_POWER, GPIOF_DIR_OUT,
+	ret = gpio_request_one(MX28EVK_MMC1_SLOT_POWER, GPIOF_OUT_INIT_LOW,
 			       "mmc1-slot-power");
 	if (ret)
 		pr_warn("failed to request gpio mmc1-slot-power: %d\n", ret);
diff -druN linux-2.6.39-libre/arch/arm/mach-mxs/mach-stmp378x_devb.c linux-3.0-rc7-libre/arch/arm/mach-mxs/mach-stmp378x_devb.c
--- linux-2.6.39-libre/arch/arm/mach-mxs/mach-stmp378x_devb.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/arm/mach-mxs/mach-stmp378x_devb.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,120 @@
+/*
+ * board setup for STMP378x-Development-Board
+ *
+ * based on mx23evk board setup and information gained form the original
+ * plat-stmp based board setup, now converted to mach-mxs.
+ *
+ * Copyright 2010 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright (C) 2011 Wolfram Sang, Pengutronix e.K.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/platform_device.h>
+#include <linux/gpio.h>
+#include <linux/irq.h>
+#include <linux/spi/spi.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+
+#include <mach/common.h>
+#include <mach/iomux-mx23.h>
+
+#include "devices-mx23.h"
+
+#define STMP378X_DEVB_MMC0_WRITE_PROTECT	MXS_GPIO_NR(1, 30)
+#define STMP378X_DEVB_MMC0_SLOT_POWER		MXS_GPIO_NR(1, 29)
+
+#define STMP378X_DEVB_PAD_AUART (MXS_PAD_4MA | MXS_PAD_1V8 | MXS_PAD_NOPULL)
+
+static const iomux_cfg_t stmp378x_dvb_pads[] __initconst = {
+	/* duart (extended setup missing in old boardcode, too */
+	MX23_PAD_PWM0__DUART_RX,
+	MX23_PAD_PWM1__DUART_TX,
+
+	/* auart */
+	MX23_PAD_AUART1_RX__AUART1_RX | STMP378X_DEVB_PAD_AUART,
+	MX23_PAD_AUART1_TX__AUART1_TX | STMP378X_DEVB_PAD_AUART,
+	MX23_PAD_AUART1_CTS__AUART1_CTS | STMP378X_DEVB_PAD_AUART,
+	MX23_PAD_AUART1_RTS__AUART1_RTS | STMP378X_DEVB_PAD_AUART,
+
+	/* mmc */
+	MX23_PAD_SSP1_DATA0__SSP1_DATA0 |
+		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+	MX23_PAD_SSP1_DATA1__SSP1_DATA1 |
+		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+	MX23_PAD_SSP1_DATA2__SSP1_DATA2 |
+		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+	MX23_PAD_SSP1_DATA3__SSP1_DATA3 |
+		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+	MX23_PAD_SSP1_CMD__SSP1_CMD |
+		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+	MX23_PAD_SSP1_DETECT__SSP1_DETECT |
+		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_NOPULL),
+	MX23_PAD_SSP1_SCK__SSP1_SCK |
+		(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_NOPULL),
+	MX23_PAD_PWM4__GPIO_1_30 | MXS_PAD_CTRL, /* write protect */
+	MX23_PAD_PWM3__GPIO_1_29 | MXS_PAD_CTRL, /* power enable */
+};
+
+static struct mxs_mmc_platform_data stmp378x_dvb_mmc_pdata __initdata = {
+	.wp_gpio = STMP378X_DEVB_MMC0_WRITE_PROTECT,
+};
+
+static struct spi_board_info spi_board_info[] __initdata = {
+#if defined(CONFIG_ENC28J60) || defined(CONFIG_ENC28J60_MODULE)
+	{
+		.modalias       = "enc28j60",
+		.max_speed_hz   = 6 * 1000 * 1000,
+		.bus_num	= 1,
+		.chip_select    = 0,
+		.platform_data  = NULL,
+	},
+#endif
+};
+
+static void __init stmp378x_dvb_init(void)
+{
+	int ret;
+
+	mxs_iomux_setup_multiple_pads(stmp378x_dvb_pads,
+			ARRAY_SIZE(stmp378x_dvb_pads));
+
+	mx23_add_duart();
+	mx23_add_auart0();
+
+	/* power on mmc slot */
+	ret = gpio_request_one(STMP378X_DEVB_MMC0_SLOT_POWER,
+		GPIOF_OUT_INIT_LOW, "mmc0-slot-power");
+	if (ret)
+		pr_warn("could not power mmc (%d)\n", ret);
+
+	mx23_add_mxs_mmc(0, &stmp378x_dvb_mmc_pdata);
+
+	spi_register_board_info(spi_board_info, ARRAY_SIZE(spi_board_info));
+}
+
+static void __init stmp378x_dvb_timer_init(void)
+{
+	mx23_clocks_init();
+}
+
+static struct sys_timer stmp378x_dvb_timer = {
+	.init	= stmp378x_dvb_timer_init,
+};
+
+MACHINE_START(STMP378X, "STMP378X")
+	.map_io		= mx23_map_io,
+	.init_irq	= mx23_init_irq,
+	.init_machine	= stmp378x_dvb_init,
+	.timer		= &stmp378x_dvb_timer,
+MACHINE_END
diff -druN linux-2.6.39-libre/arch/arm/mach-mxs/Makefile linux-3.0-rc7-libre/arch/arm/mach-mxs/Makefile
--- linux-2.6.39-libre/arch/arm/mach-mxs/Makefile	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-mxs/Makefile	2011-07-11 19:51:52.000000000 -0400
@@ -7,6 +7,7 @@
 obj-$(CONFIG_SOC_IMX23) += clock-mx23.o mm-mx23.o
 obj-$(CONFIG_SOC_IMX28) += clock-mx28.o mm-mx28.o
 
+obj-$(CONFIG_MACH_STMP378X_DEVB) += mach-stmp378x_devb.o
 obj-$(CONFIG_MACH_MX23EVK) += mach-mx23evk.o
 obj-$(CONFIG_MACH_MX28EVK) += mach-mx28evk.o
 obj-$(CONFIG_MODULE_TX28) += module-tx28.o
diff -druN linux-2.6.39-libre/arch/arm/mach-mxs/ocotp.c linux-3.0-rc7-libre/arch/arm/mach-mxs/ocotp.c
--- linux-2.6.39-libre/arch/arm/mach-mxs/ocotp.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-mxs/ocotp.c	2011-07-11 19:51:52.000000000 -0400
@@ -16,6 +16,8 @@
 #include <linux/err.h>
 #include <linux/mutex.h>
 
+#include <asm/processor.h>	/* for cpu_relax() */
+
 #include <mach/mxs.h>
 
 #define OCOTP_WORD_OFFSET		0x20
diff -druN linux-2.6.39-libre/arch/arm/mach-mxs/timer.c linux-3.0-rc7-libre/arch/arm/mach-mxs/timer.c
--- linux-2.6.39-libre/arch/arm/mach-mxs/timer.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-mxs/timer.c	2011-07-11 19:51:52.000000000 -0400
@@ -101,11 +101,6 @@
 			& 0xffff0000) >> 16);
 }
 
-static cycle_t timrotv2_get_cycles(struct clocksource *cs)
-{
-	return ~__raw_readl(mxs_timrot_base + HW_TIMROT_RUNNING_COUNTn(1));
-}
-
 static int timrotv1_set_next_event(unsigned long evt,
 					struct clock_event_device *dev)
 {
@@ -230,8 +225,8 @@
 static struct clocksource clocksource_mxs = {
 	.name		= "mxs_timer",
 	.rating		= 200,
-	.read		= timrotv2_get_cycles,
-	.mask		= CLOCKSOURCE_MASK(32),
+	.read		= timrotv1_get_cycles,
+	.mask		= CLOCKSOURCE_MASK(16),
 	.flags		= CLOCK_SOURCE_IS_CONTINUOUS,
 };
 
@@ -239,12 +234,11 @@
 {
 	unsigned int c = clk_get_rate(timer_clk);
 
-	if (timrot_is_v1()) {
-		clocksource_mxs.read = timrotv1_get_cycles;
-		clocksource_mxs.mask = CLOCKSOURCE_MASK(16);
-	}
-
-	clocksource_register_hz(&clocksource_mxs, c);
+	if (timrot_is_v1())
+		clocksource_register_hz(&clocksource_mxs, c);
+	else
+		clocksource_mmio_init(mxs_timrot_base + HW_TIMROT_RUNNING_COUNTn(1),
+			"mxs_timer", c, 200, 32, clocksource_mmio_readl_down);
 
 	return 0;
 }
diff -druN linux-2.6.39-libre/arch/arm/mach-netx/fb.c linux-3.0-rc7-libre/arch/arm/mach-netx/fb.c
--- linux-2.6.39-libre/arch/arm/mach-netx/fb.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-netx/fb.c	2011-07-11 19:51:52.000000000 -0400
@@ -103,7 +103,6 @@
 		.flags	= IORESOURCE_MEM,
 	},
 	.irq		= { NETX_IRQ_LCD, NO_IRQ },
-	.periphid	= 0x10112400,
 };
 
 int netx_fb_init(struct clcd_board *board, struct clcd_panel *panel)
diff -druN linux-2.6.39-libre/arch/arm/mach-netx/time.c linux-3.0-rc7-libre/arch/arm/mach-netx/time.c
--- linux-2.6.39-libre/arch/arm/mach-netx/time.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-netx/time.c	2011-07-11 19:51:52.000000000 -0400
@@ -104,19 +104,6 @@
 	.handler	= netx_timer_interrupt,
 };
 
-cycle_t netx_get_cycles(struct clocksource *cs)
-{
-	return readl(NETX_GPIO_COUNTER_CURRENT(TIMER_CLOCKSOURCE));
-}
-
-static struct clocksource clocksource_netx = {
-	.name		= "netx_timer",
-	.rating		= 200,
-	.read		= netx_get_cycles,
-	.mask		= CLOCKSOURCE_MASK(32),
-	.flags		= CLOCK_SOURCE_IS_CONTINUOUS,
-};
-
 /*
  * Set up timer interrupt
  */
@@ -150,7 +137,8 @@
 	writel(NETX_GPIO_COUNTER_CTRL_RUN,
 			NETX_GPIO_COUNTER_CTRL(TIMER_CLOCKSOURCE));
 
-	clocksource_register_hz(&clocksource_netx, CLOCK_TICK_RATE);
+	clocksource_mmio_init(NETX_GPIO_COUNTER_CURRENT(TIMER_CLOCKSOURCE),
+		"netx_timer", CLOCK_TICK_RATE, 200, 32, clocksource_mmio_readl_up);
 
 	netx_clockevent.mult = div_sc(CLOCK_TICK_RATE, NSEC_PER_SEC,
 			netx_clockevent.shift);
diff -druN linux-2.6.39-libre/arch/arm/mach-nomadik/Kconfig linux-3.0-rc7-libre/arch/arm/mach-nomadik/Kconfig
--- linux-2.6.39-libre/arch/arm/mach-nomadik/Kconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-nomadik/Kconfig	2011-07-11 19:51:52.000000000 -0400
@@ -6,7 +6,6 @@
 	bool "ST 8815 Nomadik Hardware Kit (evaluation board)"
 	select NOMADIK_8815
 	select HAS_MTU
-	select NOMADIK_GPIO
 
 endmenu
 
diff -druN linux-2.6.39-libre/arch/arm/mach-ns9xxx/board-a9m9750dev.c linux-3.0-rc7-libre/arch/arm/mach-ns9xxx/board-a9m9750dev.c
--- linux-2.6.39-libre/arch/arm/mach-ns9xxx/board-a9m9750dev.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-ns9xxx/board-a9m9750dev.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,156 +0,0 @@
-/*
- * arch/arm/mach-ns9xxx/board-a9m9750dev.c
- *
- * Copyright (C) 2006,2007 by Digi International 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/irq.h>
-
-#include <asm/mach/map.h>
-#include <asm/gpio.h>
-
-#include <mach/board.h>
-#include <mach/processor-ns9360.h>
-#include <mach/regs-sys-ns9360.h>
-#include <mach/regs-mem.h>
-#include <mach/regs-bbu.h>
-#include <mach/regs-board-a9m9750dev.h>
-
-#include "board-a9m9750dev.h"
-
-static struct map_desc board_a9m9750dev_io_desc[] __initdata = {
-	{ /* FPGA on CS0 */
-		.virtual = io_p2v(NS9XXX_CSxSTAT_PHYS(0)),
-		.pfn = __phys_to_pfn(NS9XXX_CSxSTAT_PHYS(0)),
-		.length = NS9XXX_CS0STAT_LENGTH,
-		.type = MT_DEVICE,
-	},
-};
-
-void __init board_a9m9750dev_map_io(void)
-{
-	iotable_init(board_a9m9750dev_io_desc,
-		     ARRAY_SIZE(board_a9m9750dev_io_desc));
-}
-
-static void a9m9750dev_fpga_ack_irq(struct irq_data *d)
-{
-	/* nothing */
-}
-
-static void a9m9750dev_fpga_mask_irq(struct irq_data *d)
-{
-	u8 ier;
-
-	ier = __raw_readb(FPGA_IER);
-
-	ier &= ~(1 << (d->irq - FPGA_IRQ(0)));
-
-	__raw_writeb(ier, FPGA_IER);
-}
-
-static void a9m9750dev_fpga_maskack_irq(struct irq_data *d)
-{
-	a9m9750dev_fpga_mask_irq(d);
-	a9m9750dev_fpga_ack_irq(d);
-}
-
-static void a9m9750dev_fpga_unmask_irq(struct irq_data *d)
-{
-	u8 ier;
-
-	ier = __raw_readb(FPGA_IER);
-
-	ier |= 1 << (d->irq - FPGA_IRQ(0));
-
-	__raw_writeb(ier, FPGA_IER);
-}
-
-static struct irq_chip a9m9750dev_fpga_chip = {
-	.irq_ack	= a9m9750dev_fpga_ack_irq,
-	.irq_mask	= a9m9750dev_fpga_mask_irq,
-	.irq_mask_ack	= a9m9750dev_fpga_maskack_irq,
-	.irq_unmask	= a9m9750dev_fpga_unmask_irq,
-};
-
-static void a9m9750dev_fpga_demux_handler(unsigned int irq,
-		struct irq_desc *desc)
-{
-	u8 stat = __raw_readb(FPGA_ISR);
-
-	desc->irq_data.chip->irq_mask_ack(&desc->irq_data);
-
-	while (stat != 0) {
-		int irqno = fls(stat) - 1;
-
-		stat &= ~(1 << irqno);
-
-		generic_handle_irq(FPGA_IRQ(irqno));
-	}
-
-	desc->irq_data.chip->irq_unmask(&desc->irq_data);
-}
-
-void __init board_a9m9750dev_init_irq(void)
-{
-	u32 eic;
-	int i;
-
-	if (gpio_request(11, "board a9m9750dev extirq2") == 0)
-		ns9360_gpio_configure(11, 0, 1);
-	else
-		printk(KERN_ERR "%s: cannot get gpio 11 for IRQ_NS9XXX_EXT2\n",
-				__func__);
-
-	for (i = FPGA_IRQ(0); i <= FPGA_IRQ(7); ++i) {
-		irq_set_chip_and_handler(i, &a9m9750dev_fpga_chip,
-					 handle_level_irq);
-		set_irq_flags(i, IRQF_VALID);
-	}
-
-	/* IRQ_NS9XXX_EXT2: level sensitive + active low */
-	eic = __raw_readl(SYS_EIC(2));
-	REGSET(eic, SYS_EIC, PLTY, AL);
-	REGSET(eic, SYS_EIC, LVEDG, LEVEL);
-	__raw_writel(eic, SYS_EIC(2));
-
-	irq_set_chained_handler(IRQ_NS9XXX_EXT2,
-				a9m9750dev_fpga_demux_handler);
-}
-
-void __init board_a9m9750dev_init_machine(void)
-{
-	u32 reg;
-
-	/* setup static CS0: memory base ... */
-	reg = __raw_readl(SYS_SMCSSMB(0));
-	REGSETIM(reg, SYS_SMCSSMB, CSxB, NS9XXX_CSxSTAT_PHYS(0) >> 12);
-	__raw_writel(reg, SYS_SMCSSMB(0));
-
-	/* ... and mask */
-	reg = __raw_readl(SYS_SMCSSMM(0));
-	REGSETIM(reg, SYS_SMCSSMM, CSxM, 0xfffff);
-	REGSET(reg, SYS_SMCSSMM, CSEx, EN);
-	__raw_writel(reg, SYS_SMCSSMM(0));
-
-	/* setup static CS0: memory configuration */
-	reg = __raw_readl(MEM_SMC(0));
-	REGSET(reg, MEM_SMC, PSMC, OFF);
-	REGSET(reg, MEM_SMC, BSMC, OFF);
-	REGSET(reg, MEM_SMC, EW, OFF);
-	REGSET(reg, MEM_SMC, PB, 1);
-	REGSET(reg, MEM_SMC, PC, AL);
-	REGSET(reg, MEM_SMC, PM, DIS);
-	REGSET(reg, MEM_SMC, MW, 8);
-	__raw_writel(reg, MEM_SMC(0));
-
-	/* setup static CS0: timing */
-	__raw_writel(0x2, MEM_SMWED(0));
-	__raw_writel(0x2, MEM_SMOED(0));
-	__raw_writel(0x6, MEM_SMRD(0));
-	__raw_writel(0x6, MEM_SMWD(0));
-}
diff -druN linux-2.6.39-libre/arch/arm/mach-ns9xxx/board-a9m9750dev.h linux-3.0-rc7-libre/arch/arm/mach-ns9xxx/board-a9m9750dev.h
--- linux-2.6.39-libre/arch/arm/mach-ns9xxx/board-a9m9750dev.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-ns9xxx/board-a9m9750dev.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,15 +0,0 @@
-/*
- * arch/arm/mach-ns9xxx/board-a9m9750dev.h
- *
- * Copyright (C) 2006 by Digi International 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>
-
-void __init board_a9m9750dev_map_io(void);
-void __init board_a9m9750dev_init_machine(void);
-void __init board_a9m9750dev_init_irq(void);
diff -druN linux-2.6.39-libre/arch/arm/mach-ns9xxx/board-jscc9p9360.c linux-3.0-rc7-libre/arch/arm/mach-ns9xxx/board-jscc9p9360.c
--- linux-2.6.39-libre/arch/arm/mach-ns9xxx/board-jscc9p9360.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-ns9xxx/board-jscc9p9360.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,17 +0,0 @@
-/*
- * arch/arm/mach-ns9xxx/board-jscc9p9360.c
- *
- * Copyright (C) 2006,2007 by Digi International 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 "board-jscc9p9360.h"
-
-void __init board_jscc9p9360_init_machine(void)
-{
-	/* TODO: reserve GPIOs for push buttons, etc pp */
-}
-
diff -druN linux-2.6.39-libre/arch/arm/mach-ns9xxx/board-jscc9p9360.h linux-3.0-rc7-libre/arch/arm/mach-ns9xxx/board-jscc9p9360.h
--- linux-2.6.39-libre/arch/arm/mach-ns9xxx/board-jscc9p9360.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-ns9xxx/board-jscc9p9360.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,13 +0,0 @@
-/*
- * arch/arm/mach-ns9xxx/board-jscc9p9360.h
- *
- * Copyright (C) 2006 by Digi International 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>
-
-void __init board_jscc9p9360_init_machine(void);
diff -druN linux-2.6.39-libre/arch/arm/mach-ns9xxx/clock.c linux-3.0-rc7-libre/arch/arm/mach-ns9xxx/clock.c
--- linux-2.6.39-libre/arch/arm/mach-ns9xxx/clock.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-ns9xxx/clock.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,215 +0,0 @@
-/*
- * arch/arm/mach-ns9xxx/clock.c
- *
- * Copyright (C) 2007 by Digi International 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/err.h>
-#include <linux/module.h>
-#include <linux/list.h>
-#include <linux/clk.h>
-#include <linux/string.h>
-#include <linux/platform_device.h>
-#include <linux/semaphore.h>
-
-#include "clock.h"
-
-static LIST_HEAD(clocks);
-static DEFINE_SPINLOCK(clk_lock);
-
-struct clk *clk_get(struct device *dev, const char *id)
-{
-	struct clk *p, *ret = NULL, *retgen = NULL;
-	unsigned long flags;
-	int idno;
-
-	if (dev == NULL || dev->bus != &platform_bus_type)
-		idno = -1;
-	else
-		idno = to_platform_device(dev)->id;
-
-	spin_lock_irqsave(&clk_lock, flags);
-	list_for_each_entry(p, &clocks, node) {
-		if (strcmp(id, p->name) == 0) {
-			if (p->id == idno) {
-				if (!try_module_get(p->owner))
-					continue;
-				ret = p;
-				break;
-			} else if (p->id == -1)
-				/* remember match with id == -1 in case there is
-				 * no clock for idno */
-				retgen = p;
-		}
-	}
-
-	if (!ret && retgen && try_module_get(retgen->owner))
-		ret = retgen;
-
-	if (ret)
-		++ret->refcount;
-
-	spin_unlock_irqrestore(&clk_lock, flags);
-
-	return ret ? ret : ERR_PTR(-ENOENT);
-}
-EXPORT_SYMBOL(clk_get);
-
-void clk_put(struct clk *clk)
-{
-	module_put(clk->owner);
-	--clk->refcount;
-}
-EXPORT_SYMBOL(clk_put);
-
-static int clk_enable_unlocked(struct clk *clk)
-{
-	int ret = 0;
-	if (clk->parent) {
-		ret = clk_enable_unlocked(clk->parent);
-		if (ret)
-			return ret;
-	}
-
-	if (clk->usage++ == 0 && clk->endisable)
-		ret = clk->endisable(clk, 1);
-
-	return ret;
-}
-
-int clk_enable(struct clk *clk)
-{
-	int ret;
-	unsigned long flags;
-
-	spin_lock_irqsave(&clk_lock, flags);
-
-	ret = clk_enable_unlocked(clk);
-
-	spin_unlock_irqrestore(&clk_lock, flags);
-
-	return ret;
-}
-EXPORT_SYMBOL(clk_enable);
-
-static void clk_disable_unlocked(struct clk *clk)
-{
-	if (--clk->usage == 0 && clk->endisable)
-		clk->endisable(clk, 0);
-
-	if (clk->parent)
-		clk_disable_unlocked(clk->parent);
-}
-
-void clk_disable(struct clk *clk)
-{
-	unsigned long flags;
-
-	spin_lock_irqsave(&clk_lock, flags);
-
-	clk_disable_unlocked(clk);
-
-	spin_unlock_irqrestore(&clk_lock, flags);
-}
-EXPORT_SYMBOL(clk_disable);
-
-unsigned long clk_get_rate(struct clk *clk)
-{
-	if (clk->get_rate)
-		return clk->get_rate(clk);
-
-	if (clk->rate)
-		return clk->rate;
-
-	if (clk->parent)
-		return clk_get_rate(clk->parent);
-
-	return 0;
-}
-EXPORT_SYMBOL(clk_get_rate);
-
-int clk_register(struct clk *clk)
-{
-	unsigned long flags;
-
-	spin_lock_irqsave(&clk_lock, flags);
-
-	list_add(&clk->node, &clocks);
-
-	if (clk->parent)
-		++clk->parent->refcount;
-
-	spin_unlock_irqrestore(&clk_lock, flags);
-
-	return 0;
-}
-
-int clk_unregister(struct clk *clk)
-{
-	int ret = 0;
-	unsigned long flags;
-
-	spin_lock_irqsave(&clk_lock, flags);
-
-	if (clk->usage || clk->refcount)
-		ret = -EBUSY;
-	else
-		list_del(&clk->node);
-
-	if (clk->parent)
-		--clk->parent->refcount;
-
-	spin_unlock_irqrestore(&clk_lock, flags);
-
-	return ret;
-}
-
-#if defined CONFIG_DEBUG_FS
-
-#include <linux/debugfs.h>
-#include <linux/seq_file.h>
-
-static int clk_debugfs_show(struct seq_file *s, void *null)
-{
-	unsigned long flags;
-	struct clk *p;
-
-	spin_lock_irqsave(&clk_lock, flags);
-
-	list_for_each_entry(p, &clocks, node)
-		seq_printf(s, "%s.%d: usage=%lu refcount=%lu rate=%lu\n",
-				p->name, p->id, p->usage, p->refcount,
-				p->usage ? clk_get_rate(p) : 0);
-
-	spin_unlock_irqrestore(&clk_lock, flags);
-
-	return 0;
-}
-
-static int clk_debugfs_open(struct inode *inode, struct file *file)
-{
-	return single_open(file, clk_debugfs_show, NULL);
-}
-
-static const struct file_operations clk_debugfs_operations = {
-	.open = clk_debugfs_open,
-	.read = seq_read,
-	.llseek = seq_lseek,
-	.release = single_release,
-};
-
-static int __init clk_debugfs_init(void)
-{
-	struct dentry *dentry;
-
-	dentry = debugfs_create_file("clk", S_IFREG | S_IRUGO, NULL, NULL,
-			&clk_debugfs_operations);
-	return IS_ERR(dentry) ? PTR_ERR(dentry) : 0;
-}
-subsys_initcall(clk_debugfs_init);
-
-#endif /* if defined CONFIG_DEBUG_FS */
diff -druN linux-2.6.39-libre/arch/arm/mach-ns9xxx/clock.h linux-3.0-rc7-libre/arch/arm/mach-ns9xxx/clock.h
--- linux-2.6.39-libre/arch/arm/mach-ns9xxx/clock.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-ns9xxx/clock.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,35 +0,0 @@
-/*
- * arch/arm/mach-ns9xxx/clock.h
- *
- * Copyright (C) 2007 by Digi International 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 __NS9XXX_CLOCK_H
-#define __NS9XXX_CLOCK_H
-
-#include <linux/list.h>
-
-struct clk {
-	struct module *owner;
-	const char *name;
-	int id;
-
-	struct clk *parent;
-
-	unsigned long rate;
-	int (*endisable)(struct clk *, int enable);
-	unsigned long (*get_rate)(struct clk *);
-
-	struct list_head node;
-	unsigned long refcount;
-	unsigned long usage;
-};
-
-int clk_register(struct clk *clk);
-int clk_unregister(struct clk *clk);
-
-#endif /* ifndef __NS9XXX_CLOCK_H */
diff -druN linux-2.6.39-libre/arch/arm/mach-ns9xxx/generic.c linux-3.0-rc7-libre/arch/arm/mach-ns9xxx/generic.c
--- linux-2.6.39-libre/arch/arm/mach-ns9xxx/generic.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-ns9xxx/generic.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,19 +0,0 @@
-/*
- * arch/arm/mach-ns9xxx/generic.c
- *
- * Copyright (C) 2006,2007 by Digi International 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/kernel.h>
-#include <linux/init.h>
-#include <asm/memory.h>
-
-#include "generic.h"
-
-void __init ns9xxx_init_machine(void)
-{
-}
diff -druN linux-2.6.39-libre/arch/arm/mach-ns9xxx/generic.h linux-3.0-rc7-libre/arch/arm/mach-ns9xxx/generic.h
--- linux-2.6.39-libre/arch/arm/mach-ns9xxx/generic.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-ns9xxx/generic.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,16 +0,0 @@
-/*
- * arch/arm/mach-ns9xxx/generic.h
- *
- * Copyright (C) 2006,2007 by Digi International 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/time.h>
-#include <asm/mach/time.h>
-#include <linux/init.h>
-
-void __init ns9xxx_init_irq(void);
-void __init ns9xxx_init_machine(void);
diff -druN linux-2.6.39-libre/arch/arm/mach-ns9xxx/gpio.c linux-3.0-rc7-libre/arch/arm/mach-ns9xxx/gpio.c
--- linux-2.6.39-libre/arch/arm/mach-ns9xxx/gpio.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-ns9xxx/gpio.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,147 +0,0 @@
-/*
- * arch/arm/mach-ns9xxx/gpio.c
- *
- * Copyright (C) 2006,2007 by Digi International 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/kernel.h>
-#include <linux/compiler.h>
-#include <linux/init.h>
-#include <linux/spinlock.h>
-#include <linux/module.h>
-#include <linux/bitops.h>
-
-#include <mach/gpio.h>
-#include <mach/processor.h>
-#include <mach/processor-ns9360.h>
-#include <asm/bug.h>
-#include <asm/types.h>
-
-#include "gpio-ns9360.h"
-
-#if defined(CONFIG_PROCESSOR_NS9360)
-#define GPIO_MAX 72
-#elif defined(CONFIG_PROCESSOR_NS9750)
-#define GPIO_MAX 49
-#endif
-
-/* protects BBU_GCONFx and BBU_GCTRLx */
-static spinlock_t gpio_lock = __SPIN_LOCK_UNLOCKED(gpio_lock);
-
-/* only access gpiores with atomic ops */
-static DECLARE_BITMAP(gpiores, GPIO_MAX + 1);
-
-static inline int ns9xxx_valid_gpio(unsigned gpio)
-{
-#if defined(CONFIG_PROCESSOR_NS9360)
-	if (processor_is_ns9360())
-		return gpio <= 72;
-	else
-#endif
-#if defined(CONFIG_PROCESSOR_NS9750)
-	if (processor_is_ns9750())
-		return gpio <= 49;
-	else
-#endif
-	{
-		BUG();
-		return 0;
-	}
-}
-
-int gpio_request(unsigned gpio, const char *label)
-{
-	if (likely(ns9xxx_valid_gpio(gpio)))
-		return test_and_set_bit(gpio, gpiores) ? -EBUSY : 0;
-	else
-		return -EINVAL;
-}
-EXPORT_SYMBOL(gpio_request);
-
-void gpio_free(unsigned gpio)
-{
-	might_sleep();
-	clear_bit(gpio, gpiores);
-	return;
-}
-EXPORT_SYMBOL(gpio_free);
-
-int gpio_direction_input(unsigned gpio)
-{
-	if (likely(ns9xxx_valid_gpio(gpio))) {
-		int ret = -EINVAL;
-		unsigned long flags;
-
-		spin_lock_irqsave(&gpio_lock, flags);
-#if defined(CONFIG_PROCESSOR_NS9360)
-		if (processor_is_ns9360())
-			ret = __ns9360_gpio_configure(gpio, 0, 0, 3);
-		else
-#endif
-			BUG();
-
-		spin_unlock_irqrestore(&gpio_lock, flags);
-
-		return ret;
-
-	} else
-		return -EINVAL;
-}
-EXPORT_SYMBOL(gpio_direction_input);
-
-int gpio_direction_output(unsigned gpio, int value)
-{
-	if (likely(ns9xxx_valid_gpio(gpio))) {
-		int ret = -EINVAL;
-		unsigned long flags;
-
-		gpio_set_value(gpio, value);
-
-		spin_lock_irqsave(&gpio_lock, flags);
-#if defined(CONFIG_PROCESSOR_NS9360)
-		if (processor_is_ns9360())
-			ret = __ns9360_gpio_configure(gpio, 1, 0, 3);
-		else
-#endif
-			BUG();
-
-		spin_unlock_irqrestore(&gpio_lock, flags);
-
-		return ret;
-	} else
-		return -EINVAL;
-}
-EXPORT_SYMBOL(gpio_direction_output);
-
-int gpio_get_value(unsigned gpio)
-{
-#if defined(CONFIG_PROCESSOR_NS9360)
-	if (processor_is_ns9360())
-		return ns9360_gpio_get_value(gpio);
-	else
-#endif
-	{
-		BUG();
-		return -EINVAL;
-	}
-}
-EXPORT_SYMBOL(gpio_get_value);
-
-void gpio_set_value(unsigned gpio, int value)
-{
-	unsigned long flags;
-	spin_lock_irqsave(&gpio_lock, flags);
-#if defined(CONFIG_PROCESSOR_NS9360)
-	if (processor_is_ns9360())
-		ns9360_gpio_set_value(gpio, value);
-	else
-#endif
-		BUG();
-
-	spin_unlock_irqrestore(&gpio_lock, flags);
-}
-EXPORT_SYMBOL(gpio_set_value);
diff -druN linux-2.6.39-libre/arch/arm/mach-ns9xxx/gpio-ns9360.c linux-3.0-rc7-libre/arch/arm/mach-ns9xxx/gpio-ns9360.c
--- linux-2.6.39-libre/arch/arm/mach-ns9xxx/gpio-ns9360.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-ns9xxx/gpio-ns9360.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,118 +0,0 @@
-/*
- * arch/arm/mach-ns9xxx/gpio-ns9360.c
- *
- * Copyright (C) 2006,2007 by Digi International 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/bug.h>
-#include <linux/errno.h>
-#include <linux/io.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-
-#include <mach/regs-bbu.h>
-#include <mach/processor-ns9360.h>
-
-#include "gpio-ns9360.h"
-
-static inline int ns9360_valid_gpio(unsigned gpio)
-{
-	return gpio <= 72;
-}
-
-static inline void __iomem *ns9360_gpio_get_gconfaddr(unsigned gpio)
-{
-	if (gpio < 56)
-		return BBU_GCONFb1(gpio / 8);
-	else
-		/*
-		 * this could be optimised away on
-		 * ns9750 only builds, but it isn't ...
-		 */
-		return BBU_GCONFb2((gpio - 56) / 8);
-}
-
-static inline void __iomem *ns9360_gpio_get_gctrladdr(unsigned gpio)
-{
-	if (gpio < 32)
-		return BBU_GCTRL1;
-	else if (gpio < 64)
-		return BBU_GCTRL2;
-	else
-		/* this could be optimised away on ns9750 only builds */
-		return BBU_GCTRL3;
-}
-
-static inline void __iomem *ns9360_gpio_get_gstataddr(unsigned gpio)
-{
-	if (gpio < 32)
-		return BBU_GSTAT1;
-	else if (gpio < 64)
-		return BBU_GSTAT2;
-	else
-		/* this could be optimised away on ns9750 only builds */
-		return BBU_GSTAT3;
-}
-
-/*
- * each gpio can serve for 4 different purposes [0..3].  These are called
- * "functions" and passed in the parameter func.  Functions 0-2 are always some
- * special things, function 3 is GPIO.  If func == 3 dir specifies input or
- * output, and with inv you can enable an inverter (independent of func).
- */
-int __ns9360_gpio_configure(unsigned gpio, int dir, int inv, int func)
-{
-	void __iomem *conf = ns9360_gpio_get_gconfaddr(gpio);
-	u32 confval;
-
-	confval = __raw_readl(conf);
-	REGSETIM_IDX(confval, BBU_GCONFx, DIR, gpio & 7, dir);
-	REGSETIM_IDX(confval, BBU_GCONFx, INV, gpio & 7, inv);
-	REGSETIM_IDX(confval, BBU_GCONFx, FUNC, gpio & 7, func);
-	__raw_writel(confval, conf);
-
-	return 0;
-}
-
-int ns9360_gpio_configure(unsigned gpio, int inv, int func)
-{
-	if (likely(ns9360_valid_gpio(gpio))) {
-		if (func == 3) {
-			printk(KERN_WARNING "use gpio_direction_input "
-					"or gpio_direction_output\n");
-			return -EINVAL;
-		} else
-			return __ns9360_gpio_configure(gpio, 0, inv, func);
-	} else
-		return -EINVAL;
-}
-EXPORT_SYMBOL(ns9360_gpio_configure);
-
-int ns9360_gpio_get_value(unsigned gpio)
-{
-	void __iomem *stat = ns9360_gpio_get_gstataddr(gpio);
-	int ret;
-
-	ret = 1 & (__raw_readl(stat) >> (gpio & 31));
-
-	return ret;
-}
-
-void ns9360_gpio_set_value(unsigned gpio, int value)
-{
-	void __iomem *ctrl = ns9360_gpio_get_gctrladdr(gpio);
-	u32 ctrlval;
-
-	ctrlval = __raw_readl(ctrl);
-
-	if (value)
-		ctrlval |= 1 << (gpio & 31);
-	else
-		ctrlval &= ~(1 << (gpio & 31));
-
-	__raw_writel(ctrlval, ctrl);
-}
diff -druN linux-2.6.39-libre/arch/arm/mach-ns9xxx/gpio-ns9360.h linux-3.0-rc7-libre/arch/arm/mach-ns9xxx/gpio-ns9360.h
--- linux-2.6.39-libre/arch/arm/mach-ns9xxx/gpio-ns9360.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-ns9xxx/gpio-ns9360.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,13 +0,0 @@
-/*
- * arch/arm/mach-ns9xxx/gpio-ns9360.h
- *
- * Copyright (C) 2006,2007 by Digi International 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.
- */
-int __ns9360_gpio_configure(unsigned gpio, int dir, int inv, int func);
-int ns9360_gpio_get_value(unsigned gpio);
-void ns9360_gpio_set_value(unsigned gpio, int value);
diff -druN linux-2.6.39-libre/arch/arm/mach-ns9xxx/include/mach/board.h linux-3.0-rc7-libre/arch/arm/mach-ns9xxx/include/mach/board.h
--- linux-2.6.39-libre/arch/arm/mach-ns9xxx/include/mach/board.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-ns9xxx/include/mach/board.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,40 +0,0 @@
-/*
- * arch/arm/mach-ns9xxx/include/mach/board.h
- *
- * Copyright (C) 2006,2007 by Digi International 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_BOARD_H
-#define __ASM_ARCH_BOARD_H
-
-#include <asm/mach-types.h>
-
-#define board_is_a9m9750dev()	(0			\
-		|| machine_is_cc9p9750dev()		\
-		)
-
-#define board_is_a9mvali()	(0			\
-		|| machine_is_cc9p9750val()		\
-		)
-
-#define board_is_jscc9p9210()	(0			\
-		|| machine_is_cc9p9210js()		\
-		)
-
-#define board_is_jscc9p9215()	(0			\
-		|| machine_is_cc9p9215js()		\
-		)
-
-#define board_is_jscc9p9360()	(0			\
-		|| machine_is_cc9p9360js()		\
-		)
-
-#define board_is_uncbas()	(0			\
-		|| machine_is_cc7ucamry()		\
-		)
-
-#endif /* ifndef __ASM_ARCH_BOARD_H */
diff -druN linux-2.6.39-libre/arch/arm/mach-ns9xxx/include/mach/debug-macro.S linux-3.0-rc7-libre/arch/arm/mach-ns9xxx/include/mach/debug-macro.S
--- linux-2.6.39-libre/arch/arm/mach-ns9xxx/include/mach/debug-macro.S	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-ns9xxx/include/mach/debug-macro.S	1969-12-31 19:00:00.000000000 -0500
@@ -1,21 +0,0 @@
-/*
- * arch/arm/mach-ns9xxx/include/mach/debug-macro.S
- * Copyright (C) 2006 by Digi International 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 <mach/hardware.h>
-#include <asm/memory.h>
-
-#include <mach/regs-board-a9m9750dev.h>
-
-		.macro	addruart, rp, rv
-		ldr	\rp, =NS9XXX_CSxSTAT_PHYS(0)
-		ldr	\rv, =io_p2v(NS9XXX_CSxSTAT_PHYS(0))
-		.endm
-
-#define UART_SHIFT	2
-#include <asm/hardware/debug-8250.S>
diff -druN linux-2.6.39-libre/arch/arm/mach-ns9xxx/include/mach/entry-macro.S linux-3.0-rc7-libre/arch/arm/mach-ns9xxx/include/mach/entry-macro.S
--- linux-2.6.39-libre/arch/arm/mach-ns9xxx/include/mach/entry-macro.S	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-ns9xxx/include/mach/entry-macro.S	1969-12-31 19:00:00.000000000 -0500
@@ -1,28 +0,0 @@
-/*
- * arch/arm/mach-ns9xxx/include/mach/entry-macro.S
- *
- * Copyright (C) 2006,2007 by Digi International 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 <mach/hardware.h>
-#include <mach/regs-sys-common.h>
-
-		.macro	get_irqnr_preamble, base, tmp
-		ldr	\base, =SYS_ISRADDR
-		.endm
-
-		.macro	arch_ret_to_user, tmp1, tmp2
-		.endm
-
-		.macro	get_irqnr_and_base, irqnr, irqstat, base, tmp
-		ldr	\irqstat, [\base, #(SYS_ISA - SYS_ISRADDR)]
-		cmp	\irqstat, #0
-		ldrne	\irqnr, [\base]
-		.endm
-
-		.macro	disable_fiq
-		.endm
diff -druN linux-2.6.39-libre/arch/arm/mach-ns9xxx/include/mach/gpio.h linux-3.0-rc7-libre/arch/arm/mach-ns9xxx/include/mach/gpio.h
--- linux-2.6.39-libre/arch/arm/mach-ns9xxx/include/mach/gpio.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-ns9xxx/include/mach/gpio.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,47 +0,0 @@
-/*
- * arch/arm/mach-ns9xxx/include/mach/gpio.h
- *
- * Copyright (C) 2007 by Digi International 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_GPIO_H
-#define __ASM_ARCH_GPIO_H
-
-#include <asm/errno.h>
-
-int gpio_request(unsigned gpio, const char *label);
-
-void gpio_free(unsigned gpio);
-
-int ns9xxx_gpio_configure(unsigned gpio, int inv, int func);
-
-int gpio_direction_input(unsigned gpio);
-
-int gpio_direction_output(unsigned gpio, int value);
-
-int gpio_get_value(unsigned gpio);
-
-void gpio_set_value(unsigned gpio, int value);
-
-/*
- * ns9xxx can use gpio pins to trigger an irq, but it's not generic
- * enough to be supported by the gpio_to_irq/irq_to_gpio interface
- */
-static inline int gpio_to_irq(unsigned gpio)
-{
-	return -EINVAL;
-}
-
-static inline int irq_to_gpio(unsigned irq)
-{
-	return -EINVAL;
-}
-
-/* get the cansleep() stubs */
-#include <asm-generic/gpio.h>
-
-#endif /* ifndef __ASM_ARCH_GPIO_H */
diff -druN linux-2.6.39-libre/arch/arm/mach-ns9xxx/include/mach/hardware.h linux-3.0-rc7-libre/arch/arm/mach-ns9xxx/include/mach/hardware.h
--- linux-2.6.39-libre/arch/arm/mach-ns9xxx/include/mach/hardware.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-ns9xxx/include/mach/hardware.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,77 +0,0 @@
-/*
- * arch/arm/mach-ns9xxx/include/mach/hardware.h
- *
- * Copyright (C) 2006 by Digi International 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_HARDWARE_H
-#define __ASM_ARCH_HARDWARE_H
-
-/*
- * NetSilicon NS9xxx internal mapping:
- *
- * physical                <--> virtual
- * 0x90000000 - 0x906fffff <--> 0xf9000000 - 0xf96fffff
- * 0xa0100000 - 0xa0afffff <--> 0xfa100000 - 0xfaafffff
- */
-#define io_p2v(x)	(0xf0000000 \
-			 + (((x) & 0xf0000000) >> 4) \
-			 + ((x) & 0x00ffffff))
-
-#define io_v2p(x)	((((x) & 0x0f000000) << 4) \
-			 + ((x) & 0x00ffffff))
-
-#define __REGSHIFT(mask)	((mask) & (-(mask)))
-
-#define __REGBIT(bit)		((u32)1 << (bit))
-#define __REGBITS(hbit, lbit)	((((u32)1 << ((hbit) - (lbit) + 1)) - 1) << (lbit))
-#define __REGVAL(mask, value)	(((value) * __REGSHIFT(mask)) & (mask))
-
-#ifndef __ASSEMBLY__
-
-#  define __REG(x)	((void __iomem __force *)io_p2v((x)))
-#  define __REG2(x, y)	((void __iomem __force *)(io_p2v((x)) + 4 * (y)))
-
-#  define __REGSET(var, field, value)					\
-	((var) = (((var) & ~((field) & ~(value))) | (value)))
-
-#  define REGSET(var, reg, field, value)				\
-	__REGSET(var, reg ## _ ## field, reg ## _ ## field ## _ ## value)
-
-#  define REGSET_IDX(var, reg, field, idx, value)			\
-	__REGSET(var, reg ## _ ## field((idx)), reg ## _ ## field ## _ ## value((idx)))
-
-#  define REGSETIM(var, reg, field, value)				\
-	__REGSET(var, reg ## _ ## field, __REGVAL(reg ## _ ## field, (value)))
-
-#  define REGSETIM_IDX(var, reg, field, idx, value)			\
-	__REGSET(var, reg ## _ ## field((idx)), __REGVAL(reg ## _ ## field((idx)), (value)))
-
-#  define __REGGET(var, field)						\
-	(((var) & (field)))
-
-#  define REGGET(var, reg, field)					\
-	 __REGGET(var, reg ## _ ## field)
-
-#  define REGGET_IDX(var, reg, field, idx)				\
-	 __REGGET(var, reg ## _ ## field((idx)))
-
-#  define REGGETIM(var, reg, field)					\
-	 __REGGET(var, reg ## _ ## field) / __REGSHIFT(reg ## _ ## field)
-
-#  define REGGETIM_IDX(var, reg, field, idx)				\
-	 __REGGET(var, reg ## _ ## field((idx))) /			\
-	 __REGSHIFT(reg ## _ ## field((idx)))
-
-#else
-
-#  define __REG(x)	io_p2v(x)
-#  define __REG2(x, y)	io_p2v((x) + 4 * (y))
-
-#endif
-
-#endif /* ifndef __ASM_ARCH_HARDWARE_H */
diff -druN linux-2.6.39-libre/arch/arm/mach-ns9xxx/include/mach/io.h linux-3.0-rc7-libre/arch/arm/mach-ns9xxx/include/mach/io.h
--- linux-2.6.39-libre/arch/arm/mach-ns9xxx/include/mach/io.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-ns9xxx/include/mach/io.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,20 +0,0 @@
-/*
- * arch/arm/mach-ns9xxx/include/mach/io.h
- *
- * Copyright (C) 2006 by Digi International 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_IO_H
-#define __ASM_ARCH_IO_H
-
-#define IO_SPACE_LIMIT  0xffffffff /* XXX */
-
-#define __io(a)		__typesafe_io(a)
-#define __mem_pci(a)    (a)
-#define __mem_isa(a)    (IO_BASE + (a))
-
-#endif /* ifndef __ASM_ARCH_IO_H */
diff -druN linux-2.6.39-libre/arch/arm/mach-ns9xxx/include/mach/irqs.h linux-3.0-rc7-libre/arch/arm/mach-ns9xxx/include/mach/irqs.h
--- linux-2.6.39-libre/arch/arm/mach-ns9xxx/include/mach/irqs.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-ns9xxx/include/mach/irqs.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,86 +0,0 @@
-/*
- * arch/arm/mach-ns9xxx/include/mach/irqs.h
- *
- * Copyright (C) 2006,2007 by Digi International 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_IRQS_H
-#define __ASM_ARCH_IRQS_H
-
-/* NetSilicon 9360 */
-#define IRQ_NS9XXX_WATCHDOG	0
-#define IRQ_NS9XXX_AHBBUSERR	1
-#define IRQ_NS9360_BBUSAGG	2
-/* irq 3 is reserved for NS9360 */
-#define IRQ_NS9XXX_ETHRX	4
-#define IRQ_NS9XXX_ETHTX	5
-#define IRQ_NS9XXX_ETHPHY	6
-#define IRQ_NS9360_LCD		7
-#define IRQ_NS9360_SERBRX	8
-#define IRQ_NS9360_SERBTX	9
-#define IRQ_NS9360_SERARX	10
-#define IRQ_NS9360_SERATX	11
-#define IRQ_NS9360_SERCRX	12
-#define IRQ_NS9360_SERCTX	13
-#define IRQ_NS9360_I2C		14
-#define IRQ_NS9360_BBUSDMA	15
-#define IRQ_NS9360_TIMER0	16
-#define IRQ_NS9360_TIMER1	17
-#define IRQ_NS9360_TIMER2	18
-#define IRQ_NS9360_TIMER3	19
-#define IRQ_NS9360_TIMER4	20
-#define IRQ_NS9360_TIMER5	21
-#define IRQ_NS9360_TIMER6	22
-#define IRQ_NS9360_TIMER7	23
-#define IRQ_NS9360_RTC		24
-#define IRQ_NS9360_USBHOST	25
-#define IRQ_NS9360_USBDEVICE	26
-#define IRQ_NS9360_IEEE1284	27
-#define IRQ_NS9XXX_EXT0		28
-#define IRQ_NS9XXX_EXT1		29
-#define IRQ_NS9XXX_EXT2		30
-#define IRQ_NS9XXX_EXT3		31
-
-#define BBUS_IRQ(irq)	(32 + irq)
-
-#define IRQ_BBUS_DMA		BBUS_IRQ(0)
-#define IRQ_BBUS_SERBRX		BBUS_IRQ(2)
-#define IRQ_BBUS_SERBTX		BBUS_IRQ(3)
-#define IRQ_BBUS_SERARX		BBUS_IRQ(4)
-#define IRQ_BBUS_SERATX		BBUS_IRQ(5)
-#define IRQ_BBUS_SERCRX		BBUS_IRQ(6)
-#define IRQ_BBUS_SERCTX		BBUS_IRQ(7)
-#define IRQ_BBUS_SERDRX		BBUS_IRQ(8)
-#define IRQ_BBUS_SERDTX		BBUS_IRQ(9)
-#define IRQ_BBUS_I2C		BBUS_IRQ(10)
-#define IRQ_BBUS_1284		BBUS_IRQ(11)
-#define IRQ_BBUS_UTIL		BBUS_IRQ(12)
-#define IRQ_BBUS_RTC		BBUS_IRQ(13)
-#define IRQ_BBUS_USBHST		BBUS_IRQ(14)
-#define IRQ_BBUS_USBDEV		BBUS_IRQ(15)
-#define IRQ_BBUS_AHBDMA1	BBUS_IRQ(24)
-#define IRQ_BBUS_AHBDMA2	BBUS_IRQ(25)
-
-/*
- * these Interrupts are specific for the a9m9750dev board.
- * They are generated by an FPGA that interrupts the CPU on
- * IRQ_NS9360_EXT2
- */
-#define FPGA_IRQ(irq)	(64 + irq)
-
-#define IRQ_FPGA_UARTA		FPGA_IRQ(0)
-#define IRQ_FPGA_UARTB		FPGA_IRQ(1)
-#define IRQ_FPGA_UARTC		FPGA_IRQ(2)
-#define IRQ_FPGA_UARTD		FPGA_IRQ(3)
-#define IRQ_FPGA_TOUCH		FPGA_IRQ(4)
-#define IRQ_FPGA_CF		FPGA_IRQ(5)
-#define IRQ_FPGA_CAN0		FPGA_IRQ(6)
-#define IRQ_FPGA_CAN1		FPGA_IRQ(7)
-
-#define NR_IRQS	72
-
-#endif /* __ASM_ARCH_IRQS_H */
diff -druN linux-2.6.39-libre/arch/arm/mach-ns9xxx/include/mach/memory.h linux-3.0-rc7-libre/arch/arm/mach-ns9xxx/include/mach/memory.h
--- linux-2.6.39-libre/arch/arm/mach-ns9xxx/include/mach/memory.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-ns9xxx/include/mach/memory.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,24 +0,0 @@
-/*
- * arch/arm/mach-ns9xxx/include/mach/memory.h
- *
- * Copyright (C) 2006 by Digi International 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_MEMORY_H
-#define __ASM_ARCH_MEMORY_H
-
-/* x in [0..3] */
-#define NS9XXX_CSxSTAT_PHYS(x)	UL(((x) + 4) << 28)
-
-#define NS9XXX_CS0STAT_LENGTH	UL(0x1000)
-#define NS9XXX_CS1STAT_LENGTH	UL(0x1000)
-#define NS9XXX_CS2STAT_LENGTH	UL(0x1000)
-#define NS9XXX_CS3STAT_LENGTH	UL(0x1000)
-
-#define PLAT_PHYS_OFFSET	UL(0x00000000)
-
-#endif
diff -druN linux-2.6.39-libre/arch/arm/mach-ns9xxx/include/mach/module.h linux-3.0-rc7-libre/arch/arm/mach-ns9xxx/include/mach/module.h
--- linux-2.6.39-libre/arch/arm/mach-ns9xxx/include/mach/module.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-ns9xxx/include/mach/module.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,55 +0,0 @@
-/*
- * arch/arm/mach-ns9xxx/include/mach/module.h
- *
- * Copyright (C) 2007 by Digi International 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_MODULE_H
-#define __ASM_ARCH_MODULE_H
-
-#include <asm/mach-types.h>
-
-#define module_is_cc7ucamry()	(0			\
-		|| machine_is_cc7ucamry()		\
-		)
-
-#define module_is_cc9c()	(0			\
-		)
-
-#define module_is_cc9p9210()	(0			\
-		|| machine_is_cc9p9210()		\
-		|| machine_is_cc9p9210js()		\
-		)
-
-#define module_is_cc9p9215()	(0			\
-		|| machine_is_cc9p9215()		\
-		|| machine_is_cc9p9215js()		\
-		)
-
-#define module_is_cc9p9360()	(0			\
-		|| machine_is_cc9p9360dev()		\
-		|| machine_is_cc9p9360js()		\
-		)
-
-#define module_is_cc9p9750()	(0			\
-		|| machine_is_a9m9750()			\
-		|| machine_is_cc9p9750js()		\
-		|| machine_is_cc9p9750val()		\
-		)
-
-#define module_is_ccw9c()	(0			\
-		)
-
-#define module_is_inc20otter()	(0			\
-		|| machine_is_inc20otter()		\
-		)
-
-#define module_is_otter()	(0			\
-		|| machine_is_otter()			\
-		)
-
-#endif /* ifndef __ASM_ARCH_MODULE_H */
diff -druN linux-2.6.39-libre/arch/arm/mach-ns9xxx/include/mach/processor.h linux-3.0-rc7-libre/arch/arm/mach-ns9xxx/include/mach/processor.h
--- linux-2.6.39-libre/arch/arm/mach-ns9xxx/include/mach/processor.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-ns9xxx/include/mach/processor.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,42 +0,0 @@
-/*
- * arch/arm/mach-ns9xxx/include/mach/processor.h
- *
- * Copyright (C) 2006,2007 by Digi International 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_PROCESSOR_H
-#define __ASM_ARCH_PROCESSOR_H
-
-#include <mach/module.h>
-
-#define processor_is_ns9210()	(0			\
-		|| module_is_cc7ucamry()		\
-		|| module_is_cc9p9210()			\
-		|| module_is_inc20otter()		\
-		|| module_is_otter()			\
-		)
-
-#define processor_is_ns9215()	(0			\
-		|| module_is_cc9p9215()			\
-		)
-
-#define processor_is_ns9360()	(0			\
-		|| module_is_cc9p9360()			\
-		|| module_is_cc9c()			\
-		|| module_is_ccw9c()			\
-		)
-
-#define processor_is_ns9750()	(0			\
-		|| module_is_cc9p9750()			\
-		)
-
-#define processor_is_ns921x()	(0			\
-		|| processor_is_ns9210()		\
-		|| processor_is_ns9215()		\
-		)
-
-#endif /* ifndef __ASM_ARCH_PROCESSOR_H */
diff -druN linux-2.6.39-libre/arch/arm/mach-ns9xxx/include/mach/processor-ns9360.h linux-3.0-rc7-libre/arch/arm/mach-ns9xxx/include/mach/processor-ns9360.h
--- linux-2.6.39-libre/arch/arm/mach-ns9xxx/include/mach/processor-ns9360.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-ns9xxx/include/mach/processor-ns9360.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,32 +0,0 @@
-/*
- * arch/arm/mach-ns9xxx/include/mach/processor-ns9360.h
- *
- * Copyright (C) 2007 by Digi International 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_PROCESSORNS9360_H
-#define __ASM_ARCH_PROCESSORNS9360_H
-
-#include <linux/init.h>
-
-void ns9360_reset(char mode);
-
-unsigned long ns9360_systemclock(void) __attribute__((const));
-
-static inline unsigned long ns9360_cpuclock(void) __attribute__((const));
-static inline unsigned long ns9360_cpuclock(void)
-{
-	return ns9360_systemclock() / 2;
-}
-
-void __init ns9360_map_io(void);
-
-extern struct sys_timer ns9360_timer;
-
-int ns9360_gpio_configure(unsigned gpio, int inv, int func);
-
-#endif /* ifndef __ASM_ARCH_PROCESSORNS9360_H */
diff -druN linux-2.6.39-libre/arch/arm/mach-ns9xxx/include/mach/regs-bbu.h linux-3.0-rc7-libre/arch/arm/mach-ns9xxx/include/mach/regs-bbu.h
--- linux-2.6.39-libre/arch/arm/mach-ns9xxx/include/mach/regs-bbu.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-ns9xxx/include/mach/regs-bbu.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,45 +0,0 @@
-/*
- * arch/arm/mach-ns9xxx/include/mach/regs-bbu.h
- *
- * Copyright (C) 2006 by Digi International 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_REGSBBU_H
-#define __ASM_ARCH_REGSBBU_H
-
-#include <mach/hardware.h>
-
-/* BBus Utility */
-
-/* GPIO Configuration Registers block 1 */
-/* NOTE: the HRM starts counting at 1 for the GPIO registers, here the start is
- * at 0 for each block.  That is, BBU_GCONFb1(0) is GPIO Configuration Register
- * #1, BBU_GCONFb2(0) is GPIO Configuration Register #8. */
-#define BBU_GCONFb1(x)	__REG2(0x90600010, (x))
-#define BBU_GCONFb2(x)	__REG2(0x90600100, (x))
-
-#define BBU_GCONFx_DIR(m)	__REGBIT(3 + (((m) & 7) << 2))
-#define BBU_GCONFx_DIR_INPUT(m)	__REGVAL(BBU_GCONFx_DIR(m), 0)
-#define BBU_GCONFx_DIR_OUTPUT(m)	__REGVAL(BBU_GCONFx_DIR(m), 1)
-#define BBU_GCONFx_INV(m)	__REGBIT(2 + (((m) & 7) << 2))
-#define BBU_GCONFx_INV_NO(m)		__REGVAL(BBU_GCONFx_INV(m), 0)
-#define BBU_GCONFx_INV_YES(m)		__REGVAL(BBU_GCONFx_INV(m), 1)
-#define BBU_GCONFx_FUNC(m)	__REGBITS(1 + (((m) & 7) << 2), ((m) & 7) << 2)
-#define BBU_GCONFx_FUNC_0(m)		__REGVAL(BBU_GCONFx_FUNC(m), 0)
-#define BBU_GCONFx_FUNC_1(m)		__REGVAL(BBU_GCONFx_FUNC(m), 1)
-#define BBU_GCONFx_FUNC_2(m)		__REGVAL(BBU_GCONFx_FUNC(m), 2)
-#define BBU_GCONFx_FUNC_3(m)		__REGVAL(BBU_GCONFx_FUNC(m), 3)
-
-#define BBU_GCTRL1	__REG(0x90600030)
-#define BBU_GCTRL2	__REG(0x90600034)
-#define BBU_GCTRL3	__REG(0x90600120)
-
-#define BBU_GSTAT1	__REG(0x90600040)
-#define BBU_GSTAT2	__REG(0x90600044)
-#define BBU_GSTAT3	__REG(0x90600130)
-
-#endif /* ifndef __ASM_ARCH_REGSBBU_H */
diff -druN linux-2.6.39-libre/arch/arm/mach-ns9xxx/include/mach/regs-board-a9m9750dev.h linux-3.0-rc7-libre/arch/arm/mach-ns9xxx/include/mach/regs-board-a9m9750dev.h
--- linux-2.6.39-libre/arch/arm/mach-ns9xxx/include/mach/regs-board-a9m9750dev.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-ns9xxx/include/mach/regs-board-a9m9750dev.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,24 +0,0 @@
-/*
- * arch/arm/mach-ns9xxx/include/mach/regs-board-a9m9750dev.h
- *
- * Copyright (C) 2006 by Digi International 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_REGSBOARDA9M9750_H
-#define __ASM_ARCH_REGSBOARDA9M9750_H
-
-#include <mach/hardware.h>
-
-#define FPGA_UARTA_BASE	io_p2v(NS9XXX_CSxSTAT_PHYS(0))
-#define FPGA_UARTB_BASE	io_p2v(NS9XXX_CSxSTAT_PHYS(0) + 0x08)
-#define FPGA_UARTC_BASE	io_p2v(NS9XXX_CSxSTAT_PHYS(0) + 0x10)
-#define FPGA_UARTD_BASE	io_p2v(NS9XXX_CSxSTAT_PHYS(0) + 0x18)
-
-#define FPGA_IER	__REG(NS9XXX_CSxSTAT_PHYS(0) + 0x50)
-#define FPGA_ISR	__REG(NS9XXX_CSxSTAT_PHYS(0) + 0x60)
-
-#endif /* ifndef __ASM_ARCH_REGSBOARDA9M9750_H */
diff -druN linux-2.6.39-libre/arch/arm/mach-ns9xxx/include/mach/regs-mem.h linux-3.0-rc7-libre/arch/arm/mach-ns9xxx/include/mach/regs-mem.h
--- linux-2.6.39-libre/arch/arm/mach-ns9xxx/include/mach/regs-mem.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-ns9xxx/include/mach/regs-mem.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,135 +0,0 @@
-/*
- * arch/arm/mach-ns9xxx/include/mach/regs-mem.h
- *
- * Copyright (C) 2006 by Digi International 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_REGSMEM_H
-#define __ASM_ARCH_REGSMEM_H
-
-#include <mach/hardware.h>
-
-/* Memory Module */
-
-/* Control register */
-#define MEM_CTRL	__REG(0xa0700000)
-
-/* Status register */
-#define MEM_STAT	__REG(0xa0700004)
-
-/* Configuration register */
-#define MEM_CONF	__REG(0xa0700008)
-
-/* Dynamic Memory Control register */
-#define MEM_DMCTRL	__REG(0xa0700020)
-
-/* Dynamic Memory Refresh Timer */
-#define MEM_DMRT	__REG(0xa0700024)
-
-/* Dynamic Memory Read Configuration register */
-#define MEM_DMRC	__REG(0xa0700028)
-
-/* Dynamic Memory Precharge Command Period (tRP) */
-#define MEM_DMPCP	__REG(0xa0700030)
-
-/* Dynamic Memory Active to Precharge Command Period (tRAS) */
-#define MEM_DMAPCP	__REG(0xa0700034)
-
-/* Dynamic Memory Self-Refresh Exit Time (tSREX) */
-#define MEM_DMSRET	__REG(0xa0700038)
-
-/* Dynamic Memory Last Data Out to Active Time (tAPR) */
-#define MEM_DMLDOAT	__REG(0xa070003c)
-
-/* Dynamic Memory Data-in to Active Command Time (tDAL or TAPW) */
-#define MEM_DMDIACT	__REG(0xa0700040)
-
-/* Dynamic Memory Write Recovery Time (tWR, tDPL, tRWL, tRDL) */
-#define MEM_DMWRT	__REG(0xa0700044)
-
-/* Dynamic Memory Active to Active Command Period (tRC) */
-#define MEM_DMAACP	__REG(0xa0700048)
-
-/* Dynamic Memory Auto Refresh Period, and Auto Refresh to Active Command Period (tRFC) */
-#define MEM_DMARP	__REG(0xa070004c)
-
-/* Dynamic Memory Exit Self-Refresh to Active Command (tXSR) */
-#define MEM_DMESRAC	__REG(0xa0700050)
-
-/* Dynamic Memory Active Bank A to Active B Time (tRRD) */
-#define MEM_DMABAABT	__REG(0xa0700054)
-
-/* Dynamic Memory Load Mode register to Active Command Time (tMRD) */
-#define MEM_DMLMACT	__REG(0xa0700058)
-
-/* Static Memory Extended Wait */
-#define MEM_SMEW	__REG(0xa0700080)
-
-/* Dynamic Memory Configuration Register x */
-#define MEM_DMCONF(x) 	__REG2(0xa0700100, (x) << 3)
-
-/* Dynamic Memory RAS and CAS Delay x */
-#define MEM_DMRCD(x)	__REG2(0xa0700104, (x) << 3)
-
-/* Static Memory Configuration Register x */
-#define MEM_SMC(x)	__REG2(0xa0700200, (x) << 3)
-
-/* Static Memory Configuration Register x: Write protect */
-#define MEM_SMC_PSMC		__REGBIT(20)
-#define MEM_SMC_PSMC_OFF		__REGVAL(MEM_SMC_PSMC, 0)
-#define MEM_SMC_PSMC_ON			__REGVAL(MEM_SMC_PSMC, 1)
-
-/* Static Memory Configuration Register x: Buffer enable */
-#define MEM_SMC_BSMC		__REGBIT(19)
-#define MEM_SMC_BSMC_OFF		__REGVAL(MEM_SMC_BSMC, 0)
-#define MEM_SMC_BSMC_ON			__REGVAL(MEM_SMC_BSMC, 1)
-
-/* Static Memory Configuration Register x: Extended Wait */
-#define MEM_SMC_EW		__REGBIT(8)
-#define MEM_SMC_EW_OFF			__REGVAL(MEM_SMC_EW, 0)
-#define MEM_SMC_EW_ON			__REGVAL(MEM_SMC_EW, 1)
-
-/* Static Memory Configuration Register x: Byte lane state */
-#define MEM_SMC_PB		__REGBIT(7)
-#define MEM_SMC_PB_0			__REGVAL(MEM_SMC_PB, 0)
-#define MEM_SMC_PB_1			__REGVAL(MEM_SMC_PB, 1)
-
-/* Static Memory Configuration Register x: Chip select polarity */
-#define MEM_SMC_PC		__REGBIT(6)
-#define MEM_SMC_PC_AL			__REGVAL(MEM_SMC_PC, 0)
-#define MEM_SMC_PC_AH			__REGVAL(MEM_SMC_PC, 1)
-
-/* static memory configuration register x: page mode*/
-#define MEM_SMC_PM		__REGBIT(3)
-#define MEM_SMC_PM_DIS			__REGVAL(MEM_SMC_PM, 0)
-#define MEM_SMC_PM_ASYNC		__REGVAL(MEM_SMC_PM, 1)
-
-/* static memory configuration register x: Memory width */
-#define MEM_SMC_MW		__REGBITS(1, 0)
-#define MEM_SMC_MW_8			__REGVAL(MEM_SMC_MW, 0)
-#define MEM_SMC_MW_16			__REGVAL(MEM_SMC_MW, 1)
-#define MEM_SMC_MW_32			__REGVAL(MEM_SMC_MW, 2)
-
-/* Static Memory Write Enable Delay x */
-#define MEM_SMWED(x)	__REG2(0xa0700204, (x) << 3)
-
-/* Static Memory Output Enable Delay x */
-#define MEM_SMOED(x)	__REG2(0xa0700208, (x) << 3)
-
-/* Static Memory Read Delay x */
-#define MEM_SMRD(x)	__REG2(0xa070020c, (x) << 3)
-
-/* Static Memory Page Mode Read Delay 0 */
-#define MEM_SMPMRD(x)	__REG2(0xa0700210, (x) << 3)
-
-/* Static Memory Write Delay */
-#define MEM_SMWD(x)	__REG2(0xa0700214, (x) << 3)
-
-/* Static Memory Turn Round Delay x */
-#define MEM_SWT(x)	__REG2(0xa0700218, (x) << 3)
-
-#endif /* ifndef __ASM_ARCH_REGSMEM_H */
diff -druN linux-2.6.39-libre/arch/arm/mach-ns9xxx/include/mach/regs-sys-common.h linux-3.0-rc7-libre/arch/arm/mach-ns9xxx/include/mach/regs-sys-common.h
--- linux-2.6.39-libre/arch/arm/mach-ns9xxx/include/mach/regs-sys-common.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-ns9xxx/include/mach/regs-sys-common.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,31 +0,0 @@
-/*
- * arch/arm/mach-ns9xxx/include/mach/regs-sys-common.h
- *
- * Copyright (C) 2007 by Digi International 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_REGSSYSCOMMON_H
-#define __ASM_ARCH_REGSSYSCOMMON_H
-#include <mach/hardware.h>
-
-/* Interrupt Vector Address Register Level x */
-#define SYS_IVA(x)	__REG2(0xa09000c4, (x))
-
-/* Interrupt Configuration registers */
-#define SYS_IC(x)	__REG2(0xa0900144, (x))
-
-/* ISRADDR */
-#define SYS_ISRADDR     __REG(0xa0900164)
-
-/* Interrupt Status Active */
-#define SYS_ISA		__REG(0xa0900168)
-
-/* Interrupt Status Raw */
-#define SYS_ISR		__REG(0xa090016c)
-
-#endif /* ifndef __ASM_ARCH_REGSSYSCOMMON_H */
diff -druN linux-2.6.39-libre/arch/arm/mach-ns9xxx/include/mach/regs-sys-ns9360.h linux-3.0-rc7-libre/arch/arm/mach-ns9xxx/include/mach/regs-sys-ns9360.h
--- linux-2.6.39-libre/arch/arm/mach-ns9xxx/include/mach/regs-sys-ns9360.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-ns9xxx/include/mach/regs-sys-ns9360.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,148 +0,0 @@
-/*
- * arch/arm/mach-ns9xxx/include/mach/regs-sys-ns9360.h
- *
- * Copyright (C) 2006,2007 by Digi International 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_REGSSYSNS9360_H
-#define __ASM_ARCH_REGSSYSNS9360_H
-
-#include <mach/hardware.h>
-
-/* System Control Module */
-
-/* AHB Arbiter Gen Configuration */
-#define SYS_AHBAGENCONF	__REG(0xa0900000)
-
-/* BRC */
-#define SYS_BRC(x)	__REG2(0xa0900004, (x))
-
-/* Timer x Reload Count register */
-#define SYS_TRC(x)	__REG2(0xa0900044, (x))
-
-/* Timer x Read register */
-#define SYS_TR(x)	__REG2(0xa0900084, (x))
-
-/* Timer Interrupt Status register */
-#define SYS_TIS		__REG(0xa0900170)
-
-/* PLL Configuration register */
-#define SYS_PLL		__REG(0xa0900188)
-
-/* PLL FS status */
-#define SYS_PLL_FS		__REGBITS(24, 23)
-
-/* PLL ND status */
-#define SYS_PLL_ND		__REGBITS(20, 16)
-
-/* PLL Configuration register: PLL SW change */
-#define SYS_PLL_SWC		__REGBIT(15)
-#define SYS_PLL_SWC_NO			__REGVAL(SYS_PLL_SWC, 0)
-#define SYS_PLL_SWC_YES			__REGVAL(SYS_PLL_SWC, 1)
-
-/* Timer x Control register */
-#define SYS_TC(x)	__REG2(0xa0900190, (x))
-
-/* Timer x Control register: Timer enable */
-#define SYS_TCx_TEN		__REGBIT(15)
-#define SYS_TCx_TEN_DIS			__REGVAL(SYS_TCx_TEN, 0)
-#define SYS_TCx_TEN_EN			__REGVAL(SYS_TCx_TEN, 1)
-
-/* Timer x Control register: CPU debug mode */
-#define SYS_TCx_TDBG		__REGBIT(10)
-#define SYS_TCx_TDBG_CONT		__REGVAL(SYS_TCx_TDBG, 0)
-#define SYS_TCx_TDBG_STOP		__REGVAL(SYS_TCx_TDBG, 1)
-
-/* Timer x Control register: Interrupt clear */
-#define SYS_TCx_INTC		__REGBIT(9)
-#define SYS_TCx_INTC_UNSET		__REGVAL(SYS_TCx_INTC, 0)
-#define SYS_TCx_INTC_SET		__REGVAL(SYS_TCx_INTC, 1)
-
-/* Timer x Control register: Timer clock select */
-#define SYS_TCx_TLCS		__REGBITS(8, 6)
-#define SYS_TCx_TLCS_CPU		__REGVAL(SYS_TCx_TLCS, 0)	/* CPU clock */
-#define SYS_TCx_TLCS_DIV2		__REGVAL(SYS_TCx_TLCS, 1)	/* CPU clock / 2 */
-#define SYS_TCx_TLCS_DIV4		__REGVAL(SYS_TCx_TLCS, 2)	/* CPU clock / 4 */
-#define SYS_TCx_TLCS_DIV8		__REGVAL(SYS_TCx_TLCS, 3)	/* CPU clock / 8 */
-#define SYS_TCx_TLCS_DIV16		__REGVAL(SYS_TCx_TLCS, 4)	/* CPU clock / 16 */
-#define SYS_TCx_TLCS_DIV32		__REGVAL(SYS_TCx_TLCS, 5)	/* CPU clock / 32 */
-#define SYS_TCx_TLCS_DIV64		__REGVAL(SYS_TCx_TLCS, 6)	/* CPU clock / 64 */
-#define SYS_TCx_TLCS_EXT		__REGVAL(SYS_TCx_TLCS, 7)
-
-/* Timer x Control register: Timer mode */
-#define SYS_TCx_TM		__REGBITS(5, 4)
-#define SYS_TCx_TM_IEE			__REGVAL(SYS_TCx_TM, 0)		/* Internal timer or external event */
-#define SYS_TCx_TM_ELL			__REGVAL(SYS_TCx_TM, 1)		/* External low-level, gated timer */
-#define SYS_TCx_TM_EHL			__REGVAL(SYS_TCx_TM, 2)		/* External high-level, gated timer */
-#define SYS_TCx_TM_CONCAT		__REGVAL(SYS_TCx_TM, 3)		/* Concatenate the lower timer. */
-
-/* Timer x Control register: Interrupt select */
-#define SYS_TCx_INTS		__REGBIT(3)
-#define SYS_TCx_INTS_DIS		__REGVAL(SYS_TCx_INTS, 0)
-#define SYS_TCx_INTS_EN			__REGVAL(SYS_TCx_INTS, 1)
-
-/* Timer x Control register: Up/down select */
-#define SYS_TCx_UDS		__REGBIT(2)
-#define SYS_TCx_UDS_UP			__REGVAL(SYS_TCx_UDS, 0)
-#define SYS_TCx_UDS_DOWN		__REGVAL(SYS_TCx_UDS, 1)
-
-/* Timer x Control register: 32- or 16-bit timer */
-#define SYS_TCx_TSZ		__REGBIT(1)
-#define SYS_TCx_TSZ_16			__REGVAL(SYS_TCx_TSZ, 0)
-#define SYS_TCx_TSZ_32			__REGVAL(SYS_TCx_TSZ, 1)
-
-/* Timer x Control register: Reload enable */
-#define SYS_TCx_REN		__REGBIT(0)
-#define SYS_TCx_REN_DIS			__REGVAL(SYS_TCx_REN, 0)
-#define SYS_TCx_REN_EN			__REGVAL(SYS_TCx_REN, 1)
-
-/* System Memory Chip Select x Dynamic Memory Base */
-#define SYS_SMCSDMB(x)	__REG2(0xa09001d0, (x) << 1)
-
-/* System Memory Chip Select x Dynamic Memory Mask */
-#define SYS_SMCSDMM(x)	__REG2(0xa09001d4, (x) << 1)
-
-/* System Memory Chip Select x Static Memory Base */
-#define SYS_SMCSSMB(x)	__REG2(0xa09001f0, (x) << 1)
-
-/* System Memory Chip Select x Static Memory Base: Chip select x base */
-#define SYS_SMCSSMB_CSxB	__REGBITS(31, 12)
-
-/* System Memory Chip Select x Static Memory Mask */
-#define SYS_SMCSSMM(x)	__REG2(0xa09001f4, (x) << 1)
-
-/* System Memory Chip Select x Static Memory Mask: Chip select x mask */
-#define SYS_SMCSSMM_CSxM	__REGBITS(31, 12)
-
-/* System Memory Chip Select x Static Memory Mask: Chip select x enable */
-#define SYS_SMCSSMM_CSEx	__REGBIT(0)
-#define SYS_SMCSSMM_CSEx_DIS		__REGVAL(SYS_SMCSSMM_CSEx, 0)
-#define SYS_SMCSSMM_CSEx_EN		__REGVAL(SYS_SMCSSMM_CSEx, 1)
-
-/* General purpose, user-defined ID register */
-#define SYS_GENID	__REG(0xa0900210)
-
-/* External Interrupt x Control register */
-#define SYS_EIC(x)	__REG2(0xa0900214, (x))
-
-/* External Interrupt x Control register: Status */
-#define SYS_EIC_STS		__REGBIT(3)
-
-/* External Interrupt x Control register: Clear */
-#define SYS_EIC_CLR		__REGBIT(2)
-
-/* External Interrupt x Control register: Polarity */
-#define SYS_EIC_PLTY		__REGBIT(1)
-#define SYS_EIC_PLTY_AH			__REGVAL(SYS_EIC_PLTY, 0)
-#define SYS_EIC_PLTY_AL			__REGVAL(SYS_EIC_PLTY, 1)
-
-/* External Interrupt x Control register: Level edge */
-#define SYS_EIC_LVEDG		__REGBIT(0)
-#define SYS_EIC_LVEDG_LEVEL		__REGVAL(SYS_EIC_LVEDG, 0)
-#define SYS_EIC_LVEDG_EDGE		__REGVAL(SYS_EIC_LVEDG, 1)
-
-#endif /* ifndef __ASM_ARCH_REGSSYSNS9360_H */
diff -druN linux-2.6.39-libre/arch/arm/mach-ns9xxx/include/mach/system.h linux-3.0-rc7-libre/arch/arm/mach-ns9xxx/include/mach/system.h
--- linux-2.6.39-libre/arch/arm/mach-ns9xxx/include/mach/system.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-ns9xxx/include/mach/system.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,35 +0,0 @@
-/*
- * arch/arm/mach-ns9xxx/include/mach/system.h
- *
- * Copyright (C) 2006,2007 by Digi International 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_SYSTEM_H
-#define __ASM_ARCH_SYSTEM_H
-
-#include <asm/proc-fns.h>
-#include <mach/processor.h>
-#include <mach/processor-ns9360.h>
-
-static inline void arch_idle(void)
-{
-	cpu_do_idle();
-}
-
-static inline void arch_reset(char mode, const char *cmd)
-{
-#ifdef CONFIG_PROCESSOR_NS9360
-	if (processor_is_ns9360())
-		ns9360_reset(mode);
-	else
-#endif
-		BUG();
-
-	BUG();
-}
-
-#endif /* ifndef __ASM_ARCH_SYSTEM_H */
diff -druN linux-2.6.39-libre/arch/arm/mach-ns9xxx/include/mach/timex.h linux-3.0-rc7-libre/arch/arm/mach-ns9xxx/include/mach/timex.h
--- linux-2.6.39-libre/arch/arm/mach-ns9xxx/include/mach/timex.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-ns9xxx/include/mach/timex.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,20 +0,0 @@
-/*
- * arch/arm/mach-ns9xxx/include/mach/timex.h
- *
- * Copyright (C) 2005-2006 by Digi International 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_TIMEX_H
-#define __ASM_ARCH_TIMEX_H
-
-/*
- * value for CLOCK_TICK_RATE stolen from arch/arm/mach-s3c2410/include/mach/timex.h.
- * See there for an explanation.
- */
-#define CLOCK_TICK_RATE         12000000
-
-#endif /* ifndef __ASM_ARCH_TIMEX_H */
diff -druN linux-2.6.39-libre/arch/arm/mach-ns9xxx/include/mach/uncompress.h linux-3.0-rc7-libre/arch/arm/mach-ns9xxx/include/mach/uncompress.h
--- linux-2.6.39-libre/arch/arm/mach-ns9xxx/include/mach/uncompress.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-ns9xxx/include/mach/uncompress.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,164 +0,0 @@
-/*
- * arch/arm/mach-ns9xxx/include/mach/uncompress.h
- *
- * Copyright (C) 2006 by Digi International 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_UNCOMPRESS_H
-#define __ASM_ARCH_UNCOMPRESS_H
-
-#include <linux/io.h>
-
-#define __REG(x)	((void __iomem __force *)(x))
-
-static void putc_dummy(char c, void __iomem *base)
-{
-	/* nothing */
-}
-
-static int timeout;
-
-static void putc_ns9360(char c, void __iomem *base)
-{
-	do {
-		if (timeout)
-			--timeout;
-
-		if (__raw_readl(base + 8) & (1 << 3)) {
-			__raw_writeb(c, base + 16);
-			timeout = 0x10000;
-			break;
-		}
-	} while (timeout);
-}
-
-static void putc_a9m9750dev(char c, void __iomem *base)
-{
-	do {
-		if (timeout)
-			--timeout;
-
-		if (__raw_readb(base + 5) & (1 << 5)) {
-			__raw_writeb(c, base);
-			timeout = 0x10000;
-			break;
-		}
-	} while (timeout);
-
-}
-
-static void putc_ns921x(char c, void __iomem *base)
-{
-	do {
-		if (timeout)
-			--timeout;
-
-		if (!(__raw_readl(base) & (1 << 11))) {
-			__raw_writeb(c, base + 0x0028);
-			timeout = 0x10000;
-			break;
-		}
-	} while (timeout);
-}
-
-#define MSCS __REG(0xA0900184)
-
-#define NS9360_UARTA	__REG(0x90200040)
-#define NS9360_UARTB	__REG(0x90200000)
-#define NS9360_UARTC	__REG(0x90300000)
-#define NS9360_UARTD	__REG(0x90300040)
-
-#define NS9360_UART_ENABLED(base)					\
-		(__raw_readl(NS9360_UARTA) & (1 << 31))
-
-#define A9M9750DEV_UARTA	__REG(0x40000000)
-
-#define NS921XSYS_CLOCK	__REG(0xa090017c)
-#define NS921X_UARTA	__REG(0x90010000)
-#define NS921X_UARTB	__REG(0x90018000)
-#define NS921X_UARTC	__REG(0x90020000)
-#define NS921X_UARTD	__REG(0x90028000)
-
-#define NS921X_UART_ENABLED(base)					\
-		(__raw_readl((base) + 0x1000) & (1 << 29))
-
-static void autodetect(void (**putc)(char, void __iomem *), void __iomem **base)
-{
-	timeout = 0x10000;
-	if (((__raw_readl(MSCS) >> 16) & 0xfe) == 0x00) {
-		/* ns9360 or ns9750 */
-		if (NS9360_UART_ENABLED(NS9360_UARTA)) {
-			*putc = putc_ns9360;
-			*base = NS9360_UARTA;
-			return;
-		} else if (NS9360_UART_ENABLED(NS9360_UARTB)) {
-			*putc = putc_ns9360;
-			*base = NS9360_UARTB;
-			return;
-		} else if (NS9360_UART_ENABLED(NS9360_UARTC)) {
-			*putc = putc_ns9360;
-			*base = NS9360_UARTC;
-			return;
-		} else if (NS9360_UART_ENABLED(NS9360_UARTD)) {
-			*putc = putc_ns9360;
-			*base = NS9360_UARTD;
-			return;
-		} else if (__raw_readl(__REG(0xa09001f4)) == 0xfffff001) {
-			*putc = putc_a9m9750dev;
-			*base = A9M9750DEV_UARTA;
-			return;
-		}
-	} else if (((__raw_readl(MSCS) >> 16) & 0xfe) == 0x02) {
-		/* ns921x */
-		u32 clock = __raw_readl(NS921XSYS_CLOCK);
-
-		if ((clock & (1 << 1)) &&
-				NS921X_UART_ENABLED(NS921X_UARTA)) {
-			*putc = putc_ns921x;
-			*base = NS921X_UARTA;
-			return;
-		} else if ((clock & (1 << 2)) &&
-				NS921X_UART_ENABLED(NS921X_UARTB)) {
-			*putc = putc_ns921x;
-			*base = NS921X_UARTB;
-			return;
-		} else if ((clock & (1 << 3)) &&
-				NS921X_UART_ENABLED(NS921X_UARTC)) {
-			*putc = putc_ns921x;
-			*base = NS921X_UARTC;
-			return;
-		} else if ((clock & (1 << 4)) &&
-				NS921X_UART_ENABLED(NS921X_UARTD)) {
-			*putc = putc_ns921x;
-			*base = NS921X_UARTD;
-			return;
-		}
-	}
-
-	*putc = putc_dummy;
-}
-
-void (*myputc)(char, void __iomem *);
-void __iomem *base;
-
-static void putc(char c)
-{
-	myputc(c, base);
-}
-
-static void arch_decomp_setup(void)
-{
-	autodetect(&myputc, &base);
-}
-#define arch_decomp_wdog()
-
-static void flush(void)
-{
-	/* nothing */
-}
-
-#endif /* ifndef __ASM_ARCH_UNCOMPRESS_H */
diff -druN linux-2.6.39-libre/arch/arm/mach-ns9xxx/include/mach/vmalloc.h linux-3.0-rc7-libre/arch/arm/mach-ns9xxx/include/mach/vmalloc.h
--- linux-2.6.39-libre/arch/arm/mach-ns9xxx/include/mach/vmalloc.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-ns9xxx/include/mach/vmalloc.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,16 +0,0 @@
-/*
- * arch/arm/mach-ns9xxx/include/mach/vmalloc.h
- *
- * Copyright (C) 2006 by Digi International 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_VMALLOC_H
-#define __ASM_ARCH_VMALLOC_H
-
-#define VMALLOC_END     (0xf0000000UL)
-
-#endif /* ifndef __ASM_ARCH_VMALLOC_H */
diff -druN linux-2.6.39-libre/arch/arm/mach-ns9xxx/irq.c linux-3.0-rc7-libre/arch/arm/mach-ns9xxx/irq.c
--- linux-2.6.39-libre/arch/arm/mach-ns9xxx/irq.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-ns9xxx/irq.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,74 +0,0 @@
-/*
- * arch/arm/mach-ns9xxx/irq.c
- *
- * Copyright (C) 2006,2007 by Digi International 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/interrupt.h>
-#include <linux/kernel_stat.h>
-#include <linux/io.h>
-#include <asm/mach/irq.h>
-#include <mach/regs-sys-common.h>
-#include <mach/irqs.h>
-#include <mach/board.h>
-
-#include "generic.h"
-
-/* simple interrupt prio table: prio(x) < prio(y) <=> x < y */
-#define irq2prio(i) (i)
-#define prio2irq(p) (p)
-
-static void ns9xxx_mask_irq(struct irq_data *d)
-{
-	/* XXX: better use cpp symbols */
-	int prio = irq2prio(d->irq);
-	u32 ic = __raw_readl(SYS_IC(prio / 4));
-	ic &= ~(1 << (7 + 8 * (3 - (prio & 3))));
-	__raw_writel(ic, SYS_IC(prio / 4));
-}
-
-static void ns9xxx_eoi_irq(struct irq_data *d)
-{
-	__raw_writel(0, SYS_ISRADDR);
-}
-
-static void ns9xxx_unmask_irq(struct irq_data *d)
-{
-	/* XXX: better use cpp symbols */
-	int prio = irq2prio(d->irq);
-	u32 ic = __raw_readl(SYS_IC(prio / 4));
-	ic |= 1 << (7 + 8 * (3 - (prio & 3)));
-	__raw_writel(ic, SYS_IC(prio / 4));
-}
-
-static struct irq_chip ns9xxx_chip = {
-	.irq_eoi	= ns9xxx_eoi_irq,
-	.irq_mask	= ns9xxx_mask_irq,
-	.irq_unmask	= ns9xxx_unmask_irq,
-};
-
-void __init ns9xxx_init_irq(void)
-{
-	int i;
-
-	/* disable all IRQs */
-	for (i = 0; i < 8; ++i)
-		__raw_writel(prio2irq(4 * i) << 24 |
-				prio2irq(4 * i + 1) << 16 |
-				prio2irq(4 * i + 2) << 8 |
-				prio2irq(4 * i + 3),
-				SYS_IC(i));
-
-	for (i = 0; i < 32; ++i)
-		__raw_writel(prio2irq(i), SYS_IVA(i));
-
-	for (i = 0; i <= 31; ++i) {
-		irq_set_chip_and_handler(i, &ns9xxx_chip, handle_fasteoi_irq);
-		set_irq_flags(i, IRQF_VALID);
-		irq_set_status_flags(i, IRQ_LEVEL);
-	}
-}
diff -druN linux-2.6.39-libre/arch/arm/mach-ns9xxx/Kconfig linux-3.0-rc7-libre/arch/arm/mach-ns9xxx/Kconfig
--- linux-2.6.39-libre/arch/arm/mach-ns9xxx/Kconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-ns9xxx/Kconfig	1969-12-31 19:00:00.000000000 -0500
@@ -1,40 +0,0 @@
-if ARCH_NS9XXX
-
-menu "NS9xxx Implementations"
-
-config NS9XXX_HAVE_SERIAL8250
-	bool
-
-config PROCESSOR_NS9360
-	bool
-
-config MODULE_CC9P9360
-	bool
-	select PROCESSOR_NS9360
-
-config BOARD_A9M9750DEV
-	select NS9XXX_HAVE_SERIAL8250
-	bool
-
-config BOARD_JSCC9P9360
-	bool
-
-config MACH_CC9P9360DEV
-	bool "ConnectCore 9P 9360 on an A9M9750 Devboard"
-	select MODULE_CC9P9360
-	select BOARD_A9M9750DEV
-	help
-	  Say Y here if you are using the Digi ConnectCore 9P 9360
-	  on an A9M9750 Development Board.
-
-config MACH_CC9P9360JS
-	bool "ConnectCore 9P 9360 on a JSCC9P9360 Devboard"
-	select MODULE_CC9P9360
-	select BOARD_JSCC9P9360
-	help
-	  Say Y here if you are using the Digi ConnectCore 9P 9360
-	  on an JSCC9P9360 Development Board.
-
-endmenu
-
-endif
diff -druN linux-2.6.39-libre/arch/arm/mach-ns9xxx/mach-cc9p9360dev.c linux-3.0-rc7-libre/arch/arm/mach-ns9xxx/mach-cc9p9360dev.c
--- linux-2.6.39-libre/arch/arm/mach-ns9xxx/mach-cc9p9360dev.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-ns9xxx/mach-cc9p9360dev.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,43 +0,0 @@
-/*
- * arch/arm/mach-ns9xxx/mach-cc9p9360dev.c
- *
- * Copyright (C) 2006,2007 by Digi International 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 <asm/mach/arch.h>
-#include <asm/mach-types.h>
-
-#include <mach/processor-ns9360.h>
-
-#include "board-a9m9750dev.h"
-#include "generic.h"
-
-static void __init mach_cc9p9360dev_map_io(void)
-{
-	ns9360_map_io();
-	board_a9m9750dev_map_io();
-}
-
-static void __init mach_cc9p9360dev_init_irq(void)
-{
-	ns9xxx_init_irq();
-	board_a9m9750dev_init_irq();
-}
-
-static void __init mach_cc9p9360dev_init_machine(void)
-{
-	ns9xxx_init_machine();
-	board_a9m9750dev_init_machine();
-}
-
-MACHINE_START(CC9P9360DEV, "Digi ConnectCore 9P 9360 on an A9M9750 Devboard")
-	.map_io = mach_cc9p9360dev_map_io,
-	.init_irq = mach_cc9p9360dev_init_irq,
-	.init_machine = mach_cc9p9360dev_init_machine,
-	.timer = &ns9360_timer,
-	.boot_params = 0x100,
-MACHINE_END
diff -druN linux-2.6.39-libre/arch/arm/mach-ns9xxx/mach-cc9p9360js.c linux-3.0-rc7-libre/arch/arm/mach-ns9xxx/mach-cc9p9360js.c
--- linux-2.6.39-libre/arch/arm/mach-ns9xxx/mach-cc9p9360js.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-ns9xxx/mach-cc9p9360js.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,31 +0,0 @@
-/*
- * arch/arm/mach-ns9xxx/mach-cc9p9360js.c
- *
- * Copyright (C) 2006,2007 by Digi International 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 <asm/mach/arch.h>
-#include <asm/mach-types.h>
-
-#include <mach/processor-ns9360.h>
-
-#include "board-jscc9p9360.h"
-#include "generic.h"
-
-static void __init mach_cc9p9360js_init_machine(void)
-{
-	ns9xxx_init_machine();
-	board_jscc9p9360_init_machine();
-}
-
-MACHINE_START(CC9P9360JS, "Digi ConnectCore 9P 9360 on an JSCC9P9360 Devboard")
-	.map_io = ns9360_map_io,
-	.init_irq = ns9xxx_init_irq,
-	.init_machine = mach_cc9p9360js_init_machine,
-	.timer = &ns9360_timer,
-	.boot_params = 0x100,
-MACHINE_END
diff -druN linux-2.6.39-libre/arch/arm/mach-ns9xxx/Makefile linux-3.0-rc7-libre/arch/arm/mach-ns9xxx/Makefile
--- linux-2.6.39-libre/arch/arm/mach-ns9xxx/Makefile	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-ns9xxx/Makefile	1969-12-31 19:00:00.000000000 -0500
@@ -1,12 +0,0 @@
-obj-y := clock.o generic.o gpio.o irq.o
-
-obj-$(CONFIG_MACH_CC9P9360DEV) += mach-cc9p9360dev.o
-obj-$(CONFIG_MACH_CC9P9360JS) += mach-cc9p9360js.o
-
-obj-$(CONFIG_PROCESSOR_NS9360) += gpio-ns9360.o processor-ns9360.o time-ns9360.o
-
-obj-$(CONFIG_BOARD_A9M9750DEV) += board-a9m9750dev.o
-obj-$(CONFIG_BOARD_JSCC9P9360) += board-jscc9p9360.o
-
-# platform devices
-obj-$(CONFIG_NS9XXX_HAVE_SERIAL8250) += plat-serial8250.o
diff -druN linux-2.6.39-libre/arch/arm/mach-ns9xxx/Makefile.boot linux-3.0-rc7-libre/arch/arm/mach-ns9xxx/Makefile.boot
--- linux-2.6.39-libre/arch/arm/mach-ns9xxx/Makefile.boot	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-ns9xxx/Makefile.boot	1969-12-31 19:00:00.000000000 -0500
@@ -1,2 +0,0 @@
-zreladdr-y := 0x8000
-params_phys-y := 0x100
diff -druN linux-2.6.39-libre/arch/arm/mach-ns9xxx/plat-serial8250.c linux-3.0-rc7-libre/arch/arm/mach-ns9xxx/plat-serial8250.c
--- linux-2.6.39-libre/arch/arm/mach-ns9xxx/plat-serial8250.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-ns9xxx/plat-serial8250.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,70 +0,0 @@
-/*
- * arch/arm/mach-ns9xxx/plat-serial8250.c
- *
- * Copyright (C) 2008 by Digi International 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/platform_device.h>
-#include <linux/serial_8250.h>
-#include <linux/slab.h>
-
-#include <mach/regs-board-a9m9750dev.h>
-#include <mach/board.h>
-
-#define DRIVER_NAME "serial8250"
-
-static int __init ns9xxx_plat_serial8250_init(void)
-{
-	struct plat_serial8250_port *pdata;
-	struct platform_device *pdev;
-	int ret = -ENOMEM;
-	int i;
-
-	if (!board_is_a9m9750dev())
-		return -ENODEV;
-
-	pdev = platform_device_alloc(DRIVER_NAME, 0);
-	if (!pdev)
-		goto err;
-
-	pdata = kzalloc(5 * sizeof(*pdata), GFP_KERNEL);
-	if (!pdata)
-		goto err;
-
-	pdev->dev.platform_data = pdata;
-
-	pdata[0].iobase = FPGA_UARTA_BASE;
-	pdata[1].iobase = FPGA_UARTB_BASE;
-	pdata[2].iobase = FPGA_UARTC_BASE;
-	pdata[3].iobase = FPGA_UARTD_BASE;
-
-	for (i = 0; i < 4; ++i) {
-		pdata[i].membase = (void __iomem *)pdata[i].iobase;
-		pdata[i].mapbase = pdata[i].iobase;
-		pdata[i].iotype = UPIO_MEM;
-		pdata[i].uartclk = 18432000;
-		pdata[i].flags = UPF_BOOT_AUTOCONF | UPF_SHARE_IRQ;
-	}
-
-	pdata[0].irq = IRQ_FPGA_UARTA;
-	pdata[1].irq = IRQ_FPGA_UARTB;
-	pdata[2].irq = IRQ_FPGA_UARTC;
-	pdata[3].irq = IRQ_FPGA_UARTD;
-
-	ret = platform_device_add(pdev);
-	if (ret) {
-err:
-		platform_device_put(pdev);
-
-		printk(KERN_WARNING "Could not add %s (errno=%d)\n",
-				DRIVER_NAME, ret);
-	}
-
-	return 0;
-}
-
-arch_initcall(ns9xxx_plat_serial8250_init);
diff -druN linux-2.6.39-libre/arch/arm/mach-ns9xxx/processor-ns9360.c linux-3.0-rc7-libre/arch/arm/mach-ns9xxx/processor-ns9360.c
--- linux-2.6.39-libre/arch/arm/mach-ns9xxx/processor-ns9360.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-ns9xxx/processor-ns9360.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,53 +0,0 @@
-/*
- * arch/arm/mach-ns9xxx/processor-ns9360.c
- *
- * Copyright (C) 2007 by Digi International 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/io.h>
-#include <linux/kernel.h>
-
-#include <asm/page.h>
-#include <asm/mach/map.h>
-#include <mach/processor-ns9360.h>
-#include <mach/regs-sys-ns9360.h>
-
-void ns9360_reset(char mode)
-{
-	u32 reg;
-
-	reg = __raw_readl(SYS_PLL) >> 16;
-	REGSET(reg, SYS_PLL, SWC, YES);
-	__raw_writel(reg, SYS_PLL);
-}
-
-#define CRYSTAL 29491200 /* Hz */
-unsigned long ns9360_systemclock(void)
-{
-	u32 pll = __raw_readl(SYS_PLL);
-	return CRYSTAL * (REGGETIM(pll, SYS_PLL, ND) + 1)
-		>> REGGETIM(pll, SYS_PLL, FS);
-}
-
-static struct map_desc ns9360_io_desc[] __initdata = {
-	{ /* BBus */
-		.virtual = io_p2v(0x90000000),
-		.pfn = __phys_to_pfn(0x90000000),
-		.length = 0x00700000,
-		.type = MT_DEVICE,
-	}, { /* AHB */
-		.virtual = io_p2v(0xa0100000),
-		.pfn = __phys_to_pfn(0xa0100000),
-		.length = 0x00900000,
-		.type = MT_DEVICE,
-	},
-};
-
-void __init ns9360_map_io(void)
-{
-	iotable_init(ns9360_io_desc, ARRAY_SIZE(ns9360_io_desc));
-}
diff -druN linux-2.6.39-libre/arch/arm/mach-ns9xxx/time-ns9360.c linux-3.0-rc7-libre/arch/arm/mach-ns9xxx/time-ns9360.c
--- linux-2.6.39-libre/arch/arm/mach-ns9xxx/time-ns9360.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-ns9xxx/time-ns9360.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,181 +0,0 @@
-/*
- * arch/arm/mach-ns9xxx/time-ns9360.c
- *
- * Copyright (C) 2006,2007 by Digi International 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/jiffies.h>
-#include <linux/interrupt.h>
-#include <linux/irq.h>
-#include <linux/stringify.h>
-#include <linux/clocksource.h>
-#include <linux/clockchips.h>
-
-#include <mach/processor-ns9360.h>
-#include <mach/regs-sys-ns9360.h>
-#include <mach/irqs.h>
-#include <mach/system.h>
-#include "generic.h"
-
-#define TIMER_CLOCKSOURCE 0
-#define TIMER_CLOCKEVENT 1
-static u32 latch;
-
-static cycle_t ns9360_clocksource_read(struct clocksource *cs)
-{
-	return __raw_readl(SYS_TR(TIMER_CLOCKSOURCE));
-}
-
-static struct clocksource ns9360_clocksource = {
-	.name	= "ns9360-timer" __stringify(TIMER_CLOCKSOURCE),
-	.rating	= 300,
-	.read	= ns9360_clocksource_read,
-	.mask	= CLOCKSOURCE_MASK(32),
-	.flags	= CLOCK_SOURCE_IS_CONTINUOUS,
-};
-
-static void ns9360_clockevent_setmode(enum clock_event_mode mode,
-		struct clock_event_device *clk)
-{
-	u32 tc = __raw_readl(SYS_TC(TIMER_CLOCKEVENT));
-
-	switch (mode) {
-	case CLOCK_EVT_MODE_PERIODIC:
-		__raw_writel(latch, SYS_TRC(TIMER_CLOCKEVENT));
-		REGSET(tc, SYS_TCx, REN, EN);
-		REGSET(tc, SYS_TCx, INTS, EN);
-		REGSET(tc, SYS_TCx, TEN, EN);
-		break;
-
-	case CLOCK_EVT_MODE_ONESHOT:
-		REGSET(tc, SYS_TCx, REN, DIS);
-		REGSET(tc, SYS_TCx, INTS, EN);
-
-		/* fall through */
-
-	case CLOCK_EVT_MODE_UNUSED:
-	case CLOCK_EVT_MODE_SHUTDOWN:
-	case CLOCK_EVT_MODE_RESUME:
-	default:
-		REGSET(tc, SYS_TCx, TEN, DIS);
-		break;
-	}
-
-	__raw_writel(tc, SYS_TC(TIMER_CLOCKEVENT));
-}
-
-static int ns9360_clockevent_setnextevent(unsigned long evt,
-		struct clock_event_device *clk)
-{
-	u32 tc = __raw_readl(SYS_TC(TIMER_CLOCKEVENT));
-
-	if (REGGET(tc, SYS_TCx, TEN)) {
-		REGSET(tc, SYS_TCx, TEN, DIS);
-		__raw_writel(tc, SYS_TC(TIMER_CLOCKEVENT));
-	}
-
-	REGSET(tc, SYS_TCx, TEN, EN);
-
-	__raw_writel(evt, SYS_TRC(TIMER_CLOCKEVENT));
-
-	__raw_writel(tc, SYS_TC(TIMER_CLOCKEVENT));
-
-	return 0;
-}
-
-static struct clock_event_device ns9360_clockevent_device = {
-	.name		= "ns9360-timer" __stringify(TIMER_CLOCKEVENT),
-	.shift		= 20,
-	.features	= CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
-	.set_mode	= ns9360_clockevent_setmode,
-	.set_next_event	= ns9360_clockevent_setnextevent,
-};
-
-static irqreturn_t ns9360_clockevent_handler(int irq, void *dev_id)
-{
-	int timerno = irq - IRQ_NS9360_TIMER0;
-	u32 tc;
-
-	struct clock_event_device *evt = &ns9360_clockevent_device;
-
-	/* clear irq */
-	tc = __raw_readl(SYS_TC(timerno));
-	if (REGGET(tc, SYS_TCx, REN) == SYS_TCx_REN_DIS) {
-		REGSET(tc, SYS_TCx, TEN, DIS);
-		__raw_writel(tc, SYS_TC(timerno));
-	}
-	REGSET(tc, SYS_TCx, INTC, SET);
-	__raw_writel(tc, SYS_TC(timerno));
-	REGSET(tc, SYS_TCx, INTC, UNSET);
-	__raw_writel(tc, SYS_TC(timerno));
-
-	evt->event_handler(evt);
-
-	return IRQ_HANDLED;
-}
-
-static struct irqaction ns9360_clockevent_action = {
-	.name		= "ns9360-timer" __stringify(TIMER_CLOCKEVENT),
-	.flags		= IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
-	.handler	= ns9360_clockevent_handler,
-};
-
-static void __init ns9360_timer_init(void)
-{
-	int tc;
-
-	tc = __raw_readl(SYS_TC(TIMER_CLOCKSOURCE));
-	if (REGGET(tc, SYS_TCx, TEN)) {
-		REGSET(tc, SYS_TCx, TEN, DIS);
-		__raw_writel(tc, SYS_TC(TIMER_CLOCKSOURCE));
-	}
-
-	__raw_writel(0, SYS_TRC(TIMER_CLOCKSOURCE));
-
-	REGSET(tc, SYS_TCx, TEN, EN);
-	REGSET(tc, SYS_TCx, TDBG, STOP);
-	REGSET(tc, SYS_TCx, TLCS, CPU);
-	REGSET(tc, SYS_TCx, TM, IEE);
-	REGSET(tc, SYS_TCx, INTS, DIS);
-	REGSET(tc, SYS_TCx, UDS, UP);
-	REGSET(tc, SYS_TCx, TSZ, 32);
-	REGSET(tc, SYS_TCx, REN, EN);
-
-	__raw_writel(tc, SYS_TC(TIMER_CLOCKSOURCE));
-
-	clocksource_register_hz(&ns9360_clocksource, ns9360_cpuclock());
-
-	latch = SH_DIV(ns9360_cpuclock(), HZ, 0);
-
-	tc = __raw_readl(SYS_TC(TIMER_CLOCKEVENT));
-	REGSET(tc, SYS_TCx, TEN, DIS);
-	REGSET(tc, SYS_TCx, TDBG, STOP);
-	REGSET(tc, SYS_TCx, TLCS, CPU);
-	REGSET(tc, SYS_TCx, TM, IEE);
-	REGSET(tc, SYS_TCx, INTS, DIS);
-	REGSET(tc, SYS_TCx, UDS, DOWN);
-	REGSET(tc, SYS_TCx, TSZ, 32);
-	REGSET(tc, SYS_TCx, REN, EN);
-	__raw_writel(tc, SYS_TC(TIMER_CLOCKEVENT));
-
-	ns9360_clockevent_device.mult = div_sc(ns9360_cpuclock(),
-			NSEC_PER_SEC, ns9360_clockevent_device.shift);
-	ns9360_clockevent_device.max_delta_ns =
-		clockevent_delta2ns(-1, &ns9360_clockevent_device);
-	ns9360_clockevent_device.min_delta_ns =
-		clockevent_delta2ns(1, &ns9360_clockevent_device);
-
-	ns9360_clockevent_device.cpumask = cpumask_of(0);
-	clockevents_register_device(&ns9360_clockevent_device);
-
-	setup_irq(IRQ_NS9360_TIMER0 + TIMER_CLOCKEVENT,
-			&ns9360_clockevent_action);
-}
-
-struct sys_timer ns9360_timer = {
-	.init = ns9360_timer_init,
-};
diff -druN linux-2.6.39-libre/arch/arm/mach-nuc93x/include/mach/uncompress.h linux-3.0-rc7-libre/arch/arm/mach-nuc93x/include/mach/uncompress.h
--- linux-2.6.39-libre/arch/arm/mach-nuc93x/include/mach/uncompress.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-nuc93x/include/mach/uncompress.h	2011-07-11 19:51:52.000000000 -0400
@@ -27,7 +27,7 @@
 #define arch_decomp_wdog()
 
 #define TX_DONE	(UART_LSR_TEMT | UART_LSR_THRE)
-static u32 * uart_base = (u32 *)UART0_PA;
+static u32 * const uart_base = (u32 *)UART0_PA;
 
 static void putc(int ch)
 {
diff -druN linux-2.6.39-libre/arch/arm/mach-omap1/board-ams-delta.c linux-3.0-rc7-libre/arch/arm/mach-omap1/board-ams-delta.c
--- linux-2.6.39-libre/arch/arm/mach-omap1/board-ams-delta.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-omap1/board-ams-delta.c	2011-07-11 19:51:52.000000000 -0400
@@ -215,7 +215,7 @@
 	.delay		= 9,
 };
 
-static struct platform_device ams_delta_kp_device __initdata = {
+static struct platform_device ams_delta_kp_device = {
 	.name		= "omap-keypad",
 	.id		= -1,
 	.dev		= {
@@ -225,12 +225,12 @@
 	.resource	= ams_delta_kp_resources,
 };
 
-static struct platform_device ams_delta_lcd_device __initdata = {
+static struct platform_device ams_delta_lcd_device = {
 	.name	= "lcd_ams_delta",
 	.id	= -1,
 };
 
-static struct platform_device ams_delta_led_device __initdata = {
+static struct platform_device ams_delta_led_device = {
 	.name	= "ams-delta-led",
 	.id	= -1
 };
@@ -267,7 +267,7 @@
 	.power		= ams_delta_camera_power,
 };
 
-static struct platform_device ams_delta_camera_device __initdata = {
+static struct platform_device ams_delta_camera_device = {
 	.name   = "soc-camera-pdrv",
 	.id     = 0,
 	.dev    = {
diff -druN linux-2.6.39-libre/arch/arm/mach-omap1/dma.c linux-3.0-rc7-libre/arch/arm/mach-omap1/dma.c
--- linux-2.6.39-libre/arch/arm/mach-omap1/dma.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-omap1/dma.c	2011-07-11 19:51:52.000000000 -0400
@@ -284,14 +284,15 @@
 	dma_base = ioremap(res[0].start, resource_size(&res[0]));
 	if (!dma_base) {
 		pr_err("%s: Unable to ioremap\n", __func__);
-		return -ENODEV;
+		ret = -ENODEV;
+		goto exit_device_put;
 	}
 
 	ret = platform_device_add_resources(pdev, res, ARRAY_SIZE(res));
 	if (ret) {
 		dev_err(&pdev->dev, "%s: Unable to add resources for %s%d\n",
 			__func__, pdev->name, pdev->id);
-		goto exit_device_del;
+		goto exit_device_put;
 	}
 
 	p = kzalloc(sizeof(struct omap_system_dma_plat_info), GFP_KERNEL);
@@ -299,7 +300,7 @@
 		dev_err(&pdev->dev, "%s: Unable to allocate 'p' for %s\n",
 			__func__, pdev->name);
 		ret = -ENOMEM;
-		goto exit_device_put;
+		goto exit_device_del;
 	}
 
 	d = kzalloc(sizeof(struct omap_dma_dev_attr), GFP_KERNEL);
@@ -380,10 +381,10 @@
 	kfree(d);
 exit_release_p:
 	kfree(p);
-exit_device_put:
-	platform_device_put(pdev);
 exit_device_del:
 	platform_device_del(pdev);
+exit_device_put:
+	platform_device_put(pdev);
 
 	return ret;
 }
diff -druN linux-2.6.39-libre/arch/arm/mach-omap1/flash.c linux-3.0-rc7-libre/arch/arm/mach-omap1/flash.c
--- linux-2.6.39-libre/arch/arm/mach-omap1/flash.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-omap1/flash.c	2011-07-11 19:51:52.000000000 -0400
@@ -13,7 +13,7 @@
 #include <plat/tc.h>
 #include <plat/flash.h>
 
-void omap1_set_vpp(struct map_info *map, int enable)
+void omap1_set_vpp(struct platform_device *pdev, int enable)
 {
 	static int count;
 	u32 l;
diff -druN linux-2.6.39-libre/arch/arm/mach-omap1/gpio15xx.c linux-3.0-rc7-libre/arch/arm/mach-omap1/gpio15xx.c
--- linux-2.6.39-libre/arch/arm/mach-omap1/gpio15xx.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-omap1/gpio15xx.c	2011-07-11 19:51:52.000000000 -0400
@@ -41,7 +41,7 @@
 	.bank_stride		= 1,
 };
 
-static struct __initdata platform_device omap15xx_mpu_gpio = {
+static struct platform_device omap15xx_mpu_gpio = {
 	.name           = "omap_gpio",
 	.id             = 0,
 	.dev            = {
@@ -70,7 +70,7 @@
 	.bank_width		= 16,
 };
 
-static struct __initdata platform_device omap15xx_gpio = {
+static struct platform_device omap15xx_gpio = {
 	.name           = "omap_gpio",
 	.id             = 1,
 	.dev            = {
diff -druN linux-2.6.39-libre/arch/arm/mach-omap1/gpio16xx.c linux-3.0-rc7-libre/arch/arm/mach-omap1/gpio16xx.c
--- linux-2.6.39-libre/arch/arm/mach-omap1/gpio16xx.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-omap1/gpio16xx.c	2011-07-11 19:51:52.000000000 -0400
@@ -44,7 +44,7 @@
 	.bank_stride		= 1,
 };
 
-static struct __initdata platform_device omap16xx_mpu_gpio = {
+static struct platform_device omap16xx_mpu_gpio = {
 	.name           = "omap_gpio",
 	.id             = 0,
 	.dev            = {
@@ -73,7 +73,7 @@
 	.bank_width		= 16,
 };
 
-static struct __initdata platform_device omap16xx_gpio1 = {
+static struct platform_device omap16xx_gpio1 = {
 	.name           = "omap_gpio",
 	.id             = 1,
 	.dev            = {
@@ -102,7 +102,7 @@
 	.bank_width		= 16,
 };
 
-static struct __initdata platform_device omap16xx_gpio2 = {
+static struct platform_device omap16xx_gpio2 = {
 	.name           = "omap_gpio",
 	.id             = 2,
 	.dev            = {
@@ -131,7 +131,7 @@
 	.bank_width		= 16,
 };
 
-static struct __initdata platform_device omap16xx_gpio3 = {
+static struct platform_device omap16xx_gpio3 = {
 	.name           = "omap_gpio",
 	.id             = 3,
 	.dev            = {
@@ -160,7 +160,7 @@
 	.bank_width		= 16,
 };
 
-static struct __initdata platform_device omap16xx_gpio4 = {
+static struct platform_device omap16xx_gpio4 = {
 	.name           = "omap_gpio",
 	.id             = 4,
 	.dev            = {
diff -druN linux-2.6.39-libre/arch/arm/mach-omap1/gpio7xx.c linux-3.0-rc7-libre/arch/arm/mach-omap1/gpio7xx.c
--- linux-2.6.39-libre/arch/arm/mach-omap1/gpio7xx.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-omap1/gpio7xx.c	2011-07-11 19:51:52.000000000 -0400
@@ -46,7 +46,7 @@
 	.bank_stride		= 2,
 };
 
-static struct __initdata platform_device omap7xx_mpu_gpio = {
+static struct platform_device omap7xx_mpu_gpio = {
 	.name           = "omap_gpio",
 	.id             = 0,
 	.dev            = {
@@ -75,7 +75,7 @@
 	.bank_width		= 32,
 };
 
-static struct __initdata platform_device omap7xx_gpio1 = {
+static struct platform_device omap7xx_gpio1 = {
 	.name           = "omap_gpio",
 	.id             = 1,
 	.dev            = {
@@ -104,7 +104,7 @@
 	.bank_width		= 32,
 };
 
-static struct __initdata platform_device omap7xx_gpio2 = {
+static struct platform_device omap7xx_gpio2 = {
 	.name           = "omap_gpio",
 	.id             = 2,
 	.dev            = {
@@ -133,7 +133,7 @@
 	.bank_width		= 32,
 };
 
-static struct __initdata platform_device omap7xx_gpio3 = {
+static struct platform_device omap7xx_gpio3 = {
 	.name           = "omap_gpio",
 	.id             = 3,
 	.dev            = {
@@ -162,7 +162,7 @@
 	.bank_width		= 32,
 };
 
-static struct __initdata platform_device omap7xx_gpio4 = {
+static struct platform_device omap7xx_gpio4 = {
 	.name           = "omap_gpio",
 	.id             = 4,
 	.dev            = {
@@ -191,7 +191,7 @@
 	.bank_width		= 32,
 };
 
-static struct __initdata platform_device omap7xx_gpio5 = {
+static struct platform_device omap7xx_gpio5 = {
 	.name           = "omap_gpio",
 	.id             = 5,
 	.dev            = {
@@ -220,7 +220,7 @@
 	.bank_width		= 32,
 };
 
-static struct __initdata platform_device omap7xx_gpio6 = {
+static struct platform_device omap7xx_gpio6 = {
 	.name           = "omap_gpio",
 	.id             = 6,
 	.dev            = {
diff -druN linux-2.6.39-libre/arch/arm/mach-omap1/Makefile linux-3.0-rc7-libre/arch/arm/mach-omap1/Makefile
--- linux-2.6.39-libre/arch/arm/mach-omap1/Makefile	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-omap1/Makefile	2011-07-11 19:51:52.000000000 -0400
@@ -4,14 +4,14 @@
 
 # Common support
 obj-y := io.o id.o sram.o time.o irq.o mux.o flash.o serial.o devices.o dma.o
-obj-y += clock.o clock_data.o opp_data.o reset.o
+obj-y += clock.o clock_data.o opp_data.o reset.o pm_bus.o
 
 obj-$(CONFIG_OMAP_MCBSP) += mcbsp.o
 
 obj-$(CONFIG_OMAP_32K_TIMER)	+= timer32k.o
 
 # Power Management
-obj-$(CONFIG_PM) += pm.o sleep.o pm_bus.o
+obj-$(CONFIG_PM) += pm.o sleep.o
 
 # DSP
 obj-$(CONFIG_OMAP_MBOX_FWK)	+= mailbox_mach.o
diff -druN linux-2.6.39-libre/arch/arm/mach-omap1/pm_bus.c linux-3.0-rc7-libre/arch/arm/mach-omap1/pm_bus.c
--- linux-2.6.39-libre/arch/arm/mach-omap1/pm_bus.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-omap1/pm_bus.c	2011-07-11 19:51:52.000000000 -0400
@@ -24,77 +24,56 @@
 #ifdef CONFIG_PM_RUNTIME
 static int omap1_pm_runtime_suspend(struct device *dev)
 {
-	struct clk *iclk, *fclk;
-	int ret = 0;
+	int ret;
 
 	dev_dbg(dev, "%s\n", __func__);
 
 	ret = pm_generic_runtime_suspend(dev);
+	if (ret)
+		return ret;
 
-	fclk = clk_get(dev, "fck");
-	if (!IS_ERR(fclk)) {
-		clk_disable(fclk);
-		clk_put(fclk);
-	}
-
-	iclk = clk_get(dev, "ick");
-	if (!IS_ERR(iclk)) {
-		clk_disable(iclk);
-		clk_put(iclk);
+	ret = pm_runtime_clk_suspend(dev);
+	if (ret) {
+		pm_generic_runtime_resume(dev);
+		return ret;
 	}
 
 	return 0;
-};
+}
 
 static int omap1_pm_runtime_resume(struct device *dev)
 {
-	struct clk *iclk, *fclk;
-
 	dev_dbg(dev, "%s\n", __func__);
 
-	iclk = clk_get(dev, "ick");
-	if (!IS_ERR(iclk)) {
-		clk_enable(iclk);
-		clk_put(iclk);
-	}
+	pm_runtime_clk_resume(dev);
+	return pm_generic_runtime_resume(dev);
+}
 
-	fclk = clk_get(dev, "fck");
-	if (!IS_ERR(fclk)) {
-		clk_enable(fclk);
-		clk_put(fclk);
-	}
+static struct dev_power_domain default_power_domain = {
+	.ops = {
+		.runtime_suspend = omap1_pm_runtime_suspend,
+		.runtime_resume = omap1_pm_runtime_resume,
+		USE_PLATFORM_PM_SLEEP_OPS
+	},
+};
+#define OMAP1_PWR_DOMAIN (&default_power_domain)
+#else
+#define OMAP1_PWR_DOMAIN NULL
+#endif /* CONFIG_PM_RUNTIME */
 
-	return pm_generic_runtime_resume(dev);
+static struct pm_clk_notifier_block platform_bus_notifier = {
+	.pwr_domain = OMAP1_PWR_DOMAIN,
+	.con_ids = { "ick", "fck", NULL, },
 };
 
 static int __init omap1_pm_runtime_init(void)
 {
-	const struct dev_pm_ops *pm;
-	struct dev_pm_ops *omap_pm;
-
 	if (!cpu_class_is_omap1())
 		return -ENODEV;
 
-	pm = platform_bus_get_pm_ops();
-	if (!pm) {
-		pr_err("%s: unable to get dev_pm_ops from platform_bus\n",
-			__func__);
-		return -ENODEV;
-	}
-
-	omap_pm = kmemdup(pm, sizeof(struct dev_pm_ops), GFP_KERNEL);
-	if (!omap_pm) {
-		pr_err("%s: unable to alloc memory for new dev_pm_ops\n",
-			__func__);
-		return -ENOMEM;
-	}
-
-	omap_pm->runtime_suspend = omap1_pm_runtime_suspend;
-	omap_pm->runtime_resume = omap1_pm_runtime_resume;
-
-	platform_bus_set_pm_ops(omap_pm);
+	pm_runtime_clk_add_notifier(&platform_bus_type, &platform_bus_notifier);
 
 	return 0;
 }
 core_initcall(omap1_pm_runtime_init);
-#endif /* CONFIG_PM_RUNTIME */
+
diff -druN linux-2.6.39-libre/arch/arm/mach-omap1/time.c linux-3.0-rc7-libre/arch/arm/mach-omap1/time.c
--- linux-2.6.39-libre/arch/arm/mach-omap1/time.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-omap1/time.c	2011-07-11 19:51:52.000000000 -0400
@@ -68,49 +68,50 @@
 } omap_mpu_timer_regs_t;
 
 #define omap_mpu_timer_base(n)							\
-((volatile omap_mpu_timer_regs_t*)OMAP1_IO_ADDRESS(OMAP_MPU_TIMER_BASE +	\
+((omap_mpu_timer_regs_t __iomem *)OMAP1_IO_ADDRESS(OMAP_MPU_TIMER_BASE +	\
 				 (n)*OMAP_MPU_TIMER_OFFSET))
 
 static inline unsigned long notrace omap_mpu_timer_read(int nr)
 {
-	volatile omap_mpu_timer_regs_t* timer = omap_mpu_timer_base(nr);
-	return timer->read_tim;
+	omap_mpu_timer_regs_t __iomem *timer = omap_mpu_timer_base(nr);
+	return readl(&timer->read_tim);
 }
 
 static inline void omap_mpu_set_autoreset(int nr)
 {
-	volatile omap_mpu_timer_regs_t* timer = omap_mpu_timer_base(nr);
+	omap_mpu_timer_regs_t __iomem *timer = omap_mpu_timer_base(nr);
 
-	timer->cntl = timer->cntl | MPU_TIMER_AR;
+	writel(readl(&timer->cntl) | MPU_TIMER_AR, &timer->cntl);
 }
 
 static inline void omap_mpu_remove_autoreset(int nr)
 {
-	volatile omap_mpu_timer_regs_t* timer = omap_mpu_timer_base(nr);
+	omap_mpu_timer_regs_t __iomem *timer = omap_mpu_timer_base(nr);
 
-	timer->cntl = timer->cntl & ~MPU_TIMER_AR;
+	writel(readl(&timer->cntl) & ~MPU_TIMER_AR, &timer->cntl);
 }
 
 static inline void omap_mpu_timer_start(int nr, unsigned long load_val,
 					int autoreset)
 {
-	volatile omap_mpu_timer_regs_t* timer = omap_mpu_timer_base(nr);
-	unsigned int timerflags = (MPU_TIMER_CLOCK_ENABLE | MPU_TIMER_ST);
+	omap_mpu_timer_regs_t __iomem *timer = omap_mpu_timer_base(nr);
+	unsigned int timerflags = MPU_TIMER_CLOCK_ENABLE | MPU_TIMER_ST;
 
-	if (autoreset) timerflags |= MPU_TIMER_AR;
+	if (autoreset)
+		timerflags |= MPU_TIMER_AR;
 
-	timer->cntl = MPU_TIMER_CLOCK_ENABLE;
+	writel(MPU_TIMER_CLOCK_ENABLE, &timer->cntl);
 	udelay(1);
-	timer->load_tim = load_val;
+	writel(load_val, &timer->load_tim);
         udelay(1);
-	timer->cntl = timerflags;
+	writel(timerflags, &timer->cntl);
 }
 
 static inline void omap_mpu_timer_stop(int nr)
 {
-	volatile omap_mpu_timer_regs_t* timer = omap_mpu_timer_base(nr);
+	omap_mpu_timer_regs_t __iomem *timer = omap_mpu_timer_base(nr);
 
-	timer->cntl &= ~MPU_TIMER_ST;
+	writel(readl(&timer->cntl) & ~MPU_TIMER_ST, &timer->cntl);
 }
 
 /*
@@ -189,38 +190,11 @@
  * ---------------------------------------------------------------------------
  */
 
-static unsigned long omap_mpu_timer2_overflows;
-
-static irqreturn_t omap_mpu_timer2_interrupt(int irq, void *dev_id)
-{
-	omap_mpu_timer2_overflows++;
-	return IRQ_HANDLED;
-}
-
-static struct irqaction omap_mpu_timer2_irq = {
-	.name		= "mpu_timer2",
-	.flags		= IRQF_DISABLED,
-	.handler	= omap_mpu_timer2_interrupt,
-};
-
-static cycle_t mpu_read(struct clocksource *cs)
-{
-	return ~omap_mpu_timer_read(1);
-}
-
-static struct clocksource clocksource_mpu = {
-	.name		= "mpu_timer2",
-	.rating		= 300,
-	.read		= mpu_read,
-	.mask		= CLOCKSOURCE_MASK(32),
-	.flags		= CLOCK_SOURCE_IS_CONTINUOUS,
-};
-
 static DEFINE_CLOCK_DATA(cd);
 
 static inline unsigned long long notrace _omap_mpu_sched_clock(void)
 {
-	u32 cyc = mpu_read(&clocksource_mpu);
+	u32 cyc = ~omap_mpu_timer_read(1);
 	return cyc_to_sched_clock(&cd, cyc, (u32)~0);
 }
 
@@ -238,21 +212,22 @@
 
 static void notrace mpu_update_sched_clock(void)
 {
-	u32 cyc = mpu_read(&clocksource_mpu);
+	u32 cyc = ~omap_mpu_timer_read(1);
 	update_sched_clock(&cd, cyc, (u32)~0);
 }
 
 static void __init omap_init_clocksource(unsigned long rate)
 {
+	omap_mpu_timer_regs_t __iomem *timer = omap_mpu_timer_base(1);
 	static char err[] __initdata = KERN_ERR
 			"%s: can't register clocksource!\n";
 
-	setup_irq(INT_TIMER2, &omap_mpu_timer2_irq);
 	omap_mpu_timer_start(1, ~0, 1);
 	init_sched_clock(&cd, mpu_update_sched_clock, 32, rate);
 
-	if (clocksource_register_hz(&clocksource_mpu, rate))
-		printk(err, clocksource_mpu.name);
+	if (clocksource_mmio_init(&timer->read_tim, "mpu_timer2", rate,
+			300, 32, clocksource_mmio_readl_down))
+		printk(err, "mpu_timer2");
 }
 
 static void __init omap_mpu_timer_init(void)
diff -druN linux-2.6.39-libre/arch/arm/mach-omap2/board-2430sdp.c linux-3.0-rc7-libre/arch/arm/mach-omap2/board-2430sdp.c
--- linux-2.6.39-libre/arch/arm/mach-omap2/board-2430sdp.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-omap2/board-2430sdp.c	2011-07-11 19:51:52.000000000 -0400
@@ -26,13 +26,13 @@
 #include <linux/err.h>
 #include <linux/clk.h>
 #include <linux/io.h>
+#include <linux/gpio.h>
 
 #include <mach/hardware.h>
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
 
-#include <mach/gpio.h>
 #include <plat/board.h>
 #include <plat/common.h>
 #include <plat/gpmc.h>
@@ -41,6 +41,7 @@
 
 #include "mux.h"
 #include "hsmmc.h"
+#include "common-board-devices.h"
 
 #define SDP2430_CS0_BASE	0x04000000
 #define SECONDARY_LCD_GPIO		147
@@ -180,15 +181,6 @@
 	.vmmc1		= &sdp2430_vmmc1,
 };
 
-static struct i2c_board_info __initdata sdp2430_i2c_boardinfo[] = {
-	{
-		I2C_BOARD_INFO("twl4030", 0x48),
-		.flags = I2C_CLIENT_WAKE,
-		.irq = INT_24XX_SYS_NIRQ,
-		.platform_data = &sdp2430_twldata,
-	},
-};
-
 static struct i2c_board_info __initdata sdp2430_i2c1_boardinfo[] = {
 	{
 		I2C_BOARD_INFO("isp1301_omap", 0x2D),
@@ -201,8 +193,7 @@
 {
 	omap_register_i2c_bus(1, 100, sdp2430_i2c1_boardinfo,
 			ARRAY_SIZE(sdp2430_i2c1_boardinfo));
-	omap_register_i2c_bus(2, 2600, sdp2430_i2c_boardinfo,
-			ARRAY_SIZE(sdp2430_i2c_boardinfo));
+	omap2_pmic_init("twl4030", &sdp2430_twldata);
 	return 0;
 }
 
@@ -217,11 +208,6 @@
 	{}	/* Terminator */
 };
 
-static struct omap_musb_board_data musb_board_data = {
-	.interface_type		= MUSB_INTERFACE_ULPI,
-	.mode			= MUSB_OTG,
-	.power			= 100,
-};
 static struct omap_usb_config sdp2430_usb_config __initdata = {
 	.otg		= 1,
 #ifdef  CONFIG_USB_GADGET_OMAP
@@ -240,8 +226,6 @@
 
 static void __init omap_2430sdp_init(void)
 {
-	int ret;
-
 	omap2430_mux_init(board_mux, OMAP_PACKAGE_ZAC);
 
 	omap_board_config = sdp2430_config;
@@ -255,14 +239,13 @@
 	omap2_usbfs_init(&sdp2430_usb_config);
 
 	omap_mux_init_signal("usb0hs_stp", OMAP_PULL_ENA | OMAP_PULL_UP);
-	usb_musb_init(&musb_board_data);
+	usb_musb_init(NULL);
 
 	board_smc91x_init();
 
 	/* Turn off secondary LCD backlight */
-	ret = gpio_request(SECONDARY_LCD_GPIO, "Secondary LCD backlight");
-	if (ret == 0)
-		gpio_direction_output(SECONDARY_LCD_GPIO, 0);
+	gpio_request_one(SECONDARY_LCD_GPIO, GPIOF_OUT_INIT_LOW,
+			 "Secondary LCD backlight");
 }
 
 static void __init omap_2430sdp_map_io(void)
diff -druN linux-2.6.39-libre/arch/arm/mach-omap2/board-3430sdp.c linux-3.0-rc7-libre/arch/arm/mach-omap2/board-3430sdp.c
--- linux-2.6.39-libre/arch/arm/mach-omap2/board-3430sdp.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-omap2/board-3430sdp.c	2011-07-11 19:51:52.000000000 -0400
@@ -19,7 +19,6 @@
 #include <linux/input.h>
 #include <linux/input/matrix_keypad.h>
 #include <linux/spi/spi.h>
-#include <linux/spi/ads7846.h>
 #include <linux/i2c/twl.h>
 #include <linux/regulator/machine.h>
 #include <linux/io.h>
@@ -37,8 +36,8 @@
 #include <plat/common.h>
 #include <plat/dma.h>
 #include <plat/gpmc.h>
-#include <plat/display.h>
-#include <plat/panel-generic-dpi.h>
+#include <video/omapdss.h>
+#include <video/omap-panel-generic-dpi.h>
 
 #include <plat/gpmc-smc91x.h>
 
@@ -48,6 +47,7 @@
 #include "hsmmc.h"
 #include "pm.h"
 #include "control.h"
+#include "common-board-devices.h"
 
 #define CONFIG_DISABLE_HFCLK 1
 
@@ -59,24 +59,6 @@
 
 #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 uint32_t board_keymap[] = {
 	KEY(0, 0, KEY_LEFT),
 	KEY(0, 1, KEY_RIGHT),
@@ -123,63 +105,14 @@
 	.rep		= 1,
 };
 
-static int ts_gpio;	/* Needed for ads7846_get_pendown_state */
-
-/**
- * @brief ads7846_dev_init : Requests & sets GPIO line for pen-irq
- *
- * @return - void. If request gpio fails then Flag KERN_ERR.
- */
-static void ads7846_dev_init(void)
-{
-	if (gpio_request(ts_gpio, "ADS7846 pendown") < 0) {
-		printk(KERN_ERR "can't get ads746 pen down GPIO\n");
-		return;
-	}
-
-	gpio_direction_input(ts_gpio);
-	gpio_set_debounce(ts_gpio, 310);
-}
-
-static int ads7846_get_pendown_state(void)
-{
-	return !gpio_get_value(ts_gpio);
-}
-
-static struct ads7846_platform_data tsc2046_config __initdata = {
-	.get_pendown_state	= ads7846_get_pendown_state,
-	.keep_vref_on		= 1,
-	.wakeup				= true,
-};
-
-
-static struct omap2_mcspi_device_config tsc2046_mcspi_config = {
-	.turbo_mode	= 0,
-	.single_channel	= 1,	/* 0: slave, 1: master */
-};
-
-static struct spi_board_info sdp3430_spi_board_info[] __initdata = {
-	[0] = {
-		/*
-		 * TSC2046 operates at a max freqency of 2MHz, so
-		 * operate slightly below at 1.5MHz
-		 */
-		.modalias		= "ads7846",
-		.bus_num		= 1,
-		.chip_select		= 0,
-		.max_speed_hz		= 1500000,
-		.controller_data	= &tsc2046_mcspi_config,
-		.irq			= 0,
-		.platform_data		= &tsc2046_config,
-	},
-};
-
-
 #define SDP3430_LCD_PANEL_BACKLIGHT_GPIO	8
 #define SDP3430_LCD_PANEL_ENABLE_GPIO		5
 
-static unsigned backlight_gpio;
-static unsigned enable_gpio;
+static struct gpio sdp3430_dss_gpios[] __initdata = {
+	{SDP3430_LCD_PANEL_ENABLE_GPIO,    GPIOF_OUT_INIT_LOW, "LCD reset"    },
+	{SDP3430_LCD_PANEL_BACKLIGHT_GPIO, GPIOF_OUT_INIT_LOW, "LCD Backlight"},
+};
+
 static int lcd_enabled;
 static int dvi_enabled;
 
@@ -187,29 +120,11 @@
 {
 	int r;
 
-	enable_gpio    = SDP3430_LCD_PANEL_ENABLE_GPIO;
-	backlight_gpio = SDP3430_LCD_PANEL_BACKLIGHT_GPIO;
-
-	r = gpio_request(enable_gpio, "LCD reset");
-	if (r) {
-		printk(KERN_ERR "failed to get LCD reset GPIO\n");
-		goto err0;
-	}
-
-	r = gpio_request(backlight_gpio, "LCD Backlight");
-	if (r) {
-		printk(KERN_ERR "failed to get LCD backlight GPIO\n");
-		goto err1;
-	}
-
-	gpio_direction_output(enable_gpio, 0);
-	gpio_direction_output(backlight_gpio, 0);
+	r = gpio_request_array(sdp3430_dss_gpios,
+			       ARRAY_SIZE(sdp3430_dss_gpios));
+	if (r)
+		printk(KERN_ERR "failed to get LCD control GPIOs\n");
 
-	return;
-err1:
-	gpio_free(enable_gpio);
-err0:
-	return;
 }
 
 static int sdp3430_panel_enable_lcd(struct omap_dss_device *dssdev)
@@ -219,8 +134,8 @@
 		return -EINVAL;
 	}
 
-	gpio_direction_output(enable_gpio, 1);
-	gpio_direction_output(backlight_gpio, 1);
+	gpio_direction_output(SDP3430_LCD_PANEL_ENABLE_GPIO, 1);
+	gpio_direction_output(SDP3430_LCD_PANEL_BACKLIGHT_GPIO, 1);
 
 	lcd_enabled = 1;
 
@@ -231,8 +146,8 @@
 {
 	lcd_enabled = 0;
 
-	gpio_direction_output(enable_gpio, 0);
-	gpio_direction_output(backlight_gpio, 0);
+	gpio_direction_output(SDP3430_LCD_PANEL_ENABLE_GPIO, 0);
+	gpio_direction_output(SDP3430_LCD_PANEL_BACKLIGHT_GPIO, 0);
 }
 
 static int sdp3430_panel_enable_dvi(struct omap_dss_device *dssdev)
@@ -360,12 +275,10 @@
 	omap2_hsmmc_init(mmc);
 
 	/* gpio + 7 is "sub_lcd_en_bkl" (output/PWM1) */
-	gpio_request(gpio + 7, "sub_lcd_en_bkl");
-	gpio_direction_output(gpio + 7, 0);
+	gpio_request_one(gpio + 7, GPIOF_OUT_INIT_LOW, "sub_lcd_en_bkl");
 
 	/* gpio + 15 is "sub_lcd_nRST" (output) */
-	gpio_request(gpio + 15, "sub_lcd_nRST");
-	gpio_direction_output(gpio + 15, 0);
+	gpio_request_one(gpio + 15, GPIOF_OUT_INIT_LOW, "sub_lcd_nRST");
 
 	return 0;
 }
@@ -580,20 +493,10 @@
 	.vpll2		= &sdp3430_vpll2,
 };
 
-static struct i2c_board_info __initdata sdp3430_i2c_boardinfo[] = {
-	{
-		I2C_BOARD_INFO("twl4030", 0x48),
-		.flags = I2C_CLIENT_WAKE,
-		.irq = INT_34XX_SYS_NIRQ,
-		.platform_data = &sdp3430_twldata,
-	},
-};
-
 static int __init omap3430_i2c_init(void)
 {
 	/* i2c1 for PMIC only */
-	omap_register_i2c_bus(1, 2600, sdp3430_i2c_boardinfo,
-			ARRAY_SIZE(sdp3430_i2c_boardinfo));
+	omap3_pmic_init("twl4030", &sdp3430_twldata);
 	/* i2c2 on camera connector (for sensor control) and optional isp1301 */
 	omap_register_i2c_bus(2, 400, NULL, 0);
 	/* i2c3 on display connector (for DVI, tfp410) */
@@ -719,19 +622,19 @@
 			 OMAP_MUX_MODE0),
 };
 
-static struct omap_board_data serial1_data = {
+static struct omap_board_data serial1_data __initdata = {
 	.id		= 0,
 	.pads		= serial1_pads,
 	.pads_cnt	= ARRAY_SIZE(serial1_pads),
 };
 
-static struct omap_board_data serial2_data = {
+static struct omap_board_data serial2_data __initdata = {
 	.id		= 1,
 	.pads		= serial2_pads,
 	.pads_cnt	= ARRAY_SIZE(serial2_pads),
 };
 
-static struct omap_board_data serial3_data = {
+static struct omap_board_data serial3_data __initdata = {
 	.id		= 2,
 	.pads		= serial3_pads,
 	.pads_cnt	= ARRAY_SIZE(serial3_pads),
@@ -872,30 +775,22 @@
 	},
 };
 
-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)
 {
+	int gpio_pendown;
+
 	omap3_mux_init(board_mux, OMAP_PACKAGE_CBB);
 	omap_board_config = sdp3430_config;
 	omap_board_config_size = ARRAY_SIZE(sdp3430_config);
-	omap3_pm_init_cpuidle(omap3_cpuidle_params_table);
 	omap3430_i2c_init();
 	omap_display_init(&sdp3430_dss_data);
 	if (omap_rev() > OMAP3430_REV_ES1_0)
-		ts_gpio = SDP3430_TS_GPIO_IRQ_SDPV2;
+		gpio_pendown = SDP3430_TS_GPIO_IRQ_SDPV2;
 	else
-		ts_gpio = SDP3430_TS_GPIO_IRQ_SDPV1;
-	sdp3430_spi_board_info[0].irq = gpio_to_irq(ts_gpio);
-	spi_register_board_info(sdp3430_spi_board_info,
-				ARRAY_SIZE(sdp3430_spi_board_info));
-	ads7846_dev_init();
+		gpio_pendown = SDP3430_TS_GPIO_IRQ_SDPV1;
+	omap_ads7846_init(1, gpio_pendown, 310, NULL);
 	board_serial_init();
-	usb_musb_init(&musb_board_data);
+	usb_musb_init(NULL);
 	board_smc91x_init();
 	board_flash_init(sdp_flash_partitions, chip_sel_3430, 0);
 	sdp3430_display_init();
diff -druN linux-2.6.39-libre/arch/arm/mach-omap2/board-4430sdp.c linux-3.0-rc7-libre/arch/arm/mach-omap2/board-4430sdp.c
--- linux-2.6.39-libre/arch/arm/mach-omap2/board-4430sdp.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-omap2/board-4430sdp.c	2011-07-11 19:51:52.000000000 -0400
@@ -36,12 +36,13 @@
 #include <plat/usb.h>
 #include <plat/mmc.h>
 #include <plat/omap4-keypad.h>
-#include <plat/display.h>
+#include <video/omapdss.h>
 
 #include "mux.h"
 #include "hsmmc.h"
 #include "timer-gp.h"
 #include "control.h"
+#include "common-board-devices.h"
 
 #define ETH_KS8851_IRQ			34
 #define ETH_KS8851_POWER_ON		48
@@ -251,58 +252,22 @@
 	},
 };
 
-static int omap_ethernet_init(void)
+static struct gpio sdp4430_eth_gpios[] __initdata = {
+	{ ETH_KS8851_POWER_ON,	GPIOF_OUT_INIT_HIGH,	"eth_power"	},
+	{ ETH_KS8851_QUART,	GPIOF_OUT_INIT_HIGH,	"quart"		},
+	{ ETH_KS8851_IRQ,	GPIOF_IN,		"eth_irq"	},
+};
+
+static int __init omap_ethernet_init(void)
 {
 	int status;
 
 	/* Request of GPIO lines */
+	status = gpio_request_array(sdp4430_eth_gpios,
+				    ARRAY_SIZE(sdp4430_eth_gpios));
+	if (status)
+		pr_err("Cannot request ETH GPIOs\n");
 
-	status = gpio_request(ETH_KS8851_POWER_ON, "eth_power");
-	if (status) {
-		pr_err("Cannot request GPIO %d\n", ETH_KS8851_POWER_ON);
-		return status;
-	}
-
-	status = gpio_request(ETH_KS8851_QUART, "quart");
-	if (status) {
-		pr_err("Cannot request GPIO %d\n", ETH_KS8851_QUART);
-		goto error1;
-	}
-
-	status = gpio_request(ETH_KS8851_IRQ, "eth_irq");
-	if (status) {
-		pr_err("Cannot request GPIO %d\n", ETH_KS8851_IRQ);
-		goto error2;
-	}
-
-	/* Configuration of requested GPIO lines */
-
-	status = gpio_direction_output(ETH_KS8851_POWER_ON, 1);
-	if (status) {
-		pr_err("Cannot set output GPIO %d\n", ETH_KS8851_IRQ);
-		goto error3;
-	}
-
-	status = gpio_direction_output(ETH_KS8851_QUART, 1);
-	if (status) {
-		pr_err("Cannot set output GPIO %d\n", ETH_KS8851_QUART);
-		goto error3;
-	}
-
-	status = gpio_direction_input(ETH_KS8851_IRQ);
-	if (status) {
-		pr_err("Cannot set input GPIO %d\n", ETH_KS8851_IRQ);
-		goto error3;
-	}
-
-	return 0;
-
-error3:
-	gpio_free(ETH_KS8851_IRQ);
-error2:
-	gpio_free(ETH_KS8851_QUART);
-error1:
-	gpio_free(ETH_KS8851_POWER_ON);
 	return status;
 }
 
@@ -357,6 +322,7 @@
 		.gpio_wp	= -EINVAL,
 		.nonremovable   = true,
 		.ocr_mask	= MMC_VDD_29_30,
+		.no_off_init	= true,
 	},
 	{
 		.mmc		= 1,
@@ -575,14 +541,6 @@
 	.usb		= &omap4_usbphy_data
 };
 
-static struct i2c_board_info __initdata sdp4430_i2c_boardinfo[] = {
-	{
-		I2C_BOARD_INFO("twl6030", 0x48),
-		.flags = I2C_CLIENT_WAKE,
-		.irq = OMAP44XX_IRQ_SYS_1N,
-		.platform_data = &sdp4430_twldata,
-	},
-};
 static struct i2c_board_info __initdata sdp4430_i2c_3_boardinfo[] = {
 	{
 		I2C_BOARD_INFO("tmp105", 0x48),
@@ -598,12 +556,7 @@
 };
 static int __init omap4_i2c_init(void)
 {
-	/*
-	 * Phoenix Audio IC needs I2C1 to
-	 * start with 400 KHz or less
-	 */
-	omap_register_i2c_bus(1, 400, sdp4430_i2c_boardinfo,
-			ARRAY_SIZE(sdp4430_i2c_boardinfo));
+	omap4_pmic_init("twl6030", &sdp4430_twldata);
 	omap_register_i2c_bus(2, 400, NULL, 0);
 	omap_register_i2c_bus(3, 400, sdp4430_i2c_3_boardinfo,
 				ARRAY_SIZE(sdp4430_i2c_3_boardinfo));
@@ -614,21 +567,13 @@
 
 static void __init omap_sfh7741prox_init(void)
 {
-	int  error;
+	int error;
 
-	error = gpio_request(OMAP4_SFH7741_ENABLE_GPIO, "sfh7741");
-	if (error < 0) {
+	error = gpio_request_one(OMAP4_SFH7741_ENABLE_GPIO,
+				 GPIOF_OUT_INIT_LOW, "sfh7741");
+	if (error < 0)
 		pr_err("%s:failed to request GPIO %d, error %d\n",
 			__func__, OMAP4_SFH7741_ENABLE_GPIO, error);
-		return;
-	}
-
-	error = gpio_direction_output(OMAP4_SFH7741_ENABLE_GPIO , 0);
-	if (error < 0) {
-		pr_err("%s: GPIO configuration failed: GPIO %d,error %d\n",
-			 __func__, OMAP4_SFH7741_ENABLE_GPIO, error);
-		gpio_free(OMAP4_SFH7741_ENABLE_GPIO);
-	}
 }
 
 static void sdp4430_hdmi_mux_init(void)
@@ -645,27 +590,19 @@
 			OMAP_PIN_INPUT_PULLUP);
 }
 
+static struct gpio sdp4430_hdmi_gpios[] = {
+	{ HDMI_GPIO_HPD,	GPIOF_OUT_INIT_HIGH,	"hdmi_gpio_hpd"   },
+	{ HDMI_GPIO_LS_OE,	GPIOF_OUT_INIT_HIGH,	"hdmi_gpio_ls_oe" },
+};
+
 static int sdp4430_panel_enable_hdmi(struct omap_dss_device *dssdev)
 {
 	int status;
 
-	status = gpio_request_one(HDMI_GPIO_HPD, GPIOF_OUT_INIT_HIGH,
-							"hdmi_gpio_hpd");
-	if (status) {
-		pr_err("Cannot request GPIO %d\n", HDMI_GPIO_HPD);
-		return status;
-	}
-	status = gpio_request_one(HDMI_GPIO_LS_OE, GPIOF_OUT_INIT_HIGH,
-							"hdmi_gpio_ls_oe");
-	if (status) {
-		pr_err("Cannot request GPIO %d\n", HDMI_GPIO_LS_OE);
-		goto error1;
-	}
-
-	return 0;
-
-error1:
-	gpio_free(HDMI_GPIO_HPD);
+	status = gpio_request_array(sdp4430_hdmi_gpios,
+				    ARRAY_SIZE(sdp4430_hdmi_gpios));
+	if (status)
+		pr_err("%s: Cannot request HDMI GPIOs\n", __func__);
 
 	return status;
 }
@@ -680,6 +617,15 @@
 	.name = "hdmi",
 	.driver_name = "hdmi_panel",
 	.type = OMAP_DISPLAY_TYPE_HDMI,
+	.clocks	= {
+		.dispc	= {
+			.dispc_fclk_src	= OMAP_DSS_CLK_SRC_FCK,
+		},
+		.hdmi	= {
+			.regn	= 15,
+			.regm2	= 1,
+		},
+	},
 	.platform_enable = sdp4430_panel_enable_hdmi,
 	.platform_disable = sdp4430_panel_disable_hdmi,
 	.channel = OMAP_DSS_CHANNEL_DIGIT,
@@ -736,19 +682,19 @@
 			 OMAP_PIN_OUTPUT | OMAP_MUX_MODE0),
 };
 
-static struct omap_board_data serial2_data = {
+static struct omap_board_data serial2_data __initdata = {
 	.id		= 1,
 	.pads		= serial2_pads,
 	.pads_cnt	= ARRAY_SIZE(serial2_pads),
 };
 
-static struct omap_board_data serial3_data = {
+static struct omap_board_data serial3_data __initdata = {
 	.id		= 2,
 	.pads		= serial3_pads,
 	.pads_cnt	= ARRAY_SIZE(serial3_pads),
 };
 
-static struct omap_board_data serial4_data = {
+static struct omap_board_data serial4_data __initdata = {
 	.id		= 3,
 	.pads		= serial4_pads,
 	.pads_cnt	= ARRAY_SIZE(serial4_pads),
@@ -784,7 +730,7 @@
 
 	if (omap_rev() == OMAP4430_REV_ES1_0)
 		package = OMAP_PACKAGE_CBL;
-	omap4_mux_init(board_mux, package);
+	omap4_mux_init(board_mux, NULL, package);
 
 	omap_board_config = sdp4430_config;
 	omap_board_config_size = ARRAY_SIZE(sdp4430_config);
diff -druN linux-2.6.39-libre/arch/arm/mach-omap2/board-am3517crane.c linux-3.0-rc7-libre/arch/arm/mach-omap2/board-am3517crane.c
--- linux-2.6.39-libre/arch/arm/mach-omap2/board-am3517crane.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-omap2/board-am3517crane.c	2011-07-11 19:51:52.000000000 -0400
@@ -89,19 +89,13 @@
 		return;
 	}
 
-	ret = gpio_request(GPIO_USB_POWER, "usb_ehci_enable");
+	ret = gpio_request_one(GPIO_USB_POWER, GPIOF_OUT_INIT_HIGH,
+			       "usb_ehci_enable");
 	if (ret < 0) {
 		pr_err("Can not request GPIO %d\n", GPIO_USB_POWER);
 		return;
 	}
 
-	ret = gpio_direction_output(GPIO_USB_POWER, 1);
-	if (ret < 0) {
-		gpio_free(GPIO_USB_POWER);
-		pr_err("Unable to initialize EHCI power\n");
-		return;
-	}
-
 	usbhs_init(&usbhs_bdata);
 }
 
diff -druN linux-2.6.39-libre/arch/arm/mach-omap2/board-am3517evm.c linux-3.0-rc7-libre/arch/arm/mach-omap2/board-am3517evm.c
--- linux-2.6.39-libre/arch/arm/mach-omap2/board-am3517evm.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-omap2/board-am3517evm.c	2011-07-11 19:51:52.000000000 -0400
@@ -34,8 +34,8 @@
 #include <plat/board.h>
 #include <plat/common.h>
 #include <plat/usb.h>
-#include <plat/display.h>
-#include <plat/panel-generic-dpi.h>
+#include <video/omapdss.h>
+#include <video/omap-panel-generic-dpi.h>
 
 #include "mux.h"
 #include "control.h"
@@ -174,19 +174,14 @@
 	int r;
 
 	omap_mux_init_gpio(GPIO_RTCS35390A_IRQ, OMAP_PIN_INPUT_PULLUP);
-	r = gpio_request(GPIO_RTCS35390A_IRQ, "rtcs35390a-irq");
+
+	r = gpio_request_one(GPIO_RTCS35390A_IRQ, GPIOF_IN, "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_i2c1_boardinfo[0].irq = gpio_to_irq(GPIO_RTCS35390A_IRQ);
 }
 
@@ -242,6 +237,15 @@
 
 #if defined(CONFIG_PANEL_SHARP_LQ043T1DG01) || \
 		defined(CONFIG_PANEL_SHARP_LQ043T1DG01_MODULE)
+static struct gpio am3517_evm_dss_gpios[] __initdata = {
+	/* GPIO 182 = LCD Backlight Power */
+	{ LCD_PANEL_BKLIGHT_PWR, GPIOF_OUT_INIT_HIGH, "lcd_backlight_pwr" },
+	/* GPIO 181 = LCD Panel PWM */
+	{ LCD_PANEL_PWM,	 GPIOF_OUT_INIT_HIGH, "lcd bl enable"	  },
+	/* GPIO 176 = LCD Panel Power enable pin */
+	{ LCD_PANEL_PWR,	 GPIOF_OUT_INIT_HIGH, "dvi enable"	  },
+};
+
 static void __init am3517_evm_display_init(void)
 {
 	int r;
@@ -249,41 +253,15 @@
 	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");
+
+	r = gpio_request_array(am3517_evm_dss_gpios,
+			       ARRAY_SIZE(am3517_evm_dss_gpios));
 	if (r) {
-		printk(KERN_ERR "failed to get lcd_backlight_pwr\n");
+		printk(KERN_ERR "failed to get DSS panel control GPIOs\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);
 }
 #else
 static void __init am3517_evm_display_init(void) {}
@@ -396,7 +374,7 @@
 	.power                  = 500,
 	.set_phy_power		= am35x_musb_phy_power,
 	.clear_irq		= am35x_musb_clear_irq,
-	.set_mode		= am35x_musb_set_mode,
+	.set_mode		= am35x_set_mode,
 	.reset			= am35x_musb_reset,
 };
 
diff -druN linux-2.6.39-libre/arch/arm/mach-omap2/board-apollon.c linux-3.0-rc7-libre/arch/arm/mach-omap2/board-apollon.c
--- linux-2.6.39-libre/arch/arm/mach-omap2/board-apollon.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-omap2/board-apollon.c	2011-07-11 19:51:52.000000000 -0400
@@ -27,13 +27,13 @@
 #include <linux/err.h>
 #include <linux/clk.h>
 #include <linux/smc91x.h>
+#include <linux/gpio.h>
 
 #include <mach/hardware.h>
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/flash.h>
 
-#include <mach/gpio.h>
 #include <plat/led.h>
 #include <plat/usb.h>
 #include <plat/board.h>
@@ -202,6 +202,7 @@
 	unsigned int rate;
 	struct clk *gpmc_fck;
 	int eth_cs;
+	int err;
 
 	gpmc_fck = clk_get(NULL, "gpmc_fck");	/* Always on ENABLE_ON_INIT */
 	if (IS_ERR(gpmc_fck)) {
@@ -245,15 +246,13 @@
 	apollon_smc91x_resources[0].end   = base + 0x30f;
 	udelay(100);
 
-	omap_mux_init_gpio(74, 0);
-	if (gpio_request(APOLLON_ETHR_GPIO_IRQ, "SMC91x irq") < 0) {
+	omap_mux_init_gpio(APOLLON_ETHR_GPIO_IRQ, 0);
+	err = gpio_request_one(APOLLON_ETHR_GPIO_IRQ, GPIOF_IN, "SMC91x irq");
+	if (err) {
 		printk(KERN_ERR "Failed to request GPIO%d for smc91x IRQ\n",
 			APOLLON_ETHR_GPIO_IRQ);
 		gpmc_cs_free(APOLLON_ETH_CS);
-		goto out;
 	}
-	gpio_direction_input(APOLLON_ETHR_GPIO_IRQ);
-
 out:
 	clk_disable(gpmc_fck);
 	clk_put(gpmc_fck);
@@ -280,20 +279,19 @@
 	omap2_init_common_devices(NULL, NULL);
 }
 
+static struct gpio apollon_gpio_leds[] __initdata = {
+	{ LED0_GPIO13, GPIOF_OUT_INIT_LOW, "LED0" }, /* LED0 - AA10 */
+	{ LED1_GPIO14, GPIOF_OUT_INIT_LOW, "LED1" }, /* LED1 - AA6  */
+	{ LED2_GPIO15, GPIOF_OUT_INIT_LOW, "LED2" }, /* LED2 - AA4  */
+};
+
 static void __init apollon_led_init(void)
 {
-	/* LED0 - AA10 */
 	omap_mux_init_signal("vlynq_clk.gpio_13", 0);
-	gpio_request(LED0_GPIO13, "LED0");
-	gpio_direction_output(LED0_GPIO13, 0);
-	/* LED1  - AA6 */
 	omap_mux_init_signal("vlynq_rx1.gpio_14", 0);
-	gpio_request(LED1_GPIO14, "LED1");
-	gpio_direction_output(LED1_GPIO14, 0);
-	/* LED2  - AA4 */
 	omap_mux_init_signal("vlynq_rx0.gpio_15", 0);
-	gpio_request(LED2_GPIO15, "LED2");
-	gpio_direction_output(LED2_GPIO15, 0);
+
+	gpio_request_array(apollon_gpio_leds, ARRAY_SIZE(apollon_gpio_leds));
 }
 
 static void __init apollon_usb_init(void)
@@ -301,8 +299,7 @@
 	/* USB device */
 	/* DEVICE_SUSPEND */
 	omap_mux_init_signal("mcbsp2_clkx.gpio_12", 0);
-	gpio_request(12, "USB suspend");
-	gpio_direction_output(12, 0);
+	gpio_request_one(12, GPIOF_OUT_INIT_LOW, "USB suspend");
 	omap2_usbfs_init(&apollon_usb_config);
 }
 
diff -druN linux-2.6.39-libre/arch/arm/mach-omap2/board-cm-t3517.c linux-3.0-rc7-libre/arch/arm/mach-omap2/board-cm-t3517.c
--- linux-2.6.39-libre/arch/arm/mach-omap2/board-cm-t3517.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-omap2/board-cm-t3517.c	2011-07-11 19:51:52.000000000 -0400
@@ -48,6 +48,7 @@
 
 #include "mux.h"
 #include "control.h"
+#include "common-board-devices.h"
 
 #if defined(CONFIG_LEDS_GPIO) || defined(CONFIG_LEDS_GPIO_MODULE)
 static struct gpio_led cm_t3517_leds[] = {
@@ -148,14 +149,13 @@
 {
 	int err;
 
-	err = gpio_request(RTC_CS_EN_GPIO, "rtc cs en");
+	err = gpio_request_one(RTC_CS_EN_GPIO, GPIOF_OUT_INIT_HIGH,
+			       "rtc cs en");
 	if (err) {
 		pr_err("CM-T3517: rtc cs en gpio request failed: %d\n", err);
 		return;
 	}
 
-	gpio_direction_output(RTC_CS_EN_GPIO, 1);
-
 	platform_device_register(&cm_t3517_rtc_device);
 }
 #else
@@ -178,15 +178,15 @@
 	.reset_gpio_port[2]  = -EINVAL,
 };
 
-static int cm_t3517_init_usbh(void)
+static int __init cm_t3517_init_usbh(void)
 {
 	int err;
 
-	err = gpio_request(USB_HUB_RESET_GPIO, "usb hub rst");
+	err = gpio_request_one(USB_HUB_RESET_GPIO, GPIOF_OUT_INIT_LOW,
+			       "usb hub rst");
 	if (err) {
 		pr_err("CM-T3517: usb hub rst gpio request failed: %d\n", err);
 	} else {
-		gpio_direction_output(USB_HUB_RESET_GPIO, 0);
 		udelay(10);
 		gpio_set_value(USB_HUB_RESET_GPIO, 1);
 		msleep(1);
@@ -204,8 +204,6 @@
 #endif
 
 #if defined(CONFIG_MTD_NAND_OMAP2) || defined(CONFIG_MTD_NAND_OMAP2_MODULE)
-#define NAND_BLOCK_SIZE		SZ_128K
-
 static struct mtd_partition cm_t3517_nand_partitions[] = {
 	{
 		.name           = "xloader",
diff -druN linux-2.6.39-libre/arch/arm/mach-omap2/board-cm-t35.c linux-3.0-rc7-libre/arch/arm/mach-omap2/board-cm-t35.c
--- linux-2.6.39-libre/arch/arm/mach-omap2/board-cm-t35.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-omap2/board-cm-t35.c	2011-07-11 19:51:52.000000000 -0400
@@ -45,8 +45,8 @@
 #include <plat/nand.h>
 #include <plat/gpmc.h>
 #include <plat/usb.h>
-#include <plat/display.h>
-#include <plat/panel-generic-dpi.h>
+#include <video/omapdss.h>
+#include <video/omap-panel-generic-dpi.h>
 #include <plat/mcspi.h>
 
 #include <mach/hardware.h>
@@ -54,6 +54,7 @@
 #include "mux.h"
 #include "sdram-micron-mt46h32m32lf-6.h"
 #include "hsmmc.h"
+#include "common-board-devices.h"
 
 #define CM_T35_GPIO_PENDOWN	57
 
@@ -62,90 +63,30 @@
 #define SB_T35_SMSC911X_CS	4
 #define SB_T35_SMSC911X_GPIO	65
 
-#define NAND_BLOCK_SIZE		SZ_128K
-
 #if defined(CONFIG_SMSC911X) || defined(CONFIG_SMSC911X_MODULE)
 #include <linux/smsc911x.h>
+#include <plat/gpmc-smsc911x.h>
 
-static struct smsc911x_platform_config cm_t35_smsc911x_config = {
-	.irq_polarity	= SMSC911X_IRQ_POLARITY_ACTIVE_LOW,
-	.irq_type	= SMSC911X_IRQ_TYPE_OPEN_DRAIN,
-	.flags		= SMSC911X_USE_32BIT | SMSC911X_SAVE_MAC_ADDRESS,
-	.phy_interface	= PHY_INTERFACE_MODE_MII,
-};
-
-static struct resource cm_t35_smsc911x_resources[] = {
-	{
-		.flags	= IORESOURCE_MEM,
-	},
-	{
-		.start	= OMAP_GPIO_IRQ(CM_T35_SMSC911X_GPIO),
-		.end	= OMAP_GPIO_IRQ(CM_T35_SMSC911X_GPIO),
-		.flags	= IORESOURCE_IRQ | IORESOURCE_IRQ_LOWLEVEL,
-	},
-};
-
-static struct platform_device cm_t35_smsc911x_device = {
-	.name		= "smsc911x",
+static struct omap_smsc911x_platform_data cm_t35_smsc911x_cfg = {
 	.id		= 0,
-	.num_resources	= ARRAY_SIZE(cm_t35_smsc911x_resources),
-	.resource	= cm_t35_smsc911x_resources,
-	.dev		= {
-		.platform_data = &cm_t35_smsc911x_config,
-	},
-};
-
-static struct resource sb_t35_smsc911x_resources[] = {
-	{
-		.flags	= IORESOURCE_MEM,
-	},
-	{
-		.start	= OMAP_GPIO_IRQ(SB_T35_SMSC911X_GPIO),
-		.end	= OMAP_GPIO_IRQ(SB_T35_SMSC911X_GPIO),
-		.flags	= IORESOURCE_IRQ | IORESOURCE_IRQ_LOWLEVEL,
-	},
+	.cs             = CM_T35_SMSC911X_CS,
+	.gpio_irq       = CM_T35_SMSC911X_GPIO,
+	.gpio_reset     = -EINVAL,
+	.flags		= SMSC911X_USE_32BIT | SMSC911X_SAVE_MAC_ADDRESS,
 };
 
-static struct platform_device sb_t35_smsc911x_device = {
-	.name		= "smsc911x",
+static struct omap_smsc911x_platform_data sb_t35_smsc911x_cfg = {
 	.id		= 1,
-	.num_resources	= ARRAY_SIZE(sb_t35_smsc911x_resources),
-	.resource	= sb_t35_smsc911x_resources,
-	.dev		= {
-		.platform_data = &cm_t35_smsc911x_config,
-	},
+	.cs             = SB_T35_SMSC911X_CS,
+	.gpio_irq       = SB_T35_SMSC911X_GPIO,
+	.gpio_reset     = -EINVAL,
+	.flags		= SMSC911X_USE_32BIT | SMSC911X_SAVE_MAC_ADDRESS,
 };
 
-static void __init cm_t35_init_smsc911x(struct platform_device *dev,
-					int cs, int irq_gpio)
-{
-	unsigned long cs_mem_base;
-
-	if (gpmc_cs_request(cs, SZ_16M, &cs_mem_base) < 0) {
-		pr_err("CM-T35: Failed request for GPMC mem for smsc911x\n");
-		return;
-	}
-
-	dev->resource[0].start = cs_mem_base + 0x0;
-	dev->resource[0].end   = cs_mem_base + 0xff;
-
-	if ((gpio_request(irq_gpio, "ETH IRQ") == 0) &&
-	    (gpio_direction_input(irq_gpio) == 0)) {
-		gpio_export(irq_gpio, 0);
-	} else {
-		pr_err("CM-T35: could not obtain gpio for SMSC911X IRQ\n");
-		return;
-	}
-
-	platform_device_register(dev);
-}
-
 static void __init cm_t35_init_ethernet(void)
 {
-	cm_t35_init_smsc911x(&cm_t35_smsc911x_device,
-			     CM_T35_SMSC911X_CS, CM_T35_SMSC911X_GPIO);
-	cm_t35_init_smsc911x(&sb_t35_smsc911x_device,
-			     SB_T35_SMSC911X_CS, SB_T35_SMSC911X_GPIO);
+	gpmc_smsc911x_init(&cm_t35_smsc911x_cfg);
+	gpmc_smsc911x_init(&sb_t35_smsc911x_cfg);
 }
 #else
 static inline void __init cm_t35_init_ethernet(void) { return; }
@@ -235,69 +176,10 @@
 static inline void cm_t35_init_nand(void) {}
 #endif
 
-#if defined(CONFIG_TOUCHSCREEN_ADS7846) || \
-	defined(CONFIG_TOUCHSCREEN_ADS7846_MODULE)
-#include <linux/spi/ads7846.h>
-
-static struct omap2_mcspi_device_config ads7846_mcspi_config = {
-	.turbo_mode	= 0,
-	.single_channel	= 1,	/* 0: slave, 1: master */
-};
-
-static int ads7846_get_pendown_state(void)
-{
-	return !gpio_get_value(CM_T35_GPIO_PENDOWN);
-}
-
-static struct ads7846_platform_data ads7846_config = {
-	.x_max			= 0x0fff,
-	.y_max			= 0x0fff,
-	.x_plate_ohms		= 180,
-	.pressure_max		= 255,
-	.debounce_max		= 10,
-	.debounce_tol		= 3,
-	.debounce_rep		= 1,
-	.get_pendown_state	= ads7846_get_pendown_state,
-	.keep_vref_on		= 1,
-};
-
-static struct spi_board_info cm_t35_spi_board_info[] __initdata = {
-	{
-		.modalias		= "ads7846",
-		.bus_num		= 1,
-		.chip_select		= 0,
-		.max_speed_hz		= 1500000,
-		.controller_data	= &ads7846_mcspi_config,
-		.irq			= OMAP_GPIO_IRQ(CM_T35_GPIO_PENDOWN),
-		.platform_data		= &ads7846_config,
-	},
-};
-
-static void __init cm_t35_init_ads7846(void)
-{
-	if ((gpio_request(CM_T35_GPIO_PENDOWN, "ADS7846_PENDOWN") == 0) &&
-	    (gpio_direction_input(CM_T35_GPIO_PENDOWN) == 0)) {
-		gpio_export(CM_T35_GPIO_PENDOWN, 0);
-	} else {
-		pr_err("CM-T35: could not obtain gpio for ADS7846_PENDOWN\n");
-		return;
-	}
-
-	spi_register_board_info(cm_t35_spi_board_info,
-				ARRAY_SIZE(cm_t35_spi_board_info));
-}
-#else
-static inline void cm_t35_init_ads7846(void) {}
-#endif
-
 #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;
 
@@ -308,8 +190,8 @@
 		return -EINVAL;
 	}
 
-	gpio_set_value(lcd_en_gpio, 1);
-	gpio_set_value(lcd_bl_gpio, 1);
+	gpio_set_value(CM_T35_LCD_EN_GPIO, 1);
+	gpio_set_value(CM_T35_LCD_BL_GPIO, 1);
 
 	lcd_enabled = 1;
 
@@ -320,8 +202,8 @@
 {
 	lcd_enabled = 0;
 
-	gpio_set_value(lcd_bl_gpio, 0);
-	gpio_set_value(lcd_en_gpio, 0);
+	gpio_set_value(CM_T35_LCD_BL_GPIO, 0);
+	gpio_set_value(CM_T35_LCD_EN_GPIO, 0);
 }
 
 static int cm_t35_panel_enable_dvi(struct omap_dss_device *dssdev)
@@ -331,7 +213,7 @@
 		return -EINVAL;
 	}
 
-	gpio_set_value(dvi_en_gpio, 0);
+	gpio_set_value(CM_T35_DVI_EN_GPIO, 0);
 	dvi_enabled = 1;
 
 	return 0;
@@ -339,7 +221,7 @@
 
 static void cm_t35_panel_disable_dvi(struct omap_dss_device *dssdev)
 {
-	gpio_set_value(dvi_en_gpio, 1);
+	gpio_set_value(CM_T35_DVI_EN_GPIO, 1);
 	dvi_enabled = 0;
 }
 
@@ -421,62 +303,38 @@
 	},
 };
 
+static struct gpio cm_t35_dss_gpios[] __initdata = {
+	{ CM_T35_LCD_EN_GPIO, GPIOF_OUT_INIT_LOW,  "lcd enable"    },
+	{ CM_T35_LCD_BL_GPIO, GPIOF_OUT_INIT_LOW,  "lcd bl enable" },
+	{ CM_T35_DVI_EN_GPIO, GPIOF_OUT_INIT_HIGH, "dvi enable"    },
+};
+
 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");
+	err = gpio_request_array(cm_t35_dss_gpios,
+				 ARRAY_SIZE(cm_t35_dss_gpios));
 	if (err) {
-		pr_err("CM-T35: failed to get DVI reset GPIO\n");
-		goto err_dvi_en;
+		pr_err("CM-T35: failed to request DSS control GPIOs\n");
+		return;
 	}
 
-	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);
+	gpio_export(CM_T35_LCD_EN_GPIO, 0);
+	gpio_export(CM_T35_LCD_BL_GPIO, 0);
+	gpio_export(CM_T35_DVI_EN_GPIO, 0);
 
 	msleep(50);
-	gpio_set_value(lcd_en_gpio, 1);
+	gpio_set_value(CM_T35_LCD_EN_GPIO, 1);
 
 	err = omap_display_init(&cm_t35_dss_data);
 	if (err) {
 		pr_err("CM-T35: failed to register DSS device\n");
-		goto err_dev_reg;
+		gpio_free_array(cm_t35_dss_gpios, ARRAY_SIZE(cm_t35_dss_gpios));
 	}
-
-	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 = {
@@ -609,10 +467,8 @@
 {
 	int wlan_rst = gpio + 2;
 
-	if ((gpio_request(wlan_rst, "WLAN RST") == 0) &&
-	    (gpio_direction_output(wlan_rst, 1) == 0)) {
+	if (gpio_request_one(wlan_rst, GPIOF_OUT_INIT_HIGH, "WLAN RST") == 0) {
 		gpio_export(wlan_rst, 0);
-
 		udelay(10);
 		gpio_set_value(wlan_rst, 0);
 		udelay(10);
@@ -653,19 +509,9 @@
 	.vpll2		= &cm_t35_vpll2,
 };
 
-static struct i2c_board_info __initdata cm_t35_i2c_boardinfo[] = {
-	{
-		I2C_BOARD_INFO("tps65930", 0x48),
-		.flags		= I2C_CLIENT_WAKE,
-		.irq		= INT_34XX_SYS_NIRQ,
-		.platform_data	= &cm_t35_twldata,
-	},
-};
-
 static void __init cm_t35_init_i2c(void)
 {
-	omap_register_i2c_bus(1, 2600, cm_t35_i2c_boardinfo,
-			      ARRAY_SIZE(cm_t35_i2c_boardinfo));
+	omap3_pmic_init("tps65930", &cm_t35_twldata);
 }
 
 static void __init cm_t35_init_early(void)
@@ -775,12 +621,6 @@
 };
 #endif
 
-static struct omap_musb_board_data musb_board_data = {
-	.interface_type		= MUSB_INTERFACE_ULPI,
-	.mode			= MUSB_OTG,
-	.power			= 100,
-};
-
 static struct omap_board_config_kernel cm_t35_config[] __initdata = {
 };
 
@@ -792,12 +632,12 @@
 	omap_serial_init();
 	cm_t35_init_i2c();
 	cm_t35_init_nand();
-	cm_t35_init_ads7846();
+	omap_ads7846_init(1, CM_T35_GPIO_PENDOWN, 0, NULL);
 	cm_t35_init_ethernet();
 	cm_t35_init_led();
 	cm_t35_init_display();
 
-	usb_musb_init(&musb_board_data);
+	usb_musb_init(NULL);
 	usbhs_init(&usbhs_bdata);
 }
 
diff -druN linux-2.6.39-libre/arch/arm/mach-omap2/board-devkit8000.c linux-3.0-rc7-libre/arch/arm/mach-omap2/board-devkit8000.c
--- linux-2.6.39-libre/arch/arm/mach-omap2/board-devkit8000.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-omap2/board-devkit8000.c	2011-07-11 19:51:52.000000000 -0400
@@ -45,13 +45,12 @@
 #include <plat/gpmc.h>
 #include <plat/nand.h>
 #include <plat/usb.h>
-#include <plat/display.h>
-#include <plat/panel-generic-dpi.h>
+#include <video/omapdss.h>
+#include <video/omap-panel-generic-dpi.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>
 
@@ -60,8 +59,7 @@
 #include "mux.h"
 #include "hsmmc.h"
 #include "timer-gp.h"
-
-#define NAND_BLOCK_SIZE		SZ_128K
+#include "common-board-devices.h"
 
 #define OMAP_DM9000_GPIO_IRQ	25
 #define OMAP3_DEVKIT_TS_GPIO	27
@@ -97,13 +95,6 @@
 	},
 };
 
-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 omap2_hsmmc_info mmc[] = {
 	{
 		.mmc		= 1,
@@ -249,7 +240,7 @@
 	/* TWL4030_GPIO_MAX + 0 is "LCD_PWREN" (out, active high) */
 	devkit8000_lcd_device.reset_gpio = gpio + TWL4030_GPIO_MAX + 0;
 	ret = gpio_request_one(devkit8000_lcd_device.reset_gpio,
-			GPIOF_DIR_OUT | GPIOF_INIT_LOW, "LCD_PWREN");
+			       GPIOF_OUT_INIT_LOW, "LCD_PWREN");
 	if (ret < 0) {
 		devkit8000_lcd_device.reset_gpio = -EINVAL;
 		printk(KERN_ERR "Failed to request GPIO for LCD_PWRN\n");
@@ -258,7 +249,7 @@
 	/* gpio + 7 is "DVI_PD" (out, active low) */
 	devkit8000_dvi_device.reset_gpio = gpio + 7;
 	ret = gpio_request_one(devkit8000_dvi_device.reset_gpio,
-			GPIOF_DIR_OUT | GPIOF_INIT_LOW, "DVI PowerDown");
+			       GPIOF_OUT_INIT_LOW, "DVI PowerDown");
 	if (ret < 0) {
 		devkit8000_dvi_device.reset_gpio = -EINVAL;
 		printk(KERN_ERR "Failed to request GPIO for DVI PowerDown\n");
@@ -366,19 +357,9 @@
 	.keypad		= &devkit8000_kp_data,
 };
 
-static struct i2c_board_info __initdata devkit8000_i2c_boardinfo[] = {
-	{
-		I2C_BOARD_INFO("tps65930", 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));
+	omap3_pmic_init("tps65930", &devkit8000_twldata);
 	/* 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);
@@ -463,56 +444,6 @@
 #endif
 }
 
-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[] = {
@@ -550,14 +481,14 @@
 {
 	unsigned char *eth_addr = omap_dm9000_platdata.dev_addr;
 	struct omap_die_id odi;
+	int ret;
 
-	if (gpio_request(OMAP_DM9000_GPIO_IRQ, "dm9000 irq") < 0) {
+	ret = gpio_request_one(OMAP_DM9000_GPIO_IRQ, GPIOF_IN, "dm9000 irq");
+	if (ret < 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);
+	}
 
 	/* init the mac address using DIE id */
 	omap_get_die_id(&odi);
@@ -576,45 +507,6 @@
 	&omap_dm9000_dev,
 };
 
-static void __init devkit8000_flash_init(void)
-{
-	u8 cs = 0;
-	u8 nandcs = GPMC_CS_NUM + 1;
-
-	/* 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;
-
-		printk(KERN_INFO "Registering NAND on CS%d\n", nandcs);
-		if (gpmc_nand_init(&devkit8000_nand_data) < 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 usbhs_omap_board_data usbhs_bdata __initconst = {
 
 	.port_mode[0] = OMAP_EHCI_PORT_MODE_PHY,
@@ -795,14 +687,13 @@
 			ARRAY_SIZE(devkit8000_devices));
 
 	omap_display_init(&devkit8000_dss_data);
-	spi_register_board_info(devkit8000_spi_board_info,
-	ARRAY_SIZE(devkit8000_spi_board_info));
 
-	devkit8000_ads7846_init();
+	omap_ads7846_init(2, OMAP3_DEVKIT_TS_GPIO, 0, NULL);
 
-	usb_musb_init(&musb_board_data);
+	usb_musb_init(NULL);
 	usbhs_init(&usbhs_bdata);
-	devkit8000_flash_init();
+	omap_nand_flash_init(NAND_BUSWIDTH_16, devkit8000_nand_partitions,
+			     ARRAY_SIZE(devkit8000_nand_partitions));
 
 	/* Ensure SDRC pins are mux'd for self-refresh */
 	omap_mux_init_signal("sdrc_cke0", OMAP_PIN_OUTPUT);
diff -druN linux-2.6.39-libre/arch/arm/mach-omap2/board-igep0020.c linux-3.0-rc7-libre/arch/arm/mach-omap2/board-igep0020.c
--- linux-2.6.39-libre/arch/arm/mach-omap2/board-igep0020.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-omap2/board-igep0020.c	2011-07-11 19:51:52.000000000 -0400
@@ -31,13 +31,14 @@
 #include <plat/common.h>
 #include <plat/gpmc.h>
 #include <plat/usb.h>
-#include <plat/display.h>
-#include <plat/panel-generic-dpi.h>
+#include <video/omapdss.h>
+#include <video/omap-panel-generic-dpi.h>
 #include <plat/onenand.h>
 
 #include "mux.h"
 #include "hsmmc.h"
 #include "sdram-numonyx-m65kxxxxam.h"
+#include "common-board-devices.h"
 
 #define IGEP2_SMSC911X_CS       5
 #define IGEP2_SMSC911X_GPIO     176
@@ -54,6 +55,11 @@
 #define IGEP2_RC_GPIO_WIFI_NRESET  139
 #define IGEP2_RC_GPIO_BT_NRESET    137
 
+#define IGEP3_GPIO_LED0_GREEN	54
+#define IGEP3_GPIO_LED0_RED	53
+#define IGEP3_GPIO_LED1_RED	16
+#define IGEP3_GPIO_USBH_NRESET  183
+
 /*
  * IGEP2 Hardware Revision Table
  *
@@ -68,6 +74,7 @@
 
 #define IGEP2_BOARD_HWREV_B	0
 #define IGEP2_BOARD_HWREV_C	1
+#define IGEP3_BOARD_HWREV	2
 
 static u8 hwrev;
 
@@ -75,24 +82,29 @@
 {
 	u8 ret;
 
+	if (machine_is_igep0030()) {
+		hwrev = IGEP3_BOARD_HWREV;
+		return;
+	}
+
 	omap_mux_init_gpio(IGEP2_GPIO_LED1_RED, OMAP_PIN_INPUT);
 
-	if ((gpio_request(IGEP2_GPIO_LED1_RED, "GPIO_HW0_REV") == 0) &&
-	    (gpio_direction_input(IGEP2_GPIO_LED1_RED) == 0)) {
-		ret = gpio_get_value(IGEP2_GPIO_LED1_RED);
-		if (ret == 0) {
-			pr_info("IGEP2: Hardware Revision C (B-NON compatible)\n");
-			hwrev = IGEP2_BOARD_HWREV_C;
-		} else if (ret ==  1) {
-			pr_info("IGEP2: Hardware Revision B/C (B compatible)\n");
-			hwrev = IGEP2_BOARD_HWREV_B;
-		} else {
-			pr_err("IGEP2: Unknown Hardware Revision\n");
-			hwrev = -1;
-		}
-	} else {
+	if (gpio_request_one(IGEP2_GPIO_LED1_RED, GPIOF_IN, "GPIO_HW0_REV")) {
 		pr_warning("IGEP2: Could not obtain gpio GPIO_HW0_REV\n");
 		pr_err("IGEP2: Unknown Hardware Revision\n");
+		return;
+	}
+
+	ret = gpio_get_value(IGEP2_GPIO_LED1_RED);
+	if (ret == 0) {
+		pr_info("IGEP2: Hardware Revision C (B-NON compatible)\n");
+		hwrev = IGEP2_BOARD_HWREV_C;
+	} else if (ret ==  1) {
+		pr_info("IGEP2: Hardware Revision B/C (B compatible)\n");
+		hwrev = IGEP2_BOARD_HWREV_B;
+	} else {
+		pr_err("IGEP2: Unknown Hardware Revision\n");
+		hwrev = -1;
 	}
 
 	gpio_free(IGEP2_GPIO_LED1_RED);
@@ -111,7 +123,7 @@
  * So MTD regards it as 4KiB page size and 256KiB block size 64*(2*2048)
  */
 
-static struct mtd_partition igep2_onenand_partitions[] = {
+static struct mtd_partition igep_onenand_partitions[] = {
 	{
 		.name           = "X-Loader",
 		.offset         = 0,
@@ -139,21 +151,21 @@
 	},
 };
 
-static struct omap_onenand_platform_data igep2_onenand_data = {
-	.parts = igep2_onenand_partitions,
-	.nr_parts = ARRAY_SIZE(igep2_onenand_partitions),
+static struct omap_onenand_platform_data igep_onenand_data = {
+	.parts = igep_onenand_partitions,
+	.nr_parts = ARRAY_SIZE(igep_onenand_partitions),
 	.dma_channel	= -1,	/* disable DMA in OMAP OneNAND driver */
 };
 
-static struct platform_device igep2_onenand_device = {
+static struct platform_device igep_onenand_device = {
 	.name		= "omap2-onenand",
 	.id		= -1,
 	.dev = {
-		.platform_data = &igep2_onenand_data,
+		.platform_data = &igep_onenand_data,
 	},
 };
 
-static void __init igep2_flash_init(void)
+static void __init igep_flash_init(void)
 {
 	u8 cs = 0;
 	u8 onenandcs = GPMC_CS_NUM + 1;
@@ -165,7 +177,7 @@
 		/* Check if NAND/oneNAND is configured */
 		if ((ret & 0xC00) == 0x800)
 			/* NAND found */
-			pr_err("IGEP2: Unsupported NAND found\n");
+			pr_err("IGEP: Unsupported NAND found\n");
 		else {
 			ret = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG7);
 			if ((ret & 0x3F) == (ONENAND_MAP >> 24))
@@ -175,85 +187,46 @@
 	}
 
 	if (onenandcs > GPMC_CS_NUM) {
-		pr_err("IGEP2: Unable to find configuration in GPMC\n");
+		pr_err("IGEP: Unable to find configuration in GPMC\n");
 		return;
 	}
 
-	igep2_onenand_data.cs = onenandcs;
+	igep_onenand_data.cs = onenandcs;
 
-	if (platform_device_register(&igep2_onenand_device) < 0)
-		pr_err("IGEP2: Unable to register OneNAND device\n");
+	if (platform_device_register(&igep_onenand_device) < 0)
+		pr_err("IGEP: Unable to register OneNAND device\n");
 }
 
 #else
-static void __init igep2_flash_init(void) {}
+static void __init igep_flash_init(void) {}
 #endif
 
 #if defined(CONFIG_SMSC911X) || defined(CONFIG_SMSC911X_MODULE)
 
 #include <linux/smsc911x.h>
+#include <plat/gpmc-smsc911x.h>
 
-static struct smsc911x_platform_config igep2_smsc911x_config = {
-	.irq_polarity	= SMSC911X_IRQ_POLARITY_ACTIVE_LOW,
-	.irq_type	= SMSC911X_IRQ_TYPE_OPEN_DRAIN,
-	.flags		= SMSC911X_USE_32BIT | SMSC911X_SAVE_MAC_ADDRESS  ,
-	.phy_interface	= PHY_INTERFACE_MODE_MII,
-};
-
-static struct resource igep2_smsc911x_resources[] = {
-	{
-		.flags	= IORESOURCE_MEM,
-	},
-	{
-		.start	= OMAP_GPIO_IRQ(IGEP2_SMSC911X_GPIO),
-		.end	= OMAP_GPIO_IRQ(IGEP2_SMSC911X_GPIO),
-		.flags	= IORESOURCE_IRQ | IORESOURCE_IRQ_LOWLEVEL,
-	},
-};
-
-static struct platform_device igep2_smsc911x_device = {
-	.name		= "smsc911x",
-	.id		= 0,
-	.num_resources	= ARRAY_SIZE(igep2_smsc911x_resources),
-	.resource	= igep2_smsc911x_resources,
-	.dev		= {
-		.platform_data = &igep2_smsc911x_config,
-	},
+static struct omap_smsc911x_platform_data smsc911x_cfg = {
+	.cs             = IGEP2_SMSC911X_CS,
+	.gpio_irq       = IGEP2_SMSC911X_GPIO,
+	.gpio_reset     = -EINVAL,
+	.flags		= SMSC911X_USE_32BIT | SMSC911X_SAVE_MAC_ADDRESS,
 };
 
 static inline void __init igep2_init_smsc911x(void)
 {
-	unsigned long cs_mem_base;
-
-	if (gpmc_cs_request(IGEP2_SMSC911X_CS, SZ_16M, &cs_mem_base) < 0) {
-		pr_err("IGEP v2: Failed request for GPMC mem for smsc911x\n");
-		gpmc_cs_free(IGEP2_SMSC911X_CS);
-		return;
-	}
-
-	igep2_smsc911x_resources[0].start = cs_mem_base + 0x0;
-	igep2_smsc911x_resources[0].end   = cs_mem_base + 0xff;
-
-	if ((gpio_request(IGEP2_SMSC911X_GPIO, "SMSC911X IRQ") == 0) &&
-	    (gpio_direction_input(IGEP2_SMSC911X_GPIO) == 0)) {
-		gpio_export(IGEP2_SMSC911X_GPIO, 0);
-	} else {
-		pr_err("IGEP v2: Could not obtain gpio for for SMSC911X IRQ\n");
-		return;
-	}
-
-	platform_device_register(&igep2_smsc911x_device);
+	gpmc_smsc911x_init(&smsc911x_cfg);
 }
 
 #else
 static inline void __init igep2_init_smsc911x(void) { }
 #endif
 
-static struct regulator_consumer_supply igep2_vmmc1_supply =
+static struct regulator_consumer_supply igep_vmmc1_supply =
 	REGULATOR_SUPPLY("vmmc", "omap_hsmmc.0");
 
 /* VMMC1 for OMAP VDD_MMC1 (i/o) and MMC1 card */
-static struct regulator_init_data igep2_vmmc1 = {
+static struct regulator_init_data igep_vmmc1 = {
 	.constraints = {
 		.min_uV			= 1850000,
 		.max_uV			= 3150000,
@@ -264,13 +237,13 @@
 					| REGULATOR_CHANGE_STATUS,
 	},
 	.num_consumer_supplies  = 1,
-	.consumer_supplies      = &igep2_vmmc1_supply,
+	.consumer_supplies      = &igep_vmmc1_supply,
 };
 
-static struct regulator_consumer_supply igep2_vio_supply =
+static struct regulator_consumer_supply igep_vio_supply =
 	REGULATOR_SUPPLY("vmmc_aux", "omap_hsmmc.1");
 
-static struct regulator_init_data igep2_vio = {
+static struct regulator_init_data igep_vio = {
 	.constraints = {
 		.min_uV			= 1800000,
 		.max_uV			= 1800000,
@@ -282,34 +255,34 @@
 					| REGULATOR_CHANGE_STATUS,
 	},
 	.num_consumer_supplies  = 1,
-	.consumer_supplies      = &igep2_vio_supply,
+	.consumer_supplies      = &igep_vio_supply,
 };
 
-static struct regulator_consumer_supply igep2_vmmc2_supply =
+static struct regulator_consumer_supply igep_vmmc2_supply =
 	REGULATOR_SUPPLY("vmmc", "omap_hsmmc.1");
 
-static struct regulator_init_data igep2_vmmc2 = {
+static struct regulator_init_data igep_vmmc2 = {
 	.constraints		= {
 		.valid_modes_mask	= REGULATOR_MODE_NORMAL,
 		.always_on		= 1,
 	},
 	.num_consumer_supplies	= 1,
-	.consumer_supplies	= &igep2_vmmc2_supply,
+	.consumer_supplies	= &igep_vmmc2_supply,
 };
 
-static struct fixed_voltage_config igep2_vwlan = {
+static struct fixed_voltage_config igep_vwlan = {
 	.supply_name		= "vwlan",
 	.microvolts		= 3300000,
 	.gpio			= -EINVAL,
 	.enabled_at_boot	= 1,
-	.init_data		= &igep2_vmmc2,
+	.init_data		= &igep_vmmc2,
 };
 
-static struct platform_device igep2_vwlan_device = {
+static struct platform_device igep_vwlan_device = {
 	.name		= "reg-fixed-voltage",
 	.id		= 0,
 	.dev = {
-		.platform_data	= &igep2_vwlan,
+		.platform_data	= &igep_vwlan,
 	},
 };
 
@@ -334,20 +307,17 @@
 #if defined(CONFIG_LEDS_GPIO) || defined(CONFIG_LEDS_GPIO_MODULE)
 #include <linux/leds.h>
 
-static struct gpio_led igep2_gpio_leds[] = {
+static struct gpio_led igep_gpio_leds[] = {
 	[0] = {
 		.name			= "gpio-led:red:d0",
-		.gpio			= IGEP2_GPIO_LED0_RED,
 		.default_trigger	= "default-off"
 	},
 	[1] = {
 		.name			= "gpio-led:green:d0",
-		.gpio			= IGEP2_GPIO_LED0_GREEN,
 		.default_trigger	= "default-off",
 	},
 	[2] = {
 		.name			= "gpio-led:red:d1",
-		.gpio			= IGEP2_GPIO_LED1_RED,
 		.default_trigger	= "default-off",
 	},
 	[3] = {
@@ -358,94 +328,119 @@
 	},
 };
 
-static struct gpio_led_platform_data igep2_led_pdata = {
-	.leds           = igep2_gpio_leds,
-	.num_leds       = ARRAY_SIZE(igep2_gpio_leds),
+static struct gpio_led_platform_data igep_led_pdata = {
+	.leds           = igep_gpio_leds,
+	.num_leds       = ARRAY_SIZE(igep_gpio_leds),
 };
 
-static struct platform_device igep2_led_device = {
+static struct platform_device igep_led_device = {
 	 .name   = "leds-gpio",
 	 .id     = -1,
 	 .dev    = {
-		 .platform_data  =  &igep2_led_pdata,
+		 .platform_data  =  &igep_led_pdata,
 	},
 };
 
-static void __init igep2_leds_init(void)
+static void __init igep_leds_init(void)
 {
-	platform_device_register(&igep2_led_device);
+	if (machine_is_igep0020()) {
+		igep_gpio_leds[0].gpio = IGEP2_GPIO_LED0_RED;
+		igep_gpio_leds[1].gpio = IGEP2_GPIO_LED0_GREEN;
+		igep_gpio_leds[2].gpio = IGEP2_GPIO_LED1_RED;
+	} else {
+		igep_gpio_leds[0].gpio = IGEP3_GPIO_LED0_RED;
+		igep_gpio_leds[1].gpio = IGEP3_GPIO_LED0_GREEN;
+		igep_gpio_leds[2].gpio = IGEP3_GPIO_LED1_RED;
+	}
+
+	platform_device_register(&igep_led_device);
 }
 
 #else
-static inline void igep2_leds_init(void)
+static struct gpio igep_gpio_leds[] __initdata = {
+	{ -EINVAL,	GPIOF_OUT_INIT_LOW, "gpio-led:red:d0"   },
+	{ -EINVAL,	GPIOF_OUT_INIT_LOW, "gpio-led:green:d0" },
+	{ -EINVAL,	GPIOF_OUT_INIT_LOW, "gpio-led:red:d1"   },
+};
+
+static inline void igep_leds_init(void)
 {
-	if ((gpio_request(IGEP2_GPIO_LED0_RED, "gpio-led:red:d0") == 0) &&
-	    (gpio_direction_output(IGEP2_GPIO_LED0_RED, 0) == 0))
-		gpio_export(IGEP2_GPIO_LED0_RED, 0);
-	else
-		pr_warning("IGEP v2: Could not obtain gpio GPIO_LED0_RED\n");
+	int i;
 
-	if ((gpio_request(IGEP2_GPIO_LED0_GREEN, "gpio-led:green:d0") == 0) &&
-	    (gpio_direction_output(IGEP2_GPIO_LED0_GREEN, 0) == 0))
-		gpio_export(IGEP2_GPIO_LED0_GREEN, 0);
-	else
-		pr_warning("IGEP v2: Could not obtain gpio GPIO_LED0_GREEN\n");
+	if (machine_is_igep0020()) {
+		igep_gpio_leds[0].gpio = IGEP2_GPIO_LED0_RED;
+		igep_gpio_leds[1].gpio = IGEP2_GPIO_LED0_GREEN;
+		igep_gpio_leds[2].gpio = IGEP2_GPIO_LED1_RED;
+	} else {
+		igep_gpio_leds[0].gpio = IGEP3_GPIO_LED0_RED;
+		igep_gpio_leds[1].gpio = IGEP3_GPIO_LED0_GREEN;
+		igep_gpio_leds[2].gpio = IGEP3_GPIO_LED1_RED;
+	}
 
-	if ((gpio_request(IGEP2_GPIO_LED1_RED, "gpio-led:red:d1") == 0) &&
-	    (gpio_direction_output(IGEP2_GPIO_LED1_RED, 0) == 0))
-		gpio_export(IGEP2_GPIO_LED1_RED, 0);
-	else
-		pr_warning("IGEP v2: Could not obtain gpio GPIO_LED1_RED\n");
+	if (gpio_request_array(igep_gpio_leds, ARRAY_SIZE(igep_gpio_leds))) {
+		pr_warning("IGEP v2: Could not obtain leds gpios\n");
+		return;
+	}
 
+	for (i = 0; i < ARRAY_SIZE(igep_gpio_leds); i++)
+		gpio_export(igep_gpio_leds[i].gpio, 0);
 }
 #endif
 
-static int igep2_twl_gpio_setup(struct device *dev,
+static struct gpio igep2_twl_gpios[] = {
+	{ -EINVAL, GPIOF_IN,		"GPIO_EHCI_NOC"  },
+	{ -EINVAL, GPIOF_OUT_INIT_LOW,	"GPIO_USBH_CPEN" },
+};
+
+static int igep_twl_gpio_setup(struct device *dev,
 		unsigned gpio, unsigned ngpio)
 {
+	int ret;
+
 	/* gpio + 0 is "mmc0_cd" (input/IRQ) */
 	mmc[0].gpio_cd = gpio + 0;
 	omap2_hsmmc_init(mmc);
 
-	/*
-	 * REVISIT: need ehci-omap hooks for external VBUS
-	 * power switch and overcurrent detect
-	 */
-	if ((gpio_request(gpio + 1, "GPIO_EHCI_NOC") < 0) ||
-	    (gpio_direction_input(gpio + 1) < 0))
-		pr_err("IGEP2: Could not obtain gpio for EHCI NOC");
-
-	/*
-	 * TWL4030_GPIO_MAX + 0 == ledA, GPIO_USBH_CPEN
-	 * (out, active low)
-	 */
-	if ((gpio_request(gpio + TWL4030_GPIO_MAX, "GPIO_USBH_CPEN") < 0) ||
-	    (gpio_direction_output(gpio + TWL4030_GPIO_MAX, 0) < 0))
-		pr_err("IGEP2: Could not obtain gpio for USBH_CPEN");
-
 	/* TWL4030_GPIO_MAX + 1 == ledB (out, active low LED) */
 #if !defined(CONFIG_LEDS_GPIO) && !defined(CONFIG_LEDS_GPIO_MODULE)
-	if ((gpio_request(gpio+TWL4030_GPIO_MAX+1, "gpio-led:green:d1") == 0)
-	    && (gpio_direction_output(gpio + TWL4030_GPIO_MAX + 1, 1) == 0))
+	ret = gpio_request_one(gpio + TWL4030_GPIO_MAX + 1, GPIOF_OUT_INIT_HIGH,
+			       "gpio-led:green:d1");
+	if (ret == 0)
 		gpio_export(gpio + TWL4030_GPIO_MAX + 1, 0);
 	else
-		pr_warning("IGEP v2: Could not obtain gpio GPIO_LED1_GREEN\n");
+		pr_warning("IGEP: Could not obtain gpio GPIO_LED1_GREEN\n");
 #else
-	igep2_gpio_leds[3].gpio = gpio + TWL4030_GPIO_MAX + 1;
+	igep_gpio_leds[3].gpio = gpio + TWL4030_GPIO_MAX + 1;
 #endif
 
+	if (machine_is_igep0030())
+		return 0;
+
+	/*
+	 * REVISIT: need ehci-omap hooks for external VBUS
+	 * power switch and overcurrent detect
+	 */
+	igep2_twl_gpios[0].gpio = gpio + 1;
+
+	/* TWL4030_GPIO_MAX + 0 == ledA, GPIO_USBH_CPEN (out, active low) */
+	igep2_twl_gpios[1].gpio = gpio + TWL4030_GPIO_MAX;
+
+	ret = gpio_request_array(igep2_twl_gpios, ARRAY_SIZE(igep2_twl_gpios));
+	if (ret < 0)
+		pr_err("IGEP2: Could not obtain gpio for USBH_CPEN");
+
 	return 0;
 };
 
-static struct twl4030_gpio_platform_data igep2_twl4030_gpio_pdata = {
+static struct twl4030_gpio_platform_data igep_twl4030_gpio_pdata = {
 	.gpio_base	= OMAP_MAX_GPIO_LINES,
 	.irq_base	= TWL4030_GPIO_IRQ_BASE,
 	.irq_end	= TWL4030_GPIO_IRQ_END,
 	.use_leds	= true,
-	.setup		= igep2_twl_gpio_setup,
+	.setup		= igep_twl_gpio_setup,
 };
 
-static struct twl4030_usb_data igep2_usb_data = {
+static struct twl4030_usb_data igep_usb_data = {
 	.usb_mode	= T2_USB_MODE_ULPI,
 };
 
@@ -507,16 +502,17 @@
 
 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))
+	int err = gpio_request_one(IGEP2_GPIO_DVI_PUP, GPIOF_OUT_INIT_HIGH,
+				   "GPIO_DVI_PUP");
+	if (err)
 		pr_err("IGEP v2: Could not obtain gpio GPIO_DVI_PUP\n");
 }
 
-static struct platform_device *igep2_devices[] __initdata = {
-	&igep2_vwlan_device,
+static struct platform_device *igep_devices[] __initdata = {
+	&igep_vwlan_device,
 };
 
-static void __init igep2_init_early(void)
+static void __init igep_init_early(void)
 {
 	omap2_init_common_infrastructure();
 	omap2_init_common_devices(m65kxxxxam_sdrc_params,
@@ -561,27 +557,15 @@
 	.rep		= 1,
 };
 
-static struct twl4030_platform_data igep2_twldata = {
+static struct twl4030_platform_data igep_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_twl4030_gpio_pdata,
-	.keypad		= &igep2_keypad_pdata,
-	.vmmc1          = &igep2_vmmc1,
-	.vpll2		= &igep2_vpll2,
-	.vio		= &igep2_vio,
-};
-
-static struct i2c_board_info __initdata igep2_i2c1_boardinfo[] = {
-	{
-		I2C_BOARD_INFO("twl4030", 0x48),
-		.flags		= I2C_CLIENT_WAKE,
-		.irq		= INT_34XX_SYS_NIRQ,
-		.platform_data	= &igep2_twldata,
-	},
+	.usb		= &igep_usb_data,
+	.gpio		= &igep_twl4030_gpio_pdata,
+	.vmmc1          = &igep_vmmc1,
+	.vio		= &igep_vio,
 };
 
 static struct i2c_board_info __initdata igep2_i2c3_boardinfo[] = {
@@ -590,32 +574,29 @@
 	},
 };
 
-static void __init igep2_i2c_init(void)
+static void __init igep_i2c_init(void)
 {
 	int ret;
 
-	ret = omap_register_i2c_bus(1, 2600, igep2_i2c1_boardinfo,
-		ARRAY_SIZE(igep2_i2c1_boardinfo));
-	if (ret)
-		pr_warning("IGEP2: Could not register I2C1 bus (%d)\n", ret);
+	if (machine_is_igep0020()) {
+		/*
+		 * Bus 3 is attached to the DVI port where devices like the
+		 * pico DLP projector don't work reliably with 400kHz
+		 */
+		ret = omap_register_i2c_bus(3, 100, igep2_i2c3_boardinfo,
+					    ARRAY_SIZE(igep2_i2c3_boardinfo));
+		if (ret)
+			pr_warning("IGEP2: Could not register I2C3 bus (%d)\n", ret);
 
-	/*
-	 * Bus 3 is attached to the DVI port where devices like the pico DLP
-	 * projector don't work reliably with 400kHz
-	 */
-	ret = omap_register_i2c_bus(3, 100, igep2_i2c3_boardinfo,
-		ARRAY_SIZE(igep2_i2c3_boardinfo));
-	if (ret)
-		pr_warning("IGEP2: Could not register I2C3 bus (%d)\n", ret);
-}
+		igep_twldata.codec	= &igep2_codec_data;
+		igep_twldata.keypad	= &igep2_keypad_pdata;
+		igep_twldata.vpll2	= &igep2_vpll2;
+	}
 
-static struct omap_musb_board_data musb_board_data = {
-	.interface_type		= MUSB_INTERFACE_ULPI,
-	.mode			= MUSB_OTG,
-	.power			= 100,
-};
+	omap3_pmic_init("twl4030", &igep_twldata);
+}
 
-static const struct usbhs_omap_board_data usbhs_bdata __initconst = {
+static const struct usbhs_omap_board_data igep2_usbhs_bdata __initconst = {
 	.port_mode[0] = OMAP_EHCI_PORT_MODE_PHY,
 	.port_mode[1] = OMAP_USBHS_PORT_MODE_UNUSED,
 	.port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED,
@@ -626,6 +607,17 @@
 	.reset_gpio_port[2] = -EINVAL,
 };
 
+static const struct usbhs_omap_board_data igep3_usbhs_bdata __initconst = {
+	.port_mode[0] = OMAP_USBHS_PORT_MODE_UNUSED,
+	.port_mode[1] = OMAP_EHCI_PORT_MODE_PHY,
+	.port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED,
+
+	.phy_reset = true,
+	.reset_gpio_port[0] = -EINVAL,
+	.reset_gpio_port[1] = IGEP3_GPIO_USBH_NRESET,
+	.reset_gpio_port[2] = -EINVAL,
+};
+
 #ifdef CONFIG_OMAP_MUX
 static struct omap_board_mux board_mux[] __initdata = {
 	{ .reg_offset = OMAP_MUX_TERMINATOR },
@@ -633,82 +625,95 @@
 #endif
 
 #if defined(CONFIG_LIBERTAS_SDIO) || defined(CONFIG_LIBERTAS_SDIO_MODULE)
+static struct gpio igep_wlan_bt_gpios[] __initdata = {
+	{ -EINVAL, GPIOF_OUT_INIT_HIGH, "GPIO_WIFI_NPD"	   },
+	{ -EINVAL, GPIOF_OUT_INIT_HIGH, "GPIO_WIFI_NRESET" },
+	{ -EINVAL, GPIOF_OUT_INIT_HIGH, "GPIO_BT_NRESET"   },
+};
 
-static void __init igep2_wlan_bt_init(void)
+static void __init igep_wlan_bt_init(void)
 {
-	unsigned npd, wreset, btreset;
+	int err;
 
 	/* GPIO's for WLAN-BT combo depends on hardware revision */
 	if (hwrev == IGEP2_BOARD_HWREV_B) {
-		npd = IGEP2_RB_GPIO_WIFI_NPD;
-		wreset = IGEP2_RB_GPIO_WIFI_NRESET;
-		btreset = IGEP2_RB_GPIO_BT_NRESET;
-	} else if (hwrev == IGEP2_BOARD_HWREV_C) {
-		npd = IGEP2_RC_GPIO_WIFI_NPD;
-		wreset = IGEP2_RC_GPIO_WIFI_NRESET;
-		btreset = IGEP2_RC_GPIO_BT_NRESET;
+		igep_wlan_bt_gpios[0].gpio = IGEP2_RB_GPIO_WIFI_NPD;
+		igep_wlan_bt_gpios[1].gpio = IGEP2_RB_GPIO_WIFI_NRESET;
+		igep_wlan_bt_gpios[2].gpio = IGEP2_RB_GPIO_BT_NRESET;
+	} else if (hwrev == IGEP2_BOARD_HWREV_C || machine_is_igep0030()) {
+		igep_wlan_bt_gpios[0].gpio = IGEP2_RC_GPIO_WIFI_NPD;
+		igep_wlan_bt_gpios[1].gpio = IGEP2_RC_GPIO_WIFI_NRESET;
+		igep_wlan_bt_gpios[2].gpio = IGEP2_RC_GPIO_BT_NRESET;
 	} else
 		return;
 
-	/* Set GPIO's for  WLAN-BT combo module */
-	if ((gpio_request(npd, "GPIO_WIFI_NPD") == 0) &&
-	    (gpio_direction_output(npd, 1) == 0)) {
-		gpio_export(npd, 0);
-	} else
-		pr_warning("IGEP2: Could not obtain gpio GPIO_WIFI_NPD\n");
+	err = gpio_request_array(igep_wlan_bt_gpios,
+				 ARRAY_SIZE(igep_wlan_bt_gpios));
+	if (err) {
+		pr_warning("IGEP2: Could not obtain WIFI/BT gpios\n");
+		return;
+	}
 
-	if ((gpio_request(wreset, "GPIO_WIFI_NRESET") == 0) &&
-	    (gpio_direction_output(wreset, 1) == 0)) {
-		gpio_export(wreset, 0);
-		gpio_set_value(wreset, 0);
-		udelay(10);
-		gpio_set_value(wreset, 1);
-	} else
-		pr_warning("IGEP2: Could not obtain gpio GPIO_WIFI_NRESET\n");
+	gpio_export(igep_wlan_bt_gpios[0].gpio, 0);
+	gpio_export(igep_wlan_bt_gpios[1].gpio, 0);
+	gpio_export(igep_wlan_bt_gpios[2].gpio, 0);
+
+	gpio_set_value(igep_wlan_bt_gpios[1].gpio, 0);
+	udelay(10);
+	gpio_set_value(igep_wlan_bt_gpios[1].gpio, 1);
 
-	if ((gpio_request(btreset, "GPIO_BT_NRESET") == 0) &&
-	    (gpio_direction_output(btreset, 1) == 0)) {
-		gpio_export(btreset, 0);
-	} else
-		pr_warning("IGEP2: Could not obtain gpio GPIO_BT_NRESET\n");
 }
 #else
-static inline void __init igep2_wlan_bt_init(void) { }
+static inline void __init igep_wlan_bt_init(void) { }
 #endif
 
-static void __init igep2_init(void)
+static void __init igep_init(void)
 {
 	omap3_mux_init(board_mux, OMAP_PACKAGE_CBB);
 
 	/* Get IGEP2 hardware revision */
 	igep2_get_revision();
 	/* Register I2C busses and drivers */
-	igep2_i2c_init();
-	platform_add_devices(igep2_devices, ARRAY_SIZE(igep2_devices));
-	omap_display_init(&igep2_dss_data);
+	igep_i2c_init();
+	platform_add_devices(igep_devices, ARRAY_SIZE(igep_devices));
 	omap_serial_init();
-	usb_musb_init(&musb_board_data);
-	usbhs_init(&usbhs_bdata);
+	usb_musb_init(NULL);
 
-	igep2_flash_init();
-	igep2_leds_init();
-	igep2_display_init();
-	igep2_init_smsc911x();
+	igep_flash_init();
+	igep_leds_init();
 
 	/*
 	 * WLAN-BT combo module from MuRata which has a Marvell WLAN
 	 * (88W8686) + CSR Bluetooth chipset. Uses SDIO interface.
 	 */
-	igep2_wlan_bt_init();
+	igep_wlan_bt_init();
 
+	if (machine_is_igep0020()) {
+		omap_display_init(&igep2_dss_data);
+		igep2_display_init();
+		igep2_init_smsc911x();
+		usbhs_init(&igep2_usbhs_bdata);
+	} else {
+		usbhs_init(&igep3_usbhs_bdata);
+	}
 }
 
 MACHINE_START(IGEP0020, "IGEP v2 board")
 	.boot_params	= 0x80000100,
 	.reserve	= omap_reserve,
 	.map_io		= omap3_map_io,
-	.init_early	= igep2_init_early,
+	.init_early	= igep_init_early,
 	.init_irq	= omap_init_irq,
-	.init_machine	= igep2_init,
+	.init_machine	= igep_init,
+	.timer		= &omap_timer,
+MACHINE_END
+
+MACHINE_START(IGEP0030, "IGEP OMAP3 module")
+	.boot_params	= 0x80000100,
+	.reserve	= omap_reserve,
+	.map_io		= omap3_map_io,
+	.init_early	= igep_init_early,
+	.init_irq	= omap_init_irq,
+	.init_machine	= igep_init,
 	.timer		= &omap_timer,
 MACHINE_END
diff -druN linux-2.6.39-libre/arch/arm/mach-omap2/board-igep0030.c linux-3.0-rc7-libre/arch/arm/mach-omap2/board-igep0030.c
--- linux-2.6.39-libre/arch/arm/mach-omap2/board-igep0030.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-omap2/board-igep0030.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,458 +0,0 @@
-/*
- * Copyright (C) 2010 - ISEE 2007 SL
- *
- * Modified from mach-omap2/board-generic.c
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/platform_device.h>
-#include <linux/delay.h>
-#include <linux/err.h>
-#include <linux/clk.h>
-#include <linux/io.h>
-#include <linux/gpio.h>
-#include <linux/interrupt.h>
-
-#include <linux/regulator/machine.h>
-#include <linux/regulator/fixed.h>
-#include <linux/i2c/twl.h>
-#include <linux/mmc/host.h>
-
-#include <asm/mach-types.h>
-#include <asm/mach/arch.h>
-
-#include <plat/board.h>
-#include <plat/common.h>
-#include <plat/gpmc.h>
-#include <plat/usb.h>
-#include <plat/onenand.h>
-
-#include "mux.h"
-#include "hsmmc.h"
-#include "sdram-numonyx-m65kxxxxam.h"
-
-#define IGEP3_GPIO_LED0_GREEN	54
-#define IGEP3_GPIO_LED0_RED	53
-#define IGEP3_GPIO_LED1_RED	16
-
-#define IGEP3_GPIO_WIFI_NPD	138
-#define IGEP3_GPIO_WIFI_NRESET	139
-#define IGEP3_GPIO_BT_NRESET	137
-
-#define IGEP3_GPIO_USBH_NRESET  183
-
-
-#if defined(CONFIG_MTD_ONENAND_OMAP2) || \
-	defined(CONFIG_MTD_ONENAND_OMAP2_MODULE)
-
-#define ONENAND_MAP             0x20000000
-
-/*
- * 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 igep3_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 struct omap_onenand_platform_data igep3_onenand_pdata = {
-	.parts = igep3_onenand_partitions,
-	.nr_parts = ARRAY_SIZE(igep3_onenand_partitions),
-	.onenand_setup = NULL,
-	.dma_channel	= -1,	/* disable DMA in OMAP OneNAND driver */
-};
-
-static struct platform_device igep3_onenand_device = {
-	.name		= "omap2-onenand",
-	.id		= -1,
-	.dev = {
-		.platform_data = &igep3_onenand_pdata,
-	},
-};
-
-static void __init igep3_flash_init(void)
-{
-	u8 cs = 0;
-	u8 onenandcs = GPMC_CS_NUM + 1;
-
-	for (cs = 0; cs < GPMC_CS_NUM; cs++) {
-		u32 ret;
-		ret = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG1);
-
-		/* Check if NAND/oneNAND is configured */
-		if ((ret & 0xC00) == 0x800)
-			/* NAND found */
-			pr_err("IGEP3: Unsupported NAND found\n");
-		else {
-			ret = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG7);
-
-			if ((ret & 0x3F) == (ONENAND_MAP >> 24))
-				/* OneNAND found */
-				onenandcs = cs;
-		}
-	}
-
-	if (onenandcs > GPMC_CS_NUM) {
-		pr_err("IGEP3: Unable to find configuration in GPMC\n");
-		return;
-	}
-
-	igep3_onenand_pdata.cs = onenandcs;
-
-	if (platform_device_register(&igep3_onenand_device) < 0)
-		pr_err("IGEP3: Unable to register OneNAND device\n");
-}
-
-#else
-static void __init igep3_flash_init(void) {}
-#endif
-
-static struct regulator_consumer_supply igep3_vmmc1_supply =
-	REGULATOR_SUPPLY("vmmc", "omap_hsmmc.0");
-
-/* VMMC1 for OMAP VDD_MMC1 (i/o) and MMC1 card */
-static struct regulator_init_data igep3_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      = &igep3_vmmc1_supply,
-};
-
-static struct regulator_consumer_supply igep3_vio_supply =
-	REGULATOR_SUPPLY("vmmc_aux", "omap_hsmmc.1");
-
-static struct regulator_init_data igep3_vio = {
-	.constraints = {
-		.min_uV			= 1800000,
-		.max_uV			= 1800000,
-		.apply_uV		= 1,
-		.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	= &igep3_vio_supply,
-};
-
-static struct regulator_consumer_supply igep3_vmmc2_supply =
-	REGULATOR_SUPPLY("vmmc", "omap_hsmmc.1");
-
-static struct regulator_init_data igep3_vmmc2 = {
-	.constraints	= {
-		.valid_modes_mask	= REGULATOR_MODE_NORMAL,
-		.always_on		= 1,
-	},
-	.num_consumer_supplies	= 1,
-	.consumer_supplies	= &igep3_vmmc2_supply,
-};
-
-static struct fixed_voltage_config igep3_vwlan = {
-	.supply_name		= "vwlan",
-	.microvolts		= 3300000,
-	.gpio			= -EINVAL,
-	.enabled_at_boot	= 1,
-	.init_data		= &igep3_vmmc2,
-};
-
-static struct platform_device igep3_vwlan_device = {
-	.name	= "reg-fixed-voltage",
-	.id	= 0,
-	.dev	= {
-		.platform_data = &igep3_vwlan,
-	},
-};
-
-static struct omap2_hsmmc_info mmc[] = {
-	[0] = {
-		.mmc		= 1,
-		.caps		= MMC_CAP_4_BIT_DATA,
-		.gpio_cd	= -EINVAL,
-		.gpio_wp	= -EINVAL,
-	},
-#if defined(CONFIG_LIBERTAS_SDIO) || defined(CONFIG_LIBERTAS_SDIO_MODULE)
-	[1] = {
-		.mmc		= 2,
-		.caps		= MMC_CAP_4_BIT_DATA,
-		.gpio_cd	= -EINVAL,
-		.gpio_wp	= -EINVAL,
-	},
-#endif
-	{}      /* Terminator */
-};
-
-#if defined(CONFIG_LEDS_GPIO) || defined(CONFIG_LEDS_GPIO_MODULE)
-#include <linux/leds.h>
-
-static struct gpio_led igep3_gpio_leds[] = {
-	[0] = {
-		.name			= "gpio-led:red:d0",
-		.gpio			= IGEP3_GPIO_LED0_RED,
-		.default_trigger	= "default-off"
-	},
-	[1] = {
-		.name			= "gpio-led:green:d0",
-		.gpio			= IGEP3_GPIO_LED0_GREEN,
-		.default_trigger	= "default-off",
-	},
-	[2] = {
-		.name			= "gpio-led:red:d1",
-		.gpio			= IGEP3_GPIO_LED1_RED,
-		.default_trigger	= "default-off",
-	},
-	[3] = {
-		.name			= "gpio-led:green:d1",
-		.default_trigger	= "heartbeat",
-		.gpio			= -EINVAL, /* gets replaced */
-	},
-};
-
-static struct gpio_led_platform_data igep3_led_pdata = {
-	.leds           = igep3_gpio_leds,
-	.num_leds       = ARRAY_SIZE(igep3_gpio_leds),
-};
-
-static struct platform_device igep3_led_device = {
-	 .name   = "leds-gpio",
-	 .id     = -1,
-	 .dev    = {
-		 .platform_data = &igep3_led_pdata,
-	},
-};
-
-static void __init igep3_leds_init(void)
-{
-	platform_device_register(&igep3_led_device);
-}
-
-#else
-static inline void igep3_leds_init(void)
-{
-	if ((gpio_request(IGEP3_GPIO_LED0_RED, "gpio-led:red:d0") == 0) &&
-	    (gpio_direction_output(IGEP3_GPIO_LED0_RED, 1) == 0)) {
-		gpio_export(IGEP3_GPIO_LED0_RED, 0);
-		gpio_set_value(IGEP3_GPIO_LED0_RED, 1);
-	} else
-		pr_warning("IGEP3: Could not obtain gpio GPIO_LED0_RED\n");
-
-	if ((gpio_request(IGEP3_GPIO_LED0_GREEN, "gpio-led:green:d0") == 0) &&
-	    (gpio_direction_output(IGEP3_GPIO_LED0_GREEN, 1) == 0)) {
-		gpio_export(IGEP3_GPIO_LED0_GREEN, 0);
-		gpio_set_value(IGEP3_GPIO_LED0_GREEN, 1);
-	} else
-		pr_warning("IGEP3: Could not obtain gpio GPIO_LED0_GREEN\n");
-
-	if ((gpio_request(IGEP3_GPIO_LED1_RED, "gpio-led:red:d1") == 0) &&
-		(gpio_direction_output(IGEP3_GPIO_LED1_RED, 1) == 0)) {
-		gpio_export(IGEP3_GPIO_LED1_RED, 0);
-		gpio_set_value(IGEP3_GPIO_LED1_RED, 1);
-	} else
-		pr_warning("IGEP3: Could not obtain gpio GPIO_LED1_RED\n");
-}
-#endif
-
-static int igep3_twl4030_gpio_setup(struct device *dev,
-		unsigned gpio, unsigned ngpio)
-{
-	/* gpio + 0 is "mmc0_cd" (input/IRQ) */
-	mmc[0].gpio_cd = gpio + 0;
-	omap2_hsmmc_init(mmc);
-
-	/* TWL4030_GPIO_MAX + 1 == ledB (out, active low LED) */
-#if !defined(CONFIG_LEDS_GPIO) && !defined(CONFIG_LEDS_GPIO_MODULE)
-	if ((gpio_request(gpio+TWL4030_GPIO_MAX+1, "gpio-led:green:d1") == 0)
-	    && (gpio_direction_output(gpio + TWL4030_GPIO_MAX + 1, 1) == 0)) {
-		gpio_export(gpio + TWL4030_GPIO_MAX + 1, 0);
-		gpio_set_value(gpio + TWL4030_GPIO_MAX + 1, 0);
-	} else
-		pr_warning("IGEP3: Could not obtain gpio GPIO_LED1_GREEN\n");
-#else
-	igep3_gpio_leds[3].gpio = gpio + TWL4030_GPIO_MAX + 1;
-#endif
-
-	return 0;
-};
-
-static struct twl4030_gpio_platform_data igep3_twl4030_gpio_pdata = {
-	.gpio_base	= OMAP_MAX_GPIO_LINES,
-	.irq_base	= TWL4030_GPIO_IRQ_BASE,
-	.irq_end	= TWL4030_GPIO_IRQ_END,
-	.use_leds	= true,
-	.setup		= igep3_twl4030_gpio_setup,
-};
-
-static struct twl4030_usb_data igep3_twl4030_usb_data = {
-	.usb_mode	= T2_USB_MODE_ULPI,
-};
-
-static struct platform_device *igep3_devices[] __initdata = {
-	&igep3_vwlan_device,
-};
-
-static void __init igep3_init_early(void)
-{
-	omap2_init_common_infrastructure();
-	omap2_init_common_devices(m65kxxxxam_sdrc_params,
-				  m65kxxxxam_sdrc_params);
-}
-
-static struct twl4030_platform_data igep3_twl4030_pdata = {
-	.irq_base	= TWL4030_IRQ_BASE,
-	.irq_end	= TWL4030_IRQ_END,
-
-	/* platform_data for children goes here */
-	.usb		= &igep3_twl4030_usb_data,
-	.gpio		= &igep3_twl4030_gpio_pdata,
-	.vmmc1		= &igep3_vmmc1,
-	.vio		= &igep3_vio,
-};
-
-static struct i2c_board_info __initdata igep3_i2c_boardinfo[] = {
-	{
-		I2C_BOARD_INFO("twl4030", 0x48),
-		.flags		= I2C_CLIENT_WAKE,
-		.irq		= INT_34XX_SYS_NIRQ,
-		.platform_data	= &igep3_twl4030_pdata,
-	},
-};
-
-static int __init igep3_i2c_init(void)
-{
-	omap_register_i2c_bus(1, 2600, igep3_i2c_boardinfo,
-			ARRAY_SIZE(igep3_i2c_boardinfo));
-
-	return 0;
-}
-
-static struct omap_musb_board_data musb_board_data = {
-	.interface_type	= MUSB_INTERFACE_ULPI,
-	.mode		= MUSB_OTG,
-	.power		= 100,
-};
-
-#if defined(CONFIG_LIBERTAS_SDIO) || defined(CONFIG_LIBERTAS_SDIO_MODULE)
-
-static void __init igep3_wifi_bt_init(void)
-{
-	/* Configure MUX values for W-LAN + Bluetooth GPIO's */
-	omap_mux_init_gpio(IGEP3_GPIO_WIFI_NPD, OMAP_PIN_OUTPUT);
-	omap_mux_init_gpio(IGEP3_GPIO_WIFI_NRESET, OMAP_PIN_OUTPUT);
-	omap_mux_init_gpio(IGEP3_GPIO_BT_NRESET, OMAP_PIN_OUTPUT);
-
-	/* Set GPIO's for  W-LAN + Bluetooth combo module */
-	if ((gpio_request(IGEP3_GPIO_WIFI_NPD, "GPIO_WIFI_NPD") == 0) &&
-	    (gpio_direction_output(IGEP3_GPIO_WIFI_NPD, 1) == 0)) {
-		gpio_export(IGEP3_GPIO_WIFI_NPD, 0);
-	} else
-		pr_warning("IGEP3: Could not obtain gpio GPIO_WIFI_NPD\n");
-
-	if ((gpio_request(IGEP3_GPIO_WIFI_NRESET, "GPIO_WIFI_NRESET") == 0) &&
-	    (gpio_direction_output(IGEP3_GPIO_WIFI_NRESET, 1) == 0)) {
-		gpio_export(IGEP3_GPIO_WIFI_NRESET, 0);
-		gpio_set_value(IGEP3_GPIO_WIFI_NRESET, 0);
-		udelay(10);
-		gpio_set_value(IGEP3_GPIO_WIFI_NRESET, 1);
-	} else
-		pr_warning("IGEP3: Could not obtain gpio GPIO_WIFI_NRESET\n");
-
-	if ((gpio_request(IGEP3_GPIO_BT_NRESET, "GPIO_BT_NRESET") == 0) &&
-	    (gpio_direction_output(IGEP3_GPIO_BT_NRESET, 1) == 0)) {
-		gpio_export(IGEP3_GPIO_BT_NRESET, 0);
-	} else
-		pr_warning("IGEP3: Could not obtain gpio GPIO_BT_NRESET\n");
-}
-#else
-void __init igep3_wifi_bt_init(void) {}
-#endif
-
-static const struct usbhs_omap_board_data usbhs_bdata __initconst = {
-	.port_mode[0] = OMAP_USBHS_PORT_MODE_UNUSED,
-	.port_mode[1] = OMAP_EHCI_PORT_MODE_PHY,
-	.port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED,
-
-	.phy_reset = true,
-	.reset_gpio_port[0] = -EINVAL,
-	.reset_gpio_port[1] = IGEP3_GPIO_USBH_NRESET,
-	.reset_gpio_port[2] = -EINVAL,
-};
-
-#ifdef CONFIG_OMAP_MUX
-static struct omap_board_mux board_mux[] __initdata = {
-	OMAP3_MUX(I2C2_SDA, OMAP_MUX_MODE4 | OMAP_PIN_OUTPUT),
-	{ .reg_offset = OMAP_MUX_TERMINATOR },
-};
-#endif
-
-static void __init igep3_init(void)
-{
-	omap3_mux_init(board_mux, OMAP_PACKAGE_CBB);
-
-	/* Register I2C busses and drivers */
-	igep3_i2c_init();
-	platform_add_devices(igep3_devices, ARRAY_SIZE(igep3_devices));
-	omap_serial_init();
-	usb_musb_init(&musb_board_data);
-	usbhs_init(&usbhs_bdata);
-
-	igep3_flash_init();
-	igep3_leds_init();
-
-	/*
-	 * WLAN-BT combo module from MuRata which has a Marvell WLAN
-	 * (88W8686) + CSR Bluetooth chipset. Uses SDIO interface.
-	 */
-	igep3_wifi_bt_init();
-
-}
-
-MACHINE_START(IGEP0030, "IGEP OMAP3 module")
-	.boot_params	= 0x80000100,
-	.reserve	= omap_reserve,
-	.map_io		= omap3_map_io,
-	.init_early	= igep3_init_early,
-	.init_irq	= omap_init_irq,
-	.init_machine	= igep3_init,
-	.timer		= &omap_timer,
-MACHINE_END
diff -druN linux-2.6.39-libre/arch/arm/mach-omap2/board-ldp.c linux-3.0-rc7-libre/arch/arm/mach-omap2/board-ldp.c
--- linux-2.6.39-libre/arch/arm/mach-omap2/board-ldp.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-omap2/board-ldp.c	2011-07-11 19:51:52.000000000 -0400
@@ -22,7 +22,6 @@
 #include <linux/err.h>
 #include <linux/clk.h>
 #include <linux/spi/spi.h>
-#include <linux/spi/ads7846.h>
 #include <linux/regulator/machine.h>
 #include <linux/i2c/twl.h>
 #include <linux/io.h>
@@ -43,47 +42,19 @@
 
 #include <asm/delay.h>
 #include <plat/usb.h>
+#include <plat/gpmc-smsc911x.h>
 
 #include "board-flash.h"
 #include "mux.h"
 #include "hsmmc.h"
 #include "control.h"
+#include "common-board-devices.h"
 
 #define LDP_SMSC911X_CS		1
 #define LDP_SMSC911X_GPIO	152
 #define DEBUG_BASE		0x08000000
 #define LDP_ETHR_START		DEBUG_BASE
 
-static struct resource ldp_smsc911x_resources[] = {
-	[0] = {
-		.start	= LDP_ETHR_START,
-		.end	= LDP_ETHR_START + SZ_4K,
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-		.start	= 0,
-		.end	= 0,
-		.flags	= IORESOURCE_IRQ | IORESOURCE_IRQ_LOWLEVEL,
-	},
-};
-
-static struct smsc911x_platform_config ldp_smsc911x_config = {
-	.irq_polarity	= SMSC911X_IRQ_POLARITY_ACTIVE_LOW,
-	.irq_type	= SMSC911X_IRQ_TYPE_OPEN_DRAIN,
-	.flags		= SMSC911X_USE_32BIT,
-	.phy_interface	= PHY_INTERFACE_MODE_MII,
-};
-
-static struct platform_device ldp_smsc911x_device = {
-	.name		= "smsc911x",
-	.id		= -1,
-	.num_resources	= ARRAY_SIZE(ldp_smsc911x_resources),
-	.resource	= ldp_smsc911x_resources,
-	.dev		= {
-		.platform_data = &ldp_smsc911x_config,
-	},
-};
-
 static uint32_t board_keymap[] = {
 	KEY(0, 0, KEY_1),
 	KEY(1, 0, KEY_2),
@@ -197,82 +168,16 @@
 	},
 };
 
-static int ts_gpio;
-
-/**
- * @brief ads7846_dev_init : Requests & sets GPIO line for pen-irq
- *
- * @return - void. If request gpio fails then Flag KERN_ERR.
- */
-static void ads7846_dev_init(void)
-{
-	if (gpio_request(ts_gpio, "ads7846 irq") < 0) {
-		printk(KERN_ERR "can't get ads746 pen down GPIO\n");
-		return;
-	}
-
-	gpio_direction_input(ts_gpio);
-	gpio_set_debounce(ts_gpio, 310);
-}
-
-static int ads7846_get_pendown_state(void)
-{
-	return !gpio_get_value(ts_gpio);
-}
-
-static struct ads7846_platform_data tsc2046_config __initdata = {
-	.get_pendown_state	= ads7846_get_pendown_state,
-	.keep_vref_on		= 1,
-};
-
-static struct omap2_mcspi_device_config tsc2046_mcspi_config = {
-	.turbo_mode	= 0,
-	.single_channel	= 1,	/* 0: slave, 1: master */
-};
-
-static struct spi_board_info ldp_spi_board_info[] __initdata = {
-	[0] = {
-		/*
-		 * TSC2046 operates at a max freqency of 2MHz, so
-		 * operate slightly below at 1.5MHz
-		 */
-		.modalias		= "ads7846",
-		.bus_num		= 1,
-		.chip_select		= 0,
-		.max_speed_hz		= 1500000,
-		.controller_data	= &tsc2046_mcspi_config,
-		.irq			= 0,
-		.platform_data		= &tsc2046_config,
-	},
+static struct omap_smsc911x_platform_data smsc911x_cfg = {
+	.cs             = LDP_SMSC911X_CS,
+	.gpio_irq       = LDP_SMSC911X_GPIO,
+	.gpio_reset     = -EINVAL,
+	.flags		= SMSC911X_USE_32BIT,
 };
 
 static inline void __init ldp_init_smsc911x(void)
 {
-	int eth_cs;
-	unsigned long cs_mem_base;
-	int eth_gpio = 0;
-
-	eth_cs = LDP_SMSC911X_CS;
-
-	if (gpmc_cs_request(eth_cs, SZ_16M, &cs_mem_base) < 0) {
-		printk(KERN_ERR "Failed to request GPMC mem for smsc911x\n");
-		return;
-	}
-
-	ldp_smsc911x_resources[0].start = cs_mem_base + 0x0;
-	ldp_smsc911x_resources[0].end   = cs_mem_base + 0xff;
-	udelay(100);
-
-	eth_gpio = LDP_SMSC911X_GPIO;
-
-	ldp_smsc911x_resources[1].start = OMAP_GPIO_IRQ(eth_gpio);
-
-	if (gpio_request(eth_gpio, "smsc911x irq") < 0) {
-		printk(KERN_ERR "Failed to request GPIO%d for smsc911x IRQ\n",
-				eth_gpio);
-		return;
-	}
-	gpio_direction_input(eth_gpio);
+	gpmc_smsc911x_init(&smsc911x_cfg);
 }
 
 static struct platform_device ldp_lcd_device = {
@@ -360,19 +265,9 @@
 	.keypad		= &ldp_kp_twl4030_data,
 };
 
-static struct i2c_board_info __initdata ldp_i2c_boardinfo[] = {
-	{
-		I2C_BOARD_INFO("twl4030", 0x48),
-		.flags = I2C_CLIENT_WAKE,
-		.irq = INT_34XX_SYS_NIRQ,
-		.platform_data = &ldp_twldata,
-	},
-};
-
 static int __init omap_i2c_init(void)
 {
-	omap_register_i2c_bus(1, 2600, ldp_i2c_boardinfo,
-			ARRAY_SIZE(ldp_i2c_boardinfo));
+	omap3_pmic_init("twl4030", &ldp_twldata);
 	omap_register_i2c_bus(2, 400, NULL, 0);
 	omap_register_i2c_bus(3, 400, NULL, 0);
 	return 0;
@@ -389,7 +284,6 @@
 };
 
 static struct platform_device *ldp_devices[] __initdata = {
-	&ldp_smsc911x_device,
 	&ldp_lcd_device,
 	&ldp_gpio_keys_device,
 };
@@ -400,12 +294,6 @@
 };
 #endif
 
-static struct omap_musb_board_data musb_board_data = {
-	.interface_type		= MUSB_INTERFACE_ULPI,
-	.mode			= MUSB_OTG,
-	.power			= 100,
-};
-
 static struct mtd_partition ldp_nand_partitions[] = {
 	/* All the partition sizes are listed in terms of NAND block size */
 	{
@@ -446,13 +334,9 @@
 	ldp_init_smsc911x();
 	omap_i2c_init();
 	platform_add_devices(ldp_devices, ARRAY_SIZE(ldp_devices));
-	ts_gpio = 54;
-	ldp_spi_board_info[0].irq = gpio_to_irq(ts_gpio);
-	spi_register_board_info(ldp_spi_board_info,
-				ARRAY_SIZE(ldp_spi_board_info));
-	ads7846_dev_init();
+	omap_ads7846_init(1, 54, 310, NULL);
 	omap_serial_init();
-	usb_musb_init(&musb_board_data);
+	usb_musb_init(NULL);
 	board_nand_init(ldp_nand_partitions,
 		ARRAY_SIZE(ldp_nand_partitions), ZOOM_NAND_CS, 0);
 
diff -druN linux-2.6.39-libre/arch/arm/mach-omap2/board-n8x0.c linux-3.0-rc7-libre/arch/arm/mach-omap2/board-n8x0.c
--- linux-2.6.39-libre/arch/arm/mach-omap2/board-n8x0.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-omap2/board-n8x0.c	2011-07-11 19:51:52.000000000 -0400
@@ -106,14 +106,13 @@
 	static char	announce[] __initdata = KERN_INFO "TUSB 6010\n";
 
 	/* PM companion chip power control pin */
-	ret = gpio_request(TUSB6010_GPIO_ENABLE, "TUSB6010 enable");
+	ret = gpio_request_one(TUSB6010_GPIO_ENABLE, GPIOF_OUT_INIT_LOW,
+			       "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,
@@ -494,8 +493,12 @@
 
 static struct omap_mmc_platform_data *mmc_data[OMAP24XX_NR_MMC];
 
-static void __init n8x0_mmc_init(void)
+static struct gpio n810_emmc_gpios[] __initdata = {
+	{ N810_EMMC_VSD_GPIO, GPIOF_OUT_INIT_LOW,  "MMC slot 2 Vddf" },
+	{ N810_EMMC_VIO_GPIO, GPIOF_OUT_INIT_LOW,  "MMC slot 2 Vdd"  },
+};
 
+static void __init n8x0_mmc_init(void)
 {
 	int err;
 
@@ -512,27 +515,18 @@
 		mmc1_data.slots[1].ban_openended = 1;
 	}
 
-	err = gpio_request(N8X0_SLOT_SWITCH_GPIO, "MMC slot switch");
+	err = gpio_request_one(N8X0_SLOT_SWITCH_GPIO, GPIOF_OUT_INIT_LOW,
+			       "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");
+		err = gpio_request_array(n810_emmc_gpios,
+					 ARRAY_SIZE(n810_emmc_gpios));
 		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;
diff -druN linux-2.6.39-libre/arch/arm/mach-omap2/board-omap3beagle.c linux-3.0-rc7-libre/arch/arm/mach-omap2/board-omap3beagle.c
--- linux-2.6.39-libre/arch/arm/mach-omap2/board-omap3beagle.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-omap2/board-omap3beagle.c	2011-07-11 19:51:52.000000000 -0400
@@ -41,8 +41,8 @@
 
 #include <plat/board.h>
 #include <plat/common.h>
-#include <plat/display.h>
-#include <plat/panel-generic-dpi.h>
+#include <video/omapdss.h>
+#include <video/omap-panel-generic-dpi.h>
 #include <plat/gpmc.h>
 #include <plat/nand.h>
 #include <plat/usb.h>
@@ -52,8 +52,7 @@
 #include "hsmmc.h"
 #include "timer-gp.h"
 #include "pm.h"
-
-#define NAND_BLOCK_SIZE		SZ_128K
+#include "common-board-devices.h"
 
 /*
  * OMAP3 Beagle revision
@@ -79,6 +78,12 @@
 	return omap3_beagle_version;
 }
 
+static struct gpio omap3_beagle_rev_gpios[] __initdata = {
+	{ 171, GPIOF_IN, "rev_id_0"    },
+	{ 172, GPIOF_IN, "rev_id_1" },
+	{ 173, GPIOF_IN, "rev_id_2"    },
+};
+
 static void __init omap3_beagle_init_rev(void)
 {
 	int ret;
@@ -88,25 +93,20 @@
 	omap_mux_init_gpio(172, OMAP_PIN_INPUT_PULLUP);
 	omap_mux_init_gpio(173, OMAP_PIN_INPUT_PULLUP);
 
-	ret = gpio_request(171, "rev_id_0");
-	if (ret < 0)
-		goto fail0;
-
-	ret = gpio_request(172, "rev_id_1");
-	if (ret < 0)
-		goto fail1;
-
-	ret = gpio_request(173, "rev_id_2");
-	if (ret < 0)
-		goto fail2;
-
-	gpio_direction_input(171);
-	gpio_direction_input(172);
-	gpio_direction_input(173);
+	ret = gpio_request_array(omap3_beagle_rev_gpios,
+				 ARRAY_SIZE(omap3_beagle_rev_gpios));
+	if (ret < 0) {
+		printk(KERN_ERR "Unable to get revision detection GPIO pins\n");
+		omap3_beagle_version = OMAP3BEAGLE_BOARD_UNKN;
+		return;
+	}
 
 	beagle_rev = gpio_get_value(171) | (gpio_get_value(172) << 1)
 			| (gpio_get_value(173) << 2);
 
+	gpio_free_array(omap3_beagle_rev_gpios,
+			ARRAY_SIZE(omap3_beagle_rev_gpios));
+
 	switch (beagle_rev) {
 	case 7:
 		printk(KERN_INFO "OMAP3 Beagle Rev: Ax/Bx\n");
@@ -128,18 +128,6 @@
 		printk(KERN_INFO "OMAP3 Beagle Rev: unknown %hd\n", beagle_rev);
 		omap3_beagle_version = OMAP3BEAGLE_BOARD_UNKN;
 	}
-
-	return;
-
-fail2:
-	gpio_free(172);
-fail1:
-	gpio_free(171);
-fail0:
-	printk(KERN_ERR "Unable to get revision detection GPIO pins\n");
-	omap3_beagle_version = OMAP3BEAGLE_BOARD_UNKN;
-
-	return;
 }
 
 static struct mtd_partition omap3beagle_nand_partitions[] = {
@@ -173,15 +161,6 @@
 	},
 };
 
-static struct omap_nand_platform_data omap3beagle_nand_data = {
-	.options	= NAND_BUSWIDTH_16,
-	.parts		= omap3beagle_nand_partitions,
-	.nr_parts	= ARRAY_SIZE(omap3beagle_nand_partitions),
-	.dma_channel	= -1,		/* disable DMA in OMAP NAND driver */
-	.nand_setup	= NULL,
-	.dev_ready	= NULL,
-};
-
 /* DSS */
 
 static int beagle_enable_dvi(struct omap_dss_device *dssdev)
@@ -243,13 +222,10 @@
 {
 	int r;
 
-	r = gpio_request(beagle_dvi_device.reset_gpio, "DVI reset");
-	if (r < 0) {
+	r = gpio_request_one(beagle_dvi_device.reset_gpio, GPIOF_OUT_INIT_LOW,
+			     "DVI reset");
+	if (r < 0)
 		printk(KERN_ERR "Unable to get DVI reset GPIO\n");
-		return;
-	}
-
-	gpio_direction_output(beagle_dvi_device.reset_gpio, 0);
 }
 
 #include "sdram-micron-mt46h32m32lf-6.h"
@@ -276,7 +252,7 @@
 static int beagle_twl_gpio_setup(struct device *dev,
 		unsigned gpio, unsigned ngpio)
 {
-	int r;
+	int r, usb_pwr_level;
 
 	if (omap3_beagle_get_rev() == OMAP3BEAGLE_BOARD_XM) {
 		mmc[0].gpio_wp = -EINVAL;
@@ -295,66 +271,46 @@
 	beagle_vmmc1_supply.dev = mmc[0].dev;
 	beagle_vsim_supply.dev = mmc[0].dev;
 
-	/* REVISIT: need ehci-omap hooks for external VBUS
-	 * power switch and overcurrent detect
-	 */
-	if (omap3_beagle_get_rev() != OMAP3BEAGLE_BOARD_XM) {
-		r = gpio_request(gpio + 1, "EHCI_nOC");
-		if (!r) {
-			r = gpio_direction_input(gpio + 1);
-			if (r)
-				gpio_free(gpio + 1);
-		}
-		if (r)
-			pr_err("%s: unable to configure EHCI_nOC\n", __func__);
-	}
-
 	/*
 	 * TWL4030_GPIO_MAX + 0 == ledA, EHCI nEN_USB_PWR (out, XM active
 	 * high / others active low)
-	 */
-	gpio_request(gpio + TWL4030_GPIO_MAX, "nEN_USB_PWR");
-	if (omap3_beagle_get_rev() == OMAP3BEAGLE_BOARD_XM)
-		gpio_direction_output(gpio + TWL4030_GPIO_MAX, 1);
-	else
-		gpio_direction_output(gpio + TWL4030_GPIO_MAX, 0);
-
-	/* DVI reset GPIO is different between beagle revisions */
-	if (omap3_beagle_get_rev() == OMAP3BEAGLE_BOARD_XM)
-		beagle_dvi_device.reset_gpio = 129;
-	else
-		beagle_dvi_device.reset_gpio = 170;
-
-	/* TWL4030_GPIO_MAX + 1 == ledB, PMU_STAT (out, active low LED) */
-	gpio_leds[2].gpio = gpio + TWL4030_GPIO_MAX + 1;
-
-	/*
-	 * gpio + 1 on Xm controls the TFP410's enable line (active low)
-	 * gpio + 2 control varies depending on the board rev as follows:
-	 * P7/P8 revisions(prototype): Camera EN
-	 * A2+ revisions (production): LDO (supplies DVI, serial, led blocks)
+	 * DVI reset GPIO is different between beagle revisions
 	 */
 	if (omap3_beagle_get_rev() == OMAP3BEAGLE_BOARD_XM) {
-		r = gpio_request(gpio + 1, "nDVI_PWR_EN");
-		if (!r) {
-			r = gpio_direction_output(gpio + 1, 0);
-			if (r)
-				gpio_free(gpio + 1);
-		}
+		usb_pwr_level = GPIOF_OUT_INIT_HIGH;
+		beagle_dvi_device.reset_gpio = 129;
+		/*
+		 * gpio + 1 on Xm controls the TFP410's enable line (active low)
+		 * gpio + 2 control varies depending on the board rev as below:
+		 * P7/P8 revisions(prototype): Camera EN
+		 * A2+ revisions (production): LDO (DVI, serial, led blocks)
+		 */
+		r = gpio_request_one(gpio + 1, GPIOF_OUT_INIT_LOW,
+				     "nDVI_PWR_EN");
 		if (r)
 			pr_err("%s: unable to configure nDVI_PWR_EN\n",
 				__func__);
-		r = gpio_request(gpio + 2, "DVI_LDO_EN");
-		if (!r) {
-			r = gpio_direction_output(gpio + 2, 1);
-			if (r)
-				gpio_free(gpio + 2);
-		}
+		r = gpio_request_one(gpio + 2, GPIOF_OUT_INIT_HIGH,
+				     "DVI_LDO_EN");
 		if (r)
 			pr_err("%s: unable to configure DVI_LDO_EN\n",
 				__func__);
+	} else {
+		usb_pwr_level = GPIOF_OUT_INIT_LOW;
+		beagle_dvi_device.reset_gpio = 170;
+		/*
+		 * REVISIT: need ehci-omap hooks for external VBUS
+		 * power switch and overcurrent detect
+		 */
+		if (gpio_request_one(gpio + 1, GPIOF_IN, "EHCI_nOC"))
+			pr_err("%s: unable to configure EHCI_nOC\n", __func__);
 	}
 
+	gpio_request_one(gpio + TWL4030_GPIO_MAX, usb_pwr_level, "nEN_USB_PWR");
+
+	/* TWL4030_GPIO_MAX + 1 == ledB, PMU_STAT (out, active low LED) */
+	gpio_leds[2].gpio = gpio + TWL4030_GPIO_MAX + 1;
+
 	return 0;
 }
 
@@ -453,15 +409,6 @@
 	.vpll2		= &beagle_vpll2,
 };
 
-static struct i2c_board_info __initdata beagle_i2c_boardinfo[] = {
-	{
-		I2C_BOARD_INFO("twl4030", 0x48),
-		.flags = I2C_CLIENT_WAKE,
-		.irq = INT_34XX_SYS_NIRQ,
-		.platform_data = &beagle_twldata,
-	},
-};
-
 static struct i2c_board_info __initdata beagle_i2c_eeprom[] = {
        {
                I2C_BOARD_INFO("eeprom", 0x50),
@@ -470,8 +417,7 @@
 
 static int __init omap3_beagle_i2c_init(void)
 {
-	omap_register_i2c_bus(1, 2600, beagle_i2c_boardinfo,
-			ARRAY_SIZE(beagle_i2c_boardinfo));
+	omap3_pmic_init("twl4030", &beagle_twldata);
 	/* Bus 3 is attached to the DVI port where devices like the pico DLP
 	 * projector don't work reliably with 400kHz */
 	omap_register_i2c_bus(3, 100, beagle_i2c_eeprom, ARRAY_SIZE(beagle_i2c_eeprom));
@@ -551,39 +497,6 @@
 	&keys_gpio,
 };
 
-static void __init omap3beagle_flash_init(void)
-{
-	u8 cs = 0;
-	u8 nandcs = GPMC_CS_NUM + 1;
-
-	/* 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) {
-		omap3beagle_nand_data.cs = nandcs;
-
-		printk(KERN_INFO "Registering NAND on CS%d\n", nandcs);
-		if (gpmc_nand_init(&omap3beagle_nand_data) < 0)
-			printk(KERN_ERR "Unable to register NAND device\n");
-	}
-}
-
 static const struct usbhs_omap_board_data usbhs_bdata __initconst = {
 
 	.port_mode[0] = OMAP_EHCI_PORT_MODE_PHY,
@@ -602,12 +515,6 @@
 };
 #endif
 
-static struct omap_musb_board_data musb_board_data = {
-	.interface_type		= MUSB_INTERFACE_ULPI,
-	.mode			= MUSB_OTG,
-	.power			= 100,
-};
-
 static void __init beagle_opp_init(void)
 {
 	int r = 0;
@@ -665,13 +572,16 @@
 	omap_serial_init();
 
 	omap_mux_init_gpio(170, OMAP_PIN_INPUT);
-	gpio_request(170, "DVI_nPD");
 	/* REVISIT leave DVI powered down until it's needed ... */
-	gpio_direction_output(170, true);
+	gpio_request_one(170, GPIOF_OUT_INIT_HIGH, "DVI_nPD");
 
-	usb_musb_init(&musb_board_data);
+	usb_musb_init(NULL);
 	usbhs_init(&usbhs_bdata);
-	omap3beagle_flash_init();
+	omap_nand_flash_init(NAND_BUSWIDTH_16, omap3beagle_nand_partitions,
+			     ARRAY_SIZE(omap3beagle_nand_partitions));
+
+	/* Ensure msecure is mux'd to be able to set the RTC. */
+	omap_mux_init_signal("sys_drm_msecure", OMAP_PIN_OFF_OUTPUT_HIGH);
 
 	/* Ensure SDRC pins are mux'd for self-refresh */
 	omap_mux_init_signal("sdrc_cke0", OMAP_PIN_OUTPUT);
diff -druN linux-2.6.39-libre/arch/arm/mach-omap2/board-omap3evm.c linux-3.0-rc7-libre/arch/arm/mach-omap2/board-omap3evm.c
--- linux-2.6.39-libre/arch/arm/mach-omap2/board-omap3evm.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-omap2/board-omap3evm.c	2011-07-11 19:51:52.000000000 -0400
@@ -44,12 +44,13 @@
 #include <plat/usb.h>
 #include <plat/common.h>
 #include <plat/mcspi.h>
-#include <plat/display.h>
-#include <plat/panel-generic-dpi.h>
+#include <video/omapdss.h>
+#include <video/omap-panel-generic-dpi.h>
 
 #include "mux.h"
 #include "sdram-micron-mt46h32m32lf-6.h"
 #include "hsmmc.h"
+#include "common-board-devices.h"
 
 #define OMAP3_EVM_TS_GPIO	175
 #define OMAP3_EVM_EHCI_VBUS	22
@@ -101,49 +102,20 @@
 }
 
 #if defined(CONFIG_SMSC911X) || defined(CONFIG_SMSC911X_MODULE)
-static struct resource omap3evm_smsc911x_resources[] = {
-	[0] =	{
-		.start	= OMAP3EVM_ETHR_START,
-		.end	= (OMAP3EVM_ETHR_START + OMAP3EVM_ETHR_SIZE - 1),
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] =	{
-		.start	= OMAP_GPIO_IRQ(OMAP3EVM_ETHR_GPIO_IRQ),
-		.end	= OMAP_GPIO_IRQ(OMAP3EVM_ETHR_GPIO_IRQ),
-		.flags	= (IORESOURCE_IRQ | IRQF_TRIGGER_LOW),
-	},
-};
-
-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),
-};
+#include <plat/gpmc-smsc911x.h>
 
-static struct platform_device omap3evm_smsc911x_device = {
-	.name		= "smsc911x",
-	.id		= -1,
-	.num_resources	= ARRAY_SIZE(omap3evm_smsc911x_resources),
-	.resource	= &omap3evm_smsc911x_resources[0],
-	.dev		= {
-		.platform_data = &smsc911x_config,
-	},
+static struct omap_smsc911x_platform_data smsc911x_cfg = {
+	.cs             = OMAP3EVM_SMSC911X_CS,
+	.gpio_irq       = OMAP3EVM_ETHR_GPIO_IRQ,
+	.gpio_reset     = -EINVAL,
+	.flags		= SMSC911X_USE_32BIT | SMSC911X_SAVE_MAC_ADDRESS,
 };
 
 static inline void __init omap3evm_init_smsc911x(void)
 {
-	int eth_cs, eth_rst;
 	struct clk *l3ck;
 	unsigned int rate;
 
-	if (get_omap3_evm_rev() == OMAP3EVM_BOARD_GEN_1)
-		eth_rst = OMAP3EVM_GEN1_ETHR_GPIO_RST;
-	else
-		eth_rst = OMAP3EVM_GEN2_ETHR_GPIO_RST;
-
-	eth_cs = OMAP3EVM_SMSC911X_CS;
-
 	l3ck = clk_get(NULL, "l3_ck");
 	if (IS_ERR(l3ck))
 		rate = 100000000;
@@ -152,33 +124,13 @@
 
 	/* Configure ethernet controller reset gpio */
 	if (cpu_is_omap3430()) {
-		if (gpio_request(eth_rst, "SMSC911x gpio") < 0) {
-			pr_err(KERN_ERR "Failed to request %d for smsc911x\n",
-					eth_rst);
-			return;
-		}
-
-		if (gpio_direction_output(eth_rst, 1) < 0) {
-			pr_err(KERN_ERR "Failed to set direction of %d for" \
-					" smsc911x\n", eth_rst);
-			return;
-		}
-		/* reset pulse to ethernet controller*/
-		usleep_range(150, 220);
-		gpio_set_value(eth_rst, 0);
-		usleep_range(150, 220);
-		gpio_set_value(eth_rst, 1);
-		usleep_range(1, 2);
-	}
-
-	if (gpio_request(OMAP3EVM_ETHR_GPIO_IRQ, "SMSC911x irq") < 0) {
-		printk(KERN_ERR "Failed to request GPIO%d for smsc911x IRQ\n",
-			OMAP3EVM_ETHR_GPIO_IRQ);
-		return;
+		if (get_omap3_evm_rev() == OMAP3EVM_BOARD_GEN_1)
+			smsc911x_cfg.gpio_reset = OMAP3EVM_GEN1_ETHR_GPIO_RST;
+		else
+			smsc911x_cfg.gpio_reset = OMAP3EVM_GEN2_ETHR_GPIO_RST;
 	}
 
-	gpio_direction_input(OMAP3EVM_ETHR_GPIO_IRQ);
-	platform_device_register(&omap3evm_smsc911x_device);
+	gpmc_smsc911x_init(&smsc911x_cfg);
 }
 
 #else
@@ -197,6 +149,15 @@
 #define OMAP3EVM_LCD_PANEL_BKLIGHT_GPIO	210
 #define OMAP3EVM_DVI_PANEL_EN_GPIO	199
 
+static struct gpio omap3_evm_dss_gpios[] __initdata = {
+	{ OMAP3EVM_LCD_PANEL_RESB,  GPIOF_OUT_INIT_HIGH, "lcd_panel_resb"  },
+	{ OMAP3EVM_LCD_PANEL_INI,   GPIOF_OUT_INIT_HIGH, "lcd_panel_ini"   },
+	{ OMAP3EVM_LCD_PANEL_QVGA,  GPIOF_OUT_INIT_LOW,  "lcd_panel_qvga"  },
+	{ OMAP3EVM_LCD_PANEL_LR,    GPIOF_OUT_INIT_HIGH, "lcd_panel_lr"    },
+	{ OMAP3EVM_LCD_PANEL_UD,    GPIOF_OUT_INIT_HIGH, "lcd_panel_ud"    },
+	{ OMAP3EVM_LCD_PANEL_ENVDD, GPIOF_OUT_INIT_LOW,  "lcd_panel_envdd" },
+};
+
 static int lcd_enabled;
 static int dvi_enabled;
 
@@ -204,61 +165,10 @@
 {
 	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);
-
+	r = gpio_request_array(omap3_evm_dss_gpios,
+			       ARRAY_SIZE(omap3_evm_dss_gpios));
+	if (r)
+		printk(KERN_ERR "failed to get lcd_panel_* gpios\n");
 }
 
 static int omap3_evm_enable_lcd(struct omap_dss_device *dssdev)
@@ -448,7 +358,7 @@
 static int omap3evm_twl_gpio_setup(struct device *dev,
 		unsigned gpio, unsigned ngpio)
 {
-	int r;
+	int r, lcd_bl_en;
 
 	/* gpio + 0 is "mmc0_cd" (input/IRQ) */
 	omap_mux_init_gpio(63, OMAP_PIN_INPUT);
@@ -465,16 +375,14 @@
 	 */
 
 	/* TWL4030_GPIO_MAX + 0 == ledA, LCD Backlight control */
-	r = gpio_request(gpio + TWL4030_GPIO_MAX, "EN_LCD_BKL");
-	if (!r)
-		r = gpio_direction_output(gpio + TWL4030_GPIO_MAX,
-			(get_omap3_evm_rev() >= OMAP3EVM_BOARD_GEN_2) ? 1 : 0);
+	lcd_bl_en = get_omap3_evm_rev() >= OMAP3EVM_BOARD_GEN_2 ?
+		GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW;
+	r = gpio_request_one(gpio + TWL4030_GPIO_MAX, lcd_bl_en, "EN_LCD_BKL");
 	if (r)
 		printk(KERN_ERR "failed to get/set lcd_bkl gpio\n");
 
 	/* gpio + 7 == DVI Enable */
-	gpio_request(gpio + 7, "EN_DVI");
-	gpio_direction_output(gpio + 7, 0);
+	gpio_request_one(gpio + 7, GPIOF_OUT_INIT_LOW, "EN_DVI");
 
 	/* TWL4030_GPIO_MAX + 1 == ledB (out, active low LED) */
 	gpio_leds[2].gpio = gpio + TWL4030_GPIO_MAX + 1;
@@ -652,78 +560,18 @@
 	.vdac		= &omap3_evm_vdac,
 	.vpll2		= &omap3_evm_vpll2,
 	.vio		= &omap3evm_vio,
-};
-
-static struct i2c_board_info __initdata omap3evm_i2c_boardinfo[] = {
-	{
-		I2C_BOARD_INFO("twl4030", 0x48),
-		.flags = I2C_CLIENT_WAKE,
-		.irq = INT_34XX_SYS_NIRQ,
-		.platform_data = &omap3evm_twldata,
-	},
+	.vmmc1		= &omap3evm_vmmc1,
+	.vsim		= &omap3evm_vsim,
 };
 
 static int __init omap3_evm_i2c_init(void)
 {
-	/*
-	 * REVISIT: These entries can be set in omap3evm_twl_data
-	 * after a merge with MFD tree
-	 */
-	omap3evm_twldata.vmmc1 = &omap3evm_vmmc1;
-	omap3evm_twldata.vsim = &omap3evm_vsim;
-
-	omap_register_i2c_bus(1, 2600, omap3evm_i2c_boardinfo,
-			ARRAY_SIZE(omap3evm_i2c_boardinfo));
+	omap3_pmic_init("twl4030", &omap3evm_twldata);
 	omap_register_i2c_bus(2, 400, NULL, 0);
 	omap_register_i2c_bus(3, 400, NULL, 0);
 	return 0;
 }
 
-static void ads7846_dev_init(void)
-{
-	if (gpio_request(OMAP3_EVM_TS_GPIO, "ADS7846 pendown") < 0)
-		printk(KERN_ERR "can't get ads7846 pen down GPIO\n");
-
-	gpio_direction_input(OMAP3_EVM_TS_GPIO);
-	gpio_set_debounce(OMAP3_EVM_TS_GPIO, 310);
-}
-
-static int ads7846_get_pendown_state(void)
-{
-	return !gpio_get_value(OMAP3_EVM_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		= 3,
-	.debounce_rep		= 1,
-	.get_pendown_state	= ads7846_get_pendown_state,
-	.keep_vref_on		= 1,
-	.settle_delay_usecs	= 150,
-	.wakeup				= true,
-};
-
-static struct omap2_mcspi_device_config ads7846_mcspi_config = {
-	.turbo_mode	= 0,
-	.single_channel	= 1,	/* 0: slave, 1: master */
-};
-
-static struct spi_board_info omap3evm_spi_board_info[] = {
-	[0] = {
-		.modalias		= "ads7846",
-		.bus_num		= 1,
-		.chip_select		= 0,
-		.max_speed_hz		= 1500000,
-		.controller_data	= &ads7846_mcspi_config,
-		.irq			= OMAP_GPIO_IRQ(OMAP3_EVM_TS_GPIO),
-		.platform_data		= &ads7846_config,
-	},
-};
-
 static struct omap_board_config_kernel omap3_evm_config[] __initdata = {
 };
 
@@ -825,6 +673,11 @@
 	.power			= 100,
 };
 
+static struct gpio omap3_evm_ehci_gpios[] __initdata = {
+	{ OMAP3_EVM_EHCI_VBUS,	 GPIOF_OUT_INIT_HIGH,  "enable EHCI VBUS" },
+	{ OMAP3_EVM_EHCI_SELECT, GPIOF_OUT_INIT_LOW,   "select EHCI port" },
+};
+
 static void __init omap3_evm_init(void)
 {
 	omap3_evm_get_revision();
@@ -841,9 +694,6 @@
 
 	omap_display_init(&omap3_evm_dss_data);
 
-	spi_register_board_info(omap3evm_spi_board_info,
-				ARRAY_SIZE(omap3evm_spi_board_info));
-
 	omap_serial_init();
 
 	/* OMAP3EVM uses ISP1504 phy and so register nop transceiver */
@@ -851,16 +701,12 @@
 
 	if (get_omap3_evm_rev() >= OMAP3EVM_BOARD_GEN_2) {
 		/* enable EHCI VBUS using GPIO22 */
-		omap_mux_init_gpio(22, OMAP_PIN_INPUT_PULLUP);
-		gpio_request(OMAP3_EVM_EHCI_VBUS, "enable EHCI VBUS");
-		gpio_direction_output(OMAP3_EVM_EHCI_VBUS, 0);
-		gpio_set_value(OMAP3_EVM_EHCI_VBUS, 1);
-
+		omap_mux_init_gpio(OMAP3_EVM_EHCI_VBUS, OMAP_PIN_INPUT_PULLUP);
 		/* Select EHCI port on main board */
-		omap_mux_init_gpio(61, OMAP_PIN_INPUT_PULLUP);
-		gpio_request(OMAP3_EVM_EHCI_SELECT, "select EHCI port");
-		gpio_direction_output(OMAP3_EVM_EHCI_SELECT, 0);
-		gpio_set_value(OMAP3_EVM_EHCI_SELECT, 0);
+		omap_mux_init_gpio(OMAP3_EVM_EHCI_SELECT,
+				   OMAP_PIN_INPUT_PULLUP);
+		gpio_request_array(omap3_evm_ehci_gpios,
+				   ARRAY_SIZE(omap3_evm_ehci_gpios));
 
 		/* setup EHCI phy reset config */
 		omap_mux_init_gpio(21, OMAP_PIN_INPUT_PULLUP);
@@ -876,7 +722,7 @@
 	}
 	usb_musb_init(&musb_board_data);
 	usbhs_init(&usbhs_bdata);
-	ads7846_dev_init();
+	omap_ads7846_init(1, OMAP3_EVM_TS_GPIO, 310, NULL);
 	omap3evm_init_smsc911x();
 	omap3_evm_display_init();
 
diff -druN linux-2.6.39-libre/arch/arm/mach-omap2/board-omap3logic.c linux-3.0-rc7-libre/arch/arm/mach-omap2/board-omap3logic.c
--- linux-2.6.39-libre/arch/arm/mach-omap2/board-omap3logic.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-omap2/board-omap3logic.c	2011-07-11 19:51:52.000000000 -0400
@@ -37,6 +37,7 @@
 #include "hsmmc.h"
 #include "timer-gp.h"
 #include "control.h"
+#include "common-board-devices.h"
 
 #include <plat/mux.h>
 #include <plat/board.h>
@@ -93,19 +94,9 @@
 	.vmmc1		= &omap3logic_vmmc1,
 };
 
-static struct i2c_board_info __initdata omap3logic_i2c_boardinfo[] = {
-	{
-		I2C_BOARD_INFO("twl4030", 0x48),
-		.flags = I2C_CLIENT_WAKE,
-		.irq = INT_34XX_SYS_NIRQ,
-		.platform_data = &omap3logic_twldata,
-	},
-};
-
 static int __init omap3logic_i2c_init(void)
 {
-	omap_register_i2c_bus(1, 2600, omap3logic_i2c_boardinfo,
-				ARRAY_SIZE(omap3logic_i2c_boardinfo));
+	omap3_pmic_init("twl4030", &omap3logic_twldata);
 	return 0;
 }
 
@@ -147,7 +138,6 @@
 	.cs             = OMAP3LOGIC_SMSC911X_CS,
 	.gpio_irq       = -EINVAL,
 	.gpio_reset     = -EINVAL,
-	.flags          = IORESOURCE_IRQ_LOWLEVEL,
 };
 
 /* TODO/FIXME (comment by Peter Barada, LogicPD):
diff -druN linux-2.6.39-libre/arch/arm/mach-omap2/board-omap3pandora.c linux-3.0-rc7-libre/arch/arm/mach-omap2/board-omap3pandora.c
--- linux-2.6.39-libre/arch/arm/mach-omap2/board-omap3pandora.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-omap2/board-omap3pandora.c	2011-07-11 19:51:52.000000000 -0400
@@ -22,7 +22,6 @@
 #include <linux/platform_device.h>
 
 #include <linux/spi/spi.h>
-#include <linux/spi/ads7846.h>
 #include <linux/regulator/machine.h>
 #include <linux/i2c/twl.h>
 #include <linux/wl12xx.h>
@@ -31,6 +30,7 @@
 #include <linux/leds.h>
 #include <linux/input.h>
 #include <linux/input/matrix_keypad.h>
+#include <linux/gpio.h>
 #include <linux/gpio_keys.h>
 #include <linux/mmc/host.h>
 #include <linux/mmc/card.h>
@@ -42,23 +42,21 @@
 
 #include <plat/board.h>
 #include <plat/common.h>
-#include <mach/gpio.h>
 #include <mach/hardware.h>
 #include <plat/mcspi.h>
 #include <plat/usb.h>
-#include <plat/display.h>
+#include <video/omapdss.h>
 #include <plat/nand.h>
 
 #include "mux.h"
 #include "sdram-micron-mt46h32m32lf-6.h"
 #include "hsmmc.h"
+#include "common-board-devices.h"
 
 #define PANDORA_WIFI_IRQ_GPIO		21
 #define PANDORA_WIFI_NRESET_GPIO	23
 #define OMAP3_PANDORA_TS_GPIO		94
 
-#define NAND_BLOCK_SIZE			SZ_128K
-
 static struct mtd_partition omap3pandora_nand_partitions[] = {
 	{
 		.name           = "xloader",
@@ -86,7 +84,8 @@
 
 static struct omap_nand_platform_data pandora_nand_data = {
 	.cs		= 0,
-	.devsize	= 1,	/* '0' for 8-bit, '1' for 16-bit device */
+	.devsize	= NAND_BUSWIDTH_16,
+	.xfer_type	= NAND_OMAP_PREFETCH_DMA,
 	.parts		= omap3pandora_nand_partitions,
 	.nr_parts	= ARRAY_SIZE(omap3pandora_nand_partitions),
 };
@@ -305,24 +304,13 @@
 
 	/* gpio + 13 drives 32kHz buffer for wifi module */
 	gpio_32khz = gpio + 13;
-	ret = gpio_request(gpio_32khz, "wifi 32kHz");
+	ret = gpio_request_one(gpio_32khz, GPIOF_OUT_INIT_HIGH, "wifi 32kHz");
 	if (ret < 0) {
 		pr_err("Cannot get GPIO line %d, ret=%d\n", gpio_32khz, ret);
-		goto fail;
-	}
-
-	ret = gpio_direction_output(gpio_32khz, 1);
-	if (ret < 0) {
-		pr_err("Cannot set GPIO line %d, ret=%d\n", gpio_32khz, ret);
-		goto fail_direction;
+		return -ENODEV;
 	}
 
 	return 0;
-
-fail_direction:
-	gpio_free(gpio_32khz);
-fail:
-	return -ENODEV;
 }
 
 static struct twl4030_gpio_platform_data omap3pandora_gpio_data = {
@@ -544,15 +532,6 @@
 	.bci		= &pandora_bci_data,
 };
 
-static struct i2c_board_info __initdata omap3pandora_i2c_boardinfo[] = {
-	{
-		I2C_BOARD_INFO("tps65950", 0x48),
-		.flags = I2C_CLIENT_WAKE,
-		.irq = INT_34XX_SYS_NIRQ,
-		.platform_data = &omap3pandora_twldata,
-	},
-};
-
 static struct i2c_board_info __initdata omap3pandora_i2c3_boardinfo[] = {
 	{
 		I2C_BOARD_INFO("bq27500", 0x55),
@@ -562,61 +541,15 @@
 
 static int __init omap3pandora_i2c_init(void)
 {
-	omap_register_i2c_bus(1, 2600, omap3pandora_i2c_boardinfo,
-			ARRAY_SIZE(omap3pandora_i2c_boardinfo));
+	omap3_pmic_init("tps65950", &omap3pandora_twldata);
 	/* i2c2 pins are not connected */
 	omap_register_i2c_bus(3, 100, omap3pandora_i2c3_boardinfo,
 			ARRAY_SIZE(omap3pandora_i2c3_boardinfo));
 	return 0;
 }
 
-static void __init omap3pandora_ads7846_init(void)
-{
-	int gpio = OMAP3_PANDORA_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_PANDORA_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		= 3,
-	.debounce_rep		= 1,
-	.get_pendown_state	= ads7846_get_pendown_state,
-	.keep_vref_on		= 1,
-};
-
-static struct omap2_mcspi_device_config ads7846_mcspi_config = {
-	.turbo_mode	= 0,
-	.single_channel	= 1,	/* 0: slave, 1: master */
-};
-
 static struct spi_board_info omap3pandora_spi_board_info[] __initdata = {
 	{
-		.modalias		= "ads7846",
-		.bus_num		= 1,
-		.chip_select		= 0,
-		.max_speed_hz		= 1500000,
-		.controller_data	= &ads7846_mcspi_config,
-		.irq			= OMAP_GPIO_IRQ(OMAP3_PANDORA_TS_GPIO),
-		.platform_data		= &ads7846_config,
-	}, {
 		.modalias		= "tpo_td043mtea1_panel_spi",
 		.bus_num		= 1,
 		.chip_select		= 1,
@@ -639,14 +572,10 @@
 
 	memset(&pandora_wl1251_pdata, 0, sizeof(pandora_wl1251_pdata));
 
-	ret = gpio_request(PANDORA_WIFI_IRQ_GPIO, "wl1251 irq");
+	ret = gpio_request_one(PANDORA_WIFI_IRQ_GPIO, GPIOF_IN, "wl1251 irq");
 	if (ret < 0)
 		goto fail;
 
-	ret = gpio_direction_input(PANDORA_WIFI_IRQ_GPIO);
-	if (ret < 0)
-		goto fail_irq;
-
 	pandora_wl1251_pdata.irq = gpio_to_irq(PANDORA_WIFI_IRQ_GPIO);
 	if (pandora_wl1251_pdata.irq < 0)
 		goto fail_irq;
@@ -688,12 +617,6 @@
 };
 #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);
@@ -705,9 +628,9 @@
 	omap_serial_init();
 	spi_register_board_info(omap3pandora_spi_board_info,
 			ARRAY_SIZE(omap3pandora_spi_board_info));
-	omap3pandora_ads7846_init();
+	omap_ads7846_init(1, OMAP3_PANDORA_TS_GPIO, 0, NULL);
 	usbhs_init(&usbhs_bdata);
-	usb_musb_init(&musb_board_data);
+	usb_musb_init(NULL);
 	gpmc_nand_init(&pandora_nand_data);
 
 	/* Ensure SDRC pins are mux'd for self-refresh */
diff -druN linux-2.6.39-libre/arch/arm/mach-omap2/board-omap3stalker.c linux-3.0-rc7-libre/arch/arm/mach-omap2/board-omap3stalker.c
--- linux-2.6.39-libre/arch/arm/mach-omap2/board-omap3stalker.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-omap2/board-omap3stalker.c	2011-07-11 19:51:52.000000000 -0400
@@ -39,13 +39,12 @@
 #include <plat/gpmc.h>
 #include <plat/nand.h>
 #include <plat/usb.h>
-#include <plat/display.h>
-#include <plat/panel-generic-dpi.h>
+#include <video/omapdss.h>
+#include <video/omap-panel-generic-dpi.h>
 
 #include <plat/mcspi.h>
 #include <linux/input/matrix_keypad.h>
 #include <linux/spi/spi.h>
-#include <linux/spi/ads7846.h>
 #include <linux/interrupt.h>
 #include <linux/smsc911x.h>
 #include <linux/i2c/at24.h>
@@ -54,52 +53,28 @@
 #include "mux.h"
 #include "hsmmc.h"
 #include "timer-gp.h"
+#include "common-board-devices.h"
 
 #if defined(CONFIG_SMSC911X) || defined(CONFIG_SMSC911X_MODULE)
+#include <plat/gpmc-smsc911x.h>
+
 #define OMAP3STALKER_ETHR_START	0x2c000000
 #define OMAP3STALKER_ETHR_SIZE	1024
 #define OMAP3STALKER_ETHR_GPIO_IRQ	19
 #define OMAP3STALKER_SMC911X_CS	5
 
-static struct resource omap3stalker_smsc911x_resources[] = {
-	[0] = {
-	       .start	= OMAP3STALKER_ETHR_START,
-	       .end	=
-	       (OMAP3STALKER_ETHR_START + OMAP3STALKER_ETHR_SIZE - 1),
-	       .flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-	       .start	= OMAP_GPIO_IRQ(OMAP3STALKER_ETHR_GPIO_IRQ),
-	       .end	= OMAP_GPIO_IRQ(OMAP3STALKER_ETHR_GPIO_IRQ),
-	       .flags	= (IORESOURCE_IRQ | IRQF_TRIGGER_LOW),
-	},
-};
-
-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,
+static struct omap_smsc911x_platform_data smsc911x_cfg = {
+	.cs             = OMAP3STALKER_SMC911X_CS,
+	.gpio_irq       = OMAP3STALKER_ETHR_GPIO_IRQ,
+	.gpio_reset     = -EINVAL,
 	.flags		= (SMSC911X_USE_32BIT | SMSC911X_SAVE_MAC_ADDRESS),
 };
 
-static struct platform_device omap3stalker_smsc911x_device = {
-	.name		= "smsc911x",
-	.id		= -1,
-	.num_resources	= ARRAY_SIZE(omap3stalker_smsc911x_resources),
-	.resource	= &omap3stalker_smsc911x_resources[0],
-	.dev		= {
-		.platform_data	= &smsc911x_config,
-	},
-};
-
 static inline void __init omap3stalker_init_eth(void)
 {
-	int eth_cs;
 	struct clk *l3ck;
 	unsigned int rate;
 
-	eth_cs = OMAP3STALKER_SMC911X_CS;
-
 	l3ck = clk_get(NULL, "l3_ck");
 	if (IS_ERR(l3ck))
 		rate = 100000000;
@@ -107,16 +82,7 @@
 		rate = clk_get_rate(l3ck);
 
 	omap_mux_init_gpio(19, OMAP_PIN_INPUT_PULLUP);
-	if (gpio_request(OMAP3STALKER_ETHR_GPIO_IRQ, "SMC911x irq") < 0) {
-		printk(KERN_ERR
-		       "Failed to request GPIO%d for smc911x IRQ\n",
-		       OMAP3STALKER_ETHR_GPIO_IRQ);
-		return;
-	}
-
-	gpio_direction_input(OMAP3STALKER_ETHR_GPIO_IRQ);
-
-	platform_device_register(&omap3stalker_smsc911x_device);
+	gpmc_smsc911x_init(&smsc911x_cfg);
 }
 
 #else
@@ -365,12 +331,11 @@
 	 */
 
 	/* 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_request_one(gpio + TWL4030_GPIO_MAX, GPIOF_OUT_INIT_LOW,
+			 "EN_LCD_BKL");
 
 	/* gpio + 7 == DVI Enable */
-	gpio_request(gpio + 7, "EN_DVI");
-	gpio_direction_output(gpio + 7, 0);
+	gpio_request_one(gpio + 7, GPIOF_OUT_INIT_LOW, "EN_DVI");
 
 	/* TWL4030_GPIO_MAX + 1 == ledB (out, mmc0) */
 	gpio_leds[2].gpio = gpio + TWL4030_GPIO_MAX + 1;
@@ -489,15 +454,8 @@
 	.codec		= &omap3stalker_codec_data,
 	.vdac		= &omap3_stalker_vdac,
 	.vpll2		= &omap3_stalker_vpll2,
-};
-
-static struct i2c_board_info __initdata omap3stalker_i2c_boardinfo[] = {
-	{
-	 I2C_BOARD_INFO("twl4030", 0x48),
-	 .flags		= I2C_CLIENT_WAKE,
-	 .irq		= INT_34XX_SYS_NIRQ,
-	 .platform_data	= &omap3stalker_twldata,
-	 },
+	.vmmc1		= &omap3stalker_vmmc1,
+	.vsim		= &omap3stalker_vsim,
 };
 
 static struct at24_platform_data fram_info = {
@@ -516,15 +474,7 @@
 
 static int __init omap3_stalker_i2c_init(void)
 {
-	/*
-	 * REVISIT: These entries can be set in omap3evm_twl_data
-	 * after a merge with MFD tree
-	 */
-	omap3stalker_twldata.vmmc1 = &omap3stalker_vmmc1;
-	omap3stalker_twldata.vsim = &omap3stalker_vsim;
-
-	omap_register_i2c_bus(1, 2600, omap3stalker_i2c_boardinfo,
-			      ARRAY_SIZE(omap3stalker_i2c_boardinfo));
+	omap3_pmic_init("twl4030", &omap3stalker_twldata);
 	omap_register_i2c_bus(2, 400, NULL, 0);
 	omap_register_i2c_bus(3, 400, omap3stalker_i2c_boardinfo3,
 			      ARRAY_SIZE(omap3stalker_i2c_boardinfo3));
@@ -532,49 +482,6 @@
 }
 
 #define OMAP3_STALKER_TS_GPIO	175
-static void ads7846_dev_init(void)
-{
-	if (gpio_request(OMAP3_STALKER_TS_GPIO, "ADS7846 pendown") < 0)
-		printk(KERN_ERR "can't get ads7846 pen down GPIO\n");
-
-	gpio_direction_input(OMAP3_STALKER_TS_GPIO);
-	gpio_set_debounce(OMAP3_STALKER_TS_GPIO, 310);
-}
-
-static int ads7846_get_pendown_state(void)
-{
-	return !gpio_get_value(OMAP3_STALKER_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		= 3,
-	.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 omap3stalker_spi_board_info[] = {
-	[0] = {
-	       .modalias	= "ads7846",
-	       .bus_num		= 1,
-	       .chip_select	= 0,
-	       .max_speed_hz	= 1500000,
-	       .controller_data	= &ads7846_mcspi_config,
-	       .irq		= OMAP_GPIO_IRQ(OMAP3_STALKER_TS_GPIO),
-	       .platform_data	= &ads7846_config,
-	},
-};
 
 static struct omap_board_config_kernel omap3_stalker_config[] __initdata = {
 };
@@ -618,12 +525,6 @@
 };
 #endif
 
-static struct omap_musb_board_data musb_board_data = {
-	.interface_type	= MUSB_INTERFACE_ULPI,
-	.mode		= MUSB_OTG,
-	.power		= 100,
-};
-
 static void __init omap3_stalker_init(void)
 {
 	omap3_mux_init(board_mux, OMAP_PACKAGE_CUS);
@@ -636,13 +537,11 @@
 			     ARRAY_SIZE(omap3_stalker_devices));
 
 	omap_display_init(&omap3_stalker_dss_data);
-	spi_register_board_info(omap3stalker_spi_board_info,
-				ARRAY_SIZE(omap3stalker_spi_board_info));
 
 	omap_serial_init();
-	usb_musb_init(&musb_board_data);
+	usb_musb_init(NULL);
 	usbhs_init(&usbhs_bdata);
-	ads7846_dev_init();
+	omap_ads7846_init(1, OMAP3_STALKER_TS_GPIO, 310, NULL);
 
 	omap_mux_init_gpio(21, OMAP_PIN_OUTPUT);
 	omap_mux_init_gpio(18, OMAP_PIN_INPUT_PULLUP);
diff -druN linux-2.6.39-libre/arch/arm/mach-omap2/board-omap3touchbook.c linux-3.0-rc7-libre/arch/arm/mach-omap2/board-omap3touchbook.c
--- linux-2.6.39-libre/arch/arm/mach-omap2/board-omap3touchbook.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-omap2/board-omap3touchbook.c	2011-07-11 19:51:52.000000000 -0400
@@ -52,11 +52,10 @@
 #include "mux.h"
 #include "hsmmc.h"
 #include "timer-gp.h"
+#include "common-board-devices.h"
 
 #include <asm/setup.h>
 
-#define NAND_BLOCK_SIZE		SZ_128K
-
 #define OMAP3_AC_GPIO		136
 #define OMAP3_TS_GPIO		162
 #define TB_BL_PWM_TIMER		9
@@ -95,15 +94,6 @@
 	},
 };
 
-static struct omap_nand_platform_data omap3touchbook_nand_data = {
-	.options	= NAND_BUSWIDTH_16,
-	.parts		= omap3touchbook_nand_partitions,
-	.nr_parts	= ARRAY_SIZE(omap3touchbook_nand_partitions),
-	.dma_channel	= -1,		/* disable DMA in OMAP NAND driver */
-	.nand_setup	= NULL,
-	.dev_ready	= NULL,
-};
-
 #include "sdram-micron-mt46h32m32lf-6.h"
 
 static struct omap2_hsmmc_info mmc[] = {
@@ -154,13 +144,11 @@
 	/* REVISIT: need ehci-omap hooks for external VBUS
 	 * power switch and overcurrent detect
 	 */
-
-	gpio_request(gpio + 1, "EHCI_nOC");
-	gpio_direction_input(gpio + 1);
+	gpio_request_one(gpio + 1, GPIOF_IN, "EHCI_nOC");
 
 	/* TWL4030_GPIO_MAX + 0 == ledA, EHCI nEN_USB_PWR (out, active low) */
-	gpio_request(gpio + TWL4030_GPIO_MAX, "nEN_USB_PWR");
-	gpio_direction_output(gpio + TWL4030_GPIO_MAX, 0);
+	gpio_request_one(gpio + TWL4030_GPIO_MAX, GPIOF_OUT_INIT_LOW,
+			 "nEN_USB_PWR");
 
 	/* TWL4030_GPIO_MAX + 1 == ledB, PMU_STAT (out, active low LED) */
 	gpio_leds[2].gpio = gpio + TWL4030_GPIO_MAX + 1;
@@ -273,15 +261,6 @@
 	.vpll2		= &touchbook_vpll2,
 };
 
-static struct i2c_board_info __initdata touchbook_i2c_boardinfo[] = {
-	{
-		I2C_BOARD_INFO("twl4030", 0x48),
-		.flags = I2C_CLIENT_WAKE,
-		.irq = INT_34XX_SYS_NIRQ,
-		.platform_data = &touchbook_twldata,
-	},
-};
-
 static struct i2c_board_info __initdata touchBook_i2c_boardinfo[] = {
 	{
 		I2C_BOARD_INFO("bq27200", 0x55),
@@ -291,8 +270,7 @@
 static int __init omap3_touchbook_i2c_init(void)
 {
 	/* Standard TouchBook bus */
-	omap_register_i2c_bus(1, 2600, touchbook_i2c_boardinfo,
-			ARRAY_SIZE(touchbook_i2c_boardinfo));
+	omap3_pmic_init("twl4030", &touchbook_twldata);
 
 	/* Additional TouchBook bus */
 	omap_register_i2c_bus(3, 100, touchBook_i2c_boardinfo,
@@ -301,19 +279,7 @@
 	return 0;
 }
 
-static void __init omap3_ads7846_init(void)
-{
-	if (gpio_request(OMAP3_TS_GPIO, "ads7846_pen_down")) {
-		printk(KERN_ERR "Failed to request GPIO %d for "
-				"ads7846 pen down IRQ\n", OMAP3_TS_GPIO);
-		return;
-	}
-
-	gpio_direction_input(OMAP3_TS_GPIO);
-	gpio_set_debounce(OMAP3_TS_GPIO, 310);
-}
-
-static struct ads7846_platform_data ads7846_config = {
+static struct ads7846_platform_data ads7846_pdata = {
 	.x_min			= 100,
 	.y_min			= 265,
 	.x_max			= 3950,
@@ -327,23 +293,6 @@
 	.keep_vref_on		= 1,
 };
 
-static struct omap2_mcspi_device_config ads7846_mcspi_config = {
-	.turbo_mode	= 0,
-	.single_channel	= 1,	/* 0: slave, 1: master */
-};
-
-static struct spi_board_info omap3_ads7846_spi_board_info[] __initdata = {
-	{
-		.modalias		= "ads7846",
-		.bus_num		= 4,
-		.chip_select		= 0,
-		.max_speed_hz		= 1500000,
-		.controller_data	= &ads7846_mcspi_config,
-		.irq			= OMAP_GPIO_IRQ(OMAP3_TS_GPIO),
-		.platform_data		= &ads7846_config,
-	}
-};
-
 static struct gpio_led gpio_leds[] = {
 	{
 		.name			= "touchbook::usr0",
@@ -434,39 +383,6 @@
 	&keys_gpio,
 };
 
-static void __init omap3touchbook_flash_init(void)
-{
-	u8 cs = 0;
-	u8 nandcs = GPMC_CS_NUM + 1;
-
-	/* find out the chip-select on which NAND exists */
-	while (cs < GPMC_CS_NUM) {
-		u32 ret = 0;
-		ret = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG1);
-
-		if ((ret & 0xC00) == 0x800) {
-			printk(KERN_INFO "Found NAND on CS%d\n", cs);
-			if (nandcs > GPMC_CS_NUM)
-				nandcs = cs;
-		}
-		cs++;
-	}
-
-	if (nandcs > GPMC_CS_NUM) {
-		printk(KERN_INFO "NAND: Unable to find configuration "
-				 "in GPMC\n ");
-		return;
-	}
-
-	if (nandcs < GPMC_CS_NUM) {
-		omap3touchbook_nand_data.cs = nandcs;
-
-		printk(KERN_INFO "Registering NAND on CS%d\n", nandcs);
-		if (gpmc_nand_init(&omap3touchbook_nand_data) < 0)
-			printk(KERN_ERR "Unable to register NAND device\n");
-	}
-}
-
 static const struct usbhs_omap_board_data usbhs_bdata __initconst = {
 
 	.port_mode[0] = OMAP_EHCI_PORT_MODE_PHY,
@@ -481,15 +397,10 @@
 
 static void omap3_touchbook_poweroff(void)
 {
-	int r;
+	int pwr_off = TB_KILL_POWER_GPIO;
 
-	r = gpio_request(TB_KILL_POWER_GPIO, "DVI reset");
-	if (r < 0) {
+	if (gpio_request_one(pwr_off, GPIOF_OUT_INIT_LOW, "DVI reset") < 0)
 		printk(KERN_ERR "Unable to get kill power GPIO\n");
-		return;
-	}
-
-	gpio_direction_output(TB_KILL_POWER_GPIO, 0);
 }
 
 static int __init early_touchbook_revision(char *p)
@@ -501,12 +412,6 @@
 }
 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)
 {
 	omap3_mux_init(board_mux, OMAP_PACKAGE_CBB);
@@ -521,17 +426,15 @@
 	omap_serial_init();
 
 	omap_mux_init_gpio(170, OMAP_PIN_INPUT);
-	gpio_request(176, "DVI_nPD");
 	/* REVISIT leave DVI powered down until it's needed ... */
-	gpio_direction_output(176, true);
+	gpio_request_one(176, GPIOF_OUT_INIT_HIGH, "DVI_nPD");
 
 	/* Touchscreen and accelerometer */
-	spi_register_board_info(omap3_ads7846_spi_board_info,
-				ARRAY_SIZE(omap3_ads7846_spi_board_info));
-	omap3_ads7846_init();
-	usb_musb_init(&musb_board_data);
+	omap_ads7846_init(4, OMAP3_TS_GPIO, 310, &ads7846_pdata);
+	usb_musb_init(NULL);
 	usbhs_init(&usbhs_bdata);
-	omap3touchbook_flash_init();
+	omap_nand_flash_init(NAND_BUSWIDTH_16, omap3touchbook_nand_partitions,
+			     ARRAY_SIZE(omap3touchbook_nand_partitions));
 
 	/* Ensure SDRC pins are mux'd for self-refresh */
 	omap_mux_init_signal("sdrc_cke0", OMAP_PIN_OUTPUT);
diff -druN linux-2.6.39-libre/arch/arm/mach-omap2/board-omap4panda.c linux-3.0-rc7-libre/arch/arm/mach-omap2/board-omap4panda.c
--- linux-2.6.39-libre/arch/arm/mach-omap2/board-omap4panda.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-omap2/board-omap4panda.c	2011-07-11 19:51:52.000000000 -0400
@@ -34,18 +34,19 @@
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
-#include <plat/display.h>
+#include <video/omapdss.h>
 
 #include <plat/board.h>
 #include <plat/common.h>
 #include <plat/usb.h>
 #include <plat/mmc.h>
-#include <plat/panel-generic-dpi.h>
+#include <video/omap-panel-generic-dpi.h>
 #include "timer-gp.h"
 
 #include "hsmmc.h"
 #include "control.h"
 #include "mux.h"
+#include "common-board-devices.h"
 
 #define GPIO_HUB_POWER		1
 #define GPIO_HUB_NRESET		62
@@ -111,6 +112,11 @@
 	.reset_gpio_port[2]  = -EINVAL
 };
 
+static struct gpio panda_ehci_gpios[] __initdata = {
+	{ GPIO_HUB_POWER,	GPIOF_OUT_INIT_LOW,  "hub_power"  },
+	{ GPIO_HUB_NRESET,	GPIOF_OUT_INIT_LOW,  "hub_nreset" },
+};
+
 static void __init omap4_ehci_init(void)
 {
 	int ret;
@@ -120,44 +126,27 @@
 	phy_ref_clk = clk_get(NULL, "auxclk3_ck");
 	if (IS_ERR(phy_ref_clk)) {
 		pr_err("Cannot request auxclk3\n");
-		goto error1;
+		return;
 	}
 	clk_set_rate(phy_ref_clk, 19200000);
 	clk_enable(phy_ref_clk);
 
-	/* disable the power to the usb hub prior to init */
-	ret = gpio_request(GPIO_HUB_POWER, "hub_power");
+	/* disable the power to the usb hub prior to init and reset phy+hub */
+	ret = gpio_request_array(panda_ehci_gpios,
+				 ARRAY_SIZE(panda_ehci_gpios));
 	if (ret) {
-		pr_err("Cannot request GPIO %d\n", GPIO_HUB_POWER);
-		goto error1;
+		pr_err("Unable to initialize EHCI power/reset\n");
+		return;
 	}
-	gpio_export(GPIO_HUB_POWER, 0);
-	gpio_direction_output(GPIO_HUB_POWER, 0);
-	gpio_set_value(GPIO_HUB_POWER, 0);
 
-	/* reset phy+hub */
-	ret = gpio_request(GPIO_HUB_NRESET, "hub_nreset");
-	if (ret) {
-		pr_err("Cannot request GPIO %d\n", GPIO_HUB_NRESET);
-		goto error2;
-	}
+	gpio_export(GPIO_HUB_POWER, 0);
 	gpio_export(GPIO_HUB_NRESET, 0);
-	gpio_direction_output(GPIO_HUB_NRESET, 0);
-	gpio_set_value(GPIO_HUB_NRESET, 0);
 	gpio_set_value(GPIO_HUB_NRESET, 1);
 
 	usbhs_init(&usbhs_bdata);
 
 	/* enable power to hub */
 	gpio_set_value(GPIO_HUB_POWER, 1);
-	return;
-
-error2:
-	gpio_free(GPIO_HUB_POWER);
-error1:
-	pr_err("Unable to initialize EHCI power/reset\n");
-	return;
-
 }
 
 static struct omap_musb_board_data musb_board_data = {
@@ -408,15 +397,6 @@
 	.usb		= &omap4_usbphy_data,
 };
 
-static struct i2c_board_info __initdata omap4_panda_i2c_boardinfo[] = {
-	{
-		I2C_BOARD_INFO("twl6030", 0x48),
-		.flags = I2C_CLIENT_WAKE,
-		.irq = OMAP44XX_IRQ_SYS_1N,
-		.platform_data = &omap4_panda_twldata,
-	},
-};
-
 /*
  * Display monitor features are burnt in their EEPROM as EDID data. The EEPROM
  * is connected as I2C slave device, and can be accessed at address 0x50
@@ -429,12 +409,7 @@
 
 static int __init omap4_panda_i2c_init(void)
 {
-	/*
-	 * Phoenix Audio IC needs I2C1 to
-	 * start with 400 KHz or less
-	 */
-	omap_register_i2c_bus(1, 400, omap4_panda_i2c_boardinfo,
-			ARRAY_SIZE(omap4_panda_i2c_boardinfo));
+	omap4_pmic_init("twl6030", &omap4_panda_twldata);
 	omap_register_i2c_bus(2, 400, NULL, 0);
 	/*
 	 * Bus 3 is attached to the DVI port where devices like the pico DLP
@@ -551,19 +526,19 @@
 			 OMAP_PIN_OUTPUT | OMAP_MUX_MODE0),
 };
 
-static struct omap_board_data serial2_data = {
+static struct omap_board_data serial2_data __initdata = {
 	.id             = 1,
 	.pads           = serial2_pads,
 	.pads_cnt       = ARRAY_SIZE(serial2_pads),
 };
 
-static struct omap_board_data serial3_data = {
+static struct omap_board_data serial3_data __initdata = {
 	.id             = 2,
 	.pads           = serial3_pads,
 	.pads_cnt       = ARRAY_SIZE(serial3_pads),
 };
 
-static struct omap_board_data serial4_data = {
+static struct omap_board_data serial4_data __initdata = {
 	.id             = 3,
 	.pads           = serial4_pads,
 	.pads_cnt       = ARRAY_SIZE(serial4_pads),
@@ -651,27 +626,19 @@
 			OMAP_PIN_INPUT_PULLUP);
 }
 
+static struct gpio panda_hdmi_gpios[] = {
+	{ HDMI_GPIO_HPD,	GPIOF_OUT_INIT_HIGH, "hdmi_gpio_hpd"   },
+	{ HDMI_GPIO_LS_OE,	GPIOF_OUT_INIT_HIGH, "hdmi_gpio_ls_oe" },
+};
+
 static int omap4_panda_panel_enable_hdmi(struct omap_dss_device *dssdev)
 {
 	int status;
 
-	status = gpio_request_one(HDMI_GPIO_HPD, GPIOF_OUT_INIT_HIGH,
-							"hdmi_gpio_hpd");
-	if (status) {
-		pr_err("Cannot request GPIO %d\n", HDMI_GPIO_HPD);
-		return status;
-	}
-	status = gpio_request_one(HDMI_GPIO_LS_OE, GPIOF_OUT_INIT_HIGH,
-							"hdmi_gpio_ls_oe");
-	if (status) {
-		pr_err("Cannot request GPIO %d\n", HDMI_GPIO_LS_OE);
-		goto error1;
-	}
-
-	return 0;
-
-error1:
-	gpio_free(HDMI_GPIO_HPD);
+	status = gpio_request_array(panda_hdmi_gpios,
+				    ARRAY_SIZE(panda_hdmi_gpios));
+	if (status)
+		pr_err("Cannot request HDMI GPIOs\n");
 
 	return status;
 }
@@ -720,7 +687,7 @@
 
 	if (omap_rev() == OMAP4430_REV_ES1_0)
 		package = OMAP_PACKAGE_CBL;
-	omap4_mux_init(board_mux, package);
+	omap4_mux_init(board_mux, NULL, package);
 
 	if (wl12xx_set_platform_data(&omap_panda_wlan_data))
 		pr_err("error setting wl12xx data\n");
diff -druN linux-2.6.39-libre/arch/arm/mach-omap2/board-overo.c linux-3.0-rc7-libre/arch/arm/mach-omap2/board-overo.c
--- linux-2.6.39-libre/arch/arm/mach-omap2/board-overo.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-omap2/board-overo.c	2011-07-11 19:51:52.000000000 -0400
@@ -24,6 +24,7 @@
 #include <linux/err.h>
 #include <linux/init.h>
 #include <linux/io.h>
+#include <linux/gpio.h>
 #include <linux/kernel.h>
 #include <linux/platform_device.h>
 #include <linux/i2c/twl.h>
@@ -43,9 +44,8 @@
 
 #include <plat/board.h>
 #include <plat/common.h>
-#include <plat/display.h>
-#include <plat/panel-generic-dpi.h>
-#include <mach/gpio.h>
+#include <video/omapdss.h>
+#include <video/omap-panel-generic-dpi.h>
 #include <plat/gpmc.h>
 #include <mach/hardware.h>
 #include <plat/nand.h>
@@ -56,6 +56,7 @@
 #include "mux.h"
 #include "sdram-micron-mt46h32m32lf-6.h"
 #include "hsmmc.h"
+#include "common-board-devices.h"
 
 #define OVERO_GPIO_BT_XGATE	15
 #define OVERO_GPIO_W2W_NRESET	16
@@ -64,8 +65,6 @@
 #define OVERO_GPIO_USBH_CPEN	168
 #define OVERO_GPIO_USBH_NRESET	183
 
-#define NAND_BLOCK_SIZE SZ_128K
-
 #define OVERO_SMSC911X_CS      5
 #define OVERO_SMSC911X_GPIO    176
 #define OVERO_SMSC911X2_CS     4
@@ -74,30 +73,6 @@
 #if defined(CONFIG_TOUCHSCREEN_ADS7846) || \
 	defined(CONFIG_TOUCHSCREEN_ADS7846_MODULE)
 
-#include <linux/spi/ads7846.h>
-
-static struct omap2_mcspi_device_config ads7846_mcspi_config = {
-	.turbo_mode	= 0,
-	.single_channel	= 1,	/* 0: slave, 1: master */
-};
-
-static int ads7846_get_pendown_state(void)
-{
-	return !gpio_get_value(OVERO_GPIO_PENDOWN);
-}
-
-static struct ads7846_platform_data ads7846_config = {
-	.x_max			= 0x0fff,
-	.y_max			= 0x0fff,
-	.x_plate_ohms		= 180,
-	.pressure_max		= 255,
-	.debounce_max		= 10,
-	.debounce_tol		= 3,
-	.debounce_rep		= 1,
-	.get_pendown_state	= ads7846_get_pendown_state,
-	.keep_vref_on		= 1,
-};
-
 /* fixed regulator for ads7846 */
 static struct regulator_consumer_supply ads7846_supply =
 	REGULATOR_SUPPLY("vcc", "spi1.0");
@@ -128,14 +103,7 @@
 
 static void __init overo_ads7846_init(void)
 {
-	if ((gpio_request(OVERO_GPIO_PENDOWN, "ADS7846_PENDOWN") == 0) &&
-	    (gpio_direction_input(OVERO_GPIO_PENDOWN) == 0)) {
-		gpio_export(OVERO_GPIO_PENDOWN, 0);
-	} else {
-		printk(KERN_ERR "could not obtain gpio for ADS7846_PENDOWN\n");
-		return;
-	}
-
+	omap_ads7846_init(1, OVERO_GPIO_PENDOWN, 0, NULL);
 	platform_device_register(&vads7846_device);
 }
 
@@ -146,106 +114,28 @@
 #if defined(CONFIG_SMSC911X) || defined(CONFIG_SMSC911X_MODULE)
 
 #include <linux/smsc911x.h>
+#include <plat/gpmc-smsc911x.h>
 
-static struct resource overo_smsc911x_resources[] = {
-	{
-		.name	= "smsc911x-memory",
-		.flags	= IORESOURCE_MEM,
-	},
-	{
-		.flags	= IORESOURCE_IRQ | IORESOURCE_IRQ_LOWLEVEL,
-	},
-};
-
-static struct resource overo_smsc911x2_resources[] = {
-	{
-		.name	= "smsc911x2-memory",
-		.flags	= IORESOURCE_MEM,
-	},
-	{
-		.flags	= IORESOURCE_IRQ | IORESOURCE_IRQ_LOWLEVEL,
-	},
-};
-
-static struct smsc911x_platform_config overo_smsc911x_config = {
-	.irq_polarity	= SMSC911X_IRQ_POLARITY_ACTIVE_LOW,
-	.irq_type	= SMSC911X_IRQ_TYPE_OPEN_DRAIN,
-	.flags		= SMSC911X_USE_32BIT ,
-	.phy_interface	= PHY_INTERFACE_MODE_MII,
-};
-
-static struct platform_device overo_smsc911x_device = {
-	.name		= "smsc911x",
+static struct omap_smsc911x_platform_data smsc911x_cfg = {
 	.id		= 0,
-	.num_resources	= ARRAY_SIZE(overo_smsc911x_resources),
-	.resource	= overo_smsc911x_resources,
-	.dev		= {
-		.platform_data = &overo_smsc911x_config,
-	},
+	.cs             = OVERO_SMSC911X_CS,
+	.gpio_irq       = OVERO_SMSC911X_GPIO,
+	.gpio_reset     = -EINVAL,
+	.flags		= SMSC911X_USE_32BIT,
 };
 
-static struct platform_device overo_smsc911x2_device = {
-	.name		= "smsc911x",
+static struct omap_smsc911x_platform_data smsc911x2_cfg = {
 	.id		= 1,
-	.num_resources	= ARRAY_SIZE(overo_smsc911x2_resources),
-	.resource	= overo_smsc911x2_resources,
-	.dev		= {
-		.platform_data = &overo_smsc911x_config,
-	},
-};
-
-static struct platform_device *smsc911x_devices[] = {
-	&overo_smsc911x_device,
-	&overo_smsc911x2_device,
+	.cs             = OVERO_SMSC911X2_CS,
+	.gpio_irq       = OVERO_SMSC911X2_GPIO,
+	.gpio_reset     = -EINVAL,
+	.flags		= SMSC911X_USE_32BIT,
 };
 
-static inline void __init overo_init_smsc911x(void)
+static void __init overo_init_smsc911x(void)
 {
-	unsigned long cs_mem_base, cs_mem_base2;
-
-	/* set up first smsc911x chip */
-
-	if (gpmc_cs_request(OVERO_SMSC911X_CS, SZ_16M, &cs_mem_base) < 0) {
-		printk(KERN_ERR "Failed request for GPMC mem for smsc911x\n");
-		return;
-	}
-
-	overo_smsc911x_resources[0].start = cs_mem_base + 0x0;
-	overo_smsc911x_resources[0].end   = cs_mem_base + 0xff;
-
-	if ((gpio_request(OVERO_SMSC911X_GPIO, "SMSC911X IRQ") == 0) &&
-	    (gpio_direction_input(OVERO_SMSC911X_GPIO) == 0)) {
-		gpio_export(OVERO_SMSC911X_GPIO, 0);
-	} else {
-		printk(KERN_ERR "could not obtain gpio for SMSC911X IRQ\n");
-		return;
-	}
-
-	overo_smsc911x_resources[1].start = OMAP_GPIO_IRQ(OVERO_SMSC911X_GPIO);
-	overo_smsc911x_resources[1].end	  = 0;
-
-	/* set up second smsc911x chip */
-
-	if (gpmc_cs_request(OVERO_SMSC911X2_CS, SZ_16M, &cs_mem_base2) < 0) {
-		printk(KERN_ERR "Failed request for GPMC mem for smsc911x2\n");
-		return;
-	}
-
-	overo_smsc911x2_resources[0].start = cs_mem_base2 + 0x0;
-	overo_smsc911x2_resources[0].end   = cs_mem_base2 + 0xff;
-
-	if ((gpio_request(OVERO_SMSC911X2_GPIO, "SMSC911X2 IRQ") == 0) &&
-	    (gpio_direction_input(OVERO_SMSC911X2_GPIO) == 0)) {
-		gpio_export(OVERO_SMSC911X2_GPIO, 0);
-	} else {
-		printk(KERN_ERR "could not obtain gpio for SMSC911X2 IRQ\n");
-		return;
-	}
-
-	overo_smsc911x2_resources[1].start = OMAP_GPIO_IRQ(OVERO_SMSC911X2_GPIO);
-	overo_smsc911x2_resources[1].end   = 0;
-
-	platform_add_devices(smsc911x_devices, ARRAY_SIZE(smsc911x_devices));
+	gpmc_smsc911x_init(&smsc911x_cfg);
+	gpmc_smsc911x_init(&smsc911x2_cfg);
 }
 
 #else
@@ -259,21 +149,20 @@
 #define OVERO_GPIO_LCD_EN 144
 #define OVERO_GPIO_LCD_BL 145
 
+static struct gpio overo_dss_gpios[] __initdata = {
+	{ OVERO_GPIO_LCD_EN, GPIOF_OUT_INIT_HIGH, "OVERO_GPIO_LCD_EN" },
+	{ OVERO_GPIO_LCD_BL, GPIOF_OUT_INIT_HIGH, "OVERO_GPIO_LCD_BL" },
+};
+
 static void __init overo_display_init(void)
 {
-	if ((gpio_request(OVERO_GPIO_LCD_EN, "OVERO_GPIO_LCD_EN") == 0) &&
-	    (gpio_direction_output(OVERO_GPIO_LCD_EN, 1) == 0))
-		gpio_export(OVERO_GPIO_LCD_EN, 0);
-	else
-		printk(KERN_ERR "could not obtain gpio for "
-					"OVERO_GPIO_LCD_EN\n");
+	if (gpio_request_array(overo_dss_gpios, ARRAY_SIZE(overo_dss_gpios))) {
+		printk(KERN_ERR "could not obtain DSS control GPIOs\n");
+		return;
+	}
 
-	if ((gpio_request(OVERO_GPIO_LCD_BL, "OVERO_GPIO_LCD_BL") == 0) &&
-	    (gpio_direction_output(OVERO_GPIO_LCD_BL, 1) == 0))
-		gpio_export(OVERO_GPIO_LCD_BL, 0);
-	else
-		printk(KERN_ERR "could not obtain gpio for "
-					"OVERO_GPIO_LCD_BL\n");
+	gpio_export(OVERO_GPIO_LCD_EN, 0);
+	gpio_export(OVERO_GPIO_LCD_BL, 0);
 }
 
 static int overo_panel_enable_dvi(struct omap_dss_device *dssdev)
@@ -412,45 +301,6 @@
 	},
 };
 
-static struct omap_nand_platform_data overo_nand_data = {
-	.parts = overo_nand_partitions,
-	.nr_parts = ARRAY_SIZE(overo_nand_partitions),
-	.dma_channel = -1,	/* disable DMA in OMAP NAND driver */
-};
-
-static void __init overo_flash_init(void)
-{
-	u8 cs = 0;
-	u8 nandcs = GPMC_CS_NUM + 1;
-
-	/* 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) {
-		overo_nand_data.cs = nandcs;
-
-		printk(KERN_INFO "Registering NAND on CS%d\n", nandcs);
-		if (gpmc_nand_init(&overo_nand_data) < 0)
-			printk(KERN_ERR "Unable to register NAND device\n");
-	}
-}
-
 static struct omap2_hsmmc_info mmc[] = {
 	{
 		.mmc		= 1,
@@ -648,37 +498,15 @@
 	.vpll2		= &overo_vpll2,
 };
 
-static struct i2c_board_info __initdata overo_i2c_boardinfo[] = {
-	{
-		I2C_BOARD_INFO("tps65950", 0x48),
-		.flags = I2C_CLIENT_WAKE,
-		.irq = INT_34XX_SYS_NIRQ,
-		.platform_data = &overo_twldata,
-	},
-};
-
 static int __init overo_i2c_init(void)
 {
-	omap_register_i2c_bus(1, 2600, overo_i2c_boardinfo,
-			ARRAY_SIZE(overo_i2c_boardinfo));
+	omap3_pmic_init("tps65950", &overo_twldata);
 	/* i2c2 pins are used for gpio */
 	omap_register_i2c_bus(3, 400, NULL, 0);
 	return 0;
 }
 
 static struct spi_board_info overo_spi_board_info[] __initdata = {
-#if defined(CONFIG_TOUCHSCREEN_ADS7846) || \
-	defined(CONFIG_TOUCHSCREEN_ADS7846_MODULE)
-	{
-		.modalias		= "ads7846",
-		.bus_num		= 1,
-		.chip_select		= 0,
-		.max_speed_hz		= 1500000,
-		.controller_data	= &ads7846_mcspi_config,
-		.irq			= OMAP_GPIO_IRQ(OVERO_GPIO_PENDOWN),
-		.platform_data		= &ads7846_config,
-	},
-#endif
 #if defined(CONFIG_PANEL_LGPHILIPS_LB035Q02) || \
 	defined(CONFIG_PANEL_LGPHILIPS_LB035Q02_MODULE)
 	{
@@ -722,20 +550,22 @@
 };
 #endif
 
-static struct omap_musb_board_data musb_board_data = {
-	.interface_type		= MUSB_INTERFACE_ULPI,
-	.mode			= MUSB_OTG,
-	.power			= 100,
+static struct gpio overo_bt_gpios[] __initdata = {
+	{ OVERO_GPIO_BT_XGATE,	GPIOF_OUT_INIT_LOW,	"lcd enable"    },
+	{ OVERO_GPIO_BT_NRESET, GPIOF_OUT_INIT_HIGH,	"lcd bl enable" },
 };
 
 static void __init overo_init(void)
 {
+	int ret;
+
 	omap3_mux_init(board_mux, OMAP_PACKAGE_CBB);
 	overo_i2c_init();
 	omap_display_init(&overo_dss_data);
 	omap_serial_init();
-	overo_flash_init();
-	usb_musb_init(&musb_board_data);
+	omap_nand_flash_init(0, overo_nand_partitions,
+			     ARRAY_SIZE(overo_nand_partitions));
+	usb_musb_init(NULL);
 	usbhs_init(&usbhs_bdata);
 	overo_spi_init();
 	overo_ads7846_init();
@@ -748,9 +578,9 @@
 	omap_mux_init_signal("sdrc_cke0", OMAP_PIN_OUTPUT);
 	omap_mux_init_signal("sdrc_cke1", OMAP_PIN_OUTPUT);
 
-	if ((gpio_request(OVERO_GPIO_W2W_NRESET,
-			  "OVERO_GPIO_W2W_NRESET") == 0) &&
-	    (gpio_direction_output(OVERO_GPIO_W2W_NRESET, 1) == 0)) {
+	ret = gpio_request_one(OVERO_GPIO_W2W_NRESET, GPIOF_OUT_INIT_HIGH,
+			       "OVERO_GPIO_W2W_NRESET");
+	if (ret == 0) {
 		gpio_export(OVERO_GPIO_W2W_NRESET, 0);
 		gpio_set_value(OVERO_GPIO_W2W_NRESET, 0);
 		udelay(10);
@@ -760,25 +590,20 @@
 					"OVERO_GPIO_W2W_NRESET\n");
 	}
 
-	if ((gpio_request(OVERO_GPIO_BT_XGATE, "OVERO_GPIO_BT_XGATE") == 0) &&
-	    (gpio_direction_output(OVERO_GPIO_BT_XGATE, 0) == 0))
+	ret = gpio_request_array(overo_bt_gpios, ARRAY_SIZE(overo_bt_gpios));
+	if (ret) {
+		pr_err("%s: could not obtain BT gpios\n", __func__);
+	} else {
 		gpio_export(OVERO_GPIO_BT_XGATE, 0);
-	else
-		printk(KERN_ERR "could not obtain gpio for OVERO_GPIO_BT_XGATE\n");
-
-	if ((gpio_request(OVERO_GPIO_BT_NRESET, "OVERO_GPIO_BT_NRESET") == 0) &&
-	    (gpio_direction_output(OVERO_GPIO_BT_NRESET, 1) == 0)) {
 		gpio_export(OVERO_GPIO_BT_NRESET, 0);
 		gpio_set_value(OVERO_GPIO_BT_NRESET, 0);
 		mdelay(6);
 		gpio_set_value(OVERO_GPIO_BT_NRESET, 1);
-	} else {
-		printk(KERN_ERR "could not obtain gpio for "
-					"OVERO_GPIO_BT_NRESET\n");
 	}
 
-	if ((gpio_request(OVERO_GPIO_USBH_CPEN, "OVERO_GPIO_USBH_CPEN") == 0) &&
-	    (gpio_direction_output(OVERO_GPIO_USBH_CPEN, 1) == 0))
+	ret = gpio_request_one(OVERO_GPIO_USBH_CPEN, GPIOF_OUT_INIT_HIGH,
+			       "OVERO_GPIO_USBH_CPEN");
+	if (ret == 0)
 		gpio_export(OVERO_GPIO_USBH_CPEN, 0);
 	else
 		printk(KERN_ERR "could not obtain gpio for "
diff -druN linux-2.6.39-libre/arch/arm/mach-omap2/board-rm680.c linux-3.0-rc7-libre/arch/arm/mach-omap2/board-rm680.c
--- linux-2.6.39-libre/arch/arm/mach-omap2/board-rm680.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-omap2/board-rm680.c	2011-07-11 19:51:52.000000000 -0400
@@ -31,6 +31,7 @@
 #include "mux.h"
 #include "hsmmc.h"
 #include "sdram-nokia.h"
+#include "common-board-devices.h"
 
 static struct regulator_consumer_supply rm680_vemmc_consumers[] = {
 	REGULATOR_SUPPLY("vmmc", "omap_hsmmc.1"),
@@ -90,19 +91,9 @@
 	/* add rest of the children here */
 };
 
-static struct i2c_board_info __initdata rm680_twl_i2c_board_info[] = {
-	{
-		I2C_BOARD_INFO("twl5031", 0x48),
-		.flags		= I2C_CLIENT_WAKE,
-		.irq		= INT_34XX_SYS_NIRQ,
-		.platform_data	= &rm680_twl_data,
-	},
-};
-
 static void __init rm680_i2c_init(void)
 {
-	omap_register_i2c_bus(1, 2900, rm680_twl_i2c_board_info,
-				ARRAY_SIZE(rm680_twl_i2c_board_info));
+	omap_pmic_init(1, 2900, "twl5031", INT_34XX_SYS_NIRQ, &rm680_twl_data);
 	omap_register_i2c_bus(2, 400, NULL, 0);
 	omap_register_i2c_bus(3, 400, NULL, 0);
 }
@@ -153,17 +144,11 @@
 };
 #endif
 
-static struct omap_musb_board_data rm680_musb_data = {
-	.interface_type	= MUSB_INTERFACE_ULPI,
-	.mode		= MUSB_PERIPHERAL,
-	.power		= 100,
-};
-
 static void __init rm680_init(void)
 {
 	omap3_mux_init(board_mux, OMAP_PACKAGE_CBB);
 	omap_serial_init();
-	usb_musb_init(&rm680_musb_data);
+	usb_musb_init(NULL);
 	rm680_peripherals_init();
 }
 
diff -druN linux-2.6.39-libre/arch/arm/mach-omap2/board-rx51.c linux-3.0-rc7-libre/arch/arm/mach-omap2/board-rx51.c
--- linux-2.6.39-libre/arch/arm/mach-omap2/board-rx51.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-omap2/board-rx51.c	2011-07-11 19:51:52.000000000 -0400
@@ -58,21 +58,25 @@
 	},
 };
 
+/*
+ * cpuidle C-states definition override from the default values.
+ * The 'exit_latency' field is the sum of sleep and wake-up latencies.
+ */
 static struct cpuidle_params rx51_cpuidle_params[] = {
 	/* C1 */
-	{1, 110, 162, 5},
+	{110 + 162, 5 , 1},
 	/* C2 */
-	{1, 106, 180, 309},
+	{106 + 180, 309, 1},
 	/* C3 */
-	{0, 107, 410, 46057},
+	{107 + 410, 46057, 0},
 	/* C4 */
-	{0, 121, 3374, 46057},
+	{121 + 3374, 46057, 0},
 	/* C5 */
-	{1, 855, 1146, 46057},
+	{855 + 1146, 46057, 1},
 	/* C6 */
-	{0, 7580, 4134, 484329},
+	{7580 + 4134, 484329, 0},
 	/* C7 */
-	{1, 7505, 15274, 484329},
+	{7505 + 15274, 484329, 1},
 };
 
 static struct omap_lcd_config rx51_lcd_config = {
diff -druN linux-2.6.39-libre/arch/arm/mach-omap2/board-rx51-peripherals.c linux-3.0-rc7-libre/arch/arm/mach-omap2/board-rx51-peripherals.c
--- linux-2.6.39-libre/arch/arm/mach-omap2/board-rx51-peripherals.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-omap2/board-rx51-peripherals.c	2011-07-11 19:51:52.000000000 -0400
@@ -23,6 +23,7 @@
 #include <linux/gpio.h>
 #include <linux/gpio_keys.h>
 #include <linux/mmc/host.h>
+#include <linux/power/isp1704_charger.h>
 
 #include <plat/mcspi.h>
 #include <plat/board.h>
@@ -43,6 +44,7 @@
 
 #include "mux.h"
 #include "hsmmc.h"
+#include "common-board-devices.h"
 
 #define SYSTEM_REV_B_USES_VAUX3	0x1699
 #define SYSTEM_REV_S_USES_VAUX3 0x8
@@ -52,6 +54,8 @@
 #define RX51_FMTX_RESET_GPIO		163
 #define RX51_FMTX_IRQ			53
 
+#define RX51_USB_TRANSCEIVER_RST_GPIO	67
+
 /* list all spi devices here */
 enum {
 	RX51_SPI_WL1251,
@@ -110,10 +114,30 @@
 	},
 };
 
+static void rx51_charger_set_power(bool on)
+{
+	gpio_set_value(RX51_USB_TRANSCEIVER_RST_GPIO, on);
+}
+
+static struct isp1704_charger_data rx51_charger_data = {
+	.set_power	= rx51_charger_set_power,
+};
+
 static struct platform_device rx51_charger_device = {
-	.name = "isp1704_charger",
+	.name	= "isp1704_charger",
+	.dev	= {
+		.platform_data = &rx51_charger_data,
+	},
 };
 
+static void __init rx51_charger_init(void)
+{
+	WARN_ON(gpio_request_one(RX51_USB_TRANSCEIVER_RST_GPIO,
+		GPIOF_OUT_INIT_LOW, "isp1704_reset"));
+
+	platform_device_register(&rx51_charger_device);
+}
+
 #if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
 
 #define RX51_GPIO_CAMERA_LENS_COVER	110
@@ -464,6 +488,7 @@
 		.name			= "V28_A",
 		.min_uV			= 2800000,
 		.max_uV			= 3000000,
+		.always_on		= true, /* due VIO leak to AIC34 VDDs */
 		.apply_uV		= true,
 		.valid_modes_mask	= REGULATOR_MODE_NORMAL
 					| REGULATOR_MODE_STANDBY,
@@ -533,7 +558,7 @@
 	.subdev_board_info = &rx51_si4713_board_info,
 };
 
-static struct platform_device rx51_si4713_dev __initdata_or_module = {
+static struct platform_device rx51_si4713_dev = {
 	.name	= "radio-si4713",
 	.id	= -1,
 	.dev	= {
@@ -557,10 +582,8 @@
 static int rx51_twlgpio_setup(struct device *dev, unsigned gpio, unsigned n)
 {
 	/* FIXME this gpio setup is just a placeholder for now */
-	gpio_request(gpio + 6, "backlight_pwm");
-	gpio_direction_output(gpio + 6, 0);
-	gpio_request(gpio + 7, "speaker_en");
-	gpio_direction_output(gpio + 7, 1);
+	gpio_request_one(gpio + 6, GPIOF_OUT_INIT_LOW, "backlight_pwm");
+	gpio_request_one(gpio + 7, GPIOF_OUT_INIT_LOW, "speaker_en");
 
 	return 0;
 }
@@ -730,7 +753,7 @@
 	{ .resource = RES_RESET, .devgroup = -1,
 	  .type = 1, .type2 = -1, .remap_off = -1, .remap_sleep = -1
 	},
-	{ .resource = RES_Main_Ref, .devgroup = -1,
+	{ .resource = RES_MAIN_REF, .devgroup = -1,
 	  .type = 1, .type2 = -1, .remap_off = -1, .remap_sleep = -1
 	},
 	{ 0, 0},
@@ -777,15 +800,6 @@
 	.power_gpio		= 98,
 };
 
-static struct i2c_board_info __initdata rx51_peripherals_i2c_board_info_1[] = {
-	{
-		I2C_BOARD_INFO("twl5030", 0x48),
-		.flags = I2C_CLIENT_WAKE,
-		.irq = INT_34XX_SYS_NIRQ,
-		.platform_data = &rx51_twldata,
-	},
-};
-
 /* Audio setup data */
 static struct aic3x_setup_data rx51_aic34_setup = {
 	.gpio_func[0] = AIC3X_GPIO1_FUNC_DISABLED,
@@ -833,8 +847,7 @@
 		rx51_twldata.vaux3 = &rx51_vaux3_cam;
 	}
 	rx51_twldata.vmmc2 = &rx51_vmmc2;
-	omap_register_i2c_bus(1, 2200, rx51_peripherals_i2c_board_info_1,
-			      ARRAY_SIZE(rx51_peripherals_i2c_board_info_1));
+	omap_pmic_init(1, 2200, "twl5030", INT_34XX_SYS_NIRQ, &rx51_twldata);
 	omap_register_i2c_bus(2, 100, rx51_peripherals_i2c_board_info_2,
 			      ARRAY_SIZE(rx51_peripherals_i2c_board_info_2));
 	omap_register_i2c_bus(3, 400, NULL, 0);
@@ -921,26 +934,20 @@
 	gpio_set_value(RX51_WL1251_POWER_GPIO, enable);
 }
 
+static struct gpio rx51_wl1251_gpios[] __initdata = {
+	{ RX51_WL1251_POWER_GPIO, GPIOF_OUT_INIT_LOW,	"wl1251 power"	},
+	{ RX51_WL1251_IRQ_GPIO,	  GPIOF_IN,		"wl1251 irq"	},
+};
+
 static void __init rx51_init_wl1251(void)
 {
 	int irq, ret;
 
-	ret = gpio_request(RX51_WL1251_POWER_GPIO, "wl1251 power");
+	ret = gpio_request_array(rx51_wl1251_gpios,
+				 ARRAY_SIZE(rx51_wl1251_gpios));
 	if (ret < 0)
 		goto error;
 
-	ret = gpio_direction_output(RX51_WL1251_POWER_GPIO, 0);
-	if (ret < 0)
-		goto err_power;
-
-	ret = gpio_request(RX51_WL1251_IRQ_GPIO, "wl1251 irq");
-	if (ret < 0)
-		goto err_power;
-
-	ret = gpio_direction_input(RX51_WL1251_IRQ_GPIO);
-	if (ret < 0)
-		goto err_irq;
-
 	irq = gpio_to_irq(RX51_WL1251_IRQ_GPIO);
 	if (irq < 0)
 		goto err_irq;
@@ -952,10 +959,7 @@
 
 err_irq:
 	gpio_free(RX51_WL1251_IRQ_GPIO);
-
-err_power:
 	gpio_free(RX51_WL1251_POWER_GPIO);
-
 error:
 	printk(KERN_ERR "wl1251 board initialisation failed\n");
 	wl1251_pdata.set_power = NULL;
@@ -981,6 +985,6 @@
 	if (partition)
 		omap2_hsmmc_init(mmc);
 
-	platform_device_register(&rx51_charger_device);
+	rx51_charger_init();
 }
 
diff -druN linux-2.6.39-libre/arch/arm/mach-omap2/board-rx51-video.c linux-3.0-rc7-libre/arch/arm/mach-omap2/board-rx51-video.c
--- linux-2.6.39-libre/arch/arm/mach-omap2/board-rx51-video.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-omap2/board-rx51-video.c	2011-07-11 19:51:52.000000000 -0400
@@ -15,7 +15,7 @@
 #include <linux/spi/spi.h>
 #include <linux/mm.h>
 #include <asm/mach-types.h>
-#include <plat/display.h>
+#include <video/omapdss.h>
 #include <plat/vram.h>
 #include <plat/mcspi.h>
 
@@ -76,13 +76,12 @@
 		return 0;
 	}
 
-	if (gpio_request(RX51_LCD_RESET_GPIO, "LCD ACX565AKM reset")) {
+	if (gpio_request_one(RX51_LCD_RESET_GPIO, GPIOF_OUT_INIT_HIGH,
+			     "LCD ACX565AKM reset")) {
 		pr_err("%s failed to get LCD Reset GPIO\n", __func__);
 		return 0;
 	}
 
-	gpio_direction_output(RX51_LCD_RESET_GPIO, 1);
-
 	omap_display_init(&rx51_dss_board_info);
 	return 0;
 }
diff -druN linux-2.6.39-libre/arch/arm/mach-omap2/board-zoom-debugboard.c linux-3.0-rc7-libre/arch/arm/mach-omap2/board-zoom-debugboard.c
--- linux-2.6.39-libre/arch/arm/mach-omap2/board-zoom-debugboard.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-omap2/board-zoom-debugboard.c	2011-07-11 19:51:52.000000000 -0400
@@ -15,6 +15,7 @@
 #include <linux/interrupt.h>
 
 #include <plat/gpmc.h>
+#include <plat/gpmc-smsc911x.h>
 
 #include <mach/board-zoom.h>
 
@@ -26,60 +27,16 @@
 #define DEBUG_BASE		0x08000000
 #define ZOOM_ETHR_START	DEBUG_BASE
 
-static struct resource zoom_smsc911x_resources[] = {
-	[0] = {
-		.start	= ZOOM_ETHR_START,
-		.end	= ZOOM_ETHR_START + SZ_4K,
-		.flags	= IORESOURCE_MEM,
-	},
-	[1] = {
-		.flags	= IORESOURCE_IRQ | IORESOURCE_IRQ_LOWLEVEL,
-	},
-};
-
-static struct smsc911x_platform_config zoom_smsc911x_config = {
-	.irq_polarity	= SMSC911X_IRQ_POLARITY_ACTIVE_LOW,
-	.irq_type	= SMSC911X_IRQ_TYPE_OPEN_DRAIN,
+static struct omap_smsc911x_platform_data zoom_smsc911x_cfg = {
+	.cs             = ZOOM_SMSC911X_CS,
+	.gpio_irq       = ZOOM_SMSC911X_GPIO,
+	.gpio_reset     = -EINVAL,
 	.flags		= SMSC911X_USE_32BIT,
-	.phy_interface	= PHY_INTERFACE_MODE_MII,
-};
-
-static struct platform_device zoom_smsc911x_device = {
-	.name		= "smsc911x",
-	.id		= -1,
-	.num_resources	= ARRAY_SIZE(zoom_smsc911x_resources),
-	.resource	= zoom_smsc911x_resources,
-	.dev		= {
-		.platform_data = &zoom_smsc911x_config,
-	},
 };
 
 static inline void __init zoom_init_smsc911x(void)
 {
-	int eth_cs;
-	unsigned long cs_mem_base;
-	int eth_gpio = 0;
-
-	eth_cs = ZOOM_SMSC911X_CS;
-
-	if (gpmc_cs_request(eth_cs, SZ_16M, &cs_mem_base) < 0) {
-		printk(KERN_ERR "Failed to request GPMC mem for smsc911x\n");
-		return;
-	}
-
-	zoom_smsc911x_resources[0].start = cs_mem_base + 0x0;
-	zoom_smsc911x_resources[0].end   = cs_mem_base + 0xff;
-
-	eth_gpio = ZOOM_SMSC911X_GPIO;
-
-	zoom_smsc911x_resources[1].start = OMAP_GPIO_IRQ(eth_gpio);
-
-	if (gpio_request(eth_gpio, "smsc911x irq") < 0) {
-		printk(KERN_ERR "Failed to request GPIO%d for smsc911x IRQ\n",
-				eth_gpio);
-		return;
-	}
-	gpio_direction_input(eth_gpio);
+	gpmc_smsc911x_init(&zoom_smsc911x_cfg);
 }
 
 static struct plat_serial8250_port serial_platform_data[] = {
@@ -120,12 +77,9 @@
 
 	quart_gpio = ZOOM_QUADUART_GPIO;
 
-	if (gpio_request(quart_gpio, "TL16CP754C GPIO") < 0) {
+	if (gpio_request_one(quart_gpio, GPIOF_IN, "TL16CP754C GPIO") < 0)
 		printk(KERN_ERR "Failed to request GPIO%d for TL16CP754C\n",
 								quart_gpio);
-		return;
-	}
-	gpio_direction_input(quart_gpio);
 }
 
 static inline int omap_zoom_debugboard_detect(void)
@@ -135,12 +89,12 @@
 
 	debug_board_detect = ZOOM_SMSC911X_GPIO;
 
-	if (gpio_request(debug_board_detect, "Zoom debug board detect") < 0) {
+	if (gpio_request_one(debug_board_detect, GPIOF_IN,
+			     "Zoom debug board detect") < 0) {
 		printk(KERN_ERR "Failed to request GPIO%d for Zoom debug"
 		"board detect\n", debug_board_detect);
 		return 0;
 	}
-	gpio_direction_input(debug_board_detect);
 
 	if (!gpio_get_value(debug_board_detect)) {
 		ret = 0;
@@ -150,7 +104,6 @@
 }
 
 static struct platform_device *zoom_devices[] __initdata = {
-	&zoom_smsc911x_device,
 	&zoom_debugboard_serial_device,
 };
 
diff -druN linux-2.6.39-libre/arch/arm/mach-omap2/board-zoom-display.c linux-3.0-rc7-libre/arch/arm/mach-omap2/board-zoom-display.c
--- linux-2.6.39-libre/arch/arm/mach-omap2/board-zoom-display.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-omap2/board-zoom-display.c	2011-07-11 19:51:52.000000000 -0400
@@ -15,40 +15,25 @@
 #include <linux/i2c/twl.h>
 #include <linux/spi/spi.h>
 #include <plat/mcspi.h>
-#include <plat/display.h>
+#include <video/omapdss.h>
 
 #define LCD_PANEL_RESET_GPIO_PROD	96
 #define LCD_PANEL_RESET_GPIO_PILOT	55
 #define LCD_PANEL_QVGA_GPIO		56
 
-static void zoom_lcd_panel_init(void)
-{
-	int ret;
-	unsigned char lcd_panel_reset_gpio;
+static struct gpio zoom_lcd_gpios[] __initdata = {
+	{ -EINVAL,		GPIOF_OUT_INIT_HIGH, "lcd reset" },
+	{ LCD_PANEL_QVGA_GPIO,	GPIOF_OUT_INIT_HIGH, "lcd qvga"	 },
+};
 
-	lcd_panel_reset_gpio = (omap_rev() > OMAP3430_REV_ES3_0) ?
+static void __init zoom_lcd_panel_init(void)
+{
+	zoom_lcd_gpios[0].gpio = (omap_rev() > OMAP3430_REV_ES3_0) ?
 			LCD_PANEL_RESET_GPIO_PROD :
 			LCD_PANEL_RESET_GPIO_PILOT;
 
-	ret = gpio_request(lcd_panel_reset_gpio, "lcd reset");
-	if (ret) {
-		pr_err("Failed to get LCD reset GPIO (gpio%d).\n",
-			lcd_panel_reset_gpio);
-		return;
-	}
-	gpio_direction_output(lcd_panel_reset_gpio, 1);
-
-	ret = gpio_request(LCD_PANEL_QVGA_GPIO, "lcd qvga");
-	if (ret) {
-		pr_err("Failed to get LCD_PANEL_QVGA_GPIO (gpio%d).\n",
-			LCD_PANEL_QVGA_GPIO);
-		goto err0;
-	}
-	gpio_direction_output(LCD_PANEL_QVGA_GPIO, 1);
-
-	return;
-err0:
-	gpio_free(lcd_panel_reset_gpio);
+	if (gpio_request_array(zoom_lcd_gpios, ARRAY_SIZE(zoom_lcd_gpios)))
+		pr_err("%s: Failed to get LCD GPIOs.\n", __func__);
 }
 
 static int zoom_panel_enable_lcd(struct omap_dss_device *dssdev)
diff -druN linux-2.6.39-libre/arch/arm/mach-omap2/board-zoom-peripherals.c linux-3.0-rc7-libre/arch/arm/mach-omap2/board-zoom-peripherals.c
--- linux-2.6.39-libre/arch/arm/mach-omap2/board-zoom-peripherals.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-omap2/board-zoom-peripherals.c	2011-07-11 19:51:52.000000000 -0400
@@ -31,6 +31,7 @@
 
 #include "mux.h"
 #include "hsmmc.h"
+#include "common-board-devices.h"
 
 #define OMAP_ZOOM_WLAN_PMENA_GPIO	(101)
 #define OMAP_ZOOM_WLAN_IRQ_GPIO		(162)
@@ -276,13 +277,11 @@
 	zoom_vsim_supply.dev = mmc[0].dev;
 	zoom_vmmc2_supply.dev = mmc[1].dev;
 
-	ret = gpio_request(LCD_PANEL_ENABLE_GPIO, "lcd enable");
-	if (ret) {
+	ret = gpio_request_one(LCD_PANEL_ENABLE_GPIO, GPIOF_OUT_INIT_LOW,
+			       "lcd enable");
+	if (ret)
 		pr_err("Failed to get LCD_PANEL_ENABLE_GPIO (gpio%d).\n",
 				LCD_PANEL_ENABLE_GPIO);
-		return ret;
-	}
-	gpio_direction_output(LCD_PANEL_ENABLE_GPIO, 0);
 
 	return ret;
 }
@@ -349,15 +348,6 @@
 	.vdac		= &zoom_vdac,
 };
 
-static struct i2c_board_info __initdata zoom_i2c_boardinfo[] = {
-	{
-		I2C_BOARD_INFO("twl5030", 0x48),
-		.flags		= I2C_CLIENT_WAKE,
-		.irq		= INT_34XX_SYS_NIRQ,
-		.platform_data	= &zoom_twldata,
-	},
-};
-
 static int __init omap_i2c_init(void)
 {
 	if (machine_is_omap_zoom2()) {
@@ -365,19 +355,12 @@
 		zoom_audio_data.hs_extmute = 1;
 		zoom_audio_data.set_hs_extmute = zoom2_set_hs_extmute;
 	}
-	omap_register_i2c_bus(1, 2400, zoom_i2c_boardinfo,
-			ARRAY_SIZE(zoom_i2c_boardinfo));
+	omap_pmic_init(1, 2400, "twl5030", INT_34XX_SYS_NIRQ, &zoom_twldata);
 	omap_register_i2c_bus(2, 400, NULL, 0);
 	omap_register_i2c_bus(3, 400, NULL, 0);
 	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) */
@@ -392,7 +375,7 @@
 
 	omap_i2c_init();
 	platform_device_register(&omap_vwlan_device);
-	usb_musb_init(&musb_board_data);
+	usb_musb_init(NULL);
 	enable_board_wakeup_source();
 	omap_serial_init();
 }
diff -druN linux-2.6.39-libre/arch/arm/mach-omap2/common-board-devices.c linux-3.0-rc7-libre/arch/arm/mach-omap2/common-board-devices.c
--- linux-2.6.39-libre/arch/arm/mach-omap2/common-board-devices.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/arm/mach-omap2/common-board-devices.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,163 @@
+/*
+ * common-board-devices.c
+ *
+ * Copyright (C) 2011 CompuLab, Ltd.
+ * Author: Mike Rapoport <mike@compulab.co.il>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#include <linux/i2c.h>
+#include <linux/i2c/twl.h>
+
+#include <linux/gpio.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/ads7846.h>
+
+#include <plat/i2c.h>
+#include <plat/mcspi.h>
+#include <plat/nand.h>
+
+#include "common-board-devices.h"
+
+static struct i2c_board_info __initdata pmic_i2c_board_info = {
+	.addr		= 0x48,
+	.flags		= I2C_CLIENT_WAKE,
+};
+
+void __init omap_pmic_init(int bus, u32 clkrate,
+			   const char *pmic_type, int pmic_irq,
+			   struct twl4030_platform_data *pmic_data)
+{
+	strncpy(pmic_i2c_board_info.type, pmic_type,
+		sizeof(pmic_i2c_board_info.type));
+	pmic_i2c_board_info.irq = pmic_irq;
+	pmic_i2c_board_info.platform_data = pmic_data;
+
+	omap_register_i2c_bus(bus, clkrate, &pmic_i2c_board_info, 1);
+}
+
+#if defined(CONFIG_TOUCHSCREEN_ADS7846) || \
+	defined(CONFIG_TOUCHSCREEN_ADS7846_MODULE)
+static struct omap2_mcspi_device_config ads7846_mcspi_config = {
+	.turbo_mode	= 0,
+	.single_channel	= 1,	/* 0: slave, 1: master */
+};
+
+static struct ads7846_platform_data ads7846_config = {
+	.x_max			= 0x0fff,
+	.y_max			= 0x0fff,
+	.x_plate_ohms		= 180,
+	.pressure_max		= 255,
+	.debounce_max		= 10,
+	.debounce_tol		= 3,
+	.debounce_rep		= 1,
+	.gpio_pendown		= -EINVAL,
+	.keep_vref_on		= 1,
+};
+
+static struct spi_board_info ads7846_spi_board_info __initdata = {
+	.modalias		= "ads7846",
+	.bus_num		= -EINVAL,
+	.chip_select		= 0,
+	.max_speed_hz		= 1500000,
+	.controller_data	= &ads7846_mcspi_config,
+	.irq			= -EINVAL,
+	.platform_data		= &ads7846_config,
+};
+
+void __init omap_ads7846_init(int bus_num, int gpio_pendown, int gpio_debounce,
+			      struct ads7846_platform_data *board_pdata)
+{
+	struct spi_board_info *spi_bi = &ads7846_spi_board_info;
+	int err;
+
+	if (board_pdata && board_pdata->get_pendown_state) {
+		err = gpio_request_one(gpio_pendown, GPIOF_IN, "TSPenDown");
+		if (err) {
+			pr_err("Couldn't obtain gpio for TSPenDown: %d\n", err);
+			return;
+		}
+		gpio_export(gpio_pendown, 0);
+
+		if (gpio_debounce)
+			gpio_set_debounce(gpio_pendown, gpio_debounce);
+	}
+
+	ads7846_config.gpio_pendown = gpio_pendown;
+
+	spi_bi->bus_num	= bus_num;
+	spi_bi->irq	= OMAP_GPIO_IRQ(gpio_pendown);
+
+	if (board_pdata)
+		spi_bi->platform_data = board_pdata;
+
+	spi_register_board_info(&ads7846_spi_board_info, 1);
+}
+#else
+void __init omap_ads7846_init(int bus_num, int gpio_pendown, int gpio_debounce,
+			      struct ads7846_platform_data *board_pdata)
+{
+}
+#endif
+
+#if defined(CONFIG_MTD_NAND_OMAP2) || defined(CONFIG_MTD_NAND_OMAP2_MODULE)
+static struct omap_nand_platform_data nand_data = {
+	.dma_channel	= -1,		/* disable DMA in OMAP NAND driver */
+};
+
+void __init omap_nand_flash_init(int options, struct mtd_partition *parts,
+				 int nr_parts)
+{
+	u8 cs = 0;
+	u8 nandcs = GPMC_CS_NUM + 1;
+
+	/* 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) {
+		nand_data.cs = nandcs;
+		nand_data.parts = parts;
+		nand_data.nr_parts = nr_parts;
+		nand_data.options = options;
+
+		printk(KERN_INFO "Registering NAND on CS%d\n", nandcs);
+		if (gpmc_nand_init(&nand_data) < 0)
+			printk(KERN_ERR "Unable to register NAND device\n");
+	}
+}
+#else
+void __init omap_nand_flash_init(int options, struct mtd_partition *parts,
+				 int nr_parts)
+{
+}
+#endif
diff -druN linux-2.6.39-libre/arch/arm/mach-omap2/common-board-devices.h linux-3.0-rc7-libre/arch/arm/mach-omap2/common-board-devices.h
--- linux-2.6.39-libre/arch/arm/mach-omap2/common-board-devices.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/arm/mach-omap2/common-board-devices.h	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,37 @@
+#ifndef __OMAP_COMMON_BOARD_DEVICES__
+#define __OMAP_COMMON_BOARD_DEVICES__
+
+#define NAND_BLOCK_SIZE	SZ_128K
+
+struct twl4030_platform_data;
+struct mtd_partition;
+
+void omap_pmic_init(int bus, u32 clkrate, const char *pmic_type, int pmic_irq,
+		    struct twl4030_platform_data *pmic_data);
+
+static inline void omap2_pmic_init(const char *pmic_type,
+				   struct twl4030_platform_data *pmic_data)
+{
+	omap_pmic_init(2, 2600, pmic_type, INT_24XX_SYS_NIRQ, pmic_data);
+}
+
+static inline void omap3_pmic_init(const char *pmic_type,
+				   struct twl4030_platform_data *pmic_data)
+{
+	omap_pmic_init(1, 2600, pmic_type, INT_34XX_SYS_NIRQ, pmic_data);
+}
+
+static inline void omap4_pmic_init(const char *pmic_type,
+				   struct twl4030_platform_data *pmic_data)
+{
+	/* Phoenix Audio IC needs I2C1 to start with 400 KHz or less */
+	omap_pmic_init(1, 400, pmic_type, OMAP44XX_IRQ_SYS_1N, pmic_data);
+}
+
+struct ads7846_platform_data;
+
+void omap_ads7846_init(int bus_num, int gpio_pendown, int gpio_debounce,
+		       struct ads7846_platform_data *board_pdata);
+void omap_nand_flash_init(int opts, struct mtd_partition *parts, int n_parts);
+
+#endif /* __OMAP_COMMON_BOARD_DEVICES__ */
diff -druN linux-2.6.39-libre/arch/arm/mach-omap2/control.h linux-3.0-rc7-libre/arch/arm/mach-omap2/control.h
--- linux-2.6.39-libre/arch/arm/mach-omap2/control.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-omap2/control.h	2011-07-11 19:51:52.000000000 -0400
@@ -236,7 +236,7 @@
 #define OMAP343X_CONTROL_WKUP_DEBOBS3 (OMAP343X_CONTROL_GENERAL_WKUP + 0x014)
 #define OMAP343X_CONTROL_WKUP_DEBOBS4 (OMAP343X_CONTROL_GENERAL_WKUP + 0x018)
 
-/* 36xx-only RTA - Retention till Accesss control registers and bits */
+/* 36xx-only RTA - Retention till Access control registers and bits */
 #define OMAP36XX_CONTROL_MEM_RTA_CTRL	0x40C
 #define OMAP36XX_RTA_DISABLE		0x0
 
diff -druN linux-2.6.39-libre/arch/arm/mach-omap2/cpuidle34xx.c linux-3.0-rc7-libre/arch/arm/mach-omap2/cpuidle34xx.c
--- linux-2.6.39-libre/arch/arm/mach-omap2/cpuidle34xx.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-omap2/cpuidle34xx.c	2011-07-11 19:51:52.000000000 -0400
@@ -36,36 +36,6 @@
 
 #ifdef CONFIG_CPU_IDLE
 
-#define OMAP3_MAX_STATES 7
-#define OMAP3_STATE_C1 0 /* C1 - MPU WFI + Core active */
-#define OMAP3_STATE_C2 1 /* C2 - MPU WFI + Core inactive */
-#define OMAP3_STATE_C3 2 /* C3 - MPU CSWR + Core inactive */
-#define OMAP3_STATE_C4 3 /* C4 - MPU OFF + Core iactive */
-#define OMAP3_STATE_C5 4 /* C5 - MPU RET + Core RET */
-#define OMAP3_STATE_C6 5 /* C6 - MPU OFF + Core RET */
-#define OMAP3_STATE_C7 6 /* C7 - MPU OFF + Core OFF */
-
-#define OMAP3_STATE_MAX OMAP3_STATE_C7
-
-#define CPUIDLE_FLAG_CHECK_BM	0x10000	/* use omap3_enter_idle_bm() */
-
-struct omap3_processor_cx {
-	u8 valid;
-	u8 type;
-	u32 sleep_latency;
-	u32 wakeup_latency;
-	u32 mpu_state;
-	u32 core_state;
-	u32 threshold;
-	u32 flags;
-	const char *desc;
-};
-
-struct omap3_processor_cx omap3_power_states[OMAP3_MAX_STATES];
-struct omap3_processor_cx current_cx_state;
-struct powerdomain *mpu_pd, *core_pd, *per_pd;
-struct powerdomain *cam_pd;
-
 /*
  * The latencies/thresholds for various C states have
  * to be configured from the respective board files.
@@ -75,27 +45,31 @@
  */
 static struct cpuidle_params cpuidle_params_table[] = {
 	/* C1 */
-	{1, 2, 2, 5},
+	{2 + 2, 5, 1},
 	/* C2 */
-	{1, 10, 10, 30},
+	{10 + 10, 30, 1},
 	/* C3 */
-	{1, 50, 50, 300},
+	{50 + 50, 300, 1},
 	/* C4 */
-	{1, 1500, 1800, 4000},
+	{1500 + 1800, 4000, 1},
 	/* C5 */
-	{1, 2500, 7500, 12000},
+	{2500 + 7500, 12000, 1},
 	/* C6 */
-	{1, 3000, 8500, 15000},
+	{3000 + 8500, 15000, 1},
 	/* C7 */
-	{1, 10000, 30000, 300000},
+	{10000 + 30000, 300000, 1},
 };
+#define OMAP3_NUM_STATES ARRAY_SIZE(cpuidle_params_table)
 
-static int omap3_idle_bm_check(void)
-{
-	if (!omap3_can_sleep())
-		return 1;
-	return 0;
-}
+/* Mach specific information to be recorded in the C-state driver_data */
+struct omap3_idle_statedata {
+	u32 mpu_state;
+	u32 core_state;
+	u8 valid;
+};
+struct omap3_idle_statedata omap3_idle_data[OMAP3_NUM_STATES];
+
+struct powerdomain *mpu_pd, *core_pd, *per_pd, *cam_pd;
 
 static int _cpuidle_allow_idle(struct powerdomain *pwrdm,
 				struct clockdomain *clkdm)
@@ -122,12 +96,10 @@
 static int omap3_enter_idle(struct cpuidle_device *dev,
 			struct cpuidle_state *state)
 {
-	struct omap3_processor_cx *cx = cpuidle_get_statedata(state);
+	struct omap3_idle_statedata *cx = cpuidle_get_statedata(state);
 	struct timespec ts_preidle, ts_postidle, ts_idle;
 	u32 mpu_state = cx->mpu_state, core_state = cx->core_state;
 
-	current_cx_state = *cx;
-
 	/* Used to keep track of the total time in idle */
 	getnstimeofday(&ts_preidle);
 
@@ -140,7 +112,8 @@
 	if (omap_irq_pending() || need_resched())
 		goto return_sleep_time;
 
-	if (cx->type == OMAP3_STATE_C1) {
+	/* Deny idle for C1 */
+	if (state == &dev->states[0]) {
 		pwrdm_for_each_clkdm(mpu_pd, _cpuidle_deny_idle);
 		pwrdm_for_each_clkdm(core_pd, _cpuidle_deny_idle);
 	}
@@ -148,7 +121,8 @@
 	/* Execute ARM wfi */
 	omap_sram_idle();
 
-	if (cx->type == OMAP3_STATE_C1) {
+	/* Re-allow idle for C1 */
+	if (state == &dev->states[0]) {
 		pwrdm_for_each_clkdm(mpu_pd, _cpuidle_allow_idle);
 		pwrdm_for_each_clkdm(core_pd, _cpuidle_allow_idle);
 	}
@@ -164,41 +138,53 @@
 }
 
 /**
- * next_valid_state - Find next valid c-state
+ * next_valid_state - Find next valid C-state
  * @dev: cpuidle device
- * @state: Currently selected c-state
+ * @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[]).
+ * valid.
+ *
+ * A state is valid if the 'valid' field is enabled and
+ * if it satisfies the enable_off_mode condition.
  */
 static struct cpuidle_state *next_valid_state(struct cpuidle_device *dev,
-						struct cpuidle_state *curr)
+					      struct cpuidle_state *curr)
 {
 	struct cpuidle_state *next = NULL;
-	struct omap3_processor_cx *cx;
+	struct omap3_idle_statedata *cx = cpuidle_get_statedata(curr);
+	u32 mpu_deepest_state = PWRDM_POWER_RET;
+	u32 core_deepest_state = PWRDM_POWER_RET;
 
-	cx = (struct omap3_processor_cx *)cpuidle_get_statedata(curr);
+	if (enable_off_mode) {
+		mpu_deepest_state = PWRDM_POWER_OFF;
+		/*
+		 * Erratum i583: valable for ES rev < Es1.2 on 3630.
+		 * CORE OFF mode is not supported in a stable form, restrict
+		 * instead the CORE state to RET.
+		 */
+		if (!IS_PM34XX_ERRATUM(PM_SDRC_WAKEUP_ERRATUM_i583))
+			core_deepest_state = PWRDM_POWER_OFF;
+	}
 
 	/* Check if current state is valid */
-	if (cx->valid) {
+	if ((cx->valid) &&
+	    (cx->mpu_state >= mpu_deepest_state) &&
+	    (cx->core_state >= core_deepest_state)) {
 		return curr;
 	} else {
-		u8 idx = OMAP3_STATE_MAX;
+		int idx = OMAP3_NUM_STATES - 1;
 
-		/*
-		 * Reach the current state starting at highest C-state
-		 */
-		for (; idx >= OMAP3_STATE_C1; idx--) {
+		/* Reach the current state starting at highest C-state */
+		for (; idx >= 0; idx--) {
 			if (&dev->states[idx] == curr) {
 				next = &dev->states[idx];
 				break;
 			}
 		}
 
-		/*
-		 * Should never hit this condition.
-		 */
+		/* Should never hit this condition */
 		WARN_ON(next == NULL);
 
 		/*
@@ -206,17 +192,17 @@
 		 * Start search from the next (lower) state.
 		 */
 		idx--;
-		for (; idx >= OMAP3_STATE_C1; idx--) {
-			struct omap3_processor_cx *cx;
-
+		for (; idx >= 0; idx--) {
 			cx = cpuidle_get_statedata(&dev->states[idx]);
-			if (cx->valid) {
+			if ((cx->valid) &&
+			    (cx->mpu_state >= mpu_deepest_state) &&
+			    (cx->core_state >= core_deepest_state)) {
 				next = &dev->states[idx];
 				break;
 			}
 		}
 		/*
-		 * C1 and C2 are always valid.
+		 * C1 is always valid.
 		 * So, no need to check for 'next==NULL' outside this loop.
 		 */
 	}
@@ -229,36 +215,22 @@
  * @dev: cpuidle device
  * @state: The target state to be programmed
  *
- * Used for C states with CPUIDLE_FLAG_CHECK_BM flag set. This
- * function checks for any pending activity and then programs the
- * device to the specified or a safer state.
+ * This function checks for any pending activity and then programs
+ * the device to the specified or a safer state.
  */
 static int omap3_enter_idle_bm(struct cpuidle_device *dev,
 			       struct cpuidle_state *state)
 {
-	struct cpuidle_state *new_state = next_valid_state(dev, state);
-	u32 core_next_state, per_next_state = 0, per_saved_state = 0;
-	u32 cam_state;
-	struct omap3_processor_cx *cx;
+	struct cpuidle_state *new_state;
+	u32 core_next_state, per_next_state = 0, per_saved_state = 0, cam_state;
+	struct omap3_idle_statedata *cx;
 	int ret;
 
-	if ((state->flags & CPUIDLE_FLAG_CHECK_BM) && omap3_idle_bm_check()) {
-		BUG_ON(!dev->safe_state);
+	if (!omap3_can_sleep()) {
 		new_state = dev->safe_state;
 		goto select_state;
 	}
 
-	cx = cpuidle_get_statedata(state);
-	core_next_state = cx->core_state;
-
-	/*
-	 * FIXME: we currently manage device-specific idle states
-	 *        for PER and CORE in combination with CPU-specific
-	 *        idle states.  This is wrong, and device-specific
-	 *        idle management needs to be separated out into 
-	 *        its own code.
-	 */
-
 	/*
 	 * Prevent idle completely if CAM is active.
 	 * CAM does not have wakeup capability in OMAP3.
@@ -270,9 +242,19 @@
 	}
 
 	/*
+	 * FIXME: we currently manage device-specific idle states
+	 *        for PER and CORE in combination with CPU-specific
+	 *        idle states.  This is wrong, and device-specific
+	 *        idle management needs to be separated out into
+	 *        its own code.
+	 */
+
+	/*
 	 * Prevent PER off if CORE is not in retention or off as this
 	 * would disable PER wakeups completely.
 	 */
+	cx = cpuidle_get_statedata(state);
+	core_next_state = cx->core_state;
 	per_next_state = per_saved_state = pwrdm_read_next_pwrst(per_pd);
 	if ((per_next_state == PWRDM_POWER_OFF) &&
 	    (core_next_state > PWRDM_POWER_RET))
@@ -282,6 +264,8 @@
 	if (per_next_state != per_saved_state)
 		pwrdm_set_next_pwrst(per_pd, per_next_state);
 
+	new_state = next_valid_state(dev, state);
+
 select_state:
 	dev->last_state = new_state;
 	ret = omap3_enter_idle(dev, new_state);
@@ -295,31 +279,6 @@
 
 DEFINE_PER_CPU(struct cpuidle_device, omap3_idle_dev);
 
-/**
- * omap3_cpuidle_update_states() - Update the cpuidle states
- * @mpu_deepest_state:	Enable states up to and including this for mpu domain
- * @core_deepest_state:	Enable states up to and including this for core domain
- *
- * This goes through the list of states available and enables and disables the
- * validity of C states based on deepest state that can be achieved for the
- * variable domain
- */
-void omap3_cpuidle_update_states(u32 mpu_deepest_state, u32 core_deepest_state)
-{
-	int i;
-
-	for (i = OMAP3_STATE_C1; i < OMAP3_MAX_STATES; i++) {
-		struct omap3_processor_cx *cx = &omap3_power_states[i];
-
-		if ((cx->mpu_state >= mpu_deepest_state) &&
-		    (cx->core_state >= core_deepest_state)) {
-			cx->valid = 1;
-		} else {
-			cx->valid = 0;
-		}
-	}
-}
-
 void omap3_pm_init_cpuidle(struct cpuidle_params *cpuidle_board_params)
 {
 	int i;
@@ -327,212 +286,109 @@
 	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;
+	for (i = 0; i < OMAP3_NUM_STATES; i++) {
+		cpuidle_params_table[i].valid =	cpuidle_board_params[i].valid;
+		cpuidle_params_table[i].exit_latency =
+			cpuidle_board_params[i].exit_latency;
+		cpuidle_params_table[i].target_residency =
+			cpuidle_board_params[i].target_residency;
 	}
 	return;
 }
 
-/* omap3_init_power_states - Initialises the OMAP3 specific C states.
- *
- * Below is the desciption of each C state.
- * 	C1 . MPU WFI + Core active
- *	C2 . MPU WFI + Core inactive
- *	C3 . MPU CSWR + Core inactive
- *	C4 . MPU OFF + Core inactive
- *	C5 . MPU CSWR + Core CSWR
- *	C6 . MPU OFF + Core CSWR
- *	C7 . MPU OFF + Core OFF
- */
-void omap_init_power_states(void)
-{
-	/* C1 . MPU WFI + Core active */
-	omap3_power_states[OMAP3_STATE_C1].valid =
-			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 =
-			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;
-	omap3_power_states[OMAP3_STATE_C1].desc = "MPU ON + CORE ON";
-
-	/* C2 . MPU WFI + Core inactive */
-	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 =
-			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 |
-				CPUIDLE_FLAG_CHECK_BM;
-	omap3_power_states[OMAP3_STATE_C2].desc = "MPU ON + CORE ON";
-
-	/* C3 . MPU CSWR + Core inactive */
-	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 =
-			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;
-	omap3_power_states[OMAP3_STATE_C3].desc = "MPU RET + CORE ON";
-
-	/* C4 . MPU OFF + Core inactive */
-	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 =
-			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;
-	omap3_power_states[OMAP3_STATE_C4].desc = "MPU OFF + CORE ON";
-
-	/* C5 . MPU CSWR + Core CSWR*/
-	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 =
-			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;
-	omap3_power_states[OMAP3_STATE_C5].desc = "MPU RET + CORE RET";
-
-	/* C6 . MPU OFF + Core CSWR */
-	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 =
-			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;
-	omap3_power_states[OMAP3_STATE_C6].desc = "MPU OFF + CORE RET";
-
-	/* C7 . MPU OFF + Core OFF */
-	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 =
-			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 |
-				CPUIDLE_FLAG_CHECK_BM;
-	omap3_power_states[OMAP3_STATE_C7].desc = "MPU OFF + CORE OFF";
-
-	/*
-	 * Erratum i583: implementation for ES rev < Es1.2 on 3630. We cannot
-	 * enable OFF mode in a stable form for previous revisions.
-	 * we disable C7 state as a result.
-	 */
-	if (IS_PM34XX_ERRATUM(PM_SDRC_WAKEUP_ERRATUM_i583)) {
-		omap3_power_states[OMAP3_STATE_C7].valid = 0;
-		cpuidle_params_table[OMAP3_STATE_C7].valid = 0;
-		pr_warn("%s: core off state C7 disabled due to i583\n",
-				__func__);
-	}
-}
-
 struct cpuidle_driver omap3_idle_driver = {
 	.name = 	"omap3_idle",
 	.owner = 	THIS_MODULE,
 };
 
+/* Helper to fill the C-state common data and register the driver_data */
+static inline struct omap3_idle_statedata *_fill_cstate(
+					struct cpuidle_device *dev,
+					int idx, const char *descr)
+{
+	struct omap3_idle_statedata *cx = &omap3_idle_data[idx];
+	struct cpuidle_state *state = &dev->states[idx];
+
+	state->exit_latency	= cpuidle_params_table[idx].exit_latency;
+	state->target_residency	= cpuidle_params_table[idx].target_residency;
+	state->flags		= CPUIDLE_FLAG_TIME_VALID;
+	state->enter		= omap3_enter_idle_bm;
+	cx->valid		= cpuidle_params_table[idx].valid;
+	sprintf(state->name, "C%d", idx + 1);
+	strncpy(state->desc, descr, CPUIDLE_DESC_LEN);
+	cpuidle_set_statedata(state, cx);
+
+	return cx;
+}
+
 /**
  * omap3_idle_init - Init routine for OMAP3 idle
  *
- * Registers the OMAP3 specific cpuidle driver with the cpuidle
+ * Registers the OMAP3 specific cpuidle driver to the cpuidle
  * framework with the valid set of states.
  */
 int __init omap3_idle_init(void)
 {
-	int i, count = 0;
-	struct omap3_processor_cx *cx;
-	struct cpuidle_state *state;
 	struct cpuidle_device *dev;
+	struct omap3_idle_statedata *cx;
 
 	mpu_pd = pwrdm_lookup("mpu_pwrdm");
 	core_pd = pwrdm_lookup("core_pwrdm");
 	per_pd = pwrdm_lookup("per_pwrdm");
 	cam_pd = pwrdm_lookup("cam_pwrdm");
 
-	omap_init_power_states();
 	cpuidle_register_driver(&omap3_idle_driver);
-
 	dev = &per_cpu(omap3_idle_dev, smp_processor_id());
 
-	for (i = OMAP3_STATE_C1; i < OMAP3_MAX_STATES; i++) {
-		cx = &omap3_power_states[i];
-		state = &dev->states[count];
+	/* C1 . MPU WFI + Core active */
+	cx = _fill_cstate(dev, 0, "MPU ON + CORE ON");
+	(&dev->states[0])->enter = omap3_enter_idle;
+	dev->safe_state = &dev->states[0];
+	cx->valid = 1;	/* C1 is always valid */
+	cx->mpu_state = PWRDM_POWER_ON;
+	cx->core_state = PWRDM_POWER_ON;
 
-		if (!cx->valid)
-			continue;
-		cpuidle_set_statedata(state, cx);
-		state->exit_latency = cx->sleep_latency + cx->wakeup_latency;
-		state->target_residency = cx->threshold;
-		state->flags = cx->flags;
-		state->enter = (state->flags & CPUIDLE_FLAG_CHECK_BM) ?
-			omap3_enter_idle_bm : omap3_enter_idle;
-		if (cx->type == OMAP3_STATE_C1)
-			dev->safe_state = state;
-		sprintf(state->name, "C%d", count+1);
-		strncpy(state->desc, cx->desc, CPUIDLE_DESC_LEN);
-		count++;
-	}
+	/* C2 . MPU WFI + Core inactive */
+	cx = _fill_cstate(dev, 1, "MPU ON + CORE ON");
+	cx->mpu_state = PWRDM_POWER_ON;
+	cx->core_state = PWRDM_POWER_ON;
 
-	if (!count)
-		return -EINVAL;
-	dev->state_count = count;
+	/* C3 . MPU CSWR + Core inactive */
+	cx = _fill_cstate(dev, 2, "MPU RET + CORE ON");
+	cx->mpu_state = PWRDM_POWER_RET;
+	cx->core_state = PWRDM_POWER_ON;
 
-	if (enable_off_mode)
-		omap3_cpuidle_update_states(PWRDM_POWER_OFF, PWRDM_POWER_OFF);
-	else
-		omap3_cpuidle_update_states(PWRDM_POWER_RET, PWRDM_POWER_RET);
+	/* C4 . MPU OFF + Core inactive */
+	cx = _fill_cstate(dev, 3, "MPU OFF + CORE ON");
+	cx->mpu_state = PWRDM_POWER_OFF;
+	cx->core_state = PWRDM_POWER_ON;
+
+	/* C5 . MPU RET + Core RET */
+	cx = _fill_cstate(dev, 4, "MPU RET + CORE RET");
+	cx->mpu_state = PWRDM_POWER_RET;
+	cx->core_state = PWRDM_POWER_RET;
+
+	/* C6 . MPU OFF + Core RET */
+	cx = _fill_cstate(dev, 5, "MPU OFF + CORE RET");
+	cx->mpu_state = PWRDM_POWER_OFF;
+	cx->core_state = PWRDM_POWER_RET;
 
+	/* C7 . MPU OFF + Core OFF */
+	cx = _fill_cstate(dev, 6, "MPU OFF + CORE OFF");
+	/*
+	 * Erratum i583: implementation for ES rev < Es1.2 on 3630. We cannot
+	 * enable OFF mode in a stable form for previous revisions.
+	 * We disable C7 state as a result.
+	 */
+	if (IS_PM34XX_ERRATUM(PM_SDRC_WAKEUP_ERRATUM_i583)) {
+		cx->valid = 0;
+		pr_warn("%s: core off state C7 disabled due to i583\n",
+			__func__);
+	}
+	cx->mpu_state = PWRDM_POWER_OFF;
+	cx->core_state = PWRDM_POWER_OFF;
+
+	dev->state_count = OMAP3_NUM_STATES;
 	if (cpuidle_register_device(dev)) {
 		printk(KERN_ERR "%s: CPUidle register device failed\n",
 		       __func__);
diff -druN linux-2.6.39-libre/arch/arm/mach-omap2/devices.c linux-3.0-rc7-libre/arch/arm/mach-omap2/devices.c
--- linux-2.6.39-libre/arch/arm/mach-omap2/devices.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-omap2/devices.c	2011-07-11 19:51:52.000000000 -0400
@@ -97,7 +97,7 @@
 
 	WARN(IS_ERR(od), "could not build omap_device for %s\n", oh_name);
 
-	return PTR_ERR(od);
+	return IS_ERR(od) ? PTR_ERR(od) : 0;
 }
 postcore_initcall(omap4_l3_init);
 
diff -druN linux-2.6.39-libre/arch/arm/mach-omap2/display.c linux-3.0-rc7-libre/arch/arm/mach-omap2/display.c
--- linux-2.6.39-libre/arch/arm/mach-omap2/display.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-omap2/display.c	2011-07-11 19:51:52.000000000 -0400
@@ -22,7 +22,7 @@
 #include <linux/clk.h>
 #include <linux/err.h>
 
-#include <plat/display.h>
+#include <video/omapdss.h>
 #include <plat/omap_hwmod.h>
 #include <plat/omap_device.h>
 
@@ -56,37 +56,58 @@
 	return false;
 }
 
+struct omap_dss_hwmod_data {
+	const char *oh_name;
+	const char *dev_name;
+	const int id;
+};
+
+static const struct omap_dss_hwmod_data omap2_dss_hwmod_data[] __initdata = {
+	{ "dss_core", "omapdss_dss", -1 },
+	{ "dss_dispc", "omapdss_dispc", -1 },
+	{ "dss_rfbi", "omapdss_rfbi", -1 },
+	{ "dss_venc", "omapdss_venc", -1 },
+};
+
+static const struct omap_dss_hwmod_data omap3_dss_hwmod_data[] __initdata = {
+	{ "dss_core", "omapdss_dss", -1 },
+	{ "dss_dispc", "omapdss_dispc", -1 },
+	{ "dss_rfbi", "omapdss_rfbi", -1 },
+	{ "dss_venc", "omapdss_venc", -1 },
+	{ "dss_dsi1", "omapdss_dsi1", -1 },
+};
+
+static const struct omap_dss_hwmod_data omap4_dss_hwmod_data[] __initdata = {
+	{ "dss_core", "omapdss_dss", -1 },
+	{ "dss_dispc", "omapdss_dispc", -1 },
+	{ "dss_rfbi", "omapdss_rfbi", -1 },
+	{ "dss_venc", "omapdss_venc", -1 },
+	{ "dss_dsi1", "omapdss_dsi1", -1 },
+	{ "dss_dsi2", "omapdss_dsi2", -1 },
+	{ "dss_hdmi", "omapdss_hdmi", -1 },
+};
+
 int __init omap_display_init(struct omap_dss_board_info *board_data)
 {
 	int r = 0;
 	struct omap_hwmod *oh;
 	struct omap_device *od;
-	int i;
+	int i, oh_count;
 	struct omap_display_platform_data pdata;
-
-	/*
-	 * omap: valid DSS hwmod names
-	 * omap2,3,4: dss_core, dss_dispc, dss_rfbi, dss_venc
-	 * omap3,4: dss_dsi1
-	 * omap4: dss_dsi2, dss_hdmi
-	 */
-	char *oh_name[] = { "dss_core", "dss_dispc", "dss_rfbi", "dss_venc",
-		"dss_dsi1", "dss_dsi2", "dss_hdmi" };
-	char *dev_name[] = { "omapdss_dss", "omapdss_dispc", "omapdss_rfbi",
-		"omapdss_venc", "omapdss_dsi1", "omapdss_dsi2",
-		"omapdss_hdmi" };
-	int oh_count;
+	const struct omap_dss_hwmod_data *curr_dss_hwmod;
 
 	memset(&pdata, 0, sizeof(pdata));
 
-	if (cpu_is_omap24xx())
-		oh_count = ARRAY_SIZE(oh_name) - 3;
-		/* last 3 hwmod dev in oh_name are not available for omap2 */
-	else if (cpu_is_omap44xx())
-		oh_count = ARRAY_SIZE(oh_name);
-	else
-		oh_count = ARRAY_SIZE(oh_name) - 2;
-		/* last 2 hwmod dev in oh_name are not available for omap3 */
+	if (cpu_is_omap24xx()) {
+		curr_dss_hwmod = omap2_dss_hwmod_data;
+		oh_count = ARRAY_SIZE(omap2_dss_hwmod_data);
+	} else if (cpu_is_omap34xx()) {
+		curr_dss_hwmod = omap3_dss_hwmod_data;
+		oh_count = ARRAY_SIZE(omap3_dss_hwmod_data);
+	} else {
+		curr_dss_hwmod = omap4_dss_hwmod_data;
+		oh_count = ARRAY_SIZE(omap4_dss_hwmod_data);
+	}
 
 	/* opt_clks are always associated with dss hwmod */
 	oh_core = omap_hwmod_lookup("dss_core");
@@ -100,19 +121,21 @@
 	pdata.opt_clock_available = opt_clock_available;
 
 	for (i = 0; i < oh_count; i++) {
-		oh = omap_hwmod_lookup(oh_name[i]);
+		oh = omap_hwmod_lookup(curr_dss_hwmod[i].oh_name);
 		if (!oh) {
-			pr_err("Could not look up %s\n", oh_name[i]);
+			pr_err("Could not look up %s\n",
+				curr_dss_hwmod[i].oh_name);
 			return -ENODEV;
 		}
 
-		od = omap_device_build(dev_name[i], -1, oh, &pdata,
+		od = omap_device_build(curr_dss_hwmod[i].dev_name,
+				curr_dss_hwmod[i].id, oh, &pdata,
 				sizeof(struct omap_display_platform_data),
 				omap_dss_latency,
 				ARRAY_SIZE(omap_dss_latency), 0);
 
 		if (WARN((IS_ERR(od)), "Could not build omap_device for %s\n",
-				oh_name[i]))
+				curr_dss_hwmod[i].oh_name))
 			return -ENODEV;
 	}
 	omap_display_device.dev.platform_data = board_data;
diff -druN linux-2.6.39-libre/arch/arm/mach-omap2/gpmc-smc91x.c linux-3.0-rc7-libre/arch/arm/mach-omap2/gpmc-smc91x.c
--- linux-2.6.39-libre/arch/arm/mach-omap2/gpmc-smc91x.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-omap2/gpmc-smc91x.c	2011-07-11 19:51:52.000000000 -0400
@@ -147,25 +147,24 @@
 			goto free1;
 	}
 
-	if (gpio_request(gpmc_cfg->gpio_irq, "SMC91X irq") < 0)
+	if (gpio_request_one(gpmc_cfg->gpio_irq, GPIOF_IN, "SMC91X irq") < 0)
 		goto free1;
 
-	gpio_direction_input(gpmc_cfg->gpio_irq);
 	gpmc_smc91x_resources[1].start = gpio_to_irq(gpmc_cfg->gpio_irq);
 
 	if (gpmc_cfg->gpio_pwrdwn) {
-		ret = gpio_request(gpmc_cfg->gpio_pwrdwn, "SMC91X powerdown");
+		ret = gpio_request_one(gpmc_cfg->gpio_pwrdwn,
+				       GPIOF_OUT_INIT_LOW, "SMC91X powerdown");
 		if (ret)
 			goto free2;
-		gpio_direction_output(gpmc_cfg->gpio_pwrdwn, 0);
 	}
 
 	if (gpmc_cfg->gpio_reset) {
-		ret = gpio_request(gpmc_cfg->gpio_reset, "SMC91X reset");
+		ret = gpio_request_one(gpmc_cfg->gpio_reset,
+				       GPIOF_OUT_INIT_LOW, "SMC91X reset");
 		if (ret)
 			goto free3;
 
-		gpio_direction_output(gpmc_cfg->gpio_reset, 0);
 		gpio_set_value(gpmc_cfg->gpio_reset, 1);
 		msleep(100);
 		gpio_set_value(gpmc_cfg->gpio_reset, 0);
diff -druN linux-2.6.39-libre/arch/arm/mach-omap2/gpmc-smsc911x.c linux-3.0-rc7-libre/arch/arm/mach-omap2/gpmc-smsc911x.c
--- linux-2.6.39-libre/arch/arm/mach-omap2/gpmc-smsc911x.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-omap2/gpmc-smsc911x.c	2011-07-11 19:51:52.000000000 -0400
@@ -10,6 +10,7 @@
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  */
+#define pr_fmt(fmt) "%s: " fmt, __func__
 
 #include <linux/kernel.h>
 #include <linux/platform_device.h>
@@ -30,7 +31,7 @@
 		.flags		= IORESOURCE_MEM,
 	},
 	[1] = {
-		.flags		= IORESOURCE_IRQ,
+		.flags		= IORESOURCE_IRQ | IORESOURCE_IRQ_LOWLEVEL,
 	},
 };
 
@@ -41,16 +42,6 @@
 	.flags		= SMSC911X_USE_16BIT,
 };
 
-static struct platform_device gpmc_smsc911x_device = {
-	.name		= "smsc911x",
-	.id		= -1,
-	.num_resources	= ARRAY_SIZE(gpmc_smsc911x_resources),
-	.resource	= gpmc_smsc911x_resources,
-	.dev		= {
-		.platform_data = &gpmc_smsc911x_config,
-	},
-};
-
 /*
  * Initialize smsc911x device connected to the GPMC. Note that we
  * assume that pin multiplexing is done in the board-*.c file,
@@ -58,46 +49,49 @@
  */
 void __init gpmc_smsc911x_init(struct omap_smsc911x_platform_data *board_data)
 {
+	struct platform_device *pdev;
 	unsigned long cs_mem_base;
 	int ret;
 
 	gpmc_cfg = board_data;
 
 	if (gpmc_cs_request(gpmc_cfg->cs, SZ_16M, &cs_mem_base) < 0) {
-		printk(KERN_ERR "Failed to request GPMC mem for smsc911x\n");
+		pr_err("Failed to request GPMC mem region\n");
 		return;
 	}
 
 	gpmc_smsc911x_resources[0].start = cs_mem_base + 0x0;
 	gpmc_smsc911x_resources[0].end = cs_mem_base + 0xff;
 
-	if (gpio_request(gpmc_cfg->gpio_irq, "smsc911x irq") < 0) {
-		printk(KERN_ERR "Failed to request GPIO%d for smsc911x IRQ\n",
-				gpmc_cfg->gpio_irq);
+	if (gpio_request_one(gpmc_cfg->gpio_irq, GPIOF_IN, "smsc911x irq")) {
+		pr_err("Failed to request IRQ GPIO%d\n", gpmc_cfg->gpio_irq);
 		goto free1;
 	}
 
-	gpio_direction_input(gpmc_cfg->gpio_irq);
 	gpmc_smsc911x_resources[1].start = gpio_to_irq(gpmc_cfg->gpio_irq);
-	gpmc_smsc911x_resources[1].flags |=
-					(gpmc_cfg->flags & IRQF_TRIGGER_MASK);
 
 	if (gpio_is_valid(gpmc_cfg->gpio_reset)) {
-		ret = gpio_request(gpmc_cfg->gpio_reset, "smsc911x reset");
+		ret = gpio_request_one(gpmc_cfg->gpio_reset,
+				       GPIOF_OUT_INIT_HIGH, "smsc911x reset");
 		if (ret) {
-			printk(KERN_ERR "Failed to request GPIO%d for smsc911x reset\n",
-					gpmc_cfg->gpio_reset);
+			pr_err("Failed to request reset GPIO%d\n",
+			       gpmc_cfg->gpio_reset);
 			goto free2;
 		}
 
-		gpio_direction_output(gpmc_cfg->gpio_reset, 1);
 		gpio_set_value(gpmc_cfg->gpio_reset, 0);
 		msleep(100);
 		gpio_set_value(gpmc_cfg->gpio_reset, 1);
 	}
 
-	if (platform_device_register(&gpmc_smsc911x_device) < 0) {
-		printk(KERN_ERR "Unable to register smsc911x device\n");
+	if (gpmc_cfg->flags)
+		gpmc_smsc911x_config.flags = gpmc_cfg->flags;
+
+	pdev = platform_device_register_resndata(NULL, "smsc911x", gpmc_cfg->id,
+		 gpmc_smsc911x_resources, ARRAY_SIZE(gpmc_smsc911x_resources),
+		 &gpmc_smsc911x_config, sizeof(gpmc_smsc911x_config));
+	if (!pdev) {
+		pr_err("Unable to register platform device\n");
 		gpio_free(gpmc_cfg->gpio_reset);
 		goto free2;
 	}
@@ -109,5 +103,5 @@
 free1:
 	gpmc_cs_free(gpmc_cfg->cs);
 
-	printk(KERN_ERR "Could not initialize smsc911x\n");
+	pr_err("Could not initialize smsc911x device\n");
 }
diff -druN linux-2.6.39-libre/arch/arm/mach-omap2/hsmmc.c linux-3.0-rc7-libre/arch/arm/mach-omap2/hsmmc.c
--- linux-2.6.39-libre/arch/arm/mach-omap2/hsmmc.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-omap2/hsmmc.c	2011-07-11 19:51:52.000000000 -0400
@@ -145,6 +145,7 @@
 				 int power_on, int vdd)
 {
 	u32 reg;
+	unsigned long timeout;
 
 	if (power_on) {
 		reg = omap4_ctrl_pad_readl(control_pbias_offset);
@@ -157,9 +158,15 @@
 			OMAP4_MMC1_PWRDNZ_MASK |
 			OMAP4_USBC1_ICUSB_PWRDNZ_MASK);
 		omap4_ctrl_pad_writel(reg, control_pbias_offset);
-		/* 4 microsec delay for comparator to generate an error*/
-		udelay(4);
-		reg = omap4_ctrl_pad_readl(control_pbias_offset);
+
+		timeout = jiffies + msecs_to_jiffies(5);
+		do {
+			reg = omap4_ctrl_pad_readl(control_pbias_offset);
+			if (!(reg & OMAP4_MMC1_PBIASLITE_VMODE_ERROR_MASK))
+				break;
+			usleep_range(100, 200);
+		} while (!time_after(jiffies, timeout));
+
 		if (reg & OMAP4_MMC1_PBIASLITE_VMODE_ERROR_MASK) {
 			pr_err("Pbias Voltage is not same as LDO\n");
 			/* Caution : On VMODE_ERROR Power Down MMC IO */
@@ -331,6 +338,9 @@
 	if (c->no_off)
 		mmc->slots[0].no_off = 1;
 
+	if (c->no_off_init)
+		mmc->slots[0].no_regulator_off_init = c->no_off_init;
+
 	if (c->vcc_aux_disable_is_sleep)
 		mmc->slots[0].vcc_aux_disable_is_sleep = 1;
 
diff -druN linux-2.6.39-libre/arch/arm/mach-omap2/hsmmc.h linux-3.0-rc7-libre/arch/arm/mach-omap2/hsmmc.h
--- linux-2.6.39-libre/arch/arm/mach-omap2/hsmmc.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-omap2/hsmmc.h	2011-07-11 19:51:52.000000000 -0400
@@ -18,6 +18,7 @@
 	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	no_off_init;	/* no power off when not in MMC sleep state */
 	bool	vcc_aux_disable_is_sleep; /* Regulator off remapped to sleep */
 	int	gpio_cd;	/* or -EINVAL */
 	int	gpio_wp;	/* or -EINVAL */
diff -druN linux-2.6.39-libre/arch/arm/mach-omap2/include/mach/board-zoom.h linux-3.0-rc7-libre/arch/arm/mach-omap2/include/mach/board-zoom.h
--- linux-2.6.39-libre/arch/arm/mach-omap2/include/mach/board-zoom.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-omap2/include/mach/board-zoom.h	2011-07-11 19:51:52.000000000 -0400
@@ -1,7 +1,7 @@
 /*
  * Defines for zoom boards
  */
-#include <plat/display.h>
+#include <video/omapdss.h>
 
 #define ZOOM_NAND_CS    0
 
diff -druN linux-2.6.39-libre/arch/arm/mach-omap2/include/mach/omap4-common.h linux-3.0-rc7-libre/arch/arm/mach-omap2/include/mach/omap4-common.h
--- linux-2.6.39-libre/arch/arm/mach-omap2/include/mach/omap4-common.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-omap2/include/mach/omap4-common.h	2011-07-11 19:51:52.000000000 -0400
@@ -33,4 +33,11 @@
 extern void __init gic_init_irq(void);
 extern void omap_smc1(u32 fn, u32 arg);
 
+#ifdef CONFIG_SMP
+/* Needed for secondary core boot */
+extern void omap_secondary_startup(void);
+extern u32 omap_modify_auxcoreboot0(u32 set_mask, u32 clear_mask);
+extern void omap_auxcoreboot_addr(u32 cpu_addr);
+extern u32 omap_read_auxcoreboot0(void);
+#endif
 #endif
diff -druN linux-2.6.39-libre/arch/arm/mach-omap2/irq.c linux-3.0-rc7-libre/arch/arm/mach-omap2/irq.c
--- linux-2.6.39-libre/arch/arm/mach-omap2/irq.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-omap2/irq.c	2011-07-11 19:51:52.000000000 -0400
@@ -73,83 +73,18 @@
 	return __raw_readl(bank->base_reg + reg);
 }
 
-static int previous_irq;
-
-/*
- * On 34xx we can get occasional spurious interrupts if the ack from
- * an interrupt handler does not get posted before we unmask. Warn about
- * the interrupt handlers that need to flush posted writes.
- */
-static int omap_check_spurious(unsigned int irq)
-{
-	u32 sir, spurious;
-
-	sir = intc_bank_read_reg(&irq_banks[0], INTC_SIR);
-	spurious = sir >> 7;
-
-	if (spurious) {
-		printk(KERN_WARNING "Spurious irq %i: 0x%08x, please flush "
-					"posted write for irq %i\n",
-					irq, sir, previous_irq);
-		return spurious;
-	}
-
-	return 0;
-}
-
 /* XXX: FIQ and additional INTC support (only MPU at the moment) */
 static void omap_ack_irq(struct irq_data *d)
 {
 	intc_bank_write_reg(0x1, &irq_banks[0], INTC_CONTROL);
 }
 
-static void omap_mask_irq(struct irq_data *d)
-{
-	unsigned int irq = d->irq;
-	int offset = irq & (~(IRQ_BITS_PER_REG - 1));
-
-	if (cpu_is_omap34xx() && !cpu_is_ti816x()) {
-		int spurious = 0;
-
-		/*
-		 * INT_34XX_GPT12_IRQ is also the spurious irq. Maybe because
-		 * it is the highest irq number?
-		 */
-		if (irq == INT_34XX_GPT12_IRQ)
-			spurious = omap_check_spurious(irq);
-
-		if (!spurious)
-			previous_irq = irq;
-	}
-
-	irq &= (IRQ_BITS_PER_REG - 1);
-
-	intc_bank_write_reg(1 << irq, &irq_banks[0], INTC_MIR_SET0 + offset);
-}
-
-static void omap_unmask_irq(struct irq_data *d)
-{
-	unsigned int irq = d->irq;
-	int offset = irq & (~(IRQ_BITS_PER_REG - 1));
-
-	irq &= (IRQ_BITS_PER_REG - 1);
-
-	intc_bank_write_reg(1 << irq, &irq_banks[0], INTC_MIR_CLEAR0 + offset);
-}
-
 static void omap_mask_ack_irq(struct irq_data *d)
 {
-	omap_mask_irq(d);
+	irq_gc_mask_disable_reg(d);
 	omap_ack_irq(d);
 }
 
-static struct irq_chip omap_irq_chip = {
-	.name		= "INTC",
-	.irq_ack	= omap_mask_ack_irq,
-	.irq_mask	= omap_mask_irq,
-	.irq_unmask	= omap_unmask_irq,
-};
-
 static void __init omap_irq_bank_init_one(struct omap_irq_bank *bank)
 {
 	unsigned long tmp;
@@ -186,11 +121,31 @@
 	return 0;
 }
 
+static __init void
+omap_alloc_gc(void __iomem *base, unsigned int irq_start, unsigned int num)
+{
+	struct irq_chip_generic *gc;
+	struct irq_chip_type *ct;
+
+	gc = irq_alloc_generic_chip("INTC", 1, irq_start, base,
+					handle_level_irq);
+	ct = gc->chip_types;
+	ct->chip.irq_ack = omap_mask_ack_irq;
+	ct->chip.irq_mask = irq_gc_mask_disable_reg;
+	ct->chip.irq_unmask = irq_gc_unmask_enable_reg;
+
+	ct->regs.ack = INTC_CONTROL;
+	ct->regs.enable = INTC_MIR_CLEAR0;
+	ct->regs.disable = INTC_MIR_SET0;
+	irq_setup_generic_chip(gc, IRQ_MSK(num), IRQ_GC_INIT_MASK_CACHE,
+				IRQ_NOREQUEST | IRQ_NOPROBE, 0);
+}
+
 void __init omap_init_irq(void)
 {
 	unsigned long nr_of_irqs = 0;
 	unsigned int nr_banks = 0;
-	int i;
+	int i, j;
 
 	for (i = 0; i < ARRAY_SIZE(irq_banks); i++) {
 		unsigned long base = 0;
@@ -215,17 +170,15 @@
 
 		omap_irq_bank_init_one(bank);
 
+		for (i = 0, j = 0; i < bank->nr_irqs; i += 32, j += 0x20)
+			omap_alloc_gc(bank->base_reg + j, i, 32);
+
 		nr_of_irqs += bank->nr_irqs;
 		nr_banks++;
 	}
 
 	printk(KERN_INFO "Total of %ld interrupts on %d active controller%s\n",
 	       nr_of_irqs, nr_banks, nr_banks > 1 ? "s" : "");
-
-	for (i = 0; i < nr_of_irqs; i++) {
-		irq_set_chip_and_handler(i, &omap_irq_chip, handle_level_irq);
-		set_irq_flags(i, IRQF_VALID);
-	}
 }
 
 #ifdef CONFIG_ARCH_OMAP3
diff -druN linux-2.6.39-libre/arch/arm/mach-omap2/Kconfig linux-3.0-rc7-libre/arch/arm/mach-omap2/Kconfig
--- linux-2.6.39-libre/arch/arm/mach-omap2/Kconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-omap2/Kconfig	2011-07-11 19:51:52.000000000 -0400
@@ -288,6 +288,7 @@
 	depends on ARCH_OMAP3
 	default y
 	select OMAP_PACKAGE_CBB
+	select MACH_IGEP0020
 
 config MACH_SBC3530
 	bool "OMAP3 SBC STALKER board"
diff -druN linux-2.6.39-libre/arch/arm/mach-omap2/Makefile linux-3.0-rc7-libre/arch/arm/mach-omap2/Makefile
--- linux-2.6.39-libre/arch/arm/mach-omap2/Makefile	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-omap2/Makefile	2011-07-11 19:51:52.000000000 -0400
@@ -59,10 +59,10 @@
 # Power Management
 ifeq ($(CONFIG_PM),y)
 obj-$(CONFIG_ARCH_OMAP2)		+= pm24xx.o
-obj-$(CONFIG_ARCH_OMAP2)		+= sleep24xx.o pm_bus.o
+obj-$(CONFIG_ARCH_OMAP2)		+= sleep24xx.o
 obj-$(CONFIG_ARCH_OMAP3)		+= pm34xx.o sleep34xx.o \
-					   cpuidle34xx.o pm_bus.o
-obj-$(CONFIG_ARCH_OMAP4)		+= pm44xx.o pm_bus.o
+					   cpuidle34xx.o
+obj-$(CONFIG_ARCH_OMAP4)		+= pm44xx.o
 obj-$(CONFIG_PM_DEBUG)			+= pm-debug.o
 obj-$(CONFIG_OMAP_SMARTREFLEX)          += sr_device.o smartreflex.o
 obj-$(CONFIG_OMAP_SMARTREFLEX_CLASS3)	+= smartreflex-class3.o
@@ -229,8 +229,6 @@
 obj-$(CONFIG_MACH_CM_T3517)		+= board-cm-t3517.o
 obj-$(CONFIG_MACH_IGEP0020)		+= board-igep0020.o \
 					   hsmmc.o
-obj-$(CONFIG_MACH_IGEP0030)		+= board-igep0030.o \
-					   hsmmc.o
 obj-$(CONFIG_MACH_OMAP3_TOUCHBOOK)	+= board-omap3touchbook.o \
 					   hsmmc.o
 obj-$(CONFIG_MACH_OMAP_4430SDP)		+= board-4430sdp.o \
@@ -270,3 +268,5 @@
 
 disp-$(CONFIG_OMAP2_DSS)		:= display.o
 obj-y					+= $(disp-m) $(disp-y)
+
+obj-y					+= common-board-devices.o
diff -druN linux-2.6.39-libre/arch/arm/mach-omap2/mux44xx.c linux-3.0-rc7-libre/arch/arm/mach-omap2/mux44xx.c
--- linux-2.6.39-libre/arch/arm/mach-omap2/mux44xx.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-omap2/mux44xx.c	2011-07-11 19:51:52.000000000 -0400
@@ -1309,7 +1309,8 @@
 #define omap4_wkup_cbl_cbs_ball  NULL
 #endif
 
-int __init omap4_mux_init(struct omap_board_mux *board_subset, int flags)
+int __init omap4_mux_init(struct omap_board_mux *board_subset,
+	struct omap_board_mux *board_wkup_subset, int flags)
 {
 	struct omap_ball *package_balls_core;
 	struct omap_ball *package_balls_wkup = omap4_wkup_cbl_cbs_ball;
@@ -1347,7 +1348,7 @@
 			    OMAP_MUX_GPIO_IN_MODE3,
 			    OMAP4_CTRL_MODULE_PAD_WKUP_MUX_PBASE,
 			    OMAP4_CTRL_MODULE_PAD_WKUP_MUX_SIZE,
-			    omap4_wkup_muxmodes, NULL, board_subset,
+			    omap4_wkup_muxmodes, NULL, board_wkup_subset,
 			    package_balls_wkup);
 
 	return ret;
diff -druN linux-2.6.39-libre/arch/arm/mach-omap2/mux.c linux-3.0-rc7-libre/arch/arm/mach-omap2/mux.c
--- linux-2.6.39-libre/arch/arm/mach-omap2/mux.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-omap2/mux.c	2011-07-11 19:51:52.000000000 -0400
@@ -83,6 +83,9 @@
 void omap_mux_write_array(struct omap_mux_partition *partition,
 				 struct omap_board_mux *board_mux)
 {
+	if (!board_mux)
+		return;
+
 	while (board_mux->reg_offset != OMAP_MUX_TERMINATOR) {
 		omap_mux_write(partition, board_mux->value,
 			       board_mux->reg_offset);
@@ -906,7 +909,7 @@
 u16 omap_mux_get_gpio(int gpio)
 {
 	struct omap_mux_partition *partition;
-	struct omap_mux *m;
+	struct omap_mux *m = NULL;
 
 	list_for_each_entry(partition, &mux_partitions, node) {
 		m = omap_mux_get_by_gpio(partition, gpio);
diff -druN linux-2.6.39-libre/arch/arm/mach-omap2/mux.h linux-3.0-rc7-libre/arch/arm/mach-omap2/mux.h
--- linux-2.6.39-libre/arch/arm/mach-omap2/mux.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-omap2/mux.h	2011-07-11 19:51:52.000000000 -0400
@@ -323,10 +323,12 @@
 
 /**
  * omap4_mux_init() - initialize mux system with board specific set
- * @board_mux:		Board specific mux table
+ * @board_subset:	Board specific mux table
+ * @board_wkup_subset:	Board specific mux table for wakeup instance
  * @flags:		OMAP package type used for the board
  */
-int omap4_mux_init(struct omap_board_mux *board_mux, int flags);
+int omap4_mux_init(struct omap_board_mux *board_subset,
+	struct omap_board_mux *board_wkup_subset, int flags);
 
 /**
  * omap_mux_init - private mux init function, do not call
diff -druN linux-2.6.39-libre/arch/arm/mach-omap2/omap_hwmod_44xx_data.c linux-3.0-rc7-libre/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
--- linux-2.6.39-libre/arch/arm/mach-omap2/omap_hwmod_44xx_data.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-omap2/omap_hwmod_44xx_data.c	2011-07-11 19:51:52.000000000 -0400
@@ -5109,7 +5109,7 @@
 	&omap44xx_iva_seq1_hwmod,
 
 	/* kbd class */
-/*	&omap44xx_kbd_hwmod, */
+	&omap44xx_kbd_hwmod,
 
 	/* mailbox class */
 	&omap44xx_mailbox_hwmod,
diff -druN linux-2.6.39-libre/arch/arm/mach-omap2/omap_hwmod.c linux-3.0-rc7-libre/arch/arm/mach-omap2/omap_hwmod.c
--- linux-2.6.39-libre/arch/arm/mach-omap2/omap_hwmod.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-omap2/omap_hwmod.c	2011-07-11 19:51:52.000000000 -0400
@@ -1628,7 +1628,7 @@
 			void *data)
 {
 	struct omap_hwmod *temp_oh;
-	int ret;
+	int ret = 0;
 
 	if (!fn)
 		return -EINVAL;
diff -druN linux-2.6.39-libre/arch/arm/mach-omap2/omap_l3_noc.c linux-3.0-rc7-libre/arch/arm/mach-omap2/omap_l3_noc.c
--- linux-2.6.39-libre/arch/arm/mach-omap2/omap_l3_noc.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-omap2/omap_l3_noc.c	2011-07-11 19:51:52.000000000 -0400
@@ -63,10 +63,7 @@
 	char *source_name;
 
 	/* Get the Type of interrupt */
-	if (irq == l3->app_irq)
-		inttype = L3_APPLICATION_ERROR;
-	else
-		inttype = L3_DEBUG_ERROR;
+	inttype = irq == l3->app_irq ? L3_APPLICATION_ERROR : L3_DEBUG_ERROR;
 
 	for (i = 0; i < L3_MODULES; i++) {
 		/*
@@ -84,10 +81,10 @@
 
 			err_src = j;
 			/* Read the stderrlog_main_source from clk domain */
-			std_err_main_addr = base + (*(l3_targ[i] + err_src));
-			std_err_main =  readl(std_err_main_addr);
+			std_err_main_addr = base + *(l3_targ[i] + err_src);
+			std_err_main = readl(std_err_main_addr);
 
-			switch ((std_err_main & CUSTOM_ERROR)) {
+			switch (std_err_main & CUSTOM_ERROR) {
 			case STANDARD_ERROR:
 				source_name =
 				l3_targ_stderrlog_main_name[i][err_src];
@@ -132,49 +129,49 @@
 
 	l3 = kzalloc(sizeof(*l3), GFP_KERNEL);
 	if (!l3)
-		ret = -ENOMEM;
+		return -ENOMEM;
 
 	platform_set_drvdata(pdev, l3);
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	if (!res) {
 		dev_err(&pdev->dev, "couldn't find resource 0\n");
 		ret = -ENODEV;
-		goto err1;
+		goto err0;
 	}
 
 	l3->l3_base[0] = ioremap(res->start, resource_size(res));
-	if (!(l3->l3_base[0])) {
+	if (!l3->l3_base[0]) {
 		dev_err(&pdev->dev, "ioremap failed\n");
 		ret = -ENOMEM;
-		goto err2;
+		goto err0;
 	}
 
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
 	if (!res) {
 		dev_err(&pdev->dev, "couldn't find resource 1\n");
 		ret = -ENODEV;
-		goto err3;
+		goto err1;
 	}
 
 	l3->l3_base[1] = ioremap(res->start, resource_size(res));
-	if (!(l3->l3_base[1])) {
+	if (!l3->l3_base[1]) {
 		dev_err(&pdev->dev, "ioremap failed\n");
 		ret = -ENOMEM;
-		goto err4;
+		goto err1;
 	}
 
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 2);
 	if (!res) {
 		dev_err(&pdev->dev, "couldn't find resource 2\n");
 		ret = -ENODEV;
-		goto err5;
+		goto err2;
 	}
 
 	l3->l3_base[2] = ioremap(res->start, resource_size(res));
-	if (!(l3->l3_base[2])) {
+	if (!l3->l3_base[2]) {
 		dev_err(&pdev->dev, "ioremap failed\n");
 		ret = -ENOMEM;
-		goto err6;
+		goto err2;
 	}
 
 	/*
@@ -187,7 +184,7 @@
 	if (ret) {
 		pr_crit("L3: request_irq failed to register for 0x%x\n",
 					 OMAP44XX_IRQ_L3_DBG);
-		goto err7;
+		goto err3;
 	}
 	l3->debug_irq = irq;
 
@@ -198,24 +195,22 @@
 	if (ret) {
 		pr_crit("L3: request_irq failed to register for 0x%x\n",
 					 OMAP44XX_IRQ_L3_APP);
-		goto err8;
+		goto err4;
 	}
 	l3->app_irq = irq;
 
-	goto err0;
-err8:
-err7:
-	iounmap(l3->l3_base[2]);
-err6:
-err5:
-	iounmap(l3->l3_base[1]);
+	return 0;
+
 err4:
+	free_irq(l3->debug_irq, l3);
 err3:
-	iounmap(l3->l3_base[0]);
+	iounmap(l3->l3_base[2]);
 err2:
+	iounmap(l3->l3_base[1]);
 err1:
-	kfree(l3);
+	iounmap(l3->l3_base[0]);
 err0:
+	kfree(l3);
 	return ret;
 }
 
diff -druN linux-2.6.39-libre/arch/arm/mach-omap2/omap_l3_smx.c linux-3.0-rc7-libre/arch/arm/mach-omap2/omap_l3_smx.c
--- linux-2.6.39-libre/arch/arm/mach-omap2/omap_l3_smx.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-omap2/omap_l3_smx.c	2011-07-11 19:51:52.000000000 -0400
@@ -155,7 +155,7 @@
 	u8                      multi = error & L3_ERROR_LOG_MULTI;
 	u32			address = omap3_l3_decode_addr(error_addr);
 
-	WARN(true, "%s Error seen by %s %s at address %x\n",
+	WARN(true, "%s seen by %s %s at address %x\n",
 				 omap3_l3_code_string(code),
 			  omap3_l3_initiator_string(initid),
 			     multi ? "Multiple Errors" : "",
@@ -167,21 +167,15 @@
 static irqreturn_t omap3_l3_app_irq(int irq, void *_l3)
 {
 	struct omap3_l3         *l3 = _l3;
-
 	u64                     status, clear;
 	u64                     error;
 	u64			error_addr;
 	u64			err_source = 0;
 	void			__iomem *base;
 	int			int_type;
-
 	irqreturn_t             ret = IRQ_NONE;
 
-	if (irq == l3->app_irq)
-		int_type = L3_APPLICATION_ERROR;
-	else
-		int_type = L3_DEBUG_ERROR;
-
+	int_type = irq == l3->app_irq ? L3_APPLICATION_ERROR : L3_DEBUG_ERROR;
 	if (!int_type) {
 		status = omap3_l3_readll(l3->rt, L3_SI_FLAG_STATUS_0);
 		/*
@@ -202,7 +196,6 @@
 
 	base = l3->rt + *(omap3_l3_bases[int_type] + err_source);
 	error = omap3_l3_readll(base, L3_ERROR_LOG);
-
 	if (error) {
 		error_addr = omap3_l3_readll(base, L3_ERROR_LOG_ADDR);
 
@@ -210,9 +203,8 @@
 	}
 
 	/* Clear the status register */
-	clear = ((L3_AGENT_STATUS_CLEAR_IA << int_type) |
-		 (L3_AGENT_STATUS_CLEAR_TA));
-
+	clear = (L3_AGENT_STATUS_CLEAR_IA << int_type) |
+		L3_AGENT_STATUS_CLEAR_TA;
 	omap3_l3_writell(base, L3_AGENT_STATUS, clear);
 
 	/* clear the error log register */
@@ -228,10 +220,8 @@
 	int                     ret;
 
 	l3 = kzalloc(sizeof(*l3), GFP_KERNEL);
-	if (!l3) {
-		ret = -ENOMEM;
-		goto err0;
-	}
+	if (!l3)
+		return -ENOMEM;
 
 	platform_set_drvdata(pdev, l3);
 
@@ -239,13 +229,13 @@
 	if (!res) {
 		dev_err(&pdev->dev, "couldn't find resource\n");
 		ret = -ENODEV;
-		goto err1;
+		goto err0;
 	}
 	l3->rt = ioremap(res->start, resource_size(res));
-	if (!(l3->rt)) {
+	if (!l3->rt) {
 		dev_err(&pdev->dev, "ioremap failed\n");
 		ret = -ENOMEM;
-		goto err2;
+		goto err0;
 	}
 
 	l3->debug_irq = platform_get_irq(pdev, 0);
@@ -254,28 +244,26 @@
 		"l3-debug-irq", l3);
 	if (ret) {
 		dev_err(&pdev->dev, "couldn't request debug irq\n");
-		goto err3;
+		goto err1;
 	}
 
 	l3->app_irq = platform_get_irq(pdev, 1);
 	ret = request_irq(l3->app_irq, omap3_l3_app_irq,
 		IRQF_DISABLED | IRQF_TRIGGER_RISING,
 		"l3-app-irq", l3);
-
 	if (ret) {
 		dev_err(&pdev->dev, "couldn't request app irq\n");
-		goto err4;
+		goto err2;
 	}
 
-	goto err0;
+	return 0;
 
-err4:
-err3:
-	iounmap(l3->rt);
 err2:
+	free_irq(l3->debug_irq, l3);
 err1:
-	kfree(l3);
+	iounmap(l3->rt);
 err0:
+	kfree(l3);
 	return ret;
 }
 
diff -druN linux-2.6.39-libre/arch/arm/mach-omap2/omap_phy_internal.c linux-3.0-rc7-libre/arch/arm/mach-omap2/omap_phy_internal.c
--- linux-2.6.39-libre/arch/arm/mach-omap2/omap_phy_internal.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-omap2/omap_phy_internal.c	2011-07-11 19:51:52.000000000 -0400
@@ -50,13 +50,18 @@
 {
 	ctrl_base = ioremap(OMAP443X_SCM_BASE, SZ_1K);
 	if (!ctrl_base) {
-		dev_err(dev, "control module ioremap failed\n");
+		pr_err("control module ioremap failed\n");
 		return -ENOMEM;
 	}
 	/* Power down the phy */
 	__raw_writel(PHY_PD, ctrl_base + CONTROL_DEV_CONF);
-	phyclk = clk_get(dev, "ocp2scp_usb_phy_ick");
 
+	if (!dev) {
+		iounmap(ctrl_base);
+		return 0;
+	}
+
+	phyclk = clk_get(dev, "ocp2scp_usb_phy_ick");
 	if (IS_ERR(phyclk)) {
 		dev_err(dev, "cannot clk_get ocp2scp_usb_phy_ick\n");
 		iounmap(ctrl_base);
@@ -228,7 +233,7 @@
 	regval = omap_ctrl_readl(AM35XX_CONTROL_LVL_INTR_CLEAR);
 }
 
-void am35x_musb_set_mode(u8 musb_mode)
+void am35x_set_mode(u8 musb_mode)
 {
 	u32 devconf2 = omap_ctrl_readl(AM35XX_CONTROL_DEVCONF2);
 
diff -druN linux-2.6.39-libre/arch/arm/mach-omap2/omap-smp.c linux-3.0-rc7-libre/arch/arm/mach-omap2/omap-smp.c
--- linux-2.6.39-libre/arch/arm/mach-omap2/omap-smp.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-omap2/omap-smp.c	2011-07-11 19:51:52.000000000 -0400
@@ -21,6 +21,7 @@
 #include <linux/io.h>
 
 #include <asm/cacheflush.h>
+#include <asm/hardware/gic.h>
 #include <asm/smp_scu.h>
 #include <mach/hardware.h>
 #include <mach/omap4-common.h>
@@ -63,7 +64,7 @@
 	omap_modify_auxcoreboot0(0x200, 0xfffffdff);
 	flush_cache_all();
 	smp_wmb();
-	smp_cross_call(cpumask_of(cpu), 1);
+	gic_raise_softirq(cpumask_of(cpu), 1);
 
 	/*
 	 * Now the secondary core is starting up let it run its
@@ -118,6 +119,8 @@
 
 	for (i = 0; i < ncores; i++)
 		set_cpu_possible(i, true);
+
+	set_smp_cross_call(gic_raise_softirq);
 }
 
 void __init platform_smp_prepare_cpus(unsigned int max_cpus)
diff -druN linux-2.6.39-libre/arch/arm/mach-omap2/pm34xx.c linux-3.0-rc7-libre/arch/arm/mach-omap2/pm34xx.c
--- linux-2.6.39-libre/arch/arm/mach-omap2/pm34xx.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-omap2/pm34xx.c	2011-07-11 19:51:52.000000000 -0400
@@ -779,18 +779,6 @@
 	else
 		state = PWRDM_POWER_RET;
 
-#ifdef CONFIG_CPU_IDLE
-	/*
-	 * Erratum i583: implementation for ES rev < Es1.2 on 3630. We cannot
-	 * enable OFF mode in a stable form for previous revisions, restrict
-	 * instead to RET
-	 */
-	if (IS_PM34XX_ERRATUM(PM_SDRC_WAKEUP_ERRATUM_i583))
-		omap3_cpuidle_update_states(state, PWRDM_POWER_RET);
-	else
-		omap3_cpuidle_update_states(state, state);
-#endif
-
 	list_for_each_entry(pwrst, &pwrst_list, node) {
 		if (IS_PM34XX_ERRATUM(PM_SDRC_WAKEUP_ERRATUM_i583) &&
 				pwrst->pwrdm == core_pwrdm &&
@@ -895,8 +883,6 @@
 
 	pm_errata_configure();
 
-	printk(KERN_ERR "Power Management for TI OMAP3.\n");
-
 	/* XXX prcm_setup_regs needs to be before enabling hw
 	 * supervised mode for powerdomains */
 	prcm_setup_regs();
diff -druN linux-2.6.39-libre/arch/arm/mach-omap2/pm44xx.c linux-3.0-rc7-libre/arch/arm/mach-omap2/pm44xx.c
--- linux-2.6.39-libre/arch/arm/mach-omap2/pm44xx.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-omap2/pm44xx.c	2011-07-11 19:51:52.000000000 -0400
@@ -105,13 +105,11 @@
 
 	pr_err("Power Management for TI OMAP4.\n");
 
-#ifdef CONFIG_PM
 	ret = pwrdm_for_each(pwrdms_setup, NULL);
 	if (ret) {
 		pr_err("Failed to setup powerdomains\n");
 		goto err2;
 	}
-#endif
 
 #ifdef CONFIG_SUSPEND
 	suspend_set_ops(&omap_pm_ops);
diff -druN linux-2.6.39-libre/arch/arm/mach-omap2/pm_bus.c linux-3.0-rc7-libre/arch/arm/mach-omap2/pm_bus.c
--- linux-2.6.39-libre/arch/arm/mach-omap2/pm_bus.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-omap2/pm_bus.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,85 +0,0 @@
-/*
- * Runtime PM support code for OMAP
- *
- * Author: Kevin Hilman, Deep Root Systems, LLC
- *
- * Copyright (C) 2010 Texas Instruments, Inc.
- *
- * This file is licensed under the terms of the GNU General Public
- * License version 2. This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
- */
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/io.h>
-#include <linux/pm_runtime.h>
-#include <linux/platform_device.h>
-#include <linux/mutex.h>
-
-#include <plat/omap_device.h>
-#include <plat/omap-pm.h>
-
-#ifdef CONFIG_PM_RUNTIME
-static int omap_pm_runtime_suspend(struct device *dev)
-{
-	struct platform_device *pdev = to_platform_device(dev);
-	int r, ret = 0;
-
-	dev_dbg(dev, "%s\n", __func__);
-
-	ret = pm_generic_runtime_suspend(dev);
-
-	if (!ret && dev->parent == &omap_device_parent) {
-		r = omap_device_idle(pdev);
-		WARN_ON(r);
-	}
-
-	return ret;
-};
-
-static int omap_pm_runtime_resume(struct device *dev)
-{
-	struct platform_device *pdev = to_platform_device(dev);
-	int r;
-
-	dev_dbg(dev, "%s\n", __func__);
-
-	if (dev->parent == &omap_device_parent) {
-		r = omap_device_enable(pdev);
-		WARN_ON(r);
-	}
-
-	return pm_generic_runtime_resume(dev);
-};
-#else
-#define omap_pm_runtime_suspend NULL
-#define omap_pm_runtime_resume NULL
-#endif /* CONFIG_PM_RUNTIME */
-
-static int __init omap_pm_runtime_init(void)
-{
-	const struct dev_pm_ops *pm;
-	struct dev_pm_ops *omap_pm;
-
-	pm = platform_bus_get_pm_ops();
-	if (!pm) {
-		pr_err("%s: unable to get dev_pm_ops from platform_bus\n",
-			__func__);
-		return -ENODEV;
-	}
-
-	omap_pm = kmemdup(pm, sizeof(struct dev_pm_ops), GFP_KERNEL);
-	if (!omap_pm) {
-		pr_err("%s: unable to alloc memory for new dev_pm_ops\n",
-			__func__);
-		return -ENOMEM;
-	}
-
-	omap_pm->runtime_suspend = omap_pm_runtime_suspend;
-	omap_pm->runtime_resume = omap_pm_runtime_resume;
-
-	platform_bus_set_pm_ops(omap_pm);
-
-	return 0;
-}
-core_initcall(omap_pm_runtime_init);
diff -druN linux-2.6.39-libre/arch/arm/mach-omap2/pm-debug.c linux-3.0-rc7-libre/arch/arm/mach-omap2/pm-debug.c
--- linux-2.6.39-libre/arch/arm/mach-omap2/pm-debug.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-omap2/pm-debug.c	2011-07-11 19:51:52.000000000 -0400
@@ -189,7 +189,7 @@
 
 static int pm_dbg_init_done;
 
-static int __init pm_dbg_init(void);
+static int pm_dbg_init(void);
 
 enum {
 	DEBUG_FILE_COUNTERS = 0,
@@ -595,7 +595,7 @@
 
 DEFINE_SIMPLE_ATTRIBUTE(pm_dbg_option_fops, option_get, option_set, "%llu\n");
 
-static int __init pm_dbg_init(void)
+static int pm_dbg_init(void)
 {
 	int i;
 	struct dentry *d;
diff -druN linux-2.6.39-libre/arch/arm/mach-omap2/pm.h linux-3.0-rc7-libre/arch/arm/mach-omap2/pm.h
--- linux-2.6.39-libre/arch/arm/mach-omap2/pm.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-omap2/pm.h	2011-07-11 19:51:52.000000000 -0400
@@ -36,11 +36,16 @@
 }
 #endif
 
+/*
+ * cpuidle mach specific parameters
+ *
+ * The board code can override the default C-states definition using
+ * omap3_pm_init_cpuidle
+ */
 struct cpuidle_params {
-	u8  valid;
-	u32 sleep_latency;
-	u32 wake_latency;
-	u32 threshold;
+	u32 exit_latency;	/* exit_latency = sleep + wake-up latencies */
+	u32 target_residency;
+	u8 valid;		/* validates the C-state */
 };
 
 #if defined(CONFIG_PM) && defined(CONFIG_CPU_IDLE)
@@ -73,10 +78,6 @@
 #define sleep_while_idle 0
 #endif
 
-#if defined(CONFIG_CPU_IDLE)
-extern void omap3_cpuidle_update_states(u32, u32);
-#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 -druN linux-2.6.39-libre/arch/arm/mach-omap2/smartreflex.c linux-3.0-rc7-libre/arch/arm/mach-omap2/smartreflex.c
--- linux-2.6.39-libre/arch/arm/mach-omap2/smartreflex.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-omap2/smartreflex.c	2011-07-11 19:51:52.000000000 -0400
@@ -847,6 +847,14 @@
 		goto err_free_devinfo;
 	}
 
+	mem = request_mem_region(mem->start, resource_size(mem),
+					dev_name(&pdev->dev));
+	if (!mem) {
+		dev_err(&pdev->dev, "%s: no mem region\n", __func__);
+		ret = -EBUSY;
+		goto err_free_devinfo;
+	}
+
 	irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
 
 	pm_runtime_enable(&pdev->dev);
@@ -883,7 +891,7 @@
 		ret = sr_late_init(sr_info);
 		if (ret) {
 			pr_warning("%s: Error in SR late init\n", __func__);
-			goto err_release_region;
+			return ret;
 		}
 	}
 
@@ -896,7 +904,7 @@
 	vdd_dbg_dir = omap_voltage_get_dbgdir(sr_info->voltdm);
 	if (!vdd_dbg_dir) {
 		ret = -EINVAL;
-		goto err_release_region;
+		goto err_iounmap;
 	}
 
 	sr_info->dbg_dir = debugfs_create_dir("smartreflex", vdd_dbg_dir);
@@ -904,7 +912,7 @@
 		dev_err(&pdev->dev, "%s: Unable to create debugfs directory\n",
 			__func__);
 		ret = PTR_ERR(sr_info->dbg_dir);
-		goto err_release_region;
+		goto err_iounmap;
 	}
 
 	(void) debugfs_create_file("autocomp", S_IRUGO | S_IWUSR,
@@ -921,7 +929,7 @@
 		dev_err(&pdev->dev, "%s: Unable to create debugfs directory"
 			"for n-values\n", __func__);
 		ret = PTR_ERR(nvalue_dir);
-		goto err_release_region;
+		goto err_debugfs;
 	}
 
 	omap_voltage_get_volttable(sr_info->voltdm, &volt_data);
@@ -931,7 +939,7 @@
 			"entries for n-values\n",
 			__func__, sr_info->voltdm->name);
 		ret = -ENODATA;
-		goto err_release_region;
+		goto err_debugfs;
 	}
 
 	for (i = 0; i < sr_info->nvalue_count; i++) {
@@ -945,6 +953,11 @@
 
 	return ret;
 
+err_debugfs:
+	debugfs_remove_recursive(sr_info->dbg_dir);
+err_iounmap:
+	list_del(&sr_info->node);
+	iounmap(sr_info->base);
 err_release_region:
 	release_mem_region(mem->start, resource_size(mem));
 err_free_devinfo:
diff -druN linux-2.6.39-libre/arch/arm/mach-omap2/usb-musb.c linux-3.0-rc7-libre/arch/arm/mach-omap2/usb-musb.c
--- linux-2.6.39-libre/arch/arm/mach-omap2/usb-musb.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-omap2/usb-musb.c	2011-07-11 19:51:52.000000000 -0400
@@ -108,7 +108,13 @@
 	}
 }
 
-void __init usb_musb_init(struct omap_musb_board_data *board_data)
+static struct omap_musb_board_data musb_default_board_data = {
+	.interface_type		= MUSB_INTERFACE_ULPI,
+	.mode			= MUSB_OTG,
+	.power			= 100,
+};
+
+void __init usb_musb_init(struct omap_musb_board_data *musb_board_data)
 {
 	struct omap_hwmod		*oh;
 	struct omap_device		*od;
@@ -116,11 +122,12 @@
 	struct device			*dev;
 	int				bus_id = -1;
 	const char			*oh_name, *name;
+	struct omap_musb_board_data	*board_data;
 
-	if (cpu_is_omap3517() || cpu_is_omap3505()) {
-	} else if (cpu_is_omap44xx()) {
-		usb_musb_mux_init(board_data);
-	}
+	if (musb_board_data)
+		board_data = musb_board_data;
+	else
+		board_data = &musb_default_board_data;
 
 	/*
 	 * REVISIT: This line can be removed once all the platforms using
@@ -164,10 +171,15 @@
 	dev->dma_mask = &musb_dmamask;
 	dev->coherent_dma_mask = musb_dmamask;
 	put_device(dev);
+
+	if (cpu_is_omap44xx())
+		omap4430_phy_init(dev);
 }
 
 #else
 void __init usb_musb_init(struct omap_musb_board_data *board_data)
 {
+	if (cpu_is_omap44xx())
+		omap4430_phy_init(NULL);
 }
 #endif /* CONFIG_USB_MUSB_SOC */
diff -druN linux-2.6.39-libre/arch/arm/mach-omap2/usb-tusb6010.c linux-3.0-rc7-libre/arch/arm/mach-omap2/usb-tusb6010.c
--- linux-2.6.39-libre/arch/arm/mach-omap2/usb-tusb6010.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-omap2/usb-tusb6010.c	2011-07-11 19:51:52.000000000 -0400
@@ -293,12 +293,11 @@
 			);
 
 	/* IRQ */
-	status = gpio_request(irq, "TUSB6010 irq");
+	status = gpio_request_one(irq, GPIOF_IN, "TUSB6010 irq");
 	if (status < 0) {
 		printk(error, 3, status);
 		return status;
 	}
-	gpio_direction_input(irq);
 	tusb_resources[2].start = irq + IH_GPIO_BASE;
 
 	/* set up memory timings ... can speed them up later */
diff -druN linux-2.6.39-libre/arch/arm/mach-omap2/voltage.c linux-3.0-rc7-libre/arch/arm/mach-omap2/voltage.c
--- linux-2.6.39-libre/arch/arm/mach-omap2/voltage.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-omap2/voltage.c	2011-07-11 19:51:52.000000000 -0400
@@ -148,7 +148,6 @@
 	}
 
 	vsel = vdd->read_reg(prm_mod_offs, vdd->vp_data->voltage);
-	pr_notice("curr_vsel = %x\n", vsel);
 
 	if (!vdd->pmic_info->vsel_to_uv) {
 		pr_warning("PMIC function to convert vsel to voltage"
diff -druN linux-2.6.39-libre/arch/arm/mach-orion5x/common.c linux-3.0-rc7-libre/arch/arm/mach-orion5x/common.c
--- linux-2.6.39-libre/arch/arm/mach-orion5x/common.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-orion5x/common.c	2011-07-11 19:51:52.000000000 -0400
@@ -13,12 +13,11 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/platform_device.h>
+#include <linux/dma-mapping.h>
 #include <linux/serial_8250.h>
 #include <linux/mbus.h>
-#include <linux/mv643xx_eth.h>
 #include <linux/mv643xx_i2c.h>
 #include <linux/ata_platform.h>
-#include <linux/spi/orion_spi.h>
 #include <net/dsa.h>
 #include <asm/page.h>
 #include <asm/setup.h>
@@ -29,11 +28,9 @@
 #include <mach/bridge-regs.h>
 #include <mach/hardware.h>
 #include <mach/orion5x.h>
-#include <plat/ehci-orion.h>
-#include <plat/mv_xor.h>
 #include <plat/orion_nand.h>
-#include <plat/orion_wdt.h>
 #include <plat/time.h>
+#include <plat/common.h>
 #include "common.h"
 
 /*****************************************************************************
@@ -70,530 +67,124 @@
 
 
 /*****************************************************************************
- * EHCI
- ****************************************************************************/
-static struct orion_ehci_data orion5x_ehci_data = {
-	.dram		= &orion5x_mbus_dram_info,
-	.phy_version	= EHCI_PHY_ORION,
-};
-
-static u64 ehci_dmamask = 0xffffffffUL;
-
-
-/*****************************************************************************
  * EHCI0
  ****************************************************************************/
-static struct resource orion5x_ehci0_resources[] = {
-	{
-		.start	= ORION5X_USB0_PHYS_BASE,
-		.end	= ORION5X_USB0_PHYS_BASE + SZ_4K - 1,
-		.flags	= IORESOURCE_MEM,
-	}, {
-		.start	= IRQ_ORION5X_USB0_CTRL,
-		.end	= IRQ_ORION5X_USB0_CTRL,
-		.flags	= IORESOURCE_IRQ,
-	},
-};
-
-static struct platform_device orion5x_ehci0 = {
-	.name		= "orion-ehci",
-	.id		= 0,
-	.dev		= {
-		.dma_mask		= &ehci_dmamask,
-		.coherent_dma_mask	= 0xffffffff,
-		.platform_data		= &orion5x_ehci_data,
-	},
-	.resource	= orion5x_ehci0_resources,
-	.num_resources	= ARRAY_SIZE(orion5x_ehci0_resources),
-};
-
 void __init orion5x_ehci0_init(void)
 {
-	platform_device_register(&orion5x_ehci0);
+	orion_ehci_init(&orion5x_mbus_dram_info,
+			ORION5X_USB0_PHYS_BASE, IRQ_ORION5X_USB0_CTRL);
 }
 
 
 /*****************************************************************************
  * EHCI1
  ****************************************************************************/
-static struct resource orion5x_ehci1_resources[] = {
-	{
-		.start	= ORION5X_USB1_PHYS_BASE,
-		.end	= ORION5X_USB1_PHYS_BASE + SZ_4K - 1,
-		.flags	= IORESOURCE_MEM,
-	}, {
-		.start	= IRQ_ORION5X_USB1_CTRL,
-		.end	= IRQ_ORION5X_USB1_CTRL,
-		.flags	= IORESOURCE_IRQ,
-	},
-};
-
-static struct platform_device orion5x_ehci1 = {
-	.name		= "orion-ehci",
-	.id		= 1,
-	.dev		= {
-		.dma_mask		= &ehci_dmamask,
-		.coherent_dma_mask	= 0xffffffff,
-		.platform_data		= &orion5x_ehci_data,
-	},
-	.resource	= orion5x_ehci1_resources,
-	.num_resources	= ARRAY_SIZE(orion5x_ehci1_resources),
-};
-
 void __init orion5x_ehci1_init(void)
 {
-	platform_device_register(&orion5x_ehci1);
+	orion_ehci_1_init(&orion5x_mbus_dram_info,
+			  ORION5X_USB1_PHYS_BASE, IRQ_ORION5X_USB1_CTRL);
 }
 
 
 /*****************************************************************************
- * GigE
+ * GE00
  ****************************************************************************/
-struct mv643xx_eth_shared_platform_data orion5x_eth_shared_data = {
-	.dram		= &orion5x_mbus_dram_info,
-};
-
-static struct resource orion5x_eth_shared_resources[] = {
-	{
-		.start	= ORION5X_ETH_PHYS_BASE + 0x2000,
-		.end	= ORION5X_ETH_PHYS_BASE + 0x3fff,
-		.flags	= IORESOURCE_MEM,
-	}, {
-		.start	= IRQ_ORION5X_ETH_ERR,
-		.end	= IRQ_ORION5X_ETH_ERR,
-		.flags	= IORESOURCE_IRQ,
-	},
-};
-
-static struct platform_device orion5x_eth_shared = {
-	.name		= MV643XX_ETH_SHARED_NAME,
-	.id		= 0,
-	.dev		= {
-		.platform_data	= &orion5x_eth_shared_data,
-	},
-	.num_resources	= ARRAY_SIZE(orion5x_eth_shared_resources),
-	.resource	= orion5x_eth_shared_resources,
-};
-
-static struct resource orion5x_eth_resources[] = {
-	{
-		.name	= "eth irq",
-		.start	= IRQ_ORION5X_ETH_SUM,
-		.end	= IRQ_ORION5X_ETH_SUM,
-		.flags	= IORESOURCE_IRQ,
-	},
-};
-
-static struct platform_device orion5x_eth = {
-	.name		= MV643XX_ETH_NAME,
-	.id		= 0,
-	.num_resources	= 1,
-	.resource	= orion5x_eth_resources,
-	.dev		= {
-		.coherent_dma_mask	= 0xffffffff,
-	},
-};
-
 void __init orion5x_eth_init(struct mv643xx_eth_platform_data *eth_data)
 {
-	eth_data->shared = &orion5x_eth_shared;
-	orion5x_eth.dev.platform_data = eth_data;
-
-	platform_device_register(&orion5x_eth_shared);
-	platform_device_register(&orion5x_eth);
+	orion_ge00_init(eth_data, &orion5x_mbus_dram_info,
+			ORION5X_ETH_PHYS_BASE, IRQ_ORION5X_ETH_SUM,
+			IRQ_ORION5X_ETH_ERR, orion5x_tclk);
 }
 
 
 /*****************************************************************************
  * Ethernet switch
  ****************************************************************************/
-static struct resource orion5x_switch_resources[] = {
-	{
-		.start	= 0,
-		.end	= 0,
-		.flags	= IORESOURCE_IRQ,
-	},
-};
-
-static struct platform_device orion5x_switch_device = {
-	.name		= "dsa",
-	.id		= 0,
-	.num_resources	= 0,
-	.resource	= orion5x_switch_resources,
-};
-
 void __init orion5x_eth_switch_init(struct dsa_platform_data *d, int irq)
 {
-	int i;
-
-	if (irq != NO_IRQ) {
-		orion5x_switch_resources[0].start = irq;
-		orion5x_switch_resources[0].end = irq;
-		orion5x_switch_device.num_resources = 1;
-	}
-
-	d->netdev = &orion5x_eth.dev;
-	for (i = 0; i < d->nr_chips; i++)
-		d->chip[i].mii_bus = &orion5x_eth_shared.dev;
-	orion5x_switch_device.dev.platform_data = d;
-
-	platform_device_register(&orion5x_switch_device);
+	orion_ge00_switch_init(d, irq);
 }
 
 
 /*****************************************************************************
  * I2C
  ****************************************************************************/
-static struct mv64xxx_i2c_pdata orion5x_i2c_pdata = {
-	.freq_m		= 8, /* assumes 166 MHz TCLK */
-	.freq_n		= 3,
-	.timeout	= 1000, /* Default timeout of 1 second */
-};
-
-static struct resource orion5x_i2c_resources[] = {
-	{
-		.start	= I2C_PHYS_BASE,
-		.end	= I2C_PHYS_BASE + 0x1f,
-		.flags	= IORESOURCE_MEM,
-	}, {
-		.start	= IRQ_ORION5X_I2C,
-		.end	= IRQ_ORION5X_I2C,
-		.flags	= IORESOURCE_IRQ,
-	},
-};
-
-static struct platform_device orion5x_i2c = {
-	.name		= MV64XXX_I2C_CTLR_NAME,
-	.id		= 0,
-	.num_resources	= ARRAY_SIZE(orion5x_i2c_resources),
-	.resource	= orion5x_i2c_resources,
-	.dev		= {
-		.platform_data	= &orion5x_i2c_pdata,
-	},
-};
-
 void __init orion5x_i2c_init(void)
 {
-	platform_device_register(&orion5x_i2c);
+	orion_i2c_init(I2C_PHYS_BASE, IRQ_ORION5X_I2C, 8);
+
 }
 
 
 /*****************************************************************************
  * SATA
  ****************************************************************************/
-static struct resource orion5x_sata_resources[] = {
-	{
-		.name	= "sata base",
-		.start	= ORION5X_SATA_PHYS_BASE,
-		.end	= ORION5X_SATA_PHYS_BASE + 0x5000 - 1,
-		.flags	= IORESOURCE_MEM,
-	}, {
-		.name	= "sata irq",
-		.start	= IRQ_ORION5X_SATA,
-		.end	= IRQ_ORION5X_SATA,
-		.flags	= IORESOURCE_IRQ,
-	},
-};
-
-static struct platform_device orion5x_sata = {
-	.name		= "sata_mv",
-	.id		= 0,
-	.dev		= {
-		.coherent_dma_mask	= 0xffffffff,
-	},
-	.num_resources	= ARRAY_SIZE(orion5x_sata_resources),
-	.resource	= orion5x_sata_resources,
-};
-
 void __init orion5x_sata_init(struct mv_sata_platform_data *sata_data)
 {
-	sata_data->dram = &orion5x_mbus_dram_info;
-	orion5x_sata.dev.platform_data = sata_data;
-	platform_device_register(&orion5x_sata);
+	orion_sata_init(sata_data, &orion5x_mbus_dram_info,
+			ORION5X_SATA_PHYS_BASE, IRQ_ORION5X_SATA);
 }
 
 
 /*****************************************************************************
  * SPI
  ****************************************************************************/
-static struct orion_spi_info orion5x_spi_plat_data = {
-	.tclk			= 0,
-	.enable_clock_fix	= 1,
-};
-
-static struct resource orion5x_spi_resources[] = {
-	{
-		.name	= "spi base",
-		.start	= SPI_PHYS_BASE,
-		.end	= SPI_PHYS_BASE + 0x1f,
-		.flags	= IORESOURCE_MEM,
-	},
-};
-
-static struct platform_device orion5x_spi = {
-	.name		= "orion_spi",
-	.id		= 0,
-	.dev		= {
-		.platform_data	= &orion5x_spi_plat_data,
-	},
-	.num_resources	= ARRAY_SIZE(orion5x_spi_resources),
-	.resource	= orion5x_spi_resources,
-};
-
 void __init orion5x_spi_init()
 {
-	platform_device_register(&orion5x_spi);
+	orion_spi_init(SPI_PHYS_BASE, orion5x_tclk);
 }
 
 
 /*****************************************************************************
  * UART0
  ****************************************************************************/
-static struct plat_serial8250_port orion5x_uart0_data[] = {
-	{
-		.mapbase	= UART0_PHYS_BASE,
-		.membase	= (char *)UART0_VIRT_BASE,
-		.irq		= IRQ_ORION5X_UART0,
-		.flags		= UPF_SKIP_TEST | UPF_BOOT_AUTOCONF,
-		.iotype		= UPIO_MEM,
-		.regshift	= 2,
-		.uartclk	= 0,
-	}, {
-	},
-};
-
-static struct resource orion5x_uart0_resources[] = {
-	{
-		.start		= UART0_PHYS_BASE,
-		.end		= UART0_PHYS_BASE + 0xff,
-		.flags		= IORESOURCE_MEM,
-	}, {
-		.start		= IRQ_ORION5X_UART0,
-		.end		= IRQ_ORION5X_UART0,
-		.flags		= IORESOURCE_IRQ,
-	},
-};
-
-static struct platform_device orion5x_uart0 = {
-	.name			= "serial8250",
-	.id			= PLAT8250_DEV_PLATFORM,
-	.dev			= {
-		.platform_data	= orion5x_uart0_data,
-	},
-	.resource		= orion5x_uart0_resources,
-	.num_resources		= ARRAY_SIZE(orion5x_uart0_resources),
-};
-
 void __init orion5x_uart0_init(void)
 {
-	platform_device_register(&orion5x_uart0);
+	orion_uart0_init(UART0_VIRT_BASE, UART0_PHYS_BASE,
+			 IRQ_ORION5X_UART0, orion5x_tclk);
 }
 
-
 /*****************************************************************************
  * UART1
  ****************************************************************************/
-static struct plat_serial8250_port orion5x_uart1_data[] = {
-	{
-		.mapbase	= UART1_PHYS_BASE,
-		.membase	= (char *)UART1_VIRT_BASE,
-		.irq		= IRQ_ORION5X_UART1,
-		.flags		= UPF_SKIP_TEST | UPF_BOOT_AUTOCONF,
-		.iotype		= UPIO_MEM,
-		.regshift	= 2,
-		.uartclk	= 0,
-	}, {
-	},
-};
-
-static struct resource orion5x_uart1_resources[] = {
-	{
-		.start		= UART1_PHYS_BASE,
-		.end		= UART1_PHYS_BASE + 0xff,
-		.flags		= IORESOURCE_MEM,
-	}, {
-		.start		= IRQ_ORION5X_UART1,
-		.end		= IRQ_ORION5X_UART1,
-		.flags		= IORESOURCE_IRQ,
-	},
-};
-
-static struct platform_device orion5x_uart1 = {
-	.name			= "serial8250",
-	.id			= PLAT8250_DEV_PLATFORM1,
-	.dev			= {
-		.platform_data	= orion5x_uart1_data,
-	},
-	.resource		= orion5x_uart1_resources,
-	.num_resources		= ARRAY_SIZE(orion5x_uart1_resources),
-};
-
 void __init orion5x_uart1_init(void)
 {
-	platform_device_register(&orion5x_uart1);
+	orion_uart1_init(UART1_VIRT_BASE, UART1_PHYS_BASE,
+			 IRQ_ORION5X_UART1, orion5x_tclk);
 }
 
-
 /*****************************************************************************
  * XOR engine
  ****************************************************************************/
-struct mv_xor_platform_shared_data orion5x_xor_shared_data = {
-	.dram		= &orion5x_mbus_dram_info,
-};
-
-static struct resource orion5x_xor_shared_resources[] = {
-	{
-		.name	= "xor low",
-		.start	= ORION5X_XOR_PHYS_BASE,
-		.end	= ORION5X_XOR_PHYS_BASE + 0xff,
-		.flags	= IORESOURCE_MEM,
-	}, {
-		.name	= "xor high",
-		.start	= ORION5X_XOR_PHYS_BASE + 0x200,
-		.end	= ORION5X_XOR_PHYS_BASE + 0x2ff,
-		.flags	= IORESOURCE_MEM,
-	},
-};
-
-static struct platform_device orion5x_xor_shared = {
-	.name		= MV_XOR_SHARED_NAME,
-	.id		= 0,
-	.dev		= {
-		.platform_data	= &orion5x_xor_shared_data,
-	},
-	.num_resources	= ARRAY_SIZE(orion5x_xor_shared_resources),
-	.resource	= orion5x_xor_shared_resources,
-};
-
-static u64 orion5x_xor_dmamask = DMA_BIT_MASK(32);
-
-static struct resource orion5x_xor0_resources[] = {
-	[0] = {
-		.start	= IRQ_ORION5X_XOR0,
-		.end	= IRQ_ORION5X_XOR0,
-		.flags	= IORESOURCE_IRQ,
-	},
-};
-
-static struct mv_xor_platform_data orion5x_xor0_data = {
-	.shared		= &orion5x_xor_shared,
-	.hw_id		= 0,
-	.pool_size	= PAGE_SIZE,
-};
-
-static struct platform_device orion5x_xor0_channel = {
-	.name		= MV_XOR_NAME,
-	.id		= 0,
-	.num_resources	= ARRAY_SIZE(orion5x_xor0_resources),
-	.resource	= orion5x_xor0_resources,
-	.dev		= {
-		.dma_mask		= &orion5x_xor_dmamask,
-		.coherent_dma_mask	= DMA_BIT_MASK(64),
-		.platform_data		= &orion5x_xor0_data,
-	},
-};
-
-static struct resource orion5x_xor1_resources[] = {
-	[0] = {
-		.start	= IRQ_ORION5X_XOR1,
-		.end	= IRQ_ORION5X_XOR1,
-		.flags	= IORESOURCE_IRQ,
-	},
-};
-
-static struct mv_xor_platform_data orion5x_xor1_data = {
-	.shared		= &orion5x_xor_shared,
-	.hw_id		= 1,
-	.pool_size	= PAGE_SIZE,
-};
-
-static struct platform_device orion5x_xor1_channel = {
-	.name		= MV_XOR_NAME,
-	.id		= 1,
-	.num_resources	= ARRAY_SIZE(orion5x_xor1_resources),
-	.resource	= orion5x_xor1_resources,
-	.dev		= {
-		.dma_mask		= &orion5x_xor_dmamask,
-		.coherent_dma_mask	= DMA_BIT_MASK(64),
-		.platform_data		= &orion5x_xor1_data,
-	},
-};
-
 void __init orion5x_xor_init(void)
 {
-	platform_device_register(&orion5x_xor_shared);
-
-	/*
-	 * two engines can't do memset simultaneously, this limitation
-	 * satisfied by removing memset support from one of the engines.
-	 */
-	dma_cap_set(DMA_MEMCPY, orion5x_xor0_data.cap_mask);
-	dma_cap_set(DMA_XOR, orion5x_xor0_data.cap_mask);
-	platform_device_register(&orion5x_xor0_channel);
-
-	dma_cap_set(DMA_MEMCPY, orion5x_xor1_data.cap_mask);
-	dma_cap_set(DMA_MEMSET, orion5x_xor1_data.cap_mask);
-	dma_cap_set(DMA_XOR, orion5x_xor1_data.cap_mask);
-	platform_device_register(&orion5x_xor1_channel);
+	orion_xor0_init(&orion5x_mbus_dram_info,
+			ORION5X_XOR_PHYS_BASE,
+			ORION5X_XOR_PHYS_BASE + 0x200,
+			IRQ_ORION5X_XOR0, IRQ_ORION5X_XOR1);
 }
 
-static struct resource orion5x_crypto_res[] = {
-	{
-		.name   = "regs",
-		.start  = ORION5X_CRYPTO_PHYS_BASE,
-		.end    = ORION5X_CRYPTO_PHYS_BASE + 0xffff,
-		.flags  = IORESOURCE_MEM,
-	}, {
-		.name   = "sram",
-		.start  = ORION5X_SRAM_PHYS_BASE,
-		.end    = ORION5X_SRAM_PHYS_BASE + SZ_8K - 1,
-		.flags  = IORESOURCE_MEM,
-	}, {
-		.name   = "crypto interrupt",
-		.start  = IRQ_ORION5X_CESA,
-		.end    = IRQ_ORION5X_CESA,
-		.flags  = IORESOURCE_IRQ,
-	},
-};
-
-static struct platform_device orion5x_crypto_device = {
-	.name           = "mv_crypto",
-	.id             = -1,
-	.num_resources  = ARRAY_SIZE(orion5x_crypto_res),
-	.resource       = orion5x_crypto_res,
-};
-
-static int __init orion5x_crypto_init(void)
+/*****************************************************************************
+ * Cryptographic Engines and Security Accelerator (CESA)
+ ****************************************************************************/
+static void __init orion5x_crypto_init(void)
 {
 	int ret;
 
 	ret = orion5x_setup_sram_win();
 	if (ret)
-		return ret;
+		return;
 
-	return platform_device_register(&orion5x_crypto_device);
+	orion_crypto_init(ORION5X_CRYPTO_PHYS_BASE, ORION5X_SRAM_PHYS_BASE,
+			  SZ_8K, IRQ_ORION5X_CESA);
 }
 
 /*****************************************************************************
  * Watchdog
  ****************************************************************************/
-static struct orion_wdt_platform_data orion5x_wdt_data = {
-	.tclk			= 0,
-};
-
-static struct platform_device orion5x_wdt_device = {
-	.name		= "orion_wdt",
-	.id		= -1,
-	.dev		= {
-		.platform_data	= &orion5x_wdt_data,
-	},
-	.num_resources	= 0,
-};
-
 void __init orion5x_wdt_init(void)
 {
-	orion5x_wdt_data.tclk = orion5x_tclk;
-	platform_device_register(&orion5x_wdt_device);
+	orion_wdt_init(orion5x_tclk);
 }
 
 
@@ -685,11 +276,6 @@
 	orion5x_id(&dev, &rev, &dev_name);
 	printk(KERN_INFO "Orion ID: %s. TCLK=%d.\n", dev_name, orion5x_tclk);
 
-	orion5x_eth_shared_data.t_clk = orion5x_tclk;
-	orion5x_spi_plat_data.tclk = orion5x_tclk;
-	orion5x_uart0_data[0].uartclk = orion5x_tclk;
-	orion5x_uart1_data[0].uartclk = orion5x_tclk;
-
 	/*
 	 * Setup Orion address map
 	 */
diff -druN linux-2.6.39-libre/arch/arm/mach-orion5x/d2net-setup.c linux-3.0-rc7-libre/arch/arm/mach-orion5x/d2net-setup.c
--- linux-2.6.39-libre/arch/arm/mach-orion5x/d2net-setup.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-orion5x/d2net-setup.c	2011-07-11 19:51:52.000000000 -0400
@@ -267,28 +267,28 @@
  * General Setup
  ****************************************************************************/
 
-static struct orion5x_mpp_mode d2net_mpp_modes[] __initdata = {
-	{  0, MPP_GPIO },	/* Board ID (bit 0) */
-	{  1, MPP_GPIO },	/* Board ID (bit 1) */
-	{  2, MPP_GPIO },	/* Board ID (bit 2) */
-	{  3, MPP_GPIO },	/* SATA 0 power */
-	{  4, MPP_UNUSED },
-	{  5, MPP_GPIO },	/* Fan fail detection */
-	{  6, MPP_GPIO },	/* Red front LED */
-	{  7, MPP_UNUSED },
-	{  8, MPP_GPIO },	/* Rear power switch (on|auto) */
-	{  9, MPP_GPIO },	/* Rear power switch (auto|off) */
-	{ 10, MPP_UNUSED },
-	{ 11, MPP_UNUSED },
-	{ 12, MPP_GPIO },	/* SATA 1 power */
-	{ 13, MPP_UNUSED },
-	{ 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 ) */
-	{ 19, MPP_UNUSED },
-	{ -1 }
+static unsigned int d2net_mpp_modes[] __initdata = {
+	MPP0_GPIO,	/* Board ID (bit 0) */
+	MPP1_GPIO,	/* Board ID (bit 1) */
+	MPP2_GPIO,	/* Board ID (bit 2) */
+	MPP3_GPIO,	/* SATA 0 power */
+	MPP4_UNUSED,
+	MPP5_GPIO,	/* Fan fail detection */
+	MPP6_GPIO,	/* Red front LED */
+	MPP7_UNUSED,
+	MPP8_GPIO,	/* Rear power switch (on|auto) */
+	MPP9_GPIO,	/* Rear power switch (auto|off) */
+	MPP10_UNUSED,
+	MPP11_UNUSED,
+	MPP12_GPIO,	/* SATA 1 power */
+	MPP13_UNUSED,
+	MPP14_SATA_LED,	/* SATA 0 active */
+	MPP15_SATA_LED,	/* SATA 1 active */
+	MPP16_GPIO,	/* Blue front LED blink control */
+	MPP17_UNUSED,
+	MPP18_GPIO,	/* Front button (0 = Released, 1 = Pushed ) */
+	MPP19_UNUSED,
+	0,
 	/* 22: USB port 1 fuse (0 = Fail, 1 = Ok) */
 	/* 23: Blue front LED off */
 	/* 24: Inhibit board power off (0 = Disabled, 1 = Enabled) */
diff -druN linux-2.6.39-libre/arch/arm/mach-orion5x/db88f5281-setup.c linux-3.0-rc7-libre/arch/arm/mach-orion5x/db88f5281-setup.c
--- linux-2.6.39-libre/arch/arm/mach-orion5x/db88f5281-setup.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-orion5x/db88f5281-setup.c	2011-07-11 19:51:52.000000000 -0400
@@ -298,28 +298,28 @@
 /*****************************************************************************
  * General Setup
  ****************************************************************************/
-static struct orion5x_mpp_mode db88f5281_mpp_modes[] __initdata = {
-	{  0, MPP_GPIO },		/* USB Over Current */
-	{  1, MPP_GPIO },		/* USB Vbat input */
-	{  2, MPP_PCI_ARB },		/* PCI_REQn[2] */
-	{  3, MPP_PCI_ARB },		/* PCI_GNTn[2] */
-	{  4, MPP_PCI_ARB },		/* PCI_REQn[3] */
-	{  5, MPP_PCI_ARB },		/* PCI_GNTn[3] */
-	{  6, MPP_GPIO },		/* JP0, CON17.2 */
-	{  7, MPP_GPIO },		/* JP1, CON17.1 */
-	{  8, MPP_GPIO },		/* JP2, CON11.2 */
-	{  9, MPP_GPIO },		/* JP3, CON11.3 */
-	{ 10, MPP_GPIO },		/* RTC int */
-	{ 11, MPP_GPIO },		/* Baud Rate Generator */
-	{ 12, MPP_GPIO },		/* PCI int 1 */
-	{ 13, MPP_GPIO },		/* PCI int 2 */
-	{ 14, MPP_NAND },		/* NAND_REn[2] */
-	{ 15, MPP_NAND },		/* NAND_WEn[2] */
-	{ 16, MPP_UART },		/* UART1_RX */
-	{ 17, MPP_UART },		/* UART1_TX */
-	{ 18, MPP_UART },		/* UART1_CTSn */
-	{ 19, MPP_UART },		/* UART1_RTSn */
-	{ -1 },
+static unsigned int db88f5281_mpp_modes[] __initdata = {
+	MPP0_GPIO,		/* USB Over Current */
+	MPP1_GPIO,		/* USB Vbat input */
+	MPP2_PCI_ARB,		/* PCI_REQn[2] */
+	MPP3_PCI_ARB,		/* PCI_GNTn[2] */
+	MPP4_PCI_ARB,		/* PCI_REQn[3] */
+	MPP5_PCI_ARB,		/* PCI_GNTn[3] */
+	MPP6_GPIO,		/* JP0, CON17.2 */
+	MPP7_GPIO,		/* JP1, CON17.1 */
+	MPP8_GPIO,		/* JP2, CON11.2 */
+	MPP9_GPIO,		/* JP3, CON11.3 */
+	MPP10_GPIO,		/* RTC int */
+	MPP11_GPIO,		/* Baud Rate Generator */
+	MPP12_GPIO,		/* PCI int 1 */
+	MPP13_GPIO,		/* PCI int 2 */
+	MPP14_NAND,		/* NAND_REn[2] */
+	MPP15_NAND,		/* NAND_WEn[2] */
+	MPP16_UART,		/* UART1_RX */
+	MPP17_UART,		/* UART1_TX */
+	MPP18_UART,		/* UART1_CTSn */
+	MPP19_UART,		/* UART1_RTSn */
+	0,
 };
 
 static void __init db88f5281_init(void)
diff -druN linux-2.6.39-libre/arch/arm/mach-orion5x/dns323-setup.c linux-3.0-rc7-libre/arch/arm/mach-orion5x/dns323-setup.c
--- linux-2.6.39-libre/arch/arm/mach-orion5x/dns323-setup.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-orion5x/dns323-setup.c	2011-07-11 19:51:52.000000000 -0400
@@ -385,76 +385,76 @@
 /****************************************************************************
  * General Setup
  */
-static struct orion5x_mpp_mode dns323a_mpp_modes[] __initdata = {
-	{  0, MPP_PCIE_RST_OUTn },
-	{  1, MPP_GPIO },		/* right amber LED (sata ch0) */
-	{  2, MPP_GPIO },		/* left amber LED (sata ch1) */
-	{  3, MPP_UNUSED },
-	{  4, MPP_GPIO },		/* power button LED */
-	{  5, MPP_GPIO },		/* power button LED */
-	{  6, MPP_GPIO },		/* GMT G751-2f overtemp */
-	{  7, MPP_GPIO },		/* M41T80 nIRQ/OUT/SQW */
-	{  8, MPP_GPIO },		/* triggers power off */
-	{  9, MPP_GPIO },		/* power button switch */
-	{ 10, MPP_GPIO },		/* reset button switch */
-	{ 11, MPP_UNUSED },
-	{ 12, MPP_UNUSED },
-	{ 13, MPP_UNUSED },
-	{ 14, MPP_UNUSED },
-	{ 15, MPP_UNUSED },
-	{ 16, MPP_UNUSED },
-	{ 17, MPP_UNUSED },
-	{ 18, MPP_UNUSED },
-	{ 19, MPP_UNUSED },
-	{ -1 },
+static unsigned int dns323a_mpp_modes[] __initdata = {
+	MPP0_PCIE_RST_OUTn,
+	MPP1_GPIO,		/* right amber LED (sata ch0) */
+	MPP2_GPIO,		/* left amber LED (sata ch1) */
+	MPP3_UNUSED,
+	MPP4_GPIO,		/* power button LED */
+	MPP5_GPIO,		/* power button LED */
+	MPP6_GPIO,		/* GMT G751-2f overtemp */
+	MPP7_GPIO,		/* M41T80 nIRQ/OUT/SQW */
+	MPP8_GPIO,		/* triggers power off */
+	MPP9_GPIO,		/* power button switch */
+	MPP10_GPIO,		/* reset button switch */
+	MPP11_UNUSED,
+	MPP12_UNUSED,
+	MPP13_UNUSED,
+	MPP14_UNUSED,
+	MPP15_UNUSED,
+	MPP16_UNUSED,
+	MPP17_UNUSED,
+	MPP18_UNUSED,
+	MPP19_UNUSED,
+	0,
 };
 
-static struct orion5x_mpp_mode dns323b_mpp_modes[] __initdata = {
-	{  0, MPP_UNUSED },
-	{  1, MPP_GPIO },		/* right amber LED (sata ch0) */
-	{  2, MPP_GPIO },		/* left amber LED (sata ch1) */
-	{  3, MPP_GPIO },		/* system up flag */
-	{  4, MPP_GPIO },		/* power button LED */
-	{  5, MPP_GPIO },		/* power button LED */
-	{  6, MPP_GPIO },		/* GMT G751-2f overtemp */
-	{  7, MPP_GPIO },		/* M41T80 nIRQ/OUT/SQW */
-	{  8, MPP_GPIO },		/* triggers power off */
-	{  9, MPP_GPIO },		/* power button switch */
-	{ 10, MPP_GPIO },		/* reset button switch */
-	{ 11, MPP_UNUSED },
-	{ 12, MPP_SATA_LED },
-	{ 13, MPP_SATA_LED },
-	{ 14, MPP_SATA_LED },
-	{ 15, MPP_SATA_LED },
-	{ 16, MPP_UNUSED },
-	{ 17, MPP_UNUSED },
-	{ 18, MPP_UNUSED },
-	{ 19, MPP_UNUSED },
-	{ -1 },
+static unsigned int dns323b_mpp_modes[] __initdata = {
+	MPP0_UNUSED,
+	MPP1_GPIO,		/* right amber LED (sata ch0) */
+	MPP2_GPIO,		/* left amber LED (sata ch1) */
+	MPP3_GPIO,		/* system up flag */
+	MPP4_GPIO,		/* power button LED */
+	MPP5_GPIO,		/* power button LED */
+	MPP6_GPIO,		/* GMT G751-2f overtemp */
+	MPP7_GPIO,		/* M41T80 nIRQ/OUT/SQW */
+	MPP8_GPIO,		/* triggers power off */
+	MPP9_GPIO,		/* power button switch */
+	MPP10_GPIO,		/* reset button switch */
+	MPP11_UNUSED,
+	MPP12_SATA_LED,
+	MPP13_SATA_LED,
+	MPP14_SATA_LED,
+	MPP15_SATA_LED,
+	MPP16_UNUSED,
+	MPP17_UNUSED,
+	MPP18_UNUSED,
+	MPP19_UNUSED,
+	0,
 };
 
-static struct orion5x_mpp_mode dns323c_mpp_modes[] __initdata = {
-	{  0, MPP_GPIO },		/* ? input */
-	{  1, MPP_GPIO },		/* input power switch (0 = pressed) */
-	{  2, MPP_GPIO },		/* output power off */
-	{  3, MPP_UNUSED },		/* ? output */
-	{  4, MPP_UNUSED },		/* ? output */
-	{  5, MPP_UNUSED },		/* ? output */
-	{  6, MPP_UNUSED },		/* ? output */
-	{  7, MPP_UNUSED },		/* ? output */
-	{  8, MPP_GPIO },		/* i/o right amber LED */
-	{  9, MPP_GPIO },		/* i/o left amber LED */
-	{ 10, MPP_GPIO },		/* input */
-	{ 11, MPP_UNUSED },
-	{ 12, MPP_SATA_LED },
-	{ 13, MPP_SATA_LED },
-	{ 14, MPP_SATA_LED },
-	{ 15, MPP_SATA_LED },
-	{ 16, MPP_UNUSED },
-	{ 17, MPP_GPIO },		/* power button LED */
-	{ 18, MPP_GPIO },		/* fan speed bit 0 */
-	{ 19, MPP_GPIO },		/* fan speed bit 1 */
-	{ -1 },
+static unsigned int dns323c_mpp_modes[] __initdata = {
+	MPP0_GPIO,		/* ? input */
+	MPP1_GPIO,		/* input power switch (0 = pressed) */
+	MPP2_GPIO,		/* output power off */
+	MPP3_UNUSED,		/* ? output */
+	MPP4_UNUSED,		/* ? output */
+	MPP5_UNUSED,		/* ? output */
+	MPP6_UNUSED,		/* ? output */
+	MPP7_UNUSED,		/* ? output */
+	MPP8_GPIO,		/* i/o right amber LED */
+	MPP9_GPIO,		/* i/o left amber LED */
+	MPP10_GPIO,		/* input */
+	MPP11_UNUSED,
+	MPP12_SATA_LED,
+	MPP13_SATA_LED,
+	MPP14_SATA_LED,
+	MPP15_SATA_LED,
+	MPP16_UNUSED,
+	MPP17_GPIO,		/* power button LED */
+	MPP18_GPIO,		/* fan speed bit 0 */
+	MPP19_GPIO,		/* fan speed bit 1 */
+	0,
 };
 
 /* Rev C1 Fan speed notes:
diff -druN linux-2.6.39-libre/arch/arm/mach-orion5x/edmini_v2-setup.c linux-3.0-rc7-libre/arch/arm/mach-orion5x/edmini_v2-setup.c
--- linux-2.6.39-libre/arch/arm/mach-orion5x/edmini_v2-setup.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-orion5x/edmini_v2-setup.c	2011-07-11 19:51:52.000000000 -0400
@@ -180,31 +180,31 @@
 /*****************************************************************************
  * General Setup
  ****************************************************************************/
-static struct orion5x_mpp_mode edminiv2_mpp_modes[] __initdata = {
-	{  0, MPP_UNUSED },
-	{  1, MPP_UNUSED },
-	{  2, MPP_UNUSED },
-	{  3, MPP_GPIO },	/* RTC interrupt */
-	{  4, MPP_UNUSED },
-	{  5, MPP_UNUSED },
-	{  6, MPP_UNUSED },
-	{  7, MPP_UNUSED },
-	{  8, MPP_UNUSED },
-	{  9, MPP_UNUSED },
-	{ 10, MPP_UNUSED },
-	{ 11, MPP_UNUSED },
-	{ 12, MPP_SATA_LED },	/* SATA 0 presence */
-	{ 13, MPP_SATA_LED },	/* SATA 1 presence */
-	{ 14, MPP_SATA_LED },	/* SATA 0 active */
-	{ 15, MPP_SATA_LED },	/* SATA 1 active */
+static unsigned int edminiv2_mpp_modes[] __initdata = {
+	MPP0_UNUSED,
+	MPP1_UNUSED,
+	MPP2_UNUSED,
+	MPP3_GPIO,	/* RTC interrupt */
+	MPP4_UNUSED,
+	MPP5_UNUSED,
+	MPP6_UNUSED,
+	MPP7_UNUSED,
+	MPP8_UNUSED,
+	MPP9_UNUSED,
+	MPP10_UNUSED,
+	MPP11_UNUSED,
+	MPP12_SATA_LED,	/* SATA 0 presence */
+	MPP13_SATA_LED,	/* SATA 1 presence */
+	MPP14_SATA_LED,	/* SATA 0 active */
+	MPP15_SATA_LED,	/* SATA 1 active */
 	/* 16: Power LED control (0 = On, 1 = Off) */
-	{ 16, MPP_GPIO },
+	MPP16_GPIO,
 	/* 17: Power LED control select (0 = CPLD, 1 = GPIO16) */
-	{ 17, MPP_GPIO },
+	MPP17_GPIO,
 	/* 18: Power button status (0 = Released, 1 = Pressed) */
-	{ 18, MPP_GPIO },
-	{ 19, MPP_UNUSED },
-	{ -1 }
+	MPP18_GPIO,
+	MPP19_UNUSED,
+	0,
 };
 
 static void __init edmini_v2_init(void)
diff -druN linux-2.6.39-libre/arch/arm/mach-orion5x/kurobox_pro-setup.c linux-3.0-rc7-libre/arch/arm/mach-orion5x/kurobox_pro-setup.c
--- linux-2.6.39-libre/arch/arm/mach-orion5x/kurobox_pro-setup.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-orion5x/kurobox_pro-setup.c	2011-07-11 19:51:52.000000000 -0400
@@ -315,28 +315,28 @@
 /*****************************************************************************
  * General Setup
  ****************************************************************************/
-static struct orion5x_mpp_mode kurobox_pro_mpp_modes[] __initdata = {
-	{  0, MPP_UNUSED },
-	{  1, MPP_UNUSED },
-	{  2, MPP_GPIO },		/* GPIO Micon */
-	{  3, MPP_GPIO },		/* GPIO Rtc */
-	{  4, MPP_UNUSED },
-	{  5, MPP_UNUSED },
-	{  6, MPP_NAND },		/* NAND Flash REn */
-	{  7, MPP_NAND },		/* NAND Flash WEn */
-	{  8, MPP_UNUSED },
-	{  9, MPP_UNUSED },
-	{ 10, MPP_UNUSED },
-	{ 11, MPP_UNUSED },
-	{ 12, MPP_SATA_LED },		/* SATA 0 presence */
-	{ 13, MPP_SATA_LED },		/* SATA 1 presence */
-	{ 14, MPP_SATA_LED },		/* SATA 0 active */
-	{ 15, MPP_SATA_LED },		/* SATA 1 active */
-	{ 16, MPP_UART },		/* UART1 RXD */
-	{ 17, MPP_UART },		/* UART1 TXD */
-	{ 18, MPP_UART },		/* UART1 CTSn */
-	{ 19, MPP_UART },		/* UART1 RTSn */
-	{ -1 },
+static unsigned int kurobox_pro_mpp_modes[] __initdata = {
+	MPP0_UNUSED,
+	MPP1_UNUSED,
+	MPP2_GPIO,		/* GPIO Micon */
+	MPP3_GPIO,		/* GPIO Rtc */
+	MPP4_UNUSED,
+	MPP5_UNUSED,
+	MPP6_NAND,		/* NAND Flash REn */
+	MPP7_NAND,		/* NAND Flash WEn */
+	MPP8_UNUSED,
+	MPP9_UNUSED,
+	MPP10_UNUSED,
+	MPP11_UNUSED,
+	MPP12_SATA_LED,		/* SATA 0 presence */
+	MPP13_SATA_LED,		/* SATA 1 presence */
+	MPP14_SATA_LED,		/* SATA 0 active */
+	MPP15_SATA_LED,		/* SATA 1 active */
+	MPP16_UART,		/* UART1 RXD */
+	MPP17_UART,		/* UART1 TXD */
+	MPP18_UART,		/* UART1 CTSn */
+	MPP19_UART,		/* UART1 RTSn */
+	0,
 };
 
 static void __init kurobox_pro_init(void)
diff -druN linux-2.6.39-libre/arch/arm/mach-orion5x/ls-chl-setup.c linux-3.0-rc7-libre/arch/arm/mach-orion5x/ls-chl-setup.c
--- linux-2.6.39-libre/arch/arm/mach-orion5x/ls-chl-setup.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-orion5x/ls-chl-setup.c	2011-07-11 19:51:52.000000000 -0400
@@ -251,28 +251,28 @@
  * GPIO Data
  ****************************************************************************/
 
-static struct orion5x_mpp_mode lschl_mpp_modes[] __initdata = {
-	{  0, MPP_GPIO }, /* LED POWER */
-	{  1, MPP_GPIO }, /* HDD POWER */
-	{  2, MPP_GPIO }, /* LED ALARM */
-	{  3, MPP_GPIO }, /* LED INFO */
-	{  4, MPP_UNUSED },
-	{  5, MPP_UNUSED },
-	{  6, MPP_GPIO }, /* FAN LOCK */
-	{  7, MPP_GPIO }, /* SW INIT */
-	{  8, MPP_GPIO }, /* SW POWER */
-	{  9, MPP_GPIO }, /* USB POWER */
-	{ 10, MPP_GPIO }, /* SW AUTO POWER */
-	{ 11, MPP_UNUSED },
-	{ 12, MPP_UNUSED },
-	{ 13, MPP_UNUSED },
-	{ 14, MPP_GPIO }, /* FAN HIGH */
-	{ 15, MPP_GPIO }, /* SW FUNC */
-	{ 16, MPP_GPIO }, /* FAN LOW */
-	{ 17, MPP_GPIO }, /* LED FUNC */
-	{ 18, MPP_UNUSED },
-	{ 19, MPP_UNUSED },
-	{ -1 },
+static unsigned int lschl_mpp_modes[] __initdata = {
+	MPP0_GPIO, /* LED POWER */
+	MPP1_GPIO, /* HDD POWER */
+	MPP2_GPIO, /* LED ALARM */
+	MPP3_GPIO, /* LED INFO */
+	MPP4_UNUSED,
+	MPP5_UNUSED,
+	MPP6_GPIO, /* FAN LOCK */
+	MPP7_GPIO, /* SW INIT */
+	MPP8_GPIO, /* SW POWER */
+	MPP9_GPIO, /* USB POWER */
+	MPP10_GPIO, /* SW AUTO POWER */
+	MPP11_UNUSED,
+	MPP12_UNUSED,
+	MPP13_UNUSED,
+	MPP14_GPIO, /* FAN HIGH */
+	MPP15_GPIO, /* SW FUNC */
+	MPP16_GPIO, /* FAN LOW */
+	MPP17_GPIO, /* LED FUNC */
+	MPP18_UNUSED,
+	MPP19_UNUSED,
+	0,
 };
 
 static void __init lschl_init(void)
diff -druN linux-2.6.39-libre/arch/arm/mach-orion5x/ls_hgl-setup.c linux-3.0-rc7-libre/arch/arm/mach-orion5x/ls_hgl-setup.c
--- linux-2.6.39-libre/arch/arm/mach-orion5x/ls_hgl-setup.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-orion5x/ls_hgl-setup.c	2011-07-11 19:51:52.000000000 -0400
@@ -200,28 +200,28 @@
 
 #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 unsigned int ls_hgl_mpp_modes[] __initdata = {
+	MPP0_GPIO, /* LED_PWR */
+	MPP1_GPIO, /* HDD_PWR */
+	MPP2_GPIO, /* LED_ALARM */
+	MPP3_GPIO, /* LED_INFO */
+	MPP4_UNUSED,
+	MPP5_UNUSED,
+	MPP6_GPIO, /* FAN_LCK */
+	MPP7_GPIO, /* INIT */
+	MPP8_GPIO, /* POWER */
+	MPP9_GPIO, /* USB_PWR */
+	MPP10_GPIO, /* AUTO_POWER */
+	MPP11_UNUSED, /* LED_ETH (dummy) */
+	MPP12_UNUSED,
+	MPP13_UNUSED,
+	MPP14_UNUSED,
+	MPP15_GPIO, /* FUNC */
+	MPP16_UNUSED,
+	MPP17_GPIO, /* LED_FUNC */
+	MPP18_UNUSED,
+	MPP19_UNUSED,
+	0,
 };
 
 static void __init ls_hgl_init(void)
diff -druN linux-2.6.39-libre/arch/arm/mach-orion5x/lsmini-setup.c linux-3.0-rc7-libre/arch/arm/mach-orion5x/lsmini-setup.c
--- linux-2.6.39-libre/arch/arm/mach-orion5x/lsmini-setup.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-orion5x/lsmini-setup.c	2011-07-11 19:51:52.000000000 -0400
@@ -201,28 +201,28 @@
 #define LSMINI_GPIO_HDD_POWER0	1
 #define LSMINI_GPIO_HDD_POWER1	19
 
-static struct orion5x_mpp_mode lsmini_mpp_modes[] __initdata = {
-	{  0, MPP_UNUSED }, /* LED_RESERVE1 (unused) */
-	{  1, MPP_GPIO }, /* HDD_PWR */
-	{  2, MPP_GPIO }, /* LED_ALARM */
-	{  3, MPP_GPIO }, /* LED_INFO */
-	{  4, MPP_UNUSED },
-	{  5, MPP_UNUSED },
-	{  6, MPP_UNUSED },
-	{  7, MPP_UNUSED },
-	{  8, MPP_UNUSED },
-	{  9, MPP_GPIO }, /* LED_FUNC */
-	{ 10, MPP_UNUSED },
-	{ 11, MPP_UNUSED }, /* LED_ETH (dummy) */
-	{ 12, MPP_UNUSED },
-	{ 13, MPP_UNUSED },
-	{ 14, MPP_GPIO }, /* LED_PWR */
-	{ 15, MPP_GPIO }, /* FUNC */
-	{ 16, MPP_GPIO }, /* USB_PWR */
-	{ 17, MPP_GPIO }, /* AUTO_POWER */
-	{ 18, MPP_GPIO }, /* POWER */
-	{ 19, MPP_GPIO }, /* HDD_PWR1 */
-	{ -1 },
+static unsigned int lsmini_mpp_modes[] __initdata = {
+	MPP0_UNUSED, /* LED_RESERVE1 (unused) */
+	MPP1_GPIO, /* HDD_PWR */
+	MPP2_GPIO, /* LED_ALARM */
+	MPP3_GPIO, /* LED_INFO */
+	MPP4_UNUSED,
+	MPP5_UNUSED,
+	MPP6_UNUSED,
+	MPP7_UNUSED,
+	MPP8_UNUSED,
+	MPP9_GPIO, /* LED_FUNC */
+	MPP10_UNUSED,
+	MPP11_UNUSED, /* LED_ETH (dummy) */
+	MPP12_UNUSED,
+	MPP13_UNUSED,
+	MPP14_GPIO, /* LED_PWR */
+	MPP15_GPIO, /* FUNC */
+	MPP16_GPIO, /* USB_PWR */
+	MPP17_GPIO, /* AUTO_POWER */
+	MPP18_GPIO, /* POWER */
+	MPP19_GPIO, /* HDD_PWR1 */
+	0,
 };
 
 static void __init lsmini_init(void)
diff -druN linux-2.6.39-libre/arch/arm/mach-orion5x/mpp.c linux-3.0-rc7-libre/arch/arm/mach-orion5x/mpp.c
--- linux-2.6.39-libre/arch/arm/mach-orion5x/mpp.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-orion5x/mpp.c	2011-07-11 19:51:52.000000000 -0400
@@ -12,154 +12,34 @@
 #include <linux/init.h>
 #include <linux/mbus.h>
 #include <linux/io.h>
-#include <asm/gpio.h>
 #include <mach/hardware.h>
-#include "common.h"
+#include <plat/mpp.h>
 #include "mpp.h"
+#include "common.h"
 
-static int is_5181l(void)
-{
-	u32 dev;
-	u32 rev;
-
-	orion5x_pcie_id(&dev, &rev);
-
-	return !!(dev == MV88F5181_DEV_ID && rev >= MV88F5181L_REV_A0);
-}
-
-static int is_5182(void)
-{
-	u32 dev;
-	u32 rev;
-
-	orion5x_pcie_id(&dev, &rev);
-
-	return !!(dev == MV88F5182_DEV_ID);
-}
-
-static int is_5281(void)
+static unsigned int __init orion5x_variant(void)
 {
 	u32 dev;
 	u32 rev;
 
 	orion5x_pcie_id(&dev, &rev);
 
-	return !!(dev == MV88F5281_DEV_ID);
-}
-
-static int __init determine_type_encoding(int mpp, enum orion5x_mpp_type type)
-{
-	switch (type) {
-	case MPP_UNUSED:
-	case MPP_GPIO:
-		if (mpp == 0)
-			return 3;
-		if (mpp >= 1 && mpp <= 15)
-			return 0;
-		if (mpp >= 16 && mpp <= 19) {
-			if (is_5182())
-				return 5;
-			if (type == MPP_UNUSED)
-				return 0;
-		}
-		return -1;
-
-	case MPP_PCIE_RST_OUTn:
-		if (mpp == 0)
-			return 0;
-		return -1;
-
-	case MPP_PCI_ARB:
-		if (mpp >= 0 && mpp <= 7)
-			return 2;
-		return -1;
-
-	case MPP_PCI_PMEn:
-		if (mpp == 2)
-			return 3;
-		return -1;
-
-	case MPP_GIGE:
-		if (mpp >= 8 && mpp <= 19)
-			return 1;
-		return -1;
-
-	case MPP_NAND:
-		if (is_5182() || is_5281()) {
-			if (mpp >= 4 && mpp <= 7)
-				return 4;
-			if (mpp >= 12 && mpp <= 17)
-				return 4;
-		}
-		return -1;
-
-	case MPP_PCI_CLK:
-		if (is_5181l() && mpp >= 6 && mpp <= 7)
-			return 5;
-		return -1;
-
-	case MPP_SATA_LED:
-		if (is_5182()) {
-			if (mpp >= 4 && mpp <= 7)
-				return 5;
-			if (mpp >= 12 && mpp <= 15)
-				return 5;
-		}
-		return -1;
+	if (dev == MV88F5181_DEV_ID && rev >= MV88F5181L_REV_A0)
+		return MPP_F5181_MASK;
 
-	case MPP_UART:
-		if (mpp >= 16 && mpp <= 19)
-			return 0;
-		return -1;
-	}
+	if (dev == MV88F5182_DEV_ID)
+		return MPP_F5182_MASK;
 
-	printk(KERN_INFO "unknown MPP type %d\n", type);
+	if (dev == MV88F5281_DEV_ID)
+		return MPP_F5281_MASK;
 
-	return -1;
+	printk(KERN_ERR "MPP setup: unknown orion5x variant "
+	       "(dev %#x rev %#x)\n", dev, rev);
+	return 0;
 }
 
-void __init orion5x_mpp_conf(struct orion5x_mpp_mode *mode)
+void __init orion5x_mpp_conf(unsigned int *mpp_list)
 {
-	u32 mpp_0_7_ctrl = readl(MPP_0_7_CTRL);
-	u32 mpp_8_15_ctrl = readl(MPP_8_15_CTRL);
-	u32 mpp_16_19_ctrl = readl(MPP_16_19_CTRL);
-
-	for ( ; mode->mpp >= 0; mode++) {
-		u32 *reg;
-		int num_type;
-		int shift;
-
-		if (mode->mpp >= 0 && mode->mpp <= 7)
-			reg = &mpp_0_7_ctrl;
-		else if (mode->mpp >= 8 && mode->mpp <= 15)
-			reg = &mpp_8_15_ctrl;
-		else if (mode->mpp >= 16 && mode->mpp <= 19)
-			reg = &mpp_16_19_ctrl;
-		else {
-			printk(KERN_ERR "orion5x_mpp_conf: invalid MPP "
-					"(%d)\n", mode->mpp);
-			continue;
-		}
-
-		num_type = determine_type_encoding(mode->mpp, mode->type);
-		if (num_type < 0) {
-			printk(KERN_ERR "orion5x_mpp_conf: invalid MPP "
-					"combination (%d, %d)\n", mode->mpp,
-					mode->type);
-			continue;
-		}
-
-		shift = (mode->mpp & 7) << 2;
-		*reg &= ~(0xf << shift);
-		*reg |= (num_type & 0xf) << shift;
-
-		if (mode->type == MPP_UNUSED && (mode->mpp < 16 || is_5182()))
-			orion_gpio_set_unused(mode->mpp);
-
-		orion_gpio_set_valid(mode->mpp, !!(mode->type == MPP_GPIO));
-	}
-
-	writel(mpp_0_7_ctrl, MPP_0_7_CTRL);
-	writel(mpp_8_15_ctrl, MPP_8_15_CTRL);
-	writel(mpp_16_19_ctrl, MPP_16_19_CTRL);
+	orion_mpp_conf(mpp_list, orion5x_variant(),
+		       MPP_MAX, ORION5X_DEV_BUS_VIRT_BASE);
 }
diff -druN linux-2.6.39-libre/arch/arm/mach-orion5x/mpp.h linux-3.0-rc7-libre/arch/arm/mach-orion5x/mpp.h
--- linux-2.6.39-libre/arch/arm/mach-orion5x/mpp.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-orion5x/mpp.h	2011-07-11 19:51:52.000000000 -0400
@@ -1,74 +1,129 @@
 #ifndef __ARCH_ORION5X_MPP_H
 #define __ARCH_ORION5X_MPP_H
 
-enum orion5x_mpp_type {
-	/*
-	 * This MPP is unused.
-	 */
-	MPP_UNUSED,
+#define MPP(_num, _sel, _in, _out, _F5181l, _F5182, _F5281) ( \
+	/* MPP number */		((_num) & 0xff) | \
+	/* MPP select value */		(((_sel) & 0xf) << 8) | \
+	/* may be input signal */	((!!(_in)) << 12) | \
+	/* may be output signal */	((!!(_out)) << 13) | \
+	/* available on F5181l */	((!!(_F5181l)) << 14) | \
+	/* available on F5182 */	((!!(_F5182)) << 15) | \
+	/* available on F5281 */	((!!(_F5281)) << 16))
 
-	/*
-	 * This MPP pin is used as a generic GPIO pin.  Valid for
-	 * MPPs 0-15 and device bus data pins 16-31.  On 5182, also
-	 * valid for MPPs 16-19.
-	 */
-	MPP_GPIO,
+				/* num sel  i  o  5181 5182 5281 */
 
-	/*
-	 * This MPP is used as PCIe_RST_OUTn pin.  Valid for
-	 * MPP 0 only.
-	 */
-	MPP_PCIE_RST_OUTn,
+#define MPP_F5181_MASK		MPP(0,  0x0, 0, 0, 1,   0,   0)
+#define MPP_F5182_MASK		MPP(0,  0x0, 0, 0, 0,   1,   0)
+#define MPP_F5281_MASK		MPP(0,  0x0, 0, 0, 0,   0,   1)
 
-	/*
-	 * This MPP is used as PCI arbiter pin (REQn/GNTn).
-	 * Valid for MPPs 0-7 only.
-	 */
-	MPP_PCI_ARB,
+#define MPP0_UNUSED	        MPP(0,  0x3, 0, 0, 1,   1,   1)
+#define MPP0_GPIO		MPP(0,  0x3, 1, 1, 1,   1,   1)
+#define MPP0_PCIE_RST_OUTn	MPP(0,  0x0, 0, 0, 1,   1,   1)
+#define MPP0_PCI_ARB            MPP(0,  0x2, 0, 0, 1,   1,   1)
 
-	/*
-	 * This MPP is used as PCI_PMEn pin.  Valid for MPP 2 only.
-	 */
-	MPP_PCI_PMEn,
+#define MPP1_UNUSED		MPP(1,  0x0, 0, 0, 1,   1,   1)
+#define MPP1_GPIO		MPP(1,  0x0, 1, 1, 1,   1,   1)
+#define MPP1_PCI_ARB            MPP(1,  0x2, 0, 0, 1,   1,   1)
 
-	/*
-	 * This MPP is used as GigE half-duplex (COL, CRS) or GMII
-	 * (RXERR, CRS, TXERR, TXD[7:4], RXD[7:4]) pin.  Valid for
-	 * MPPs 8-19 only.
-	 */
-	MPP_GIGE,
+#define MPP2_UNUSED		MPP(2,  0x0, 0, 0, 1,   1,   1)
+#define MPP2_GPIO		MPP(2,  0x0, 1, 1, 1,   1,   1)
+#define MPP2_PCI_ARB            MPP(2,  0x2, 0, 0, 1,   1,   1)
+#define MPP2_PCI_PMEn           MPP(2,  0x3, 0, 0, 1,   1,   1)
 
-	/*
-	 * This MPP is used as NAND REn/WEn pin.  Valid for MPPs
-	 * 4-7 and 12-17 only, and only on the 5181l/5182/5281.
-	 */
-	MPP_NAND,
+#define MPP3_UNUSED		MPP(3,  0x0, 0, 0, 1,   1,   1)
+#define MPP3_GPIO		MPP(3,  0x0, 1, 1, 1,   1,   1)
+#define MPP3_PCI_ARB            MPP(3,  0x2, 0, 0, 1,   1,   1)
 
-	/*
-	 * This MPP is used as a PCI clock output pin.  Valid for
-	 * MPPs 6-7 only, and only on the 5181l.
-	 */
-	MPP_PCI_CLK,
+#define MPP4_UNUSED		MPP(4,  0x0, 0, 0, 1,   1,   1)
+#define MPP4_GPIO		MPP(4,  0x0, 1, 1, 1,   1,   1)
+#define MPP4_PCI_ARB            MPP(4,  0x2, 0, 0, 1,   1,   1)
+#define MPP4_NAND               MPP(4,  0x4, 0, 0, 0,   1,   1)
+#define MPP4_SATA_LED           MPP(4,  0x5, 0, 0, 0,   1,   0)
 
-	/*
-	 * This MPP is used as a SATA presence/activity LED.
-	 * Valid for MPPs 4-7 and 12-15 only, and only on the 5182.
-	 */
-	MPP_SATA_LED,
+#define MPP5_UNUSED		MPP(5,  0x0, 0, 0, 1,   1,   1)
+#define MPP5_GPIO		MPP(5,  0x0, 1, 1, 1,   1,   1)
+#define MPP5_PCI_ARB            MPP(5,  0x2, 0, 0, 1,   1,   1)
+#define MPP5_NAND               MPP(5,  0x4, 0, 0, 0,   1,   1)
+#define MPP5_SATA_LED           MPP(5,  0x5, 0, 0, 0,   1,   0)
 
-	/*
-	 * This MPP is used as UART1 RXD/TXD/CTSn/RTSn pin.
-	 * Valid for MPPs 16-19 only.
-	 */
-	MPP_UART,
-};
+#define MPP6_UNUSED		MPP(6,  0x0, 0, 0, 1,   1,   1)
+#define MPP6_GPIO		MPP(6,  0x0, 1, 1, 1,   1,   1)
+#define MPP6_PCI_ARB            MPP(6,  0x2, 0, 0, 1,   1,   1)
+#define MPP6_NAND               MPP(6,  0x4, 0, 0, 0,   1,   1)
+#define MPP6_PCI_CLK            MPP(6,  0x5, 0, 0, 1,   0,   0)
+#define MPP6_SATA_LED           MPP(6,  0x5, 0, 0, 0,   1,   0)
 
-struct orion5x_mpp_mode {
-	int			mpp;
-	enum orion5x_mpp_type	type;
-};
+#define MPP7_UNUSED		MPP(7,  0x0, 0, 0, 1,   1,   1)
+#define MPP7_GPIO		MPP(7,  0x0, 1, 1, 1,   1,   1)
+#define MPP7_PCI_ARB            MPP(7,  0x2, 0, 0, 1,   1,   1)
+#define MPP7_NAND               MPP(7,  0x4, 0, 0, 0,   1,   1)
+#define MPP7_PCI_CLK            MPP(7,  0x5, 0, 0, 1,   0,   0)
+#define MPP7_SATA_LED           MPP(7,  0x5, 0, 0, 0,   1,   0)
 
-void orion5x_mpp_conf(struct orion5x_mpp_mode *mode);
+#define MPP8_UNUSED		MPP(8,  0x0, 0, 0, 1,   1,   1)
+#define MPP8_GPIO		MPP(8,  0x0, 1, 1, 1,   1,   1)
+#define MPP8_GIGE               MPP(8,  0x1, 0, 0, 1,   1,   1)
+
+#define MPP9_UNUSED		MPP(9,  0x0, 0, 0, 1,   1,   1)
+#define MPP9_GPIO		MPP(9,  0x0, 0, 0, 1,   1,   1)
+#define MPP9_GIGE               MPP(9,  0x1, 1, 1, 1,   1,   1)
+
+#define MPP10_UNUSED		MPP(10, 0x0, 0, 0, 1,   1,   1)
+#define MPP10_GPIO		MPP(10, 0x0, 1, 1, 1,   1,   1)
+#define MPP10_GIGE              MPP(10, 0x1, 0, 0, 1,   1,   1)
+
+#define MPP11_UNUSED		MPP(11, 0x0, 0, 0, 1,   1,   1)
+#define MPP11_GPIO		MPP(11, 0x0, 1, 1, 1,   1,   1)
+#define MPP11_GIGE              MPP(11, 0x1, 0, 0, 1,   1,   1)
+
+#define MPP12_UNUSED		MPP(12, 0x0, 0, 0, 1,   1,   1)
+#define MPP12_GPIO		MPP(12, 0x0, 1, 1, 1,   1,   1)
+#define MPP12_GIGE              MPP(12, 0x1, 0, 0, 1,   1,   1)
+#define MPP12_NAND              MPP(12, 0x4, 0, 0, 0,   1,   1)
+#define MPP12_SATA_LED          MPP(12, 0x5, 0, 0, 0,   1,   0)
+
+#define MPP13_UNUSED		MPP(13, 0x0, 0, 0, 1,   1,   1)
+#define MPP13_GPIO		MPP(13, 0x0, 1, 1, 1,   1,   1)
+#define MPP13_GIGE              MPP(13, 0x1, 0, 0, 1,   1,   1)
+#define MPP13_NAND              MPP(13, 0x4, 0, 0, 0,   1,   1)
+#define MPP13_SATA_LED          MPP(13, 0x5, 0, 0, 0,   1,   0)
+
+#define MPP14_UNUSED		MPP(14, 0x0, 0, 0, 1,   1,   1)
+#define MPP14_GPIO		MPP(14, 0x0, 1, 1, 1,   1,   1)
+#define MPP14_GIGE              MPP(14, 0x1, 0, 0, 1,   1,   1)
+#define MPP14_NAND              MPP(14, 0x4, 0, 0, 0,   1,   1)
+#define MPP14_SATA_LED          MPP(14, 0x5, 0, 0, 0,   1,   0)
+
+#define MPP15_UNUSED		MPP(15, 0x0, 0, 0, 1,   1,   1)
+#define MPP15_GPIO		MPP(15, 0x0, 1, 1, 1,   1,   1)
+#define MPP15_GIGE              MPP(15, 0x1, 0, 0, 1,   1,   1)
+#define MPP15_NAND              MPP(15, 0x4, 0, 0, 0,   1,   1)
+#define MPP15_SATA_LED          MPP(15, 0x5, 0, 0, 0,   1,   0)
+
+#define MPP16_UNUSED		MPP(16, 0x0, 0, 0, 1,   1,   1)
+#define MPP16_GPIO		MPP(16, 0x5, 1, 1, 0,   1,   0)
+#define MPP16_GIGE              MPP(16, 0x1, 0, 0, 1,   1,   1)
+#define MPP16_NAND              MPP(16, 0x4, 0, 0, 0,   1,   1)
+#define MPP16_UART              MPP(16, 0x0, 0, 0, 0,   1,   1)
 
+#define MPP17_UNUSED		MPP(17, 0x0, 0, 0, 1,   1,   1)
+#define MPP17_GPIO		MPP(17, 0x5, 1, 1, 0,   1,   0)
+#define MPP17_GIGE              MPP(17, 0x1, 0, 0, 1,   1,   1)
+#define MPP17_NAND              MPP(17, 0x4, 0, 0, 0,   1,   1)
+#define MPP17_UART              MPP(17, 0x0, 0, 0, 0,   1,   1)
+
+#define MPP18_UNUSED		MPP(18, 0x0, 0, 0, 1,   1,   1)
+#define MPP18_GPIO		MPP(18, 0x5, 1, 1, 0,   1,   0)
+#define MPP18_GIGE              MPP(18, 0x1, 0, 0, 1,   1,   1)
+#define MPP18_UART              MPP(18, 0x0, 0, 0, 0,   1,   1)
+
+#define MPP19_UNUSED		MPP(19, 0x0, 0, 0, 1,   1,   1)
+#define MPP19_GPIO		MPP(19, 0x5, 1, 1, 0,   1,   0)
+#define MPP19_GIGE              MPP(19, 0x1, 0, 0, 1,   1,   1)
+#define MPP19_UART              MPP(19, 0x0, 0, 0, 0,   1,   1)
+
+#define MPP_MAX			19
+
+void orion5x_mpp_conf(unsigned int *mpp_list);
 
 #endif
diff -druN linux-2.6.39-libre/arch/arm/mach-orion5x/mss2-setup.c linux-3.0-rc7-libre/arch/arm/mach-orion5x/mss2-setup.c
--- linux-2.6.39-libre/arch/arm/mach-orion5x/mss2-setup.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-orion5x/mss2-setup.c	2011-07-11 19:51:52.000000000 -0400
@@ -193,28 +193,28 @@
 /****************************************************************************
  * General Setup
  ****************************************************************************/
-static struct orion5x_mpp_mode mss2_mpp_modes[] __initdata = {
-	{  0, MPP_GPIO },		/* Power LED */
-	{  1, MPP_GPIO },		/* Error LED */
-	{  2, MPP_UNUSED },
-	{  3, MPP_GPIO },		/* RTC interrupt */
-	{  4, MPP_GPIO },		/* HDD ind. (Single/Dual)*/
-	{  5, MPP_GPIO },		/* HD0 5V control */
-	{  6, MPP_GPIO },		/* HD0 12V control */
-	{  7, MPP_GPIO },		/* HD1 5V control */
-	{  8, MPP_GPIO },		/* HD1 12V control */
-	{  9, MPP_UNUSED },
-	{ 10, MPP_GPIO },		/* Fan control */
-	{ 11, MPP_GPIO },		/* Power button */
-	{ 12, MPP_GPIO },		/* Reset button */
-	{ 13, MPP_UNUSED },
-	{ 14, MPP_SATA_LED },		/* SATA 0 active */
-	{ 15, MPP_SATA_LED },		/* SATA 1 active */
-	{ 16, MPP_UNUSED },
-	{ 17, MPP_UNUSED },
-	{ 18, MPP_UNUSED },
-	{ 19, MPP_UNUSED },
-	{ -1 },
+static unsigned int mss2_mpp_modes[] __initdata = {
+	MPP0_GPIO,		/* Power LED */
+	MPP1_GPIO,		/* Error LED */
+	MPP2_UNUSED,
+	MPP3_GPIO,		/* RTC interrupt */
+	MPP4_GPIO,		/* HDD ind. (Single/Dual)*/
+	MPP5_GPIO,		/* HD0 5V control */
+	MPP6_GPIO,		/* HD0 12V control */
+	MPP7_GPIO,		/* HD1 5V control */
+	MPP8_GPIO,		/* HD1 12V control */
+	MPP9_UNUSED,
+	MPP10_GPIO,		/* Fan control */
+	MPP11_GPIO,		/* Power button */
+	MPP12_GPIO,		/* Reset button */
+	MPP13_UNUSED,
+	MPP14_SATA_LED,		/* SATA 0 active */
+	MPP15_SATA_LED,		/* SATA 1 active */
+	MPP16_UNUSED,
+	MPP17_UNUSED,
+	MPP18_UNUSED,
+	MPP19_UNUSED,
+	0,
 };
 
 static void __init mss2_init(void)
diff -druN linux-2.6.39-libre/arch/arm/mach-orion5x/mv2120-setup.c linux-3.0-rc7-libre/arch/arm/mach-orion5x/mv2120-setup.c
--- linux-2.6.39-libre/arch/arm/mach-orion5x/mv2120-setup.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-orion5x/mv2120-setup.c	2011-07-11 19:51:52.000000000 -0400
@@ -108,28 +108,28 @@
 /****************************************************************************
  * General Setup
  ****************************************************************************/
-static struct orion5x_mpp_mode mv2120_mpp_modes[] __initdata = {
-	{  0, MPP_GPIO },		/* Sys status LED */
-	{  1, MPP_GPIO },		/* Sys error LED */
-	{  2, MPP_GPIO },		/* OverTemp interrupt */
-	{  3, MPP_GPIO },		/* RTC interrupt */
-	{  4, MPP_GPIO },		/* V_LED 5V */
-	{  5, MPP_GPIO },		/* V_LED 3.3V */
-	{  6, MPP_UNUSED },
-	{  7, MPP_UNUSED },
-	{  8, MPP_GPIO },		/* SATA 0 fail LED */
-	{  9, MPP_GPIO },		/* SATA 1 fail LED */
-	{ 10, MPP_UNUSED },
-	{ 11, MPP_UNUSED },
-	{ 12, MPP_SATA_LED },		/* SATA 0 presence */
-	{ 13, MPP_SATA_LED },		/* SATA 1 presence */
-	{ 14, MPP_SATA_LED },		/* SATA 0 active */
-	{ 15, MPP_SATA_LED },		/* SATA 1 active */
-	{ 16, MPP_UNUSED },
-	{ 17, MPP_GPIO },		/* Reset button */
-	{ 18, MPP_GPIO },		/* Power button */
-	{ 19, MPP_GPIO },		/* Power off */
-	{ -1 },
+static unsigned int mv2120_mpp_modes[] __initdata = {
+	MPP0_GPIO,		/* Sys status LED */
+	MPP1_GPIO,		/* Sys error LED */
+	MPP2_GPIO,		/* OverTemp interrupt */
+	MPP3_GPIO,		/* RTC interrupt */
+	MPP4_GPIO,		/* V_LED 5V */
+	MPP5_GPIO,		/* V_LED 3.3V */
+	MPP6_UNUSED,
+	MPP7_UNUSED,
+	MPP8_GPIO,		/* SATA 0 fail LED */
+	MPP9_GPIO,		/* SATA 1 fail LED */
+	MPP10_UNUSED,
+	MPP11_UNUSED,
+	MPP12_SATA_LED,		/* SATA 0 presence */
+	MPP13_SATA_LED,		/* SATA 1 presence */
+	MPP14_SATA_LED,		/* SATA 0 active */
+	MPP15_SATA_LED,		/* SATA 1 active */
+	MPP16_UNUSED,
+	MPP17_GPIO,		/* Reset button */
+	MPP18_GPIO,		/* Power button */
+	MPP19_GPIO,		/* Power off */
+	0,
 };
 
 static struct i2c_board_info __initdata mv2120_i2c_rtc = {
diff -druN linux-2.6.39-libre/arch/arm/mach-orion5x/net2big-setup.c linux-3.0-rc7-libre/arch/arm/mach-orion5x/net2big-setup.c
--- linux-2.6.39-libre/arch/arm/mach-orion5x/net2big-setup.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-orion5x/net2big-setup.c	2011-07-11 19:51:52.000000000 -0400
@@ -339,28 +339,28 @@
  * General Setup
  ****************************************************************************/
 
-static struct orion5x_mpp_mode net2big_mpp_modes[] __initdata = {
-	{  0, MPP_GPIO },	/* Raid mode (bit 0) */
-	{  1, MPP_GPIO },	/* USB port 2 fuse (0 = Fail, 1 = Ok) */
-	{  2, MPP_GPIO },	/* Raid mode (bit 1) */
-	{  3, MPP_GPIO },	/* Board ID (bit 0) */
-	{  4, MPP_GPIO },	/* Fan activity (0 = Off, 1 = On) */
-	{  5, MPP_GPIO },	/* Fan fail detection */
-	{  6, MPP_GPIO },	/* Red front LED (0 = Off, 1 = On) */
-	{  7, MPP_GPIO },	/* Disable initial blinking on front LED */
-	{  8, MPP_GPIO },	/* Rear power switch (on|auto) */
-	{  9, MPP_GPIO },	/* Rear power switch (auto|off) */
-	{ 10, MPP_GPIO },	/* SATA 1 red LED (0 = Off, 1 = On) */
-	{ 11, MPP_GPIO },	/* SATA 0 red LED (0 = Off, 1 = On) */
-	{ 12, MPP_GPIO },	/* Board ID (bit 1) */
-	{ 13, MPP_GPIO },	/* SATA 1 blue LED blink control */
-	{ 14, MPP_SATA_LED },
-	{ 15, MPP_SATA_LED },
-	{ 16, MPP_GPIO },	/* Blue front LED control */
-	{ 17, MPP_GPIO },	/* SATA 0 blue LED blink control */
-	{ 18, MPP_GPIO },	/* Front button (0 = Released, 1 = Pushed ) */
-	{ 19, MPP_GPIO },	/* SATA{0,1} power On/Off request */
-	{ -1 }
+static unsigned int net2big_mpp_modes[] __initdata = {
+	MPP0_GPIO,	/* Raid mode (bit 0) */
+	MPP1_GPIO,	/* USB port 2 fuse (0 = Fail, 1 = Ok) */
+	MPP2_GPIO,	/* Raid mode (bit 1) */
+	MPP3_GPIO,	/* Board ID (bit 0) */
+	MPP4_GPIO,	/* Fan activity (0 = Off, 1 = On) */
+	MPP5_GPIO,	/* Fan fail detection */
+	MPP6_GPIO,	/* Red front LED (0 = Off, 1 = On) */
+	MPP7_GPIO,	/* Disable initial blinking on front LED */
+	MPP8_GPIO,	/* Rear power switch (on|auto) */
+	MPP9_GPIO,	/* Rear power switch (auto|off) */
+	MPP10_GPIO,	/* SATA 1 red LED (0 = Off, 1 = On) */
+	MPP11_GPIO,	/* SATA 0 red LED (0 = Off, 1 = On) */
+	MPP12_GPIO,	/* Board ID (bit 1) */
+	MPP13_GPIO,	/* SATA 1 blue LED blink control */
+	MPP14_SATA_LED,
+	MPP15_SATA_LED,
+	MPP16_GPIO,	/* Blue front LED control */
+	MPP17_GPIO,	/* SATA 0 blue LED blink control */
+	MPP18_GPIO,	/* Front button (0 = Released, 1 = Pushed ) */
+	MPP19_GPIO,	/* SATA{0,1} power On/Off request */
+	0,
 	/* 22: USB port 1 fuse (0 = Fail, 1 = Ok) */
 	/* 23: SATA 0 power status */
 	/* 24: Board power off */
diff -druN linux-2.6.39-libre/arch/arm/mach-orion5x/rd88f5181l-fxo-setup.c linux-3.0-rc7-libre/arch/arm/mach-orion5x/rd88f5181l-fxo-setup.c
--- linux-2.6.39-libre/arch/arm/mach-orion5x/rd88f5181l-fxo-setup.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-orion5x/rd88f5181l-fxo-setup.c	2011-07-11 19:51:52.000000000 -0400
@@ -64,28 +64,28 @@
 /*****************************************************************************
  * General Setup
  ****************************************************************************/
-static struct orion5x_mpp_mode rd88f5181l_fxo_mpp_modes[] __initdata = {
-	{  0, MPP_GPIO },		/* LED1 CardBus LED (front panel) */
-	{  1, MPP_GPIO },		/* PCI_intA */
-	{  2, MPP_GPIO },		/* Hard Reset / Factory Init*/
-	{  3, MPP_GPIO },		/* FXS or DAA select */
-	{  4, MPP_GPIO },		/* LED6 - phone LED (front panel) */
-	{  5, MPP_GPIO },		/* LED5 - phone LED (front panel) */
-	{  6, MPP_PCI_CLK },		/* CPU PCI refclk */
-	{  7, MPP_PCI_CLK },		/* PCI/PCIe refclk */
-	{  8, MPP_GPIO },		/* CardBus reset */
-	{  9, MPP_GPIO },		/* GE_RXERR */
-	{ 10, MPP_GPIO },		/* LED2 MiniPCI LED (front panel) */
-	{ 11, MPP_GPIO },		/* Lifeline control */
-	{ 12, MPP_GIGE },		/* GE_TXD[4] */
-	{ 13, MPP_GIGE },		/* GE_TXD[5] */
-	{ 14, MPP_GIGE },		/* GE_TXD[6] */
-	{ 15, MPP_GIGE },		/* GE_TXD[7] */
-	{ 16, MPP_GIGE },		/* GE_RXD[4] */
-	{ 17, MPP_GIGE },		/* GE_RXD[5] */
-	{ 18, MPP_GIGE },		/* GE_RXD[6] */
-	{ 19, MPP_GIGE },		/* GE_RXD[7] */
-	{ -1 },
+static unsigned int rd88f5181l_fxo_mpp_modes[] __initdata = {
+	MPP0_GPIO,		/* LED1 CardBus LED (front panel) */
+	MPP1_GPIO,		/* PCI_intA */
+	MPP2_GPIO,		/* Hard Reset / Factory Init*/
+	MPP3_GPIO,		/* FXS or DAA select */
+	MPP4_GPIO,		/* LED6 - phone LED (front panel) */
+	MPP5_GPIO,		/* LED5 - phone LED (front panel) */
+	MPP6_PCI_CLK,		/* CPU PCI refclk */
+	MPP7_PCI_CLK,		/* PCI/PCIe refclk */
+	MPP8_GPIO,		/* CardBus reset */
+	MPP9_GPIO,		/* GE_RXERR */
+	MPP10_GPIO,		/* LED2 MiniPCI LED (front panel) */
+	MPP11_GPIO,		/* Lifeline control */
+	MPP12_GIGE,		/* GE_TXD[4] */
+	MPP13_GIGE,		/* GE_TXD[5] */
+	MPP14_GIGE,		/* GE_TXD[6] */
+	MPP15_GIGE,		/* GE_TXD[7] */
+	MPP16_GIGE,		/* GE_RXD[4] */
+	MPP17_GIGE,		/* GE_RXD[5] */
+	MPP18_GIGE,		/* GE_RXD[6] */
+	MPP19_GIGE,		/* GE_RXD[7] */
+	0,
 };
 
 static struct mv643xx_eth_platform_data rd88f5181l_fxo_eth_data = {
diff -druN linux-2.6.39-libre/arch/arm/mach-orion5x/rd88f5181l-ge-setup.c linux-3.0-rc7-libre/arch/arm/mach-orion5x/rd88f5181l-ge-setup.c
--- linux-2.6.39-libre/arch/arm/mach-orion5x/rd88f5181l-ge-setup.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-orion5x/rd88f5181l-ge-setup.c	2011-07-11 19:51:52.000000000 -0400
@@ -65,28 +65,28 @@
 /*****************************************************************************
  * General Setup
  ****************************************************************************/
-static struct orion5x_mpp_mode rd88f5181l_ge_mpp_modes[] __initdata = {
-	{  0, MPP_GPIO },		/* LED1 */
-	{  1, MPP_GPIO },		/* LED5 */
-	{  2, MPP_GPIO },		/* LED4 */
-	{  3, MPP_GPIO },		/* LED3 */
-	{  4, MPP_GPIO },		/* PCI_intA */
-	{  5, MPP_GPIO },		/* RTC interrupt */
-	{  6, MPP_PCI_CLK },		/* CPU PCI refclk */
-	{  7, MPP_PCI_CLK },		/* PCI/PCIe refclk */
-	{  8, MPP_GPIO },		/* 88e6131 interrupt */
-	{  9, MPP_GPIO },		/* GE_RXERR */
-	{ 10, MPP_GPIO },		/* PCI_intB */
-	{ 11, MPP_GPIO },		/* LED2 */
-	{ 12, MPP_GIGE },		/* GE_TXD[4] */
-	{ 13, MPP_GIGE },		/* GE_TXD[5] */
-	{ 14, MPP_GIGE },		/* GE_TXD[6] */
-	{ 15, MPP_GIGE },		/* GE_TXD[7] */
-	{ 16, MPP_GIGE },		/* GE_RXD[4] */
-	{ 17, MPP_GIGE },		/* GE_RXD[5] */
-	{ 18, MPP_GIGE },		/* GE_RXD[6] */
-	{ 19, MPP_GIGE },		/* GE_RXD[7] */
-	{ -1 },
+static unsigned int rd88f5181l_ge_mpp_modes[] __initdata = {
+	MPP0_GPIO,		/* LED1 */
+	MPP1_GPIO,		/* LED5 */
+	MPP2_GPIO,		/* LED4 */
+	MPP3_GPIO,		/* LED3 */
+	MPP4_GPIO,		/* PCI_intA */
+	MPP5_GPIO,		/* RTC interrupt */
+	MPP6_PCI_CLK,		/* CPU PCI refclk */
+	MPP7_PCI_CLK,		/* PCI/PCIe refclk */
+	MPP8_GPIO,		/* 88e6131 interrupt */
+	MPP9_GPIO,		/* GE_RXERR */
+	MPP10_GPIO,		/* PCI_intB */
+	MPP11_GPIO,		/* LED2 */
+	MPP12_GIGE,		/* GE_TXD[4] */
+	MPP13_GIGE,		/* GE_TXD[5] */
+	MPP14_GIGE,		/* GE_TXD[6] */
+	MPP15_GIGE,		/* GE_TXD[7] */
+	MPP16_GIGE,		/* GE_RXD[4] */
+	MPP17_GIGE,		/* GE_RXD[5] */
+	MPP18_GIGE,		/* GE_RXD[6] */
+	MPP19_GIGE,		/* GE_RXD[7] */
+	0,
 };
 
 static struct mv643xx_eth_platform_data rd88f5181l_ge_eth_data = {
diff -druN linux-2.6.39-libre/arch/arm/mach-orion5x/rd88f5182-setup.c linux-3.0-rc7-libre/arch/arm/mach-orion5x/rd88f5182-setup.c
--- linux-2.6.39-libre/arch/arm/mach-orion5x/rd88f5182-setup.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-orion5x/rd88f5182-setup.c	2011-07-11 19:51:52.000000000 -0400
@@ -241,28 +241,28 @@
 /*****************************************************************************
  * General Setup
  ****************************************************************************/
-static struct orion5x_mpp_mode rd88f5182_mpp_modes[] __initdata = {
-	{  0, MPP_GPIO },		/* Debug Led */
-	{  1, MPP_GPIO },		/* Reset Switch */
-	{  2, MPP_UNUSED },
-	{  3, MPP_GPIO },		/* RTC Int */
-	{  4, MPP_GPIO },
-	{  5, MPP_GPIO },
-	{  6, MPP_GPIO },		/* PCI_intA */
-	{  7, MPP_GPIO },		/* PCI_intB */
-	{  8, MPP_UNUSED },
-	{  9, MPP_UNUSED },
-	{ 10, MPP_UNUSED },
-	{ 11, MPP_UNUSED },
-	{ 12, MPP_SATA_LED },		/* SATA 0 presence */
-	{ 13, MPP_SATA_LED },		/* SATA 1 presence */
-	{ 14, MPP_SATA_LED },		/* SATA 0 active */
-	{ 15, MPP_SATA_LED },		/* SATA 1 active */
-	{ 16, MPP_UNUSED },
-	{ 17, MPP_UNUSED },
-	{ 18, MPP_UNUSED },
-	{ 19, MPP_UNUSED },
-	{ -1 },
+static unsigned int rd88f5182_mpp_modes[] __initdata = {
+	MPP0_GPIO,		/* Debug Led */
+	MPP1_GPIO,		/* Reset Switch */
+	MPP2_UNUSED,
+	MPP3_GPIO,		/* RTC Int */
+	MPP4_GPIO,
+	MPP5_GPIO,
+	MPP6_GPIO,		/* PCI_intA */
+	MPP7_GPIO,		/* PCI_intB */
+	MPP8_UNUSED,
+	MPP9_UNUSED,
+	MPP10_UNUSED,
+	MPP11_UNUSED,
+	MPP12_SATA_LED,		/* SATA 0 presence */
+	MPP13_SATA_LED,		/* SATA 1 presence */
+	MPP14_SATA_LED,		/* SATA 0 active */
+	MPP15_SATA_LED,		/* SATA 1 active */
+	MPP16_UNUSED,
+	MPP17_UNUSED,
+	MPP18_UNUSED,
+	MPP19_UNUSED,
+	0,
 };
 
 static void __init rd88f5182_init(void)
diff -druN linux-2.6.39-libre/arch/arm/mach-orion5x/rd88f6183ap-ge-setup.c linux-3.0-rc7-libre/arch/arm/mach-orion5x/rd88f6183ap-ge-setup.c
--- linux-2.6.39-libre/arch/arm/mach-orion5x/rd88f6183ap-ge-setup.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-orion5x/rd88f6183ap-ge-setup.c	2011-07-11 19:51:52.000000000 -0400
@@ -27,7 +27,6 @@
 #include <asm/mach/pci.h>
 #include <mach/orion5x.h>
 #include "common.h"
-#include "mpp.h"
 
 static struct mv643xx_eth_platform_data rd88f6183ap_ge_eth_data = {
 	.phy_addr	= -1,
diff -druN linux-2.6.39-libre/arch/arm/mach-orion5x/terastation_pro2-setup.c linux-3.0-rc7-libre/arch/arm/mach-orion5x/terastation_pro2-setup.c
--- linux-2.6.39-libre/arch/arm/mach-orion5x/terastation_pro2-setup.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-orion5x/terastation_pro2-setup.c	2011-07-11 19:51:52.000000000 -0400
@@ -295,28 +295,28 @@
 /*****************************************************************************
  * General Setup
  ****************************************************************************/
-static struct orion5x_mpp_mode tsp2_mpp_modes[] __initdata = {
-	{  0, MPP_PCIE_RST_OUTn },
-	{  1, MPP_UNUSED },
-	{  2, MPP_UNUSED },
-	{  3, MPP_UNUSED },
-	{  4, MPP_NAND },		/* BOOT NAND Flash REn */
-	{  5, MPP_NAND },		/* BOOT NAND Flash WEn */
-	{  6, MPP_NAND },		/* BOOT NAND Flash HREn[0] */
-	{  7, MPP_NAND },		/* BOOT NAND Flash WEn[0] */
-	{  8, MPP_GPIO },		/* MICON int */
-	{  9, MPP_GPIO },		/* RTC int */
-	{ 10, MPP_UNUSED },
-	{ 11, MPP_GPIO },		/* PCI Int A */
-	{ 12, MPP_UNUSED },
-	{ 13, MPP_GPIO },		/* UPS on UART0 enable */
-	{ 14, MPP_GPIO },		/* UPS low battery detection */
-	{ 15, MPP_UNUSED },
-	{ 16, MPP_UART },		/* UART1 RXD */
-	{ 17, MPP_UART },		/* UART1 TXD */
-	{ 18, MPP_UART },		/* UART1 CTSn */
-	{ 19, MPP_UART },		/* UART1 RTSn */
-	{ -1 },
+static unsigned int tsp2_mpp_modes[] __initdata = {
+	MPP0_PCIE_RST_OUTn,
+	MPP1_UNUSED,
+	MPP2_UNUSED,
+	MPP3_UNUSED,
+	MPP4_NAND,		/* BOOT NAND Flash REn */
+	MPP5_NAND,		/* BOOT NAND Flash WEn */
+	MPP6_NAND,		/* BOOT NAND Flash HREn[0] */
+	MPP7_NAND,		/* BOOT NAND Flash WEn[0] */
+	MPP8_GPIO,		/* MICON int */
+	MPP9_GPIO,		/* RTC int */
+	MPP10_UNUSED,
+	MPP11_GPIO,		/* PCI Int A */
+	MPP12_UNUSED,
+	MPP13_GPIO,		/* UPS on UART0 enable */
+	MPP14_GPIO,		/* UPS low battery detection */
+	MPP15_UNUSED,
+	MPP16_UART,		/* UART1 RXD */
+	MPP17_UART,		/* UART1 TXD */
+	MPP18_UART,		/* UART1 CTSn */
+	MPP19_UART,		/* UART1 RTSn */
+	0,
 };
 
 static void __init tsp2_init(void)
diff -druN linux-2.6.39-libre/arch/arm/mach-orion5x/ts209-setup.c linux-3.0-rc7-libre/arch/arm/mach-orion5x/ts209-setup.c
--- linux-2.6.39-libre/arch/arm/mach-orion5x/ts209-setup.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-orion5x/ts209-setup.c	2011-07-11 19:51:52.000000000 -0400
@@ -244,28 +244,28 @@
 
  * General Setup
  ****************************************************************************/
-static struct orion5x_mpp_mode ts209_mpp_modes[] __initdata = {
-	{  0, MPP_UNUSED },
-	{  1, MPP_GPIO },		/* USB copy button */
-	{  2, MPP_GPIO },		/* Load defaults button */
-	{  3, MPP_GPIO },		/* GPIO RTC */
-	{  4, MPP_UNUSED },
-	{  5, MPP_UNUSED },
-	{  6, MPP_GPIO },		/* PCI Int A */
-	{  7, MPP_GPIO },		/* PCI Int B */
-	{  8, MPP_UNUSED },
-	{  9, MPP_UNUSED },
-	{ 10, MPP_UNUSED },
-	{ 11, MPP_UNUSED },
-	{ 12, MPP_SATA_LED },		/* SATA 0 presence */
-	{ 13, MPP_SATA_LED },		/* SATA 1 presence */
-	{ 14, MPP_SATA_LED },		/* SATA 0 active */
-	{ 15, MPP_SATA_LED },		/* SATA 1 active */
-	{ 16, MPP_UART },		/* UART1 RXD */
-	{ 17, MPP_UART },		/* UART1 TXD */
-	{ 18, MPP_GPIO },		/* SW_RST */
-	{ 19, MPP_UNUSED },
-	{ -1 },
+static unsigned int ts209_mpp_modes[] __initdata = {
+	MPP0_UNUSED,
+	MPP1_GPIO,		/* USB copy button */
+	MPP2_GPIO,		/* Load defaults button */
+	MPP3_GPIO,		/* GPIO RTC */
+	MPP4_UNUSED,
+	MPP5_UNUSED,
+	MPP6_GPIO,		/* PCI Int A */
+	MPP7_GPIO,		/* PCI Int B */
+	MPP8_UNUSED,
+	MPP9_UNUSED,
+	MPP10_UNUSED,
+	MPP11_UNUSED,
+	MPP12_SATA_LED,		/* SATA 0 presence */
+	MPP13_SATA_LED,		/* SATA 1 presence */
+	MPP14_SATA_LED,		/* SATA 0 active */
+	MPP15_SATA_LED,		/* SATA 1 active */
+	MPP16_UART,		/* UART1 RXD */
+	MPP17_UART,		/* UART1 TXD */
+	MPP18_GPIO,		/* SW_RST */
+	MPP19_UNUSED,
+	0,
 };
 
 static void __init qnap_ts209_init(void)
diff -druN linux-2.6.39-libre/arch/arm/mach-orion5x/ts409-setup.c linux-3.0-rc7-libre/arch/arm/mach-orion5x/ts409-setup.c
--- linux-2.6.39-libre/arch/arm/mach-orion5x/ts409-setup.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-orion5x/ts409-setup.c	2011-07-11 19:51:52.000000000 -0400
@@ -242,28 +242,28 @@
 /*****************************************************************************
  * General Setup
  ****************************************************************************/
-static struct orion5x_mpp_mode ts409_mpp_modes[] __initdata = {
-	{  0, MPP_UNUSED },
-	{  1, MPP_UNUSED },
-	{  2, MPP_UNUSED },
-	{  3, MPP_UNUSED },
-	{  4, MPP_GPIO },		/* HDD 1 status */
-	{  5, MPP_GPIO },		/* HDD 2 status */
-	{  6, MPP_GPIO },		/* HDD 3 status */
-	{  7, MPP_GPIO },		/* HDD 4 status */
-	{  8, MPP_UNUSED },
-	{  9, MPP_UNUSED },
-	{ 10, MPP_GPIO },		/* RTC int */
-	{ 11, MPP_UNUSED },
-	{ 12, MPP_UNUSED },
-	{ 13, MPP_UNUSED },
-	{ 14, MPP_GPIO },		/* SW_RST */
-	{ 15, MPP_GPIO },		/* USB copy button */
-	{ 16, MPP_UART },		/* UART1 RXD */
-	{ 17, MPP_UART },		/* UART1 TXD */
-	{ 18, MPP_UNUSED },
-	{ 19, MPP_UNUSED },
-	{ -1 },
+static unsigned int ts409_mpp_modes[] __initdata = {
+	MPP0_UNUSED,
+	MPP1_UNUSED,
+	MPP2_UNUSED,
+	MPP3_UNUSED,
+	MPP4_GPIO,		/* HDD 1 status */
+	MPP5_GPIO,		/* HDD 2 status */
+	MPP6_GPIO,		/* HDD 3 status */
+	MPP7_GPIO,		/* HDD 4 status */
+	MPP8_UNUSED,
+	MPP9_UNUSED,
+	MPP10_GPIO,		/* RTC int */
+	MPP11_UNUSED,
+	MPP12_UNUSED,
+	MPP13_UNUSED,
+	MPP14_GPIO,		/* SW_RST */
+	MPP15_GPIO,		/* USB copy button */
+	MPP16_UART,		/* UART1 RXD */
+	MPP17_UART,		/* UART1 TXD */
+	MPP18_UNUSED,
+	MPP19_UNUSED,
+	0,
 };
 
 static void __init qnap_ts409_init(void)
diff -druN linux-2.6.39-libre/arch/arm/mach-orion5x/ts78xx-setup.c linux-3.0-rc7-libre/arch/arm/mach-orion5x/ts78xx-setup.c
--- linux-2.6.39-libre/arch/arm/mach-orion5x/ts78xx-setup.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-orion5x/ts78xx-setup.c	2011-07-11 19:51:52.000000000 -0400
@@ -557,27 +557,27 @@
 /*****************************************************************************
  * General Setup
  ****************************************************************************/
-static struct orion5x_mpp_mode ts78xx_mpp_modes[] __initdata = {
-	{  0, MPP_UNUSED },
-	{  1, MPP_GPIO },		/* JTAG Clock */
-	{  2, MPP_GPIO },		/* JTAG Data In */
-	{  3, MPP_GPIO },		/* Lat ECP2 256 FPGA - PB2B */
-	{  4, MPP_GPIO },		/* JTAG Data Out */
-	{  5, MPP_GPIO },		/* JTAG TMS */
-	{  6, MPP_GPIO },		/* Lat ECP2 256 FPGA - PB31A_CLK4+ */
-	{  7, MPP_GPIO },		/* Lat ECP2 256 FPGA - PB22B */
-	{  8, MPP_UNUSED },
-	{  9, MPP_UNUSED },
-	{ 10, MPP_UNUSED },
-	{ 11, MPP_UNUSED },
-	{ 12, MPP_UNUSED },
-	{ 13, MPP_UNUSED },
-	{ 14, MPP_UNUSED },
-	{ 15, MPP_UNUSED },
-	{ 16, MPP_UART },
-	{ 17, MPP_UART },
-	{ 18, MPP_UART },
-	{ 19, MPP_UART },
+static unsigned int ts78xx_mpp_modes[] __initdata = {
+	MPP0_UNUSED,
+	MPP1_GPIO,		/* JTAG Clock */
+	MPP2_GPIO,		/* JTAG Data In */
+	MPP3_GPIO,		/* Lat ECP2 256 FPGA - PB2B */
+	MPP4_GPIO,		/* JTAG Data Out */
+	MPP5_GPIO,		/* JTAG TMS */
+	MPP6_GPIO,		/* Lat ECP2 256 FPGA - PB31A_CLK4+ */
+	MPP7_GPIO,		/* Lat ECP2 256 FPGA - PB22B */
+	MPP8_UNUSED,
+	MPP9_UNUSED,
+	MPP10_UNUSED,
+	MPP11_UNUSED,
+	MPP12_UNUSED,
+	MPP13_UNUSED,
+	MPP14_UNUSED,
+	MPP15_UNUSED,
+	MPP16_UART,
+	MPP17_UART,
+	MPP18_UART,
+	MPP19_UART,
 	/*
 	 * MPP[20] PCI Clock Out 1
 	 * MPP[21] PCI Clock Out 0
@@ -586,7 +586,7 @@
 	 * MPP[24] Unused
 	 * MPP[25] Unused
 	 */
-	{ -1 },
+	0,
 };
 
 static void __init ts78xx_init(void)
diff -druN linux-2.6.39-libre/arch/arm/mach-orion5x/wnr854t-setup.c linux-3.0-rc7-libre/arch/arm/mach-orion5x/wnr854t-setup.c
--- linux-2.6.39-libre/arch/arm/mach-orion5x/wnr854t-setup.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-orion5x/wnr854t-setup.c	2011-07-11 19:51:52.000000000 -0400
@@ -24,28 +24,28 @@
 #include "common.h"
 #include "mpp.h"
 
-static struct orion5x_mpp_mode wnr854t_mpp_modes[] __initdata = {
-	{  0, MPP_GPIO },		/* Power LED green (0=on) */
-	{  1, MPP_GPIO },		/* Reset Button (0=off) */
-	{  2, MPP_GPIO },		/* Power LED blink (0=off) */
-	{  3, MPP_GPIO },		/* WAN Status LED amber (0=off) */
-	{  4, MPP_GPIO },		/* PCI int */
-	{  5, MPP_GPIO },		/* ??? */
-	{  6, MPP_GPIO },		/* ??? */
-	{  7, MPP_GPIO },		/* ??? */
-	{  8, MPP_UNUSED },		/* ??? */
-	{  9, MPP_GIGE },		/* GE_RXERR */
-	{ 10, MPP_UNUSED },		/* ??? */
-	{ 11, MPP_UNUSED },		/* ??? */
-	{ 12, MPP_GIGE },		/* GE_TXD[4] */
-	{ 13, MPP_GIGE },		/* GE_TXD[5] */
-	{ 14, MPP_GIGE },		/* GE_TXD[6] */
-	{ 15, MPP_GIGE },		/* GE_TXD[7] */
-	{ 16, MPP_GIGE },		/* GE_RXD[4] */
-	{ 17, MPP_GIGE },		/* GE_RXD[5] */
-	{ 18, MPP_GIGE },		/* GE_RXD[6] */
-	{ 19, MPP_GIGE },		/* GE_RXD[7] */
-	{ -1 },
+static unsigned int wnr854t_mpp_modes[] __initdata = {
+	MPP0_GPIO,		/* Power LED green (0=on) */
+	MPP1_GPIO,		/* Reset Button (0=off) */
+	MPP2_GPIO,		/* Power LED blink (0=off) */
+	MPP3_GPIO,		/* WAN Status LED amber (0=off) */
+	MPP4_GPIO,		/* PCI int */
+	MPP5_GPIO,		/* ??? */
+	MPP6_GPIO,		/* ??? */
+	MPP7_GPIO,		/* ??? */
+	MPP8_UNUSED,		/* ??? */
+	MPP9_GIGE,		/* GE_RXERR */
+	MPP10_UNUSED,		/* ??? */
+	MPP11_UNUSED,		/* ??? */
+	MPP12_GIGE,		/* GE_TXD[4] */
+	MPP13_GIGE,		/* GE_TXD[5] */
+	MPP14_GIGE,		/* GE_TXD[6] */
+	MPP15_GIGE,		/* GE_TXD[7] */
+	MPP16_GIGE,		/* GE_RXD[4] */
+	MPP17_GIGE,		/* GE_RXD[5] */
+	MPP18_GIGE,		/* GE_RXD[6] */
+	MPP19_GIGE,		/* GE_RXD[7] */
+	0,
 };
 
 /*
diff -druN linux-2.6.39-libre/arch/arm/mach-orion5x/wrt350n-v2-setup.c linux-3.0-rc7-libre/arch/arm/mach-orion5x/wrt350n-v2-setup.c
--- linux-2.6.39-libre/arch/arm/mach-orion5x/wrt350n-v2-setup.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-orion5x/wrt350n-v2-setup.c	2011-07-11 19:51:52.000000000 -0400
@@ -101,28 +101,28 @@
 /*
  * General setup
  */
-static struct orion5x_mpp_mode wrt350n_v2_mpp_modes[] __initdata = {
-	{  0, MPP_GPIO },		/* Power LED green (0=on) */
-	{  1, MPP_GPIO },		/* Security LED (0=on) */
-	{  2, MPP_GPIO },		/* Internal Button (0=on) */
-	{  3, MPP_GPIO },		/* Reset Button (0=on) */
-	{  4, MPP_GPIO },		/* PCI int */
-	{  5, MPP_GPIO },		/* Power LED orange (0=on) */
-	{  6, MPP_GPIO },		/* USB LED (0=on) */
-	{  7, MPP_GPIO },		/* Wireless LED (0=on) */
-	{  8, MPP_UNUSED },		/* ??? */
-	{  9, MPP_GIGE },		/* GE_RXERR */
-	{ 10, MPP_UNUSED },		/* ??? */
-	{ 11, MPP_UNUSED },		/* ??? */
-	{ 12, MPP_GIGE },		/* GE_TXD[4] */
-	{ 13, MPP_GIGE },		/* GE_TXD[5] */
-	{ 14, MPP_GIGE },		/* GE_TXD[6] */
-	{ 15, MPP_GIGE },		/* GE_TXD[7] */
-	{ 16, MPP_GIGE },		/* GE_RXD[4] */
-	{ 17, MPP_GIGE },		/* GE_RXD[5] */
-	{ 18, MPP_GIGE },		/* GE_RXD[6] */
-	{ 19, MPP_GIGE },		/* GE_RXD[7] */
-	{ -1 },
+static unsigned int wrt350n_v2_mpp_modes[] __initdata = {
+	MPP0_GPIO,		/* Power LED green (0=on) */
+	MPP1_GPIO,		/* Security LED (0=on) */
+	MPP2_GPIO,		/* Internal Button (0=on) */
+	MPP3_GPIO,		/* Reset Button (0=on) */
+	MPP4_GPIO,		/* PCI int */
+	MPP5_GPIO,		/* Power LED orange (0=on) */
+	MPP6_GPIO,		/* USB LED (0=on) */
+	MPP7_GPIO,		/* Wireless LED (0=on) */
+	MPP8_UNUSED,		/* ??? */
+	MPP9_GIGE,		/* GE_RXERR */
+	MPP10_UNUSED,		/* ??? */
+	MPP11_UNUSED,		/* ??? */
+	MPP12_GIGE,		/* GE_TXD[4] */
+	MPP13_GIGE,		/* GE_TXD[5] */
+	MPP14_GIGE,		/* GE_TXD[6] */
+	MPP15_GIGE,		/* GE_TXD[7] */
+	MPP16_GIGE,		/* GE_RXD[4] */
+	MPP17_GIGE,		/* GE_RXD[5] */
+	MPP18_GIGE,		/* GE_RXD[6] */
+	MPP19_GIGE,		/* GE_RXD[7] */
+	0,
 };
 
 /*
diff -druN linux-2.6.39-libre/arch/arm/mach-pxa/balloon3.c linux-3.0-rc7-libre/arch/arm/mach-pxa/balloon3.c
--- linux-2.6.39-libre/arch/arm/mach-pxa/balloon3.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-pxa/balloon3.c	2011-07-11 19:51:52.000000000 -0400
@@ -15,7 +15,6 @@
 
 #include <linux/init.h>
 #include <linux/platform_device.h>
-#include <linux/sysdev.h>
 #include <linux/interrupt.h>
 #include <linux/sched.h>
 #include <linux/bitops.h>
diff -druN linux-2.6.39-libre/arch/arm/mach-pxa/clock.h linux-3.0-rc7-libre/arch/arm/mach-pxa/clock.h
--- linux-2.6.39-libre/arch/arm/mach-pxa/clock.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-pxa/clock.h	2011-07-11 19:51:52.000000000 -0400
@@ -1,5 +1,5 @@
 #include <linux/clkdev.h>
-#include <linux/sysdev.h>
+#include <linux/syscore_ops.h>
 
 struct clkops {
 	void			(*enable)(struct clk *);
@@ -54,7 +54,7 @@
 void clk_pxa2xx_cken_enable(struct clk *clk);
 void clk_pxa2xx_cken_disable(struct clk *clk);
 
-extern struct sysdev_class pxa2xx_clock_sysclass;
+extern struct syscore_ops pxa2xx_clock_syscore_ops;
 
 #if defined(CONFIG_PXA3xx) || defined(CONFIG_PXA95x)
 #define DEFINE_PXA3_CKEN(_name, _cken, _rate, _delay)	\
@@ -74,5 +74,6 @@
 extern void clk_pxa3xx_cken_enable(struct clk *);
 extern void clk_pxa3xx_cken_disable(struct clk *);
 
-extern struct sysdev_class pxa3xx_clock_sysclass;
+extern struct syscore_ops pxa3xx_clock_syscore_ops;
+
 #endif
diff -druN linux-2.6.39-libre/arch/arm/mach-pxa/clock-pxa2xx.c linux-3.0-rc7-libre/arch/arm/mach-pxa/clock-pxa2xx.c
--- linux-2.6.39-libre/arch/arm/mach-pxa/clock-pxa2xx.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-pxa/clock-pxa2xx.c	2011-07-11 19:51:52.000000000 -0400
@@ -9,7 +9,7 @@
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
-#include <linux/sysdev.h>
+#include <linux/syscore_ops.h>
 
 #include <mach/pxa2xx-regs.h>
 
@@ -33,32 +33,22 @@
 #ifdef CONFIG_PM
 static uint32_t saved_cken;
 
-static int pxa2xx_clock_suspend(struct sys_device *d, pm_message_t state)
+static int pxa2xx_clock_suspend(void)
 {
 	saved_cken = CKEN;
 	return 0;
 }
 
-static int pxa2xx_clock_resume(struct sys_device *d)
+static void pxa2xx_clock_resume(void)
 {
 	CKEN = saved_cken;
-	return 0;
 }
 #else
 #define pxa2xx_clock_suspend	NULL
 #define pxa2xx_clock_resume	NULL
 #endif
 
-struct sysdev_class pxa2xx_clock_sysclass = {
-	.name		= "pxa2xx-clock",
+struct syscore_ops pxa2xx_clock_syscore_ops = {
 	.suspend	= pxa2xx_clock_suspend,
 	.resume		= pxa2xx_clock_resume,
 };
-
-static int __init pxa2xx_clock_init(void)
-{
-	if (cpu_is_pxa2xx())
-		return sysdev_class_register(&pxa2xx_clock_sysclass);
-	return 0;
-}
-postcore_initcall(pxa2xx_clock_init);
diff -druN linux-2.6.39-libre/arch/arm/mach-pxa/clock-pxa3xx.c linux-3.0-rc7-libre/arch/arm/mach-pxa/clock-pxa3xx.c
--- linux-2.6.39-libre/arch/arm/mach-pxa/clock-pxa3xx.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-pxa/clock-pxa3xx.c	2011-07-11 19:51:52.000000000 -0400
@@ -10,6 +10,7 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/io.h>
+#include <linux/syscore_ops.h>
 
 #include <mach/smemc.h>
 #include <mach/pxa3xx-regs.h>
@@ -182,7 +183,7 @@
 static uint32_t cken[2];
 static uint32_t accr;
 
-static int pxa3xx_clock_suspend(struct sys_device *d, pm_message_t state)
+static int pxa3xx_clock_suspend(void)
 {
 	cken[0] = CKENA;
 	cken[1] = CKENB;
@@ -190,28 +191,18 @@
 	return 0;
 }
 
-static int pxa3xx_clock_resume(struct sys_device *d)
+static void pxa3xx_clock_resume(void)
 {
 	ACCR = accr;
 	CKENA = cken[0];
 	CKENB = cken[1];
-	return 0;
 }
 #else
 #define pxa3xx_clock_suspend	NULL
 #define pxa3xx_clock_resume	NULL
 #endif
 
-struct sysdev_class pxa3xx_clock_sysclass = {
-	.name		= "pxa3xx-clock",
+struct syscore_ops pxa3xx_clock_syscore_ops = {
 	.suspend	= pxa3xx_clock_suspend,
 	.resume		= pxa3xx_clock_resume,
 };
-
-static int __init pxa3xx_clock_init(void)
-{
-	if (cpu_is_pxa3xx() || cpu_is_pxa95x())
-		return sysdev_class_register(&pxa3xx_clock_sysclass);
-	return 0;
-}
-postcore_initcall(pxa3xx_clock_init);
diff -druN linux-2.6.39-libre/arch/arm/mach-pxa/cm-x270.c linux-3.0-rc7-libre/arch/arm/mach-pxa/cm-x270.c
--- linux-2.6.39-libre/arch/arm/mach-pxa/cm-x270.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-pxa/cm-x270.c	2011-07-11 19:51:52.000000000 -0400
@@ -10,7 +10,6 @@
  */
 
 #include <linux/platform_device.h>
-#include <linux/sysdev.h>
 #include <linux/irq.h>
 #include <linux/gpio.h>
 #include <linux/delay.h>
diff -druN linux-2.6.39-libre/arch/arm/mach-pxa/cm-x2xx.c linux-3.0-rc7-libre/arch/arm/mach-pxa/cm-x2xx.c
--- linux-2.6.39-libre/arch/arm/mach-pxa/cm-x2xx.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-pxa/cm-x2xx.c	2011-07-11 19:51:52.000000000 -0400
@@ -10,7 +10,7 @@
  */
 
 #include <linux/platform_device.h>
-#include <linux/sysdev.h>
+#include <linux/syscore_ops.h>
 #include <linux/irq.h>
 #include <linux/gpio.h>
 
@@ -388,7 +388,7 @@
 #ifdef CONFIG_PM
 static unsigned long sleep_save_msc[10];
 
-static int cmx2xx_suspend(struct sys_device *dev, pm_message_t state)
+static int cmx2xx_suspend(void)
 {
 	cmx2xx_pci_suspend();
 
@@ -412,7 +412,7 @@
 	return 0;
 }
 
-static int cmx2xx_resume(struct sys_device *dev)
+static void cmx2xx_resume(void)
 {
 	cmx2xx_pci_resume();
 
@@ -420,27 +420,18 @@
 	__raw_writel(sleep_save_msc[0], MSC0);
 	__raw_writel(sleep_save_msc[1], MSC1);
 	__raw_writel(sleep_save_msc[2], MSC2);
-
-	return 0;
 }
 
-static struct sysdev_class cmx2xx_pm_sysclass = {
-	.name = "pm",
+static struct syscore_ops cmx2xx_pm_syscore_ops = {
 	.resume = cmx2xx_resume,
 	.suspend = cmx2xx_suspend,
 };
 
-static struct sys_device cmx2xx_pm_device = {
-	.cls = &cmx2xx_pm_sysclass,
-};
-
 static int __init cmx2xx_pm_init(void)
 {
-	int error;
-	error = sysdev_class_register(&cmx2xx_pm_sysclass);
-	if (error == 0)
-		error = sysdev_register(&cmx2xx_pm_device);
-	return error;
+	register_syscore_ops(&cmx2xx_pm_syscore_ops);
+
+	return 0;
 }
 #else
 static int __init cmx2xx_pm_init(void) { return 0; }
diff -druN linux-2.6.39-libre/arch/arm/mach-pxa/cm-x2xx-pci.c linux-3.0-rc7-libre/arch/arm/mach-pxa/cm-x2xx-pci.c
--- linux-2.6.39-libre/arch/arm/mach-pxa/cm-x2xx-pci.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-pxa/cm-x2xx-pci.c	2011-07-11 19:51:52.000000000 -0400
@@ -29,33 +29,6 @@
 unsigned long it8152_base_address;
 static int cmx2xx_it8152_irq_gpio;
 
-/*
- * Only first 64MB of memory can be accessed via PCI.
- * We use GFP_DMA to allocate safe buffers to do map/unmap.
- * This is really ugly and we need a better way of specifying
- * DMA-capable regions of memory.
- */
-void __init cmx2xx_pci_adjust_zones(unsigned long *zone_size,
-	unsigned long *zhole_size)
-{
-	unsigned int sz = SZ_64M >> PAGE_SHIFT;
-
-	if (machine_is_armcore()) {
-		pr_info("Adjusting zones for CM-X2XX\n");
-
-		/*
-		 * Only adjust if > 64M on current system
-		 */
-		if (zone_size[0] <= sz)
-			return;
-
-		zone_size[1] = zone_size[0] - sz;
-		zone_size[0] = sz;
-		zhole_size[1] = zhole_size[0];
-		zhole_size[0] = 0;
-	}
-}
-
 static void cmx2xx_it8152_irq_demux(unsigned int irq, struct irq_desc *desc)
 {
 	/* clear our parent irq */
diff -druN linux-2.6.39-libre/arch/arm/mach-pxa/colibri-evalboard.c linux-3.0-rc7-libre/arch/arm/mach-pxa/colibri-evalboard.c
--- linux-2.6.39-libre/arch/arm/mach-pxa/colibri-evalboard.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-pxa/colibri-evalboard.c	2011-07-11 19:51:52.000000000 -0400
@@ -13,7 +13,6 @@
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/platform_device.h>
-#include <linux/sysdev.h>
 #include <linux/interrupt.h>
 #include <linux/gpio.h>
 #include <asm/mach-types.h>
diff -druN linux-2.6.39-libre/arch/arm/mach-pxa/colibri-pxa270.c linux-3.0-rc7-libre/arch/arm/mach-pxa/colibri-pxa270.c
--- linux-2.6.39-libre/arch/arm/mach-pxa/colibri-pxa270.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-pxa/colibri-pxa270.c	2011-07-11 19:51:52.000000000 -0400
@@ -17,7 +17,6 @@
 #include <linux/mtd/partitions.h>
 #include <linux/mtd/physmap.h>
 #include <linux/platform_device.h>
-#include <linux/sysdev.h>
 #include <linux/ucb1400.h>
 
 #include <asm/mach/arch.h>
diff -druN linux-2.6.39-libre/arch/arm/mach-pxa/colibri-pxa270-income.c linux-3.0-rc7-libre/arch/arm/mach-pxa/colibri-pxa270-income.c
--- linux-2.6.39-libre/arch/arm/mach-pxa/colibri-pxa270-income.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-pxa/colibri-pxa270-income.c	2011-07-11 19:51:52.000000000 -0400
@@ -22,7 +22,6 @@
 #include <linux/platform_device.h>
 #include <linux/pwm_backlight.h>
 #include <linux/i2c/pxa-i2c.h>
-#include <linux/sysdev.h>
 
 #include <asm/irq.h>
 #include <asm/mach-types.h>
diff -druN linux-2.6.39-libre/arch/arm/mach-pxa/generic.h linux-3.0-rc7-libre/arch/arm/mach-pxa/generic.h
--- linux-2.6.39-libre/arch/arm/mach-pxa/generic.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-pxa/generic.h	2011-07-11 19:51:52.000000000 -0400
@@ -61,10 +61,10 @@
 #define pxa3xx_get_clk_frequency_khz(x)		(0)
 #endif
 
-extern struct sysdev_class pxa_irq_sysclass;
-extern struct sysdev_class pxa_gpio_sysclass;
-extern struct sysdev_class pxa2xx_mfp_sysclass;
-extern struct sysdev_class pxa3xx_mfp_sysclass;
+extern struct syscore_ops pxa_irq_syscore_ops;
+extern struct syscore_ops pxa_gpio_syscore_ops;
+extern struct syscore_ops pxa2xx_mfp_syscore_ops;
+extern struct syscore_ops pxa3xx_mfp_syscore_ops;
 
 void __init pxa_set_ffuart_info(void *info);
 void __init pxa_set_btuart_info(void *info);
diff -druN linux-2.6.39-libre/arch/arm/mach-pxa/hx4700.c linux-3.0-rc7-libre/arch/arm/mach-pxa/hx4700.c
--- linux-2.6.39-libre/arch/arm/mach-pxa/hx4700.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-pxa/hx4700.c	2011-07-11 19:51:52.000000000 -0400
@@ -735,7 +735,7 @@
  * StrataFlash
  */
 
-static void hx4700_set_vpp(struct map_info *map, int vpp)
+static void hx4700_set_vpp(struct platform_device *pdev, int vpp)
 {
 	gpio_set_value(GPIO91_HX4700_FLASH_VPEN, vpp);
 }
diff -druN linux-2.6.39-libre/arch/arm/mach-pxa/include/mach/memory.h linux-3.0-rc7-libre/arch/arm/mach-pxa/include/mach/memory.h
--- linux-2.6.39-libre/arch/arm/mach-pxa/include/mach/memory.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-pxa/include/mach/memory.h	2011-07-11 19:51:52.000000000 -0400
@@ -17,14 +17,8 @@
  */
 #define PLAT_PHYS_OFFSET	UL(0xa0000000)
 
-#if !defined(__ASSEMBLY__) && defined(CONFIG_MACH_ARMCORE) && defined(CONFIG_PCI)
-void cmx2xx_pci_adjust_zones(unsigned long *size, unsigned long *holes);
-
-#define arch_adjust_zones(size, holes) \
-	cmx2xx_pci_adjust_zones(size, holes)
-
-#define ISA_DMA_THRESHOLD	(PHYS_OFFSET + SZ_64M - 1)
-#define MAX_DMA_ADDRESS		(PAGE_OFFSET + SZ_64M)
+#if defined(CONFIG_MACH_ARMCORE) && defined(CONFIG_PCI)
+#define ARM_DMA_ZONE_SIZE	SZ_64M
 #endif
 
 #endif
diff -druN linux-2.6.39-libre/arch/arm/mach-pxa/include/mach/uncompress.h linux-3.0-rc7-libre/arch/arm/mach-pxa/include/mach/uncompress.h
--- linux-2.6.39-libre/arch/arm/mach-pxa/include/mach/uncompress.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-pxa/include/mach/uncompress.h	2011-07-11 19:51:52.000000000 -0400
@@ -16,9 +16,9 @@
 #define BTUART_BASE	(0x40200000)
 #define STUART_BASE	(0x40700000)
 
-static unsigned long uart_base;
-static unsigned int uart_shift;
-static unsigned int uart_is_pxa;
+unsigned long uart_base;
+unsigned int uart_shift;
+unsigned int uart_is_pxa;
 
 static inline unsigned char uart_read(int offset)
 {
diff -druN linux-2.6.39-libre/arch/arm/mach-pxa/irq.c linux-3.0-rc7-libre/arch/arm/mach-pxa/irq.c
--- linux-2.6.39-libre/arch/arm/mach-pxa/irq.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-pxa/irq.c	2011-07-11 19:51:52.000000000 -0400
@@ -15,7 +15,7 @@
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/interrupt.h>
-#include <linux/sysdev.h>
+#include <linux/syscore_ops.h>
 #include <linux/io.h>
 #include <linux/irq.h>
 
@@ -183,7 +183,7 @@
 static unsigned long saved_icmr[MAX_INTERNAL_IRQS/32];
 static unsigned long saved_ipr[MAX_INTERNAL_IRQS];
 
-static int pxa_irq_suspend(struct sys_device *dev, pm_message_t state)
+static int pxa_irq_suspend(void)
 {
 	int i;
 
@@ -202,7 +202,7 @@
 	return 0;
 }
 
-static int pxa_irq_resume(struct sys_device *dev)
+static void pxa_irq_resume(void)
 {
 	int i;
 
@@ -218,22 +218,13 @@
 			__raw_writel(saved_ipr[i], IRQ_BASE + IPR(i));
 
 	__raw_writel(1, IRQ_BASE + ICCR);
-	return 0;
 }
 #else
 #define pxa_irq_suspend		NULL
 #define pxa_irq_resume		NULL
 #endif
 
-struct sysdev_class pxa_irq_sysclass = {
-	.name		= "irq",
+struct syscore_ops pxa_irq_syscore_ops = {
 	.suspend	= pxa_irq_suspend,
 	.resume		= pxa_irq_resume,
 };
-
-static int __init pxa_irq_init(void)
-{
-	return sysdev_class_register(&pxa_irq_sysclass);
-}
-
-core_initcall(pxa_irq_init);
diff -druN linux-2.6.39-libre/arch/arm/mach-pxa/Kconfig linux-3.0-rc7-libre/arch/arm/mach-pxa/Kconfig
--- linux-2.6.39-libre/arch/arm/mach-pxa/Kconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-pxa/Kconfig	2011-07-11 19:51:52.000000000 -0400
@@ -153,7 +153,6 @@
 	bool "Iskratel Electronics XCEP"
 	select PXA25x
 	select MTD
-	select MTD_PARTITIONS
 	select MTD_PHYSMAP
 	select MTD_CFI_INTELEXT
 	select MTD_CFI
diff -druN linux-2.6.39-libre/arch/arm/mach-pxa/lpd270.c linux-3.0-rc7-libre/arch/arm/mach-pxa/lpd270.c
--- linux-2.6.39-libre/arch/arm/mach-pxa/lpd270.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-pxa/lpd270.c	2011-07-11 19:51:52.000000000 -0400
@@ -15,7 +15,7 @@
 
 #include <linux/init.h>
 #include <linux/platform_device.h>
-#include <linux/sysdev.h>
+#include <linux/syscore_ops.h>
 #include <linux/interrupt.h>
 #include <linux/sched.h>
 #include <linux/bitops.h>
@@ -159,30 +159,22 @@
 
 
 #ifdef CONFIG_PM
-static int lpd270_irq_resume(struct sys_device *dev)
+static void lpd270_irq_resume(void)
 {
 	__raw_writew(lpd270_irq_enabled, LPD270_INT_MASK);
-	return 0;
 }
 
-static struct sysdev_class lpd270_irq_sysclass = {
-	.name = "cpld_irq",
+static struct syscore_ops lpd270_irq_syscore_ops = {
 	.resume = lpd270_irq_resume,
 };
 
-static struct sys_device lpd270_irq_device = {
-	.cls = &lpd270_irq_sysclass,
-};
-
 static int __init lpd270_irq_device_init(void)
 {
-	int ret = -ENODEV;
 	if (machine_is_logicpd_pxa270()) {
-		ret = sysdev_class_register(&lpd270_irq_sysclass);
-		if (ret == 0)
-			ret = sysdev_register(&lpd270_irq_device);
+		register_syscore_ops(&lpd270_irq_syscore_ops);
+		return 0;
 	}
-	return ret;
+	return -ENODEV;
 }
 
 device_initcall(lpd270_irq_device_init);
diff -druN linux-2.6.39-libre/arch/arm/mach-pxa/lubbock.c linux-3.0-rc7-libre/arch/arm/mach-pxa/lubbock.c
--- linux-2.6.39-libre/arch/arm/mach-pxa/lubbock.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-pxa/lubbock.c	2011-07-11 19:51:52.000000000 -0400
@@ -15,7 +15,7 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/platform_device.h>
-#include <linux/sysdev.h>
+#include <linux/syscore_ops.h>
 #include <linux/major.h>
 #include <linux/fb.h>
 #include <linux/interrupt.h>
@@ -176,31 +176,22 @@
 
 #ifdef CONFIG_PM
 
-static int lubbock_irq_resume(struct sys_device *dev)
+static void lubbock_irq_resume(void)
 {
 	LUB_IRQ_MASK_EN = lubbock_irq_enabled;
-	return 0;
 }
 
-static struct sysdev_class lubbock_irq_sysclass = {
-	.name = "cpld_irq",
+static struct syscore_ops lubbock_irq_syscore_ops = {
 	.resume = lubbock_irq_resume,
 };
 
-static struct sys_device lubbock_irq_device = {
-	.cls = &lubbock_irq_sysclass,
-};
-
 static int __init lubbock_irq_device_init(void)
 {
-	int ret = -ENODEV;
-
 	if (machine_is_lubbock()) {
-		ret = sysdev_class_register(&lubbock_irq_sysclass);
-		if (ret == 0)
-			ret = sysdev_register(&lubbock_irq_device);
+		register_syscore_ops(&lubbock_irq_syscore_ops);
+		return 0;
 	}
-	return ret;
+	return -ENODEV;
 }
 
 device_initcall(lubbock_irq_device_init);
diff -druN linux-2.6.39-libre/arch/arm/mach-pxa/magician.c linux-3.0-rc7-libre/arch/arm/mach-pxa/magician.c
--- linux-2.6.39-libre/arch/arm/mach-pxa/magician.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-pxa/magician.c	2011-07-11 19:51:52.000000000 -0400
@@ -662,7 +662,7 @@
  * StrataFlash
  */
 
-static void magician_set_vpp(struct map_info *map, int vpp)
+static void magician_set_vpp(struct platform_device *pdev, int vpp)
 {
 	gpio_set_value(EGPIO_MAGICIAN_FLASH_VPP, vpp);
 }
diff -druN linux-2.6.39-libre/arch/arm/mach-pxa/mainstone.c linux-3.0-rc7-libre/arch/arm/mach-pxa/mainstone.c
--- linux-2.6.39-libre/arch/arm/mach-pxa/mainstone.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-pxa/mainstone.c	2011-07-11 19:51:52.000000000 -0400
@@ -15,7 +15,7 @@
 
 #include <linux/init.h>
 #include <linux/platform_device.h>
-#include <linux/sysdev.h>
+#include <linux/syscore_ops.h>
 #include <linux/interrupt.h>
 #include <linux/sched.h>
 #include <linux/bitops.h>
@@ -185,31 +185,21 @@
 
 #ifdef CONFIG_PM
 
-static int mainstone_irq_resume(struct sys_device *dev)
+static void mainstone_irq_resume(void)
 {
 	MST_INTMSKENA = mainstone_irq_enabled;
-	return 0;
 }
 
-static struct sysdev_class mainstone_irq_sysclass = {
-	.name = "cpld_irq",
+static struct syscore_ops mainstone_irq_syscore_ops = {
 	.resume = mainstone_irq_resume,
 };
 
-static struct sys_device mainstone_irq_device = {
-	.cls = &mainstone_irq_sysclass,
-};
-
 static int __init mainstone_irq_device_init(void)
 {
-	int ret = -ENODEV;
+	if (machine_is_mainstone())
+		register_syscore_ops(&mainstone_irq_syscore_ops);
 
-	if (machine_is_mainstone()) {
-		ret = sysdev_class_register(&mainstone_irq_sysclass);
-		if (ret == 0)
-			ret = sysdev_register(&mainstone_irq_device);
-	}
-	return ret;
+	return 0;
 }
 
 device_initcall(mainstone_irq_device_init);
diff -druN linux-2.6.39-libre/arch/arm/mach-pxa/mfp-pxa2xx.c linux-3.0-rc7-libre/arch/arm/mach-pxa/mfp-pxa2xx.c
--- linux-2.6.39-libre/arch/arm/mach-pxa/mfp-pxa2xx.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-pxa/mfp-pxa2xx.c	2011-07-11 19:51:52.000000000 -0400
@@ -16,7 +16,7 @@
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
-#include <linux/sysdev.h>
+#include <linux/syscore_ops.h>
 
 #include <mach/gpio.h>
 #include <mach/pxa2xx-regs.h>
@@ -338,7 +338,7 @@
 static unsigned long saved_gpdr[4];
 static unsigned long saved_pgsr[4];
 
-static int pxa2xx_mfp_suspend(struct sys_device *d, pm_message_t state)
+static int pxa2xx_mfp_suspend(void)
 {
 	int i;
 
@@ -365,7 +365,7 @@
 	return 0;
 }
 
-static int pxa2xx_mfp_resume(struct sys_device *d)
+static void pxa2xx_mfp_resume(void)
 {
 	int i;
 
@@ -376,15 +376,13 @@
 		PGSR(i) = saved_pgsr[i];
 	}
 	PSSR = PSSR_RDH | PSSR_PH;
-	return 0;
 }
 #else
 #define pxa2xx_mfp_suspend	NULL
 #define pxa2xx_mfp_resume	NULL
 #endif
 
-struct sysdev_class pxa2xx_mfp_sysclass = {
-	.name		= "mfp",
+struct syscore_ops pxa2xx_mfp_syscore_ops = {
 	.suspend	= pxa2xx_mfp_suspend,
 	.resume		= pxa2xx_mfp_resume,
 };
@@ -409,6 +407,6 @@
 	for (i = 0; i <= gpio_to_bank(pxa_last_gpio); i++)
 		gpdr_lpm[i] = GPDR(i * 32);
 
-	return sysdev_class_register(&pxa2xx_mfp_sysclass);
+	return 0;
 }
 postcore_initcall(pxa2xx_mfp_init);
diff -druN linux-2.6.39-libre/arch/arm/mach-pxa/mfp-pxa3xx.c linux-3.0-rc7-libre/arch/arm/mach-pxa/mfp-pxa3xx.c
--- linux-2.6.39-libre/arch/arm/mach-pxa/mfp-pxa3xx.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-pxa/mfp-pxa3xx.c	2011-07-11 19:51:52.000000000 -0400
@@ -17,7 +17,7 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/io.h>
-#include <linux/sysdev.h>
+#include <linux/syscore_ops.h>
 
 #include <mach/hardware.h>
 #include <mach/mfp-pxa3xx.h>
@@ -31,13 +31,13 @@
  * a pull-down mode if they're an active low chip select, and we're
  * just entering standby.
  */
-static int pxa3xx_mfp_suspend(struct sys_device *d, pm_message_t state)
+static int pxa3xx_mfp_suspend(void)
 {
 	mfp_config_lpm();
 	return 0;
 }
 
-static int pxa3xx_mfp_resume(struct sys_device *d)
+static void pxa3xx_mfp_resume(void)
 {
 	mfp_config_run();
 
@@ -47,24 +47,13 @@
 	 * preserve them here in case they will be referenced later
 	 */
 	ASCR &= ~(ASCR_RDH | ASCR_D1S | ASCR_D2S | ASCR_D3S);
-	return 0;
 }
 #else
 #define pxa3xx_mfp_suspend	NULL
 #define pxa3xx_mfp_resume	NULL
 #endif
 
-struct sysdev_class pxa3xx_mfp_sysclass = {
-	.name		= "mfp",
+struct syscore_ops pxa3xx_mfp_syscore_ops = {
 	.suspend	= pxa3xx_mfp_suspend,
-	.resume 	= pxa3xx_mfp_resume,
+	.resume		= pxa3xx_mfp_resume,
 };
-
-static int __init mfp_init_devicefs(void)
-{
-	if (cpu_is_pxa3xx())
-		return sysdev_class_register(&pxa3xx_mfp_sysclass);
-
-	return 0;
-}
-postcore_initcall(mfp_init_devicefs);
diff -druN linux-2.6.39-libre/arch/arm/mach-pxa/mioa701.c linux-3.0-rc7-libre/arch/arm/mach-pxa/mioa701.c
--- linux-2.6.39-libre/arch/arm/mach-pxa/mioa701.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-pxa/mioa701.c	2011-07-11 19:51:52.000000000 -0400
@@ -22,7 +22,7 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/platform_device.h>
-#include <linux/sysdev.h>
+#include <linux/syscore_ops.h>
 #include <linux/input.h>
 #include <linux/delay.h>
 #include <linux/gpio_keys.h>
@@ -488,7 +488,7 @@
 }
 
 
-static int mioa701_sys_suspend(struct sys_device *sysdev, pm_message_t state)
+static int mioa701_sys_suspend(void)
 {
 	int i = 0, is_bt_on;
 	u32 *mem_resume_vector	= phys_to_virt(RESUME_VECTOR_ADDR);
@@ -514,7 +514,7 @@
 	return 0;
 }
 
-static int mioa701_sys_resume(struct sys_device *sysdev)
+static void mioa701_sys_resume(void)
 {
 	int i = 0;
 	u32 *mem_resume_vector	= phys_to_virt(RESUME_VECTOR_ADDR);
@@ -527,43 +527,18 @@
 	*mem_resume_enabler = save_buffer[i++];
 	*mem_resume_bt	    = save_buffer[i++];
 	*mem_resume_unknown = save_buffer[i++];
-
-	return 0;
 }
 
-static struct sysdev_class mioa701_sysclass = {
-	.name = "mioa701",
-};
-
-static struct sys_device sysdev_bootstrap = {
-	.cls		= &mioa701_sysclass,
-};
-
-static struct sysdev_driver driver_bootstrap = {
-	.suspend	= &mioa701_sys_suspend,
-	.resume		= &mioa701_sys_resume,
+static struct syscore_ops mioa701_syscore_ops = {
+	.suspend	= mioa701_sys_suspend,
+	.resume		= mioa701_sys_resume,
 };
 
 static int __init bootstrap_init(void)
 {
-	int rc;
 	int save_size = mioa701_bootstrap_lg + (sizeof(u32) * 3);
 
-	rc = sysdev_class_register(&mioa701_sysclass);
-	if (rc) {
-		printk(KERN_ERR "Failed registering mioa701 sys class\n");
-		return -ENODEV;
-	}
-	rc = sysdev_register(&sysdev_bootstrap);
-	if (rc) {
-		printk(KERN_ERR "Failed registering mioa701 sys device\n");
-		return -ENODEV;
-	}
-	rc = sysdev_driver_register(&mioa701_sysclass, &driver_bootstrap);
-	if (rc) {
-		printk(KERN_ERR "Failed registering PMU sys driver\n");
-		return -ENODEV;
-	}
+	register_syscore_ops(&mioa701_syscore_ops);
 
 	save_buffer = kmalloc(save_size, GFP_KERNEL);
 	if (!save_buffer)
@@ -576,9 +551,7 @@
 static void bootstrap_exit(void)
 {
 	kfree(save_buffer);
-	sysdev_driver_unregister(&mioa701_sysclass, &driver_bootstrap);
-	sysdev_unregister(&sysdev_bootstrap);
-	sysdev_class_unregister(&mioa701_sysclass);
+	unregister_syscore_ops(&mioa701_syscore_ops);
 
 	printk(KERN_CRIT "Unregistering mioa701 suspend will hang next"
 	       "resume !!!\n");
diff -druN linux-2.6.39-libre/arch/arm/mach-pxa/palmld.c linux-3.0-rc7-libre/arch/arm/mach-pxa/palmld.c
--- linux-2.6.39-libre/arch/arm/mach-pxa/palmld.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-pxa/palmld.c	2011-07-11 19:51:52.000000000 -0400
@@ -24,7 +24,6 @@
 #include <linux/gpio.h>
 #include <linux/wm97xx.h>
 #include <linux/power_supply.h>
-#include <linux/sysdev.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/partitions.h>
 #include <linux/mtd/physmap.h>
diff -druN linux-2.6.39-libre/arch/arm/mach-pxa/palmtreo.c linux-3.0-rc7-libre/arch/arm/mach-pxa/palmtreo.c
--- linux-2.6.39-libre/arch/arm/mach-pxa/palmtreo.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-pxa/palmtreo.c	2011-07-11 19:51:52.000000000 -0400
@@ -25,7 +25,6 @@
 #include <linux/pwm_backlight.h>
 #include <linux/gpio.h>
 #include <linux/power_supply.h>
-#include <linux/sysdev.h>
 #include <linux/w1-gpio.h>
 
 #include <asm/mach-types.h>
diff -druN linux-2.6.39-libre/arch/arm/mach-pxa/palmz72.c linux-3.0-rc7-libre/arch/arm/mach-pxa/palmz72.c
--- linux-2.6.39-libre/arch/arm/mach-pxa/palmz72.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-pxa/palmz72.c	2011-07-11 19:51:52.000000000 -0400
@@ -19,7 +19,7 @@
  */
 
 #include <linux/platform_device.h>
-#include <linux/sysdev.h>
+#include <linux/syscore_ops.h>
 #include <linux/delay.h>
 #include <linux/irq.h>
 #include <linux/gpio_keys.h>
@@ -233,9 +233,9 @@
 
 static unsigned long store_ptr;
 
-/* sys_device for Palm Zire 72 PM */
+/* syscore_ops for Palm Zire 72 PM */
 
-static int palmz72_pm_suspend(struct sys_device *dev, pm_message_t msg)
+static int palmz72_pm_suspend(void)
 {
 	/* setup the resume_info struct for the original bootloader */
 	palmz72_resume_info.resume_addr = (u32) cpu_resume;
@@ -249,31 +249,23 @@
 	return 0;
 }
 
-static int palmz72_pm_resume(struct sys_device *dev)
+static void palmz72_pm_resume(void)
 {
 	*PALMZ72_SAVE_DWORD = store_ptr;
-	return 0;
 }
 
-static struct sysdev_class palmz72_pm_sysclass = {
-	.name = "palmz72_pm",
+static struct syscore_ops palmz72_pm_syscore_ops = {
 	.suspend = palmz72_pm_suspend,
 	.resume = palmz72_pm_resume,
 };
 
-static struct sys_device palmz72_pm_device = {
-	.cls = &palmz72_pm_sysclass,
-};
-
 static int __init palmz72_pm_init(void)
 {
-	int ret = -ENODEV;
 	if (machine_is_palmz72()) {
-		ret = sysdev_class_register(&palmz72_pm_sysclass);
-		if (ret == 0)
-			ret = sysdev_register(&palmz72_pm_device);
+		register_syscore_ops(&palmz72_pm_syscore_ops);
+		return 0;
 	}
-	return ret;
+	return -ENODEV;
 }
 
 device_initcall(palmz72_pm_init);
diff -druN linux-2.6.39-libre/arch/arm/mach-pxa/pxa25x.c linux-3.0-rc7-libre/arch/arm/mach-pxa/pxa25x.c
--- linux-2.6.39-libre/arch/arm/mach-pxa/pxa25x.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-pxa/pxa25x.c	2011-07-11 19:51:52.000000000 -0400
@@ -21,7 +21,7 @@
 #include <linux/init.h>
 #include <linux/platform_device.h>
 #include <linux/suspend.h>
-#include <linux/sysdev.h>
+#include <linux/syscore_ops.h>
 #include <linux/irq.h>
 
 #include <asm/mach/map.h>
@@ -350,21 +350,9 @@
 	&pxa_device_asoc_platform,
 };
 
-static struct sys_device pxa25x_sysdev[] = {
-	{
-		.cls	= &pxa_irq_sysclass,
-	}, {
-		.cls	= &pxa2xx_mfp_sysclass,
-	}, {
-		.cls	= &pxa_gpio_sysclass,
-	}, {
-		.cls	= &pxa2xx_clock_sysclass,
-	}
-};
-
 static int __init pxa25x_init(void)
 {
-	int i, ret = 0;
+	int ret = 0;
 
 	if (cpu_is_pxa25x()) {
 
@@ -377,11 +365,10 @@
 
 		pxa25x_init_pm();
 
-		for (i = 0; i < ARRAY_SIZE(pxa25x_sysdev); i++) {
-			ret = sysdev_register(&pxa25x_sysdev[i]);
-			if (ret)
-				pr_err("failed to register sysdev[%d]\n", i);
-		}
+		register_syscore_ops(&pxa_irq_syscore_ops);
+		register_syscore_ops(&pxa2xx_mfp_syscore_ops);
+		register_syscore_ops(&pxa_gpio_syscore_ops);
+		register_syscore_ops(&pxa2xx_clock_syscore_ops);
 
 		ret = platform_add_devices(pxa25x_devices,
 					   ARRAY_SIZE(pxa25x_devices));
diff -druN linux-2.6.39-libre/arch/arm/mach-pxa/pxa27x.c linux-3.0-rc7-libre/arch/arm/mach-pxa/pxa27x.c
--- linux-2.6.39-libre/arch/arm/mach-pxa/pxa27x.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-pxa/pxa27x.c	2011-07-11 19:51:52.000000000 -0400
@@ -16,7 +16,7 @@
 #include <linux/init.h>
 #include <linux/suspend.h>
 #include <linux/platform_device.h>
-#include <linux/sysdev.h>
+#include <linux/syscore_ops.h>
 #include <linux/io.h>
 #include <linux/irq.h>
 #include <linux/i2c/pxa-i2c.h>
@@ -428,21 +428,9 @@
 	&pxa27x_device_pwm1,
 };
 
-static struct sys_device pxa27x_sysdev[] = {
-	{
-		.cls	= &pxa_irq_sysclass,
-	}, {
-		.cls	= &pxa2xx_mfp_sysclass,
-	}, {
-		.cls	= &pxa_gpio_sysclass,
-	}, {
-		.cls	= &pxa2xx_clock_sysclass,
-	}
-};
-
 static int __init pxa27x_init(void)
 {
-	int i, ret = 0;
+	int ret = 0;
 
 	if (cpu_is_pxa27x()) {
 
@@ -455,11 +443,10 @@
 
 		pxa27x_init_pm();
 
-		for (i = 0; i < ARRAY_SIZE(pxa27x_sysdev); i++) {
-			ret = sysdev_register(&pxa27x_sysdev[i]);
-			if (ret)
-				pr_err("failed to register sysdev[%d]\n", i);
-		}
+		register_syscore_ops(&pxa_irq_syscore_ops);
+		register_syscore_ops(&pxa2xx_mfp_syscore_ops);
+		register_syscore_ops(&pxa_gpio_syscore_ops);
+		register_syscore_ops(&pxa2xx_clock_syscore_ops);
 
 		ret = platform_add_devices(devices, ARRAY_SIZE(devices));
 	}
diff -druN linux-2.6.39-libre/arch/arm/mach-pxa/pxa3xx.c linux-3.0-rc7-libre/arch/arm/mach-pxa/pxa3xx.c
--- linux-2.6.39-libre/arch/arm/mach-pxa/pxa3xx.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-pxa/pxa3xx.c	2011-07-11 19:51:52.000000000 -0400
@@ -20,7 +20,7 @@
 #include <linux/platform_device.h>
 #include <linux/irq.h>
 #include <linux/io.h>
-#include <linux/sysdev.h>
+#include <linux/syscore_ops.h>
 #include <linux/i2c/pxa-i2c.h>
 
 #include <asm/mach/map.h>
@@ -427,21 +427,9 @@
 	&pxa27x_device_pwm1,
 };
 
-static struct sys_device pxa3xx_sysdev[] = {
-	{
-		.cls	= &pxa_irq_sysclass,
-	}, {
-		.cls	= &pxa3xx_mfp_sysclass,
-	}, {
-		.cls	= &pxa_gpio_sysclass,
-	}, {
-		.cls	= &pxa3xx_clock_sysclass,
-	}
-};
-
 static int __init pxa3xx_init(void)
 {
-	int i, ret = 0;
+	int ret = 0;
 
 	if (cpu_is_pxa3xx()) {
 
@@ -462,11 +450,10 @@
 
 		pxa3xx_init_pm();
 
-		for (i = 0; i < ARRAY_SIZE(pxa3xx_sysdev); i++) {
-			ret = sysdev_register(&pxa3xx_sysdev[i]);
-			if (ret)
-				pr_err("failed to register sysdev[%d]\n", i);
-		}
+		register_syscore_ops(&pxa_irq_syscore_ops);
+		register_syscore_ops(&pxa3xx_mfp_syscore_ops);
+		register_syscore_ops(&pxa_gpio_syscore_ops);
+		register_syscore_ops(&pxa3xx_clock_syscore_ops);
 
 		ret = platform_add_devices(devices, ARRAY_SIZE(devices));
 	}
diff -druN linux-2.6.39-libre/arch/arm/mach-pxa/pxa95x.c linux-3.0-rc7-libre/arch/arm/mach-pxa/pxa95x.c
--- linux-2.6.39-libre/arch/arm/mach-pxa/pxa95x.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-pxa/pxa95x.c	2011-07-11 19:51:52.000000000 -0400
@@ -18,7 +18,7 @@
 #include <linux/i2c/pxa-i2c.h>
 #include <linux/irq.h>
 #include <linux/io.h>
-#include <linux/sysdev.h>
+#include <linux/syscore_ops.h>
 
 #include <mach/hardware.h>
 #include <mach/gpio.h>
@@ -260,16 +260,6 @@
 	&pxa27x_device_pwm1,
 };
 
-static struct sys_device pxa95x_sysdev[] = {
-	{
-		.cls	= &pxa_irq_sysclass,
-	}, {
-		.cls	= &pxa_gpio_sysclass,
-	}, {
-		.cls	= &pxa3xx_clock_sysclass,
-	}
-};
-
 static int __init pxa95x_init(void)
 {
 	int ret = 0, i;
@@ -293,11 +283,9 @@
 		if ((ret = pxa_init_dma(IRQ_DMA, 32)))
 			return ret;
 
-		for (i = 0; i < ARRAY_SIZE(pxa95x_sysdev); i++) {
-			ret = sysdev_register(&pxa95x_sysdev[i]);
-			if (ret)
-				pr_err("failed to register sysdev[%d]\n", i);
-		}
+		register_syscore_ops(&pxa_irq_syscore_ops);
+		register_syscore_ops(&pxa_gpio_syscore_ops);
+		register_syscore_ops(&pxa3xx_clock_syscore_ops);
 
 		ret = platform_add_devices(devices, ARRAY_SIZE(devices));
 	}
diff -druN linux-2.6.39-libre/arch/arm/mach-pxa/raumfeld.c linux-3.0-rc7-libre/arch/arm/mach-pxa/raumfeld.c
--- linux-2.6.39-libre/arch/arm/mach-pxa/raumfeld.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-pxa/raumfeld.c	2011-07-11 19:51:52.000000000 -0400
@@ -18,7 +18,6 @@
 
 #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>
diff -druN linux-2.6.39-libre/arch/arm/mach-pxa/smemc.c linux-3.0-rc7-libre/arch/arm/mach-pxa/smemc.c
--- linux-2.6.39-libre/arch/arm/mach-pxa/smemc.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-pxa/smemc.c	2011-07-11 19:51:52.000000000 -0400
@@ -6,7 +6,7 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/io.h>
-#include <linux/sysdev.h>
+#include <linux/syscore_ops.h>
 
 #include <mach/hardware.h>
 #include <mach/smemc.h>
@@ -16,7 +16,7 @@
 static unsigned long sxcnfg, memclkcfg;
 static unsigned long csadrcfg[4];
 
-static int pxa3xx_smemc_suspend(struct sys_device *dev, pm_message_t state)
+static int pxa3xx_smemc_suspend(void)
 {
 	msc[0] = __raw_readl(MSC0);
 	msc[1] = __raw_readl(MSC1);
@@ -30,7 +30,7 @@
 	return 0;
 }
 
-static int pxa3xx_smemc_resume(struct sys_device *dev)
+static void pxa3xx_smemc_resume(void)
 {
 	__raw_writel(msc[0], MSC0);
 	__raw_writel(msc[1], MSC1);
@@ -40,34 +40,19 @@
 	__raw_writel(csadrcfg[1], CSADRCFG1);
 	__raw_writel(csadrcfg[2], CSADRCFG2);
 	__raw_writel(csadrcfg[3], CSADRCFG3);
-
-	return 0;
 }
 
-static struct sysdev_class smemc_sysclass = {
-	.name		= "smemc",
+static struct syscore_ops smemc_syscore_ops = {
 	.suspend	= pxa3xx_smemc_suspend,
 	.resume		= pxa3xx_smemc_resume,
 };
 
-static struct sys_device smemc_sysdev = {
-	.id		= 0,
-	.cls		= &smemc_sysclass,
-};
-
 static int __init smemc_init(void)
 {
-	int ret = 0;
-
-	if (cpu_is_pxa3xx()) {
-		ret = sysdev_class_register(&smemc_sysclass);
-		if (ret)
-			return ret;
-
-		ret = sysdev_register(&smemc_sysdev);
-	}
+	if (cpu_is_pxa3xx())
+		register_syscore_ops(&smemc_syscore_ops);
 
-	return ret;
+	return 0;
 }
 subsys_initcall(smemc_init);
 #endif
diff -druN linux-2.6.39-libre/arch/arm/mach-pxa/spitz_pm.c linux-3.0-rc7-libre/arch/arm/mach-pxa/spitz_pm.c
--- linux-2.6.39-libre/arch/arm/mach-pxa/spitz_pm.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-pxa/spitz_pm.c	2011-07-11 19:51:52.000000000 -0400
@@ -14,6 +14,7 @@
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/delay.h>
+#include <linux/gpio.h>
 #include <linux/interrupt.h>
 #include <linux/platform_device.h>
 #include <linux/apm-emulation.h>
diff -druN linux-2.6.39-libre/arch/arm/mach-pxa/time.c linux-3.0-rc7-libre/arch/arm/mach-pxa/time.c
--- linux-2.6.39-libre/arch/arm/mach-pxa/time.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-pxa/time.c	2011-07-11 19:51:52.000000000 -0400
@@ -105,19 +105,6 @@
 	.set_mode	= pxa_osmr0_set_mode,
 };
 
-static cycle_t pxa_read_oscr(struct clocksource *cs)
-{
-	return OSCR;
-}
-
-static struct clocksource cksrc_pxa_oscr0 = {
-	.name           = "oscr0",
-	.rating         = 200,
-	.read           = pxa_read_oscr,
-	.mask           = CLOCKSOURCE_MASK(32),
-	.flags		= CLOCK_SOURCE_IS_CONTINUOUS,
-};
-
 static struct irqaction pxa_ost0_irq = {
 	.name		= "ost0",
 	.flags		= IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
@@ -134,7 +121,6 @@
 
 	init_sched_clock(&cd, pxa_update_sched_clock, 32, clock_tick_rate);
 
-	clocksource_calc_mult_shift(&cksrc_pxa_oscr0, clock_tick_rate, 4);
 	clockevents_calc_mult_shift(&ckevt_pxa_osmr0, clock_tick_rate, 4);
 	ckevt_pxa_osmr0.max_delta_ns =
 		clockevent_delta2ns(0x7fffffff, &ckevt_pxa_osmr0);
@@ -144,7 +130,8 @@
 
 	setup_irq(IRQ_OST0, &pxa_ost0_irq);
 
-	clocksource_register_hz(&cksrc_pxa_oscr0, clock_tick_rate);
+	clocksource_mmio_init(&OSCR, "oscr0", clock_tick_rate, 200, 32,
+		clocksource_mmio_readl_up);
 	clockevents_register_device(&ckevt_pxa_osmr0);
 }
 
diff -druN linux-2.6.39-libre/arch/arm/mach-pxa/trizeps4.c linux-3.0-rc7-libre/arch/arm/mach-pxa/trizeps4.c
--- linux-2.6.39-libre/arch/arm/mach-pxa/trizeps4.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-pxa/trizeps4.c	2011-07-11 19:51:52.000000000 -0400
@@ -15,7 +15,6 @@
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/platform_device.h>
-#include <linux/sysdev.h>
 #include <linux/interrupt.h>
 #include <linux/sched.h>
 #include <linux/bitops.h>
diff -druN linux-2.6.39-libre/arch/arm/mach-pxa/viper.c linux-3.0-rc7-libre/arch/arm/mach-pxa/viper.c
--- linux-2.6.39-libre/arch/arm/mach-pxa/viper.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-pxa/viper.c	2011-07-11 19:51:52.000000000 -0400
@@ -44,6 +44,7 @@
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/partitions.h>
 #include <linux/mtd/physmap.h>
+#include <linux/syscore_ops.h>
 
 #include <mach/pxa25x.h>
 #include <mach/audio.h>
@@ -130,20 +131,19 @@
 	return v1;
 }
 
-/* CPU sysdev */
-static int viper_cpu_suspend(struct sys_device *sysdev, pm_message_t state)
+/* CPU system core operations. */
+static int viper_cpu_suspend(void)
 {
 	viper_icr_set_bit(VIPER_ICR_R_DIS);
 	return 0;
 }
 
-static int viper_cpu_resume(struct sys_device *sysdev)
+static void viper_cpu_resume(void)
 {
 	viper_icr_clear_bit(VIPER_ICR_R_DIS);
-	return 0;
 }
 
-static struct sysdev_driver viper_cpu_sysdev_driver = {
+static struct syscore_ops viper_cpu_syscore_ops = {
 	.suspend	= viper_cpu_suspend,
 	.resume		= viper_cpu_resume,
 };
@@ -945,7 +945,7 @@
 	viper_init_vcore_gpios();
 	viper_init_cpufreq();
 
-	sysdev_driver_register(&cpu_sysdev_class, &viper_cpu_sysdev_driver);
+	register_syscore_ops(&viper_cpu_syscore_ops);
 
 	if (version) {
 		pr_info("viper: hardware v%di%d detected. "
diff -druN linux-2.6.39-libre/arch/arm/mach-pxa/vpac270.c linux-3.0-rc7-libre/arch/arm/mach-pxa/vpac270.c
--- linux-2.6.39-libre/arch/arm/mach-pxa/vpac270.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-pxa/vpac270.c	2011-07-11 19:51:52.000000000 -0400
@@ -16,7 +16,6 @@
 #include <linux/gpio_keys.h>
 #include <linux/input.h>
 #include <linux/gpio.h>
-#include <linux/sysdev.h>
 #include <linux/usb/gpio_vbus.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/partitions.h>
diff -druN linux-2.6.39-libre/arch/arm/mach-realview/core.c linux-3.0-rc7-libre/arch/arm/mach-realview/core.c
--- linux-2.6.39-libre/arch/arm/mach-realview/core.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-realview/core.c	2011-07-11 19:51:52.000000000 -0400
@@ -31,6 +31,7 @@
 #include <linux/amba/mmci.h>
 #include <linux/gfp.h>
 #include <linux/clkdev.h>
+#include <linux/mtd/physmap.h>
 
 #include <asm/system.h>
 #include <mach/hardware.h>
@@ -41,7 +42,6 @@
 #include <asm/hardware/icst.h>
 
 #include <asm/mach/arch.h>
-#include <asm/mach/flash.h>
 #include <asm/mach/irq.h>
 #include <asm/mach/map.h>
 
@@ -56,48 +56,9 @@
 
 #include "core.h"
 
-#ifdef CONFIG_ZONE_DMA
-/*
- * Adjust the zones if there are restrictions for DMA access.
- */
-void __init realview_adjust_zones(unsigned long *size, unsigned long *hole)
-{
-	unsigned long dma_size = SZ_256M >> PAGE_SHIFT;
-
-	if (!machine_is_realview_pbx() || size[0] <= dma_size)
-		return;
-
-	size[ZONE_NORMAL] = size[0] - dma_size;
-	size[ZONE_DMA] = dma_size;
-	hole[ZONE_NORMAL] = hole[0];
-	hole[ZONE_DMA] = 0;
-}
-#endif
-
-
 #define REALVIEW_FLASHCTRL    (__io_address(REALVIEW_SYS_BASE) + REALVIEW_SYS_FLASH_OFFSET)
 
-static int realview_flash_init(void)
-{
-	u32 val;
-
-	val = __raw_readl(REALVIEW_FLASHCTRL);
-	val &= ~REALVIEW_FLASHPROG_FLVPPEN;
-	__raw_writel(val, REALVIEW_FLASHCTRL);
-
-	return 0;
-}
-
-static void realview_flash_exit(void)
-{
-	u32 val;
-
-	val = __raw_readl(REALVIEW_FLASHCTRL);
-	val &= ~REALVIEW_FLASHPROG_FLVPPEN;
-	__raw_writel(val, REALVIEW_FLASHCTRL);
-}
-
-static void realview_flash_set_vpp(int on)
+static void realview_flash_set_vpp(struct platform_device *pdev, int on)
 {
 	u32 val;
 
@@ -109,16 +70,13 @@
 	__raw_writel(val, REALVIEW_FLASHCTRL);
 }
 
-static struct flash_platform_data realview_flash_data = {
-	.map_name		= "cfi_probe",
+static struct physmap_flash_data realview_flash_data = {
 	.width			= 4,
-	.init			= realview_flash_init,
-	.exit			= realview_flash_exit,
 	.set_vpp		= realview_flash_set_vpp,
 };
 
 struct platform_device realview_flash_device = {
-	.name			= "armflash",
+	.name			= "physmap-flash",
 	.id			= 0,
 	.dev			= {
 		.platform_data	= &realview_flash_data,
@@ -315,6 +273,10 @@
 	.rate	= 24000000,
 };
 
+static struct clk sp804_clk = {
+	.rate	= 1000000,
+};
+
 static struct clk dummy_apb_pclk;
 
 static struct clk_lookup lookups[] = {
@@ -357,7 +319,10 @@
 	}, {	/* SSP */
 		.dev_id		= "dev:ssp0",
 		.clk		= &ref24_clk,
-	}
+	}, {	/* SP804 timers */
+		.dev_id		= "sp804",
+		.clk		= &sp804_clk,
+	},
 };
 
 void __init realview_init_early(void)
@@ -545,8 +510,8 @@
 	writel(0, timer2_va_base + TIMER_CTRL);
 	writel(0, timer3_va_base + TIMER_CTRL);
 
-	sp804_clocksource_init(timer3_va_base);
-	sp804_clockevents_init(timer0_va_base, timer_irq);
+	sp804_clocksource_init(timer3_va_base, "timer3");
+	sp804_clockevents_init(timer0_va_base, timer_irq, "timer0");
 }
 
 /*
diff -druN linux-2.6.39-libre/arch/arm/mach-realview/include/mach/memory.h linux-3.0-rc7-libre/arch/arm/mach-realview/include/mach/memory.h
--- linux-2.6.39-libre/arch/arm/mach-realview/include/mach/memory.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-realview/include/mach/memory.h	2011-07-11 19:51:52.000000000 -0400
@@ -29,13 +29,8 @@
 #define PLAT_PHYS_OFFSET		UL(0x00000000)
 #endif
 
-#if !defined(__ASSEMBLY__) && defined(CONFIG_ZONE_DMA)
-extern void realview_adjust_zones(unsigned long *size, unsigned long *hole);
-#define arch_adjust_zones(size, hole) \
-	realview_adjust_zones(size, hole)
-
-#define ISA_DMA_THRESHOLD	(PHYS_OFFSET + SZ_256M - 1)
-#define MAX_DMA_ADDRESS		(PAGE_OFFSET + SZ_256M)
+#ifdef CONFIG_ZONE_DMA
+#define ARM_DMA_ZONE_SIZE	SZ_256M
 #endif
 
 #ifdef CONFIG_SPARSEMEM
diff -druN linux-2.6.39-libre/arch/arm/mach-realview/include/mach/smp.h linux-3.0-rc7-libre/arch/arm/mach-realview/include/mach/smp.h
--- linux-2.6.39-libre/arch/arm/mach-realview/include/mach/smp.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-realview/include/mach/smp.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,14 +0,0 @@
-#ifndef ASMARM_ARCH_SMP_H
-#define ASMARM_ARCH_SMP_H
-
-#include <asm/hardware/gic.h>
-
-/*
- * We use IRQ1 as the IPI
- */
-static inline void smp_cross_call(const struct cpumask *mask, int ipi)
-{
-	gic_raise_softirq(mask, ipi);
-}
-
-#endif
diff -druN linux-2.6.39-libre/arch/arm/mach-realview/platsmp.c linux-3.0-rc7-libre/arch/arm/mach-realview/platsmp.c
--- linux-2.6.39-libre/arch/arm/mach-realview/platsmp.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-realview/platsmp.c	2011-07-11 19:51:52.000000000 -0400
@@ -14,6 +14,7 @@
 #include <linux/io.h>
 
 #include <mach/hardware.h>
+#include <asm/hardware/gic.h>
 #include <asm/mach-types.h>
 #include <asm/smp_scu.h>
 #include <asm/unified.h>
@@ -61,6 +62,8 @@
 
 	for (i = 0; i < ncores; i++)
 		set_cpu_possible(i, true);
+
+	set_smp_cross_call(gic_raise_softirq);
 }
 
 void __init platform_smp_prepare_cpus(unsigned int max_cpus)
diff -druN linux-2.6.39-libre/arch/arm/mach-rpc/include/mach/uncompress.h linux-3.0-rc7-libre/arch/arm/mach-rpc/include/mach/uncompress.h
--- linux-2.6.39-libre/arch/arm/mach-rpc/include/mach/uncompress.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-rpc/include/mach/uncompress.h	2011-07-11 19:51:52.000000000 -0400
@@ -66,12 +66,12 @@
 #define params (params())
 
 #ifndef STANDALONE_DEBUG 
-static unsigned long video_num_cols;
-static unsigned long video_num_rows;
-static unsigned long video_x;
-static unsigned long video_y;
-static unsigned char bytes_per_char_v;
-static int white;
+unsigned long video_num_cols;
+unsigned long video_num_rows;
+unsigned long video_x;
+unsigned long video_y;
+unsigned char bytes_per_char_v;
+int white;
 
 /*
  * This does not append a newline
diff -druN linux-2.6.39-libre/arch/arm/mach-s3c2410/include/mach/map.h linux-3.0-rc7-libre/arch/arm/mach-s3c2410/include/mach/map.h
--- linux-2.6.39-libre/arch/arm/mach-s3c2410/include/mach/map.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-s3c2410/include/mach/map.h	2011-07-11 19:51:52.000000000 -0400
@@ -21,6 +21,10 @@
 /* USB host controller */
 #define S3C2410_PA_USBHOST (0x49000000)
 
+/* S3C2416/S3C2443/S3C2450 High-Speed USB Gadget */
+#define S3C2416_PA_HSUDC	(0x49800000)
+#define S3C2416_SZ_HSUDC	(SZ_4K)
+
 /* DMA controller */
 #define S3C2410_PA_DMA	   (0x4B000000)
 #define S3C24XX_SZ_DMA	   SZ_1M
diff -druN linux-2.6.39-libre/arch/arm/mach-s3c2410/include/mach/regs-s3c2443-clock.h linux-3.0-rc7-libre/arch/arm/mach-s3c2410/include/mach/regs-s3c2443-clock.h
--- linux-2.6.39-libre/arch/arm/mach-s3c2410/include/mach/regs-s3c2443-clock.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-s3c2410/include/mach/regs-s3c2443-clock.h	2011-07-11 19:51:52.000000000 -0400
@@ -37,6 +37,10 @@
 #define S3C2443_SYSID			S3C2443_CLKREG(0x5C)
 #define S3C2443_PWRCFG			S3C2443_CLKREG(0x60)
 #define S3C2443_RSTCON			S3C2443_CLKREG(0x64)
+#define S3C2443_PHYCTRL			S3C2443_CLKREG(0x80)
+#define S3C2443_PHYPWR			S3C2443_CLKREG(0x84)
+#define S3C2443_URSTCON			S3C2443_CLKREG(0x88)
+#define S3C2443_UCLKCON			S3C2443_CLKREG(0x8C)
 
 #define S3C2443_SWRST_RESET		(0x533c2443)
 
@@ -121,6 +125,27 @@
 
 #define S3C2443_PWRCFG_SLEEP		(1<<15)
 
+#define S3C2443_PWRCFG_USBPHY		(1 << 4)
+
+#define S3C2443_URSTCON_FUNCRST		(1 << 2)
+#define S3C2443_URSTCON_PHYRST		(1 << 0)
+
+#define S3C2443_PHYCTRL_CLKSEL		(1 << 3)
+#define S3C2443_PHYCTRL_EXTCLK		(1 << 2)
+#define S3C2443_PHYCTRL_PLLSEL		(1 << 1)
+#define S3C2443_PHYCTRL_DSPORT		(1 << 0)
+
+#define S3C2443_PHYPWR_COMMON_ON	(1 << 31)
+#define S3C2443_PHYPWR_ANALOG_PD	(1 << 4)
+#define S3C2443_PHYPWR_PLL_REFCLK	(1 << 3)
+#define S3C2443_PHYPWR_XO_ON		(1 << 2)
+#define S3C2443_PHYPWR_PLL_PWRDN	(1 << 1)
+#define S3C2443_PHYPWR_FSUSPEND		(1 << 0)
+
+#define S3C2443_UCLKCON_DETECT_VBUS	(1 << 31)
+#define S3C2443_UCLKCON_FUNC_CLKEN	(1 << 2)
+#define S3C2443_UCLKCON_TCLKEN		(1 << 0)
+
 #include <asm/div64.h>
 
 static inline unsigned int
diff -druN linux-2.6.39-libre/arch/arm/mach-s3c2410/irq.c linux-3.0-rc7-libre/arch/arm/mach-s3c2410/irq.c
--- linux-2.6.39-libre/arch/arm/mach-s3c2410/irq.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-s3c2410/irq.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,60 +0,0 @@
-/* linux/arch/arm/mach-s3c2410/irq.c
- *
- * Copyright (c) 2006 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 <plat/cpu.h>
-#include <plat/pm.h>
-
-static int s3c2410_irq_add(struct sys_device *sysdev)
-{
-	return 0;
-}
-
-static struct sysdev_driver s3c2410_irq_driver = {
-	.add		= s3c2410_irq_add,
-	.suspend	= s3c24xx_irq_suspend,
-	.resume		= s3c24xx_irq_resume,
-};
-
-static int __init s3c2410_irq_init(void)
-{
-	return sysdev_driver_register(&s3c2410_sysclass, &s3c2410_irq_driver);
-}
-
-arch_initcall(s3c2410_irq_init);
-
-static struct sysdev_driver s3c2410a_irq_driver = {
-	.add		= s3c2410_irq_add,
-	.suspend	= s3c24xx_irq_suspend,
-	.resume		= s3c24xx_irq_resume,
-};
-
-static int __init s3c2410a_irq_init(void)
-{
-	return sysdev_driver_register(&s3c2410a_sysclass, &s3c2410a_irq_driver);
-}
-
-arch_initcall(s3c2410a_irq_init);
diff -druN linux-2.6.39-libre/arch/arm/mach-s3c2410/mach-amlm5900.c linux-3.0-rc7-libre/arch/arm/mach-s3c2410/mach-amlm5900.c
--- linux-2.6.39-libre/arch/arm/mach-s3c2410/mach-amlm5900.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-s3c2410/mach-amlm5900.c	2011-07-11 19:51:52.000000000 -0400
@@ -58,8 +58,6 @@
 #include <plat/cpu.h>
 #include <plat/gpio-cfg.h>
 
-#ifdef CONFIG_MTD_PARTITIONS
-
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/partitions.h>
 #include <linux/mtd/map.h>
@@ -113,7 +111,6 @@
 	.num_resources	= 1,
 	.resource	= &amlm5900_nor_resource,
 };
-#endif
 
 static struct map_desc amlm5900_iodesc[] __initdata = {
 };
@@ -158,9 +155,7 @@
  	&s3c_device_rtc,
 	&s3c_device_usbgadget,
         &s3c_device_sdi,
-#ifdef CONFIG_MTD_PARTITIONS
 	&amlm5900_device_nor,
-#endif
 };
 
 static void __init amlm5900_map_io(void)
diff -druN linux-2.6.39-libre/arch/arm/mach-s3c2410/mach-bast.c linux-3.0-rc7-libre/arch/arm/mach-s3c2410/mach-bast.c
--- linux-2.6.39-libre/arch/arm/mach-s3c2410/mach-bast.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-s3c2410/mach-bast.c	2011-07-11 19:51:52.000000000 -0400
@@ -17,7 +17,7 @@
 #include <linux/timer.h>
 #include <linux/init.h>
 #include <linux/gpio.h>
-#include <linux/sysdev.h>
+#include <linux/syscore_ops.h>
 #include <linux/serial_core.h>
 #include <linux/platform_device.h>
 #include <linux/dm9000.h>
@@ -214,17 +214,16 @@
 /* NAND Flash on BAST board */
 
 #ifdef CONFIG_PM
-static int bast_pm_suspend(struct sys_device *sd, pm_message_t state)
+static int bast_pm_suspend(void)
 {
 	/* ensure that an nRESET is not generated on resume. */
 	gpio_direction_output(S3C2410_GPA(21), 1);
 	return 0;
 }
 
-static int bast_pm_resume(struct sys_device *sd)
+static void bast_pm_resume(void)
 {
 	s3c_gpio_cfgpin(S3C2410_GPA(21), S3C2410_GPA21_nRSTOUT);
-	return 0;
 }
 
 #else
@@ -232,16 +231,11 @@
 #define bast_pm_resume NULL
 #endif
 
-static struct sysdev_class bast_pm_sysclass = {
-	.name		= "mach-bast",
+static struct syscore_ops bast_pm_syscore_ops = {
 	.suspend	= bast_pm_suspend,
 	.resume		= bast_pm_resume,
 };
 
-static struct sys_device bast_pm_sysdev = {
-	.cls		= &bast_pm_sysclass,
-};
-
 static int smartmedia_map[] = { 0 };
 static int chip0_map[] = { 1 };
 static int chip1_map[] = { 2 };
@@ -642,8 +636,7 @@
 
 static void __init bast_init(void)
 {
-	sysdev_class_register(&bast_pm_sysclass);
-	sysdev_register(&bast_pm_sysdev);
+	register_syscore_ops(&bast_pm_syscore_ops);
 
 	s3c_i2c0_set_platdata(&bast_i2c_info);
 	s3c_nand_set_platdata(&bast_nand_info);
diff -druN linux-2.6.39-libre/arch/arm/mach-s3c2410/mach-tct_hammer.c linux-3.0-rc7-libre/arch/arm/mach-s3c2410/mach-tct_hammer.c
--- linux-2.6.39-libre/arch/arm/mach-s3c2410/mach-tct_hammer.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-s3c2410/mach-tct_hammer.c	2011-07-11 19:51:52.000000000 -0400
@@ -49,8 +49,6 @@
 #include <plat/devs.h>
 #include <plat/cpu.h>
 
-#ifdef CONFIG_MTD_PARTITIONS
-
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/partitions.h>
 #include <linux/mtd/map.h>
@@ -91,8 +89,6 @@
 	.resource	= &tct_hammer_nor_resource,
 };
 
-#endif
-
 static struct map_desc tct_hammer_iodesc[] __initdata = {
 };
 
@@ -133,9 +129,7 @@
 	&s3c_device_rtc,
 	&s3c_device_usbgadget,
 	&s3c_device_sdi,
-#ifdef CONFIG_MTD_PARTITIONS
 	&tct_hammer_device_nor,
-#endif
 };
 
 static void __init tct_hammer_map_io(void)
diff -druN linux-2.6.39-libre/arch/arm/mach-s3c2410/Makefile linux-3.0-rc7-libre/arch/arm/mach-s3c2410/Makefile
--- linux-2.6.39-libre/arch/arm/mach-s3c2410/Makefile	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-s3c2410/Makefile	2011-07-11 19:51:52.000000000 -0400
@@ -10,7 +10,6 @@
 obj-				:=
 
 obj-$(CONFIG_CPU_S3C2410)	+= s3c2410.o
-obj-$(CONFIG_CPU_S3C2410)	+= irq.o
 obj-$(CONFIG_CPU_S3C2410_DMA)	+= dma.o
 obj-$(CONFIG_CPU_S3C2410_DMA)	+= dma.o
 obj-$(CONFIG_S3C2410_PM)	+= pm.o sleep.o
diff -druN linux-2.6.39-libre/arch/arm/mach-s3c2410/nor-simtec.c linux-3.0-rc7-libre/arch/arm/mach-s3c2410/nor-simtec.c
--- linux-2.6.39-libre/arch/arm/mach-s3c2410/nor-simtec.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-s3c2410/nor-simtec.c	2011-07-11 19:51:52.000000000 -0400
@@ -32,7 +32,7 @@
 
 #include "nor-simtec.h"
 
-static void simtec_nor_vpp(struct map_info *map, int vpp)
+static void simtec_nor_vpp(struct platform_device *pdev, int vpp)
 {
 	unsigned int val;
 	unsigned long flags;
diff -druN linux-2.6.39-libre/arch/arm/mach-s3c2410/pm.c linux-3.0-rc7-libre/arch/arm/mach-s3c2410/pm.c
--- linux-2.6.39-libre/arch/arm/mach-s3c2410/pm.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-s3c2410/pm.c	2011-07-11 19:51:52.000000000 -0400
@@ -25,6 +25,7 @@
 #include <linux/errno.h>
 #include <linux/time.h>
 #include <linux/sysdev.h>
+#include <linux/syscore_ops.h>
 #include <linux/gpio.h>
 #include <linux/io.h>
 
@@ -92,7 +93,7 @@
 	}
 }
 
-static int s3c2410_pm_resume(struct sys_device *dev)
+static void s3c2410_pm_resume(void)
 {
 	unsigned long tmp;
 
@@ -104,10 +105,12 @@
 
 	if ( machine_is_aml_m5900() )
 		s3c2410_gpio_setpin(S3C2410_GPF(2), 0);
-
-	return 0;
 }
 
+struct syscore_ops s3c2410_pm_syscore_ops = {
+	.resume		= s3c2410_pm_resume,
+};
+
 static int s3c2410_pm_add(struct sys_device *dev)
 {
 	pm_cpu_prep = s3c2410_pm_prepare;
@@ -119,7 +122,6 @@
 #if defined(CONFIG_CPU_S3C2410)
 static struct sysdev_driver s3c2410_pm_driver = {
 	.add		= s3c2410_pm_add,
-	.resume		= s3c2410_pm_resume,
 };
 
 /* register ourselves */
@@ -133,7 +135,6 @@
 
 static struct sysdev_driver s3c2410a_pm_driver = {
 	.add		= s3c2410_pm_add,
-	.resume		= s3c2410_pm_resume,
 };
 
 static int __init s3c2410a_pm_drvinit(void)
@@ -147,7 +148,6 @@
 #if defined(CONFIG_CPU_S3C2440)
 static struct sysdev_driver s3c2440_pm_driver = {
 	.add		= s3c2410_pm_add,
-	.resume		= s3c2410_pm_resume,
 };
 
 static int __init s3c2440_pm_drvinit(void)
@@ -161,7 +161,6 @@
 #if defined(CONFIG_CPU_S3C2442)
 static struct sysdev_driver s3c2442_pm_driver = {
 	.add		= s3c2410_pm_add,
-	.resume		= s3c2410_pm_resume,
 };
 
 static int __init s3c2442_pm_drvinit(void)
diff -druN linux-2.6.39-libre/arch/arm/mach-s3c2410/s3c2410.c linux-3.0-rc7-libre/arch/arm/mach-s3c2410/s3c2410.c
--- linux-2.6.39-libre/arch/arm/mach-s3c2410/s3c2410.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-s3c2410/s3c2410.c	2011-07-11 19:51:52.000000000 -0400
@@ -19,6 +19,7 @@
 #include <linux/gpio.h>
 #include <linux/clk.h>
 #include <linux/sysdev.h>
+#include <linux/syscore_ops.h>
 #include <linux/serial_core.h>
 #include <linux/platform_device.h>
 #include <linux/io.h>
@@ -40,6 +41,7 @@
 #include <plat/devs.h>
 #include <plat/clock.h>
 #include <plat/pll.h>
+#include <plat/pm.h>
 
 #include <plat/gpio-core.h>
 #include <plat/gpio-cfg.h>
@@ -168,6 +170,9 @@
 {
 	printk("S3C2410: Initialising architecture\n");
 
+	register_syscore_ops(&s3c2410_pm_syscore_ops);
+	register_syscore_ops(&s3c24xx_irq_syscore_ops);
+
 	return sysdev_register(&s3c2410_sysdev);
 }
 
diff -druN linux-2.6.39-libre/arch/arm/mach-s3c2412/irq.c linux-3.0-rc7-libre/arch/arm/mach-s3c2412/irq.c
--- linux-2.6.39-libre/arch/arm/mach-s3c2412/irq.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-s3c2412/irq.c	2011-07-11 19:51:52.000000000 -0400
@@ -202,8 +202,6 @@
 
 static struct sysdev_driver s3c2412_irq_driver = {
 	.add		= s3c2412_irq_add,
-	.suspend	= s3c24xx_irq_suspend,
-	.resume		= s3c24xx_irq_resume,
 };
 
 static int s3c2412_irq_init(void)
diff -druN linux-2.6.39-libre/arch/arm/mach-s3c2412/mach-jive.c linux-3.0-rc7-libre/arch/arm/mach-s3c2412/mach-jive.c
--- linux-2.6.39-libre/arch/arm/mach-s3c2412/mach-jive.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-s3c2412/mach-jive.c	2011-07-11 19:51:52.000000000 -0400
@@ -17,7 +17,7 @@
 #include <linux/timer.h>
 #include <linux/init.h>
 #include <linux/gpio.h>
-#include <linux/sysdev.h>
+#include <linux/syscore_ops.h>
 #include <linux/serial_core.h>
 #include <linux/platform_device.h>
 #include <linux/i2c.h>
@@ -486,7 +486,7 @@
 /* Jive power management device */
 
 #ifdef CONFIG_PM
-static int jive_pm_suspend(struct sys_device *sd, pm_message_t state)
+static int jive_pm_suspend(void)
 {
 	/* Write the magic value u-boot uses to check for resume into
 	 * the INFORM0 register, and ensure INFORM1 is set to the
@@ -498,10 +498,9 @@
 	return 0;
 }
 
-static int jive_pm_resume(struct sys_device *sd)
+static void jive_pm_resume(void)
 {
 	__raw_writel(0x0, S3C2412_INFORM0);
-	return 0;
 }
 
 #else
@@ -509,16 +508,11 @@
 #define jive_pm_resume NULL
 #endif
 
-static struct sysdev_class jive_pm_sysclass = {
-	.name		= "jive-pm",
+static struct syscore_ops jive_pm_syscore_ops = {
 	.suspend	= jive_pm_suspend,
 	.resume		= jive_pm_resume,
 };
 
-static struct sys_device jive_pm_sysdev = {
-	.cls		= &jive_pm_sysclass,
-};
-
 static void __init jive_map_io(void)
 {
 	s3c24xx_init_io(jive_iodesc, ARRAY_SIZE(jive_iodesc));
@@ -536,10 +530,9 @@
 
 static void __init jive_machine_init(void)
 {
-	/* register system devices for managing low level suspend */
+	/* register system core operations for managing low level suspend */
 
-	sysdev_class_register(&jive_pm_sysclass);
-	sysdev_register(&jive_pm_sysdev);
+	register_syscore_ops(&jive_pm_syscore_ops);
 
 	/* write our sleep configurations for the IO. Pull down all unused
 	 * IO, ensure that we have turned off all peripherals we do not
diff -druN linux-2.6.39-libre/arch/arm/mach-s3c2412/pm.c linux-3.0-rc7-libre/arch/arm/mach-s3c2412/pm.c
--- linux-2.6.39-libre/arch/arm/mach-s3c2412/pm.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-s3c2412/pm.c	2011-07-11 19:51:52.000000000 -0400
@@ -17,6 +17,7 @@
 #include <linux/timer.h>
 #include <linux/init.h>
 #include <linux/sysdev.h>
+#include <linux/syscore_ops.h>
 #include <linux/platform_device.h>
 #include <linux/io.h>
 
@@ -86,13 +87,24 @@
 	SAVE_ITEM(S3C2413_GPJSLPCON),
 };
 
-static int s3c2412_pm_suspend(struct sys_device *dev, pm_message_t state)
+static struct sysdev_driver s3c2412_pm_driver = {
+	.add		= s3c2412_pm_add,
+};
+
+static __init int s3c2412_pm_init(void)
+{
+	return sysdev_driver_register(&s3c2412_sysclass, &s3c2412_pm_driver);
+}
+
+arch_initcall(s3c2412_pm_init);
+
+static int s3c2412_pm_suspend(void)
 {
 	s3c_pm_do_save(s3c2412_sleep, ARRAY_SIZE(s3c2412_sleep));
 	return 0;
 }
 
-static int s3c2412_pm_resume(struct sys_device *dev)
+static void s3c2412_pm_resume(void)
 {
 	unsigned long tmp;
 
@@ -102,18 +114,9 @@
 	__raw_writel(tmp, S3C2412_PWRCFG);
 
 	s3c_pm_do_restore(s3c2412_sleep, ARRAY_SIZE(s3c2412_sleep));
-	return 0;
 }
 
-static struct sysdev_driver s3c2412_pm_driver = {
-	.add		= s3c2412_pm_add,
+struct syscore_ops s3c2412_pm_syscore_ops = {
 	.suspend	= s3c2412_pm_suspend,
 	.resume		= s3c2412_pm_resume,
 };
-
-static __init int s3c2412_pm_init(void)
-{
-	return sysdev_driver_register(&s3c2412_sysclass, &s3c2412_pm_driver);
-}
-
-arch_initcall(s3c2412_pm_init);
diff -druN linux-2.6.39-libre/arch/arm/mach-s3c2412/s3c2412.c linux-3.0-rc7-libre/arch/arm/mach-s3c2412/s3c2412.c
--- linux-2.6.39-libre/arch/arm/mach-s3c2412/s3c2412.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-s3c2412/s3c2412.c	2011-07-11 19:51:52.000000000 -0400
@@ -19,6 +19,7 @@
 #include <linux/clk.h>
 #include <linux/delay.h>
 #include <linux/sysdev.h>
+#include <linux/syscore_ops.h>
 #include <linux/serial_core.h>
 #include <linux/platform_device.h>
 #include <linux/io.h>
@@ -244,5 +245,8 @@
 {
 	printk("S3C2412: Initialising architecture\n");
 
+	register_syscore_ops(&s3c2412_pm_syscore_ops);
+	register_syscore_ops(&s3c24xx_irq_syscore_ops);
+
 	return sysdev_register(&s3c2412_sysdev);
 }
diff -druN linux-2.6.39-libre/arch/arm/mach-s3c2416/irq.c linux-3.0-rc7-libre/arch/arm/mach-s3c2416/irq.c
--- linux-2.6.39-libre/arch/arm/mach-s3c2416/irq.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-s3c2416/irq.c	2011-07-11 19:51:52.000000000 -0400
@@ -236,8 +236,6 @@
 
 static struct sysdev_driver s3c2416_irq_driver = {
 	.add		= s3c2416_irq_add,
-	.suspend	= s3c24xx_irq_suspend,
-	.resume		= s3c24xx_irq_resume,
 };
 
 static int __init s3c2416_irq_init(void)
diff -druN linux-2.6.39-libre/arch/arm/mach-s3c2416/mach-smdk2416.c linux-3.0-rc7-libre/arch/arm/mach-s3c2416/mach-smdk2416.c
--- linux-2.6.39-libre/arch/arm/mach-s3c2416/mach-smdk2416.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-s3c2416/mach-smdk2416.c	2011-07-11 19:51:52.000000000 -0400
@@ -23,6 +23,7 @@
 #include <linux/mtd/partitions.h>
 #include <linux/gpio.h>
 #include <linux/fb.h>
+#include <linux/delay.h>
 
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
@@ -35,6 +36,7 @@
 #include <plat/regs-serial.h>
 #include <mach/regs-gpio.h>
 #include <mach/regs-lcd.h>
+#include <mach/regs-s3c2443-clock.h>
 
 #include <mach/idle.h>
 #include <mach/leds-gpio.h>
@@ -47,6 +49,7 @@
 #include <plat/cpu.h>
 #include <plat/nand.h>
 #include <plat/sdhci.h>
+#include <plat/udc.h>
 
 #include <plat/regs-fb-v4.h>
 #include <plat/fb.h>
@@ -121,6 +124,27 @@
 	}
 };
 
+void smdk2416_hsudc_gpio_init(void)
+{
+	s3c_gpio_setpull(S3C2410_GPH(14), S3C_GPIO_PULL_UP);
+	s3c_gpio_setpull(S3C2410_GPF(2), S3C_GPIO_PULL_NONE);
+	s3c_gpio_cfgpin(S3C2410_GPH(14), S3C_GPIO_SFN(1));
+	s3c2410_modify_misccr(S3C2416_MISCCR_SEL_SUSPND, 0);
+}
+
+void smdk2416_hsudc_gpio_uninit(void)
+{
+	s3c2410_modify_misccr(S3C2416_MISCCR_SEL_SUSPND, 1);
+	s3c_gpio_setpull(S3C2410_GPH(14), S3C_GPIO_PULL_NONE);
+	s3c_gpio_cfgpin(S3C2410_GPH(14), S3C_GPIO_SFN(0));
+}
+
+struct s3c24xx_hsudc_platdata smdk2416_hsudc_platdata = {
+	.epnum = 9,
+	.gpio_init = smdk2416_hsudc_gpio_init,
+	.gpio_uninit = smdk2416_hsudc_gpio_uninit,
+};
+
 struct s3c_fb_pd_win smdk2416_fb_win[] = {
 	[0] = {
 		/* think this is the same as the smdk6410 */
@@ -186,6 +210,7 @@
 	&s3c_device_i2c0,
 	&s3c_device_hsmmc0,
 	&s3c_device_hsmmc1,
+	&s3c_device_usb_hsudc,
 };
 
 static void __init smdk2416_map_io(void)
@@ -203,6 +228,8 @@
 	s3c_sdhci0_set_platdata(&smdk2416_hsmmc0_pdata);
 	s3c_sdhci1_set_platdata(&smdk2416_hsmmc1_pdata);
 
+	s3c24xx_hsudc_set_platdata(&smdk2416_hsudc_platdata);
+
 	gpio_request(S3C2410_GPB(4), "USBHost Power");
 	gpio_direction_output(S3C2410_GPB(4), 1);
 
diff -druN linux-2.6.39-libre/arch/arm/mach-s3c2416/pm.c linux-3.0-rc7-libre/arch/arm/mach-s3c2416/pm.c
--- linux-2.6.39-libre/arch/arm/mach-s3c2416/pm.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-s3c2416/pm.c	2011-07-11 19:51:52.000000000 -0400
@@ -11,6 +11,7 @@
 */
 
 #include <linux/sysdev.h>
+#include <linux/syscore_ops.h>
 #include <linux/io.h>
 
 #include <asm/cacheflush.h>
@@ -55,30 +56,26 @@
 	return 0;
 }
 
-static int s3c2416_pm_suspend(struct sys_device *dev, pm_message_t state)
+static struct sysdev_driver s3c2416_pm_driver = {
+	.add		= s3c2416_pm_add,
+};
+
+static __init int s3c2416_pm_init(void)
 {
-	return 0;
+	return sysdev_driver_register(&s3c2416_sysclass, &s3c2416_pm_driver);
 }
 
-static int s3c2416_pm_resume(struct sys_device *dev)
+arch_initcall(s3c2416_pm_init);
+
+
+static void s3c2416_pm_resume(void)
 {
 	/* unset the return-from-sleep amd inform flags */
 	__raw_writel(0x0, S3C2443_PWRMODE);
 	__raw_writel(0x0, S3C2412_INFORM0);
 	__raw_writel(0x0, S3C2412_INFORM1);
-
-	return 0;
 }
 
-static struct sysdev_driver s3c2416_pm_driver = {
-	.add		= s3c2416_pm_add,
-	.suspend	= s3c2416_pm_suspend,
+struct syscore_ops s3c2416_pm_syscore_ops = {
 	.resume		= s3c2416_pm_resume,
 };
-
-static __init int s3c2416_pm_init(void)
-{
-	return sysdev_driver_register(&s3c2416_sysclass, &s3c2416_pm_driver);
-}
-
-arch_initcall(s3c2416_pm_init);
diff -druN linux-2.6.39-libre/arch/arm/mach-s3c2416/s3c2416.c linux-3.0-rc7-libre/arch/arm/mach-s3c2416/s3c2416.c
--- linux-2.6.39-libre/arch/arm/mach-s3c2416/s3c2416.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-s3c2416/s3c2416.c	2011-07-11 19:51:52.000000000 -0400
@@ -32,6 +32,7 @@
 #include <linux/platform_device.h>
 #include <linux/serial_core.h>
 #include <linux/sysdev.h>
+#include <linux/syscore_ops.h>
 #include <linux/clk.h>
 #include <linux/io.h>
 
@@ -54,6 +55,7 @@
 #include <plat/devs.h>
 #include <plat/cpu.h>
 #include <plat/sdhci.h>
+#include <plat/pm.h>
 
 #include <plat/iic-core.h>
 #include <plat/fb-core.h>
@@ -95,6 +97,9 @@
 
 	s3c_fb_setname("s3c2443-fb");
 
+	register_syscore_ops(&s3c2416_pm_syscore_ops);
+	register_syscore_ops(&s3c24xx_irq_syscore_ops);
+
 	return sysdev_register(&s3c2416_sysdev);
 }
 
diff -druN linux-2.6.39-libre/arch/arm/mach-s3c2440/mach-mini2440.c linux-3.0-rc7-libre/arch/arm/mach-s3c2440/mach-mini2440.c
--- linux-2.6.39-libre/arch/arm/mach-s3c2440/mach-mini2440.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-s3c2440/mach-mini2440.c	2011-07-11 19:51:52.000000000 -0400
@@ -552,7 +552,7 @@
 	struct platform_device *optional[8];
 };
 
-static void mini2440_parse_features(
+static void __init mini2440_parse_features(
 		struct mini2440_features_t * features,
 		const char * features_str )
 {
diff -druN linux-2.6.39-libre/arch/arm/mach-s3c2440/mach-osiris.c linux-3.0-rc7-libre/arch/arm/mach-s3c2440/mach-osiris.c
--- linux-2.6.39-libre/arch/arm/mach-s3c2440/mach-osiris.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-s3c2440/mach-osiris.c	2011-07-11 19:51:52.000000000 -0400
@@ -17,7 +17,7 @@
 #include <linux/init.h>
 #include <linux/gpio.h>
 #include <linux/device.h>
-#include <linux/sysdev.h>
+#include <linux/syscore_ops.h>
 #include <linux/serial_core.h>
 #include <linux/clk.h>
 #include <linux/i2c.h>
@@ -284,7 +284,7 @@
 #ifdef CONFIG_PM
 static unsigned char pm_osiris_ctrl0;
 
-static int osiris_pm_suspend(struct sys_device *sd, pm_message_t state)
+static int osiris_pm_suspend(void)
 {
 	unsigned int tmp;
 
@@ -304,7 +304,7 @@
 	return 0;
 }
 
-static int osiris_pm_resume(struct sys_device *sd)
+static void osiris_pm_resume(void)
 {
 	if (pm_osiris_ctrl0 & OSIRIS_CTRL0_FIX8)
 		__raw_writeb(OSIRIS_CTRL1_FIX8, OSIRIS_VA_CTRL1);
@@ -312,8 +312,6 @@
 	__raw_writeb(pm_osiris_ctrl0, OSIRIS_VA_CTRL0);
 
 	s3c_gpio_cfgpin(S3C2410_GPA(21), S3C2410_GPA21_nRSTOUT);
-
-	return 0;
 }
 
 #else
@@ -321,16 +319,11 @@
 #define osiris_pm_resume NULL
 #endif
 
-static struct sysdev_class osiris_pm_sysclass = {
-	.name		= "mach-osiris",
+static struct syscore_ops osiris_pm_syscore_ops = {
 	.suspend	= osiris_pm_suspend,
 	.resume		= osiris_pm_resume,
 };
 
-static struct sys_device osiris_pm_sysdev = {
-	.cls		= &osiris_pm_sysclass,
-};
-
 /* Link for DVS driver to TPS65011 */
 
 static void osiris_tps_release(struct device *dev)
@@ -439,8 +432,7 @@
 
 static void __init osiris_init(void)
 {
-	sysdev_class_register(&osiris_pm_sysclass);
-	sysdev_register(&osiris_pm_sysdev);
+	register_syscore_ops(&osiris_pm_syscore_ops);
 
 	s3c_i2c0_set_platdata(NULL);
 	s3c_nand_set_platdata(&osiris_nand_info);
diff -druN linux-2.6.39-libre/arch/arm/mach-s3c2440/s3c2440.c linux-3.0-rc7-libre/arch/arm/mach-s3c2440/s3c2440.c
--- linux-2.6.39-libre/arch/arm/mach-s3c2440/s3c2440.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-s3c2440/s3c2440.c	2011-07-11 19:51:52.000000000 -0400
@@ -19,6 +19,7 @@
 #include <linux/platform_device.h>
 #include <linux/serial_core.h>
 #include <linux/sysdev.h>
+#include <linux/syscore_ops.h>
 #include <linux/gpio.h>
 #include <linux/clk.h>
 #include <linux/io.h>
@@ -33,6 +34,7 @@
 #include <plat/devs.h>
 #include <plat/cpu.h>
 #include <plat/s3c244x.h>
+#include <plat/pm.h>
 
 #include <plat/gpio-core.h>
 #include <plat/gpio-cfg.h>
@@ -51,6 +53,12 @@
 	s3c_device_wdt.resource[1].start = IRQ_S3C2440_WDT;
 	s3c_device_wdt.resource[1].end   = IRQ_S3C2440_WDT;
 
+	/* register suspend/resume handlers */
+
+	register_syscore_ops(&s3c2410_pm_syscore_ops);
+	register_syscore_ops(&s3c244x_pm_syscore_ops);
+	register_syscore_ops(&s3c24xx_irq_syscore_ops);
+
 	/* register our system device for everything else */
 
 	return sysdev_register(&s3c2440_sysdev);
diff -druN linux-2.6.39-libre/arch/arm/mach-s3c2440/s3c2442.c linux-3.0-rc7-libre/arch/arm/mach-s3c2440/s3c2442.c
--- linux-2.6.39-libre/arch/arm/mach-s3c2440/s3c2442.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-s3c2440/s3c2442.c	2011-07-11 19:51:52.000000000 -0400
@@ -29,6 +29,7 @@
 #include <linux/err.h>
 #include <linux/device.h>
 #include <linux/sysdev.h>
+#include <linux/syscore_ops.h>
 #include <linux/interrupt.h>
 #include <linux/ioport.h>
 #include <linux/mutex.h>
@@ -45,6 +46,7 @@
 #include <plat/clock.h>
 #include <plat/cpu.h>
 #include <plat/s3c244x.h>
+#include <plat/pm.h>
 
 #include <plat/gpio-core.h>
 #include <plat/gpio-cfg.h>
@@ -167,6 +169,10 @@
 {
 	printk("S3C2442: Initialising architecture\n");
 
+	register_syscore_ops(&s3c2410_pm_syscore_ops);
+	register_syscore_ops(&s3c244x_pm_syscore_ops);
+	register_syscore_ops(&s3c24xx_irq_syscore_ops);
+
 	return sysdev_register(&s3c2442_sysdev);
 }
 
diff -druN linux-2.6.39-libre/arch/arm/mach-s3c2440/s3c244x.c linux-3.0-rc7-libre/arch/arm/mach-s3c2440/s3c244x.c
--- linux-2.6.39-libre/arch/arm/mach-s3c2440/s3c244x.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-s3c2440/s3c244x.c	2011-07-11 19:51:52.000000000 -0400
@@ -19,6 +19,7 @@
 #include <linux/serial_core.h>
 #include <linux/platform_device.h>
 #include <linux/sysdev.h>
+#include <linux/syscore_ops.h>
 #include <linux/clk.h>
 #include <linux/io.h>
 
@@ -134,45 +135,14 @@
 	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
@@ -194,3 +164,33 @@
 }
 
 core_initcall(s3c2442_core_init);
+
+
+#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(void)
+{
+	s3c_pm_do_save(s3c244x_sleep, ARRAY_SIZE(s3c244x_sleep));
+	return 0;
+}
+
+static void s3c244x_resume(void)
+{
+	s3c_pm_do_restore(s3c244x_sleep, ARRAY_SIZE(s3c244x_sleep));
+}
+#else
+#define s3c244x_suspend NULL
+#define s3c244x_resume  NULL
+#endif
+
+struct syscore_ops s3c244x_pm_syscore_ops = {
+	.suspend	= s3c244x_suspend,
+	.resume		= s3c244x_resume,
+};
diff -druN linux-2.6.39-libre/arch/arm/mach-s3c2440/s3c244x-irq.c linux-3.0-rc7-libre/arch/arm/mach-s3c2440/s3c244x-irq.c
--- linux-2.6.39-libre/arch/arm/mach-s3c2440/s3c244x-irq.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-s3c2440/s3c244x-irq.c	2011-07-11 19:51:52.000000000 -0400
@@ -116,8 +116,6 @@
 
 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)
@@ -129,8 +127,6 @@
 
 static struct sysdev_driver s3c2442_irq_driver = {
 	.add		= s3c244x_irq_add,
-	.suspend	= s3c24xx_irq_suspend,
-	.resume		= s3c24xx_irq_resume,
 };
 
 
diff -druN linux-2.6.39-libre/arch/arm/mach-s3c64xx/dev-spi.c linux-3.0-rc7-libre/arch/arm/mach-s3c64xx/dev-spi.c
--- linux-2.6.39-libre/arch/arm/mach-s3c64xx/dev-spi.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-s3c64xx/dev-spi.c	2011-07-11 19:51:52.000000000 -0400
@@ -16,7 +16,6 @@
 
 #include <mach/dma.h>
 #include <mach/map.h>
-#include <mach/gpio-bank-c.h>
 #include <mach/spi-clocks.h>
 #include <mach/irqs.h>
 
@@ -40,23 +39,15 @@
  */
 static int s3c64xx_spi_cfg_gpio(struct platform_device *pdev)
 {
+	unsigned int base;
+
 	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);
+		base = S3C64XX_GPC(0);
 		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);
+		base = S3C64XX_GPC(4);
 		break;
 
 	default:
@@ -64,6 +55,9 @@
 		return -EINVAL;
 	}
 
+	s3c_gpio_cfgall_range(base, 3,
+			      S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP);
+
 	return 0;
 }
 
@@ -94,6 +88,7 @@
 	.cfg_gpio = s3c64xx_spi_cfg_gpio,
 	.fifo_lvl_mask = 0x7f,
 	.rx_lvl_offset = 13,
+	.tx_st_done = 21,
 };
 
 static u64 spi_dmamask = DMA_BIT_MASK(32);
@@ -138,6 +133,7 @@
 	.cfg_gpio = s3c64xx_spi_cfg_gpio,
 	.fifo_lvl_mask = 0x7f,
 	.rx_lvl_offset = 13,
+	.tx_st_done = 21,
 };
 
 struct platform_device s3c64xx_device_spi1 = {
diff -druN linux-2.6.39-libre/arch/arm/mach-s3c64xx/include/mach/gpio-bank-a.h linux-3.0-rc7-libre/arch/arm/mach-s3c64xx/include/mach/gpio-bank-a.h
--- linux-2.6.39-libre/arch/arm/mach-s3c64xx/include/mach/gpio-bank-a.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-s3c64xx/include/mach/gpio-bank-a.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,48 +0,0 @@
-/* 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 -druN linux-2.6.39-libre/arch/arm/mach-s3c64xx/include/mach/gpio-bank-b.h linux-3.0-rc7-libre/arch/arm/mach-s3c64xx/include/mach/gpio-bank-b.h
--- linux-2.6.39-libre/arch/arm/mach-s3c64xx/include/mach/gpio-bank-b.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-s3c64xx/include/mach/gpio-bank-b.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,60 +0,0 @@
-/* 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 -druN linux-2.6.39-libre/arch/arm/mach-s3c64xx/include/mach/gpio-bank-c.h linux-3.0-rc7-libre/arch/arm/mach-s3c64xx/include/mach/gpio-bank-c.h
--- linux-2.6.39-libre/arch/arm/mach-s3c64xx/include/mach/gpio-bank-c.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-s3c64xx/include/mach/gpio-bank-c.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,53 +0,0 @@
-/* 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 -druN linux-2.6.39-libre/arch/arm/mach-s3c64xx/include/mach/gpio-bank-d.h linux-3.0-rc7-libre/arch/arm/mach-s3c64xx/include/mach/gpio-bank-d.h
--- linux-2.6.39-libre/arch/arm/mach-s3c64xx/include/mach/gpio-bank-d.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-s3c64xx/include/mach/gpio-bank-d.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,49 +0,0 @@
-/* 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 -druN linux-2.6.39-libre/arch/arm/mach-s3c64xx/include/mach/gpio-bank-e.h linux-3.0-rc7-libre/arch/arm/mach-s3c64xx/include/mach/gpio-bank-e.h
--- linux-2.6.39-libre/arch/arm/mach-s3c64xx/include/mach/gpio-bank-e.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-s3c64xx/include/mach/gpio-bank-e.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,44 +0,0 @@
-/* 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 -druN linux-2.6.39-libre/arch/arm/mach-s3c64xx/include/mach/gpio-bank-f.h linux-3.0-rc7-libre/arch/arm/mach-s3c64xx/include/mach/gpio-bank-f.h
--- linux-2.6.39-libre/arch/arm/mach-s3c64xx/include/mach/gpio-bank-f.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-s3c64xx/include/mach/gpio-bank-f.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,71 +0,0 @@
-/* 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 -druN linux-2.6.39-libre/arch/arm/mach-s3c64xx/include/mach/gpio-bank-g.h linux-3.0-rc7-libre/arch/arm/mach-s3c64xx/include/mach/gpio-bank-g.h
--- linux-2.6.39-libre/arch/arm/mach-s3c64xx/include/mach/gpio-bank-g.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-s3c64xx/include/mach/gpio-bank-g.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,42 +0,0 @@
-/* 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 -druN linux-2.6.39-libre/arch/arm/mach-s3c64xx/include/mach/gpio-bank-h.h linux-3.0-rc7-libre/arch/arm/mach-s3c64xx/include/mach/gpio-bank-h.h
--- linux-2.6.39-libre/arch/arm/mach-s3c64xx/include/mach/gpio-bank-h.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-s3c64xx/include/mach/gpio-bank-h.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,74 +0,0 @@
-/* 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 -druN linux-2.6.39-libre/arch/arm/mach-s3c64xx/include/mach/gpio-bank-i.h linux-3.0-rc7-libre/arch/arm/mach-s3c64xx/include/mach/gpio-bank-i.h
--- linux-2.6.39-libre/arch/arm/mach-s3c64xx/include/mach/gpio-bank-i.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-s3c64xx/include/mach/gpio-bank-i.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,40 +0,0 @@
-/* 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 -druN linux-2.6.39-libre/arch/arm/mach-s3c64xx/include/mach/gpio-bank-j.h linux-3.0-rc7-libre/arch/arm/mach-s3c64xx/include/mach/gpio-bank-j.h
--- linux-2.6.39-libre/arch/arm/mach-s3c64xx/include/mach/gpio-bank-j.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-s3c64xx/include/mach/gpio-bank-j.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,36 +0,0 @@
-/* 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 -druN linux-2.6.39-libre/arch/arm/mach-s3c64xx/include/mach/gpio-bank-n.h linux-3.0-rc7-libre/arch/arm/mach-s3c64xx/include/mach/gpio-bank-n.h
--- linux-2.6.39-libre/arch/arm/mach-s3c64xx/include/mach/gpio-bank-n.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-s3c64xx/include/mach/gpio-bank-n.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,54 +0,0 @@
-/* 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 -druN linux-2.6.39-libre/arch/arm/mach-s3c64xx/include/mach/gpio-bank-o.h linux-3.0-rc7-libre/arch/arm/mach-s3c64xx/include/mach/gpio-bank-o.h
--- linux-2.6.39-libre/arch/arm/mach-s3c64xx/include/mach/gpio-bank-o.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-s3c64xx/include/mach/gpio-bank-o.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,70 +0,0 @@
-/* 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 -druN linux-2.6.39-libre/arch/arm/mach-s3c64xx/include/mach/gpio-bank-p.h linux-3.0-rc7-libre/arch/arm/mach-s3c64xx/include/mach/gpio-bank-p.h
--- linux-2.6.39-libre/arch/arm/mach-s3c64xx/include/mach/gpio-bank-p.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-s3c64xx/include/mach/gpio-bank-p.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,69 +0,0 @@
-/* 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 -druN linux-2.6.39-libre/arch/arm/mach-s3c64xx/include/mach/gpio-bank-q.h linux-3.0-rc7-libre/arch/arm/mach-s3c64xx/include/mach/gpio-bank-q.h
--- linux-2.6.39-libre/arch/arm/mach-s3c64xx/include/mach/gpio-bank-q.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-s3c64xx/include/mach/gpio-bank-q.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,46 +0,0 @@
-/* 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 -druN linux-2.6.39-libre/arch/arm/mach-s3c64xx/irq.c linux-3.0-rc7-libre/arch/arm/mach-s3c64xx/irq.c
--- linux-2.6.39-libre/arch/arm/mach-s3c64xx/irq.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-s3c64xx/irq.c	2011-07-11 19:51:52.000000000 -0400
@@ -58,12 +58,7 @@
 	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_vic_timer_irq(5, IRQ_TIMER0);
 
 	s3c_init_uart_irqs(uart_irqs, ARRAY_SIZE(uart_irqs));
 }
diff -druN linux-2.6.39-libre/arch/arm/mach-s3c64xx/irq-pm.c linux-3.0-rc7-libre/arch/arm/mach-s3c64xx/irq-pm.c
--- linux-2.6.39-libre/arch/arm/mach-s3c64xx/irq-pm.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-s3c64xx/irq-pm.c	2011-07-11 19:51:52.000000000 -0400
@@ -13,7 +13,7 @@
  */
 
 #include <linux/kernel.h>
-#include <linux/sysdev.h>
+#include <linux/syscore_ops.h>
 #include <linux/interrupt.h>
 #include <linux/serial_core.h>
 #include <linux/irq.h>
@@ -54,7 +54,7 @@
 
 static u32 irq_uart_mask[CONFIG_SERIAL_SAMSUNG_UARTS];
 
-static int s3c64xx_irq_pm_suspend(struct sys_device *dev, pm_message_t state)
+static int s3c64xx_irq_pm_suspend(void)
 {
 	struct irq_grp_save *grp = eint_grp_save;
 	int i;
@@ -75,7 +75,7 @@
 	return 0;
 }
 
-static int s3c64xx_irq_pm_resume(struct sys_device *dev)
+static void s3c64xx_irq_pm_resume(void)
 {
 	struct irq_grp_save *grp = eint_grp_save;
 	int i;
@@ -94,18 +94,18 @@
 	}
 
 	S3C_PMDBG("%s: IRQ configuration restored\n", __func__);
-	return 0;
 }
 
-static struct sysdev_driver s3c64xx_irq_driver = {
+struct syscore_ops s3c64xx_irq_syscore_ops = {
 	.suspend = s3c64xx_irq_pm_suspend,
 	.resume	 = s3c64xx_irq_pm_resume,
 };
 
-static int __init s3c64xx_irq_pm_init(void)
+static __init int s3c64xx_syscore_init(void)
 {
-	return sysdev_driver_register(&s3c64xx_sysclass, &s3c64xx_irq_driver);
-}
+	register_syscore_ops(&s3c64xx_irq_syscore_ops);
 
-arch_initcall(s3c64xx_irq_pm_init);
+	return 0;
+}
 
+core_initcall(s3c64xx_syscore_init);
diff -druN linux-2.6.39-libre/arch/arm/mach-s3c64xx/mach-smdk6410.c linux-3.0-rc7-libre/arch/arm/mach-s3c64xx/mach-smdk6410.c
--- linux-2.6.39-libre/arch/arm/mach-s3c64xx/mach-smdk6410.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-s3c64xx/mach-smdk6410.c	2011-07-11 19:51:52.000000000 -0400
@@ -50,7 +50,6 @@
 #include <mach/hardware.h>
 #include <mach/regs-fb.h>
 #include <mach/map.h>
-#include <mach/gpio-bank-f.h>
 
 #include <asm/irq.h>
 #include <asm/mach-types.h>
diff -druN linux-2.6.39-libre/arch/arm/mach-s3c64xx/pm.c linux-3.0-rc7-libre/arch/arm/mach-s3c64xx/pm.c
--- linux-2.6.39-libre/arch/arm/mach-s3c64xx/pm.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-s3c64xx/pm.c	2011-07-11 19:51:52.000000000 -0400
@@ -30,26 +30,18 @@
 #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;
+	int i;
 
 	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);
-
+	for (i = 0; i < 4; i++) {
+		if (clear & (1 << i))
+			gpio_set_value(S3C64XX_GPN(12 + i), 0);
+		if (set & (1 << i))
+			gpio_set_value(S3C64XX_GPN(12 + i), 1);
+	}
 	local_irq_restore(flags);
 }
 #endif
@@ -187,6 +179,18 @@
 	pm_cpu_prep = s3c64xx_pm_prepare;
 	pm_cpu_sleep = s3c64xx_cpu_suspend;
 	pm_uart_udivslot = 1;
+
+#ifdef CONFIG_S3C_PM_DEBUG_LED_SMDK
+	gpio_request(S3C64XX_GPN(12), "DEBUG_LED0");
+	gpio_request(S3C64XX_GPN(13), "DEBUG_LED1");
+	gpio_request(S3C64XX_GPN(14), "DEBUG_LED2");
+	gpio_request(S3C64XX_GPN(15), "DEBUG_LED3");
+	gpio_direction_output(S3C64XX_GPN(12), 0);
+	gpio_direction_output(S3C64XX_GPN(13), 0);
+	gpio_direction_output(S3C64XX_GPN(14), 0);
+	gpio_direction_output(S3C64XX_GPN(15), 0);
+#endif
+
 	return 0;
 }
 
diff -druN linux-2.6.39-libre/arch/arm/mach-s3c64xx/setup-i2c0.c linux-3.0-rc7-libre/arch/arm/mach-s3c64xx/setup-i2c0.c
--- linux-2.6.39-libre/arch/arm/mach-s3c64xx/setup-i2c0.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-s3c64xx/setup-i2c0.c	2011-07-11 19:51:52.000000000 -0400
@@ -18,14 +18,11 @@
 
 struct platform_device; /* don't need the contents */
 
-#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);
+	s3c_gpio_cfgall_range(S3C64XX_GPB(5), 2,
+			      S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP);
 }
diff -druN linux-2.6.39-libre/arch/arm/mach-s3c64xx/setup-i2c1.c linux-3.0-rc7-libre/arch/arm/mach-s3c64xx/setup-i2c1.c
--- linux-2.6.39-libre/arch/arm/mach-s3c64xx/setup-i2c1.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-s3c64xx/setup-i2c1.c	2011-07-11 19:51:52.000000000 -0400
@@ -18,14 +18,11 @@
 
 struct platform_device; /* don't need the contents */
 
-#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);
+	s3c_gpio_cfgall_range(S3C64XX_GPB(2), 2,
+			      S3C_GPIO_SFN(6), S3C_GPIO_PULL_UP);
 }
diff -druN linux-2.6.39-libre/arch/arm/mach-s3c64xx/sleep.S linux-3.0-rc7-libre/arch/arm/mach-s3c64xx/sleep.S
--- linux-2.6.39-libre/arch/arm/mach-s3c64xx/sleep.S	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-s3c64xx/sleep.S	2011-07-11 19:51:52.000000000 -0400
@@ -20,7 +20,6 @@
 #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))
 
@@ -68,6 +67,13 @@
 	ldr	r2, =LL_UART		/* for debug */
 
 #ifdef CONFIG_S3C_PM_DEBUG_LED_SMDK
+
+#define S3C64XX_GPNCON			(S3C64XX_GPN_BASE + 0x00)
+#define S3C64XX_GPNDAT			(S3C64XX_GPN_BASE + 0x04)
+
+#define S3C64XX_GPN_CONMASK(__gpio)	(0x3 << ((__gpio) * 2))
+#define S3C64XX_GPN_OUTPUT(__gpio)	(0x1 << ((__gpio) * 2))
+
 	/* 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.
diff -druN linux-2.6.39-libre/arch/arm/mach-s5p6442/clock.c linux-3.0-rc7-libre/arch/arm/mach-s5p6442/clock.c
--- linux-2.6.39-libre/arch/arm/mach-s5p6442/clock.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-s5p6442/clock.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,420 +0,0 @@
-/* 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_ip0_ctrl(struct clk *clk, int enable)
-{
-	return s5p_gatectrl(S5P_CLKGATE_IP0, clk, enable);
-}
-
-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 "S5P6442: 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_off[] = {
-	{
-		.name		= "pdma",
-		.id		= -1,
-		.parent		= &clk_pclkd1,
-		.enable		= s5p6442_clk_ip0_ctrl,
-		.ctrlbit	= (1 << 3),
-	},
-};
-
-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		= "watchdog",
-		.id		= -1,
-		.parent		= &clk_pclkd1,
-		.enable		= s5p6442_clk_ip3_ctrl,
-		.ctrlbit	= (1 << 22),
-	}, {
-		.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_register_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
-	s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
-
-	s3c_pwmclk_init();
-}
diff -druN linux-2.6.39-libre/arch/arm/mach-s5p6442/cpu.c linux-3.0-rc7-libre/arch/arm/mach-s5p6442/cpu.c
--- linux-2.6.39-libre/arch/arm/mach-s5p6442/cpu.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-s5p6442/cpu.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,143 +0,0 @@
-/* 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 <linux/sched.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)S5P_VA_GPIO,
-		.pfn		= __phys_to_pfn(S5P6442_PA_GPIO),
-		.length		= SZ_4K,
-		.type		= MT_DEVICE,
-	}, {
-		.virtual	= (unsigned long)VA_VIC0,
-		.pfn		= __phys_to_pfn(S5P6442_PA_VIC0),
-		.length		= SZ_16K,
-		.type		= MT_DEVICE,
-	}, {
-		.virtual	= (unsigned long)VA_VIC1,
-		.pfn		= __phys_to_pfn(S5P6442_PA_VIC1),
-		.length		= SZ_16K,
-		.type		= MT_DEVICE,
-	}, {
-		.virtual	= (unsigned long)VA_VIC2,
-		.pfn		= __phys_to_pfn(S5P6442_PA_VIC2),
-		.length		= SZ_16K,
-		.type		= MT_DEVICE,
-	}, {
-		.virtual	= (unsigned long)S3C_VA_UART,
-		.pfn		= __phys_to_pfn(S3C_PA_UART),
-		.length		= SZ_512K,
-		.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));
-}
-
-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 -druN linux-2.6.39-libre/arch/arm/mach-s5p6442/dev-audio.c linux-3.0-rc7-libre/arch/arm/mach-s5p6442/dev-audio.c
--- linux-2.6.39-libre/arch/arm/mach-s5p6442/dev-audio.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-s5p6442/dev-audio.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,217 +0,0 @@
-/* linux/arch/arm/mach-s5p6442/dev-audio.c
- *
- * Copyright (c) 2010 Samsung Electronics Co. Ltd
- *	Jaswinder Singh <jassi.brar@samsung.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/platform_device.h>
-#include <linux/dma-mapping.h>
-#include <linux/gpio.h>
-
-#include <plat/gpio-cfg.h>
-#include <plat/audio.h>
-
-#include <mach/map.h>
-#include <mach/dma.h>
-#include <mach/irqs.h>
-
-static int s5p6442_cfg_i2s(struct platform_device *pdev)
-{
-	unsigned int base;
-
-	/* configure GPIO for i2s port */
-	switch (pdev->id) {
-	case 1:
-		base = S5P6442_GPC1(0);
-		break;
-
-	case 0:
-		base = S5P6442_GPC0(0);
-		break;
-
-	default:
-		printk(KERN_ERR "Invalid Device %d\n", pdev->id);
-		return -EINVAL;
-	}
-
-	s3c_gpio_cfgpin_range(base, 5, S3C_GPIO_SFN(2));
-	return 0;
-}
-
-static const char *rclksrc_v35[] = {
-	[0] = "busclk",
-	[1] = "i2sclk",
-};
-
-static struct s3c_audio_pdata i2sv35_pdata = {
-	.cfg_gpio = s5p6442_cfg_i2s,
-	.type = {
-		.i2s = {
-			.quirks = QUIRK_SEC_DAI | QUIRK_NEED_RSTCLR,
-			.src_clk = rclksrc_v35,
-		},
-	},
-};
-
-static struct resource s5p6442_iis0_resource[] = {
-	[0] = {
-		.start = S5P6442_PA_I2S0,
-		.end   = S5P6442_PA_I2S0 + 0x100 - 1,
-		.flags = IORESOURCE_MEM,
-	},
-	[1] = {
-		.start = DMACH_I2S0_TX,
-		.end   = DMACH_I2S0_TX,
-		.flags = IORESOURCE_DMA,
-	},
-	[2] = {
-		.start = DMACH_I2S0_RX,
-		.end   = DMACH_I2S0_RX,
-		.flags = IORESOURCE_DMA,
-	},
-	[3] = {
-		.start = DMACH_I2S0S_TX,
-		.end = DMACH_I2S0S_TX,
-		.flags = IORESOURCE_DMA,
-	},
-};
-
-struct platform_device s5p6442_device_iis0 = {
-	.name = "samsung-i2s",
-	.id = 0,
-	.num_resources	  = ARRAY_SIZE(s5p6442_iis0_resource),
-	.resource	  = s5p6442_iis0_resource,
-	.dev = {
-		.platform_data = &i2sv35_pdata,
-	},
-};
-
-static const char *rclksrc_v3[] = {
-	[0] = "iis",
-	[1] = "sclk_audio",
-};
-
-static struct s3c_audio_pdata i2sv3_pdata = {
-	.cfg_gpio = s5p6442_cfg_i2s,
-	.type = {
-		.i2s = {
-			.src_clk = rclksrc_v3,
-		},
-	},
-};
-
-static struct resource s5p6442_iis1_resource[] = {
-	[0] = {
-		.start = S5P6442_PA_I2S1,
-		.end   = S5P6442_PA_I2S1 + 0x100 - 1,
-		.flags = IORESOURCE_MEM,
-	},
-	[1] = {
-		.start = DMACH_I2S1_TX,
-		.end   = DMACH_I2S1_TX,
-		.flags = IORESOURCE_DMA,
-	},
-	[2] = {
-		.start = DMACH_I2S1_RX,
-		.end   = DMACH_I2S1_RX,
-		.flags = IORESOURCE_DMA,
-	},
-};
-
-struct platform_device s5p6442_device_iis1 = {
-	.name		  = "samsung-i2s",
-	.id		  = 1,
-	.num_resources	  = ARRAY_SIZE(s5p6442_iis1_resource),
-	.resource	  = s5p6442_iis1_resource,
-	.dev = {
-		.platform_data = &i2sv3_pdata,
-	},
-};
-
-/* PCM Controller platform_devices */
-
-static int s5p6442_pcm_cfg_gpio(struct platform_device *pdev)
-{
-	unsigned int base;
-
-	switch (pdev->id) {
-	case 0:
-		base = S5P6442_GPC0(0);
-		break;
-
-	case 1:
-		base = S5P6442_GPC1(0);
-		break;
-
-	default:
-		printk(KERN_DEBUG "Invalid PCM Controller number!");
-		return -EINVAL;
-	}
-
-	s3c_gpio_cfgpin_range(base, 5, S3C_GPIO_SFN(3));
-	return 0;
-}
-
-static struct s3c_audio_pdata s3c_pcm_pdata = {
-	.cfg_gpio = s5p6442_pcm_cfg_gpio,
-};
-
-static struct resource s5p6442_pcm0_resource[] = {
-	[0] = {
-		.start = S5P6442_PA_PCM0,
-		.end   = S5P6442_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,
-	},
-};
-
-struct platform_device s5p6442_device_pcm0 = {
-	.name		  = "samsung-pcm",
-	.id		  = 0,
-	.num_resources	  = ARRAY_SIZE(s5p6442_pcm0_resource),
-	.resource	  = s5p6442_pcm0_resource,
-	.dev = {
-		.platform_data = &s3c_pcm_pdata,
-	},
-};
-
-static struct resource s5p6442_pcm1_resource[] = {
-	[0] = {
-		.start = S5P6442_PA_PCM1,
-		.end   = S5P6442_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,
-	},
-};
-
-struct platform_device s5p6442_device_pcm1 = {
-	.name		  = "samsung-pcm",
-	.id		  = 1,
-	.num_resources	  = ARRAY_SIZE(s5p6442_pcm1_resource),
-	.resource	  = s5p6442_pcm1_resource,
-	.dev = {
-		.platform_data = &s3c_pcm_pdata,
-	},
-};
diff -druN linux-2.6.39-libre/arch/arm/mach-s5p6442/dev-spi.c linux-3.0-rc7-libre/arch/arm/mach-s5p6442/dev-spi.c
--- linux-2.6.39-libre/arch/arm/mach-s5p6442/dev-spi.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-s5p6442/dev-spi.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,121 +0,0 @@
-/* linux/arch/arm/mach-s5p6442/dev-spi.c
- *
- * Copyright (C) 2010 Samsung Electronics Co. Ltd.
- *	Jaswinder Singh <jassi.brar@samsung.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/platform_device.h>
-#include <linux/dma-mapping.h>
-#include <linux/gpio.h>
-
-#include <mach/dma.h>
-#include <mach/map.h>
-#include <mach/irqs.h>
-#include <mach/spi-clocks.h>
-
-#include <plat/s3c64xx-spi.h>
-#include <plat/gpio-cfg.h>
-
-static char *spi_src_clks[] = {
-	[S5P6442_SPI_SRCCLK_PCLK] = "pclk",
-	[S5P6442_SPI_SRCCLK_SCLK] = "spi_epll",
-};
-
-/* SPI Controller platform_devices */
-
-/* Since we emulate multi-cs capability, we do not touch the CS.
- * 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 s5p6442_spi_cfg_gpio(struct platform_device *pdev)
-{
-	switch (pdev->id) {
-	case 0:
-		s3c_gpio_cfgpin(S5P6442_GPB(0), S3C_GPIO_SFN(2));
-		s3c_gpio_setpull(S5P6442_GPB(0), S3C_GPIO_PULL_UP);
-		s3c_gpio_cfgall_range(S5P6442_GPB(2), 2,
-				      S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP);
-		break;
-
-	default:
-		dev_err(&pdev->dev, "Invalid SPI Controller number!");
-		return -EINVAL;
-	}
-
-	return 0;
-}
-
-static struct resource s5p6442_spi0_resource[] = {
-	[0] = {
-		.start = S5P6442_PA_SPI,
-		.end   = S5P6442_PA_SPI + 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 s5p6442_spi0_pdata = {
-	.cfg_gpio = s5p6442_spi_cfg_gpio,
-	.fifo_lvl_mask = 0x1ff,
-	.rx_lvl_offset = 15,
-};
-
-static u64 spi_dmamask = DMA_BIT_MASK(32);
-
-struct platform_device s5p6442_device_spi = {
-	.name		  = "s3c64xx-spi",
-	.id		  = 0,
-	.num_resources	  = ARRAY_SIZE(s5p6442_spi0_resource),
-	.resource	  = s5p6442_spi0_resource,
-	.dev = {
-		.dma_mask		= &spi_dmamask,
-		.coherent_dma_mask	= DMA_BIT_MASK(32),
-		.platform_data = &s5p6442_spi0_pdata,
-	},
-};
-
-void __init s5p6442_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 > S5P6442_SPI_SRCCLK_SCLK) {
-		printk(KERN_ERR "%s: Invalid SPI configuration\n", __func__);
-		return;
-	}
-
-	switch (cntrlr) {
-	case 0:
-		pd = &s5p6442_spi0_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 -druN linux-2.6.39-libre/arch/arm/mach-s5p6442/dma.c linux-3.0-rc7-libre/arch/arm/mach-s5p6442/dma.c
--- linux-2.6.39-libre/arch/arm/mach-s5p6442/dma.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-s5p6442/dma.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,105 +0,0 @@
-/*
- * Copyright (C) 2010 Samsung Electronics Co. Ltd.
- *	Jaswinder Singh <jassi.brar@samsung.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <linux/platform_device.h>
-#include <linux/dma-mapping.h>
-
-#include <plat/devs.h>
-#include <plat/irqs.h>
-
-#include <mach/map.h>
-#include <mach/irqs.h>
-
-#include <plat/s3c-pl330-pdata.h>
-
-static u64 dma_dmamask = DMA_BIT_MASK(32);
-
-static struct resource s5p6442_pdma_resource[] = {
-	[0] = {
-		.start  = S5P6442_PA_PDMA,
-		.end    = S5P6442_PA_PDMA + SZ_4K,
-		.flags = IORESOURCE_MEM,
-	},
-	[1] = {
-		.start	= IRQ_PDMA,
-		.end	= IRQ_PDMA,
-		.flags	= IORESOURCE_IRQ,
-	},
-};
-
-static struct s3c_pl330_platdata s5p6442_pdma_pdata = {
-	.peri = {
-		[0] = DMACH_UART0_RX,
-		[1] = DMACH_UART0_TX,
-		[2] = DMACH_UART1_RX,
-		[3] = DMACH_UART1_TX,
-		[4] = DMACH_UART2_RX,
-		[5] = DMACH_UART2_TX,
-		[6] = DMACH_MAX,
-		[7] = DMACH_MAX,
-		[8] = DMACH_MAX,
-		[9] = DMACH_I2S0_RX,
-		[10] = DMACH_I2S0_TX,
-		[11] = DMACH_I2S0S_TX,
-		[12] = DMACH_I2S1_RX,
-		[13] = DMACH_I2S1_TX,
-		[14] = DMACH_MAX,
-		[15] = DMACH_MAX,
-		[16] = DMACH_SPI0_RX,
-		[17] = DMACH_SPI0_TX,
-		[18] = DMACH_MAX,
-		[19] = DMACH_MAX,
-		[20] = DMACH_PCM0_RX,
-		[21] = DMACH_PCM0_TX,
-		[22] = DMACH_PCM1_RX,
-		[23] = DMACH_PCM1_TX,
-		[24] = DMACH_MAX,
-		[25] = DMACH_MAX,
-		[26] = DMACH_MAX,
-		[27] = DMACH_MSM_REQ0,
-		[28] = DMACH_MSM_REQ1,
-		[29] = DMACH_MSM_REQ2,
-		[30] = DMACH_MSM_REQ3,
-		[31] = DMACH_MAX,
-	},
-};
-
-static struct platform_device s5p6442_device_pdma = {
-	.name		= "s3c-pl330",
-	.id		= -1,
-	.num_resources	= ARRAY_SIZE(s5p6442_pdma_resource),
-	.resource	= s5p6442_pdma_resource,
-	.dev		= {
-		.dma_mask = &dma_dmamask,
-		.coherent_dma_mask = DMA_BIT_MASK(32),
-		.platform_data = &s5p6442_pdma_pdata,
-	},
-};
-
-static struct platform_device *s5p6442_dmacs[] __initdata = {
-	&s5p6442_device_pdma,
-};
-
-static int __init s5p6442_dma_init(void)
-{
-	platform_add_devices(s5p6442_dmacs, ARRAY_SIZE(s5p6442_dmacs));
-
-	return 0;
-}
-arch_initcall(s5p6442_dma_init);
diff -druN linux-2.6.39-libre/arch/arm/mach-s5p6442/include/mach/debug-macro.S linux-3.0-rc7-libre/arch/arm/mach-s5p6442/include/mach/debug-macro.S
--- linux-2.6.39-libre/arch/arm/mach-s5p6442/include/mach/debug-macro.S	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-s5p6442/include/mach/debug-macro.S	1969-12-31 19:00:00.000000000 -0500
@@ -1,35 +0,0 @@
-/* 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, rp, rv
-		ldr	\rp, = S3C_PA_UART
-		ldr	\rv, = S3C_VA_UART
-#if CONFIG_DEBUG_S3C_UART != 0
-		add	\rp, \rp, #(0x400 * CONFIG_DEBUG_S3C_UART)
-		add	\rv, \rv, #(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 -druN linux-2.6.39-libre/arch/arm/mach-s5p6442/include/mach/dma.h linux-3.0-rc7-libre/arch/arm/mach-s5p6442/include/mach/dma.h
--- linux-2.6.39-libre/arch/arm/mach-s5p6442/include/mach/dma.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-s5p6442/include/mach/dma.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,26 +0,0 @@
-/*
- * Copyright (C) 2010 Samsung Electronics Co. Ltd.
- *	Jaswinder Singh <jassi.brar@samsung.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef __MACH_DMA_H
-#define __MACH_DMA_H
-
-/* This platform uses the common S3C DMA API driver for PL330 */
-#include <plat/s3c-dma-pl330.h>
-
-#endif /* __MACH_DMA_H */
diff -druN linux-2.6.39-libre/arch/arm/mach-s5p6442/include/mach/entry-macro.S linux-3.0-rc7-libre/arch/arm/mach-s5p6442/include/mach/entry-macro.S
--- linux-2.6.39-libre/arch/arm/mach-s5p6442/include/mach/entry-macro.S	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-s5p6442/include/mach/entry-macro.S	1969-12-31 19:00:00.000000000 -0500
@@ -1,48 +0,0 @@
-/* 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 -druN linux-2.6.39-libre/arch/arm/mach-s5p6442/include/mach/gpio.h linux-3.0-rc7-libre/arch/arm/mach-s5p6442/include/mach/gpio.h
--- linux-2.6.39-libre/arch/arm/mach-s5p6442/include/mach/gpio.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-s5p6442/include/mach/gpio.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,123 +0,0 @@
-/* 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 -druN linux-2.6.39-libre/arch/arm/mach-s5p6442/include/mach/hardware.h linux-3.0-rc7-libre/arch/arm/mach-s5p6442/include/mach/hardware.h
--- linux-2.6.39-libre/arch/arm/mach-s5p6442/include/mach/hardware.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-s5p6442/include/mach/hardware.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,18 +0,0 @@
-/* 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 -druN linux-2.6.39-libre/arch/arm/mach-s5p6442/include/mach/io.h linux-3.0-rc7-libre/arch/arm/mach-s5p6442/include/mach/io.h
--- linux-2.6.39-libre/arch/arm/mach-s5p6442/include/mach/io.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-s5p6442/include/mach/io.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,17 +0,0 @@
-/* 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 -druN linux-2.6.39-libre/arch/arm/mach-s5p6442/include/mach/irqs.h linux-3.0-rc7-libre/arch/arm/mach-s5p6442/include/mach/irqs.h
--- linux-2.6.39-libre/arch/arm/mach-s5p6442/include/mach/irqs.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-s5p6442/include/mach/irqs.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,87 +0,0 @@
-/* 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_PMU			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 S5P_EINT_BASE1		(S5P_IRQ_VIC0(0))
-#define S5P_EINT_BASE2		(S5P_IRQ_EINT_BASE)
-
-/* Set the default NR_IRQS */
-
-#define NR_IRQS 		(IRQ_EINT(31) + 1)
-
-#endif /* __ASM_ARCH_IRQS_H */
diff -druN linux-2.6.39-libre/arch/arm/mach-s5p6442/include/mach/map.h linux-3.0-rc7-libre/arch/arm/mach-s5p6442/include/mach/map.h
--- linux-2.6.39-libre/arch/arm/mach-s5p6442/include/mach/map.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-s5p6442/include/mach/map.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,76 +0,0 @@
-/* linux/arch/arm/mach-s5p6442/include/mach/map.h
- *
- * Copyright (c) 2010-2011 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_SDRAM	0x20000000
-
-#define S5P6442_PA_I2S0		0xC0B00000
-#define S5P6442_PA_I2S1		0xF2200000
-
-#define S5P6442_PA_CHIPID	0xE0000000
-
-#define S5P6442_PA_SYSCON	0xE0100000
-
-#define S5P6442_PA_GPIO		0xE0200000
-
-#define S5P6442_PA_VIC0		0xE4000000
-#define S5P6442_PA_VIC1		0xE4100000
-#define S5P6442_PA_VIC2		0xE4200000
-
-#define S5P6442_PA_SROMC	0xE7000000
-
-#define S5P6442_PA_MDMA		0xE8000000
-#define S5P6442_PA_PDMA		0xE9000000
-
-#define S5P6442_PA_TIMER	0xEA000000
-
-#define S5P6442_PA_SYSTIMER	0xEA100000
-
-#define S5P6442_PA_WATCHDOG	0xEA200000
-
-#define S5P6442_PA_UART		0xEC000000
-
-#define S5P6442_PA_IIC0		0xEC100000
-
-#define S5P6442_PA_SPI		0xEC300000
-
-#define S5P6442_PA_PCM0		0xF2400000
-#define S5P6442_PA_PCM1		0xF2500000
-
-/* Compatibiltiy Defines */
-
-#define S3C_PA_IIC		S5P6442_PA_IIC0
-#define S3C_PA_WDT		S5P6442_PA_WATCHDOG
-
-#define S5P_PA_CHIPID		S5P6442_PA_CHIPID
-#define S5P_PA_SDRAM		S5P6442_PA_SDRAM
-#define S5P_PA_SROMC		S5P6442_PA_SROMC
-#define S5P_PA_SYSCON		S5P6442_PA_SYSCON
-#define S5P_PA_TIMER		S5P6442_PA_TIMER
-
-/* UART */
-
-#define S3C_PA_UART		S5P6442_PA_UART
-
-#define S5P_PA_UART(x)		(S3C_PA_UART + ((x) * S3C_UART_OFFSET))
-#define S5P_PA_UART0		S5P_PA_UART(0)
-#define S5P_PA_UART1		S5P_PA_UART(1)
-#define S5P_PA_UART2		S5P_PA_UART(2)
-
-#define S5P_SZ_UART		SZ_256
-
-#endif /* __ASM_ARCH_MAP_H */
diff -druN linux-2.6.39-libre/arch/arm/mach-s5p6442/include/mach/memory.h linux-3.0-rc7-libre/arch/arm/mach-s5p6442/include/mach/memory.h
--- linux-2.6.39-libre/arch/arm/mach-s5p6442/include/mach/memory.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-s5p6442/include/mach/memory.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,19 +0,0 @@
-/* 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 PLAT_PHYS_OFFSET		UL(0x20000000)
-#define CONSISTENT_DMA_SIZE	SZ_8M
-
-#endif /* __ASM_ARCH_MEMORY_H */
diff -druN linux-2.6.39-libre/arch/arm/mach-s5p6442/include/mach/pwm-clock.h linux-3.0-rc7-libre/arch/arm/mach-s5p6442/include/mach/pwm-clock.h
--- linux-2.6.39-libre/arch/arm/mach-s5p6442/include/mach/pwm-clock.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-s5p6442/include/mach/pwm-clock.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,70 +0,0 @@
-/* linux/arch/arm/mach-s5p6442/include/mach/pwm-clock.h
- *
- * Copyright (c) 2010 Samsung Electronics Co., Ltd.
- *		http://www.samsung.com/
- *
- * Copyright 2008 Openmoko, Inc.
- * Copyright 2008 Simtec Electronics
- *      Ben Dooks <ben@simtec.co.uk>
- *      http://armlinux.simtec.co.uk/
- *
- * Based on arch/arm/mach-s3c64xx/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
- * @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
-
-#endif /* __ASM_ARCH_PWMCLK_H */
diff -druN linux-2.6.39-libre/arch/arm/mach-s5p6442/include/mach/regs-clock.h linux-3.0-rc7-libre/arch/arm/mach-s5p6442/include/mach/regs-clock.h
--- linux-2.6.39-libre/arch/arm/mach-s5p6442/include/mach/regs-clock.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-s5p6442/include/mach/regs-clock.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,104 +0,0 @@
-/* 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_IP0		S5P_CLKREG(0x460)
-#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 -druN linux-2.6.39-libre/arch/arm/mach-s5p6442/include/mach/regs-irq.h linux-3.0-rc7-libre/arch/arm/mach-s5p6442/include/mach/regs-irq.h
--- linux-2.6.39-libre/arch/arm/mach-s5p6442/include/mach/regs-irq.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-s5p6442/include/mach/regs-irq.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,19 +0,0 @@
-/* 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 -druN linux-2.6.39-libre/arch/arm/mach-s5p6442/include/mach/spi-clocks.h linux-3.0-rc7-libre/arch/arm/mach-s5p6442/include/mach/spi-clocks.h
--- linux-2.6.39-libre/arch/arm/mach-s5p6442/include/mach/spi-clocks.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-s5p6442/include/mach/spi-clocks.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,17 +0,0 @@
-/* linux/arch/arm/mach-s5p6442/include/mach/spi-clocks.h
- *
- * Copyright (C) 2010 Samsung Electronics Co. Ltd.
- *	Jaswinder Singh <jassi.brar@samsung.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#ifndef __S5P6442_PLAT_SPI_CLKS_H
-#define __S5P6442_PLAT_SPI_CLKS_H __FILE__
-
-#define S5P6442_SPI_SRCCLK_PCLK		0
-#define S5P6442_SPI_SRCCLK_SCLK		1
-
-#endif /* __S5P6442_PLAT_SPI_CLKS_H */
diff -druN linux-2.6.39-libre/arch/arm/mach-s5p6442/include/mach/system.h linux-3.0-rc7-libre/arch/arm/mach-s5p6442/include/mach/system.h
--- linux-2.6.39-libre/arch/arm/mach-s5p6442/include/mach/system.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-s5p6442/include/mach/system.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,23 +0,0 @@
-/* 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__
-
-#include <plat/system-reset.h>
-
-static void arch_idle(void)
-{
-	/* nothing here yet */
-}
-
-#endif /* __ASM_ARCH_SYSTEM_H */
diff -druN linux-2.6.39-libre/arch/arm/mach-s5p6442/include/mach/tick.h linux-3.0-rc7-libre/arch/arm/mach-s5p6442/include/mach/tick.h
--- linux-2.6.39-libre/arch/arm/mach-s5p6442/include/mach/tick.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-s5p6442/include/mach/tick.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,26 +0,0 @@
-/* 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 -druN linux-2.6.39-libre/arch/arm/mach-s5p6442/include/mach/timex.h linux-3.0-rc7-libre/arch/arm/mach-s5p6442/include/mach/timex.h
--- linux-2.6.39-libre/arch/arm/mach-s5p6442/include/mach/timex.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-s5p6442/include/mach/timex.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,24 +0,0 @@
-/* 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 -druN linux-2.6.39-libre/arch/arm/mach-s5p6442/include/mach/uncompress.h linux-3.0-rc7-libre/arch/arm/mach-s5p6442/include/mach/uncompress.h
--- linux-2.6.39-libre/arch/arm/mach-s5p6442/include/mach/uncompress.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-s5p6442/include/mach/uncompress.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,24 +0,0 @@
-/* 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 -druN linux-2.6.39-libre/arch/arm/mach-s5p6442/include/mach/vmalloc.h linux-3.0-rc7-libre/arch/arm/mach-s5p6442/include/mach/vmalloc.h
--- linux-2.6.39-libre/arch/arm/mach-s5p6442/include/mach/vmalloc.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-s5p6442/include/mach/vmalloc.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,17 +0,0 @@
-/* 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	0xF6000000UL
-
-#endif /* __ASM_ARCH_VMALLOC_H */
diff -druN linux-2.6.39-libre/arch/arm/mach-s5p6442/init.c linux-3.0-rc7-libre/arch/arm/mach-s5p6442/init.c
--- linux-2.6.39-libre/arch/arm/mach-s5p6442/init.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-s5p6442/init.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,44 +0,0 @@
-/* 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 -druN linux-2.6.39-libre/arch/arm/mach-s5p6442/Kconfig linux-3.0-rc7-libre/arch/arm/mach-s5p6442/Kconfig
--- linux-2.6.39-libre/arch/arm/mach-s5p6442/Kconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-s5p6442/Kconfig	1969-12-31 19:00:00.000000000 -0500
@@ -1,25 +0,0 @@
-# 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 S3C_PL330_DMA
-	help
-	  Enable S5P6442 CPU support
-
-config MACH_SMDK6442
-	bool "SMDK6442"
-	select CPU_S5P6442
-	select S3C_DEV_WDT
-	help
-	  Machine support for Samsung SMDK6442
-
-endif
diff -druN linux-2.6.39-libre/arch/arm/mach-s5p6442/mach-smdk6442.c linux-3.0-rc7-libre/arch/arm/mach-s5p6442/mach-smdk6442.c
--- linux-2.6.39-libre/arch/arm/mach-s5p6442/mach-smdk6442.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-s5p6442/mach-smdk6442.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,102 +0,0 @@
-/* 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 <linux/i2c.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>
-#include <plat/iic.h>
-
-/* Following are default values for UCON, ULCON and UFCON UART registers */
-#define SMDK6442_UCON_DEFAULT	(S3C2410_UCON_TXILEVEL |	\
-				 S3C2410_UCON_RXILEVEL |	\
-				 S3C2410_UCON_TXIRQMODE |	\
-				 S3C2410_UCON_RXIRQMODE |	\
-				 S3C2410_UCON_RXFIFO_TOI |	\
-				 S3C2443_UCON_RXERR_IRQEN)
-
-#define SMDK6442_ULCON_DEFAULT	S3C2410_LCON_CS8
-
-#define SMDK6442_UFCON_DEFAULT	(S3C2410_UFCON_FIFOMODE |	\
-				 S5PV210_UFCON_TXTRIG4 |	\
-				 S5PV210_UFCON_RXTRIG4)
-
-static struct s3c2410_uartcfg smdk6442_uartcfgs[] __initdata = {
-	[0] = {
-		.hwport		= 0,
-		.flags		= 0,
-		.ucon		= SMDK6442_UCON_DEFAULT,
-		.ulcon		= SMDK6442_ULCON_DEFAULT,
-		.ufcon		= SMDK6442_UFCON_DEFAULT,
-	},
-	[1] = {
-		.hwport		= 1,
-		.flags		= 0,
-		.ucon		= SMDK6442_UCON_DEFAULT,
-		.ulcon		= SMDK6442_ULCON_DEFAULT,
-		.ufcon		= SMDK6442_UFCON_DEFAULT,
-	},
-	[2] = {
-		.hwport		= 2,
-		.flags		= 0,
-		.ucon		= SMDK6442_UCON_DEFAULT,
-		.ulcon		= SMDK6442_ULCON_DEFAULT,
-		.ufcon		= SMDK6442_UFCON_DEFAULT,
-	},
-};
-
-static struct platform_device *smdk6442_devices[] __initdata = {
-	&s3c_device_i2c0,
-	&samsung_asoc_dma,
-	&s5p6442_device_iis0,
-	&s3c_device_wdt,
-};
-
-static struct i2c_board_info smdk6442_i2c_devs0[] __initdata = {
-	{ I2C_BOARD_INFO("wm8580", 0x1b), },
-};
-
-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)
-{
-	s3c_i2c0_set_platdata(NULL);
-	i2c_register_board_info(0, smdk6442_i2c_devs0,
-			ARRAY_SIZE(smdk6442_i2c_devs0));
-	platform_add_devices(smdk6442_devices, ARRAY_SIZE(smdk6442_devices));
-}
-
-MACHINE_START(SMDK6442, "SMDK6442")
-	/* Maintainer: Kukjin Kim <kgene.kim@samsung.com> */
-	.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 -druN linux-2.6.39-libre/arch/arm/mach-s5p6442/Makefile linux-3.0-rc7-libre/arch/arm/mach-s5p6442/Makefile
--- linux-2.6.39-libre/arch/arm/mach-s5p6442/Makefile	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-s5p6442/Makefile	1969-12-31 19:00:00.000000000 -0500
@@ -1,24 +0,0 @@
-# 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 dma.o
-obj-$(CONFIG_CPU_S5P6442)	+= setup-i2c0.o
-
-# machine support
-
-obj-$(CONFIG_MACH_SMDK6442)	+= mach-smdk6442.o
-
-# device support
-obj-y				+= dev-audio.o
-obj-$(CONFIG_S3C64XX_DEV_SPI)	+= dev-spi.o
diff -druN linux-2.6.39-libre/arch/arm/mach-s5p6442/Makefile.boot linux-3.0-rc7-libre/arch/arm/mach-s5p6442/Makefile.boot
--- linux-2.6.39-libre/arch/arm/mach-s5p6442/Makefile.boot	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-s5p6442/Makefile.boot	1969-12-31 19:00:00.000000000 -0500
@@ -1,2 +0,0 @@
-   zreladdr-y	:= 0x20008000
-params_phys-y	:= 0x20000100
diff -druN linux-2.6.39-libre/arch/arm/mach-s5p6442/setup-i2c0.c linux-3.0-rc7-libre/arch/arm/mach-s5p6442/setup-i2c0.c
--- linux-2.6.39-libre/arch/arm/mach-s5p6442/setup-i2c0.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-s5p6442/setup-i2c0.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,28 +0,0 @@
-/* linux/arch/arm/mach-s5p6442/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>
-#include <linux/gpio.h>
-
-struct platform_device; /* don't need the contents */
-
-#include <plat/gpio-cfg.h>
-#include <plat/iic.h>
-
-void s3c_i2c0_cfg_gpio(struct platform_device *dev)
-{
-	s3c_gpio_cfgall_range(S5P6442_GPD1(0), 2,
-			      S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP);
-}
diff -druN linux-2.6.39-libre/arch/arm/mach-s5p64x0/dev-spi.c linux-3.0-rc7-libre/arch/arm/mach-s5p64x0/dev-spi.c
--- linux-2.6.39-libre/arch/arm/mach-s5p64x0/dev-spi.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-s5p64x0/dev-spi.c	2011-07-11 19:51:52.000000000 -0400
@@ -112,12 +112,14 @@
 	.cfg_gpio	= s5p6440_spi_cfg_gpio,
 	.fifo_lvl_mask	= 0x1ff,
 	.rx_lvl_offset	= 15,
+	.tx_st_done	= 25,
 };
 
 static struct s3c64xx_spi_info s5p6450_spi0_pdata = {
 	.cfg_gpio	= s5p6450_spi_cfg_gpio,
 	.fifo_lvl_mask	= 0x1ff,
 	.rx_lvl_offset	= 15,
+	.tx_st_done	= 25,
 };
 
 static u64 spi_dmamask = DMA_BIT_MASK(32);
@@ -160,12 +162,14 @@
 	.cfg_gpio	= s5p6440_spi_cfg_gpio,
 	.fifo_lvl_mask	= 0x7f,
 	.rx_lvl_offset	= 15,
+	.tx_st_done	= 25,
 };
 
 static struct s3c64xx_spi_info s5p6450_spi1_pdata = {
 	.cfg_gpio	= s5p6450_spi_cfg_gpio,
 	.fifo_lvl_mask	= 0x7f,
 	.rx_lvl_offset	= 15,
+	.tx_st_done	= 25,
 };
 
 struct platform_device s5p64x0_device_spi1 = {
diff -druN linux-2.6.39-libre/arch/arm/mach-s5p64x0/include/mach/uncompress.h linux-3.0-rc7-libre/arch/arm/mach-s5p64x0/include/mach/uncompress.h
--- linux-2.6.39-libre/arch/arm/mach-s5p64x0/include/mach/uncompress.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-s5p64x0/include/mach/uncompress.h	2011-07-11 19:51:52.000000000 -0400
@@ -24,8 +24,8 @@
 
 /* uart setup */
 
-static unsigned int fifo_mask;
-static unsigned int fifo_max;
+unsigned int fifo_mask;
+unsigned int fifo_max;
 
 /* forward declerations */
 
@@ -43,7 +43,7 @@
 /* how many bytes we allow into the FIFO at a time in FIFO mode */
 #define FIFO_MAX	 (14)
 
-static unsigned long uart_base;
+unsigned long uart_base;
 
 static __inline__ void get_uart_base(void)
 {
diff -druN linux-2.6.39-libre/arch/arm/mach-s5pc100/dev-spi.c linux-3.0-rc7-libre/arch/arm/mach-s5pc100/dev-spi.c
--- linux-2.6.39-libre/arch/arm/mach-s5pc100/dev-spi.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-s5pc100/dev-spi.c	2011-07-11 19:51:52.000000000 -0400
@@ -15,6 +15,7 @@
 #include <mach/dma.h>
 #include <mach/map.h>
 #include <mach/spi-clocks.h>
+#include <mach/irqs.h>
 
 #include <plat/s3c64xx-spi.h>
 #include <plat/gpio-cfg.h>
@@ -90,6 +91,7 @@
 	.fifo_lvl_mask = 0x7f,
 	.rx_lvl_offset = 13,
 	.high_speed = 1,
+	.tx_st_done = 21,
 };
 
 static u64 spi_dmamask = DMA_BIT_MASK(32);
@@ -134,6 +136,7 @@
 	.fifo_lvl_mask = 0x7f,
 	.rx_lvl_offset = 13,
 	.high_speed = 1,
+	.tx_st_done = 21,
 };
 
 struct platform_device s5pc100_device_spi1 = {
@@ -176,6 +179,7 @@
 	.fifo_lvl_mask = 0x7f,
 	.rx_lvl_offset = 13,
 	.high_speed = 1,
+	.tx_st_done = 21,
 };
 
 struct platform_device s5pc100_device_spi2 = {
diff -druN linux-2.6.39-libre/arch/arm/mach-s5pc100/gpiolib.c linux-3.0-rc7-libre/arch/arm/mach-s5pc100/gpiolib.c
--- linux-2.6.39-libre/arch/arm/mach-s5pc100/gpiolib.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-s5pc100/gpiolib.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,355 +0,0 @@
-/* linux/arch/arm/mach-s5pc100/gpiolib.c
- *
- * Copyright (c) 2010 Samsung Electronics Co., Ltd.
- *		http://www.samsung.com
- *
- *  Copyright 2009 Samsung Electronics Co
- *  Kyungmin Park <kyungmin.park@samsung.com>
- *
- * S5PC100 - GPIOlib support
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/kernel.h>
-#include <linux/irq.h>
-#include <linux/io.h>
-#include <linux/gpio.h>
-
-#include <mach/map.h>
-#include <mach/regs-gpio.h>
-
-#include <plat/gpio-core.h>
-#include <plat/gpio-cfg.h>
-#include <plat/gpio-cfg-helpers.h>
-
-/* S5PC100 GPIO bank summary:
- *
- * Bank	GPIOs	Style	INT Type
- * A0	8	4Bit	GPIO_INT0
- * A1	5	4Bit	GPIO_INT1
- * B	8	4Bit	GPIO_INT2
- * C	5	4Bit	GPIO_INT3
- * D	7	4Bit	GPIO_INT4
- * E0	8	4Bit	GPIO_INT5
- * E1	6	4Bit	GPIO_INT6
- * F0	8	4Bit	GPIO_INT7
- * F1	8	4Bit	GPIO_INT8
- * F2	8	4Bit	GPIO_INT9
- * F3	4	4Bit	GPIO_INT10
- * G0	8	4Bit	GPIO_INT11
- * G1	3	4Bit	GPIO_INT12
- * G2	7	4Bit	GPIO_INT13
- * G3	7	4Bit	GPIO_INT14
- * H0	8	4Bit	WKUP_INT
- * H1	8	4Bit	WKUP_INT
- * H2	8	4Bit	WKUP_INT
- * H3	8	4Bit	WKUP_INT
- * I	8	4Bit	GPIO_INT15
- * J0	8	4Bit	GPIO_INT16
- * J1	5	4Bit	GPIO_INT17
- * J2	8	4Bit	GPIO_INT18
- * J3	8	4Bit	GPIO_INT19
- * J4	4	4Bit	GPIO_INT20
- * K0	8	4Bit	None
- * K1	6	4Bit	None
- * K2	8	4Bit	None
- * K3	8	4Bit	None
- * L0	8	4Bit	None
- * L1	8	4Bit	None
- * L2	8	4Bit	None
- * L3	8	4Bit	None
- */
-
-static struct s3c_gpio_cfg gpio_cfg = {
-	.set_config	= s3c_gpio_setcfg_s3c64xx_4bit,
-	.set_pull	= s3c_gpio_setpull_updown,
-	.get_pull	= s3c_gpio_getpull_updown,
-};
-
-static struct s3c_gpio_cfg gpio_cfg_eint = {
-	.cfg_eint	= 0xf,
-	.set_config	= s3c_gpio_setcfg_s3c64xx_4bit,
-	.set_pull	= s3c_gpio_setpull_updown,
-	.get_pull	= s3c_gpio_getpull_updown,
-};
-
-static struct s3c_gpio_cfg gpio_cfg_noint = {
-	.set_config	= s3c_gpio_setcfg_s3c64xx_4bit,
-	.set_pull	= s3c_gpio_setpull_updown,
-	.get_pull	= s3c_gpio_getpull_updown,
-};
-
-/*
- * GPIO bank's base address given the index of the bank in the
- * list of all gpio banks.
- */
-#define S5PC100_BANK_BASE(bank_nr)	(S5P_VA_GPIO + ((bank_nr) * 0x20))
-
-/*
- * Following are the gpio banks in S5PC100.
- *
- * The 'config' member when left to NULL, is initialized to the default
- * structure gpio_cfg in the init function below.
- *
- * The 'base' member is also initialized in the init function below.
- * Note: The initialization of 'base' member of s3c_gpio_chip structure
- * uses the above macro and depends on the banks being listed in order here.
- */
-static struct s3c_gpio_chip s5pc100_gpio_chips[] = {
-	{
-		.chip	= {
-			.base	= S5PC100_GPA0(0),
-			.ngpio	= S5PC100_GPIO_A0_NR,
-			.label	= "GPA0",
-		},
-	}, {
-		.chip	= {
-			.base	= S5PC100_GPA1(0),
-			.ngpio	= S5PC100_GPIO_A1_NR,
-			.label	= "GPA1",
-		},
-	}, {
-		.chip	= {
-			.base	= S5PC100_GPB(0),
-			.ngpio	= S5PC100_GPIO_B_NR,
-			.label	= "GPB",
-		},
-	}, {
-		.chip	= {
-			.base	= S5PC100_GPC(0),
-			.ngpio	= S5PC100_GPIO_C_NR,
-			.label	= "GPC",
-		},
-	}, {
-		.chip	= {
-			.base	= S5PC100_GPD(0),
-			.ngpio	= S5PC100_GPIO_D_NR,
-			.label	= "GPD",
-		},
-	}, {
-		.chip	= {
-			.base	= S5PC100_GPE0(0),
-			.ngpio	= S5PC100_GPIO_E0_NR,
-			.label	= "GPE0",
-		},
-	}, {
-		.chip	= {
-			.base	= S5PC100_GPE1(0),
-			.ngpio	= S5PC100_GPIO_E1_NR,
-			.label	= "GPE1",
-		},
-	}, {
-		.chip	= {
-			.base	= S5PC100_GPF0(0),
-			.ngpio	= S5PC100_GPIO_F0_NR,
-			.label	= "GPF0",
-		},
-	}, {
-		.chip	= {
-			.base	= S5PC100_GPF1(0),
-			.ngpio	= S5PC100_GPIO_F1_NR,
-			.label	= "GPF1",
-		},
-	}, {
-		.chip	= {
-			.base	= S5PC100_GPF2(0),
-			.ngpio	= S5PC100_GPIO_F2_NR,
-			.label	= "GPF2",
-		},
-	}, {
-		.chip	= {
-			.base	= S5PC100_GPF3(0),
-			.ngpio	= S5PC100_GPIO_F3_NR,
-			.label	= "GPF3",
-		},
-	}, {
-		.chip	= {
-			.base	= S5PC100_GPG0(0),
-			.ngpio	= S5PC100_GPIO_G0_NR,
-			.label	= "GPG0",
-		},
-	}, {
-		.chip	= {
-			.base	= S5PC100_GPG1(0),
-			.ngpio	= S5PC100_GPIO_G1_NR,
-			.label	= "GPG1",
-		},
-	}, {
-		.chip	= {
-			.base	= S5PC100_GPG2(0),
-			.ngpio	= S5PC100_GPIO_G2_NR,
-			.label	= "GPG2",
-		},
-	}, {
-		.chip	= {
-			.base	= S5PC100_GPG3(0),
-			.ngpio	= S5PC100_GPIO_G3_NR,
-			.label	= "GPG3",
-		},
-	}, {
-		.chip	= {
-			.base	= S5PC100_GPI(0),
-			.ngpio	= S5PC100_GPIO_I_NR,
-			.label	= "GPI",
-		},
-	}, {
-		.chip	= {
-			.base	= S5PC100_GPJ0(0),
-			.ngpio	= S5PC100_GPIO_J0_NR,
-			.label	= "GPJ0",
-		},
-	}, {
-		.chip	= {
-			.base	= S5PC100_GPJ1(0),
-			.ngpio	= S5PC100_GPIO_J1_NR,
-			.label	= "GPJ1",
-		},
-	}, {
-		.chip	= {
-			.base	= S5PC100_GPJ2(0),
-			.ngpio	= S5PC100_GPIO_J2_NR,
-			.label	= "GPJ2",
-		},
-	}, {
-		.chip	= {
-			.base	= S5PC100_GPJ3(0),
-			.ngpio	= S5PC100_GPIO_J3_NR,
-			.label	= "GPJ3",
-		},
-	}, {
-		.chip	= {
-			.base	= S5PC100_GPJ4(0),
-			.ngpio	= S5PC100_GPIO_J4_NR,
-			.label	= "GPJ4",
-		},
-	}, {
-		.config	= &gpio_cfg_noint,
-		.chip	= {
-			.base	= S5PC100_GPK0(0),
-			.ngpio	= S5PC100_GPIO_K0_NR,
-			.label	= "GPK0",
-		},
-	}, {
-		.config	= &gpio_cfg_noint,
-		.chip	= {
-			.base	= S5PC100_GPK1(0),
-			.ngpio	= S5PC100_GPIO_K1_NR,
-			.label	= "GPK1",
-		},
-	}, {
-		.config	= &gpio_cfg_noint,
-		.chip	= {
-			.base	= S5PC100_GPK2(0),
-			.ngpio	= S5PC100_GPIO_K2_NR,
-			.label	= "GPK2",
-		},
-	}, {
-		.config	= &gpio_cfg_noint,
-		.chip	= {
-			.base	= S5PC100_GPK3(0),
-			.ngpio	= S5PC100_GPIO_K3_NR,
-			.label	= "GPK3",
-		},
-	}, {
-		.config	= &gpio_cfg_noint,
-		.chip	= {
-			.base	= S5PC100_GPL0(0),
-			.ngpio	= S5PC100_GPIO_L0_NR,
-			.label	= "GPL0",
-		},
-	}, {
-		.config	= &gpio_cfg_noint,
-		.chip	= {
-			.base	= S5PC100_GPL1(0),
-			.ngpio	= S5PC100_GPIO_L1_NR,
-			.label	= "GPL1",
-		},
-	}, {
-		.config	= &gpio_cfg_noint,
-		.chip	= {
-			.base	= S5PC100_GPL2(0),
-			.ngpio	= S5PC100_GPIO_L2_NR,
-			.label	= "GPL2",
-		},
-	}, {
-		.config	= &gpio_cfg_noint,
-		.chip	= {
-			.base	= S5PC100_GPL3(0),
-			.ngpio	= S5PC100_GPIO_L3_NR,
-			.label	= "GPL3",
-		},
-	}, {
-		.config	= &gpio_cfg_noint,
-		.chip	= {
-			.base	= S5PC100_GPL4(0),
-			.ngpio	= S5PC100_GPIO_L4_NR,
-			.label	= "GPL4",
-		},
-	}, {
-		.base	= (S5P_VA_GPIO + 0xC00),
-		.config	= &gpio_cfg_eint,
-		.irq_base = IRQ_EINT(0),
-		.chip	= {
-			.base	= S5PC100_GPH0(0),
-			.ngpio	= S5PC100_GPIO_H0_NR,
-			.label	= "GPH0",
-			.to_irq = samsung_gpiolib_to_irq,
-		},
-	}, {
-		.base	= (S5P_VA_GPIO + 0xC20),
-		.config	= &gpio_cfg_eint,
-		.irq_base = IRQ_EINT(8),
-		.chip	= {
-			.base	= S5PC100_GPH1(0),
-			.ngpio	= S5PC100_GPIO_H1_NR,
-			.label	= "GPH1",
-			.to_irq = samsung_gpiolib_to_irq,
-		},
-	}, {
-		.base	= (S5P_VA_GPIO + 0xC40),
-		.config	= &gpio_cfg_eint,
-		.irq_base = IRQ_EINT(16),
-		.chip	= {
-			.base	= S5PC100_GPH2(0),
-			.ngpio	= S5PC100_GPIO_H2_NR,
-			.label	= "GPH2",
-			.to_irq = samsung_gpiolib_to_irq,
-		},
-	}, {
-		.base	= (S5P_VA_GPIO + 0xC60),
-		.config	= &gpio_cfg_eint,
-		.irq_base = IRQ_EINT(24),
-		.chip	= {
-			.base	= S5PC100_GPH3(0),
-			.ngpio	= S5PC100_GPIO_H3_NR,
-			.label	= "GPH3",
-			.to_irq = samsung_gpiolib_to_irq,
-		},
-	},
-};
-
-static __init int s5pc100_gpiolib_init(void)
-{
-	struct s3c_gpio_chip *chip = s5pc100_gpio_chips;
-	int nr_chips = ARRAY_SIZE(s5pc100_gpio_chips);
-	int gpioint_group = 0;
-	int i;
-
-	for (i = 0; i < nr_chips; i++, chip++) {
-		if (chip->config == NULL) {
-			chip->config = &gpio_cfg;
-			chip->group = gpioint_group++;
-		}
-		if (chip->base == NULL)
-			chip->base = S5PC100_BANK_BASE(i);
-	}
-
-	samsung_gpiolib_add_4bit_chips(s5pc100_gpio_chips, nr_chips);
-	s5p_register_gpioint_bank(IRQ_GPIOINT, 0, S5P_GPIOINT_GROUP_MAXNR);
-
-	return 0;
-}
-core_initcall(s5pc100_gpiolib_init);
diff -druN linux-2.6.39-libre/arch/arm/mach-s5pc100/Makefile linux-3.0-rc7-libre/arch/arm/mach-s5pc100/Makefile
--- linux-2.6.39-libre/arch/arm/mach-s5pc100/Makefile	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-s5pc100/Makefile	2011-07-11 19:51:52.000000000 -0400
@@ -11,7 +11,7 @@
 
 # Core support for S5PC100 system
 
-obj-$(CONFIG_CPU_S5PC100)	+= cpu.o init.o clock.o gpiolib.o
+obj-$(CONFIG_CPU_S5PC100)	+= cpu.o init.o clock.o
 obj-$(CONFIG_CPU_S5PC100)	+= setup-i2c0.o
 obj-$(CONFIG_CPU_S5PC100)	+= dma.o
 
diff -druN linux-2.6.39-libre/arch/arm/mach-s5pv210/cpufreq.c linux-3.0-rc7-libre/arch/arm/mach-s5pv210/cpufreq.c
--- linux-2.6.39-libre/arch/arm/mach-s5pv210/cpufreq.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-s5pv210/cpufreq.c	2011-07-11 19:51:52.000000000 -0400
@@ -101,12 +101,14 @@
 	unsigned long tmp, tmp1;
 	void __iomem *reg = NULL;
 
-	if (ch == DMC0)
+	if (ch == DMC0) {
 		reg = (S5P_VA_DMC0 + 0x30);
-	else if (ch == DMC1)
+	} else if (ch == DMC1) {
 		reg = (S5P_VA_DMC1 + 0x30);
-	else
+	} else {
 		printk(KERN_ERR "Cannot find DMC port\n");
+		return;
+	}
 
 	/* Find current DRAM frequency */
 	tmp = s5pv210_dram_conf[ch].freq;
diff -druN linux-2.6.39-libre/arch/arm/mach-s5pv210/dev-spi.c linux-3.0-rc7-libre/arch/arm/mach-s5pv210/dev-spi.c
--- linux-2.6.39-libre/arch/arm/mach-s5pv210/dev-spi.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-s5pv210/dev-spi.c	2011-07-11 19:51:52.000000000 -0400
@@ -85,6 +85,7 @@
 	.fifo_lvl_mask = 0x1ff,
 	.rx_lvl_offset = 15,
 	.high_speed = 1,
+	.tx_st_done = 25,
 };
 
 static u64 spi_dmamask = DMA_BIT_MASK(32);
@@ -129,6 +130,7 @@
 	.fifo_lvl_mask = 0x7f,
 	.rx_lvl_offset = 15,
 	.high_speed = 1,
+	.tx_st_done = 25,
 };
 
 struct platform_device s5pv210_device_spi1 = {
diff -druN linux-2.6.39-libre/arch/arm/mach-s5pv210/gpiolib.c linux-3.0-rc7-libre/arch/arm/mach-s5pv210/gpiolib.c
--- linux-2.6.39-libre/arch/arm/mach-s5pv210/gpiolib.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-s5pv210/gpiolib.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,288 +0,0 @@
-/* linux/arch/arm/mach-s5pv210/gpiolib.c
- *
- * Copyright (c) 2010 Samsung Electronics Co., Ltd.
- *		http://www.samsung.com/
- *
- * S5PV210 - GPIOlib support
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/kernel.h>
-#include <linux/irq.h>
-#include <linux/io.h>
-#include <linux/gpio.h>
-#include <plat/gpio-core.h>
-#include <plat/gpio-cfg.h>
-#include <plat/gpio-cfg-helpers.h>
-#include <mach/map.h>
-
-static struct s3c_gpio_cfg gpio_cfg = {
-	.set_config	= s3c_gpio_setcfg_s3c64xx_4bit,
-	.set_pull	= s3c_gpio_setpull_updown,
-	.get_pull	= s3c_gpio_getpull_updown,
-};
-
-static struct s3c_gpio_cfg gpio_cfg_noint = {
-	.set_config	= s3c_gpio_setcfg_s3c64xx_4bit,
-	.set_pull	= s3c_gpio_setpull_updown,
-	.get_pull	= s3c_gpio_getpull_updown,
-};
-
-/* GPIO bank's base address given the index of the bank in the
- * list of all gpio banks.
- */
-#define S5PV210_BANK_BASE(bank_nr)	(S5P_VA_GPIO + ((bank_nr) * 0x20))
-
-/*
- * Following are the gpio banks in v210.
- *
- * The 'config' member when left to NULL, is initialized to the default
- * structure gpio_cfg in the init function below.
- *
- * The 'base' member is also initialized in the init function below.
- * Note: The initialization of 'base' member of s3c_gpio_chip structure
- * uses the above macro and depends on the banks being listed in order here.
- */
-static struct s3c_gpio_chip s5pv210_gpio_4bit[] = {
-	{
-		.chip	= {
-			.base	= S5PV210_GPA0(0),
-			.ngpio	= S5PV210_GPIO_A0_NR,
-			.label	= "GPA0",
-		},
-	}, {
-		.chip	= {
-			.base	= S5PV210_GPA1(0),
-			.ngpio	= S5PV210_GPIO_A1_NR,
-			.label	= "GPA1",
-		},
-	}, {
-		.chip	= {
-			.base	= S5PV210_GPB(0),
-			.ngpio	= S5PV210_GPIO_B_NR,
-			.label	= "GPB",
-		},
-	}, {
-		.chip	= {
-			.base	= S5PV210_GPC0(0),
-			.ngpio	= S5PV210_GPIO_C0_NR,
-			.label	= "GPC0",
-		},
-	}, {
-		.chip	= {
-			.base	= S5PV210_GPC1(0),
-			.ngpio	= S5PV210_GPIO_C1_NR,
-			.label	= "GPC1",
-		},
-	}, {
-		.chip	= {
-			.base	= S5PV210_GPD0(0),
-			.ngpio	= S5PV210_GPIO_D0_NR,
-			.label	= "GPD0",
-		},
-	}, {
-		.chip	= {
-			.base	= S5PV210_GPD1(0),
-			.ngpio	= S5PV210_GPIO_D1_NR,
-			.label	= "GPD1",
-		},
-	}, {
-		.chip	= {
-			.base	= S5PV210_GPE0(0),
-			.ngpio	= S5PV210_GPIO_E0_NR,
-			.label	= "GPE0",
-		},
-	}, {
-		.chip	= {
-			.base	= S5PV210_GPE1(0),
-			.ngpio	= S5PV210_GPIO_E1_NR,
-			.label	= "GPE1",
-		},
-	}, {
-		.chip	= {
-			.base	= S5PV210_GPF0(0),
-			.ngpio	= S5PV210_GPIO_F0_NR,
-			.label	= "GPF0",
-		},
-	}, {
-		.chip	= {
-			.base	= S5PV210_GPF1(0),
-			.ngpio	= S5PV210_GPIO_F1_NR,
-			.label	= "GPF1",
-		},
-	}, {
-		.chip	= {
-			.base	= S5PV210_GPF2(0),
-			.ngpio	= S5PV210_GPIO_F2_NR,
-			.label	= "GPF2",
-		},
-	}, {
-		.chip	= {
-			.base	= S5PV210_GPF3(0),
-			.ngpio	= S5PV210_GPIO_F3_NR,
-			.label	= "GPF3",
-		},
-	}, {
-		.chip	= {
-			.base	= S5PV210_GPG0(0),
-			.ngpio	= S5PV210_GPIO_G0_NR,
-			.label	= "GPG0",
-		},
-	}, {
-		.chip	= {
-			.base	= S5PV210_GPG1(0),
-			.ngpio	= S5PV210_GPIO_G1_NR,
-			.label	= "GPG1",
-		},
-	}, {
-		.chip	= {
-			.base	= S5PV210_GPG2(0),
-			.ngpio	= S5PV210_GPIO_G2_NR,
-			.label	= "GPG2",
-		},
-	}, {
-		.chip	= {
-			.base	= S5PV210_GPG3(0),
-			.ngpio	= S5PV210_GPIO_G3_NR,
-			.label	= "GPG3",
-		},
-	}, {
-		.config	= &gpio_cfg_noint,
-		.chip	= {
-			.base	= S5PV210_GPI(0),
-			.ngpio	= S5PV210_GPIO_I_NR,
-			.label	= "GPI",
-		},
-	}, {
-		.chip	= {
-			.base	= S5PV210_GPJ0(0),
-			.ngpio	= S5PV210_GPIO_J0_NR,
-			.label	= "GPJ0",
-		},
-	}, {
-		.chip	= {
-			.base	= S5PV210_GPJ1(0),
-			.ngpio	= S5PV210_GPIO_J1_NR,
-			.label	= "GPJ1",
-		},
-	}, {
-		.chip	= {
-			.base	= S5PV210_GPJ2(0),
-			.ngpio	= S5PV210_GPIO_J2_NR,
-			.label	= "GPJ2",
-		},
-	}, {
-		.chip	= {
-			.base	= S5PV210_GPJ3(0),
-			.ngpio	= S5PV210_GPIO_J3_NR,
-			.label	= "GPJ3",
-		},
-	}, {
-		.chip	= {
-			.base	= S5PV210_GPJ4(0),
-			.ngpio	= S5PV210_GPIO_J4_NR,
-			.label	= "GPJ4",
-		},
-	}, {
-		.config	= &gpio_cfg_noint,
-		.chip	= {
-			.base	= S5PV210_MP01(0),
-			.ngpio	= S5PV210_GPIO_MP01_NR,
-			.label	= "MP01",
-		},
-	}, {
-		.config	= &gpio_cfg_noint,
-		.chip	= {
-			.base	= S5PV210_MP02(0),
-			.ngpio	= S5PV210_GPIO_MP02_NR,
-			.label	= "MP02",
-		},
-	}, {
-		.config	= &gpio_cfg_noint,
-		.chip	= {
-			.base	= S5PV210_MP03(0),
-			.ngpio	= S5PV210_GPIO_MP03_NR,
-			.label	= "MP03",
-		},
-	}, {
-		.config	= &gpio_cfg_noint,
-		.chip	= {
-			.base	= S5PV210_MP04(0),
-			.ngpio	= S5PV210_GPIO_MP04_NR,
-			.label	= "MP04",
-		},
-	}, {
-		.config	= &gpio_cfg_noint,
-		.chip	= {
-			.base	= S5PV210_MP05(0),
-			.ngpio	= S5PV210_GPIO_MP05_NR,
-			.label	= "MP05",
-		},
-	}, {
-		.base	= (S5P_VA_GPIO + 0xC00),
-		.config	= &gpio_cfg_noint,
-		.irq_base = IRQ_EINT(0),
-		.chip	= {
-			.base	= S5PV210_GPH0(0),
-			.ngpio	= S5PV210_GPIO_H0_NR,
-			.label	= "GPH0",
-			.to_irq = samsung_gpiolib_to_irq,
-		},
-	}, {
-		.base	= (S5P_VA_GPIO + 0xC20),
-		.config	= &gpio_cfg_noint,
-		.irq_base = IRQ_EINT(8),
-		.chip	= {
-			.base	= S5PV210_GPH1(0),
-			.ngpio	= S5PV210_GPIO_H1_NR,
-			.label	= "GPH1",
-			.to_irq = samsung_gpiolib_to_irq,
-		},
-	}, {
-		.base	= (S5P_VA_GPIO + 0xC40),
-		.config	= &gpio_cfg_noint,
-		.irq_base = IRQ_EINT(16),
-		.chip	= {
-			.base	= S5PV210_GPH2(0),
-			.ngpio	= S5PV210_GPIO_H2_NR,
-			.label	= "GPH2",
-			.to_irq = samsung_gpiolib_to_irq,
-		},
-	}, {
-		.base	= (S5P_VA_GPIO + 0xC60),
-		.config	= &gpio_cfg_noint,
-		.irq_base = IRQ_EINT(24),
-		.chip	= {
-			.base	= S5PV210_GPH3(0),
-			.ngpio	= S5PV210_GPIO_H3_NR,
-			.label	= "GPH3",
-			.to_irq = samsung_gpiolib_to_irq,
-		},
-	},
-};
-
-static __init int s5pv210_gpiolib_init(void)
-{
-	struct s3c_gpio_chip *chip = s5pv210_gpio_4bit;
-	int nr_chips = ARRAY_SIZE(s5pv210_gpio_4bit);
-	int gpioint_group = 0;
-	int i = 0;
-
-	for (i = 0; i < nr_chips; i++, chip++) {
-		if (chip->config == NULL) {
-			chip->config = &gpio_cfg;
-			chip->group = gpioint_group++;
-		}
-		if (chip->base == NULL)
-			chip->base = S5PV210_BANK_BASE(i);
-	}
-
-	samsung_gpiolib_add_4bit_chips(s5pv210_gpio_4bit, nr_chips);
-	s5p_register_gpioint_bank(IRQ_GPIOINT, 0, S5P_GPIOINT_GROUP_MAXNR);
-
-	return 0;
-}
-core_initcall(s5pv210_gpiolib_init);
diff -druN linux-2.6.39-libre/arch/arm/mach-s5pv210/Makefile linux-3.0-rc7-libre/arch/arm/mach-s5pv210/Makefile
--- linux-2.6.39-libre/arch/arm/mach-s5pv210/Makefile	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-s5pv210/Makefile	2011-07-11 19:51:52.000000000 -0400
@@ -12,7 +12,7 @@
 
 # Core support for S5PV210 system
 
-obj-$(CONFIG_CPU_S5PV210)	+= cpu.o init.o clock.o dma.o gpiolib.o
+obj-$(CONFIG_CPU_S5PV210)	+= cpu.o init.o clock.o dma.o
 obj-$(CONFIG_CPU_S5PV210)	+= setup-i2c0.o
 obj-$(CONFIG_S5PV210_PM)	+= pm.o sleep.o
 obj-$(CONFIG_CPU_FREQ)		+= cpufreq.o
diff -druN linux-2.6.39-libre/arch/arm/mach-s5pv210/pm.c linux-3.0-rc7-libre/arch/arm/mach-s5pv210/pm.c
--- linux-2.6.39-libre/arch/arm/mach-s5pv210/pm.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-s5pv210/pm.c	2011-07-11 19:51:52.000000000 -0400
@@ -16,6 +16,7 @@
 
 #include <linux/init.h>
 #include <linux/suspend.h>
+#include <linux/syscore_ops.h>
 #include <linux/io.h>
 
 #include <plat/cpu.h>
@@ -140,7 +141,17 @@
 	return 0;
 }
 
-static int s5pv210_pm_resume(struct sys_device *dev)
+static struct sysdev_driver s5pv210_pm_driver = {
+	.add		= s5pv210_pm_add,
+};
+
+static __init int s5pv210_pm_drvinit(void)
+{
+	return sysdev_driver_register(&s5pv210_sysclass, &s5pv210_pm_driver);
+}
+arch_initcall(s5pv210_pm_drvinit);
+
+static void s5pv210_pm_resume(void)
 {
 	u32 tmp;
 
@@ -150,17 +161,15 @@
 	__raw_writel(tmp , S5P_OTHERS);
 
 	s3c_pm_do_restore_core(s5pv210_core_save, ARRAY_SIZE(s5pv210_core_save));
-
-	return 0;
 }
 
-static struct sysdev_driver s5pv210_pm_driver = {
-	.add		= s5pv210_pm_add,
+static struct syscore_ops s5pv210_pm_syscore_ops = {
 	.resume		= s5pv210_pm_resume,
 };
 
-static __init int s5pv210_pm_drvinit(void)
+static __init int s5pv210_pm_syscore_init(void)
 {
-	return sysdev_driver_register(&s5pv210_sysclass, &s5pv210_pm_driver);
+	register_syscore_ops(&s5pv210_pm_syscore_ops);
+	return 0;
 }
-arch_initcall(s5pv210_pm_drvinit);
+arch_initcall(s5pv210_pm_syscore_init);
diff -druN linux-2.6.39-libre/arch/arm/mach-sa1100/include/mach/memory.h linux-3.0-rc7-libre/arch/arm/mach-sa1100/include/mach/memory.h
--- linux-2.6.39-libre/arch/arm/mach-sa1100/include/mach/memory.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-sa1100/include/mach/memory.h	2011-07-11 19:51:52.000000000 -0400
@@ -14,18 +14,8 @@
  */
 #define PLAT_PHYS_OFFSET	UL(0xc0000000)
 
-#ifndef __ASSEMBLY__
-
 #ifdef CONFIG_SA1111
-void sa1111_adjust_zones(unsigned long *size, unsigned long *holes);
-
-#define arch_adjust_zones(size, holes) \
-	sa1111_adjust_zones(size, holes)
-
-#define ISA_DMA_THRESHOLD	(PHYS_OFFSET + SZ_1M - 1)
-#define MAX_DMA_ADDRESS		(PAGE_OFFSET + SZ_1M)
-
-#endif
+#define ARM_DMA_ZONE_SIZE	SZ_1M
 #endif
 
 /*
diff -druN linux-2.6.39-libre/arch/arm/mach-sa1100/irq.c linux-3.0-rc7-libre/arch/arm/mach-sa1100/irq.c
--- linux-2.6.39-libre/arch/arm/mach-sa1100/irq.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-sa1100/irq.c	2011-07-11 19:51:52.000000000 -0400
@@ -14,7 +14,7 @@
 #include <linux/interrupt.h>
 #include <linux/irq.h>
 #include <linux/ioport.h>
-#include <linux/sysdev.h>
+#include <linux/syscore_ops.h>
 
 #include <mach/hardware.h>
 #include <asm/mach/irq.h>
@@ -234,7 +234,7 @@
 	unsigned int	iccr;
 } sa1100irq_state;
 
-static int sa1100irq_suspend(struct sys_device *dev, pm_message_t state)
+static int sa1100irq_suspend(void)
 {
 	struct sa1100irq_state *st = &sa1100irq_state;
 
@@ -264,7 +264,7 @@
 	return 0;
 }
 
-static int sa1100irq_resume(struct sys_device *dev)
+static void sa1100irq_resume(void)
 {
 	struct sa1100irq_state *st = &sa1100irq_state;
 
@@ -277,24 +277,17 @@
 
 		ICMR = st->icmr;
 	}
-	return 0;
 }
 
-static struct sysdev_class sa1100irq_sysclass = {
-	.name		= "sa11x0-irq",
+static struct syscore_ops sa1100irq_syscore_ops = {
 	.suspend	= sa1100irq_suspend,
 	.resume		= sa1100irq_resume,
 };
 
-static struct sys_device sa1100irq_device = {
-	.id		= 0,
-	.cls		= &sa1100irq_sysclass,
-};
-
 static int __init sa1100irq_init_devicefs(void)
 {
-	sysdev_class_register(&sa1100irq_sysclass);
-	return sysdev_register(&sa1100irq_device);
+	register_syscore_ops(&sa1100irq_syscore_ops);
+	return 0;
 }
 
 device_initcall(sa1100irq_init_devicefs);
diff -druN linux-2.6.39-libre/arch/arm/mach-sa1100/time.c linux-3.0-rc7-libre/arch/arm/mach-sa1100/time.c
--- linux-2.6.39-libre/arch/arm/mach-sa1100/time.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-sa1100/time.c	2011-07-11 19:51:52.000000000 -0400
@@ -92,25 +92,11 @@
 static struct clock_event_device ckevt_sa1100_osmr0 = {
 	.name		= "osmr0",
 	.features	= CLOCK_EVT_FEAT_ONESHOT,
-	.shift		= 32,
 	.rating		= 200,
 	.set_next_event	= sa1100_osmr0_set_next_event,
 	.set_mode	= sa1100_osmr0_set_mode,
 };
 
-static cycle_t sa1100_read_oscr(struct clocksource *s)
-{
-	return OSCR;
-}
-
-static struct clocksource cksrc_sa1100_oscr = {
-	.name		= "oscr",
-	.rating		= 200,
-	.read		= sa1100_read_oscr,
-	.mask		= CLOCKSOURCE_MASK(32),
-	.flags		= CLOCK_SOURCE_IS_CONTINUOUS,
-};
-
 static struct irqaction sa1100_timer_irq = {
 	.name		= "ost0",
 	.flags		= IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
@@ -120,14 +106,13 @@
 
 static void __init sa1100_timer_init(void)
 {
-	OIER = 0;		/* disable any timer interrupts */
-	OSSR = 0xf;		/* clear status on all timers */
+	OIER = 0;
+	OSSR = OSSR_M0 | OSSR_M1 | OSSR_M2 | OSSR_M3;
 
 	init_fixed_sched_clock(&cd, sa1100_update_sched_clock, 32,
 			       3686400, SC_MULT, SC_SHIFT);
 
-	ckevt_sa1100_osmr0.mult =
-		div_sc(3686400, NSEC_PER_SEC, ckevt_sa1100_osmr0.shift);
+	clockevents_calc_mult_shift(&ckevt_sa1100_osmr0, 3686400, 4);
 	ckevt_sa1100_osmr0.max_delta_ns =
 		clockevent_delta2ns(0x7fffffff, &ckevt_sa1100_osmr0);
 	ckevt_sa1100_osmr0.min_delta_ns =
@@ -136,7 +121,8 @@
 
 	setup_irq(IRQ_OST0, &sa1100_timer_irq);
 
-	clocksource_register_hz(&cksrc_sa1100_oscr, CLOCK_TICK_RATE);
+	clocksource_mmio_init(&OSCR, "oscr", CLOCK_TICK_RATE, 200, 32,
+		clocksource_mmio_readl_up);
 	clockevents_register_device(&ckevt_sa1100_osmr0);
 }
 
diff -druN linux-2.6.39-libre/arch/arm/mach-shark/include/mach/memory.h linux-3.0-rc7-libre/arch/arm/mach-shark/include/mach/memory.h
--- linux-2.6.39-libre/arch/arm/mach-shark/include/mach/memory.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-shark/include/mach/memory.h	2011-07-11 19:51:52.000000000 -0400
@@ -17,25 +17,7 @@
  */
 #define PLAT_PHYS_OFFSET     UL(0x08000000)
 
-#ifndef __ASSEMBLY__
-
-static inline void __arch_adjust_zones(unsigned long *zone_size, unsigned long *zhole_size)
-{
-  /* Only the first 4 MB (=1024 Pages) are usable for DMA */
-  /* See dev / -> .properties in OpenFirmware. */
-  zone_size[1] = zone_size[0] - 1024;
-  zone_size[0] = 1024;
-  zhole_size[1] = zhole_size[0];
-  zhole_size[0] = 0;
-}
-
-#define arch_adjust_zones(size, holes) \
-	__arch_adjust_zones(size, holes)
-
-#define ISA_DMA_THRESHOLD	(PHYS_OFFSET + SZ_4M - 1)
-#define MAX_DMA_ADDRESS		(PAGE_OFFSET + SZ_4M)
-
-#endif
+#define ARM_DMA_ZONE_SIZE	SZ_4M
 
 /*
  * Cache flushing area
diff -druN linux-2.6.39-libre/arch/arm/mach-shmobile/board-ag5evm.c linux-3.0-rc7-libre/arch/arm/mach-shmobile/board-ag5evm.c
--- linux-2.6.39-libre/arch/arm/mach-shmobile/board-ag5evm.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-shmobile/board-ag5evm.c	2011-07-11 19:51:52.000000000 -0400
@@ -34,6 +34,8 @@
 #include <linux/input/sh_keysc.h>
 #include <linux/mmc/host.h>
 #include <linux/mmc/sh_mmcif.h>
+#include <linux/mmc/sh_mobile_sdhi.h>
+#include <linux/mfd/tmio.h>
 #include <linux/sh_clk.h>
 #include <video/sh_mobile_lcdc.h>
 #include <video/sh_mipi_dsi.h>
@@ -156,10 +158,19 @@
 	},
 };
 
+static struct sh_mmcif_dma sh_mmcif_dma = {
+	.chan_priv_rx	= {
+		.slave_id	= SHDMA_SLAVE_MMCIF_RX,
+	},
+	.chan_priv_tx	= {
+		.slave_id	= SHDMA_SLAVE_MMCIF_TX,
+	},
+};
 static struct sh_mmcif_plat_data sh_mmcif_platdata = {
 	.sup_pclk	= 0,
 	.ocr		= MMC_VDD_165_195,
 	.caps		= MMC_CAP_8_BIT_DATA | MMC_CAP_NONREMOVABLE,
+	.dma		= &sh_mmcif_dma,
 };
 
 static struct platform_device mmc_device = {
@@ -296,11 +307,13 @@
 /* MIPI-DSI */
 static struct resource mipidsi0_resources[] = {
 	[0] = {
+		.name	= "DSI0",
 		.start  = 0xfeab0000,
 		.end    = 0xfeab3fff,
 		.flags  = IORESOURCE_MEM,
 	},
 	[1] = {
+		.name	= "DSI0",
 		.start  = 0xfeab4000,
 		.end    = 0xfeab7fff,
 		.flags  = IORESOURCE_MEM,
@@ -325,6 +338,87 @@
 	},
 };
 
+static struct sh_mobile_sdhi_info sdhi0_info = {
+	.dma_slave_tx	= SHDMA_SLAVE_SDHI0_TX,
+	.dma_slave_rx	= SHDMA_SLAVE_SDHI0_RX,
+	.tmio_caps	= MMC_CAP_SD_HIGHSPEED,
+	.tmio_ocr_mask	= MMC_VDD_27_28 | MMC_VDD_28_29,
+};
+
+static struct resource sdhi0_resources[] = {
+	[0] = {
+		.name	= "SDHI0",
+		.start	= 0xee100000,
+		.end	= 0xee1000ff,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= gic_spi(83),
+		.flags	= IORESOURCE_IRQ,
+	},
+	[2] = {
+		.start	= gic_spi(84),
+		.flags	= IORESOURCE_IRQ,
+	},
+	[3] = {
+		.start	= gic_spi(85),
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device sdhi0_device = {
+	.name		= "sh_mobile_sdhi",
+	.id		= 0,
+	.num_resources	= ARRAY_SIZE(sdhi0_resources),
+	.resource	= sdhi0_resources,
+	.dev	= {
+		.platform_data	= &sdhi0_info,
+	},
+};
+
+void ag5evm_sdhi1_set_pwr(struct platform_device *pdev, int state)
+{
+	gpio_set_value(GPIO_PORT114, state);
+}
+
+static struct sh_mobile_sdhi_info sh_sdhi1_info = {
+	.tmio_flags	= TMIO_MMC_WRPROTECT_DISABLE,
+	.tmio_caps	= MMC_CAP_NONREMOVABLE | MMC_CAP_SDIO_IRQ,
+	.tmio_ocr_mask	= MMC_VDD_32_33 | MMC_VDD_33_34,
+	.set_pwr	= ag5evm_sdhi1_set_pwr,
+};
+
+static struct resource sdhi1_resources[] = {
+	[0] = {
+		.name	= "SDHI1",
+		.start	= 0xee120000,
+		.end	= 0xee1200ff,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= gic_spi(87),
+		.flags	= IORESOURCE_IRQ,
+	},
+	[2] = {
+		.start	= gic_spi(88),
+		.flags	= IORESOURCE_IRQ,
+	},
+	[3] = {
+		.start	= gic_spi(89),
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device sdhi1_device = {
+	.name		= "sh_mobile_sdhi",
+	.id		= 1,
+	.dev		= {
+		.platform_data	= &sh_sdhi1_info,
+	},
+	.num_resources	= ARRAY_SIZE(sdhi1_resources),
+	.resource	= sdhi1_resources,
+};
+
 static struct platform_device *ag5evm_devices[] __initdata = {
 	&eth_device,
 	&keysc_device,
@@ -333,6 +427,8 @@
 	&irda_device,
 	&lcdc0_device,
 	&mipidsi0_device,
+	&sdhi0_device,
+	&sdhi1_device,
 };
 
 static struct map_desc ag5evm_io_desc[] __initdata = {
@@ -454,6 +550,26 @@
 	/* MIPI-DSI clock setup */
 	__raw_writel(0x2a809010, DSI0PHYCR);
 
+	/* enable SDHI0 on CN15 [SD I/F] */
+	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);
+
+	/* enable SDHI1 on CN4 [WLAN I/F] */
+	gpio_request(GPIO_FN_SDHICLK1, NULL);
+	gpio_request(GPIO_FN_SDHICMD1_PU, NULL);
+	gpio_request(GPIO_FN_SDHID1_3_PU, NULL);
+	gpio_request(GPIO_FN_SDHID1_2_PU, NULL);
+	gpio_request(GPIO_FN_SDHID1_1_PU, NULL);
+	gpio_request(GPIO_FN_SDHID1_0_PU, NULL);
+	gpio_request(GPIO_PORT114, "sdhi1_power");
+	gpio_direction_output(GPIO_PORT114, 0);
+
 #ifdef CONFIG_CACHE_L2X0
 	/* Shared attribute override enable, 64K*8way */
 	l2x0_init(__io(0xf0100000), 0x00460000, 0xc2000fff);
diff -druN linux-2.6.39-libre/arch/arm/mach-shmobile/board-ap4evb.c linux-3.0-rc7-libre/arch/arm/mach-shmobile/board-ap4evb.c
--- linux-2.6.39-libre/arch/arm/mach-shmobile/board-ap4evb.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-shmobile/board-ap4evb.c	2011-07-11 19:51:52.000000000 -0400
@@ -249,6 +249,29 @@
 {
 	return !gpio_get_value(GPIO_PORT41);
 }
+/* MERAM */
+static struct sh_mobile_meram_info meram_info = {
+	.addr_mode      = SH_MOBILE_MERAM_MODE1,
+};
+
+static struct resource meram_resources[] = {
+	[0] = {
+		.name   = "MERAM",
+		.start  = 0xe8000000,
+		.end    = 0xe81fffff,
+		.flags  = IORESOURCE_MEM,
+	},
+};
+
+static struct platform_device meram_device = {
+	.name           = "sh_mobile_meram",
+	.id             = 0,
+	.num_resources  = ARRAY_SIZE(meram_resources),
+	.resource       = meram_resources,
+	.dev            = {
+		.platform_data = &meram_info,
+	},
+};
 
 /* SH_MMCIF */
 static struct resource sh_mmcif_resources[] = {
@@ -316,8 +339,16 @@
 		.flags  = IORESOURCE_MEM,
 	},
 	[1] = {
-		.start  = evt2irq(0x0e00) /* SDHI0 */,
-		.flags  = IORESOURCE_IRQ,
+		.start	= evt2irq(0x0e00) /* SDHI0_SDHI0I0 */,
+		.flags	= IORESOURCE_IRQ,
+	},
+	[2] = {
+		.start	= evt2irq(0x0e20) /* SDHI0_SDHI0I1 */,
+		.flags	= IORESOURCE_IRQ,
+	},
+	[3] = {
+		.start	= evt2irq(0x0e40) /* SDHI0_SDHI0I2 */,
+		.flags	= IORESOURCE_IRQ,
 	},
 };
 
@@ -349,8 +380,16 @@
 		.flags  = IORESOURCE_MEM,
 	},
 	[1] = {
-		.start  = evt2irq(0x0e80),
-		.flags  = IORESOURCE_IRQ,
+		.start	= evt2irq(0x0e80), /* SDHI1_SDHI1I0 */
+		.flags	= IORESOURCE_IRQ,
+	},
+	[2] = {
+		.start	= evt2irq(0x0ea0), /* SDHI1_SDHI1I1 */
+		.flags	= IORESOURCE_IRQ,
+	},
+	[3] = {
+		.start	= evt2irq(0x0ec0), /* SDHI1_SDHI1I2 */
+		.flags	= IORESOURCE_IRQ,
 	},
 };
 
@@ -431,13 +470,29 @@
 #endif
 	},
 };
+static struct sh_mobile_meram_cfg lcd_meram_cfg = {
+	.icb[0] = {
+		.marker_icb     = 28,
+		.cache_icb      = 24,
+		.meram_offset   = 0x0,
+		.meram_size     = 0x40,
+	},
+	.icb[1] = {
+		.marker_icb     = 29,
+		.cache_icb      = 25,
+		.meram_offset   = 0x40,
+		.meram_size     = 0x40,
+	},
+};
 
 static struct sh_mobile_lcdc_info lcdc_info = {
+	.meram_dev = &meram_info,
 	.ch[0] = {
 		.chan = LCDC_CHAN_MAINLCD,
 		.bpp = 16,
 		.lcd_cfg = ap4evb_lcdc_modes,
 		.num_cfg = ARRAY_SIZE(ap4evb_lcdc_modes),
+		.meram_cfg = &lcd_meram_cfg,
 	}
 };
 
@@ -708,15 +763,31 @@
 static struct platform_device fsi_ak4643_device = {
 	.name		= "sh_fsi2_a_ak4643",
 };
+static struct sh_mobile_meram_cfg hdmi_meram_cfg = {
+	.icb[0] = {
+		.marker_icb     = 30,
+		.cache_icb      = 26,
+		.meram_offset   = 0x80,
+		.meram_size     = 0x100,
+	},
+	.icb[1] = {
+		.marker_icb     = 31,
+		.cache_icb      = 27,
+		.meram_offset   = 0x180,
+		.meram_size     = 0x100,
+	},
+};
 
 static struct sh_mobile_lcdc_info sh_mobile_lcdc1_info = {
 	.clock_source = LCDC_CLK_EXTERNAL,
+	.meram_dev = &meram_info,
 	.ch[0] = {
 		.chan = LCDC_CHAN_MAINLCD,
 		.bpp = 16,
 		.interface_type = RGB24,
 		.clock_divider = 1,
 		.flags = LCDC_FLAGS_DWPOL,
+		.meram_cfg = &hdmi_meram_cfg,
 	}
 };
 
@@ -842,7 +913,7 @@
 	I2C_BOARD_INFO("imx074", 0x1a),
 };
 
-struct soc_camera_link imx074_link = {
+static struct soc_camera_link imx074_link = {
 	.bus_id		= 0,
 	.board_info	= &imx074_info,
 	.i2c_adapter_id	= 0,
@@ -945,6 +1016,7 @@
 	&csi2_device,
 	&ceu_device,
 	&ap4evb_camera,
+	&meram_device,
 };
 
 static void __init hdmi_init_pm_clock(void)
@@ -980,11 +1052,6 @@
 		goto out;
 	}
 
-	ret = clk_enable(&sh7372_pllc2_clk);
-	if (ret < 0) {
-		pr_err("Cannot enable pllc2 clock\n");
-		goto out;
-	}
 	pr_debug("PLLC2 set frequency %lu\n", rate);
 
 	ret = clk_set_parent(hdmi_ick, &sh7372_pllc2_clk);
@@ -1343,6 +1410,7 @@
 
 	hdmi_init_pm_clock();
 	fsi_init_pm_clock();
+	sh7372_pm_init();
 }
 
 static void __init ap4evb_timer_init(void)
diff -druN linux-2.6.39-libre/arch/arm/mach-shmobile/board-g4evm.c linux-3.0-rc7-libre/arch/arm/mach-shmobile/board-g4evm.c
--- linux-2.6.39-libre/arch/arm/mach-shmobile/board-g4evm.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-shmobile/board-g4evm.c	2011-07-11 19:51:52.000000000 -0400
@@ -205,7 +205,7 @@
 	[0] = {
 		.name	= "SDHI0",
 		.start  = 0xe6d50000,
-		.end    = 0xe6d50nff,
+		.end    = 0xe6d500ff,
 		.flags  = IORESOURCE_MEM,
 	},
 	[1] = {
diff -druN linux-2.6.39-libre/arch/arm/mach-shmobile/board-mackerel.c linux-3.0-rc7-libre/arch/arm/mach-shmobile/board-mackerel.c
--- linux-2.6.39-libre/arch/arm/mach-shmobile/board-mackerel.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-shmobile/board-mackerel.c	2011-07-11 19:51:52.000000000 -0400
@@ -39,10 +39,12 @@
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/partitions.h>
 #include <linux/mtd/physmap.h>
+#include <linux/pm_runtime.h>
 #include <linux/smsc911x.h>
 #include <linux/sh_intc.h>
 #include <linux/tca6416_keypad.h>
 #include <linux/usb/r8a66597.h>
+#include <linux/usb/renesas_usbhs.h>
 
 #include <video/sh_mobile_hdmi.h>
 #include <video/sh_mobile_lcdc.h>
@@ -124,7 +126,7 @@
  * ------+--------------------+--------------------+-------
  * IRQ0  | ICR1A.IRQ0SA=0010  | SDHI2 card detect  | Low
  * IRQ6  | ICR1A.IRQ6SA=0011  | Ether(LAN9220)     | High
- * IRQ7  | ICR1A.IRQ7SA=0010  | LCD Tuch Panel     | Low
+ * IRQ7  | ICR1A.IRQ7SA=0010  | LCD Touch Panel    | Low
  * IRQ8  | ICR2A.IRQ8SA=0010  | MMC/SD card detect | Low
  * IRQ9  | ICR2A.IRQ9SA=0010  | KEY(TCA6408)       | Low
  * IRQ21 | ICR4A.IRQ21SA=0011 | Sensor(ADXL345)    | High
@@ -143,7 +145,30 @@
  * open      | external VBUS | Function
  *
  * *1
- * CN31 is used as Host in Linux.
+ * CN31 is used as
+ * CONFIG_USB_R8A66597_HCD	Host
+ * CONFIG_USB_RENESAS_USBHS	Function
+ *
+ * CAUTION
+ *
+ * renesas_usbhs driver can use external interrupt mode
+ * (which come from USB-PHY) or autonomy mode (it use own interrupt)
+ * for detecting connection/disconnection when Function.
+ * USB will be power OFF while it has been disconnecting
+ * if external interrupt mode, and it is always power ON if autonomy mode,
+ *
+ * mackerel can not use external interrupt (IRQ7-PORT167) mode on "USB0",
+ * because Touchscreen is using IRQ7-PORT40.
+ * It is impossible to use IRQ7 demux on this board.
+ *
+ * We can use external interrupt mode USB-Function on "USB1".
+ * USB1 can become Host by r8a66597, and become Function by renesas_usbhs.
+ * But don't select both drivers in same time.
+ * These uses same IRQ number for request_irq(), and aren't supporting
+ * IRQF_SHARED / IORESOURCE_IRQ_SHAREABLE.
+ *
+ * Actually these are old/new version of USB driver.
+ * This mean its register will be broken if it supports shared IRQ,
  */
 
 /*
@@ -185,6 +210,7 @@
  * FIXME !!
  *
  * gpio_no_direction
+ * gpio_pull_down
  * are quick_hack.
  *
  * current gpio frame work doesn't have
@@ -196,6 +222,16 @@
 	__raw_writeb(0x00, addr);
 }
 
+static void __init gpio_pull_down(u32 addr)
+{
+	u8 data = __raw_readb(addr);
+
+	data &= 0x0F;
+	data |= 0xA0;
+
+	__raw_writeb(data, addr);
+}
+
 /* MTD */
 static struct mtd_partition nor_flash_partitions[] = {
 	{
@@ -279,6 +315,30 @@
 	},
 };
 
+/* MERAM */
+static struct sh_mobile_meram_info mackerel_meram_info = {
+	.addr_mode	= SH_MOBILE_MERAM_MODE1,
+};
+
+static struct resource meram_resources[] = {
+	[0] = {
+		.name	= "MERAM",
+		.start	= 0xe8000000,
+		.end	= 0xe81fffff,
+		.flags	= IORESOURCE_MEM,
+	},
+};
+
+static struct platform_device meram_device = {
+	.name		= "sh_mobile_meram",
+	.id		= 0,
+	.num_resources	= ARRAY_SIZE(meram_resources),
+	.resource	= meram_resources,
+	.dev		= {
+		.platform_data = &mackerel_meram_info,
+	},
+};
+
 /* LCDC */
 static struct fb_videomode mackerel_lcdc_modes[] = {
 	{
@@ -307,7 +367,23 @@
 	return gpio_get_value(GPIO_PORT31);
 }
 
+static struct sh_mobile_meram_cfg lcd_meram_cfg = {
+	.icb[0] = {
+		.marker_icb     = 28,
+		.cache_icb      = 24,
+		.meram_offset   = 0x0,
+		.meram_size     = 0x40,
+	},
+	.icb[1] = {
+		.marker_icb     = 29,
+		.cache_icb      = 25,
+		.meram_offset   = 0x40,
+		.meram_size     = 0x40,
+	},
+};
+
 static struct sh_mobile_lcdc_info lcdc_info = {
+	.meram_dev = &mackerel_meram_info,
 	.clock_source = LCDC_CLK_BUS,
 	.ch[0] = {
 		.chan = LCDC_CHAN_MAINLCD,
@@ -327,6 +403,7 @@
 			.name = "sh_mobile_lcdc_bl",
 			.max_brightness = 1,
 		},
+		.meram_cfg = &lcd_meram_cfg,
 	}
 };
 
@@ -353,8 +430,23 @@
 	},
 };
 
+static struct sh_mobile_meram_cfg hdmi_meram_cfg = {
+	.icb[0] = {
+		.marker_icb     = 30,
+		.cache_icb      = 26,
+		.meram_offset   = 0x80,
+		.meram_size     = 0x100,
+	},
+	.icb[1] = {
+		.marker_icb     = 31,
+		.cache_icb      = 27,
+		.meram_offset   = 0x180,
+		.meram_size     = 0x100,
+	},
+};
 /* HDMI */
 static struct sh_mobile_lcdc_info hdmi_lcdc_info = {
+	.meram_dev = &mackerel_meram_info,
 	.clock_source = LCDC_CLK_EXTERNAL,
 	.ch[0] = {
 		.chan = LCDC_CHAN_MAINLCD,
@@ -362,6 +454,7 @@
 		.interface_type = RGB24,
 		.clock_divider = 1,
 		.flags = LCDC_FLAGS_DWPOL,
+		.meram_cfg = &hdmi_meram_cfg,
 	}
 };
 
@@ -458,12 +551,6 @@
 		goto out;
 	}
 
-	ret = clk_enable(&sh7372_pllc2_clk);
-	if (ret < 0) {
-		pr_err("Cannot enable pllc2 clock\n");
-		goto out;
-	}
-
 	pr_debug("PLLC2 set frequency %lu\n", rate);
 
 	ret = clk_set_parent(hdmi_ick, &sh7372_pllc2_clk);
@@ -475,7 +562,121 @@
 		clk_put(hdmi_ick);
 }
 
-/* USB1 (Host) */
+/* USBHS0 is connected to CN22 which takes a USB Mini-B plug
+ *
+ * The sh7372 SoC has IRQ7 set aside for USBHS0 hotplug,
+ * but on this particular board IRQ7 is already used by
+ * the touch screen. This leaves us with software polling.
+ */
+#define USBHS0_POLL_INTERVAL (HZ * 5)
+
+struct usbhs_private {
+	unsigned int usbphyaddr;
+	unsigned int usbcrcaddr;
+	struct renesas_usbhs_platform_info info;
+	struct delayed_work work;
+	struct platform_device *pdev;
+};
+
+#define usbhs_get_priv(pdev)				\
+	container_of(renesas_usbhs_get_info(pdev),	\
+		     struct usbhs_private, info)
+
+#define usbhs_is_connected(priv)			\
+	(!((1 << 7) & __raw_readw(priv->usbcrcaddr)))
+
+static int usbhs_get_vbus(struct platform_device *pdev)
+{
+	return usbhs_is_connected(usbhs_get_priv(pdev));
+}
+
+static void usbhs_phy_reset(struct platform_device *pdev)
+{
+	struct usbhs_private *priv = usbhs_get_priv(pdev);
+
+	/* init phy */
+	__raw_writew(0x8a0a, priv->usbcrcaddr);
+}
+
+static int usbhs0_get_id(struct platform_device *pdev)
+{
+	return USBHS_GADGET;
+}
+
+static void usbhs0_work_function(struct work_struct *work)
+{
+	struct usbhs_private *priv = container_of(work, struct usbhs_private,
+						  work.work);
+
+	renesas_usbhs_call_notify_hotplug(priv->pdev);
+	schedule_delayed_work(&priv->work, USBHS0_POLL_INTERVAL);
+}
+
+static int usbhs0_hardware_init(struct platform_device *pdev)
+{
+	struct usbhs_private *priv = usbhs_get_priv(pdev);
+
+	priv->pdev = pdev;
+	INIT_DELAYED_WORK(&priv->work, usbhs0_work_function);
+	schedule_delayed_work(&priv->work, USBHS0_POLL_INTERVAL);
+	return 0;
+}
+
+static void usbhs0_hardware_exit(struct platform_device *pdev)
+{
+	struct usbhs_private *priv = usbhs_get_priv(pdev);
+
+	cancel_delayed_work_sync(&priv->work);
+}
+
+static struct usbhs_private usbhs0_private = {
+	.usbcrcaddr	= 0xe605810c,		/* USBCR2 */
+	.info = {
+		.platform_callback = {
+			.hardware_init	= usbhs0_hardware_init,
+			.hardware_exit	= usbhs0_hardware_exit,
+			.phy_reset	= usbhs_phy_reset,
+			.get_id		= usbhs0_get_id,
+			.get_vbus	= usbhs_get_vbus,
+		},
+		.driver_param = {
+			.buswait_bwait	= 4,
+		},
+	},
+};
+
+static struct resource usbhs0_resources[] = {
+	[0] = {
+		.name	= "USBHS0",
+		.start	= 0xe6890000,
+		.end	= 0xe68900e6 - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= evt2irq(0x1ca0) /* USB0_USB0I0 */,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device usbhs0_device = {
+	.name	= "renesas_usbhs",
+	.id	= 0,
+	.dev = {
+		.platform_data		= &usbhs0_private.info,
+	},
+	.num_resources	= ARRAY_SIZE(usbhs0_resources),
+	.resource	= usbhs0_resources,
+};
+
+/* USBHS1 is connected to CN31 which takes a USB Mini-AB plug
+ *
+ * Use J30 to select between Host and Function. This setting
+ * can however not be detected by software. Hotplug of USBHS1
+ * is provided via IRQ8.
+ */
+#define IRQ8 evt2irq(0x0300)
+
+/* USBHS1 USB Host support via r8a66597_hcd */
 static void usb1_host_port_power(int port, int power)
 {
 	if (!power) /* only power-on is supported for now */
@@ -492,9 +693,9 @@
 
 static struct resource usb1_host_resources[] = {
 	[0] = {
-		.name	= "USBHS",
-		.start	= 0xE68B0000,
-		.end	= 0xE68B00E6 - 1,
+		.name	= "USBHS1",
+		.start	= 0xe68b0000,
+		.end	= 0xe68b00e6 - 1,
 		.flags	= IORESOURCE_MEM,
 	},
 	[1] = {
@@ -515,6 +716,127 @@
 	.resource	= usb1_host_resources,
 };
 
+/* USBHS1 USB Function support via renesas_usbhs */
+
+#define USB_PHY_MODE		(1 << 4)
+#define USB_PHY_INT_EN		((1 << 3) | (1 << 2))
+#define USB_PHY_ON		(1 << 1)
+#define USB_PHY_OFF		(1 << 0)
+#define USB_PHY_INT_CLR		(USB_PHY_ON | USB_PHY_OFF)
+
+static irqreturn_t usbhs1_interrupt(int irq, void *data)
+{
+	struct platform_device *pdev = data;
+	struct usbhs_private *priv = usbhs_get_priv(pdev);
+
+	dev_dbg(&pdev->dev, "%s\n", __func__);
+
+	renesas_usbhs_call_notify_hotplug(pdev);
+
+	/* clear status */
+	__raw_writew(__raw_readw(priv->usbphyaddr) | USB_PHY_INT_CLR,
+		     priv->usbphyaddr);
+
+	return IRQ_HANDLED;
+}
+
+static int usbhs1_hardware_init(struct platform_device *pdev)
+{
+	struct usbhs_private *priv = usbhs_get_priv(pdev);
+	int ret;
+
+	/* clear interrupt status */
+	__raw_writew(USB_PHY_MODE | USB_PHY_INT_CLR, priv->usbphyaddr);
+
+	ret = request_irq(IRQ8, usbhs1_interrupt, IRQF_TRIGGER_HIGH,
+			  dev_name(&pdev->dev), pdev);
+	if (ret) {
+		dev_err(&pdev->dev, "request_irq err\n");
+		return ret;
+	}
+
+	/* enable USB phy interrupt */
+	__raw_writew(USB_PHY_MODE | USB_PHY_INT_EN, priv->usbphyaddr);
+
+	return 0;
+}
+
+static void usbhs1_hardware_exit(struct platform_device *pdev)
+{
+	struct usbhs_private *priv = usbhs_get_priv(pdev);
+
+	/* clear interrupt status */
+	__raw_writew(USB_PHY_MODE | USB_PHY_INT_CLR, priv->usbphyaddr);
+
+	free_irq(IRQ8, pdev);
+}
+
+static int usbhs1_get_id(struct platform_device *pdev)
+{
+	return USBHS_GADGET;
+}
+
+static u32 usbhs1_pipe_cfg[] = {
+	USB_ENDPOINT_XFER_CONTROL,
+	USB_ENDPOINT_XFER_ISOC,
+	USB_ENDPOINT_XFER_ISOC,
+	USB_ENDPOINT_XFER_BULK,
+	USB_ENDPOINT_XFER_BULK,
+	USB_ENDPOINT_XFER_BULK,
+	USB_ENDPOINT_XFER_INT,
+	USB_ENDPOINT_XFER_INT,
+	USB_ENDPOINT_XFER_INT,
+	USB_ENDPOINT_XFER_BULK,
+	USB_ENDPOINT_XFER_BULK,
+	USB_ENDPOINT_XFER_BULK,
+	USB_ENDPOINT_XFER_BULK,
+	USB_ENDPOINT_XFER_BULK,
+	USB_ENDPOINT_XFER_BULK,
+	USB_ENDPOINT_XFER_BULK,
+};
+
+static struct usbhs_private usbhs1_private = {
+	.usbphyaddr	= 0xe60581e2,		/* USBPHY1INTAP */
+	.usbcrcaddr	= 0xe6058130,		/* USBCR4 */
+	.info = {
+		.platform_callback = {
+			.hardware_init	= usbhs1_hardware_init,
+			.hardware_exit	= usbhs1_hardware_exit,
+			.get_id		= usbhs1_get_id,
+			.phy_reset	= usbhs_phy_reset,
+			.get_vbus	= usbhs_get_vbus,
+		},
+		.driver_param = {
+			.buswait_bwait	= 4,
+			.pipe_type	= usbhs1_pipe_cfg,
+			.pipe_size	= ARRAY_SIZE(usbhs1_pipe_cfg),
+		},
+	},
+};
+
+static struct resource usbhs1_resources[] = {
+	[0] = {
+		.name	= "USBHS1",
+		.start	= 0xe68b0000,
+		.end	= 0xe68b00e6 - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= evt2irq(0x1ce0) /* USB1_USB1I0 */,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device usbhs1_device = {
+	.name	= "renesas_usbhs",
+	.id	= 1,
+	.dev = {
+		.platform_data		= &usbhs1_private.info,
+	},
+	.num_resources	= ARRAY_SIZE(usbhs1_resources),
+	.resource	= usbhs1_resources,
+};
+
 /* LED */
 static struct gpio_led mackerel_leds[] = {
 	{
@@ -676,6 +998,17 @@
 }
 
 /* SDHI0 */
+static irqreturn_t mackerel_sdhi0_gpio_cd(int irq, void *arg)
+{
+	struct device *dev = arg;
+	struct sh_mobile_sdhi_info *info = dev->platform_data;
+	struct tmio_mmc_data *pdata = info->pdata;
+
+	tmio_mmc_cd_wakeup(pdata);
+
+	return IRQ_HANDLED;
+}
+
 static struct sh_mobile_sdhi_info sdhi0_info = {
 	.dma_slave_tx	= SHDMA_SLAVE_SDHI0_TX,
 	.dma_slave_rx	= SHDMA_SLAVE_SDHI0_RX,
@@ -690,7 +1023,15 @@
 		.flags	= IORESOURCE_MEM,
 	},
 	[1] = {
-		.start	= evt2irq(0x0e00) /* SDHI0 */,
+		.start	= evt2irq(0x0e00) /* SDHI0_SDHI0I0 */,
+		.flags	= IORESOURCE_IRQ,
+	},
+	[2] = {
+		.start	= evt2irq(0x0e20) /* SDHI0_SDHI0I1 */,
+		.flags	= IORESOURCE_IRQ,
+	},
+	[3] = {
+		.start	= evt2irq(0x0e40) /* SDHI0_SDHI0I2 */,
 		.flags	= IORESOURCE_IRQ,
 	},
 };
@@ -705,7 +1046,7 @@
 	},
 };
 
-#if !defined(CONFIG_MMC_SH_MMCIF)
+#if !defined(CONFIG_MMC_SH_MMCIF) && !defined(CONFIG_MMC_SH_MMCIF_MODULE)
 /* SDHI1 */
 static struct sh_mobile_sdhi_info sdhi1_info = {
 	.dma_slave_tx	= SHDMA_SLAVE_SDHI1_TX,
@@ -725,7 +1066,15 @@
 		.flags	= IORESOURCE_MEM,
 	},
 	[1] = {
-		.start	= evt2irq(0x0e80),
+		.start	= evt2irq(0x0e80), /* SDHI1_SDHI1I0 */
+		.flags	= IORESOURCE_IRQ,
+	},
+	[2] = {
+		.start	= evt2irq(0x0ea0), /* SDHI1_SDHI1I1 */
+		.flags	= IORESOURCE_IRQ,
+	},
+	[3] = {
+		.start	= evt2irq(0x0ec0), /* SDHI1_SDHI1I2 */
 		.flags	= IORESOURCE_IRQ,
 	},
 };
@@ -768,7 +1117,15 @@
 		.flags	= IORESOURCE_MEM,
 	},
 	[1] = {
-		.start	= evt2irq(0x1200),
+		.start	= evt2irq(0x1200), /* SDHI2_SDHI2I0 */
+		.flags	= IORESOURCE_IRQ,
+	},
+	[2] = {
+		.start	= evt2irq(0x1220), /* SDHI2_SDHI2I1 */
+		.flags	= IORESOURCE_IRQ,
+	},
+	[3] = {
+		.start	= evt2irq(0x1240), /* SDHI2_SDHI2I2 */
 		.flags	= IORESOURCE_IRQ,
 	},
 };
@@ -803,6 +1160,15 @@
 	},
 };
 
+static struct sh_mmcif_dma sh_mmcif_dma = {
+	.chan_priv_rx	= {
+		.slave_id	= SHDMA_SLAVE_MMCIF_RX,
+	},
+	.chan_priv_tx	= {
+		.slave_id	= SHDMA_SLAVE_MMCIF_TX,
+	},
+};
+
 static struct sh_mmcif_plat_data sh_mmcif_plat = {
 	.sup_pclk	= 0,
 	.ocr		= MMC_VDD_165_195 | MMC_VDD_32_33 | MMC_VDD_33_34,
@@ -810,6 +1176,7 @@
 			  MMC_CAP_8_BIT_DATA |
 			  MMC_CAP_NEEDS_POLL,
 	.get_cd		= slot_cn7_get_cd,
+	.dma		= &sh_mmcif_dma,
 };
 
 static struct platform_device sh_mmcif_device = {
@@ -858,37 +1225,23 @@
 	.priv		= &camera_info,
 };
 
-static void dummy_release(struct device *dev)
+static struct platform_device *camera_device;
+
+static void mackerel_camera_release(struct device *dev)
 {
+	soc_camera_platform_release(&camera_device);
 }
 
-static struct platform_device camera_device = {
-	.name		= "soc_camera_platform",
-	.dev		= {
-		.platform_data	= &camera_info,
-		.release	= dummy_release,
-	},
-};
-
 static int mackerel_camera_add(struct soc_camera_link *icl,
 			       struct device *dev)
 {
-	if (icl != &camera_link)
-		return -ENODEV;
-
-	camera_info.dev = dev;
-
-	return platform_device_register(&camera_device);
+	return soc_camera_platform_add(icl, dev, &camera_device, &camera_link,
+				       mackerel_camera_release, 0);
 }
 
 static void mackerel_camera_del(struct soc_camera_link *icl)
 {
-	if (icl != &camera_link)
-		return;
-
-	platform_device_unregister(&camera_device);
-	memset(&camera_device.dev.kobj, 0,
-	       sizeof(camera_device.dev.kobj));
+	soc_camera_platform_del(icl, camera_device, &camera_link);
 }
 
 static struct sh_mobile_ceu_info sh_mobile_ceu_info = {
@@ -935,12 +1288,14 @@
 	&smc911x_device,
 	&lcdc_device,
 	&usb1_host_device,
+	&usbhs1_device,
+	&usbhs0_device,
 	&leds_device,
 	&fsi_device,
 	&fsi_ak4643_device,
 	&fsi_hdmi_device,
 	&sdhi0_device,
-#if !defined(CONFIG_MMC_SH_MMCIF)
+#if !defined(CONFIG_MMC_SH_MMCIF) && !defined(CONFIG_MMC_SH_MMCIF_MODULE)
 	&sdhi1_device,
 #endif
 	&sdhi2_device,
@@ -949,6 +1304,7 @@
 	&mackerel_camera,
 	&hdmi_lcdc_device,
 	&hdmi_device,
+	&meram_device,
 };
 
 /* Keypad Initialization */
@@ -1030,12 +1386,15 @@
 
 #define GPIO_PORT9CR	0xE6051009
 #define GPIO_PORT10CR	0xE605100A
+#define GPIO_PORT167CR	0xE60520A7
+#define GPIO_PORT168CR	0xE60520A8
 #define SRCR4		0xe61580bc
 #define USCCR1		0xE6058144
 static void __init mackerel_init(void)
 {
 	u32 srcr4;
 	struct clk *clk;
+	int ret;
 
 	sh7372_pinmux_init();
 
@@ -1081,16 +1440,17 @@
 	gpio_request(GPIO_PORT151, NULL); /* LCDDON */
 	gpio_direction_output(GPIO_PORT151, 1);
 
-	/* USB enable */
-	gpio_request(GPIO_FN_VBUS0_1,    NULL);
-	gpio_request(GPIO_FN_IDIN_1_18,  NULL);
-	gpio_request(GPIO_FN_PWEN_1_115, NULL);
-	gpio_request(GPIO_FN_OVCN_1_114, NULL);
-	gpio_request(GPIO_FN_EXTLP_1,    NULL);
-	gpio_request(GPIO_FN_OVCN2_1,    NULL);
+	/* USBHS0 */
+	gpio_request(GPIO_FN_VBUS0_0, NULL);
+	gpio_pull_down(GPIO_PORT168CR); /* VBUS0_0 pull down */
 
-	/* setup USB phy */
-	__raw_writew(0x8a0a, 0xE6058130);	/* USBCR4 */
+	/* USBHS1 */
+	gpio_request(GPIO_FN_VBUS0_1, NULL);
+	gpio_pull_down(GPIO_PORT167CR); /* VBUS0_1 pull down */
+	gpio_request(GPIO_FN_IDIN_1_113, NULL);
+
+	/* USB phy tweak to make the r8a66597_hcd host driver work */
+	__raw_writew(0x8a0a, 0xe6058130);       /* USBCR4 */
 
 	/* enable FSI2 port A (ak4643) */
 	gpio_request(GPIO_FN_FSIAIBT,	NULL);
@@ -1140,7 +1500,14 @@
 	gpio_request(GPIO_FN_SDHID0_1, NULL);
 	gpio_request(GPIO_FN_SDHID0_0, NULL);
 
-#if !defined(CONFIG_MMC_SH_MMCIF)
+	ret = request_irq(evt2irq(0x3340), mackerel_sdhi0_gpio_cd,
+			  IRQF_TRIGGER_FALLING, "sdhi0 cd", &sdhi0_device.dev);
+	if (!ret)
+		sdhi0_info.tmio_flags |= TMIO_MMC_HAS_COLD_CD;
+	else
+		pr_err("Cannot get IRQ #%d: %d\n", evt2irq(0x3340), ret);
+
+#if !defined(CONFIG_MMC_SH_MMCIF) && !defined(CONFIG_MMC_SH_MMCIF_MODULE)
 	/* enable SDHI1 */
 	gpio_request(GPIO_FN_SDHICMD1, NULL);
 	gpio_request(GPIO_FN_SDHICLK1, NULL);
@@ -1216,6 +1583,7 @@
 	platform_add_devices(mackerel_devices, ARRAY_SIZE(mackerel_devices));
 
 	hdmi_init_pm_clock();
+	sh7372_pm_init();
 }
 
 static void __init mackerel_timer_init(void)
diff -druN linux-2.6.39-libre/arch/arm/mach-shmobile/clock-sh7372.c linux-3.0-rc7-libre/arch/arm/mach-shmobile/clock-sh7372.c
--- linux-2.6.39-libre/arch/arm/mach-shmobile/clock-sh7372.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-shmobile/clock-sh7372.c	2011-07-11 19:51:52.000000000 -0400
@@ -44,6 +44,11 @@
 #define DSI1PCKCR	0xe6150098
 #define PLLC01CR	0xe6150028
 #define PLLC2CR		0xe615002c
+#define RMSTPCR0	0xe6150110
+#define RMSTPCR1	0xe6150114
+#define RMSTPCR2	0xe6150118
+#define RMSTPCR3	0xe615011c
+#define RMSTPCR4	0xe6150120
 #define SMSTPCR0	0xe6150130
 #define SMSTPCR1	0xe6150134
 #define SMSTPCR2	0xe6150138
@@ -421,9 +426,6 @@
 
 	value = __raw_readl(clk->mapping->base);
 
-	if ((value & 0x3) != 0x3)
-		return 0;
-
 	value >>= 16;
 	if (value < 2)
 		return 0;
@@ -504,9 +506,10 @@
 enum { MSTP001,
        MSTP131, MSTP130,
        MSTP129, MSTP128, MSTP127, MSTP126, MSTP125,
-       MSTP118, MSTP117, MSTP116,
+       MSTP118, MSTP117, MSTP116, MSTP113,
        MSTP106, MSTP101, MSTP100,
        MSTP223,
+       MSTP218, MSTP217, MSTP216,
        MSTP207, MSTP206, MSTP204, MSTP203, MSTP202, MSTP201, MSTP200,
        MSTP329, MSTP328, MSTP323, MSTP322, MSTP314, MSTP313, MSTP312,
        MSTP423, MSTP415, MSTP413, MSTP411, MSTP410, MSTP406, MSTP403,
@@ -527,10 +530,14 @@
 	[MSTP118] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 18, 0), /* DSITX */
 	[MSTP117] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 17, 0), /* LCDC1 */
 	[MSTP116] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR1, 16, 0), /* IIC0 */
+	[MSTP113] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR1, 13, 0), /* MERAM */
 	[MSTP106] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 6, 0), /* JPU */
 	[MSTP101] = MSTP(&div4_clks[DIV4_M1], SMSTPCR1, 1, 0), /* VPU */
 	[MSTP100] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 0, 0), /* LCDC0 */
 	[MSTP223] = MSTP(&div6_clks[DIV6_SPU], SMSTPCR2, 23, 0), /* SPU2 */
+	[MSTP218] = MSTP(&div4_clks[DIV4_HP], SMSTPCR2, 18, 0), /* DMAC1 */
+	[MSTP217] = MSTP(&div4_clks[DIV4_HP], SMSTPCR2, 17, 0), /* DMAC2 */
+	[MSTP216] = MSTP(&div4_clks[DIV4_HP], SMSTPCR2, 16, 0), /* DMAC3 */
 	[MSTP207] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 7, 0), /* SCIFA5 */
 	[MSTP206] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 6, 0), /* SCIFB */
 	[MSTP204] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 4, 0), /* SCIFA0 */
@@ -617,11 +624,15 @@
 	CLKDEV_DEV_ID("sh-mipi-dsi.0", &mstp_clks[MSTP118]), /* DSITX0 */
 	CLKDEV_DEV_ID("sh_mobile_lcdc_fb.1", &mstp_clks[MSTP117]), /* LCDC1 */
 	CLKDEV_DEV_ID("i2c-sh_mobile.0", &mstp_clks[MSTP116]), /* IIC0 */
+	CLKDEV_DEV_ID("sh_mobile_meram.0", &mstp_clks[MSTP113]), /* MERAM */
 	CLKDEV_DEV_ID("uio_pdrv_genirq.5", &mstp_clks[MSTP106]), /* JPU */
 	CLKDEV_DEV_ID("uio_pdrv_genirq.0", &mstp_clks[MSTP101]), /* VPU */
 	CLKDEV_DEV_ID("sh_mobile_lcdc_fb.0", &mstp_clks[MSTP100]), /* LCDC0 */
 	CLKDEV_DEV_ID("uio_pdrv_genirq.6", &mstp_clks[MSTP223]), /* SPU2DSP0 */
 	CLKDEV_DEV_ID("uio_pdrv_genirq.7", &mstp_clks[MSTP223]), /* SPU2DSP1 */
+	CLKDEV_DEV_ID("sh-dma-engine.0", &mstp_clks[MSTP218]), /* DMAC1 */
+	CLKDEV_DEV_ID("sh-dma-engine.1", &mstp_clks[MSTP217]), /* DMAC2 */
+	CLKDEV_DEV_ID("sh-dma-engine.2", &mstp_clks[MSTP216]), /* DMAC3 */
 	CLKDEV_DEV_ID("sh-sci.5", &mstp_clks[MSTP207]), /* SCIFA5 */
 	CLKDEV_DEV_ID("sh-sci.6", &mstp_clks[MSTP206]), /* SCIFB */
 	CLKDEV_DEV_ID("sh-sci.0", &mstp_clks[MSTP204]), /* SCIFA0 */
@@ -634,6 +645,7 @@
 	CLKDEV_DEV_ID("i2c-sh_mobile.1", &mstp_clks[MSTP323]), /* IIC1 */
 	CLKDEV_DEV_ID("r8a66597_hcd.0", &mstp_clks[MSTP322]), /* USB0 */
 	CLKDEV_DEV_ID("r8a66597_udc.0", &mstp_clks[MSTP322]), /* USB0 */
+	CLKDEV_DEV_ID("renesas_usbhs.0", &mstp_clks[MSTP322]), /* USB0 */
 	CLKDEV_DEV_ID("sh_mobile_sdhi.0", &mstp_clks[MSTP314]), /* SDHI0 */
 	CLKDEV_DEV_ID("sh_mobile_sdhi.1", &mstp_clks[MSTP313]), /* SDHI1 */
 	CLKDEV_DEV_ID("sh_mmcif.0", &mstp_clks[MSTP312]), /* MMC */
@@ -644,6 +656,7 @@
 	CLKDEV_DEV_ID("i2c-sh_mobile.4", &mstp_clks[MSTP410]), /* IIC4 */
 	CLKDEV_DEV_ID("r8a66597_hcd.1", &mstp_clks[MSTP406]), /* USB1 */
 	CLKDEV_DEV_ID("r8a66597_udc.1", &mstp_clks[MSTP406]), /* USB1 */
+	CLKDEV_DEV_ID("renesas_usbhs.1", &mstp_clks[MSTP406]), /* USB1 */
 	CLKDEV_DEV_ID("sh_keysc.0", &mstp_clks[MSTP403]), /* KEYSC */
 
 	CLKDEV_ICK_ID("ick", "sh-mobile-hdmi", &div6_reparent_clks[DIV6_HDMI]),
@@ -655,6 +668,13 @@
 {
 	int k, ret = 0;
 
+	/* make sure MSTP bits on the RT/SH4AL-DSP side are off */
+	__raw_writel(0xe4ef8087, RMSTPCR0);
+	__raw_writel(0xffffffff, RMSTPCR1);
+	__raw_writel(0x37c7f7ff, RMSTPCR2);
+	__raw_writel(0xffffffff, RMSTPCR3);
+	__raw_writel(0xffe0fffd, RMSTPCR4);
+
 	for (k = 0; !ret && (k < ARRAY_SIZE(main_clks)); k++)
 		ret = clk_register(main_clks[k]);
 
diff -druN linux-2.6.39-libre/arch/arm/mach-shmobile/clock-sh73a0.c linux-3.0-rc7-libre/arch/arm/mach-shmobile/clock-sh73a0.c
--- linux-2.6.39-libre/arch/arm/mach-shmobile/clock-sh73a0.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-shmobile/clock-sh73a0.c	2011-07-11 19:51:52.000000000 -0400
@@ -266,7 +266,8 @@
 	MSTP129, MSTP128, MSTP127, MSTP126, MSTP125, MSTP118, MSTP116, MSTP100,
 	MSTP219,
 	MSTP207, MSTP206, MSTP204, MSTP203, MSTP202, MSTP201, MSTP200,
-	MSTP331, MSTP329, MSTP325, MSTP323, MSTP312,
+	MSTP331, MSTP329, MSTP325, MSTP323, MSTP318,
+	MSTP314, MSTP313, MSTP312, MSTP311,
 	MSTP411, MSTP410, MSTP403,
 	MSTP_NR };
 
@@ -295,7 +296,11 @@
 	[MSTP329] = MSTP(&r_clk, SMSTPCR3, 29, 0), /* CMT10 */
 	[MSTP325] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR3, 25, 0), /* IrDA */
 	[MSTP323] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 23, 0), /* IIC1 */
+	[MSTP318] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 18, 0), /* SY-DMAC */
+	[MSTP314] = MSTP(&div6_clks[DIV6_SDHI0], SMSTPCR3, 14, 0), /* SDHI0 */
+	[MSTP313] = MSTP(&div6_clks[DIV6_SDHI1], SMSTPCR3, 13, 0), /* SDHI1 */
 	[MSTP312] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 12, 0), /* MMCIF0 */
+	[MSTP311] = MSTP(&div6_clks[DIV6_SDHI2], SMSTPCR3, 11, 0), /* SDHI2 */
 	[MSTP411] = MSTP(&div4_clks[DIV4_HP], SMSTPCR4, 11, 0), /* IIC3 */
 	[MSTP410] = MSTP(&div4_clks[DIV4_HP], SMSTPCR4, 10, 0), /* IIC4 */
 	[MSTP403] = MSTP(&r_clk, SMSTPCR4, 3, 0), /* KEYSC */
@@ -313,6 +318,9 @@
 	CLKDEV_CON_ID("vck1_clk", &div6_clks[DIV6_VCK1]),
 	CLKDEV_CON_ID("vck2_clk", &div6_clks[DIV6_VCK2]),
 	CLKDEV_CON_ID("vck3_clk", &div6_clks[DIV6_VCK3]),
+	CLKDEV_CON_ID("sdhi0_clk", &div6_clks[DIV6_SDHI0]),
+	CLKDEV_CON_ID("sdhi1_clk", &div6_clks[DIV6_SDHI1]),
+	CLKDEV_CON_ID("sdhi2_clk", &div6_clks[DIV6_SDHI2]),
 	CLKDEV_ICK_ID("dsit_clk", "sh-mipi-dsi.0", &div6_clks[DIV6_DSIT]),
 	CLKDEV_ICK_ID("dsit_clk", "sh-mipi-dsi.1", &div6_clks[DIV6_DSIT]),
 	CLKDEV_ICK_ID("dsi0p_clk", "sh-mipi-dsi.0", &div6_clks[DIV6_DSI0P]),
@@ -341,7 +349,11 @@
 	CLKDEV_DEV_ID("sh_cmt.10", &mstp_clks[MSTP329]), /* CMT10 */
 	CLKDEV_DEV_ID("sh_irda.0", &mstp_clks[MSTP325]), /* IrDA */
 	CLKDEV_DEV_ID("i2c-sh_mobile.1", &mstp_clks[MSTP323]), /* I2C1 */
+	CLKDEV_DEV_ID("sh-dma-engine.0", &mstp_clks[MSTP318]), /* SY-DMAC */
+	CLKDEV_DEV_ID("sh_mobile_sdhi.0", &mstp_clks[MSTP314]), /* SDHI0 */
+	CLKDEV_DEV_ID("sh_mobile_sdhi.1", &mstp_clks[MSTP313]), /* SDHI1 */
 	CLKDEV_DEV_ID("sh_mmcif.0", &mstp_clks[MSTP312]), /* MMCIF0 */
+	CLKDEV_DEV_ID("sh_mobile_sdhi.2", &mstp_clks[MSTP311]), /* SDHI2 */
 	CLKDEV_DEV_ID("i2c-sh_mobile.3", &mstp_clks[MSTP411]), /* I2C3 */
 	CLKDEV_DEV_ID("i2c-sh_mobile.4", &mstp_clks[MSTP410]), /* I2C4 */
 	CLKDEV_DEV_ID("sh_keysc.0", &mstp_clks[MSTP403]), /* KEYSC */
@@ -351,6 +363,11 @@
 {
 	int k, ret = 0;
 
+	/* Set SDHI clocks to a known state */
+	__raw_writel(0x108, SD0CKCR);
+	__raw_writel(0x108, SD1CKCR);
+	__raw_writel(0x108, SD2CKCR);
+
 	/* detect main clock parent */
 	switch ((__raw_readl(CKSCR) >> 24) & 0x03) {
 	case 0:
diff -druN linux-2.6.39-libre/arch/arm/mach-shmobile/cpuidle.c linux-3.0-rc7-libre/arch/arm/mach-shmobile/cpuidle.c
--- linux-2.6.39-libre/arch/arm/mach-shmobile/cpuidle.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/arm/mach-shmobile/cpuidle.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,92 @@
+/*
+ * CPUIdle support code for SH-Mobile ARM
+ *
+ *  Copyright (C) 2011 Magnus Damm
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+
+#include <linux/pm.h>
+#include <linux/cpuidle.h>
+#include <linux/suspend.h>
+#include <linux/module.h>
+#include <linux/err.h>
+#include <asm/system.h>
+#include <asm/io.h>
+
+static void shmobile_enter_wfi(void)
+{
+	cpu_do_idle();
+}
+
+void (*shmobile_cpuidle_modes[CPUIDLE_STATE_MAX])(void) = {
+	shmobile_enter_wfi, /* regular sleep mode */
+};
+
+static int shmobile_cpuidle_enter(struct cpuidle_device *dev,
+				  struct cpuidle_state *state)
+{
+	ktime_t before, after;
+	int requested_state = state - &dev->states[0];
+
+	dev->last_state = &dev->states[requested_state];
+	before = ktime_get();
+
+	local_irq_disable();
+	local_fiq_disable();
+
+	shmobile_cpuidle_modes[requested_state]();
+
+	local_irq_enable();
+	local_fiq_enable();
+
+	after = ktime_get();
+	return ktime_to_ns(ktime_sub(after, before)) >> 10;
+}
+
+static struct cpuidle_device shmobile_cpuidle_dev;
+static struct cpuidle_driver shmobile_cpuidle_driver = {
+	.name =		"shmobile_cpuidle",
+	.owner =	THIS_MODULE,
+};
+
+void (*shmobile_cpuidle_setup)(struct cpuidle_device *dev);
+
+static int shmobile_cpuidle_init(void)
+{
+	struct cpuidle_device *dev = &shmobile_cpuidle_dev;
+	struct cpuidle_state *state;
+	int i;
+
+	cpuidle_register_driver(&shmobile_cpuidle_driver);
+
+	for (i = 0; i < CPUIDLE_STATE_MAX; i++) {
+		dev->states[i].name[0] = '\0';
+		dev->states[i].desc[0] = '\0';
+		dev->states[i].enter = shmobile_cpuidle_enter;
+	}
+
+	i = CPUIDLE_DRIVER_STATE_START;
+
+	state = &dev->states[i++];
+	snprintf(state->name, CPUIDLE_NAME_LEN, "C1");
+	strncpy(state->desc, "WFI", CPUIDLE_DESC_LEN);
+	state->exit_latency = 1;
+	state->target_residency = 1 * 2;
+	state->power_usage = 3;
+	state->flags = 0;
+	state->flags |= CPUIDLE_FLAG_TIME_VALID;
+
+	dev->safe_state = state;
+	dev->state_count = i;
+
+	if (shmobile_cpuidle_setup)
+		shmobile_cpuidle_setup(dev);
+
+	cpuidle_register_device(dev);
+
+	return 0;
+}
+late_initcall(shmobile_cpuidle_init);
diff -druN linux-2.6.39-libre/arch/arm/mach-shmobile/headsmp.S linux-3.0-rc7-libre/arch/arm/mach-shmobile/headsmp.S
--- linux-2.6.39-libre/arch/arm/mach-shmobile/headsmp.S	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-shmobile/headsmp.S	2011-07-11 19:51:52.000000000 -0400
@@ -24,4 +24,4 @@
 	.align  12
 ENTRY(shmobile_secondary_vector)
 	ldr     pc, 1f
-1:	.long   secondary_startup - PAGE_OFFSET + PHYS_OFFSET
+1:	.long   secondary_startup - PAGE_OFFSET + PLAT_PHYS_OFFSET
diff -druN linux-2.6.39-libre/arch/arm/mach-shmobile/include/mach/common.h linux-3.0-rc7-libre/arch/arm/mach-shmobile/include/mach/common.h
--- linux-2.6.39-libre/arch/arm/mach-shmobile/include/mach/common.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-shmobile/include/mach/common.h	2011-07-11 19:51:52.000000000 -0400
@@ -8,6 +8,10 @@
 extern int clk_init(void);
 extern void shmobile_handle_irq_intc(struct pt_regs *);
 extern void shmobile_handle_irq_gic(struct pt_regs *);
+extern struct platform_suspend_ops shmobile_suspend_ops;
+struct cpuidle_device;
+extern void (*shmobile_cpuidle_modes[])(void);
+extern void (*shmobile_cpuidle_setup)(struct cpuidle_device *dev);
 
 extern void sh7367_init_irq(void);
 extern void sh7367_add_early_devices(void);
@@ -30,6 +34,9 @@
 extern void sh7372_add_standard_devices(void);
 extern void sh7372_clock_init(void);
 extern void sh7372_pinmux_init(void);
+extern void sh7372_pm_init(void);
+extern void sh7372_cpu_suspend(void);
+extern void sh7372_cpu_resume(void);
 extern struct clk sh7372_extal1_clk;
 extern struct clk sh7372_extal2_clk;
 
diff -druN linux-2.6.39-libre/arch/arm/mach-shmobile/include/mach/head-ap4evb.txt linux-3.0-rc7-libre/arch/arm/mach-shmobile/include/mach/head-ap4evb.txt
--- linux-2.6.39-libre/arch/arm/mach-shmobile/include/mach/head-ap4evb.txt	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-shmobile/include/mach/head-ap4evb.txt	2011-07-11 19:51:52.000000000 -0400
@@ -87,8 +87,7 @@
 ED 0xFE400354, 0x01AD8002
 
 LIST "SCIF0 - Serial port for earlyprintk"
-EB 0xE6053098, 0x11
 EB 0xE6053098, 0xe1
 EW 0xE6C40000, 0x0000
 EB 0xE6C40004, 0x19
-EW 0xE6C40008, 0x3000
+EW 0xE6C40008, 0x0030
diff -druN linux-2.6.39-libre/arch/arm/mach-shmobile/include/mach/head-mackerel.txt linux-3.0-rc7-libre/arch/arm/mach-shmobile/include/mach/head-mackerel.txt
--- linux-2.6.39-libre/arch/arm/mach-shmobile/include/mach/head-mackerel.txt	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-shmobile/include/mach/head-mackerel.txt	2011-07-11 19:51:52.000000000 -0400
@@ -87,8 +87,7 @@
 ED 0xFE400354, 0x01AD8002
 
 LIST "SCIF0 - Serial port for earlyprintk"
-EB 0xE6053098, 0x11
 EB 0xE6053098, 0xe1
 EW 0xE6C40000, 0x0000
 EB 0xE6C40004, 0x19
-EW 0xE6C40008, 0x3000
+EW 0xE6C40008, 0x0030
diff -druN linux-2.6.39-libre/arch/arm/mach-shmobile/include/mach/sh7372.h linux-3.0-rc7-libre/arch/arm/mach-shmobile/include/mach/sh7372.h
--- linux-2.6.39-libre/arch/arm/mach-shmobile/include/mach/sh7372.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-shmobile/include/mach/sh7372.h	2011-07-11 19:51:52.000000000 -0400
@@ -435,6 +435,7 @@
 
 /* DMA slave IDs */
 enum {
+	SHDMA_SLAVE_INVALID,
 	SHDMA_SLAVE_SCIF0_TX,
 	SHDMA_SLAVE_SCIF0_RX,
 	SHDMA_SLAVE_SCIF1_TX,
diff -druN linux-2.6.39-libre/arch/arm/mach-shmobile/include/mach/sh73a0.h linux-3.0-rc7-libre/arch/arm/mach-shmobile/include/mach/sh73a0.h
--- linux-2.6.39-libre/arch/arm/mach-shmobile/include/mach/sh73a0.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-shmobile/include/mach/sh73a0.h	2011-07-11 19:51:52.000000000 -0400
@@ -463,5 +463,35 @@
 	GPIO_FN_FSIAIBT_PU,
 	GPIO_FN_FSIAISLD_PU,
 };
+/* DMA slave IDs */
+enum {
+	SHDMA_SLAVE_INVALID,
+	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_SCIF6_TX,
+	SHDMA_SLAVE_SCIF6_RX,
+	SHDMA_SLAVE_SCIF7_TX,
+	SHDMA_SLAVE_SCIF7_RX,
+	SHDMA_SLAVE_SCIF8_TX,
+	SHDMA_SLAVE_SCIF8_RX,
+	SHDMA_SLAVE_SDHI0_TX,
+	SHDMA_SLAVE_SDHI0_RX,
+	SHDMA_SLAVE_SDHI1_TX,
+	SHDMA_SLAVE_SDHI1_RX,
+	SHDMA_SLAVE_SDHI2_TX,
+	SHDMA_SLAVE_SDHI2_RX,
+	SHDMA_SLAVE_MMCIF_TX,
+	SHDMA_SLAVE_MMCIF_RX,
+};
 
 #endif /* __ASM_SH73A0_H__ */
diff -druN linux-2.6.39-libre/arch/arm/mach-shmobile/include/mach/smp.h linux-3.0-rc7-libre/arch/arm/mach-shmobile/include/mach/smp.h
--- linux-2.6.39-libre/arch/arm/mach-shmobile/include/mach/smp.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-shmobile/include/mach/smp.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,16 +0,0 @@
-#ifndef __MACH_SMP_H
-#define __MACH_SMP_H
-
-#include <asm/hardware/gic.h>
-
-/*
- * We use IRQ1 as the IPI
- */
-static inline void smp_cross_call(const struct cpumask *mask, int ipi)
-{
-#if defined(CONFIG_ARM_GIC)
-	gic_raise_softirq(mask, ipi);
-#endif
-}
-
-#endif
diff -druN linux-2.6.39-libre/arch/arm/mach-shmobile/intc-sh7372.c linux-3.0-rc7-libre/arch/arm/mach-shmobile/intc-sh7372.c
--- linux-2.6.39-libre/arch/arm/mach-shmobile/intc-sh7372.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-shmobile/intc-sh7372.c	2011-07-11 19:51:52.000000000 -0400
@@ -27,8 +27,6 @@
 
 enum {
 	UNUSED_INTCA = 0,
-	ENABLED,
-	DISABLED,
 
 	/* interrupt sources INTCA */
 	IRQ0A, IRQ1A, IRQ2A, IRQ3A, IRQ4A, IRQ5A, IRQ6A, IRQ7A,
@@ -49,14 +47,14 @@
 	MSIOF2, MSIOF1,
 	SCIFA4, SCIFA5, SCIFB,
 	FLCTL_FLSTEI, FLCTL_FLTENDI, FLCTL_FLTREQ0I, FLCTL_FLTREQ1I,
-	SDHI0,
-	SDHI1,
+	SDHI0_SDHI0I0, SDHI0_SDHI0I1, SDHI0_SDHI0I2, SDHI0_SDHI0I3,
+	SDHI1_SDHI1I0, SDHI1_SDHI1I1, SDHI1_SDHI1I2,
 	IRREM,
 	IRDA,
 	TPU0,
 	TTI20,
 	DDM,
-	SDHI2,
+	SDHI2_SDHI2I0, SDHI2_SDHI2I1, SDHI2_SDHI2I2, SDHI2_SDHI2I3,
 	RWDT0,
 	DMAC1_1_DEI0, DMAC1_1_DEI1, DMAC1_1_DEI2, DMAC1_1_DEI3,
 	DMAC1_2_DEI4, DMAC1_2_DEI5, DMAC1_2_DADERR,
@@ -84,7 +82,7 @@
 
 	/* interrupt groups INTCA */
 	DMAC1_1, DMAC1_2, DMAC2_1, DMAC2_2, DMAC3_1, DMAC3_2, SHWYSTAT,
-	AP_ARM1, AP_ARM2, SPU2, FLCTL, IIC1
+	AP_ARM1, AP_ARM2, SPU2, FLCTL, IIC1, SDHI0, SDHI1, SDHI2
 };
 
 static struct intc_vect intca_vectors[] __initdata = {
@@ -125,17 +123,17 @@
 	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(SDHI0_SDHI0I0, 0x0e00), INTC_VECT(SDHI0_SDHI0I1, 0x0e20),
+	INTC_VECT(SDHI0_SDHI0I2, 0x0e40), INTC_VECT(SDHI0_SDHI0I3, 0x0e60),
+	INTC_VECT(SDHI1_SDHI1I0, 0x0e80), INTC_VECT(SDHI1_SDHI1I1, 0x0ea0),
+	INTC_VECT(SDHI1_SDHI1I2, 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(SDHI2_SDHI2I0, 0x1200), INTC_VECT(SDHI2_SDHI2I1, 0x1220),
+	INTC_VECT(SDHI2_SDHI2I2, 0x1240), INTC_VECT(SDHI2_SDHI2I3, 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),
@@ -195,6 +193,12 @@
 	INTC_GROUP(FLCTL, FLCTL_FLSTEI, FLCTL_FLTENDI,
 		   FLCTL_FLTREQ0I, FLCTL_FLTREQ1I),
 	INTC_GROUP(IIC1, IIC1_ALI1, IIC1_TACKI1, IIC1_WAITI1, IIC1_DTEI1),
+	INTC_GROUP(SDHI0, SDHI0_SDHI0I0, SDHI0_SDHI0I1,
+		   SDHI0_SDHI0I2, SDHI0_SDHI0I3),
+	INTC_GROUP(SDHI1, SDHI1_SDHI1I0, SDHI1_SDHI1I1,
+		   SDHI1_SDHI1I2),
+	INTC_GROUP(SDHI2, SDHI2_SDHI2I0, SDHI2_SDHI2I1,
+		   SDHI2_SDHI2I2, SDHI2_SDHI2I3),
 	INTC_GROUP(SHWYSTAT, SHWYSTAT_RT, SHWYSTAT_HS, SHWYSTAT_COM),
 };
 
@@ -230,10 +234,10 @@
 	  { SCIFB, SCIFA5, SCIFA4, MSIOF1,
 	    0, 0, MSIOF2, 0 } },
 	{ 0xe694009c, 0xe69400dc, 8, /* IMR7A / IMCR7A */
-	  { DISABLED, ENABLED, ENABLED, ENABLED,
+	  { SDHI0_SDHI0I3, SDHI0_SDHI0I2, SDHI0_SDHI0I1, SDHI0_SDHI0I0,
 	    FLCTL_FLTREQ1I, FLCTL_FLTREQ0I, FLCTL_FLTENDI, FLCTL_FLSTEI } },
 	{ 0xe69400a0, 0xe69400e0, 8, /* IMR8A / IMCR8A */
-	  { 0, ENABLED, ENABLED, ENABLED,
+	  { 0, SDHI1_SDHI1I2, SDHI1_SDHI1I1, SDHI1_SDHI1I0,
 	    TTI20, USBHSDMAC0_USHDMI, 0, 0 } },
 	{ 0xe69400a4, 0xe69400e4, 8, /* IMR9A / IMCR9A */
 	  { CMT1_CMT13, CMT1_CMT12, CMT1_CMT11, CMT1_CMT10,
@@ -248,7 +252,7 @@
 	  { 0, 0, TPU0, 0,
 	    0, 0, 0, 0 } },
 	{ 0xe69400b4, 0xe69400f4, 8, /* IMR13A / IMCR13A */
-	  { DISABLED, DISABLED, ENABLED, ENABLED,
+	  { SDHI2_SDHI2I3, SDHI2_SDHI2I2, SDHI2_SDHI2I1, SDHI2_SDHI2I0,
 	    0, CMT3, 0, RWDT0 } },
 	{ 0xe6950080, 0xe69500c0, 8, /* IMR0A3 / IMCR0A3 */
 	  { SHWYSTAT_RT, SHWYSTAT_HS, SHWYSTAT_COM, 0,
@@ -354,14 +358,10 @@
 	  { 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),
-};
+static DECLARE_INTC_DESC_ACK(intca_desc, "sh7372-intca",
+			     intca_vectors, intca_groups,
+			     intca_mask_registers, intca_prio_registers,
+			     intca_sense_registers, intca_ack_registers);
 
 enum {
 	UNUSED_INTCS = 0,
diff -druN linux-2.6.39-libre/arch/arm/mach-shmobile/intc-sh73a0.c linux-3.0-rc7-libre/arch/arm/mach-shmobile/intc-sh73a0.c
--- linux-2.6.39-libre/arch/arm/mach-shmobile/intc-sh73a0.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-shmobile/intc-sh73a0.c	2011-07-11 19:51:52.000000000 -0400
@@ -250,6 +250,11 @@
 	return IRQ_HANDLED;
 }
 
+static int sh73a0_set_wake(struct irq_data *data, unsigned int on)
+{
+	return 0; /* always allow wakeup */
+}
+
 void __init sh73a0_init_irq(void)
 {
 	void __iomem *gic_dist_base = __io(0xf0001000);
@@ -257,6 +262,7 @@
 	void __iomem *intevtsa = ioremap_nocache(0xffd20100, PAGE_SIZE);
 
 	gic_init(0, 29, gic_dist_base, gic_cpu_base);
+	gic_arch_extn.irq_set_wake = sh73a0_set_wake;
 
 	register_intc_controller(&intcs_desc);
 
diff -druN linux-2.6.39-libre/arch/arm/mach-shmobile/Makefile linux-3.0-rc7-libre/arch/arm/mach-shmobile/Makefile
--- linux-2.6.39-libre/arch/arm/mach-shmobile/Makefile	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-shmobile/Makefile	2011-07-11 19:51:52.000000000 -0400
@@ -30,6 +30,11 @@
 obj-$(CONFIG_ARCH_SH7372)	+= entry-intc.o
 obj-$(CONFIG_ARCH_SH73A0)	+= entry-gic.o
 
+# PM objects
+obj-$(CONFIG_SUSPEND)		+= suspend.o
+obj-$(CONFIG_CPU_IDLE)		+= cpuidle.o
+obj-$(CONFIG_ARCH_SH7372)	+= pm-sh7372.o sleep-sh7372.o
+
 # Board objects
 obj-$(CONFIG_MACH_G3EVM)	+= board-g3evm.o
 obj-$(CONFIG_MACH_G4EVM)	+= board-g4evm.o
diff -druN linux-2.6.39-libre/arch/arm/mach-shmobile/platsmp.c linux-3.0-rc7-libre/arch/arm/mach-shmobile/platsmp.c
--- linux-2.6.39-libre/arch/arm/mach-shmobile/platsmp.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-shmobile/platsmp.c	2011-07-11 19:51:52.000000000 -0400
@@ -16,6 +16,7 @@
 #include <linux/device.h>
 #include <linux/smp.h>
 #include <linux/io.h>
+#include <asm/hardware/gic.h>
 #include <asm/localtimer.h>
 #include <asm/mach-types.h>
 #include <mach/common.h>
@@ -57,6 +58,8 @@
 
 	for (i = 0; i < ncores; i++)
 		set_cpu_possible(i, true);
+
+	set_smp_cross_call(gic_raise_softirq);
 }
 
 void __init platform_smp_prepare_cpus(unsigned int max_cpus)
diff -druN linux-2.6.39-libre/arch/arm/mach-shmobile/pm_runtime.c linux-3.0-rc7-libre/arch/arm/mach-shmobile/pm_runtime.c
--- linux-2.6.39-libre/arch/arm/mach-shmobile/pm_runtime.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-shmobile/pm_runtime.c	2011-07-11 19:51:52.000000000 -0400
@@ -18,152 +18,41 @@
 #include <linux/clk.h>
 #include <linux/sh_clk.h>
 #include <linux/bitmap.h>
+#include <linux/slab.h>
 
 #ifdef CONFIG_PM_RUNTIME
-#define BIT_ONCE 0
-#define BIT_ACTIVE 1
-#define BIT_CLK_ENABLED 2
-
-struct pm_runtime_data {
-	unsigned long flags;
-	struct clk *clk;
-};
 
-static void __devres_release(struct device *dev, void *res)
-{
-	struct pm_runtime_data *prd = res;
-
-	dev_dbg(dev, "__devres_release()\n");
-
-	if (test_bit(BIT_CLK_ENABLED, &prd->flags))
-		clk_disable(prd->clk);
-
-	if (test_bit(BIT_ACTIVE, &prd->flags))
-		clk_put(prd->clk);
-}
-
-static struct pm_runtime_data *__to_prd(struct device *dev)
-{
-	return devres_find(dev, __devres_release, NULL, NULL);
-}
-
-static void platform_pm_runtime_init(struct device *dev,
-				     struct pm_runtime_data *prd)
-{
-	if (prd && !test_and_set_bit(BIT_ONCE, &prd->flags)) {
-		prd->clk = clk_get(dev, NULL);
-		if (!IS_ERR(prd->clk)) {
-			set_bit(BIT_ACTIVE, &prd->flags);
-			dev_info(dev, "clocks managed by runtime pm\n");
-		}
-	}
-}
-
-static void platform_pm_runtime_bug(struct device *dev,
-				    struct pm_runtime_data *prd)
-{
-	if (prd && !test_and_set_bit(BIT_ONCE, &prd->flags))
-		dev_err(dev, "runtime pm suspend before resume\n");
-}
-
-int platform_pm_runtime_suspend(struct device *dev)
-{
-	struct pm_runtime_data *prd = __to_prd(dev);
-
-	dev_dbg(dev, "platform_pm_runtime_suspend()\n");
-
-	platform_pm_runtime_bug(dev, prd);
-
-	if (prd && test_bit(BIT_ACTIVE, &prd->flags)) {
-		clk_disable(prd->clk);
-		clear_bit(BIT_CLK_ENABLED, &prd->flags);
-	}
-
-	return 0;
-}
-
-int platform_pm_runtime_resume(struct device *dev)
-{
-	struct pm_runtime_data *prd = __to_prd(dev);
-
-	dev_dbg(dev, "platform_pm_runtime_resume()\n");
-
-	platform_pm_runtime_init(dev, prd);
-
-	if (prd && test_bit(BIT_ACTIVE, &prd->flags)) {
-		clk_enable(prd->clk);
-		set_bit(BIT_CLK_ENABLED, &prd->flags);
-	}
-
-	return 0;
-}
-
-int platform_pm_runtime_idle(struct device *dev)
+static int default_platform_runtime_idle(struct device *dev)
 {
 	/* suspend synchronously to disable clocks immediately */
 	return pm_runtime_suspend(dev);
 }
 
-static int platform_bus_notify(struct notifier_block *nb,
-			       unsigned long action, void *data)
-{
-	struct device *dev = data;
-	struct pm_runtime_data *prd;
-
-	dev_dbg(dev, "platform_bus_notify() %ld !\n", action);
-
-	if (action == BUS_NOTIFY_BIND_DRIVER) {
-		prd = devres_alloc(__devres_release, sizeof(*prd), GFP_KERNEL);
-		if (prd)
-			devres_add(dev, prd);
-		else
-			dev_err(dev, "unable to alloc memory for runtime pm\n");
-	}
-
-	return 0;
-}
-
-#else /* CONFIG_PM_RUNTIME */
-
-static int platform_bus_notify(struct notifier_block *nb,
-			       unsigned long action, void *data)
-{
-	struct device *dev = data;
-	struct clk *clk;
+static struct dev_power_domain default_power_domain = {
+	.ops = {
+		.runtime_suspend = pm_runtime_clk_suspend,
+		.runtime_resume = pm_runtime_clk_resume,
+		.runtime_idle = default_platform_runtime_idle,
+		USE_PLATFORM_PM_SLEEP_OPS
+	},
+};
 
-	dev_dbg(dev, "platform_bus_notify() %ld !\n", action);
+#define DEFAULT_PWR_DOMAIN_PTR	(&default_power_domain)
 
-	switch (action) {
-	case BUS_NOTIFY_BIND_DRIVER:
-		clk = clk_get(dev, NULL);
-		if (!IS_ERR(clk)) {
-			clk_enable(clk);
-			clk_put(clk);
-			dev_info(dev, "runtime pm disabled, clock forced on\n");
-		}
-		break;
-	case BUS_NOTIFY_UNBOUND_DRIVER:
-		clk = clk_get(dev, NULL);
-		if (!IS_ERR(clk)) {
-			clk_disable(clk);
-			clk_put(clk);
-			dev_info(dev, "runtime pm disabled, clock forced off\n");
-		}
-		break;
-	}
+#else
 
-	return 0;
-}
+#define DEFAULT_PWR_DOMAIN_PTR	NULL
 
 #endif /* CONFIG_PM_RUNTIME */
 
-static struct notifier_block platform_bus_notifier = {
-	.notifier_call = platform_bus_notify
+static struct pm_clk_notifier_block platform_bus_notifier = {
+	.pwr_domain = DEFAULT_PWR_DOMAIN_PTR,
+	.con_ids = { NULL, },
 };
 
 static int __init sh_pm_runtime_init(void)
 {
-	bus_register_notifier(&platform_bus_type, &platform_bus_notifier);
+	pm_runtime_clk_add_notifier(&platform_bus_type, &platform_bus_notifier);
 	return 0;
 }
 core_initcall(sh_pm_runtime_init);
diff -druN linux-2.6.39-libre/arch/arm/mach-shmobile/pm-sh7372.c linux-3.0-rc7-libre/arch/arm/mach-shmobile/pm-sh7372.c
--- linux-2.6.39-libre/arch/arm/mach-shmobile/pm-sh7372.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/arm/mach-shmobile/pm-sh7372.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,108 @@
+/*
+ * sh7372 Power management support
+ *
+ *  Copyright (C) 2011 Magnus Damm
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+
+#include <linux/pm.h>
+#include <linux/suspend.h>
+#include <linux/cpuidle.h>
+#include <linux/module.h>
+#include <linux/list.h>
+#include <linux/err.h>
+#include <linux/slab.h>
+#include <asm/system.h>
+#include <asm/io.h>
+#include <asm/tlbflush.h>
+#include <mach/common.h>
+
+#define SMFRAM 0xe6a70000
+#define SYSTBCR 0xe6150024
+#define SBAR 0xe6180020
+#define APARMBAREA 0xe6f10020
+
+static void sh7372_enter_core_standby(void)
+{
+	void __iomem *smfram = (void __iomem *)SMFRAM;
+
+	__raw_writel(0, APARMBAREA); /* translate 4k */
+	__raw_writel(__pa(sh7372_cpu_resume), SBAR); /* set reset vector */
+	__raw_writel(0x10, SYSTBCR); /* enable core standby */
+
+	__raw_writel(0, smfram + 0x3c); /* clear page table address */
+
+	sh7372_cpu_suspend();
+	cpu_init();
+
+	/* if page table address is non-NULL then we have been powered down */
+	if (__raw_readl(smfram + 0x3c)) {
+		__raw_writel(__raw_readl(smfram + 0x40),
+			     __va(__raw_readl(smfram + 0x3c)));
+
+		flush_tlb_all();
+		set_cr(__raw_readl(smfram + 0x38));
+	}
+
+	__raw_writel(0, SYSTBCR); /* disable core standby */
+	__raw_writel(0, SBAR); /* disable reset vector translation */
+}
+
+#ifdef CONFIG_CPU_IDLE
+static void sh7372_cpuidle_setup(struct cpuidle_device *dev)
+{
+	struct cpuidle_state *state;
+	int i = dev->state_count;
+
+	state = &dev->states[i];
+	snprintf(state->name, CPUIDLE_NAME_LEN, "C2");
+	strncpy(state->desc, "Core Standby Mode", CPUIDLE_DESC_LEN);
+	state->exit_latency = 10;
+	state->target_residency = 20 + 10;
+	state->power_usage = 1; /* perhaps not */
+	state->flags = 0;
+	state->flags |= CPUIDLE_FLAG_TIME_VALID;
+	shmobile_cpuidle_modes[i] = sh7372_enter_core_standby;
+
+	dev->state_count = i + 1;
+}
+
+static void sh7372_cpuidle_init(void)
+{
+	shmobile_cpuidle_setup = sh7372_cpuidle_setup;
+}
+#else
+static void sh7372_cpuidle_init(void) {}
+#endif
+
+#ifdef CONFIG_SUSPEND
+static int sh7372_enter_suspend(suspend_state_t suspend_state)
+{
+	sh7372_enter_core_standby();
+	return 0;
+}
+
+static void sh7372_suspend_init(void)
+{
+	shmobile_suspend_ops.enter = sh7372_enter_suspend;
+}
+#else
+static void sh7372_suspend_init(void) {}
+#endif
+
+#define DBGREG1 0xe6100020
+#define DBGREG9 0xe6100040
+
+void __init sh7372_pm_init(void)
+{
+	/* enable DBG hardware block to kick SYSC */
+	__raw_writel(0x0000a500, DBGREG9);
+	__raw_writel(0x0000a501, DBGREG9);
+	__raw_writel(0x00000000, DBGREG1);
+
+	sh7372_suspend_init();
+	sh7372_cpuidle_init();
+}
diff -druN linux-2.6.39-libre/arch/arm/mach-shmobile/setup-sh7367.c linux-3.0-rc7-libre/arch/arm/mach-shmobile/setup-sh7367.c
--- linux-2.6.39-libre/arch/arm/mach-shmobile/setup-sh7367.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-shmobile/setup-sh7367.c	2011-07-11 19:51:52.000000000 -0400
@@ -22,6 +22,7 @@
 #include <linux/interrupt.h>
 #include <linux/irq.h>
 #include <linux/platform_device.h>
+#include <linux/uio_driver.h>
 #include <linux/delay.h>
 #include <linux/input.h>
 #include <linux/io.h>
@@ -37,7 +38,7 @@
 	.flags		= UPF_BOOT_AUTOCONF,
 	.scscr		= SCSCR_RE | SCSCR_TE,
 	.scbrr_algo_id	= SCBRR_ALGO_4,
-	.type		= PORT_SCIF,
+	.type		= PORT_SCIFA,
 	.irqs		= { evt2irq(0xc00), evt2irq(0xc00),
 			    evt2irq(0xc00), evt2irq(0xc00) },
 };
@@ -56,7 +57,7 @@
 	.flags		= UPF_BOOT_AUTOCONF,
 	.scscr		= SCSCR_RE | SCSCR_TE,
 	.scbrr_algo_id	= SCBRR_ALGO_4,
-	.type		= PORT_SCIF,
+	.type		= PORT_SCIFA,
 	.irqs		= { evt2irq(0xc20), evt2irq(0xc20),
 			    evt2irq(0xc20), evt2irq(0xc20) },
 };
@@ -75,7 +76,7 @@
 	.flags		= UPF_BOOT_AUTOCONF,
 	.scscr		= SCSCR_RE | SCSCR_TE,
 	.scbrr_algo_id	= SCBRR_ALGO_4,
-	.type		= PORT_SCIF,
+	.type		= PORT_SCIFA,
 	.irqs		= { evt2irq(0xc40), evt2irq(0xc40),
 			    evt2irq(0xc40), evt2irq(0xc40) },
 };
@@ -94,7 +95,7 @@
 	.flags		= UPF_BOOT_AUTOCONF,
 	.scscr		= SCSCR_RE | SCSCR_TE,
 	.scbrr_algo_id	= SCBRR_ALGO_4,
-	.type		= PORT_SCIF,
+	.type		= PORT_SCIFA,
 	.irqs		= { evt2irq(0xc60), evt2irq(0xc60),
 			    evt2irq(0xc60), evt2irq(0xc60) },
 };
@@ -113,7 +114,7 @@
 	.flags		= UPF_BOOT_AUTOCONF,
 	.scscr		= SCSCR_RE | SCSCR_TE,
 	.scbrr_algo_id	= SCBRR_ALGO_4,
-	.type		= PORT_SCIF,
+	.type		= PORT_SCIFA,
 	.irqs		= { evt2irq(0xd20), evt2irq(0xd20),
 			    evt2irq(0xd20), evt2irq(0xd20) },
 };
@@ -132,7 +133,7 @@
 	.flags		= UPF_BOOT_AUTOCONF,
 	.scscr		= SCSCR_RE | SCSCR_TE,
 	.scbrr_algo_id	= SCBRR_ALGO_4,
-	.type		= PORT_SCIF,
+	.type		= PORT_SCIFA,
 	.irqs		= { evt2irq(0xd40), evt2irq(0xd40),
 			    evt2irq(0xd40), evt2irq(0xd40) },
 };
@@ -151,7 +152,7 @@
 	.flags		= UPF_BOOT_AUTOCONF,
 	.scscr		= SCSCR_RE | SCSCR_TE,
 	.scbrr_algo_id	= SCBRR_ALGO_4,
-	.type		= PORT_SCIF,
+	.type		= PORT_SCIFB,
 	.irqs		= { evt2irq(0xd60), evt2irq(0xd60),
 			    evt2irq(0xd60), evt2irq(0xd60) },
 };
@@ -195,6 +196,214 @@
 	.num_resources	= ARRAY_SIZE(cmt10_resources),
 };
 
+/* VPU */
+static struct uio_info vpu_platform_data = {
+	.name = "VPU5",
+	.version = "0",
+	.irq = intcs_evt2irq(0x980),
+};
+
+static struct resource vpu_resources[] = {
+	[0] = {
+		.name	= "VPU",
+		.start	= 0xfe900000,
+		.end	= 0xfe902807,
+		.flags	= IORESOURCE_MEM,
+	},
+};
+
+static struct platform_device vpu_device = {
+	.name		= "uio_pdrv_genirq",
+	.id		= 0,
+	.dev = {
+		.platform_data	= &vpu_platform_data,
+	},
+	.resource	= vpu_resources,
+	.num_resources	= ARRAY_SIZE(vpu_resources),
+};
+
+/* VEU0 */
+static struct uio_info veu0_platform_data = {
+	.name = "VEU0",
+	.version = "0",
+	.irq = intcs_evt2irq(0x700),
+};
+
+static struct resource veu0_resources[] = {
+	[0] = {
+		.name	= "VEU0",
+		.start	= 0xfe920000,
+		.end	= 0xfe9200b7,
+		.flags	= IORESOURCE_MEM,
+	},
+};
+
+static struct platform_device veu0_device = {
+	.name		= "uio_pdrv_genirq",
+	.id		= 1,
+	.dev = {
+		.platform_data	= &veu0_platform_data,
+	},
+	.resource	= veu0_resources,
+	.num_resources	= ARRAY_SIZE(veu0_resources),
+};
+
+/* VEU1 */
+static struct uio_info veu1_platform_data = {
+	.name = "VEU1",
+	.version = "0",
+	.irq = intcs_evt2irq(0x720),
+};
+
+static struct resource veu1_resources[] = {
+	[0] = {
+		.name	= "VEU1",
+		.start	= 0xfe924000,
+		.end	= 0xfe9240b7,
+		.flags	= IORESOURCE_MEM,
+	},
+};
+
+static struct platform_device veu1_device = {
+	.name		= "uio_pdrv_genirq",
+	.id		= 2,
+	.dev = {
+		.platform_data	= &veu1_platform_data,
+	},
+	.resource	= veu1_resources,
+	.num_resources	= ARRAY_SIZE(veu1_resources),
+};
+
+/* VEU2 */
+static struct uio_info veu2_platform_data = {
+	.name = "VEU2",
+	.version = "0",
+	.irq = intcs_evt2irq(0x740),
+};
+
+static struct resource veu2_resources[] = {
+	[0] = {
+		.name	= "VEU2",
+		.start	= 0xfe928000,
+		.end	= 0xfe9280b7,
+		.flags	= IORESOURCE_MEM,
+	},
+};
+
+static struct platform_device veu2_device = {
+	.name		= "uio_pdrv_genirq",
+	.id		= 3,
+	.dev = {
+		.platform_data	= &veu2_platform_data,
+	},
+	.resource	= veu2_resources,
+	.num_resources	= ARRAY_SIZE(veu2_resources),
+};
+
+/* VEU3 */
+static struct uio_info veu3_platform_data = {
+	.name = "VEU3",
+	.version = "0",
+	.irq = intcs_evt2irq(0x760),
+};
+
+static struct resource veu3_resources[] = {
+	[0] = {
+		.name	= "VEU3",
+		.start	= 0xfe92c000,
+		.end	= 0xfe92c0b7,
+		.flags	= IORESOURCE_MEM,
+	},
+};
+
+static struct platform_device veu3_device = {
+	.name		= "uio_pdrv_genirq",
+	.id		= 4,
+	.dev = {
+		.platform_data	= &veu3_platform_data,
+	},
+	.resource	= veu3_resources,
+	.num_resources	= ARRAY_SIZE(veu3_resources),
+};
+
+/* VEU2H */
+static struct uio_info veu2h_platform_data = {
+	.name = "VEU2H",
+	.version = "0",
+	.irq = intcs_evt2irq(0x520),
+};
+
+static struct resource veu2h_resources[] = {
+	[0] = {
+		.name	= "VEU2H",
+		.start	= 0xfe93c000,
+		.end	= 0xfe93c27b,
+		.flags	= IORESOURCE_MEM,
+	},
+};
+
+static struct platform_device veu2h_device = {
+	.name		= "uio_pdrv_genirq",
+	.id		= 5,
+	.dev = {
+		.platform_data	= &veu2h_platform_data,
+	},
+	.resource	= veu2h_resources,
+	.num_resources	= ARRAY_SIZE(veu2h_resources),
+};
+
+/* JPU */
+static struct uio_info jpu_platform_data = {
+	.name = "JPU",
+	.version = "0",
+	.irq = intcs_evt2irq(0x560),
+};
+
+static struct resource jpu_resources[] = {
+	[0] = {
+		.name	= "JPU",
+		.start	= 0xfe980000,
+		.end	= 0xfe9902d3,
+		.flags	= IORESOURCE_MEM,
+	},
+};
+
+static struct platform_device jpu_device = {
+	.name		= "uio_pdrv_genirq",
+	.id		= 6,
+	.dev = {
+		.platform_data	= &jpu_platform_data,
+	},
+	.resource	= jpu_resources,
+	.num_resources	= ARRAY_SIZE(jpu_resources),
+};
+
+/* SPU1 */
+static struct uio_info spu1_platform_data = {
+	.name = "SPU1",
+	.version = "0",
+	.irq = evt2irq(0xfc0),
+};
+
+static struct resource spu1_resources[] = {
+	[0] = {
+		.name	= "SPU1",
+		.start	= 0xfe300000,
+		.end	= 0xfe3fffff,
+		.flags	= IORESOURCE_MEM,
+	},
+};
+
+static struct platform_device spu1_device = {
+	.name		= "uio_pdrv_genirq",
+	.id		= 7,
+	.dev = {
+		.platform_data	= &spu1_platform_data,
+	},
+	.resource	= spu1_resources,
+	.num_resources	= ARRAY_SIZE(spu1_resources),
+};
+
 static struct platform_device *sh7367_early_devices[] __initdata = {
 	&scif0_device,
 	&scif1_device,
@@ -206,10 +415,24 @@
 	&cmt10_device,
 };
 
+static struct platform_device *sh7367_devices[] __initdata = {
+	&vpu_device,
+	&veu0_device,
+	&veu1_device,
+	&veu2_device,
+	&veu3_device,
+	&veu2h_device,
+	&jpu_device,
+	&spu1_device,
+};
+
 void __init sh7367_add_standard_devices(void)
 {
 	platform_add_devices(sh7367_early_devices,
 			     ARRAY_SIZE(sh7367_early_devices));
+
+	platform_add_devices(sh7367_devices,
+			    ARRAY_SIZE(sh7367_devices));
 }
 
 #define SYMSTPCR2 0xe6158048
diff -druN linux-2.6.39-libre/arch/arm/mach-shmobile/setup-sh7372.c linux-3.0-rc7-libre/arch/arm/mach-shmobile/setup-sh7372.c
--- linux-2.6.39-libre/arch/arm/mach-shmobile/setup-sh7372.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-shmobile/setup-sh7372.c	2011-07-11 19:51:52.000000000 -0400
@@ -22,6 +22,7 @@
 #include <linux/interrupt.h>
 #include <linux/irq.h>
 #include <linux/platform_device.h>
+#include <linux/uio_driver.h>
 #include <linux/delay.h>
 #include <linux/input.h>
 #include <linux/io.h>
@@ -601,6 +602,214 @@
 	},
 };
 
+/* VPU */
+static struct uio_info vpu_platform_data = {
+	.name = "VPU5HG",
+	.version = "0",
+	.irq = intcs_evt2irq(0x980),
+};
+
+static struct resource vpu_resources[] = {
+	[0] = {
+		.name	= "VPU",
+		.start	= 0xfe900000,
+		.end	= 0xfe900157,
+		.flags	= IORESOURCE_MEM,
+	},
+};
+
+static struct platform_device vpu_device = {
+	.name		= "uio_pdrv_genirq",
+	.id		= 0,
+	.dev = {
+		.platform_data	= &vpu_platform_data,
+	},
+	.resource	= vpu_resources,
+	.num_resources	= ARRAY_SIZE(vpu_resources),
+};
+
+/* VEU0 */
+static struct uio_info veu0_platform_data = {
+	.name = "VEU0",
+	.version = "0",
+	.irq = intcs_evt2irq(0x700),
+};
+
+static struct resource veu0_resources[] = {
+	[0] = {
+		.name	= "VEU0",
+		.start	= 0xfe920000,
+		.end	= 0xfe9200cb,
+		.flags	= IORESOURCE_MEM,
+	},
+};
+
+static struct platform_device veu0_device = {
+	.name		= "uio_pdrv_genirq",
+	.id		= 1,
+	.dev = {
+		.platform_data	= &veu0_platform_data,
+	},
+	.resource	= veu0_resources,
+	.num_resources	= ARRAY_SIZE(veu0_resources),
+};
+
+/* VEU1 */
+static struct uio_info veu1_platform_data = {
+	.name = "VEU1",
+	.version = "0",
+	.irq = intcs_evt2irq(0x720),
+};
+
+static struct resource veu1_resources[] = {
+	[0] = {
+		.name	= "VEU1",
+		.start	= 0xfe924000,
+		.end	= 0xfe9240cb,
+		.flags	= IORESOURCE_MEM,
+	},
+};
+
+static struct platform_device veu1_device = {
+	.name		= "uio_pdrv_genirq",
+	.id		= 2,
+	.dev = {
+		.platform_data	= &veu1_platform_data,
+	},
+	.resource	= veu1_resources,
+	.num_resources	= ARRAY_SIZE(veu1_resources),
+};
+
+/* VEU2 */
+static struct uio_info veu2_platform_data = {
+	.name = "VEU2",
+	.version = "0",
+	.irq = intcs_evt2irq(0x740),
+};
+
+static struct resource veu2_resources[] = {
+	[0] = {
+		.name	= "VEU2",
+		.start	= 0xfe928000,
+		.end	= 0xfe928307,
+		.flags	= IORESOURCE_MEM,
+	},
+};
+
+static struct platform_device veu2_device = {
+	.name		= "uio_pdrv_genirq",
+	.id		= 3,
+	.dev = {
+		.platform_data	= &veu2_platform_data,
+	},
+	.resource	= veu2_resources,
+	.num_resources	= ARRAY_SIZE(veu2_resources),
+};
+
+/* VEU3 */
+static struct uio_info veu3_platform_data = {
+	.name = "VEU3",
+	.version = "0",
+	.irq = intcs_evt2irq(0x760),
+};
+
+static struct resource veu3_resources[] = {
+	[0] = {
+		.name	= "VEU3",
+		.start	= 0xfe92c000,
+		.end	= 0xfe92c307,
+		.flags	= IORESOURCE_MEM,
+	},
+};
+
+static struct platform_device veu3_device = {
+	.name		= "uio_pdrv_genirq",
+	.id		= 4,
+	.dev = {
+		.platform_data	= &veu3_platform_data,
+	},
+	.resource	= veu3_resources,
+	.num_resources	= ARRAY_SIZE(veu3_resources),
+};
+
+/* JPU */
+static struct uio_info jpu_platform_data = {
+	.name = "JPU",
+	.version = "0",
+	.irq = intcs_evt2irq(0x560),
+};
+
+static struct resource jpu_resources[] = {
+	[0] = {
+		.name	= "JPU",
+		.start	= 0xfe980000,
+		.end	= 0xfe9902d3,
+		.flags	= IORESOURCE_MEM,
+	},
+};
+
+static struct platform_device jpu_device = {
+	.name		= "uio_pdrv_genirq",
+	.id		= 5,
+	.dev = {
+		.platform_data	= &jpu_platform_data,
+	},
+	.resource	= jpu_resources,
+	.num_resources	= ARRAY_SIZE(jpu_resources),
+};
+
+/* SPU2DSP0 */
+static struct uio_info spu0_platform_data = {
+	.name = "SPU2DSP0",
+	.version = "0",
+	.irq = evt2irq(0x1800),
+};
+
+static struct resource spu0_resources[] = {
+	[0] = {
+		.name	= "SPU2DSP0",
+		.start	= 0xfe200000,
+		.end	= 0xfe2fffff,
+		.flags	= IORESOURCE_MEM,
+	},
+};
+
+static struct platform_device spu0_device = {
+	.name		= "uio_pdrv_genirq",
+	.id		= 6,
+	.dev = {
+		.platform_data	= &spu0_platform_data,
+	},
+	.resource	= spu0_resources,
+	.num_resources	= ARRAY_SIZE(spu0_resources),
+};
+
+/* SPU2DSP1 */
+static struct uio_info spu1_platform_data = {
+	.name = "SPU2DSP1",
+	.version = "0",
+	.irq = evt2irq(0x1820),
+};
+
+static struct resource spu1_resources[] = {
+	[0] = {
+		.name	= "SPU2DSP1",
+		.start	= 0xfe300000,
+		.end	= 0xfe3fffff,
+		.flags	= IORESOURCE_MEM,
+	},
+};
+
+static struct platform_device spu1_device = {
+	.name		= "uio_pdrv_genirq",
+	.id		= 7,
+	.dev = {
+		.platform_data	= &spu1_platform_data,
+	},
+	.resource	= spu1_resources,
+	.num_resources	= ARRAY_SIZE(spu1_resources),
+};
+
 static struct platform_device *sh7372_early_devices[] __initdata = {
 	&scif0_device,
 	&scif1_device,
@@ -620,6 +829,14 @@
 	&dma0_device,
 	&dma1_device,
 	&dma2_device,
+	&vpu_device,
+	&veu0_device,
+	&veu1_device,
+	&veu2_device,
+	&veu3_device,
+	&jpu_device,
+	&spu0_device,
+	&spu1_device,
 };
 
 void __init sh7372_add_standard_devices(void)
diff -druN linux-2.6.39-libre/arch/arm/mach-shmobile/setup-sh7377.c linux-3.0-rc7-libre/arch/arm/mach-shmobile/setup-sh7377.c
--- linux-2.6.39-libre/arch/arm/mach-shmobile/setup-sh7377.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-shmobile/setup-sh7377.c	2011-07-11 19:51:52.000000000 -0400
@@ -22,6 +22,7 @@
 #include <linux/interrupt.h>
 #include <linux/irq.h>
 #include <linux/platform_device.h>
+#include <linux/uio_driver.h>
 #include <linux/delay.h>
 #include <linux/input.h>
 #include <linux/io.h>
@@ -38,7 +39,7 @@
 	.flags		= UPF_BOOT_AUTOCONF,
 	.scscr		= SCSCR_RE | SCSCR_TE,
 	.scbrr_algo_id	= SCBRR_ALGO_4,
-	.type		= PORT_SCIF,
+	.type		= PORT_SCIFA,
 	.irqs		= { evt2irq(0xc00), evt2irq(0xc00),
 			    evt2irq(0xc00), evt2irq(0xc00) },
 };
@@ -57,7 +58,7 @@
 	.flags		= UPF_BOOT_AUTOCONF,
 	.scscr		= SCSCR_RE | SCSCR_TE,
 	.scbrr_algo_id	= SCBRR_ALGO_4,
-	.type		= PORT_SCIF,
+	.type		= PORT_SCIFA,
 	.irqs		= { evt2irq(0xc20), evt2irq(0xc20),
 			    evt2irq(0xc20), evt2irq(0xc20) },
 };
@@ -76,7 +77,7 @@
 	.flags		= UPF_BOOT_AUTOCONF,
 	.scscr		= SCSCR_RE | SCSCR_TE,
 	.scbrr_algo_id	= SCBRR_ALGO_4,
-	.type		= PORT_SCIF,
+	.type		= PORT_SCIFA,
 	.irqs		= { evt2irq(0xc40), evt2irq(0xc40),
 			    evt2irq(0xc40), evt2irq(0xc40) },
 };
@@ -95,7 +96,7 @@
 	.flags		= UPF_BOOT_AUTOCONF,
 	.scscr		= SCSCR_RE | SCSCR_TE,
 	.scbrr_algo_id	= SCBRR_ALGO_4,
-	.type		= PORT_SCIF,
+	.type		= PORT_SCIFA,
 	.irqs		= { evt2irq(0xc60), evt2irq(0xc60),
 			    evt2irq(0xc60), evt2irq(0xc60) },
 };
@@ -114,7 +115,7 @@
 	.flags		= UPF_BOOT_AUTOCONF,
 	.scscr		= SCSCR_RE | SCSCR_TE,
 	.scbrr_algo_id	= SCBRR_ALGO_4,
-	.type		= PORT_SCIF,
+	.type		= PORT_SCIFA,
 	.irqs		= { evt2irq(0xd20), evt2irq(0xd20),
 			    evt2irq(0xd20), evt2irq(0xd20) },
 };
@@ -133,7 +134,7 @@
 	.flags		= UPF_BOOT_AUTOCONF,
 	.scscr		= SCSCR_RE | SCSCR_TE,
 	.scbrr_algo_id	= SCBRR_ALGO_4,
-	.type		= PORT_SCIF,
+	.type		= PORT_SCIFA,
 	.irqs		= { evt2irq(0xd40), evt2irq(0xd40),
 			    evt2irq(0xd40), evt2irq(0xd40) },
 };
@@ -152,7 +153,7 @@
 	.flags		= UPF_BOOT_AUTOCONF,
 	.scscr		= SCSCR_RE | SCSCR_TE,
 	.scbrr_algo_id	= SCBRR_ALGO_4,
-	.type		= PORT_SCIF,
+	.type		= PORT_SCIFA,
 	.irqs		= { intcs_evt2irq(0x1a80), intcs_evt2irq(0x1a80),
 			    intcs_evt2irq(0x1a80), intcs_evt2irq(0x1a80) },
 };
@@ -171,7 +172,7 @@
 	.flags		= UPF_BOOT_AUTOCONF,
 	.scscr		= SCSCR_RE | SCSCR_TE,
 	.scbrr_algo_id	= SCBRR_ALGO_4,
-	.type		= PORT_SCIF,
+	.type		= PORT_SCIFB,
 	.irqs		= { evt2irq(0xd60), evt2irq(0xd60),
 			    evt2irq(0xd60), evt2irq(0xd60) },
 };
@@ -215,6 +216,214 @@
 	.num_resources	= ARRAY_SIZE(cmt10_resources),
 };
 
+/* VPU */
+static struct uio_info vpu_platform_data = {
+	.name = "VPU5HG",
+	.version = "0",
+	.irq = intcs_evt2irq(0x980),
+};
+
+static struct resource vpu_resources[] = {
+	[0] = {
+		.name	= "VPU",
+		.start	= 0xfe900000,
+		.end	= 0xfe900157,
+		.flags	= IORESOURCE_MEM,
+	},
+};
+
+static struct platform_device vpu_device = {
+	.name		= "uio_pdrv_genirq",
+	.id		= 0,
+	.dev = {
+		.platform_data	= &vpu_platform_data,
+	},
+	.resource	= vpu_resources,
+	.num_resources	= ARRAY_SIZE(vpu_resources),
+};
+
+/* VEU0 */
+static struct uio_info veu0_platform_data = {
+	.name = "VEU0",
+	.version = "0",
+	.irq = intcs_evt2irq(0x700),
+};
+
+static struct resource veu0_resources[] = {
+	[0] = {
+		.name	= "VEU0",
+		.start	= 0xfe920000,
+		.end	= 0xfe9200cb,
+		.flags	= IORESOURCE_MEM,
+	},
+};
+
+static struct platform_device veu0_device = {
+	.name		= "uio_pdrv_genirq",
+	.id		= 1,
+	.dev = {
+		.platform_data	= &veu0_platform_data,
+	},
+	.resource	= veu0_resources,
+	.num_resources	= ARRAY_SIZE(veu0_resources),
+};
+
+/* VEU1 */
+static struct uio_info veu1_platform_data = {
+	.name = "VEU1",
+	.version = "0",
+	.irq = intcs_evt2irq(0x720),
+};
+
+static struct resource veu1_resources[] = {
+	[0] = {
+		.name	= "VEU1",
+		.start	= 0xfe924000,
+		.end	= 0xfe9240cb,
+		.flags	= IORESOURCE_MEM,
+	},
+};
+
+static struct platform_device veu1_device = {
+	.name		= "uio_pdrv_genirq",
+	.id		= 2,
+	.dev = {
+		.platform_data	= &veu1_platform_data,
+	},
+	.resource	= veu1_resources,
+	.num_resources	= ARRAY_SIZE(veu1_resources),
+};
+
+/* VEU2 */
+static struct uio_info veu2_platform_data = {
+	.name = "VEU2",
+	.version = "0",
+	.irq = intcs_evt2irq(0x740),
+};
+
+static struct resource veu2_resources[] = {
+	[0] = {
+		.name	= "VEU2",
+		.start	= 0xfe928000,
+		.end	= 0xfe928307,
+		.flags	= IORESOURCE_MEM,
+	},
+};
+
+static struct platform_device veu2_device = {
+	.name		= "uio_pdrv_genirq",
+	.id		= 3,
+	.dev = {
+		.platform_data	= &veu2_platform_data,
+	},
+	.resource	= veu2_resources,
+	.num_resources	= ARRAY_SIZE(veu2_resources),
+};
+
+/* VEU3 */
+static struct uio_info veu3_platform_data = {
+	.name = "VEU3",
+	.version = "0",
+	.irq = intcs_evt2irq(0x760),
+};
+
+static struct resource veu3_resources[] = {
+	[0] = {
+		.name	= "VEU3",
+		.start	= 0xfe92c000,
+		.end	= 0xfe92c307,
+		.flags	= IORESOURCE_MEM,
+	},
+};
+
+static struct platform_device veu3_device = {
+	.name		= "uio_pdrv_genirq",
+	.id		= 4,
+	.dev = {
+		.platform_data	= &veu3_platform_data,
+	},
+	.resource	= veu3_resources,
+	.num_resources	= ARRAY_SIZE(veu3_resources),
+};
+
+/* JPU */
+static struct uio_info jpu_platform_data = {
+	.name = "JPU",
+	.version = "0",
+	.irq = intcs_evt2irq(0x560),
+};
+
+static struct resource jpu_resources[] = {
+	[0] = {
+		.name	= "JPU",
+		.start	= 0xfe980000,
+		.end	= 0xfe9902d3,
+		.flags	= IORESOURCE_MEM,
+	},
+};
+
+static struct platform_device jpu_device = {
+	.name		= "uio_pdrv_genirq",
+	.id		= 5,
+	.dev = {
+		.platform_data	= &jpu_platform_data,
+	},
+	.resource	= jpu_resources,
+	.num_resources	= ARRAY_SIZE(jpu_resources),
+};
+
+/* SPU2DSP0 */
+static struct uio_info spu0_platform_data = {
+	.name = "SPU2DSP0",
+	.version = "0",
+	.irq = evt2irq(0x1800),
+};
+
+static struct resource spu0_resources[] = {
+	[0] = {
+		.name	= "SPU2DSP0",
+		.start	= 0xfe200000,
+		.end	= 0xfe2fffff,
+		.flags	= IORESOURCE_MEM,
+	},
+};
+
+static struct platform_device spu0_device = {
+	.name		= "uio_pdrv_genirq",
+	.id		= 6,
+	.dev = {
+		.platform_data	= &spu0_platform_data,
+	},
+	.resource	= spu0_resources,
+	.num_resources	= ARRAY_SIZE(spu0_resources),
+};
+
+/* SPU2DSP1 */
+static struct uio_info spu1_platform_data = {
+	.name = "SPU2DSP1",
+	.version = "0",
+	.irq = evt2irq(0x1820),
+};
+
+static struct resource spu1_resources[] = {
+	[0] = {
+		.name	= "SPU2DSP1",
+		.start	= 0xfe300000,
+		.end	= 0xfe3fffff,
+		.flags	= IORESOURCE_MEM,
+	},
+};
+
+static struct platform_device spu1_device = {
+	.name		= "uio_pdrv_genirq",
+	.id		= 7,
+	.dev = {
+		.platform_data	= &spu1_platform_data,
+	},
+	.resource	= spu1_resources,
+	.num_resources	= ARRAY_SIZE(spu1_resources),
+};
+
 static struct platform_device *sh7377_early_devices[] __initdata = {
 	&scif0_device,
 	&scif1_device,
@@ -227,10 +436,24 @@
 	&cmt10_device,
 };
 
+static struct platform_device *sh7377_devices[] __initdata = {
+	&vpu_device,
+	&veu0_device,
+	&veu1_device,
+	&veu2_device,
+	&veu3_device,
+	&jpu_device,
+	&spu0_device,
+	&spu1_device,
+};
+
 void __init sh7377_add_standard_devices(void)
 {
 	platform_add_devices(sh7377_early_devices,
 			    ARRAY_SIZE(sh7377_early_devices));
+
+	platform_add_devices(sh7377_devices,
+			    ARRAY_SIZE(sh7377_devices));
 }
 
 #define SMSTPCR3 0xe615013c
diff -druN linux-2.6.39-libre/arch/arm/mach-shmobile/setup-sh73a0.c linux-3.0-rc7-libre/arch/arm/mach-shmobile/setup-sh73a0.c
--- linux-2.6.39-libre/arch/arm/mach-shmobile/setup-sh73a0.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-shmobile/setup-sh73a0.c	2011-07-11 19:51:52.000000000 -0400
@@ -27,9 +27,11 @@
 #include <linux/input.h>
 #include <linux/io.h>
 #include <linux/serial_sci.h>
+#include <linux/sh_dma.h>
 #include <linux/sh_intc.h>
 #include <linux/sh_timer.h>
 #include <mach/hardware.h>
+#include <mach/sh73a0.h>
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 
@@ -392,6 +394,242 @@
 	.num_resources	= ARRAY_SIZE(i2c4_resources),
 };
 
+/* 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_512BIT		= 5,
+};
+
+/* 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_512BIT]	= 6,	\
+}
+
+#define TS_INDEX2VAL(i) ((((i) & 3) << 3) | (((i) & 0xc) << (20 - 2)))
+#define CHCR_TX(xmit_sz) (DM_FIX | SM_INC | 0x800 | TS_INDEX2VAL((xmit_sz)))
+#define CHCR_RX(xmit_sz) (DM_INC | SM_FIX | 0x800 | TS_INDEX2VAL((xmit_sz)))
+
+static const struct sh_dmae_slave_config sh73a0_dmae_slaves[] = {
+	{
+		.slave_id	= SHDMA_SLAVE_SCIF0_TX,
+		.addr		= 0xe6c40020,
+		.chcr		= CHCR_TX(XMIT_SZ_8BIT),
+		.mid_rid	= 0x21,
+	}, {
+		.slave_id	= SHDMA_SLAVE_SCIF0_RX,
+		.addr		= 0xe6c40024,
+		.chcr		= CHCR_RX(XMIT_SZ_8BIT),
+		.mid_rid	= 0x22,
+	}, {
+		.slave_id	= SHDMA_SLAVE_SCIF1_TX,
+		.addr		= 0xe6c50020,
+		.chcr		= CHCR_TX(XMIT_SZ_8BIT),
+		.mid_rid	= 0x25,
+	}, {
+		.slave_id	= SHDMA_SLAVE_SCIF1_RX,
+		.addr		= 0xe6c50024,
+		.chcr		= CHCR_RX(XMIT_SZ_8BIT),
+		.mid_rid	= 0x26,
+	}, {
+		.slave_id	= SHDMA_SLAVE_SCIF2_TX,
+		.addr		= 0xe6c60020,
+		.chcr		= CHCR_TX(XMIT_SZ_8BIT),
+		.mid_rid	= 0x29,
+	}, {
+		.slave_id	= SHDMA_SLAVE_SCIF2_RX,
+		.addr		= 0xe6c60024,
+		.chcr		= CHCR_RX(XMIT_SZ_8BIT),
+		.mid_rid	= 0x2a,
+	}, {
+		.slave_id	= SHDMA_SLAVE_SCIF3_TX,
+		.addr		= 0xe6c70020,
+		.chcr		= CHCR_TX(XMIT_SZ_8BIT),
+		.mid_rid	= 0x2d,
+	}, {
+		.slave_id	= SHDMA_SLAVE_SCIF3_RX,
+		.addr		= 0xe6c70024,
+		.chcr		= CHCR_RX(XMIT_SZ_8BIT),
+		.mid_rid	= 0x2e,
+	}, {
+		.slave_id	= SHDMA_SLAVE_SCIF4_TX,
+		.addr		= 0xe6c80020,
+		.chcr		= CHCR_TX(XMIT_SZ_8BIT),
+		.mid_rid	= 0x39,
+	}, {
+		.slave_id	= SHDMA_SLAVE_SCIF4_RX,
+		.addr		= 0xe6c80024,
+		.chcr		= CHCR_RX(XMIT_SZ_8BIT),
+		.mid_rid	= 0x3a,
+	}, {
+		.slave_id	= SHDMA_SLAVE_SCIF5_TX,
+		.addr		= 0xe6cb0020,
+		.chcr		= CHCR_TX(XMIT_SZ_8BIT),
+		.mid_rid	= 0x35,
+	}, {
+		.slave_id	= SHDMA_SLAVE_SCIF5_RX,
+		.addr		= 0xe6cb0024,
+		.chcr		= CHCR_RX(XMIT_SZ_8BIT),
+		.mid_rid	= 0x36,
+	}, {
+		.slave_id	= SHDMA_SLAVE_SCIF6_TX,
+		.addr		= 0xe6cc0020,
+		.chcr		= CHCR_TX(XMIT_SZ_8BIT),
+		.mid_rid	= 0x1d,
+	}, {
+		.slave_id	= SHDMA_SLAVE_SCIF6_RX,
+		.addr		= 0xe6cc0024,
+		.chcr		= CHCR_RX(XMIT_SZ_8BIT),
+		.mid_rid	= 0x1e,
+	}, {
+		.slave_id	= SHDMA_SLAVE_SCIF7_TX,
+		.addr		= 0xe6cd0020,
+		.chcr		= CHCR_TX(XMIT_SZ_8BIT),
+		.mid_rid	= 0x19,
+	}, {
+		.slave_id	= SHDMA_SLAVE_SCIF7_RX,
+		.addr		= 0xe6cd0024,
+		.chcr		= CHCR_RX(XMIT_SZ_8BIT),
+		.mid_rid	= 0x1a,
+	}, {
+		.slave_id	= SHDMA_SLAVE_SCIF8_TX,
+		.addr		= 0xe6c30040,
+		.chcr		= CHCR_TX(XMIT_SZ_8BIT),
+		.mid_rid	= 0x3d,
+	}, {
+		.slave_id	= SHDMA_SLAVE_SCIF8_RX,
+		.addr		= 0xe6c30060,
+		.chcr		= CHCR_RX(XMIT_SZ_8BIT),
+		.mid_rid	= 0x3e,
+	}, {
+		.slave_id	= SHDMA_SLAVE_SDHI0_TX,
+		.addr		= 0xee100030,
+		.chcr		= CHCR_TX(XMIT_SZ_16BIT),
+		.mid_rid	= 0xc1,
+	}, {
+		.slave_id	= SHDMA_SLAVE_SDHI0_RX,
+		.addr		= 0xee100030,
+		.chcr		= CHCR_RX(XMIT_SZ_16BIT),
+		.mid_rid	= 0xc2,
+	}, {
+		.slave_id	= SHDMA_SLAVE_SDHI1_TX,
+		.addr		= 0xee120030,
+		.chcr		= CHCR_TX(XMIT_SZ_16BIT),
+		.mid_rid	= 0xc9,
+	}, {
+		.slave_id	= SHDMA_SLAVE_SDHI1_RX,
+		.addr		= 0xee120030,
+		.chcr		= CHCR_RX(XMIT_SZ_16BIT),
+		.mid_rid	= 0xca,
+	}, {
+		.slave_id	= SHDMA_SLAVE_SDHI2_TX,
+		.addr		= 0xee140030,
+		.chcr		= CHCR_TX(XMIT_SZ_16BIT),
+		.mid_rid	= 0xcd,
+	}, {
+		.slave_id	= SHDMA_SLAVE_SDHI2_RX,
+		.addr		= 0xee140030,
+		.chcr		= CHCR_RX(XMIT_SZ_16BIT),
+		.mid_rid	= 0xce,
+	}, {
+		.slave_id	= SHDMA_SLAVE_MMCIF_TX,
+		.addr		= 0xe6bd0034,
+		.chcr		= CHCR_TX(XMIT_SZ_32BIT),
+		.mid_rid	= 0xd1,
+	}, {
+		.slave_id	= SHDMA_SLAVE_MMCIF_RX,
+		.addr		= 0xe6bd0034,
+		.chcr		= CHCR_RX(XMIT_SZ_32BIT),
+		.mid_rid	= 0xd2,
+	},
+};
+
+#define DMAE_CHANNEL(_offset)					\
+	{							\
+		.offset         = _offset - 0x20,		\
+		.dmars          = _offset - 0x20 + 0x40,	\
+	}
+
+static const struct sh_dmae_channel sh73a0_dmae_channels[] = {
+	DMAE_CHANNEL(0x8000),
+	DMAE_CHANNEL(0x8080),
+	DMAE_CHANNEL(0x8100),
+	DMAE_CHANNEL(0x8180),
+	DMAE_CHANNEL(0x8200),
+	DMAE_CHANNEL(0x8280),
+	DMAE_CHANNEL(0x8300),
+	DMAE_CHANNEL(0x8380),
+	DMAE_CHANNEL(0x8400),
+	DMAE_CHANNEL(0x8480),
+	DMAE_CHANNEL(0x8500),
+	DMAE_CHANNEL(0x8580),
+	DMAE_CHANNEL(0x8600),
+	DMAE_CHANNEL(0x8680),
+	DMAE_CHANNEL(0x8700),
+	DMAE_CHANNEL(0x8780),
+	DMAE_CHANNEL(0x8800),
+	DMAE_CHANNEL(0x8880),
+	DMAE_CHANNEL(0x8900),
+	DMAE_CHANNEL(0x8980),
+};
+
+static const unsigned int ts_shift[] = TS_SHIFT;
+
+static struct sh_dmae_pdata sh73a0_dmae_platform_data = {
+	.slave          = sh73a0_dmae_slaves,
+	.slave_num      = ARRAY_SIZE(sh73a0_dmae_slaves),
+	.channel        = sh73a0_dmae_channels,
+	.channel_num    = ARRAY_SIZE(sh73a0_dmae_channels),
+	.ts_low_shift   = 3,
+	.ts_low_mask    = 0x18,
+	.ts_high_shift  = (20 - 2),     /* 2 bits for shifted low TS */
+	.ts_high_mask   = 0x00300000,
+	.ts_shift       = ts_shift,
+	.ts_shift_num   = ARRAY_SIZE(ts_shift),
+	.dmaor_init     = DMAOR_DME,
+};
+
+static struct resource sh73a0_dmae_resources[] = {
+	{
+		/* Registers including DMAOR and channels including DMARSx */
+		.start  = 0xfe000020,
+		.end    = 0xfe008a00 - 1,
+		.flags  = IORESOURCE_MEM,
+	},
+	{
+		/* DMA error IRQ */
+		.start  = gic_spi(129),
+		.end    = gic_spi(129),
+		.flags  = IORESOURCE_IRQ,
+	},
+	{
+		/* IRQ for channels 0-19 */
+		.start  = gic_spi(109),
+		.end    = gic_spi(128),
+		.flags  = IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device dma0_device = {
+	.name		= "sh-dma-engine",
+	.id		= 0,
+	.resource	= sh73a0_dmae_resources,
+	.num_resources	= ARRAY_SIZE(sh73a0_dmae_resources),
+	.dev		= {
+		.platform_data	= &sh73a0_dmae_platform_data,
+	},
+};
+
 static struct platform_device *sh73a0_early_devices[] __initdata = {
 	&scif0_device,
 	&scif1_device,
@@ -413,10 +651,16 @@
 	&i2c2_device,
 	&i2c3_device,
 	&i2c4_device,
+	&dma0_device,
 };
 
+#define SRCR2          0xe61580b0
+
 void __init sh73a0_add_standard_devices(void)
 {
+	/* Clear software reset bit on SY-DMAC module */
+	__raw_writel(__raw_readl(SRCR2) & ~(1 << 18), SRCR2);
+
 	platform_add_devices(sh73a0_early_devices,
 			    ARRAY_SIZE(sh73a0_early_devices));
 	platform_add_devices(sh73a0_late_devices,
diff -druN linux-2.6.39-libre/arch/arm/mach-shmobile/sleep-sh7372.S linux-3.0-rc7-libre/arch/arm/mach-shmobile/sleep-sh7372.S
--- linux-2.6.39-libre/arch/arm/mach-shmobile/sleep-sh7372.S	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/arm/mach-shmobile/sleep-sh7372.S	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,260 @@
+/*
+ * sh7372 lowlevel sleep code for "Core Standby Mode"
+ *
+ * Copyright (C) 2011 Magnus Damm
+ *
+ * In "Core Standby Mode" the ARM core is off, but L2 cache is still on
+ *
+ * Based on mach-omap2/sleep34xx.S
+ *
+ * (C) Copyright 2007 Texas Instruments
+ * Karthik Dasu <karthik-dp@ti.com>
+ *
+ * (C) Copyright 2004 Texas Instruments, <www.ti.com>
+ * Richard Woodruff <r-woodruff2@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR /PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+
+#define SMFRAM 0xe6a70000
+
+	.align
+kernel_flush:
+	.word	v7_flush_dcache_all
+
+	.align	3
+ENTRY(sh7372_cpu_suspend)
+	stmfd	sp!, {r0-r12, lr}	@ save registers on stack
+
+	ldr	r8, =SMFRAM
+
+	mov	r4, sp			@ Store sp
+	mrs	r5, spsr		@ Store spsr
+	mov	r6, lr			@ Store lr
+	stmia	r8!, {r4-r6}
+
+	mrc	p15, 0, r4, c1, c0, 2	@ Coprocessor access control register
+	mrc	p15, 0, r5, c2, c0, 0	@ TTBR0
+	mrc	p15, 0, r6, c2, c0, 1	@ TTBR1
+	mrc	p15, 0, r7, c2, c0, 2	@ TTBCR
+	stmia	r8!, {r4-r7}
+
+	mrc	p15, 0, r4, c3, c0, 0	@ Domain access Control Register
+	mrc	p15, 0, r5, c10, c2, 0	@ PRRR
+	mrc	p15, 0, r6, c10, c2, 1	@ NMRR
+	stmia	r8!,{r4-r6}
+
+	mrc	p15, 0, r4, c13, c0, 1	@ Context ID
+	mrc	p15, 0, r5, c13, c0, 2	@ User r/w thread and process ID
+	mrc	p15, 0, r6, c12, c0, 0	@ Secure or NS vector base address
+	mrs	r7, cpsr		@ Store current cpsr
+	stmia	r8!, {r4-r7}
+
+	mrc	p15, 0, r4, c1, c0, 0	@ save control register
+	stmia	r8!, {r4}
+
+	/*
+	 * jump out to kernel flush routine
+	 *  - reuse that code is better
+	 *  - it executes in a cached space so is faster than refetch per-block
+	 *  - should be faster and will change with kernel
+	 *  - 'might' have to copy address, load and jump to it
+	 * Flush all data from the L1 data cache before disabling
+	 * SCTLR.C bit.
+	 */
+	ldr	r1, kernel_flush
+	mov	lr, pc
+	bx	r1
+
+	/*
+	 * Clear the SCTLR.C bit to prevent further data cache
+	 * allocation. Clearing SCTLR.C would make all the data accesses
+	 * strongly ordered and would not hit the cache.
+	 */
+	mrc	p15, 0, r0, c1, c0, 0
+	bic	r0, r0, #(1 << 2)	@ Disable the C bit
+	mcr	p15, 0, r0, c1, c0, 0
+	isb
+
+	/*
+	 * Invalidate L1 data cache. Even though only invalidate is
+	 * necessary exported flush API is used here. Doing clean
+	 * on already clean cache would be almost NOP.
+	 */
+	ldr	r1, kernel_flush
+	blx	r1
+	/*
+	 * The kernel doesn't interwork: v7_flush_dcache_all in particluar will
+	 * always return in Thumb state when CONFIG_THUMB2_KERNEL is enabled.
+	 * This sequence switches back to ARM.  Note that .align may insert a
+	 * nop: bx pc needs to be word-aligned in order to work.
+	 */
+ THUMB(	.thumb		)
+ THUMB(	.align		)
+ THUMB(	bx	pc	)
+ THUMB(	nop		)
+	.arm
+
+	/* Data memory barrier and Data sync barrier */
+	dsb
+	dmb
+
+/*
+ * ===================================
+ * == WFI instruction => Enter idle ==
+ * ===================================
+ */
+	wfi				@ wait for interrupt
+
+/*
+ * ===================================
+ * == Resume path for non-OFF modes ==
+ * ===================================
+ */
+	mrc	p15, 0, r0, c1, c0, 0
+	tst	r0, #(1 << 2)		@ Check C bit enabled?
+	orreq	r0, r0, #(1 << 2)	@ Enable the C bit if cleared
+	mcreq	p15, 0, r0, c1, c0, 0
+	isb
+
+/*
+ * ===================================
+ * == Exit point from non-OFF modes ==
+ * ===================================
+ */
+	ldmfd	sp!, {r0-r12, pc}	@ restore regs and return
+
+	.pool
+
+	.align	12
+	.text
+	.global	sh7372_cpu_resume
+sh7372_cpu_resume:
+
+	mov	r1, #0
+	/*
+	 * Invalidate all instruction caches to PoU
+	 * and flush branch target cache
+	 */
+	mcr	p15, 0, r1, c7, c5, 0
+
+	ldr	r3, =SMFRAM
+
+	ldmia	r3!, {r4-r6}
+	mov	sp, r4			@ Restore sp
+	msr	spsr_cxsf, r5		@ Restore spsr
+	mov	lr, r6			@ Restore lr
+
+	ldmia	r3!, {r4-r7}
+	mcr	p15, 0, r4, c1, c0, 2	@ Coprocessor access Control Register
+	mcr	p15, 0, r5, c2, c0, 0	@ TTBR0
+	mcr	p15, 0, r6, c2, c0, 1	@ TTBR1
+	mcr	p15, 0, r7, c2, c0, 2	@ TTBCR
+
+	ldmia	r3!,{r4-r6}
+	mcr	p15, 0, r4, c3, c0, 0	@ Domain access Control Register
+	mcr	p15, 0, r5, c10, c2, 0	@ PRRR
+	mcr	p15, 0, r6, c10, c2, 1	@ NMRR
+
+	ldmia	r3!,{r4-r7}
+	mcr	p15, 0, r4, c13, c0, 1	@ Context ID
+	mcr	p15, 0, r5, c13, c0, 2	@ User r/w thread and process ID
+	mrc	p15, 0, r6, c12, c0, 0	@ Secure or NS vector base address
+	msr	cpsr, r7		@ store cpsr
+
+	/* Starting to enable MMU here */
+	mrc	p15, 0, r7, c2, c0, 2 	@ Read TTBRControl
+	/* Extract N (0:2) bits and decide whether to use TTBR0 or TTBR1 */
+	and	r7, #0x7
+	cmp	r7, #0x0
+	beq	usettbr0
+ttbr_error:
+	/*
+	 * More work needs to be done to support N[0:2] value other than 0
+	 * So looping here so that the error can be detected
+	 */
+	b	ttbr_error
+
+	.align
+cache_pred_disable_mask:
+	.word	0xFFFFE7FB
+ttbrbit_mask:
+	.word	0xFFFFC000
+table_index_mask:
+	.word	0xFFF00000
+table_entry:
+	.word	0x00000C02
+usettbr0:
+
+	mrc	p15, 0, r2, c2, c0, 0
+	ldr	r5, ttbrbit_mask
+	and	r2, r5
+	mov	r4, pc
+	ldr	r5, table_index_mask
+	and	r4, r5			@ r4 = 31 to 20 bits of pc
+	/* Extract the value to be written to table entry */
+	ldr	r6, table_entry
+	/* r6 has the value to be written to table entry */
+	add	r6, r6, r4
+	/* Getting the address of table entry to modify */
+	lsr	r4, #18
+	/* r2 has the location which needs to be modified */
+	add	r2, r4
+	ldr	r4, [r2]
+	str	r6, [r2] /* modify the table entry */
+
+	mov	r7, r6
+	mov	r5, r2
+	mov	r6, r4
+	/* r5 = original page table address */
+	/* r6 = original page table data */
+
+	mov	r0, #0
+	mcr	p15, 0, r0, c7, c5, 4	@ Flush prefetch buffer
+	mcr	p15, 0, r0, c7, c5, 6	@ Invalidate branch predictor array
+	mcr	p15, 0, r0, c8, c5, 0	@ Invalidate instruction TLB
+	mcr	p15, 0, r0, c8, c6, 0	@ Invalidate data TLB
+
+	/*
+	 * Restore control register. This enables the MMU.
+	 * The caches and prediction are not enabled here, they
+	 * will be enabled after restoring the MMU table entry.
+	 */
+	ldmia	r3!, {r4}
+	stmia	r3!, {r5} /* save original page table address */
+	stmia	r3!, {r6} /* save original page table data */
+	stmia	r3!, {r7} /* save modified page table data */
+
+	ldr	r2, cache_pred_disable_mask
+	and	r4, r2
+	mcr	p15, 0, r4, c1, c0, 0
+	dsb
+	isb
+
+	ldr     r0, =restoremmu_on
+	bx      r0
+
+/*
+ * ==============================
+ * == Exit point from OFF mode ==
+ * ==============================
+ */
+restoremmu_on:
+
+	ldmfd	sp!, {r0-r12, pc}	@ restore regs and return
diff -druN linux-2.6.39-libre/arch/arm/mach-shmobile/smp-sh73a0.c linux-3.0-rc7-libre/arch/arm/mach-shmobile/smp-sh73a0.c
--- linux-2.6.39-libre/arch/arm/mach-shmobile/smp-sh73a0.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-shmobile/smp-sh73a0.c	2011-07-11 19:51:52.000000000 -0400
@@ -59,6 +59,11 @@
 {
 	void __iomem *scu_base = scu_base_addr();
 
+#ifdef CONFIG_HAVE_ARM_TWD
+	/* twd_base needs to be initialized before percpu_timer_setup() */
+	twd_base = (void __iomem *)0xf0000600;
+#endif
+
 	return scu_get_core_count(scu_base);
 }
 
@@ -82,10 +87,6 @@
 
 void __init sh73a0_smp_prepare_cpus(void)
 {
-#ifdef CONFIG_HAVE_ARM_TWD
-	twd_base = (void __iomem *)0xf0000600;
-#endif
-
 	scu_enable(scu_base_addr());
 
 	/* Map the reset vector (in headsmp.S) */
diff -druN linux-2.6.39-libre/arch/arm/mach-shmobile/suspend.c linux-3.0-rc7-libre/arch/arm/mach-shmobile/suspend.c
--- linux-2.6.39-libre/arch/arm/mach-shmobile/suspend.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/arm/mach-shmobile/suspend.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,47 @@
+/*
+ * Suspend-to-RAM support code for SH-Mobile ARM
+ *
+ *  Copyright (C) 2011 Magnus Damm
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+
+#include <linux/pm.h>
+#include <linux/suspend.h>
+#include <linux/module.h>
+#include <linux/err.h>
+#include <asm/system.h>
+#include <asm/io.h>
+
+static int shmobile_suspend_default_enter(suspend_state_t suspend_state)
+{
+	cpu_do_idle();
+	return 0;
+}
+
+static int shmobile_suspend_begin(suspend_state_t state)
+{
+	disable_hlt();
+	return 0;
+}
+
+static void shmobile_suspend_end(void)
+{
+	enable_hlt();
+}
+
+struct platform_suspend_ops shmobile_suspend_ops = {
+	.begin		= shmobile_suspend_begin,
+	.end		= shmobile_suspend_end,
+	.enter		= shmobile_suspend_default_enter,
+	.valid		= suspend_valid_only_mem,
+};
+
+static int __init shmobile_suspend_init(void)
+{
+	suspend_set_ops(&shmobile_suspend_ops);
+	return 0;
+}
+late_initcall(shmobile_suspend_init);
diff -druN linux-2.6.39-libre/arch/arm/mach-spear3xx/clock.c linux-3.0-rc7-libre/arch/arm/mach-spear3xx/clock.c
--- linux-2.6.39-libre/arch/arm/mach-spear3xx/clock.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-spear3xx/clock.c	2011-07-11 19:51:52.000000000 -0400
@@ -13,6 +13,7 @@
 
 #include <linux/init.h>
 #include <linux/kernel.h>
+#include <asm/mach-types.h>
 #include <plat/clock.h>
 #include <mach/misc_regs.h>
 
@@ -688,56 +689,71 @@
 	{ .dev_id = "adc",		.clk = &adc_clk},
 	{ .dev_id = "ssp-pl022.0",	.clk = &ssp0_clk},
 	{ .dev_id = "gpio",		.clk = &gpio_clk},
-#if defined(CONFIG_MACH_SPEAR310) || defined(CONFIG_MACH_SPEAR320)
-	{ .dev_id = "physmap-flash",	.clk = &emi_clk},
-#endif
-#if defined(CONFIG_MACH_SPEAR300) || defined(CONFIG_MACH_SPEAR310) || \
-	defined(CONFIG_MACH_SPEAR320)
-	{ .con_id = "fsmc",		.clk = &fsmc_clk},
-#endif
-
-/* common clocks to spear310 and spear320 */
-#if defined(CONFIG_MACH_SPEAR310) || defined(CONFIG_MACH_SPEAR320)
-	{ .dev_id = "uart1",		.clk = &uart1_clk},
-	{ .dev_id = "uart2",		.clk = &uart2_clk},
-#endif
-
-	/* common clock to spear300 and spear320 */
-#if defined(CONFIG_MACH_SPEAR300) || defined(CONFIG_MACH_SPEAR320)
-	{ .dev_id = "clcd",		.clk = &clcd_clk},
-	{ .dev_id = "sdhci",		.clk = &sdhci_clk},
-#endif /* CONFIG_MACH_SPEAR300 || CONFIG_MACH_SPEAR320 */
+};
 
-	/* spear300 machine specific clock structures */
+/* array of all spear 300 clock lookups */
 #ifdef CONFIG_MACH_SPEAR300
+static struct clk_lookup spear300_clk_lookups[] = {
+	{ .dev_id = "clcd",		.clk = &clcd_clk},
+	{ .con_id = "fsmc",		.clk = &fsmc_clk},
 	{ .dev_id = "gpio1",		.clk = &gpio1_clk},
 	{ .dev_id = "keyboard",		.clk = &kbd_clk},
+	{ .dev_id = "sdhci",		.clk = &sdhci_clk},
+};
 #endif
 
-	/* spear310 machine specific clock structures */
+/* array of all spear 310 clock lookups */
 #ifdef CONFIG_MACH_SPEAR310
+static struct clk_lookup spear310_clk_lookups[] = {
+	{ .con_id = "fsmc",		.clk = &fsmc_clk},
+	{ .con_id = "emi",		.clk = &emi_clk},
+	{ .dev_id = "uart1",		.clk = &uart1_clk},
+	{ .dev_id = "uart2",		.clk = &uart2_clk},
 	{ .dev_id = "uart3",		.clk = &uart3_clk},
 	{ .dev_id = "uart4",		.clk = &uart4_clk},
 	{ .dev_id = "uart5",		.clk = &uart5_clk},
-
+};
 #endif
-	/* spear320 machine specific clock structures */
+
+/* array of all spear 320 clock lookups */
 #ifdef CONFIG_MACH_SPEAR320
+static struct clk_lookup spear320_clk_lookups[] = {
+	{ .dev_id = "clcd",		.clk = &clcd_clk},
+	{ .con_id = "fsmc",		.clk = &fsmc_clk},
+	{ .dev_id = "i2c_designware.1",	.clk = &i2c1_clk},
+	{ .con_id = "emi",		.clk = &emi_clk},
+	{ .dev_id = "pwm",		.clk = &pwm_clk},
+	{ .dev_id = "sdhci",		.clk = &sdhci_clk},
 	{ .dev_id = "c_can_platform.0",	.clk = &can0_clk},
 	{ .dev_id = "c_can_platform.1",	.clk = &can1_clk},
-	{ .dev_id = "i2c_designware.1",	.clk = &i2c1_clk},
 	{ .dev_id = "ssp-pl022.1",	.clk = &ssp1_clk},
 	{ .dev_id = "ssp-pl022.2",	.clk = &ssp2_clk},
-	{ .dev_id = "pwm",		.clk = &pwm_clk},
-#endif
+	{ .dev_id = "uart1",		.clk = &uart1_clk},
+	{ .dev_id = "uart2",		.clk = &uart2_clk},
 };
+#endif
 
-void __init clk_init(void)
+void __init spear3xx_clk_init(void)
 {
-	int i;
+	int i, cnt;
+	struct clk_lookup *lookups;
+
+	if (machine_is_spear300()) {
+		cnt = ARRAY_SIZE(spear300_clk_lookups);
+		lookups = spear300_clk_lookups;
+	} else if (machine_is_spear310()) {
+		cnt = ARRAY_SIZE(spear310_clk_lookups);
+		lookups = spear310_clk_lookups;
+	} else {
+		cnt = ARRAY_SIZE(spear320_clk_lookups);
+		lookups = spear320_clk_lookups;
+	}
 
 	for (i = 0; i < ARRAY_SIZE(spear_clk_lookups); i++)
 		clk_register(&spear_clk_lookups[i]);
 
-	recalc_root_clocks();
+	for (i = 0; i < cnt; i++)
+		clk_register(&lookups[i]);
+
+	clk_init();
 }
diff -druN linux-2.6.39-libre/arch/arm/mach-spear3xx/include/mach/generic.h linux-3.0-rc7-libre/arch/arm/mach-spear3xx/include/mach/generic.h
--- linux-2.6.39-libre/arch/arm/mach-spear3xx/include/mach/generic.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-spear3xx/include/mach/generic.h	2011-07-11 19:51:52.000000000 -0400
@@ -27,16 +27,16 @@
  * Following GPT channels will be used as clock source and clockevent
  */
 #define SPEAR_GPT0_BASE		SPEAR3XX_ML1_TMR_BASE
-#define SPEAR_GPT0_CHAN0_IRQ	IRQ_CPU_GPT1_1
-#define SPEAR_GPT0_CHAN1_IRQ	IRQ_CPU_GPT1_2
+#define SPEAR_GPT0_CHAN0_IRQ	SPEAR3XX_IRQ_CPU_GPT1_1
+#define SPEAR_GPT0_CHAN1_IRQ	SPEAR3XX_IRQ_CPU_GPT1_2
 
 /* Add spear3xx family device structure declarations here */
-extern struct amba_device gpio_device;
-extern struct amba_device uart_device;
+extern struct amba_device spear3xx_gpio_device;
+extern struct amba_device spear3xx_uart_device;
 extern struct sys_timer spear3xx_timer;
 
 /* Add spear3xx family function declarations here */
-void __init clk_init(void);
+void __init spear3xx_clk_init(void);
 void __init spear_setup_timer(void);
 void __init spear3xx_map_io(void);
 void __init spear3xx_init_irq(void);
@@ -60,81 +60,80 @@
 #define PMX_TIMER_1_2_MASK	(1 << 0)
 
 /* pad mux devices */
-extern struct pmx_dev pmx_firda;
-extern struct pmx_dev pmx_i2c;
-extern struct pmx_dev pmx_ssp_cs;
-extern struct pmx_dev pmx_ssp;
-extern struct pmx_dev pmx_mii;
-extern struct pmx_dev pmx_gpio_pin0;
-extern struct pmx_dev pmx_gpio_pin1;
-extern struct pmx_dev pmx_gpio_pin2;
-extern struct pmx_dev pmx_gpio_pin3;
-extern struct pmx_dev pmx_gpio_pin4;
-extern struct pmx_dev pmx_gpio_pin5;
-extern struct pmx_dev pmx_uart0_modem;
-extern struct pmx_dev pmx_uart0;
-extern struct pmx_dev pmx_timer_3_4;
-extern struct pmx_dev pmx_timer_1_2;
+extern struct pmx_dev spear3xx_pmx_firda;
+extern struct pmx_dev spear3xx_pmx_i2c;
+extern struct pmx_dev spear3xx_pmx_ssp_cs;
+extern struct pmx_dev spear3xx_pmx_ssp;
+extern struct pmx_dev spear3xx_pmx_mii;
+extern struct pmx_dev spear3xx_pmx_gpio_pin0;
+extern struct pmx_dev spear3xx_pmx_gpio_pin1;
+extern struct pmx_dev spear3xx_pmx_gpio_pin2;
+extern struct pmx_dev spear3xx_pmx_gpio_pin3;
+extern struct pmx_dev spear3xx_pmx_gpio_pin4;
+extern struct pmx_dev spear3xx_pmx_gpio_pin5;
+extern struct pmx_dev spear3xx_pmx_uart0_modem;
+extern struct pmx_dev spear3xx_pmx_uart0;
+extern struct pmx_dev spear3xx_pmx_timer_3_4;
+extern struct pmx_dev spear3xx_pmx_timer_1_2;
 
 #if defined(CONFIG_MACH_SPEAR310) || defined(CONFIG_MACH_SPEAR320)
 /* padmux plgpio devices */
-extern struct pmx_dev pmx_plgpio_0_1;
-extern struct pmx_dev pmx_plgpio_2_3;
-extern struct pmx_dev pmx_plgpio_4_5;
-extern struct pmx_dev pmx_plgpio_6_9;
-extern struct pmx_dev pmx_plgpio_10_27;
-extern struct pmx_dev pmx_plgpio_28;
-extern struct pmx_dev pmx_plgpio_29;
-extern struct pmx_dev pmx_plgpio_30;
-extern struct pmx_dev pmx_plgpio_31;
-extern struct pmx_dev pmx_plgpio_32;
-extern struct pmx_dev pmx_plgpio_33;
-extern struct pmx_dev pmx_plgpio_34_36;
-extern struct pmx_dev pmx_plgpio_37_42;
-extern struct pmx_dev pmx_plgpio_43_44_47_48;
-extern struct pmx_dev pmx_plgpio_45_46_49_50;
+extern struct pmx_dev spear3xx_pmx_plgpio_0_1;
+extern struct pmx_dev spear3xx_pmx_plgpio_2_3;
+extern struct pmx_dev spear3xx_pmx_plgpio_4_5;
+extern struct pmx_dev spear3xx_pmx_plgpio_6_9;
+extern struct pmx_dev spear3xx_pmx_plgpio_10_27;
+extern struct pmx_dev spear3xx_pmx_plgpio_28;
+extern struct pmx_dev spear3xx_pmx_plgpio_29;
+extern struct pmx_dev spear3xx_pmx_plgpio_30;
+extern struct pmx_dev spear3xx_pmx_plgpio_31;
+extern struct pmx_dev spear3xx_pmx_plgpio_32;
+extern struct pmx_dev spear3xx_pmx_plgpio_33;
+extern struct pmx_dev spear3xx_pmx_plgpio_34_36;
+extern struct pmx_dev spear3xx_pmx_plgpio_37_42;
+extern struct pmx_dev spear3xx_pmx_plgpio_43_44_47_48;
+extern struct pmx_dev spear3xx_pmx_plgpio_45_46_49_50;
 #endif
 
-extern struct pmx_driver pmx_driver;
-
 /* spear300 declarations */
 #ifdef CONFIG_MACH_SPEAR300
 /* Add spear300 machine device structure declarations here */
-extern struct amba_device gpio1_device;
+extern struct amba_device spear300_gpio1_device;
 
 /* pad mux modes */
-extern struct pmx_mode nand_mode;
-extern struct pmx_mode nor_mode;
-extern struct pmx_mode photo_frame_mode;
-extern struct pmx_mode lend_ip_phone_mode;
-extern struct pmx_mode hend_ip_phone_mode;
-extern struct pmx_mode lend_wifi_phone_mode;
-extern struct pmx_mode hend_wifi_phone_mode;
-extern struct pmx_mode ata_pabx_wi2s_mode;
-extern struct pmx_mode ata_pabx_i2s_mode;
-extern struct pmx_mode caml_lcdw_mode;
-extern struct pmx_mode camu_lcd_mode;
-extern struct pmx_mode camu_wlcd_mode;
-extern struct pmx_mode caml_lcd_mode;
+extern struct pmx_mode spear300_nand_mode;
+extern struct pmx_mode spear300_nor_mode;
+extern struct pmx_mode spear300_photo_frame_mode;
+extern struct pmx_mode spear300_lend_ip_phone_mode;
+extern struct pmx_mode spear300_hend_ip_phone_mode;
+extern struct pmx_mode spear300_lend_wifi_phone_mode;
+extern struct pmx_mode spear300_hend_wifi_phone_mode;
+extern struct pmx_mode spear300_ata_pabx_wi2s_mode;
+extern struct pmx_mode spear300_ata_pabx_i2s_mode;
+extern struct pmx_mode spear300_caml_lcdw_mode;
+extern struct pmx_mode spear300_camu_lcd_mode;
+extern struct pmx_mode spear300_camu_wlcd_mode;
+extern struct pmx_mode spear300_caml_lcd_mode;
 
 /* pad mux devices */
-extern struct pmx_dev pmx_fsmc_2_chips;
-extern struct pmx_dev pmx_fsmc_4_chips;
-extern struct pmx_dev pmx_keyboard;
-extern struct pmx_dev pmx_clcd;
-extern struct pmx_dev pmx_telecom_gpio;
-extern struct pmx_dev pmx_telecom_tdm;
-extern struct pmx_dev pmx_telecom_spi_cs_i2c_clk;
-extern struct pmx_dev pmx_telecom_camera;
-extern struct pmx_dev pmx_telecom_dac;
-extern struct pmx_dev pmx_telecom_i2s;
-extern struct pmx_dev pmx_telecom_boot_pins;
-extern struct pmx_dev pmx_telecom_sdhci_4bit;
-extern struct pmx_dev pmx_telecom_sdhci_8bit;
-extern struct pmx_dev pmx_gpio1;
+extern struct pmx_dev spear300_pmx_fsmc_2_chips;
+extern struct pmx_dev spear300_pmx_fsmc_4_chips;
+extern struct pmx_dev spear300_pmx_keyboard;
+extern struct pmx_dev spear300_pmx_clcd;
+extern struct pmx_dev spear300_pmx_telecom_gpio;
+extern struct pmx_dev spear300_pmx_telecom_tdm;
+extern struct pmx_dev spear300_pmx_telecom_spi_cs_i2c_clk;
+extern struct pmx_dev spear300_pmx_telecom_camera;
+extern struct pmx_dev spear300_pmx_telecom_dac;
+extern struct pmx_dev spear300_pmx_telecom_i2s;
+extern struct pmx_dev spear300_pmx_telecom_boot_pins;
+extern struct pmx_dev spear300_pmx_telecom_sdhci_4bit;
+extern struct pmx_dev spear300_pmx_telecom_sdhci_8bit;
+extern struct pmx_dev spear300_pmx_gpio1;
 
 /* Add spear300 machine function declarations here */
-void __init spear300_init(void);
+void __init spear300_init(struct pmx_mode *pmx_mode, struct pmx_dev **pmx_devs,
+		u8 pmx_dev_count);
 
 #endif /* CONFIG_MACH_SPEAR300 */
 
@@ -143,17 +142,18 @@
 /* Add spear310 machine device structure declarations here */
 
 /* pad mux devices */
-extern struct pmx_dev pmx_emi_cs_0_1_4_5;
-extern struct pmx_dev pmx_emi_cs_2_3;
-extern struct pmx_dev pmx_uart1;
-extern struct pmx_dev pmx_uart2;
-extern struct pmx_dev pmx_uart3_4_5;
-extern struct pmx_dev pmx_fsmc;
-extern struct pmx_dev pmx_rs485_0_1;
-extern struct pmx_dev pmx_tdm0;
+extern struct pmx_dev spear310_pmx_emi_cs_0_1_4_5;
+extern struct pmx_dev spear310_pmx_emi_cs_2_3;
+extern struct pmx_dev spear310_pmx_uart1;
+extern struct pmx_dev spear310_pmx_uart2;
+extern struct pmx_dev spear310_pmx_uart3_4_5;
+extern struct pmx_dev spear310_pmx_fsmc;
+extern struct pmx_dev spear310_pmx_rs485_0_1;
+extern struct pmx_dev spear310_pmx_tdm0;
 
 /* Add spear310 machine function declarations here */
-void __init spear310_init(void);
+void __init spear310_init(struct pmx_mode *pmx_mode, struct pmx_dev **pmx_devs,
+		u8 pmx_dev_count);
 
 #endif /* CONFIG_MACH_SPEAR310 */
 
@@ -162,37 +162,38 @@
 /* Add spear320 machine device structure declarations here */
 
 /* pad mux modes */
-extern struct pmx_mode auto_net_smii_mode;
-extern struct pmx_mode auto_net_mii_mode;
-extern struct pmx_mode auto_exp_mode;
-extern struct pmx_mode small_printers_mode;
+extern struct pmx_mode spear320_auto_net_smii_mode;
+extern struct pmx_mode spear320_auto_net_mii_mode;
+extern struct pmx_mode spear320_auto_exp_mode;
+extern struct pmx_mode spear320_small_printers_mode;
 
 /* pad mux devices */
-extern struct pmx_dev pmx_clcd;
-extern struct pmx_dev pmx_emi;
-extern struct pmx_dev pmx_fsmc;
-extern struct pmx_dev pmx_spp;
-extern struct pmx_dev pmx_sdhci;
-extern struct pmx_dev pmx_i2s;
-extern struct pmx_dev pmx_uart1;
-extern struct pmx_dev pmx_uart1_modem;
-extern struct pmx_dev pmx_uart2;
-extern struct pmx_dev pmx_touchscreen;
-extern struct pmx_dev pmx_can;
-extern struct pmx_dev pmx_sdhci_led;
-extern struct pmx_dev pmx_pwm0;
-extern struct pmx_dev pmx_pwm1;
-extern struct pmx_dev pmx_pwm2;
-extern struct pmx_dev pmx_pwm3;
-extern struct pmx_dev pmx_ssp1;
-extern struct pmx_dev pmx_ssp2;
-extern struct pmx_dev pmx_mii1;
-extern struct pmx_dev pmx_smii0;
-extern struct pmx_dev pmx_smii1;
-extern struct pmx_dev pmx_i2c1;
+extern struct pmx_dev spear320_pmx_clcd;
+extern struct pmx_dev spear320_pmx_emi;
+extern struct pmx_dev spear320_pmx_fsmc;
+extern struct pmx_dev spear320_pmx_spp;
+extern struct pmx_dev spear320_pmx_sdhci;
+extern struct pmx_dev spear320_pmx_i2s;
+extern struct pmx_dev spear320_pmx_uart1;
+extern struct pmx_dev spear320_pmx_uart1_modem;
+extern struct pmx_dev spear320_pmx_uart2;
+extern struct pmx_dev spear320_pmx_touchscreen;
+extern struct pmx_dev spear320_pmx_can;
+extern struct pmx_dev spear320_pmx_sdhci_led;
+extern struct pmx_dev spear320_pmx_pwm0;
+extern struct pmx_dev spear320_pmx_pwm1;
+extern struct pmx_dev spear320_pmx_pwm2;
+extern struct pmx_dev spear320_pmx_pwm3;
+extern struct pmx_dev spear320_pmx_ssp1;
+extern struct pmx_dev spear320_pmx_ssp2;
+extern struct pmx_dev spear320_pmx_mii1;
+extern struct pmx_dev spear320_pmx_smii0;
+extern struct pmx_dev spear320_pmx_smii1;
+extern struct pmx_dev spear320_pmx_i2c1;
 
 /* Add spear320 machine function declarations here */
-void __init spear320_init(void);
+void __init spear320_init(struct pmx_mode *pmx_mode, struct pmx_dev **pmx_devs,
+		u8 pmx_dev_count);
 
 #endif /* CONFIG_MACH_SPEAR320 */
 
diff -druN linux-2.6.39-libre/arch/arm/mach-spear3xx/include/mach/irqs.h linux-3.0-rc7-libre/arch/arm/mach-spear3xx/include/mach/irqs.h
--- linux-2.6.39-libre/arch/arm/mach-spear3xx/include/mach/irqs.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-spear3xx/include/mach/irqs.h	2011-07-11 19:51:52.000000000 -0400
@@ -15,138 +15,140 @@
 #define __MACH_IRQS_H
 
 /* SPEAr3xx IRQ definitions */
-#define IRQ_HW_ACCEL_MOD_0			0
-#define IRQ_INTRCOMM_RAS_ARM			1
-#define IRQ_CPU_GPT1_1				2
-#define IRQ_CPU_GPT1_2				3
-#define IRQ_BASIC_GPT1_1			4
-#define IRQ_BASIC_GPT1_2			5
-#define IRQ_BASIC_GPT2_1			6
-#define IRQ_BASIC_GPT2_2			7
-#define IRQ_BASIC_DMA				8
-#define IRQ_BASIC_SMI				9
-#define IRQ_BASIC_RTC				10
-#define IRQ_BASIC_GPIO				11
-#define IRQ_BASIC_WDT				12
-#define IRQ_DDR_CONTROLLER			13
-#define IRQ_SYS_ERROR				14
-#define IRQ_WAKEUP_RCV				15
-#define IRQ_JPEG				16
-#define IRQ_IRDA				17
-#define IRQ_ADC					18
-#define IRQ_UART				19
-#define IRQ_SSP					20
-#define IRQ_I2C					21
-#define IRQ_MAC_1				22
-#define IRQ_MAC_2				23
-#define IRQ_USB_DEV				24
-#define IRQ_USB_H_OHCI_0			25
-#define IRQ_USB_H_EHCI_0			26
-#define IRQ_USB_H_EHCI_1			IRQ_USB_H_EHCI_0
-#define IRQ_USB_H_OHCI_1			27
-#define IRQ_GEN_RAS_1				28
-#define IRQ_GEN_RAS_2				29
-#define IRQ_GEN_RAS_3				30
-#define IRQ_HW_ACCEL_MOD_1			31
-#define IRQ_VIC_END				32
+#define SPEAR3XX_IRQ_HW_ACCEL_MOD_0		0
+#define SPEAR3XX_IRQ_INTRCOMM_RAS_ARM		1
+#define SPEAR3XX_IRQ_CPU_GPT1_1			2
+#define SPEAR3XX_IRQ_CPU_GPT1_2			3
+#define SPEAR3XX_IRQ_BASIC_GPT1_1		4
+#define SPEAR3XX_IRQ_BASIC_GPT1_2		5
+#define SPEAR3XX_IRQ_BASIC_GPT2_1		6
+#define SPEAR3XX_IRQ_BASIC_GPT2_2		7
+#define SPEAR3XX_IRQ_BASIC_DMA			8
+#define SPEAR3XX_IRQ_BASIC_SMI			9
+#define SPEAR3XX_IRQ_BASIC_RTC			10
+#define SPEAR3XX_IRQ_BASIC_GPIO			11
+#define SPEAR3XX_IRQ_BASIC_WDT			12
+#define SPEAR3XX_IRQ_DDR_CONTROLLER		13
+#define SPEAR3XX_IRQ_SYS_ERROR			14
+#define SPEAR3XX_IRQ_WAKEUP_RCV			15
+#define SPEAR3XX_IRQ_JPEG			16
+#define SPEAR3XX_IRQ_IRDA			17
+#define SPEAR3XX_IRQ_ADC			18
+#define SPEAR3XX_IRQ_UART			19
+#define SPEAR3XX_IRQ_SSP			20
+#define SPEAR3XX_IRQ_I2C			21
+#define SPEAR3XX_IRQ_MAC_1			22
+#define SPEAR3XX_IRQ_MAC_2			23
+#define SPEAR3XX_IRQ_USB_DEV			24
+#define SPEAR3XX_IRQ_USB_H_OHCI_0		25
+#define SPEAR3XX_IRQ_USB_H_EHCI_0		26
+#define SPEAR3XX_IRQ_USB_H_EHCI_1		SPEAR3XX_IRQ_USB_H_EHCI_0
+#define SPEAR3XX_IRQ_USB_H_OHCI_1		27
+#define SPEAR3XX_IRQ_GEN_RAS_1			28
+#define SPEAR3XX_IRQ_GEN_RAS_2			29
+#define SPEAR3XX_IRQ_GEN_RAS_3			30
+#define SPEAR3XX_IRQ_HW_ACCEL_MOD_1		31
+#define SPEAR3XX_IRQ_VIC_END			32
 
-#define VIRQ_START				IRQ_VIC_END
+#define SPEAR3XX_VIRQ_START			SPEAR3XX_IRQ_VIC_END
 
 /* SPEAr300 Virtual irq definitions */
-#ifdef CONFIG_MACH_SPEAR300
 /* IRQs sharing IRQ_GEN_RAS_1 */
-#define VIRQ_IT_PERS_S				(VIRQ_START + 0)
-#define VIRQ_IT_CHANGE_S			(VIRQ_START + 1)
-#define VIRQ_I2S				(VIRQ_START + 2)
-#define VIRQ_TDM				(VIRQ_START + 3)
-#define VIRQ_CAMERA_L				(VIRQ_START + 4)
-#define VIRQ_CAMERA_F				(VIRQ_START + 5)
-#define VIRQ_CAMERA_V				(VIRQ_START + 6)
-#define VIRQ_KEYBOARD				(VIRQ_START + 7)
-#define VIRQ_GPIO1				(VIRQ_START + 8)
+#define SPEAR300_VIRQ_IT_PERS_S			(SPEAR3XX_VIRQ_START + 0)
+#define SPEAR300_VIRQ_IT_CHANGE_S		(SPEAR3XX_VIRQ_START + 1)
+#define SPEAR300_VIRQ_I2S			(SPEAR3XX_VIRQ_START + 2)
+#define SPEAR300_VIRQ_TDM			(SPEAR3XX_VIRQ_START + 3)
+#define SPEAR300_VIRQ_CAMERA_L			(SPEAR3XX_VIRQ_START + 4)
+#define SPEAR300_VIRQ_CAMERA_F			(SPEAR3XX_VIRQ_START + 5)
+#define SPEAR300_VIRQ_CAMERA_V			(SPEAR3XX_VIRQ_START + 6)
+#define SPEAR300_VIRQ_KEYBOARD			(SPEAR3XX_VIRQ_START + 7)
+#define SPEAR300_VIRQ_GPIO1			(SPEAR3XX_VIRQ_START + 8)
 
 /* IRQs sharing IRQ_GEN_RAS_3 */
-#define IRQ_CLCD				IRQ_GEN_RAS_3
+#define SPEAR300_IRQ_CLCD			SPEAR3XX_IRQ_GEN_RAS_3
 
 /* IRQs sharing IRQ_INTRCOMM_RAS_ARM */
-#define IRQ_SDHCI				IRQ_INTRCOMM_RAS_ARM
-
-/* GPIO pins virtual irqs */
-#define SPEAR_GPIO_INT_BASE			(VIRQ_START + 9)
-#define SPEAR_GPIO1_INT_BASE			(SPEAR_GPIO_INT_BASE + 8)
-#define SPEAR_GPIO_INT_END			(SPEAR_GPIO1_INT_BASE + 8)
+#define SPEAR300_IRQ_SDHCI			SPEAR3XX_IRQ_INTRCOMM_RAS_ARM
 
 /* SPEAr310 Virtual irq definitions */
-#elif defined(CONFIG_MACH_SPEAR310)
 /* IRQs sharing IRQ_GEN_RAS_1 */
-#define VIRQ_SMII0				(VIRQ_START + 0)
-#define VIRQ_SMII1				(VIRQ_START + 1)
-#define VIRQ_SMII2				(VIRQ_START + 2)
-#define VIRQ_SMII3				(VIRQ_START + 3)
-#define VIRQ_WAKEUP_SMII0			(VIRQ_START + 4)
-#define VIRQ_WAKEUP_SMII1			(VIRQ_START + 5)
-#define VIRQ_WAKEUP_SMII2			(VIRQ_START + 6)
-#define VIRQ_WAKEUP_SMII3			(VIRQ_START + 7)
+#define SPEAR310_VIRQ_SMII0			(SPEAR3XX_VIRQ_START + 0)
+#define SPEAR310_VIRQ_SMII1			(SPEAR3XX_VIRQ_START + 1)
+#define SPEAR310_VIRQ_SMII2			(SPEAR3XX_VIRQ_START + 2)
+#define SPEAR310_VIRQ_SMII3			(SPEAR3XX_VIRQ_START + 3)
+#define SPEAR310_VIRQ_WAKEUP_SMII0		(SPEAR3XX_VIRQ_START + 4)
+#define SPEAR310_VIRQ_WAKEUP_SMII1		(SPEAR3XX_VIRQ_START + 5)
+#define SPEAR310_VIRQ_WAKEUP_SMII2		(SPEAR3XX_VIRQ_START + 6)
+#define SPEAR310_VIRQ_WAKEUP_SMII3		(SPEAR3XX_VIRQ_START + 7)
 
 /* IRQs sharing IRQ_GEN_RAS_2 */
-#define VIRQ_UART1				(VIRQ_START + 8)
-#define VIRQ_UART2				(VIRQ_START + 9)
-#define VIRQ_UART3				(VIRQ_START + 10)
-#define VIRQ_UART4				(VIRQ_START + 11)
-#define VIRQ_UART5				(VIRQ_START + 12)
+#define SPEAR310_VIRQ_UART1			(SPEAR3XX_VIRQ_START + 8)
+#define SPEAR310_VIRQ_UART2			(SPEAR3XX_VIRQ_START + 9)
+#define SPEAR310_VIRQ_UART3			(SPEAR3XX_VIRQ_START + 10)
+#define SPEAR310_VIRQ_UART4			(SPEAR3XX_VIRQ_START + 11)
+#define SPEAR310_VIRQ_UART5			(SPEAR3XX_VIRQ_START + 12)
 
 /* IRQs sharing IRQ_GEN_RAS_3 */
-#define VIRQ_EMI				(VIRQ_START + 13)
-#define VIRQ_PLGPIO				(VIRQ_START + 14)
+#define SPEAR310_VIRQ_EMI			(SPEAR3XX_VIRQ_START + 13)
+#define SPEAR310_VIRQ_PLGPIO			(SPEAR3XX_VIRQ_START + 14)
 
 /* IRQs sharing IRQ_INTRCOMM_RAS_ARM */
-#define VIRQ_TDM_HDLC				(VIRQ_START + 15)
-#define VIRQ_RS485_0				(VIRQ_START + 16)
-#define VIRQ_RS485_1				(VIRQ_START + 17)
-
-/* GPIO pins virtual irqs */
-#define SPEAR_GPIO_INT_BASE			(VIRQ_START + 18)
+#define SPEAR310_VIRQ_TDM_HDLC			(SPEAR3XX_VIRQ_START + 15)
+#define SPEAR310_VIRQ_RS485_0			(SPEAR3XX_VIRQ_START + 16)
+#define SPEAR310_VIRQ_RS485_1			(SPEAR3XX_VIRQ_START + 17)
 
 /* SPEAr320 Virtual irq definitions */
-#else
 /* IRQs sharing IRQ_GEN_RAS_1 */
-#define VIRQ_EMI				(VIRQ_START + 0)
-#define VIRQ_CLCD				(VIRQ_START + 1)
-#define VIRQ_SPP				(VIRQ_START + 2)
+#define SPEAR320_VIRQ_EMI			(SPEAR3XX_VIRQ_START + 0)
+#define SPEAR320_VIRQ_CLCD			(SPEAR3XX_VIRQ_START + 1)
+#define SPEAR320_VIRQ_SPP			(SPEAR3XX_VIRQ_START + 2)
 
 /* IRQs sharing IRQ_GEN_RAS_2 */
-#define IRQ_SDHCI				IRQ_GEN_RAS_2
+#define SPEAR320_IRQ_SDHCI			SPEAR3XX_IRQ_GEN_RAS_2
 
 /* IRQs sharing IRQ_GEN_RAS_3 */
-#define VIRQ_PLGPIO				(VIRQ_START + 3)
-#define VIRQ_I2S_PLAY				(VIRQ_START + 4)
-#define VIRQ_I2S_REC				(VIRQ_START + 5)
+#define SPEAR320_VIRQ_PLGPIO			(SPEAR3XX_VIRQ_START + 3)
+#define SPEAR320_VIRQ_I2S_PLAY			(SPEAR3XX_VIRQ_START + 4)
+#define SPEAR320_VIRQ_I2S_REC			(SPEAR3XX_VIRQ_START + 5)
 
 /* IRQs sharing IRQ_INTRCOMM_RAS_ARM */
-#define VIRQ_CANU				(VIRQ_START + 6)
-#define VIRQ_CANL				(VIRQ_START + 7)
-#define VIRQ_UART1				(VIRQ_START + 8)
-#define VIRQ_UART2				(VIRQ_START + 9)
-#define VIRQ_SSP1				(VIRQ_START + 10)
-#define VIRQ_SSP2				(VIRQ_START + 11)
-#define VIRQ_SMII0				(VIRQ_START + 12)
-#define VIRQ_MII1_SMII1				(VIRQ_START + 13)
-#define VIRQ_WAKEUP_SMII0			(VIRQ_START + 14)
-#define VIRQ_WAKEUP_MII1_SMII1			(VIRQ_START + 15)
-#define VIRQ_I2C				(VIRQ_START + 16)
-
-/* GPIO pins virtual irqs */
-#define SPEAR_GPIO_INT_BASE			(VIRQ_START + 17)
+#define SPEAR320_VIRQ_CANU			(SPEAR3XX_VIRQ_START + 6)
+#define SPEAR320_VIRQ_CANL			(SPEAR3XX_VIRQ_START + 7)
+#define SPEAR320_VIRQ_UART1			(SPEAR3XX_VIRQ_START + 8)
+#define SPEAR320_VIRQ_UART2			(SPEAR3XX_VIRQ_START + 9)
+#define SPEAR320_VIRQ_SSP1			(SPEAR3XX_VIRQ_START + 10)
+#define SPEAR320_VIRQ_SSP2			(SPEAR3XX_VIRQ_START + 11)
+#define SPEAR320_VIRQ_SMII0			(SPEAR3XX_VIRQ_START + 12)
+#define SPEAR320_VIRQ_MII1_SMII1		(SPEAR3XX_VIRQ_START + 13)
+#define SPEAR320_VIRQ_WAKEUP_SMII0		(SPEAR3XX_VIRQ_START + 14)
+#define SPEAR320_VIRQ_WAKEUP_MII1_SMII1		(SPEAR3XX_VIRQ_START + 15)
+#define SPEAR320_VIRQ_I2C1			(SPEAR3XX_VIRQ_START + 16)
 
+/*
+ * GPIO pins virtual irqs
+ * Use the lowest number for the GPIO virtual IRQs base on which subarchs
+ * we have compiled in
+ */
+#if defined(CONFIG_MACH_SPEAR310)
+#define SPEAR3XX_GPIO_INT_BASE			(SPEAR3XX_VIRQ_START + 18)
+#elif defined(CONFIG_MACH_SPEAR320)
+#define SPEAR3XX_GPIO_INT_BASE			(SPEAR3XX_VIRQ_START + 17)
+#else
+#define SPEAR3XX_GPIO_INT_BASE			(SPEAR3XX_VIRQ_START + 9)
 #endif
 
-/* PLGPIO Virtual IRQs */
+#define SPEAR300_GPIO1_INT_BASE			(SPEAR3XX_GPIO_INT_BASE + 8)
+#define SPEAR3XX_PLGPIO_COUNT	102
+
 #if defined(CONFIG_MACH_SPEAR310) || defined(CONFIG_MACH_SPEAR320)
-#define SPEAR_PLGPIO_INT_BASE			(SPEAR_GPIO_INT_BASE + 8)
-#define SPEAR_GPIO_INT_END			(SPEAR_PLGPIO_INT_BASE + 102)
+#define SPEAR3XX_PLGPIO_INT_BASE		(SPEAR3XX_GPIO_INT_BASE + 8)
+#define SPEAR3XX_GPIO_INT_END			(SPEAR3XX_PLGPIO_INT_BASE + \
+							SPEAR3XX_PLGPIO_COUNT)
+#else
+#define SPEAR3XX_GPIO_INT_END	(SPEAR300_GPIO1_INT_BASE + 8)
 #endif
 
-#define VIRQ_END				SPEAR_GPIO_INT_END
-#define NR_IRQS					VIRQ_END
+#define SPEAR3XX_VIRQ_END	SPEAR3XX_GPIO_INT_END
+#define NR_IRQS			SPEAR3XX_VIRQ_END
 
 #endif /* __MACH_IRQS_H */
diff -druN linux-2.6.39-libre/arch/arm/mach-spear3xx/include/mach/spear300.h linux-3.0-rc7-libre/arch/arm/mach-spear3xx/include/mach/spear300.h
--- linux-2.6.39-libre/arch/arm/mach-spear3xx/include/mach/spear300.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-spear3xx/include/mach/spear300.h	2011-07-11 19:51:52.000000000 -0400
@@ -20,19 +20,19 @@
 #define SPEAR300_TELECOM_BASE		UL(0x50000000)
 
 /* Interrupt registers offsets and masks */
-#define INT_ENB_MASK_REG		0x54
-#define INT_STS_MASK_REG		0x58
-#define IT_PERS_S_IRQ_MASK		(1 << 0)
-#define IT_CHANGE_S_IRQ_MASK		(1 << 1)
-#define I2S_IRQ_MASK			(1 << 2)
-#define TDM_IRQ_MASK			(1 << 3)
-#define CAMERA_L_IRQ_MASK		(1 << 4)
-#define CAMERA_F_IRQ_MASK		(1 << 5)
-#define CAMERA_V_IRQ_MASK		(1 << 6)
-#define KEYBOARD_IRQ_MASK		(1 << 7)
-#define GPIO1_IRQ_MASK			(1 << 8)
+#define SPEAR300_INT_ENB_MASK_REG	0x54
+#define SPEAR300_INT_STS_MASK_REG	0x58
+#define SPEAR300_IT_PERS_S_IRQ_MASK	(1 << 0)
+#define SPEAR300_IT_CHANGE_S_IRQ_MASK	(1 << 1)
+#define SPEAR300_I2S_IRQ_MASK		(1 << 2)
+#define SPEAR300_TDM_IRQ_MASK		(1 << 3)
+#define SPEAR300_CAMERA_L_IRQ_MASK	(1 << 4)
+#define SPEAR300_CAMERA_F_IRQ_MASK	(1 << 5)
+#define SPEAR300_CAMERA_V_IRQ_MASK	(1 << 6)
+#define SPEAR300_KEYBOARD_IRQ_MASK	(1 << 7)
+#define SPEAR300_GPIO1_IRQ_MASK		(1 << 8)
 
-#define SHIRQ_RAS1_MASK			0x1FF
+#define SPEAR300_SHIRQ_RAS1_MASK	0x1FF
 
 #define SPEAR300_CLCD_BASE		UL(0x60000000)
 #define SPEAR300_SDHCI_BASE		UL(0x70000000)
diff -druN linux-2.6.39-libre/arch/arm/mach-spear3xx/include/mach/spear310.h linux-3.0-rc7-libre/arch/arm/mach-spear3xx/include/mach/spear310.h
--- linux-2.6.39-libre/arch/arm/mach-spear3xx/include/mach/spear310.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-spear3xx/include/mach/spear310.h	2011-07-11 19:51:52.000000000 -0400
@@ -29,29 +29,29 @@
 #define SPEAR310_SOC_CONFIG_BASE	UL(0xB4000000)
 
 /* Interrupt registers offsets and masks */
-#define INT_STS_MASK_REG		0x04
-#define SMII0_IRQ_MASK			(1 << 0)
-#define SMII1_IRQ_MASK			(1 << 1)
-#define SMII2_IRQ_MASK			(1 << 2)
-#define SMII3_IRQ_MASK			(1 << 3)
-#define WAKEUP_SMII0_IRQ_MASK		(1 << 4)
-#define WAKEUP_SMII1_IRQ_MASK		(1 << 5)
-#define WAKEUP_SMII2_IRQ_MASK		(1 << 6)
-#define WAKEUP_SMII3_IRQ_MASK		(1 << 7)
-#define UART1_IRQ_MASK			(1 << 8)
-#define UART2_IRQ_MASK			(1 << 9)
-#define UART3_IRQ_MASK			(1 << 10)
-#define UART4_IRQ_MASK			(1 << 11)
-#define UART5_IRQ_MASK			(1 << 12)
-#define EMI_IRQ_MASK			(1 << 13)
-#define TDM_HDLC_IRQ_MASK		(1 << 14)
-#define RS485_0_IRQ_MASK		(1 << 15)
-#define RS485_1_IRQ_MASK		(1 << 16)
+#define SPEAR310_INT_STS_MASK_REG	0x04
+#define SPEAR310_SMII0_IRQ_MASK		(1 << 0)
+#define SPEAR310_SMII1_IRQ_MASK		(1 << 1)
+#define SPEAR310_SMII2_IRQ_MASK		(1 << 2)
+#define SPEAR310_SMII3_IRQ_MASK		(1 << 3)
+#define SPEAR310_WAKEUP_SMII0_IRQ_MASK	(1 << 4)
+#define SPEAR310_WAKEUP_SMII1_IRQ_MASK	(1 << 5)
+#define SPEAR310_WAKEUP_SMII2_IRQ_MASK	(1 << 6)
+#define SPEAR310_WAKEUP_SMII3_IRQ_MASK	(1 << 7)
+#define SPEAR310_UART1_IRQ_MASK		(1 << 8)
+#define SPEAR310_UART2_IRQ_MASK		(1 << 9)
+#define SPEAR310_UART3_IRQ_MASK		(1 << 10)
+#define SPEAR310_UART4_IRQ_MASK		(1 << 11)
+#define SPEAR310_UART5_IRQ_MASK		(1 << 12)
+#define SPEAR310_EMI_IRQ_MASK		(1 << 13)
+#define SPEAR310_TDM_HDLC_IRQ_MASK	(1 << 14)
+#define SPEAR310_RS485_0_IRQ_MASK	(1 << 15)
+#define SPEAR310_RS485_1_IRQ_MASK	(1 << 16)
 
-#define SHIRQ_RAS1_MASK			0x000FF
-#define SHIRQ_RAS2_MASK			0x01F00
-#define SHIRQ_RAS3_MASK			0x02000
-#define SHIRQ_INTRCOMM_RAS_MASK		0x1C000
+#define SPEAR310_SHIRQ_RAS1_MASK	0x000FF
+#define SPEAR310_SHIRQ_RAS2_MASK	0x01F00
+#define SPEAR310_SHIRQ_RAS3_MASK	0x02000
+#define SPEAR310_SHIRQ_INTRCOMM_RAS_MASK	0x1C000
 
 #endif /* __MACH_SPEAR310_H */
 
diff -druN linux-2.6.39-libre/arch/arm/mach-spear3xx/include/mach/spear320.h linux-3.0-rc7-libre/arch/arm/mach-spear3xx/include/mach/spear320.h
--- linux-2.6.39-libre/arch/arm/mach-spear3xx/include/mach/spear320.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-spear3xx/include/mach/spear320.h	2011-07-11 19:51:52.000000000 -0400
@@ -36,31 +36,31 @@
 #define SPEAR320_SOC_CONFIG_BASE	UL(0xB3000000)
 
 /* Interrupt registers offsets and masks */
-#define INT_STS_MASK_REG		0x04
-#define INT_CLR_MASK_REG		0x04
-#define INT_ENB_MASK_REG		0x08
-#define GPIO_IRQ_MASK			(1 << 0)
-#define I2S_PLAY_IRQ_MASK		(1 << 1)
-#define I2S_REC_IRQ_MASK		(1 << 2)
-#define EMI_IRQ_MASK			(1 << 7)
-#define CLCD_IRQ_MASK			(1 << 8)
-#define SPP_IRQ_MASK			(1 << 9)
-#define SDHCI_IRQ_MASK			(1 << 10)
-#define CAN_U_IRQ_MASK			(1 << 11)
-#define CAN_L_IRQ_MASK			(1 << 12)
-#define UART1_IRQ_MASK			(1 << 13)
-#define UART2_IRQ_MASK			(1 << 14)
-#define SSP1_IRQ_MASK			(1 << 15)
-#define SSP2_IRQ_MASK			(1 << 16)
-#define SMII0_IRQ_MASK			(1 << 17)
-#define MII1_SMII1_IRQ_MASK		(1 << 18)
-#define WAKEUP_SMII0_IRQ_MASK		(1 << 19)
-#define WAKEUP_MII1_SMII1_IRQ_MASK	(1 << 20)
-#define I2C1_IRQ_MASK			(1 << 21)
+#define SPEAR320_INT_STS_MASK_REG		0x04
+#define SPEAR320_INT_CLR_MASK_REG		0x04
+#define SPEAR320_INT_ENB_MASK_REG		0x08
+#define SPEAR320_GPIO_IRQ_MASK			(1 << 0)
+#define SPEAR320_I2S_PLAY_IRQ_MASK		(1 << 1)
+#define SPEAR320_I2S_REC_IRQ_MASK		(1 << 2)
+#define SPEAR320_EMI_IRQ_MASK			(1 << 7)
+#define SPEAR320_CLCD_IRQ_MASK			(1 << 8)
+#define SPEAR320_SPP_IRQ_MASK			(1 << 9)
+#define SPEAR320_SDHCI_IRQ_MASK			(1 << 10)
+#define SPEAR320_CAN_U_IRQ_MASK			(1 << 11)
+#define SPEAR320_CAN_L_IRQ_MASK			(1 << 12)
+#define SPEAR320_UART1_IRQ_MASK			(1 << 13)
+#define SPEAR320_UART2_IRQ_MASK			(1 << 14)
+#define SPEAR320_SSP1_IRQ_MASK			(1 << 15)
+#define SPEAR320_SSP2_IRQ_MASK			(1 << 16)
+#define SPEAR320_SMII0_IRQ_MASK			(1 << 17)
+#define SPEAR320_MII1_SMII1_IRQ_MASK		(1 << 18)
+#define SPEAR320_WAKEUP_SMII0_IRQ_MASK		(1 << 19)
+#define SPEAR320_WAKEUP_MII1_SMII1_IRQ_MASK	(1 << 20)
+#define SPEAR320_I2C1_IRQ_MASK			(1 << 21)
 
-#define SHIRQ_RAS1_MASK			0x000380
-#define SHIRQ_RAS3_MASK			0x000007
-#define SHIRQ_INTRCOMM_RAS_MASK		0x3FF800
+#define SPEAR320_SHIRQ_RAS1_MASK		0x000380
+#define SPEAR320_SHIRQ_RAS3_MASK		0x000007
+#define SPEAR320_SHIRQ_INTRCOMM_RAS_MASK	0x3FF800
 
 #endif /* __MACH_SPEAR320_H */
 
diff -druN linux-2.6.39-libre/arch/arm/mach-spear3xx/Kconfig linux-3.0-rc7-libre/arch/arm/mach-spear3xx/Kconfig
--- linux-2.6.39-libre/arch/arm/mach-spear3xx/Kconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-spear3xx/Kconfig	2011-07-11 19:51:52.000000000 -0400
@@ -4,9 +4,26 @@
 
 if ARCH_SPEAR3XX
 
-choice
-	prompt "SPEAr3XX Family"
-	default MACH_SPEAR300
+menu "SPEAr3xx Implementations"
+config BOARD_SPEAR300_EVB
+	bool "SPEAr300 Evaluation Board"
+	select MACH_SPEAR300
+	help
+	  Supports ST SPEAr300 Evaluation Board
+
+config BOARD_SPEAR310_EVB
+	bool "SPEAr310 Evaluation Board"
+	select MACH_SPEAR310
+	help
+	  Supports ST SPEAr310 Evaluation Board
+
+config BOARD_SPEAR320_EVB
+	bool "SPEAr320 Evaluation Board"
+	select MACH_SPEAR320
+	help
+	  Supports ST SPEAr320 Evaluation Board
+
+endmenu
 
 config MACH_SPEAR300
 	bool "SPEAr300"
@@ -23,11 +40,4 @@
 	help
 	  Supports ST SPEAr320 Machine
 
-endchoice
-
-# Adding SPEAr3XX machine specific configuration files
-source "arch/arm/mach-spear3xx/Kconfig300"
-source "arch/arm/mach-spear3xx/Kconfig310"
-source "arch/arm/mach-spear3xx/Kconfig320"
-
 endif #ARCH_SPEAR3XX
diff -druN linux-2.6.39-libre/arch/arm/mach-spear3xx/Kconfig300 linux-3.0-rc7-libre/arch/arm/mach-spear3xx/Kconfig300
--- linux-2.6.39-libre/arch/arm/mach-spear3xx/Kconfig300	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-spear3xx/Kconfig300	1969-12-31 19:00:00.000000000 -0500
@@ -1,17 +0,0 @@
-#
-# SPEAr300 machine configuration file
-#
-
-if MACH_SPEAR300
-
-choice
-	prompt "SPEAr300 Boards"
-	default BOARD_SPEAR300_EVB
-
-config BOARD_SPEAR300_EVB
-	bool "SPEAr300 Evaluation Board"
-	help
-	  Supports ST SPEAr300 Evaluation Board
-endchoice
-
-endif	#MACH_SPEAR300
diff -druN linux-2.6.39-libre/arch/arm/mach-spear3xx/Kconfig310 linux-3.0-rc7-libre/arch/arm/mach-spear3xx/Kconfig310
--- linux-2.6.39-libre/arch/arm/mach-spear3xx/Kconfig310	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-spear3xx/Kconfig310	1969-12-31 19:00:00.000000000 -0500
@@ -1,17 +0,0 @@
-#
-# SPEAr310 machine configuration file
-#
-
-if MACH_SPEAR310
-
-choice
-	prompt "SPEAr310 Boards"
-	default BOARD_SPEAR310_EVB
-
-config BOARD_SPEAR310_EVB
-	bool "SPEAr310 Evaluation Board"
-	help
-	  Supports ST SPEAr310 Evaluation Board
-endchoice
-
-endif	#MACH_SPEAR310
diff -druN linux-2.6.39-libre/arch/arm/mach-spear3xx/Kconfig320 linux-3.0-rc7-libre/arch/arm/mach-spear3xx/Kconfig320
--- linux-2.6.39-libre/arch/arm/mach-spear3xx/Kconfig320	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-spear3xx/Kconfig320	1969-12-31 19:00:00.000000000 -0500
@@ -1,17 +0,0 @@
-#
-# SPEAr320 machine configuration file
-#
-
-if MACH_SPEAR320
-
-choice
-	prompt "SPEAr320 Boards"
-	default BOARD_SPEAR320_EVB
-
-config BOARD_SPEAR320_EVB
-	bool "SPEAr320 Evaluation Board"
-	help
-	  Supports ST SPEAr320 Evaluation Board
-endchoice
-
-endif	#MACH_SPEAR320
diff -druN linux-2.6.39-libre/arch/arm/mach-spear3xx/spear300.c linux-3.0-rc7-libre/arch/arm/mach-spear3xx/spear300.c
--- linux-2.6.39-libre/arch/arm/mach-spear3xx/spear300.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-spear3xx/spear300.c	2011-07-11 19:51:52.000000000 -0400
@@ -40,86 +40,86 @@
 #define CAML_LCD_MODE			(1 << 12)
 #define ALL_MODES			0x1FFF
 
-struct pmx_mode nand_mode = {
+struct pmx_mode spear300_nand_mode = {
 	.id = NAND_MODE,
 	.name = "nand mode",
 	.mask = 0x00,
 };
 
-struct pmx_mode nor_mode = {
+struct pmx_mode spear300_nor_mode = {
 	.id = NOR_MODE,
 	.name = "nor mode",
 	.mask = 0x01,
 };
 
-struct pmx_mode photo_frame_mode = {
+struct pmx_mode spear300_photo_frame_mode = {
 	.id = PHOTO_FRAME_MODE,
 	.name = "photo frame mode",
 	.mask = 0x02,
 };
 
-struct pmx_mode lend_ip_phone_mode = {
+struct pmx_mode spear300_lend_ip_phone_mode = {
 	.id = LEND_IP_PHONE_MODE,
 	.name = "lend ip phone mode",
 	.mask = 0x03,
 };
 
-struct pmx_mode hend_ip_phone_mode = {
+struct pmx_mode spear300_hend_ip_phone_mode = {
 	.id = HEND_IP_PHONE_MODE,
 	.name = "hend ip phone mode",
 	.mask = 0x04,
 };
 
-struct pmx_mode lend_wifi_phone_mode = {
+struct pmx_mode spear300_lend_wifi_phone_mode = {
 	.id = LEND_WIFI_PHONE_MODE,
 	.name = "lend wifi phone mode",
 	.mask = 0x05,
 };
 
-struct pmx_mode hend_wifi_phone_mode = {
+struct pmx_mode spear300_hend_wifi_phone_mode = {
 	.id = HEND_WIFI_PHONE_MODE,
 	.name = "hend wifi phone mode",
 	.mask = 0x06,
 };
 
-struct pmx_mode ata_pabx_wi2s_mode = {
+struct pmx_mode spear300_ata_pabx_wi2s_mode = {
 	.id = ATA_PABX_WI2S_MODE,
 	.name = "ata pabx wi2s mode",
 	.mask = 0x07,
 };
 
-struct pmx_mode ata_pabx_i2s_mode = {
+struct pmx_mode spear300_ata_pabx_i2s_mode = {
 	.id = ATA_PABX_I2S_MODE,
 	.name = "ata pabx i2s mode",
 	.mask = 0x08,
 };
 
-struct pmx_mode caml_lcdw_mode = {
+struct pmx_mode spear300_caml_lcdw_mode = {
 	.id = CAML_LCDW_MODE,
 	.name = "caml lcdw mode",
 	.mask = 0x0C,
 };
 
-struct pmx_mode camu_lcd_mode = {
+struct pmx_mode spear300_camu_lcd_mode = {
 	.id = CAMU_LCD_MODE,
 	.name = "camu lcd mode",
 	.mask = 0x0D,
 };
 
-struct pmx_mode camu_wlcd_mode = {
+struct pmx_mode spear300_camu_wlcd_mode = {
 	.id = CAMU_WLCD_MODE,
 	.name = "camu wlcd mode",
 	.mask = 0x0E,
 };
 
-struct pmx_mode caml_lcd_mode = {
+struct pmx_mode spear300_caml_lcd_mode = {
 	.id = CAML_LCD_MODE,
 	.name = "caml lcd mode",
 	.mask = 0x0F,
 };
 
 /* devices */
-struct pmx_dev_mode pmx_fsmc_2_chips_modes[] = {
+static struct pmx_dev_mode pmx_fsmc_2_chips_modes[] = {
 	{
 		.ids = NAND_MODE | NOR_MODE | PHOTO_FRAME_MODE |
 			ATA_PABX_WI2S_MODE | ATA_PABX_I2S_MODE,
@@ -127,14 +127,14 @@
 	},
 };
 
-struct pmx_dev pmx_fsmc_2_chips = {
+struct pmx_dev spear300_pmx_fsmc_2_chips = {
 	.name = "fsmc_2_chips",
 	.modes = pmx_fsmc_2_chips_modes,
 	.mode_count = ARRAY_SIZE(pmx_fsmc_2_chips_modes),
 	.enb_on_reset = 1,
 };
 
-struct pmx_dev_mode pmx_fsmc_4_chips_modes[] = {
+static struct pmx_dev_mode pmx_fsmc_4_chips_modes[] = {
 	{
 		.ids = NAND_MODE | NOR_MODE | PHOTO_FRAME_MODE |
 			ATA_PABX_WI2S_MODE | ATA_PABX_I2S_MODE,
@@ -142,14 +142,14 @@
 	},
 };
 
-struct pmx_dev pmx_fsmc_4_chips = {
+struct pmx_dev spear300_pmx_fsmc_4_chips = {
 	.name = "fsmc_4_chips",
 	.modes = pmx_fsmc_4_chips_modes,
 	.mode_count = ARRAY_SIZE(pmx_fsmc_4_chips_modes),
 	.enb_on_reset = 1,
 };
 
-struct pmx_dev_mode pmx_keyboard_modes[] = {
+static struct pmx_dev_mode pmx_keyboard_modes[] = {
 	{
 		.ids = LEND_IP_PHONE_MODE | HEND_IP_PHONE_MODE |
 			LEND_WIFI_PHONE_MODE | HEND_WIFI_PHONE_MODE |
@@ -159,14 +159,14 @@
 	},
 };
 
-struct pmx_dev pmx_keyboard = {
+struct pmx_dev spear300_pmx_keyboard = {
 	.name = "keyboard",
 	.modes = pmx_keyboard_modes,
 	.mode_count = ARRAY_SIZE(pmx_keyboard_modes),
 	.enb_on_reset = 1,
 };
 
-struct pmx_dev_mode pmx_clcd_modes[] = {
+static struct pmx_dev_mode pmx_clcd_modes[] = {
 	{
 		.ids = PHOTO_FRAME_MODE,
 		.mask = PMX_TIMER_1_2_MASK | PMX_TIMER_3_4_MASK ,
@@ -177,14 +177,14 @@
 	},
 };
 
-struct pmx_dev pmx_clcd = {
+struct pmx_dev spear300_pmx_clcd = {
 	.name = "clcd",
 	.modes = pmx_clcd_modes,
 	.mode_count = ARRAY_SIZE(pmx_clcd_modes),
 	.enb_on_reset = 1,
 };
 
-struct pmx_dev_mode pmx_telecom_gpio_modes[] = {
+static struct pmx_dev_mode pmx_telecom_gpio_modes[] = {
 	{
 		.ids = PHOTO_FRAME_MODE | CAMU_LCD_MODE | CAML_LCD_MODE,
 		.mask = PMX_MII_MASK,
@@ -204,14 +204,14 @@
 	},
 };
 
-struct pmx_dev pmx_telecom_gpio = {
+struct pmx_dev spear300_pmx_telecom_gpio = {
 	.name = "telecom_gpio",
 	.modes = pmx_telecom_gpio_modes,
 	.mode_count = ARRAY_SIZE(pmx_telecom_gpio_modes),
 	.enb_on_reset = 1,
 };
 
-struct pmx_dev_mode pmx_telecom_tdm_modes[] = {
+static struct pmx_dev_mode pmx_telecom_tdm_modes[] = {
 	{
 		.ids = PHOTO_FRAME_MODE | LEND_IP_PHONE_MODE |
 			HEND_IP_PHONE_MODE | LEND_WIFI_PHONE_MODE
@@ -222,14 +222,14 @@
 	},
 };
 
-struct pmx_dev pmx_telecom_tdm = {
+struct pmx_dev spear300_pmx_telecom_tdm = {
 	.name = "telecom_tdm",
 	.modes = pmx_telecom_tdm_modes,
 	.mode_count = ARRAY_SIZE(pmx_telecom_tdm_modes),
 	.enb_on_reset = 1,
 };
 
-struct pmx_dev_mode pmx_telecom_spi_cs_i2c_clk_modes[] = {
+static struct pmx_dev_mode pmx_telecom_spi_cs_i2c_clk_modes[] = {
 	{
 		.ids = LEND_IP_PHONE_MODE | HEND_IP_PHONE_MODE |
 			LEND_WIFI_PHONE_MODE | HEND_WIFI_PHONE_MODE
@@ -239,14 +239,14 @@
 	},
 };
 
-struct pmx_dev pmx_telecom_spi_cs_i2c_clk = {
+struct pmx_dev spear300_pmx_telecom_spi_cs_i2c_clk = {
 	.name = "telecom_spi_cs_i2c_clk",
 	.modes = pmx_telecom_spi_cs_i2c_clk_modes,
 	.mode_count = ARRAY_SIZE(pmx_telecom_spi_cs_i2c_clk_modes),
 	.enb_on_reset = 1,
 };
 
-struct pmx_dev_mode pmx_telecom_camera_modes[] = {
+static struct pmx_dev_mode pmx_telecom_camera_modes[] = {
 	{
 		.ids = CAML_LCDW_MODE | CAML_LCD_MODE,
 		.mask = PMX_MII_MASK,
@@ -256,14 +256,14 @@
 	},
 };
 
-struct pmx_dev pmx_telecom_camera = {
+struct pmx_dev spear300_pmx_telecom_camera = {
 	.name = "telecom_camera",
 	.modes = pmx_telecom_camera_modes,
 	.mode_count = ARRAY_SIZE(pmx_telecom_camera_modes),
 	.enb_on_reset = 1,
 };
 
-struct pmx_dev_mode pmx_telecom_dac_modes[] = {
+static struct pmx_dev_mode pmx_telecom_dac_modes[] = {
 	{
 		.ids = ATA_PABX_I2S_MODE | CAML_LCDW_MODE | CAMU_LCD_MODE
 			| CAMU_WLCD_MODE | CAML_LCD_MODE,
@@ -271,14 +271,14 @@
 	},
 };
 
-struct pmx_dev pmx_telecom_dac = {
+struct pmx_dev spear300_pmx_telecom_dac = {
 	.name = "telecom_dac",
 	.modes = pmx_telecom_dac_modes,
 	.mode_count = ARRAY_SIZE(pmx_telecom_dac_modes),
 	.enb_on_reset = 1,
 };
 
-struct pmx_dev_mode pmx_telecom_i2s_modes[] = {
+static struct pmx_dev_mode pmx_telecom_i2s_modes[] = {
 	{
 		.ids = LEND_IP_PHONE_MODE | HEND_IP_PHONE_MODE
 			| LEND_WIFI_PHONE_MODE | HEND_WIFI_PHONE_MODE |
@@ -288,14 +288,14 @@
 	},
 };
 
-struct pmx_dev pmx_telecom_i2s = {
+struct pmx_dev spear300_pmx_telecom_i2s = {
 	.name = "telecom_i2s",
 	.modes = pmx_telecom_i2s_modes,
 	.mode_count = ARRAY_SIZE(pmx_telecom_i2s_modes),
 	.enb_on_reset = 1,
 };
 
-struct pmx_dev_mode pmx_telecom_boot_pins_modes[] = {
+static struct pmx_dev_mode pmx_telecom_boot_pins_modes[] = {
 	{
 		.ids = NAND_MODE | NOR_MODE,
 		.mask = PMX_UART0_MODEM_MASK | PMX_TIMER_1_2_MASK |
@@ -303,14 +303,14 @@
 	},
 };
 
-struct pmx_dev pmx_telecom_boot_pins = {
+struct pmx_dev spear300_pmx_telecom_boot_pins = {
 	.name = "telecom_boot_pins",
 	.modes = pmx_telecom_boot_pins_modes,
 	.mode_count = ARRAY_SIZE(pmx_telecom_boot_pins_modes),
 	.enb_on_reset = 1,
 };
 
-struct pmx_dev_mode pmx_telecom_sdhci_4bit_modes[] = {
+static struct pmx_dev_mode pmx_telecom_sdhci_4bit_modes[] = {
 	{
 		.ids = PHOTO_FRAME_MODE | LEND_IP_PHONE_MODE |
 			HEND_IP_PHONE_MODE | LEND_WIFI_PHONE_MODE |
@@ -323,14 +323,14 @@
 	},
 };
 
-struct pmx_dev pmx_telecom_sdhci_4bit = {
+struct pmx_dev spear300_pmx_telecom_sdhci_4bit = {
 	.name = "telecom_sdhci_4bit",
 	.modes = pmx_telecom_sdhci_4bit_modes,
 	.mode_count = ARRAY_SIZE(pmx_telecom_sdhci_4bit_modes),
 	.enb_on_reset = 1,
 };
 
-struct pmx_dev_mode pmx_telecom_sdhci_8bit_modes[] = {
+static struct pmx_dev_mode pmx_telecom_sdhci_8bit_modes[] = {
 	{
 		.ids = PHOTO_FRAME_MODE | LEND_IP_PHONE_MODE |
 			HEND_IP_PHONE_MODE | LEND_WIFI_PHONE_MODE |
@@ -342,14 +342,14 @@
 	},
 };
 
-struct pmx_dev pmx_telecom_sdhci_8bit = {
+struct pmx_dev spear300_pmx_telecom_sdhci_8bit = {
 	.name = "telecom_sdhci_8bit",
 	.modes = pmx_telecom_sdhci_8bit_modes,
 	.mode_count = ARRAY_SIZE(pmx_telecom_sdhci_8bit_modes),
 	.enb_on_reset = 1,
 };
 
-struct pmx_dev_mode pmx_gpio1_modes[] = {
+static struct pmx_dev_mode pmx_gpio1_modes[] = {
 	{
 		.ids = PHOTO_FRAME_MODE,
 		.mask = PMX_UART0_MODEM_MASK | PMX_TIMER_1_2_MASK |
@@ -357,7 +357,7 @@
 	},
 };
 
-struct pmx_dev pmx_gpio1 = {
+struct pmx_dev spear300_pmx_gpio1 = {
 	.name = "arm gpio1",
 	.modes = pmx_gpio1_modes,
 	.mode_count = ARRAY_SIZE(pmx_gpio1_modes),
@@ -365,60 +365,60 @@
 };
 
 /* pmx driver structure */
-struct pmx_driver pmx_driver = {
+static struct pmx_driver pmx_driver = {
 	.mode_reg = {.offset = MODE_CONFIG_REG, .mask = 0x0000000f},
 	.mux_reg = {.offset = PAD_MUX_CONFIG_REG, .mask = 0x00007fff},
 };
 
 /* spear3xx shared irq */
-struct shirq_dev_config shirq_ras1_config[] = {
+static struct shirq_dev_config shirq_ras1_config[] = {
 	{
-		.virq = VIRQ_IT_PERS_S,
-		.enb_mask = IT_PERS_S_IRQ_MASK,
-		.status_mask = IT_PERS_S_IRQ_MASK,
+		.virq = SPEAR300_VIRQ_IT_PERS_S,
+		.enb_mask = SPEAR300_IT_PERS_S_IRQ_MASK,
+		.status_mask = SPEAR300_IT_PERS_S_IRQ_MASK,
 	}, {
-		.virq = VIRQ_IT_CHANGE_S,
-		.enb_mask = IT_CHANGE_S_IRQ_MASK,
-		.status_mask = IT_CHANGE_S_IRQ_MASK,
+		.virq = SPEAR300_VIRQ_IT_CHANGE_S,
+		.enb_mask = SPEAR300_IT_CHANGE_S_IRQ_MASK,
+		.status_mask = SPEAR300_IT_CHANGE_S_IRQ_MASK,
 	}, {
-		.virq = VIRQ_I2S,
-		.enb_mask = I2S_IRQ_MASK,
-		.status_mask = I2S_IRQ_MASK,
+		.virq = SPEAR300_VIRQ_I2S,
+		.enb_mask = SPEAR300_I2S_IRQ_MASK,
+		.status_mask = SPEAR300_I2S_IRQ_MASK,
 	}, {
-		.virq = VIRQ_TDM,
-		.enb_mask = TDM_IRQ_MASK,
-		.status_mask = TDM_IRQ_MASK,
+		.virq = SPEAR300_VIRQ_TDM,
+		.enb_mask = SPEAR300_TDM_IRQ_MASK,
+		.status_mask = SPEAR300_TDM_IRQ_MASK,
 	}, {
-		.virq = VIRQ_CAMERA_L,
-		.enb_mask = CAMERA_L_IRQ_MASK,
-		.status_mask = CAMERA_L_IRQ_MASK,
+		.virq = SPEAR300_VIRQ_CAMERA_L,
+		.enb_mask = SPEAR300_CAMERA_L_IRQ_MASK,
+		.status_mask = SPEAR300_CAMERA_L_IRQ_MASK,
 	}, {
-		.virq = VIRQ_CAMERA_F,
-		.enb_mask = CAMERA_F_IRQ_MASK,
-		.status_mask = CAMERA_F_IRQ_MASK,
+		.virq = SPEAR300_VIRQ_CAMERA_F,
+		.enb_mask = SPEAR300_CAMERA_F_IRQ_MASK,
+		.status_mask = SPEAR300_CAMERA_F_IRQ_MASK,
 	}, {
-		.virq = VIRQ_CAMERA_V,
-		.enb_mask = CAMERA_V_IRQ_MASK,
-		.status_mask = CAMERA_V_IRQ_MASK,
+		.virq = SPEAR300_VIRQ_CAMERA_V,
+		.enb_mask = SPEAR300_CAMERA_V_IRQ_MASK,
+		.status_mask = SPEAR300_CAMERA_V_IRQ_MASK,
 	}, {
-		.virq = VIRQ_KEYBOARD,
-		.enb_mask = KEYBOARD_IRQ_MASK,
-		.status_mask = KEYBOARD_IRQ_MASK,
+		.virq = SPEAR300_VIRQ_KEYBOARD,
+		.enb_mask = SPEAR300_KEYBOARD_IRQ_MASK,
+		.status_mask = SPEAR300_KEYBOARD_IRQ_MASK,
 	}, {
-		.virq = VIRQ_GPIO1,
-		.enb_mask = GPIO1_IRQ_MASK,
-		.status_mask = GPIO1_IRQ_MASK,
+		.virq = SPEAR300_VIRQ_GPIO1,
+		.enb_mask = SPEAR300_GPIO1_IRQ_MASK,
+		.status_mask = SPEAR300_GPIO1_IRQ_MASK,
 	},
 };
 
-struct spear_shirq shirq_ras1 = {
-	.irq = IRQ_GEN_RAS_1,
+static struct spear_shirq shirq_ras1 = {
+	.irq = SPEAR3XX_IRQ_GEN_RAS_1,
 	.dev_config = shirq_ras1_config,
 	.dev_count = ARRAY_SIZE(shirq_ras1_config),
 	.regs = {
-		.enb_reg = INT_ENB_MASK_REG,
-		.status_reg = INT_STS_MASK_REG,
-		.status_reg_mask = SHIRQ_RAS1_MASK,
+		.enb_reg = SPEAR300_INT_ENB_MASK_REG,
+		.status_reg = SPEAR300_INT_STS_MASK_REG,
+		.status_reg_mask = SPEAR300_SHIRQ_RAS1_MASK,
 		.clear_reg = -1,
 	},
 };
@@ -427,10 +427,10 @@
 /* arm gpio1 device registration */
 static struct pl061_platform_data gpio1_plat_data = {
 	.gpio_base	= 8,
-	.irq_base	= SPEAR_GPIO1_INT_BASE,
+	.irq_base	= SPEAR300_GPIO1_INT_BASE,
 };
 
-struct amba_device gpio1_device = {
+struct amba_device spear300_gpio1_device = {
 	.dev = {
 		.init_name = "gpio1",
 		.platform_data = &gpio1_plat_data,
@@ -440,11 +440,12 @@
 		.end = SPEAR300_GPIO_BASE + SZ_4K - 1,
 		.flags = IORESOURCE_MEM,
 	},
-	.irq = {VIRQ_GPIO1, NO_IRQ},
+	.irq = {SPEAR300_VIRQ_GPIO1, NO_IRQ},
 };
 
 /* spear300 routines */
-void __init spear300_init(void)
+void __init spear300_init(struct pmx_mode *pmx_mode, struct pmx_dev **pmx_devs,
+		u8 pmx_dev_count)
 {
 	int ret = 0;
 
@@ -460,6 +461,10 @@
 	}
 
 	/* pmx initialization */
+	pmx_driver.mode = pmx_mode;
+	pmx_driver.devs = pmx_devs;
+	pmx_driver.devs_count = pmx_dev_count;
+
 	pmx_driver.base = ioremap(SPEAR300_SOC_CONFIG_BASE, SZ_4K);
 	if (pmx_driver.base) {
 		ret = pmx_register(&pmx_driver);
diff -druN linux-2.6.39-libre/arch/arm/mach-spear3xx/spear300_evb.c linux-3.0-rc7-libre/arch/arm/mach-spear3xx/spear300_evb.c
--- linux-2.6.39-libre/arch/arm/mach-spear3xx/spear300_evb.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-spear3xx/spear300_evb.c	2011-07-11 19:51:52.000000000 -0400
@@ -19,26 +19,26 @@
 /* padmux devices to enable */
 static struct pmx_dev *pmx_devs[] = {
 	/* spear3xx specific devices */
-	&pmx_i2c,
-	&pmx_ssp_cs,
-	&pmx_ssp,
-	&pmx_mii,
-	&pmx_uart0,
+	&spear3xx_pmx_i2c,
+	&spear3xx_pmx_ssp_cs,
+	&spear3xx_pmx_ssp,
+	&spear3xx_pmx_mii,
+	&spear3xx_pmx_uart0,
 
 	/* spear300 specific devices */
-	&pmx_fsmc_2_chips,
-	&pmx_clcd,
-	&pmx_telecom_sdhci_4bit,
-	&pmx_gpio1,
+	&spear300_pmx_fsmc_2_chips,
+	&spear300_pmx_clcd,
+	&spear300_pmx_telecom_sdhci_4bit,
+	&spear300_pmx_gpio1,
 };
 
 static struct amba_device *amba_devs[] __initdata = {
 	/* spear3xx specific devices */
-	&gpio_device,
-	&uart_device,
+	&spear3xx_gpio_device,
+	&spear3xx_uart_device,
 
 	/* spear300 specific devices */
-	&gpio1_device,
+	&spear300_gpio1_device,
 };
 
 static struct platform_device *plat_devs[] __initdata = {
@@ -51,13 +51,9 @@
 {
 	unsigned int i;
 
-	/* padmux initialization, must be done before spear300_init */
-	pmx_driver.mode = &photo_frame_mode;
-	pmx_driver.devs = pmx_devs;
-	pmx_driver.devs_count = ARRAY_SIZE(pmx_devs);
-
 	/* call spear300 machine init function */
-	spear300_init();
+	spear300_init(&spear300_photo_frame_mode, pmx_devs,
+			ARRAY_SIZE(pmx_devs));
 
 	/* Add Platform Devices */
 	platform_add_devices(plat_devs, ARRAY_SIZE(plat_devs));
diff -druN linux-2.6.39-libre/arch/arm/mach-spear3xx/spear310.c linux-3.0-rc7-libre/arch/arm/mach-spear3xx/spear310.c
--- linux-2.6.39-libre/arch/arm/mach-spear3xx/spear310.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-spear3xx/spear310.c	2011-07-11 19:51:52.000000000 -0400
@@ -22,112 +22,112 @@
 #define PAD_MUX_CONFIG_REG	0x08
 
 /* devices */
-struct pmx_dev_mode pmx_emi_cs_0_1_4_5_modes[] = {
+static struct pmx_dev_mode pmx_emi_cs_0_1_4_5_modes[] = {
 	{
 		.ids = 0x00,
 		.mask = PMX_TIMER_3_4_MASK,
 	},
 };
 
-struct pmx_dev pmx_emi_cs_0_1_4_5 = {
+struct pmx_dev spear310_pmx_emi_cs_0_1_4_5 = {
 	.name = "emi_cs_0_1_4_5",
 	.modes = pmx_emi_cs_0_1_4_5_modes,
 	.mode_count = ARRAY_SIZE(pmx_emi_cs_0_1_4_5_modes),
 	.enb_on_reset = 1,
 };
 
-struct pmx_dev_mode pmx_emi_cs_2_3_modes[] = {
+static struct pmx_dev_mode pmx_emi_cs_2_3_modes[] = {
 	{
 		.ids = 0x00,
 		.mask = PMX_TIMER_1_2_MASK,
 	},
 };
 
-struct pmx_dev pmx_emi_cs_2_3 = {
+struct pmx_dev spear310_pmx_emi_cs_2_3 = {
 	.name = "emi_cs_2_3",
 	.modes = pmx_emi_cs_2_3_modes,
 	.mode_count = ARRAY_SIZE(pmx_emi_cs_2_3_modes),
 	.enb_on_reset = 1,
 };
 
-struct pmx_dev_mode pmx_uart1_modes[] = {
+static struct pmx_dev_mode pmx_uart1_modes[] = {
 	{
 		.ids = 0x00,
 		.mask = PMX_FIRDA_MASK,
 	},
 };
 
-struct pmx_dev pmx_uart1 = {
+struct pmx_dev spear310_pmx_uart1 = {
 	.name = "uart1",
 	.modes = pmx_uart1_modes,
 	.mode_count = ARRAY_SIZE(pmx_uart1_modes),
 	.enb_on_reset = 1,
 };
 
-struct pmx_dev_mode pmx_uart2_modes[] = {
+static struct pmx_dev_mode pmx_uart2_modes[] = {
 	{
 		.ids = 0x00,
 		.mask = PMX_TIMER_1_2_MASK,
 	},
 };
 
-struct pmx_dev pmx_uart2 = {
+struct pmx_dev spear310_pmx_uart2 = {
 	.name = "uart2",
 	.modes = pmx_uart2_modes,
 	.mode_count = ARRAY_SIZE(pmx_uart2_modes),
 	.enb_on_reset = 1,
 };
 
-struct pmx_dev_mode pmx_uart3_4_5_modes[] = {
+static struct pmx_dev_mode pmx_uart3_4_5_modes[] = {
 	{
 		.ids = 0x00,
 		.mask = PMX_UART0_MODEM_MASK,
 	},
 };
 
-struct pmx_dev pmx_uart3_4_5 = {
+struct pmx_dev spear310_pmx_uart3_4_5 = {
 	.name = "uart3_4_5",
 	.modes = pmx_uart3_4_5_modes,
 	.mode_count = ARRAY_SIZE(pmx_uart3_4_5_modes),
 	.enb_on_reset = 1,
 };
 
-struct pmx_dev_mode pmx_fsmc_modes[] = {
+static struct pmx_dev_mode pmx_fsmc_modes[] = {
 	{
 		.ids = 0x00,
 		.mask = PMX_SSP_CS_MASK,
 	},
 };
 
-struct pmx_dev pmx_fsmc = {
+struct pmx_dev spear310_pmx_fsmc = {
 	.name = "fsmc",
 	.modes = pmx_fsmc_modes,
 	.mode_count = ARRAY_SIZE(pmx_fsmc_modes),
 	.enb_on_reset = 1,
 };
 
-struct pmx_dev_mode pmx_rs485_0_1_modes[] = {
+static struct pmx_dev_mode pmx_rs485_0_1_modes[] = {
 	{
 		.ids = 0x00,
 		.mask = PMX_MII_MASK,
 	},
 };
 
-struct pmx_dev pmx_rs485_0_1 = {
+struct pmx_dev spear310_pmx_rs485_0_1 = {
 	.name = "rs485_0_1",
 	.modes = pmx_rs485_0_1_modes,
 	.mode_count = ARRAY_SIZE(pmx_rs485_0_1_modes),
 	.enb_on_reset = 1,
 };
 
-struct pmx_dev_mode pmx_tdm0_modes[] = {
+static struct pmx_dev_mode pmx_tdm0_modes[] = {
 	{
 		.ids = 0x00,
 		.mask = PMX_MII_MASK,
 	},
 };
 
-struct pmx_dev pmx_tdm0 = {
+struct pmx_dev spear310_pmx_tdm0 = {
 	.name = "tdm0",
 	.modes = pmx_tdm0_modes,
 	.mode_count = ARRAY_SIZE(pmx_tdm0_modes),
@@ -135,122 +135,122 @@
 };
 
 /* pmx driver structure */
-struct pmx_driver pmx_driver = {
+static struct pmx_driver pmx_driver = {
 	.mux_reg = {.offset = PAD_MUX_CONFIG_REG, .mask = 0x00007fff},
 };
 
 /* spear3xx shared irq */
-struct shirq_dev_config shirq_ras1_config[] = {
+static struct shirq_dev_config shirq_ras1_config[] = {
 	{
-		.virq = VIRQ_SMII0,
-		.status_mask = SMII0_IRQ_MASK,
+		.virq = SPEAR310_VIRQ_SMII0,
+		.status_mask = SPEAR310_SMII0_IRQ_MASK,
 	}, {
-		.virq = VIRQ_SMII1,
-		.status_mask = SMII1_IRQ_MASK,
+		.virq = SPEAR310_VIRQ_SMII1,
+		.status_mask = SPEAR310_SMII1_IRQ_MASK,
 	}, {
-		.virq = VIRQ_SMII2,
-		.status_mask = SMII2_IRQ_MASK,
+		.virq = SPEAR310_VIRQ_SMII2,
+		.status_mask = SPEAR310_SMII2_IRQ_MASK,
 	}, {
-		.virq = VIRQ_SMII3,
-		.status_mask = SMII3_IRQ_MASK,
+		.virq = SPEAR310_VIRQ_SMII3,
+		.status_mask = SPEAR310_SMII3_IRQ_MASK,
 	}, {
-		.virq = VIRQ_WAKEUP_SMII0,
-		.status_mask = WAKEUP_SMII0_IRQ_MASK,
+		.virq = SPEAR310_VIRQ_WAKEUP_SMII0,
+		.status_mask = SPEAR310_WAKEUP_SMII0_IRQ_MASK,
 	}, {
-		.virq = VIRQ_WAKEUP_SMII1,
-		.status_mask = WAKEUP_SMII1_IRQ_MASK,
+		.virq = SPEAR310_VIRQ_WAKEUP_SMII1,
+		.status_mask = SPEAR310_WAKEUP_SMII1_IRQ_MASK,
 	}, {
-		.virq = VIRQ_WAKEUP_SMII2,
-		.status_mask = WAKEUP_SMII2_IRQ_MASK,
+		.virq = SPEAR310_VIRQ_WAKEUP_SMII2,
+		.status_mask = SPEAR310_WAKEUP_SMII2_IRQ_MASK,
 	}, {
-		.virq = VIRQ_WAKEUP_SMII3,
-		.status_mask = WAKEUP_SMII3_IRQ_MASK,
+		.virq = SPEAR310_VIRQ_WAKEUP_SMII3,
+		.status_mask = SPEAR310_WAKEUP_SMII3_IRQ_MASK,
 	},
 };
 
-struct spear_shirq shirq_ras1 = {
-	.irq = IRQ_GEN_RAS_1,
+static struct spear_shirq shirq_ras1 = {
+	.irq = SPEAR3XX_IRQ_GEN_RAS_1,
 	.dev_config = shirq_ras1_config,
 	.dev_count = ARRAY_SIZE(shirq_ras1_config),
 	.regs = {
 		.enb_reg = -1,
-		.status_reg = INT_STS_MASK_REG,
-		.status_reg_mask = SHIRQ_RAS1_MASK,
+		.status_reg = SPEAR310_INT_STS_MASK_REG,
+		.status_reg_mask = SPEAR310_SHIRQ_RAS1_MASK,
 		.clear_reg = -1,
 	},
 };
 
-struct shirq_dev_config shirq_ras2_config[] = {
+static struct shirq_dev_config shirq_ras2_config[] = {
 	{
-		.virq = VIRQ_UART1,
-		.status_mask = UART1_IRQ_MASK,
+		.virq = SPEAR310_VIRQ_UART1,
+		.status_mask = SPEAR310_UART1_IRQ_MASK,
 	}, {
-		.virq = VIRQ_UART2,
-		.status_mask = UART2_IRQ_MASK,
+		.virq = SPEAR310_VIRQ_UART2,
+		.status_mask = SPEAR310_UART2_IRQ_MASK,
 	}, {
-		.virq = VIRQ_UART3,
-		.status_mask = UART3_IRQ_MASK,
+		.virq = SPEAR310_VIRQ_UART3,
+		.status_mask = SPEAR310_UART3_IRQ_MASK,
 	}, {
-		.virq = VIRQ_UART4,
-		.status_mask = UART4_IRQ_MASK,
+		.virq = SPEAR310_VIRQ_UART4,
+		.status_mask = SPEAR310_UART4_IRQ_MASK,
 	}, {
-		.virq = VIRQ_UART5,
-		.status_mask = UART5_IRQ_MASK,
+		.virq = SPEAR310_VIRQ_UART5,
+		.status_mask = SPEAR310_UART5_IRQ_MASK,
 	},
 };
 
-struct spear_shirq shirq_ras2 = {
-	.irq = IRQ_GEN_RAS_2,
+static struct spear_shirq shirq_ras2 = {
+	.irq = SPEAR3XX_IRQ_GEN_RAS_2,
 	.dev_config = shirq_ras2_config,
 	.dev_count = ARRAY_SIZE(shirq_ras2_config),
 	.regs = {
 		.enb_reg = -1,
-		.status_reg = INT_STS_MASK_REG,
-		.status_reg_mask = SHIRQ_RAS2_MASK,
+		.status_reg = SPEAR310_INT_STS_MASK_REG,
+		.status_reg_mask = SPEAR310_SHIRQ_RAS2_MASK,
 		.clear_reg = -1,
 	},
 };
 
-struct shirq_dev_config shirq_ras3_config[] = {
+static struct shirq_dev_config shirq_ras3_config[] = {
 	{
-		.virq = VIRQ_EMI,
-		.status_mask = EMI_IRQ_MASK,
+		.virq = SPEAR310_VIRQ_EMI,
+		.status_mask = SPEAR310_EMI_IRQ_MASK,
 	},
 };
 
-struct spear_shirq shirq_ras3 = {
-	.irq = IRQ_GEN_RAS_3,
+static struct spear_shirq shirq_ras3 = {
+	.irq = SPEAR3XX_IRQ_GEN_RAS_3,
 	.dev_config = shirq_ras3_config,
 	.dev_count = ARRAY_SIZE(shirq_ras3_config),
 	.regs = {
 		.enb_reg = -1,
-		.status_reg = INT_STS_MASK_REG,
-		.status_reg_mask = SHIRQ_RAS3_MASK,
+		.status_reg = SPEAR310_INT_STS_MASK_REG,
+		.status_reg_mask = SPEAR310_SHIRQ_RAS3_MASK,
 		.clear_reg = -1,
 	},
 };
 
-struct shirq_dev_config shirq_intrcomm_ras_config[] = {
+static struct shirq_dev_config shirq_intrcomm_ras_config[] = {
 	{
-		.virq = VIRQ_TDM_HDLC,
-		.status_mask = TDM_HDLC_IRQ_MASK,
+		.virq = SPEAR310_VIRQ_TDM_HDLC,
+		.status_mask = SPEAR310_TDM_HDLC_IRQ_MASK,
 	}, {
-		.virq = VIRQ_RS485_0,
-		.status_mask = RS485_0_IRQ_MASK,
+		.virq = SPEAR310_VIRQ_RS485_0,
+		.status_mask = SPEAR310_RS485_0_IRQ_MASK,
 	}, {
-		.virq = VIRQ_RS485_1,
-		.status_mask = RS485_1_IRQ_MASK,
+		.virq = SPEAR310_VIRQ_RS485_1,
+		.status_mask = SPEAR310_RS485_1_IRQ_MASK,
 	},
 };
 
-struct spear_shirq shirq_intrcomm_ras = {
-	.irq = IRQ_INTRCOMM_RAS_ARM,
+static struct spear_shirq shirq_intrcomm_ras = {
+	.irq = SPEAR3XX_IRQ_INTRCOMM_RAS_ARM,
 	.dev_config = shirq_intrcomm_ras_config,
 	.dev_count = ARRAY_SIZE(shirq_intrcomm_ras_config),
 	.regs = {
 		.enb_reg = -1,
-		.status_reg = INT_STS_MASK_REG,
-		.status_reg_mask = SHIRQ_INTRCOMM_RAS_MASK,
+		.status_reg = SPEAR310_INT_STS_MASK_REG,
+		.status_reg_mask = SPEAR310_SHIRQ_INTRCOMM_RAS_MASK,
 		.clear_reg = -1,
 	},
 };
@@ -258,7 +258,8 @@
 /* Add spear310 specific devices here */
 
 /* spear310 routines */
-void __init spear310_init(void)
+void __init spear310_init(struct pmx_mode *pmx_mode, struct pmx_dev **pmx_devs,
+		u8 pmx_dev_count)
 {
 	void __iomem *base;
 	int ret = 0;
@@ -296,6 +297,10 @@
 
 	/* pmx initialization */
 	pmx_driver.base = base;
+	pmx_driver.mode = pmx_mode;
+	pmx_driver.devs = pmx_devs;
+	pmx_driver.devs_count = pmx_dev_count;
+
 	ret = pmx_register(&pmx_driver);
 	if (ret)
 		printk(KERN_ERR "padmux: registeration failed. err no: %d\n",
diff -druN linux-2.6.39-libre/arch/arm/mach-spear3xx/spear310_evb.c linux-3.0-rc7-libre/arch/arm/mach-spear3xx/spear310_evb.c
--- linux-2.6.39-libre/arch/arm/mach-spear3xx/spear310_evb.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-spear3xx/spear310_evb.c	2011-07-11 19:51:52.000000000 -0400
@@ -19,31 +19,31 @@
 /* padmux devices to enable */
 static struct pmx_dev *pmx_devs[] = {
 	/* spear3xx specific devices */
-	&pmx_i2c,
-	&pmx_ssp,
-	&pmx_gpio_pin0,
-	&pmx_gpio_pin1,
-	&pmx_gpio_pin2,
-	&pmx_gpio_pin3,
-	&pmx_gpio_pin4,
-	&pmx_gpio_pin5,
-	&pmx_uart0,
+	&spear3xx_pmx_i2c,
+	&spear3xx_pmx_ssp,
+	&spear3xx_pmx_gpio_pin0,
+	&spear3xx_pmx_gpio_pin1,
+	&spear3xx_pmx_gpio_pin2,
+	&spear3xx_pmx_gpio_pin3,
+	&spear3xx_pmx_gpio_pin4,
+	&spear3xx_pmx_gpio_pin5,
+	&spear3xx_pmx_uart0,
 
 	/* spear310 specific devices */
-	&pmx_emi_cs_0_1_4_5,
-	&pmx_emi_cs_2_3,
-	&pmx_uart1,
-	&pmx_uart2,
-	&pmx_uart3_4_5,
-	&pmx_fsmc,
-	&pmx_rs485_0_1,
-	&pmx_tdm0,
+	&spear310_pmx_emi_cs_0_1_4_5,
+	&spear310_pmx_emi_cs_2_3,
+	&spear310_pmx_uart1,
+	&spear310_pmx_uart2,
+	&spear310_pmx_uart3_4_5,
+	&spear310_pmx_fsmc,
+	&spear310_pmx_rs485_0_1,
+	&spear310_pmx_tdm0,
 };
 
 static struct amba_device *amba_devs[] __initdata = {
 	/* spear3xx specific devices */
-	&gpio_device,
-	&uart_device,
+	&spear3xx_gpio_device,
+	&spear3xx_uart_device,
 
 	/* spear310 specific devices */
 };
@@ -58,13 +58,8 @@
 {
 	unsigned int i;
 
-	/* padmux initialization, must be done before spear310_init */
-	pmx_driver.mode = NULL;
-	pmx_driver.devs = pmx_devs;
-	pmx_driver.devs_count = ARRAY_SIZE(pmx_devs);
-
 	/* call spear310 machine init function */
-	spear310_init();
+	spear310_init(NULL, pmx_devs, ARRAY_SIZE(pmx_devs));
 
 	/* Add Platform Devices */
 	platform_add_devices(plat_devs, ARRAY_SIZE(plat_devs));
diff -druN linux-2.6.39-libre/arch/arm/mach-spear3xx/spear320.c linux-3.0-rc7-libre/arch/arm/mach-spear3xx/spear320.c
--- linux-2.6.39-libre/arch/arm/mach-spear3xx/spear320.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-spear3xx/spear320.c	2011-07-11 19:51:52.000000000 -0400
@@ -29,88 +29,88 @@
 #define SMALL_PRINTERS_MODE	(1 << 3)
 #define ALL_MODES		0xF
 
-struct pmx_mode auto_net_smii_mode = {
+struct pmx_mode spear320_auto_net_smii_mode = {
 	.id = AUTO_NET_SMII_MODE,
 	.name = "Automation Networking SMII Mode",
 	.mask = 0x00,
 };
 
-struct pmx_mode auto_net_mii_mode = {
+struct pmx_mode spear320_auto_net_mii_mode = {
 	.id = AUTO_NET_MII_MODE,
 	.name = "Automation Networking MII Mode",
 	.mask = 0x01,
 };
 
-struct pmx_mode auto_exp_mode = {
+struct pmx_mode spear320_auto_exp_mode = {
 	.id = AUTO_EXP_MODE,
 	.name = "Automation Expanded Mode",
 	.mask = 0x02,
 };
 
-struct pmx_mode small_printers_mode = {
+struct pmx_mode spear320_small_printers_mode = {
 	.id = SMALL_PRINTERS_MODE,
 	.name = "Small Printers Mode",
 	.mask = 0x03,
 };
 
 /* devices */
-struct pmx_dev_mode pmx_clcd_modes[] = {
+static struct pmx_dev_mode pmx_clcd_modes[] = {
 	{
 		.ids = AUTO_NET_SMII_MODE,
 		.mask = 0x0,
 	},
 };
 
-struct pmx_dev pmx_clcd = {
+struct pmx_dev spear320_pmx_clcd = {
 	.name = "clcd",
 	.modes = pmx_clcd_modes,
 	.mode_count = ARRAY_SIZE(pmx_clcd_modes),
 	.enb_on_reset = 1,
 };
 
-struct pmx_dev_mode pmx_emi_modes[] = {
+static struct pmx_dev_mode pmx_emi_modes[] = {
 	{
 		.ids = AUTO_EXP_MODE,
 		.mask = PMX_TIMER_1_2_MASK | PMX_TIMER_3_4_MASK,
 	},
 };
 
-struct pmx_dev pmx_emi = {
+struct pmx_dev spear320_pmx_emi = {
 	.name = "emi",
 	.modes = pmx_emi_modes,
 	.mode_count = ARRAY_SIZE(pmx_emi_modes),
 	.enb_on_reset = 1,
 };
 
-struct pmx_dev_mode pmx_fsmc_modes[] = {
+static struct pmx_dev_mode pmx_fsmc_modes[] = {
 	{
 		.ids = ALL_MODES,
 		.mask = 0x0,
 	},
 };
 
-struct pmx_dev pmx_fsmc = {
+struct pmx_dev spear320_pmx_fsmc = {
 	.name = "fsmc",
 	.modes = pmx_fsmc_modes,
 	.mode_count = ARRAY_SIZE(pmx_fsmc_modes),
 	.enb_on_reset = 1,
 };
 
-struct pmx_dev_mode pmx_spp_modes[] = {
+static struct pmx_dev_mode pmx_spp_modes[] = {
 	{
 		.ids = SMALL_PRINTERS_MODE,
 		.mask = 0x0,
 	},
 };
 
-struct pmx_dev pmx_spp = {
+struct pmx_dev spear320_pmx_spp = {
 	.name = "spp",
 	.modes = pmx_spp_modes,
 	.mode_count = ARRAY_SIZE(pmx_spp_modes),
 	.enb_on_reset = 1,
 };
 
-struct pmx_dev_mode pmx_sdhci_modes[] = {
+static struct pmx_dev_mode pmx_sdhci_modes[] = {
 	{
 		.ids = AUTO_NET_SMII_MODE | AUTO_NET_MII_MODE |
 			SMALL_PRINTERS_MODE,
@@ -118,42 +118,42 @@
 	},
 };
 
-struct pmx_dev pmx_sdhci = {
+struct pmx_dev spear320_pmx_sdhci = {
 	.name = "sdhci",
 	.modes = pmx_sdhci_modes,
 	.mode_count = ARRAY_SIZE(pmx_sdhci_modes),
 	.enb_on_reset = 1,
 };
 
-struct pmx_dev_mode pmx_i2s_modes[] = {
+static struct pmx_dev_mode pmx_i2s_modes[] = {
 	{
 		.ids = AUTO_NET_SMII_MODE | AUTO_NET_MII_MODE,
 		.mask = PMX_UART0_MODEM_MASK,
 	},
 };
 
-struct pmx_dev pmx_i2s = {
+struct pmx_dev spear320_pmx_i2s = {
 	.name = "i2s",
 	.modes = pmx_i2s_modes,
 	.mode_count = ARRAY_SIZE(pmx_i2s_modes),
 	.enb_on_reset = 1,
 };
 
-struct pmx_dev_mode pmx_uart1_modes[] = {
+static struct pmx_dev_mode pmx_uart1_modes[] = {
 	{
 		.ids = ALL_MODES,
 		.mask = PMX_GPIO_PIN0_MASK | PMX_GPIO_PIN1_MASK,
 	},
 };
 
-struct pmx_dev pmx_uart1 = {
+struct pmx_dev spear320_pmx_uart1 = {
 	.name = "uart1",
 	.modes = pmx_uart1_modes,
 	.mode_count = ARRAY_SIZE(pmx_uart1_modes),
 	.enb_on_reset = 1,
 };
 
-struct pmx_dev_mode pmx_uart1_modem_modes[] = {
+static struct pmx_dev_mode pmx_uart1_modem_modes[] = {
 	{
 		.ids = AUTO_EXP_MODE,
 		.mask = PMX_TIMER_1_2_MASK | PMX_TIMER_3_4_MASK |
@@ -165,42 +165,42 @@
 	},
 };
 
-struct pmx_dev pmx_uart1_modem = {
+struct pmx_dev spear320_pmx_uart1_modem = {
 	.name = "uart1_modem",
 	.modes = pmx_uart1_modem_modes,
 	.mode_count = ARRAY_SIZE(pmx_uart1_modem_modes),
 	.enb_on_reset = 1,
 };
 
-struct pmx_dev_mode pmx_uart2_modes[] = {
+static struct pmx_dev_mode pmx_uart2_modes[] = {
 	{
 		.ids = ALL_MODES,
 		.mask = PMX_FIRDA_MASK,
 	},
 };
 
-struct pmx_dev pmx_uart2 = {
+struct pmx_dev spear320_pmx_uart2 = {
 	.name = "uart2",
 	.modes = pmx_uart2_modes,
 	.mode_count = ARRAY_SIZE(pmx_uart2_modes),
 	.enb_on_reset = 1,
 };
 
-struct pmx_dev_mode pmx_touchscreen_modes[] = {
+static struct pmx_dev_mode pmx_touchscreen_modes[] = {
 	{
 		.ids = AUTO_NET_SMII_MODE,
 		.mask = PMX_SSP_CS_MASK,
 	},
 };
 
-struct pmx_dev pmx_touchscreen = {
+struct pmx_dev spear320_pmx_touchscreen = {
 	.name = "touchscreen",
 	.modes = pmx_touchscreen_modes,
 	.mode_count = ARRAY_SIZE(pmx_touchscreen_modes),
 	.enb_on_reset = 1,
 };
 
-struct pmx_dev_mode pmx_can_modes[] = {
+static struct pmx_dev_mode pmx_can_modes[] = {
 	{
 		.ids = AUTO_NET_SMII_MODE | AUTO_NET_MII_MODE | AUTO_EXP_MODE,
 		.mask = PMX_GPIO_PIN2_MASK | PMX_GPIO_PIN3_MASK |
@@ -208,28 +208,28 @@
 	},
 };
 
-struct pmx_dev pmx_can = {
+struct pmx_dev spear320_pmx_can = {
 	.name = "can",
 	.modes = pmx_can_modes,
 	.mode_count = ARRAY_SIZE(pmx_can_modes),
 	.enb_on_reset = 1,
 };
 
-struct pmx_dev_mode pmx_sdhci_led_modes[] = {
+static struct pmx_dev_mode pmx_sdhci_led_modes[] = {
 	{
 		.ids = AUTO_NET_SMII_MODE | AUTO_NET_MII_MODE,
 		.mask = PMX_SSP_CS_MASK,
 	},
 };
 
-struct pmx_dev pmx_sdhci_led = {
+struct pmx_dev spear320_pmx_sdhci_led = {
 	.name = "sdhci_led",
 	.modes = pmx_sdhci_led_modes,
 	.mode_count = ARRAY_SIZE(pmx_sdhci_led_modes),
 	.enb_on_reset = 1,
 };
 
-struct pmx_dev_mode pmx_pwm0_modes[] = {
+static struct pmx_dev_mode pmx_pwm0_modes[] = {
 	{
 		.ids = AUTO_NET_SMII_MODE | AUTO_NET_MII_MODE,
 		.mask = PMX_UART0_MODEM_MASK,
@@ -239,14 +239,14 @@
 	},
 };
 
-struct pmx_dev pmx_pwm0 = {
+struct pmx_dev spear320_pmx_pwm0 = {
 	.name = "pwm0",
 	.modes = pmx_pwm0_modes,
 	.mode_count = ARRAY_SIZE(pmx_pwm0_modes),
 	.enb_on_reset = 1,
 };
 
-struct pmx_dev_mode pmx_pwm1_modes[] = {
+static struct pmx_dev_mode pmx_pwm1_modes[] = {
 	{
 		.ids = AUTO_NET_SMII_MODE | AUTO_NET_MII_MODE,
 		.mask = PMX_UART0_MODEM_MASK,
@@ -256,14 +256,14 @@
 	},
 };
 
-struct pmx_dev pmx_pwm1 = {
+struct pmx_dev spear320_pmx_pwm1 = {
 	.name = "pwm1",
 	.modes = pmx_pwm1_modes,
 	.mode_count = ARRAY_SIZE(pmx_pwm1_modes),
 	.enb_on_reset = 1,
 };
 
-struct pmx_dev_mode pmx_pwm2_modes[] = {
+static struct pmx_dev_mode pmx_pwm2_modes[] = {
 	{
 		.ids = AUTO_NET_SMII_MODE | AUTO_NET_MII_MODE,
 		.mask = PMX_SSP_CS_MASK,
@@ -273,105 +273,105 @@
 	},
 };
 
-struct pmx_dev pmx_pwm2 = {
+struct pmx_dev spear320_pmx_pwm2 = {
 	.name = "pwm2",
 	.modes = pmx_pwm2_modes,
 	.mode_count = ARRAY_SIZE(pmx_pwm2_modes),
 	.enb_on_reset = 1,
 };
 
-struct pmx_dev_mode pmx_pwm3_modes[] = {
+static struct pmx_dev_mode pmx_pwm3_modes[] = {
 	{
 		.ids = AUTO_EXP_MODE | SMALL_PRINTERS_MODE | AUTO_NET_SMII_MODE,
 		.mask = PMX_MII_MASK,
 	},
 };
 
-struct pmx_dev pmx_pwm3 = {
+struct pmx_dev spear320_pmx_pwm3 = {
 	.name = "pwm3",
 	.modes = pmx_pwm3_modes,
 	.mode_count = ARRAY_SIZE(pmx_pwm3_modes),
 	.enb_on_reset = 1,
 };
 
-struct pmx_dev_mode pmx_ssp1_modes[] = {
+static struct pmx_dev_mode pmx_ssp1_modes[] = {
 	{
 		.ids = SMALL_PRINTERS_MODE | AUTO_NET_SMII_MODE,
 		.mask = PMX_MII_MASK,
 	},
 };
 
-struct pmx_dev pmx_ssp1 = {
+struct pmx_dev spear320_pmx_ssp1 = {
 	.name = "ssp1",
 	.modes = pmx_ssp1_modes,
 	.mode_count = ARRAY_SIZE(pmx_ssp1_modes),
 	.enb_on_reset = 1,
 };
 
-struct pmx_dev_mode pmx_ssp2_modes[] = {
+static struct pmx_dev_mode pmx_ssp2_modes[] = {
 	{
 		.ids = AUTO_NET_SMII_MODE,
 		.mask = PMX_MII_MASK,
 	},
 };
 
-struct pmx_dev pmx_ssp2 = {
+struct pmx_dev spear320_pmx_ssp2 = {
 	.name = "ssp2",
 	.modes = pmx_ssp2_modes,
 	.mode_count = ARRAY_SIZE(pmx_ssp2_modes),
 	.enb_on_reset = 1,
 };
 
-struct pmx_dev_mode pmx_mii1_modes[] = {
+static struct pmx_dev_mode pmx_mii1_modes[] = {
 	{
 		.ids = AUTO_NET_MII_MODE,
 		.mask = 0x0,
 	},
 };
 
-struct pmx_dev pmx_mii1 = {
+struct pmx_dev spear320_pmx_mii1 = {
 	.name = "mii1",
 	.modes = pmx_mii1_modes,
 	.mode_count = ARRAY_SIZE(pmx_mii1_modes),
 	.enb_on_reset = 1,
 };
 
-struct pmx_dev_mode pmx_smii0_modes[] = {
+static struct pmx_dev_mode pmx_smii0_modes[] = {
 	{
 		.ids = AUTO_NET_SMII_MODE | AUTO_EXP_MODE | SMALL_PRINTERS_MODE,
 		.mask = PMX_MII_MASK,
 	},
 };
 
-struct pmx_dev pmx_smii0 = {
+struct pmx_dev spear320_pmx_smii0 = {
 	.name = "smii0",
 	.modes = pmx_smii0_modes,
 	.mode_count = ARRAY_SIZE(pmx_smii0_modes),
 	.enb_on_reset = 1,
 };
 
-struct pmx_dev_mode pmx_smii1_modes[] = {
+static struct pmx_dev_mode pmx_smii1_modes[] = {
 	{
 		.ids = AUTO_NET_SMII_MODE | SMALL_PRINTERS_MODE,
 		.mask = PMX_MII_MASK,
 	},
 };
 
-struct pmx_dev pmx_smii1 = {
+struct pmx_dev spear320_pmx_smii1 = {
 	.name = "smii1",
 	.modes = pmx_smii1_modes,
 	.mode_count = ARRAY_SIZE(pmx_smii1_modes),
 	.enb_on_reset = 1,
 };
 
-struct pmx_dev_mode pmx_i2c1_modes[] = {
+static struct pmx_dev_mode pmx_i2c1_modes[] = {
 	{
 		.ids = AUTO_EXP_MODE,
 		.mask = 0x0,
 	},
 };
 
-struct pmx_dev pmx_i2c1 = {
+struct pmx_dev spear320_pmx_i2c1 = {
 	.name = "i2c1",
 	.modes = pmx_i2c1_modes,
 	.mode_count = ARRAY_SIZE(pmx_i2c1_modes),
@@ -379,131 +379,131 @@
 };
 
 /* pmx driver structure */
-struct pmx_driver pmx_driver = {
+static struct pmx_driver pmx_driver = {
 	.mode_reg = {.offset = MODE_CONFIG_REG, .mask = 0x00000007},
 	.mux_reg = {.offset = PAD_MUX_CONFIG_REG, .mask = 0x00007fff},
 };
 
 /* spear3xx shared irq */
-struct shirq_dev_config shirq_ras1_config[] = {
+static struct shirq_dev_config shirq_ras1_config[] = {
 	{
-		.virq = VIRQ_EMI,
-		.status_mask = EMI_IRQ_MASK,
-		.clear_mask = EMI_IRQ_MASK,
+		.virq = SPEAR320_VIRQ_EMI,
+		.status_mask = SPEAR320_EMI_IRQ_MASK,
+		.clear_mask = SPEAR320_EMI_IRQ_MASK,
 	}, {
-		.virq = VIRQ_CLCD,
-		.status_mask = CLCD_IRQ_MASK,
-		.clear_mask = CLCD_IRQ_MASK,
+		.virq = SPEAR320_VIRQ_CLCD,
+		.status_mask = SPEAR320_CLCD_IRQ_MASK,
+		.clear_mask = SPEAR320_CLCD_IRQ_MASK,
 	}, {
-		.virq = VIRQ_SPP,
-		.status_mask = SPP_IRQ_MASK,
-		.clear_mask = SPP_IRQ_MASK,
+		.virq = SPEAR320_VIRQ_SPP,
+		.status_mask = SPEAR320_SPP_IRQ_MASK,
+		.clear_mask = SPEAR320_SPP_IRQ_MASK,
 	},
 };
 
-struct spear_shirq shirq_ras1 = {
-	.irq = IRQ_GEN_RAS_1,
+static struct spear_shirq shirq_ras1 = {
+	.irq = SPEAR3XX_IRQ_GEN_RAS_1,
 	.dev_config = shirq_ras1_config,
 	.dev_count = ARRAY_SIZE(shirq_ras1_config),
 	.regs = {
 		.enb_reg = -1,
-		.status_reg = INT_STS_MASK_REG,
-		.status_reg_mask = SHIRQ_RAS1_MASK,
-		.clear_reg = INT_CLR_MASK_REG,
+		.status_reg = SPEAR320_INT_STS_MASK_REG,
+		.status_reg_mask = SPEAR320_SHIRQ_RAS1_MASK,
+		.clear_reg = SPEAR320_INT_CLR_MASK_REG,
 		.reset_to_clear = 1,
 	},
 };
 
-struct shirq_dev_config shirq_ras3_config[] = {
+static struct shirq_dev_config shirq_ras3_config[] = {
 	{
-		.virq = VIRQ_PLGPIO,
-		.enb_mask = GPIO_IRQ_MASK,
-		.status_mask = GPIO_IRQ_MASK,
-		.clear_mask = GPIO_IRQ_MASK,
+		.virq = SPEAR320_VIRQ_PLGPIO,
+		.enb_mask = SPEAR320_GPIO_IRQ_MASK,
+		.status_mask = SPEAR320_GPIO_IRQ_MASK,
+		.clear_mask = SPEAR320_GPIO_IRQ_MASK,
 	}, {
-		.virq = VIRQ_I2S_PLAY,
-		.enb_mask = I2S_PLAY_IRQ_MASK,
-		.status_mask = I2S_PLAY_IRQ_MASK,
-		.clear_mask = I2S_PLAY_IRQ_MASK,
+		.virq = SPEAR320_VIRQ_I2S_PLAY,
+		.enb_mask = SPEAR320_I2S_PLAY_IRQ_MASK,
+		.status_mask = SPEAR320_I2S_PLAY_IRQ_MASK,
+		.clear_mask = SPEAR320_I2S_PLAY_IRQ_MASK,
 	}, {
-		.virq = VIRQ_I2S_REC,
-		.enb_mask = I2S_REC_IRQ_MASK,
-		.status_mask = I2S_REC_IRQ_MASK,
-		.clear_mask = I2S_REC_IRQ_MASK,
+		.virq = SPEAR320_VIRQ_I2S_REC,
+		.enb_mask = SPEAR320_I2S_REC_IRQ_MASK,
+		.status_mask = SPEAR320_I2S_REC_IRQ_MASK,
+		.clear_mask = SPEAR320_I2S_REC_IRQ_MASK,
 	},
 };
 
-struct spear_shirq shirq_ras3 = {
-	.irq = IRQ_GEN_RAS_3,
+static struct spear_shirq shirq_ras3 = {
+	.irq = SPEAR3XX_IRQ_GEN_RAS_3,
 	.dev_config = shirq_ras3_config,
 	.dev_count = ARRAY_SIZE(shirq_ras3_config),
 	.regs = {
-		.enb_reg = INT_ENB_MASK_REG,
+		.enb_reg = SPEAR320_INT_ENB_MASK_REG,
 		.reset_to_enb = 1,
-		.status_reg = INT_STS_MASK_REG,
-		.status_reg_mask = SHIRQ_RAS3_MASK,
-		.clear_reg = INT_CLR_MASK_REG,
+		.status_reg = SPEAR320_INT_STS_MASK_REG,
+		.status_reg_mask = SPEAR320_SHIRQ_RAS3_MASK,
+		.clear_reg = SPEAR320_INT_CLR_MASK_REG,
 		.reset_to_clear = 1,
 	},
 };
 
-struct shirq_dev_config shirq_intrcomm_ras_config[] = {
+static struct shirq_dev_config shirq_intrcomm_ras_config[] = {
 	{
-		.virq = VIRQ_CANU,
-		.status_mask = CAN_U_IRQ_MASK,
-		.clear_mask = CAN_U_IRQ_MASK,
+		.virq = SPEAR320_VIRQ_CANU,
+		.status_mask = SPEAR320_CAN_U_IRQ_MASK,
+		.clear_mask = SPEAR320_CAN_U_IRQ_MASK,
 	}, {
-		.virq = VIRQ_CANL,
-		.status_mask = CAN_L_IRQ_MASK,
-		.clear_mask = CAN_L_IRQ_MASK,
+		.virq = SPEAR320_VIRQ_CANL,
+		.status_mask = SPEAR320_CAN_L_IRQ_MASK,
+		.clear_mask = SPEAR320_CAN_L_IRQ_MASK,
 	}, {
-		.virq = VIRQ_UART1,
-		.status_mask = UART1_IRQ_MASK,
-		.clear_mask = UART1_IRQ_MASK,
+		.virq = SPEAR320_VIRQ_UART1,
+		.status_mask = SPEAR320_UART1_IRQ_MASK,
+		.clear_mask = SPEAR320_UART1_IRQ_MASK,
 	}, {
-		.virq = VIRQ_UART2,
-		.status_mask = UART2_IRQ_MASK,
-		.clear_mask = UART2_IRQ_MASK,
+		.virq = SPEAR320_VIRQ_UART2,
+		.status_mask = SPEAR320_UART2_IRQ_MASK,
+		.clear_mask = SPEAR320_UART2_IRQ_MASK,
 	}, {
-		.virq = VIRQ_SSP1,
-		.status_mask = SSP1_IRQ_MASK,
-		.clear_mask = SSP1_IRQ_MASK,
+		.virq = SPEAR320_VIRQ_SSP1,
+		.status_mask = SPEAR320_SSP1_IRQ_MASK,
+		.clear_mask = SPEAR320_SSP1_IRQ_MASK,
 	}, {
-		.virq = VIRQ_SSP2,
-		.status_mask = SSP2_IRQ_MASK,
-		.clear_mask = SSP2_IRQ_MASK,
+		.virq = SPEAR320_VIRQ_SSP2,
+		.status_mask = SPEAR320_SSP2_IRQ_MASK,
+		.clear_mask = SPEAR320_SSP2_IRQ_MASK,
 	}, {
-		.virq = VIRQ_SMII0,
-		.status_mask = SMII0_IRQ_MASK,
-		.clear_mask = SMII0_IRQ_MASK,
+		.virq = SPEAR320_VIRQ_SMII0,
+		.status_mask = SPEAR320_SMII0_IRQ_MASK,
+		.clear_mask = SPEAR320_SMII0_IRQ_MASK,
 	}, {
-		.virq = VIRQ_MII1_SMII1,
-		.status_mask = MII1_SMII1_IRQ_MASK,
-		.clear_mask = MII1_SMII1_IRQ_MASK,
+		.virq = SPEAR320_VIRQ_MII1_SMII1,
+		.status_mask = SPEAR320_MII1_SMII1_IRQ_MASK,
+		.clear_mask = SPEAR320_MII1_SMII1_IRQ_MASK,
 	}, {
-		.virq = VIRQ_WAKEUP_SMII0,
-		.status_mask = WAKEUP_SMII0_IRQ_MASK,
-		.clear_mask = WAKEUP_SMII0_IRQ_MASK,
+		.virq = SPEAR320_VIRQ_WAKEUP_SMII0,
+		.status_mask = SPEAR320_WAKEUP_SMII0_IRQ_MASK,
+		.clear_mask = SPEAR320_WAKEUP_SMII0_IRQ_MASK,
 	}, {
-		.virq = VIRQ_WAKEUP_MII1_SMII1,
-		.status_mask = WAKEUP_MII1_SMII1_IRQ_MASK,
-		.clear_mask = WAKEUP_MII1_SMII1_IRQ_MASK,
+		.virq = SPEAR320_VIRQ_WAKEUP_MII1_SMII1,
+		.status_mask = SPEAR320_WAKEUP_MII1_SMII1_IRQ_MASK,
+		.clear_mask = SPEAR320_WAKEUP_MII1_SMII1_IRQ_MASK,
 	}, {
-		.virq = VIRQ_I2C,
-		.status_mask = I2C1_IRQ_MASK,
-		.clear_mask = I2C1_IRQ_MASK,
+		.virq = SPEAR320_VIRQ_I2C1,
+		.status_mask = SPEAR320_I2C1_IRQ_MASK,
+		.clear_mask = SPEAR320_I2C1_IRQ_MASK,
 	},
 };
 
-struct spear_shirq shirq_intrcomm_ras = {
-	.irq = IRQ_INTRCOMM_RAS_ARM,
+static struct spear_shirq shirq_intrcomm_ras = {
+	.irq = SPEAR3XX_IRQ_INTRCOMM_RAS_ARM,
 	.dev_config = shirq_intrcomm_ras_config,
 	.dev_count = ARRAY_SIZE(shirq_intrcomm_ras_config),
 	.regs = {
 		.enb_reg = -1,
-		.status_reg = INT_STS_MASK_REG,
-		.status_reg_mask = SHIRQ_INTRCOMM_RAS_MASK,
-		.clear_reg = INT_CLR_MASK_REG,
+		.status_reg = SPEAR320_INT_STS_MASK_REG,
+		.status_reg_mask = SPEAR320_SHIRQ_INTRCOMM_RAS_MASK,
+		.clear_reg = SPEAR320_INT_CLR_MASK_REG,
 		.reset_to_clear = 1,
 	},
 };
@@ -511,7 +511,8 @@
 /* Add spear320 specific devices here */
 
 /* spear320 routines */
-void __init spear320_init(void)
+void __init spear320_init(struct pmx_mode *pmx_mode, struct pmx_dev **pmx_devs,
+		u8 pmx_dev_count)
 {
 	void __iomem *base;
 	int ret = 0;
@@ -543,6 +544,10 @@
 
 	/* pmx initialization */
 	pmx_driver.base = base;
+	pmx_driver.mode = pmx_mode;
+	pmx_driver.devs = pmx_devs;
+	pmx_driver.devs_count = pmx_dev_count;
+
 	ret = pmx_register(&pmx_driver);
 	if (ret)
 		printk(KERN_ERR "padmux: registeration failed. err no: %d\n",
diff -druN linux-2.6.39-libre/arch/arm/mach-spear3xx/spear320_evb.c linux-3.0-rc7-libre/arch/arm/mach-spear3xx/spear320_evb.c
--- linux-2.6.39-libre/arch/arm/mach-spear3xx/spear320_evb.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-spear3xx/spear320_evb.c	2011-07-11 19:51:52.000000000 -0400
@@ -19,28 +19,28 @@
 /* padmux devices to enable */
 static struct pmx_dev *pmx_devs[] = {
 	/* spear3xx specific devices */
-	&pmx_i2c,
-	&pmx_ssp,
-	&pmx_mii,
-	&pmx_uart0,
+	&spear3xx_pmx_i2c,
+	&spear3xx_pmx_ssp,
+	&spear3xx_pmx_mii,
+	&spear3xx_pmx_uart0,
 
 	/* spear320 specific devices */
-	&pmx_fsmc,
-	&pmx_sdhci,
-	&pmx_i2s,
-	&pmx_uart1,
-	&pmx_uart2,
-	&pmx_can,
-	&pmx_pwm0,
-	&pmx_pwm1,
-	&pmx_pwm2,
-	&pmx_mii1,
+	&spear320_pmx_fsmc,
+	&spear320_pmx_sdhci,
+	&spear320_pmx_i2s,
+	&spear320_pmx_uart1,
+	&spear320_pmx_uart2,
+	&spear320_pmx_can,
+	&spear320_pmx_pwm0,
+	&spear320_pmx_pwm1,
+	&spear320_pmx_pwm2,
+	&spear320_pmx_mii1,
 };
 
 static struct amba_device *amba_devs[] __initdata = {
 	/* spear3xx specific devices */
-	&gpio_device,
-	&uart_device,
+	&spear3xx_gpio_device,
+	&spear3xx_uart_device,
 
 	/* spear320 specific devices */
 };
@@ -55,13 +55,9 @@
 {
 	unsigned int i;
 
-	/* padmux initialization, must be done before spear320_init */
-	pmx_driver.mode = &auto_net_mii_mode;
-	pmx_driver.devs = pmx_devs;
-	pmx_driver.devs_count = ARRAY_SIZE(pmx_devs);
-
 	/* call spear320 machine init function */
-	spear320_init();
+	spear320_init(&spear320_auto_net_mii_mode, pmx_devs,
+			ARRAY_SIZE(pmx_devs));
 
 	/* Add Platform Devices */
 	platform_add_devices(plat_devs, ARRAY_SIZE(plat_devs));
diff -druN linux-2.6.39-libre/arch/arm/mach-spear3xx/spear3xx.c linux-3.0-rc7-libre/arch/arm/mach-spear3xx/spear3xx.c
--- linux-2.6.39-libre/arch/arm/mach-spear3xx/spear3xx.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-spear3xx/spear3xx.c	2011-07-11 19:51:52.000000000 -0400
@@ -25,10 +25,10 @@
 /* gpio device registration */
 static struct pl061_platform_data gpio_plat_data = {
 	.gpio_base	= 0,
-	.irq_base	= SPEAR_GPIO_INT_BASE,
+	.irq_base	= SPEAR3XX_GPIO_INT_BASE,
 };
 
-struct amba_device gpio_device = {
+struct amba_device spear3xx_gpio_device = {
 	.dev = {
 		.init_name = "gpio",
 		.platform_data = &gpio_plat_data,
@@ -38,11 +38,11 @@
 		.end = SPEAR3XX_ICM3_GPIO_BASE + SZ_4K - 1,
 		.flags = IORESOURCE_MEM,
 	},
-	.irq = {IRQ_BASIC_GPIO, NO_IRQ},
+	.irq = {SPEAR3XX_IRQ_BASIC_GPIO, NO_IRQ},
 };
 
 /* uart device registration */
-struct amba_device uart_device = {
+struct amba_device spear3xx_uart_device = {
 	.dev = {
 		.init_name = "uart",
 	},
@@ -51,7 +51,7 @@
 		.end = SPEAR3XX_ICM1_UART_BASE + SZ_4K - 1,
 		.flags = IORESOURCE_MEM,
 	},
-	.irq = {IRQ_UART, NO_IRQ},
+	.irq = {SPEAR3XX_IRQ_UART, NO_IRQ},
 };
 
 /* Do spear3xx familiy common initialization part here */
@@ -97,215 +97,215 @@
 	iotable_init(spear3xx_io_desc, ARRAY_SIZE(spear3xx_io_desc));
 
 	/* This will initialize clock framework */
-	clk_init();
+	spear3xx_clk_init();
 }
 
 /* pad multiplexing support */
 /* devices */
-struct pmx_dev_mode pmx_firda_modes[] = {
+static struct pmx_dev_mode pmx_firda_modes[] = {
 	{
 		.ids = 0xffffffff,
 		.mask = PMX_FIRDA_MASK,
 	},
 };
 
-struct pmx_dev pmx_firda = {
+struct pmx_dev spear3xx_pmx_firda = {
 	.name = "firda",
 	.modes = pmx_firda_modes,
 	.mode_count = ARRAY_SIZE(pmx_firda_modes),
 	.enb_on_reset = 0,
 };
 
-struct pmx_dev_mode pmx_i2c_modes[] = {
+static struct pmx_dev_mode pmx_i2c_modes[] = {
 	{
 		.ids = 0xffffffff,
 		.mask = PMX_I2C_MASK,
 	},
 };
 
-struct pmx_dev pmx_i2c = {
+struct pmx_dev spear3xx_pmx_i2c = {
 	.name = "i2c",
 	.modes = pmx_i2c_modes,
 	.mode_count = ARRAY_SIZE(pmx_i2c_modes),
 	.enb_on_reset = 0,
 };
 
-struct pmx_dev_mode pmx_ssp_cs_modes[] = {
+static struct pmx_dev_mode pmx_ssp_cs_modes[] = {
 	{
 		.ids = 0xffffffff,
 		.mask = PMX_SSP_CS_MASK,
 	},
 };
 
-struct pmx_dev pmx_ssp_cs = {
+struct pmx_dev spear3xx_pmx_ssp_cs = {
 	.name = "ssp_chip_selects",
 	.modes = pmx_ssp_cs_modes,
 	.mode_count = ARRAY_SIZE(pmx_ssp_cs_modes),
 	.enb_on_reset = 0,
 };
 
-struct pmx_dev_mode pmx_ssp_modes[] = {
+static struct pmx_dev_mode pmx_ssp_modes[] = {
 	{
 		.ids = 0xffffffff,
 		.mask = PMX_SSP_MASK,
 	},
 };
 
-struct pmx_dev pmx_ssp = {
+struct pmx_dev spear3xx_pmx_ssp = {
 	.name = "ssp",
 	.modes = pmx_ssp_modes,
 	.mode_count = ARRAY_SIZE(pmx_ssp_modes),
 	.enb_on_reset = 0,
 };
 
-struct pmx_dev_mode pmx_mii_modes[] = {
+static struct pmx_dev_mode pmx_mii_modes[] = {
 	{
 		.ids = 0xffffffff,
 		.mask = PMX_MII_MASK,
 	},
 };
 
-struct pmx_dev pmx_mii = {
+struct pmx_dev spear3xx_pmx_mii = {
 	.name = "mii",
 	.modes = pmx_mii_modes,
 	.mode_count = ARRAY_SIZE(pmx_mii_modes),
 	.enb_on_reset = 0,
 };
 
-struct pmx_dev_mode pmx_gpio_pin0_modes[] = {
+static struct pmx_dev_mode pmx_gpio_pin0_modes[] = {
 	{
 		.ids = 0xffffffff,
 		.mask = PMX_GPIO_PIN0_MASK,
 	},
 };
 
-struct pmx_dev pmx_gpio_pin0 = {
+struct pmx_dev spear3xx_pmx_gpio_pin0 = {
 	.name = "gpio_pin0",
 	.modes = pmx_gpio_pin0_modes,
 	.mode_count = ARRAY_SIZE(pmx_gpio_pin0_modes),
 	.enb_on_reset = 0,
 };
 
-struct pmx_dev_mode pmx_gpio_pin1_modes[] = {
+static struct pmx_dev_mode pmx_gpio_pin1_modes[] = {
 	{
 		.ids = 0xffffffff,
 		.mask = PMX_GPIO_PIN1_MASK,
 	},
 };
 
-struct pmx_dev pmx_gpio_pin1 = {
+struct pmx_dev spear3xx_pmx_gpio_pin1 = {
 	.name = "gpio_pin1",
 	.modes = pmx_gpio_pin1_modes,
 	.mode_count = ARRAY_SIZE(pmx_gpio_pin1_modes),
 	.enb_on_reset = 0,
 };
 
-struct pmx_dev_mode pmx_gpio_pin2_modes[] = {
+static struct pmx_dev_mode pmx_gpio_pin2_modes[] = {
 	{
 		.ids = 0xffffffff,
 		.mask = PMX_GPIO_PIN2_MASK,
 	},
 };
 
-struct pmx_dev pmx_gpio_pin2 = {
+struct pmx_dev spear3xx_pmx_gpio_pin2 = {
 	.name = "gpio_pin2",
 	.modes = pmx_gpio_pin2_modes,
 	.mode_count = ARRAY_SIZE(pmx_gpio_pin2_modes),
 	.enb_on_reset = 0,
 };
 
-struct pmx_dev_mode pmx_gpio_pin3_modes[] = {
+static struct pmx_dev_mode pmx_gpio_pin3_modes[] = {
 	{
 		.ids = 0xffffffff,
 		.mask = PMX_GPIO_PIN3_MASK,
 	},
 };
 
-struct pmx_dev pmx_gpio_pin3 = {
+struct pmx_dev spear3xx_pmx_gpio_pin3 = {
 	.name = "gpio_pin3",
 	.modes = pmx_gpio_pin3_modes,
 	.mode_count = ARRAY_SIZE(pmx_gpio_pin3_modes),
 	.enb_on_reset = 0,
 };
 
-struct pmx_dev_mode pmx_gpio_pin4_modes[] = {
+static struct pmx_dev_mode pmx_gpio_pin4_modes[] = {
 	{
 		.ids = 0xffffffff,
 		.mask = PMX_GPIO_PIN4_MASK,
 	},
 };
 
-struct pmx_dev pmx_gpio_pin4 = {
+struct pmx_dev spear3xx_pmx_gpio_pin4 = {
 	.name = "gpio_pin4",
 	.modes = pmx_gpio_pin4_modes,
 	.mode_count = ARRAY_SIZE(pmx_gpio_pin4_modes),
 	.enb_on_reset = 0,
 };
 
-struct pmx_dev_mode pmx_gpio_pin5_modes[] = {
+static struct pmx_dev_mode pmx_gpio_pin5_modes[] = {
 	{
 		.ids = 0xffffffff,
 		.mask = PMX_GPIO_PIN5_MASK,
 	},
 };
 
-struct pmx_dev pmx_gpio_pin5 = {
+struct pmx_dev spear3xx_pmx_gpio_pin5 = {
 	.name = "gpio_pin5",
 	.modes = pmx_gpio_pin5_modes,
 	.mode_count = ARRAY_SIZE(pmx_gpio_pin5_modes),
 	.enb_on_reset = 0,
 };
 
-struct pmx_dev_mode pmx_uart0_modem_modes[] = {
+static struct pmx_dev_mode pmx_uart0_modem_modes[] = {
 	{
 		.ids = 0xffffffff,
 		.mask = PMX_UART0_MODEM_MASK,
 	},
 };
 
-struct pmx_dev pmx_uart0_modem = {
+struct pmx_dev spear3xx_pmx_uart0_modem = {
 	.name = "uart0_modem",
 	.modes = pmx_uart0_modem_modes,
 	.mode_count = ARRAY_SIZE(pmx_uart0_modem_modes),
 	.enb_on_reset = 0,
 };
 
-struct pmx_dev_mode pmx_uart0_modes[] = {
+static struct pmx_dev_mode pmx_uart0_modes[] = {
 	{
 		.ids = 0xffffffff,
 		.mask = PMX_UART0_MASK,
 	},
 };
 
-struct pmx_dev pmx_uart0 = {
+struct pmx_dev spear3xx_pmx_uart0 = {
 	.name = "uart0",
 	.modes = pmx_uart0_modes,
 	.mode_count = ARRAY_SIZE(pmx_uart0_modes),
 	.enb_on_reset = 0,
 };
 
-struct pmx_dev_mode pmx_timer_3_4_modes[] = {
+static struct pmx_dev_mode pmx_timer_3_4_modes[] = {
 	{
 		.ids = 0xffffffff,
 		.mask = PMX_TIMER_3_4_MASK,
 	},
 };
 
-struct pmx_dev pmx_timer_3_4 = {
+struct pmx_dev spear3xx_pmx_timer_3_4 = {
 	.name = "timer_3_4",
 	.modes = pmx_timer_3_4_modes,
 	.mode_count = ARRAY_SIZE(pmx_timer_3_4_modes),
 	.enb_on_reset = 0,
 };
 
-struct pmx_dev_mode pmx_timer_1_2_modes[] = {
+static struct pmx_dev_mode pmx_timer_1_2_modes[] = {
 	{
 		.ids = 0xffffffff,
 		.mask = PMX_TIMER_1_2_MASK,
 	},
 };
 
-struct pmx_dev pmx_timer_1_2 = {
+struct pmx_dev spear3xx_pmx_timer_1_2 = {
 	.name = "timer_1_2",
 	.modes = pmx_timer_1_2_modes,
 	.mode_count = ARRAY_SIZE(pmx_timer_1_2_modes),
@@ -314,210 +314,210 @@
 
 #if defined(CONFIG_MACH_SPEAR310) || defined(CONFIG_MACH_SPEAR320)
 /* plgpios devices */
-struct pmx_dev_mode pmx_plgpio_0_1_modes[] = {
+static struct pmx_dev_mode pmx_plgpio_0_1_modes[] = {
 	{
 		.ids = 0x00,
 		.mask = PMX_FIRDA_MASK,
 	},
 };
 
-struct pmx_dev pmx_plgpio_0_1 = {
+struct pmx_dev spear3xx_pmx_plgpio_0_1 = {
 	.name = "plgpio 0 and 1",
 	.modes = pmx_plgpio_0_1_modes,
 	.mode_count = ARRAY_SIZE(pmx_plgpio_0_1_modes),
 	.enb_on_reset = 1,
 };
 
-struct pmx_dev_mode pmx_plgpio_2_3_modes[] = {
+static struct pmx_dev_mode pmx_plgpio_2_3_modes[] = {
 	{
 		.ids = 0x00,
 		.mask = PMX_UART0_MASK,
 	},
 };
 
-struct pmx_dev pmx_plgpio_2_3 = {
+struct pmx_dev spear3xx_pmx_plgpio_2_3 = {
 	.name = "plgpio 2 and 3",
 	.modes = pmx_plgpio_2_3_modes,
 	.mode_count = ARRAY_SIZE(pmx_plgpio_2_3_modes),
 	.enb_on_reset = 1,
 };
 
-struct pmx_dev_mode pmx_plgpio_4_5_modes[] = {
+static struct pmx_dev_mode pmx_plgpio_4_5_modes[] = {
 	{
 		.ids = 0x00,
 		.mask = PMX_I2C_MASK,
 	},
 };
 
-struct pmx_dev pmx_plgpio_4_5 = {
+struct pmx_dev spear3xx_pmx_plgpio_4_5 = {
 	.name = "plgpio 4 and 5",
 	.modes = pmx_plgpio_4_5_modes,
 	.mode_count = ARRAY_SIZE(pmx_plgpio_4_5_modes),
 	.enb_on_reset = 1,
 };
 
-struct pmx_dev_mode pmx_plgpio_6_9_modes[] = {
+static struct pmx_dev_mode pmx_plgpio_6_9_modes[] = {
 	{
 		.ids = 0x00,
 		.mask = PMX_SSP_MASK,
 	},
 };
 
-struct pmx_dev pmx_plgpio_6_9 = {
+struct pmx_dev spear3xx_pmx_plgpio_6_9 = {
 	.name = "plgpio 6 to 9",
 	.modes = pmx_plgpio_6_9_modes,
 	.mode_count = ARRAY_SIZE(pmx_plgpio_6_9_modes),
 	.enb_on_reset = 1,
 };
 
-struct pmx_dev_mode pmx_plgpio_10_27_modes[] = {
+static struct pmx_dev_mode pmx_plgpio_10_27_modes[] = {
 	{
 		.ids = 0x00,
 		.mask = PMX_MII_MASK,
 	},
 };
 
-struct pmx_dev pmx_plgpio_10_27 = {
+struct pmx_dev spear3xx_pmx_plgpio_10_27 = {
 	.name = "plgpio 10 to 27",
 	.modes = pmx_plgpio_10_27_modes,
 	.mode_count = ARRAY_SIZE(pmx_plgpio_10_27_modes),
 	.enb_on_reset = 1,
 };
 
-struct pmx_dev_mode pmx_plgpio_28_modes[] = {
+static struct pmx_dev_mode pmx_plgpio_28_modes[] = {
 	{
 		.ids = 0x00,
 		.mask = PMX_GPIO_PIN0_MASK,
 	},
 };
 
-struct pmx_dev pmx_plgpio_28 = {
+struct pmx_dev spear3xx_pmx_plgpio_28 = {
 	.name = "plgpio 28",
 	.modes = pmx_plgpio_28_modes,
 	.mode_count = ARRAY_SIZE(pmx_plgpio_28_modes),
 	.enb_on_reset = 1,
 };
 
-struct pmx_dev_mode pmx_plgpio_29_modes[] = {
+static struct pmx_dev_mode pmx_plgpio_29_modes[] = {
 	{
 		.ids = 0x00,
 		.mask = PMX_GPIO_PIN1_MASK,
 	},
 };
 
-struct pmx_dev pmx_plgpio_29 = {
+struct pmx_dev spear3xx_pmx_plgpio_29 = {
 	.name = "plgpio 29",
 	.modes = pmx_plgpio_29_modes,
 	.mode_count = ARRAY_SIZE(pmx_plgpio_29_modes),
 	.enb_on_reset = 1,
 };
 
-struct pmx_dev_mode pmx_plgpio_30_modes[] = {
+static struct pmx_dev_mode pmx_plgpio_30_modes[] = {
 	{
 		.ids = 0x00,
 		.mask = PMX_GPIO_PIN2_MASK,
 	},
 };
 
-struct pmx_dev pmx_plgpio_30 = {
+struct pmx_dev spear3xx_pmx_plgpio_30 = {
 	.name = "plgpio 30",
 	.modes = pmx_plgpio_30_modes,
 	.mode_count = ARRAY_SIZE(pmx_plgpio_30_modes),
 	.enb_on_reset = 1,
 };
 
-struct pmx_dev_mode pmx_plgpio_31_modes[] = {
+static struct pmx_dev_mode pmx_plgpio_31_modes[] = {
 	{
 		.ids = 0x00,
 		.mask = PMX_GPIO_PIN3_MASK,
 	},
 };
 
-struct pmx_dev pmx_plgpio_31 = {
+struct pmx_dev spear3xx_pmx_plgpio_31 = {
 	.name = "plgpio 31",
 	.modes = pmx_plgpio_31_modes,
 	.mode_count = ARRAY_SIZE(pmx_plgpio_31_modes),
 	.enb_on_reset = 1,
 };
 
-struct pmx_dev_mode pmx_plgpio_32_modes[] = {
+static struct pmx_dev_mode pmx_plgpio_32_modes[] = {
 	{
 		.ids = 0x00,
 		.mask = PMX_GPIO_PIN4_MASK,
 	},
 };
 
-struct pmx_dev pmx_plgpio_32 = {
+struct pmx_dev spear3xx_pmx_plgpio_32 = {
 	.name = "plgpio 32",
 	.modes = pmx_plgpio_32_modes,
 	.mode_count = ARRAY_SIZE(pmx_plgpio_32_modes),
 	.enb_on_reset = 1,
 };
 
-struct pmx_dev_mode pmx_plgpio_33_modes[] = {
+static struct pmx_dev_mode pmx_plgpio_33_modes[] = {
 	{
 		.ids = 0x00,
 		.mask = PMX_GPIO_PIN5_MASK,
 	},
 };
 
-struct pmx_dev pmx_plgpio_33 = {
+struct pmx_dev spear3xx_pmx_plgpio_33 = {
 	.name = "plgpio 33",
 	.modes = pmx_plgpio_33_modes,
 	.mode_count = ARRAY_SIZE(pmx_plgpio_33_modes),
 	.enb_on_reset = 1,
 };
 
-struct pmx_dev_mode pmx_plgpio_34_36_modes[] = {
+static struct pmx_dev_mode pmx_plgpio_34_36_modes[] = {
 	{
 		.ids = 0x00,
 		.mask = PMX_SSP_CS_MASK,
 	},
 };
 
-struct pmx_dev pmx_plgpio_34_36 = {
+struct pmx_dev spear3xx_pmx_plgpio_34_36 = {
 	.name = "plgpio 34 to 36",
 	.modes = pmx_plgpio_34_36_modes,
 	.mode_count = ARRAY_SIZE(pmx_plgpio_34_36_modes),
 	.enb_on_reset = 1,
 };
 
-struct pmx_dev_mode pmx_plgpio_37_42_modes[] = {
+static struct pmx_dev_mode pmx_plgpio_37_42_modes[] = {
 	{
 		.ids = 0x00,
 		.mask = PMX_UART0_MODEM_MASK,
 	},
 };
 
-struct pmx_dev pmx_plgpio_37_42 = {
+struct pmx_dev spear3xx_pmx_plgpio_37_42 = {
 	.name = "plgpio 37 to 42",
 	.modes = pmx_plgpio_37_42_modes,
 	.mode_count = ARRAY_SIZE(pmx_plgpio_37_42_modes),
 	.enb_on_reset = 1,
 };
 
-struct pmx_dev_mode pmx_plgpio_43_44_47_48_modes[] = {
+static struct pmx_dev_mode pmx_plgpio_43_44_47_48_modes[] = {
 	{
 		.ids = 0x00,
 		.mask = PMX_TIMER_1_2_MASK,
 	},
 };
 
-struct pmx_dev pmx_plgpio_43_44_47_48 = {
+struct pmx_dev spear3xx_pmx_plgpio_43_44_47_48 = {
 	.name = "plgpio 43, 44, 47 and 48",
 	.modes = pmx_plgpio_43_44_47_48_modes,
 	.mode_count = ARRAY_SIZE(pmx_plgpio_43_44_47_48_modes),
 	.enb_on_reset = 1,
 };
 
-struct pmx_dev_mode pmx_plgpio_45_46_49_50_modes[] = {
+static struct pmx_dev_mode pmx_plgpio_45_46_49_50_modes[] = {
 	{
 		.ids = 0x00,
 		.mask = PMX_TIMER_3_4_MASK,
 	},
 };
 
-struct pmx_dev pmx_plgpio_45_46_49_50 = {
+struct pmx_dev spear3xx_pmx_plgpio_45_46_49_50 = {
 	.name = "plgpio 45, 46, 49 and 50",
 	.modes = pmx_plgpio_45_46_49_50_modes,
 	.mode_count = ARRAY_SIZE(pmx_plgpio_45_46_49_50_modes),
diff -druN linux-2.6.39-libre/arch/arm/mach-spear6xx/clock.c linux-3.0-rc7-libre/arch/arm/mach-spear6xx/clock.c
--- linux-2.6.39-libre/arch/arm/mach-spear6xx/clock.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-spear6xx/clock.c	2011-07-11 19:51:52.000000000 -0400
@@ -671,12 +671,12 @@
 	{ .dev_id = "gpio2",		.clk = &gpio2_clk},
 };
 
-void __init clk_init(void)
+void __init spear6xx_clk_init(void)
 {
 	int i;
 
 	for (i = 0; i < ARRAY_SIZE(spear_clk_lookups); i++)
 		clk_register(&spear_clk_lookups[i]);
 
-	recalc_root_clocks();
+	clk_init();
 }
diff -druN linux-2.6.39-libre/arch/arm/mach-spear6xx/include/mach/generic.h linux-3.0-rc7-libre/arch/arm/mach-spear6xx/include/mach/generic.h
--- linux-2.6.39-libre/arch/arm/mach-spear6xx/include/mach/generic.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-spear6xx/include/mach/generic.h	2011-07-11 19:51:52.000000000 -0400
@@ -39,7 +39,7 @@
 void __init spear6xx_init_irq(void);
 void __init spear6xx_init(void);
 void __init spear600_init(void);
-void __init clk_init(void);
+void __init spear6xx_clk_init(void);
 
 /* Add spear600 machine device structure declarations here */
 
diff -druN linux-2.6.39-libre/arch/arm/mach-spear6xx/Kconfig linux-3.0-rc7-libre/arch/arm/mach-spear6xx/Kconfig
--- linux-2.6.39-libre/arch/arm/mach-spear6xx/Kconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-spear6xx/Kconfig	2011-07-11 19:51:52.000000000 -0400
@@ -4,17 +4,18 @@
 
 if ARCH_SPEAR6XX
 
-choice
-	prompt "SPEAr6XX Family"
-	default MACH_SPEAR600
+menu "SPEAr6xx Implementations"
+config BOARD_SPEAR600_EVB
+	bool "SPEAr600 Evaluation Board"
+	select MACH_SPEAR600
+	help
+	  Supports ST SPEAr600 Evaluation Board
+
+endmenu
 
 config MACH_SPEAR600
 	bool "SPEAr600"
 	help
 	  Supports ST SPEAr600 Machine
-endchoice
-
-# Adding SPEAr6XX machine specific configuration files
-source "arch/arm/mach-spear6xx/Kconfig600"
 
 endif #ARCH_SPEAR6XX
diff -druN linux-2.6.39-libre/arch/arm/mach-spear6xx/Kconfig600 linux-3.0-rc7-libre/arch/arm/mach-spear6xx/Kconfig600
--- linux-2.6.39-libre/arch/arm/mach-spear6xx/Kconfig600	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-spear6xx/Kconfig600	1969-12-31 19:00:00.000000000 -0500
@@ -1,17 +0,0 @@
-#
-# SPEAr600 machine configuration file
-#
-
-if MACH_SPEAR600
-
-choice
-	prompt "SPEAr600 Boards"
-	default BOARD_SPEAR600_EVB
-
-config	BOARD_SPEAR600_EVB
-	bool "SPEAr600 Evaluation Board"
-	help
-	  Supports ST SPEAr600 Evaluation Board
-endchoice
-
-endif	#MACH_SPEAR600
diff -druN linux-2.6.39-libre/arch/arm/mach-spear6xx/spear6xx.c linux-3.0-rc7-libre/arch/arm/mach-spear6xx/spear6xx.c
--- linux-2.6.39-libre/arch/arm/mach-spear6xx/spear6xx.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-spear6xx/spear6xx.c	2011-07-11 19:51:52.000000000 -0400
@@ -148,7 +148,7 @@
 	iotable_init(spear6xx_io_desc, ARRAY_SIZE(spear6xx_io_desc));
 
 	/* This will initialize clock framework */
-	clk_init();
+	spear6xx_clk_init();
 }
 
 static void __init spear6xx_timer_init(void)
diff -druN linux-2.6.39-libre/arch/arm/mach-stmp378x/include/mach/entry-macro.S linux-3.0-rc7-libre/arch/arm/mach-stmp378x/include/mach/entry-macro.S
--- linux-2.6.39-libre/arch/arm/mach-stmp378x/include/mach/entry-macro.S	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-stmp378x/include/mach/entry-macro.S	1969-12-31 19:00:00.000000000 -0500
@@ -1,35 +0,0 @@
-/*
- * Low-level IRQ helper macros for Freescale STMP378X
- *
- * Embedded Alley Solutions, Inc <source@embeddedalley.com>
- *
- * Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved.
- * Copyright 2008 Embedded Alley Solutions, 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
- */
-
-		.macro	disable_fiq
-		.endm
-
-		.macro	get_irqnr_and_base, irqnr, irqstat, base, tmp
-
-	        mov	\base, #0xf0000000	@ vm address of IRQ controller
-		ldr	\irqnr, [\base, #0x70]	@ HW_ICOLL_STAT
-		cmp	\irqnr, #0x7f
-		moveqs	\irqnr, #0		@ Zero flag set for no IRQ
-
-		.endm
-
-                .macro  get_irqnr_preamble, base, tmp
-                .endm
-
-                .macro  arch_ret_to_user, tmp1, tmp2
-                .endm
diff -druN linux-2.6.39-libre/arch/arm/mach-stmp378x/include/mach/irqs.h linux-3.0-rc7-libre/arch/arm/mach-stmp378x/include/mach/irqs.h
--- linux-2.6.39-libre/arch/arm/mach-stmp378x/include/mach/irqs.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-stmp378x/include/mach/irqs.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,95 +0,0 @@
-/*
- * Freescale STMP378X interrupts
- *
- * Copyright (C) 2005 Sigmatel Inc
- *
- * Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved.
- * Copyright 2008 Embedded Alley Solutions, 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
- */
-
-#define IRQ_DEBUG_UART			0
-#define IRQ_COMMS_RX			1
-#define IRQ_COMMS_TX			1
-#define IRQ_SSP2_ERROR			2
-#define IRQ_VDD5V			3
-#define IRQ_HEADPHONE_SHORT		4
-#define IRQ_DAC_DMA			5
-#define IRQ_DAC_ERROR			6
-#define IRQ_ADC_DMA			7
-#define IRQ_ADC_ERROR			8
-#define IRQ_SPDIF_DMA			9
-#define IRQ_SAIF2_DMA			9
-#define IRQ_SPDIF_ERROR			10
-#define IRQ_SAIF1_IRQ			10
-#define IRQ_SAIF2_IRQ			10
-#define IRQ_USB_CTRL			11
-#define IRQ_USB_WAKEUP			12
-#define IRQ_GPMI_DMA			13
-#define IRQ_SSP1_DMA			14
-#define IRQ_SSP_ERROR			15
-#define IRQ_GPIO0			16
-#define IRQ_GPIO1			17
-#define IRQ_GPIO2			18
-#define IRQ_SAIF1_DMA			19
-#define IRQ_SSP2_DMA			20
-#define IRQ_ECC8_IRQ			21
-#define IRQ_RTC_ALARM			22
-#define IRQ_UARTAPP_TX_DMA		23
-#define IRQ_UARTAPP_INTERNAL		24
-#define IRQ_UARTAPP_RX_DMA		25
-#define IRQ_I2C_DMA			26
-#define IRQ_I2C_ERROR			27
-#define IRQ_TIMER0			28
-#define IRQ_TIMER1			29
-#define IRQ_TIMER2			30
-#define IRQ_TIMER3			31
-#define IRQ_BATT_BRNOUT			32
-#define IRQ_VDDD_BRNOUT			33
-#define IRQ_VDDIO_BRNOUT		34
-#define IRQ_VDD18_BRNOUT		35
-#define IRQ_TOUCH_DETECT		36
-#define IRQ_LRADC_CH0			37
-#define IRQ_LRADC_CH1			38
-#define IRQ_LRADC_CH2			39
-#define IRQ_LRADC_CH3			40
-#define IRQ_LRADC_CH4			41
-#define IRQ_LRADC_CH5			42
-#define IRQ_LRADC_CH6			43
-#define IRQ_LRADC_CH7			44
-#define IRQ_LCDIF_DMA			45
-#define IRQ_LCDIF_ERROR			46
-#define IRQ_DIGCTL_DEBUG_TRAP		47
-#define IRQ_RTC_1MSEC			48
-#define IRQ_DRI_DMA			49
-#define IRQ_DRI_ATTENTION		50
-#define IRQ_GPMI_ATTENTION		51
-#define IRQ_IR				52
-#define IRQ_DCP_VMI			53
-#define IRQ_DCP				54
-#define IRQ_BCH				56
-#define IRQ_PXP				57
-#define IRQ_UARTAPP2_TX_DMA		58
-#define IRQ_UARTAPP2_INTERNAL		59
-#define IRQ_UARTAPP2_RX_DMA		60
-#define IRQ_VDAC_DETECT			61
-#define IRQ_VDD5V_DROOP			64
-#define IRQ_DCDC4P2_BO			65
-
-
-#define NR_REAL_IRQS	128
-#define NR_IRQS		(NR_REAL_IRQS + 32 * 3)
-
-/* All interrupts are FIQ capable */
-#define FIQ_START		IRQ_DEBUG_UART
-
-/* Hard disk IRQ is a GPMI attention IRQ */
-#define IRQ_HARDDISK		IRQ_GPMI_ATTENTION
diff -druN linux-2.6.39-libre/arch/arm/mach-stmp378x/include/mach/pins.h linux-3.0-rc7-libre/arch/arm/mach-stmp378x/include/mach/pins.h
--- linux-2.6.39-libre/arch/arm/mach-stmp378x/include/mach/pins.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-stmp378x/include/mach/pins.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,151 +0,0 @@
-/*
- * Freescale STMP378X SoC pin multiplexing
- *
- * Author: Vladislav Buzov <vbuzov@embeddedalley.com>
- *
- * Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved.
- * Copyright 2008 Embedded Alley Solutions, 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 __ASM_ARCH_PINS_H
-#define __ASM_ARCH_PINS_H
-
-/*
- * Define all STMP378x pins, a pin name corresponds to a STMP378x hardware
- * interface  this pin belongs to.
- */
-
-/* Bank 0 */
-#define PINID_GPMI_D00		STMP3XXX_PINID(0, 0)
-#define PINID_GPMI_D01		STMP3XXX_PINID(0, 1)
-#define PINID_GPMI_D02		STMP3XXX_PINID(0, 2)
-#define PINID_GPMI_D03		STMP3XXX_PINID(0, 3)
-#define PINID_GPMI_D04		STMP3XXX_PINID(0, 4)
-#define PINID_GPMI_D05		STMP3XXX_PINID(0, 5)
-#define PINID_GPMI_D06		STMP3XXX_PINID(0, 6)
-#define PINID_GPMI_D07		STMP3XXX_PINID(0, 7)
-#define PINID_GPMI_D08		STMP3XXX_PINID(0, 8)
-#define PINID_GPMI_D09		STMP3XXX_PINID(0, 9)
-#define PINID_GPMI_D10		STMP3XXX_PINID(0, 10)
-#define PINID_GPMI_D11		STMP3XXX_PINID(0, 11)
-#define PINID_GPMI_D12		STMP3XXX_PINID(0, 12)
-#define PINID_GPMI_D13		STMP3XXX_PINID(0, 13)
-#define PINID_GPMI_D14		STMP3XXX_PINID(0, 14)
-#define PINID_GPMI_D15		STMP3XXX_PINID(0, 15)
-#define PINID_GPMI_CLE		STMP3XXX_PINID(0, 16)
-#define PINID_GPMI_ALE		STMP3XXX_PINID(0, 17)
-#define PINID_GMPI_CE2N		STMP3XXX_PINID(0, 18)
-#define PINID_GPMI_RDY0		STMP3XXX_PINID(0, 19)
-#define PINID_GPMI_RDY1		STMP3XXX_PINID(0, 20)
-#define PINID_GPMI_RDY2		STMP3XXX_PINID(0, 21)
-#define PINID_GPMI_RDY3		STMP3XXX_PINID(0, 22)
-#define PINID_GPMI_WPN		STMP3XXX_PINID(0, 23)
-#define PINID_GPMI_WRN		STMP3XXX_PINID(0, 24)
-#define PINID_GPMI_RDN		STMP3XXX_PINID(0, 25)
-#define PINID_AUART1_CTS	STMP3XXX_PINID(0, 26)
-#define PINID_AUART1_RTS	STMP3XXX_PINID(0, 27)
-#define PINID_AUART1_RX		STMP3XXX_PINID(0, 28)
-#define PINID_AUART1_TX		STMP3XXX_PINID(0, 29)
-#define PINID_I2C_SCL		STMP3XXX_PINID(0, 30)
-#define PINID_I2C_SDA		STMP3XXX_PINID(0, 31)
-
-/* Bank 1 */
-#define PINID_LCD_D00		STMP3XXX_PINID(1, 0)
-#define PINID_LCD_D01		STMP3XXX_PINID(1, 1)
-#define PINID_LCD_D02		STMP3XXX_PINID(1, 2)
-#define PINID_LCD_D03		STMP3XXX_PINID(1, 3)
-#define PINID_LCD_D04		STMP3XXX_PINID(1, 4)
-#define PINID_LCD_D05		STMP3XXX_PINID(1, 5)
-#define PINID_LCD_D06		STMP3XXX_PINID(1, 6)
-#define PINID_LCD_D07		STMP3XXX_PINID(1, 7)
-#define PINID_LCD_D08		STMP3XXX_PINID(1, 8)
-#define PINID_LCD_D09		STMP3XXX_PINID(1, 9)
-#define PINID_LCD_D10		STMP3XXX_PINID(1, 10)
-#define PINID_LCD_D11		STMP3XXX_PINID(1, 11)
-#define PINID_LCD_D12		STMP3XXX_PINID(1, 12)
-#define PINID_LCD_D13		STMP3XXX_PINID(1, 13)
-#define PINID_LCD_D14		STMP3XXX_PINID(1, 14)
-#define PINID_LCD_D15		STMP3XXX_PINID(1, 15)
-#define PINID_LCD_D16		STMP3XXX_PINID(1, 16)
-#define PINID_LCD_D17		STMP3XXX_PINID(1, 17)
-#define PINID_LCD_RESET		STMP3XXX_PINID(1, 18)
-#define PINID_LCD_RS		STMP3XXX_PINID(1, 19)
-#define PINID_LCD_WR		STMP3XXX_PINID(1, 20)
-#define PINID_LCD_CS		STMP3XXX_PINID(1, 21)
-#define PINID_LCD_DOTCK		STMP3XXX_PINID(1, 22)
-#define PINID_LCD_ENABLE	STMP3XXX_PINID(1, 23)
-#define PINID_LCD_HSYNC		STMP3XXX_PINID(1, 24)
-#define PINID_LCD_VSYNC		STMP3XXX_PINID(1, 25)
-#define PINID_PWM0		STMP3XXX_PINID(1, 26)
-#define PINID_PWM1		STMP3XXX_PINID(1, 27)
-#define PINID_PWM2		STMP3XXX_PINID(1, 28)
-#define PINID_PWM3		STMP3XXX_PINID(1, 29)
-#define PINID_PWM4		STMP3XXX_PINID(1, 30)
-
-/* Bank 2 */
-#define PINID_SSP1_CMD		STMP3XXX_PINID(2, 0)
-#define PINID_SSP1_DETECT	STMP3XXX_PINID(2, 1)
-#define PINID_SSP1_DATA0	STMP3XXX_PINID(2, 2)
-#define PINID_SSP1_DATA1	STMP3XXX_PINID(2, 3)
-#define PINID_SSP1_DATA2	STMP3XXX_PINID(2, 4)
-#define PINID_SSP1_DATA3	STMP3XXX_PINID(2, 5)
-#define PINID_SSP1_SCK		STMP3XXX_PINID(2, 6)
-#define PINID_ROTARYA		STMP3XXX_PINID(2, 7)
-#define PINID_ROTARYB		STMP3XXX_PINID(2, 8)
-#define PINID_EMI_A00		STMP3XXX_PINID(2, 9)
-#define PINID_EMI_A01		STMP3XXX_PINID(2, 10)
-#define PINID_EMI_A02		STMP3XXX_PINID(2, 11)
-#define PINID_EMI_A03		STMP3XXX_PINID(2, 12)
-#define PINID_EMI_A04		STMP3XXX_PINID(2, 13)
-#define PINID_EMI_A05		STMP3XXX_PINID(2, 14)
-#define PINID_EMI_A06		STMP3XXX_PINID(2, 15)
-#define PINID_EMI_A07		STMP3XXX_PINID(2, 16)
-#define PINID_EMI_A08		STMP3XXX_PINID(2, 17)
-#define PINID_EMI_A09		STMP3XXX_PINID(2, 18)
-#define PINID_EMI_A10		STMP3XXX_PINID(2, 19)
-#define PINID_EMI_A11		STMP3XXX_PINID(2, 20)
-#define PINID_EMI_A12		STMP3XXX_PINID(2, 21)
-#define PINID_EMI_BA0		STMP3XXX_PINID(2, 22)
-#define PINID_EMI_BA1		STMP3XXX_PINID(2, 23)
-#define PINID_EMI_CASN		STMP3XXX_PINID(2, 24)
-#define PINID_EMI_CE0N		STMP3XXX_PINID(2, 25)
-#define PINID_EMI_CE1N		STMP3XXX_PINID(2, 26)
-#define PINID_GPMI_CE1N		STMP3XXX_PINID(2, 27)
-#define PINID_GPMI_CE0N		STMP3XXX_PINID(2, 28)
-#define PINID_EMI_CKE		STMP3XXX_PINID(2, 29)
-#define PINID_EMI_RASN		STMP3XXX_PINID(2, 30)
-#define PINID_EMI_WEN		STMP3XXX_PINID(2, 31)
-
-/* Bank 3 */
-#define PINID_EMI_D00		STMP3XXX_PINID(3, 0)
-#define PINID_EMI_D01		STMP3XXX_PINID(3, 1)
-#define PINID_EMI_D02		STMP3XXX_PINID(3, 2)
-#define PINID_EMI_D03		STMP3XXX_PINID(3, 3)
-#define PINID_EMI_D04		STMP3XXX_PINID(3, 4)
-#define PINID_EMI_D05		STMP3XXX_PINID(3, 5)
-#define PINID_EMI_D06		STMP3XXX_PINID(3, 6)
-#define PINID_EMI_D07		STMP3XXX_PINID(3, 7)
-#define PINID_EMI_D08		STMP3XXX_PINID(3, 8)
-#define PINID_EMI_D09		STMP3XXX_PINID(3, 9)
-#define PINID_EMI_D10		STMP3XXX_PINID(3, 10)
-#define PINID_EMI_D11		STMP3XXX_PINID(3, 11)
-#define PINID_EMI_D12		STMP3XXX_PINID(3, 12)
-#define PINID_EMI_D13		STMP3XXX_PINID(3, 13)
-#define PINID_EMI_D14		STMP3XXX_PINID(3, 14)
-#define PINID_EMI_D15		STMP3XXX_PINID(3, 15)
-#define PINID_EMI_DQM0		STMP3XXX_PINID(3, 16)
-#define PINID_EMI_DQM1		STMP3XXX_PINID(3, 17)
-#define PINID_EMI_DQS0		STMP3XXX_PINID(3, 18)
-#define PINID_EMI_DQS1		STMP3XXX_PINID(3, 19)
-#define PINID_EMI_CLK		STMP3XXX_PINID(3, 20)
-#define PINID_EMI_CLKN		STMP3XXX_PINID(3, 21)
-
-#endif /* __ASM_ARCH_PINS_H */
diff -druN linux-2.6.39-libre/arch/arm/mach-stmp378x/include/mach/regs-apbh.h linux-3.0-rc7-libre/arch/arm/mach-stmp378x/include/mach/regs-apbh.h
--- linux-2.6.39-libre/arch/arm/mach-stmp378x/include/mach/regs-apbh.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-stmp378x/include/mach/regs-apbh.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,101 +0,0 @@
-/*
- * stmp378x: APBH register definitions
- *
- * Copyright (c) 2008 Freescale Semiconductor
- * Copyright 2008 Embedded Alley Solutions, 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
- */
-#ifndef _MACH_REGS_APBH
-#define _MACH_REGS_APBH
-
-#define REGS_APBH_BASE	(STMP3XXX_REGS_BASE + 0x4000)
-#define REGS_APBH_PHYS	0x80004000
-#define REGS_APBH_SIZE	0x2000
-
-#define HW_APBH_CTRL0		0x0
-#define BM_APBH_CTRL0_RESET_CHANNEL	0x00FF0000
-#define BP_APBH_CTRL0_RESET_CHANNEL	16
-#define BM_APBH_CTRL0_CLKGATE	0x40000000
-#define BM_APBH_CTRL0_SFTRST	0x80000000
-
-#define HW_APBH_CTRL1		0x10
-#define BM_APBH_CTRL1_CH0_CMDCMPLT_IRQ	0x00000001
-#define BP_APBH_CTRL1_CH0_CMDCMPLT_IRQ	0
-
-#define HW_APBH_CTRL2		0x20
-
-#define HW_APBH_DEVSEL		0x30
-
-#define HW_APBH_CH0_NXTCMDAR	(0x50 + 0 * 0x70)
-#define HW_APBH_CH1_NXTCMDAR	(0x50 + 1 * 0x70)
-#define HW_APBH_CH2_NXTCMDAR	(0x50 + 2 * 0x70)
-#define HW_APBH_CH3_NXTCMDAR	(0x50 + 3 * 0x70)
-#define HW_APBH_CH4_NXTCMDAR	(0x50 + 4 * 0x70)
-#define HW_APBH_CH5_NXTCMDAR	(0x50 + 5 * 0x70)
-#define HW_APBH_CH6_NXTCMDAR	(0x50 + 6 * 0x70)
-#define HW_APBH_CH7_NXTCMDAR	(0x50 + 7 * 0x70)
-#define HW_APBH_CH8_NXTCMDAR	(0x50 + 8 * 0x70)
-#define HW_APBH_CH9_NXTCMDAR	(0x50 + 9 * 0x70)
-#define HW_APBH_CH10_NXTCMDAR	(0x50 + 10 * 0x70)
-#define HW_APBH_CH11_NXTCMDAR	(0x50 + 11 * 0x70)
-#define HW_APBH_CH12_NXTCMDAR	(0x50 + 12 * 0x70)
-#define HW_APBH_CH13_NXTCMDAR	(0x50 + 13 * 0x70)
-#define HW_APBH_CH14_NXTCMDAR	(0x50 + 14 * 0x70)
-#define HW_APBH_CH15_NXTCMDAR	(0x50 + 15 * 0x70)
-
-#define HW_APBH_CHn_NXTCMDAR	0x50
-
-#define BV_APBH_CHn_CMD_COMMAND__NO_DMA_XFER	 0
-#define BV_APBH_CHn_CMD_COMMAND__DMA_WRITE	 1
-#define BV_APBH_CHn_CMD_COMMAND__DMA_READ	 2
-#define BV_APBH_CHn_CMD_COMMAND__DMA_SENSE	 3
-#define BM_APBH_CHn_CMD_COMMAND	0x00000003
-#define BP_APBH_CHn_CMD_COMMAND	0
-#define BM_APBH_CHn_CMD_CHAIN	0x00000004
-#define BM_APBH_CHn_CMD_IRQONCMPLT	0x00000008
-#define BM_APBH_CHn_CMD_NANDLOCK	0x00000010
-#define BM_APBH_CHn_CMD_NANDWAIT4READY	0x00000020
-#define BM_APBH_CHn_CMD_SEMAPHORE	0x00000040
-#define BM_APBH_CHn_CMD_WAIT4ENDCMD	0x00000080
-#define BM_APBH_CHn_CMD_CMDWORDS	0x0000F000
-#define BP_APBH_CHn_CMD_CMDWORDS	12
-#define BM_APBH_CHn_CMD_XFER_COUNT	0xFFFF0000
-#define BP_APBH_CHn_CMD_XFER_COUNT	16
-
-#define HW_APBH_CH0_SEMA	(0x80 + 0 * 0x70)
-#define HW_APBH_CH1_SEMA	(0x80 + 1 * 0x70)
-#define HW_APBH_CH2_SEMA	(0x80 + 2 * 0x70)
-#define HW_APBH_CH3_SEMA	(0x80 + 3 * 0x70)
-#define HW_APBH_CH4_SEMA	(0x80 + 4 * 0x70)
-#define HW_APBH_CH5_SEMA	(0x80 + 5 * 0x70)
-#define HW_APBH_CH6_SEMA	(0x80 + 6 * 0x70)
-#define HW_APBH_CH7_SEMA	(0x80 + 7 * 0x70)
-#define HW_APBH_CH8_SEMA	(0x80 + 8 * 0x70)
-#define HW_APBH_CH9_SEMA	(0x80 + 9 * 0x70)
-#define HW_APBH_CH10_SEMA	(0x80 + 10 * 0x70)
-#define HW_APBH_CH11_SEMA	(0x80 + 11 * 0x70)
-#define HW_APBH_CH12_SEMA	(0x80 + 12 * 0x70)
-#define HW_APBH_CH13_SEMA	(0x80 + 13 * 0x70)
-#define HW_APBH_CH14_SEMA	(0x80 + 14 * 0x70)
-#define HW_APBH_CH15_SEMA	(0x80 + 15 * 0x70)
-
-#define HW_APBH_CHn_SEMA	0x80
-#define BM_APBH_CHn_SEMA_INCREMENT_SEMA	0x000000FF
-#define BP_APBH_CHn_SEMA_INCREMENT_SEMA	0
-#define BM_APBH_CHn_SEMA_PHORE	0x00FF0000
-#define BP_APBH_CHn_SEMA_PHORE	16
-
-#endif
diff -druN linux-2.6.39-libre/arch/arm/mach-stmp378x/include/mach/regs-apbx.h linux-3.0-rc7-libre/arch/arm/mach-stmp378x/include/mach/regs-apbx.h
--- linux-2.6.39-libre/arch/arm/mach-stmp378x/include/mach/regs-apbx.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-stmp378x/include/mach/regs-apbx.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,119 +0,0 @@
-/*
- * stmp378x: APBX register definitions
- *
- * Copyright (c) 2008 Freescale Semiconductor
- * Copyright 2008 Embedded Alley Solutions, 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
- */
-#ifndef _MACH_REGS_APBX
-#define _MACH_REGS_APBX
-
-#define REGS_APBX_BASE	(STMP3XXX_REGS_BASE + 0x24000)
-#define REGS_APBX_PHYS	0x80024000
-#define REGS_APBX_SIZE	0x2000
-
-#define HW_APBX_CTRL0		0x0
-#define BM_APBX_CTRL0_CLKGATE	0x40000000
-#define BM_APBX_CTRL0_SFTRST	0x80000000
-
-#define HW_APBX_CTRL1		0x10
-
-#define HW_APBX_CTRL2		0x20
-
-#define HW_APBX_CHANNEL_CTRL	0x30
-#define BM_APBX_CHANNEL_CTRL_RESET_CHANNEL	0xFFFF0000
-#define BP_APBX_CHANNEL_CTRL_RESET_CHANNEL	16
-
-#define HW_APBX_DEVSEL		0x40
-
-#define HW_APBX_CH0_NXTCMDAR	(0x110 + 0 * 0x70)
-#define HW_APBX_CH1_NXTCMDAR	(0x110 + 1 * 0x70)
-#define HW_APBX_CH2_NXTCMDAR	(0x110 + 2 * 0x70)
-#define HW_APBX_CH3_NXTCMDAR	(0x110 + 3 * 0x70)
-#define HW_APBX_CH4_NXTCMDAR	(0x110 + 4 * 0x70)
-#define HW_APBX_CH5_NXTCMDAR	(0x110 + 5 * 0x70)
-#define HW_APBX_CH6_NXTCMDAR	(0x110 + 6 * 0x70)
-#define HW_APBX_CH7_NXTCMDAR	(0x110 + 7 * 0x70)
-#define HW_APBX_CH8_NXTCMDAR	(0x110 + 8 * 0x70)
-#define HW_APBX_CH9_NXTCMDAR	(0x110 + 9 * 0x70)
-#define HW_APBX_CH10_NXTCMDAR	(0x110 + 10 * 0x70)
-#define HW_APBX_CH11_NXTCMDAR	(0x110 + 11 * 0x70)
-#define HW_APBX_CH12_NXTCMDAR	(0x110 + 12 * 0x70)
-#define HW_APBX_CH13_NXTCMDAR	(0x110 + 13 * 0x70)
-#define HW_APBX_CH14_NXTCMDAR	(0x110 + 14 * 0x70)
-#define HW_APBX_CH15_NXTCMDAR	(0x110 + 15 * 0x70)
-
-#define HW_APBX_CHn_NXTCMDAR	0x110
-#define BM_APBX_CHn_CMD_COMMAND	0x00000003
-#define BP_APBX_CHn_CMD_COMMAND	0
-#define BV_APBX_CHn_CMD_COMMAND__NO_DMA_XFER	 0
-#define BV_APBX_CHn_CMD_COMMAND__DMA_WRITE	 1
-#define BV_APBX_CHn_CMD_COMMAND__DMA_READ	 2
-#define BV_APBX_CHn_CMD_COMMAND__DMA_SENSE	 3
-#define BM_APBX_CHn_CMD_CHAIN	0x00000004
-#define BM_APBX_CHn_CMD_IRQONCMPLT	0x00000008
-#define BM_APBX_CHn_CMD_SEMAPHORE	0x00000040
-#define BM_APBX_CHn_CMD_WAIT4ENDCMD	0x00000080
-#define BM_APBX_CHn_CMD_HALTONTERMINATE	0x00000100
-#define BM_APBX_CHn_CMD_CMDWORDS	0x0000F000
-#define BP_APBX_CHn_CMD_CMDWORDS	12
-#define BM_APBX_CHn_CMD_XFER_COUNT	0xFFFF0000
-#define BP_APBX_CHn_CMD_XFER_COUNT	16
-
-#define HW_APBX_CH0_BAR		(0x130 + 0 * 0x70)
-#define HW_APBX_CH1_BAR		(0x130 + 1 * 0x70)
-#define HW_APBX_CH2_BAR		(0x130 + 2 * 0x70)
-#define HW_APBX_CH3_BAR		(0x130 + 3 * 0x70)
-#define HW_APBX_CH4_BAR		(0x130 + 4 * 0x70)
-#define HW_APBX_CH5_BAR		(0x130 + 5 * 0x70)
-#define HW_APBX_CH6_BAR		(0x130 + 6 * 0x70)
-#define HW_APBX_CH7_BAR		(0x130 + 7 * 0x70)
-#define HW_APBX_CH8_BAR		(0x130 + 8 * 0x70)
-#define HW_APBX_CH9_BAR		(0x130 + 9 * 0x70)
-#define HW_APBX_CH10_BAR		(0x130 + 10 * 0x70)
-#define HW_APBX_CH11_BAR		(0x130 + 11 * 0x70)
-#define HW_APBX_CH12_BAR		(0x130 + 12 * 0x70)
-#define HW_APBX_CH13_BAR		(0x130 + 13 * 0x70)
-#define HW_APBX_CH14_BAR		(0x130 + 14 * 0x70)
-#define HW_APBX_CH15_BAR		(0x130 + 15 * 0x70)
-
-#define HW_APBX_CHn_BAR		0x130
-
-#define HW_APBX_CH0_SEMA	(0x140 + 0 * 0x70)
-#define HW_APBX_CH1_SEMA	(0x140 + 1 * 0x70)
-#define HW_APBX_CH2_SEMA	(0x140 + 2 * 0x70)
-#define HW_APBX_CH3_SEMA	(0x140 + 3 * 0x70)
-#define HW_APBX_CH4_SEMA	(0x140 + 4 * 0x70)
-#define HW_APBX_CH5_SEMA	(0x140 + 5 * 0x70)
-#define HW_APBX_CH6_SEMA	(0x140 + 6 * 0x70)
-#define HW_APBX_CH7_SEMA	(0x140 + 7 * 0x70)
-#define HW_APBX_CH8_SEMA	(0x140 + 8 * 0x70)
-#define HW_APBX_CH9_SEMA	(0x140 + 9 * 0x70)
-#define HW_APBX_CH10_SEMA	(0x140 + 10 * 0x70)
-#define HW_APBX_CH11_SEMA	(0x140 + 11 * 0x70)
-#define HW_APBX_CH12_SEMA	(0x140 + 12 * 0x70)
-#define HW_APBX_CH13_SEMA	(0x140 + 13 * 0x70)
-#define HW_APBX_CH14_SEMA	(0x140 + 14 * 0x70)
-#define HW_APBX_CH15_SEMA	(0x140 + 15 * 0x70)
-
-#define HW_APBX_CHn_SEMA	0x140
-#define BM_APBX_CHn_SEMA_INCREMENT_SEMA	0x000000FF
-#define BP_APBX_CHn_SEMA_INCREMENT_SEMA	0
-#define BM_APBX_CHn_SEMA_PHORE	0x00FF0000
-#define BP_APBX_CHn_SEMA_PHORE	16
-
-#endif
-
diff -druN linux-2.6.39-libre/arch/arm/mach-stmp378x/include/mach/regs-audioin.h linux-3.0-rc7-libre/arch/arm/mach-stmp378x/include/mach/regs-audioin.h
--- linux-2.6.39-libre/arch/arm/mach-stmp378x/include/mach/regs-audioin.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-stmp378x/include/mach/regs-audioin.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,63 +0,0 @@
-/*
- * stmp378x: AUDIOIN register definitions
- *
- * Copyright (c) 2008 Freescale Semiconductor
- * Copyright 2008 Embedded Alley Solutions, 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
- */
-#define REGS_AUDIOIN_BASE	(STMP3XXX_REGS_BASE + 0x4C000)
-#define REGS_AUDIOIN_PHYS	0x8004C000
-#define REGS_AUDIOIN_SIZE	0x2000
-
-#define HW_AUDIOIN_CTRL		0x0
-#define BM_AUDIOIN_CTRL_RUN	0x00000001
-#define BP_AUDIOIN_CTRL_RUN	0
-#define BM_AUDIOIN_CTRL_FIFO_ERROR_IRQ_EN	0x00000002
-#define BM_AUDIOIN_CTRL_FIFO_OVERFLOW_IRQ	0x00000004
-#define BM_AUDIOIN_CTRL_FIFO_UNDERFLOW_IRQ	0x00000008
-#define BM_AUDIOIN_CTRL_WORD_LENGTH	0x00000020
-#define BM_AUDIOIN_CTRL_CLKGATE	0x40000000
-#define BM_AUDIOIN_CTRL_SFTRST	0x80000000
-
-#define HW_AUDIOIN_STAT		0x10
-
-#define HW_AUDIOIN_ADCSRR	0x20
-
-#define HW_AUDIOIN_ADCVOLUME	0x30
-#define BM_AUDIOIN_ADCVOLUME_VOLUME_RIGHT	0x000000FF
-#define BP_AUDIOIN_ADCVOLUME_VOLUME_RIGHT	0
-#define BM_AUDIOIN_ADCVOLUME_VOLUME_LEFT	0x00FF0000
-#define BP_AUDIOIN_ADCVOLUME_VOLUME_LEFT	16
-
-#define HW_AUDIOIN_ADCDEBUG	0x40
-
-#define HW_AUDIOIN_ADCVOL	0x50
-#define BM_AUDIOIN_ADCVOL_GAIN_RIGHT	0x0000000F
-#define BP_AUDIOIN_ADCVOL_GAIN_RIGHT	0
-#define BM_AUDIOIN_ADCVOL_SELECT_RIGHT	0x00000030
-#define BP_AUDIOIN_ADCVOL_SELECT_RIGHT	4
-#define BM_AUDIOIN_ADCVOL_GAIN_LEFT	0x00000F00
-#define BP_AUDIOIN_ADCVOL_GAIN_LEFT	8
-#define BM_AUDIOIN_ADCVOL_SELECT_LEFT	0x00003000
-#define BP_AUDIOIN_ADCVOL_SELECT_LEFT	12
-#define BM_AUDIOIN_ADCVOL_MUTE	0x01000000
-
-#define HW_AUDIOIN_MICLINE	0x60
-
-#define HW_AUDIOIN_ANACLKCTRL	0x70
-#define BM_AUDIOIN_ANACLKCTRL_CLKGATE	0x80000000
-
-#define HW_AUDIOIN_DATA		0x80
diff -druN linux-2.6.39-libre/arch/arm/mach-stmp378x/include/mach/regs-audioout.h linux-3.0-rc7-libre/arch/arm/mach-stmp378x/include/mach/regs-audioout.h
--- linux-2.6.39-libre/arch/arm/mach-stmp378x/include/mach/regs-audioout.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-stmp378x/include/mach/regs-audioout.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,104 +0,0 @@
-/*
- * stmp378x: AUDIOOUT register definitions
- *
- * Copyright (c) 2008 Freescale Semiconductor
- * Copyright 2008 Embedded Alley Solutions, 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
- */
-#define REGS_AUDIOOUT_BASE	(STMP3XXX_REGS_BASE + 0x48000)
-#define REGS_AUDIOOUT_PHYS	0x80048000
-#define REGS_AUDIOOUT_SIZE	0x2000
-
-#define HW_AUDIOOUT_CTRL	0x0
-#define BM_AUDIOOUT_CTRL_RUN	0x00000001
-#define BP_AUDIOOUT_CTRL_RUN	0
-#define BM_AUDIOOUT_CTRL_FIFO_ERROR_IRQ_EN	0x00000002
-#define BM_AUDIOOUT_CTRL_FIFO_OVERFLOW_IRQ	0x00000004
-#define BM_AUDIOOUT_CTRL_FIFO_UNDERFLOW_IRQ	0x00000008
-#define BM_AUDIOOUT_CTRL_WORD_LENGTH	0x00000040
-#define BM_AUDIOOUT_CTRL_CLKGATE	0x40000000
-#define BM_AUDIOOUT_CTRL_SFTRST	0x80000000
-
-#define HW_AUDIOOUT_STAT	0x10
-
-#define HW_AUDIOOUT_DACSRR	0x20
-#define BM_AUDIOOUT_DACSRR_SRC_FRAC	0x00001FFF
-#define BP_AUDIOOUT_DACSRR_SRC_FRAC	0
-#define BM_AUDIOOUT_DACSRR_SRC_INT	0x001F0000
-#define BP_AUDIOOUT_DACSRR_SRC_INT	16
-#define BM_AUDIOOUT_DACSRR_SRC_HOLD	0x07000000
-#define BP_AUDIOOUT_DACSRR_SRC_HOLD	24
-#define BM_AUDIOOUT_DACSRR_BASEMULT	0x70000000
-#define BP_AUDIOOUT_DACSRR_BASEMULT	28
-
-#define HW_AUDIOOUT_DACVOLUME	0x30
-#define BM_AUDIOOUT_DACVOLUME_MUTE_RIGHT	0x00000100
-#define BM_AUDIOOUT_DACVOLUME_MUTE_LEFT	0x01000000
-#define BM_AUDIOOUT_DACVOLUME_EN_ZCD	0x02000000
-
-#define HW_AUDIOOUT_DACDEBUG	0x40
-
-#define HW_AUDIOOUT_HPVOL	0x50
-#define BM_AUDIOOUT_HPVOL_MUTE	0x01000000
-#define BM_AUDIOOUT_HPVOL_EN_MSTR_ZCD	0x02000000
-
-#define HW_AUDIOOUT_PWRDN	0x70
-#define BM_AUDIOOUT_PWRDN_HEADPHONE	0x00000001
-#define BP_AUDIOOUT_PWRDN_HEADPHONE	0
-#define BM_AUDIOOUT_PWRDN_CAPLESS	0x00000010
-#define BM_AUDIOOUT_PWRDN_ADC	0x00000100
-#define BM_AUDIOOUT_PWRDN_DAC	0x00001000
-#define BM_AUDIOOUT_PWRDN_RIGHT_ADC	0x00010000
-#define BM_AUDIOOUT_PWRDN_SPEAKER	0x01000000
-
-#define HW_AUDIOOUT_REFCTRL	0x80
-#define BM_AUDIOOUT_REFCTRL_VAG_VAL	0x000000F0
-#define BP_AUDIOOUT_REFCTRL_VAG_VAL	4
-#define BM_AUDIOOUT_REFCTRL_ADC_REFVAL	0x00000F00
-#define BP_AUDIOOUT_REFCTRL_ADC_REFVAL	8
-#define BM_AUDIOOUT_REFCTRL_ADJ_VAG	0x00001000
-#define BM_AUDIOOUT_REFCTRL_ADJ_ADC	0x00002000
-#define BM_AUDIOOUT_REFCTRL_BIAS_CTRL	0x00030000
-#define BP_AUDIOOUT_REFCTRL_BIAS_CTRL	16
-#define BM_AUDIOOUT_REFCTRL_LOW_PWR	0x00080000
-#define BM_AUDIOOUT_REFCTRL_VBG_ADJ	0x00700000
-#define BP_AUDIOOUT_REFCTRL_VBG_ADJ	20
-#define BM_AUDIOOUT_REFCTRL_XTAL_BGR_BIAS	0x01000000
-#define BM_AUDIOOUT_REFCTRL_RAISE_REF	0x02000000
-
-#define HW_AUDIOOUT_ANACTRL	0x90
-#define BM_AUDIOOUT_ANACTRL_HP_CLASSAB	0x00000010
-#define BM_AUDIOOUT_ANACTRL_HP_HOLD_GND	0x00000020
-
-#define HW_AUDIOOUT_TEST	0xA0
-#define BM_AUDIOOUT_TEST_HP_I1_ADJ	0x00C00000
-#define BP_AUDIOOUT_TEST_HP_I1_ADJ	22
-
-#define HW_AUDIOOUT_BISTCTRL	0xB0
-
-#define HW_AUDIOOUT_BISTSTAT0	0xC0
-
-#define HW_AUDIOOUT_BISTSTAT1	0xD0
-
-#define HW_AUDIOOUT_ANACLKCTRL	0xE0
-#define BM_AUDIOOUT_ANACLKCTRL_CLKGATE	0x80000000
-
-#define HW_AUDIOOUT_DATA	0xF0
-
-#define HW_AUDIOOUT_SPEAKERCTRL	0x100
-#define BM_AUDIOOUT_SPEAKERCTRL_MUTE	0x01000000
-
-#define HW_AUDIOOUT_VERSION	0x200
diff -druN linux-2.6.39-libre/arch/arm/mach-stmp378x/include/mach/regs-bch.h linux-3.0-rc7-libre/arch/arm/mach-stmp378x/include/mach/regs-bch.h
--- linux-2.6.39-libre/arch/arm/mach-stmp378x/include/mach/regs-bch.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-stmp378x/include/mach/regs-bch.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,56 +0,0 @@
-/*
- * stmp378x: BCH register definitions
- *
- * Copyright (c) 2008 Freescale Semiconductor
- * Copyright 2008 Embedded Alley Solutions, 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
- */
-#define REGS_BCH_BASE	(STMP3XXX_REGS_BASE + 0xA000)
-#define REGS_BCH_PHYS	0x8000A000
-#define REGS_BCH_SIZE	0x2000
-
-#define HW_BCH_CTRL		0x0
-#define BM_BCH_CTRL_COMPLETE_IRQ	0x00000001
-#define BP_BCH_CTRL_COMPLETE_IRQ	0
-#define BM_BCH_CTRL_COMPLETE_IRQ_EN	0x00000100
-
-#define HW_BCH_STATUS0		0x10
-#define BM_BCH_STATUS0_UNCORRECTABLE	0x00000004
-#define BM_BCH_STATUS0_CORRECTED	0x00000008
-#define BM_BCH_STATUS0_STATUS_BLK0	0x0000FF00
-#define BP_BCH_STATUS0_STATUS_BLK0	8
-#define BM_BCH_STATUS0_COMPLETED_CE	0x000F0000
-#define BP_BCH_STATUS0_COMPLETED_CE	16
-
-#define HW_BCH_LAYOUTSELECT	0x70
-
-#define HW_BCH_FLASH0LAYOUT0	0x80
-#define BM_BCH_FLASH0LAYOUT0_DATA0_SIZE	0x00000FFF
-#define BP_BCH_FLASH0LAYOUT0_DATA0_SIZE	0
-#define BM_BCH_FLASH0LAYOUT0_ECC0	0x0000F000
-#define BP_BCH_FLASH0LAYOUT0_ECC0	12
-#define BM_BCH_FLASH0LAYOUT0_META_SIZE	0x00FF0000
-#define BP_BCH_FLASH0LAYOUT0_META_SIZE	16
-#define BM_BCH_FLASH0LAYOUT0_NBLOCKS	0xFF000000
-#define BP_BCH_FLASH0LAYOUT0_NBLOCKS	24
-#define BM_BCH_FLASH0LAYOUT1_DATAN_SIZE	0x00000FFF
-#define BP_BCH_FLASH0LAYOUT1_DATAN_SIZE	0
-#define BM_BCH_FLASH0LAYOUT1_ECCN	0x0000F000
-#define BP_BCH_FLASH0LAYOUT1_ECCN	12
-#define BM_BCH_FLASH0LAYOUT1_PAGE_SIZE	0xFFFF0000
-#define BP_BCH_FLASH0LAYOUT1_PAGE_SIZE	16
-
-#define HW_BCH_BLOCKNAME	0x150
diff -druN linux-2.6.39-libre/arch/arm/mach-stmp378x/include/mach/regs-clkctrl.h linux-3.0-rc7-libre/arch/arm/mach-stmp378x/include/mach/regs-clkctrl.h
--- linux-2.6.39-libre/arch/arm/mach-stmp378x/include/mach/regs-clkctrl.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-stmp378x/include/mach/regs-clkctrl.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,88 +0,0 @@
-/*
- * stmp378x: CLKCTRL register definitions
- *
- * Copyright (c) 2008 Freescale Semiconductor
- * Copyright 2008 Embedded Alley Solutions, 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
- */
-#ifndef _MACH_REGS_CLKCTRL
-#define _MACH_REGS_CLKCTRL
-
-#define REGS_CLKCTRL_BASE	(STMP3XXX_REGS_BASE + 0x40000)
-#define REGS_CLKCTRL_PHYS	0x80040000
-#define REGS_CLKCTRL_SIZE	0x2000
-
-#define HW_CLKCTRL_PLLCTRL0	0x0
-#define BM_CLKCTRL_PLLCTRL0_EN_USB_CLKS	0x00040000
-
-#define HW_CLKCTRL_CPU		0x20
-#define BM_CLKCTRL_CPU_DIV_CPU	0x0000003F
-#define BP_CLKCTRL_CPU_DIV_CPU	0
-
-#define HW_CLKCTRL_HBUS		0x30
-#define BM_CLKCTRL_HBUS_DIV	0x0000001F
-#define BP_CLKCTRL_HBUS_DIV	0
-#define BM_CLKCTRL_HBUS_DIV_FRAC_EN	0x00000020
-
-#define HW_CLKCTRL_XBUS		0x40
-
-#define HW_CLKCTRL_XTAL		0x50
-#define BM_CLKCTRL_XTAL_DRI_CLK24M_GATE	0x10000000
-
-#define HW_CLKCTRL_PIX		0x60
-#define BM_CLKCTRL_PIX_DIV	0x00000FFF
-#define BP_CLKCTRL_PIX_DIV	0
-#define BM_CLKCTRL_PIX_CLKGATE	0x80000000
-
-#define HW_CLKCTRL_SSP		0x70
-
-#define HW_CLKCTRL_GPMI		0x80
-
-#define HW_CLKCTRL_SPDIF	0x90
-
-#define HW_CLKCTRL_EMI		0xA0
-#define BM_CLKCTRL_EMI_DIV_EMI	0x0000003F
-#define BP_CLKCTRL_EMI_DIV_EMI	0
-#define BM_CLKCTRL_EMI_DCC_RESYNC_ENABLE	0x00010000
-#define BM_CLKCTRL_EMI_BUSY_DCC_RESYNC	0x00020000
-#define BM_CLKCTRL_EMI_BUSY_REF_EMI	0x10000000
-#define BM_CLKCTRL_EMI_BUSY_REF_XTAL	0x20000000
-
-#define HW_CLKCTRL_IR		0xB0
-
-#define HW_CLKCTRL_SAIF		0xC0
-
-#define HW_CLKCTRL_TV		0xD0
-
-#define HW_CLKCTRL_ETM		0xE0
-
-#define HW_CLKCTRL_FRAC		0xF0
-#define BM_CLKCTRL_FRAC_EMIFRAC	0x00003F00
-#define BP_CLKCTRL_FRAC_EMIFRAC	8
-#define BM_CLKCTRL_FRAC_PIXFRAC	0x003F0000
-#define BP_CLKCTRL_FRAC_PIXFRAC	16
-#define BM_CLKCTRL_FRAC_CLKGATEPIX	0x00800000
-
-#define HW_CLKCTRL_FRAC1	0x100
-
-#define HW_CLKCTRL_CLKSEQ	0x110
-#define BM_CLKCTRL_CLKSEQ_BYPASS_PIX	0x00000002
-
-#define HW_CLKCTRL_RESET	0x120
-#define BM_CLKCTRL_RESET_DIG	0x00000001
-#define BP_CLKCTRL_RESET_DIG	0
-
-#endif
diff -druN linux-2.6.39-libre/arch/arm/mach-stmp378x/include/mach/regs-dcp.h linux-3.0-rc7-libre/arch/arm/mach-stmp378x/include/mach/regs-dcp.h
--- linux-2.6.39-libre/arch/arm/mach-stmp378x/include/mach/regs-dcp.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-stmp378x/include/mach/regs-dcp.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,87 +0,0 @@
-/*
- * stmp378x: DCP register definitions
- *
- * Copyright (c) 2008 Freescale Semiconductor
- * Copyright 2008 Embedded Alley Solutions, 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
- */
-#define REGS_DCP_BASE	(STMP3XXX_REGS_BASE + 0x28000)
-#define REGS_DCP_PHYS	0x80028000
-#define REGS_DCP_SIZE	0x2000
-
-#define HW_DCP_CTRL		0x0
-#define BM_DCP_CTRL_CHANNEL_INTERRUPT_ENABLE	0x000000FF
-#define BP_DCP_CTRL_CHANNEL_INTERRUPT_ENABLE	0
-#define BM_DCP_CTRL_ENABLE_CONTEXT_CACHING	0x00400000
-#define BM_DCP_CTRL_GATHER_RESIDUAL_WRITES	0x00800000
-#define BM_DCP_CTRL_CLKGATE	0x40000000
-#define BM_DCP_CTRL_SFTRST	0x80000000
-
-#define HW_DCP_STAT		0x10
-#define BM_DCP_STAT_IRQ		0x0000000F
-#define BP_DCP_STAT_IRQ		0
-
-#define HW_DCP_CHANNELCTRL	0x20
-#define BM_DCP_CHANNELCTRL_ENABLE_CHANNEL	0x000000FF
-#define BP_DCP_CHANNELCTRL_ENABLE_CHANNEL	0
-
-#define HW_DCP_CONTEXT		0x50
-#define BM_DCP_PACKET1_INTERRUPT	0x00000001
-#define BP_DCP_PACKET1_INTERRUPT	0
-#define BM_DCP_PACKET1_DECR_SEMAPHORE	0x00000002
-#define BM_DCP_PACKET1_CHAIN	0x00000004
-#define BM_DCP_PACKET1_CHAIN_CONTIGUOUS	0x00000008
-#define BM_DCP_PACKET1_ENABLE_CIPHER	0x00000020
-#define BM_DCP_PACKET1_ENABLE_HASH	0x00000040
-#define BM_DCP_PACKET1_CIPHER_ENCRYPT	0x00000100
-#define BM_DCP_PACKET1_CIPHER_INIT	0x00000200
-#define BM_DCP_PACKET1_OTP_KEY	0x00000400
-#define BM_DCP_PACKET1_PAYLOAD_KEY	0x00000800
-#define BM_DCP_PACKET1_HASH_INIT	0x00001000
-#define BM_DCP_PACKET1_HASH_TERM	0x00002000
-#define BM_DCP_PACKET2_CIPHER_SELECT	0x0000000F
-#define BP_DCP_PACKET2_CIPHER_SELECT	0
-#define BM_DCP_PACKET2_CIPHER_MODE	0x000000F0
-#define BP_DCP_PACKET2_CIPHER_MODE	4
-#define BM_DCP_PACKET2_KEY_SELECT	0x0000FF00
-#define BP_DCP_PACKET2_KEY_SELECT	8
-#define BM_DCP_PACKET2_HASH_SELECT	0x000F0000
-#define BP_DCP_PACKET2_HASH_SELECT	16
-#define BM_DCP_PACKET2_CIPHER_CFG	0xFF000000
-#define BP_DCP_PACKET2_CIPHER_CFG	24
-
-#define HW_DCP_CH0CMDPTR	(0x100 + 0 * 0x40)
-#define HW_DCP_CH1CMDPTR	(0x100 + 1 * 0x40)
-#define HW_DCP_CH2CMDPTR	(0x100 + 2 * 0x40)
-#define HW_DCP_CH3CMDPTR	(0x100 + 3 * 0x40)
-
-#define HW_DCP_CHnCMDPTR	0x100
-
-#define HW_DCP_CH0SEMA		(0x110 + 0 * 0x40)
-#define HW_DCP_CH1SEMA		(0x110 + 1 * 0x40)
-#define HW_DCP_CH2SEMA		(0x110 + 2 * 0x40)
-#define HW_DCP_CH3SEMA		(0x110 + 3 * 0x40)
-
-#define HW_DCP_CHnSEMA		0x110
-#define BM_DCP_CHnSEMA_INCREMENT	0x000000FF
-#define BP_DCP_CHnSEMA_INCREMENT	0
-
-#define HW_DCP_CH0STAT		(0x120 + 0 * 0x40)
-#define HW_DCP_CH1STAT		(0x120 + 1 * 0x40)
-#define HW_DCP_CH2STAT		(0x120 + 2 * 0x40)
-#define HW_DCP_CH3STAT		(0x120 + 3 * 0x40)
-
-#define HW_DCP_CHnSTAT		0x120
diff -druN linux-2.6.39-libre/arch/arm/mach-stmp378x/include/mach/regs-digctl.h linux-3.0-rc7-libre/arch/arm/mach-stmp378x/include/mach/regs-digctl.h
--- linux-2.6.39-libre/arch/arm/mach-stmp378x/include/mach/regs-digctl.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-stmp378x/include/mach/regs-digctl.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,38 +0,0 @@
-/*
- * stmp378x: DIGCTL register definitions
- *
- * Copyright (c) 2008 Freescale Semiconductor
- * Copyright 2008 Embedded Alley Solutions, 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
- */
-#define REGS_DIGCTL_BASE	(STMP3XXX_REGS_BASE + 0x1C000)
-#define REGS_DIGCTL_PHYS	0x8001C000
-#define REGS_DIGCTL_SIZE	0x2000
-
-#define HW_DIGCTL_CTRL		0x0
-#define BM_DIGCTL_CTRL_USB_CLKGATE	0x00000004
-
-#define HW_DIGCTL_ARMCACHE	0x2B0
-#define BM_DIGCTL_ARMCACHE_ITAG_SS	0x00000003
-#define BP_DIGCTL_ARMCACHE_ITAG_SS	0
-#define BM_DIGCTL_ARMCACHE_DTAG_SS	0x00000030
-#define BP_DIGCTL_ARMCACHE_DTAG_SS	4
-#define BM_DIGCTL_ARMCACHE_CACHE_SS	0x00000300
-#define BP_DIGCTL_ARMCACHE_CACHE_SS	8
-#define BM_DIGCTL_ARMCACHE_DRTY_SS	0x00003000
-#define BP_DIGCTL_ARMCACHE_DRTY_SS	12
-#define BM_DIGCTL_ARMCACHE_VALID_SS	0x00030000
-#define BP_DIGCTL_ARMCACHE_VALID_SS	16
diff -druN linux-2.6.39-libre/arch/arm/mach-stmp378x/include/mach/regs-dram.h linux-3.0-rc7-libre/arch/arm/mach-stmp378x/include/mach/regs-dram.h
--- linux-2.6.39-libre/arch/arm/mach-stmp378x/include/mach/regs-dram.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-stmp378x/include/mach/regs-dram.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,27 +0,0 @@
-/*
- * stmp378x: DRAM register definitions
- *
- * Copyright (c) 2008 Freescale Semiconductor
- * Copyright 2008 Embedded Alley Solutions, 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
- */
-#define REGS_DRAM_BASE	(STMP3XXX_REGS_BASE + 0xE0000)
-#define REGS_DRAM_PHYS	0x800E0000
-#define REGS_DRAM_SIZE	0x2000
-
-#define HW_DRAM_CTL06		0x18
-
-#define HW_DRAM_CTL08		0x20
diff -druN linux-2.6.39-libre/arch/arm/mach-stmp378x/include/mach/regs-dri.h linux-3.0-rc7-libre/arch/arm/mach-stmp378x/include/mach/regs-dri.h
--- linux-2.6.39-libre/arch/arm/mach-stmp378x/include/mach/regs-dri.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-stmp378x/include/mach/regs-dri.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,45 +0,0 @@
-/*
- * stmp378x: DRI register definitions
- *
- * Copyright (c) 2008 Freescale Semiconductor
- * Copyright 2008 Embedded Alley Solutions, 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
- */
-#define REGS_DRI_BASE	(STMP3XXX_REGS_BASE + 0x74000)
-#define REGS_DRI_PHYS	0x80074000
-#define REGS_DRI_SIZE	0x2000
-
-#define HW_DRI_CTRL		0x0
-#define BM_DRI_CTRL_RUN		0x00000001
-#define BP_DRI_CTRL_RUN		0
-#define BM_DRI_CTRL_ATTENTION_IRQ	0x00000002
-#define BM_DRI_CTRL_PILOT_SYNC_LOSS_IRQ	0x00000004
-#define BM_DRI_CTRL_OVERFLOW_IRQ	0x00000008
-#define BM_DRI_CTRL_ATTENTION_IRQ_EN	0x00000200
-#define BM_DRI_CTRL_PILOT_SYNC_LOSS_IRQ_EN	0x00000400
-#define BM_DRI_CTRL_OVERFLOW_IRQ_EN	0x00000800
-#define BM_DRI_CTRL_REACQUIRE_PHASE	0x00008000
-#define BM_DRI_CTRL_STOP_ON_PILOT_ERROR	0x02000000
-#define BM_DRI_CTRL_STOP_ON_OFLOW_ERROR	0x04000000
-#define BM_DRI_CTRL_ENABLE_INPUTS	0x20000000
-#define BM_DRI_CTRL_CLKGATE	0x40000000
-#define BM_DRI_CTRL_SFTRST	0x80000000
-
-#define HW_DRI_TIMING		0x10
-#define BM_DRI_TIMING_GAP_DETECTION_INTERVAL	0x000000FF
-#define BP_DRI_TIMING_GAP_DETECTION_INTERVAL	0
-#define BM_DRI_TIMING_PILOT_REP_RATE	0x000F0000
-#define BP_DRI_TIMING_PILOT_REP_RATE	16
diff -druN linux-2.6.39-libre/arch/arm/mach-stmp378x/include/mach/regs-ecc8.h linux-3.0-rc7-libre/arch/arm/mach-stmp378x/include/mach/regs-ecc8.h
--- linux-2.6.39-libre/arch/arm/mach-stmp378x/include/mach/regs-ecc8.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-stmp378x/include/mach/regs-ecc8.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,39 +0,0 @@
-/*
- * stmp378x: ECC8 register definitions
- *
- * Copyright (c) 2008 Freescale Semiconductor
- * Copyright 2008 Embedded Alley Solutions, 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
- */
-#define REGS_ECC8_BASE	(STMP3XXX_REGS_BASE + 0x8000)
-#define REGS_ECC8_PHYS	0x80008000
-#define REGS_ECC8_SIZE	0x2000
-
-#define HW_ECC8_CTRL		0x0
-#define BM_ECC8_CTRL_COMPLETE_IRQ	0x00000001
-#define BP_ECC8_CTRL_COMPLETE_IRQ	0
-#define BM_ECC8_CTRL_COMPLETE_IRQ_EN	0x00000100
-#define BM_ECC8_CTRL_AHBM_SFTRST	0x20000000
-
-#define HW_ECC8_STATUS0		0x10
-#define BM_ECC8_STATUS0_UNCORRECTABLE	0x00000004
-#define BM_ECC8_STATUS0_CORRECTED	0x00000008
-#define BM_ECC8_STATUS0_STATUS_AUX	0x00000F00
-#define BP_ECC8_STATUS0_STATUS_AUX	8
-#define BM_ECC8_STATUS0_COMPLETED_CE	0x000F0000
-#define BP_ECC8_STATUS0_COMPLETED_CE	16
-
-#define HW_ECC8_STATUS1		0x20
diff -druN linux-2.6.39-libre/arch/arm/mach-stmp378x/include/mach/regs-emi.h linux-3.0-rc7-libre/arch/arm/mach-stmp378x/include/mach/regs-emi.h
--- linux-2.6.39-libre/arch/arm/mach-stmp378x/include/mach/regs-emi.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-stmp378x/include/mach/regs-emi.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,25 +0,0 @@
-/*
- * stmp378x: EMI register definitions
- *
- * Copyright (c) 2008 Freescale Semiconductor
- * Copyright 2008 Embedded Alley Solutions, 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
- */
-#define REGS_EMI_BASE	(STMP3XXX_REGS_BASE + 0x20000)
-#define REGS_EMI_PHYS	0x80020000
-#define REGS_EMI_SIZE	0x2000
-
-#define HW_EMI_STAT		0x10
diff -druN linux-2.6.39-libre/arch/arm/mach-stmp378x/include/mach/regs-gpmi.h linux-3.0-rc7-libre/arch/arm/mach-stmp378x/include/mach/regs-gpmi.h
--- linux-2.6.39-libre/arch/arm/mach-stmp378x/include/mach/regs-gpmi.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-stmp378x/include/mach/regs-gpmi.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,78 +0,0 @@
-/*
- * stmp378x: GPMI register definitions
- *
- * Copyright (c) 2008 Freescale Semiconductor
- * Copyright 2008 Embedded Alley Solutions, 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
- */
-#define REGS_GPMI_BASE	(STMP3XXX_REGS_BASE + 0xC000)
-#define REGS_GPMI_PHYS	0x8000C000
-#define REGS_GPMI_SIZE	0x2000
-
-#define HW_GPMI_CTRL0		0x0
-#define BM_GPMI_CTRL0_XFER_COUNT	0x0000FFFF
-#define BP_GPMI_CTRL0_XFER_COUNT	0
-#define BM_GPMI_CTRL0_CS	0x00300000
-#define BP_GPMI_CTRL0_CS	20
-#define BM_GPMI_CTRL0_LOCK_CS	0x00400000
-#define BM_GPMI_CTRL0_WORD_LENGTH	0x00800000
-#define BM_GPMI_CTRL0_ADDRESS      0x000E0000
-#define BP_GPMI_CTRL0_ADDRESS      17
-#define BV_GPMI_CTRL0_ADDRESS__NAND_DATA  0x0
-#define BV_GPMI_CTRL0_ADDRESS__NAND_CLE   0x1
-#define BV_GPMI_CTRL0_ADDRESS__NAND_ALE   0x2
-#define BM_GPMI_CTRL0_ADDRESS_INCREMENT      0x00010000
-#define BM_GPMI_CTRL0_COMMAND_MODE	0x03000000
-#define BP_GPMI_CTRL0_COMMAND_MODE	24
-#define BV_GPMI_CTRL0_COMMAND_MODE__WRITE	    0x0
-#define BV_GPMI_CTRL0_COMMAND_MODE__READ	     0x1
-#define BV_GPMI_CTRL0_COMMAND_MODE__READ_AND_COMPARE 0x2
-#define BV_GPMI_CTRL0_COMMAND_MODE__WAIT_FOR_READY   0x3
-#define BM_GPMI_CTRL0_RUN	0x20000000
-#define BM_GPMI_CTRL0_CLKGATE	0x40000000
-#define BM_GPMI_CTRL0_SFTRST	0x80000000
-#define BM_GPMI_ECCCTRL_BUFFER_MASK	0x000001FF
-#define BP_GPMI_ECCCTRL_BUFFER_MASK	0
-#define BM_GPMI_ECCCTRL_ENABLE_ECC	0x00001000
-#define BM_GPMI_ECCCTRL_ECC_CMD	0x00006000
-#define BP_GPMI_ECCCTRL_ECC_CMD	13
-#define BV_GPMI_ECCCTRL_ECC_CMD__DECODE_4_BIT			0
-#define BV_GPMI_ECCCTRL_ECC_CMD__ENCODE_4_BIT			1
-#define BV_GPMI_ECCCTRL_ECC_CMD__DECODE_8_BIT			2
-#define BV_GPMI_ECCCTRL_ECC_CMD__ENCODE_8_BIT			3
-
-#define HW_GPMI_CTRL1		0x60
-#define BM_GPMI_CTRL1_GPMI_MODE	0x00000001
-#define BP_GPMI_CTRL1_GPMI_MODE	0
-#define BM_GPMI_CTRL1_ATA_IRQRDY_POLARITY	0x00000004
-#define BM_GPMI_CTRL1_DEV_RESET	0x00000008
-#define BM_GPMI_CTRL1_TIMEOUT_IRQ	0x00000200
-#define BM_GPMI_CTRL1_DEV_IRQ	0x00000400
-#define BM_GPMI_CTRL1_RDN_DELAY	0x0000F000
-#define BP_GPMI_CTRL1_RDN_DELAY	12
-#define BM_GPMI_CTRL1_BCH_MODE	0x00040000
-
-#define HW_GPMI_TIMING0		0x70
-#define BM_GPMI_TIMING0_DATA_SETUP	0x000000FF
-#define BP_GPMI_TIMING0_DATA_SETUP	0
-#define BM_GPMI_TIMING0_DATA_HOLD	0x0000FF00
-#define BP_GPMI_TIMING0_DATA_HOLD	8
-#define BM_GPMI_TIMING0_ADDRESS_SETUP	0x00FF0000
-#define BP_GPMI_TIMING0_ADDRESS_SETUP	16
-
-#define HW_GPMI_TIMING1		0x80
-#define BM_GPMI_TIMING1_DEVICE_BUSY_TIMEOUT	0xFFFF0000
-#define BP_GPMI_TIMING1_DEVICE_BUSY_TIMEOUT	16
diff -druN linux-2.6.39-libre/arch/arm/mach-stmp378x/include/mach/regs-i2c.h linux-3.0-rc7-libre/arch/arm/mach-stmp378x/include/mach/regs-i2c.h
--- linux-2.6.39-libre/arch/arm/mach-stmp378x/include/mach/regs-i2c.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-stmp378x/include/mach/regs-i2c.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,55 +0,0 @@
-/*
- * stmp378x: I2C register definitions
- *
- * Copyright (c) 2008 Freescale Semiconductor
- * Copyright 2008 Embedded Alley Solutions, 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
- */
-#define REGS_I2C_BASE	(STMP3XXX_REGS_BASE + 0x58000)
-#define REGS_I2C_PHYS	0x80058000
-#define REGS_I2C_SIZE	0x2000
-
-#define HW_I2C_CTRL0		0x0
-#define BM_I2C_CTRL0_XFER_COUNT	0x0000FFFF
-#define BP_I2C_CTRL0_XFER_COUNT	0
-#define BM_I2C_CTRL0_DIRECTION	0x00010000
-#define BM_I2C_CTRL0_MASTER_MODE	0x00020000
-#define BM_I2C_CTRL0_PRE_SEND_START	0x00080000
-#define BM_I2C_CTRL0_POST_SEND_STOP	0x00100000
-#define BM_I2C_CTRL0_RETAIN_CLOCK	0x00200000
-#define BM_I2C_CTRL0_SEND_NAK_ON_LAST	0x02000000
-#define BM_I2C_CTRL0_CLKGATE	0x40000000
-#define BM_I2C_CTRL0_SFTRST	0x80000000
-
-#define HW_I2C_TIMING0		0x10
-
-#define HW_I2C_TIMING1		0x20
-
-#define HW_I2C_TIMING2		0x30
-
-#define HW_I2C_CTRL1		0x40
-#define BM_I2C_CTRL1_SLAVE_IRQ	0x00000001
-#define BP_I2C_CTRL1_SLAVE_IRQ	0
-#define BM_I2C_CTRL1_SLAVE_STOP_IRQ	0x00000002
-#define BM_I2C_CTRL1_MASTER_LOSS_IRQ	0x00000004
-#define BM_I2C_CTRL1_EARLY_TERM_IRQ	0x00000008
-#define BM_I2C_CTRL1_OVERSIZE_XFER_TERM_IRQ	0x00000010
-#define BM_I2C_CTRL1_NO_SLAVE_ACK_IRQ	0x00000020
-#define BM_I2C_CTRL1_DATA_ENGINE_CMPLT_IRQ	0x00000040
-#define BM_I2C_CTRL1_BUS_FREE_IRQ	0x00000080
-#define BM_I2C_CTRL1_CLR_GOT_A_NAK	0x10000000
-
-#define HW_I2C_VERSION		0x90
diff -druN linux-2.6.39-libre/arch/arm/mach-stmp378x/include/mach/regs-icoll.h linux-3.0-rc7-libre/arch/arm/mach-stmp378x/include/mach/regs-icoll.h
--- linux-2.6.39-libre/arch/arm/mach-stmp378x/include/mach/regs-icoll.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-stmp378x/include/mach/regs-icoll.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,45 +0,0 @@
-/*
- * stmp378x: ICOLL register definitions
- *
- * Copyright (c) 2008 Freescale Semiconductor
- * Copyright 2008 Embedded Alley Solutions, 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
- */
-#ifndef _MACH_REGS_ICOLL
-#define _MACH_REGS_ICOLL
-
-#define REGS_ICOLL_BASE	(STMP3XXX_REGS_BASE + 0x0)
-#define REGS_ICOLL_PHYS	0x80000000
-#define REGS_ICOLL_SIZE	0x2000
-
-#define HW_ICOLL_VECTOR		0x0
-
-#define HW_ICOLL_LEVELACK	0x10
-#define BM_ICOLL_LEVELACK_IRQLEVELACK	0x0000000F
-#define BP_ICOLL_LEVELACK_IRQLEVELACK	0
-
-#define HW_ICOLL_CTRL		0x20
-#define BM_ICOLL_CTRL_CLKGATE	0x40000000
-#define BM_ICOLL_CTRL_SFTRST	0x80000000
-
-#define HW_ICOLL_STAT		0x70
-
-#define HW_ICOLL_INTERRUPTn	0x120
-
-#define HW_ICOLL_INTERRUPTn	0x120
-#define BM_ICOLL_INTERRUPTn_ENABLE	0x00000004
-
-#endif
diff -druN linux-2.6.39-libre/arch/arm/mach-stmp378x/include/mach/regs-ir.h linux-3.0-rc7-libre/arch/arm/mach-stmp378x/include/mach/regs-ir.h
--- linux-2.6.39-libre/arch/arm/mach-stmp378x/include/mach/regs-ir.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-stmp378x/include/mach/regs-ir.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,23 +0,0 @@
-/*
- * stmp378x: IR register definitions
- *
- * Copyright (c) 2008 Freescale Semiconductor
- * Copyright 2008 Embedded Alley Solutions, 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
- */
-#define REGS_IR_BASE	(STMP3XXX_REGS_BASE + 0x78000)
-#define REGS_IR_PHYS	0x80078000
-#define REGS_IR_SIZE	0x2000
diff -druN linux-2.6.39-libre/arch/arm/mach-stmp378x/include/mach/regs-lcdif.h linux-3.0-rc7-libre/arch/arm/mach-stmp378x/include/mach/regs-lcdif.h
--- linux-2.6.39-libre/arch/arm/mach-stmp378x/include/mach/regs-lcdif.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-stmp378x/include/mach/regs-lcdif.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,195 +0,0 @@
-/*
- * stmp378x: LCDIF register definitions
- *
- * Copyright (c) 2008 Freescale Semiconductor
- * Copyright 2008 Embedded Alley Solutions, 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
- */
-#define REGS_LCDIF_BASE	(STMP3XXX_REGS_BASE + 0x30000)
-#define REGS_LCDIF_PHYS	0x80030000
-#define REGS_LCDIF_SIZE	0x2000
-
-#define HW_LCDIF_CTRL		0x0
-#define BM_LCDIF_CTRL_RUN	0x00000001
-#define BP_LCDIF_CTRL_RUN	0
-#define BM_LCDIF_CTRL_LCDIF_MASTER	0x00000020
-#define BM_LCDIF_CTRL_RGB_TO_YCBCR422_CSC	0x00000080
-#define BM_LCDIF_CTRL_WORD_LENGTH	0x00000300
-#define BP_LCDIF_CTRL_WORD_LENGTH	8
-#define BM_LCDIF_CTRL_LCD_DATABUS_WIDTH	0x00000C00
-#define BP_LCDIF_CTRL_LCD_DATABUS_WIDTH	10
-#define BM_LCDIF_CTRL_INPUT_DATA_SWIZZLE	0x0000C000
-#define BP_LCDIF_CTRL_INPUT_DATA_SWIZZLE	14
-#define BM_LCDIF_CTRL_DATA_SELECT	0x00010000
-#define BM_LCDIF_CTRL_DOTCLK_MODE	0x00020000
-#define BM_LCDIF_CTRL_VSYNC_MODE	0x00040000
-#define BM_LCDIF_CTRL_BYPASS_COUNT	0x00080000
-#define BM_LCDIF_CTRL_DVI_MODE	0x00100000
-#define BM_LCDIF_CTRL_SHIFT_NUM_BITS	0x03E00000
-#define BP_LCDIF_CTRL_SHIFT_NUM_BITS	21
-#define BM_LCDIF_CTRL_DATA_SHIFT_DIR	0x04000000
-#define BM_LCDIF_CTRL_WAIT_FOR_VSYNC_EDGE	0x08000000
-#define BM_LCDIF_CTRL_CLKGATE	0x40000000
-#define BM_LCDIF_CTRL_SFTRST	0x80000000
-
-#define HW_LCDIF_CTRL1		0x10
-#define BM_LCDIF_CTRL1_RESET	0x00000001
-#define BP_LCDIF_CTRL1_RESET	0
-#define BM_LCDIF_CTRL1_MODE86	0x00000002
-#define BM_LCDIF_CTRL1_BUSY_ENABLE	0x00000004
-#define BM_LCDIF_CTRL1_VSYNC_EDGE_IRQ	0x00000100
-#define BM_LCDIF_CTRL1_CUR_FRAME_DONE_IRQ	0x00000200
-#define BM_LCDIF_CTRL1_UNDERFLOW_IRQ	0x00000400
-#define BM_LCDIF_CTRL1_OVERFLOW_IRQ	0x00000800
-#define BM_LCDIF_CTRL1_VSYNC_EDGE_IRQ_EN	0x00001000
-#define BM_LCDIF_CTRL1_BYTE_PACKING_FORMAT	0x000F0000
-#define BP_LCDIF_CTRL1_BYTE_PACKING_FORMAT	16
-#define BM_LCDIF_CTRL1_INTERLACE_FIELDS	0x00800000
-#define BM_LCDIF_CTRL1_RECOVER_ON_UNDERFLOW	0x01000000
-
-#define HW_LCDIF_TRANSFER_COUNT	0x20
-#define BM_LCDIF_TRANSFER_COUNT_H_COUNT	0x0000FFFF
-#define BP_LCDIF_TRANSFER_COUNT_H_COUNT	0
-#define BM_LCDIF_TRANSFER_COUNT_V_COUNT	0xFFFF0000
-#define BP_LCDIF_TRANSFER_COUNT_V_COUNT	16
-
-#define HW_LCDIF_CUR_BUF	0x30
-
-#define HW_LCDIF_NEXT_BUF	0x40
-
-#define HW_LCDIF_TIMING		0x60
-
-#define HW_LCDIF_VDCTRL0	0x70
-#define BM_LCDIF_VDCTRL0_VSYNC_PULSE_WIDTH	0x0003FFFF
-#define BP_LCDIF_VDCTRL0_VSYNC_PULSE_WIDTH	0
-#define BM_LCDIF_VDCTRL0_VSYNC_PULSE_WIDTH_UNIT	0x00100000
-#define BM_LCDIF_VDCTRL0_VSYNC_PERIOD_UNIT	0x00200000
-#define BM_LCDIF_VDCTRL0_ENABLE_POL	0x01000000
-#define BM_LCDIF_VDCTRL0_DOTCLK_POL	0x02000000
-#define BM_LCDIF_VDCTRL0_HSYNC_POL	0x04000000
-#define BM_LCDIF_VDCTRL0_VSYNC_POL	0x08000000
-#define BM_LCDIF_VDCTRL0_ENABLE_PRESENT	0x10000000
-#define BM_LCDIF_VDCTRL0_VSYNC_OEB	0x20000000
-
-#define HW_LCDIF_VDCTRL1	0x80
-#define BM_LCDIF_VDCTRL1_VSYNC_PERIOD	0xFFFFFFFF
-#define BP_LCDIF_VDCTRL1_VSYNC_PERIOD	0
-
-#define HW_LCDIF_VDCTRL2	0x90
-#define BM_LCDIF_VDCTRL2_HSYNC_PERIOD	0x0003FFFF
-#define BP_LCDIF_VDCTRL2_HSYNC_PERIOD	0
-#define BM_LCDIF_VDCTRL2_HSYNC_PULSE_WIDTH	0xFF000000
-#define BP_LCDIF_VDCTRL2_HSYNC_PULSE_WIDTH	24
-
-#define HW_LCDIF_VDCTRL3	0xA0
-#define BM_LCDIF_VDCTRL3_VERTICAL_WAIT_CNT	0x0000FFFF
-#define BP_LCDIF_VDCTRL3_VERTICAL_WAIT_CNT	0
-#define BM_LCDIF_VDCTRL3_HORIZONTAL_WAIT_CNT	0x0FFF0000
-#define BP_LCDIF_VDCTRL3_HORIZONTAL_WAIT_CNT	16
-
-#define HW_LCDIF_VDCTRL4	0xB0
-#define BM_LCDIF_VDCTRL4_DOTCLK_H_VALID_DATA_CNT	0x0003FFFF
-#define BP_LCDIF_VDCTRL4_DOTCLK_H_VALID_DATA_CNT	0
-#define BM_LCDIF_VDCTRL4_SYNC_SIGNALS_ON	0x00040000
-
-#define HW_LCDIF_DVICTRL0	0xC0
-#define BM_LCDIF_DVICTRL0_V_LINES_CNT	0x000003FF
-#define BP_LCDIF_DVICTRL0_V_LINES_CNT	0
-#define BM_LCDIF_DVICTRL0_H_BLANKING_CNT	0x000FFC00
-#define BP_LCDIF_DVICTRL0_H_BLANKING_CNT	10
-#define BM_LCDIF_DVICTRL0_H_ACTIVE_CNT	0x7FF00000
-#define BP_LCDIF_DVICTRL0_H_ACTIVE_CNT	20
-
-#define HW_LCDIF_DVICTRL1	0xD0
-#define BM_LCDIF_DVICTRL1_F2_START_LINE	0x000003FF
-#define BP_LCDIF_DVICTRL1_F2_START_LINE	0
-#define BM_LCDIF_DVICTRL1_F1_END_LINE	0x000FFC00
-#define BP_LCDIF_DVICTRL1_F1_END_LINE	10
-#define BM_LCDIF_DVICTRL1_F1_START_LINE	0x3FF00000
-#define BP_LCDIF_DVICTRL1_F1_START_LINE	20
-
-#define HW_LCDIF_DVICTRL2	0xE0
-#define BM_LCDIF_DVICTRL2_V1_BLANK_END_LINE	0x000003FF
-#define BP_LCDIF_DVICTRL2_V1_BLANK_END_LINE	0
-#define BM_LCDIF_DVICTRL2_V1_BLANK_START_LINE	0x000FFC00
-#define BP_LCDIF_DVICTRL2_V1_BLANK_START_LINE	10
-#define BM_LCDIF_DVICTRL2_F2_END_LINE	0x3FF00000
-#define BP_LCDIF_DVICTRL2_F2_END_LINE	20
-
-#define HW_LCDIF_DVICTRL3	0xF0
-#define BM_LCDIF_DVICTRL3_V2_BLANK_END_LINE	0x000003FF
-#define BP_LCDIF_DVICTRL3_V2_BLANK_END_LINE	0
-#define BM_LCDIF_DVICTRL3_V2_BLANK_START_LINE	0x03FF0000
-#define BP_LCDIF_DVICTRL3_V2_BLANK_START_LINE	16
-
-#define HW_LCDIF_DVICTRL4	0x100
-#define BM_LCDIF_DVICTRL4_H_FILL_CNT	0x000000FF
-#define BP_LCDIF_DVICTRL4_H_FILL_CNT	0
-#define BM_LCDIF_DVICTRL4_CR_FILL_VALUE	0x0000FF00
-#define BP_LCDIF_DVICTRL4_CR_FILL_VALUE	8
-#define BM_LCDIF_DVICTRL4_CB_FILL_VALUE	0x00FF0000
-#define BP_LCDIF_DVICTRL4_CB_FILL_VALUE	16
-#define BM_LCDIF_DVICTRL4_Y_FILL_VALUE	0xFF000000
-#define BP_LCDIF_DVICTRL4_Y_FILL_VALUE	24
-
-#define HW_LCDIF_CSC_COEFF0	0x110
-#define BM_LCDIF_CSC_COEFF0_CSC_SUBSAMPLE_FILTER	0x00000003
-#define BP_LCDIF_CSC_COEFF0_CSC_SUBSAMPLE_FILTER	0
-#define BM_LCDIF_CSC_COEFF0_C0	0x03FF0000
-#define BP_LCDIF_CSC_COEFF0_C0	16
-
-#define HW_LCDIF_CSC_COEFF1	0x120
-#define BM_LCDIF_CSC_COEFF1_C1	0x000003FF
-#define BP_LCDIF_CSC_COEFF1_C1	0
-#define BM_LCDIF_CSC_COEFF1_C2	0x03FF0000
-#define BP_LCDIF_CSC_COEFF1_C2	16
-
-#define HW_LCDIF_CSC_COEFF2	0x130
-#define BM_LCDIF_CSC_COEFF2_C3	0x000003FF
-#define BP_LCDIF_CSC_COEFF2_C3	0
-#define BM_LCDIF_CSC_COEFF2_C4	0x03FF0000
-#define BP_LCDIF_CSC_COEFF2_C4	16
-
-#define HW_LCDIF_CSC_COEFF3	0x140
-#define BM_LCDIF_CSC_COEFF3_C5	0x000003FF
-#define BP_LCDIF_CSC_COEFF3_C5	0
-#define BM_LCDIF_CSC_COEFF3_C6	0x03FF0000
-#define BP_LCDIF_CSC_COEFF3_C6	16
-
-#define HW_LCDIF_CSC_COEFF4	0x150
-#define BM_LCDIF_CSC_COEFF4_C7	0x000003FF
-#define BP_LCDIF_CSC_COEFF4_C7	0
-#define BM_LCDIF_CSC_COEFF4_C8	0x03FF0000
-#define BP_LCDIF_CSC_COEFF4_C8	16
-
-#define HW_LCDIF_CSC_OFFSET	0x160
-#define BM_LCDIF_CSC_OFFSET_Y_OFFSET	0x000001FF
-#define BP_LCDIF_CSC_OFFSET_Y_OFFSET	0
-#define BM_LCDIF_CSC_OFFSET_CBCR_OFFSET	0x01FF0000
-#define BP_LCDIF_CSC_OFFSET_CBCR_OFFSET	16
-
-#define HW_LCDIF_CSC_LIMIT	0x170
-#define BM_LCDIF_CSC_LIMIT_Y_MAX	0x000000FF
-#define BP_LCDIF_CSC_LIMIT_Y_MAX	0
-#define BM_LCDIF_CSC_LIMIT_Y_MIN	0x0000FF00
-#define BP_LCDIF_CSC_LIMIT_Y_MIN	8
-#define BM_LCDIF_CSC_LIMIT_CBCR_MAX	0x00FF0000
-#define BP_LCDIF_CSC_LIMIT_CBCR_MAX	16
-#define BM_LCDIF_CSC_LIMIT_CBCR_MIN	0xFF000000
-#define BP_LCDIF_CSC_LIMIT_CBCR_MIN	24
-
-#define HW_LCDIF_STAT		0x1D0
-#define BM_LCDIF_STAT_TXFIFO_EMPTY	0x04000000
diff -druN linux-2.6.39-libre/arch/arm/mach-stmp378x/include/mach/regs-lradc.h linux-3.0-rc7-libre/arch/arm/mach-stmp378x/include/mach/regs-lradc.h
--- linux-2.6.39-libre/arch/arm/mach-stmp378x/include/mach/regs-lradc.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-stmp378x/include/mach/regs-lradc.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,99 +0,0 @@
-/*
- * stmp378x: LRADC register definitions
- *
- * Copyright (c) 2008 Freescale Semiconductor
- * Copyright 2008 Embedded Alley Solutions, 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
- */
-#define REGS_LRADC_BASE	(STMP3XXX_REGS_BASE + 0x50000)
-#define REGS_LRADC_PHYS	0x80050000
-#define REGS_LRADC_SIZE	0x2000
-
-#define HW_LRADC_CTRL0		0x0
-#define BM_LRADC_CTRL0_SCHEDULE	0x000000FF
-#define BP_LRADC_CTRL0_SCHEDULE	0
-#define BM_LRADC_CTRL0_XPLUS_ENABLE	0x00010000
-#define BM_LRADC_CTRL0_YPLUS_ENABLE	0x00020000
-#define BM_LRADC_CTRL0_XMINUS_ENABLE	0x00040000
-#define BM_LRADC_CTRL0_YMINUS_ENABLE	0x00080000
-#define BM_LRADC_CTRL0_TOUCH_DETECT_ENABLE	0x00100000
-#define BM_LRADC_CTRL0_ONCHIP_GROUNDREF	0x00200000
-#define BM_LRADC_CTRL0_CLKGATE	0x40000000
-#define BM_LRADC_CTRL0_SFTRST	0x80000000
-
-#define HW_LRADC_CTRL1		0x10
-#define BM_LRADC_CTRL1_LRADC0_IRQ	0x00000001
-#define BP_LRADC_CTRL1_LRADC0_IRQ	0
-#define BM_LRADC_CTRL1_LRADC5_IRQ	0x00000020
-#define BM_LRADC_CTRL1_LRADC6_IRQ	0x00000040
-#define BM_LRADC_CTRL1_TOUCH_DETECT_IRQ	0x00000100
-#define BM_LRADC_CTRL1_LRADC0_IRQ_EN	0x00010000
-#define BM_LRADC_CTRL1_LRADC5_IRQ_EN	0x00200000
-#define BM_LRADC_CTRL1_TOUCH_DETECT_IRQ_EN	0x01000000
-
-#define HW_LRADC_CTRL2		0x20
-#define BM_LRADC_CTRL2_BL_BRIGHTNESS	0x001F0000
-#define BP_LRADC_CTRL2_BL_BRIGHTNESS	16
-#define BM_LRADC_CTRL2_BL_MUX_SELECT	0x00200000
-#define BM_LRADC_CTRL2_BL_ENABLE	0x00400000
-#define BM_LRADC_CTRL2_DIVIDE_BY_TWO	0xFF000000
-#define BP_LRADC_CTRL2_DIVIDE_BY_TWO	24
-
-#define HW_LRADC_CTRL3		0x30
-#define BM_LRADC_CTRL3_CYCLE_TIME	0x00000300
-#define BP_LRADC_CTRL3_CYCLE_TIME	8
-
-#define HW_LRADC_STATUS		0x40
-#define BM_LRADC_STATUS_TOUCH_DETECT_RAW	0x00000001
-#define BP_LRADC_STATUS_TOUCH_DETECT_RAW	0
-
-#define HW_LRADC_CH0		(0x50 + 0 * 0x10)
-#define HW_LRADC_CH1		(0x50 + 1 * 0x10)
-#define HW_LRADC_CH2		(0x50 + 2 * 0x10)
-#define HW_LRADC_CH3		(0x50 + 3 * 0x10)
-#define HW_LRADC_CH4		(0x50 + 4 * 0x10)
-#define HW_LRADC_CH5		(0x50 + 5 * 0x10)
-#define HW_LRADC_CH6		(0x50 + 6 * 0x10)
-#define HW_LRADC_CH7		(0x50 + 7 * 0x10)
-
-#define HW_LRADC_CHn		0x50
-#define BM_LRADC_CHn_VALUE	0x0003FFFF
-#define BP_LRADC_CHn_VALUE	0
-#define BM_LRADC_CHn_NUM_SAMPLES	0x1F000000
-#define BP_LRADC_CHn_NUM_SAMPLES	24
-#define BM_LRADC_CHn_ACCUMULATE	0x20000000
-
-#define HW_LRADC_DELAY0		(0xD0 + 0 * 0x10)
-#define HW_LRADC_DELAY1		(0xD0 + 1 * 0x10)
-#define HW_LRADC_DELAY2		(0xD0 + 2 * 0x10)
-#define HW_LRADC_DELAY3		(0xD0 + 3 * 0x10)
-
-#define HW_LRADC_DELAYn		0xD0
-#define BM_LRADC_DELAYn_DELAY	0x000007FF
-#define BP_LRADC_DELAYn_DELAY	0
-#define BM_LRADC_DELAYn_LOOP_COUNT	0x0000F800
-#define BP_LRADC_DELAYn_LOOP_COUNT	11
-#define BM_LRADC_DELAYn_TRIGGER_DELAYS	0x000F0000
-#define BP_LRADC_DELAYn_TRIGGER_DELAYS	16
-#define BM_LRADC_DELAYn_KICK	0x00100000
-#define BM_LRADC_DELAYn_TRIGGER_LRADCS	0xFF000000
-#define BP_LRADC_DELAYn_TRIGGER_LRADCS	24
-
-#define HW_LRADC_CTRL4		0x140
-#define BM_LRADC_CTRL4_LRADC6SELECT	0x0F000000
-#define BP_LRADC_CTRL4_LRADC6SELECT	24
-#define BM_LRADC_CTRL4_LRADC7SELECT	0xF0000000
-#define BP_LRADC_CTRL4_LRADC7SELECT	28
diff -druN linux-2.6.39-libre/arch/arm/mach-stmp378x/include/mach/regs-ocotp.h linux-3.0-rc7-libre/arch/arm/mach-stmp378x/include/mach/regs-ocotp.h
--- linux-2.6.39-libre/arch/arm/mach-stmp378x/include/mach/regs-ocotp.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-stmp378x/include/mach/regs-ocotp.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,40 +0,0 @@
-/*
- * stmp378x: OCOTP register definitions
- *
- * Copyright (c) 2008 Freescale Semiconductor
- * Copyright 2008 Embedded Alley Solutions, 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
- */
-#define REGS_OCOTP_BASE	(STMP3XXX_REGS_BASE + 0x2C000)
-#define REGS_OCOTP_PHYS	0x8002C000
-#define REGS_OCOTP_SIZE	0x2000
-
-#define HW_OCOTP_CTRL		0x0
-#define BM_OCOTP_CTRL_BUSY	0x00000100
-#define BM_OCOTP_CTRL_ERROR	0x00000200
-#define BM_OCOTP_CTRL_RD_BANK_OPEN	0x00001000
-#define BM_OCOTP_CTRL_RELOAD_SHADOWS	0x00002000
-#define BM_OCOTP_CTRL_WR_UNLOCK	0xFFFF0000
-#define BP_OCOTP_CTRL_WR_UNLOCK	16
-
-#define HW_OCOTP_DATA		0x10
-
-#define HW_OCOTP_CUST0		(0x20 + 0 * 0x10)
-#define HW_OCOTP_CUST1		(0x20 + 1 * 0x10)
-#define HW_OCOTP_CUST2		(0x20 + 2 * 0x10)
-#define HW_OCOTP_CUST3		(0x20 + 3 * 0x10)
-
-#define HW_OCOTP_CUSTn		0x20
diff -druN linux-2.6.39-libre/arch/arm/mach-stmp378x/include/mach/regs-pinctrl.h linux-3.0-rc7-libre/arch/arm/mach-stmp378x/include/mach/regs-pinctrl.h
--- linux-2.6.39-libre/arch/arm/mach-stmp378x/include/mach/regs-pinctrl.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-stmp378x/include/mach/regs-pinctrl.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,90 +0,0 @@
-/*
- * stmp378x: PINCTRL register definitions
- *
- * Copyright (c) 2008 Freescale Semiconductor
- * Copyright 2008 Embedded Alley Solutions, 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
- */
-#ifndef _MACH_REGS_PINCTRL
-#define _MACH_REGS_PINCTRL
-
-#define REGS_PINCTRL_BASE	(STMP3XXX_REGS_BASE + 0x18000)
-#define REGS_PINCTRL_PHYS	0x80018000
-#define REGS_PINCTRL_SIZE	0x2000
-
-#define HW_PINCTRL_MUXSEL0	0x100
-#define HW_PINCTRL_MUXSEL1	0x110
-#define HW_PINCTRL_MUXSEL2	0x120
-#define HW_PINCTRL_MUXSEL3	0x130
-#define HW_PINCTRL_MUXSEL4	0x140
-#define HW_PINCTRL_MUXSEL5	0x150
-#define HW_PINCTRL_MUXSEL6	0x160
-#define HW_PINCTRL_MUXSEL7	0x170
-
-#define HW_PINCTRL_DRIVE0	0x200
-#define HW_PINCTRL_DRIVE1	0x210
-#define HW_PINCTRL_DRIVE2	0x220
-#define HW_PINCTRL_DRIVE3	0x230
-#define HW_PINCTRL_DRIVE4	0x240
-#define HW_PINCTRL_DRIVE5	0x250
-#define HW_PINCTRL_DRIVE6	0x260
-#define HW_PINCTRL_DRIVE7	0x270
-#define HW_PINCTRL_DRIVE8	0x280
-#define HW_PINCTRL_DRIVE9	0x290
-#define HW_PINCTRL_DRIVE10	0x2A0
-#define HW_PINCTRL_DRIVE11	0x2B0
-#define HW_PINCTRL_DRIVE12	0x2C0
-#define HW_PINCTRL_DRIVE13	0x2D0
-#define HW_PINCTRL_DRIVE14	0x2E0
-
-#define HW_PINCTRL_PULL0	0x400
-#define HW_PINCTRL_PULL1	0x410
-#define HW_PINCTRL_PULL2	0x420
-#define HW_PINCTRL_PULL3	0x430
-
-#define HW_PINCTRL_DOUT0	0x500
-#define HW_PINCTRL_DOUT1	0x510
-#define HW_PINCTRL_DOUT2	0x520
-
-#define HW_PINCTRL_DIN0		0x600
-#define HW_PINCTRL_DIN1		0x610
-#define HW_PINCTRL_DIN2		0x620
-
-#define HW_PINCTRL_DOE0		0x700
-#define HW_PINCTRL_DOE1		0x710
-#define HW_PINCTRL_DOE2		0x720
-
-#define HW_PINCTRL_PIN2IRQ0	0x800
-#define HW_PINCTRL_PIN2IRQ1	0x810
-#define HW_PINCTRL_PIN2IRQ2	0x820
-
-#define HW_PINCTRL_IRQEN0	0x900
-#define HW_PINCTRL_IRQEN1	0x910
-#define HW_PINCTRL_IRQEN2	0x920
-
-#define HW_PINCTRL_IRQLEVEL0	0xA00
-#define HW_PINCTRL_IRQLEVEL1	0xA10
-#define HW_PINCTRL_IRQLEVEL2	0xA20
-
-#define HW_PINCTRL_IRQPOL0	0xB00
-#define HW_PINCTRL_IRQPOL1	0xB10
-#define HW_PINCTRL_IRQPOL2	0xB20
-
-#define HW_PINCTRL_IRQSTAT0	0xC00
-#define HW_PINCTRL_IRQSTAT1	0xC10
-#define HW_PINCTRL_IRQSTAT2	0xC20
-
-#endif
diff -druN linux-2.6.39-libre/arch/arm/mach-stmp378x/include/mach/regs-power.h linux-3.0-rc7-libre/arch/arm/mach-stmp378x/include/mach/regs-power.h
--- linux-2.6.39-libre/arch/arm/mach-stmp378x/include/mach/regs-power.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-stmp378x/include/mach/regs-power.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,63 +0,0 @@
-/*
- * stmp378x: POWER register definitions
- *
- * Copyright (c) 2008 Freescale Semiconductor
- * Copyright 2008 Embedded Alley Solutions, 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
- */
-#ifndef _MACH_REGS_POWER
-#define _MACH_REGS_POWER
-
-#define REGS_POWER_BASE	(STMP3XXX_REGS_BASE + 0x44000)
-#define REGS_POWER_PHYS	0x80044000
-#define REGS_POWER_SIZE	0x2000
-
-#define HW_POWER_CTRL		0x0
-#define BM_POWER_CTRL_ENIRQ_VDD5V_GT_VDDIO	0x00000001
-#define BP_POWER_CTRL_ENIRQ_VDD5V_GT_VDDIO	0
-#define BM_POWER_CTRL_ENIRQ_PSWITCH	0x00020000
-#define BM_POWER_CTRL_PSWITCH_IRQ	0x00100000
-#define BM_POWER_CTRL_CLKGATE	0x40000000
-
-#define HW_POWER_5VCTRL		0x10
-#define BM_POWER_5VCTRL_ENABLE_LINREG_ILIMIT	0x00000040
-
-#define HW_POWER_MINPWR		0x20
-
-#define HW_POWER_CHARGE		0x30
-
-#define HW_POWER_VDDDCTRL	0x40
-
-#define HW_POWER_VDDACTRL	0x50
-
-#define HW_POWER_VDDIOCTRL	0x60
-#define BM_POWER_VDDIOCTRL_TRG	0x0000001F
-#define BP_POWER_VDDIOCTRL_TRG	0
-
-#define HW_POWER_STS		0xC0
-#define BM_POWER_STS_VBUSVALID	0x00000002
-#define BM_POWER_STS_BVALID	0x00000004
-#define BM_POWER_STS_AVALID	0x00000008
-#define BM_POWER_STS_DC_OK	0x00000200
-
-#define HW_POWER_RESET		0x100
-
-#define HW_POWER_DEBUG		0x110
-#define BM_POWER_DEBUG_BVALIDPIOLOCK	0x00000002
-#define BM_POWER_DEBUG_AVALIDPIOLOCK	0x00000004
-#define BM_POWER_DEBUG_VBUSVALIDPIOLOCK	0x00000008
-
-#endif
diff -druN linux-2.6.39-libre/arch/arm/mach-stmp378x/include/mach/regs-pwm.h linux-3.0-rc7-libre/arch/arm/mach-stmp378x/include/mach/regs-pwm.h
--- linux-2.6.39-libre/arch/arm/mach-stmp378x/include/mach/regs-pwm.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-stmp378x/include/mach/regs-pwm.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,53 +0,0 @@
-/*
- * stmp378x: PWM register definitions
- *
- * Copyright (c) 2008 Freescale Semiconductor
- * Copyright 2008 Embedded Alley Solutions, 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
- */
-#define REGS_PWM_BASE	(STMP3XXX_REGS_BASE + 0x64000)
-#define REGS_PWM_PHYS	0x80064000
-#define REGS_PWM_SIZE	0x2000
-
-#define HW_PWM_CTRL		0x0
-#define BM_PWM_CTRL_PWM2_ENABLE	0x00000004
-#define BM_PWM_CTRL_PWM2_ANA_CTRL_ENABLE	0x00000020
-
-#define HW_PWM_ACTIVE0		(0x10 + 0 * 0x20)
-#define HW_PWM_ACTIVE1		(0x10 + 1 * 0x20)
-#define HW_PWM_ACTIVE2		(0x10 + 2 * 0x20)
-#define HW_PWM_ACTIVE3		(0x10 + 3 * 0x20)
-
-#define HW_PWM_ACTIVEn		0x10
-#define BM_PWM_ACTIVEn_ACTIVE	0x0000FFFF
-#define BP_PWM_ACTIVEn_ACTIVE	0
-#define BM_PWM_ACTIVEn_INACTIVE	0xFFFF0000
-#define BP_PWM_ACTIVEn_INACTIVE	16
-
-#define HW_PWM_PERIOD0		(0x20 + 0 * 0x20)
-#define HW_PWM_PERIOD1		(0x20 + 1 * 0x20)
-#define HW_PWM_PERIOD2		(0x20 + 2 * 0x20)
-#define HW_PWM_PERIOD3		(0x20 + 3 * 0x20)
-
-#define HW_PWM_PERIODn		0x20
-#define BM_PWM_PERIODn_PERIOD	0x0000FFFF
-#define BP_PWM_PERIODn_PERIOD	0
-#define BM_PWM_PERIODn_ACTIVE_STATE	0x00030000
-#define BP_PWM_PERIODn_ACTIVE_STATE	16
-#define BM_PWM_PERIODn_INACTIVE_STATE	0x000C0000
-#define BP_PWM_PERIODn_INACTIVE_STATE	18
-#define BM_PWM_PERIODn_CDIV	0x00700000
-#define BP_PWM_PERIODn_CDIV	20
diff -druN linux-2.6.39-libre/arch/arm/mach-stmp378x/include/mach/regs-pxp.h linux-3.0-rc7-libre/arch/arm/mach-stmp378x/include/mach/regs-pxp.h
--- linux-2.6.39-libre/arch/arm/mach-stmp378x/include/mach/regs-pxp.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-stmp378x/include/mach/regs-pxp.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,140 +0,0 @@
-/*
- * stmp378x: PXP register definitions
- *
- * Copyright (c) 2008 Freescale Semiconductor
- * Copyright 2008 Embedded Alley Solutions, 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
- */
-#define REGS_PXP_BASE	(STMP3XXX_REGS_BASE + 0x2A000)
-#define REGS_PXP_PHYS	0x8002A000
-#define REGS_PXP_SIZE	0x2000
-
-#define HW_PXP_CTRL		0x0
-#define BM_PXP_CTRL_ENABLE	0x00000001
-#define BP_PXP_CTRL_ENABLE	0
-#define BM_PXP_CTRL_IRQ_ENABLE	0x00000002
-#define BM_PXP_CTRL_OUTPUT_RGB_FORMAT	0x000000F0
-#define BP_PXP_CTRL_OUTPUT_RGB_FORMAT	4
-#define BM_PXP_CTRL_ROTATE	0x00000300
-#define BP_PXP_CTRL_ROTATE	8
-#define BM_PXP_CTRL_HFLIP	0x00000400
-#define BM_PXP_CTRL_VFLIP	0x00000800
-#define BM_PXP_CTRL_S0_FORMAT	0x0000F000
-#define BP_PXP_CTRL_S0_FORMAT	12
-#define BM_PXP_CTRL_SCALE	0x00040000
-#define BM_PXP_CTRL_CROP	0x00080000
-
-#define HW_PXP_STAT		0x10
-#define BM_PXP_STAT_IRQ		0x00000001
-#define BP_PXP_STAT_IRQ		0
-
-#define HW_PXP_RGBBUF		0x20
-
-#define HW_PXP_RGBSIZE		0x40
-#define BM_PXP_RGBSIZE_HEIGHT	0x00000FFF
-#define BP_PXP_RGBSIZE_HEIGHT	0
-#define BM_PXP_RGBSIZE_WIDTH	0x00FFF000
-#define BP_PXP_RGBSIZE_WIDTH	12
-
-#define HW_PXP_S0BUF		0x50
-
-#define HW_PXP_S0UBUF		0x60
-
-#define HW_PXP_S0VBUF		0x70
-
-#define HW_PXP_S0PARAM		0x80
-#define BM_PXP_S0PARAM_HEIGHT	0x000000FF
-#define BP_PXP_S0PARAM_HEIGHT	0
-#define BM_PXP_S0PARAM_WIDTH	0x0000FF00
-#define BP_PXP_S0PARAM_WIDTH	8
-#define BM_PXP_S0PARAM_YBASE	0x00FF0000
-#define BP_PXP_S0PARAM_YBASE	16
-#define BM_PXP_S0PARAM_XBASE	0xFF000000
-#define BP_PXP_S0PARAM_XBASE	24
-
-#define HW_PXP_S0BACKGROUND	0x90
-
-#define HW_PXP_S0CROP		0xA0
-#define BM_PXP_S0CROP_HEIGHT	0x000000FF
-#define BP_PXP_S0CROP_HEIGHT	0
-#define BM_PXP_S0CROP_WIDTH	0x0000FF00
-#define BP_PXP_S0CROP_WIDTH	8
-#define BM_PXP_S0CROP_YBASE	0x00FF0000
-#define BP_PXP_S0CROP_YBASE	16
-#define BM_PXP_S0CROP_XBASE	0xFF000000
-#define BP_PXP_S0CROP_XBASE	24
-
-#define HW_PXP_S0SCALE		0xB0
-#define BM_PXP_S0SCALE_XSCALE	0x00003FFF
-#define BP_PXP_S0SCALE_XSCALE	0
-#define BM_PXP_S0SCALE_YSCALE	0x3FFF0000
-#define BP_PXP_S0SCALE_YSCALE	16
-
-#define HW_PXP_CSCCOEFF0	0xD0
-
-#define HW_PXP_CSCCOEFF1	0xE0
-
-#define HW_PXP_CSCCOEFF2	0xF0
-
-#define HW_PXP_S0COLORKEYLOW	0x180
-
-#define HW_PXP_S0COLORKEYHIGH	0x190
-
-#define HW_PXP_OL0		(0x200 + 0 * 0x40)
-#define HW_PXP_OL1		(0x200 + 1 * 0x40)
-#define HW_PXP_OL2		(0x200 + 2 * 0x40)
-#define HW_PXP_OL3		(0x200 + 3 * 0x40)
-#define HW_PXP_OL4		(0x200 + 4 * 0x40)
-#define HW_PXP_OL5		(0x200 + 5 * 0x40)
-#define HW_PXP_OL6		(0x200 + 6 * 0x40)
-#define HW_PXP_OL7		(0x200 + 7 * 0x40)
-
-#define HW_PXP_OLn		0x200
-
-#define HW_PXP_OL0SIZE		(0x210 + 0 * 0x40)
-#define HW_PXP_OL1SIZE		(0x210 + 1 * 0x40)
-#define HW_PXP_OL2SIZE		(0x210 + 2 * 0x40)
-#define HW_PXP_OL3SIZE		(0x210 + 3 * 0x40)
-#define HW_PXP_OL4SIZE		(0x210 + 4 * 0x40)
-#define HW_PXP_OL5SIZE		(0x210 + 5 * 0x40)
-#define HW_PXP_OL6SIZE		(0x210 + 6 * 0x40)
-#define HW_PXP_OL7SIZE		(0x210 + 7 * 0x40)
-
-#define HW_PXP_OLnSIZE		0x210
-#define BM_PXP_OLnSIZE_HEIGHT	0x000000FF
-#define BP_PXP_OLnSIZE_HEIGHT	0
-#define BM_PXP_OLnSIZE_WIDTH	0x0000FF00
-#define BP_PXP_OLnSIZE_WIDTH	8
-
-#define HW_PXP_OL0PARAM		(0x220 + 0 * 0x40)
-#define HW_PXP_OL1PARAM		(0x220 + 1 * 0x40)
-#define HW_PXP_OL2PARAM		(0x220 + 2 * 0x40)
-#define HW_PXP_OL3PARAM		(0x220 + 3 * 0x40)
-#define HW_PXP_OL4PARAM		(0x220 + 4 * 0x40)
-#define HW_PXP_OL5PARAM		(0x220 + 5 * 0x40)
-#define HW_PXP_OL6PARAM		(0x220 + 6 * 0x40)
-#define HW_PXP_OL7PARAM		(0x220 + 7 * 0x40)
-
-#define HW_PXP_OLnPARAM		0x220
-#define BM_PXP_OLnPARAM_ENABLE	0x00000001
-#define BP_PXP_OLnPARAM_ENABLE	0
-#define BM_PXP_OLnPARAM_ALPHA_CNTL	0x00000006
-#define BP_PXP_OLnPARAM_ALPHA_CNTL	1
-#define BM_PXP_OLnPARAM_ENABLE_COLORKEY	0x00000008
-#define BM_PXP_OLnPARAM_FORMAT	0x000000F0
-#define BP_PXP_OLnPARAM_FORMAT	4
-#define BM_PXP_OLnPARAM_ALPHA	0x0000FF00
-#define BP_PXP_OLnPARAM_ALPHA	8
diff -druN linux-2.6.39-libre/arch/arm/mach-stmp378x/include/mach/regs-rtc.h linux-3.0-rc7-libre/arch/arm/mach-stmp378x/include/mach/regs-rtc.h
--- linux-2.6.39-libre/arch/arm/mach-stmp378x/include/mach/regs-rtc.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-stmp378x/include/mach/regs-rtc.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,59 +0,0 @@
-/*
- * stmp378x: RTC register definitions
- *
- * Copyright (c) 2008 Freescale Semiconductor
- * Copyright 2008 Embedded Alley Solutions, 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
- */
-#define REGS_RTC_BASE	(STMP3XXX_REGS_BASE + 0x5C000)
-#define REGS_RTC_PHYS	0x8005C000
-#define REGS_RTC_SIZE	0x2000
-
-#define HW_RTC_CTRL		0x0
-#define BM_RTC_CTRL_ALARM_IRQ_EN	0x00000001
-#define BP_RTC_CTRL_ALARM_IRQ_EN	0
-#define BM_RTC_CTRL_ONEMSEC_IRQ_EN	0x00000002
-#define BM_RTC_CTRL_ALARM_IRQ	0x00000004
-#define BM_RTC_CTRL_ONEMSEC_IRQ	0x00000008
-#define BM_RTC_CTRL_WATCHDOGEN	0x00000010
-
-#define HW_RTC_STAT		0x10
-#define BM_RTC_STAT_NEW_REGS	0x0000FF00
-#define BP_RTC_STAT_NEW_REGS	8
-#define BM_RTC_STAT_STALE_REGS	0x00FF0000
-#define BP_RTC_STAT_STALE_REGS	16
-#define BM_RTC_STAT_RTC_PRESENT	0x80000000
-
-#define HW_RTC_SECONDS		0x30
-
-#define HW_RTC_ALARM		0x40
-
-#define HW_RTC_WATCHDOG		0x50
-
-#define HW_RTC_PERSISTENT0	0x60
-#define BM_RTC_PERSISTENT0_ALARM_WAKE_EN	0x00000002
-#define BM_RTC_PERSISTENT0_ALARM_EN	0x00000004
-#define BM_RTC_PERSISTENT0_XTAL24MHZ_PWRUP	0x00000010
-#define BM_RTC_PERSISTENT0_XTAL32KHZ_PWRUP	0x00000020
-#define BM_RTC_PERSISTENT0_ALARM_WAKE	0x00000080
-#define BM_RTC_PERSISTENT0_SPARE_ANALOG	0xFFFC0000
-#define BP_RTC_PERSISTENT0_SPARE_ANALOG	18
-
-#define HW_RTC_PERSISTENT1	0x70
-#define BM_RTC_PERSISTENT1_GENERAL	0xFFFFFFFF
-#define BP_RTC_PERSISTENT1_GENERAL	0
-
-#define HW_RTC_VERSION		0xD0
diff -druN linux-2.6.39-libre/arch/arm/mach-stmp378x/include/mach/regs-saif.h linux-3.0-rc7-libre/arch/arm/mach-stmp378x/include/mach/regs-saif.h
--- linux-2.6.39-libre/arch/arm/mach-stmp378x/include/mach/regs-saif.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-stmp378x/include/mach/regs-saif.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,21 +0,0 @@
-/*
- * stmp378x: SAIF register definitions
- *
- * Copyright (c) 2008 Freescale Semiconductor
- * Copyright 2008 Embedded Alley Solutions, 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
- */
-#define REGS_SAIF_SIZE	0x2000
diff -druN linux-2.6.39-libre/arch/arm/mach-stmp378x/include/mach/regs-spdif.h linux-3.0-rc7-libre/arch/arm/mach-stmp378x/include/mach/regs-spdif.h
--- linux-2.6.39-libre/arch/arm/mach-stmp378x/include/mach/regs-spdif.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-stmp378x/include/mach/regs-spdif.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,49 +0,0 @@
-/*
- * stmp378x: SPDIF register definitions
- *
- * Copyright (c) 2008 Freescale Semiconductor
- * Copyright 2008 Embedded Alley Solutions, 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
- */
-#define REGS_SPDIF_BASE	(STMP3XXX_REGS_BASE + 0x54000)
-#define REGS_SPDIF_PHYS	0x80054000
-#define REGS_SPDIF_SIZE	0x2000
-
-#define HW_SPDIF_CTRL		0x0
-#define BM_SPDIF_CTRL_RUN	0x00000001
-#define BP_SPDIF_CTRL_RUN	0
-#define BM_SPDIF_CTRL_FIFO_ERROR_IRQ_EN	0x00000002
-#define BM_SPDIF_CTRL_FIFO_OVERFLOW_IRQ	0x00000004
-#define BM_SPDIF_CTRL_FIFO_UNDERFLOW_IRQ	0x00000008
-#define BM_SPDIF_CTRL_WORD_LENGTH	0x00000010
-#define BM_SPDIF_CTRL_CLKGATE	0x40000000
-#define BM_SPDIF_CTRL_SFTRST	0x80000000
-
-#define HW_SPDIF_STAT		0x10
-
-#define HW_SPDIF_FRAMECTRL	0x20
-
-#define HW_SPDIF_SRR		0x30
-#define BM_SPDIF_SRR_RATE	0x000FFFFF
-#define BP_SPDIF_SRR_RATE	0
-#define BM_SPDIF_SRR_BASEMULT	0x70000000
-#define BP_SPDIF_SRR_BASEMULT	28
-
-#define HW_SPDIF_DEBUG		0x40
-
-#define HW_SPDIF_DATA		0x50
-
-#define HW_SPDIF_VERSION	0x60
diff -druN linux-2.6.39-libre/arch/arm/mach-stmp378x/include/mach/regs-ssp.h linux-3.0-rc7-libre/arch/arm/mach-stmp378x/include/mach/regs-ssp.h
--- linux-2.6.39-libre/arch/arm/mach-stmp378x/include/mach/regs-ssp.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-stmp378x/include/mach/regs-ssp.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,102 +0,0 @@
-/*
- * stmp378x: SSP register definitions
- *
- * Copyright (c) 2008 Freescale Semiconductor
- * Copyright 2008 Embedded Alley Solutions, 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
- */
-#define REGS_SSP1_BASE	(STMP3XXX_REGS_BASE + 0x10000)
-#define REGS_SSP1_PHYS	0x80010000
-#define REGS_SSP2_BASE	(STMP3XXX_REGS_BASE + 0x34000)
-#define REGS_SSP2_PHYS	0x80034000
-#define REGS_SSP_SIZE	0x2000
-
-#define HW_SSP_CTRL0		0x0
-#define BM_SSP_CTRL0_XFER_COUNT	0x0000FFFF
-#define BP_SSP_CTRL0_XFER_COUNT	0
-#define BM_SSP_CTRL0_ENABLE	0x00010000
-#define BM_SSP_CTRL0_GET_RESP	0x00020000
-#define BM_SSP_CTRL0_LONG_RESP	0x00080000
-#define BM_SSP_CTRL0_WAIT_FOR_CMD	0x00100000
-#define BM_SSP_CTRL0_WAIT_FOR_IRQ	0x00200000
-#define BM_SSP_CTRL0_BUS_WIDTH	0x00C00000
-#define BP_SSP_CTRL0_BUS_WIDTH	22
-#define BM_SSP_CTRL0_DATA_XFER	0x01000000
-#define BM_SSP_CTRL0_READ	0x02000000
-#define BM_SSP_CTRL0_IGNORE_CRC	0x04000000
-#define BM_SSP_CTRL0_LOCK_CS	0x08000000
-#define BM_SSP_CTRL0_RUN	0x20000000
-#define BM_SSP_CTRL0_CLKGATE	0x40000000
-#define BM_SSP_CTRL0_SFTRST	0x80000000
-
-#define HW_SSP_CMD0		0x10
-#define BM_SSP_CMD0_CMD		0x000000FF
-#define BP_SSP_CMD0_CMD		0
-#define BM_SSP_CMD0_BLOCK_COUNT	0x0000FF00
-#define BP_SSP_CMD0_BLOCK_COUNT	8
-#define BM_SSP_CMD0_BLOCK_SIZE	0x000F0000
-#define BP_SSP_CMD0_BLOCK_SIZE	16
-#define BM_SSP_CMD0_APPEND_8CYC	0x00100000
-#define BM_SSP_CMD1_CMD_ARG	0xFFFFFFFF
-#define BP_SSP_CMD1_CMD_ARG	0
-
-#define HW_SSP_TIMING		0x50
-#define BM_SSP_TIMING_CLOCK_RATE	0x000000FF
-#define BP_SSP_TIMING_CLOCK_RATE	0
-#define BM_SSP_TIMING_CLOCK_DIVIDE	0x0000FF00
-#define BP_SSP_TIMING_CLOCK_DIVIDE	8
-#define BM_SSP_TIMING_TIMEOUT	0xFFFF0000
-#define BP_SSP_TIMING_TIMEOUT	16
-
-#define HW_SSP_CTRL1		0x60
-#define BM_SSP_CTRL1_SSP_MODE	0x0000000F
-#define BP_SSP_CTRL1_SSP_MODE	0
-#define BM_SSP_CTRL1_WORD_LENGTH	0x000000F0
-#define BP_SSP_CTRL1_WORD_LENGTH	4
-#define BM_SSP_CTRL1_POLARITY	0x00000200
-#define BM_SSP_CTRL1_PHASE	0x00000400
-#define BM_SSP_CTRL1_DMA_ENABLE	0x00002000
-#define BM_SSP_CTRL1_FIFO_OVERRUN_IRQ	0x00008000
-#define BM_SSP_CTRL1_RECV_TIMEOUT_IRQ_EN	0x00010000
-#define BM_SSP_CTRL1_RECV_TIMEOUT_IRQ	0x00020000
-#define BM_SSP_CTRL1_FIFO_UNDERRUN_IRQ	0x00200000
-#define BM_SSP_CTRL1_DATA_CRC_IRQ_EN	0x00400000
-#define BM_SSP_CTRL1_DATA_CRC_IRQ	0x00800000
-#define BM_SSP_CTRL1_DATA_TIMEOUT_IRQ_EN	0x01000000
-#define BM_SSP_CTRL1_DATA_TIMEOUT_IRQ	0x02000000
-#define BM_SSP_CTRL1_RESP_TIMEOUT_IRQ_EN	0x04000000
-#define BM_SSP_CTRL1_RESP_TIMEOUT_IRQ	0x08000000
-#define BM_SSP_CTRL1_RESP_ERR_IRQ_EN	0x10000000
-#define BM_SSP_CTRL1_RESP_ERR_IRQ	0x20000000
-#define BM_SSP_CTRL1_SDIO_IRQ	0x80000000
-
-#define HW_SSP_DATA		0x70
-
-#define HW_SSP_SDRESP0		0x80
-
-#define HW_SSP_SDRESP1		0x90
-
-#define HW_SSP_SDRESP2		0xA0
-
-#define HW_SSP_SDRESP3		0xB0
-
-#define HW_SSP_STATUS		0xC0
-#define BM_SSP_STATUS_FIFO_EMPTY	0x00000020
-#define BM_SSP_STATUS_TIMEOUT	0x00001000
-#define BM_SSP_STATUS_RESP_TIMEOUT	0x00004000
-#define BM_SSP_STATUS_RESP_ERR	0x00008000
-#define BM_SSP_STATUS_RESP_CRC_ERR	0x00010000
-#define BM_SSP_STATUS_CARD_DETECT	0x10000000
diff -druN linux-2.6.39-libre/arch/arm/mach-stmp378x/include/mach/regs-sydma.h linux-3.0-rc7-libre/arch/arm/mach-stmp378x/include/mach/regs-sydma.h
--- linux-2.6.39-libre/arch/arm/mach-stmp378x/include/mach/regs-sydma.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-stmp378x/include/mach/regs-sydma.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,23 +0,0 @@
-/*
- * stmp378x: SYDMA register definitions
- *
- * Copyright (c) 2008 Freescale Semiconductor
- * Copyright 2008 Embedded Alley Solutions, 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
- */
-#define REGS_SYDMA_BASE	(STMP3XXX_REGS_BASE + 0x26000)
-#define REGS_SYDMA_PHYS	0x80026000
-#define REGS_SYDMA_SIZE	0x2000
diff -druN linux-2.6.39-libre/arch/arm/mach-stmp378x/include/mach/regs-timrot.h linux-3.0-rc7-libre/arch/arm/mach-stmp378x/include/mach/regs-timrot.h
--- linux-2.6.39-libre/arch/arm/mach-stmp378x/include/mach/regs-timrot.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-stmp378x/include/mach/regs-timrot.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,68 +0,0 @@
-/*
- * stmp378x: TIMROT register definitions
- *
- * Copyright (c) 2008 Freescale Semiconductor
- * Copyright 2008 Embedded Alley Solutions, 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
- */
-#ifndef _MACH_REGS_TIMROT
-#define _MACH_REGS_TIMROT
-
-#define REGS_TIMROT_BASE	(STMP3XXX_REGS_BASE + 0x68000)
-#define REGS_TIMROT_PHYS	0x80068000
-#define REGS_TIMROT_SIZE	0x2000
-
-#define HW_TIMROT_ROTCTRL	0x0
-#define BM_TIMROT_ROTCTRL_SELECT_A	0x00000007
-#define BP_TIMROT_ROTCTRL_SELECT_A	0
-#define BM_TIMROT_ROTCTRL_SELECT_B	0x00000070
-#define BP_TIMROT_ROTCTRL_SELECT_B	4
-#define BM_TIMROT_ROTCTRL_POLARITY_A	0x00000100
-#define BM_TIMROT_ROTCTRL_POLARITY_B	0x00000200
-#define BM_TIMROT_ROTCTRL_OVERSAMPLE	0x00000C00
-#define BP_TIMROT_ROTCTRL_OVERSAMPLE	10
-#define BM_TIMROT_ROTCTRL_RELATIVE	0x00001000
-#define BM_TIMROT_ROTCTRL_DIVIDER	0x003F0000
-#define BP_TIMROT_ROTCTRL_DIVIDER	16
-#define BM_TIMROT_ROTCTRL_ROTARY_PRESENT	0x20000000
-#define BM_TIMROT_ROTCTRL_CLKGATE	0x40000000
-#define BM_TIMROT_ROTCTRL_SFTRST	0x80000000
-
-#define HW_TIMROT_ROTCOUNT	0x10
-#define BM_TIMROT_ROTCOUNT_UPDOWN	0x0000FFFF
-#define BP_TIMROT_ROTCOUNT_UPDOWN	0
-
-#define HW_TIMROT_TIMCTRL0	(0x20 + 0 * 0x20)
-#define HW_TIMROT_TIMCTRL1	(0x20 + 1 * 0x20)
-#define HW_TIMROT_TIMCTRL2	(0x20 + 2 * 0x20)
-
-#define HW_TIMROT_TIMCTRLn	0x20
-#define BM_TIMROT_TIMCTRLn_SELECT	0x0000000F
-#define BP_TIMROT_TIMCTRLn_SELECT	0
-#define BM_TIMROT_TIMCTRLn_PRESCALE	0x00000030
-#define BP_TIMROT_TIMCTRLn_PRESCALE	4
-#define BM_TIMROT_TIMCTRLn_RELOAD	0x00000040
-#define BM_TIMROT_TIMCTRLn_UPDATE	0x00000080
-#define BM_TIMROT_TIMCTRLn_IRQ_EN	0x00004000
-#define BM_TIMROT_TIMCTRLn_IRQ	0x00008000
-
-#define HW_TIMROT_TIMCOUNT0	(0x30 + 0 * 0x20)
-#define HW_TIMROT_TIMCOUNT1	(0x30 + 1 * 0x20)
-#define HW_TIMROT_TIMCOUNT2	(0x30 + 2 * 0x20)
-
-#define HW_TIMROT_TIMCOUNTn	0x30
-
-#endif
diff -druN linux-2.6.39-libre/arch/arm/mach-stmp378x/include/mach/regs-tvenc.h linux-3.0-rc7-libre/arch/arm/mach-stmp378x/include/mach/regs-tvenc.h
--- linux-2.6.39-libre/arch/arm/mach-stmp378x/include/mach/regs-tvenc.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-stmp378x/include/mach/regs-tvenc.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,67 +0,0 @@
-/*
- * stmp378x: TVENC register definitions
- *
- * Copyright (c) 2008 Freescale Semiconductor
- * Copyright 2008 Embedded Alley Solutions, 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
- */
-#define REGS_TVENC_BASE	(STMP3XXX_REGS_BASE + 0x38000)
-#define REGS_TVENC_PHYS	0x80038000
-#define REGS_TVENC_SIZE	0x2000
-
-#define HW_TVENC_CTRL		0x0
-#define BM_TVENC_CTRL_CLKGATE	0x40000000
-#define BM_TVENC_CTRL_SFTRST	0x80000000
-
-#define HW_TVENC_CONFIG		0x10
-#define BM_TVENC_CONFIG_ENCD_MODE	0x00000007
-#define BP_TVENC_CONFIG_ENCD_MODE	0
-#define BM_TVENC_CONFIG_SYNC_MODE	0x00000070
-#define BP_TVENC_CONFIG_SYNC_MODE	4
-#define BM_TVENC_CONFIG_FSYNC_PHS	0x00000200
-#define BM_TVENC_CONFIG_CGAIN	0x0000C000
-#define BP_TVENC_CONFIG_CGAIN	14
-#define BM_TVENC_CONFIG_YGAIN_SEL	0x00030000
-#define BP_TVENC_CONFIG_YGAIN_SEL	16
-#define BM_TVENC_CONFIG_PAL_SHAPE	0x00100000
-
-#define HW_TVENC_SYNCOFFSET	0x30
-
-#define HW_TVENC_COLORSUB0	0xC0
-
-#define HW_TVENC_COLORBURST	0x140
-#define BM_TVENC_COLORBURST_PBA	0x00FF0000
-#define BP_TVENC_COLORBURST_PBA	16
-#define BM_TVENC_COLORBURST_NBA	0xFF000000
-#define BP_TVENC_COLORBURST_NBA	24
-
-#define HW_TVENC_MACROVISION0	0x150
-
-#define HW_TVENC_MACROVISION1	0x160
-
-#define HW_TVENC_MACROVISION2	0x170
-
-#define HW_TVENC_MACROVISION3	0x180
-
-#define HW_TVENC_MACROVISION4	0x190
-
-#define HW_TVENC_DACCTRL	0x1A0
-#define BM_TVENC_DACCTRL_RVAL	0x00000070
-#define BP_TVENC_DACCTRL_RVAL	4
-#define BM_TVENC_DACCTRL_DUMP_TOVDD1	0x00000100
-#define BM_TVENC_DACCTRL_PWRUP1	0x00001000
-#define BM_TVENC_DACCTRL_GAINUP	0x00040000
-#define BM_TVENC_DACCTRL_GAINDN	0x00080000
diff -druN linux-2.6.39-libre/arch/arm/mach-stmp378x/include/mach/regs-uartapp.h linux-3.0-rc7-libre/arch/arm/mach-stmp378x/include/mach/regs-uartapp.h
--- linux-2.6.39-libre/arch/arm/mach-stmp378x/include/mach/regs-uartapp.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-stmp378x/include/mach/regs-uartapp.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,87 +0,0 @@
-/*
- * stmp378x: UARTAPP register definitions
- *
- * Copyright (c) 2008 Freescale Semiconductor
- * Copyright 2008 Embedded Alley Solutions, 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
- */
-#define REGS_UARTAPP1_BASE	(STMP3XXX_REGS_BASE + 0x6C000)
-#define REGS_UARTAPP1_PHYS	0x8006C000
-#define REGS_UARTAPP2_BASE	(STMP3XXX_REGS_BASE + 0x6E000)
-#define REGS_UARTAPP2_PHYS	0x8006E000
-#define REGS_UARTAPP_SIZE	0x2000
-
-#define HW_UARTAPP_CTRL0	0x0
-#define BM_UARTAPP_CTRL0_XFER_COUNT	0x0000FFFF
-#define BP_UARTAPP_CTRL0_XFER_COUNT	0
-#define BM_UARTAPP_CTRL0_RXTIMEOUT	0x07FF0000
-#define BP_UARTAPP_CTRL0_RXTIMEOUT	16
-#define BM_UARTAPP_CTRL0_RXTO_ENABLE	0x08000000
-#define BM_UARTAPP_CTRL0_RUN	0x20000000
-#define BM_UARTAPP_CTRL0_SFTRST	0x80000000
-#define BM_UARTAPP_CTRL1_XFER_COUNT	0x0000FFFF
-#define BP_UARTAPP_CTRL1_XFER_COUNT	0
-#define BM_UARTAPP_CTRL1_RUN	0x10000000
-
-#define HW_UARTAPP_CTRL2	0x20
-#define BM_UARTAPP_CTRL2_UARTEN	0x00000001
-#define BP_UARTAPP_CTRL2_UARTEN	0
-#define BM_UARTAPP_CTRL2_TXE	0x00000100
-#define BM_UARTAPP_CTRL2_RXE	0x00000200
-#define BM_UARTAPP_CTRL2_RTS	0x00000800
-#define BM_UARTAPP_CTRL2_RTSEN	0x00004000
-#define BM_UARTAPP_CTRL2_CTSEN	0x00008000
-#define BM_UARTAPP_CTRL2_RXDMAE	0x01000000
-#define BM_UARTAPP_CTRL2_TXDMAE	0x02000000
-#define BM_UARTAPP_CTRL2_DMAONERR	0x04000000
-
-#define HW_UARTAPP_LINECTRL	0x30
-#define BM_UARTAPP_LINECTRL_BRK	0x00000001
-#define BP_UARTAPP_LINECTRL_BRK	0
-#define BM_UARTAPP_LINECTRL_PEN	0x00000002
-#define BM_UARTAPP_LINECTRL_EPS	0x00000004
-#define BM_UARTAPP_LINECTRL_STP2	0x00000008
-#define BM_UARTAPP_LINECTRL_FEN	0x00000010
-#define BM_UARTAPP_LINECTRL_WLEN	0x00000060
-#define BP_UARTAPP_LINECTRL_WLEN	5
-#define BM_UARTAPP_LINECTRL_SPS	0x00000080
-#define BM_UARTAPP_LINECTRL_BAUD_DIVFRAC	0x00003F00
-#define BP_UARTAPP_LINECTRL_BAUD_DIVFRAC	8
-#define BM_UARTAPP_LINECTRL_BAUD_DIVINT	0xFFFF0000
-#define BP_UARTAPP_LINECTRL_BAUD_DIVINT	16
-
-#define HW_UARTAPP_INTR		0x50
-#define BM_UARTAPP_INTR_CTSMIS	0x00000002
-#define BM_UARTAPP_INTR_RTIS	0x00000040
-#define BM_UARTAPP_INTR_CTSMIEN	0x00020000
-#define BM_UARTAPP_INTR_RXIEN	0x00100000
-#define BM_UARTAPP_INTR_RTIEN	0x00400000
-
-#define HW_UARTAPP_DATA		0x60
-
-#define HW_UARTAPP_STAT		0x70
-#define BM_UARTAPP_STAT_RXCOUNT	0x0000FFFF
-#define BP_UARTAPP_STAT_RXCOUNT	0
-#define BM_UARTAPP_STAT_FERR	0x00010000
-#define BM_UARTAPP_STAT_PERR	0x00020000
-#define BM_UARTAPP_STAT_BERR	0x00040000
-#define BM_UARTAPP_STAT_OERR	0x00080000
-#define BM_UARTAPP_STAT_RXFE	0x01000000
-#define BM_UARTAPP_STAT_TXFF	0x02000000
-#define BM_UARTAPP_STAT_TXFE	0x08000000
-#define BM_UARTAPP_STAT_CTS	0x10000000
-
-#define HW_UARTAPP_VERSION	0x90
diff -druN linux-2.6.39-libre/arch/arm/mach-stmp378x/include/mach/regs-uartdbg.h linux-3.0-rc7-libre/arch/arm/mach-stmp378x/include/mach/regs-uartdbg.h
--- linux-2.6.39-libre/arch/arm/mach-stmp378x/include/mach/regs-uartdbg.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-stmp378x/include/mach/regs-uartdbg.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,268 +0,0 @@
-/*
- * stmp378x: UARTDBG register definitions
- *
- * Copyright (c) 2008 Freescale Semiconductor
- * Copyright 2008 Embedded Alley Solutions, 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
- */
-#define REGS_UARTDBG_BASE	(STMP3XXX_REGS_BASE + 0x70000)
-#define REGS_UARTDBG_PHYS	0x80070000
-#define REGS_UARTDBG_SIZE	0x2000
-
-#define HW_UARTDBGDR 0x00000000
-#define BP_UARTDBGDR_UNAVAILABLE      16
-#define BM_UARTDBGDR_UNAVAILABLE 0xFFFF0000
-#define BF_UARTDBGDR_UNAVAILABLE(v) \
-	(((v) << 16) & BM_UARTDBGDR_UNAVAILABLE)
-#define BP_UARTDBGDR_RESERVED      12
-#define BM_UARTDBGDR_RESERVED 0x0000F000
-#define BF_UARTDBGDR_RESERVED(v)  \
-	(((v) << 12) & BM_UARTDBGDR_RESERVED)
-#define BM_UARTDBGDR_OE 0x00000800
-#define BM_UARTDBGDR_BE 0x00000400
-#define BM_UARTDBGDR_PE 0x00000200
-#define BM_UARTDBGDR_FE 0x00000100
-#define BP_UARTDBGDR_DATA      0
-#define BM_UARTDBGDR_DATA 0x000000FF
-#define BF_UARTDBGDR_DATA(v)  \
-	(((v) << 0) & BM_UARTDBGDR_DATA)
-#define HW_UARTDBGRSR_ECR 0x00000004
-#define BP_UARTDBGRSR_ECR_UNAVAILABLE      8
-#define BM_UARTDBGRSR_ECR_UNAVAILABLE 0xFFFFFF00
-#define BF_UARTDBGRSR_ECR_UNAVAILABLE(v) \
-	(((v) << 8) & BM_UARTDBGRSR_ECR_UNAVAILABLE)
-#define BP_UARTDBGRSR_ECR_EC      4
-#define BM_UARTDBGRSR_ECR_EC 0x000000F0
-#define BF_UARTDBGRSR_ECR_EC(v)  \
-	(((v) << 4) & BM_UARTDBGRSR_ECR_EC)
-#define BM_UARTDBGRSR_ECR_OE 0x00000008
-#define BM_UARTDBGRSR_ECR_BE 0x00000004
-#define BM_UARTDBGRSR_ECR_PE 0x00000002
-#define BM_UARTDBGRSR_ECR_FE 0x00000001
-#define HW_UARTDBGFR 0x00000018
-#define BP_UARTDBGFR_UNAVAILABLE      16
-#define BM_UARTDBGFR_UNAVAILABLE 0xFFFF0000
-#define BF_UARTDBGFR_UNAVAILABLE(v) \
-	(((v) << 16) & BM_UARTDBGFR_UNAVAILABLE)
-#define BP_UARTDBGFR_RESERVED      9
-#define BM_UARTDBGFR_RESERVED 0x0000FE00
-#define BF_UARTDBGFR_RESERVED(v)  \
-	(((v) << 9) & BM_UARTDBGFR_RESERVED)
-#define BM_UARTDBGFR_RI 0x00000100
-#define BM_UARTDBGFR_TXFE 0x00000080
-#define BM_UARTDBGFR_RXFF 0x00000040
-#define BM_UARTDBGFR_TXFF 0x00000020
-#define BM_UARTDBGFR_RXFE 0x00000010
-#define BM_UARTDBGFR_BUSY 0x00000008
-#define BM_UARTDBGFR_DCD 0x00000004
-#define BM_UARTDBGFR_DSR 0x00000002
-#define BM_UARTDBGFR_CTS 0x00000001
-#define HW_UARTDBGILPR 0x00000020
-#define BP_UARTDBGILPR_UNAVAILABLE      8
-#define BM_UARTDBGILPR_UNAVAILABLE 0xFFFFFF00
-#define BF_UARTDBGILPR_UNAVAILABLE(v) \
-	(((v) << 8) & BM_UARTDBGILPR_UNAVAILABLE)
-#define BP_UARTDBGILPR_ILPDVSR      0
-#define BM_UARTDBGILPR_ILPDVSR 0x000000FF
-#define BF_UARTDBGILPR_ILPDVSR(v)  \
-	(((v) << 0) & BM_UARTDBGILPR_ILPDVSR)
-#define HW_UARTDBGIBRD 0x00000024
-#define BP_UARTDBGIBRD_UNAVAILABLE      16
-#define BM_UARTDBGIBRD_UNAVAILABLE 0xFFFF0000
-#define BF_UARTDBGIBRD_UNAVAILABLE(v) \
-	(((v) << 16) & BM_UARTDBGIBRD_UNAVAILABLE)
-#define BP_UARTDBGIBRD_BAUD_DIVINT      0
-#define BM_UARTDBGIBRD_BAUD_DIVINT 0x0000FFFF
-#define BF_UARTDBGIBRD_BAUD_DIVINT(v)  \
-	(((v) << 0) & BM_UARTDBGIBRD_BAUD_DIVINT)
-#define HW_UARTDBGFBRD 0x00000028
-#define BP_UARTDBGFBRD_UNAVAILABLE      8
-#define BM_UARTDBGFBRD_UNAVAILABLE 0xFFFFFF00
-#define BF_UARTDBGFBRD_UNAVAILABLE(v) \
-	(((v) << 8) & BM_UARTDBGFBRD_UNAVAILABLE)
-#define BP_UARTDBGFBRD_RESERVED      6
-#define BM_UARTDBGFBRD_RESERVED 0x000000C0
-#define BF_UARTDBGFBRD_RESERVED(v)  \
-	(((v) << 6) & BM_UARTDBGFBRD_RESERVED)
-#define BP_UARTDBGFBRD_BAUD_DIVFRAC      0
-#define BM_UARTDBGFBRD_BAUD_DIVFRAC 0x0000003F
-#define BF_UARTDBGFBRD_BAUD_DIVFRAC(v)  \
-	(((v) << 0) & BM_UARTDBGFBRD_BAUD_DIVFRAC)
-#define HW_UARTDBGLCR_H 0x0000002c
-#define BP_UARTDBGLCR_H_UNAVAILABLE      16
-#define BM_UARTDBGLCR_H_UNAVAILABLE 0xFFFF0000
-#define BF_UARTDBGLCR_H_UNAVAILABLE(v) \
-	(((v) << 16) & BM_UARTDBGLCR_H_UNAVAILABLE)
-#define BP_UARTDBGLCR_H_RESERVED      8
-#define BM_UARTDBGLCR_H_RESERVED 0x0000FF00
-#define BF_UARTDBGLCR_H_RESERVED(v)  \
-	(((v) << 8) & BM_UARTDBGLCR_H_RESERVED)
-#define BM_UARTDBGLCR_H_SPS 0x00000080
-#define BP_UARTDBGLCR_H_WLEN      5
-#define BM_UARTDBGLCR_H_WLEN 0x00000060
-#define BF_UARTDBGLCR_H_WLEN(v)  \
-	(((v) << 5) & BM_UARTDBGLCR_H_WLEN)
-#define BM_UARTDBGLCR_H_FEN 0x00000010
-#define BM_UARTDBGLCR_H_STP2 0x00000008
-#define BM_UARTDBGLCR_H_EPS 0x00000004
-#define BM_UARTDBGLCR_H_PEN 0x00000002
-#define BM_UARTDBGLCR_H_BRK 0x00000001
-#define HW_UARTDBGCR 0x00000030
-#define BP_UARTDBGCR_UNAVAILABLE      16
-#define BM_UARTDBGCR_UNAVAILABLE 0xFFFF0000
-#define BF_UARTDBGCR_UNAVAILABLE(v) \
-	(((v) << 16) & BM_UARTDBGCR_UNAVAILABLE)
-#define BM_UARTDBGCR_CTSEN 0x00008000
-#define BM_UARTDBGCR_RTSEN 0x00004000
-#define BM_UARTDBGCR_OUT2 0x00002000
-#define BM_UARTDBGCR_OUT1 0x00001000
-#define BM_UARTDBGCR_RTS 0x00000800
-#define BM_UARTDBGCR_DTR 0x00000400
-#define BM_UARTDBGCR_RXE 0x00000200
-#define BM_UARTDBGCR_TXE 0x00000100
-#define BM_UARTDBGCR_LBE 0x00000080
-#define BP_UARTDBGCR_RESERVED      3
-#define BM_UARTDBGCR_RESERVED 0x00000078
-#define BF_UARTDBGCR_RESERVED(v)  \
-	(((v) << 3) & BM_UARTDBGCR_RESERVED)
-#define BM_UARTDBGCR_SIRLP 0x00000004
-#define BM_UARTDBGCR_SIREN 0x00000002
-#define BM_UARTDBGCR_UARTEN 0x00000001
-#define HW_UARTDBGIFLS 0x00000034
-#define BP_UARTDBGIFLS_UNAVAILABLE      16
-#define BM_UARTDBGIFLS_UNAVAILABLE 0xFFFF0000
-#define BF_UARTDBGIFLS_UNAVAILABLE(v) \
-	(((v) << 16) & BM_UARTDBGIFLS_UNAVAILABLE)
-#define BP_UARTDBGIFLS_RESERVED      6
-#define BM_UARTDBGIFLS_RESERVED 0x0000FFC0
-#define BF_UARTDBGIFLS_RESERVED(v)  \
-	(((v) << 6) & BM_UARTDBGIFLS_RESERVED)
-#define BP_UARTDBGIFLS_RXIFLSEL      3
-#define BM_UARTDBGIFLS_RXIFLSEL 0x00000038
-#define BF_UARTDBGIFLS_RXIFLSEL(v)  \
-	(((v) << 3) & BM_UARTDBGIFLS_RXIFLSEL)
-#define BV_UARTDBGIFLS_RXIFLSEL__NOT_EMPTY      0x0
-#define BV_UARTDBGIFLS_RXIFLSEL__ONE_QUARTER    0x1
-#define BV_UARTDBGIFLS_RXIFLSEL__ONE_HALF       0x2
-#define BV_UARTDBGIFLS_RXIFLSEL__THREE_QUARTERS 0x3
-#define BV_UARTDBGIFLS_RXIFLSEL__SEVEN_EIGHTHS  0x4
-#define BV_UARTDBGIFLS_RXIFLSEL__INVALID5       0x5
-#define BV_UARTDBGIFLS_RXIFLSEL__INVALID6       0x6
-#define BV_UARTDBGIFLS_RXIFLSEL__INVALID7       0x7
-#define BP_UARTDBGIFLS_TXIFLSEL      0
-#define BM_UARTDBGIFLS_TXIFLSEL 0x00000007
-#define BF_UARTDBGIFLS_TXIFLSEL(v)  \
-	(((v) << 0) & BM_UARTDBGIFLS_TXIFLSEL)
-#define BV_UARTDBGIFLS_TXIFLSEL__EMPTY	  0x0
-#define BV_UARTDBGIFLS_TXIFLSEL__ONE_QUARTER    0x1
-#define BV_UARTDBGIFLS_TXIFLSEL__ONE_HALF       0x2
-#define BV_UARTDBGIFLS_TXIFLSEL__THREE_QUARTERS 0x3
-#define BV_UARTDBGIFLS_TXIFLSEL__SEVEN_EIGHTHS  0x4
-#define BV_UARTDBGIFLS_TXIFLSEL__INVALID5       0x5
-#define BV_UARTDBGIFLS_TXIFLSEL__INVALID6       0x6
-#define BV_UARTDBGIFLS_TXIFLSEL__INVALID7       0x7
-#define HW_UARTDBGIMSC 0x00000038
-#define BP_UARTDBGIMSC_UNAVAILABLE      16
-#define BM_UARTDBGIMSC_UNAVAILABLE 0xFFFF0000
-#define BF_UARTDBGIMSC_UNAVAILABLE(v) \
-	(((v) << 16) & BM_UARTDBGIMSC_UNAVAILABLE)
-#define BP_UARTDBGIMSC_RESERVED      11
-#define BM_UARTDBGIMSC_RESERVED 0x0000F800
-#define BF_UARTDBGIMSC_RESERVED(v)  \
-	(((v) << 11) & BM_UARTDBGIMSC_RESERVED)
-#define BM_UARTDBGIMSC_OEIM 0x00000400
-#define BM_UARTDBGIMSC_BEIM 0x00000200
-#define BM_UARTDBGIMSC_PEIM 0x00000100
-#define BM_UARTDBGIMSC_FEIM 0x00000080
-#define BM_UARTDBGIMSC_RTIM 0x00000040
-#define BM_UARTDBGIMSC_TXIM 0x00000020
-#define BM_UARTDBGIMSC_RXIM 0x00000010
-#define BM_UARTDBGIMSC_DSRMIM 0x00000008
-#define BM_UARTDBGIMSC_DCDMIM 0x00000004
-#define BM_UARTDBGIMSC_CTSMIM 0x00000002
-#define BM_UARTDBGIMSC_RIMIM 0x00000001
-#define HW_UARTDBGRIS 0x0000003c
-#define BP_UARTDBGRIS_UNAVAILABLE      16
-#define BM_UARTDBGRIS_UNAVAILABLE 0xFFFF0000
-#define BF_UARTDBGRIS_UNAVAILABLE(v) \
-	(((v) << 16) & BM_UARTDBGRIS_UNAVAILABLE)
-#define BP_UARTDBGRIS_RESERVED      11
-#define BM_UARTDBGRIS_RESERVED 0x0000F800
-#define BF_UARTDBGRIS_RESERVED(v)  \
-	(((v) << 11) & BM_UARTDBGRIS_RESERVED)
-#define BM_UARTDBGRIS_OERIS 0x00000400
-#define BM_UARTDBGRIS_BERIS 0x00000200
-#define BM_UARTDBGRIS_PERIS 0x00000100
-#define BM_UARTDBGRIS_FERIS 0x00000080
-#define BM_UARTDBGRIS_RTRIS 0x00000040
-#define BM_UARTDBGRIS_TXRIS 0x00000020
-#define BM_UARTDBGRIS_RXRIS 0x00000010
-#define BM_UARTDBGRIS_DSRRMIS 0x00000008
-#define BM_UARTDBGRIS_DCDRMIS 0x00000004
-#define BM_UARTDBGRIS_CTSRMIS 0x00000002
-#define BM_UARTDBGRIS_RIRMIS 0x00000001
-#define HW_UARTDBGMIS 0x00000040
-#define BP_UARTDBGMIS_UNAVAILABLE      16
-#define BM_UARTDBGMIS_UNAVAILABLE 0xFFFF0000
-#define BF_UARTDBGMIS_UNAVAILABLE(v) \
-	(((v) << 16) & BM_UARTDBGMIS_UNAVAILABLE)
-#define BP_UARTDBGMIS_RESERVED      11
-#define BM_UARTDBGMIS_RESERVED 0x0000F800
-#define BF_UARTDBGMIS_RESERVED(v)  \
-	(((v) << 11) & BM_UARTDBGMIS_RESERVED)
-#define BM_UARTDBGMIS_OEMIS 0x00000400
-#define BM_UARTDBGMIS_BEMIS 0x00000200
-#define BM_UARTDBGMIS_PEMIS 0x00000100
-#define BM_UARTDBGMIS_FEMIS 0x00000080
-#define BM_UARTDBGMIS_RTMIS 0x00000040
-#define BM_UARTDBGMIS_TXMIS 0x00000020
-#define BM_UARTDBGMIS_RXMIS 0x00000010
-#define BM_UARTDBGMIS_DSRMMIS 0x00000008
-#define BM_UARTDBGMIS_DCDMMIS 0x00000004
-#define BM_UARTDBGMIS_CTSMMIS 0x00000002
-#define BM_UARTDBGMIS_RIMMIS 0x00000001
-#define HW_UARTDBGICR 0x00000044
-#define BP_UARTDBGICR_UNAVAILABLE      16
-#define BM_UARTDBGICR_UNAVAILABLE 0xFFFF0000
-#define BF_UARTDBGICR_UNAVAILABLE(v) \
-	(((v) << 16) & BM_UARTDBGICR_UNAVAILABLE)
-#define BP_UARTDBGICR_RESERVED      11
-#define BM_UARTDBGICR_RESERVED 0x0000F800
-#define BF_UARTDBGICR_RESERVED(v)  \
-	(((v) << 11) & BM_UARTDBGICR_RESERVED)
-#define BM_UARTDBGICR_OEIC 0x00000400
-#define BM_UARTDBGICR_BEIC 0x00000200
-#define BM_UARTDBGICR_PEIC 0x00000100
-#define BM_UARTDBGICR_FEIC 0x00000080
-#define BM_UARTDBGICR_RTIC 0x00000040
-#define BM_UARTDBGICR_TXIC 0x00000020
-#define BM_UARTDBGICR_RXIC 0x00000010
-#define BM_UARTDBGICR_DSRMIC 0x00000008
-#define BM_UARTDBGICR_DCDMIC 0x00000004
-#define BM_UARTDBGICR_CTSMIC 0x00000002
-#define BM_UARTDBGICR_RIMIC 0x00000001
-#define HW_UARTDBGDMACR 0x00000048
-#define BP_UARTDBGDMACR_UNAVAILABLE      16
-#define BM_UARTDBGDMACR_UNAVAILABLE 0xFFFF0000
-#define BF_UARTDBGDMACR_UNAVAILABLE(v) \
-	(((v) << 16) & BM_UARTDBGDMACR_UNAVAILABLE)
-#define BP_UARTDBGDMACR_RESERVED      3
-#define BM_UARTDBGDMACR_RESERVED 0x0000FFF8
-#define BF_UARTDBGDMACR_RESERVED(v)  \
-	(((v) << 3) & BM_UARTDBGDMACR_RESERVED)
-#define BM_UARTDBGDMACR_DMAONERR 0x00000004
-#define BM_UARTDBGDMACR_TXDMAE 0x00000002
-#define BM_UARTDBGDMACR_RXDMAE 0x00000001
diff -druN linux-2.6.39-libre/arch/arm/mach-stmp378x/include/mach/regs-usbctrl.h linux-3.0-rc7-libre/arch/arm/mach-stmp378x/include/mach/regs-usbctrl.h
--- linux-2.6.39-libre/arch/arm/mach-stmp378x/include/mach/regs-usbctrl.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-stmp378x/include/mach/regs-usbctrl.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,40 +0,0 @@
-/*
- * stmp378x: USBCTRL register definitions
- *
- * Copyright (c) 2008 Freescale Semiconductor
- * Copyright 2008 Embedded Alley Solutions, 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
- */
-#define REGS_USBCTRL_BASE	(STMP3XXX_REGS_BASE + 0x80000)
-#define REGS_USBCTRL_PHYS	0x80080000
-#define REGS_USBCTRL_SIZE	0x2000
-
-#define HW_USBCTRL_USBCMD	0x140
-#define BM_USBCTRL_USBCMD_RS	0x00000001
-#define BP_USBCTRL_USBCMD_RS	0
-#define BM_USBCTRL_USBCMD_RST	0x00000002
-
-#define HW_USBCTRL_USBINTR	0x148
-#define BM_USBCTRL_USBINTR_UE	0x00000001
-#define BP_USBCTRL_USBINTR_UE	0
-
-#define HW_USBCTRL_PORTSC1	0x184
-#define BM_USBCTRL_PORTSC1_PHCD	0x00800000
-
-#define HW_USBCTRL_OTGSC	0x1A4
-#define BM_USBCTRL_OTGSC_ID	0x00000100
-#define BM_USBCTRL_OTGSC_IDIS	0x00010000
-#define BM_USBCTRL_OTGSC_IDIE	0x01000000
diff -druN linux-2.6.39-libre/arch/arm/mach-stmp378x/include/mach/regs-usbphy.h linux-3.0-rc7-libre/arch/arm/mach-stmp378x/include/mach/regs-usbphy.h
--- linux-2.6.39-libre/arch/arm/mach-stmp378x/include/mach/regs-usbphy.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-stmp378x/include/mach/regs-usbphy.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,37 +0,0 @@
-/*
- * stmp378x: USBPHY register definitions
- *
- * Copyright (c) 2008 Freescale Semiconductor
- * Copyright 2008 Embedded Alley Solutions, 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
- */
-#define REGS_USBPHY_BASE	(STMP3XXX_REGS_BASE + 0x7C000)
-#define REGS_USBPHY_PHYS	0x8007C000
-#define REGS_USBPHY_SIZE	0x2000
-
-#define HW_USBPHY_PWD		0x0
-
-#define HW_USBPHY_CTRL		0x30
-#define BM_USBPHY_CTRL_ENHOSTDISCONDETECT	0x00000002
-#define BM_USBPHY_CTRL_ENDEVPLUGINDETECT	0x00000010
-#define BM_USBPHY_CTRL_ENOTGIDDETECT	0x00000080
-#define BM_USBPHY_CTRL_ENIRQDEVPLUGIN	0x00000800
-#define BM_USBPHY_CTRL_CLKGATE	0x40000000
-#define BM_USBPHY_CTRL_SFTRST	0x80000000
-
-#define HW_USBPHY_STATUS	0x40
-#define BM_USBPHY_STATUS_DEVPLUGIN_STATUS	0x00000040
-#define BM_USBPHY_STATUS_OTGID_STATUS	0x00000100
diff -druN linux-2.6.39-libre/arch/arm/mach-stmp378x/Makefile linux-3.0-rc7-libre/arch/arm/mach-stmp378x/Makefile
--- linux-2.6.39-libre/arch/arm/mach-stmp378x/Makefile	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-stmp378x/Makefile	1969-12-31 19:00:00.000000000 -0500
@@ -1,2 +0,0 @@
-obj-$(CONFIG_ARCH_STMP378X) += stmp378x.o
-obj-$(CONFIG_MACH_STMP378X) += stmp378x_devb.o
diff -druN linux-2.6.39-libre/arch/arm/mach-stmp378x/Makefile.boot linux-3.0-rc7-libre/arch/arm/mach-stmp378x/Makefile.boot
--- linux-2.6.39-libre/arch/arm/mach-stmp378x/Makefile.boot	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-stmp378x/Makefile.boot	1969-12-31 19:00:00.000000000 -0500
@@ -1,3 +0,0 @@
-   zreladdr-y	:= 0x40008000
-params_phys-y	:= 0x40000100
-initrd_phys-y	:= 0x40800000
diff -druN linux-2.6.39-libre/arch/arm/mach-stmp378x/stmp378x.c linux-3.0-rc7-libre/arch/arm/mach-stmp378x/stmp378x.c
--- linux-2.6.39-libre/arch/arm/mach-stmp378x/stmp378x.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-stmp378x/stmp378x.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,299 +0,0 @@
-/*
- * Freescale STMP378X platform support
- *
- * Embedded Alley Solutions, Inc <source@embeddedalley.com>
- *
- * Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved.
- * Copyright 2008 Embedded Alley Solutions, 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/kernel.h>
-#include <linux/init.h>
-#include <linux/platform_device.h>
-#include <linux/irq.h>
-#include <linux/dma-mapping.h>
-
-#include <asm/dma.h>
-#include <asm/setup.h>
-#include <asm/mach-types.h>
-
-#include <asm/mach/arch.h>
-#include <asm/mach/irq.h>
-#include <asm/mach/map.h>
-#include <asm/mach/time.h>
-
-#include <mach/pins.h>
-#include <mach/pinmux.h>
-#include <mach/dma.h>
-#include <mach/hardware.h>
-#include <mach/system.h>
-#include <mach/platform.h>
-#include <mach/stmp3xxx.h>
-#include <mach/regs-icoll.h>
-#include <mach/regs-apbh.h>
-#include <mach/regs-apbx.h>
-#include <mach/regs-pxp.h>
-#include <mach/regs-i2c.h>
-
-#include "stmp378x.h"
-/*
- * IRQ handling
- */
-static void stmp378x_ack_irq(struct irq_data *d)
-{
-	/* Tell ICOLL to release IRQ line */
-	__raw_writel(0, REGS_ICOLL_BASE + HW_ICOLL_VECTOR);
-
-	/* ACK current interrupt */
-	__raw_writel(0x01 /* BV_ICOLL_LEVELACK_IRQLEVELACK__LEVEL0 */,
-			REGS_ICOLL_BASE + HW_ICOLL_LEVELACK);
-
-	/* Barrier */
-	(void)__raw_readl(REGS_ICOLL_BASE + HW_ICOLL_STAT);
-}
-
-static void stmp378x_mask_irq(struct irq_data *d)
-{
-	/* IRQ disable */
-	stmp3xxx_clearl(BM_ICOLL_INTERRUPTn_ENABLE,
-			REGS_ICOLL_BASE + HW_ICOLL_INTERRUPTn + d->irq * 0x10);
-}
-
-static void stmp378x_unmask_irq(struct irq_data *d)
-{
-	/* IRQ enable */
-	stmp3xxx_setl(BM_ICOLL_INTERRUPTn_ENABLE,
-		      REGS_ICOLL_BASE + HW_ICOLL_INTERRUPTn + d->irq * 0x10);
-}
-
-static struct irq_chip stmp378x_chip = {
-	.irq_ack	= stmp378x_ack_irq,
-	.irq_mask	= stmp378x_mask_irq,
-	.irq_unmask	= stmp378x_unmask_irq,
-};
-
-void __init stmp378x_init_irq(void)
-{
-	stmp3xxx_init_irq(&stmp378x_chip);
-}
-
-/*
- * DMA interrupt handling
- */
-void stmp3xxx_arch_dma_enable_interrupt(int channel)
-{
-	void __iomem *c1, *c2;
-
-	switch (STMP3XXX_DMA_BUS(channel)) {
-	case STMP3XXX_BUS_APBH:
-		c1 = REGS_APBH_BASE + HW_APBH_CTRL1;
-		c2 = REGS_APBH_BASE + HW_APBH_CTRL2;
-		break;
-
-	case STMP3XXX_BUS_APBX:
-		c1 = REGS_APBX_BASE + HW_APBX_CTRL1;
-		c2 = REGS_APBX_BASE + HW_APBX_CTRL2;
-		break;
-
-	default:
-		return;
-	}
-	stmp3xxx_setl(1 << (16 + STMP3XXX_DMA_CHANNEL(channel)), c1);
-	stmp3xxx_setl(1 << (16 + STMP3XXX_DMA_CHANNEL(channel)), c2);
-}
-EXPORT_SYMBOL(stmp3xxx_arch_dma_enable_interrupt);
-
-void stmp3xxx_arch_dma_clear_interrupt(int channel)
-{
-	void __iomem *c1, *c2;
-
-	switch (STMP3XXX_DMA_BUS(channel)) {
-	case STMP3XXX_BUS_APBH:
-		c1 = REGS_APBH_BASE + HW_APBH_CTRL1;
-		c2 = REGS_APBH_BASE + HW_APBH_CTRL2;
-		break;
-
-	case STMP3XXX_BUS_APBX:
-		c1 = REGS_APBX_BASE + HW_APBX_CTRL1;
-		c2 = REGS_APBX_BASE + HW_APBX_CTRL2;
-		break;
-
-	default:
-		return;
-	}
-	stmp3xxx_clearl(1 << STMP3XXX_DMA_CHANNEL(channel), c1);
-	stmp3xxx_clearl(1 << STMP3XXX_DMA_CHANNEL(channel), c2);
-}
-EXPORT_SYMBOL(stmp3xxx_arch_dma_clear_interrupt);
-
-int stmp3xxx_arch_dma_is_interrupt(int channel)
-{
-	int r = 0;
-
-	switch (STMP3XXX_DMA_BUS(channel)) {
-	case STMP3XXX_BUS_APBH:
-		r = __raw_readl(REGS_APBH_BASE + HW_APBH_CTRL1) &
-			(1 << STMP3XXX_DMA_CHANNEL(channel));
-		break;
-
-	case STMP3XXX_BUS_APBX:
-		r = __raw_readl(REGS_APBX_BASE + HW_APBX_CTRL1) &
-			(1 << STMP3XXX_DMA_CHANNEL(channel));
-		break;
-	}
-	return r;
-}
-EXPORT_SYMBOL(stmp3xxx_arch_dma_is_interrupt);
-
-void stmp3xxx_arch_dma_reset_channel(int channel)
-{
-	unsigned chbit = 1 << STMP3XXX_DMA_CHANNEL(channel);
-	void __iomem *c0;
-	u32 mask;
-
-	switch (STMP3XXX_DMA_BUS(channel)) {
-	case STMP3XXX_BUS_APBH:
-		c0 = REGS_APBH_BASE + HW_APBH_CTRL0;
-		mask = chbit << BP_APBH_CTRL0_RESET_CHANNEL;
-		break;
-	case STMP3XXX_BUS_APBX:
-		c0 = REGS_APBX_BASE + HW_APBX_CHANNEL_CTRL;
-		mask = chbit << BP_APBX_CHANNEL_CTRL_RESET_CHANNEL;
-		break;
-	default:
-		return;
-	}
-
-	/* Reset channel and wait for it to complete */
-	stmp3xxx_setl(mask, c0);
-	while (__raw_readl(c0) & mask)
-		cpu_relax();
-}
-EXPORT_SYMBOL(stmp3xxx_arch_dma_reset_channel);
-
-void stmp3xxx_arch_dma_freeze(int channel)
-{
-	unsigned chbit = 1 << STMP3XXX_DMA_CHANNEL(channel);
-	u32 mask = 1 << chbit;
-
-	switch (STMP3XXX_DMA_BUS(channel)) {
-	case STMP3XXX_BUS_APBH:
-		stmp3xxx_setl(mask, REGS_APBH_BASE + HW_APBH_CTRL0);
-		break;
-	case STMP3XXX_BUS_APBX:
-		stmp3xxx_setl(mask, REGS_APBX_BASE + HW_APBX_CHANNEL_CTRL);
-		break;
-	}
-}
-EXPORT_SYMBOL(stmp3xxx_arch_dma_freeze);
-
-void stmp3xxx_arch_dma_unfreeze(int channel)
-{
-	unsigned chbit = 1 << STMP3XXX_DMA_CHANNEL(channel);
-	u32 mask = 1 << chbit;
-
-	switch (STMP3XXX_DMA_BUS(channel)) {
-	case STMP3XXX_BUS_APBH:
-		stmp3xxx_clearl(mask, REGS_APBH_BASE + HW_APBH_CTRL0);
-		break;
-	case STMP3XXX_BUS_APBX:
-		stmp3xxx_clearl(mask, REGS_APBX_BASE + HW_APBX_CHANNEL_CTRL);
-		break;
-	}
-}
-EXPORT_SYMBOL(stmp3xxx_arch_dma_unfreeze);
-
-/*
- * The registers are all very closely mapped, so we might as well map them all
- * with a single mapping
- *
- * Logical      Physical
- * f0000000	80000000	On-chip registers
- * f1000000	00000000	32k on-chip SRAM
- */
-
-static struct map_desc stmp378x_io_desc[] __initdata = {
-	{
-		.virtual	= (u32)STMP3XXX_REGS_BASE,
-		.pfn		= __phys_to_pfn(STMP3XXX_REGS_PHBASE),
-		.length		= STMP3XXX_REGS_SIZE,
-		.type		= MT_DEVICE,
-	},
-	{
-		.virtual	= (u32)STMP3XXX_OCRAM_BASE,
-		.pfn		= __phys_to_pfn(STMP3XXX_OCRAM_PHBASE),
-		.length		= STMP3XXX_OCRAM_SIZE,
-		.type		= MT_DEVICE,
-	},
-};
-
-
-static u64 common_dmamask = DMA_BIT_MASK(32);
-
-/*
- * devices that are present only on stmp378x, not on all 3xxx boards:
- * 	PxP
- * 	I2C
- */
-static struct resource pxp_resource[] = {
-	{
-		.flags	= IORESOURCE_MEM,
-		.start	= REGS_PXP_PHYS,
-		.end	= REGS_PXP_PHYS + REGS_PXP_SIZE,
-	}, {
-		.flags	= IORESOURCE_IRQ,
-		.start	= IRQ_PXP,
-		.end	= IRQ_PXP,
-	},
-};
-
-struct platform_device stmp378x_pxp = {
-	.name		= "stmp3xxx-pxp",
-	.id		= -1,
-	.dev		= {
-		.dma_mask		= &common_dmamask,
-		.coherent_dma_mask	= DMA_BIT_MASK(32),
-	},
-	.num_resources	= ARRAY_SIZE(pxp_resource),
-	.resource	= pxp_resource,
-};
-
-static struct resource i2c_resources[] = {
-	{
-		.flags = IORESOURCE_IRQ,
-		.start = IRQ_I2C_ERROR,
-		.end = IRQ_I2C_ERROR,
-	}, {
-		.flags = IORESOURCE_MEM,
-		.start = REGS_I2C_PHYS,
-		.end = REGS_I2C_PHYS + REGS_I2C_SIZE,
-	}, {
-		.flags = IORESOURCE_DMA,
-		.start = STMP3XXX_DMA(3, STMP3XXX_BUS_APBX),
-		.end = STMP3XXX_DMA(3, STMP3XXX_BUS_APBX),
-	},
-};
-
-struct platform_device stmp378x_i2c = {
-	.name = "i2c_stmp3xxx",
-	.id = 0,
-	.dev	= {
-		.dma_mask	= &common_dmamask,
-		.coherent_dma_mask = DMA_BIT_MASK(32),
-	},
-	.resource = i2c_resources,
-	.num_resources = ARRAY_SIZE(i2c_resources),
-};
-
-void __init stmp378x_map_io(void)
-{
-	iotable_init(stmp378x_io_desc, ARRAY_SIZE(stmp378x_io_desc));
-}
diff -druN linux-2.6.39-libre/arch/arm/mach-stmp378x/stmp378x_devb.c linux-3.0-rc7-libre/arch/arm/mach-stmp378x/stmp378x_devb.c
--- linux-2.6.39-libre/arch/arm/mach-stmp378x/stmp378x_devb.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-stmp378x/stmp378x_devb.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,332 +0,0 @@
-/*
- * Freescale STMP378X development board support
- *
- * Embedded Alley Solutions, Inc <source@embeddedalley.com>
- *
- * Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved.
- * Copyright 2008 Embedded Alley Solutions, 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/kernel.h>
-#include <linux/init.h>
-#include <linux/io.h>
-#include <linux/platform_device.h>
-#include <linux/delay.h>
-#include <linux/clk.h>
-#include <linux/err.h>
-#include <linux/spi/spi.h>
-
-#include <asm/setup.h>
-#include <asm/mach-types.h>
-#include <asm/mach/arch.h>
-
-#include <mach/pins.h>
-#include <mach/pinmux.h>
-#include <mach/platform.h>
-#include <mach/stmp3xxx.h>
-#include <mach/mmc.h>
-#include <mach/gpmi.h>
-
-#include "stmp378x.h"
-
-static struct platform_device *devices[] = {
-	&stmp3xxx_dbguart,
-	&stmp3xxx_appuart,
-	&stmp3xxx_watchdog,
-	&stmp3xxx_touchscreen,
-	&stmp3xxx_rtc,
-	&stmp3xxx_keyboard,
-	&stmp3xxx_framebuffer,
-	&stmp3xxx_backlight,
-	&stmp3xxx_rotdec,
-	&stmp3xxx_persistent,
-	&stmp3xxx_dcp_bootstream,
-	&stmp3xxx_dcp,
-	&stmp3xxx_battery,
-	&stmp378x_pxp,
-	&stmp378x_i2c,
-};
-
-static struct pin_desc i2c_pins_desc[] = {
-	{ PINID_I2C_SCL, PIN_FUN1, PIN_4MA, PIN_3_3V, 0 },
-	{ PINID_I2C_SDA, PIN_FUN1, PIN_4MA, PIN_3_3V, 0 },
-};
-
-static struct pin_group i2c_pins = {
-	.pins		= i2c_pins_desc,
-	.nr_pins	= ARRAY_SIZE(i2c_pins_desc),
-};
-
-static struct pin_desc dbguart_pins_0[] = {
-	{ PINID_PWM0, PIN_FUN3, },
-	{ PINID_PWM1, PIN_FUN3, },
-};
-
-static struct pin_group dbguart_pins[] = {
-	[0] = {
-		.pins		= dbguart_pins_0,
-		.nr_pins	= ARRAY_SIZE(dbguart_pins_0),
-	},
-};
-
-static int dbguart_pins_control(int id, int request)
-{
-	int r = 0;
-
-	if (request)
-		r = stmp3xxx_request_pin_group(&dbguart_pins[id], "debug uart");
-	else
-		stmp3xxx_release_pin_group(&dbguart_pins[id], "debug uart");
-	return r;
-}
-
-static struct pin_desc appuart_pins_0[] = {
-	{ PINID_AUART1_CTS, PIN_FUN1, PIN_4MA, PIN_1_8V, 0, },
-	{ PINID_AUART1_RTS, PIN_FUN1, PIN_4MA, PIN_1_8V, 0, },
-	{ PINID_AUART1_RX, PIN_FUN1, PIN_4MA, PIN_1_8V, 0, },
-	{ PINID_AUART1_TX, PIN_FUN1, PIN_4MA, PIN_1_8V, 0, },
-};
-
-static struct pin_desc appuart_pins_1[] = {
-#if 0 /* enable these when second appuart will be connected */
-	{ PINID_AUART2_CTS, PIN_FUN1, PIN_4MA, PIN_1_8V, 0, },
-	{ PINID_AUART2_RTS, PIN_FUN1, PIN_4MA, PIN_1_8V, 0, },
-	{ PINID_AUART2_RX, PIN_FUN1, PIN_4MA, PIN_1_8V, 0, },
-	{ PINID_AUART2_TX, PIN_FUN1, PIN_4MA, PIN_1_8V, 0, },
-#endif
-};
-
-static struct pin_desc mmc_pins_desc[] = {
-	{ PINID_SSP1_DATA0, PIN_FUN1, PIN_8MA, PIN_3_3V, 1 },
-	{ PINID_SSP1_DATA1, PIN_FUN1, PIN_8MA, PIN_3_3V, 1 },
-	{ PINID_SSP1_DATA2, PIN_FUN1, PIN_8MA, PIN_3_3V, 1 },
-	{ PINID_SSP1_DATA3, PIN_FUN1, PIN_8MA, PIN_3_3V, 1 },
-	{ PINID_SSP1_CMD, PIN_FUN1, PIN_8MA, PIN_3_3V, 1 },
-	{ PINID_SSP1_SCK, PIN_FUN1, PIN_8MA, PIN_3_3V, 0 },
-	{ PINID_SSP1_DETECT, PIN_FUN1, PIN_8MA, PIN_3_3V, 0 },
-};
-
-static struct pin_group mmc_pins = {
-	.pins		= mmc_pins_desc,
-	.nr_pins	= ARRAY_SIZE(mmc_pins_desc),
-};
-
-static int stmp3xxxmmc_get_wp(void)
-{
-	return gpio_get_value(PINID_PWM4);
-}
-
-static int stmp3xxxmmc_hw_init_ssp1(void)
-{
-	int ret;
-
-	ret = stmp3xxx_request_pin_group(&mmc_pins, "mmc");
-	if (ret)
-		goto out;
-
-	/* Configure write protect GPIO pin */
-	ret = gpio_request(PINID_PWM4, "mmc wp");
-	if (ret)
-		goto out_wp;
-
-	gpio_direction_input(PINID_PWM4);
-
-	/* Configure POWER pin as gpio to drive power to MMC slot */
-	ret = gpio_request(PINID_PWM3, "mmc power");
-	if (ret)
-		goto out_power;
-
-	gpio_direction_output(PINID_PWM3, 0);
-	mdelay(100);
-
-	return 0;
-
-out_power:
-	gpio_free(PINID_PWM4);
-out_wp:
-	stmp3xxx_release_pin_group(&mmc_pins, "mmc");
-out:
-	return ret;
-}
-
-static void stmp3xxxmmc_hw_release_ssp1(void)
-{
-	gpio_free(PINID_PWM3);
-	gpio_free(PINID_PWM4);
-	stmp3xxx_release_pin_group(&mmc_pins, "mmc");
-}
-
-static void stmp3xxxmmc_cmd_pullup_ssp1(int enable)
-{
-	stmp3xxx_pin_pullup(PINID_SSP1_CMD, enable, "mmc");
-}
-
-static unsigned long
-stmp3xxxmmc_setclock_ssp1(void __iomem *base, unsigned long hz)
-{
-	struct clk *ssp, *parent;
-	char *p;
-	long r;
-
-	ssp = clk_get(NULL, "ssp");
-
-	/* using SSP1, no timeout, clock rate 1 */
-	writel(BF(2, SSP_TIMING_CLOCK_DIVIDE) |
-	       BF(0xFFFF, SSP_TIMING_TIMEOUT),
-	       base + HW_SSP_TIMING);
-
-	p = (hz > 1000000) ? "io" : "osc_24M";
-	parent = clk_get(NULL, p);
-	clk_set_parent(ssp, parent);
-	r = clk_set_rate(ssp, 2 * hz / 1000);
-	clk_put(parent);
-	clk_put(ssp);
-
-	return hz;
-}
-
-static struct stmp3xxxmmc_platform_data mmc_data = {
-	.hw_init	= stmp3xxxmmc_hw_init_ssp1,
-	.hw_release	= stmp3xxxmmc_hw_release_ssp1,
-	.get_wp		= stmp3xxxmmc_get_wp,
-	.cmd_pullup	= stmp3xxxmmc_cmd_pullup_ssp1,
-	.setclock	= stmp3xxxmmc_setclock_ssp1,
-};
-
-
-static struct pin_group appuart_pins[] = {
-	[0] = {
-		.pins		= appuart_pins_0,
-		.nr_pins	= ARRAY_SIZE(appuart_pins_0),
-	},
-	[1] = {
-		.pins		= appuart_pins_1,
-		.nr_pins	= ARRAY_SIZE(appuart_pins_1),
-	},
-};
-
-static struct pin_desc ssp1_pins_desc[] = {
-	{ PINID_SSP1_SCK,	PIN_FUN1, PIN_8MA, PIN_3_3V, 0, },
-	{ PINID_SSP1_CMD,	PIN_FUN1, PIN_4MA, PIN_3_3V, 0, },
-	{ PINID_SSP1_DATA0,	PIN_FUN1, PIN_4MA, PIN_3_3V, 0, },
-	{ PINID_SSP1_DATA3,	PIN_FUN1, PIN_4MA, PIN_3_3V, 0, },
-};
-
-static struct pin_desc ssp2_pins_desc[] = {
-	{ PINID_GPMI_WRN,	PIN_FUN3, PIN_8MA, PIN_3_3V, 0, },
-	{ PINID_GPMI_RDY1,	PIN_FUN3, PIN_4MA, PIN_3_3V, 0, },
-	{ PINID_GPMI_D00,	PIN_FUN3, PIN_4MA, PIN_3_3V, 0, },
-	{ PINID_GPMI_D03,	PIN_FUN3, PIN_4MA, PIN_3_3V, 0, },
-};
-
-static struct pin_group ssp1_pins = {
-	.pins = ssp1_pins_desc,
-	.nr_pins = ARRAY_SIZE(ssp1_pins_desc),
-};
-
-static struct pin_group ssp2_pins = {
-	.pins = ssp1_pins_desc,
-	.nr_pins = ARRAY_SIZE(ssp2_pins_desc),
-};
-
-static struct pin_desc gpmi_pins_desc[] = {
-	{ PINID_GPMI_CE0N, PIN_FUN1, PIN_4MA, PIN_3_3V, 0 },
-	{ PINID_GPMI_CE1N, PIN_FUN1, PIN_4MA, PIN_3_3V, 0 },
-	{ PINID_GMPI_CE2N, PIN_FUN1, PIN_4MA, PIN_3_3V, 0 },
-	{ PINID_GPMI_CLE, PIN_FUN1, PIN_4MA, PIN_3_3V, 0 },
-	{ PINID_GPMI_ALE, PIN_FUN1, PIN_4MA, PIN_3_3V, 0 },
-	{ PINID_GPMI_WPN, PIN_FUN1, PIN_12MA, PIN_3_3V, 0 },
-	{ PINID_GPMI_RDY1, PIN_FUN1, PIN_4MA, PIN_3_3V, 0 },
-	{ PINID_GPMI_D00, PIN_FUN1, PIN_4MA, PIN_3_3V, 0 },
-	{ PINID_GPMI_D01, PIN_FUN1, PIN_4MA, PIN_3_3V, 0 },
-	{ PINID_GPMI_D02, PIN_FUN1, PIN_4MA, PIN_3_3V, 0 },
-	{ PINID_GPMI_D03, PIN_FUN1, PIN_4MA, PIN_3_3V, 0 },
-	{ PINID_GPMI_D04, PIN_FUN1, PIN_4MA, PIN_3_3V, 0 },
-	{ PINID_GPMI_D05, PIN_FUN1, PIN_4MA, PIN_3_3V, 0 },
-	{ PINID_GPMI_D06, PIN_FUN1, PIN_4MA, PIN_3_3V, 0 },
-	{ PINID_GPMI_D07, PIN_FUN1, PIN_4MA, PIN_3_3V, 0 },
-	{ PINID_GPMI_RDY0, PIN_FUN1, PIN_4MA, PIN_3_3V, 0 },
-	{ PINID_GPMI_RDY2, PIN_FUN1, PIN_4MA, PIN_3_3V, 0 },
-	{ PINID_GPMI_RDY3, PIN_FUN1, PIN_4MA, PIN_3_3V, 0 },
-	{ PINID_GPMI_WRN, PIN_FUN1, PIN_12MA, PIN_3_3V, 0 },
-	{ PINID_GPMI_RDN, PIN_FUN1, PIN_12MA, PIN_3_3V, 0 },
-};
-
-static struct pin_group gpmi_pins = {
-	.pins		= gpmi_pins_desc,
-	.nr_pins	= ARRAY_SIZE(gpmi_pins_desc),
-};
-
-static struct mtd_partition gpmi_partitions[] = {
-	[0] = {
-		.name	= "boot",
-		.size	= 10 * SZ_1M,
-		.offset	= 0,
-	},
-	[1] = {
-		.name	= "data",
-		.size	= MTDPART_SIZ_FULL,
-		.offset	= MTDPART_OFS_APPEND,
-	},
-};
-
-static struct gpmi_platform_data gpmi_data = {
-	.pins = &gpmi_pins,
-	.nr_parts = ARRAY_SIZE(gpmi_partitions),
-	.parts = gpmi_partitions,
-	.part_types = { "cmdline", NULL },
-};
-
-static struct spi_board_info spi_board_info[] __initdata = {
-#if defined(CONFIG_ENC28J60) || defined(CONFIG_ENC28J60_MODULE)
-	{
-		.modalias       = "enc28j60",
-		.max_speed_hz   = 6 * 1000 * 1000,
-		.bus_num	= 1,
-		.chip_select    = 0,
-		.platform_data  = NULL,
-	},
-#endif
-};
-
-static void __init stmp378x_devb_init(void)
-{
-	stmp3xxx_pinmux_init(NR_REAL_IRQS);
-
-	/* init stmp3xxx platform */
-	stmp3xxx_init();
-
-	stmp3xxx_dbguart.dev.platform_data = dbguart_pins_control;
-	stmp3xxx_appuart.dev.platform_data = appuart_pins;
-	stmp3xxx_mmc.dev.platform_data = &mmc_data;
-	stmp3xxx_gpmi.dev.platform_data = &gpmi_data;
-	stmp3xxx_spi1.dev.platform_data = &ssp1_pins;
-	stmp3xxx_spi2.dev.platform_data = &ssp2_pins;
-	stmp378x_i2c.dev.platform_data = &i2c_pins;
-
-	/* register spi devices */
-	spi_register_board_info(spi_board_info, ARRAY_SIZE(spi_board_info));
-
-	/* add board's devices */
-	platform_add_devices(devices, ARRAY_SIZE(devices));
-
-	/* add devices selected by command line ssp1= and ssp2= options */
-	stmp3xxx_ssp1_device_register();
-	stmp3xxx_ssp2_device_register();
-}
-
-MACHINE_START(STMP378X, "STMP378X")
-	.boot_params	= 0x40000100,
-	.map_io		= stmp378x_map_io,
-	.init_irq	= stmp378x_init_irq,
-	.timer		= &stmp3xxx_timer,
-	.init_machine	= stmp378x_devb_init,
-MACHINE_END
diff -druN linux-2.6.39-libre/arch/arm/mach-stmp378x/stmp378x.h linux-3.0-rc7-libre/arch/arm/mach-stmp378x/stmp378x.h
--- linux-2.6.39-libre/arch/arm/mach-stmp378x/stmp378x.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-stmp378x/stmp378x.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,25 +0,0 @@
-/*
- * Freescale STMP37XX/STMP378X internal functions and data declarations
- *
- * Embedded Alley Solutions, Inc <source@embeddedalley.com>
- *
- * Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved.
- * Copyright 2008 Embedded Alley Solutions, 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 __MACH_STMP378X_H
-#define __MACH_STMP378X_H
-
-void stmp378x_map_io(void);
-void stmp378x_init_irq(void);
-
-extern struct platform_device stmp378x_pxp, stmp378x_i2c;
-#endif /* __MACH_STMP378X_COMMON_H */
diff -druN linux-2.6.39-libre/arch/arm/mach-stmp37xx/include/mach/entry-macro.S linux-3.0-rc7-libre/arch/arm/mach-stmp37xx/include/mach/entry-macro.S
--- linux-2.6.39-libre/arch/arm/mach-stmp37xx/include/mach/entry-macro.S	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-stmp37xx/include/mach/entry-macro.S	1969-12-31 19:00:00.000000000 -0500
@@ -1,37 +0,0 @@
-/*
- * Low-level IRQ helper macros for Freescale STMP37XX
- *
- * Embedded Alley Solutions, Inc <source@embeddedalley.com>
- *
- * Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved.
- * Copyright 2008 Embedded Alley Solutions, 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
- */
-
-		.macro	disable_fiq
-		.endm
-
-		.macro	get_irqnr_and_base, irqnr, irqstat, base, tmp
-
-	        mov	\base, #0xf0000000	@ vm address of IRQ controller
-		ldr	\irqnr, [\base, #0x30]	@ HW_ICOLL_STAT
-		cmp	\irqnr, #0x3f
-		movne	\irqstat, #0		@ Ack this IRQ
-		strne	\irqstat, [\base, #0x00]@ HW_ICOLL_VECTOR
-		moveqs	\irqnr, #0		@ Zero flag set for no IRQ
-
-		.endm
-
-                .macro  get_irqnr_preamble, base, tmp
-                .endm
-
-                .macro  arch_ret_to_user, tmp1, tmp2
-                .endm
diff -druN linux-2.6.39-libre/arch/arm/mach-stmp37xx/include/mach/irqs.h linux-3.0-rc7-libre/arch/arm/mach-stmp37xx/include/mach/irqs.h
--- linux-2.6.39-libre/arch/arm/mach-stmp37xx/include/mach/irqs.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-stmp37xx/include/mach/irqs.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,99 +0,0 @@
-/*
- * Freescale STMP37XX interrupts
- *
- * Copyright (C) 2005 Sigmatel Inc
- *
- * Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved.
- * Copyright 2008 Embedded Alley Solutions, 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 _ASM_ARCH_IRQS_H
-#define _ASM_ARCH_IRQS_H
-
-#define IRQ_DEBUG_UART	         0
-#define IRQ_COMMS_RX	           1
-#define IRQ_COMMS_TX	           1
-#define IRQ_SSP2_ERROR	         2
-#define IRQ_VDD5V	              3
-#define IRQ_HEADPHONE_SHORT	    4
-#define IRQ_DAC_DMA	            5
-#define IRQ_DAC_ERROR	          6
-#define IRQ_ADC_DMA	            7
-#define IRQ_ADC_ERROR	          8
-#define IRQ_SPDIF_DMA	          9
-#define IRQ_SAIF2_DMA	          9
-#define IRQ_SPDIF_ERROR	        10
-#define IRQ_SAIF1_IRQ	          10
-#define IRQ_SAIF2_IRQ	          10
-#define IRQ_USB_CTRL	           11
-#define IRQ_USB_WAKEUP	         12
-#define IRQ_GPMI_DMA	           13
-#define IRQ_SSP1_DMA	           14
-#define IRQ_SSP_ERROR	          15
-#define IRQ_GPIO0	              16
-#define IRQ_GPIO1	              17
-#define IRQ_GPIO2	              18
-#define IRQ_SAIF1_DMA	          19
-#define IRQ_SSP2_DMA	           20
-#define IRQ_ECC8_IRQ	           21
-#define IRQ_RTC_ALARM	          22
-#define IRQ_UARTAPP_TX_DMA	     23
-#define IRQ_UARTAPP_INTERNAL	   24
-#define IRQ_UARTAPP_RX_DMA	     25
-#define IRQ_I2C_DMA	            26
-#define IRQ_I2C_ERROR	          27
-#define IRQ_TIMER0	             28
-#define IRQ_TIMER1	             29
-#define IRQ_TIMER2	             30
-#define IRQ_TIMER3	             31
-#define IRQ_BATT_BRNOUT	        32
-#define IRQ_VDDD_BRNOUT	        33
-#define IRQ_VDDIO_BRNOUT	       34
-#define IRQ_VDD18_BRNOUT	       35
-#define IRQ_TOUCH_DETECT	       36
-#define IRQ_LRADC_CH0	          37
-#define IRQ_LRADC_CH1	          38
-#define IRQ_LRADC_CH2	          39
-#define IRQ_LRADC_CH3	          40
-#define IRQ_LRADC_CH4	          41
-#define IRQ_LRADC_CH5	          42
-#define IRQ_LRADC_CH6	          43
-#define IRQ_LRADC_CH7	          44
-#define IRQ_LCDIF_DMA	          45
-#define IRQ_LCDIF_ERROR	        46
-#define IRQ_DIGCTL_DEBUG_TRAP	  47
-#define IRQ_RTC_1MSEC	          48
-#define IRQ_DRI_DMA	            49
-#define IRQ_DRI_ATTENTION	      50
-#define IRQ_GPMI_ATTENTION	     51
-#define IRQ_IR	                 52
-#define IRQ_DCP_VMI	            53
-#define IRQ_DCP	                54
-#define IRQ_RESERVED_55	        55
-#define IRQ_RESERVED_56	        56
-#define IRQ_RESERVED_57	        57
-#define IRQ_RESERVED_58	        58
-#define IRQ_RESERVED_59	        59
-#define SW_IRQ_60	              60
-#define SW_IRQ_61	              61
-#define SW_IRQ_62	              62
-#define SW_IRQ_63	              63
-
-#define NR_REAL_IRQS		64
-#define NR_IRQS			(NR_REAL_IRQS + 32 * 3)
-
-/* TIMER and BRNOUT are FIQ capable */
-#define FIQ_START			IRQ_TIMER0
-
-/* Hard disk IRQ is a GPMI attention IRQ */
-#define IRQ_HARDDISK		IRQ_GPMI_ATTENTION
-
-#endif /* _ASM_ARCH_IRQS_H */
diff -druN linux-2.6.39-libre/arch/arm/mach-stmp37xx/include/mach/pins.h linux-3.0-rc7-libre/arch/arm/mach-stmp37xx/include/mach/pins.h
--- linux-2.6.39-libre/arch/arm/mach-stmp37xx/include/mach/pins.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-stmp37xx/include/mach/pins.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,147 +0,0 @@
-/*
- * Freescale STMP37XX SoC pin multiplexing
- *
- * Author: Vladislav Buzov <vbuzov@embeddedalley.com>
- *
- * Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved.
- * Copyright 2008 Embedded Alley Solutions, 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 __ASM_ARCH_PINS_H
-#define __ASM_ARCH_PINS_H
-
-/*
- * Define all STMP37XX pins, a pin name corresponds to a STMP37xx hardware
- * interface  this pin belongs to.
- */
-
-/* Bank 0 */
-#define PINID_GPMI_D00		STMP3XXX_PINID(0, 0)
-#define PINID_GPMI_D01		STMP3XXX_PINID(0, 1)
-#define PINID_GPMI_D02		STMP3XXX_PINID(0, 2)
-#define PINID_GPMI_D03		STMP3XXX_PINID(0, 3)
-#define PINID_GPMI_D04		STMP3XXX_PINID(0, 4)
-#define PINID_GPMI_D05		STMP3XXX_PINID(0, 5)
-#define PINID_GPMI_D06		STMP3XXX_PINID(0, 6)
-#define PINID_GPMI_D07		STMP3XXX_PINID(0, 7)
-#define PINID_GPMI_D08		STMP3XXX_PINID(0, 8)
-#define PINID_GPMI_D09		STMP3XXX_PINID(0, 9)
-#define PINID_GPMI_D10		STMP3XXX_PINID(0, 10)
-#define PINID_GPMI_D11		STMP3XXX_PINID(0, 11)
-#define PINID_GPMI_D12		STMP3XXX_PINID(0, 12)
-#define PINID_GPMI_D13		STMP3XXX_PINID(0, 13)
-#define PINID_GPMI_D14		STMP3XXX_PINID(0, 14)
-#define PINID_GPMI_D15		STMP3XXX_PINID(0, 15)
-#define PINID_GPMI_A0		STMP3XXX_PINID(0, 16)
-#define PINID_GPMI_A1		STMP3XXX_PINID(0, 17)
-#define PINID_GPMI_A2		STMP3XXX_PINID(0, 18)
-#define PINID_GPMI_RDY0		STMP3XXX_PINID(0, 19)
-#define PINID_GPMI_RDY2		STMP3XXX_PINID(0, 20)
-#define PINID_GPMI_RDY3		STMP3XXX_PINID(0, 21)
-#define PINID_GPMI_RESETN	STMP3XXX_PINID(0, 22)
-#define PINID_GPMI_IRQ		STMP3XXX_PINID(0, 23)
-#define PINID_GPMI_WRN		STMP3XXX_PINID(0, 24)
-#define PINID_GPMI_RDN		STMP3XXX_PINID(0, 25)
-#define PINID_UART2_CTS		STMP3XXX_PINID(0, 26)
-#define PINID_UART2_RTS		STMP3XXX_PINID(0, 27)
-#define PINID_UART2_RX		STMP3XXX_PINID(0, 28)
-#define PINID_UART2_TX		STMP3XXX_PINID(0, 29)
-
-/* Bank 1 */
-#define PINID_LCD_D00		STMP3XXX_PINID(1, 0)
-#define PINID_LCD_D01		STMP3XXX_PINID(1, 1)
-#define PINID_LCD_D02		STMP3XXX_PINID(1, 2)
-#define PINID_LCD_D03		STMP3XXX_PINID(1, 3)
-#define PINID_LCD_D04		STMP3XXX_PINID(1, 4)
-#define PINID_LCD_D05		STMP3XXX_PINID(1, 5)
-#define PINID_LCD_D06		STMP3XXX_PINID(1, 6)
-#define PINID_LCD_D07		STMP3XXX_PINID(1, 7)
-#define PINID_LCD_D08		STMP3XXX_PINID(1, 8)
-#define PINID_LCD_D09		STMP3XXX_PINID(1, 9)
-#define PINID_LCD_D10		STMP3XXX_PINID(1, 10)
-#define PINID_LCD_D11		STMP3XXX_PINID(1, 11)
-#define PINID_LCD_D12		STMP3XXX_PINID(1, 12)
-#define PINID_LCD_D13		STMP3XXX_PINID(1, 13)
-#define PINID_LCD_D14		STMP3XXX_PINID(1, 14)
-#define PINID_LCD_D15		STMP3XXX_PINID(1, 15)
-#define PINID_LCD_RESET 	STMP3XXX_PINID(1, 16)
-#define PINID_LCD_RS		STMP3XXX_PINID(1, 17)
-#define PINID_LCD_WR_RWN	STMP3XXX_PINID(1, 18)
-#define PINID_LCD_RD_E		STMP3XXX_PINID(1, 19)
-#define PINID_LCD_CS		STMP3XXX_PINID(1, 20)
-#define PINID_LCD_BUSY		STMP3XXX_PINID(1, 21)
-#define PINID_SSP1_CMD		STMP3XXX_PINID(1, 22)
-#define PINID_SSP1_SCK		STMP3XXX_PINID(1, 23)
-#define PINID_SSP1_DATA0	STMP3XXX_PINID(1, 24)
-#define PINID_SSP1_DATA1	STMP3XXX_PINID(1, 25)
-#define PINID_SSP1_DATA2	STMP3XXX_PINID(1, 26)
-#define PINID_SSP1_DATA3	STMP3XXX_PINID(1, 27)
-#define PINID_SSP1_DETECT	STMP3XXX_PINID(1, 28)
-
-/* Bank 2 */
-#define PINID_PWM0		STMP3XXX_PINID(2, 0)
-#define PINID_PWM1		STMP3XXX_PINID(2, 1)
-#define PINID_PWM2		STMP3XXX_PINID(2, 2)
-#define PINID_PWM3		STMP3XXX_PINID(2, 3)
-#define PINID_PWM4		STMP3XXX_PINID(2, 4)
-#define PINID_I2C_SCL		STMP3XXX_PINID(2, 5)
-#define PINID_I2C_SDA		STMP3XXX_PINID(2, 6)
-#define PINID_ROTTARYA		STMP3XXX_PINID(2, 7)
-#define PINID_ROTTARYB		STMP3XXX_PINID(2, 8)
-#define PINID_EMI_CKE		STMP3XXX_PINID(2, 9)
-#define PINID_EMI_RASN		STMP3XXX_PINID(2, 10)
-#define PINID_EMI_CASN		STMP3XXX_PINID(2, 11)
-#define PINID_EMI_CE0N		STMP3XXX_PINID(2, 12)
-#define PINID_EMI_CE1N		STMP3XXX_PINID(2, 13)
-#define PINID_EMI_CE2N		STMP3XXX_PINID(2, 14)
-#define PINID_EMI_CE3N		STMP3XXX_PINID(2, 15)
-#define PINID_EMI_A00		STMP3XXX_PINID(2, 16)
-#define PINID_EMI_A01		STMP3XXX_PINID(2, 17)
-#define PINID_EMI_A02		STMP3XXX_PINID(2, 18)
-#define PINID_EMI_A03		STMP3XXX_PINID(2, 19)
-#define PINID_EMI_A04		STMP3XXX_PINID(2, 20)
-#define PINID_EMI_A05		STMP3XXX_PINID(2, 21)
-#define PINID_EMI_A06		STMP3XXX_PINID(2, 22)
-#define PINID_EMI_A07		STMP3XXX_PINID(2, 23)
-#define PINID_EMI_A08		STMP3XXX_PINID(2, 24)
-#define PINID_EMI_A09		STMP3XXX_PINID(2, 25)
-#define PINID_EMI_A10		STMP3XXX_PINID(2, 26)
-#define PINID_EMI_A11		STMP3XXX_PINID(2, 27)
-#define PINID_EMI_A12		STMP3XXX_PINID(2, 28)
-#define PINID_EMI_A13		STMP3XXX_PINID(2, 29)
-#define PINID_EMI_A14		STMP3XXX_PINID(2, 30)
-#define PINID_EMI_WEN		STMP3XXX_PINID(2, 31)
-
-/* Bank 3 */
-#define PINID_EMI_D00		STMP3XXX_PINID(3, 0)
-#define PINID_EMI_D01		STMP3XXX_PINID(3, 1)
-#define PINID_EMI_D02		STMP3XXX_PINID(3, 2)
-#define PINID_EMI_D03		STMP3XXX_PINID(3, 3)
-#define PINID_EMI_D04		STMP3XXX_PINID(3, 4)
-#define PINID_EMI_D05		STMP3XXX_PINID(3, 5)
-#define PINID_EMI_D06		STMP3XXX_PINID(3, 6)
-#define PINID_EMI_D07		STMP3XXX_PINID(3, 7)
-#define PINID_EMI_D08		STMP3XXX_PINID(3, 8)
-#define PINID_EMI_D09		STMP3XXX_PINID(3, 9)
-#define PINID_EMI_D10		STMP3XXX_PINID(3, 10)
-#define PINID_EMI_D11		STMP3XXX_PINID(3, 11)
-#define PINID_EMI_D12		STMP3XXX_PINID(3, 12)
-#define PINID_EMI_D13		STMP3XXX_PINID(3, 13)
-#define PINID_EMI_D14		STMP3XXX_PINID(3, 14)
-#define PINID_EMI_D15		STMP3XXX_PINID(3, 15)
-#define PINID_EMI_DQS0		STMP3XXX_PINID(3, 16)
-#define PINID_EMI_DQS1		STMP3XXX_PINID(3, 17)
-#define PINID_EMI_DQM0		STMP3XXX_PINID(3, 18)
-#define PINID_EMI_DQM1		STMP3XXX_PINID(3, 19)
-#define PINID_EMI_CLK		STMP3XXX_PINID(3, 20)
-#define PINID_EMI_CLKN		STMP3XXX_PINID(3, 21)
-
-#endif /* __ASM_ARCH_PINS_H */
diff -druN linux-2.6.39-libre/arch/arm/mach-stmp37xx/include/mach/regs-apbh.h linux-3.0-rc7-libre/arch/arm/mach-stmp37xx/include/mach/regs-apbh.h
--- linux-2.6.39-libre/arch/arm/mach-stmp37xx/include/mach/regs-apbh.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-stmp37xx/include/mach/regs-apbh.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,97 +0,0 @@
-/*
- * stmp37xx: APBH register definitions
- *
- * Copyright (c) 2008 Freescale Semiconductor
- * Copyright 2008 Embedded Alley Solutions, 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
- */
-#ifndef _MACH_REGS_APBH
-#define _MACH_REGS_APBH
-
-#define REGS_APBH_BASE	(STMP3XXX_REGS_BASE + 0x4000)
-
-#define HW_APBH_CTRL0		0x0
-#define BM_APBH_CTRL0_RESET_CHANNEL	0x00FF0000
-#define BP_APBH_CTRL0_RESET_CHANNEL	16
-#define BM_APBH_CTRL0_CLKGATE	0x40000000
-#define BM_APBH_CTRL0_SFTRST	0x80000000
-
-#define HW_APBH_CTRL1		0x10
-#define BM_APBH_CTRL1_CH0_CMDCMPLT_IRQ	0x00000001
-#define BP_APBH_CTRL1_CH0_CMDCMPLT_IRQ	0
-
-#define HW_APBH_DEVSEL		0x20
-
-#define HW_APBH_CH0_NXTCMDAR	(0x50 + 0 * 0x70)
-#define HW_APBH_CH1_NXTCMDAR	(0x50 + 1 * 0x70)
-#define HW_APBH_CH2_NXTCMDAR	(0x50 + 2 * 0x70)
-#define HW_APBH_CH3_NXTCMDAR	(0x50 + 3 * 0x70)
-#define HW_APBH_CH4_NXTCMDAR	(0x50 + 4 * 0x70)
-#define HW_APBH_CH5_NXTCMDAR	(0x50 + 5 * 0x70)
-#define HW_APBH_CH6_NXTCMDAR	(0x50 + 6 * 0x70)
-#define HW_APBH_CH7_NXTCMDAR	(0x50 + 7 * 0x70)
-#define HW_APBH_CH8_NXTCMDAR	(0x50 + 8 * 0x70)
-#define HW_APBH_CH9_NXTCMDAR	(0x50 + 9 * 0x70)
-#define HW_APBH_CH10_NXTCMDAR	(0x50 + 10 * 0x70)
-#define HW_APBH_CH11_NXTCMDAR	(0x50 + 11 * 0x70)
-#define HW_APBH_CH12_NXTCMDAR	(0x50 + 12 * 0x70)
-#define HW_APBH_CH13_NXTCMDAR	(0x50 + 13 * 0x70)
-#define HW_APBH_CH14_NXTCMDAR	(0x50 + 14 * 0x70)
-#define HW_APBH_CH15_NXTCMDAR	(0x50 + 15 * 0x70)
-
-#define HW_APBH_CHn_NXTCMDAR	0x50
-
-#define BM_APBH_CHn_CMD_MODE		0x00000003
-#define BP_APBH_CHn_CMD_MODE		0x00000001
-#define BV_APBH_CHn_CMD_MODE_NOOP		 0
-#define BV_APBH_CHn_CMD_MODE_WRITE		 1
-#define BV_APBH_CHn_CMD_MODE_READ		 2
-#define BV_APBH_CHn_CMD_MODE_SENSE		 3
-#define BM_APBH_CHn_CMD_CHAIN		0x00000004
-#define BM_APBH_CHn_CMD_IRQONCMPLT	0x00000008
-#define BM_APBH_CHn_CMD_NANDLOCK	0x00000010
-#define BM_APBH_CHn_CMD_NANDWAIT4READY	0x00000020
-#define BM_APBH_CHn_CMD_SEMAPHORE	0x00000040
-#define BM_APBH_CHn_CMD_WAIT4ENDCMD	0x00000080
-#define BM_APBH_CHn_CMD_CMDWORDS	0x0000F000
-#define BP_APBH_CHn_CMD_CMDWORDS	12
-#define BM_APBH_CHn_CMD_XFER_COUNT	0xFFFF0000
-#define BP_APBH_CHn_CMD_XFER_COUNT	16
-
-#define HW_APBH_CH0_SEMA	(0x80 + 0 * 0x70)
-#define HW_APBH_CH1_SEMA	(0x80 + 1 * 0x70)
-#define HW_APBH_CH2_SEMA	(0x80 + 2 * 0x70)
-#define HW_APBH_CH3_SEMA	(0x80 + 3 * 0x70)
-#define HW_APBH_CH4_SEMA	(0x80 + 4 * 0x70)
-#define HW_APBH_CH5_SEMA	(0x80 + 5 * 0x70)
-#define HW_APBH_CH6_SEMA	(0x80 + 6 * 0x70)
-#define HW_APBH_CH7_SEMA	(0x80 + 7 * 0x70)
-#define HW_APBH_CH8_SEMA	(0x80 + 8 * 0x70)
-#define HW_APBH_CH9_SEMA	(0x80 + 9 * 0x70)
-#define HW_APBH_CH10_SEMA	(0x80 + 10 * 0x70)
-#define HW_APBH_CH11_SEMA	(0x80 + 11 * 0x70)
-#define HW_APBH_CH12_SEMA	(0x80 + 12 * 0x70)
-#define HW_APBH_CH13_SEMA	(0x80 + 13 * 0x70)
-#define HW_APBH_CH14_SEMA	(0x80 + 14 * 0x70)
-#define HW_APBH_CH15_SEMA	(0x80 + 15 * 0x70)
-
-#define HW_APBH_CHn_SEMA	0x80
-#define BM_APBH_CHn_SEMA_INCREMENT_SEMA	0x000000FF
-#define BP_APBH_CHn_SEMA_INCREMENT_SEMA	0
-#define BM_APBH_CHn_SEMA_PHORE	0x00FF0000
-#define BP_APBH_CHn_SEMA_PHORE	16
-
-#endif
diff -druN linux-2.6.39-libre/arch/arm/mach-stmp37xx/include/mach/regs-apbx.h linux-3.0-rc7-libre/arch/arm/mach-stmp37xx/include/mach/regs-apbx.h
--- linux-2.6.39-libre/arch/arm/mach-stmp37xx/include/mach/regs-apbx.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-stmp37xx/include/mach/regs-apbx.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,113 +0,0 @@
-/*
- * stmp37xx: APBX register definitions
- *
- * Copyright (c) 2008 Freescale Semiconductor
- * Copyright 2008 Embedded Alley Solutions, 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
- */
-#ifndef _MACH_REGS_APBX
-#define _MACH_REGS_APBX
-
-#define REGS_APBX_BASE	(STMP3XXX_REGS_BASE + 0x24000)
-
-#define HW_APBX_CTRL0		0x0
-#define BM_APBX_CTRL0_RESET_CHANNEL	0x00FF0000
-#define BP_APBX_CTRL0_RESET_CHANNEL	16
-#define BM_APBX_CTRL0_CLKGATE	0x40000000
-#define BM_APBX_CTRL0_SFTRST	0x80000000
-
-#define HW_APBX_CTRL1		0x10
-
-#define HW_APBX_DEVSEL		0x20
-
-#define HW_APBX_CH0_NXTCMDAR	(0x50 + 0 * 0x70)
-#define HW_APBX_CH1_NXTCMDAR	(0x50 + 1 * 0x70)
-#define HW_APBX_CH2_NXTCMDAR	(0x50 + 2 * 0x70)
-#define HW_APBX_CH3_NXTCMDAR	(0x50 + 3 * 0x70)
-#define HW_APBX_CH4_NXTCMDAR	(0x50 + 4 * 0x70)
-#define HW_APBX_CH5_NXTCMDAR	(0x50 + 5 * 0x70)
-#define HW_APBX_CH6_NXTCMDAR	(0x50 + 6 * 0x70)
-#define HW_APBX_CH7_NXTCMDAR	(0x50 + 7 * 0x70)
-#define HW_APBX_CH8_NXTCMDAR	(0x50 + 8 * 0x70)
-#define HW_APBX_CH9_NXTCMDAR	(0x50 + 9 * 0x70)
-#define HW_APBX_CH10_NXTCMDAR	(0x50 + 10 * 0x70)
-#define HW_APBX_CH11_NXTCMDAR	(0x50 + 11 * 0x70)
-#define HW_APBX_CH12_NXTCMDAR	(0x50 + 12 * 0x70)
-#define HW_APBX_CH13_NXTCMDAR	(0x50 + 13 * 0x70)
-#define HW_APBX_CH14_NXTCMDAR	(0x50 + 14 * 0x70)
-#define HW_APBX_CH15_NXTCMDAR	(0x50 + 15 * 0x70)
-
-#define HW_APBX_CHn_NXTCMDAR	0x50
-#define BM_APBX_CHn_CMD_MODE		0x00000003
-#define BP_APBX_CHn_CMD_MODE		0x00000001
-#define BV_APBX_CHn_CMD_MODE_NOOP		 0
-#define BV_APBX_CHn_CMD_MODE_WRITE		 1
-#define BV_APBX_CHn_CMD_MODE_READ		 2
-#define BV_APBX_CHn_CMD_MODE_SENSE		 3
-#define BM_APBX_CHn_CMD_COMMAND	0x00000003
-#define BP_APBX_CHn_CMD_COMMAND	0
-#define BM_APBX_CHn_CMD_CHAIN	0x00000004
-#define BM_APBX_CHn_CMD_IRQONCMPLT	0x00000008
-#define BM_APBX_CHn_CMD_SEMAPHORE	0x00000040
-#define BM_APBX_CHn_CMD_WAIT4ENDCMD	0x00000080
-#define BM_APBX_CHn_CMD_CMDWORDS	0x0000F000
-#define BP_APBX_CHn_CMD_CMDWORDS	12
-#define BM_APBX_CHn_CMD_XFER_COUNT	0xFFFF0000
-#define BP_APBX_CHn_CMD_XFER_COUNT	16
-
-#define HW_APBX_CH0_BAR		(0x70 + 0 * 0x70)
-#define HW_APBX_CH1_BAR		(0x70 + 1 * 0x70)
-#define HW_APBX_CH2_BAR		(0x70 + 2 * 0x70)
-#define HW_APBX_CH3_BAR		(0x70 + 3 * 0x70)
-#define HW_APBX_CH4_BAR		(0x70 + 4 * 0x70)
-#define HW_APBX_CH5_BAR		(0x70 + 5 * 0x70)
-#define HW_APBX_CH6_BAR		(0x70 + 6 * 0x70)
-#define HW_APBX_CH7_BAR		(0x70 + 7 * 0x70)
-#define HW_APBX_CH8_BAR		(0x70 + 8 * 0x70)
-#define HW_APBX_CH9_BAR		(0x70 + 9 * 0x70)
-#define HW_APBX_CH10_BAR		(0x70 + 10 * 0x70)
-#define HW_APBX_CH11_BAR		(0x70 + 11 * 0x70)
-#define HW_APBX_CH12_BAR		(0x70 + 12 * 0x70)
-#define HW_APBX_CH13_BAR		(0x70 + 13 * 0x70)
-#define HW_APBX_CH14_BAR		(0x70 + 14 * 0x70)
-#define HW_APBX_CH15_BAR		(0x70 + 15 * 0x70)
-
-#define HW_APBX_CHn_BAR		0x70
-
-#define HW_APBX_CH0_SEMA	(0x80 + 0 * 0x70)
-#define HW_APBX_CH1_SEMA	(0x80 + 1 * 0x70)
-#define HW_APBX_CH2_SEMA	(0x80 + 2 * 0x70)
-#define HW_APBX_CH3_SEMA	(0x80 + 3 * 0x70)
-#define HW_APBX_CH4_SEMA	(0x80 + 4 * 0x70)
-#define HW_APBX_CH5_SEMA	(0x80 + 5 * 0x70)
-#define HW_APBX_CH6_SEMA	(0x80 + 6 * 0x70)
-#define HW_APBX_CH7_SEMA	(0x80 + 7 * 0x70)
-#define HW_APBX_CH8_SEMA	(0x80 + 8 * 0x70)
-#define HW_APBX_CH9_SEMA	(0x80 + 9 * 0x70)
-#define HW_APBX_CH10_SEMA	(0x80 + 10 * 0x70)
-#define HW_APBX_CH11_SEMA	(0x80 + 11 * 0x70)
-#define HW_APBX_CH12_SEMA	(0x80 + 12 * 0x70)
-#define HW_APBX_CH13_SEMA	(0x80 + 13 * 0x70)
-#define HW_APBX_CH14_SEMA	(0x80 + 14 * 0x70)
-#define HW_APBX_CH15_SEMA	(0x80 + 15 * 0x70)
-
-#define HW_APBX_CHn_SEMA	0x80
-#define BM_APBX_CHn_SEMA_INCREMENT_SEMA	0x000000FF
-#define BP_APBX_CHn_SEMA_INCREMENT_SEMA	0
-#define BM_APBX_CHn_SEMA_PHORE	0x00FF0000
-#define BP_APBX_CHn_SEMA_PHORE	16
-
-#endif
diff -druN linux-2.6.39-libre/arch/arm/mach-stmp37xx/include/mach/regs-audioin.h linux-3.0-rc7-libre/arch/arm/mach-stmp37xx/include/mach/regs-audioin.h
--- linux-2.6.39-libre/arch/arm/mach-stmp37xx/include/mach/regs-audioin.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-stmp37xx/include/mach/regs-audioin.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,61 +0,0 @@
-/*
- * stmp37xx: AUDIOIN register definitions
- *
- * Copyright (c) 2008 Freescale Semiconductor
- * Copyright 2008 Embedded Alley Solutions, 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
- */
-#define REGS_AUDIOIN_BASE	(STMP3XXX_REGS_BASE + 0x4C000)
-
-#define HW_AUDIOIN_CTRL		0x0
-#define BM_AUDIOIN_CTRL_RUN	0x00000001
-#define BP_AUDIOIN_CTRL_RUN	0
-#define BM_AUDIOIN_CTRL_FIFO_ERROR_IRQ_EN	0x00000002
-#define BM_AUDIOIN_CTRL_FIFO_OVERFLOW_IRQ	0x00000004
-#define BM_AUDIOIN_CTRL_FIFO_UNDERFLOW_IRQ	0x00000008
-#define BM_AUDIOIN_CTRL_WORD_LENGTH	0x00000020
-#define BM_AUDIOIN_CTRL_CLKGATE	0x40000000
-#define BM_AUDIOIN_CTRL_SFTRST	0x80000000
-
-#define HW_AUDIOIN_STAT		0x10
-
-#define HW_AUDIOIN_ADCSRR	0x20
-
-#define HW_AUDIOIN_ADCVOLUME	0x30
-#define BM_AUDIOIN_ADCVOLUME_VOLUME_RIGHT	0x000000FF
-#define BP_AUDIOIN_ADCVOLUME_VOLUME_RIGHT	0
-#define BM_AUDIOIN_ADCVOLUME_VOLUME_LEFT	0x00FF0000
-#define BP_AUDIOIN_ADCVOLUME_VOLUME_LEFT	16
-
-#define HW_AUDIOIN_ADCDEBUG	0x40
-
-#define HW_AUDIOIN_ADCVOL	0x50
-#define BM_AUDIOIN_ADCVOL_GAIN_RIGHT	0x0000000F
-#define BP_AUDIOIN_ADCVOL_GAIN_RIGHT	0
-#define BM_AUDIOIN_ADCVOL_SELECT_RIGHT	0x00000030
-#define BP_AUDIOIN_ADCVOL_SELECT_RIGHT	4
-#define BM_AUDIOIN_ADCVOL_GAIN_LEFT	0x00000F00
-#define BP_AUDIOIN_ADCVOL_GAIN_LEFT	8
-#define BM_AUDIOIN_ADCVOL_SELECT_LEFT	0x00003000
-#define BP_AUDIOIN_ADCVOL_SELECT_LEFT	12
-#define BM_AUDIOIN_ADCVOL_MUTE	0x01000000
-
-#define HW_AUDIOIN_MICLINE	0x60
-
-#define HW_AUDIOIN_ANACLKCTRL	0x70
-#define BM_AUDIOIN_ANACLKCTRL_CLKGATE	0x80000000
-
-#define HW_AUDIOIN_DATA		0x80
diff -druN linux-2.6.39-libre/arch/arm/mach-stmp37xx/include/mach/regs-audioout.h linux-3.0-rc7-libre/arch/arm/mach-stmp37xx/include/mach/regs-audioout.h
--- linux-2.6.39-libre/arch/arm/mach-stmp37xx/include/mach/regs-audioout.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-stmp37xx/include/mach/regs-audioout.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,111 +0,0 @@
-/*
- * stmp37xx: AUDIOOUT register definitions
- *
- * Copyright (c) 2008 Freescale Semiconductor
- * Copyright 2008 Embedded Alley Solutions, 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
- */
-#define REGS_AUDIOOUT_BASE	(STMP3XXX_REGS_BASE + 0x48000)
-
-#define HW_AUDIOOUT_CTRL	0x0
-#define BM_AUDIOOUT_CTRL_RUN	0x00000001
-#define BP_AUDIOOUT_CTRL_RUN	0
-#define BM_AUDIOOUT_CTRL_FIFO_ERROR_IRQ_EN	0x00000002
-#define BM_AUDIOOUT_CTRL_FIFO_OVERFLOW_IRQ	0x00000004
-#define BM_AUDIOOUT_CTRL_FIFO_UNDERFLOW_IRQ	0x00000008
-#define BM_AUDIOOUT_CTRL_WORD_LENGTH	0x00000040
-#define BM_AUDIOOUT_CTRL_CLKGATE	0x40000000
-#define BM_AUDIOOUT_CTRL_SFTRST	0x80000000
-
-#define HW_AUDIOOUT_STAT	0x10
-
-#define HW_AUDIOOUT_DACSRR	0x20
-#define BM_AUDIOOUT_DACSRR_SRC_FRAC	0x00001FFF
-#define BP_AUDIOOUT_DACSRR_SRC_FRAC	0
-#define BM_AUDIOOUT_DACSRR_SRC_INT	0x001F0000
-#define BP_AUDIOOUT_DACSRR_SRC_INT	16
-#define BM_AUDIOOUT_DACSRR_SRC_HOLD	0x07000000
-#define BP_AUDIOOUT_DACSRR_SRC_HOLD	24
-#define BM_AUDIOOUT_DACSRR_BASEMULT	0x70000000
-#define BP_AUDIOOUT_DACSRR_BASEMULT	28
-
-#define HW_AUDIOOUT_DACVOLUME	0x30
-#define BM_AUDIOOUT_DACVOLUME_MUTE_RIGHT	0x00000100
-#define BM_AUDIOOUT_DACVOLUME_MUTE_LEFT	0x01000000
-#define BM_AUDIOOUT_DACVOLUME_EN_ZCD	0x02000000
-
-#define HW_AUDIOOUT_DACDEBUG	0x40
-
-#define HW_AUDIOOUT_HPVOL	0x50
-#define BM_AUDIOOUT_HPVOL_MUTE	0x01000000
-#define BM_AUDIOOUT_HPVOL_EN_MSTR_ZCD	0x02000000
-
-#define HW_AUDIOOUT_PWRDN	0x70
-#define BM_AUDIOOUT_PWRDN_HEADPHONE	0x00000001
-#define BP_AUDIOOUT_PWRDN_HEADPHONE	0
-#define BM_AUDIOOUT_PWRDN_CAPLESS	0x00000010
-#define BM_AUDIOOUT_PWRDN_ADC	0x00000100
-#define BM_AUDIOOUT_PWRDN_DAC	0x00001000
-#define BM_AUDIOOUT_PWRDN_RIGHT_ADC	0x00010000
-#define BM_AUDIOOUT_PWRDN_LINEOUT	0x01000000
-
-#define HW_AUDIOOUT_REFCTRL	0x80
-#define BM_AUDIOOUT_REFCTRL_VAG_VAL	0x000000F0
-#define BP_AUDIOOUT_REFCTRL_VAG_VAL	4
-#define BM_AUDIOOUT_REFCTRL_ADC_REFVAL	0x00000F00
-#define BP_AUDIOOUT_REFCTRL_ADC_REFVAL	8
-#define BM_AUDIOOUT_REFCTRL_ADJ_VAG	0x00001000
-#define BM_AUDIOOUT_REFCTRL_ADJ_ADC	0x00002000
-#define BM_AUDIOOUT_REFCTRL_BIAS_CTRL	0x00030000
-#define BP_AUDIOOUT_REFCTRL_BIAS_CTRL	16
-#define BM_AUDIOOUT_REFCTRL_LOW_PWR	0x00080000
-#define BM_AUDIOOUT_REFCTRL_VBG_ADJ	0x00700000
-#define BP_AUDIOOUT_REFCTRL_VBG_ADJ	20
-#define BM_AUDIOOUT_REFCTRL_XTAL_BGR_BIAS	0x01000000
-#define BM_AUDIOOUT_REFCTRL_RAISE_REF	0x02000000
-
-#define HW_AUDIOOUT_ANACTRL	0x90
-#define BM_AUDIOOUT_ANACTRL_HP_CLASSAB	0x00000010
-#define BM_AUDIOOUT_ANACTRL_HP_HOLD_GND	0x00000020
-
-#define HW_AUDIOOUT_TEST	0xA0
-#define BM_AUDIOOUT_TEST_HP_I1_ADJ	0x00C00000
-#define BP_AUDIOOUT_TEST_HP_I1_ADJ	22
-
-#define HW_AUDIOOUT_BISTCTRL	0xB0
-
-#define HW_AUDIOOUT_BISTSTAT0	0xC0
-
-#define HW_AUDIOOUT_BISTSTAT1	0xD0
-
-#define HW_AUDIOOUT_ANACLKCTRL	0xE0
-#define BM_AUDIOOUT_ANACLKCTRL_CLKGATE	0x80000000
-
-#define HW_AUDIOOUT_DATA	0xF0
-
-#define HW_AUDIOOUT_LINEOUTCTRL	0x100
-#define BM_AUDIOOUT_LINEOUTCTRL_VOL_RIGHT	0x0000001F
-#define BP_AUDIOOUT_LINEOUTCTRL_VOL_RIGHT	0
-#define BM_AUDIOOUT_LINEOUTCTRL_VOL_LEFT	0x00001F00
-#define BP_AUDIOOUT_LINEOUTCTRL_VOL_LEFT	8
-#define BM_AUDIOOUT_LINEOUTCTRL_CHARGE_CAP	0x00007000
-#define BP_AUDIOOUT_LINEOUTCTRL_CHARGE_CAP	12
-#define BM_AUDIOOUT_LINEOUTCTRL_VAG_CTRL	0x00F00000
-#define BP_AUDIOOUT_LINEOUTCTRL_VAG_CTRL	20
-#define BM_AUDIOOUT_LINEOUTCTRL_MUTE	0x01000000
-#define BM_AUDIOOUT_LINEOUTCTRL_EN_ZCD	0x02000000
-
-#define HW_AUDIOOUT_VERSION	0x200
diff -druN linux-2.6.39-libre/arch/arm/mach-stmp37xx/include/mach/regs-clkctrl.h linux-3.0-rc7-libre/arch/arm/mach-stmp37xx/include/mach/regs-clkctrl.h
--- linux-2.6.39-libre/arch/arm/mach-stmp37xx/include/mach/regs-clkctrl.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-stmp37xx/include/mach/regs-clkctrl.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,72 +0,0 @@
-/*
- * stmp37xx: CLKCTRL register definitions
- *
- * Copyright (c) 2008 Freescale Semiconductor
- * Copyright 2008 Embedded Alley Solutions, 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
- */
-#ifndef _MACH_REGS_CLKCTRL
-#define _MACH_REGS_CLKCTRL
-
-#define REGS_CLKCTRL_BASE	(STMP3XXX_REGS_BASE + 0x40000)
-
-#define HW_CLKCTRL_PLLCTRL0	0x0
-#define BM_CLKCTRL_PLLCTRL0_EN_USB_CLKS	0x00040000
-
-#define HW_CLKCTRL_CPU		0x20
-#define BM_CLKCTRL_CPU_DIV_CPU	0x0000003F
-#define BP_CLKCTRL_CPU_DIV_CPU	0
-
-#define HW_CLKCTRL_HBUS		0x30
-#define BM_CLKCTRL_HBUS_DIV	0x0000001F
-#define BP_CLKCTRL_HBUS_DIV	0
-
-#define HW_CLKCTRL_XBUS		0x40
-
-#define HW_CLKCTRL_XTAL		0x50
-
-#define HW_CLKCTRL_PIX		0x60
-#define BM_CLKCTRL_PIX_DIV	0x00007FFF
-#define BP_CLKCTRL_PIX_DIV	0
-#define BM_CLKCTRL_PIX_CLKGATE	0x80000000
-
-#define HW_CLKCTRL_SSP		0x70
-
-#define HW_CLKCTRL_GPMI		0x80
-
-#define HW_CLKCTRL_SPDIF	0x90
-
-#define HW_CLKCTRL_EMI		0xA0
-
-#define HW_CLKCTRL_IR		0xB0
-
-#define HW_CLKCTRL_SAIF		0xC0
-
-#define HW_CLKCTRL_FRAC		0xD0
-#define BM_CLKCTRL_FRAC_EMIFRAC	0x00003F00
-#define BP_CLKCTRL_FRAC_EMIFRAC	8
-#define BM_CLKCTRL_FRAC_PIXFRAC	0x003F0000
-#define BP_CLKCTRL_FRAC_PIXFRAC	16
-#define BM_CLKCTRL_FRAC_CLKGATEPIX	0x00800000
-
-#define HW_CLKCTRL_CLKSEQ	0xE0
-#define BM_CLKCTRL_CLKSEQ_BYPASS_PIX	0x00000002
-
-#define HW_CLKCTRL_RESET	0xF0
-#define BM_CLKCTRL_RESET_DIG	0x00000001
-#define BP_CLKCTRL_RESET_DIG	0
-
-#endif
diff -druN linux-2.6.39-libre/arch/arm/mach-stmp37xx/include/mach/regs-digctl.h linux-3.0-rc7-libre/arch/arm/mach-stmp37xx/include/mach/regs-digctl.h
--- linux-2.6.39-libre/arch/arm/mach-stmp37xx/include/mach/regs-digctl.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-stmp37xx/include/mach/regs-digctl.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,24 +0,0 @@
-/*
- * stmp37xx: DIGCTL register definitions
- *
- * Copyright (c) 2008 Freescale Semiconductor
- * Copyright 2008 Embedded Alley Solutions, 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
- */
-#define REGS_DIGCTL_BASE	(STMP3XXX_REGS_BASE + 0x1C000)
-
-#define HW_DIGCTL_CTRL		0x0
-#define BM_DIGCTL_CTRL_USB_CLKGATE	0x00000004
diff -druN linux-2.6.39-libre/arch/arm/mach-stmp37xx/include/mach/regs-ecc8.h linux-3.0-rc7-libre/arch/arm/mach-stmp37xx/include/mach/regs-ecc8.h
--- linux-2.6.39-libre/arch/arm/mach-stmp37xx/include/mach/regs-ecc8.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-stmp37xx/include/mach/regs-ecc8.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,37 +0,0 @@
-/*
- * stmp37xx: ECC8 register definitions
- *
- * Copyright (c) 2008 Freescale Semiconductor
- * Copyright 2008 Embedded Alley Solutions, 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
- */
-#define REGS_ECC8_BASE	(STMP3XXX_REGS_BASE + 0x8000)
-
-#define HW_ECC8_CTRL		0x0
-#define BM_ECC8_CTRL_COMPLETE_IRQ	0x00000001
-#define BP_ECC8_CTRL_COMPLETE_IRQ	0
-#define BM_ECC8_CTRL_COMPLETE_IRQ_EN	0x00000100
-#define BM_ECC8_CTRL_AHBM_SFTRST	0x20000000
-
-#define HW_ECC8_STATUS0		0x10
-#define BM_ECC8_STATUS0_UNCORRECTABLE	0x00000004
-#define BM_ECC8_STATUS0_CORRECTED	0x00000008
-#define BM_ECC8_STATUS0_STATUS_AUX	0x00000F00
-#define BP_ECC8_STATUS0_STATUS_AUX	8
-#define BM_ECC8_STATUS0_COMPLETED_CE	0x000F0000
-#define BP_ECC8_STATUS0_COMPLETED_CE	16
-
-#define HW_ECC8_STATUS1		0x20
diff -druN linux-2.6.39-libre/arch/arm/mach-stmp37xx/include/mach/regs-gpmi.h linux-3.0-rc7-libre/arch/arm/mach-stmp37xx/include/mach/regs-gpmi.h
--- linux-2.6.39-libre/arch/arm/mach-stmp37xx/include/mach/regs-gpmi.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-stmp37xx/include/mach/regs-gpmi.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,63 +0,0 @@
-/*
- * stmp37xx: GPMI register definitions
- *
- * Copyright (c) 2008 Freescale Semiconductor
- * Copyright 2008 Embedded Alley Solutions, 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
- */
-#define REGS_GPMI_BASE	(STMP3XXX_REGS_BASE + 0xC000)
-#define REGS_GPMI_PHYS	0x8000C000
-#define REGS_GPMI_SIZE	0x2000
-
-#define HW_GPMI_CTRL0		0x0
-#define BM_GPMI_CTRL0_XFER_COUNT	0x0000FFFF
-#define BP_GPMI_CTRL0_XFER_COUNT	0
-#define BM_GPMI_CTRL0_CS	0x00300000
-#define BP_GPMI_CTRL0_CS	20
-#define BM_GPMI_CTRL0_LOCK_CS	0x00400000
-#define BM_GPMI_CTRL0_WORD_LENGTH	0x00800000
-#define BM_GPMI_CTRL0_COMMAND_MODE	0x03000000
-#define BP_GPMI_CTRL0_COMMAND_MODE	24
-#define BV_GPMI_CTRL0_COMMAND_MODE__WRITE	    0x0
-#define BV_GPMI_CTRL0_COMMAND_MODE__READ	     0x1
-#define BV_GPMI_CTRL0_COMMAND_MODE__READ_AND_COMPARE 0x2
-#define BV_GPMI_CTRL0_COMMAND_MODE__WAIT_FOR_READY   0x3
-#define BM_GPMI_CTRL0_RUN	0x20000000
-#define BM_GPMI_CTRL0_CLKGATE	0x40000000
-#define BM_GPMI_CTRL0_SFTRST	0x80000000
-#define BM_GPMI_ECCCTRL_ENABLE_ECC	0x00001000
-#define BM_GPMI_ECCCTRL_ECC_CMD	0x00006000
-#define BP_GPMI_ECCCTRL_ECC_CMD	13
-
-#define HW_GPMI_CTRL1		0x60
-#define BM_GPMI_CTRL1_GPMI_MODE	0x00000003
-#define BP_GPMI_CTRL1_GPMI_MODE	0
-#define BM_GPMI_CTRL1_ATA_IRQRDY_POLARITY	0x00000004
-#define BM_GPMI_CTRL1_DEV_RESET	0x00000008
-#define BM_GPMI_CTRL1_TIMEOUT_IRQ	0x00000200
-#define BM_GPMI_CTRL1_DEV_IRQ	0x00000400
-#define BM_GPMI_CTRL1_DSAMPLE_TIME	0x00007000
-#define BP_GPMI_CTRL1_DSAMPLE_TIME	12
-
-#define HW_GPMI_TIMING0		0x70
-#define BM_GPMI_TIMING0_DATA_SETUP	0x000000FF
-#define BP_GPMI_TIMING0_DATA_SETUP	0
-#define BM_GPMI_TIMING0_DATA_HOLD	0x0000FF00
-#define BP_GPMI_TIMING0_DATA_HOLD	8
-
-#define HW_GPMI_TIMING1		0x80
-#define BM_GPMI_TIMING1_DEVICE_BUSY_TIMEOUT	0xFFFF0000
-#define BP_GPMI_TIMING1_DEVICE_BUSY_TIMEOUT	16
diff -druN linux-2.6.39-libre/arch/arm/mach-stmp37xx/include/mach/regs-i2c.h linux-3.0-rc7-libre/arch/arm/mach-stmp37xx/include/mach/regs-i2c.h
--- linux-2.6.39-libre/arch/arm/mach-stmp37xx/include/mach/regs-i2c.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-stmp37xx/include/mach/regs-i2c.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,55 +0,0 @@
-/*
- * stmp37xx: I2C register definitions
- *
- * Copyright (c) 2008 Freescale Semiconductor
- * Copyright 2008 Embedded Alley Solutions, 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
- */
-#define REGS_I2C_BASE	(STMP3XXX_REGS_BASE + 0x58000)
-#define REGS_I2C_PHYS	0x80058000
-#define REGS_I2C_SIZE	0x2000
-
-#define HW_I2C_CTRL0		0x0
-#define BM_I2C_CTRL0_XFER_COUNT	0x0000FFFF
-#define BP_I2C_CTRL0_XFER_COUNT	0
-#define BM_I2C_CTRL0_DIRECTION	0x00010000
-#define BM_I2C_CTRL0_MASTER_MODE	0x00020000
-#define BM_I2C_CTRL0_PRE_SEND_START	0x00080000
-#define BM_I2C_CTRL0_POST_SEND_STOP	0x00100000
-#define BM_I2C_CTRL0_RETAIN_CLOCK	0x00200000
-#define BM_I2C_CTRL0_SEND_NAK_ON_LAST	0x02000000
-#define BM_I2C_CTRL0_CLKGATE	0x40000000
-#define BM_I2C_CTRL0_SFTRST	0x80000000
-
-#define HW_I2C_TIMING0		0x10
-
-#define HW_I2C_TIMING1		0x20
-
-#define HW_I2C_TIMING2		0x30
-
-#define HW_I2C_CTRL1		0x40
-#define BM_I2C_CTRL1_SLAVE_IRQ	0x00000001
-#define BP_I2C_CTRL1_SLAVE_IRQ	0
-#define BM_I2C_CTRL1_SLAVE_STOP_IRQ	0x00000002
-#define BM_I2C_CTRL1_MASTER_LOSS_IRQ	0x00000004
-#define BM_I2C_CTRL1_EARLY_TERM_IRQ	0x00000008
-#define BM_I2C_CTRL1_OVERSIZE_XFER_TERM_IRQ	0x00000010
-#define BM_I2C_CTRL1_NO_SLAVE_ACK_IRQ	0x00000020
-#define BM_I2C_CTRL1_DATA_ENGINE_CMPLT_IRQ	0x00000040
-#define BM_I2C_CTRL1_BUS_FREE_IRQ	0x00000080
-#define BM_I2C_CTRL1_CLR_GOT_A_NAK	0x10000000
-
-#define HW_I2C_VERSION		0x90
diff -druN linux-2.6.39-libre/arch/arm/mach-stmp37xx/include/mach/regs-icoll.h linux-3.0-rc7-libre/arch/arm/mach-stmp37xx/include/mach/regs-icoll.h
--- linux-2.6.39-libre/arch/arm/mach-stmp37xx/include/mach/regs-icoll.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-stmp37xx/include/mach/regs-icoll.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,43 +0,0 @@
-/*
- * stmp37xx: ICOLL register definitions
- *
- * Copyright (c) 2008 Freescale Semiconductor
- * Copyright 2008 Embedded Alley Solutions, 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
- */
-#ifndef _MACH_REGS_ICOLL
-#define _MACH_REGS_ICOLL
-
-#define REGS_ICOLL_BASE	(STMP3XXX_REGS_BASE + 0x0)
-
-#define HW_ICOLL_VECTOR		0x0
-
-#define HW_ICOLL_LEVELACK	0x10
-
-#define HW_ICOLL_CTRL		0x20
-#define BM_ICOLL_CTRL_CLKGATE	0x40000000
-#define BM_ICOLL_CTRL_SFTRST	0x80000000
-
-#define HW_ICOLL_STAT		0x30
-
-#define HW_ICOLL_PRIORITY0	(0x60 + 0 * 0x10)
-#define HW_ICOLL_PRIORITY1	(0x60 + 1 * 0x10)
-#define HW_ICOLL_PRIORITY2	(0x60 + 2 * 0x10)
-#define HW_ICOLL_PRIORITY3	(0x60 + 3 * 0x10)
-
-#define HW_ICOLL_PRIORITYn	0x60
-
-#endif
diff -druN linux-2.6.39-libre/arch/arm/mach-stmp37xx/include/mach/regs-lcdif.h linux-3.0-rc7-libre/arch/arm/mach-stmp37xx/include/mach/regs-lcdif.h
--- linux-2.6.39-libre/arch/arm/mach-stmp37xx/include/mach/regs-lcdif.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-stmp37xx/include/mach/regs-lcdif.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,89 +0,0 @@
-/*
- * stmp37xx: LCDIF register definitions
- *
- * Copyright (c) 2008 Freescale Semiconductor
- * Copyright 2008 Embedded Alley Solutions, 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
- */
-#define REGS_LCDIF_BASE	(STMP3XXX_REGS_BASE + 0x30000)
-#define REGS_LCDIF_PHYS	0x80030000
-#define REGS_LCDIF_SIZE	0x2000
-
-#define HW_LCDIF_CTRL		0x0
-#define BM_LCDIF_CTRL_COUNT	0x0000FFFF
-#define BP_LCDIF_CTRL_COUNT	0
-#define BM_LCDIF_CTRL_RUN	0x00010000
-#define BM_LCDIF_CTRL_WORD_LENGTH	0x00020000
-#define BM_LCDIF_CTRL_DATA_SELECT	0x00040000
-#define BM_LCDIF_CTRL_DOTCLK_MODE	0x00080000
-#define BM_LCDIF_CTRL_VSYNC_MODE	0x00100000
-#define BM_LCDIF_CTRL_DATA_SWIZZLE	0x00600000
-#define BP_LCDIF_CTRL_DATA_SWIZZLE	21
-#define BM_LCDIF_CTRL_BYPASS_COUNT	0x00800000
-#define BM_LCDIF_CTRL_SHIFT_NUM_BITS	0x06000000
-#define BP_LCDIF_CTRL_SHIFT_NUM_BITS	25
-#define BM_LCDIF_CTRL_DATA_SHIFT_DIR	0x08000000
-#define BM_LCDIF_CTRL_WAIT_FOR_VSYNC_EDGE	0x10000000
-#define BM_LCDIF_CTRL_CLKGATE	0x40000000
-#define BM_LCDIF_CTRL_SFTRST	0x80000000
-
-#define HW_LCDIF_CTRL1		0x10
-#define BM_LCDIF_CTRL1_RESET	0x00000001
-#define BP_LCDIF_CTRL1_RESET	0
-#define BM_LCDIF_CTRL1_MODE86	0x00000002
-#define BM_LCDIF_CTRL1_BUSY_ENABLE	0x00000004
-#define BM_LCDIF_CTRL1_VSYNC_EDGE_IRQ	0x00000100
-#define BM_LCDIF_CTRL1_CUR_FRAME_DONE_IRQ	0x00000200
-#define BM_LCDIF_CTRL1_UNDERFLOW_IRQ	0x00000400
-#define BM_LCDIF_CTRL1_OVERFLOW_IRQ	0x00000800
-#define BM_LCDIF_CTRL1_VSYNC_EDGE_IRQ_EN	0x00001000
-#define BM_LCDIF_CTRL1_BYTE_PACKING_FORMAT	0x000F0000
-#define BP_LCDIF_CTRL1_BYTE_PACKING_FORMAT	16
-
-#define HW_LCDIF_TIMING		0x20
-
-#define HW_LCDIF_VDCTRL0	0x30
-#define BM_LCDIF_VDCTRL0_VALID_DATA_CNT	0x000003FF
-#define BP_LCDIF_VDCTRL0_VALID_DATA_CNT	0
-#define BM_LCDIF_VDCTRL0_VSYNC_PULSE_WIDTH_UNIT	0x00100000
-#define BM_LCDIF_VDCTRL0_VSYNC_PERIOD_UNIT	0x00200000
-#define BM_LCDIF_VDCTRL0_ENABLE_POL	0x01000000
-#define BM_LCDIF_VDCTRL0_DOTCLK_POL	0x02000000
-#define BM_LCDIF_VDCTRL0_HSYNC_POL	0x04000000
-#define BM_LCDIF_VDCTRL0_VSYNC_POL	0x08000000
-#define BM_LCDIF_VDCTRL0_ENABLE_PRESENT	0x10000000
-#define BM_LCDIF_VDCTRL0_VSYNC_OEB	0x20000000
-
-#define HW_LCDIF_VDCTRL1	0x40
-#define BM_LCDIF_VDCTRL1_VSYNC_PERIOD	0x000FFFFF
-#define BP_LCDIF_VDCTRL1_VSYNC_PERIOD	0
-#define BM_LCDIF_VDCTRL1_VSYNC_PULSE_WIDTH	0xFFF00000
-#define BP_LCDIF_VDCTRL1_VSYNC_PULSE_WIDTH	20
-
-#define HW_LCDIF_VDCTRL2	0x50
-#define BM_LCDIF_VDCTRL2_VALID_DATA_CNT	0x000007FF
-#define BP_LCDIF_VDCTRL2_VALID_DATA_CNT	0
-#define BM_LCDIF_VDCTRL2_HSYNC_PERIOD	0x007FF800
-#define BP_LCDIF_VDCTRL2_HSYNC_PERIOD	11
-#define BM_LCDIF_VDCTRL2_HSYNC_PULSE_WIDTH	0xFF800000
-#define BP_LCDIF_VDCTRL2_HSYNC_PULSE_WIDTH	23
-
-#define HW_LCDIF_VDCTRL3	0x60
-#define BM_LCDIF_VDCTRL3_VERTICAL_WAIT_CNT	0x000001FF
-#define BP_LCDIF_VDCTRL3_VERTICAL_WAIT_CNT	0
-#define BM_LCDIF_VDCTRL3_HORIZONTAL_WAIT_CNT	0x00FFF000
-#define BP_LCDIF_VDCTRL3_HORIZONTAL_WAIT_CNT	12
-#define BM_LCDIF_VDCTRL3_SYNC_SIGNALS_ON	0x01000000
diff -druN linux-2.6.39-libre/arch/arm/mach-stmp37xx/include/mach/regs-lradc.h linux-3.0-rc7-libre/arch/arm/mach-stmp37xx/include/mach/regs-lradc.h
--- linux-2.6.39-libre/arch/arm/mach-stmp37xx/include/mach/regs-lradc.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-stmp37xx/include/mach/regs-lradc.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,97 +0,0 @@
-/*
- * stmp37xx: LRADC register definitions
- *
- * Copyright (c) 2008 Freescale Semiconductor
- * Copyright 2008 Embedded Alley Solutions, 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
- */
-#define REGS_LRADC_BASE	(STMP3XXX_REGS_BASE + 0x50000)
-
-#define HW_LRADC_CTRL0		0x0
-#define BM_LRADC_CTRL0_SCHEDULE	0x000000FF
-#define BP_LRADC_CTRL0_SCHEDULE	0
-#define BM_LRADC_CTRL0_XPLUS_ENABLE	0x00010000
-#define BM_LRADC_CTRL0_YPLUS_ENABLE	0x00020000
-#define BM_LRADC_CTRL0_XMINUS_ENABLE	0x00040000
-#define BM_LRADC_CTRL0_YMINUS_ENABLE	0x00080000
-#define BM_LRADC_CTRL0_TOUCH_DETECT_ENABLE	0x00100000
-#define BM_LRADC_CTRL0_ONCHIP_GROUNDREF	0x00200000
-#define BM_LRADC_CTRL0_CLKGATE	0x40000000
-#define BM_LRADC_CTRL0_SFTRST	0x80000000
-
-#define HW_LRADC_CTRL1		0x10
-#define BM_LRADC_CTRL1_LRADC0_IRQ	0x00000001
-#define BP_LRADC_CTRL1_LRADC0_IRQ	0
-#define BM_LRADC_CTRL1_LRADC5_IRQ	0x00000020
-#define BM_LRADC_CTRL1_LRADC6_IRQ	0x00000040
-#define BM_LRADC_CTRL1_TOUCH_DETECT_IRQ	0x00000100
-#define BM_LRADC_CTRL1_LRADC0_IRQ_EN	0x00010000
-#define BM_LRADC_CTRL1_LRADC5_IRQ_EN	0x00200000
-#define BM_LRADC_CTRL1_TOUCH_DETECT_IRQ_EN	0x01000000
-
-#define HW_LRADC_CTRL2		0x20
-#define BM_LRADC_CTRL2_BL_BRIGHTNESS	0x001F0000
-#define BP_LRADC_CTRL2_BL_BRIGHTNESS	16
-#define BM_LRADC_CTRL2_BL_MUX_SELECT	0x00200000
-#define BM_LRADC_CTRL2_BL_ENABLE	0x00400000
-#define BM_LRADC_CTRL2_DIVIDE_BY_TWO	0xFF000000
-#define BP_LRADC_CTRL2_DIVIDE_BY_TWO	24
-
-#define HW_LRADC_CTRL3		0x30
-#define BM_LRADC_CTRL3_CYCLE_TIME	0x00000300
-#define BP_LRADC_CTRL3_CYCLE_TIME	8
-
-#define HW_LRADC_STATUS		0x40
-#define BM_LRADC_STATUS_TOUCH_DETECT_RAW	0x00000001
-#define BP_LRADC_STATUS_TOUCH_DETECT_RAW	0
-
-#define HW_LRADC_CH0		(0x50 + 0 * 0x10)
-#define HW_LRADC_CH1		(0x50 + 1 * 0x10)
-#define HW_LRADC_CH2		(0x50 + 2 * 0x10)
-#define HW_LRADC_CH3		(0x50 + 3 * 0x10)
-#define HW_LRADC_CH4		(0x50 + 4 * 0x10)
-#define HW_LRADC_CH5		(0x50 + 5 * 0x10)
-#define HW_LRADC_CH6		(0x50 + 6 * 0x10)
-#define HW_LRADC_CH7		(0x50 + 7 * 0x10)
-
-#define HW_LRADC_CHn		0x50
-#define BM_LRADC_CHn_VALUE	0x0003FFFF
-#define BP_LRADC_CHn_VALUE	0
-#define BM_LRADC_CHn_NUM_SAMPLES	0x1F000000
-#define BP_LRADC_CHn_NUM_SAMPLES	24
-#define BM_LRADC_CHn_ACCUMULATE	0x20000000
-
-#define HW_LRADC_DELAY0		(0xD0 + 0 * 0x10)
-#define HW_LRADC_DELAY1		(0xD0 + 1 * 0x10)
-#define HW_LRADC_DELAY2		(0xD0 + 2 * 0x10)
-#define HW_LRADC_DELAY3		(0xD0 + 3 * 0x10)
-
-#define HW_LRADC_DELAYn		0xD0
-#define BM_LRADC_DELAYn_DELAY	0x000007FF
-#define BP_LRADC_DELAYn_DELAY	0
-#define BM_LRADC_DELAYn_LOOP_COUNT	0x0000F800
-#define BP_LRADC_DELAYn_LOOP_COUNT	11
-#define BM_LRADC_DELAYn_TRIGGER_DELAYS	0x000F0000
-#define BP_LRADC_DELAYn_TRIGGER_DELAYS	16
-#define BM_LRADC_DELAYn_KICK	0x00100000
-#define BM_LRADC_DELAYn_TRIGGER_LRADCS	0xFF000000
-#define BP_LRADC_DELAYn_TRIGGER_LRADCS	24
-
-#define HW_LRADC_CTRL4		0x140
-#define BM_LRADC_CTRL4_LRADC6SELECT	0x0F000000
-#define BP_LRADC_CTRL4_LRADC6SELECT	24
-#define BM_LRADC_CTRL4_LRADC7SELECT	0xF0000000
-#define BP_LRADC_CTRL4_LRADC7SELECT	28
diff -druN linux-2.6.39-libre/arch/arm/mach-stmp37xx/include/mach/regs-pinctrl.h linux-3.0-rc7-libre/arch/arm/mach-stmp37xx/include/mach/regs-pinctrl.h
--- linux-2.6.39-libre/arch/arm/mach-stmp37xx/include/mach/regs-pinctrl.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-stmp37xx/include/mach/regs-pinctrl.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,88 +0,0 @@
-/*
- * stmp37xx: PINCTRL register definitions
- *
- * Copyright (c) 2008 Freescale Semiconductor
- * Copyright 2008 Embedded Alley Solutions, 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
- */
-#ifndef _MACH_REGS_PINCTRL
-#define _MACH_REGS_PINCTRL
-
-#define REGS_PINCTRL_BASE	(STMP3XXX_REGS_BASE + 0x18000)
-
-#define HW_PINCTRL_MUXSEL0	0x100
-#define HW_PINCTRL_MUXSEL1	0x110
-#define HW_PINCTRL_MUXSEL2	0x120
-#define HW_PINCTRL_MUXSEL3	0x130
-#define HW_PINCTRL_MUXSEL4	0x140
-#define HW_PINCTRL_MUXSEL5	0x150
-#define HW_PINCTRL_MUXSEL6	0x160
-#define HW_PINCTRL_MUXSEL7	0x170
-
-#define HW_PINCTRL_DRIVE0	0x200
-#define HW_PINCTRL_DRIVE1	0x210
-#define HW_PINCTRL_DRIVE2	0x220
-#define HW_PINCTRL_DRIVE3	0x230
-#define HW_PINCTRL_DRIVE4	0x240
-#define HW_PINCTRL_DRIVE5	0x250
-#define HW_PINCTRL_DRIVE6	0x260
-#define HW_PINCTRL_DRIVE7	0x270
-#define HW_PINCTRL_DRIVE8	0x280
-#define HW_PINCTRL_DRIVE9	0x290
-#define HW_PINCTRL_DRIVE10	0x2A0
-#define HW_PINCTRL_DRIVE11	0x2B0
-#define HW_PINCTRL_DRIVE12	0x2C0
-#define HW_PINCTRL_DRIVE13	0x2D0
-#define HW_PINCTRL_DRIVE14	0x2E0
-
-#define HW_PINCTRL_PULL0	0x300
-#define HW_PINCTRL_PULL1	0x310
-#define HW_PINCTRL_PULL2	0x320
-#define HW_PINCTRL_PULL3	0x330
-
-#define HW_PINCTRL_DOUT0	0x400
-#define HW_PINCTRL_DOUT1	0x410
-#define HW_PINCTRL_DOUT2	0x420
-
-#define HW_PINCTRL_DIN0		0x500
-#define HW_PINCTRL_DIN1		0x510
-#define HW_PINCTRL_DIN2		0x520
-
-#define HW_PINCTRL_DOE0		0x600
-#define HW_PINCTRL_DOE1		0x610
-#define HW_PINCTRL_DOE2		0x620
-
-#define HW_PINCTRL_PIN2IRQ0	0x700
-#define HW_PINCTRL_PIN2IRQ1	0x710
-#define HW_PINCTRL_PIN2IRQ2	0x720
-
-#define HW_PINCTRL_IRQEN0	0x800
-#define HW_PINCTRL_IRQEN1	0x810
-#define HW_PINCTRL_IRQEN2	0x820
-
-#define HW_PINCTRL_IRQLEVEL0	0x900
-#define HW_PINCTRL_IRQLEVEL1	0x910
-#define HW_PINCTRL_IRQLEVEL2	0x920
-
-#define HW_PINCTRL_IRQPOL0	0xA00
-#define HW_PINCTRL_IRQPOL1	0xA10
-#define HW_PINCTRL_IRQPOL2	0xA20
-
-#define HW_PINCTRL_IRQSTAT0	0xB00
-#define HW_PINCTRL_IRQSTAT1	0xB10
-#define HW_PINCTRL_IRQSTAT2	0xB20
-
-#endif
diff -druN linux-2.6.39-libre/arch/arm/mach-stmp37xx/include/mach/regs-power.h linux-3.0-rc7-libre/arch/arm/mach-stmp37xx/include/mach/regs-power.h
--- linux-2.6.39-libre/arch/arm/mach-stmp37xx/include/mach/regs-power.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-stmp37xx/include/mach/regs-power.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,56 +0,0 @@
-/*
- * stmp37xx: POWER register definitions
- *
- * Copyright (c) 2008 Freescale Semiconductor
- * Copyright 2008 Embedded Alley Solutions, 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
- */
-#ifndef _MACH_REGS_POWER
-#define _MACH_REGS_POWER
-
-#define REGS_POWER_BASE	(STMP3XXX_REGS_BASE + 0x44000)
-
-#define HW_POWER_CTRL		0x0
-#define BM_POWER_CTRL_CLKGATE	0x40000000
-
-#define HW_POWER_5VCTRL		0x10
-
-#define HW_POWER_MINPWR		0x20
-
-#define HW_POWER_CHARGE		0x30
-
-#define HW_POWER_VDDDCTRL	0x40
-
-#define HW_POWER_VDDACTRL	0x50
-
-#define HW_POWER_VDDIOCTRL	0x60
-#define BM_POWER_VDDIOCTRL_TRG	0x0000001F
-#define BP_POWER_VDDIOCTRL_TRG	0
-
-#define HW_POWER_STS		0xB0
-#define BM_POWER_STS_VBUSVALID	0x00000002
-#define BM_POWER_STS_BVALID	0x00000004
-#define BM_POWER_STS_AVALID	0x00000008
-#define BM_POWER_STS_DC_OK	0x00000100
-
-#define HW_POWER_RESET		0xE0
-
-#define HW_POWER_DEBUG		0xF0
-#define BM_POWER_DEBUG_BVALIDPIOLOCK	0x00000002
-#define BM_POWER_DEBUG_AVALIDPIOLOCK	0x00000004
-#define BM_POWER_DEBUG_VBUSVALIDPIOLOCK	0x00000008
-
-#endif
diff -druN linux-2.6.39-libre/arch/arm/mach-stmp37xx/include/mach/regs-pwm.h linux-3.0-rc7-libre/arch/arm/mach-stmp37xx/include/mach/regs-pwm.h
--- linux-2.6.39-libre/arch/arm/mach-stmp37xx/include/mach/regs-pwm.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-stmp37xx/include/mach/regs-pwm.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,51 +0,0 @@
-/*
- * stmp37xx: PWM register definitions
- *
- * Copyright (c) 2008 Freescale Semiconductor
- * Copyright 2008 Embedded Alley Solutions, 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
- */
-#define REGS_PWM_BASE	(STMP3XXX_REGS_BASE + 0x64000)
-
-#define HW_PWM_CTRL		0x0
-#define BM_PWM_CTRL_PWM2_ENABLE	0x00000004
-#define BM_PWM_CTRL_PWM2_ANA_CTRL_ENABLE	0x00000020
-
-#define HW_PWM_ACTIVE0		(0x10 + 0 * 0x20)
-#define HW_PWM_ACTIVE1		(0x10 + 1 * 0x20)
-#define HW_PWM_ACTIVE2		(0x10 + 2 * 0x20)
-#define HW_PWM_ACTIVE3		(0x10 + 3 * 0x20)
-
-#define HW_PWM_ACTIVEn		0x10
-#define BM_PWM_ACTIVEn_ACTIVE	0x0000FFFF
-#define BP_PWM_ACTIVEn_ACTIVE	0
-#define BM_PWM_ACTIVEn_INACTIVE	0xFFFF0000
-#define BP_PWM_ACTIVEn_INACTIVE	16
-
-#define HW_PWM_PERIOD0		(0x20 + 0 * 0x20)
-#define HW_PWM_PERIOD1		(0x20 + 1 * 0x20)
-#define HW_PWM_PERIOD2		(0x20 + 2 * 0x20)
-#define HW_PWM_PERIOD3		(0x20 + 3 * 0x20)
-
-#define HW_PWM_PERIODn		0x20
-#define BM_PWM_PERIODn_PERIOD	0x0000FFFF
-#define BP_PWM_PERIODn_PERIOD	0
-#define BM_PWM_PERIODn_ACTIVE_STATE	0x00030000
-#define BP_PWM_PERIODn_ACTIVE_STATE	16
-#define BM_PWM_PERIODn_INACTIVE_STATE	0x000C0000
-#define BP_PWM_PERIODn_INACTIVE_STATE	18
-#define BM_PWM_PERIODn_CDIV	0x00700000
-#define BP_PWM_PERIODn_CDIV	20
diff -druN linux-2.6.39-libre/arch/arm/mach-stmp37xx/include/mach/regs-rtc.h linux-3.0-rc7-libre/arch/arm/mach-stmp37xx/include/mach/regs-rtc.h
--- linux-2.6.39-libre/arch/arm/mach-stmp37xx/include/mach/regs-rtc.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-stmp37xx/include/mach/regs-rtc.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,57 +0,0 @@
-/*
- * stmp37xx: RTC register definitions
- *
- * Copyright (c) 2008 Freescale Semiconductor
- * Copyright 2008 Embedded Alley Solutions, 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
- */
-#define REGS_RTC_BASE	(STMP3XXX_REGS_BASE + 0x5C000)
-#define REGS_RTC_PHYS   0x8005C000
-#define REGS_RTC_SIZE   0x2000
-
-#define HW_RTC_CTRL		0x0
-#define BM_RTC_CTRL_ALARM_IRQ_EN	0x00000001
-#define BP_RTC_CTRL_ALARM_IRQ_EN	0
-#define BM_RTC_CTRL_ONEMSEC_IRQ_EN	0x00000002
-#define BM_RTC_CTRL_ALARM_IRQ	0x00000004
-#define BM_RTC_CTRL_ONEMSEC_IRQ	0x00000008
-#define BM_RTC_CTRL_WATCHDOGEN	0x00000010
-
-#define HW_RTC_STAT		0x10
-#define BM_RTC_STAT_NEW_REGS	0x0000FF00
-#define BP_RTC_STAT_NEW_REGS	8
-#define BM_RTC_STAT_STALE_REGS	0x00FF0000
-#define BP_RTC_STAT_STALE_REGS	16
-#define BM_RTC_STAT_RTC_PRESENT	0x80000000
-
-#define HW_RTC_SECONDS		0x30
-
-#define HW_RTC_ALARM		0x40
-
-#define HW_RTC_WATCHDOG		0x50
-
-#define HW_RTC_PERSISTENT0	0x60
-#define BM_RTC_PERSISTENT0_ALARM_WAKE_EN	0x00000002
-#define BM_RTC_PERSISTENT0_ALARM_EN	0x00000004
-#define BM_RTC_PERSISTENT0_XTAL24MHZ_PWRUP	0x00000010
-#define BM_RTC_PERSISTENT0_XTAL32KHZ_PWRUP	0x00000020
-#define BM_RTC_PERSISTENT0_ALARM_WAKE	0x00000080
-#define BM_RTC_PERSISTENT0_SPARE_ANALOG	0xFFFC0000
-#define BP_RTC_PERSISTENT0_SPARE_ANALOG	18
-
-#define HW_RTC_PERSISTENT1	0x70
-
-#define HW_RTC_VERSION		0xD0
diff -druN linux-2.6.39-libre/arch/arm/mach-stmp37xx/include/mach/regs-ssp.h linux-3.0-rc7-libre/arch/arm/mach-stmp37xx/include/mach/regs-ssp.h
--- linux-2.6.39-libre/arch/arm/mach-stmp37xx/include/mach/regs-ssp.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-stmp37xx/include/mach/regs-ssp.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,101 +0,0 @@
-/*
- * stmp37xx: SSP register definitions
- *
- * Copyright (c) 2008 Freescale Semiconductor
- * Copyright 2008 Embedded Alley Solutions, 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
- */
-#define REGS_SSP_BASE	(STMP3XXX_REGS_BASE + 0x10000)
-#define REGS_SSP1_PHYS	0x80010000
-#define REGS_SSP2_PHYS	0x80034000
-#define REGS_SSP_SIZE	0x2000
-
-#define HW_SSP_CTRL0		0x0
-#define BM_SSP_CTRL0_XFER_COUNT	0x0000FFFF
-#define BP_SSP_CTRL0_XFER_COUNT	0
-#define BM_SSP_CTRL0_ENABLE	0x00010000
-#define BM_SSP_CTRL0_GET_RESP	0x00020000
-#define BM_SSP_CTRL0_LONG_RESP	0x00080000
-#define BM_SSP_CTRL0_WAIT_FOR_CMD	0x00100000
-#define BM_SSP_CTRL0_WAIT_FOR_IRQ	0x00200000
-#define BM_SSP_CTRL0_BUS_WIDTH	0x00C00000
-#define BP_SSP_CTRL0_BUS_WIDTH	22
-#define BM_SSP_CTRL0_DATA_XFER	0x01000000
-#define BM_SSP_CTRL0_READ	0x02000000
-#define BM_SSP_CTRL0_IGNORE_CRC	0x04000000
-#define BM_SSP_CTRL0_LOCK_CS	0x08000000
-#define BM_SSP_CTRL0_RUN	0x20000000
-#define BM_SSP_CTRL0_CLKGATE	0x40000000
-#define BM_SSP_CTRL0_SFTRST	0x80000000
-
-#define HW_SSP_CMD0		0x10
-#define BM_SSP_CMD0_CMD		0x000000FF
-#define BP_SSP_CMD0_CMD		0
-#define BM_SSP_CMD0_BLOCK_COUNT	0x0000FF00
-#define BP_SSP_CMD0_BLOCK_COUNT	8
-#define BM_SSP_CMD0_BLOCK_SIZE	0x000F0000
-#define BP_SSP_CMD0_BLOCK_SIZE	16
-#define BM_SSP_CMD0_APPEND_8CYC	0x00100000
-#define BM_SSP_CMD1_CMD_ARG	0xFFFFFFFF
-#define BP_SSP_CMD1_CMD_ARG	0
-
-#define HW_SSP_TIMING		0x50
-#define BM_SSP_TIMING_CLOCK_RATE	0x000000FF
-#define BP_SSP_TIMING_CLOCK_RATE	0
-#define BM_SSP_TIMING_CLOCK_DIVIDE	0x0000FF00
-#define BP_SSP_TIMING_CLOCK_DIVIDE	8
-#define BM_SSP_TIMING_TIMEOUT	0xFFFF0000
-#define BP_SSP_TIMING_TIMEOUT	16
-
-#define HW_SSP_CTRL1		0x60
-#define BM_SSP_CTRL1_SSP_MODE	0x0000000F
-#define BP_SSP_CTRL1_SSP_MODE	0
-#define BM_SSP_CTRL1_WORD_LENGTH	0x000000F0
-#define BP_SSP_CTRL1_WORD_LENGTH	4
-#define BM_SSP_CTRL1_POLARITY	0x00000200
-#define BM_SSP_CTRL1_PHASE	0x00000400
-#define BM_SSP_CTRL1_DMA_ENABLE	0x00002000
-#define BM_SSP_CTRL1_FIFO_OVERRUN_IRQ	0x00008000
-#define BM_SSP_CTRL1_RECV_TIMEOUT_IRQ_EN	0x00010000
-#define BM_SSP_CTRL1_RECV_TIMEOUT_IRQ	0x00020000
-#define BM_SSP_CTRL1_FIFO_UNDERRUN_IRQ	0x00200000
-#define BM_SSP_CTRL1_DATA_CRC_IRQ_EN	0x00400000
-#define BM_SSP_CTRL1_DATA_CRC_IRQ	0x00800000
-#define BM_SSP_CTRL1_DATA_TIMEOUT_IRQ_EN	0x01000000
-#define BM_SSP_CTRL1_DATA_TIMEOUT_IRQ	0x02000000
-#define BM_SSP_CTRL1_RESP_TIMEOUT_IRQ_EN	0x04000000
-#define BM_SSP_CTRL1_RESP_TIMEOUT_IRQ	0x08000000
-#define BM_SSP_CTRL1_RESP_ERR_IRQ_EN	0x10000000
-#define BM_SSP_CTRL1_RESP_ERR_IRQ	0x20000000
-#define BM_SSP_CTRL1_SDIO_IRQ	0x80000000
-
-#define HW_SSP_DATA		0x70
-
-#define HW_SSP_SDRESP0		0x80
-
-#define HW_SSP_SDRESP1		0x90
-
-#define HW_SSP_SDRESP2		0xA0
-
-#define HW_SSP_SDRESP3		0xB0
-
-#define HW_SSP_STATUS		0xC0
-#define BM_SSP_STATUS_FIFO_EMPTY	0x00000020
-#define BM_SSP_STATUS_TIMEOUT	0x00001000
-#define BM_SSP_STATUS_RESP_TIMEOUT	0x00004000
-#define BM_SSP_STATUS_RESP_ERR	0x00008000
-#define BM_SSP_STATUS_RESP_CRC_ERR	0x00010000
-#define BM_SSP_STATUS_CARD_DETECT	0x10000000
diff -druN linux-2.6.39-libre/arch/arm/mach-stmp37xx/include/mach/regs-timrot.h linux-3.0-rc7-libre/arch/arm/mach-stmp37xx/include/mach/regs-timrot.h
--- linux-2.6.39-libre/arch/arm/mach-stmp37xx/include/mach/regs-timrot.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-stmp37xx/include/mach/regs-timrot.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,49 +0,0 @@
-/*
- * stmp37xx: TIMROT register definitions
- *
- * Copyright (c) 2008 Freescale Semiconductor
- * Copyright 2008 Embedded Alley Solutions, 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
- */
-#ifndef _MACH_REGS_TIMROT
-#define _MACH_REGS_TIMROT
-
-#define REGS_TIMROT_BASE	(STMP3XXX_REGS_BASE + 0x68000)
-
-#define HW_TIMROT_ROTCTRL	0x0
-#define BM_TIMROT_ROTCTRL_CLKGATE	0x40000000
-#define BM_TIMROT_ROTCTRL_SFTRST	0x80000000
-
-#define HW_TIMROT_TIMCTRL0	(0x20 + 0 * 0x20)
-#define HW_TIMROT_TIMCTRL1	(0x20 + 1 * 0x20)
-#define HW_TIMROT_TIMCTRL2	(0x20 + 2 * 0x20)
-
-#define HW_TIMROT_TIMCTRLn	0x20
-#define BM_TIMROT_TIMCTRLn_SELECT	0x0000000F
-#define BP_TIMROT_TIMCTRLn_SELECT	0
-#define BM_TIMROT_TIMCTRLn_PRESCALE	0x00000030
-#define BP_TIMROT_TIMCTRLn_PRESCALE	4
-#define BM_TIMROT_TIMCTRLn_RELOAD	0x00000040
-#define BM_TIMROT_TIMCTRLn_UPDATE	0x00000080
-#define BM_TIMROT_TIMCTRLn_IRQ_EN	0x00004000
-#define BM_TIMROT_TIMCTRLn_IRQ	0x00008000
-
-#define HW_TIMROT_TIMCOUNT0	(0x30 + 0 * 0x20)
-#define HW_TIMROT_TIMCOUNT1	(0x30 + 1 * 0x20)
-#define HW_TIMROT_TIMCOUNT2	(0x30 + 2 * 0x20)
-
-#define HW_TIMROT_TIMCOUNTn	0x30
-#endif
diff -druN linux-2.6.39-libre/arch/arm/mach-stmp37xx/include/mach/regs-uartapp.h linux-3.0-rc7-libre/arch/arm/mach-stmp37xx/include/mach/regs-uartapp.h
--- linux-2.6.39-libre/arch/arm/mach-stmp37xx/include/mach/regs-uartapp.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-stmp37xx/include/mach/regs-uartapp.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,85 +0,0 @@
-/*
- * stmp37xx: UARTAPP register definitions
- *
- * Copyright (c) 2008 Freescale Semiconductor
- * Copyright 2008 Embedded Alley Solutions, 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
- */
-#define REGS_UARTAPP_BASE	(STMP3XXX_REGS_BASE + 0x6C000)
-#define REGS_UARTAPP1_PHYS	0x8006C000
-#define REGS_UARTAPP_SIZE	0x2000
-
-#define HW_UARTAPP_CTRL0	0x0
-#define BM_UARTAPP_CTRL0_XFER_COUNT	0x0000FFFF
-#define BP_UARTAPP_CTRL0_XFER_COUNT	0
-#define BM_UARTAPP_CTRL0_RXTIMEOUT	0x07FF0000
-#define BP_UARTAPP_CTRL0_RXTIMEOUT	16
-#define BM_UARTAPP_CTRL0_RXTO_ENABLE	0x08000000
-#define BM_UARTAPP_CTRL0_RUN	0x20000000
-#define BM_UARTAPP_CTRL0_SFTRST	0x80000000
-#define BM_UARTAPP_CTRL1_XFER_COUNT	0x0000FFFF
-#define BP_UARTAPP_CTRL1_XFER_COUNT	0
-#define BM_UARTAPP_CTRL1_RUN	0x10000000
-
-#define HW_UARTAPP_CTRL2	0x20
-#define BM_UARTAPP_CTRL2_UARTEN	0x00000001
-#define BP_UARTAPP_CTRL2_UARTEN	0
-#define BM_UARTAPP_CTRL2_TXE	0x00000100
-#define BM_UARTAPP_CTRL2_RXE	0x00000200
-#define BM_UARTAPP_CTRL2_RTS	0x00000800
-#define BM_UARTAPP_CTRL2_RTSEN	0x00004000
-#define BM_UARTAPP_CTRL2_CTSEN	0x00008000
-#define BM_UARTAPP_CTRL2_RXDMAE	0x01000000
-#define BM_UARTAPP_CTRL2_TXDMAE	0x02000000
-#define BM_UARTAPP_CTRL2_DMAONERR	0x04000000
-
-#define HW_UARTAPP_LINECTRL	0x30
-#define BM_UARTAPP_LINECTRL_BRK	0x00000001
-#define BP_UARTAPP_LINECTRL_BRK	0
-#define BM_UARTAPP_LINECTRL_PEN	0x00000002
-#define BM_UARTAPP_LINECTRL_EPS	0x00000004
-#define BM_UARTAPP_LINECTRL_STP2	0x00000008
-#define BM_UARTAPP_LINECTRL_FEN	0x00000010
-#define BM_UARTAPP_LINECTRL_WLEN	0x00000060
-#define BP_UARTAPP_LINECTRL_WLEN	5
-#define BM_UARTAPP_LINECTRL_SPS	0x00000080
-#define BM_UARTAPP_LINECTRL_BAUD_DIVFRAC	0x00003F00
-#define BP_UARTAPP_LINECTRL_BAUD_DIVFRAC	8
-#define BM_UARTAPP_LINECTRL_BAUD_DIVINT	0xFFFF0000
-#define BP_UARTAPP_LINECTRL_BAUD_DIVINT	16
-
-#define HW_UARTAPP_INTR		0x50
-#define BM_UARTAPP_INTR_CTSMIS	0x00000002
-#define BM_UARTAPP_INTR_RTIS	0x00000040
-#define BM_UARTAPP_INTR_CTSMIEN	0x00020000
-#define BM_UARTAPP_INTR_RXIEN	0x00100000
-#define BM_UARTAPP_INTR_RTIEN	0x00400000
-
-#define HW_UARTAPP_DATA		0x60
-
-#define HW_UARTAPP_STAT		0x70
-#define BM_UARTAPP_STAT_RXCOUNT	0x0000FFFF
-#define BP_UARTAPP_STAT_RXCOUNT	0
-#define BM_UARTAPP_STAT_FERR	0x00010000
-#define BM_UARTAPP_STAT_PERR	0x00020000
-#define BM_UARTAPP_STAT_BERR	0x00040000
-#define BM_UARTAPP_STAT_OERR	0x00080000
-#define BM_UARTAPP_STAT_RXFE	0x01000000
-#define BM_UARTAPP_STAT_TXFF	0x02000000
-#define BM_UARTAPP_STAT_TXFE	0x08000000
-#define BM_UARTAPP_STAT_CTS	0x10000000
-
-#define HW_UARTAPP_VERSION	0x90
diff -druN linux-2.6.39-libre/arch/arm/mach-stmp37xx/include/mach/regs-uartdbg.h linux-3.0-rc7-libre/arch/arm/mach-stmp37xx/include/mach/regs-uartdbg.h
--- linux-2.6.39-libre/arch/arm/mach-stmp37xx/include/mach/regs-uartdbg.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-stmp37xx/include/mach/regs-uartdbg.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,268 +0,0 @@
-/*
- * stmp378x: UARTDBG register definitions
- *
- * Copyright (c) 2008 Freescale Semiconductor
- * Copyright 2008 Embedded Alley Solutions, 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
- */
-#define REGS_UARTDBG_BASE	(STMP3XXX_REGS_BASE + 0x70000)
-#define REGS_UARTDBG_PHYS	0x80070000
-#define REGS_UARTDBG_SIZE	0x2000
-
-#define HW_UARTDBGDR 0x00000000
-#define BP_UARTDBGDR_UNAVAILABLE      16
-#define BM_UARTDBGDR_UNAVAILABLE 0xFFFF0000
-#define BF_UARTDBGDR_UNAVAILABLE(v) \
-	(((v) << 16) & BM_UARTDBGDR_UNAVAILABLE)
-#define BP_UARTDBGDR_RESERVED      12
-#define BM_UARTDBGDR_RESERVED 0x0000F000
-#define BF_UARTDBGDR_RESERVED(v)  \
-	(((v) << 12) & BM_UARTDBGDR_RESERVED)
-#define BM_UARTDBGDR_OE 0x00000800
-#define BM_UARTDBGDR_BE 0x00000400
-#define BM_UARTDBGDR_PE 0x00000200
-#define BM_UARTDBGDR_FE 0x00000100
-#define BP_UARTDBGDR_DATA      0
-#define BM_UARTDBGDR_DATA 0x000000FF
-#define BF_UARTDBGDR_DATA(v)  \
-	(((v) << 0) & BM_UARTDBGDR_DATA)
-#define HW_UARTDBGRSR_ECR 0x00000004
-#define BP_UARTDBGRSR_ECR_UNAVAILABLE      8
-#define BM_UARTDBGRSR_ECR_UNAVAILABLE 0xFFFFFF00
-#define BF_UARTDBGRSR_ECR_UNAVAILABLE(v) \
-	(((v) << 8) & BM_UARTDBGRSR_ECR_UNAVAILABLE)
-#define BP_UARTDBGRSR_ECR_EC      4
-#define BM_UARTDBGRSR_ECR_EC 0x000000F0
-#define BF_UARTDBGRSR_ECR_EC(v)  \
-	(((v) << 4) & BM_UARTDBGRSR_ECR_EC)
-#define BM_UARTDBGRSR_ECR_OE 0x00000008
-#define BM_UARTDBGRSR_ECR_BE 0x00000004
-#define BM_UARTDBGRSR_ECR_PE 0x00000002
-#define BM_UARTDBGRSR_ECR_FE 0x00000001
-#define HW_UARTDBGFR 0x00000018
-#define BP_UARTDBGFR_UNAVAILABLE      16
-#define BM_UARTDBGFR_UNAVAILABLE 0xFFFF0000
-#define BF_UARTDBGFR_UNAVAILABLE(v) \
-	(((v) << 16) & BM_UARTDBGFR_UNAVAILABLE)
-#define BP_UARTDBGFR_RESERVED      9
-#define BM_UARTDBGFR_RESERVED 0x0000FE00
-#define BF_UARTDBGFR_RESERVED(v)  \
-	(((v) << 9) & BM_UARTDBGFR_RESERVED)
-#define BM_UARTDBGFR_RI 0x00000100
-#define BM_UARTDBGFR_TXFE 0x00000080
-#define BM_UARTDBGFR_RXFF 0x00000040
-#define BM_UARTDBGFR_TXFF 0x00000020
-#define BM_UARTDBGFR_RXFE 0x00000010
-#define BM_UARTDBGFR_BUSY 0x00000008
-#define BM_UARTDBGFR_DCD 0x00000004
-#define BM_UARTDBGFR_DSR 0x00000002
-#define BM_UARTDBGFR_CTS 0x00000001
-#define HW_UARTDBGILPR 0x00000020
-#define BP_UARTDBGILPR_UNAVAILABLE      8
-#define BM_UARTDBGILPR_UNAVAILABLE 0xFFFFFF00
-#define BF_UARTDBGILPR_UNAVAILABLE(v) \
-	(((v) << 8) & BM_UARTDBGILPR_UNAVAILABLE)
-#define BP_UARTDBGILPR_ILPDVSR      0
-#define BM_UARTDBGILPR_ILPDVSR 0x000000FF
-#define BF_UARTDBGILPR_ILPDVSR(v)  \
-	(((v) << 0) & BM_UARTDBGILPR_ILPDVSR)
-#define HW_UARTDBGIBRD 0x00000024
-#define BP_UARTDBGIBRD_UNAVAILABLE      16
-#define BM_UARTDBGIBRD_UNAVAILABLE 0xFFFF0000
-#define BF_UARTDBGIBRD_UNAVAILABLE(v) \
-	(((v) << 16) & BM_UARTDBGIBRD_UNAVAILABLE)
-#define BP_UARTDBGIBRD_BAUD_DIVINT      0
-#define BM_UARTDBGIBRD_BAUD_DIVINT 0x0000FFFF
-#define BF_UARTDBGIBRD_BAUD_DIVINT(v)  \
-	(((v) << 0) & BM_UARTDBGIBRD_BAUD_DIVINT)
-#define HW_UARTDBGFBRD 0x00000028
-#define BP_UARTDBGFBRD_UNAVAILABLE      8
-#define BM_UARTDBGFBRD_UNAVAILABLE 0xFFFFFF00
-#define BF_UARTDBGFBRD_UNAVAILABLE(v) \
-	(((v) << 8) & BM_UARTDBGFBRD_UNAVAILABLE)
-#define BP_UARTDBGFBRD_RESERVED      6
-#define BM_UARTDBGFBRD_RESERVED 0x000000C0
-#define BF_UARTDBGFBRD_RESERVED(v)  \
-	(((v) << 6) & BM_UARTDBGFBRD_RESERVED)
-#define BP_UARTDBGFBRD_BAUD_DIVFRAC      0
-#define BM_UARTDBGFBRD_BAUD_DIVFRAC 0x0000003F
-#define BF_UARTDBGFBRD_BAUD_DIVFRAC(v)  \
-	(((v) << 0) & BM_UARTDBGFBRD_BAUD_DIVFRAC)
-#define HW_UARTDBGLCR_H 0x0000002c
-#define BP_UARTDBGLCR_H_UNAVAILABLE      16
-#define BM_UARTDBGLCR_H_UNAVAILABLE 0xFFFF0000
-#define BF_UARTDBGLCR_H_UNAVAILABLE(v) \
-	(((v) << 16) & BM_UARTDBGLCR_H_UNAVAILABLE)
-#define BP_UARTDBGLCR_H_RESERVED      8
-#define BM_UARTDBGLCR_H_RESERVED 0x0000FF00
-#define BF_UARTDBGLCR_H_RESERVED(v)  \
-	(((v) << 8) & BM_UARTDBGLCR_H_RESERVED)
-#define BM_UARTDBGLCR_H_SPS 0x00000080
-#define BP_UARTDBGLCR_H_WLEN      5
-#define BM_UARTDBGLCR_H_WLEN 0x00000060
-#define BF_UARTDBGLCR_H_WLEN(v)  \
-	(((v) << 5) & BM_UARTDBGLCR_H_WLEN)
-#define BM_UARTDBGLCR_H_FEN 0x00000010
-#define BM_UARTDBGLCR_H_STP2 0x00000008
-#define BM_UARTDBGLCR_H_EPS 0x00000004
-#define BM_UARTDBGLCR_H_PEN 0x00000002
-#define BM_UARTDBGLCR_H_BRK 0x00000001
-#define HW_UARTDBGCR 0x00000030
-#define BP_UARTDBGCR_UNAVAILABLE      16
-#define BM_UARTDBGCR_UNAVAILABLE 0xFFFF0000
-#define BF_UARTDBGCR_UNAVAILABLE(v) \
-	(((v) << 16) & BM_UARTDBGCR_UNAVAILABLE)
-#define BM_UARTDBGCR_CTSEN 0x00008000
-#define BM_UARTDBGCR_RTSEN 0x00004000
-#define BM_UARTDBGCR_OUT2 0x00002000
-#define BM_UARTDBGCR_OUT1 0x00001000
-#define BM_UARTDBGCR_RTS 0x00000800
-#define BM_UARTDBGCR_DTR 0x00000400
-#define BM_UARTDBGCR_RXE 0x00000200
-#define BM_UARTDBGCR_TXE 0x00000100
-#define BM_UARTDBGCR_LBE 0x00000080
-#define BP_UARTDBGCR_RESERVED      3
-#define BM_UARTDBGCR_RESERVED 0x00000078
-#define BF_UARTDBGCR_RESERVED(v)  \
-	(((v) << 3) & BM_UARTDBGCR_RESERVED)
-#define BM_UARTDBGCR_SIRLP 0x00000004
-#define BM_UARTDBGCR_SIREN 0x00000002
-#define BM_UARTDBGCR_UARTEN 0x00000001
-#define HW_UARTDBGIFLS 0x00000034
-#define BP_UARTDBGIFLS_UNAVAILABLE      16
-#define BM_UARTDBGIFLS_UNAVAILABLE 0xFFFF0000
-#define BF_UARTDBGIFLS_UNAVAILABLE(v) \
-	(((v) << 16) & BM_UARTDBGIFLS_UNAVAILABLE)
-#define BP_UARTDBGIFLS_RESERVED      6
-#define BM_UARTDBGIFLS_RESERVED 0x0000FFC0
-#define BF_UARTDBGIFLS_RESERVED(v)  \
-	(((v) << 6) & BM_UARTDBGIFLS_RESERVED)
-#define BP_UARTDBGIFLS_RXIFLSEL      3
-#define BM_UARTDBGIFLS_RXIFLSEL 0x00000038
-#define BF_UARTDBGIFLS_RXIFLSEL(v)  \
-	(((v) << 3) & BM_UARTDBGIFLS_RXIFLSEL)
-#define BV_UARTDBGIFLS_RXIFLSEL__NOT_EMPTY      0x0
-#define BV_UARTDBGIFLS_RXIFLSEL__ONE_QUARTER    0x1
-#define BV_UARTDBGIFLS_RXIFLSEL__ONE_HALF       0x2
-#define BV_UARTDBGIFLS_RXIFLSEL__THREE_QUARTERS 0x3
-#define BV_UARTDBGIFLS_RXIFLSEL__SEVEN_EIGHTHS  0x4
-#define BV_UARTDBGIFLS_RXIFLSEL__INVALID5       0x5
-#define BV_UARTDBGIFLS_RXIFLSEL__INVALID6       0x6
-#define BV_UARTDBGIFLS_RXIFLSEL__INVALID7       0x7
-#define BP_UARTDBGIFLS_TXIFLSEL      0
-#define BM_UARTDBGIFLS_TXIFLSEL 0x00000007
-#define BF_UARTDBGIFLS_TXIFLSEL(v)  \
-	(((v) << 0) & BM_UARTDBGIFLS_TXIFLSEL)
-#define BV_UARTDBGIFLS_TXIFLSEL__EMPTY	  0x0
-#define BV_UARTDBGIFLS_TXIFLSEL__ONE_QUARTER    0x1
-#define BV_UARTDBGIFLS_TXIFLSEL__ONE_HALF       0x2
-#define BV_UARTDBGIFLS_TXIFLSEL__THREE_QUARTERS 0x3
-#define BV_UARTDBGIFLS_TXIFLSEL__SEVEN_EIGHTHS  0x4
-#define BV_UARTDBGIFLS_TXIFLSEL__INVALID5       0x5
-#define BV_UARTDBGIFLS_TXIFLSEL__INVALID6       0x6
-#define BV_UARTDBGIFLS_TXIFLSEL__INVALID7       0x7
-#define HW_UARTDBGIMSC 0x00000038
-#define BP_UARTDBGIMSC_UNAVAILABLE      16
-#define BM_UARTDBGIMSC_UNAVAILABLE 0xFFFF0000
-#define BF_UARTDBGIMSC_UNAVAILABLE(v) \
-	(((v) << 16) & BM_UARTDBGIMSC_UNAVAILABLE)
-#define BP_UARTDBGIMSC_RESERVED      11
-#define BM_UARTDBGIMSC_RESERVED 0x0000F800
-#define BF_UARTDBGIMSC_RESERVED(v)  \
-	(((v) << 11) & BM_UARTDBGIMSC_RESERVED)
-#define BM_UARTDBGIMSC_OEIM 0x00000400
-#define BM_UARTDBGIMSC_BEIM 0x00000200
-#define BM_UARTDBGIMSC_PEIM 0x00000100
-#define BM_UARTDBGIMSC_FEIM 0x00000080
-#define BM_UARTDBGIMSC_RTIM 0x00000040
-#define BM_UARTDBGIMSC_TXIM 0x00000020
-#define BM_UARTDBGIMSC_RXIM 0x00000010
-#define BM_UARTDBGIMSC_DSRMIM 0x00000008
-#define BM_UARTDBGIMSC_DCDMIM 0x00000004
-#define BM_UARTDBGIMSC_CTSMIM 0x00000002
-#define BM_UARTDBGIMSC_RIMIM 0x00000001
-#define HW_UARTDBGRIS 0x0000003c
-#define BP_UARTDBGRIS_UNAVAILABLE      16
-#define BM_UARTDBGRIS_UNAVAILABLE 0xFFFF0000
-#define BF_UARTDBGRIS_UNAVAILABLE(v) \
-	(((v) << 16) & BM_UARTDBGRIS_UNAVAILABLE)
-#define BP_UARTDBGRIS_RESERVED      11
-#define BM_UARTDBGRIS_RESERVED 0x0000F800
-#define BF_UARTDBGRIS_RESERVED(v)  \
-	(((v) << 11) & BM_UARTDBGRIS_RESERVED)
-#define BM_UARTDBGRIS_OERIS 0x00000400
-#define BM_UARTDBGRIS_BERIS 0x00000200
-#define BM_UARTDBGRIS_PERIS 0x00000100
-#define BM_UARTDBGRIS_FERIS 0x00000080
-#define BM_UARTDBGRIS_RTRIS 0x00000040
-#define BM_UARTDBGRIS_TXRIS 0x00000020
-#define BM_UARTDBGRIS_RXRIS 0x00000010
-#define BM_UARTDBGRIS_DSRRMIS 0x00000008
-#define BM_UARTDBGRIS_DCDRMIS 0x00000004
-#define BM_UARTDBGRIS_CTSRMIS 0x00000002
-#define BM_UARTDBGRIS_RIRMIS 0x00000001
-#define HW_UARTDBGMIS 0x00000040
-#define BP_UARTDBGMIS_UNAVAILABLE      16
-#define BM_UARTDBGMIS_UNAVAILABLE 0xFFFF0000
-#define BF_UARTDBGMIS_UNAVAILABLE(v) \
-	(((v) << 16) & BM_UARTDBGMIS_UNAVAILABLE)
-#define BP_UARTDBGMIS_RESERVED      11
-#define BM_UARTDBGMIS_RESERVED 0x0000F800
-#define BF_UARTDBGMIS_RESERVED(v)  \
-	(((v) << 11) & BM_UARTDBGMIS_RESERVED)
-#define BM_UARTDBGMIS_OEMIS 0x00000400
-#define BM_UARTDBGMIS_BEMIS 0x00000200
-#define BM_UARTDBGMIS_PEMIS 0x00000100
-#define BM_UARTDBGMIS_FEMIS 0x00000080
-#define BM_UARTDBGMIS_RTMIS 0x00000040
-#define BM_UARTDBGMIS_TXMIS 0x00000020
-#define BM_UARTDBGMIS_RXMIS 0x00000010
-#define BM_UARTDBGMIS_DSRMMIS 0x00000008
-#define BM_UARTDBGMIS_DCDMMIS 0x00000004
-#define BM_UARTDBGMIS_CTSMMIS 0x00000002
-#define BM_UARTDBGMIS_RIMMIS 0x00000001
-#define HW_UARTDBGICR 0x00000044
-#define BP_UARTDBGICR_UNAVAILABLE      16
-#define BM_UARTDBGICR_UNAVAILABLE 0xFFFF0000
-#define BF_UARTDBGICR_UNAVAILABLE(v) \
-	(((v) << 16) & BM_UARTDBGICR_UNAVAILABLE)
-#define BP_UARTDBGICR_RESERVED      11
-#define BM_UARTDBGICR_RESERVED 0x0000F800
-#define BF_UARTDBGICR_RESERVED(v)  \
-	(((v) << 11) & BM_UARTDBGICR_RESERVED)
-#define BM_UARTDBGICR_OEIC 0x00000400
-#define BM_UARTDBGICR_BEIC 0x00000200
-#define BM_UARTDBGICR_PEIC 0x00000100
-#define BM_UARTDBGICR_FEIC 0x00000080
-#define BM_UARTDBGICR_RTIC 0x00000040
-#define BM_UARTDBGICR_TXIC 0x00000020
-#define BM_UARTDBGICR_RXIC 0x00000010
-#define BM_UARTDBGICR_DSRMIC 0x00000008
-#define BM_UARTDBGICR_DCDMIC 0x00000004
-#define BM_UARTDBGICR_CTSMIC 0x00000002
-#define BM_UARTDBGICR_RIMIC 0x00000001
-#define HW_UARTDBGDMACR 0x00000048
-#define BP_UARTDBGDMACR_UNAVAILABLE      16
-#define BM_UARTDBGDMACR_UNAVAILABLE 0xFFFF0000
-#define BF_UARTDBGDMACR_UNAVAILABLE(v) \
-	(((v) << 16) & BM_UARTDBGDMACR_UNAVAILABLE)
-#define BP_UARTDBGDMACR_RESERVED      3
-#define BM_UARTDBGDMACR_RESERVED 0x0000FFF8
-#define BF_UARTDBGDMACR_RESERVED(v)  \
-	(((v) << 3) & BM_UARTDBGDMACR_RESERVED)
-#define BM_UARTDBGDMACR_DMAONERR 0x00000004
-#define BM_UARTDBGDMACR_TXDMAE 0x00000002
-#define BM_UARTDBGDMACR_RXDMAE 0x00000001
diff -druN linux-2.6.39-libre/arch/arm/mach-stmp37xx/include/mach/regs-usbctl.h linux-3.0-rc7-libre/arch/arm/mach-stmp37xx/include/mach/regs-usbctl.h
--- linux-2.6.39-libre/arch/arm/mach-stmp37xx/include/mach/regs-usbctl.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-stmp37xx/include/mach/regs-usbctl.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,22 +0,0 @@
-/*
- * stmp37xx: USBCTL register definitions
- *
- * Copyright (c) 2008 Freescale Semiconductor
- * Copyright 2008 Embedded Alley Solutions, 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
- */
-#define REGS_USBCTL_BASE	(STMP3XXX_REGS_BASE + 0x80000)
-#define REGS_USBCTL_PHYS	0x80000
diff -druN linux-2.6.39-libre/arch/arm/mach-stmp37xx/include/mach/regs-usbctrl.h linux-3.0-rc7-libre/arch/arm/mach-stmp37xx/include/mach/regs-usbctrl.h
--- linux-2.6.39-libre/arch/arm/mach-stmp37xx/include/mach/regs-usbctrl.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-stmp37xx/include/mach/regs-usbctrl.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,22 +0,0 @@
-/*
- * stmp37xx: USBCTRL register definitions
- *
- * Copyright (c) 2008 Freescale Semiconductor
- * Copyright 2008 Embedded Alley Solutions, 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
- */
-#define REGS_USBCTRL_BASE	(STMP3XXX_REGS_BASE + 0x80000)
-#define REGS_USBCTRL_PHYS	0x80080000
diff -druN linux-2.6.39-libre/arch/arm/mach-stmp37xx/include/mach/regs-usbphy.h linux-3.0-rc7-libre/arch/arm/mach-stmp37xx/include/mach/regs-usbphy.h
--- linux-2.6.39-libre/arch/arm/mach-stmp37xx/include/mach/regs-usbphy.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-stmp37xx/include/mach/regs-usbphy.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,37 +0,0 @@
-/*
- * stmp37xx: USBPHY register definitions
- *
- * Copyright (c) 2008 Freescale Semiconductor
- * Copyright 2008 Embedded Alley Solutions, 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
- */
-#define REGS_USBPHY_BASE	(STMP3XXX_REGS_BASE + 0x7C000)
-
-#define HW_USBPHY_PWD		0x0
-
-#define HW_USBPHY_CTRL		0x30
-#define BM_USBPHY_CTRL_ENHSPRECHARGEXMIT	0x00000001
-#define BP_USBPHY_CTRL_ENHSPRECHARGEXMIT	0
-#define BM_USBPHY_CTRL_ENHOSTDISCONDETECT	0x00000002
-#define BM_USBPHY_CTRL_ENDEVPLUGINDETECT	0x00000010
-#define BM_USBPHY_CTRL_ENOTGIDDETECT	0x00000080
-#define BM_USBPHY_CTRL_ENIRQDEVPLUGIN	0x00000800
-#define BM_USBPHY_CTRL_CLKGATE	0x40000000
-#define BM_USBPHY_CTRL_SFTRST	0x80000000
-
-#define HW_USBPHY_STATUS	0x40
-#define BM_USBPHY_STATUS_DEVPLUGIN_STATUS	0x00000040
-#define BM_USBPHY_STATUS_OTGID_STATUS	0x00000100
diff -druN linux-2.6.39-libre/arch/arm/mach-stmp37xx/Makefile linux-3.0-rc7-libre/arch/arm/mach-stmp37xx/Makefile
--- linux-2.6.39-libre/arch/arm/mach-stmp37xx/Makefile	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-stmp37xx/Makefile	1969-12-31 19:00:00.000000000 -0500
@@ -1,2 +0,0 @@
-obj-$(CONFIG_ARCH_STMP37XX) += stmp37xx.o
-obj-$(CONFIG_MACH_STMP37XX) += stmp37xx_devb.o
diff -druN linux-2.6.39-libre/arch/arm/mach-stmp37xx/Makefile.boot linux-3.0-rc7-libre/arch/arm/mach-stmp37xx/Makefile.boot
--- linux-2.6.39-libre/arch/arm/mach-stmp37xx/Makefile.boot	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-stmp37xx/Makefile.boot	1969-12-31 19:00:00.000000000 -0500
@@ -1,3 +0,0 @@
-   zreladdr-y	:= 0x40008000
-params_phys-y	:= 0x40000100
-initrd_phys-y	:= 0x40800000
diff -druN linux-2.6.39-libre/arch/arm/mach-stmp37xx/stmp37xx.c linux-3.0-rc7-libre/arch/arm/mach-stmp37xx/stmp37xx.c
--- linux-2.6.39-libre/arch/arm/mach-stmp37xx/stmp37xx.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-stmp37xx/stmp37xx.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,219 +0,0 @@
-/*
- * Freescale STMP37XX platform support
- *
- * Embedded Alley Solutions, Inc <source@embeddedalley.com>
- *
- * Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved.
- * Copyright 2008 Embedded Alley Solutions, 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/types.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/device.h>
-#include <linux/platform_device.h>
-#include <linux/irq.h>
-#include <linux/io.h>
-
-#include <asm/setup.h>
-#include <asm/mach-types.h>
-
-#include <asm/mach/arch.h>
-#include <asm/mach/irq.h>
-#include <asm/mach/map.h>
-#include <asm/mach/time.h>
-
-#include <mach/stmp3xxx.h>
-#include <mach/dma.h>
-
-#include <mach/platform.h>
-#include <mach/regs-icoll.h>
-#include <mach/regs-apbh.h>
-#include <mach/regs-apbx.h>
-#include "stmp37xx.h"
-
-/*
- * IRQ handling
- */
-static void stmp37xx_ack_irq(struct irq_data *d)
-{
-	/* Disable IRQ */
-	stmp3xxx_clearl(0x04 << ((d->irq % 4) * 8),
-		REGS_ICOLL_BASE + HW_ICOLL_PRIORITYn + d->irq / 4 * 0x10);
-
-	/* ACK current interrupt */
-	__raw_writel(1, REGS_ICOLL_BASE + HW_ICOLL_LEVELACK);
-
-	/* Barrier */
-	(void)__raw_readl(REGS_ICOLL_BASE + HW_ICOLL_STAT);
-}
-
-static void stmp37xx_mask_irq(struct irq_data *d)
-{
-	/* IRQ disable */
-	stmp3xxx_clearl(0x04 << ((d->irq % 4) * 8),
-		REGS_ICOLL_BASE + HW_ICOLL_PRIORITYn + d->irq / 4 * 0x10);
-}
-
-static void stmp37xx_unmask_irq(struct irq_data *d)
-{
-	/* IRQ enable */
-	stmp3xxx_setl(0x04 << ((d->irq % 4) * 8),
-		REGS_ICOLL_BASE + HW_ICOLL_PRIORITYn + d->irq / 4 * 0x10);
-}
-
-static struct irq_chip stmp37xx_chip = {
-	.irq_ack	= stmp37xx_ack_irq,
-	.irq_mask	= stmp37xx_mask_irq,
-	.irq_unmask	= stmp37xx_unmask_irq,
-};
-
-void __init stmp37xx_init_irq(void)
-{
-	stmp3xxx_init_irq(&stmp37xx_chip);
-}
-
-/*
- * DMA interrupt handling
- */
-void stmp3xxx_arch_dma_enable_interrupt(int channel)
-{
-	switch (STMP3XXX_DMA_BUS(channel)) {
-	case STMP3XXX_BUS_APBH:
-		stmp3xxx_setl(1 << (8 + STMP3XXX_DMA_CHANNEL(channel)),
-			REGS_APBH_BASE + HW_APBH_CTRL1);
-		break;
-
-	case STMP3XXX_BUS_APBX:
-		stmp3xxx_setl(1 << (8 + STMP3XXX_DMA_CHANNEL(channel)),
-			REGS_APBX_BASE + HW_APBX_CTRL1);
-		break;
-	}
-}
-EXPORT_SYMBOL(stmp3xxx_arch_dma_enable_interrupt);
-
-void stmp3xxx_arch_dma_clear_interrupt(int channel)
-{
-	switch (STMP3XXX_DMA_BUS(channel)) {
-	case STMP3XXX_BUS_APBH:
-		stmp3xxx_clearl(1 << STMP3XXX_DMA_CHANNEL(channel),
-				REGS_APBH_BASE + HW_APBH_CTRL1);
-		break;
-
-	case STMP3XXX_BUS_APBX:
-		stmp3xxx_clearl(1 << STMP3XXX_DMA_CHANNEL(channel),
-				REGS_APBX_BASE + HW_APBX_CTRL1);
-		break;
-	}
-}
-EXPORT_SYMBOL(stmp3xxx_arch_dma_clear_interrupt);
-
-int stmp3xxx_arch_dma_is_interrupt(int channel)
-{
-	int r = 0;
-
-	switch (STMP3XXX_DMA_BUS(channel)) {
-	case STMP3XXX_BUS_APBH:
-		r = __raw_readl(REGS_APBH_BASE + HW_APBH_CTRL1) &
-			(1 << STMP3XXX_DMA_CHANNEL(channel));
-		break;
-
-	case STMP3XXX_BUS_APBX:
-		r = __raw_readl(REGS_APBH_BASE + HW_APBH_CTRL1) &
-			(1 << STMP3XXX_DMA_CHANNEL(channel));
-		break;
-	}
-	return r;
-}
-EXPORT_SYMBOL(stmp3xxx_arch_dma_is_interrupt);
-
-void stmp3xxx_arch_dma_reset_channel(int channel)
-{
-	unsigned chbit = 1 << STMP3XXX_DMA_CHANNEL(channel);
-
-	switch (STMP3XXX_DMA_BUS(channel)) {
-	case STMP3XXX_BUS_APBH:
-		/* Reset channel and wait for it to complete */
-		stmp3xxx_setl(chbit << BP_APBH_CTRL0_RESET_CHANNEL,
-			REGS_APBH_BASE + HW_APBH_CTRL0);
-		while (__raw_readl(REGS_APBH_BASE + HW_APBH_CTRL0) &
-		       (chbit << BP_APBH_CTRL0_RESET_CHANNEL))
-				cpu_relax();
-		break;
-
-	case STMP3XXX_BUS_APBX:
-		stmp3xxx_setl(chbit << BP_APBX_CTRL0_RESET_CHANNEL,
-			REGS_APBX_BASE + HW_APBX_CTRL0);
-		while (__raw_readl(REGS_APBX_BASE + HW_APBX_CTRL0) &
-		       (chbit << BP_APBX_CTRL0_RESET_CHANNEL))
-				cpu_relax();
-		break;
-	}
-}
-EXPORT_SYMBOL(stmp3xxx_arch_dma_reset_channel);
-
-void stmp3xxx_arch_dma_freeze(int channel)
-{
-	unsigned chbit = 1 << STMP3XXX_DMA_CHANNEL(channel);
-
-	switch (STMP3XXX_DMA_BUS(channel)) {
-	case STMP3XXX_BUS_APBH:
-		stmp3xxx_setl(1 << chbit, REGS_APBH_BASE + HW_APBH_CTRL0);
-		break;
-	case STMP3XXX_BUS_APBX:
-		stmp3xxx_setl(1 << chbit, REGS_APBH_BASE + HW_APBH_CTRL0);
-		break;
-	}
-}
-EXPORT_SYMBOL(stmp3xxx_arch_dma_freeze);
-
-void stmp3xxx_arch_dma_unfreeze(int channel)
-{
-	unsigned chbit = 1 << STMP3XXX_DMA_CHANNEL(channel);
-
-	switch (STMP3XXX_DMA_BUS(channel)) {
-	case STMP3XXX_BUS_APBH:
-		stmp3xxx_clearl(1 << chbit, REGS_APBH_BASE + HW_APBH_CTRL0);
-		break;
-	case STMP3XXX_BUS_APBX:
-		stmp3xxx_clearl(1 << chbit, REGS_APBH_BASE + HW_APBH_CTRL0);
-		break;
-	}
-}
-EXPORT_SYMBOL(stmp3xxx_arch_dma_unfreeze);
-
-/*
- * The registers are all very closely mapped, so we might as well map them all
- * with a single mapping
- *
- * Logical      Physical
- * f0000000	80000000	On-chip registers
- * f1000000	00000000	32k on-chip SRAM
- */
-static struct map_desc stmp37xx_io_desc[] __initdata = {
-	{
-		.virtual	= (u32)STMP3XXX_REGS_BASE,
-		.pfn		= __phys_to_pfn(STMP3XXX_REGS_PHBASE),
-		.length		= SZ_1M,
-		.type		= MT_DEVICE
-	},
-	{
-		.virtual	= (u32)STMP3XXX_OCRAM_BASE,
-		.pfn		= __phys_to_pfn(STMP3XXX_OCRAM_PHBASE),
-		.length		= STMP3XXX_OCRAM_SIZE,
-		.type		= MT_DEVICE,
-	},
-};
-
-void __init stmp37xx_map_io(void)
-{
-	iotable_init(stmp37xx_io_desc, ARRAY_SIZE(stmp37xx_io_desc));
-}
diff -druN linux-2.6.39-libre/arch/arm/mach-stmp37xx/stmp37xx_devb.c linux-3.0-rc7-libre/arch/arm/mach-stmp37xx/stmp37xx_devb.c
--- linux-2.6.39-libre/arch/arm/mach-stmp37xx/stmp37xx_devb.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-stmp37xx/stmp37xx_devb.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,99 +0,0 @@
-/*
- * Freescale STMP37XX development board support
- *
- * Embedded Alley Solutions, Inc <source@embeddedalley.com>
- *
- * Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved.
- * Copyright 2008 Embedded Alley Solutions, 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/kernel.h>
-#include <linux/init.h>
-#include <linux/device.h>
-#include <linux/platform_device.h>
-#include <asm/setup.h>
-#include <asm/mach-types.h>
-#include <asm/mach/arch.h>
-
-#include <mach/stmp3xxx.h>
-#include <mach/pins.h>
-#include <mach/pinmux.h>
-#include "stmp37xx.h"
-
-/*
- * List of STMP37xx development board specific devices
- */
-static struct platform_device *stmp37xx_devb_devices[] = {
-	&stmp3xxx_dbguart,
-	&stmp3xxx_appuart,
-};
-
-static struct pin_desc dbguart_pins_0[] = {
-	{ PINID_PWM0, PIN_FUN3, },
-	{ PINID_PWM1, PIN_FUN3, },
-};
-
-struct pin_desc appuart_pins_0[] = {
-	{ PINID_UART2_CTS, PIN_FUN1, PIN_4MA, PIN_1_8V, 0, },
-	{ PINID_UART2_RTS, PIN_FUN1, PIN_4MA, PIN_1_8V, 0, },
-	{ PINID_UART2_RX, PIN_FUN1, PIN_4MA, PIN_1_8V, 0, },
-	{ PINID_UART2_TX, PIN_FUN1, PIN_4MA, PIN_1_8V, 0, },
-};
-
-static struct pin_group appuart_pins[] = {
-	[0] = {
-		.pins		= appuart_pins_0,
-		.nr_pins	= ARRAY_SIZE(appuart_pins_0),
-	},
-	/* 37xx has the only app uart */
-};
-
-static struct pin_group dbguart_pins[] = {
-	[0] = {
-		.pins		= dbguart_pins_0,
-		.nr_pins	= ARRAY_SIZE(dbguart_pins_0),
-	},
-};
-
-static int dbguart_pins_control(int id, int request)
-{
-	int r = 0;
-
-	if (request)
-		r = stmp3xxx_request_pin_group(&dbguart_pins[id], "debug uart");
-	else
-		stmp3xxx_release_pin_group(&dbguart_pins[id], "debug uart");
-	return r;
-}
-
-
-static void __init stmp37xx_devb_init(void)
-{
-	stmp3xxx_pinmux_init(NR_REAL_IRQS);
-
-	/* Init STMP3xxx platform */
-	stmp3xxx_init();
-
-	stmp3xxx_dbguart.dev.platform_data = dbguart_pins_control;
-	stmp3xxx_appuart.dev.platform_data = appuart_pins;
-
-	/* Add STMP37xx development board devices */
-	platform_add_devices(stmp37xx_devb_devices,
-			ARRAY_SIZE(stmp37xx_devb_devices));
-}
-
-MACHINE_START(STMP37XX, "STMP37XX")
-	.boot_params	= 0x40000100,
-	.map_io		= stmp37xx_map_io,
-	.init_irq	= stmp37xx_init_irq,
-	.timer		= &stmp3xxx_timer,
-	.init_machine	= stmp37xx_devb_init,
-MACHINE_END
diff -druN linux-2.6.39-libre/arch/arm/mach-stmp37xx/stmp37xx.h linux-3.0-rc7-libre/arch/arm/mach-stmp37xx/stmp37xx.h
--- linux-2.6.39-libre/arch/arm/mach-stmp37xx/stmp37xx.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-stmp37xx/stmp37xx.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,24 +0,0 @@
-/*
- * Freescale STMP37XX/STMP378X internal functions and data declarations
- *
- * Embedded Alley Solutions, Inc <source@embeddedalley.com>
- *
- * Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved.
- * Copyright 2008 Embedded Alley Solutions, 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 __MACH_STMP37XX_H
-#define __MACH_STMP37XX_H
-
-void stmp37xx_map_io(void);
-void stmp37xx_init_irq(void);
-
-#endif /* __MACH_STMP37XX_H */
diff -druN linux-2.6.39-libre/arch/arm/mach-tcc8k/time.c linux-3.0-rc7-libre/arch/arm/mach-tcc8k/time.c
--- linux-2.6.39-libre/arch/arm/mach-tcc8k/time.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-tcc8k/time.c	2011-07-11 19:51:52.000000000 -0400
@@ -25,19 +25,6 @@
 
 static void __iomem *timer_base;
 
-static cycle_t tcc_get_cycles(struct clocksource *cs)
-{
-	return __raw_readl(timer_base + TC32MCNT_OFFS);
-}
-
-static struct clocksource clocksource_tcc = {
-	.name		= "tcc_tc32",
-	.rating		= 200,
-	.read		= tcc_get_cycles,
-	.mask		= CLOCKSOURCE_MASK(32),
-	.flags		= CLOCK_SOURCE_IS_CONTINUOUS,
-};
-
 static int tcc_set_next_event(unsigned long evt,
 			      struct clock_event_device *unused)
 {
@@ -102,7 +89,8 @@
 {
 	unsigned int c = clk_get_rate(clock);
 
-	clocksource_register_hz(&clocksource_tcc, c);
+	clocksource_mmio_init(timer_base + TC32MCNT_OFFS, "tcc_tc32", c,
+		200, 32, clocksource_mmio_readl_up);
 
 	clockevent_tcc.mult = div_sc(c, NSEC_PER_SEC,
 					clockevent_tcc.shift);
diff -druN linux-2.6.39-libre/arch/arm/mach-tegra/board-harmony.c linux-3.0-rc7-libre/arch/arm/mach-tegra/board-harmony.c
--- linux-2.6.39-libre/arch/arm/mach-tegra/board-harmony.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-tegra/board-harmony.c	2011-07-11 19:51:52.000000000 -0400
@@ -34,7 +34,7 @@
 #include <asm/mach/time.h>
 #include <asm/setup.h>
 
-#include <mach/harmony_audio.h>
+#include <mach/tegra_wm8903_pdata.h>
 #include <mach/iomap.h>
 #include <mach/irqs.h>
 #include <mach/sdhci.h>
@@ -67,15 +67,16 @@
 	},
 };
 
-static struct harmony_audio_platform_data harmony_audio_pdata = {
+static struct tegra_wm8903_platform_data harmony_audio_pdata = {
 	.gpio_spkr_en		= TEGRA_GPIO_SPKR_EN,
 	.gpio_hp_det		= TEGRA_GPIO_HP_DET,
+	.gpio_hp_mute		= -1,
 	.gpio_int_mic_en	= TEGRA_GPIO_INT_MIC_EN,
 	.gpio_ext_mic_en	= TEGRA_GPIO_EXT_MIC_EN,
 };
 
 static struct platform_device harmony_audio_device = {
-	.name	= "tegra-snd-harmony",
+	.name	= "tegra-snd-wm8903",
 	.id	= 0,
 	.dev	= {
 		.platform_data  = &harmony_audio_pdata,
diff -druN linux-2.6.39-libre/arch/arm/mach-tegra/board-harmony.h linux-3.0-rc7-libre/arch/arm/mach-tegra/board-harmony.h
--- linux-2.6.39-libre/arch/arm/mach-tegra/board-harmony.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-tegra/board-harmony.h	2011-07-11 19:51:52.000000000 -0400
@@ -17,7 +17,8 @@
 #ifndef _MACH_TEGRA_BOARD_HARMONY_H
 #define _MACH_TEGRA_BOARD_HARMONY_H
 
-#define HARMONY_GPIO_WM8903(_x_)	(TEGRA_NR_GPIOS + (_x_))
+#define HARMONY_GPIO_TPS6586X(_x_)	(TEGRA_NR_GPIOS + (_x_))
+#define HARMONY_GPIO_WM8903(_x_)	(HARMONY_GPIO_TPS6586X(4) + (_x_))
 
 #define TEGRA_GPIO_SD2_CD		TEGRA_GPIO_PI5
 #define TEGRA_GPIO_SD2_WP		TEGRA_GPIO_PH1
diff -druN linux-2.6.39-libre/arch/arm/mach-tegra/board-harmony-power.c linux-3.0-rc7-libre/arch/arm/mach-tegra/board-harmony-power.c
--- linux-2.6.39-libre/arch/arm/mach-tegra/board-harmony-power.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-tegra/board-harmony-power.c	2011-07-11 19:51:52.000000000 -0400
@@ -24,6 +24,8 @@
 
 #include <mach/irqs.h>
 
+#include "board-harmony.h"
+
 #define PMC_CTRL		0x0
 #define PMC_CTRL_INTR_LOW	(1 << 17)
 
@@ -98,7 +100,7 @@
 	.irq_base	= TEGRA_NR_IRQS,
 	.num_subdevs	= ARRAY_SIZE(tps_devs),
 	.subdevs	= tps_devs,
-	.gpio_base	= TEGRA_NR_GPIOS,
+	.gpio_base	= HARMONY_GPIO_TPS6586X(0),
 };
 
 static struct i2c_board_info __initdata harmony_regulators[] = {
diff -druN linux-2.6.39-libre/arch/arm/mach-tegra/gpio.c linux-3.0-rc7-libre/arch/arm/mach-tegra/gpio.c
--- linux-2.6.39-libre/arch/arm/mach-tegra/gpio.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-tegra/gpio.c	2011-07-11 19:51:52.000000000 -0400
@@ -24,6 +24,8 @@
 #include <linux/io.h>
 #include <linux/gpio.h>
 
+#include <asm/mach/irq.h>
+
 #include <mach/iomap.h>
 #include <mach/suspend.h>
 
@@ -221,8 +223,9 @@
 	int port;
 	int pin;
 	int unmasked = 0;
+	struct irq_chip *chip = irq_desc_get_chip(desc);
 
-	desc->irq_data.chip->irq_ack(&desc->irq_data);
+	chained_irq_enter(chip, desc);
 
 	bank = irq_get_handler_data(irq);
 
@@ -241,7 +244,7 @@
 			 */
 			if (lvl & (0x100 << pin)) {
 				unmasked = 1;
-				desc->irq_data.chip->irq_unmask(&desc->irq_data);
+				chained_irq_exit(chip, desc);
 			}
 
 			generic_handle_irq(gpio_to_irq(gpio + pin));
@@ -249,7 +252,7 @@
 	}
 
 	if (!unmasked)
-		desc->irq_data.chip->irq_unmask(&desc->irq_data);
+		chained_irq_exit(chip, desc);
 
 }
 
diff -druN linux-2.6.39-libre/arch/arm/mach-tegra/include/mach/harmony_audio.h linux-3.0-rc7-libre/arch/arm/mach-tegra/include/mach/harmony_audio.h
--- linux-2.6.39-libre/arch/arm/mach-tegra/include/mach/harmony_audio.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-tegra/include/mach/harmony_audio.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,22 +0,0 @@
-/*
- * arch/arm/mach-tegra/include/mach/harmony_audio.h
- *
- * Copyright 2011 NVIDIA, 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.
- *
- */
-
-struct harmony_audio_platform_data {
-	int gpio_spkr_en;
-	int gpio_hp_det;
-	int gpio_int_mic_en;
-	int gpio_ext_mic_en;
-};
diff -druN linux-2.6.39-libre/arch/arm/mach-tegra/include/mach/kbc.h linux-3.0-rc7-libre/arch/arm/mach-tegra/include/mach/kbc.h
--- linux-2.6.39-libre/arch/arm/mach-tegra/include/mach/kbc.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-tegra/include/mach/kbc.h	2011-07-11 19:51:52.000000000 -0400
@@ -50,13 +50,11 @@
 	unsigned int debounce_cnt;
 	unsigned int repeat_cnt;
 
-	unsigned int wake_cnt; /* 0:wake on any key >1:wake on wake_cfg */
-	const struct tegra_kbc_wake_key *wake_cfg;
-
 	struct tegra_kbc_pin_cfg pin_cfg[KBC_MAX_GPIO];
 	const struct matrix_keymap_data *keymap_data;
 
 	bool wakeup;
 	bool use_fn_map;
+	bool use_ghost_filter;
 };
 #endif
diff -druN linux-2.6.39-libre/arch/arm/mach-tegra/include/mach/legacy_irq.h linux-3.0-rc7-libre/arch/arm/mach-tegra/include/mach/legacy_irq.h
--- linux-2.6.39-libre/arch/arm/mach-tegra/include/mach/legacy_irq.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-tegra/include/mach/legacy_irq.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,35 +0,0 @@
-/*
- * arch/arm/mach-tegra/include/mach/legacy_irq.h
- *
- * Copyright (C) 2010 Google, Inc.
- * Author: Colin Cross <ccross@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 _ARCH_ARM_MACH_TEGRA_LEGARY_IRQ_H
-#define _ARCH_ARM_MACH_TEGRA_LEGARY_IRQ_H
-
-void tegra_legacy_mask_irq(unsigned int irq);
-void tegra_legacy_unmask_irq(unsigned int irq);
-void tegra_legacy_select_fiq(unsigned int irq, bool fiq);
-void tegra_legacy_force_irq_set(unsigned int irq);
-void tegra_legacy_force_irq_clr(unsigned int irq);
-int tegra_legacy_force_irq_status(unsigned int irq);
-void tegra_legacy_select_fiq(unsigned int irq, bool fiq);
-unsigned long tegra_legacy_vfiq(int nr);
-unsigned long tegra_legacy_class(int nr);
-int tegra_legacy_irq_set_wake(int irq, int enable);
-void tegra_legacy_irq_set_lp1_wake_mask(void);
-void tegra_legacy_irq_restore_mask(void);
-void tegra_init_legacy_irq(void);
-
-#endif
diff -druN linux-2.6.39-libre/arch/arm/mach-tegra/include/mach/sdhci.h linux-3.0-rc7-libre/arch/arm/mach-tegra/include/mach/sdhci.h
--- linux-2.6.39-libre/arch/arm/mach-tegra/include/mach/sdhci.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-tegra/include/mach/sdhci.h	2011-07-11 19:51:52.000000000 -0400
@@ -24,6 +24,7 @@
 	int wp_gpio;
 	int power_gpio;
 	int is_8bit;
+	int pm_flags;
 };
 
 #endif
diff -druN linux-2.6.39-libre/arch/arm/mach-tegra/include/mach/smp.h linux-3.0-rc7-libre/arch/arm/mach-tegra/include/mach/smp.h
--- linux-2.6.39-libre/arch/arm/mach-tegra/include/mach/smp.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-tegra/include/mach/smp.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,14 +0,0 @@
-#ifndef ASMARM_ARCH_SMP_H
-#define ASMARM_ARCH_SMP_H
-
-#include <asm/hardware/gic.h>
-
-/*
- * We use IRQ1 as the IPI
- */
-static inline void smp_cross_call(const struct cpumask *mask, int ipi)
-{
-	gic_raise_softirq(mask, ipi);
-}
-
-#endif
diff -druN linux-2.6.39-libre/arch/arm/mach-tegra/include/mach/tegra_wm8903_pdata.h linux-3.0-rc7-libre/arch/arm/mach-tegra/include/mach/tegra_wm8903_pdata.h
--- linux-2.6.39-libre/arch/arm/mach-tegra/include/mach/tegra_wm8903_pdata.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/arm/mach-tegra/include/mach/tegra_wm8903_pdata.h	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,23 @@
+/*
+ * arch/arm/mach-tegra/include/mach/tegra_wm8903_pdata.h
+ *
+ * Copyright 2011 NVIDIA, 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.
+ *
+ */
+
+struct tegra_wm8903_platform_data {
+	int gpio_spkr_en;
+	int gpio_hp_det;
+	int gpio_hp_mute;
+	int gpio_int_mic_en;
+	int gpio_ext_mic_en;
+};
diff -druN linux-2.6.39-libre/arch/arm/mach-tegra/irq.c linux-3.0-rc7-libre/arch/arm/mach-tegra/irq.c
--- linux-2.6.39-libre/arch/arm/mach-tegra/irq.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-tegra/irq.c	2011-07-11 19:51:52.000000000 -0400
@@ -1,8 +1,8 @@
 /*
- * Copyright (C) 2010 Google, Inc.
+ * Copyright (C) 2011 Google, Inc.
  *
  * Author:
- *	Colin Cross <ccross@google.com>
+ *	Colin Cross <ccross@android.com>
  *
  * Copyright (C) 2010, NVIDIA Corporation
  *
@@ -18,8 +18,6 @@
  */
 
 #include <linux/kernel.h>
-#include <linux/delay.h>
-#include <linux/init.h>
 #include <linux/interrupt.h>
 #include <linux/irq.h>
 #include <linux/io.h>
@@ -27,134 +25,110 @@
 #include <asm/hardware/gic.h>
 
 #include <mach/iomap.h>
-#include <mach/legacy_irq.h>
-#include <mach/suspend.h>
 
 #include "board.h"
 
-#define PMC_CTRL		0x0
-#define PMC_CTRL_LATCH_WAKEUPS	(1 << 5)
-#define PMC_WAKE_MASK		0xc
-#define PMC_WAKE_LEVEL		0x10
-#define PMC_WAKE_STATUS		0x14
-#define PMC_SW_WAKE_STATUS	0x18
-#define PMC_DPD_SAMPLE		0x20
+#define INT_SYS_NR	(INT_GPIO_BASE - INT_PRI_BASE)
+#define INT_SYS_SZ	(INT_SEC_BASE - INT_PRI_BASE)
+#define PPI_NR		((INT_SYS_NR+INT_SYS_SZ-1)/INT_SYS_SZ)
 
-static void __iomem *pmc = IO_ADDRESS(TEGRA_PMC_BASE);
+#define ICTLR_CPU_IEP_VFIQ	0x08
+#define ICTLR_CPU_IEP_FIR	0x14
+#define ICTLR_CPU_IEP_FIR_SET	0x18
+#define ICTLR_CPU_IEP_FIR_CLR	0x1c
 
-static u32 tegra_lp0_wake_enb;
-static u32 tegra_lp0_wake_level;
-static u32 tegra_lp0_wake_level_any;
+#define ICTLR_CPU_IER		0x20
+#define ICTLR_CPU_IER_SET	0x24
+#define ICTLR_CPU_IER_CLR	0x28
+#define ICTLR_CPU_IEP_CLASS	0x2C
 
-static void (*tegra_gic_mask_irq)(struct irq_data *d);
-static void (*tegra_gic_unmask_irq)(struct irq_data *d);
-static void (*tegra_gic_ack_irq)(struct irq_data *d);
+#define ICTLR_COP_IER		0x30
+#define ICTLR_COP_IER_SET	0x34
+#define ICTLR_COP_IER_CLR	0x38
+#define ICTLR_COP_IEP_CLASS	0x3c
 
-/* ensures that sufficient time is passed for a register write to
- * serialize into the 32KHz domain */
-static void pmc_32kwritel(u32 val, unsigned long offs)
-{
-	writel(val, pmc + offs);
-	udelay(130);
-}
+#define NUM_ICTLRS 4
+#define FIRST_LEGACY_IRQ 32
 
-int tegra_set_lp1_wake(int irq, int enable)
-{
-	return tegra_legacy_irq_set_wake(irq, enable);
-}
+static void __iomem *ictlr_reg_base[] = {
+	IO_ADDRESS(TEGRA_PRIMARY_ICTLR_BASE),
+	IO_ADDRESS(TEGRA_SECONDARY_ICTLR_BASE),
+	IO_ADDRESS(TEGRA_TERTIARY_ICTLR_BASE),
+	IO_ADDRESS(TEGRA_QUATERNARY_ICTLR_BASE),
+};
 
-void tegra_set_lp0_wake_pads(u32 wake_enb, u32 wake_level, u32 wake_any)
+static inline void tegra_irq_write_mask(unsigned int irq, unsigned long reg)
 {
-	u32 temp;
-	u32 status;
-	u32 lvl;
-
-	wake_level &= wake_enb;
-	wake_any &= wake_enb;
-
-	wake_level |= (tegra_lp0_wake_level & tegra_lp0_wake_enb);
-	wake_any |= (tegra_lp0_wake_level_any & tegra_lp0_wake_enb);
-
-	wake_enb |= tegra_lp0_wake_enb;
-
-	pmc_32kwritel(0, PMC_SW_WAKE_STATUS);
-	temp = readl(pmc + PMC_CTRL);
-	temp |= PMC_CTRL_LATCH_WAKEUPS;
-	pmc_32kwritel(temp, PMC_CTRL);
-	temp &= ~PMC_CTRL_LATCH_WAKEUPS;
-	pmc_32kwritel(temp, PMC_CTRL);
-	status = readl(pmc + PMC_SW_WAKE_STATUS);
-	lvl = readl(pmc + PMC_WAKE_LEVEL);
-
-	/* flip the wakeup trigger for any-edge triggered pads
-	 * which are currently asserting as wakeups */
-	lvl ^= status;
-	lvl &= wake_any;
+	void __iomem *base;
+	u32 mask;
 
-	wake_level |= lvl;
+	BUG_ON(irq < FIRST_LEGACY_IRQ ||
+		irq >= FIRST_LEGACY_IRQ + NUM_ICTLRS * 32);
 
-	writel(wake_level, pmc + PMC_WAKE_LEVEL);
-	/* Enable DPD sample to trigger sampling pads data and direction
-	 * in which pad will be driven during lp0 mode*/
-	writel(0x1, pmc + PMC_DPD_SAMPLE);
+	base = ictlr_reg_base[(irq - FIRST_LEGACY_IRQ) / 32];
+	mask = BIT((irq - FIRST_LEGACY_IRQ) % 32);
 
-	writel(wake_enb, pmc + PMC_WAKE_MASK);
+	__raw_writel(mask, base + reg);
 }
 
 static void tegra_mask(struct irq_data *d)
 {
-	tegra_gic_mask_irq(d);
-	tegra_legacy_mask_irq(d->irq);
+	if (d->irq < FIRST_LEGACY_IRQ)
+		return;
+
+	tegra_irq_write_mask(d->irq, ICTLR_CPU_IER_CLR);
 }
 
 static void tegra_unmask(struct irq_data *d)
 {
-	tegra_gic_unmask_irq(d);
-	tegra_legacy_unmask_irq(d->irq);
+	if (d->irq < FIRST_LEGACY_IRQ)
+		return;
+
+	tegra_irq_write_mask(d->irq, ICTLR_CPU_IER_SET);
 }
 
 static void tegra_ack(struct irq_data *d)
 {
-	tegra_legacy_force_irq_clr(d->irq);
-	tegra_gic_ack_irq(d);
+	if (d->irq < FIRST_LEGACY_IRQ)
+		return;
+
+	tegra_irq_write_mask(d->irq, ICTLR_CPU_IEP_FIR_CLR);
+}
+
+static void tegra_eoi(struct irq_data *d)
+{
+	if (d->irq < FIRST_LEGACY_IRQ)
+		return;
+
+	tegra_irq_write_mask(d->irq, ICTLR_CPU_IEP_FIR_CLR);
 }
 
 static int tegra_retrigger(struct irq_data *d)
 {
-	tegra_legacy_force_irq_set(d->irq);
+	if (d->irq < FIRST_LEGACY_IRQ)
+		return 0;
+
+	tegra_irq_write_mask(d->irq, ICTLR_CPU_IEP_FIR_SET);
+
 	return 1;
 }
 
-static struct irq_chip tegra_irq = {
-	.name			= "PPI",
-	.irq_ack		= tegra_ack,
-	.irq_mask		= tegra_mask,
-	.irq_unmask		= tegra_unmask,
-	.irq_retrigger		= tegra_retrigger,
-};
-
 void __init tegra_init_irq(void)
 {
-	struct irq_chip *gic;
-	unsigned int i;
-	int irq;
+	int i;
 
-	tegra_init_legacy_irq();
+	for (i = 0; i < NUM_ICTLRS; i++) {
+		void __iomem *ictlr = ictlr_reg_base[i];
+		writel(~0, ictlr + ICTLR_CPU_IER_CLR);
+		writel(0, ictlr + ICTLR_CPU_IEP_CLASS);
+	}
+
+	gic_arch_extn.irq_ack = tegra_ack;
+	gic_arch_extn.irq_eoi = tegra_eoi;
+	gic_arch_extn.irq_mask = tegra_mask;
+	gic_arch_extn.irq_unmask = tegra_unmask;
+	gic_arch_extn.irq_retrigger = tegra_retrigger;
 
 	gic_init(0, 29, IO_ADDRESS(TEGRA_ARM_INT_DIST_BASE),
 		 IO_ADDRESS(TEGRA_ARM_PERIF_BASE + 0x100));
-
-	gic = irq_get_chip(29);
-	tegra_gic_unmask_irq = gic->irq_unmask;
-	tegra_gic_mask_irq = gic->irq_mask;
-	tegra_gic_ack_irq = gic->irq_ack;
-#ifdef CONFIG_SMP
-	tegra_irq.irq_set_affinity = gic->irq_set_affinity;
-#endif
-
-	for (i = 0; i < INT_MAIN_NR; i++) {
-		irq = INT_PRI_BASE + i;
-		irq_set_chip_and_handler(irq, &tegra_irq, handle_level_irq);
-		set_irq_flags(irq, IRQF_VALID);
-	}
 }
diff -druN linux-2.6.39-libre/arch/arm/mach-tegra/Kconfig linux-3.0-rc7-libre/arch/arm/mach-tegra/Kconfig
--- linux-2.6.39-libre/arch/arm/mach-tegra/Kconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-tegra/Kconfig	2011-07-11 19:51:52.000000000 -0400
@@ -27,12 +27,14 @@
 
 config MACH_HARMONY
        bool "Harmony board"
+       select MACH_HAS_SND_SOC_TEGRA_WM8903
        help
          Support for nVidia Harmony development platform
 
 config MACH_KAEN
        bool "Kaen board"
        select MACH_SEABOARD
+       select MACH_HAS_SND_SOC_TEGRA_WM8903
        help
          Support for the Kaen version of Seaboard
 
@@ -43,6 +45,7 @@
 
 config MACH_SEABOARD
        bool "Seaboard board"
+       select MACH_HAS_SND_SOC_TEGRA_WM8903
        help
          Support for nVidia Seaboard development platform. It will
 	 also be included for some of the derivative boards that
diff -druN linux-2.6.39-libre/arch/arm/mach-tegra/legacy_irq.c linux-3.0-rc7-libre/arch/arm/mach-tegra/legacy_irq.c
--- linux-2.6.39-libre/arch/arm/mach-tegra/legacy_irq.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-tegra/legacy_irq.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,215 +0,0 @@
-/*
- * arch/arm/mach-tegra/legacy_irq.c
- *
- * Copyright (C) 2010 Google, Inc.
- * Author: Colin Cross <ccross@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.
- *
- */
-
-#include <linux/io.h>
-#include <linux/kernel.h>
-#include <mach/iomap.h>
-#include <mach/irqs.h>
-#include <mach/legacy_irq.h>
-
-#define INT_SYS_NR	(INT_GPIO_BASE - INT_PRI_BASE)
-#define INT_SYS_SZ	(INT_SEC_BASE - INT_PRI_BASE)
-#define PPI_NR		((INT_SYS_NR+INT_SYS_SZ-1)/INT_SYS_SZ)
-
-#define ICTLR_CPU_IEP_VFIQ	0x08
-#define ICTLR_CPU_IEP_FIR	0x14
-#define ICTLR_CPU_IEP_FIR_SET	0x18
-#define ICTLR_CPU_IEP_FIR_CLR	0x1c
-
-#define ICTLR_CPU_IER		0x20
-#define ICTLR_CPU_IER_SET	0x24
-#define ICTLR_CPU_IER_CLR	0x28
-#define ICTLR_CPU_IEP_CLASS	0x2C
-
-#define ICTLR_COP_IER		0x30
-#define ICTLR_COP_IER_SET	0x34
-#define ICTLR_COP_IER_CLR	0x38
-#define ICTLR_COP_IEP_CLASS	0x3c
-
-#define NUM_ICTLRS 4
-
-static void __iomem *ictlr_reg_base[] = {
-	IO_ADDRESS(TEGRA_PRIMARY_ICTLR_BASE),
-	IO_ADDRESS(TEGRA_SECONDARY_ICTLR_BASE),
-	IO_ADDRESS(TEGRA_TERTIARY_ICTLR_BASE),
-	IO_ADDRESS(TEGRA_QUATERNARY_ICTLR_BASE),
-};
-
-static u32 tegra_legacy_wake_mask[4];
-static u32 tegra_legacy_saved_mask[4];
-
-/* When going into deep sleep, the CPU is powered down, taking the GIC with it
-   In order to wake, the wake interrupts need to be enabled in the legacy
-   interrupt controller. */
-void tegra_legacy_unmask_irq(unsigned int irq)
-{
-	void __iomem *base;
-	pr_debug("%s: %d\n", __func__, irq);
-
-	irq -= 32;
-	base = ictlr_reg_base[irq>>5];
-	writel(1 << (irq & 31), base + ICTLR_CPU_IER_SET);
-}
-
-void tegra_legacy_mask_irq(unsigned int irq)
-{
-	void __iomem *base;
-	pr_debug("%s: %d\n", __func__, irq);
-
-	irq -= 32;
-	base = ictlr_reg_base[irq>>5];
-	writel(1 << (irq & 31), base + ICTLR_CPU_IER_CLR);
-}
-
-void tegra_legacy_force_irq_set(unsigned int irq)
-{
-	void __iomem *base;
-	pr_debug("%s: %d\n", __func__, irq);
-
-	irq -= 32;
-	base = ictlr_reg_base[irq>>5];
-	writel(1 << (irq & 31), base + ICTLR_CPU_IEP_FIR_SET);
-}
-
-void tegra_legacy_force_irq_clr(unsigned int irq)
-{
-	void __iomem *base;
-	pr_debug("%s: %d\n", __func__, irq);
-
-	irq -= 32;
-	base = ictlr_reg_base[irq>>5];
-	writel(1 << (irq & 31), base + ICTLR_CPU_IEP_FIR_CLR);
-}
-
-int tegra_legacy_force_irq_status(unsigned int irq)
-{
-	void __iomem *base;
-	pr_debug("%s: %d\n", __func__, irq);
-
-	irq -= 32;
-	base = ictlr_reg_base[irq>>5];
-	return !!(readl(base + ICTLR_CPU_IEP_FIR) & (1 << (irq & 31)));
-}
-
-void tegra_legacy_select_fiq(unsigned int irq, bool fiq)
-{
-	void __iomem *base;
-	pr_debug("%s: %d\n", __func__, irq);
-
-	irq -= 32;
-	base = ictlr_reg_base[irq>>5];
-	writel(fiq << (irq & 31), base + ICTLR_CPU_IEP_CLASS);
-}
-
-unsigned long tegra_legacy_vfiq(int nr)
-{
-	void __iomem *base;
-	base = ictlr_reg_base[nr];
-	return readl(base + ICTLR_CPU_IEP_VFIQ);
-}
-
-unsigned long tegra_legacy_class(int nr)
-{
-	void __iomem *base;
-	base = ictlr_reg_base[nr];
-	return readl(base + ICTLR_CPU_IEP_CLASS);
-}
-
-int tegra_legacy_irq_set_wake(int irq, int enable)
-{
-	irq -= 32;
-	if (enable)
-		tegra_legacy_wake_mask[irq >> 5] |= 1 << (irq & 31);
-	else
-		tegra_legacy_wake_mask[irq >> 5] &= ~(1 << (irq & 31));
-
-	return 0;
-}
-
-void tegra_legacy_irq_set_lp1_wake_mask(void)
-{
-	void __iomem *base;
-	int i;
-
-	for (i = 0; i < NUM_ICTLRS; i++) {
-		base = ictlr_reg_base[i];
-		tegra_legacy_saved_mask[i] = readl(base + ICTLR_CPU_IER);
-		writel(tegra_legacy_wake_mask[i], base + ICTLR_CPU_IER);
-	}
-}
-
-void tegra_legacy_irq_restore_mask(void)
-{
-	void __iomem *base;
-	int i;
-
-	for (i = 0; i < NUM_ICTLRS; i++) {
-		base = ictlr_reg_base[i];
-		writel(tegra_legacy_saved_mask[i], base + ICTLR_CPU_IER);
-	}
-}
-
-void tegra_init_legacy_irq(void)
-{
-	int i;
-
-	for (i = 0; i < NUM_ICTLRS; i++) {
-		void __iomem *ictlr = ictlr_reg_base[i];
-		writel(~0, ictlr + ICTLR_CPU_IER_CLR);
-		writel(0, ictlr + ICTLR_CPU_IEP_CLASS);
-	}
-}
-
-#ifdef CONFIG_PM
-static u32 cop_ier[NUM_ICTLRS];
-static u32 cpu_ier[NUM_ICTLRS];
-static u32 cpu_iep[NUM_ICTLRS];
-
-void tegra_irq_suspend(void)
-{
-	unsigned long flags;
-	int i;
-
-	local_irq_save(flags);
-	for (i = 0; i < NUM_ICTLRS; i++) {
-		void __iomem *ictlr = ictlr_reg_base[i];
-		cpu_ier[i] = readl(ictlr + ICTLR_CPU_IER);
-		cpu_iep[i] = readl(ictlr + ICTLR_CPU_IEP_CLASS);
-		cop_ier[i] = readl(ictlr + ICTLR_COP_IER);
-		writel(~0, ictlr + ICTLR_COP_IER_CLR);
-	}
-	local_irq_restore(flags);
-}
-
-void tegra_irq_resume(void)
-{
-	unsigned long flags;
-	int i;
-
-	local_irq_save(flags);
-	for (i = 0; i < NUM_ICTLRS; i++) {
-		void __iomem *ictlr = ictlr_reg_base[i];
-		writel(cpu_iep[i], ictlr + ICTLR_CPU_IEP_CLASS);
-		writel(~0ul, ictlr + ICTLR_CPU_IER_CLR);
-		writel(cpu_ier[i], ictlr + ICTLR_CPU_IER_SET);
-		writel(0, ictlr + ICTLR_COP_IEP_CLASS);
-		writel(~0ul, ictlr + ICTLR_COP_IER_CLR);
-		writel(cop_ier[i], ictlr + ICTLR_COP_IER_SET);
-	}
-	local_irq_restore(flags);
-}
-#endif
diff -druN linux-2.6.39-libre/arch/arm/mach-tegra/Makefile linux-3.0-rc7-libre/arch/arm/mach-tegra/Makefile
--- linux-2.6.39-libre/arch/arm/mach-tegra/Makefile	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-tegra/Makefile	2011-07-11 19:51:52.000000000 -0400
@@ -1,7 +1,7 @@
 obj-y                                   += common.o
 obj-y                                   += devices.o
 obj-y                                   += io.o
-obj-y                                   += irq.o legacy_irq.o
+obj-y                                   += irq.o
 obj-y                                   += clock.o
 obj-y                                   += timer.o
 obj-y                                   += gpio.o
diff -druN linux-2.6.39-libre/arch/arm/mach-tegra/platsmp.c linux-3.0-rc7-libre/arch/arm/mach-tegra/platsmp.c
--- linux-2.6.39-libre/arch/arm/mach-tegra/platsmp.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-tegra/platsmp.c	2011-07-11 19:51:52.000000000 -0400
@@ -20,6 +20,7 @@
 #include <linux/io.h>
 
 #include <asm/cacheflush.h>
+#include <asm/hardware/gic.h>
 #include <mach/hardware.h>
 #include <asm/mach-types.h>
 #include <asm/smp_scu.h>
@@ -122,6 +123,8 @@
 
 	for (i = 0; i < ncores; i++)
 		cpu_set(i, cpu_possible_map);
+
+	set_smp_cross_call(gic_raise_softirq);
 }
 
 void __init platform_smp_prepare_cpus(unsigned int max_cpus)
diff -druN linux-2.6.39-libre/arch/arm/mach-tegra/tegra2_clocks.c linux-3.0-rc7-libre/arch/arm/mach-tegra/tegra2_clocks.c
--- linux-2.6.39-libre/arch/arm/mach-tegra/tegra2_clocks.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-tegra/tegra2_clocks.c	2011-07-11 19:51:52.000000000 -0400
@@ -337,7 +337,7 @@
 	const struct clk_mux_sel *sel;
 	int shift;
 
-	val = clk_readl(c->reg + SUPER_CLK_MUX);;
+	val = clk_readl(c->reg + SUPER_CLK_MUX);
 	BUG_ON(((val & SUPER_STATE_MASK) != SUPER_STATE_RUN) &&
 		((val & SUPER_STATE_MASK) != SUPER_STATE_IDLE));
 	shift = ((val & SUPER_STATE_MASK) == SUPER_STATE_IDLE) ?
diff -druN linux-2.6.39-libre/arch/arm/mach-tegra/timer.c linux-3.0-rc7-libre/arch/arm/mach-tegra/timer.c
--- linux-2.6.39-libre/arch/arm/mach-tegra/timer.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-tegra/timer.c	2011-07-11 19:51:52.000000000 -0400
@@ -98,11 +98,6 @@
 	}
 }
 
-static cycle_t tegra_clocksource_read(struct clocksource *cs)
-{
-	return timer_readl(TIMERUS_CNTR_1US);
-}
-
 static struct clock_event_device tegra_clockevent = {
 	.name		= "timer0",
 	.rating		= 300,
@@ -111,14 +106,6 @@
 	.set_mode	= tegra_timer_set_mode,
 };
 
-static struct clocksource tegra_clocksource = {
-	.name	= "timer_us",
-	.rating	= 300,
-	.read	= tegra_clocksource_read,
-	.mask	= CLOCKSOURCE_MASK(32),
-	.flags	= CLOCK_SOURCE_IS_CONTINUOUS,
-};
-
 static DEFINE_CLOCK_DATA(cd);
 
 /*
@@ -234,7 +221,8 @@
 	init_fixed_sched_clock(&cd, tegra_update_sched_clock, 32,
 			       1000000, SC_MULT, SC_SHIFT);
 
-	if (clocksource_register_hz(&tegra_clocksource, 1000000)) {
+	if (clocksource_mmio_init(timer_reg_base + TIMERUS_CNTR_1US,
+		"timer_us", 1000000, 300, 32, clocksource_mmio_readl_up)) {
 		printk(KERN_ERR "Failed to register clocksource\n");
 		BUG();
 	}
diff -druN linux-2.6.39-libre/arch/arm/mach-u300/clock.h linux-3.0-rc7-libre/arch/arm/mach-u300/clock.h
--- linux-2.6.39-libre/arch/arm/mach-u300/clock.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-u300/clock.h	2011-07-11 19:51:52.000000000 -0400
@@ -31,7 +31,7 @@
 	bool reset;
 	__u16 clk_val;
 	__s8 usecount;
-	__u32 res_reg;
+	void __iomem * res_reg;
 	__u16 res_mask;
 
 	bool hw_ctrld;
diff -druN linux-2.6.39-libre/arch/arm/mach-u300/gpio.c linux-3.0-rc7-libre/arch/arm/mach-u300/gpio.c
--- linux-2.6.39-libre/arch/arm/mach-u300/gpio.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-u300/gpio.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,700 +0,0 @@
-/*
- *
- * arch/arm/mach-u300/gpio.c
- *
- *
- * Copyright (C) 2007-2009 ST-Ericsson AB
- * License terms: GNU General Public License (GPL) version 2
- * U300 GPIO module.
- * This can driver either of the two basic GPIO cores
- * available in the U300 platforms:
- * COH 901 335   - Used in DB3150 (U300 1.0) and DB3200 (U330 1.0)
- * COH 901 571/3 - Used in DB3210 (U365 2.0) and DB3350 (U335 1.0)
- * Notice that you also have inline macros in <asm-arch/gpio.h>
- * Author: Linus Walleij <linus.walleij@stericsson.com>
- * Author: Jonas Aaberg <jonas.aberg@stericsson.com>
- *
- */
-#include <linux/module.h>
-#include <linux/interrupt.h>
-#include <linux/delay.h>
-#include <linux/errno.h>
-#include <linux/io.h>
-#include <linux/clk.h>
-#include <linux/err.h>
-#include <linux/platform_device.h>
-#include <linux/gpio.h>
-
-/* Reference to GPIO block clock */
-static struct clk *clk;
-
-/* Memory resource */
-static struct resource *memres;
-static void __iomem *virtbase;
-static struct device *gpiodev;
-
-struct u300_gpio_port {
-	const char *name;
-	int irq;
-	int number;
-};
-
-
-static struct u300_gpio_port gpio_ports[] = {
-	{
-		.name = "gpio0",
-		.number = 0,
-	},
-	{
-		.name = "gpio1",
-		.number = 1,
-	},
-	{
-		.name = "gpio2",
-		.number = 2,
-	},
-#ifdef U300_COH901571_3
-	{
-		.name = "gpio3",
-		.number = 3,
-	},
-	{
-		.name = "gpio4",
-		.number = 4,
-	},
-#ifdef CONFIG_MACH_U300_BS335
-	{
-		.name = "gpio5",
-		.number = 5,
-	},
-	{
-		.name = "gpio6",
-		.number = 6,
-	},
-#endif
-#endif
-
-};
-
-
-#ifdef U300_COH901571_3
-
-/* Default input value */
-#define DEFAULT_OUTPUT_LOW   0
-#define DEFAULT_OUTPUT_HIGH  1
-
-/* GPIO Pull-Up status */
-#define DISABLE_PULL_UP  0
-#define ENABLE_PULL_UP  1
-
-#define GPIO_NOT_USED 0
-#define GPIO_IN       1
-#define GPIO_OUT      2
-
-struct u300_gpio_configuration_data {
-	unsigned char pin_usage;
-	unsigned char default_output_value;
-	unsigned char pull_up;
-};
-
-/* Initial configuration */
-const struct u300_gpio_configuration_data
-u300_gpio_config[U300_GPIO_NUM_PORTS][U300_GPIO_PINS_PER_PORT] = {
-#ifdef CONFIG_MACH_U300_BS335
-	/* Port 0, pins 0-7 */
-	{
-		{GPIO_IN,  DEFAULT_OUTPUT_LOW,   DISABLE_PULL_UP},
-		{GPIO_OUT, DEFAULT_OUTPUT_HIGH,  DISABLE_PULL_UP},
-		{GPIO_IN,  DEFAULT_OUTPUT_LOW,   DISABLE_PULL_UP},
-		{GPIO_OUT, DEFAULT_OUTPUT_LOW,   DISABLE_PULL_UP},
-		{GPIO_OUT, DEFAULT_OUTPUT_LOW,   DISABLE_PULL_UP},
-		{GPIO_OUT, DEFAULT_OUTPUT_LOW,   DISABLE_PULL_UP},
-		{GPIO_OUT, DEFAULT_OUTPUT_LOW,   DISABLE_PULL_UP},
-		{GPIO_OUT, DEFAULT_OUTPUT_LOW,   DISABLE_PULL_UP}
-	},
-	/* Port 1, pins 0-7 */
-	{
-		{GPIO_OUT, DEFAULT_OUTPUT_LOW,   DISABLE_PULL_UP},
-		{GPIO_OUT, DEFAULT_OUTPUT_LOW,   DISABLE_PULL_UP},
-		{GPIO_OUT, DEFAULT_OUTPUT_LOW,   DISABLE_PULL_UP},
-		{GPIO_IN,  DEFAULT_OUTPUT_LOW,    ENABLE_PULL_UP},
-		{GPIO_IN,  DEFAULT_OUTPUT_LOW,   DISABLE_PULL_UP},
-		{GPIO_OUT, DEFAULT_OUTPUT_HIGH,  DISABLE_PULL_UP},
-		{GPIO_OUT, DEFAULT_OUTPUT_LOW,   DISABLE_PULL_UP},
-		{GPIO_OUT, DEFAULT_OUTPUT_LOW,   DISABLE_PULL_UP}
-	},
-	/* Port 2, pins 0-7 */
-	{
-		{GPIO_IN,  DEFAULT_OUTPUT_LOW,   DISABLE_PULL_UP},
-		{GPIO_IN,  DEFAULT_OUTPUT_LOW,   DISABLE_PULL_UP},
-		{GPIO_IN,  DEFAULT_OUTPUT_LOW,   DISABLE_PULL_UP},
-		{GPIO_IN,  DEFAULT_OUTPUT_LOW,   DISABLE_PULL_UP},
-		{GPIO_OUT, DEFAULT_OUTPUT_LOW,   DISABLE_PULL_UP},
-		{GPIO_IN,  DEFAULT_OUTPUT_LOW,    ENABLE_PULL_UP},
-		{GPIO_OUT, DEFAULT_OUTPUT_LOW,   DISABLE_PULL_UP},
-		{GPIO_IN,  DEFAULT_OUTPUT_LOW,    ENABLE_PULL_UP}
-	},
-	/* Port 3, pins 0-7 */
-	{
-		{GPIO_IN,  DEFAULT_OUTPUT_LOW,    ENABLE_PULL_UP},
-		{GPIO_OUT, DEFAULT_OUTPUT_LOW,   DISABLE_PULL_UP},
-		{GPIO_IN,  DEFAULT_OUTPUT_LOW,   DISABLE_PULL_UP},
-		{GPIO_IN,  DEFAULT_OUTPUT_LOW,   DISABLE_PULL_UP},
-		{GPIO_IN,  DEFAULT_OUTPUT_LOW,   DISABLE_PULL_UP},
-		{GPIO_IN,  DEFAULT_OUTPUT_LOW,   DISABLE_PULL_UP},
-		{GPIO_IN,  DEFAULT_OUTPUT_LOW,   DISABLE_PULL_UP},
-		{GPIO_IN,  DEFAULT_OUTPUT_LOW,   DISABLE_PULL_UP}
-	},
-	/* Port 4, pins 0-7 */
-	{
-		{GPIO_IN,  DEFAULT_OUTPUT_LOW,   DISABLE_PULL_UP},
-		{GPIO_IN,  DEFAULT_OUTPUT_LOW,   DISABLE_PULL_UP},
-		{GPIO_IN,  DEFAULT_OUTPUT_LOW,   DISABLE_PULL_UP},
-		{GPIO_IN,  DEFAULT_OUTPUT_LOW,   DISABLE_PULL_UP},
-		{GPIO_IN,  DEFAULT_OUTPUT_LOW,   DISABLE_PULL_UP},
-		{GPIO_IN,  DEFAULT_OUTPUT_LOW,   DISABLE_PULL_UP},
-		{GPIO_IN,  DEFAULT_OUTPUT_LOW,   DISABLE_PULL_UP},
-		{GPIO_IN,  DEFAULT_OUTPUT_LOW,   DISABLE_PULL_UP}
-	},
-	/* Port 5, pins 0-7 */
-	{
-		{GPIO_IN,  DEFAULT_OUTPUT_LOW,   DISABLE_PULL_UP},
-		{GPIO_IN,  DEFAULT_OUTPUT_LOW,   DISABLE_PULL_UP},
-		{GPIO_IN,  DEFAULT_OUTPUT_LOW,   DISABLE_PULL_UP},
-		{GPIO_IN,  DEFAULT_OUTPUT_LOW,   DISABLE_PULL_UP},
-		{GPIO_IN,  DEFAULT_OUTPUT_LOW,   DISABLE_PULL_UP},
-		{GPIO_IN,  DEFAULT_OUTPUT_LOW,   DISABLE_PULL_UP},
-		{GPIO_IN,  DEFAULT_OUTPUT_LOW,   DISABLE_PULL_UP},
-		{GPIO_IN,  DEFAULT_OUTPUT_LOW,   DISABLE_PULL_UP}
-	},
-	/* Port 6, pind 0-7 */
-	{
-		{GPIO_IN,  DEFAULT_OUTPUT_LOW,   DISABLE_PULL_UP},
-		{GPIO_IN,  DEFAULT_OUTPUT_LOW,   DISABLE_PULL_UP},
-		{GPIO_IN,  DEFAULT_OUTPUT_LOW,   DISABLE_PULL_UP},
-		{GPIO_IN,  DEFAULT_OUTPUT_LOW,   DISABLE_PULL_UP},
-		{GPIO_IN,  DEFAULT_OUTPUT_LOW,   DISABLE_PULL_UP},
-		{GPIO_IN,  DEFAULT_OUTPUT_LOW,   DISABLE_PULL_UP},
-		{GPIO_IN,  DEFAULT_OUTPUT_LOW,   DISABLE_PULL_UP},
-		{GPIO_IN,  DEFAULT_OUTPUT_LOW,   DISABLE_PULL_UP}
-	}
-#endif
-
-#ifdef CONFIG_MACH_U300_BS365
-	/* Port 0, pins 0-7 */
-	{
-		{GPIO_IN,  DEFAULT_OUTPUT_LOW,   DISABLE_PULL_UP},
-		{GPIO_OUT, DEFAULT_OUTPUT_LOW,   DISABLE_PULL_UP},
-		{GPIO_IN,  DEFAULT_OUTPUT_LOW,   DISABLE_PULL_UP},
-		{GPIO_OUT, DEFAULT_OUTPUT_LOW,   DISABLE_PULL_UP},
-		{GPIO_OUT, DEFAULT_OUTPUT_LOW,   DISABLE_PULL_UP},
-		{GPIO_OUT, DEFAULT_OUTPUT_LOW,   DISABLE_PULL_UP},
-		{GPIO_IN,  DEFAULT_OUTPUT_LOW,    ENABLE_PULL_UP},
-		{GPIO_IN,  DEFAULT_OUTPUT_LOW,   DISABLE_PULL_UP}
-	},
-	/* Port 1, pins 0-7 */
-	{
-		{GPIO_OUT, DEFAULT_OUTPUT_LOW,   DISABLE_PULL_UP},
-		{GPIO_IN,  DEFAULT_OUTPUT_LOW,   DISABLE_PULL_UP},
-		{GPIO_OUT, DEFAULT_OUTPUT_LOW,   DISABLE_PULL_UP},
-		{GPIO_IN,  DEFAULT_OUTPUT_LOW,   DISABLE_PULL_UP},
-		{GPIO_IN,  DEFAULT_OUTPUT_LOW,   DISABLE_PULL_UP},
-		{GPIO_OUT, DEFAULT_OUTPUT_HIGH,  DISABLE_PULL_UP},
-		{GPIO_OUT, DEFAULT_OUTPUT_LOW,   DISABLE_PULL_UP},
-		{GPIO_OUT, DEFAULT_OUTPUT_LOW,   DISABLE_PULL_UP}
-	},
-	/* Port 2, pins 0-7 */
-	{
-		{GPIO_IN,  DEFAULT_OUTPUT_LOW,   DISABLE_PULL_UP},
-		{GPIO_IN,  DEFAULT_OUTPUT_LOW,    ENABLE_PULL_UP},
-		{GPIO_OUT, DEFAULT_OUTPUT_LOW,   DISABLE_PULL_UP},
-		{GPIO_OUT, DEFAULT_OUTPUT_LOW,   DISABLE_PULL_UP},
-		{GPIO_IN,  DEFAULT_OUTPUT_LOW,    ENABLE_PULL_UP},
-		{GPIO_IN,  DEFAULT_OUTPUT_LOW,    ENABLE_PULL_UP},
-		{GPIO_IN,  DEFAULT_OUTPUT_LOW,    ENABLE_PULL_UP},
-		{GPIO_IN,  DEFAULT_OUTPUT_LOW,    ENABLE_PULL_UP}
-	},
-	/* Port 3, pins 0-7 */
-	{
-		{GPIO_IN,  DEFAULT_OUTPUT_LOW,    ENABLE_PULL_UP},
-		{GPIO_IN,  DEFAULT_OUTPUT_LOW,    ENABLE_PULL_UP},
-		{GPIO_IN,  DEFAULT_OUTPUT_LOW,    ENABLE_PULL_UP},
-		{GPIO_IN,  DEFAULT_OUTPUT_LOW,    ENABLE_PULL_UP},
-		{GPIO_IN,  DEFAULT_OUTPUT_LOW,    ENABLE_PULL_UP},
-		{GPIO_IN,  DEFAULT_OUTPUT_LOW,    ENABLE_PULL_UP},
-		{GPIO_IN,  DEFAULT_OUTPUT_LOW,    ENABLE_PULL_UP},
-		{GPIO_IN,  DEFAULT_OUTPUT_LOW,    ENABLE_PULL_UP}
-	},
-	/* Port 4, pins 0-7 */
-	{
-		{GPIO_IN,  DEFAULT_OUTPUT_LOW,    ENABLE_PULL_UP},
-		{GPIO_IN,  DEFAULT_OUTPUT_LOW,    ENABLE_PULL_UP},
-		{GPIO_IN,  DEFAULT_OUTPUT_LOW,    ENABLE_PULL_UP},
-		{GPIO_IN,  DEFAULT_OUTPUT_LOW,    ENABLE_PULL_UP},
-		/* These 4 pins doesn't exist on DB3210 */
-		{GPIO_OUT, DEFAULT_OUTPUT_LOW,    ENABLE_PULL_UP},
-		{GPIO_OUT, DEFAULT_OUTPUT_LOW,    ENABLE_PULL_UP},
-		{GPIO_OUT, DEFAULT_OUTPUT_LOW,    ENABLE_PULL_UP},
-		{GPIO_OUT, DEFAULT_OUTPUT_LOW,    ENABLE_PULL_UP}
-	}
-#endif
-};
-#endif
-
-
-/* No users == we can power down GPIO */
-static int gpio_users;
-
-struct gpio_struct {
-	int (*callback)(void *);
-	void *data;
-	int users;
-};
-
-static struct gpio_struct gpio_pin[U300_GPIO_MAX];
-
-/*
- * Let drivers register callback in order to get notified when there is
- * an interrupt on the gpio pin
- */
-int gpio_register_callback(unsigned gpio, int (*func)(void *arg), void *data)
-{
-	if (gpio_pin[gpio].callback)
-		dev_warn(gpiodev, "%s: WARNING: callback already "
-			 "registered for gpio pin#%d\n", __func__, gpio);
-	gpio_pin[gpio].callback = func;
-	gpio_pin[gpio].data = data;
-
-	return 0;
-}
-EXPORT_SYMBOL(gpio_register_callback);
-
-int gpio_unregister_callback(unsigned gpio)
-{
-	if (!gpio_pin[gpio].callback)
-		dev_warn(gpiodev, "%s: WARNING: callback already "
-			 "unregistered for gpio pin#%d\n", __func__, gpio);
-	gpio_pin[gpio].callback = NULL;
-	gpio_pin[gpio].data = NULL;
-
-	return 0;
-}
-EXPORT_SYMBOL(gpio_unregister_callback);
-
-/* Non-zero means valid */
-int gpio_is_valid(int number)
-{
-	if (number >= 0 &&
-	    number < (U300_GPIO_NUM_PORTS * U300_GPIO_PINS_PER_PORT))
-		return 1;
-	return 0;
-}
-EXPORT_SYMBOL(gpio_is_valid);
-
-int gpio_request(unsigned gpio, const char *label)
-{
-	if (gpio_pin[gpio].users)
-		return -EINVAL;
-	else
-		gpio_pin[gpio].users++;
-
-	gpio_users++;
-
-	return 0;
-}
-EXPORT_SYMBOL(gpio_request);
-
-void gpio_free(unsigned gpio)
-{
-	gpio_users--;
-	gpio_pin[gpio].users--;
-	if (unlikely(gpio_pin[gpio].users < 0)) {
-		dev_warn(gpiodev, "warning: gpio#%d release mismatch\n",
-			 gpio);
-		gpio_pin[gpio].users = 0;
-	}
-
-	return;
-}
-EXPORT_SYMBOL(gpio_free);
-
-/* This returns zero or nonzero */
-int gpio_get_value(unsigned gpio)
-{
-	return readl(virtbase + U300_GPIO_PXPDIR +
-	  PIN_TO_PORT(gpio) * U300_GPIO_PORTX_SPACING) & (1 << (gpio & 0x07));
-}
-EXPORT_SYMBOL(gpio_get_value);
-
-/*
- * We hope that the compiler will optimize away the unused branch
- * in case "value" is a constant
- */
-void gpio_set_value(unsigned gpio, int value)
-{
-	u32 val;
-	unsigned long flags;
-
-	local_irq_save(flags);
-	if (value) {
-		/* set */
-		val = readl(virtbase + U300_GPIO_PXPDOR +
-		  PIN_TO_PORT(gpio) * U300_GPIO_PORTX_SPACING)
-		  & (1 << (gpio & 0x07));
-		writel(val | (1 << (gpio & 0x07)), virtbase +
-		  U300_GPIO_PXPDOR +
-		  PIN_TO_PORT(gpio) * U300_GPIO_PORTX_SPACING);
-	} else {
-		/* clear */
-		val = readl(virtbase + U300_GPIO_PXPDOR +
-		  PIN_TO_PORT(gpio) * U300_GPIO_PORTX_SPACING)
-		  & (1 << (gpio & 0x07));
-		writel(val & ~(1 << (gpio & 0x07)), virtbase +
-		  U300_GPIO_PXPDOR +
-		  PIN_TO_PORT(gpio) * U300_GPIO_PORTX_SPACING);
-	}
-	local_irq_restore(flags);
-}
-EXPORT_SYMBOL(gpio_set_value);
-
-int gpio_direction_input(unsigned gpio)
-{
-	unsigned long flags;
-	u32 val;
-
-	if (gpio > U300_GPIO_MAX)
-		return -EINVAL;
-
-	local_irq_save(flags);
-	val = readl(virtbase + U300_GPIO_PXPCR + PIN_TO_PORT(gpio) *
-				U300_GPIO_PORTX_SPACING);
-	/* Mask out this pin*/
-	val &= ~(U300_GPIO_PXPCR_PIN_MODE_MASK << ((gpio & 0x07) << 1));
-	/* This is not needed since it sets the bits to zero.*/
-	/* val |= (U300_GPIO_PXPCR_PIN_MODE_INPUT << (gpio*2)); */
-	writel(val, virtbase + U300_GPIO_PXPCR + PIN_TO_PORT(gpio) *
-				U300_GPIO_PORTX_SPACING);
-	local_irq_restore(flags);
-	return 0;
-}
-EXPORT_SYMBOL(gpio_direction_input);
-
-int gpio_direction_output(unsigned gpio, int value)
-{
-	unsigned long flags;
-	u32 val;
-
-	if (gpio > U300_GPIO_MAX)
-		return -EINVAL;
-
-	local_irq_save(flags);
-	val = readl(virtbase + U300_GPIO_PXPCR + PIN_TO_PORT(gpio) *
-				U300_GPIO_PORTX_SPACING);
-	/* Mask out this pin */
-	val &= ~(U300_GPIO_PXPCR_PIN_MODE_MASK << ((gpio & 0x07) << 1));
-	/*
-	 * FIXME: configure for push/pull, open drain or open source per pin
-	 * in setup. The current driver will only support push/pull.
-	 */
-	val |= (U300_GPIO_PXPCR_PIN_MODE_OUTPUT_PUSH_PULL
-			<< ((gpio & 0x07) << 1));
-	writel(val, virtbase + U300_GPIO_PXPCR + PIN_TO_PORT(gpio) *
-				U300_GPIO_PORTX_SPACING);
-	gpio_set_value(gpio, value);
-	local_irq_restore(flags);
-	return 0;
-}
-EXPORT_SYMBOL(gpio_direction_output);
-
-/*
- * Enable an IRQ, edge is rising edge (!= 0) or falling edge (==0).
- */
-void enable_irq_on_gpio_pin(unsigned gpio, int edge)
-{
-	u32 val;
-	unsigned long flags;
-	local_irq_save(flags);
-
-	val = readl(virtbase + U300_GPIO_PXIEN + PIN_TO_PORT(gpio) *
-				U300_GPIO_PORTX_SPACING);
-	val |= (1 << (gpio & 0x07));
-	writel(val, virtbase + U300_GPIO_PXIEN + PIN_TO_PORT(gpio) *
-				U300_GPIO_PORTX_SPACING);
-	val = readl(virtbase + U300_GPIO_PXICR + PIN_TO_PORT(gpio) *
-				U300_GPIO_PORTX_SPACING);
-	if (edge)
-		val |= (1 << (gpio & 0x07));
-	else
-		val &= ~(1 << (gpio & 0x07));
-	writel(val, virtbase + U300_GPIO_PXICR + PIN_TO_PORT(gpio) *
-				U300_GPIO_PORTX_SPACING);
-	local_irq_restore(flags);
-}
-EXPORT_SYMBOL(enable_irq_on_gpio_pin);
-
-void disable_irq_on_gpio_pin(unsigned gpio)
-{
-	u32 val;
-	unsigned long flags;
-
-	local_irq_save(flags);
-	val = readl(virtbase + U300_GPIO_PXIEN + PIN_TO_PORT(gpio) *
-				U300_GPIO_PORTX_SPACING);
-	val &= ~(1 << (gpio & 0x07));
-	writel(val, virtbase + U300_GPIO_PXIEN + PIN_TO_PORT(gpio) *
-				U300_GPIO_PORTX_SPACING);
-	local_irq_restore(flags);
-}
-EXPORT_SYMBOL(disable_irq_on_gpio_pin);
-
-/* Enable (value == 0) or disable (value == 1) internal pullup */
-void gpio_pullup(unsigned gpio, int value)
-{
-	u32 val;
-	unsigned long flags;
-
-	local_irq_save(flags);
-	if (value) {
-		val = readl(virtbase + U300_GPIO_PXPER + PIN_TO_PORT(gpio) *
-					U300_GPIO_PORTX_SPACING);
-		writel(val | (1 << (gpio & 0x07)), virtbase + U300_GPIO_PXPER +
-				PIN_TO_PORT(gpio) * U300_GPIO_PORTX_SPACING);
-	} else {
-		val = readl(virtbase + U300_GPIO_PXPER + PIN_TO_PORT(gpio) *
-					U300_GPIO_PORTX_SPACING);
-		writel(val & ~(1 << (gpio & 0x07)), virtbase + U300_GPIO_PXPER +
-				PIN_TO_PORT(gpio) * U300_GPIO_PORTX_SPACING);
-	}
-	local_irq_restore(flags);
-}
-EXPORT_SYMBOL(gpio_pullup);
-
-static irqreturn_t gpio_irq_handler(int irq, void *dev_id)
-{
-	struct u300_gpio_port *port = dev_id;
-	u32 val;
-	int pin;
-
-	/* Read event register */
-	val = readl(virtbase + U300_GPIO_PXIEV + port->number *
-				U300_GPIO_PORTX_SPACING);
-	/* Mask with enable register */
-	val &= readl(virtbase + U300_GPIO_PXIEV + port->number *
-				U300_GPIO_PORTX_SPACING);
-	/* Mask relevant bits */
-	val &= U300_GPIO_PXIEV_ALL_IRQ_EVENT_MASK;
-	/* ACK IRQ (clear event) */
-	writel(val, virtbase + U300_GPIO_PXIEV + port->number *
-				U300_GPIO_PORTX_SPACING);
-	/* Print message */
-	while (val != 0) {
-		unsigned gpio;
-
-		pin = __ffs(val);
-		/* mask off this pin */
-		val &= ~(1 << pin);
-		gpio = (port->number << 3) + pin;
-
-		if (gpio_pin[gpio].callback)
-			(void)gpio_pin[gpio].callback(gpio_pin[gpio].data);
-		else
-			dev_dbg(gpiodev, "stray GPIO IRQ on line %d\n",
-			       gpio);
-	}
-	return IRQ_HANDLED;
-}
-
-static void gpio_set_initial_values(void)
-{
-#ifdef U300_COH901571_3
-	int i, j;
-	unsigned long flags;
-	u32 val;
-
-	/* Write default values to all pins */
-	for (i = 0; i < U300_GPIO_NUM_PORTS; i++) {
-		val = 0;
-		for (j = 0; j < 8; j++)
-			val |= (u32) (u300_gpio_config[i][j].default_output_value != DEFAULT_OUTPUT_LOW) << j;
-		local_irq_save(flags);
-		writel(val, virtbase + U300_GPIO_PXPDOR + i * U300_GPIO_PORTX_SPACING);
-		local_irq_restore(flags);
-	}
-
-	/*
-	 * Put all pins that are set to either 'GPIO_OUT' or 'GPIO_NOT_USED'
-	 * to output and 'GPIO_IN' to input for each port. And initialize
-	 * default value on outputs.
-	 */
-	for (i = 0; i < U300_GPIO_NUM_PORTS; i++) {
-		for (j = 0; j < U300_GPIO_PINS_PER_PORT; j++) {
-			local_irq_save(flags);
-			val = readl(virtbase + U300_GPIO_PXPCR +
-					 i * U300_GPIO_PORTX_SPACING);
-			/* Mask out this pin */
-			val &= ~(U300_GPIO_PXPCR_PIN_MODE_MASK << (j << 1));
-
-			if (u300_gpio_config[i][j].pin_usage != GPIO_IN)
-				val |= (U300_GPIO_PXPCR_PIN_MODE_OUTPUT_PUSH_PULL << (j << 1));
-			writel(val, virtbase + U300_GPIO_PXPCR +
-					 i * U300_GPIO_PORTX_SPACING);
-			local_irq_restore(flags);
-		}
-	}
-
-	/* Enable or disable the internal pull-ups in the GPIO ASIC block */
-	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);
-		local_irq_save(flags);
-		writel(val, virtbase + U300_GPIO_PXPER + i * U300_GPIO_PORTX_SPACING);
-		local_irq_restore(flags);
-	}
-#endif
-}
-
-static int __init gpio_probe(struct platform_device *pdev)
-{
-	u32 val;
-	int err = 0;
-	int i;
-	int num_irqs;
-
-	gpiodev = &pdev->dev;
-	memset(gpio_pin, 0, sizeof(gpio_pin));
-
-	/* Get GPIO clock */
-	clk = clk_get(&pdev->dev, NULL);
-	if (IS_ERR(clk)) {
-		err = PTR_ERR(clk);
-		dev_err(gpiodev, "could not get GPIO clock\n");
-		goto err_no_clk;
-	}
-	err = clk_enable(clk);
-	if (err) {
-		dev_err(gpiodev, "could not enable GPIO clock\n");
-		goto err_no_clk_enable;
-	}
-
-	memres = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	if (!memres)
-		goto err_no_resource;
-
-	if (request_mem_region(memres->start, memres->end - memres->start, "GPIO Controller")
-	    == NULL) {
-		err = -ENODEV;
-		goto err_no_ioregion;
-	}
-
-	virtbase = ioremap(memres->start, resource_size(memres));
-	if (!virtbase) {
-		err = -ENOMEM;
-		goto err_no_ioremap;
-	}
-	dev_info(gpiodev, "remapped 0x%08x to %p\n",
-		 memres->start, virtbase);
-
-#ifdef U300_COH901335
-	dev_info(gpiodev, "initializing GPIO Controller COH 901 335\n");
-	/* Turn on the GPIO block */
-	writel(U300_GPIO_CR_BLOCK_CLOCK_ENABLE, virtbase + U300_GPIO_CR);
-#endif
-
-#ifdef U300_COH901571_3
-	dev_info(gpiodev, "initializing GPIO Controller COH 901 571/3\n");
-	val = readl(virtbase + U300_GPIO_CR);
-	dev_info(gpiodev, "COH901571/3 block version: %d, " \
-	       "number of cores: %d\n",
-	       ((val & 0x0000FE00) >> 9),
-	       ((val & 0x000001FC) >> 2));
-	writel(U300_GPIO_CR_BLOCK_CLKRQ_ENABLE, virtbase + U300_GPIO_CR);
-#endif
-
-	gpio_set_initial_values();
-
-	for (num_irqs = 0 ; num_irqs < U300_GPIO_NUM_PORTS; num_irqs++) {
-
-		gpio_ports[num_irqs].irq =
-			platform_get_irq_byname(pdev,
-						gpio_ports[num_irqs].name);
-
-		err = request_irq(gpio_ports[num_irqs].irq,
-				  gpio_irq_handler, IRQF_DISABLED,
-				  gpio_ports[num_irqs].name,
-				  &gpio_ports[num_irqs]);
-		if (err) {
-			dev_err(gpiodev, "cannot allocate IRQ for %s!\n",
-				gpio_ports[num_irqs].name);
-			goto err_no_irq;
-		}
-		/* Turns off PortX_irq_force */
-		writel(0x0, virtbase + U300_GPIO_PXIFR +
-				 num_irqs * U300_GPIO_PORTX_SPACING);
-	}
-
-	return 0;
-
- err_no_irq:
-	for (i = 0; i < num_irqs; i++)
-		free_irq(gpio_ports[i].irq, &gpio_ports[i]);
-	iounmap(virtbase);
- err_no_ioremap:
-	release_mem_region(memres->start, memres->end - memres->start);
- err_no_ioregion:
- err_no_resource:
-	clk_disable(clk);
- err_no_clk_enable:
-	clk_put(clk);
- err_no_clk:
-	dev_info(gpiodev, "module ERROR:%d\n", err);
-	return err;
-}
-
-static int __exit gpio_remove(struct platform_device *pdev)
-{
-	int i;
-
-	/* Turn off the GPIO block */
-	writel(0x00000000U, virtbase + U300_GPIO_CR);
-	for (i = 0 ; i < U300_GPIO_NUM_PORTS; i++)
-		free_irq(gpio_ports[i].irq, &gpio_ports[i]);
-	iounmap(virtbase);
-	release_mem_region(memres->start, memres->end - memres->start);
-	clk_disable(clk);
-	clk_put(clk);
-	return 0;
-}
-
-static struct platform_driver gpio_driver = {
-	.driver		= {
-		.name	= "u300-gpio",
-	},
-	.remove		= __exit_p(gpio_remove),
-};
-
-
-static int __init u300_gpio_init(void)
-{
-	return platform_driver_probe(&gpio_driver, gpio_probe);
-}
-
-static void __exit u300_gpio_exit(void)
-{
-	platform_driver_unregister(&gpio_driver);
-}
-
-arch_initcall(u300_gpio_init);
-module_exit(u300_gpio_exit);
-
-MODULE_AUTHOR("Linus Walleij <linus.walleij@stericsson.com>");
-
-#ifdef U300_COH901571_3
-MODULE_DESCRIPTION("ST-Ericsson AB COH 901 571/3 GPIO driver");
-#endif
-
-#ifdef U300_COH901335
-MODULE_DESCRIPTION("ST-Ericsson AB COH 901 335 GPIO driver");
-#endif
-
-MODULE_LICENSE("GPL");
diff -druN linux-2.6.39-libre/arch/arm/mach-u300/include/mach/u300-regs.h linux-3.0-rc7-libre/arch/arm/mach-u300/include/mach/u300-regs.h
--- linux-2.6.39-libre/arch/arm/mach-u300/include/mach/u300-regs.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-u300/include/mach/u300-regs.h	2011-07-11 19:51:52.000000000 -0400
@@ -18,6 +18,12 @@
  * the defines are used for setting up the I/O memory mapping.
  */
 
+#ifdef __ASSEMBLER__
+#define IOMEM(a) (a)
+#else
+#define IOMEM(a) (void __iomem *) a
+#endif
+
 /* NAND Flash CS0 */
 #define U300_NAND_CS0_PHYS_BASE		0x80000000
 
@@ -48,13 +54,6 @@
 #endif
 
 /*
- * All the following peripherals are specified at their PHYSICAL address,
- * so if you need to access them (in the kernel), you MUST use the macros
- * defined in <asm/io.h> to map to the IO_ADDRESS_AHB() IO_ADDRESS_FAST()
- * etc.
- */
-
-/*
  * AHB peripherals
  */
 
@@ -63,11 +62,11 @@
 
 /* Vectored Interrupt Controller 0, servicing 32 interrupts */
 #define U300_INTCON0_BASE		(U300_AHB_PER_PHYS_BASE+0x1000)
-#define U300_INTCON0_VBASE		(U300_AHB_PER_VIRT_BASE+0x1000)
+#define U300_INTCON0_VBASE		IOMEM(U300_AHB_PER_VIRT_BASE+0x1000)
 
 /* Vectored Interrupt Controller 1, servicing 32 interrupts */
 #define U300_INTCON1_BASE		(U300_AHB_PER_PHYS_BASE+0x2000)
-#define U300_INTCON1_VBASE		(U300_AHB_PER_VIRT_BASE+0x2000)
+#define U300_INTCON1_VBASE		IOMEM(U300_AHB_PER_VIRT_BASE+0x2000)
 
 /* Memory Stick Pro (MSPRO) controller */
 #define U300_MSPRO_BASE			(U300_AHB_PER_PHYS_BASE+0x3000)
@@ -115,7 +114,7 @@
 
 /* SYSCON */
 #define U300_SYSCON_BASE		(U300_SLOW_PER_PHYS_BASE+0x1000)
-#define U300_SYSCON_VBASE		(U300_SLOW_PER_VIRT_BASE+0x1000)
+#define U300_SYSCON_VBASE		IOMEM(U300_SLOW_PER_VIRT_BASE+0x1000)
 
 /* Watchdog */
 #define U300_WDOG_BASE			(U300_SLOW_PER_PHYS_BASE+0x2000)
@@ -125,7 +124,7 @@
 
 /* APP side special timer */
 #define U300_TIMER_APP_BASE		(U300_SLOW_PER_PHYS_BASE+0x4000)
-#define U300_TIMER_APP_VBASE		(U300_SLOW_PER_VIRT_BASE+0x4000)
+#define U300_TIMER_APP_VBASE		IOMEM(U300_SLOW_PER_VIRT_BASE+0x4000)
 
 /* Keypad */
 #define U300_KEYPAD_BASE		(U300_SLOW_PER_PHYS_BASE+0x5000)
@@ -181,5 +180,4 @@
  * Virtual accessor macros for static devices
  */
 
-
 #endif
diff -druN linux-2.6.39-libre/arch/arm/mach-u300/Makefile linux-3.0-rc7-libre/arch/arm/mach-u300/Makefile
--- linux-2.6.39-libre/arch/arm/mach-u300/Makefile	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-u300/Makefile	2011-07-11 19:51:52.000000000 -0400
@@ -2,7 +2,7 @@
 # Makefile for the linux kernel, U300 machine.
 #
 
-obj-y		:= core.o clock.o timer.o gpio.o padmux.o
+obj-y		:= core.o clock.o timer.o padmux.o
 obj-m		:=
 obj-n		:=
 obj-		:=
diff -druN linux-2.6.39-libre/arch/arm/mach-u300/timer.c linux-3.0-rc7-libre/arch/arm/mach-u300/timer.c
--- linux-2.6.39-libre/arch/arm/mach-u300/timer.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-u300/timer.c	2011-07-11 19:51:52.000000000 -0400
@@ -333,20 +333,6 @@
 	.handler        = u300_timer_interrupt,
 };
 
-/* Use general purpose timer 2 as clock source */
-static cycle_t u300_get_cycles(struct clocksource *cs)
-{
-	return (cycles_t) readl(U300_TIMER_APP_VBASE + U300_TIMER_APP_GPT2CC);
-}
-
-static struct clocksource clocksource_u300_1mhz = {
-	.name           = "GPT2",
-	.rating         = 300, /* Reasonably fast and accurate clock source */
-	.read           = u300_get_cycles,
-	.mask           = CLOCKSOURCE_MASK(32), /* 32 bits */
-	.flags          = CLOCK_SOURCE_IS_CONTINUOUS,
-};
-
 /*
  * Override the global weak sched_clock symbol with this
  * local implementation which uses the clocksource to get some
@@ -422,9 +408,10 @@
 	writel(U300_TIMER_APP_EGPT2_TIMER_ENABLE,
 		U300_TIMER_APP_VBASE + U300_TIMER_APP_EGPT2);
 
-	if (clocksource_register_hz(&clocksource_u300_1mhz, rate))
-		printk(KERN_ERR "timer: failed to initialize clock "
-		       "source %s\n", clocksource_u300_1mhz.name);
+	/* Use general purpose timer 2 as clock source */
+	if (clocksource_mmio_init(U300_TIMER_APP_VBASE + U300_TIMER_APP_GPT2CC,
+			"GPT2", rate, 300, 32, clocksource_mmio_readl_up))
+		pr_err("timer: failed to initialize U300 clock source\n");
 
 	clockevents_calc_mult_shift(&clockevent_u300_1mhz,
 				    rate, APPTIMER_MIN_RANGE);
diff -druN linux-2.6.39-libre/arch/arm/mach-ux500/board-mop500.c linux-3.0-rc7-libre/arch/arm/mach-ux500/board-mop500.c
--- linux-2.6.39-libre/arch/arm/mach-ux500/board-mop500.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-ux500/board-mop500.c	2011-07-11 19:51:52.000000000 -0400
@@ -27,18 +27,21 @@
 #include <linux/leds-lp5521.h>
 #include <linux/input.h>
 #include <linux/gpio_keys.h>
+#include <linux/delay.h>
 
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 
 #include <plat/i2c.h>
 #include <plat/ste_dma40.h>
+#include <plat/pincfg.h>
 
 #include <mach/hardware.h>
 #include <mach/setup.h>
 #include <mach/devices.h>
 #include <mach/irqs.h>
 
+#include "pins-db8500.h"
 #include "ste-dma40-db8500.h"
 #include "devices-db8500.h"
 #include "board-mop500.h"
@@ -204,7 +207,7 @@
 	},
 };
 
-#define U8500_I2C_CONTROLLER(id, _slsu, _tft, _rft, clk, _sm) \
+#define U8500_I2C_CONTROLLER(id, _slsu, _tft, _rft, clk, t_out, _sm)	\
 static struct nmk_i2c_controller u8500_i2c##id##_data = { \
 	/*				\
 	 * slave data setup time, which is	\
@@ -219,19 +222,21 @@
 	.rft		= _rft,		\
 	/* std. mode operation */	\
 	.clk_freq	= clk,		\
+	/* Slave response timeout(ms) */\
+	.timeout	= t_out,	\
 	.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
+ * Tx & Rx FIFO threshold values as 8 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);
+U8500_I2C_CONTROLLER(0, 0xe, 1, 8, 100000, 200, I2C_FREQ_MODE_FAST);
+U8500_I2C_CONTROLLER(1, 0xe, 1, 8, 100000, 200, I2C_FREQ_MODE_FAST);
+U8500_I2C_CONTROLLER(2,	0xe, 1, 8, 100000, 200, I2C_FREQ_MODE_FAST);
+U8500_I2C_CONTROLLER(3,	0xe, 1, 8, 100000, 200, I2C_FREQ_MODE_FAST);
 
 static void __init mop500_i2c_init(void)
 {
@@ -391,12 +396,63 @@
 };
 #endif
 
+
+static pin_cfg_t mop500_pins_uart0[] = {
+	GPIO0_U0_CTSn   | PIN_INPUT_PULLUP,
+	GPIO1_U0_RTSn   | PIN_OUTPUT_HIGH,
+	GPIO2_U0_RXD    | PIN_INPUT_PULLUP,
+	GPIO3_U0_TXD    | PIN_OUTPUT_HIGH,
+};
+
+#define PRCC_K_SOFTRST_SET      0x18
+#define PRCC_K_SOFTRST_CLEAR    0x1C
+static void ux500_uart0_reset(void)
+{
+	void __iomem *prcc_rst_set, *prcc_rst_clr;
+
+	prcc_rst_set = (void __iomem *)IO_ADDRESS(U8500_CLKRST1_BASE +
+			PRCC_K_SOFTRST_SET);
+	prcc_rst_clr = (void __iomem *)IO_ADDRESS(U8500_CLKRST1_BASE +
+			PRCC_K_SOFTRST_CLEAR);
+
+	/* Activate soft reset PRCC_K_SOFTRST_CLEAR */
+	writel((readl(prcc_rst_clr) | 0x1), prcc_rst_clr);
+	udelay(1);
+
+	/* Release soft reset PRCC_K_SOFTRST_SET */
+	writel((readl(prcc_rst_set) | 0x1), prcc_rst_set);
+	udelay(1);
+}
+
+static void ux500_uart0_init(void)
+{
+	int ret;
+
+	ret = nmk_config_pins(mop500_pins_uart0,
+			ARRAY_SIZE(mop500_pins_uart0));
+	if (ret < 0)
+		pr_err("pl011: uart pins_enable failed\n");
+}
+
+static void ux500_uart0_exit(void)
+{
+	int ret;
+
+	ret = nmk_config_pins_sleep(mop500_pins_uart0,
+			ARRAY_SIZE(mop500_pins_uart0));
+	if (ret < 0)
+		pr_err("pl011: uart pins_disable failed\n");
+}
+
 static struct amba_pl011_data uart0_plat = {
 #ifdef CONFIG_STE_DMA40
 	.dma_filter = stedma40_filter,
 	.dma_rx_param = &uart0_dma_cfg_rx,
 	.dma_tx_param = &uart0_dma_cfg_tx,
 #endif
+	.init = ux500_uart0_init,
+	.exit = ux500_uart0_exit,
+	.reset = ux500_uart0_reset,
 };
 
 static struct amba_pl011_data uart1_plat = {
diff -druN linux-2.6.39-libre/arch/arm/mach-ux500/board-mop500-pins.c linux-3.0-rc7-libre/arch/arm/mach-ux500/board-mop500-pins.c
--- linux-2.6.39-libre/arch/arm/mach-ux500/board-mop500-pins.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-ux500/board-mop500-pins.c	2011-07-11 19:51:52.000000000 -0400
@@ -110,10 +110,18 @@
 	GPIO168_KP_O0,
 
 	/* UART */
-	GPIO0_U0_CTSn	| PIN_INPUT_PULLUP,
-	GPIO1_U0_RTSn	| PIN_OUTPUT_HIGH,
-	GPIO2_U0_RXD	| PIN_INPUT_PULLUP,
-	GPIO3_U0_TXD	| PIN_OUTPUT_HIGH,
+	/* uart-0 pins gpio configuration should be
+	 * kept intact to prevent glitch in tx line
+	 * when tty dev is opened. Later these pins
+	 * are configured to uart mop500_pins_uart0
+	 *
+	 * It will be replaced with uart configuration
+	 * once the issue is solved.
+	 */
+	GPIO0_GPIO	| PIN_INPUT_PULLUP,
+	GPIO1_GPIO	| PIN_OUTPUT_HIGH,
+	GPIO2_GPIO	| PIN_INPUT_PULLUP,
+	GPIO3_GPIO	| PIN_OUTPUT_HIGH,
 
 	GPIO29_U2_RXD	| PIN_INPUT_PULLUP,
 	GPIO30_U2_TXD	| PIN_OUTPUT_HIGH,
diff -druN linux-2.6.39-libre/arch/arm/mach-ux500/board-mop500-sdi.c linux-3.0-rc7-libre/arch/arm/mach-ux500/board-mop500-sdi.c
--- linux-2.6.39-libre/arch/arm/mach-ux500/board-mop500-sdi.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-ux500/board-mop500-sdi.c	2011-07-11 19:51:52.000000000 -0400
@@ -99,8 +99,11 @@
 	gpio_direction_output(sdi0_vsel, 0);
 	gpio_direction_output(sdi0_en, 1);
 
-	/* Add the device */
-	db8500_add_sdi0(&mop500_sdi0_data);
+	/* Add the device, force v2 to subrevision 1 */
+	if (cpu_is_u8500v2())
+		db8500_add_sdi0(&mop500_sdi0_data, 0x10480180);
+	else
+		db8500_add_sdi0(&mop500_sdi0_data, 0);
 }
 
 void mop500_sdi_tc35892_init(void)
@@ -188,13 +191,18 @@
 
 void __init mop500_sdi_init(void)
 {
+	u32 periphid = 0;
+
+	/* v2 has a new version of this block that need to be forced */
+	if (cpu_is_u8500v2())
+		periphid = 0x10480180;
 	/* PoP:ed eMMC on top of DB8500 v1.0 has problems with high speed */
 	if (!cpu_is_u8500v10())
 		mop500_sdi2_data.capabilities |= MMC_CAP_MMC_HIGHSPEED;
-	db8500_add_sdi2(&mop500_sdi2_data);
+	db8500_add_sdi2(&mop500_sdi2_data, periphid);
 
 	/* On-board eMMC */
-	db8500_add_sdi4(&mop500_sdi4_data);
+	db8500_add_sdi4(&mop500_sdi4_data, periphid);
 
 	if (machine_is_hrefv60()) {
 		mop500_sdi0_data.gpio_cd = HREFV60_SDMMC_CD_GPIO;
diff -druN linux-2.6.39-libre/arch/arm/mach-ux500/cpu.c linux-3.0-rc7-libre/arch/arm/mach-ux500/cpu.c
--- linux-2.6.39-libre/arch/arm/mach-ux500/cpu.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-ux500/cpu.c	2011-07-11 19:51:52.000000000 -0400
@@ -8,6 +8,8 @@
 #include <linux/platform_device.h>
 #include <linux/io.h>
 #include <linux/clk.h>
+#include <linux/mfd/db8500-prcmu.h>
+#include <linux/mfd/db5500-prcmu.h>
 
 #include <asm/cacheflush.h>
 #include <asm/hardware/cache-l2x0.h>
@@ -19,10 +21,11 @@
 #include <mach/hardware.h>
 #include <mach/setup.h>
 #include <mach/devices.h>
-#include <mach/prcmu.h>
 
 #include "clock.h"
 
+void __iomem *_PRCMU_BASE;
+
 #ifdef CONFIG_CACHE_L2X0
 static void __iomem *l2x0_base;
 #endif
@@ -47,6 +50,8 @@
 	 * Init clocks here so that they are available for system timer
 	 * initialization.
 	 */
+	if (cpu_is_u5500())
+		db5500_prcmu_early_init();
 	if (cpu_is_u8500())
 		prcmu_early_init();
 	clk_init();
diff -druN linux-2.6.39-libre/arch/arm/mach-ux500/cpu-db5500.c linux-3.0-rc7-libre/arch/arm/mach-ux500/cpu-db5500.c
--- linux-2.6.39-libre/arch/arm/mach-ux500/cpu-db5500.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-ux500/cpu-db5500.c	2011-07-11 19:51:52.000000000 -0400
@@ -188,6 +188,8 @@
 	ux500_map_io();
 
 	iotable_init(u5500_io_desc, ARRAY_SIZE(u5500_io_desc));
+
+	_PRCMU_BASE = __io_address(U5500_PRCMU_BASE);
 }
 
 static int usb_db5500_rx_dma_cfg[] = {
diff -druN linux-2.6.39-libre/arch/arm/mach-ux500/cpu-db8500.c linux-3.0-rc7-libre/arch/arm/mach-ux500/cpu-db8500.c
--- linux-2.6.39-libre/arch/arm/mach-ux500/cpu-db8500.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-ux500/cpu-db8500.c	2011-07-11 19:51:52.000000000 -0400
@@ -87,6 +87,8 @@
 		iotable_init(u8500_v1_io_desc, ARRAY_SIZE(u8500_v1_io_desc));
 	else if (cpu_is_u8500v2())
 		iotable_init(u8500_v2_io_desc, ARRAY_SIZE(u8500_v2_io_desc));
+
+	_PRCMU_BASE = __io_address(U8500_PRCMU_BASE);
 }
 
 static struct resource db8500_pmu_resources[] = {
@@ -129,9 +131,14 @@
 	.dev.platform_data	= &db8500_pmu_platdata,
 };
 
+static struct platform_device db8500_prcmu_device = {
+	.name			= "db8500-prcmu",
+};
+
 static struct platform_device *platform_devs[] __initdata = {
 	&u8500_dma40_device,
 	&db8500_pmu_device,
+	&db8500_prcmu_device,
 };
 
 static resource_size_t __initdata db8500_gpio_base[] = {
@@ -152,6 +159,9 @@
 		/* No custom data yet */
 	};
 
+	if (cpu_is_u8500v2())
+		pdata.supports_sleepmode = true;
+
 	dbx500_add_gpios(ARRAY_AND_SIZE(db8500_gpio_base),
 			 IRQ_DB8500_GPIO0, &pdata);
 }
diff -druN linux-2.6.39-libre/arch/arm/mach-ux500/cpufreq.c linux-3.0-rc7-libre/arch/arm/mach-ux500/cpufreq.c
--- linux-2.6.39-libre/arch/arm/mach-ux500/cpufreq.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-ux500/cpufreq.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,211 +0,0 @@
-/*
- * CPU frequency scaling for u8500
- * Inspired by linux/arch/arm/mach-davinci/cpufreq.c
- *
- * Copyright (C) STMicroelectronics 2009
- * Copyright (C) ST-Ericsson SA 2010
- *
- * License Terms: GNU General Public License v2
- *
- * Author: Sundar Iyer <sundar.iyer@stericsson.com>
- * Author: Martin Persson <martin.persson@stericsson.com>
- * Author: Jonas Aaberg <jonas.aberg@stericsson.com>
- *
- */
-
-#include <linux/platform_device.h>
-#include <linux/kernel.h>
-#include <linux/cpufreq.h>
-#include <linux/delay.h>
-
-#include <mach/hardware.h>
-#include <mach/prcmu.h>
-#include <mach/prcmu-defs.h>
-
-#define DRIVER_NAME "cpufreq-u8500"
-#define CPUFREQ_NAME "u8500"
-
-static struct device *dev;
-
-static struct cpufreq_frequency_table freq_table[] = {
-	[0] = {
-		.index = 0,
-		.frequency = 200000,
-	},
-	[1] = {
-		.index = 1,
-		.frequency = 300000,
-	},
-	[2] = {
-		.index = 2,
-		.frequency = 600000,
-	},
-	[3] = {
-		/* Used for CPU_OPP_MAX, if available */
-		.index = 3,
-		.frequency = CPUFREQ_TABLE_END,
-	},
-	[4] = {
-		.index = 4,
-		.frequency = CPUFREQ_TABLE_END,
-	},
-};
-
-static enum prcmu_cpu_opp index2opp[] = {
-	CPU_OPP_EXT_CLK,
-	CPU_OPP_50,
-	CPU_OPP_100,
-	CPU_OPP_MAX
-};
-
-static int u8500_cpufreq_verify_speed(struct cpufreq_policy *policy)
-{
-	return cpufreq_frequency_table_verify(policy, freq_table);
-}
-
-static int u8500_cpufreq_target(struct cpufreq_policy *policy,
-				unsigned int target_freq,
-				unsigned int relation)
-{
-	struct cpufreq_freqs freqs;
-	unsigned int index;
-	int ret = 0;
-
-	/*
-	 * Ensure desired rate is within allowed range.  Some govenors
-	 * (ondemand) will just pass target_freq=0 to get the minimum.
-	 */
-	if (target_freq < policy->cpuinfo.min_freq)
-		target_freq = policy->cpuinfo.min_freq;
-	if (target_freq > policy->cpuinfo.max_freq)
-		target_freq = policy->cpuinfo.max_freq;
-
-	ret = cpufreq_frequency_table_target(policy, freq_table,
-					     target_freq, relation, &index);
-	if (ret < 0) {
-		dev_err(dev, "Could not look up next frequency\n");
-		return ret;
-	}
-
-	freqs.old = policy->cur;
-	freqs.new = freq_table[index].frequency;
-	freqs.cpu = policy->cpu;
-
-	if (freqs.old == freqs.new) {
-		dev_dbg(dev, "Current and target frequencies are equal\n");
-		return 0;
-	}
-
-	dev_dbg(dev, "transition: %u --> %u\n", freqs.old, freqs.new);
-	cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
-
-	ret = prcmu_set_cpu_opp(index2opp[index]);
-	if (ret < 0) {
-		dev_err(dev, "Failed to set OPP level\n");
-		return ret;
-	}
-
-	cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
-
-	return ret;
-}
-
-static unsigned int u8500_cpufreq_getspeed(unsigned int cpu)
-{
-	int i;
-
-	for (i = 0; prcmu_get_cpu_opp() != index2opp[i]; i++)
-		;
-	return freq_table[i].frequency;
-}
-
-static int __cpuinit u8500_cpu_init(struct cpufreq_policy *policy)
-{
-	int res;
-
-	BUILD_BUG_ON(ARRAY_SIZE(index2opp) + 1 != ARRAY_SIZE(freq_table));
-
-	if (cpu_is_u8500v2()) {
-		freq_table[1].frequency = 400000;
-		freq_table[2].frequency = 800000;
-		if (prcmu_has_arm_maxopp())
-			freq_table[3].frequency = 1000000;
-	}
-
-	/* get policy fields based on the table */
-	res = cpufreq_frequency_table_cpuinfo(policy, freq_table);
-	if (!res)
-		cpufreq_frequency_table_get_attr(freq_table, policy->cpu);
-	else {
-		dev_err(dev, "u8500-cpufreq : Failed to read policy table\n");
-		return res;
-	}
-
-	policy->min = policy->cpuinfo.min_freq;
-	policy->max = policy->cpuinfo.max_freq;
-	policy->cur = u8500_cpufreq_getspeed(policy->cpu);
-	policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
-
-	/*
-	 * FIXME : Need to take time measurement across the target()
-	 *	   function with no/some/all drivers in the notification
-	 *	   list.
-	 */
-	policy->cpuinfo.transition_latency = 200 * 1000; /* in ns */
-
-	/* policy sharing between dual CPUs */
-	cpumask_copy(policy->cpus, &cpu_present_map);
-
-	policy->shared_type = CPUFREQ_SHARED_TYPE_ALL;
-
-	return res;
-}
-
-static struct freq_attr *u8500_cpufreq_attr[] = {
-	&cpufreq_freq_attr_scaling_available_freqs,
-	NULL,
-};
-static int u8500_cpu_exit(struct cpufreq_policy *policy)
-{
-	cpufreq_frequency_table_put_attr(policy->cpu);
-	return 0;
-}
-
-static struct cpufreq_driver u8500_driver = {
-	.owner = THIS_MODULE,
-	.flags = CPUFREQ_STICKY,
-	.verify = u8500_cpufreq_verify_speed,
-	.target = u8500_cpufreq_target,
-	.get = u8500_cpufreq_getspeed,
-	.init = u8500_cpu_init,
-	.exit = u8500_cpu_exit,
-	.name = CPUFREQ_NAME,
-	.attr = u8500_cpufreq_attr,
-};
-
-static int __init u8500_cpufreq_probe(struct platform_device *pdev)
-{
-	dev = &pdev->dev;
-	return cpufreq_register_driver(&u8500_driver);
-}
-
-static int __exit u8500_cpufreq_remove(struct platform_device *pdev)
-{
-	return cpufreq_unregister_driver(&u8500_driver);
-}
-
-static struct platform_driver u8500_cpufreq_driver = {
-	.driver = {
-		.name	 = DRIVER_NAME,
-		.owner	 = THIS_MODULE,
-	},
-	.remove = __exit_p(u8500_cpufreq_remove),
-};
-
-static int __init u8500_cpufreq_init(void)
-{
-	return platform_driver_probe(&u8500_cpufreq_driver,
-				     &u8500_cpufreq_probe);
-}
-
-device_initcall(u8500_cpufreq_init);
diff -druN linux-2.6.39-libre/arch/arm/mach-ux500/devices-common.h linux-3.0-rc7-libre/arch/arm/mach-ux500/devices-common.h
--- linux-2.6.39-libre/arch/arm/mach-ux500/devices-common.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-ux500/devices-common.h	2011-07-11 19:51:52.000000000 -0400
@@ -28,18 +28,20 @@
 
 static inline struct amba_device *
 dbx500_add_spi(const char *name, resource_size_t base, int irq,
-				   struct spi_master_cntlr *pdata)
+	       struct spi_master_cntlr *pdata,
+	       u32 periphid)
 {
-	return dbx500_add_amba_device(name, base, irq, pdata, 0);
+	return dbx500_add_amba_device(name, base, irq, pdata, periphid);
 }
 
 struct mmci_platform_data;
 
 static inline struct amba_device *
 dbx500_add_sdi(const char *name, resource_size_t base, int irq,
-	       struct mmci_platform_data *pdata)
+	       struct mmci_platform_data *pdata,
+	       u32 periphid)
 {
-	return dbx500_add_amba_device(name, base, irq, pdata, 0);
+	return dbx500_add_amba_device(name, base, irq, pdata, periphid);
 }
 
 struct amba_pl011_data;
diff -druN linux-2.6.39-libre/arch/arm/mach-ux500/devices-db5500.h linux-3.0-rc7-libre/arch/arm/mach-ux500/devices-db5500.h
--- linux-2.6.39-libre/arch/arm/mach-ux500/devices-db5500.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-ux500/devices-db5500.h	2011-07-11 19:51:52.000000000 -0400
@@ -38,24 +38,34 @@
 	ux500_add_usb(U5500_USBOTG_BASE, IRQ_DB5500_USBOTG, rx_cfg, tx_cfg)
 
 #define db5500_add_sdi0(pdata) \
-	dbx500_add_sdi("sdi0", U5500_SDI0_BASE, IRQ_DB5500_SDMMC0, pdata)
+	dbx500_add_sdi("sdi0", U5500_SDI0_BASE, IRQ_DB5500_SDMMC0, pdata, \
+		       0x10480180)
 #define db5500_add_sdi1(pdata) \
-	dbx500_add_sdi("sdi1", U5500_SDI1_BASE, IRQ_DB5500_SDMMC1, pdata)
+	dbx500_add_sdi("sdi1", U5500_SDI1_BASE, IRQ_DB5500_SDMMC1, pdata, \
+		       0x10480180)
 #define db5500_add_sdi2(pdata) \
-	dbx500_add_sdi("sdi2", U5500_SDI2_BASE, IRQ_DB5500_SDMMC2, pdata)
+	dbx500_add_sdi("sdi2", U5500_SDI2_BASE, IRQ_DB5500_SDMMC2, pdata \
+		       0x10480180)
 #define db5500_add_sdi3(pdata) \
-	dbx500_add_sdi("sdi3", U5500_SDI3_BASE, IRQ_DB5500_SDMMC3, pdata)
+	dbx500_add_sdi("sdi3", U5500_SDI3_BASE, IRQ_DB5500_SDMMC3, pdata \
+		       0x10480180)
 #define db5500_add_sdi4(pdata) \
-	dbx500_add_sdi("sdi4", U5500_SDI4_BASE, IRQ_DB5500_SDMMC4, pdata)
+	dbx500_add_sdi("sdi4", U5500_SDI4_BASE, IRQ_DB5500_SDMMC4, pdata \
+		       0x10480180)
 
+/* This one has a bad peripheral ID in the U5500 silicon */
 #define db5500_add_spi0(pdata) \
-	dbx500_add_spi("spi0", U5500_SPI0_BASE, IRQ_DB5500_SPI0, pdata)
+	dbx500_add_spi("spi0", U5500_SPI0_BASE, IRQ_DB5500_SPI0, pdata, \
+		       0x10080023)
 #define db5500_add_spi1(pdata) \
-	dbx500_add_spi("spi1", U5500_SPI1_BASE, IRQ_DB5500_SPI1, pdata)
+	dbx500_add_spi("spi1", U5500_SPI1_BASE, IRQ_DB5500_SPI1, pdata, \
+		       0x10080023)
 #define db5500_add_spi2(pdata) \
-	dbx500_add_spi("spi2", U5500_SPI2_BASE, IRQ_DB5500_SPI2, pdata)
+	dbx500_add_spi("spi2", U5500_SPI2_BASE, IRQ_DB5500_SPI2, pdata \
+		       0x10080023)
 #define db5500_add_spi3(pdata) \
-	dbx500_add_spi("spi3", U5500_SPI3_BASE, IRQ_DB5500_SPI3, pdata)
+	dbx500_add_spi("spi3", U5500_SPI3_BASE, IRQ_DB5500_SPI3, pdata \
+		       0x10080023)
 
 #define db5500_add_uart0(plat) \
 	dbx500_add_uart("uart0", U5500_UART0_BASE, IRQ_DB5500_UART0, plat)
diff -druN linux-2.6.39-libre/arch/arm/mach-ux500/devices-db8500.h linux-3.0-rc7-libre/arch/arm/mach-ux500/devices-db8500.h
--- linux-2.6.39-libre/arch/arm/mach-ux500/devices-db8500.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-ux500/devices-db8500.h	2011-07-11 19:51:52.000000000 -0400
@@ -25,7 +25,7 @@
 db8500_add_ssp(const char *name, resource_size_t base, int irq,
 	       struct pl022_ssp_controller *pdata)
 {
-	return dbx500_add_amba_device(name, base, irq, pdata, SSP_PER_ID);
+	return dbx500_add_amba_device(name, base, irq, pdata, 0);
 }
 
 
@@ -64,18 +64,18 @@
 #define db8500_add_usb(rx_cfg, tx_cfg) \
 	ux500_add_usb(U8500_USBOTG_BASE, IRQ_DB8500_USBOTG, rx_cfg, tx_cfg)
 
-#define db8500_add_sdi0(pdata) \
-	dbx500_add_sdi("sdi0", U8500_SDI0_BASE, IRQ_DB8500_SDMMC0, pdata)
-#define db8500_add_sdi1(pdata) \
-	dbx500_add_sdi("sdi1", U8500_SDI1_BASE, IRQ_DB8500_SDMMC1, pdata)
-#define db8500_add_sdi2(pdata) \
-	dbx500_add_sdi("sdi2", U8500_SDI2_BASE, IRQ_DB8500_SDMMC2, pdata)
-#define db8500_add_sdi3(pdata) \
-	dbx500_add_sdi("sdi3", U8500_SDI3_BASE, IRQ_DB8500_SDMMC3, pdata)
-#define db8500_add_sdi4(pdata) \
-	dbx500_add_sdi("sdi4", U8500_SDI4_BASE, IRQ_DB8500_SDMMC4, pdata)
-#define db8500_add_sdi5(pdata) \
-	dbx500_add_sdi("sdi5", U8500_SDI5_BASE, IRQ_DB8500_SDMMC5, pdata)
+#define db8500_add_sdi0(pdata, pid) \
+	dbx500_add_sdi("sdi0", U8500_SDI0_BASE, IRQ_DB8500_SDMMC0, pdata, pid)
+#define db8500_add_sdi1(pdata, pid) \
+	dbx500_add_sdi("sdi1", U8500_SDI1_BASE, IRQ_DB8500_SDMMC1, pdata, pid)
+#define db8500_add_sdi2(pdata, pid) \
+	dbx500_add_sdi("sdi2", U8500_SDI2_BASE, IRQ_DB8500_SDMMC2, pdata, pid)
+#define db8500_add_sdi3(pdata, pid) \
+	dbx500_add_sdi("sdi3", U8500_SDI3_BASE, IRQ_DB8500_SDMMC3, pdata, pid)
+#define db8500_add_sdi4(pdata, pid) \
+	dbx500_add_sdi("sdi4", U8500_SDI4_BASE, IRQ_DB8500_SDMMC4, pdata, pid)
+#define db8500_add_sdi5(pdata, pid) \
+	dbx500_add_sdi("sdi5", U8500_SDI5_BASE, IRQ_DB8500_SDMMC5, pdata, pid)
 
 #define db8500_add_ssp0(pdata) \
 	db8500_add_ssp("ssp0", U8500_SSP0_BASE, IRQ_DB8500_SSP0, pdata)
@@ -83,13 +83,13 @@
 	db8500_add_ssp("ssp1", U8500_SSP1_BASE, IRQ_DB8500_SSP1, pdata)
 
 #define db8500_add_spi0(pdata) \
-	dbx500_add_spi("spi0", U8500_SPI0_BASE, IRQ_DB8500_SPI0, pdata)
+	dbx500_add_spi("spi0", U8500_SPI0_BASE, IRQ_DB8500_SPI0, pdata, 0)
 #define db8500_add_spi1(pdata) \
-	dbx500_add_spi("spi1", U8500_SPI1_BASE, IRQ_DB8500_SPI1, pdata)
+	dbx500_add_spi("spi1", U8500_SPI1_BASE, IRQ_DB8500_SPI1, pdata, 0)
 #define db8500_add_spi2(pdata) \
-	dbx500_add_spi("spi2", U8500_SPI2_BASE, IRQ_DB8500_SPI2, pdata)
+	dbx500_add_spi("spi2", U8500_SPI2_BASE, IRQ_DB8500_SPI2, pdata, 0)
 #define db8500_add_spi3(pdata) \
-	dbx500_add_spi("spi3", U8500_SPI3_BASE, IRQ_DB8500_SPI3, pdata)
+	dbx500_add_spi("spi3", U8500_SPI3_BASE, IRQ_DB8500_SPI3, pdata, 0)
 
 #define db8500_add_uart0(pdata) \
 	dbx500_add_uart("uart0", U8500_UART0_BASE, IRQ_DB8500_UART0, pdata)
diff -druN linux-2.6.39-libre/arch/arm/mach-ux500/include/mach/db5500-regs.h linux-3.0-rc7-libre/arch/arm/mach-ux500/include/mach/db5500-regs.h
--- linux-2.6.39-libre/arch/arm/mach-ux500/include/mach/db5500-regs.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-ux500/include/mach/db5500-regs.h	2011-07-11 19:51:52.000000000 -0400
@@ -17,6 +17,8 @@
 #define U5500_GIC_DIST_BASE	0xA0411000
 #define U5500_GIC_CPU_BASE	0xA0410100
 #define U5500_DMA_BASE		0x90030000
+#define U5500_STM_BASE		0x90020000
+#define U5500_STM_REG_BASE	(U5500_STM_BASE + 0xF000)
 #define U5500_MCDE_BASE		0xA0400000
 #define U5500_MODEM_BASE	0xB0000000
 #define U5500_L2CC_BASE		0xA0412000
@@ -29,7 +31,9 @@
 #define U5500_NAND0_BASE	0x60000000
 #define U5500_NAND1_BASE	0x70000000
 #define U5500_TWD_BASE		0xa0410600
+#define U5500_ICN_BASE		0xA0040000
 #define U5500_B2R2_BASE		0xa0200000
+#define U5500_BOOT_ROM_BASE	0x90000000
 
 #define U5500_FSMC_BASE		(U5500_PER1_BASE + 0x0000)
 #define U5500_SDI0_BASE		(U5500_PER1_BASE + 0x1000)
@@ -60,6 +64,7 @@
 #define U5500_MSP1_BASE		(U5500_PER4_BASE + 0x9000)
 #define U5500_GPIO2_BASE	(U5500_PER4_BASE + 0xA000)
 #define U5500_CDETECT_BASE	(U5500_PER4_BASE + 0xF000)
+#define U5500_PRCMU_TCDM_BASE	(U5500_PER4_BASE + 0x18000)
 
 #define U5500_SPI0_BASE		(U5500_PER5_BASE + 0x0000)
 #define U5500_SPI1_BASE		(U5500_PER5_BASE + 0x1000)
@@ -83,7 +88,7 @@
 #define U5500_HASH0_BASE	(U5500_PER6_BASE + 0x1000)
 #define U5500_HASH1_BASE	(U5500_PER6_BASE + 0x2000)
 #define U5500_PKA_BASE		(U5500_PER6_BASE + 0x4000)
-#define U5500_PKAM_BASE		(U5500_PER6_BASE + 0x5000)
+#define U5500_PKAM_BASE		(U5500_PER6_BASE + 0x5100)
 #define U5500_MTU0_BASE		(U5500_PER6_BASE + 0x6000)
 #define U5500_MTU1_BASE		(U5500_PER6_BASE + 0x7000)
 #define U5500_CR_BASE		(U5500_PER6_BASE + 0x8000)
@@ -114,8 +119,19 @@
 #define U5500_MBOX2_LOCAL_START	(U5500_MBOX_BASE + 0x20)
 #define U5500_MBOX2_LOCAL_END	(U5500_MBOX_BASE + 0x3F)
 
-#define U5500_ESRAM_BASE		0x40000000
+#define U5500_ACCCON_BASE_SEC	(0xBFFF0000)
+#define U5500_ACCCON_BASE		(0xBFFF1000)
+#define U5500_ACCCON_CPUVEC_RESET_ADDR_OFFSET (0x00000020)
+#define U5500_ACCCON_ACC_CPU_CTRL_OFFSET (0x000000BC)
+
+#define U5500_ESRAM_BASE	        0x40000000
 #define U5500_ESRAM_DMA_LCPA_OFFSET	0x10000
 #define U5500_DMA_LCPA_BASE    (U5500_ESRAM_BASE + U5500_ESRAM_DMA_LCPA_OFFSET)
 
+#define U5500_MCDE_SIZE		0x1000
+#define U5500_DSI_LINK_SIZE	0x1000
+#define U5500_DSI_LINK_COUNT	0x2
+#define U5500_DSI_LINK1_BASE	(U5500_MCDE_BASE + U5500_MCDE_SIZE)
+#define U5500_DSI_LINK2_BASE	(U5500_DSI_LINK1_BASE + U5500_DSI_LINK_SIZE)
+
 #endif
diff -druN linux-2.6.39-libre/arch/arm/mach-ux500/include/mach/db8500-regs.h linux-3.0-rc7-libre/arch/arm/mach-ux500/include/mach/db8500-regs.h
--- linux-2.6.39-libre/arch/arm/mach-ux500/include/mach/db8500-regs.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-ux500/include/mach/db8500-regs.h	2011-07-11 19:51:52.000000000 -0400
@@ -15,8 +15,13 @@
 #define U8500_ESRAM_BANK2	(U8500_ESRAM_BANK1 + U8500_ESRAM_BANK_SIZE)
 #define U8500_ESRAM_BANK3	(U8500_ESRAM_BANK2 + U8500_ESRAM_BANK_SIZE)
 #define U8500_ESRAM_BANK4	(U8500_ESRAM_BANK3 + U8500_ESRAM_BANK_SIZE)
-/* Use bank 4 for DMA LCPA */
-#define U8500_DMA_LCPA_BASE	U8500_ESRAM_BANK4
+/*
+ * on V1 DMA uses 4KB for logical parameters position is right after the 64KB
+ * reserved for security
+ */
+#define U8500_ESRAM_DMA_LCPA_OFFSET     0x10000
+
+#define U8500_DMA_LCPA_BASE    (U8500_ESRAM_BANK0 + U8500_ESRAM_DMA_LCPA_OFFSET)
 #define U8500_DMA_LCPA_BASE_ED	(U8500_ESRAM_BANK4 + 0x4000)
 
 #define U8500_PER3_BASE		0x80000000
@@ -27,9 +32,12 @@
 #define U8500_B2R2_BASE		0x80130000
 #define U8500_HSEM_BASE		0x80140000
 #define U8500_PER4_BASE		0x80150000
+#define U8500_TPIU_BASE		0x80190000
 #define U8500_ICN_BASE		0x81000000
 
 #define U8500_BOOT_ROM_BASE	0x90000000
+/* ASIC ID is at 0xbf4 offset within this region */
+#define U8500_ASIC_ID_BASE	0x9001D000
 
 #define U8500_PER6_BASE		0xa03c0000
 #define U8500_PER5_BASE		0xa03e0000
@@ -70,13 +78,15 @@
 
 /* per6 base addresses */
 #define U8500_RNG_BASE		(U8500_PER6_BASE + 0x0000)
-#define U8500_PKA_BASE		(U8500_PER6_BASE + 0x1000)
-#define U8500_PKAM_BASE		(U8500_PER6_BASE + 0x2000)
+#define U8500_HASH0_BASE        (U8500_PER6_BASE + 0x1000)
+#define U8500_HASH1_BASE        (U8500_PER6_BASE + 0x2000)
+#define U8500_PKA_BASE		(U8500_PER6_BASE + 0x4000)
+#define U8500_PKAM_BASE		(U8500_PER6_BASE + 0x5100)
 #define U8500_MTU0_BASE		(U8500_PER6_BASE + 0x6000) /* v1 */
 #define U8500_MTU1_BASE		(U8500_PER6_BASE + 0x7000) /* v1 */
 #define U8500_CR_BASE		(U8500_PER6_BASE + 0x8000) /* v1 */
-#define U8500_CRYPTO0_BASE	(U8500_PER6_BASE + 0xa000)
-#define U8500_CRYPTO1_BASE	(U8500_PER6_BASE + 0xb000)
+#define U8500_CRYP0_BASE	(U8500_PER6_BASE + 0xa000)
+#define U8500_CRYP1_BASE	(U8500_PER6_BASE + 0xb000)
 #define U8500_CLKRST6_BASE	(U8500_PER6_BASE + 0xf000)
 
 /* per5 base addresses */
@@ -93,7 +103,8 @@
 #define U8500_DMC_BASE		(U8500_PER4_BASE + 0x06000)
 #define U8500_PRCMU_BASE	(U8500_PER4_BASE + 0x07000)
 #define U8500_PRCMU_TCDM_BASE_V1 (U8500_PER4_BASE + 0x0f000)
-#define U8500_PRCMU_TCDM_BASE   (U8500_PER4_BASE + 0x68000)
+#define U8500_PRCMU_TCDM_BASE	(U8500_PER4_BASE + 0x68000)
+#define U8500_PRCMU_TCPM_BASE   (U8500_PER4_BASE + 0x60000)
 
 /* per3 base addresses */
 #define U8500_FSMC_BASE		(U8500_PER3_BASE + 0x0000)
@@ -124,6 +135,7 @@
 #define U8500_I2C1_BASE		(U8500_PER1_BASE + 0x2000)
 #define U8500_MSP0_BASE		(U8500_PER1_BASE + 0x3000)
 #define U8500_MSP1_BASE		(U8500_PER1_BASE + 0x4000)
+#define U8500_MSP3_BASE		(U8500_PER1_BASE + 0x5000)
 #define U8500_SDI0_BASE		(U8500_PER1_BASE + 0x6000)
 #define U8500_I2C2_BASE		(U8500_PER1_BASE + 0x8000)
 #define U8500_SPI3_BASE		(U8500_PER1_BASE + 0x9000)
@@ -143,4 +155,15 @@
 #define U8500_GPIOBANK7_BASE	(U8500_GPIO2_BASE + 0x80)
 #define U8500_GPIOBANK8_BASE	U8500_GPIO3_BASE
 
+#define U8500_MCDE_SIZE		0x1000
+#define U8500_DSI_LINK_SIZE	0x1000
+#define U8500_DSI_LINK1_BASE	(U8500_MCDE_BASE + U8500_MCDE_SIZE)
+#define U8500_DSI_LINK2_BASE	(U8500_DSI_LINK1_BASE + U8500_DSI_LINK_SIZE)
+#define U8500_DSI_LINK3_BASE	(U8500_DSI_LINK2_BASE + U8500_DSI_LINK_SIZE)
+#define U8500_DSI_LINK_COUNT	0x3
+
+/* Modem and APE physical addresses */
+#define U8500_MODEM_BASE	0xe000000
+#define U8500_APE_BASE		0x6000000
+
 #endif
diff -druN linux-2.6.39-libre/arch/arm/mach-ux500/include/mach/hardware.h linux-3.0-rc7-libre/arch/arm/mach-ux500/include/mach/hardware.h
--- linux-2.6.39-libre/arch/arm/mach-ux500/include/mach/hardware.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-ux500/include/mach/hardware.h	2011-07-11 19:51:52.000000000 -0400
@@ -29,12 +29,10 @@
 #include <mach/db8500-regs.h>
 #include <mach/db5500-regs.h>
 
-/* ST-Ericsson modified pl022 id */
-#define SSP_PER_ID		0x01080022
-
 #ifndef __ASSEMBLY__
 
 #include <mach/id.h>
+extern void __iomem *_PRCMU_BASE;
 
 #define ARRAY_AND_SIZE(x)	(x), ARRAY_SIZE(x)
 
diff -druN linux-2.6.39-libre/arch/arm/mach-ux500/include/mach/id.h linux-3.0-rc7-libre/arch/arm/mach-ux500/include/mach/id.h
--- linux-2.6.39-libre/arch/arm/mach-ux500/include/mach/id.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-ux500/include/mach/id.h	2011-07-11 19:51:52.000000000 -0400
@@ -75,6 +75,26 @@
 	return cpu_is_u8500() && ((dbx500_revision() & 0xf0) == 0xB0);
 }
 
+static inline bool cpu_is_u8500v20(void)
+{
+	return cpu_is_u8500() && (dbx500_revision() == 0xB0);
+}
+
+static inline bool cpu_is_u8500v21(void)
+{
+	return cpu_is_u8500() && (dbx500_revision() == 0xB1);
+}
+
+static inline bool cpu_is_u8500v20_or_later(void)
+{
+	return cpu_is_u8500() && !cpu_is_u8500v10() && !cpu_is_u8500v11();
+}
+
+static inline bool ux500_is_svp(void)
+{
+	return false;
+}
+
 #define ux500_unknown_soc()	BUG()
 
 #endif
diff -druN linux-2.6.39-libre/arch/arm/mach-ux500/include/mach/irqs-board-mop500.h linux-3.0-rc7-libre/arch/arm/mach-ux500/include/mach/irqs-board-mop500.h
--- linux-2.6.39-libre/arch/arm/mach-ux500/include/mach/irqs-board-mop500.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-ux500/include/mach/irqs-board-mop500.h	2011-07-11 19:51:52.000000000 -0400
@@ -50,6 +50,11 @@
 
 #define MOP500_IRQ_END		MOP500_NR_IRQS
 
+/*
+ * We may have several boards, but only one will run at a
+ * time, so the one with most IRQs will bump this ahead,
+ * but the IRQ_BOARD_START remains the same for either board.
+ */
 #if MOP500_IRQ_END > IRQ_BOARD_END
 #undef IRQ_BOARD_END
 #define IRQ_BOARD_END	MOP500_IRQ_END
diff -druN linux-2.6.39-libre/arch/arm/mach-ux500/include/mach/irqs-board-u5500.h linux-3.0-rc7-libre/arch/arm/mach-ux500/include/mach/irqs-board-u5500.h
--- linux-2.6.39-libre/arch/arm/mach-ux500/include/mach/irqs-board-u5500.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/arm/mach-ux500/include/mach/irqs-board-u5500.h	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2010
+ *
+ * License terms: GNU General Public License (GPL) version 2
+ */
+
+#ifndef __MACH_IRQS_BOARD_U5500_H
+#define __MACH_IRQS_BOARD_U5500_H
+
+#define AB5500_NR_IRQS		5
+#define IRQ_AB5500_BASE		IRQ_BOARD_START
+#define IRQ_AB5500_END		(IRQ_AB5500_BASE + AB5500_NR_IRQS)
+
+#define U5500_IRQ_END		IRQ_AB5500_END
+
+#if IRQ_BOARD_END < U5500_IRQ_END
+#undef IRQ_BOARD_END
+#define IRQ_BOARD_END		U5500_IRQ_END
+#endif
+
+#endif
diff -druN linux-2.6.39-libre/arch/arm/mach-ux500/include/mach/irqs-db5500.h linux-3.0-rc7-libre/arch/arm/mach-ux500/include/mach/irqs-db5500.h
--- linux-2.6.39-libre/arch/arm/mach-ux500/include/mach/irqs-db5500.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-ux500/include/mach/irqs-db5500.h	2011-07-11 19:51:52.000000000 -0400
@@ -83,4 +83,31 @@
 #define IRQ_DB5500_GPIO6		(IRQ_SHPI_START + 125)
 #define IRQ_DB5500_GPIO7		(IRQ_SHPI_START + 126)
 
+#ifdef CONFIG_UX500_SOC_DB5500
+
+/*
+ * After the GPIO ones we reserve a range of IRQ:s in which virtual
+ * IRQ:s representing modem IRQ:s can be allocated
+ */
+#define IRQ_MODEM_EVENTS_BASE	IRQ_SOC_START
+#define IRQ_MODEM_EVENTS_NBR	72
+#define IRQ_MODEM_EVENTS_END	(IRQ_MODEM_EVENTS_BASE + IRQ_MODEM_EVENTS_NBR)
+
+/* List of virtual IRQ:s that are allocated from the range above */
+#define MBOX_PAIR0_VIRT_IRQ	(IRQ_MODEM_EVENTS_BASE + 43)
+#define MBOX_PAIR1_VIRT_IRQ	(IRQ_MODEM_EVENTS_BASE + 45)
+#define MBOX_PAIR2_VIRT_IRQ	(IRQ_MODEM_EVENTS_BASE + 41)
+
+/*
+ * We may have several SoCs, but only one will run at a
+ * time, so the one with most IRQs will bump this ahead,
+ * but the IRQ_SOC_START remains the same for either SoC.
+ */
+#if IRQ_SOC_END < IRQ_MODEM_EVENTS_END
+#undef IRQ_SOC_END
+#define IRQ_SOC_END		IRQ_MODEM_EVENTS_END
+#endif
+
+#endif /* CONFIG_UX500_SOC_DB5500 */
+
 #endif
diff -druN linux-2.6.39-libre/arch/arm/mach-ux500/include/mach/irqs-db8500.h linux-3.0-rc7-libre/arch/arm/mach-ux500/include/mach/irqs-db8500.h
--- linux-2.6.39-libre/arch/arm/mach-ux500/include/mach/irqs-db8500.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-ux500/include/mach/irqs-db8500.h	2011-07-11 19:51:52.000000000 -0400
@@ -93,4 +93,58 @@
 #define IRQ_DB8500_GPIO7		(IRQ_SHPI_START + 126)
 #define IRQ_DB8500_GPIO8		(IRQ_SHPI_START + 127)
 
+#define IRQ_CA_WAKE_REQ_ED			(IRQ_SHPI_START + 71)
+#define IRQ_AC_READ_NOTIFICATION_0_ED		(IRQ_SHPI_START + 66)
+#define IRQ_AC_READ_NOTIFICATION_1_ED		(IRQ_SHPI_START + 64)
+#define IRQ_CA_MSG_PEND_NOTIFICATION_0_ED	(IRQ_SHPI_START + 67)
+#define IRQ_CA_MSG_PEND_NOTIFICATION_1_ED	(IRQ_SHPI_START + 65)
+
+#define IRQ_CA_WAKE_REQ_V1			(IRQ_SHPI_START + 83)
+#define IRQ_AC_READ_NOTIFICATION_0_V1		(IRQ_SHPI_START + 78)
+#define IRQ_AC_READ_NOTIFICATION_1_V1		(IRQ_SHPI_START + 76)
+#define IRQ_CA_MSG_PEND_NOTIFICATION_0_V1	(IRQ_SHPI_START + 79)
+#define IRQ_CA_MSG_PEND_NOTIFICATION_1_V1	(IRQ_SHPI_START + 77)
+
+#ifdef CONFIG_UX500_SOC_DB8500
+
+/* Virtual interrupts corresponding to the PRCMU wakeups.  */
+#define IRQ_PRCMU_BASE IRQ_SOC_START
+#define NUM_PRCMU_WAKEUPS (IRQ_PRCMU_END - IRQ_PRCMU_BASE)
+
+#define IRQ_PRCMU_RTC (IRQ_PRCMU_BASE)
+#define IRQ_PRCMU_RTT0 (IRQ_PRCMU_BASE + 1)
+#define IRQ_PRCMU_RTT1 (IRQ_PRCMU_BASE + 2)
+#define IRQ_PRCMU_HSI0 (IRQ_PRCMU_BASE + 3)
+#define IRQ_PRCMU_HSI1 (IRQ_PRCMU_BASE + 4)
+#define IRQ_PRCMU_CA_WAKE (IRQ_PRCMU_BASE + 5)
+#define IRQ_PRCMU_USB (IRQ_PRCMU_BASE + 6)
+#define IRQ_PRCMU_ABB (IRQ_PRCMU_BASE + 7)
+#define IRQ_PRCMU_ABB_FIFO (IRQ_PRCMU_BASE + 8)
+#define IRQ_PRCMU_ARM (IRQ_PRCMU_BASE + 9)
+#define IRQ_PRCMU_MODEM_SW_RESET_REQ (IRQ_PRCMU_BASE + 10)
+#define IRQ_PRCMU_GPIO0 (IRQ_PRCMU_BASE + 11)
+#define IRQ_PRCMU_GPIO1 (IRQ_PRCMU_BASE + 12)
+#define IRQ_PRCMU_GPIO2 (IRQ_PRCMU_BASE + 13)
+#define IRQ_PRCMU_GPIO3 (IRQ_PRCMU_BASE + 14)
+#define IRQ_PRCMU_GPIO4 (IRQ_PRCMU_BASE + 15)
+#define IRQ_PRCMU_GPIO5 (IRQ_PRCMU_BASE + 16)
+#define IRQ_PRCMU_GPIO6 (IRQ_PRCMU_BASE + 17)
+#define IRQ_PRCMU_GPIO7 (IRQ_PRCMU_BASE + 18)
+#define IRQ_PRCMU_GPIO8 (IRQ_PRCMU_BASE + 19)
+#define IRQ_PRCMU_CA_SLEEP (IRQ_PRCMU_BASE + 20)
+#define IRQ_PRCMU_HOTMON_LOW (IRQ_PRCMU_BASE + 21)
+#define IRQ_PRCMU_HOTMON_HIGH (IRQ_PRCMU_BASE + 22)
+#define IRQ_PRCMU_END (IRQ_PRCMU_BASE + 23)
+
+/*
+ * We may have several SoCs, but only one will run at a
+ * time, so the one with most IRQs will bump this ahead,
+ * but the IRQ_SOC_START remains the same for either SoC.
+ */
+#if IRQ_SOC_END < IRQ_PRCMU_END
+#undef IRQ_SOC_END
+#define IRQ_SOC_END IRQ_PRCMU_END
+#endif
+
+#endif /* CONFIG_UX500_SOC_DB8500 */
 #endif
diff -druN linux-2.6.39-libre/arch/arm/mach-ux500/include/mach/irqs.h linux-3.0-rc7-libre/arch/arm/mach-ux500/include/mach/irqs.h
--- linux-2.6.39-libre/arch/arm/mach-ux500/include/mach/irqs.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-ux500/include/mach/irqs.h	2011-07-11 19:51:52.000000000 -0400
@@ -10,49 +10,47 @@
 #ifndef ASM_ARCH_IRQS_H
 #define ASM_ARCH_IRQS_H
 
-#include <mach/irqs-db5500.h>
-#include <mach/irqs-db8500.h>
+#include <mach/hardware.h>
 
-#define IRQ_LOCALTIMER                  29
-#define IRQ_LOCALWDOG                   30
+#define IRQ_LOCALTIMER			29
+#define IRQ_LOCALWDOG			30
 
 /* Shared Peripheral Interrupt (SHPI) */
 #define IRQ_SHPI_START			32
 
-/* Interrupt numbers generic for shared peripheral */
+/*
+ * MTU0 preserved for now until plat-nomadik is taught not to use it.  Don't
+ * add any other IRQs here, use the irqs-dbx500.h files.
+ */
 #define IRQ_MTU0		(IRQ_SHPI_START + 4)
 
-/* There are 128 shared peripheral interrupts assigned to
- * INTID[160:32]. The first 32 interrupts are reserved.
- */
-#define DBX500_NR_INTERNAL_IRQS		161
+#define DBX500_NR_INTERNAL_IRQS		160
 
 /* After chip-specific IRQ numbers we have the GPIO ones */
 #define NOMADIK_NR_GPIO			288
 #define NOMADIK_GPIO_TO_IRQ(gpio)	((gpio) + DBX500_NR_INTERNAL_IRQS)
 #define NOMADIK_IRQ_TO_GPIO(irq)	((irq) - DBX500_NR_INTERNAL_IRQS)
-#define IRQ_BOARD_START			NOMADIK_GPIO_TO_IRQ(NOMADIK_NR_GPIO)
+#define IRQ_GPIO_END			NOMADIK_GPIO_TO_IRQ(NOMADIK_NR_GPIO)
+
+#define IRQ_SOC_START		IRQ_GPIO_END
+/* This will be overridden by SoC-specific irq headers */
+#define IRQ_SOC_END		IRQ_SOC_START
 
+#include <mach/irqs-db5500.h>
+#include <mach/irqs-db8500.h>
+
+#define IRQ_BOARD_START		IRQ_SOC_END
 /* This will be overridden by board-specific irq headers */
-#define IRQ_BOARD_END			IRQ_BOARD_START
+#define IRQ_BOARD_END		IRQ_BOARD_START
 
 #ifdef CONFIG_MACH_U8500
 #include <mach/irqs-board-mop500.h>
 #endif
 
-/*
- * After the board specific IRQ:s we reserve a range of IRQ:s in which virtual
- * IRQ:s representing modem IRQ:s can be allocated
- */
-#define IRQ_MODEM_EVENTS_BASE (IRQ_BOARD_END + 1)
-#define IRQ_MODEM_EVENTS_NBR 72
-#define IRQ_MODEM_EVENTS_END (IRQ_MODEM_EVENTS_BASE + IRQ_MODEM_EVENTS_NBR)
-
-/* List of virtual IRQ:s that are allocated from the range above */
-#define MBOX_PAIR0_VIRT_IRQ (IRQ_MODEM_EVENTS_BASE + 43)
-#define MBOX_PAIR1_VIRT_IRQ (IRQ_MODEM_EVENTS_BASE + 45)
-#define MBOX_PAIR2_VIRT_IRQ (IRQ_MODEM_EVENTS_BASE + 41)
+#ifdef CONFIG_MACH_U5500
+#include <mach/irqs-board-u5500.h>
+#endif
 
-#define NR_IRQS				IRQ_MODEM_EVENTS_END
+#define NR_IRQS			IRQ_BOARD_END
 
 #endif /* ASM_ARCH_IRQS_H */
diff -druN linux-2.6.39-libre/arch/arm/mach-ux500/include/mach/prcmu-defs.h linux-3.0-rc7-libre/arch/arm/mach-ux500/include/mach/prcmu-defs.h
--- linux-2.6.39-libre/arch/arm/mach-ux500/include/mach/prcmu-defs.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-ux500/include/mach/prcmu-defs.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,30 +0,0 @@
-/*
- * Copyright (C) STMicroelectronics 2009
- * Copyright (C) ST-Ericsson SA 2010
- *
- * Author: Sundar Iyer <sundar.iyer@stericsson.com>
- * Author: Martin Persson <martin.persson@stericsson.com>
- *
- * License Terms: GNU General Public License v2
- *
- * PRCM Unit definitions
- */
-
-#ifndef __MACH_PRCMU_DEFS_H
-#define __MACH_PRCMU_DEFS_H
-
-enum prcmu_cpu_opp {
-	CPU_OPP_INIT	  = 0x00,
-	CPU_OPP_NO_CHANGE = 0x01,
-	CPU_OPP_100	  = 0x02,
-	CPU_OPP_50	  = 0x03,
-	CPU_OPP_MAX	  = 0x04,
-	CPU_OPP_EXT_CLK	  = 0x07
-};
-enum prcmu_ape_opp {
-	APE_OPP_NO_CHANGE = 0x00,
-	APE_OPP_100	  = 0x02,
-	APE_OPP_50	  = 0x03,
-};
-
-#endif /* __MACH_PRCMU_DEFS_H */
diff -druN linux-2.6.39-libre/arch/arm/mach-ux500/include/mach/prcmu.h linux-3.0-rc7-libre/arch/arm/mach-ux500/include/mach/prcmu.h
--- linux-2.6.39-libre/arch/arm/mach-ux500/include/mach/prcmu.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-ux500/include/mach/prcmu.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,28 +0,0 @@
-/*
- * Copyright (C) STMicroelectronics 2009
- * Copyright (C) ST-Ericsson SA 2010
- *
- * Author: Kumar Sanghvi <kumar.sanghvi@stericsson.com>
- * Author: Sundar Iyer <sundar.iyer@stericsson.com>
- * Author: Mattias Nilsson <mattias.i.nilsson@stericsson.com>
- *
- * License Terms: GNU General Public License v2
- *
- * PRCM Unit f/w API
- */
-#ifndef __MACH_PRCMU_H
-#define __MACH_PRCMU_H
-#include <mach/prcmu-defs.h>
-
-void __init prcmu_early_init(void);
-int prcmu_abb_read(u8 slave, u8 reg, u8 *value, u8 size);
-int prcmu_abb_write(u8 slave, u8 reg, u8 *value, u8 size);
-int prcmu_set_ape_opp(enum prcmu_ape_opp opp);
-int prcmu_set_cpu_opp(enum prcmu_cpu_opp opp);
-int prcmu_set_ape_cpu_opps(enum prcmu_ape_opp ape_opp,
-			   enum prcmu_cpu_opp cpu_opp);
-int prcmu_get_ape_opp(void);
-int prcmu_get_cpu_opp(void);
-bool prcmu_has_arm_maxopp(void);
-
-#endif /* __MACH_PRCMU_H */
diff -druN linux-2.6.39-libre/arch/arm/mach-ux500/include/mach/prcmu-regs.h linux-3.0-rc7-libre/arch/arm/mach-ux500/include/mach/prcmu-regs.h
--- linux-2.6.39-libre/arch/arm/mach-ux500/include/mach/prcmu-regs.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-ux500/include/mach/prcmu-regs.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,96 +0,0 @@
-/*
- * Copyright (C) STMicroelectronics 2009
- * Copyright (C) ST-Ericsson SA 2010
- *
- * Author: Kumar Sanghvi <kumar.sanghvi@stericsson.com>
- * Author: Sundar Iyer <sundar.iyer@stericsson.com>
- *
- * License Terms: GNU General Public License v2
- *
- * PRCM Unit registers
- */
-
-#ifndef __MACH_PRCMU_REGS_H
-#define __MACH_PRCMU_REGS_H
-
-#include <mach/hardware.h>
-
-#define _PRCMU_BASE		IO_ADDRESS(U8500_PRCMU_BASE)
-
-#define PRCM_ARM_PLLDIVPS	(_PRCMU_BASE + 0x118)
-#define PRCM_ARM_CHGCLKREQ	(_PRCMU_BASE + 0x114)
-#define PRCM_PLLARM_ENABLE	(_PRCMU_BASE + 0x98)
-#define PRCM_ARMCLKFIX_MGT	(_PRCMU_BASE + 0x0)
-#define PRCM_A9_RESETN_CLR	(_PRCMU_BASE + 0x1f4)
-#define PRCM_A9_RESETN_SET	(_PRCMU_BASE + 0x1f0)
-#define PRCM_ARM_LS_CLAMP	(_PRCMU_BASE + 0x30c)
-#define PRCM_SRAM_A9		(_PRCMU_BASE + 0x308)
-
-/* ARM WFI Standby signal register */
-#define PRCM_ARM_WFI_STANDBY    (_PRCMU_BASE + 0x130)
-#define PRCMU_IOCR              (_PRCMU_BASE + 0x310)
-
-/* CPU mailbox registers */
-#define PRCM_MBOX_CPU_VAL	(_PRCMU_BASE + 0x0fc)
-#define PRCM_MBOX_CPU_SET	(_PRCMU_BASE + 0x100)
-#define PRCM_MBOX_CPU_CLR	(_PRCMU_BASE + 0x104)
-
-/* Dual A9 core interrupt management unit registers */
-#define PRCM_A9_MASK_REQ	(_PRCMU_BASE + 0x328)
-#define PRCM_A9_MASK_ACK	(_PRCMU_BASE + 0x32c)
-#define PRCM_ARMITMSK31TO0	(_PRCMU_BASE + 0x11c)
-#define PRCM_ARMITMSK63TO32	(_PRCMU_BASE + 0x120)
-#define PRCM_ARMITMSK95TO64	(_PRCMU_BASE + 0x124)
-#define PRCM_ARMITMSK127TO96	(_PRCMU_BASE + 0x128)
-#define PRCM_POWER_STATE_VAL	(_PRCMU_BASE + 0x25C)
-#define PRCM_ARMITVAL31TO0	(_PRCMU_BASE + 0x260)
-#define PRCM_ARMITVAL63TO32	(_PRCMU_BASE + 0x264)
-#define PRCM_ARMITVAL95TO64	(_PRCMU_BASE + 0x268)
-#define PRCM_ARMITVAL127TO96	(_PRCMU_BASE + 0x26C)
-
-#define PRCM_HOSTACCESS_REQ	(_PRCMU_BASE + 0x334)
-#define ARM_WAKEUP_MODEM	0x1
-
-#define PRCM_ARM_IT1_CLEAR	(_PRCMU_BASE + 0x48C)
-#define PRCM_ARM_IT1_VAL	(_PRCMU_BASE + 0x494)
-#define PRCM_HOLD_EVT		(_PRCMU_BASE + 0x174)
-
-#define PRCM_ITSTATUS0		(_PRCMU_BASE + 0x148)
-#define PRCM_ITSTATUS1		(_PRCMU_BASE + 0x150)
-#define PRCM_ITSTATUS2		(_PRCMU_BASE + 0x158)
-#define PRCM_ITSTATUS3		(_PRCMU_BASE + 0x160)
-#define PRCM_ITSTATUS4		(_PRCMU_BASE + 0x168)
-#define PRCM_ITSTATUS5		(_PRCMU_BASE + 0x484)
-#define PRCM_ITCLEAR5		(_PRCMU_BASE + 0x488)
-#define PRCM_ARMIT_MASKXP70_IT	(_PRCMU_BASE + 0x1018)
-
-/* System reset register */
-#define PRCM_APE_SOFTRST	(_PRCMU_BASE + 0x228)
-
-/* Level shifter and clamp control registers */
-#define PRCM_MMIP_LS_CLAMP_SET     (_PRCMU_BASE + 0x420)
-#define PRCM_MMIP_LS_CLAMP_CLR     (_PRCMU_BASE + 0x424)
-
-/* PRCMU clock/PLL/reset registers */
-#define PRCM_PLLDSI_FREQ           (_PRCMU_BASE + 0x500)
-#define PRCM_PLLDSI_ENABLE         (_PRCMU_BASE + 0x504)
-#define PRCM_LCDCLK_MGT            (_PRCMU_BASE + 0x044)
-#define PRCM_MCDECLK_MGT           (_PRCMU_BASE + 0x064)
-#define PRCM_HDMICLK_MGT           (_PRCMU_BASE + 0x058)
-#define PRCM_TVCLK_MGT             (_PRCMU_BASE + 0x07c)
-#define PRCM_DSI_PLLOUT_SEL        (_PRCMU_BASE + 0x530)
-#define PRCM_DSITVCLK_DIV          (_PRCMU_BASE + 0x52C)
-#define PRCM_APE_RESETN_SET        (_PRCMU_BASE + 0x1E4)
-#define PRCM_APE_RESETN_CLR        (_PRCMU_BASE + 0x1E8)
-
-/* ePOD and memory power signal control registers */
-#define PRCM_EPOD_C_SET            (_PRCMU_BASE + 0x410)
-#define PRCM_SRAM_LS_SLEEP         (_PRCMU_BASE + 0x304)
-
-/* Debug power control unit registers */
-#define PRCM_POWER_STATE_SET       (_PRCMU_BASE + 0x254)
-
-/* Miscellaneous unit registers */
-#define PRCM_DSI_SW_RESET          (_PRCMU_BASE + 0x324)
-
-#endif /* __MACH_PRCMU_REGS_H */
diff -druN linux-2.6.39-libre/arch/arm/mach-ux500/include/mach/smp.h linux-3.0-rc7-libre/arch/arm/mach-ux500/include/mach/smp.h
--- linux-2.6.39-libre/arch/arm/mach-ux500/include/mach/smp.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-ux500/include/mach/smp.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,24 +0,0 @@
-/*
- * This file is based ARM realview platform.
- * Copyright (C) ARM Limited.
- *
- * This file is licensed under  the terms of the GNU General Public
- * License version 2. This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
- */
-#ifndef ASMARM_ARCH_SMP_H
-#define ASMARM_ARCH_SMP_H
-
-#include <asm/hardware/gic.h>
-
-/* This is required to wakeup the secondary core */
-extern void u8500_secondary_startup(void);
-
-/*
- * We use IRQ1 as the IPI
- */
-static inline void smp_cross_call(const struct cpumask *mask, int ipi)
-{
-	gic_raise_softirq(mask, ipi);
-}
-#endif
diff -druN linux-2.6.39-libre/arch/arm/mach-ux500/include/mach/uncompress.h linux-3.0-rc7-libre/arch/arm/mach-ux500/include/mach/uncompress.h
--- linux-2.6.39-libre/arch/arm/mach-ux500/include/mach/uncompress.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-ux500/include/mach/uncompress.h	2011-07-11 19:51:52.000000000 -0400
@@ -24,7 +24,7 @@
 #include <linux/amba/serial.h>
 #include <mach/hardware.h>
 
-static u32 ux500_uart_base;
+u32 ux500_uart_base;
 
 static void putc(const char c)
 {
diff -druN linux-2.6.39-libre/arch/arm/mach-ux500/Kconfig linux-3.0-rc7-libre/arch/arm/mach-ux500/Kconfig
--- linux-2.6.39-libre/arch/arm/mach-ux500/Kconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-ux500/Kconfig	2011-07-11 19:51:52.000000000 -0400
@@ -5,16 +5,18 @@
 	default y
 	select ARM_GIC
 	select HAS_MTU
-	select NOMADIK_GPIO
 	select ARM_ERRATA_753970
 
 menu "Ux500 SoC"
 
 config UX500_SOC_DB5500
 	bool "DB5500"
+	select MFD_DB5500_PRCMU
 
 config UX500_SOC_DB8500
 	bool "DB8500"
+	select MFD_DB8500_PRCMU
+	select REGULATOR_DB8500_PRCMU
 
 endmenu
 
diff -druN linux-2.6.39-libre/arch/arm/mach-ux500/Makefile linux-3.0-rc7-libre/arch/arm/mach-ux500/Makefile
--- linux-2.6.39-libre/arch/arm/mach-ux500/Makefile	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-ux500/Makefile	2011-07-11 19:51:52.000000000 -0400
@@ -5,7 +5,7 @@
 obj-y				:= clock.o cpu.o devices.o devices-common.o \
 				   id.o usb.o
 obj-$(CONFIG_UX500_SOC_DB5500)	+= cpu-db5500.o dma-db5500.o
-obj-$(CONFIG_UX500_SOC_DB8500)	+= cpu-db8500.o devices-db8500.o prcmu.o
+obj-$(CONFIG_UX500_SOC_DB8500)	+= cpu-db8500.o devices-db8500.o
 obj-$(CONFIG_MACH_U8500)	+= board-mop500.o board-mop500-sdi.o \
 				board-mop500-regulators.o \
 				board-mop500-uib.o board-mop500-stuib.o \
@@ -17,4 +17,4 @@
 obj-$(CONFIG_LOCAL_TIMERS)	+= localtimer.o
 obj-$(CONFIG_U5500_MODEM_IRQ)	+= modem-irq-db5500.o
 obj-$(CONFIG_U5500_MBOX)	+= mbox-db5500.o
-obj-$(CONFIG_CPU_FREQ)		+= cpufreq.o
+
diff -druN linux-2.6.39-libre/arch/arm/mach-ux500/mbox-db5500.c linux-3.0-rc7-libre/arch/arm/mach-ux500/mbox-db5500.c
--- linux-2.6.39-libre/arch/arm/mach-ux500/mbox-db5500.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-ux500/mbox-db5500.c	2011-07-11 19:51:52.000000000 -0400
@@ -416,8 +416,7 @@
 	dev_dbg(&(mbox->pdev->dev),
 		"Resource name: %s start: 0x%X, end: 0x%X\n",
 		resource->name, resource->start, resource->end);
-	mbox->virtbase_peer =
-		ioremap(resource->start, resource->end - resource->start);
+	mbox->virtbase_peer = ioremap(resource->start, resource_size(resource));
 	if (!mbox->virtbase_peer) {
 		dev_err(&(mbox->pdev->dev), "Unable to ioremap peer mbox\n");
 		mbox = NULL;
@@ -440,8 +439,7 @@
 	dev_dbg(&(mbox->pdev->dev),
 		"Resource name: %s start: 0x%X, end: 0x%X\n",
 		resource->name, resource->start, resource->end);
-	mbox->virtbase_local =
-		ioremap(resource->start, resource->end - resource->start);
+	mbox->virtbase_local = ioremap(resource->start, resource_size(resource));
 	if (!mbox->virtbase_local) {
 		dev_err(&(mbox->pdev->dev), "Unable to ioremap local mbox\n");
 		mbox = NULL;
diff -druN linux-2.6.39-libre/arch/arm/mach-ux500/platsmp.c linux-3.0-rc7-libre/arch/arm/mach-ux500/platsmp.c
--- linux-2.6.39-libre/arch/arm/mach-ux500/platsmp.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-ux500/platsmp.c	2011-07-11 19:51:52.000000000 -0400
@@ -18,10 +18,14 @@
 #include <linux/io.h>
 
 #include <asm/cacheflush.h>
+#include <asm/hardware/gic.h>
 #include <asm/smp_scu.h>
 #include <mach/hardware.h>
 #include <mach/setup.h>
 
+/* This is called from headsmp.S to wakeup the secondary core */
+extern void u8500_secondary_startup(void);
+
 /*
  * control for which core is the next to come out of the secondary
  * boot "holding pen"
@@ -94,7 +98,7 @@
 	 */
 	write_pen_release(cpu);
 
-	smp_cross_call(cpumask_of(cpu), 1);
+	gic_raise_softirq(cpumask_of(cpu), 1);
 
 	timeout = jiffies + (1 * HZ);
 	while (time_before(jiffies, timeout)) {
@@ -162,6 +166,8 @@
 
 	for (i = 0; i < ncores; i++)
 		set_cpu_possible(i, true);
+
+	set_smp_cross_call(gic_raise_softirq);
 }
 
 void __init platform_smp_prepare_cpus(unsigned int max_cpus)
diff -druN linux-2.6.39-libre/arch/arm/mach-ux500/prcmu.c linux-3.0-rc7-libre/arch/arm/mach-ux500/prcmu.c
--- linux-2.6.39-libre/arch/arm/mach-ux500/prcmu.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-ux500/prcmu.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,394 +0,0 @@
-/*
- * Copyright (C) STMicroelectronics 2009
- * Copyright (C) ST-Ericsson SA 2010
- *
- * License Terms: GNU General Public License v2
- * Author: Kumar Sanghvi <kumar.sanghvi@stericsson.com>
- * Author: Sundar Iyer <sundar.iyer@stericsson.com>
- * Author: Mattias Nilsson <mattias.i.nilsson@stericsson.com>
- *
- * U8500 PRCM Unit interface driver
- *
- */
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/errno.h>
-#include <linux/err.h>
-#include <linux/io.h>
-#include <linux/mutex.h>
-#include <linux/completion.h>
-#include <linux/jiffies.h>
-#include <linux/bitops.h>
-#include <linux/interrupt.h>
-
-#include <mach/hardware.h>
-#include <mach/prcmu-regs.h>
-#include <mach/prcmu-defs.h>
-
-/* Global var to runtime determine TCDM base for v2 or v1 */
-static __iomem void *tcdm_base;
-
-#define _MBOX_HEADER		(tcdm_base + 0xFE8)
-#define MBOX_HEADER_REQ_MB0	(_MBOX_HEADER + 0x0)
-
-#define REQ_MB1 (tcdm_base + 0xFD0)
-#define REQ_MB5 (tcdm_base + 0xE44)
-
-#define REQ_MB1_ARMOPP		(REQ_MB1 + 0x0)
-#define REQ_MB1_APEOPP		(REQ_MB1 + 0x1)
-#define REQ_MB1_BOOSTOPP	(REQ_MB1 + 0x2)
-
-#define ACK_MB1 (tcdm_base + 0xE04)
-#define ACK_MB5 (tcdm_base + 0xDF4)
-
-#define ACK_MB1_CURR_ARMOPP		(ACK_MB1 + 0x0)
-#define ACK_MB1_CURR_APEOPP		(ACK_MB1 + 0x1)
-
-#define REQ_MB5_I2C_SLAVE_OP (REQ_MB5)
-#define REQ_MB5_I2C_HW_BITS (REQ_MB5 + 1)
-#define REQ_MB5_I2C_REG (REQ_MB5 + 2)
-#define REQ_MB5_I2C_VAL (REQ_MB5 + 3)
-
-#define ACK_MB5_I2C_STATUS (ACK_MB5 + 1)
-#define ACK_MB5_I2C_VAL (ACK_MB5 + 3)
-
-#define PRCM_AVS_VARM_MAX_OPP		(tcdm_base + 0x2E4)
-#define PRCM_AVS_ISMODEENABLE		7
-#define PRCM_AVS_ISMODEENABLE_MASK	(1 << PRCM_AVS_ISMODEENABLE)
-
-#define I2C_WRITE(slave) \
-	(((slave) << 1) | (cpu_is_u8500v2() ? BIT(6) : 0))
-#define I2C_READ(slave) \
-	(((slave) << 1) | (cpu_is_u8500v2() ? BIT(6) : 0) | BIT(0))
-#define I2C_STOP_EN BIT(3)
-
-enum mb1_h {
-	MB1H_ARM_OPP = 1,
-	MB1H_APE_OPP,
-	MB1H_ARM_APE_OPP,
-};
-
-static struct {
-	struct mutex lock;
-	struct completion work;
-	struct {
-		u8 arm_opp;
-		u8 ape_opp;
-		u8 arm_status;
-		u8 ape_status;
-	} ack;
-} mb1_transfer;
-
-enum ack_mb5_status {
-	I2C_WR_OK = 0x01,
-	I2C_RD_OK = 0x02,
-};
-
-#define MBOX_BIT BIT
-#define NUM_MBOX 8
-
-static struct {
-	struct mutex lock;
-	struct completion work;
-	bool failed;
-	struct {
-		u8 status;
-		u8 value;
-	} ack;
-} mb5_transfer;
-
-/**
- * prcmu_abb_read() - Read register value(s) from the ABB.
- * @slave:	The I2C slave address.
- * @reg:	The (start) register address.
- * @value:	The read out value(s).
- * @size:	The number of registers to read.
- *
- * Reads register value(s) from the ABB.
- * @size has to be 1 for the current firmware version.
- */
-int prcmu_abb_read(u8 slave, u8 reg, u8 *value, u8 size)
-{
-	int r;
-
-	if (size != 1)
-		return -EINVAL;
-
-	r = mutex_lock_interruptible(&mb5_transfer.lock);
-	if (r)
-		return r;
-
-	while (readl(PRCM_MBOX_CPU_VAL) & MBOX_BIT(5))
-		cpu_relax();
-
-	writeb(I2C_READ(slave), REQ_MB5_I2C_SLAVE_OP);
-	writeb(I2C_STOP_EN, REQ_MB5_I2C_HW_BITS);
-	writeb(reg, REQ_MB5_I2C_REG);
-
-	writel(MBOX_BIT(5), PRCM_MBOX_CPU_SET);
-	if (!wait_for_completion_timeout(&mb5_transfer.work,
-			msecs_to_jiffies(500))) {
-		pr_err("prcmu: prcmu_abb_read timed out.\n");
-		r = -EIO;
-		goto unlock_and_return;
-	}
-	r = ((mb5_transfer.ack.status == I2C_RD_OK) ? 0 : -EIO);
-	if (!r)
-		*value = mb5_transfer.ack.value;
-
-unlock_and_return:
-	mutex_unlock(&mb5_transfer.lock);
-	return r;
-}
-EXPORT_SYMBOL(prcmu_abb_read);
-
-/**
- * prcmu_abb_write() - Write register value(s) to the ABB.
- * @slave:	The I2C slave address.
- * @reg:	The (start) register address.
- * @value:	The value(s) to write.
- * @size:	The number of registers to write.
- *
- * Reads register value(s) from the ABB.
- * @size has to be 1 for the current firmware version.
- */
-int prcmu_abb_write(u8 slave, u8 reg, u8 *value, u8 size)
-{
-	int r;
-
-	if (size != 1)
-		return -EINVAL;
-
-	r = mutex_lock_interruptible(&mb5_transfer.lock);
-	if (r)
-		return r;
-
-
-	while (readl(PRCM_MBOX_CPU_VAL) & MBOX_BIT(5))
-		cpu_relax();
-
-	writeb(I2C_WRITE(slave), REQ_MB5_I2C_SLAVE_OP);
-	writeb(I2C_STOP_EN, REQ_MB5_I2C_HW_BITS);
-	writeb(reg, REQ_MB5_I2C_REG);
-	writeb(*value, REQ_MB5_I2C_VAL);
-
-	writel(MBOX_BIT(5), PRCM_MBOX_CPU_SET);
-	if (!wait_for_completion_timeout(&mb5_transfer.work,
-			msecs_to_jiffies(500))) {
-		pr_err("prcmu: prcmu_abb_write timed out.\n");
-		r = -EIO;
-		goto unlock_and_return;
-	}
-	r = ((mb5_transfer.ack.status == I2C_WR_OK) ? 0 : -EIO);
-
-unlock_and_return:
-	mutex_unlock(&mb5_transfer.lock);
-	return r;
-}
-EXPORT_SYMBOL(prcmu_abb_write);
-
-static int set_ape_cpu_opps(u8 header, enum prcmu_ape_opp ape_opp,
-			    enum prcmu_cpu_opp cpu_opp)
-{
-	bool do_ape;
-	bool do_arm;
-	int err = 0;
-
-	do_ape = ((header == MB1H_APE_OPP) || (header == MB1H_ARM_APE_OPP));
-	do_arm = ((header == MB1H_ARM_OPP) || (header == MB1H_ARM_APE_OPP));
-
-	mutex_lock(&mb1_transfer.lock);
-
-	while (readl(PRCM_MBOX_CPU_VAL) & MBOX_BIT(1))
-		cpu_relax();
-
-	writeb(0, MBOX_HEADER_REQ_MB0);
-	writeb(cpu_opp, REQ_MB1_ARMOPP);
-	writeb(ape_opp, REQ_MB1_APEOPP);
-	writeb(0, REQ_MB1_BOOSTOPP);
-	writel(MBOX_BIT(1), PRCM_MBOX_CPU_SET);
-	wait_for_completion(&mb1_transfer.work);
-	if ((do_ape) && (mb1_transfer.ack.ape_status != 0))
-		err = -EIO;
-	if ((do_arm) && (mb1_transfer.ack.arm_status != 0))
-		err = -EIO;
-
-	mutex_unlock(&mb1_transfer.lock);
-
-	return err;
-}
-
-/**
- * prcmu_set_ape_opp() - Set the OPP of the APE.
- * @opp:	The OPP to set.
- *
- * This function sets the OPP of the APE.
- */
-int prcmu_set_ape_opp(enum prcmu_ape_opp opp)
-{
-	return set_ape_cpu_opps(MB1H_APE_OPP, opp, APE_OPP_NO_CHANGE);
-}
-EXPORT_SYMBOL(prcmu_set_ape_opp);
-
-/**
- * prcmu_set_cpu_opp() - Set the OPP of the CPU.
- * @opp:	The OPP to set.
- *
- * This function sets the OPP of the CPU.
- */
-int prcmu_set_cpu_opp(enum prcmu_cpu_opp opp)
-{
-	return set_ape_cpu_opps(MB1H_ARM_OPP, CPU_OPP_NO_CHANGE, opp);
-}
-EXPORT_SYMBOL(prcmu_set_cpu_opp);
-
-/**
- * prcmu_set_ape_cpu_opps() - Set the OPPs of the APE and the CPU.
- * @ape_opp:	The APE OPP to set.
- * @cpu_opp:	The CPU OPP to set.
- *
- * This function sets the OPPs of the APE and the CPU.
- */
-int prcmu_set_ape_cpu_opps(enum prcmu_ape_opp ape_opp,
-			   enum prcmu_cpu_opp cpu_opp)
-{
-	return set_ape_cpu_opps(MB1H_ARM_APE_OPP, ape_opp, cpu_opp);
-}
-EXPORT_SYMBOL(prcmu_set_ape_cpu_opps);
-
-/**
- * prcmu_get_ape_opp() - Get the OPP of the APE.
- *
- * This function gets the OPP of the APE.
- */
-enum prcmu_ape_opp prcmu_get_ape_opp(void)
-{
-	return readb(ACK_MB1_CURR_APEOPP);
-}
-EXPORT_SYMBOL(prcmu_get_ape_opp);
-
-/**
- * prcmu_get_cpu_opp() - Get the OPP of the CPU.
- *
- * This function gets the OPP of the CPU. The OPP is specified in %%.
- * PRCMU_OPP_EXT is a special OPP value, not specified in %%.
- */
-int prcmu_get_cpu_opp(void)
-{
-	return readb(ACK_MB1_CURR_ARMOPP);
-}
-EXPORT_SYMBOL(prcmu_get_cpu_opp);
-
-bool prcmu_has_arm_maxopp(void)
-{
-	return (readb(PRCM_AVS_VARM_MAX_OPP) & PRCM_AVS_ISMODEENABLE_MASK)
-		== PRCM_AVS_ISMODEENABLE_MASK;
-}
-
-static void read_mailbox_0(void)
-{
-	writel(MBOX_BIT(0), PRCM_ARM_IT1_CLEAR);
-}
-
-static void read_mailbox_1(void)
-{
-	mb1_transfer.ack.arm_opp = readb(ACK_MB1_CURR_ARMOPP);
-	mb1_transfer.ack.ape_opp = readb(ACK_MB1_CURR_APEOPP);
-	complete(&mb1_transfer.work);
-	writel(MBOX_BIT(1), PRCM_ARM_IT1_CLEAR);
-}
-
-static void read_mailbox_2(void)
-{
-	writel(MBOX_BIT(2), PRCM_ARM_IT1_CLEAR);
-}
-
-static void read_mailbox_3(void)
-{
-	writel(MBOX_BIT(3), PRCM_ARM_IT1_CLEAR);
-}
-
-static void read_mailbox_4(void)
-{
-	writel(MBOX_BIT(4), PRCM_ARM_IT1_CLEAR);
-}
-
-static void read_mailbox_5(void)
-{
-	mb5_transfer.ack.status = readb(ACK_MB5_I2C_STATUS);
-	mb5_transfer.ack.value = readb(ACK_MB5_I2C_VAL);
-	complete(&mb5_transfer.work);
-	writel(MBOX_BIT(5), PRCM_ARM_IT1_CLEAR);
-}
-
-static void read_mailbox_6(void)
-{
-	writel(MBOX_BIT(6), PRCM_ARM_IT1_CLEAR);
-}
-
-static void read_mailbox_7(void)
-{
-	writel(MBOX_BIT(7), PRCM_ARM_IT1_CLEAR);
-}
-
-static void (* const read_mailbox[NUM_MBOX])(void) = {
-	read_mailbox_0,
-	read_mailbox_1,
-	read_mailbox_2,
-	read_mailbox_3,
-	read_mailbox_4,
-	read_mailbox_5,
-	read_mailbox_6,
-	read_mailbox_7
-};
-
-static irqreturn_t prcmu_irq_handler(int irq, void *data)
-{
-	u32 bits;
-	u8 n;
-
-	bits = (readl(PRCM_ARM_IT1_VAL) & (MBOX_BIT(NUM_MBOX) - 1));
-	if (unlikely(!bits))
-		return IRQ_NONE;
-
-	for (n = 0; bits; n++) {
-		if (bits & MBOX_BIT(n)) {
-			bits -= MBOX_BIT(n);
-			read_mailbox[n]();
-		}
-	}
-	return IRQ_HANDLED;
-}
-
-void __init prcmu_early_init(void)
-{
-	if (cpu_is_u8500v11() || cpu_is_u8500ed()) {
-		tcdm_base = __io_address(U8500_PRCMU_TCDM_BASE_V1);
-	} else if (cpu_is_u8500v2()) {
-		tcdm_base = __io_address(U8500_PRCMU_TCDM_BASE);
-	} else {
-		pr_err("prcmu: Unsupported chip version\n");
-		BUG();
-	}
-}
-
-static int __init prcmu_init(void)
-{
-	if (cpu_is_u8500ed()) {
-		pr_err("prcmu: Unsupported chip version\n");
-		return 0;
-	}
-
-	mutex_init(&mb1_transfer.lock);
-	init_completion(&mb1_transfer.work);
-	mutex_init(&mb5_transfer.lock);
-	init_completion(&mb5_transfer.work);
-
-	/* Clean up the mailbox interrupts after pre-kernel code. */
-	writel((MBOX_BIT(NUM_MBOX) - 1), PRCM_ARM_IT1_CLEAR);
-
-	return request_irq(IRQ_DB8500_PRCMU1, prcmu_irq_handler, 0,
-			   "prcmu", NULL);
-}
-
-arch_initcall(prcmu_init);
diff -druN linux-2.6.39-libre/arch/arm/mach-versatile/core.c linux-3.0-rc7-libre/arch/arm/mach-versatile/core.c
--- linux-2.6.39-libre/arch/arm/mach-versatile/core.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-versatile/core.c	2011-07-11 19:51:52.000000000 -0400
@@ -32,6 +32,7 @@
 #include <linux/io.h>
 #include <linux/gfp.h>
 #include <linux/clkdev.h>
+#include <linux/mtd/physmap.h>
 
 #include <asm/system.h>
 #include <asm/irq.h>
@@ -42,7 +43,6 @@
 #include <asm/mach-types.h>
 
 #include <asm/mach/arch.h>
-#include <asm/mach/flash.h>
 #include <asm/mach/irq.h>
 #include <asm/mach/time.h>
 #include <asm/mach/map.h>
@@ -190,27 +190,7 @@
 
 #define VERSATILE_FLASHCTRL    (__io_address(VERSATILE_SYS_BASE) + VERSATILE_SYS_FLASH_OFFSET)
 
-static int versatile_flash_init(void)
-{
-	u32 val;
-
-	val = __raw_readl(VERSATILE_FLASHCTRL);
-	val &= ~VERSATILE_FLASHPROG_FLVPPEN;
-	__raw_writel(val, VERSATILE_FLASHCTRL);
-
-	return 0;
-}
-
-static void versatile_flash_exit(void)
-{
-	u32 val;
-
-	val = __raw_readl(VERSATILE_FLASHCTRL);
-	val &= ~VERSATILE_FLASHPROG_FLVPPEN;
-	__raw_writel(val, VERSATILE_FLASHCTRL);
-}
-
-static void versatile_flash_set_vpp(int on)
+static void versatile_flash_set_vpp(struct platform_device *pdev, int on)
 {
 	u32 val;
 
@@ -222,11 +202,8 @@
 	__raw_writel(val, VERSATILE_FLASHCTRL);
 }
 
-static struct flash_platform_data versatile_flash_data = {
-	.map_name		= "cfi_probe",
+static struct physmap_flash_data versatile_flash_data = {
 	.width			= 4,
-	.init			= versatile_flash_init,
-	.exit			= versatile_flash_exit,
 	.set_vpp		= versatile_flash_set_vpp,
 };
 
@@ -237,7 +214,7 @@
 };
 
 static struct platform_device versatile_flash_device = {
-	.name			= "armflash",
+	.name			= "physmap-flash",
 	.id			= 0,
 	.dev			= {
 		.platform_data	= &versatile_flash_data,
@@ -375,6 +352,10 @@
 	.rate	= 24000000,
 };
 
+static struct clk sp804_clk = {
+	.rate	= 1000000,
+};
+
 static struct clk dummy_apb_pclk;
 
 static struct clk_lookup lookups[] = {
@@ -411,7 +392,10 @@
 	}, {	/* CLCD */
 		.dev_id		= "dev:20",
 		.clk		= &osc4_clk,
-	}
+	}, {	/* SP804 timers */
+		.dev_id		= "sp804",
+		.clk		= &sp804_clk,
+	},
 };
 
 /*
@@ -764,8 +748,8 @@
 	writel(0, TIMER2_VA_BASE + TIMER_CTRL);
 	writel(0, TIMER3_VA_BASE + TIMER_CTRL);
 
-	sp804_clocksource_init(TIMER3_VA_BASE);
-	sp804_clockevents_init(TIMER0_VA_BASE, IRQ_TIMERINT0_1);
+	sp804_clocksource_init(TIMER3_VA_BASE, "timer3");
+	sp804_clockevents_init(TIMER0_VA_BASE, IRQ_TIMERINT0_1, "timer0");
 }
 
 struct sys_timer versatile_timer = {
diff -druN linux-2.6.39-libre/arch/arm/mach-vexpress/ct-ca9x4.c linux-3.0-rc7-libre/arch/arm/mach-vexpress/ct-ca9x4.c
--- linux-2.6.39-libre/arch/arm/mach-vexpress/ct-ca9x4.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-vexpress/ct-ca9x4.c	2011-07-11 19:51:52.000000000 -0400
@@ -71,8 +71,9 @@
 	writel(0, MMIO_P2V(CT_CA9X4_TIMER0) + TIMER_CTRL);
 	writel(0, MMIO_P2V(CT_CA9X4_TIMER1) + TIMER_CTRL);
 
-	sp804_clocksource_init(MMIO_P2V(CT_CA9X4_TIMER1));
-	sp804_clockevents_init(MMIO_P2V(CT_CA9X4_TIMER0), IRQ_CT_CA9X4_TIMER0);
+	sp804_clocksource_init(MMIO_P2V(CT_CA9X4_TIMER1), "ct-timer1");
+	sp804_clockevents_init(MMIO_P2V(CT_CA9X4_TIMER0), IRQ_CT_CA9X4_TIMER0,
+		"ct-timer0");
 }
 
 static struct sys_timer ct_ca9x4_timer = {
@@ -141,10 +142,22 @@
 	.rate	= 24000000,
 };
 
+static struct clk ct_sp804_clk = {
+	.rate	= 1000000,
+};
+
 static struct clk_lookup lookups[] = {
 	{	/* CLCD */
 		.dev_id		= "ct:clcd",
 		.clk		= &osc1_clk,
+	}, {	/* SP804 timers */
+		.dev_id		= "sp804",
+		.con_id		= "ct-timer0",
+		.clk		= &ct_sp804_clk,
+	}, {	/* SP804 timers */
+		.dev_id		= "sp804",
+		.con_id		= "ct-timer1",
+		.clk		= &ct_sp804_clk,
 	},
 };
 
@@ -210,6 +223,8 @@
 
 	for (i = 0; i < ncores; ++i)
 		set_cpu_possible(i, true);
+
+	set_smp_cross_call(gic_raise_softirq);
 }
 
 static void ct_ca9x4_smp_enable(unsigned int max_cpus)
diff -druN linux-2.6.39-libre/arch/arm/mach-vexpress/include/mach/smp.h linux-3.0-rc7-libre/arch/arm/mach-vexpress/include/mach/smp.h
--- linux-2.6.39-libre/arch/arm/mach-vexpress/include/mach/smp.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-vexpress/include/mach/smp.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,13 +0,0 @@
-#ifndef __MACH_SMP_H
-#define __MACH_SMP_H
-
-#include <asm/hardware/gic.h>
-
-/*
- * We use IRQ1 as the IPI
- */
-static inline void smp_cross_call(const struct cpumask *mask, int ipi)
-{
-	gic_raise_softirq(mask, ipi);
-}
-#endif
diff -druN linux-2.6.39-libre/arch/arm/mach-vexpress/v2m.c linux-3.0-rc7-libre/arch/arm/mach-vexpress/v2m.c
--- linux-2.6.39-libre/arch/arm/mach-vexpress/v2m.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-vexpress/v2m.c	2011-07-11 19:51:52.000000000 -0400
@@ -13,11 +13,11 @@
 #include <linux/sysdev.h>
 #include <linux/usb/isp1760.h>
 #include <linux/clkdev.h>
+#include <linux/mtd/physmap.h>
 
 #include <asm/mach-types.h>
 #include <asm/sizes.h>
 #include <asm/mach/arch.h>
-#include <asm/mach/flash.h>
 #include <asm/mach/map.h>
 #include <asm/mach/time.h>
 #include <asm/hardware/arm_timer.h>
@@ -46,12 +46,6 @@
 	},
 };
 
-static void __init v2m_init_early(void)
-{
-	ct_desc->init_early();
-	versatile_sched_clock_init(MMIO_P2V(V2M_SYS_24MHZ), 24000000);
-}
-
 static void __init v2m_timer_init(void)
 {
 	u32 scctrl;
@@ -65,8 +59,9 @@
 	writel(0, MMIO_P2V(V2M_TIMER0) + TIMER_CTRL);
 	writel(0, MMIO_P2V(V2M_TIMER1) + TIMER_CTRL);
 
-	sp804_clocksource_init(MMIO_P2V(V2M_TIMER1));
-	sp804_clockevents_init(MMIO_P2V(V2M_TIMER0), IRQ_V2M_TIMER0);
+	sp804_clocksource_init(MMIO_P2V(V2M_TIMER1), "v2m-timer1");
+	sp804_clockevents_init(MMIO_P2V(V2M_TIMER0), IRQ_V2M_TIMER0,
+		"v2m-timer0");
 }
 
 static struct sys_timer v2m_timer = {
@@ -206,27 +201,13 @@
 	.dev.platform_data = &v2m_usb_config,
 };
 
-static int v2m_flash_init(void)
-{
-	writel(0, MMIO_P2V(V2M_SYS_FLASH));
-	return 0;
-}
-
-static void v2m_flash_exit(void)
-{
-	writel(0, MMIO_P2V(V2M_SYS_FLASH));
-}
-
-static void v2m_flash_set_vpp(int on)
+static void v2m_flash_set_vpp(struct platform_device *pdev, int on)
 {
 	writel(on != 0, MMIO_P2V(V2M_SYS_FLASH));
 }
 
-static struct flash_platform_data v2m_flash_data = {
-	.map_name	= "cfi_probe",
+static struct physmap_flash_data v2m_flash_data = {
 	.width		= 4,
-	.init		= v2m_flash_init,
-	.exit		= v2m_flash_exit,
 	.set_vpp	= v2m_flash_set_vpp,
 };
 
@@ -243,7 +224,7 @@
 };
 
 static struct platform_device v2m_flash_device = {
-	.name		= "armflash",
+	.name		= "physmap-flash",
 	.id		= -1,
 	.resource	= v2m_flash_resources,
 	.num_resources	= ARRAY_SIZE(v2m_flash_resources),
@@ -333,6 +314,10 @@
 	.rate	= 24000000,
 };
 
+static struct clk v2m_sp804_clk = {
+	.rate	= 1000000,
+};
+
 static struct clk dummy_apb_pclk;
 
 static struct clk_lookup v2m_lookups[] = {
@@ -363,9 +348,24 @@
 	}, {	/* CLCD */
 		.dev_id		= "mb:clcd",
 		.clk		= &osc1_clk,
+	}, {	/* SP804 timers */
+		.dev_id		= "sp804",
+		.con_id		= "v2m-timer0",
+		.clk		= &v2m_sp804_clk,
+	}, {	/* SP804 timers */
+		.dev_id		= "sp804",
+		.con_id		= "v2m-timer1",
+		.clk		= &v2m_sp804_clk,
 	},
 };
 
+static void __init v2m_init_early(void)
+{
+	ct_desc->init_early();
+	clkdev_add_table(v2m_lookups, ARRAY_SIZE(v2m_lookups));
+	versatile_sched_clock_init(MMIO_P2V(V2M_SYS_24MHZ), 24000000);
+}
+
 static void v2m_power_off(void)
 {
 	if (v2m_cfg_write(SYS_CFG_SHUTDOWN | SYS_CFG_SITE_MB, 0))
@@ -419,8 +419,6 @@
 {
 	int i;
 
-	clkdev_add_table(v2m_lookups, ARRAY_SIZE(v2m_lookups));
-
 	platform_device_register(&v2m_pcie_i2c_device);
 	platform_device_register(&v2m_ddc_i2c_device);
 	platform_device_register(&v2m_flash_device);
diff -druN linux-2.6.39-libre/arch/arm/mach-vt8500/irq.c linux-3.0-rc7-libre/arch/arm/mach-vt8500/irq.c
--- linux-2.6.39-libre/arch/arm/mach-vt8500/irq.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-vt8500/irq.c	2011-07-11 19:51:52.000000000 -0400
@@ -39,9 +39,10 @@
 static void __iomem *ic_regbase;
 static void __iomem *sic_regbase;
 
-static void vt8500_irq_mask(unsigned int irq)
+static void vt8500_irq_mask(struct irq_data *d)
 {
 	void __iomem *base = ic_regbase;
+	unsigned irq = d->irq;
 	u8 edge;
 
 	if (irq >= 64) {
@@ -64,9 +65,10 @@
 	}
 }
 
-static void vt8500_irq_unmask(unsigned int irq)
+static void vt8500_irq_unmask(struct irq_data *d)
 {
 	void __iomem *base = ic_regbase;
+	unsigned irq = d->irq;
 	u8 dctr;
 
 	if (irq >= 64) {
@@ -78,10 +80,11 @@
 	writeb(dctr, base + VT8500_IC_DCTR + irq);
 }
 
-static int vt8500_irq_set_type(unsigned int irq, unsigned int flow_type)
+static int vt8500_irq_set_type(struct irq_data *d, unsigned int flow_type)
 {
 	void __iomem *base = ic_regbase;
-	unsigned int orig_irq = irq;
+	unsigned irq = d->irq;
+	unsigned orig_irq = irq;
 	u8 dctr;
 
 	if (irq >= 64) {
@@ -114,11 +117,11 @@
 }
 
 static struct irq_chip vt8500_irq_chip = {
-	.name      = "vt8500",
-	.ack       = vt8500_irq_mask,
-	.mask      = vt8500_irq_mask,
-	.unmask    = vt8500_irq_unmask,
-	.set_type  = vt8500_irq_set_type,
+	.name = "vt8500",
+	.irq_ack = vt8500_irq_mask,
+	.irq_mask = vt8500_irq_mask,
+	.irq_unmask = vt8500_irq_unmask,
+	.irq_set_type = vt8500_irq_set_type,
 };
 
 void __init vt8500_init_irq(void)
diff -druN linux-2.6.39-libre/arch/arm/mach-w90x900/include/mach/uncompress.h linux-3.0-rc7-libre/arch/arm/mach-w90x900/include/mach/uncompress.h
--- linux-2.6.39-libre/arch/arm/mach-w90x900/include/mach/uncompress.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-w90x900/include/mach/uncompress.h	2011-07-11 19:51:52.000000000 -0400
@@ -27,7 +27,7 @@
 #define arch_decomp_wdog()
 
 #define TX_DONE	(UART_LSR_TEMT | UART_LSR_THRE)
-static volatile u32 * uart_base = (u32 *)UART0_PA;
+static volatile u32 * const uart_base = (u32 *)UART0_PA;
 
 static void putc(int ch)
 {
diff -druN linux-2.6.39-libre/arch/arm/mach-w90x900/time.c linux-3.0-rc7-libre/arch/arm/mach-w90x900/time.c
--- linux-2.6.39-libre/arch/arm/mach-w90x900/time.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mach-w90x900/time.c	2011-07-11 19:51:52.000000000 -0400
@@ -43,7 +43,6 @@
 #define PRESCALE	0x63 /* Divider = prescale + 1 */
 
 #define	TDR_SHIFT	24
-#define	TDR_MASK	((1 << TDR_SHIFT) - 1)
 
 static unsigned int timer0_load;
 
@@ -143,19 +142,6 @@
 	clockevents_register_device(&nuc900_clockevent_device);
 }
 
-static cycle_t nuc900_get_cycles(struct clocksource *cs)
-{
-	return (~__raw_readl(REG_TDR1)) & TDR_MASK;
-}
-
-static struct clocksource clocksource_nuc900 = {
-	.name	= "nuc900-timer1",
-	.rating	= 200,
-	.read	= nuc900_get_cycles,
-	.mask	= CLOCKSOURCE_MASK(TDR_SHIFT),
-	.flags	= CLOCK_SOURCE_IS_CONTINUOUS,
-};
-
 static void __init nuc900_clocksource_init(void)
 {
 	unsigned int val;
@@ -175,7 +161,8 @@
 	val |= (COUNTEN | PERIOD | PRESCALE);
 	__raw_writel(val, REG_TCSR1);
 
-	clocksource_register_hz(&clocksource_nuc900, rate);
+	clocksource_mmio_init(REG_TDR1, "nuc900-timer1", rate, 200,
+		TDR_SHIFT, clocksource_mmio_readl_down);
 }
 
 static void __init nuc900_timer_init(void)
diff -druN linux-2.6.39-libre/arch/arm/Makefile linux-3.0-rc7-libre/arch/arm/Makefile
--- linux-2.6.39-libre/arch/arm/Makefile	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/Makefile	2011-07-11 19:51:52.000000000 -0400
@@ -158,13 +158,11 @@
 machine-$(CONFIG_ARCH_MX1)		:= imx
 machine-$(CONFIG_ARCH_MX2)		:= imx
 machine-$(CONFIG_ARCH_MX25)		:= imx
-machine-$(CONFIG_ARCH_MX3)		:= mx3
+machine-$(CONFIG_ARCH_MX3)		:= imx
 machine-$(CONFIG_ARCH_MX5)		:= mx5
-machine-$(CONFIG_ARCH_MXC91231)		:= mxc91231
 machine-$(CONFIG_ARCH_MXS)		:= mxs
 machine-$(CONFIG_ARCH_NETX)		:= netx
 machine-$(CONFIG_ARCH_NOMADIK)		:= nomadik
-machine-$(CONFIG_ARCH_NS9XXX)		:= ns9xxx
 machine-$(CONFIG_ARCH_OMAP1)		:= omap1
 machine-$(CONFIG_ARCH_OMAP2)		:= omap2
 machine-$(CONFIG_ARCH_OMAP3)		:= omap2
@@ -178,15 +176,12 @@
 machine-$(CONFIG_ARCH_S3C24A0)		:= s3c24a0
 machine-$(CONFIG_ARCH_S3C64XX)		:= s3c64xx
 machine-$(CONFIG_ARCH_S5P64X0)		:= s5p64x0
-machine-$(CONFIG_ARCH_S5P6442)		:= s5p6442
 machine-$(CONFIG_ARCH_S5PC100)		:= s5pc100
 machine-$(CONFIG_ARCH_S5PV210)		:= s5pv210
 machine-$(CONFIG_ARCH_EXYNOS4)		:= exynos4
 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_TCC8K)		:= tcc8k
 machine-$(CONFIG_ARCH_TEGRA)		:= tegra
 machine-$(CONFIG_ARCH_U300)		:= u300
@@ -207,7 +202,6 @@
 plat-$(CONFIG_ARCH_MXC)		:= mxc
 plat-$(CONFIG_ARCH_OMAP)	:= omap
 plat-$(CONFIG_ARCH_S3C64XX)	:= samsung
-plat-$(CONFIG_ARCH_STMP3XXX)	:= stmp3xxx
 plat-$(CONFIG_ARCH_TCC_926)	:= tcc
 plat-$(CONFIG_PLAT_IOP)		:= iop
 plat-$(CONFIG_PLAT_NOMADIK)	:= nomadik
diff -druN linux-2.6.39-libre/arch/arm/mm/cache-l2x0.c linux-3.0-rc7-libre/arch/arm/mm/cache-l2x0.c
--- linux-2.6.39-libre/arch/arm/mm/cache-l2x0.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mm/cache-l2x0.c	2011-07-11 19:51:52.000000000 -0400
@@ -120,17 +120,22 @@
 	spin_unlock_irqrestore(&l2x0_lock, flags);
 }
 
-static void l2x0_flush_all(void)
+static void __l2x0_flush_all(void)
 {
-	unsigned long flags;
-
-	/* clean all ways */
-	spin_lock_irqsave(&l2x0_lock, flags);
 	debug_writel(0x03);
 	writel_relaxed(l2x0_way_mask, l2x0_base + L2X0_CLEAN_INV_WAY);
 	cache_wait_way(l2x0_base + L2X0_CLEAN_INV_WAY, l2x0_way_mask);
 	cache_sync();
 	debug_writel(0x00);
+}
+
+static void l2x0_flush_all(void)
+{
+	unsigned long flags;
+
+	/* clean all ways */
+	spin_lock_irqsave(&l2x0_lock, flags);
+	__l2x0_flush_all();
 	spin_unlock_irqrestore(&l2x0_lock, flags);
 }
 
@@ -266,7 +271,9 @@
 	unsigned long flags;
 
 	spin_lock_irqsave(&l2x0_lock, flags);
-	writel(0, l2x0_base + L2X0_CTRL);
+	__l2x0_flush_all();
+	writel_relaxed(0, l2x0_base + L2X0_CTRL);
+	dsb();
 	spin_unlock_irqrestore(&l2x0_lock, flags);
 }
 
diff -druN linux-2.6.39-libre/arch/arm/mm/cache-v6.S linux-3.0-rc7-libre/arch/arm/mm/cache-v6.S
--- linux-2.6.39-libre/arch/arm/mm/cache-v6.S	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mm/cache-v6.S	2011-07-11 19:51:52.000000000 -0400
@@ -176,6 +176,7 @@
  */
 ENTRY(v6_flush_kern_dcache_area)
 	add	r1, r0, r1
+	bic	r0, r0, #D_CACHE_LINE_SIZE - 1
 1:
 #ifdef HARVARD_CACHE
 	mcr	p15, 0, r0, c7, c14, 1		@ clean & invalidate D line
diff -druN linux-2.6.39-libre/arch/arm/mm/cache-v7.S linux-3.0-rc7-libre/arch/arm/mm/cache-v7.S
--- linux-2.6.39-libre/arch/arm/mm/cache-v7.S	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mm/cache-v7.S	2011-07-11 19:51:52.000000000 -0400
@@ -221,6 +221,8 @@
 ENTRY(v7_flush_kern_dcache_area)
 	dcache_line_size r2, r3
 	add	r1, r0, r1
+	sub	r3, r2, #1
+	bic	r0, r0, r3
 1:
 	mcr	p15, 0, r0, c7, c14, 1		@ clean & invalidate D line / unified line
 	add	r0, r0, r2
diff -druN linux-2.6.39-libre/arch/arm/mm/flush.c linux-3.0-rc7-libre/arch/arm/mm/flush.c
--- linux-2.6.39-libre/arch/arm/mm/flush.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mm/flush.c	2011-07-11 19:51:52.000000000 -0400
@@ -253,8 +253,8 @@
 
 	if (!test_and_set_bit(PG_dcache_clean, &page->flags))
 		__flush_dcache_page(mapping, page);
-	/* pte_exec() already checked above for non-aliasing VIPT cache */
-	if (cache_is_vipt_nonaliasing() || pte_exec(pteval))
+
+	if (pte_exec(pteval))
 		__flush_icache_all();
 }
 #endif
@@ -275,7 +275,8 @@
  *  kernel cache lines for later.  Otherwise, we assume we have
  *  aliasing mappings.
  *
- * Note that we disable the lazy flush for SMP.
+ * Note that we disable the lazy flush for SMP configurations where
+ * the cache maintenance operations are not automatically broadcasted.
  */
 void flush_dcache_page(struct page *page)
 {
diff -druN linux-2.6.39-libre/arch/arm/mm/init.c linux-3.0-rc7-libre/arch/arm/mm/init.c
--- linux-2.6.39-libre/arch/arm/mm/init.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mm/init.c	2011-07-11 19:51:52.000000000 -0400
@@ -15,12 +15,14 @@
 #include <linux/mman.h>
 #include <linux/nodemask.h>
 #include <linux/initrd.h>
+#include <linux/of_fdt.h>
 #include <linux/highmem.h>
 #include <linux/gfp.h>
 #include <linux/memblock.h>
 #include <linux/sort.h>
 
 #include <asm/mach-types.h>
+#include <asm/prom.h>
 #include <asm/sections.h>
 #include <asm/setup.h>
 #include <asm/sizes.h>
@@ -71,6 +73,14 @@
 
 __tagtable(ATAG_INITRD2, parse_tag_initrd2);
 
+#ifdef CONFIG_OF_FLATTREE
+void __init early_init_dt_setup_initrd_arch(unsigned long start, unsigned long end)
+{
+	phys_initrd_start = start;
+	phys_initrd_size = end - start;
+}
+#endif /* CONFIG_OF_FLATTREE */
+
 /*
  * This keeps memory configuration data used by a couple memory
  * initialization functions, as well as show_mem() for the skipping
@@ -85,7 +95,7 @@
 	struct meminfo * mi = &meminfo;
 
 	printk("Mem-info:\n");
-	show_free_areas();
+	show_free_areas(filter);
 
 	for_each_bank (i, mi) {
 		struct membank *bank = &mi->bank[i];
@@ -201,6 +211,20 @@
 	}
 }
 
+#ifdef CONFIG_ZONE_DMA
+static void __init arm_adjust_dma_zone(unsigned long *size, unsigned long *hole,
+	unsigned long dma_size)
+{
+	if (size[0] <= dma_size)
+		return;
+
+	size[ZONE_NORMAL] = size[0] - dma_size;
+	size[ZONE_DMA] = dma_size;
+	hole[ZONE_NORMAL] = hole[0];
+	hole[ZONE_DMA] = 0;
+}
+#endif
+
 static void __init arm_bootmem_free(unsigned long min, unsigned long max_low,
 	unsigned long max_high)
 {
@@ -243,22 +267,31 @@
 #endif
 	}
 
+#ifdef ARM_DMA_ZONE_SIZE
+#ifndef CONFIG_ZONE_DMA
+#error ARM_DMA_ZONE_SIZE set but no DMA zone to limit allocations
+#endif
+
 	/*
 	 * Adjust the sizes according to any special requirements for
 	 * this machine type.
 	 */
-	arch_adjust_zones(zone_size, zhole_size);
+	arm_adjust_dma_zone(zone_size, zhole_size,
+		ARM_DMA_ZONE_SIZE >> PAGE_SHIFT);
+#endif
 
 	free_area_init_node(0, zone_size, min, zhole_size);
 }
 
-#ifndef CONFIG_SPARSEMEM
+#ifdef CONFIG_HAVE_ARCH_PFN_VALID
 int pfn_valid(unsigned long pfn)
 {
 	return memblock_is_memory(pfn << PAGE_SHIFT);
 }
 EXPORT_SYMBOL(pfn_valid);
+#endif
 
+#ifndef CONFIG_SPARSEMEM
 static void arm_memory_present(void)
 {
 }
@@ -298,6 +331,12 @@
 #endif
 #ifdef CONFIG_BLK_DEV_INITRD
 	if (phys_initrd_size &&
+	    !memblock_is_region_memory(phys_initrd_start, phys_initrd_size)) {
+		pr_err("INITRD: 0x%08lx+0x%08lx is not a memory region - disabling initrd\n",
+		       phys_initrd_start, phys_initrd_size);
+		phys_initrd_start = phys_initrd_size = 0;
+	}
+	if (phys_initrd_size &&
 	    memblock_is_region_reserved(phys_initrd_start, phys_initrd_size)) {
 		pr_err("INITRD: 0x%08lx+0x%08lx overlaps in-use memory region - disabling initrd\n",
 		       phys_initrd_start, phys_initrd_size);
@@ -313,6 +352,7 @@
 #endif
 
 	arm_mm_memblock_reserve();
+	arm_dt_memblock_reserve();
 
 	/* reserve any platform specific memblock areas */
 	if (mdesc->reserve)
@@ -601,7 +641,8 @@
 			"    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",
+			"      .data : 0x%p" " - 0x%p" "   (%4d kB)\n"
+			"       .bss : 0x%p" " - 0x%p" "   (%4d kB)\n",
 
 			MLK(UL(CONFIG_VECTORS_BASE), UL(CONFIG_VECTORS_BASE) +
 				(PAGE_SIZE)),
@@ -623,7 +664,8 @@
 
 			MLK_ROUNDUP(__init_begin, __init_end),
 			MLK_ROUNDUP(_text, _etext),
-			MLK_ROUNDUP(_sdata, _edata));
+			MLK_ROUNDUP(_sdata, _edata),
+			MLK_ROUNDUP(__bss_start, __bss_stop));
 
 #undef MLK
 #undef MLM
diff -druN linux-2.6.39-libre/arch/arm/mm/mm.h linux-3.0-rc7-libre/arch/arm/mm/mm.h
--- linux-2.6.39-libre/arch/arm/mm/mm.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mm/mm.h	2011-07-11 19:51:52.000000000 -0400
@@ -5,14 +5,9 @@
 
 #define TOP_PTE(x)	pte_offset_kernel(top_pmd, x)
 
-static inline pmd_t *pmd_off(pgd_t *pgd, unsigned long virt)
-{
-	return pmd_offset(pud_offset(pgd, virt), virt);
-}
-
 static inline pmd_t *pmd_off_k(unsigned long virt)
 {
-	return pmd_off(pgd_offset_k(virt), virt);
+	return pmd_offset(pud_offset(pgd_offset_k(virt), virt), virt);
 }
 
 struct mem_type {
diff -druN linux-2.6.39-libre/arch/arm/mm/mmu.c linux-3.0-rc7-libre/arch/arm/mm/mmu.c
--- linux-2.6.39-libre/arch/arm/mm/mmu.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mm/mmu.c	2011-07-11 19:51:52.000000000 -0400
@@ -31,8 +31,6 @@
 
 #include "mm.h"
 
-DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
-
 /*
  * empty_zero_page is a special page that is used for
  * zero-initialized data and COW.
@@ -761,19 +759,16 @@
 
 static phys_addr_t lowmem_limit __initdata = 0;
 
-static void __init sanity_check_meminfo(void)
+void __init sanity_check_meminfo(void)
 {
 	int i, j, highmem = 0;
 
-	lowmem_limit = __pa(vmalloc_min - 1) + 1;
-	memblock_set_current_limit(lowmem_limit);
-
 	for (i = 0, j = 0; i < meminfo.nr_banks; i++) {
 		struct membank *bank = &meminfo.bank[j];
 		*bank = meminfo.bank[i];
 
 #ifdef CONFIG_HIGHMEM
-		if (__va(bank->start) > vmalloc_min ||
+		if (__va(bank->start) >= vmalloc_min ||
 		    __va(bank->start) < (void *)PAGE_OFFSET)
 			highmem = 1;
 
@@ -831,6 +826,9 @@
 			bank->size = newsize;
 		}
 #endif
+		if (!bank->highmem && bank->start + bank->size > lowmem_limit)
+			lowmem_limit = bank->start + bank->size;
+
 		j++;
 	}
 #ifdef CONFIG_HIGHMEM
@@ -854,6 +852,7 @@
 	}
 #endif
 	meminfo.nr_banks = j;
+	memblock_set_current_limit(lowmem_limit);
 }
 
 static inline void prepare_page_table(void)
@@ -1033,8 +1032,9 @@
 {
 	void *zero_page;
 
+	memblock_set_current_limit(lowmem_limit);
+
 	build_mem_type_table();
-	sanity_check_meminfo();
 	prepare_page_table();
 	map_lowmem();
 	devicemaps_init(mdesc);
diff -druN linux-2.6.39-libre/arch/arm/mm/nommu.c linux-3.0-rc7-libre/arch/arm/mm/nommu.c
--- linux-2.6.39-libre/arch/arm/mm/nommu.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mm/nommu.c	2011-07-11 19:51:52.000000000 -0400
@@ -27,6 +27,10 @@
 	memblock_reserve(CONFIG_VECTORS_BASE, PAGE_SIZE);
 }
 
+void __init sanity_check_meminfo(void)
+{
+}
+
 /*
  * paging_init() sets up the page tables, initialises the zone memory
  * maps, and sets up the zero page, bad page and bad page tables.
diff -druN linux-2.6.39-libre/arch/arm/mm/proc-arm7tdmi.S linux-3.0-rc7-libre/arch/arm/mm/proc-arm7tdmi.S
--- linux-2.6.39-libre/arch/arm/mm/proc-arm7tdmi.S	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mm/proc-arm7tdmi.S	2011-07-11 19:51:52.000000000 -0400
@@ -146,7 +146,7 @@
 		.long	0
 		.long	0
 		.long	v4_cache_fns
-		.size	__arm7tdmi_proc_info, . - __arm7dmi_proc_info
+		.size	__arm7tdmi_proc_info, . - __arm7tdmi_proc_info
 
 		.type	__triscenda7_proc_info, #object
 __triscenda7_proc_info:
diff -druN linux-2.6.39-libre/arch/arm/mm/proc-arm9tdmi.S linux-3.0-rc7-libre/arch/arm/mm/proc-arm9tdmi.S
--- linux-2.6.39-libre/arch/arm/mm/proc-arm9tdmi.S	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mm/proc-arm9tdmi.S	2011-07-11 19:51:52.000000000 -0400
@@ -116,7 +116,7 @@
 		.long	0
 		.long	0
 		.long	v4_cache_fns
-		.size	__arm9tdmi_proc_info, . - __arm9dmi_proc_info
+		.size	__arm9tdmi_proc_info, . - __arm9tdmi_proc_info
 
 		.type	__p2001_proc_info, #object
 __p2001_proc_info:
diff -druN linux-2.6.39-libre/arch/arm/mm/proc-v6.S linux-3.0-rc7-libre/arch/arm/mm/proc-v6.S
--- linux-2.6.39-libre/arch/arm/mm/proc-v6.S	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mm/proc-v6.S	2011-07-11 19:51:52.000000000 -0400
@@ -175,11 +175,6 @@
 	.asciz	"ARMv6-compatible processor"
 	.size	cpu_v6_name, . - cpu_v6_name
 
-	.type	cpu_pj4_name, #object
-cpu_pj4_name:
-	.asciz	"Marvell PJ4 processor"
-	.size	cpu_pj4_name, . - cpu_pj4_name
-
 	.align
 
 	__CPUINIT
@@ -218,7 +213,9 @@
 	mcr	p15, 0, r0, c2, c0, 2		@ TTB control register
 	ALT_SMP(orr	r4, r4, #TTB_FLAGS_SMP)
 	ALT_UP(orr	r4, r4, #TTB_FLAGS_UP)
-	mcr	p15, 0, r4, c2, c0, 1		@ load TTB1
+	ALT_SMP(orr	r8, r8, #TTB_FLAGS_SMP)
+	ALT_UP(orr	r8, r8, #TTB_FLAGS_UP)
+	mcr	p15, 0, r8, c2, c0, 1		@ load TTB1
 #endif /* CONFIG_MMU */
 	adr	r5, v6_crval
 	ldmia	r5, {r5, r6}
@@ -305,32 +302,3 @@
 	.long	v6_user_fns
 	.long	v6_cache_fns
 	.size	__v6_proc_info, . - __v6_proc_info
-
-	.type	__pj4_v6_proc_info, #object
-__pj4_v6_proc_info:
-	.long	0x560f5810
-	.long	0xff0ffff0
-	ALT_SMP(.long \
-		PMD_TYPE_SECT | \
-		PMD_SECT_AP_WRITE | \
-		PMD_SECT_AP_READ | \
-		PMD_FLAGS_SMP)
-	ALT_UP(.long \
-		PMD_TYPE_SECT | \
-		PMD_SECT_AP_WRITE | \
-		PMD_SECT_AP_READ | \
-		PMD_FLAGS_UP)
-	.long   PMD_TYPE_SECT | \
-		PMD_SECT_XN | \
-		PMD_SECT_AP_WRITE | \
-		PMD_SECT_AP_READ
-	b	__v6_setup
-	.long	cpu_arch_name
-	.long	cpu_elf_name
-	.long	HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP|HWCAP_TLS
-	.long	cpu_pj4_name
-	.long	v6_processor_functions
-	.long	v6wbi_tlb_fns
-	.long	v6_user_fns
-	.long	v6_cache_fns
-	.size	__pj4_v6_proc_info, . - __pj4_v6_proc_info
diff -druN linux-2.6.39-libre/arch/arm/mm/proc-v7.S linux-3.0-rc7-libre/arch/arm/mm/proc-v7.S
--- linux-2.6.39-libre/arch/arm/mm/proc-v7.S	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/mm/proc-v7.S	2011-07-11 19:51:52.000000000 -0400
@@ -210,19 +210,21 @@
 
 /* Suspend/resume support: derived from arch/arm/mach-s5pv210/sleep.S */
 .globl	cpu_v7_suspend_size
-.equ	cpu_v7_suspend_size, 4 * 8
+.equ	cpu_v7_suspend_size, 4 * 9
 #ifdef CONFIG_PM_SLEEP
 ENTRY(cpu_v7_do_suspend)
 	stmfd	sp!, {r4 - r11, lr}
 	mrc	p15, 0, r4, c13, c0, 0	@ FCSE/PID
 	mrc	p15, 0, r5, c13, c0, 1	@ Context ID
+	mrc	p15, 0, r6, c13, c0, 3	@ User r/o thread ID
+	stmia	r0!, {r4 - r6}
 	mrc	p15, 0, r6, c3, c0, 0	@ Domain ID
 	mrc	p15, 0, r7, c2, c0, 0	@ TTB 0
 	mrc	p15, 0, r8, c2, c0, 1	@ TTB 1
 	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 control
-	stmia	r0, {r4 - r11}
+	stmia	r0, {r6 - r11}
 	ldmfd	sp!, {r4 - r11, pc}
 ENDPROC(cpu_v7_do_suspend)
 
@@ -230,9 +232,11 @@
 	mov	ip, #0
 	mcr	p15, 0, ip, c8, c7, 0	@ invalidate TLBs
 	mcr	p15, 0, ip, c7, c5, 0	@ invalidate I cache
-	ldmia	r0, {r4 - r11}
+	ldmia	r0!, {r4 - r6}
 	mcr	p15, 0, r4, c13, c0, 0	@ FCSE/PID
 	mcr	p15, 0, r5, c13, c0, 1	@ Context ID
+	mcr	p15, 0, r6, c13, c0, 3	@ User r/o thread ID
+	ldmia	r0, {r6 - r11}
 	mcr	p15, 0, r6, c3, c0, 0	@ Domain ID
 	mcr	p15, 0, r7, c2, c0, 0	@ TTB 0
 	mcr	p15, 0, r8, c2, c0, 1	@ TTB 1
@@ -368,7 +372,9 @@
 	mcr	p15, 0, r10, c2, c0, 2		@ TTB control register
 	ALT_SMP(orr	r4, r4, #TTB_FLAGS_SMP)
 	ALT_UP(orr	r4, r4, #TTB_FLAGS_UP)
-	mcr	p15, 0, r4, c2, c0, 1		@ load TTB1
+	ALT_SMP(orr	r8, r8, #TTB_FLAGS_SMP)
+	ALT_UP(orr	r8, r8, #TTB_FLAGS_UP)
+	mcr	p15, 0, r8, c2, c0, 1		@ load TTB1
 	ldr	r5, =PRRR			@ PRRR
 	ldr	r6, =NMRR			@ NMRR
 	mcr	p15, 0, r5, c10, c2, 0		@ write PRRR
@@ -416,9 +422,9 @@
 	.word	cpu_v7_dcache_clean_area
 	.word	cpu_v7_switch_mm
 	.word	cpu_v7_set_pte_ext
-	.word	0
-	.word	0
-	.word	0
+	.word	cpu_v7_suspend_size
+	.word	cpu_v7_do_suspend
+	.word	cpu_v7_do_resume
 	.size	v7_processor_functions, . - v7_processor_functions
 
 	.section ".rodata"
diff -druN linux-2.6.39-libre/arch/arm/plat-iop/cp6.c linux-3.0-rc7-libre/arch/arm/plat-iop/cp6.c
--- linux-2.6.39-libre/arch/arm/plat-iop/cp6.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/plat-iop/cp6.c	2011-07-11 19:51:52.000000000 -0400
@@ -18,6 +18,7 @@
  */
 #include <linux/init.h>
 #include <asm/traps.h>
+#include <asm/ptrace.h>
 
 static int cp6_trap(struct pt_regs *regs, unsigned int instr)
 {
diff -druN linux-2.6.39-libre/arch/arm/plat-iop/time.c linux-3.0-rc7-libre/arch/arm/plat-iop/time.c
--- linux-2.6.39-libre/arch/arm/plat-iop/time.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/plat-iop/time.c	2011-07-11 19:51:52.000000000 -0400
@@ -17,7 +17,6 @@
 #include <linux/interrupt.h>
 #include <linux/time.h>
 #include <linux/init.h>
-#include <linux/sched.h>
 #include <linux/timex.h>
 #include <linux/sched.h>
 #include <linux/io.h>
diff -druN linux-2.6.39-libre/arch/arm/plat-mxc/cpufreq.c linux-3.0-rc7-libre/arch/arm/plat-mxc/cpufreq.c
--- linux-2.6.39-libre/arch/arm/plat-mxc/cpufreq.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/plat-mxc/cpufreq.c	2011-07-11 19:51:52.000000000 -0400
@@ -153,8 +153,8 @@
 	ret = cpufreq_frequency_table_cpuinfo(policy, imx_freq_table);
 
 	if (ret < 0) {
-		printk(KERN_ERR "%s: failed to register i.MXC CPUfreq \
-				with error code %d\n", __func__, ret);
+		printk(KERN_ERR "%s: failed to register i.MXC CPUfreq with error code %d\n",
+		       __func__, ret);
 		goto err;
 	}
 
diff -druN linux-2.6.39-libre/arch/arm/plat-mxc/devices/Kconfig linux-3.0-rc7-libre/arch/arm/plat-mxc/devices/Kconfig
--- linux-2.6.39-libre/arch/arm/plat-mxc/devices/Kconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/plat-mxc/devices/Kconfig	2011-07-11 19:51:52.000000000 -0400
@@ -24,7 +24,6 @@
 
 config IMX_HAVE_PLATFORM_IMX_FB
 	bool
-	select HAVE_FB_IMX
 
 config IMX_HAVE_PLATFORM_IMX_I2C
 	bool
@@ -41,6 +40,9 @@
 config IMX_HAVE_PLATFORM_IMX_UDC
 	bool
 
+config IMX_HAVE_PLATFORM_IPU_CORE
+	bool
+
 config IMX_HAVE_PLATFORM_MX1_CAMERA
 	bool
 
@@ -63,6 +65,9 @@
 	bool
 	select ARCH_HAS_RNGA
 
+config IMX_HAVE_PLATFORM_MXC_RTC
+	bool
+
 config IMX_HAVE_PLATFORM_MXC_W1
 	bool
 
diff -druN linux-2.6.39-libre/arch/arm/plat-mxc/devices/Makefile linux-3.0-rc7-libre/arch/arm/plat-mxc/devices/Makefile
--- linux-2.6.39-libre/arch/arm/plat-mxc/devices/Makefile	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/plat-mxc/devices/Makefile	2011-07-11 19:51:52.000000000 -0400
@@ -12,6 +12,7 @@
 obj-$(CONFIG_IMX_HAVE_PLATFORM_IMX_SSI) += platform-imx-ssi.o
 obj-$(CONFIG_IMX_HAVE_PLATFORM_IMX_UART) += platform-imx-uart.o
 obj-$(CONFIG_IMX_HAVE_PLATFORM_IMX_UDC) += platform-imx_udc.o
+obj-$(CONFIG_IMX_HAVE_PLATFORM_IPU_CORE) += platform-ipu-core.o
 obj-$(CONFIG_IMX_HAVE_PLATFORM_MX1_CAMERA) += platform-mx1-camera.o
 obj-$(CONFIG_IMX_HAVE_PLATFORM_MX2_CAMERA) += platform-mx2-camera.o
 obj-$(CONFIG_IMX_HAVE_PLATFORM_MXC_EHCI) += platform-mxc-ehci.o
@@ -19,6 +20,7 @@
 obj-$(CONFIG_IMX_HAVE_PLATFORM_MXC_NAND) += platform-mxc_nand.o
 obj-$(CONFIG_IMX_HAVE_PLATFORM_MXC_PWM) += platform-mxc_pwm.o
 obj-$(CONFIG_IMX_HAVE_PLATFORM_MXC_RNGA) += platform-mxc_rnga.o
+obj-$(CONFIG_IMX_HAVE_PLATFORM_MXC_RTC) += platform-mxc_rtc.o
 obj-$(CONFIG_IMX_HAVE_PLATFORM_MXC_W1) += platform-mxc_w1.o
 obj-$(CONFIG_IMX_HAVE_PLATFORM_SDHCI_ESDHC_IMX) += platform-sdhci-esdhc-imx.o
 obj-$(CONFIG_IMX_HAVE_PLATFORM_SPI_IMX) +=  platform-spi_imx.o
diff -druN linux-2.6.39-libre/arch/arm/plat-mxc/devices/platform-imx-dma.c linux-3.0-rc7-libre/arch/arm/plat-mxc/devices/platform-imx-dma.c
--- linux-2.6.39-libre/arch/arm/plat-mxc/devices/platform-imx-dma.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/plat-mxc/devices/platform-imx-dma.c	2011-07-11 19:51:52.000000000 -0400
@@ -139,7 +139,7 @@
 #endif
 
 #ifdef CONFIG_SOC_IMX51
-static struct sdma_script_start_addrs addr_imx51_to1 = {
+static struct sdma_script_start_addrs addr_imx51 = {
 	.ap_2_ap_addr = 642,
 	.uart_2_mcu_addr = 817,
 	.mcu_2_app_addr = 747,
@@ -196,7 +196,9 @@
 
 #if defined(CONFIG_SOC_IMX51)
 	if (cpu_is_mx51()) {
-		imx51_imx_sdma_data.pdata.script_addrs = &addr_imx51_to1;
+		int to_version = mx51_revision() >> 4;
+		imx51_imx_sdma_data.pdata.to_version = to_version;
+		imx51_imx_sdma_data.pdata.script_addrs = &addr_imx51;
 		ret = imx_add_imx_sdma(&imx51_imx_sdma_data);
 	} else
 #endif
diff -druN linux-2.6.39-libre/arch/arm/plat-mxc/devices/platform-ipu-core.c linux-3.0-rc7-libre/arch/arm/plat-mxc/devices/platform-ipu-core.c
--- linux-2.6.39-libre/arch/arm/plat-mxc/devices/platform-ipu-core.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/arm/plat-mxc/devices/platform-ipu-core.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,129 @@
+/*
+ * Copyright (C) 2011 Pengutronix
+ * Uwe Kleine-Koenig <u.kleine-koenig@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 <mach/hardware.h>
+#include <mach/devices-common.h>
+
+#define imx_ipu_core_entry_single(soc)					\
+{									\
+	.iobase = soc ## _IPU_CTRL_BASE_ADDR,				\
+	.synirq = soc ## _INT_IPU_SYN,					\
+	.errirq = soc ## _INT_IPU_ERR,					\
+}
+
+#ifdef CONFIG_SOC_IMX31
+const struct imx_ipu_core_data imx31_ipu_core_data __initconst =
+	imx_ipu_core_entry_single(MX31);
+#endif
+
+#ifdef CONFIG_SOC_IMX35
+const struct imx_ipu_core_data imx35_ipu_core_data __initconst =
+	imx_ipu_core_entry_single(MX35);
+#endif
+
+static struct platform_device *imx_ipu_coredev __initdata;
+
+struct platform_device *__init imx_add_ipu_core(
+		const struct imx_ipu_core_data *data,
+		const struct ipu_platform_data *pdata)
+{
+	/* The resource order is important! */
+	struct resource res[] = {
+		{
+			.start = data->iobase,
+			.end = data->iobase + 0x5f,
+			.flags = IORESOURCE_MEM,
+		}, {
+			.start = data->iobase + 0x88,
+			.end = data->iobase + 0xb3,
+			.flags = IORESOURCE_MEM,
+		}, {
+			.start = data->synirq,
+			.end = data->synirq,
+			.flags = IORESOURCE_IRQ,
+		}, {
+			.start = data->errirq,
+			.end = data->errirq,
+			.flags = IORESOURCE_IRQ,
+		},
+	};
+
+	return imx_ipu_coredev = imx_add_platform_device("ipu-core", -1,
+			res, ARRAY_SIZE(res), pdata, sizeof(*pdata));
+}
+
+struct platform_device *__init imx_alloc_mx3_camera(
+		const struct imx_ipu_core_data *data,
+		const struct mx3_camera_pdata *pdata)
+{
+	struct resource res[] = {
+		{
+			.start = data->iobase + 0x60,
+			.end = data->iobase + 0x87,
+			.flags = IORESOURCE_MEM,
+		},
+	};
+	int ret = -ENOMEM;
+	struct platform_device *pdev;
+
+	if (IS_ERR_OR_NULL(imx_ipu_coredev))
+		return ERR_PTR(-ENODEV);
+
+	pdev = platform_device_alloc("mx3-camera", 0);
+	if (!pdev)
+		goto err;
+
+	pdev->dev.dma_mask = kmalloc(sizeof(*pdev->dev.dma_mask), GFP_KERNEL);
+	if (!pdev->dev.dma_mask)
+		goto err;
+
+	*pdev->dev.dma_mask = DMA_BIT_MASK(32);
+	pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
+
+	ret = platform_device_add_resources(pdev, res, ARRAY_SIZE(res));
+	if (ret)
+		goto err;
+
+	if (pdata) {
+		struct mx3_camera_pdata *copied_pdata;
+
+		ret = platform_device_add_data(pdev, pdata, sizeof(*pdata));
+		if (ret) {
+err:
+			kfree(pdev->dev.dma_mask);
+			platform_device_put(pdev);
+			return ERR_PTR(-ENODEV);
+		}
+		copied_pdata = dev_get_platdata(&pdev->dev);
+		copied_pdata->dma_dev = &imx_ipu_coredev->dev;
+	}
+
+	return pdev;
+}
+
+struct platform_device *__init imx_add_mx3_sdc_fb(
+		const struct imx_ipu_core_data *data,
+		struct mx3fb_platform_data *pdata)
+{
+	struct resource res[] = {
+		{
+			.start = data->iobase + 0xb4,
+			.end = data->iobase + 0x1bf,
+			.flags = IORESOURCE_MEM,
+		},
+	};
+
+	if (IS_ERR_OR_NULL(imx_ipu_coredev))
+		return ERR_PTR(-ENODEV);
+
+	pdata->dma_dev = &imx_ipu_coredev->dev;
+
+	return imx_add_platform_device_dmamask("mx3_sdc_fb", -1,
+			res, ARRAY_SIZE(res), pdata, sizeof(*pdata),
+			DMA_BIT_MASK(32));
+}
diff -druN linux-2.6.39-libre/arch/arm/plat-mxc/devices/platform-mxc_rtc.c linux-3.0-rc7-libre/arch/arm/plat-mxc/devices/platform-mxc_rtc.c
--- linux-2.6.39-libre/arch/arm/plat-mxc/devices/platform-mxc_rtc.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/arm/plat-mxc/devices/platform-mxc_rtc.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2010-2011 Pengutronix
+ * Uwe Kleine-Koenig <u.kleine-koenig@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 <mach/hardware.h>
+#include <mach/devices-common.h>
+
+#define imx_mxc_rtc_data_entry_single(soc)				\
+	{								\
+		.iobase = soc ## _RTC_BASE_ADDR,			\
+		.irq = soc ## _INT_RTC,					\
+	}
+
+#ifdef CONFIG_SOC_IMX31
+const struct imx_mxc_rtc_data imx31_mxc_rtc_data __initconst =
+	imx_mxc_rtc_data_entry_single(MX31);
+#endif /* ifdef CONFIG_SOC_IMX31 */
+
+struct platform_device *__init imx_add_mxc_rtc(
+		const struct imx_mxc_rtc_data *data)
+{
+	struct resource res[] = {
+		{
+			.start = data->iobase,
+			.end = data->iobase + SZ_16K - 1,
+			.flags = IORESOURCE_MEM,
+		}, {
+			.start = data->irq,
+			.end = data->irq,
+			.flags = IORESOURCE_IRQ,
+		},
+	};
+
+	return imx_add_platform_device("mxc_rtc", -1,
+			res, ARRAY_SIZE(res), NULL, 0);
+}
diff -druN linux-2.6.39-libre/arch/arm/plat-mxc/devices/platform-spi_imx.c linux-3.0-rc7-libre/arch/arm/plat-mxc/devices/platform-spi_imx.c
--- linux-2.6.39-libre/arch/arm/plat-mxc/devices/platform-spi_imx.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/plat-mxc/devices/platform-spi_imx.c	2011-07-11 19:51:52.000000000 -0400
@@ -80,7 +80,7 @@
 
 #ifdef CONFIG_SOC_IMX51
 const struct imx_spi_imx_data imx51_cspi_data __initconst =
-	imx_spi_imx_data_entry_single(MX51, CSPI, "imx51-cspi", 0, , SZ_4K);
+	imx_spi_imx_data_entry_single(MX51, CSPI, "imx51-cspi", 2, , SZ_4K);
 
 const struct imx_spi_imx_data imx51_ecspi_data[] __initconst = {
 #define imx51_ecspi_data_entry(_id, _hwid)				\
diff -druN linux-2.6.39-libre/arch/arm/plat-mxc/epit.c linux-3.0-rc7-libre/arch/arm/plat-mxc/epit.c
--- linux-2.6.39-libre/arch/arm/plat-mxc/epit.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/plat-mxc/epit.c	2011-07-11 19:51:52.000000000 -0400
@@ -83,26 +83,12 @@
 	__raw_writel(EPITSR_OCIF, timer_base + EPITSR);
 }
 
-static cycle_t epit_read(struct clocksource *cs)
-{
-	return 0 - __raw_readl(timer_base + EPITCNR);
-}
-
-static struct clocksource clocksource_epit = {
-	.name		= "epit",
-	.rating		= 200,
-	.read		= epit_read,
-	.mask		= CLOCKSOURCE_MASK(32),
-	.flags		= CLOCK_SOURCE_IS_CONTINUOUS,
-};
-
 static int __init epit_clocksource_init(struct clk *timer_clk)
 {
 	unsigned int c = clk_get_rate(timer_clk);
 
-	clocksource_register_hz(&clocksource_epit, c);
-
-	return 0;
+	return clocksource_mmio_init(timer_base + EPITCNR, "epit", c, 200, 32,
+			clocksource_mmio_readl_down);
 }
 
 /* clock event */
diff -druN linux-2.6.39-libre/arch/arm/plat-mxc/include/mach/common.h linux-3.0-rc7-libre/arch/arm/plat-mxc/include/mach/common.h
--- linux-2.6.39-libre/arch/arm/plat-mxc/include/mach/common.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/plat-mxc/include/mach/common.h	2011-07-11 19:51:52.000000000 -0400
@@ -23,7 +23,6 @@
 extern void mx50_map_io(void);
 extern void mx51_map_io(void);
 extern void mx53_map_io(void);
-extern void mxc91231_map_io(void);
 extern void imx1_init_early(void);
 extern void imx21_init_early(void);
 extern void imx25_init_early(void);
@@ -33,7 +32,6 @@
 extern void imx50_init_early(void);
 extern void imx51_init_early(void);
 extern void imx53_init_early(void);
-extern void mxc91231_init_early(void);
 extern void mxc_init_irq(void __iomem *);
 extern void tzic_init_irq(void __iomem *);
 extern void mx1_init_irq(void);
@@ -45,7 +43,6 @@
 extern void mx50_init_irq(void);
 extern void mx51_init_irq(void);
 extern void mx53_init_irq(void);
-extern void mxc91231_init_irq(void);
 extern void epit_timer_init(struct clk *timer_clk, void __iomem *base, int irq);
 extern void mxc_timer_init(struct clk *timer_clk, void __iomem *, int);
 extern int mx1_clocks_init(unsigned long fref);
@@ -58,14 +55,11 @@
 			unsigned long ckih1, unsigned long ckih2);
 extern int mx53_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);
 extern void mxc_set_cpu_type(unsigned int type);
 extern void mxc_arch_reset_init(void __iomem *);
-extern void mxc91231_power_off(void);
-extern void mxc91231_arch_reset(int, const char *);
-extern void mxc91231_prepare_idle(void);
 extern void mx51_efikamx_reset(void);
 extern int mx53_revision(void);
+extern int mx53_display_revision(void);
 #endif
diff -druN linux-2.6.39-libre/arch/arm/plat-mxc/include/mach/debug-macro.S linux-3.0-rc7-libre/arch/arm/plat-mxc/include/mach/debug-macro.S
--- linux-2.6.39-libre/arch/arm/plat-mxc/include/mach/debug-macro.S	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/plat-mxc/include/mach/debug-macro.S	2011-07-11 19:51:52.000000000 -0400
@@ -44,13 +44,6 @@
 #define UART_PADDR	MX51_UART1_BASE_ADDR
 #endif
 
-#ifdef CONFIG_ARCH_MXC91231
-#ifdef UART_PADDR
-#error "CONFIG_DEBUG_LL is incompatible with multiple archs"
-#endif
-#define UART_PADDR	MXC91231_UART2_BASE_ADDR
-#endif
-
 #define UART_VADDR	IMX_IO_ADDRESS(UART_PADDR)
 
 		.macro	addruart, rp, rv
diff -druN linux-2.6.39-libre/arch/arm/plat-mxc/include/mach/devices-common.h linux-3.0-rc7-libre/arch/arm/plat-mxc/include/mach/devices-common.h
--- linux-2.6.39-libre/arch/arm/plat-mxc/include/mach/devices-common.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/plat-mxc/include/mach/devices-common.h	2011-07-11 19:51:52.000000000 -0400
@@ -166,6 +166,24 @@
 		const struct imx_imx_udc_data *data,
 		const struct imxusb_platform_data *pdata);
 
+#include <mach/ipu.h>
+#include <mach/mx3fb.h>
+#include <mach/mx3_camera.h>
+struct imx_ipu_core_data {
+	resource_size_t iobase;
+	resource_size_t synirq;
+	resource_size_t errirq;
+};
+struct platform_device *__init imx_add_ipu_core(
+		const struct imx_ipu_core_data *data,
+		const struct ipu_platform_data *pdata);
+struct platform_device *__init imx_alloc_mx3_camera(
+		const struct imx_ipu_core_data *data,
+		const struct mx3_camera_pdata *pdata);
+struct platform_device *__init imx_add_mx3_sdc_fb(
+		const struct imx_ipu_core_data *data,
+		struct mx3fb_platform_data *pdata);
+
 #include <mach/mx1_camera.h>
 struct imx_mx1_camera_data {
 	resource_size_t iobase;
@@ -237,6 +255,15 @@
 struct platform_device *__init imx_add_mxc_pwm(
 		const struct imx_mxc_pwm_data *data);
 
+/* mxc_rtc */
+struct imx_mxc_rtc_data {
+	resource_size_t iobase;
+	resource_size_t irq;
+};
+struct platform_device *__init imx_add_mxc_rtc(
+		const struct imx_mxc_rtc_data *data);
+
+/* mxc_w1 */
 struct imx_mxc_w1_data {
 	resource_size_t iobase;
 };
diff -druN linux-2.6.39-libre/arch/arm/plat-mxc/include/mach/hardware.h linux-3.0-rc7-libre/arch/arm/plat-mxc/include/mach/hardware.h
--- linux-2.6.39-libre/arch/arm/plat-mxc/include/mach/hardware.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/plat-mxc/include/mach/hardware.h	2011-07-11 19:51:52.000000000 -0400
@@ -86,15 +86,6 @@
  *	SPBA0	0x70000000+0x100000	->	0xf5400000+0x100000
  *	AIPS1	0x73f00000+0x100000	->	0xf5700000+0x100000
  *	AIPS2	0x83f00000+0x100000	->	0xf4300000+0x100000
- * mxc91231:
- *	L2CC	0x30000000+0x010000	->	0xf4400000+0x010000
- *	X_MEMC	0xb8000000+0x010000	->	0xf4c00000+0x010000
- *	ROMP	0x60000000+0x010000	->	0xf5000000+0x010000
- *	AVIC	0x68000000+0x010000	->	0xf5800000+0x010000
- *	AIPS1	0x43f00000+0x100000	->	0xf5300000+0x100000
- *	SPBA0	0x50000000+0x100000	->	0xf5400000+0x100000
- *	SPBA1	0x52000000+0x100000	->	0xf5600000+0x100000
- *	AIPS2	0x53f00000+0x100000	->	0xf5700000+0x100000
  */
 #define IMX_IO_P2V(x)	(						\
 			0xf4000000 +					\
@@ -104,6 +95,8 @@
 
 #define IMX_IO_ADDRESS(x)	IOMEM(IMX_IO_P2V(x))
 
+#include <mach/mxc.h>
+
 #ifdef CONFIG_ARCH_MX5
 #include <mach/mx50.h>
 #include <mach/mx51.h>
@@ -134,12 +127,6 @@
 # include <mach/mx25.h>
 #endif
 
-#ifdef CONFIG_ARCH_MXC91231
-# include <mach/mxc91231.h>
-#endif
-
-#include <mach/mxc.h>
-
 #define imx_map_entry(soc, name, _type)	{				\
 	.virtual = soc ## _IO_P2V(soc ## _ ## name ## _BASE_ADDR),	\
 	.pfn = __phys_to_pfn(soc ## _ ## name ## _BASE_ADDR),		\
diff -druN linux-2.6.39-libre/arch/arm/plat-mxc/include/mach/io.h linux-3.0-rc7-libre/arch/arm/plat-mxc/include/mach/io.h
--- linux-2.6.39-libre/arch/arm/plat-mxc/include/mach/io.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/plat-mxc/include/mach/io.h	2011-07-11 19:51:52.000000000 -0400
@@ -14,19 +14,26 @@
 /* Allow IO space to be anywhere in the memory */
 #define IO_SPACE_LIMIT 0xffffffff
 
-#ifdef CONFIG_ARCH_MX3
-#define __arch_ioremap __mx3_ioremap
+#if defined(CONFIG_SOC_IMX31) || defined(CONFIG_SOC_IMX35)
+#include <mach/hardware.h>
+
+#define __arch_ioremap __imx_ioremap
 #define __arch_iounmap __iounmap
 
+#define addr_in_module(addr, mod) \
+	((unsigned long)(addr) - mod ## _BASE_ADDR < mod ## _SIZE)
+
 static inline void __iomem *
-__mx3_ioremap(unsigned long phys_addr, size_t size, unsigned int mtype)
+__imx_ioremap(unsigned long phys_addr, size_t size, unsigned int mtype)
 {
-	if (mtype == MT_DEVICE) {
-		/* Access all peripherals below 0x80000000 as nonshared device
-		 * but leave l2cc alone.
+	if (mtype == MT_DEVICE && (cpu_is_mx31() || cpu_is_mx35())) {
+		/*
+		 * Access all peripherals below 0x80000000 as nonshared device
+		 * on mx3, but leave l2cc alone.  Otherwise cache corruptions
+		 * can occur.
 		 */
-		if ((phys_addr < 0x80000000) && ((phys_addr < 0x30000000) ||
-			(phys_addr >= 0x30000000 + SZ_1M)))
+		if (phys_addr < 0x80000000 &&
+				!addr_in_module(phys_addr, MX3x_L2CC))
 			mtype = MT_DEVICE_NONSHARED;
 	}
 
diff -druN linux-2.6.39-libre/arch/arm/plat-mxc/include/mach/iomux-mx25.h linux-3.0-rc7-libre/arch/arm/plat-mxc/include/mach/iomux-mx25.h
--- linux-2.6.39-libre/arch/arm/plat-mxc/include/mach/iomux-mx25.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/plat-mxc/include/mach/iomux-mx25.h	2011-07-11 19:51:52.000000000 -0400
@@ -89,13 +89,16 @@
 #define MX25_PAD_CS0__GPIO_4_2		IOMUX_PAD(0x000, 0x04c, 0x05, 0, 0, NO_PAD_CTRL)
 
 #define MX25_PAD_CS1__CS1		IOMUX_PAD(0x000, 0x050, 0x00, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_CS1__NF_CE3		IOMUX_PAD(0x000, 0x050, 0x01, 0, 0, NO_PAD_CTRL)
 #define MX25_PAD_CS1__GPIO_4_3		IOMUX_PAD(0x000, 0x050, 0x05, 0, 0, NO_PAD_CTRL)
 
 #define MX25_PAD_CS4__CS4		IOMUX_PAD(0x264, 0x054, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_CS4__NF_CE1		IOMUX_PAD(0x264, 0x054, 0x01, 0, 0, NO_PAD_CTRL)
 #define MX25_PAD_CS4__UART5_CTS		IOMUX_PAD(0x264, 0x054, 0x13, 0, 0, NO_PAD_CTRL)
 #define MX25_PAD_CS4__GPIO_3_20		IOMUX_PAD(0x264, 0x054, 0x15, 0, 0, NO_PAD_CTRL)
 
 #define MX25_PAD_CS5__CS5		IOMUX_PAD(0x268, 0x058, 0x10, 0, 0, NO_PAD_CTRL)
+#define MX25_PAD_CS5__NF_CE2		IOMUX_PAD(0x268, 0x058, 0x01, 0, 0, NO_PAD_CTRL)
 #define MX25_PAD_CS5__UART5_RTS		IOMUX_PAD(0x268, 0x058, 0x13, 0x574, 0, NO_PAD_CTRL)
 #define MX25_PAD_CS5__GPIO_3_21		IOMUX_PAD(0x268, 0x058, 0x15, 0, 0, NO_PAD_CTRL)
 
diff -druN linux-2.6.39-libre/arch/arm/plat-mxc/include/mach/iomux-mxc91231.h linux-3.0-rc7-libre/arch/arm/plat-mxc/include/mach/iomux-mxc91231.h
--- linux-2.6.39-libre/arch/arm/plat-mxc/include/mach/iomux-mxc91231.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/plat-mxc/include/mach/iomux-mxc91231.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,283 +0,0 @@
-/*
- * Copyright 2004-2006 Freescale Semiconductor, Inc. All Rights Reserved.
- * Copyright (C) 2008 by Sascha Hauer <kernel@pengutronix.de>
- * Copyright (C) 2009 by Dmitriy Taychenachev <dimichxp@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 __MACH_IOMUX_MXC91231_H__
-#define __MACH_IOMUX_MXC91231_H__
-
-/*
- * various IOMUX output functions
- */
-
-#define	IOMUX_OCONFIG_GPIO (0 << 4)	/* used as GPIO */
-#define	IOMUX_OCONFIG_FUNC (1 << 4)	/* used as function */
-#define	IOMUX_OCONFIG_ALT1 (2 << 4)	/* used as alternate function 1 */
-#define	IOMUX_OCONFIG_ALT2 (3 << 4)	/* used as alternate function 2 */
-#define	IOMUX_OCONFIG_ALT3 (4 << 4)	/* used as alternate function 3 */
-#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_GPIO  1		/* used as GPIO */
-#define	IOMUX_ICONFIG_FUNC  2		/* used as function */
-#define	IOMUX_ICONFIG_ALT1  4		/* used as alternate function 1 */
-#define	IOMUX_ICONFIG_ALT2  8		/* used as alternate function 2 */
-
-#define IOMUX_CONFIG_GPIO (IOMUX_OCONFIG_GPIO | IOMUX_ICONFIG_GPIO)
-#define IOMUX_CONFIG_FUNC (IOMUX_OCONFIG_FUNC | IOMUX_ICONFIG_FUNC)
-#define IOMUX_CONFIG_ALT1 (IOMUX_OCONFIG_ALT1 | IOMUX_ICONFIG_ALT1)
-#define IOMUX_CONFIG_ALT2 (IOMUX_OCONFIG_ALT2 | IOMUX_ICONFIG_ALT2)
-
-/*
- * setups a single pin:
- * 	- reserves the pin so that it is not claimed by another driver
- * 	- setups the iomux according to the configuration
- * 	- if the pin is configured as a GPIO, we claim it through kernel gpiolib
- */
-int mxc_iomux_alloc_pin(unsigned int pin_mode, const char *label);
-/*
- * setups mutliple pins
- * convenient way to call the above function with tables
- */
-int mxc_iomux_setup_multiple_pins(const unsigned int *pin_list, unsigned count,
-		const char *label);
-
-/*
- * releases a single pin:
- * 	- make it available for a future use by another driver
- * 	- frees the GPIO if the pin was configured as GPIO
- * 	- DOES NOT reconfigure the IOMUX in its reset state
- */
-void mxc_iomux_release_pin(unsigned int pin_mode);
-/*
- * releases multiple pins
- * convenvient way to call the above function with tables
- */
-void mxc_iomux_release_multiple_pins(const unsigned int *pin_list, int count);
-
-#define MUX_SIDE_AP		(0)
-#define MUX_SIDE_SP		(1)
-
-#define MUX_SIDE_SHIFT		(26)
-#define MUX_SIDE_MASK		(0x1 << MUX_SIDE_SHIFT)
-
-#define MUX_GPIO_PORT_SHIFT	(23)
-#define MUX_GPIO_PORT_MASK	(0x7 << MUX_GPIO_PORT_SHIFT)
-
-#define MUX_GPIO_PIN_SHIFT	(20)
-#define MUX_GPIO_PIN_MASK	(0x1f << MUX_GPIO_PIN_SHIFT)
-
-#define MUX_REG_SHIFT		(15)
-#define MUX_REG_MASK		(0x1f << MUX_REG_SHIFT)
-
-#define MUX_FIELD_SHIFT		(13)
-#define MUX_FIELD_MASK		(0x3 << MUX_FIELD_SHIFT)
-
-#define MUX_PADGRP_SHIFT	(8)
-#define MUX_PADGRP_MASK		(0x1f << MUX_PADGRP_SHIFT)
-
-#define MUX_PIN_MASK		(0xffffff << 8)
-
-#define GPIO_PORT_MAX		(3)
-
-#define IOMUX_PIN(side, gport, gpin, ctlreg, ctlfield, padgrp) \
-	(((side) << MUX_SIDE_SHIFT) |		  \
-	 (gport << MUX_GPIO_PORT_SHIFT) |		\
-	 ((gpin) << MUX_GPIO_PIN_SHIFT) |		\
-	 ((ctlreg) << MUX_REG_SHIFT) |		\
-	 ((ctlfield) << MUX_FIELD_SHIFT) |		\
-	 ((padgrp) << MUX_PADGRP_SHIFT))
-
-#define MUX_MODE_OUT_SHIFT	(4)
-#define MUX_MODE_IN_SHIFT	(0)
-#define MUX_MODE_SHIFT		(0)
-#define MUX_MODE_MASK		(0xff << MUX_MODE_SHIFT)
-
-#define IOMUX_MODE(pin, mode) \
-	(pin | (mode << MUX_MODE_SHIFT))
-
-enum iomux_pins {
-	/* AP Side pins */
-	MXC91231_PIN_AP_CLE		= IOMUX_PIN(0, 0,  0,  0, 0, 24),
-	MXC91231_PIN_AP_ALE		= IOMUX_PIN(0, 0,  1,  0, 1, 24),
-	MXC91231_PIN_AP_CE_B		= IOMUX_PIN(0, 0,  2,  0, 2, 24),
-	MXC91231_PIN_AP_RE_B		= IOMUX_PIN(0, 0,  3,  0, 3, 24),
-	MXC91231_PIN_AP_WE_B		= IOMUX_PIN(0, 0,  4,  1, 0, 24),
-	MXC91231_PIN_AP_WP_B		= IOMUX_PIN(0, 0,  5,  1, 1, 24),
-	MXC91231_PIN_AP_BSY_B		= IOMUX_PIN(0, 0,  6,  1, 2, 24),
-	MXC91231_PIN_AP_U1_TXD		= IOMUX_PIN(0, 0,  7,  1, 3, 28),
-	MXC91231_PIN_AP_U1_RXD		= IOMUX_PIN(0, 0,  8,  2, 0, 28),
-	MXC91231_PIN_AP_U1_RTS_B	= IOMUX_PIN(0, 0,  9,  2, 1, 28),
-	MXC91231_PIN_AP_U1_CTS_B	= IOMUX_PIN(0, 0, 10,  2, 2, 28),
-	MXC91231_PIN_AP_AD1_TXD		= IOMUX_PIN(0, 0, 11,  2, 3,  9),
-	MXC91231_PIN_AP_AD1_RXD		= IOMUX_PIN(0, 0, 12,  3, 0,  9),
-	MXC91231_PIN_AP_AD1_TXC		= IOMUX_PIN(0, 0, 13,  3, 1,  9),
-	MXC91231_PIN_AP_AD1_TXFS	= IOMUX_PIN(0, 0, 14,  3, 2,  9),
-	MXC91231_PIN_AP_AD2_TXD		= IOMUX_PIN(0, 0, 15,  3, 3,  9),
-	MXC91231_PIN_AP_AD2_RXD		= IOMUX_PIN(0, 0, 16,  4, 0,  9),
-	MXC91231_PIN_AP_AD2_TXC		= IOMUX_PIN(0, 0, 17,  4, 1,  9),
-	MXC91231_PIN_AP_AD2_TXFS	= IOMUX_PIN(0, 0, 18,  4, 2,  9),
-	MXC91231_PIN_AP_OWDAT		= IOMUX_PIN(0, 0, 19,  4, 3, 28),
-	MXC91231_PIN_AP_IPU_LD17	= IOMUX_PIN(0, 0, 20,  5, 0, 28),
-	MXC91231_PIN_AP_IPU_D3_VSYNC	= IOMUX_PIN(0, 0, 21,  5, 1, 28),
-	MXC91231_PIN_AP_IPU_D3_HSYNC	= IOMUX_PIN(0, 0, 22,  5, 2, 28),
-	MXC91231_PIN_AP_IPU_D3_CLK	= IOMUX_PIN(0, 0, 23,  5, 3, 28),
-	MXC91231_PIN_AP_IPU_D3_DRDY	= IOMUX_PIN(0, 0, 24,  6, 0, 28),
-	MXC91231_PIN_AP_IPU_D3_CONTR	= IOMUX_PIN(0, 0, 25,  6, 1, 28),
-	MXC91231_PIN_AP_IPU_D0_CS	= IOMUX_PIN(0, 0, 26,  6, 2, 28),
-	MXC91231_PIN_AP_IPU_LD16	= IOMUX_PIN(0, 0, 27,  6, 3, 28),
-	MXC91231_PIN_AP_IPU_D2_CS	= IOMUX_PIN(0, 0, 28,  7, 0, 28),
-	MXC91231_PIN_AP_IPU_PAR_RS	= IOMUX_PIN(0, 0, 29,  7, 1, 28),
-	MXC91231_PIN_AP_IPU_D3_PS	= IOMUX_PIN(0, 0, 30,  7, 2, 28),
-	MXC91231_PIN_AP_IPU_D3_CLS	= IOMUX_PIN(0, 0, 31,  7, 3, 28),
-	MXC91231_PIN_AP_IPU_RD		= IOMUX_PIN(0, 1,  0,  8, 0, 28),
-	MXC91231_PIN_AP_IPU_WR		= IOMUX_PIN(0, 1,  1,  8, 1, 28),
-	MXC91231_PIN_AP_IPU_LD0		= IOMUX_PIN(0, 7,  0,  8, 2, 28),
-	MXC91231_PIN_AP_IPU_LD1		= IOMUX_PIN(0, 7,  0,  8, 3, 28),
-	MXC91231_PIN_AP_IPU_LD2		= IOMUX_PIN(0, 7,  0,  9, 0, 28),
-	MXC91231_PIN_AP_IPU_LD3		= IOMUX_PIN(0, 1,  2,  9, 1, 28),
-	MXC91231_PIN_AP_IPU_LD4		= IOMUX_PIN(0, 1,  3,  9, 2, 28),
-	MXC91231_PIN_AP_IPU_LD5		= IOMUX_PIN(0, 1,  4,  9, 3, 28),
-	MXC91231_PIN_AP_IPU_LD6		= IOMUX_PIN(0, 1,  5, 10, 0, 28),
-	MXC91231_PIN_AP_IPU_LD7		= IOMUX_PIN(0, 1,  6, 10, 1, 28),
-	MXC91231_PIN_AP_IPU_LD8		= IOMUX_PIN(0, 1,  7, 10, 2, 28),
-	MXC91231_PIN_AP_IPU_LD9		= IOMUX_PIN(0, 1,  8, 10, 3, 28),
-	MXC91231_PIN_AP_IPU_LD10	= IOMUX_PIN(0, 1,  9, 11, 0, 28),
-	MXC91231_PIN_AP_IPU_LD11	= IOMUX_PIN(0, 1, 10, 11, 1, 28),
-	MXC91231_PIN_AP_IPU_LD12	= IOMUX_PIN(0, 1, 11, 11, 2, 28),
-	MXC91231_PIN_AP_IPU_LD13	= IOMUX_PIN(0, 1, 12, 11, 3, 28),
-	MXC91231_PIN_AP_IPU_LD14	= IOMUX_PIN(0, 1, 13, 12, 0, 28),
-	MXC91231_PIN_AP_IPU_LD15	= IOMUX_PIN(0, 1, 14, 12, 1, 28),
-	MXC91231_PIN_AP_KPROW4		= IOMUX_PIN(0, 7,  0, 12, 2, 10),
-	MXC91231_PIN_AP_KPROW5		= IOMUX_PIN(0, 1, 16, 12, 3, 10),
-	MXC91231_PIN_AP_GPIO_AP_B17	= IOMUX_PIN(0, 1, 17, 13, 0, 10),
-	MXC91231_PIN_AP_GPIO_AP_B18	= IOMUX_PIN(0, 1, 18, 13, 1, 10),
-	MXC91231_PIN_AP_KPCOL3		= IOMUX_PIN(0, 1, 19, 13, 2, 11),
-	MXC91231_PIN_AP_KPCOL4		= IOMUX_PIN(0, 1, 20, 13, 3, 11),
-	MXC91231_PIN_AP_KPCOL5		= IOMUX_PIN(0, 1, 21, 14, 0, 11),
-	MXC91231_PIN_AP_GPIO_AP_B22	= IOMUX_PIN(0, 1, 22, 14, 1, 11),
-	MXC91231_PIN_AP_GPIO_AP_B23	= IOMUX_PIN(0, 1, 23, 14, 2, 11),
-	MXC91231_PIN_AP_CSI_D0		= IOMUX_PIN(0, 1, 24, 14, 3, 21),
-	MXC91231_PIN_AP_CSI_D1		= IOMUX_PIN(0, 1, 25, 15, 0, 21),
-	MXC91231_PIN_AP_CSI_D2		= IOMUX_PIN(0, 1, 26, 15, 1, 21),
-	MXC91231_PIN_AP_CSI_D3		= IOMUX_PIN(0, 1, 27, 15, 2, 21),
-	MXC91231_PIN_AP_CSI_D4		= IOMUX_PIN(0, 1, 28, 15, 3, 21),
-	MXC91231_PIN_AP_CSI_D5		= IOMUX_PIN(0, 1, 29, 16, 0, 21),
-	MXC91231_PIN_AP_CSI_D6		= IOMUX_PIN(0, 1, 30, 16, 1, 21),
-	MXC91231_PIN_AP_CSI_D7		= IOMUX_PIN(0, 1, 31, 16, 2, 21),
-	MXC91231_PIN_AP_CSI_D8		= IOMUX_PIN(0, 2,  0, 16, 3, 21),
-	MXC91231_PIN_AP_CSI_D9		= IOMUX_PIN(0, 2,  1, 17, 0, 21),
-	MXC91231_PIN_AP_CSI_MCLK	= IOMUX_PIN(0, 2,  2, 17, 1, 21),
-	MXC91231_PIN_AP_CSI_VSYNC	= IOMUX_PIN(0, 2,  3, 17, 2, 21),
-	MXC91231_PIN_AP_CSI_HSYNC	= IOMUX_PIN(0, 2,  4, 17, 3, 21),
-	MXC91231_PIN_AP_CSI_PIXCLK	= IOMUX_PIN(0, 2,  5, 18, 0, 21),
-	MXC91231_PIN_AP_I2CLK		= IOMUX_PIN(0, 2,  6, 18, 1, 12),
-	MXC91231_PIN_AP_I2DAT		= IOMUX_PIN(0, 2,  7, 18, 2, 12),
-	MXC91231_PIN_AP_GPIO_AP_C8	= IOMUX_PIN(0, 2,  8, 18, 3,  9),
-	MXC91231_PIN_AP_GPIO_AP_C9	= IOMUX_PIN(0, 2,  9, 19, 0,  9),
-	MXC91231_PIN_AP_GPIO_AP_C10	= IOMUX_PIN(0, 2, 10, 19, 1,  9),
-	MXC91231_PIN_AP_GPIO_AP_C11	= IOMUX_PIN(0, 2, 11, 19, 2,  9),
-	MXC91231_PIN_AP_GPIO_AP_C12	= IOMUX_PIN(0, 2, 12, 19, 3,  9),
-	MXC91231_PIN_AP_GPIO_AP_C13	= IOMUX_PIN(0, 2, 13, 20, 0, 28),
-	MXC91231_PIN_AP_GPIO_AP_C14	= IOMUX_PIN(0, 2, 14, 20, 1, 28),
-	MXC91231_PIN_AP_GPIO_AP_C15	= IOMUX_PIN(0, 2, 15, 20, 2,  9),
-	MXC91231_PIN_AP_GPIO_AP_C16	= IOMUX_PIN(0, 2, 16, 20, 3,  9),
-	MXC91231_PIN_AP_GPIO_AP_C17	= IOMUX_PIN(0, 2, 17, 21, 0,  9),
-	MXC91231_PIN_AP_ED_INT0		= IOMUX_PIN(0, 2, 18, 21, 1, 22),
-	MXC91231_PIN_AP_ED_INT1		= IOMUX_PIN(0, 2, 19, 21, 2, 22),
-	MXC91231_PIN_AP_ED_INT2		= IOMUX_PIN(0, 2, 20, 21, 3, 22),
-	MXC91231_PIN_AP_ED_INT3		= IOMUX_PIN(0, 2, 21, 22, 0, 22),
-	MXC91231_PIN_AP_ED_INT4		= IOMUX_PIN(0, 2, 22, 22, 1, 23),
-	MXC91231_PIN_AP_ED_INT5		= IOMUX_PIN(0, 2, 23, 22, 2, 23),
-	MXC91231_PIN_AP_ED_INT6		= IOMUX_PIN(0, 2, 24, 22, 3, 23),
-	MXC91231_PIN_AP_ED_INT7		= IOMUX_PIN(0, 2, 25, 23, 0, 23),
-	MXC91231_PIN_AP_U2_DSR_B	= IOMUX_PIN(0, 2, 26, 23, 1, 28),
-	MXC91231_PIN_AP_U2_RI_B		= IOMUX_PIN(0, 2, 27, 23, 2, 28),
-	MXC91231_PIN_AP_U2_CTS_B	= IOMUX_PIN(0, 2, 28, 23, 3, 28),
-	MXC91231_PIN_AP_U2_DTR_B	= IOMUX_PIN(0, 2, 29, 24, 0, 28),
-	MXC91231_PIN_AP_KPROW0		= IOMUX_PIN(0, 7,  0, 24, 1, 10),
-	MXC91231_PIN_AP_KPROW1		= IOMUX_PIN(0, 1, 15, 24, 2, 10),
-	MXC91231_PIN_AP_KPROW2		= IOMUX_PIN(0, 7,  0, 24, 3, 10),
-	MXC91231_PIN_AP_KPROW3		= IOMUX_PIN(0, 7,  0, 25, 0, 10),
-	MXC91231_PIN_AP_KPCOL0		= IOMUX_PIN(0, 7,  0, 25, 1, 11),
-	MXC91231_PIN_AP_KPCOL1		= IOMUX_PIN(0, 7,  0, 25, 2, 11),
-	MXC91231_PIN_AP_KPCOL2		= IOMUX_PIN(0, 7,  0, 25, 3, 11),
-
-	/* Shared pins */
-	MXC91231_PIN_SP_U3_TXD		= IOMUX_PIN(1, 3,  0,  0, 0, 28),
-	MXC91231_PIN_SP_U3_RXD		= IOMUX_PIN(1, 3,  1,  0, 1, 28),
-	MXC91231_PIN_SP_U3_RTS_B	= IOMUX_PIN(1, 3,  2,  0, 2, 28),
-	MXC91231_PIN_SP_U3_CTS_B	= IOMUX_PIN(1, 3,  3,  0, 3, 28),
-	MXC91231_PIN_SP_USB_TXOE_B	= IOMUX_PIN(1, 3,  4,  1, 0, 28),
-	MXC91231_PIN_SP_USB_DAT_VP	= IOMUX_PIN(1, 3,  5,  1, 1, 28),
-	MXC91231_PIN_SP_USB_SE0_VM	= IOMUX_PIN(1, 3,  6,  1, 2, 28),
-	MXC91231_PIN_SP_USB_RXD		= IOMUX_PIN(1, 3,  7,  1, 3, 28),
-	MXC91231_PIN_SP_UH2_TXOE_B	= IOMUX_PIN(1, 3,  8,  2, 0, 28),
-	MXC91231_PIN_SP_UH2_SPEED	= IOMUX_PIN(1, 3,  9,  2, 1, 28),
-	MXC91231_PIN_SP_UH2_SUSPEN	= IOMUX_PIN(1, 3, 10,  2, 2, 28),
-	MXC91231_PIN_SP_UH2_TXDP	= IOMUX_PIN(1, 3, 11,  2, 3, 28),
-	MXC91231_PIN_SP_UH2_RXDP	= IOMUX_PIN(1, 3, 12,  3, 0, 28),
-	MXC91231_PIN_SP_UH2_RXDM	= IOMUX_PIN(1, 3, 13,  3, 1, 28),
-	MXC91231_PIN_SP_UH2_OVR		= IOMUX_PIN(1, 3, 14,  3, 2, 28),
-	MXC91231_PIN_SP_UH2_PWR		= IOMUX_PIN(1, 3, 15,  3, 3, 28),
-	MXC91231_PIN_SP_SD1_DAT0	= IOMUX_PIN(1, 3, 16,  4, 0, 25),
-	MXC91231_PIN_SP_SD1_DAT1	= IOMUX_PIN(1, 3, 17,  4, 1, 25),
-	MXC91231_PIN_SP_SD1_DAT2	= IOMUX_PIN(1, 3, 18,  4, 2, 25),
-	MXC91231_PIN_SP_SD1_DAT3	= IOMUX_PIN(1, 3, 19,  4, 3, 25),
-	MXC91231_PIN_SP_SD1_CMD		= IOMUX_PIN(1, 3, 20,  5, 0, 25),
-	MXC91231_PIN_SP_SD1_CLK		= IOMUX_PIN(1, 3, 21,  5, 1, 25),
-	MXC91231_PIN_SP_SD2_DAT0	= IOMUX_PIN(1, 3, 22,  5, 2, 26),
-	MXC91231_PIN_SP_SD2_DAT1	= IOMUX_PIN(1, 3, 23,  5, 3, 26),
-	MXC91231_PIN_SP_SD2_DAT2	= IOMUX_PIN(1, 3, 24,  6, 0, 26),
-	MXC91231_PIN_SP_SD2_DAT3	= IOMUX_PIN(1, 3, 25,  6, 1, 26),
-	MXC91231_PIN_SP_GPIO_SP_A26	= IOMUX_PIN(1, 3, 26,  6, 2, 28),
-	MXC91231_PIN_SP_SPI1_CLK	= IOMUX_PIN(1, 3, 27,  6, 3, 13),
-	MXC91231_PIN_SP_SPI1_MOSI	= IOMUX_PIN(1, 3, 28,  7, 0, 13),
-	MXC91231_PIN_SP_SPI1_MISO	= IOMUX_PIN(1, 3, 29,  7, 1, 13),
-	MXC91231_PIN_SP_SPI1_SS0	= IOMUX_PIN(1, 3, 30,  7, 2, 13),
-	MXC91231_PIN_SP_SPI1_SS1	= IOMUX_PIN(1, 3, 31,  7, 3, 13),
-	MXC91231_PIN_SP_SD2_CMD		= IOMUX_PIN(1, 7,  0,  8, 0, 26),
-	MXC91231_PIN_SP_SD2_CLK		= IOMUX_PIN(1, 7,  0,  8, 1, 26),
-	MXC91231_PIN_SP_SIM1_RST_B	= IOMUX_PIN(1, 2, 30,  8, 2, 28),
-	MXC91231_PIN_SP_SIM1_SVEN	= IOMUX_PIN(1, 7,  0,  8, 3, 28),
-	MXC91231_PIN_SP_SIM1_CLK	= IOMUX_PIN(1, 7,  0,  9, 0, 28),
-	MXC91231_PIN_SP_SIM1_TRXD	= IOMUX_PIN(1, 7,  0,  9, 1, 28),
-	MXC91231_PIN_SP_SIM1_PD		= IOMUX_PIN(1, 2, 31,  9, 2, 28),
-	MXC91231_PIN_SP_UH2_TXDM	= IOMUX_PIN(1, 7,  0,  9, 3, 28),
-	MXC91231_PIN_SP_UH2_RXD		= IOMUX_PIN(1, 7,  0, 10, 0, 28),
-};
-
-#define PIN_AP_MAX	(104)
-#define PIN_SP_MAX	(41)
-
-#define PIN_MAX		(PIN_AP_MAX + PIN_SP_MAX)
-
-/*
- * Convenience values for use with mxc_iomux_mode()
- *
- * Format here is MXC91231_PIN_(pin name)__(function)
- */
-
-#define MXC91231_PIN_SP_USB_DAT_VP__USB_DAT_VP \
-	IOMUX_MODE(MXC91231_PIN_SP_USB_DAT_VP, IOMUX_CONFIG_FUNC)
-#define MXC91231_PIN_SP_USB_SE0_VM__USB_SE0_VM \
-	IOMUX_MODE(MXC91231_PIN_SP_USB_SE0_VM, IOMUX_CONFIG_FUNC)
-#define MXC91231_PIN_SP_USB_DAT_VP__RXD2 \
-	IOMUX_MODE(MXC91231_PIN_SP_USB_DAT_VP, IOMUX_CONFIG_ALT1)
-#define MXC91231_PIN_SP_USB_SE0_VM__TXD2 \
-	IOMUX_MODE(MXC91231_PIN_SP_USB_SE0_VM, IOMUX_CONFIG_ALT1)
-
-
-#endif /* __MACH_IOMUX_MXC91231_H__ */
diff -druN linux-2.6.39-libre/arch/arm/plat-mxc/include/mach/irqs.h linux-3.0-rc7-libre/arch/arm/plat-mxc/include/mach/irqs.h
--- linux-2.6.39-libre/arch/arm/plat-mxc/include/mach/irqs.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/plat-mxc/include/mach/irqs.h	2011-07-11 19:51:52.000000000 -0400
@@ -35,8 +35,6 @@
 #define MXC_GPIO_IRQS		(32 * 4)
 #elif defined CONFIG_SOC_IMX51
 #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
diff -druN linux-2.6.39-libre/arch/arm/plat-mxc/include/mach/memory.h linux-3.0-rc7-libre/arch/arm/plat-mxc/include/mach/memory.h
--- linux-2.6.39-libre/arch/arm/plat-mxc/include/mach/memory.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/plat-mxc/include/mach/memory.h	2011-07-11 19:51:52.000000000 -0400
@@ -19,7 +19,6 @@
 #define MX50_PHYS_OFFSET	UL(0x70000000)
 #define MX51_PHYS_OFFSET	UL(0x90000000)
 #define MX53_PHYS_OFFSET	UL(0x70000000)
-#define MXC91231_PHYS_OFFSET	UL(0x90000000)
 
 #if !defined(CONFIG_RUNTIME_PHYS_OFFSET)
 # if defined CONFIG_ARCH_MX1
@@ -32,8 +31,6 @@
 #  define PLAT_PHYS_OFFSET		MX27_PHYS_OFFSET
 # elif defined CONFIG_ARCH_MX3
 #  define PLAT_PHYS_OFFSET		MX3x_PHYS_OFFSET
-# elif defined CONFIG_ARCH_MXC91231
-#  define PLAT_PHYS_OFFSET		MXC91231_PHYS_OFFSET
 # elif defined CONFIG_ARCH_MX50
 #  define PLAT_PHYS_OFFSET		MX50_PHYS_OFFSET
 # elif defined CONFIG_ARCH_MX51
diff -druN linux-2.6.39-libre/arch/arm/plat-mxc/include/mach/mx27.h linux-3.0-rc7-libre/arch/arm/plat-mxc/include/mach/mx27.h
--- linux-2.6.39-libre/arch/arm/plat-mxc/include/mach/mx27.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/plat-mxc/include/mach/mx27.h	2011-07-11 19:51:52.000000000 -0400
@@ -60,8 +60,8 @@
 #define MX27_AUDMUX_BASE_ADDR			(MX27_AIPI_BASE_ADDR + 0x16000)
 #define MX27_CSPI3_BASE_ADDR			(MX27_AIPI_BASE_ADDR + 0x17000)
 #define MX27_MSHC_BASE_ADDR			(MX27_AIPI_BASE_ADDR + 0x18000)
-#define MX27_GPT5_BASE_ADDR			(MX27_AIPI_BASE_ADDR + 0x19000)
-#define MX27_GPT4_BASE_ADDR			(MX27_AIPI_BASE_ADDR + 0x1a000)
+#define MX27_GPT4_BASE_ADDR			(MX27_AIPI_BASE_ADDR + 0x19000)
+#define MX27_GPT5_BASE_ADDR			(MX27_AIPI_BASE_ADDR + 0x1a000)
 #define MX27_UART5_BASE_ADDR			(MX27_AIPI_BASE_ADDR + 0x1b000)
 #define MX27_UART6_BASE_ADDR			(MX27_AIPI_BASE_ADDR + 0x1c000)
 #define MX27_I2C2_BASE_ADDR			(MX27_AIPI_BASE_ADDR + 0x1d000)
diff -druN linux-2.6.39-libre/arch/arm/plat-mxc/include/mach/mx53.h linux-3.0-rc7-libre/arch/arm/plat-mxc/include/mach/mx53.h
--- linux-2.6.39-libre/arch/arm/plat-mxc/include/mach/mx53.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/plat-mxc/include/mach/mx53.h	2011-07-11 19:51:52.000000000 -0400
@@ -337,17 +337,4 @@
 #define MX53_INT_GPIO7_LOW	107
 #define MX53_INT_GPIO7_HIGH	108
 
-/* silicon revisions specific to i.MX53 */
-#define MX53_CHIP_REV_1_0		0x10
-#define MX53_CHIP_REV_1_1		0x11
-#define MX53_CHIP_REV_1_2		0x12
-#define MX53_CHIP_REV_1_3		0x13
-#define MX53_CHIP_REV_2_0		0x20
-#define MX53_CHIP_REV_2_1		0x21
-#define MX53_CHIP_REV_2_2		0x22
-#define MX53_CHIP_REV_2_3		0x23
-#define MX53_CHIP_REV_3_0		0x30
-#define MX53_CHIP_REV_3_1		0x31
-#define MX53_CHIP_REV_3_2		0x32
-
 #endif /* ifndef __MACH_MX53_H__ */
diff -druN linux-2.6.39-libre/arch/arm/plat-mxc/include/mach/mxc91231.h linux-3.0-rc7-libre/arch/arm/plat-mxc/include/mach/mxc91231.h
--- linux-2.6.39-libre/arch/arm/plat-mxc/include/mach/mxc91231.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/plat-mxc/include/mach/mxc91231.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,256 +0,0 @@
-/*
- *  Copyright 2004-2006 Freescale Semiconductor, Inc. All Rights Reserved.
- *    - Platform specific register memory map
- *
- *  Copyright 2005-2007 Motorola, 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.
- */
-#ifndef __MACH_MXC91231_H__
-#define __MACH_MXC91231_H__
-
-/*
- * L2CC
- */
-#define MXC91231_L2CC_BASE_ADDR		0x30000000
-#define MXC91231_L2CC_SIZE		SZ_64K
-
-/*
- * AIPS 1
- */
-#define MXC91231_AIPS1_BASE_ADDR	0x43F00000
-#define MXC91231_AIPS1_SIZE		SZ_1M
-
-#define MXC91231_AIPS1_CTRL_BASE_ADDR	MXC91231_AIPS1_BASE_ADDR
-#define MXC91231_MAX_BASE_ADDR		(MXC91231_AIPS1_BASE_ADDR + 0x04000)
-#define MXC91231_EVTMON_BASE_ADDR	(MXC91231_AIPS1_BASE_ADDR + 0x08000)
-#define MXC91231_CLKCTL_BASE_ADDR	(MXC91231_AIPS1_BASE_ADDR + 0x0C000)
-#define MXC91231_ETB_SLOT4_BASE_ADDR	(MXC91231_AIPS1_BASE_ADDR + 0x10000)
-#define MXC91231_ETB_SLOT5_BASE_ADDR	(MXC91231_AIPS1_BASE_ADDR + 0x14000)
-#define MXC91231_ECT_CTIO_BASE_ADDR	(MXC91231_AIPS1_BASE_ADDR + 0x18000)
-#define MXC91231_I2C_BASE_ADDR		(MXC91231_AIPS1_BASE_ADDR + 0x80000)
-#define MXC91231_MU_BASE_ADDR		(MXC91231_AIPS1_BASE_ADDR + 0x88000)
-#define MXC91231_UART1_BASE_ADDR	(MXC91231_AIPS1_BASE_ADDR + 0x90000)
-#define MXC91231_UART2_BASE_ADDR	(MXC91231_AIPS1_BASE_ADDR + 0x94000)
-#define MXC91231_DSM_BASE_ADDR		(MXC91231_AIPS1_BASE_ADDR + 0x98000)
-#define MXC91231_OWIRE_BASE_ADDR	(MXC91231_AIPS1_BASE_ADDR + 0x9C000)
-#define MXC91231_SSI1_BASE_ADDR		(MXC91231_AIPS1_BASE_ADDR + 0xA0000)
-#define MXC91231_KPP_BASE_ADDR		(MXC91231_AIPS1_BASE_ADDR + 0xA8000)
-#define MXC91231_IOMUX_AP_BASE_ADDR	(MXC91231_AIPS1_BASE_ADDR + 0xAC000)
-#define MXC91231_CTI_AP_BASE_ADDR	(MXC91231_AIPS1_BASE_ADDR + 0xB8000)
-
-/*
- * AIPS 2
- */
-#define MXC91231_AIPS2_BASE_ADDR	0x53F00000
-#define MXC91231_AIPS2_SIZE		SZ_1M
-
-#define MXC91231_GEMK_BASE_ADDR		(MXC91231_AIPS2_BASE_ADDR + 0x8C000)
-#define MXC91231_GPT1_BASE_ADDR		(MXC91231_AIPS2_BASE_ADDR + 0x90000)
-#define MXC91231_EPIT1_AP_BASE_ADDR	(MXC91231_AIPS2_BASE_ADDR + 0x94000)
-#define MXC91231_SCC_BASE_ADDR		(MXC91231_AIPS2_BASE_ADDR + 0xAC000)
-#define MXC91231_RNGA_BASE_ADDR		(MXC91231_AIPS2_BASE_ADDR + 0xB0000)
-#define MXC91231_IPU_CTRL_BASE_ADDR	(MXC91231_AIPS2_BASE_ADDR + 0xC0000)
-#define MXC91231_AUDMUX_BASE_ADDR	(MXC91231_AIPS2_BASE_ADDR + 0xC4000)
-#define MXC91231_EDIO_BASE_ADDR		(MXC91231_AIPS2_BASE_ADDR + 0xC8000)
-#define MXC91231_GPIO1_AP_BASE_ADDR	(MXC91231_AIPS2_BASE_ADDR + 0xCC000)
-#define MXC91231_GPIO2_AP_BASE_ADDR	(MXC91231_AIPS2_BASE_ADDR + 0xD0000)
-#define MXC91231_SDMA_BASE_ADDR		(MXC91231_AIPS2_BASE_ADDR + 0xD4000)
-#define MXC91231_RTC_BASE_ADDR		(MXC91231_AIPS2_BASE_ADDR + 0xD8000)
-#define MXC91231_WDOG1_BASE_ADDR	(MXC91231_AIPS2_BASE_ADDR + 0xDC000)
-#define MXC91231_PWM_BASE_ADDR		(MXC91231_AIPS2_BASE_ADDR + 0xE0000)
-#define MXC91231_GPIO3_AP_BASE_ADDR	(MXC91231_AIPS2_BASE_ADDR + 0xE4000)
-#define MXC91231_WDOG2_BASE_ADDR	(MXC91231_AIPS2_BASE_ADDR + 0xE8000)
-#define MXC91231_RTIC_BASE_ADDR		(MXC91231_AIPS2_BASE_ADDR + 0xEC000)
-#define MXC91231_LPMC_BASE_ADDR		(MXC91231_AIPS2_BASE_ADDR + 0xF0000)
-
-/*
- * SPBA global module 0
- */
-#define MXC91231_SPBA0_BASE_ADDR	0x50000000
-#define MXC91231_SPBA0_SIZE		SZ_1M
-
-#define MXC91231_MMC_SDHC1_BASE_ADDR	(MXC91231_SPBA0_BASE_ADDR + 0x04000)
-#define MXC91231_MMC_SDHC2_BASE_ADDR	(MXC91231_SPBA0_BASE_ADDR + 0x08000)
-#define MXC91231_UART3_BASE_ADDR	(MXC91231_SPBA0_BASE_ADDR + 0x0C000)
-#define MXC91231_CSPI2_BASE_ADDR	(MXC91231_SPBA0_BASE_ADDR + 0x10000)
-#define MXC91231_SSI2_BASE_ADDR		(MXC91231_SPBA0_BASE_ADDR + 0x14000)
-#define MXC91231_SIM_BASE_ADDR		(MXC91231_SPBA0_BASE_ADDR + 0x18000)
-#define MXC91231_IIM_BASE_ADDR		(MXC91231_SPBA0_BASE_ADDR + 0x1C000)
-#define MXC91231_CTI_SDMA_BASE_ADDR	(MXC91231_SPBA0_BASE_ADDR + 0x20000)
-#define MXC91231_USBOTG_CTRL_BASE_ADDR	(MXC91231_SPBA0_BASE_ADDR + 0x24000)
-#define MXC91231_USBOTG_DATA_BASE_ADDR	(MXC91231_SPBA0_BASE_ADDR + 0x28000)
-#define MXC91231_CSPI1_BASE_ADDR	(MXC91231_SPBA0_BASE_ADDR + 0x30000)
-#define MXC91231_SPBA_CTRL_BASE_ADDR	(MXC91231_SPBA0_BASE_ADDR + 0x3C000)
-#define MXC91231_IOMUX_COM_BASE_ADDR	(MXC91231_SPBA0_BASE_ADDR + 0x40000)
-#define MXC91231_CRM_COM_BASE_ADDR	(MXC91231_SPBA0_BASE_ADDR + 0x44000)
-#define MXC91231_CRM_AP_BASE_ADDR	(MXC91231_SPBA0_BASE_ADDR + 0x48000)
-#define MXC91231_PLL0_BASE_ADDR		(MXC91231_SPBA0_BASE_ADDR + 0x4C000)
-#define MXC91231_PLL1_BASE_ADDR		(MXC91231_SPBA0_BASE_ADDR + 0x50000)
-#define MXC91231_PLL2_BASE_ADDR		(MXC91231_SPBA0_BASE_ADDR + 0x54000)
-#define MXC91231_GPIO4_SH_BASE_ADDR	(MXC91231_SPBA0_BASE_ADDR + 0x58000)
-#define MXC91231_HAC_BASE_ADDR		(MXC91231_SPBA0_BASE_ADDR + 0x5C000)
-#define MXC91231_SAHARA_BASE_ADDR	(MXC91231_SPBA0_BASE_ADDR + 0x5C000)
-#define MXC91231_PLL3_BASE_ADDR		(MXC91231_SPBA0_BASE_ADDR + 0x60000)
-
-/*
- * SPBA global module 1
- */
-#define MXC91231_SPBA1_BASE_ADDR	0x52000000
-#define MXC91231_SPBA1_SIZE		SZ_1M
-
-#define MXC91231_MQSPI_BASE_ADDR	(MXC91231_SPBA1_BASE_ADDR + 0x34000)
-#define MXC91231_EL1T_BASE_ADDR		(MXC91231_SPBA1_BASE_ADDR + 0x38000)
-
-/*!
- * Defines for SPBA modules
- */
-#define MXC91231_SPBA_SDHC1		0x04
-#define MXC91231_SPBA_SDHC2		0x08
-#define MXC91231_SPBA_UART3		0x0C
-#define MXC91231_SPBA_CSPI2		0x10
-#define MXC91231_SPBA_SSI2		0x14
-#define MXC91231_SPBA_SIM		0x18
-#define MXC91231_SPBA_IIM		0x1C
-#define MXC91231_SPBA_CTI_SDMA		0x20
-#define MXC91231_SPBA_USBOTG_CTRL_REGS	0x24
-#define MXC91231_SPBA_USBOTG_DATA_REGS	0x28
-#define MXC91231_SPBA_CSPI1		0x30
-#define MXC91231_SPBA_MQSPI		0x34
-#define MXC91231_SPBA_EL1T		0x38
-#define MXC91231_SPBA_IOMUX		0x40
-#define MXC91231_SPBA_CRM_COM		0x44
-#define MXC91231_SPBA_CRM_AP		0x48
-#define MXC91231_SPBA_PLL0		0x4C
-#define MXC91231_SPBA_PLL1		0x50
-#define MXC91231_SPBA_PLL2		0x54
-#define MXC91231_SPBA_GPIO4		0x58
-#define MXC91231_SPBA_SAHARA		0x5C
-
-/*
- * ROMP and AVIC
- */
-#define MXC91231_ROMP_BASE_ADDR		0x60000000
-#define MXC91231_ROMP_SIZE		SZ_64K
-
-#define MXC91231_AVIC_BASE_ADDR		0x68000000
-#define MXC91231_AVIC_SIZE		SZ_64K
-
-/*
- * NAND, SDRAM, WEIM, M3IF, EMI controllers
- */
-#define MXC91231_X_MEMC_BASE_ADDR	0xB8000000
-#define MXC91231_X_MEMC_SIZE		SZ_64K
-
-#define MXC91231_NFC_BASE_ADDR		(MXC91231_X_MEMC_BASE_ADDR + 0x0000)
-#define MXC91231_ESDCTL_BASE_ADDR	(MXC91231_X_MEMC_BASE_ADDR + 0x1000)
-#define MXC91231_WEIM_BASE_ADDR		(MXC91231_X_MEMC_BASE_ADDR + 0x2000)
-#define MXC91231_M3IF_BASE_ADDR		(MXC91231_X_MEMC_BASE_ADDR + 0x3000)
-#define MXC91231_EMI_CTL_BASE_ADDR	(MXC91231_X_MEMC_BASE_ADDR + 0x4000)
-
-/*
- * Memory regions and CS
- * CPLD is connected on CS4
- * CS5 is TP1021 or it is not connected
- * */
-#define MXC91231_FB_RAM_BASE_ADDR	0x78000000
-#define MXC91231_FB_RAM_SIZE		SZ_256K
-#define MXC91231_CSD0_BASE_ADDR		0x80000000
-#define MXC91231_CSD1_BASE_ADDR		0x90000000
-#define MXC91231_CS0_BASE_ADDR		0xA0000000
-#define MXC91231_CS1_BASE_ADDR		0xA8000000
-#define MXC91231_CS2_BASE_ADDR		0xB0000000
-#define MXC91231_CS3_BASE_ADDR		0xB2000000
-#define MXC91231_CS4_BASE_ADDR		0xB4000000
-#define MXC91231_CS5_BASE_ADDR		0xB6000000
-
-/*
- * 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.
- */
-#define MXC91231_IO_P2V(x)		IMX_IO_P2V(x)
-#define MXC91231_IO_ADDRESS(x)		IOMEM(MXC91231_IO_P2V(x))
-
-/*
- * Interrupt numbers
- */
-#define MXC91231_INT_GPIO3		0
-#define MXC91231_INT_EL1T_CI		1
-#define MXC91231_INT_EL1T_RFCI		2
-#define MXC91231_INT_EL1T_RFI		3
-#define MXC91231_INT_EL1T_MCU		4
-#define MXC91231_INT_EL1T_IPI		5
-#define MXC91231_INT_MU_GEN		6
-#define MXC91231_INT_GPIO4		7
-#define MXC91231_INT_MMC_SDHC2		8
-#define MXC91231_INT_MMC_SDHC1		9
-#define MXC91231_INT_I2C		10
-#define MXC91231_INT_SSI2		11
-#define MXC91231_INT_SSI1		12
-#define MXC91231_INT_CSPI2		13
-#define MXC91231_INT_CSPI1		14
-#define MXC91231_INT_RTIC		15
-#define MXC91231_INT_SAHARA		15
-#define MXC91231_INT_HAC		15
-#define MXC91231_INT_UART3_RX		16
-#define MXC91231_INT_UART3_TX		17
-#define MXC91231_INT_UART3_MINT		18
-#define MXC91231_INT_ECT		19
-#define MXC91231_INT_SIM_IPB		20
-#define MXC91231_INT_SIM_DATA		21
-#define MXC91231_INT_RNGA		22
-#define MXC91231_INT_DSM_AP		23
-#define MXC91231_INT_KPP		24
-#define MXC91231_INT_RTC		25
-#define MXC91231_INT_PWM		26
-#define MXC91231_INT_GEMK_AP		27
-#define MXC91231_INT_EPIT		28
-#define MXC91231_INT_GPT		29
-#define MXC91231_INT_UART2_RX		30
-#define MXC91231_INT_UART2_TX		31
-#define MXC91231_INT_UART2_MINT		32
-#define MXC91231_INT_NANDFC		33
-#define MXC91231_INT_SDMA		34
-#define MXC91231_INT_USB_WAKEUP		35
-#define MXC91231_INT_USB_SOF		36
-#define MXC91231_INT_PMU_EVTMON		37
-#define MXC91231_INT_USB_FUNC		38
-#define MXC91231_INT_USB_DMA		39
-#define MXC91231_INT_USB_CTRL		40
-#define MXC91231_INT_IPU_ERR		41
-#define MXC91231_INT_IPU_SYN		42
-#define MXC91231_INT_UART1_RX		43
-#define MXC91231_INT_UART1_TX		44
-#define MXC91231_INT_UART1_MINT		45
-#define MXC91231_INT_IIM		46
-#define MXC91231_INT_MU_RX_OR		47
-#define MXC91231_INT_MU_TX_OR		48
-#define MXC91231_INT_SCC_SCM		49
-#define MXC91231_INT_SCC_SMN		50
-#define MXC91231_INT_GPIO2		51
-#define MXC91231_INT_GPIO1		52
-#define MXC91231_INT_MQSPI1		53
-#define MXC91231_INT_MQSPI2		54
-#define MXC91231_INT_WDOG2		55
-#define MXC91231_INT_EXT_INT7		56
-#define MXC91231_INT_EXT_INT6		57
-#define MXC91231_INT_EXT_INT5		58
-#define MXC91231_INT_EXT_INT4		59
-#define MXC91231_INT_EXT_INT3		60
-#define MXC91231_INT_EXT_INT2		61
-#define MXC91231_INT_EXT_INT1		62
-#define MXC91231_INT_EXT_INT0		63
-
-#define MXC91231_MAX_INT_LINES		63
-#define MXC91231_MAX_EXT_LINES		8
-
-#endif /* __MACH_MXC91231_H__ */
diff -druN linux-2.6.39-libre/arch/arm/plat-mxc/include/mach/mxc.h linux-3.0-rc7-libre/arch/arm/plat-mxc/include/mach/mxc.h
--- linux-2.6.39-libre/arch/arm/plat-mxc/include/mach/mxc.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/plat-mxc/include/mach/mxc.h	2011-07-11 19:51:52.000000000 -0400
@@ -35,7 +35,6 @@
 #define MXC_CPU_MX50		50
 #define MXC_CPU_MX51		51
 #define MXC_CPU_MX53		53
-#define MXC_CPU_MXC91231	91231
 
 #define IMX_CHIP_REVISION_1_0		0x10
 #define IMX_CHIP_REVISION_1_1		0x11
@@ -177,18 +176,6 @@
 # define cpu_is_mx53()		(0)
 #endif
 
-#ifdef CONFIG_ARCH_MXC91231
-# ifdef mxc_cpu_type
-#  undef mxc_cpu_type
-#  define mxc_cpu_type __mxc_cpu_type
-# else
-#  define mxc_cpu_type MXC_CPU_MXC91231
-# endif
-# define cpu_is_mxc91231()	(mxc_cpu_type == MXC_CPU_MXC91231)
-#else
-# define cpu_is_mxc91231()	(0)
-#endif
-
 #ifndef __ASSEMBLY__
 
 struct cpu_op {
@@ -207,14 +194,7 @@
 extern struct cpu_op *(*get_cpu_op)(int *op);
 #endif
 
-#if defined(CONFIG_ARCH_MX3) || defined(CONFIG_ARCH_MX2)
-/* 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())
+#define cpu_is_mx3()	(cpu_is_mx31() || cpu_is_mx35())
 #define cpu_is_mx2()	(cpu_is_mx21() || cpu_is_mx27())
 
 #endif /*  __ASM_ARCH_MXC_H__ */
diff -druN linux-2.6.39-libre/arch/arm/plat-mxc/include/mach/system.h linux-3.0-rc7-libre/arch/arm/plat-mxc/include/mach/system.h
--- linux-2.6.39-libre/arch/arm/plat-mxc/include/mach/system.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/plat-mxc/include/mach/system.h	2011-07-11 19:51:52.000000000 -0400
@@ -24,12 +24,6 @@
 
 static inline void arch_idle(void)
 {
-#ifdef CONFIG_ARCH_MXC91231
-	if (cpu_is_mxc91231()) {
-		/* Need this to set DSM low-power mode */
-		mxc91231_prepare_idle();
-	}
-#endif
 	/* fix i.MX31 errata TLSbo65953 and i.MX35 errata ENGcm09472 */
 	if (cpu_is_mx31() || cpu_is_mx35()) {
 		unsigned long reg = 0;
diff -druN linux-2.6.39-libre/arch/arm/plat-mxc/include/mach/timex.h linux-3.0-rc7-libre/arch/arm/plat-mxc/include/mach/timex.h
--- linux-2.6.39-libre/arch/arm/plat-mxc/include/mach/timex.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/plat-mxc/include/mach/timex.h	2011-07-11 19:51:52.000000000 -0400
@@ -26,8 +26,6 @@
 #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
 
 #endif				/* __ASM_ARCH_MXC_TIMEX_H__ */
diff -druN linux-2.6.39-libre/arch/arm/plat-mxc/include/mach/uncompress.h linux-3.0-rc7-libre/arch/arm/plat-mxc/include/mach/uncompress.h
--- linux-2.6.39-libre/arch/arm/plat-mxc/include/mach/uncompress.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/plat-mxc/include/mach/uncompress.h	2011-07-11 19:51:52.000000000 -0400
@@ -21,7 +21,7 @@
 
 #include <asm/mach-types.h>
 
-static unsigned long uart_base;
+unsigned long uart_base;
 
 #define UART(x) (*(volatile unsigned long *)(uart_base + (x)))
 
diff -druN linux-2.6.39-libre/arch/arm/plat-mxc/Kconfig linux-3.0-rc7-libre/arch/arm/plat-mxc/Kconfig
--- linux-2.6.39-libre/arch/arm/plat-mxc/Kconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/plat-mxc/Kconfig	2011-07-11 19:51:52.000000000 -0400
@@ -4,13 +4,18 @@
 
 menu "Freescale MXC Implementations"
 
+config ARCH_MX50_SUPPORTED
+	bool
+
+config ARCH_MX53_SUPPORTED
+	bool
+
 choice
 	prompt "Freescale CPU family:"
 	default ARCH_MX3
 
 config ARCH_MX1
 	bool "MX1-based"
-	select SOC_IMX1
 	help
 	  This enables support for systems based on the Freescale i.MX1 family
 
@@ -26,29 +31,26 @@
 
 config ARCH_MX3
 	bool "MX3-based"
-	select CPU_V6
 	help
 	  This enables support for systems based on the Freescale i.MX3 family
 
-config ARCH_MXC91231
-	bool "MXC91231-based"
-	select CPU_V6
-	select MXC_AVIC
+config ARCH_MX503
+	bool "i.MX50 + i.MX53"
+	select ARCH_MX50_SUPPORTED
+	select ARCH_MX53_SUPPORTED
 	help
-	  This enables support for systems based on the Freescale MXC91231 family
+	  This enables support for machines using Freescale's i.MX50 and i.MX51
+	  processors.
 
-config ARCH_MX5
-	bool "MX5-based"
-	select CPU_V7
-	select ARM_L1_CACHE_SHIFT_6
+config ARCH_MX51
+	bool "i.MX51"
+	select ARCH_MX51_SUPPORTED
 	help
 	  This enables support for systems based on the Freescale i.MX51 family
 
 endchoice
 
 source "arch/arm/mach-imx/Kconfig"
-source "arch/arm/mach-mx3/Kconfig"
-source "arch/arm/mach-mxc91231/Kconfig"
 source "arch/arm/mach-mx5/Kconfig"
 
 endmenu
diff -druN linux-2.6.39-libre/arch/arm/plat-mxc/system.c linux-3.0-rc7-libre/arch/arm/plat-mxc/system.c
--- linux-2.6.39-libre/arch/arm/plat-mxc/system.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/plat-mxc/system.c	2011-07-11 19:51:52.000000000 -0400
@@ -37,12 +37,6 @@
 {
 	unsigned int wcr_enable;
 
-#ifdef CONFIG_ARCH_MXC91231
-	if (cpu_is_mxc91231()) {
-		mxc91231_arch_reset(mode, cmd);
-		return;
-	}
-#endif
 #ifdef CONFIG_MACH_MX51_EFIKAMX
 	if (machine_is_mx51_efikamx()) {
 		mx51_efikamx_reset();
diff -druN linux-2.6.39-libre/arch/arm/plat-mxc/time.c linux-3.0-rc7-libre/arch/arm/plat-mxc/time.c
--- linux-2.6.39-libre/arch/arm/plat-mxc/time.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/plat-mxc/time.c	2011-07-11 19:51:52.000000000 -0400
@@ -54,7 +54,7 @@
 #define MX2_TSTAT_CAPT		(1 << 1)
 #define MX2_TSTAT_COMP		(1 << 0)
 
-/* MX31, MX35, MX25, MXC91231, MX5 */
+/* MX31, MX35, MX25, MX5 */
 #define V2_TCTL_WAITEN		(1 << 3) /* Wait enable mode */
 #define V2_TCTL_CLK_IPG		(1 << 6)
 #define V2_TCTL_FRR		(1 << 9)
@@ -106,56 +106,32 @@
 		__raw_writel(V2_TSTAT_OF1, timer_base + V2_TSTAT);
 }
 
-static cycle_t dummy_get_cycles(struct clocksource *cs)
-{
-	return 0;
-}
-
-static cycle_t mx1_2_get_cycles(struct clocksource *cs)
-{
-	return __raw_readl(timer_base + MX1_2_TCN);
-}
-
-static cycle_t v2_get_cycles(struct clocksource *cs)
-{
-	return __raw_readl(timer_base + V2_TCN);
-}
-
-static struct clocksource clocksource_mxc = {
-	.name 		= "mxc_timer1",
-	.rating		= 200,
-	.read		= dummy_get_cycles,
-	.mask		= CLOCKSOURCE_MASK(32),
-	.flags		= CLOCK_SOURCE_IS_CONTINUOUS,
-};
+static void __iomem *sched_clock_reg;
 
 static DEFINE_CLOCK_DATA(cd);
 unsigned long long notrace sched_clock(void)
 {
-	cycle_t cyc = clocksource_mxc.read(&clocksource_mxc);
+	cycle_t cyc = sched_clock_reg ? __raw_readl(sched_clock_reg) : 0;
 
 	return cyc_to_sched_clock(&cd, cyc, (u32)~0);
 }
 
 static void notrace mxc_update_sched_clock(void)
 {
-	cycle_t cyc = clocksource_mxc.read(&clocksource_mxc);
+	cycle_t cyc = sched_clock_reg ? __raw_readl(sched_clock_reg) : 0;
 	update_sched_clock(&cd, cyc, (u32)~0);
 }
 
 static int __init mxc_clocksource_init(struct clk *timer_clk)
 {
 	unsigned int c = clk_get_rate(timer_clk);
+	void __iomem *reg = timer_base + (timer_is_v2() ? V2_TCN : MX1_2_TCN);
 
-	if (timer_is_v2())
-		clocksource_mxc.read = v2_get_cycles;
-	else
-		clocksource_mxc.read = mx1_2_get_cycles;
+	sched_clock_reg = reg;
 
 	init_sched_clock(&cd, mxc_update_sched_clock, 32, c);
-	clocksource_register_hz(&clocksource_mxc, c);
-
-	return 0;
+	return clocksource_mmio_init(reg, "mxc_timer1", c, 200, 32,
+			clocksource_mmio_readl_up);
 }
 
 /* clock event */
diff -druN linux-2.6.39-libre/arch/arm/plat-nomadik/gpio.c linux-3.0-rc7-libre/arch/arm/plat-nomadik/gpio.c
--- linux-2.6.39-libre/arch/arm/plat-nomadik/gpio.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/plat-nomadik/gpio.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,1024 +0,0 @@
-/*
- * Generic GPIO driver for logic cells found in the Nomadik SoC
- *
- * Copyright (C) 2008,2009 STMicroelectronics
- * Copyright (C) 2009 Alessandro Rubini <rubini@unipv.it>
- *   Rewritten based on work by Prafulla WADASKAR <prafulla.wadaskar@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/kernel.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/device.h>
-#include <linux/platform_device.h>
-#include <linux/io.h>
-#include <linux/clk.h>
-#include <linux/err.h>
-#include <linux/gpio.h>
-#include <linux/spinlock.h>
-#include <linux/interrupt.h>
-#include <linux/irq.h>
-#include <linux/slab.h>
-
-#include <plat/pincfg.h>
-#include <mach/hardware.h>
-#include <mach/gpio.h>
-
-/*
- * The GPIO module in the Nomadik family of Systems-on-Chip is an
- * AMBA device, managing 32 pins and alternate functions.  The logic block
- * is currently used in the Nomadik and ux500.
- *
- * Symbols in this file are called "nmk_gpio" for "nomadik gpio"
- */
-
-#define NMK_GPIO_PER_CHIP	32
-
-struct nmk_gpio_chip {
-	struct gpio_chip chip;
-	void __iomem *addr;
-	struct clk *clk;
-	unsigned int bank;
-	unsigned int parent_irq;
-	int secondary_parent_irq;
-	u32 (*get_secondary_status)(unsigned int bank);
-	void (*set_ioforce)(bool enable);
-	spinlock_t lock;
-	/* Keep track of configured edges */
-	u32 edge_rising;
-	u32 edge_falling;
-	u32 real_wake;
-	u32 rwimsc;
-	u32 fwimsc;
-	u32 slpm;
-	u32 enabled;
-};
-
-static struct nmk_gpio_chip *
-nmk_gpio_chips[DIV_ROUND_UP(ARCH_NR_GPIOS, NMK_GPIO_PER_CHIP)];
-
-static DEFINE_SPINLOCK(nmk_gpio_slpm_lock);
-
-#define NUM_BANKS ARRAY_SIZE(nmk_gpio_chips)
-
-static void __nmk_gpio_set_mode(struct nmk_gpio_chip *nmk_chip,
-				unsigned offset, int gpio_mode)
-{
-	u32 bit = 1 << offset;
-	u32 afunc, bfunc;
-
-	afunc = readl(nmk_chip->addr + NMK_GPIO_AFSLA) & ~bit;
-	bfunc = readl(nmk_chip->addr + NMK_GPIO_AFSLB) & ~bit;
-	if (gpio_mode & NMK_GPIO_ALT_A)
-		afunc |= bit;
-	if (gpio_mode & NMK_GPIO_ALT_B)
-		bfunc |= bit;
-	writel(afunc, nmk_chip->addr + NMK_GPIO_AFSLA);
-	writel(bfunc, nmk_chip->addr + NMK_GPIO_AFSLB);
-}
-
-static void __nmk_gpio_set_slpm(struct nmk_gpio_chip *nmk_chip,
-				unsigned offset, enum nmk_gpio_slpm mode)
-{
-	u32 bit = 1 << offset;
-	u32 slpm;
-
-	slpm = readl(nmk_chip->addr + NMK_GPIO_SLPC);
-	if (mode == NMK_GPIO_SLPM_NOCHANGE)
-		slpm |= bit;
-	else
-		slpm &= ~bit;
-	writel(slpm, nmk_chip->addr + NMK_GPIO_SLPC);
-}
-
-static void __nmk_gpio_set_pull(struct nmk_gpio_chip *nmk_chip,
-				unsigned offset, enum nmk_gpio_pull pull)
-{
-	u32 bit = 1 << offset;
-	u32 pdis;
-
-	pdis = readl(nmk_chip->addr + NMK_GPIO_PDIS);
-	if (pull == NMK_GPIO_PULL_NONE)
-		pdis |= bit;
-	else
-		pdis &= ~bit;
-	writel(pdis, nmk_chip->addr + NMK_GPIO_PDIS);
-
-	if (pull == NMK_GPIO_PULL_UP)
-		writel(bit, nmk_chip->addr + NMK_GPIO_DATS);
-	else if (pull == NMK_GPIO_PULL_DOWN)
-		writel(bit, nmk_chip->addr + NMK_GPIO_DATC);
-}
-
-static void __nmk_gpio_make_input(struct nmk_gpio_chip *nmk_chip,
-				  unsigned offset)
-{
-	writel(1 << offset, nmk_chip->addr + NMK_GPIO_DIRC);
-}
-
-static void __nmk_gpio_set_output(struct nmk_gpio_chip *nmk_chip,
-				  unsigned offset, int val)
-{
-	if (val)
-		writel(1 << offset, nmk_chip->addr + NMK_GPIO_DATS);
-	else
-		writel(1 << offset, nmk_chip->addr + NMK_GPIO_DATC);
-}
-
-static void __nmk_gpio_make_output(struct nmk_gpio_chip *nmk_chip,
-				  unsigned offset, int val)
-{
-	writel(1 << offset, nmk_chip->addr + NMK_GPIO_DIRS);
-	__nmk_gpio_set_output(nmk_chip, offset, val);
-}
-
-static void __nmk_gpio_set_mode_safe(struct nmk_gpio_chip *nmk_chip,
-				     unsigned offset, int gpio_mode,
-				     bool glitch)
-{
-	u32 rwimsc = readl(nmk_chip->addr + NMK_GPIO_RWIMSC);
-	u32 fwimsc = readl(nmk_chip->addr + NMK_GPIO_FWIMSC);
-
-	if (glitch && nmk_chip->set_ioforce) {
-		u32 bit = BIT(offset);
-
-		/* Prevent spurious wakeups */
-		writel(rwimsc & ~bit, nmk_chip->addr + NMK_GPIO_RWIMSC);
-		writel(fwimsc & ~bit, nmk_chip->addr + NMK_GPIO_FWIMSC);
-
-		nmk_chip->set_ioforce(true);
-	}
-
-	__nmk_gpio_set_mode(nmk_chip, offset, gpio_mode);
-
-	if (glitch && nmk_chip->set_ioforce) {
-		nmk_chip->set_ioforce(false);
-
-		writel(rwimsc, nmk_chip->addr + NMK_GPIO_RWIMSC);
-		writel(fwimsc, nmk_chip->addr + NMK_GPIO_FWIMSC);
-	}
-}
-
-static void __nmk_config_pin(struct nmk_gpio_chip *nmk_chip, unsigned offset,
-			     pin_cfg_t cfg, bool sleep, unsigned int *slpmregs)
-{
-	static const char *afnames[] = {
-		[NMK_GPIO_ALT_GPIO]	= "GPIO",
-		[NMK_GPIO_ALT_A]	= "A",
-		[NMK_GPIO_ALT_B]	= "B",
-		[NMK_GPIO_ALT_C]	= "C"
-	};
-	static const char *pullnames[] = {
-		[NMK_GPIO_PULL_NONE]	= "none",
-		[NMK_GPIO_PULL_UP]	= "up",
-		[NMK_GPIO_PULL_DOWN]	= "down",
-		[3] /* illegal */	= "??"
-	};
-	static const char *slpmnames[] = {
-		[NMK_GPIO_SLPM_INPUT]		= "input/wakeup",
-		[NMK_GPIO_SLPM_NOCHANGE]	= "no-change/no-wakeup",
-	};
-
-	int pin = PIN_NUM(cfg);
-	int pull = PIN_PULL(cfg);
-	int af = PIN_ALT(cfg);
-	int slpm = PIN_SLPM(cfg);
-	int output = PIN_DIR(cfg);
-	int val = PIN_VAL(cfg);
-	bool glitch = af == NMK_GPIO_ALT_C;
-
-	dev_dbg(nmk_chip->chip.dev, "pin %d [%#lx]: af %s, pull %s, slpm %s (%s%s)\n",
-		pin, cfg, afnames[af], pullnames[pull], slpmnames[slpm],
-		output ? "output " : "input",
-		output ? (val ? "high" : "low") : "");
-
-	if (sleep) {
-		int slpm_pull = PIN_SLPM_PULL(cfg);
-		int slpm_output = PIN_SLPM_DIR(cfg);
-		int slpm_val = PIN_SLPM_VAL(cfg);
-
-		af = NMK_GPIO_ALT_GPIO;
-
-		/*
-		 * The SLPM_* values are normal values + 1 to allow zero to
-		 * mean "same as normal".
-		 */
-		if (slpm_pull)
-			pull = slpm_pull - 1;
-		if (slpm_output)
-			output = slpm_output - 1;
-		if (slpm_val)
-			val = slpm_val - 1;
-
-		dev_dbg(nmk_chip->chip.dev, "pin %d: sleep pull %s, dir %s, val %s\n",
-			pin,
-			slpm_pull ? pullnames[pull] : "same",
-			slpm_output ? (output ? "output" : "input") : "same",
-			slpm_val ? (val ? "high" : "low") : "same");
-	}
-
-	if (output)
-		__nmk_gpio_make_output(nmk_chip, offset, val);
-	else {
-		__nmk_gpio_make_input(nmk_chip, offset);
-		__nmk_gpio_set_pull(nmk_chip, offset, pull);
-	}
-
-	/*
-	 * If we've backed up the SLPM registers (glitch workaround), modify
-	 * the backups since they will be restored.
-	 */
-	if (slpmregs) {
-		if (slpm == NMK_GPIO_SLPM_NOCHANGE)
-			slpmregs[nmk_chip->bank] |= BIT(offset);
-		else
-			slpmregs[nmk_chip->bank] &= ~BIT(offset);
-	} else
-		__nmk_gpio_set_slpm(nmk_chip, offset, slpm);
-
-	__nmk_gpio_set_mode_safe(nmk_chip, offset, af, glitch);
-}
-
-/*
- * Safe sequence used to switch IOs between GPIO and Alternate-C mode:
- *  - Save SLPM registers
- *  - Set SLPM=0 for the IOs you want to switch and others to 1
- *  - Configure the GPIO registers for the IOs that are being switched
- *  - Set IOFORCE=1
- *  - Modify the AFLSA/B registers for the IOs that are being switched
- *  - Set IOFORCE=0
- *  - Restore SLPM registers
- *  - Any spurious wake up event during switch sequence to be ignored and
- *    cleared
- */
-static void nmk_gpio_glitch_slpm_init(unsigned int *slpm)
-{
-	int i;
-
-	for (i = 0; i < NUM_BANKS; i++) {
-		struct nmk_gpio_chip *chip = nmk_gpio_chips[i];
-		unsigned int temp = slpm[i];
-
-		if (!chip)
-			break;
-
-		slpm[i] = readl(chip->addr + NMK_GPIO_SLPC);
-		writel(temp, chip->addr + NMK_GPIO_SLPC);
-	}
-}
-
-static void nmk_gpio_glitch_slpm_restore(unsigned int *slpm)
-{
-	int i;
-
-	for (i = 0; i < NUM_BANKS; i++) {
-		struct nmk_gpio_chip *chip = nmk_gpio_chips[i];
-
-		if (!chip)
-			break;
-
-		writel(slpm[i], chip->addr + NMK_GPIO_SLPC);
-	}
-}
-
-static int __nmk_config_pins(pin_cfg_t *cfgs, int num, bool sleep)
-{
-	static unsigned int slpm[NUM_BANKS];
-	unsigned long flags;
-	bool glitch = false;
-	int ret = 0;
-	int i;
-
-	for (i = 0; i < num; i++) {
-		if (PIN_ALT(cfgs[i]) == NMK_GPIO_ALT_C) {
-			glitch = true;
-			break;
-		}
-	}
-
-	spin_lock_irqsave(&nmk_gpio_slpm_lock, flags);
-
-	if (glitch) {
-		memset(slpm, 0xff, sizeof(slpm));
-
-		for (i = 0; i < num; i++) {
-			int pin = PIN_NUM(cfgs[i]);
-			int offset = pin % NMK_GPIO_PER_CHIP;
-
-			if (PIN_ALT(cfgs[i]) == NMK_GPIO_ALT_C)
-				slpm[pin / NMK_GPIO_PER_CHIP] &= ~BIT(offset);
-		}
-
-		nmk_gpio_glitch_slpm_init(slpm);
-	}
-
-	for (i = 0; i < num; i++) {
-		struct nmk_gpio_chip *nmk_chip;
-		int pin = PIN_NUM(cfgs[i]);
-
-		nmk_chip = irq_get_chip_data(NOMADIK_GPIO_TO_IRQ(pin));
-		if (!nmk_chip) {
-			ret = -EINVAL;
-			break;
-		}
-
-		spin_lock(&nmk_chip->lock);
-		__nmk_config_pin(nmk_chip, pin - nmk_chip->chip.base,
-				 cfgs[i], sleep, glitch ? slpm : NULL);
-		spin_unlock(&nmk_chip->lock);
-	}
-
-	if (glitch)
-		nmk_gpio_glitch_slpm_restore(slpm);
-
-	spin_unlock_irqrestore(&nmk_gpio_slpm_lock, flags);
-
-	return ret;
-}
-
-/**
- * nmk_config_pin - configure a pin's mux attributes
- * @cfg: pin confguration
- *
- * Configures a pin's mode (alternate function or GPIO), its pull up status,
- * and its sleep mode based on the specified configuration.  The @cfg is
- * usually one of the SoC specific macros defined in mach/<soc>-pins.h.  These
- * are constructed using, and can be further enhanced with, the macros in
- * plat/pincfg.h.
- *
- * If a pin's mode is set to GPIO, it is configured as an input to avoid
- * side-effects.  The gpio can be manipulated later using standard GPIO API
- * calls.
- */
-int nmk_config_pin(pin_cfg_t cfg, bool sleep)
-{
-	return __nmk_config_pins(&cfg, 1, sleep);
-}
-EXPORT_SYMBOL(nmk_config_pin);
-
-/**
- * nmk_config_pins - configure several pins at once
- * @cfgs: array of pin configurations
- * @num: number of elments in the array
- *
- * Configures several pins using nmk_config_pin().  Refer to that function for
- * further information.
- */
-int nmk_config_pins(pin_cfg_t *cfgs, int num)
-{
-	return __nmk_config_pins(cfgs, num, false);
-}
-EXPORT_SYMBOL(nmk_config_pins);
-
-int nmk_config_pins_sleep(pin_cfg_t *cfgs, int num)
-{
-	return __nmk_config_pins(cfgs, num, true);
-}
-EXPORT_SYMBOL(nmk_config_pins_sleep);
-
-/**
- * nmk_gpio_set_slpm() - configure the sleep mode of a pin
- * @gpio: pin number
- * @mode: NMK_GPIO_SLPM_INPUT or NMK_GPIO_SLPM_NOCHANGE,
- *
- * Sets the sleep mode of a pin.  If @mode is NMK_GPIO_SLPM_INPUT, the pin is
- * changed to an input (with pullup/down enabled) in sleep and deep sleep.  If
- * @mode is NMK_GPIO_SLPM_NOCHANGE, the pin remains in the state it was
- * configured even when in sleep and deep sleep.
- *
- * On DB8500v2 onwards, this setting loses the previous meaning and instead
- * indicates if wakeup detection is enabled on the pin.  Note that
- * enable_irq_wake() will automatically enable wakeup detection.
- */
-int nmk_gpio_set_slpm(int gpio, enum nmk_gpio_slpm mode)
-{
-	struct nmk_gpio_chip *nmk_chip;
-	unsigned long flags;
-
-	nmk_chip = irq_get_chip_data(NOMADIK_GPIO_TO_IRQ(gpio));
-	if (!nmk_chip)
-		return -EINVAL;
-
-	spin_lock_irqsave(&nmk_gpio_slpm_lock, flags);
-	spin_lock(&nmk_chip->lock);
-
-	__nmk_gpio_set_slpm(nmk_chip, gpio - nmk_chip->chip.base, mode);
-
-	spin_unlock(&nmk_chip->lock);
-	spin_unlock_irqrestore(&nmk_gpio_slpm_lock, flags);
-
-	return 0;
-}
-
-/**
- * nmk_gpio_set_pull() - enable/disable pull up/down on a gpio
- * @gpio: pin number
- * @pull: one of NMK_GPIO_PULL_DOWN, NMK_GPIO_PULL_UP, and NMK_GPIO_PULL_NONE
- *
- * Enables/disables pull up/down on a specified pin.  This only takes effect if
- * the pin is configured as an input (either explicitly or by the alternate
- * function).
- *
- * NOTE: If enabling the pull up/down, the caller must ensure that the GPIO is
- * configured as an input.  Otherwise, due to the way the controller registers
- * work, this function will change the value output on the pin.
- */
-int nmk_gpio_set_pull(int gpio, enum nmk_gpio_pull pull)
-{
-	struct nmk_gpio_chip *nmk_chip;
-	unsigned long flags;
-
-	nmk_chip = irq_get_chip_data(NOMADIK_GPIO_TO_IRQ(gpio));
-	if (!nmk_chip)
-		return -EINVAL;
-
-	spin_lock_irqsave(&nmk_chip->lock, flags);
-	__nmk_gpio_set_pull(nmk_chip, gpio - nmk_chip->chip.base, pull);
-	spin_unlock_irqrestore(&nmk_chip->lock, flags);
-
-	return 0;
-}
-
-/* Mode functions */
-/**
- * nmk_gpio_set_mode() - set the mux mode of a gpio pin
- * @gpio: pin number
- * @gpio_mode: one of NMK_GPIO_ALT_GPIO, NMK_GPIO_ALT_A,
- *	       NMK_GPIO_ALT_B, and NMK_GPIO_ALT_C
- *
- * Sets the mode of the specified pin to one of the alternate functions or
- * plain GPIO.
- */
-int nmk_gpio_set_mode(int gpio, int gpio_mode)
-{
-	struct nmk_gpio_chip *nmk_chip;
-	unsigned long flags;
-
-	nmk_chip = irq_get_chip_data(NOMADIK_GPIO_TO_IRQ(gpio));
-	if (!nmk_chip)
-		return -EINVAL;
-
-	spin_lock_irqsave(&nmk_chip->lock, flags);
-	__nmk_gpio_set_mode(nmk_chip, gpio - nmk_chip->chip.base, gpio_mode);
-	spin_unlock_irqrestore(&nmk_chip->lock, flags);
-
-	return 0;
-}
-EXPORT_SYMBOL(nmk_gpio_set_mode);
-
-int nmk_gpio_get_mode(int gpio)
-{
-	struct nmk_gpio_chip *nmk_chip;
-	u32 afunc, bfunc, bit;
-
-	nmk_chip = irq_get_chip_data(NOMADIK_GPIO_TO_IRQ(gpio));
-	if (!nmk_chip)
-		return -EINVAL;
-
-	bit = 1 << (gpio - nmk_chip->chip.base);
-
-	afunc = readl(nmk_chip->addr + NMK_GPIO_AFSLA) & bit;
-	bfunc = readl(nmk_chip->addr + NMK_GPIO_AFSLB) & bit;
-
-	return (afunc ? NMK_GPIO_ALT_A : 0) | (bfunc ? NMK_GPIO_ALT_B : 0);
-}
-EXPORT_SYMBOL(nmk_gpio_get_mode);
-
-
-/* IRQ functions */
-static inline int nmk_gpio_get_bitmask(int gpio)
-{
-	return 1 << (gpio % 32);
-}
-
-static void nmk_gpio_irq_ack(struct irq_data *d)
-{
-	int gpio;
-	struct nmk_gpio_chip *nmk_chip;
-
-	gpio = NOMADIK_IRQ_TO_GPIO(d->irq);
-	nmk_chip = irq_data_get_irq_chip_data(d);
-	if (!nmk_chip)
-		return;
-	writel(nmk_gpio_get_bitmask(gpio), nmk_chip->addr + NMK_GPIO_IC);
-}
-
-enum nmk_gpio_irq_type {
-	NORMAL,
-	WAKE,
-};
-
-static void __nmk_gpio_irq_modify(struct nmk_gpio_chip *nmk_chip,
-				  int gpio, enum nmk_gpio_irq_type which,
-				  bool enable)
-{
-	u32 rimsc = which == WAKE ? NMK_GPIO_RWIMSC : NMK_GPIO_RIMSC;
-	u32 fimsc = which == WAKE ? NMK_GPIO_FWIMSC : NMK_GPIO_FIMSC;
-	u32 bitmask = nmk_gpio_get_bitmask(gpio);
-	u32 reg;
-
-	/* we must individually set/clear the two edges */
-	if (nmk_chip->edge_rising & bitmask) {
-		reg = readl(nmk_chip->addr + rimsc);
-		if (enable)
-			reg |= bitmask;
-		else
-			reg &= ~bitmask;
-		writel(reg, nmk_chip->addr + rimsc);
-	}
-	if (nmk_chip->edge_falling & bitmask) {
-		reg = readl(nmk_chip->addr + fimsc);
-		if (enable)
-			reg |= bitmask;
-		else
-			reg &= ~bitmask;
-		writel(reg, nmk_chip->addr + fimsc);
-	}
-}
-
-static void __nmk_gpio_set_wake(struct nmk_gpio_chip *nmk_chip,
-				int gpio, bool on)
-{
-	__nmk_gpio_irq_modify(nmk_chip, gpio, WAKE, on);
-}
-
-static int nmk_gpio_irq_maskunmask(struct irq_data *d, bool enable)
-{
-	int gpio;
-	struct nmk_gpio_chip *nmk_chip;
-	unsigned long flags;
-	u32 bitmask;
-
-	gpio = NOMADIK_IRQ_TO_GPIO(d->irq);
-	nmk_chip = irq_data_get_irq_chip_data(d);
-	bitmask = nmk_gpio_get_bitmask(gpio);
-	if (!nmk_chip)
-		return -EINVAL;
-
-	if (enable)
-		nmk_chip->enabled |= bitmask;
-	else
-		nmk_chip->enabled &= ~bitmask;
-
-	spin_lock_irqsave(&nmk_gpio_slpm_lock, flags);
-	spin_lock(&nmk_chip->lock);
-
-	__nmk_gpio_irq_modify(nmk_chip, gpio, NORMAL, enable);
-
-	if (!(nmk_chip->real_wake & bitmask))
-		__nmk_gpio_set_wake(nmk_chip, gpio, enable);
-
-	spin_unlock(&nmk_chip->lock);
-	spin_unlock_irqrestore(&nmk_gpio_slpm_lock, flags);
-
-	return 0;
-}
-
-static void nmk_gpio_irq_mask(struct irq_data *d)
-{
-	nmk_gpio_irq_maskunmask(d, false);
-}
-
-static void nmk_gpio_irq_unmask(struct irq_data *d)
-{
-	nmk_gpio_irq_maskunmask(d, true);
-}
-
-static int nmk_gpio_irq_set_wake(struct irq_data *d, unsigned int on)
-{
-	struct nmk_gpio_chip *nmk_chip;
-	unsigned long flags;
-	u32 bitmask;
-	int gpio;
-
-	gpio = NOMADIK_IRQ_TO_GPIO(d->irq);
-	nmk_chip = irq_data_get_irq_chip_data(d);
-	if (!nmk_chip)
-		return -EINVAL;
-	bitmask = nmk_gpio_get_bitmask(gpio);
-
-	spin_lock_irqsave(&nmk_gpio_slpm_lock, flags);
-	spin_lock(&nmk_chip->lock);
-
-	if (!(nmk_chip->enabled & bitmask))
-		__nmk_gpio_set_wake(nmk_chip, gpio, on);
-
-	if (on)
-		nmk_chip->real_wake |= bitmask;
-	else
-		nmk_chip->real_wake &= ~bitmask;
-
-	spin_unlock(&nmk_chip->lock);
-	spin_unlock_irqrestore(&nmk_gpio_slpm_lock, flags);
-
-	return 0;
-}
-
-static int nmk_gpio_irq_set_type(struct irq_data *d, unsigned int type)
-{
-	bool enabled, wake = irqd_is_wakeup_set(d);
-	int gpio;
-	struct nmk_gpio_chip *nmk_chip;
-	unsigned long flags;
-	u32 bitmask;
-
-	gpio = NOMADIK_IRQ_TO_GPIO(d->irq);
-	nmk_chip = irq_data_get_irq_chip_data(d);
-	bitmask = nmk_gpio_get_bitmask(gpio);
-	if (!nmk_chip)
-		return -EINVAL;
-
-	if (type & IRQ_TYPE_LEVEL_HIGH)
-		return -EINVAL;
-	if (type & IRQ_TYPE_LEVEL_LOW)
-		return -EINVAL;
-
-	enabled = nmk_chip->enabled & bitmask;
-
-	spin_lock_irqsave(&nmk_chip->lock, flags);
-
-	if (enabled)
-		__nmk_gpio_irq_modify(nmk_chip, gpio, NORMAL, false);
-
-	if (enabled || wake)
-		__nmk_gpio_irq_modify(nmk_chip, gpio, WAKE, false);
-
-	nmk_chip->edge_rising &= ~bitmask;
-	if (type & IRQ_TYPE_EDGE_RISING)
-		nmk_chip->edge_rising |= bitmask;
-
-	nmk_chip->edge_falling &= ~bitmask;
-	if (type & IRQ_TYPE_EDGE_FALLING)
-		nmk_chip->edge_falling |= bitmask;
-
-	if (enabled)
-		__nmk_gpio_irq_modify(nmk_chip, gpio, NORMAL, true);
-
-	if (enabled || wake)
-		__nmk_gpio_irq_modify(nmk_chip, gpio, WAKE, true);
-
-	spin_unlock_irqrestore(&nmk_chip->lock, flags);
-
-	return 0;
-}
-
-static struct irq_chip nmk_gpio_irq_chip = {
-	.name		= "Nomadik-GPIO",
-	.irq_ack	= nmk_gpio_irq_ack,
-	.irq_mask	= nmk_gpio_irq_mask,
-	.irq_unmask	= nmk_gpio_irq_unmask,
-	.irq_set_type	= nmk_gpio_irq_set_type,
-	.irq_set_wake	= nmk_gpio_irq_set_wake,
-};
-
-static void __nmk_gpio_irq_handler(unsigned int irq, struct irq_desc *desc,
-				   u32 status)
-{
-	struct nmk_gpio_chip *nmk_chip;
-	struct irq_chip *host_chip = irq_get_chip(irq);
-	unsigned int first_irq;
-
-	if (host_chip->irq_mask_ack)
-		host_chip->irq_mask_ack(&desc->irq_data);
-	else {
-		host_chip->irq_mask(&desc->irq_data);
-		if (host_chip->irq_ack)
-			host_chip->irq_ack(&desc->irq_data);
-	}
-
-	nmk_chip = irq_get_handler_data(irq);
-	first_irq = NOMADIK_GPIO_TO_IRQ(nmk_chip->chip.base);
-	while (status) {
-		int bit = __ffs(status);
-
-		generic_handle_irq(first_irq + bit);
-		status &= ~BIT(bit);
-	}
-
-	host_chip->irq_unmask(&desc->irq_data);
-}
-
-static void nmk_gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
-{
-	struct nmk_gpio_chip *nmk_chip = irq_get_handler_data(irq);
-	u32 status = readl(nmk_chip->addr + NMK_GPIO_IS);
-
-	__nmk_gpio_irq_handler(irq, desc, status);
-}
-
-static void nmk_gpio_secondary_irq_handler(unsigned int irq,
-					   struct irq_desc *desc)
-{
-	struct nmk_gpio_chip *nmk_chip = irq_get_handler_data(irq);
-	u32 status = nmk_chip->get_secondary_status(nmk_chip->bank);
-
-	__nmk_gpio_irq_handler(irq, desc, status);
-}
-
-static int nmk_gpio_init_irq(struct nmk_gpio_chip *nmk_chip)
-{
-	unsigned int first_irq;
-	int i;
-
-	first_irq = NOMADIK_GPIO_TO_IRQ(nmk_chip->chip.base);
-	for (i = first_irq; i < first_irq + nmk_chip->chip.ngpio; i++) {
-		irq_set_chip_and_handler(i, &nmk_gpio_irq_chip,
-					 handle_edge_irq);
-		set_irq_flags(i, IRQF_VALID);
-		irq_set_chip_data(i, nmk_chip);
-		irq_set_irq_type(i, IRQ_TYPE_EDGE_FALLING);
-	}
-
-	irq_set_chained_handler(nmk_chip->parent_irq, nmk_gpio_irq_handler);
-	irq_set_handler_data(nmk_chip->parent_irq, nmk_chip);
-
-	if (nmk_chip->secondary_parent_irq >= 0) {
-		irq_set_chained_handler(nmk_chip->secondary_parent_irq,
-					nmk_gpio_secondary_irq_handler);
-		irq_set_handler_data(nmk_chip->secondary_parent_irq, nmk_chip);
-	}
-
-	return 0;
-}
-
-/* I/O Functions */
-static int nmk_gpio_make_input(struct gpio_chip *chip, unsigned offset)
-{
-	struct nmk_gpio_chip *nmk_chip =
-		container_of(chip, struct nmk_gpio_chip, chip);
-
-	writel(1 << offset, nmk_chip->addr + NMK_GPIO_DIRC);
-	return 0;
-}
-
-static int nmk_gpio_get_input(struct gpio_chip *chip, unsigned offset)
-{
-	struct nmk_gpio_chip *nmk_chip =
-		container_of(chip, struct nmk_gpio_chip, chip);
-	u32 bit = 1 << offset;
-
-	return (readl(nmk_chip->addr + NMK_GPIO_DAT) & bit) != 0;
-}
-
-static void nmk_gpio_set_output(struct gpio_chip *chip, unsigned offset,
-				int val)
-{
-	struct nmk_gpio_chip *nmk_chip =
-		container_of(chip, struct nmk_gpio_chip, chip);
-
-	__nmk_gpio_set_output(nmk_chip, offset, val);
-}
-
-static int nmk_gpio_make_output(struct gpio_chip *chip, unsigned offset,
-				int val)
-{
-	struct nmk_gpio_chip *nmk_chip =
-		container_of(chip, struct nmk_gpio_chip, chip);
-
-	__nmk_gpio_make_output(nmk_chip, offset, val);
-
-	return 0;
-}
-
-static int nmk_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
-{
-	struct nmk_gpio_chip *nmk_chip =
-		container_of(chip, struct nmk_gpio_chip, chip);
-
-	return NOMADIK_GPIO_TO_IRQ(nmk_chip->chip.base) + offset;
-}
-
-#ifdef CONFIG_DEBUG_FS
-
-#include <linux/seq_file.h>
-
-static void nmk_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip)
-{
-	int mode;
-	unsigned		i;
-	unsigned		gpio = chip->base;
-	int			is_out;
-	struct nmk_gpio_chip *nmk_chip =
-		container_of(chip, struct nmk_gpio_chip, chip);
-	const char *modes[] = {
-		[NMK_GPIO_ALT_GPIO]	= "gpio",
-		[NMK_GPIO_ALT_A]	= "altA",
-		[NMK_GPIO_ALT_B]	= "altB",
-		[NMK_GPIO_ALT_C]	= "altC",
-	};
-
-	for (i = 0; i < chip->ngpio; i++, gpio++) {
-		const char *label = gpiochip_is_requested(chip, i);
-		bool pull;
-		u32 bit = 1 << i;
-
-		if (!label)
-			continue;
-
-		is_out = readl(nmk_chip->addr + NMK_GPIO_DIR) & bit;
-		pull = !(readl(nmk_chip->addr + NMK_GPIO_PDIS) & bit);
-		mode = nmk_gpio_get_mode(gpio);
-		seq_printf(s, " gpio-%-3d (%-20.20s) %s %s %s %s",
-			gpio, label,
-			is_out ? "out" : "in ",
-			chip->get
-				? (chip->get(chip, i) ? "hi" : "lo")
-				: "?  ",
-			(mode < 0) ? "unknown" : modes[mode],
-			pull ? "pull" : "none");
-		seq_printf(s, "\n");
-	}
-}
-
-#else
-#define nmk_gpio_dbg_show	NULL
-#endif
-
-/* This structure is replicated for each GPIO block allocated at probe time */
-static struct gpio_chip nmk_gpio_template = {
-	.direction_input	= nmk_gpio_make_input,
-	.get			= nmk_gpio_get_input,
-	.direction_output	= nmk_gpio_make_output,
-	.set			= nmk_gpio_set_output,
-	.to_irq			= nmk_gpio_to_irq,
-	.dbg_show		= nmk_gpio_dbg_show,
-	.can_sleep		= 0,
-};
-
-/*
- * Called from the suspend/resume path to only keep the real wakeup interrupts
- * (those that have had set_irq_wake() called on them) as wakeup interrupts,
- * and not the rest of the interrupts which we needed to have as wakeups for
- * cpuidle.
- *
- * PM ops are not used since this needs to be done at the end, after all the
- * other drivers are done with their suspend callbacks.
- */
-void nmk_gpio_wakeups_suspend(void)
-{
-	int i;
-
-	for (i = 0; i < NUM_BANKS; i++) {
-		struct nmk_gpio_chip *chip = nmk_gpio_chips[i];
-
-		if (!chip)
-			break;
-
-		chip->rwimsc = readl(chip->addr + NMK_GPIO_RWIMSC);
-		chip->fwimsc = readl(chip->addr + NMK_GPIO_FWIMSC);
-
-		writel(chip->rwimsc & chip->real_wake,
-		       chip->addr + NMK_GPIO_RWIMSC);
-		writel(chip->fwimsc & chip->real_wake,
-		       chip->addr + NMK_GPIO_FWIMSC);
-
-		if (cpu_is_u8500v2()) {
-			chip->slpm = readl(chip->addr + NMK_GPIO_SLPC);
-
-			/* 0 -> wakeup enable */
-			writel(~chip->real_wake, chip->addr + NMK_GPIO_SLPC);
-		}
-	}
-}
-
-void nmk_gpio_wakeups_resume(void)
-{
-	int i;
-
-	for (i = 0; i < NUM_BANKS; i++) {
-		struct nmk_gpio_chip *chip = nmk_gpio_chips[i];
-
-		if (!chip)
-			break;
-
-		writel(chip->rwimsc, chip->addr + NMK_GPIO_RWIMSC);
-		writel(chip->fwimsc, chip->addr + NMK_GPIO_FWIMSC);
-
-		if (cpu_is_u8500v2())
-			writel(chip->slpm, chip->addr + NMK_GPIO_SLPC);
-	}
-}
-
-static int __devinit nmk_gpio_probe(struct platform_device *dev)
-{
-	struct nmk_gpio_platform_data *pdata = dev->dev.platform_data;
-	struct nmk_gpio_chip *nmk_chip;
-	struct gpio_chip *chip;
-	struct resource *res;
-	struct clk *clk;
-	int secondary_irq;
-	int irq;
-	int ret;
-
-	if (!pdata)
-		return -ENODEV;
-
-	res = platform_get_resource(dev, IORESOURCE_MEM, 0);
-	if (!res) {
-		ret = -ENOENT;
-		goto out;
-	}
-
-	irq = platform_get_irq(dev, 0);
-	if (irq < 0) {
-		ret = irq;
-		goto out;
-	}
-
-	secondary_irq = platform_get_irq(dev, 1);
-	if (secondary_irq >= 0 && !pdata->get_secondary_status) {
-		ret = -EINVAL;
-		goto out;
-	}
-
-	if (request_mem_region(res->start, resource_size(res),
-			       dev_name(&dev->dev)) == NULL) {
-		ret = -EBUSY;
-		goto out;
-	}
-
-	clk = clk_get(&dev->dev, NULL);
-	if (IS_ERR(clk)) {
-		ret = PTR_ERR(clk);
-		goto out_release;
-	}
-
-	clk_enable(clk);
-
-	nmk_chip = kzalloc(sizeof(*nmk_chip), GFP_KERNEL);
-	if (!nmk_chip) {
-		ret = -ENOMEM;
-		goto out_clk;
-	}
-	/*
-	 * The virt address in nmk_chip->addr is in the nomadik register space,
-	 * so we can simply convert the resource address, without remapping
-	 */
-	nmk_chip->bank = dev->id;
-	nmk_chip->clk = clk;
-	nmk_chip->addr = io_p2v(res->start);
-	nmk_chip->chip = nmk_gpio_template;
-	nmk_chip->parent_irq = irq;
-	nmk_chip->secondary_parent_irq = secondary_irq;
-	nmk_chip->get_secondary_status = pdata->get_secondary_status;
-	nmk_chip->set_ioforce = pdata->set_ioforce;
-	spin_lock_init(&nmk_chip->lock);
-
-	chip = &nmk_chip->chip;
-	chip->base = pdata->first_gpio;
-	chip->ngpio = pdata->num_gpio;
-	chip->label = pdata->name ?: dev_name(&dev->dev);
-	chip->dev = &dev->dev;
-	chip->owner = THIS_MODULE;
-
-	ret = gpiochip_add(&nmk_chip->chip);
-	if (ret)
-		goto out_free;
-
-	BUG_ON(nmk_chip->bank >= ARRAY_SIZE(nmk_gpio_chips));
-
-	nmk_gpio_chips[nmk_chip->bank] = nmk_chip;
-	platform_set_drvdata(dev, nmk_chip);
-
-	nmk_gpio_init_irq(nmk_chip);
-
-	dev_info(&dev->dev, "Bits %i-%i at address %p\n",
-		 nmk_chip->chip.base, nmk_chip->chip.base+31, nmk_chip->addr);
-	return 0;
-
-out_free:
-	kfree(nmk_chip);
-out_clk:
-	clk_disable(clk);
-	clk_put(clk);
-out_release:
-	release_mem_region(res->start, resource_size(res));
-out:
-	dev_err(&dev->dev, "Failure %i for GPIO %i-%i\n", ret,
-		  pdata->first_gpio, pdata->first_gpio+31);
-	return ret;
-}
-
-static struct platform_driver nmk_gpio_driver = {
-	.driver = {
-		.owner = THIS_MODULE,
-		.name = "gpio",
-	},
-	.probe = nmk_gpio_probe,
-};
-
-static int __init nmk_gpio_init(void)
-{
-	return platform_driver_register(&nmk_gpio_driver);
-}
-
-core_initcall(nmk_gpio_init);
-
-MODULE_AUTHOR("Prafulla WADASKAR and Alessandro Rubini");
-MODULE_DESCRIPTION("Nomadik GPIO Driver");
-MODULE_LICENSE("GPL");
-
-
diff -druN linux-2.6.39-libre/arch/arm/plat-nomadik/include/plat/gpio.h linux-3.0-rc7-libre/arch/arm/plat-nomadik/include/plat/gpio.h
--- linux-2.6.39-libre/arch/arm/plat-nomadik/include/plat/gpio.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/plat-nomadik/include/plat/gpio.h	2011-07-11 19:51:52.000000000 -0400
@@ -78,6 +78,8 @@
 extern void nmk_gpio_wakeups_suspend(void);
 extern void nmk_gpio_wakeups_resume(void);
 
+extern void nmk_gpio_read_pull(int gpio_bank, u32 *pull_up);
+
 /*
  * Platform data to register a block: only the initial gpio/irq number.
  */
@@ -88,6 +90,7 @@
 	int num_gpio;
 	u32 (*get_secondary_status)(unsigned int bank);
 	void (*set_ioforce)(bool enable);
+	bool supports_sleepmode;
 };
 
 #endif /* __ASM_PLAT_GPIO_H */
diff -druN linux-2.6.39-libre/arch/arm/plat-nomadik/include/plat/i2c.h linux-3.0-rc7-libre/arch/arm/plat-nomadik/include/plat/i2c.h
--- linux-2.6.39-libre/arch/arm/plat-nomadik/include/plat/i2c.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/plat-nomadik/include/plat/i2c.h	2011-07-11 19:51:52.000000000 -0400
@@ -11,8 +11,8 @@
 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_HIGH_SPEED,	/* up to 3.4 Mb/s */
 	I2C_FREQ_MODE_FAST_PLUS,	/* up to 1 Mb/s */
-	I2C_FREQ_MODE_HIGH_SPEED	/* up to 3.4 Mb/s */
 };
 
 /**
@@ -24,13 +24,15 @@
  *		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
+ * @timeout	Slave response timeout(ms)
  * @sm:		speed mode
  */
 struct nmk_i2c_controller {
 	unsigned long	clk_freq;
 	unsigned short	slsu;
-	unsigned char 	tft;
-	unsigned char 	rft;
+	unsigned char	tft;
+	unsigned char	rft;
+	int timeout;
 	enum i2c_freq_mode	sm;
 };
 
diff -druN linux-2.6.39-libre/arch/arm/plat-nomadik/Kconfig linux-3.0-rc7-libre/arch/arm/plat-nomadik/Kconfig
--- linux-2.6.39-libre/arch/arm/plat-nomadik/Kconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/plat-nomadik/Kconfig	2011-07-11 19:51:52.000000000 -0400
@@ -5,6 +5,7 @@
 config PLAT_NOMADIK
 	bool
 	depends on ARCH_NOMADIK || ARCH_U8500
+	select CLKSRC_MMIO
 	default y
 	help
 	  Common platform code for Nomadik and other ST-Ericsson
@@ -20,9 +21,4 @@
 	  to multiple interrupt generating programmable
 	  32-bit free running decrementing counters.
 
-config NOMADIK_GPIO
-	bool
-	help
-	  Support for the Nomadik GPIO controller.
-
 endif
diff -druN linux-2.6.39-libre/arch/arm/plat-nomadik/Makefile linux-3.0-rc7-libre/arch/arm/plat-nomadik/Makefile
--- linux-2.6.39-libre/arch/arm/plat-nomadik/Makefile	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/plat-nomadik/Makefile	2011-07-11 19:51:52.000000000 -0400
@@ -3,4 +3,3 @@
 # Licensed under GPLv2
 
 obj-$(CONFIG_HAS_MTU)	+= timer.o
-obj-$(CONFIG_NOMADIK_GPIO)	+= gpio.o
diff -druN linux-2.6.39-libre/arch/arm/plat-nomadik/timer.c linux-3.0-rc7-libre/arch/arm/plat-nomadik/timer.c
--- linux-2.6.39-libre/arch/arm/plat-nomadik/timer.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/plat-nomadik/timer.c	2011-07-11 19:51:52.000000000 -0400
@@ -26,29 +26,6 @@
 void __iomem *mtu_base; /* Assigned by machine code */
 
 /*
- * Kernel assumes that sched_clock can be called early
- * but the MTU may not yet be initialized.
- */
-static cycle_t nmdk_read_timer_dummy(struct clocksource *cs)
-{
-	return 0;
-}
-
-/* clocksource: MTU decrements, so we negate the value being read. */
-static cycle_t nmdk_read_timer(struct clocksource *cs)
-{
-	return -readl(mtu_base + MTU_VAL(0));
-}
-
-static struct clocksource nmdk_clksrc = {
-	.name		= "mtu_0",
-	.rating		= 200,
-	.read		= nmdk_read_timer_dummy,
-	.mask		= CLOCKSOURCE_MASK(32),
-	.flags		= CLOCK_SOURCE_IS_CONTINUOUS,
-};
-
-/*
  * Override the global weak sched_clock symbol with this
  * local implementation which uses the clocksource to get some
  * better resolution when scheduling the kernel.
@@ -172,12 +149,10 @@
 	writel(0, mtu_base + MTU_BGLR(0));
 	writel(cr | MTU_CRn_ENA, mtu_base + MTU_CR(0));
 
-	/* Now the clock source is ready */
-	nmdk_clksrc.read = nmdk_read_timer;
-
-	if (clocksource_register_hz(&nmdk_clksrc, rate))
+	if (clocksource_mmio_init(mtu_base + MTU_VAL(0), "mtu_0",
+			rate, 200, 32, clocksource_mmio_readl_down))
 		pr_err("timer: failed to initialize clock source %s\n",
-		       nmdk_clksrc.name);
+		       "mtu_0");
 
 	init_sched_clock(&cd, nomadik_update_sched_clock, 32, rate);
 
diff -druN linux-2.6.39-libre/arch/arm/plat-omap/gpio.c linux-3.0-rc7-libre/arch/arm/plat-omap/gpio.c
--- linux-2.6.39-libre/arch/arm/plat-omap/gpio.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/plat-omap/gpio.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,2128 +0,0 @@
-/*
- *  linux/arch/arm/plat-omap/gpio.c
- *
- * Support functions for OMAP GPIO
- *
- * Copyright (C) 2003-2005 Nokia Corporation
- * Written by Juha Yrjölä <juha.yrjola@nokia.com>
- *
- * Copyright (C) 2009 Texas Instruments
- * Added OMAP4 support - Santosh Shilimkar <santosh.shilimkar@ti.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/interrupt.h>
-#include <linux/sysdev.h>
-#include <linux/err.h>
-#include <linux/clk.h>
-#include <linux/io.h>
-#include <linux/slab.h>
-#include <linux/pm_runtime.h>
-
-#include <mach/hardware.h>
-#include <asm/irq.h>
-#include <mach/irqs.h>
-#include <mach/gpio.h>
-#include <asm/mach/irq.h>
-
-/*
- * OMAP1510 GPIO registers
- */
-#define OMAP1510_GPIO_DATA_INPUT	0x00
-#define OMAP1510_GPIO_DATA_OUTPUT	0x04
-#define OMAP1510_GPIO_DIR_CONTROL	0x08
-#define OMAP1510_GPIO_INT_CONTROL	0x0c
-#define OMAP1510_GPIO_INT_MASK		0x10
-#define OMAP1510_GPIO_INT_STATUS	0x14
-#define OMAP1510_GPIO_PIN_CONTROL	0x18
-
-#define OMAP1510_IH_GPIO_BASE		64
-
-/*
- * OMAP1610 specific GPIO registers
- */
-#define OMAP1610_GPIO_REVISION		0x0000
-#define OMAP1610_GPIO_SYSCONFIG		0x0010
-#define OMAP1610_GPIO_SYSSTATUS		0x0014
-#define OMAP1610_GPIO_IRQSTATUS1	0x0018
-#define OMAP1610_GPIO_IRQENABLE1	0x001c
-#define OMAP1610_GPIO_WAKEUPENABLE	0x0028
-#define OMAP1610_GPIO_DATAIN		0x002c
-#define OMAP1610_GPIO_DATAOUT		0x0030
-#define OMAP1610_GPIO_DIRECTION		0x0034
-#define OMAP1610_GPIO_EDGE_CTRL1	0x0038
-#define OMAP1610_GPIO_EDGE_CTRL2	0x003c
-#define OMAP1610_GPIO_CLEAR_IRQENABLE1	0x009c
-#define OMAP1610_GPIO_CLEAR_WAKEUPENA	0x00a8
-#define OMAP1610_GPIO_CLEAR_DATAOUT	0x00b0
-#define OMAP1610_GPIO_SET_IRQENABLE1	0x00dc
-#define OMAP1610_GPIO_SET_WAKEUPENA	0x00e8
-#define OMAP1610_GPIO_SET_DATAOUT	0x00f0
-
-/*
- * OMAP7XX specific GPIO registers
- */
-#define OMAP7XX_GPIO_DATA_INPUT		0x00
-#define OMAP7XX_GPIO_DATA_OUTPUT	0x04
-#define OMAP7XX_GPIO_DIR_CONTROL	0x08
-#define OMAP7XX_GPIO_INT_CONTROL	0x0c
-#define OMAP7XX_GPIO_INT_MASK		0x10
-#define OMAP7XX_GPIO_INT_STATUS		0x14
-
-/*
- * omap2+ specific GPIO registers
- */
-#define OMAP24XX_GPIO_REVISION		0x0000
-#define OMAP24XX_GPIO_IRQSTATUS1	0x0018
-#define OMAP24XX_GPIO_IRQSTATUS2	0x0028
-#define OMAP24XX_GPIO_IRQENABLE2	0x002c
-#define OMAP24XX_GPIO_IRQENABLE1	0x001c
-#define OMAP24XX_GPIO_WAKE_EN		0x0020
-#define OMAP24XX_GPIO_CTRL		0x0030
-#define OMAP24XX_GPIO_OE		0x0034
-#define OMAP24XX_GPIO_DATAIN		0x0038
-#define OMAP24XX_GPIO_DATAOUT		0x003c
-#define OMAP24XX_GPIO_LEVELDETECT0	0x0040
-#define OMAP24XX_GPIO_LEVELDETECT1	0x0044
-#define OMAP24XX_GPIO_RISINGDETECT	0x0048
-#define OMAP24XX_GPIO_FALLINGDETECT	0x004c
-#define OMAP24XX_GPIO_DEBOUNCE_EN	0x0050
-#define OMAP24XX_GPIO_DEBOUNCE_VAL	0x0054
-#define OMAP24XX_GPIO_CLEARIRQENABLE1	0x0060
-#define OMAP24XX_GPIO_SETIRQENABLE1	0x0064
-#define OMAP24XX_GPIO_CLEARWKUENA	0x0080
-#define OMAP24XX_GPIO_SETWKUENA		0x0084
-#define OMAP24XX_GPIO_CLEARDATAOUT	0x0090
-#define OMAP24XX_GPIO_SETDATAOUT	0x0094
-
-#define OMAP4_GPIO_REVISION		0x0000
-#define OMAP4_GPIO_EOI			0x0020
-#define OMAP4_GPIO_IRQSTATUSRAW0	0x0024
-#define OMAP4_GPIO_IRQSTATUSRAW1	0x0028
-#define OMAP4_GPIO_IRQSTATUS0		0x002c
-#define OMAP4_GPIO_IRQSTATUS1		0x0030
-#define OMAP4_GPIO_IRQSTATUSSET0	0x0034
-#define OMAP4_GPIO_IRQSTATUSSET1	0x0038
-#define OMAP4_GPIO_IRQSTATUSCLR0	0x003c
-#define OMAP4_GPIO_IRQSTATUSCLR1	0x0040
-#define OMAP4_GPIO_IRQWAKEN0		0x0044
-#define OMAP4_GPIO_IRQWAKEN1		0x0048
-#define OMAP4_GPIO_IRQENABLE1		0x011c
-#define OMAP4_GPIO_WAKE_EN		0x0120
-#define OMAP4_GPIO_IRQSTATUS2		0x0128
-#define OMAP4_GPIO_IRQENABLE2		0x012c
-#define OMAP4_GPIO_CTRL			0x0130
-#define OMAP4_GPIO_OE			0x0134
-#define OMAP4_GPIO_DATAIN		0x0138
-#define OMAP4_GPIO_DATAOUT		0x013c
-#define OMAP4_GPIO_LEVELDETECT0		0x0140
-#define OMAP4_GPIO_LEVELDETECT1		0x0144
-#define OMAP4_GPIO_RISINGDETECT		0x0148
-#define OMAP4_GPIO_FALLINGDETECT	0x014c
-#define OMAP4_GPIO_DEBOUNCENABLE	0x0150
-#define OMAP4_GPIO_DEBOUNCINGTIME	0x0154
-#define OMAP4_GPIO_CLEARIRQENABLE1	0x0160
-#define OMAP4_GPIO_SETIRQENABLE1	0x0164
-#define OMAP4_GPIO_CLEARWKUENA		0x0180
-#define OMAP4_GPIO_SETWKUENA		0x0184
-#define OMAP4_GPIO_CLEARDATAOUT		0x0190
-#define OMAP4_GPIO_SETDATAOUT		0x0194
-
-struct gpio_bank {
-	unsigned long pbase;
-	void __iomem *base;
-	u16 irq;
-	u16 virtual_irq_start;
-	int method;
-#if defined(CONFIG_ARCH_OMAP16XX) || defined(CONFIG_ARCH_OMAP2PLUS)
-	u32 suspend_wakeup;
-	u32 saved_wakeup;
-#endif
-	u32 non_wakeup_gpios;
-	u32 enabled_non_wakeup_gpios;
-
-	u32 saved_datain;
-	u32 saved_fallingdetect;
-	u32 saved_risingdetect;
-	u32 level_mask;
-	u32 toggle_mask;
-	spinlock_t lock;
-	struct gpio_chip chip;
-	struct clk *dbck;
-	u32 mod_usage;
-	u32 dbck_enable_mask;
-	struct device *dev;
-	bool dbck_flag;
-	int stride;
-};
-
-#ifdef CONFIG_ARCH_OMAP3
-struct omap3_gpio_regs {
-	u32 irqenable1;
-	u32 irqenable2;
-	u32 wake_en;
-	u32 ctrl;
-	u32 oe;
-	u32 leveldetect0;
-	u32 leveldetect1;
-	u32 risingdetect;
-	u32 fallingdetect;
-	u32 dataout;
-};
-
-static struct omap3_gpio_regs gpio_context[OMAP34XX_NR_GPIOS];
-#endif
-
-/*
- * TODO: Cleanup gpio_bank usage as it is having information
- * related to all instances of the device
- */
-static struct gpio_bank *gpio_bank;
-
-static int bank_width;
-
-/* TODO: Analyze removing gpio_bank_count usage from driver code */
-int gpio_bank_count;
-
-static inline struct gpio_bank *get_gpio_bank(int gpio)
-{
-	if (cpu_is_omap15xx()) {
-		if (OMAP_GPIO_IS_MPUIO(gpio))
-			return &gpio_bank[0];
-		return &gpio_bank[1];
-	}
-	if (cpu_is_omap16xx()) {
-		if (OMAP_GPIO_IS_MPUIO(gpio))
-			return &gpio_bank[0];
-		return &gpio_bank[1 + (gpio >> 4)];
-	}
-	if (cpu_is_omap7xx()) {
-		if (OMAP_GPIO_IS_MPUIO(gpio))
-			return &gpio_bank[0];
-		return &gpio_bank[1 + (gpio >> 5)];
-	}
-	if (cpu_is_omap24xx())
-		return &gpio_bank[gpio >> 5];
-	if (cpu_is_omap34xx() || cpu_is_omap44xx())
-		return &gpio_bank[gpio >> 5];
-	BUG();
-	return NULL;
-}
-
-static inline int get_gpio_index(int gpio)
-{
-	if (cpu_is_omap7xx())
-		return gpio & 0x1f;
-	if (cpu_is_omap24xx())
-		return gpio & 0x1f;
-	if (cpu_is_omap34xx() || cpu_is_omap44xx())
-		return gpio & 0x1f;
-	return gpio & 0x0f;
-}
-
-static inline int gpio_valid(int gpio)
-{
-	if (gpio < 0)
-		return -1;
-	if (cpu_class_is_omap1() && OMAP_GPIO_IS_MPUIO(gpio)) {
-		if (gpio >= OMAP_MAX_GPIO_LINES + 16)
-			return -1;
-		return 0;
-	}
-	if (cpu_is_omap15xx() && gpio < 16)
-		return 0;
-	if ((cpu_is_omap16xx()) && gpio < 64)
-		return 0;
-	if (cpu_is_omap7xx() && gpio < 192)
-		return 0;
-	if (cpu_is_omap2420() && gpio < 128)
-		return 0;
-	if (cpu_is_omap2430() && gpio < 160)
-		return 0;
-	if ((cpu_is_omap34xx() || cpu_is_omap44xx()) && gpio < 192)
-		return 0;
-	return -1;
-}
-
-static int check_gpio(int gpio)
-{
-	if (unlikely(gpio_valid(gpio) < 0)) {
-		printk(KERN_ERR "omap-gpio: invalid GPIO %d\n", gpio);
-		dump_stack();
-		return -1;
-	}
-	return 0;
-}
-
-static void _set_gpio_direction(struct gpio_bank *bank, int gpio, int is_input)
-{
-	void __iomem *reg = bank->base;
-	u32 l;
-
-	switch (bank->method) {
-#ifdef CONFIG_ARCH_OMAP1
-	case METHOD_MPUIO:
-		reg += OMAP_MPUIO_IO_CNTL / bank->stride;
-		break;
-#endif
-#ifdef CONFIG_ARCH_OMAP15XX
-	case METHOD_GPIO_1510:
-		reg += OMAP1510_GPIO_DIR_CONTROL;
-		break;
-#endif
-#ifdef CONFIG_ARCH_OMAP16XX
-	case METHOD_GPIO_1610:
-		reg += OMAP1610_GPIO_DIRECTION;
-		break;
-#endif
-#if defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP850)
-	case METHOD_GPIO_7XX:
-		reg += OMAP7XX_GPIO_DIR_CONTROL;
-		break;
-#endif
-#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_44XX:
-		reg += OMAP4_GPIO_OE;
-		break;
-#endif
-	default:
-		WARN_ON(1);
-		return;
-	}
-	l = __raw_readl(reg);
-	if (is_input)
-		l |= 1 << gpio;
-	else
-		l &= ~(1 << gpio);
-	__raw_writel(l, reg);
-}
-
-static void _set_gpio_dataout(struct gpio_bank *bank, int gpio, int enable)
-{
-	void __iomem *reg = bank->base;
-	u32 l = 0;
-
-	switch (bank->method) {
-#ifdef CONFIG_ARCH_OMAP1
-	case METHOD_MPUIO:
-		reg += OMAP_MPUIO_OUTPUT / bank->stride;
-		l = __raw_readl(reg);
-		if (enable)
-			l |= 1 << gpio;
-		else
-			l &= ~(1 << gpio);
-		break;
-#endif
-#ifdef CONFIG_ARCH_OMAP15XX
-	case METHOD_GPIO_1510:
-		reg += OMAP1510_GPIO_DATA_OUTPUT;
-		l = __raw_readl(reg);
-		if (enable)
-			l |= 1 << gpio;
-		else
-			l &= ~(1 << gpio);
-		break;
-#endif
-#ifdef CONFIG_ARCH_OMAP16XX
-	case METHOD_GPIO_1610:
-		if (enable)
-			reg += OMAP1610_GPIO_SET_DATAOUT;
-		else
-			reg += OMAP1610_GPIO_CLEAR_DATAOUT;
-		l = 1 << gpio;
-		break;
-#endif
-#if defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP850)
-	case METHOD_GPIO_7XX:
-		reg += OMAP7XX_GPIO_DATA_OUTPUT;
-		l = __raw_readl(reg);
-		if (enable)
-			l |= 1 << gpio;
-		else
-			l &= ~(1 << gpio);
-		break;
-#endif
-#if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3)
-	case METHOD_GPIO_24XX:
-		if (enable)
-			reg += OMAP24XX_GPIO_SETDATAOUT;
-		else
-			reg += OMAP24XX_GPIO_CLEARDATAOUT;
-		l = 1 << gpio;
-		break;
-#endif
-#ifdef CONFIG_ARCH_OMAP4
-	case METHOD_GPIO_44XX:
-		if (enable)
-			reg += OMAP4_GPIO_SETDATAOUT;
-		else
-			reg += OMAP4_GPIO_CLEARDATAOUT;
-		l = 1 << gpio;
-		break;
-#endif
-	default:
-		WARN_ON(1);
-		return;
-	}
-	__raw_writel(l, reg);
-}
-
-static int _get_gpio_datain(struct gpio_bank *bank, int gpio)
-{
-	void __iomem *reg;
-
-	if (check_gpio(gpio) < 0)
-		return -EINVAL;
-	reg = bank->base;
-	switch (bank->method) {
-#ifdef CONFIG_ARCH_OMAP1
-	case METHOD_MPUIO:
-		reg += OMAP_MPUIO_INPUT_LATCH / bank->stride;
-		break;
-#endif
-#ifdef CONFIG_ARCH_OMAP15XX
-	case METHOD_GPIO_1510:
-		reg += OMAP1510_GPIO_DATA_INPUT;
-		break;
-#endif
-#ifdef CONFIG_ARCH_OMAP16XX
-	case METHOD_GPIO_1610:
-		reg += OMAP1610_GPIO_DATAIN;
-		break;
-#endif
-#if defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP850)
-	case METHOD_GPIO_7XX:
-		reg += OMAP7XX_GPIO_DATA_INPUT;
-		break;
-#endif
-#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_44XX:
-		reg += OMAP4_GPIO_DATAIN;
-		break;
-#endif
-	default:
-		return -EINVAL;
-	}
-	return (__raw_readl(reg)
-			& (1 << get_gpio_index(gpio))) != 0;
-}
-
-static int _get_gpio_dataout(struct gpio_bank *bank, int gpio)
-{
-	void __iomem *reg;
-
-	if (check_gpio(gpio) < 0)
-		return -EINVAL;
-	reg = bank->base;
-
-	switch (bank->method) {
-#ifdef CONFIG_ARCH_OMAP1
-	case METHOD_MPUIO:
-		reg += OMAP_MPUIO_OUTPUT / bank->stride;
-		break;
-#endif
-#ifdef CONFIG_ARCH_OMAP15XX
-	case METHOD_GPIO_1510:
-		reg += OMAP1510_GPIO_DATA_OUTPUT;
-		break;
-#endif
-#ifdef CONFIG_ARCH_OMAP16XX
-	case METHOD_GPIO_1610:
-		reg += OMAP1610_GPIO_DATAOUT;
-		break;
-#endif
-#if defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP850)
-	case METHOD_GPIO_7XX:
-		reg += OMAP7XX_GPIO_DATA_OUTPUT;
-		break;
-#endif
-#if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3)
-	case METHOD_GPIO_24XX:
-		reg += OMAP24XX_GPIO_DATAOUT;
-		break;
-#endif
-#ifdef CONFIG_ARCH_OMAP4
-	case METHOD_GPIO_44XX:
-		reg += OMAP4_GPIO_DATAOUT;
-		break;
-#endif
-	default:
-		return -EINVAL;
-	}
-
-	return (__raw_readl(reg) & (1 << get_gpio_index(gpio))) != 0;
-}
-
-#define MOD_REG_BIT(reg, bit_mask, set)	\
-do {	\
-	int l = __raw_readl(base + reg); \
-	if (set) l |= bit_mask; \
-	else l &= ~bit_mask; \
-	__raw_writel(l, base + reg); \
-} while(0)
-
-/**
- * _set_gpio_debounce - low level gpio debounce time
- * @bank: the gpio bank we're acting upon
- * @gpio: the gpio number on this @gpio
- * @debounce: debounce time to use
- *
- * OMAP's debounce time is in 31us steps so we need
- * to convert and round up to the closest unit.
- */
-static void _set_gpio_debounce(struct gpio_bank *bank, unsigned gpio,
-		unsigned debounce)
-{
-	void __iomem		*reg = bank->base;
-	u32			val;
-	u32			l;
-
-	if (!bank->dbck_flag)
-		return;
-
-	if (debounce < 32)
-		debounce = 0x01;
-	else if (debounce > 7936)
-		debounce = 0xff;
-	else
-		debounce = (debounce / 0x1f) - 1;
-
-	l = 1 << get_gpio_index(gpio);
-
-	if (bank->method == METHOD_GPIO_44XX)
-		reg += OMAP4_GPIO_DEBOUNCINGTIME;
-	else
-		reg += OMAP24XX_GPIO_DEBOUNCE_VAL;
-
-	__raw_writel(debounce, reg);
-
-	reg = bank->base;
-	if (bank->method == METHOD_GPIO_44XX)
-		reg += OMAP4_GPIO_DEBOUNCENABLE;
-	else
-		reg += OMAP24XX_GPIO_DEBOUNCE_EN;
-
-	val = __raw_readl(reg);
-
-	if (debounce) {
-		val |= l;
-		clk_enable(bank->dbck);
-	} else {
-		val &= ~l;
-		clk_disable(bank->dbck);
-	}
-	bank->dbck_enable_mask = val;
-
-	__raw_writel(val, reg);
-}
-
-#ifdef CONFIG_ARCH_OMAP2PLUS
-static inline void set_24xx_gpio_triggering(struct gpio_bank *bank, int gpio,
-						int trigger)
-{
-	void __iomem *base = bank->base;
-	u32 gpio_bit = 1 << gpio;
-	u32 val;
-
-	if (cpu_is_omap44xx()) {
-		MOD_REG_BIT(OMAP4_GPIO_LEVELDETECT0, gpio_bit,
-			trigger & IRQ_TYPE_LEVEL_LOW);
-		MOD_REG_BIT(OMAP4_GPIO_LEVELDETECT1, gpio_bit,
-			trigger & IRQ_TYPE_LEVEL_HIGH);
-		MOD_REG_BIT(OMAP4_GPIO_RISINGDETECT, gpio_bit,
-			trigger & IRQ_TYPE_EDGE_RISING);
-		MOD_REG_BIT(OMAP4_GPIO_FALLINGDETECT, gpio_bit,
-			trigger & IRQ_TYPE_EDGE_FALLING);
-	} else {
-		MOD_REG_BIT(OMAP24XX_GPIO_LEVELDETECT0, gpio_bit,
-			trigger & IRQ_TYPE_LEVEL_LOW);
-		MOD_REG_BIT(OMAP24XX_GPIO_LEVELDETECT1, gpio_bit,
-			trigger & IRQ_TYPE_LEVEL_HIGH);
-		MOD_REG_BIT(OMAP24XX_GPIO_RISINGDETECT, gpio_bit,
-			trigger & IRQ_TYPE_EDGE_RISING);
-		MOD_REG_BIT(OMAP24XX_GPIO_FALLINGDETECT, gpio_bit,
-			trigger & IRQ_TYPE_EDGE_FALLING);
-	}
-	if (likely(!(bank->non_wakeup_gpios & gpio_bit))) {
-		if (cpu_is_omap44xx()) {
-			if (trigger != 0)
-				__raw_writel(1 << gpio, bank->base+
-						OMAP4_GPIO_IRQWAKEN0);
-			else {
-				val = __raw_readl(bank->base +
-							OMAP4_GPIO_IRQWAKEN0);
-				__raw_writel(val & (~(1 << gpio)), bank->base +
-							 OMAP4_GPIO_IRQWAKEN0);
-			}
-		} else {
-			/*
-			 * GPIO wakeup request can only be generated on edge
-			 * transitions
-			 */
-			if (trigger & IRQ_TYPE_EDGE_BOTH)
-				__raw_writel(1 << gpio, bank->base
-					+ OMAP24XX_GPIO_SETWKUENA);
-			else
-				__raw_writel(1 << gpio, bank->base
-					+ OMAP24XX_GPIO_CLEARWKUENA);
-		}
-	}
-	/* This part needs to be executed always for OMAP34xx */
-	if (cpu_is_omap34xx() || (bank->non_wakeup_gpios & gpio_bit)) {
-		/*
-		 * Log the edge gpio and manually trigger the IRQ
-		 * after resume if the input level changes
-		 * to avoid irq lost during PER RET/OFF mode
-		 * Applies for omap2 non-wakeup gpio and all omap3 gpios
-		 */
-		if (trigger & IRQ_TYPE_EDGE_BOTH)
-			bank->enabled_non_wakeup_gpios |= gpio_bit;
-		else
-			bank->enabled_non_wakeup_gpios &= ~gpio_bit;
-	}
-
-	if (cpu_is_omap44xx()) {
-		bank->level_mask =
-			__raw_readl(bank->base + OMAP4_GPIO_LEVELDETECT0) |
-			__raw_readl(bank->base + OMAP4_GPIO_LEVELDETECT1);
-	} else {
-		bank->level_mask =
-			__raw_readl(bank->base + OMAP24XX_GPIO_LEVELDETECT0) |
-			__raw_readl(bank->base + OMAP24XX_GPIO_LEVELDETECT1);
-	}
-}
-#endif
-
-#ifdef CONFIG_ARCH_OMAP1
-/*
- * This only applies to chips that can't do both rising and falling edge
- * detection at once.  For all other chips, this function is a noop.
- */
-static void _toggle_gpio_edge_triggering(struct gpio_bank *bank, int gpio)
-{
-	void __iomem *reg = bank->base;
-	u32 l = 0;
-
-	switch (bank->method) {
-	case METHOD_MPUIO:
-		reg += OMAP_MPUIO_GPIO_INT_EDGE / bank->stride;
-		break;
-#ifdef CONFIG_ARCH_OMAP15XX
-	case METHOD_GPIO_1510:
-		reg += OMAP1510_GPIO_INT_CONTROL;
-		break;
-#endif
-#if defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP850)
-	case METHOD_GPIO_7XX:
-		reg += OMAP7XX_GPIO_INT_CONTROL;
-		break;
-#endif
-	default:
-		return;
-	}
-
-	l = __raw_readl(reg);
-	if ((l >> gpio) & 1)
-		l &= ~(1 << gpio);
-	else
-		l |= 1 << gpio;
-
-	__raw_writel(l, reg);
-}
-#endif
-
-static int _set_gpio_triggering(struct gpio_bank *bank, int gpio, int trigger)
-{
-	void __iomem *reg = bank->base;
-	u32 l = 0;
-
-	switch (bank->method) {
-#ifdef CONFIG_ARCH_OMAP1
-	case METHOD_MPUIO:
-		reg += OMAP_MPUIO_GPIO_INT_EDGE / bank->stride;
-		l = __raw_readl(reg);
-		if ((trigger & IRQ_TYPE_SENSE_MASK) == IRQ_TYPE_EDGE_BOTH)
-			bank->toggle_mask |= 1 << gpio;
-		if (trigger & IRQ_TYPE_EDGE_RISING)
-			l |= 1 << gpio;
-		else if (trigger & IRQ_TYPE_EDGE_FALLING)
-			l &= ~(1 << gpio);
-		else
-			goto bad;
-		break;
-#endif
-#ifdef CONFIG_ARCH_OMAP15XX
-	case METHOD_GPIO_1510:
-		reg += OMAP1510_GPIO_INT_CONTROL;
-		l = __raw_readl(reg);
-		if ((trigger & IRQ_TYPE_SENSE_MASK) == IRQ_TYPE_EDGE_BOTH)
-			bank->toggle_mask |= 1 << gpio;
-		if (trigger & IRQ_TYPE_EDGE_RISING)
-			l |= 1 << gpio;
-		else if (trigger & IRQ_TYPE_EDGE_FALLING)
-			l &= ~(1 << gpio);
-		else
-			goto bad;
-		break;
-#endif
-#ifdef CONFIG_ARCH_OMAP16XX
-	case METHOD_GPIO_1610:
-		if (gpio & 0x08)
-			reg += OMAP1610_GPIO_EDGE_CTRL2;
-		else
-			reg += OMAP1610_GPIO_EDGE_CTRL1;
-		gpio &= 0x07;
-		l = __raw_readl(reg);
-		l &= ~(3 << (gpio << 1));
-		if (trigger & IRQ_TYPE_EDGE_RISING)
-			l |= 2 << (gpio << 1);
-		if (trigger & IRQ_TYPE_EDGE_FALLING)
-			l |= 1 << (gpio << 1);
-		if (trigger)
-			/* Enable wake-up during idle for dynamic tick */
-			__raw_writel(1 << gpio, bank->base + OMAP1610_GPIO_SET_WAKEUPENA);
-		else
-			__raw_writel(1 << gpio, bank->base + OMAP1610_GPIO_CLEAR_WAKEUPENA);
-		break;
-#endif
-#if defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP850)
-	case METHOD_GPIO_7XX:
-		reg += OMAP7XX_GPIO_INT_CONTROL;
-		l = __raw_readl(reg);
-		if ((trigger & IRQ_TYPE_SENSE_MASK) == IRQ_TYPE_EDGE_BOTH)
-			bank->toggle_mask |= 1 << gpio;
-		if (trigger & IRQ_TYPE_EDGE_RISING)
-			l |= 1 << gpio;
-		else if (trigger & IRQ_TYPE_EDGE_FALLING)
-			l &= ~(1 << gpio);
-		else
-			goto bad;
-		break;
-#endif
-#ifdef CONFIG_ARCH_OMAP2PLUS
-	case METHOD_GPIO_24XX:
-	case METHOD_GPIO_44XX:
-		set_24xx_gpio_triggering(bank, gpio, trigger);
-		return 0;
-#endif
-	default:
-		goto bad;
-	}
-	__raw_writel(l, reg);
-	return 0;
-bad:
-	return -EINVAL;
-}
-
-static int gpio_irq_type(struct irq_data *d, unsigned type)
-{
-	struct gpio_bank *bank;
-	unsigned gpio;
-	int retval;
-	unsigned long flags;
-
-	if (!cpu_class_is_omap2() && d->irq > IH_MPUIO_BASE)
-		gpio = OMAP_MPUIO(d->irq - IH_MPUIO_BASE);
-	else
-		gpio = d->irq - IH_GPIO_BASE;
-
-	if (check_gpio(gpio) < 0)
-		return -EINVAL;
-
-	if (type & ~IRQ_TYPE_SENSE_MASK)
-		return -EINVAL;
-
-	/* OMAP1 allows only only edge triggering */
-	if (!cpu_class_is_omap2()
-			&& (type & (IRQ_TYPE_LEVEL_LOW|IRQ_TYPE_LEVEL_HIGH)))
-		return -EINVAL;
-
-	bank = irq_data_get_irq_chip_data(d);
-	spin_lock_irqsave(&bank->lock, flags);
-	retval = _set_gpio_triggering(bank, get_gpio_index(gpio), type);
-	spin_unlock_irqrestore(&bank->lock, flags);
-
-	if (type & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_LEVEL_HIGH))
-		__irq_set_handler_locked(d->irq, handle_level_irq);
-	else if (type & (IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING))
-		__irq_set_handler_locked(d->irq, handle_edge_irq);
-
-	return retval;
-}
-
-static void _clear_gpio_irqbank(struct gpio_bank *bank, int gpio_mask)
-{
-	void __iomem *reg = bank->base;
-
-	switch (bank->method) {
-#ifdef CONFIG_ARCH_OMAP1
-	case METHOD_MPUIO:
-		/* MPUIO irqstatus is reset by reading the status register,
-		 * so do nothing here */
-		return;
-#endif
-#ifdef CONFIG_ARCH_OMAP15XX
-	case METHOD_GPIO_1510:
-		reg += OMAP1510_GPIO_INT_STATUS;
-		break;
-#endif
-#ifdef CONFIG_ARCH_OMAP16XX
-	case METHOD_GPIO_1610:
-		reg += OMAP1610_GPIO_IRQSTATUS1;
-		break;
-#endif
-#if defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP850)
-	case METHOD_GPIO_7XX:
-		reg += OMAP7XX_GPIO_INT_STATUS;
-		break;
-#endif
-#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_44XX:
-		reg += OMAP4_GPIO_IRQSTATUS0;
-		break;
-#endif
-	default:
-		WARN_ON(1);
-		return;
-	}
-	__raw_writel(gpio_mask, reg);
-
-	/* Workaround for clearing DSP GPIO interrupts to allow retention */
-	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);
-
-	/* Flush posted write for the irq status to avoid spurious interrupts */
-	__raw_readl(reg);
-	}
-}
-
-static inline void _clear_gpio_irqstatus(struct gpio_bank *bank, int gpio)
-{
-	_clear_gpio_irqbank(bank, 1 << get_gpio_index(gpio));
-}
-
-static u32 _get_gpio_irqbank_mask(struct gpio_bank *bank)
-{
-	void __iomem *reg = bank->base;
-	int inv = 0;
-	u32 l;
-	u32 mask;
-
-	switch (bank->method) {
-#ifdef CONFIG_ARCH_OMAP1
-	case METHOD_MPUIO:
-		reg += OMAP_MPUIO_GPIO_MASKIT / bank->stride;
-		mask = 0xffff;
-		inv = 1;
-		break;
-#endif
-#ifdef CONFIG_ARCH_OMAP15XX
-	case METHOD_GPIO_1510:
-		reg += OMAP1510_GPIO_INT_MASK;
-		mask = 0xffff;
-		inv = 1;
-		break;
-#endif
-#ifdef CONFIG_ARCH_OMAP16XX
-	case METHOD_GPIO_1610:
-		reg += OMAP1610_GPIO_IRQENABLE1;
-		mask = 0xffff;
-		break;
-#endif
-#if defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP850)
-	case METHOD_GPIO_7XX:
-		reg += OMAP7XX_GPIO_INT_MASK;
-		mask = 0xffffffff;
-		inv = 1;
-		break;
-#endif
-#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_44XX:
-		reg += OMAP4_GPIO_IRQSTATUSSET0;
-		mask = 0xffffffff;
-		break;
-#endif
-	default:
-		WARN_ON(1);
-		return 0;
-	}
-
-	l = __raw_readl(reg);
-	if (inv)
-		l = ~l;
-	l &= mask;
-	return l;
-}
-
-static void _enable_gpio_irqbank(struct gpio_bank *bank, int gpio_mask, int enable)
-{
-	void __iomem *reg = bank->base;
-	u32 l;
-
-	switch (bank->method) {
-#ifdef CONFIG_ARCH_OMAP1
-	case METHOD_MPUIO:
-		reg += OMAP_MPUIO_GPIO_MASKIT / bank->stride;
-		l = __raw_readl(reg);
-		if (enable)
-			l &= ~(gpio_mask);
-		else
-			l |= gpio_mask;
-		break;
-#endif
-#ifdef CONFIG_ARCH_OMAP15XX
-	case METHOD_GPIO_1510:
-		reg += OMAP1510_GPIO_INT_MASK;
-		l = __raw_readl(reg);
-		if (enable)
-			l &= ~(gpio_mask);
-		else
-			l |= gpio_mask;
-		break;
-#endif
-#ifdef CONFIG_ARCH_OMAP16XX
-	case METHOD_GPIO_1610:
-		if (enable)
-			reg += OMAP1610_GPIO_SET_IRQENABLE1;
-		else
-			reg += OMAP1610_GPIO_CLEAR_IRQENABLE1;
-		l = gpio_mask;
-		break;
-#endif
-#if defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP850)
-	case METHOD_GPIO_7XX:
-		reg += OMAP7XX_GPIO_INT_MASK;
-		l = __raw_readl(reg);
-		if (enable)
-			l &= ~(gpio_mask);
-		else
-			l |= gpio_mask;
-		break;
-#endif
-#if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3)
-	case METHOD_GPIO_24XX:
-		if (enable)
-			reg += OMAP24XX_GPIO_SETIRQENABLE1;
-		else
-			reg += OMAP24XX_GPIO_CLEARIRQENABLE1;
-		l = gpio_mask;
-		break;
-#endif
-#ifdef CONFIG_ARCH_OMAP4
-	case METHOD_GPIO_44XX:
-		if (enable)
-			reg += OMAP4_GPIO_IRQSTATUSSET0;
-		else
-			reg += OMAP4_GPIO_IRQSTATUSCLR0;
-		l = gpio_mask;
-		break;
-#endif
-	default:
-		WARN_ON(1);
-		return;
-	}
-	__raw_writel(l, reg);
-}
-
-static inline void _set_gpio_irqenable(struct gpio_bank *bank, int gpio, int enable)
-{
-	_enable_gpio_irqbank(bank, 1 << get_gpio_index(gpio), enable);
-}
-
-/*
- * Note that ENAWAKEUP needs to be enabled in GPIO_SYSCONFIG register.
- * 1510 does not seem to have a wake-up register. If JTAG is connected
- * to the target, system will wake up always on GPIO events. While
- * system is running all registered GPIO interrupts need to have wake-up
- * enabled. When system is suspended, only selected GPIO interrupts need
- * to have wake-up enabled.
- */
-static int _set_gpio_wakeup(struct gpio_bank *bank, int gpio, int enable)
-{
-	unsigned long uninitialized_var(flags);
-
-	switch (bank->method) {
-#ifdef CONFIG_ARCH_OMAP16XX
-	case METHOD_MPUIO:
-	case METHOD_GPIO_1610:
-		spin_lock_irqsave(&bank->lock, flags);
-		if (enable)
-			bank->suspend_wakeup |= (1 << gpio);
-		else
-			bank->suspend_wakeup &= ~(1 << gpio);
-		spin_unlock_irqrestore(&bank->lock, flags);
-		return 0;
-#endif
-#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",
-					(bank - gpio_bank) * 32 + gpio);
-			return -EINVAL;
-		}
-		spin_lock_irqsave(&bank->lock, flags);
-		if (enable)
-			bank->suspend_wakeup |= (1 << gpio);
-		else
-			bank->suspend_wakeup &= ~(1 << gpio);
-		spin_unlock_irqrestore(&bank->lock, flags);
-		return 0;
-#endif
-	default:
-		printk(KERN_ERR "Can't enable GPIO wakeup for method %i\n",
-		       bank->method);
-		return -EINVAL;
-	}
-}
-
-static void _reset_gpio(struct gpio_bank *bank, int gpio)
-{
-	_set_gpio_direction(bank, get_gpio_index(gpio), 1);
-	_set_gpio_irqenable(bank, gpio, 0);
-	_clear_gpio_irqstatus(bank, gpio);
-	_set_gpio_triggering(bank, get_gpio_index(gpio), IRQ_TYPE_NONE);
-}
-
-/* Use disable_irq_wake() and enable_irq_wake() functions from drivers */
-static int gpio_wake_enable(struct irq_data *d, unsigned int enable)
-{
-	unsigned int gpio = d->irq - IH_GPIO_BASE;
-	struct gpio_bank *bank;
-	int retval;
-
-	if (check_gpio(gpio) < 0)
-		return -ENODEV;
-	bank = irq_data_get_irq_chip_data(d);
-	retval = _set_gpio_wakeup(bank, get_gpio_index(gpio), enable);
-
-	return retval;
-}
-
-static int omap_gpio_request(struct gpio_chip *chip, unsigned offset)
-{
-	struct gpio_bank *bank = container_of(chip, struct gpio_bank, chip);
-	unsigned long flags;
-
-	spin_lock_irqsave(&bank->lock, flags);
-
-	/* Set trigger to none. You need to enable the desired trigger with
-	 * request_irq() or set_irq_type().
-	 */
-	_set_gpio_triggering(bank, offset, IRQ_TYPE_NONE);
-
-#ifdef CONFIG_ARCH_OMAP15XX
-	if (bank->method == METHOD_GPIO_1510) {
-		void __iomem *reg;
-
-		/* Claim the pin for MPU */
-		reg = bank->base + OMAP1510_GPIO_PIN_CONTROL;
-		__raw_writel(__raw_readl(reg) | (1 << offset), reg);
-	}
-#endif
-	if (!cpu_class_is_omap1()) {
-		if (!bank->mod_usage) {
-			void __iomem *reg = bank->base;
-			u32 ctrl;
-
-			if (cpu_is_omap24xx() || cpu_is_omap34xx())
-				reg += OMAP24XX_GPIO_CTRL;
-			else if (cpu_is_omap44xx())
-				reg += OMAP4_GPIO_CTRL;
-			ctrl = __raw_readl(reg);
-			/* Module is enabled, clocks are not gated */
-			ctrl &= 0xFFFFFFFE;
-			__raw_writel(ctrl, reg);
-		}
-		bank->mod_usage |= 1 << offset;
-	}
-	spin_unlock_irqrestore(&bank->lock, flags);
-
-	return 0;
-}
-
-static void omap_gpio_free(struct gpio_chip *chip, unsigned offset)
-{
-	struct gpio_bank *bank = container_of(chip, struct gpio_bank, chip);
-	unsigned long flags;
-
-	spin_lock_irqsave(&bank->lock, flags);
-#ifdef CONFIG_ARCH_OMAP16XX
-	if (bank->method == METHOD_GPIO_1610) {
-		/* Disable wake-up during idle for dynamic tick */
-		void __iomem *reg = bank->base + OMAP1610_GPIO_CLEAR_WAKEUPENA;
-		__raw_writel(1 << offset, reg);
-	}
-#endif
-#if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3)
-	if (bank->method == METHOD_GPIO_24XX) {
-		/* Disable wake-up during idle for dynamic tick */
-		void __iomem *reg = bank->base + OMAP24XX_GPIO_CLEARWKUENA;
-		__raw_writel(1 << offset, reg);
-	}
-#endif
-#ifdef CONFIG_ARCH_OMAP4
-	if (bank->method == METHOD_GPIO_44XX) {
-		/* Disable wake-up during idle for dynamic tick */
-		void __iomem *reg = bank->base + OMAP4_GPIO_IRQWAKEN0;
-		__raw_writel(1 << offset, reg);
-	}
-#endif
-	if (!cpu_class_is_omap1()) {
-		bank->mod_usage &= ~(1 << offset);
-		if (!bank->mod_usage) {
-			void __iomem *reg = bank->base;
-			u32 ctrl;
-
-			if (cpu_is_omap24xx() || cpu_is_omap34xx())
-				reg += OMAP24XX_GPIO_CTRL;
-			else if (cpu_is_omap44xx())
-				reg += OMAP4_GPIO_CTRL;
-			ctrl = __raw_readl(reg);
-			/* Module is disabled, clocks are gated */
-			ctrl |= 1;
-			__raw_writel(ctrl, reg);
-		}
-	}
-	_reset_gpio(bank, bank->chip.base + offset);
-	spin_unlock_irqrestore(&bank->lock, flags);
-}
-
-/*
- * We need to unmask the GPIO bank interrupt as soon as possible to
- * avoid missing GPIO interrupts for other lines in the bank.
- * Then we need to mask-read-clear-unmask the triggered GPIO lines
- * in the bank to avoid missing nested interrupts for a GPIO line.
- * If we wait to unmask individual GPIO lines in the bank after the
- * line's interrupt handler has been run, we may miss some nested
- * interrupts.
- */
-static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
-{
-	void __iomem *isr_reg = NULL;
-	u32 isr;
-	unsigned int gpio_irq, gpio_index;
-	struct gpio_bank *bank;
-	u32 retrigger = 0;
-	int unmasked = 0;
-
-	desc->irq_data.chip->irq_ack(&desc->irq_data);
-
-	bank = irq_get_handler_data(irq);
-#ifdef CONFIG_ARCH_OMAP1
-	if (bank->method == METHOD_MPUIO)
-		isr_reg = bank->base +
-				OMAP_MPUIO_GPIO_INT / bank->stride;
-#endif
-#ifdef CONFIG_ARCH_OMAP15XX
-	if (bank->method == METHOD_GPIO_1510)
-		isr_reg = bank->base + OMAP1510_GPIO_INT_STATUS;
-#endif
-#if defined(CONFIG_ARCH_OMAP16XX)
-	if (bank->method == METHOD_GPIO_1610)
-		isr_reg = bank->base + OMAP1610_GPIO_IRQSTATUS1;
-#endif
-#if defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP850)
-	if (bank->method == METHOD_GPIO_7XX)
-		isr_reg = bank->base + OMAP7XX_GPIO_INT_STATUS;
-#endif
-#if defined(CONFIG_ARCH_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_44XX)
-		isr_reg = bank->base + OMAP4_GPIO_IRQSTATUS0;
-#endif
-
-	if (WARN_ON(!isr_reg))
-		goto exit;
-
-	while(1) {
-		u32 isr_saved, level_mask = 0;
-		u32 enabled;
-
-		enabled = _get_gpio_irqbank_mask(bank);
-		isr_saved = isr = __raw_readl(isr_reg) & enabled;
-
-		if (cpu_is_omap15xx() && (bank->method == METHOD_MPUIO))
-			isr &= 0x0000ffff;
-
-		if (cpu_class_is_omap2()) {
-			level_mask = bank->level_mask & enabled;
-		}
-
-		/* clear edge sensitive interrupts before handler(s) are
-		called so that we don't miss any interrupt occurred while
-		executing them */
-		_enable_gpio_irqbank(bank, isr_saved & ~level_mask, 0);
-		_clear_gpio_irqbank(bank, isr_saved & ~level_mask);
-		_enable_gpio_irqbank(bank, isr_saved & ~level_mask, 1);
-
-		/* if there is only edge sensitive GPIO pin interrupts
-		configured, we could unmask GPIO bank interrupt immediately */
-		if (!level_mask && !unmasked) {
-			unmasked = 1;
-			desc->irq_data.chip->irq_unmask(&desc->irq_data);
-		}
-
-		isr |= retrigger;
-		retrigger = 0;
-		if (!isr)
-			break;
-
-		gpio_irq = bank->virtual_irq_start;
-		for (; isr != 0; isr >>= 1, gpio_irq++) {
-			gpio_index = get_gpio_index(irq_to_gpio(gpio_irq));
-
-			if (!(isr & 1))
-				continue;
-
-#ifdef CONFIG_ARCH_OMAP1
-			/*
-			 * Some chips can't respond to both rising and falling
-			 * at the same time.  If this irq was requested with
-			 * both flags, we need to flip the ICR data for the IRQ
-			 * to respond to the IRQ for the opposite direction.
-			 * This will be indicated in the bank toggle_mask.
-			 */
-			if (bank->toggle_mask & (1 << gpio_index))
-				_toggle_gpio_edge_triggering(bank, gpio_index);
-#endif
-
-			generic_handle_irq(gpio_irq);
-		}
-	}
-	/* if bank has any level sensitive GPIO pin interrupt
-	configured, we must unmask the bank interrupt only after
-	handler(s) are executed in order to avoid spurious bank
-	interrupt */
-exit:
-	if (!unmasked)
-		desc->irq_data.chip->irq_unmask(&desc->irq_data);
-}
-
-static void gpio_irq_shutdown(struct irq_data *d)
-{
-	unsigned int gpio = d->irq - IH_GPIO_BASE;
-	struct gpio_bank *bank = irq_data_get_irq_chip_data(d);
-
-	_reset_gpio(bank, gpio);
-}
-
-static void gpio_ack_irq(struct irq_data *d)
-{
-	unsigned int gpio = d->irq - IH_GPIO_BASE;
-	struct gpio_bank *bank = irq_data_get_irq_chip_data(d);
-
-	_clear_gpio_irqstatus(bank, gpio);
-}
-
-static void gpio_mask_irq(struct irq_data *d)
-{
-	unsigned int gpio = d->irq - IH_GPIO_BASE;
-	struct gpio_bank *bank = irq_data_get_irq_chip_data(d);
-
-	_set_gpio_irqenable(bank, gpio, 0);
-	_set_gpio_triggering(bank, get_gpio_index(gpio), IRQ_TYPE_NONE);
-}
-
-static void gpio_unmask_irq(struct irq_data *d)
-{
-	unsigned int gpio = d->irq - IH_GPIO_BASE;
-	struct gpio_bank *bank = irq_data_get_irq_chip_data(d);
-	unsigned int irq_mask = 1 << get_gpio_index(gpio);
-	u32 trigger = irqd_get_trigger_type(d);
-
-	if (trigger)
-		_set_gpio_triggering(bank, get_gpio_index(gpio), trigger);
-
-	/* For level-triggered GPIOs, the clearing must be done after
-	 * the HW source is cleared, thus after the handler has run */
-	if (bank->level_mask & irq_mask) {
-		_set_gpio_irqenable(bank, gpio, 0);
-		_clear_gpio_irqstatus(bank, gpio);
-	}
-
-	_set_gpio_irqenable(bank, gpio, 1);
-}
-
-static struct irq_chip gpio_irq_chip = {
-	.name		= "GPIO",
-	.irq_shutdown	= gpio_irq_shutdown,
-	.irq_ack	= gpio_ack_irq,
-	.irq_mask	= gpio_mask_irq,
-	.irq_unmask	= gpio_unmask_irq,
-	.irq_set_type	= gpio_irq_type,
-	.irq_set_wake	= gpio_wake_enable,
-};
-
-/*---------------------------------------------------------------------*/
-
-#ifdef CONFIG_ARCH_OMAP1
-
-/* MPUIO uses the always-on 32k clock */
-
-static void mpuio_ack_irq(struct irq_data *d)
-{
-	/* The ISR is reset automatically, so do nothing here. */
-}
-
-static void mpuio_mask_irq(struct irq_data *d)
-{
-	unsigned int gpio = OMAP_MPUIO(d->irq - IH_MPUIO_BASE);
-	struct gpio_bank *bank = irq_data_get_irq_chip_data(d);
-
-	_set_gpio_irqenable(bank, gpio, 0);
-}
-
-static void mpuio_unmask_irq(struct irq_data *d)
-{
-	unsigned int gpio = OMAP_MPUIO(d->irq - IH_MPUIO_BASE);
-	struct gpio_bank *bank = irq_data_get_irq_chip_data(d);
-
-	_set_gpio_irqenable(bank, gpio, 1);
-}
-
-static struct irq_chip mpuio_irq_chip = {
-	.name		= "MPUIO",
-	.irq_ack	= mpuio_ack_irq,
-	.irq_mask	= mpuio_mask_irq,
-	.irq_unmask	= mpuio_unmask_irq,
-	.irq_set_type	= gpio_irq_type,
-#ifdef CONFIG_ARCH_OMAP16XX
-	/* REVISIT: assuming only 16xx supports MPUIO wake events */
-	.irq_set_wake	= gpio_wake_enable,
-#endif
-};
-
-
-#define bank_is_mpuio(bank)	((bank)->method == METHOD_MPUIO)
-
-
-#ifdef CONFIG_ARCH_OMAP16XX
-
-#include <linux/platform_device.h>
-
-static int omap_mpuio_suspend_noirq(struct device *dev)
-{
-	struct platform_device *pdev = to_platform_device(dev);
-	struct gpio_bank	*bank = platform_get_drvdata(pdev);
-	void __iomem		*mask_reg = bank->base +
-					OMAP_MPUIO_GPIO_MASKIT / bank->stride;
-	unsigned long		flags;
-
-	spin_lock_irqsave(&bank->lock, flags);
-	bank->saved_wakeup = __raw_readl(mask_reg);
-	__raw_writel(0xffff & ~bank->suspend_wakeup, mask_reg);
-	spin_unlock_irqrestore(&bank->lock, flags);
-
-	return 0;
-}
-
-static int omap_mpuio_resume_noirq(struct device *dev)
-{
-	struct platform_device *pdev = to_platform_device(dev);
-	struct gpio_bank	*bank = platform_get_drvdata(pdev);
-	void __iomem		*mask_reg = bank->base +
-					OMAP_MPUIO_GPIO_MASKIT / bank->stride;
-	unsigned long		flags;
-
-	spin_lock_irqsave(&bank->lock, flags);
-	__raw_writel(bank->saved_wakeup, mask_reg);
-	spin_unlock_irqrestore(&bank->lock, flags);
-
-	return 0;
-}
-
-static const struct dev_pm_ops omap_mpuio_dev_pm_ops = {
-	.suspend_noirq = omap_mpuio_suspend_noirq,
-	.resume_noirq = omap_mpuio_resume_noirq,
-};
-
-/* use platform_driver for this, now that there's no longer any
- * point to sys_device (other than not disturbing old code).
- */
-static struct platform_driver omap_mpuio_driver = {
-	.driver		= {
-		.name	= "mpuio",
-		.pm	= &omap_mpuio_dev_pm_ops,
-	},
-};
-
-static struct platform_device omap_mpuio_device = {
-	.name		= "mpuio",
-	.id		= -1,
-	.dev = {
-		.driver = &omap_mpuio_driver.driver,
-	}
-	/* could list the /proc/iomem resources */
-};
-
-static inline void mpuio_init(void)
-{
-	struct gpio_bank *bank = get_gpio_bank(OMAP_MPUIO(0));
-	platform_set_drvdata(&omap_mpuio_device, bank);
-
-	if (platform_driver_register(&omap_mpuio_driver) == 0)
-		(void) platform_device_register(&omap_mpuio_device);
-}
-
-#else
-static inline void mpuio_init(void) {}
-#endif	/* 16xx */
-
-#else
-
-extern struct irq_chip mpuio_irq_chip;
-
-#define bank_is_mpuio(bank)	0
-static inline void mpuio_init(void) {}
-
-#endif
-
-/*---------------------------------------------------------------------*/
-
-/* REVISIT these are stupid implementations!  replace by ones that
- * don't switch on METHOD_* and which mostly avoid spinlocks
- */
-
-static int gpio_input(struct gpio_chip *chip, unsigned offset)
-{
-	struct gpio_bank *bank;
-	unsigned long flags;
-
-	bank = container_of(chip, struct gpio_bank, chip);
-	spin_lock_irqsave(&bank->lock, flags);
-	_set_gpio_direction(bank, offset, 1);
-	spin_unlock_irqrestore(&bank->lock, flags);
-	return 0;
-}
-
-static int gpio_is_input(struct gpio_bank *bank, int mask)
-{
-	void __iomem *reg = bank->base;
-
-	switch (bank->method) {
-	case METHOD_MPUIO:
-		reg += OMAP_MPUIO_IO_CNTL / bank->stride;
-		break;
-	case METHOD_GPIO_1510:
-		reg += OMAP1510_GPIO_DIR_CONTROL;
-		break;
-	case METHOD_GPIO_1610:
-		reg += OMAP1610_GPIO_DIRECTION;
-		break;
-	case METHOD_GPIO_7XX:
-		reg += OMAP7XX_GPIO_DIR_CONTROL;
-		break;
-	case METHOD_GPIO_24XX:
-		reg += OMAP24XX_GPIO_OE;
-		break;
-	case METHOD_GPIO_44XX:
-		reg += OMAP4_GPIO_OE;
-		break;
-	default:
-		WARN_ONCE(1, "gpio_is_input: incorrect OMAP GPIO method");
-		return -EINVAL;
-	}
-	return __raw_readl(reg) & mask;
-}
-
-static int gpio_get(struct gpio_chip *chip, unsigned offset)
-{
-	struct gpio_bank *bank;
-	void __iomem *reg;
-	int gpio;
-	u32 mask;
-
-	gpio = chip->base + offset;
-	bank = get_gpio_bank(gpio);
-	reg = bank->base;
-	mask = 1 << get_gpio_index(gpio);
-
-	if (gpio_is_input(bank, mask))
-		return _get_gpio_datain(bank, gpio);
-	else
-		return _get_gpio_dataout(bank, gpio);
-}
-
-static int gpio_output(struct gpio_chip *chip, unsigned offset, int value)
-{
-	struct gpio_bank *bank;
-	unsigned long flags;
-
-	bank = container_of(chip, struct gpio_bank, chip);
-	spin_lock_irqsave(&bank->lock, flags);
-	_set_gpio_dataout(bank, offset, value);
-	_set_gpio_direction(bank, offset, 0);
-	spin_unlock_irqrestore(&bank->lock, flags);
-	return 0;
-}
-
-static int gpio_debounce(struct gpio_chip *chip, unsigned offset,
-		unsigned debounce)
-{
-	struct gpio_bank *bank;
-	unsigned long flags;
-
-	bank = container_of(chip, struct gpio_bank, chip);
-
-	if (!bank->dbck) {
-		bank->dbck = clk_get(bank->dev, "dbclk");
-		if (IS_ERR(bank->dbck))
-			dev_err(bank->dev, "Could not get gpio dbck\n");
-	}
-
-	spin_lock_irqsave(&bank->lock, flags);
-	_set_gpio_debounce(bank, offset, debounce);
-	spin_unlock_irqrestore(&bank->lock, flags);
-
-	return 0;
-}
-
-static void gpio_set(struct gpio_chip *chip, unsigned offset, int value)
-{
-	struct gpio_bank *bank;
-	unsigned long flags;
-
-	bank = container_of(chip, struct gpio_bank, chip);
-	spin_lock_irqsave(&bank->lock, flags);
-	_set_gpio_dataout(bank, offset, value);
-	spin_unlock_irqrestore(&bank->lock, flags);
-}
-
-static int gpio_2irq(struct gpio_chip *chip, unsigned offset)
-{
-	struct gpio_bank *bank;
-
-	bank = container_of(chip, struct gpio_bank, chip);
-	return bank->virtual_irq_start + offset;
-}
-
-/*---------------------------------------------------------------------*/
-
-static void __init omap_gpio_show_rev(struct gpio_bank *bank)
-{
-	u32 rev;
-
-	if (cpu_is_omap16xx() && !(bank->method != METHOD_MPUIO))
-		rev = __raw_readw(bank->base + OMAP1610_GPIO_REVISION);
-	else if (cpu_is_omap24xx() || cpu_is_omap34xx())
-		rev = __raw_readl(bank->base + OMAP24XX_GPIO_REVISION);
-	else if (cpu_is_omap44xx())
-		rev = __raw_readl(bank->base + OMAP4_GPIO_REVISION);
-	else
-		return;
-
-	printk(KERN_INFO "OMAP GPIO hardware version %d.%d\n",
-		(rev >> 4) & 0x0f, rev & 0x0f);
-}
-
-/* This lock class tells lockdep that GPIO irqs are in a different
- * category than their parents, so it won't report false recursion.
- */
-static struct lock_class_key gpio_lock_class;
-
-static inline int init_gpio_info(struct platform_device *pdev)
-{
-	/* TODO: Analyze removing gpio_bank_count usage from driver code */
-	gpio_bank = kzalloc(gpio_bank_count * sizeof(struct gpio_bank),
-				GFP_KERNEL);
-	if (!gpio_bank) {
-		dev_err(&pdev->dev, "Memory alloc failed for gpio_bank\n");
-		return -ENOMEM;
-	}
-	return 0;
-}
-
-/* TODO: Cleanup cpu_is_* checks */
-static void omap_gpio_mod_init(struct gpio_bank *bank, int id)
-{
-	if (cpu_class_is_omap2()) {
-		if (cpu_is_omap44xx()) {
-			__raw_writel(0xffffffff, bank->base +
-					OMAP4_GPIO_IRQSTATUSCLR0);
-			__raw_writel(0x00000000, bank->base +
-					 OMAP4_GPIO_DEBOUNCENABLE);
-			/* Initialize interface clk ungated, module enabled */
-			__raw_writel(0, bank->base + OMAP4_GPIO_CTRL);
-		} else if (cpu_is_omap34xx()) {
-			__raw_writel(0x00000000, bank->base +
-					OMAP24XX_GPIO_IRQENABLE1);
-			__raw_writel(0xffffffff, bank->base +
-					OMAP24XX_GPIO_IRQSTATUS1);
-			__raw_writel(0x00000000, bank->base +
-					OMAP24XX_GPIO_DEBOUNCE_EN);
-
-			/* Initialize interface clk ungated, module enabled */
-			__raw_writel(0, bank->base + OMAP24XX_GPIO_CTRL);
-		} else if (cpu_is_omap24xx()) {
-			static const u32 non_wakeup_gpios[] = {
-				0xe203ffc0, 0x08700040
-			};
-			if (id < ARRAY_SIZE(non_wakeup_gpios))
-				bank->non_wakeup_gpios = non_wakeup_gpios[id];
-		}
-	} else if (cpu_class_is_omap1()) {
-		if (bank_is_mpuio(bank))
-			__raw_writew(0xffff, bank->base +
-				OMAP_MPUIO_GPIO_MASKIT / bank->stride);
-		if (cpu_is_omap15xx() && bank->method == METHOD_GPIO_1510) {
-			__raw_writew(0xffff, bank->base
-						+ OMAP1510_GPIO_INT_MASK);
-			__raw_writew(0x0000, bank->base
-						+ OMAP1510_GPIO_INT_STATUS);
-		}
-		if (cpu_is_omap16xx() && bank->method == METHOD_GPIO_1610) {
-			__raw_writew(0x0000, bank->base
-						+ OMAP1610_GPIO_IRQENABLE1);
-			__raw_writew(0xffff, bank->base
-						+ OMAP1610_GPIO_IRQSTATUS1);
-			__raw_writew(0x0014, bank->base
-						+ OMAP1610_GPIO_SYSCONFIG);
-
-			/*
-			 * Enable system clock for GPIO module.
-			 * The CAM_CLK_CTRL *is* really the right place.
-			 */
-			omap_writel(omap_readl(ULPD_CAM_CLK_CTRL) | 0x04,
-						ULPD_CAM_CLK_CTRL);
-		}
-		if (cpu_is_omap7xx() && bank->method == METHOD_GPIO_7XX) {
-			__raw_writel(0xffffffff, bank->base
-						+ OMAP7XX_GPIO_INT_MASK);
-			__raw_writel(0x00000000, bank->base
-						+ OMAP7XX_GPIO_INT_STATUS);
-		}
-	}
-}
-
-static void __init omap_gpio_chip_init(struct gpio_bank *bank)
-{
-	int j;
-	static int gpio;
-
-	bank->mod_usage = 0;
-	/*
-	 * REVISIT eventually switch from OMAP-specific gpio structs
-	 * over to the generic ones
-	 */
-	bank->chip.request = omap_gpio_request;
-	bank->chip.free = omap_gpio_free;
-	bank->chip.direction_input = gpio_input;
-	bank->chip.get = gpio_get;
-	bank->chip.direction_output = gpio_output;
-	bank->chip.set_debounce = gpio_debounce;
-	bank->chip.set = gpio_set;
-	bank->chip.to_irq = gpio_2irq;
-	if (bank_is_mpuio(bank)) {
-		bank->chip.label = "mpuio";
-#ifdef CONFIG_ARCH_OMAP16XX
-		bank->chip.dev = &omap_mpuio_device.dev;
-#endif
-		bank->chip.base = OMAP_MPUIO(0);
-	} else {
-		bank->chip.label = "gpio";
-		bank->chip.base = gpio;
-		gpio += bank_width;
-	}
-	bank->chip.ngpio = bank_width;
-
-	gpiochip_add(&bank->chip);
-
-	for (j = bank->virtual_irq_start;
-		     j < bank->virtual_irq_start + bank_width; j++) {
-		irq_set_lockdep_class(j, &gpio_lock_class);
-		irq_set_chip_data(j, bank);
-		if (bank_is_mpuio(bank))
-			irq_set_chip(j, &mpuio_irq_chip);
-		else
-			irq_set_chip(j, &gpio_irq_chip);
-		irq_set_handler(j, handle_simple_irq);
-		set_irq_flags(j, IRQF_VALID);
-	}
-	irq_set_chained_handler(bank->irq, gpio_irq_handler);
-	irq_set_handler_data(bank->irq, bank);
-}
-
-static int __devinit omap_gpio_probe(struct platform_device *pdev)
-{
-	static int gpio_init_done;
-	struct omap_gpio_platform_data *pdata;
-	struct resource *res;
-	int id;
-	struct gpio_bank *bank;
-
-	if (!pdev->dev.platform_data)
-		return -EINVAL;
-
-	pdata = pdev->dev.platform_data;
-
-	if (!gpio_init_done) {
-		int ret;
-
-		ret = init_gpio_info(pdev);
-		if (ret)
-			return ret;
-	}
-
-	id = pdev->id;
-	bank = &gpio_bank[id];
-
-	res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
-	if (unlikely(!res)) {
-		dev_err(&pdev->dev, "GPIO Bank %i Invalid IRQ resource\n", id);
-		return -ENODEV;
-	}
-
-	bank->irq = res->start;
-	bank->virtual_irq_start = pdata->virtual_irq_start;
-	bank->method = pdata->bank_type;
-	bank->dev = &pdev->dev;
-	bank->dbck_flag = pdata->dbck_flag;
-	bank->stride = pdata->bank_stride;
-	bank_width = pdata->bank_width;
-
-	spin_lock_init(&bank->lock);
-
-	/* Static mapping, never released */
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	if (unlikely(!res)) {
-		dev_err(&pdev->dev, "GPIO Bank %i Invalid mem resource\n", id);
-		return -ENODEV;
-	}
-
-	bank->base = ioremap(res->start, resource_size(res));
-	if (!bank->base) {
-		dev_err(&pdev->dev, "Could not ioremap gpio bank%i\n", id);
-		return -ENOMEM;
-	}
-
-	pm_runtime_enable(bank->dev);
-	pm_runtime_get_sync(bank->dev);
-
-	omap_gpio_mod_init(bank, id);
-	omap_gpio_chip_init(bank);
-	omap_gpio_show_rev(bank);
-
-	if (!gpio_init_done)
-		gpio_init_done = 1;
-
-	return 0;
-}
-
-#if defined(CONFIG_ARCH_OMAP16XX) || defined(CONFIG_ARCH_OMAP2PLUS)
-static int omap_gpio_suspend(struct sys_device *dev, pm_message_t mesg)
-{
-	int i;
-
-	if (!cpu_class_is_omap2() && !cpu_is_omap16xx())
-		return 0;
-
-	for (i = 0; i < gpio_bank_count; i++) {
-		struct gpio_bank *bank = &gpio_bank[i];
-		void __iomem *wake_status;
-		void __iomem *wake_clear;
-		void __iomem *wake_set;
-		unsigned long flags;
-
-		switch (bank->method) {
-#ifdef CONFIG_ARCH_OMAP16XX
-		case METHOD_GPIO_1610:
-			wake_status = bank->base + OMAP1610_GPIO_WAKEUPENABLE;
-			wake_clear = bank->base + OMAP1610_GPIO_CLEAR_WAKEUPENA;
-			wake_set = bank->base + OMAP1610_GPIO_SET_WAKEUPENA;
-			break;
-#endif
-#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;
-			wake_set = bank->base + OMAP24XX_GPIO_SETWKUENA;
-			break;
-#endif
-#ifdef CONFIG_ARCH_OMAP4
-		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;
-			break;
-#endif
-		default:
-			continue;
-		}
-
-		spin_lock_irqsave(&bank->lock, flags);
-		bank->saved_wakeup = __raw_readl(wake_status);
-		__raw_writel(0xffffffff, wake_clear);
-		__raw_writel(bank->suspend_wakeup, wake_set);
-		spin_unlock_irqrestore(&bank->lock, flags);
-	}
-
-	return 0;
-}
-
-static int omap_gpio_resume(struct sys_device *dev)
-{
-	int i;
-
-	if (!cpu_class_is_omap2() && !cpu_is_omap16xx())
-		return 0;
-
-	for (i = 0; i < gpio_bank_count; i++) {
-		struct gpio_bank *bank = &gpio_bank[i];
-		void __iomem *wake_clear;
-		void __iomem *wake_set;
-		unsigned long flags;
-
-		switch (bank->method) {
-#ifdef CONFIG_ARCH_OMAP16XX
-		case METHOD_GPIO_1610:
-			wake_clear = bank->base + OMAP1610_GPIO_CLEAR_WAKEUPENA;
-			wake_set = bank->base + OMAP1610_GPIO_SET_WAKEUPENA;
-			break;
-#endif
-#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_44XX:
-			wake_clear = bank->base + OMAP4_GPIO_IRQWAKEN0;
-			wake_set = bank->base + OMAP4_GPIO_IRQWAKEN0;
-			break;
-#endif
-		default:
-			continue;
-		}
-
-		spin_lock_irqsave(&bank->lock, flags);
-		__raw_writel(0xffffffff, wake_clear);
-		__raw_writel(bank->saved_wakeup, wake_set);
-		spin_unlock_irqrestore(&bank->lock, flags);
-	}
-
-	return 0;
-}
-
-static struct sysdev_class omap_gpio_sysclass = {
-	.name		= "gpio",
-	.suspend	= omap_gpio_suspend,
-	.resume		= omap_gpio_resume,
-};
-
-static struct sys_device omap_gpio_device = {
-	.id		= 0,
-	.cls		= &omap_gpio_sysclass,
-};
-
-#endif
-
-#ifdef CONFIG_ARCH_OMAP2PLUS
-
-static int workaround_enabled;
-
-void omap2_gpio_prepare_for_idle(int off_mode)
-{
-	int i, c = 0;
-	int min = 0;
-
-	if (cpu_is_omap34xx())
-		min = 1;
-
-	for (i = min; i < gpio_bank_count; i++) {
-		struct gpio_bank *bank = &gpio_bank[i];
-		u32 l1 = 0, l2 = 0;
-		int j;
-
-		for (j = 0; j < hweight_long(bank->dbck_enable_mask); j++)
-			clk_disable(bank->dbck);
-
-		if (!off_mode)
-			continue;
-
-		/* If going to OFF, remove triggering for all
-		 * non-wakeup GPIOs.  Otherwise spurious IRQs will be
-		 * generated.  See OMAP2420 Errata item 1.101. */
-		if (!(bank->enabled_non_wakeup_gpios))
-			continue;
-
-		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 (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) {
-		workaround_enabled = 0;
-		return;
-	}
-	workaround_enabled = 1;
-}
-
-void omap2_gpio_resume_after_idle(void)
-{
-	int i;
-	int min = 0;
-
-	if (cpu_is_omap34xx())
-		min = 1;
-	for (i = min; i < gpio_bank_count; i++) {
-		struct gpio_bank *bank = &gpio_bank[i];
-		u32 l = 0, gen, gen0, gen1;
-		int j;
-
-		for (j = 0; j < hweight_long(bank->dbck_enable_mask); j++)
-			clk_enable(bank->dbck);
-
-		if (!workaround_enabled)
-			continue;
-
-		if (!(bank->enabled_non_wakeup_gpios))
-			continue;
-
-		if (cpu_is_omap24xx() || cpu_is_omap34xx()) {
-			__raw_writel(bank->saved_fallingdetect,
-				 bank->base + OMAP24XX_GPIO_FALLINGDETECT);
-			__raw_writel(bank->saved_risingdetect,
-				 bank->base + OMAP24XX_GPIO_RISINGDETECT);
-			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,
-				 bank->base + OMAP4_GPIO_RISINGDETECT);
-			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
-		 * this silicon bug. */
-		l ^= bank->saved_datain;
-		l &= bank->enabled_non_wakeup_gpios;
-
-		/*
-		 * No need to generate IRQs for the rising edge for gpio IRQs
-		 * configured with falling edge only; and vice versa.
-		 */
-		gen0 = l & bank->saved_fallingdetect;
-		gen0 &= bank->saved_datain;
-
-		gen1 = l & bank->saved_risingdetect;
-		gen1 &= ~(bank->saved_datain);
-
-		/* FIXME: Consider GPIO IRQs with level detections properly! */
-		gen = l & (~(bank->saved_fallingdetect) &
-				~(bank->saved_risingdetect));
-		/* Consider all GPIO IRQs needed to be updated */
-		gen |= gen0 | gen1;
-
-		if (gen) {
-			u32 old0, old1;
-
-			if (cpu_is_omap24xx() || cpu_is_omap34xx()) {
-				old0 = __raw_readl(bank->base +
-					OMAP24XX_GPIO_LEVELDETECT0);
-				old1 = __raw_readl(bank->base +
-					OMAP24XX_GPIO_LEVELDETECT1);
-				__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 +
-						OMAP4_GPIO_LEVELDETECT1);
-				__raw_writel(old0 | l, bank->base +
-						OMAP4_GPIO_LEVELDETECT0);
-				__raw_writel(old1 | l, bank->base +
-						OMAP4_GPIO_LEVELDETECT1);
-				__raw_writel(old0, bank->base +
-						OMAP4_GPIO_LEVELDETECT0);
-				__raw_writel(old1, bank->base +
-						OMAP4_GPIO_LEVELDETECT1);
-			}
-		}
-	}
-
-}
-
-#endif
-
-#ifdef CONFIG_ARCH_OMAP3
-/* save the registers of bank 2-6 */
-void omap_gpio_save_context(void)
-{
-	int i;
-
-	/* saving banks from 2-6 only since GPIO1 is in WKUP */
-	for (i = 1; i < gpio_bank_count; i++) {
-		struct gpio_bank *bank = &gpio_bank[i];
-		gpio_context[i].irqenable1 =
-			__raw_readl(bank->base + OMAP24XX_GPIO_IRQENABLE1);
-		gpio_context[i].irqenable2 =
-			__raw_readl(bank->base + OMAP24XX_GPIO_IRQENABLE2);
-		gpio_context[i].wake_en =
-			__raw_readl(bank->base + OMAP24XX_GPIO_WAKE_EN);
-		gpio_context[i].ctrl =
-			__raw_readl(bank->base + OMAP24XX_GPIO_CTRL);
-		gpio_context[i].oe =
-			__raw_readl(bank->base + OMAP24XX_GPIO_OE);
-		gpio_context[i].leveldetect0 =
-			__raw_readl(bank->base + OMAP24XX_GPIO_LEVELDETECT0);
-		gpio_context[i].leveldetect1 =
-			__raw_readl(bank->base + OMAP24XX_GPIO_LEVELDETECT1);
-		gpio_context[i].risingdetect =
-			__raw_readl(bank->base + OMAP24XX_GPIO_RISINGDETECT);
-		gpio_context[i].fallingdetect =
-			__raw_readl(bank->base + OMAP24XX_GPIO_FALLINGDETECT);
-		gpio_context[i].dataout =
-			__raw_readl(bank->base + OMAP24XX_GPIO_DATAOUT);
-	}
-}
-
-/* restore the required registers of bank 2-6 */
-void omap_gpio_restore_context(void)
-{
-	int i;
-
-	for (i = 1; i < gpio_bank_count; i++) {
-		struct gpio_bank *bank = &gpio_bank[i];
-		__raw_writel(gpio_context[i].irqenable1,
-				bank->base + OMAP24XX_GPIO_IRQENABLE1);
-		__raw_writel(gpio_context[i].irqenable2,
-				bank->base + OMAP24XX_GPIO_IRQENABLE2);
-		__raw_writel(gpio_context[i].wake_en,
-				bank->base + OMAP24XX_GPIO_WAKE_EN);
-		__raw_writel(gpio_context[i].ctrl,
-				bank->base + OMAP24XX_GPIO_CTRL);
-		__raw_writel(gpio_context[i].oe,
-				bank->base + OMAP24XX_GPIO_OE);
-		__raw_writel(gpio_context[i].leveldetect0,
-				bank->base + OMAP24XX_GPIO_LEVELDETECT0);
-		__raw_writel(gpio_context[i].leveldetect1,
-				bank->base + OMAP24XX_GPIO_LEVELDETECT1);
-		__raw_writel(gpio_context[i].risingdetect,
-				bank->base + OMAP24XX_GPIO_RISINGDETECT);
-		__raw_writel(gpio_context[i].fallingdetect,
-				bank->base + OMAP24XX_GPIO_FALLINGDETECT);
-		__raw_writel(gpio_context[i].dataout,
-				bank->base + OMAP24XX_GPIO_DATAOUT);
-	}
-}
-#endif
-
-static struct platform_driver omap_gpio_driver = {
-	.probe		= omap_gpio_probe,
-	.driver		= {
-		.name	= "omap_gpio",
-	},
-};
-
-/*
- * gpio driver register needs to be done before
- * machine_init functions access gpio APIs.
- * Hence omap_gpio_drv_reg() is a postcore_initcall.
- */
-static int __init omap_gpio_drv_reg(void)
-{
-	return platform_driver_register(&omap_gpio_driver);
-}
-postcore_initcall(omap_gpio_drv_reg);
-
-static int __init omap_gpio_sysinit(void)
-{
-	int ret = 0;
-
-	mpuio_init();
-
-#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);
-			if (ret == 0)
-				ret = sysdev_register(&omap_gpio_device);
-		}
-	}
-#endif
-
-	return ret;
-}
-
-arch_initcall(omap_gpio_sysinit);
diff -druN linux-2.6.39-libre/arch/arm/plat-omap/include/plat/display.h linux-3.0-rc7-libre/arch/arm/plat-omap/include/plat/display.h
--- linux-2.6.39-libre/arch/arm/plat-omap/include/plat/display.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/plat-omap/include/plat/display.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,591 +0,0 @@
-/*
- * linux/include/asm-arm/arch-omap/display.h
- *
- * Copyright (C) 2008 Nokia Corporation
- * Author: Tomi Valkeinen <tomi.valkeinen@nokia.com>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 as published by
- * the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef __ASM_ARCH_OMAP_DISPLAY_H
-#define __ASM_ARCH_OMAP_DISPLAY_H
-
-#include <linux/list.h>
-#include <linux/kobject.h>
-#include <linux/device.h>
-#include <linux/platform_device.h>
-#include <asm/atomic.h>
-
-#define DISPC_IRQ_FRAMEDONE		(1 << 0)
-#define DISPC_IRQ_VSYNC			(1 << 1)
-#define DISPC_IRQ_EVSYNC_EVEN		(1 << 2)
-#define DISPC_IRQ_EVSYNC_ODD		(1 << 3)
-#define DISPC_IRQ_ACBIAS_COUNT_STAT	(1 << 4)
-#define DISPC_IRQ_PROG_LINE_NUM		(1 << 5)
-#define DISPC_IRQ_GFX_FIFO_UNDERFLOW	(1 << 6)
-#define DISPC_IRQ_GFX_END_WIN		(1 << 7)
-#define DISPC_IRQ_PAL_GAMMA_MASK	(1 << 8)
-#define DISPC_IRQ_OCP_ERR		(1 << 9)
-#define DISPC_IRQ_VID1_FIFO_UNDERFLOW	(1 << 10)
-#define DISPC_IRQ_VID1_END_WIN		(1 << 11)
-#define DISPC_IRQ_VID2_FIFO_UNDERFLOW	(1 << 12)
-#define DISPC_IRQ_VID2_END_WIN		(1 << 13)
-#define DISPC_IRQ_SYNC_LOST		(1 << 14)
-#define DISPC_IRQ_SYNC_LOST_DIGIT	(1 << 15)
-#define DISPC_IRQ_WAKEUP		(1 << 16)
-#define DISPC_IRQ_SYNC_LOST2		(1 << 17)
-#define DISPC_IRQ_VSYNC2		(1 << 18)
-#define DISPC_IRQ_ACBIAS_COUNT_STAT2	(1 << 21)
-#define DISPC_IRQ_FRAMEDONE2		(1 << 22)
-
-struct omap_dss_device;
-struct omap_overlay_manager;
-
-enum omap_display_type {
-	OMAP_DISPLAY_TYPE_NONE		= 0,
-	OMAP_DISPLAY_TYPE_DPI		= 1 << 0,
-	OMAP_DISPLAY_TYPE_DBI		= 1 << 1,
-	OMAP_DISPLAY_TYPE_SDI		= 1 << 2,
-	OMAP_DISPLAY_TYPE_DSI		= 1 << 3,
-	OMAP_DISPLAY_TYPE_VENC		= 1 << 4,
-	OMAP_DISPLAY_TYPE_HDMI		= 1 << 5,
-};
-
-enum omap_plane {
-	OMAP_DSS_GFX	= 0,
-	OMAP_DSS_VIDEO1	= 1,
-	OMAP_DSS_VIDEO2	= 2
-};
-
-enum omap_channel {
-	OMAP_DSS_CHANNEL_LCD	= 0,
-	OMAP_DSS_CHANNEL_DIGIT	= 1,
-	OMAP_DSS_CHANNEL_LCD2	= 2,
-};
-
-enum omap_color_mode {
-	OMAP_DSS_COLOR_CLUT1	= 1 << 0,  /* BITMAP 1 */
-	OMAP_DSS_COLOR_CLUT2	= 1 << 1,  /* BITMAP 2 */
-	OMAP_DSS_COLOR_CLUT4	= 1 << 2,  /* BITMAP 4 */
-	OMAP_DSS_COLOR_CLUT8	= 1 << 3,  /* BITMAP 8 */
-	OMAP_DSS_COLOR_RGB12U	= 1 << 4,  /* RGB12, 16-bit container */
-	OMAP_DSS_COLOR_ARGB16	= 1 << 5,  /* ARGB16 */
-	OMAP_DSS_COLOR_RGB16	= 1 << 6,  /* RGB16 */
-	OMAP_DSS_COLOR_RGB24U	= 1 << 7,  /* RGB24, 32-bit container */
-	OMAP_DSS_COLOR_RGB24P	= 1 << 8,  /* RGB24, 24-bit container */
-	OMAP_DSS_COLOR_YUV2	= 1 << 9,  /* YUV2 4:2:2 co-sited */
-	OMAP_DSS_COLOR_UYVY	= 1 << 10, /* UYVY 4:2:2 co-sited */
-	OMAP_DSS_COLOR_ARGB32	= 1 << 11, /* ARGB32 */
-	OMAP_DSS_COLOR_RGBA32	= 1 << 12, /* RGBA32 */
-	OMAP_DSS_COLOR_RGBX32	= 1 << 13, /* RGBx32 */
-};
-
-enum omap_lcd_display_type {
-	OMAP_DSS_LCD_DISPLAY_STN,
-	OMAP_DSS_LCD_DISPLAY_TFT,
-};
-
-enum omap_dss_load_mode {
-	OMAP_DSS_LOAD_CLUT_AND_FRAME	= 0,
-	OMAP_DSS_LOAD_CLUT_ONLY		= 1,
-	OMAP_DSS_LOAD_FRAME_ONLY	= 2,
-	OMAP_DSS_LOAD_CLUT_ONCE_FRAME	= 3,
-};
-
-enum omap_dss_trans_key_type {
-	OMAP_DSS_COLOR_KEY_GFX_DST = 0,
-	OMAP_DSS_COLOR_KEY_VID_SRC = 1,
-};
-
-enum omap_rfbi_te_mode {
-	OMAP_DSS_RFBI_TE_MODE_1 = 1,
-	OMAP_DSS_RFBI_TE_MODE_2 = 2,
-};
-
-enum omap_panel_config {
-	OMAP_DSS_LCD_IVS		= 1<<0,
-	OMAP_DSS_LCD_IHS		= 1<<1,
-	OMAP_DSS_LCD_IPC		= 1<<2,
-	OMAP_DSS_LCD_IEO		= 1<<3,
-	OMAP_DSS_LCD_RF			= 1<<4,
-	OMAP_DSS_LCD_ONOFF		= 1<<5,
-
-	OMAP_DSS_LCD_TFT		= 1<<20,
-};
-
-enum omap_dss_venc_type {
-	OMAP_DSS_VENC_TYPE_COMPOSITE,
-	OMAP_DSS_VENC_TYPE_SVIDEO,
-};
-
-enum omap_display_caps {
-	OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE	= 1 << 0,
-	OMAP_DSS_DISPLAY_CAP_TEAR_ELIM		= 1 << 1,
-};
-
-enum omap_dss_update_mode {
-	OMAP_DSS_UPDATE_DISABLED = 0,
-	OMAP_DSS_UPDATE_AUTO,
-	OMAP_DSS_UPDATE_MANUAL,
-};
-
-enum omap_dss_display_state {
-	OMAP_DSS_DISPLAY_DISABLED = 0,
-	OMAP_DSS_DISPLAY_ACTIVE,
-	OMAP_DSS_DISPLAY_SUSPENDED,
-};
-
-/* XXX perhaps this should be removed */
-enum omap_dss_overlay_managers {
-	OMAP_DSS_OVL_MGR_LCD,
-	OMAP_DSS_OVL_MGR_TV,
-	OMAP_DSS_OVL_MGR_LCD2,
-};
-
-enum omap_dss_rotation_type {
-	OMAP_DSS_ROT_DMA = 0,
-	OMAP_DSS_ROT_VRFB = 1,
-};
-
-/* clockwise rotation angle */
-enum omap_dss_rotation_angle {
-	OMAP_DSS_ROT_0   = 0,
-	OMAP_DSS_ROT_90  = 1,
-	OMAP_DSS_ROT_180 = 2,
-	OMAP_DSS_ROT_270 = 3,
-};
-
-enum omap_overlay_caps {
-	OMAP_DSS_OVL_CAP_SCALE = 1 << 0,
-	OMAP_DSS_OVL_CAP_DISPC = 1 << 1,
-};
-
-enum omap_overlay_manager_caps {
-	OMAP_DSS_OVL_MGR_CAP_DISPC = 1 << 0,
-};
-
-/* RFBI */
-
-struct rfbi_timings {
-	int cs_on_time;
-	int cs_off_time;
-	int we_on_time;
-	int we_off_time;
-	int re_on_time;
-	int re_off_time;
-	int we_cycle_time;
-	int re_cycle_time;
-	int cs_pulse_width;
-	int access_time;
-
-	int clk_div;
-
-	u32 tim[5];             /* set by rfbi_convert_timings() */
-
-	int converted;
-};
-
-void omap_rfbi_write_command(const void *buf, u32 len);
-void omap_rfbi_read_data(void *buf, u32 len);
-void omap_rfbi_write_data(const void *buf, u32 len);
-void omap_rfbi_write_pixels(const void __iomem *buf, int scr_width,
-		u16 x, u16 y,
-		u16 w, u16 h);
-int omap_rfbi_enable_te(bool enable, unsigned line);
-int omap_rfbi_setup_te(enum omap_rfbi_te_mode mode,
-			     unsigned hs_pulse_time, unsigned vs_pulse_time,
-			     int hs_pol_inv, int vs_pol_inv, int extif_div);
-
-/* DSI */
-void dsi_bus_lock(void);
-void dsi_bus_unlock(void);
-int dsi_vc_dcs_write(int channel, u8 *data, int len);
-int dsi_vc_dcs_write_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, u8 *data1, u8 *data2);
-int dsi_vc_set_max_rx_packet_size(int channel, u16 len);
-int dsi_vc_send_null(int channel);
-int dsi_vc_send_bta_sync(int channel);
-
-/* Board specific data */
-struct omap_dss_board_info {
-	int (*get_last_off_on_transaction_id)(struct device *dev);
-	int num_devices;
-	struct omap_dss_device **devices;
-	struct omap_dss_device *default_device;
-};
-
-#if defined(CONFIG_OMAP2_DSS_MODULE) || defined(CONFIG_OMAP2_DSS)
-/* Init with the board info */
-extern int omap_display_init(struct omap_dss_board_info *board_data);
-#else
-static inline int omap_display_init(struct omap_dss_board_info *board_data)
-{
-	return 0;
-}
-#endif
-
-struct omap_display_platform_data {
-	struct omap_dss_board_info *board_data;
-	/* TODO: Additional members to be added when PM is considered */
-
-	bool (*opt_clock_available)(const char *clk_role);
-};
-
-struct omap_video_timings {
-	/* Unit: pixels */
-	u16 x_res;
-	/* Unit: pixels */
-	u16 y_res;
-	/* Unit: KHz */
-	u32 pixel_clock;
-	/* Unit: pixel clocks */
-	u16 hsw;	/* Horizontal synchronization pulse width */
-	/* Unit: pixel clocks */
-	u16 hfp;	/* Horizontal front porch */
-	/* Unit: pixel clocks */
-	u16 hbp;	/* Horizontal back porch */
-	/* Unit: line clocks */
-	u16 vsw;	/* Vertical synchronization pulse width */
-	/* Unit: line clocks */
-	u16 vfp;	/* Vertical front porch */
-	/* Unit: line clocks */
-	u16 vbp;	/* Vertical back porch */
-};
-
-#ifdef CONFIG_OMAP2_DSS_VENC
-/* Hardcoded timings for tv modes. Venc only uses these to
- * identify the mode, and does not actually use the configs
- * itself. However, the configs should be something that
- * a normal monitor can also show */
-extern const struct omap_video_timings omap_dss_pal_timings;
-extern const struct omap_video_timings omap_dss_ntsc_timings;
-#endif
-
-struct omap_overlay_info {
-	bool enabled;
-
-	u32 paddr;
-	void __iomem *vaddr;
-	u16 screen_width;
-	u16 width;
-	u16 height;
-	enum omap_color_mode color_mode;
-	u8 rotation;
-	enum omap_dss_rotation_type rotation_type;
-	bool mirror;
-
-	u16 pos_x;
-	u16 pos_y;
-	u16 out_width;	/* if 0, out_width == width */
-	u16 out_height;	/* if 0, out_height == height */
-	u8 global_alpha;
-	u8 pre_mult_alpha;
-};
-
-struct omap_overlay {
-	struct kobject kobj;
-	struct list_head list;
-
-	/* static fields */
-	const char *name;
-	int id;
-	enum omap_color_mode supported_modes;
-	enum omap_overlay_caps caps;
-
-	/* dynamic fields */
-	struct omap_overlay_manager *manager;
-	struct omap_overlay_info info;
-
-	/* if true, info has been changed, but not applied() yet */
-	bool info_dirty;
-
-	int (*set_manager)(struct omap_overlay *ovl,
-		struct omap_overlay_manager *mgr);
-	int (*unset_manager)(struct omap_overlay *ovl);
-
-	int (*set_overlay_info)(struct omap_overlay *ovl,
-			struct omap_overlay_info *info);
-	void (*get_overlay_info)(struct omap_overlay *ovl,
-			struct omap_overlay_info *info);
-
-	int (*wait_for_go)(struct omap_overlay *ovl);
-};
-
-struct omap_overlay_manager_info {
-	u32 default_color;
-
-	enum omap_dss_trans_key_type trans_key_type;
-	u32 trans_key;
-	bool trans_enabled;
-
-	bool alpha_enabled;
-};
-
-struct omap_overlay_manager {
-	struct kobject kobj;
-	struct list_head list;
-
-	/* static fields */
-	const char *name;
-	int id;
-	enum omap_overlay_manager_caps caps;
-	int num_overlays;
-	struct omap_overlay **overlays;
-	enum omap_display_type supported_displays;
-
-	/* dynamic fields */
-	struct omap_dss_device *device;
-	struct omap_overlay_manager_info info;
-
-	bool device_changed;
-	/* if true, info has been changed but not applied() yet */
-	bool info_dirty;
-
-	int (*set_device)(struct omap_overlay_manager *mgr,
-		struct omap_dss_device *dssdev);
-	int (*unset_device)(struct omap_overlay_manager *mgr);
-
-	int (*set_manager_info)(struct omap_overlay_manager *mgr,
-			struct omap_overlay_manager_info *info);
-	void (*get_manager_info)(struct omap_overlay_manager *mgr,
-			struct omap_overlay_manager_info *info);
-
-	int (*apply)(struct omap_overlay_manager *mgr);
-	int (*wait_for_go)(struct omap_overlay_manager *mgr);
-	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 {
-	struct device dev;
-
-	enum omap_display_type type;
-
-	enum omap_channel channel;
-
-	union {
-		struct {
-			u8 data_lines;
-		} dpi;
-
-		struct {
-			u8 channel;
-			u8 data_lines;
-		} rfbi;
-
-		struct {
-			u8 datapairs;
-		} sdi;
-
-		struct {
-			u8 clk_lane;
-			u8 clk_pol;
-			u8 data1_lane;
-			u8 data1_pol;
-			u8 data2_lane;
-			u8 data2_pol;
-
-			struct {
-				u16 regn;
-				u16 regm;
-				u16 regm_dispc;
-				u16 regm_dsi;
-
-				u16 lp_clk_div;
-
-				u16 lck_div;
-				u16 pck_div;
-			} div;
-
-			bool ext_te;
-			u8 ext_te_gpio;
-		} dsi;
-
-		struct {
-			enum omap_dss_venc_type type;
-			bool invert_polarity;
-		} venc;
-	} phy;
-
-	struct {
-		struct omap_video_timings timings;
-
-		int acbi;	/* ac-bias pin transitions per interrupt */
-		/* Unit: line clocks */
-		int acb;	/* ac-bias pin frequency */
-
-		enum omap_panel_config config;
-	} panel;
-
-	struct {
-		u8 pixel_size;
-		struct rfbi_timings rfbi_timings;
-	} ctrl;
-
-	int reset_gpio;
-
-	int max_backlight_level;
-
-	const char *name;
-
-	/* used to match device to driver */
-	const char *driver_name;
-
-	void *data;
-
-	struct omap_dss_driver *driver;
-
-	/* helper variable for driver suspend/resume */
-	bool activate_after_resume;
-
-	enum omap_display_caps caps;
-
-	struct omap_overlay_manager *manager;
-
-	enum omap_dss_display_state state;
-
-	/* platform specific  */
-	int (*platform_enable)(struct omap_dss_device *dssdev);
-	void (*platform_disable)(struct omap_dss_device *dssdev);
-	int (*set_backlight)(struct omap_dss_device *dssdev, int level);
-	int (*get_backlight)(struct omap_dss_device *dssdev);
-};
-
-struct omap_dss_driver {
-	struct device_driver driver;
-
-	int (*probe)(struct omap_dss_device *);
-	void (*remove)(struct omap_dss_device *);
-
-	int (*enable)(struct omap_dss_device *display);
-	void (*disable)(struct omap_dss_device *display);
-	int (*suspend)(struct omap_dss_device *display);
-	int (*resume)(struct omap_dss_device *display);
-	int (*run_test)(struct omap_dss_device *display, int test);
-
-	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 (*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 (*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 *);
-void omap_dss_unregister_driver(struct omap_dss_driver *);
-
-int omap_dss_register_device(struct omap_dss_device *);
-void omap_dss_unregister_device(struct omap_dss_device *);
-
-void omap_dss_get_device(struct omap_dss_device *dssdev);
-void omap_dss_put_device(struct omap_dss_device *dssdev);
-#define for_each_dss_dev(d) while ((d = omap_dss_get_next_device(d)) != NULL)
-struct omap_dss_device *omap_dss_get_next_device(struct omap_dss_device *from);
-struct omap_dss_device *omap_dss_find_device(void *data,
-		int (*match)(struct omap_dss_device *dssdev, void *data));
-
-int omap_dss_start_device(struct omap_dss_device *dssdev);
-void omap_dss_stop_device(struct omap_dss_device *dssdev);
-
-int omap_dss_get_num_overlay_managers(void);
-struct omap_overlay_manager *omap_dss_get_overlay_manager(int num);
-
-int omap_dss_get_num_overlays(void);
-struct omap_overlay *omap_dss_get_overlay(int num);
-
-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);
-
-int omap_dispc_wait_for_irq_timeout(u32 irqmask, unsigned long timeout);
-int omap_dispc_wait_for_irq_interruptible_timeout(u32 irqmask,
-		unsigned long timeout);
-
-#define to_dss_driver(x) container_of((x), struct omap_dss_driver, driver)
-#define to_dss_device(x) container_of((x), struct omap_dss_device, dev)
-
-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,
-				    bool enlarge_update_area);
-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 omap_dsi_request_vc(struct omap_dss_device *dssdev, int *channel);
-int omap_dsi_set_vc_id(struct omap_dss_device *dssdev, int channel, int vc_id);
-void omap_dsi_release_vc(struct omap_dss_device *dssdev, int channel);
-
-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 -druN linux-2.6.39-libre/arch/arm/plat-omap/include/plat/flash.h linux-3.0-rc7-libre/arch/arm/plat-omap/include/plat/flash.h
--- linux-2.6.39-libre/arch/arm/plat-omap/include/plat/flash.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/plat-omap/include/plat/flash.h	2011-07-11 19:51:52.000000000 -0400
@@ -11,6 +11,7 @@
 
 #include <linux/mtd/map.h>
 
-extern void omap1_set_vpp(struct map_info *map, int enable);
+struct platform_device;
+extern void omap1_set_vpp(struct platform_device *pdev, int enable);
 
 #endif
diff -druN linux-2.6.39-libre/arch/arm/plat-omap/include/plat/gpio.h linux-3.0-rc7-libre/arch/arm/plat-omap/include/plat/gpio.h
--- linux-2.6.39-libre/arch/arm/plat-omap/include/plat/gpio.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/plat-omap/include/plat/gpio.h	2011-07-11 19:51:52.000000000 -0400
@@ -52,6 +52,109 @@
 
 #define OMAP34XX_NR_GPIOS		6
 
+/*
+ * OMAP1510 GPIO registers
+ */
+#define OMAP1510_GPIO_DATA_INPUT	0x00
+#define OMAP1510_GPIO_DATA_OUTPUT	0x04
+#define OMAP1510_GPIO_DIR_CONTROL	0x08
+#define OMAP1510_GPIO_INT_CONTROL	0x0c
+#define OMAP1510_GPIO_INT_MASK		0x10
+#define OMAP1510_GPIO_INT_STATUS	0x14
+#define OMAP1510_GPIO_PIN_CONTROL	0x18
+
+#define OMAP1510_IH_GPIO_BASE		64
+
+/*
+ * OMAP1610 specific GPIO registers
+ */
+#define OMAP1610_GPIO_REVISION		0x0000
+#define OMAP1610_GPIO_SYSCONFIG		0x0010
+#define OMAP1610_GPIO_SYSSTATUS		0x0014
+#define OMAP1610_GPIO_IRQSTATUS1	0x0018
+#define OMAP1610_GPIO_IRQENABLE1	0x001c
+#define OMAP1610_GPIO_WAKEUPENABLE	0x0028
+#define OMAP1610_GPIO_DATAIN		0x002c
+#define OMAP1610_GPIO_DATAOUT		0x0030
+#define OMAP1610_GPIO_DIRECTION		0x0034
+#define OMAP1610_GPIO_EDGE_CTRL1	0x0038
+#define OMAP1610_GPIO_EDGE_CTRL2	0x003c
+#define OMAP1610_GPIO_CLEAR_IRQENABLE1	0x009c
+#define OMAP1610_GPIO_CLEAR_WAKEUPENA	0x00a8
+#define OMAP1610_GPIO_CLEAR_DATAOUT	0x00b0
+#define OMAP1610_GPIO_SET_IRQENABLE1	0x00dc
+#define OMAP1610_GPIO_SET_WAKEUPENA	0x00e8
+#define OMAP1610_GPIO_SET_DATAOUT	0x00f0
+
+/*
+ * OMAP7XX specific GPIO registers
+ */
+#define OMAP7XX_GPIO_DATA_INPUT		0x00
+#define OMAP7XX_GPIO_DATA_OUTPUT	0x04
+#define OMAP7XX_GPIO_DIR_CONTROL	0x08
+#define OMAP7XX_GPIO_INT_CONTROL	0x0c
+#define OMAP7XX_GPIO_INT_MASK		0x10
+#define OMAP7XX_GPIO_INT_STATUS		0x14
+
+/*
+ * omap2+ specific GPIO registers
+ */
+#define OMAP24XX_GPIO_REVISION		0x0000
+#define OMAP24XX_GPIO_IRQSTATUS1	0x0018
+#define OMAP24XX_GPIO_IRQSTATUS2	0x0028
+#define OMAP24XX_GPIO_IRQENABLE2	0x002c
+#define OMAP24XX_GPIO_IRQENABLE1	0x001c
+#define OMAP24XX_GPIO_WAKE_EN		0x0020
+#define OMAP24XX_GPIO_CTRL		0x0030
+#define OMAP24XX_GPIO_OE		0x0034
+#define OMAP24XX_GPIO_DATAIN		0x0038
+#define OMAP24XX_GPIO_DATAOUT		0x003c
+#define OMAP24XX_GPIO_LEVELDETECT0	0x0040
+#define OMAP24XX_GPIO_LEVELDETECT1	0x0044
+#define OMAP24XX_GPIO_RISINGDETECT	0x0048
+#define OMAP24XX_GPIO_FALLINGDETECT	0x004c
+#define OMAP24XX_GPIO_DEBOUNCE_EN	0x0050
+#define OMAP24XX_GPIO_DEBOUNCE_VAL	0x0054
+#define OMAP24XX_GPIO_CLEARIRQENABLE1	0x0060
+#define OMAP24XX_GPIO_SETIRQENABLE1	0x0064
+#define OMAP24XX_GPIO_CLEARWKUENA	0x0080
+#define OMAP24XX_GPIO_SETWKUENA		0x0084
+#define OMAP24XX_GPIO_CLEARDATAOUT	0x0090
+#define OMAP24XX_GPIO_SETDATAOUT	0x0094
+
+#define OMAP4_GPIO_REVISION		0x0000
+#define OMAP4_GPIO_EOI			0x0020
+#define OMAP4_GPIO_IRQSTATUSRAW0	0x0024
+#define OMAP4_GPIO_IRQSTATUSRAW1	0x0028
+#define OMAP4_GPIO_IRQSTATUS0		0x002c
+#define OMAP4_GPIO_IRQSTATUS1		0x0030
+#define OMAP4_GPIO_IRQSTATUSSET0	0x0034
+#define OMAP4_GPIO_IRQSTATUSSET1	0x0038
+#define OMAP4_GPIO_IRQSTATUSCLR0	0x003c
+#define OMAP4_GPIO_IRQSTATUSCLR1	0x0040
+#define OMAP4_GPIO_IRQWAKEN0		0x0044
+#define OMAP4_GPIO_IRQWAKEN1		0x0048
+#define OMAP4_GPIO_IRQENABLE1		0x011c
+#define OMAP4_GPIO_WAKE_EN		0x0120
+#define OMAP4_GPIO_IRQSTATUS2		0x0128
+#define OMAP4_GPIO_IRQENABLE2		0x012c
+#define OMAP4_GPIO_CTRL			0x0130
+#define OMAP4_GPIO_OE			0x0134
+#define OMAP4_GPIO_DATAIN		0x0138
+#define OMAP4_GPIO_DATAOUT		0x013c
+#define OMAP4_GPIO_LEVELDETECT0		0x0140
+#define OMAP4_GPIO_LEVELDETECT1		0x0144
+#define OMAP4_GPIO_RISINGDETECT		0x0148
+#define OMAP4_GPIO_FALLINGDETECT	0x014c
+#define OMAP4_GPIO_DEBOUNCENABLE	0x0150
+#define OMAP4_GPIO_DEBOUNCINGTIME	0x0154
+#define OMAP4_GPIO_CLEARIRQENABLE1	0x0160
+#define OMAP4_GPIO_SETIRQENABLE1	0x0164
+#define OMAP4_GPIO_CLEARWKUENA		0x0180
+#define OMAP4_GPIO_SETWKUENA		0x0184
+#define OMAP4_GPIO_CLEARDATAOUT		0x0190
+#define OMAP4_GPIO_SETDATAOUT		0x0194
+
 #define OMAP_MPUIO(nr)		(OMAP_MAX_GPIO_LINES + (nr))
 #define OMAP_GPIO_IS_MPUIO(nr)	((nr) >= OMAP_MAX_GPIO_LINES)
 
diff -druN linux-2.6.39-libre/arch/arm/plat-omap/include/plat/gpmc-smsc911x.h linux-3.0-rc7-libre/arch/arm/plat-omap/include/plat/gpmc-smsc911x.h
--- linux-2.6.39-libre/arch/arm/plat-omap/include/plat/gpmc-smsc911x.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/plat-omap/include/plat/gpmc-smsc911x.h	2011-07-11 19:51:52.000000000 -0400
@@ -14,14 +14,14 @@
 #ifndef __ASM_ARCH_OMAP_GPMC_SMSC911X_H__
 
 struct omap_smsc911x_platform_data {
+	int	id;
 	int	cs;
 	int	gpio_irq;
 	int	gpio_reset;
 	u32	flags;
 };
 
-#if defined(CONFIG_SMSC911X) || \
-	defined(CONFIG_SMSC911X_MODULE)
+#if defined(CONFIG_SMSC911X) || defined(CONFIG_SMSC911X_MODULE)
 
 extern void gpmc_smsc911x_init(struct omap_smsc911x_platform_data *d);
 
diff -druN linux-2.6.39-libre/arch/arm/plat-omap/include/plat/iovmm.h linux-3.0-rc7-libre/arch/arm/plat-omap/include/plat/iovmm.h
--- linux-2.6.39-libre/arch/arm/plat-omap/include/plat/iovmm.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/plat-omap/include/plat/iovmm.h	2011-07-11 19:51:52.000000000 -0400
@@ -29,9 +29,6 @@
  * lower 16 bit is used for h/w and upper 16 bit is for s/w.
  */
 #define IOVMF_SW_SHIFT		16
-#define IOVMF_HW_SIZE		(1 << IOVMF_SW_SHIFT)
-#define IOVMF_HW_MASK		(IOVMF_HW_SIZE - 1)
-#define IOVMF_SW_MASK		(~IOVMF_HW_MASK)UL
 
 /*
  * iovma: h/w flags derived from cam and ram attribute
diff -druN linux-2.6.39-libre/arch/arm/plat-omap/include/plat/mmc.h linux-3.0-rc7-libre/arch/arm/plat-omap/include/plat/mmc.h
--- linux-2.6.39-libre/arch/arm/plat-omap/include/plat/mmc.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/plat-omap/include/plat/mmc.h	2011-07-11 19:51:52.000000000 -0400
@@ -101,6 +101,9 @@
 		/* If using power_saving and the MMC power is not to go off */
 		unsigned no_off:1;
 
+		/* eMMC does not handle power off when not in sleep state */
+		unsigned no_regulator_off_init:1;
+
 		/* Regulator off remapped to sleep */
 		unsigned vcc_aux_disable_is_sleep:1;
 
diff -druN linux-2.6.39-libre/arch/arm/plat-omap/include/plat/nokia-dsi-panel.h linux-3.0-rc7-libre/arch/arm/plat-omap/include/plat/nokia-dsi-panel.h
--- linux-2.6.39-libre/arch/arm/plat-omap/include/plat/nokia-dsi-panel.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/plat-omap/include/plat/nokia-dsi-panel.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,31 +0,0 @@
-#ifndef __ARCH_ARM_PLAT_OMAP_NOKIA_DSI_PANEL_H
-#define __ARCH_ARM_PLAT_OMAP_NOKIA_DSI_PANEL_H
-
-#include "display.h"
-
-/**
- * struct nokia_dsi_panel_data - Nokia DSI panel driver configuration
- * @name: panel name
- * @use_ext_te: use external TE
- * @ext_te_gpio: external TE GPIO
- * @use_esd_check: perform ESD checks
- * @max_backlight_level: maximum backlight level
- * @set_backlight: pointer to backlight set function
- * @get_backlight: pointer to backlight get function
- */
-struct nokia_dsi_panel_data {
-	const char *name;
-
-	int reset_gpio;
-
-	bool use_ext_te;
-	int ext_te_gpio;
-
-	bool use_esd_check;
-
-	int max_backlight_level;
-	int (*set_backlight)(struct omap_dss_device *dssdev, int level);
-	int (*get_backlight)(struct omap_dss_device *dssdev);
-};
-
-#endif /* __ARCH_ARM_PLAT_OMAP_NOKIA_DSI_PANEL_H */
diff -druN linux-2.6.39-libre/arch/arm/plat-omap/include/plat/panel-generic-dpi.h linux-3.0-rc7-libre/arch/arm/plat-omap/include/plat/panel-generic-dpi.h
--- linux-2.6.39-libre/arch/arm/plat-omap/include/plat/panel-generic-dpi.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/plat-omap/include/plat/panel-generic-dpi.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,37 +0,0 @@
-/*
- * Header for generic DPI panel driver
- *
- * Copyright (C) 2010 Canonical Ltd.
- * Author: Bryan Wu <bryan.wu@canonical.com>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 as published by
- * the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef __ARCH_ARM_PLAT_OMAP_PANEL_GENERIC_DPI_H
-#define __ARCH_ARM_PLAT_OMAP_PANEL_GENERIC_DPI_H
-
-#include "display.h"
-
-/**
- * struct panel_generic_dpi_data - panel driver configuration data
- * @name: panel name
- * @platform_enable: platform specific panel enable function
- * @platform_disable: platform specific panel disable function
- */
-struct panel_generic_dpi_data {
-	const char *name;
-	int (*platform_enable)(struct omap_dss_device *dssdev);
-	void (*platform_disable)(struct omap_dss_device *dssdev);
-};
-
-#endif /* __ARCH_ARM_PLAT_OMAP_PANEL_GENERIC_DPI_H */
diff -druN linux-2.6.39-libre/arch/arm/plat-omap/include/plat/smp.h linux-3.0-rc7-libre/arch/arm/plat-omap/include/plat/smp.h
--- linux-2.6.39-libre/arch/arm/plat-omap/include/plat/smp.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/plat-omap/include/plat/smp.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,36 +0,0 @@
-/*
- * OMAP4 machine specific smp.h
- *
- * Copyright (C) 2009 Texas Instruments, Inc.
- *
- * Author:
- *	Santosh Shilimkar <santosh.shilimkar@ti.com>
- *
- * Interface functions needed for the SMP. This file is based on arm
- * realview smp platform.
- * Copyright (c) 2003 ARM Limited.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-#ifndef OMAP_ARCH_SMP_H
-#define OMAP_ARCH_SMP_H
-
-#include <asm/hardware/gic.h>
-
-/* Needed for secondary core boot */
-extern void omap_secondary_startup(void);
-extern u32 omap_modify_auxcoreboot0(u32 set_mask, u32 clear_mask);
-extern void omap_auxcoreboot_addr(u32 cpu_addr);
-extern u32 omap_read_auxcoreboot0(void);
-
-/*
- * We use Soft IRQ1 as the IPI
- */
-static inline void smp_cross_call(const struct cpumask *mask, int ipi)
-{
-	gic_raise_softirq(mask, ipi);
-}
-
-#endif
diff -druN linux-2.6.39-libre/arch/arm/plat-omap/include/plat/uncompress.h linux-3.0-rc7-libre/arch/arm/plat-omap/include/plat/uncompress.h
--- linux-2.6.39-libre/arch/arm/plat-omap/include/plat/uncompress.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/plat-omap/include/plat/uncompress.h	2011-07-11 19:51:52.000000000 -0400
@@ -27,8 +27,8 @@
 
 #define MDR1_MODE_MASK			0x07
 
-static volatile u8 *uart_base;
-static int uart_shift;
+volatile u8 *uart_base;
+int uart_shift;
 
 /*
  * Store the DEBUG_LL uart number into memory.
@@ -129,7 +129,6 @@
 		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);
diff -druN linux-2.6.39-libre/arch/arm/plat-omap/include/plat/usb.h linux-3.0-rc7-libre/arch/arm/plat-omap/include/plat/usb.h
--- linux-2.6.39-libre/arch/arm/plat-omap/include/plat/usb.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/plat-omap/include/plat/usb.h	2011-07-11 19:51:52.000000000 -0400
@@ -113,7 +113,7 @@
 extern void am35x_musb_reset(void);
 extern void am35x_musb_phy_power(u8 on);
 extern void am35x_musb_clear_irq(void);
-extern void am35x_musb_set_mode(u8 musb_mode);
+extern void am35x_set_mode(u8 musb_mode);
 
 /*
  * FIXME correct answer depends on hmc_mode,
diff -druN linux-2.6.39-libre/arch/arm/plat-omap/iovmm.c linux-3.0-rc7-libre/arch/arm/plat-omap/iovmm.c
--- linux-2.6.39-libre/arch/arm/plat-omap/iovmm.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/plat-omap/iovmm.c	2011-07-11 19:51:52.000000000 -0400
@@ -648,7 +648,6 @@
 			return PTR_ERR(va);
 	}
 
-	flags &= IOVMF_HW_MASK;
 	flags |= IOVMF_DISCONT;
 	flags |= IOVMF_MMIO;
 
@@ -706,7 +705,6 @@
 	if (!va)
 		return -ENOMEM;
 
-	flags &= IOVMF_HW_MASK;
 	flags |= IOVMF_DISCONT;
 	flags |= IOVMF_ALLOC;
 
@@ -795,7 +793,6 @@
 	if (!va)
 		return -ENOMEM;
 
-	flags &= IOVMF_HW_MASK;
 	flags |= IOVMF_LINEAR;
 	flags |= IOVMF_MMIO;
 
@@ -853,7 +850,6 @@
 		return -ENOMEM;
 	pa = virt_to_phys(va);
 
-	flags &= IOVMF_HW_MASK;
 	flags |= IOVMF_LINEAR;
 	flags |= IOVMF_ALLOC;
 
diff -druN linux-2.6.39-libre/arch/arm/plat-omap/Kconfig linux-3.0-rc7-libre/arch/arm/plat-omap/Kconfig
--- linux-2.6.39-libre/arch/arm/plat-omap/Kconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/plat-omap/Kconfig	2011-07-11 19:51:52.000000000 -0400
@@ -12,12 +12,14 @@
 config ARCH_OMAP1
 	bool "TI OMAP1"
 	select CLKDEV_LOOKUP
+	select CLKSRC_MMIO
 	help
 	  "Systems based on omap7xx, omap15xx or omap16xx"
 
 config ARCH_OMAP2PLUS
 	bool "TI OMAP2/3/4"
 	select CLKDEV_LOOKUP
+	select GENERIC_IRQ_CHIP
 	select OMAP_DM_TIMER
 	help
 	  "Systems based on OMAP2, OMAP3 or OMAP4"
diff -druN linux-2.6.39-libre/arch/arm/plat-omap/Makefile linux-3.0-rc7-libre/arch/arm/plat-omap/Makefile
--- linux-2.6.39-libre/arch/arm/plat-omap/Makefile	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/plat-omap/Makefile	2011-07-11 19:51:52.000000000 -0400
@@ -3,7 +3,7 @@
 #
 
 # Common support
-obj-y := common.o sram.o clock.o devices.o dma.o mux.o gpio.o \
+obj-y := common.o sram.o clock.o devices.o dma.o mux.o \
 	 usb.o fb.o io.o counter_32k.o
 obj-m :=
 obj-n :=
diff -druN linux-2.6.39-libre/arch/arm/plat-omap/omap_device.c linux-3.0-rc7-libre/arch/arm/plat-omap/omap_device.c
--- linux-2.6.39-libre/arch/arm/plat-omap/omap_device.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/plat-omap/omap_device.c	2011-07-11 19:51:52.000000000 -0400
@@ -84,6 +84,7 @@
 #include <linux/io.h>
 #include <linux/clk.h>
 #include <linux/clkdev.h>
+#include <linux/pm_runtime.h>
 
 #include <plat/omap_device.h>
 #include <plat/omap_hwmod.h>
@@ -536,6 +537,42 @@
 	return 0;
 }
 
+static int _od_runtime_suspend(struct device *dev)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	int ret;
+
+	ret = pm_generic_runtime_suspend(dev);
+
+	if (!ret)
+		omap_device_idle(pdev);
+
+	return ret;
+}
+
+static int _od_runtime_idle(struct device *dev)
+{
+	return pm_generic_runtime_idle(dev);
+}
+
+static int _od_runtime_resume(struct device *dev)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+
+	omap_device_enable(pdev);
+
+	return pm_generic_runtime_resume(dev);
+}
+
+static struct dev_power_domain omap_device_power_domain = {
+	.ops = {
+		.runtime_suspend = _od_runtime_suspend,
+		.runtime_idle = _od_runtime_idle,
+		.runtime_resume = _od_runtime_resume,
+		USE_PLATFORM_PM_SLEEP_OPS
+	}
+};
+
 /**
  * omap_device_register - register an omap_device with one omap_hwmod
  * @od: struct omap_device * to register
@@ -549,6 +586,7 @@
 	pr_debug("omap_device: %s: registering\n", od->pdev.name);
 
 	od->pdev.dev.parent = &omap_device_parent;
+	od->pdev.dev.pwr_domain = &omap_device_power_domain;
 	return platform_device_register(&od->pdev);
 }
 
diff -druN linux-2.6.39-libre/arch/arm/plat-omap/sram.c linux-3.0-rc7-libre/arch/arm/plat-omap/sram.c
--- linux-2.6.39-libre/arch/arm/plat-omap/sram.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/plat-omap/sram.c	2011-07-11 19:51:52.000000000 -0400
@@ -166,7 +166,7 @@
 		else if (cpu_is_omap1611())
 			omap_sram_size = SZ_256K;
 		else {
-			printk(KERN_ERR "Could not detect SRAM size\n");
+			pr_err("Could not detect SRAM size\n");
 			omap_sram_size = 0x4000;
 		}
 	}
@@ -221,10 +221,10 @@
 	omap_sram_io_desc[0].length = ROUND_DOWN(omap_sram_size, PAGE_SIZE);
 	iotable_init(omap_sram_io_desc, ARRAY_SIZE(omap_sram_io_desc));
 
-	printk(KERN_INFO "SRAM: Mapped pa 0x%08lx to va 0x%08lx size: 0x%lx\n",
-	__pfn_to_phys(omap_sram_io_desc[0].pfn),
-	omap_sram_io_desc[0].virtual,
-	       omap_sram_io_desc[0].length);
+	pr_info("SRAM: Mapped pa 0x%08llx to va 0x%08lx size: 0x%lx\n",
+		(long long) __pfn_to_phys(omap_sram_io_desc[0].pfn),
+		omap_sram_io_desc[0].virtual,
+		omap_sram_io_desc[0].length);
 
 	/*
 	 * Normally devicemaps_init() would flush caches and tlb after
@@ -252,7 +252,7 @@
 void *omap_sram_push_address(unsigned long size)
 {
 	if (size > (omap_sram_ceil - (omap_sram_base + SRAM_BOOTLOADER_SZ))) {
-		printk(KERN_ERR "Not enough space in SRAM\n");
+		pr_err("Not enough space in SRAM\n");
 		return NULL;
 	}
 
diff -druN linux-2.6.39-libre/arch/arm/plat-orion/common.c linux-3.0-rc7-libre/arch/arm/plat-orion/common.c
--- linux-2.6.39-libre/arch/arm/plat-orion/common.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/arm/plat-orion/common.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,957 @@
+/*
+ * arch/arm/plat-orion/common.c
+ *
+ * Marvell Orion SoC common setup code used by multiple mach-/common.c
+ *
+ * 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/dma-mapping.h>
+#include <linux/serial_8250.h>
+#include <linux/mbus.h>
+#include <linux/ata_platform.h>
+#include <linux/mv643xx_eth.h>
+#include <linux/mv643xx_i2c.h>
+#include <net/dsa.h>
+#include <linux/spi/orion_spi.h>
+#include <plat/orion_wdt.h>
+#include <plat/mv_xor.h>
+#include <plat/ehci-orion.h>
+
+/* Fill in the resources structure and link it into the platform
+   device structure. There is always a memory region, and nearly
+   always an interrupt.*/
+static void fill_resources(struct platform_device *device,
+			   struct resource *resources,
+			   resource_size_t mapbase,
+			   resource_size_t size,
+			   unsigned int irq)
+{
+	device->resource = resources;
+	device->num_resources = 1;
+	resources[0].flags = IORESOURCE_MEM;
+	resources[0].start = mapbase;
+	resources[0].end = mapbase + size;
+
+	if (irq != NO_IRQ) {
+		device->num_resources++;
+		resources[1].flags = IORESOURCE_IRQ;
+		resources[1].start = irq;
+		resources[1].end = irq;
+	}
+}
+
+/*****************************************************************************
+ * UART
+ ****************************************************************************/
+static void __init uart_complete(
+	struct platform_device *orion_uart,
+	struct plat_serial8250_port *data,
+	struct resource *resources,
+	unsigned int membase,
+	resource_size_t mapbase,
+	unsigned int irq,
+	unsigned int uartclk)
+{
+	data->mapbase = mapbase;
+	data->membase = (void __iomem *)membase;
+	data->irq = irq;
+	data->uartclk = uartclk;
+	orion_uart->dev.platform_data = data;
+
+	fill_resources(orion_uart, resources, mapbase, 0xff, irq);
+	platform_device_register(orion_uart);
+}
+
+/*****************************************************************************
+ * UART0
+ ****************************************************************************/
+static struct plat_serial8250_port orion_uart0_data[] = {
+	{
+		.flags		= UPF_SKIP_TEST | UPF_BOOT_AUTOCONF,
+		.iotype		= UPIO_MEM,
+		.regshift	= 2,
+	}, {
+	},
+};
+
+static struct resource orion_uart0_resources[2];
+
+static struct platform_device orion_uart0 = {
+	.name			= "serial8250",
+	.id			= PLAT8250_DEV_PLATFORM,
+};
+
+void __init orion_uart0_init(unsigned int membase,
+			     resource_size_t mapbase,
+			     unsigned int irq,
+			     unsigned int uartclk)
+{
+	uart_complete(&orion_uart0, orion_uart0_data, orion_uart0_resources,
+		      membase, mapbase, irq, uartclk);
+}
+
+/*****************************************************************************
+ * UART1
+ ****************************************************************************/
+static struct plat_serial8250_port orion_uart1_data[] = {
+	{
+		.flags		= UPF_SKIP_TEST | UPF_BOOT_AUTOCONF,
+		.iotype		= UPIO_MEM,
+		.regshift	= 2,
+	}, {
+	},
+};
+
+static struct resource orion_uart1_resources[2];
+
+static struct platform_device orion_uart1 = {
+	.name			= "serial8250",
+	.id			= PLAT8250_DEV_PLATFORM1,
+};
+
+void __init orion_uart1_init(unsigned int membase,
+			     resource_size_t mapbase,
+			     unsigned int irq,
+			     unsigned int uartclk)
+{
+	uart_complete(&orion_uart1, orion_uart1_data, orion_uart1_resources,
+		      membase, mapbase, irq, uartclk);
+}
+
+/*****************************************************************************
+ * UART2
+ ****************************************************************************/
+static struct plat_serial8250_port orion_uart2_data[] = {
+	{
+		.flags		= UPF_SKIP_TEST | UPF_BOOT_AUTOCONF,
+		.iotype		= UPIO_MEM,
+		.regshift	= 2,
+	}, {
+	},
+};
+
+static struct resource orion_uart2_resources[2];
+
+static struct platform_device orion_uart2 = {
+	.name			= "serial8250",
+	.id			= PLAT8250_DEV_PLATFORM2,
+};
+
+void __init orion_uart2_init(unsigned int membase,
+			     resource_size_t mapbase,
+			     unsigned int irq,
+			     unsigned int uartclk)
+{
+	uart_complete(&orion_uart2, orion_uart2_data, orion_uart2_resources,
+		      membase, mapbase, irq, uartclk);
+}
+
+/*****************************************************************************
+ * UART3
+ ****************************************************************************/
+static struct plat_serial8250_port orion_uart3_data[] = {
+	{
+		.flags		= UPF_SKIP_TEST | UPF_BOOT_AUTOCONF,
+		.iotype		= UPIO_MEM,
+		.regshift	= 2,
+	}, {
+	},
+};
+
+static struct resource orion_uart3_resources[2];
+
+static struct platform_device orion_uart3 = {
+	.name			= "serial8250",
+	.id			= 3,
+};
+
+void __init orion_uart3_init(unsigned int membase,
+			     resource_size_t mapbase,
+			     unsigned int irq,
+			     unsigned int uartclk)
+{
+	uart_complete(&orion_uart3, orion_uart3_data, orion_uart3_resources,
+		      membase, mapbase, irq, uartclk);
+}
+
+/*****************************************************************************
+ * SoC RTC
+ ****************************************************************************/
+static struct resource orion_rtc_resource[2];
+
+void __init orion_rtc_init(unsigned long mapbase,
+			   unsigned long irq)
+{
+	orion_rtc_resource[0].start = mapbase;
+	orion_rtc_resource[0].end = mapbase + SZ_32 - 1;
+	orion_rtc_resource[0].flags = IORESOURCE_MEM;
+	orion_rtc_resource[1].start = irq;
+	orion_rtc_resource[1].end = irq;
+	orion_rtc_resource[1].flags = IORESOURCE_IRQ;
+
+	platform_device_register_simple("rtc-mv", -1, orion_rtc_resource, 2);
+}
+
+/*****************************************************************************
+ * GE
+ ****************************************************************************/
+static __init void ge_complete(
+	struct mv643xx_eth_shared_platform_data *orion_ge_shared_data,
+	struct mbus_dram_target_info *mbus_dram_info, int tclk,
+	struct resource *orion_ge_resource, unsigned long irq,
+	struct platform_device *orion_ge_shared,
+	struct mv643xx_eth_platform_data *eth_data,
+	struct platform_device *orion_ge)
+{
+	orion_ge_shared_data->dram = mbus_dram_info;
+	orion_ge_shared_data->t_clk = tclk;
+	orion_ge_resource->start = irq;
+	orion_ge_resource->end = irq;
+	eth_data->shared = orion_ge_shared;
+	orion_ge->dev.platform_data = eth_data;
+
+	platform_device_register(orion_ge_shared);
+	platform_device_register(orion_ge);
+}
+
+/*****************************************************************************
+ * GE00
+ ****************************************************************************/
+struct mv643xx_eth_shared_platform_data orion_ge00_shared_data;
+
+static struct resource orion_ge00_shared_resources[] = {
+	{
+		.name	= "ge00 base",
+	}, {
+		.name	= "ge00 err irq",
+	},
+};
+
+static struct platform_device orion_ge00_shared = {
+	.name		= MV643XX_ETH_SHARED_NAME,
+	.id		= 0,
+	.dev		= {
+		.platform_data	= &orion_ge00_shared_data,
+	},
+};
+
+static struct resource orion_ge00_resources[] = {
+	{
+		.name	= "ge00 irq",
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device orion_ge00 = {
+	.name		= MV643XX_ETH_NAME,
+	.id		= 0,
+	.num_resources	= 1,
+	.resource	= orion_ge00_resources,
+	.dev		= {
+		.coherent_dma_mask	= DMA_BIT_MASK(32),
+	},
+};
+
+void __init orion_ge00_init(struct mv643xx_eth_platform_data *eth_data,
+			    struct mbus_dram_target_info *mbus_dram_info,
+			    unsigned long mapbase,
+			    unsigned long irq,
+			    unsigned long irq_err,
+			    int tclk)
+{
+	fill_resources(&orion_ge00_shared, orion_ge00_shared_resources,
+		       mapbase + 0x2000, SZ_16K - 1, irq_err);
+	ge_complete(&orion_ge00_shared_data, mbus_dram_info, tclk,
+		    orion_ge00_resources, irq, &orion_ge00_shared,
+		    eth_data, &orion_ge00);
+}
+
+/*****************************************************************************
+ * GE01
+ ****************************************************************************/
+struct mv643xx_eth_shared_platform_data orion_ge01_shared_data = {
+	.shared_smi	= &orion_ge00_shared,
+};
+
+static struct resource orion_ge01_shared_resources[] = {
+	{
+		.name	= "ge01 base",
+	}, {
+		.name	= "ge01 err irq",
+	},
+};
+
+static struct platform_device orion_ge01_shared = {
+	.name		= MV643XX_ETH_SHARED_NAME,
+	.id		= 1,
+	.dev		= {
+		.platform_data	= &orion_ge01_shared_data,
+	},
+};
+
+static struct resource orion_ge01_resources[] = {
+	{
+		.name	= "ge01 irq",
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device orion_ge01 = {
+	.name		= MV643XX_ETH_NAME,
+	.id		= 1,
+	.num_resources	= 1,
+	.resource	= orion_ge01_resources,
+	.dev		= {
+		.coherent_dma_mask	= DMA_BIT_MASK(32),
+	},
+};
+
+void __init orion_ge01_init(struct mv643xx_eth_platform_data *eth_data,
+			    struct mbus_dram_target_info *mbus_dram_info,
+			    unsigned long mapbase,
+			    unsigned long irq,
+			    unsigned long irq_err,
+			    int tclk)
+{
+	fill_resources(&orion_ge01_shared, orion_ge01_shared_resources,
+		       mapbase + 0x2000, SZ_16K - 1, irq_err);
+	ge_complete(&orion_ge01_shared_data, mbus_dram_info, tclk,
+		    orion_ge01_resources, irq, &orion_ge01_shared,
+		    eth_data, &orion_ge01);
+}
+
+/*****************************************************************************
+ * GE10
+ ****************************************************************************/
+struct mv643xx_eth_shared_platform_data orion_ge10_shared_data = {
+	.shared_smi	= &orion_ge00_shared,
+};
+
+static struct resource orion_ge10_shared_resources[] = {
+	{
+		.name	= "ge10 base",
+	}, {
+		.name	= "ge10 err irq",
+	},
+};
+
+static struct platform_device orion_ge10_shared = {
+	.name		= MV643XX_ETH_SHARED_NAME,
+	.id		= 1,
+	.dev		= {
+		.platform_data	= &orion_ge10_shared_data,
+	},
+};
+
+static struct resource orion_ge10_resources[] = {
+	{
+		.name	= "ge10 irq",
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device orion_ge10 = {
+	.name		= MV643XX_ETH_NAME,
+	.id		= 1,
+	.num_resources	= 2,
+	.resource	= orion_ge10_resources,
+	.dev		= {
+		.coherent_dma_mask	= DMA_BIT_MASK(32),
+	},
+};
+
+void __init orion_ge10_init(struct mv643xx_eth_platform_data *eth_data,
+			    struct mbus_dram_target_info *mbus_dram_info,
+			    unsigned long mapbase,
+			    unsigned long irq,
+			    unsigned long irq_err,
+			    int tclk)
+{
+	fill_resources(&orion_ge10_shared, orion_ge10_shared_resources,
+		       mapbase + 0x2000, SZ_16K - 1, irq_err);
+	ge_complete(&orion_ge10_shared_data, mbus_dram_info, tclk,
+		    orion_ge10_resources, irq, &orion_ge10_shared,
+		    eth_data, &orion_ge10);
+}
+
+/*****************************************************************************
+ * GE11
+ ****************************************************************************/
+struct mv643xx_eth_shared_platform_data orion_ge11_shared_data = {
+	.shared_smi	= &orion_ge00_shared,
+};
+
+static struct resource orion_ge11_shared_resources[] = {
+	{
+		.name	= "ge11 base",
+	}, {
+		.name	= "ge11 err irq",
+	},
+};
+
+static struct platform_device orion_ge11_shared = {
+	.name		= MV643XX_ETH_SHARED_NAME,
+	.id		= 1,
+	.dev		= {
+		.platform_data	= &orion_ge11_shared_data,
+	},
+};
+
+static struct resource orion_ge11_resources[] = {
+	{
+		.name	= "ge11 irq",
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device orion_ge11 = {
+	.name		= MV643XX_ETH_NAME,
+	.id		= 1,
+	.num_resources	= 2,
+	.resource	= orion_ge11_resources,
+	.dev		= {
+		.coherent_dma_mask	= DMA_BIT_MASK(32),
+	},
+};
+
+void __init orion_ge11_init(struct mv643xx_eth_platform_data *eth_data,
+			    struct mbus_dram_target_info *mbus_dram_info,
+			    unsigned long mapbase,
+			    unsigned long irq,
+			    unsigned long irq_err,
+			    int tclk)
+{
+	fill_resources(&orion_ge11_shared, orion_ge11_shared_resources,
+		       mapbase + 0x2000, SZ_16K - 1, irq_err);
+	ge_complete(&orion_ge11_shared_data, mbus_dram_info, tclk,
+		    orion_ge11_resources, irq, &orion_ge11_shared,
+		    eth_data, &orion_ge11);
+}
+
+/*****************************************************************************
+ * Ethernet switch
+ ****************************************************************************/
+static struct resource orion_switch_resources[] = {
+	{
+		.start	= 0,
+		.end	= 0,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device orion_switch_device = {
+	.name		= "dsa",
+	.id		= 0,
+	.num_resources	= 0,
+	.resource	= orion_switch_resources,
+};
+
+void __init orion_ge00_switch_init(struct dsa_platform_data *d, int irq)
+{
+	int i;
+
+	if (irq != NO_IRQ) {
+		orion_switch_resources[0].start = irq;
+		orion_switch_resources[0].end = irq;
+		orion_switch_device.num_resources = 1;
+	}
+
+	d->netdev = &orion_ge00.dev;
+	for (i = 0; i < d->nr_chips; i++)
+		d->chip[i].mii_bus = &orion_ge00_shared.dev;
+	orion_switch_device.dev.platform_data = d;
+
+	platform_device_register(&orion_switch_device);
+}
+
+/*****************************************************************************
+ * I2C
+ ****************************************************************************/
+static struct mv64xxx_i2c_pdata orion_i2c_pdata = {
+	.freq_n		= 3,
+	.timeout	= 1000, /* Default timeout of 1 second */
+};
+
+static struct resource orion_i2c_resources[2];
+
+static struct platform_device orion_i2c = {
+	.name		= MV64XXX_I2C_CTLR_NAME,
+	.id		= 0,
+	.dev		= {
+		.platform_data	= &orion_i2c_pdata,
+	},
+};
+
+static struct mv64xxx_i2c_pdata orion_i2c_1_pdata = {
+	.freq_n		= 3,
+	.timeout	= 1000, /* Default timeout of 1 second */
+};
+
+static struct resource orion_i2c_1_resources[2];
+
+static struct platform_device orion_i2c_1 = {
+	.name		= MV64XXX_I2C_CTLR_NAME,
+	.id		= 1,
+	.dev		= {
+		.platform_data	= &orion_i2c_1_pdata,
+	},
+};
+
+void __init orion_i2c_init(unsigned long mapbase,
+			   unsigned long irq,
+			   unsigned long freq_m)
+{
+	orion_i2c_pdata.freq_m = freq_m;
+	fill_resources(&orion_i2c, orion_i2c_resources, mapbase,
+		       SZ_32 - 1, irq);
+	platform_device_register(&orion_i2c);
+}
+
+void __init orion_i2c_1_init(unsigned long mapbase,
+			     unsigned long irq,
+			     unsigned long freq_m)
+{
+	orion_i2c_1_pdata.freq_m = freq_m;
+	fill_resources(&orion_i2c_1, orion_i2c_1_resources, mapbase,
+		       SZ_32 - 1, irq);
+	platform_device_register(&orion_i2c_1);
+}
+
+/*****************************************************************************
+ * SPI
+ ****************************************************************************/
+static struct orion_spi_info orion_spi_plat_data;
+static struct resource orion_spi_resources;
+
+static struct platform_device orion_spi = {
+	.name		= "orion_spi",
+	.id		= 0,
+	.dev		= {
+		.platform_data	= &orion_spi_plat_data,
+	},
+};
+
+static struct orion_spi_info orion_spi_1_plat_data;
+static struct resource orion_spi_1_resources;
+
+static struct platform_device orion_spi_1 = {
+	.name		= "orion_spi",
+	.id		= 1,
+	.dev		= {
+		.platform_data	= &orion_spi_1_plat_data,
+	},
+};
+
+/* Note: The SPI silicon core does have interrupts. However the
+ * current Linux software driver does not use interrupts. */
+
+void __init orion_spi_init(unsigned long mapbase,
+			   unsigned long tclk)
+{
+	orion_spi_plat_data.tclk = tclk;
+	fill_resources(&orion_spi, &orion_spi_resources,
+		       mapbase, SZ_512 - 1, NO_IRQ);
+	platform_device_register(&orion_spi);
+}
+
+void __init orion_spi_1_init(unsigned long mapbase,
+			     unsigned long tclk)
+{
+	orion_spi_1_plat_data.tclk = tclk;
+	fill_resources(&orion_spi_1, &orion_spi_1_resources,
+		       mapbase, SZ_512 - 1, NO_IRQ);
+	platform_device_register(&orion_spi_1);
+}
+
+/*****************************************************************************
+ * Watchdog
+ ****************************************************************************/
+static struct orion_wdt_platform_data orion_wdt_data;
+
+static struct platform_device orion_wdt_device = {
+	.name		= "orion_wdt",
+	.id		= -1,
+	.dev		= {
+		.platform_data	= &orion_wdt_data,
+	},
+	.num_resources	= 0,
+};
+
+void __init orion_wdt_init(unsigned long tclk)
+{
+	orion_wdt_data.tclk = tclk;
+	platform_device_register(&orion_wdt_device);
+}
+
+/*****************************************************************************
+ * XOR
+ ****************************************************************************/
+static struct mv_xor_platform_shared_data orion_xor_shared_data;
+
+static u64 orion_xor_dmamask = DMA_BIT_MASK(32);
+
+void __init orion_xor_init_channels(
+	struct mv_xor_platform_data *orion_xor0_data,
+	struct platform_device *orion_xor0_channel,
+	struct mv_xor_platform_data *orion_xor1_data,
+	struct platform_device *orion_xor1_channel)
+{
+	/*
+	 * two engines can't do memset simultaneously, this limitation
+	 * satisfied by removing memset support from one of the engines.
+	 */
+	dma_cap_set(DMA_MEMCPY, orion_xor0_data->cap_mask);
+	dma_cap_set(DMA_XOR, orion_xor0_data->cap_mask);
+	platform_device_register(orion_xor0_channel);
+
+	dma_cap_set(DMA_MEMCPY, orion_xor1_data->cap_mask);
+	dma_cap_set(DMA_MEMSET, orion_xor1_data->cap_mask);
+	dma_cap_set(DMA_XOR, orion_xor1_data->cap_mask);
+	platform_device_register(orion_xor1_channel);
+}
+
+/*****************************************************************************
+ * XOR0
+ ****************************************************************************/
+static struct resource orion_xor0_shared_resources[] = {
+	{
+		.name	= "xor 0 low",
+		.flags	= IORESOURCE_MEM,
+	}, {
+		.name	= "xor 0 high",
+		.flags	= IORESOURCE_MEM,
+	},
+};
+
+static struct platform_device orion_xor0_shared = {
+	.name		= MV_XOR_SHARED_NAME,
+	.id		= 0,
+	.dev		= {
+		.platform_data = &orion_xor_shared_data,
+	},
+	.num_resources	= ARRAY_SIZE(orion_xor0_shared_resources),
+	.resource	= orion_xor0_shared_resources,
+};
+
+static struct resource orion_xor00_resources[] = {
+	[0] = {
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct mv_xor_platform_data orion_xor00_data = {
+	.shared		= &orion_xor0_shared,
+	.hw_id		= 0,
+	.pool_size	= PAGE_SIZE,
+};
+
+static struct platform_device orion_xor00_channel = {
+	.name		= MV_XOR_NAME,
+	.id		= 0,
+	.num_resources	= ARRAY_SIZE(orion_xor00_resources),
+	.resource	= orion_xor00_resources,
+	.dev		= {
+		.dma_mask		= &orion_xor_dmamask,
+		.coherent_dma_mask	= DMA_BIT_MASK(64),
+		.platform_data		= &orion_xor00_data,
+	},
+};
+
+static struct resource orion_xor01_resources[] = {
+	[0] = {
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct mv_xor_platform_data orion_xor01_data = {
+	.shared		= &orion_xor0_shared,
+	.hw_id		= 1,
+	.pool_size	= PAGE_SIZE,
+};
+
+static struct platform_device orion_xor01_channel = {
+	.name		= MV_XOR_NAME,
+	.id		= 1,
+	.num_resources	= ARRAY_SIZE(orion_xor01_resources),
+	.resource	= orion_xor01_resources,
+	.dev		= {
+		.dma_mask		= &orion_xor_dmamask,
+		.coherent_dma_mask	= DMA_BIT_MASK(64),
+		.platform_data		= &orion_xor01_data,
+	},
+};
+
+void __init orion_xor0_init(struct mbus_dram_target_info *mbus_dram_info,
+			    unsigned long mapbase_low,
+			    unsigned long mapbase_high,
+			    unsigned long irq_0,
+			    unsigned long irq_1)
+{
+	orion_xor_shared_data.dram = mbus_dram_info;
+
+	orion_xor0_shared_resources[0].start = mapbase_low;
+	orion_xor0_shared_resources[0].end = mapbase_low + 0xff;
+	orion_xor0_shared_resources[1].start = mapbase_high;
+	orion_xor0_shared_resources[1].end = mapbase_high + 0xff;
+
+	orion_xor00_resources[0].start = irq_0;
+	orion_xor00_resources[0].end = irq_0;
+	orion_xor01_resources[0].start = irq_1;
+	orion_xor01_resources[0].end = irq_1;
+
+	platform_device_register(&orion_xor0_shared);
+
+	orion_xor_init_channels(&orion_xor00_data, &orion_xor00_channel,
+				&orion_xor01_data, &orion_xor01_channel);
+}
+
+/*****************************************************************************
+ * XOR1
+ ****************************************************************************/
+static struct resource orion_xor1_shared_resources[] = {
+	{
+		.name	= "xor 1 low",
+		.flags	= IORESOURCE_MEM,
+	}, {
+		.name	= "xor 1 high",
+		.flags	= IORESOURCE_MEM,
+	},
+};
+
+static struct platform_device orion_xor1_shared = {
+	.name		= MV_XOR_SHARED_NAME,
+	.id		= 1,
+	.dev		= {
+		.platform_data = &orion_xor_shared_data,
+	},
+	.num_resources	= ARRAY_SIZE(orion_xor1_shared_resources),
+	.resource	= orion_xor1_shared_resources,
+};
+
+static struct resource orion_xor10_resources[] = {
+	[0] = {
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct mv_xor_platform_data orion_xor10_data = {
+	.shared		= &orion_xor1_shared,
+	.hw_id		= 0,
+	.pool_size	= PAGE_SIZE,
+};
+
+static struct platform_device orion_xor10_channel = {
+	.name		= MV_XOR_NAME,
+	.id		= 2,
+	.num_resources	= ARRAY_SIZE(orion_xor10_resources),
+	.resource	= orion_xor10_resources,
+	.dev		= {
+		.dma_mask		= &orion_xor_dmamask,
+		.coherent_dma_mask	= DMA_BIT_MASK(64),
+		.platform_data		= &orion_xor10_data,
+	},
+};
+
+static struct resource orion_xor11_resources[] = {
+	[0] = {
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct mv_xor_platform_data orion_xor11_data = {
+	.shared		= &orion_xor1_shared,
+	.hw_id		= 1,
+	.pool_size	= PAGE_SIZE,
+};
+
+static struct platform_device orion_xor11_channel = {
+	.name		= MV_XOR_NAME,
+	.id		= 3,
+	.num_resources	= ARRAY_SIZE(orion_xor11_resources),
+	.resource	= orion_xor11_resources,
+	.dev		= {
+		.dma_mask		= &orion_xor_dmamask,
+		.coherent_dma_mask	= DMA_BIT_MASK(64),
+		.platform_data		= &orion_xor11_data,
+	},
+};
+
+void __init orion_xor1_init(unsigned long mapbase_low,
+			    unsigned long mapbase_high,
+			    unsigned long irq_0,
+			    unsigned long irq_1)
+{
+	orion_xor1_shared_resources[0].start = mapbase_low;
+	orion_xor1_shared_resources[0].end = mapbase_low + 0xff;
+	orion_xor1_shared_resources[1].start = mapbase_high;
+	orion_xor1_shared_resources[1].end = mapbase_high + 0xff;
+
+	orion_xor10_resources[0].start = irq_0;
+	orion_xor10_resources[0].end = irq_0;
+	orion_xor11_resources[0].start = irq_1;
+	orion_xor11_resources[0].end = irq_1;
+
+	platform_device_register(&orion_xor1_shared);
+
+	orion_xor_init_channels(&orion_xor10_data, &orion_xor10_channel,
+				&orion_xor11_data, &orion_xor11_channel);
+}
+
+/*****************************************************************************
+ * EHCI
+ ****************************************************************************/
+static struct orion_ehci_data orion_ehci_data = {
+	.phy_version	= EHCI_PHY_NA,
+};
+
+static u64 ehci_dmamask = DMA_BIT_MASK(32);
+
+
+/*****************************************************************************
+ * EHCI0
+ ****************************************************************************/
+static struct resource orion_ehci_resources[2];
+
+static struct platform_device orion_ehci = {
+	.name		= "orion-ehci",
+	.id		= 0,
+	.dev		= {
+		.dma_mask		= &ehci_dmamask,
+		.coherent_dma_mask	= DMA_BIT_MASK(32),
+		.platform_data		= &orion_ehci_data,
+	},
+};
+
+void __init orion_ehci_init(struct mbus_dram_target_info *mbus_dram_info,
+			    unsigned long mapbase,
+			    unsigned long irq)
+{
+	orion_ehci_data.dram = mbus_dram_info;
+	fill_resources(&orion_ehci, orion_ehci_resources, mapbase, SZ_4K - 1,
+		       irq);
+
+	platform_device_register(&orion_ehci);
+}
+
+/*****************************************************************************
+ * EHCI1
+ ****************************************************************************/
+static struct resource orion_ehci_1_resources[2];
+
+static struct platform_device orion_ehci_1 = {
+	.name		= "orion-ehci",
+	.id		= 1,
+	.dev		= {
+		.dma_mask		= &ehci_dmamask,
+		.coherent_dma_mask	= DMA_BIT_MASK(32),
+		.platform_data		= &orion_ehci_data,
+	},
+};
+
+void __init orion_ehci_1_init(struct mbus_dram_target_info *mbus_dram_info,
+			      unsigned long mapbase,
+			      unsigned long irq)
+{
+	orion_ehci_data.dram = mbus_dram_info;
+	fill_resources(&orion_ehci_1, orion_ehci_1_resources,
+		       mapbase, SZ_4K - 1, irq);
+
+	platform_device_register(&orion_ehci_1);
+}
+
+/*****************************************************************************
+ * EHCI2
+ ****************************************************************************/
+static struct resource orion_ehci_2_resources[2];
+
+static struct platform_device orion_ehci_2 = {
+	.name		= "orion-ehci",
+	.id		= 2,
+	.dev		= {
+		.dma_mask		= &ehci_dmamask,
+		.coherent_dma_mask	= DMA_BIT_MASK(32),
+		.platform_data		= &orion_ehci_data,
+	},
+};
+
+void __init orion_ehci_2_init(struct mbus_dram_target_info *mbus_dram_info,
+			      unsigned long mapbase,
+			      unsigned long irq)
+{
+	orion_ehci_data.dram = mbus_dram_info;
+	fill_resources(&orion_ehci_2, orion_ehci_2_resources,
+		       mapbase, SZ_4K - 1, irq);
+
+	platform_device_register(&orion_ehci_2);
+}
+
+/*****************************************************************************
+ * SATA
+ ****************************************************************************/
+static struct resource orion_sata_resources[2] = {
+	{
+		.name	= "sata base",
+	}, {
+		.name	= "sata irq",
+	},
+};
+
+static struct platform_device orion_sata = {
+	.name		= "sata_mv",
+	.id		= 0,
+	.dev		= {
+		.coherent_dma_mask	= DMA_BIT_MASK(32),
+	},
+};
+
+void __init orion_sata_init(struct mv_sata_platform_data *sata_data,
+			    struct mbus_dram_target_info *mbus_dram_info,
+			    unsigned long mapbase,
+			    unsigned long irq)
+{
+	sata_data->dram = mbus_dram_info;
+	orion_sata.dev.platform_data = sata_data;
+	fill_resources(&orion_sata, orion_sata_resources,
+		       mapbase, 0x5000 - 1, irq);
+
+	platform_device_register(&orion_sata);
+}
+
+/*****************************************************************************
+ * Cryptographic Engines and Security Accelerator (CESA)
+ ****************************************************************************/
+static struct resource orion_crypto_resources[] = {
+	{
+		.name   = "regs",
+	}, {
+		.name   = "crypto interrupt",
+	}, {
+		.name   = "sram",
+		.flags  = IORESOURCE_MEM,
+	},
+};
+
+static struct platform_device orion_crypto = {
+	.name           = "mv_crypto",
+	.id             = -1,
+};
+
+void __init orion_crypto_init(unsigned long mapbase,
+			      unsigned long srambase,
+			      unsigned long sram_size,
+			      unsigned long irq)
+{
+	fill_resources(&orion_crypto, orion_crypto_resources,
+		       mapbase, 0xffff, irq);
+	orion_crypto.num_resources = 3;
+	orion_crypto_resources[2].start = srambase;
+	orion_crypto_resources[2].end = srambase + sram_size - 1;
+
+	platform_device_register(&orion_crypto);
+}
diff -druN linux-2.6.39-libre/arch/arm/plat-orion/gpio.c linux-3.0-rc7-libre/arch/arm/plat-orion/gpio.c
--- linux-2.6.39-libre/arch/arm/plat-orion/gpio.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/plat-orion/gpio.c	2011-07-11 19:51:52.000000000 -0400
@@ -321,59 +321,16 @@
  *        polarity    LEVEL          mask
  *
  ****************************************************************************/
-static void gpio_irq_ack(struct irq_data *d)
-{
-	struct orion_gpio_chip *ochip = irq_data_get_irq_chip_data(d);
-	int type = irqd_get_trigger_type(d);
-
-	if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING)) {
-		int pin = d->irq - ochip->secondary_irq_base;
-
-		writel(~(1 << pin), GPIO_EDGE_CAUSE(ochip));
-	}
-}
-
-static void gpio_irq_mask(struct irq_data *d)
-{
-	struct orion_gpio_chip *ochip = irq_data_get_irq_chip_data(d);
-	int type = irqd_get_trigger_type(d);
-	void __iomem *reg;
-	int pin;
-
-	if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING))
-		reg = GPIO_EDGE_MASK(ochip);
-	else
-		reg = GPIO_LEVEL_MASK(ochip);
-
-	pin = d->irq - ochip->secondary_irq_base;
-
-	writel(readl(reg) & ~(1 << pin), reg);
-}
-
-static void gpio_irq_unmask(struct irq_data *d)
-{
-	struct orion_gpio_chip *ochip = irq_data_get_irq_chip_data(d);
-	int type = irqd_get_trigger_type(d);
-	void __iomem *reg;
-	int pin;
-
-	if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING))
-		reg = GPIO_EDGE_MASK(ochip);
-	else
-		reg = GPIO_LEVEL_MASK(ochip);
-
-	pin = d->irq - ochip->secondary_irq_base;
-
-	writel(readl(reg) | (1 << pin), reg);
-}
 
 static int gpio_irq_set_type(struct irq_data *d, u32 type)
 {
-	struct orion_gpio_chip *ochip = irq_data_get_irq_chip_data(d);
+	struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
+	struct irq_chip_type *ct = irq_data_get_chip_type(d);
+	struct orion_gpio_chip *ochip = gc->private;
 	int pin;
 	u32 u;
 
-	pin = d->irq - ochip->secondary_irq_base;
+	pin = d->irq - gc->irq_base;
 
 	u = readl(GPIO_IO_CONF(ochip)) & (1 << pin);
 	if (!u) {
@@ -382,18 +339,14 @@
 		return -EINVAL;
 	}
 
-	/*
-	 * Set edge/level type.
-	 */
-	if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING)) {
-		__irq_set_handler_locked(d->irq, handle_edge_irq);
-	} else if (type & (IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW)) {
-		__irq_set_handler_locked(d->irq, handle_level_irq);
-	} else {
-		printk(KERN_ERR "failed to set irq=%d (type=%d)\n",
-		       d->irq, type);
+	type &= IRQ_TYPE_SENSE_MASK;
+	if (type == IRQ_TYPE_NONE)
 		return -EINVAL;
-	}
+
+	/* Check if we need to change chip and handler */
+	if (!(ct->type & type))
+		if (irq_setup_alt_chip(d, type))
+			return -EINVAL;
 
 	/*
 	 * Configure interrupt polarity.
@@ -425,19 +378,12 @@
 	return 0;
 }
 
-struct irq_chip orion_gpio_irq_chip = {
-	.name		= "orion_gpio_irq",
-	.irq_ack	= gpio_irq_ack,
-	.irq_mask	= gpio_irq_mask,
-	.irq_unmask	= gpio_irq_unmask,
-	.irq_set_type	= gpio_irq_set_type,
-};
-
 void __init orion_gpio_init(int gpio_base, int ngpio,
 			    u32 base, int mask_offset, int secondary_irq_base)
 {
 	struct orion_gpio_chip *ochip;
-	int i;
+	struct irq_chip_generic *gc;
+	struct irq_chip_type *ct;
 
 	if (orion_gpio_chip_count == ARRAY_SIZE(orion_gpio_chips))
 		return;
@@ -471,15 +417,29 @@
 	writel(0, GPIO_EDGE_MASK(ochip));
 	writel(0, GPIO_LEVEL_MASK(ochip));
 
-	for (i = 0; i < ngpio; i++) {
-		unsigned int irq = secondary_irq_base + i;
+	gc = irq_alloc_generic_chip("orion_gpio_irq", 2, secondary_irq_base,
+				    ochip->base, handle_level_irq);
+	gc->private = ochip;
 
-		irq_set_chip_and_handler(irq, &orion_gpio_irq_chip,
-					 handle_level_irq);
-		irq_set_chip_data(irq, ochip);
-		irq_set_status_flags(irq, IRQ_LEVEL);
-		set_irq_flags(irq, IRQF_VALID);
-	}
+	ct = gc->chip_types;
+	ct->regs.mask = ochip->mask_offset + GPIO_LEVEL_MASK_OFF;
+	ct->type = IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW;
+	ct->chip.irq_mask = irq_gc_mask_clr_bit;
+	ct->chip.irq_unmask = irq_gc_mask_set_bit;
+	ct->chip.irq_set_type = gpio_irq_set_type;
+
+	ct++;
+	ct->regs.mask = ochip->mask_offset + GPIO_EDGE_MASK_OFF;
+	ct->regs.ack = GPIO_EDGE_CAUSE_OFF;
+	ct->type = IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING;
+	ct->chip.irq_ack = irq_gc_ack;
+	ct->chip.irq_mask = irq_gc_mask_clr_bit;
+	ct->chip.irq_unmask = irq_gc_mask_set_bit;
+	ct->chip.irq_set_type = gpio_irq_set_type;
+	ct->handler = handle_edge_irq;
+
+	irq_setup_generic_chip(gc, IRQ_MSK(ngpio), IRQ_GC_INIT_MASK_CACHE,
+			       IRQ_NOREQUEST, IRQ_LEVEL | IRQ_NOPROBE);
 }
 
 void orion_gpio_irq_handler(int pinoff)
diff -druN linux-2.6.39-libre/arch/arm/plat-orion/include/plat/common.h linux-3.0-rc7-libre/arch/arm/plat-orion/include/plat/common.h
--- linux-2.6.39-libre/arch/arm/plat-orion/include/plat/common.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/arm/plat-orion/include/plat/common.h	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,117 @@
+/*
+ * arch/arm/plat-orion/include/plat/common.h
+ *
+ * Marvell Orion SoC common setup code used by different mach-/common.c
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2.  This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __PLAT_COMMON_H
+#include <linux/mv643xx_eth.h>
+
+struct dsa_platform_data;
+
+void __init orion_uart0_init(unsigned int membase,
+			     resource_size_t mapbase,
+			     unsigned int irq,
+			     unsigned int uartclk);
+
+void __init orion_uart1_init(unsigned int membase,
+			     resource_size_t mapbase,
+			     unsigned int irq,
+			     unsigned int uartclk);
+
+void __init orion_uart2_init(unsigned int membase,
+			     resource_size_t mapbase,
+			     unsigned int irq,
+			     unsigned int uartclk);
+
+void __init orion_uart3_init(unsigned int membase,
+			     resource_size_t mapbase,
+			     unsigned int irq,
+			     unsigned int uartclk);
+
+void __init orion_rtc_init(unsigned long mapbase,
+			   unsigned long irq);
+
+void __init orion_ge00_init(struct mv643xx_eth_platform_data *eth_data,
+			    struct mbus_dram_target_info *mbus_dram_info,
+			    unsigned long mapbase,
+			    unsigned long irq,
+			    unsigned long irq_err,
+			    int tclk);
+
+void __init orion_ge01_init(struct mv643xx_eth_platform_data *eth_data,
+			    struct mbus_dram_target_info *mbus_dram_info,
+			    unsigned long mapbase,
+			    unsigned long irq,
+			    unsigned long irq_err,
+			    int tclk);
+
+void __init orion_ge10_init(struct mv643xx_eth_platform_data *eth_data,
+			    struct mbus_dram_target_info *mbus_dram_info,
+			    unsigned long mapbase,
+			    unsigned long irq,
+			    unsigned long irq_err,
+			    int tclk);
+
+void __init orion_ge11_init(struct mv643xx_eth_platform_data *eth_data,
+			    struct mbus_dram_target_info *mbus_dram_info,
+			    unsigned long mapbase,
+			    unsigned long irq,
+			    unsigned long irq_err,
+			    int tclk);
+
+void __init orion_ge00_switch_init(struct dsa_platform_data *d,
+				   int irq);
+void __init orion_i2c_init(unsigned long mapbase,
+			   unsigned long irq,
+			   unsigned long freq_m);
+
+void __init orion_i2c_1_init(unsigned long mapbase,
+			     unsigned long irq,
+			     unsigned long freq_m);
+
+void __init orion_spi_init(unsigned long mapbase,
+			   unsigned long tclk);
+
+void __init orion_spi_1_init(unsigned long mapbase,
+			     unsigned long tclk);
+
+void __init orion_wdt_init(unsigned long tclk);
+
+void __init orion_xor0_init(struct mbus_dram_target_info *mbus_dram_info,
+			    unsigned long mapbase_low,
+			    unsigned long mapbase_high,
+			    unsigned long irq_0,
+			    unsigned long irq_1);
+
+void __init orion_xor1_init(unsigned long mapbase_low,
+			    unsigned long mapbase_high,
+			    unsigned long irq_0,
+			    unsigned long irq_1);
+
+void __init orion_ehci_init(struct mbus_dram_target_info *mbus_dram_info,
+			    unsigned long mapbase,
+			    unsigned long irq);
+
+void __init orion_ehci_1_init(struct mbus_dram_target_info *mbus_dram_info,
+			      unsigned long mapbase,
+			      unsigned long irq);
+
+void __init orion_ehci_2_init(struct mbus_dram_target_info *mbus_dram_info,
+			      unsigned long mapbase,
+			      unsigned long irq);
+
+void __init orion_sata_init(struct mv_sata_platform_data *sata_data,
+			    struct mbus_dram_target_info *mbus_dram_info,
+			    unsigned long mapbase,
+			    unsigned long irq);
+
+void __init orion_crypto_init(unsigned long mapbase,
+			      unsigned long srambase,
+			      unsigned long sram_size,
+			      unsigned long irq);
+#endif
diff -druN linux-2.6.39-libre/arch/arm/plat-orion/include/plat/gpio.h linux-3.0-rc7-libre/arch/arm/plat-orion/include/plat/gpio.h
--- linux-2.6.39-libre/arch/arm/plat-orion/include/plat/gpio.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/plat-orion/include/plat/gpio.h	2011-07-11 19:51:52.000000000 -0400
@@ -39,7 +39,6 @@
 /*
  * GPIO interrupt handling.
  */
-extern struct irq_chip orion_gpio_irq_chip;
 void orion_gpio_irq_handler(int irqoff);
 
 
diff -druN linux-2.6.39-libre/arch/arm/plat-orion/include/plat/mpp.h linux-3.0-rc7-libre/arch/arm/plat-orion/include/plat/mpp.h
--- linux-2.6.39-libre/arch/arm/plat-orion/include/plat/mpp.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/arm/plat-orion/include/plat/mpp.h	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,34 @@
+/*
+ * arch/arm/plat-orion/include/plat/mpp.h
+ *
+ * Marvell Orion SoC MPP handling.
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2.  This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __PLAT_MPP_H
+#define __PLAT_MPP_H
+
+#define MPP_NUM(x)	((x) & 0xff)
+#define MPP_SEL(x)	(((x) >> 8) & 0xf)
+
+/* This is the generic MPP macro, without any variant information.
+   Each machine architecture is expected to extend this with further
+   bit fields indicating which MPP configurations are valid for a
+   specific variant. */
+
+#define GENERIC_MPP(_num, _sel, _in, _out) ( \
+	/* MPP number */		((_num) & 0xff) | \
+	/* MPP select value */		(((_sel) & 0xf) << 8) | \
+	/* may be input signal */	((!!(_in)) << 12) | \
+	/* may be output signal */	((!!(_out)) << 13))
+
+#define MPP_INPUT_MASK		GENERIC_MPP(0, 0x0, 1, 0)
+#define MPP_OUTPUT_MASK		GENERIC_MPP(0, 0x0, 0, 1)
+
+void __init orion_mpp_conf(unsigned int *mpp_list, unsigned int variant_mask,
+			   unsigned int mpp_max, unsigned int dev_bus);
+
+#endif
diff -druN linux-2.6.39-libre/arch/arm/plat-orion/irq.c linux-3.0-rc7-libre/arch/arm/plat-orion/irq.c
--- linux-2.6.39-libre/arch/arm/plat-orion/irq.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/plat-orion/irq.c	2011-07-11 19:51:52.000000000 -0400
@@ -14,52 +14,21 @@
 #include <linux/io.h>
 #include <plat/irq.h>
 
-static void orion_irq_mask(struct irq_data *d)
-{
-	void __iomem *maskaddr = irq_data_get_irq_chip_data(d);
-	u32 mask;
-
-	mask = readl(maskaddr);
-	mask &= ~(1 << (d->irq & 31));
-	writel(mask, maskaddr);
-}
-
-static void orion_irq_unmask(struct irq_data *d)
-{
-	void __iomem *maskaddr = irq_data_get_irq_chip_data(d);
-	u32 mask;
-
-	mask = readl(maskaddr);
-	mask |= 1 << (d->irq & 31);
-	writel(mask, maskaddr);
-}
-
-static struct irq_chip orion_irq_chip = {
-	.name		= "orion_irq",
-	.irq_mask	= orion_irq_mask,
-	.irq_mask_ack	= orion_irq_mask,
-	.irq_unmask	= orion_irq_unmask,
-};
-
 void __init orion_irq_init(unsigned int irq_start, void __iomem *maskaddr)
 {
-	unsigned int i;
+	struct irq_chip_generic *gc;
+	struct irq_chip_type *ct;
 
 	/*
 	 * Mask all interrupts initially.
 	 */
 	writel(0, maskaddr);
 
-	/*
-	 * Register IRQ sources.
-	 */
-	for (i = 0; i < 32; i++) {
-		unsigned int irq = irq_start + i;
-
-		irq_set_chip_and_handler(irq, &orion_irq_chip,
-					 handle_level_irq);
-		irq_set_chip_data(irq, maskaddr);
-		irq_set_status_flags(irq, IRQ_LEVEL);
-		set_irq_flags(irq, IRQF_VALID);
-	}
+	gc = irq_alloc_generic_chip("orion_irq", 1, irq_start, maskaddr,
+				    handle_level_irq);
+	ct = gc->chip_types;
+	ct->chip.irq_mask = irq_gc_mask_clr_bit;
+	ct->chip.irq_unmask = irq_gc_mask_set_bit;
+	irq_setup_generic_chip(gc, IRQ_MSK(32), IRQ_GC_INIT_MASK_CACHE,
+			       IRQ_NOREQUEST, IRQ_LEVEL | IRQ_NOPROBE);
 }
diff -druN linux-2.6.39-libre/arch/arm/plat-orion/Makefile linux-3.0-rc7-libre/arch/arm/plat-orion/Makefile
--- linux-2.6.39-libre/arch/arm/plat-orion/Makefile	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/plat-orion/Makefile	2011-07-11 19:51:52.000000000 -0400
@@ -2,7 +2,7 @@
 # Makefile for the linux kernel.
 #
 
-obj-y	:= irq.o pcie.o time.o
+obj-y	:= irq.o pcie.o time.o common.o mpp.o
 obj-m	:=
 obj-n	:=
 obj-	:=
diff -druN linux-2.6.39-libre/arch/arm/plat-orion/mpp.c linux-3.0-rc7-libre/arch/arm/plat-orion/mpp.c
--- linux-2.6.39-libre/arch/arm/plat-orion/mpp.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/arm/plat-orion/mpp.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,78 @@
+/*
+ * arch/arm/plat-orion/mpp.c
+ *
+ * MPP functions for Marvell orion 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 <linux/gpio.h>
+#include <mach/hardware.h>
+#include <plat/mpp.h>
+
+/* Address of the ith MPP control register */
+static __init unsigned long mpp_ctrl_addr(unsigned int i,
+					  unsigned long dev_bus)
+{
+	return dev_bus + (i) * 4;
+}
+
+
+void __init orion_mpp_conf(unsigned int *mpp_list, unsigned int variant_mask,
+			   unsigned int mpp_max, unsigned int dev_bus)
+{
+	unsigned int mpp_nr_regs = (1 + mpp_max/8);
+	u32 mpp_ctrl[mpp_nr_regs];
+	int i;
+
+	printk(KERN_DEBUG "initial MPP regs:");
+	for (i = 0; i < mpp_nr_regs; i++) {
+		mpp_ctrl[i] = readl(mpp_ctrl_addr(i, dev_bus));
+		printk(" %08x", mpp_ctrl[i]);
+	}
+	printk("\n");
+
+	for ( ; *mpp_list; 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 "orion_mpp_conf: invalid MPP "
+					"number (%u)\n", num);
+			continue;
+		}
+		if (variant_mask & !(*mpp_list & variant_mask)) {
+			printk(KERN_WARNING
+			       "orion_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);
+	}
+
+	printk(KERN_DEBUG "  final MPP regs:");
+	for (i = 0; i < mpp_nr_regs; i++) {
+		writel(mpp_ctrl[i], mpp_ctrl_addr(i, dev_bus));
+		printk(" %08x", mpp_ctrl[i]);
+	}
+	printk("\n");
+}
diff -druN linux-2.6.39-libre/arch/arm/plat-orion/time.c linux-3.0-rc7-libre/arch/arm/plat-orion/time.c
--- linux-2.6.39-libre/arch/arm/plat-orion/time.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/plat-orion/time.c	2011-07-11 19:51:52.000000000 -0400
@@ -81,24 +81,6 @@
 }
 
 /*
- * Clocksource handling.
- */
-static cycle_t orion_clksrc_read(struct clocksource *cs)
-{
-	return 0xffffffff - readl(timer_base + TIMER0_VAL_OFF);
-}
-
-static struct clocksource orion_clksrc = {
-	.name		= "orion_clocksource",
-	.rating		= 300,
-	.read		= orion_clksrc_read,
-	.mask		= CLOCKSOURCE_MASK(32),
-	.flags		= CLOCK_SOURCE_IS_CONTINUOUS,
-};
-
-
-
-/*
  * Clockevent handling.
  */
 static int
@@ -247,7 +229,8 @@
 	writel(u & ~BRIDGE_INT_TIMER0, bridge_base + BRIDGE_MASK_OFF);
 	u = readl(timer_base + TIMER_CTRL_OFF);
 	writel(u | TIMER0_EN | TIMER0_RELOAD_EN, timer_base + TIMER_CTRL_OFF);
-	clocksource_register_hz(&orion_clksrc, tclk);
+	clocksource_mmio_init(timer_base + TIMER0_VAL_OFF, "orion_clocksource",
+		tclk, 300, 32, clocksource_mmio_readl_down);
 
 	/*
 	 * Setup clockevent timer (interrupt-driven).
diff -druN linux-2.6.39-libre/arch/arm/plat-pxa/gpio.c linux-3.0-rc7-libre/arch/arm/plat-pxa/gpio.c
--- linux-2.6.39-libre/arch/arm/plat-pxa/gpio.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/plat-pxa/gpio.c	2011-07-11 19:51:52.000000000 -0400
@@ -15,7 +15,7 @@
 #include <linux/init.h>
 #include <linux/irq.h>
 #include <linux/io.h>
-#include <linux/sysdev.h>
+#include <linux/syscore_ops.h>
 #include <linux/slab.h>
 
 #include <mach/gpio.h>
@@ -295,7 +295,7 @@
 }
 
 #ifdef CONFIG_PM
-static int pxa_gpio_suspend(struct sys_device *dev, pm_message_t state)
+static int pxa_gpio_suspend(void)
 {
 	struct pxa_gpio_chip *c;
 	int gpio;
@@ -312,7 +312,7 @@
 	return 0;
 }
 
-static int pxa_gpio_resume(struct sys_device *dev)
+static void pxa_gpio_resume(void)
 {
 	struct pxa_gpio_chip *c;
 	int gpio;
@@ -326,22 +326,13 @@
 		__raw_writel(c->saved_gfer, c->regbase + GFER_OFFSET);
 		__raw_writel(c->saved_gpdr, c->regbase + GPDR_OFFSET);
 	}
-	return 0;
 }
 #else
 #define pxa_gpio_suspend	NULL
 #define pxa_gpio_resume		NULL
 #endif
 
-struct sysdev_class pxa_gpio_sysclass = {
-	.name		= "gpio",
+struct syscore_ops pxa_gpio_syscore_ops = {
 	.suspend	= pxa_gpio_suspend,
 	.resume		= pxa_gpio_resume,
 };
-
-static int __init pxa_gpio_init(void)
-{
-	return sysdev_class_register(&pxa_gpio_sysclass);
-}
-
-core_initcall(pxa_gpio_init);
diff -druN linux-2.6.39-libre/arch/arm/plat-pxa/mfp.c linux-3.0-rc7-libre/arch/arm/plat-pxa/mfp.c
--- linux-2.6.39-libre/arch/arm/plat-pxa/mfp.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/plat-pxa/mfp.c	2011-07-11 19:51:52.000000000 -0400
@@ -17,7 +17,6 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/io.h>
-#include <linux/sysdev.h>
 
 #include <plat/mfp.h>
 
diff -druN linux-2.6.39-libre/arch/arm/plat-s3c24xx/devs.c linux-3.0-rc7-libre/arch/arm/plat-s3c24xx/devs.c
--- linux-2.6.39-libre/arch/arm/plat-s3c24xx/devs.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/plat-s3c24xx/devs.c	2011-07-11 19:51:52.000000000 -0400
@@ -22,6 +22,7 @@
 #include <linux/io.h>
 #include <linux/slab.h>
 #include <linux/string.h>
+#include <linux/dma-mapping.h>
 
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
@@ -233,6 +234,46 @@
 	}
 }
 
+/* USB High Speed 2.0 Device (Gadget) */
+static struct resource s3c_hsudc_resource[] = {
+	[0] = {
+		.start	= S3C2416_PA_HSUDC,
+		.end	= S3C2416_PA_HSUDC + S3C2416_SZ_HSUDC - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= IRQ_USBD,
+		.end	= IRQ_USBD,
+		.flags	= IORESOURCE_IRQ,
+	}
+};
+
+static u64 s3c_hsudc_dmamask = DMA_BIT_MASK(32);
+
+struct platform_device s3c_device_usb_hsudc = {
+	.name		= "s3c-hsudc",
+	.id		= -1,
+	.num_resources	= ARRAY_SIZE(s3c_hsudc_resource),
+	.resource	= s3c_hsudc_resource,
+	.dev		= {
+		.dma_mask		= &s3c_hsudc_dmamask,
+		.coherent_dma_mask	= DMA_BIT_MASK(32),
+	},
+};
+
+void __init s3c24xx_hsudc_set_platdata(struct s3c24xx_hsudc_platdata *pd)
+{
+	struct s3c24xx_hsudc_platdata *npd;
+
+	npd = kmalloc(sizeof(*npd), GFP_KERNEL);
+	if (npd) {
+		memcpy(npd, pd, sizeof(*npd));
+		s3c_device_usb_hsudc.dev.platform_data = npd;
+	} else {
+		printk(KERN_ERR "no memory for udc platform data\n");
+	}
+}
+
 /* IIS */
 
 static struct resource s3c_iis_resource[] = {
diff -druN linux-2.6.39-libre/arch/arm/plat-s3c24xx/dma.c linux-3.0-rc7-libre/arch/arm/plat-s3c24xx/dma.c
--- linux-2.6.39-libre/arch/arm/plat-s3c24xx/dma.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/plat-s3c24xx/dma.c	2011-07-11 19:51:52.000000000 -0400
@@ -22,7 +22,7 @@
 #include <linux/sched.h>
 #include <linux/spinlock.h>
 #include <linux/interrupt.h>
-#include <linux/sysdev.h>
+#include <linux/syscore_ops.h>
 #include <linux/slab.h>
 #include <linux/errno.h>
 #include <linux/io.h>
@@ -1027,17 +1027,13 @@
 	struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel);
 	unsigned int dcon;
 
-	pr_debug("%s: chan=%d, xfer_unit=%d, dcon=%08x\n",
-		 __func__, channel, xferunit, dcon);
+	pr_debug("%s: chan=%d, xfer_unit=%d\n", __func__, channel, xferunit);
 
 	if (chan == NULL)
 		return -EINVAL;
 
-	pr_debug("%s: Initial dcon is %08x\n", __func__, dcon);
-
 	dcon = chan->dcon & dma_sel.dcon_mask;
-
-	pr_debug("%s: New dcon is %08x\n", __func__, dcon);
+	pr_debug("%s: dcon is %08x\n", __func__, dcon);
 
 	switch (chan->req_ch) {
 	case DMACH_I2S_IN:
@@ -1195,19 +1191,12 @@
 
 EXPORT_SYMBOL(s3c2410_dma_getposition);
 
-static inline struct s3c2410_dma_chan *to_dma_chan(struct sys_device *dev)
-{
-	return container_of(dev, struct s3c2410_dma_chan, dev);
-}
-
-/* system device class */
+/* system core operations */
 
 #ifdef CONFIG_PM
 
-static int s3c2410_dma_suspend(struct sys_device *dev, pm_message_t state)
+static void s3c2410_dma_suspend_chan(struct s3c2410_dma_chan *cp)
 {
-	struct s3c2410_dma_chan *cp = to_dma_chan(dev);
-
 	printk(KERN_DEBUG "suspending dma channel %d\n", cp->number);
 
 	if (dma_rdreg(cp, S3C2410_DMA_DMASKTRIG) & S3C2410_DMASKTRIG_ON) {
@@ -1222,19 +1211,27 @@
 
 		s3c2410_dma_dostop(cp);
 	}
+}
+
+static int s3c2410_dma_suspend(void)
+{
+	struct s3c2410_dma_chan *cp = s3c2410_chans;
+	int channel;
+
+	for (channel = 0; channel < dma_channels; cp++, channel++)
+		s3c2410_dma_suspend_chan(cp);
 
 	return 0;
 }
 
-static int s3c2410_dma_resume(struct sys_device *dev)
+static void s3c2410_dma_resume_chan(struct s3c2410_dma_chan *cp)
 {
-	struct s3c2410_dma_chan *cp = to_dma_chan(dev);
 	unsigned int no = cp->number | DMACH_LOW_LEVEL;
 
 	/* restore channel's hardware configuration */
 
 	if (!cp->in_use)
-		return 0;
+		return;
 
 	printk(KERN_INFO "dma%d: restoring configuration\n", cp->number);
 
@@ -1245,8 +1242,15 @@
 
 	if (cp->map != NULL)
 		dma_sel.select(cp, cp->map);
+}
 
-	return 0;
+static void s3c2410_dma_resume(void)
+{
+	struct s3c2410_dma_chan *cp = s3c2410_chans + dma_channels - 1;
+	int channel;
+
+	for (channel = dma_channels - 1; channel >= 0; cp++, channel--)
+		s3c2410_dma_resume_chan(cp);
 }
 
 #else
@@ -1254,8 +1258,7 @@
 #define s3c2410_dma_resume  NULL
 #endif /* CONFIG_PM */
 
-struct sysdev_class dma_sysclass = {
-	.name		= "s3c24xx-dma",
+struct syscore_ops dma_syscore_ops = {
 	.suspend	= s3c2410_dma_suspend,
 	.resume		= s3c2410_dma_resume,
 };
@@ -1269,39 +1272,14 @@
 
 /* initialisation code */
 
-static int __init s3c24xx_dma_sysclass_init(void)
-{
-	int ret = sysdev_class_register(&dma_sysclass);
-
-	if (ret != 0)
-		printk(KERN_ERR "dma sysclass registration failed\n");
-
-	return ret;
-}
-
-core_initcall(s3c24xx_dma_sysclass_init);
-
-static int __init s3c24xx_dma_sysdev_register(void)
+static int __init s3c24xx_dma_syscore_init(void)
 {
-	struct s3c2410_dma_chan *cp = s3c2410_chans;
-	int channel, ret;
-
-	for (channel = 0; channel < dma_channels; cp++, channel++) {
-		cp->dev.cls = &dma_sysclass;
-		cp->dev.id  = channel;
-		ret = sysdev_register(&cp->dev);
-
-		if (ret) {
-			printk(KERN_ERR "error registering dev for dma %d\n",
-			       channel);
- 			return ret;
-		}
-	}
+	register_syscore_ops(&dma_syscore_ops);
 
 	return 0;
 }
 
-late_initcall(s3c24xx_dma_sysdev_register);
+late_initcall(s3c24xx_dma_syscore_init);
 
 int __init s3c24xx_dma_init(unsigned int channels, unsigned int irq,
 			    unsigned int stride)
diff -druN linux-2.6.39-libre/arch/arm/plat-s3c24xx/include/plat/udc.h linux-3.0-rc7-libre/arch/arm/plat-s3c24xx/include/plat/udc.h
--- linux-2.6.39-libre/arch/arm/plat-s3c24xx/include/plat/udc.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/plat-s3c24xx/include/plat/udc.h	2011-07-11 19:51:52.000000000 -0400
@@ -37,4 +37,21 @@
 
 extern void __init s3c24xx_udc_set_platdata(struct s3c2410_udc_mach_info *);
 
+/**
+ * s3c24xx_hsudc_platdata - Platform data for USB High-Speed gadget controller.
+ * @epnum: Number of endpoints to be instantiated by the controller driver.
+ * @gpio_init: Platform specific USB related GPIO initialization.
+ * @gpio_uninit: Platform specific USB releted GPIO uninitialzation.
+ *
+ * Representation of platform data for the S3C24XX USB 2.0 High Speed gadget
+ * controllers.
+ */
+struct s3c24xx_hsudc_platdata {
+	unsigned int	epnum;
+	void		(*gpio_init)(void);
+	void		(*gpio_uninit)(void);
+};
+
+extern void __init s3c24xx_hsudc_set_platdata(struct s3c24xx_hsudc_platdata *pd);
+
 #endif /* __ASM_ARM_ARCH_UDC_H */
diff -druN linux-2.6.39-libre/arch/arm/plat-s3c24xx/irq.c linux-3.0-rc7-libre/arch/arm/plat-s3c24xx/irq.c
--- linux-2.6.39-libre/arch/arm/plat-s3c24xx/irq.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/plat-s3c24xx/irq.c	2011-07-11 19:51:52.000000000 -0400
@@ -23,6 +23,7 @@
 #include <linux/interrupt.h>
 #include <linux/ioport.h>
 #include <linux/sysdev.h>
+#include <linux/syscore_ops.h>
 
 #include <asm/irq.h>
 #include <asm/mach/irq.h>
@@ -668,3 +669,8 @@
 
 	irqdbf("s3c2410: registered interrupt handlers\n");
 }
+
+struct syscore_ops s3c24xx_irq_syscore_ops = {
+	.suspend	= s3c24xx_irq_suspend,
+	.resume		= s3c24xx_irq_resume,
+};
diff -druN linux-2.6.39-libre/arch/arm/plat-s3c24xx/irq-pm.c linux-3.0-rc7-libre/arch/arm/plat-s3c24xx/irq-pm.c
--- linux-2.6.39-libre/arch/arm/plat-s3c24xx/irq-pm.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/plat-s3c24xx/irq-pm.c	2011-07-11 19:51:52.000000000 -0400
@@ -14,7 +14,6 @@
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/interrupt.h>
-#include <linux/sysdev.h>
 #include <linux/irq.h>
 
 #include <plat/cpu.h>
@@ -65,7 +64,7 @@
 static unsigned long save_eintflt[4];
 static unsigned long save_eintmask;
 
-int s3c24xx_irq_suspend(struct sys_device *dev, pm_message_t state)
+int s3c24xx_irq_suspend(void)
 {
 	unsigned int i;
 
@@ -81,7 +80,7 @@
 	return 0;
 }
 
-int s3c24xx_irq_resume(struct sys_device *dev)
+void s3c24xx_irq_resume(void)
 {
 	unsigned int i;
 
@@ -93,6 +92,4 @@
 
 	s3c_pm_do_restore(irq_save, ARRAY_SIZE(irq_save));
 	__raw_writel(save_eintmask, S3C24XX_EINTMASK);
-
-	return 0;
 }
diff -druN linux-2.6.39-libre/arch/arm/plat-s5p/cpu.c linux-3.0-rc7-libre/arch/arm/plat-s5p/cpu.c
--- linux-2.6.39-libre/arch/arm/plat-s5p/cpu.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/plat-s5p/cpu.c	2011-07-11 19:51:52.000000000 -0400
@@ -21,7 +21,6 @@
 
 #include <plat/cpu.h>
 #include <plat/s5p6440.h>
-#include <plat/s5p6442.h>
 #include <plat/s5p6450.h>
 #include <plat/s5pc100.h>
 #include <plat/s5pv210.h>
@@ -30,7 +29,6 @@
 /* table of supported CPUs */
 
 static const char name_s5p6440[] = "S5P6440";
-static const char name_s5p6442[] = "S5P6442";
 static const char name_s5p6450[] = "S5P6450";
 static const char name_s5pc100[] = "S5PC100";
 static const char name_s5pv210[] = "S5PV210/S5PC110";
@@ -46,14 +44,6 @@
 		.init		= s5p64x0_init,
 		.name		= name_s5p6440,
 	}, {
-		.idcode		= 0x36442000,
-		.idmask		= 0xfffff000,
-		.map_io		= s5p6442_map_io,
-		.init_clocks	= s5p6442_init_clocks,
-		.init_uarts	= s5p6442_init_uarts,
-		.init		= s5p6442_init,
-		.name		= name_s5p6442,
-	}, {
 		.idcode		= 0x36450000,
 		.idmask		= 0xfffff000,
 		.map_io		= s5p6450_map_io,
diff -druN linux-2.6.39-libre/arch/arm/plat-s5p/dev-ehci.c linux-3.0-rc7-libre/arch/arm/plat-s5p/dev-ehci.c
--- linux-2.6.39-libre/arch/arm/plat-s5p/dev-ehci.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/arm/plat-s5p/dev-ehci.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2011 Samsung Electronics Co.Ltd
+ * Author: Joonyoung Shim <jy0922.shim@samsung.com>
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ */
+
+#include <linux/platform_device.h>
+#include <mach/irqs.h>
+#include <mach/map.h>
+#include <plat/devs.h>
+#include <plat/ehci.h>
+#include <plat/usb-phy.h>
+
+/* USB EHCI Host Controller registration */
+static struct resource s5p_ehci_resource[] = {
+	[0] = {
+		.start	= S5P_PA_EHCI,
+		.end	= S5P_PA_EHCI + SZ_256 - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= IRQ_USB_HOST,
+		.end	= IRQ_USB_HOST,
+		.flags	= IORESOURCE_IRQ,
+	}
+};
+
+static u64 s5p_device_ehci_dmamask = 0xffffffffUL;
+
+struct platform_device s5p_device_ehci = {
+	.name		= "s5p-ehci",
+	.id		= -1,
+	.num_resources	= ARRAY_SIZE(s5p_ehci_resource),
+	.resource	= s5p_ehci_resource,
+	.dev		= {
+		.dma_mask = &s5p_device_ehci_dmamask,
+		.coherent_dma_mask = 0xffffffffUL
+	}
+};
+
+void __init s5p_ehci_set_platdata(struct s5p_ehci_platdata *pd)
+{
+	struct s5p_ehci_platdata *npd;
+
+	npd = s3c_set_platdata(pd, sizeof(struct s5p_ehci_platdata),
+			&s5p_device_ehci);
+
+	if (!npd->phy_init)
+		npd->phy_init = s5p_usb_phy_init;
+	if (!npd->phy_exit)
+		npd->phy_exit = s5p_usb_phy_exit;
+}
diff -druN linux-2.6.39-libre/arch/arm/plat-s5p/dev-onenand.c linux-3.0-rc7-libre/arch/arm/plat-s5p/dev-onenand.c
--- linux-2.6.39-libre/arch/arm/plat-s5p/dev-onenand.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/plat-s5p/dev-onenand.c	2011-07-11 19:51:52.000000000 -0400
@@ -15,8 +15,6 @@
 
 #include <linux/kernel.h>
 #include <linux/platform_device.h>
-#include <linux/mtd/mtd.h>
-#include <linux/mtd/onenand.h>
 
 #include <mach/irqs.h>
 #include <mach/map.h>
@@ -45,13 +43,3 @@
 	.num_resources	= ARRAY_SIZE(s5p_onenand_resources),
 	.resource	= s5p_onenand_resources,
 };
-
-void s5p_onenand_set_platdata(struct onenand_platform_data *pdata)
-{
-	struct onenand_platform_data *pd;
-
-	pd = kmemdup(pdata, sizeof(struct onenand_platform_data), GFP_KERNEL);
-	if (!pd)
-		printk(KERN_ERR "%s: no memory for platform data\n", __func__);
-	s5p_device_onenand.dev.platform_data = pd;
-}
diff -druN linux-2.6.39-libre/arch/arm/plat-s5p/include/plat/ehci.h linux-3.0-rc7-libre/arch/arm/plat-s5p/include/plat/ehci.h
--- linux-2.6.39-libre/arch/arm/plat-s5p/include/plat/ehci.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/arm/plat-s5p/include/plat/ehci.h	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2011 Samsung Electronics Co.Ltd
+ * Author: Joonyoung Shim <jy0922.shim@samsung.com>
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+#ifndef __PLAT_S5P_EHCI_H
+#define __PLAT_S5P_EHCI_H
+
+struct s5p_ehci_platdata {
+	int (*phy_init)(struct platform_device *pdev, int type);
+	int (*phy_exit)(struct platform_device *pdev, int type);
+};
+
+extern void s5p_ehci_set_platdata(struct s5p_ehci_platdata *pd);
+
+#endif /* __PLAT_S5P_EHCI_H */
diff -druN linux-2.6.39-libre/arch/arm/plat-s5p/include/plat/s5p6442.h linux-3.0-rc7-libre/arch/arm/plat-s5p/include/plat/s5p6442.h
--- linux-2.6.39-libre/arch/arm/plat-s5p/include/plat/s5p6442.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/plat-s5p/include/plat/s5p6442.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,33 +0,0 @@
-/* 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 -druN linux-2.6.39-libre/arch/arm/plat-s5p/include/plat/usb-phy.h linux-3.0-rc7-libre/arch/arm/plat-s5p/include/plat/usb-phy.h
--- linux-2.6.39-libre/arch/arm/plat-s5p/include/plat/usb-phy.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/arm/plat-s5p/include/plat/usb-phy.h	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2011 Samsung Electronics Co.Ltd
+ * Author: Joonyoung Shim <jy0922.shim@samsung.com>
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+#ifndef __PLAT_S5P_USB_PHY_H
+#define __PLAT_S5P_USB_PHY_H
+
+enum s5p_usb_phy_type {
+	S5P_USB_PHY_DEVICE,
+	S5P_USB_PHY_HOST,
+};
+
+extern int s5p_usb_phy_init(struct platform_device *pdev, int type);
+extern int s5p_usb_phy_exit(struct platform_device *pdev, int type);
+
+#endif /* __PLAT_S5P_REGS_USB_PHY_H */
diff -druN linux-2.6.39-libre/arch/arm/plat-s5p/irq.c linux-3.0-rc7-libre/arch/arm/plat-s5p/irq.c
--- linux-2.6.39-libre/arch/arm/plat-s5p/irq.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/plat-s5p/irq.c	2011-07-11 19:51:52.000000000 -0400
@@ -64,11 +64,7 @@
 		vic_init(VA_VIC(irq), VIC_BASE(irq), vic[irq], 0);
 #endif
 
-	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_vic_timer_irq(5, IRQ_TIMER0);
 
 	s3c_init_uart_irqs(uart_irqs, ARRAY_SIZE(uart_irqs));
 }
diff -druN linux-2.6.39-libre/arch/arm/plat-s5p/irq-gpioint.c linux-3.0-rc7-libre/arch/arm/plat-s5p/irq-gpioint.c
--- linux-2.6.39-libre/arch/arm/plat-s5p/irq-gpioint.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/plat-s5p/irq-gpioint.c	2011-07-11 19:51:52.000000000 -0400
@@ -41,72 +41,11 @@
 
 LIST_HEAD(banks);
 
-static int s5p_gpioint_get_offset(struct irq_data *data)
-{
-	struct s3c_gpio_chip *chip = irq_data_get_irq_handler_data(data);
-	return data->irq - chip->irq_base;
-}
-
-static void s5p_gpioint_ack(struct irq_data *data)
-{
-	struct s3c_gpio_chip *chip = irq_data_get_irq_handler_data(data);
-	int group, offset, pend_offset;
-	unsigned int value;
-
-	group = chip->group;
-	offset = s5p_gpioint_get_offset(data);
-	pend_offset = REG_OFFSET(group);
-
-	value = __raw_readl(GPIO_BASE(chip) + PEND_OFFSET + pend_offset);
-	value |= BIT(offset);
-	__raw_writel(value, GPIO_BASE(chip) + PEND_OFFSET + pend_offset);
-}
-
-static void s5p_gpioint_mask(struct irq_data *data)
-{
-	struct s3c_gpio_chip *chip = irq_data_get_irq_handler_data(data);
-	int group, offset, mask_offset;
-	unsigned int value;
-
-	group = chip->group;
-	offset = s5p_gpioint_get_offset(data);
-	mask_offset = REG_OFFSET(group);
-
-	value = __raw_readl(GPIO_BASE(chip) + MASK_OFFSET + mask_offset);
-	value |= BIT(offset);
-	__raw_writel(value, GPIO_BASE(chip) + MASK_OFFSET + mask_offset);
-}
-
-static void s5p_gpioint_unmask(struct irq_data *data)
-{
-	struct s3c_gpio_chip *chip = irq_data_get_irq_handler_data(data);
-	int group, offset, mask_offset;
-	unsigned int value;
-
-	group = chip->group;
-	offset = s5p_gpioint_get_offset(data);
-	mask_offset = REG_OFFSET(group);
-
-	value = __raw_readl(GPIO_BASE(chip) + MASK_OFFSET + mask_offset);
-	value &= ~BIT(offset);
-	__raw_writel(value, GPIO_BASE(chip) + MASK_OFFSET + mask_offset);
-}
-
-static void s5p_gpioint_mask_ack(struct irq_data *data)
-{
-	s5p_gpioint_mask(data);
-	s5p_gpioint_ack(data);
-}
-
-static int s5p_gpioint_set_type(struct irq_data *data, unsigned int type)
+static int s5p_gpioint_set_type(struct irq_data *d, unsigned int type)
 {
-	struct s3c_gpio_chip *chip = irq_data_get_irq_handler_data(data);
-	int group, offset, con_offset;
-	unsigned int value;
-
-	group = chip->group;
-	offset = s5p_gpioint_get_offset(data);
-	con_offset = REG_OFFSET(group);
+	struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
+	struct irq_chip_type *ct = gc->chip_types;
+	unsigned int shift = (d->irq - gc->irq_base) << 2;
 
 	switch (type) {
 	case IRQ_TYPE_EDGE_RISING:
@@ -130,23 +69,12 @@
 		return -EINVAL;
 	}
 
-	value = __raw_readl(GPIO_BASE(chip) + CON_OFFSET + con_offset);
-	value &= ~(0x7 << (offset * 0x4));
-	value |= (type << (offset * 0x4));
-	__raw_writel(value, GPIO_BASE(chip) + CON_OFFSET + con_offset);
-
+	gc->type_cache &= ~(0x7 << shift);
+	gc->type_cache |= type << shift;
+	writel(gc->type_cache, gc->reg_base + ct->regs.type);
 	return 0;
 }
 
-static struct irq_chip s5p_gpioint = {
-	.name		= "s5p_gpioint",
-	.irq_ack	= s5p_gpioint_ack,
-	.irq_mask	= s5p_gpioint_mask,
-	.irq_mask_ack	= s5p_gpioint_mask_ack,
-	.irq_unmask	= s5p_gpioint_unmask,
-	.irq_set_type	= s5p_gpioint_set_type,
-};
-
 static void s5p_gpioint_handler(unsigned int irq, struct irq_desc *desc)
 {
 	struct s5p_gpioint_bank *bank = irq_get_handler_data(irq);
@@ -179,9 +107,10 @@
 static __init int s5p_gpioint_add(struct s3c_gpio_chip *chip)
 {
 	static int used_gpioint_groups = 0;
-	int irq, group = chip->group;
-	int i;
+	int group = chip->group;
 	struct s5p_gpioint_bank *bank = NULL;
+	struct irq_chip_generic *gc;
+	struct irq_chip_type *ct;
 
 	if (used_gpioint_groups >= S5P_GPIOINT_GROUP_COUNT)
 		return -ENOMEM;
@@ -211,19 +140,28 @@
 	 * chained GPIO irq has been successfully registered, allocate new gpio
 	 * int group and assign irq nubmers
 	 */
-
 	chip->irq_base = S5P_GPIOINT_BASE +
 			 used_gpioint_groups * S5P_GPIOINT_GROUP_SIZE;
 	used_gpioint_groups++;
 
 	bank->chips[group - bank->start] = chip;
-	for (i = 0; i < chip->chip.ngpio; i++) {
-		irq = chip->irq_base + i;
-		irq_set_chip(irq, &s5p_gpioint);
-		irq_set_handler_data(irq, chip);
-		irq_set_handler(irq, handle_level_irq);
-		set_irq_flags(irq, IRQF_VALID);
-	}
+
+	gc = irq_alloc_generic_chip("s5p_gpioint", 1, chip->irq_base,
+				    (void __iomem *)GPIO_BASE(chip),
+				    handle_level_irq);
+	if (!gc)
+		return -ENOMEM;
+	ct = gc->chip_types;
+	ct->chip.irq_ack = irq_gc_ack;
+	ct->chip.irq_mask = irq_gc_mask_set_bit;
+	ct->chip.irq_unmask = irq_gc_mask_clr_bit;
+	ct->chip.irq_set_type = s5p_gpioint_set_type,
+	ct->regs.ack = PEND_OFFSET + REG_OFFSET(chip->group);
+	ct->regs.mask = MASK_OFFSET + REG_OFFSET(chip->group);
+	ct->regs.type = CON_OFFSET + REG_OFFSET(chip->group);
+	irq_setup_generic_chip(gc, IRQ_MSK(chip->chip.ngpio),
+			       IRQ_GC_INIT_MASK_CACHE,
+			       IRQ_NOREQUEST | IRQ_NOPROBE, 0);
 	return 0;
 }
 
diff -druN linux-2.6.39-libre/arch/arm/plat-s5p/irq-pm.c linux-3.0-rc7-libre/arch/arm/plat-s5p/irq-pm.c
--- linux-2.6.39-libre/arch/arm/plat-s5p/irq-pm.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/plat-s5p/irq-pm.c	2011-07-11 19:51:52.000000000 -0400
@@ -16,7 +16,6 @@
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/interrupt.h>
-#include <linux/sysdev.h>
 
 #include <plat/cpu.h>
 #include <plat/irqs.h>
@@ -77,17 +76,15 @@
 	SAVE_ITEM(S5P_EINT_MASK(3)),
 };
 
-int s3c24xx_irq_suspend(struct sys_device *dev, pm_message_t state)
+int s3c24xx_irq_suspend(void)
 {
 	s3c_pm_do_save(eint_save, ARRAY_SIZE(eint_save));
 
 	return 0;
 }
 
-int s3c24xx_irq_resume(struct sys_device *dev)
+void s3c24xx_irq_resume(void)
 {
 	s3c_pm_do_restore(eint_save, ARRAY_SIZE(eint_save));
-
-	return 0;
 }
 
diff -druN linux-2.6.39-libre/arch/arm/plat-s5p/Kconfig linux-3.0-rc7-libre/arch/arm/plat-s5p/Kconfig
--- linux-2.6.39-libre/arch/arm/plat-s5p/Kconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/plat-s5p/Kconfig	2011-07-11 19:51:52.000000000 -0400
@@ -7,7 +7,7 @@
 
 config PLAT_S5P
 	bool
-	depends on (ARCH_S5P64X0 || ARCH_S5P6442 || ARCH_S5PC100 || ARCH_S5PV210 || ARCH_EXYNOS4)
+	depends on (ARCH_S5P64X0 || ARCH_S5PC100 || ARCH_S5PV210 || ARCH_EXYNOS4)
 	default y
 	select ARM_VIC if !ARCH_EXYNOS4
 	select ARM_GIC if ARCH_EXYNOS4
@@ -85,6 +85,11 @@
 	help
 	  Compile in platform device definitions for MIPI-CSIS channel 1
 
+config S5P_DEV_USB_EHCI
+	bool
+	help
+	  Compile in platform device definition for USB EHCI
+
 config S5P_SETUP_MIPIPHY
 	bool
 	help
diff -druN linux-2.6.39-libre/arch/arm/plat-s5p/Makefile linux-3.0-rc7-libre/arch/arm/plat-s5p/Makefile
--- linux-2.6.39-libre/arch/arm/plat-s5p/Makefile	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/plat-s5p/Makefile	2011-07-11 19:51:52.000000000 -0400
@@ -33,4 +33,5 @@
 obj-$(CONFIG_S5P_DEV_ONENAND)	+= dev-onenand.o
 obj-$(CONFIG_S5P_DEV_CSIS0)	+= dev-csis0.o
 obj-$(CONFIG_S5P_DEV_CSIS1)	+= dev-csis1.o
+obj-$(CONFIG_S5P_DEV_USB_EHCI)	+= dev-ehci.o
 obj-$(CONFIG_S5P_SETUP_MIPIPHY)	+= setup-mipiphy.o
diff -druN linux-2.6.39-libre/arch/arm/plat-s5p/s5p-time.c linux-3.0-rc7-libre/arch/arm/plat-s5p/s5p-time.c
--- linux-2.6.39-libre/arch/arm/plat-s5p/s5p-time.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/plat-s5p/s5p-time.c	2011-07-11 19:51:52.000000000 -0400
@@ -290,7 +290,7 @@
 	setup_irq(irq_number, &s5p_clock_event_irq);
 }
 
-static cycle_t s5p_timer_read(struct clocksource *cs)
+static void __iomem *s5p_timer_reg(void)
 {
 	unsigned long offset = 0;
 
@@ -308,10 +308,17 @@
 
 	default:
 		printk(KERN_ERR "Invalid Timer %d\n", timer_source.source_id);
-		return 0;
+		return NULL;
 	}
 
-	return (cycle_t) ~__raw_readl(S3C_TIMERREG(offset));
+	return S3C_TIMERREG(offset);
+}
+
+static cycle_t s5p_timer_read(struct clocksource *cs)
+{
+	void __iomem *reg = s5p_timer_reg();
+
+	return (cycle_t) (reg ? ~__raw_readl(reg) : 0);
 }
 
 /*
@@ -325,53 +332,22 @@
 
 unsigned long long notrace sched_clock(void)
 {
-	u32 cyc;
-	unsigned long offset = 0;
-
-	switch (timer_source.source_id) {
-	case S5P_PWM0:
-	case S5P_PWM1:
-	case S5P_PWM2:
-	case S5P_PWM3:
-		offset = (timer_source.source_id * 0x0c) + 0x14;
-		break;
-
-	case S5P_PWM4:
-		offset = 0x40;
-		break;
+	void __iomem *reg = s5p_timer_reg();
 
-	default:
-		printk(KERN_ERR "Invalid Timer %d\n", timer_source.source_id);
+	if (!reg)
 		return 0;
-	}
 
-	cyc = ~__raw_readl(S3C_TIMERREG(offset));
-	return cyc_to_sched_clock(&cd, cyc, (u32)~0);
+	return cyc_to_sched_clock(&cd, ~__raw_readl(reg), (u32)~0);
 }
 
 static void notrace s5p_update_sched_clock(void)
 {
-	u32 cyc;
-	unsigned long offset = 0;
-
-	switch (timer_source.source_id) {
-	case S5P_PWM0:
-	case S5P_PWM1:
-	case S5P_PWM2:
-	case S5P_PWM3:
-		offset = (timer_source.source_id * 0x0c) + 0x14;
-		break;
-
-	case S5P_PWM4:
-		offset = 0x40;
-		break;
+	void __iomem *reg = s5p_timer_reg();
 
-	default:
-		printk(KERN_ERR "Invalid Timer %d\n", timer_source.source_id);
-	}
+	if (!reg)
+		return;
 
-	cyc = ~__raw_readl(S3C_TIMERREG(offset));
-	update_sched_clock(&cd, cyc, (u32)~0);
+	update_sched_clock(&cd, ~__raw_readl(reg), (u32)~0);
 }
 
 struct clocksource time_clocksource = {
@@ -394,11 +370,11 @@
 
 	clock_rate = clk_get_rate(tin_source);
 
-	init_sched_clock(&cd, s5p_update_sched_clock, 32, clock_rate);
-
 	s5p_time_setup(timer_source.source_id, TCNT_MAX);
 	s5p_time_start(timer_source.source_id, PERIODIC);
 
+	init_sched_clock(&cd, s5p_update_sched_clock, 32, clock_rate);
+
 	if (clocksource_register_hz(&time_clocksource, clock_rate))
 		panic("%s: can't register clocksource\n", time_clocksource.name);
 }
diff -druN linux-2.6.39-libre/arch/arm/plat-samsung/dev-onenand.c linux-3.0-rc7-libre/arch/arm/plat-samsung/dev-onenand.c
--- linux-2.6.39-libre/arch/arm/plat-samsung/dev-onenand.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/plat-samsung/dev-onenand.c	2011-07-11 19:51:52.000000000 -0400
@@ -13,8 +13,6 @@
 
 #include <linux/kernel.h>
 #include <linux/platform_device.h>
-#include <linux/mtd/mtd.h>
-#include <linux/mtd/onenand.h>
 
 #include <mach/irqs.h>
 #include <mach/map.h>
@@ -43,13 +41,3 @@
 	.num_resources	= ARRAY_SIZE(s3c_onenand_resources),
 	.resource	= s3c_onenand_resources,
 };
-
-void s3c_onenand_set_platdata(struct onenand_platform_data *pdata)
-{
-	struct onenand_platform_data *pd;
-
-	pd = kmemdup(pdata, sizeof(struct onenand_platform_data), GFP_KERNEL);
-	if (!pd)
-		printk(KERN_ERR "%s: no memory for platform data\n", __func__);
-	s3c_device_onenand.dev.platform_data = pd;
-}
diff -druN linux-2.6.39-libre/arch/arm/plat-samsung/gpiolib.c linux-3.0-rc7-libre/arch/arm/plat-samsung/gpiolib.c
--- linux-2.6.39-libre/arch/arm/plat-samsung/gpiolib.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/plat-samsung/gpiolib.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,206 +0,0 @@
-/* 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 <linux/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);
-	}
-}
-
-void __init samsung_gpiolib_add_2bit_chips(struct s3c_gpio_chip *chip,
-					   int nr_chips)
-{
-	for (; nr_chips > 0; nr_chips--, chip++)
-		s3c_gpiolib_add(chip);
-}
diff -druN linux-2.6.39-libre/arch/arm/plat-samsung/include/plat/cpu.h linux-3.0-rc7-libre/arch/arm/plat-samsung/include/plat/cpu.h
--- linux-2.6.39-libre/arch/arm/plat-samsung/include/plat/cpu.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/plat-samsung/include/plat/cpu.h	2011-07-11 19:51:52.000000000 -0400
@@ -68,6 +68,12 @@
 struct sys_timer;
 extern struct sys_timer s3c24xx_timer;
 
+extern struct syscore_ops s3c2410_pm_syscore_ops;
+extern struct syscore_ops s3c2412_pm_syscore_ops;
+extern struct syscore_ops s3c2416_pm_syscore_ops;
+extern struct syscore_ops s3c244x_pm_syscore_ops;
+extern struct syscore_ops s3c64xx_irq_syscore_ops;
+
 /* system device classes */
 
 extern struct sysdev_class s3c2410_sysclass;
@@ -80,7 +86,6 @@
 extern struct sysdev_class s3c6410_sysclass;
 extern struct sysdev_class s3c64xx_sysclass;
 extern struct sysdev_class s5p64x0_sysclass;
-extern struct sysdev_class s5p6442_sysclass;
 extern struct sysdev_class s5pv210_sysclass;
 extern struct sysdev_class exynos4_sysclass;
 
diff -druN linux-2.6.39-libre/arch/arm/plat-samsung/include/plat/debug-macro.S linux-3.0-rc7-libre/arch/arm/plat-samsung/include/plat/debug-macro.S
--- linux-2.6.39-libre/arch/arm/plat-samsung/include/plat/debug-macro.S	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/plat-samsung/include/plat/debug-macro.S	2011-07-11 19:51:52.000000000 -0400
@@ -11,7 +11,7 @@
 
 #include <plat/regs-serial.h>
 
-/* The S5PV210/S5PC110 and S5P6442 implementations are as belows. */
+/* The S5PV210/S5PC110 implementations are as belows. */
 
 	.macro fifo_level_s5pv210 rd, rx
 		ldr	\rd, [ \rx, # S3C2410_UFSTAT ]
diff -druN linux-2.6.39-libre/arch/arm/plat-samsung/include/plat/devs.h linux-3.0-rc7-libre/arch/arm/plat-samsung/include/plat/devs.h
--- linux-2.6.39-libre/arch/arm/plat-samsung/include/plat/devs.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/plat-samsung/include/plat/devs.h	2011-07-11 19:51:52.000000000 -0400
@@ -12,6 +12,10 @@
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
 */
+
+#ifndef __PLAT_DEVS_H
+#define __PLAT_DEVS_H __FILE__
+
 #include <linux/platform_device.h>
 
 struct s3c24xx_uart_resources {
@@ -75,10 +79,8 @@
 extern struct platform_device s5pc100_device_spi2;
 extern struct platform_device s5pv210_device_spi0;
 extern struct platform_device s5pv210_device_spi1;
-extern struct platform_device s5p6440_device_spi0;
-extern struct platform_device s5p6440_device_spi1;
-extern struct platform_device s5p6450_device_spi0;
-extern struct platform_device s5p6450_device_spi1;
+extern struct platform_device s5p64x0_device_spi0;
+extern struct platform_device s5p64x0_device_spi1;
 
 extern struct platform_device s3c_device_hwmon;
 
@@ -88,6 +90,7 @@
 extern struct platform_device s5p_device_onenand;
 
 extern struct platform_device s3c_device_usbgadget;
+extern struct platform_device s3c_device_usb_hsudc;
 extern struct platform_device s3c_device_usb_hsotg;
 
 extern struct platform_device s5pv210_device_ac97;
@@ -110,12 +113,6 @@
 extern struct platform_device exynos4_device_pd[];
 extern struct platform_device exynos4_device_ahci;
 
-extern struct platform_device s5p6442_device_pcm0;
-extern struct platform_device s5p6442_device_pcm1;
-extern struct platform_device s5p6442_device_iis0;
-extern struct platform_device s5p6442_device_iis1;
-extern struct platform_device s5p6442_device_spi;
-
 extern struct platform_device s5p6440_device_pcm;
 extern struct platform_device s5p6440_device_iis;
 
@@ -142,6 +139,8 @@
 extern struct platform_device s5p_device_mipi_csis0;
 extern struct platform_device s5p_device_mipi_csis1;
 
+extern struct platform_device s5p_device_ehci;
+
 extern struct platform_device exynos4_device_sysmmu;
 
 /* s3c2440 specific devices */
@@ -164,3 +163,5 @@
  */
 extern void *s3c_set_platdata(void *pd, size_t pdsize,
 			      struct platform_device *pdev);
+
+#endif /* __PLAT_DEVS_H */
diff -druN linux-2.6.39-libre/arch/arm/plat-samsung/include/plat/irq-vic-timer.h linux-3.0-rc7-libre/arch/arm/plat-samsung/include/plat/irq-vic-timer.h
--- linux-2.6.39-libre/arch/arm/plat-samsung/include/plat/irq-vic-timer.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/plat-samsung/include/plat/irq-vic-timer.h	2011-07-11 19:51:52.000000000 -0400
@@ -10,4 +10,4 @@
  * published by the Free Software Foundation.
 */
 
-extern void s3c_init_vic_timer_irq(unsigned int vic, unsigned int timer);
+extern void s3c_init_vic_timer_irq(unsigned int num, unsigned int timer_irq);
diff -druN linux-2.6.39-libre/arch/arm/plat-samsung/include/plat/pm.h linux-3.0-rc7-libre/arch/arm/plat-samsung/include/plat/pm.h
--- linux-2.6.39-libre/arch/arm/plat-samsung/include/plat/pm.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/plat-samsung/include/plat/pm.h	2011-07-11 19:51:52.000000000 -0400
@@ -103,14 +103,16 @@
 
 #ifdef CONFIG_PM
 extern int s3c_irqext_wake(struct irq_data *data, 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);
+extern int s3c24xx_irq_suspend(void);
+extern void s3c24xx_irq_resume(void);
 #else
 #define s3c_irqext_wake NULL
 #define s3c24xx_irq_suspend NULL
 #define s3c24xx_irq_resume  NULL
 #endif
 
+extern struct syscore_ops s3c24xx_irq_syscore_ops;
+
 /* PM debug functions */
 
 #ifdef CONFIG_SAMSUNG_PM_DEBUG
diff -druN linux-2.6.39-libre/arch/arm/plat-samsung/include/plat/regs-serial.h linux-3.0-rc7-libre/arch/arm/plat-samsung/include/plat/regs-serial.h
--- linux-2.6.39-libre/arch/arm/plat-samsung/include/plat/regs-serial.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/plat-samsung/include/plat/regs-serial.h	2011-07-11 19:51:52.000000000 -0400
@@ -194,7 +194,7 @@
 #define S3C64XX_UINTSP		0x34
 #define S3C64XX_UINTM		0x38
 
-/* Following are specific to S5PV210 and S5P6442 */
+/* Following are specific to S5PV210 */
 #define S5PV210_UCON_CLKMASK	(1<<10)
 #define S5PV210_UCON_PCLK	(0<<10)
 #define S5PV210_UCON_UCLK	(1<<10)
@@ -224,6 +224,8 @@
 #define S5PV210_UFSTAT_RXMASK	(255<<0)
 #define S5PV210_UFSTAT_RXSHIFT	(0)
 
+#define NO_NEED_CHECK_CLKSRC	1
+
 #ifndef __ASSEMBLY__
 
 /* struct s3c24xx_uart_clksrc
diff -druN linux-2.6.39-libre/arch/arm/plat-samsung/include/plat/s3c64xx-spi.h linux-3.0-rc7-libre/arch/arm/plat-samsung/include/plat/s3c64xx-spi.h
--- linux-2.6.39-libre/arch/arm/plat-samsung/include/plat/s3c64xx-spi.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/plat-samsung/include/plat/s3c64xx-spi.h	2011-07-11 19:51:52.000000000 -0400
@@ -39,6 +39,7 @@
  * @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
+ * @tx_st_done: Depends on tx fifo_lvl field
  */
 struct s3c64xx_spi_info {
 	int src_clk_nr;
@@ -53,6 +54,7 @@
 	int fifo_lvl_mask;
 	int rx_lvl_offset;
 	int high_speed;
+	int tx_st_done;
 };
 
 /**
@@ -69,6 +71,5 @@
 extern void s5pc100_spi_set_info(int cntrlr, int src_clk_nr, int num_cs);
 extern void s5pv210_spi_set_info(int cntrlr, int src_clk_nr, int num_cs);
 extern void s5p64x0_spi_set_info(int cntrlr, int src_clk_nr, int num_cs);
-extern void s5p6442_spi_set_info(int cntrlr, int src_clk_nr, int num_cs);
 
 #endif /* __S3C64XX_PLAT_SPI_H */
diff -druN linux-2.6.39-libre/arch/arm/plat-samsung/include/plat/uncompress.h linux-3.0-rc7-libre/arch/arm/plat-samsung/include/plat/uncompress.h
--- linux-2.6.39-libre/arch/arm/plat-samsung/include/plat/uncompress.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/plat-samsung/include/plat/uncompress.h	2011-07-11 19:51:52.000000000 -0400
@@ -18,8 +18,8 @@
 
 /* uart setup */
 
-static unsigned int fifo_mask;
-static unsigned int fifo_max;
+unsigned int fifo_mask;
+unsigned int fifo_max;
 
 /* forward declerations */
 
diff -druN linux-2.6.39-libre/arch/arm/plat-samsung/irq-uart.c linux-3.0-rc7-libre/arch/arm/plat-samsung/irq-uart.c
--- linux-2.6.39-libre/arch/arm/plat-samsung/irq-uart.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/plat-samsung/irq-uart.c	2011-07-11 19:51:52.000000000 -0400
@@ -27,60 +27,6 @@
 /* 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(struct irq_data *data)
-{
-	struct s3c_uart_irq *uirq = irq_data_get_irq_chip_data(data);
-	return uirq->regs;
-}
-
-static inline unsigned int s3c_irq_uart_bit(unsigned int irq)
-{
-	return irq & 3;
-}
-
-static void s3c_irq_uart_mask(struct irq_data *data)
-{
-	void __iomem *regs = s3c_irq_uart_base(data);
-	unsigned int bit = s3c_irq_uart_bit(data->irq);
-	u32 reg;
-
-	reg = __raw_readl(regs + S3C64XX_UINTM);
-	reg |= (1 << bit);
-	__raw_writel(reg, regs + S3C64XX_UINTM);
-}
-
-static void s3c_irq_uart_maskack(struct irq_data *data)
-{
-	void __iomem *regs = s3c_irq_uart_base(data);
-	unsigned int bit = s3c_irq_uart_bit(data->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(struct irq_data *data)
-{
-	void __iomem *regs = s3c_irq_uart_base(data);
-	unsigned int bit = s3c_irq_uart_bit(data->irq);
-	u32 reg;
-
-	reg = __raw_readl(regs + S3C64XX_UINTM);
-	reg &= ~(1 << bit);
-	__raw_writel(reg, regs + S3C64XX_UINTM);
-}
-
-static void s3c_irq_uart_ack(struct irq_data *data)
-{
-	void __iomem *regs = s3c_irq_uart_base(data);
-	unsigned int bit = s3c_irq_uart_bit(data->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->irq_data.handler_data;
@@ -97,30 +43,25 @@
 		generic_handle_irq(base + 3);
 }
 
-static struct irq_chip s3c_irq_uart = {
-	.name		= "s3c-uart",
-	.irq_mask	= s3c_irq_uart_mask,
-	.irq_unmask	= s3c_irq_uart_unmask,
-	.irq_mask_ack	= s3c_irq_uart_maskack,
-	.irq_ack	= s3c_irq_uart_ack,
-};
-
 static void __init s3c_init_uart_irq(struct s3c_uart_irq *uirq)
 {
 	void __iomem *reg_base = uirq->regs;
-	unsigned int irq;
-	int offs;
+	struct irq_chip_generic *gc;
+	struct irq_chip_type *ct;
 
 	/* mask all interrupts at the start. */
 	__raw_writel(0xf, reg_base + S3C64XX_UINTM);
 
-	for (offs = 0; offs < 3; offs++) {
-		irq = uirq->base_irq + offs;
-
-		irq_set_chip_and_handler(irq, &s3c_irq_uart, handle_level_irq);
-		irq_set_chip_data(irq, uirq);
-		set_irq_flags(irq, IRQF_VALID);
-	}
+	gc = irq_alloc_generic_chip("s3c-uart", 1, uirq->base_irq, reg_base,
+				    handle_level_irq);
+	ct = gc->chip_types;
+	ct->chip.irq_ack = irq_gc_ack;
+	ct->chip.irq_mask = irq_gc_mask_set_bit;
+	ct->chip.irq_unmask = irq_gc_mask_clr_bit;
+	ct->regs.ack = S3C64XX_UINTP;
+	ct->regs.mask = S3C64XX_UINTM;
+	irq_setup_generic_chip(gc, IRQ_MSK(4), IRQ_GC_INIT_MASK_CACHE,
+			       IRQ_NOREQUEST | IRQ_NOPROBE, 0);
 
 	irq_set_handler_data(uirq->parent_irq, uirq);
 	irq_set_chained_handler(uirq->parent_irq, s3c_irq_demux_uart);
diff -druN linux-2.6.39-libre/arch/arm/plat-samsung/irq-vic-timer.c linux-3.0-rc7-libre/arch/arm/plat-samsung/irq-vic-timer.c
--- linux-2.6.39-libre/arch/arm/plat-samsung/irq-vic-timer.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/plat-samsung/irq-vic-timer.c	2011-07-11 19:51:52.000000000 -0400
@@ -28,60 +28,43 @@
 }
 
 /* We assume the IRQ_TIMER0..IRQ_TIMER4 range is continuous. */
-
-static void s3c_irq_timer_mask(struct irq_data *data)
-{
-	u32 reg = __raw_readl(S3C64XX_TINT_CSTAT);
-	u32 mask = (u32)data->chip_data;
-
-	reg &= 0x1f;  /* mask out pending interrupts */
-	reg &= ~mask;
-	__raw_writel(reg, S3C64XX_TINT_CSTAT);
-}
-
-static void s3c_irq_timer_unmask(struct irq_data *data)
-{
-	u32 reg = __raw_readl(S3C64XX_TINT_CSTAT);
-	u32 mask = (u32)data->chip_data;
-
-	reg &= 0x1f;  /* mask out pending interrupts */
-	reg |= mask;
-	__raw_writel(reg, S3C64XX_TINT_CSTAT);
-}
-
-static void s3c_irq_timer_ack(struct irq_data *data)
+static void s3c_irq_timer_ack(struct irq_data *d)
 {
-	u32 reg = __raw_readl(S3C64XX_TINT_CSTAT);
-	u32 mask = (u32)data->chip_data;
+	struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
+	u32 mask = (1 << 5) << (d->irq - gc->irq_base);
 
-	reg &= 0x1f;
-	reg |= mask << 5;
-	__raw_writel(reg, S3C64XX_TINT_CSTAT);
+	irq_reg_writel(mask | gc->mask_cache, gc->reg_base);
 }
 
-static struct irq_chip s3c_irq_timer = {
-	.name		= "s3c-timer",
-	.irq_mask	= s3c_irq_timer_mask,
-	.irq_unmask	= s3c_irq_timer_unmask,
-	.irq_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.
+ * @num: Number of timers to initialize
+ * @timer_irq: Base IRQ number to be used for the timers.
  *
  * 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)
+void __init s3c_init_vic_timer_irq(unsigned int num, unsigned int timer_irq)
 {
+	unsigned int pirq[5] = { IRQ_TIMER0_VIC, IRQ_TIMER1_VIC, IRQ_TIMER2_VIC,
+				 IRQ_TIMER3_VIC, IRQ_TIMER4_VIC };
+	struct irq_chip_generic *s3c_tgc;
+	struct irq_chip_type *ct;
+	unsigned int i;
 
-	irq_set_chained_handler(parent_irq, s3c_irq_demux_vic_timer);
-	irq_set_handler_data(parent_irq, (void *)timer_irq);
+	s3c_tgc = irq_alloc_generic_chip("s3c-timer", 1, timer_irq,
+					 S3C64XX_TINT_CSTAT, handle_level_irq);
+	ct = s3c_tgc->chip_types;
+	ct->chip.irq_mask = irq_gc_mask_clr_bit;
+	ct->chip.irq_unmask = irq_gc_mask_set_bit;
+	ct->chip.irq_ack = s3c_irq_timer_ack;
+	irq_setup_generic_chip(s3c_tgc, IRQ_MSK(num), IRQ_GC_INIT_MASK_CACHE,
+			       IRQ_NOREQUEST | IRQ_NOPROBE, 0);
+	/* Clear the upper bits of the mask_cache*/
+	s3c_tgc->mask_cache &= 0x1f;
 
-	irq_set_chip_and_handler(timer_irq, &s3c_irq_timer, handle_level_irq);
-	irq_set_chip_data(timer_irq, (void *)(1 << (timer_irq - IRQ_TIMER0)));
-	set_irq_flags(timer_irq, IRQF_VALID);
+	for (i = 0; i < num; i++, timer_irq++) {
+		irq_set_chained_handler(pirq[i], s3c_irq_demux_vic_timer);
+		irq_set_handler_data(pirq[i], (void *)timer_irq);
+	}
 }
diff -druN linux-2.6.39-libre/arch/arm/plat-samsung/Kconfig linux-3.0-rc7-libre/arch/arm/plat-samsung/Kconfig
--- linux-2.6.39-libre/arch/arm/plat-samsung/Kconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/plat-samsung/Kconfig	2011-07-11 19:51:52.000000000 -0400
@@ -8,6 +8,7 @@
 	bool
 	depends on PLAT_S3C24XX || ARCH_S3C64XX || PLAT_S5P
 	select NO_IOPORT
+	select GENERIC_IRQ_CHIP
 	default y
 	help
 	  Base platform code for all Samsung SoC based systems
diff -druN linux-2.6.39-libre/arch/arm/plat-samsung/Makefile linux-3.0-rc7-libre/arch/arm/plat-samsung/Makefile
--- linux-2.6.39-libre/arch/arm/plat-samsung/Makefile	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/plat-samsung/Makefile	2011-07-11 19:51:52.000000000 -0400
@@ -19,7 +19,6 @@
 obj-y				+= gpio-config.o
 obj-y				+= dev-asocdma.o
 
-obj-$(CONFIG_SAMSUNG_GPIOLIB_4BIT)	+= gpiolib.o
 obj-$(CONFIG_SAMSUNG_CLKSRC)	+= clock-clksrc.o
 
 obj-$(CONFIG_SAMSUNG_IRQ_UART)	+= irq-uart.o
diff -druN linux-2.6.39-libre/arch/arm/plat-spear/clock.c linux-3.0-rc7-libre/arch/arm/plat-spear/clock.c
--- linux-2.6.39-libre/arch/arm/plat-spear/clock.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/plat-spear/clock.c	2011-07-11 19:51:52.000000000 -0400
@@ -903,6 +903,11 @@
 	spin_unlock_irqrestore(&clocks_lock, flags);
 }
 
+void __init clk_init(void)
+{
+	recalc_root_clocks();
+}
+
 #ifdef CONFIG_DEBUG_FS
 /*
  *	debugfs support to trace clock tree hierarchy and attributes
diff -druN linux-2.6.39-libre/arch/arm/plat-spear/include/plat/clock.h linux-3.0-rc7-libre/arch/arm/plat-spear/include/plat/clock.h
--- linux-2.6.39-libre/arch/arm/plat-spear/include/plat/clock.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/plat-spear/include/plat/clock.h	2011-07-11 19:51:52.000000000 -0400
@@ -224,6 +224,7 @@
 };
 
 /* platform specific clock functions */
+void __init clk_init(void);
 void clk_register(struct clk_lookup *cl);
 void recalc_root_clocks(void);
 
diff -druN linux-2.6.39-libre/arch/arm/plat-spear/time.c linux-3.0-rc7-libre/arch/arm/plat-spear/time.c
--- linux-2.6.39-libre/arch/arm/plat-spear/time.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/plat-spear/time.c	2011-07-11 19:51:52.000000000 -0400
@@ -70,19 +70,6 @@
 static int clockevent_next_event(unsigned long evt,
 				 struct clock_event_device *clk_event_dev);
 
-static cycle_t clocksource_read_cycles(struct clocksource *cs)
-{
-	return (cycle_t) readw(gpt_base + COUNT(CLKSRC));
-}
-
-static struct clocksource clksrc = {
-	.name = "tmr1",
-	.rating = 200,		/* its a pretty decent clock */
-	.read = clocksource_read_cycles,
-	.mask = 0xFFFF,		/* 16 bits */
-	.flags = CLOCK_SOURCE_IS_CONTINUOUS,
-};
-
 static void spear_clocksource_init(void)
 {
 	u32 tick_rate;
@@ -103,7 +90,8 @@
 	writew(val, gpt_base + CR(CLKSRC));
 
 	/* register the clocksource */
-	clocksource_register_hz(&clksrc, tick_rate);
+	clocksource_mmio_init(gpt_base + COUNT(CLKSRC), "tmr1", tick_rate,
+		200, 16, clocksource_mmio_readw_up);
 }
 
 static struct clock_event_device clkevt = {
diff -druN linux-2.6.39-libre/arch/arm/plat-stmp3xxx/clock.c linux-3.0-rc7-libre/arch/arm/plat-stmp3xxx/clock.c
--- linux-2.6.39-libre/arch/arm/plat-stmp3xxx/clock.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/plat-stmp3xxx/clock.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,1134 +0,0 @@
-/*
- * Clock manipulation routines for Freescale STMP37XX/STMP378X
- *
- * Author: Vitaly Wool <vital@embeddedalley.com>
- *
- * Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved.
- * Copyright 2008 Embedded Alley Solutions, 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
- */
-#define DEBUG
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/clk.h>
-#include <linux/spinlock.h>
-#include <linux/errno.h>
-#include <linux/err.h>
-#include <linux/delay.h>
-#include <linux/io.h>
-#include <linux/clkdev.h>
-
-#include <asm/mach-types.h>
-#include <mach/platform.h>
-#include <mach/regs-clkctrl.h>
-
-#include "clock.h"
-
-static DEFINE_SPINLOCK(clocks_lock);
-
-static struct clk osc_24M;
-static struct clk pll_clk;
-static struct clk cpu_clk;
-static struct clk hclk;
-
-static int propagate_rate(struct clk *);
-
-static inline int clk_is_busy(struct clk *clk)
-{
-	return __raw_readl(clk->busy_reg) & (1 << clk->busy_bit);
-}
-
-static inline int clk_good(struct clk *clk)
-{
-	return clk && !IS_ERR(clk) && clk->ops;
-}
-
-static int std_clk_enable(struct clk *clk)
-{
-	if (clk->enable_reg) {
-		u32 clk_reg = __raw_readl(clk->enable_reg);
-		if (clk->enable_negate)
-			clk_reg &= ~(1 << clk->enable_shift);
-		else
-			clk_reg |= (1 << clk->enable_shift);
-		__raw_writel(clk_reg, clk->enable_reg);
-		if (clk->enable_wait)
-			udelay(clk->enable_wait);
-		return 0;
-	} else
-		return -EINVAL;
-}
-
-static int std_clk_disable(struct clk *clk)
-{
-	if (clk->enable_reg) {
-		u32 clk_reg = __raw_readl(clk->enable_reg);
-		if (clk->enable_negate)
-			clk_reg |= (1 << clk->enable_shift);
-		else
-			clk_reg &= ~(1 << clk->enable_shift);
-		__raw_writel(clk_reg, clk->enable_reg);
-		return 0;
-	} else
-		return -EINVAL;
-}
-
-static int io_set_rate(struct clk *clk, u32 rate)
-{
-	u32 reg_frac, clkctrl_frac;
-	int i, ret = 0, mask = 0x1f;
-
-	clkctrl_frac = (clk->parent->rate * 18 + rate - 1) / rate;
-
-	if (clkctrl_frac < 18 || clkctrl_frac > 35) {
-		ret = -EINVAL;
-		goto out;
-	}
-
-	reg_frac = __raw_readl(clk->scale_reg);
-	reg_frac &= ~(mask << clk->scale_shift);
-	__raw_writel(reg_frac | (clkctrl_frac << clk->scale_shift),
-				clk->scale_reg);
-	if (clk->busy_reg) {
-		for (i = 10000; i; i--)
-			if (!clk_is_busy(clk))
-				break;
-		if (!i)
-			ret = -ETIMEDOUT;
-		else
-			ret = 0;
-	}
-out:
-	return ret;
-}
-
-static long io_get_rate(struct clk *clk)
-{
-	long rate = clk->parent->rate * 18;
-	int mask = 0x1f;
-
-	rate /= (__raw_readl(clk->scale_reg) >> clk->scale_shift) & mask;
-	clk->rate = rate;
-
-	return rate;
-}
-
-static long per_get_rate(struct clk *clk)
-{
-	long rate = clk->parent->rate;
-	long div;
-	const int mask = 0xff;
-
-	if (clk->enable_reg &&
-			!(__raw_readl(clk->enable_reg) & clk->enable_shift))
-		clk->rate = 0;
-	else {
-		div = (__raw_readl(clk->scale_reg) >> clk->scale_shift) & mask;
-		if (div)
-			rate /= div;
-		clk->rate = rate;
-	}
-
-	return clk->rate;
-}
-
-static int per_set_rate(struct clk *clk, u32 rate)
-{
-	int ret = -EINVAL;
-	int div = (clk->parent->rate + rate - 1) / rate;
-	u32 reg_frac;
-	const int mask = 0xff;
-	int try = 10;
-	int i = -1;
-
-	if (div == 0 || div > mask)
-		goto out;
-
-	reg_frac = __raw_readl(clk->scale_reg);
-	reg_frac &= ~(mask << clk->scale_shift);
-
-	while (try--) {
-		__raw_writel(reg_frac | (div << clk->scale_shift),
-				clk->scale_reg);
-
-		if (clk->busy_reg) {
-			for (i = 10000; i; i--)
-				if (!clk_is_busy(clk))
-					break;
-		}
-		if (i)
-			break;
-	}
-
-	if (!i)
-		ret = -ETIMEDOUT;
-	else
-		ret = 0;
-
-out:
-	if (ret != 0)
-		printk(KERN_ERR "%s: error %d\n", __func__, ret);
-	return ret;
-}
-
-static long lcdif_get_rate(struct clk *clk)
-{
-	long rate = clk->parent->rate;
-	long div;
-	const int mask = 0xff;
-
-	div = (__raw_readl(clk->scale_reg) >> clk->scale_shift) & mask;
-	if (div) {
-		rate /= div;
-		div = (__raw_readl(REGS_CLKCTRL_BASE + HW_CLKCTRL_FRAC) &
-			BM_CLKCTRL_FRAC_PIXFRAC) >> BP_CLKCTRL_FRAC_PIXFRAC;
-		rate /= div;
-	}
-	clk->rate = rate;
-
-	return rate;
-}
-
-static int lcdif_set_rate(struct clk *clk, u32 rate)
-{
-	int ret = 0;
-	/*
-	 * On 3700, we can get most timings exact by modifying ref_pix
-	 * and the divider, but keeping the phase timings at 1 (2
-	 * phases per cycle).
-	 *
-	 * ref_pix can be between 480e6*18/35=246.9MHz and 480e6*18/18=480MHz,
-	 * which is between 18/(18*480e6)=2.084ns and 35/(18*480e6)=4.050ns.
-	 *
-	 * ns_cycle >= 2*18e3/(18*480) = 25/6
-	 * ns_cycle <= 2*35e3/(18*480) = 875/108
-	 *
-	 * Multiply the ns_cycle by 'div' to lengthen it until it fits the
-	 * bounds. This is the divider we'll use after ref_pix.
-	 *
-	 * 6 * ns_cycle >= 25 * div
-	 * 108 * ns_cycle <= 875 * div
-	 */
-	u32 ns_cycle = 1000000 / rate;
-	u32 div, reg_val;
-	u32 lowest_result = (u32) -1;
-	u32 lowest_div = 0, lowest_fracdiv = 0;
-
-	for (div = 1; div < 256; ++div) {
-		u32 fracdiv;
-		u32 ps_result;
-		int lower_bound = 6 * ns_cycle >= 25 * div;
-		int upper_bound = 108 * ns_cycle <= 875 * div;
-		if (!lower_bound)
-			break;
-		if (!upper_bound)
-			continue;
-		/*
-		 * Found a matching div. Calculate fractional divider needed,
-		 * rounded up.
-		 */
-		fracdiv = ((clk->parent->rate / 1000 * 18 / 2) *
-				ns_cycle + 1000 * div - 1) /
-				(1000 * div);
-		if (fracdiv < 18 || fracdiv > 35) {
-			ret = -EINVAL;
-			goto out;
-		}
-		/* Calculate the actual cycle time this results in */
-		ps_result = 6250 * div * fracdiv / 27;
-
-		/* Use the fastest result that doesn't break ns_cycle */
-		if (ps_result <= lowest_result) {
-			lowest_result = ps_result;
-			lowest_div = div;
-			lowest_fracdiv = fracdiv;
-		}
-	}
-
-	if (div >= 256 || lowest_result == (u32) -1) {
-		ret = -EINVAL;
-		goto out;
-	}
-	pr_debug("Programming PFD=%u,DIV=%u ref_pix=%uMHz "
-			"PIXCLK=%uMHz cycle=%u.%03uns\n",
-			lowest_fracdiv, lowest_div,
-			480*18/lowest_fracdiv, 480*18/lowest_fracdiv/lowest_div,
-			lowest_result / 1000, lowest_result % 1000);
-
-	/* Program ref_pix phase fractional divider */
-	reg_val = __raw_readl(REGS_CLKCTRL_BASE + HW_CLKCTRL_FRAC);
-	reg_val &= ~BM_CLKCTRL_FRAC_PIXFRAC;
-	reg_val |= BF(lowest_fracdiv, CLKCTRL_FRAC_PIXFRAC);
-	__raw_writel(reg_val, REGS_CLKCTRL_BASE + HW_CLKCTRL_FRAC);
-
-	/* Ungate PFD */
-	stmp3xxx_clearl(BM_CLKCTRL_FRAC_CLKGATEPIX,
-			REGS_CLKCTRL_BASE + HW_CLKCTRL_FRAC);
-
-	/* Program pix divider */
-	reg_val = __raw_readl(clk->scale_reg);
-	reg_val &= ~(BM_CLKCTRL_PIX_DIV | BM_CLKCTRL_PIX_CLKGATE);
-	reg_val |= BF(lowest_div, CLKCTRL_PIX_DIV);
-	__raw_writel(reg_val, clk->scale_reg);
-
-	/* Wait for divider update */
-	if (clk->busy_reg) {
-		int i;
-		for (i = 10000; i; i--)
-			if (!clk_is_busy(clk))
-				break;
-		if (!i) {
-			ret = -ETIMEDOUT;
-			goto out;
-		}
-	}
-
-	/* Switch to ref_pix source */
-	reg_val = __raw_readl(REGS_CLKCTRL_BASE + HW_CLKCTRL_CLKSEQ);
-	reg_val &= ~BM_CLKCTRL_CLKSEQ_BYPASS_PIX;
-	__raw_writel(reg_val, REGS_CLKCTRL_BASE + HW_CLKCTRL_CLKSEQ);
-
-out:
-	return ret;
-}
-
-
-static int cpu_set_rate(struct clk *clk, u32 rate)
-{
-	u32 reg_val;
-
-	if (rate < 24000)
-		return -EINVAL;
-	else if (rate == 24000) {
-		/* switch to the 24M source */
-		clk_set_parent(clk, &osc_24M);
-	} else {
-		int i;
-		u32 clkctrl_cpu = 1;
-		u32 c = clkctrl_cpu;
-		u32 clkctrl_frac = 1;
-		u32 val;
-		for ( ; c < 0x40; c++) {
-			u32 f = (pll_clk.rate*18/c + rate/2) / rate;
-			int s1, s2;
-
-			if (f < 18 || f > 35)
-				continue;
-			s1 = pll_clk.rate*18/clkctrl_frac/clkctrl_cpu - rate;
-			s2 = pll_clk.rate*18/c/f - rate;
-			pr_debug("%s: s1 %d, s2 %d\n", __func__, s1, s2);
-			if (abs(s1) > abs(s2)) {
-				clkctrl_cpu = c;
-				clkctrl_frac = f;
-			}
-			if (s2 == 0)
-				break;
-		};
-		pr_debug("%s: clkctrl_cpu %d, clkctrl_frac %d\n", __func__,
-				clkctrl_cpu, clkctrl_frac);
-		if (c == 0x40) {
-			int  d = pll_clk.rate*18/clkctrl_frac/clkctrl_cpu -
-				rate;
-			if (abs(d) > 100 ||
-			    clkctrl_frac < 18 || clkctrl_frac > 35)
-				return -EINVAL;
-		}
-
-		/* 4.6.2 */
-		val = __raw_readl(clk->scale_reg);
-		val &= ~(0x3f << clk->scale_shift);
-		val |= clkctrl_frac;
-		clk_set_parent(clk, &osc_24M);
-		udelay(10);
-		__raw_writel(val, clk->scale_reg);
-		/* ungate */
-		__raw_writel(1<<7, clk->scale_reg + 8);
-		/* write clkctrl_cpu */
-		clk->saved_div = clkctrl_cpu;
-
-		reg_val = __raw_readl(REGS_CLKCTRL_BASE + HW_CLKCTRL_CPU);
-		reg_val &= ~0x3F;
-		reg_val |= clkctrl_cpu;
-		__raw_writel(reg_val, REGS_CLKCTRL_BASE + HW_CLKCTRL_CPU);
-
-		for (i = 10000; i; i--)
-			if (!clk_is_busy(clk))
-				break;
-		if (!i) {
-			printk(KERN_ERR "couldn't set up CPU divisor\n");
-			return -ETIMEDOUT;
-		}
-		clk_set_parent(clk, &pll_clk);
-		clk->saved_div = 0;
-		udelay(10);
-	}
-	return 0;
-}
-
-static long cpu_get_rate(struct clk *clk)
-{
-	long rate = clk->parent->rate * 18;
-
-	rate /= (__raw_readl(clk->scale_reg) >> clk->scale_shift) & 0x3f;
-	rate /= __raw_readl(REGS_CLKCTRL_BASE + HW_CLKCTRL_CPU) & 0x3f;
-	rate = ((rate + 9) / 10) * 10;
-	clk->rate = rate;
-
-	return rate;
-}
-
-static long cpu_round_rate(struct clk *clk, u32 rate)
-{
-	unsigned long r = 0;
-
-	if (rate <= 24000)
-		r = 24000;
-	else {
-		u32 clkctrl_cpu = 1;
-		u32 clkctrl_frac;
-		do {
-			clkctrl_frac =
-				(pll_clk.rate*18 / clkctrl_cpu + rate/2) / rate;
-			if (clkctrl_frac > 35)
-				continue;
-			if (pll_clk.rate*18 / clkctrl_frac / clkctrl_cpu/10 ==
-			    rate / 10)
-				break;
-		} while (pll_clk.rate / 2  >= clkctrl_cpu++ * rate);
-		if (pll_clk.rate / 2 < (clkctrl_cpu - 1) * rate)
-			clkctrl_cpu--;
-		pr_debug("%s: clkctrl_cpu %d, clkctrl_frac %d\n", __func__,
-				clkctrl_cpu, clkctrl_frac);
-		if (clkctrl_frac < 18)
-			clkctrl_frac = 18;
-		if (clkctrl_frac > 35)
-			clkctrl_frac = 35;
-
-		r = pll_clk.rate * 18;
-		r /= clkctrl_frac;
-		r /= clkctrl_cpu;
-		r = 10 * ((r + 9) / 10);
-	}
-	return r;
-}
-
-static long emi_get_rate(struct clk *clk)
-{
-	long rate = clk->parent->rate * 18;
-
-	rate /= (__raw_readl(clk->scale_reg) >> clk->scale_shift) & 0x3f;
-	rate /= __raw_readl(REGS_CLKCTRL_BASE + HW_CLKCTRL_EMI) & 0x3f;
-	clk->rate = rate;
-
-	return rate;
-}
-
-static int clkseq_set_parent(struct clk *clk, struct clk *parent)
-{
-	int ret = -EINVAL;
-	int shift = 8;
-
-	/* bypass? */
-	if (parent == &osc_24M)
-		shift = 4;
-
-	if (clk->bypass_reg) {
-#ifdef CONFIG_ARCH_STMP378X
-		u32 hbus_val, cpu_val;
-
-		if (clk == &cpu_clk && shift == 4) {
-			hbus_val = __raw_readl(REGS_CLKCTRL_BASE +
-					HW_CLKCTRL_HBUS);
-			cpu_val = __raw_readl(REGS_CLKCTRL_BASE +
-					HW_CLKCTRL_CPU);
-
-			hbus_val &= ~(BM_CLKCTRL_HBUS_DIV_FRAC_EN |
-				      BM_CLKCTRL_HBUS_DIV);
-			clk->saved_div = cpu_val & BM_CLKCTRL_CPU_DIV_CPU;
-			cpu_val &= ~BM_CLKCTRL_CPU_DIV_CPU;
-			cpu_val |= 1;
-
-			if (machine_is_stmp378x()) {
-				__raw_writel(hbus_val,
-					REGS_CLKCTRL_BASE + HW_CLKCTRL_HBUS);
-				__raw_writel(cpu_val,
-					REGS_CLKCTRL_BASE + HW_CLKCTRL_CPU);
-				hclk.rate = 0;
-			}
-		} else if (clk == &cpu_clk && shift == 8) {
-			hbus_val = __raw_readl(REGS_CLKCTRL_BASE +
-							HW_CLKCTRL_HBUS);
-			cpu_val = __raw_readl(REGS_CLKCTRL_BASE +
-							HW_CLKCTRL_CPU);
-			hbus_val &= ~(BM_CLKCTRL_HBUS_DIV_FRAC_EN |
-				      BM_CLKCTRL_HBUS_DIV);
-			hbus_val |= 2;
-			cpu_val &= ~BM_CLKCTRL_CPU_DIV_CPU;
-			if (clk->saved_div)
-				cpu_val |= clk->saved_div;
-			else
-				cpu_val |= 2;
-
-			if (machine_is_stmp378x()) {
-				__raw_writel(hbus_val,
-					REGS_CLKCTRL_BASE + HW_CLKCTRL_HBUS);
-				__raw_writel(cpu_val,
-					REGS_CLKCTRL_BASE + HW_CLKCTRL_CPU);
-				hclk.rate = 0;
-			}
-		}
-#endif
-		__raw_writel(1 << clk->bypass_shift, clk->bypass_reg + shift);
-
-		ret = 0;
-	}
-
-	return ret;
-}
-
-static int hbus_set_rate(struct clk *clk, u32 rate)
-{
-	u8 div = 0;
-	int is_frac = 0;
-	u32 clkctrl_hbus;
-	struct clk *parent = clk->parent;
-
-	pr_debug("%s: rate %d, parent rate %d\n", __func__, rate,
-			parent->rate);
-
-	if (rate > parent->rate)
-		return -EINVAL;
-
-	if (((parent->rate + rate/2) / rate) * rate != parent->rate &&
-	    parent->rate / rate < 32) {
-		pr_debug("%s: switching to fractional mode\n", __func__);
-		is_frac = 1;
-	}
-
-	if (is_frac)
-		div = (32 * rate + parent->rate / 2) / parent->rate;
-	else
-		div = (parent->rate + rate - 1) / rate;
-	pr_debug("%s: div calculated is %d\n", __func__, div);
-	if (!div || div > 0x1f)
-		return -EINVAL;
-
-	clk_set_parent(&cpu_clk, &osc_24M);
-	udelay(10);
-	clkctrl_hbus = __raw_readl(clk->scale_reg);
-	clkctrl_hbus &= ~0x3f;
-	clkctrl_hbus |= div;
-	clkctrl_hbus |= (is_frac << 5);
-
-	__raw_writel(clkctrl_hbus, clk->scale_reg);
-	if (clk->busy_reg) {
-		int i;
-		for (i = 10000; i; i--)
-			if (!clk_is_busy(clk))
-				break;
-		if (!i) {
-			printk(KERN_ERR "couldn't set up CPU divisor\n");
-			return -ETIMEDOUT;
-		}
-	}
-	clk_set_parent(&cpu_clk, &pll_clk);
-	__raw_writel(clkctrl_hbus, clk->scale_reg);
-	udelay(10);
-	return 0;
-}
-
-static long hbus_get_rate(struct clk *clk)
-{
-	long rate = clk->parent->rate;
-
-	if (__raw_readl(clk->scale_reg) & 0x20) {
-		rate *= __raw_readl(clk->scale_reg) & 0x1f;
-		rate /= 32;
-	} else
-		rate /= __raw_readl(clk->scale_reg) & 0x1f;
-	clk->rate = rate;
-
-	return rate;
-}
-
-static int xbus_set_rate(struct clk *clk, u32 rate)
-{
-	u16 div = 0;
-	u32 clkctrl_xbus;
-
-	pr_debug("%s: rate %d, parent rate %d\n", __func__, rate,
-			clk->parent->rate);
-
-	div = (clk->parent->rate + rate - 1) / rate;
-	pr_debug("%s: div calculated is %d\n", __func__, div);
-	if (!div || div > 0x3ff)
-		return -EINVAL;
-
-	clkctrl_xbus = __raw_readl(clk->scale_reg);
-	clkctrl_xbus &= ~0x3ff;
-	clkctrl_xbus |= div;
-	__raw_writel(clkctrl_xbus, clk->scale_reg);
-	if (clk->busy_reg) {
-		int i;
-		for (i = 10000; i; i--)
-			if (!clk_is_busy(clk))
-				break;
-		if (!i) {
-			printk(KERN_ERR "couldn't set up xbus divisor\n");
-			return -ETIMEDOUT;
-		}
-	}
-	return 0;
-}
-
-static long xbus_get_rate(struct clk *clk)
-{
-	long rate = clk->parent->rate;
-
-	rate /= __raw_readl(clk->scale_reg) & 0x3ff;
-	clk->rate = rate;
-
-	return rate;
-}
-
-
-/* Clock ops */
-
-static struct clk_ops std_ops = {
-	.enable		= std_clk_enable,
-	.disable	= std_clk_disable,
-	.get_rate	= per_get_rate,
-	.set_rate	= per_set_rate,
-	.set_parent	= clkseq_set_parent,
-};
-
-static struct clk_ops min_ops = {
-	.enable		= std_clk_enable,
-	.disable	= std_clk_disable,
-};
-
-static struct clk_ops cpu_ops = {
-	.enable		= std_clk_enable,
-	.disable	= std_clk_disable,
-	.get_rate	= cpu_get_rate,
-	.set_rate	= cpu_set_rate,
-	.round_rate	= cpu_round_rate,
-	.set_parent	= clkseq_set_parent,
-};
-
-static struct clk_ops io_ops = {
-	.enable		= std_clk_enable,
-	.disable	= std_clk_disable,
-	.get_rate	= io_get_rate,
-	.set_rate	= io_set_rate,
-};
-
-static struct clk_ops hbus_ops = {
-	.get_rate	= hbus_get_rate,
-	.set_rate	= hbus_set_rate,
-};
-
-static struct clk_ops xbus_ops = {
-	.get_rate	= xbus_get_rate,
-	.set_rate	= xbus_set_rate,
-};
-
-static struct clk_ops lcdif_ops = {
-	.enable		= std_clk_enable,
-	.disable	= std_clk_disable,
-	.get_rate	= lcdif_get_rate,
-	.set_rate	= lcdif_set_rate,
-	.set_parent	= clkseq_set_parent,
-};
-
-static struct clk_ops emi_ops = {
-	.get_rate	= emi_get_rate,
-};
-
-/* List of on-chip clocks */
-
-static struct clk osc_24M = {
-	.flags		= FIXED_RATE | ENABLED,
-	.rate		= 24000,
-};
-
-static struct clk pll_clk = {
-	.parent		= &osc_24M,
-	.enable_reg	= REGS_CLKCTRL_BASE + HW_CLKCTRL_PLLCTRL0,
-	.enable_shift	= 16,
-	.enable_wait	= 10,
-	.flags		= FIXED_RATE | ENABLED,
-	.rate		= 480000,
-	.ops		= &min_ops,
-};
-
-static struct clk cpu_clk = {
-	.parent		= &pll_clk,
-	.scale_reg	= REGS_CLKCTRL_BASE + HW_CLKCTRL_FRAC,
-	.scale_shift	= 0,
-	.bypass_reg	= REGS_CLKCTRL_BASE + HW_CLKCTRL_CLKSEQ,
-	.bypass_shift	= 7,
-	.busy_reg	= REGS_CLKCTRL_BASE + HW_CLKCTRL_CPU,
-	.busy_bit	= 28,
-	.flags		= RATE_PROPAGATES | ENABLED,
-	.ops		= &cpu_ops,
-};
-
-static struct clk io_clk = {
-	.parent		= &pll_clk,
-	.enable_reg	= REGS_CLKCTRL_BASE + HW_CLKCTRL_FRAC,
-	.enable_shift	= 31,
-	.enable_negate	= 1,
-	.scale_reg	= REGS_CLKCTRL_BASE + HW_CLKCTRL_FRAC,
-	.scale_shift	= 24,
-	.flags		= RATE_PROPAGATES | ENABLED,
-	.ops		= &io_ops,
-};
-
-static struct clk hclk = {
-	.parent		= &cpu_clk,
-	.scale_reg	= REGS_CLKCTRL_BASE + HW_CLKCTRL_HBUS,
-	.bypass_reg	= REGS_CLKCTRL_BASE + HW_CLKCTRL_CLKSEQ,
-	.bypass_shift	= 7,
-	.busy_reg	= REGS_CLKCTRL_BASE + HW_CLKCTRL_HBUS,
-	.busy_bit	= 29,
-	.flags		= RATE_PROPAGATES | ENABLED,
-	.ops		= &hbus_ops,
-};
-
-static struct clk xclk = {
-	.parent		= &osc_24M,
-	.scale_reg	= REGS_CLKCTRL_BASE + HW_CLKCTRL_XBUS,
-	.busy_reg	= REGS_CLKCTRL_BASE + HW_CLKCTRL_XBUS,
-	.busy_bit	= 31,
-	.flags		= RATE_PROPAGATES | ENABLED,
-	.ops		= &xbus_ops,
-};
-
-static struct clk uart_clk = {
-	.parent		= &xclk,
-	.enable_reg	= REGS_CLKCTRL_BASE + HW_CLKCTRL_XTAL,
-	.enable_shift	= 31,
-	.enable_negate	= 1,
-	.flags		= ENABLED,
-	.ops		= &min_ops,
-};
-
-static struct clk audio_clk = {
-	.parent		= &xclk,
-	.enable_reg	= REGS_CLKCTRL_BASE + HW_CLKCTRL_XTAL,
-	.enable_shift	= 30,
-	.enable_negate	= 1,
-	.ops		= &min_ops,
-};
-
-static struct clk pwm_clk = {
-	.parent		= &xclk,
-	.enable_reg	= REGS_CLKCTRL_BASE + HW_CLKCTRL_XTAL,
-	.enable_shift	= 29,
-	.enable_negate	= 1,
-	.ops		= &min_ops,
-};
-
-static struct clk dri_clk = {
-	.parent		= &xclk,
-	.enable_reg	= REGS_CLKCTRL_BASE + HW_CLKCTRL_XTAL,
-	.enable_shift	= 28,
-	.enable_negate	= 1,
-	.ops		= &min_ops,
-};
-
-static struct clk digctl_clk = {
-	.parent		= &xclk,
-	.enable_reg	= REGS_CLKCTRL_BASE + HW_CLKCTRL_XTAL,
-	.enable_shift	= 27,
-	.enable_negate	= 1,
-	.ops		= &min_ops,
-};
-
-static struct clk timer_clk = {
-	.parent		= &xclk,
-	.enable_reg	= REGS_CLKCTRL_BASE + HW_CLKCTRL_XTAL,
-	.enable_shift	= 26,
-	.enable_negate	= 1,
-	.flags		= ENABLED,
-	.ops		= &min_ops,
-};
-
-static struct clk lcdif_clk = {
-	.parent		= &pll_clk,
-	.scale_reg	= REGS_CLKCTRL_BASE + HW_CLKCTRL_PIX,
-	.busy_reg	= REGS_CLKCTRL_BASE + HW_CLKCTRL_PIX,
-	.busy_bit	= 29,
-	.enable_reg	= REGS_CLKCTRL_BASE + HW_CLKCTRL_PIX,
-	.enable_shift	= 31,
-	.enable_negate	= 1,
-	.bypass_reg	= REGS_CLKCTRL_BASE + HW_CLKCTRL_CLKSEQ,
-	.bypass_shift	= 1,
-	.flags		= NEEDS_SET_PARENT,
-	.ops		= &lcdif_ops,
-};
-
-static struct clk ssp_clk = {
-	.parent		= &io_clk,
-	.scale_reg	= REGS_CLKCTRL_BASE + HW_CLKCTRL_SSP,
-	.busy_reg	= REGS_CLKCTRL_BASE + HW_CLKCTRL_SSP,
-	.busy_bit	= 29,
-	.enable_reg	= REGS_CLKCTRL_BASE + HW_CLKCTRL_SSP,
-	.enable_shift	= 31,
-	.bypass_reg	= REGS_CLKCTRL_BASE + HW_CLKCTRL_CLKSEQ,
-	.bypass_shift	= 5,
-	.enable_negate	= 1,
-	.flags		= NEEDS_SET_PARENT,
-	.ops		= &std_ops,
-};
-
-static struct clk gpmi_clk = {
-	.parent		= &io_clk,
-	.scale_reg	= REGS_CLKCTRL_BASE + HW_CLKCTRL_GPMI,
-	.busy_reg	= REGS_CLKCTRL_BASE + HW_CLKCTRL_GPMI,
-	.busy_bit	= 29,
-	.enable_reg	= REGS_CLKCTRL_BASE + HW_CLKCTRL_GPMI,
-	.enable_shift	= 31,
-	.enable_negate	= 1,
-	.bypass_reg	= REGS_CLKCTRL_BASE + HW_CLKCTRL_CLKSEQ,
-	.bypass_shift	= 4,
-	.flags		= NEEDS_SET_PARENT,
-	.ops		= &std_ops,
-};
-
-static struct clk spdif_clk = {
-	.parent		= &pll_clk,
-	.enable_reg	= REGS_CLKCTRL_BASE + HW_CLKCTRL_SPDIF,
-	.enable_shift	= 31,
-	.enable_negate	= 1,
-	.ops		= &min_ops,
-};
-
-static struct clk emi_clk = {
-	.parent		= &pll_clk,
-	.enable_reg	= REGS_CLKCTRL_BASE + HW_CLKCTRL_EMI,
-	.enable_shift	= 31,
-	.enable_negate	= 1,
-	.scale_reg	= REGS_CLKCTRL_BASE + HW_CLKCTRL_FRAC,
-	.scale_shift	= 8,
-	.busy_reg	= REGS_CLKCTRL_BASE + HW_CLKCTRL_EMI,
-	.busy_bit	= 28,
-	.bypass_reg	= REGS_CLKCTRL_BASE + HW_CLKCTRL_CLKSEQ,
-	.bypass_shift	= 6,
-	.flags		= ENABLED,
-	.ops		= &emi_ops,
-};
-
-static struct clk ir_clk = {
-	.parent		= &io_clk,
-	.enable_reg	= REGS_CLKCTRL_BASE + HW_CLKCTRL_IR,
-	.enable_shift	= 31,
-	.enable_negate	= 1,
-	.bypass_reg	= REGS_CLKCTRL_BASE + HW_CLKCTRL_CLKSEQ,
-	.bypass_shift	= 3,
-	.ops		= &min_ops,
-};
-
-static struct clk saif_clk = {
-	.parent		= &pll_clk,
-	.scale_reg	= REGS_CLKCTRL_BASE + HW_CLKCTRL_SAIF,
-	.busy_reg	= REGS_CLKCTRL_BASE + HW_CLKCTRL_SAIF,
-	.busy_bit	= 29,
-	.enable_reg	= REGS_CLKCTRL_BASE + HW_CLKCTRL_SAIF,
-	.enable_shift	= 31,
-	.enable_negate	= 1,
-	.bypass_reg	= REGS_CLKCTRL_BASE + HW_CLKCTRL_CLKSEQ,
-	.bypass_shift	= 0,
-	.ops		= &std_ops,
-};
-
-static struct clk usb_clk = {
-	.parent		= &pll_clk,
-	.enable_reg	= REGS_CLKCTRL_BASE + HW_CLKCTRL_PLLCTRL0,
-	.enable_shift	= 18,
-	.enable_negate	= 1,
-	.ops		= &min_ops,
-};
-
-/* list of all the clocks */
-static struct clk_lookup onchip_clks[] = {
-	{
-		.con_id = "osc_24M",
-		.clk = &osc_24M,
-	}, {
-		.con_id = "pll",
-		.clk = &pll_clk,
-	}, {
-		.con_id = "cpu",
-		.clk = &cpu_clk,
-	}, {
-		.con_id = "hclk",
-		.clk = &hclk,
-	}, {
-		.con_id = "xclk",
-		.clk = &xclk,
-	}, {
-		.con_id = "io",
-		.clk = &io_clk,
-	}, {
-		.con_id = "uart",
-		.clk = &uart_clk,
-	}, {
-		.con_id = "audio",
-		.clk = &audio_clk,
-	}, {
-		.con_id = "pwm",
-		.clk = &pwm_clk,
-	}, {
-		.con_id = "dri",
-		.clk = &dri_clk,
-	}, {
-		.con_id = "digctl",
-		.clk = &digctl_clk,
-	}, {
-		.con_id = "timer",
-		.clk = &timer_clk,
-	}, {
-		.con_id = "lcdif",
-		.clk = &lcdif_clk,
-	}, {
-		.con_id = "ssp",
-		.clk = &ssp_clk,
-	}, {
-		.con_id = "gpmi",
-		.clk = &gpmi_clk,
-	}, {
-		.con_id = "spdif",
-		.clk = &spdif_clk,
-	}, {
-		.con_id = "emi",
-		.clk = &emi_clk,
-	}, {
-		.con_id = "ir",
-		.clk = &ir_clk,
-	}, {
-		.con_id = "saif",
-		.clk = &saif_clk,
-	}, {
-		.con_id = "usb",
-		.clk = &usb_clk,
-	},
-};
-
-static int __init propagate_rate(struct clk *clk)
-{
-	struct clk_lookup *cl;
-
-	for (cl = onchip_clks; cl < onchip_clks + ARRAY_SIZE(onchip_clks);
-	     cl++) {
-		if (unlikely(!clk_good(cl->clk)))
-			continue;
-		if (cl->clk->parent == clk && cl->clk->ops->get_rate) {
-			cl->clk->ops->get_rate(cl->clk);
-			if (cl->clk->flags & RATE_PROPAGATES)
-				propagate_rate(cl->clk);
-		}
-	}
-
-	return 0;
-}
-
-/* Exported API */
-unsigned long clk_get_rate(struct clk *clk)
-{
-	if (unlikely(!clk_good(clk)))
-		return 0;
-
-	if (clk->rate != 0)
-		return clk->rate;
-
-	if (clk->ops->get_rate != NULL)
-		return clk->ops->get_rate(clk);
-
-	return clk_get_rate(clk->parent);
-}
-EXPORT_SYMBOL(clk_get_rate);
-
-long clk_round_rate(struct clk *clk, unsigned long rate)
-{
-	if (unlikely(!clk_good(clk)))
-		return 0;
-
-	if (clk->ops->round_rate)
-		return clk->ops->round_rate(clk, rate);
-
-	return 0;
-}
-EXPORT_SYMBOL(clk_round_rate);
-
-static inline int close_enough(long rate1, long rate2)
-{
-	return rate1 && !((rate2 - rate1) * 1000 / rate1);
-}
-
-int clk_set_rate(struct clk *clk, unsigned long rate)
-{
-	int ret = -EINVAL;
-
-	if (unlikely(!clk_good(clk)))
-		goto out;
-
-	if (clk->flags & FIXED_RATE || !clk->ops->set_rate)
-		goto out;
-
-	else if (!close_enough(clk->rate, rate)) {
-		ret = clk->ops->set_rate(clk, rate);
-		if (ret < 0)
-			goto out;
-		clk->rate = rate;
-		if (clk->flags & RATE_PROPAGATES)
-			propagate_rate(clk);
-	} else
-		ret = 0;
-
-out:
-	return ret;
-}
-EXPORT_SYMBOL(clk_set_rate);
-
-int clk_enable(struct clk *clk)
-{
-	unsigned long clocks_flags;
-
-	if (unlikely(!clk_good(clk)))
-		return -EINVAL;
-
-	if (clk->parent)
-		clk_enable(clk->parent);
-
-	spin_lock_irqsave(&clocks_lock, clocks_flags);
-
-	clk->usage++;
-	if (clk->ops && clk->ops->enable)
-		clk->ops->enable(clk);
-
-	spin_unlock_irqrestore(&clocks_lock, clocks_flags);
-	return 0;
-}
-EXPORT_SYMBOL(clk_enable);
-
-static void local_clk_disable(struct clk *clk)
-{
-	if (unlikely(!clk_good(clk)))
-		return;
-
-	if (clk->usage == 0 && clk->ops->disable)
-		clk->ops->disable(clk);
-
-	if (clk->parent)
-		local_clk_disable(clk->parent);
-}
-
-void clk_disable(struct clk *clk)
-{
-	unsigned long clocks_flags;
-
-	if (unlikely(!clk_good(clk)))
-		return;
-
-	spin_lock_irqsave(&clocks_lock, clocks_flags);
-
-	if ((--clk->usage) == 0 && clk->ops->disable)
-		clk->ops->disable(clk);
-
-	spin_unlock_irqrestore(&clocks_lock, clocks_flags);
-	if (clk->parent)
-		clk_disable(clk->parent);
-}
-EXPORT_SYMBOL(clk_disable);
-
-/* Some additional API */
-int clk_set_parent(struct clk *clk, struct clk *parent)
-{
-	int ret = -ENODEV;
-	unsigned long clocks_flags;
-
-	if (unlikely(!clk_good(clk)))
-		goto out;
-
-	if (!clk->ops->set_parent)
-		goto out;
-
-	spin_lock_irqsave(&clocks_lock, clocks_flags);
-
-	ret = clk->ops->set_parent(clk, parent);
-	if (!ret) {
-		/* disable if usage count is 0 */
-		local_clk_disable(parent);
-
-		parent->usage += clk->usage;
-		clk->parent->usage -= clk->usage;
-
-		/* disable if new usage count is 0 */
-		local_clk_disable(clk->parent);
-
-		clk->parent = parent;
-	}
-	spin_unlock_irqrestore(&clocks_lock, clocks_flags);
-
-out:
-	return ret;
-}
-EXPORT_SYMBOL(clk_set_parent);
-
-struct clk *clk_get_parent(struct clk *clk)
-{
-	if (unlikely(!clk_good(clk)))
-		return NULL;
-	return clk->parent;
-}
-EXPORT_SYMBOL(clk_get_parent);
-
-static int __init clk_init(void)
-{
-	struct clk_lookup *cl;
-	struct clk_ops *ops;
-
-	spin_lock_init(&clocks_lock);
-
-	for (cl = onchip_clks; cl < onchip_clks + ARRAY_SIZE(onchip_clks);
-	     cl++) {
-		if (cl->clk->flags & ENABLED)
-			clk_enable(cl->clk);
-		else
-			local_clk_disable(cl->clk);
-
-		ops = cl->clk->ops;
-
-		if ((cl->clk->flags & NEEDS_INITIALIZATION) &&
-				ops && ops->set_rate)
-			ops->set_rate(cl->clk, cl->clk->rate);
-
-		if (cl->clk->flags & FIXED_RATE) {
-			if (cl->clk->flags & RATE_PROPAGATES)
-				propagate_rate(cl->clk);
-		} else {
-			if (ops && ops->get_rate)
-				ops->get_rate(cl->clk);
-		}
-
-		if (cl->clk->flags & NEEDS_SET_PARENT) {
-			if (ops && ops->set_parent)
-				ops->set_parent(cl->clk, cl->clk->parent);
-		}
-	}
-	clkdev_add_table(onchip_clks, ARRAY_SIZE(onchip_clks));
-	return 0;
-}
-
-arch_initcall(clk_init);
diff -druN linux-2.6.39-libre/arch/arm/plat-stmp3xxx/clock.h linux-3.0-rc7-libre/arch/arm/plat-stmp3xxx/clock.h
--- linux-2.6.39-libre/arch/arm/plat-stmp3xxx/clock.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/plat-stmp3xxx/clock.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,61 +0,0 @@
-/*
- * Clock control driver for Freescale STMP37XX/STMP378X - internal header file
- *
- * Author: Vitaly Wool <vital@embeddedalley.com>
- *
- * Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved.
- * Copyright 2008 Embedded Alley Solutions, 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_STMX3XXX_CLOCK_H__
-#define __ARCH_ARM_STMX3XXX_CLOCK_H__
-
-#ifndef __ASSEMBLER__
-
-struct clk_ops {
-	int (*enable) (struct clk *);
-	int (*disable) (struct clk *);
-	long (*get_rate) (struct clk *);
-	long (*round_rate) (struct clk *, u32);
-	int (*set_rate) (struct clk *, u32);
-	int (*set_parent) (struct clk *, struct clk *);
-};
-
-struct clk {
-	struct clk *parent;
-	u32 rate;
-	u32 flags;
-	u8 scale_shift;
-	u8 enable_shift;
-	u8 bypass_shift;
-	u8 busy_bit;
-	s8 usage;
-	int enable_wait;
-	int enable_negate;
-	u32 saved_div;
-	void __iomem *enable_reg;
-	void __iomem *scale_reg;
-	void __iomem *bypass_reg;
-	void __iomem *busy_reg;
-	struct clk_ops *ops;
-};
-
-#endif /* __ASSEMBLER__ */
-
-/* Flags */
-#define RATE_PROPAGATES      (1<<0)
-#define NEEDS_INITIALIZATION (1<<1)
-#define PARENT_SET_RATE      (1<<2)
-#define FIXED_RATE           (1<<3)
-#define ENABLED	             (1<<4)
-#define NEEDS_SET_PARENT     (1<<5)
-
-#endif
diff -druN linux-2.6.39-libre/arch/arm/plat-stmp3xxx/core.c linux-3.0-rc7-libre/arch/arm/plat-stmp3xxx/core.c
--- linux-2.6.39-libre/arch/arm/plat-stmp3xxx/core.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/plat-stmp3xxx/core.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,128 +0,0 @@
-/*
- * Freescale STMP37XX/STMP378X core routines
- *
- * Embedded Alley Solutions, Inc <source@embeddedalley.com>
- *
- * Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved.
- * Copyright 2008 Embedded Alley Solutions, 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/kernel.h>
-#include <linux/init.h>
-#include <linux/io.h>
-
-#include <mach/stmp3xxx.h>
-#include <mach/platform.h>
-#include <mach/dma.h>
-#include <mach/regs-clkctrl.h>
-
-static int __stmp3xxx_reset_block(void __iomem *hwreg, int just_enable)
-{
-	u32 c;
-	int timeout;
-
-	/* the process of software reset of IP block is done
-	   in several steps:
-
-	   - clear SFTRST and wait for block is enabled;
-	   - clear clock gating (CLKGATE bit);
-	   - set the SFTRST again and wait for block is in reset;
-	   - clear SFTRST and wait for reset completion.
-	*/
-	c = __raw_readl(hwreg);
-	c &= ~(1<<31);		/* clear SFTRST */
-	__raw_writel(c, hwreg);
-	for (timeout = 1000000; timeout > 0; timeout--)
-		/* still in SFTRST state ? */
-		if ((__raw_readl(hwreg) & (1<<31)) == 0)
-			break;
-	if (timeout <= 0) {
-		printk(KERN_ERR"%s(%p): timeout when enabling\n",
-				__func__, hwreg);
-		return -ETIME;
-	}
-
-	c = __raw_readl(hwreg);
-	c &= ~(1<<30);		/* clear CLKGATE */
-	__raw_writel(c, hwreg);
-
-	if (!just_enable) {
-		c = __raw_readl(hwreg);
-		c |= (1<<31);		/* now again set SFTRST */
-		__raw_writel(c, hwreg);
-		for (timeout = 1000000; timeout > 0; timeout--)
-			/* poll until CLKGATE set */
-			if (__raw_readl(hwreg) & (1<<30))
-				break;
-		if (timeout <= 0) {
-			printk(KERN_ERR"%s(%p): timeout when resetting\n",
-					__func__, hwreg);
-			return -ETIME;
-		}
-
-		c = __raw_readl(hwreg);
-		c &= ~(1<<31);		/* clear SFTRST */
-		__raw_writel(c, hwreg);
-		for (timeout = 1000000; timeout > 0; timeout--)
-			/* still in SFTRST state ? */
-			if ((__raw_readl(hwreg) & (1<<31)) == 0)
-				break;
-		if (timeout <= 0) {
-			printk(KERN_ERR"%s(%p): timeout when enabling "
-					"after reset\n", __func__, hwreg);
-			return -ETIME;
-		}
-
-		c = __raw_readl(hwreg);
-		c &= ~(1<<30);		/* clear CLKGATE */
-		__raw_writel(c, hwreg);
-	}
-	for (timeout = 1000000; timeout > 0; timeout--)
-		/* still in SFTRST state ? */
-		if ((__raw_readl(hwreg) & (1<<30)) == 0)
-			break;
-
-	if (timeout <= 0) {
-		printk(KERN_ERR"%s(%p): timeout when unclockgating\n",
-				__func__, hwreg);
-		return -ETIME;
-	}
-
-	return 0;
-}
-
-int stmp3xxx_reset_block(void __iomem *hwreg, int just_enable)
-{
-	int try = 10;
-	int r;
-
-	while (try--) {
-		r = __stmp3xxx_reset_block(hwreg, just_enable);
-		if (!r)
-			break;
-		pr_debug("%s: try %d failed\n", __func__, 10 - try);
-	}
-	return r;
-}
-EXPORT_SYMBOL(stmp3xxx_reset_block);
-
-struct platform_device stmp3xxx_dbguart = {
-	.name = "stmp3xxx-dbguart",
-	.id = -1,
-};
-
-void __init stmp3xxx_init(void)
-{
-	/* Turn off auto-slow and other tricks */
-	stmp3xxx_clearl(0x7f00000, REGS_CLKCTRL_BASE + HW_CLKCTRL_HBUS);
-
-	stmp3xxx_dma_init();
-}
diff -druN linux-2.6.39-libre/arch/arm/plat-stmp3xxx/devices.c linux-3.0-rc7-libre/arch/arm/plat-stmp3xxx/devices.c
--- linux-2.6.39-libre/arch/arm/plat-stmp3xxx/devices.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/plat-stmp3xxx/devices.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,389 +0,0 @@
-/*
-* Freescale STMP37XX/STMP378X platform devices
-*
-* Embedded Alley Solutions, Inc <source@embeddedalley.com>
-*
-* Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved.
-* Copyright 2008 Embedded Alley Solutions, 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/kernel.h>
-#include <linux/init.h>
-#include <linux/device.h>
-#include <linux/platform_device.h>
-#include <linux/dma-mapping.h>
-
-#include <mach/dma.h>
-#include <mach/platform.h>
-#include <mach/stmp3xxx.h>
-#include <mach/regs-lcdif.h>
-#include <mach/regs-uartapp.h>
-#include <mach/regs-gpmi.h>
-#include <mach/regs-usbctrl.h>
-#include <mach/regs-ssp.h>
-#include <mach/regs-rtc.h>
-
-static u64 common_dmamask = DMA_BIT_MASK(32);
-
-static struct resource appuart_resources[] = {
-	{
-		.start = IRQ_UARTAPP_INTERNAL,
-		.end = IRQ_UARTAPP_INTERNAL,
-		.flags = IORESOURCE_IRQ,
-	}, {
-		.start = IRQ_UARTAPP_RX_DMA,
-		.end = IRQ_UARTAPP_RX_DMA,
-		.flags = IORESOURCE_IRQ,
-	}, {
-		.start = IRQ_UARTAPP_TX_DMA,
-		.end = IRQ_UARTAPP_TX_DMA,
-		.flags = IORESOURCE_IRQ,
-	}, {
-		.start = REGS_UARTAPP1_PHYS,
-		.end = REGS_UARTAPP1_PHYS + REGS_UARTAPP_SIZE,
-		.flags = IORESOURCE_MEM,
-	}, {
-		/* Rx DMA channel */
-		.start = STMP3XXX_DMA(6, STMP3XXX_BUS_APBX),
-		.end = STMP3XXX_DMA(6, STMP3XXX_BUS_APBX),
-		.flags = IORESOURCE_DMA,
-	}, {
-		/* Tx DMA channel */
-		.start = STMP3XXX_DMA(7, STMP3XXX_BUS_APBX),
-		.end = STMP3XXX_DMA(7, STMP3XXX_BUS_APBX),
-		.flags = IORESOURCE_DMA,
-	},
-};
-
-struct platform_device stmp3xxx_appuart = {
-	.name = "stmp3xxx-appuart",
-	.id = 0,
-	.resource = appuart_resources,
-	.num_resources = ARRAY_SIZE(appuart_resources),
-	.dev = {
-		.dma_mask	= &common_dmamask,
-		.coherent_dma_mask = DMA_BIT_MASK(32),
-	},
-};
-
-struct platform_device stmp3xxx_watchdog = {
-      .name   = "stmp3xxx_wdt",
-      .id     = -1,
-};
-
-static struct resource ts_resource[] = {
-	{
-		.flags  = IORESOURCE_IRQ,
-		.start  = IRQ_TOUCH_DETECT,
-		.end    = IRQ_TOUCH_DETECT,
-	}, {
-		.flags  = IORESOURCE_IRQ,
-		.start  = IRQ_LRADC_CH5,
-		.end    = IRQ_LRADC_CH5,
-	},
-};
-
-struct platform_device stmp3xxx_touchscreen = {
-	.name		= "stmp3xxx_ts",
-	.id		= -1,
-	.resource	= ts_resource,
-	.num_resources	= ARRAY_SIZE(ts_resource),
-};
-
-/*
-* Keypad device
-*/
-struct platform_device stmp3xxx_keyboard = {
-	.name		= "stmp3xxx-keyboard",
-	.id		= -1,
-};
-
-static struct resource gpmi_resources[] = {
-	{
-		.flags = IORESOURCE_MEM,
-		.start = REGS_GPMI_PHYS,
-		.end = REGS_GPMI_PHYS + REGS_GPMI_SIZE,
-	}, {
-		.flags = IORESOURCE_IRQ,
-		.start = IRQ_GPMI_DMA,
-		.end = IRQ_GPMI_DMA,
-	}, {
-		.flags = IORESOURCE_DMA,
-		.start = STMP3XXX_DMA(4, STMP3XXX_BUS_APBH),
-		.end = STMP3XXX_DMA(8, STMP3XXX_BUS_APBH),
-	},
-};
-
-struct platform_device stmp3xxx_gpmi = {
-	.name = "gpmi",
-	.id = -1,
-	.dev	= {
-		.dma_mask	= &common_dmamask,
-		.coherent_dma_mask = DMA_BIT_MASK(32),
-	},
-	.resource = gpmi_resources,
-	.num_resources = ARRAY_SIZE(gpmi_resources),
-};
-
-static struct resource mmc1_resource[] = {
-	{
-		.flags	= IORESOURCE_MEM,
-		.start	= REGS_SSP1_PHYS,
-		.end	= REGS_SSP1_PHYS + REGS_SSP_SIZE,
-	}, {
-		.flags	= IORESOURCE_DMA,
-		.start	= STMP3XXX_DMA(1, STMP3XXX_BUS_APBH),
-		.end	= STMP3XXX_DMA(1, STMP3XXX_BUS_APBH),
-	}, {
-		.flags	= IORESOURCE_IRQ,
-		.start	= IRQ_SSP1_DMA,
-		.end	= IRQ_SSP1_DMA,
-	}, {
-		.flags	= IORESOURCE_IRQ,
-		.start	= IRQ_SSP_ERROR,
-		.end	= IRQ_SSP_ERROR,
-	},
-};
-
-struct platform_device stmp3xxx_mmc = {
-	.name	= "stmp3xxx-mmc",
-	.id	= 1,
-	.dev	= {
-		.dma_mask	= &common_dmamask,
-		.coherent_dma_mask = DMA_BIT_MASK(32),
-	},
-	.resource = mmc1_resource,
-	.num_resources = ARRAY_SIZE(mmc1_resource),
-};
-
-static struct resource usb_resources[] = {
-	{
-		.start	= REGS_USBCTRL_PHYS,
-		.end	= REGS_USBCTRL_PHYS + SZ_4K,
-		.flags	= IORESOURCE_MEM,
-	}, {
-		.start	= IRQ_USB_CTRL,
-		.end	= IRQ_USB_CTRL,
-		.flags	= IORESOURCE_IRQ,
-	},
-};
-
-struct platform_device stmp3xxx_udc = {
-	.name		= "fsl-usb2-udc",
-	.id		= -1,
-	.dev		= {
-		.dma_mask		= &common_dmamask,
-		.coherent_dma_mask	= DMA_BIT_MASK(32),
-	},
-	.resource = usb_resources,
-	.num_resources = ARRAY_SIZE(usb_resources),
-};
-
-struct platform_device stmp3xxx_ehci = {
-	.name		= "fsl-ehci",
-	.id		= -1,
-	.dev		= {
-		.dma_mask		= &common_dmamask,
-		.coherent_dma_mask	= DMA_BIT_MASK(32),
-	},
-	.resource	= usb_resources,
-	.num_resources	= ARRAY_SIZE(usb_resources),
-};
-
-static struct resource rtc_resources[] = {
-	{
-		.start	= REGS_RTC_PHYS,
-		.end	= REGS_RTC_PHYS + REGS_RTC_SIZE,
-		.flags	= IORESOURCE_MEM,
-	}, {
-		.start	= IRQ_RTC_ALARM,
-		.end	= IRQ_RTC_ALARM,
-		.flags	= IORESOURCE_IRQ,
-	}, {
-		.start	= IRQ_RTC_1MSEC,
-		.end	= IRQ_RTC_1MSEC,
-		.flags	= IORESOURCE_IRQ,
-	},
-};
-
-struct platform_device stmp3xxx_rtc = {
-	.name		= "stmp3xxx-rtc",
-	.id		= -1,
-	.resource	= rtc_resources,
-	.num_resources	= ARRAY_SIZE(rtc_resources),
-};
-
-static struct resource ssp1_resources[] = {
-	{
-		.start	= REGS_SSP1_PHYS,
-		.end	= REGS_SSP1_PHYS + REGS_SSP_SIZE,
-		.flags	= IORESOURCE_MEM,
-	}, {
-		.start	= IRQ_SSP1_DMA,
-		.end	= IRQ_SSP1_DMA,
-		.flags	= IORESOURCE_IRQ,
-	}, {
-		.start	= STMP3XXX_DMA(1, STMP3XXX_BUS_APBH),
-		.end	= STMP3XXX_DMA(1, STMP3XXX_BUS_APBH),
-		.flags	= IORESOURCE_DMA,
-	},
-};
-
-static struct resource ssp2_resources[] = {
-	{
-		.start	= REGS_SSP2_PHYS,
-		.end	= REGS_SSP2_PHYS + REGS_SSP_SIZE,
-		.flags	= IORESOURCE_MEM,
-	}, {
-		.start	= IRQ_SSP2_DMA,
-		.end	= IRQ_SSP2_DMA,
-		.flags	= IORESOURCE_IRQ,
-	}, {
-		.start	= STMP3XXX_DMA(2, STMP3XXX_BUS_APBH),
-		.end	= STMP3XXX_DMA(2, STMP3XXX_BUS_APBH),
-		.flags	= IORESOURCE_DMA,
-	},
-};
-
-struct platform_device stmp3xxx_spi1 = {
-	.name	= "stmp3xxx_ssp",
-	.id	= 1,
-	.dev	= {
-		.dma_mask	= &common_dmamask,
-		.coherent_dma_mask = DMA_BIT_MASK(32),
-	},
-	.resource = ssp1_resources,
-	.num_resources = ARRAY_SIZE(ssp1_resources),
-};
-
-struct platform_device stmp3xxx_spi2 = {
-	.name	= "stmp3xxx_ssp",
-	.id	= 2,
-	.dev	= {
-		.dma_mask	= &common_dmamask,
-		.coherent_dma_mask = DMA_BIT_MASK(32),
-	},
-	.resource = ssp2_resources,
-	.num_resources = ARRAY_SIZE(ssp2_resources),
-};
-
-static struct resource fb_resource[] = {
-	{
-		.flags	= IORESOURCE_IRQ,
-		.start	= IRQ_LCDIF_DMA,
-		.end	= IRQ_LCDIF_DMA,
-	}, {
-		.flags	= IORESOURCE_IRQ,
-		.start	= IRQ_LCDIF_ERROR,
-		.end	= IRQ_LCDIF_ERROR,
-	}, {
-		.flags	= IORESOURCE_MEM,
-		.start	= REGS_LCDIF_PHYS,
-		.end	= REGS_LCDIF_PHYS + REGS_LCDIF_SIZE,
-	},
-};
-
-struct platform_device stmp3xxx_framebuffer = {
-	.name		= "stmp3xxx-fb",
-	.id		= -1,
-	.dev		= {
-		.dma_mask		= &common_dmamask,
-		.coherent_dma_mask	= DMA_BIT_MASK(32),
-	},
-	.num_resources	= ARRAY_SIZE(fb_resource),
-	.resource	= fb_resource,
-};
-
-#define CMDLINE_DEVICE_CHOOSE(name, dev1, dev2)			\
-	static char *cmdline_device_##name;			\
-	static int cmdline_device_##name##_setup(char *dev)	\
-	{							\
-		cmdline_device_##name = dev + 1;		\
-		return 0;					\
-	}							\
-	__setup(#name, cmdline_device_##name##_setup);		\
-	int stmp3xxx_##name##_device_register(void)		\
-	{							\
-		struct platform_device *d = NULL;		\
-		if (!cmdline_device_##name ||			\
-			!strcmp(cmdline_device_##name, #dev1))	\
-				d = &stmp3xxx_##dev1;		\
-		else if (!strcmp(cmdline_device_##name, #dev2))	\
-				d = &stmp3xxx_##dev2;		\
-		else						\
-			printk(KERN_ERR"Unknown %s assignment '%s'.\n",	\
-				#name, cmdline_device_##name);	\
-		return d ? platform_device_register(d) : -ENOENT;	\
-	}
-
-CMDLINE_DEVICE_CHOOSE(ssp1, mmc, spi1)
-CMDLINE_DEVICE_CHOOSE(ssp2, gpmi, spi2)
-
-struct platform_device stmp3xxx_backlight = {
-	.name		= "stmp3xxx-bl",
-	.id		= -1,
-};
-
-struct platform_device stmp3xxx_rotdec = {
-	.name	= "stmp3xxx-rotdec",
-	.id	= -1,
-};
-
-struct platform_device stmp3xxx_persistent = {
-	.name			= "stmp3xxx-persistent",
-	.id			= -1,
-};
-
-struct platform_device stmp3xxx_dcp_bootstream = {
-	.name			= "stmp3xxx-dcpboot",
-	.id			= -1,
-	.dev	= {
-		.dma_mask	= &common_dmamask,
-		.coherent_dma_mask = DMA_BIT_MASK(32),
-	},
-};
-
-static struct resource dcp_resources[] = {
-	{
-		.start = IRQ_DCP_VMI,
-		.end = IRQ_DCP_VMI,
-		.flags = IORESOURCE_IRQ,
-	}, {
-		.start = IRQ_DCP,
-		.end = IRQ_DCP,
-		.flags = IORESOURCE_IRQ,
-	},
-};
-
-struct platform_device stmp3xxx_dcp = {
-	.name			= "stmp3xxx-dcp",
-	.id			= -1,
-	.resource		= dcp_resources,
-	.num_resources		= ARRAY_SIZE(dcp_resources),
-	.dev	= {
-		.dma_mask	= &common_dmamask,
-		.coherent_dma_mask = DMA_BIT_MASK(32),
-	},
-};
-
-static struct resource battery_resource[] = {
-	{
-		.flags  = IORESOURCE_IRQ,
-		.start  = IRQ_VDD5V,
-		.end    = IRQ_VDD5V,
-	},
-};
-
-struct platform_device stmp3xxx_battery = {
-	.name   = "stmp3xxx-battery",
-	.resource = battery_resource,
-	.num_resources = ARRAY_SIZE(battery_resource),
-};
diff -druN linux-2.6.39-libre/arch/arm/plat-stmp3xxx/dma.c linux-3.0-rc7-libre/arch/arm/plat-stmp3xxx/dma.c
--- linux-2.6.39-libre/arch/arm/plat-stmp3xxx/dma.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/plat-stmp3xxx/dma.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,464 +0,0 @@
-/*
- * DMA helper routines for Freescale STMP37XX/STMP378X
- *
- * Author: dmitry pervushin <dpervushin@embeddedalley.com>
- *
- * Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved.
- * Copyright 2008 Embedded Alley Solutions, 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/gfp.h>
-#include <linux/kernel.h>
-#include <linux/device.h>
-#include <linux/dmapool.h>
-#include <linux/sysdev.h>
-#include <linux/cpufreq.h>
-
-#include <asm/page.h>
-
-#include <mach/platform.h>
-#include <mach/dma.h>
-#include <mach/regs-apbx.h>
-#include <mach/regs-apbh.h>
-
-static const size_t pool_item_size = sizeof(struct stmp3xxx_dma_command);
-static const size_t pool_alignment = 8;
-static struct stmp3xxx_dma_user {
-	void *pool;
-	int inuse;
-	const char *name;
-} channels[MAX_DMA_CHANNELS];
-
-#define IS_VALID_CHANNEL(ch) ((ch) >= 0 && (ch) < MAX_DMA_CHANNELS)
-#define IS_USED(ch) (channels[ch].inuse)
-
-int stmp3xxx_dma_request(int ch, struct device *dev, const char *name)
-{
-	struct stmp3xxx_dma_user *user;
-	int err = 0;
-
-	user = channels + ch;
-	if (!IS_VALID_CHANNEL(ch)) {
-		err = -ENODEV;
-		goto out;
-	}
-	if (IS_USED(ch)) {
-		err = -EBUSY;
-		goto out;
-	}
-	/* Create a pool to allocate dma commands from */
-	user->pool = dma_pool_create(name, dev, pool_item_size,
-				     pool_alignment, PAGE_SIZE);
-	if (user->pool == NULL) {
-		err = -ENOMEM;
-		goto out;
-	}
-	user->name = name;
-	user->inuse++;
-out:
-	return err;
-}
-EXPORT_SYMBOL(stmp3xxx_dma_request);
-
-int stmp3xxx_dma_release(int ch)
-{
-	struct stmp3xxx_dma_user *user = channels + ch;
-	int err = 0;
-
-	if (!IS_VALID_CHANNEL(ch)) {
-		err = -ENODEV;
-		goto out;
-	}
-	if (!IS_USED(ch)) {
-		err = -EBUSY;
-		goto out;
-	}
-	BUG_ON(user->pool == NULL);
-	dma_pool_destroy(user->pool);
-	user->inuse--;
-out:
-	return err;
-}
-EXPORT_SYMBOL(stmp3xxx_dma_release);
-
-int stmp3xxx_dma_read_semaphore(int channel)
-{
-	int sem = -1;
-
-	switch (STMP3XXX_DMA_BUS(channel)) {
-	case STMP3XXX_BUS_APBH:
-		sem = __raw_readl(REGS_APBH_BASE + HW_APBH_CHn_SEMA +
-				STMP3XXX_DMA_CHANNEL(channel) * 0x70);
-		sem &= BM_APBH_CHn_SEMA_PHORE;
-		sem >>= BP_APBH_CHn_SEMA_PHORE;
-		break;
-
-	case STMP3XXX_BUS_APBX:
-		sem = __raw_readl(REGS_APBX_BASE + HW_APBX_CHn_SEMA +
-				STMP3XXX_DMA_CHANNEL(channel) * 0x70);
-		sem &= BM_APBX_CHn_SEMA_PHORE;
-		sem >>= BP_APBX_CHn_SEMA_PHORE;
-		break;
-	default:
-		BUG();
-	}
-	return sem;
-}
-EXPORT_SYMBOL(stmp3xxx_dma_read_semaphore);
-
-int stmp3xxx_dma_allocate_command(int channel,
-				  struct stmp3xxx_dma_descriptor *descriptor)
-{
-	struct stmp3xxx_dma_user *user = channels + channel;
-	int err = 0;
-
-	if (!IS_VALID_CHANNEL(channel)) {
-		err = -ENODEV;
-		goto out;
-	}
-	if (!IS_USED(channel)) {
-		err = -EBUSY;
-		goto out;
-	}
-	if (descriptor == NULL) {
-		err = -EINVAL;
-		goto out;
-	}
-
-	/* Allocate memory for a command from the buffer */
-	descriptor->command =
-	    dma_pool_alloc(user->pool, GFP_KERNEL, &descriptor->handle);
-
-	/* Check it worked */
-	if (!descriptor->command) {
-		err = -ENOMEM;
-		goto out;
-	}
-
-	memset(descriptor->command, 0, pool_item_size);
-out:
-	WARN_ON(err);
-	return err;
-}
-EXPORT_SYMBOL(stmp3xxx_dma_allocate_command);
-
-int stmp3xxx_dma_free_command(int channel,
-			      struct stmp3xxx_dma_descriptor *descriptor)
-{
-	int err = 0;
-
-	if (!IS_VALID_CHANNEL(channel)) {
-		err = -ENODEV;
-		goto out;
-	}
-	if (!IS_USED(channel)) {
-		err = -EBUSY;
-		goto out;
-	}
-
-	/* Return the command memory to the pool */
-	dma_pool_free(channels[channel].pool, descriptor->command,
-		      descriptor->handle);
-
-	/* Initialise descriptor so we're not tempted to use it */
-	descriptor->command = NULL;
-	descriptor->handle = 0;
-	descriptor->virtual_buf_ptr = NULL;
-	descriptor->next_descr = NULL;
-
-	WARN_ON(err);
-out:
-	return err;
-}
-EXPORT_SYMBOL(stmp3xxx_dma_free_command);
-
-void stmp3xxx_dma_go(int channel,
-		     struct stmp3xxx_dma_descriptor *head, u32 semaphore)
-{
-	int ch = STMP3XXX_DMA_CHANNEL(channel);
-	void __iomem *c, *s;
-
-	switch (STMP3XXX_DMA_BUS(channel)) {
-	case STMP3XXX_BUS_APBH:
-		c = REGS_APBH_BASE + HW_APBH_CHn_NXTCMDAR + 0x70 * ch;
-		s = REGS_APBH_BASE + HW_APBH_CHn_SEMA + 0x70 * ch;
-		break;
-
-	case STMP3XXX_BUS_APBX:
-		c = REGS_APBX_BASE + HW_APBX_CHn_NXTCMDAR + 0x70 * ch;
-		s = REGS_APBX_BASE + HW_APBX_CHn_SEMA + 0x70 * ch;
-		break;
-
-	default:
-		return;
-	}
-
-	/* Set next command */
-	__raw_writel(head->handle, c);
-	/* Set counting semaphore (kicks off transfer). Assumes
-	   peripheral has been set up correctly */
-	__raw_writel(semaphore, s);
-}
-EXPORT_SYMBOL(stmp3xxx_dma_go);
-
-int stmp3xxx_dma_running(int channel)
-{
-	switch (STMP3XXX_DMA_BUS(channel)) {
-	case STMP3XXX_BUS_APBH:
-		return (__raw_readl(REGS_APBH_BASE + HW_APBH_CHn_SEMA +
-			0x70 * STMP3XXX_DMA_CHANNEL(channel))) &
-			    BM_APBH_CHn_SEMA_PHORE;
-
-	case STMP3XXX_BUS_APBX:
-		return (__raw_readl(REGS_APBX_BASE + HW_APBX_CHn_SEMA +
-			0x70 * STMP3XXX_DMA_CHANNEL(channel))) &
-			    BM_APBX_CHn_SEMA_PHORE;
-	default:
-		BUG();
-		return 0;
-	}
-}
-EXPORT_SYMBOL(stmp3xxx_dma_running);
-
-/*
- * Circular dma chain management
- */
-void stmp3xxx_dma_free_chain(struct stmp37xx_circ_dma_chain *chain)
-{
-	int i;
-
-	for (i = 0; i < chain->total_count; i++)
-		stmp3xxx_dma_free_command(
-			STMP3XXX_DMA(chain->channel, chain->bus),
-			&chain->chain[i]);
-}
-EXPORT_SYMBOL(stmp3xxx_dma_free_chain);
-
-int stmp3xxx_dma_make_chain(int ch, struct stmp37xx_circ_dma_chain *chain,
-			    struct stmp3xxx_dma_descriptor descriptors[],
-			    unsigned items)
-{
-	int i;
-	int err = 0;
-
-	if (items == 0)
-		return err;
-
-	for (i = 0; i < items; i++) {
-		err = stmp3xxx_dma_allocate_command(ch, &descriptors[i]);
-		if (err) {
-			WARN_ON(err);
-			/*
-			 * Couldn't allocate the whole chain.
-			 * deallocate what has been allocated
-			 */
-			if (i) {
-				do {
-					stmp3xxx_dma_free_command(ch,
-								  &descriptors
-								  [i]);
-				} while (i-- > 0);
-			}
-			return err;
-		}
-
-		/* link them! */
-		if (i > 0) {
-			descriptors[i - 1].next_descr = &descriptors[i];
-			descriptors[i - 1].command->next =
-						descriptors[i].handle;
-		}
-	}
-
-	/* make list circular */
-	descriptors[items - 1].next_descr = &descriptors[0];
-	descriptors[items - 1].command->next = descriptors[0].handle;
-
-	chain->total_count = items;
-	chain->chain = descriptors;
-	chain->free_index = 0;
-	chain->active_index = 0;
-	chain->cooked_index = 0;
-	chain->free_count = items;
-	chain->active_count = 0;
-	chain->cooked_count = 0;
-	chain->bus = STMP3XXX_DMA_BUS(ch);
-	chain->channel = STMP3XXX_DMA_CHANNEL(ch);
-	return err;
-}
-EXPORT_SYMBOL(stmp3xxx_dma_make_chain);
-
-void stmp37xx_circ_clear_chain(struct stmp37xx_circ_dma_chain *chain)
-{
-	BUG_ON(stmp3xxx_dma_running(STMP3XXX_DMA(chain->channel, chain->bus)));
-	chain->free_index = 0;
-	chain->active_index = 0;
-	chain->cooked_index = 0;
-	chain->free_count = chain->total_count;
-	chain->active_count = 0;
-	chain->cooked_count = 0;
-}
-EXPORT_SYMBOL(stmp37xx_circ_clear_chain);
-
-void stmp37xx_circ_advance_free(struct stmp37xx_circ_dma_chain *chain,
-		unsigned count)
-{
-	BUG_ON(chain->cooked_count < count);
-
-	chain->cooked_count -= count;
-	chain->cooked_index += count;
-	chain->cooked_index %= chain->total_count;
-	chain->free_count += count;
-}
-EXPORT_SYMBOL(stmp37xx_circ_advance_free);
-
-void stmp37xx_circ_advance_active(struct stmp37xx_circ_dma_chain *chain,
-		unsigned count)
-{
-	void __iomem *c;
-	u32 mask_clr, mask;
-	BUG_ON(chain->free_count < count);
-
-	chain->free_count -= count;
-	chain->free_index += count;
-	chain->free_index %= chain->total_count;
-	chain->active_count += count;
-
-	switch (chain->bus) {
-	case STMP3XXX_BUS_APBH:
-		c = REGS_APBH_BASE + HW_APBH_CHn_SEMA + 0x70 * chain->channel;
-		mask_clr = BM_APBH_CHn_SEMA_INCREMENT_SEMA;
-		mask = BF(count, APBH_CHn_SEMA_INCREMENT_SEMA);
-		break;
-	case STMP3XXX_BUS_APBX:
-		c = REGS_APBX_BASE + HW_APBX_CHn_SEMA + 0x70 * chain->channel;
-		mask_clr = BM_APBX_CHn_SEMA_INCREMENT_SEMA;
-		mask = BF(count, APBX_CHn_SEMA_INCREMENT_SEMA);
-		break;
-	default:
-		BUG();
-		return;
-	}
-
-	/* Set counting semaphore (kicks off transfer). Assumes
-	   peripheral has been set up correctly */
-	stmp3xxx_clearl(mask_clr, c);
-	stmp3xxx_setl(mask, c);
-}
-EXPORT_SYMBOL(stmp37xx_circ_advance_active);
-
-unsigned stmp37xx_circ_advance_cooked(struct stmp37xx_circ_dma_chain *chain)
-{
-	unsigned cooked;
-
-	cooked = chain->active_count -
-	  stmp3xxx_dma_read_semaphore(STMP3XXX_DMA(chain->channel, chain->bus));
-
-	chain->active_count -= cooked;
-	chain->active_index += cooked;
-	chain->active_index %= chain->total_count;
-
-	chain->cooked_count += cooked;
-
-	return cooked;
-}
-EXPORT_SYMBOL(stmp37xx_circ_advance_cooked);
-
-void stmp3xxx_dma_set_alt_target(int channel, int function)
-{
-#if defined(CONFIG_ARCH_STMP37XX)
-	unsigned bits = 4;
-#elif defined(CONFIG_ARCH_STMP378X)
-	unsigned bits = 2;
-#else
-#error wrong arch
-#endif
-	int shift = STMP3XXX_DMA_CHANNEL(channel) * bits;
-	unsigned mask = (1<<bits) - 1;
-	void __iomem *c;
-
-	BUG_ON(function < 0 || function >= (1<<bits));
-	pr_debug("%s: channel = %d, using mask %x, "
-		 "shift = %d\n", __func__, channel, mask, shift);
-
-	switch (STMP3XXX_DMA_BUS(channel)) {
-	case STMP3XXX_BUS_APBH:
-		c = REGS_APBH_BASE + HW_APBH_DEVSEL;
-		break;
-	case STMP3XXX_BUS_APBX:
-		c = REGS_APBX_BASE + HW_APBX_DEVSEL;
-		break;
-	default:
-		BUG();
-	}
-	stmp3xxx_clearl(mask << shift, c);
-	stmp3xxx_setl(mask << shift, c);
-}
-EXPORT_SYMBOL(stmp3xxx_dma_set_alt_target);
-
-void stmp3xxx_dma_suspend(void)
-{
-	stmp3xxx_setl(BM_APBH_CTRL0_CLKGATE, REGS_APBH_BASE + HW_APBH_CTRL0);
-	stmp3xxx_setl(BM_APBX_CTRL0_CLKGATE, REGS_APBX_BASE + HW_APBX_CTRL0);
-}
-
-void stmp3xxx_dma_resume(void)
-{
-	stmp3xxx_clearl(BM_APBH_CTRL0_CLKGATE | BM_APBH_CTRL0_SFTRST,
-			REGS_APBH_BASE + HW_APBH_CTRL0);
-	stmp3xxx_clearl(BM_APBX_CTRL0_CLKGATE | BM_APBX_CTRL0_SFTRST,
-			REGS_APBX_BASE + HW_APBX_CTRL0);
-}
-
-#ifdef CONFIG_CPU_FREQ
-
-struct dma_notifier_block {
-	struct notifier_block nb;
-	void *data;
-};
-
-static int dma_cpufreq_notifier(struct notifier_block *self,
-				unsigned long phase, void *p)
-{
-	switch (phase) {
-	case CPUFREQ_POSTCHANGE:
-		stmp3xxx_dma_resume();
-		break;
-
-	case CPUFREQ_PRECHANGE:
-		stmp3xxx_dma_suspend();
-		break;
-
-	default:
-		break;
-	}
-
-	return NOTIFY_DONE;
-}
-
-static struct dma_notifier_block dma_cpufreq_nb = {
-	.nb = {
-		.notifier_call = dma_cpufreq_notifier,
-	},
-};
-#endif /* CONFIG_CPU_FREQ */
-
-void __init stmp3xxx_dma_init(void)
-{
-	stmp3xxx_clearl(BM_APBH_CTRL0_CLKGATE | BM_APBH_CTRL0_SFTRST,
-			REGS_APBH_BASE + HW_APBH_CTRL0);
-	stmp3xxx_clearl(BM_APBX_CTRL0_CLKGATE | BM_APBX_CTRL0_SFTRST,
-			REGS_APBX_BASE + HW_APBX_CTRL0);
-#ifdef CONFIG_CPU_FREQ
-	cpufreq_register_notifier(&dma_cpufreq_nb.nb,
-				CPUFREQ_TRANSITION_NOTIFIER);
-#endif /* CONFIG_CPU_FREQ */
-}
diff -druN linux-2.6.39-libre/arch/arm/plat-stmp3xxx/include/mach/clkdev.h linux-3.0-rc7-libre/arch/arm/plat-stmp3xxx/include/mach/clkdev.h
--- linux-2.6.39-libre/arch/arm/plat-stmp3xxx/include/mach/clkdev.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/plat-stmp3xxx/include/mach/clkdev.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,18 +0,0 @@
-/*
- * Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved.
- * Copyright 2008 Embedded Alley Solutions, 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 __ASM_MACH_CLKDEV_H
-#define __ASM_MACH_CLKDEV_H
-
-#define __clk_get(clk) ({ 1; })
-#define __clk_put(clk) do { } while (0)
-
-#endif
diff -druN linux-2.6.39-libre/arch/arm/plat-stmp3xxx/include/mach/cputype.h linux-3.0-rc7-libre/arch/arm/plat-stmp3xxx/include/mach/cputype.h
--- linux-2.6.39-libre/arch/arm/plat-stmp3xxx/include/mach/cputype.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/plat-stmp3xxx/include/mach/cputype.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,33 +0,0 @@
-/*
- * Freescale STMP37XX/STMP378X CPU type detection
- *
- * Embedded Alley Solutions, Inc <source@embeddedalley.com>
- *
- * Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved.
- * Copyright 2008 Embedded Alley Solutions, 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 __ASM_PLAT_CPU_H
-#define __ASM_PLAT_CPU_H
-
-#ifdef CONFIG_ARCH_STMP37XX
-#define cpu_is_stmp37xx()	(1)
-#else
-#define cpu_is_stmp37xx()	(0)
-#endif
-
-#ifdef CONFIG_ARCH_STMP378X
-#define cpu_is_stmp378x()	(1)
-#else
-#define cpu_is_stmp378x()	(0)
-#endif
-
-#endif /* __ASM_PLAT_CPU_H */
diff -druN linux-2.6.39-libre/arch/arm/plat-stmp3xxx/include/mach/debug-macro.S linux-3.0-rc7-libre/arch/arm/plat-stmp3xxx/include/mach/debug-macro.S
--- linux-2.6.39-libre/arch/arm/plat-stmp3xxx/include/mach/debug-macro.S	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/plat-stmp3xxx/include/mach/debug-macro.S	1969-12-31 19:00:00.000000000 -0500
@@ -1,39 +0,0 @@
-/*
- * Debugging macro include header
- *
- * Embedded Alley Solutions, Inc <source@embeddedalley.com>
- *
- * Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved.
- * Copyright 2008 Embedded Alley Solutions, 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
- */
-
-		.macro	addruart, rp, rv
-		mov	\rp,      #0x00070000
-		add	\rv, \rp, #0xf0000000	@ virtual base
-		add	\rp, \rp, #0x80000000	@ physical base
-		.endm
-
-		.macro	senduart,rd,rx
-		strb	\rd, [\rx, #0]		@ data register at 0
-		.endm
-
-		.macro	waituart,rd,rx
-1001:		ldr	\rd, [\rx, #0x18]	@ UARTFLG
-		tst	\rd, #1 << 5		@ UARTFLGUTXFF - 1 when full
-		bne	1001b
-		.endm
-
-		.macro	busyuart,rd,rx
-1001:		ldr	\rd, [\rx, #0x18]	@ UARTFLG
-		tst	\rd, #1 << 3		@ UARTFLGUBUSY - 1 when busy
-		bne	1001b
-		.endm
diff -druN linux-2.6.39-libre/arch/arm/plat-stmp3xxx/include/mach/dma.h linux-3.0-rc7-libre/arch/arm/plat-stmp3xxx/include/mach/dma.h
--- linux-2.6.39-libre/arch/arm/plat-stmp3xxx/include/mach/dma.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/plat-stmp3xxx/include/mach/dma.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,153 +0,0 @@
-/*
- * Freescale STMP37XX/STMP378X DMA helper interface
- *
- * Embedded Alley Solutions, Inc <source@embeddedalley.com>
- *
- * Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved.
- * Copyright 2008 Embedded Alley Solutions, 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 __ASM_PLAT_STMP3XXX_DMA_H
-#define __ASM_PLAT_STMP3XXX_DMA_H
-
-#include <linux/platform_device.h>
-#include <linux/dmapool.h>
-
-#if !defined(MAX_PIO_WORDS)
-#define MAX_PIO_WORDS   (15)
-#endif
-
-#define STMP3XXX_BUS_APBH		0
-#define STMP3XXX_BUS_APBX		1
-#define STMP3XXX_DMA_MAX_CHANNEL	16
-#define STMP3XXX_DMA_BUS(dma)		((dma) / 16)
-#define STMP3XXX_DMA_CHANNEL(dma)	((dma) % 16)
-#define STMP3XXX_DMA(channel, bus)	((bus) * 16 + (channel))
-#define MAX_DMA_ADDRESS			0xffffffff
-#define MAX_DMA_CHANNELS		32
-
-struct stmp3xxx_dma_command {
-	u32 next;
-	u32 cmd;
-	union {
-		u32 buf_ptr;
-		u32 alternate;
-	};
-	u32 pio_words[MAX_PIO_WORDS];
-};
-
-struct stmp3xxx_dma_descriptor {
-	struct stmp3xxx_dma_command *command;
-	dma_addr_t handle;
-
-	/* The virtual address of the buffer pointer */
-	void *virtual_buf_ptr;
-	/* The next descriptor in a the DMA chain (optional) */
-	struct stmp3xxx_dma_descriptor *next_descr;
-};
-
-struct stmp37xx_circ_dma_chain {
-	unsigned total_count;
-	struct stmp3xxx_dma_descriptor *chain;
-
-	unsigned free_index;
-	unsigned free_count;
-	unsigned active_index;
-	unsigned active_count;
-	unsigned cooked_index;
-	unsigned cooked_count;
-
-	int bus;
-	unsigned channel;
-};
-
-static inline struct stmp3xxx_dma_descriptor
-    *stmp3xxx_dma_circ_get_free_head(struct stmp37xx_circ_dma_chain *chain)
-{
-	return &(chain->chain[chain->free_index]);
-}
-
-static inline struct stmp3xxx_dma_descriptor
-    *stmp3xxx_dma_circ_get_cooked_head(struct stmp37xx_circ_dma_chain *chain)
-{
-	return &(chain->chain[chain->cooked_index]);
-}
-
-int stmp3xxx_dma_request(int ch, struct device *dev, const char *name);
-int stmp3xxx_dma_release(int ch);
-int stmp3xxx_dma_allocate_command(int ch,
-				  struct stmp3xxx_dma_descriptor *descriptor);
-int stmp3xxx_dma_free_command(int ch,
-			      struct stmp3xxx_dma_descriptor *descriptor);
-void stmp3xxx_dma_continue(int channel, u32 semaphore);
-void stmp3xxx_dma_go(int ch, struct stmp3xxx_dma_descriptor *head,
-		     u32 semaphore);
-int stmp3xxx_dma_running(int ch);
-int stmp3xxx_dma_make_chain(int ch, struct stmp37xx_circ_dma_chain *chain,
-			    struct stmp3xxx_dma_descriptor descriptors[],
-			    unsigned items);
-void stmp3xxx_dma_free_chain(struct stmp37xx_circ_dma_chain *chain);
-void stmp37xx_circ_clear_chain(struct stmp37xx_circ_dma_chain *chain);
-void stmp37xx_circ_advance_free(struct stmp37xx_circ_dma_chain *chain,
-		unsigned count);
-void stmp37xx_circ_advance_active(struct stmp37xx_circ_dma_chain *chain,
-		unsigned count);
-unsigned stmp37xx_circ_advance_cooked(struct stmp37xx_circ_dma_chain *chain);
-int stmp3xxx_dma_read_semaphore(int ch);
-void stmp3xxx_dma_init(void);
-void stmp3xxx_dma_set_alt_target(int ch, int target);
-void stmp3xxx_dma_suspend(void);
-void stmp3xxx_dma_resume(void);
-
-/*
- * STMP37xx and STMP378x have different DMA control
- * registers layout
- */
-
-void stmp3xxx_arch_dma_freeze(int ch);
-void stmp3xxx_arch_dma_unfreeze(int ch);
-void stmp3xxx_arch_dma_reset_channel(int ch);
-void stmp3xxx_arch_dma_enable_interrupt(int ch);
-void stmp3xxx_arch_dma_clear_interrupt(int ch);
-int stmp3xxx_arch_dma_is_interrupt(int ch);
-
-static inline void stmp3xxx_dma_reset_channel(int ch)
-{
-	stmp3xxx_arch_dma_reset_channel(ch);
-}
-
-
-static inline void stmp3xxx_dma_freeze(int ch)
-{
-	stmp3xxx_arch_dma_freeze(ch);
-}
-
-static inline void stmp3xxx_dma_unfreeze(int ch)
-{
-	stmp3xxx_arch_dma_unfreeze(ch);
-}
-
-static inline void stmp3xxx_dma_enable_interrupt(int ch)
-{
-	stmp3xxx_arch_dma_enable_interrupt(ch);
-}
-
-static inline void stmp3xxx_dma_clear_interrupt(int ch)
-{
-	stmp3xxx_arch_dma_clear_interrupt(ch);
-}
-
-static inline int stmp3xxx_dma_is_interrupt(int ch)
-{
-	return stmp3xxx_arch_dma_is_interrupt(ch);
-}
-
-#endif /* __ASM_PLAT_STMP3XXX_DMA_H */
diff -druN linux-2.6.39-libre/arch/arm/plat-stmp3xxx/include/mach/gpio.h linux-3.0-rc7-libre/arch/arm/plat-stmp3xxx/include/mach/gpio.h
--- linux-2.6.39-libre/arch/arm/plat-stmp3xxx/include/mach/gpio.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/plat-stmp3xxx/include/mach/gpio.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,28 +0,0 @@
-/*
- * Freescale STMP37XX/STMP378X GPIO interface
- *
- * Embedded Alley Solutions, Inc <source@embeddedalley.com>
- *
- * Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved.
- * Copyright 2008 Embedded Alley Solutions, 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 __ASM_PLAT_GPIO_H
-#define __ASM_PLAT_GPIO_H
-
-#define ARCH_NR_GPIOS	(32 * 3)
-#define gpio_to_irq(gpio) __gpio_to_irq(gpio)
-#define gpio_get_value(gpio) __gpio_get_value(gpio)
-#define gpio_set_value(gpio, value) __gpio_set_value(gpio, value)
-
-#include <asm-generic/gpio.h>
-
-#endif /* __ASM_PLAT_GPIO_H */
diff -druN linux-2.6.39-libre/arch/arm/plat-stmp3xxx/include/mach/gpmi.h linux-3.0-rc7-libre/arch/arm/plat-stmp3xxx/include/mach/gpmi.h
--- linux-2.6.39-libre/arch/arm/plat-stmp3xxx/include/mach/gpmi.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/plat-stmp3xxx/include/mach/gpmi.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,12 +0,0 @@
-#ifndef __MACH_GPMI_H
-
-#include <linux/mtd/partitions.h>
-#include <mach/regs-gpmi.h>
-
-struct gpmi_platform_data {
-	void *pins;
-	int nr_parts;
-	struct mtd_partition *parts;
-	const char *part_types[];
-};
-#endif
diff -druN linux-2.6.39-libre/arch/arm/plat-stmp3xxx/include/mach/hardware.h linux-3.0-rc7-libre/arch/arm/plat-stmp3xxx/include/mach/hardware.h
--- linux-2.6.39-libre/arch/arm/plat-stmp3xxx/include/mach/hardware.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/plat-stmp3xxx/include/mach/hardware.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,32 +0,0 @@
-/*
- * This file contains the hardware definitions of the Freescale STMP3XXX
- *
- * Copyright (C) 2005 Sigmatel Inc
- *
- * Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved.
- * Copyright 2008 Embedded Alley Solutions, 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 __ASM_ARCH_HARDWARE_H
-#define __ASM_ARCH_HARDWARE_H
-
-/*
- * Where in virtual memory the IO devices (timers, system controllers
- * and so on)
- */
-#define IO_BASE			0xF0000000                 /* VA of IO  */
-#define IO_SIZE			0x00100000                 /* How much? */
-#define IO_START		0x80000000                 /* PA of IO  */
-
-/* macro to get at IO space when running virtually */
-#define IO_ADDRESS(x) (((x) & 0x000fffff) | IO_BASE)
-
-#endif
diff -druN linux-2.6.39-libre/arch/arm/plat-stmp3xxx/include/mach/io.h linux-3.0-rc7-libre/arch/arm/plat-stmp3xxx/include/mach/io.h
--- linux-2.6.39-libre/arch/arm/plat-stmp3xxx/include/mach/io.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/plat-stmp3xxx/include/mach/io.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,25 +0,0 @@
-/*
- * Copyright (C) 2005 Sigmatel Inc
- *
- * Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved.
- * Copyright 2008 Embedded Alley Solutions, 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 __ASM_ARM_ARCH_IO_H
-#define __ASM_ARM_ARCH_IO_H
-
-#define IO_SPACE_LIMIT 0xffffffff
-
-#define __io(a) 	__typesafe_io(a)
-#define __mem_pci(a)	(a)
-#define __mem_isa(a)	(a)
-
-#endif
diff -druN linux-2.6.39-libre/arch/arm/plat-stmp3xxx/include/mach/memory.h linux-3.0-rc7-libre/arch/arm/plat-stmp3xxx/include/mach/memory.h
--- linux-2.6.39-libre/arch/arm/plat-stmp3xxx/include/mach/memory.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/plat-stmp3xxx/include/mach/memory.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,22 +0,0 @@
-/*
- * Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved.
- * Copyright 2008 Embedded Alley Solutions, 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 __ASM_ARCH_MEMORY_H
-#define __ASM_ARCH_MEMORY_H
-
-/*
- * Physical DRAM offset.
- */
-#define PLAT_PHYS_OFFSET	UL(0x40000000)
-
-#endif
diff -druN linux-2.6.39-libre/arch/arm/plat-stmp3xxx/include/mach/mmc.h linux-3.0-rc7-libre/arch/arm/plat-stmp3xxx/include/mach/mmc.h
--- linux-2.6.39-libre/arch/arm/plat-stmp3xxx/include/mach/mmc.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/plat-stmp3xxx/include/mach/mmc.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,14 +0,0 @@
-#ifndef _MACH_MMC_H
-#define _MACH_MMC_H
-
-#include <mach/regs-ssp.h>
-
-struct stmp3xxxmmc_platform_data {
-	int (*get_wp)(void);
-	unsigned long (*setclock)(void __iomem *base, unsigned long);
-	void (*cmd_pullup)(int);
-	int  (*hw_init)(void);
-	void (*hw_release)(void);
-};
-
-#endif
diff -druN linux-2.6.39-libre/arch/arm/plat-stmp3xxx/include/mach/pinmux.h linux-3.0-rc7-libre/arch/arm/plat-stmp3xxx/include/mach/pinmux.h
--- linux-2.6.39-libre/arch/arm/plat-stmp3xxx/include/mach/pinmux.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/plat-stmp3xxx/include/mach/pinmux.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,157 +0,0 @@
-/*
- * Freescale STMP37XX/STMP378X Pin Multiplexing
- *
- * Author: Vladislav Buzov <vbuzov@embeddedalley.com>
- *
- * Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved.
- * Copyright 2008 Embedded Alley Solutions, 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 __PINMUX_H
-#define __PINMUX_H
-
-#include <linux/spinlock.h>
-#include <linux/types.h>
-#include <linux/gpio.h>
-#include <asm-generic/gpio.h>
-
-/* Pin definitions */
-#include "pins.h"
-#include <mach/pins.h>
-
-/*
- * Each pin may be routed up to four different HW interfaces
- * including GPIO
- */
-enum pin_fun {
-	PIN_FUN1 = 0,
-	PIN_FUN2,
-	PIN_FUN3,
-	PIN_GPIO,
-};
-
-/*
- * Each pin may have different output drive strength in range from
- * 4mA to 20mA. The most common case is 4, 8 and 12 mA strengths.
- */
-enum pin_strength {
-	PIN_4MA = 0,
-	PIN_8MA,
-	PIN_12MA,
-	PIN_16MA,
-	PIN_20MA,
-};
-
-/*
- * Each pin can be programmed for 1.8V or 3.3V
- */
-enum pin_voltage {
-	PIN_1_8V = 0,
-	PIN_3_3V,
-};
-
-/*
- * Structure to define a group of pins and their parameters
- */
-struct pin_desc {
-	unsigned id;
-	enum pin_fun fun;
-	enum pin_strength strength;
-	enum pin_voltage voltage;
-	unsigned pullup:1;
-};
-
-struct pin_group {
-	struct pin_desc *pins;
-	int nr_pins;
-};
-
-/* Set pin drive strength */
-void stmp3xxx_pin_strength(unsigned id, enum pin_strength strength,
-			   const char *label);
-
-/* Set pin voltage */
-void stmp3xxx_pin_voltage(unsigned id, enum pin_voltage voltage,
-			   const char *label);
-
-/* Enable pull-up resistor for a pin */
-void stmp3xxx_pin_pullup(unsigned id, int enable, const char *label);
-
-/*
- * Request a pin ownership, only one module (identified by @label)
- * may own a pin.
- */
-int stmp3xxx_request_pin(unsigned id, enum pin_fun fun, const char *label);
-
-/* Release pin */
-void stmp3xxx_release_pin(unsigned id, const char *label);
-
-void stmp3xxx_set_pin_type(unsigned id, enum pin_fun fun);
-
-/*
- * Each bank is associated with a number of registers to control
- * pin function, drive strength, voltage and pull-up reigster. The
- * number of registers of a given type depends on the number of bits
- * describin particular pin.
- */
-#define HW_MUXSEL_NUM		2	/* registers per bank */
-#define HW_MUXSEL_PIN_LEN	2	/* bits per pin */
-#define HW_MUXSEL_PIN_NUM	16	/* pins per register */
-#define HW_MUXSEL_PINFUN_MASK	0x3	/* pin function mask */
-#define HW_MUXSEL_PINFUN_NUM	4	/* four options for a pin */
-
-#define HW_DRIVE_NUM		4	/* registers per bank */
-#define HW_DRIVE_PIN_LEN	4	/* bits per pin */
-#define HW_DRIVE_PIN_NUM	8	/* pins per register */
-#define HW_DRIVE_PINDRV_MASK	0x3	/* pin strength mask - 2 bits */
-#define HW_DRIVE_PINDRV_NUM	5	/* five possible strength values */
-#define HW_DRIVE_PINV_MASK	0x4	/* pin voltage mask - 1 bit */
-
-
-struct stmp3xxx_pinmux_bank {
-	struct gpio_chip chip;
-
-	/* Pins allocation map */
-	unsigned long pin_map;
-
-	/* Pin owner names */
-	const char *pin_labels[32];
-
-	/* Bank registers */
-	void __iomem *hw_muxsel[HW_MUXSEL_NUM];
-	void __iomem *hw_drive[HW_DRIVE_NUM];
-	void __iomem *hw_pull;
-
-	void __iomem *pin2irq,
-		*irqlevel,
-		*irqpolarity,
-		*irqen,
-		*irqstat;
-
-	/* HW MUXSEL register function bit values */
-	u8 functions[HW_MUXSEL_PINFUN_NUM];
-
-	/*
-	 * HW DRIVE register strength bit values:
-	 * 0xff - requested strength is not supported for this bank
-	 */
-	u8 strengths[HW_DRIVE_PINDRV_NUM];
-
-	/* GPIO things */
-	void __iomem *hw_gpio_in,
-		     *hw_gpio_out,
-		     *hw_gpio_doe;
-	int irq, virq;
-};
-
-int __init stmp3xxx_pinmux_init(int virtual_irq_start);
-
-#endif /* __PINMUX_H */
diff -druN linux-2.6.39-libre/arch/arm/plat-stmp3xxx/include/mach/pins.h linux-3.0-rc7-libre/arch/arm/plat-stmp3xxx/include/mach/pins.h
--- linux-2.6.39-libre/arch/arm/plat-stmp3xxx/include/mach/pins.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/plat-stmp3xxx/include/mach/pins.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,30 +0,0 @@
-/*
- * Freescale STMP37XX/STMP378X Pin multiplexing interface definitions
- *
- * Author: Vladislav Buzov <vbuzov@embeddedalley.com>
- *
- * Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved.
- * Copyright 2008 Embedded Alley Solutions, 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 __ASM_PLAT_PINS_H
-#define __ASM_PLAT_PINS_H
-
-#define STMP3XXX_PINID(bank, pin)	(bank * 32 + pin)
-#define STMP3XXX_PINID_TO_BANK(pinid)	(pinid / 32)
-#define STMP3XXX_PINID_TO_PINNUM(pinid)	(pinid % 32)
-
-/*
- * Special invalid pin identificator to show a pin doesn't exist
- */
-#define PINID_NO_PIN	STMP3XXX_PINID(0xFF, 0xFF)
-
-#endif /* __ASM_PLAT_PINS_H */
diff -druN linux-2.6.39-libre/arch/arm/plat-stmp3xxx/include/mach/platform.h linux-3.0-rc7-libre/arch/arm/plat-stmp3xxx/include/mach/platform.h
--- linux-2.6.39-libre/arch/arm/plat-stmp3xxx/include/mach/platform.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/plat-stmp3xxx/include/mach/platform.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,68 +0,0 @@
-/*
- * Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved.
- * Copyright 2008 Embedded Alley Solutions, 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 __ASM_PLAT_PLATFORM_H
-#define __ASM_PLAT_PLATFORM_H
-
-#ifndef __ASSEMBLER__
-#include <linux/io.h>
-#endif
-#include <asm/sizes.h>
-
-/* Virtual address where registers are mapped */
-#define STMP3XXX_REGS_PHBASE	0x80000000
-#ifdef __ASSEMBLER__
-#define STMP3XXX_REGS_BASE	0xF0000000
-#else
-#define STMP3XXX_REGS_BASE	(void __iomem *)0xF0000000
-#endif
-#define STMP3XXX_REGS_SIZE	SZ_1M
-
-/* Virtual address where OCRAM is mapped */
-#define STMP3XXX_OCRAM_PHBASE	0x00000000
-#ifdef __ASSEMBLER__
-#define STMP3XXX_OCRAM_BASE	0xf1000000
-#else
-#define STMP3XXX_OCRAM_BASE	(void __iomem *)0xf1000000
-#endif
-#define STMP3XXX_OCRAM_SIZE	(32 * SZ_1K)
-
-#ifdef CONFIG_ARCH_STMP37XX
-#define IRQ_PRIORITY_REG_RD	HW_ICOLL_PRIORITYn_RD
-#define IRQ_PRIORITY_REG_WR	HW_ICOLL_PRIORITYn_WR
-#endif
-
-#ifdef CONFIG_ARCH_STMP378X
-#define IRQ_PRIORITY_REG_RD	HW_ICOLL_INTERRUPTn_RD
-#define IRQ_PRIORITY_REG_WR	HW_ICOLL_INTERRUPTn_WR
-#endif
-
-#define HW_STMP3XXX_SET		0x04
-#define HW_STMP3XXX_CLR		0x08
-#define HW_STMP3XXX_TOG		0x0c
-
-#ifndef __ASSEMBLER__
-static inline void stmp3xxx_clearl(u32 v, void __iomem *r)
-{
-	__raw_writel(v, r + HW_STMP3XXX_CLR);
-}
-
-static inline void stmp3xxx_setl(u32 v, void __iomem *r)
-{
-	__raw_writel(v, r + HW_STMP3XXX_SET);
-}
-#endif
-
-#define BF(value, field) (((value) << BP_##field) & BM_##field)
-
-#endif /* __ASM_ARCH_PLATFORM_H */
diff -druN linux-2.6.39-libre/arch/arm/plat-stmp3xxx/include/mach/stmp3xxx.h linux-3.0-rc7-libre/arch/arm/plat-stmp3xxx/include/mach/stmp3xxx.h
--- linux-2.6.39-libre/arch/arm/plat-stmp3xxx/include/mach/stmp3xxx.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/plat-stmp3xxx/include/mach/stmp3xxx.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,54 +0,0 @@
-/*
- * Freescale STMP37XX/STMP378X core structure and function declarations
- *
- * Embedded Alley Solutions, Inc <source@embeddedalley.com>
- *
- * Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved.
- * Copyright 2008 Embedded Alley Solutions, 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 __ASM_PLAT_STMP3XXX_H
-#define __ASM_PLAT_STMP3XXX_H
-
-#include <linux/irq.h>
-
-extern struct sys_timer stmp3xxx_timer;
-
-void stmp3xxx_init_irq(struct irq_chip *chip);
-void stmp3xxx_init(void);
-int stmp3xxx_reset_block(void __iomem *hwreg, int just_enable);
-extern struct platform_device stmp3xxx_dbguart,
-			      stmp3xxx_appuart,
-			      stmp3xxx_watchdog,
-			      stmp3xxx_touchscreen,
-			      stmp3xxx_keyboard,
-			      stmp3xxx_gpmi,
-			      stmp3xxx_mmc,
-			      stmp3xxx_udc,
-			      stmp3xxx_ehci,
-			      stmp3xxx_rtc,
-			      stmp3xxx_spi1,
-			      stmp3xxx_spi2,
-			      stmp3xxx_backlight,
-			      stmp3xxx_rotdec,
-			      stmp3xxx_dcp,
-			      stmp3xxx_dcp_bootstream,
-			      stmp3xxx_persistent,
-			      stmp3xxx_framebuffer,
-			      stmp3xxx_battery;
-int stmp3xxx_ssp1_device_register(void);
-int stmp3xxx_ssp2_device_register(void);
-
-struct pin_group;
-void stmp3xxx_release_pin_group(struct pin_group *pin_group, const char *label);
-int stmp3xxx_request_pin_group(struct pin_group *pin_group, const char *label);
-
-#endif /* __ASM_PLAT_STMP3XXX_H */
diff -druN linux-2.6.39-libre/arch/arm/plat-stmp3xxx/include/mach/system.h linux-3.0-rc7-libre/arch/arm/plat-stmp3xxx/include/mach/system.h
--- linux-2.6.39-libre/arch/arm/plat-stmp3xxx/include/mach/system.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/plat-stmp3xxx/include/mach/system.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,49 +0,0 @@
-/*
- * Copyright (C) 2005 Sigmatel Inc
- *
- * Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved.
- * Copyright 2008 Embedded Alley Solutions, 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 __ASM_ARCH_SYSTEM_H
-#define __ASM_ARCH_SYSTEM_H
-
-#include <asm/proc-fns.h>
-#include <mach/platform.h>
-#include <mach/regs-clkctrl.h>
-#include <mach/regs-power.h>
-
-static inline void arch_idle(void)
-{
-	/*
-	 * This should do all the clock switching
-	 * and wait for interrupt tricks
-	 */
-
-	cpu_do_idle();
-}
-
-static inline void arch_reset(char mode, const char *cmd)
-{
-	/* Set BATTCHRG to default value */
-	__raw_writel(0x00010000, REGS_POWER_BASE + HW_POWER_CHARGE);
-
-	/* Set MINPWR to default value   */
-	__raw_writel(0, REGS_POWER_BASE + HW_POWER_MINPWR);
-
-	/* Reset digital side of chip (but not power or RTC) */
-	__raw_writel(BM_CLKCTRL_RESET_DIG,
-			REGS_CLKCTRL_BASE + HW_CLKCTRL_RESET);
-
-	/* Should not return */
-}
-
-#endif
diff -druN linux-2.6.39-libre/arch/arm/plat-stmp3xxx/include/mach/timex.h linux-3.0-rc7-libre/arch/arm/plat-stmp3xxx/include/mach/timex.h
--- linux-2.6.39-libre/arch/arm/plat-stmp3xxx/include/mach/timex.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/plat-stmp3xxx/include/mach/timex.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,20 +0,0 @@
-/*
- * Copyright (C) 1999 ARM Limited
- *
- * Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved.
- * Copyright 2008 Embedded Alley Solutions, 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
- */
-
-/*
- * System time clock is sourced from the 32k clock
- */
-#define CLOCK_TICK_RATE		(32768)
diff -druN linux-2.6.39-libre/arch/arm/plat-stmp3xxx/include/mach/uncompress.h linux-3.0-rc7-libre/arch/arm/plat-stmp3xxx/include/mach/uncompress.h
--- linux-2.6.39-libre/arch/arm/plat-stmp3xxx/include/mach/uncompress.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/plat-stmp3xxx/include/mach/uncompress.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,53 +0,0 @@
-/*
- *
- * Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved.
- * Copyright 2008 Embedded Alley Solutions, 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 __ASM_PLAT_UNCOMPRESS_H
-#define __ASM_PLAT_UNCOMPRESS_H
-
-/*
- * Register includes are for when the MMU enabled; we need to define our
- * own stuff here for pre-MMU use
- */
-#define UARTDBG_BASE		0x80070000
-#define UART(c)			(((volatile unsigned *)UARTDBG_BASE)[c])
-
-/*
- * This does not append a newline
- */
-static void putc(char c)
-{
-	/* Wait for TX fifo empty */
-	while ((UART(6) & (1<<7)) == 0)
-		continue;
-
-	/* Write byte */
-	UART(0) = c;
-
-	/* Wait for last bit to exit the UART */
-	while (UART(6) & (1<<3))
-		continue;
-}
-
-static void flush(void)
-{
-}
-
-/*
- * nothing to do
- */
-#define arch_decomp_setup()
-
-#define arch_decomp_wdog()
-
-#endif /* __ASM_PLAT_UNCOMPRESS_H */
diff -druN linux-2.6.39-libre/arch/arm/plat-stmp3xxx/include/mach/vmalloc.h linux-3.0-rc7-libre/arch/arm/plat-stmp3xxx/include/mach/vmalloc.h
--- linux-2.6.39-libre/arch/arm/plat-stmp3xxx/include/mach/vmalloc.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/plat-stmp3xxx/include/mach/vmalloc.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,12 +0,0 @@
-/*
- * Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved.
- * Copyright 2008 Embedded Alley Solutions, 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
- */
-#define VMALLOC_END       0xf0000000UL
diff -druN linux-2.6.39-libre/arch/arm/plat-stmp3xxx/irq.c linux-3.0-rc7-libre/arch/arm/plat-stmp3xxx/irq.c
--- linux-2.6.39-libre/arch/arm/plat-stmp3xxx/irq.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/plat-stmp3xxx/irq.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,50 +0,0 @@
-/*
- * Freescale STMP37XX/STMP378X common interrupt handling code
- *
- * Author: Vladislav Buzov <vbuzov@embeddedalley.com>
- *
- * Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved.
- * Copyright 2008 Embedded Alley Solutions, 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/init.h>
-#include <linux/interrupt.h>
-#include <linux/delay.h>
-#include <linux/irq.h>
-#include <linux/sysdev.h>
-
-#include <mach/stmp3xxx.h>
-#include <mach/platform.h>
-#include <mach/regs-icoll.h>
-
-void __init stmp3xxx_init_irq(struct irq_chip *chip)
-{
-	unsigned int i, lv;
-
-	/* Reset the interrupt controller */
-	stmp3xxx_reset_block(REGS_ICOLL_BASE + HW_ICOLL_CTRL, true);
-
-	/* Disable all interrupts initially */
-	for (i = 0; i < NR_REAL_IRQS; i++) {
-		chip->irq_mask(irq_get_irq_data(i));
-		irq_set_chip_and_handler(i, chip, handle_level_irq);
-		set_irq_flags(i, IRQF_VALID | IRQF_PROBE);
-	}
-
-	/* Ensure vector is cleared */
-	for (lv = 0; lv < 4; lv++)
-		__raw_writel(1 << lv, REGS_ICOLL_BASE + HW_ICOLL_LEVELACK);
-	__raw_writel(0, REGS_ICOLL_BASE + HW_ICOLL_VECTOR);
-
-	/* Barrier */
-	(void)__raw_readl(REGS_ICOLL_BASE + HW_ICOLL_STAT);
-}
-
diff -druN linux-2.6.39-libre/arch/arm/plat-stmp3xxx/Kconfig linux-3.0-rc7-libre/arch/arm/plat-stmp3xxx/Kconfig
--- linux-2.6.39-libre/arch/arm/plat-stmp3xxx/Kconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/plat-stmp3xxx/Kconfig	1969-12-31 19:00:00.000000000 -0500
@@ -1,37 +0,0 @@
-if ARCH_STMP3XXX
-
-menu "Freescale STMP3xxx implementations"
-
-choice
-	prompt "Select STMP3xxx chip family"
-
-config ARCH_STMP37XX
-	bool "Freescale SMTP37xx"
-	select CPU_ARM926T
-	---help---
-	 STMP37xx refers to 3700 through 3769 chips
-
-config ARCH_STMP378X
-	bool "Freescale STMP378x"
-	select CPU_ARM926T
-	---help---
-	 STMP378x refers to 3780 through 3789 chips
-
-endchoice
-
-choice
-	prompt "Select STMP3xxx board type"
-
-config MACH_STMP37XX
-	depends on ARCH_STMP37XX
-	bool "Freescale STMP37xx development board"
-
-config MACH_STMP378X
-	depends on ARCH_STMP378X
-	bool "Freescale STMP378x development board"
-
-endchoice
-
-endmenu
-
-endif
diff -druN linux-2.6.39-libre/arch/arm/plat-stmp3xxx/Makefile linux-3.0-rc7-libre/arch/arm/plat-stmp3xxx/Makefile
--- linux-2.6.39-libre/arch/arm/plat-stmp3xxx/Makefile	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/plat-stmp3xxx/Makefile	1969-12-31 19:00:00.000000000 -0500
@@ -1,5 +0,0 @@
-#
-# Makefile for the linux kernel.
-#
-# Object file lists.
-obj-y += core.o timer.o irq.o dma.o clock.o pinmux.o devices.o
diff -druN linux-2.6.39-libre/arch/arm/plat-stmp3xxx/pinmux.c linux-3.0-rc7-libre/arch/arm/plat-stmp3xxx/pinmux.c
--- linux-2.6.39-libre/arch/arm/plat-stmp3xxx/pinmux.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/plat-stmp3xxx/pinmux.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,550 +0,0 @@
-/*
- * Freescale STMP378X/STMP378X Pin Multiplexing
- *
- * Author: Vladislav Buzov <vbuzov@embeddedalley.com>
- *
- * Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved.
- * Copyright 2008 Embedded Alley Solutions, 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
- */
-#define DEBUG
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/sysdev.h>
-#include <linux/string.h>
-#include <linux/bitops.h>
-#include <linux/irq.h>
-
-#include <mach/hardware.h>
-#include <mach/platform.h>
-#include <mach/regs-pinctrl.h>
-#include <mach/pins.h>
-#include <mach/pinmux.h>
-
-#define NR_BANKS ARRAY_SIZE(pinmux_banks)
-static struct stmp3xxx_pinmux_bank pinmux_banks[] = {
-	[0] = {
-		.hw_muxsel = {
-			REGS_PINCTRL_BASE + HW_PINCTRL_MUXSEL0,
-			REGS_PINCTRL_BASE + HW_PINCTRL_MUXSEL1,
-		},
-		.hw_drive = {
-			REGS_PINCTRL_BASE + HW_PINCTRL_DRIVE0,
-			REGS_PINCTRL_BASE + HW_PINCTRL_DRIVE1,
-			REGS_PINCTRL_BASE + HW_PINCTRL_DRIVE2,
-			REGS_PINCTRL_BASE + HW_PINCTRL_DRIVE3,
-		},
-		.hw_pull = REGS_PINCTRL_BASE + HW_PINCTRL_PULL0,
-		.functions = { 0x0, 0x1, 0x2, 0x3 },
-		.strengths = { 0x0, 0x1, 0x2, 0x3, 0xff },
-
-		.hw_gpio_in = REGS_PINCTRL_BASE + HW_PINCTRL_DIN0,
-		.hw_gpio_out = REGS_PINCTRL_BASE + HW_PINCTRL_DOUT0,
-		.hw_gpio_doe = REGS_PINCTRL_BASE + HW_PINCTRL_DOE0,
-		.irq = IRQ_GPIO0,
-
-		.pin2irq = REGS_PINCTRL_BASE + HW_PINCTRL_PIN2IRQ0,
-		.irqstat = REGS_PINCTRL_BASE + HW_PINCTRL_IRQSTAT0,
-		.irqlevel = REGS_PINCTRL_BASE + HW_PINCTRL_IRQLEVEL0,
-		.irqpolarity = REGS_PINCTRL_BASE + HW_PINCTRL_IRQPOL0,
-		.irqen = REGS_PINCTRL_BASE + HW_PINCTRL_IRQEN0,
-	},
-	[1] = {
-		.hw_muxsel = {
-			REGS_PINCTRL_BASE + HW_PINCTRL_MUXSEL2,
-			REGS_PINCTRL_BASE + HW_PINCTRL_MUXSEL3,
-		},
-		.hw_drive = {
-			REGS_PINCTRL_BASE + HW_PINCTRL_DRIVE4,
-			REGS_PINCTRL_BASE + HW_PINCTRL_DRIVE5,
-			REGS_PINCTRL_BASE + HW_PINCTRL_DRIVE6,
-			REGS_PINCTRL_BASE + HW_PINCTRL_DRIVE7,
-		},
-		.hw_pull = REGS_PINCTRL_BASE + HW_PINCTRL_PULL1,
-		.functions = { 0x0, 0x1, 0x2, 0x3 },
-		.strengths = { 0x0, 0x1, 0x2, 0x3, 0xff },
-
-		.hw_gpio_in = REGS_PINCTRL_BASE + HW_PINCTRL_DIN1,
-		.hw_gpio_out = REGS_PINCTRL_BASE + HW_PINCTRL_DOUT1,
-		.hw_gpio_doe = REGS_PINCTRL_BASE + HW_PINCTRL_DOE1,
-		.irq = IRQ_GPIO1,
-
-		.pin2irq = REGS_PINCTRL_BASE + HW_PINCTRL_PIN2IRQ1,
-		.irqstat = REGS_PINCTRL_BASE + HW_PINCTRL_IRQSTAT1,
-		.irqlevel = REGS_PINCTRL_BASE + HW_PINCTRL_IRQLEVEL1,
-		.irqpolarity = REGS_PINCTRL_BASE + HW_PINCTRL_IRQPOL1,
-		.irqen = REGS_PINCTRL_BASE + HW_PINCTRL_IRQEN1,
-	},
-	[2] = {
-	       .hw_muxsel = {
-			REGS_PINCTRL_BASE + HW_PINCTRL_MUXSEL4,
-			REGS_PINCTRL_BASE + HW_PINCTRL_MUXSEL5,
-		},
-		.hw_drive = {
-			REGS_PINCTRL_BASE + HW_PINCTRL_DRIVE8,
-			REGS_PINCTRL_BASE + HW_PINCTRL_DRIVE9,
-			REGS_PINCTRL_BASE + HW_PINCTRL_DRIVE10,
-			REGS_PINCTRL_BASE + HW_PINCTRL_DRIVE11,
-		},
-		.hw_pull = REGS_PINCTRL_BASE + HW_PINCTRL_PULL2,
-		.functions = { 0x0, 0x1, 0x2, 0x3 },
-		.strengths = { 0x0, 0x1, 0x2, 0x1, 0x2 },
-
-		.hw_gpio_in = REGS_PINCTRL_BASE + HW_PINCTRL_DIN2,
-		.hw_gpio_out = REGS_PINCTRL_BASE + HW_PINCTRL_DOUT2,
-		.hw_gpio_doe = REGS_PINCTRL_BASE + HW_PINCTRL_DOE2,
-		.irq = IRQ_GPIO2,
-
-		.pin2irq = REGS_PINCTRL_BASE + HW_PINCTRL_PIN2IRQ2,
-		.irqstat = REGS_PINCTRL_BASE + HW_PINCTRL_IRQSTAT2,
-		.irqlevel = REGS_PINCTRL_BASE + HW_PINCTRL_IRQLEVEL2,
-		.irqpolarity = REGS_PINCTRL_BASE + HW_PINCTRL_IRQPOL2,
-		.irqen = REGS_PINCTRL_BASE + HW_PINCTRL_IRQEN2,
-	},
-	[3] = {
-	       .hw_muxsel = {
-		       REGS_PINCTRL_BASE + HW_PINCTRL_MUXSEL6,
-		       REGS_PINCTRL_BASE + HW_PINCTRL_MUXSEL7,
-	       },
-	       .hw_drive = {
-			REGS_PINCTRL_BASE + HW_PINCTRL_DRIVE12,
-			REGS_PINCTRL_BASE + HW_PINCTRL_DRIVE13,
-			REGS_PINCTRL_BASE + HW_PINCTRL_DRIVE14,
-			NULL,
-	       },
-	       .hw_pull = REGS_PINCTRL_BASE + HW_PINCTRL_PULL3,
-	       .functions = {0x0, 0x1, 0x2, 0x3},
-	       .strengths = {0x0, 0x1, 0x2, 0x3, 0xff},
-	},
-};
-
-static inline struct stmp3xxx_pinmux_bank *
-stmp3xxx_pinmux_bank(unsigned id, unsigned *bank, unsigned *pin)
-{
-	unsigned b, p;
-
-	b = STMP3XXX_PINID_TO_BANK(id);
-	p = STMP3XXX_PINID_TO_PINNUM(id);
-	BUG_ON(b >= NR_BANKS);
-	if (bank)
-		*bank = b;
-	if (pin)
-		*pin = p;
-	return &pinmux_banks[b];
-}
-
-/* Check if requested pin is owned by caller */
-static int stmp3xxx_check_pin(unsigned id, const char *label)
-{
-	unsigned pin;
-	struct stmp3xxx_pinmux_bank *pm = stmp3xxx_pinmux_bank(id, NULL, &pin);
-
-	if (!test_bit(pin, &pm->pin_map)) {
-		printk(KERN_WARNING
-		       "%s: Accessing free pin %x, caller %s\n",
-		       __func__, id, label);
-
-		return -EINVAL;
-	}
-
-	if (label && pm->pin_labels[pin] &&
-	    strcmp(label, pm->pin_labels[pin])) {
-		printk(KERN_WARNING
-		       "%s: Wrong pin owner %x, caller %s owner %s\n",
-		       __func__, id, label, pm->pin_labels[pin]);
-
-		return -EINVAL;
-	}
-	return 0;
-}
-
-void stmp3xxx_pin_strength(unsigned id, enum pin_strength strength,
-		const char *label)
-{
-	struct stmp3xxx_pinmux_bank *pbank;
-	void __iomem *hwdrive;
-	u32 shift, val;
-	u32 bank, pin;
-
-	pbank = stmp3xxx_pinmux_bank(id, &bank, &pin);
-	pr_debug("%s: label %s bank %d pin %d strength %d\n", __func__, label,
-		 bank, pin, strength);
-
-	hwdrive = pbank->hw_drive[pin / HW_DRIVE_PIN_NUM];
-	shift = (pin % HW_DRIVE_PIN_NUM) * HW_DRIVE_PIN_LEN;
-	val = pbank->strengths[strength];
-	if (val == 0xff) {
-		printk(KERN_WARNING
-		       "%s: strength is not supported for bank %d, caller %s",
-		       __func__, bank, label);
-		return;
-	}
-
-	if (stmp3xxx_check_pin(id, label))
-		return;
-
-	pr_debug("%s: writing 0x%x to 0x%p register\n", __func__,
-			val << shift, hwdrive);
-	stmp3xxx_clearl(HW_DRIVE_PINDRV_MASK << shift, hwdrive);
-	stmp3xxx_setl(val << shift, hwdrive);
-}
-
-void stmp3xxx_pin_voltage(unsigned id, enum pin_voltage voltage,
-			  const char *label)
-{
-	struct stmp3xxx_pinmux_bank *pbank;
-	void __iomem *hwdrive;
-	u32 shift;
-	u32 bank, pin;
-
-	pbank = stmp3xxx_pinmux_bank(id, &bank, &pin);
-	pr_debug("%s: label %s bank %d pin %d voltage %d\n", __func__, label,
-		 bank, pin, voltage);
-
-	hwdrive = pbank->hw_drive[pin / HW_DRIVE_PIN_NUM];
-	shift = (pin % HW_DRIVE_PIN_NUM) * HW_DRIVE_PIN_LEN;
-
-	if (stmp3xxx_check_pin(id, label))
-		return;
-
-	pr_debug("%s: changing 0x%x bit in 0x%p register\n",
-			__func__, HW_DRIVE_PINV_MASK << shift, hwdrive);
-	if (voltage == PIN_1_8V)
-		stmp3xxx_clearl(HW_DRIVE_PINV_MASK << shift, hwdrive);
-	else
-		stmp3xxx_setl(HW_DRIVE_PINV_MASK << shift, hwdrive);
-}
-
-void stmp3xxx_pin_pullup(unsigned id, int enable, const char *label)
-{
-	struct stmp3xxx_pinmux_bank *pbank;
-	void __iomem *hwpull;
-	u32 bank, pin;
-
-	pbank = stmp3xxx_pinmux_bank(id, &bank, &pin);
-	pr_debug("%s: label %s bank %d pin %d enable %d\n", __func__, label,
-		 bank, pin, enable);
-
-	hwpull = pbank->hw_pull;
-
-	if (stmp3xxx_check_pin(id, label))
-		return;
-
-	pr_debug("%s: changing 0x%x bit in 0x%p register\n",
-			__func__, 1 << pin, hwpull);
-	if (enable)
-		stmp3xxx_setl(1 << pin, hwpull);
-	else
-		stmp3xxx_clearl(1 << pin, hwpull);
-}
-
-int stmp3xxx_request_pin(unsigned id, enum pin_fun fun, const char *label)
-{
-	struct stmp3xxx_pinmux_bank *pbank;
-	u32 bank, pin;
-	int ret = 0;
-
-	pbank = stmp3xxx_pinmux_bank(id, &bank, &pin);
-	pr_debug("%s: label %s bank %d pin %d fun %d\n", __func__, label,
-		 bank, pin, fun);
-
-	if (test_bit(pin, &pbank->pin_map)) {
-		printk(KERN_WARNING
-		       "%s: CONFLICT DETECTED pin %d:%d caller %s owner %s\n",
-		       __func__, bank, pin, label, pbank->pin_labels[pin]);
-		return -EBUSY;
-	}
-
-	set_bit(pin, &pbank->pin_map);
-	pbank->pin_labels[pin] = label;
-
-	stmp3xxx_set_pin_type(id, fun);
-
-	return ret;
-}
-
-void stmp3xxx_set_pin_type(unsigned id, enum pin_fun fun)
-{
-	struct stmp3xxx_pinmux_bank *pbank;
-	void __iomem *hwmux;
-	u32 shift, val;
-	u32 bank, pin;
-
-	pbank = stmp3xxx_pinmux_bank(id, &bank, &pin);
-
-	hwmux = pbank->hw_muxsel[pin / HW_MUXSEL_PIN_NUM];
-	shift = (pin % HW_MUXSEL_PIN_NUM) * HW_MUXSEL_PIN_LEN;
-
-	val = pbank->functions[fun];
-	shift = (pin % HW_MUXSEL_PIN_NUM) * HW_MUXSEL_PIN_LEN;
-	pr_debug("%s: writing 0x%x to 0x%p register\n",
-			__func__, val << shift, hwmux);
-	stmp3xxx_clearl(HW_MUXSEL_PINFUN_MASK << shift, hwmux);
-	stmp3xxx_setl(val << shift, hwmux);
-}
-
-void stmp3xxx_release_pin(unsigned id, const char *label)
-{
-	struct stmp3xxx_pinmux_bank *pbank;
-	u32 bank, pin;
-
-	pbank = stmp3xxx_pinmux_bank(id, &bank, &pin);
-	pr_debug("%s: label %s bank %d pin %d\n", __func__, label, bank, pin);
-
-	if (stmp3xxx_check_pin(id, label))
-		return;
-
-	clear_bit(pin, &pbank->pin_map);
-	pbank->pin_labels[pin] = NULL;
-}
-
-int stmp3xxx_request_pin_group(struct pin_group *pin_group, const char *label)
-{
-	struct pin_desc *pin;
-	int p;
-	int err = 0;
-
-	/* Allocate and configure pins */
-	for (p = 0; p < pin_group->nr_pins; p++) {
-		pr_debug("%s: #%d\n", __func__, p);
-		pin = &pin_group->pins[p];
-
-		err = stmp3xxx_request_pin(pin->id, pin->fun, label);
-		if (err)
-			goto out_err;
-
-		stmp3xxx_pin_strength(pin->id, pin->strength, label);
-		stmp3xxx_pin_voltage(pin->id, pin->voltage, label);
-		stmp3xxx_pin_pullup(pin->id, pin->pullup, label);
-	}
-
-	return 0;
-
-out_err:
-	/* Release allocated pins in case of error */
-	while (--p >= 0) {
-		pr_debug("%s: releasing #%d\n", __func__, p);
-		stmp3xxx_release_pin(pin_group->pins[p].id, label);
-	}
-	return err;
-}
-EXPORT_SYMBOL(stmp3xxx_request_pin_group);
-
-void stmp3xxx_release_pin_group(struct pin_group *pin_group, const char *label)
-{
-	struct pin_desc *pin;
-	int p;
-
-	for (p = 0; p < pin_group->nr_pins; p++) {
-		pin = &pin_group->pins[p];
-		stmp3xxx_release_pin(pin->id, label);
-	}
-}
-EXPORT_SYMBOL(stmp3xxx_release_pin_group);
-
-static int stmp3xxx_irq_data_to_gpio(struct irq_data *d,
-	struct stmp3xxx_pinmux_bank **bank, unsigned *gpio)
-{
-	struct stmp3xxx_pinmux_bank *pm;
-
-	for (pm = pinmux_banks; pm < pinmux_banks + NR_BANKS; pm++)
-		if (pm->virq <= d->irq && d->irq < pm->virq + 32) {
-			*bank = pm;
-			*gpio = d->irq - pm->virq;
-			return 0;
-		}
-	return -ENOENT;
-}
-
-static int stmp3xxx_set_irqtype(struct irq_data *d, unsigned type)
-{
-	struct stmp3xxx_pinmux_bank *pm;
-	unsigned gpio;
-	int l, p;
-
-	stmp3xxx_irq_data_to_gpio(d, &pm, &gpio);
-	switch (type) {
-	case IRQ_TYPE_EDGE_RISING:
-		l = 0; p = 1; break;
-	case IRQ_TYPE_EDGE_FALLING:
-		l = 0; p = 0; break;
-	case IRQ_TYPE_LEVEL_HIGH:
-		l = 1; p = 1; break;
-	case IRQ_TYPE_LEVEL_LOW:
-		l = 1; p = 0; break;
-	default:
-		pr_debug("%s: Incorrect GPIO interrupt type 0x%x\n",
-				__func__, type);
-		return -ENXIO;
-	}
-
-	if (l)
-		stmp3xxx_setl(1 << gpio, pm->irqlevel);
-	else
-		stmp3xxx_clearl(1 << gpio, pm->irqlevel);
-	if (p)
-		stmp3xxx_setl(1 << gpio, pm->irqpolarity);
-	else
-		stmp3xxx_clearl(1 << gpio, pm->irqpolarity);
-	return 0;
-}
-
-static void stmp3xxx_pin_ack_irq(struct irq_data *d)
-{
-	u32 stat;
-	struct stmp3xxx_pinmux_bank *pm;
-	unsigned gpio;
-
-	stmp3xxx_irq_data_to_gpio(d, &pm, &gpio);
-	stat = __raw_readl(pm->irqstat) & (1 << gpio);
-	stmp3xxx_clearl(stat, pm->irqstat);
-}
-
-static void stmp3xxx_pin_mask_irq(struct irq_data *d)
-{
-	struct stmp3xxx_pinmux_bank *pm;
-	unsigned gpio;
-
-	stmp3xxx_irq_data_to_gpio(d, &pm, &gpio);
-	stmp3xxx_clearl(1 << gpio, pm->irqen);
-	stmp3xxx_clearl(1 << gpio, pm->pin2irq);
-}
-
-static void stmp3xxx_pin_unmask_irq(struct irq_data *d)
-{
-	struct stmp3xxx_pinmux_bank *pm;
-	unsigned gpio;
-
-	stmp3xxx_irq_data_to_gpio(d, &pm, &gpio);
-	stmp3xxx_setl(1 << gpio, pm->irqen);
-	stmp3xxx_setl(1 << gpio, pm->pin2irq);
-}
-
-static inline
-struct stmp3xxx_pinmux_bank *to_pinmux_bank(struct gpio_chip *chip)
-{
-	return container_of(chip, struct stmp3xxx_pinmux_bank, chip);
-}
-
-static int stmp3xxx_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
-{
-	struct stmp3xxx_pinmux_bank *pm = to_pinmux_bank(chip);
-	return pm->virq + offset;
-}
-
-static int stmp3xxx_gpio_get(struct gpio_chip *chip, unsigned offset)
-{
-	struct stmp3xxx_pinmux_bank *pm = to_pinmux_bank(chip);
-	unsigned v;
-
-	v = __raw_readl(pm->hw_gpio_in) & (1 << offset);
-	return v ? 1 : 0;
-}
-
-static void stmp3xxx_gpio_set(struct gpio_chip *chip, unsigned offset, int v)
-{
-	struct stmp3xxx_pinmux_bank *pm = to_pinmux_bank(chip);
-
-	if (v)
-		stmp3xxx_setl(1 << offset, pm->hw_gpio_out);
-	else
-		stmp3xxx_clearl(1 << offset, pm->hw_gpio_out);
-}
-
-static int stmp3xxx_gpio_output(struct gpio_chip *chip, unsigned offset, int v)
-{
-	struct stmp3xxx_pinmux_bank *pm = to_pinmux_bank(chip);
-
-	stmp3xxx_setl(1 << offset, pm->hw_gpio_doe);
-	stmp3xxx_gpio_set(chip, offset, v);
-	return 0;
-}
-
-static int stmp3xxx_gpio_input(struct gpio_chip *chip, unsigned offset)
-{
-	struct stmp3xxx_pinmux_bank *pm = to_pinmux_bank(chip);
-
-	stmp3xxx_clearl(1 << offset, pm->hw_gpio_doe);
-	return 0;
-}
-
-static int stmp3xxx_gpio_request(struct gpio_chip *chip, unsigned offset)
-{
-	return stmp3xxx_request_pin(chip->base + offset, PIN_GPIO, "gpio");
-}
-
-static void stmp3xxx_gpio_free(struct gpio_chip *chip, unsigned offset)
-{
-	stmp3xxx_release_pin(chip->base + offset, "gpio");
-}
-
-static void stmp3xxx_gpio_irq(u32 irq, struct irq_desc *desc)
-{
-	struct stmp3xxx_pinmux_bank *pm = irq_get_handler_data(irq);
-	int gpio_irq = pm->virq;
-	u32 stat = __raw_readl(pm->irqstat);
-
-	while (stat) {
-		if (stat & 1)
-			generic_handle_irq(gpio_irq);
-		gpio_irq++;
-		stat >>= 1;
-	}
-}
-
-static struct irq_chip gpio_irq_chip = {
-	.irq_ack	= stmp3xxx_pin_ack_irq,
-	.irq_mask	= stmp3xxx_pin_mask_irq,
-	.irq_unmask	= stmp3xxx_pin_unmask_irq,
-	.irq_set_type	= stmp3xxx_set_irqtype,
-};
-
-int __init stmp3xxx_pinmux_init(int virtual_irq_start)
-{
-	int b, r = 0;
-	struct stmp3xxx_pinmux_bank *pm;
-	int virq;
-
-	for (b = 0; b < 3; b++) {
-		/* only banks 0,1,2 are allowed to GPIO */
-		pm = pinmux_banks + b;
-		pm->chip.base = 32 * b;
-		pm->chip.ngpio = 32;
-		pm->chip.owner = THIS_MODULE;
-		pm->chip.can_sleep = 1;
-		pm->chip.exported = 1;
-		pm->chip.to_irq = stmp3xxx_gpio_to_irq;
-		pm->chip.direction_input = stmp3xxx_gpio_input;
-		pm->chip.direction_output = stmp3xxx_gpio_output;
-		pm->chip.get = stmp3xxx_gpio_get;
-		pm->chip.set = stmp3xxx_gpio_set;
-		pm->chip.request = stmp3xxx_gpio_request;
-		pm->chip.free = stmp3xxx_gpio_free;
-		pm->virq = virtual_irq_start + b * 32;
-
-		for (virq = pm->virq; virq < pm->virq; virq++) {
-			gpio_irq_chip.irq_mask(irq_get_irq_data(virq));
-			irq_set_chip_and_handler(virq, &gpio_irq_chip,
-						 handle_level_irq);
-			set_irq_flags(virq, IRQF_VALID);
-		}
-		r = gpiochip_add(&pm->chip);
-		if (r < 0)
-			break;
-		irq_set_chained_handler(pm->irq, stmp3xxx_gpio_irq);
-		irq_set_handler_data(pm->irq, pm);
-	}
-	return r;
-}
-
-MODULE_AUTHOR("Vladislav Buzov");
-MODULE_LICENSE("GPL");
diff -druN linux-2.6.39-libre/arch/arm/plat-stmp3xxx/timer.c linux-3.0-rc7-libre/arch/arm/plat-stmp3xxx/timer.c
--- linux-2.6.39-libre/arch/arm/plat-stmp3xxx/timer.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/plat-stmp3xxx/timer.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,186 +0,0 @@
-/*
- * System timer for Freescale STMP37XX/STMP378X
- *
- * Embedded Alley Solutions, Inc <source@embeddedalley.com>
- *
- * Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved.
- * Copyright 2008 Embedded Alley Solutions, 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/kernel.h>
-#include <linux/init.h>
-#include <linux/spinlock.h>
-#include <linux/clocksource.h>
-#include <linux/clockchips.h>
-#include <linux/io.h>
-#include <linux/irq.h>
-#include <linux/interrupt.h>
-
-#include <asm/mach/time.h>
-#include <mach/stmp3xxx.h>
-#include <mach/platform.h>
-#include <mach/regs-timrot.h>
-
-static irqreturn_t
-stmp3xxx_timer_interrupt(int irq, void *dev_id)
-{
-	struct clock_event_device *c = dev_id;
-
-	/* timer 0 */
-	if (__raw_readl(REGS_TIMROT_BASE + HW_TIMROT_TIMCTRL0) &
-			BM_TIMROT_TIMCTRLn_IRQ) {
-		stmp3xxx_clearl(BM_TIMROT_TIMCTRLn_IRQ,
-				REGS_TIMROT_BASE + HW_TIMROT_TIMCTRL0);
-		c->event_handler(c);
-	}
-
-	/* timer 1 */
-	else if (__raw_readl(REGS_TIMROT_BASE + HW_TIMROT_TIMCTRL1)
-			& BM_TIMROT_TIMCTRLn_IRQ) {
-		stmp3xxx_clearl(BM_TIMROT_TIMCTRLn_IRQ,
-				REGS_TIMROT_BASE + HW_TIMROT_TIMCTRL1);
-		stmp3xxx_clearl(BM_TIMROT_TIMCTRLn_IRQ_EN,
-				REGS_TIMROT_BASE + HW_TIMROT_TIMCTRL1);
-		__raw_writel(0xFFFF, REGS_TIMROT_BASE + HW_TIMROT_TIMCOUNT1);
-	}
-
-	return IRQ_HANDLED;
-}
-
-static cycle_t stmp3xxx_clock_read(struct clocksource *cs)
-{
-	return ~((__raw_readl(REGS_TIMROT_BASE + HW_TIMROT_TIMCOUNT1)
-				& 0xFFFF0000) >> 16);
-}
-
-static int
-stmp3xxx_timrot_set_next_event(unsigned long delta,
-		struct clock_event_device *dev)
-{
-	/* reload the timer */
-	__raw_writel(delta, REGS_TIMROT_BASE + HW_TIMROT_TIMCOUNT0);
-	return 0;
-}
-
-static void
-stmp3xxx_timrot_set_mode(enum clock_event_mode mode,
-		struct clock_event_device *dev)
-{
-}
-
-static struct clock_event_device ckevt_timrot = {
-	.name		= "timrot",
-	.features	= CLOCK_EVT_FEAT_ONESHOT,
-	.shift		= 32,
-	.set_next_event	= stmp3xxx_timrot_set_next_event,
-	.set_mode	= stmp3xxx_timrot_set_mode,
-};
-
-static struct clocksource cksrc_stmp3xxx = {
-	.name           = "cksrc_stmp3xxx",
-	.rating         = 250,
-	.read           = stmp3xxx_clock_read,
-	.mask           = CLOCKSOURCE_MASK(16),
-	.flags		= CLOCK_SOURCE_IS_CONTINUOUS,
-};
-
-static struct irqaction stmp3xxx_timer_irq = {
-	.name		= "stmp3xxx_timer",
-	.flags		= IRQF_DISABLED | IRQF_TIMER,
-	.handler	= stmp3xxx_timer_interrupt,
-	.dev_id		= &ckevt_timrot,
-};
-
-
-/*
- * Set up timer interrupt, and return the current time in seconds.
- */
-static void __init stmp3xxx_init_timer(void)
-{
-	ckevt_timrot.mult = div_sc(CLOCK_TICK_RATE, NSEC_PER_SEC,
-				ckevt_timrot.shift);
-	ckevt_timrot.min_delta_ns = clockevent_delta2ns(2, &ckevt_timrot);
-	ckevt_timrot.max_delta_ns = clockevent_delta2ns(0xFFF, &ckevt_timrot);
-	ckevt_timrot.cpumask = cpumask_of(0);
-
-	stmp3xxx_reset_block(REGS_TIMROT_BASE, false);
-
-	/* clear two timers */
-	__raw_writel(0, REGS_TIMROT_BASE + HW_TIMROT_TIMCOUNT0);
-	__raw_writel(0, REGS_TIMROT_BASE + HW_TIMROT_TIMCOUNT1);
-
-	/* configure them */
-	__raw_writel(
-		(8 << BP_TIMROT_TIMCTRLn_SELECT) |  /* 32 kHz */
-		BM_TIMROT_TIMCTRLn_RELOAD |
-		BM_TIMROT_TIMCTRLn_UPDATE |
-		BM_TIMROT_TIMCTRLn_IRQ_EN,
-			REGS_TIMROT_BASE + HW_TIMROT_TIMCTRL0);
-	__raw_writel(
-		(8 << BP_TIMROT_TIMCTRLn_SELECT) |  /* 32 kHz */
-		BM_TIMROT_TIMCTRLn_RELOAD |
-		BM_TIMROT_TIMCTRLn_UPDATE |
-		BM_TIMROT_TIMCTRLn_IRQ_EN,
-			REGS_TIMROT_BASE + HW_TIMROT_TIMCTRL1);
-
-	__raw_writel(CLOCK_TICK_RATE / HZ - 1,
-			REGS_TIMROT_BASE + HW_TIMROT_TIMCOUNT0);
-	__raw_writel(0xFFFF, REGS_TIMROT_BASE + HW_TIMROT_TIMCOUNT1);
-
-	setup_irq(IRQ_TIMER0, &stmp3xxx_timer_irq);
-
-	clocksource_register_hz(&cksrc_stmp3xxx, CLOCK_TICK_RATE);
-	clockevents_register_device(&ckevt_timrot);
-}
-
-#ifdef CONFIG_PM
-
-void stmp3xxx_suspend_timer(void)
-{
-	stmp3xxx_clearl(BM_TIMROT_TIMCTRLn_IRQ_EN | BM_TIMROT_TIMCTRLn_IRQ,
-			REGS_TIMROT_BASE + HW_TIMROT_TIMCTRL0);
-	stmp3xxx_setl(BM_TIMROT_ROTCTRL_CLKGATE,
-			REGS_TIMROT_BASE + HW_TIMROT_ROTCTRL);
-}
-
-void stmp3xxx_resume_timer(void)
-{
-	stmp3xxx_clearl(BM_TIMROT_ROTCTRL_SFTRST | BM_TIMROT_ROTCTRL_CLKGATE,
-			REGS_TIMROT_BASE + HW_TIMROT_ROTCTRL);
-	__raw_writel(
-		8 << BP_TIMROT_TIMCTRLn_SELECT |  /* 32 kHz */
-		BM_TIMROT_TIMCTRLn_RELOAD |
-		BM_TIMROT_TIMCTRLn_UPDATE |
-		BM_TIMROT_TIMCTRLn_IRQ_EN,
-			REGS_TIMROT_BASE + HW_TIMROT_TIMCTRL0);
-	__raw_writel(
-		8 << BP_TIMROT_TIMCTRLn_SELECT |  /* 32 kHz */
-		BM_TIMROT_TIMCTRLn_RELOAD |
-		BM_TIMROT_TIMCTRLn_UPDATE |
-		BM_TIMROT_TIMCTRLn_IRQ_EN,
-			REGS_TIMROT_BASE + HW_TIMROT_TIMCTRL1);
-	__raw_writel(CLOCK_TICK_RATE / HZ - 1,
-			REGS_TIMROT_BASE + HW_TIMROT_TIMCOUNT0);
-	__raw_writel(0xFFFF, REGS_TIMROT_BASE + HW_TIMROT_TIMCOUNT1);
-}
-
-#else
-
-#define stmp3xxx_suspend_timer	NULL
-#define	stmp3xxx_resume_timer	NULL
-
-#endif	/* CONFIG_PM */
-
-struct sys_timer stmp3xxx_timer = {
-	.init		= stmp3xxx_init_timer,
-	.suspend	= stmp3xxx_suspend_timer,
-	.resume		= stmp3xxx_resume_timer,
-};
diff -druN linux-2.6.39-libre/arch/arm/plat-versatile/platsmp.c linux-3.0-rc7-libre/arch/arm/plat-versatile/platsmp.c
--- linux-2.6.39-libre/arch/arm/plat-versatile/platsmp.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/plat-versatile/platsmp.c	2011-07-11 19:51:52.000000000 -0400
@@ -16,6 +16,7 @@
 #include <linux/smp.h>
 
 #include <asm/cacheflush.h>
+#include <asm/hardware/gic.h>
 
 /*
  * control for which core is the next to come out of the secondary
@@ -83,7 +84,7 @@
 	 * the boot monitor to read the system wide flags register,
 	 * and branch to the address found there.
 	 */
-	smp_cross_call(cpumask_of(cpu), 1);
+	gic_raise_softirq(cpumask_of(cpu), 1);
 
 	timeout = jiffies + (1 * HZ);
 	while (time_before(jiffies, timeout)) {
diff -druN linux-2.6.39-libre/arch/arm/tools/mach-types linux-3.0-rc7-libre/arch/arm/tools/mach-types
--- linux-2.6.39-libre/arch/arm/tools/mach-types	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/tools/mach-types	2011-07-11 19:51:52.000000000 -0400
@@ -17,7 +17,7 @@
 # XXX: the last 12 months.  If your entry is missing please email rmk at
 # XXX: <linux@arm.linux.org.uk>
 #
-# Last update: Sun Mar 20 18:06:11 2011
+# Last update: Sat May 7 08:48:24 2011
 #
 # machine_is_xxx	CONFIG_xxxx		MACH_TYPE_xxx		number
 #
@@ -377,6 +377,8 @@
 at91sam9g10ek		MACH_AT91SAM9G10EK	AT91SAM9G10EK		2159
 omap_4430sdp		MACH_OMAP_4430SDP	OMAP_4430SDP		2160
 magx_zn5		MACH_MAGX_ZN5		MAGX_ZN5		2162
+btmavb101		MACH_BTMAVB101		BTMAVB101		2172
+btmawb101		MACH_BTMAWB101		BTMAWB101		2173
 omap3_torpedo		MACH_OMAP3_TORPEDO	OMAP3_TORPEDO		2178
 anw6410			MACH_ANW6410		ANW6410			2183
 imx27_visstrim_m10	MACH_IMX27_VISSTRIM_M10	IMX27_VISSTRIM_M10	2187
@@ -400,6 +402,7 @@
 bigdisk			MACH_BIGDISK		BIGDISK			2283
 at91sam9g20ek_2mmc	MACH_AT91SAM9G20EK_2MMC	AT91SAM9G20EK_2MMC	2288
 bcmring			MACH_BCMRING		BCMRING			2289
+dp6xx			MACH_DP6XX		DP6XX			2302
 mahimahi		MACH_MAHIMAHI		MAHIMAHI		2304
 smdk6442		MACH_SMDK6442		SMDK6442		2324
 openrd_base		MACH_OPENRD_BASE	OPENRD_BASE		2325
@@ -424,6 +427,7 @@
 omap_zoom3		MACH_OMAP_ZOOM3		OMAP_ZOOM3		2464
 omap_3630sdp		MACH_OMAP_3630SDP	OMAP_3630SDP		2465
 smartq7			MACH_SMARTQ7		SMARTQ7			2479
+watson_efm_plugin	MACH_WATSON_EFM_PLUGIN	WATSON_EFM_PLUGIN	2491
 g4evm			MACH_G4EVM		G4EVM			2493
 omapl138_hawkboard	MACH_OMAPL138_HAWKBOARD	OMAPL138_HAWKBOARD	2495
 ts41x			MACH_TS41X		TS41X			2502
@@ -433,6 +437,8 @@
 smartq5			MACH_SMARTQ5		SMARTQ5			2534
 davinci_dm6467tevm	MACH_DAVINCI_DM6467TEVM	DAVINCI_DM6467TEVM	2548
 mxt_td60		MACH_MXT_TD60		MXT_TD60		2550
+riot_bei2		MACH_RIOT_BEI2		RIOT_BEI2		2576
+riot_x37		MACH_RIOT_X37		RIOT_X37		2578
 capc7117		MACH_CAPC7117		CAPC7117		2612
 icontrol		MACH_ICONTROL		ICONTROL		2624
 qsd8x50a_st1_5		MACH_QSD8X50A_ST1_5	QSD8X50A_ST1_5		2627
@@ -445,6 +451,7 @@
 aquila			MACH_AQUILA		AQUILA			2676
 sheeva_esata		MACH_ESATA_SHEEVAPLUG	ESATA_SHEEVAPLUG	2678
 msm7x30_surf		MACH_MSM7X30_SURF	MSM7X30_SURF		2679
+ea2478devkit		MACH_EA2478DEVKIT	EA2478DEVKIT		2683
 terastation_wxl		MACH_TERASTATION_WXL	TERASTATION_WXL		2697
 msm7x25_surf		MACH_MSM7X25_SURF	MSM7X25_SURF		2703
 msm7x25_ffa		MACH_MSM7X25_FFA	MSM7X25_FFA		2704
@@ -463,75 +470,16 @@
 msm8x60_surf		MACH_MSM8X60_SURF	MSM8X60_SURF		2755
 msm8x60_sim		MACH_MSM8X60_SIM	MSM8X60_SIM		2756
 tcc8000_sdk		MACH_TCC8000_SDK	TCC8000_SDK		2758
-ap420			MACH_AP420		AP420			2765
-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
+nanos			MACH_NANOS		NANOS			2759
+stamp9g45		MACH_STAMP9G45		STAMP9G45		2761
 cns3420vb		MACH_CNS3420VB		CNS3420VB		2776
-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
-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
 eukrea_cpuimx25sd	MACH_EUKREA_CPUIMX25	EUKREA_CPUIMX25		2820
 eukrea_cpuimx35sd	MACH_EUKREA_CPUIMX35	EUKREA_CPUIMX35		2821
 eukrea_cpuimx51sd	MACH_EUKREA_CPUIMX51SD	EUKREA_CPUIMX51SD	2822
 eukrea_cpuimx51		MACH_EUKREA_CPUIMX51	EUKREA_CPUIMX51		2823
-p565			MACH_P565		P565			2824
-acer_a4			MACH_ACER_A4		ACER_A4			2825
-davinci_dm368_bip	MACH_DAVINCI_DM368_BIP	DAVINCI_DM368_BIP	2826
-eshare			MACH_ESHARE		ESHARE			2827
-wlbargn			MACH_WLBARGN		WLBARGN			2829
-bm170			MACH_BM170		BM170			2830
-netspace_mini_v2	MACH_NETSPACE_MINI_V2	NETSPACE_MINI_V2	2831
-netspace_plug_v2	MACH_NETSPACE_PLUG_V2	NETSPACE_PLUG_V2	2832
-siemens_l1		MACH_SIEMENS_L1		SIEMENS_L1		2833
-elv_lcu1		MACH_ELV_LCU1		ELV_LCU1		2834
-mcu1			MACH_MCU1		MCU1			2835
-omap3_tao3530		MACH_OMAP3_TAO3530	OMAP3_TAO3530		2836
-omap3_pcutouch		MACH_OMAP3_PCUTOUCH	OMAP3_PCUTOUCH		2837
 smdkc210		MACH_SMDKC210		SMDKC210		2838
 omap3_braillo		MACH_OMAP3_BRAILLO	OMAP3_BRAILLO		2839
 spyplug			MACH_SPYPLUG		SPYPLUG			2840
@@ -973,9 +921,7 @@
 rascal			MACH_RASCAL		RASCAL			3292
 hrefv60			MACH_HREFV60		HREFV60			3293
 tpt_2_0			MACH_TPT_2_0		TPT_2_0			3294
-pyramid_td		MACH_PYRAMID_TD		PYRAMID_TD		3295
 splendor		MACH_SPLENDOR		SPLENDOR		3296
-guf_planet		MACH_GUF_PLANET		GUF_PLANET		3297
 msm8x60_qt		MACH_MSM8X60_QT		MSM8X60_QT		3298
 htc_hd_mini		MACH_HTC_HD_MINI	HTC_HD_MINI		3299
 athene			MACH_ATHENE		ATHENE			3300
@@ -1099,3 +1045,71 @@
 hsgx6d			MACH_HSGX6D		HSGX6D			3422
 dawad7			MACH_DAWAD7		DAWAD7			3423
 sam9repeater		MACH_SAM9REPEATER	SAM9REPEATER		3424
+gt_i5700		MACH_GT_I5700		GT_I5700		3425
+ctera_plug_c2		MACH_CTERA_PLUG_C2	CTERA_PLUG_C2		3426
+marvelct		MACH_MARVELCT		MARVELCT		3427
+ag11005			MACH_AG11005		AG11005			3428
+vangogh			MACH_VANGOGH		VANGOGH			3430
+matrix505		MACH_MATRIX505		MATRIX505		3431
+oce_nigma		MACH_OCE_NIGMA		OCE_NIGMA		3432
+t55			MACH_T55		T55			3433
+bio3k			MACH_BIO3K		BIO3K			3434
+expressct		MACH_EXPRESSCT		EXPRESSCT		3435
+cardhu			MACH_CARDHU		CARDHU			3436
+aruba			MACH_ARUBA		ARUBA			3437
+bonaire			MACH_BONAIRE		BONAIRE			3438
+nuc700evb		MACH_NUC700EVB		NUC700EVB		3439
+nuc710evb		MACH_NUC710EVB		NUC710EVB		3440
+nuc740evb		MACH_NUC740EVB		NUC740EVB		3441
+nuc745evb		MACH_NUC745EVB		NUC745EVB		3442
+transcede		MACH_TRANSCEDE		TRANSCEDE		3443
+mora			MACH_MORA		MORA			3444
+nda_evm			MACH_NDA_EVM		NDA_EVM			3445
+timu			MACH_TIMU		TIMU			3446
+expressh		MACH_EXPRESSH		EXPRESSH		3447
+veridis_a300		MACH_VERIDIS_A300	VERIDIS_A300		3448
+dm368_leopard		MACH_DM368_LEOPARD	DM368_LEOPARD		3449
+omap_mcop		MACH_OMAP_MCOP		OMAP_MCOP		3450
+tritip			MACH_TRITIP		TRITIP			3451
+sm1k			MACH_SM1K		SM1K			3452
+monch			MACH_MONCH		MONCH			3453
+curacao			MACH_CURACAO		CURACAO			3454
+origen			MACH_ORIGEN		ORIGEN			3455
+epc10			MACH_EPC10		EPC10			3456
+sgh_i740		MACH_SGH_I740		SGH_I740		3457
+tuna			MACH_TUNA		TUNA			3458
+mx51_tulip		MACH_MX51_TULIP		MX51_TULIP		3459
+mx51_aster7		MACH_MX51_ASTER7	MX51_ASTER7		3460
+acro37xbrd		MACH_ACRO37XBRD		ACRO37XBRD		3461
+elke			MACH_ELKE		ELKE			3462
+sbc6000x		MACH_SBC6000X		SBC6000X		3463
+r1801e			MACH_R1801E		R1801E			3464
+h1600			MACH_H1600		H1600			3465
+mini210			MACH_MINI210		MINI210			3466
+mini8168		MACH_MINI8168		MINI8168		3467
+pc7308			MACH_PC7308		PC7308			3468
+kmm2m01			MACH_KMM2M01		KMM2M01			3470
+mx51erebus		MACH_MX51EREBUS		MX51EREBUS		3471
+wm8650refboard		MACH_WM8650REFBOARD	WM8650REFBOARD		3472
+tuxrail			MACH_TUXRAIL		TUXRAIL			3473
+arthur			MACH_ARTHUR		ARTHUR			3474
+doorboy			MACH_DOORBOY		DOORBOY			3475
+xarina			MACH_XARINA		XARINA			3476
+roverx7			MACH_ROVERX7		ROVERX7			3477
+sdvr			MACH_SDVR		SDVR			3478
+acer_maya		MACH_ACER_MAYA		ACER_MAYA		3479
+pico			MACH_PICO		PICO			3480
+cwmx233			MACH_CWMX233		CWMX233			3481
+cwam1808		MACH_CWAM1808		CWAM1808		3482
+cwdm365			MACH_CWDM365		CWDM365			3483
+mx51_moray		MACH_MX51_MORAY		MX51_MORAY		3484
+thales_cbc		MACH_THALES_CBC		THALES_CBC		3485
+bluepoint		MACH_BLUEPOINT		BLUEPOINT		3486
+dir665			MACH_DIR665		DIR665			3487
+acmerover1		MACH_ACMEROVER1		ACMEROVER1		3488
+shooter_ct		MACH_SHOOTER_CT		SHOOTER_CT		3489
+bliss			MACH_BLISS		BLISS			3490
+blissc			MACH_BLISSC		BLISSC			3491
+thales_adc		MACH_THALES_ADC		THALES_ADC		3492
+ubisys_p9d_evp		MACH_UBISYS_P9D_EVP	UBISYS_P9D_EVP		3493
+atdgp318		MACH_ATDGP318		ATDGP318		3494
diff -druN linux-2.6.39-libre/arch/arm/vfp/vfpmodule.c linux-3.0-rc7-libre/arch/arm/vfp/vfpmodule.c
--- linux-2.6.39-libre/arch/arm/vfp/vfpmodule.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/arm/vfp/vfpmodule.c	2011-07-11 19:51:52.000000000 -0400
@@ -398,9 +398,9 @@
 }
 
 #ifdef CONFIG_PM
-#include <linux/sysdev.h>
+#include <linux/syscore_ops.h>
 
-static int vfp_pm_suspend(struct sys_device *dev, pm_message_t state)
+static int vfp_pm_suspend(void)
 {
 	struct thread_info *ti = current_thread_info();
 	u32 fpexc = fmrx(FPEXC);
@@ -420,34 +420,25 @@
 	return 0;
 }
 
-static int vfp_pm_resume(struct sys_device *dev)
+static void vfp_pm_resume(void)
 {
 	/* ensure we have access to the vfp */
 	vfp_enable(NULL);
 
 	/* and disable it to ensure the next usage restores the state */
 	fmxr(FPEXC, fmrx(FPEXC) & ~FPEXC_EN);
-
-	return 0;
 }
 
-static struct sysdev_class vfp_pm_sysclass = {
-	.name		= "vfp",
+static struct syscore_ops vfp_pm_syscore_ops = {
 	.suspend	= vfp_pm_suspend,
 	.resume		= vfp_pm_resume,
 };
 
-static struct sys_device vfp_pm_sysdev = {
-	.cls	= &vfp_pm_sysclass,
-};
-
 static void vfp_pm_init(void)
 {
-	sysdev_class_register(&vfp_pm_sysclass);
-	sysdev_register(&vfp_pm_sysdev);
+	register_syscore_ops(&vfp_pm_syscore_ops);
 }
 
-
 #else
 static inline void vfp_pm_init(void) { }
 #endif /* CONFIG_PM */
diff -druN linux-2.6.39-libre/arch/avr32/configs/atngw100_defconfig linux-3.0-rc7-libre/arch/avr32/configs/atngw100_defconfig
--- linux-2.6.39-libre/arch/avr32/configs/atngw100_defconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/avr32/configs/atngw100_defconfig	2011-07-11 19:51:52.000000000 -0400
@@ -5,6 +5,7 @@
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_RELAY=y
 CONFIG_BLK_DEV_INITRD=y
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
 # CONFIG_SYSCTL_SYSCALL is not set
 # CONFIG_BASE_FULL is not set
 # CONFIG_COMPAT_BRK is not set
diff -druN linux-2.6.39-libre/arch/avr32/configs/atngw100_evklcd100_defconfig linux-3.0-rc7-libre/arch/avr32/configs/atngw100_evklcd100_defconfig
--- linux-2.6.39-libre/arch/avr32/configs/atngw100_evklcd100_defconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/avr32/configs/atngw100_evklcd100_defconfig	2011-07-11 19:51:52.000000000 -0400
@@ -5,6 +5,7 @@
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_RELAY=y
 CONFIG_BLK_DEV_INITRD=y
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
 # CONFIG_SYSCTL_SYSCALL is not set
 # CONFIG_BASE_FULL is not set
 # CONFIG_COMPAT_BRK is not set
diff -druN linux-2.6.39-libre/arch/avr32/configs/atngw100_evklcd101_defconfig linux-3.0-rc7-libre/arch/avr32/configs/atngw100_evklcd101_defconfig
--- linux-2.6.39-libre/arch/avr32/configs/atngw100_evklcd101_defconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/avr32/configs/atngw100_evklcd101_defconfig	2011-07-11 19:51:52.000000000 -0400
@@ -5,6 +5,7 @@
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_RELAY=y
 CONFIG_BLK_DEV_INITRD=y
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
 # CONFIG_SYSCTL_SYSCALL is not set
 # CONFIG_BASE_FULL is not set
 # CONFIG_COMPAT_BRK is not set
diff -druN linux-2.6.39-libre/arch/avr32/configs/atngw100mkii_defconfig linux-3.0-rc7-libre/arch/avr32/configs/atngw100mkii_defconfig
--- linux-2.6.39-libre/arch/avr32/configs/atngw100mkii_defconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/avr32/configs/atngw100mkii_defconfig	2011-07-11 19:51:52.000000000 -0400
@@ -5,6 +5,7 @@
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_RELAY=y
 CONFIG_BLK_DEV_INITRD=y
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
 # CONFIG_SYSCTL_SYSCALL is not set
 # CONFIG_BASE_FULL is not set
 # CONFIG_COMPAT_BRK is not set
diff -druN linux-2.6.39-libre/arch/avr32/configs/atngw100mkii_evklcd100_defconfig linux-3.0-rc7-libre/arch/avr32/configs/atngw100mkii_evklcd100_defconfig
--- linux-2.6.39-libre/arch/avr32/configs/atngw100mkii_evklcd100_defconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/avr32/configs/atngw100mkii_evklcd100_defconfig	2011-07-11 19:51:52.000000000 -0400
@@ -5,6 +5,7 @@
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_RELAY=y
 CONFIG_BLK_DEV_INITRD=y
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
 # CONFIG_SYSCTL_SYSCALL is not set
 # CONFIG_BASE_FULL is not set
 # CONFIG_COMPAT_BRK is not set
diff -druN linux-2.6.39-libre/arch/avr32/configs/atngw100mkii_evklcd101_defconfig linux-3.0-rc7-libre/arch/avr32/configs/atngw100mkii_evklcd101_defconfig
--- linux-2.6.39-libre/arch/avr32/configs/atngw100mkii_evklcd101_defconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/avr32/configs/atngw100mkii_evklcd101_defconfig	2011-07-11 19:51:52.000000000 -0400
@@ -5,6 +5,7 @@
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_RELAY=y
 CONFIG_BLK_DEV_INITRD=y
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
 # CONFIG_SYSCTL_SYSCALL is not set
 # CONFIG_BASE_FULL is not set
 # CONFIG_COMPAT_BRK is not set
diff -druN linux-2.6.39-libre/arch/avr32/configs/atngw100_mrmt_defconfig linux-3.0-rc7-libre/arch/avr32/configs/atngw100_mrmt_defconfig
--- linux-2.6.39-libre/arch/avr32/configs/atngw100_mrmt_defconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/avr32/configs/atngw100_mrmt_defconfig	2011-07-11 19:51:52.000000000 -0400
@@ -7,6 +7,7 @@
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_SYSFS_DEPRECATED_V2=y
 CONFIG_BLK_DEV_INITRD=y
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
 # CONFIG_SYSCTL_SYSCALL is not set
 # CONFIG_BASE_FULL is not set
 # CONFIG_SLUB_DEBUG is not set
@@ -109,7 +110,7 @@
 CONFIG_LEDS_TRIGGERS=y
 CONFIG_LEDS_TRIGGER_TIMER=y
 CONFIG_LEDS_TRIGGER_HEARTBEAT=y
-CONFIG_RTC_CLASS=m
+CONFIG_RTC_CLASS=y
 CONFIG_RTC_DRV_S35390A=m
 CONFIG_RTC_DRV_AT32AP700X=m
 CONFIG_DMADEVICES=y
diff -druN linux-2.6.39-libre/arch/avr32/configs/atstk1002_defconfig linux-3.0-rc7-libre/arch/avr32/configs/atstk1002_defconfig
--- linux-2.6.39-libre/arch/avr32/configs/atstk1002_defconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/avr32/configs/atstk1002_defconfig	2011-07-11 19:51:52.000000000 -0400
@@ -5,6 +5,7 @@
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_RELAY=y
 CONFIG_BLK_DEV_INITRD=y
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
 # CONFIG_SYSCTL_SYSCALL is not set
 # CONFIG_BASE_FULL is not set
 # CONFIG_COMPAT_BRK is not set
diff -druN linux-2.6.39-libre/arch/avr32/configs/atstk1003_defconfig linux-3.0-rc7-libre/arch/avr32/configs/atstk1003_defconfig
--- linux-2.6.39-libre/arch/avr32/configs/atstk1003_defconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/avr32/configs/atstk1003_defconfig	2011-07-11 19:51:52.000000000 -0400
@@ -5,6 +5,7 @@
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_RELAY=y
 CONFIG_BLK_DEV_INITRD=y
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
 # CONFIG_SYSCTL_SYSCALL is not set
 # CONFIG_BASE_FULL is not set
 # CONFIG_COMPAT_BRK is not set
diff -druN linux-2.6.39-libre/arch/avr32/configs/atstk1004_defconfig linux-3.0-rc7-libre/arch/avr32/configs/atstk1004_defconfig
--- linux-2.6.39-libre/arch/avr32/configs/atstk1004_defconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/avr32/configs/atstk1004_defconfig	2011-07-11 19:51:52.000000000 -0400
@@ -5,6 +5,7 @@
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_RELAY=y
 CONFIG_BLK_DEV_INITRD=y
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
 # CONFIG_SYSCTL_SYSCALL is not set
 # CONFIG_BASE_FULL is not set
 # CONFIG_COMPAT_BRK is not set
diff -druN linux-2.6.39-libre/arch/avr32/configs/atstk1006_defconfig linux-3.0-rc7-libre/arch/avr32/configs/atstk1006_defconfig
--- linux-2.6.39-libre/arch/avr32/configs/atstk1006_defconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/avr32/configs/atstk1006_defconfig	2011-07-11 19:51:52.000000000 -0400
@@ -5,6 +5,7 @@
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_RELAY=y
 CONFIG_BLK_DEV_INITRD=y
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
 # CONFIG_SYSCTL_SYSCALL is not set
 # CONFIG_BASE_FULL is not set
 # CONFIG_COMPAT_BRK is not set
diff -druN linux-2.6.39-libre/arch/avr32/configs/favr-32_defconfig linux-3.0-rc7-libre/arch/avr32/configs/favr-32_defconfig
--- linux-2.6.39-libre/arch/avr32/configs/favr-32_defconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/avr32/configs/favr-32_defconfig	2011-07-11 19:51:52.000000000 -0400
@@ -6,6 +6,7 @@
 CONFIG_SYSFS_DEPRECATED_V2=y
 CONFIG_RELAY=y
 CONFIG_BLK_DEV_INITRD=y
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
 # CONFIG_SYSCTL_SYSCALL is not set
 # CONFIG_BASE_FULL is not set
 # CONFIG_COMPAT_BRK is not set
diff -druN linux-2.6.39-libre/arch/avr32/configs/hammerhead_defconfig linux-3.0-rc7-libre/arch/avr32/configs/hammerhead_defconfig
--- linux-2.6.39-libre/arch/avr32/configs/hammerhead_defconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/avr32/configs/hammerhead_defconfig	2011-07-11 19:51:52.000000000 -0400
@@ -7,6 +7,7 @@
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_SYSFS_DEPRECATED_V2=y
 CONFIG_BLK_DEV_INITRD=y
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
 # CONFIG_SYSCTL_SYSCALL is not set
 # CONFIG_BASE_FULL is not set
 # CONFIG_COMPAT_BRK is not set
diff -druN linux-2.6.39-libre/arch/avr32/configs/merisc_defconfig linux-3.0-rc7-libre/arch/avr32/configs/merisc_defconfig
--- linux-2.6.39-libre/arch/avr32/configs/merisc_defconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/avr32/configs/merisc_defconfig	2011-07-11 19:51:52.000000000 -0400
@@ -7,6 +7,7 @@
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_SYSFS_DEPRECATED_V2=y
 CONFIG_BLK_DEV_INITRD=y
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
 # CONFIG_SYSCTL_SYSCALL is not set
 # CONFIG_BASE_FULL is not set
 CONFIG_MODULES=y
diff -druN linux-2.6.39-libre/arch/avr32/configs/mimc200_defconfig linux-3.0-rc7-libre/arch/avr32/configs/mimc200_defconfig
--- linux-2.6.39-libre/arch/avr32/configs/mimc200_defconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/avr32/configs/mimc200_defconfig	2011-07-11 19:51:52.000000000 -0400
@@ -7,6 +7,7 @@
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_SYSFS_DEPRECATED_V2=y
 CONFIG_BLK_DEV_INITRD=y
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
 # CONFIG_SYSCTL_SYSCALL is not set
 # CONFIG_BASE_FULL is not set
 # CONFIG_COMPAT_BRK is not set
diff -druN linux-2.6.39-libre/arch/avr32/include/asm/bitops.h linux-3.0-rc7-libre/arch/avr32/include/asm/bitops.h
--- linux-2.6.39-libre/arch/avr32/include/asm/bitops.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/avr32/include/asm/bitops.h	2011-07-11 19:51:52.000000000 -0400
@@ -270,14 +270,21 @@
 
 unsigned long find_first_zero_bit(const unsigned long *addr,
 				  unsigned long size);
+#define find_first_zero_bit find_first_zero_bit
+
 unsigned long find_next_zero_bit(const unsigned long *addr,
 				 unsigned long size,
 				 unsigned long offset);
+#define find_next_zero_bit find_next_zero_bit
+
 unsigned long find_first_bit(const unsigned long *addr,
 			     unsigned long size);
+#define find_first_bit find_first_bit
+
 unsigned long find_next_bit(const unsigned long *addr,
 				 unsigned long size,
 				 unsigned long offset);
+#define find_next_bit find_next_bit
 
 /*
  * ffs: find first bit set. This is defined the same way as
@@ -299,6 +306,14 @@
 #include <asm-generic/bitops/hweight.h>
 #include <asm-generic/bitops/lock.h>
 
+extern unsigned long find_next_zero_bit_le(const void *addr,
+		unsigned long size, unsigned long offset);
+#define find_next_zero_bit_le find_next_zero_bit_le
+
+extern unsigned long find_next_bit_le(const void *addr,
+		unsigned long size, unsigned long offset);
+#define find_next_bit_le find_next_bit_le
+
 #include <asm-generic/bitops/le.h>
 #include <asm-generic/bitops/ext2-atomic.h>
 
diff -druN linux-2.6.39-libre/arch/avr32/include/asm/processor.h linux-3.0-rc7-libre/arch/avr32/include/asm/processor.h
--- linux-2.6.39-libre/arch/avr32/include/asm/processor.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/avr32/include/asm/processor.h	2011-07-11 19:51:52.000000000 -0400
@@ -131,7 +131,6 @@
  */
 #define start_thread(regs, new_pc, new_sp)	 \
 	do {					 \
-		set_fs(USER_DS);		 \
 		memset(regs, 0, sizeof(*regs));	 \
 		regs->sr = MODE_USER;		 \
 		regs->pc = new_pc & ~1;		 \
diff -druN linux-2.6.39-libre/arch/avr32/include/asm/unistd.h linux-3.0-rc7-libre/arch/avr32/include/asm/unistd.h
--- linux-2.6.39-libre/arch/avr32/include/asm/unistd.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/avr32/include/asm/unistd.h	2011-07-11 19:51:52.000000000 -0400
@@ -299,9 +299,10 @@
 #define __NR_signalfd		279
 /* 280 was __NR_timerfd */
 #define __NR_eventfd		281
+#define __NR_setns		283
 
 #ifdef __KERNEL__
-#define NR_syscalls		282
+#define NR_syscalls		284
 
 /* Old stuff */
 #define __IGNORE_uselib
diff -druN linux-2.6.39-libre/arch/avr32/kernel/syscall_table.S linux-3.0-rc7-libre/arch/avr32/kernel/syscall_table.S
--- linux-2.6.39-libre/arch/avr32/kernel/syscall_table.S	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/avr32/kernel/syscall_table.S	2011-07-11 19:51:52.000000000 -0400
@@ -296,4 +296,5 @@
 	.long	sys_ni_syscall		/* 280, was sys_timerfd */
 	.long	sys_eventfd
 	.long	sys_recvmmsg
+	.long	sys_setns
 	.long	sys_ni_syscall		/* r8 is saturated at nr_syscalls */
diff -druN linux-2.6.39-libre/arch/avr32/mach-at32ap/at32ap700x.c linux-3.0-rc7-libre/arch/avr32/mach-at32ap/at32ap700x.c
--- linux-2.6.39-libre/arch/avr32/mach-at32ap/at32ap700x.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/avr32/mach-at32ap/at32ap700x.c	2011-07-11 19:51:52.000000000 -0400
@@ -1014,6 +1014,7 @@
 void __init at32_map_usart(unsigned int hw_id, unsigned int line, int flags)
 {
 	struct platform_device *pdev;
+	struct atmel_uart_data *pdata;
 
 	switch (hw_id) {
 	case 0:
@@ -1043,6 +1044,8 @@
 	}
 
 	pdev->id = line;
+	pdata = pdev->dev.platform_data;
+	pdata->num = line;
 	at32_usarts[line] = pdev;
 }
 
diff -druN linux-2.6.39-libre/arch/avr32/mach-at32ap/include/mach/board.h linux-3.0-rc7-libre/arch/avr32/mach-at32ap/include/mach/board.h
--- linux-2.6.39-libre/arch/avr32/mach-at32ap/include/mach/board.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/avr32/mach-at32ap/include/mach/board.h	2011-07-11 19:51:52.000000000 -0400
@@ -33,6 +33,7 @@
 #define	ATMEL_USART_CLK		0x04
 
 struct atmel_uart_data {
+	int		num;		/* port num */
 	short		use_dma_tx;	/* use transmit DMA? */
 	short		use_dma_rx;	/* use receive DMA? */
 	void __iomem	*regs;		/* virtual base address, if any */
diff -druN linux-2.6.39-libre/arch/avr32/mach-at32ap/include/mach/cpu.h linux-3.0-rc7-libre/arch/avr32/mach-at32ap/include/mach/cpu.h
--- linux-2.6.39-libre/arch/avr32/mach-at32ap/include/mach/cpu.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/avr32/mach-at32ap/include/mach/cpu.h	2011-07-11 19:51:52.000000000 -0400
@@ -31,8 +31,20 @@
 #define cpu_is_at91sam9263()	(0)
 #define cpu_is_at91sam9rl()	(0)
 #define cpu_is_at91cap9()	(0)
+#define cpu_is_at91cap9_revB()	(0)
+#define cpu_is_at91cap9_revC()	(0)
 #define cpu_is_at91sam9g10()	(0)
+#define cpu_is_at91sam9g20()	(0)
 #define cpu_is_at91sam9g45()	(0)
 #define cpu_is_at91sam9g45es()	(0)
+#define cpu_is_at91sam9m10()	(0)
+#define cpu_is_at91sam9g46()	(0)
+#define cpu_is_at91sam9m11()	(0)
+#define cpu_is_at91sam9x5()	(0)
+#define cpu_is_at91sam9g15()	(0)
+#define cpu_is_at91sam9g35()	(0)
+#define cpu_is_at91sam9x35()	(0)
+#define cpu_is_at91sam9g25()	(0)
+#define cpu_is_at91sam9x25()	(0)
 
 #endif /* __ASM_ARCH_CPU_H */
diff -druN linux-2.6.39-libre/arch/avr32/mach-at32ap/intc.c linux-3.0-rc7-libre/arch/avr32/mach-at32ap/intc.c
--- linux-2.6.39-libre/arch/avr32/mach-at32ap/intc.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/avr32/mach-at32ap/intc.c	2011-07-11 19:51:52.000000000 -0400
@@ -12,7 +12,7 @@
 #include <linux/interrupt.h>
 #include <linux/irq.h>
 #include <linux/platform_device.h>
-#include <linux/sysdev.h>
+#include <linux/syscore_ops.h>
 
 #include <asm/io.h>
 
@@ -21,7 +21,6 @@
 struct intc {
 	void __iomem		*regs;
 	struct irq_chip		chip;
-	struct sys_device	sysdev;
 #ifdef CONFIG_PM
 	unsigned long		suspend_ipr;
 	unsigned long		saved_ipr[64];
@@ -146,9 +145,8 @@
 	intc0.suspend_ipr = offset;
 }
 
-static int intc_suspend(struct sys_device *sdev, pm_message_t state)
+static int intc_suspend(void)
 {
-	struct intc *intc = container_of(sdev, struct intc, sysdev);
 	int i;
 
 	if (unlikely(!irqs_disabled())) {
@@ -156,57 +154,43 @@
 		return -EINVAL;
 	}
 
-	if (unlikely(!intc->suspend_ipr)) {
+	if (unlikely(!intc0.suspend_ipr)) {
 		pr_err("intc_suspend: suspend_ipr not initialized\n");
 		return -EINVAL;
 	}
 
 	for (i = 0; i < 64; i++) {
-		intc->saved_ipr[i] = intc_readl(intc, INTPR0 + 4 * i);
-		intc_writel(intc, INTPR0 + 4 * i, intc->suspend_ipr);
+		intc0.saved_ipr[i] = intc_readl(&intc0, INTPR0 + 4 * i);
+		intc_writel(&intc0, INTPR0 + 4 * i, intc0.suspend_ipr);
 	}
 
 	return 0;
 }
 
-static int intc_resume(struct sys_device *sdev)
+static void intc_resume(void)
 {
-	struct intc *intc = container_of(sdev, struct intc, sysdev);
 	int i;
 
-	WARN_ON(!irqs_disabled());
-
 	for (i = 0; i < 64; i++)
-		intc_writel(intc, INTPR0 + 4 * i, intc->saved_ipr[i]);
-
-	return 0;
+		intc_writel(&intc0, INTPR0 + 4 * i, intc0.saved_ipr[i]);
 }
 #else
 #define intc_suspend	NULL
 #define intc_resume	NULL
 #endif
 
-static struct sysdev_class intc_class = {
-	.name		= "intc",
+static struct syscore_ops intc_syscore_ops = {
 	.suspend	= intc_suspend,
 	.resume		= intc_resume,
 };
 
-static int __init intc_init_sysdev(void)
+static int __init intc_init_syscore(void)
 {
-	int ret;
-
-	ret = sysdev_class_register(&intc_class);
-	if (ret)
-		return ret;
-
-	intc0.sysdev.id = 0;
-	intc0.sysdev.cls = &intc_class;
-	ret = sysdev_register(&intc0.sysdev);
+	register_syscore_ops(&intc_syscore_ops);
 
-	return ret;
+	return 0;
 }
-device_initcall(intc_init_sysdev);
+device_initcall(intc_init_syscore);
 
 unsigned long intc_get_pending(unsigned int group)
 {
diff -druN linux-2.6.39-libre/arch/avr32/mm/init.c linux-3.0-rc7-libre/arch/avr32/mm/init.c
--- linux-2.6.39-libre/arch/avr32/mm/init.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/avr32/mm/init.c	2011-07-11 19:51:52.000000000 -0400
@@ -25,8 +25,6 @@
 #include <asm/setup.h>
 #include <asm/sections.h>
 
-DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
-
 pgd_t swapper_pg_dir[PTRS_PER_PGD] __page_aligned_data;
 
 struct page *empty_zero_page;
diff -druN linux-2.6.39-libre/arch/blackfin/configs/BF527-EZKIT_defconfig linux-3.0-rc7-libre/arch/blackfin/configs/BF527-EZKIT_defconfig
--- linux-2.6.39-libre/arch/blackfin/configs/BF527-EZKIT_defconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/blackfin/configs/BF527-EZKIT_defconfig	2011-07-11 19:51:52.000000000 -0400
@@ -96,7 +96,7 @@
 # CONFIG_HW_RANDOM is not set
 CONFIG_I2C=y
 CONFIG_I2C_CHARDEV=m
-CONFIG_I2C_BLACKFIN_TWI=m
+CONFIG_I2C_BLACKFIN_TWI=y
 CONFIG_I2C_BLACKFIN_TWI_CLK_KHZ=100
 CONFIG_SPI=y
 CONFIG_SPI_BFIN=y
@@ -115,13 +115,11 @@
 # CONFIG_LOGO_LINUX_VGA16 is not set
 # CONFIG_LOGO_LINUX_CLUT224 is not set
 # CONFIG_LOGO_BLACKFIN_VGA16 is not set
-CONFIG_SOUND=m
-CONFIG_SND=m
-CONFIG_SND_SOC=m
-CONFIG_SND_BF5XX_I2S=m
-CONFIG_SND_BF5XX_SOC_SSM2602=m
-CONFIG_SND_BF5XX_AC97=m
-CONFIG_SND_BF5XX_SOC_AD1980=m
+CONFIG_SOUND=y
+CONFIG_SND=y
+CONFIG_SND_SOC=y
+CONFIG_SND_BF5XX_I2S=y
+CONFIG_SND_BF5XX_SOC_SSM2602=y
 CONFIG_HID_A4TECH=y
 CONFIG_HID_APPLE=y
 CONFIG_HID_BELKIN=y
diff -druN linux-2.6.39-libre/arch/blackfin/configs/BF527-EZKIT-V2_defconfig linux-3.0-rc7-libre/arch/blackfin/configs/BF527-EZKIT-V2_defconfig
--- linux-2.6.39-libre/arch/blackfin/configs/BF527-EZKIT-V2_defconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/blackfin/configs/BF527-EZKIT-V2_defconfig	2011-07-11 19:51:52.000000000 -0400
@@ -121,13 +121,11 @@
 # CONFIG_LOGO_LINUX_VGA16 is not set
 # CONFIG_LOGO_LINUX_CLUT224 is not set
 # CONFIG_LOGO_BLACKFIN_VGA16 is not set
-CONFIG_SOUND=m
-CONFIG_SND=m
-CONFIG_SND_SOC=m
-CONFIG_SND_BF5XX_I2S=m
-CONFIG_SND_BF5XX_SOC_SSM2602=m
-CONFIG_SND_BF5XX_AC97=m
-CONFIG_SND_BF5XX_SOC_AD1980=m
+CONFIG_SOUND=y
+CONFIG_SND=y
+CONFIG_SND_SOC=y
+CONFIG_SND_BF5XX_I2S=y
+CONFIG_SND_BF5XX_SOC_SSM2602=y
 CONFIG_HID_A4TECH=y
 CONFIG_HID_APPLE=y
 CONFIG_HID_BELKIN=y
diff -druN linux-2.6.39-libre/arch/blackfin/configs/BF533-STAMP_defconfig linux-3.0-rc7-libre/arch/blackfin/configs/BF533-STAMP_defconfig
--- linux-2.6.39-libre/arch/blackfin/configs/BF533-STAMP_defconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/blackfin/configs/BF533-STAMP_defconfig	2011-07-11 19:51:52.000000000 -0400
@@ -99,8 +99,6 @@
 CONFIG_SND_SOC=m
 CONFIG_SND_BF5XX_I2S=m
 CONFIG_SND_BF5XX_SOC_AD73311=m
-CONFIG_SND_BF5XX_AC97=m
-CONFIG_SND_BF5XX_SOC_AD1980=m
 # CONFIG_USB_SUPPORT is not set
 CONFIG_RTC_CLASS=y
 CONFIG_RTC_DRV_BFIN=y
diff -druN linux-2.6.39-libre/arch/blackfin/configs/BF537-STAMP_defconfig linux-3.0-rc7-libre/arch/blackfin/configs/BF537-STAMP_defconfig
--- linux-2.6.39-libre/arch/blackfin/configs/BF537-STAMP_defconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/blackfin/configs/BF537-STAMP_defconfig	2011-07-11 19:51:52.000000000 -0400
@@ -110,8 +110,6 @@
 CONFIG_SND_SOC=m
 CONFIG_SND_BF5XX_I2S=m
 CONFIG_SND_BF5XX_SOC_AD73311=m
-CONFIG_SND_BF5XX_AC97=m
-CONFIG_SND_BF5XX_SOC_AD1980=m
 # CONFIG_USB_SUPPORT is not set
 CONFIG_RTC_CLASS=y
 CONFIG_RTC_DRV_BFIN=y
diff -druN linux-2.6.39-libre/arch/blackfin/configs/CM-BF548_defconfig linux-3.0-rc7-libre/arch/blackfin/configs/CM-BF548_defconfig
--- linux-2.6.39-libre/arch/blackfin/configs/CM-BF548_defconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/blackfin/configs/CM-BF548_defconfig	2011-07-11 19:51:52.000000000 -0400
@@ -112,7 +112,7 @@
 CONFIG_USB_G_PRINTER=m
 CONFIG_MMC=m
 CONFIG_SDH_BFIN=m
-CONFIG_RTC_CLASS=m
+CONFIG_RTC_CLASS=y
 CONFIG_RTC_DRV_BFIN=m
 CONFIG_EXT2_FS=m
 # CONFIG_DNOTIFY is not set
diff -druN linux-2.6.39-libre/arch/blackfin/include/asm/bfin-global.h linux-3.0-rc7-libre/arch/blackfin/include/asm/bfin-global.h
--- linux-2.6.39-libre/arch/blackfin/include/asm/bfin-global.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/blackfin/include/asm/bfin-global.h	2011-07-11 19:51:52.000000000 -0400
@@ -49,16 +49,6 @@
 #define dump_bfin_trace_buffer()
 #endif
 
-/* init functions only */
-extern int init_arch_irq(void);
-extern void init_exception_vectors(void);
-extern void program_IAR(void);
-
-extern asmlinkage void lower_to_irq14(void);
-extern asmlinkage void bfin_return_from_exception(void);
-extern asmlinkage void asm_do_IRQ(unsigned int irq, struct pt_regs *regs);
-extern int bfin_internal_set_wake(unsigned int irq, unsigned int state);
-
 extern void *l1_data_A_sram_alloc(size_t);
 extern void *l1_data_B_sram_alloc(size_t);
 extern void *l1_inst_sram_alloc(size_t);
diff -druN linux-2.6.39-libre/arch/blackfin/include/asm/bfin_pfmon.h linux-3.0-rc7-libre/arch/blackfin/include/asm/bfin_pfmon.h
--- linux-2.6.39-libre/arch/blackfin/include/asm/bfin_pfmon.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/blackfin/include/asm/bfin_pfmon.h	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,44 @@
+/*
+ * Blackfin Performance Monitor definitions
+ *
+ * Copyright 2005-2011 Analog Devices Inc.
+ *
+ * Licensed under the ADI BSD license or GPL-2 (or later).
+ */
+
+#ifndef __ASM_BFIN_PFMON_H__
+#define __ASM_BFIN_PFMON_H__
+
+/* PFCTL Masks */
+#define PFMON_MASK	0xff
+#define PFCEN_MASK	0x3
+#define PFCEN_DISABLE	0x0
+#define PFCEN_ENABLE_USER	0x1
+#define PFCEN_ENABLE_SUPV	0x2
+#define PFCEN_ENABLE_ALL	(PFCEN_ENABLE_USER | PFCEN_ENABLE_SUPV)
+
+#define PFPWR_P	0
+#define PEMUSW0_P	2
+#define PFCEN0_P	3
+#define PFMON0_P	5
+#define PEMUSW1_P	13
+#define PFCEN1_P	14
+#define PFMON1_P	16
+#define PFCNT0_P	24
+#define PFCNT1_P	25
+
+#define PFPWR	(1 << PFPWR_P)
+#define PEMUSW(n, x)	((x) << ((n) ? PEMUSW1_P : PEMUSW0_P))
+#define PEMUSW0	PEMUSW(0, 1)
+#define PEMUSW1	PEMUSW(1, 1)
+#define PFCEN(n, x)	((x) << ((n) ? PFCEN1_P : PFCEN0_P))
+#define PFCEN0	PFCEN(0, PFCEN_MASK)
+#define PFCEN1	PFCEN(1, PFCEN_MASK)
+#define PFCNT(n, x)	((x) << ((n) ? PFCNT1_P : PFCNT0_P))
+#define PFCNT0	PFCNT(0, 1)
+#define PFCNT1	PFCNT(1, 1)
+#define PFMON(n, x)	((x) << ((n) ? PFMON1_P : PFMON0_P))
+#define PFMON0	PFMON(0, PFMON_MASK)
+#define PFMON1	PFMON(1, PFMON_MASK)
+
+#endif
diff -druN linux-2.6.39-libre/arch/blackfin/include/asm/bfin_serial.h linux-3.0-rc7-libre/arch/blackfin/include/asm/bfin_serial.h
--- linux-2.6.39-libre/arch/blackfin/include/asm/bfin_serial.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/blackfin/include/asm/bfin_serial.h	2011-07-11 19:51:52.000000000 -0400
@@ -184,7 +184,7 @@
 #undef __BFP
 
 #ifndef port_membase
-# define port_membase(p) (((struct bfin_serial_port *)(p))->port.membase)
+# define port_membase(p) 0
 #endif
 
 #define UART_GET_CHAR(p)      bfin_read16(port_membase(p) + OFFSET_RBR)
@@ -235,10 +235,10 @@
 #define UART_SET_DLAB(p)      do { UART_PUT_LCR(p, UART_GET_LCR(p) | DLAB); SSYNC(); } while (0)
 
 #ifndef put_lsr_cache
-# define put_lsr_cache(p, v) (((struct bfin_serial_port *)(p))->lsr = (v))
+# define put_lsr_cache(p, v)
 #endif
 #ifndef get_lsr_cache
-# define get_lsr_cache(p)    (((struct bfin_serial_port *)(p))->lsr)
+# define get_lsr_cache(p) 0
 #endif
 
 /* The hardware clears the LSR bits upon read, so we need to cache
diff -druN linux-2.6.39-libre/arch/blackfin/include/asm/bfin_sport.h linux-3.0-rc7-libre/arch/blackfin/include/asm/bfin_sport.h
--- linux-2.6.39-libre/arch/blackfin/include/asm/bfin_sport.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/blackfin/include/asm/bfin_sport.h	2011-07-11 19:51:52.000000000 -0400
@@ -100,6 +100,10 @@
 };
 #undef __BFP
 
+struct bfin_snd_platform_data {
+	const unsigned short *pin_req;
+};
+
 #define bfin_read_sport_rx32(base) \
 ({ \
 	struct sport_register *__mmrs = (void *)base; \
diff -druN linux-2.6.39-libre/arch/blackfin/include/asm/cacheflush.h linux-3.0-rc7-libre/arch/blackfin/include/asm/cacheflush.h
--- linux-2.6.39-libre/arch/blackfin/include/asm/cacheflush.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/blackfin/include/asm/cacheflush.h	2011-07-11 19:51:52.000000000 -0400
@@ -39,8 +39,13 @@
 
 static inline void flush_icache_range(unsigned start, unsigned end)
 {
-#if defined(CONFIG_BFIN_EXTMEM_WRITEBACK) || defined(CONFIG_BFIN_L2_WRITEBACK)
-	blackfin_dcache_flush_range(start, end);
+#if defined(CONFIG_BFIN_EXTMEM_WRITEBACK)
+	if (end <= physical_mem_end)
+		blackfin_dcache_flush_range(start, end);
+#endif
+#if defined(CONFIG_BFIN_L2_WRITEBACK)
+	if (start >= L2_START && end <= L2_START + L2_LENGTH)
+		blackfin_dcache_flush_range(start, end);
 #endif
 
 	/* Make sure all write buffers in the data side of the core
@@ -52,9 +57,17 @@
 	 * the pipeline.
 	 */
 	SSYNC();
-#if defined(CONFIG_BFIN_ICACHE)
-	blackfin_icache_flush_range(start, end);
-	flush_icache_range_others(start, end);
+#if defined(CONFIG_BFIN_EXTMEM_ICACHEABLE)
+	if (end <= physical_mem_end) {
+		blackfin_icache_flush_range(start, end);
+		flush_icache_range_others(start, end);
+	}
+#endif
+#if defined(CONFIG_BFIN_L2_ICACHEABLE)
+	if (start >= L2_START && end <= L2_START + L2_LENGTH) {
+		blackfin_icache_flush_range(start, end);
+		flush_icache_range_others(start, end);
+	}
 #endif
 }
 
diff -druN linux-2.6.39-libre/arch/blackfin/include/asm/cpu.h linux-3.0-rc7-libre/arch/blackfin/include/asm/cpu.h
--- linux-2.6.39-libre/arch/blackfin/include/asm/cpu.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/blackfin/include/asm/cpu.h	2011-07-11 19:51:52.000000000 -0400
@@ -10,11 +10,8 @@
 
 #include <linux/percpu.h>
 
-struct task_struct;
-
 struct blackfin_cpudata {
 	struct cpu cpu;
-	struct task_struct *idle;
 	unsigned int imemctl;
 	unsigned int dmemctl;
 };
diff -druN linux-2.6.39-libre/arch/blackfin/include/asm/def_LPBlackfin.h linux-3.0-rc7-libre/arch/blackfin/include/asm/def_LPBlackfin.h
--- linux-2.6.39-libre/arch/blackfin/include/asm/def_LPBlackfin.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/blackfin/include/asm/def_LPBlackfin.h	2011-07-11 19:51:52.000000000 -0400
@@ -52,10 +52,10 @@
 
 #define bfin_read(addr) \
 ({ \
-    sizeof(*(addr)) == 1 ? bfin_read8(addr)  : \
-    sizeof(*(addr)) == 2 ? bfin_read16(addr) : \
-    sizeof(*(addr)) == 4 ? bfin_read32(addr) : \
-    ({ BUG(); 0; }); \
+	sizeof(*(addr)) == 1 ? bfin_read8(addr)  : \
+	sizeof(*(addr)) == 2 ? bfin_read16(addr) : \
+	sizeof(*(addr)) == 4 ? bfin_read32(addr) : \
+	({ BUG(); 0; }); \
 })
 #define bfin_write(addr, val) \
 do { \
@@ -69,13 +69,13 @@
 
 #define bfin_write_or(addr, bits) \
 do { \
-	void *__addr = (void *)(addr); \
+	typeof(addr) __addr = (addr); \
 	bfin_write(__addr, bfin_read(__addr) | (bits)); \
 } while (0)
 
 #define bfin_write_and(addr, bits) \
 do { \
-	void *__addr = (void *)(addr); \
+	typeof(addr) __addr = (addr); \
 	bfin_write(__addr, bfin_read(__addr) & (bits)); \
 } while (0)
 
diff -druN linux-2.6.39-libre/arch/blackfin/include/asm/gptimers.h linux-3.0-rc7-libre/arch/blackfin/include/asm/gptimers.h
--- linux-2.6.39-libre/arch/blackfin/include/asm/gptimers.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/blackfin/include/asm/gptimers.h	2011-07-11 19:51:52.000000000 -0400
@@ -193,4 +193,22 @@
 uint32_t get_gptimer_status(unsigned int group);
 void     set_gptimer_status(unsigned int group, uint32_t value);
 
+/*
+ * 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 timer registers layout
+ */
+struct bfin_gptimer_regs {
+	__BFP(config);
+	u32 counter;
+	u32 period;
+	u32 width;
+};
+
+#undef __BFP
+
 #endif
diff -druN linux-2.6.39-libre/arch/blackfin/include/asm/irq_handler.h linux-3.0-rc7-libre/arch/blackfin/include/asm/irq_handler.h
--- linux-2.6.39-libre/arch/blackfin/include/asm/irq_handler.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/blackfin/include/asm/irq_handler.h	2011-07-11 19:51:52.000000000 -0400
@@ -10,6 +10,16 @@
 #include <linux/types.h>
 #include <linux/linkage.h>
 
+/* init functions only */
+extern int __init init_arch_irq(void);
+extern void init_exception_vectors(void);
+extern void __init program_IAR(void);
+#ifdef init_mach_irq
+extern void __init init_mach_irq(void);
+#else
+# define init_mach_irq()
+#endif
+
 /* BASE LEVEL interrupt handler routines */
 asmlinkage void evt_exception(void);
 asmlinkage void trap(void);
@@ -37,4 +47,19 @@
 extern int bfin_request_exception(unsigned int exception, void (*handler)(void));
 extern int bfin_free_exception(unsigned int exception, void (*handler)(void));
 
+extern asmlinkage void lower_to_irq14(void);
+extern asmlinkage void bfin_return_from_exception(void);
+extern asmlinkage void asm_do_IRQ(unsigned int irq, struct pt_regs *regs);
+extern int bfin_internal_set_wake(unsigned int irq, unsigned int state);
+
+struct irq_data;
+extern void bfin_handle_irq(unsigned irq);
+extern void bfin_ack_noop(struct irq_data *);
+extern void bfin_internal_mask_irq(unsigned int irq);
+extern void bfin_internal_unmask_irq(unsigned int irq);
+
+struct irq_desc;
+extern void bfin_demux_mac_status_irq(unsigned int, struct irq_desc *);
+extern void bfin_demux_gpio_irq(unsigned int, struct irq_desc *);
+
 #endif
diff -druN linux-2.6.39-libre/arch/blackfin/include/asm/kgdb.h linux-3.0-rc7-libre/arch/blackfin/include/asm/kgdb.h
--- linux-2.6.39-libre/arch/blackfin/include/asm/kgdb.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/blackfin/include/asm/kgdb.h	2011-07-11 19:51:52.000000000 -0400
@@ -103,7 +103,12 @@
 	asm("EXCPT 2;");
 }
 #define BREAK_INSTR_SIZE	2
-#define CACHE_FLUSH_IS_SAFE	1
+#ifdef CONFIG_SMP
+# define CACHE_FLUSH_IS_SAFE	0
+#else
+# define CACHE_FLUSH_IS_SAFE	1
+#endif
+#define GDB_ADJUSTS_BREAK_OFFSET
 #define HW_INST_WATCHPOINT_NUM	6
 #define HW_WATCHPOINT_NUM	8
 #define TYPE_INST_WATCHPOINT	0
diff -druN linux-2.6.39-libre/arch/blackfin/include/asm/perf_event.h linux-3.0-rc7-libre/arch/blackfin/include/asm/perf_event.h
--- linux-2.6.39-libre/arch/blackfin/include/asm/perf_event.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/blackfin/include/asm/perf_event.h	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1 @@
+#define MAX_HWEVENTS 2
diff -druN linux-2.6.39-libre/arch/blackfin/include/asm/ptrace.h linux-3.0-rc7-libre/arch/blackfin/include/asm/ptrace.h
--- linux-2.6.39-libre/arch/blackfin/include/asm/ptrace.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/blackfin/include/asm/ptrace.h	2011-07-11 19:51:52.000000000 -0400
@@ -102,14 +102,9 @@
 /* user_mode returns true if only one bit is set in IPEND, other than the
    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)
 
@@ -130,6 +125,8 @@
 	    ((unsigned long)task_stack_page(task) + \
 	     (THREAD_SIZE - sizeof(struct pt_regs)))
 
+#include <asm-generic/ptrace.h>
+
 #endif  /*  __KERNEL__  */
 
 #endif				/* __ASSEMBLY__ */
diff -druN linux-2.6.39-libre/arch/blackfin/include/asm/unistd.h linux-3.0-rc7-libre/arch/blackfin/include/asm/unistd.h
--- linux-2.6.39-libre/arch/blackfin/include/asm/unistd.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/blackfin/include/asm/unistd.h	2011-07-11 19:51:52.000000000 -0400
@@ -397,8 +397,10 @@
 #define __NR_open_by_handle_at	376
 #define __NR_clock_adjtime	377
 #define __NR_syncfs		378
+#define __NR_setns		379
+#define __NR_sendmmsg		380
 
-#define __NR_syscall		379
+#define __NR_syscall		381
 #define NR_syscalls		__NR_syscall
 
 /* Old optional stuff no one actually uses */
diff -druN linux-2.6.39-libre/arch/blackfin/include/mach-common/irq.h linux-3.0-rc7-libre/arch/blackfin/include/mach-common/irq.h
--- linux-2.6.39-libre/arch/blackfin/include/mach-common/irq.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/blackfin/include/mach-common/irq.h	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,57 @@
+/*
+ * Common Blackfin IRQ definitions (i.e. the CEC)
+ *
+ * Copyright 2005-2011 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2 or later
+ */
+
+#ifndef _MACH_COMMON_IRQ_H_
+#define _MACH_COMMON_IRQ_H_
+
+/*
+ * Core events interrupt source definitions
+ *
+ *  Event Source       Event Name
+ *  Emulation          EMU            0  (highest priority)
+ *  Reset              RST            1
+ *  NMI                NMI            2
+ *  Exception          EVX            3
+ *  Reserved           --             4
+ *  Hardware Error     IVHW           5
+ *  Core Timer         IVTMR          6
+ *  Peripherals        IVG7           7
+ *  Peripherals        IVG8           8
+ *  Peripherals        IVG9           9
+ *  Peripherals        IVG10         10
+ *  Peripherals        IVG11         11
+ *  Peripherals        IVG12         12
+ *  Peripherals        IVG13         13
+ *  Softirq            IVG14         14
+ *  System Call        IVG15         15  (lowest priority)
+ */
+
+/* The ABSTRACT IRQ definitions */
+#define IRQ_EMU			0	/* Emulation */
+#define IRQ_RST			1	/* reset */
+#define IRQ_NMI			2	/* Non Maskable */
+#define IRQ_EVX			3	/* Exception */
+#define IRQ_UNUSED		4	/* - unused interrupt */
+#define IRQ_HWERR		5	/* Hardware Error */
+#define IRQ_CORETMR		6	/* Core timer */
+
+#define BFIN_IRQ(x)		((x) + 7)
+
+#define IVG7			7
+#define IVG8			8
+#define IVG9			9
+#define IVG10			10
+#define IVG11			11
+#define IVG12			12
+#define IVG13			13
+#define IVG14			14
+#define IVG15			15
+
+#define NR_IRQS			(NR_MACH_IRQS + NR_SPARE_IRQS)
+
+#endif
diff -druN linux-2.6.39-libre/arch/blackfin/Kconfig linux-3.0-rc7-libre/arch/blackfin/Kconfig
--- linux-2.6.39-libre/arch/blackfin/Kconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/blackfin/Kconfig	2011-07-11 19:51:52.000000000 -0400
@@ -24,11 +24,13 @@
 	select HAVE_FUNCTION_TRACER
 	select HAVE_FUNCTION_TRACE_MCOUNT_TEST
 	select HAVE_IDE
+	select HAVE_IRQ_WORK
 	select HAVE_KERNEL_GZIP if RAMKERNEL
 	select HAVE_KERNEL_BZIP2 if RAMKERNEL
 	select HAVE_KERNEL_LZMA if RAMKERNEL
 	select HAVE_KERNEL_LZO if RAMKERNEL
 	select HAVE_OPROFILE
+	select HAVE_PERF_EVENTS
 	select ARCH_WANT_OPTIONAL_GPIOLIB
 	select HAVE_GENERIC_HARDIRQS
 	select GENERIC_ATOMIC64
@@ -45,9 +47,6 @@
 config ZONE_DMA
 	def_bool y
 
-config GENERIC_FIND_NEXT_BIT
-	def_bool y
-
 config GENERIC_GPIO
 	def_bool y
 
diff -druN linux-2.6.39-libre/arch/blackfin/Kconfig.debug linux-3.0-rc7-libre/arch/blackfin/Kconfig.debug
--- linux-2.6.39-libre/arch/blackfin/Kconfig.debug	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/blackfin/Kconfig.debug	2011-07-11 19:51:52.000000000 -0400
@@ -9,15 +9,6 @@
 	  This option will cause messages to be printed if free stack space
 	  drops below a certain limit.
 
-config DEBUG_STACK_USAGE
-	bool "Enable stack utilization instrumentation"
-	depends on DEBUG_KERNEL
-	help
-	  Enables the display of the minimum amount of free stack which each
-	  task has ever had available in the sysrq-T output.
-
-	  This option will slow down process creation somewhat.
-
 config DEBUG_VERBOSE
 	bool "Verbose fault messages"
 	default y
@@ -32,7 +23,7 @@
 	  Most people should say N here.
 
 config DEBUG_MMRS
-	bool "Generate Blackfin MMR tree"
+	tristate "Generate Blackfin MMR tree"
 	select DEBUG_FS
 	help
 	  Create a tree of Blackfin MMRs via the debugfs tree.  If
diff -druN linux-2.6.39-libre/arch/blackfin/kernel/bfin_dma_5xx.c linux-3.0-rc7-libre/arch/blackfin/kernel/bfin_dma_5xx.c
--- linux-2.6.39-libre/arch/blackfin/kernel/bfin_dma_5xx.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/blackfin/kernel/bfin_dma_5xx.c	2011-07-11 19:51:52.000000000 -0400
@@ -36,6 +36,11 @@
 
 	printk(KERN_INFO "Blackfin DMA Controller\n");
 
+
+#if ANOMALY_05000480
+	bfin_write_DMAC_TC_PER(0x0111);
+#endif
+
 	for (i = 0; i < MAX_DMA_CHANNELS; i++) {
 		atomic_set(&dma_ch[i].chan_status, 0);
 		dma_ch[i].regs = dma_io_base_addr[i];
diff -druN linux-2.6.39-libre/arch/blackfin/kernel/bfin_gpio.c linux-3.0-rc7-libre/arch/blackfin/kernel/bfin_gpio.c
--- linux-2.6.39-libre/arch/blackfin/kernel/bfin_gpio.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/blackfin/kernel/bfin_gpio.c	2011-07-11 19:51:52.000000000 -0400
@@ -10,10 +10,12 @@
 #include <linux/module.h>
 #include <linux/err.h>
 #include <linux/proc_fs.h>
+#include <linux/seq_file.h>
 #include <asm/blackfin.h>
 #include <asm/gpio.h>
 #include <asm/portmux.h>
 #include <linux/irq.h>
+#include <asm/irq_handler.h>
 
 #if ANOMALY_05000311 || ANOMALY_05000323
 enum {
@@ -534,7 +536,7 @@
 #if defined(BF533_FAMILY)
 	IRQ_PROG_INTB
 #elif defined(BF537_FAMILY)
-	IRQ_PROG_INTB, IRQ_PORTG_INTB, IRQ_MAC_TX
+	IRQ_PF_INTB_WATCH, IRQ_PORTG_INTB, IRQ_PH_INTB_MAC_TX
 #elif defined(BF538_FAMILY)
 	IRQ_PORTF_INTB
 #elif defined(CONFIG_BF52x) || defined(CONFIG_BF51x)
@@ -1203,35 +1205,43 @@
 }
 
 #if defined(CONFIG_PROC_FS)
-static int gpio_proc_read(char *buf, char **start, off_t offset,
-			  int len, int *unused_i, void *unused_v)
+static int gpio_proc_show(struct seq_file *m, void *v)
 {
-	int c, irq, gpio, outlen = 0;
+	int c, irq, gpio;
 
 	for (c = 0; c < MAX_RESOURCES; c++) {
 		irq = is_reserved(gpio_irq, c, 1);
 		gpio = is_reserved(gpio, c, 1);
 		if (!check_gpio(c) && (gpio || irq))
-			len = sprintf(buf, "GPIO_%d: \t%s%s \t\tGPIO %s\n", c,
+			seq_printf(m, "GPIO_%d: \t%s%s \t\tGPIO %s\n", c,
 				 get_label(c), (gpio && irq) ? " *" : "",
 				 get_gpio_dir(c) ? "OUTPUT" : "INPUT");
 		else if (is_reserved(peri, c, 1))
-			len = sprintf(buf, "GPIO_%d: \t%s \t\tPeripheral\n", c, get_label(c));
+			seq_printf(m, "GPIO_%d: \t%s \t\tPeripheral\n", c, get_label(c));
 		else
 			continue;
-		buf += len;
-		outlen += len;
 	}
-	return outlen;
+
+	return 0;
 }
 
+static int gpio_proc_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, gpio_proc_show, NULL);
+}
+
+static const struct file_operations gpio_proc_ops = {
+	.open		= gpio_proc_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
 static __init int gpio_register_proc(void)
 {
 	struct proc_dir_entry *proc_gpio;
 
-	proc_gpio = create_proc_entry("gpio", S_IRUGO, NULL);
-	if (proc_gpio)
-		proc_gpio->read_proc = gpio_proc_read;
+	proc_gpio = proc_create("gpio", S_IRUGO, NULL, &gpio_proc_ops);
 	return proc_gpio != NULL;
 }
 __initcall(gpio_register_proc);
diff -druN linux-2.6.39-libre/arch/blackfin/kernel/bfin_ksyms.c linux-3.0-rc7-libre/arch/blackfin/kernel/bfin_ksyms.c
--- linux-2.6.39-libre/arch/blackfin/kernel/bfin_ksyms.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/blackfin/kernel/bfin_ksyms.c	2011-07-11 19:51:52.000000000 -0400
@@ -11,6 +11,7 @@
 
 #include <asm/cacheflush.h>
 #include <asm/io.h>
+#include <asm/irq_handler.h>
 
 /* Allow people to have their own Blackfin exception handler in a module */
 EXPORT_SYMBOL(bfin_return_from_exception);
diff -druN linux-2.6.39-libre/arch/blackfin/kernel/debug-mmrs.c linux-3.0-rc7-libre/arch/blackfin/kernel/debug-mmrs.c
--- linux-2.6.39-libre/arch/blackfin/kernel/debug-mmrs.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/blackfin/kernel/debug-mmrs.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,1860 @@
+/*
+ * debugfs interface to core/system MMRs
+ *
+ * Copyright 2007-2011 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2 or later
+ */
+
+#include <linux/debugfs.h>
+#include <linux/fs.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+
+#include <asm/blackfin.h>
+#include <asm/gpio.h>
+#include <asm/gptimers.h>
+#include <asm/bfin_can.h>
+#include <asm/bfin_dma.h>
+#include <asm/bfin_ppi.h>
+#include <asm/bfin_serial.h>
+#include <asm/bfin5xx_spi.h>
+#include <asm/bfin_twi.h>
+
+/* Common code defines PORT_MUX on us, so redirect the MMR back locally */
+#ifdef BFIN_PORT_MUX
+#undef PORT_MUX
+#define PORT_MUX BFIN_PORT_MUX
+#endif
+
+#define _d(name, bits, addr, perms) debugfs_create_x##bits(name, perms, parent, (u##bits *)addr)
+#define d(name, bits, addr)         _d(name, bits, addr, S_IRUSR|S_IWUSR)
+#define d_RO(name, bits, addr)      _d(name, bits, addr, S_IRUSR)
+#define d_WO(name, bits, addr)      _d(name, bits, addr, S_IWUSR)
+
+#define D_RO(name, bits) d_RO(#name, bits, name)
+#define D_WO(name, bits) d_WO(#name, bits, name)
+#define D32(name)        d(#name, 32, name)
+#define D16(name)        d(#name, 16, name)
+
+#define REGS_OFF(peri, mmr) offsetof(struct bfin_##peri##_regs, mmr)
+#define __REGS(peri, sname, rname) \
+	do { \
+		struct bfin_##peri##_regs r; \
+		void *addr = (void *)(base + REGS_OFF(peri, rname)); \
+		strcpy(_buf, sname); \
+		if (sizeof(r.rname) == 2) \
+			debugfs_create_x16(buf, S_IRUSR|S_IWUSR, parent, addr); \
+		else \
+			debugfs_create_x32(buf, S_IRUSR|S_IWUSR, parent, addr); \
+	} while (0)
+#define REGS_STR_PFX(buf, pfx, num) \
+	({ \
+		buf + (num >= 0 ? \
+			sprintf(buf, #pfx "%i_", num) : \
+			sprintf(buf, #pfx "_")); \
+	})
+#define REGS_STR_PFX_C(buf, pfx, num) \
+	({ \
+		buf + (num >= 0 ? \
+			sprintf(buf, #pfx "%c_", 'A' + num) : \
+			sprintf(buf, #pfx "_")); \
+	})
+
+/*
+ * Core registers (not memory mapped)
+ */
+extern u32 last_seqstat;
+
+static int debug_cclk_get(void *data, u64 *val)
+{
+	*val = get_cclk();
+	return 0;
+}
+DEFINE_SIMPLE_ATTRIBUTE(fops_debug_cclk, debug_cclk_get, NULL, "0x%08llx\n");
+
+static int debug_sclk_get(void *data, u64 *val)
+{
+	*val = get_sclk();
+	return 0;
+}
+DEFINE_SIMPLE_ATTRIBUTE(fops_debug_sclk, debug_sclk_get, NULL, "0x%08llx\n");
+
+#define DEFINE_SYSREG(sr, pre, post) \
+static int sysreg_##sr##_get(void *data, u64 *val) \
+{ \
+	unsigned long tmp; \
+	pre; \
+	__asm__ __volatile__("%0 = " #sr ";" : "=d"(tmp)); \
+	*val = tmp; \
+	return 0; \
+} \
+static int sysreg_##sr##_set(void *data, u64 val) \
+{ \
+	unsigned long tmp = val; \
+	__asm__ __volatile__(#sr " = %0;" : : "d"(tmp)); \
+	post; \
+	return 0; \
+} \
+DEFINE_SIMPLE_ATTRIBUTE(fops_sysreg_##sr, sysreg_##sr##_get, sysreg_##sr##_set, "0x%08llx\n")
+
+DEFINE_SYSREG(cycles, , );
+DEFINE_SYSREG(cycles2, __asm__ __volatile__("%0 = cycles;" : "=d"(tmp)), );
+DEFINE_SYSREG(emudat, , );
+DEFINE_SYSREG(seqstat, , );
+DEFINE_SYSREG(syscfg, , CSYNC());
+#define D_SYSREG(sr) debugfs_create_file(#sr, S_IRUSR|S_IWUSR, parent, NULL, &fops_sysreg_##sr)
+
+/*
+ * CAN
+ */
+#define CAN_OFF(mmr)  REGS_OFF(can, mmr)
+#define __CAN(uname, lname) __REGS(can, #uname, lname)
+static void __init __maybe_unused
+bfin_debug_mmrs_can(struct dentry *parent, unsigned long base, int num)
+{
+	static struct dentry *am, *mb;
+	int i, j;
+	char buf[32], *_buf = REGS_STR_PFX(buf, CAN, num);
+
+	if (!am) {
+		am = debugfs_create_dir("am", parent);
+		mb = debugfs_create_dir("mb", parent);
+	}
+
+	__CAN(MC1, mc1);
+	__CAN(MD1, md1);
+	__CAN(TRS1, trs1);
+	__CAN(TRR1, trr1);
+	__CAN(TA1, ta1);
+	__CAN(AA1, aa1);
+	__CAN(RMP1, rmp1);
+	__CAN(RML1, rml1);
+	__CAN(MBTIF1, mbtif1);
+	__CAN(MBRIF1, mbrif1);
+	__CAN(MBIM1, mbim1);
+	__CAN(RFH1, rfh1);
+	__CAN(OPSS1, opss1);
+
+	__CAN(MC2, mc2);
+	__CAN(MD2, md2);
+	__CAN(TRS2, trs2);
+	__CAN(TRR2, trr2);
+	__CAN(TA2, ta2);
+	__CAN(AA2, aa2);
+	__CAN(RMP2, rmp2);
+	__CAN(RML2, rml2);
+	__CAN(MBTIF2, mbtif2);
+	__CAN(MBRIF2, mbrif2);
+	__CAN(MBIM2, mbim2);
+	__CAN(RFH2, rfh2);
+	__CAN(OPSS2, opss2);
+
+	__CAN(CLOCK, clock);
+	__CAN(TIMING, timing);
+	__CAN(DEBUG, debug);
+	__CAN(STATUS, status);
+	__CAN(CEC, cec);
+	__CAN(GIS, gis);
+	__CAN(GIM, gim);
+	__CAN(GIF, gif);
+	__CAN(CONTROL, control);
+	__CAN(INTR, intr);
+	__CAN(VERSION, version);
+	__CAN(MBTD, mbtd);
+	__CAN(EWR, ewr);
+	__CAN(ESR, esr);
+	/*__CAN(UCREG, ucreg); no longer exists */
+	__CAN(UCCNT, uccnt);
+	__CAN(UCRC, ucrc);
+	__CAN(UCCNF, uccnf);
+	__CAN(VERSION2, version2);
+
+	for (i = 0; i < 32; ++i) {
+		sprintf(_buf, "AM%02iL", i);
+		debugfs_create_x16(buf, S_IRUSR|S_IWUSR, am,
+			(u16 *)(base + CAN_OFF(msk[i].aml)));
+		sprintf(_buf, "AM%02iH", i);
+		debugfs_create_x16(buf, S_IRUSR|S_IWUSR, am,
+			(u16 *)(base + CAN_OFF(msk[i].amh)));
+
+		for (j = 0; j < 3; ++j) {
+			sprintf(_buf, "MB%02i_DATA%i", i, j);
+			debugfs_create_x16(buf, S_IRUSR|S_IWUSR, mb,
+				(u16 *)(base + CAN_OFF(chl[i].data[j*2])));
+		}
+		sprintf(_buf, "MB%02i_LENGTH", i);
+		debugfs_create_x16(buf, S_IRUSR|S_IWUSR, mb,
+			(u16 *)(base + CAN_OFF(chl[i].dlc)));
+		sprintf(_buf, "MB%02i_TIMESTAMP", i);
+		debugfs_create_x16(buf, S_IRUSR|S_IWUSR, mb,
+			(u16 *)(base + CAN_OFF(chl[i].tsv)));
+		sprintf(_buf, "MB%02i_ID0", i);
+		debugfs_create_x16(buf, S_IRUSR|S_IWUSR, mb,
+			(u16 *)(base + CAN_OFF(chl[i].id0)));
+		sprintf(_buf, "MB%02i_ID1", i);
+		debugfs_create_x16(buf, S_IRUSR|S_IWUSR, mb,
+			(u16 *)(base + CAN_OFF(chl[i].id1)));
+	}
+}
+#define CAN(num) bfin_debug_mmrs_can(parent, CAN##num##_MC1, num)
+
+/*
+ * DMA
+ */
+#define __DMA(uname, lname) __REGS(dma, #uname, lname)
+static void __init __maybe_unused
+bfin_debug_mmrs_dma(struct dentry *parent, unsigned long base, int num, char mdma, const char *pfx)
+{
+	char buf[32], *_buf;
+
+	if (mdma)
+		_buf = buf + sprintf(buf, "%s_%c%i_", pfx, mdma, num);
+	else
+		_buf = buf + sprintf(buf, "%s%i_", pfx, num);
+
+	__DMA(NEXT_DESC_PTR, next_desc_ptr);
+	__DMA(START_ADDR, start_addr);
+	__DMA(CONFIG, config);
+	__DMA(X_COUNT, x_count);
+	__DMA(X_MODIFY, x_modify);
+	__DMA(Y_COUNT, y_count);
+	__DMA(Y_MODIFY, y_modify);
+	__DMA(CURR_DESC_PTR, curr_desc_ptr);
+	__DMA(CURR_ADDR, curr_addr);
+	__DMA(IRQ_STATUS, irq_status);
+	__DMA(PERIPHERAL_MAP, peripheral_map);
+	__DMA(CURR_X_COUNT, curr_x_count);
+	__DMA(CURR_Y_COUNT, curr_y_count);
+}
+#define _DMA(num, base, mdma, pfx) bfin_debug_mmrs_dma(parent, base, num, mdma, pfx "DMA")
+#define DMA(num)  _DMA(num, DMA##num##_NEXT_DESC_PTR, 0, "")
+#define _MDMA(num, x) \
+	do { \
+		_DMA(num, x##DMA_D##num##_NEXT_DESC_PTR, 'D', #x); \
+		_DMA(num, x##DMA_S##num##_NEXT_DESC_PTR, 'S', #x); \
+	} while (0)
+#define MDMA(num) _MDMA(num, M)
+#define IMDMA(num) _MDMA(num, IM)
+
+/*
+ * EPPI
+ */
+#define __EPPI(uname, lname) __REGS(eppi, #uname, lname)
+static void __init __maybe_unused
+bfin_debug_mmrs_eppi(struct dentry *parent, unsigned long base, int num)
+{
+	char buf[32], *_buf = REGS_STR_PFX(buf, EPPI, num);
+	__EPPI(STATUS, status);
+	__EPPI(HCOUNT, hcount);
+	__EPPI(HDELAY, hdelay);
+	__EPPI(VCOUNT, vcount);
+	__EPPI(VDELAY, vdelay);
+	__EPPI(FRAME, frame);
+	__EPPI(LINE, line);
+	__EPPI(CLKDIV, clkdiv);
+	__EPPI(CONTROL, control);
+	__EPPI(FS1W_HBL, fs1w_hbl);
+	__EPPI(FS1P_AVPL, fs1p_avpl);
+	__EPPI(FS2W_LVB, fs2w_lvb);
+	__EPPI(FS2P_LAVF, fs2p_lavf);
+	__EPPI(CLIP, clip);
+}
+#define EPPI(num) bfin_debug_mmrs_eppi(parent, EPPI##num##_STATUS, num)
+
+/*
+ * General Purpose Timers
+ */
+#define __GPTIMER(uname, lname) __REGS(gptimer, #uname, lname)
+static void __init __maybe_unused
+bfin_debug_mmrs_gptimer(struct dentry *parent, unsigned long base, int num)
+{
+	char buf[32], *_buf = REGS_STR_PFX(buf, TIMER, num);
+	__GPTIMER(CONFIG, config);
+	__GPTIMER(COUNTER, counter);
+	__GPTIMER(PERIOD, period);
+	__GPTIMER(WIDTH, width);
+}
+#define GPTIMER(num) bfin_debug_mmrs_gptimer(parent, TIMER##num##_CONFIG, num)
+
+/*
+ * Handshake MDMA
+ */
+#define __HMDMA(uname, lname) __REGS(hmdma, #uname, lname)
+static void __init __maybe_unused
+bfin_debug_mmrs_hmdma(struct dentry *parent, unsigned long base, int num)
+{
+	char buf[32], *_buf = REGS_STR_PFX(buf, HMDMA, num);
+	__HMDMA(CONTROL, control);
+	__HMDMA(ECINIT, ecinit);
+	__HMDMA(BCINIT, bcinit);
+	__HMDMA(ECURGENT, ecurgent);
+	__HMDMA(ECOVERFLOW, ecoverflow);
+	__HMDMA(ECOUNT, ecount);
+	__HMDMA(BCOUNT, bcount);
+}
+#define HMDMA(num) bfin_debug_mmrs_hmdma(parent, HMDMA##num##_CONTROL, num)
+
+/*
+ * Port/GPIO
+ */
+#define bfin_gpio_regs gpio_port_t
+#define __PORT(uname, lname) __REGS(gpio, #uname, lname)
+static void __init __maybe_unused
+bfin_debug_mmrs_port(struct dentry *parent, unsigned long base, int num)
+{
+	char buf[32], *_buf;
+#ifdef __ADSPBF54x__
+	_buf = REGS_STR_PFX_C(buf, PORT, num);
+	__PORT(FER, port_fer);
+	__PORT(SET, data_set);
+	__PORT(CLEAR, data_clear);
+	__PORT(DIR_SET, dir_set);
+	__PORT(DIR_CLEAR, dir_clear);
+	__PORT(INEN, inen);
+	__PORT(MUX, port_mux);
+#else
+	_buf = buf + sprintf(buf, "PORT%cIO_", num);
+	__PORT(CLEAR, data_clear);
+	__PORT(SET, data_set);
+	__PORT(TOGGLE, toggle);
+	__PORT(MASKA, maska);
+	__PORT(MASKA_CLEAR, maska_clear);
+	__PORT(MASKA_SET, maska_set);
+	__PORT(MASKA_TOGGLE, maska_toggle);
+	__PORT(MASKB, maskb);
+	__PORT(MASKB_CLEAR, maskb_clear);
+	__PORT(MASKB_SET, maskb_set);
+	__PORT(MASKB_TOGGLE, maskb_toggle);
+	__PORT(DIR, dir);
+	__PORT(POLAR, polar);
+	__PORT(EDGE, edge);
+	__PORT(BOTH, both);
+	__PORT(INEN, inen);
+#endif
+	_buf[-1] = '\0';
+	d(buf, 16, base + REGS_OFF(gpio, data));
+}
+#define PORT(base, num) bfin_debug_mmrs_port(parent, base, num)
+
+/*
+ * PPI
+ */
+#define __PPI(uname, lname) __REGS(ppi, #uname, lname)
+static void __init __maybe_unused
+bfin_debug_mmrs_ppi(struct dentry *parent, unsigned long base, int num)
+{
+	char buf[32], *_buf = REGS_STR_PFX(buf, PPI, num);
+	__PPI(CONTROL, control);
+	__PPI(STATUS, status);
+	__PPI(COUNT, count);
+	__PPI(DELAY, delay);
+	__PPI(FRAME, frame);
+}
+#define PPI(num) bfin_debug_mmrs_ppi(parent, PPI##num##_CONTROL, num)
+
+/*
+ * SPI
+ */
+#define __SPI(uname, lname) __REGS(spi, #uname, lname)
+static void __init __maybe_unused
+bfin_debug_mmrs_spi(struct dentry *parent, unsigned long base, int num)
+{
+	char buf[32], *_buf = REGS_STR_PFX(buf, SPI, num);
+	__SPI(CTL, ctl);
+	__SPI(FLG, flg);
+	__SPI(STAT, stat);
+	__SPI(TDBR, tdbr);
+	__SPI(RDBR, rdbr);
+	__SPI(BAUD, baud);
+	__SPI(SHADOW, shadow);
+}
+#define SPI(num) bfin_debug_mmrs_spi(parent, SPI##num##_REGBASE, num)
+
+/*
+ * SPORT
+ */
+static inline int sport_width(void *mmr)
+{
+	unsigned long lmmr = (unsigned long)mmr;
+	if ((lmmr & 0xff) == 0x10)
+		/* SPORT#_TX has 0x10 offset -> SPORT#_TCR2 has 0x04 offset */
+		lmmr -= 0xc;
+	else
+		/* SPORT#_RX has 0x18 offset -> SPORT#_RCR2 has 0x24 offset */
+		lmmr += 0xc;
+	/* extract SLEN field from control register 2 and add 1 */
+	return (bfin_read16(lmmr) & 0x1f) + 1;
+}
+static int sport_set(void *mmr, u64 val)
+{
+	unsigned long flags;
+	local_irq_save(flags);
+	if (sport_width(mmr) <= 16)
+		bfin_write16(mmr, val);
+	else
+		bfin_write32(mmr, val);
+	local_irq_restore(flags);
+	return 0;
+}
+static int sport_get(void *mmr, u64 *val)
+{
+	unsigned long flags;
+	local_irq_save(flags);
+	if (sport_width(mmr) <= 16)
+		*val = bfin_read16(mmr);
+	else
+		*val = bfin_read32(mmr);
+	local_irq_restore(flags);
+	return 0;
+}
+DEFINE_SIMPLE_ATTRIBUTE(fops_sport, sport_get, sport_set, "0x%08llx\n");
+/*DEFINE_SIMPLE_ATTRIBUTE(fops_sport_ro, sport_get, NULL, "0x%08llx\n");*/
+DEFINE_SIMPLE_ATTRIBUTE(fops_sport_wo, NULL, sport_set, "0x%08llx\n");
+#define SPORT_OFF(mmr) (SPORT0_##mmr - SPORT0_TCR1)
+#define _D_SPORT(name, perms, fops) \
+	do { \
+		strcpy(_buf, #name); \
+		debugfs_create_file(buf, perms, parent, (void *)(base + SPORT_OFF(name)), fops); \
+	} while (0)
+#define __SPORT_RW(name) _D_SPORT(name, S_IRUSR|S_IWUSR, &fops_sport)
+#define __SPORT_RO(name) _D_SPORT(name, S_IRUSR, &fops_sport_ro)
+#define __SPORT_WO(name) _D_SPORT(name, S_IWUSR, &fops_sport_wo)
+#define __SPORT(name, bits) \
+	do { \
+		strcpy(_buf, #name); \
+		debugfs_create_x##bits(buf, S_IRUSR|S_IWUSR, parent, (u##bits *)(base + SPORT_OFF(name))); \
+	} while (0)
+static void __init __maybe_unused
+bfin_debug_mmrs_sport(struct dentry *parent, unsigned long base, int num)
+{
+	char buf[32], *_buf = REGS_STR_PFX(buf, SPORT, num);
+	__SPORT(CHNL, 16);
+	__SPORT(MCMC1, 16);
+	__SPORT(MCMC2, 16);
+	__SPORT(MRCS0, 32);
+	__SPORT(MRCS1, 32);
+	__SPORT(MRCS2, 32);
+	__SPORT(MRCS3, 32);
+	__SPORT(MTCS0, 32);
+	__SPORT(MTCS1, 32);
+	__SPORT(MTCS2, 32);
+	__SPORT(MTCS3, 32);
+	__SPORT(RCLKDIV, 16);
+	__SPORT(RCR1, 16);
+	__SPORT(RCR2, 16);
+	__SPORT(RFSDIV, 16);
+	__SPORT_RW(RX);
+	__SPORT(STAT, 16);
+	__SPORT(TCLKDIV, 16);
+	__SPORT(TCR1, 16);
+	__SPORT(TCR2, 16);
+	__SPORT(TFSDIV, 16);
+	__SPORT_WO(TX);
+}
+#define SPORT(num) bfin_debug_mmrs_sport(parent, SPORT##num##_TCR1, num)
+
+/*
+ * TWI
+ */
+#define __TWI(uname, lname) __REGS(twi, #uname, lname)
+static void __init __maybe_unused
+bfin_debug_mmrs_twi(struct dentry *parent, unsigned long base, int num)
+{
+	char buf[32], *_buf = REGS_STR_PFX(buf, TWI, num);
+	__TWI(CLKDIV, clkdiv);
+	__TWI(CONTROL, control);
+	__TWI(SLAVE_CTL, slave_ctl);
+	__TWI(SLAVE_STAT, slave_stat);
+	__TWI(SLAVE_ADDR, slave_addr);
+	__TWI(MASTER_CTL, master_ctl);
+	__TWI(MASTER_STAT, master_stat);
+	__TWI(MASTER_ADDR, master_addr);
+	__TWI(INT_STAT, int_stat);
+	__TWI(INT_MASK, int_mask);
+	__TWI(FIFO_CTL, fifo_ctl);
+	__TWI(FIFO_STAT, fifo_stat);
+	__TWI(XMT_DATA8, xmt_data8);
+	__TWI(XMT_DATA16, xmt_data16);
+	__TWI(RCV_DATA8, rcv_data8);
+	__TWI(RCV_DATA16, rcv_data16);
+}
+#define TWI(num) bfin_debug_mmrs_twi(parent, TWI##num##_CLKDIV, num)
+
+/*
+ * UART
+ */
+#define __UART(uname, lname) __REGS(uart, #uname, lname)
+static void __init __maybe_unused
+bfin_debug_mmrs_uart(struct dentry *parent, unsigned long base, int num)
+{
+	char buf[32], *_buf = REGS_STR_PFX(buf, UART, num);
+#ifdef BFIN_UART_BF54X_STYLE
+	__UART(DLL, dll);
+	__UART(DLH, dlh);
+	__UART(GCTL, gctl);
+	__UART(LCR, lcr);
+	__UART(MCR, mcr);
+	__UART(LSR, lsr);
+	__UART(MSR, msr);
+	__UART(SCR, scr);
+	__UART(IER_SET, ier_set);
+	__UART(IER_CLEAR, ier_clear);
+	__UART(THR, thr);
+	__UART(RBR, rbr);
+#else
+	__UART(DLL, dll);
+	__UART(THR, thr);
+	__UART(RBR, rbr);
+	__UART(DLH, dlh);
+	__UART(IER, ier);
+	__UART(IIR, iir);
+	__UART(LCR, lcr);
+	__UART(MCR, mcr);
+	__UART(LSR, lsr);
+	__UART(MSR, msr);
+	__UART(SCR, scr);
+	__UART(GCTL, gctl);
+#endif
+}
+#define UART(num) bfin_debug_mmrs_uart(parent, UART##num##_DLL, num)
+
+/*
+ * The actual debugfs generation
+ */
+static struct dentry *debug_mmrs_dentry;
+
+static int __init bfin_debug_mmrs_init(void)
+{
+	struct dentry *top, *parent;
+
+	pr_info("debug-mmrs: setting up Blackfin MMR debugfs\n");
+
+	top = debugfs_create_dir("blackfin", NULL);
+	if (top == NULL)
+		return -1;
+
+	parent = debugfs_create_dir("core_regs", top);
+	debugfs_create_file("cclk", S_IRUSR, parent, NULL, &fops_debug_cclk);
+	debugfs_create_file("sclk", S_IRUSR, parent, NULL, &fops_debug_sclk);
+	debugfs_create_x32("last_seqstat", S_IRUSR, parent, &last_seqstat);
+	D_SYSREG(cycles);
+	D_SYSREG(cycles2);
+	D_SYSREG(emudat);
+	D_SYSREG(seqstat);
+	D_SYSREG(syscfg);
+
+	/* Core MMRs */
+	parent = debugfs_create_dir("ctimer", top);
+	D32(TCNTL);
+	D32(TCOUNT);
+	D32(TPERIOD);
+	D32(TSCALE);
+
+	parent = debugfs_create_dir("cec", top);
+	D32(EVT0);
+	D32(EVT1);
+	D32(EVT2);
+	D32(EVT3);
+	D32(EVT4);
+	D32(EVT5);
+	D32(EVT6);
+	D32(EVT7);
+	D32(EVT8);
+	D32(EVT9);
+	D32(EVT10);
+	D32(EVT11);
+	D32(EVT12);
+	D32(EVT13);
+	D32(EVT14);
+	D32(EVT15);
+	D32(EVT_OVERRIDE);
+	D32(IMASK);
+	D32(IPEND);
+	D32(ILAT);
+	D32(IPRIO);
+
+	parent = debugfs_create_dir("debug", top);
+	D32(DBGSTAT);
+	D32(DSPID);
+
+	parent = debugfs_create_dir("mmu", top);
+	D32(SRAM_BASE_ADDRESS);
+	D32(DCPLB_ADDR0);
+	D32(DCPLB_ADDR10);
+	D32(DCPLB_ADDR11);
+	D32(DCPLB_ADDR12);
+	D32(DCPLB_ADDR13);
+	D32(DCPLB_ADDR14);
+	D32(DCPLB_ADDR15);
+	D32(DCPLB_ADDR1);
+	D32(DCPLB_ADDR2);
+	D32(DCPLB_ADDR3);
+	D32(DCPLB_ADDR4);
+	D32(DCPLB_ADDR5);
+	D32(DCPLB_ADDR6);
+	D32(DCPLB_ADDR7);
+	D32(DCPLB_ADDR8);
+	D32(DCPLB_ADDR9);
+	D32(DCPLB_DATA0);
+	D32(DCPLB_DATA10);
+	D32(DCPLB_DATA11);
+	D32(DCPLB_DATA12);
+	D32(DCPLB_DATA13);
+	D32(DCPLB_DATA14);
+	D32(DCPLB_DATA15);
+	D32(DCPLB_DATA1);
+	D32(DCPLB_DATA2);
+	D32(DCPLB_DATA3);
+	D32(DCPLB_DATA4);
+	D32(DCPLB_DATA5);
+	D32(DCPLB_DATA6);
+	D32(DCPLB_DATA7);
+	D32(DCPLB_DATA8);
+	D32(DCPLB_DATA9);
+	D32(DCPLB_FAULT_ADDR);
+	D32(DCPLB_STATUS);
+	D32(DMEM_CONTROL);
+	D32(DTEST_COMMAND);
+	D32(DTEST_DATA0);
+	D32(DTEST_DATA1);
+
+	D32(ICPLB_ADDR0);
+	D32(ICPLB_ADDR1);
+	D32(ICPLB_ADDR2);
+	D32(ICPLB_ADDR3);
+	D32(ICPLB_ADDR4);
+	D32(ICPLB_ADDR5);
+	D32(ICPLB_ADDR6);
+	D32(ICPLB_ADDR7);
+	D32(ICPLB_ADDR8);
+	D32(ICPLB_ADDR9);
+	D32(ICPLB_ADDR10);
+	D32(ICPLB_ADDR11);
+	D32(ICPLB_ADDR12);
+	D32(ICPLB_ADDR13);
+	D32(ICPLB_ADDR14);
+	D32(ICPLB_ADDR15);
+	D32(ICPLB_DATA0);
+	D32(ICPLB_DATA1);
+	D32(ICPLB_DATA2);
+	D32(ICPLB_DATA3);
+	D32(ICPLB_DATA4);
+	D32(ICPLB_DATA5);
+	D32(ICPLB_DATA6);
+	D32(ICPLB_DATA7);
+	D32(ICPLB_DATA8);
+	D32(ICPLB_DATA9);
+	D32(ICPLB_DATA10);
+	D32(ICPLB_DATA11);
+	D32(ICPLB_DATA12);
+	D32(ICPLB_DATA13);
+	D32(ICPLB_DATA14);
+	D32(ICPLB_DATA15);
+	D32(ICPLB_FAULT_ADDR);
+	D32(ICPLB_STATUS);
+	D32(IMEM_CONTROL);
+	if (!ANOMALY_05000481) {
+		D32(ITEST_COMMAND);
+		D32(ITEST_DATA0);
+		D32(ITEST_DATA1);
+	}
+
+	parent = debugfs_create_dir("perf", top);
+	D32(PFCNTR0);
+	D32(PFCNTR1);
+	D32(PFCTL);
+
+	parent = debugfs_create_dir("trace", top);
+	D32(TBUF);
+	D32(TBUFCTL);
+	D32(TBUFSTAT);
+
+	parent = debugfs_create_dir("watchpoint", top);
+	D32(WPIACTL);
+	D32(WPIA0);
+	D32(WPIA1);
+	D32(WPIA2);
+	D32(WPIA3);
+	D32(WPIA4);
+	D32(WPIA5);
+	D32(WPIACNT0);
+	D32(WPIACNT1);
+	D32(WPIACNT2);
+	D32(WPIACNT3);
+	D32(WPIACNT4);
+	D32(WPIACNT5);
+	D32(WPDACTL);
+	D32(WPDA0);
+	D32(WPDA1);
+	D32(WPDACNT0);
+	D32(WPDACNT1);
+	D32(WPSTAT);
+
+	/* System MMRs */
+#ifdef ATAPI_CONTROL
+	parent = debugfs_create_dir("atapi", top);
+	D16(ATAPI_CONTROL);
+	D16(ATAPI_DEV_ADDR);
+	D16(ATAPI_DEV_RXBUF);
+	D16(ATAPI_DEV_TXBUF);
+	D16(ATAPI_DMA_TFRCNT);
+	D16(ATAPI_INT_MASK);
+	D16(ATAPI_INT_STATUS);
+	D16(ATAPI_LINE_STATUS);
+	D16(ATAPI_MULTI_TIM_0);
+	D16(ATAPI_MULTI_TIM_1);
+	D16(ATAPI_MULTI_TIM_2);
+	D16(ATAPI_PIO_TFRCNT);
+	D16(ATAPI_PIO_TIM_0);
+	D16(ATAPI_PIO_TIM_1);
+	D16(ATAPI_REG_TIM_0);
+	D16(ATAPI_SM_STATE);
+	D16(ATAPI_STATUS);
+	D16(ATAPI_TERMINATE);
+	D16(ATAPI_UDMAOUT_TFRCNT);
+	D16(ATAPI_ULTRA_TIM_0);
+	D16(ATAPI_ULTRA_TIM_1);
+	D16(ATAPI_ULTRA_TIM_2);
+	D16(ATAPI_ULTRA_TIM_3);
+	D16(ATAPI_UMAIN_TFRCNT);
+	D16(ATAPI_XFER_LEN);
+#endif
+
+#if defined(CAN_MC1) || defined(CAN0_MC1) || defined(CAN1_MC1)
+	parent = debugfs_create_dir("can", top);
+# ifdef CAN_MC1
+	bfin_debug_mmrs_can(parent, CAN_MC1, -1);
+# endif
+# ifdef CAN0_MC1
+	CAN(0);
+# endif
+# ifdef CAN1_MC1
+	CAN(1);
+# endif
+#endif
+
+#ifdef CNT_COMMAND
+	parent = debugfs_create_dir("counter", top);
+	D16(CNT_COMMAND);
+	D16(CNT_CONFIG);
+	D32(CNT_COUNTER);
+	D16(CNT_DEBOUNCE);
+	D16(CNT_IMASK);
+	D32(CNT_MAX);
+	D32(CNT_MIN);
+	D16(CNT_STATUS);
+#endif
+
+	parent = debugfs_create_dir("dmac", top);
+#ifdef DMA_TC_CNT
+	D16(DMAC_TC_CNT);
+	D16(DMAC_TC_PER);
+#endif
+#ifdef DMAC0_TC_CNT
+	D16(DMAC0_TC_CNT);
+	D16(DMAC0_TC_PER);
+#endif
+#ifdef DMAC1_TC_CNT
+	D16(DMAC1_TC_CNT);
+	D16(DMAC1_TC_PER);
+#endif
+#ifdef DMAC1_PERIMUX
+	D16(DMAC1_PERIMUX);
+#endif
+
+#ifdef __ADSPBF561__
+	/* XXX: should rewrite the MMR map */
+# define DMA0_NEXT_DESC_PTR DMA2_0_NEXT_DESC_PTR
+# define DMA1_NEXT_DESC_PTR DMA2_1_NEXT_DESC_PTR
+# define DMA2_NEXT_DESC_PTR DMA2_2_NEXT_DESC_PTR
+# define DMA3_NEXT_DESC_PTR DMA2_3_NEXT_DESC_PTR
+# define DMA4_NEXT_DESC_PTR DMA2_4_NEXT_DESC_PTR
+# define DMA5_NEXT_DESC_PTR DMA2_5_NEXT_DESC_PTR
+# define DMA6_NEXT_DESC_PTR DMA2_6_NEXT_DESC_PTR
+# define DMA7_NEXT_DESC_PTR DMA2_7_NEXT_DESC_PTR
+# define DMA8_NEXT_DESC_PTR DMA2_8_NEXT_DESC_PTR
+# define DMA9_NEXT_DESC_PTR DMA2_9_NEXT_DESC_PTR
+# define DMA10_NEXT_DESC_PTR DMA2_10_NEXT_DESC_PTR
+# define DMA11_NEXT_DESC_PTR DMA2_11_NEXT_DESC_PTR
+# define DMA12_NEXT_DESC_PTR DMA1_0_NEXT_DESC_PTR
+# define DMA13_NEXT_DESC_PTR DMA1_1_NEXT_DESC_PTR
+# define DMA14_NEXT_DESC_PTR DMA1_2_NEXT_DESC_PTR
+# define DMA15_NEXT_DESC_PTR DMA1_3_NEXT_DESC_PTR
+# define DMA16_NEXT_DESC_PTR DMA1_4_NEXT_DESC_PTR
+# define DMA17_NEXT_DESC_PTR DMA1_5_NEXT_DESC_PTR
+# define DMA18_NEXT_DESC_PTR DMA1_6_NEXT_DESC_PTR
+# define DMA19_NEXT_DESC_PTR DMA1_7_NEXT_DESC_PTR
+# define DMA20_NEXT_DESC_PTR DMA1_8_NEXT_DESC_PTR
+# define DMA21_NEXT_DESC_PTR DMA1_9_NEXT_DESC_PTR
+# define DMA22_NEXT_DESC_PTR DMA1_10_NEXT_DESC_PTR
+# define DMA23_NEXT_DESC_PTR DMA1_11_NEXT_DESC_PTR
+#endif
+	parent = debugfs_create_dir("dma", top);
+	DMA(0);
+	DMA(1);
+	DMA(1);
+	DMA(2);
+	DMA(3);
+	DMA(4);
+	DMA(5);
+	DMA(6);
+	DMA(7);
+#ifdef DMA8_NEXT_DESC_PTR
+	DMA(8);
+	DMA(9);
+	DMA(10);
+	DMA(11);
+#endif
+#ifdef DMA12_NEXT_DESC_PTR
+	DMA(12);
+	DMA(13);
+	DMA(14);
+	DMA(15);
+	DMA(16);
+	DMA(17);
+	DMA(18);
+	DMA(19);
+#endif
+#ifdef DMA20_NEXT_DESC_PTR
+	DMA(20);
+	DMA(21);
+	DMA(22);
+	DMA(23);
+#endif
+
+	parent = debugfs_create_dir("ebiu_amc", top);
+	D32(EBIU_AMBCTL0);
+	D32(EBIU_AMBCTL1);
+	D16(EBIU_AMGCTL);
+#ifdef EBIU_MBSCTL
+	D16(EBIU_MBSCTL);
+	D32(EBIU_ARBSTAT);
+	D32(EBIU_MODE);
+	D16(EBIU_FCTL);
+#endif
+
+#ifdef EBIU_SDGCTL
+	parent = debugfs_create_dir("ebiu_sdram", top);
+# ifdef __ADSPBF561__
+	D32(EBIU_SDBCTL);
+# else
+	D16(EBIU_SDBCTL);
+# endif
+	D32(EBIU_SDGCTL);
+	D16(EBIU_SDRRC);
+	D16(EBIU_SDSTAT);
+#endif
+
+#ifdef EBIU_DDRACCT
+	parent = debugfs_create_dir("ebiu_ddr", top);
+	D32(EBIU_DDRACCT);
+	D32(EBIU_DDRARCT);
+	D32(EBIU_DDRBRC0);
+	D32(EBIU_DDRBRC1);
+	D32(EBIU_DDRBRC2);
+	D32(EBIU_DDRBRC3);
+	D32(EBIU_DDRBRC4);
+	D32(EBIU_DDRBRC5);
+	D32(EBIU_DDRBRC6);
+	D32(EBIU_DDRBRC7);
+	D32(EBIU_DDRBWC0);
+	D32(EBIU_DDRBWC1);
+	D32(EBIU_DDRBWC2);
+	D32(EBIU_DDRBWC3);
+	D32(EBIU_DDRBWC4);
+	D32(EBIU_DDRBWC5);
+	D32(EBIU_DDRBWC6);
+	D32(EBIU_DDRBWC7);
+	D32(EBIU_DDRCTL0);
+	D32(EBIU_DDRCTL1);
+	D32(EBIU_DDRCTL2);
+	D32(EBIU_DDRCTL3);
+	D32(EBIU_DDRGC0);
+	D32(EBIU_DDRGC1);
+	D32(EBIU_DDRGC2);
+	D32(EBIU_DDRGC3);
+	D32(EBIU_DDRMCCL);
+	D32(EBIU_DDRMCEN);
+	D32(EBIU_DDRQUE);
+	D32(EBIU_DDRTACT);
+	D32(EBIU_ERRADD);
+	D16(EBIU_ERRMST);
+	D16(EBIU_RSTCTL);
+#endif
+
+#ifdef EMAC_ADDRHI
+	parent = debugfs_create_dir("emac", top);
+	D32(EMAC_ADDRHI);
+	D32(EMAC_ADDRLO);
+	D32(EMAC_FLC);
+	D32(EMAC_HASHHI);
+	D32(EMAC_HASHLO);
+	D32(EMAC_MMC_CTL);
+	D32(EMAC_MMC_RIRQE);
+	D32(EMAC_MMC_RIRQS);
+	D32(EMAC_MMC_TIRQE);
+	D32(EMAC_MMC_TIRQS);
+	D32(EMAC_OPMODE);
+	D32(EMAC_RXC_ALIGN);
+	D32(EMAC_RXC_ALLFRM);
+	D32(EMAC_RXC_ALLOCT);
+	D32(EMAC_RXC_BROAD);
+	D32(EMAC_RXC_DMAOVF);
+	D32(EMAC_RXC_EQ64);
+	D32(EMAC_RXC_FCS);
+	D32(EMAC_RXC_GE1024);
+	D32(EMAC_RXC_LNERRI);
+	D32(EMAC_RXC_LNERRO);
+	D32(EMAC_RXC_LONG);
+	D32(EMAC_RXC_LT1024);
+	D32(EMAC_RXC_LT128);
+	D32(EMAC_RXC_LT256);
+	D32(EMAC_RXC_LT512);
+	D32(EMAC_RXC_MACCTL);
+	D32(EMAC_RXC_MULTI);
+	D32(EMAC_RXC_OCTET);
+	D32(EMAC_RXC_OK);
+	D32(EMAC_RXC_OPCODE);
+	D32(EMAC_RXC_PAUSE);
+	D32(EMAC_RXC_SHORT);
+	D32(EMAC_RXC_TYPED);
+	D32(EMAC_RXC_UNICST);
+	D32(EMAC_RX_IRQE);
+	D32(EMAC_RX_STAT);
+	D32(EMAC_RX_STKY);
+	D32(EMAC_STAADD);
+	D32(EMAC_STADAT);
+	D32(EMAC_SYSCTL);
+	D32(EMAC_SYSTAT);
+	D32(EMAC_TXC_1COL);
+	D32(EMAC_TXC_ABORT);
+	D32(EMAC_TXC_ALLFRM);
+	D32(EMAC_TXC_ALLOCT);
+	D32(EMAC_TXC_BROAD);
+	D32(EMAC_TXC_CRSERR);
+	D32(EMAC_TXC_DEFER);
+	D32(EMAC_TXC_DMAUND);
+	D32(EMAC_TXC_EQ64);
+	D32(EMAC_TXC_GE1024);
+	D32(EMAC_TXC_GT1COL);
+	D32(EMAC_TXC_LATECL);
+	D32(EMAC_TXC_LT1024);
+	D32(EMAC_TXC_LT128);
+	D32(EMAC_TXC_LT256);
+	D32(EMAC_TXC_LT512);
+	D32(EMAC_TXC_MACCTL);
+	D32(EMAC_TXC_MULTI);
+	D32(EMAC_TXC_OCTET);
+	D32(EMAC_TXC_OK);
+	D32(EMAC_TXC_UNICST);
+	D32(EMAC_TXC_XS_COL);
+	D32(EMAC_TXC_XS_DFR);
+	D32(EMAC_TX_IRQE);
+	D32(EMAC_TX_STAT);
+	D32(EMAC_TX_STKY);
+	D32(EMAC_VLAN1);
+	D32(EMAC_VLAN2);
+	D32(EMAC_WKUP_CTL);
+	D32(EMAC_WKUP_FFCMD);
+	D32(EMAC_WKUP_FFCRC0);
+	D32(EMAC_WKUP_FFCRC1);
+	D32(EMAC_WKUP_FFMSK0);
+	D32(EMAC_WKUP_FFMSK1);
+	D32(EMAC_WKUP_FFMSK2);
+	D32(EMAC_WKUP_FFMSK3);
+	D32(EMAC_WKUP_FFOFF);
+# ifdef EMAC_PTP_ACCR
+	D32(EMAC_PTP_ACCR);
+	D32(EMAC_PTP_ADDEND);
+	D32(EMAC_PTP_ALARMHI);
+	D32(EMAC_PTP_ALARMLO);
+	D16(EMAC_PTP_CTL);
+	D32(EMAC_PTP_FOFF);
+	D32(EMAC_PTP_FV1);
+	D32(EMAC_PTP_FV2);
+	D32(EMAC_PTP_FV3);
+	D16(EMAC_PTP_ID_OFF);
+	D32(EMAC_PTP_ID_SNAP);
+	D16(EMAC_PTP_IE);
+	D16(EMAC_PTP_ISTAT);
+	D32(EMAC_PTP_OFFSET);
+	D32(EMAC_PTP_PPS_PERIOD);
+	D32(EMAC_PTP_PPS_STARTHI);
+	D32(EMAC_PTP_PPS_STARTLO);
+	D32(EMAC_PTP_RXSNAPHI);
+	D32(EMAC_PTP_RXSNAPLO);
+	D32(EMAC_PTP_TIMEHI);
+	D32(EMAC_PTP_TIMELO);
+	D32(EMAC_PTP_TXSNAPHI);
+	D32(EMAC_PTP_TXSNAPLO);
+# endif
+#endif
+
+#if defined(EPPI0_STATUS) || defined(EPPI1_STATUS) || defined(EPPI2_STATUS)
+	parent = debugfs_create_dir("eppi", top);
+# ifdef EPPI0_STATUS
+	EPPI(0);
+# endif
+# ifdef EPPI1_STATUS
+	EPPI(1);
+# endif
+# ifdef EPPI2_STATUS
+	EPPI(2);
+# endif
+#endif
+
+	parent = debugfs_create_dir("gptimer", top);
+#ifdef TIMER_DISABLE
+	D16(TIMER_DISABLE);
+	D16(TIMER_ENABLE);
+	D32(TIMER_STATUS);
+#endif
+#ifdef TIMER_DISABLE0
+	D16(TIMER_DISABLE0);
+	D16(TIMER_ENABLE0);
+	D32(TIMER_STATUS0);
+#endif
+#ifdef TIMER_DISABLE1
+	D16(TIMER_DISABLE1);
+	D16(TIMER_ENABLE1);
+	D32(TIMER_STATUS1);
+#endif
+	/* XXX: Should convert BF561 MMR names */
+#ifdef TMRS4_DISABLE
+	D16(TMRS4_DISABLE);
+	D16(TMRS4_ENABLE);
+	D32(TMRS4_STATUS);
+	D16(TMRS8_DISABLE);
+	D16(TMRS8_ENABLE);
+	D32(TMRS8_STATUS);
+#endif
+	GPTIMER(0);
+	GPTIMER(1);
+	GPTIMER(2);
+#ifdef TIMER3_CONFIG
+	GPTIMER(3);
+	GPTIMER(4);
+	GPTIMER(5);
+	GPTIMER(6);
+	GPTIMER(7);
+#endif
+#ifdef TIMER8_CONFIG
+	GPTIMER(8);
+	GPTIMER(9);
+	GPTIMER(10);
+#endif
+#ifdef TIMER11_CONFIG
+	GPTIMER(11);
+#endif
+
+#ifdef HMDMA0_CONTROL
+	parent = debugfs_create_dir("hmdma", top);
+	HMDMA(0);
+	HMDMA(1);
+#endif
+
+#ifdef HOST_CONTROL
+	parent = debugfs_create_dir("hostdp", top);
+	D16(HOST_CONTROL);
+	D16(HOST_STATUS);
+	D16(HOST_TIMEOUT);
+#endif
+
+#ifdef IMDMA_S0_CONFIG
+	parent = debugfs_create_dir("imdma", top);
+	IMDMA(0);
+	IMDMA(1);
+#endif
+
+#ifdef KPAD_CTL
+	parent = debugfs_create_dir("keypad", top);
+	D16(KPAD_CTL);
+	D16(KPAD_PRESCALE);
+	D16(KPAD_MSEL);
+	D16(KPAD_ROWCOL);
+	D16(KPAD_STAT);
+	D16(KPAD_SOFTEVAL);
+#endif
+
+	parent = debugfs_create_dir("mdma", top);
+	MDMA(0);
+	MDMA(1);
+#ifdef MDMA_D2_CONFIG
+	MDMA(2);
+	MDMA(3);
+#endif
+
+#ifdef MXVR_CONFIG
+	parent = debugfs_create_dir("mxvr", top);
+	D16(MXVR_CONFIG);
+# ifdef MXVR_PLL_CTL_0
+	D32(MXVR_PLL_CTL_0);
+# endif
+	D32(MXVR_STATE_0);
+	D32(MXVR_STATE_1);
+	D32(MXVR_INT_STAT_0);
+	D32(MXVR_INT_STAT_1);
+	D32(MXVR_INT_EN_0);
+	D32(MXVR_INT_EN_1);
+	D16(MXVR_POSITION);
+	D16(MXVR_MAX_POSITION);
+	D16(MXVR_DELAY);
+	D16(MXVR_MAX_DELAY);
+	D32(MXVR_LADDR);
+	D16(MXVR_GADDR);
+	D32(MXVR_AADDR);
+	D32(MXVR_ALLOC_0);
+	D32(MXVR_ALLOC_1);
+	D32(MXVR_ALLOC_2);
+	D32(MXVR_ALLOC_3);
+	D32(MXVR_ALLOC_4);
+	D32(MXVR_ALLOC_5);
+	D32(MXVR_ALLOC_6);
+	D32(MXVR_ALLOC_7);
+	D32(MXVR_ALLOC_8);
+	D32(MXVR_ALLOC_9);
+	D32(MXVR_ALLOC_10);
+	D32(MXVR_ALLOC_11);
+	D32(MXVR_ALLOC_12);
+	D32(MXVR_ALLOC_13);
+	D32(MXVR_ALLOC_14);
+	D32(MXVR_SYNC_LCHAN_0);
+	D32(MXVR_SYNC_LCHAN_1);
+	D32(MXVR_SYNC_LCHAN_2);
+	D32(MXVR_SYNC_LCHAN_3);
+	D32(MXVR_SYNC_LCHAN_4);
+	D32(MXVR_SYNC_LCHAN_5);
+	D32(MXVR_SYNC_LCHAN_6);
+	D32(MXVR_SYNC_LCHAN_7);
+	D32(MXVR_DMA0_CONFIG);
+	D32(MXVR_DMA0_START_ADDR);
+	D16(MXVR_DMA0_COUNT);
+	D32(MXVR_DMA0_CURR_ADDR);
+	D16(MXVR_DMA0_CURR_COUNT);
+	D32(MXVR_DMA1_CONFIG);
+	D32(MXVR_DMA1_START_ADDR);
+	D16(MXVR_DMA1_COUNT);
+	D32(MXVR_DMA1_CURR_ADDR);
+	D16(MXVR_DMA1_CURR_COUNT);
+	D32(MXVR_DMA2_CONFIG);
+	D32(MXVR_DMA2_START_ADDR);
+	D16(MXVR_DMA2_COUNT);
+	D32(MXVR_DMA2_CURR_ADDR);
+	D16(MXVR_DMA2_CURR_COUNT);
+	D32(MXVR_DMA3_CONFIG);
+	D32(MXVR_DMA3_START_ADDR);
+	D16(MXVR_DMA3_COUNT);
+	D32(MXVR_DMA3_CURR_ADDR);
+	D16(MXVR_DMA3_CURR_COUNT);
+	D32(MXVR_DMA4_CONFIG);
+	D32(MXVR_DMA4_START_ADDR);
+	D16(MXVR_DMA4_COUNT);
+	D32(MXVR_DMA4_CURR_ADDR);
+	D16(MXVR_DMA4_CURR_COUNT);
+	D32(MXVR_DMA5_CONFIG);
+	D32(MXVR_DMA5_START_ADDR);
+	D16(MXVR_DMA5_COUNT);
+	D32(MXVR_DMA5_CURR_ADDR);
+	D16(MXVR_DMA5_CURR_COUNT);
+	D32(MXVR_DMA6_CONFIG);
+	D32(MXVR_DMA6_START_ADDR);
+	D16(MXVR_DMA6_COUNT);
+	D32(MXVR_DMA6_CURR_ADDR);
+	D16(MXVR_DMA6_CURR_COUNT);
+	D32(MXVR_DMA7_CONFIG);
+	D32(MXVR_DMA7_START_ADDR);
+	D16(MXVR_DMA7_COUNT);
+	D32(MXVR_DMA7_CURR_ADDR);
+	D16(MXVR_DMA7_CURR_COUNT);
+	D16(MXVR_AP_CTL);
+	D32(MXVR_APRB_START_ADDR);
+	D32(MXVR_APRB_CURR_ADDR);
+	D32(MXVR_APTB_START_ADDR);
+	D32(MXVR_APTB_CURR_ADDR);
+	D32(MXVR_CM_CTL);
+	D32(MXVR_CMRB_START_ADDR);
+	D32(MXVR_CMRB_CURR_ADDR);
+	D32(MXVR_CMTB_START_ADDR);
+	D32(MXVR_CMTB_CURR_ADDR);
+	D32(MXVR_RRDB_START_ADDR);
+	D32(MXVR_RRDB_CURR_ADDR);
+	D32(MXVR_PAT_DATA_0);
+	D32(MXVR_PAT_EN_0);
+	D32(MXVR_PAT_DATA_1);
+	D32(MXVR_PAT_EN_1);
+	D16(MXVR_FRAME_CNT_0);
+	D16(MXVR_FRAME_CNT_1);
+	D32(MXVR_ROUTING_0);
+	D32(MXVR_ROUTING_1);
+	D32(MXVR_ROUTING_2);
+	D32(MXVR_ROUTING_3);
+	D32(MXVR_ROUTING_4);
+	D32(MXVR_ROUTING_5);
+	D32(MXVR_ROUTING_6);
+	D32(MXVR_ROUTING_7);
+	D32(MXVR_ROUTING_8);
+	D32(MXVR_ROUTING_9);
+	D32(MXVR_ROUTING_10);
+	D32(MXVR_ROUTING_11);
+	D32(MXVR_ROUTING_12);
+	D32(MXVR_ROUTING_13);
+	D32(MXVR_ROUTING_14);
+# ifdef MXVR_PLL_CTL_1
+	D32(MXVR_PLL_CTL_1);
+# endif
+	D16(MXVR_BLOCK_CNT);
+# ifdef MXVR_CLK_CTL
+	D32(MXVR_CLK_CTL);
+# endif
+# ifdef MXVR_CDRPLL_CTL
+	D32(MXVR_CDRPLL_CTL);
+# endif
+# ifdef MXVR_FMPLL_CTL
+	D32(MXVR_FMPLL_CTL);
+# endif
+# ifdef MXVR_PIN_CTL
+	D16(MXVR_PIN_CTL);
+# endif
+# ifdef MXVR_SCLK_CNT
+	D16(MXVR_SCLK_CNT);
+# endif
+#endif
+
+#ifdef NFC_ADDR
+	parent = debugfs_create_dir("nfc", top);
+	D_WO(NFC_ADDR, 16);
+	D_WO(NFC_CMD, 16);
+	D_RO(NFC_COUNT, 16);
+	D16(NFC_CTL);
+	D_WO(NFC_DATA_RD, 16);
+	D_WO(NFC_DATA_WR, 16);
+	D_RO(NFC_ECC0, 16);
+	D_RO(NFC_ECC1, 16);
+	D_RO(NFC_ECC2, 16);
+	D_RO(NFC_ECC3, 16);
+	D16(NFC_IRQMASK);
+	D16(NFC_IRQSTAT);
+	D_WO(NFC_PGCTL, 16);
+	D_RO(NFC_READ, 16);
+	D16(NFC_RST);
+	D_RO(NFC_STAT, 16);
+#endif
+
+#ifdef OTP_CONTROL
+	parent = debugfs_create_dir("otp", top);
+	D16(OTP_CONTROL);
+	D16(OTP_BEN);
+	D16(OTP_STATUS);
+	D32(OTP_TIMING);
+	D32(OTP_DATA0);
+	D32(OTP_DATA1);
+	D32(OTP_DATA2);
+	D32(OTP_DATA3);
+#endif
+
+#ifdef PIXC_CTL
+	parent = debugfs_create_dir("pixc", top);
+	D16(PIXC_CTL);
+	D16(PIXC_PPL);
+	D16(PIXC_LPF);
+	D16(PIXC_AHSTART);
+	D16(PIXC_AHEND);
+	D16(PIXC_AVSTART);
+	D16(PIXC_AVEND);
+	D16(PIXC_ATRANSP);
+	D16(PIXC_BHSTART);
+	D16(PIXC_BHEND);
+	D16(PIXC_BVSTART);
+	D16(PIXC_BVEND);
+	D16(PIXC_BTRANSP);
+	D16(PIXC_INTRSTAT);
+	D32(PIXC_RYCON);
+	D32(PIXC_GUCON);
+	D32(PIXC_BVCON);
+	D32(PIXC_CCBIAS);
+	D32(PIXC_TC);
+#endif
+
+	parent = debugfs_create_dir("pll", top);
+	D16(PLL_CTL);
+	D16(PLL_DIV);
+	D16(PLL_LOCKCNT);
+	D16(PLL_STAT);
+	D16(VR_CTL);
+	D32(CHIPID);	/* it's part of this hardware block */
+
+#if defined(PPI_CONTROL) || defined(PPI0_CONTROL) || defined(PPI1_CONTROL)
+	parent = debugfs_create_dir("ppi", top);
+# ifdef PPI_CONTROL
+	bfin_debug_mmrs_ppi(parent, PPI_CONTROL, -1);
+# endif
+# ifdef PPI0_CONTROL
+	PPI(0);
+# endif
+# ifdef PPI1_CONTROL
+	PPI(1);
+# endif
+#endif
+
+#ifdef PWM_CTRL
+	parent = debugfs_create_dir("pwm", top);
+	D16(PWM_CTRL);
+	D16(PWM_STAT);
+	D16(PWM_TM);
+	D16(PWM_DT);
+	D16(PWM_GATE);
+	D16(PWM_CHA);
+	D16(PWM_CHB);
+	D16(PWM_CHC);
+	D16(PWM_SEG);
+	D16(PWM_SYNCWT);
+	D16(PWM_CHAL);
+	D16(PWM_CHBL);
+	D16(PWM_CHCL);
+	D16(PWM_LSI);
+	D16(PWM_STAT2);
+#endif
+
+#ifdef RSI_CONFIG
+	parent = debugfs_create_dir("rsi", top);
+	D32(RSI_ARGUMENT);
+	D16(RSI_CEATA_CONTROL);
+	D16(RSI_CLK_CONTROL);
+	D16(RSI_COMMAND);
+	D16(RSI_CONFIG);
+	D16(RSI_DATA_CNT);
+	D16(RSI_DATA_CONTROL);
+	D16(RSI_DATA_LGTH);
+	D32(RSI_DATA_TIMER);
+	D16(RSI_EMASK);
+	D16(RSI_ESTAT);
+	D32(RSI_FIFO);
+	D16(RSI_FIFO_CNT);
+	D32(RSI_MASK0);
+	D32(RSI_MASK1);
+	D16(RSI_PID0);
+	D16(RSI_PID1);
+	D16(RSI_PID2);
+	D16(RSI_PID3);
+	D16(RSI_PID4);
+	D16(RSI_PID5);
+	D16(RSI_PID6);
+	D16(RSI_PID7);
+	D16(RSI_PWR_CONTROL);
+	D16(RSI_RD_WAIT_EN);
+	D32(RSI_RESPONSE0);
+	D32(RSI_RESPONSE1);
+	D32(RSI_RESPONSE2);
+	D32(RSI_RESPONSE3);
+	D16(RSI_RESP_CMD);
+	D32(RSI_STATUS);
+	D_WO(RSI_STATUSCL, 16);
+#endif
+
+#ifdef RTC_ALARM
+	parent = debugfs_create_dir("rtc", top);
+	D32(RTC_ALARM);
+	D16(RTC_ICTL);
+	D16(RTC_ISTAT);
+	D16(RTC_PREN);
+	D32(RTC_STAT);
+	D16(RTC_SWCNT);
+#endif
+
+#ifdef SDH_CFG
+	parent = debugfs_create_dir("sdh", top);
+	D32(SDH_ARGUMENT);
+	D16(SDH_CFG);
+	D16(SDH_CLK_CTL);
+	D16(SDH_COMMAND);
+	D_RO(SDH_DATA_CNT, 16);
+	D16(SDH_DATA_CTL);
+	D16(SDH_DATA_LGTH);
+	D32(SDH_DATA_TIMER);
+	D16(SDH_E_MASK);
+	D16(SDH_E_STATUS);
+	D32(SDH_FIFO);
+	D_RO(SDH_FIFO_CNT, 16);
+	D32(SDH_MASK0);
+	D32(SDH_MASK1);
+	D_RO(SDH_PID0, 16);
+	D_RO(SDH_PID1, 16);
+	D_RO(SDH_PID2, 16);
+	D_RO(SDH_PID3, 16);
+	D_RO(SDH_PID4, 16);
+	D_RO(SDH_PID5, 16);
+	D_RO(SDH_PID6, 16);
+	D_RO(SDH_PID7, 16);
+	D16(SDH_PWR_CTL);
+	D16(SDH_RD_WAIT_EN);
+	D_RO(SDH_RESPONSE0, 32);
+	D_RO(SDH_RESPONSE1, 32);
+	D_RO(SDH_RESPONSE2, 32);
+	D_RO(SDH_RESPONSE3, 32);
+	D_RO(SDH_RESP_CMD, 16);
+	D_RO(SDH_STATUS, 32);
+	D_WO(SDH_STATUS_CLR, 16);
+#endif
+
+#ifdef SECURE_CONTROL
+	parent = debugfs_create_dir("security", top);
+	D16(SECURE_CONTROL);
+	D16(SECURE_STATUS);
+	D32(SECURE_SYSSWT);
+#endif
+
+	parent = debugfs_create_dir("sic", top);
+	D16(SWRST);
+	D16(SYSCR);
+	D16(SIC_RVECT);
+	D32(SIC_IAR0);
+	D32(SIC_IAR1);
+	D32(SIC_IAR2);
+#ifdef SIC_IAR3
+	D32(SIC_IAR3);
+#endif
+#ifdef SIC_IAR4
+	D32(SIC_IAR4);
+	D32(SIC_IAR5);
+	D32(SIC_IAR6);
+#endif
+#ifdef SIC_IAR7
+	D32(SIC_IAR7);
+#endif
+#ifdef SIC_IAR8
+	D32(SIC_IAR8);
+	D32(SIC_IAR9);
+	D32(SIC_IAR10);
+	D32(SIC_IAR11);
+#endif
+#ifdef SIC_IMASK
+	D32(SIC_IMASK);
+	D32(SIC_ISR);
+	D32(SIC_IWR);
+#endif
+#ifdef SIC_IMASK0
+	D32(SIC_IMASK0);
+	D32(SIC_IMASK1);
+	D32(SIC_ISR0);
+	D32(SIC_ISR1);
+	D32(SIC_IWR0);
+	D32(SIC_IWR1);
+#endif
+#ifdef SIC_IMASK2
+	D32(SIC_IMASK2);
+	D32(SIC_ISR2);
+	D32(SIC_IWR2);
+#endif
+#ifdef SICB_RVECT
+	D16(SICB_SWRST);
+	D16(SICB_SYSCR);
+	D16(SICB_RVECT);
+	D32(SICB_IAR0);
+	D32(SICB_IAR1);
+	D32(SICB_IAR2);
+	D32(SICB_IAR3);
+	D32(SICB_IAR4);
+	D32(SICB_IAR5);
+	D32(SICB_IAR6);
+	D32(SICB_IAR7);
+	D32(SICB_IMASK0);
+	D32(SICB_IMASK1);
+	D32(SICB_ISR0);
+	D32(SICB_ISR1);
+	D32(SICB_IWR0);
+	D32(SICB_IWR1);
+#endif
+
+	parent = debugfs_create_dir("spi", top);
+#ifdef SPI0_REGBASE
+	SPI(0);
+#endif
+#ifdef SPI1_REGBASE
+	SPI(1);
+#endif
+#ifdef SPI2_REGBASE
+	SPI(2);
+#endif
+
+	parent = debugfs_create_dir("sport", top);
+#ifdef SPORT0_STAT
+	SPORT(0);
+#endif
+#ifdef SPORT1_STAT
+	SPORT(1);
+#endif
+#ifdef SPORT2_STAT
+	SPORT(2);
+#endif
+#ifdef SPORT3_STAT
+	SPORT(3);
+#endif
+
+#if defined(TWI_CLKDIV) || defined(TWI0_CLKDIV) || defined(TWI1_CLKDIV)
+	parent = debugfs_create_dir("twi", top);
+# ifdef TWI_CLKDIV
+	bfin_debug_mmrs_twi(parent, TWI_CLKDIV, -1);
+# endif
+# ifdef TWI0_CLKDIV
+	TWI(0);
+# endif
+# ifdef TWI1_CLKDIV
+	TWI(1);
+# endif
+#endif
+
+	parent = debugfs_create_dir("uart", top);
+#ifdef BFIN_UART_DLL
+	bfin_debug_mmrs_uart(parent, BFIN_UART_DLL, -1);
+#endif
+#ifdef UART0_DLL
+	UART(0);
+#endif
+#ifdef UART1_DLL
+	UART(1);
+#endif
+#ifdef UART2_DLL
+	UART(2);
+#endif
+#ifdef UART3_DLL
+	UART(3);
+#endif
+
+#ifdef USB_FADDR
+	parent = debugfs_create_dir("usb", top);
+	D16(USB_FADDR);
+	D16(USB_POWER);
+	D16(USB_INTRTX);
+	D16(USB_INTRRX);
+	D16(USB_INTRTXE);
+	D16(USB_INTRRXE);
+	D16(USB_INTRUSB);
+	D16(USB_INTRUSBE);
+	D16(USB_FRAME);
+	D16(USB_INDEX);
+	D16(USB_TESTMODE);
+	D16(USB_GLOBINTR);
+	D16(USB_GLOBAL_CTL);
+	D16(USB_TX_MAX_PACKET);
+	D16(USB_CSR0);
+	D16(USB_TXCSR);
+	D16(USB_RX_MAX_PACKET);
+	D16(USB_RXCSR);
+	D16(USB_COUNT0);
+	D16(USB_RXCOUNT);
+	D16(USB_TXTYPE);
+	D16(USB_NAKLIMIT0);
+	D16(USB_TXINTERVAL);
+	D16(USB_RXTYPE);
+	D16(USB_RXINTERVAL);
+	D16(USB_TXCOUNT);
+	D16(USB_EP0_FIFO);
+	D16(USB_EP1_FIFO);
+	D16(USB_EP2_FIFO);
+	D16(USB_EP3_FIFO);
+	D16(USB_EP4_FIFO);
+	D16(USB_EP5_FIFO);
+	D16(USB_EP6_FIFO);
+	D16(USB_EP7_FIFO);
+	D16(USB_OTG_DEV_CTL);
+	D16(USB_OTG_VBUS_IRQ);
+	D16(USB_OTG_VBUS_MASK);
+	D16(USB_LINKINFO);
+	D16(USB_VPLEN);
+	D16(USB_HS_EOF1);
+	D16(USB_FS_EOF1);
+	D16(USB_LS_EOF1);
+	D16(USB_APHY_CNTRL);
+	D16(USB_APHY_CALIB);
+	D16(USB_APHY_CNTRL2);
+	D16(USB_PHY_TEST);
+	D16(USB_PLLOSC_CTRL);
+	D16(USB_SRP_CLKDIV);
+	D16(USB_EP_NI0_TXMAXP);
+	D16(USB_EP_NI0_TXCSR);
+	D16(USB_EP_NI0_RXMAXP);
+	D16(USB_EP_NI0_RXCSR);
+	D16(USB_EP_NI0_RXCOUNT);
+	D16(USB_EP_NI0_TXTYPE);
+	D16(USB_EP_NI0_TXINTERVAL);
+	D16(USB_EP_NI0_RXTYPE);
+	D16(USB_EP_NI0_RXINTERVAL);
+	D16(USB_EP_NI0_TXCOUNT);
+	D16(USB_EP_NI1_TXMAXP);
+	D16(USB_EP_NI1_TXCSR);
+	D16(USB_EP_NI1_RXMAXP);
+	D16(USB_EP_NI1_RXCSR);
+	D16(USB_EP_NI1_RXCOUNT);
+	D16(USB_EP_NI1_TXTYPE);
+	D16(USB_EP_NI1_TXINTERVAL);
+	D16(USB_EP_NI1_RXTYPE);
+	D16(USB_EP_NI1_RXINTERVAL);
+	D16(USB_EP_NI1_TXCOUNT);
+	D16(USB_EP_NI2_TXMAXP);
+	D16(USB_EP_NI2_TXCSR);
+	D16(USB_EP_NI2_RXMAXP);
+	D16(USB_EP_NI2_RXCSR);
+	D16(USB_EP_NI2_RXCOUNT);
+	D16(USB_EP_NI2_TXTYPE);
+	D16(USB_EP_NI2_TXINTERVAL);
+	D16(USB_EP_NI2_RXTYPE);
+	D16(USB_EP_NI2_RXINTERVAL);
+	D16(USB_EP_NI2_TXCOUNT);
+	D16(USB_EP_NI3_TXMAXP);
+	D16(USB_EP_NI3_TXCSR);
+	D16(USB_EP_NI3_RXMAXP);
+	D16(USB_EP_NI3_RXCSR);
+	D16(USB_EP_NI3_RXCOUNT);
+	D16(USB_EP_NI3_TXTYPE);
+	D16(USB_EP_NI3_TXINTERVAL);
+	D16(USB_EP_NI3_RXTYPE);
+	D16(USB_EP_NI3_RXINTERVAL);
+	D16(USB_EP_NI3_TXCOUNT);
+	D16(USB_EP_NI4_TXMAXP);
+	D16(USB_EP_NI4_TXCSR);
+	D16(USB_EP_NI4_RXMAXP);
+	D16(USB_EP_NI4_RXCSR);
+	D16(USB_EP_NI4_RXCOUNT);
+	D16(USB_EP_NI4_TXTYPE);
+	D16(USB_EP_NI4_TXINTERVAL);
+	D16(USB_EP_NI4_RXTYPE);
+	D16(USB_EP_NI4_RXINTERVAL);
+	D16(USB_EP_NI4_TXCOUNT);
+	D16(USB_EP_NI5_TXMAXP);
+	D16(USB_EP_NI5_TXCSR);
+	D16(USB_EP_NI5_RXMAXP);
+	D16(USB_EP_NI5_RXCSR);
+	D16(USB_EP_NI5_RXCOUNT);
+	D16(USB_EP_NI5_TXTYPE);
+	D16(USB_EP_NI5_TXINTERVAL);
+	D16(USB_EP_NI5_RXTYPE);
+	D16(USB_EP_NI5_RXINTERVAL);
+	D16(USB_EP_NI5_TXCOUNT);
+	D16(USB_EP_NI6_TXMAXP);
+	D16(USB_EP_NI6_TXCSR);
+	D16(USB_EP_NI6_RXMAXP);
+	D16(USB_EP_NI6_RXCSR);
+	D16(USB_EP_NI6_RXCOUNT);
+	D16(USB_EP_NI6_TXTYPE);
+	D16(USB_EP_NI6_TXINTERVAL);
+	D16(USB_EP_NI6_RXTYPE);
+	D16(USB_EP_NI6_RXINTERVAL);
+	D16(USB_EP_NI6_TXCOUNT);
+	D16(USB_EP_NI7_TXMAXP);
+	D16(USB_EP_NI7_TXCSR);
+	D16(USB_EP_NI7_RXMAXP);
+	D16(USB_EP_NI7_RXCSR);
+	D16(USB_EP_NI7_RXCOUNT);
+	D16(USB_EP_NI7_TXTYPE);
+	D16(USB_EP_NI7_TXINTERVAL);
+	D16(USB_EP_NI7_RXTYPE);
+	D16(USB_EP_NI7_RXINTERVAL);
+	D16(USB_EP_NI7_TXCOUNT);
+	D16(USB_DMA_INTERRUPT);
+	D16(USB_DMA0CONTROL);
+	D16(USB_DMA0ADDRLOW);
+	D16(USB_DMA0ADDRHIGH);
+	D16(USB_DMA0COUNTLOW);
+	D16(USB_DMA0COUNTHIGH);
+	D16(USB_DMA1CONTROL);
+	D16(USB_DMA1ADDRLOW);
+	D16(USB_DMA1ADDRHIGH);
+	D16(USB_DMA1COUNTLOW);
+	D16(USB_DMA1COUNTHIGH);
+	D16(USB_DMA2CONTROL);
+	D16(USB_DMA2ADDRLOW);
+	D16(USB_DMA2ADDRHIGH);
+	D16(USB_DMA2COUNTLOW);
+	D16(USB_DMA2COUNTHIGH);
+	D16(USB_DMA3CONTROL);
+	D16(USB_DMA3ADDRLOW);
+	D16(USB_DMA3ADDRHIGH);
+	D16(USB_DMA3COUNTLOW);
+	D16(USB_DMA3COUNTHIGH);
+	D16(USB_DMA4CONTROL);
+	D16(USB_DMA4ADDRLOW);
+	D16(USB_DMA4ADDRHIGH);
+	D16(USB_DMA4COUNTLOW);
+	D16(USB_DMA4COUNTHIGH);
+	D16(USB_DMA5CONTROL);
+	D16(USB_DMA5ADDRLOW);
+	D16(USB_DMA5ADDRHIGH);
+	D16(USB_DMA5COUNTLOW);
+	D16(USB_DMA5COUNTHIGH);
+	D16(USB_DMA6CONTROL);
+	D16(USB_DMA6ADDRLOW);
+	D16(USB_DMA6ADDRHIGH);
+	D16(USB_DMA6COUNTLOW);
+	D16(USB_DMA6COUNTHIGH);
+	D16(USB_DMA7CONTROL);
+	D16(USB_DMA7ADDRLOW);
+	D16(USB_DMA7ADDRHIGH);
+	D16(USB_DMA7COUNTLOW);
+	D16(USB_DMA7COUNTHIGH);
+#endif
+
+#ifdef WDOG_CNT
+	parent = debugfs_create_dir("watchdog", top);
+	D32(WDOG_CNT);
+	D16(WDOG_CTL);
+	D32(WDOG_STAT);
+#endif
+#ifdef WDOGA_CNT
+	parent = debugfs_create_dir("watchdog", top);
+	D32(WDOGA_CNT);
+	D16(WDOGA_CTL);
+	D32(WDOGA_STAT);
+	D32(WDOGB_CNT);
+	D16(WDOGB_CTL);
+	D32(WDOGB_STAT);
+#endif
+
+	/* BF533 glue */
+#ifdef FIO_FLAG_D
+#define PORTFIO FIO_FLAG_D
+#endif
+	/* BF561 glue */
+#ifdef FIO0_FLAG_D
+#define PORTFIO FIO0_FLAG_D
+#endif
+#ifdef FIO1_FLAG_D
+#define PORTGIO FIO1_FLAG_D
+#endif
+#ifdef FIO2_FLAG_D
+#define PORTHIO FIO2_FLAG_D
+#endif
+	parent = debugfs_create_dir("port", top);
+#ifdef PORTFIO
+	PORT(PORTFIO, 'F');
+#endif
+#ifdef PORTGIO
+	PORT(PORTGIO, 'G');
+#endif
+#ifdef PORTHIO
+	PORT(PORTHIO, 'H');
+#endif
+
+#ifdef __ADSPBF51x__
+	D16(PORTF_FER);
+	D16(PORTF_DRIVE);
+	D16(PORTF_HYSTERESIS);
+	D16(PORTF_MUX);
+
+	D16(PORTG_FER);
+	D16(PORTG_DRIVE);
+	D16(PORTG_HYSTERESIS);
+	D16(PORTG_MUX);
+
+	D16(PORTH_FER);
+	D16(PORTH_DRIVE);
+	D16(PORTH_HYSTERESIS);
+	D16(PORTH_MUX);
+
+	D16(MISCPORT_DRIVE);
+	D16(MISCPORT_HYSTERESIS);
+#endif	/* BF51x */
+
+#ifdef __ADSPBF52x__
+	D16(PORTF_FER);
+	D16(PORTF_DRIVE);
+	D16(PORTF_HYSTERESIS);
+	D16(PORTF_MUX);
+	D16(PORTF_SLEW);
+
+	D16(PORTG_FER);
+	D16(PORTG_DRIVE);
+	D16(PORTG_HYSTERESIS);
+	D16(PORTG_MUX);
+	D16(PORTG_SLEW);
+
+	D16(PORTH_FER);
+	D16(PORTH_DRIVE);
+	D16(PORTH_HYSTERESIS);
+	D16(PORTH_MUX);
+	D16(PORTH_SLEW);
+
+	D16(MISCPORT_DRIVE);
+	D16(MISCPORT_HYSTERESIS);
+	D16(MISCPORT_SLEW);
+#endif	/* BF52x */
+
+#ifdef BF537_FAMILY
+	D16(PORTF_FER);
+	D16(PORTG_FER);
+	D16(PORTH_FER);
+	D16(PORT_MUX);
+#endif	/* BF534 BF536 BF537 */
+
+#ifdef BF538_FAMILY
+	D16(PORTCIO_FER);
+	D16(PORTCIO);
+	D16(PORTCIO_CLEAR);
+	D16(PORTCIO_SET);
+	D16(PORTCIO_TOGGLE);
+	D16(PORTCIO_DIR);
+	D16(PORTCIO_INEN);
+
+	D16(PORTDIO);
+	D16(PORTDIO_CLEAR);
+	D16(PORTDIO_DIR);
+	D16(PORTDIO_FER);
+	D16(PORTDIO_INEN);
+	D16(PORTDIO_SET);
+	D16(PORTDIO_TOGGLE);
+
+	D16(PORTEIO);
+	D16(PORTEIO_CLEAR);
+	D16(PORTEIO_DIR);
+	D16(PORTEIO_FER);
+	D16(PORTEIO_INEN);
+	D16(PORTEIO_SET);
+	D16(PORTEIO_TOGGLE);
+#endif	/* BF538 BF539 */
+
+#ifdef __ADSPBF54x__
+	{
+		int num;
+		unsigned long base;
+		char *_buf, buf[32];
+
+		base = PORTA_FER;
+		for (num = 0; num < 10; ++num) {
+			PORT(base, num);
+			base += sizeof(struct bfin_gpio_regs);
+		}
+
+#define __PINT(uname, lname) __REGS(pint, #uname, lname)
+		parent = debugfs_create_dir("pint", top);
+		base = PINT0_MASK_SET;
+		for (num = 0; num < 4; ++num) {
+			_buf = REGS_STR_PFX(buf, PINT, num);
+			__PINT(MASK_SET, mask_set);
+			__PINT(MASK_CLEAR, mask_clear);
+			__PINT(IRQ, irq);
+			__PINT(ASSIGN, assign);
+			__PINT(EDGE_SET, edge_set);
+			__PINT(EDGE_CLEAR, edge_clear);
+			__PINT(INVERT_SET, invert_set);
+			__PINT(INVERT_CLEAR, invert_clear);
+			__PINT(PINSTATE, pinstate);
+			__PINT(LATCH, latch);
+			base += sizeof(struct bfin_pint_regs);
+		}
+
+	}
+#endif	/* BF54x */
+
+	debug_mmrs_dentry = top;
+
+	return 0;
+}
+module_init(bfin_debug_mmrs_init);
+
+static void __exit bfin_debug_mmrs_exit(void)
+{
+	debugfs_remove_recursive(debug_mmrs_dentry);
+}
+module_exit(bfin_debug_mmrs_exit);
+
+MODULE_LICENSE("GPL");
diff -druN linux-2.6.39-libre/arch/blackfin/kernel/ipipe.c linux-3.0-rc7-libre/arch/blackfin/kernel/ipipe.c
--- linux-2.6.39-libre/arch/blackfin/kernel/ipipe.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/blackfin/kernel/ipipe.c	2011-07-11 19:51:52.000000000 -0400
@@ -33,6 +33,7 @@
 #include <linux/io.h>
 #include <asm/system.h>
 #include <asm/atomic.h>
+#include <asm/irq_handler.h>
 
 DEFINE_PER_CPU(struct pt_regs, __ipipe_tick_regs);
 
diff -druN linux-2.6.39-libre/arch/blackfin/kernel/irqchip.c linux-3.0-rc7-libre/arch/blackfin/kernel/irqchip.c
--- linux-2.6.39-libre/arch/blackfin/kernel/irqchip.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/blackfin/kernel/irqchip.c	2011-07-11 19:51:52.000000000 -0400
@@ -11,6 +11,7 @@
 #include <linux/kallsyms.h>
 #include <linux/interrupt.h>
 #include <linux/irq.h>
+#include <asm/irq_handler.h>
 #include <asm/trace.h>
 #include <asm/pda.h>
 
diff -druN linux-2.6.39-libre/arch/blackfin/kernel/Makefile linux-3.0-rc7-libre/arch/blackfin/kernel/Makefile
--- linux-2.6.39-libre/arch/blackfin/kernel/Makefile	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/blackfin/kernel/Makefile	2011-07-11 19:51:52.000000000 -0400
@@ -33,7 +33,10 @@
 obj-$(CONFIG_STACKTRACE)             += stacktrace.o
 obj-$(CONFIG_DEBUG_VERBOSE)          += trace.o
 obj-$(CONFIG_BFIN_PSEUDODBG_INSNS)   += pseudodbg.o
+obj-$(CONFIG_PERF_EVENTS)            += perf_event.o
 
 # the kgdb test puts code into L2 and without linker
 # relaxation, we need to force long calls to/from it
 CFLAGS_kgdb_test.o := -mlong-calls -O0
+
+obj-$(CONFIG_DEBUG_MMRS)             += debug-mmrs.o
diff -druN linux-2.6.39-libre/arch/blackfin/kernel/nmi.c linux-3.0-rc7-libre/arch/blackfin/kernel/nmi.c
--- linux-2.6.39-libre/arch/blackfin/kernel/nmi.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/blackfin/kernel/nmi.c	2011-07-11 19:51:52.000000000 -0400
@@ -12,7 +12,7 @@
 
 #include <linux/bitops.h>
 #include <linux/hardirq.h>
-#include <linux/sysdev.h>
+#include <linux/syscore_ops.h>
 #include <linux/pm.h>
 #include <linux/nmi.h>
 #include <linux/smp.h>
@@ -145,16 +145,16 @@
 {
 	unsigned int this_cpu = smp_processor_id();
 	unsigned int cpu;
+	cpumask_t mask;
 
-	cpumask_t mask = cpu_online_map;
-
+	cpumask_copy(&mask, cpu_online_mask);
 	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) {
+	cpumask_clear_cpu(this_cpu, &mask);
+	for_each_cpu(cpu, &mask) {
 		invalidate_dcache_range((unsigned long)(&nmi_touched[cpu]),
 				(unsigned long)(&nmi_touched[cpu]));
 		if (!atomic_read(&nmi_touched[cpu]))
@@ -196,43 +196,31 @@
 
 /* Suspend/resume support */
 #ifdef CONFIG_PM
-static int nmi_wdt_suspend(struct sys_device *dev, pm_message_t state)
+static int nmi_wdt_suspend(void)
 {
 	nmi_wdt_stop();
 	return 0;
 }
 
-static int nmi_wdt_resume(struct sys_device *dev)
+static void nmi_wdt_resume(void)
 {
 	if (nmi_active)
 		nmi_wdt_start();
-	return 0;
 }
 
-static struct sysdev_class nmi_sysclass = {
-	.name		= DRV_NAME,
+static struct syscore_ops nmi_syscore_ops = {
 	.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)
+static int __init init_nmi_wdt_syscore(void)
 {
-	int error;
-
-	if (!nmi_active)
-		return 0;
+	if (nmi_active)
+		register_syscore_ops(&nmi_syscore_ops);
 
-	error = sysdev_class_register(&nmi_sysclass);
-	if (!error)
-		error = sysdev_register(&device_nmi_wdt);
-	return error;
+	return 0;
 }
-late_initcall(init_nmi_wdt_sysfs);
+late_initcall(init_nmi_wdt_syscore);
 
 #endif	/* CONFIG_PM */
 
diff -druN linux-2.6.39-libre/arch/blackfin/kernel/perf_event.c linux-3.0-rc7-libre/arch/blackfin/kernel/perf_event.c
--- linux-2.6.39-libre/arch/blackfin/kernel/perf_event.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/blackfin/kernel/perf_event.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,498 @@
+/*
+ * Blackfin performance counters
+ *
+ * Copyright 2011 Analog Devices Inc.
+ *
+ * Ripped from SuperH version:
+ *
+ *  Copyright (C) 2009  Paul Mundt
+ *
+ * Heavily based on the x86 and PowerPC implementations.
+ *
+ * x86:
+ *  Copyright (C) 2008 Thomas Gleixner <tglx@linutronix.de>
+ *  Copyright (C) 2008-2009 Red Hat, Inc., Ingo Molnar
+ *  Copyright (C) 2009 Jaswinder Singh Rajput
+ *  Copyright (C) 2009 Advanced Micro Devices, Inc., Robert Richter
+ *  Copyright (C) 2008-2009 Red Hat, Inc., Peter Zijlstra <pzijlstr@redhat.com>
+ *  Copyright (C) 2009 Intel Corporation, <markus.t.metzger@intel.com>
+ *
+ * ppc:
+ *  Copyright 2008-2009 Paul Mackerras, IBM Corporation.
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/perf_event.h>
+#include <asm/bfin_pfmon.h>
+
+/*
+ * We have two counters, and each counter can support an event type.
+ * The 'o' is PFCNTx=1 and 's' is PFCNTx=0
+ *
+ * 0x04 o pc invariant branches
+ * 0x06 o mispredicted branches
+ * 0x09 o predicted branches taken
+ * 0x0B o EXCPT insn
+ * 0x0C o CSYNC/SSYNC insn
+ * 0x0D o Insns committed
+ * 0x0E o Interrupts taken
+ * 0x0F o Misaligned address exceptions
+ * 0x80 o Code memory fetches stalled due to DMA
+ * 0x83 o 64bit insn fetches delivered
+ * 0x9A o data cache fills (bank a)
+ * 0x9B o data cache fills (bank b)
+ * 0x9C o data cache lines evicted (bank a)
+ * 0x9D o data cache lines evicted (bank b)
+ * 0x9E o data cache high priority fills
+ * 0x9F o data cache low priority fills
+ * 0x00 s loop 0 iterations
+ * 0x01 s loop 1 iterations
+ * 0x0A s CSYNC/SSYNC stalls
+ * 0x10 s DAG read/after write hazards
+ * 0x13 s RAW data hazards
+ * 0x81 s code TAG stalls
+ * 0x82 s code fill stalls
+ * 0x90 s processor to memory stalls
+ * 0x91 s data memory stalls not hidden by 0x90
+ * 0x92 s data store buffer full stalls
+ * 0x93 s data memory write buffer full stalls due to high->low priority
+ * 0x95 s data memory fill buffer stalls
+ * 0x96 s data TAG collision stalls
+ * 0x97 s data collision stalls
+ * 0x98 s data stalls
+ * 0x99 s data stalls sent to processor
+ */
+
+static const int event_map[] = {
+	/* use CYCLES cpu register */
+	[PERF_COUNT_HW_CPU_CYCLES]          = -1,
+	[PERF_COUNT_HW_INSTRUCTIONS]        = 0x0D,
+	[PERF_COUNT_HW_CACHE_REFERENCES]    = -1,
+	[PERF_COUNT_HW_CACHE_MISSES]        = 0x83,
+	[PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = 0x09,
+	[PERF_COUNT_HW_BRANCH_MISSES]       = 0x06,
+	[PERF_COUNT_HW_BUS_CYCLES]          = -1,
+};
+
+#define C(x)	PERF_COUNT_HW_CACHE_##x
+
+static const int cache_events[PERF_COUNT_HW_CACHE_MAX]
+                             [PERF_COUNT_HW_CACHE_OP_MAX]
+                             [PERF_COUNT_HW_CACHE_RESULT_MAX] =
+{
+	[C(L1D)] = {	/* Data bank A */
+		[C(OP_READ)] = {
+			[C(RESULT_ACCESS)] = 0,
+			[C(RESULT_MISS)  ] = 0x9A,
+		},
+		[C(OP_WRITE)] = {
+			[C(RESULT_ACCESS)] = 0,
+			[C(RESULT_MISS)  ] = 0,
+		},
+		[C(OP_PREFETCH)] = {
+			[C(RESULT_ACCESS)] = 0,
+			[C(RESULT_MISS)  ] = 0,
+		},
+	},
+
+	[C(L1I)] = {
+		[C(OP_READ)] = {
+			[C(RESULT_ACCESS)] = 0,
+			[C(RESULT_MISS)  ] = 0x83,
+		},
+		[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)] = -1,
+			[C(RESULT_MISS)  ] = -1,
+		},
+		[C(OP_WRITE)] = {
+			[C(RESULT_ACCESS)] = -1,
+			[C(RESULT_MISS)  ] = -1,
+		},
+		[C(OP_PREFETCH)] = {
+			[C(RESULT_ACCESS)] = -1,
+			[C(RESULT_MISS)  ] = -1,
+		},
+	},
+
+	[C(DTLB)] = {
+		[C(OP_READ)] = {
+			[C(RESULT_ACCESS)] = -1,
+			[C(RESULT_MISS)  ] = -1,
+		},
+		[C(OP_WRITE)] = {
+			[C(RESULT_ACCESS)] = -1,
+			[C(RESULT_MISS)  ] = -1,
+		},
+		[C(OP_PREFETCH)] = {
+			[C(RESULT_ACCESS)] = -1,
+			[C(RESULT_MISS)  ] = -1,
+		},
+	},
+
+	[C(ITLB)] = {
+		[C(OP_READ)] = {
+			[C(RESULT_ACCESS)] = -1,
+			[C(RESULT_MISS)  ] = -1,
+		},
+		[C(OP_WRITE)] = {
+			[C(RESULT_ACCESS)] = -1,
+			[C(RESULT_MISS)  ] = -1,
+		},
+		[C(OP_PREFETCH)] = {
+			[C(RESULT_ACCESS)] = -1,
+			[C(RESULT_MISS)  ] = -1,
+		},
+	},
+
+	[C(BPU)] = {
+		[C(OP_READ)] = {
+			[C(RESULT_ACCESS)] = -1,
+			[C(RESULT_MISS)  ] = -1,
+		},
+		[C(OP_WRITE)] = {
+			[C(RESULT_ACCESS)] = -1,
+			[C(RESULT_MISS)  ] = -1,
+		},
+		[C(OP_PREFETCH)] = {
+			[C(RESULT_ACCESS)] = -1,
+			[C(RESULT_MISS)  ] = -1,
+		},
+	},
+};
+
+const char *perf_pmu_name(void)
+{
+	return "bfin";
+}
+EXPORT_SYMBOL(perf_pmu_name);
+
+int perf_num_counters(void)
+{
+	return ARRAY_SIZE(event_map);
+}
+EXPORT_SYMBOL(perf_num_counters);
+
+static u64 bfin_pfmon_read(int idx)
+{
+	return bfin_read32(PFCNTR0 + (idx * 4));
+}
+
+static void bfin_pfmon_disable(struct hw_perf_event *hwc, int idx)
+{
+	bfin_write_PFCTL(bfin_read_PFCTL() & ~PFCEN(idx, PFCEN_MASK));
+}
+
+static void bfin_pfmon_enable(struct hw_perf_event *hwc, int idx)
+{
+	u32 val, mask;
+
+	val = PFPWR;
+	if (idx) {
+		mask = ~(PFCNT1 | PFMON1 | PFCEN1 | PEMUSW1);
+		/* The packed config is for event0, so shift it to event1 slots */
+		val |= (hwc->config << (PFMON1_P - PFMON0_P));
+		val |= (hwc->config & PFCNT0) << (PFCNT1_P - PFCNT0_P);
+		bfin_write_PFCNTR1(0);
+	} else {
+		mask = ~(PFCNT0 | PFMON0 | PFCEN0 | PEMUSW0);
+		val |= hwc->config;
+		bfin_write_PFCNTR0(0);
+	}
+
+	bfin_write_PFCTL((bfin_read_PFCTL() & mask) | val);
+}
+
+static void bfin_pfmon_disable_all(void)
+{
+	bfin_write_PFCTL(bfin_read_PFCTL() & ~PFPWR);
+}
+
+static void bfin_pfmon_enable_all(void)
+{
+	bfin_write_PFCTL(bfin_read_PFCTL() | PFPWR);
+}
+
+struct cpu_hw_events {
+	struct perf_event *events[MAX_HWEVENTS];
+	unsigned long used_mask[BITS_TO_LONGS(MAX_HWEVENTS)];
+};
+DEFINE_PER_CPU(struct cpu_hw_events, cpu_hw_events);
+
+static int hw_perf_cache_event(int config, int *evp)
+{
+	unsigned long type, op, result;
+	int ev;
+
+	/* 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 = cache_events[type][op][result];
+	if (ev == 0)
+		return -EOPNOTSUPP;
+	if (ev == -1)
+		return -EINVAL;
+	*evp = ev;
+	return 0;
+}
+
+static void bfin_perf_event_update(struct perf_event *event,
+				   struct hw_perf_event *hwc, int idx)
+{
+	u64 prev_raw_count, new_raw_count;
+	s64 delta;
+	int shift = 0;
+
+	/*
+	 * Depending on the counter configuration, they may or may not
+	 * be chained, in which case the previous counter value can be
+	 * updated underneath us if the lower-half overflows.
+	 *
+	 * Our tactic to handle this is to first atomically read and
+	 * exchange a new raw count - then add that new-prev delta
+	 * count to the generic counter atomically.
+	 *
+	 * As there is no interrupt associated with the overflow events,
+	 * this is the simplest approach for maintaining consistency.
+	 */
+again:
+	prev_raw_count = local64_read(&hwc->prev_count);
+	new_raw_count = bfin_pfmon_read(idx);
+
+	if (local64_cmpxchg(&hwc->prev_count, prev_raw_count,
+			     new_raw_count) != prev_raw_count)
+		goto again;
+
+	/*
+	 * Now we have the new raw value and have updated the prev
+	 * timestamp already. We can now calculate the elapsed delta
+	 * (counter-)time and add that to the generic counter.
+	 *
+	 * Careful, not all hw sign-extends above the physical width
+	 * of the count.
+	 */
+	delta = (new_raw_count << shift) - (prev_raw_count << shift);
+	delta >>= shift;
+
+	local64_add(delta, &event->count);
+}
+
+static void bfin_pmu_stop(struct perf_event *event, int flags)
+{
+	struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
+	struct hw_perf_event *hwc = &event->hw;
+	int idx = hwc->idx;
+
+	if (!(event->hw.state & PERF_HES_STOPPED)) {
+		bfin_pfmon_disable(hwc, idx);
+		cpuc->events[idx] = NULL;
+		event->hw.state |= PERF_HES_STOPPED;
+	}
+
+	if ((flags & PERF_EF_UPDATE) && !(event->hw.state & PERF_HES_UPTODATE)) {
+		bfin_perf_event_update(event, &event->hw, idx);
+		event->hw.state |= PERF_HES_UPTODATE;
+	}
+}
+
+static void bfin_pmu_start(struct perf_event *event, int flags)
+{
+	struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
+	struct hw_perf_event *hwc = &event->hw;
+	int idx = hwc->idx;
+
+	if (WARN_ON_ONCE(idx == -1))
+		return;
+
+	if (flags & PERF_EF_RELOAD)
+		WARN_ON_ONCE(!(event->hw.state & PERF_HES_UPTODATE));
+
+	cpuc->events[idx] = event;
+	event->hw.state = 0;
+	bfin_pfmon_enable(hwc, idx);
+}
+
+static void bfin_pmu_del(struct perf_event *event, int flags)
+{
+	struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
+
+	bfin_pmu_stop(event, PERF_EF_UPDATE);
+	__clear_bit(event->hw.idx, cpuc->used_mask);
+
+	perf_event_update_userpage(event);
+}
+
+static int bfin_pmu_add(struct perf_event *event, int flags)
+{
+	struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
+	struct hw_perf_event *hwc = &event->hw;
+	int idx = hwc->idx;
+	int ret = -EAGAIN;
+
+	perf_pmu_disable(event->pmu);
+
+	if (__test_and_set_bit(idx, cpuc->used_mask)) {
+		idx = find_first_zero_bit(cpuc->used_mask, MAX_HWEVENTS);
+		if (idx == MAX_HWEVENTS)
+			goto out;
+
+		__set_bit(idx, cpuc->used_mask);
+		hwc->idx = idx;
+	}
+
+	bfin_pfmon_disable(hwc, idx);
+
+	event->hw.state = PERF_HES_UPTODATE | PERF_HES_STOPPED;
+	if (flags & PERF_EF_START)
+		bfin_pmu_start(event, PERF_EF_RELOAD);
+
+	perf_event_update_userpage(event);
+	ret = 0;
+out:
+	perf_pmu_enable(event->pmu);
+	return ret;
+}
+
+static void bfin_pmu_read(struct perf_event *event)
+{
+	bfin_perf_event_update(event, &event->hw, event->hw.idx);
+}
+
+static int bfin_pmu_event_init(struct perf_event *event)
+{
+	struct perf_event_attr *attr = &event->attr;
+	struct hw_perf_event *hwc = &event->hw;
+	int config = -1;
+	int ret;
+
+	if (attr->exclude_hv || attr->exclude_idle)
+		return -EPERM;
+
+	/*
+	 * All of the on-chip counters are "limited", in that they have
+	 * no interrupts, and are therefore unable to do sampling without
+	 * further work and timer assistance.
+	 */
+	if (hwc->sample_period)
+		return -EINVAL;
+
+	ret = 0;
+	switch (attr->type) {
+	case PERF_TYPE_RAW:
+		config = PFMON(0, attr->config & PFMON_MASK) |
+			PFCNT(0, !(attr->config & 0x100));
+		break;
+	case PERF_TYPE_HW_CACHE:
+		ret = hw_perf_cache_event(attr->config, &config);
+		break;
+	case PERF_TYPE_HARDWARE:
+		if (attr->config >= ARRAY_SIZE(event_map))
+			return -EINVAL;
+
+		config = event_map[attr->config];
+		break;
+	}
+
+	if (config == -1)
+		return -EINVAL;
+
+	if (!attr->exclude_kernel)
+		config |= PFCEN(0, PFCEN_ENABLE_SUPV);
+	if (!attr->exclude_user)
+		config |= PFCEN(0, PFCEN_ENABLE_USER);
+
+	hwc->config |= config;
+
+	return ret;
+}
+
+static void bfin_pmu_enable(struct pmu *pmu)
+{
+	struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
+	struct perf_event *event;
+	struct hw_perf_event *hwc;
+	int i;
+
+	for (i = 0; i < MAX_HWEVENTS; ++i) {
+		event = cpuc->events[i];
+		if (!event)
+			continue;
+		hwc = &event->hw;
+		bfin_pfmon_enable(hwc, hwc->idx);
+	}
+
+	bfin_pfmon_enable_all();
+}
+
+static void bfin_pmu_disable(struct pmu *pmu)
+{
+	bfin_pfmon_disable_all();
+}
+
+static struct pmu pmu = {
+	.pmu_enable  = bfin_pmu_enable,
+	.pmu_disable = bfin_pmu_disable,
+	.event_init  = bfin_pmu_event_init,
+	.add         = bfin_pmu_add,
+	.del         = bfin_pmu_del,
+	.start       = bfin_pmu_start,
+	.stop        = bfin_pmu_stop,
+	.read        = bfin_pmu_read,
+};
+
+static void bfin_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
+bfin_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:
+		bfin_write_PFCTL(0);
+		bfin_pmu_setup(cpu);
+		break;
+
+	default:
+		break;
+	}
+
+	return NOTIFY_OK;
+}
+
+static int __init bfin_pmu_init(void)
+{
+	int ret;
+
+	ret = perf_pmu_register(&pmu, "cpu", PERF_TYPE_RAW);
+	if (!ret)
+		perf_cpu_notifier(bfin_pmu_notifier);
+
+	return ret;
+}
+early_initcall(bfin_pmu_init);
diff -druN linux-2.6.39-libre/arch/blackfin/kernel/process.c linux-3.0-rc7-libre/arch/blackfin/kernel/process.c
--- linux-2.6.39-libre/arch/blackfin/kernel/process.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/blackfin/kernel/process.c	2011-07-11 19:51:52.000000000 -0400
@@ -171,10 +171,8 @@
 	unsigned long newsp;
 
 #ifdef __ARCH_SYNC_CORE_DCACHE
-	if (current->rt.nr_cpus_allowed == num_possible_cpus()) {
-		current->cpus_allowed = cpumask_of_cpu(smp_processor_id());
-		current->rt.nr_cpus_allowed = 1;
-	}
+	if (current->rt.nr_cpus_allowed == num_possible_cpus())
+		set_cpus_allowed_ptr(current, cpumask_of(smp_processor_id()));
 #endif
 
 	/* syscall2 puts clone_flags in r0 and usp in r1 */
diff -druN linux-2.6.39-libre/arch/blackfin/kernel/reboot.c linux-3.0-rc7-libre/arch/blackfin/kernel/reboot.c
--- linux-2.6.39-libre/arch/blackfin/kernel/reboot.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/blackfin/kernel/reboot.c	2011-07-11 19:51:52.000000000 -0400
@@ -23,6 +23,9 @@
 __attribute__ ((__l1_text__, __noreturn__))
 static void bfin_reset(void)
 {
+	if (!ANOMALY_05000353 && !ANOMALY_05000386)
+		bfrom_SoftReset((void *)(L1_SCRATCH_START + L1_SCRATCH_LENGTH - 20));
+
 	/* Wait for completion of "system" events such as cache line
 	 * line fills so that we avoid infinite stalls later on as
 	 * much as possible.  This code is in L1, so it won't trigger
@@ -30,46 +33,40 @@
 	 */
 	__builtin_bfin_ssync();
 
-	/* The bootrom checks to see how it was reset and will
-	 * automatically perform a software reset for us when
-	 * it starts executing after the core reset.
-	 */
-	if (ANOMALY_05000353 || ANOMALY_05000386) {
-		/* Initiate System software reset. */
-		bfin_write_SWRST(0x7);
+	/* Initiate System software reset. */
+	bfin_write_SWRST(0x7);
 
-		/* Due to the way reset is handled in the hardware, we need
-		 * to delay for 10 SCLKS.  The only reliable way to do this is
-		 * to calculate the CCLK/SCLK ratio and multiply 10.  For now,
-		 * we'll assume worse case which is a 1:15 ratio.
-		 */
-		asm(
-			"LSETUP (1f, 1f) LC0 = %0\n"
-			"1: nop;"
-			:
-			: "a" (15 * 10)
-			: "LC0", "LB0", "LT0"
-		);
+	/* Due to the way reset is handled in the hardware, we need
+	 * to delay for 10 SCLKS.  The only reliable way to do this is
+	 * to calculate the CCLK/SCLK ratio and multiply 10.  For now,
+	 * we'll assume worse case which is a 1:15 ratio.
+	 */
+	asm(
+		"LSETUP (1f, 1f) LC0 = %0\n"
+		"1: nop;"
+		:
+		: "a" (15 * 10)
+		: "LC0", "LB0", "LT0"
+	);
 
-		/* Clear System software reset */
-		bfin_write_SWRST(0);
+	/* Clear System software reset */
+	bfin_write_SWRST(0);
 
-		/* The BF526 ROM will crash during reset */
+	/* The BF526 ROM will crash during reset */
 #if defined(__ADSPBF522__) || defined(__ADSPBF524__) || defined(__ADSPBF526__)
-		bfin_read_SWRST();
+	bfin_read_SWRST();
 #endif
 
-		/* Wait for the SWRST write to complete.  Cannot rely on SSYNC
-		 * though as the System state is all reset now.
-		 */
-		asm(
-			"LSETUP (1f, 1f) LC1 = %0\n"
-			"1: nop;"
-			:
-			: "a" (15 * 1)
-			: "LC1", "LB1", "LT1"
-		);
-	}
+	/* Wait for the SWRST write to complete.  Cannot rely on SSYNC
+	 * though as the System state is all reset now.
+	 */
+	asm(
+		"LSETUP (1f, 1f) LC1 = %0\n"
+		"1: nop;"
+		:
+		: "a" (15 * 1)
+		: "LC1", "LB1", "LT1"
+	);
 
 	while (1)
 		/* Issue core reset */
diff -druN linux-2.6.39-libre/arch/blackfin/kernel/setup.c linux-3.0-rc7-libre/arch/blackfin/kernel/setup.c
--- linux-2.6.39-libre/arch/blackfin/kernel/setup.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/blackfin/kernel/setup.c	2011-07-11 19:51:52.000000000 -0400
@@ -29,6 +29,7 @@
 #include <asm/cpu.h>
 #include <asm/fixed_code.h>
 #include <asm/early_printk.h>
+#include <asm/irq_handler.h>
 
 u16 _bfin_swrst;
 EXPORT_SYMBOL(_bfin_swrst);
@@ -105,6 +106,8 @@
 	bfin_dcache_init(dcplb_tbl[cpu]);
 #endif
 
+	bfin_setup_cpudata(cpu);
+
 	/*
 	 * In cache coherence emulation mode, we need to have the
 	 * D-cache enabled before running any atomic operation which
@@ -163,7 +166,6 @@
 {
 	struct blackfin_cpudata *cpudata = &per_cpu(cpu_data, cpu);
 
-	cpudata->idle = current;
 	cpudata->imemctl = bfin_read_IMEM_CONTROL();
 	cpudata->dmemctl = bfin_read_DMEM_CONTROL();
 }
@@ -851,6 +853,7 @@
 
 void __init setup_arch(char **cmdline_p)
 {
+	u32 mmr;
 	unsigned long sclk, cclk;
 
 	native_machine_early_platform_add_devices();
@@ -902,10 +905,10 @@
 	bfin_write_EBIU_FCTL(CONFIG_EBIU_FCTLVAL);
 #endif
 #ifdef CONFIG_BFIN_HYSTERESIS_CONTROL
-	bfin_write_PORTF_HYSTERISIS(HYST_PORTF_0_15);
-	bfin_write_PORTG_HYSTERISIS(HYST_PORTG_0_15);
-	bfin_write_PORTH_HYSTERISIS(HYST_PORTH_0_15);
-	bfin_write_MISCPORT_HYSTERISIS((bfin_read_MISCPORT_HYSTERISIS() &
+	bfin_write_PORTF_HYSTERESIS(HYST_PORTF_0_15);
+	bfin_write_PORTG_HYSTERESIS(HYST_PORTG_0_15);
+	bfin_write_PORTH_HYSTERESIS(HYST_PORTH_0_15);
+	bfin_write_MISCPORT_HYSTERESIS((bfin_read_MISCPORT_HYSTERESIS() &
 					~HYST_NONEGPIO_MASK) | HYST_NONEGPIO);
 #endif
 
@@ -921,17 +924,14 @@
 		bfin_read_IMDMA_D1_IRQ_STATUS();
 	}
 #endif
-	printk(KERN_INFO "Hardware Trace ");
-	if (bfin_read_TBUFCTL() & 0x1)
-		printk(KERN_CONT "Active ");
-	else
-		printk(KERN_CONT "Off ");
-	if (bfin_read_TBUFCTL() & 0x2)
-		printk(KERN_CONT "and Enabled\n");
-	else
-		printk(KERN_CONT "and Disabled\n");
 
-	printk(KERN_INFO "Boot Mode: %i\n", bfin_read_SYSCR() & 0xF);
+	mmr = bfin_read_TBUFCTL();
+	printk(KERN_INFO "Hardware Trace %s and %sabled\n",
+		(mmr & 0x1) ? "active" : "off",
+		(mmr & 0x2) ? "en" : "dis");
+
+	mmr = bfin_read_SYSCR();
+	printk(KERN_INFO "Boot Mode: %i\n", mmr & 0xF);
 
 	/* Newer parts mirror SWRST bits in SYSCR */
 #if defined(CONFIG_BF53x) || defined(CONFIG_BF561) || \
@@ -939,7 +939,7 @@
 	_bfin_swrst = bfin_read_SWRST();
 #else
 	/* Clear boot mode field */
-	_bfin_swrst = bfin_read_SYSCR() & ~0xf;
+	_bfin_swrst = mmr & ~0xf;
 #endif
 
 #ifdef CONFIG_DEBUG_DOUBLEFAULT_PRINT
@@ -1036,8 +1036,6 @@
 static int __init topology_init(void)
 {
 	unsigned int cpu;
-	/* Record CPU-private information for the boot processor. */
-	bfin_setup_cpudata(0);
 
 	for_each_possible_cpu(cpu) {
 		register_cpu(&per_cpu(cpu_data, cpu).cpu, cpu);
@@ -1283,12 +1281,14 @@
 		   dsup_banks, BFIN_DSUBBANKS, BFIN_DWAYS,
 		   BFIN_DLINES);
 #ifdef __ARCH_SYNC_CORE_DCACHE
-	seq_printf(m, "SMP Dcache Flushes\t: %lu\n\n", dcache_invld_count[cpu_num]);
+	seq_printf(m, "dcache flushes\t: %lu\n", dcache_invld_count[cpu_num]);
 #endif
 #ifdef __ARCH_SYNC_CORE_ICACHE
-	seq_printf(m, "SMP Icache Flushes\t: %lu\n\n", icache_invld_count[cpu_num]);
+	seq_printf(m, "icache flushes\t: %lu\n", icache_invld_count[cpu_num]);
 #endif
 
+	seq_printf(m, "\n");
+
 	if (cpu_num != num_possible_cpus() - 1)
 		return 0;
 
@@ -1312,13 +1312,11 @@
 			      " in data cache\n");
 	}
 	seq_printf(m, "board name\t: %s\n", bfin_board_name);
-	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",
+	seq_printf(m, "board memory\t: %ld kB (0x%08lx -> 0x%08lx)\n",
+		physical_mem_end >> 10, 0ul, physical_mem_end);
+	seq_printf(m, "kernel memory\t: %d kB (0x%08lx -> 0x%08lx)\n",
 		((int)memory_end - (int)_rambase) >> 10,
-		(void *)_rambase,
-		(void *)memory_end);
-	seq_printf(m, "\n");
+		_rambase, memory_end);
 
 	return 0;
 }
@@ -1326,7 +1324,7 @@
 static void *c_start(struct seq_file *m, loff_t *pos)
 {
 	if (*pos == 0)
-		*pos = first_cpu(cpu_online_map);
+		*pos = cpumask_first(cpu_online_mask);
 	if (*pos >= num_online_cpus())
 		return NULL;
 
@@ -1335,7 +1333,7 @@
 
 static void *c_next(struct seq_file *m, void *v, loff_t *pos)
 {
-	*pos = next_cpu(*pos, cpu_online_map);
+	*pos = cpumask_next(*pos, cpu_online_mask);
 
 	return c_start(m, pos);
 }
diff -druN linux-2.6.39-libre/arch/blackfin/kernel/time-ts.c linux-3.0-rc7-libre/arch/blackfin/kernel/time-ts.c
--- linux-2.6.39-libre/arch/blackfin/kernel/time-ts.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/blackfin/kernel/time-ts.c	2011-07-11 19:51:52.000000000 -0400
@@ -23,29 +23,6 @@
 #include <asm/gptimers.h>
 #include <asm/nmi.h>
 
-/* Accelerators for sched_clock()
- * convert from cycles(64bits) => nanoseconds (64bits)
- *  basic equation:
- *		ns = cycles / (freq / ns_per_sec)
- *		ns = cycles * (ns_per_sec / freq)
- *		ns = cycles * (10^9 / (cpu_khz * 10^3))
- *		ns = cycles * (10^6 / cpu_khz)
- *
- *	Then we use scaling math (suggested by george@mvista.com) to get:
- *		ns = cycles * (10^6 * SC / cpu_khz) / SC
- *		ns = cycles * cyc2ns_scale / SC
- *
- *	And since SC is a constant power of two, we can convert the div
- *  into a shift.
- *
- *  We can use khz divisor instead of mhz to keep a better precision, since
- *  cyc2ns_scale is limited to 10^6 * 2^10, which fits in 32 bits.
- *  (mathieu.desnoyers@polymtl.ca)
- *
- *			-johnstul@us.ibm.com "math is hard, lets go shopping!"
- */
-
-#define CYC2NS_SCALE_FACTOR 10 /* 2^10, carefully chosen */
 
 #if defined(CONFIG_CYCLES_CLOCKSOURCE)
 
@@ -63,7 +40,6 @@
 	.rating		= 400,
 	.read		= bfin_read_cycles,
 	.mask		= CLOCKSOURCE_MASK(64),
-	.shift		= CYC2NS_SCALE_FACTOR,
 	.flags		= CLOCK_SOURCE_IS_CONTINUOUS,
 };
 
@@ -75,10 +51,7 @@
 
 static int __init bfin_cs_cycles_init(void)
 {
-	bfin_cs_cycles.mult = \
-		clocksource_hz2mult(get_cclk(), bfin_cs_cycles.shift);
-
-	if (clocksource_register(&bfin_cs_cycles))
+	if (clocksource_register_hz(&bfin_cs_cycles, get_cclk()))
 		panic("failed to register clocksource");
 
 	return 0;
@@ -111,7 +84,6 @@
 	.rating		= 350,
 	.read		= bfin_read_gptimer0,
 	.mask		= CLOCKSOURCE_MASK(32),
-	.shift		= CYC2NS_SCALE_FACTOR,
 	.flags		= CLOCK_SOURCE_IS_CONTINUOUS,
 };
 
@@ -125,10 +97,7 @@
 {
 	setup_gptimer0();
 
-	bfin_cs_gptimer0.mult = \
-		clocksource_hz2mult(get_sclk(), bfin_cs_gptimer0.shift);
-
-	if (clocksource_register(&bfin_cs_gptimer0))
+	if (clocksource_register_hz(&bfin_cs_gptimer0, get_sclk()))
 		panic("failed to register clocksource");
 
 	return 0;
diff -druN linux-2.6.39-libre/arch/blackfin/kernel/vmlinux.lds.S linux-3.0-rc7-libre/arch/blackfin/kernel/vmlinux.lds.S
--- linux-2.6.39-libre/arch/blackfin/kernel/vmlinux.lds.S	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/blackfin/kernel/vmlinux.lds.S	2011-07-11 19:51:52.000000000 -0400
@@ -136,7 +136,7 @@
 
 	. = ALIGN(16);
 	INIT_DATA_SECTION(16)
-	PERCPU(32, PAGE_SIZE)
+	PERCPU_SECTION(32)
 
 	.exit.data :
 	{
@@ -155,14 +155,8 @@
 		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 = .;
+		PERCPU_INPUT(32)
 
 		EXIT_DATA
 		__einitdata = .;
diff -druN linux-2.6.39-libre/arch/blackfin/lib/strncpy.S linux-3.0-rc7-libre/arch/blackfin/lib/strncpy.S
--- linux-2.6.39-libre/arch/blackfin/lib/strncpy.S	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/blackfin/lib/strncpy.S	2011-07-11 19:51:52.000000000 -0400
@@ -25,7 +25,7 @@
 
 ENTRY(_strncpy)
 	CC = R2 == 0;
-	if CC JUMP 4f;
+	if CC JUMP 6f;
 
 	P2 = R2 ;       /* size */
 	P0 = R0 ;       /* dst*/
diff -druN linux-2.6.39-libre/arch/blackfin/mach-bf518/include/mach/anomaly.h linux-3.0-rc7-libre/arch/blackfin/mach-bf518/include/mach/anomaly.h
--- linux-2.6.39-libre/arch/blackfin/mach-bf518/include/mach/anomaly.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/blackfin/mach-bf518/include/mach/anomaly.h	2011-07-11 19:51:52.000000000 -0400
@@ -5,7 +5,7 @@
  * and can be replaced with that version at any time
  * DO NOT EDIT THIS FILE
  *
- * Copyright 2004-2010 Analog Devices Inc.
+ * Copyright 2004-2011 Analog Devices Inc.
  * Licensed under the ADI BSD license.
  *   https://docs.blackfin.uclinux.org/doku.php?id=adi_bsd
  */
@@ -141,6 +141,7 @@
 #define ANOMALY_05000364 (0)
 #define ANOMALY_05000371 (0)
 #define ANOMALY_05000380 (0)
+#define ANOMALY_05000383 (0)
 #define ANOMALY_05000386 (0)
 #define ANOMALY_05000389 (0)
 #define ANOMALY_05000400 (0)
@@ -155,6 +156,7 @@
 #define ANOMALY_05000467 (0)
 #define ANOMALY_05000474 (0)
 #define ANOMALY_05000475 (0)
+#define ANOMALY_05000480 (0)
 #define ANOMALY_05000485 (0)
 
 #endif
diff -druN linux-2.6.39-libre/arch/blackfin/mach-bf518/include/mach/bfin_serial_5xx.h linux-3.0-rc7-libre/arch/blackfin/mach-bf518/include/mach/bfin_serial_5xx.h
--- linux-2.6.39-libre/arch/blackfin/mach-bf518/include/mach/bfin_serial_5xx.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/blackfin/mach-bf518/include/mach/bfin_serial_5xx.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,79 +0,0 @@
-/*
- * Copyright 2008-2009 Analog Devices Inc.
- *
- * Licensed under the GPL-2 or later
- */
-
-#include <asm/dma.h>
-#include <asm/portmux.h>
-
-#if defined(CONFIG_BFIN_UART0_CTSRTS) || defined(CONFIG_BFIN_UART1_CTSRTS)
-# define CONFIG_SERIAL_BFIN_CTSRTS
-
-# ifndef CONFIG_UART0_CTS_PIN
-#  define CONFIG_UART0_CTS_PIN -1
-# endif
-
-# ifndef CONFIG_UART0_RTS_PIN
-#  define CONFIG_UART0_RTS_PIN -1
-# endif
-
-# ifndef CONFIG_UART1_CTS_PIN
-#  define CONFIG_UART1_CTS_PIN -1
-# endif
-
-# ifndef CONFIG_UART1_RTS_PIN
-#  define CONFIG_UART1_RTS_PIN -1
-# endif
-#endif
-
-struct bfin_serial_res {
-	unsigned long uart_base_addr;
-	int uart_irq;
-	int uart_status_irq;
-#ifdef CONFIG_SERIAL_BFIN_DMA
-	unsigned int uart_tx_dma_channel;
-	unsigned int uart_rx_dma_channel;
-#endif
-#ifdef CONFIG_SERIAL_BFIN_CTSRTS
-	int uart_cts_pin;
-	int uart_rts_pin;
-#endif
-};
-
-struct bfin_serial_res bfin_serial_resource[] = {
-#ifdef CONFIG_SERIAL_BFIN_UART0
-	{
-	 0xFFC00400,
-	 IRQ_UART0_RX,
-	 IRQ_UART0_ERROR,
-#ifdef CONFIG_SERIAL_BFIN_DMA
-	 CH_UART0_TX,
-	 CH_UART0_RX,
-#endif
-#ifdef CONFIG_SERIAL_BFIN_CTSRTS
-	 CONFIG_UART0_CTS_PIN,
-	 CONFIG_UART0_RTS_PIN,
-#endif
-	 },
-#endif
-#ifdef CONFIG_SERIAL_BFIN_UART1
-	{
-	 0xFFC02000,
-	 IRQ_UART1_RX,
-	 IRQ_UART1_ERROR,
-#ifdef CONFIG_SERIAL_BFIN_DMA
-	 CH_UART1_TX,
-	 CH_UART1_RX,
-#endif
-#ifdef CONFIG_SERIAL_BFIN_CTSRTS
-	 CONFIG_UART1_CTS_PIN,
-	 CONFIG_UART1_RTS_PIN,
-#endif
-	 },
-#endif
-};
-
-#define DRIVER_NAME "bfin-uart"
-
-#include <asm/bfin_serial.h>
diff -druN linux-2.6.39-libre/arch/blackfin/mach-bf518/include/mach/cdefBF512.h linux-3.0-rc7-libre/arch/blackfin/mach-bf518/include/mach/cdefBF512.h
--- linux-2.6.39-libre/arch/blackfin/mach-bf518/include/mach/cdefBF512.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/blackfin/mach-bf518/include/mach/cdefBF512.h	2011-07-11 19:51:52.000000000 -0400
@@ -990,18 +990,18 @@
 #define bfin_write_PORTG_SLEW(val)		bfin_write16(PORTG_SLEW, val)
 #define bfin_read_PORTH_SLEW()			bfin_read16(PORTH_SLEW)
 #define bfin_write_PORTH_SLEW(val)		bfin_write16(PORTH_SLEW, val)
-#define bfin_read_PORTF_HYSTERISIS()		bfin_read16(PORTF_HYSTERISIS)
-#define bfin_write_PORTF_HYSTERISIS(val)	bfin_write16(PORTF_HYSTERISIS, val)
-#define bfin_read_PORTG_HYSTERISIS()		bfin_read16(PORTG_HYSTERISIS)
-#define bfin_write_PORTG_HYSTERISIS(val)	bfin_write16(PORTG_HYSTERISIS, val)
-#define bfin_read_PORTH_HYSTERISIS()		bfin_read16(PORTH_HYSTERISIS)
-#define bfin_write_PORTH_HYSTERISIS(val)	bfin_write16(PORTH_HYSTERISIS, val)
+#define bfin_read_PORTF_HYSTERESIS()		bfin_read16(PORTF_HYSTERESIS)
+#define bfin_write_PORTF_HYSTERESIS(val)	bfin_write16(PORTF_HYSTERESIS, val)
+#define bfin_read_PORTG_HYSTERESIS()		bfin_read16(PORTG_HYSTERESIS)
+#define bfin_write_PORTG_HYSTERESIS(val)	bfin_write16(PORTG_HYSTERESIS, val)
+#define bfin_read_PORTH_HYSTERESIS()		bfin_read16(PORTH_HYSTERESIS)
+#define bfin_write_PORTH_HYSTERESIS(val)	bfin_write16(PORTH_HYSTERESIS, val)
 #define bfin_read_MISCPORT_DRIVE()		bfin_read16(MISCPORT_DRIVE)
 #define bfin_write_MISCPORT_DRIVE(val)		bfin_write16(MISCPORT_DRIVE, val)
 #define bfin_read_MISCPORT_SLEW()		bfin_read16(MISCPORT_SLEW)
 #define bfin_write_MISCPORT_SLEW(val)		bfin_write16(MISCPORT_SLEW, val)
-#define bfin_read_MISCPORT_HYSTERISIS()		bfin_read16(MISCPORT_HYSTERISIS)
-#define bfin_write_MISCPORT_HYSTERISIS(val)	bfin_write16(MISCPORT_HYSTERISIS, val)
+#define bfin_read_MISCPORT_HYSTERESIS()		bfin_read16(MISCPORT_HYSTERESIS)
+#define bfin_write_MISCPORT_HYSTERESIS(val)	bfin_write16(MISCPORT_HYSTERESIS, val)
 
 /* HOST Port Registers */
 
diff -druN linux-2.6.39-libre/arch/blackfin/mach-bf518/include/mach/defBF512.h linux-3.0-rc7-libre/arch/blackfin/mach-bf518/include/mach/defBF512.h
--- linux-2.6.39-libre/arch/blackfin/mach-bf518/include/mach/defBF512.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/blackfin/mach-bf518/include/mach/defBF512.h	2011-07-11 19:51:52.000000000 -0400
@@ -561,12 +561,12 @@
 #define PORTF_SLEW              0xFFC03230      /* Port F slew control */
 #define PORTG_SLEW              0xFFC03234      /* Port G slew control */
 #define PORTH_SLEW              0xFFC03238      /* Port H slew control */
-#define PORTF_HYSTERISIS        0xFFC03240      /* Port F Schmitt trigger control */
-#define PORTG_HYSTERISIS        0xFFC03244      /* Port G Schmitt trigger control */
-#define PORTH_HYSTERISIS        0xFFC03248      /* Port H Schmitt trigger control */
+#define PORTF_HYSTERESIS        0xFFC03240      /* Port F Schmitt trigger control */
+#define PORTG_HYSTERESIS        0xFFC03244      /* Port G Schmitt trigger control */
+#define PORTH_HYSTERESIS        0xFFC03248      /* Port H Schmitt trigger control */
 #define MISCPORT_DRIVE          0xFFC03280      /* Misc Port drive strength control */
 #define MISCPORT_SLEW           0xFFC03284      /* Misc Port slew control */
-#define MISCPORT_HYSTERISIS     0xFFC03288      /* Misc Port Schmitt trigger control */
+#define MISCPORT_HYSTERESIS     0xFFC03288      /* Misc Port Schmitt trigger control */
 
 
 /***********************************************************************************
diff -druN linux-2.6.39-libre/arch/blackfin/mach-bf518/include/mach/defBF514.h linux-3.0-rc7-libre/arch/blackfin/mach-bf518/include/mach/defBF514.h
--- linux-2.6.39-libre/arch/blackfin/mach-bf518/include/mach/defBF514.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/blackfin/mach-bf518/include/mach/defBF514.h	2011-07-11 19:51:52.000000000 -0400
@@ -36,13 +36,13 @@
 #define RSI_EMASK                      0xFFC038C4 /* RSI Exception Mask Register */
 #define RSI_CONFIG                     0xFFC038C8 /* RSI Configuration Register */
 #define RSI_RD_WAIT_EN                 0xFFC038CC /* RSI Read Wait Enable Register */
-#define RSI_PID0                       0xFFC03FE0 /* RSI Peripheral ID Register 0 */
-#define RSI_PID1                       0xFFC03FE4 /* RSI Peripheral ID Register 1 */
-#define RSI_PID2                       0xFFC03FE8 /* RSI Peripheral ID Register 2 */
-#define RSI_PID3                       0xFFC03FEC /* RSI Peripheral ID Register 3 */
-#define RSI_PID4                       0xFFC03FF0 /* RSI Peripheral ID Register 4 */
-#define RSI_PID5                       0xFFC03FF4 /* RSI Peripheral ID Register 5 */
-#define RSI_PID6                       0xFFC03FF8 /* RSI Peripheral ID Register 6 */
-#define RSI_PID7                       0xFFC03FFC /* RSI Peripheral ID Register 7 */
+#define RSI_PID0                       0xFFC038D0 /* RSI Peripheral ID Register 0 */
+#define RSI_PID1                       0xFFC038D4 /* RSI Peripheral ID Register 1 */
+#define RSI_PID2                       0xFFC038D8 /* RSI Peripheral ID Register 2 */
+#define RSI_PID3                       0xFFC038DC /* RSI Peripheral ID Register 3 */
+#define RSI_PID4                       0xFFC038E0 /* RSI Peripheral ID Register 0 */
+#define RSI_PID5                       0xFFC038E4 /* RSI Peripheral ID Register 1 */
+#define RSI_PID6                       0xFFC038E8 /* RSI Peripheral ID Register 2 */
+#define RSI_PID7                       0xFFC038EC /* RSI Peripheral ID Register 3 */
 
 #endif /* _DEF_BF514_H */
diff -druN linux-2.6.39-libre/arch/blackfin/mach-bf518/include/mach/irq.h linux-3.0-rc7-libre/arch/blackfin/mach-bf518/include/mach/irq.h
--- linux-2.6.39-libre/arch/blackfin/mach-bf518/include/mach/irq.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/blackfin/mach-bf518/include/mach/irq.h	2011-07-11 19:51:52.000000000 -0400
@@ -7,38 +7,9 @@
 #ifndef _BF518_IRQ_H_
 #define _BF518_IRQ_H_
 
-/*
- * Interrupt source definitions
-	Event Source    Core Event Name
-	Core        Emulation               **
-	Events         (highest priority)  EMU         0
-	Reset                   RST         1
-	NMI                     NMI         2
-	Exception               EVX         3
-	Reserved                --          4
-	Hardware Error          IVHW        5
-	Core Timer              IVTMR       6 *
-
-	.....
-
-	 Software Interrupt 1    IVG14       31
-	 Software Interrupt 2    --
-	 (lowest priority)  IVG15       32 *
-*/
-
-#define NR_PERI_INTS    (2 * 32)
-
-/* The ABSTRACT IRQ definitions */
-/** the first seven of the following are fixed, the rest you change if you need to **/
-#define IRQ_EMU			0	/* Emulation */
-#define IRQ_RST			1	/* reset */
-#define IRQ_NMI			2	/* Non Maskable */
-#define IRQ_EVX			3	/* Exception */
-#define IRQ_UNUSED		4	/* - unused interrupt */
-#define IRQ_HWERR		5	/* Hardware Error */
-#define IRQ_CORETMR		6	/* Core timer */
+#include <mach-common/irq.h>
 
-#define BFIN_IRQ(x)		((x) + 7)
+#define NR_PERI_INTS		(2 * 32)
 
 #define IRQ_PLL_WAKEUP		BFIN_IRQ(0)	/* PLL Wakeup Interrupt */
 #define IRQ_DMA0_ERROR		BFIN_IRQ(1)	/* DMA Error 0 (generic) */
@@ -54,23 +25,23 @@
 #define IRQ_UART0_ERROR		BFIN_IRQ(12)	/* UART0 Status */
 #define IRQ_UART1_ERROR		BFIN_IRQ(13)	/* UART1 Status */
 #define IRQ_RTC			BFIN_IRQ(14)	/* RTC */
-#define IRQ_PPI      		BFIN_IRQ(15)	/* DMA Channel 0 (PPI) */
+#define IRQ_PPI			BFIN_IRQ(15)	/* DMA Channel 0 (PPI) */
 #define IRQ_SPORT0_RX		BFIN_IRQ(16)	/* DMA 3 Channel (SPORT0 RX) */
 #define IRQ_SPORT0_TX		BFIN_IRQ(17)	/* DMA 4 Channel (SPORT0 TX) */
 #define IRQ_RSI			BFIN_IRQ(17)	/* DMA 4 Channel (RSI) */
 #define IRQ_SPORT1_RX		BFIN_IRQ(18)	/* DMA 5 Channel (SPORT1 RX/SPI) */
 #define IRQ_SPI1		BFIN_IRQ(18)	/* DMA 5 Channel (SPI1) */
 #define IRQ_SPORT1_TX		BFIN_IRQ(19)	/* DMA 6 Channel (SPORT1 TX) */
-#define IRQ_TWI      		BFIN_IRQ(20)	/* TWI */
-#define IRQ_SPI0     		BFIN_IRQ(21)	/* DMA 7 Channel (SPI0) */
-#define IRQ_UART0_RX 		BFIN_IRQ(22)	/* DMA8 Channel (UART0 RX) */
-#define IRQ_UART0_TX 		BFIN_IRQ(23)	/* DMA9 Channel (UART0 TX) */
-#define IRQ_UART1_RX 		BFIN_IRQ(24)	/* DMA10 Channel (UART1 RX) */
-#define IRQ_UART1_TX 		BFIN_IRQ(25)	/* DMA11 Channel (UART1 TX) */
-#define IRQ_OPTSEC   		BFIN_IRQ(26)	/* OTPSEC Interrupt */
-#define IRQ_CNT   		BFIN_IRQ(27)	/* GP Counter */
-#define IRQ_MAC_RX   		BFIN_IRQ(28)	/* DMA1 Channel (MAC RX) */
-#define IRQ_PORTH_INTA   	BFIN_IRQ(29)	/* Port H Interrupt A */
+#define IRQ_TWI			BFIN_IRQ(20)	/* TWI */
+#define IRQ_SPI0		BFIN_IRQ(21)	/* DMA 7 Channel (SPI0) */
+#define IRQ_UART0_RX		BFIN_IRQ(22)	/* DMA8 Channel (UART0 RX) */
+#define IRQ_UART0_TX		BFIN_IRQ(23)	/* DMA9 Channel (UART0 TX) */
+#define IRQ_UART1_RX		BFIN_IRQ(24)	/* DMA10 Channel (UART1 RX) */
+#define IRQ_UART1_TX		BFIN_IRQ(25)	/* DMA11 Channel (UART1 TX) */
+#define IRQ_OPTSEC		BFIN_IRQ(26)	/* OTPSEC Interrupt */
+#define IRQ_CNT			BFIN_IRQ(27)	/* GP Counter */
+#define IRQ_MAC_RX		BFIN_IRQ(28)	/* DMA1 Channel (MAC RX) */
+#define IRQ_PORTH_INTA		BFIN_IRQ(29)	/* Port H Interrupt A */
 #define IRQ_MAC_TX		BFIN_IRQ(30)	/* DMA2 Channel (MAC TX) */
 #define IRQ_PORTH_INTB		BFIN_IRQ(31)	/* Port H Interrupt B */
 #define IRQ_TIMER0		BFIN_IRQ(32)	/* Timer 0 */
@@ -96,101 +67,90 @@
 #define IRQ_PWM_SYNC		BFIN_IRQ(54)	/* PWM Sync Interrupt */
 #define IRQ_PTP_STAT		BFIN_IRQ(55)	/* PTP Stat Interrupt */
 
-#define SYS_IRQS        	BFIN_IRQ(63)	/* 70 */
-
-#define IRQ_PF0         71
-#define IRQ_PF1         72
-#define IRQ_PF2         73
-#define IRQ_PF3         74
-#define IRQ_PF4         75
-#define IRQ_PF5         76
-#define IRQ_PF6         77
-#define IRQ_PF7         78
-#define IRQ_PF8         79
-#define IRQ_PF9         80
-#define IRQ_PF10        81
-#define IRQ_PF11        82
-#define IRQ_PF12        83
-#define IRQ_PF13        84
-#define IRQ_PF14        85
-#define IRQ_PF15        86
+#define SYS_IRQS		BFIN_IRQ(63)	/* 70 */
 
-#define IRQ_PG0         87
-#define IRQ_PG1         88
-#define IRQ_PG2         89
-#define IRQ_PG3         90
-#define IRQ_PG4         91
-#define IRQ_PG5         92
-#define IRQ_PG6         93
-#define IRQ_PG7         94
-#define IRQ_PG8         95
-#define IRQ_PG9         96
-#define IRQ_PG10        97
-#define IRQ_PG11        98
-#define IRQ_PG12        99
-#define IRQ_PG13        100
-#define IRQ_PG14        101
-#define IRQ_PG15        102
+#define IRQ_PF0			71
+#define IRQ_PF1			72
+#define IRQ_PF2			73
+#define IRQ_PF3			74
+#define IRQ_PF4			75
+#define IRQ_PF5			76
+#define IRQ_PF6			77
+#define IRQ_PF7			78
+#define IRQ_PF8			79
+#define IRQ_PF9			80
+#define IRQ_PF10		81
+#define IRQ_PF11		82
+#define IRQ_PF12		83
+#define IRQ_PF13		84
+#define IRQ_PF14		85
+#define IRQ_PF15		86
 
-#define IRQ_PH0         103
-#define IRQ_PH1         104
-#define IRQ_PH2         105
-#define IRQ_PH3         106
-#define IRQ_PH4         107
-#define IRQ_PH5         108
-#define IRQ_PH6         109
-#define IRQ_PH7         110
-#define IRQ_PH8         111
-#define IRQ_PH9         112
-#define IRQ_PH10        113
-#define IRQ_PH11        114
-#define IRQ_PH12        115
-#define IRQ_PH13        116
-#define IRQ_PH14        117
-#define IRQ_PH15        118
+#define IRQ_PG0			87
+#define IRQ_PG1			88
+#define IRQ_PG2			89
+#define IRQ_PG3			90
+#define IRQ_PG4			91
+#define IRQ_PG5			92
+#define IRQ_PG6			93
+#define IRQ_PG7			94
+#define IRQ_PG8			95
+#define IRQ_PG9			96
+#define IRQ_PG10		97
+#define IRQ_PG11		98
+#define IRQ_PG12		99
+#define IRQ_PG13		100
+#define IRQ_PG14		101
+#define IRQ_PG15		102
 
-#define GPIO_IRQ_BASE	IRQ_PF0
+#define IRQ_PH0			103
+#define IRQ_PH1			104
+#define IRQ_PH2			105
+#define IRQ_PH3			106
+#define IRQ_PH4			107
+#define IRQ_PH5			108
+#define IRQ_PH6			109
+#define IRQ_PH7			110
+#define IRQ_PH8			111
+#define IRQ_PH9			112
+#define IRQ_PH10		113
+#define IRQ_PH11		114
+#define IRQ_PH12		115
+#define IRQ_PH13		116
+#define IRQ_PH14		117
+#define IRQ_PH15		118
 
-#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 GPIO_IRQ_BASE		IRQ_PF0
 
-#define NR_MACH_IRQS	(IRQ_MAC_STMDONE + 1)
-#define NR_IRQS		(NR_MACH_IRQS + NR_SPARE_IRQS)
+#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 IVG7            7
-#define IVG8            8
-#define IVG9            9
-#define IVG10           10
-#define IVG11           11
-#define IVG12           12
-#define IVG13           13
-#define IVG14           14
-#define IVG15           15
+#define NR_MACH_IRQS		(IRQ_MAC_STMDONE + 1)
 
 /* IAR0 BIT FIELDS */
 #define IRQ_PLL_WAKEUP_POS	0
 #define IRQ_DMA0_ERROR_POS	4
-#define IRQ_DMAR0_BLK_POS 	8
-#define IRQ_DMAR1_BLK_POS 	12
-#define IRQ_DMAR0_OVR_POS 	16
-#define IRQ_DMAR1_OVR_POS 	20
-#define IRQ_PPI_ERROR_POS 	24
-#define IRQ_MAC_ERROR_POS 	28
+#define IRQ_DMAR0_BLK_POS	8
+#define IRQ_DMAR1_BLK_POS	12
+#define IRQ_DMAR0_OVR_POS	16
+#define IRQ_DMAR1_OVR_POS	20
+#define IRQ_PPI_ERROR_POS	24
+#define IRQ_MAC_ERROR_POS	28
 
 /* IAR1 BIT FIELDS */
 #define IRQ_SPORT0_ERROR_POS	0
 #define IRQ_SPORT1_ERROR_POS	4
 #define IRQ_PTP_ERROR_POS	8
-#define IRQ_UART0_ERROR_POS 	16
-#define IRQ_UART1_ERROR_POS 	20
-#define IRQ_RTC_POS         	24
-#define IRQ_PPI_POS         	28
+#define IRQ_UART0_ERROR_POS	16
+#define IRQ_UART1_ERROR_POS	20
+#define IRQ_RTC_POS		24
+#define IRQ_PPI_POS		28
 
 /* IAR2 BIT FIELDS */
 #define IRQ_SPORT0_RX_POS	0
@@ -199,19 +159,19 @@
 #define IRQ_SPORT1_RX_POS	8
 #define IRQ_SPI1_POS		8
 #define IRQ_SPORT1_TX_POS	12
-#define IRQ_TWI_POS      	16
-#define IRQ_SPI0_POS      	20
-#define IRQ_UART0_RX_POS 	24
-#define IRQ_UART0_TX_POS 	28
+#define IRQ_TWI_POS		16
+#define IRQ_SPI0_POS		20
+#define IRQ_UART0_RX_POS	24
+#define IRQ_UART0_TX_POS	28
 
 /* IAR3 BIT FIELDS */
-#define IRQ_UART1_RX_POS  	0
-#define IRQ_UART1_TX_POS  	4
-#define IRQ_OPTSEC_POS    	8
-#define IRQ_CNT_POS       	12
-#define IRQ_MAC_RX_POS    	16
+#define IRQ_UART1_RX_POS	0
+#define IRQ_UART1_TX_POS	4
+#define IRQ_OPTSEC_POS		8
+#define IRQ_CNT_POS		12
+#define IRQ_MAC_RX_POS		16
 #define IRQ_PORTH_INTA_POS	20
-#define IRQ_MAC_TX_POS    	24
+#define IRQ_MAC_TX_POS		24
 #define IRQ_PORTH_INTB_POS	28
 
 /* IAR4 BIT FIELDS */
@@ -227,19 +187,19 @@
 /* IAR5 BIT FIELDS */
 #define IRQ_PORTG_INTA_POS	0
 #define IRQ_PORTG_INTB_POS	4
-#define IRQ_MEM_DMA0_POS  	8
-#define IRQ_MEM_DMA1_POS  	12
-#define IRQ_WATCH_POS     	16
+#define IRQ_MEM_DMA0_POS	8
+#define IRQ_MEM_DMA1_POS	12
+#define IRQ_WATCH_POS		16
 #define IRQ_PORTF_INTA_POS	20
 #define IRQ_PORTF_INTB_POS	24
-#define IRQ_SPI0_ERROR_POS 	28
+#define IRQ_SPI0_ERROR_POS	28
 
 /* IAR6 BIT FIELDS */
-#define IRQ_SPI1_ERROR_POS  	0
-#define IRQ_RSI_INT0_POS   	12
-#define IRQ_RSI_INT1_POS   	16
-#define IRQ_PWM_TRIP_POS   	20
-#define IRQ_PWM_SYNC_POS   	24
-#define IRQ_PTP_STAT_POS    	28
+#define IRQ_SPI1_ERROR_POS	0
+#define IRQ_RSI_INT0_POS	12
+#define IRQ_RSI_INT1_POS	16
+#define IRQ_PWM_TRIP_POS	20
+#define IRQ_PWM_SYNC_POS	24
+#define IRQ_PTP_STAT_POS	28
 
-#endif				/* _BF518_IRQ_H_ */
+#endif
diff -druN linux-2.6.39-libre/arch/blackfin/mach-bf527/boards/ezkit.c linux-3.0-rc7-libre/arch/blackfin/mach-bf527/boards/ezkit.c
--- linux-2.6.39-libre/arch/blackfin/mach-bf527/boards/ezkit.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/blackfin/mach-bf527/boards/ezkit.c	2011-07-11 19:51:52.000000000 -0400
@@ -26,6 +26,7 @@
 #include <asm/portmux.h>
 #include <asm/dpmc.h>
 #include <linux/spi/ad7877.h>
+#include <asm/bfin_sport.h>
 
 /*
  * Name the Board for the /proc/cpuinfo
@@ -526,11 +527,69 @@
 };
 #endif
 
+#if defined(CONFIG_SND_BF5XX_I2S) || defined(CONFIG_SND_BF5XX_I2S_MODULE) || \
+	defined(CONFIG_SND_BF5XX_TDM) || defined(CONFIG_SND_BF5XX_TDM_MODULE)
+
+static const u16 bfin_snd_pin[][7] = {
+	{P_SPORT0_DTPRI, P_SPORT0_TSCLK, P_SPORT0_RFS,
+		P_SPORT0_DRPRI, P_SPORT0_RSCLK, 0, 0},
+	{P_SPORT1_DTPRI, P_SPORT1_TSCLK, P_SPORT1_RFS,
+		P_SPORT1_DRPRI, P_SPORT1_RSCLK, P_SPORT1_TFS, 0},
+};
+
+static struct bfin_snd_platform_data bfin_snd_data[] = {
+	{
+		.pin_req = &bfin_snd_pin[0][0],
+	},
+	{
+		.pin_req = &bfin_snd_pin[1][0],
+	},
+};
+
+#define BFIN_SND_RES(x) \
+	[x] = { \
+		{ \
+			.start = SPORT##x##_TCR1, \
+			.end = SPORT##x##_TCR1, \
+			.flags = IORESOURCE_MEM \
+		}, \
+		{ \
+			.start = CH_SPORT##x##_RX, \
+			.end = CH_SPORT##x##_RX, \
+			.flags = IORESOURCE_DMA, \
+		}, \
+		{ \
+			.start = CH_SPORT##x##_TX, \
+			.end = CH_SPORT##x##_TX, \
+			.flags = IORESOURCE_DMA, \
+		}, \
+		{ \
+			.start = IRQ_SPORT##x##_ERROR, \
+			.end = IRQ_SPORT##x##_ERROR, \
+			.flags = IORESOURCE_IRQ, \
+		} \
+	}
+
+static struct resource bfin_snd_resources[][4] = {
+	BFIN_SND_RES(0),
+	BFIN_SND_RES(1),
+};
+
+static struct platform_device bfin_pcm = {
+	.name = "bfin-pcm-audio",
+	.id = -1,
+};
+#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 */
+	.num_resources = ARRAY_SIZE(bfin_snd_resources[CONFIG_SND_BF5XX_SPORT_NUM]),
+	.resource = bfin_snd_resources[CONFIG_SND_BF5XX_SPORT_NUM],
+	.dev = {
+		.platform_data = &bfin_snd_data[CONFIG_SND_BF5XX_SPORT_NUM],
+	},
 };
 #endif
 
@@ -538,7 +597,11 @@
 static struct platform_device bfin_tdm = {
 	.name = "bfin-tdm",
 	.id = CONFIG_SND_BF5XX_SPORT_NUM,
-	/* TODO: add platform data here */
+	.num_resources = ARRAY_SIZE(bfin_snd_resources[CONFIG_SND_BF5XX_SPORT_NUM]),
+	.resource = bfin_snd_resources[CONFIG_SND_BF5XX_SPORT_NUM],
+	.dev = {
+		.platform_data = &bfin_snd_data[CONFIG_SND_BF5XX_SPORT_NUM],
+	},
 };
 #endif
 
@@ -583,7 +646,9 @@
 		.max_speed_hz = 3125000,     /* max spi clock (SCK) speed in HZ */
 		.bus_num = 0,
 		.chip_select = 4,
+		.platform_data = "ad1836",
 		.controller_data = &ad1836_spi_chip_info,
+		.mode = SPI_MODE_3,
 	},
 #endif
 #if defined(CONFIG_MMC_SPI) || defined(CONFIG_MMC_SPI_MODULE)
@@ -1211,6 +1276,11 @@
 	&ezkit_flash_device,
 #endif
 
+#if defined(CONFIG_SND_BF5XX_I2S) || defined(CONFIG_SND_BF5XX_I2S_MODULE) || \
+	defined(CONFIG_SND_BF5XX_TDM) || defined(CONFIG_SND_BF5XX_TDM_MODULE)
+	&bfin_pcm,
+#endif
+
 #if defined(CONFIG_SND_BF5XX_I2S) || defined(CONFIG_SND_BF5XX_I2S_MODULE)
 	&bfin_i2s,
 #endif
diff -druN linux-2.6.39-libre/arch/blackfin/mach-bf527/include/mach/anomaly.h linux-3.0-rc7-libre/arch/blackfin/mach-bf527/include/mach/anomaly.h
--- linux-2.6.39-libre/arch/blackfin/mach-bf527/include/mach/anomaly.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/blackfin/mach-bf527/include/mach/anomaly.h	2011-07-11 19:51:52.000000000 -0400
@@ -5,14 +5,14 @@
  * and can be replaced with that version at any time
  * DO NOT EDIT THIS FILE
  *
- * Copyright 2004-2010 Analog Devices Inc.
+ * Copyright 2004-2011 Analog Devices Inc.
  * Licensed under the ADI BSD license.
  *   https://docs.blackfin.uclinux.org/doku.php?id=adi_bsd
  */
 
 /* This file should be up to date with:
  *  - Revision E, 03/15/2010; ADSP-BF526 Blackfin Processor Anomaly List
- *  - Revision G, 08/25/2009; ADSP-BF527 Blackfin Processor Anomaly List
+ *  - Revision H, 04/29/2010; ADSP-BF527 Blackfin Processor Anomaly List
  */
 
 #ifndef _MACH_ANOMALY_H_
@@ -220,6 +220,8 @@
 #define ANOMALY_05000483 (1)
 /* PLL_CTL Change Using bfrom_SysControl() Can Result in Processor Overclocking */
 #define ANOMALY_05000485 (_ANOMALY_BF526_BF527(< 2, < 3))
+/* The CODEC Zero-Cross Detect Feature is not Functional */
+#define ANOMALY_05000487 (1)
 /* IFLUSH sucks at life */
 #define ANOMALY_05000491 (1)
 
@@ -268,11 +270,13 @@
 #define ANOMALY_05000323 (0)
 #define ANOMALY_05000362 (1)
 #define ANOMALY_05000363 (0)
+#define ANOMALY_05000383 (0)
 #define ANOMALY_05000400 (0)
 #define ANOMALY_05000402 (0)
 #define ANOMALY_05000412 (0)
 #define ANOMALY_05000447 (0)
 #define ANOMALY_05000448 (0)
 #define ANOMALY_05000474 (0)
+#define ANOMALY_05000480 (0)
 
 #endif
diff -druN linux-2.6.39-libre/arch/blackfin/mach-bf527/include/mach/bfin_serial_5xx.h linux-3.0-rc7-libre/arch/blackfin/mach-bf527/include/mach/bfin_serial_5xx.h
--- linux-2.6.39-libre/arch/blackfin/mach-bf527/include/mach/bfin_serial_5xx.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/blackfin/mach-bf527/include/mach/bfin_serial_5xx.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,79 +0,0 @@
-/*
- * Copyright 2007-2009 Analog Devices Inc.
- *
- * Licensed under the GPL-2 or later
- */
-
-#include <asm/dma.h>
-#include <asm/portmux.h>
-
-#if defined(CONFIG_BFIN_UART0_CTSRTS) || defined(CONFIG_BFIN_UART1_CTSRTS)
-# define CONFIG_SERIAL_BFIN_CTSRTS
-
-# ifndef CONFIG_UART0_CTS_PIN
-#  define CONFIG_UART0_CTS_PIN -1
-# endif
-
-# ifndef CONFIG_UART0_RTS_PIN
-#  define CONFIG_UART0_RTS_PIN -1
-# endif
-
-# ifndef CONFIG_UART1_CTS_PIN
-#  define CONFIG_UART1_CTS_PIN -1
-# endif
-
-# ifndef CONFIG_UART1_RTS_PIN
-#  define CONFIG_UART1_RTS_PIN -1
-# endif
-#endif
-
-struct bfin_serial_res {
-	unsigned long uart_base_addr;
-	int uart_irq;
-	int uart_status_irq;
-#ifdef CONFIG_SERIAL_BFIN_DMA
-	unsigned int uart_tx_dma_channel;
-	unsigned int uart_rx_dma_channel;
-#endif
-#ifdef CONFIG_SERIAL_BFIN_CTSRTS
-	int uart_cts_pin;
-	int uart_rts_pin;
-#endif
-};
-
-struct bfin_serial_res bfin_serial_resource[] = {
-#ifdef CONFIG_SERIAL_BFIN_UART0
-	{
-	 0xFFC00400,
-	 IRQ_UART0_RX,
-	 IRQ_UART0_ERROR,
-#ifdef CONFIG_SERIAL_BFIN_DMA
-	 CH_UART0_TX,
-	 CH_UART0_RX,
-#endif
-#ifdef CONFIG_SERIAL_BFIN_CTSRTS
-	 CONFIG_UART0_CTS_PIN,
-	 CONFIG_UART0_RTS_PIN,
-#endif
-	 },
-#endif
-#ifdef CONFIG_SERIAL_BFIN_UART1
-	{
-	 0xFFC02000,
-	 IRQ_UART1_RX,
-	 IRQ_UART1_ERROR,
-#ifdef CONFIG_SERIAL_BFIN_DMA
-	 CH_UART1_TX,
-	 CH_UART1_RX,
-#endif
-#ifdef CONFIG_SERIAL_BFIN_CTSRTS
-	 CONFIG_UART1_CTS_PIN,
-	 CONFIG_UART1_RTS_PIN,
-#endif
-	 },
-#endif
-};
-
-#define DRIVER_NAME "bfin-uart"
-
-#include <asm/bfin_serial.h>
diff -druN linux-2.6.39-libre/arch/blackfin/mach-bf527/include/mach/cdefBF522.h linux-3.0-rc7-libre/arch/blackfin/mach-bf527/include/mach/cdefBF522.h
--- linux-2.6.39-libre/arch/blackfin/mach-bf527/include/mach/cdefBF522.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/blackfin/mach-bf527/include/mach/cdefBF522.h	2011-07-11 19:51:52.000000000 -0400
@@ -1007,18 +1007,18 @@
 #define bfin_write_PORTG_SLEW(val)		bfin_write16(PORTG_SLEW, val)
 #define bfin_read_PORTH_SLEW()			bfin_read16(PORTH_SLEW)
 #define bfin_write_PORTH_SLEW(val)		bfin_write16(PORTH_SLEW, val)
-#define bfin_read_PORTF_HYSTERISIS()		bfin_read16(PORTF_HYSTERISIS)
-#define bfin_write_PORTF_HYSTERISIS(val)	bfin_write16(PORTF_HYSTERISIS, val)
-#define bfin_read_PORTG_HYSTERISIS()		bfin_read16(PORTG_HYSTERISIS)
-#define bfin_write_PORTG_HYSTERISIS(val)	bfin_write16(PORTG_HYSTERISIS, val)
-#define bfin_read_PORTH_HYSTERISIS()		bfin_read16(PORTH_HYSTERISIS)
-#define bfin_write_PORTH_HYSTERISIS(val)	bfin_write16(PORTH_HYSTERISIS, val)
+#define bfin_read_PORTF_HYSTERESIS()		bfin_read16(PORTF_HYSTERESIS)
+#define bfin_write_PORTF_HYSTERESIS(val)	bfin_write16(PORTF_HYSTERESIS, val)
+#define bfin_read_PORTG_HYSTERESIS()		bfin_read16(PORTG_HYSTERESIS)
+#define bfin_write_PORTG_HYSTERESIS(val)	bfin_write16(PORTG_HYSTERESIS, val)
+#define bfin_read_PORTH_HYSTERESIS()		bfin_read16(PORTH_HYSTERESIS)
+#define bfin_write_PORTH_HYSTERESIS(val)	bfin_write16(PORTH_HYSTERESIS, val)
 #define bfin_read_MISCPORT_DRIVE()		bfin_read16(MISCPORT_DRIVE)
 #define bfin_write_MISCPORT_DRIVE(val)		bfin_write16(MISCPORT_DRIVE, val)
 #define bfin_read_MISCPORT_SLEW()		bfin_read16(MISCPORT_SLEW)
 #define bfin_write_MISCPORT_SLEW(val)		bfin_write16(MISCPORT_SLEW, val)
-#define bfin_read_MISCPORT_HYSTERISIS()		bfin_read16(MISCPORT_HYSTERISIS)
-#define bfin_write_MISCPORT_HYSTERISIS(val)	bfin_write16(MISCPORT_HYSTERISIS, val)
+#define bfin_read_MISCPORT_HYSTERESIS()		bfin_read16(MISCPORT_HYSTERESIS)
+#define bfin_write_MISCPORT_HYSTERESIS(val)	bfin_write16(MISCPORT_HYSTERESIS, val)
 
 /* HOST Port Registers */
 
diff -druN linux-2.6.39-libre/arch/blackfin/mach-bf527/include/mach/defBF522.h linux-3.0-rc7-libre/arch/blackfin/mach-bf527/include/mach/defBF522.h
--- linux-2.6.39-libre/arch/blackfin/mach-bf527/include/mach/defBF522.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/blackfin/mach-bf527/include/mach/defBF522.h	2011-07-11 19:51:52.000000000 -0400
@@ -562,12 +562,12 @@
 #define PORTF_SLEW              0xFFC03230      /* Port F slew control */
 #define PORTG_SLEW              0xFFC03234      /* Port G slew control */
 #define PORTH_SLEW              0xFFC03238      /* Port H slew control */
-#define PORTF_HYSTERISIS        0xFFC03240      /* Port F Schmitt trigger control */
-#define PORTG_HYSTERISIS        0xFFC03244      /* Port G Schmitt trigger control */
-#define PORTH_HYSTERISIS        0xFFC03248      /* Port H Schmitt trigger control */
+#define PORTF_HYSTERESIS        0xFFC03240      /* Port F Schmitt trigger control */
+#define PORTG_HYSTERESIS        0xFFC03244      /* Port G Schmitt trigger control */
+#define PORTH_HYSTERESIS        0xFFC03248      /* Port H Schmitt trigger control */
 #define MISCPORT_DRIVE          0xFFC03280      /* Misc Port drive strength control */
 #define MISCPORT_SLEW           0xFFC03284      /* Misc Port slew control */
-#define MISCPORT_HYSTERISIS     0xFFC03288      /* Misc Port Schmitt trigger control */
+#define MISCPORT_HYSTERESIS     0xFFC03288      /* Misc Port Schmitt trigger control */
 
 
 /***********************************************************************************
diff -druN linux-2.6.39-libre/arch/blackfin/mach-bf527/include/mach/defBF525.h linux-3.0-rc7-libre/arch/blackfin/mach-bf527/include/mach/defBF525.h
--- linux-2.6.39-libre/arch/blackfin/mach-bf527/include/mach/defBF525.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/blackfin/mach-bf527/include/mach/defBF525.h	2011-07-11 19:51:52.000000000 -0400
@@ -185,8 +185,8 @@
 #define                USB_EP_NI7_TXTYPE  0xffc03bd4   /* Sets the transaction protocol and peripheral endpoint number for the Host Tx endpoint7 */
 #define            USB_EP_NI7_TXINTERVAL  0xffc03bd8   /* Sets the NAK response timeout on Endpoint7 */
 #define                USB_EP_NI7_RXTYPE  0xffc03bdc   /* Sets the transaction protocol and peripheral endpoint number for the Host Rx endpoint7 */
-#define            USB_EP_NI7_RXINTERVAL  0xffc03bf0   /* Sets the polling interval for Interrupt/Isochronous transfers or the NAK response timeout on Bulk transfers for Host Rx endpoint7 */
-#define               USB_EP_NI7_TXCOUNT  0xffc03bf8   /* Number of bytes to be written to the endpoint7 Tx FIFO */
+#define            USB_EP_NI7_RXINTERVAL  0xffc03be0   /* Sets the polling interval for Interrupt/Isochronous transfers or the NAK response timeout on Bulk transfers for Host Rx endpoint7 */
+#define               USB_EP_NI7_TXCOUNT  0xffc03be8   /* Number of bytes to be written to the endpoint7 Tx FIFO */
 
 #define                USB_DMA_INTERRUPT  0xffc03c00   /* Indicates pending interrupts for the DMA channels */
 
diff -druN linux-2.6.39-libre/arch/blackfin/mach-bf527/include/mach/irq.h linux-3.0-rc7-libre/arch/blackfin/mach-bf527/include/mach/irq.h
--- linux-2.6.39-libre/arch/blackfin/mach-bf527/include/mach/irq.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/blackfin/mach-bf527/include/mach/irq.h	2011-07-11 19:51:52.000000000 -0400
@@ -7,38 +7,9 @@
 #ifndef _BF527_IRQ_H_
 #define _BF527_IRQ_H_
 
-/*
- * Interrupt source definitions
-	Event Source    Core Event Name
-	Core        Emulation               **
-	Events         (highest priority)  EMU         0
-	Reset                   RST         1
-	NMI                     NMI         2
-	Exception               EVX         3
-	Reserved                --          4
-	Hardware Error          IVHW        5
-	Core Timer              IVTMR       6 *
-
-	.....
-
-	 Software Interrupt 1    IVG14       31
-	 Software Interrupt 2    --
-	 (lowest priority)  IVG15       32 *
-*/
-
-#define NR_PERI_INTS    (2 * 32)
-
-/* The ABSTRACT IRQ definitions */
-/** the first seven of the following are fixed, the rest you change if you need to **/
-#define IRQ_EMU			0	/* Emulation */
-#define IRQ_RST			1	/* reset */
-#define IRQ_NMI			2	/* Non Maskable */
-#define IRQ_EVX			3	/* Exception */
-#define IRQ_UNUSED		4	/* - unused interrupt */
-#define IRQ_HWERR		5	/* Hardware Error */
-#define IRQ_CORETMR		6	/* Core timer */
+#include <mach-common/irq.h>
 
-#define BFIN_IRQ(x)		((x) + 7)
+#define NR_PERI_INTS		(2 * 32)
 
 #define IRQ_PLL_WAKEUP		BFIN_IRQ(0)	/* PLL Wakeup Interrupt */
 #define IRQ_DMA0_ERROR		BFIN_IRQ(1)	/* DMA Error 0 (generic) */
@@ -53,21 +24,21 @@
 #define IRQ_UART0_ERROR		BFIN_IRQ(12)	/* UART0 Status */
 #define IRQ_UART1_ERROR		BFIN_IRQ(13)	/* UART1 Status */
 #define IRQ_RTC			BFIN_IRQ(14)	/* RTC */
-#define IRQ_PPI      		BFIN_IRQ(15)	/* DMA Channel 0 (PPI/NAND) */
+#define IRQ_PPI			BFIN_IRQ(15)	/* DMA Channel 0 (PPI/NAND) */
 #define IRQ_SPORT0_RX		BFIN_IRQ(16)	/* DMA 3 Channel (SPORT0 RX) */
 #define IRQ_SPORT0_TX		BFIN_IRQ(17)	/* DMA 4 Channel (SPORT0 TX) */
 #define IRQ_SPORT1_RX		BFIN_IRQ(18)	/* DMA 5 Channel (SPORT1 RX) */
 #define IRQ_SPORT1_TX		BFIN_IRQ(19)	/* DMA 6 Channel (SPORT1 TX) */
-#define IRQ_TWI      		BFIN_IRQ(20)	/* TWI */
-#define IRQ_SPI      		BFIN_IRQ(21)	/* DMA 7 Channel (SPI) */
-#define IRQ_UART0_RX 		BFIN_IRQ(22)	/* DMA8 Channel (UART0 RX) */
-#define IRQ_UART0_TX 		BFIN_IRQ(23)	/* DMA9 Channel (UART0 TX) */
-#define IRQ_UART1_RX 		BFIN_IRQ(24)	/* DMA10 Channel (UART1 RX) */
-#define IRQ_UART1_TX 		BFIN_IRQ(25)	/* DMA11 Channel (UART1 TX) */
-#define IRQ_OPTSEC   		BFIN_IRQ(26)	/* OTPSEC Interrupt */
-#define IRQ_CNT   		BFIN_IRQ(27)	/* GP Counter */
-#define IRQ_MAC_RX   		BFIN_IRQ(28)	/* DMA1 Channel (MAC RX/HDMA) */
-#define IRQ_PORTH_INTA   	BFIN_IRQ(29)	/* Port H Interrupt A */
+#define IRQ_TWI			BFIN_IRQ(20)	/* TWI */
+#define IRQ_SPI			BFIN_IRQ(21)	/* DMA 7 Channel (SPI) */
+#define IRQ_UART0_RX		BFIN_IRQ(22)	/* DMA8 Channel (UART0 RX) */
+#define IRQ_UART0_TX		BFIN_IRQ(23)	/* DMA9 Channel (UART0 TX) */
+#define IRQ_UART1_RX		BFIN_IRQ(24)	/* DMA10 Channel (UART1 RX) */
+#define IRQ_UART1_TX		BFIN_IRQ(25)	/* DMA11 Channel (UART1 TX) */
+#define IRQ_OPTSEC		BFIN_IRQ(26)	/* OTPSEC Interrupt */
+#define IRQ_CNT			BFIN_IRQ(27)	/* GP Counter */
+#define IRQ_MAC_RX		BFIN_IRQ(28)	/* DMA1 Channel (MAC RX/HDMA) */
+#define IRQ_PORTH_INTA		BFIN_IRQ(29)	/* Port H Interrupt A */
 #define IRQ_MAC_TX		BFIN_IRQ(30)	/* DMA2 Channel (MAC TX/NAND) */
 #define IRQ_NFC			BFIN_IRQ(30)	/* DMA2 Channel (MAC TX/NAND) */
 #define IRQ_PORTH_INTB		BFIN_IRQ(31)	/* Port H Interrupt B */
@@ -96,119 +67,108 @@
 #define IRQ_USB_INT2		BFIN_IRQ(54)	/* USB_INT2 Interrupt */
 #define IRQ_USB_DMA		BFIN_IRQ(55)	/* USB_DMAINT Interrupt */
 
-#define SYS_IRQS        	BFIN_IRQ(63)	/* 70 */
-
-#define IRQ_PF0         71
-#define IRQ_PF1         72
-#define IRQ_PF2         73
-#define IRQ_PF3         74
-#define IRQ_PF4         75
-#define IRQ_PF5         76
-#define IRQ_PF6         77
-#define IRQ_PF7         78
-#define IRQ_PF8         79
-#define IRQ_PF9         80
-#define IRQ_PF10        81
-#define IRQ_PF11        82
-#define IRQ_PF12        83
-#define IRQ_PF13        84
-#define IRQ_PF14        85
-#define IRQ_PF15        86
+#define SYS_IRQS		BFIN_IRQ(63)	/* 70 */
 
-#define IRQ_PG0         87
-#define IRQ_PG1         88
-#define IRQ_PG2         89
-#define IRQ_PG3         90
-#define IRQ_PG4         91
-#define IRQ_PG5         92
-#define IRQ_PG6         93
-#define IRQ_PG7         94
-#define IRQ_PG8         95
-#define IRQ_PG9         96
-#define IRQ_PG10        97
-#define IRQ_PG11        98
-#define IRQ_PG12        99
-#define IRQ_PG13        100
-#define IRQ_PG14        101
-#define IRQ_PG15        102
+#define IRQ_PF0			71
+#define IRQ_PF1			72
+#define IRQ_PF2			73
+#define IRQ_PF3			74
+#define IRQ_PF4			75
+#define IRQ_PF5			76
+#define IRQ_PF6			77
+#define IRQ_PF7			78
+#define IRQ_PF8			79
+#define IRQ_PF9			80
+#define IRQ_PF10		81
+#define IRQ_PF11		82
+#define IRQ_PF12		83
+#define IRQ_PF13		84
+#define IRQ_PF14		85
+#define IRQ_PF15		86
 
-#define IRQ_PH0         103
-#define IRQ_PH1         104
-#define IRQ_PH2         105
-#define IRQ_PH3         106
-#define IRQ_PH4         107
-#define IRQ_PH5         108
-#define IRQ_PH6         109
-#define IRQ_PH7         110
-#define IRQ_PH8         111
-#define IRQ_PH9         112
-#define IRQ_PH10        113
-#define IRQ_PH11        114
-#define IRQ_PH12        115
-#define IRQ_PH13        116
-#define IRQ_PH14        117
-#define IRQ_PH15        118
+#define IRQ_PG0			87
+#define IRQ_PG1			88
+#define IRQ_PG2			89
+#define IRQ_PG3			90
+#define IRQ_PG4			91
+#define IRQ_PG5			92
+#define IRQ_PG6			93
+#define IRQ_PG7			94
+#define IRQ_PG8			95
+#define IRQ_PG9			96
+#define IRQ_PG10		97
+#define IRQ_PG11		98
+#define IRQ_PG12		99
+#define IRQ_PG13		100
+#define IRQ_PG14		101
+#define IRQ_PG15		102
 
-#define GPIO_IRQ_BASE	IRQ_PF0
+#define IRQ_PH0			103
+#define IRQ_PH1			104
+#define IRQ_PH2			105
+#define IRQ_PH3			106
+#define IRQ_PH4			107
+#define IRQ_PH5			108
+#define IRQ_PH6			109
+#define IRQ_PH7			110
+#define IRQ_PH8			111
+#define IRQ_PH9			112
+#define IRQ_PH10		113
+#define IRQ_PH11		114
+#define IRQ_PH12		115
+#define IRQ_PH13		116
+#define IRQ_PH14		117
+#define IRQ_PH15		118
 
-#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 GPIO_IRQ_BASE		IRQ_PF0
 
-#define NR_MACH_IRQS	(IRQ_MAC_STMDONE + 1)
-#define NR_IRQS		(NR_MACH_IRQS + NR_SPARE_IRQS)
+#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 IVG7            7
-#define IVG8            8
-#define IVG9            9
-#define IVG10           10
-#define IVG11           11
-#define IVG12           12
-#define IVG13           13
-#define IVG14           14
-#define IVG15           15
+#define NR_MACH_IRQS		(IRQ_MAC_STMDONE + 1)
 
 /* IAR0 BIT FIELDS */
 #define IRQ_PLL_WAKEUP_POS	0
 #define IRQ_DMA0_ERROR_POS	4
-#define IRQ_DMAR0_BLK_POS 	8
-#define IRQ_DMAR1_BLK_POS 	12
-#define IRQ_DMAR0_OVR_POS 	16
-#define IRQ_DMAR1_OVR_POS 	20
-#define IRQ_PPI_ERROR_POS 	24
-#define IRQ_MAC_ERROR_POS 	28
+#define IRQ_DMAR0_BLK_POS	8
+#define IRQ_DMAR1_BLK_POS	12
+#define IRQ_DMAR0_OVR_POS	16
+#define IRQ_DMAR1_OVR_POS	20
+#define IRQ_PPI_ERROR_POS	24
+#define IRQ_MAC_ERROR_POS	28
 
 /* IAR1 BIT FIELDS */
 #define IRQ_SPORT0_ERROR_POS	0
 #define IRQ_SPORT1_ERROR_POS	4
-#define IRQ_UART0_ERROR_POS 	16
-#define IRQ_UART1_ERROR_POS 	20
-#define IRQ_RTC_POS         	24
-#define IRQ_PPI_POS         	28
+#define IRQ_UART0_ERROR_POS	16
+#define IRQ_UART1_ERROR_POS	20
+#define IRQ_RTC_POS		24
+#define IRQ_PPI_POS		28
 
 /* IAR2 BIT FIELDS */
 #define IRQ_SPORT0_RX_POS	0
 #define IRQ_SPORT0_TX_POS	4
 #define IRQ_SPORT1_RX_POS	8
 #define IRQ_SPORT1_TX_POS	12
-#define IRQ_TWI_POS      	16
-#define IRQ_SPI_POS      	20
-#define IRQ_UART0_RX_POS 	24
-#define IRQ_UART0_TX_POS 	28
+#define IRQ_TWI_POS		16
+#define IRQ_SPI_POS		20
+#define IRQ_UART0_RX_POS	24
+#define IRQ_UART0_TX_POS	28
 
 /* IAR3 BIT FIELDS */
-#define IRQ_UART1_RX_POS  	0
-#define IRQ_UART1_TX_POS  	4
-#define IRQ_OPTSEC_POS    	8
-#define IRQ_CNT_POS       	12
-#define IRQ_MAC_RX_POS    	16
+#define IRQ_UART1_RX_POS	0
+#define IRQ_UART1_TX_POS	4
+#define IRQ_OPTSEC_POS		8
+#define IRQ_CNT_POS		12
+#define IRQ_MAC_RX_POS		16
 #define IRQ_PORTH_INTA_POS	20
-#define IRQ_MAC_TX_POS    	24
+#define IRQ_MAC_TX_POS		24
 #define IRQ_PORTH_INTB_POS	28
 
 /* IAR4 BIT FIELDS */
@@ -224,21 +184,21 @@
 /* IAR5 BIT FIELDS */
 #define IRQ_PORTG_INTA_POS	0
 #define IRQ_PORTG_INTB_POS	4
-#define IRQ_MEM_DMA0_POS  	8
-#define IRQ_MEM_DMA1_POS  	12
-#define IRQ_WATCH_POS     	16
+#define IRQ_MEM_DMA0_POS	8
+#define IRQ_MEM_DMA1_POS	12
+#define IRQ_WATCH_POS		16
 #define IRQ_PORTF_INTA_POS	20
 #define IRQ_PORTF_INTB_POS	24
-#define IRQ_SPI_ERROR_POS 	28
+#define IRQ_SPI_ERROR_POS	28
 
 /* IAR6 BIT FIELDS */
-#define IRQ_NFC_ERROR_POS  	0
-#define IRQ_HDMA_ERROR_POS 	4
-#define IRQ_HDMA_POS       	8
-#define IRQ_USB_EINT_POS   	12
-#define IRQ_USB_INT0_POS   	16
-#define IRQ_USB_INT1_POS   	20
-#define IRQ_USB_INT2_POS   	24
-#define IRQ_USB_DMA_POS    	28
+#define IRQ_NFC_ERROR_POS	0
+#define IRQ_HDMA_ERROR_POS	4
+#define IRQ_HDMA_POS		8
+#define IRQ_USB_EINT_POS	12
+#define IRQ_USB_INT0_POS	16
+#define IRQ_USB_INT1_POS	20
+#define IRQ_USB_INT2_POS	24
+#define IRQ_USB_DMA_POS		28
 
-#endif				/* _BF527_IRQ_H_ */
+#endif
diff -druN linux-2.6.39-libre/arch/blackfin/mach-bf533/include/mach/anomaly.h linux-3.0-rc7-libre/arch/blackfin/mach-bf533/include/mach/anomaly.h
--- linux-2.6.39-libre/arch/blackfin/mach-bf533/include/mach/anomaly.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/blackfin/mach-bf533/include/mach/anomaly.h	2011-07-11 19:51:52.000000000 -0400
@@ -5,13 +5,13 @@
  * and can be replaced with that version at any time
  * DO NOT EDIT THIS FILE
  *
- * Copyright 2004-2010 Analog Devices Inc.
+ * Copyright 2004-2011 Analog Devices Inc.
  * Licensed under the ADI BSD license.
  *   https://docs.blackfin.uclinux.org/doku.php?id=adi_bsd
  */
 
 /* This file should be up to date with:
- *  - Revision E, 09/18/2008; ADSP-BF531/BF532/BF533 Blackfin Processor Anomaly List
+ *  - Revision F, 05/25/2010; ADSP-BF531/BF532/BF533 Blackfin Processor Anomaly List
  */
 
 #ifndef _MACH_ANOMALY_H_
@@ -206,6 +206,10 @@
 #define ANOMALY_05000443 (1)
 /* False Hardware Error when RETI Points to Invalid Memory */
 #define ANOMALY_05000461 (1)
+/* Synchronization Problem at Startup May Cause SPORT Transmit Channels to Misalign */
+#define ANOMALY_05000462 (1)
+/* Boot Failure When SDRAM Control Signals Toggle Coming Out Of Reset */
+#define ANOMALY_05000471 (1)
 /* Interrupted 32-Bit SPORT Data Register Access Results In Underflow */
 #define ANOMALY_05000473 (1)
 /* Possible Lockup Condition whem Modifying PLL from External Memory */
@@ -351,12 +355,14 @@
 #define ANOMALY_05000362 (1)
 #define ANOMALY_05000364 (0)
 #define ANOMALY_05000380 (0)
+#define ANOMALY_05000383 (0)
 #define ANOMALY_05000386 (1)
 #define ANOMALY_05000389 (0)
 #define ANOMALY_05000412 (0)
 #define ANOMALY_05000430 (0)
 #define ANOMALY_05000432 (0)
 #define ANOMALY_05000435 (0)
+#define ANOMALY_05000440 (0)
 #define ANOMALY_05000447 (0)
 #define ANOMALY_05000448 (0)
 #define ANOMALY_05000456 (0)
@@ -364,6 +370,7 @@
 #define ANOMALY_05000465 (0)
 #define ANOMALY_05000467 (0)
 #define ANOMALY_05000474 (0)
+#define ANOMALY_05000480 (0)
 #define ANOMALY_05000485 (0)
 
 #endif
diff -druN linux-2.6.39-libre/arch/blackfin/mach-bf533/include/mach/bfin_serial_5xx.h linux-3.0-rc7-libre/arch/blackfin/mach-bf533/include/mach/bfin_serial_5xx.h
--- linux-2.6.39-libre/arch/blackfin/mach-bf533/include/mach/bfin_serial_5xx.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/blackfin/mach-bf533/include/mach/bfin_serial_5xx.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,52 +0,0 @@
-/*
- * Copyright 2006-2009 Analog Devices Inc.
- *
- * Licensed under the GPL-2 or later
- */
-
-#include <asm/dma.h>
-#include <asm/portmux.h>
-
-#ifdef CONFIG_BFIN_UART0_CTSRTS
-# define CONFIG_SERIAL_BFIN_CTSRTS
-# ifndef CONFIG_UART0_CTS_PIN
-#  define CONFIG_UART0_CTS_PIN -1
-# endif
-# ifndef CONFIG_UART0_RTS_PIN
-#  define CONFIG_UART0_RTS_PIN -1
-# endif
-#endif
-
-struct bfin_serial_res {
-	unsigned long	uart_base_addr;
-	int		uart_irq;
-	int		uart_status_irq;
-#ifdef CONFIG_SERIAL_BFIN_DMA
-	unsigned int	uart_tx_dma_channel;
-	unsigned int	uart_rx_dma_channel;
-#endif
-#ifdef CONFIG_SERIAL_BFIN_CTSRTS
-	int		uart_cts_pin;
-	int		uart_rts_pin;
-#endif
-};
-
-struct bfin_serial_res bfin_serial_resource[] = {
-	{
-	0xFFC00400,
-	IRQ_UART0_RX,
-	IRQ_UART0_ERROR,
-#ifdef CONFIG_SERIAL_BFIN_DMA
-	CH_UART0_TX,
-	CH_UART0_RX,
-#endif
-#ifdef CONFIG_SERIAL_BFIN_CTSRTS
-	CONFIG_UART0_CTS_PIN,
-	CONFIG_UART0_RTS_PIN,
-#endif
-	}
-};
-
-#define DRIVER_NAME "bfin-uart"
-
-#include <asm/bfin_serial.h>
diff -druN linux-2.6.39-libre/arch/blackfin/mach-bf533/include/mach/irq.h linux-3.0-rc7-libre/arch/blackfin/mach-bf533/include/mach/irq.h
--- linux-2.6.39-libre/arch/blackfin/mach-bf533/include/mach/irq.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/blackfin/mach-bf533/include/mach/irq.h	2011-07-11 19:51:52.000000000 -0400
@@ -7,83 +7,36 @@
 #ifndef _BF533_IRQ_H_
 #define _BF533_IRQ_H_
 
-/*
- * Interrupt source definitions
-             Event Source    Core Event Name
-Core        Emulation               **
- Events         (highest priority)  EMU         0
-            Reset                   RST         1
-            NMI                     NMI         2
-            Exception               EVX         3
-            Reserved                --          4
-            Hardware Error          IVHW        5
-            Core Timer              IVTMR       6 *
-	    PLL Wakeup Interrupt    IVG7	7
-	    DMA Error (generic)	    IVG7	8
-	    PPI Error Interrupt     IVG7	9
-	    SPORT0 Error Interrupt  IVG7	10
-	    SPORT1 Error Interrupt  IVG7	11
-	    SPI Error Interrupt	    IVG7	12
-	    UART Error Interrupt    IVG7	13
-	    RTC Interrupt	    IVG8        14
-	    DMA0 Interrupt (PPI)    IVG8	15
-	    DMA1 (SPORT0 RX)	    IVG9	16
-	    DMA2 (SPORT0 TX)	    IVG9        17
-	    DMA3 (SPORT1 RX)        IVG9	18
-	    DMA4 (SPORT1 TX)	    IVG9	19
-	    DMA5 (PPI)		    IVG10	20
-	    DMA6 (UART RX)	    IVG10	21
-	    DMA7 (UART TX)	    IVG10	22
-	    Timer0		    IVG11	23
-	    Timer1		    IVG11	24
-	    Timer2		    IVG11	25
-	    PF Interrupt A	    IVG12	26
-	    PF Interrupt B	    IVG12	27
-	    DMA8/9 Interrupt	    IVG13	28
-	    DMA10/11 Interrupt	    IVG13	29
-	    Watchdog Timer	    IVG13	30
+#include <mach-common/irq.h>
 
-            Softirq		    IVG14       31
-            System Call    --
-                 (lowest priority)  IVG15       32 *
- */
-#define SYS_IRQS	31
-#define NR_PERI_INTS	24
+#define NR_PERI_INTS		24
 
-/* The ABSTRACT IRQ definitions */
-/** the first seven of the following are fixed, the rest you change if you need to **/
-#define	IRQ_EMU			0	/*Emulation */
-#define	IRQ_RST			1	/*reset */
-#define	IRQ_NMI			2	/*Non Maskable */
-#define	IRQ_EVX			3	/*Exception */
-#define	IRQ_UNUSED		4	/*- unused interrupt*/
-#define	IRQ_HWERR		5	/*Hardware Error */
-#define	IRQ_CORETMR		6	/*Core timer */
+#define IRQ_PLL_WAKEUP		BFIN_IRQ(0)	/* PLL Wakeup Interrupt */
+#define IRQ_DMA_ERROR		BFIN_IRQ(1)	/* DMA Error (general) */
+#define IRQ_PPI_ERROR		BFIN_IRQ(2)	/* PPI Error Interrupt */
+#define IRQ_SPORT0_ERROR	BFIN_IRQ(3)	/* SPORT0 Error Interrupt */
+#define IRQ_SPORT1_ERROR	BFIN_IRQ(4)	/* SPORT1 Error Interrupt */
+#define IRQ_SPI_ERROR		BFIN_IRQ(5)	/* SPI Error Interrupt */
+#define IRQ_UART0_ERROR		BFIN_IRQ(6)	/* UART Error Interrupt */
+#define IRQ_RTC			BFIN_IRQ(7)	/* RTC Interrupt */
+#define IRQ_PPI			BFIN_IRQ(8)	/* DMA0 Interrupt (PPI) */
+#define IRQ_SPORT0_RX		BFIN_IRQ(9)	/* DMA1 Interrupt (SPORT0 RX) */
+#define IRQ_SPORT0_TX		BFIN_IRQ(10)	/* DMA2 Interrupt (SPORT0 TX) */
+#define IRQ_SPORT1_RX		BFIN_IRQ(11)	/* DMA3 Interrupt (SPORT1 RX) */
+#define IRQ_SPORT1_TX		BFIN_IRQ(12)	/* DMA4 Interrupt (SPORT1 TX) */
+#define IRQ_SPI			BFIN_IRQ(13)	/* DMA5 Interrupt (SPI) */
+#define IRQ_UART0_RX		BFIN_IRQ(14)	/* DMA6 Interrupt (UART RX) */
+#define IRQ_UART0_TX		BFIN_IRQ(15)	/* DMA7 Interrupt (UART TX) */
+#define IRQ_TIMER0		BFIN_IRQ(16)	/* Timer 0 */
+#define IRQ_TIMER1		BFIN_IRQ(17)	/* Timer 1 */
+#define IRQ_TIMER2		BFIN_IRQ(18)	/* Timer 2 */
+#define IRQ_PROG_INTA		BFIN_IRQ(19)	/* Programmable Flags A (8) */
+#define IRQ_PROG_INTB		BFIN_IRQ(20)	/* Programmable Flags B (8) */
+#define IRQ_MEM_DMA0		BFIN_IRQ(21)	/* DMA8/9 Interrupt (Memory DMA Stream 0) */
+#define IRQ_MEM_DMA1		BFIN_IRQ(22)	/* DMA10/11 Interrupt (Memory DMA Stream 1) */
+#define IRQ_WATCH		BFIN_IRQ(23)	/* Watch Dog Timer */
 
-#define	IRQ_PLL_WAKEUP		7	/*PLL Wakeup Interrupt */
-#define	IRQ_DMA_ERROR		8	/*DMA Error (general) */
-#define	IRQ_PPI_ERROR		9	/*PPI Error Interrupt */
-#define	IRQ_SPORT0_ERROR	10	/*SPORT0 Error Interrupt */
-#define	IRQ_SPORT1_ERROR	11	/*SPORT1 Error Interrupt */
-#define	IRQ_SPI_ERROR		12	/*SPI Error Interrupt */
-#define	IRQ_UART0_ERROR		13	/*UART Error Interrupt */
-#define	IRQ_RTC			14	/*RTC Interrupt */
-#define	IRQ_PPI			15	/*DMA0 Interrupt (PPI) */
-#define	IRQ_SPORT0_RX		16	/*DMA1 Interrupt (SPORT0 RX) */
-#define	IRQ_SPORT0_TX		17	/*DMA2 Interrupt (SPORT0 TX) */
-#define	IRQ_SPORT1_RX		18	/*DMA3 Interrupt (SPORT1 RX) */
-#define	IRQ_SPORT1_TX		19	/*DMA4 Interrupt (SPORT1 TX) */
-#define	IRQ_SPI			20	/*DMA5 Interrupt (SPI) */
-#define	IRQ_UART0_RX		21	/*DMA6 Interrupt (UART RX) */
-#define	IRQ_UART0_TX		22	/*DMA7 Interrupt (UART TX) */
-#define	IRQ_TIMER0		23	/*Timer 0 */
-#define	IRQ_TIMER1		24	/*Timer 1 */
-#define	IRQ_TIMER2		25	/*Timer 2 */
-#define	IRQ_PROG_INTA		26	/*Programmable Flags A (8) */
-#define	IRQ_PROG_INTB		27	/*Programmable Flags B (8) */
-#define	IRQ_MEM_DMA0		28	/*DMA8/9 Interrupt (Memory DMA Stream 0) */
-#define	IRQ_MEM_DMA1		29	/*DMA10/11 Interrupt (Memory DMA Stream 1) */
-#define	IRQ_WATCH	   	30	/*Watch Dog Timer */
+#define SYS_IRQS		31
 
 #define IRQ_PF0			33
 #define IRQ_PF1			34
@@ -105,46 +58,35 @@
 #define GPIO_IRQ_BASE		IRQ_PF0
 
 #define NR_MACH_IRQS		(IRQ_PF15 + 1)
-#define NR_IRQS			(NR_MACH_IRQS + NR_SPARE_IRQS)
-
-#define IVG7			7
-#define IVG8			8
-#define IVG9			9
-#define IVG10			10
-#define IVG11			11
-#define IVG12			12
-#define IVG13			13
-#define IVG14			14
-#define IVG15			15
 
-/* IAR0 BIT FIELDS*/
-#define RTC_ERROR_POS			28
-#define UART_ERROR_POS			24
-#define SPORT1_ERROR_POS		20
-#define SPI_ERROR_POS			16
-#define SPORT0_ERROR_POS		12
-#define PPI_ERROR_POS			8
-#define DMA_ERROR_POS			4
-#define PLLWAKE_ERROR_POS		0
+/* IAR0 BIT FIELDS */
+#define RTC_ERROR_POS		28
+#define UART_ERROR_POS		24
+#define SPORT1_ERROR_POS	20
+#define SPI_ERROR_POS		16
+#define SPORT0_ERROR_POS	12
+#define PPI_ERROR_POS		8
+#define DMA_ERROR_POS		4
+#define PLLWAKE_ERROR_POS	0
 
-/* IAR1 BIT FIELDS*/
-#define DMA7_UARTTX_POS			28
-#define DMA6_UARTRX_POS			24
-#define DMA5_SPI_POS			20
-#define DMA4_SPORT1TX_POS		16
-#define DMA3_SPORT1RX_POS		12
-#define DMA2_SPORT0TX_POS		8
-#define DMA1_SPORT0RX_POS		4
-#define DMA0_PPI_POS			0
+/* IAR1 BIT FIELDS */
+#define DMA7_UARTTX_POS		28
+#define DMA6_UARTRX_POS		24
+#define DMA5_SPI_POS		20
+#define DMA4_SPORT1TX_POS	16
+#define DMA3_SPORT1RX_POS	12
+#define DMA2_SPORT0TX_POS	8
+#define DMA1_SPORT0RX_POS	4
+#define DMA0_PPI_POS		0
 
-/* IAR2 BIT FIELDS*/
-#define WDTIMER_POS			28
-#define MEMDMA1_POS			24
-#define MEMDMA0_POS			20
-#define PFB_POS				16
-#define PFA_POS				12
-#define TIMER2_POS			8
-#define TIMER1_POS			4
-#define TIMER0_POS			0
+/* IAR2 BIT FIELDS */
+#define WDTIMER_POS		28
+#define MEMDMA1_POS		24
+#define MEMDMA0_POS		20
+#define PFB_POS			16
+#define PFA_POS			12
+#define TIMER2_POS		8
+#define TIMER1_POS		4
+#define TIMER0_POS		0
 
-#endif				/* _BF533_IRQ_H_ */
+#endif
diff -druN linux-2.6.39-libre/arch/blackfin/mach-bf537/boards/stamp.c linux-3.0-rc7-libre/arch/blackfin/mach-bf537/boards/stamp.c
--- linux-2.6.39-libre/arch/blackfin/mach-bf537/boards/stamp.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/blackfin/mach-bf537/boards/stamp.c	2011-07-11 19:51:52.000000000 -0400
@@ -35,6 +35,7 @@
 #include <asm/reboot.h>
 #include <asm/portmux.h>
 #include <asm/dpmc.h>
+#include <asm/bfin_sport.h>
 #ifdef CONFIG_REGULATOR_FIXED_VOLTAGE
 #include <linux/regulator/fixed.h>
 #endif
@@ -381,7 +382,6 @@
 #endif
 
 #if defined(CONFIG_MTD_NAND_PLATFORM) || defined(CONFIG_MTD_NAND_PLATFORM_MODULE)
-#ifdef CONFIG_MTD_PARTITIONS
 const char *part_probes[] = { "cmdlinepart", "RedBoot", NULL };
 
 static struct mtd_partition bfin_plat_nand_partitions[] = {
@@ -395,7 +395,6 @@
 		.offset = MTDPART_OFS_APPEND,
 	},
 };
-#endif
 
 #define BFIN_NAND_PLAT_CLE 2
 #define BFIN_NAND_PLAT_ALE 1
@@ -422,11 +421,9 @@
 	.chip = {
 		.nr_chips = 1,
 		.chip_delay = 30,
-#ifdef CONFIG_MTD_PARTITIONS
 		.part_probe_types = part_probes,
 		.partitions = bfin_plat_nand_partitions,
 		.nr_partitions = ARRAY_SIZE(bfin_plat_nand_partitions),
-#endif
 	},
 	.ctrl = {
 		.cmd_ctrl  = bfin_plat_nand_cmd_ctrl,
@@ -2585,27 +2582,103 @@
 	},
 };
 
-#if defined(CONFIG_SND_BF5XX_I2S) || defined(CONFIG_SND_BF5XX_I2S_MODULE)
+#if defined(CONFIG_SND_BF5XX_I2S) || defined(CONFIG_SND_BF5XX_I2S_MODULE) || \
+	defined(CONFIG_SND_BF5XX_TDM) || defined(CONFIG_SND_BF5XX_TDM_MODULE) || \
+	defined(CONFIG_SND_BF5XX_AC97) || defined(CONFIG_SND_BF5XX_AC97_MODULE)
+
+#define SPORT_REQ(x) \
+	[x] = {P_SPORT##x##_TFS, P_SPORT##x##_DTPRI, P_SPORT##x##_TSCLK, \
+		P_SPORT##x##_RFS, P_SPORT##x##_DRPRI, P_SPORT##x##_RSCLK, 0}
+
+static const u16 bfin_snd_pin[][7] = {
+	SPORT_REQ(0),
+	SPORT_REQ(1),
+};
+
+static struct bfin_snd_platform_data bfin_snd_data[] = {
+	{
+		.pin_req = &bfin_snd_pin[0][0],
+	},
+	{
+		.pin_req = &bfin_snd_pin[1][0],
+	},
+};
+
+#define BFIN_SND_RES(x) \
+	[x] = { \
+		{ \
+			.start = SPORT##x##_TCR1, \
+			.end = SPORT##x##_TCR1, \
+			.flags = IORESOURCE_MEM \
+		}, \
+		{ \
+			.start = CH_SPORT##x##_RX, \
+			.end = CH_SPORT##x##_RX, \
+			.flags = IORESOURCE_DMA, \
+		}, \
+		{ \
+			.start = CH_SPORT##x##_TX, \
+			.end = CH_SPORT##x##_TX, \
+			.flags = IORESOURCE_DMA, \
+		}, \
+		{ \
+			.start = IRQ_SPORT##x##_ERROR, \
+			.end = IRQ_SPORT##x##_ERROR, \
+			.flags = IORESOURCE_IRQ, \
+		} \
+	}
+
+static struct resource bfin_snd_resources[][4] = {
+	BFIN_SND_RES(0),
+	BFIN_SND_RES(1),
+};
+
+static struct platform_device bfin_pcm = {
+	.name = "bfin-pcm-audio",
+	.id = -1,
+};
+#endif
+
+#if defined(CONFIG_SND_BF5XX_SOC_AD73311) || defined(CONFIG_SND_BF5XX_SOC_AD73311_MODULE)
+static struct platform_device bfin_ad73311_codec_device = {
+	.name = "ad73311",
+	.id = -1,
+};
+#endif
+
+#if defined(CONFIG_SND_BF5XX_SOC_I2S) || defined(CONFIG_SND_BF5XX_SOC_I2S_MODULE)
 static struct platform_device bfin_i2s = {
 	.name = "bfin-i2s",
 	.id = CONFIG_SND_BF5XX_SPORT_NUM,
-	/* TODO: add platform data here */
+	.num_resources = ARRAY_SIZE(bfin_snd_resources[CONFIG_SND_BF5XX_SPORT_NUM]),
+	.resource = bfin_snd_resources[CONFIG_SND_BF5XX_SPORT_NUM],
+	.dev = {
+		.platform_data = &bfin_snd_data[CONFIG_SND_BF5XX_SPORT_NUM],
+	},
 };
 #endif
 
-#if defined(CONFIG_SND_BF5XX_TDM) || defined(CONFIG_SND_BF5XX_TDM_MODULE)
+#if defined(CONFIG_SND_BF5XX_SOC_TDM) || defined(CONFIG_SND_BF5XX_SOC_TDM_MODULE)
 static struct platform_device bfin_tdm = {
 	.name = "bfin-tdm",
 	.id = CONFIG_SND_BF5XX_SPORT_NUM,
-	/* TODO: add platform data here */
+	.num_resources = ARRAY_SIZE(bfin_snd_resources[CONFIG_SND_BF5XX_SPORT_NUM]),
+	.resource = bfin_snd_resources[CONFIG_SND_BF5XX_SPORT_NUM],
+	.dev = {
+		.platform_data = &bfin_snd_data[CONFIG_SND_BF5XX_SPORT_NUM],
+	},
 };
 #endif
 
-#if defined(CONFIG_SND_BF5XX_AC97) || defined(CONFIG_SND_BF5XX_AC97_MODULE)
+#if defined(CONFIG_SND_BF5XX_SOC_AC97) || defined(CONFIG_SND_BF5XX_SOC_AC97_MODULE)
 static struct platform_device bfin_ac97 = {
 	.name = "bfin-ac97",
 	.id = CONFIG_SND_BF5XX_SPORT_NUM,
-	/* TODO: add platform data here */
+	.num_resources = ARRAY_SIZE(bfin_snd_resources[CONFIG_SND_BF5XX_SPORT_NUM]),
+	.resource = bfin_snd_resources[CONFIG_SND_BF5XX_SPORT_NUM],
+	.dev = {
+		.platform_data = &bfin_snd_data[CONFIG_SND_BF5XX_SPORT_NUM],
+	},
 };
 #endif
 
@@ -2796,17 +2869,28 @@
 	&stamp_flash_device,
 #endif
 
-#if defined(CONFIG_SND_BF5XX_I2S) || defined(CONFIG_SND_BF5XX_I2S_MODULE)
+#if defined(CONFIG_SND_BF5XX_I2S) || defined(CONFIG_SND_BF5XX_I2S_MODULE) || \
+	defined(CONFIG_SND_BF5XX_TDM) || defined(CONFIG_SND_BF5XX_TDM_MODULE) || \
+	defined(CONFIG_SND_BF5XX_AC97) || defined(CONFIG_SND_BF5XX_AC97_MODULE)
+	&bfin_pcm,
+#endif
+
+#if defined(CONFIG_SND_BF5XX_SOC_AD73311) || defined(CONFIG_SND_BF5XX_SOC_AD73311_MODULE)
+	&bfin_ad73311_codec_device,
+#endif
+
+#if defined(CONFIG_SND_BF5XX_SOC_I2S) || defined(CONFIG_SND_BF5XX_SOC_I2S_MODULE)
 	&bfin_i2s,
 #endif
 
-#if defined(CONFIG_SND_BF5XX_TDM) || defined(CONFIG_SND_BF5XX_TDM_MODULE)
+#if defined(CONFIG_SND_BF5XX_SOC_TDM) || defined(CONFIG_SND_BF5XX_SOC_TDM_MODULE)
 	&bfin_tdm,
 #endif
 
-#if defined(CONFIG_SND_BF5XX_AC97) || defined(CONFIG_SND_BF5XX_AC97_MODULE)
+#if defined(CONFIG_SND_BF5XX_SOC_AC97) || defined(CONFIG_SND_BF5XX_SOC_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)
diff -druN linux-2.6.39-libre/arch/blackfin/mach-bf537/include/mach/anomaly.h linux-3.0-rc7-libre/arch/blackfin/mach-bf537/include/mach/anomaly.h
--- linux-2.6.39-libre/arch/blackfin/mach-bf537/include/mach/anomaly.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/blackfin/mach-bf537/include/mach/anomaly.h	2011-07-11 19:51:52.000000000 -0400
@@ -5,13 +5,13 @@
  * and can be replaced with that version at any time
  * DO NOT EDIT THIS FILE
  *
- * Copyright 2004-2010 Analog Devices Inc.
+ * Copyright 2004-2011 Analog Devices Inc.
  * Licensed under the ADI BSD license.
  *   https://docs.blackfin.uclinux.org/doku.php?id=adi_bsd
  */
 
 /* This file should be up to date with:
- *  - Revision D, 09/18/2008; ADSP-BF534/ADSP-BF536/ADSP-BF537 Blackfin Processor Anomaly List
+ *  - Revision E, 05/25/2010; ADSP-BF534/ADSP-BF536/ADSP-BF537 Blackfin Processor Anomaly List
  */
 
 #ifndef _MACH_ANOMALY_H_
@@ -160,12 +160,16 @@
 #define ANOMALY_05000443 (1)
 /* False Hardware Error when RETI Points to Invalid Memory */
 #define ANOMALY_05000461 (1)
+/* Synchronization Problem at Startup May Cause SPORT Transmit Channels to Misalign */
+#define ANOMALY_05000462 (1)
 /* Interrupted 32-Bit SPORT Data Register Access Results In Underflow */
 #define ANOMALY_05000473 (1)
 /* Possible Lockup Condition whem Modifying PLL from External Memory */
 #define ANOMALY_05000475 (1)
 /* TESTSET Instruction Cannot Be Interrupted */
 #define ANOMALY_05000477 (1)
+/* Multiple Simultaneous Urgent DMA Requests May Cause DMA System Instability */
+#define ANOMALY_05000480 (__SILICON_REVISION__ < 3)
 /* Reads of ITEST_COMMAND and ITEST_DATA Registers Cause Cache Corruption */
 #define ANOMALY_05000481 (1)
 /* IFLUSH sucks at life */
@@ -204,6 +208,7 @@
 #define ANOMALY_05000363 (0)
 #define ANOMALY_05000364 (0)
 #define ANOMALY_05000380 (0)
+#define ANOMALY_05000383 (0)
 #define ANOMALY_05000386 (1)
 #define ANOMALY_05000389 (0)
 #define ANOMALY_05000400 (0)
@@ -211,6 +216,7 @@
 #define ANOMALY_05000430 (0)
 #define ANOMALY_05000432 (0)
 #define ANOMALY_05000435 (0)
+#define ANOMALY_05000440 (0)
 #define ANOMALY_05000447 (0)
 #define ANOMALY_05000448 (0)
 #define ANOMALY_05000456 (0)
diff -druN linux-2.6.39-libre/arch/blackfin/mach-bf537/include/mach/bfin_serial_5xx.h linux-3.0-rc7-libre/arch/blackfin/mach-bf537/include/mach/bfin_serial_5xx.h
--- linux-2.6.39-libre/arch/blackfin/mach-bf537/include/mach/bfin_serial_5xx.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/blackfin/mach-bf537/include/mach/bfin_serial_5xx.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,79 +0,0 @@
-/*
- * Copyright 2006-2009 Analog Devices Inc.
- *
- * Licensed under the GPL-2 or later
- */
-
-#include <asm/dma.h>
-#include <asm/portmux.h>
-
-#if defined(CONFIG_BFIN_UART0_CTSRTS) || defined(CONFIG_BFIN_UART1_CTSRTS)
-# define CONFIG_SERIAL_BFIN_CTSRTS
-
-# ifndef CONFIG_UART0_CTS_PIN
-#  define CONFIG_UART0_CTS_PIN -1
-# endif
-
-# ifndef CONFIG_UART0_RTS_PIN
-#  define CONFIG_UART0_RTS_PIN -1
-# endif
-
-# ifndef CONFIG_UART1_CTS_PIN
-#  define CONFIG_UART1_CTS_PIN -1
-# endif
-
-# ifndef CONFIG_UART1_RTS_PIN
-#  define CONFIG_UART1_RTS_PIN -1
-# endif
-#endif
-
-struct bfin_serial_res {
-	unsigned long	uart_base_addr;
-	int		uart_irq;
-	int		uart_status_irq;
-#ifdef CONFIG_SERIAL_BFIN_DMA
-	unsigned int	uart_tx_dma_channel;
-	unsigned int	uart_rx_dma_channel;
-#endif
-#ifdef CONFIG_SERIAL_BFIN_CTSRTS
-	int	uart_cts_pin;
-	int	uart_rts_pin;
-#endif
-};
-
-struct bfin_serial_res bfin_serial_resource[] = {
-#ifdef CONFIG_SERIAL_BFIN_UART0
-	{
-	0xFFC00400,
-	IRQ_UART0_RX,
-	IRQ_UART0_ERROR,
-#ifdef CONFIG_SERIAL_BFIN_DMA
-	CH_UART0_TX,
-	CH_UART0_RX,
-#endif
-#ifdef CONFIG_SERIAL_BFIN_CTSRTS
-	CONFIG_UART0_CTS_PIN,
-	CONFIG_UART0_RTS_PIN,
-#endif
-	},
-#endif
-#ifdef CONFIG_SERIAL_BFIN_UART1
-	{
-	0xFFC02000,
-	IRQ_UART1_RX,
-	IRQ_UART1_ERROR,
-#ifdef CONFIG_SERIAL_BFIN_DMA
-	CH_UART1_TX,
-	CH_UART1_RX,
-#endif
-#ifdef CONFIG_SERIAL_BFIN_CTSRTS
-	CONFIG_UART1_CTS_PIN,
-	CONFIG_UART1_RTS_PIN,
-#endif
-	},
-#endif
-};
-
-#define DRIVER_NAME "bfin-uart"
-
-#include <asm/bfin_serial.h>
diff -druN linux-2.6.39-libre/arch/blackfin/mach-bf537/include/mach/irq.h linux-3.0-rc7-libre/arch/blackfin/mach-bf537/include/mach/irq.h
--- linux-2.6.39-libre/arch/blackfin/mach-bf537/include/mach/irq.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/blackfin/mach-bf537/include/mach/irq.h	2011-07-11 19:51:52.000000000 -0400
@@ -7,193 +7,178 @@
 #ifndef _BF537_IRQ_H_
 #define _BF537_IRQ_H_
 
-/*
- * Interrupt source definitions
- *            Event Source    Core Event Name
- * Core       Emulation               **
- * Events         (highest priority)  EMU         0
- *            Reset                   RST         1
- *            NMI                     NMI         2
- *            Exception               EVX         3
- *            Reserved                --          4
- *            Hardware Error          IVHW        5
- *            Core Timer              IVTMR       6
- *  .....
- *
- *            Softirq		      IVG14
- *            System Call    --
- *               (lowest priority)    IVG15
- */
+#include <mach-common/irq.h>
 
-#define SYS_IRQS        39
-#define NR_PERI_INTS    32
+#define NR_PERI_INTS		32
 
-/* The ABSTRACT IRQ definitions */
-/** the first seven of the following are fixed, the rest you change if you need to **/
-#define IRQ_EMU             0	/*Emulation */
-#define IRQ_RST             1	/*reset */
-#define IRQ_NMI             2	/*Non Maskable */
-#define IRQ_EVX             3	/*Exception */
-#define IRQ_UNUSED          4	/*- unused interrupt*/
-#define IRQ_HWERR           5	/*Hardware Error */
-#define IRQ_CORETMR         6	/*Core timer */
+#define IRQ_PLL_WAKEUP		BFIN_IRQ(0)	/* PLL Wakeup Interrupt */
+#define IRQ_DMA_ERROR		BFIN_IRQ(1)	/* DMA Error (general) */
+#define IRQ_GENERIC_ERROR	BFIN_IRQ(2)	/* GENERIC Error Interrupt */
+#define IRQ_RTC			BFIN_IRQ(3)	/* RTC Interrupt */
+#define IRQ_PPI			BFIN_IRQ(4)	/* DMA0 Interrupt (PPI) */
+#define IRQ_SPORT0_RX		BFIN_IRQ(5)	/* DMA3 Interrupt (SPORT0 RX) */
+#define IRQ_SPORT0_TX		BFIN_IRQ(6)	/* DMA4 Interrupt (SPORT0 TX) */
+#define IRQ_SPORT1_RX		BFIN_IRQ(7)	/* DMA5 Interrupt (SPORT1 RX) */
+#define IRQ_SPORT1_TX		BFIN_IRQ(8)	/* DMA6 Interrupt (SPORT1 TX) */
+#define IRQ_TWI			BFIN_IRQ(9)	/* TWI Interrupt */
+#define IRQ_SPI			BFIN_IRQ(10)	/* DMA7 Interrupt (SPI) */
+#define IRQ_UART0_RX		BFIN_IRQ(11)	/* DMA8 Interrupt (UART0 RX) */
+#define IRQ_UART0_TX		BFIN_IRQ(12)	/* DMA9 Interrupt (UART0 TX) */
+#define IRQ_UART1_RX		BFIN_IRQ(13)	/* DMA10 Interrupt (UART1 RX) */
+#define IRQ_UART1_TX		BFIN_IRQ(14)	/* DMA11 Interrupt (UART1 TX) */
+#define IRQ_CAN_RX		BFIN_IRQ(15)	/* CAN Receive Interrupt */
+#define IRQ_CAN_TX		BFIN_IRQ(16)	/* CAN Transmit Interrupt */
+#define IRQ_PH_INTA_MAC_RX	BFIN_IRQ(17)	/* Port H Interrupt A & DMA1 Interrupt (Ethernet RX) */
+#define IRQ_PH_INTB_MAC_TX	BFIN_IRQ(18)	/* Port H Interrupt B & DMA2 Interrupt (Ethernet TX) */
+#define IRQ_TIMER0		BFIN_IRQ(19)	/* Timer 0 */
+#define IRQ_TIMER1		BFIN_IRQ(20)	/* Timer 1 */
+#define IRQ_TIMER2		BFIN_IRQ(21)	/* Timer 2 */
+#define IRQ_TIMER3		BFIN_IRQ(22)	/* Timer 3 */
+#define IRQ_TIMER4		BFIN_IRQ(23)	/* Timer 4 */
+#define IRQ_TIMER5		BFIN_IRQ(24)	/* Timer 5 */
+#define IRQ_TIMER6		BFIN_IRQ(25)	/* Timer 6 */
+#define IRQ_TIMER7		BFIN_IRQ(26)	/* Timer 7 */
+#define IRQ_PF_INTA_PG_INTA	BFIN_IRQ(27)	/* Ports F&G Interrupt A */
+#define IRQ_PORTG_INTB		BFIN_IRQ(28)	/* Port G Interrupt B */
+#define IRQ_MEM_DMA0		BFIN_IRQ(29)	/* (Memory DMA Stream 0) */
+#define IRQ_MEM_DMA1		BFIN_IRQ(30)	/* (Memory DMA Stream 1) */
+#define IRQ_PF_INTB_WATCH	BFIN_IRQ(31)	/* Watchdog & Port F Interrupt B */
 
-#define IRQ_PLL_WAKEUP      7	/*PLL Wakeup Interrupt */
-#define IRQ_DMA_ERROR       8	/*DMA Error (general) */
-#define IRQ_GENERIC_ERROR   9	/*GENERIC Error Interrupt */
-#define IRQ_RTC             10	/*RTC Interrupt */
-#define IRQ_PPI             11	/*DMA0 Interrupt (PPI) */
-#define IRQ_SPORT0_RX       12	/*DMA3 Interrupt (SPORT0 RX) */
-#define IRQ_SPORT0_TX       13	/*DMA4 Interrupt (SPORT0 TX) */
-#define IRQ_SPORT1_RX       14	/*DMA5 Interrupt (SPORT1 RX) */
-#define IRQ_SPORT1_TX       15	/*DMA6 Interrupt (SPORT1 TX) */
-#define IRQ_TWI             16	/*TWI Interrupt */
-#define IRQ_SPI             17	/*DMA7 Interrupt (SPI) */
-#define IRQ_UART0_RX        18	/*DMA8 Interrupt (UART0 RX) */
-#define IRQ_UART0_TX        19	/*DMA9 Interrupt (UART0 TX) */
-#define IRQ_UART1_RX        20	/*DMA10 Interrupt (UART1 RX) */
-#define IRQ_UART1_TX        21	/*DMA11 Interrupt (UART1 TX) */
-#define IRQ_CAN_RX          22	/*CAN Receive Interrupt */
-#define IRQ_CAN_TX          23	/*CAN Transmit Interrupt */
-#define IRQ_MAC_RX          24	/*DMA1 (Ethernet RX) Interrupt */
-#define IRQ_MAC_TX          25	/*DMA2 (Ethernet TX) Interrupt */
-#define IRQ_TIMER0            26	/*Timer 0 */
-#define IRQ_TIMER1            27	/*Timer 1 */
-#define IRQ_TIMER2            28	/*Timer 2 */
-#define IRQ_TIMER3            29	/*Timer 3 */
-#define IRQ_TIMER4            30	/*Timer 4 */
-#define IRQ_TIMER5            31	/*Timer 5 */
-#define IRQ_TIMER6            32	/*Timer 6 */
-#define IRQ_TIMER7            33	/*Timer 7 */
-#define IRQ_PROG_INTA       34	/* PF Ports F&G (PF15:0) Interrupt A */
-#define IRQ_PORTG_INTB      35	/* PF Port G (PF15:0) Interrupt B */
-#define IRQ_MEM_DMA0        36	/*(Memory DMA Stream 0) */
-#define IRQ_MEM_DMA1        37	/*(Memory DMA Stream 1) */
-#define IRQ_PROG_INTB	      38	/* PF Ports F (PF15:0) Interrupt B */
-#define IRQ_WATCH           38	/*Watch Dog Timer */
+#define SYS_IRQS		39
 
-#define IRQ_PPI_ERROR       42	/*PPI Error Interrupt */
-#define IRQ_CAN_ERROR       43	/*CAN Error Interrupt */
-#define IRQ_MAC_ERROR       44	/*MAC Status/Error Interrupt */
-#define IRQ_SPORT0_ERROR    45	/*SPORT0 Error Interrupt */
-#define IRQ_SPORT1_ERROR    46	/*SPORT1 Error Interrupt */
-#define IRQ_SPI_ERROR       47	/*SPI Error Interrupt */
-#define IRQ_UART0_ERROR     48	/*UART Error Interrupt */
-#define IRQ_UART1_ERROR     49	/*UART Error Interrupt */
+#define IRQ_PPI_ERROR		42	/* PPI Error Interrupt */
+#define IRQ_CAN_ERROR		43	/* CAN Error Interrupt */
+#define IRQ_MAC_ERROR		44	/* MAC Status/Error Interrupt */
+#define IRQ_SPORT0_ERROR	45	/* SPORT0 Error Interrupt */
+#define IRQ_SPORT1_ERROR	46	/* SPORT1 Error Interrupt */
+#define IRQ_SPI_ERROR		47	/* SPI Error Interrupt */
+#define IRQ_UART0_ERROR		48	/* UART Error Interrupt */
+#define IRQ_UART1_ERROR		49	/* UART Error Interrupt */
 
-#define IRQ_PF0         50
-#define IRQ_PF1         51
-#define IRQ_PF2         52
-#define IRQ_PF3         53
-#define IRQ_PF4         54
-#define IRQ_PF5         55
-#define IRQ_PF6         56
-#define IRQ_PF7         57
-#define IRQ_PF8         58
-#define IRQ_PF9         59
-#define IRQ_PF10        60
-#define IRQ_PF11        61
-#define IRQ_PF12        62
-#define IRQ_PF13        63
-#define IRQ_PF14        64
-#define IRQ_PF15        65
+#define IRQ_PF0			50
+#define IRQ_PF1			51
+#define IRQ_PF2			52
+#define IRQ_PF3			53
+#define IRQ_PF4			54
+#define IRQ_PF5			55
+#define IRQ_PF6			56
+#define IRQ_PF7			57
+#define IRQ_PF8			58
+#define IRQ_PF9			59
+#define IRQ_PF10		60
+#define IRQ_PF11		61
+#define IRQ_PF12		62
+#define IRQ_PF13		63
+#define IRQ_PF14		64
+#define IRQ_PF15		65
 
-#define IRQ_PG0         66
-#define IRQ_PG1         67
-#define IRQ_PG2         68
-#define IRQ_PG3         69
-#define IRQ_PG4         70
-#define IRQ_PG5         71
-#define IRQ_PG6         72
-#define IRQ_PG7         73
-#define IRQ_PG8         74
-#define IRQ_PG9         75
-#define IRQ_PG10        76
-#define IRQ_PG11        77
-#define IRQ_PG12        78
-#define IRQ_PG13        79
-#define IRQ_PG14        80
-#define IRQ_PG15        81
+#define IRQ_PG0			66
+#define IRQ_PG1			67
+#define IRQ_PG2			68
+#define IRQ_PG3			69
+#define IRQ_PG4			70
+#define IRQ_PG5			71
+#define IRQ_PG6			72
+#define IRQ_PG7			73
+#define IRQ_PG8			74
+#define IRQ_PG9			75
+#define IRQ_PG10		76
+#define IRQ_PG11		77
+#define IRQ_PG12		78
+#define IRQ_PG13		79
+#define IRQ_PG14		80
+#define IRQ_PG15		81
 
-#define IRQ_PH0         82
-#define IRQ_PH1         83
-#define IRQ_PH2         84
-#define IRQ_PH3         85
-#define IRQ_PH4         86
-#define IRQ_PH5         87
-#define IRQ_PH6         88
-#define IRQ_PH7         89
-#define IRQ_PH8         90
-#define IRQ_PH9         91
-#define IRQ_PH10        92
-#define IRQ_PH11        93
-#define IRQ_PH12        94
-#define IRQ_PH13        95
-#define IRQ_PH14        96
-#define IRQ_PH15        97
+#define IRQ_PH0			82
+#define IRQ_PH1			83
+#define IRQ_PH2			84
+#define IRQ_PH3			85
+#define IRQ_PH4			86
+#define IRQ_PH5			87
+#define IRQ_PH6			88
+#define IRQ_PH7			89
+#define IRQ_PH8			90
+#define IRQ_PH9			91
+#define IRQ_PH10		92
+#define IRQ_PH11		93
+#define IRQ_PH12		94
+#define IRQ_PH13		95
+#define IRQ_PH14		96
+#define IRQ_PH15		97
 
-#define GPIO_IRQ_BASE	IRQ_PF0
+#define GPIO_IRQ_BASE		IRQ_PF0
 
-#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 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 IRQ_MAC_RX		106	/* DMA1 Interrupt (Ethernet RX) */
+#define IRQ_PORTH_INTA		107	/* Port H Interrupt A */
 
-#define IVG7            7
-#define IVG8            8
-#define IVG9            9
-#define IVG10           10
-#define IVG11           11
-#define IVG12           12
-#define IVG13           13
-#define IVG14           14
-#define IVG15           15
+#if 0 /* No Interrupt B support (yet) */
+#define IRQ_MAC_TX		108	/* DMA2 Interrupt (Ethernet TX) */
+#define IRQ_PORTH_INTB		109	/* Port H Interrupt B */
+#else
+#define IRQ_MAC_TX		IRQ_PH_INTB_MAC_TX
+#endif
 
-/* IAR0 BIT FIELDS*/
-#define IRQ_PLL_WAKEUP_POS  0
-#define IRQ_DMA_ERROR_POS   4
-#define IRQ_ERROR_POS       8
-#define IRQ_RTC_POS         12
-#define IRQ_PPI_POS         16
-#define IRQ_SPORT0_RX_POS   20
-#define IRQ_SPORT0_TX_POS   24
-#define IRQ_SPORT1_RX_POS   28
+#define IRQ_PORTF_INTA		110	/* Port F Interrupt A */
+#define IRQ_PORTG_INTA		111	/* Port G Interrupt A */
 
-/* IAR1 BIT FIELDS*/
-#define IRQ_SPORT1_TX_POS   0
-#define IRQ_TWI_POS         4
-#define IRQ_SPI_POS         8
-#define IRQ_UART0_RX_POS    12
-#define IRQ_UART0_TX_POS    16
-#define IRQ_UART1_RX_POS    20
-#define IRQ_UART1_TX_POS    24
-#define IRQ_CAN_RX_POS      28
+#if 0 /* No Interrupt B support (yet) */
+#define IRQ_WATCH		112	/* Watchdog Timer */
+#define IRQ_PORTF_INTB		113	/* Port F Interrupt B */
+#else
+#define IRQ_WATCH		IRQ_PF_INTB_WATCH
+#endif
 
-/* IAR2 BIT FIELDS*/
-#define IRQ_CAN_TX_POS      0
-#define IRQ_MAC_RX_POS      4
-#define IRQ_MAC_TX_POS      8
-#define IRQ_TIMER0_POS        12
-#define IRQ_TIMER1_POS        16
-#define IRQ_TIMER2_POS        20
-#define IRQ_TIMER3_POS        24
-#define IRQ_TIMER4_POS        28
+#define NR_MACH_IRQS		(113 + 1)
 
-/* IAR3 BIT FIELDS*/
-#define IRQ_TIMER5_POS        0
-#define IRQ_TIMER6_POS        4
-#define IRQ_TIMER7_POS        8
-#define IRQ_PROG_INTA_POS   12
-#define IRQ_PORTG_INTB_POS   16
-#define IRQ_MEM_DMA0_POS    20
-#define IRQ_MEM_DMA1_POS    24
-#define IRQ_WATCH_POS       28
+/* IAR0 BIT FIELDS */
+#define IRQ_PLL_WAKEUP_POS	0
+#define IRQ_DMA_ERROR_POS	4
+#define IRQ_ERROR_POS		8
+#define IRQ_RTC_POS		12
+#define IRQ_PPI_POS		16
+#define IRQ_SPORT0_RX_POS	20
+#define IRQ_SPORT0_TX_POS	24
+#define IRQ_SPORT1_RX_POS	28
 
-#endif				/* _BF537_IRQ_H_ */
+/* IAR1 BIT FIELDS */
+#define IRQ_SPORT1_TX_POS	0
+#define IRQ_TWI_POS		4
+#define IRQ_SPI_POS		8
+#define IRQ_UART0_RX_POS	12
+#define IRQ_UART0_TX_POS	16
+#define IRQ_UART1_RX_POS	20
+#define IRQ_UART1_TX_POS	24
+#define IRQ_CAN_RX_POS		28
+
+/* IAR2 BIT FIELDS */
+#define IRQ_CAN_TX_POS		0
+#define IRQ_MAC_RX_POS		4
+#define IRQ_MAC_TX_POS		8
+#define IRQ_TIMER0_POS		12
+#define IRQ_TIMER1_POS		16
+#define IRQ_TIMER2_POS		20
+#define IRQ_TIMER3_POS		24
+#define IRQ_TIMER4_POS		28
+
+/* IAR3 BIT FIELDS */
+#define IRQ_TIMER5_POS		0
+#define IRQ_TIMER6_POS		4
+#define IRQ_TIMER7_POS		8
+#define IRQ_PROG_INTA_POS	12
+#define IRQ_PORTG_INTB_POS	16
+#define IRQ_MEM_DMA0_POS	20
+#define IRQ_MEM_DMA1_POS	24
+#define IRQ_WATCH_POS		28
+
+#define init_mach_irq init_mach_irq
+
+#endif
diff -druN linux-2.6.39-libre/arch/blackfin/mach-bf537/ints-priority.c linux-3.0-rc7-libre/arch/blackfin/mach-bf537/ints-priority.c
--- linux-2.6.39-libre/arch/blackfin/mach-bf537/ints-priority.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/blackfin/mach-bf537/ints-priority.c	2011-07-11 19:51:52.000000000 -0400
@@ -10,6 +10,13 @@
 #include <linux/irq.h>
 #include <asm/blackfin.h>
 
+#include <asm/irq_handler.h>
+#include <asm/bfin5xx_spi.h>
+#include <asm/bfin_sport.h>
+#include <asm/bfin_can.h>
+#include <asm/bfin_dma.h>
+#include <asm/dpmc.h>
+
 void __init program_IAR(void)
 {
 	/* Program the IAR0 Register with the configured priority */
@@ -51,3 +58,159 @@
 
 	SSYNC();
 }
+
+#define SPI_ERR_MASK   (BIT_STAT_TXCOL | BIT_STAT_RBSY | BIT_STAT_MODF | BIT_STAT_TXE)	/* SPI_STAT */
+#define SPORT_ERR_MASK (ROVF | RUVF | TOVF | TUVF)	/* SPORT_STAT */
+#define PPI_ERR_MASK   (0xFFFF & ~FLD)	/* PPI_STATUS */
+#define EMAC_ERR_MASK  (PHYINT | MMCINT | RXFSINT | TXFSINT | WAKEDET | RXDMAERR | TXDMAERR | STMDONE)	/* EMAC_SYSTAT */
+#define UART_ERR_MASK  (0x6)	/* UART_IIR */
+#define CAN_ERR_MASK   (EWTIF | EWRIF | EPIF | BOIF | WUIF | UIAIF | AAIF | RMLIF | UCEIF | EXTIF | ADIF)	/* CAN_GIF */
+
+static int error_int_mask;
+
+static void bf537_generic_error_mask_irq(struct irq_data *d)
+{
+	error_int_mask &= ~(1L << (d->irq - IRQ_PPI_ERROR));
+	if (!error_int_mask)
+		bfin_internal_mask_irq(IRQ_GENERIC_ERROR);
+}
+
+static void bf537_generic_error_unmask_irq(struct irq_data *d)
+{
+	bfin_internal_unmask_irq(IRQ_GENERIC_ERROR);
+	error_int_mask |= 1L << (d->irq - IRQ_PPI_ERROR);
+}
+
+static struct irq_chip bf537_generic_error_irqchip = {
+	.name = "ERROR",
+	.irq_ack = bfin_ack_noop,
+	.irq_mask_ack = bf537_generic_error_mask_irq,
+	.irq_mask = bf537_generic_error_mask_irq,
+	.irq_unmask = bf537_generic_error_unmask_irq,
+};
+
+static void bf537_demux_error_irq(unsigned int int_err_irq,
+				  struct irq_desc *inta_desc)
+{
+	int irq = 0;
+
+#if (defined(CONFIG_BF537) || defined(CONFIG_BF536))
+	if (bfin_read_EMAC_SYSTAT() & EMAC_ERR_MASK)
+		irq = IRQ_MAC_ERROR;
+	else
+#endif
+	if (bfin_read_SPORT0_STAT() & SPORT_ERR_MASK)
+		irq = IRQ_SPORT0_ERROR;
+	else if (bfin_read_SPORT1_STAT() & SPORT_ERR_MASK)
+		irq = IRQ_SPORT1_ERROR;
+	else if (bfin_read_PPI_STATUS() & PPI_ERR_MASK)
+		irq = IRQ_PPI_ERROR;
+	else if (bfin_read_CAN_GIF() & CAN_ERR_MASK)
+		irq = IRQ_CAN_ERROR;
+	else if (bfin_read_SPI_STAT() & SPI_ERR_MASK)
+		irq = IRQ_SPI_ERROR;
+	else if ((bfin_read_UART0_IIR() & UART_ERR_MASK) == UART_ERR_MASK)
+		irq = IRQ_UART0_ERROR;
+	else if ((bfin_read_UART1_IIR() & UART_ERR_MASK) == UART_ERR_MASK)
+		irq = IRQ_UART1_ERROR;
+
+	if (irq) {
+		if (error_int_mask & (1L << (irq - IRQ_PPI_ERROR)))
+			bfin_handle_irq(irq);
+		else {
+
+			switch (irq) {
+			case IRQ_PPI_ERROR:
+				bfin_write_PPI_STATUS(PPI_ERR_MASK);
+				break;
+#if (defined(CONFIG_BF537) || defined(CONFIG_BF536))
+			case IRQ_MAC_ERROR:
+				bfin_write_EMAC_SYSTAT(EMAC_ERR_MASK);
+				break;
+#endif
+			case IRQ_SPORT0_ERROR:
+				bfin_write_SPORT0_STAT(SPORT_ERR_MASK);
+				break;
+
+			case IRQ_SPORT1_ERROR:
+				bfin_write_SPORT1_STAT(SPORT_ERR_MASK);
+				break;
+
+			case IRQ_CAN_ERROR:
+				bfin_write_CAN_GIS(CAN_ERR_MASK);
+				break;
+
+			case IRQ_SPI_ERROR:
+				bfin_write_SPI_STAT(SPI_ERR_MASK);
+				break;
+
+			default:
+				break;
+			}
+
+			pr_debug("IRQ %d:"
+				 " MASKED PERIPHERAL ERROR INTERRUPT ASSERTED\n",
+				 irq);
+		}
+	} else
+		pr_err("%s: IRQ ?: PERIPHERAL ERROR INTERRUPT ASSERTED BUT NO SOURCE FOUND\n",
+		       __func__);
+
+}
+
+#if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE)
+static int mac_rx_int_mask;
+
+static void bf537_mac_rx_mask_irq(struct irq_data *d)
+{
+	mac_rx_int_mask &= ~(1L << (d->irq - IRQ_MAC_RX));
+	if (!mac_rx_int_mask)
+		bfin_internal_mask_irq(IRQ_PH_INTA_MAC_RX);
+}
+
+static void bf537_mac_rx_unmask_irq(struct irq_data *d)
+{
+	bfin_internal_unmask_irq(IRQ_PH_INTA_MAC_RX);
+	mac_rx_int_mask |= 1L << (d->irq - IRQ_MAC_RX);
+}
+
+static struct irq_chip bf537_mac_rx_irqchip = {
+	.name = "ERROR",
+	.irq_ack = bfin_ack_noop,
+	.irq_mask_ack = bf537_mac_rx_mask_irq,
+	.irq_mask = bf537_mac_rx_mask_irq,
+	.irq_unmask = bf537_mac_rx_unmask_irq,
+};
+
+static void bf537_demux_mac_rx_irq(unsigned int int_irq,
+				   struct irq_desc *desc)
+{
+	if (bfin_read_DMA1_IRQ_STATUS() & (DMA_DONE | DMA_ERR))
+		bfin_handle_irq(IRQ_MAC_RX);
+	else
+		bfin_demux_gpio_irq(int_irq, desc);
+}
+#endif
+
+void __init init_mach_irq(void)
+{
+	int irq;
+
+#if defined(CONFIG_BF537) || defined(CONFIG_BF536)
+	/* Clear EMAC Interrupt Status bits so we can demux it later */
+	bfin_write_EMAC_SYSTAT(-1);
+#endif
+
+	irq_set_chained_handler(IRQ_GENERIC_ERROR, bf537_demux_error_irq);
+	for (irq = IRQ_PPI_ERROR; irq <= IRQ_UART1_ERROR; irq++)
+		irq_set_chip_and_handler(irq, &bf537_generic_error_irqchip,
+					 handle_level_irq);
+
+#if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE)
+	irq_set_chained_handler(IRQ_PH_INTA_MAC_RX, bf537_demux_mac_rx_irq);
+	irq_set_chip_and_handler(IRQ_MAC_RX, &bf537_mac_rx_irqchip, handle_level_irq);
+	irq_set_chip_and_handler(IRQ_PORTH_INTA, &bf537_mac_rx_irqchip, handle_level_irq);
+
+	irq_set_chained_handler(IRQ_MAC_ERROR, bfin_demux_mac_status_irq);
+#endif
+}
diff -druN linux-2.6.39-libre/arch/blackfin/mach-bf538/include/mach/anomaly.h linux-3.0-rc7-libre/arch/blackfin/mach-bf538/include/mach/anomaly.h
--- linux-2.6.39-libre/arch/blackfin/mach-bf538/include/mach/anomaly.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/blackfin/mach-bf538/include/mach/anomaly.h	2011-07-11 19:51:52.000000000 -0400
@@ -5,14 +5,14 @@
  * and can be replaced with that version at any time
  * DO NOT EDIT THIS FILE
  *
- * Copyright 2004-2010 Analog Devices Inc.
+ * Copyright 2004-2011 Analog Devices Inc.
  * Licensed under the ADI BSD license.
  *   https://docs.blackfin.uclinux.org/doku.php?id=adi_bsd
  */
 
 /* This file should be up to date with:
- *  - Revision H, 07/10/2009; ADSP-BF538/BF538F Blackfin Processor Anomaly List
- *  - Revision M, 07/10/2009; ADSP-BF539/BF539F Blackfin Processor Anomaly List
+ *  - Revision I, 05/25/2010; ADSP-BF538/BF538F Blackfin Processor Anomaly List
+ *  - Revision N, 05/25/2010; ADSP-BF539/BF539F Blackfin Processor Anomaly List
  */
 
 #ifndef _MACH_ANOMALY_H_
@@ -179,6 +179,7 @@
 #define ANOMALY_05000363 (0)
 #define ANOMALY_05000364 (0)
 #define ANOMALY_05000380 (0)
+#define ANOMALY_05000383 (0)
 #define ANOMALY_05000386 (1)
 #define ANOMALY_05000389 (0)
 #define ANOMALY_05000400 (0)
@@ -186,6 +187,7 @@
 #define ANOMALY_05000430 (0)
 #define ANOMALY_05000432 (0)
 #define ANOMALY_05000435 (0)
+#define ANOMALY_05000440 (0)
 #define ANOMALY_05000447 (0)
 #define ANOMALY_05000448 (0)
 #define ANOMALY_05000456 (0)
@@ -193,6 +195,7 @@
 #define ANOMALY_05000465 (0)
 #define ANOMALY_05000467 (0)
 #define ANOMALY_05000474 (0)
+#define ANOMALY_05000480 (0)
 #define ANOMALY_05000485 (0)
 
 #endif
diff -druN linux-2.6.39-libre/arch/blackfin/mach-bf538/include/mach/bfin_serial_5xx.h linux-3.0-rc7-libre/arch/blackfin/mach-bf538/include/mach/bfin_serial_5xx.h
--- linux-2.6.39-libre/arch/blackfin/mach-bf538/include/mach/bfin_serial_5xx.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/blackfin/mach-bf538/include/mach/bfin_serial_5xx.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,93 +0,0 @@
-/*
- * Copyright 2008-2009 Analog Devices Inc.
- *
- * Licensed under the GPL-2 or later.
- */
-
-#include <asm/dma.h>
-#include <asm/portmux.h>
-
-#if defined(CONFIG_BFIN_UART0_CTSRTS) || defined(CONFIG_BFIN_UART1_CTSRTS)
-# define CONFIG_SERIAL_BFIN_CTSRTS
-
-# ifndef CONFIG_UART0_CTS_PIN
-#  define CONFIG_UART0_CTS_PIN -1
-# endif
-
-# ifndef CONFIG_UART0_RTS_PIN
-#  define CONFIG_UART0_RTS_PIN -1
-# endif
-
-# ifndef CONFIG_UART1_CTS_PIN
-#  define CONFIG_UART1_CTS_PIN -1
-# endif
-
-# ifndef CONFIG_UART1_RTS_PIN
-#  define CONFIG_UART1_RTS_PIN -1
-# endif
-#endif
-
-struct bfin_serial_res {
-	unsigned long	uart_base_addr;
-	int		uart_irq;
-	int		uart_status_irq;
-#ifdef CONFIG_SERIAL_BFIN_DMA
-	unsigned int	uart_tx_dma_channel;
-	unsigned int	uart_rx_dma_channel;
-#endif
-#ifdef CONFIG_SERIAL_BFIN_CTSRTS
-	int	uart_cts_pin;
-	int	uart_rts_pin;
-#endif
-};
-
-struct bfin_serial_res bfin_serial_resource[] = {
-#ifdef CONFIG_SERIAL_BFIN_UART0
-	{
-	0xFFC00400,
-	IRQ_UART0_RX,
-	IRQ_UART0_ERROR,
-#ifdef CONFIG_SERIAL_BFIN_DMA
-	CH_UART0_TX,
-	CH_UART0_RX,
-#endif
-#ifdef CONFIG_SERIAL_BFIN_CTSRTS
-	CONFIG_UART0_CTS_PIN,
-	CONFIG_UART0_RTS_PIN,
-#endif
-	},
-#endif
-#ifdef CONFIG_SERIAL_BFIN_UART1
-	{
-	0xFFC02000,
-	IRQ_UART1_RX,
-	IRQ_UART1_ERROR,
-#ifdef CONFIG_SERIAL_BFIN_DMA
-	CH_UART1_TX,
-	CH_UART1_RX,
-#endif
-#ifdef CONFIG_SERIAL_BFIN_CTSRTS
-	CONFIG_UART1_CTS_PIN,
-	CONFIG_UART1_RTS_PIN,
-#endif
-	},
-#endif
-#ifdef CONFIG_SERIAL_BFIN_UART2
-	{
-	0xFFC02100,
-	IRQ_UART2_RX,
-#ifdef CONFIG_SERIAL_BFIN_DMA
-	CH_UART2_TX,
-	CH_UART2_RX,
-#endif
-#ifdef CONFIG_BFIN_UART2_CTSRTS
-	CONFIG_UART2_CTS_PIN,
-	CONFIG_UART2_RTS_PIN,
-#endif
-	},
-#endif
-};
-
-#define DRIVER_NAME "bfin-uart"
-
-#include <asm/bfin_serial.h>
diff -druN linux-2.6.39-libre/arch/blackfin/mach-bf538/include/mach/irq.h linux-3.0-rc7-libre/arch/blackfin/mach-bf538/include/mach/irq.h
--- linux-2.6.39-libre/arch/blackfin/mach-bf538/include/mach/irq.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/blackfin/mach-bf538/include/mach/irq.h	2011-07-11 19:51:52.000000000 -0400
@@ -7,38 +7,9 @@
 #ifndef _BF538_IRQ_H_
 #define _BF538_IRQ_H_
 
-/*
- * Interrupt source definitions
-	Event Source    Core Event Name
-	Core        Emulation               **
-	Events         (highest priority)  EMU         0
-	Reset                   RST         1
-	NMI                     NMI         2
-	Exception               EVX         3
-	Reserved                --          4
-	Hardware Error          IVHW        5
-	Core Timer              IVTMR       6 *
-
-	.....
-
-	 Software Interrupt 1    IVG14       31
-	 Software Interrupt 2    --
-	 (lowest priority)  IVG15       32 *
-*/
-
-#define NR_PERI_INTS    (2 * 32)
-
-/* The ABSTRACT IRQ definitions */
-/** the first seven of the following are fixed, the rest you change if you need to **/
-#define IRQ_EMU			0	/* Emulation */
-#define IRQ_RST			1	/* reset */
-#define IRQ_NMI			2	/* Non Maskable */
-#define IRQ_EVX			3	/* Exception */
-#define IRQ_UNUSED		4	/* - unused interrupt */
-#define IRQ_HWERR		5	/* Hardware Error */
-#define IRQ_CORETMR		6	/* Core timer */
+#include <mach-common/irq.h>
 
-#define BFIN_IRQ(x)		((x) + 7)
+#define NR_PERI_INTS		(2 * 32)
 
 #define IRQ_PLL_WAKEUP		BFIN_IRQ(0)	/* PLL Wakeup Interrupt */
 #define IRQ_DMA0_ERROR		BFIN_IRQ(1)	/* DMA Error 0 (generic) */
@@ -91,37 +62,26 @@
 
 #define SYS_IRQS		BFIN_IRQ(63)	/* 70 */
 
-#define IRQ_PF0         71
-#define IRQ_PF1         72
-#define IRQ_PF2         73
-#define IRQ_PF3         74
-#define IRQ_PF4         75
-#define IRQ_PF5         76
-#define IRQ_PF6         77
-#define IRQ_PF7         78
-#define IRQ_PF8         79
-#define IRQ_PF9         80
-#define IRQ_PF10        81
-#define IRQ_PF11        82
-#define IRQ_PF12        83
-#define IRQ_PF13        84
-#define IRQ_PF14        85
-#define IRQ_PF15        86
-
-#define GPIO_IRQ_BASE	IRQ_PF0
+#define IRQ_PF0			71
+#define IRQ_PF1			72
+#define IRQ_PF2			73
+#define IRQ_PF3			74
+#define IRQ_PF4			75
+#define IRQ_PF5			76
+#define IRQ_PF6			77
+#define IRQ_PF7			78
+#define IRQ_PF8			79
+#define IRQ_PF9			80
+#define IRQ_PF10		81
+#define IRQ_PF11		82
+#define IRQ_PF12		83
+#define IRQ_PF13		84
+#define IRQ_PF14		85
+#define IRQ_PF15		86
 
-#define NR_MACH_IRQS	(IRQ_PF15 + 1)
-#define NR_IRQS		(NR_MACH_IRQS + NR_SPARE_IRQS)
+#define GPIO_IRQ_BASE		IRQ_PF0
 
-#define IVG7            7
-#define IVG8            8
-#define IVG9            9
-#define IVG10           10
-#define IVG11           11
-#define IVG12           12
-#define IVG13           13
-#define IVG14           14
-#define IVG15           15
+#define NR_MACH_IRQS		(IRQ_PF15 + 1)
 
 /* IAR0 BIT FIELDS */
 #define IRQ_PLL_WAKEUP_POS	0
@@ -184,4 +144,5 @@
 #define IRQ_CAN_TX_POS		0
 #define IRQ_MEM1_DMA0_POS	4
 #define IRQ_MEM1_DMA1_POS	8
-#endif				/* _BF538_IRQ_H_ */
+
+#endif
diff -druN linux-2.6.39-libre/arch/blackfin/mach-bf548/boards/ezkit.c linux-3.0-rc7-libre/arch/blackfin/mach-bf548/boards/ezkit.c
--- linux-2.6.39-libre/arch/blackfin/mach-bf548/boards/ezkit.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/blackfin/mach-bf548/boards/ezkit.c	2011-07-11 19:51:52.000000000 -0400
@@ -22,6 +22,7 @@
 #include <asm/gpio.h>
 #include <asm/nand.h>
 #include <asm/dpmc.h>
+#include <asm/bfin_sport.h>
 #include <asm/portmux.h>
 #include <asm/bfin_sdh.h>
 #include <mach/bf54x_keys.h>
@@ -956,7 +957,15 @@
 		.offset     = MTDPART_OFS_APPEND,
 	}, {
 		.name       = "file system(nor)",
-		.size       = MTDPART_SIZ_FULL,
+		.size       = 0x1000000 - 0x80000 - 0x400000 - 0x8000 * 4,
+		.offset     = MTDPART_OFS_APPEND,
+	}, {
+		.name       = "config(nor)",
+		.size       = 0x8000 * 3,
+		.offset     = MTDPART_OFS_APPEND,
+	}, {
+		.name       = "u-boot env(nor)",
+		.size       = 0x8000,
 		.offset     = MTDPART_OFS_APPEND,
 	}
 };
@@ -1312,27 +1321,110 @@
 	},
 };
 
-#if defined(CONFIG_SND_BF5XX_I2S) || defined(CONFIG_SND_BF5XX_I2S_MODULE)
+#if defined(CONFIG_SND_BF5XX_I2S) || defined(CONFIG_SND_BF5XX_I2S_MODULE) || \
+	defined(CONFIG_SND_BF5XX_TDM) || defined(CONFIG_SND_BF5XX_TDM_MODULE) || \
+	defined(CONFIG_SND_BF5XX_AC97) || defined(CONFIG_SND_BF5XX_AC97_MODULE)
+
+#define SPORT_REQ(x) \
+	[x] = {P_SPORT##x##_TFS, P_SPORT##x##_DTPRI, P_SPORT##x##_TSCLK, \
+		P_SPORT##x##_RFS, P_SPORT##x##_DRPRI, P_SPORT##x##_RSCLK, 0}
+
+static const u16 bfin_snd_pin[][7] = {
+	SPORT_REQ(0),
+	SPORT_REQ(1),
+};
+
+static struct bfin_snd_platform_data bfin_snd_data[] = {
+	{
+		.pin_req = &bfin_snd_pin[0][0],
+	},
+	{
+		.pin_req = &bfin_snd_pin[1][0],
+	},
+};
+
+#define BFIN_SND_RES(x) \
+	[x] = { \
+		{ \
+			.start = SPORT##x##_TCR1, \
+			.end = SPORT##x##_TCR1, \
+			.flags = IORESOURCE_MEM \
+		}, \
+		{ \
+			.start = CH_SPORT##x##_RX, \
+			.end = CH_SPORT##x##_RX, \
+			.flags = IORESOURCE_DMA, \
+		}, \
+		{ \
+			.start = CH_SPORT##x##_TX, \
+			.end = CH_SPORT##x##_TX, \
+			.flags = IORESOURCE_DMA, \
+		}, \
+		{ \
+			.start = IRQ_SPORT##x##_ERROR, \
+			.end = IRQ_SPORT##x##_ERROR, \
+			.flags = IORESOURCE_IRQ, \
+		} \
+	}
+
+static struct resource bfin_snd_resources[][4] = {
+	BFIN_SND_RES(0),
+	BFIN_SND_RES(1),
+};
+
+static struct platform_device bfin_pcm = {
+	.name = "bfin-pcm-audio",
+	.id = -1,
+};
+#endif
+
+#if defined(CONFIG_SND_BF5XX_SOC_AD73311) || defined(CONFIG_SND_BF5XX_SOC_AD73311_MODULE)
+static struct platform_device bfin_ad73311_codec_device = {
+	.name = "ad73311",
+	.id = -1,
+};
+#endif
+
+#if defined(CONFIG_SND_BF5XX_SOC_AD1980) || defined(CONFIG_SND_BF5XX_SOC_AD1980_MODULE)
+static struct platform_device bfin_ad1980_codec_device = {
+	.name = "ad1980",
+	.id = -1,
+};
+#endif
+
+#if defined(CONFIG_SND_BF5XX_SOC_I2S) || defined(CONFIG_SND_BF5XX_SOC_I2S_MODULE)
 static struct platform_device bfin_i2s = {
 	.name = "bfin-i2s",
 	.id = CONFIG_SND_BF5XX_SPORT_NUM,
-	/* TODO: add platform data here */
+	.num_resources = ARRAY_SIZE(bfin_snd_resources[CONFIG_SND_BF5XX_SPORT_NUM]),
+	.resource = bfin_snd_resources[CONFIG_SND_BF5XX_SPORT_NUM],
+	.dev = {
+		.platform_data = &bfin_snd_data[CONFIG_SND_BF5XX_SPORT_NUM],
+	},
 };
 #endif
 
-#if defined(CONFIG_SND_BF5XX_TDM) || defined(CONFIG_SND_BF5XX_TDM_MODULE)
+#if defined(CONFIG_SND_BF5XX_SOC_TDM) || defined(CONFIG_SND_BF5XX_SOC_TDM_MODULE)
 static struct platform_device bfin_tdm = {
 	.name = "bfin-tdm",
 	.id = CONFIG_SND_BF5XX_SPORT_NUM,
-	/* TODO: add platform data here */
+	.num_resources = ARRAY_SIZE(bfin_snd_resources[CONFIG_SND_BF5XX_SPORT_NUM]),
+	.resource = bfin_snd_resources[CONFIG_SND_BF5XX_SPORT_NUM],
+	.dev = {
+		.platform_data = &bfin_snd_data[CONFIG_SND_BF5XX_SPORT_NUM],
+	},
 };
 #endif
 
-#if defined(CONFIG_SND_BF5XX_AC97) || defined(CONFIG_SND_BF5XX_AC97_MODULE)
+#if defined(CONFIG_SND_BF5XX_SOC_AC97) || defined(CONFIG_SND_BF5XX_SOC_AC97_MODULE)
 static struct platform_device bfin_ac97 = {
 	.name = "bfin-ac97",
 	.id = CONFIG_SND_BF5XX_SPORT_NUM,
-	/* TODO: add platform data here */
+	.num_resources = ARRAY_SIZE(bfin_snd_resources[CONFIG_SND_BF5XX_SPORT_NUM]),
+	.resource = bfin_snd_resources[CONFIG_SND_BF5XX_SPORT_NUM],
+	.dev = {
+		.platform_data = &bfin_snd_data[CONFIG_SND_BF5XX_SPORT_NUM],
+	},
 };
 #endif
 
@@ -1450,6 +1542,16 @@
 	&ezkit_flash_device,
 #endif
 
+#if defined(CONFIG_SND_BF5XX_I2S) || defined(CONFIG_SND_BF5XX_I2S_MODULE) || \
+	defined(CONFIG_SND_BF5XX_TDM) || defined(CONFIG_SND_BF5XX_TDM_MODULE) || \
+	defined(CONFIG_SND_BF5XX_AC97) || defined(CONFIG_SND_BF5XX_AC97_MODULE)
+	&bfin_pcm,
+#endif
+
+#if defined(CONFIG_SND_BF5XX_SOC_AD1980) || defined(CONFIG_SND_BF5XX_SOC_AD1980_MODULE)
+	&bfin_ad1980_codec_device,
+#endif
+
 #if defined(CONFIG_SND_BF5XX_I2S) || defined(CONFIG_SND_BF5XX_I2S_MODULE)
 	&bfin_i2s,
 #endif
diff -druN linux-2.6.39-libre/arch/blackfin/mach-bf548/include/mach/anomaly.h linux-3.0-rc7-libre/arch/blackfin/mach-bf548/include/mach/anomaly.h
--- linux-2.6.39-libre/arch/blackfin/mach-bf548/include/mach/anomaly.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/blackfin/mach-bf548/include/mach/anomaly.h	2011-07-11 19:51:52.000000000 -0400
@@ -5,13 +5,13 @@
  * and can be replaced with that version at any time
  * DO NOT EDIT THIS FILE
  *
- * Copyright 2004-2010 Analog Devices Inc.
+ * Copyright 2004-2011 Analog Devices Inc.
  * Licensed under the ADI BSD license.
  *   https://docs.blackfin.uclinux.org/doku.php?id=adi_bsd
  */
 
 /* This file should be up to date with:
- *  - Revision I, 07/23/2009; ADSP-BF542/BF544/BF547/BF548/BF549 Blackfin Processor Anomaly List
+ *  - Revision J, 06/03/2010; ADSP-BF542/BF544/BF547/BF548/BF549 Blackfin Processor Anomaly List
  */
 
 #ifndef _MACH_ANOMALY_H_
@@ -220,6 +220,8 @@
 #define ANOMALY_05000481 (1)
 /* Possible USB Data Corruption When Multiple Endpoints Are Accessed by the Core */
 #define ANOMALY_05000483 (1)
+/* DDR Trim May Not Be Performed for Certain VLEV Values in OTP Page PBS00L */
+#define ANOMALY_05000484 (__SILICON_REVISION__ < 3)
 /* PLL_CTL Change Using bfrom_SysControl() Can Result in Processor Overclocking */
 #define ANOMALY_05000485 (__SILICON_REVISION__ >= 2)
 /* IFLUSH sucks at life */
@@ -274,6 +276,8 @@
 #define ANOMALY_05000412 (0)
 #define ANOMALY_05000432 (0)
 #define ANOMALY_05000435 (0)
+#define ANOMALY_05000440 (0)
 #define ANOMALY_05000475 (0)
+#define ANOMALY_05000480 (0)
 
 #endif
diff -druN linux-2.6.39-libre/arch/blackfin/mach-bf548/include/mach/bfin_serial_5xx.h linux-3.0-rc7-libre/arch/blackfin/mach-bf548/include/mach/bfin_serial_5xx.h
--- linux-2.6.39-libre/arch/blackfin/mach-bf548/include/mach/bfin_serial_5xx.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/blackfin/mach-bf548/include/mach/bfin_serial_5xx.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,94 +0,0 @@
-/*
- * Copyright 2007-2009 Analog Devices Inc.
- *
- * Licensed under the GPL-2 or later.
- */
-
-#include <asm/dma.h>
-#include <asm/portmux.h>
-
-#if defined(CONFIG_BFIN_UART0_CTSRTS) || defined(CONFIG_BFIN_UART1_CTSRTS) || \
-	defined(CONFIG_BFIN_UART2_CTSRTS) || defined(CONFIG_BFIN_UART3_CTSRTS)
-# define CONFIG_SERIAL_BFIN_HARD_CTSRTS
-#endif
-
-struct bfin_serial_res {
-	unsigned long	uart_base_addr;
-	int		uart_irq;
-	int		uart_status_irq;
-#ifdef CONFIG_SERIAL_BFIN_DMA
-	unsigned int	uart_tx_dma_channel;
-	unsigned int	uart_rx_dma_channel;
-#endif
-#ifdef CONFIG_SERIAL_BFIN_HARD_CTSRTS
-	int		uart_cts_pin;
-	int		uart_rts_pin;
-#endif
-};
-
-struct bfin_serial_res bfin_serial_resource[] = {
-#ifdef CONFIG_SERIAL_BFIN_UART0
-	{
-	0xFFC00400,
-	IRQ_UART0_RX,
-	IRQ_UART0_ERROR,
-#ifdef CONFIG_SERIAL_BFIN_DMA
-	CH_UART0_TX,
-	CH_UART0_RX,
-#endif
-#ifdef CONFIG_SERIAL_BFIN_HARD_CTSRTS
-	0,
-	0,
-#endif
-	},
-#endif
-#ifdef CONFIG_SERIAL_BFIN_UART1
-	{
-	0xFFC02000,
-	IRQ_UART1_RX,
-	IRQ_UART1_ERROR,
-#ifdef CONFIG_SERIAL_BFIN_DMA
-	CH_UART1_TX,
-	CH_UART1_RX,
-#endif
-#ifdef CONFIG_SERIAL_BFIN_HARD_CTSRTS
-	GPIO_PE10,
-	GPIO_PE9,
-#endif
-	},
-#endif
-#ifdef CONFIG_SERIAL_BFIN_UART2
-	{
-	0xFFC02100,
-	IRQ_UART2_RX,
-	IRQ_UART2_ERROR,
-#ifdef CONFIG_SERIAL_BFIN_DMA
-	CH_UART2_TX,
-	CH_UART2_RX,
-#endif
-#ifdef CONFIG_SERIAL_BFIN_HARD_CTSRTS
-	0,
-	0,
-#endif
-	},
-#endif
-#ifdef CONFIG_SERIAL_BFIN_UART3
-	{
-	0xFFC03100,
-	IRQ_UART3_RX,
-	IRQ_UART3_ERROR,
-#ifdef CONFIG_SERIAL_BFIN_DMA
-	CH_UART3_TX,
-	CH_UART3_RX,
-#endif
-#ifdef CONFIG_SERIAL_BFIN_HARD_CTSRTS
-	GPIO_PB3,
-	GPIO_PB2,
-#endif
-	},
-#endif
-};
-
-#define DRIVER_NAME "bfin-uart"
-
-#include <asm/bfin_serial.h>
diff -druN linux-2.6.39-libre/arch/blackfin/mach-bf548/include/mach/defBF547.h linux-3.0-rc7-libre/arch/blackfin/mach-bf548/include/mach/defBF547.h
--- linux-2.6.39-libre/arch/blackfin/mach-bf548/include/mach/defBF547.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/blackfin/mach-bf548/include/mach/defBF547.h	2011-07-11 19:51:52.000000000 -0400
@@ -271,10 +271,10 @@
 #define            USB_EP_NI0_TXINTERVAL  0xffc03e18   /* Sets the NAK response timeout on Endpoint 0 */
 #define                USB_EP_NI0_RXTYPE  0xffc03e1c   /* Sets the transaction protocol and peripheral endpoint number for the Host Rx endpoint0 */
 #define            USB_EP_NI0_RXINTERVAL  0xffc03e20   /* Sets the polling interval for Interrupt/Isochronous transfers or the NAK response timeout on Bulk transfers for Host Rx endpoint0 */
+#define               USB_EP_NI0_TXCOUNT  0xffc03e28   /* Number of bytes to be written to the endpoint0 Tx FIFO */
 
 /* USB Endpoint 1 Control Registers */
 
-#define               USB_EP_NI0_TXCOUNT  0xffc03e28   /* Number of bytes to be written to the endpoint0 Tx FIFO */
 #define                USB_EP_NI1_TXMAXP  0xffc03e40   /* Maximum packet size for Host Tx endpoint1 */
 #define                 USB_EP_NI1_TXCSR  0xffc03e44   /* Control Status register for endpoint1 */
 #define                USB_EP_NI1_RXMAXP  0xffc03e48   /* Maximum packet size for Host Rx endpoint1 */
@@ -284,10 +284,10 @@
 #define            USB_EP_NI1_TXINTERVAL  0xffc03e58   /* Sets the NAK response timeout on Endpoint1 */
 #define                USB_EP_NI1_RXTYPE  0xffc03e5c   /* Sets the transaction protocol and peripheral endpoint number for the Host Rx endpoint1 */
 #define            USB_EP_NI1_RXINTERVAL  0xffc03e60   /* Sets the polling interval for Interrupt/Isochronous transfers or the NAK response timeout on Bulk transfers for Host Rx endpoint1 */
+#define               USB_EP_NI1_TXCOUNT  0xffc03e68   /* Number of bytes to be written to the+H102 endpoint1 Tx FIFO */
 
 /* USB Endpoint 2 Control Registers */
 
-#define               USB_EP_NI1_TXCOUNT  0xffc03e68   /* Number of bytes to be written to the+H102 endpoint1 Tx FIFO */
 #define                USB_EP_NI2_TXMAXP  0xffc03e80   /* Maximum packet size for Host Tx endpoint2 */
 #define                 USB_EP_NI2_TXCSR  0xffc03e84   /* Control Status register for endpoint2 */
 #define                USB_EP_NI2_RXMAXP  0xffc03e88   /* Maximum packet size for Host Rx endpoint2 */
@@ -297,10 +297,10 @@
 #define            USB_EP_NI2_TXINTERVAL  0xffc03e98   /* Sets the NAK response timeout on Endpoint2 */
 #define                USB_EP_NI2_RXTYPE  0xffc03e9c   /* Sets the transaction protocol and peripheral endpoint number for the Host Rx endpoint2 */
 #define            USB_EP_NI2_RXINTERVAL  0xffc03ea0   /* Sets the polling interval for Interrupt/Isochronous transfers or the NAK response timeout on Bulk transfers for Host Rx endpoint2 */
+#define               USB_EP_NI2_TXCOUNT  0xffc03ea8   /* Number of bytes to be written to the endpoint2 Tx FIFO */
 
 /* USB Endpoint 3 Control Registers */
 
-#define               USB_EP_NI2_TXCOUNT  0xffc03ea8   /* Number of bytes to be written to the endpoint2 Tx FIFO */
 #define                USB_EP_NI3_TXMAXP  0xffc03ec0   /* Maximum packet size for Host Tx endpoint3 */
 #define                 USB_EP_NI3_TXCSR  0xffc03ec4   /* Control Status register for endpoint3 */
 #define                USB_EP_NI3_RXMAXP  0xffc03ec8   /* Maximum packet size for Host Rx endpoint3 */
@@ -310,10 +310,10 @@
 #define            USB_EP_NI3_TXINTERVAL  0xffc03ed8   /* Sets the NAK response timeout on Endpoint3 */
 #define                USB_EP_NI3_RXTYPE  0xffc03edc   /* Sets the transaction protocol and peripheral endpoint number for the Host Rx endpoint3 */
 #define            USB_EP_NI3_RXINTERVAL  0xffc03ee0   /* Sets the polling interval for Interrupt/Isochronous transfers or the NAK response timeout on Bulk transfers for Host Rx endpoint3 */
+#define               USB_EP_NI3_TXCOUNT  0xffc03ee8   /* Number of bytes to be written to the H124endpoint3 Tx FIFO */
 
 /* USB Endpoint 4 Control Registers */
 
-#define               USB_EP_NI3_TXCOUNT  0xffc03ee8   /* Number of bytes to be written to the H124endpoint3 Tx FIFO */
 #define                USB_EP_NI4_TXMAXP  0xffc03f00   /* Maximum packet size for Host Tx endpoint4 */
 #define                 USB_EP_NI4_TXCSR  0xffc03f04   /* Control Status register for endpoint4 */
 #define                USB_EP_NI4_RXMAXP  0xffc03f08   /* Maximum packet size for Host Rx endpoint4 */
@@ -323,10 +323,10 @@
 #define            USB_EP_NI4_TXINTERVAL  0xffc03f18   /* Sets the NAK response timeout on Endpoint4 */
 #define                USB_EP_NI4_RXTYPE  0xffc03f1c   /* Sets the transaction protocol and peripheral endpoint number for the Host Rx endpoint4 */
 #define            USB_EP_NI4_RXINTERVAL  0xffc03f20   /* Sets the polling interval for Interrupt/Isochronous transfers or the NAK response timeout on Bulk transfers for Host Rx endpoint4 */
+#define               USB_EP_NI4_TXCOUNT  0xffc03f28   /* Number of bytes to be written to the endpoint4 Tx FIFO */
 
 /* USB Endpoint 5 Control Registers */
 
-#define               USB_EP_NI4_TXCOUNT  0xffc03f28   /* Number of bytes to be written to the endpoint4 Tx FIFO */
 #define                USB_EP_NI5_TXMAXP  0xffc03f40   /* Maximum packet size for Host Tx endpoint5 */
 #define                 USB_EP_NI5_TXCSR  0xffc03f44   /* Control Status register for endpoint5 */
 #define                USB_EP_NI5_RXMAXP  0xffc03f48   /* Maximum packet size for Host Rx endpoint5 */
@@ -336,10 +336,10 @@
 #define            USB_EP_NI5_TXINTERVAL  0xffc03f58   /* Sets the NAK response timeout on Endpoint5 */
 #define                USB_EP_NI5_RXTYPE  0xffc03f5c   /* Sets the transaction protocol and peripheral endpoint number for the Host Rx endpoint5 */
 #define            USB_EP_NI5_RXINTERVAL  0xffc03f60   /* Sets the polling interval for Interrupt/Isochronous transfers or the NAK response timeout on Bulk transfers for Host Rx endpoint5 */
+#define               USB_EP_NI5_TXCOUNT  0xffc03f68   /* Number of bytes to be written to the H145endpoint5 Tx FIFO */
 
 /* USB Endpoint 6 Control Registers */
 
-#define               USB_EP_NI5_TXCOUNT  0xffc03f68   /* Number of bytes to be written to the H145endpoint5 Tx FIFO */
 #define                USB_EP_NI6_TXMAXP  0xffc03f80   /* Maximum packet size for Host Tx endpoint6 */
 #define                 USB_EP_NI6_TXCSR  0xffc03f84   /* Control Status register for endpoint6 */
 #define                USB_EP_NI6_RXMAXP  0xffc03f88   /* Maximum packet size for Host Rx endpoint6 */
@@ -349,10 +349,10 @@
 #define            USB_EP_NI6_TXINTERVAL  0xffc03f98   /* Sets the NAK response timeout on Endpoint6 */
 #define                USB_EP_NI6_RXTYPE  0xffc03f9c   /* Sets the transaction protocol and peripheral endpoint number for the Host Rx endpoint6 */
 #define            USB_EP_NI6_RXINTERVAL  0xffc03fa0   /* Sets the polling interval for Interrupt/Isochronous transfers or the NAK response timeout on Bulk transfers for Host Rx endpoint6 */
+#define               USB_EP_NI6_TXCOUNT  0xffc03fa8   /* Number of bytes to be written to the endpoint6 Tx FIFO */
 
 /* USB Endpoint 7 Control Registers */
 
-#define               USB_EP_NI6_TXCOUNT  0xffc03fa8   /* Number of bytes to be written to the endpoint6 Tx FIFO */
 #define                USB_EP_NI7_TXMAXP  0xffc03fc0   /* Maximum packet size for Host Tx endpoint7 */
 #define                 USB_EP_NI7_TXCSR  0xffc03fc4   /* Control Status register for endpoint7 */
 #define                USB_EP_NI7_RXMAXP  0xffc03fc8   /* Maximum packet size for Host Rx endpoint7 */
@@ -361,8 +361,9 @@
 #define                USB_EP_NI7_TXTYPE  0xffc03fd4   /* Sets the transaction protocol and peripheral endpoint number for the Host Tx endpoint7 */
 #define            USB_EP_NI7_TXINTERVAL  0xffc03fd8   /* Sets the NAK response timeout on Endpoint7 */
 #define                USB_EP_NI7_RXTYPE  0xffc03fdc   /* Sets the transaction protocol and peripheral endpoint number for the Host Rx endpoint7 */
-#define            USB_EP_NI7_RXINTERVAL  0xffc03ff0   /* Sets the polling interval for Interrupt/Isochronous transfers or the NAK response timeout on Bulk transfers for Host Rx endpoint7 */
-#define               USB_EP_NI7_TXCOUNT  0xffc03ff8   /* Number of bytes to be written to the endpoint7 Tx FIFO */
+#define            USB_EP_NI7_RXINTERVAL  0xffc03fe0   /* Sets the polling interval for Interrupt/Isochronous transfers or the NAK response timeout on Bulk transfers for Host Rx endpoint7 */
+#define               USB_EP_NI7_TXCOUNT  0xffc03fe8   /* Number of bytes to be written to the endpoint7 Tx FIFO */
+
 #define                USB_DMA_INTERRUPT  0xffc04000   /* Indicates pending interrupts for the DMA channels */
 
 /* USB Channel 0 Config Registers */
diff -druN linux-2.6.39-libre/arch/blackfin/mach-bf548/include/mach/irq.h linux-3.0-rc7-libre/arch/blackfin/mach-bf548/include/mach/irq.h
--- linux-2.6.39-libre/arch/blackfin/mach-bf548/include/mach/irq.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/blackfin/mach-bf548/include/mach/irq.h	2011-07-11 19:51:52.000000000 -0400
@@ -7,38 +7,9 @@
 #ifndef _BF548_IRQ_H_
 #define _BF548_IRQ_H_
 
-/*
- * Interrupt source definitions
-            Event Source    Core Event Name
-Core        Emulation               **
-Events         (highest priority)  EMU         0
-            Reset                   RST         1
-            NMI                     NMI         2
-            Exception               EVX         3
-            Reserved                --          4
-            Hardware Error          IVHW        5
-            Core Timer              IVTMR       6 *
-
-.....
-
-            Software Interrupt 1    IVG14       31
-            Software Interrupt 2    --
-                 (lowest priority)  IVG15       32 *
- */
-
-#define NR_PERI_INTS    (32 * 3)
-
-/* The ABSTRACT IRQ definitions */
-/** the first seven of the following are fixed, the rest you change if you need to **/
-#define IRQ_EMU			0	/* Emulation */
-#define IRQ_RST			1	/* reset */
-#define IRQ_NMI			2	/* Non Maskable */
-#define IRQ_EVX			3	/* Exception */
-#define IRQ_UNUSED		4	/* - unused interrupt*/
-#define IRQ_HWERR		5	/* Hardware Error */
-#define IRQ_CORETMR		6	/* Core timer */
+#include <mach-common/irq.h>
 
-#define BFIN_IRQ(x)		((x) + 7)
+#define NR_PERI_INTS		(3 * 32)
 
 #define IRQ_PLL_WAKEUP		BFIN_IRQ(0)	/* PLL Wakeup Interrupt */
 #define IRQ_DMAC0_ERROR		BFIN_IRQ(1)	/* DMAC0 Status Interrupt */
@@ -311,49 +282,37 @@
 #define IRQ_PJ14		BFIN_PJ_IRQ(14)		/* N/A */
 #define IRQ_PJ15		BFIN_PJ_IRQ(15)		/* N/A */
 
-#define GPIO_IRQ_BASE	IRQ_PA0
+#define GPIO_IRQ_BASE		IRQ_PA0
 
-#define NR_MACH_IRQS	(IRQ_PJ15 + 1)
-#define NR_IRQS		(NR_MACH_IRQS + NR_SPARE_IRQS)
+#define NR_MACH_IRQS		(IRQ_PJ15 + 1)
 
 /* For compatibility reasons with existing code */
 
-#define IRQ_DMAC0_ERR 		IRQ_DMAC0_ERROR
-#define IRQ_EPPI0_ERR 		IRQ_EPPI0_ERROR
+#define IRQ_DMAC0_ERR		IRQ_DMAC0_ERROR
+#define IRQ_EPPI0_ERR		IRQ_EPPI0_ERROR
 #define IRQ_SPORT0_ERR		IRQ_SPORT0_ERROR
 #define IRQ_SPORT1_ERR		IRQ_SPORT1_ERROR
-#define IRQ_SPI0_ERR  		IRQ_SPI0_ERROR
-#define IRQ_UART0_ERR 		IRQ_UART0_ERROR
-#define IRQ_DMAC1_ERR 		IRQ_DMAC1_ERROR
+#define IRQ_SPI0_ERR		IRQ_SPI0_ERROR
+#define IRQ_UART0_ERR		IRQ_UART0_ERROR
+#define IRQ_DMAC1_ERR		IRQ_DMAC1_ERROR
 #define IRQ_SPORT2_ERR		IRQ_SPORT2_ERROR
 #define IRQ_SPORT3_ERR		IRQ_SPORT3_ERROR
-#define IRQ_SPI1_ERR  		IRQ_SPI1_ERROR
-#define IRQ_SPI2_ERR  		IRQ_SPI2_ERROR
-#define IRQ_UART1_ERR 		IRQ_UART1_ERROR
-#define IRQ_UART2_ERR 		IRQ_UART2_ERROR
-#define IRQ_CAN0_ERR  		IRQ_CAN0_ERROR
-#define IRQ_MXVR_ERR  		IRQ_MXVR_ERROR
-#define IRQ_EPPI1_ERR  		IRQ_EPPI1_ERROR
-#define IRQ_EPPI2_ERR  		IRQ_EPPI2_ERROR
-#define IRQ_UART3_ERR 		IRQ_UART3_ERROR
-#define IRQ_HOST_ERR  		IRQ_HOST_ERROR
-#define IRQ_PIXC_ERR  		IRQ_PIXC_ERROR
-#define IRQ_NFC_ERR   		IRQ_NFC_ERROR
-#define IRQ_ATAPI_ERR 		IRQ_ATAPI_ERROR
-#define IRQ_CAN1_ERR  		IRQ_CAN1_ERROR
+#define IRQ_SPI1_ERR		IRQ_SPI1_ERROR
+#define IRQ_SPI2_ERR		IRQ_SPI2_ERROR
+#define IRQ_UART1_ERR		IRQ_UART1_ERROR
+#define IRQ_UART2_ERR		IRQ_UART2_ERROR
+#define IRQ_CAN0_ERR		IRQ_CAN0_ERROR
+#define IRQ_MXVR_ERR		IRQ_MXVR_ERROR
+#define IRQ_EPPI1_ERR		IRQ_EPPI1_ERROR
+#define IRQ_EPPI2_ERR		IRQ_EPPI2_ERROR
+#define IRQ_UART3_ERR		IRQ_UART3_ERROR
+#define IRQ_HOST_ERR		IRQ_HOST_ERROR
+#define IRQ_PIXC_ERR		IRQ_PIXC_ERROR
+#define IRQ_NFC_ERR		IRQ_NFC_ERROR
+#define IRQ_ATAPI_ERR		IRQ_ATAPI_ERROR
+#define IRQ_CAN1_ERR		IRQ_CAN1_ERROR
 #define IRQ_HS_DMA_ERR		IRQ_HS_DMA_ERROR
 
-
-#define IVG7            7
-#define IVG8            8
-#define IVG9            9
-#define IVG10           10
-#define IVG11           11
-#define IVG12           12
-#define IVG13           13
-#define IVG14           14
-#define IVG15           15
-
 /* IAR0 BIT FIELDS */
 #define IRQ_PLL_WAKEUP_POS	0
 #define IRQ_DMAC0_ERR_POS	4
@@ -492,4 +451,4 @@
 
 #endif
 
-#endif /* _BF548_IRQ_H_ */
+#endif
diff -druN linux-2.6.39-libre/arch/blackfin/mach-bf561/boards/acvilon.c linux-3.0-rc7-libre/arch/blackfin/mach-bf561/boards/acvilon.c
--- linux-2.6.39-libre/arch/blackfin/mach-bf561/boards/acvilon.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/blackfin/mach-bf561/boards/acvilon.c	2011-07-11 19:51:52.000000000 -0400
@@ -243,7 +243,6 @@
 
 #if defined(CONFIG_MTD_NAND_PLATFORM) || defined(CONFIG_MTD_NAND_PLATFORM_MODULE)
 
-#ifdef CONFIG_MTD_PARTITIONS
 const char *part_probes[] = { "cmdlinepart", NULL };
 
 static struct mtd_partition bfin_plat_nand_partitions[] = {
@@ -257,7 +256,6 @@
 	     .offset = MTDPART_OFS_APPEND,
 	     },
 };
-#endif
 
 #define BFIN_NAND_PLAT_CLE 2
 #define BFIN_NAND_PLAT_ALE 3
@@ -286,11 +284,9 @@
 	.chip = {
 		 .nr_chips = 1,
 		 .chip_delay = 30,
-#ifdef CONFIG_MTD_PARTITIONS
 		 .part_probe_types = part_probes,
 		 .partitions = bfin_plat_nand_partitions,
 		 .nr_partitions = ARRAY_SIZE(bfin_plat_nand_partitions),
-#endif
 		 },
 	.ctrl = {
 		 .cmd_ctrl = bfin_plat_nand_cmd_ctrl,
diff -druN linux-2.6.39-libre/arch/blackfin/mach-bf561/boards/ezkit.c linux-3.0-rc7-libre/arch/blackfin/mach-bf561/boards/ezkit.c
--- linux-2.6.39-libre/arch/blackfin/mach-bf561/boards/ezkit.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/blackfin/mach-bf561/boards/ezkit.c	2011-07-11 19:51:52.000000000 -0400
@@ -247,7 +247,15 @@
 		.offset     = MTDPART_OFS_APPEND,
 	}, {
 		.name       = "file system(nor)",
-		.size       = MTDPART_SIZ_FULL,
+		.size       = 0x800000 - 0x40000 - 0x1C0000 - 0x2000 * 8,
+		.offset     = MTDPART_OFS_APPEND,
+	}, {
+		.name       = "config(nor)",
+		.size       = 0x2000 * 7,
+		.offset     = MTDPART_OFS_APPEND,
+	}, {
+		.name       = "u-boot env(nor)",
+		.size       = 0x2000,
 		.offset     = MTDPART_OFS_APPEND,
 	}
 };
diff -druN linux-2.6.39-libre/arch/blackfin/mach-bf561/include/mach/anomaly.h linux-3.0-rc7-libre/arch/blackfin/mach-bf561/include/mach/anomaly.h
--- linux-2.6.39-libre/arch/blackfin/mach-bf561/include/mach/anomaly.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/blackfin/mach-bf561/include/mach/anomaly.h	2011-07-11 19:51:52.000000000 -0400
@@ -5,13 +5,13 @@
  * and can be replaced with that version at any time
  * DO NOT EDIT THIS FILE
  *
- * Copyright 2004-2010 Analog Devices Inc.
+ * Copyright 2004-2011 Analog Devices Inc.
  * Licensed under the ADI BSD license.
  *   https://docs.blackfin.uclinux.org/doku.php?id=adi_bsd
  */
 
 /* This file should be up to date with:
- *  - Revision Q, 11/07/2008; ADSP-BF561 Blackfin Processor Anomaly List
+ *  - Revision R, 05/25/2010; ADSP-BF561 Blackfin Processor Anomaly List
  */
 
 #ifndef _MACH_ANOMALY_H_
@@ -290,12 +290,18 @@
 #define ANOMALY_05000428 (__SILICON_REVISION__ > 3)
 /* IFLUSH Instruction at End of Hardware Loop Causes Infinite Stall */
 #define ANOMALY_05000443 (1)
+/* SCKELOW Feature Is Not Functional */
+#define ANOMALY_05000458 (1)
 /* False Hardware Error when RETI Points to Invalid Memory */
 #define ANOMALY_05000461 (1)
+/* Synchronization Problem at Startup May Cause SPORT Transmit Channels to Misalign */
+#define ANOMALY_05000462 (1)
+/* Boot Failure When SDRAM Control Signals Toggle Coming Out Of Reset */
+#define ANOMALY_05000471 (1)
 /* Interrupted 32-Bit SPORT Data Register Access Results In Underflow */
 #define ANOMALY_05000473 (1)
 /* Possible Lockup Condition whem Modifying PLL from External Memory */
-#define ANOMALY_05000475 (__SILICON_REVISION__ < 4)
+#define ANOMALY_05000475 (1)
 /* TESTSET Instruction Cannot Be Interrupted */
 #define ANOMALY_05000477 (1)
 /* Reads of ITEST_COMMAND and ITEST_DATA Registers Cause Cache Corruption */
@@ -314,12 +320,14 @@
 #define ANOMALY_05000353 (1)
 #define ANOMALY_05000364 (0)
 #define ANOMALY_05000380 (0)
+#define ANOMALY_05000383 (0)
 #define ANOMALY_05000386 (1)
 #define ANOMALY_05000389 (0)
 #define ANOMALY_05000400 (0)
 #define ANOMALY_05000430 (0)
 #define ANOMALY_05000432 (0)
 #define ANOMALY_05000435 (0)
+#define ANOMALY_05000440 (0)
 #define ANOMALY_05000447 (0)
 #define ANOMALY_05000448 (0)
 #define ANOMALY_05000456 (0)
@@ -327,6 +335,7 @@
 #define ANOMALY_05000465 (0)
 #define ANOMALY_05000467 (0)
 #define ANOMALY_05000474 (0)
+#define ANOMALY_05000480 (0)
 #define ANOMALY_05000485 (0)
 
 #endif
diff -druN linux-2.6.39-libre/arch/blackfin/mach-bf561/include/mach/bfin_serial_5xx.h linux-3.0-rc7-libre/arch/blackfin/mach-bf561/include/mach/bfin_serial_5xx.h
--- linux-2.6.39-libre/arch/blackfin/mach-bf561/include/mach/bfin_serial_5xx.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/blackfin/mach-bf561/include/mach/bfin_serial_5xx.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,52 +0,0 @@
-/*
- * Copyright 2006-2009 Analog Devices Inc.
- *
- * Licensed under the GPL-2 or later.
- */
-
-#include <asm/dma.h>
-#include <asm/portmux.h>
-
-#ifdef CONFIG_BFIN_UART0_CTSRTS
-# define CONFIG_SERIAL_BFIN_CTSRTS
-# ifndef CONFIG_UART0_CTS_PIN
-#  define CONFIG_UART0_CTS_PIN -1
-# endif
-# ifndef CONFIG_UART0_RTS_PIN
-#  define CONFIG_UART0_RTS_PIN -1
-# endif
-#endif
-
-struct bfin_serial_res {
-	unsigned long	uart_base_addr;
-	int		uart_irq;
-	int		uart_status_irq;
-#ifdef CONFIG_SERIAL_BFIN_DMA
-	unsigned int	uart_tx_dma_channel;
-	unsigned int	uart_rx_dma_channel;
-#endif
-#ifdef CONFIG_SERIAL_BFIN_CTSRTS
-	int		uart_cts_pin;
-	int		uart_rts_pin;
-#endif
-};
-
-struct bfin_serial_res bfin_serial_resource[] = {
-	{
-	0xFFC00400,
-	IRQ_UART_RX,
-	IRQ_UART_ERROR,
-#ifdef CONFIG_SERIAL_BFIN_DMA
-	CH_UART_TX,
-	CH_UART_RX,
-#endif
-#ifdef CONFIG_SERIAL_BFIN_CTSRTS
-	CONFIG_UART0_CTS_PIN,
-	CONFIG_UART0_RTS_PIN,
-#endif
-	}
-};
-
-#define DRIVER_NAME "bfin-uart"
-
-#include <asm/bfin_serial.h>
diff -druN linux-2.6.39-libre/arch/blackfin/mach-bf561/include/mach/irq.h linux-3.0-rc7-libre/arch/blackfin/mach-bf561/include/mach/irq.h
--- linux-2.6.39-libre/arch/blackfin/mach-bf561/include/mach/irq.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/blackfin/mach-bf561/include/mach/irq.h	2011-07-11 19:51:52.000000000 -0400
@@ -7,212 +7,98 @@
 #ifndef _BF561_IRQ_H_
 #define _BF561_IRQ_H_
 
-/***********************************************************************
- * Interrupt source definitions:
-             Event Source		Core Event Name	    IRQ No
-						(highest priority)
-	    Emulation Events			EMU         0
-            Reset				RST         1
-            NMI					NMI         2
-            Exception				EVX         3
-            Reserved				--          4
-            Hardware Error			IVHW        5
-            Core Timer				IVTMR       6 *
-
-	    PLL Wakeup Interrupt		IVG7	    7
-	    DMA1 Error (generic)		IVG7	    8
-	    DMA2 Error (generic)		IVG7	    9
-	    IMDMA Error (generic)		IVG7	    10
-	    PPI1 Error Interrupt		IVG7	    11
-	    PPI2 Error Interrupt		IVG7	    12
-	    SPORT0 Error Interrupt		IVG7	    13
-	    SPORT1 Error Interrupt		IVG7	    14
-	    SPI Error Interrupt			IVG7	    15
-	    UART Error Interrupt		IVG7	    16
-	    Reserved Interrupt			IVG7        17
-
-	    DMA1 0  Interrupt(PPI1)	        IVG8	    18
-	    DMA1 1  Interrupt(PPI2)             IVG8	    19
-	    DMA1 2  Interrupt	                IVG8	    20
-	    DMA1 3  Interrupt	                IVG8	    21
-	    DMA1 4  Interrupt	                IVG8	    22
-	    DMA1 5  Interrupt	                IVG8	    23
-	    DMA1 6  Interrupt	                IVG8	    24
-	    DMA1 7  Interrupt	                IVG8	    25
-	    DMA1 8  Interrupt	                IVG8	    26
-	    DMA1 9  Interrupt	                IVG8	    27
-	    DMA1 10 Interrupt	                IVG8	    28
-	    DMA1 11 Interrupt	                IVG8	    29
-
-	    DMA2 0  (SPORT0 RX)		        IVG9	    30
-	    DMA2 1  (SPORT0 TX)	                IVG9	    31
-	    DMA2 2  (SPORT1 RX)	                IVG9	    32
-	    DMA2 3  (SPORT2 TX)	                IVG9	    33
-	    DMA2 4  (SPI)	                IVG9	    34
-	    DMA2 5  (UART RX)	                IVG9	    35
-	    DMA2 6  (UART TX)	                IVG9	    36
-	    DMA2 7  Interrupt	                IVG9	    37
-	    DMA2 8  Interrupt	                IVG9	    38
-	    DMA2 9  Interrupt	                IVG9	    39
-	    DMA2 10 Interrupt	                IVG9	    40
-	    DMA2 11 Interrupt	                IVG9	    41
-
-	    TIMER 0  Interrupt		        IVG10	    42
-	    TIMER 1  Interrupt	                IVG10	    43
-	    TIMER 2  Interrupt	                IVG10	    44
-	    TIMER 3  Interrupt	                IVG10	    45
-	    TIMER 4  Interrupt	                IVG10	    46
-	    TIMER 5  Interrupt	                IVG10	    47
-	    TIMER 6  Interrupt	                IVG10	    48
-	    TIMER 7  Interrupt	                IVG10	    49
-	    TIMER 8  Interrupt	                IVG10	    50
-	    TIMER 9  Interrupt	                IVG10	    51
-	    TIMER 10 Interrupt	                IVG10	    52
-	    TIMER 11 Interrupt	                IVG10	    53
-
-	    Programmable Flags0 A (8)	        IVG11	    54
-	    Programmable Flags0 B (8)           IVG11	    55
-	    Programmable Flags1 A (8)           IVG11	    56
-	    Programmable Flags1 B (8)           IVG11	    57
-	    Programmable Flags2 A (8)           IVG11	    58
-	    Programmable Flags2 B (8)           IVG11	    59
-
-	    MDMA1 0 write/read INT		IVG8	    60
-	    MDMA1 1 write/read INT		IVG8	    61
-
-	    MDMA2 0 write/read INT		IVG9	    62
-	    MDMA2 1 write/read INT		IVG9	    63
-
-	    IMDMA 0 write/read INT		IVG12	    64
-	    IMDMA 1 write/read INT		IVG12	    65
-
-	    Watch Dog Timer			IVG13	    66
-
-	    Reserved interrupt			IVG7	    67
-	    Reserved interrupt			IVG7	    68
-	    Supplemental interrupt 0		IVG7	    69
-	    supplemental interrupt 1		IVG7	    70
-
-            Softirq		    		IVG14
-            System Call    --
-                 (lowest priority)  		IVG15
-
- **********************************************************************/
-
-#define SYS_IRQS		71
-#define NR_PERI_INTS		64
+#include <mach-common/irq.h>
 
-/*
- * The ABSTRACT IRQ definitions
- *  the first seven of the following are fixed,
- *  the rest you change if you need to.
- */
-/* IVG 0-6*/
-#define	IRQ_EMU			0	/* Emulation                */
-#define	IRQ_RST			1	/* Reset                    */
-#define	IRQ_NMI			2	/* Non Maskable Interrupt   */
-#define	IRQ_EVX			3	/* Exception                */
-#define	IRQ_UNUSED		4	/* Reserved interrupt       */
-#define	IRQ_HWERR		5	/* Hardware Error           */
-#define	IRQ_CORETMR		6	/* Core timer               */
+#define NR_PERI_INTS		(2 * 32)
 
-#define IVG_BASE		7
-/* IVG 7  */
-#define	IRQ_PLL_WAKEUP		(IVG_BASE + 0)	/* PLL Wakeup Interrupt     */
-#define	IRQ_DMA1_ERROR		(IVG_BASE + 1)	/* DMA1   Error (general)   */
-#define	IRQ_DMA_ERROR		IRQ_DMA1_ERROR	/* DMA1   Error (general)   */
-#define	IRQ_DMA2_ERROR		(IVG_BASE + 2)	/* DMA2   Error (general)   */
-#define IRQ_IMDMA_ERROR		(IVG_BASE + 3)	/* IMDMA  Error Interrupt   */
-#define	IRQ_PPI1_ERROR		(IVG_BASE + 4)	/* PPI1   Error Interrupt   */
-#define	IRQ_PPI_ERROR		IRQ_PPI1_ERROR	/* PPI1   Error Interrupt   */
-#define	IRQ_PPI2_ERROR		(IVG_BASE + 5)	/* PPI2   Error Interrupt   */
-#define	IRQ_SPORT0_ERROR	(IVG_BASE + 6)	/* SPORT0 Error Interrupt   */
-#define	IRQ_SPORT1_ERROR	(IVG_BASE + 7)	/* SPORT1 Error Interrupt   */
-#define	IRQ_SPI_ERROR		(IVG_BASE + 8)	/* SPI    Error Interrupt   */
-#define	IRQ_UART_ERROR		(IVG_BASE + 9)	/* UART   Error Interrupt   */
-#define IRQ_RESERVED_ERROR	(IVG_BASE + 10)	/* Reversed     Interrupt   */
-/* IVG 8  */
-#define	IRQ_DMA1_0		(IVG_BASE + 11)	/* DMA1 0  Interrupt(PPI1)  */
-#define	IRQ_PPI			IRQ_DMA1_0	/* DMA1 0  Interrupt(PPI1)  */
-#define	IRQ_PPI0		IRQ_DMA1_0	/* DMA1 0  Interrupt(PPI1)  */
-#define	IRQ_DMA1_1		(IVG_BASE + 12)	/* DMA1 1  Interrupt(PPI2)  */
-#define	IRQ_PPI1		IRQ_DMA1_1	/* DMA1 1  Interrupt(PPI2)  */
-#define	IRQ_DMA1_2		(IVG_BASE + 13)	/* DMA1 2  Interrupt        */
-#define	IRQ_DMA1_3		(IVG_BASE + 14)	/* DMA1 3  Interrupt        */
-#define	IRQ_DMA1_4		(IVG_BASE + 15)	/* DMA1 4  Interrupt        */
-#define	IRQ_DMA1_5		(IVG_BASE + 16)	/* DMA1 5  Interrupt        */
-#define	IRQ_DMA1_6		(IVG_BASE + 17)	/* DMA1 6  Interrupt        */
-#define	IRQ_DMA1_7		(IVG_BASE + 18)	/* DMA1 7  Interrupt        */
-#define	IRQ_DMA1_8		(IVG_BASE + 19)	/* DMA1 8  Interrupt        */
-#define	IRQ_DMA1_9		(IVG_BASE + 20)	/* DMA1 9  Interrupt        */
-#define	IRQ_DMA1_10		(IVG_BASE + 21)	/* DMA1 10 Interrupt        */
-#define	IRQ_DMA1_11		(IVG_BASE + 22)	/* DMA1 11 Interrupt        */
-/* IVG 9  */
-#define	IRQ_DMA2_0		(IVG_BASE + 23)	/* DMA2 0  (SPORT0 RX)      */
-#define	IRQ_SPORT0_RX		IRQ_DMA2_0	/* DMA2 0  (SPORT0 RX)      */
-#define	IRQ_DMA2_1		(IVG_BASE + 24)	/* DMA2 1  (SPORT0 TX)      */
-#define	IRQ_SPORT0_TX		IRQ_DMA2_1	/* DMA2 1  (SPORT0 TX)      */
-#define	IRQ_DMA2_2		(IVG_BASE + 25)	/* DMA2 2  (SPORT1 RX)      */
-#define	IRQ_SPORT1_RX		IRQ_DMA2_2	/* DMA2 2  (SPORT1 RX)      */
-#define	IRQ_DMA2_3		(IVG_BASE + 26)	/* DMA2 3  (SPORT2 TX)      */
-#define	IRQ_SPORT1_TX		IRQ_DMA2_3	/* DMA2 3  (SPORT2 TX)      */
-#define	IRQ_DMA2_4		(IVG_BASE + 27)	/* DMA2 4  (SPI)            */
-#define	IRQ_SPI			IRQ_DMA2_4	/* DMA2 4  (SPI)            */
-#define	IRQ_DMA2_5		(IVG_BASE + 28)	/* DMA2 5  (UART RX)        */
-#define	IRQ_UART_RX		IRQ_DMA2_5	/* DMA2 5  (UART RX)        */
-#define	IRQ_DMA2_6		(IVG_BASE + 29)	/* DMA2 6  (UART TX)        */
-#define	IRQ_UART_TX		IRQ_DMA2_6	/* DMA2 6  (UART TX)        */
-#define	IRQ_DMA2_7		(IVG_BASE + 30)	/* DMA2 7  Interrupt        */
-#define	IRQ_DMA2_8		(IVG_BASE + 31)	/* DMA2 8  Interrupt        */
-#define	IRQ_DMA2_9		(IVG_BASE + 32)	/* DMA2 9  Interrupt        */
-#define	IRQ_DMA2_10		(IVG_BASE + 33)	/* DMA2 10 Interrupt        */
-#define	IRQ_DMA2_11		(IVG_BASE + 34)	/* DMA2 11 Interrupt        */
-/* IVG 10 */
-#define IRQ_TIMER0		(IVG_BASE + 35)	/* TIMER 0  Interrupt       */
-#define IRQ_TIMER1		(IVG_BASE + 36)	/* TIMER 1  Interrupt       */
-#define IRQ_TIMER2		(IVG_BASE + 37)	/* TIMER 2  Interrupt       */
-#define IRQ_TIMER3		(IVG_BASE + 38)	/* TIMER 3  Interrupt       */
-#define IRQ_TIMER4		(IVG_BASE + 39)	/* TIMER 4  Interrupt       */
-#define IRQ_TIMER5		(IVG_BASE + 40)	/* TIMER 5  Interrupt       */
-#define IRQ_TIMER6		(IVG_BASE + 41)	/* TIMER 6  Interrupt       */
-#define IRQ_TIMER7		(IVG_BASE + 42)	/* TIMER 7  Interrupt       */
-#define IRQ_TIMER8		(IVG_BASE + 43)	/* TIMER 8  Interrupt       */
-#define IRQ_TIMER9		(IVG_BASE + 44)	/* TIMER 9  Interrupt       */
-#define IRQ_TIMER10		(IVG_BASE + 45)	/* TIMER 10 Interrupt       */
-#define IRQ_TIMER11		(IVG_BASE + 46)	/* TIMER 11 Interrupt       */
-/* IVG 11 */
-#define	IRQ_PROG0_INTA		(IVG_BASE + 47)	/* Programmable Flags0 A (8) */
-#define	IRQ_PROG_INTA		IRQ_PROG0_INTA	/* Programmable Flags0 A (8) */
-#define	IRQ_PROG0_INTB		(IVG_BASE + 48)	/* Programmable Flags0 B (8) */
-#define	IRQ_PROG_INTB		IRQ_PROG0_INTB	/* Programmable Flags0 B (8) */
-#define	IRQ_PROG1_INTA		(IVG_BASE + 49)	/* Programmable Flags1 A (8) */
-#define	IRQ_PROG1_INTB		(IVG_BASE + 50)	/* Programmable Flags1 B (8) */
-#define	IRQ_PROG2_INTA		(IVG_BASE + 51)	/* Programmable Flags2 A (8) */
-#define	IRQ_PROG2_INTB		(IVG_BASE + 52)	/* Programmable Flags2 B (8) */
-/* IVG 8  */
-#define IRQ_DMA1_WRRD0		(IVG_BASE + 53)	/* MDMA1 0 write/read INT   */
-#define IRQ_DMA_WRRD0		IRQ_DMA1_WRRD0	/* MDMA1 0 write/read INT   */
+#define IRQ_PLL_WAKEUP		BFIN_IRQ(0)	/* PLL Wakeup Interrupt */
+#define IRQ_DMA1_ERROR		BFIN_IRQ(1)	/* DMA1   Error (general) */
+#define IRQ_DMA_ERROR		IRQ_DMA1_ERROR	/* DMA1   Error (general) */
+#define IRQ_DMA2_ERROR		BFIN_IRQ(2)	/* DMA2   Error (general) */
+#define IRQ_IMDMA_ERROR		BFIN_IRQ(3)	/* IMDMA  Error Interrupt */
+#define IRQ_PPI1_ERROR		BFIN_IRQ(4)	/* PPI1   Error Interrupt */
+#define IRQ_PPI_ERROR		IRQ_PPI1_ERROR	/* PPI1   Error Interrupt */
+#define IRQ_PPI2_ERROR		BFIN_IRQ(5)	/* PPI2   Error Interrupt */
+#define IRQ_SPORT0_ERROR	BFIN_IRQ(6)	/* SPORT0 Error Interrupt */
+#define IRQ_SPORT1_ERROR	BFIN_IRQ(7)	/* SPORT1 Error Interrupt */
+#define IRQ_SPI_ERROR		BFIN_IRQ(8)	/* SPI    Error Interrupt */
+#define IRQ_UART_ERROR		BFIN_IRQ(9)	/* UART   Error Interrupt */
+#define IRQ_RESERVED_ERROR	BFIN_IRQ(10)	/* Reversed */
+#define IRQ_DMA1_0		BFIN_IRQ(11)	/* DMA1 0  Interrupt(PPI1) */
+#define IRQ_PPI			IRQ_DMA1_0	/* DMA1 0  Interrupt(PPI1) */
+#define IRQ_PPI0		IRQ_DMA1_0	/* DMA1 0  Interrupt(PPI1) */
+#define IRQ_DMA1_1		BFIN_IRQ(12)	/* DMA1 1  Interrupt(PPI2) */
+#define IRQ_PPI1		IRQ_DMA1_1	/* DMA1 1  Interrupt(PPI2) */
+#define IRQ_DMA1_2		BFIN_IRQ(13)	/* DMA1 2  Interrupt */
+#define IRQ_DMA1_3		BFIN_IRQ(14)	/* DMA1 3  Interrupt */
+#define IRQ_DMA1_4		BFIN_IRQ(15)	/* DMA1 4  Interrupt */
+#define IRQ_DMA1_5		BFIN_IRQ(16)	/* DMA1 5  Interrupt */
+#define IRQ_DMA1_6		BFIN_IRQ(17)	/* DMA1 6  Interrupt */
+#define IRQ_DMA1_7		BFIN_IRQ(18)	/* DMA1 7  Interrupt */
+#define IRQ_DMA1_8		BFIN_IRQ(19)	/* DMA1 8  Interrupt */
+#define IRQ_DMA1_9		BFIN_IRQ(20)	/* DMA1 9  Interrupt */
+#define IRQ_DMA1_10		BFIN_IRQ(21)	/* DMA1 10 Interrupt */
+#define IRQ_DMA1_11		BFIN_IRQ(22)	/* DMA1 11 Interrupt */
+#define IRQ_DMA2_0		BFIN_IRQ(23)	/* DMA2 0  (SPORT0 RX) */
+#define IRQ_SPORT0_RX		IRQ_DMA2_0	/* DMA2 0  (SPORT0 RX) */
+#define IRQ_DMA2_1		BFIN_IRQ(24)	/* DMA2 1  (SPORT0 TX) */
+#define IRQ_SPORT0_TX		IRQ_DMA2_1	/* DMA2 1  (SPORT0 TX) */
+#define IRQ_DMA2_2		BFIN_IRQ(25)	/* DMA2 2  (SPORT1 RX) */
+#define IRQ_SPORT1_RX		IRQ_DMA2_2	/* DMA2 2  (SPORT1 RX) */
+#define IRQ_DMA2_3		BFIN_IRQ(26)	/* DMA2 3  (SPORT2 TX) */
+#define IRQ_SPORT1_TX		IRQ_DMA2_3	/* DMA2 3  (SPORT2 TX) */
+#define IRQ_DMA2_4		BFIN_IRQ(27)	/* DMA2 4  (SPI) */
+#define IRQ_SPI			IRQ_DMA2_4	/* DMA2 4  (SPI) */
+#define IRQ_DMA2_5		BFIN_IRQ(28)	/* DMA2 5  (UART RX) */
+#define IRQ_UART_RX		IRQ_DMA2_5	/* DMA2 5  (UART RX) */
+#define IRQ_DMA2_6		BFIN_IRQ(29)	/* DMA2 6  (UART TX) */
+#define IRQ_UART_TX		IRQ_DMA2_6	/* DMA2 6  (UART TX) */
+#define IRQ_DMA2_7		BFIN_IRQ(30)	/* DMA2 7  Interrupt */
+#define IRQ_DMA2_8		BFIN_IRQ(31)	/* DMA2 8  Interrupt */
+#define IRQ_DMA2_9		BFIN_IRQ(32)	/* DMA2 9  Interrupt */
+#define IRQ_DMA2_10		BFIN_IRQ(33)	/* DMA2 10 Interrupt */
+#define IRQ_DMA2_11		BFIN_IRQ(34)	/* DMA2 11 Interrupt */
+#define IRQ_TIMER0		BFIN_IRQ(35)	/* TIMER 0  Interrupt */
+#define IRQ_TIMER1		BFIN_IRQ(36)	/* TIMER 1  Interrupt */
+#define IRQ_TIMER2		BFIN_IRQ(37)	/* TIMER 2  Interrupt */
+#define IRQ_TIMER3		BFIN_IRQ(38)	/* TIMER 3  Interrupt */
+#define IRQ_TIMER4		BFIN_IRQ(39)	/* TIMER 4  Interrupt */
+#define IRQ_TIMER5		BFIN_IRQ(40)	/* TIMER 5  Interrupt */
+#define IRQ_TIMER6		BFIN_IRQ(41)	/* TIMER 6  Interrupt */
+#define IRQ_TIMER7		BFIN_IRQ(42)	/* TIMER 7  Interrupt */
+#define IRQ_TIMER8		BFIN_IRQ(43)	/* TIMER 8  Interrupt */
+#define IRQ_TIMER9		BFIN_IRQ(44)	/* TIMER 9  Interrupt */
+#define IRQ_TIMER10		BFIN_IRQ(45)	/* TIMER 10 Interrupt */
+#define IRQ_TIMER11		BFIN_IRQ(46)	/* TIMER 11 Interrupt */
+#define IRQ_PROG0_INTA		BFIN_IRQ(47)	/* Programmable Flags0 A (8) */
+#define IRQ_PROG_INTA		IRQ_PROG0_INTA	/* Programmable Flags0 A (8) */
+#define IRQ_PROG0_INTB		BFIN_IRQ(48)	/* Programmable Flags0 B (8) */
+#define IRQ_PROG_INTB		IRQ_PROG0_INTB	/* Programmable Flags0 B (8) */
+#define IRQ_PROG1_INTA		BFIN_IRQ(49)	/* Programmable Flags1 A (8) */
+#define IRQ_PROG1_INTB		BFIN_IRQ(50)	/* Programmable Flags1 B (8) */
+#define IRQ_PROG2_INTA		BFIN_IRQ(51)	/* Programmable Flags2 A (8) */
+#define IRQ_PROG2_INTB		BFIN_IRQ(52)	/* Programmable Flags2 B (8) */
+#define IRQ_DMA1_WRRD0		BFIN_IRQ(53)	/* MDMA1 0 write/read INT */
+#define IRQ_DMA_WRRD0		IRQ_DMA1_WRRD0	/* MDMA1 0 write/read INT */
 #define IRQ_MEM_DMA0		IRQ_DMA1_WRRD0
-#define IRQ_DMA1_WRRD1		(IVG_BASE + 54)	/* MDMA1 1 write/read INT   */
-#define IRQ_DMA_WRRD1		IRQ_DMA1_WRRD1	/* MDMA1 1 write/read INT   */
+#define IRQ_DMA1_WRRD1		BFIN_IRQ(54)	/* MDMA1 1 write/read INT */
+#define IRQ_DMA_WRRD1		IRQ_DMA1_WRRD1	/* MDMA1 1 write/read INT */
 #define IRQ_MEM_DMA1		IRQ_DMA1_WRRD1
-/* IVG 9  */
-#define IRQ_DMA2_WRRD0		(IVG_BASE + 55)	/* MDMA2 0 write/read INT   */
+#define IRQ_DMA2_WRRD0		BFIN_IRQ(55)	/* MDMA2 0 write/read INT */
 #define IRQ_MEM_DMA2		IRQ_DMA2_WRRD0
-#define IRQ_DMA2_WRRD1		(IVG_BASE + 56)	/* MDMA2 1 write/read INT   */
+#define IRQ_DMA2_WRRD1		BFIN_IRQ(56)	/* MDMA2 1 write/read INT */
 #define IRQ_MEM_DMA3		IRQ_DMA2_WRRD1
-/* IVG 12 */
-#define IRQ_IMDMA_WRRD0		(IVG_BASE + 57)	/* IMDMA 0 write/read INT   */
+#define IRQ_IMDMA_WRRD0		BFIN_IRQ(57)	/* IMDMA 0 write/read INT */
 #define IRQ_IMEM_DMA0		IRQ_IMDMA_WRRD0
-#define IRQ_IMDMA_WRRD1		(IVG_BASE + 58)	/* IMDMA 1 write/read INT   */
+#define IRQ_IMDMA_WRRD1		BFIN_IRQ(58)	/* IMDMA 1 write/read INT */
 #define IRQ_IMEM_DMA1		IRQ_IMDMA_WRRD1
-/* IVG 13 */
-#define	IRQ_WATCH	   	(IVG_BASE + 59)	/* Watch Dog Timer          */
-/* IVG 7  */
-#define IRQ_RESERVED_1		(IVG_BASE + 60)	/* Reserved interrupt       */
-#define IRQ_RESERVED_2		(IVG_BASE + 61)	/* Reserved interrupt       */
-#define IRQ_SUPPLE_0		(IVG_BASE + 62)	/* Supplemental interrupt 0 */
-#define IRQ_SUPPLE_1		(IVG_BASE + 63)	/* supplemental interrupt 1 */
+#define IRQ_WATCH		BFIN_IRQ(59)	/* Watch Dog Timer */
+#define IRQ_RESERVED_1		BFIN_IRQ(60)	/* Reserved interrupt */
+#define IRQ_RESERVED_2		BFIN_IRQ(61)	/* Reserved interrupt */
+#define IRQ_SUPPLE_0		BFIN_IRQ(62)	/* Supplemental interrupt 0 */
+#define IRQ_SUPPLE_1		BFIN_IRQ(63)	/* supplemental interrupt 1 */
+
+#define SYS_IRQS		71
 
 #define IRQ_PF0			73
 #define IRQ_PF1			74
@@ -266,158 +152,85 @@
 #define GPIO_IRQ_BASE		IRQ_PF0
 
 #define NR_MACH_IRQS		(IRQ_PF47 + 1)
-#define NR_IRQS			(NR_MACH_IRQS + NR_SPARE_IRQS)
-
-#define IVG7			7
-#define IVG8			8
-#define IVG9			9
-#define IVG10			10
-#define IVG11			11
-#define IVG12			12
-#define IVG13			13
-#define IVG14			14
-#define IVG15			15
-
-/*
- * DEFAULT PRIORITIES:
- */
-
-#define	CONFIG_DEF_PLL_WAKEUP		7
-#define	CONFIG_DEF_DMA1_ERROR		7
-#define	CONFIG_DEF_DMA2_ERROR		7
-#define CONFIG_DEF_IMDMA_ERROR		7
-#define	CONFIG_DEF_PPI1_ERROR		7
-#define	CONFIG_DEF_PPI2_ERROR		7
-#define	CONFIG_DEF_SPORT0_ERROR		7
-#define	CONFIG_DEF_SPORT1_ERROR		7
-#define	CONFIG_DEF_SPI_ERROR		7
-#define	CONFIG_DEF_UART_ERROR		7
-#define CONFIG_DEF_RESERVED_ERROR	7
-#define	CONFIG_DEF_DMA1_0		8
-#define	CONFIG_DEF_DMA1_1		8
-#define	CONFIG_DEF_DMA1_2		8
-#define	CONFIG_DEF_DMA1_3		8
-#define	CONFIG_DEF_DMA1_4		8
-#define	CONFIG_DEF_DMA1_5		8
-#define	CONFIG_DEF_DMA1_6		8
-#define	CONFIG_DEF_DMA1_7		8
-#define	CONFIG_DEF_DMA1_8		8
-#define	CONFIG_DEF_DMA1_9		8
-#define	CONFIG_DEF_DMA1_10		8
-#define	CONFIG_DEF_DMA1_11		8
-#define	CONFIG_DEF_DMA2_0		9
-#define	CONFIG_DEF_DMA2_1		9
-#define	CONFIG_DEF_DMA2_2		9
-#define	CONFIG_DEF_DMA2_3		9
-#define	CONFIG_DEF_DMA2_4		9
-#define	CONFIG_DEF_DMA2_5		9
-#define	CONFIG_DEF_DMA2_6		9
-#define	CONFIG_DEF_DMA2_7		9
-#define	CONFIG_DEF_DMA2_8		9
-#define	CONFIG_DEF_DMA2_9		9
-#define	CONFIG_DEF_DMA2_10		9
-#define	CONFIG_DEF_DMA2_11		9
-#define CONFIG_DEF_TIMER0		10
-#define CONFIG_DEF_TIMER1		10
-#define CONFIG_DEF_TIMER2		10
-#define CONFIG_DEF_TIMER3		10
-#define CONFIG_DEF_TIMER4		10
-#define CONFIG_DEF_TIMER5		10
-#define CONFIG_DEF_TIMER6		10
-#define CONFIG_DEF_TIMER7		10
-#define CONFIG_DEF_TIMER8		10
-#define CONFIG_DEF_TIMER9		10
-#define CONFIG_DEF_TIMER10		10
-#define CONFIG_DEF_TIMER11		10
-#define	CONFIG_DEF_PROG0_INTA		11
-#define	CONFIG_DEF_PROG0_INTB		11
-#define	CONFIG_DEF_PROG1_INTA		11
-#define	CONFIG_DEF_PROG1_INTB		11
-#define	CONFIG_DEF_PROG2_INTA		11
-#define	CONFIG_DEF_PROG2_INTB		11
-#define CONFIG_DEF_DMA1_WRRD0		8
-#define CONFIG_DEF_DMA1_WRRD1		8
-#define CONFIG_DEF_DMA2_WRRD0		9
-#define CONFIG_DEF_DMA2_WRRD1		9
-#define CONFIG_DEF_IMDMA_WRRD0		12
-#define CONFIG_DEF_IMDMA_WRRD1		12
-#define	CONFIG_DEF_WATCH	   	13
-#define CONFIG_DEF_RESERVED_1		7
-#define CONFIG_DEF_RESERVED_2		7
-#define CONFIG_DEF_SUPPLE_0		7
-#define CONFIG_DEF_SUPPLE_1		7
 
 /* IAR0 BIT FIELDS */
-#define	IRQ_PLL_WAKEUP_POS			0
-#define	IRQ_DMA1_ERROR_POS			4
-#define	IRQ_DMA2_ERROR_POS			8
-#define IRQ_IMDMA_ERROR_POS			12
-#define	IRQ_PPI0_ERROR_POS			16
-#define	IRQ_PPI1_ERROR_POS			20
-#define	IRQ_SPORT0_ERROR_POS		24
-#define	IRQ_SPORT1_ERROR_POS		28
+#define IRQ_PLL_WAKEUP_POS	0
+#define IRQ_DMA1_ERROR_POS	4
+#define IRQ_DMA2_ERROR_POS	8
+#define IRQ_IMDMA_ERROR_POS	12
+#define IRQ_PPI0_ERROR_POS	16
+#define IRQ_PPI1_ERROR_POS	20
+#define IRQ_SPORT0_ERROR_POS	24
+#define IRQ_SPORT1_ERROR_POS	28
+
 /* IAR1 BIT FIELDS */
-#define	IRQ_SPI_ERROR_POS			0
-#define	IRQ_UART_ERROR_POS			4
-#define IRQ_RESERVED_ERROR_POS		8
-#define	IRQ_DMA1_0_POS			12
-#define	IRQ_DMA1_1_POS			16
-#define IRQ_DMA1_2_POS			20
-#define IRQ_DMA1_3_POS			24
-#define IRQ_DMA1_4_POS			28
+#define IRQ_SPI_ERROR_POS	0
+#define IRQ_UART_ERROR_POS	4
+#define IRQ_RESERVED_ERROR_POS	8
+#define IRQ_DMA1_0_POS		12
+#define IRQ_DMA1_1_POS		16
+#define IRQ_DMA1_2_POS		20
+#define IRQ_DMA1_3_POS		24
+#define IRQ_DMA1_4_POS		28
+
 /* IAR2 BIT FIELDS */
-#define IRQ_DMA1_5_POS			0
-#define IRQ_DMA1_6_POS			4
-#define IRQ_DMA1_7_POS			8
-#define IRQ_DMA1_8_POS			12
-#define IRQ_DMA1_9_POS			16
-#define IRQ_DMA1_10_POS			20
-#define IRQ_DMA1_11_POS			24
-#define IRQ_DMA2_0_POS			28
+#define IRQ_DMA1_5_POS		0
+#define IRQ_DMA1_6_POS		4
+#define IRQ_DMA1_7_POS		8
+#define IRQ_DMA1_8_POS		12
+#define IRQ_DMA1_9_POS		16
+#define IRQ_DMA1_10_POS		20
+#define IRQ_DMA1_11_POS		24
+#define IRQ_DMA2_0_POS		28
+
 /* IAR3 BIT FIELDS */
-#define IRQ_DMA2_1_POS			0
-#define IRQ_DMA2_2_POS			4
-#define IRQ_DMA2_3_POS			8
-#define IRQ_DMA2_4_POS			12
-#define IRQ_DMA2_5_POS			16
-#define IRQ_DMA2_6_POS			20
-#define IRQ_DMA2_7_POS			24
-#define IRQ_DMA2_8_POS			28
+#define IRQ_DMA2_1_POS		0
+#define IRQ_DMA2_2_POS		4
+#define IRQ_DMA2_3_POS		8
+#define IRQ_DMA2_4_POS		12
+#define IRQ_DMA2_5_POS		16
+#define IRQ_DMA2_6_POS		20
+#define IRQ_DMA2_7_POS		24
+#define IRQ_DMA2_8_POS		28
+
 /* IAR4 BIT FIELDS */
-#define IRQ_DMA2_9_POS			0
-#define IRQ_DMA2_10_POS			4
-#define IRQ_DMA2_11_POS			8
-#define IRQ_TIMER0_POS			12
-#define IRQ_TIMER1_POS			16
-#define IRQ_TIMER2_POS			20
-#define IRQ_TIMER3_POS			24
-#define IRQ_TIMER4_POS			28
+#define IRQ_DMA2_9_POS		0
+#define IRQ_DMA2_10_POS		4
+#define IRQ_DMA2_11_POS		8
+#define IRQ_TIMER0_POS		12
+#define IRQ_TIMER1_POS		16
+#define IRQ_TIMER2_POS		20
+#define IRQ_TIMER3_POS		24
+#define IRQ_TIMER4_POS		28
+
 /* IAR5 BIT FIELDS */
-#define IRQ_TIMER5_POS			0
-#define IRQ_TIMER6_POS			4
-#define IRQ_TIMER7_POS			8
-#define IRQ_TIMER8_POS			12
-#define IRQ_TIMER9_POS			16
-#define IRQ_TIMER10_POS			20
-#define IRQ_TIMER11_POS			24
-#define IRQ_PROG0_INTA_POS			28
+#define IRQ_TIMER5_POS		0
+#define IRQ_TIMER6_POS		4
+#define IRQ_TIMER7_POS		8
+#define IRQ_TIMER8_POS		12
+#define IRQ_TIMER9_POS		16
+#define IRQ_TIMER10_POS		20
+#define IRQ_TIMER11_POS		24
+#define IRQ_PROG0_INTA_POS	28
+
 /* IAR6 BIT FIELDS */
-#define IRQ_PROG0_INTB_POS			0
-#define IRQ_PROG1_INTA_POS			4
-#define IRQ_PROG1_INTB_POS			8
-#define IRQ_PROG2_INTA_POS			12
-#define IRQ_PROG2_INTB_POS			16
-#define IRQ_DMA1_WRRD0_POS			20
-#define IRQ_DMA1_WRRD1_POS			24
-#define IRQ_DMA2_WRRD0_POS			28
+#define IRQ_PROG0_INTB_POS	0
+#define IRQ_PROG1_INTA_POS	4
+#define IRQ_PROG1_INTB_POS	8
+#define IRQ_PROG2_INTA_POS	12
+#define IRQ_PROG2_INTB_POS	16
+#define IRQ_DMA1_WRRD0_POS	20
+#define IRQ_DMA1_WRRD1_POS	24
+#define IRQ_DMA2_WRRD0_POS	28
+
 /* IAR7 BIT FIELDS */
-#define IRQ_DMA2_WRRD1_POS			0
-#define IRQ_IMDMA_WRRD0_POS			4
-#define IRQ_IMDMA_WRRD1_POS			8
-#define	IRQ_WDTIMER_POS			12
-#define IRQ_RESERVED_1_POS			16
-#define IRQ_RESERVED_2_POS			20
-#define IRQ_SUPPLE_0_POS			24
-#define IRQ_SUPPLE_1_POS			28
+#define IRQ_DMA2_WRRD1_POS	0
+#define IRQ_IMDMA_WRRD0_POS	4
+#define IRQ_IMDMA_WRRD1_POS	8
+#define IRQ_WDTIMER_POS		12
+#define IRQ_RESERVED_1_POS	16
+#define IRQ_RESERVED_2_POS	20
+#define IRQ_SUPPLE_0_POS	24
+#define IRQ_SUPPLE_1_POS	28
 
-#endif				/* _BF561_IRQ_H_ */
+#endif
diff -druN linux-2.6.39-libre/arch/blackfin/mach-bf561/smp.c linux-3.0-rc7-libre/arch/blackfin/mach-bf561/smp.c
--- linux-2.6.39-libre/arch/blackfin/mach-bf561/smp.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/blackfin/mach-bf561/smp.c	2011-07-11 19:51:52.000000000 -0400
@@ -24,17 +24,23 @@
 
 void __init platform_init_cpus(void)
 {
-	cpu_set(0, cpu_possible_map); /* CoreA */
-	cpu_set(1, cpu_possible_map); /* CoreB */
+	struct cpumask mask;
+
+	cpumask_set_cpu(0, &mask); /* CoreA */
+	cpumask_set_cpu(1, &mask); /* CoreB */
+	init_cpu_possible(&mask);
 }
 
 void __init platform_prepare_cpus(unsigned int max_cpus)
 {
+	struct cpumask mask;
+
 	bfin_relocate_coreb_l1_mem();
 
 	/* Both cores ought to be present on a bf561! */
-	cpu_set(0, cpu_present_map); /* CoreA */
-	cpu_set(1, cpu_present_map); /* CoreB */
+	cpumask_set_cpu(0, &mask); /* CoreA */
+	cpumask_set_cpu(1, &mask); /* CoreB */
+	init_cpu_present(&mask);
 }
 
 int __init setup_profiling_timer(unsigned int multiplier) /* not supported */
@@ -62,9 +68,6 @@
 	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. */
 	set_cpu_online(cpu, true);
 	spin_lock(&boot_lock);
diff -druN linux-2.6.39-libre/arch/blackfin/mach-common/dpmc.c linux-3.0-rc7-libre/arch/blackfin/mach-common/dpmc.c
--- linux-2.6.39-libre/arch/blackfin/mach-common/dpmc.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/blackfin/mach-common/dpmc.c	2011-07-11 19:51:52.000000000 -0400
@@ -19,9 +19,6 @@
 
 #define DRIVER_NAME "bfin dpmc"
 
-#define dprintk(msg...) \
-	cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, DRIVER_NAME, msg)
-
 struct bfin_dpmc_platform_data *pdata;
 
 /**
@@ -88,10 +85,11 @@
 {
 	unsigned int cpu;
 	unsigned int this_cpu = smp_processor_id();
-	cpumask_t mask = cpu_online_map;
+	cpumask_t mask;
 
-	cpu_clear(this_cpu, mask);
-	for_each_cpu_mask(cpu, mask)
+	cpumask_copy(&mask, cpu_online_mask);
+	cpumask_clear_cpu(this_cpu, &mask);
+	for_each_cpu(cpu, &mask)
 		platform_send_ipi_cpu(cpu, IRQ_SUPPLE_0);
 }
 
diff -druN linux-2.6.39-libre/arch/blackfin/mach-common/entry.S linux-3.0-rc7-libre/arch/blackfin/mach-common/entry.S
--- linux-2.6.39-libre/arch/blackfin/mach-common/entry.S	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/blackfin/mach-common/entry.S	2011-07-11 19:51:52.000000000 -0400
@@ -1753,6 +1753,8 @@
 	.long _sys_open_by_handle_at
 	.long _sys_clock_adjtime
 	.long _sys_syncfs
+	.long _sys_setns
+	.long _sys_sendmmsg		/* 380 */
 
 	.rept NR_syscalls-(.-_sys_call_table)/4
 	.long _sys_ni_syscall
diff -druN linux-2.6.39-libre/arch/blackfin/mach-common/ints-priority.c linux-3.0-rc7-libre/arch/blackfin/mach-common/ints-priority.c
--- linux-2.6.39-libre/arch/blackfin/mach-common/ints-priority.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/blackfin/mach-common/ints-priority.c	2011-07-11 19:51:52.000000000 -0400
@@ -19,32 +19,14 @@
 #ifdef CONFIG_IPIPE
 #include <linux/ipipe.h>
 #endif
-#ifdef CONFIG_KGDB
-#include <linux/kgdb.h>
-#endif
 #include <asm/traps.h>
 #include <asm/blackfin.h>
 #include <asm/gpio.h>
 #include <asm/irq_handler.h>
 #include <asm/dpmc.h>
-#include <asm/bfin5xx_spi.h>
-#include <asm/bfin_sport.h>
-#include <asm/bfin_can.h>
 
 #define SIC_SYSIRQ(irq)	(irq - (IRQ_CORETMR + 1))
 
-#ifdef BF537_FAMILY
-# define BF537_GENERIC_ERROR_INT_DEMUX
-# define SPI_ERR_MASK   (BIT_STAT_TXCOL | BIT_STAT_RBSY | BIT_STAT_MODF | BIT_STAT_TXE)	/* SPI_STAT */
-# define SPORT_ERR_MASK (ROVF | RUVF | TOVF | TUVF)	/* SPORT_STAT */
-# define PPI_ERR_MASK   (0xFFFF & ~FLD)	/* PPI_STATUS */
-# define EMAC_ERR_MASK  (PHYINT | MMCINT | RXFSINT | TXFSINT | WAKEDET | RXDMAERR | TXDMAERR | STMDONE)	/* EMAC_SYSTAT */
-# define UART_ERR_MASK  (0x6)	/* UART_IIR */
-# define CAN_ERR_MASK   (EWTIF | EWRIF | EPIF | BOIF | WUIF | UIAIF | AAIF | RMLIF | UCEIF | EXTIF | ADIF)	/* CAN_GIF */
-#else
-# undef BF537_GENERIC_ERROR_INT_DEMUX
-#endif
-
 /*
  * NOTES:
  * - we have separated the physical Hardware interrupt from the
@@ -63,22 +45,19 @@
 EXPORT_SYMBOL(bfin_irq_flags);
 #endif
 
-/* The number of spurious interrupts */
-atomic_t num_spurious;
-
 #ifdef CONFIG_PM
 unsigned long bfin_sic_iwr[3];	/* Up to 3 SIC_IWRx registers */
 unsigned vr_wakeup;
 #endif
 
-struct ivgx {
+static struct ivgx {
 	/* irq number for request_irq, available in mach-bf5xx/irq.h */
 	unsigned int irqno;
 	/* corresponding bit in the SIC_ISR register */
 	unsigned int isrflag;
 } ivg_table[NR_PERI_INTS];
 
-struct ivg_slice {
+static struct ivg_slice {
 	/* position of first irq in ivg_table for given ivg */
 	struct ivgx *ifirst;
 	struct ivgx *istop;
@@ -125,7 +104,7 @@
  * This is for core internal IRQs
  */
 
-static void bfin_ack_noop(struct irq_data *d)
+void bfin_ack_noop(struct irq_data *d)
 {
 	/* Dummy function.  */
 }
@@ -154,26 +133,24 @@
 	return;
 }
 
-static void bfin_internal_mask_irq(unsigned int irq)
+void bfin_internal_mask_irq(unsigned int irq)
 {
-	unsigned long flags;
+	unsigned long flags = hard_local_irq_save();
 
-#ifdef CONFIG_BF53x
-	flags = hard_local_irq_save();
-	bfin_write_SIC_IMASK(bfin_read_SIC_IMASK() &
-			     ~(1 << SIC_SYSIRQ(irq)));
-#else
-	unsigned mask_bank, mask_bit;
-	flags = hard_local_irq_save();
-	mask_bank = SIC_SYSIRQ(irq) / 32;
-	mask_bit = SIC_SYSIRQ(irq) % 32;
+#ifdef SIC_IMASK0
+	unsigned mask_bank = SIC_SYSIRQ(irq) / 32;
+	unsigned mask_bit = SIC_SYSIRQ(irq) % 32;
 	bfin_write_SIC_IMASK(mask_bank, bfin_read_SIC_IMASK(mask_bank) &
 			     ~(1 << mask_bit));
-#ifdef CONFIG_SMP
+# ifdef CONFIG_SMP
 	bfin_write_SICB_IMASK(mask_bank, bfin_read_SICB_IMASK(mask_bank) &
 			     ~(1 << mask_bit));
+# endif
+#else
+	bfin_write_SIC_IMASK(bfin_read_SIC_IMASK() &
+			     ~(1 << SIC_SYSIRQ(irq)));
 #endif
-#endif
+
 	hard_local_irq_restore(flags);
 }
 
@@ -186,33 +163,31 @@
 static void bfin_internal_unmask_irq_affinity(unsigned int irq,
 		const struct cpumask *affinity)
 #else
-static void bfin_internal_unmask_irq(unsigned int irq)
+void bfin_internal_unmask_irq(unsigned int irq)
 #endif
 {
-	unsigned long flags;
+	unsigned long flags = hard_local_irq_save();
 
-#ifdef CONFIG_BF53x
-	flags = hard_local_irq_save();
-	bfin_write_SIC_IMASK(bfin_read_SIC_IMASK() |
-			     (1 << SIC_SYSIRQ(irq)));
-#else
-	unsigned mask_bank, mask_bit;
-	flags = hard_local_irq_save();
-	mask_bank = SIC_SYSIRQ(irq) / 32;
-	mask_bit = SIC_SYSIRQ(irq) % 32;
-#ifdef CONFIG_SMP
+#ifdef SIC_IMASK0
+	unsigned mask_bank = SIC_SYSIRQ(irq) / 32;
+	unsigned mask_bit = SIC_SYSIRQ(irq) % 32;
+# ifdef CONFIG_SMP
 	if (cpumask_test_cpu(0, affinity))
-#endif
+# endif
 		bfin_write_SIC_IMASK(mask_bank,
 			bfin_read_SIC_IMASK(mask_bank) |
 			(1 << mask_bit));
-#ifdef CONFIG_SMP
+# 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
+#else
+	bfin_write_SIC_IMASK(bfin_read_SIC_IMASK() |
+			     (1 << SIC_SYSIRQ(irq)));
 #endif
-#endif
+
 	hard_local_irq_restore(flags);
 }
 
@@ -295,6 +270,8 @@
 {
 	return bfin_internal_set_wake(d->irq, state);
 }
+#else
+# define bfin_internal_set_wake_chip NULL
 #endif
 
 static struct irq_chip bfin_core_irqchip = {
@@ -315,12 +292,10 @@
 #ifdef CONFIG_SMP
 	.irq_set_affinity = bfin_internal_set_affinity,
 #endif
-#ifdef CONFIG_PM
 	.irq_set_wake = bfin_internal_set_wake_chip,
-#endif
 };
 
-static void bfin_handle_irq(unsigned irq)
+void bfin_handle_irq(unsigned irq)
 {
 #ifdef CONFIG_IPIPE
 	struct pt_regs regs;    /* Contents not used. */
@@ -332,102 +307,6 @@
 #endif  /* !CONFIG_IPIPE */
 }
 
-#ifdef BF537_GENERIC_ERROR_INT_DEMUX
-static int error_int_mask;
-
-static void bfin_generic_error_mask_irq(struct irq_data *d)
-{
-	error_int_mask &= ~(1L << (d->irq - IRQ_PPI_ERROR));
-	if (!error_int_mask)
-		bfin_internal_mask_irq(IRQ_GENERIC_ERROR);
-}
-
-static void bfin_generic_error_unmask_irq(struct irq_data *d)
-{
-	bfin_internal_unmask_irq(IRQ_GENERIC_ERROR);
-	error_int_mask |= 1L << (d->irq - IRQ_PPI_ERROR);
-}
-
-static struct irq_chip bfin_generic_error_irqchip = {
-	.name = "ERROR",
-	.irq_ack = bfin_ack_noop,
-	.irq_mask_ack = bfin_generic_error_mask_irq,
-	.irq_mask = bfin_generic_error_mask_irq,
-	.irq_unmask = bfin_generic_error_unmask_irq,
-};
-
-static void bfin_demux_error_irq(unsigned int int_err_irq,
-				 struct irq_desc *inta_desc)
-{
-	int irq = 0;
-
-#if (defined(CONFIG_BF537) || defined(CONFIG_BF536))
-	if (bfin_read_EMAC_SYSTAT() & EMAC_ERR_MASK)
-		irq = IRQ_MAC_ERROR;
-	else
-#endif
-	if (bfin_read_SPORT0_STAT() & SPORT_ERR_MASK)
-		irq = IRQ_SPORT0_ERROR;
-	else if (bfin_read_SPORT1_STAT() & SPORT_ERR_MASK)
-		irq = IRQ_SPORT1_ERROR;
-	else if (bfin_read_PPI_STATUS() & PPI_ERR_MASK)
-		irq = IRQ_PPI_ERROR;
-	else if (bfin_read_CAN_GIF() & CAN_ERR_MASK)
-		irq = IRQ_CAN_ERROR;
-	else if (bfin_read_SPI_STAT() & SPI_ERR_MASK)
-		irq = IRQ_SPI_ERROR;
-	else if ((bfin_read_UART0_IIR() & UART_ERR_MASK) == UART_ERR_MASK)
-		irq = IRQ_UART0_ERROR;
-	else if ((bfin_read_UART1_IIR() & UART_ERR_MASK) == UART_ERR_MASK)
-		irq = IRQ_UART1_ERROR;
-
-	if (irq) {
-		if (error_int_mask & (1L << (irq - IRQ_PPI_ERROR)))
-			bfin_handle_irq(irq);
-		else {
-
-			switch (irq) {
-			case IRQ_PPI_ERROR:
-				bfin_write_PPI_STATUS(PPI_ERR_MASK);
-				break;
-#if (defined(CONFIG_BF537) || defined(CONFIG_BF536))
-			case IRQ_MAC_ERROR:
-				bfin_write_EMAC_SYSTAT(EMAC_ERR_MASK);
-				break;
-#endif
-			case IRQ_SPORT0_ERROR:
-				bfin_write_SPORT0_STAT(SPORT_ERR_MASK);
-				break;
-
-			case IRQ_SPORT1_ERROR:
-				bfin_write_SPORT1_STAT(SPORT_ERR_MASK);
-				break;
-
-			case IRQ_CAN_ERROR:
-				bfin_write_CAN_GIS(CAN_ERR_MASK);
-				break;
-
-			case IRQ_SPI_ERROR:
-				bfin_write_SPI_STAT(SPI_ERR_MASK);
-				break;
-
-			default:
-				break;
-			}
-
-			pr_debug("IRQ %d:"
-				 " MASKED PERIPHERAL ERROR INTERRUPT ASSERTED\n",
-				 irq);
-		}
-	} else
-		printk(KERN_ERR
-		       "%s : %s : LINE %d :\nIRQ ?: PERIPHERAL ERROR"
-		       " INTERRUPT ASSERTED BUT NO SOURCE FOUND\n",
-		       __func__, __FILE__, __LINE__);
-
-}
-#endif				/* BF537_GENERIC_ERROR_INT_DEMUX */
-
 #if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE)
 static int mac_stat_int_mask;
 
@@ -468,7 +347,7 @@
 	unsigned int irq = d->irq;
 
 	mac_stat_int_mask &= ~(1L << (irq - IRQ_MAC_PHYINT));
-#ifdef BF537_GENERIC_ERROR_INT_DEMUX
+#ifdef BF537_FAMILY
 	switch (irq) {
 	case IRQ_MAC_PHYINT:
 		bfin_write_EMAC_SYSCTL(bfin_read_EMAC_SYSCTL() & ~PHYIE);
@@ -487,7 +366,7 @@
 {
 	unsigned int irq = d->irq;
 
-#ifdef BF537_GENERIC_ERROR_INT_DEMUX
+#ifdef BF537_FAMILY
 	switch (irq) {
 	case IRQ_MAC_PHYINT:
 		bfin_write_EMAC_SYSCTL(bfin_read_EMAC_SYSCTL() | PHYIE);
@@ -505,12 +384,14 @@
 #ifdef CONFIG_PM
 int bfin_mac_status_set_wake(struct irq_data *d, unsigned int state)
 {
-#ifdef BF537_GENERIC_ERROR_INT_DEMUX
+#ifdef BF537_FAMILY
 	return bfin_internal_set_wake(IRQ_GENERIC_ERROR, state);
 #else
 	return bfin_internal_set_wake(IRQ_MAC_ERROR, state);
 #endif
 }
+#else
+# define bfin_mac_status_set_wake NULL
 #endif
 
 static struct irq_chip bfin_mac_status_irqchip = {
@@ -519,13 +400,11 @@
 	.irq_mask_ack = bfin_mac_status_mask_irq,
 	.irq_mask = bfin_mac_status_mask_irq,
 	.irq_unmask = bfin_mac_status_unmask_irq,
-#ifdef CONFIG_PM
 	.irq_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)
+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();
@@ -680,29 +559,48 @@
 }
 
 #ifdef CONFIG_PM
-int bfin_gpio_set_wake(struct irq_data *d, unsigned int state)
+static int bfin_gpio_set_wake(struct irq_data *d, unsigned int state)
 {
 	return gpio_pm_wakeup_ctrl(irq_to_gpio(d->irq), state);
 }
+#else
+# define bfin_gpio_set_wake NULL
 #endif
 
-static void bfin_demux_gpio_irq(unsigned int inta_irq,
-				struct irq_desc *desc)
+static void bfin_demux_gpio_block(unsigned int irq)
 {
-	unsigned int i, gpio, mask, irq, search = 0;
+	unsigned int gpio, mask;
+
+	gpio = irq_to_gpio(irq);
+	mask = get_gpiop_data(gpio) & get_gpiop_maska(gpio);
+
+	while (mask) {
+		if (mask & 1)
+			bfin_handle_irq(irq);
+		irq++;
+		mask >>= 1;
+	}
+}
+
+void bfin_demux_gpio_irq(unsigned int inta_irq,
+			 struct irq_desc *desc)
+{
+	unsigned int irq;
 
 	switch (inta_irq) {
-#if defined(CONFIG_BF53x)
-	case IRQ_PROG_INTA:
-		irq = IRQ_PF0;
-		search = 1;
+#if defined(BF537_FAMILY)
+	case IRQ_PF_INTA_PG_INTA:
+		bfin_demux_gpio_block(IRQ_PF0);
+		irq = IRQ_PG0;
 		break;
-# if defined(BF537_FAMILY) && !(defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE))
-	case IRQ_MAC_RX:
+	case IRQ_PH_INTA_MAC_RX:
 		irq = IRQ_PH0;
 		break;
-# endif
-#elif defined(CONFIG_BF538) || defined(CONFIG_BF539)
+#elif defined(BF533_FAMILY)
+	case IRQ_PROG_INTA:
+		irq = IRQ_PF0;
+		break;
+#elif defined(BF538_FAMILY)
 	case IRQ_PORTF_INTA:
 		irq = IRQ_PF0;
 		break;
@@ -732,31 +630,7 @@
 		return;
 	}
 
-	if (search) {
-		for (i = 0; i < MAX_BLACKFIN_GPIOS; i += GPIO_BANKSIZE) {
-			irq += i;
-
-			mask = get_gpiop_data(i) & get_gpiop_maska(i);
-
-			while (mask) {
-				if (mask & 1)
-					bfin_handle_irq(irq);
-				irq++;
-				mask >>= 1;
-			}
-		}
-	} else {
-			gpio = irq_to_gpio(irq);
-			mask = get_gpiop_data(gpio) & get_gpiop_maska(gpio);
-
-			do {
-				if (mask & 1)
-					bfin_handle_irq(irq);
-				irq++;
-				mask >>= 1;
-			} while (mask);
-	}
-
+	bfin_demux_gpio_block(irq);
 }
 
 #else				/* CONFIG_BF54x */
@@ -974,15 +848,11 @@
 }
 
 #ifdef CONFIG_PM
-u32 pint_saved_masks[NR_PINT_SYS_IRQS];
-u32 pint_wakeup_masks[NR_PINT_SYS_IRQS];
-
-int bfin_gpio_set_wake(struct irq_data *d, unsigned int state)
+static int bfin_gpio_set_wake(struct irq_data *d, unsigned int state)
 {
 	u32 pint_irq;
 	u32 pint_val = irq2pint_lut[d->irq - SYS_IRQS];
 	u32 bank = PINT_2_BANK(pint_val);
-	u32 pintbit = PINT_BIT(pint_val);
 
 	switch (bank) {
 	case 0:
@@ -1003,46 +873,14 @@
 
 	bfin_internal_set_wake(pint_irq, state);
 
-	if (state)
-		pint_wakeup_masks[bank] |= pintbit;
-	else
-		pint_wakeup_masks[bank] &= ~pintbit;
-
-	return 0;
-}
-
-u32 bfin_pm_setup(void)
-{
-	u32 val, i;
-
-	for (i = 0; i < NR_PINT_SYS_IRQS; i++) {
-		val = pint[i]->mask_clear;
-		pint_saved_masks[i] = val;
-		if (val ^ pint_wakeup_masks[i]) {
-			pint[i]->mask_clear = val;
-			pint[i]->mask_set = pint_wakeup_masks[i];
-		}
-	}
-
 	return 0;
 }
-
-void bfin_pm_restore(void)
-{
-	u32 i, val;
-
-	for (i = 0; i < NR_PINT_SYS_IRQS; i++) {
-		val = pint_saved_masks[i];
-		if (val ^ pint_wakeup_masks[i]) {
-			pint[i]->mask_clear = pint[i]->mask_clear;
-			pint[i]->mask_set = val;
-		}
-	}
-}
+#else
+# define bfin_gpio_set_wake NULL
 #endif
 
-static void bfin_demux_gpio_irq(unsigned int inta_irq,
-				struct irq_desc *desc)
+void bfin_demux_gpio_irq(unsigned int inta_irq,
+			 struct irq_desc *desc)
 {
 	u32 bank, pint_val;
 	u32 request, irq;
@@ -1091,9 +929,7 @@
 	.irq_set_type = bfin_gpio_irq_type,
 	.irq_startup = bfin_gpio_irq_startup,
 	.irq_shutdown = bfin_gpio_irq_shutdown,
-#ifdef CONFIG_PM
 	.irq_set_wake = bfin_gpio_set_wake,
-#endif
 };
 
 void __cpuinit init_exception_vectors(void)
@@ -1127,12 +963,12 @@
 {
 	int irq;
 	unsigned long ilat = 0;
+
 	/*  Disable all the peripheral intrs  - page 4-29 HW Ref manual */
-#if defined(CONFIG_BF54x) || defined(CONFIG_BF52x) || defined(CONFIG_BF561) \
-	|| defined(BF538_FAMILY) || defined(CONFIG_BF51x)
+#ifdef SIC_IMASK0
 	bfin_write_SIC_IMASK0(SIC_UNMASK_ALL);
 	bfin_write_SIC_IMASK1(SIC_UNMASK_ALL);
-# ifdef CONFIG_BF54x
+# ifdef SIC_IMASK2
 	bfin_write_SIC_IMASK2(SIC_UNMASK_ALL);
 # endif
 # ifdef CONFIG_SMP
@@ -1145,11 +981,6 @@
 
 	local_irq_disable();
 
-#if (defined(CONFIG_BF537) || defined(CONFIG_BF536))
-	/* Clear EMAC Interrupt Status bits so we can demux it later */
-	bfin_write_EMAC_SYSTAT(-1);
-#endif
-
 #ifdef CONFIG_BF54x
 # ifdef CONFIG_PINTx_REASSIGN
 	pint[0]->assign = CONFIG_PINT0_ASSIGN;
@@ -1168,11 +999,11 @@
 			irq_set_chip(irq, &bfin_internal_irqchip);
 
 		switch (irq) {
-#if defined(CONFIG_BF53x)
+#if defined(BF537_FAMILY)
+		case IRQ_PH_INTA_MAC_RX:
+		case IRQ_PF_INTA_PG_INTA:
+#elif defined(BF533_FAMILY)
 		case IRQ_PROG_INTA:
-# if defined(BF537_FAMILY) && !(defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE))
-		case IRQ_MAC_RX:
-# endif
 #elif defined(CONFIG_BF54x)
 		case IRQ_PINT0:
 		case IRQ_PINT1:
@@ -1186,16 +1017,11 @@
 		case IRQ_PROG0_INTA:
 		case IRQ_PROG1_INTA:
 		case IRQ_PROG2_INTA:
-#elif defined(CONFIG_BF538) || defined(CONFIG_BF539)
+#elif defined(BF538_FAMILY)
 		case IRQ_PORTF_INTA:
 #endif
 			irq_set_chained_handler(irq, bfin_demux_gpio_irq);
 			break;
-#ifdef BF537_GENERIC_ERROR_INT_DEMUX
-		case IRQ_GENERIC_ERROR:
-			irq_set_chained_handler(irq, bfin_demux_error_irq);
-			break;
-#endif
 #if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE)
 		case IRQ_MAC_ERROR:
 			irq_set_chained_handler(irq,
@@ -1213,11 +1039,10 @@
 		case IRQ_CORETMR:
 # ifdef CONFIG_SMP
 			irq_set_handler(irq, handle_percpu_irq);
-			break;
 # else
 			irq_set_handler(irq, handle_simple_irq);
-			break;
 # endif
+			break;
 #endif
 
 #ifdef CONFIG_TICKSOURCE_GPTMR0
@@ -1226,26 +1051,17 @@
 			break;
 #endif
 
-#ifdef CONFIG_IPIPE
 		default:
+#ifdef CONFIG_IPIPE
 			irq_set_handler(irq, handle_level_irq);
-			break;
-#else /* !CONFIG_IPIPE */
-		default:
+#else
 			irq_set_handler(irq, handle_simple_irq);
+#endif
 			break;
-#endif /* !CONFIG_IPIPE */
 		}
 	}
 
-#ifdef BF537_GENERIC_ERROR_INT_DEMUX
-	for (irq = IRQ_PPI_ERROR; irq <= IRQ_UART1_ERROR; irq++)
-		irq_set_chip_and_handler(irq, &bfin_generic_error_irqchip,
-					 handle_level_irq);
-#if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE)
-	irq_set_chained_handler(IRQ_MAC_ERROR, bfin_demux_mac_status_irq);
-#endif
-#endif
+	init_mach_irq();
 
 #if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE)
 	for (irq = IRQ_MAC_PHYINT; irq <= IRQ_MAC_STMDONE; irq++)
@@ -1307,53 +1123,54 @@
 #ifdef CONFIG_DO_IRQ_L1
 __attribute__((l1_text))
 #endif
-void do_irq(int vec, struct pt_regs *fp)
+static int vec_to_irq(int vec)
 {
-	if (vec == EVT_IVTMR_P) {
-		vec = IRQ_CORETMR;
-	} else {
-		struct ivgx *ivg = ivg7_13[vec - IVG7].ifirst;
-		struct ivgx *ivg_stop = ivg7_13[vec - IVG7].istop;
-#if defined(SIC_ISR0)
-		unsigned long sic_status[3];
+	struct ivgx *ivg = ivg7_13[vec - IVG7].ifirst;
+	struct ivgx *ivg_stop = ivg7_13[vec - IVG7].istop;
+	unsigned long sic_status[3];
 
-		if (smp_processor_id()) {
+	if (likely(vec == EVT_IVTMR_P))
+		return IRQ_CORETMR;
+
+#ifdef SIC_ISR
+	sic_status[0] = bfin_read_SIC_IMASK() & bfin_read_SIC_ISR();
+#else
+	if (smp_processor_id()) {
 # ifdef SICB_ISR0
-			/* This will be optimized out in UP mode. */
-			sic_status[0] = bfin_read_SICB_ISR0() & bfin_read_SICB_IMASK0();
-			sic_status[1] = bfin_read_SICB_ISR1() & bfin_read_SICB_IMASK1();
-# endif
-		} else {
-			sic_status[0] = bfin_read_SIC_ISR0() & bfin_read_SIC_IMASK0();
-			sic_status[1] = bfin_read_SIC_ISR1() & bfin_read_SIC_IMASK1();
-		}
-# ifdef SIC_ISR2
-		sic_status[2] = bfin_read_SIC_ISR2() & bfin_read_SIC_IMASK2();
+		/* This will be optimized out in UP mode. */
+		sic_status[0] = bfin_read_SICB_ISR0() & bfin_read_SICB_IMASK0();
+		sic_status[1] = bfin_read_SICB_ISR1() & bfin_read_SICB_IMASK1();
 # endif
-		for (;; ivg++) {
-			if (ivg >= ivg_stop) {
-				atomic_inc(&num_spurious);
-				return;
-			}
-			if (sic_status[(ivg->irqno - IVG7) / 32] & ivg->isrflag)
-				break;
-		}
-#else
-		unsigned long sic_status;
-
-		sic_status = bfin_read_SIC_IMASK() & bfin_read_SIC_ISR();
+	} else {
+		sic_status[0] = bfin_read_SIC_ISR0() & bfin_read_SIC_IMASK0();
+		sic_status[1] = bfin_read_SIC_ISR1() & bfin_read_SIC_IMASK1();
+	}
+#endif
+#ifdef SIC_ISR2
+	sic_status[2] = bfin_read_SIC_ISR2() & bfin_read_SIC_IMASK2();
+#endif
 
-		for (;; ivg++) {
-			if (ivg >= ivg_stop) {
-				atomic_inc(&num_spurious);
-				return;
-			} else if (sic_status & ivg->isrflag)
-				break;
-		}
+	for (;; ivg++) {
+		if (ivg >= ivg_stop)
+			return -1;
+#ifdef SIC_ISR
+		if (sic_status[0] & ivg->isrflag)
+#else
+		if (sic_status[(ivg->irqno - IVG7) / 32] & ivg->isrflag)
 #endif
-		vec = ivg->irqno;
+			return ivg->irqno;
 	}
-	asm_do_IRQ(vec, fp);
+}
+
+#ifdef CONFIG_DO_IRQ_L1
+__attribute__((l1_text))
+#endif
+void do_irq(int vec, struct pt_regs *fp)
+{
+	int irq = vec_to_irq(vec);
+	if (irq == -1)
+		return;
+	asm_do_IRQ(irq, fp);
 }
 
 #ifdef CONFIG_IPIPE
@@ -1391,40 +1208,9 @@
 	struct ivgx *ivg = ivg7_13[vec-IVG7].ifirst;
 	int irq, s = 0;
 
-	if (likely(vec == EVT_IVTMR_P))
-		irq = IRQ_CORETMR;
-	else {
-#if defined(SIC_ISR0)
-		unsigned long sic_status[3];
-
-		sic_status[0] = bfin_read_SIC_ISR0() & bfin_read_SIC_IMASK0();
-		sic_status[1] = bfin_read_SIC_ISR1() & bfin_read_SIC_IMASK1();
-# ifdef SIC_ISR2
-		sic_status[2] = bfin_read_SIC_ISR2() & bfin_read_SIC_IMASK2();
-# endif
-		for (;; ivg++) {
-			if (ivg >= ivg_stop) {
-				atomic_inc(&num_spurious);
-				return 0;
-			}
-			if (sic_status[(ivg->irqno - IVG7) / 32] & ivg->isrflag)
-				break;
-		}
-#else
-		unsigned long sic_status;
-
-		sic_status = bfin_read_SIC_IMASK() & bfin_read_SIC_ISR();
-
-		for (;; ivg++) {
-			if (ivg >= ivg_stop) {
-				atomic_inc(&num_spurious);
-				return 0;
-			} else if (sic_status & ivg->isrflag)
-				break;
-		}
-#endif
-		irq = ivg->irqno;
-	}
+	irq = vec_to_irq(vec);
+	if (irq == -1)
+		return 0;
 
 	if (irq == IRQ_SYSTMR) {
 #if !defined(CONFIG_GENERIC_CLOCKEVENTS) || defined(CONFIG_TICKSOURCE_GPTMR0)
diff -druN linux-2.6.39-libre/arch/blackfin/mach-common/smp.c linux-3.0-rc7-libre/arch/blackfin/mach-common/smp.c
--- linux-2.6.39-libre/arch/blackfin/mach-common/smp.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/blackfin/mach-common/smp.c	2011-07-11 19:51:52.000000000 -0400
@@ -25,6 +25,7 @@
 #include <linux/slab.h>
 #include <asm/atomic.h>
 #include <asm/cacheflush.h>
+#include <asm/irq_handler.h>
 #include <asm/mmu_context.h>
 #include <asm/pgtable.h>
 #include <asm/pgalloc.h>
@@ -96,7 +97,7 @@
 	dump_stack();
 	spin_unlock(&stop_lock);
 
-	cpu_clear(cpu, cpu_online_map);
+	set_cpu_online(cpu, false);
 
 	local_irq_disable();
 
@@ -146,7 +147,7 @@
 		 */
 		resync_core_dcache();
 #endif
-		cpu_clear(cpu, *msg->call_struct.waitmask);
+		cpumask_clear_cpu(cpu, msg->call_struct.waitmask);
 	}
 }
 
@@ -177,6 +178,9 @@
 	while (msg_queue->count) {
 		msg = &msg_queue->ipi_message[msg_queue->head];
 		switch (msg->type) {
+		case BFIN_IPI_RESCHEDULE:
+			scheduler_ipi();
+			break;
 		case BFIN_IPI_CALL_FUNC:
 			spin_unlock_irqrestore(&msg_queue->lock, flags);
 			ipi_call_function(cpu, msg);
@@ -219,9 +223,10 @@
 	struct ipi_message_queue *msg_queue;
 	struct ipi_message *msg;
 	unsigned long flags, next_msg;
-	cpumask_t waitmask = callmap; /* waitmask is shared by all cpus */
+	cpumask_t waitmask; /* waitmask is shared by all cpus */
 
-	for_each_cpu_mask(cpu, callmap) {
+	cpumask_copy(&waitmask, &callmap);
+	for_each_cpu(cpu, &callmap) {
 		msg_queue = &per_cpu(ipi_msg_queue, cpu);
 		spin_lock_irqsave(&msg_queue->lock, flags);
 		if (msg_queue->count < BFIN_IPI_MSGQ_LEN) {
@@ -243,7 +248,7 @@
 	}
 
 	if (wait) {
-		while (!cpus_empty(waitmask))
+		while (!cpumask_empty(&waitmask))
 			blackfin_dcache_invalidate_range(
 				(unsigned long)(&waitmask),
 				(unsigned long)(&waitmask));
@@ -262,9 +267,9 @@
 	cpumask_t callmap;
 
 	preempt_disable();
-	callmap = cpu_online_map;
-	cpu_clear(smp_processor_id(), callmap);
-	if (!cpus_empty(callmap))
+	cpumask_copy(&callmap, cpu_online_mask);
+	cpumask_clear_cpu(smp_processor_id(), &callmap);
+	if (!cpumask_empty(&callmap))
 		smp_send_message(callmap, BFIN_IPI_CALL_FUNC, func, info, wait);
 
 	preempt_enable();
@@ -281,8 +286,8 @@
 
 	if (cpu_is_offline(cpu))
 		return 0;
-	cpus_clear(callmap);
-	cpu_set(cpu, callmap);
+	cpumask_clear(&callmap);
+	cpumask_set_cpu(cpu, &callmap);
 
 	smp_send_message(callmap, BFIN_IPI_CALL_FUNC, func, info, wait);
 
@@ -305,9 +310,9 @@
 	cpumask_t callmap;
 
 	preempt_disable();
-	callmap = cpu_online_map;
-	cpu_clear(smp_processor_id(), callmap);
-	if (!cpus_empty(callmap))
+	cpumask_copy(&callmap, cpu_online_mask);
+	cpumask_clear_cpu(smp_processor_id(), &callmap);
+	if (!cpumask_empty(&callmap))
 		smp_send_message(callmap, BFIN_IPI_CPU_STOP, NULL, NULL, 0);
 
 	preempt_enable();
diff -druN linux-2.6.39-libre/arch/blackfin/mm/maccess.c linux-3.0-rc7-libre/arch/blackfin/mm/maccess.c
--- linux-2.6.39-libre/arch/blackfin/mm/maccess.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/blackfin/mm/maccess.c	2011-07-11 19:51:52.000000000 -0400
@@ -16,7 +16,7 @@
 	return bfin_mem_access_type(addr, size);
 }
 
-long probe_kernel_read(void *dst, void *src, size_t size)
+long probe_kernel_read(void *dst, const void *src, size_t size)
 {
 	unsigned long lsrc = (unsigned long)src;
 	int mem_type;
@@ -55,7 +55,7 @@
 	return -EFAULT;
 }
 
-long probe_kernel_write(void *dst, void *src, size_t size)
+long probe_kernel_write(void *dst, const void *src, size_t size)
 {
 	unsigned long ldst = (unsigned long)dst;
 	int mem_type;
diff -druN linux-2.6.39-libre/arch/blackfin/mm/sram-alloc.c linux-3.0-rc7-libre/arch/blackfin/mm/sram-alloc.c
--- linux-2.6.39-libre/arch/blackfin/mm/sram-alloc.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/blackfin/mm/sram-alloc.c	2011-07-11 19:51:52.000000000 -0400
@@ -15,6 +15,7 @@
 #include <linux/init.h>
 #include <linux/poll.h>
 #include <linux/proc_fs.h>
+#include <linux/seq_file.h>
 #include <linux/spinlock.h>
 #include <linux/rtc.h>
 #include <linux/slab.h>
@@ -764,7 +765,7 @@
 /* Need to keep line of output the same.  Currently, that is 44 bytes
  * (including newline).
  */
-static int _sram_proc_read(char *buf, int *len, int count, const char *desc,
+static int _sram_proc_show(struct seq_file *m, const char *desc,
 		struct sram_piece *pfree_head,
 		struct sram_piece *pused_head)
 {
@@ -773,13 +774,13 @@
 	if (!pfree_head || !pused_head)
 		return -1;
 
-	*len += sprintf(&buf[*len], "--- SRAM %-14s Size   PID State     \n", desc);
+	seq_printf(m, "--- SRAM %-14s Size   PID State     \n", desc);
 
 	/* search the relevant memory slot */
 	pslot = pused_head->next;
 
 	while (pslot != NULL) {
-		*len += sprintf(&buf[*len], "%p-%p %10i %5i %-10s\n",
+		seq_printf(m, "%p-%p %10i %5i %-10s\n",
 			pslot->paddr, pslot->paddr + pslot->size,
 			pslot->size, pslot->pid, "ALLOCATED");
 
@@ -789,7 +790,7 @@
 	pslot = pfree_head->next;
 
 	while (pslot != NULL) {
-		*len += sprintf(&buf[*len], "%p-%p %10i %5i %-10s\n",
+		seq_printf(m, "%p-%p %10i %5i %-10s\n",
 			pslot->paddr, pslot->paddr + pslot->size,
 			pslot->size, pslot->pid, "FREE");
 
@@ -798,54 +799,62 @@
 
 	return 0;
 }
-static int sram_proc_read(char *buf, char **start, off_t offset, int count,
-		int *eof, void *data)
+static int sram_proc_show(struct seq_file *m, void *v)
 {
-	int len = 0;
 	unsigned int cpu;
 
 	for (cpu = 0; cpu < num_possible_cpus(); ++cpu) {
-		if (_sram_proc_read(buf, &len, count, "Scratchpad",
+		if (_sram_proc_show(m, "Scratchpad",
 			&per_cpu(free_l1_ssram_head, cpu), &per_cpu(used_l1_ssram_head, cpu)))
 			goto not_done;
 #if L1_DATA_A_LENGTH != 0
-		if (_sram_proc_read(buf, &len, count, "L1 Data A",
+		if (_sram_proc_show(m, "L1 Data A",
 			&per_cpu(free_l1_data_A_sram_head, cpu),
 			&per_cpu(used_l1_data_A_sram_head, cpu)))
 			goto not_done;
 #endif
 #if L1_DATA_B_LENGTH != 0
-		if (_sram_proc_read(buf, &len, count, "L1 Data B",
+		if (_sram_proc_show(m, "L1 Data B",
 			&per_cpu(free_l1_data_B_sram_head, cpu),
 			&per_cpu(used_l1_data_B_sram_head, cpu)))
 			goto not_done;
 #endif
 #if L1_CODE_LENGTH != 0
-		if (_sram_proc_read(buf, &len, count, "L1 Instruction",
+		if (_sram_proc_show(m, "L1 Instruction",
 			&per_cpu(free_l1_inst_sram_head, cpu),
 			&per_cpu(used_l1_inst_sram_head, cpu)))
 			goto not_done;
 #endif
 	}
 #if L2_LENGTH != 0
-	if (_sram_proc_read(buf, &len, count, "L2", &free_l2_sram_head,
-		&used_l2_sram_head))
+	if (_sram_proc_show(m, "L2", &free_l2_sram_head, &used_l2_sram_head))
 		goto not_done;
 #endif
-	*eof = 1;
  not_done:
-	return len;
+	return 0;
 }
 
+static int sram_proc_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, sram_proc_show, NULL);
+}
+
+static const struct file_operations sram_proc_ops = {
+	.open		= sram_proc_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
 static int __init sram_proc_init(void)
 {
 	struct proc_dir_entry *ptr;
-	ptr = create_proc_entry("sram", S_IFREG | S_IRUGO, NULL);
+
+	ptr = proc_create("sram", S_IRUGO, NULL, &sram_proc_ops);
 	if (!ptr) {
 		printk(KERN_WARNING "unable to create /proc/sram\n");
 		return -1;
 	}
-	ptr->read_proc = sram_proc_read;
 	return 0;
 }
 late_initcall(sram_proc_init);
diff -druN linux-2.6.39-libre/arch/cris/arch-v10/drivers/axisflashmap.c linux-3.0-rc7-libre/arch/cris/arch-v10/drivers/axisflashmap.c
--- linux-2.6.39-libre/arch/cris/arch-v10/drivers/axisflashmap.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/cris/arch-v10/drivers/axisflashmap.c	2011-07-11 19:51:52.000000000 -0400
@@ -372,7 +372,7 @@
 #ifdef CONFIG_ETRAX_AXISFLASHMAP_MTD0WHOLE
 	if (mymtd) {
 		main_partition.size = mymtd->size;
-		err = add_mtd_partitions(mymtd, &main_partition, 1);
+		err = mtd_device_register(mymtd, &main_partition, 1);
 		if (err)
 			panic("axisflashmap: Could not initialize "
 			      "partition for whole main mtd device!\n");
@@ -382,10 +382,12 @@
         if (mymtd) {
 		if (use_default_ptable) {
 			printk(KERN_INFO " Using default partition table.\n");
-			err = add_mtd_partitions(mymtd, axis_default_partitions,
-						 NUM_DEFAULT_PARTITIONS);
+			err = mtd_device_register(mymtd,
+						  axis_default_partitions,
+						  NUM_DEFAULT_PARTITIONS);
 		} else {
-			err = add_mtd_partitions(mymtd, axis_partitions, pidx);
+			err = mtd_device_register(mymtd, axis_partitions,
+						  pidx);
 		}
 
 		if (err)
diff -druN linux-2.6.39-libre/arch/cris/arch-v10/kernel/entry.S linux-3.0-rc7-libre/arch/cris/arch-v10/kernel/entry.S
--- linux-2.6.39-libre/arch/cris/arch-v10/kernel/entry.S	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/cris/arch-v10/kernel/entry.S	2011-07-11 19:51:52.000000000 -0400
@@ -937,6 +937,7 @@
 	.long sys_inotify_init1
 	.long sys_preadv
 	.long sys_pwritev
+	.long sys_setns			/* 335 */
 
         /*
          * NOTE!! This doesn't have to be exact - we just have
diff -druN linux-2.6.39-libre/arch/cris/arch-v32/drivers/axisflashmap.c linux-3.0-rc7-libre/arch/cris/arch-v32/drivers/axisflashmap.c
--- linux-2.6.39-libre/arch/cris/arch-v32/drivers/axisflashmap.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/cris/arch-v32/drivers/axisflashmap.c	2011-07-11 19:51:52.000000000 -0400
@@ -561,7 +561,7 @@
 #ifdef CONFIG_ETRAX_AXISFLASHMAP_MTD0WHOLE
 	if (main_mtd) {
 		main_partition.size = main_mtd->size;
-		err = add_mtd_partitions(main_mtd, &main_partition, 1);
+		err = mtd_device_register(main_mtd, &main_partition, 1);
 		if (err)
 			panic("axisflashmap: Could not initialize "
 			      "partition for whole main mtd device!\n");
@@ -597,7 +597,8 @@
 			mtd_ram->erasesize = (main_mtd ? main_mtd->erasesize :
 				CONFIG_ETRAX_PTABLE_SECTOR);
 		} else {
-			err = add_mtd_partitions(main_mtd, &partition[part], 1);
+			err = mtd_device_register(main_mtd, &partition[part],
+						  1);
 			if (err)
 				panic("axisflashmap: Could not add mtd "
 					"partition %d\n", part);
@@ -633,7 +634,7 @@
 #ifndef CONFIG_ETRAX_VCS_SIM
 	if (aux_mtd) {
 		aux_partition.size = aux_mtd->size;
-		err = add_mtd_partitions(aux_mtd, &aux_partition, 1);
+		err = mtd_device_register(aux_mtd, &aux_partition, 1);
 		if (err)
 			panic("axisflashmap: Could not initialize "
 			      "aux mtd device!\n");
diff -druN linux-2.6.39-libre/arch/cris/arch-v32/drivers/Kconfig linux-3.0-rc7-libre/arch/cris/arch-v32/drivers/Kconfig
--- linux-2.6.39-libre/arch/cris/arch-v32/drivers/Kconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/cris/arch-v32/drivers/Kconfig	2011-07-11 19:51:52.000000000 -0400
@@ -405,7 +405,6 @@
 	select MTD_JEDECPROBE
 	select MTD_CHAR
 	select MTD_BLOCK
-	select MTD_PARTITIONS
 	select MTD_COMPLEX_MAPPINGS
 	help
 	  This option enables MTD mapping of flash devices.  Needed to use
diff -druN linux-2.6.39-libre/arch/cris/arch-v32/kernel/entry.S linux-3.0-rc7-libre/arch/cris/arch-v32/kernel/entry.S
--- linux-2.6.39-libre/arch/cris/arch-v32/kernel/entry.S	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/cris/arch-v32/kernel/entry.S	2011-07-11 19:51:52.000000000 -0400
@@ -880,6 +880,7 @@
 	.long sys_inotify_init1
 	.long sys_preadv
 	.long sys_pwritev
+	.long sys_setns			/* 335 */
 
         /*
          * NOTE!! This doesn't have to be exact - we just have
diff -druN linux-2.6.39-libre/arch/cris/arch-v32/kernel/irq.c linux-3.0-rc7-libre/arch/cris/arch-v32/kernel/irq.c
--- linux-2.6.39-libre/arch/cris/arch-v32/kernel/irq.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/cris/arch-v32/kernel/irq.c	2011-07-11 19:51:52.000000000 -0400
@@ -266,11 +266,11 @@
 
 
 	/* Let the interrupt stay if possible */
-	if (cpu_isset(cpu, irq_allocations[irq - FIRST_IRQ].mask))
+	if (cpumask_test_cpu(cpu, &irq_allocations[irq - FIRST_IRQ].mask))
 		goto out;
 
 	/* IRQ must be moved to another CPU. */
-	cpu = first_cpu(irq_allocations[irq - FIRST_IRQ].mask);
+	cpu = cpumask_first(&irq_allocations[irq - FIRST_IRQ].mask);
 	irq_allocations[irq - FIRST_IRQ].cpu = cpu;
 out:
 	spin_unlock_irqrestore(&irq_lock, flags);
diff -druN linux-2.6.39-libre/arch/cris/arch-v32/kernel/smp.c linux-3.0-rc7-libre/arch/cris/arch-v32/kernel/smp.c
--- linux-2.6.39-libre/arch/cris/arch-v32/kernel/smp.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/cris/arch-v32/kernel/smp.c	2011-07-11 19:51:52.000000000 -0400
@@ -81,7 +81,7 @@
 
 	/* Mark all possible CPUs as present */
 	for (i = 0; i < max_cpus; i++)
-	    cpu_set(i, phys_cpu_present_map);
+		cpumask_set_cpu(i, &phys_cpu_present_map);
 }
 
 void __devinit smp_prepare_boot_cpu(void)
@@ -98,7 +98,7 @@
 	SUPP_REG_WR(RW_MM_TLB_PGD, pgd);
 
 	set_cpu_online(0, true);
-	cpu_set(0, phys_cpu_present_map);
+	cpumask_set_cpu(0, &phys_cpu_present_map);
 	set_cpu_possible(0, true);
 }
 
@@ -112,8 +112,9 @@
 {
 	unsigned timeout;
 	struct task_struct *idle;
-	cpumask_t cpu_mask = CPU_MASK_NONE;
+	cpumask_t cpu_mask;
 
+	cpumask_clear(&cpu_mask);
 	idle = fork_idle(cpuid);
 	if (IS_ERR(idle))
 		panic("SMP: fork failed for CPU:%d", cpuid);
@@ -125,10 +126,10 @@
 	cpu_now_booting = cpuid;
 
 	/* Kick it */
-	cpu_set(cpuid, cpu_online_map);
-	cpu_set(cpuid, cpu_mask);
+	set_cpu_online(cpuid, true);
+	cpumask_set_cpu(cpuid, &cpu_mask);
 	send_ipi(IPI_BOOT, 0, cpu_mask);
-	cpu_clear(cpuid, cpu_online_map);
+	set_cpu_online(cpuid, false);
 
 	/* Wait for CPU to come online */
 	for (timeout = 0; timeout < 10000; timeout++) {
@@ -176,7 +177,7 @@
 	notify_cpu_starting(cpu);
 	local_irq_enable();
 
-	cpu_set(cpu, cpu_online_map);
+	set_cpu_online(cpu, true);
 	cpu_idle();
 }
 
@@ -214,8 +215,9 @@
 
 void smp_send_reschedule(int cpu)
 {
-	cpumask_t cpu_mask = CPU_MASK_NONE;
-	cpu_set(cpu, cpu_mask);
+	cpumask_t cpu_mask;
+	cpumask_clear(&cpu_mask);
+	cpumask_set_cpu(cpu, &cpu_mask);
 	send_ipi(IPI_SCHEDULE, 0, cpu_mask);
 }
 
@@ -232,7 +234,7 @@
 
 	spin_lock_irqsave(&tlbstate_lock, flags);
 	cpu_mask = (mm == FLUSH_ALL ? cpu_all_mask : *mm_cpumask(mm));
-	cpu_clear(smp_processor_id(), cpu_mask);
+	cpumask_clear_cpu(smp_processor_id(), &cpu_mask);
 	flush_mm = mm;
 	flush_vma = vma;
 	flush_addr = addr;
@@ -277,10 +279,10 @@
 	int ret = 0;
 
 	/* Calculate CPUs to send to. */
-	cpus_and(cpu_mask, cpu_mask, cpu_online_map);
+	cpumask_and(&cpu_mask, &cpu_mask, cpu_online_mask);
 
 	/* Send the IPI. */
-	for_each_cpu_mask(i, cpu_mask)
+	for_each_cpu(i, &cpu_mask)
 	{
 		ipi.vector |= vector;
 		REG_WR(intr_vect, irq_regs[i], rw_ipi, ipi);
@@ -288,7 +290,7 @@
 
 	/* Wait for IPI to finish on other CPUS */
 	if (wait) {
-		for_each_cpu_mask(i, cpu_mask) {
+		for_each_cpu(i, &cpu_mask) {
                         int j;
                         for (j = 0 ; j < 1000; j++) {
 				ipi = REG_RD(intr_vect, irq_regs[i], rw_ipi);
@@ -314,11 +316,12 @@
  */
 int smp_call_function(void (*func)(void *info), void *info, int wait)
 {
-	cpumask_t cpu_mask = CPU_MASK_ALL;
+	cpumask_t cpu_mask;
 	struct call_data_struct data;
 	int ret;
 
-	cpu_clear(smp_processor_id(), cpu_mask);
+	cpumask_setall(&cpu_mask);
+	cpumask_clear_cpu(smp_processor_id(), &cpu_mask);
 
 	WARN_ON(irqs_disabled());
 
@@ -342,15 +345,18 @@
 
 	ipi = REG_RD(intr_vect, irq_regs[smp_processor_id()], rw_ipi);
 
+	if (ipi.vector & IPI_SCHEDULE) {
+		scheduler_ipi();
+	}
 	if (ipi.vector & IPI_CALL) {
-	         func(info);
+		func(info);
 	}
 	if (ipi.vector & IPI_FLUSH_TLB) {
-		     if (flush_mm == FLUSH_ALL)
-			 __flush_tlb_all();
-		     else if (flush_vma == FLUSH_ALL)
+		if (flush_mm == FLUSH_ALL)
+			__flush_tlb_all();
+		else if (flush_vma == FLUSH_ALL)
 			__flush_tlb_mm(flush_mm);
-		     else
+		else
 			__flush_tlb_page(flush_vma, flush_addr);
 	}
 
diff -druN linux-2.6.39-libre/arch/cris/arch-v32/mach-fs/Makefile linux-3.0-rc7-libre/arch/cris/arch-v32/mach-fs/Makefile
--- linux-2.6.39-libre/arch/cris/arch-v32/mach-fs/Makefile	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/cris/arch-v32/mach-fs/Makefile	2011-07-11 19:51:52.000000000 -0400
@@ -4,7 +4,7 @@
 #
 
 obj-y   := dma.o pinmux.o io.o arbiter.o
-bj-$(CONFIG_ETRAX_VCS_SIM) += vcs_hook.o
+obj-$(CONFIG_ETRAX_VCS_SIM) += vcs_hook.o
 obj-$(CONFIG_CPU_FREQ)   += cpufreq.o
 
 clean:
diff -druN linux-2.6.39-libre/arch/cris/include/asm/unistd.h linux-3.0-rc7-libre/arch/cris/include/asm/unistd.h
--- linux-2.6.39-libre/arch/cris/include/asm/unistd.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/cris/include/asm/unistd.h	2011-07-11 19:51:52.000000000 -0400
@@ -339,10 +339,11 @@
 #define __NR_inotify_init1	332
 #define __NR_preadv		333
 #define __NR_pwritev		334
+#define __NR_setns		335
 
 #ifdef __KERNEL__
 
-#define NR_syscalls 335
+#define NR_syscalls 336
 
 #include <arch/unistd.h>
 
diff -druN linux-2.6.39-libre/arch/cris/Kconfig linux-3.0-rc7-libre/arch/cris/Kconfig
--- linux-2.6.39-libre/arch/cris/Kconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/cris/Kconfig	2011-07-11 19:51:52.000000000 -0400
@@ -31,10 +31,6 @@
 	bool
 	default n
 
-config GENERIC_FIND_NEXT_BIT
-	bool
-	default y
-
 config GENERIC_HWEIGHT
 	bool
 	default y
@@ -274,7 +270,6 @@
 	select MTD_JEDECPROBE if ETRAX_ARCH_V32
 	select MTD_CHAR
 	select MTD_BLOCK
-	select MTD_PARTITIONS
 	select MTD_COMPLEX_MAPPINGS
 	help
 	  This option enables MTD mapping of flash devices.  Needed to use
diff -druN linux-2.6.39-libre/arch/cris/kernel/vmlinux.lds.S linux-3.0-rc7-libre/arch/cris/kernel/vmlinux.lds.S
--- linux-2.6.39-libre/arch/cris/kernel/vmlinux.lds.S	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/cris/kernel/vmlinux.lds.S	2011-07-11 19:51:52.000000000 -0400
@@ -102,7 +102,7 @@
 #endif
 	__vmlinux_end = .;		/* Last address of the physical file. */
 #ifdef CONFIG_ETRAX_ARCH_V32
-	PERCPU(32, PAGE_SIZE)
+	PERCPU_SECTION(32)
 
 	.init.ramfs : {
 		INIT_RAM_FS
diff -druN linux-2.6.39-libre/arch/cris/mm/init.c linux-3.0-rc7-libre/arch/cris/mm/init.c
--- linux-2.6.39-libre/arch/cris/mm/init.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/cris/mm/init.c	2011-07-11 19:51:52.000000000 -0400
@@ -13,8 +13,6 @@
 #include <linux/bootmem.h>
 #include <asm/tlb.h>
 
-DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
-
 unsigned long empty_zero_page;
 
 extern char _stext, _edata, _etext; /* From linkerscript */
diff -druN linux-2.6.39-libre/arch/frv/include/asm/suspend.h linux-3.0-rc7-libre/arch/frv/include/asm/suspend.h
--- linux-2.6.39-libre/arch/frv/include/asm/suspend.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/frv/include/asm/suspend.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,20 +0,0 @@
-/* suspend.h: suspension stuff
- *
- * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
- * Written by David Howells (dhowells@redhat.com)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- */
-
-#ifndef _ASM_SUSPEND_H
-#define _ASM_SUSPEND_H
-
-static inline int arch_prepare_suspend(void)
-{
-	return 0;
-}
-
-#endif /* _ASM_SUSPEND_H */
diff -druN linux-2.6.39-libre/arch/frv/include/asm/unistd.h linux-3.0-rc7-libre/arch/frv/include/asm/unistd.h
--- linux-2.6.39-libre/arch/frv/include/asm/unistd.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/frv/include/asm/unistd.h	2011-07-11 19:51:52.000000000 -0400
@@ -343,10 +343,11 @@
 #define __NR_pwritev		334
 #define __NR_rt_tgsigqueueinfo	335
 #define __NR_perf_event_open	336
+#define __NR_setns		337
 
 #ifdef __KERNEL__
 
-#define NR_syscalls 337
+#define NR_syscalls 338
 
 #define __ARCH_WANT_IPC_PARSE_VERSION
 /* #define __ARCH_WANT_OLD_READDIR */
diff -druN linux-2.6.39-libre/arch/frv/Kconfig linux-3.0-rc7-libre/arch/frv/Kconfig
--- linux-2.6.39-libre/arch/frv/Kconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/frv/Kconfig	2011-07-11 19:51:52.000000000 -0400
@@ -19,14 +19,6 @@
 config RWSEM_XCHGADD_ALGORITHM
 	bool
 
-config GENERIC_FIND_NEXT_BIT
-	bool
-	default y
-
-config GENERIC_FIND_BIT_LE
-	bool
-	default y
-
 config GENERIC_HWEIGHT
 	bool
 	default y
diff -druN linux-2.6.39-libre/arch/frv/kernel/entry.S linux-3.0-rc7-libre/arch/frv/kernel/entry.S
--- linux-2.6.39-libre/arch/frv/kernel/entry.S	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/frv/kernel/entry.S	2011-07-11 19:51:52.000000000 -0400
@@ -1526,5 +1526,6 @@
 	.long sys_pwritev
 	.long sys_rt_tgsigqueueinfo	/* 335 */
 	.long sys_perf_event_open
+	.long sys_setns
 
 syscall_table_size = (. - sys_call_table)
diff -druN linux-2.6.39-libre/arch/frv/kernel/vmlinux.lds.S linux-3.0-rc7-libre/arch/frv/kernel/vmlinux.lds.S
--- linux-2.6.39-libre/arch/frv/kernel/vmlinux.lds.S	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/frv/kernel/vmlinux.lds.S	2011-07-11 19:51:52.000000000 -0400
@@ -37,7 +37,7 @@
   _einittext = .;
 
   INIT_DATA_SECTION(8)
-  PERCPU(L1_CACHE_BYTES, 4096)
+  PERCPU_SECTION(L1_CACHE_BYTES)
 
   . = ALIGN(PAGE_SIZE);
   __init_end = .;
diff -druN linux-2.6.39-libre/arch/frv/mm/init.c linux-3.0-rc7-libre/arch/frv/mm/init.c
--- linux-2.6.39-libre/arch/frv/mm/init.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/frv/mm/init.c	2011-07-11 19:51:52.000000000 -0400
@@ -41,8 +41,6 @@
 
 #undef DEBUG
 
-DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
-
 /*
  * BAD_PAGE is the page that is used for page faults when linux
  * is out-of-memory. Older versions of linux just did a
diff -druN linux-2.6.39-libre/arch/h8300/include/asm/unistd.h linux-3.0-rc7-libre/arch/h8300/include/asm/unistd.h
--- linux-2.6.39-libre/arch/h8300/include/asm/unistd.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/h8300/include/asm/unistd.h	2011-07-11 19:51:52.000000000 -0400
@@ -325,10 +325,11 @@
 #define __NR_move_pages		317
 #define __NR_getcpu		318
 #define __NR_epoll_pwait	319
+#define __NR_setns		320
 
 #ifdef __KERNEL__
 
-#define NR_syscalls 320
+#define NR_syscalls 321
 
 #define __ARCH_WANT_IPC_PARSE_VERSION
 #define __ARCH_WANT_OLD_READDIR
diff -druN linux-2.6.39-libre/arch/h8300/Kconfig linux-3.0-rc7-libre/arch/h8300/Kconfig
--- linux-2.6.39-libre/arch/h8300/Kconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/h8300/Kconfig	2011-07-11 19:51:52.000000000 -0400
@@ -41,14 +41,6 @@
 	bool
 	default n
 
-config GENERIC_FIND_NEXT_BIT
-	bool
-	default y
-
-config GENERIC_FIND_BIT_LE
-	bool
-	default y
-
 config GENERIC_HWEIGHT
 	bool
 	default y
diff -druN linux-2.6.39-libre/arch/h8300/kernel/syscalls.S linux-3.0-rc7-libre/arch/h8300/kernel/syscalls.S
--- linux-2.6.39-libre/arch/h8300/kernel/syscalls.S	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/h8300/kernel/syscalls.S	2011-07-11 19:51:52.000000000 -0400
@@ -333,6 +333,7 @@
 	.long SYMBOL_NAME(sys_ni_syscall)	/* sys_move_pages */
 	.long SYMBOL_NAME(sys_getcpu)
 	.long SYMBOL_NAME(sys_ni_syscall)	/* sys_epoll_pwait */
+	.long SYMBOL_NAME(sys_setns)		/* 320 */
 
 	.macro	call_sp addr
 	mov.l	#SYMBOL_NAME(\addr),er6
diff -druN linux-2.6.39-libre/arch/ia64/hp/common/sba_iommu.c linux-3.0-rc7-libre/arch/ia64/hp/common/sba_iommu.c
--- linux-2.6.39-libre/arch/ia64/hp/common/sba_iommu.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/ia64/hp/common/sba_iommu.c	2011-07-11 19:51:52.000000000 -0400
@@ -37,6 +37,7 @@
 #include <linux/crash_dump.h>
 #include <linux/iommu-helper.h>
 #include <linux/dma-mapping.h>
+#include <linux/prefetch.h>
 
 #include <asm/delay.h>		/* ia64_get_itc() */
 #include <asm/io.h>
@@ -1063,7 +1064,7 @@
 		/*
 		** Address does not fall w/in IOVA, must be bypassing
 		*/
-		DBG_BYPASS("sba_unmap_single_atttrs() bypass addr: 0x%lx\n",
+		DBG_BYPASS("sba_unmap_single_attrs() bypass addr: 0x%lx\n",
 			   iova);
 
 #ifdef ENABLE_MARK_CLEAN
diff -druN linux-2.6.39-libre/arch/ia64/include/asm/tlb.h linux-3.0-rc7-libre/arch/ia64/include/asm/tlb.h
--- linux-2.6.39-libre/arch/ia64/include/asm/tlb.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/ia64/include/asm/tlb.h	2011-07-11 19:51:52.000000000 -0400
@@ -47,21 +47,27 @@
 #include <asm/machvec.h>
 
 #ifdef CONFIG_SMP
-# define FREE_PTE_NR		2048
 # define tlb_fast_mode(tlb)	((tlb)->nr == ~0U)
 #else
-# define FREE_PTE_NR		0
 # define tlb_fast_mode(tlb)	(1)
 #endif
 
+/*
+ * If we can't allocate a page to make a big batch of page pointers
+ * to work on, then just handle a few from the on-stack structure.
+ */
+#define	IA64_GATHER_BUNDLE	8
+
 struct mmu_gather {
 	struct mm_struct	*mm;
 	unsigned int		nr;		/* == ~0U => fast mode */
+	unsigned int		max;
 	unsigned char		fullmm;		/* non-zero means full mm flush */
 	unsigned char		need_flush;	/* really unmapped some PTEs? */
 	unsigned long		start_addr;
 	unsigned long		end_addr;
-	struct page 		*pages[FREE_PTE_NR];
+	struct page		**pages;
+	struct page		*local[IA64_GATHER_BUNDLE];
 };
 
 struct ia64_tr_entry {
@@ -90,9 +96,6 @@
 #define RR_RID_MASK	0x00000000ffffff00L
 #define RR_TO_RID(val) 	((val >> 8) & 0xffffff)
 
-/* Users of the generic TLB shootdown code must declare this storage space. */
-DECLARE_PER_CPU(struct mmu_gather, mmu_gathers);
-
 /*
  * Flush the TLB for address range START to END and, if not in fast mode, release the
  * freed pages that where gathered up to this point.
@@ -147,15 +150,23 @@
 	}
 }
 
-/*
- * Return a pointer to an initialized struct mmu_gather.
- */
-static inline struct mmu_gather *
-tlb_gather_mmu (struct mm_struct *mm, unsigned int full_mm_flush)
+static inline void __tlb_alloc_page(struct mmu_gather *tlb)
 {
-	struct mmu_gather *tlb = &get_cpu_var(mmu_gathers);
+	unsigned long addr = __get_free_pages(GFP_NOWAIT | __GFP_NOWARN, 0);
+
+	if (addr) {
+		tlb->pages = (void *)addr;
+		tlb->max = PAGE_SIZE / sizeof(void *);
+	}
+}
 
+
+static inline void
+tlb_gather_mmu(struct mmu_gather *tlb, struct mm_struct *mm, unsigned int full_mm_flush)
+{
 	tlb->mm = mm;
+	tlb->max = ARRAY_SIZE(tlb->local);
+	tlb->pages = tlb->local;
 	/*
 	 * Use fast mode if only 1 CPU is online.
 	 *
@@ -172,7 +183,6 @@
 	tlb->nr = (num_online_cpus() == 1) ? ~0U : 0;
 	tlb->fullmm = full_mm_flush;
 	tlb->start_addr = ~0UL;
-	return tlb;
 }
 
 /*
@@ -180,7 +190,7 @@
  * collected.
  */
 static inline void
-tlb_finish_mmu (struct mmu_gather *tlb, unsigned long start, unsigned long end)
+tlb_finish_mmu(struct mmu_gather *tlb, unsigned long start, unsigned long end)
 {
 	/*
 	 * Note: tlb->nr may be 0 at this point, so we can't rely on tlb->start_addr and
@@ -191,7 +201,8 @@
 	/* keep the page table cache within bounds */
 	check_pgt_cache();
 
-	put_cpu_var(mmu_gathers);
+	if (tlb->pages != tlb->local)
+		free_pages((unsigned long)tlb->pages, 0);
 }
 
 /*
@@ -199,18 +210,33 @@
  * must be delayed until after the TLB has been flushed (see comments at the beginning of
  * this file).
  */
-static inline void
-tlb_remove_page (struct mmu_gather *tlb, struct page *page)
+static inline int __tlb_remove_page(struct mmu_gather *tlb, struct page *page)
 {
 	tlb->need_flush = 1;
 
 	if (tlb_fast_mode(tlb)) {
 		free_page_and_swap_cache(page);
-		return;
+		return 1; /* avoid calling tlb_flush_mmu */
 	}
+
+	if (!tlb->nr && tlb->pages == tlb->local)
+		__tlb_alloc_page(tlb);
+
 	tlb->pages[tlb->nr++] = page;
-	if (tlb->nr >= FREE_PTE_NR)
-		ia64_tlb_flush_mmu(tlb, tlb->start_addr, tlb->end_addr);
+	VM_BUG_ON(tlb->nr > tlb->max);
+
+	return tlb->max - tlb->nr;
+}
+
+static inline void tlb_flush_mmu(struct mmu_gather *tlb)
+{
+	ia64_tlb_flush_mmu(tlb, tlb->start_addr, tlb->end_addr);
+}
+
+static inline void tlb_remove_page(struct mmu_gather *tlb, struct page *page)
+{
+	if (!__tlb_remove_page(tlb, page))
+		tlb_flush_mmu(tlb);
 }
 
 /*
diff -druN linux-2.6.39-libre/arch/ia64/include/asm/unistd.h linux-3.0-rc7-libre/arch/ia64/include/asm/unistd.h
--- linux-2.6.39-libre/arch/ia64/include/asm/unistd.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/ia64/include/asm/unistd.h	2011-07-11 19:51:52.000000000 -0400
@@ -319,11 +319,13 @@
 #define __NR_open_by_handle_at  	1327
 #define __NR_clock_adjtime		1328
 #define __NR_syncfs			1329
+#define __NR_setns			1330
+#define __NR_sendmmsg			1331
 
 #ifdef __KERNEL__
 
 
-#define NR_syscalls			306 /* length of syscall table */
+#define NR_syscalls			308 /* length of syscall table */
 
 /*
  * The following defines stop scripts/checksyscalls.sh from complaining about
diff -druN linux-2.6.39-libre/arch/ia64/Kconfig linux-3.0-rc7-libre/arch/ia64/Kconfig
--- linux-2.6.39-libre/arch/ia64/Kconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/ia64/Kconfig	2011-07-11 19:51:52.000000000 -0400
@@ -78,10 +78,6 @@
 	depends on HUGETLB_PAGE
 	default y
 
-config GENERIC_FIND_NEXT_BIT
-	bool
-	default y
-
 config GENERIC_CALIBRATE_DELAY
 	bool
 	default y
diff -druN linux-2.6.39-libre/arch/ia64/kernel/cpufreq/acpi-cpufreq.c linux-3.0-rc7-libre/arch/ia64/kernel/cpufreq/acpi-cpufreq.c
--- linux-2.6.39-libre/arch/ia64/kernel/cpufreq/acpi-cpufreq.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/ia64/kernel/cpufreq/acpi-cpufreq.c	2011-07-11 19:51:52.000000000 -0400
@@ -23,8 +23,6 @@
 #include <linux/acpi.h>
 #include <acpi/processor.h>
 
-#define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, "acpi-cpufreq", msg)
-
 MODULE_AUTHOR("Venkatesh Pallipadi");
 MODULE_DESCRIPTION("ACPI Processor P-States Driver");
 MODULE_LICENSE("GPL");
@@ -47,12 +45,12 @@
 {
 	s64 retval;
 
-	dprintk("processor_set_pstate\n");
+	pr_debug("processor_set_pstate\n");
 
 	retval = ia64_pal_set_pstate((u64)value);
 
 	if (retval) {
-		dprintk("Failed to set freq to 0x%x, with error 0x%lx\n",
+		pr_debug("Failed to set freq to 0x%x, with error 0x%lx\n",
 		        value, retval);
 		return -ENODEV;
 	}
@@ -67,14 +65,14 @@
 	u64	pstate_index = 0;
 	s64 	retval;
 
-	dprintk("processor_get_pstate\n");
+	pr_debug("processor_get_pstate\n");
 
 	retval = ia64_pal_get_pstate(&pstate_index,
 	                             PAL_GET_PSTATE_TYPE_INSTANT);
 	*value = (u32) pstate_index;
 
 	if (retval)
-		dprintk("Failed to get current freq with "
+		pr_debug("Failed to get current freq with "
 			"error 0x%lx, idx 0x%x\n", retval, *value);
 
 	return (int)retval;
@@ -90,7 +88,7 @@
 {
 	unsigned long i;
 
-	dprintk("extract_clock\n");
+	pr_debug("extract_clock\n");
 
 	for (i = 0; i < data->acpi_data.state_count; i++) {
 		if (value == data->acpi_data.states[i].status)
@@ -110,7 +108,7 @@
 	cpumask_t		saved_mask;
 	unsigned long 		clock_freq;
 
-	dprintk("processor_get_freq\n");
+	pr_debug("processor_get_freq\n");
 
 	saved_mask = current->cpus_allowed;
 	set_cpus_allowed_ptr(current, cpumask_of(cpu));
@@ -148,7 +146,7 @@
 	cpumask_t		saved_mask;
 	int			retval;
 
-	dprintk("processor_set_freq\n");
+	pr_debug("processor_set_freq\n");
 
 	saved_mask = current->cpus_allowed;
 	set_cpus_allowed_ptr(current, cpumask_of(cpu));
@@ -159,16 +157,16 @@
 
 	if (state == data->acpi_data.state) {
 		if (unlikely(data->resume)) {
-			dprintk("Called after resume, resetting to P%d\n", state);
+			pr_debug("Called after resume, resetting to P%d\n", state);
 			data->resume = 0;
 		} else {
-			dprintk("Already at target state (P%d)\n", state);
+			pr_debug("Already at target state (P%d)\n", state);
 			retval = 0;
 			goto migrate_end;
 		}
 	}
 
-	dprintk("Transitioning from P%d to P%d\n",
+	pr_debug("Transitioning from P%d to P%d\n",
 		data->acpi_data.state, state);
 
 	/* cpufreq frequency struct */
@@ -186,7 +184,7 @@
 
 	value = (u32) data->acpi_data.states[state].control;
 
-	dprintk("Transitioning to state: 0x%08x\n", value);
+	pr_debug("Transitioning to state: 0x%08x\n", value);
 
 	ret = processor_set_pstate(value);
 	if (ret) {
@@ -219,7 +217,7 @@
 {
 	struct cpufreq_acpi_io *data = acpi_io_data[cpu];
 
-	dprintk("acpi_cpufreq_get\n");
+	pr_debug("acpi_cpufreq_get\n");
 
 	return processor_get_freq(data, cpu);
 }
@@ -235,7 +233,7 @@
 	unsigned int next_state = 0;
 	unsigned int result = 0;
 
-	dprintk("acpi_cpufreq_setpolicy\n");
+	pr_debug("acpi_cpufreq_setpolicy\n");
 
 	result = cpufreq_frequency_table_target(policy,
 			data->freq_table, target_freq, relation, &next_state);
@@ -255,7 +253,7 @@
 	unsigned int result = 0;
 	struct cpufreq_acpi_io *data = acpi_io_data[policy->cpu];
 
-	dprintk("acpi_cpufreq_verify\n");
+	pr_debug("acpi_cpufreq_verify\n");
 
 	result = cpufreq_frequency_table_verify(policy,
 			data->freq_table);
@@ -273,7 +271,7 @@
 	struct cpufreq_acpi_io	*data;
 	unsigned int		result = 0;
 
-	dprintk("acpi_cpufreq_cpu_init\n");
+	pr_debug("acpi_cpufreq_cpu_init\n");
 
 	data = kzalloc(sizeof(struct cpufreq_acpi_io), GFP_KERNEL);
 	if (!data)
@@ -288,7 +286,7 @@
 
 	/* capability check */
 	if (data->acpi_data.state_count <= 1) {
-		dprintk("No P-States\n");
+		pr_debug("No P-States\n");
 		result = -ENODEV;
 		goto err_unreg;
 	}
@@ -297,7 +295,7 @@
 					ACPI_ADR_SPACE_FIXED_HARDWARE) ||
 	    (data->acpi_data.status_register.space_id !=
 					ACPI_ADR_SPACE_FIXED_HARDWARE)) {
-		dprintk("Unsupported address space [%d, %d]\n",
+		pr_debug("Unsupported address space [%d, %d]\n",
 			(u32) (data->acpi_data.control_register.space_id),
 			(u32) (data->acpi_data.status_register.space_id));
 		result = -ENODEV;
@@ -348,7 +346,7 @@
 	       "activated.\n", cpu);
 
 	for (i = 0; i < data->acpi_data.state_count; i++)
-		dprintk("     %cP%d: %d MHz, %d mW, %d uS, %d uS, 0x%x 0x%x\n",
+		pr_debug("     %cP%d: %d MHz, %d mW, %d uS, %d uS, 0x%x 0x%x\n",
 			(i == data->acpi_data.state?'*':' '), i,
 			(u32) data->acpi_data.states[i].core_frequency,
 			(u32) data->acpi_data.states[i].power,
@@ -383,7 +381,7 @@
 {
 	struct cpufreq_acpi_io *data = acpi_io_data[policy->cpu];
 
-	dprintk("acpi_cpufreq_cpu_exit\n");
+	pr_debug("acpi_cpufreq_cpu_exit\n");
 
 	if (data) {
 		cpufreq_frequency_table_put_attr(policy->cpu);
@@ -418,7 +416,7 @@
 static int __init
 acpi_cpufreq_init (void)
 {
-	dprintk("acpi_cpufreq_init\n");
+	pr_debug("acpi_cpufreq_init\n");
 
  	return cpufreq_register_driver(&acpi_cpufreq_driver);
 }
@@ -427,7 +425,7 @@
 static void __exit
 acpi_cpufreq_exit (void)
 {
-	dprintk("acpi_cpufreq_exit\n");
+	pr_debug("acpi_cpufreq_exit\n");
 
 	cpufreq_unregister_driver(&acpi_cpufreq_driver);
 	return;
diff -druN linux-2.6.39-libre/arch/ia64/kernel/cyclone.c linux-3.0-rc7-libre/arch/ia64/kernel/cyclone.c
--- linux-2.6.39-libre/arch/ia64/kernel/cyclone.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/ia64/kernel/cyclone.c	2011-07-11 19:51:52.000000000 -0400
@@ -31,8 +31,6 @@
         .rating         = 300,
         .read           = read_cyclone,
         .mask           = (1LL << 40) - 1,
-        .mult           = 0, /*to be calculated*/
-        .shift          = 16,
         .flags          = CLOCK_SOURCE_IS_CONTINUOUS,
 };
 
@@ -118,9 +116,7 @@
 	/* initialize last tick */
 	cyclone_mc = cyclone_timer;
 	clocksource_cyclone.fsys_mmio = cyclone_timer;
-	clocksource_cyclone.mult = clocksource_hz2mult(CYCLONE_TIMER_FREQ,
-						clocksource_cyclone.shift);
-	clocksource_register(&clocksource_cyclone);
+	clocksource_register_hz(&clocksource_cyclone, CYCLONE_TIMER_FREQ);
 
 	return 0;
 }
diff -druN linux-2.6.39-libre/arch/ia64/kernel/entry.S linux-3.0-rc7-libre/arch/ia64/kernel/entry.S
--- linux-2.6.39-libre/arch/ia64/kernel/entry.S	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/ia64/kernel/entry.S	2011-07-11 19:51:52.000000000 -0400
@@ -1775,6 +1775,8 @@
 	data8 sys_open_by_handle_at
 	data8 sys_clock_adjtime
 	data8 sys_syncfs
+	data8 sys_setns				// 1330
+	data8 sys_sendmmsg
 
 	.org sys_call_table + 8*NR_syscalls	// guard against failures to increase NR_syscalls
 #endif /* __IA64_ASM_PARAVIRTUALIZED_NATIVE */
diff -druN linux-2.6.39-libre/arch/ia64/kernel/irq_ia64.c linux-3.0-rc7-libre/arch/ia64/kernel/irq_ia64.c
--- linux-2.6.39-libre/arch/ia64/kernel/irq_ia64.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/ia64/kernel/irq_ia64.c	2011-07-11 19:51:52.000000000 -0400
@@ -31,6 +31,7 @@
 #include <linux/irq.h>
 #include <linux/ratelimit.h>
 #include <linux/acpi.h>
+#include <linux/sched.h>
 
 #include <asm/delay.h>
 #include <asm/intrinsics.h>
@@ -496,6 +497,7 @@
 			smp_local_flush_tlb();
 			kstat_incr_irqs_this_cpu(irq, desc);
 		} else if (unlikely(IS_RESCHEDULE(vector))) {
+			scheduler_ipi();
 			kstat_incr_irqs_this_cpu(irq, desc);
 		} else {
 			ia64_setreg(_IA64_REG_CR_TPR, vector);
diff -druN linux-2.6.39-libre/arch/ia64/kernel/time.c linux-3.0-rc7-libre/arch/ia64/kernel/time.c
--- linux-2.6.39-libre/arch/ia64/kernel/time.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/ia64/kernel/time.c	2011-07-11 19:51:52.000000000 -0400
@@ -36,7 +36,7 @@
 static cycle_t itc_get_cycles(struct clocksource *cs);
 
 struct fsyscall_gtod_data_t fsyscall_gtod_data = {
-	.lock = SEQLOCK_UNLOCKED,
+	.lock = __SEQLOCK_UNLOCKED(fsyscall_gtod_data.lock),
 };
 
 struct itc_jitter_data_t itc_jitter_data;
@@ -73,8 +73,6 @@
 	.rating         = 350,
 	.read           = itc_get_cycles,
 	.mask           = CLOCKSOURCE_MASK(64),
-	.mult           = 0, /*to be calculated*/
-	.shift          = 16,
 	.flags          = CLOCK_SOURCE_IS_CONTINUOUS,
 #ifdef CONFIG_PARAVIRT
 	.resume		= paravirt_clocksource_resume,
@@ -365,11 +363,8 @@
 	ia64_cpu_local_tick();
 
 	if (!itc_clocksource) {
-		/* Sort out mult/shift values: */
-		clocksource_itc.mult =
-			clocksource_hz2mult(local_cpu_data->itc_freq,
-						clocksource_itc.shift);
-		clocksource_register(&clocksource_itc);
+		clocksource_register_hz(&clocksource_itc,
+						local_cpu_data->itc_freq);
 		itc_clocksource = &clocksource_itc;
 	}
 }
diff -druN linux-2.6.39-libre/arch/ia64/kernel/vmlinux.lds.S linux-3.0-rc7-libre/arch/ia64/kernel/vmlinux.lds.S
--- linux-2.6.39-libre/arch/ia64/kernel/vmlinux.lds.S	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/ia64/kernel/vmlinux.lds.S	2011-07-11 19:51:52.000000000 -0400
@@ -209,6 +209,7 @@
 	data : {
 	} :data
 	.data : AT(ADDR(.data) - LOAD_OFFSET) {
+		_sdata  =  .;
 		INIT_TASK_DATA(PAGE_SIZE)
 		CACHELINE_ALIGNED_DATA(SMP_CACHE_BYTES)
 		READ_MOSTLY_DATA(SMP_CACHE_BYTES)
diff -druN linux-2.6.39-libre/arch/ia64/kvm/vti.h linux-3.0-rc7-libre/arch/ia64/kvm/vti.h
--- linux-2.6.39-libre/arch/ia64/kvm/vti.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/ia64/kvm/vti.h	2011-07-11 19:51:52.000000000 -0400
@@ -83,13 +83,13 @@
 union vac {
 	unsigned long value;
 	struct {
-		int a_int:1;
-		int a_from_int_cr:1;
-		int a_to_int_cr:1;
-		int a_from_psr:1;
-		int a_from_cpuid:1;
-		int a_cover:1;
-		int a_bsw:1;
+		unsigned int a_int:1;
+		unsigned int a_from_int_cr:1;
+		unsigned int a_to_int_cr:1;
+		unsigned int a_from_psr:1;
+		unsigned int a_from_cpuid:1;
+		unsigned int a_cover:1;
+		unsigned int a_bsw:1;
 		long reserved:57;
 	};
 };
@@ -97,12 +97,12 @@
 union vdc {
 	unsigned long value;
 	struct {
-		int d_vmsw:1;
-		int d_extint:1;
-		int d_ibr_dbr:1;
-		int d_pmc:1;
-		int d_to_pmd:1;
-		int d_itm:1;
+		unsigned int d_vmsw:1;
+		unsigned int d_extint:1;
+		unsigned int d_ibr_dbr:1;
+		unsigned int d_pmc:1;
+		unsigned int d_to_pmd:1;
+		unsigned int d_itm:1;
 		long reserved:58;
 	};
 };
diff -druN linux-2.6.39-libre/arch/ia64/mm/contig.c linux-3.0-rc7-libre/arch/ia64/mm/contig.c
--- linux-2.6.39-libre/arch/ia64/mm/contig.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/ia64/mm/contig.c	2011-07-11 19:51:52.000000000 -0400
@@ -44,13 +44,16 @@
 	pg_data_t *pgdat;
 
 	printk(KERN_INFO "Mem-info:\n");
-	show_free_areas();
+	show_free_areas(filter);
 	printk(KERN_INFO "Node memory in pages:\n");
 	for_each_online_pgdat(pgdat) {
 		unsigned long present;
 		unsigned long flags;
 		int shared = 0, cached = 0, reserved = 0;
+		int nid = pgdat->node_id;
 
+		if (skip_free_areas_node(filter, nid))
+			continue;
 		pgdat_resize_lock(pgdat, &flags);
 		present = pgdat->node_present_pages;
 		for(i = 0; i < pgdat->node_spanned_pages; i++) {
@@ -64,8 +67,7 @@
 				if (max_gap < LARGE_GAP)
 					continue;
 #endif
-				i = vmemmap_find_next_valid_pfn(pgdat->node_id,
-					 i) - 1;
+				i = vmemmap_find_next_valid_pfn(nid, i) - 1;
 				continue;
 			}
 			if (PageReserved(page))
@@ -81,7 +83,7 @@
 		total_cached += cached;
 		total_shared += shared;
 		printk(KERN_INFO "Node %4d:  RAM: %11ld, rsvd: %8d, "
-		       "shrd: %10d, swpd: %10d\n", pgdat->node_id,
+		       "shrd: %10d, swpd: %10d\n", nid,
 		       present, reserved, shared, cached);
 	}
 	printk(KERN_INFO "%ld pages of RAM\n", total_present);
diff -druN linux-2.6.39-libre/arch/ia64/mm/discontig.c linux-3.0-rc7-libre/arch/ia64/mm/discontig.c
--- linux-2.6.39-libre/arch/ia64/mm/discontig.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/ia64/mm/discontig.c	2011-07-11 19:51:52.000000000 -0400
@@ -622,13 +622,16 @@
 	pg_data_t *pgdat;
 
 	printk(KERN_INFO "Mem-info:\n");
-	show_free_areas();
+	show_free_areas(filter);
 	printk(KERN_INFO "Node memory in pages:\n");
 	for_each_online_pgdat(pgdat) {
 		unsigned long present;
 		unsigned long flags;
 		int shared = 0, cached = 0, reserved = 0;
+		int nid = pgdat->node_id;
 
+		if (skip_free_areas_node(filter, nid))
+			continue;
 		pgdat_resize_lock(pgdat, &flags);
 		present = pgdat->node_present_pages;
 		for(i = 0; i < pgdat->node_spanned_pages; i++) {
@@ -638,8 +641,7 @@
 			if (pfn_valid(pgdat->node_start_pfn + i))
 				page = pfn_to_page(pgdat->node_start_pfn + i);
 			else {
-				i = vmemmap_find_next_valid_pfn(pgdat->node_id,
-					 i) - 1;
+				i = vmemmap_find_next_valid_pfn(nid, i) - 1;
 				continue;
 			}
 			if (PageReserved(page))
@@ -655,7 +657,7 @@
 		total_cached += cached;
 		total_shared += shared;
 		printk(KERN_INFO "Node %4d:  RAM: %11ld, rsvd: %8d, "
-		       "shrd: %10d, swpd: %10d\n", pgdat->node_id,
+		       "shrd: %10d, swpd: %10d\n", nid,
 		       present, reserved, shared, cached);
 	}
 	printk(KERN_INFO "%ld pages of RAM\n", total_present);
diff -druN linux-2.6.39-libre/arch/ia64/mm/fault.c linux-3.0-rc7-libre/arch/ia64/mm/fault.c
--- linux-2.6.39-libre/arch/ia64/mm/fault.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/ia64/mm/fault.c	2011-07-11 19:51:52.000000000 -0400
@@ -10,6 +10,7 @@
 #include <linux/interrupt.h>
 #include <linux/kprobes.h>
 #include <linux/kdebug.h>
+#include <linux/prefetch.h>
 
 #include <asm/pgtable.h>
 #include <asm/processor.h>
diff -druN linux-2.6.39-libre/arch/ia64/mm/init.c linux-3.0-rc7-libre/arch/ia64/mm/init.c
--- linux-2.6.39-libre/arch/ia64/mm/init.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/ia64/mm/init.c	2011-07-11 19:51:52.000000000 -0400
@@ -36,8 +36,6 @@
 #include <asm/mca.h>
 #include <asm/paravirt.h>
 
-DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
-
 extern void ia64_tlb_init (void);
 
 unsigned long MAX_DMA_ADDRESS = PAGE_OFFSET + 0x100000000UL;
diff -druN linux-2.6.39-libre/arch/ia64/oprofile/backtrace.c linux-3.0-rc7-libre/arch/ia64/oprofile/backtrace.c
--- linux-2.6.39-libre/arch/ia64/oprofile/backtrace.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/ia64/oprofile/backtrace.c	2011-07-11 19:51:52.000000000 -0400
@@ -29,7 +29,7 @@
 	unsigned int depth;
 	struct pt_regs *regs;
 	struct unw_frame_info frame;
-	u64 *prev_pfs_loc;	/* state for WAR for old spinlock ool code */
+	unsigned long *prev_pfs_loc;	/* state for WAR for old spinlock ool code */
 } ia64_backtrace_t;
 
 /* Returns non-zero if the PC is in the Interrupt Vector Table */
diff -druN linux-2.6.39-libre/arch/ia64/sn/kernel/sn2/timer.c linux-3.0-rc7-libre/arch/ia64/sn/kernel/sn2/timer.c
--- linux-2.6.39-libre/arch/ia64/sn/kernel/sn2/timer.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/ia64/sn/kernel/sn2/timer.c	2011-07-11 19:51:52.000000000 -0400
@@ -33,8 +33,6 @@
         .rating         = 450,
         .read           = read_sn2,
         .mask           = (1LL << 55) - 1,
-        .mult           = 0,
-        .shift          = 10,
         .flags          = CLOCK_SOURCE_IS_CONTINUOUS,
 };
 
@@ -57,9 +55,7 @@
 void __init sn_timer_init(void)
 {
 	clocksource_sn2.fsys_mmio = RTC_COUNTER_ADDR;
-	clocksource_sn2.mult = clocksource_hz2mult(sn_rtc_cycles_per_second,
-							clocksource_sn2.shift);
-	clocksource_register(&clocksource_sn2);
+	clocksource_register_hz(&clocksource_sn2, sn_rtc_cycles_per_second);
 
 	ia64_udelay = &ia64_sn_udelay;
 }
diff -druN linux-2.6.39-libre/arch/ia64/xen/irq_xen.c linux-3.0-rc7-libre/arch/ia64/xen/irq_xen.c
--- linux-2.6.39-libre/arch/ia64/xen/irq_xen.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/ia64/xen/irq_xen.c	2011-07-11 19:51:52.000000000 -0400
@@ -92,6 +92,8 @@
 static int xen_slab_ready;
 
 #ifdef CONFIG_SMP
+#include <linux/sched.h>
+
 /* Dummy stub. Though we may check XEN_RESCHEDULE_VECTOR before __do_IRQ,
  * it ends up to issue several memory accesses upon percpu data and
  * thus adds unnecessary traffic to other paths.
@@ -99,7 +101,13 @@
 static irqreturn_t
 xen_dummy_handler(int irq, void *dev_id)
 {
+	return IRQ_HANDLED;
+}
 
+static irqreturn_t
+xen_resched_handler(int irq, void *dev_id)
+{
+	scheduler_ipi();
 	return IRQ_HANDLED;
 }
 
@@ -110,7 +118,7 @@
 };
 
 static struct irqaction xen_resched_irqaction = {
-	.handler =	xen_dummy_handler,
+	.handler =	xen_resched_handler,
 	.flags =	IRQF_DISABLED,
 	.name =		"resched"
 };
diff -druN linux-2.6.39-libre/arch/Kconfig linux-3.0-rc7-libre/arch/Kconfig
--- linux-2.6.39-libre/arch/Kconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/Kconfig	2011-07-11 19:51:52.000000000 -0400
@@ -144,9 +144,6 @@
 config HAVE_DMA_API_DEBUG
 	bool
 
-config HAVE_DEFAULT_NO_SPIN_MUTEXES
-	bool
-
 config HAVE_HW_BREAKPOINT
 	bool
 	depends on PERF_EVENTS
@@ -178,4 +175,7 @@
 config HAVE_ARCH_MUTEX_CPU_RELAX
 	bool
 
+config HAVE_RCU_TABLE_FREE
+	bool
+
 source "kernel/gcov/Kconfig"
diff -druN linux-2.6.39-libre/arch/m32r/include/asm/mmzone.h linux-3.0-rc7-libre/arch/m32r/include/asm/mmzone.h
--- linux-2.6.39-libre/arch/m32r/include/asm/mmzone.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/m32r/include/asm/mmzone.h	2011-07-11 19:51:52.000000000 -0400
@@ -14,12 +14,6 @@
 #define NODE_DATA(nid)		(node_data[nid])
 
 #define node_localnr(pfn, nid)	((pfn) - NODE_DATA(nid)->node_start_pfn)
-#define node_start_pfn(nid)	(NODE_DATA(nid)->node_start_pfn)
-#define node_end_pfn(nid)						\
-({									\
-	pg_data_t *__pgdat = NODE_DATA(nid);				\
-	__pgdat->node_start_pfn + __pgdat->node_spanned_pages - 1;	\
-})
 
 #define pmd_page(pmd)		(pfn_to_page(pmd_val(pmd) >> PAGE_SHIFT))
 /*
@@ -44,7 +38,7 @@
 	int node;
 
 	for (node = 0 ; node < MAX_NUMNODES ; node++)
-		if (pfn >= node_start_pfn(node) && pfn <= node_end_pfn(node))
+		if (pfn >= node_start_pfn(node) && pfn < node_end_pfn(node))
 			break;
 
 	return node;
diff -druN linux-2.6.39-libre/arch/m32r/include/asm/smp.h linux-3.0-rc7-libre/arch/m32r/include/asm/smp.h
--- linux-2.6.39-libre/arch/m32r/include/asm/smp.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/m32r/include/asm/smp.h	2011-07-11 19:51:52.000000000 -0400
@@ -81,11 +81,11 @@
 
 static __inline__ unsigned int num_booting_cpus(void)
 {
-	return cpus_weight(cpu_callout_map);
+	return cpumask_weight(&cpu_callout_map);
 }
 
 extern void smp_send_timer(void);
-extern unsigned long send_IPI_mask_phys(cpumask_t, int, int);
+extern unsigned long send_IPI_mask_phys(const cpumask_t*, int, int);
 
 extern void arch_send_call_function_single_ipi(int cpu);
 extern void arch_send_call_function_ipi_mask(const struct cpumask *mask);
@@ -94,8 +94,6 @@
 
 #define NO_PROC_ID (0xff)	/* No processor magic marker */
 
-#define PROC_CHANGE_PENALTY	(15)	/* Schedule penalty */
-
 /*
  * M32R-mp IPI
  */
diff -druN linux-2.6.39-libre/arch/m32r/include/asm/unistd.h linux-3.0-rc7-libre/arch/m32r/include/asm/unistd.h
--- linux-2.6.39-libre/arch/m32r/include/asm/unistd.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/m32r/include/asm/unistd.h	2011-07-11 19:51:52.000000000 -0400
@@ -330,10 +330,11 @@
 /* #define __NR_timerfd		322 removed */
 #define __NR_eventfd		323
 #define __NR_fallocate		324
+#define __NR_setns		325
 
 #ifdef __KERNEL__
 
-#define NR_syscalls 325
+#define NR_syscalls 326
 
 #define __ARCH_WANT_IPC_PARSE_VERSION
 #define __ARCH_WANT_STAT64
diff -druN linux-2.6.39-libre/arch/m32r/Kconfig linux-3.0-rc7-libre/arch/m32r/Kconfig
--- linux-2.6.39-libre/arch/m32r/Kconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/m32r/Kconfig	2011-07-11 19:51:52.000000000 -0400
@@ -256,14 +256,6 @@
 	bool
 	default n
 
-config GENERIC_FIND_NEXT_BIT
-	bool
-	default y
-
-config GENERIC_FIND_BIT_LE
-	bool
-	default y
-
 config GENERIC_HWEIGHT
 	bool
 	default y
diff -druN linux-2.6.39-libre/arch/m32r/Kconfig.debug linux-3.0-rc7-libre/arch/m32r/Kconfig.debug
--- linux-2.6.39-libre/arch/m32r/Kconfig.debug	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/m32r/Kconfig.debug	2011-07-11 19:51:52.000000000 -0400
@@ -9,15 +9,6 @@
 	  This option will cause messages to be printed if free stack space
 	  drops below a certain limit.
 
-config DEBUG_STACK_USAGE
-	bool "Stack utilization instrumentation"
-	depends on DEBUG_KERNEL
-	help
-	  Enables the display of the minimum amount of free stack which each
-	  task has ever had available in the sysrq-T and sysrq-P debug output.
-
-	  This option will slow down process creation somewhat.
-
 config DEBUG_PAGEALLOC
 	bool "Debug page memory allocations"
 	depends on DEBUG_KERNEL && BROKEN
diff -druN linux-2.6.39-libre/arch/m32r/kernel/smpboot.c linux-3.0-rc7-libre/arch/m32r/kernel/smpboot.c
--- linux-2.6.39-libre/arch/m32r/kernel/smpboot.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/m32r/kernel/smpboot.c	2011-07-11 19:51:52.000000000 -0400
@@ -135,9 +135,9 @@
 {
 	bsp_phys_id = hard_smp_processor_id();
 	physid_set(bsp_phys_id, phys_cpu_present_map);
-	cpu_set(0, cpu_online_map);	/* BSP's cpu_id == 0 */
-	cpu_set(0, cpu_callout_map);
-	cpu_set(0, cpu_callin_map);
+	set_cpu_online(0, true);	/* BSP's cpu_id == 0 */
+	cpumask_set_cpu(0, &cpu_callout_map);
+	cpumask_set_cpu(0, &cpu_callin_map);
 
 	/*
 	 * Initialize the logical to physical CPU number mapping
@@ -178,7 +178,7 @@
 	for (phys_id = 0 ; phys_id < nr_cpu ; phys_id++)
 		physid_set(phys_id, phys_cpu_present_map);
 #ifndef CONFIG_HOTPLUG_CPU
-	init_cpu_present(&cpu_possible_map);
+	init_cpu_present(cpu_possible_mask);
 #endif
 
 	show_mp_info(nr_cpu);
@@ -294,10 +294,10 @@
 	send_status = 0;
 	boot_status = 0;
 
-	cpu_set(phys_id, cpu_bootout_map);
+	cpumask_set_cpu(phys_id, &cpu_bootout_map);
 
 	/* Send Startup IPI */
-	send_IPI_mask_phys(cpumask_of_cpu(phys_id), CPU_BOOT_IPI, 0);
+	send_IPI_mask_phys(cpumask_of(phys_id), CPU_BOOT_IPI, 0);
 
 	Dprintk("Waiting for send to finish...\n");
 	timeout = 0;
@@ -306,7 +306,7 @@
 	do {
 		Dprintk("+");
 		udelay(1000);
-		send_status = !cpu_isset(phys_id, cpu_bootin_map);
+		send_status = !cpumask_test_cpu(phys_id, &cpu_bootin_map);
 	} while (send_status && (timeout++ < 100));
 
 	Dprintk("After Startup.\n");
@@ -316,19 +316,19 @@
 		 * allow APs to start initializing.
 		 */
 		Dprintk("Before Callout %d.\n", cpu_id);
-		cpu_set(cpu_id, cpu_callout_map);
+		cpumask_set_cpu(cpu_id, &cpu_callout_map);
 		Dprintk("After Callout %d.\n", cpu_id);
 
 		/*
 		 * Wait 5s total for a response
 		 */
 		for (timeout = 0; timeout < 5000; timeout++) {
-			if (cpu_isset(cpu_id, cpu_callin_map))
+			if (cpumask_test_cpu(cpu_id, &cpu_callin_map))
 				break;	/* It has booted */
 			udelay(1000);
 		}
 
-		if (cpu_isset(cpu_id, cpu_callin_map)) {
+		if (cpumask_test_cpu(cpu_id, &cpu_callin_map)) {
 			/* number CPUs logically, starting from 1 (BSP is 0) */
 			Dprintk("OK.\n");
 		} else {
@@ -340,9 +340,9 @@
 
 	if (send_status || boot_status) {
 		unmap_cpu_to_physid(cpu_id, phys_id);
-		cpu_clear(cpu_id, cpu_callout_map);
-		cpu_clear(cpu_id, cpu_callin_map);
-		cpu_clear(cpu_id, cpu_initialized);
+		cpumask_clear_cpu(cpu_id, &cpu_callout_map);
+		cpumask_clear_cpu(cpu_id, &cpu_callin_map);
+		cpumask_clear_cpu(cpu_id, &cpu_initialized);
 		cpucount--;
 	}
 }
@@ -351,17 +351,17 @@
 {
 	int timeout;
 
-	cpu_set(cpu_id, smp_commenced_mask);
+	cpumask_set_cpu(cpu_id, &smp_commenced_mask);
 
 	/*
 	 * Wait 5s total for a response
 	 */
 	for (timeout = 0; timeout < 5000; timeout++) {
-		if (cpu_isset(cpu_id, cpu_online_map))
+		if (cpu_online(cpu_id))
 			break;
 		udelay(1000);
 	}
-	if (!cpu_isset(cpu_id, cpu_online_map))
+	if (!cpu_online(cpu_id))
 		BUG();
 
 	return 0;
@@ -373,11 +373,11 @@
 	unsigned long bogosum = 0;
 
 	for (timeout = 0; timeout < 5000; timeout++) {
-		if (cpus_equal(cpu_callin_map, cpu_online_map))
+		if (cpumask_equal(&cpu_callin_map, cpu_online_mask))
 			break;
 		udelay(1000);
 	}
-	if (!cpus_equal(cpu_callin_map, cpu_online_map))
+	if (!cpumask_equal(&cpu_callin_map, cpu_online_mask))
 		BUG();
 
 	for (cpu_id = 0 ; cpu_id < num_online_cpus() ; cpu_id++)
@@ -388,7 +388,7 @@
 	 */
 	Dprintk("Before bogomips.\n");
 	if (cpucount) {
-		for_each_cpu_mask(cpu_id, cpu_online_map)
+		for_each_cpu(cpu_id,cpu_online_mask)
 			bogosum += cpu_data[cpu_id].loops_per_jiffy;
 
 		printk(KERN_INFO "Total of %d processors activated " \
@@ -425,7 +425,7 @@
 	cpu_init();
 	preempt_disable();
 	smp_callin();
-	while (!cpu_isset(smp_processor_id(), smp_commenced_mask))
+	while (!cpumask_test_cpu(smp_processor_id(), &smp_commenced_mask))
 		cpu_relax();
 
 	smp_online();
@@ -463,7 +463,7 @@
 	int cpu_id = smp_processor_id();
 	unsigned long timeout;
 
-	if (cpu_isset(cpu_id, cpu_callin_map)) {
+	if (cpumask_test_cpu(cpu_id, &cpu_callin_map)) {
 		printk("huh, phys CPU#%d, CPU#%d already present??\n",
 			phys_id, cpu_id);
 		BUG();
@@ -474,7 +474,7 @@
 	timeout = jiffies + (2 * HZ);
 	while (time_before(jiffies, timeout)) {
 		/* Has the boot CPU finished it's STARTUP sequence ? */
-		if (cpu_isset(cpu_id, cpu_callout_map))
+		if (cpumask_test_cpu(cpu_id, &cpu_callout_map))
 			break;
 		cpu_relax();
 	}
@@ -486,7 +486,7 @@
 	}
 
 	/* Allow the master to continue. */
-	cpu_set(cpu_id, cpu_callin_map);
+	cpumask_set_cpu(cpu_id, &cpu_callin_map);
 }
 
 static void __init smp_online(void)
@@ -503,7 +503,7 @@
 	/* Save our processor parameters */
  	smp_store_cpu_info(cpu_id);
 
-	cpu_set(cpu_id, cpu_online_map);
+	set_cpu_online(cpu_id, true);
 }
 
 /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
diff -druN linux-2.6.39-libre/arch/m32r/kernel/smp.c linux-3.0-rc7-libre/arch/m32r/kernel/smp.c
--- linux-2.6.39-libre/arch/m32r/kernel/smp.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/m32r/kernel/smp.c	2011-07-11 19:51:52.000000000 -0400
@@ -30,6 +30,7 @@
 #include <asm/io.h>
 #include <asm/mmu_context.h>
 #include <asm/m32r.h>
+#include <asm/tlbflush.h>
 
 /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
 /* Data structures and variables                                             */
@@ -61,33 +62,22 @@
 /* Function Prototypes                                                       */
 /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
 
-void smp_send_reschedule(int);
 void smp_reschedule_interrupt(void);
-
-void smp_flush_cache_all(void);
 void smp_flush_cache_all_interrupt(void);
 
-void smp_flush_tlb_all(void);
 static void flush_tlb_all_ipi(void *);
-
-void smp_flush_tlb_mm(struct mm_struct *);
-void smp_flush_tlb_range(struct vm_area_struct *, unsigned long, \
-	unsigned long);
-void smp_flush_tlb_page(struct vm_area_struct *, unsigned long);
 static void flush_tlb_others(cpumask_t, struct mm_struct *,
 	struct vm_area_struct *, unsigned long);
+
 void smp_invalidate_interrupt(void);
 
-void smp_send_stop(void);
 static void stop_this_cpu(void *);
 
-void smp_send_timer(void);
 void smp_ipi_timer_interrupt(struct pt_regs *);
 void smp_local_timer_interrupt(void);
 
 static void send_IPI_allbutself(int, int);
 static void send_IPI_mask(const struct cpumask *, int, int);
-unsigned long send_IPI_mask_phys(cpumask_t, int, int);
 
 /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
 /* Rescheduling request Routines                                             */
@@ -122,8 +112,6 @@
  *
  * Description:  This routine executes on CPU which received
  *               'RESCHEDULE_IPI'.
- *               Rescheduling is processed at the exit of interrupt
- *               operation.
  *
  * Born on Date: 2002.02.05
  *
@@ -138,7 +126,7 @@
  *==========================================================================*/
 void smp_reschedule_interrupt(void)
 {
-	/* nothing to do */
+	scheduler_ipi();
 }
 
 /*==========================================================================*
@@ -164,10 +152,10 @@
 	unsigned long *mask;
 
 	preempt_disable();
-	cpumask = cpu_online_map;
-	cpu_clear(smp_processor_id(), cpumask);
+	cpumask_copy(&cpumask, cpu_online_mask);
+	cpumask_clear_cpu(smp_processor_id(), &cpumask);
 	spin_lock(&flushcache_lock);
-	mask=cpus_addr(cpumask);
+	mask=cpumask_bits(&cpumask);
 	atomic_set_mask(*mask, (atomic_t *)&flushcache_cpumask);
 	send_IPI_mask(&cpumask, INVALIDATE_CACHE_IPI, 0);
 	_flush_cache_copyback_all();
@@ -265,8 +253,8 @@
 	preempt_disable();
 	cpu_id = smp_processor_id();
 	mmc = &mm->context[cpu_id];
-	cpu_mask = *mm_cpumask(mm);
-	cpu_clear(cpu_id, cpu_mask);
+	cpumask_copy(&cpu_mask, mm_cpumask(mm));
+	cpumask_clear_cpu(cpu_id, &cpu_mask);
 
 	if (*mmc != NO_CONTEXT) {
 		local_irq_save(flags);
@@ -277,7 +265,7 @@
 			cpumask_clear_cpu(cpu_id, mm_cpumask(mm));
 		local_irq_restore(flags);
 	}
-	if (!cpus_empty(cpu_mask))
+	if (!cpumask_empty(&cpu_mask))
 		flush_tlb_others(cpu_mask, mm, NULL, FLUSH_ALL);
 
 	preempt_enable();
@@ -335,8 +323,8 @@
 	preempt_disable();
 	cpu_id = smp_processor_id();
 	mmc = &mm->context[cpu_id];
-	cpu_mask = *mm_cpumask(mm);
-	cpu_clear(cpu_id, cpu_mask);
+	cpumask_copy(&cpu_mask, mm_cpumask(mm));
+	cpumask_clear_cpu(cpu_id, &cpu_mask);
 
 #ifdef DEBUG_SMP
 	if (!mm)
@@ -350,7 +338,7 @@
 		__flush_tlb_page(va);
 		local_irq_restore(flags);
 	}
-	if (!cpus_empty(cpu_mask))
+	if (!cpumask_empty(&cpu_mask))
 		flush_tlb_others(cpu_mask, mm, vma, va);
 
 	preempt_enable();
@@ -397,14 +385,14 @@
 	 * - current CPU must not be in mask
 	 * - mask must exist :)
 	 */
-	BUG_ON(cpus_empty(cpumask));
+	BUG_ON(cpumask_empty(&cpumask));
 
-	BUG_ON(cpu_isset(smp_processor_id(), cpumask));
+	BUG_ON(cpumask_test_cpu(smp_processor_id(), &cpumask));
 	BUG_ON(!mm);
 
 	/* If a CPU which we ran on has gone down, OK. */
-	cpus_and(cpumask, cpumask, cpu_online_map);
-	if (cpus_empty(cpumask))
+	cpumask_and(&cpumask, &cpumask, cpu_online_mask);
+	if (cpumask_empty(&cpumask))
 		return;
 
 	/*
@@ -418,7 +406,7 @@
 	flush_mm = mm;
 	flush_vma = vma;
 	flush_va = va;
-	mask=cpus_addr(cpumask);
+	mask=cpumask_bits(&cpumask);
 	atomic_set_mask(*mask, (atomic_t *)&flush_cpumask);
 
 	/*
@@ -427,7 +415,7 @@
 	 */
 	send_IPI_mask(&cpumask, INVALIDATE_TLB_IPI, 0);
 
-	while (!cpus_empty(flush_cpumask)) {
+	while (!cpumask_empty((cpumask_t*)&flush_cpumask)) {
 		/* nothing. lockup detection does not belong here */
 		mb();
 	}
@@ -462,7 +450,7 @@
 	int cpu_id = smp_processor_id();
 	unsigned long *mmc = &flush_mm->context[cpu_id];
 
-	if (!cpu_isset(cpu_id, flush_cpumask))
+	if (!cpumask_test_cpu(cpu_id, &flush_cpumask))
 		return;
 
 	if (flush_va == FLUSH_ALL) {
@@ -480,7 +468,7 @@
 			__flush_tlb_page(va);
 		}
 	}
-	cpu_clear(cpu_id, flush_cpumask);
+	cpumask_clear_cpu(cpu_id, (cpumask_t*)&flush_cpumask);
 }
 
 /*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
@@ -532,7 +520,7 @@
 	/*
 	 * Remove this CPU:
 	 */
-	cpu_clear(cpu_id, cpu_online_map);
+	set_cpu_online(cpu_id, false);
 
 	/*
 	 * PSW IE = 1;
@@ -727,8 +715,8 @@
 {
 	cpumask_t cpumask;
 
-	cpumask = cpu_online_map;
-	cpu_clear(smp_processor_id(), cpumask);
+	cpumask_copy(&cpumask, cpu_online_mask);
+	cpumask_clear_cpu(smp_processor_id(), &cpumask);
 
 	send_IPI_mask(&cpumask, ipi_num, try);
 }
@@ -765,13 +753,13 @@
 	cpumask_and(&tmp, cpumask, cpu_online_mask);
 	BUG_ON(!cpumask_equal(cpumask, &tmp));
 
-	physid_mask = CPU_MASK_NONE;
+	cpumask_clear(&physid_mask);
 	for_each_cpu(cpu_id, cpumask) {
 		if ((phys_id = cpu_to_physid(cpu_id)) != -1)
-			cpu_set(phys_id, physid_mask);
+			cpumask_set_cpu(phys_id, &physid_mask);
 	}
 
-	send_IPI_mask_phys(physid_mask, ipi_num, try);
+	send_IPI_mask_phys(&physid_mask, ipi_num, try);
 }
 
 /*==========================================================================*
@@ -794,14 +782,14 @@
  * ---------- --- --------------------------------------------------------
  *
  *==========================================================================*/
-unsigned long send_IPI_mask_phys(cpumask_t physid_mask, int ipi_num,
+unsigned long send_IPI_mask_phys(const cpumask_t *physid_mask, int ipi_num,
 	int try)
 {
 	spinlock_t *ipilock;
 	volatile unsigned long *ipicr_addr;
 	unsigned long ipicr_val;
 	unsigned long my_physid_mask;
-	unsigned long mask = cpus_addr(physid_mask)[0];
+	unsigned long mask = cpumask_bits(physid_mask)[0];
 
 
 	if (mask & ~physids_coerce(phys_cpu_present_map))
diff -druN linux-2.6.39-libre/arch/m32r/kernel/syscall_table.S linux-3.0-rc7-libre/arch/m32r/kernel/syscall_table.S
--- linux-2.6.39-libre/arch/m32r/kernel/syscall_table.S	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/m32r/kernel/syscall_table.S	2011-07-11 19:51:52.000000000 -0400
@@ -324,3 +324,4 @@
 	.long sys_ni_syscall
 	.long sys_eventfd
 	.long sys_fallocate
+	.long sys_setns			/* 325 */
diff -druN linux-2.6.39-libre/arch/m32r/kernel/vmlinux.lds.S linux-3.0-rc7-libre/arch/m32r/kernel/vmlinux.lds.S
--- linux-2.6.39-libre/arch/m32r/kernel/vmlinux.lds.S	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/m32r/kernel/vmlinux.lds.S	2011-07-11 19:51:52.000000000 -0400
@@ -44,6 +44,7 @@
   EXCEPTION_TABLE(16)
   NOTES
 
+  _sdata = .;			/* Start of data section */
   RODATA
   RW_DATA_SECTION(32, PAGE_SIZE, THREAD_SIZE)
   _edata = .;			/* End of data section */
@@ -53,7 +54,7 @@
   __init_begin = .;
   INIT_TEXT_SECTION(PAGE_SIZE)
   INIT_DATA_SECTION(16)
-  PERCPU(32, PAGE_SIZE)
+  PERCPU_SECTION(32)
   . = ALIGN(PAGE_SIZE);
   __init_end = .;
   /* freed after init ends here */
diff -druN linux-2.6.39-libre/arch/m32r/mm/discontig.c linux-3.0-rc7-libre/arch/m32r/mm/discontig.c
--- linux-2.6.39-libre/arch/m32r/mm/discontig.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/m32r/mm/discontig.c	2011-07-11 19:51:52.000000000 -0400
@@ -149,6 +149,7 @@
 		zholes_size[ZONE_DMA] = mp->holes;
 		holes += zholes_size[ZONE_DMA];
 
+		node_set_state(nid, N_NORMAL_MEMORY);
 		free_area_init_node(nid, zones_size, start_pfn, zholes_size);
 	}
 
diff -druN linux-2.6.39-libre/arch/m32r/mm/init.c linux-3.0-rc7-libre/arch/m32r/mm/init.c
--- linux-2.6.39-libre/arch/m32r/mm/init.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/m32r/mm/init.c	2011-07-11 19:51:52.000000000 -0400
@@ -35,8 +35,6 @@
 
 pgd_t swapper_pg_dir[1024];
 
-DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
-
 /*
  * Cache of MMU context last used.
  */
diff -druN linux-2.6.39-libre/arch/m68k/atari/atakeyb.c linux-3.0-rc7-libre/arch/m68k/atari/atakeyb.c
--- linux-2.6.39-libre/arch/m68k/atari/atakeyb.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/m68k/atari/atakeyb.c	2011-07-11 19:51:52.000000000 -0400
@@ -36,13 +36,10 @@
 
 /* Hook for MIDI serial driver */
 void (*atari_MIDI_interrupt_hook) (void);
-/* Hook for mouse driver */
-void (*atari_mouse_interrupt_hook) (char *);
 /* Hook for keyboard inputdev  driver */
 void (*atari_input_keyboard_interrupt_hook) (unsigned char, char);
 /* Hook for mouse inputdev  driver */
 void (*atari_input_mouse_interrupt_hook) (char *);
-EXPORT_SYMBOL(atari_mouse_interrupt_hook);
 EXPORT_SYMBOL(atari_input_keyboard_interrupt_hook);
 EXPORT_SYMBOL(atari_input_mouse_interrupt_hook);
 
@@ -263,8 +260,8 @@
 			kb_state.buf[kb_state.len++] = scancode;
 			if (kb_state.len == 3) {
 				kb_state.state = KEYBOARD;
-				if (atari_mouse_interrupt_hook)
-					atari_mouse_interrupt_hook(kb_state.buf);
+				if (atari_input_mouse_interrupt_hook)
+					atari_input_mouse_interrupt_hook(kb_state.buf);
 			}
 			break;
 
@@ -575,7 +572,7 @@
 	kb_state.len = 0;
 
 	error = request_irq(IRQ_MFP_ACIA, atari_keyboard_interrupt,
-			    IRQ_TYPE_SLOW, "keyboard/mouse/MIDI",
+			    IRQ_TYPE_SLOW, "keyboard,mouse,MIDI",
 			    atari_keyboard_interrupt);
 	if (error)
 		return error;
diff -druN linux-2.6.39-libre/arch/m68k/atari/stdma.c linux-3.0-rc7-libre/arch/m68k/atari/stdma.c
--- linux-2.6.39-libre/arch/m68k/atari/stdma.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/m68k/atari/stdma.c	2011-07-11 19:51:52.000000000 -0400
@@ -180,7 +180,7 @@
 {
 	stdma_isr = NULL;
 	if (request_irq(IRQ_MFP_FDC, stdma_int, IRQ_TYPE_SLOW | IRQF_SHARED,
-			"ST-DMA: floppy/ACSI/IDE/Falcon-SCSI", stdma_int))
+			"ST-DMA floppy,ACSI,IDE,Falcon-SCSI", stdma_int))
 		pr_err("Couldn't register ST-DMA interrupt\n");
 }
 
diff -druN linux-2.6.39-libre/arch/m68k/include/asm/atarikb.h linux-3.0-rc7-libre/arch/m68k/include/asm/atarikb.h
--- linux-2.6.39-libre/arch/m68k/include/asm/atarikb.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/m68k/include/asm/atarikb.h	2011-07-11 19:51:52.000000000 -0400
@@ -34,8 +34,6 @@
 
 /* Hook for MIDI serial driver */
 extern void (*atari_MIDI_interrupt_hook) (void);
-/* Hook for mouse driver */
-extern void (*atari_mouse_interrupt_hook) (char *);
 /* Hook for keyboard inputdev  driver */
 extern void (*atari_input_keyboard_interrupt_hook) (unsigned char, char);
 /* Hook for mouse inputdev  driver */
diff -druN linux-2.6.39-libre/arch/m68k/include/asm/bitops_mm.h linux-3.0-rc7-libre/arch/m68k/include/asm/bitops_mm.h
--- linux-2.6.39-libre/arch/m68k/include/asm/bitops_mm.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/m68k/include/asm/bitops_mm.h	2011-07-11 19:51:52.000000000 -0400
@@ -181,14 +181,15 @@
 {
 	const unsigned long *p = vaddr;
 	int res = 32;
+	unsigned int words;
 	unsigned long num;
 
 	if (!size)
 		return 0;
 
-	size = (size + 31) >> 5;
+	words = (size + 31) >> 5;
 	while (!(num = ~*p++)) {
-		if (!--size)
+		if (!--words)
 			goto out;
 	}
 
@@ -196,8 +197,10 @@
 			      : "=d" (res) : "d" (num & -num));
 	res ^= 31;
 out:
-	return ((long)p - (long)vaddr - 4) * 8 + res;
+	res += ((long)p - (long)vaddr - 4) * 8;
+	return res < size ? res : size;
 }
+#define find_first_zero_bit find_first_zero_bit
 
 static inline int find_next_zero_bit(const unsigned long *vaddr, int size,
 				     int offset)
@@ -215,27 +218,33 @@
 		/* Look for zero in first longword */
 		__asm__ __volatile__ ("bfffo %1{#0,#0},%0"
 				      : "=d" (res) : "d" (num & -num));
-		if (res < 32)
-			return offset + (res ^ 31);
+		if (res < 32) {
+			offset += res ^ 31;
+			return offset < size ? offset : size;
+		}
 		offset += 32;
+
+		if (offset >= size)
+			return size;
 	}
 	/* No zero yet, search remaining full bytes for a zero */
-	res = find_first_zero_bit(p, size - ((long)p - (long)vaddr) * 8);
-	return offset + res;
+	return offset + find_first_zero_bit(p, size - offset);
 }
+#define find_next_zero_bit find_next_zero_bit
 
 static inline int find_first_bit(const unsigned long *vaddr, unsigned size)
 {
 	const unsigned long *p = vaddr;
 	int res = 32;
+	unsigned int words;
 	unsigned long num;
 
 	if (!size)
 		return 0;
 
-	size = (size + 31) >> 5;
+	words = (size + 31) >> 5;
 	while (!(num = *p++)) {
-		if (!--size)
+		if (!--words)
 			goto out;
 	}
 
@@ -243,8 +252,10 @@
 			      : "=d" (res) : "d" (num & -num));
 	res ^= 31;
 out:
-	return ((long)p - (long)vaddr - 4) * 8 + res;
+	res += ((long)p - (long)vaddr - 4) * 8;
+	return res < size ? res : size;
 }
+#define find_first_bit find_first_bit
 
 static inline int find_next_bit(const unsigned long *vaddr, int size,
 				int offset)
@@ -262,14 +273,19 @@
 		/* Look for one in first longword */
 		__asm__ __volatile__ ("bfffo %1{#0,#0},%0"
 				      : "=d" (res) : "d" (num & -num));
-		if (res < 32)
-			return offset + (res ^ 31);
+		if (res < 32) {
+			offset += res ^ 31;
+			return offset < size ? offset : size;
+		}
 		offset += 32;
+
+		if (offset >= size)
+			return size;
 	}
 	/* No one yet, search remaining full bytes for a one */
-	res = find_first_bit(p, size - ((long)p - (long)vaddr) * 8);
-	return offset + res;
+	return offset + find_first_bit(p, size - offset);
 }
+#define find_next_bit find_next_bit
 
 /*
  * ffz = Find First Zero in word. Undefined if no zero exists,
@@ -366,24 +382,27 @@
 static inline int find_first_zero_bit_le(const void *vaddr, unsigned size)
 {
 	const unsigned long *p = vaddr, *addr = vaddr;
-	int res;
+	int res = 0;
+	unsigned int words;
 
 	if (!size)
 		return 0;
 
-	size = (size >> 5) + ((size & 31) > 0);
-	while (*p++ == ~0UL)
-	{
-		if (--size == 0)
-			return (p - addr) << 5;
+	words = (size >> 5) + ((size & 31) > 0);
+	while (*p++ == ~0UL) {
+		if (--words == 0)
+			goto out;
 	}
 
 	--p;
 	for (res = 0; res < 32; res++)
 		if (!test_bit_le(res, p))
 			break;
-	return (p - addr) * 32 + res;
+out:
+	res += (p - addr) * 32;
+	return res < size ? res : size;
 }
+#define find_first_zero_bit_le find_first_zero_bit_le
 
 static inline unsigned long find_next_zero_bit_le(const void *addr,
 		unsigned long size, unsigned long offset)
@@ -400,35 +419,45 @@
 		offset -= bit;
 		/* Look for zero in first longword */
 		for (res = bit; res < 32; res++)
-			if (!test_bit_le(res, p))
-				return offset + res;
+			if (!test_bit_le(res, p)) {
+				offset += res;
+				return offset < size ? offset : size;
+			}
 		p++;
 		offset += 32;
+
+		if (offset >= size)
+			return size;
 	}
 	/* No zero yet, search remaining full bytes for a zero */
 	return offset + find_first_zero_bit_le(p, size - offset);
 }
+#define find_next_zero_bit_le find_next_zero_bit_le
 
 static inline int find_first_bit_le(const void *vaddr, unsigned size)
 {
 	const unsigned long *p = vaddr, *addr = vaddr;
-	int res;
+	int res = 0;
+	unsigned int words;
 
 	if (!size)
 		return 0;
 
-	size = (size >> 5) + ((size & 31) > 0);
+	words = (size >> 5) + ((size & 31) > 0);
 	while (*p++ == 0UL) {
-		if (--size == 0)
-			return (p - addr) << 5;
+		if (--words == 0)
+			goto out;
 	}
 
 	--p;
 	for (res = 0; res < 32; res++)
 		if (test_bit_le(res, p))
 			break;
-	return (p - addr) * 32 + res;
+out:
+	res += (p - addr) * 32;
+	return res < size ? res : size;
 }
+#define find_first_bit_le find_first_bit_le
 
 static inline unsigned long find_next_bit_le(const void *addr,
 		unsigned long size, unsigned long offset)
@@ -445,14 +474,20 @@
 		offset -= bit;
 		/* Look for one in first longword */
 		for (res = bit; res < 32; res++)
-			if (test_bit_le(res, p))
-				return offset + res;
+			if (test_bit_le(res, p)) {
+				offset += res;
+				return offset < size ? offset : size;
+			}
 		p++;
 		offset += 32;
+
+		if (offset >= size)
+			return size;
 	}
 	/* No set bit yet, search remaining full bytes for a set bit */
 	return offset + find_first_bit_le(p, size - offset);
 }
+#define find_next_bit_le find_next_bit_le
 
 /* Bitmap functions for the ext2 filesystem. */
 
diff -druN linux-2.6.39-libre/arch/m68k/include/asm/bitops_no.h linux-3.0-rc7-libre/arch/m68k/include/asm/bitops_no.h
--- linux-2.6.39-libre/arch/m68k/include/asm/bitops_no.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/m68k/include/asm/bitops_no.h	2011-07-11 19:51:52.000000000 -0400
@@ -246,23 +246,7 @@
 	return retval;
 }
 
-#define ext2_set_bit_atomic(lock, nr, addr)		\
-	({						\
-		int ret;				\
-		spin_lock(lock);			\
-		ret = __test_and_set_bit_le((nr), (addr));	\
-		spin_unlock(lock);			\
-		ret;					\
-	})
-
-#define ext2_clear_bit_atomic(lock, nr, addr)		\
-	({						\
-		int ret;				\
-		spin_lock(lock);			\
-		ret = __test_and_clear_bit_le((nr), (addr));	\
-		spin_unlock(lock);			\
-		ret;					\
-	})
+#include <asm-generic/bitops/ext2-atomic.h>
 
 static inline int test_bit_le(int nr, const volatile void *addr)
 {
@@ -335,6 +319,10 @@
 found_middle:
 	return result + ffz(__swab32(tmp));
 }
+#define find_next_zero_bit_le find_next_zero_bit_le
+
+extern unsigned long find_next_bit_le(const void *addr,
+		unsigned long size, unsigned long offset);
 
 #endif /* __KERNEL__ */
 
diff -druN linux-2.6.39-libre/arch/m68k/include/asm/io_no.h linux-3.0-rc7-libre/arch/m68k/include/asm/io_no.h
--- linux-2.6.39-libre/arch/m68k/include/asm/io_no.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/m68k/include/asm/io_no.h	2011-07-11 19:51:52.000000000 -0400
@@ -144,8 +144,10 @@
 #define IOMAP_NOCACHE_NONSER		2
 #define IOMAP_WRITETHROUGH		3
 
-extern void *__ioremap(unsigned long physaddr, unsigned long size, int cacheflag);
-
+static inline void *__ioremap(unsigned long physaddr, unsigned long size, int cacheflag)
+{
+	return (void *) physaddr;
+}
 static inline void *ioremap(unsigned long physaddr, unsigned long size)
 {
 	return __ioremap(physaddr, size, IOMAP_NOCACHE_SER);
@@ -163,7 +165,7 @@
 	return __ioremap(physaddr, size, IOMAP_FULL_CACHING);
 }
 
-extern void iounmap(void *addr);
+#define	iounmap(addr)	do { } while(0)
 
 /*
  * Convert a physical pointer to a virtual kernel pointer for /dev/mem
diff -druN linux-2.6.39-libre/arch/m68k/include/asm/MC68EZ328.h linux-3.0-rc7-libre/arch/m68k/include/asm/MC68EZ328.h
--- linux-2.6.39-libre/arch/m68k/include/asm/MC68EZ328.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/m68k/include/asm/MC68EZ328.h	2011-07-11 19:51:52.000000000 -0400
@@ -1047,7 +1047,7 @@
 
 #define WATCHDOG_EN	0x0001	/* Watchdog Enabled */
 #define WATCHDOG_ISEL	0x0002	/* Select the watchdog interrupt */
-#define WATCHDOG_INTF	0x0080	/* Watchdog interrupt occcured */
+#define WATCHDOG_INTF	0x0080	/* Watchdog interrupt occurred */
 #define WATCHDOG_CNT_MASK  0x0300	/* Watchdog Counter */
 #define WATCHDOG_CNT_SHIFT 8
 
diff -druN linux-2.6.39-libre/arch/m68k/include/asm/MC68VZ328.h linux-3.0-rc7-libre/arch/m68k/include/asm/MC68VZ328.h
--- linux-2.6.39-libre/arch/m68k/include/asm/MC68VZ328.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/m68k/include/asm/MC68VZ328.h	2011-07-11 19:51:52.000000000 -0400
@@ -1143,7 +1143,7 @@
 
 #define WATCHDOG_EN	0x0001	/* Watchdog Enabled */
 #define WATCHDOG_ISEL	0x0002	/* Select the watchdog interrupt */
-#define WATCHDOG_INTF	0x0080	/* Watchdog interrupt occcured */
+#define WATCHDOG_INTF	0x0080	/* Watchdog interrupt occurred */
 #define WATCHDOG_CNT_MASK  0x0300	/* Watchdog Counter */
 #define WATCHDOG_CNT_SHIFT 8
 
diff -druN linux-2.6.39-libre/arch/m68k/include/asm/unistd.h linux-3.0-rc7-libre/arch/m68k/include/asm/unistd.h
--- linux-2.6.39-libre/arch/m68k/include/asm/unistd.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/m68k/include/asm/unistd.h	2011-07-11 19:51:52.000000000 -0400
@@ -22,7 +22,7 @@
 #define __NR_mknod		 14
 #define __NR_chmod		 15
 #define __NR_chown		 16
-#define __NR_break		 17
+/*#define __NR_break		 17*/
 #define __NR_oldstat		 18
 #define __NR_lseek		 19
 #define __NR_getpid		 20
@@ -36,11 +36,11 @@
 #define __NR_oldfstat		 28
 #define __NR_pause		 29
 #define __NR_utime		 30
-#define __NR_stty		 31
-#define __NR_gtty		 32
+/*#define __NR_stty		 31*/
+/*#define __NR_gtty		 32*/
 #define __NR_access		 33
 #define __NR_nice		 34
-#define __NR_ftime		 35
+/*#define __NR_ftime		 35*/
 #define __NR_sync		 36
 #define __NR_kill		 37
 #define __NR_rename		 38
@@ -49,7 +49,7 @@
 #define __NR_dup		 41
 #define __NR_pipe		 42
 #define __NR_times		 43
-#define __NR_prof		 44
+/*#define __NR_prof		 44*/
 #define __NR_brk		 45
 #define __NR_setgid		 46
 #define __NR_getgid		 47
@@ -58,13 +58,13 @@
 #define __NR_getegid		 50
 #define __NR_acct		 51
 #define __NR_umount2		 52
-#define __NR_lock		 53
+/*#define __NR_lock		 53*/
 #define __NR_ioctl		 54
 #define __NR_fcntl		 55
-#define __NR_mpx		 56
+/*#define __NR_mpx		 56*/
 #define __NR_setpgid		 57
-#define __NR_ulimit		 58
-#define __NR_oldolduname	 59
+/*#define __NR_ulimit		 58*/
+/*#define __NR_oldolduname	 59*/
 #define __NR_umask		 60
 #define __NR_chroot		 61
 #define __NR_ustat		 62
@@ -103,10 +103,10 @@
 #define __NR_fchown		 95
 #define __NR_getpriority	 96
 #define __NR_setpriority	 97
-#define __NR_profil		 98
+/*#define __NR_profil		 98*/
 #define __NR_statfs		 99
 #define __NR_fstatfs		100
-#define __NR_ioperm		101
+/*#define __NR_ioperm		101*/
 #define __NR_socketcall		102
 #define __NR_syslog		103
 #define __NR_setitimer		104
@@ -114,11 +114,11 @@
 #define __NR_stat		106
 #define __NR_lstat		107
 #define __NR_fstat		108
-#define __NR_olduname		109
-#define __NR_iopl		/* 110 */ not supported
+/*#define __NR_olduname		109*/
+/*#define __NR_iopl		110*/ /* not supported */
 #define __NR_vhangup		111
-#define __NR_idle		/* 112 */ Obsolete
-#define __NR_vm86		/* 113 */ not supported
+/*#define __NR_idle		112*/ /* Obsolete */
+/*#define __NR_vm86		113*/ /* not supported */
 #define __NR_wait4		114
 #define __NR_swapoff		115
 #define __NR_sysinfo		116
@@ -132,17 +132,17 @@
 #define __NR_adjtimex		124
 #define __NR_mprotect		125
 #define __NR_sigprocmask	126
-#define __NR_create_module	127
+/*#define __NR_create_module	127*/
 #define __NR_init_module	128
 #define __NR_delete_module	129
-#define __NR_get_kernel_syms	130
+/*#define __NR_get_kernel_syms	130*/
 #define __NR_quotactl		131
 #define __NR_getpgid		132
 #define __NR_fchdir		133
 #define __NR_bdflush		134
 #define __NR_sysfs		135
 #define __NR_personality	136
-#define __NR_afs_syscall	137 /* Syscall for Andrew File System */
+/*#define __NR_afs_syscall	137*/ /* Syscall for Andrew File System */
 #define __NR_setfsuid		138
 #define __NR_setfsgid		139
 #define __NR__llseek		140
@@ -172,7 +172,7 @@
 #define __NR_setresuid		164
 #define __NR_getresuid		165
 #define __NR_getpagesize	166
-#define __NR_query_module	167
+/*#define __NR_query_module	167*/
 #define __NR_poll		168
 #define __NR_nfsservctl		169
 #define __NR_setresgid		170
@@ -193,8 +193,8 @@
 #define __NR_capset		185
 #define __NR_sigaltstack	186
 #define __NR_sendfile		187
-#define __NR_getpmsg		188	/* some people actually want streams */
-#define __NR_putpmsg		189	/* some people actually want streams */
+/*#define __NR_getpmsg		188*/	/* some people actually want streams */
+/*#define __NR_putpmsg		189*/	/* some people actually want streams */
 #define __NR_vfork		190
 #define __NR_ugetrlimit		191
 #define __NR_mmap2		192
@@ -223,6 +223,8 @@
 #define __NR_setfsuid32		215
 #define __NR_setfsgid32		216
 #define __NR_pivot_root		217
+/* 218*/
+/* 219*/
 #define __NR_getdents64		220
 #define __NR_gettid		221
 #define __NR_tkill		222
@@ -281,7 +283,7 @@
 #define __NR_mq_notify		275
 #define __NR_mq_getsetattr	276
 #define __NR_waitid		277
-#define __NR_vserver		278
+/*#define __NR_vserver		278*/
 #define __NR_add_key		279
 #define __NR_request_key	280
 #define __NR_keyctl		281
@@ -347,10 +349,11 @@
 #define __NR_open_by_handle_at	341
 #define __NR_clock_adjtime	342
 #define __NR_syncfs		343
+#define __NR_setns		344
 
 #ifdef __KERNEL__
 
-#define NR_syscalls		344
+#define NR_syscalls		345
 
 #define __ARCH_WANT_IPC_PARSE_VERSION
 #define __ARCH_WANT_OLD_READDIR
diff -druN linux-2.6.39-libre/arch/m68k/Kconfig linux-3.0-rc7-libre/arch/m68k/Kconfig
--- linux-2.6.39-libre/arch/m68k/Kconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/m68k/Kconfig	2011-07-11 19:51:52.000000000 -0400
@@ -5,6 +5,7 @@
 	select HAVE_AOUT if MMU
 	select GENERIC_ATOMIC64 if MMU
 	select HAVE_GENERIC_HARDIRQS if !MMU
+	select GENERIC_IRQ_SHOW if !MMU
 
 config RWSEM_GENERIC_SPINLOCK
 	bool
diff -druN linux-2.6.39-libre/arch/m68k/Kconfig.nommu linux-3.0-rc7-libre/arch/m68k/Kconfig.nommu
--- linux-2.6.39-libre/arch/m68k/Kconfig.nommu	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/m68k/Kconfig.nommu	2011-07-11 19:51:52.000000000 -0400
@@ -2,10 +2,6 @@
 	bool
 	default n
 
-config GENERIC_FIND_NEXT_BIT
-	bool
-	default y
-
 config GENERIC_GPIO
 	bool
 	default n
@@ -18,6 +14,33 @@
 	bool
 	default n
 
+config M68000
+	bool
+	help
+	  The Freescale (was Motorola) 68000 CPU is the first generation of
+	  the well known M68K family of processors. The CPU core as well as
+	  being available as a stand alone CPU was also used in many
+	  System-On-Chip devices (eg 68328, 68302, etc). It does not contain
+	  a paging MMU.
+
+config MCPU32
+	bool
+	help
+	  The Freescale (was then Motorola) CPU32 is a CPU core that is
+	  based on the 68020 processor. For the most part it is used in
+	  System-On-Chip parts, and does not contain a paging MMU.
+
+config COLDFIRE
+	bool
+	select GENERIC_GPIO
+	select ARCH_REQUIRE_GPIOLIB
+	help
+	  The Freescale ColdFire family of processors is a modern derivitive
+	  of the 68000 processor family. They are mainly targeted at embedded
+	  applications, and are all System-On-Chip (SOC) devices, as opposed
+	  to stand alone CPUs. They implement a subset of the original 68000
+	  processor instruction set.
+
 config COLDFIRE_SW_A7
 	bool
 	default n
@@ -40,26 +63,31 @@
 
 config M68328
 	bool "MC68328"
+	select M68000
 	help
 	  Motorola 68328 processor support.
 
 config M68EZ328
 	bool "MC68EZ328"
+	select M68000
 	help
 	  Motorola 68EX328 processor support.
 
 config M68VZ328
 	bool "MC68VZ328"
+	select M68000
 	help
 	  Motorola 68VZ328 processor support.
 
 config M68360
 	bool "MC68360"
+	select MCPU32
 	help
 	  Motorola 68360 processor support.
 
 config M5206
 	bool "MCF5206"
+	select COLDFIRE
 	select COLDFIRE_SW_A7
 	select HAVE_MBAR
 	help
@@ -67,6 +95,7 @@
 
 config M5206e
 	bool "MCF5206e"
+	select COLDFIRE
 	select COLDFIRE_SW_A7
 	select HAVE_MBAR
 	help
@@ -74,6 +103,7 @@
 
 config M520x
 	bool "MCF520x"
+	select COLDFIRE
 	select GENERIC_CLOCKEVENTS
 	select HAVE_CACHE_SPLIT
 	help
@@ -81,6 +111,7 @@
 
 config M523x
 	bool "MCF523x"
+	select COLDFIRE
 	select GENERIC_CLOCKEVENTS
 	select HAVE_CACHE_SPLIT
 	select HAVE_IPSBAR
@@ -89,6 +120,7 @@
 
 config M5249
 	bool "MCF5249"
+	select COLDFIRE
 	select COLDFIRE_SW_A7
 	select HAVE_MBAR
 	help
@@ -96,6 +128,7 @@
 
 config M5271
 	bool "MCF5271"
+	select COLDFIRE
 	select HAVE_CACHE_SPLIT
 	select HAVE_IPSBAR
 	help
@@ -103,6 +136,7 @@
 
 config M5272
 	bool "MCF5272"
+	select COLDFIRE
 	select COLDFIRE_SW_A7
 	select HAVE_MBAR
 	help
@@ -110,6 +144,7 @@
 
 config M5275
 	bool "MCF5275"
+	select COLDFIRE
 	select HAVE_CACHE_SPLIT
 	select HAVE_IPSBAR
 	help
@@ -117,6 +152,7 @@
 
 config M528x
 	bool "MCF528x"
+	select COLDFIRE
 	select GENERIC_CLOCKEVENTS
 	select HAVE_CACHE_SPLIT
 	select HAVE_IPSBAR
@@ -125,6 +161,7 @@
 
 config M5307
 	bool "MCF5307"
+	select COLDFIRE
 	select COLDFIRE_SW_A7
 	select HAVE_CACHE_CB
 	select HAVE_MBAR
@@ -133,12 +170,14 @@
 
 config M532x
 	bool "MCF532x"
+	select COLDFIRE
 	select HAVE_CACHE_CB
 	help
 	  Freescale (Motorola) ColdFire 532x processor support.
 
 config M5407
 	bool "MCF5407"
+	select COLDFIRE
 	select COLDFIRE_SW_A7
 	select HAVE_CACHE_CB
 	select HAVE_MBAR
@@ -147,6 +186,7 @@
 
 config M547x
 	bool "MCF547x"
+	select COLDFIRE
 	select HAVE_CACHE_CB
 	select HAVE_MBAR
 	help
@@ -154,6 +194,7 @@
 
 config M548x
 	bool "MCF548x"
+	select COLDFIRE
 	select HAVE_CACHE_CB
 	select HAVE_MBAR
 	help
@@ -172,13 +213,6 @@
 	depends on (M548x || M547x)
 	default y
 
-config COLDFIRE
-	bool
-	depends on (M5206 || M5206e || M520x || M523x || M5249 || M527x || M5272 || M528x || M5307 || M532x || M5407 || M54xx)
-	select GENERIC_GPIO
-	select ARCH_REQUIRE_GPIOLIB
-	default y
-
 config CLOCK_SET
 	bool "Enable setting the CPU clock frequency"
 	default n
diff -druN linux-2.6.39-libre/arch/m68k/kernel/asm-offsets.c linux-3.0-rc7-libre/arch/m68k/kernel/asm-offsets.c
--- linux-2.6.39-libre/arch/m68k/kernel/asm-offsets.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/m68k/kernel/asm-offsets.c	2011-07-11 19:51:52.000000000 -0400
@@ -1,5 +1,105 @@
-#ifdef CONFIG_MMU
-#include "asm-offsets_mm.c"
+/*
+ * This program is used to generate definitions needed by
+ * assembly language modules.
+ *
+ * We use the technique used in the OSF Mach kernel code:
+ * generate asm statements containing #defines,
+ * compile this file to assembler, and then extract the
+ * #defines from the assembly-language output.
+ */
+
+#define ASM_OFFSETS_C
+
+#include <linux/stddef.h>
+#include <linux/sched.h>
+#include <linux/kernel_stat.h>
+#include <linux/kbuild.h>
+#include <asm/bootinfo.h>
+#include <asm/irq.h>
+#include <asm/amigahw.h>
+#include <linux/font.h>
+
+int main(void)
+{
+	/* offsets into the task struct */
+	DEFINE(TASK_THREAD, offsetof(struct task_struct, thread));
+	DEFINE(TASK_MM, offsetof(struct task_struct, mm));
+	DEFINE(TASK_INFO, offsetof(struct task_struct, thread.info));
+	DEFINE(TASK_TINFO, offsetof(struct task_struct, thread.info));
+
+	/* offsets into the thread struct */
+	DEFINE(THREAD_KSP, offsetof(struct thread_struct, ksp));
+	DEFINE(THREAD_USP, offsetof(struct thread_struct, usp));
+	DEFINE(THREAD_SR, offsetof(struct thread_struct, sr));
+	DEFINE(THREAD_FS, offsetof(struct thread_struct, fs));
+	DEFINE(THREAD_CRP, offsetof(struct thread_struct, crp));
+	DEFINE(THREAD_ESP0, offsetof(struct thread_struct, esp0));
+	DEFINE(THREAD_FPREG, offsetof(struct thread_struct, fp));
+	DEFINE(THREAD_FPCNTL, offsetof(struct thread_struct, fpcntl));
+	DEFINE(THREAD_FPSTATE, offsetof(struct thread_struct, fpstate));
+
+	/* offsets into the thread_info struct */
+	DEFINE(TINFO_PREEMPT, offsetof(struct thread_info, preempt_count));
+	DEFINE(TINFO_FLAGS, offsetof(struct thread_info, flags));
+
+	/* offsets into the pt_regs */
+	DEFINE(PT_OFF_D0, offsetof(struct pt_regs, d0));
+	DEFINE(PT_OFF_ORIG_D0, offsetof(struct pt_regs, orig_d0));
+	DEFINE(PT_OFF_D1, offsetof(struct pt_regs, d1));
+	DEFINE(PT_OFF_D2, offsetof(struct pt_regs, d2));
+	DEFINE(PT_OFF_D3, offsetof(struct pt_regs, d3));
+	DEFINE(PT_OFF_D4, offsetof(struct pt_regs, d4));
+	DEFINE(PT_OFF_D5, offsetof(struct pt_regs, d5));
+	DEFINE(PT_OFF_A0, offsetof(struct pt_regs, a0));
+	DEFINE(PT_OFF_A1, offsetof(struct pt_regs, a1));
+	DEFINE(PT_OFF_A2, offsetof(struct pt_regs, a2));
+	DEFINE(PT_OFF_PC, offsetof(struct pt_regs, pc));
+	DEFINE(PT_OFF_SR, offsetof(struct pt_regs, sr));
+
+	/* bitfields are a bit difficult */
+#ifdef CONFIG_COLDFIRE
+	DEFINE(PT_OFF_FORMATVEC, offsetof(struct pt_regs, sr) - 2);
 #else
-#include "asm-offsets_no.c"
+	DEFINE(PT_OFF_FORMATVEC, offsetof(struct pt_regs, pc) + 4);
 #endif
+
+	/* offsets into the irq_cpustat_t struct */
+	DEFINE(CPUSTAT_SOFTIRQ_PENDING, offsetof(irq_cpustat_t, __softirq_pending));
+
+	/* signal defines */
+	DEFINE(LSIGSEGV, SIGSEGV);
+	DEFINE(LSEGV_MAPERR, SEGV_MAPERR);
+	DEFINE(LSIGTRAP, SIGTRAP);
+	DEFINE(LTRAP_TRACE, TRAP_TRACE);
+
+#ifdef CONFIG_MMU
+	/* offsets into the bi_record struct */
+	DEFINE(BIR_TAG, offsetof(struct bi_record, tag));
+	DEFINE(BIR_SIZE, offsetof(struct bi_record, size));
+	DEFINE(BIR_DATA, offsetof(struct bi_record, data));
+
+	/* offsets into font_desc (drivers/video/console/font.h) */
+	DEFINE(FONT_DESC_IDX, offsetof(struct font_desc, idx));
+	DEFINE(FONT_DESC_NAME, offsetof(struct font_desc, name));
+	DEFINE(FONT_DESC_WIDTH, offsetof(struct font_desc, width));
+	DEFINE(FONT_DESC_HEIGHT, offsetof(struct font_desc, height));
+	DEFINE(FONT_DESC_DATA, offsetof(struct font_desc, data));
+	DEFINE(FONT_DESC_PREF, offsetof(struct font_desc, pref));
+
+	/* offsets into the custom struct */
+	DEFINE(CUSTOMBASE, &amiga_custom);
+	DEFINE(C_INTENAR, offsetof(struct CUSTOM, intenar));
+	DEFINE(C_INTREQR, offsetof(struct CUSTOM, intreqr));
+	DEFINE(C_INTENA, offsetof(struct CUSTOM, intena));
+	DEFINE(C_INTREQ, offsetof(struct CUSTOM, intreq));
+	DEFINE(C_SERDATR, offsetof(struct CUSTOM, serdatr));
+	DEFINE(C_SERDAT, offsetof(struct CUSTOM, serdat));
+	DEFINE(C_SERPER, offsetof(struct CUSTOM, serper));
+	DEFINE(CIAABASE, &ciaa);
+	DEFINE(CIABBASE, &ciab);
+	DEFINE(C_PRA, offsetof(struct CIA, pra));
+	DEFINE(ZTWOBASE, zTwoBase);
+#endif
+
+	return 0;
+}
diff -druN linux-2.6.39-libre/arch/m68k/kernel/asm-offsets_mm.c linux-3.0-rc7-libre/arch/m68k/kernel/asm-offsets_mm.c
--- linux-2.6.39-libre/arch/m68k/kernel/asm-offsets_mm.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/m68k/kernel/asm-offsets_mm.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,100 +0,0 @@
-/*
- * This program is used to generate definitions needed by
- * assembly language modules.
- *
- * We use the technique used in the OSF Mach kernel code:
- * generate asm statements containing #defines,
- * compile this file to assembler, and then extract the
- * #defines from the assembly-language output.
- */
-
-#define ASM_OFFSETS_C
-
-#include <linux/stddef.h>
-#include <linux/sched.h>
-#include <linux/kernel_stat.h>
-#include <linux/kbuild.h>
-#include <asm/bootinfo.h>
-#include <asm/irq.h>
-#include <asm/amigahw.h>
-#include <linux/font.h>
-
-int main(void)
-{
-	/* offsets into the task struct */
-	DEFINE(TASK_THREAD, offsetof(struct task_struct, thread));
-	DEFINE(TASK_INFO, offsetof(struct task_struct, thread.info));
-	DEFINE(TASK_MM, offsetof(struct task_struct, mm));
-#ifdef CONFIG_MMU
-	DEFINE(TASK_TINFO, offsetof(struct task_struct, thread.info));
-#endif
-
-	/* offsets into the thread struct */
-	DEFINE(THREAD_KSP, offsetof(struct thread_struct, ksp));
-	DEFINE(THREAD_USP, offsetof(struct thread_struct, usp));
-	DEFINE(THREAD_SR, offsetof(struct thread_struct, sr));
-	DEFINE(THREAD_FS, offsetof(struct thread_struct, fs));
-	DEFINE(THREAD_CRP, offsetof(struct thread_struct, crp));
-	DEFINE(THREAD_ESP0, offsetof(struct thread_struct, esp0));
-	DEFINE(THREAD_FPREG, offsetof(struct thread_struct, fp));
-	DEFINE(THREAD_FPCNTL, offsetof(struct thread_struct, fpcntl));
-	DEFINE(THREAD_FPSTATE, offsetof(struct thread_struct, fpstate));
-
-	/* offsets into the thread_info struct */
-	DEFINE(TINFO_PREEMPT, offsetof(struct thread_info, preempt_count));
-	DEFINE(TINFO_FLAGS, offsetof(struct thread_info, flags));
-
-	/* offsets into the pt_regs */
-	DEFINE(PT_OFF_D0, offsetof(struct pt_regs, d0));
-	DEFINE(PT_OFF_ORIG_D0, offsetof(struct pt_regs, orig_d0));
-	DEFINE(PT_OFF_D1, offsetof(struct pt_regs, d1));
-	DEFINE(PT_OFF_D2, offsetof(struct pt_regs, d2));
-	DEFINE(PT_OFF_D3, offsetof(struct pt_regs, d3));
-	DEFINE(PT_OFF_D4, offsetof(struct pt_regs, d4));
-	DEFINE(PT_OFF_D5, offsetof(struct pt_regs, d5));
-	DEFINE(PT_OFF_A0, offsetof(struct pt_regs, a0));
-	DEFINE(PT_OFF_A1, offsetof(struct pt_regs, a1));
-	DEFINE(PT_OFF_A2, offsetof(struct pt_regs, a2));
-	DEFINE(PT_OFF_PC, offsetof(struct pt_regs, pc));
-	DEFINE(PT_OFF_SR, offsetof(struct pt_regs, sr));
-	/* bitfields are a bit difficult */
-	DEFINE(PT_OFF_FORMATVEC, offsetof(struct pt_regs, pc) + 4);
-
-	/* offsets into the irq_cpustat_t struct */
-	DEFINE(CPUSTAT_SOFTIRQ_PENDING, offsetof(irq_cpustat_t, __softirq_pending));
-
-	/* offsets into the bi_record struct */
-	DEFINE(BIR_TAG, offsetof(struct bi_record, tag));
-	DEFINE(BIR_SIZE, offsetof(struct bi_record, size));
-	DEFINE(BIR_DATA, offsetof(struct bi_record, data));
-
-	/* offsets into font_desc (drivers/video/console/font.h) */
-	DEFINE(FONT_DESC_IDX, offsetof(struct font_desc, idx));
-	DEFINE(FONT_DESC_NAME, offsetof(struct font_desc, name));
-	DEFINE(FONT_DESC_WIDTH, offsetof(struct font_desc, width));
-	DEFINE(FONT_DESC_HEIGHT, offsetof(struct font_desc, height));
-	DEFINE(FONT_DESC_DATA, offsetof(struct font_desc, data));
-	DEFINE(FONT_DESC_PREF, offsetof(struct font_desc, pref));
-
-	/* signal defines */
-	DEFINE(LSIGSEGV, SIGSEGV);
-	DEFINE(LSEGV_MAPERR, SEGV_MAPERR);
-	DEFINE(LSIGTRAP, SIGTRAP);
-	DEFINE(LTRAP_TRACE, TRAP_TRACE);
-
-	/* offsets into the custom struct */
-	DEFINE(CUSTOMBASE, &amiga_custom);
-	DEFINE(C_INTENAR, offsetof(struct CUSTOM, intenar));
-	DEFINE(C_INTREQR, offsetof(struct CUSTOM, intreqr));
-	DEFINE(C_INTENA, offsetof(struct CUSTOM, intena));
-	DEFINE(C_INTREQ, offsetof(struct CUSTOM, intreq));
-	DEFINE(C_SERDATR, offsetof(struct CUSTOM, serdatr));
-	DEFINE(C_SERDAT, offsetof(struct CUSTOM, serdat));
-	DEFINE(C_SERPER, offsetof(struct CUSTOM, serper));
-	DEFINE(CIAABASE, &ciaa);
-	DEFINE(CIABBASE, &ciab);
-	DEFINE(C_PRA, offsetof(struct CIA, pra));
-	DEFINE(ZTWOBASE, zTwoBase);
-
-	return 0;
-}
diff -druN linux-2.6.39-libre/arch/m68k/kernel/asm-offsets_no.c linux-3.0-rc7-libre/arch/m68k/kernel/asm-offsets_no.c
--- linux-2.6.39-libre/arch/m68k/kernel/asm-offsets_no.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/m68k/kernel/asm-offsets_no.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,76 +0,0 @@
-/*
- * This program is used to generate definitions needed by
- * assembly language modules.
- *
- * We use the technique used in the OSF Mach kernel code:
- * generate asm statements containing #defines,
- * compile this file to assembler, and then extract the
- * #defines from the assembly-language output.
- */
-
-#include <linux/stddef.h>
-#include <linux/sched.h>
-#include <linux/kernel_stat.h>
-#include <linux/ptrace.h>
-#include <linux/hardirq.h>
-#include <linux/kbuild.h>
-#include <asm/bootinfo.h>
-#include <asm/irq.h>
-#include <asm/thread_info.h>
-
-int main(void)
-{
-	/* offsets into the task struct */
-	DEFINE(TASK_THREAD, offsetof(struct task_struct, thread));
-	DEFINE(TASK_MM, offsetof(struct task_struct, mm));
-
-	/* offsets into the irq_cpustat_t struct */
-	DEFINE(CPUSTAT_SOFTIRQ_PENDING, offsetof(irq_cpustat_t, __softirq_pending));
-
-	/* offsets into the thread struct */
-	DEFINE(THREAD_KSP, offsetof(struct thread_struct, ksp));
-	DEFINE(THREAD_USP, offsetof(struct thread_struct, usp));
-	DEFINE(THREAD_SR, offsetof(struct thread_struct, sr));
-	DEFINE(THREAD_FS, offsetof(struct thread_struct, fs));
-	DEFINE(THREAD_CRP, offsetof(struct thread_struct, crp));
-	DEFINE(THREAD_ESP0, offsetof(struct thread_struct, esp0));
-	DEFINE(THREAD_FPREG, offsetof(struct thread_struct, fp));
-	DEFINE(THREAD_FPCNTL, offsetof(struct thread_struct, fpcntl));
-	DEFINE(THREAD_FPSTATE, offsetof(struct thread_struct, fpstate));
-
-	/* offsets into the pt_regs */
-	DEFINE(PT_OFF_D0, offsetof(struct pt_regs, d0));
-	DEFINE(PT_OFF_ORIG_D0, offsetof(struct pt_regs, orig_d0));
-	DEFINE(PT_OFF_D1, offsetof(struct pt_regs, d1));
-	DEFINE(PT_OFF_D2, offsetof(struct pt_regs, d2));
-	DEFINE(PT_OFF_D3, offsetof(struct pt_regs, d3));
-	DEFINE(PT_OFF_D4, offsetof(struct pt_regs, d4));
-	DEFINE(PT_OFF_D5, offsetof(struct pt_regs, d5));
-	DEFINE(PT_OFF_A0, offsetof(struct pt_regs, a0));
-	DEFINE(PT_OFF_A1, offsetof(struct pt_regs, a1));
-	DEFINE(PT_OFF_A2, offsetof(struct pt_regs, a2));
-	DEFINE(PT_OFF_PC, offsetof(struct pt_regs, pc));
-	DEFINE(PT_OFF_SR, offsetof(struct pt_regs, sr));
-
-#ifdef CONFIG_COLDFIRE
-	/* bitfields are a bit difficult */
-	DEFINE(PT_OFF_FORMATVEC, offsetof(struct pt_regs, sr) - 2);
-#else
-	/* bitfields are a bit difficult */
-	DEFINE(PT_OFF_FORMATVEC, offsetof(struct pt_regs, pc) + 4);
-#endif
-
-	/* signal defines */
-	DEFINE(SIGSEGV, SIGSEGV);
-	DEFINE(SEGV_MAPERR, SEGV_MAPERR);
-	DEFINE(SIGTRAP, SIGTRAP);
-	DEFINE(TRAP_TRACE, TRAP_TRACE);
-
-	DEFINE(PT_PTRACED, PT_PTRACED);
-
-	/* Offsets in thread_info structure */
-	DEFINE(TI_FLAGS, offsetof(struct thread_info, flags));
-	DEFINE(TI_PREEMPTCOUNT, offsetof(struct thread_info, preempt_count));
-
-	return 0;
-}
diff -druN linux-2.6.39-libre/arch/m68k/kernel/entry_mm.S linux-3.0-rc7-libre/arch/m68k/kernel/entry_mm.S
--- linux-2.6.39-libre/arch/m68k/kernel/entry_mm.S	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/m68k/kernel/entry_mm.S	2011-07-11 19:51:52.000000000 -0400
@@ -407,351 +407,3 @@
 
 	rts
 
-.data
-ALIGN
-sys_call_table:
-	.long sys_restart_syscall	/* 0 - old "setup()" system call, used for restarting */
-	.long sys_exit
-	.long sys_fork
-	.long sys_read
-	.long sys_write
-	.long sys_open		/* 5 */
-	.long sys_close
-	.long sys_waitpid
-	.long sys_creat
-	.long sys_link
-	.long sys_unlink	/* 10 */
-	.long sys_execve
-	.long sys_chdir
-	.long sys_time
-	.long sys_mknod
-	.long sys_chmod		/* 15 */
-	.long sys_chown16
-	.long sys_ni_syscall				/* old break syscall holder */
-	.long sys_stat
-	.long sys_lseek
-	.long sys_getpid	/* 20 */
-	.long sys_mount
-	.long sys_oldumount
-	.long sys_setuid16
-	.long sys_getuid16
-	.long sys_stime		/* 25 */
-	.long sys_ptrace
-	.long sys_alarm
-	.long sys_fstat
-	.long sys_pause
-	.long sys_utime		/* 30 */
-	.long sys_ni_syscall				/* old stty syscall holder */
-	.long sys_ni_syscall				/* old gtty syscall holder */
-	.long sys_access
-	.long sys_nice
-	.long sys_ni_syscall	/* 35 */	/* old ftime syscall holder */
-	.long sys_sync
-	.long sys_kill
-	.long sys_rename
-	.long sys_mkdir
-	.long sys_rmdir		/* 40 */
-	.long sys_dup
-	.long sys_pipe
-	.long sys_times
-	.long sys_ni_syscall				/* old prof syscall holder */
-	.long sys_brk		/* 45 */
-	.long sys_setgid16
-	.long sys_getgid16
-	.long sys_signal
-	.long sys_geteuid16
-	.long sys_getegid16	/* 50 */
-	.long sys_acct
-	.long sys_umount				/* recycled never used phys() */
-	.long sys_ni_syscall				/* old lock syscall holder */
-	.long sys_ioctl
-	.long sys_fcntl		/* 55 */
-	.long sys_ni_syscall				/* old mpx syscall holder */
-	.long sys_setpgid
-	.long sys_ni_syscall				/* old ulimit syscall holder */
-	.long sys_ni_syscall
-	.long sys_umask		/* 60 */
-	.long sys_chroot
-	.long sys_ustat
-	.long sys_dup2
-	.long sys_getppid
-	.long sys_getpgrp	/* 65 */
-	.long sys_setsid
-	.long sys_sigaction
-	.long sys_sgetmask
-	.long sys_ssetmask
-	.long sys_setreuid16	/* 70 */
-	.long sys_setregid16
-	.long sys_sigsuspend
-	.long sys_sigpending
-	.long sys_sethostname
-	.long sys_setrlimit	/* 75 */
-	.long sys_old_getrlimit
-	.long sys_getrusage
-	.long sys_gettimeofday
-	.long sys_settimeofday
-	.long sys_getgroups16	/* 80 */
-	.long sys_setgroups16
-	.long sys_old_select
-	.long sys_symlink
-	.long sys_lstat
-	.long sys_readlink	/* 85 */
-	.long sys_uselib
-	.long sys_swapon
-	.long sys_reboot
-	.long sys_old_readdir
-	.long sys_old_mmap	/* 90 */
-	.long sys_munmap
-	.long sys_truncate
-	.long sys_ftruncate
-	.long sys_fchmod
-	.long sys_fchown16	/* 95 */
-	.long sys_getpriority
-	.long sys_setpriority
-	.long sys_ni_syscall				/* old profil syscall holder */
-	.long sys_statfs
-	.long sys_fstatfs	/* 100 */
-	.long sys_ni_syscall				/* ioperm for i386 */
-	.long sys_socketcall
-	.long sys_syslog
-	.long sys_setitimer
-	.long sys_getitimer	/* 105 */
-	.long sys_newstat
-	.long sys_newlstat
-	.long sys_newfstat
-	.long sys_ni_syscall
-	.long sys_ni_syscall	/* 110 */	/* iopl for i386 */
-	.long sys_vhangup
-	.long sys_ni_syscall				/* obsolete idle() syscall */
-	.long sys_ni_syscall				/* vm86old for i386 */
-	.long sys_wait4
-	.long sys_swapoff	/* 115 */
-	.long sys_sysinfo
-	.long sys_ipc
-	.long sys_fsync
-	.long sys_sigreturn
-	.long sys_clone		/* 120 */
-	.long sys_setdomainname
-	.long sys_newuname
-	.long sys_cacheflush				/* modify_ldt for i386 */
-	.long sys_adjtimex
-	.long sys_mprotect	/* 125 */
-	.long sys_sigprocmask
-	.long sys_ni_syscall		/* old "create_module" */
-	.long sys_init_module
-	.long sys_delete_module
-	.long sys_ni_syscall	/* 130 - old "get_kernel_syms" */
-	.long sys_quotactl
-	.long sys_getpgid
-	.long sys_fchdir
-	.long sys_bdflush
-	.long sys_sysfs		/* 135 */
-	.long sys_personality
-	.long sys_ni_syscall				/* for afs_syscall */
-	.long sys_setfsuid16
-	.long sys_setfsgid16
-	.long sys_llseek	/* 140 */
-	.long sys_getdents
-	.long sys_select
-	.long sys_flock
-	.long sys_msync
-	.long sys_readv		/* 145 */
-	.long sys_writev
-	.long sys_getsid
-	.long sys_fdatasync
-	.long sys_sysctl
-	.long sys_mlock		/* 150 */
-	.long sys_munlock
-	.long sys_mlockall
-	.long sys_munlockall
-	.long sys_sched_setparam
-	.long sys_sched_getparam	/* 155 */
-	.long sys_sched_setscheduler
-	.long sys_sched_getscheduler
-	.long sys_sched_yield
-	.long sys_sched_get_priority_max
-	.long sys_sched_get_priority_min  /* 160 */
-	.long sys_sched_rr_get_interval
-	.long sys_nanosleep
-	.long sys_mremap
-	.long sys_setresuid16
-	.long sys_getresuid16	/* 165 */
-	.long sys_getpagesize
-	.long sys_ni_syscall		/* old sys_query_module */
-	.long sys_poll
-	.long sys_nfsservctl
-	.long sys_setresgid16	/* 170 */
-	.long sys_getresgid16
-	.long sys_prctl
-	.long sys_rt_sigreturn
-	.long sys_rt_sigaction
-	.long sys_rt_sigprocmask	/* 175 */
-	.long sys_rt_sigpending
-	.long sys_rt_sigtimedwait
-	.long sys_rt_sigqueueinfo
-	.long sys_rt_sigsuspend
-	.long sys_pread64	/* 180 */
-	.long sys_pwrite64
-	.long sys_lchown16;
-	.long sys_getcwd
-	.long sys_capget
-	.long sys_capset	/* 185 */
-	.long sys_sigaltstack
-	.long sys_sendfile
-	.long sys_ni_syscall				/* streams1 */
-	.long sys_ni_syscall				/* streams2 */
-	.long sys_vfork		/* 190 */
-	.long sys_getrlimit
-	.long sys_mmap2
-	.long sys_truncate64
-	.long sys_ftruncate64
-	.long sys_stat64	/* 195 */
-	.long sys_lstat64
-	.long sys_fstat64
-	.long sys_chown
-	.long sys_getuid
-	.long sys_getgid	/* 200 */
-	.long sys_geteuid
-	.long sys_getegid
-	.long sys_setreuid
-	.long sys_setregid
-	.long sys_getgroups	/* 205 */
-	.long sys_setgroups
-	.long sys_fchown
-	.long sys_setresuid
-	.long sys_getresuid
-	.long sys_setresgid	/* 210 */
-	.long sys_getresgid
-	.long sys_lchown
-	.long sys_setuid
-	.long sys_setgid
-	.long sys_setfsuid	/* 215 */
-	.long sys_setfsgid
-	.long sys_pivot_root
-	.long sys_ni_syscall
-	.long sys_ni_syscall
-	.long sys_getdents64	/* 220 */
-	.long sys_gettid
-	.long sys_tkill
-	.long sys_setxattr
-	.long sys_lsetxattr
-	.long sys_fsetxattr	/* 225 */
-	.long sys_getxattr
-	.long sys_lgetxattr
-	.long sys_fgetxattr
-	.long sys_listxattr
-	.long sys_llistxattr	/* 230 */
-	.long sys_flistxattr
-	.long sys_removexattr
-	.long sys_lremovexattr
-	.long sys_fremovexattr
-	.long sys_futex		/* 235 */
-	.long sys_sendfile64
-	.long sys_mincore
-	.long sys_madvise
-	.long sys_fcntl64
-	.long sys_readahead	/* 240 */
-	.long sys_io_setup
-	.long sys_io_destroy
-	.long sys_io_getevents
-	.long sys_io_submit
-	.long sys_io_cancel	/* 245 */
-	.long sys_fadvise64
-	.long sys_exit_group
-	.long sys_lookup_dcookie
-	.long sys_epoll_create
-	.long sys_epoll_ctl	/* 250 */
-	.long sys_epoll_wait
-	.long sys_remap_file_pages
-	.long sys_set_tid_address
-	.long sys_timer_create
-	.long sys_timer_settime	/* 255 */
-	.long sys_timer_gettime
-	.long sys_timer_getoverrun
-	.long sys_timer_delete
-	.long sys_clock_settime
-	.long sys_clock_gettime	/* 260 */
-	.long sys_clock_getres
-	.long sys_clock_nanosleep
-	.long sys_statfs64
-	.long sys_fstatfs64
-	.long sys_tgkill	/* 265 */
-	.long sys_utimes
-	.long sys_fadvise64_64
-	.long sys_mbind
-	.long sys_get_mempolicy
-	.long sys_set_mempolicy	/* 270 */
-	.long sys_mq_open
-	.long sys_mq_unlink
-	.long sys_mq_timedsend
-	.long sys_mq_timedreceive
-	.long sys_mq_notify	/* 275 */
-	.long sys_mq_getsetattr
-	.long sys_waitid
-	.long sys_ni_syscall	/* for sys_vserver */
-	.long sys_add_key
-	.long sys_request_key	/* 280 */
-	.long sys_keyctl
-	.long sys_ioprio_set
-	.long sys_ioprio_get
-	.long sys_inotify_init
-	.long sys_inotify_add_watch	/* 285 */
-	.long sys_inotify_rm_watch
-	.long sys_migrate_pages
-	.long sys_openat
-	.long sys_mkdirat
-	.long sys_mknodat		/* 290 */
-	.long sys_fchownat
-	.long sys_futimesat
-	.long sys_fstatat64
-	.long sys_unlinkat
-	.long sys_renameat		/* 295 */
-	.long sys_linkat
-	.long sys_symlinkat
-	.long sys_readlinkat
-	.long sys_fchmodat
-	.long sys_faccessat		/* 300 */
-	.long sys_ni_syscall		/* Reserved for pselect6 */
-	.long sys_ni_syscall		/* Reserved for ppoll */
-	.long sys_unshare
-	.long sys_set_robust_list
-	.long sys_get_robust_list	/* 305 */
-	.long sys_splice
-	.long sys_sync_file_range
-	.long sys_tee
-	.long sys_vmsplice
-	.long sys_move_pages		/* 310 */
-	.long sys_sched_setaffinity
-	.long sys_sched_getaffinity
-	.long sys_kexec_load
-	.long sys_getcpu
-	.long sys_epoll_pwait		/* 315 */
-	.long sys_utimensat
-	.long sys_signalfd
-	.long sys_timerfd_create
-	.long sys_eventfd
-	.long sys_fallocate		/* 320 */
-	.long sys_timerfd_settime
-	.long sys_timerfd_gettime
-	.long sys_signalfd4
-	.long sys_eventfd2
-	.long sys_epoll_create1		/* 325 */
-	.long sys_dup3
-	.long sys_pipe2
-	.long sys_inotify_init1
-	.long sys_preadv
-	.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
-	.long sys_fanotify_init
-	.long sys_fanotify_mark
-	.long sys_prlimit64
-	.long sys_name_to_handle_at	/* 340 */
-	.long sys_open_by_handle_at
-	.long sys_clock_adjtime
-	.long sys_syncfs
-
diff -druN linux-2.6.39-libre/arch/m68k/kernel/entry_no.S linux-3.0-rc7-libre/arch/m68k/kernel/entry_no.S
--- linux-2.6.39-libre/arch/m68k/kernel/entry_no.S	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/m68k/kernel/entry_no.S	2011-07-11 19:51:52.000000000 -0400
@@ -24,7 +24,6 @@
  * linux 2.4 support David McCullough <davidm@snapgear.com>
  */
 
-#include <linux/sys.h>
 #include <linux/linkage.h>
 #include <asm/errno.h>
 #include <asm/setup.h>
diff -druN linux-2.6.39-libre/arch/m68k/kernel/irq.c linux-3.0-rc7-libre/arch/m68k/kernel/irq.c
--- linux-2.6.39-libre/arch/m68k/kernel/irq.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/m68k/kernel/irq.c	2011-07-11 19:51:52.000000000 -0400
@@ -28,31 +28,3 @@
 
 	set_irq_regs(oldregs);
 }
-
-int show_interrupts(struct seq_file *p, void *v)
-{
-	struct irqaction *ap;
-	int irq = *((loff_t *) v);
-
-	if (irq == 0)
-		seq_puts(p, "           CPU0\n");
-
-	if (irq < NR_IRQS) {
-		struct irq_desc *desc = irq_to_desc(irq);
-
-		ap = desc->action;
-		if (ap) {
-			seq_printf(p, "%3d: ", irq);
-			seq_printf(p, "%10u ", kstat_irqs(irq));
-			seq_printf(p, "%14s  ", irq_desc_get_chip(desc)->name);
-
-			seq_printf(p, "%s", ap->name);
-			for (ap = ap->next; ap; ap = ap->next)
-				seq_printf(p, ", %s", ap->name);
-			seq_putc(p, '\n');
-		}
-	}
-
-	return 0;
-}
-
diff -druN linux-2.6.39-libre/arch/m68k/kernel/m68k_ksyms.c linux-3.0-rc7-libre/arch/m68k/kernel/m68k_ksyms.c
--- linux-2.6.39-libre/arch/m68k/kernel/m68k_ksyms.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/m68k/kernel/m68k_ksyms.c	2011-07-11 19:51:52.000000000 -0400
@@ -1,5 +1,32 @@
-#ifdef CONFIG_MMU
-#include "m68k_ksyms_mm.c"
-#else
-#include "m68k_ksyms_no.c"
+#include <linux/module.h>
+
+asmlinkage long long __ashldi3 (long long, int);
+asmlinkage long long __ashrdi3 (long long, int);
+asmlinkage long long __lshrdi3 (long long, int);
+asmlinkage long long __muldi3 (long long, long long);
+
+/* The following are special because they're not called
+   explicitly (the C compiler generates them).  Fortunately,
+   their interface isn't gonna change any time soon now, so
+   it's OK to leave it out of version control.  */
+EXPORT_SYMBOL(__ashldi3);
+EXPORT_SYMBOL(__ashrdi3);
+EXPORT_SYMBOL(__lshrdi3);
+EXPORT_SYMBOL(__muldi3);
+
+#if defined(CONFIG_M68000) || defined(CONFIG_COLDFIRE)
+/*
+ * Simpler 68k and ColdFire parts also need a few other gcc functions.
+ */
+extern long long __divsi3(long long, long long);
+extern long long __modsi3(long long, long long);
+extern long long __mulsi3(long long, long long);
+extern long long __udivsi3(long long, long long);
+extern long long __umodsi3(long long, long long);
+
+EXPORT_SYMBOL(__divsi3);
+EXPORT_SYMBOL(__modsi3);
+EXPORT_SYMBOL(__mulsi3);
+EXPORT_SYMBOL(__udivsi3);
+EXPORT_SYMBOL(__umodsi3);
 #endif
diff -druN linux-2.6.39-libre/arch/m68k/kernel/m68k_ksyms_mm.c linux-3.0-rc7-libre/arch/m68k/kernel/m68k_ksyms_mm.c
--- linux-2.6.39-libre/arch/m68k/kernel/m68k_ksyms_mm.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/m68k/kernel/m68k_ksyms_mm.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,16 +0,0 @@
-#include <linux/module.h>
-
-asmlinkage long long __ashldi3 (long long, int);
-asmlinkage long long __ashrdi3 (long long, int);
-asmlinkage long long __lshrdi3 (long long, int);
-asmlinkage long long __muldi3 (long long, long long);
-
-/* The following are special because they're not called
-   explicitly (the C compiler generates them).  Fortunately,
-   their interface isn't gonna change any time soon now, so
-   it's OK to leave it out of version control.  */
-EXPORT_SYMBOL(__ashldi3);
-EXPORT_SYMBOL(__ashrdi3);
-EXPORT_SYMBOL(__lshrdi3);
-EXPORT_SYMBOL(__muldi3);
-
diff -druN linux-2.6.39-libre/arch/m68k/kernel/m68k_ksyms_no.c linux-3.0-rc7-libre/arch/m68k/kernel/m68k_ksyms_no.c
--- linux-2.6.39-libre/arch/m68k/kernel/m68k_ksyms_no.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/m68k/kernel/m68k_ksyms_no.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,78 +0,0 @@
-#include <linux/module.h>
-#include <linux/linkage.h>
-#include <linux/sched.h>
-#include <linux/string.h>
-#include <linux/mm.h>
-#include <linux/user.h>
-#include <linux/elfcore.h>
-#include <linux/in6.h>
-#include <linux/interrupt.h>
-
-#include <asm/setup.h>
-#include <asm/machdep.h>
-#include <asm/pgalloc.h>
-#include <asm/irq.h>
-#include <asm/io.h>
-#include <asm/checksum.h>
-#include <asm/current.h>
-
-extern int dump_fpu(struct pt_regs *, elf_fpregset_t *);
-
-/* platform dependent support */
-
-EXPORT_SYMBOL(__ioremap);
-EXPORT_SYMBOL(iounmap);
-EXPORT_SYMBOL(dump_fpu);
-
-EXPORT_SYMBOL(ip_fast_csum);
-
-EXPORT_SYMBOL(kernel_thread);
-
-/* Networking helper routines. */
-EXPORT_SYMBOL(csum_partial_copy_nocheck);
-
-/* The following are special because they're not called
-   explicitly (the C compiler generates them).  Fortunately,
-   their interface isn't gonna change any time soon now, so
-   it's OK to leave it out of version control.  */
-EXPORT_SYMBOL(memcpy);
-EXPORT_SYMBOL(memset);
-
-/*
- * libgcc functions - functions that are used internally by the
- * compiler...  (prototypes are not correct though, but that
- * doesn't really matter since they're not versioned).
- */
-extern void __ashldi3(void);
-extern void __ashrdi3(void);
-extern void __divsi3(void);
-extern void __lshrdi3(void);
-extern void __modsi3(void);
-extern void __muldi3(void);
-extern void __mulsi3(void);
-extern void __udivsi3(void);
-extern void __umodsi3(void);
-
-        /* gcc lib functions */
-EXPORT_SYMBOL(__ashldi3);
-EXPORT_SYMBOL(__ashrdi3);
-EXPORT_SYMBOL(__divsi3);
-EXPORT_SYMBOL(__lshrdi3);
-EXPORT_SYMBOL(__modsi3);
-EXPORT_SYMBOL(__muldi3);
-EXPORT_SYMBOL(__mulsi3);
-EXPORT_SYMBOL(__udivsi3);
-EXPORT_SYMBOL(__umodsi3);
-
-#ifdef CONFIG_COLDFIRE
-extern unsigned int *dma_device_address;
-extern unsigned long dma_base_addr, _ramend;
-EXPORT_SYMBOL(dma_base_addr);
-EXPORT_SYMBOL(dma_device_address);
-EXPORT_SYMBOL(_ramend);
-
-extern asmlinkage void trap(void);
-extern void	*_ramvec;
-EXPORT_SYMBOL(trap);
-EXPORT_SYMBOL(_ramvec);
-#endif /* CONFIG_COLDFIRE */
diff -druN linux-2.6.39-libre/arch/m68k/kernel/Makefile_mm linux-3.0-rc7-libre/arch/m68k/kernel/Makefile_mm
--- linux-2.6.39-libre/arch/m68k/kernel/Makefile_mm	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/m68k/kernel/Makefile_mm	2011-07-11 19:51:52.000000000 -0400
@@ -10,7 +10,7 @@
 extra-y	+= vmlinux.lds
 
 obj-y	:= entry.o process.o traps.o ints.o signal.o ptrace.o module.o \
-	   sys_m68k.o time.o setup.o m68k_ksyms.o devres.o
+	   sys_m68k.o time.o setup.o m68k_ksyms.o devres.o syscalltable.o
 
 devres-y = ../../../kernel/irq/devres.o
 
diff -druN linux-2.6.39-libre/arch/m68k/kernel/process_no.c linux-3.0-rc7-libre/arch/m68k/kernel/process_no.c
--- linux-2.6.39-libre/arch/m68k/kernel/process_no.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/m68k/kernel/process_no.c	2011-07-11 19:51:52.000000000 -0400
@@ -151,6 +151,7 @@
 	set_fs(fs);
 	return retval;
 }
+EXPORT_SYMBOL(kernel_thread);
 
 void flush_thread(void)
 {
@@ -283,6 +284,7 @@
 #endif
 	return 1;
 }
+EXPORT_SYMBOL(dump_fpu);
 
 /*
  *	Generic dumping code. Used for panic and debug.
diff -druN linux-2.6.39-libre/arch/m68k/kernel/syscalltable.S linux-3.0-rc7-libre/arch/m68k/kernel/syscalltable.S
--- linux-2.6.39-libre/arch/m68k/kernel/syscalltable.S	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/m68k/kernel/syscalltable.S	2011-07-11 19:51:52.000000000 -0400
@@ -1,6 +1,4 @@
 /*
- *  linux/arch/m68knommu/kernel/syscalltable.S
- *
  *  Copyright (C) 2002, Greg Ungerer (gerg@snapgear.com)
  *
  *  Based on older entry.S files, the following copyrights apply:
@@ -9,171 +7,175 @@
  *                      Kenneth Albanowski <kjahds@kjahds.com>,
  *  Copyright (C) 2000  Lineo Inc. (www.lineo.com) 
  *  Copyright (C) 1991, 1992  Linus Torvalds
+ *
+ *  Linux/m68k support by Hamish Macdonald
  */
 
-#include <linux/sys.h>
 #include <linux/linkage.h>
-#include <asm/unistd.h>
 
-.text
+#ifndef CONFIG_MMU
+#define sys_mmap2		sys_mmap_pgoff
+#endif
+
+.section .rodata
 ALIGN
 ENTRY(sys_call_table)
-	.long sys_restart_syscall	/* 0  -  old "setup()" system call */
+	.long sys_restart_syscall	/* 0 - old "setup()" system call, used for restarting */
 	.long sys_exit
 	.long sys_fork
 	.long sys_read
 	.long sys_write
-	.long sys_open		/* 5 */
+	.long sys_open			/* 5 */
 	.long sys_close
 	.long sys_waitpid
 	.long sys_creat
 	.long sys_link
-	.long sys_unlink	/* 10 */
+	.long sys_unlink		/* 10 */
 	.long sys_execve
 	.long sys_chdir
 	.long sys_time
 	.long sys_mknod
-	.long sys_chmod		/* 15 */
+	.long sys_chmod			/* 15 */
 	.long sys_chown16
-	.long sys_ni_syscall	/* old break syscall holder */
+	.long sys_ni_syscall		/* old break syscall holder */
 	.long sys_stat
 	.long sys_lseek
-	.long sys_getpid	/* 20 */
+	.long sys_getpid		/* 20 */
 	.long sys_mount
 	.long sys_oldumount
 	.long sys_setuid16
 	.long sys_getuid16
-	.long sys_stime		/* 25 */
+	.long sys_stime			/* 25 */
 	.long sys_ptrace
 	.long sys_alarm
 	.long sys_fstat
 	.long sys_pause
-	.long sys_utime		/* 30 */
-	.long sys_ni_syscall	/* old stty syscall holder */
-	.long sys_ni_syscall	/* old gtty syscall holder */
+	.long sys_utime			/* 30 */
+	.long sys_ni_syscall		/* old stty syscall holder */
+	.long sys_ni_syscall		/* old gtty syscall holder */
 	.long sys_access
 	.long sys_nice
-	.long sys_ni_syscall	/* 35 */ /* old ftime syscall holder */
+	.long sys_ni_syscall		/* 35 - old ftime syscall holder */
 	.long sys_sync
 	.long sys_kill
 	.long sys_rename
 	.long sys_mkdir
-	.long sys_rmdir		/* 40 */
+	.long sys_rmdir			/* 40 */
 	.long sys_dup
 	.long sys_pipe
 	.long sys_times
-	.long sys_ni_syscall	/* old prof syscall holder */
-	.long sys_brk		/* 45 */
+	.long sys_ni_syscall		/* old prof syscall holder */
+	.long sys_brk			/* 45 */
 	.long sys_setgid16
 	.long sys_getgid16
 	.long sys_signal
 	.long sys_geteuid16
-	.long sys_getegid16	/* 50 */
+	.long sys_getegid16		/* 50 */
 	.long sys_acct
-	.long sys_umount	/* recycled never used phys() */
-	.long sys_ni_syscall	/* old lock syscall holder */
+	.long sys_umount		/* recycled never used phys() */
+	.long sys_ni_syscall		/* old lock syscall holder */
 	.long sys_ioctl
-	.long sys_fcntl		/* 55 */
-	.long sys_ni_syscall	/* old mpx syscall holder */
+	.long sys_fcntl			/* 55 */
+	.long sys_ni_syscall		/* old mpx syscall holder */
 	.long sys_setpgid
-	.long sys_ni_syscall	/* old ulimit syscall holder */
+	.long sys_ni_syscall		/* old ulimit syscall holder */
 	.long sys_ni_syscall
-	.long sys_umask		/* 60 */
+	.long sys_umask			/* 60 */
 	.long sys_chroot
 	.long sys_ustat
 	.long sys_dup2
 	.long sys_getppid
-	.long sys_getpgrp	/* 65 */
+	.long sys_getpgrp		/* 65 */
 	.long sys_setsid
 	.long sys_sigaction
 	.long sys_sgetmask
 	.long sys_ssetmask
-	.long sys_setreuid16	/* 70 */
+	.long sys_setreuid16		/* 70 */
 	.long sys_setregid16
 	.long sys_sigsuspend
 	.long sys_sigpending
 	.long sys_sethostname
-	.long sys_setrlimit	/* 75 */
+	.long sys_setrlimit		/* 75 */
 	.long sys_old_getrlimit
 	.long sys_getrusage
 	.long sys_gettimeofday
 	.long sys_settimeofday
-	.long sys_getgroups16	/* 80 */
+	.long sys_getgroups16		/* 80 */
 	.long sys_setgroups16
 	.long sys_old_select
 	.long sys_symlink
 	.long sys_lstat
-	.long sys_readlink	/* 85 */
+	.long sys_readlink		/* 85 */
 	.long sys_uselib
-	.long sys_ni_syscall	/* sys_swapon */
+	.long sys_swapon
 	.long sys_reboot
 	.long sys_old_readdir
-	.long sys_old_mmap	/* 90 */
+	.long sys_old_mmap		/* 90 */
 	.long sys_munmap
 	.long sys_truncate
 	.long sys_ftruncate
 	.long sys_fchmod
-	.long sys_fchown16	/* 95 */
+	.long sys_fchown16		/* 95 */
 	.long sys_getpriority
 	.long sys_setpriority
-	.long sys_ni_syscall	/* old profil syscall holder */
+	.long sys_ni_syscall		/* old profil syscall holder */
 	.long sys_statfs
-	.long sys_fstatfs	/* 100 */
-	.long sys_ni_syscall	/* ioperm for i386 */
+	.long sys_fstatfs		/* 100 */
+	.long sys_ni_syscall		/* ioperm for i386 */
 	.long sys_socketcall
 	.long sys_syslog
 	.long sys_setitimer
-	.long sys_getitimer	/* 105 */
+	.long sys_getitimer		/* 105 */
 	.long sys_newstat
 	.long sys_newlstat
 	.long sys_newfstat
 	.long sys_ni_syscall
-	.long sys_ni_syscall	/* iopl for i386 */ /* 110 */
+	.long sys_ni_syscall		/* 110 - iopl for i386 */
 	.long sys_vhangup
-	.long sys_ni_syscall	/* obsolete idle() syscall */
-	.long sys_ni_syscall	/* vm86old for i386 */
+	.long sys_ni_syscall		/* obsolete idle() syscall */
+	.long sys_ni_syscall		/* vm86old for i386 */
 	.long sys_wait4
-	.long sys_ni_syscall	/* 115 */ /* sys_swapoff */
+	.long sys_swapoff		/* 115 */
 	.long sys_sysinfo
 	.long sys_ipc
 	.long sys_fsync
 	.long sys_sigreturn
-	.long sys_clone		/* 120 */
+	.long sys_clone			/* 120 */
 	.long sys_setdomainname
 	.long sys_newuname
-	.long sys_cacheflush	/* modify_ldt for i386 */
+	.long sys_cacheflush		/* modify_ldt for i386 */
 	.long sys_adjtimex
-	.long sys_ni_syscall	/* 125 */ /* sys_mprotect */
+	.long sys_mprotect		/* 125 */
 	.long sys_sigprocmask
-	.long sys_ni_syscall	/* old "creat_module" */
+	.long sys_ni_syscall		/* old "create_module" */
 	.long sys_init_module
 	.long sys_delete_module
-	.long sys_ni_syscall	/* 130: old "get_kernel_syms" */
+	.long sys_ni_syscall		/* 130 - old "get_kernel_syms" */
 	.long sys_quotactl
 	.long sys_getpgid
 	.long sys_fchdir
 	.long sys_bdflush
-	.long sys_sysfs		/* 135 */
+	.long sys_sysfs			/* 135 */
 	.long sys_personality
-	.long sys_ni_syscall	/* for afs_syscall */
+	.long sys_ni_syscall		/* for afs_syscall */
 	.long sys_setfsuid16
 	.long sys_setfsgid16
-	.long sys_llseek	/* 140 */
+	.long sys_llseek		/* 140 */
 	.long sys_getdents
 	.long sys_select
 	.long sys_flock
-	.long sys_ni_syscall	/* sys_msync */
-	.long sys_readv		/* 145 */
+	.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_getparam	/* 155 */
 	.long sys_sched_setscheduler
 	.long sys_sched_getscheduler
 	.long sys_sched_yield
@@ -181,124 +183,124 @@
 	.long sys_sched_get_priority_min  /* 160 */
 	.long sys_sched_rr_get_interval
 	.long sys_nanosleep
-	.long sys_ni_syscall	/* sys_mremap */
+	.long sys_mremap
 	.long sys_setresuid16
-	.long sys_getresuid16	/* 165 */
-	.long sys_getpagesize	/* sys_getpagesize */
-	.long sys_ni_syscall	/* old "query_module" */
+	.long sys_getresuid16		/* 165 */
+	.long sys_getpagesize
+	.long sys_ni_syscall		/* old "query_module" */
 	.long sys_poll
-	.long sys_ni_syscall	/* sys_nfsservctl */
-	.long sys_setresgid16	/* 170 */
+	.long sys_nfsservctl
+	.long sys_setresgid16		/* 170 */
 	.long sys_getresgid16
 	.long sys_prctl
 	.long sys_rt_sigreturn
 	.long sys_rt_sigaction
-	.long sys_rt_sigprocmask /* 175 */
+	.long sys_rt_sigprocmask	/* 175 */
 	.long sys_rt_sigpending
 	.long sys_rt_sigtimedwait
 	.long sys_rt_sigqueueinfo
 	.long sys_rt_sigsuspend
-	.long sys_pread64	/* 180 */
+	.long sys_pread64		/* 180 */
 	.long sys_pwrite64
 	.long sys_lchown16
 	.long sys_getcwd
 	.long sys_capget
-	.long sys_capset	/* 185 */
+	.long sys_capset		/* 185 */
 	.long sys_sigaltstack
 	.long sys_sendfile
-	.long sys_ni_syscall	/* streams1 */
-	.long sys_ni_syscall	/* streams2 */
-	.long sys_vfork		/* 190 */
+	.long sys_ni_syscall		/* streams1 */
+	.long sys_ni_syscall		/* streams2 */
+	.long sys_vfork			/* 190 */
 	.long sys_getrlimit
-	.long sys_mmap_pgoff
+	.long sys_mmap2
 	.long sys_truncate64
 	.long sys_ftruncate64
-	.long sys_stat64	/* 195 */
+	.long sys_stat64		/* 195 */
 	.long sys_lstat64
 	.long sys_fstat64
 	.long sys_chown
 	.long sys_getuid
-	.long sys_getgid	/* 200 */
+	.long sys_getgid		/* 200 */
 	.long sys_geteuid
 	.long sys_getegid
 	.long sys_setreuid
 	.long sys_setregid
-	.long sys_getgroups	/* 205 */
+	.long sys_getgroups		/* 205 */
 	.long sys_setgroups
 	.long sys_fchown
 	.long sys_setresuid
 	.long sys_getresuid
-	.long sys_setresgid	/* 210 */
+	.long sys_setresgid		/* 210 */
 	.long sys_getresgid
 	.long sys_lchown
 	.long sys_setuid
 	.long sys_setgid
-	.long sys_setfsuid	/* 215 */
+	.long sys_setfsuid		/* 215 */
 	.long sys_setfsgid
 	.long sys_pivot_root
 	.long sys_ni_syscall
 	.long sys_ni_syscall
-	.long sys_getdents64	/* 220 */
+	.long sys_getdents64		/* 220 */
 	.long sys_gettid
 	.long sys_tkill
 	.long sys_setxattr
 	.long sys_lsetxattr
-	.long sys_fsetxattr	/* 225 */
+	.long sys_fsetxattr		/* 225 */
 	.long sys_getxattr
 	.long sys_lgetxattr
 	.long sys_fgetxattr
 	.long sys_listxattr
-	.long sys_llistxattr	/* 230 */
+	.long sys_llistxattr		/* 230 */
 	.long sys_flistxattr
 	.long sys_removexattr
 	.long sys_lremovexattr
 	.long sys_fremovexattr
-	.long sys_futex		/* 235 */
+	.long sys_futex			/* 235 */
 	.long sys_sendfile64
-	.long sys_ni_syscall	/* sys_mincore */
-	.long sys_ni_syscall	/* sys_madvise */
+	.long sys_mincore
+	.long sys_madvise
 	.long sys_fcntl64
-	.long sys_readahead	/* 240 */
+	.long sys_readahead		/* 240 */
 	.long sys_io_setup
 	.long sys_io_destroy
 	.long sys_io_getevents
 	.long sys_io_submit
-	.long sys_io_cancel	/* 245 */
+	.long sys_io_cancel		/* 245 */
 	.long sys_fadvise64
 	.long sys_exit_group
 	.long sys_lookup_dcookie
 	.long sys_epoll_create
-	.long sys_epoll_ctl	/* 250 */
+	.long sys_epoll_ctl		/* 250 */
 	.long sys_epoll_wait
-	.long sys_ni_syscall	/* sys_remap_file_pages */
+	.long sys_remap_file_pages
 	.long sys_set_tid_address
 	.long sys_timer_create
-	.long sys_timer_settime	/* 255 */
+	.long sys_timer_settime		/* 255 */
 	.long sys_timer_gettime
 	.long sys_timer_getoverrun
 	.long sys_timer_delete
 	.long sys_clock_settime
-	.long sys_clock_gettime	/* 260 */
+	.long sys_clock_gettime		/* 260 */
 	.long sys_clock_getres
 	.long sys_clock_nanosleep
 	.long sys_statfs64
 	.long sys_fstatfs64
-	.long sys_tgkill	/* 265 */
+	.long sys_tgkill		/* 265 */
 	.long sys_utimes
 	.long sys_fadvise64_64
-	.long sys_mbind	
+	.long sys_mbind
 	.long sys_get_mempolicy
-	.long sys_set_mempolicy	/* 270 */
+	.long sys_set_mempolicy		/* 270 */
 	.long sys_mq_open
 	.long sys_mq_unlink
 	.long sys_mq_timedsend
 	.long sys_mq_timedreceive
-	.long sys_mq_notify	/* 275 */
+	.long sys_mq_notify		/* 275 */
 	.long sys_mq_getsetattr
 	.long sys_waitid
-	.long sys_ni_syscall	/* for sys_vserver */
+	.long sys_ni_syscall		/* for sys_vserver */
 	.long sys_add_key
-	.long sys_request_key	/* 280 */
+	.long sys_request_key		/* 280 */
 	.long sys_keyctl
 	.long sys_ioprio_set
 	.long sys_ioprio_get
@@ -319,8 +321,8 @@
 	.long sys_readlinkat
 	.long sys_fchmodat
 	.long sys_faccessat		/* 300 */
-	.long sys_ni_syscall		/* Reserved for pselect6 */
-	.long sys_ni_syscall		/* Reserved for ppoll */
+	.long sys_pselect6
+	.long sys_ppoll
 	.long sys_unshare
 	.long sys_set_robust_list
 	.long sys_get_robust_list	/* 305 */
@@ -362,8 +364,5 @@
 	.long sys_open_by_handle_at
 	.long sys_clock_adjtime
 	.long sys_syncfs
-
-	.rept NR_syscalls-(.-sys_call_table)/4
-		.long sys_ni_syscall
-	.endr
+	.long sys_setns
 
diff -druN linux-2.6.39-libre/arch/m68k/kernel/sys_m68k.c linux-3.0-rc7-libre/arch/m68k/kernel/sys_m68k.c
--- linux-2.6.39-libre/arch/m68k/kernel/sys_m68k.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/m68k/kernel/sys_m68k.c	2011-07-11 19:51:52.000000000 -0400
@@ -1,5 +1,580 @@
+/*
+ * linux/arch/m68k/kernel/sys_m68k.c
+ *
+ * This file contains various random system calls that
+ * have a non-standard calling sequence on the Linux/m68k
+ * platform.
+ */
+
+#include <linux/capability.h>
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/fs.h>
+#include <linux/smp.h>
+#include <linux/sem.h>
+#include <linux/msg.h>
+#include <linux/shm.h>
+#include <linux/stat.h>
+#include <linux/syscalls.h>
+#include <linux/mman.h>
+#include <linux/file.h>
+#include <linux/ipc.h>
+
+#include <asm/setup.h>
+#include <asm/uaccess.h>
+#include <asm/cachectl.h>
+#include <asm/traps.h>
+#include <asm/page.h>
+#include <asm/unistd.h>
+#include <asm/cacheflush.h>
+
 #ifdef CONFIG_MMU
-#include "sys_m68k_mm.c"
+
+#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,
+	unsigned long fd, unsigned long pgoff)
+{
+	/*
+	 * This is wrong for sun3 - there PAGE_SIZE is 8Kb,
+	 * so we need to shift the argument down by 1; m68k mmap64(3)
+	 * (in libc) expects the last argument of mmap2 in 4Kb units.
+	 */
+	return sys_mmap_pgoff(addr, len, prot, flags, fd, pgoff);
+}
+
+/* Convert virtual (user) address VADDR to physical address PADDR */
+#define virt_to_phys_040(vaddr)						\
+({									\
+  unsigned long _mmusr, _paddr;						\
+									\
+  __asm__ __volatile__ (".chip 68040\n\t"				\
+			"ptestr (%1)\n\t"				\
+			"movec %%mmusr,%0\n\t"				\
+			".chip 68k"					\
+			: "=r" (_mmusr)					\
+			: "a" (vaddr));					\
+  _paddr = (_mmusr & MMU_R_040) ? (_mmusr & PAGE_MASK) : 0;		\
+  _paddr;								\
+})
+
+static inline int
+cache_flush_040 (unsigned long addr, int scope, int cache, unsigned long len)
+{
+  unsigned long paddr, i;
+
+  switch (scope)
+    {
+    case FLUSH_SCOPE_ALL:
+      switch (cache)
+	{
+	case FLUSH_CACHE_DATA:
+	  /* This nop is needed for some broken versions of the 68040.  */
+	  __asm__ __volatile__ ("nop\n\t"
+				".chip 68040\n\t"
+				"cpusha %dc\n\t"
+				".chip 68k");
+	  break;
+	case FLUSH_CACHE_INSN:
+	  __asm__ __volatile__ ("nop\n\t"
+				".chip 68040\n\t"
+				"cpusha %ic\n\t"
+				".chip 68k");
+	  break;
+	default:
+	case FLUSH_CACHE_BOTH:
+	  __asm__ __volatile__ ("nop\n\t"
+				".chip 68040\n\t"
+				"cpusha %bc\n\t"
+				".chip 68k");
+	  break;
+	}
+      break;
+
+    case FLUSH_SCOPE_LINE:
+      /* Find the physical address of the first mapped page in the
+	 address range.  */
+      if ((paddr = virt_to_phys_040(addr))) {
+        paddr += addr & ~(PAGE_MASK | 15);
+        len = (len + (addr & 15) + 15) >> 4;
+      } else {
+	unsigned long tmp = PAGE_SIZE - (addr & ~PAGE_MASK);
+
+	if (len <= tmp)
+	  return 0;
+	addr += tmp;
+	len -= tmp;
+	tmp = PAGE_SIZE;
+	for (;;)
+	  {
+	    if ((paddr = virt_to_phys_040(addr)))
+	      break;
+	    if (len <= tmp)
+	      return 0;
+	    addr += tmp;
+	    len -= tmp;
+	  }
+	len = (len + 15) >> 4;
+      }
+      i = (PAGE_SIZE - (paddr & ~PAGE_MASK)) >> 4;
+      while (len--)
+	{
+	  switch (cache)
+	    {
+	    case FLUSH_CACHE_DATA:
+	      __asm__ __volatile__ ("nop\n\t"
+				    ".chip 68040\n\t"
+				    "cpushl %%dc,(%0)\n\t"
+				    ".chip 68k"
+				    : : "a" (paddr));
+	      break;
+	    case FLUSH_CACHE_INSN:
+	      __asm__ __volatile__ ("nop\n\t"
+				    ".chip 68040\n\t"
+				    "cpushl %%ic,(%0)\n\t"
+				    ".chip 68k"
+				    : : "a" (paddr));
+	      break;
+	    default:
+	    case FLUSH_CACHE_BOTH:
+	      __asm__ __volatile__ ("nop\n\t"
+				    ".chip 68040\n\t"
+				    "cpushl %%bc,(%0)\n\t"
+				    ".chip 68k"
+				    : : "a" (paddr));
+	      break;
+	    }
+	  if (!--i && len)
+	    {
+	      /*
+	       * No need to page align here since it is done by
+	       * virt_to_phys_040().
+	       */
+	      addr += PAGE_SIZE;
+	      i = PAGE_SIZE / 16;
+	      /* Recompute physical address when crossing a page
+	         boundary. */
+	      for (;;)
+		{
+		  if ((paddr = virt_to_phys_040(addr)))
+		    break;
+		  if (len <= i)
+		    return 0;
+		  len -= i;
+		  addr += PAGE_SIZE;
+		}
+	    }
+	  else
+	    paddr += 16;
+	}
+      break;
+
+    default:
+    case FLUSH_SCOPE_PAGE:
+      len += (addr & ~PAGE_MASK) + (PAGE_SIZE - 1);
+      for (len >>= PAGE_SHIFT; len--; addr += PAGE_SIZE)
+	{
+	  if (!(paddr = virt_to_phys_040(addr)))
+	    continue;
+	  switch (cache)
+	    {
+	    case FLUSH_CACHE_DATA:
+	      __asm__ __volatile__ ("nop\n\t"
+				    ".chip 68040\n\t"
+				    "cpushp %%dc,(%0)\n\t"
+				    ".chip 68k"
+				    : : "a" (paddr));
+	      break;
+	    case FLUSH_CACHE_INSN:
+	      __asm__ __volatile__ ("nop\n\t"
+				    ".chip 68040\n\t"
+				    "cpushp %%ic,(%0)\n\t"
+				    ".chip 68k"
+				    : : "a" (paddr));
+	      break;
+	    default:
+	    case FLUSH_CACHE_BOTH:
+	      __asm__ __volatile__ ("nop\n\t"
+				    ".chip 68040\n\t"
+				    "cpushp %%bc,(%0)\n\t"
+				    ".chip 68k"
+				    : : "a" (paddr));
+	      break;
+	    }
+	}
+      break;
+    }
+  return 0;
+}
+
+#define virt_to_phys_060(vaddr)				\
+({							\
+  unsigned long paddr;					\
+  __asm__ __volatile__ (".chip 68060\n\t"		\
+			"plpar (%0)\n\t"		\
+			".chip 68k"			\
+			: "=a" (paddr)			\
+			: "0" (vaddr));			\
+  (paddr); /* XXX */					\
+})
+
+static inline int
+cache_flush_060 (unsigned long addr, int scope, int cache, unsigned long len)
+{
+  unsigned long paddr, i;
+
+  /*
+   * 68060 manual says:
+   *  cpush %dc : flush DC, remains valid (with our %cacr setup)
+   *  cpush %ic : invalidate IC
+   *  cpush %bc : flush DC + invalidate IC
+   */
+  switch (scope)
+    {
+    case FLUSH_SCOPE_ALL:
+      switch (cache)
+	{
+	case FLUSH_CACHE_DATA:
+	  __asm__ __volatile__ (".chip 68060\n\t"
+				"cpusha %dc\n\t"
+				".chip 68k");
+	  break;
+	case FLUSH_CACHE_INSN:
+	  __asm__ __volatile__ (".chip 68060\n\t"
+				"cpusha %ic\n\t"
+				".chip 68k");
+	  break;
+	default:
+	case FLUSH_CACHE_BOTH:
+	  __asm__ __volatile__ (".chip 68060\n\t"
+				"cpusha %bc\n\t"
+				".chip 68k");
+	  break;
+	}
+      break;
+
+    case FLUSH_SCOPE_LINE:
+      /* Find the physical address of the first mapped page in the
+	 address range.  */
+      len += addr & 15;
+      addr &= -16;
+      if (!(paddr = virt_to_phys_060(addr))) {
+	unsigned long tmp = PAGE_SIZE - (addr & ~PAGE_MASK);
+
+	if (len <= tmp)
+	  return 0;
+	addr += tmp;
+	len -= tmp;
+	tmp = PAGE_SIZE;
+	for (;;)
+	  {
+	    if ((paddr = virt_to_phys_060(addr)))
+	      break;
+	    if (len <= tmp)
+	      return 0;
+	    addr += tmp;
+	    len -= tmp;
+	  }
+      }
+      len = (len + 15) >> 4;
+      i = (PAGE_SIZE - (paddr & ~PAGE_MASK)) >> 4;
+      while (len--)
+	{
+	  switch (cache)
+	    {
+	    case FLUSH_CACHE_DATA:
+	      __asm__ __volatile__ (".chip 68060\n\t"
+				    "cpushl %%dc,(%0)\n\t"
+				    ".chip 68k"
+				    : : "a" (paddr));
+	      break;
+	    case FLUSH_CACHE_INSN:
+	      __asm__ __volatile__ (".chip 68060\n\t"
+				    "cpushl %%ic,(%0)\n\t"
+				    ".chip 68k"
+				    : : "a" (paddr));
+	      break;
+	    default:
+	    case FLUSH_CACHE_BOTH:
+	      __asm__ __volatile__ (".chip 68060\n\t"
+				    "cpushl %%bc,(%0)\n\t"
+				    ".chip 68k"
+				    : : "a" (paddr));
+	      break;
+	    }
+	  if (!--i && len)
+	    {
+
+	      /*
+	       * We just want to jump to the first cache line
+	       * in the next page.
+	       */
+	      addr += PAGE_SIZE;
+	      addr &= PAGE_MASK;
+
+	      i = PAGE_SIZE / 16;
+	      /* Recompute physical address when crossing a page
+	         boundary. */
+	      for (;;)
+	        {
+	          if ((paddr = virt_to_phys_060(addr)))
+	            break;
+	          if (len <= i)
+	            return 0;
+	          len -= i;
+	          addr += PAGE_SIZE;
+	        }
+	    }
+	  else
+	    paddr += 16;
+	}
+      break;
+
+    default:
+    case FLUSH_SCOPE_PAGE:
+      len += (addr & ~PAGE_MASK) + (PAGE_SIZE - 1);
+      addr &= PAGE_MASK;	/* Workaround for bug in some
+				   revisions of the 68060 */
+      for (len >>= PAGE_SHIFT; len--; addr += PAGE_SIZE)
+	{
+	  if (!(paddr = virt_to_phys_060(addr)))
+	    continue;
+	  switch (cache)
+	    {
+	    case FLUSH_CACHE_DATA:
+	      __asm__ __volatile__ (".chip 68060\n\t"
+				    "cpushp %%dc,(%0)\n\t"
+				    ".chip 68k"
+				    : : "a" (paddr));
+	      break;
+	    case FLUSH_CACHE_INSN:
+	      __asm__ __volatile__ (".chip 68060\n\t"
+				    "cpushp %%ic,(%0)\n\t"
+				    ".chip 68k"
+				    : : "a" (paddr));
+	      break;
+	    default:
+	    case FLUSH_CACHE_BOTH:
+	      __asm__ __volatile__ (".chip 68060\n\t"
+				    "cpushp %%bc,(%0)\n\t"
+				    ".chip 68k"
+				    : : "a" (paddr));
+	      break;
+	    }
+	}
+      break;
+    }
+  return 0;
+}
+
+/* sys_cacheflush -- flush (part of) the processor cache.  */
+asmlinkage int
+sys_cacheflush (unsigned long addr, int scope, int cache, unsigned long len)
+{
+	struct vm_area_struct *vma;
+	int ret = -EINVAL;
+
+	if (scope < FLUSH_SCOPE_LINE || scope > FLUSH_SCOPE_ALL ||
+	    cache & ~FLUSH_CACHE_BOTH)
+		goto out;
+
+	if (scope == FLUSH_SCOPE_ALL) {
+		/* Only the superuser may explicitly flush the whole cache. */
+		ret = -EPERM;
+		if (!capable(CAP_SYS_ADMIN))
+			goto out;
+	} else {
+		/*
+		 * Verify that the specified address region actually belongs
+		 * to this process.
+		 */
+		vma = find_vma (current->mm, addr);
+		ret = -EINVAL;
+		/* Check for overflow.  */
+		if (addr + len < addr)
+			goto out;
+		if (vma == NULL || addr < vma->vm_start || addr + len > vma->vm_end)
+			goto out;
+	}
+
+	if (CPU_IS_020_OR_030) {
+		if (scope == FLUSH_SCOPE_LINE && len < 256) {
+			unsigned long cacr;
+			__asm__ ("movec %%cacr, %0" : "=r" (cacr));
+			if (cache & FLUSH_CACHE_INSN)
+				cacr |= 4;
+			if (cache & FLUSH_CACHE_DATA)
+				cacr |= 0x400;
+			len >>= 2;
+			while (len--) {
+				__asm__ __volatile__ ("movec %1, %%caar\n\t"
+						      "movec %0, %%cacr"
+						      : /* no outputs */
+						      : "r" (cacr), "r" (addr));
+				addr += 4;
+			}
+		} else {
+			/* Flush the whole cache, even if page granularity requested. */
+			unsigned long cacr;
+			__asm__ ("movec %%cacr, %0" : "=r" (cacr));
+			if (cache & FLUSH_CACHE_INSN)
+				cacr |= 8;
+			if (cache & FLUSH_CACHE_DATA)
+				cacr |= 0x800;
+			__asm__ __volatile__ ("movec %0, %%cacr" : : "r" (cacr));
+		}
+		ret = 0;
+		goto out;
+	} else {
+	    /*
+	     * 040 or 060: don't blindly trust 'scope', someone could
+	     * try to flush a few megs of memory.
+	     */
+
+	    if (len>=3*PAGE_SIZE && scope<FLUSH_SCOPE_PAGE)
+	        scope=FLUSH_SCOPE_PAGE;
+	    if (len>=10*PAGE_SIZE && scope<FLUSH_SCOPE_ALL)
+	        scope=FLUSH_SCOPE_ALL;
+	    if (CPU_IS_040) {
+		ret = cache_flush_040 (addr, scope, cache, len);
+	    } else if (CPU_IS_060) {
+		ret = cache_flush_060 (addr, scope, cache, len);
+	    }
+	}
+out:
+	return ret;
+}
+
+/* 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;
+		}
+	}
+}
+
 #else
-#include "sys_m68k_no.c"
-#endif
+
+/* sys_cacheflush -- flush (part of) the processor cache.  */
+asmlinkage int
+sys_cacheflush (unsigned long addr, int scope, int cache, unsigned long len)
+{
+	flush_cache_all();
+	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;
+}
+
+#endif /* CONFIG_MMU */
+
+asmlinkage int sys_getpagesize(void)
+{
+	return PAGE_SIZE;
+}
+
+/*
+ * Do a system call from kernel instead of calling sys_execve so we
+ * end up with proper pt_regs.
+ */
+int kernel_execve(const char *filename,
+		  const char *const argv[],
+		  const char *const envp[])
+{
+	register long __res asm ("%d0") = __NR_execve;
+	register long __a asm ("%d1") = (long)(filename);
+	register long __b asm ("%d2") = (long)(argv);
+	register long __c asm ("%d3") = (long)(envp);
+	asm volatile ("trap  #0" : "+d" (__res)
+			: "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;
+}
+
+asmlinkage int sys_atomic_barrier(void)
+{
+	/* no code needed for uniprocs */
+	return 0;
+}
diff -druN linux-2.6.39-libre/arch/m68k/kernel/sys_m68k_mm.c linux-3.0-rc7-libre/arch/m68k/kernel/sys_m68k_mm.c
--- linux-2.6.39-libre/arch/m68k/kernel/sys_m68k_mm.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/m68k/kernel/sys_m68k_mm.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,546 +0,0 @@
-/*
- * linux/arch/m68k/kernel/sys_m68k.c
- *
- * This file contains various random system calls that
- * have a non-standard calling sequence on the Linux/m68k
- * platform.
- */
-
-#include <linux/capability.h>
-#include <linux/errno.h>
-#include <linux/sched.h>
-#include <linux/mm.h>
-#include <linux/fs.h>
-#include <linux/smp.h>
-#include <linux/sem.h>
-#include <linux/msg.h>
-#include <linux/shm.h>
-#include <linux/stat.h>
-#include <linux/syscalls.h>
-#include <linux/mman.h>
-#include <linux/file.h>
-#include <linux/ipc.h>
-
-#include <asm/setup.h>
-#include <asm/uaccess.h>
-#include <asm/cachectl.h>
-#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,
-	unsigned long fd, unsigned long pgoff)
-{
-	/*
-	 * This is wrong for sun3 - there PAGE_SIZE is 8Kb,
-	 * so we need to shift the argument down by 1; m68k mmap64(3)
-	 * (in libc) expects the last argument of mmap2 in 4Kb units.
-	 */
-	return sys_mmap_pgoff(addr, len, prot, flags, fd, pgoff);
-}
-
-/* Convert virtual (user) address VADDR to physical address PADDR */
-#define virt_to_phys_040(vaddr)						\
-({									\
-  unsigned long _mmusr, _paddr;						\
-									\
-  __asm__ __volatile__ (".chip 68040\n\t"				\
-			"ptestr (%1)\n\t"				\
-			"movec %%mmusr,%0\n\t"				\
-			".chip 68k"					\
-			: "=r" (_mmusr)					\
-			: "a" (vaddr));					\
-  _paddr = (_mmusr & MMU_R_040) ? (_mmusr & PAGE_MASK) : 0;		\
-  _paddr;								\
-})
-
-static inline int
-cache_flush_040 (unsigned long addr, int scope, int cache, unsigned long len)
-{
-  unsigned long paddr, i;
-
-  switch (scope)
-    {
-    case FLUSH_SCOPE_ALL:
-      switch (cache)
-	{
-	case FLUSH_CACHE_DATA:
-	  /* This nop is needed for some broken versions of the 68040.  */
-	  __asm__ __volatile__ ("nop\n\t"
-				".chip 68040\n\t"
-				"cpusha %dc\n\t"
-				".chip 68k");
-	  break;
-	case FLUSH_CACHE_INSN:
-	  __asm__ __volatile__ ("nop\n\t"
-				".chip 68040\n\t"
-				"cpusha %ic\n\t"
-				".chip 68k");
-	  break;
-	default:
-	case FLUSH_CACHE_BOTH:
-	  __asm__ __volatile__ ("nop\n\t"
-				".chip 68040\n\t"
-				"cpusha %bc\n\t"
-				".chip 68k");
-	  break;
-	}
-      break;
-
-    case FLUSH_SCOPE_LINE:
-      /* Find the physical address of the first mapped page in the
-	 address range.  */
-      if ((paddr = virt_to_phys_040(addr))) {
-        paddr += addr & ~(PAGE_MASK | 15);
-        len = (len + (addr & 15) + 15) >> 4;
-      } else {
-	unsigned long tmp = PAGE_SIZE - (addr & ~PAGE_MASK);
-
-	if (len <= tmp)
-	  return 0;
-	addr += tmp;
-	len -= tmp;
-	tmp = PAGE_SIZE;
-	for (;;)
-	  {
-	    if ((paddr = virt_to_phys_040(addr)))
-	      break;
-	    if (len <= tmp)
-	      return 0;
-	    addr += tmp;
-	    len -= tmp;
-	  }
-	len = (len + 15) >> 4;
-      }
-      i = (PAGE_SIZE - (paddr & ~PAGE_MASK)) >> 4;
-      while (len--)
-	{
-	  switch (cache)
-	    {
-	    case FLUSH_CACHE_DATA:
-	      __asm__ __volatile__ ("nop\n\t"
-				    ".chip 68040\n\t"
-				    "cpushl %%dc,(%0)\n\t"
-				    ".chip 68k"
-				    : : "a" (paddr));
-	      break;
-	    case FLUSH_CACHE_INSN:
-	      __asm__ __volatile__ ("nop\n\t"
-				    ".chip 68040\n\t"
-				    "cpushl %%ic,(%0)\n\t"
-				    ".chip 68k"
-				    : : "a" (paddr));
-	      break;
-	    default:
-	    case FLUSH_CACHE_BOTH:
-	      __asm__ __volatile__ ("nop\n\t"
-				    ".chip 68040\n\t"
-				    "cpushl %%bc,(%0)\n\t"
-				    ".chip 68k"
-				    : : "a" (paddr));
-	      break;
-	    }
-	  if (!--i && len)
-	    {
-	      /*
-	       * No need to page align here since it is done by
-	       * virt_to_phys_040().
-	       */
-	      addr += PAGE_SIZE;
-	      i = PAGE_SIZE / 16;
-	      /* Recompute physical address when crossing a page
-	         boundary. */
-	      for (;;)
-		{
-		  if ((paddr = virt_to_phys_040(addr)))
-		    break;
-		  if (len <= i)
-		    return 0;
-		  len -= i;
-		  addr += PAGE_SIZE;
-		}
-	    }
-	  else
-	    paddr += 16;
-	}
-      break;
-
-    default:
-    case FLUSH_SCOPE_PAGE:
-      len += (addr & ~PAGE_MASK) + (PAGE_SIZE - 1);
-      for (len >>= PAGE_SHIFT; len--; addr += PAGE_SIZE)
-	{
-	  if (!(paddr = virt_to_phys_040(addr)))
-	    continue;
-	  switch (cache)
-	    {
-	    case FLUSH_CACHE_DATA:
-	      __asm__ __volatile__ ("nop\n\t"
-				    ".chip 68040\n\t"
-				    "cpushp %%dc,(%0)\n\t"
-				    ".chip 68k"
-				    : : "a" (paddr));
-	      break;
-	    case FLUSH_CACHE_INSN:
-	      __asm__ __volatile__ ("nop\n\t"
-				    ".chip 68040\n\t"
-				    "cpushp %%ic,(%0)\n\t"
-				    ".chip 68k"
-				    : : "a" (paddr));
-	      break;
-	    default:
-	    case FLUSH_CACHE_BOTH:
-	      __asm__ __volatile__ ("nop\n\t"
-				    ".chip 68040\n\t"
-				    "cpushp %%bc,(%0)\n\t"
-				    ".chip 68k"
-				    : : "a" (paddr));
-	      break;
-	    }
-	}
-      break;
-    }
-  return 0;
-}
-
-#define virt_to_phys_060(vaddr)				\
-({							\
-  unsigned long paddr;					\
-  __asm__ __volatile__ (".chip 68060\n\t"		\
-			"plpar (%0)\n\t"		\
-			".chip 68k"			\
-			: "=a" (paddr)			\
-			: "0" (vaddr));			\
-  (paddr); /* XXX */					\
-})
-
-static inline int
-cache_flush_060 (unsigned long addr, int scope, int cache, unsigned long len)
-{
-  unsigned long paddr, i;
-
-  /*
-   * 68060 manual says:
-   *  cpush %dc : flush DC, remains valid (with our %cacr setup)
-   *  cpush %ic : invalidate IC
-   *  cpush %bc : flush DC + invalidate IC
-   */
-  switch (scope)
-    {
-    case FLUSH_SCOPE_ALL:
-      switch (cache)
-	{
-	case FLUSH_CACHE_DATA:
-	  __asm__ __volatile__ (".chip 68060\n\t"
-				"cpusha %dc\n\t"
-				".chip 68k");
-	  break;
-	case FLUSH_CACHE_INSN:
-	  __asm__ __volatile__ (".chip 68060\n\t"
-				"cpusha %ic\n\t"
-				".chip 68k");
-	  break;
-	default:
-	case FLUSH_CACHE_BOTH:
-	  __asm__ __volatile__ (".chip 68060\n\t"
-				"cpusha %bc\n\t"
-				".chip 68k");
-	  break;
-	}
-      break;
-
-    case FLUSH_SCOPE_LINE:
-      /* Find the physical address of the first mapped page in the
-	 address range.  */
-      len += addr & 15;
-      addr &= -16;
-      if (!(paddr = virt_to_phys_060(addr))) {
-	unsigned long tmp = PAGE_SIZE - (addr & ~PAGE_MASK);
-
-	if (len <= tmp)
-	  return 0;
-	addr += tmp;
-	len -= tmp;
-	tmp = PAGE_SIZE;
-	for (;;)
-	  {
-	    if ((paddr = virt_to_phys_060(addr)))
-	      break;
-	    if (len <= tmp)
-	      return 0;
-	    addr += tmp;
-	    len -= tmp;
-	  }
-      }
-      len = (len + 15) >> 4;
-      i = (PAGE_SIZE - (paddr & ~PAGE_MASK)) >> 4;
-      while (len--)
-	{
-	  switch (cache)
-	    {
-	    case FLUSH_CACHE_DATA:
-	      __asm__ __volatile__ (".chip 68060\n\t"
-				    "cpushl %%dc,(%0)\n\t"
-				    ".chip 68k"
-				    : : "a" (paddr));
-	      break;
-	    case FLUSH_CACHE_INSN:
-	      __asm__ __volatile__ (".chip 68060\n\t"
-				    "cpushl %%ic,(%0)\n\t"
-				    ".chip 68k"
-				    : : "a" (paddr));
-	      break;
-	    default:
-	    case FLUSH_CACHE_BOTH:
-	      __asm__ __volatile__ (".chip 68060\n\t"
-				    "cpushl %%bc,(%0)\n\t"
-				    ".chip 68k"
-				    : : "a" (paddr));
-	      break;
-	    }
-	  if (!--i && len)
-	    {
-
-	      /*
-	       * We just want to jump to the first cache line
-	       * in the next page.
-	       */
-	      addr += PAGE_SIZE;
-	      addr &= PAGE_MASK;
-
-	      i = PAGE_SIZE / 16;
-	      /* Recompute physical address when crossing a page
-	         boundary. */
-	      for (;;)
-	        {
-	          if ((paddr = virt_to_phys_060(addr)))
-	            break;
-	          if (len <= i)
-	            return 0;
-	          len -= i;
-	          addr += PAGE_SIZE;
-	        }
-	    }
-	  else
-	    paddr += 16;
-	}
-      break;
-
-    default:
-    case FLUSH_SCOPE_PAGE:
-      len += (addr & ~PAGE_MASK) + (PAGE_SIZE - 1);
-      addr &= PAGE_MASK;	/* Workaround for bug in some
-				   revisions of the 68060 */
-      for (len >>= PAGE_SHIFT; len--; addr += PAGE_SIZE)
-	{
-	  if (!(paddr = virt_to_phys_060(addr)))
-	    continue;
-	  switch (cache)
-	    {
-	    case FLUSH_CACHE_DATA:
-	      __asm__ __volatile__ (".chip 68060\n\t"
-				    "cpushp %%dc,(%0)\n\t"
-				    ".chip 68k"
-				    : : "a" (paddr));
-	      break;
-	    case FLUSH_CACHE_INSN:
-	      __asm__ __volatile__ (".chip 68060\n\t"
-				    "cpushp %%ic,(%0)\n\t"
-				    ".chip 68k"
-				    : : "a" (paddr));
-	      break;
-	    default:
-	    case FLUSH_CACHE_BOTH:
-	      __asm__ __volatile__ (".chip 68060\n\t"
-				    "cpushp %%bc,(%0)\n\t"
-				    ".chip 68k"
-				    : : "a" (paddr));
-	      break;
-	    }
-	}
-      break;
-    }
-  return 0;
-}
-
-/* sys_cacheflush -- flush (part of) the processor cache.  */
-asmlinkage int
-sys_cacheflush (unsigned long addr, int scope, int cache, unsigned long len)
-{
-	struct vm_area_struct *vma;
-	int ret = -EINVAL;
-
-	if (scope < FLUSH_SCOPE_LINE || scope > FLUSH_SCOPE_ALL ||
-	    cache & ~FLUSH_CACHE_BOTH)
-		goto out;
-
-	if (scope == FLUSH_SCOPE_ALL) {
-		/* Only the superuser may explicitly flush the whole cache. */
-		ret = -EPERM;
-		if (!capable(CAP_SYS_ADMIN))
-			goto out;
-	} else {
-		/*
-		 * Verify that the specified address region actually belongs
-		 * to this process.
-		 */
-		vma = find_vma (current->mm, addr);
-		ret = -EINVAL;
-		/* Check for overflow.  */
-		if (addr + len < addr)
-			goto out;
-		if (vma == NULL || addr < vma->vm_start || addr + len > vma->vm_end)
-			goto out;
-	}
-
-	if (CPU_IS_020_OR_030) {
-		if (scope == FLUSH_SCOPE_LINE && len < 256) {
-			unsigned long cacr;
-			__asm__ ("movec %%cacr, %0" : "=r" (cacr));
-			if (cache & FLUSH_CACHE_INSN)
-				cacr |= 4;
-			if (cache & FLUSH_CACHE_DATA)
-				cacr |= 0x400;
-			len >>= 2;
-			while (len--) {
-				__asm__ __volatile__ ("movec %1, %%caar\n\t"
-						      "movec %0, %%cacr"
-						      : /* no outputs */
-						      : "r" (cacr), "r" (addr));
-				addr += 4;
-			}
-		} else {
-			/* Flush the whole cache, even if page granularity requested. */
-			unsigned long cacr;
-			__asm__ ("movec %%cacr, %0" : "=r" (cacr));
-			if (cache & FLUSH_CACHE_INSN)
-				cacr |= 8;
-			if (cache & FLUSH_CACHE_DATA)
-				cacr |= 0x800;
-			__asm__ __volatile__ ("movec %0, %%cacr" : : "r" (cacr));
-		}
-		ret = 0;
-		goto out;
-	} else {
-	    /*
-	     * 040 or 060: don't blindly trust 'scope', someone could
-	     * try to flush a few megs of memory.
-	     */
-
-	    if (len>=3*PAGE_SIZE && scope<FLUSH_SCOPE_PAGE)
-	        scope=FLUSH_SCOPE_PAGE;
-	    if (len>=10*PAGE_SIZE && scope<FLUSH_SCOPE_ALL)
-	        scope=FLUSH_SCOPE_ALL;
-	    if (CPU_IS_040) {
-		ret = cache_flush_040 (addr, scope, cache, len);
-	    } else if (CPU_IS_060) {
-		ret = cache_flush_060 (addr, scope, cache, len);
-	    }
-	}
-out:
-	return ret;
-}
-
-asmlinkage int sys_getpagesize(void)
-{
-	return PAGE_SIZE;
-}
-
-/*
- * Do a system call from kernel instead of calling sys_execve so we
- * end up with proper pt_regs.
- */
-int kernel_execve(const char *filename,
-		  const char *const argv[],
-		  const char *const envp[])
-{
-	register long __res asm ("%d0") = __NR_execve;
-	register long __a asm ("%d1") = (long)(filename);
-	register long __b asm ("%d2") = (long)(argv);
-	register long __c asm ("%d3") = (long)(envp);
-	asm volatile ("trap  #0" : "+d" (__res)
-			: "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 -druN linux-2.6.39-libre/arch/m68k/kernel/sys_m68k_no.c linux-3.0-rc7-libre/arch/m68k/kernel/sys_m68k_no.c
--- linux-2.6.39-libre/arch/m68k/kernel/sys_m68k_no.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/m68k/kernel/sys_m68k_no.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,94 +0,0 @@
-/*
- * linux/arch/m68knommu/kernel/sys_m68k.c
- *
- * This file contains various random system calls that
- * have a non-standard calling sequence on the Linux/m68k
- * platform.
- */
-
-#include <linux/errno.h>
-#include <linux/sched.h>
-#include <linux/mm.h>
-#include <linux/smp.h>
-#include <linux/sem.h>
-#include <linux/msg.h>
-#include <linux/shm.h>
-#include <linux/stat.h>
-#include <linux/syscalls.h>
-#include <linux/mman.h>
-#include <linux/file.h>
-#include <linux/ipc.h>
-#include <linux/fs.h>
-
-#include <asm/setup.h>
-#include <asm/uaccess.h>
-#include <asm/cachectl.h>
-#include <asm/traps.h>
-#include <asm/cacheflush.h>
-#include <asm/unistd.h>
-
-/* sys_cacheflush -- flush (part of) the processor cache.  */
-asmlinkage int
-sys_cacheflush (unsigned long addr, int scope, int cache, unsigned long len)
-{
-	flush_cache_all();
-	return(0);
-}
-
-asmlinkage int sys_getpagesize(void)
-{
-	return PAGE_SIZE;
-}
-
-/*
- * Do a system call from kernel instead of calling sys_execve so we
- * end up with proper pt_regs.
- */
-int kernel_execve(const char *filename,
-		  const char *const argv[],
-		  const char *const envp[])
-{
-	register long __res asm ("%d0") = __NR_execve;
-	register long __a asm ("%d1") = (long)(filename);
-	register long __b asm ("%d2") = (long)(argv);
-	register long __c asm ("%d3") = (long)(envp);
-	asm volatile ("trap  #0" : "+d" (__res)
-			: "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 -druN linux-2.6.39-libre/arch/m68k/kernel/vmlinux.lds_no.S linux-3.0-rc7-libre/arch/m68k/kernel/vmlinux.lds_no.S
--- linux-2.6.39-libre/arch/m68k/kernel/vmlinux.lds_no.S	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/m68k/kernel/vmlinux.lds_no.S	2011-07-11 19:51:52.000000000 -0400
@@ -84,52 +84,52 @@
 		/* Kernel symbol table: Normal symbols */
 		. = ALIGN(4);
 		__start___ksymtab = .;
-		*(__ksymtab)
+		*(SORT(___ksymtab+*))
 		__stop___ksymtab = .;
 
 		/* Kernel symbol table: GPL-only symbols */
 		__start___ksymtab_gpl = .;
-		*(__ksymtab_gpl)
+		*(SORT(___ksymtab_gpl+*))
 		__stop___ksymtab_gpl = .;
 
 		/* Kernel symbol table: Normal unused symbols */
 		__start___ksymtab_unused = .;
-		*(__ksymtab_unused)
+		*(SORT(___ksymtab_unused+*))
 		__stop___ksymtab_unused = .;
 
 		/* Kernel symbol table: GPL-only unused symbols */
 		__start___ksymtab_unused_gpl = .;
-		*(__ksymtab_unused_gpl)
+		*(SORT(___ksymtab_unused_gpl+*))
 		__stop___ksymtab_unused_gpl = .;
 
 		/* Kernel symbol table: GPL-future symbols */
 		__start___ksymtab_gpl_future = .;
-		*(__ksymtab_gpl_future)
+		*(SORT(___ksymtab_gpl_future+*))
 		__stop___ksymtab_gpl_future = .;
 
 		/* Kernel symbol table: Normal symbols */
 		__start___kcrctab = .;
-		*(__kcrctab)
+		*(SORT(___kcrctab+*))
 		__stop___kcrctab = .;
 
 		/* Kernel symbol table: GPL-only symbols */
 		__start___kcrctab_gpl = .;
-		*(__kcrctab_gpl)
+		*(SORT(___kcrctab_gpl+*))
 		__stop___kcrctab_gpl = .;
 
 		/* Kernel symbol table: Normal unused symbols */
 		__start___kcrctab_unused = .;
-		*(__kcrctab_unused)
+		*(SORT(___kcrctab_unused+*))
 		__stop___kcrctab_unused = .;
 
 		/* Kernel symbol table: GPL-only unused symbols */
 		__start___kcrctab_unused_gpl = .;
-		*(__kcrctab_unused_gpl)
+		*(SORT(___kcrctab_unused_gpl+*))
 		__stop___kcrctab_unused_gpl = .;
 
 		/* Kernel symbol table: GPL-future symbols */
 		__start___kcrctab_gpl_future = .;
-		*(__kcrctab_gpl_future)
+		*(SORT(___kcrctab_gpl_future+*))
 		__stop___kcrctab_gpl_future = .;
 
 		/* Kernel symbol table: strings */
diff -druN linux-2.6.39-libre/arch/m68k/kernel/vmlinux-std.lds linux-3.0-rc7-libre/arch/m68k/kernel/vmlinux-std.lds
--- linux-2.6.39-libre/arch/m68k/kernel/vmlinux-std.lds	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/m68k/kernel/vmlinux-std.lds	2011-07-11 19:51:52.000000000 -0400
@@ -25,6 +25,8 @@
 
   EXCEPTION_TABLE(16)
 
+  _sdata = .;			/* Start of data section */
+
   RODATA
 
   RW_DATA_SECTION(16, PAGE_SIZE, THREAD_SIZE)
diff -druN linux-2.6.39-libre/arch/m68k/kernel/vmlinux-sun3.lds linux-3.0-rc7-libre/arch/m68k/kernel/vmlinux-sun3.lds
--- linux-2.6.39-libre/arch/m68k/kernel/vmlinux-sun3.lds	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/m68k/kernel/vmlinux-sun3.lds	2011-07-11 19:51:52.000000000 -0400
@@ -25,6 +25,7 @@
   _etext = .;			/* End of text section */
 
   EXCEPTION_TABLE(16) :data
+  _sdata = .;			/* Start of rw data section */
   RW_DATA_SECTION(16, PAGE_SIZE, THREAD_SIZE) :data
   /* End of data goes *here* so that freeing init code works properly. */
   _edata = .;
diff -druN linux-2.6.39-libre/arch/m68k/lib/checksum.c linux-3.0-rc7-libre/arch/m68k/lib/checksum.c
--- linux-2.6.39-libre/arch/m68k/lib/checksum.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/m68k/lib/checksum.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,5 +0,0 @@
-#ifdef CONFIG_MMU
-#include "checksum_mm.c"
-#else
-#include "checksum_no.c"
-#endif
diff -druN linux-2.6.39-libre/arch/m68k/lib/checksum_no.c linux-3.0-rc7-libre/arch/m68k/lib/checksum_no.c
--- linux-2.6.39-libre/arch/m68k/lib/checksum_no.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/m68k/lib/checksum_no.c	2011-07-11 19:51:52.000000000 -0400
@@ -101,6 +101,7 @@
 {
 	return (__force __sum16)~do_csum(iph,ihl*4);
 }
+EXPORT_SYMBOL(ip_fast_csum);
 #endif
 
 /*
@@ -140,6 +141,7 @@
 	memcpy(dst, (__force const void *)src, len);
 	return csum_partial(dst, len, sum);
 }
+EXPORT_SYMBOL(csum_partial_copy_from_user);
 
 /*
  * copy from ds while checksumming, otherwise like csum_partial
@@ -151,3 +153,4 @@
 	memcpy(dst, src, len);
 	return csum_partial(dst, len, sum);
 }
+EXPORT_SYMBOL(csum_partial_copy_nocheck);
diff -druN linux-2.6.39-libre/arch/m68k/lib/Makefile linux-3.0-rc7-libre/arch/m68k/lib/Makefile
--- linux-2.6.39-libre/arch/m68k/lib/Makefile	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/m68k/lib/Makefile	2011-07-11 19:51:52.000000000 -0400
@@ -1,5 +1,14 @@
+
+#
+# Makefile for m68k-specific library files..
+#
+
+lib-y	:= ashldi3.o ashrdi3.o lshrdi3.o muldi3.o \
+	   memcpy.o memset.o memmove.o
+
 ifdef CONFIG_MMU
-include arch/m68k/lib/Makefile_mm
+lib-y	+= string.o uaccess.o checksum_mm.o
 else
-include arch/m68k/lib/Makefile_no
+lib-y	+= mulsi3.o divsi3.o udivsi3.o modsi3.o umodsi3.o delay.o checksum_no.o
 endif
+
diff -druN linux-2.6.39-libre/arch/m68k/lib/Makefile_mm linux-3.0-rc7-libre/arch/m68k/lib/Makefile_mm
--- linux-2.6.39-libre/arch/m68k/lib/Makefile_mm	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/m68k/lib/Makefile_mm	1969-12-31 19:00:00.000000000 -0500
@@ -1,6 +0,0 @@
-#
-# Makefile for m68k-specific library files..
-#
-
-lib-y	:= ashldi3.o ashrdi3.o lshrdi3.o muldi3.o \
-	   checksum.o string.o uaccess.o
diff -druN linux-2.6.39-libre/arch/m68k/lib/Makefile_no linux-3.0-rc7-libre/arch/m68k/lib/Makefile_no
--- linux-2.6.39-libre/arch/m68k/lib/Makefile_no	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/m68k/lib/Makefile_no	1969-12-31 19:00:00.000000000 -0500
@@ -1,7 +0,0 @@
-#
-# Makefile for m68knommu specific library files..
-#
-
-lib-y	:= ashldi3.o ashrdi3.o lshrdi3.o \
-	   muldi3.o mulsi3.o divsi3.o udivsi3.o modsi3.o umodsi3.o \
-	   checksum.o memcpy.o memmove.o memset.o delay.o
diff -druN linux-2.6.39-libre/arch/m68k/lib/memcpy.c linux-3.0-rc7-libre/arch/m68k/lib/memcpy.c
--- linux-2.6.39-libre/arch/m68k/lib/memcpy.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/m68k/lib/memcpy.c	2011-07-11 19:51:52.000000000 -0400
@@ -1,62 +1,79 @@
+/*
+ * 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/module.h>
+#include <linux/string.h>
 
-void * memcpy(void * to, const void * from, size_t n)
+void *memcpy(void *to, const void *from, size_t n)
 {
-#ifdef CONFIG_COLDFIRE
-  void *xto = to;
-  size_t temp;
+	void *xto = to;
+	size_t temp, temp1;
 
-  if (!n)
-    return xto;
-  if ((long) to & 1)
-    {
-      char *cto = to;
-      const char *cfrom = from;
-      *cto++ = *cfrom++;
-      to = cto;
-      from = cfrom;
-      n--;
-    }
-  if (n > 2 && (long) to & 2)
-    {
-      short *sto = to;
-      const short *sfrom = from;
-      *sto++ = *sfrom++;
-      to = sto;
-      from = sfrom;
-      n -= 2;
-    }
-  temp = n >> 2;
-  if (temp)
-    {
-      long *lto = to;
-      const long *lfrom = from;
-      for (; temp; temp--)
-	*lto++ = *lfrom++;
-      to = lto;
-      from = lfrom;
-    }
-  if (n & 2)
-    {
-      short *sto = to;
-      const short *sfrom = from;
-      *sto++ = *sfrom++;
-      to = sto;
-      from = sfrom;
-    }
-  if (n & 1)
-    {
-      char *cto = to;
-      const char *cfrom = from;
-      *cto = *cfrom;
-    }
-  return xto;
+	if (!n)
+		return xto;
+	if ((long)to & 1) {
+		char *cto = to;
+		const char *cfrom = from;
+		*cto++ = *cfrom++;
+		to = cto;
+		from = cfrom;
+		n--;
+	}
+	if (n > 2 && (long)to & 2) {
+		short *sto = to;
+		const short *sfrom = from;
+		*sto++ = *sfrom++;
+		to = sto;
+		from = sfrom;
+		n -= 2;
+	}
+	temp = n >> 2;
+	if (temp) {
+		long *lto = to;
+		const long *lfrom = from;
+#if defined(CONFIG_M68000) || defined(CONFIG_COLDFIRE)
+		for (; temp; temp--)
+			*lto++ = *lfrom++;
 #else
-  const char *c_from = from;
-  char *c_to = to;
-  while (n-- > 0)
-    *c_to++ = *c_from++;
-  return((void *) to);
+		asm volatile (
+			"	movel %2,%3\n"
+			"	andw  #7,%3\n"
+			"	lsrl  #3,%2\n"
+			"	negw  %3\n"
+			"	jmp   %%pc@(1f,%3:w:2)\n"
+			"4:	movel %0@+,%1@+\n"
+			"	movel %0@+,%1@+\n"
+			"	movel %0@+,%1@+\n"
+			"	movel %0@+,%1@+\n"
+			"	movel %0@+,%1@+\n"
+			"	movel %0@+,%1@+\n"
+			"	movel %0@+,%1@+\n"
+			"	movel %0@+,%1@+\n"
+			"1:	dbra  %2,4b\n"
+			"	clrw  %2\n"
+			"	subql #1,%2\n"
+			"	jpl   4b"
+			: "=a" (lfrom), "=a" (lto), "=d" (temp), "=&d" (temp1)
+			: "0" (lfrom), "1" (lto), "2" (temp));
 #endif
+		to = lto;
+		from = lfrom;
+	}
+	if (n & 2) {
+		short *sto = to;
+		const short *sfrom = from;
+		*sto++ = *sfrom++;
+		to = sto;
+		from = sfrom;
+	}
+	if (n & 1) {
+		char *cto = to;
+		const char *cfrom = from;
+		*cto = *cfrom;
+	}
+	return xto;
 }
+EXPORT_SYMBOL(memcpy);
diff -druN linux-2.6.39-libre/arch/m68k/lib/memmove.c linux-3.0-rc7-libre/arch/m68k/lib/memmove.c
--- linux-2.6.39-libre/arch/m68k/lib/memmove.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/m68k/lib/memmove.c	2011-07-11 19:51:52.000000000 -0400
@@ -4,8 +4,6 @@
  * for more details.
  */
 
-#define __IN_STRING_C
-
 #include <linux/module.h>
 #include <linux/string.h>
 
diff -druN linux-2.6.39-libre/arch/m68k/lib/memset.c linux-3.0-rc7-libre/arch/m68k/lib/memset.c
--- linux-2.6.39-libre/arch/m68k/lib/memset.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/m68k/lib/memset.c	2011-07-11 19:51:52.000000000 -0400
@@ -1,47 +1,74 @@
-#include <linux/types.h>
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file COPYING in the main directory of this archive
+ * for more details.
+ */
 
-void * memset(void * s, int c, size_t count)
+#include <linux/module.h>
+#include <linux/string.h>
+
+void *memset(void *s, int c, size_t count)
 {
-  void *xs = s;
-  size_t temp;
+	void *xs = s;
+	size_t temp;
 
-  if (!count)
-    return xs;
-  c &= 0xff;
-  c |= c << 8;
-  c |= c << 16;
-  if ((long) s & 1)
-    {
-      char *cs = s;
-      *cs++ = c;
-      s = cs;
-      count--;
-    }
-  if (count > 2 && (long) s & 2)
-    {
-      short *ss = s;
-      *ss++ = c;
-      s = ss;
-      count -= 2;
-    }
-  temp = count >> 2;
-  if (temp)
-    {
-      long *ls = s;
-      for (; temp; temp--)
-	*ls++ = c;
-      s = ls;
-    }
-  if (count & 2)
-    {
-      short *ss = s;
-      *ss++ = c;
-      s = ss;
-    }
-  if (count & 1)
-    {
-      char *cs = s;
-      *cs = c;
-    }
-  return xs;
+	if (!count)
+		return xs;
+	c &= 0xff;
+	c |= c << 8;
+	c |= c << 16;
+	if ((long)s & 1) {
+		char *cs = s;
+		*cs++ = c;
+		s = cs;
+		count--;
+	}
+	if (count > 2 && (long)s & 2) {
+		short *ss = s;
+		*ss++ = c;
+		s = ss;
+		count -= 2;
+	}
+	temp = count >> 2;
+	if (temp) {
+		long *ls = s;
+#if defined(CONFIG_M68000) || defined(CONFIG_COLDFIRE)
+		for (; temp; temp--)
+			*ls++ = c;
+#else
+		size_t temp1;
+		asm volatile (
+			"	movel %1,%2\n"
+			"	andw  #7,%2\n"
+			"	lsrl  #3,%1\n"
+			"	negw  %2\n"
+			"	jmp   %%pc@(2f,%2:w:2)\n"
+			"1:	movel %3,%0@+\n"
+			"	movel %3,%0@+\n"
+			"	movel %3,%0@+\n"
+			"	movel %3,%0@+\n"
+			"	movel %3,%0@+\n"
+			"	movel %3,%0@+\n"
+			"	movel %3,%0@+\n"
+			"	movel %3,%0@+\n"
+			"2:	dbra  %1,1b\n"
+			"	clrw  %1\n"
+			"	subql #1,%1\n"
+			"	jpl   1b"
+			: "=a" (ls), "=d" (temp), "=&d" (temp1)
+			: "d" (c), "0" (ls), "1" (temp));
+#endif
+		s = ls;
+	}
+	if (count & 2) {
+		short *ss = s;
+		*ss++ = c;
+		s = ss;
+	}
+	if (count & 1) {
+		char *cs = s;
+		*cs = c;
+	}
+	return xs;
 }
+EXPORT_SYMBOL(memset);
diff -druN linux-2.6.39-libre/arch/m68k/lib/muldi3.c linux-3.0-rc7-libre/arch/m68k/lib/muldi3.c
--- linux-2.6.39-libre/arch/m68k/lib/muldi3.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/m68k/lib/muldi3.c	2011-07-11 19:51:52.000000000 -0400
@@ -1,5 +1,97 @@
-#ifdef CONFIG_MMU
-#include "muldi3_mm.c"
+/* muldi3.c extracted from gcc-2.7.2.3/libgcc2.c and 
+			   gcc-2.7.2.3/longlong.h which is: */
+/* Copyright (C) 1989, 1992, 1993, 1994, 1995 Free Software Foundation, Inc.
+
+This file is part of GNU CC.
+
+GNU CC is free software; you can redistribute 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.
+
+GNU CC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU CC; see the file COPYING.  If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.  */
+
+#if defined(CONFIG_M68000) || defined(CONFIG_COLDFIRE)
+
+#define SI_TYPE_SIZE 32
+#define __BITS4 (SI_TYPE_SIZE / 4)
+#define __ll_B (1L << (SI_TYPE_SIZE / 2))
+#define __ll_lowpart(t) ((USItype) (t) % __ll_B)
+#define __ll_highpart(t) ((USItype) (t) / __ll_B)
+
+#define umul_ppmm(w1, w0, u, v)						\
+  do {									\
+    USItype __x0, __x1, __x2, __x3;					\
+    USItype __ul, __vl, __uh, __vh;					\
+									\
+    __ul = __ll_lowpart (u);						\
+    __uh = __ll_highpart (u);						\
+    __vl = __ll_lowpart (v);						\
+    __vh = __ll_highpart (v);						\
+									\
+    __x0 = (USItype) __ul * __vl;					\
+    __x1 = (USItype) __ul * __vh;					\
+    __x2 = (USItype) __uh * __vl;					\
+    __x3 = (USItype) __uh * __vh;					\
+									\
+    __x1 += __ll_highpart (__x0);/* this can't give carry */		\
+    __x1 += __x2;		/* but this indeed can */		\
+    if (__x1 < __x2)		/* did we get it? */			\
+      __x3 += __ll_B;		/* yes, add it in the proper pos. */	\
+									\
+    (w1) = __x3 + __ll_highpart (__x1);					\
+    (w0) = __ll_lowpart (__x1) * __ll_B + __ll_lowpart (__x0);		\
+  } while (0)
+
 #else
-#include "muldi3_no.c"
+
+#define umul_ppmm(w1, w0, u, v) \
+  __asm__ ("mulu%.l %3,%1:%0"						\
+           : "=d" ((USItype)(w0)),					\
+             "=d" ((USItype)(w1))					\
+           : "%0" ((USItype)(u)),					\
+             "dmi" ((USItype)(v)))
+
 #endif
+
+#define __umulsidi3(u, v) \
+  ({DIunion __w;							\
+    umul_ppmm (__w.s.high, __w.s.low, u, v);				\
+    __w.ll; })
+
+typedef 	 int SItype	__attribute__ ((mode (SI)));
+typedef unsigned int USItype	__attribute__ ((mode (SI)));
+typedef		 int DItype	__attribute__ ((mode (DI)));
+typedef int word_type __attribute__ ((mode (__word__)));
+
+struct DIstruct {SItype high, low;};
+
+typedef union
+{
+  struct DIstruct s;
+  DItype ll;
+} DIunion;
+
+DItype
+__muldi3 (DItype u, DItype v)
+{
+  DIunion w;
+  DIunion uu, vv;
+
+  uu.ll = u,
+  vv.ll = v;
+
+  w.ll = __umulsidi3 (uu.s.low, vv.s.low);
+  w.s.high += ((USItype) uu.s.low * (USItype) vv.s.high
+	       + (USItype) uu.s.high * (USItype) vv.s.low);
+
+  return w.ll;
+}
diff -druN linux-2.6.39-libre/arch/m68k/lib/muldi3_mm.c linux-3.0-rc7-libre/arch/m68k/lib/muldi3_mm.c
--- linux-2.6.39-libre/arch/m68k/lib/muldi3_mm.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/m68k/lib/muldi3_mm.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,63 +0,0 @@
-/* muldi3.c extracted from gcc-2.7.2.3/libgcc2.c and
-			   gcc-2.7.2.3/longlong.h which is: */
-/* Copyright (C) 1989, 1992, 1993, 1994, 1995 Free Software Foundation, Inc.
-
-This file is part of GNU CC.
-
-GNU CC is free software; you can redistribute 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.
-
-GNU CC is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with GNU CC; see the file COPYING.  If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA.  */
-
-#define BITS_PER_UNIT 8
-
-#define umul_ppmm(w1, w0, u, v) \
-  __asm__ ("mulu%.l %3,%1:%0"						\
-           : "=d" ((USItype)(w0)),					\
-             "=d" ((USItype)(w1))					\
-           : "%0" ((USItype)(u)),					\
-             "dmi" ((USItype)(v)))
-
-#define __umulsidi3(u, v) \
-  ({DIunion __w;							\
-    umul_ppmm (__w.s.high, __w.s.low, u, v);				\
-    __w.ll; })
-
-typedef		 int SItype	__attribute__ ((mode (SI)));
-typedef unsigned int USItype	__attribute__ ((mode (SI)));
-typedef		 int DItype	__attribute__ ((mode (DI)));
-typedef int word_type __attribute__ ((mode (__word__)));
-
-struct DIstruct {SItype high, low;};
-
-typedef union
-{
-  struct DIstruct s;
-  DItype ll;
-} DIunion;
-
-DItype
-__muldi3 (DItype u, DItype v)
-{
-  DIunion w;
-  DIunion uu, vv;
-
-  uu.ll = u,
-  vv.ll = v;
-
-  w.ll = __umulsidi3 (uu.s.low, vv.s.low);
-  w.s.high += ((USItype) uu.s.low * (USItype) vv.s.high
-	       + (USItype) uu.s.high * (USItype) vv.s.low);
-
-  return w.ll;
-}
diff -druN linux-2.6.39-libre/arch/m68k/lib/muldi3_no.c linux-3.0-rc7-libre/arch/m68k/lib/muldi3_no.c
--- linux-2.6.39-libre/arch/m68k/lib/muldi3_no.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/m68k/lib/muldi3_no.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,86 +0,0 @@
-/* muldi3.c extracted from gcc-2.7.2.3/libgcc2.c and 
-			   gcc-2.7.2.3/longlong.h which is: */
-/* Copyright (C) 1989, 1992, 1993, 1994, 1995 Free Software Foundation, Inc.
-
-This file is part of GNU CC.
-
-GNU CC is free software; you can redistribute 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.
-
-GNU CC is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with GNU CC; see the file COPYING.  If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA.  */
-
-#define BITS_PER_UNIT 8
-#define SI_TYPE_SIZE 32
-
-#define __BITS4 (SI_TYPE_SIZE / 4)
-#define __ll_B (1L << (SI_TYPE_SIZE / 2))
-#define __ll_lowpart(t) ((USItype) (t) % __ll_B)
-#define __ll_highpart(t) ((USItype) (t) / __ll_B)
-
-#define umul_ppmm(w1, w0, u, v)						\
-  do {									\
-    USItype __x0, __x1, __x2, __x3;					\
-    USItype __ul, __vl, __uh, __vh;					\
-									\
-    __ul = __ll_lowpart (u);						\
-    __uh = __ll_highpart (u);						\
-    __vl = __ll_lowpart (v);						\
-    __vh = __ll_highpart (v);						\
-									\
-    __x0 = (USItype) __ul * __vl;					\
-    __x1 = (USItype) __ul * __vh;					\
-    __x2 = (USItype) __uh * __vl;					\
-    __x3 = (USItype) __uh * __vh;					\
-									\
-    __x1 += __ll_highpart (__x0);/* this can't give carry */		\
-    __x1 += __x2;		/* but this indeed can */		\
-    if (__x1 < __x2)		/* did we get it? */			\
-      __x3 += __ll_B;		/* yes, add it in the proper pos. */	\
-									\
-    (w1) = __x3 + __ll_highpart (__x1);					\
-    (w0) = __ll_lowpart (__x1) * __ll_B + __ll_lowpart (__x0);		\
-  } while (0)
-
-#define __umulsidi3(u, v) \
-  ({DIunion __w;							\
-    umul_ppmm (__w.s.high, __w.s.low, u, v);				\
-    __w.ll; })
-
-typedef 	 int SItype	__attribute__ ((mode (SI)));
-typedef unsigned int USItype	__attribute__ ((mode (SI)));
-typedef		 int DItype	__attribute__ ((mode (DI)));
-typedef int word_type __attribute__ ((mode (__word__)));
-
-struct DIstruct {SItype high, low;};
-
-typedef union
-{
-  struct DIstruct s;
-  DItype ll;
-} DIunion;
-
-DItype
-__muldi3 (DItype u, DItype v)
-{
-  DIunion w;
-  DIunion uu, vv;
-
-  uu.ll = u,
-  vv.ll = v;
-
-  w.ll = __umulsidi3 (uu.s.low, vv.s.low);
-  w.s.high += ((USItype) uu.s.low * (USItype) vv.s.high
-	       + (USItype) uu.s.high * (USItype) vv.s.low);
-
-  return w.ll;
-}
diff -druN linux-2.6.39-libre/arch/m68k/lib/string.c linux-3.0-rc7-libre/arch/m68k/lib/string.c
--- linux-2.6.39-libre/arch/m68k/lib/string.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/m68k/lib/string.c	2011-07-11 19:51:52.000000000 -0400
@@ -20,226 +20,3 @@
 	return __kernel_strcpy(dest + __kernel_strlen(dest), src);
 }
 EXPORT_SYMBOL(strcat);
-
-void *memset(void *s, int c, size_t count)
-{
-	void *xs = s;
-	size_t temp, temp1;
-
-	if (!count)
-		return xs;
-	c &= 0xff;
-	c |= c << 8;
-	c |= c << 16;
-	if ((long)s & 1) {
-		char *cs = s;
-		*cs++ = c;
-		s = cs;
-		count--;
-	}
-	if (count > 2 && (long)s & 2) {
-		short *ss = s;
-		*ss++ = c;
-		s = ss;
-		count -= 2;
-	}
-	temp = count >> 2;
-	if (temp) {
-		long *ls = s;
-
-		asm volatile (
-			"	movel %1,%2\n"
-			"	andw  #7,%2\n"
-			"	lsrl  #3,%1\n"
-			"	negw  %2\n"
-			"	jmp   %%pc@(2f,%2:w:2)\n"
-			"1:	movel %3,%0@+\n"
-			"	movel %3,%0@+\n"
-			"	movel %3,%0@+\n"
-			"	movel %3,%0@+\n"
-			"	movel %3,%0@+\n"
-			"	movel %3,%0@+\n"
-			"	movel %3,%0@+\n"
-			"	movel %3,%0@+\n"
-			"2:	dbra  %1,1b\n"
-			"	clrw  %1\n"
-			"	subql #1,%1\n"
-			"	jpl   1b"
-			: "=a" (ls), "=d" (temp), "=&d" (temp1)
-			: "d" (c), "0" (ls), "1" (temp));
-		s = ls;
-	}
-	if (count & 2) {
-		short *ss = s;
-		*ss++ = c;
-		s = ss;
-	}
-	if (count & 1) {
-		char *cs = s;
-		*cs = c;
-	}
-	return xs;
-}
-EXPORT_SYMBOL(memset);
-
-void *memcpy(void *to, const void *from, size_t n)
-{
-	void *xto = to;
-	size_t temp, temp1;
-
-	if (!n)
-		return xto;
-	if ((long)to & 1) {
-		char *cto = to;
-		const char *cfrom = from;
-		*cto++ = *cfrom++;
-		to = cto;
-		from = cfrom;
-		n--;
-	}
-	if (n > 2 && (long)to & 2) {
-		short *sto = to;
-		const short *sfrom = from;
-		*sto++ = *sfrom++;
-		to = sto;
-		from = sfrom;
-		n -= 2;
-	}
-	temp = n >> 2;
-	if (temp) {
-		long *lto = to;
-		const long *lfrom = from;
-
-		asm volatile (
-			"	movel %2,%3\n"
-			"	andw  #7,%3\n"
-			"	lsrl  #3,%2\n"
-			"	negw  %3\n"
-			"	jmp   %%pc@(1f,%3:w:2)\n"
-			"4:	movel %0@+,%1@+\n"
-			"	movel %0@+,%1@+\n"
-			"	movel %0@+,%1@+\n"
-			"	movel %0@+,%1@+\n"
-			"	movel %0@+,%1@+\n"
-			"	movel %0@+,%1@+\n"
-			"	movel %0@+,%1@+\n"
-			"	movel %0@+,%1@+\n"
-			"1:	dbra  %2,4b\n"
-			"	clrw  %2\n"
-			"	subql #1,%2\n"
-			"	jpl   4b"
-			: "=a" (lfrom), "=a" (lto), "=d" (temp), "=&d" (temp1)
-			: "0" (lfrom), "1" (lto), "2" (temp));
-		to = lto;
-		from = lfrom;
-	}
-	if (n & 2) {
-		short *sto = to;
-		const short *sfrom = from;
-		*sto++ = *sfrom++;
-		to = sto;
-		from = sfrom;
-	}
-	if (n & 1) {
-		char *cto = to;
-		const char *cfrom = from;
-		*cto = *cfrom;
-	}
-	return xto;
-}
-EXPORT_SYMBOL(memcpy);
-
-void *memmove(void *dest, const void *src, size_t n)
-{
-	void *xdest = dest;
-	size_t temp;
-
-	if (!n)
-		return xdest;
-
-	if (dest < src) {
-		if ((long)dest & 1) {
-			char *cdest = dest;
-			const char *csrc = src;
-			*cdest++ = *csrc++;
-			dest = cdest;
-			src = csrc;
-			n--;
-		}
-		if (n > 2 && (long)dest & 2) {
-			short *sdest = dest;
-			const short *ssrc = src;
-			*sdest++ = *ssrc++;
-			dest = sdest;
-			src = ssrc;
-			n -= 2;
-		}
-		temp = n >> 2;
-		if (temp) {
-			long *ldest = dest;
-			const long *lsrc = src;
-			temp--;
-			do
-				*ldest++ = *lsrc++;
-			while (temp--);
-			dest = ldest;
-			src = lsrc;
-		}
-		if (n & 2) {
-			short *sdest = dest;
-			const short *ssrc = src;
-			*sdest++ = *ssrc++;
-			dest = sdest;
-			src = ssrc;
-		}
-		if (n & 1) {
-			char *cdest = dest;
-			const char *csrc = src;
-			*cdest = *csrc;
-		}
-	} else {
-		dest = (char *)dest + n;
-		src = (const char *)src + n;
-		if ((long)dest & 1) {
-			char *cdest = dest;
-			const char *csrc = src;
-			*--cdest = *--csrc;
-			dest = cdest;
-			src = csrc;
-			n--;
-		}
-		if (n > 2 && (long)dest & 2) {
-			short *sdest = dest;
-			const short *ssrc = src;
-			*--sdest = *--ssrc;
-			dest = sdest;
-			src = ssrc;
-			n -= 2;
-		}
-		temp = n >> 2;
-		if (temp) {
-			long *ldest = dest;
-			const long *lsrc = src;
-			temp--;
-			do
-				*--ldest = *--lsrc;
-			while (temp--);
-			dest = ldest;
-			src = lsrc;
-		}
-		if (n & 2) {
-			short *sdest = dest;
-			const short *ssrc = src;
-			*--sdest = *--ssrc;
-			dest = sdest;
-			src = ssrc;
-		}
-		if (n & 1) {
-			char *cdest = dest;
-			const char *csrc = src;
-			*--cdest = *--csrc;
-		}
-	}
-	return xdest;
-}
-EXPORT_SYMBOL(memmove);
diff -druN linux-2.6.39-libre/arch/m68k/mm/init_mm.c linux-3.0-rc7-libre/arch/m68k/mm/init_mm.c
--- linux-2.6.39-libre/arch/m68k/mm/init_mm.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/m68k/mm/init_mm.c	2011-07-11 19:51:52.000000000 -0400
@@ -32,8 +32,6 @@
 #include <asm/sections.h>
 #include <asm/tlb.h>
 
-DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
-
 pg_data_t pg_data_map[MAX_NUMNODES];
 EXPORT_SYMBOL(pg_data_map);
 
diff -druN linux-2.6.39-libre/arch/m68k/mm/init_no.c linux-3.0-rc7-libre/arch/m68k/mm/init_no.c
--- linux-2.6.39-libre/arch/m68k/mm/init_no.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/m68k/mm/init_no.c	2011-07-11 19:51:52.000000000 -0400
@@ -38,28 +38,10 @@
 #include <asm/system.h>
 #include <asm/machdep.h>
 
-#undef DEBUG
-
-extern void die_if_kernel(char *,struct pt_regs *,long);
-extern void free_initmem(void);
-
 /*
- * BAD_PAGE is the page that is used for page faults when linux
- * is out-of-memory. Older versions of linux just did a
- * do_exit(), but using this instead means there is less risk
- * for a process dying in kernel mode, possibly leaving a inode
- * unused etc..
- *
- * BAD_PAGETABLE is the accompanying page-table: it is initialized
- * to point to BAD_PAGE entries.
- *
  * ZERO_PAGE is a special page that is used for zero-initialized
  * data and COW.
  */
-static unsigned long empty_bad_page_table;
-
-static unsigned long empty_bad_page;
-
 unsigned long empty_zero_page;
 
 extern unsigned long memory_start;
@@ -77,22 +59,9 @@
 	 * Make sure start_mem is page aligned, otherwise bootmem and
 	 * page_alloc get different views of the world.
 	 */
-#ifdef DEBUG
-	unsigned long start_mem = PAGE_ALIGN(memory_start);
-#endif
 	unsigned long end_mem   = memory_end & PAGE_MASK;
+	unsigned long zones_size[MAX_NR_ZONES] = {0, };
 
-#ifdef DEBUG
-	printk (KERN_DEBUG "start_mem is %#lx\nvirtual_end is %#lx\n",
-		start_mem, end_mem);
-#endif
-
-	/*
-	 * Initialize the bad page table and bad page to point
-	 * to a couple of allocated pages.
-	 */
-	empty_bad_page_table = (unsigned long)alloc_bootmem_pages(PAGE_SIZE);
-	empty_bad_page = (unsigned long)alloc_bootmem_pages(PAGE_SIZE);
 	empty_zero_page = (unsigned long)alloc_bootmem_pages(PAGE_SIZE);
 	memset((void *)empty_zero_page, 0, PAGE_SIZE);
 
@@ -101,19 +70,8 @@
 	 */
 	set_fs (USER_DS);
 
-#ifdef DEBUG
-	printk (KERN_DEBUG "before free_area_init\n");
-
-	printk (KERN_DEBUG "free_area_init -> start_mem is %#lx\nvirtual_end is %#lx\n",
-		start_mem, end_mem);
-#endif
-
-	{
-		unsigned long zones_size[MAX_NR_ZONES] = {0, };
-
-		zones_size[ZONE_DMA] = (end_mem - PAGE_OFFSET) >> PAGE_SHIFT;
-		free_area_init(zones_size);
-	}
+	zones_size[ZONE_DMA] = (end_mem - PAGE_OFFSET) >> PAGE_SHIFT;
+	free_area_init(zones_size);
 }
 
 void __init mem_init(void)
@@ -166,8 +124,7 @@
 }
 #endif
 
-void
-free_initmem()
+void free_initmem(void)
 {
 #ifdef CONFIG_RAMKERNEL
 	unsigned long addr;
diff -druN linux-2.6.39-libre/arch/m68k/mm/kmap.c linux-3.0-rc7-libre/arch/m68k/mm/kmap.c
--- linux-2.6.39-libre/arch/m68k/mm/kmap.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/m68k/mm/kmap.c	2011-07-11 19:51:52.000000000 -0400
@@ -1,5 +1,367 @@
-#ifdef CONFIG_MMU
-#include "kmap_mm.c"
+/*
+ *  linux/arch/m68k/mm/kmap.c
+ *
+ *  Copyright (C) 1997 Roman Hodek
+ *
+ *  10/01/99 cleaned up the code and changing to the same interface
+ *	     used by other architectures		/Roman Zippel
+ */
+
+#include <linux/module.h>
+#include <linux/mm.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <linux/vmalloc.h>
+
+#include <asm/setup.h>
+#include <asm/segment.h>
+#include <asm/page.h>
+#include <asm/pgalloc.h>
+#include <asm/io.h>
+#include <asm/system.h>
+
+#undef DEBUG
+
+#define PTRTREESIZE	(256*1024)
+
+/*
+ * For 040/060 we can use the virtual memory area like other architectures,
+ * but for 020/030 we want to use early termination page descriptor and we
+ * can't mix this with normal page descriptors, so we have to copy that code
+ * (mm/vmalloc.c) and return appriorate aligned addresses.
+ */
+
+#ifdef CPU_M68040_OR_M68060_ONLY
+
+#define IO_SIZE		PAGE_SIZE
+
+static inline struct vm_struct *get_io_area(unsigned long size)
+{
+	return get_vm_area(size, VM_IOREMAP);
+}
+
+
+static inline void free_io_area(void *addr)
+{
+	vfree((void *)(PAGE_MASK & (unsigned long)addr));
+}
+
 #else
-#include "kmap_no.c"
+
+#define IO_SIZE		(256*1024)
+
+static struct vm_struct *iolist;
+
+static struct vm_struct *get_io_area(unsigned long size)
+{
+	unsigned long addr;
+	struct vm_struct **p, *tmp, *area;
+
+	area = kmalloc(sizeof(*area), GFP_KERNEL);
+	if (!area)
+		return NULL;
+	addr = KMAP_START;
+	for (p = &iolist; (tmp = *p) ; p = &tmp->next) {
+		if (size + addr < (unsigned long)tmp->addr)
+			break;
+		if (addr > KMAP_END-size) {
+			kfree(area);
+			return NULL;
+		}
+		addr = tmp->size + (unsigned long)tmp->addr;
+	}
+	area->addr = (void *)addr;
+	area->size = size + IO_SIZE;
+	area->next = *p;
+	*p = area;
+	return area;
+}
+
+static inline void free_io_area(void *addr)
+{
+	struct vm_struct **p, *tmp;
+
+	if (!addr)
+		return;
+	addr = (void *)((unsigned long)addr & -IO_SIZE);
+	for (p = &iolist ; (tmp = *p) ; p = &tmp->next) {
+		if (tmp->addr == addr) {
+			*p = tmp->next;
+			__iounmap(tmp->addr, tmp->size);
+			kfree(tmp);
+			return;
+		}
+	}
+}
+
+#endif
+
+/*
+ * Map some physical address range into the kernel address space.
+ */
+/* Rewritten by Andreas Schwab to remove all races. */
+
+void __iomem *__ioremap(unsigned long physaddr, unsigned long size, int cacheflag)
+{
+	struct vm_struct *area;
+	unsigned long virtaddr, retaddr;
+	long offset;
+	pgd_t *pgd_dir;
+	pmd_t *pmd_dir;
+	pte_t *pte_dir;
+
+	/*
+	 * Don't allow mappings that wrap..
+	 */
+	if (!size || physaddr > (unsigned long)(-size))
+		return NULL;
+
+#ifdef CONFIG_AMIGA
+	if (MACH_IS_AMIGA) {
+		if ((physaddr >= 0x40000000) && (physaddr + size < 0x60000000)
+		    && (cacheflag == IOMAP_NOCACHE_SER))
+			return (void __iomem *)physaddr;
+	}
+#endif
+
+#ifdef DEBUG
+	printk("ioremap: 0x%lx,0x%lx(%d) - ", physaddr, size, cacheflag);
+#endif
+	/*
+	 * Mappings have to be aligned
+	 */
+	offset = physaddr & (IO_SIZE - 1);
+	physaddr &= -IO_SIZE;
+	size = (size + offset + IO_SIZE - 1) & -IO_SIZE;
+
+	/*
+	 * Ok, go for it..
+	 */
+	area = get_io_area(size);
+	if (!area)
+		return NULL;
+
+	virtaddr = (unsigned long)area->addr;
+	retaddr = virtaddr + offset;
+#ifdef DEBUG
+	printk("0x%lx,0x%lx,0x%lx", physaddr, virtaddr, retaddr);
+#endif
+
+	/*
+	 * add cache and table flags to physical address
+	 */
+	if (CPU_IS_040_OR_060) {
+		physaddr |= (_PAGE_PRESENT | _PAGE_GLOBAL040 |
+			     _PAGE_ACCESSED | _PAGE_DIRTY);
+		switch (cacheflag) {
+		case IOMAP_FULL_CACHING:
+			physaddr |= _PAGE_CACHE040;
+			break;
+		case IOMAP_NOCACHE_SER:
+		default:
+			physaddr |= _PAGE_NOCACHE_S;
+			break;
+		case IOMAP_NOCACHE_NONSER:
+			physaddr |= _PAGE_NOCACHE;
+			break;
+		case IOMAP_WRITETHROUGH:
+			physaddr |= _PAGE_CACHE040W;
+			break;
+		}
+	} else {
+		physaddr |= (_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_DIRTY);
+		switch (cacheflag) {
+		case IOMAP_NOCACHE_SER:
+		case IOMAP_NOCACHE_NONSER:
+		default:
+			physaddr |= _PAGE_NOCACHE030;
+			break;
+		case IOMAP_FULL_CACHING:
+		case IOMAP_WRITETHROUGH:
+			break;
+		}
+	}
+
+	while ((long)size > 0) {
+#ifdef DEBUG
+		if (!(virtaddr & (PTRTREESIZE-1)))
+			printk ("\npa=%#lx va=%#lx ", physaddr, virtaddr);
+#endif
+		pgd_dir = pgd_offset_k(virtaddr);
+		pmd_dir = pmd_alloc(&init_mm, pgd_dir, virtaddr);
+		if (!pmd_dir) {
+			printk("ioremap: no mem for pmd_dir\n");
+			return NULL;
+		}
+
+		if (CPU_IS_020_OR_030) {
+			pmd_dir->pmd[(virtaddr/PTRTREESIZE) & 15] = physaddr;
+			physaddr += PTRTREESIZE;
+			virtaddr += PTRTREESIZE;
+			size -= PTRTREESIZE;
+		} else {
+			pte_dir = pte_alloc_kernel(pmd_dir, virtaddr);
+			if (!pte_dir) {
+				printk("ioremap: no mem for pte_dir\n");
+				return NULL;
+			}
+
+			pte_val(*pte_dir) = physaddr;
+			virtaddr += PAGE_SIZE;
+			physaddr += PAGE_SIZE;
+			size -= PAGE_SIZE;
+		}
+	}
+#ifdef DEBUG
+	printk("\n");
+#endif
+	flush_tlb_all();
+
+	return (void __iomem *)retaddr;
+}
+EXPORT_SYMBOL(__ioremap);
+
+/*
+ * Unmap a ioremap()ed region again
+ */
+void iounmap(void __iomem *addr)
+{
+#ifdef CONFIG_AMIGA
+	if ((!MACH_IS_AMIGA) ||
+	    (((unsigned long)addr < 0x40000000) ||
+	     ((unsigned long)addr > 0x60000000)))
+			free_io_area((__force void *)addr);
+#else
+	free_io_area((__force void *)addr);
 #endif
+}
+EXPORT_SYMBOL(iounmap);
+
+/*
+ * __iounmap unmaps nearly everything, so be careful
+ * it doesn't free currently pointer/page tables anymore but it
+ * wans't used anyway and might be added later.
+ */
+void __iounmap(void *addr, unsigned long size)
+{
+	unsigned long virtaddr = (unsigned long)addr;
+	pgd_t *pgd_dir;
+	pmd_t *pmd_dir;
+	pte_t *pte_dir;
+
+	while ((long)size > 0) {
+		pgd_dir = pgd_offset_k(virtaddr);
+		if (pgd_bad(*pgd_dir)) {
+			printk("iounmap: bad pgd(%08lx)\n", pgd_val(*pgd_dir));
+			pgd_clear(pgd_dir);
+			return;
+		}
+		pmd_dir = pmd_offset(pgd_dir, virtaddr);
+
+		if (CPU_IS_020_OR_030) {
+			int pmd_off = (virtaddr/PTRTREESIZE) & 15;
+			int pmd_type = pmd_dir->pmd[pmd_off] & _DESCTYPE_MASK;
+
+			if (pmd_type == _PAGE_PRESENT) {
+				pmd_dir->pmd[pmd_off] = 0;
+				virtaddr += PTRTREESIZE;
+				size -= PTRTREESIZE;
+				continue;
+			} else if (pmd_type == 0)
+				continue;
+		}
+
+		if (pmd_bad(*pmd_dir)) {
+			printk("iounmap: bad pmd (%08lx)\n", pmd_val(*pmd_dir));
+			pmd_clear(pmd_dir);
+			return;
+		}
+		pte_dir = pte_offset_kernel(pmd_dir, virtaddr);
+
+		pte_val(*pte_dir) = 0;
+		virtaddr += PAGE_SIZE;
+		size -= PAGE_SIZE;
+	}
+
+	flush_tlb_all();
+}
+
+/*
+ * Set new cache mode for some kernel address space.
+ * The caller must push data for that range itself, if such data may already
+ * be in the cache.
+ */
+void kernel_set_cachemode(void *addr, unsigned long size, int cmode)
+{
+	unsigned long virtaddr = (unsigned long)addr;
+	pgd_t *pgd_dir;
+	pmd_t *pmd_dir;
+	pte_t *pte_dir;
+
+	if (CPU_IS_040_OR_060) {
+		switch (cmode) {
+		case IOMAP_FULL_CACHING:
+			cmode = _PAGE_CACHE040;
+			break;
+		case IOMAP_NOCACHE_SER:
+		default:
+			cmode = _PAGE_NOCACHE_S;
+			break;
+		case IOMAP_NOCACHE_NONSER:
+			cmode = _PAGE_NOCACHE;
+			break;
+		case IOMAP_WRITETHROUGH:
+			cmode = _PAGE_CACHE040W;
+			break;
+		}
+	} else {
+		switch (cmode) {
+		case IOMAP_NOCACHE_SER:
+		case IOMAP_NOCACHE_NONSER:
+		default:
+			cmode = _PAGE_NOCACHE030;
+			break;
+		case IOMAP_FULL_CACHING:
+		case IOMAP_WRITETHROUGH:
+			cmode = 0;
+		}
+	}
+
+	while ((long)size > 0) {
+		pgd_dir = pgd_offset_k(virtaddr);
+		if (pgd_bad(*pgd_dir)) {
+			printk("iocachemode: bad pgd(%08lx)\n", pgd_val(*pgd_dir));
+			pgd_clear(pgd_dir);
+			return;
+		}
+		pmd_dir = pmd_offset(pgd_dir, virtaddr);
+
+		if (CPU_IS_020_OR_030) {
+			int pmd_off = (virtaddr/PTRTREESIZE) & 15;
+
+			if ((pmd_dir->pmd[pmd_off] & _DESCTYPE_MASK) == _PAGE_PRESENT) {
+				pmd_dir->pmd[pmd_off] = (pmd_dir->pmd[pmd_off] &
+							 _CACHEMASK040) | cmode;
+				virtaddr += PTRTREESIZE;
+				size -= PTRTREESIZE;
+				continue;
+			}
+		}
+
+		if (pmd_bad(*pmd_dir)) {
+			printk("iocachemode: bad pmd (%08lx)\n", pmd_val(*pmd_dir));
+			pmd_clear(pmd_dir);
+			return;
+		}
+		pte_dir = pte_offset_kernel(pmd_dir, virtaddr);
+
+		pte_val(*pte_dir) = (pte_val(*pte_dir) & _CACHEMASK040) | cmode;
+		virtaddr += PAGE_SIZE;
+		size -= PAGE_SIZE;
+	}
+
+	flush_tlb_all();
+}
+EXPORT_SYMBOL(kernel_set_cachemode);
diff -druN linux-2.6.39-libre/arch/m68k/mm/kmap_mm.c linux-3.0-rc7-libre/arch/m68k/mm/kmap_mm.c
--- linux-2.6.39-libre/arch/m68k/mm/kmap_mm.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/m68k/mm/kmap_mm.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,367 +0,0 @@
-/*
- *  linux/arch/m68k/mm/kmap.c
- *
- *  Copyright (C) 1997 Roman Hodek
- *
- *  10/01/99 cleaned up the code and changing to the same interface
- *	     used by other architectures		/Roman Zippel
- */
-
-#include <linux/module.h>
-#include <linux/mm.h>
-#include <linux/kernel.h>
-#include <linux/string.h>
-#include <linux/types.h>
-#include <linux/slab.h>
-#include <linux/vmalloc.h>
-
-#include <asm/setup.h>
-#include <asm/segment.h>
-#include <asm/page.h>
-#include <asm/pgalloc.h>
-#include <asm/io.h>
-#include <asm/system.h>
-
-#undef DEBUG
-
-#define PTRTREESIZE	(256*1024)
-
-/*
- * For 040/060 we can use the virtual memory area like other architectures,
- * but for 020/030 we want to use early termination page descriptor and we
- * can't mix this with normal page descriptors, so we have to copy that code
- * (mm/vmalloc.c) and return appriorate aligned addresses.
- */
-
-#ifdef CPU_M68040_OR_M68060_ONLY
-
-#define IO_SIZE		PAGE_SIZE
-
-static inline struct vm_struct *get_io_area(unsigned long size)
-{
-	return get_vm_area(size, VM_IOREMAP);
-}
-
-
-static inline void free_io_area(void *addr)
-{
-	vfree((void *)(PAGE_MASK & (unsigned long)addr));
-}
-
-#else
-
-#define IO_SIZE		(256*1024)
-
-static struct vm_struct *iolist;
-
-static struct vm_struct *get_io_area(unsigned long size)
-{
-	unsigned long addr;
-	struct vm_struct **p, *tmp, *area;
-
-	area = kmalloc(sizeof(*area), GFP_KERNEL);
-	if (!area)
-		return NULL;
-	addr = KMAP_START;
-	for (p = &iolist; (tmp = *p) ; p = &tmp->next) {
-		if (size + addr < (unsigned long)tmp->addr)
-			break;
-		if (addr > KMAP_END-size) {
-			kfree(area);
-			return NULL;
-		}
-		addr = tmp->size + (unsigned long)tmp->addr;
-	}
-	area->addr = (void *)addr;
-	area->size = size + IO_SIZE;
-	area->next = *p;
-	*p = area;
-	return area;
-}
-
-static inline void free_io_area(void *addr)
-{
-	struct vm_struct **p, *tmp;
-
-	if (!addr)
-		return;
-	addr = (void *)((unsigned long)addr & -IO_SIZE);
-	for (p = &iolist ; (tmp = *p) ; p = &tmp->next) {
-		if (tmp->addr == addr) {
-			*p = tmp->next;
-			__iounmap(tmp->addr, tmp->size);
-			kfree(tmp);
-			return;
-		}
-	}
-}
-
-#endif
-
-/*
- * Map some physical address range into the kernel address space.
- */
-/* Rewritten by Andreas Schwab to remove all races. */
-
-void __iomem *__ioremap(unsigned long physaddr, unsigned long size, int cacheflag)
-{
-	struct vm_struct *area;
-	unsigned long virtaddr, retaddr;
-	long offset;
-	pgd_t *pgd_dir;
-	pmd_t *pmd_dir;
-	pte_t *pte_dir;
-
-	/*
-	 * Don't allow mappings that wrap..
-	 */
-	if (!size || physaddr > (unsigned long)(-size))
-		return NULL;
-
-#ifdef CONFIG_AMIGA
-	if (MACH_IS_AMIGA) {
-		if ((physaddr >= 0x40000000) && (physaddr + size < 0x60000000)
-		    && (cacheflag == IOMAP_NOCACHE_SER))
-			return (void __iomem *)physaddr;
-	}
-#endif
-
-#ifdef DEBUG
-	printk("ioremap: 0x%lx,0x%lx(%d) - ", physaddr, size, cacheflag);
-#endif
-	/*
-	 * Mappings have to be aligned
-	 */
-	offset = physaddr & (IO_SIZE - 1);
-	physaddr &= -IO_SIZE;
-	size = (size + offset + IO_SIZE - 1) & -IO_SIZE;
-
-	/*
-	 * Ok, go for it..
-	 */
-	area = get_io_area(size);
-	if (!area)
-		return NULL;
-
-	virtaddr = (unsigned long)area->addr;
-	retaddr = virtaddr + offset;
-#ifdef DEBUG
-	printk("0x%lx,0x%lx,0x%lx", physaddr, virtaddr, retaddr);
-#endif
-
-	/*
-	 * add cache and table flags to physical address
-	 */
-	if (CPU_IS_040_OR_060) {
-		physaddr |= (_PAGE_PRESENT | _PAGE_GLOBAL040 |
-			     _PAGE_ACCESSED | _PAGE_DIRTY);
-		switch (cacheflag) {
-		case IOMAP_FULL_CACHING:
-			physaddr |= _PAGE_CACHE040;
-			break;
-		case IOMAP_NOCACHE_SER:
-		default:
-			physaddr |= _PAGE_NOCACHE_S;
-			break;
-		case IOMAP_NOCACHE_NONSER:
-			physaddr |= _PAGE_NOCACHE;
-			break;
-		case IOMAP_WRITETHROUGH:
-			physaddr |= _PAGE_CACHE040W;
-			break;
-		}
-	} else {
-		physaddr |= (_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_DIRTY);
-		switch (cacheflag) {
-		case IOMAP_NOCACHE_SER:
-		case IOMAP_NOCACHE_NONSER:
-		default:
-			physaddr |= _PAGE_NOCACHE030;
-			break;
-		case IOMAP_FULL_CACHING:
-		case IOMAP_WRITETHROUGH:
-			break;
-		}
-	}
-
-	while ((long)size > 0) {
-#ifdef DEBUG
-		if (!(virtaddr & (PTRTREESIZE-1)))
-			printk ("\npa=%#lx va=%#lx ", physaddr, virtaddr);
-#endif
-		pgd_dir = pgd_offset_k(virtaddr);
-		pmd_dir = pmd_alloc(&init_mm, pgd_dir, virtaddr);
-		if (!pmd_dir) {
-			printk("ioremap: no mem for pmd_dir\n");
-			return NULL;
-		}
-
-		if (CPU_IS_020_OR_030) {
-			pmd_dir->pmd[(virtaddr/PTRTREESIZE) & 15] = physaddr;
-			physaddr += PTRTREESIZE;
-			virtaddr += PTRTREESIZE;
-			size -= PTRTREESIZE;
-		} else {
-			pte_dir = pte_alloc_kernel(pmd_dir, virtaddr);
-			if (!pte_dir) {
-				printk("ioremap: no mem for pte_dir\n");
-				return NULL;
-			}
-
-			pte_val(*pte_dir) = physaddr;
-			virtaddr += PAGE_SIZE;
-			physaddr += PAGE_SIZE;
-			size -= PAGE_SIZE;
-		}
-	}
-#ifdef DEBUG
-	printk("\n");
-#endif
-	flush_tlb_all();
-
-	return (void __iomem *)retaddr;
-}
-EXPORT_SYMBOL(__ioremap);
-
-/*
- * Unmap a ioremap()ed region again
- */
-void iounmap(void __iomem *addr)
-{
-#ifdef CONFIG_AMIGA
-	if ((!MACH_IS_AMIGA) ||
-	    (((unsigned long)addr < 0x40000000) ||
-	     ((unsigned long)addr > 0x60000000)))
-			free_io_area((__force void *)addr);
-#else
-	free_io_area((__force void *)addr);
-#endif
-}
-EXPORT_SYMBOL(iounmap);
-
-/*
- * __iounmap unmaps nearly everything, so be careful
- * it doesn't free currently pointer/page tables anymore but it
- * wans't used anyway and might be added later.
- */
-void __iounmap(void *addr, unsigned long size)
-{
-	unsigned long virtaddr = (unsigned long)addr;
-	pgd_t *pgd_dir;
-	pmd_t *pmd_dir;
-	pte_t *pte_dir;
-
-	while ((long)size > 0) {
-		pgd_dir = pgd_offset_k(virtaddr);
-		if (pgd_bad(*pgd_dir)) {
-			printk("iounmap: bad pgd(%08lx)\n", pgd_val(*pgd_dir));
-			pgd_clear(pgd_dir);
-			return;
-		}
-		pmd_dir = pmd_offset(pgd_dir, virtaddr);
-
-		if (CPU_IS_020_OR_030) {
-			int pmd_off = (virtaddr/PTRTREESIZE) & 15;
-			int pmd_type = pmd_dir->pmd[pmd_off] & _DESCTYPE_MASK;
-
-			if (pmd_type == _PAGE_PRESENT) {
-				pmd_dir->pmd[pmd_off] = 0;
-				virtaddr += PTRTREESIZE;
-				size -= PTRTREESIZE;
-				continue;
-			} else if (pmd_type == 0)
-				continue;
-		}
-
-		if (pmd_bad(*pmd_dir)) {
-			printk("iounmap: bad pmd (%08lx)\n", pmd_val(*pmd_dir));
-			pmd_clear(pmd_dir);
-			return;
-		}
-		pte_dir = pte_offset_kernel(pmd_dir, virtaddr);
-
-		pte_val(*pte_dir) = 0;
-		virtaddr += PAGE_SIZE;
-		size -= PAGE_SIZE;
-	}
-
-	flush_tlb_all();
-}
-
-/*
- * Set new cache mode for some kernel address space.
- * The caller must push data for that range itself, if such data may already
- * be in the cache.
- */
-void kernel_set_cachemode(void *addr, unsigned long size, int cmode)
-{
-	unsigned long virtaddr = (unsigned long)addr;
-	pgd_t *pgd_dir;
-	pmd_t *pmd_dir;
-	pte_t *pte_dir;
-
-	if (CPU_IS_040_OR_060) {
-		switch (cmode) {
-		case IOMAP_FULL_CACHING:
-			cmode = _PAGE_CACHE040;
-			break;
-		case IOMAP_NOCACHE_SER:
-		default:
-			cmode = _PAGE_NOCACHE_S;
-			break;
-		case IOMAP_NOCACHE_NONSER:
-			cmode = _PAGE_NOCACHE;
-			break;
-		case IOMAP_WRITETHROUGH:
-			cmode = _PAGE_CACHE040W;
-			break;
-		}
-	} else {
-		switch (cmode) {
-		case IOMAP_NOCACHE_SER:
-		case IOMAP_NOCACHE_NONSER:
-		default:
-			cmode = _PAGE_NOCACHE030;
-			break;
-		case IOMAP_FULL_CACHING:
-		case IOMAP_WRITETHROUGH:
-			cmode = 0;
-		}
-	}
-
-	while ((long)size > 0) {
-		pgd_dir = pgd_offset_k(virtaddr);
-		if (pgd_bad(*pgd_dir)) {
-			printk("iocachemode: bad pgd(%08lx)\n", pgd_val(*pgd_dir));
-			pgd_clear(pgd_dir);
-			return;
-		}
-		pmd_dir = pmd_offset(pgd_dir, virtaddr);
-
-		if (CPU_IS_020_OR_030) {
-			int pmd_off = (virtaddr/PTRTREESIZE) & 15;
-
-			if ((pmd_dir->pmd[pmd_off] & _DESCTYPE_MASK) == _PAGE_PRESENT) {
-				pmd_dir->pmd[pmd_off] = (pmd_dir->pmd[pmd_off] &
-							 _CACHEMASK040) | cmode;
-				virtaddr += PTRTREESIZE;
-				size -= PTRTREESIZE;
-				continue;
-			}
-		}
-
-		if (pmd_bad(*pmd_dir)) {
-			printk("iocachemode: bad pmd (%08lx)\n", pmd_val(*pmd_dir));
-			pmd_clear(pmd_dir);
-			return;
-		}
-		pte_dir = pte_offset_kernel(pmd_dir, virtaddr);
-
-		pte_val(*pte_dir) = (pte_val(*pte_dir) & _CACHEMASK040) | cmode;
-		virtaddr += PAGE_SIZE;
-		size -= PAGE_SIZE;
-	}
-
-	flush_tlb_all();
-}
-EXPORT_SYMBOL(kernel_set_cachemode);
diff -druN linux-2.6.39-libre/arch/m68k/mm/kmap_no.c linux-3.0-rc7-libre/arch/m68k/mm/kmap_no.c
--- linux-2.6.39-libre/arch/m68k/mm/kmap_no.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/m68k/mm/kmap_no.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,45 +0,0 @@
-/*
- *  linux/arch/m68knommu/mm/kmap.c
- *
- *  Copyright (C) 2000 Lineo, <davidm@snapgear.com>
- *  Copyright (C) 2000-2002 David McCullough <davidm@snapgear.com>
- */
-
-#include <linux/mm.h>
-#include <linux/kernel.h>
-#include <linux/string.h>
-#include <linux/types.h>
-#include <linux/vmalloc.h>
-
-#include <asm/setup.h>
-#include <asm/segment.h>
-#include <asm/page.h>
-#include <asm/pgalloc.h>
-#include <asm/io.h>
-#include <asm/system.h>
-
-#undef DEBUG
-
-/*
- * Map some physical address range into the kernel address space.
- */
-void *__ioremap(unsigned long physaddr, unsigned long size, int cacheflag)
-{
-	return (void *)physaddr;
-}
-
-/*
- * Unmap a ioremap()ed region again.
- */
-void iounmap(void *addr)
-{
-}
-
-/*
- * Set new cache mode for some kernel address space.
- * The caller must push data for that range itself, if such data may already
- * be in the cache.
- */
-void kernel_set_cachemode(void *addr, unsigned long size, int cmode)
-{
-}
diff -druN linux-2.6.39-libre/arch/m68k/mm/Makefile linux-3.0-rc7-libre/arch/m68k/mm/Makefile
--- linux-2.6.39-libre/arch/m68k/mm/Makefile	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/m68k/mm/Makefile	2011-07-11 19:51:52.000000000 -0400
@@ -1,5 +1,9 @@
-ifdef CONFIG_MMU
-include arch/m68k/mm/Makefile_mm
-else
-include arch/m68k/mm/Makefile_no
-endif
+#
+# Makefile for the linux m68k-specific parts of the memory manager.
+#
+
+obj-y	:= init.o
+
+obj-$(CONFIG_MMU)		+= cache.o fault.o hwtest.o
+obj-$(CONFIG_MMU_MOTOROLA)	+= kmap.o memory.o motorola.o
+obj-$(CONFIG_MMU_SUN3)		+= sun3kmap.o sun3mmu.o
diff -druN linux-2.6.39-libre/arch/m68k/mm/Makefile_mm linux-3.0-rc7-libre/arch/m68k/mm/Makefile_mm
--- linux-2.6.39-libre/arch/m68k/mm/Makefile_mm	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/m68k/mm/Makefile_mm	1969-12-31 19:00:00.000000000 -0500
@@ -1,8 +0,0 @@
-#
-# Makefile for the linux m68k-specific parts of the memory manager.
-#
-
-obj-y		:= cache.o init.o fault.o hwtest.o
-
-obj-$(CONFIG_MMU_MOTOROLA)	+= kmap.o memory.o motorola.o
-obj-$(CONFIG_MMU_SUN3)		+= sun3kmap.o sun3mmu.o
diff -druN linux-2.6.39-libre/arch/m68k/mm/Makefile_no linux-3.0-rc7-libre/arch/m68k/mm/Makefile_no
--- linux-2.6.39-libre/arch/m68k/mm/Makefile_no	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/m68k/mm/Makefile_no	1969-12-31 19:00:00.000000000 -0500
@@ -1,5 +0,0 @@
-#
-# Makefile for the linux m68knommu specific parts of the memory manager.
-#
-
-obj-y += init.o kmap.o
diff -druN linux-2.6.39-libre/arch/m68k/platform/68328/entry.S linux-3.0-rc7-libre/arch/m68k/platform/68328/entry.S
--- linux-2.6.39-libre/arch/m68k/platform/68328/entry.S	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/m68k/platform/68328/entry.S	2011-07-11 19:51:52.000000000 -0400
@@ -10,7 +10,6 @@
  * Linux/m68k support by Hamish Macdonald
  */
 
-#include <linux/sys.h>
 #include <linux/linkage.h>
 #include <asm/thread_info.h>
 #include <asm/unistd.h>
@@ -80,7 +79,7 @@
 	movel	%sp,%d1			/* get thread_info pointer */
 	andl	#-THREAD_SIZE,%d1
 	movel	%d1,%a2
-	btst	#(TIF_SYSCALL_TRACE%8),%a2@(TI_FLAGS+(31-TIF_SYSCALL_TRACE)/8)
+	btst	#(TIF_SYSCALL_TRACE%8),%a2@(TINFO_FLAGS+(31-TIF_SYSCALL_TRACE)/8)
 	jne	do_trace
 	cmpl	#NR_syscalls,%d0
 	jcc	badsys
@@ -107,12 +106,12 @@
 	andl	#-THREAD_SIZE,%d1
 	movel	%d1,%a2
 1:
-	move	%a2@(TI_FLAGS),%d1	/* thread_info->flags */
+	move	%a2@(TINFO_FLAGS),%d1	/* thread_info->flags */
 	jne	Lwork_to_do
 	RESTORE_ALL
 
 Lwork_to_do:
-	movel	%a2@(TI_FLAGS),%d1	/* thread_info->flags */
+	movel	%a2@(TINFO_FLAGS),%d1	/* thread_info->flags */
 	btst	#TIF_NEED_RESCHED,%d1
 	jne	reschedule
 
diff -druN linux-2.6.39-libre/arch/m68k/platform/68360/entry.S linux-3.0-rc7-libre/arch/m68k/platform/68360/entry.S
--- linux-2.6.39-libre/arch/m68k/platform/68360/entry.S	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/m68k/platform/68360/entry.S	2011-07-11 19:51:52.000000000 -0400
@@ -12,7 +12,6 @@
  * M68360 Port by SED Systems, and Lineo.
  */
 
-#include <linux/sys.h>
 #include <linux/linkage.h>
 #include <asm/thread_info.h>
 #include <asm/unistd.h>
@@ -76,7 +75,7 @@
 	movel	%sp,%d1			/* get thread_info pointer */
 	andl	#-THREAD_SIZE,%d1
 	movel	%d1,%a2
-	btst	#(TIF_SYSCALL_TRACE%8),%a2@(TI_FLAGS+(31-TIF_SYSCALL_TRACE)/8)
+	btst	#(TIF_SYSCALL_TRACE%8),%a2@(TINFO_FLAGS+(31-TIF_SYSCALL_TRACE)/8)
 	jne	do_trace
 	cmpl	#NR_syscalls,%d0
 	jcc	badsys
@@ -103,12 +102,12 @@
 	andl	#-THREAD_SIZE,%d1
 	movel	%d1,%a2
 1:
-	move	%a2@(TI_FLAGS),%d1	/* thread_info->flags */
+	move	%a2@(TINFO_FLAGS),%d1	/* thread_info->flags */
 	jne	Lwork_to_do
 	RESTORE_ALL
 
 Lwork_to_do:
-	movel	%a2@(TI_FLAGS),%d1	/* thread_info->flags */
+	movel	%a2@(TINFO_FLAGS),%d1	/* thread_info->flags */
 	btst	#TIF_NEED_RESCHED,%d1
 	jne	reschedule
 
diff -druN linux-2.6.39-libre/arch/m68k/platform/coldfire/dma.c linux-3.0-rc7-libre/arch/m68k/platform/coldfire/dma.c
--- linux-2.6.39-libre/arch/m68k/platform/coldfire/dma.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/m68k/platform/coldfire/dma.c	2011-07-11 19:51:52.000000000 -0400
@@ -9,6 +9,7 @@
 /***************************************************************************/
 
 #include <linux/kernel.h>
+#include <linux/module.h>
 #include <asm/dma.h>
 #include <asm/coldfire.h>
 #include <asm/mcfsim.h>
@@ -33,7 +34,9 @@
 	MCFDMA_BASE3,
 #endif
 };
+EXPORT_SYMBOL(dma_base_addr);
 
 unsigned int dma_device_address[MAX_M68K_DMA_CHANNELS];
+EXPORT_SYMBOL(dma_device_address);
 
 /***************************************************************************/
diff -druN linux-2.6.39-libre/arch/m68k/platform/coldfire/entry.S linux-3.0-rc7-libre/arch/m68k/platform/coldfire/entry.S
--- linux-2.6.39-libre/arch/m68k/platform/coldfire/entry.S	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/m68k/platform/coldfire/entry.S	2011-07-11 19:51:52.000000000 -0400
@@ -26,7 +26,6 @@
  * Bug, speed and maintainability fixes by Philippe De Muyter <phdm@macqel.be>
  */
 
-#include <linux/sys.h>
 #include <linux/linkage.h>
 #include <asm/unistd.h>
 #include <asm/thread_info.h>
@@ -78,7 +77,7 @@
 	movel	%d2,%a0
 	movel	%a0@,%a1		/* save top of frame */
 	movel	%sp,%a1@(TASK_THREAD+THREAD_ESP0)
-	btst	#(TIF_SYSCALL_TRACE%8),%a0@(TI_FLAGS+(31-TIF_SYSCALL_TRACE)/8)
+	btst	#(TIF_SYSCALL_TRACE%8),%a0@(TINFO_FLAGS+(31-TIF_SYSCALL_TRACE)/8)
 	bnes	1f
 
 	movel	%d3,%a0
@@ -113,11 +112,11 @@
 	movel	%sp,%d1			/* get thread_info pointer */
 	andl	#-THREAD_SIZE,%d1	/* at base of kernel stack */
 	movel	%d1,%a0
-	movel	%a0@(TI_FLAGS),%d1	/* get thread_info->flags */
+	movel	%a0@(TINFO_FLAGS),%d1	/* get thread_info->flags */
 	andl	#(1<<TIF_NEED_RESCHED),%d1
 	jeq	Lkernel_return
 
-	movel	%a0@(TI_PREEMPTCOUNT),%d1
+	movel	%a0@(TINFO_PREEMPT),%d1
 	cmpl	#0,%d1
 	jne	Lkernel_return
 
@@ -137,14 +136,14 @@
 	movel	%sp,%d1			/* get thread_info pointer */
 	andl	#-THREAD_SIZE,%d1	/* at base of kernel stack */
 	movel	%d1,%a0
-	movel	%a0@(TI_FLAGS),%d1	/* get thread_info->flags */
+	movel	%a0@(TINFO_FLAGS),%d1	/* get thread_info->flags */
 	jne	Lwork_to_do		/* still work to do */
 
 Lreturn:
 	RESTORE_USER
 
 Lwork_to_do:
-	movel	%a0@(TI_FLAGS),%d1	/* get thread_info->flags */
+	movel	%a0@(TINFO_FLAGS),%d1	/* get thread_info->flags */
 	move	#0x2000,%sr		/* enable intrs again */
 	btst	#TIF_NEED_RESCHED,%d1
 	jne	reschedule
diff -druN linux-2.6.39-libre/arch/m68k/platform/coldfire/head.S linux-3.0-rc7-libre/arch/m68k/platform/coldfire/head.S
--- linux-2.6.39-libre/arch/m68k/platform/coldfire/head.S	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/m68k/platform/coldfire/head.S	2011-07-11 19:51:52.000000000 -0400
@@ -8,7 +8,6 @@
 
 /*****************************************************************************/
 
-#include <linux/sys.h>
 #include <linux/linkage.h>
 #include <linux/init.h>
 #include <asm/asm-offsets.h>
diff -druN linux-2.6.39-libre/arch/microblaze/include/asm/unistd.h linux-3.0-rc7-libre/arch/microblaze/include/asm/unistd.h
--- linux-2.6.39-libre/arch/microblaze/include/asm/unistd.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/microblaze/include/asm/unistd.h	2011-07-11 19:51:52.000000000 -0400
@@ -390,8 +390,9 @@
 #define __NR_open_by_handle_at	372
 #define __NR_clock_adjtime	373
 #define __NR_syncfs		374
+#define __NR_setns		375
 
-#define __NR_syscalls		375
+#define __NR_syscalls		376
 
 #ifdef __KERNEL__
 #ifndef __ASSEMBLY__
diff -druN linux-2.6.39-libre/arch/microblaze/Kconfig linux-3.0-rc7-libre/arch/microblaze/Kconfig
--- linux-2.6.39-libre/arch/microblaze/Kconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/microblaze/Kconfig	2011-07-11 19:51:52.000000000 -0400
@@ -33,12 +33,6 @@
 config ARCH_HAS_ILOG2_U64
 	def_bool n
 
-config GENERIC_FIND_NEXT_BIT
-	def_bool y
-
-config GENERIC_FIND_BIT_LE
-	def_bool y
-
 config GENERIC_HWEIGHT
 	def_bool y
 
diff -druN linux-2.6.39-libre/arch/microblaze/kernel/prom.c linux-3.0-rc7-libre/arch/microblaze/kernel/prom.c
--- linux-2.6.39-libre/arch/microblaze/kernel/prom.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/microblaze/kernel/prom.c	2011-07-11 19:51:52.000000000 -0400
@@ -130,7 +130,7 @@
 	 * device-tree, including the platform type, initrd location and
 	 * size, TCE reserve, and more ...
 	 */
-	of_scan_flat_dt(early_init_dt_scan_chosen, NULL);
+	of_scan_flat_dt(early_init_dt_scan_chosen, cmd_line);
 
 	/* Scan memory nodes and rebuild MEMBLOCKs */
 	memblock_init();
diff -druN linux-2.6.39-libre/arch/microblaze/kernel/syscall_table.S linux-3.0-rc7-libre/arch/microblaze/kernel/syscall_table.S
--- linux-2.6.39-libre/arch/microblaze/kernel/syscall_table.S	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/microblaze/kernel/syscall_table.S	2011-07-11 19:51:52.000000000 -0400
@@ -379,3 +379,4 @@
 	.long sys_open_by_handle_at
 	.long sys_clock_adjtime
 	.long sys_syncfs
+	.long sys_setns			/* 375 */
diff -druN linux-2.6.39-libre/arch/microblaze/kernel/timer.c linux-3.0-rc7-libre/arch/microblaze/kernel/timer.c
--- linux-2.6.39-libre/arch/microblaze/kernel/timer.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/microblaze/kernel/timer.c	2011-07-11 19:51:52.000000000 -0400
@@ -217,16 +217,12 @@
 	.rating		= 300,
 	.read		= microblaze_read,
 	.mask		= CLOCKSOURCE_MASK(32),
-	.shift		= 8, /* I can shift it */
 	.flags		= CLOCK_SOURCE_IS_CONTINUOUS,
 };
 
 static int __init microblaze_clocksource_init(void)
 {
-	clocksource_microblaze.mult =
-			clocksource_hz2mult(timer_clock_freq,
-						clocksource_microblaze.shift);
-	if (clocksource_register(&clocksource_microblaze))
+	if (clocksource_register_hz(&clocksource_microblaze, timer_clock_freq))
 		panic("failed to register clocksource");
 
 	/* stop timer1 */
diff -druN linux-2.6.39-libre/arch/microblaze/mm/init.c linux-3.0-rc7-libre/arch/microblaze/mm/init.c
--- linux-2.6.39-libre/arch/microblaze/mm/init.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/microblaze/mm/init.c	2011-07-11 19:51:52.000000000 -0400
@@ -32,8 +32,6 @@
 EXPORT_SYMBOL(__page_offset);
 
 #else
-DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
-
 static int init_bootmem_done;
 #endif /* CONFIG_MMU */
 
diff -druN linux-2.6.39-libre/arch/mips/alchemy/common/dbdma.c linux-3.0-rc7-libre/arch/mips/alchemy/common/dbdma.c
--- linux-2.6.39-libre/arch/mips/alchemy/common/dbdma.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/mips/alchemy/common/dbdma.c	2011-07-11 19:51:52.000000000 -0400
@@ -36,7 +36,7 @@
 #include <linux/spinlock.h>
 #include <linux/interrupt.h>
 #include <linux/module.h>
-#include <linux/sysdev.h>
+#include <linux/syscore_ops.h>
 #include <asm/mach-au1x00/au1000.h>
 #include <asm/mach-au1x00/au1xxx_dbdma.h>
 
@@ -58,7 +58,8 @@
 /* I couldn't find a macro that did this... */
 #define ALIGN_ADDR(x, a)	((((u32)(x)) + (a-1)) & ~(a-1))
 
-static dbdma_global_t *dbdma_gptr = (dbdma_global_t *)DDMA_GLOBAL_BASE;
+static dbdma_global_t *dbdma_gptr =
+			(dbdma_global_t *)KSEG1ADDR(AU1550_DBDMA_CONF_PHYS_ADDR);
 static int dbdma_initialized;
 
 static dbdev_tab_t dbdev_tab[] = {
@@ -299,7 +300,7 @@
 	if (ctp != NULL) {
 		memset(ctp, 0, sizeof(chan_tab_t));
 		ctp->chan_index = chan = i;
-		dcp = DDMA_CHANNEL_BASE;
+		dcp = KSEG1ADDR(AU1550_DBDMA_PHYS_ADDR);
 		dcp += (0x0100 * chan);
 		ctp->chan_ptr = (au1x_dma_chan_t *)dcp;
 		cp = (au1x_dma_chan_t *)dcp;
@@ -958,105 +959,75 @@
 }
 
 
-struct alchemy_dbdma_sysdev {
-	struct sys_device sysdev;
-	u32 pm_regs[NUM_DBDMA_CHANS + 1][6];
-};
+static unsigned long alchemy_dbdma_pm_data[NUM_DBDMA_CHANS + 1][6];
 
-static int alchemy_dbdma_suspend(struct sys_device *dev,
-				 pm_message_t state)
+static int alchemy_dbdma_suspend(void)
 {
-	struct alchemy_dbdma_sysdev *sdev =
-		container_of(dev, struct alchemy_dbdma_sysdev, sysdev);
 	int i;
-	u32 addr;
+	void __iomem *addr;
 
-	addr = DDMA_GLOBAL_BASE;
-	sdev->pm_regs[0][0] = au_readl(addr + 0x00);
-	sdev->pm_regs[0][1] = au_readl(addr + 0x04);
-	sdev->pm_regs[0][2] = au_readl(addr + 0x08);
-	sdev->pm_regs[0][3] = au_readl(addr + 0x0c);
+	addr = (void __iomem *)KSEG1ADDR(AU1550_DBDMA_CONF_PHYS_ADDR);
+	alchemy_dbdma_pm_data[0][0] = __raw_readl(addr + 0x00);
+	alchemy_dbdma_pm_data[0][1] = __raw_readl(addr + 0x04);
+	alchemy_dbdma_pm_data[0][2] = __raw_readl(addr + 0x08);
+	alchemy_dbdma_pm_data[0][3] = __raw_readl(addr + 0x0c);
 
 	/* save channel configurations */
-	for (i = 1, addr = DDMA_CHANNEL_BASE; i <= NUM_DBDMA_CHANS; i++) {
-		sdev->pm_regs[i][0] = au_readl(addr + 0x00);
-		sdev->pm_regs[i][1] = au_readl(addr + 0x04);
-		sdev->pm_regs[i][2] = au_readl(addr + 0x08);
-		sdev->pm_regs[i][3] = au_readl(addr + 0x0c);
-		sdev->pm_regs[i][4] = au_readl(addr + 0x10);
-		sdev->pm_regs[i][5] = au_readl(addr + 0x14);
+	addr = (void __iomem *)KSEG1ADDR(AU1550_DBDMA_PHYS_ADDR);
+	for (i = 1; i <= NUM_DBDMA_CHANS; i++) {
+		alchemy_dbdma_pm_data[i][0] = __raw_readl(addr + 0x00);
+		alchemy_dbdma_pm_data[i][1] = __raw_readl(addr + 0x04);
+		alchemy_dbdma_pm_data[i][2] = __raw_readl(addr + 0x08);
+		alchemy_dbdma_pm_data[i][3] = __raw_readl(addr + 0x0c);
+		alchemy_dbdma_pm_data[i][4] = __raw_readl(addr + 0x10);
+		alchemy_dbdma_pm_data[i][5] = __raw_readl(addr + 0x14);
 
 		/* halt channel */
-		au_writel(sdev->pm_regs[i][0] & ~1, addr + 0x00);
-		au_sync();
-		while (!(au_readl(addr + 0x14) & 1))
-			au_sync();
+		__raw_writel(alchemy_dbdma_pm_data[i][0] & ~1, addr + 0x00);
+		wmb();
+		while (!(__raw_readl(addr + 0x14) & 1))
+			wmb();
 
 		addr += 0x100;	/* next channel base */
 	}
 	/* disable channel interrupts */
-	au_writel(0, DDMA_GLOBAL_BASE + 0x0c);
-	au_sync();
+	addr = (void __iomem *)KSEG1ADDR(AU1550_DBDMA_CONF_PHYS_ADDR);
+	__raw_writel(0, addr + 0x0c);
+	wmb();
 
 	return 0;
 }
 
-static int alchemy_dbdma_resume(struct sys_device *dev)
+static void alchemy_dbdma_resume(void)
 {
-	struct alchemy_dbdma_sysdev *sdev =
-		container_of(dev, struct alchemy_dbdma_sysdev, sysdev);
 	int i;
-	u32 addr;
+	void __iomem *addr;
 
-	addr = DDMA_GLOBAL_BASE;
-	au_writel(sdev->pm_regs[0][0], addr + 0x00);
-	au_writel(sdev->pm_regs[0][1], addr + 0x04);
-	au_writel(sdev->pm_regs[0][2], addr + 0x08);
-	au_writel(sdev->pm_regs[0][3], addr + 0x0c);
+	addr = (void __iomem *)KSEG1ADDR(AU1550_DBDMA_CONF_PHYS_ADDR);
+	__raw_writel(alchemy_dbdma_pm_data[0][0], addr + 0x00);
+	__raw_writel(alchemy_dbdma_pm_data[0][1], addr + 0x04);
+	__raw_writel(alchemy_dbdma_pm_data[0][2], addr + 0x08);
+	__raw_writel(alchemy_dbdma_pm_data[0][3], addr + 0x0c);
 
 	/* restore channel configurations */
-	for (i = 1, addr = DDMA_CHANNEL_BASE; i <= NUM_DBDMA_CHANS; i++) {
-		au_writel(sdev->pm_regs[i][0], addr + 0x00);
-		au_writel(sdev->pm_regs[i][1], addr + 0x04);
-		au_writel(sdev->pm_regs[i][2], addr + 0x08);
-		au_writel(sdev->pm_regs[i][3], addr + 0x0c);
-		au_writel(sdev->pm_regs[i][4], addr + 0x10);
-		au_writel(sdev->pm_regs[i][5], addr + 0x14);
-		au_sync();
+	addr = (void __iomem *)KSEG1ADDR(AU1550_DBDMA_PHYS_ADDR);
+	for (i = 1; i <= NUM_DBDMA_CHANS; i++) {
+		__raw_writel(alchemy_dbdma_pm_data[i][0], addr + 0x00);
+		__raw_writel(alchemy_dbdma_pm_data[i][1], addr + 0x04);
+		__raw_writel(alchemy_dbdma_pm_data[i][2], addr + 0x08);
+		__raw_writel(alchemy_dbdma_pm_data[i][3], addr + 0x0c);
+		__raw_writel(alchemy_dbdma_pm_data[i][4], addr + 0x10);
+		__raw_writel(alchemy_dbdma_pm_data[i][5], addr + 0x14);
+		wmb();
 		addr += 0x100;	/* next channel base */
 	}
-
-	return 0;
 }
 
-static struct sysdev_class alchemy_dbdma_sysdev_class = {
-	.name		= "dbdma",
+static struct syscore_ops alchemy_dbdma_syscore_ops = {
 	.suspend	= alchemy_dbdma_suspend,
 	.resume		= alchemy_dbdma_resume,
 };
 
-static int __init alchemy_dbdma_sysdev_init(void)
-{
-	struct alchemy_dbdma_sysdev *sdev;
-	int ret;
-
-	ret = sysdev_class_register(&alchemy_dbdma_sysdev_class);
-	if (ret)
-		return ret;
-
-	sdev = kzalloc(sizeof(struct alchemy_dbdma_sysdev), GFP_KERNEL);
-	if (!sdev)
-		return -ENOMEM;
-
-	sdev->sysdev.id = -1;
-	sdev->sysdev.cls = &alchemy_dbdma_sysdev_class;
-	ret = sysdev_register(&sdev->sysdev);
-	if (ret)
-		kfree(sdev);
-
-	return ret;
-}
-
 static int __init au1xxx_dbdma_init(void)
 {
 	int irq_nr, ret;
@@ -1084,11 +1055,7 @@
 	else {
 		dbdma_initialized = 1;
 		printk(KERN_INFO "Alchemy DBDMA initialized\n");
-		ret = alchemy_dbdma_sysdev_init();
-		if (ret) {
-			printk(KERN_ERR "DBDMA PM init failed\n");
-			ret = 0;
-		}
+		register_syscore_ops(&alchemy_dbdma_syscore_ops);
 	}
 
 	return ret;
diff -druN linux-2.6.39-libre/arch/mips/alchemy/common/dma.c linux-3.0-rc7-libre/arch/mips/alchemy/common/dma.c
--- linux-2.6.39-libre/arch/mips/alchemy/common/dma.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/mips/alchemy/common/dma.c	2011-07-11 19:51:52.000000000 -0400
@@ -58,6 +58,9 @@
  * returned from request_dma.
  */
 
+/* DMA Channel register block spacing */
+#define DMA_CHANNEL_LEN		0x00000100
+
 DEFINE_SPINLOCK(au1000_dma_spin_lock);
 
 struct dma_chan au1000_dma_table[NUM_AU1000_DMA_CHANNELS] = {
@@ -77,22 +80,23 @@
 	unsigned int fifo_addr;
 	unsigned int dma_mode;
 } dma_dev_table[DMA_NUM_DEV] = {
-	{UART0_ADDR + UART_TX, 0},
-	{UART0_ADDR + UART_RX, 0},
-	{0, 0},
-	{0, 0},
-	{AC97C_DATA, DMA_DW16 },          /* coherent */
-	{AC97C_DATA, DMA_DR | DMA_DW16 }, /* coherent */
-	{UART3_ADDR + UART_TX, DMA_DW8 | DMA_NC},
-	{UART3_ADDR + UART_RX, DMA_DR | DMA_DW8 | DMA_NC},
-	{USBD_EP0RD, DMA_DR | DMA_DW8 | DMA_NC},
-	{USBD_EP0WR, DMA_DW8 | DMA_NC},
-	{USBD_EP2WR, DMA_DW8 | DMA_NC},
-	{USBD_EP3WR, DMA_DW8 | DMA_NC},
-	{USBD_EP4RD, DMA_DR | DMA_DW8 | DMA_NC},
-	{USBD_EP5RD, DMA_DR | DMA_DW8 | DMA_NC},
-	{I2S_DATA, DMA_DW32 | DMA_NC},
-	{I2S_DATA, DMA_DR | DMA_DW32 | DMA_NC}
+	{ AU1000_UART0_PHYS_ADDR + 0x04, DMA_DW8 },		/* UART0_TX */
+	{ AU1000_UART0_PHYS_ADDR + 0x00, DMA_DW8 | DMA_DR },	/* UART0_RX */
+	{ 0, 0 },	/* DMA_REQ0 */
+	{ 0, 0 },	/* DMA_REQ1 */
+	{ AU1000_AC97_PHYS_ADDR + 0x08, DMA_DW16 },		/* AC97 TX c */
+	{ AU1000_AC97_PHYS_ADDR + 0x08, DMA_DW16 | DMA_DR },	/* AC97 RX c */
+	{ AU1000_UART3_PHYS_ADDR + 0x04, DMA_DW8 | DMA_NC },	/* UART3_TX */
+	{ AU1000_UART3_PHYS_ADDR + 0x00, DMA_DW8 | DMA_NC | DMA_DR }, /* UART3_RX */
+	{ AU1000_USBD_PHYS_ADDR + 0x00, DMA_DW8 | DMA_NC | DMA_DR }, /* EP0RD */
+	{ AU1000_USBD_PHYS_ADDR + 0x04, DMA_DW8 | DMA_NC }, /* EP0WR */
+	{ AU1000_USBD_PHYS_ADDR + 0x08, DMA_DW8 | DMA_NC }, /* EP2WR */
+	{ AU1000_USBD_PHYS_ADDR + 0x0c, DMA_DW8 | DMA_NC }, /* EP3WR */
+	{ AU1000_USBD_PHYS_ADDR + 0x10, DMA_DW8 | DMA_NC | DMA_DR }, /* EP4RD */
+	{ AU1000_USBD_PHYS_ADDR + 0x14, DMA_DW8 | DMA_NC | DMA_DR }, /* EP5RD */
+	/* on Au1500, these 2 are DMA_REQ2/3 (GPIO208/209) instead! */
+	{ AU1000_I2S_PHYS_ADDR + 0x00, DMA_DW32 | DMA_NC},	/* I2S TX */
+	{ AU1000_I2S_PHYS_ADDR + 0x00, DMA_DW32 | DMA_NC | DMA_DR}, /* I2S RX */
 };
 
 int au1000_dma_read_proc(char *buf, char **start, off_t fpos,
@@ -123,10 +127,10 @@
 
 /* Device FIFO addresses and default DMA modes - 2nd bank */
 static const struct dma_dev dma_dev_table_bank2[DMA_NUM_DEV_BANK2] = {
-	{ SD0_XMIT_FIFO, DMA_DS | DMA_DW8 },		/* coherent */
-	{ SD0_RECV_FIFO, DMA_DS | DMA_DR | DMA_DW8 },	/* coherent */
-	{ SD1_XMIT_FIFO, DMA_DS | DMA_DW8 },		/* coherent */
-	{ SD1_RECV_FIFO, DMA_DS | DMA_DR | DMA_DW8 }	/* coherent */
+	{ AU1100_SD0_PHYS_ADDR + 0x00, DMA_DS | DMA_DW8 },		/* coherent */
+	{ AU1100_SD0_PHYS_ADDR + 0x04, DMA_DS | DMA_DW8 | DMA_DR },	/* coherent */
+	{ AU1100_SD1_PHYS_ADDR + 0x00, DMA_DS | DMA_DW8 },		/* coherent */
+	{ AU1100_SD1_PHYS_ADDR + 0x04, DMA_DS | DMA_DW8 | DMA_DR }	/* coherent */
 };
 
 void dump_au1000_dma_channel(unsigned int dmanr)
@@ -202,7 +206,7 @@
 	}
 
 	/* fill it in */
-	chan->io = DMA_CHANNEL_BASE + i * DMA_CHANNEL_LEN;
+	chan->io = KSEG1ADDR(AU1000_DMA_PHYS_ADDR) + i * DMA_CHANNEL_LEN;
 	chan->dev_id = dev_id;
 	chan->dev_str = dev_str;
 	chan->fifo_addr = dev->fifo_addr;
diff -druN linux-2.6.39-libre/arch/mips/alchemy/common/irq.c linux-3.0-rc7-libre/arch/mips/alchemy/common/irq.c
--- linux-2.6.39-libre/arch/mips/alchemy/common/irq.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/mips/alchemy/common/irq.c	2011-07-11 19:51:52.000000000 -0400
@@ -30,7 +30,7 @@
 #include <linux/interrupt.h>
 #include <linux/irq.h>
 #include <linux/slab.h>
-#include <linux/sysdev.h>
+#include <linux/syscore_ops.h>
 
 #include <asm/irq_cpu.h>
 #include <asm/mipsregs.h>
@@ -39,6 +39,36 @@
 #include <asm/mach-pb1x00/pb1000.h>
 #endif
 
+/* Interrupt Controller register offsets */
+#define IC_CFG0RD	0x40
+#define IC_CFG0SET	0x40
+#define IC_CFG0CLR	0x44
+#define IC_CFG1RD	0x48
+#define IC_CFG1SET	0x48
+#define IC_CFG1CLR	0x4C
+#define IC_CFG2RD	0x50
+#define IC_CFG2SET	0x50
+#define IC_CFG2CLR	0x54
+#define IC_REQ0INT	0x54
+#define IC_SRCRD	0x58
+#define IC_SRCSET	0x58
+#define IC_SRCCLR	0x5C
+#define IC_REQ1INT	0x5C
+#define IC_ASSIGNRD	0x60
+#define IC_ASSIGNSET	0x60
+#define IC_ASSIGNCLR	0x64
+#define IC_WAKERD	0x68
+#define IC_WAKESET	0x68
+#define IC_WAKECLR	0x6C
+#define IC_MASKRD	0x70
+#define IC_MASKSET	0x70
+#define IC_MASKCLR	0x74
+#define IC_RISINGRD	0x78
+#define IC_RISINGCLR	0x78
+#define IC_FALLINGRD	0x7C
+#define IC_FALLINGCLR	0x7C
+#define IC_TESTBIT	0x80
+
 static int au1x_ic_settype(struct irq_data *d, unsigned int flow_type);
 
 /* NOTE on interrupt priorities: The original writers of this code said:
@@ -221,89 +251,101 @@
 static void au1x_ic0_unmask(struct irq_data *d)
 {
 	unsigned int bit = d->irq - AU1000_INTC0_INT_BASE;
-	au_writel(1 << bit, IC0_MASKSET);
-	au_writel(1 << bit, IC0_WAKESET);
-	au_sync();
+	void __iomem *base = (void __iomem *)KSEG1ADDR(AU1000_IC0_PHYS_ADDR);
+
+	__raw_writel(1 << bit, base + IC_MASKSET);
+	__raw_writel(1 << bit, base + IC_WAKESET);
+	wmb();
 }
 
 static void au1x_ic1_unmask(struct irq_data *d)
 {
 	unsigned int bit = d->irq - AU1000_INTC1_INT_BASE;
-	au_writel(1 << bit, IC1_MASKSET);
-	au_writel(1 << bit, IC1_WAKESET);
+	void __iomem *base = (void __iomem *)KSEG1ADDR(AU1000_IC1_PHYS_ADDR);
+
+	__raw_writel(1 << bit, base + IC_MASKSET);
+	__raw_writel(1 << bit, base + IC_WAKESET);
 
 /* very hacky. does the pb1000 cpld auto-disable this int?
  * nowhere in the current kernel sources is it disabled.	--mlau
  */
 #if defined(CONFIG_MIPS_PB1000)
 	if (d->irq == AU1000_GPIO15_INT)
-		au_writel(0x4000, PB1000_MDR); /* enable int */
+		__raw_writel(0x4000, (void __iomem *)PB1000_MDR); /* enable int */
 #endif
-	au_sync();
+	wmb();
 }
 
 static void au1x_ic0_mask(struct irq_data *d)
 {
 	unsigned int bit = d->irq - AU1000_INTC0_INT_BASE;
-	au_writel(1 << bit, IC0_MASKCLR);
-	au_writel(1 << bit, IC0_WAKECLR);
-	au_sync();
+	void __iomem *base = (void __iomem *)KSEG1ADDR(AU1000_IC0_PHYS_ADDR);
+
+	__raw_writel(1 << bit, base + IC_MASKCLR);
+	__raw_writel(1 << bit, base + IC_WAKECLR);
+	wmb();
 }
 
 static void au1x_ic1_mask(struct irq_data *d)
 {
 	unsigned int bit = d->irq - AU1000_INTC1_INT_BASE;
-	au_writel(1 << bit, IC1_MASKCLR);
-	au_writel(1 << bit, IC1_WAKECLR);
-	au_sync();
+	void __iomem *base = (void __iomem *)KSEG1ADDR(AU1000_IC1_PHYS_ADDR);
+
+	__raw_writel(1 << bit, base + IC_MASKCLR);
+	__raw_writel(1 << bit, base + IC_WAKECLR);
+	wmb();
 }
 
 static void au1x_ic0_ack(struct irq_data *d)
 {
 	unsigned int bit = d->irq - AU1000_INTC0_INT_BASE;
+	void __iomem *base = (void __iomem *)KSEG1ADDR(AU1000_IC0_PHYS_ADDR);
 
 	/*
 	 * This may assume that we don't get interrupts from
 	 * both edges at once, or if we do, that we don't care.
 	 */
-	au_writel(1 << bit, IC0_FALLINGCLR);
-	au_writel(1 << bit, IC0_RISINGCLR);
-	au_sync();
+	__raw_writel(1 << bit, base + IC_FALLINGCLR);
+	__raw_writel(1 << bit, base + IC_RISINGCLR);
+	wmb();
 }
 
 static void au1x_ic1_ack(struct irq_data *d)
 {
 	unsigned int bit = d->irq - AU1000_INTC1_INT_BASE;
+	void __iomem *base = (void __iomem *)KSEG1ADDR(AU1000_IC1_PHYS_ADDR);
 
 	/*
 	 * This may assume that we don't get interrupts from
 	 * both edges at once, or if we do, that we don't care.
 	 */
-	au_writel(1 << bit, IC1_FALLINGCLR);
-	au_writel(1 << bit, IC1_RISINGCLR);
-	au_sync();
+	__raw_writel(1 << bit, base + IC_FALLINGCLR);
+	__raw_writel(1 << bit, base + IC_RISINGCLR);
+	wmb();
 }
 
 static void au1x_ic0_maskack(struct irq_data *d)
 {
 	unsigned int bit = d->irq - AU1000_INTC0_INT_BASE;
+	void __iomem *base = (void __iomem *)KSEG1ADDR(AU1000_IC0_PHYS_ADDR);
 
-	au_writel(1 << bit, IC0_WAKECLR);
-	au_writel(1 << bit, IC0_MASKCLR);
-	au_writel(1 << bit, IC0_RISINGCLR);
-	au_writel(1 << bit, IC0_FALLINGCLR);
-	au_sync();
+	__raw_writel(1 << bit, base + IC_WAKECLR);
+	__raw_writel(1 << bit, base + IC_MASKCLR);
+	__raw_writel(1 << bit, base + IC_RISINGCLR);
+	__raw_writel(1 << bit, base + IC_FALLINGCLR);
+	wmb();
 }
 
 static void au1x_ic1_maskack(struct irq_data *d)
 {
 	unsigned int bit = d->irq - AU1000_INTC1_INT_BASE;
+	void __iomem *base = (void __iomem *)KSEG1ADDR(AU1000_IC1_PHYS_ADDR);
 
-	au_writel(1 << bit, IC1_WAKECLR);
-	au_writel(1 << bit, IC1_MASKCLR);
-	au_writel(1 << bit, IC1_RISINGCLR);
-	au_writel(1 << bit, IC1_FALLINGCLR);
-	au_sync();
+	__raw_writel(1 << bit, base + IC_WAKECLR);
+	__raw_writel(1 << bit, base + IC_MASKCLR);
+	__raw_writel(1 << bit, base + IC_RISINGCLR);
+	__raw_writel(1 << bit, base + IC_FALLINGCLR);
+	wmb();
 }
 
 static int au1x_ic1_setwake(struct irq_data *d, unsigned int on)
@@ -318,13 +360,13 @@
 		return -EINVAL;
 
 	local_irq_save(flags);
-	wakemsk = au_readl(SYS_WAKEMSK);
+	wakemsk = __raw_readl((void __iomem *)SYS_WAKEMSK);
 	if (on)
 		wakemsk |= 1 << bit;
 	else
 		wakemsk &= ~(1 << bit);
-	au_writel(wakemsk, SYS_WAKEMSK);
-	au_sync();
+	__raw_writel(wakemsk, (void __iomem *)SYS_WAKEMSK);
+	wmb();
 	local_irq_restore(flags);
 
 	return 0;
@@ -356,81 +398,74 @@
 static int au1x_ic_settype(struct irq_data *d, unsigned int flow_type)
 {
 	struct irq_chip *chip;
-	unsigned long icr[6];
-	unsigned int bit, ic, irq = d->irq;
+	unsigned int bit, irq = d->irq;
 	irq_flow_handler_t handler = NULL;
 	unsigned char *name = NULL;
+	void __iomem *base;
 	int ret;
 
 	if (irq >= AU1000_INTC1_INT_BASE) {
 		bit = irq - AU1000_INTC1_INT_BASE;
 		chip = &au1x_ic1_chip;
-		ic = 1;
+		base = (void __iomem *)KSEG1ADDR(AU1000_IC1_PHYS_ADDR);
 	} else {
 		bit = irq - AU1000_INTC0_INT_BASE;
 		chip = &au1x_ic0_chip;
-		ic = 0;
+		base = (void __iomem *)KSEG1ADDR(AU1000_IC0_PHYS_ADDR);
 	}
 
 	if (bit > 31)
 		return -EINVAL;
 
-	icr[0] = ic ? IC1_CFG0SET : IC0_CFG0SET;
-	icr[1] = ic ? IC1_CFG1SET : IC0_CFG1SET;
-	icr[2] = ic ? IC1_CFG2SET : IC0_CFG2SET;
-	icr[3] = ic ? IC1_CFG0CLR : IC0_CFG0CLR;
-	icr[4] = ic ? IC1_CFG1CLR : IC0_CFG1CLR;
-	icr[5] = ic ? IC1_CFG2CLR : IC0_CFG2CLR;
-
 	ret = 0;
 
 	switch (flow_type) {	/* cfgregs 2:1:0 */
 	case IRQ_TYPE_EDGE_RISING:	/* 0:0:1 */
-		au_writel(1 << bit, icr[5]);
-		au_writel(1 << bit, icr[4]);
-		au_writel(1 << bit, icr[0]);
+		__raw_writel(1 << bit, base + IC_CFG2CLR);
+		__raw_writel(1 << bit, base + IC_CFG1CLR);
+		__raw_writel(1 << bit, base + IC_CFG0SET);
 		handler = handle_edge_irq;
 		name = "riseedge";
 		break;
 	case IRQ_TYPE_EDGE_FALLING:	/* 0:1:0 */
-		au_writel(1 << bit, icr[5]);
-		au_writel(1 << bit, icr[1]);
-		au_writel(1 << bit, icr[3]);
+		__raw_writel(1 << bit, base + IC_CFG2CLR);
+		__raw_writel(1 << bit, base + IC_CFG1SET);
+		__raw_writel(1 << bit, base + IC_CFG0CLR);
 		handler = handle_edge_irq;
 		name = "falledge";
 		break;
 	case IRQ_TYPE_EDGE_BOTH:	/* 0:1:1 */
-		au_writel(1 << bit, icr[5]);
-		au_writel(1 << bit, icr[1]);
-		au_writel(1 << bit, icr[0]);
+		__raw_writel(1 << bit, base + IC_CFG2CLR);
+		__raw_writel(1 << bit, base + IC_CFG1SET);
+		__raw_writel(1 << bit, base + IC_CFG0SET);
 		handler = handle_edge_irq;
 		name = "bothedge";
 		break;
 	case IRQ_TYPE_LEVEL_HIGH:	/* 1:0:1 */
-		au_writel(1 << bit, icr[2]);
-		au_writel(1 << bit, icr[4]);
-		au_writel(1 << bit, icr[0]);
+		__raw_writel(1 << bit, base + IC_CFG2SET);
+		__raw_writel(1 << bit, base + IC_CFG1CLR);
+		__raw_writel(1 << bit, base + IC_CFG0SET);
 		handler = handle_level_irq;
 		name = "hilevel";
 		break;
 	case IRQ_TYPE_LEVEL_LOW:	/* 1:1:0 */
-		au_writel(1 << bit, icr[2]);
-		au_writel(1 << bit, icr[1]);
-		au_writel(1 << bit, icr[3]);
+		__raw_writel(1 << bit, base + IC_CFG2SET);
+		__raw_writel(1 << bit, base + IC_CFG1SET);
+		__raw_writel(1 << bit, base + IC_CFG0CLR);
 		handler = handle_level_irq;
 		name = "lowlevel";
 		break;
 	case IRQ_TYPE_NONE:		/* 0:0:0 */
-		au_writel(1 << bit, icr[5]);
-		au_writel(1 << bit, icr[4]);
-		au_writel(1 << bit, icr[3]);
+		__raw_writel(1 << bit, base + IC_CFG2CLR);
+		__raw_writel(1 << bit, base + IC_CFG1CLR);
+		__raw_writel(1 << bit, base + IC_CFG0CLR);
 		break;
 	default:
 		ret = -EINVAL;
 	}
 	__irq_set_chip_handler_name_locked(d->irq, chip, handler, name);
 
-	au_sync();
+	wmb();
 
 	return ret;
 }
@@ -444,21 +479,21 @@
 		off = MIPS_CPU_IRQ_BASE + 7;
 		goto handle;
 	} else if (pending & CAUSEF_IP2) {
-		s = IC0_REQ0INT;
+		s = KSEG1ADDR(AU1000_IC0_PHYS_ADDR) + IC_REQ0INT;
 		off = AU1000_INTC0_INT_BASE;
 	} else if (pending & CAUSEF_IP3) {
-		s = IC0_REQ1INT;
+		s = KSEG1ADDR(AU1000_IC0_PHYS_ADDR) + IC_REQ1INT;
 		off = AU1000_INTC0_INT_BASE;
 	} else if (pending & CAUSEF_IP4) {
-		s = IC1_REQ0INT;
+		s = KSEG1ADDR(AU1000_IC1_PHYS_ADDR) + IC_REQ0INT;
 		off = AU1000_INTC1_INT_BASE;
 	} else if (pending & CAUSEF_IP5) {
-		s = IC1_REQ1INT;
+		s = KSEG1ADDR(AU1000_IC1_PHYS_ADDR) + IC_REQ1INT;
 		off = AU1000_INTC1_INT_BASE;
 	} else
 		goto spurious;
 
-	s = au_readl(s);
+	s = __raw_readl((void __iomem *)s);
 	if (unlikely(!s)) {
 spurious:
 		spurious_interrupt();
@@ -469,48 +504,42 @@
 	do_IRQ(off);
 }
 
+
+static inline void ic_init(void __iomem *base)
+{
+	/* initialize interrupt controller to a safe state */
+	__raw_writel(0xffffffff, base + IC_CFG0CLR);
+	__raw_writel(0xffffffff, base + IC_CFG1CLR);
+	__raw_writel(0xffffffff, base + IC_CFG2CLR);
+	__raw_writel(0xffffffff, base + IC_MASKCLR);
+	__raw_writel(0xffffffff, base + IC_ASSIGNCLR);
+	__raw_writel(0xffffffff, base + IC_WAKECLR);
+	__raw_writel(0xffffffff, base + IC_SRCSET);
+	__raw_writel(0xffffffff, base + IC_FALLINGCLR);
+	__raw_writel(0xffffffff, base + IC_RISINGCLR);
+	__raw_writel(0x00000000, base + IC_TESTBIT);
+	wmb();
+}
+
 static void __init au1000_init_irq(struct au1xxx_irqmap *map)
 {
 	unsigned int bit, irq_nr;
-	int i;
-
-	/*
-	 * Initialize interrupt controllers to a safe state.
-	 */
-	au_writel(0xffffffff, IC0_CFG0CLR);
-	au_writel(0xffffffff, IC0_CFG1CLR);
-	au_writel(0xffffffff, IC0_CFG2CLR);
-	au_writel(0xffffffff, IC0_MASKCLR);
-	au_writel(0xffffffff, IC0_ASSIGNCLR);
-	au_writel(0xffffffff, IC0_WAKECLR);
-	au_writel(0xffffffff, IC0_SRCSET);
-	au_writel(0xffffffff, IC0_FALLINGCLR);
-	au_writel(0xffffffff, IC0_RISINGCLR);
-	au_writel(0x00000000, IC0_TESTBIT);
-
-	au_writel(0xffffffff, IC1_CFG0CLR);
-	au_writel(0xffffffff, IC1_CFG1CLR);
-	au_writel(0xffffffff, IC1_CFG2CLR);
-	au_writel(0xffffffff, IC1_MASKCLR);
-	au_writel(0xffffffff, IC1_ASSIGNCLR);
-	au_writel(0xffffffff, IC1_WAKECLR);
-	au_writel(0xffffffff, IC1_SRCSET);
-	au_writel(0xffffffff, IC1_FALLINGCLR);
-	au_writel(0xffffffff, IC1_RISINGCLR);
-	au_writel(0x00000000, IC1_TESTBIT);
+	void __iomem *base;
 
+	ic_init((void __iomem *)KSEG1ADDR(AU1000_IC0_PHYS_ADDR));
+	ic_init((void __iomem *)KSEG1ADDR(AU1000_IC1_PHYS_ADDR));
 	mips_cpu_irq_init();
 
 	/* register all 64 possible IC0+IC1 irq sources as type "none".
 	 * Use set_irq_type() to set edge/level behaviour at runtime.
 	 */
-	for (i = AU1000_INTC0_INT_BASE;
-	     (i < AU1000_INTC0_INT_BASE + 32); i++)
-		au1x_ic_settype(irq_get_irq_data(i), IRQ_TYPE_NONE);
+	for (irq_nr = AU1000_INTC0_INT_BASE;
+	     (irq_nr < AU1000_INTC0_INT_BASE + 32); irq_nr++)
+		au1x_ic_settype(irq_get_irq_data(irq_nr), IRQ_TYPE_NONE);
 
-	for (i = AU1000_INTC1_INT_BASE;
-	     (i < AU1000_INTC1_INT_BASE + 32); i++)
-		au1x_ic_settype(irq_get_irq_data(i), IRQ_TYPE_NONE);
+	for (irq_nr = AU1000_INTC1_INT_BASE;
+	     (irq_nr < AU1000_INTC1_INT_BASE + 32); irq_nr++)
+		au1x_ic_settype(irq_get_irq_data(irq_nr), IRQ_TYPE_NONE);
 
 	/*
 	 * Initialize IC0, which is fixed per processor.
@@ -520,13 +549,13 @@
 
 		if (irq_nr >= AU1000_INTC1_INT_BASE) {
 			bit = irq_nr - AU1000_INTC1_INT_BASE;
-			if (map->im_request)
-				au_writel(1 << bit, IC1_ASSIGNSET);
+			base = (void __iomem *)KSEG1ADDR(AU1000_IC1_PHYS_ADDR);
 		} else {
 			bit = irq_nr - AU1000_INTC0_INT_BASE;
-			if (map->im_request)
-				au_writel(1 << bit, IC0_ASSIGNSET);
+			base = (void __iomem *)KSEG1ADDR(AU1000_IC0_PHYS_ADDR);
 		}
+		if (map->im_request)
+			__raw_writel(1 << bit, base + IC_ASSIGNSET);
 
 		au1x_ic_settype(irq_get_irq_data(irq_nr), map->im_type);
 		++map;
@@ -556,90 +585,62 @@
 	}
 }
 
-struct alchemy_ic_sysdev {
-	struct sys_device sysdev;
-	void __iomem *base;
-	unsigned long pmdata[7];
-};
 
-static int alchemy_ic_suspend(struct sys_device *dev, pm_message_t state)
-{
-	struct alchemy_ic_sysdev *icdev =
-			container_of(dev, struct alchemy_ic_sysdev, sysdev);
-
-	icdev->pmdata[0] = __raw_readl(icdev->base + IC_CFG0RD);
-	icdev->pmdata[1] = __raw_readl(icdev->base + IC_CFG1RD);
-	icdev->pmdata[2] = __raw_readl(icdev->base + IC_CFG2RD);
-	icdev->pmdata[3] = __raw_readl(icdev->base + IC_SRCRD);
-	icdev->pmdata[4] = __raw_readl(icdev->base + IC_ASSIGNRD);
-	icdev->pmdata[5] = __raw_readl(icdev->base + IC_WAKERD);
-	icdev->pmdata[6] = __raw_readl(icdev->base + IC_MASKRD);
+static unsigned long alchemy_ic_pmdata[7 * 2];
 
-	return 0;
+static inline void alchemy_ic_suspend_one(void __iomem *base, unsigned long *d)
+{
+	d[0] = __raw_readl(base + IC_CFG0RD);
+	d[1] = __raw_readl(base + IC_CFG1RD);
+	d[2] = __raw_readl(base + IC_CFG2RD);
+	d[3] = __raw_readl(base + IC_SRCRD);
+	d[4] = __raw_readl(base + IC_ASSIGNRD);
+	d[5] = __raw_readl(base + IC_WAKERD);
+	d[6] = __raw_readl(base + IC_MASKRD);
+	ic_init(base);		/* shut it up too while at it */
 }
 
-static int alchemy_ic_resume(struct sys_device *dev)
+static inline void alchemy_ic_resume_one(void __iomem *base, unsigned long *d)
 {
-	struct alchemy_ic_sysdev *icdev =
-			container_of(dev, struct alchemy_ic_sysdev, sysdev);
+	ic_init(base);
 
-	__raw_writel(0xffffffff, icdev->base + IC_MASKCLR);
-	__raw_writel(0xffffffff, icdev->base + IC_CFG0CLR);
-	__raw_writel(0xffffffff, icdev->base + IC_CFG1CLR);
-	__raw_writel(0xffffffff, icdev->base + IC_CFG2CLR);
-	__raw_writel(0xffffffff, icdev->base + IC_SRCCLR);
-	__raw_writel(0xffffffff, icdev->base + IC_ASSIGNCLR);
-	__raw_writel(0xffffffff, icdev->base + IC_WAKECLR);
-	__raw_writel(0xffffffff, icdev->base + IC_RISINGCLR);
-	__raw_writel(0xffffffff, icdev->base + IC_FALLINGCLR);
-	__raw_writel(0x00000000, icdev->base + IC_TESTBIT);
-	wmb();
-	__raw_writel(icdev->pmdata[0], icdev->base + IC_CFG0SET);
-	__raw_writel(icdev->pmdata[1], icdev->base + IC_CFG1SET);
-	__raw_writel(icdev->pmdata[2], icdev->base + IC_CFG2SET);
-	__raw_writel(icdev->pmdata[3], icdev->base + IC_SRCSET);
-	__raw_writel(icdev->pmdata[4], icdev->base + IC_ASSIGNSET);
-	__raw_writel(icdev->pmdata[5], icdev->base + IC_WAKESET);
+	__raw_writel(d[0], base + IC_CFG0SET);
+	__raw_writel(d[1], base + IC_CFG1SET);
+	__raw_writel(d[2], base + IC_CFG2SET);
+	__raw_writel(d[3], base + IC_SRCSET);
+	__raw_writel(d[4], base + IC_ASSIGNSET);
+	__raw_writel(d[5], base + IC_WAKESET);
 	wmb();
 
-	__raw_writel(icdev->pmdata[6], icdev->base + IC_MASKSET);
+	__raw_writel(d[6], base + IC_MASKSET);
 	wmb();
+}
 
+static int alchemy_ic_suspend(void)
+{
+	alchemy_ic_suspend_one((void __iomem *)KSEG1ADDR(AU1000_IC0_PHYS_ADDR),
+			       alchemy_ic_pmdata);
+	alchemy_ic_suspend_one((void __iomem *)KSEG1ADDR(AU1000_IC1_PHYS_ADDR),
+			       &alchemy_ic_pmdata[7]);
 	return 0;
 }
 
-static struct sysdev_class alchemy_ic_sysdev_class = {
-	.name		= "ic",
+static void alchemy_ic_resume(void)
+{
+	alchemy_ic_resume_one((void __iomem *)KSEG1ADDR(AU1000_IC1_PHYS_ADDR),
+			      &alchemy_ic_pmdata[7]);
+	alchemy_ic_resume_one((void __iomem *)KSEG1ADDR(AU1000_IC0_PHYS_ADDR),
+			      alchemy_ic_pmdata);
+}
+
+static struct syscore_ops alchemy_ic_syscore_ops = {
 	.suspend	= alchemy_ic_suspend,
 	.resume		= alchemy_ic_resume,
 };
 
-static int __init alchemy_ic_sysdev_init(void)
+static int __init alchemy_ic_pm_init(void)
 {
-	struct alchemy_ic_sysdev *icdev;
-	unsigned long icbase[2] = { IC0_PHYS_ADDR, IC1_PHYS_ADDR };
-	int err, i;
-
-	err = sysdev_class_register(&alchemy_ic_sysdev_class);
-	if (err)
-		return err;
-
-	for (i = 0; i < 2; i++) {
-		icdev = kzalloc(sizeof(struct alchemy_ic_sysdev), GFP_KERNEL);
-		if (!icdev)
-			return -ENOMEM;
-
-		icdev->base = ioremap(icbase[i], 0x1000);
-
-		icdev->sysdev.id = i;
-		icdev->sysdev.cls = &alchemy_ic_sysdev_class;
-		err = sysdev_register(&icdev->sysdev);
-		if (err) {
-			kfree(icdev);
-			return err;
-		}
-	}
-
+	register_syscore_ops(&alchemy_ic_syscore_ops);
 	return 0;
 }
-device_initcall(alchemy_ic_sysdev_init);
+device_initcall(alchemy_ic_pm_init);
diff -druN linux-2.6.39-libre/arch/mips/alchemy/common/platform.c linux-3.0-rc7-libre/arch/mips/alchemy/common/platform.c
--- linux-2.6.39-libre/arch/mips/alchemy/common/platform.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/mips/alchemy/common/platform.c	2011-07-11 19:51:52.000000000 -0400
@@ -13,9 +13,10 @@
 
 #include <linux/dma-mapping.h>
 #include <linux/etherdevice.h>
+#include <linux/init.h>
 #include <linux/platform_device.h>
 #include <linux/serial_8250.h>
-#include <linux/init.h>
+#include <linux/slab.h>
 
 #include <asm/mach-au1x00/au1xxx.h>
 #include <asm/mach-au1x00/au1xxx_dbdma.h>
@@ -30,21 +31,12 @@
 #ifdef CONFIG_SERIAL_8250
 	switch (state) {
 	case 0:
-		if ((__raw_readl(port->membase + UART_MOD_CNTRL) & 3) != 3) {
-			/* power-on sequence as suggested in the databooks */
-			__raw_writel(0, port->membase + UART_MOD_CNTRL);
-			wmb();
-			__raw_writel(1, port->membase + UART_MOD_CNTRL);
-			wmb();
-		}
-		__raw_writel(3, port->membase + UART_MOD_CNTRL); /* full on */
-		wmb();
+		alchemy_uart_enable(CPHYSADDR(port->membase));
 		serial8250_do_pm(port, state, old_state);
 		break;
 	case 3:		/* power off */
 		serial8250_do_pm(port, state, old_state);
-		__raw_writel(0, port->membase + UART_MOD_CNTRL);
-		wmb();
+		alchemy_uart_disable(CPHYSADDR(port->membase));
 		break;
 	default:
 		serial8250_do_pm(port, state, old_state);
@@ -65,38 +57,60 @@
 		.pm		= alchemy_8250_pm,		\
 	}
 
-static struct plat_serial8250_port au1x00_uart_data[] = {
-#if defined(CONFIG_SOC_AU1000)
-	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_PHYS_ADDR, AU1500_UART0_INT),
-	PORT(UART3_PHYS_ADDR, AU1500_UART3_INT),
-#elif defined(CONFIG_SOC_AU1100)
-	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_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_PHYS_ADDR, AU1200_UART0_INT),
-	PORT(UART1_PHYS_ADDR, AU1200_UART1_INT),
-#endif
-	{ },
+static struct plat_serial8250_port au1x00_uart_data[][4] __initdata = {
+	[ALCHEMY_CPU_AU1000] = {
+		PORT(AU1000_UART0_PHYS_ADDR, AU1000_UART0_INT),
+		PORT(AU1000_UART1_PHYS_ADDR, AU1000_UART1_INT),
+		PORT(AU1000_UART2_PHYS_ADDR, AU1000_UART2_INT),
+		PORT(AU1000_UART3_PHYS_ADDR, AU1000_UART3_INT),
+	},
+	[ALCHEMY_CPU_AU1500] = {
+		PORT(AU1000_UART0_PHYS_ADDR, AU1500_UART0_INT),
+		PORT(AU1000_UART3_PHYS_ADDR, AU1500_UART3_INT),
+	},
+	[ALCHEMY_CPU_AU1100] = {
+		PORT(AU1000_UART0_PHYS_ADDR, AU1100_UART0_INT),
+		PORT(AU1000_UART1_PHYS_ADDR, AU1100_UART1_INT),
+		PORT(AU1000_UART3_PHYS_ADDR, AU1100_UART3_INT),
+	},
+	[ALCHEMY_CPU_AU1550] = {
+		PORT(AU1000_UART0_PHYS_ADDR, AU1550_UART0_INT),
+		PORT(AU1000_UART1_PHYS_ADDR, AU1550_UART1_INT),
+		PORT(AU1000_UART3_PHYS_ADDR, AU1550_UART3_INT),
+	},
+	[ALCHEMY_CPU_AU1200] = {
+		PORT(AU1000_UART0_PHYS_ADDR, AU1200_UART0_INT),
+		PORT(AU1000_UART1_PHYS_ADDR, AU1200_UART1_INT),
+	},
 };
 
 static struct platform_device au1xx0_uart_device = {
 	.name			= "serial8250",
 	.id			= PLAT8250_DEV_AU1X00,
-	.dev			= {
-		.platform_data	= au1x00_uart_data,
-	},
 };
 
+static void __init alchemy_setup_uarts(int ctype)
+{
+	unsigned int uartclk = get_au1x00_uart_baud_base() * 16;
+	int s = sizeof(struct plat_serial8250_port);
+	int c = alchemy_get_uarts(ctype);
+	struct plat_serial8250_port *ports;
+
+	ports = kzalloc(s * (c + 1), GFP_KERNEL);
+	if (!ports) {
+		printk(KERN_INFO "Alchemy: no memory for UART data\n");
+		return;
+	}
+	memcpy(ports, au1x00_uart_data[ctype], s * c);
+	au1xx0_uart_device.dev.platform_data = ports;
+
+	/* Fill up uartclk. */
+	for (s = 0; s < c; s++)
+		ports[s].uartclk = uartclk;
+	if (platform_device_register(&au1xx0_uart_device))
+		printk(KERN_INFO "Alchemy: failed to register UARTs\n");
+}
+
 /* OHCI (USB full speed host controller) */
 static struct resource au1xxx_usb_ohci_resources[] = {
 	[0] = {
@@ -269,8 +283,8 @@
 
 static struct resource au1200_mmc0_resources[] = {
 	[0] = {
-		.start          = SD0_PHYS_ADDR,
-		.end            = SD0_PHYS_ADDR + 0x7ffff,
+		.start          = AU1100_SD0_PHYS_ADDR,
+		.end            = AU1100_SD0_PHYS_ADDR + 0xfff,
 		.flags          = IORESOURCE_MEM,
 	},
 	[1] = {
@@ -305,8 +319,8 @@
 #ifndef CONFIG_MIPS_DB1200
 static struct resource au1200_mmc1_resources[] = {
 	[0] = {
-		.start          = SD1_PHYS_ADDR,
-		.end            = SD1_PHYS_ADDR + 0x7ffff,
+		.start          = AU1100_SD1_PHYS_ADDR,
+		.end            = AU1100_SD1_PHYS_ADDR + 0xfff,
 		.flags          = IORESOURCE_MEM,
 	},
 	[1] = {
@@ -359,15 +373,16 @@
 #endif
 
 /* Macro to help defining the Ethernet MAC resources */
+#define MAC_RES_COUNT	3	/* MAC regs base, MAC enable reg, MAC INT */
 #define MAC_RES(_base, _enable, _irq)			\
 	{						\
-		.start	= CPHYSADDR(_base),		\
-		.end	= CPHYSADDR(_base + 0xffff),	\
+		.start	= _base,			\
+		.end	= _base + 0xffff,		\
 		.flags	= IORESOURCE_MEM,		\
 	},						\
 	{						\
-		.start	= CPHYSADDR(_enable),		\
-		.end	= CPHYSADDR(_enable + 0x3),	\
+		.start	= _enable,			\
+		.end	= _enable + 0x3,		\
 		.flags	= IORESOURCE_MEM,		\
 	},						\
 	{						\
@@ -376,19 +391,29 @@
 		.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 resource au1xxx_eth0_resources[][MAC_RES_COUNT] __initdata = {
+	[ALCHEMY_CPU_AU1000] = {
+		MAC_RES(AU1000_MAC0_PHYS_ADDR,
+			AU1000_MACEN_PHYS_ADDR,
+			AU1000_MAC0_DMA_INT)
+	},
+	[ALCHEMY_CPU_AU1500] = {
+		MAC_RES(AU1500_MAC0_PHYS_ADDR,
+			AU1500_MACEN_PHYS_ADDR,
+			AU1500_MAC0_DMA_INT)
+	},
+	[ALCHEMY_CPU_AU1100] = {
+		MAC_RES(AU1000_MAC0_PHYS_ADDR,
+			AU1000_MACEN_PHYS_ADDR,
+			AU1100_MAC0_DMA_INT)
+	},
+	[ALCHEMY_CPU_AU1550] = {
+		MAC_RES(AU1000_MAC0_PHYS_ADDR,
+			AU1000_MACEN_PHYS_ADDR,
+			AU1550_MAC0_DMA_INT)
+	},
 };
 
-
 static struct au1000_eth_platform_data au1xxx_eth0_platform_data = {
 	.phy1_search_mac0 = 1,
 };
@@ -396,20 +421,26 @@
 static struct platform_device au1xxx_eth0_device = {
 	.name		= "au1000-eth",
 	.id		= 0,
-	.num_resources	= ARRAY_SIZE(au1xxx_eth0_resources),
-	.resource	= au1xxx_eth0_resources,
+	.num_resources	= MAC_RES_COUNT,
 	.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 resource au1xxx_eth1_resources[][MAC_RES_COUNT] __initdata = {
+	[ALCHEMY_CPU_AU1000] = {
+		MAC_RES(AU1000_MAC1_PHYS_ADDR,
+			AU1000_MACEN_PHYS_ADDR + 4,
+			AU1000_MAC1_DMA_INT)
+	},
+	[ALCHEMY_CPU_AU1500] = {
+		MAC_RES(AU1500_MAC1_PHYS_ADDR,
+			AU1500_MACEN_PHYS_ADDR + 4,
+			AU1500_MAC1_DMA_INT)
+	},
+	[ALCHEMY_CPU_AU1550] = {
+		MAC_RES(AU1000_MAC1_PHYS_ADDR,
+			AU1000_MACEN_PHYS_ADDR + 4,
+			AU1550_MAC1_DMA_INT)
+	},
 };
 
 static struct au1000_eth_platform_data au1xxx_eth1_platform_data = {
@@ -419,11 +450,9 @@
 static struct platform_device au1xxx_eth1_device = {
 	.name		= "au1000-eth",
 	.id		= 1,
-	.num_resources	= ARRAY_SIZE(au1xxx_eth1_resources),
-	.resource	= au1xxx_eth1_resources,
+	.num_resources	= MAC_RES_COUNT,
 	.dev.platform_data = &au1xxx_eth1_platform_data,
 };
-#endif
 
 void __init au1xxx_override_eth_cfg(unsigned int port,
 			struct au1000_eth_platform_data *eth_data)
@@ -434,15 +463,65 @@
 	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 void __init alchemy_setup_macs(int ctype)
+{
+	int ret, i;
+	unsigned char ethaddr[6];
+	struct resource *macres;
+
+	/* Handle 1st MAC */
+	if (alchemy_get_macs(ctype) < 1)
+		return;
+
+	macres = kmalloc(sizeof(struct resource) * MAC_RES_COUNT, GFP_KERNEL);
+	if (!macres) {
+		printk(KERN_INFO "Alchemy: no memory for MAC0 resources\n");
+		return;
+	}
+	memcpy(macres, au1xxx_eth0_resources[ctype],
+	       sizeof(struct resource) * MAC_RES_COUNT);
+	au1xxx_eth0_device.resource = macres;
+
+	i = prom_get_ethernet_addr(ethaddr);
+	if (!i && !is_valid_ether_addr(au1xxx_eth0_platform_data.mac))
+		memcpy(au1xxx_eth0_platform_data.mac, ethaddr, 6);
+
+	ret = platform_device_register(&au1xxx_eth0_device);
+	if (!ret)
+		printk(KERN_INFO "Alchemy: failed to register MAC0\n");
+
+
+	/* Handle 2nd MAC */
+	if (alchemy_get_macs(ctype) < 2)
+		return;
+
+	macres = kmalloc(sizeof(struct resource) * MAC_RES_COUNT, GFP_KERNEL);
+	if (!macres) {
+		printk(KERN_INFO "Alchemy: no memory for MAC1 resources\n");
+		return;
+	}
+	memcpy(macres, au1xxx_eth1_resources[ctype],
+	       sizeof(struct resource) * MAC_RES_COUNT);
+	au1xxx_eth1_device.resource = macres;
+
+	ethaddr[5] += 1;	/* next addr for 2nd MAC */
+	if (!i && !is_valid_ether_addr(au1xxx_eth1_platform_data.mac))
+		memcpy(au1xxx_eth1_platform_data.mac, ethaddr, 6);
+
+	/* Register second MAC if enabled in pinfunc */
+	if (!(au_readl(SYS_PINFUNC) & (u32)SYS_PF_NI2)) {
+		ret = platform_device_register(&au1xxx_eth1_device);
+		if (ret)
+			printk(KERN_INFO "Alchemy: failed to register MAC1\n");
+	}
 }
 
 static struct platform_device *au1xxx_platform_devices[] __initdata = {
-	&au1xx0_uart_device,
 	&au1xxx_usb_ohci_device,
 #ifdef CONFIG_FB_AU1100
 	&au1100_lcd_device,
@@ -460,36 +539,17 @@
 #ifdef SMBUS_PSC_BASE
 	&pbdb_smbus_device,
 #endif
-	&au1xxx_eth0_device,
 };
 
 static int __init au1xxx_platform_init(void)
 {
-	unsigned int uartclk = get_au1x00_uart_baud_base() * 16;
-	int err, i;
-	unsigned char ethaddr[6];
-
-	/* Fill up uartclk. */
-	for (i = 0; au1x00_uart_data[i].flags; i++)
-		au1x00_uart_data[i].uartclk = uartclk;
+	int err, ctype = alchemy_get_cputype();
 
-	/* use firmware-provided mac addr if available and necessary */
-	i = prom_get_ethernet_addr(ethaddr);
-	if (!i && !is_valid_ether_addr(au1xxx_eth0_platform_data.mac))
-		memcpy(au1xxx_eth0_platform_data.mac, ethaddr, 6);
+	alchemy_setup_uarts(ctype);
+	alchemy_setup_macs(ctype);
 
 	err = platform_add_devices(au1xxx_platform_devices,
 				   ARRAY_SIZE(au1xxx_platform_devices));
-#ifndef CONFIG_SOC_AU1100
-	ethaddr[5] += 1;	/* next addr for 2nd MAC */
-	if (!i && !is_valid_ether_addr(au1xxx_eth1_platform_data.mac))
-		memcpy(au1xxx_eth1_platform_data.mac, ethaddr, 6);
-
-	/* Register second MAC if enabled in pinfunc */
-	if (!err && !(au_readl(SYS_PINFUNC) & (u32)SYS_PF_NI2))
-		err = platform_device_register(&au1xxx_eth1_device);
-#endif
-
 	return err;
 }
 
diff -druN linux-2.6.39-libre/arch/mips/alchemy/common/setup.c linux-3.0-rc7-libre/arch/mips/alchemy/common/setup.c
--- linux-2.6.39-libre/arch/mips/alchemy/common/setup.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/mips/alchemy/common/setup.c	2011-07-11 19:51:52.000000000 -0400
@@ -52,8 +52,6 @@
 	/* this is faster than wasting cycles trying to approximate it */
 	preset_lpj = (est_freq >> 1) / HZ;
 
-	board_setup();  /* board specific setup */
-
 	if (au1xxx_cpu_needs_config_od())
 		/* Various early Au1xx0 errata corrected by this */
 		set_c0_config(1 << 19); /* Set Config[OD] */
@@ -61,6 +59,8 @@
 		/* Clear to obtain best system bus performance */
 		clear_c0_config(1 << 19); /* Clear Config[OD] */
 
+	board_setup();  /* board specific setup */
+
 	/* IO/MEM resources. */
 	set_io_port_base(0);
 	ioport_resource.start = IOPORT_RESOURCE_START;
diff -druN linux-2.6.39-libre/arch/mips/alchemy/common/time.c linux-3.0-rc7-libre/arch/mips/alchemy/common/time.c
--- linux-2.6.39-libre/arch/mips/alchemy/common/time.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/mips/alchemy/common/time.c	2011-07-11 19:51:52.000000000 -0400
@@ -141,8 +141,7 @@
 		goto cntr_err;
 
 	/* register counter1 clocksource and event device */
-	clocksource_set_clock(&au1x_counter1_clocksource, 32768);
-	clocksource_register(&au1x_counter1_clocksource);
+	clocksource_register_hz(&au1x_counter1_clocksource, 32768);
 
 	cd->shift = 32;
 	cd->mult = div_sc(32768, NSEC_PER_SEC, cd->shift);
diff -druN linux-2.6.39-libre/arch/mips/alchemy/devboards/db1200/setup.c linux-3.0-rc7-libre/arch/mips/alchemy/devboards/db1200/setup.c
--- linux-2.6.39-libre/arch/mips/alchemy/devboards/db1200/setup.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/mips/alchemy/devboards/db1200/setup.c	2011-07-11 19:51:52.000000000 -0400
@@ -23,6 +23,13 @@
 	unsigned long freq0, clksrc, div, pfc;
 	unsigned short whoami;
 
+	/* Set Config[OD] (disable overlapping bus transaction):
+	 * This gets rid of a _lot_ of spurious interrupts (especially
+	 * wrt. IDE); but incurs ~10% performance hit in some
+	 * cpu-bound applications.
+	 */
+	set_c0_config(1 << 19);
+
 	bcsr_init(DB1200_BCSR_PHYS_ADDR,
 		  DB1200_BCSR_PHYS_ADDR + DB1200_BCSR_HEXLED_OFS);
 
diff -druN linux-2.6.39-libre/arch/mips/alchemy/devboards/pb1000/board_setup.c linux-3.0-rc7-libre/arch/mips/alchemy/devboards/pb1000/board_setup.c
--- linux-2.6.39-libre/arch/mips/alchemy/devboards/pb1000/board_setup.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/mips/alchemy/devboards/pb1000/board_setup.c	2011-07-11 19:51:52.000000000 -0400
@@ -65,7 +65,7 @@
 
 	/* Set AUX clock to 12 MHz * 8 = 96 MHz */
 	au_writel(8, SYS_AUXPLL);
-	au_writel(0, SYS_PINSTATERD);
+	alchemy_gpio1_input_enable();
 	udelay(100);
 
 #if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
diff -druN linux-2.6.39-libre/arch/mips/alchemy/devboards/pb1500/board_setup.c linux-3.0-rc7-libre/arch/mips/alchemy/devboards/pb1500/board_setup.c
--- linux-2.6.39-libre/arch/mips/alchemy/devboards/pb1500/board_setup.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/mips/alchemy/devboards/pb1500/board_setup.c	2011-07-11 19:51:52.000000000 -0400
@@ -56,7 +56,7 @@
 	sys_clksrc = sys_freqctrl = pin_func = 0;
 	/* Set AUX clock to 12 MHz * 8 = 96 MHz */
 	au_writel(8, SYS_AUXPLL);
-	au_writel(0, SYS_PINSTATERD);
+	alchemy_gpio1_input_enable();
 	udelay(100);
 
 	/* GPIO201 is input for PCMCIA card detect */
diff -druN linux-2.6.39-libre/arch/mips/alchemy/devboards/prom.c linux-3.0-rc7-libre/arch/mips/alchemy/devboards/prom.c
--- linux-2.6.39-libre/arch/mips/alchemy/devboards/prom.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/mips/alchemy/devboards/prom.c	2011-07-11 19:51:52.000000000 -0400
@@ -62,5 +62,5 @@
 
 void prom_putchar(unsigned char c)
 {
-    alchemy_uart_putchar(UART0_PHYS_ADDR, c);
+	alchemy_uart_putchar(AU1000_UART0_PHYS_ADDR, c);
 }
diff -druN linux-2.6.39-libre/arch/mips/alchemy/gpr/board_setup.c linux-3.0-rc7-libre/arch/mips/alchemy/gpr/board_setup.c
--- linux-2.6.39-libre/arch/mips/alchemy/gpr/board_setup.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/mips/alchemy/gpr/board_setup.c	2011-07-11 19:51:52.000000000 -0400
@@ -36,9 +36,6 @@
 
 #include <prom.h>
 
-#define UART1_ADDR	KSEG1ADDR(UART1_PHYS_ADDR)
-#define UART3_ADDR	KSEG1ADDR(UART3_PHYS_ADDR)
-
 char irq_tab_alchemy[][5] __initdata = {
 	[0] = { -1, AU1500_PCI_INTA, AU1500_PCI_INTB, 0xff, 0xff },
 };
@@ -67,18 +64,15 @@
 
 void __init board_setup(void)
 {
-	printk(KERN_INFO "Tarpeze ITS GPR board\n");
+	printk(KERN_INFO "Trapeze ITS GPR board\n");
 
 	pm_power_off = gpr_power_off;
 	_machine_halt = gpr_power_off;
 	_machine_restart = gpr_reset;
 
-	/* Enable UART3 */
-	au_writel(0x1, UART3_ADDR + UART_MOD_CNTRL);/* clock enable (CE) */
-	au_writel(0x3, UART3_ADDR + UART_MOD_CNTRL); /* CE and "enable" */
-	/* Enable UART1 */
-	au_writel(0x1, UART1_ADDR + UART_MOD_CNTRL); /* clock enable (CE) */
-	au_writel(0x3, UART1_ADDR + UART_MOD_CNTRL); /* CE and "enable" */
+	/* Enable UART1/3 */
+	alchemy_uart_enable(AU1000_UART3_PHYS_ADDR);
+	alchemy_uart_enable(AU1000_UART1_PHYS_ADDR);
 
 	/* Take away Reset of UMTS-card */
 	alchemy_gpio_direction_output(215, 1);
diff -druN linux-2.6.39-libre/arch/mips/alchemy/gpr/init.c linux-3.0-rc7-libre/arch/mips/alchemy/gpr/init.c
--- linux-2.6.39-libre/arch/mips/alchemy/gpr/init.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/mips/alchemy/gpr/init.c	2011-07-11 19:51:52.000000000 -0400
@@ -59,5 +59,5 @@
 
 void prom_putchar(unsigned char c)
 {
-	alchemy_uart_putchar(UART0_PHYS_ADDR, c);
+	alchemy_uart_putchar(AU1000_UART0_PHYS_ADDR, c);
 }
diff -druN linux-2.6.39-libre/arch/mips/alchemy/mtx-1/board_setup.c linux-3.0-rc7-libre/arch/mips/alchemy/mtx-1/board_setup.c
--- linux-2.6.39-libre/arch/mips/alchemy/mtx-1/board_setup.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/mips/alchemy/mtx-1/board_setup.c	2011-07-11 19:51:52.000000000 -0400
@@ -87,7 +87,7 @@
 	au_writel(SYS_PF_NI2, SYS_PINFUNC);
 
 	/* Initialize GPIO */
-	au_writel(0xFFFFFFFF, SYS_TRIOUTCLR);
+	au_writel(~0, KSEG1ADDR(AU1000_SYS_PHYS_ADDR) + SYS_TRIOUTCLR);
 	alchemy_gpio_direction_output(0, 0);	/* Disable M66EN (PCI 66MHz) */
 	alchemy_gpio_direction_output(3, 1);	/* Disable PCI CLKRUN# */
 	alchemy_gpio_direction_output(1, 1);	/* Enable EXT_IO3 */
diff -druN linux-2.6.39-libre/arch/mips/alchemy/mtx-1/init.c linux-3.0-rc7-libre/arch/mips/alchemy/mtx-1/init.c
--- linux-2.6.39-libre/arch/mips/alchemy/mtx-1/init.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/mips/alchemy/mtx-1/init.c	2011-07-11 19:51:52.000000000 -0400
@@ -62,5 +62,5 @@
 
 void prom_putchar(unsigned char c)
 {
-	alchemy_uart_putchar(UART0_PHYS_ADDR, c);
+	alchemy_uart_putchar(AU1000_UART0_PHYS_ADDR, c);
 }
diff -druN linux-2.6.39-libre/arch/mips/alchemy/mtx-1/platform.c linux-3.0-rc7-libre/arch/mips/alchemy/mtx-1/platform.c
--- linux-2.6.39-libre/arch/mips/alchemy/mtx-1/platform.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/mips/alchemy/mtx-1/platform.c	2011-07-11 19:51:52.000000000 -0400
@@ -53,8 +53,8 @@
 
 static struct resource mtx1_wdt_res[] = {
 	[0] = {
-		.start	= 15,
-		.end	= 15,
+		.start	= 215,
+		.end	= 215,
 		.name	= "mtx1-wdt-gpio",
 		.flags	= IORESOURCE_IRQ,
 	}
diff -druN linux-2.6.39-libre/arch/mips/alchemy/xxs1500/board_setup.c linux-3.0-rc7-libre/arch/mips/alchemy/xxs1500/board_setup.c
--- linux-2.6.39-libre/arch/mips/alchemy/xxs1500/board_setup.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/mips/alchemy/xxs1500/board_setup.c	2011-07-11 19:51:52.000000000 -0400
@@ -66,13 +66,10 @@
 	au_writel(pin_func, SYS_PINFUNC);
 
 	/* Enable UART */
-	au_writel(0x01, UART3_ADDR + UART_MOD_CNTRL); /* clock enable (CE) */
-	mdelay(10);
-	au_writel(0x03, UART3_ADDR + UART_MOD_CNTRL); /* CE and "enable" */
-	mdelay(10);
-
-	/* Enable DTR = USB power up */
-	au_writel(0x01, UART3_ADDR + UART_MCR); /* UART_MCR_DTR is 0x01??? */
+	alchemy_uart_enable(AU1000_UART3_PHYS_ADDR);
+	/* Enable DTR (MCR bit 0) = USB power up */
+	__raw_writel(1, (void __iomem *)KSEG1ADDR(AU1000_UART3_PHYS_ADDR + 0x18));
+	wmb();
 
 #ifdef CONFIG_PCI
 #if defined(__MIPSEB__)
diff -druN linux-2.6.39-libre/arch/mips/alchemy/xxs1500/init.c linux-3.0-rc7-libre/arch/mips/alchemy/xxs1500/init.c
--- linux-2.6.39-libre/arch/mips/alchemy/xxs1500/init.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/mips/alchemy/xxs1500/init.c	2011-07-11 19:51:52.000000000 -0400
@@ -59,5 +59,5 @@
 
 void prom_putchar(unsigned char c)
 {
-	alchemy_uart_putchar(UART0_PHYS_ADDR, c);
+	alchemy_uart_putchar(AU1000_UART0_PHYS_ADDR, c);
 }
diff -druN linux-2.6.39-libre/arch/mips/ath79/Kconfig linux-3.0-rc7-libre/arch/mips/ath79/Kconfig
--- linux-2.6.39-libre/arch/mips/ath79/Kconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/mips/ath79/Kconfig	2011-07-11 19:51:52.000000000 -0400
@@ -26,12 +26,17 @@
 endmenu
 
 config SOC_AR71XX
+	select USB_ARCH_HAS_EHCI
+	select USB_ARCH_HAS_OHCI
 	def_bool n
 
 config SOC_AR724X
+	select USB_ARCH_HAS_EHCI
+	select USB_ARCH_HAS_OHCI
 	def_bool n
 
 config SOC_AR913X
+	select USB_ARCH_HAS_EHCI
 	def_bool n
 
 config ATH79_DEV_AR913X_WMAC
diff -druN linux-2.6.39-libre/arch/mips/bcm47xx/nvram.c linux-3.0-rc7-libre/arch/mips/bcm47xx/nvram.c
--- linux-2.6.39-libre/arch/mips/bcm47xx/nvram.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/mips/bcm47xx/nvram.c	2011-07-11 19:51:52.000000000 -0400
@@ -3,6 +3,7 @@
  *
  * Copyright (C) 2005 Broadcom Corporation
  * Copyright (C) 2006 Felix Fietkau <nbd@openwrt.org>
+ * Copyright (C) 2010-2011 Hauke Mehrtens <hauke@hauke-m.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
@@ -23,7 +24,7 @@
 static char nvram_buf[NVRAM_SPACE];
 
 /* Probe for NVRAM header */
-static void __init early_nvram_init(void)
+static void early_nvram_init(void)
 {
 	struct ssb_mipscore *mcore = &ssb_bcm47xx.mipscore;
 	struct nvram_header *header;
diff -druN linux-2.6.39-libre/arch/mips/bcm47xx/setup.c linux-3.0-rc7-libre/arch/mips/bcm47xx/setup.c
--- linux-2.6.39-libre/arch/mips/bcm47xx/setup.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/mips/bcm47xx/setup.c	2011-07-11 19:51:52.000000000 -0400
@@ -3,6 +3,7 @@
  *  Copyright (C) 2006 Felix Fietkau <nbd@openwrt.org>
  *  Copyright (C) 2006 Michael Buesch <mb@bu3sch.de>
  *  Copyright (C) 2010 Waldemar Brodkorb <wbx@openadk.org>
+ *  Copyright (C) 2010-2011 Hauke Mehrtens <hauke@hauke-m.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
@@ -57,10 +58,49 @@
 }
 
 #define READ_FROM_NVRAM(_outvar, name, buf) \
-	if (nvram_getenv(name, buf, sizeof(buf)) >= 0)\
+	if (nvram_getprefix(prefix, name, buf, sizeof(buf)) >= 0)\
 		sprom->_outvar = simple_strtoul(buf, NULL, 0);
 
-static void bcm47xx_fill_sprom(struct ssb_sprom *sprom)
+#define READ_FROM_NVRAM2(_outvar, name1, name2, buf) \
+	if (nvram_getprefix(prefix, name1, buf, sizeof(buf)) >= 0 || \
+	    nvram_getprefix(prefix, name2, buf, sizeof(buf)) >= 0)\
+		sprom->_outvar = simple_strtoul(buf, NULL, 0);
+
+static inline int nvram_getprefix(const char *prefix, char *name,
+				  char *buf, int len)
+{
+	if (prefix) {
+		char key[100];
+
+		snprintf(key, sizeof(key), "%s%s", prefix, name);
+		return nvram_getenv(key, buf, len);
+	}
+
+	return nvram_getenv(name, buf, len);
+}
+
+static u32 nvram_getu32(const char *name, char *buf, int len)
+{
+	int rv;
+	char key[100];
+	u16 var0, var1;
+
+	snprintf(key, sizeof(key), "%s0", name);
+	rv = nvram_getenv(key, buf, len);
+	/* return 0 here so this looks like unset */
+	if (rv < 0)
+		return 0;
+	var0 = simple_strtoul(buf, NULL, 0);
+
+	snprintf(key, sizeof(key), "%s1", name);
+	rv = nvram_getenv(key, buf, len);
+	if (rv < 0)
+		return 0;
+	var1 = simple_strtoul(buf, NULL, 0);
+	return var1 << 16 | var0;
+}
+
+static void bcm47xx_fill_sprom(struct ssb_sprom *sprom, const char *prefix)
 {
 	char buf[100];
 	u32 boardflags;
@@ -69,11 +109,12 @@
 
 	sprom->revision = 1; /* Fallback: Old hardware does not define this. */
 	READ_FROM_NVRAM(revision, "sromrev", buf);
-	if (nvram_getenv("il0macaddr", buf, sizeof(buf)) >= 0)
+	if (nvram_getprefix(prefix, "il0macaddr", buf, sizeof(buf)) >= 0 ||
+	    nvram_getprefix(prefix, "macaddr", buf, sizeof(buf)) >= 0)
 		nvram_parse_macaddr(buf, sprom->il0mac);
-	if (nvram_getenv("et0macaddr", buf, sizeof(buf)) >= 0)
+	if (nvram_getprefix(prefix, "et0macaddr", buf, sizeof(buf)) >= 0)
 		nvram_parse_macaddr(buf, sprom->et0mac);
-	if (nvram_getenv("et1macaddr", buf, sizeof(buf)) >= 0)
+	if (nvram_getprefix(prefix, "et1macaddr", buf, sizeof(buf)) >= 0)
 		nvram_parse_macaddr(buf, sprom->et1mac);
 	READ_FROM_NVRAM(et0phyaddr, "et0phyaddr", buf);
 	READ_FROM_NVRAM(et1phyaddr, "et1phyaddr", buf);
@@ -95,20 +136,36 @@
 	READ_FROM_NVRAM(pa1hib0, "pa1hib0", buf);
 	READ_FROM_NVRAM(pa1hib2, "pa1hib1", buf);
 	READ_FROM_NVRAM(pa1hib1, "pa1hib2", buf);
-	READ_FROM_NVRAM(gpio0, "wl0gpio0", buf);
-	READ_FROM_NVRAM(gpio1, "wl0gpio1", buf);
-	READ_FROM_NVRAM(gpio2, "wl0gpio2", buf);
-	READ_FROM_NVRAM(gpio3, "wl0gpio3", buf);
-	READ_FROM_NVRAM(maxpwr_bg, "pa0maxpwr", buf);
-	READ_FROM_NVRAM(maxpwr_al, "pa1lomaxpwr", buf);
-	READ_FROM_NVRAM(maxpwr_a, "pa1maxpwr", buf);
-	READ_FROM_NVRAM(maxpwr_ah, "pa1himaxpwr", buf);
-	READ_FROM_NVRAM(itssi_a, "pa1itssit", buf);
-	READ_FROM_NVRAM(itssi_bg, "pa0itssit", buf);
+	READ_FROM_NVRAM2(gpio0, "ledbh0", "wl0gpio0", buf);
+	READ_FROM_NVRAM2(gpio1, "ledbh1", "wl0gpio1", buf);
+	READ_FROM_NVRAM2(gpio2, "ledbh2", "wl0gpio2", buf);
+	READ_FROM_NVRAM2(gpio3, "ledbh3", "wl0gpio3", buf);
+	READ_FROM_NVRAM2(maxpwr_bg, "maxp2ga0", "pa0maxpwr", buf);
+	READ_FROM_NVRAM2(maxpwr_al, "maxp5gla0", "pa1lomaxpwr", buf);
+	READ_FROM_NVRAM2(maxpwr_a, "maxp5ga0", "pa1maxpwr", buf);
+	READ_FROM_NVRAM2(maxpwr_ah, "maxp5gha0", "pa1himaxpwr", buf);
+	READ_FROM_NVRAM2(itssi_bg, "itt5ga0", "pa0itssit", buf);
+	READ_FROM_NVRAM2(itssi_a, "itt2ga0", "pa1itssit", buf);
 	READ_FROM_NVRAM(tri2g, "tri2g", buf);
 	READ_FROM_NVRAM(tri5gl, "tri5gl", buf);
 	READ_FROM_NVRAM(tri5g, "tri5g", buf);
 	READ_FROM_NVRAM(tri5gh, "tri5gh", buf);
+	READ_FROM_NVRAM(txpid2g[0], "txpid2ga0", buf);
+	READ_FROM_NVRAM(txpid2g[1], "txpid2ga1", buf);
+	READ_FROM_NVRAM(txpid2g[2], "txpid2ga2", buf);
+	READ_FROM_NVRAM(txpid2g[3], "txpid2ga3", buf);
+	READ_FROM_NVRAM(txpid5g[0], "txpid5ga0", buf);
+	READ_FROM_NVRAM(txpid5g[1], "txpid5ga1", buf);
+	READ_FROM_NVRAM(txpid5g[2], "txpid5ga2", buf);
+	READ_FROM_NVRAM(txpid5g[3], "txpid5ga3", buf);
+	READ_FROM_NVRAM(txpid5gl[0], "txpid5gla0", buf);
+	READ_FROM_NVRAM(txpid5gl[1], "txpid5gla1", buf);
+	READ_FROM_NVRAM(txpid5gl[2], "txpid5gla2", buf);
+	READ_FROM_NVRAM(txpid5gl[3], "txpid5gla3", buf);
+	READ_FROM_NVRAM(txpid5gh[0], "txpid5gha0", buf);
+	READ_FROM_NVRAM(txpid5gh[1], "txpid5gha1", buf);
+	READ_FROM_NVRAM(txpid5gh[2], "txpid5gha2", buf);
+	READ_FROM_NVRAM(txpid5gh[3], "txpid5gha3", buf);
 	READ_FROM_NVRAM(rxpo2g, "rxpo2g", buf);
 	READ_FROM_NVRAM(rxpo5g, "rxpo5g", buf);
 	READ_FROM_NVRAM(rssisav2g, "rssisav2g", buf);
@@ -120,19 +177,27 @@
 	READ_FROM_NVRAM(rssismf5g, "rssismf5g", buf);
 	READ_FROM_NVRAM(bxa5g, "bxa5g", buf);
 	READ_FROM_NVRAM(cck2gpo, "cck2gpo", buf);
-	READ_FROM_NVRAM(ofdm2gpo, "ofdm2gpo", buf);
-	READ_FROM_NVRAM(ofdm5glpo, "ofdm5glpo", buf);
-	READ_FROM_NVRAM(ofdm5gpo, "ofdm5gpo", buf);
-	READ_FROM_NVRAM(ofdm5ghpo, "ofdm5ghpo", buf);
 
-	if (nvram_getenv("boardflags", buf, sizeof(buf)) >= 0) {
+	sprom->ofdm2gpo = nvram_getu32("ofdm2gpo", buf, sizeof(buf));
+	sprom->ofdm5glpo = nvram_getu32("ofdm5glpo", buf, sizeof(buf));
+	sprom->ofdm5gpo = nvram_getu32("ofdm5gpo", buf, sizeof(buf));
+	sprom->ofdm5ghpo = nvram_getu32("ofdm5ghpo", buf, sizeof(buf));
+
+	READ_FROM_NVRAM(antenna_gain.ghz24.a0, "ag0", buf);
+	READ_FROM_NVRAM(antenna_gain.ghz24.a1, "ag1", buf);
+	READ_FROM_NVRAM(antenna_gain.ghz24.a2, "ag2", buf);
+	READ_FROM_NVRAM(antenna_gain.ghz24.a3, "ag3", buf);
+	memcpy(&sprom->antenna_gain.ghz5, &sprom->antenna_gain.ghz24,
+	       sizeof(sprom->antenna_gain.ghz5));
+
+	if (nvram_getprefix(prefix, "boardflags", buf, sizeof(buf)) >= 0) {
 		boardflags = simple_strtoul(buf, NULL, 0);
 		if (boardflags) {
 			sprom->boardflags_lo = (boardflags & 0x0000FFFFU);
 			sprom->boardflags_hi = (boardflags & 0xFFFF0000U) >> 16;
 		}
 	}
-	if (nvram_getenv("boardflags2", buf, sizeof(buf)) >= 0) {
+	if (nvram_getprefix(prefix, "boardflags2", buf, sizeof(buf)) >= 0) {
 		boardflags = simple_strtoul(buf, NULL, 0);
 		if (boardflags) {
 			sprom->boardflags2_lo = (boardflags & 0x0000FFFFU);
@@ -141,6 +206,22 @@
 	}
 }
 
+int bcm47xx_get_sprom(struct ssb_bus *bus, struct ssb_sprom *out)
+{
+	char prefix[10];
+
+	if (bus->bustype == SSB_BUSTYPE_PCI) {
+		snprintf(prefix, sizeof(prefix), "pci/%u/%u/",
+			 bus->host_pci->bus->number + 1,
+			 PCI_SLOT(bus->host_pci->devfn));
+		bcm47xx_fill_sprom(out, prefix);
+		return 0;
+	} else {
+		printk(KERN_WARNING "bcm47xx: unable to fill SPROM for given bustype.\n");
+		return -EINVAL;
+	}
+}
+
 static int bcm47xx_get_invariants(struct ssb_bus *bus,
 				   struct ssb_init_invariants *iv)
 {
@@ -158,7 +239,7 @@
 	if (nvram_getenv("boardrev", buf, sizeof(buf)) >= 0)
 		iv->boardinfo.rev = (u16)simple_strtoul(buf, NULL, 0);
 
-	bcm47xx_fill_sprom(&iv->sprom);
+	bcm47xx_fill_sprom(&iv->sprom, NULL);
 
 	if (nvram_getenv("cardbus", buf, sizeof(buf)) >= 0)
 		iv->has_cardbus_slot = !!simple_strtoul(buf, NULL, 10);
@@ -172,6 +253,11 @@
 	char buf[100];
 	struct ssb_mipscore *mcore;
 
+	err = ssb_arch_register_fallback_sprom(&bcm47xx_get_sprom);
+	if (err)
+		printk(KERN_WARNING "bcm47xx: someone else already registered"
+			" a ssb SPROM callback handler (err %d)\n", err);
+
 	err = ssb_bus_ssbbus_register(&ssb_bcm47xx, SSB_ENUM_BASE,
 				      bcm47xx_get_invariants);
 	if (err)
diff -druN linux-2.6.39-libre/arch/mips/bcm63xx/boards/board_bcm963xx.c linux-3.0-rc7-libre/arch/mips/bcm63xx/boards/board_bcm963xx.c
--- linux-2.6.39-libre/arch/mips/bcm63xx/boards/board_bcm963xx.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/mips/bcm63xx/boards/board_bcm963xx.c	2011-07-11 19:51:52.000000000 -0400
@@ -643,6 +643,17 @@
 	.boardflags_lo		= 0x2848,
 	.boardflags_hi		= 0x0000,
 };
+
+int bcm63xx_get_fallback_sprom(struct ssb_bus *bus, struct ssb_sprom *out)
+{
+	if (bus->bustype == SSB_BUSTYPE_PCI) {
+		memcpy(out, &bcm63xx_sprom, sizeof(struct ssb_sprom));
+		return 0;
+	} else {
+		printk(KERN_ERR PFX "unable to fill SPROM for given bustype.\n");
+		return -EINVAL;
+	}
+}
 #endif
 
 /*
@@ -793,8 +804,9 @@
 	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");
+		if (ssb_arch_register_fallback_sprom(
+				&bcm63xx_get_fallback_sprom) < 0)
+			printk(KERN_ERR PFX "failed to register fallback SPROM\n");
 	}
 #endif
 }
diff -druN linux-2.6.39-libre/arch/mips/boot/compressed/uart-alchemy.c linux-3.0-rc7-libre/arch/mips/boot/compressed/uart-alchemy.c
--- linux-2.6.39-libre/arch/mips/boot/compressed/uart-alchemy.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/mips/boot/compressed/uart-alchemy.c	2011-07-11 19:51:52.000000000 -0400
@@ -3,5 +3,5 @@
 void putc(char c)
 {
 	/* all current (Jan. 2010) in-kernel boards */
-	alchemy_uart_putchar(UART0_PHYS_ADDR, c);
+	alchemy_uart_putchar(AU1000_UART0_PHYS_ADDR, c);
 }
diff -druN linux-2.6.39-libre/arch/mips/cavium-octeon/csrc-octeon.c linux-3.0-rc7-libre/arch/mips/cavium-octeon/csrc-octeon.c
--- linux-2.6.39-libre/arch/mips/cavium-octeon/csrc-octeon.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/mips/cavium-octeon/csrc-octeon.c	2011-07-11 19:51:52.000000000 -0400
@@ -105,8 +105,7 @@
 void __init plat_time_init(void)
 {
 	clocksource_mips.rating = 300;
-	clocksource_set_clock(&clocksource_mips, octeon_get_clock_rate());
-	clocksource_register(&clocksource_mips);
+	clocksource_register_hz(&clocksource_mips, octeon_get_clock_rate());
 }
 
 static u64 octeon_udelay_factor;
diff -druN linux-2.6.39-libre/arch/mips/cavium-octeon/flash_setup.c linux-3.0-rc7-libre/arch/mips/cavium-octeon/flash_setup.c
--- linux-2.6.39-libre/arch/mips/cavium-octeon/flash_setup.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/mips/cavium-octeon/flash_setup.c	2011-07-11 19:51:52.000000000 -0400
@@ -16,7 +16,6 @@
 
 static struct map_info flash_map;
 static struct mtd_info *mymtd;
-#ifdef CONFIG_MTD_PARTITIONS
 static int nr_parts;
 static struct mtd_partition *parts;
 static const char *part_probe_types[] = {
@@ -26,7 +25,6 @@
 #endif
 	NULL
 };
-#endif
 
 /**
  * Module/ driver initialization.
@@ -63,17 +61,10 @@
 		if (mymtd) {
 			mymtd->owner = THIS_MODULE;
 
-#ifdef CONFIG_MTD_PARTITIONS
 			nr_parts = parse_mtd_partitions(mymtd,
 							part_probe_types,
 							&parts, 0);
-			if (nr_parts > 0)
-				add_mtd_partitions(mymtd, parts, nr_parts);
-			else
-				add_mtd_device(mymtd);
-#else
-			add_mtd_device(mymtd);
-#endif
+			mtd_device_register(mymtd, parts, nr_parts);
 		} else {
 			pr_err("Failed to register MTD device for flash\n");
 		}
diff -druN linux-2.6.39-libre/arch/mips/cavium-octeon/setup.c linux-3.0-rc7-libre/arch/mips/cavium-octeon/setup.c
--- linux-2.6.39-libre/arch/mips/cavium-octeon/setup.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/mips/cavium-octeon/setup.c	2011-07-11 19:51:52.000000000 -0400
@@ -288,7 +288,6 @@
 	union octeon_cvmemctl cvmmemctl;
 	union cvmx_iob_fau_timeout fau_timeout;
 	union cvmx_pow_nw_tim nm_tim;
-	uint64_t cvmctl;
 
 	/* Get the current settings for CP0_CVMMEMCTL_REG */
 	cvmmemctl.u64 = read_c0_cvmmemctl();
@@ -392,12 +391,6 @@
 			  CONFIG_CAVIUM_OCTEON_CVMSEG_SIZE,
 			  CONFIG_CAVIUM_OCTEON_CVMSEG_SIZE * 128);
 
-	/* Move the performance counter interrupts to IRQ 6 */
-	cvmctl = read_c0_cvmctl();
-	cvmctl &= ~(7 << 7);
-	cvmctl |= 6 << 7;
-	write_c0_cvmctl(cvmctl);
-
 	/* Set a default for the hardware timeouts */
 	fau_timeout.u64 = 0;
 	fau_timeout.s.tout_val = 0xfff;
diff -druN linux-2.6.39-libre/arch/mips/cavium-octeon/smp.c linux-3.0-rc7-libre/arch/mips/cavium-octeon/smp.c
--- linux-2.6.39-libre/arch/mips/cavium-octeon/smp.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/mips/cavium-octeon/smp.c	2011-07-11 19:51:52.000000000 -0400
@@ -37,13 +37,15 @@
 	uint64_t action;
 
 	/* Load the mailbox register to figure out what we're supposed to do */
-	action = cvmx_read_csr(CVMX_CIU_MBOX_CLRX(coreid));
+	action = cvmx_read_csr(CVMX_CIU_MBOX_CLRX(coreid)) & 0xffff;
 
 	/* Clear the mailbox to clear the interrupt */
 	cvmx_write_csr(CVMX_CIU_MBOX_CLRX(coreid), action);
 
 	if (action & SMP_CALL_FUNCTION)
 		smp_call_function_interrupt();
+	if (action & SMP_RESCHEDULE_YOURSELF)
+		scheduler_ipi();
 
 	/* Check if we've been told to flush the icache */
 	if (action & SMP_ICACHE_FLUSH)
@@ -200,16 +202,15 @@
 	if (labi->labi_signature != LABI_SIGNATURE)
 		panic("The bootloader version on this board is incorrect.");
 #endif
-
-	cvmx_write_csr(CVMX_CIU_MBOX_CLRX(cvmx_get_core_num()), 0xffffffff);
+	/*
+	 * Only the low order mailbox bits are used for IPIs, leave
+	 * the other bits alone.
+	 */
+	cvmx_write_csr(CVMX_CIU_MBOX_CLRX(cvmx_get_core_num()), 0xffff);
 	if (request_irq(OCTEON_IRQ_MBOX0, mailbox_interrupt, IRQF_DISABLED,
-			"mailbox0", mailbox_interrupt)) {
+			"SMP-IPI", mailbox_interrupt)) {
 		panic("Cannot request_irq(OCTEON_IRQ_MBOX0)\n");
 	}
-	if (request_irq(OCTEON_IRQ_MBOX1, mailbox_interrupt, IRQF_DISABLED,
-			"mailbox1", mailbox_interrupt)) {
-		panic("Cannot request_irq(OCTEON_IRQ_MBOX1)\n");
-	}
 }
 
 /**
diff -druN linux-2.6.39-libre/arch/mips/configs/bcm47xx_defconfig linux-3.0-rc7-libre/arch/mips/configs/bcm47xx_defconfig
--- linux-2.6.39-libre/arch/mips/configs/bcm47xx_defconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/mips/configs/bcm47xx_defconfig	2011-07-11 19:51:52.000000000 -0400
@@ -16,7 +16,6 @@
 CONFIG_AUDIT=y
 CONFIG_TINY_RCU=y
 CONFIG_CGROUPS=y
-CONFIG_CGROUP_NS=y
 CONFIG_CGROUP_CPUACCT=y
 CONFIG_RELAY=y
 CONFIG_BLK_DEV_INITRD=y
diff -druN linux-2.6.39-libre/arch/mips/configs/lemote2f_defconfig linux-3.0-rc7-libre/arch/mips/configs/lemote2f_defconfig
--- linux-2.6.39-libre/arch/mips/configs/lemote2f_defconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/mips/configs/lemote2f_defconfig	2011-07-11 19:51:52.000000000 -0400
@@ -86,8 +86,8 @@
 CONFIG_NET_EMATCH=y
 CONFIG_NET_CLS_ACT=y
 CONFIG_BT=m
-CONFIG_BT_L2CAP=m
-CONFIG_BT_SCO=m
+CONFIG_BT_L2CAP=y
+CONFIG_BT_SCO=y
 CONFIG_BT_RFCOMM=m
 CONFIG_BT_RFCOMM_TTY=y
 CONFIG_BT_BNEP=m
@@ -329,7 +329,7 @@
 CONFIG_USB_GADGET=m
 CONFIG_USB_GADGET_M66592=y
 CONFIG_MMC=m
-CONFIG_LEDS_CLASS=m
+CONFIG_LEDS_CLASS=y
 CONFIG_STAGING=y
 # CONFIG_STAGING_EXCLUDE_BUILD is not set
 CONFIG_FB_SM7XX=y
diff -druN linux-2.6.39-libre/arch/mips/configs/malta_defconfig linux-3.0-rc7-libre/arch/mips/configs/malta_defconfig
--- linux-2.6.39-libre/arch/mips/configs/malta_defconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/mips/configs/malta_defconfig	2011-07-11 19:51:52.000000000 -0400
@@ -374,7 +374,7 @@
 # CONFIG_VGA_CONSOLE is not set
 CONFIG_FRAMEBUFFER_CONSOLE=y
 CONFIG_HID=m
-CONFIG_LEDS_CLASS=m
+CONFIG_LEDS_CLASS=y
 CONFIG_LEDS_TRIGGER_TIMER=m
 CONFIG_LEDS_TRIGGER_IDE_DISK=y
 CONFIG_LEDS_TRIGGER_HEARTBEAT=m
diff -druN linux-2.6.39-libre/arch/mips/configs/mtx1_defconfig linux-3.0-rc7-libre/arch/mips/configs/mtx1_defconfig
--- linux-2.6.39-libre/arch/mips/configs/mtx1_defconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/mips/configs/mtx1_defconfig	2011-07-11 19:51:52.000000000 -0400
@@ -225,8 +225,8 @@
 CONFIG_VLSI_FIR=m
 CONFIG_MCS_FIR=m
 CONFIG_BT=m
-CONFIG_BT_L2CAP=m
-CONFIG_BT_SCO=m
+CONFIG_BT_L2CAP=y
+CONFIG_BT_SCO=y
 CONFIG_BT_RFCOMM=m
 CONFIG_BT_RFCOMM_TTY=y
 CONFIG_BT_BNEP=m
@@ -678,7 +678,7 @@
 CONFIG_LEDS_TRIGGER_TIMER=y
 CONFIG_LEDS_TRIGGER_HEARTBEAT=y
 CONFIG_LEDS_TRIGGER_DEFAULT_ON=y
-CONFIG_RTC_CLASS=m
+CONFIG_RTC_CLASS=y
 CONFIG_RTC_INTF_DEV_UIE_EMUL=y
 CONFIG_RTC_DRV_TEST=m
 CONFIG_RTC_DRV_DS1307=m
diff -druN linux-2.6.39-libre/arch/mips/configs/nlm_xlr_defconfig linux-3.0-rc7-libre/arch/mips/configs/nlm_xlr_defconfig
--- linux-2.6.39-libre/arch/mips/configs/nlm_xlr_defconfig	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/mips/configs/nlm_xlr_defconfig	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,574 @@
+CONFIG_NLM_XLR_BOARD=y
+CONFIG_HIGHMEM=y
+CONFIG_KSM=y
+CONFIG_DEFAULT_MMAP_MIN_ADDR=65536
+CONFIG_SMP=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_PREEMPT_VOLUNTARY=y
+CONFIG_KEXEC=y
+CONFIG_EXPERIMENTAL=y
+CONFIG_CROSS_COMPILE="mips64-unknown-linux-gnu-"
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_SYSVIPC=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_BSD_PROCESS_ACCT=y
+CONFIG_BSD_PROCESS_ACCT_V3=y
+CONFIG_TASKSTATS=y
+CONFIG_TASK_DELAY_ACCT=y
+CONFIG_TASK_XACCT=y
+CONFIG_TASK_IO_ACCOUNTING=y
+CONFIG_AUDIT=y
+CONFIG_NAMESPACES=y
+CONFIG_SCHED_AUTOGROUP=y
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE="usr/dev_file_list usr/rootfs"
+CONFIG_RD_BZIP2=y
+CONFIG_RD_LZMA=y
+CONFIG_INITRAMFS_COMPRESSION_GZIP=y
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_EXPERT=y
+CONFIG_KALLSYMS_ALL=y
+# CONFIG_ELF_CORE is not set
+# CONFIG_PCSPKR_PLATFORM is not set
+# CONFIG_PERF_EVENTS is not set
+# CONFIG_COMPAT_BRK is not set
+CONFIG_PROFILING=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODVERSIONS=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+CONFIG_BLK_DEV_INTEGRITY=y
+CONFIG_BINFMT_MISC=m
+CONFIG_PM_RUNTIME=y
+CONFIG_PM_DEBUG=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_XFRM_USER=m
+CONFIG_NET_KEY=m
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_ADVANCED_ROUTER=y
+CONFIG_IP_MULTIPLE_TABLES=y
+CONFIG_IP_ROUTE_MULTIPATH=y
+CONFIG_IP_ROUTE_VERBOSE=y
+CONFIG_NET_IPIP=m
+CONFIG_IP_MROUTE=y
+CONFIG_IP_PIMSM_V1=y
+CONFIG_IP_PIMSM_V2=y
+CONFIG_SYN_COOKIES=y
+CONFIG_INET_AH=m
+CONFIG_INET_ESP=m
+CONFIG_INET_IPCOMP=m
+CONFIG_INET_XFRM_MODE_TRANSPORT=m
+CONFIG_INET_XFRM_MODE_TUNNEL=m
+CONFIG_INET_XFRM_MODE_BEET=m
+CONFIG_TCP_CONG_ADVANCED=y
+CONFIG_TCP_CONG_HSTCP=m
+CONFIG_TCP_CONG_HYBLA=m
+CONFIG_TCP_CONG_SCALABLE=m
+CONFIG_TCP_CONG_LP=m
+CONFIG_TCP_CONG_VENO=m
+CONFIG_TCP_CONG_YEAH=m
+CONFIG_TCP_CONG_ILLINOIS=m
+CONFIG_TCP_MD5SIG=y
+CONFIG_IPV6=y
+CONFIG_IPV6_PRIVACY=y
+CONFIG_INET6_AH=m
+CONFIG_INET6_ESP=m
+CONFIG_INET6_IPCOMP=m
+CONFIG_INET6_XFRM_MODE_TRANSPORT=m
+CONFIG_INET6_XFRM_MODE_TUNNEL=m
+CONFIG_INET6_XFRM_MODE_BEET=m
+CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m
+CONFIG_IPV6_SIT=m
+CONFIG_IPV6_TUNNEL=m
+CONFIG_IPV6_MULTIPLE_TABLES=y
+CONFIG_NETLABEL=y
+CONFIG_NETFILTER=y
+CONFIG_NF_CONNTRACK=m
+CONFIG_NF_CONNTRACK_SECMARK=y
+CONFIG_NF_CONNTRACK_EVENTS=y
+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=m
+CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
+CONFIG_NETFILTER_XT_TARGET_CONNMARK=m
+CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=m
+CONFIG_NETFILTER_XT_TARGET_DSCP=m
+CONFIG_NETFILTER_XT_TARGET_MARK=m
+CONFIG_NETFILTER_XT_TARGET_NFLOG=m
+CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
+CONFIG_NETFILTER_XT_TARGET_NOTRACK=m
+CONFIG_NETFILTER_XT_TARGET_TPROXY=m
+CONFIG_NETFILTER_XT_TARGET_TRACE=m
+CONFIG_NETFILTER_XT_TARGET_SECMARK=m
+CONFIG_NETFILTER_XT_TARGET_TCPMSS=m
+CONFIG_NETFILTER_XT_MATCH_CLUSTER=m
+CONFIG_NETFILTER_XT_MATCH_COMMENT=m
+CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m
+CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m
+CONFIG_NETFILTER_XT_MATCH_CONNMARK=m
+CONFIG_NETFILTER_XT_MATCH_CONNTRACK=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_IPRANGE=m
+CONFIG_NETFILTER_XT_MATCH_LENGTH=m
+CONFIG_NETFILTER_XT_MATCH_LIMIT=m
+CONFIG_NETFILTER_XT_MATCH_MAC=m
+CONFIG_NETFILTER_XT_MATCH_MARK=m
+CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m
+CONFIG_NETFILTER_XT_MATCH_OSF=m
+CONFIG_NETFILTER_XT_MATCH_OWNER=m
+CONFIG_NETFILTER_XT_MATCH_POLICY=m
+CONFIG_NETFILTER_XT_MATCH_PHYSDEV=m
+CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m
+CONFIG_NETFILTER_XT_MATCH_QUOTA=m
+CONFIG_NETFILTER_XT_MATCH_RATEEST=m
+CONFIG_NETFILTER_XT_MATCH_REALM=m
+CONFIG_NETFILTER_XT_MATCH_RECENT=m
+CONFIG_NETFILTER_XT_MATCH_SOCKET=m
+CONFIG_NETFILTER_XT_MATCH_STATE=m
+CONFIG_NETFILTER_XT_MATCH_STATISTIC=m
+CONFIG_NETFILTER_XT_MATCH_STRING=m
+CONFIG_NETFILTER_XT_MATCH_TCPMSS=m
+CONFIG_NETFILTER_XT_MATCH_TIME=m
+CONFIG_NETFILTER_XT_MATCH_U32=m
+CONFIG_IP_VS=m
+CONFIG_IP_VS_IPV6=y
+CONFIG_IP_VS_PROTO_TCP=y
+CONFIG_IP_VS_PROTO_UDP=y
+CONFIG_IP_VS_PROTO_ESP=y
+CONFIG_IP_VS_PROTO_AH=y
+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
+CONFIG_IP_VS_FTP=m
+CONFIG_NF_CONNTRACK_IPV4=m
+CONFIG_IP_NF_QUEUE=m
+CONFIG_IP_NF_IPTABLES=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_IP_NF_TARGET_MASQUERADE=m
+CONFIG_IP_NF_TARGET_NETMAP=m
+CONFIG_IP_NF_TARGET_REDIRECT=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_SECURITY=m
+CONFIG_IP_NF_ARPTABLES=m
+CONFIG_IP_NF_ARPFILTER=m
+CONFIG_IP_NF_ARP_MANGLE=m
+CONFIG_NF_CONNTRACK_IPV6=m
+CONFIG_IP6_NF_QUEUE=m
+CONFIG_IP6_NF_IPTABLES=m
+CONFIG_IP6_NF_MATCH_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_IP6_NF_SECURITY=m
+CONFIG_DECNET_NF_GRABULATOR=m
+CONFIG_BRIDGE_NF_EBTABLES=m
+CONFIG_BRIDGE_EBT_BROUTE=m
+CONFIG_BRIDGE_EBT_T_FILTER=m
+CONFIG_BRIDGE_EBT_T_NAT=m
+CONFIG_BRIDGE_EBT_802_3=m
+CONFIG_BRIDGE_EBT_AMONG=m
+CONFIG_BRIDGE_EBT_ARP=m
+CONFIG_BRIDGE_EBT_IP=m
+CONFIG_BRIDGE_EBT_IP6=m
+CONFIG_BRIDGE_EBT_LIMIT=m
+CONFIG_BRIDGE_EBT_MARK=m
+CONFIG_BRIDGE_EBT_PKTTYPE=m
+CONFIG_BRIDGE_EBT_STP=m
+CONFIG_BRIDGE_EBT_VLAN=m
+CONFIG_BRIDGE_EBT_ARPREPLY=m
+CONFIG_BRIDGE_EBT_DNAT=m
+CONFIG_BRIDGE_EBT_MARK_T=m
+CONFIG_BRIDGE_EBT_REDIRECT=m
+CONFIG_BRIDGE_EBT_SNAT=m
+CONFIG_BRIDGE_EBT_LOG=m
+CONFIG_BRIDGE_EBT_ULOG=m
+CONFIG_BRIDGE_EBT_NFLOG=m
+CONFIG_IP_DCCP=m
+CONFIG_RDS=m
+CONFIG_RDS_TCP=m
+CONFIG_TIPC=m
+CONFIG_ATM=m
+CONFIG_ATM_CLIP=m
+CONFIG_ATM_LANE=m
+CONFIG_ATM_MPOA=m
+CONFIG_ATM_BR2684=m
+CONFIG_BRIDGE=m
+CONFIG_VLAN_8021Q=m
+CONFIG_VLAN_8021Q_GVRP=y
+CONFIG_DECNET=m
+CONFIG_LLC2=m
+CONFIG_IPX=m
+CONFIG_ATALK=m
+CONFIG_DEV_APPLETALK=m
+CONFIG_IPDDP=m
+CONFIG_IPDDP_ENCAP=y
+CONFIG_IPDDP_DECAP=y
+CONFIG_X25=m
+CONFIG_LAPB=m
+CONFIG_ECONET=m
+CONFIG_ECONET_AUNUDP=y
+CONFIG_ECONET_NATIVE=y
+CONFIG_WAN_ROUTER=m
+CONFIG_PHONET=m
+CONFIG_IEEE802154=m
+CONFIG_NET_SCHED=y
+CONFIG_NET_SCH_CBQ=m
+CONFIG_NET_SCH_HTB=m
+CONFIG_NET_SCH_HFSC=m
+CONFIG_NET_SCH_ATM=m
+CONFIG_NET_SCH_PRIO=m
+CONFIG_NET_SCH_MULTIQ=m
+CONFIG_NET_SCH_RED=m
+CONFIG_NET_SCH_SFQ=m
+CONFIG_NET_SCH_TEQL=m
+CONFIG_NET_SCH_TBF=m
+CONFIG_NET_SCH_GRED=m
+CONFIG_NET_SCH_DSMARK=m
+CONFIG_NET_SCH_NETEM=m
+CONFIG_NET_SCH_DRR=m
+CONFIG_NET_SCH_INGRESS=m
+CONFIG_NET_CLS_BASIC=m
+CONFIG_NET_CLS_TCINDEX=m
+CONFIG_NET_CLS_ROUTE4=m
+CONFIG_NET_CLS_FW=m
+CONFIG_NET_CLS_U32=m
+CONFIG_CLS_U32_MARK=y
+CONFIG_NET_CLS_RSVP=m
+CONFIG_NET_CLS_RSVP6=m
+CONFIG_NET_CLS_FLOW=m
+CONFIG_NET_EMATCH=y
+CONFIG_NET_EMATCH_CMP=m
+CONFIG_NET_EMATCH_NBYTE=m
+CONFIG_NET_EMATCH_U32=m
+CONFIG_NET_EMATCH_META=m
+CONFIG_NET_EMATCH_TEXT=m
+CONFIG_NET_CLS_ACT=y
+CONFIG_NET_ACT_POLICE=m
+CONFIG_NET_ACT_GACT=m
+CONFIG_GACT_PROB=y
+CONFIG_NET_ACT_MIRRED=m
+CONFIG_NET_ACT_IPT=m
+CONFIG_NET_ACT_NAT=m
+CONFIG_NET_ACT_PEDIT=m
+CONFIG_NET_ACT_SIMP=m
+CONFIG_NET_ACT_SKBEDIT=m
+CONFIG_DCB=y
+CONFIG_NET_PKTGEN=m
+# CONFIG_WIRELESS is not set
+CONFIG_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
+# CONFIG_STANDALONE is not set
+CONFIG_CONNECTOR=y
+CONFIG_MTD=m
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_CRYPTOLOOP=m
+CONFIG_BLK_DEV_NBD=m
+CONFIG_BLK_DEV_OSD=m
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=65536
+CONFIG_CDROM_PKTCDVD=y
+CONFIG_MISC_DEVICES=y
+CONFIG_RAID_ATTRS=m
+CONFIG_SCSI=y
+CONFIG_SCSI_TGT=m
+CONFIG_BLK_DEV_SD=y
+CONFIG_CHR_DEV_ST=m
+CONFIG_CHR_DEV_OSST=m
+CONFIG_BLK_DEV_SR=y
+CONFIG_CHR_DEV_SG=y
+CONFIG_CHR_DEV_SCH=m
+CONFIG_SCSI_MULTI_LUN=y
+CONFIG_SCSI_CONSTANTS=y
+CONFIG_SCSI_LOGGING=y
+CONFIG_SCSI_SCAN_ASYNC=y
+CONFIG_SCSI_SPI_ATTRS=m
+CONFIG_SCSI_FC_TGT_ATTRS=y
+CONFIG_SCSI_SAS_LIBSAS=m
+CONFIG_SCSI_SRP_ATTRS=m
+CONFIG_SCSI_SRP_TGT_ATTRS=y
+CONFIG_ISCSI_TCP=m
+CONFIG_LIBFCOE=m
+CONFIG_SCSI_DEBUG=m
+CONFIG_SCSI_DH=y
+CONFIG_SCSI_DH_RDAC=m
+CONFIG_SCSI_DH_HP_SW=m
+CONFIG_SCSI_DH_EMC=m
+CONFIG_SCSI_DH_ALUA=m
+CONFIG_SCSI_OSD_INITIATOR=m
+CONFIG_SCSI_OSD_ULD=m
+# CONFIG_INPUT_MOUSEDEV is not set
+CONFIG_INPUT_EVDEV=y
+CONFIG_INPUT_EVBUG=m
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_SERIO_I8042 is not set
+CONFIG_SERIO_SERPORT=m
+CONFIG_SERIO_LIBPS2=y
+CONFIG_SERIO_RAW=m
+CONFIG_VT_HW_CONSOLE_BINDING=y
+CONFIG_DEVPTS_MULTIPLE_INSTANCES=y
+CONFIG_LEGACY_PTY_COUNT=0
+CONFIG_SERIAL_NONSTANDARD=y
+CONFIG_N_HDLC=m
+# CONFIG_DEVKMEM is not set
+CONFIG_STALDRV=y
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_NR_UARTS=48
+CONFIG_SERIAL_8250_EXTENDED=y
+CONFIG_SERIAL_8250_MANY_PORTS=y
+CONFIG_SERIAL_8250_SHARE_IRQ=y
+CONFIG_SERIAL_8250_RSA=y
+CONFIG_HW_RANDOM=y
+CONFIG_HW_RANDOM_TIMERIOMEM=m
+CONFIG_RAW_DRIVER=m
+# CONFIG_HWMON is not set
+# CONFIG_VGA_CONSOLE is not set
+# CONFIG_HID_SUPPORT is not set
+# CONFIG_USB_SUPPORT is not set
+CONFIG_UIO=y
+CONFIG_UIO_PDRV=m
+CONFIG_UIO_PDRV_GENIRQ=m
+CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XATTR=y
+CONFIG_EXT2_FS_POSIX_ACL=y
+CONFIG_EXT2_FS_SECURITY=y
+CONFIG_EXT3_FS=y
+CONFIG_EXT3_FS_POSIX_ACL=y
+CONFIG_EXT3_FS_SECURITY=y
+CONFIG_EXT4_FS=y
+CONFIG_EXT4_FS_POSIX_ACL=y
+CONFIG_EXT4_FS_SECURITY=y
+CONFIG_GFS2_FS=m
+CONFIG_GFS2_FS_LOCKING_DLM=y
+CONFIG_OCFS2_FS=m
+CONFIG_BTRFS_FS=m
+CONFIG_BTRFS_FS_POSIX_ACL=y
+CONFIG_NILFS2_FS=m
+CONFIG_QUOTA_NETLINK_INTERFACE=y
+# CONFIG_PRINT_QUOTA_WARNING is not set
+CONFIG_QFMT_V1=m
+CONFIG_QFMT_V2=m
+CONFIG_AUTOFS4_FS=m
+CONFIG_FUSE_FS=y
+CONFIG_CUSE=m
+CONFIG_FSCACHE=m
+CONFIG_FSCACHE_STATS=y
+CONFIG_FSCACHE_HISTOGRAM=y
+CONFIG_CACHEFILES=m
+CONFIG_ISO9660_FS=m
+CONFIG_JOLIET=y
+CONFIG_ZISOFS=y
+CONFIG_UDF_FS=m
+CONFIG_MSDOS_FS=m
+CONFIG_VFAT_FS=m
+CONFIG_NTFS_FS=m
+CONFIG_PROC_KCORE=y
+CONFIG_TMPFS=y
+CONFIG_TMPFS_POSIX_ACL=y
+CONFIG_CONFIGFS_FS=y
+CONFIG_ADFS_FS=m
+CONFIG_AFFS_FS=m
+CONFIG_ECRYPT_FS=y
+CONFIG_HFS_FS=m
+CONFIG_HFSPLUS_FS=m
+CONFIG_BEFS_FS=m
+CONFIG_BFS_FS=m
+CONFIG_EFS_FS=m
+CONFIG_CRAMFS=m
+CONFIG_SQUASHFS=m
+CONFIG_VXFS_FS=m
+CONFIG_MINIX_FS=m
+CONFIG_OMFS_FS=m
+CONFIG_HPFS_FS=m
+CONFIG_QNX4FS_FS=m
+CONFIG_ROMFS_FS=m
+CONFIG_SYSV_FS=m
+CONFIG_UFS_FS=m
+CONFIG_EXOFS_FS=m
+CONFIG_NFS_FS=m
+CONFIG_NFS_V3=y
+CONFIG_NFS_V3_ACL=y
+CONFIG_NFS_V4=y
+CONFIG_NFS_FSCACHE=y
+CONFIG_NFSD=m
+CONFIG_NFSD_V3_ACL=y
+CONFIG_NFSD_V4=y
+CONFIG_CIFS=m
+CONFIG_CIFS_WEAK_PW_HASH=y
+CONFIG_CIFS_UPCALL=y
+CONFIG_CIFS_XATTR=y
+CONFIG_CIFS_POSIX=y
+CONFIG_CIFS_DFS_UPCALL=y
+CONFIG_CIFS_EXPERIMENTAL=y
+CONFIG_NCP_FS=m
+CONFIG_NCPFS_PACKET_SIGNING=y
+CONFIG_NCPFS_IOCTL_LOCKING=y
+CONFIG_NCPFS_STRONG=y
+CONFIG_NCPFS_NFS_NS=y
+CONFIG_NCPFS_OS2_NS=y
+CONFIG_NCPFS_NLS=y
+CONFIG_NCPFS_EXTRAS=y
+CONFIG_CODA_FS=m
+CONFIG_AFS_FS=m
+CONFIG_PARTITION_ADVANCED=y
+CONFIG_ACORN_PARTITION=y
+CONFIG_ACORN_PARTITION_ICS=y
+CONFIG_ACORN_PARTITION_RISCIX=y
+CONFIG_OSF_PARTITION=y
+CONFIG_AMIGA_PARTITION=y
+CONFIG_ATARI_PARTITION=y
+CONFIG_MAC_PARTITION=y
+CONFIG_BSD_DISKLABEL=y
+CONFIG_MINIX_SUBPARTITION=y
+CONFIG_SOLARIS_X86_PARTITION=y
+CONFIG_UNIXWARE_DISKLABEL=y
+CONFIG_LDM_PARTITION=y
+CONFIG_SGI_PARTITION=y
+CONFIG_ULTRIX_PARTITION=y
+CONFIG_SUN_PARTITION=y
+CONFIG_KARMA_PARTITION=y
+CONFIG_EFI_PARTITION=y
+CONFIG_SYSV68_PARTITION=y
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="cp437"
+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_PRINTK_TIME=y
+# CONFIG_ENABLE_WARN_DEPRECATED is not set
+# CONFIG_ENABLE_MUST_CHECK is not set
+CONFIG_UNUSED_SYMBOLS=y
+CONFIG_DEBUG_KERNEL=y
+CONFIG_DETECT_HUNG_TASK=y
+CONFIG_SCHEDSTATS=y
+CONFIG_TIMER_STATS=y
+CONFIG_DEBUG_INFO=y
+CONFIG_DEBUG_MEMORY_INIT=y
+CONFIG_SYSCTL_SYSCALL_CHECK=y
+CONFIG_SCHED_TRACER=y
+CONFIG_BLK_DEV_IO_TRACE=y
+CONFIG_KGDB=y
+CONFIG_SECURITY=y
+CONFIG_SECURITY_NETWORK=y
+CONFIG_LSM_MMAP_MIN_ADDR=0
+CONFIG_SECURITY_SELINUX=y
+CONFIG_SECURITY_SELINUX_BOOTPARAM=y
+CONFIG_SECURITY_SELINUX_BOOTPARAM_VALUE=0
+CONFIG_SECURITY_SELINUX_DISABLE=y
+CONFIG_SECURITY_SMACK=y
+CONFIG_SECURITY_TOMOYO=y
+CONFIG_CRYPTO_NULL=m
+CONFIG_CRYPTO_CRYPTD=m
+CONFIG_CRYPTO_TEST=m
+CONFIG_CRYPTO_CCM=m
+CONFIG_CRYPTO_GCM=m
+CONFIG_CRYPTO_CTS=m
+CONFIG_CRYPTO_LRW=m
+CONFIG_CRYPTO_PCBC=m
+CONFIG_CRYPTO_XTS=m
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_XCBC=m
+CONFIG_CRYPTO_VMAC=m
+CONFIG_CRYPTO_MICHAEL_MIC=m
+CONFIG_CRYPTO_RMD128=m
+CONFIG_CRYPTO_RMD160=m
+CONFIG_CRYPTO_RMD256=m
+CONFIG_CRYPTO_RMD320=m
+CONFIG_CRYPTO_SHA256=m
+CONFIG_CRYPTO_SHA512=m
+CONFIG_CRYPTO_TGR192=m
+CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_ANUBIS=m
+CONFIG_CRYPTO_BLOWFISH=m
+CONFIG_CRYPTO_CAMELLIA=m
+CONFIG_CRYPTO_CAST5=m
+CONFIG_CRYPTO_CAST6=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_ZLIB=m
+CONFIG_CRYPTO_LZO=m
+CONFIG_CRC_CCITT=m
+CONFIG_CRC7=m
diff -druN linux-2.6.39-libre/arch/mips/fw/arc/cmdline.c linux-3.0-rc7-libre/arch/mips/fw/arc/cmdline.c
--- linux-2.6.39-libre/arch/mips/fw/arc/cmdline.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/mips/fw/arc/cmdline.c	2011-07-11 19:51:52.000000000 -0400
@@ -5,7 +5,7 @@
  *
  * cmdline.c: Kernel command line creation using ARCS argc/argv.
  *
- * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
+ * Copyright (C) 1996 David S. Miller (davem@davemloft.net)
  */
 #include <linux/init.h>
 #include <linux/kernel.h>
diff -druN linux-2.6.39-libre/arch/mips/fw/arc/env.c linux-3.0-rc7-libre/arch/mips/fw/arc/env.c
--- linux-2.6.39-libre/arch/mips/fw/arc/env.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/mips/fw/arc/env.c	2011-07-11 19:51:52.000000000 -0400
@@ -5,7 +5,7 @@
  *
  * env.c: ARCS environment variable routines.
  *
- * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
+ * Copyright (C) 1996 David S. Miller (davem@davemloft.net)
  */
 #include <linux/init.h>
 #include <linux/kernel.h>
diff -druN linux-2.6.39-libre/arch/mips/fw/arc/identify.c linux-3.0-rc7-libre/arch/mips/fw/arc/identify.c
--- linux-2.6.39-libre/arch/mips/fw/arc/identify.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/mips/fw/arc/identify.c	2011-07-11 19:51:52.000000000 -0400
@@ -9,7 +9,7 @@
  *
  * This code is based on arch/mips/sgi/kernel/system.c, which is
  *
- * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
+ * Copyright (C) 1996 David S. Miller (davem@davemloft.net)
  */
 #include <linux/init.h>
 #include <linux/kernel.h>
diff -druN linux-2.6.39-libre/arch/mips/fw/arc/init.c linux-3.0-rc7-libre/arch/mips/fw/arc/init.c
--- linux-2.6.39-libre/arch/mips/fw/arc/init.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/mips/fw/arc/init.c	2011-07-11 19:51:52.000000000 -0400
@@ -5,7 +5,7 @@
  *
  * PROM library initialisation code.
  *
- * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
+ * Copyright (C) 1996 David S. Miller (davem@davemloft.net)
  */
 #include <linux/init.h>
 #include <linux/kernel.h>
diff -druN linux-2.6.39-libre/arch/mips/fw/arc/misc.c linux-3.0-rc7-libre/arch/mips/fw/arc/misc.c
--- linux-2.6.39-libre/arch/mips/fw/arc/misc.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/mips/fw/arc/misc.c	2011-07-11 19:51:52.000000000 -0400
@@ -5,7 +5,7 @@
  *
  * Miscellaneous ARCS PROM routines.
  *
- * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
+ * Copyright (C) 1996 David S. Miller (davem@davemloft.net)
  * Copyright (C) 1999 Ralf Baechle (ralf@gnu.org)
  * Copyright (C) 1999 Silicon Graphics, Inc.
  */
diff -druN linux-2.6.39-libre/arch/mips/fw/arc/salone.c linux-3.0-rc7-libre/arch/mips/fw/arc/salone.c
--- linux-2.6.39-libre/arch/mips/fw/arc/salone.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/mips/fw/arc/salone.c	2011-07-11 19:51:52.000000000 -0400
@@ -2,7 +2,7 @@
  * Routines to load into memory and execute stand-along program images using
  * ARCS PROM firmware.
  *
- * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
+ * Copyright (C) 1996 David S. Miller (davem@davemloft.net)
  */
 #include <linux/init.h>
 #include <asm/sgialib.h>
diff -druN linux-2.6.39-libre/arch/mips/fw/arc/time.c linux-3.0-rc7-libre/arch/mips/fw/arc/time.c
--- linux-2.6.39-libre/arch/mips/fw/arc/time.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/mips/fw/arc/time.c	2011-07-11 19:51:52.000000000 -0400
@@ -5,7 +5,7 @@
  *
  * Extracting time information from ARCS prom.
  *
- * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
+ * Copyright (C) 1996 David S. Miller (davem@davemloft.net)
  */
 #include <linux/init.h>
 
diff -druN linux-2.6.39-libre/arch/mips/fw/arc/tree.c linux-3.0-rc7-libre/arch/mips/fw/arc/tree.c
--- linux-2.6.39-libre/arch/mips/fw/arc/tree.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/mips/fw/arc/tree.c	2011-07-11 19:51:52.000000000 -0400
@@ -5,7 +5,7 @@
  *
  * PROM component device tree code.
  *
- * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
+ * Copyright (C) 1996 David S. Miller (davem@davemloft.net)
  * Copyright (C) 1999 Ralf Baechle (ralf@gnu.org)
  * Copyright (C) 1999 Silicon Graphics, Inc.
  */
diff -druN linux-2.6.39-libre/arch/mips/include/asm/asmmacro-32.h linux-3.0-rc7-libre/arch/mips/include/asm/asmmacro-32.h
--- linux-2.6.39-libre/arch/mips/include/asm/asmmacro-32.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/mips/include/asm/asmmacro-32.h	2011-07-11 19:51:52.000000000 -0400
@@ -1,7 +1,7 @@
 /*
  * asmmacro.h: Assembler macros to make things easier to read.
  *
- * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
+ * Copyright (C) 1996 David S. Miller (davem@davemloft.net)
  * Copyright (C) 1998, 1999, 2003 Ralf Baechle
  */
 #ifndef _ASM_ASMMACRO_32_H
diff -druN linux-2.6.39-libre/arch/mips/include/asm/asmmacro-64.h linux-3.0-rc7-libre/arch/mips/include/asm/asmmacro-64.h
--- linux-2.6.39-libre/arch/mips/include/asm/asmmacro-64.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/mips/include/asm/asmmacro-64.h	2011-07-11 19:51:52.000000000 -0400
@@ -1,7 +1,7 @@
 /*
  * asmmacro.h: Assembler macros to make things easier to read.
  *
- * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
+ * Copyright (C) 1996 David S. Miller (davem@davemloft.net)
  * Copyright (C) 1998, 1999 Ralf Baechle
  * Copyright (C) 1999 Silicon Graphics, Inc.
  */
diff -druN linux-2.6.39-libre/arch/mips/include/asm/cpu.h linux-3.0-rc7-libre/arch/mips/include/asm/cpu.h
--- linux-2.6.39-libre/arch/mips/include/asm/cpu.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/mips/include/asm/cpu.h	2011-07-11 19:51:52.000000000 -0400
@@ -2,7 +2,7 @@
  * cpu.h: Values of the PRId register used to match up
  *        various MIPS cpu types.
  *
- * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
+ * Copyright (C) 1996 David S. Miller (davem@davemloft.net)
  * Copyright (C) 2004  Maciej W. Rozycki
  */
 #ifndef _ASM_CPU_H
@@ -33,6 +33,7 @@
 #define PRID_COMP_TOSHIBA	0x070000
 #define PRID_COMP_LSI		0x080000
 #define PRID_COMP_LEXRA		0x0b0000
+#define PRID_COMP_NETLOGIC	0x0c0000
 #define PRID_COMP_CAVIUM	0x0d0000
 #define PRID_COMP_INGENIC	0xd00000
 
@@ -142,6 +143,31 @@
 #define PRID_IMP_JZRISC        0x0200
 
 /*
+ * These are the PRID's for when 23:16 == PRID_COMP_NETLOGIC
+ */
+#define PRID_IMP_NETLOGIC_XLR732	0x0000
+#define PRID_IMP_NETLOGIC_XLR716	0x0200
+#define PRID_IMP_NETLOGIC_XLR532	0x0900
+#define PRID_IMP_NETLOGIC_XLR308	0x0600
+#define PRID_IMP_NETLOGIC_XLR532C	0x0800
+#define PRID_IMP_NETLOGIC_XLR516C	0x0a00
+#define PRID_IMP_NETLOGIC_XLR508C	0x0b00
+#define PRID_IMP_NETLOGIC_XLR308C	0x0f00
+#define PRID_IMP_NETLOGIC_XLS608	0x8000
+#define PRID_IMP_NETLOGIC_XLS408	0x8800
+#define PRID_IMP_NETLOGIC_XLS404	0x8c00
+#define PRID_IMP_NETLOGIC_XLS208	0x8e00
+#define PRID_IMP_NETLOGIC_XLS204	0x8f00
+#define PRID_IMP_NETLOGIC_XLS108	0xce00
+#define PRID_IMP_NETLOGIC_XLS104	0xcf00
+#define PRID_IMP_NETLOGIC_XLS616B	0x4000
+#define PRID_IMP_NETLOGIC_XLS608B	0x4a00
+#define PRID_IMP_NETLOGIC_XLS416B	0x4400
+#define PRID_IMP_NETLOGIC_XLS412B	0x4c00
+#define PRID_IMP_NETLOGIC_XLS408B	0x4e00
+#define PRID_IMP_NETLOGIC_XLS404B	0x4f00
+
+/*
  * Definitions for 7:0 on legacy processors
  */
 
@@ -234,6 +260,7 @@
 	 */
 	CPU_5KC, CPU_20KC, CPU_25KF, CPU_SB1, CPU_SB1A, CPU_LOONGSON2,
 	CPU_CAVIUM_OCTEON, CPU_CAVIUM_OCTEON_PLUS, CPU_CAVIUM_OCTEON2,
+	CPU_XLR,
 
 	CPU_LAST
 };
diff -druN linux-2.6.39-libre/arch/mips/include/asm/i8253.h linux-3.0-rc7-libre/arch/mips/include/asm/i8253.h
--- linux-2.6.39-libre/arch/mips/include/asm/i8253.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/mips/include/asm/i8253.h	2011-07-11 19:51:52.000000000 -0400
@@ -12,8 +12,13 @@
 #define PIT_CH0			0x40
 #define PIT_CH2			0x42
 
+#define PIT_LATCH		LATCH
+
 extern raw_spinlock_t i8253_lock;
 
 extern void setup_pit_timer(void);
 
+#define inb_pit inb_p
+#define outb_pit outb_p
+
 #endif /* __ASM_I8253_H */
diff -druN linux-2.6.39-libre/arch/mips/include/asm/jump_label.h linux-3.0-rc7-libre/arch/mips/include/asm/jump_label.h
--- linux-2.6.39-libre/arch/mips/include/asm/jump_label.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/mips/include/asm/jump_label.h	2011-07-11 19:51:52.000000000 -0400
@@ -20,16 +20,18 @@
 #define WORD_INSN ".word"
 #endif
 
-#define JUMP_LABEL(key, label)						\
-	do {								\
-		asm goto("1:\tnop\n\t"					\
-			"nop\n\t"					\
-			".pushsection __jump_table,  \"a\"\n\t"		\
-			WORD_INSN " 1b, %l[" #label "], %0\n\t"		\
-			".popsection\n\t"				\
-			: :  "i" (key) :  : label);			\
-	} while (0)
-
+static __always_inline bool arch_static_branch(struct jump_label_key *key)
+{
+	asm goto("1:\tnop\n\t"
+		"nop\n\t"
+		".pushsection __jump_table,  \"aw\"\n\t"
+		WORD_INSN " 1b, %l[l_yes], %0\n\t"
+		".popsection\n\t"
+		: :  "i" (key) : : l_yes);
+	return false;
+l_yes:
+	return true;
+}
 
 #endif /* __KERNEL__ */
 
diff -druN linux-2.6.39-libre/arch/mips/include/asm/mach-au1x00/au1000_dma.h linux-3.0-rc7-libre/arch/mips/include/asm/mach-au1x00/au1000_dma.h
--- linux-2.6.39-libre/arch/mips/include/asm/mach-au1x00/au1000_dma.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/mips/include/asm/mach-au1x00/au1000_dma.h	2011-07-11 19:51:52.000000000 -0400
@@ -37,10 +37,6 @@
 
 #define NUM_AU1000_DMA_CHANNELS	8
 
-/* DMA Channel Base Addresses */
-#define DMA_CHANNEL_BASE	0xB4002000
-#define DMA_CHANNEL_LEN		0x00000100
-
 /* DMA Channel Register Offsets */
 #define DMA_MODE_SET		0x00000000
 #define DMA_MODE_READ		DMA_MODE_SET
diff -druN linux-2.6.39-libre/arch/mips/include/asm/mach-au1x00/au1000.h linux-3.0-rc7-libre/arch/mips/include/asm/mach-au1x00/au1000.h
--- linux-2.6.39-libre/arch/mips/include/asm/mach-au1x00/au1000.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/mips/include/asm/mach-au1x00/au1000.h	2011-07-11 19:51:52.000000000 -0400
@@ -161,6 +161,45 @@
 	return ALCHEMY_CPU_UNKNOWN;
 }
 
+/* return number of uarts on a given cputype */
+static inline int alchemy_get_uarts(int type)
+{
+	switch (type) {
+	case ALCHEMY_CPU_AU1000:
+		return 4;
+	case ALCHEMY_CPU_AU1500:
+	case ALCHEMY_CPU_AU1200:
+		return 2;
+	case ALCHEMY_CPU_AU1100:
+	case ALCHEMY_CPU_AU1550:
+		return 3;
+	}
+	return 0;
+}
+
+/* enable an UART block if it isn't already */
+static inline void alchemy_uart_enable(u32 uart_phys)
+{
+	void __iomem *addr = (void __iomem *)KSEG1ADDR(uart_phys);
+
+	/* reset, enable clock, deassert reset */
+	if ((__raw_readl(addr + 0x100) & 3) != 3) {
+		__raw_writel(0, addr + 0x100);
+		wmb();
+		__raw_writel(1, addr + 0x100);
+		wmb();
+	}
+	__raw_writel(3, addr + 0x100);
+	wmb();
+}
+
+static inline void alchemy_uart_disable(u32 uart_phys)
+{
+	void __iomem *addr = (void __iomem *)KSEG1ADDR(uart_phys);
+	__raw_writel(0, addr + 0x100);	/* UART_MOD_CNTRL */
+	wmb();
+}
+
 static inline void alchemy_uart_putchar(u32 uart_phys, u8 c)
 {
 	void __iomem *base = (void __iomem *)KSEG1ADDR(uart_phys);
@@ -180,6 +219,20 @@
 	wmb();
 }
 
+/* return number of ethernet MACs on a given cputype */
+static inline int alchemy_get_macs(int type)
+{
+	switch (type) {
+	case ALCHEMY_CPU_AU1000:
+	case ALCHEMY_CPU_AU1500:
+	case ALCHEMY_CPU_AU1550:
+		return 2;
+	case ALCHEMY_CPU_AU1100:
+		return 1;
+	}
+	return 0;
+}
+
 /* arch/mips/au1000/common/clocks.c */
 extern void set_au1x00_speed(unsigned int new_freq);
 extern unsigned int get_au1x00_speed(void);
@@ -630,38 +683,42 @@
 
 /*
  * Physical base addresses for integrated peripherals
+ * 0..au1000 1..au1500 2..au1100 3..au1550 4..au1200
  */
 
+#define AU1000_AC97_PHYS_ADDR		0x10000000 /* 012 */
+#define AU1000_USBD_PHYS_ADDR		0x10200000 /* 0123 */
+#define AU1000_IC0_PHYS_ADDR		0x10400000 /* 01234 */
+#define AU1000_MAC0_PHYS_ADDR		0x10500000 /* 023 */
+#define AU1000_MAC1_PHYS_ADDR		0x10510000 /* 023 */
+#define AU1000_MACEN_PHYS_ADDR		0x10520000 /* 023 */
+#define AU1100_SD0_PHYS_ADDR		0x10600000 /* 24 */
+#define AU1100_SD1_PHYS_ADDR		0x10680000 /* 24 */
+#define AU1000_I2S_PHYS_ADDR		0x11000000 /* 02 */
+#define AU1500_MAC0_PHYS_ADDR		0x11500000 /* 1 */
+#define AU1500_MAC1_PHYS_ADDR		0x11510000 /* 1 */
+#define AU1500_MACEN_PHYS_ADDR		0x11520000 /* 1 */
+#define AU1000_UART0_PHYS_ADDR		0x11100000 /* 01234 */
+#define AU1000_UART1_PHYS_ADDR		0x11200000 /* 0234 */
+#define AU1000_UART2_PHYS_ADDR		0x11300000 /* 0 */
+#define AU1000_UART3_PHYS_ADDR		0x11400000 /* 0123 */
+#define AU1500_GPIO2_PHYS_ADDR		0x11700000 /* 1234 */
+#define AU1000_IC1_PHYS_ADDR		0x11800000 /* 01234 */
+#define AU1000_SYS_PHYS_ADDR		0x11900000 /* 01234 */
+#define AU1000_DMA_PHYS_ADDR		0x14002000 /* 012 */
+#define AU1550_DBDMA_PHYS_ADDR		0x14002000 /* 34 */
+#define AU1550_DBDMA_CONF_PHYS_ADDR	0x14003000 /* 34 */
+#define AU1000_MACDMA0_PHYS_ADDR	0x14004000 /* 0123 */
+#define AU1000_MACDMA1_PHYS_ADDR	0x14004200 /* 0123 */
+
+
 #ifdef CONFIG_SOC_AU1000
 #define	MEM_PHYS_ADDR		0x14000000
 #define	STATIC_MEM_PHYS_ADDR	0x14001000
-#define	DMA0_PHYS_ADDR		0x14002000
-#define	DMA1_PHYS_ADDR		0x14002100
-#define	DMA2_PHYS_ADDR		0x14002200
-#define	DMA3_PHYS_ADDR		0x14002300
-#define	DMA4_PHYS_ADDR		0x14002400
-#define	DMA5_PHYS_ADDR		0x14002500
-#define	DMA6_PHYS_ADDR		0x14002600
-#define	DMA7_PHYS_ADDR		0x14002700
-#define	IC0_PHYS_ADDR		0x10400000
-#define	IC1_PHYS_ADDR		0x11800000
-#define	AC97_PHYS_ADDR		0x10000000
 #define	USBH_PHYS_ADDR		0x10100000
-#define	USBD_PHYS_ADDR		0x10200000
 #define	IRDA_PHYS_ADDR		0x10300000
-#define	MAC0_PHYS_ADDR		0x10500000
-#define	MAC1_PHYS_ADDR		0x10510000
-#define	MACEN_PHYS_ADDR		0x10520000
-#define	MACDMA0_PHYS_ADDR	0x14004000
-#define	MACDMA1_PHYS_ADDR	0x14004200
-#define	I2S_PHYS_ADDR		0x11000000
-#define	UART0_PHYS_ADDR		0x11100000
-#define	UART1_PHYS_ADDR		0x11200000
-#define	UART2_PHYS_ADDR		0x11300000
-#define	UART3_PHYS_ADDR		0x11400000
 #define	SSI0_PHYS_ADDR		0x11600000
 #define	SSI1_PHYS_ADDR		0x11680000
-#define	SYS_PHYS_ADDR		0x11900000
 #define PCMCIA_IO_PHYS_ADDR	0xF00000000ULL
 #define PCMCIA_ATTR_PHYS_ADDR	0xF40000000ULL
 #define PCMCIA_MEM_PHYS_ADDR	0xF80000000ULL
@@ -672,30 +729,8 @@
 #ifdef CONFIG_SOC_AU1500
 #define	MEM_PHYS_ADDR		0x14000000
 #define	STATIC_MEM_PHYS_ADDR	0x14001000
-#define	DMA0_PHYS_ADDR		0x14002000
-#define	DMA1_PHYS_ADDR		0x14002100
-#define	DMA2_PHYS_ADDR		0x14002200
-#define	DMA3_PHYS_ADDR		0x14002300
-#define	DMA4_PHYS_ADDR		0x14002400
-#define	DMA5_PHYS_ADDR		0x14002500
-#define	DMA6_PHYS_ADDR		0x14002600
-#define	DMA7_PHYS_ADDR		0x14002700
-#define	IC0_PHYS_ADDR		0x10400000
-#define	IC1_PHYS_ADDR		0x11800000
-#define	AC97_PHYS_ADDR		0x10000000
 #define	USBH_PHYS_ADDR		0x10100000
-#define	USBD_PHYS_ADDR		0x10200000
 #define PCI_PHYS_ADDR		0x14005000
-#define	MAC0_PHYS_ADDR		0x11500000
-#define	MAC1_PHYS_ADDR		0x11510000
-#define	MACEN_PHYS_ADDR		0x11520000
-#define	MACDMA0_PHYS_ADDR	0x14004000
-#define	MACDMA1_PHYS_ADDR	0x14004200
-#define	I2S_PHYS_ADDR		0x11000000
-#define	UART0_PHYS_ADDR		0x11100000
-#define	UART3_PHYS_ADDR		0x11400000
-#define GPIO2_PHYS_ADDR		0x11700000
-#define	SYS_PHYS_ADDR		0x11900000
 #define PCI_MEM_PHYS_ADDR	0x400000000ULL
 #define PCI_IO_PHYS_ADDR	0x500000000ULL
 #define PCI_CONFIG0_PHYS_ADDR	0x600000000ULL
@@ -710,34 +745,10 @@
 #ifdef CONFIG_SOC_AU1100
 #define	MEM_PHYS_ADDR		0x14000000
 #define	STATIC_MEM_PHYS_ADDR	0x14001000
-#define	DMA0_PHYS_ADDR		0x14002000
-#define	DMA1_PHYS_ADDR		0x14002100
-#define	DMA2_PHYS_ADDR		0x14002200
-#define	DMA3_PHYS_ADDR		0x14002300
-#define	DMA4_PHYS_ADDR		0x14002400
-#define	DMA5_PHYS_ADDR		0x14002500
-#define	DMA6_PHYS_ADDR		0x14002600
-#define	DMA7_PHYS_ADDR		0x14002700
-#define	IC0_PHYS_ADDR		0x10400000
-#define SD0_PHYS_ADDR		0x10600000
-#define SD1_PHYS_ADDR		0x10680000
-#define	IC1_PHYS_ADDR		0x11800000
-#define	AC97_PHYS_ADDR		0x10000000
 #define	USBH_PHYS_ADDR		0x10100000
-#define	USBD_PHYS_ADDR		0x10200000
 #define	IRDA_PHYS_ADDR		0x10300000
-#define	MAC0_PHYS_ADDR		0x10500000
-#define	MACEN_PHYS_ADDR		0x10520000
-#define	MACDMA0_PHYS_ADDR	0x14004000
-#define	MACDMA1_PHYS_ADDR	0x14004200
-#define	I2S_PHYS_ADDR		0x11000000
-#define	UART0_PHYS_ADDR		0x11100000
-#define	UART1_PHYS_ADDR		0x11200000
-#define	UART3_PHYS_ADDR		0x11400000
 #define	SSI0_PHYS_ADDR		0x11600000
 #define	SSI1_PHYS_ADDR		0x11680000
-#define GPIO2_PHYS_ADDR		0x11700000
-#define	SYS_PHYS_ADDR		0x11900000
 #define LCD_PHYS_ADDR		0x15000000
 #define PCMCIA_IO_PHYS_ADDR	0xF00000000ULL
 #define PCMCIA_ATTR_PHYS_ADDR	0xF40000000ULL
@@ -749,22 +760,8 @@
 #ifdef CONFIG_SOC_AU1550
 #define	MEM_PHYS_ADDR		0x14000000
 #define	STATIC_MEM_PHYS_ADDR	0x14001000
-#define	IC0_PHYS_ADDR		0x10400000
-#define	IC1_PHYS_ADDR		0x11800000
 #define	USBH_PHYS_ADDR		0x14020000
-#define	USBD_PHYS_ADDR		0x10200000
 #define PCI_PHYS_ADDR		0x14005000
-#define	MAC0_PHYS_ADDR		0x10500000
-#define	MAC1_PHYS_ADDR		0x10510000
-#define	MACEN_PHYS_ADDR		0x10520000
-#define	MACDMA0_PHYS_ADDR	0x14004000
-#define	MACDMA1_PHYS_ADDR	0x14004200
-#define	UART0_PHYS_ADDR		0x11100000
-#define	UART1_PHYS_ADDR		0x11200000
-#define	UART3_PHYS_ADDR		0x11400000
-#define GPIO2_PHYS_ADDR		0x11700000
-#define	SYS_PHYS_ADDR		0x11900000
-#define	DDMA_PHYS_ADDR		0x14002000
 #define PE_PHYS_ADDR		0x14008000
 #define PSC0_PHYS_ADDR		0x11A00000
 #define PSC1_PHYS_ADDR		0x11B00000
@@ -786,19 +783,10 @@
 #define	STATIC_MEM_PHYS_ADDR	0x14001000
 #define AES_PHYS_ADDR		0x10300000
 #define CIM_PHYS_ADDR		0x14004000
-#define	IC0_PHYS_ADDR		0x10400000
-#define	IC1_PHYS_ADDR		0x11800000
 #define USBM_PHYS_ADDR		0x14020000
 #define	USBH_PHYS_ADDR		0x14020100
-#define	UART0_PHYS_ADDR		0x11100000
-#define	UART1_PHYS_ADDR		0x11200000
-#define GPIO2_PHYS_ADDR		0x11700000
-#define	SYS_PHYS_ADDR		0x11900000
-#define	DDMA_PHYS_ADDR		0x14002000
 #define PSC0_PHYS_ADDR	 	0x11A00000
 #define PSC1_PHYS_ADDR	 	0x11B00000
-#define SD0_PHYS_ADDR		0x10600000
-#define SD1_PHYS_ADDR		0x10680000
 #define LCD_PHYS_ADDR		0x15000000
 #define SWCNT_PHYS_ADDR		0x1110010C
 #define MAEFE_PHYS_ADDR		0x14012000
@@ -835,183 +823,43 @@
 #endif
 
 
-/* Interrupt Controller register offsets */
-#define IC_CFG0RD		0x40
-#define IC_CFG0SET		0x40
-#define IC_CFG0CLR		0x44
-#define IC_CFG1RD		0x48
-#define IC_CFG1SET		0x48
-#define IC_CFG1CLR		0x4C
-#define IC_CFG2RD		0x50
-#define IC_CFG2SET		0x50
-#define IC_CFG2CLR		0x54
-#define IC_REQ0INT		0x54
-#define IC_SRCRD		0x58
-#define IC_SRCSET		0x58
-#define IC_SRCCLR		0x5C
-#define IC_REQ1INT		0x5C
-#define IC_ASSIGNRD		0x60
-#define IC_ASSIGNSET		0x60
-#define IC_ASSIGNCLR		0x64
-#define IC_WAKERD		0x68
-#define IC_WAKESET		0x68
-#define IC_WAKECLR		0x6C
-#define IC_MASKRD		0x70
-#define IC_MASKSET		0x70
-#define IC_MASKCLR		0x74
-#define IC_RISINGRD		0x78
-#define IC_RISINGCLR		0x78
-#define IC_FALLINGRD		0x7C
-#define IC_FALLINGCLR		0x7C
-#define IC_TESTBIT		0x80
-
-
-/* Interrupt Controller 0 */
-#define IC0_CFG0RD		0xB0400040
-#define IC0_CFG0SET		0xB0400040
-#define IC0_CFG0CLR		0xB0400044
-
-#define IC0_CFG1RD		0xB0400048
-#define IC0_CFG1SET		0xB0400048
-#define IC0_CFG1CLR		0xB040004C
-
-#define IC0_CFG2RD		0xB0400050
-#define IC0_CFG2SET		0xB0400050
-#define IC0_CFG2CLR		0xB0400054
-
-#define IC0_REQ0INT		0xB0400054
-#define IC0_SRCRD		0xB0400058
-#define IC0_SRCSET		0xB0400058
-#define IC0_SRCCLR		0xB040005C
-#define IC0_REQ1INT		0xB040005C
-
-#define IC0_ASSIGNRD		0xB0400060
-#define IC0_ASSIGNSET		0xB0400060
-#define IC0_ASSIGNCLR		0xB0400064
-
-#define IC0_WAKERD		0xB0400068
-#define IC0_WAKESET		0xB0400068
-#define IC0_WAKECLR		0xB040006C
-
-#define IC0_MASKRD		0xB0400070
-#define IC0_MASKSET		0xB0400070
-#define IC0_MASKCLR		0xB0400074
-
-#define IC0_RISINGRD		0xB0400078
-#define IC0_RISINGCLR		0xB0400078
-#define IC0_FALLINGRD		0xB040007C
-#define IC0_FALLINGCLR		0xB040007C
-
-#define IC0_TESTBIT		0xB0400080
-
-/* Interrupt Controller 1 */
-#define IC1_CFG0RD		0xB1800040
-#define IC1_CFG0SET		0xB1800040
-#define IC1_CFG0CLR		0xB1800044
-
-#define IC1_CFG1RD		0xB1800048
-#define IC1_CFG1SET		0xB1800048
-#define IC1_CFG1CLR		0xB180004C
-
-#define IC1_CFG2RD		0xB1800050
-#define IC1_CFG2SET		0xB1800050
-#define IC1_CFG2CLR		0xB1800054
-
-#define IC1_REQ0INT		0xB1800054
-#define IC1_SRCRD		0xB1800058
-#define IC1_SRCSET		0xB1800058
-#define IC1_SRCCLR		0xB180005C
-#define IC1_REQ1INT		0xB180005C
-
-#define IC1_ASSIGNRD            0xB1800060
-#define IC1_ASSIGNSET           0xB1800060
-#define IC1_ASSIGNCLR           0xB1800064
-
-#define IC1_WAKERD		0xB1800068
-#define IC1_WAKESET		0xB1800068
-#define IC1_WAKECLR		0xB180006C
-
-#define IC1_MASKRD		0xB1800070
-#define IC1_MASKSET		0xB1800070
-#define IC1_MASKCLR		0xB1800074
-
-#define IC1_RISINGRD		0xB1800078
-#define IC1_RISINGCLR		0xB1800078
-#define IC1_FALLINGRD		0xB180007C
-#define IC1_FALLINGCLR		0xB180007C
-
-#define IC1_TESTBIT		0xB1800080
 
 
 /* Au1000 */
 #ifdef CONFIG_SOC_AU1000
 
-#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 AU1000_USB_HOST_INT
-
-#define AU1000_ETH0_BASE	0xB0500000
-#define AU1000_ETH1_BASE	0xB0510000
-#define AU1000_MAC0_ENABLE	0xB0520000
-#define AU1000_MAC1_ENABLE	0xB0520004
-#define NUM_ETH_INTERFACES 2
 #endif /* CONFIG_SOC_AU1000 */
 
 /* Au1500 */
 #ifdef CONFIG_SOC_AU1500
 
-#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
-#define AU1500_MAC0_ENABLE	0xB1520000
-#define AU1500_MAC1_ENABLE	0xB1520004
-#define NUM_ETH_INTERFACES 2
 #endif /* CONFIG_SOC_AU1500 */
 
 /* Au1100 */
 #ifdef CONFIG_SOC_AU1100
 
-#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 AU1100_USB_HOST_INT
-
-#define AU1100_ETH0_BASE	0xB0500000
-#define AU1100_MAC0_ENABLE	0xB0520000
-#define NUM_ETH_INTERFACES 1
 #endif /* CONFIG_SOC_AU1100 */
 
 #ifdef CONFIG_SOC_AU1550
-#define UART0_ADDR		0xB1100000
 
 #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
-#define AU1550_MAC0_ENABLE	0xB0520000
-#define AU1550_MAC1_ENABLE	0xB0520004
-#define NUM_ETH_INTERFACES 2
 #endif /* CONFIG_SOC_AU1550 */
 
 
 #ifdef CONFIG_SOC_AU1200
 
-#define UART0_ADDR		0xB1100000
-
 #define USB_UOC_BASE		0x14020020
 #define USB_UOC_LEN		0x20
 #define USB_OHCI_BASE		0x14020100
@@ -1504,22 +1352,6 @@
 #define SYS_PINFUNC_S1B 	(1 << 2)
 #endif
 
-#define SYS_TRIOUTRD		0xB1900100
-#define SYS_TRIOUTCLR		0xB1900100
-#define SYS_OUTPUTRD		0xB1900108
-#define SYS_OUTPUTSET		0xB1900108
-#define SYS_OUTPUTCLR		0xB190010C
-#define SYS_PINSTATERD		0xB1900110
-#define SYS_PININPUTEN		0xB1900110
-
-/* GPIO2, Au1500, Au1550 only */
-#define GPIO2_BASE		0xB1700000
-#define GPIO2_DIR		(GPIO2_BASE + 0)
-#define GPIO2_OUTPUT		(GPIO2_BASE + 8)
-#define GPIO2_PINSTATE		(GPIO2_BASE + 0xC)
-#define GPIO2_INTENABLE 	(GPIO2_BASE + 0x10)
-#define GPIO2_ENABLE		(GPIO2_BASE + 0x14)
-
 /* Power Management */
 #define SYS_SCRATCH0		0xB1900018
 #define SYS_SCRATCH1		0xB190001C
@@ -1635,12 +1467,6 @@
 #  define AC97C_RS		(1 << 1)
 #  define AC97C_CE		(1 << 0)
 
-/* Secure Digital (SD) Controller */
-#define SD0_XMIT_FIFO	0xB0600000
-#define SD0_RECV_FIFO	0xB0600004
-#define SD1_XMIT_FIFO	0xB0680000
-#define SD1_RECV_FIFO	0xB0680004
-
 #if defined(CONFIG_SOC_AU1500) || defined(CONFIG_SOC_AU1550)
 /* Au1500 PCI Controller */
 #define Au1500_CFG_BASE 	0xB4005000	/* virtual, KSEG1 addr */
diff -druN linux-2.6.39-libre/arch/mips/include/asm/mach-au1x00/au1xxx_dbdma.h linux-3.0-rc7-libre/arch/mips/include/asm/mach-au1x00/au1xxx_dbdma.h
--- linux-2.6.39-libre/arch/mips/include/asm/mach-au1x00/au1xxx_dbdma.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/mips/include/asm/mach-au1x00/au1xxx_dbdma.h	2011-07-11 19:51:52.000000000 -0400
@@ -37,14 +37,6 @@
 
 #ifndef _LANGUAGE_ASSEMBLY
 
-/*
- * The DMA base addresses.
- * The channels are every 256 bytes (0x0100) from the channel 0 base.
- * Interrupt status/enable is bits 15:0 for channels 15 to zero.
- */
-#define DDMA_GLOBAL_BASE	0xb4003000
-#define DDMA_CHANNEL_BASE	0xb4002000
-
 typedef volatile struct dbdma_global {
 	u32	ddma_config;
 	u32	ddma_intstat;
diff -druN linux-2.6.39-libre/arch/mips/include/asm/mach-au1x00/gpio-au1000.h linux-3.0-rc7-libre/arch/mips/include/asm/mach-au1x00/gpio-au1000.h
--- linux-2.6.39-libre/arch/mips/include/asm/mach-au1x00/gpio-au1000.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/mips/include/asm/mach-au1x00/gpio-au1000.h	2011-07-11 19:51:52.000000000 -0400
@@ -24,6 +24,23 @@
 
 #define MAKE_IRQ(intc, off)	(AU1000_INTC##intc##_INT_BASE + (off))
 
+/* GPIO1 registers within SYS_ area */
+#define SYS_TRIOUTRD		0x100
+#define SYS_TRIOUTCLR		0x100
+#define SYS_OUTPUTRD		0x108
+#define SYS_OUTPUTSET		0x108
+#define SYS_OUTPUTCLR		0x10C
+#define SYS_PINSTATERD		0x110
+#define SYS_PININPUTEN		0x110
+
+/* register offsets within GPIO2 block */
+#define GPIO2_DIR		0x00
+#define GPIO2_OUTPUT		0x08
+#define GPIO2_PINSTATE		0x0C
+#define GPIO2_INTENABLE		0x10
+#define GPIO2_ENABLE		0x14
+
+struct gpio;
 
 static inline int au1000_gpio1_to_irq(int gpio)
 {
@@ -200,23 +217,26 @@
  */
 static inline void alchemy_gpio1_set_value(int gpio, int v)
 {
+	void __iomem *base = (void __iomem *)KSEG1ADDR(AU1000_SYS_PHYS_ADDR);
 	unsigned long mask = 1 << (gpio - ALCHEMY_GPIO1_BASE);
 	unsigned long r = v ? SYS_OUTPUTSET : SYS_OUTPUTCLR;
-	au_writel(mask, r);
-	au_sync();
+	__raw_writel(mask, base + r);
+	wmb();
 }
 
 static inline int alchemy_gpio1_get_value(int gpio)
 {
+	void __iomem *base = (void __iomem *)KSEG1ADDR(AU1000_SYS_PHYS_ADDR);
 	unsigned long mask = 1 << (gpio - ALCHEMY_GPIO1_BASE);
-	return au_readl(SYS_PINSTATERD) & mask;
+	return __raw_readl(base + SYS_PINSTATERD) & mask;
 }
 
 static inline int alchemy_gpio1_direction_input(int gpio)
 {
+	void __iomem *base = (void __iomem *)KSEG1ADDR(AU1000_SYS_PHYS_ADDR);
 	unsigned long mask = 1 << (gpio - ALCHEMY_GPIO1_BASE);
-	au_writel(mask, SYS_TRIOUTCLR);
-	au_sync();
+	__raw_writel(mask, base + SYS_TRIOUTCLR);
+	wmb();
 	return 0;
 }
 
@@ -257,27 +277,31 @@
  */
 static inline void __alchemy_gpio2_mod_dir(int gpio, int to_out)
 {
+	void __iomem *base = (void __iomem *)KSEG1ADDR(AU1500_GPIO2_PHYS_ADDR);
 	unsigned long mask = 1 << (gpio - ALCHEMY_GPIO2_BASE);
-	unsigned long d = au_readl(GPIO2_DIR);
+	unsigned long d = __raw_readl(base + GPIO2_DIR);
+
 	if (to_out)
 		d |= mask;
 	else
 		d &= ~mask;
-	au_writel(d, GPIO2_DIR);
-	au_sync();
+	__raw_writel(d, base + GPIO2_DIR);
+	wmb();
 }
 
 static inline void alchemy_gpio2_set_value(int gpio, int v)
 {
+	void __iomem *base = (void __iomem *)KSEG1ADDR(AU1500_GPIO2_PHYS_ADDR);
 	unsigned long mask;
 	mask = ((v) ? 0x00010001 : 0x00010000) << (gpio - ALCHEMY_GPIO2_BASE);
-	au_writel(mask, GPIO2_OUTPUT);
-	au_sync();
+	__raw_writel(mask, base + GPIO2_OUTPUT);
+	wmb();
 }
 
 static inline int alchemy_gpio2_get_value(int gpio)
 {
-	return au_readl(GPIO2_PINSTATE) & (1 << (gpio - ALCHEMY_GPIO2_BASE));
+	void __iomem *base = (void __iomem *)KSEG1ADDR(AU1500_GPIO2_PHYS_ADDR);
+	return __raw_readl(base + GPIO2_PINSTATE) & (1 << (gpio - ALCHEMY_GPIO2_BASE));
 }
 
 static inline int alchemy_gpio2_direction_input(int gpio)
@@ -329,21 +353,23 @@
  */
 static inline void alchemy_gpio1_input_enable(void)
 {
-	au_writel(0, SYS_PININPUTEN);	/* the write op is key */
-	au_sync();
+	void __iomem *base = (void __iomem *)KSEG1ADDR(AU1000_SYS_PHYS_ADDR);
+	__raw_writel(0, base + SYS_PININPUTEN);	/* the write op is key */
+	wmb();
 }
 
 /* GPIO2 shared interrupts and control */
 
 static inline void __alchemy_gpio2_mod_int(int gpio2, int en)
 {
-	unsigned long r = au_readl(GPIO2_INTENABLE);
+	void __iomem *base = (void __iomem *)KSEG1ADDR(AU1500_GPIO2_PHYS_ADDR);
+	unsigned long r = __raw_readl(base + GPIO2_INTENABLE);
 	if (en)
 		r |= 1 << gpio2;
 	else
 		r &= ~(1 << gpio2);
-	au_writel(r, GPIO2_INTENABLE);
-	au_sync();
+	__raw_writel(r, base + GPIO2_INTENABLE);
+	wmb();
 }
 
 /**
@@ -418,10 +444,11 @@
  */
 static inline void alchemy_gpio2_enable(void)
 {
-	au_writel(3, GPIO2_ENABLE);	/* reset, clock enabled */
-	au_sync();
-	au_writel(1, GPIO2_ENABLE);	/* clock enabled */
-	au_sync();
+	void __iomem *base = (void __iomem *)KSEG1ADDR(AU1500_GPIO2_PHYS_ADDR);
+	__raw_writel(3, base + GPIO2_ENABLE);	/* reset, clock enabled */
+	wmb();
+	__raw_writel(1, base + GPIO2_ENABLE);	/* clock enabled */
+	wmb();
 }
 
 /**
@@ -431,8 +458,9 @@
  */
 static inline void alchemy_gpio2_disable(void)
 {
-	au_writel(2, GPIO2_ENABLE);	/* reset, clock disabled */
-	au_sync();
+	void __iomem *base = (void __iomem *)KSEG1ADDR(AU1500_GPIO2_PHYS_ADDR);
+	__raw_writel(2, base + GPIO2_ENABLE);	/* reset, clock disabled */
+	wmb();
 }
 
 /**********************************************************************/
@@ -556,6 +584,16 @@
 	alchemy_gpio_set_value(gpio, v);
 }
 
+static inline int gpio_get_value_cansleep(unsigned gpio)
+{
+	return gpio_get_value(gpio);
+}
+
+static inline void gpio_set_value_cansleep(unsigned gpio, int value)
+{
+	gpio_set_value(gpio, value);
+}
+
 static inline int gpio_is_valid(int gpio)
 {
 	return alchemy_gpio_is_valid(gpio);
@@ -581,10 +619,50 @@
 	return 0;
 }
 
+static inline int gpio_request_one(unsigned gpio,
+					unsigned long flags, const char *label)
+{
+	return 0;
+}
+
+static inline int gpio_request_array(struct gpio *array, size_t num)
+{
+	return 0;
+}
+
 static inline void gpio_free(unsigned gpio)
 {
 }
 
+static inline void gpio_free_array(struct gpio *array, size_t num)
+{
+}
+
+static inline int gpio_set_debounce(unsigned gpio, unsigned debounce)
+{
+	return -ENOSYS;
+}
+
+static inline int gpio_export(unsigned gpio, bool direction_may_change)
+{
+	return -ENOSYS;
+}
+
+static inline int gpio_export_link(struct device *dev, const char *name,
+				   unsigned gpio)
+{
+	return -ENOSYS;
+}
+
+static inline int gpio_sysfs_set_active_low(unsigned gpio, int value)
+{
+	return -ENOSYS;
+}
+
+static inline void gpio_unexport(unsigned gpio)
+{
+}
+
 #endif	/* !CONFIG_ALCHEMY_GPIO_INDIRECT */
 
 
diff -druN linux-2.6.39-libre/arch/mips/include/asm/mach-bcm47xx/nvram.h linux-3.0-rc7-libre/arch/mips/include/asm/mach-bcm47xx/nvram.h
--- linux-2.6.39-libre/arch/mips/include/asm/mach-bcm47xx/nvram.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/mips/include/asm/mach-bcm47xx/nvram.h	2011-07-11 19:51:52.000000000 -0400
@@ -39,8 +39,16 @@
 
 static inline void nvram_parse_macaddr(char *buf, u8 *macaddr)
 {
-	sscanf(buf, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx", &macaddr[0], &macaddr[1],
-	       &macaddr[2], &macaddr[3], &macaddr[4], &macaddr[5]);
+	if (strchr(buf, ':'))
+		sscanf(buf, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx", &macaddr[0],
+			&macaddr[1], &macaddr[2], &macaddr[3], &macaddr[4],
+			&macaddr[5]);
+	else if (strchr(buf, '-'))
+		sscanf(buf, "%hhx-%hhx-%hhx-%hhx-%hhx-%hhx", &macaddr[0],
+			&macaddr[1], &macaddr[2], &macaddr[3], &macaddr[4],
+			&macaddr[5]);
+	else
+		printk(KERN_WARNING "Can not parse mac address: %s\n", buf);
 }
 
 #endif
diff -druN linux-2.6.39-libre/arch/mips/include/asm/mach-cavium-octeon/kernel-entry-init.h linux-3.0-rc7-libre/arch/mips/include/asm/mach-cavium-octeon/kernel-entry-init.h
--- linux-2.6.39-libre/arch/mips/include/asm/mach-cavium-octeon/kernel-entry-init.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/mips/include/asm/mach-cavium-octeon/kernel-entry-init.h	2011-07-11 19:51:52.000000000 -0400
@@ -63,6 +63,11 @@
 	# CN30XX Disable instruction prefetching
 	or  v0, v0, 0x2000
 skip:
+	# First clear off CvmCtl[IPPCI] bit and move the performance
+	# counters interrupt to IRQ 6
+	li	v1, ~(7 << 7)
+	and	v0, v0, v1
+	ori	v0, v0, (6 << 7)
 	# Write the cavium control register
 	dmtc0   v0, CP0_CVMCTL_REG
 	sync
diff -druN linux-2.6.39-libre/arch/mips/include/asm/mach-lantiq/lantiq.h linux-3.0-rc7-libre/arch/mips/include/asm/mach-lantiq/lantiq.h
--- linux-2.6.39-libre/arch/mips/include/asm/mach-lantiq/lantiq.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/mips/include/asm/mach-lantiq/lantiq.h	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,63 @@
+/*
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License version 2 as published
+ *  by the Free Software Foundation.
+ *
+ *  Copyright (C) 2010 John Crispin <blogic@openwrt.org>
+ */
+#ifndef _LANTIQ_H__
+#define _LANTIQ_H__
+
+#include <linux/irq.h>
+
+/* generic reg access functions */
+#define ltq_r32(reg)		__raw_readl(reg)
+#define ltq_w32(val, reg)	__raw_writel(val, reg)
+#define ltq_w32_mask(clear, set, reg)	\
+	ltq_w32((ltq_r32(reg) & ~(clear)) | (set), reg)
+#define ltq_r8(reg)		__raw_readb(reg)
+#define ltq_w8(val, reg)	__raw_writeb(val, reg)
+
+/* register access macros for EBU and CGU */
+#define ltq_ebu_w32(x, y)	ltq_w32((x), ltq_ebu_membase + (y))
+#define ltq_ebu_r32(x)		ltq_r32(ltq_ebu_membase + (x))
+#define ltq_cgu_w32(x, y)	ltq_w32((x), ltq_cgu_membase + (y))
+#define ltq_cgu_r32(x)		ltq_r32(ltq_cgu_membase + (x))
+
+extern __iomem void *ltq_ebu_membase;
+extern __iomem void *ltq_cgu_membase;
+
+extern unsigned int ltq_get_cpu_ver(void);
+extern unsigned int ltq_get_soc_type(void);
+
+/* clock speeds */
+#define CLOCK_60M	60000000
+#define CLOCK_83M	83333333
+#define CLOCK_111M	111111111
+#define CLOCK_133M	133333333
+#define CLOCK_167M	166666667
+#define CLOCK_200M	200000000
+#define CLOCK_266M	266666666
+#define CLOCK_333M	333333333
+#define CLOCK_400M	400000000
+
+/* spinlock all ebu i/o */
+extern spinlock_t ebu_lock;
+
+/* some irq helpers */
+extern void ltq_disable_irq(struct irq_data *data);
+extern void ltq_mask_and_ack_irq(struct irq_data *data);
+extern void ltq_enable_irq(struct irq_data *data);
+
+/* find out what caused the last cpu reset */
+extern int ltq_reset_cause(void);
+#define LTQ_RST_CAUSE_WDTRST	0x20
+
+#define IOPORT_RESOURCE_START	0x10000000
+#define IOPORT_RESOURCE_END	0xffffffff
+#define IOMEM_RESOURCE_START	0x10000000
+#define IOMEM_RESOURCE_END	0xffffffff
+#define LTQ_FLASH_START		0x10000000
+#define LTQ_FLASH_MAX		0x04000000
+
+#endif
diff -druN linux-2.6.39-libre/arch/mips/include/asm/mach-lantiq/lantiq_platform.h linux-3.0-rc7-libre/arch/mips/include/asm/mach-lantiq/lantiq_platform.h
--- linux-2.6.39-libre/arch/mips/include/asm/mach-lantiq/lantiq_platform.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/mips/include/asm/mach-lantiq/lantiq_platform.h	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,53 @@
+/*
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License version 2 as published
+ *  by the Free Software Foundation.
+ *
+ *  Copyright (C) 2010 John Crispin <blogic@openwrt.org>
+ */
+
+#ifndef _LANTIQ_PLATFORM_H__
+#define _LANTIQ_PLATFORM_H__
+
+#include <linux/mtd/partitions.h>
+#include <linux/socket.h>
+
+/* struct used to pass info to the pci core */
+enum {
+	PCI_CLOCK_INT = 0,
+	PCI_CLOCK_EXT
+};
+
+#define PCI_EXIN0	0x0001
+#define PCI_EXIN1	0x0002
+#define PCI_EXIN2	0x0004
+#define PCI_EXIN3	0x0008
+#define PCI_EXIN4	0x0010
+#define PCI_EXIN5	0x0020
+#define PCI_EXIN_MAX	6
+
+#define PCI_GNT1	0x0040
+#define PCI_GNT2	0x0080
+#define PCI_GNT3	0x0100
+#define PCI_GNT4	0x0200
+
+#define PCI_REQ1	0x0400
+#define PCI_REQ2	0x0800
+#define PCI_REQ3	0x1000
+#define PCI_REQ4	0x2000
+#define PCI_REQ_SHIFT	10
+#define PCI_REQ_MASK	0xf
+
+struct ltq_pci_data {
+	int clock;
+	int gpio;
+	int irq[16];
+};
+
+/* struct used to pass info to network drivers */
+struct ltq_eth_data {
+	struct sockaddr mac;
+	int mii_mode;
+};
+
+#endif
diff -druN linux-2.6.39-libre/arch/mips/include/asm/mach-lantiq/war.h linux-3.0-rc7-libre/arch/mips/include/asm/mach-lantiq/war.h
--- linux-2.6.39-libre/arch/mips/include/asm/mach-lantiq/war.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/mips/include/asm/mach-lantiq/war.h	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,24 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ */
+#ifndef __ASM_MIPS_MACH_LANTIQ_WAR_H
+#define __ASM_MIPS_MACH_LANTIQ_WAR_H
+
+#define R4600_V1_INDEX_ICACHEOP_WAR     0
+#define R4600_V1_HIT_CACHEOP_WAR        0
+#define R4600_V2_HIT_CACHEOP_WAR        0
+#define R5432_CP0_INTERRUPT_WAR         0
+#define BCM1250_M3_WAR                  0
+#define SIBYTE_1956_WAR                 0
+#define MIPS4K_ICACHE_REFILL_WAR        0
+#define MIPS_CACHE_SYNC_WAR             0
+#define TX49XX_ICACHE_INDEX_INV_WAR     0
+#define RM9000_CDEX_SMP_WAR             0
+#define ICACHE_REFILLS_WORKAROUND_WAR   0
+#define R10000_LLSC_WAR                 0
+#define MIPS34K_MISSED_ITLB_WAR         0
+
+#endif
diff -druN linux-2.6.39-libre/arch/mips/include/asm/mach-lantiq/xway/irq.h linux-3.0-rc7-libre/arch/mips/include/asm/mach-lantiq/xway/irq.h
--- linux-2.6.39-libre/arch/mips/include/asm/mach-lantiq/xway/irq.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/mips/include/asm/mach-lantiq/xway/irq.h	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,18 @@
+/*
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License version 2 as published
+ *  by the Free Software Foundation.
+ *
+ *  Copyright (C) 2010 John Crispin <blogic@openwrt.org>
+ */
+
+#ifndef __LANTIQ_IRQ_H
+#define __LANTIQ_IRQ_H
+
+#include <lantiq_irq.h>
+
+#define NR_IRQS 256
+
+#include_next <irq.h>
+
+#endif
diff -druN linux-2.6.39-libre/arch/mips/include/asm/mach-lantiq/xway/lantiq_irq.h linux-3.0-rc7-libre/arch/mips/include/asm/mach-lantiq/xway/lantiq_irq.h
--- linux-2.6.39-libre/arch/mips/include/asm/mach-lantiq/xway/lantiq_irq.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/mips/include/asm/mach-lantiq/xway/lantiq_irq.h	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,66 @@
+/*
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License version 2 as published
+ *  by the Free Software Foundation.
+ *
+ *  Copyright (C) 2010 John Crispin <blogic@openwrt.org>
+ */
+
+#ifndef _LANTIQ_XWAY_IRQ_H__
+#define _LANTIQ_XWAY_IRQ_H__
+
+#define INT_NUM_IRQ0		8
+#define INT_NUM_IM0_IRL0	(INT_NUM_IRQ0 + 0)
+#define INT_NUM_IM1_IRL0	(INT_NUM_IRQ0 + 32)
+#define INT_NUM_IM2_IRL0	(INT_NUM_IRQ0 + 64)
+#define INT_NUM_IM3_IRL0	(INT_NUM_IRQ0 + 96)
+#define INT_NUM_IM4_IRL0	(INT_NUM_IRQ0 + 128)
+#define INT_NUM_IM_OFFSET	(INT_NUM_IM1_IRL0 - INT_NUM_IM0_IRL0)
+
+#define LTQ_ASC_TIR(x)		(INT_NUM_IM3_IRL0 + (x * 8))
+#define LTQ_ASC_RIR(x)		(INT_NUM_IM3_IRL0 + (x * 8) + 1)
+#define LTQ_ASC_EIR(x)		(INT_NUM_IM3_IRL0 + (x * 8) + 2)
+
+#define LTQ_ASC_ASE_TIR		INT_NUM_IM2_IRL0
+#define LTQ_ASC_ASE_RIR		(INT_NUM_IM2_IRL0 + 2)
+#define LTQ_ASC_ASE_EIR		(INT_NUM_IM2_IRL0 + 3)
+
+#define LTQ_SSC_TIR		(INT_NUM_IM0_IRL0 + 15)
+#define LTQ_SSC_RIR		(INT_NUM_IM0_IRL0 + 14)
+#define LTQ_SSC_EIR		(INT_NUM_IM0_IRL0 + 16)
+
+#define LTQ_MEI_DYING_GASP_INT	(INT_NUM_IM1_IRL0 + 21)
+#define LTQ_MEI_INT		(INT_NUM_IM1_IRL0 + 23)
+
+#define LTQ_TIMER6_INT		(INT_NUM_IM1_IRL0 + 23)
+#define LTQ_USB_INT		(INT_NUM_IM1_IRL0 + 22)
+#define LTQ_USB_OC_INT		(INT_NUM_IM4_IRL0 + 23)
+
+#define MIPS_CPU_TIMER_IRQ		7
+
+#define LTQ_DMA_CH0_INT		(INT_NUM_IM2_IRL0)
+#define LTQ_DMA_CH1_INT		(INT_NUM_IM2_IRL0 + 1)
+#define LTQ_DMA_CH2_INT		(INT_NUM_IM2_IRL0 + 2)
+#define LTQ_DMA_CH3_INT		(INT_NUM_IM2_IRL0 + 3)
+#define LTQ_DMA_CH4_INT		(INT_NUM_IM2_IRL0 + 4)
+#define LTQ_DMA_CH5_INT		(INT_NUM_IM2_IRL0 + 5)
+#define LTQ_DMA_CH6_INT		(INT_NUM_IM2_IRL0 + 6)
+#define LTQ_DMA_CH7_INT		(INT_NUM_IM2_IRL0 + 7)
+#define LTQ_DMA_CH8_INT		(INT_NUM_IM2_IRL0 + 8)
+#define LTQ_DMA_CH9_INT		(INT_NUM_IM2_IRL0 + 9)
+#define LTQ_DMA_CH10_INT	(INT_NUM_IM2_IRL0 + 10)
+#define LTQ_DMA_CH11_INT	(INT_NUM_IM2_IRL0 + 11)
+#define LTQ_DMA_CH12_INT	(INT_NUM_IM2_IRL0 + 25)
+#define LTQ_DMA_CH13_INT	(INT_NUM_IM2_IRL0 + 26)
+#define LTQ_DMA_CH14_INT	(INT_NUM_IM2_IRL0 + 27)
+#define LTQ_DMA_CH15_INT	(INT_NUM_IM2_IRL0 + 28)
+#define LTQ_DMA_CH16_INT	(INT_NUM_IM2_IRL0 + 29)
+#define LTQ_DMA_CH17_INT	(INT_NUM_IM2_IRL0 + 30)
+#define LTQ_DMA_CH18_INT	(INT_NUM_IM2_IRL0 + 16)
+#define LTQ_DMA_CH19_INT	(INT_NUM_IM2_IRL0 + 21)
+
+#define LTQ_PPE_MBOX_INT	(INT_NUM_IM2_IRL0 + 24)
+
+#define INT_NUM_IM4_IRL14	(INT_NUM_IM4_IRL0 + 14)
+
+#endif
diff -druN linux-2.6.39-libre/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h linux-3.0-rc7-libre/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h
--- linux-2.6.39-libre/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,141 @@
+/*
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License version 2 as published
+ *  by the Free Software Foundation.
+ *
+ *  Copyright (C) 2010 John Crispin <blogic@openwrt.org>
+ */
+
+#ifndef _LTQ_XWAY_H__
+#define _LTQ_XWAY_H__
+
+#ifdef CONFIG_SOC_TYPE_XWAY
+
+#include <lantiq.h>
+
+/* Chip IDs */
+#define SOC_ID_DANUBE1		0x129
+#define SOC_ID_DANUBE2		0x12B
+#define SOC_ID_TWINPASS		0x12D
+#define SOC_ID_AMAZON_SE	0x152
+#define SOC_ID_ARX188		0x16C
+#define SOC_ID_ARX168		0x16D
+#define SOC_ID_ARX182		0x16F
+
+/* SoC Types */
+#define SOC_TYPE_DANUBE		0x01
+#define SOC_TYPE_TWINPASS	0x02
+#define SOC_TYPE_AR9		0x03
+#define SOC_TYPE_VR9		0x04
+#define SOC_TYPE_AMAZON_SE	0x05
+
+/* ASC0/1 - serial port */
+#define LTQ_ASC0_BASE_ADDR	0x1E100400
+#define LTQ_ASC1_BASE_ADDR	0x1E100C00
+#define LTQ_ASC_SIZE		0x400
+
+/* RCU - reset control unit */
+#define LTQ_RCU_BASE_ADDR	0x1F203000
+#define LTQ_RCU_SIZE		0x1000
+
+/* GPTU - general purpose timer unit */
+#define LTQ_GPTU_BASE_ADDR	0x18000300
+#define LTQ_GPTU_SIZE		0x100
+
+/* EBU - external bus unit */
+#define LTQ_EBU_GPIO_START	0x14000000
+#define LTQ_EBU_GPIO_SIZE	0x1000
+
+#define LTQ_EBU_BASE_ADDR	0x1E105300
+#define LTQ_EBU_SIZE		0x100
+
+#define LTQ_EBU_BUSCON0		0x0060
+#define LTQ_EBU_PCC_CON		0x0090
+#define LTQ_EBU_PCC_IEN		0x00A4
+#define LTQ_EBU_PCC_ISTAT	0x00A0
+#define LTQ_EBU_BUSCON1		0x0064
+#define LTQ_EBU_ADDRSEL1	0x0024
+#define EBU_WRDIS		0x80000000
+
+/* CGU - clock generation unit */
+#define LTQ_CGU_BASE_ADDR	0x1F103000
+#define LTQ_CGU_SIZE		0x1000
+
+/* ICU - interrupt control unit */
+#define LTQ_ICU_BASE_ADDR	0x1F880200
+#define LTQ_ICU_SIZE		0x100
+
+/* EIU - external interrupt unit */
+#define LTQ_EIU_BASE_ADDR	0x1F101000
+#define LTQ_EIU_SIZE		0x1000
+
+/* PMU - power management unit */
+#define LTQ_PMU_BASE_ADDR	0x1F102000
+#define LTQ_PMU_SIZE		0x1000
+
+#define PMU_DMA			0x0020
+#define PMU_USB			0x8041
+#define PMU_LED			0x0800
+#define PMU_GPT			0x1000
+#define PMU_PPE			0x2000
+#define PMU_FPI			0x4000
+#define PMU_SWITCH		0x10000000
+
+/* ETOP - ethernet */
+#define LTQ_ETOP_BASE_ADDR	0x1E180000
+#define LTQ_ETOP_SIZE		0x40000
+
+/* DMA */
+#define LTQ_DMA_BASE_ADDR	0x1E104100
+#define LTQ_DMA_SIZE		0x800
+
+/* PCI */
+#define PCI_CR_BASE_ADDR	0x1E105400
+#define PCI_CR_SIZE		0x400
+
+/* WDT */
+#define LTQ_WDT_BASE_ADDR	0x1F8803F0
+#define LTQ_WDT_SIZE		0x10
+
+/* STP - serial to parallel conversion unit */
+#define LTQ_STP_BASE_ADDR	0x1E100BB0
+#define LTQ_STP_SIZE		0x40
+
+/* GPIO */
+#define LTQ_GPIO0_BASE_ADDR	0x1E100B10
+#define LTQ_GPIO1_BASE_ADDR	0x1E100B40
+#define LTQ_GPIO2_BASE_ADDR	0x1E100B70
+#define LTQ_GPIO_SIZE		0x30
+
+/* SSC */
+#define LTQ_SSC_BASE_ADDR	0x1e100800
+#define LTQ_SSC_SIZE		0x100
+
+/* MEI - dsl core */
+#define LTQ_MEI_BASE_ADDR	0x1E116000
+
+/* DEU - data encryption unit */
+#define LTQ_DEU_BASE_ADDR	0x1E103100
+
+/* MPS - multi processor unit (voice) */
+#define LTQ_MPS_BASE_ADDR	(KSEG1 + 0x1F107000)
+#define LTQ_MPS_CHIPID		((u32 *)(LTQ_MPS_BASE_ADDR + 0x0344))
+
+/* request a non-gpio and set the PIO config */
+extern int  ltq_gpio_request(unsigned int pin, unsigned int alt0,
+	unsigned int alt1, unsigned int dir, const char *name);
+extern void ltq_pmu_enable(unsigned int module);
+extern void ltq_pmu_disable(unsigned int module);
+
+static inline int ltq_is_ar9(void)
+{
+	return (ltq_get_soc_type() == SOC_TYPE_AR9);
+}
+
+static inline int ltq_is_vr9(void)
+{
+	return (ltq_get_soc_type() == SOC_TYPE_VR9);
+}
+
+#endif /* CONFIG_SOC_TYPE_XWAY */
+#endif /* _LTQ_XWAY_H__ */
diff -druN linux-2.6.39-libre/arch/mips/include/asm/mach-lantiq/xway/xway_dma.h linux-3.0-rc7-libre/arch/mips/include/asm/mach-lantiq/xway/xway_dma.h
--- linux-2.6.39-libre/arch/mips/include/asm/mach-lantiq/xway/xway_dma.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/mips/include/asm/mach-lantiq/xway/xway_dma.h	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,60 @@
+/*
+ *   This program is free software; you can redistribute it and/or modify it
+ *   under the terms of the GNU General Public License version 2 as published
+ *   by the Free Software Foundation.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+ *
+ *   Copyright (C) 2011 John Crispin <blogic@openwrt.org>
+ */
+
+#ifndef LTQ_DMA_H__
+#define LTQ_DMA_H__
+
+#define LTQ_DESC_SIZE		0x08	/* each descriptor is 64bit */
+#define LTQ_DESC_NUM		0x40	/* 64 descriptors / channel */
+
+#define LTQ_DMA_OWN		BIT(31)	/* owner bit */
+#define LTQ_DMA_C		BIT(30) /* complete bit */
+#define LTQ_DMA_SOP		BIT(29) /* start of packet */
+#define LTQ_DMA_EOP		BIT(28) /* end of packet */
+#define LTQ_DMA_TX_OFFSET(x)	((x & 0x1f) << 23) /* data bytes offset */
+#define LTQ_DMA_RX_OFFSET(x)	((x & 0x7) << 23) /* data bytes offset */
+#define LTQ_DMA_SIZE_MASK	(0xffff) /* the size field is 16 bit */
+
+struct ltq_dma_desc {
+	u32 ctl;
+	u32 addr;
+};
+
+struct ltq_dma_channel {
+	int nr;				/* the channel number */
+	int irq;			/* the mapped irq */
+	int desc;			/* the current descriptor */
+	struct ltq_dma_desc *desc_base;	/* the descriptor base */
+	int phys;			/* physical addr */
+};
+
+enum {
+	DMA_PORT_ETOP = 0,
+	DMA_PORT_DEU,
+};
+
+extern void ltq_dma_enable_irq(struct ltq_dma_channel *ch);
+extern void ltq_dma_disable_irq(struct ltq_dma_channel *ch);
+extern void ltq_dma_ack_irq(struct ltq_dma_channel *ch);
+extern void ltq_dma_open(struct ltq_dma_channel *ch);
+extern void ltq_dma_close(struct ltq_dma_channel *ch);
+extern void ltq_dma_alloc_tx(struct ltq_dma_channel *ch);
+extern void ltq_dma_alloc_rx(struct ltq_dma_channel *ch);
+extern void ltq_dma_free(struct ltq_dma_channel *ch);
+extern void ltq_dma_init_port(int p);
+
+#endif
diff -druN linux-2.6.39-libre/arch/mips/include/asm/mach-netlogic/cpu-feature-overrides.h linux-3.0-rc7-libre/arch/mips/include/asm/mach-netlogic/cpu-feature-overrides.h
--- linux-2.6.39-libre/arch/mips/include/asm/mach-netlogic/cpu-feature-overrides.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/mips/include/asm/mach-netlogic/cpu-feature-overrides.h	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,47 @@
+/*
+ * 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) 2011 Netlogic Microsystems
+ * Copyright (C) 2003 Ralf Baechle
+ */
+#ifndef __ASM_MACH_NETLOGIC_CPU_FEATURE_OVERRIDES_H
+#define __ASM_MACH_NETLOGIC_CPU_FEATURE_OVERRIDES_H
+
+#define cpu_has_4kex		1
+#define cpu_has_4k_cache	1
+#define cpu_has_watch		1
+#define cpu_has_mips16		0
+#define cpu_has_counter		1
+#define cpu_has_divec		1
+#define cpu_has_vce		0
+#define cpu_has_cache_cdex_p	0
+#define cpu_has_cache_cdex_s	0
+#define cpu_has_prefetch	1
+#define cpu_has_mcheck		1
+#define cpu_has_ejtag		1
+
+#define cpu_has_llsc		1
+#define cpu_has_vtag_icache	0
+#define cpu_has_dc_aliases	0
+#define cpu_has_ic_fills_f_dc	0
+#define cpu_has_dsp		0
+#define cpu_has_mipsmt		0
+#define cpu_has_userlocal	0
+#define cpu_icache_snoops_remote_store	0
+
+#define cpu_has_nofpuex		0
+#define cpu_has_64bits		1
+
+#define cpu_has_mips32r1	1
+#define cpu_has_mips32r2	0
+#define cpu_has_mips64r1	1
+#define cpu_has_mips64r2	0
+
+#define cpu_has_inclusive_pcaches	0
+
+#define cpu_dcache_line_size()	32
+#define cpu_icache_line_size()	32
+
+#endif /* __ASM_MACH_NETLOGIC_CPU_FEATURE_OVERRIDES_H */
diff -druN linux-2.6.39-libre/arch/mips/include/asm/mach-netlogic/irq.h linux-3.0-rc7-libre/arch/mips/include/asm/mach-netlogic/irq.h
--- linux-2.6.39-libre/arch/mips/include/asm/mach-netlogic/irq.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/mips/include/asm/mach-netlogic/irq.h	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,14 @@
+/*
+ * 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) 2011 Netlogic Microsystems.
+ */
+#ifndef __ASM_NETLOGIC_IRQ_H
+#define __ASM_NETLOGIC_IRQ_H
+
+#define NR_IRQS			64
+#define MIPS_CPU_IRQ_BASE	0
+
+#endif /* __ASM_NETLOGIC_IRQ_H */
diff -druN linux-2.6.39-libre/arch/mips/include/asm/mach-netlogic/war.h linux-3.0-rc7-libre/arch/mips/include/asm/mach-netlogic/war.h
--- linux-2.6.39-libre/arch/mips/include/asm/mach-netlogic/war.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/mips/include/asm/mach-netlogic/war.h	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,26 @@
+/*
+ * 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) 2011 Netlogic Microsystems.
+ * Copyright (C) 2002, 2004, 2007 by Ralf Baechle <ralf@linux-mips.org>
+ */
+#ifndef __ASM_MIPS_MACH_NLM_WAR_H
+#define __ASM_MIPS_MACH_NLM_WAR_H
+
+#define R4600_V1_INDEX_ICACHEOP_WAR	0
+#define R4600_V1_HIT_CACHEOP_WAR	0
+#define R4600_V2_HIT_CACHEOP_WAR	0
+#define R5432_CP0_INTERRUPT_WAR		0
+#define BCM1250_M3_WAR			0
+#define SIBYTE_1956_WAR			0
+#define MIPS4K_ICACHE_REFILL_WAR	0
+#define MIPS_CACHE_SYNC_WAR		0
+#define TX49XX_ICACHE_INDEX_INV_WAR	0
+#define RM9000_CDEX_SMP_WAR		0
+#define ICACHE_REFILLS_WORKAROUND_WAR	0
+#define R10000_LLSC_WAR			0
+#define MIPS34K_MISSED_ITLB_WAR		0
+
+#endif /* __ASM_MIPS_MACH_NLM_WAR_H */
diff -druN linux-2.6.39-libre/arch/mips/include/asm/module.h linux-3.0-rc7-libre/arch/mips/include/asm/module.h
--- linux-2.6.39-libre/arch/mips/include/asm/module.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/mips/include/asm/module.h	2011-07-11 19:51:52.000000000 -0400
@@ -118,6 +118,8 @@
 #define MODULE_PROC_FAMILY "LOONGSON2 "
 #elif defined CONFIG_CPU_CAVIUM_OCTEON
 #define MODULE_PROC_FAMILY "OCTEON "
+#elif defined CONFIG_CPU_XLR
+#define MODULE_PROC_FAMILY "XLR "
 #else
 #error MODULE_PROC_FAMILY undefined for your processor configuration
 #endif
diff -druN linux-2.6.39-libre/arch/mips/include/asm/netlogic/interrupt.h linux-3.0-rc7-libre/arch/mips/include/asm/netlogic/interrupt.h
--- linux-2.6.39-libre/arch/mips/include/asm/netlogic/interrupt.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/mips/include/asm/netlogic/interrupt.h	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2003-2011 NetLogic Microsystems, Inc. (NetLogic). 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 NetLogic
+ * license below:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NETLOGIC ``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 NETLOGIC OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _ASM_NLM_INTERRUPT_H
+#define _ASM_NLM_INTERRUPT_H
+
+/* Defines for the IRQ numbers */
+
+#define IRQ_IPI_SMP_FUNCTION	3
+#define IRQ_IPI_SMP_RESCHEDULE	4
+#define IRQ_MSGRING		6
+#define IRQ_TIMER		7
+
+#endif
diff -druN linux-2.6.39-libre/arch/mips/include/asm/netlogic/mips-extns.h linux-3.0-rc7-libre/arch/mips/include/asm/netlogic/mips-extns.h
--- linux-2.6.39-libre/arch/mips/include/asm/netlogic/mips-extns.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/mips/include/asm/netlogic/mips-extns.h	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,76 @@
+/*
+ * Copyright 2003-2011 NetLogic Microsystems, Inc. (NetLogic). 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 NetLogic
+ * license below:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NETLOGIC ``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 NETLOGIC OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _ASM_NLM_MIPS_EXTS_H
+#define _ASM_NLM_MIPS_EXTS_H
+
+/*
+ * XLR and XLP interrupt request and interrupt mask registers
+ */
+#define read_c0_eirr()		__read_64bit_c0_register($9, 6)
+#define read_c0_eimr()		__read_64bit_c0_register($9, 7)
+#define write_c0_eirr(val)	__write_64bit_c0_register($9, 6, val)
+
+/*
+ * Writing EIMR in 32 bit is a special case, the lower 8 bit of the
+ * EIMR is shadowed in the status register, so we cannot save and
+ * restore status register for split read.
+ */
+#define write_c0_eimr(val)						\
+do {									\
+	if (sizeof(unsigned long) == 4)	{				\
+		unsigned long __flags;					\
+									\
+		local_irq_save(__flags);				\
+		__asm__ __volatile__(					\
+			".set\tmips64\n\t"				\
+			"dsll\t%L0, %L0, 32\n\t"			\
+			"dsrl\t%L0, %L0, 32\n\t"			\
+			"dsll\t%M0, %M0, 32\n\t"			\
+			"or\t%L0, %L0, %M0\n\t"				\
+			"dmtc0\t%L0, $9, 7\n\t"				\
+			".set\tmips0"					\
+			: : "r" (val));					\
+		__flags = (__flags & 0xffff00ff) | (((val) & 0xff) << 8);\
+		local_irq_restore(__flags);				\
+	} else								\
+		__write_64bit_c0_register($9, 7, (val));		\
+} while (0)
+
+static inline int hard_smp_processor_id(void)
+{
+	return __read_32bit_c0_register($15, 1) & 0x3ff;
+}
+
+#endif /*_ASM_NLM_MIPS_EXTS_H */
diff -druN linux-2.6.39-libre/arch/mips/include/asm/netlogic/psb-bootinfo.h linux-3.0-rc7-libre/arch/mips/include/asm/netlogic/psb-bootinfo.h
--- linux-2.6.39-libre/arch/mips/include/asm/netlogic/psb-bootinfo.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/mips/include/asm/netlogic/psb-bootinfo.h	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,109 @@
+/*
+ * Copyright 2003-2011 NetLogic Microsystems, Inc. (NetLogic). 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 NetLogic
+ * license below:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NETLOGIC ``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 NETLOGIC OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _ASM_NETLOGIC_BOOTINFO_H
+#define _ASM_NETLOGIC_BOOTINFO_H
+
+struct psb_info {
+	uint64_t boot_level;
+	uint64_t io_base;
+	uint64_t output_device;
+	uint64_t uart_print;
+	uint64_t led_output;
+	uint64_t init;
+	uint64_t exit;
+	uint64_t warm_reset;
+	uint64_t wakeup;
+	uint64_t online_cpu_map;
+	uint64_t master_reentry_sp;
+	uint64_t master_reentry_gp;
+	uint64_t master_reentry_fn;
+	uint64_t slave_reentry_fn;
+	uint64_t magic_dword;
+	uint64_t uart_putchar;
+	uint64_t size;
+	uint64_t uart_getchar;
+	uint64_t nmi_handler;
+	uint64_t psb_version;
+	uint64_t mac_addr;
+	uint64_t cpu_frequency;
+	uint64_t board_version;
+	uint64_t malloc;
+	uint64_t free;
+	uint64_t global_shmem_addr;
+	uint64_t global_shmem_size;
+	uint64_t psb_os_cpu_map;
+	uint64_t userapp_cpu_map;
+	uint64_t wakeup_os;
+	uint64_t psb_mem_map;
+	uint64_t board_major_version;
+	uint64_t board_minor_version;
+	uint64_t board_manf_revision;
+	uint64_t board_serial_number;
+	uint64_t psb_physaddr_map;
+	uint64_t xlr_loaderip_config;
+	uint64_t bldr_envp;
+	uint64_t avail_mem_map;
+};
+
+enum {
+	NETLOGIC_IO_SPACE = 0x10,
+	PCIX_IO_SPACE,
+	PCIX_CFG_SPACE,
+	PCIX_MEMORY_SPACE,
+	HT_IO_SPACE,
+	HT_CFG_SPACE,
+	HT_MEMORY_SPACE,
+	SRAM_SPACE,
+	FLASH_CONTROLLER_SPACE
+};
+
+#define NLM_MAX_ARGS	64
+#define NLM_MAX_ENVS	32
+
+/* This is what netlboot passes and linux boot_mem_map is subtly different */
+#define NLM_BOOT_MEM_MAP_MAX	32
+struct nlm_boot_mem_map {
+	int nr_map;
+	struct nlm_boot_mem_map_entry {
+		uint64_t addr;		/* start of memory segment */
+		uint64_t size;		/* size of memory segment */
+		uint32_t type;		/* type of memory segment */
+	} map[NLM_BOOT_MEM_MAP_MAX];
+};
+
+/* Pointer to saved boot loader info */
+extern struct psb_info nlm_prom_info;
+
+#endif
diff -druN linux-2.6.39-libre/arch/mips/include/asm/netlogic/xlr/gpio.h linux-3.0-rc7-libre/arch/mips/include/asm/netlogic/xlr/gpio.h
--- linux-2.6.39-libre/arch/mips/include/asm/netlogic/xlr/gpio.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/mips/include/asm/netlogic/xlr/gpio.h	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,73 @@
+/*
+ * Copyright 2003-2011 NetLogic Microsystems, Inc. (NetLogic). 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 NetLogic
+ * license below:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NETLOGIC ``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 NETLOGIC OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _ASM_NLM_GPIO_H
+#define _ASM_NLM_GPIO_H
+
+#define NETLOGIC_GPIO_INT_EN_REG		0
+#define NETLOGIC_GPIO_INPUT_INVERSION_REG	1
+#define NETLOGIC_GPIO_IO_DIR_REG		2
+#define NETLOGIC_GPIO_IO_DATA_WR_REG		3
+#define NETLOGIC_GPIO_IO_DATA_RD_REG		4
+
+#define NETLOGIC_GPIO_SWRESET_REG		8
+#define NETLOGIC_GPIO_DRAM1_CNTRL_REG		9
+#define NETLOGIC_GPIO_DRAM1_RATIO_REG		10
+#define NETLOGIC_GPIO_DRAM1_RESET_REG		11
+#define NETLOGIC_GPIO_DRAM1_STATUS_REG		12
+#define NETLOGIC_GPIO_DRAM2_CNTRL_REG		13
+#define NETLOGIC_GPIO_DRAM2_RATIO_REG		14
+#define NETLOGIC_GPIO_DRAM2_RESET_REG		15
+#define NETLOGIC_GPIO_DRAM2_STATUS_REG		16
+
+#define NETLOGIC_GPIO_PWRON_RESET_CFG_REG	21
+#define NETLOGIC_GPIO_BIST_ALL_GO_STATUS_REG	24
+#define NETLOGIC_GPIO_BIST_CPU_GO_STATUS_REG	25
+#define NETLOGIC_GPIO_BIST_DEV_GO_STATUS_REG	26
+
+#define NETLOGIC_GPIO_FUSE_BANK_REG		35
+#define NETLOGIC_GPIO_CPU_RESET_REG		40
+#define NETLOGIC_GPIO_RNG_REG			43
+
+#define NETLOGIC_PWRON_RESET_PCMCIA_BOOT	17
+#define NETLOGIC_GPIO_LED_BITMAP	0x1700000
+#define NETLOGIC_GPIO_LED_0_SHIFT		20
+#define NETLOGIC_GPIO_LED_1_SHIFT		24
+
+#define NETLOGIC_GPIO_LED_OUTPUT_CODE_RESET	0x01
+#define NETLOGIC_GPIO_LED_OUTPUT_CODE_HARD_RESET 0x02
+#define NETLOGIC_GPIO_LED_OUTPUT_CODE_SOFT_RESET 0x03
+#define NETLOGIC_GPIO_LED_OUTPUT_CODE_MAIN	0x04
+
+#endif
diff -druN linux-2.6.39-libre/arch/mips/include/asm/netlogic/xlr/iomap.h linux-3.0-rc7-libre/arch/mips/include/asm/netlogic/xlr/iomap.h
--- linux-2.6.39-libre/arch/mips/include/asm/netlogic/xlr/iomap.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/mips/include/asm/netlogic/xlr/iomap.h	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,131 @@
+/*
+ * Copyright 2003-2011 NetLogic Microsystems, Inc. (NetLogic). 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 NetLogic
+ * license below:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NETLOGIC ``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 NETLOGIC OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _ASM_NLM_IOMAP_H
+#define _ASM_NLM_IOMAP_H
+
+#define DEFAULT_NETLOGIC_IO_BASE           CKSEG1ADDR(0x1ef00000)
+#define NETLOGIC_IO_DDR2_CHN0_OFFSET       0x01000
+#define NETLOGIC_IO_DDR2_CHN1_OFFSET       0x02000
+#define NETLOGIC_IO_DDR2_CHN2_OFFSET       0x03000
+#define NETLOGIC_IO_DDR2_CHN3_OFFSET       0x04000
+#define NETLOGIC_IO_PIC_OFFSET             0x08000
+#define NETLOGIC_IO_UART_0_OFFSET          0x14000
+#define NETLOGIC_IO_UART_1_OFFSET          0x15100
+
+#define NETLOGIC_IO_SIZE                   0x1000
+
+#define NETLOGIC_IO_BRIDGE_OFFSET          0x00000
+
+#define NETLOGIC_IO_RLD2_CHN0_OFFSET       0x05000
+#define NETLOGIC_IO_RLD2_CHN1_OFFSET       0x06000
+
+#define NETLOGIC_IO_SRAM_OFFSET            0x07000
+
+#define NETLOGIC_IO_PCIX_OFFSET            0x09000
+#define NETLOGIC_IO_HT_OFFSET              0x0A000
+
+#define NETLOGIC_IO_SECURITY_OFFSET        0x0B000
+
+#define NETLOGIC_IO_GMAC_0_OFFSET          0x0C000
+#define NETLOGIC_IO_GMAC_1_OFFSET          0x0D000
+#define NETLOGIC_IO_GMAC_2_OFFSET          0x0E000
+#define NETLOGIC_IO_GMAC_3_OFFSET          0x0F000
+
+/* XLS devices */
+#define NETLOGIC_IO_GMAC_4_OFFSET          0x20000
+#define NETLOGIC_IO_GMAC_5_OFFSET          0x21000
+#define NETLOGIC_IO_GMAC_6_OFFSET          0x22000
+#define NETLOGIC_IO_GMAC_7_OFFSET          0x23000
+
+#define NETLOGIC_IO_PCIE_0_OFFSET          0x1E000
+#define NETLOGIC_IO_PCIE_1_OFFSET          0x1F000
+#define NETLOGIC_IO_SRIO_0_OFFSET          0x1E000
+#define NETLOGIC_IO_SRIO_1_OFFSET          0x1F000
+
+#define NETLOGIC_IO_USB_0_OFFSET           0x24000
+#define NETLOGIC_IO_USB_1_OFFSET           0x25000
+
+#define NETLOGIC_IO_COMP_OFFSET            0x1D000
+/* end XLS devices */
+
+/* XLR devices */
+#define NETLOGIC_IO_SPI4_0_OFFSET          0x10000
+#define NETLOGIC_IO_XGMAC_0_OFFSET         0x11000
+#define NETLOGIC_IO_SPI4_1_OFFSET          0x12000
+#define NETLOGIC_IO_XGMAC_1_OFFSET         0x13000
+/* end XLR devices */
+
+#define NETLOGIC_IO_I2C_0_OFFSET           0x16000
+#define NETLOGIC_IO_I2C_1_OFFSET           0x17000
+
+#define NETLOGIC_IO_GPIO_OFFSET            0x18000
+#define NETLOGIC_IO_FLASH_OFFSET           0x19000
+#define NETLOGIC_IO_TB_OFFSET              0x1C000
+
+#define NETLOGIC_CPLD_OFFSET               KSEG1ADDR(0x1d840000)
+
+/*
+ * Base Address (Virtual) of the PCI Config address space
+ * For now, choose 256M phys in kseg1 = 0xA0000000 + (1<<28)
+ * Config space spans 256 (num of buses) * 256 (num functions) * 256 bytes
+ * ie 1<<24 = 16M
+ */
+#define DEFAULT_PCI_CONFIG_BASE         0x18000000
+#define DEFAULT_HT_TYPE0_CFG_BASE       0x16000000
+#define DEFAULT_HT_TYPE1_CFG_BASE       0x17000000
+
+#ifndef __ASSEMBLY__
+#include <linux/types.h>
+#include <asm/byteorder.h>
+
+typedef volatile __u32 nlm_reg_t;
+extern unsigned long netlogic_io_base;
+
+/* FIXME read once in write_reg */
+#ifdef CONFIG_CPU_LITTLE_ENDIAN
+#define netlogic_read_reg(base, offset)		((base)[(offset)])
+#define netlogic_write_reg(base, offset, value)	((base)[(offset)] = (value))
+#else
+#define netlogic_read_reg(base, offset)		(be32_to_cpu((base)[(offset)]))
+#define netlogic_write_reg(base, offset, value) \
+				((base)[(offset)] = cpu_to_be32((value)))
+#endif
+
+#define netlogic_read_reg_le32(base, offset) (le32_to_cpu((base)[(offset)]))
+#define netlogic_write_reg_le32(base, offset, value) \
+				((base)[(offset)] = cpu_to_le32((value)))
+#define netlogic_io_mmio(offset) ((nlm_reg_t *)(netlogic_io_base+(offset)))
+#endif /* __ASSEMBLY__ */
+#endif
diff -druN linux-2.6.39-libre/arch/mips/include/asm/netlogic/xlr/pic.h linux-3.0-rc7-libre/arch/mips/include/asm/netlogic/xlr/pic.h
--- linux-2.6.39-libre/arch/mips/include/asm/netlogic/xlr/pic.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/mips/include/asm/netlogic/xlr/pic.h	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,231 @@
+/*
+ * Copyright 2003-2011 NetLogic Microsystems, Inc. (NetLogic). 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 NetLogic
+ * license below:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NETLOGIC ``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 NETLOGIC OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _ASM_NLM_XLR_PIC_H
+#define _ASM_NLM_XLR_PIC_H
+
+#define PIC_CLKS_PER_SEC		66666666ULL
+/* PIC hardware interrupt numbers */
+#define PIC_IRT_WD_INDEX		0
+#define PIC_IRT_TIMER_0_INDEX		1
+#define PIC_IRT_TIMER_1_INDEX		2
+#define PIC_IRT_TIMER_2_INDEX		3
+#define PIC_IRT_TIMER_3_INDEX		4
+#define PIC_IRT_TIMER_4_INDEX		5
+#define PIC_IRT_TIMER_5_INDEX		6
+#define PIC_IRT_TIMER_6_INDEX		7
+#define PIC_IRT_TIMER_7_INDEX		8
+#define PIC_IRT_CLOCK_INDEX		PIC_IRT_TIMER_7_INDEX
+#define PIC_IRT_UART_0_INDEX		9
+#define PIC_IRT_UART_1_INDEX		10
+#define PIC_IRT_I2C_0_INDEX		11
+#define PIC_IRT_I2C_1_INDEX		12
+#define PIC_IRT_PCMCIA_INDEX		13
+#define PIC_IRT_GPIO_INDEX		14
+#define PIC_IRT_HYPER_INDEX		15
+#define PIC_IRT_PCIX_INDEX		16
+/* XLS */
+#define PIC_IRT_CDE_INDEX		15
+#define PIC_IRT_BRIDGE_TB_XLS_INDEX	16
+/* XLS */
+#define PIC_IRT_GMAC0_INDEX		17
+#define PIC_IRT_GMAC1_INDEX		18
+#define PIC_IRT_GMAC2_INDEX		19
+#define PIC_IRT_GMAC3_INDEX		20
+#define PIC_IRT_XGS0_INDEX		21
+#define PIC_IRT_XGS1_INDEX		22
+#define PIC_IRT_HYPER_FATAL_INDEX	23
+#define PIC_IRT_PCIX_FATAL_INDEX	24
+#define PIC_IRT_BRIDGE_AERR_INDEX	25
+#define PIC_IRT_BRIDGE_BERR_INDEX	26
+#define PIC_IRT_BRIDGE_TB_XLR_INDEX	27
+#define PIC_IRT_BRIDGE_AERR_NMI_INDEX	28
+/* XLS */
+#define PIC_IRT_GMAC4_INDEX		21
+#define PIC_IRT_GMAC5_INDEX		22
+#define PIC_IRT_GMAC6_INDEX		23
+#define PIC_IRT_GMAC7_INDEX		24
+#define PIC_IRT_BRIDGE_ERR_INDEX	25
+#define PIC_IRT_PCIE_LINK0_INDEX	26
+#define PIC_IRT_PCIE_LINK1_INDEX	27
+#define PIC_IRT_PCIE_LINK2_INDEX	23
+#define PIC_IRT_PCIE_LINK3_INDEX	24
+#define PIC_IRT_PCIE_XLSB0_LINK2_INDEX	28
+#define PIC_IRT_PCIE_XLSB0_LINK3_INDEX	29
+#define PIC_IRT_SRIO_LINK0_INDEX	26
+#define PIC_IRT_SRIO_LINK1_INDEX	27
+#define PIC_IRT_SRIO_LINK2_INDEX	28
+#define PIC_IRT_SRIO_LINK3_INDEX	29
+#define PIC_IRT_PCIE_INT_INDEX		28
+#define PIC_IRT_PCIE_FATAL_INDEX	29
+#define PIC_IRT_GPIO_B_INDEX		30
+#define PIC_IRT_USB_INDEX		31
+/* XLS */
+#define PIC_NUM_IRTS			32
+
+
+#define PIC_CLOCK_TIMER			7
+
+/* PIC Registers */
+#define PIC_CTRL			0x00
+#define PIC_IPI				0x04
+#define PIC_INT_ACK			0x06
+
+#define WD_MAX_VAL_0			0x08
+#define WD_MAX_VAL_1			0x09
+#define WD_MASK_0			0x0a
+#define WD_MASK_1			0x0b
+#define WD_HEARBEAT_0			0x0c
+#define WD_HEARBEAT_1			0x0d
+
+#define PIC_IRT_0_BASE			0x40
+#define PIC_IRT_1_BASE			0x80
+#define PIC_TIMER_MAXVAL_0_BASE		0x100
+#define PIC_TIMER_MAXVAL_1_BASE		0x110
+#define PIC_TIMER_COUNT_0_BASE		0x120
+#define PIC_TIMER_COUNT_1_BASE		0x130
+
+#define PIC_IRT_0(picintr)      (PIC_IRT_0_BASE + (picintr))
+#define PIC_IRT_1(picintr)	(PIC_IRT_1_BASE + (picintr))
+
+#define PIC_TIMER_MAXVAL_0(i)	(PIC_TIMER_MAXVAL_0_BASE + (i))
+#define PIC_TIMER_MAXVAL_1(i)	(PIC_TIMER_MAXVAL_1_BASE + (i))
+#define PIC_TIMER_COUNT_0(i)	(PIC_TIMER_COUNT_0_BASE + (i))
+#define PIC_TIMER_COUNT_1(i)	(PIC_TIMER_COUNT_0_BASE + (i))
+
+/*
+ * Mapping between hardware interrupt numbers and IRQs on CPU
+ * we use a simple scheme to map PIC interrupts 0-31 to IRQs
+ * 8-39. This leaves the IRQ 0-7 for cpu interrupts like
+ * count/compare and FMN
+ */
+#define PIC_IRQ_BASE            8
+#define PIC_INTR_TO_IRQ(i)      (PIC_IRQ_BASE + (i))
+#define PIC_IRQ_TO_INTR(i)      ((i) - PIC_IRQ_BASE)
+
+#define PIC_IRT_FIRST_IRQ	PIC_IRQ_BASE
+#define PIC_WD_IRQ		PIC_INTR_TO_IRQ(PIC_IRT_WD_INDEX)
+#define PIC_TIMER_0_IRQ		PIC_INTR_TO_IRQ(PIC_IRT_TIMER_0_INDEX)
+#define PIC_TIMER_1_IRQ		PIC_INTR_TO_IRQ(PIC_IRT_TIMER_1_INDEX)
+#define PIC_TIMER_2_IRQ		PIC_INTR_TO_IRQ(PIC_IRT_TIMER_2_INDEX)
+#define PIC_TIMER_3_IRQ		PIC_INTR_TO_IRQ(PIC_IRT_TIMER_3_INDEX)
+#define PIC_TIMER_4_IRQ		PIC_INTR_TO_IRQ(PIC_IRT_TIMER_4_INDEX)
+#define PIC_TIMER_5_IRQ		PIC_INTR_TO_IRQ(PIC_IRT_TIMER_5_INDEX)
+#define PIC_TIMER_6_IRQ		PIC_INTR_TO_IRQ(PIC_IRT_TIMER_6_INDEX)
+#define PIC_TIMER_7_IRQ		PIC_INTR_TO_IRQ(PIC_IRT_TIMER_7_INDEX)
+#define PIC_CLOCK_IRQ		(PIC_TIMER_7_IRQ)
+#define PIC_UART_0_IRQ		PIC_INTR_TO_IRQ(PIC_IRT_UART_0_INDEX)
+#define PIC_UART_1_IRQ		PIC_INTR_TO_IRQ(PIC_IRT_UART_1_INDEX)
+#define PIC_I2C_0_IRQ		PIC_INTR_TO_IRQ(PIC_IRT_I2C_0_INDEX)
+#define PIC_I2C_1_IRQ		PIC_INTR_TO_IRQ(PIC_IRT_I2C_1_INDEX)
+#define PIC_PCMCIA_IRQ		PIC_INTR_TO_IRQ(PIC_IRT_PCMCIA_INDEX)
+#define PIC_GPIO_IRQ		PIC_INTR_TO_IRQ(PIC_IRT_GPIO_INDEX)
+#define PIC_HYPER_IRQ		PIC_INTR_TO_IRQ(PIC_IRT_HYPER_INDEX)
+#define PIC_PCIX_IRQ		PIC_INTR_TO_IRQ(PIC_IRT_PCIX_INDEX)
+/* XLS */
+#define PIC_CDE_IRQ		PIC_INTR_TO_IRQ(PIC_IRT_CDE_INDEX)
+#define PIC_BRIDGE_TB_XLS_IRQ	PIC_INTR_TO_IRQ(PIC_IRT_BRIDGE_TB_XLS_INDEX)
+/* end XLS */
+#define PIC_GMAC_0_IRQ		PIC_INTR_TO_IRQ(PIC_IRT_GMAC0_INDEX)
+#define PIC_GMAC_1_IRQ		PIC_INTR_TO_IRQ(PIC_IRT_GMAC1_INDEX)
+#define PIC_GMAC_2_IRQ		PIC_INTR_TO_IRQ(PIC_IRT_GMAC2_INDEX)
+#define PIC_GMAC_3_IRQ		PIC_INTR_TO_IRQ(PIC_IRT_GMAC3_INDEX)
+#define PIC_XGS_0_IRQ		PIC_INTR_TO_IRQ(PIC_IRT_XGS0_INDEX)
+#define PIC_XGS_1_IRQ		PIC_INTR_TO_IRQ(PIC_IRT_XGS1_INDEX)
+#define PIC_HYPER_FATAL_IRQ	PIC_INTR_TO_IRQ(PIC_IRT_HYPER_FATAL_INDEX)
+#define PIC_PCIX_FATAL_IRQ	PIC_INTR_TO_IRQ(PIC_IRT_PCIX_FATAL_INDEX)
+#define PIC_BRIDGE_AERR_IRQ	PIC_INTR_TO_IRQ(PIC_IRT_BRIDGE_AERR_INDEX)
+#define PIC_BRIDGE_BERR_IRQ	PIC_INTR_TO_IRQ(PIC_IRT_BRIDGE_BERR_INDEX)
+#define PIC_BRIDGE_TB_XLR_IRQ	PIC_INTR_TO_IRQ(PIC_IRT_BRIDGE_TB_XLR_INDEX)
+#define PIC_BRIDGE_AERR_NMI_IRQ	PIC_INTR_TO_IRQ(PIC_IRT_BRIDGE_AERR_NMI_INDEX)
+/* XLS defines */
+#define PIC_GMAC_4_IRQ		PIC_INTR_TO_IRQ(PIC_IRT_GMAC4_INDEX)
+#define PIC_GMAC_5_IRQ		PIC_INTR_TO_IRQ(PIC_IRT_GMAC5_INDEX)
+#define PIC_GMAC_6_IRQ		PIC_INTR_TO_IRQ(PIC_IRT_GMAC6_INDEX)
+#define PIC_GMAC_7_IRQ		PIC_INTR_TO_IRQ(PIC_IRT_GMAC7_INDEX)
+#define PIC_BRIDGE_ERR_IRQ	PIC_INTR_TO_IRQ(PIC_IRT_BRIDGE_ERR_INDEX)
+#define PIC_PCIE_LINK0_IRQ	PIC_INTR_TO_IRQ(PIC_IRT_PCIE_LINK0_INDEX)
+#define PIC_PCIE_LINK1_IRQ	PIC_INTR_TO_IRQ(PIC_IRT_PCIE_LINK1_INDEX)
+#define PIC_PCIE_LINK2_IRQ	PIC_INTR_TO_IRQ(PIC_IRT_PCIE_LINK2_INDEX)
+#define PIC_PCIE_LINK3_IRQ	PIC_INTR_TO_IRQ(PIC_IRT_PCIE_LINK3_INDEX)
+#define PIC_PCIE_XLSB0_LINK2_IRQ PIC_INTR_TO_IRQ(PIC_IRT_PCIE_XLSB0_LINK2_INDEX)
+#define PIC_PCIE_XLSB0_LINK3_IRQ PIC_INTR_TO_IRQ(PIC_IRT_PCIE_XLSB0_LINK3_INDEX)
+#define PIC_SRIO_LINK0_IRQ	PIC_INTR_TO_IRQ(PIC_IRT_SRIO_LINK0_INDEX)
+#define PIC_SRIO_LINK1_IRQ	PIC_INTR_TO_IRQ(PIC_IRT_SRIO_LINK1_INDEX)
+#define PIC_SRIO_LINK2_IRQ	PIC_INTR_TO_IRQ(PIC_IRT_SRIO_LINK2_INDEX)
+#define PIC_SRIO_LINK3_IRQ	PIC_INTR_TO_IRQ(PIC_IRT_SRIO_LINK3_INDEX)
+#define PIC_PCIE_INT_IRQ	PIC_INTR_TO_IRQ(PIC_IRT_PCIE_INT__INDEX)
+#define PIC_PCIE_FATAL_IRQ	PIC_INTR_TO_IRQ(PIC_IRT_PCIE_FATAL_INDEX)
+#define PIC_GPIO_B_IRQ		PIC_INTR_TO_IRQ(PIC_IRT_GPIO_B_INDEX)
+#define PIC_USB_IRQ		PIC_INTR_TO_IRQ(PIC_IRT_USB_INDEX)
+#define PIC_IRT_LAST_IRQ	PIC_USB_IRQ
+/* end XLS */
+
+#ifndef __ASSEMBLY__
+static inline void pic_send_ipi(u32 ipi)
+{
+	nlm_reg_t *mmio = netlogic_io_mmio(NETLOGIC_IO_PIC_OFFSET);
+
+	netlogic_write_reg(mmio, PIC_IPI, ipi);
+}
+
+static inline u32 pic_read_control(void)
+{
+	nlm_reg_t *mmio = netlogic_io_mmio(NETLOGIC_IO_PIC_OFFSET);
+
+	return netlogic_read_reg(mmio, PIC_CTRL);
+}
+
+static inline void pic_write_control(u32 control)
+{
+	nlm_reg_t *mmio = netlogic_io_mmio(NETLOGIC_IO_PIC_OFFSET);
+
+	netlogic_write_reg(mmio, PIC_CTRL, control);
+}
+
+static inline void pic_update_control(u32 control)
+{
+	nlm_reg_t *mmio = netlogic_io_mmio(NETLOGIC_IO_PIC_OFFSET);
+
+	netlogic_write_reg(mmio, PIC_CTRL,
+		(control | netlogic_read_reg(mmio, PIC_CTRL)));
+}
+
+#define PIC_IRQ_IS_EDGE_TRIGGERED(irq)	(((irq) >= PIC_TIMER_0_IRQ) && \
+					((irq) <= PIC_TIMER_7_IRQ))
+#define PIC_IRQ_IS_IRT(irq)		(((irq) >= PIC_IRT_FIRST_IRQ) && \
+					((irq) <= PIC_IRT_LAST_IRQ))
+#endif
+
+#endif /* _ASM_NLM_XLR_PIC_H */
diff -druN linux-2.6.39-libre/arch/mips/include/asm/netlogic/xlr/xlr.h linux-3.0-rc7-libre/arch/mips/include/asm/netlogic/xlr/xlr.h
--- linux-2.6.39-libre/arch/mips/include/asm/netlogic/xlr/xlr.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/mips/include/asm/netlogic/xlr/xlr.h	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2003-2011 NetLogic Microsystems, Inc. (NetLogic). 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 NetLogic
+ * license below:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NETLOGIC ``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 NETLOGIC OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _ASM_NLM_XLR_H
+#define _ASM_NLM_XLR_H
+
+/* Platform UART functions */
+struct uart_port;
+unsigned int nlm_xlr_uart_in(struct uart_port *, int);
+void nlm_xlr_uart_out(struct uart_port *, int, int);
+
+/* SMP support functions */
+struct irq_desc;
+void nlm_smp_function_ipi_handler(unsigned int irq, struct irq_desc *desc);
+void nlm_smp_resched_ipi_handler(unsigned int irq, struct irq_desc *desc);
+int nlm_wakeup_secondary_cpus(u32 wakeup_mask);
+void nlm_smp_irq_init(void);
+void nlm_boot_smp_nmi(void);
+void prom_pre_boot_secondary_cpus(void);
+
+extern struct plat_smp_ops nlm_smp_ops;
+extern unsigned long nlm_common_ebase;
+
+/* XLS B silicon "Rook" */
+static inline unsigned int nlm_chip_is_xls_b(void)
+{
+	uint32_t prid = read_c0_prid();
+
+	return ((prid & 0xf000) == 0x4000);
+}
+
+/*
+ *  XLR chip types
+ */
+ /* The XLS product line has chip versions 0x[48c]? */
+static inline unsigned int nlm_chip_is_xls(void)
+{
+	uint32_t prid = read_c0_prid();
+
+	return ((prid & 0xf000) == 0x8000 || (prid & 0xf000) == 0x4000 ||
+		(prid & 0xf000) == 0xc000);
+}
+
+#endif /* _ASM_NLM_XLR_H */
diff -druN linux-2.6.39-libre/arch/mips/include/asm/prom.h linux-3.0-rc7-libre/arch/mips/include/asm/prom.h
--- linux-2.6.39-libre/arch/mips/include/asm/prom.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/mips/include/asm/prom.h	2011-07-11 19:51:52.000000000 -0400
@@ -14,9 +14,6 @@
 #ifdef CONFIG_OF
 #include <asm/bootinfo.h>
 
-/* which is compatible with the flattened device tree (FDT) */
-#define cmd_line arcs_cmdline
-
 extern int early_init_dt_scan_memory_arch(unsigned long node,
 	const char *uname, int depth, void *data);
 
diff -druN linux-2.6.39-libre/arch/mips/include/asm/ptrace.h linux-3.0-rc7-libre/arch/mips/include/asm/ptrace.h
--- linux-2.6.39-libre/arch/mips/include/asm/ptrace.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/mips/include/asm/ptrace.h	2011-07-11 19:51:52.000000000 -0400
@@ -141,7 +141,8 @@
 #define instruction_pointer(regs) ((regs)->cp0_epc)
 #define profile_pc(regs) instruction_pointer(regs)
 
-extern asmlinkage void do_syscall_trace(struct pt_regs *regs, int entryexit);
+extern asmlinkage void syscall_trace_enter(struct pt_regs *regs);
+extern asmlinkage void syscall_trace_leave(struct pt_regs *regs);
 
 extern NORET_TYPE void die(const char *, struct pt_regs *) ATTRIB_NORET;
 
diff -druN linux-2.6.39-libre/arch/mips/include/asm/r4kcache.h linux-3.0-rc7-libre/arch/mips/include/asm/r4kcache.h
--- linux-2.6.39-libre/arch/mips/include/asm/r4kcache.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/mips/include/asm/r4kcache.h	2011-07-11 19:51:52.000000000 -0400
@@ -5,7 +5,7 @@
  *
  * Inline assembly cache operations.
  *
- * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
+ * Copyright (C) 1996 David S. Miller (davem@davemloft.net)
  * Copyright (C) 1997 - 2002 Ralf Baechle (ralf@gnu.org)
  * Copyright (C) 2004 Ralf Baechle (ralf@linux-mips.org)
  */
diff -druN linux-2.6.39-libre/arch/mips/include/asm/sgialib.h linux-3.0-rc7-libre/arch/mips/include/asm/sgialib.h
--- linux-2.6.39-libre/arch/mips/include/asm/sgialib.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/mips/include/asm/sgialib.h	2011-07-11 19:51:52.000000000 -0400
@@ -5,7 +5,7 @@
  *
  * SGI ARCS firmware interface library for the Linux kernel.
  *
- * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
+ * Copyright (C) 1996 David S. Miller (davem@davemloft.net)
  * Copyright (C) 2001, 2002 Ralf Baechle (ralf@gnu.org)
  */
 #ifndef _ASM_SGIALIB_H
diff -druN linux-2.6.39-libre/arch/mips/include/asm/sgiarcs.h linux-3.0-rc7-libre/arch/mips/include/asm/sgiarcs.h
--- linux-2.6.39-libre/arch/mips/include/asm/sgiarcs.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/mips/include/asm/sgiarcs.h	2011-07-11 19:51:52.000000000 -0400
@@ -5,7 +5,7 @@
  *
  * ARC firmware interface defines.
  *
- * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
+ * Copyright (C) 1996 David S. Miller (davem@davemloft.net)
  * Copyright (C) 1999, 2001 Ralf Baechle (ralf@gnu.org)
  * Copyright (C) 1999 Silicon Graphics, Inc.
  */
diff -druN linux-2.6.39-libre/arch/mips/include/asm/suspend.h linux-3.0-rc7-libre/arch/mips/include/asm/suspend.h
--- linux-2.6.39-libre/arch/mips/include/asm/suspend.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/mips/include/asm/suspend.h	2011-07-11 19:51:52.000000000 -0400
@@ -1,8 +1,6 @@
 #ifndef __ASM_SUSPEND_H
 #define __ASM_SUSPEND_H
 
-static inline int arch_prepare_suspend(void) { return 0; }
-
 /* References to section boundaries */
 extern const void __nosave_begin, __nosave_end;
 
diff -druN linux-2.6.39-libre/arch/mips/include/asm/thread_info.h linux-3.0-rc7-libre/arch/mips/include/asm/thread_info.h
--- linux-2.6.39-libre/arch/mips/include/asm/thread_info.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/mips/include/asm/thread_info.h	2011-07-11 19:51:52.000000000 -0400
@@ -149,6 +149,9 @@
 #define _TIF_FPUBOUND		(1<<TIF_FPUBOUND)
 #define _TIF_LOAD_WATCH		(1<<TIF_LOAD_WATCH)
 
+/* work to do in syscall_trace_leave() */
+#define _TIF_WORK_SYSCALL_EXIT	(_TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT)
+
 /* work to do on interrupt/exception return */
 #define _TIF_WORK_MASK		(0x0000ffef &				\
 					~(_TIF_SECCOMP | _TIF_SYSCALL_AUDIT))
diff -druN linux-2.6.39-libre/arch/mips/include/asm/time.h linux-3.0-rc7-libre/arch/mips/include/asm/time.h
--- linux-2.6.39-libre/arch/mips/include/asm/time.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/mips/include/asm/time.h	2011-07-11 19:51:52.000000000 -0400
@@ -84,12 +84,6 @@
 #endif
 }
 
-static inline void clocksource_set_clock(struct clocksource *cs,
-					 unsigned int clock)
-{
-	clocksource_calc_mult_shift(cs, clock, 4);
-}
-
 static inline void clockevent_set_clock(struct clock_event_device *cd,
 					unsigned int clock)
 {
diff -druN linux-2.6.39-libre/arch/mips/include/asm/unistd.h linux-3.0-rc7-libre/arch/mips/include/asm/unistd.h
--- linux-2.6.39-libre/arch/mips/include/asm/unistd.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/mips/include/asm/unistd.h	2011-07-11 19:51:52.000000000 -0400
@@ -363,16 +363,17 @@
 #define __NR_open_by_handle_at		(__NR_Linux + 340)
 #define __NR_clock_adjtime		(__NR_Linux + 341)
 #define __NR_syncfs			(__NR_Linux + 342)
+#define __NR_setns			(__NR_Linux + 343)
 
 /*
  * Offset of the last Linux o32 flavoured syscall
  */
-#define __NR_Linux_syscalls		342
+#define __NR_Linux_syscalls		343
 
 #endif /* _MIPS_SIM == _MIPS_SIM_ABI32 */
 
 #define __NR_O32_Linux			4000
-#define __NR_O32_Linux_syscalls		342
+#define __NR_O32_Linux_syscalls		343
 
 #if _MIPS_SIM == _MIPS_SIM_ABI64
 
@@ -682,16 +683,17 @@
 #define __NR_open_by_handle_at		(__NR_Linux + 299)
 #define __NR_clock_adjtime		(__NR_Linux + 300)
 #define __NR_syncfs			(__NR_Linux + 301)
+#define __NR_setns			(__NR_Linux + 302)
 
 /*
  * Offset of the last Linux 64-bit flavoured syscall
  */
-#define __NR_Linux_syscalls		301
+#define __NR_Linux_syscalls		302
 
 #endif /* _MIPS_SIM == _MIPS_SIM_ABI64 */
 
 #define __NR_64_Linux			5000
-#define __NR_64_Linux_syscalls		301
+#define __NR_64_Linux_syscalls		302
 
 #if _MIPS_SIM == _MIPS_SIM_NABI32
 
@@ -1006,16 +1008,17 @@
 #define __NR_open_by_handle_at		(__NR_Linux + 304)
 #define __NR_clock_adjtime		(__NR_Linux + 305)
 #define __NR_syncfs			(__NR_Linux + 306)
+#define __NR_setns			(__NR_Linux + 307)
 
 /*
  * Offset of the last N32 flavoured syscall
  */
-#define __NR_Linux_syscalls		306
+#define __NR_Linux_syscalls		307
 
 #endif /* _MIPS_SIM == _MIPS_SIM_NABI32 */
 
 #define __NR_N32_Linux			6000
-#define __NR_N32_Linux_syscalls		306
+#define __NR_N32_Linux_syscalls		307
 
 #ifdef __KERNEL__
 
diff -druN linux-2.6.39-libre/arch/mips/jz4740/setup.c linux-3.0-rc7-libre/arch/mips/jz4740/setup.c
--- linux-2.6.39-libre/arch/mips/jz4740/setup.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/mips/jz4740/setup.c	2011-07-11 19:51:52.000000000 -0400
@@ -1,5 +1,6 @@
 /*
  *  Copyright (C) 2009-2010, Lars-Peter Clausen <lars@metafoo.de>
+ *  Copyright (C) 2011, Maarten ter Huurne <maarten@treewalker.org>
  *  JZ4740 setup code
  *
  *  This program is free software; you can redistribute it and/or modify it
@@ -14,13 +15,44 @@
  */
 
 #include <linux/init.h>
+#include <linux/io.h>
 #include <linux/kernel.h>
 
+#include <asm/bootinfo.h>
+
+#include <asm/mach-jz4740/base.h>
+
 #include "reset.h"
 
+
+#define JZ4740_EMC_SDRAM_CTRL 0x80
+
+
+static void __init jz4740_detect_mem(void)
+{
+	void __iomem *jz_emc_base;
+	u32 ctrl, bus, bank, rows, cols;
+	phys_t size;
+
+	jz_emc_base = ioremap(JZ4740_EMC_BASE_ADDR, 0x100);
+	ctrl = readl(jz_emc_base + JZ4740_EMC_SDRAM_CTRL);
+	bus = 2 - ((ctrl >> 31) & 1);
+	bank = 1 + ((ctrl >> 19) & 1);
+	cols = 8 + ((ctrl >> 26) & 7);
+	rows = 11 + ((ctrl >> 20) & 3);
+	printk(KERN_DEBUG
+		"SDRAM preconfigured: bus:%u bank:%u rows:%u cols:%u\n",
+		bus, bank, rows, cols);
+	iounmap(jz_emc_base);
+
+	size = 1 << (bus + bank + cols + rows);
+	add_memory_region(0, size, BOOT_MEM_RAM);
+}
+
 void __init plat_mem_setup(void)
 {
 	jz4740_reset_init();
+	jz4740_detect_mem();
 }
 
 const char *get_system_type(void)
diff -druN linux-2.6.39-libre/arch/mips/jz4740/time.c linux-3.0-rc7-libre/arch/mips/jz4740/time.c
--- linux-2.6.39-libre/arch/mips/jz4740/time.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/mips/jz4740/time.c	2011-07-11 19:51:52.000000000 -0400
@@ -121,8 +121,7 @@
 
 	clockevents_register_device(&jz4740_clockevent);
 
-	clocksource_set_clock(&jz4740_clocksource, clk_rate);
-	ret = clocksource_register(&jz4740_clocksource);
+	ret = clocksource_register_hz(&jz4740_clocksource, clk_rate);
 
 	if (ret)
 		printk(KERN_ERR "Failed to register clocksource: %d\n", ret);
diff -druN linux-2.6.39-libre/arch/mips/Kbuild.platforms linux-3.0-rc7-libre/arch/mips/Kbuild.platforms
--- linux-2.6.39-libre/arch/mips/Kbuild.platforms	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/mips/Kbuild.platforms	2011-07-11 19:51:52.000000000 -0400
@@ -11,6 +11,7 @@
 platforms += emma
 platforms += jazz
 platforms += jz4740
+platforms += lantiq
 platforms += lasat
 platforms += loongson
 platforms += mipssim
diff -druN linux-2.6.39-libre/arch/mips/Kconfig linux-3.0-rc7-libre/arch/mips/Kconfig
--- linux-2.6.39-libre/arch/mips/Kconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/mips/Kconfig	2011-07-11 19:51:52.000000000 -0400
@@ -212,6 +212,24 @@
 	select HAVE_PWM
 	select HAVE_CLK
 
+config LANTIQ
+	bool "Lantiq based platforms"
+	select DMA_NONCOHERENT
+	select IRQ_CPU
+	select CEVT_R4K
+	select CSRC_R4K
+	select SYS_HAS_CPU_MIPS32_R1
+	select SYS_HAS_CPU_MIPS32_R2
+	select SYS_SUPPORTS_BIG_ENDIAN
+	select SYS_SUPPORTS_32BIT_KERNEL
+	select SYS_SUPPORTS_MULTITHREADING
+	select SYS_HAS_EARLY_PRINTK
+	select ARCH_REQUIRE_GPIOLIB
+	select SWAP_IO_SPACE
+	select BOOT_RAW
+	select HAVE_CLK
+	select MIPS_MACHINE
+
 config LASAT
 	bool "LASAT Networks platforms"
 	select CEVT_R4K
@@ -736,6 +754,33 @@
 		Hikari
 	  Say Y here for most Octeon reference boards.
 
+config NLM_XLR_BOARD
+	bool "Netlogic XLR/XLS based systems"
+	depends on EXPERIMENTAL
+	select BOOT_ELF32
+	select NLM_COMMON
+	select NLM_XLR
+	select SYS_HAS_CPU_XLR
+	select SYS_SUPPORTS_SMP
+	select HW_HAS_PCI
+	select SWAP_IO_SPACE
+	select SYS_SUPPORTS_32BIT_KERNEL
+	select SYS_SUPPORTS_64BIT_KERNEL
+	select 64BIT_PHYS_ADDR
+	select SYS_SUPPORTS_BIG_ENDIAN
+	select SYS_SUPPORTS_HIGHMEM
+	select DMA_COHERENT
+	select NR_CPUS_DEFAULT_32
+	select CEVT_R4K
+	select CSRC_R4K
+	select IRQ_CPU
+	select ZONE_DMA if 64BIT
+	select SYNC_R4K
+	select SYS_HAS_EARLY_PRINTK
+	help
+	  Support for systems based on Netlogic XLR and XLS processors.
+	  Say Y here if you have a XLR or XLS based board.
+
 endchoice
 
 source "arch/mips/alchemy/Kconfig"
@@ -743,6 +788,7 @@
 source "arch/mips/bcm63xx/Kconfig"
 source "arch/mips/jazz/Kconfig"
 source "arch/mips/jz4740/Kconfig"
+source "arch/mips/lantiq/Kconfig"
 source "arch/mips/lasat/Kconfig"
 source "arch/mips/pmc-sierra/Kconfig"
 source "arch/mips/powertv/Kconfig"
@@ -752,6 +798,7 @@
 source "arch/mips/vr41xx/Kconfig"
 source "arch/mips/cavium-octeon/Kconfig"
 source "arch/mips/loongson/Kconfig"
+source "arch/mips/netlogic/Kconfig"
 
 endmenu
 
@@ -774,14 +821,6 @@
 	bool
 	default y if !MIPS_MT_SMTC
 
-config GENERIC_FIND_NEXT_BIT
-	bool
-	default y
-
-config GENERIC_FIND_BIT_LE
-	bool
-	default y
-
 config GENERIC_HWEIGHT
 	bool
 	default y
@@ -1420,6 +1459,17 @@
 	help
 	  Broadcom BMIPS5000 processors.
 
+config CPU_XLR
+	bool "Netlogic XLR SoC"
+	depends on SYS_HAS_CPU_XLR
+	select CPU_SUPPORTS_32BIT_KERNEL
+	select CPU_SUPPORTS_64BIT_KERNEL
+	select CPU_SUPPORTS_HIGHMEM
+	select WEAK_ORDERING
+	select WEAK_REORDERING_BEYOND_LLSC
+	select CPU_SUPPORTS_HUGEPAGES
+	help
+	  Netlogic Microsystems XLR/XLS processors.
 endchoice
 
 if CPU_LOONGSON2F
@@ -1550,6 +1600,9 @@
 config SYS_HAS_CPU_BMIPS5000
 	bool
 
+config SYS_HAS_CPU_XLR
+	bool
+
 #
 # CPU may reorder R->R, R->W, W->R, W->W
 # Reordering beyond LL and SC is handled in WEAK_REORDERING_BEYOND_LLSC
@@ -2334,6 +2387,7 @@
 
 config I8253
 	bool
+	select CLKSRC_I8253
 	select MIPS_EXTERNAL_TIMER
 
 config ZONE_DMA32
diff -druN linux-2.6.39-libre/arch/mips/Kconfig.debug linux-3.0-rc7-libre/arch/mips/Kconfig.debug
--- linux-2.6.39-libre/arch/mips/Kconfig.debug	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/mips/Kconfig.debug	2011-07-11 19:51:52.000000000 -0400
@@ -76,15 +76,6 @@
 	  provides another way to check stack overflow happened on kernel mode
 	  stack usually caused by nested interruption.
 
-config DEBUG_STACK_USAGE
-	bool "Enable stack utilization instrumentation"
-	depends on DEBUG_KERNEL
-	help
-	  Enables the display of the minimum amount of free stack which each
-	  task has ever had available in the sysrq-T and sysrq-P debug output.
-
-	  This option will slow down process creation somewhat.
-
 config SMTC_IDLE_HOOK_DEBUG
 	bool "Enable additional debug checks before going into CPU idle loop"
 	depends on DEBUG_KERNEL && MIPS_MT_SMTC
diff -druN linux-2.6.39-libre/arch/mips/kernel/cevt-txx9.c linux-3.0-rc7-libre/arch/mips/kernel/cevt-txx9.c
--- linux-2.6.39-libre/arch/mips/kernel/cevt-txx9.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/mips/kernel/cevt-txx9.c	2011-07-11 19:51:52.000000000 -0400
@@ -51,8 +51,7 @@
 {
 	struct txx9_tmr_reg __iomem *tmrptr;
 
-	clocksource_set_clock(&txx9_clocksource.cs, TIMER_CLK(imbusclk));
-	clocksource_register(&txx9_clocksource.cs);
+	clocksource_register_hz(&txx9_clocksource.cs, TIMER_CLK(imbusclk));
 
 	tmrptr = ioremap(baseaddr, sizeof(struct txx9_tmr_reg));
 	__raw_writel(TCR_BASE, &tmrptr->tcr);
diff -druN linux-2.6.39-libre/arch/mips/kernel/cpu-probe.c linux-3.0-rc7-libre/arch/mips/kernel/cpu-probe.c
--- linux-2.6.39-libre/arch/mips/kernel/cpu-probe.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/mips/kernel/cpu-probe.c	2011-07-11 19:51:52.000000000 -0400
@@ -291,6 +291,12 @@
 #endif
 }
 
+static inline void set_elf_platform(int cpu, const char *plat)
+{
+	if (cpu == 0)
+		__elf_platform = plat;
+}
+
 /*
  * Get the FPU Implementation/Revision.
  */
@@ -614,6 +620,16 @@
 	case PRID_IMP_LOONGSON2:
 		c->cputype = CPU_LOONGSON2;
 		__cpu_name[cpu] = "ICT Loongson-2";
+
+		switch (c->processor_id & PRID_REV_MASK) {
+		case PRID_REV_LOONGSON2E:
+			set_elf_platform(cpu, "loongson2e");
+			break;
+		case PRID_REV_LOONGSON2F:
+			set_elf_platform(cpu, "loongson2f");
+			break;
+		}
+
 		c->isa_level = MIPS_CPU_ISA_III;
 		c->options = R4K_OPTS |
 			     MIPS_CPU_FPU | MIPS_CPU_LLSC |
@@ -911,12 +927,14 @@
 	case PRID_IMP_BMIPS32_REV8:
 		c->cputype = CPU_BMIPS32;
 		__cpu_name[cpu] = "Broadcom BMIPS32";
+		set_elf_platform(cpu, "bmips32");
 		break;
 	case PRID_IMP_BMIPS3300:
 	case PRID_IMP_BMIPS3300_ALT:
 	case PRID_IMP_BMIPS3300_BUG:
 		c->cputype = CPU_BMIPS3300;
 		__cpu_name[cpu] = "Broadcom BMIPS3300";
+		set_elf_platform(cpu, "bmips3300");
 		break;
 	case PRID_IMP_BMIPS43XX: {
 		int rev = c->processor_id & 0xff;
@@ -925,15 +943,18 @@
 				rev <= PRID_REV_BMIPS4380_HI) {
 			c->cputype = CPU_BMIPS4380;
 			__cpu_name[cpu] = "Broadcom BMIPS4380";
+			set_elf_platform(cpu, "bmips4380");
 		} else {
 			c->cputype = CPU_BMIPS4350;
 			__cpu_name[cpu] = "Broadcom BMIPS4350";
+			set_elf_platform(cpu, "bmips4350");
 		}
 		break;
 	}
 	case PRID_IMP_BMIPS5000:
 		c->cputype = CPU_BMIPS5000;
 		__cpu_name[cpu] = "Broadcom BMIPS5000";
+		set_elf_platform(cpu, "bmips5000");
 		c->options |= MIPS_CPU_ULRI;
 		break;
 	}
@@ -956,14 +977,12 @@
 		c->cputype = CPU_CAVIUM_OCTEON_PLUS;
 		__cpu_name[cpu] = "Cavium Octeon+";
 platform:
-		if (cpu == 0)
-			__elf_platform = "octeon";
+		set_elf_platform(cpu, "octeon");
 		break;
 	case PRID_IMP_CAVIUM_CN63XX:
 		c->cputype = CPU_CAVIUM_OCTEON2;
 		__cpu_name[cpu] = "Cavium Octeon II";
-		if (cpu == 0)
-			__elf_platform = "octeon2";
+		set_elf_platform(cpu, "octeon2");
 		break;
 	default:
 		printk(KERN_INFO "Unknown Octeon chip!\n");
@@ -988,6 +1007,59 @@
 	}
 }
 
+static inline void cpu_probe_netlogic(struct cpuinfo_mips *c, int cpu)
+{
+	decode_configs(c);
+
+	c->options = (MIPS_CPU_TLB       |
+			MIPS_CPU_4KEX    |
+			MIPS_CPU_COUNTER |
+			MIPS_CPU_DIVEC   |
+			MIPS_CPU_WATCH   |
+			MIPS_CPU_EJTAG   |
+			MIPS_CPU_LLSC);
+
+	switch (c->processor_id & 0xff00) {
+	case PRID_IMP_NETLOGIC_XLR732:
+	case PRID_IMP_NETLOGIC_XLR716:
+	case PRID_IMP_NETLOGIC_XLR532:
+	case PRID_IMP_NETLOGIC_XLR308:
+	case PRID_IMP_NETLOGIC_XLR532C:
+	case PRID_IMP_NETLOGIC_XLR516C:
+	case PRID_IMP_NETLOGIC_XLR508C:
+	case PRID_IMP_NETLOGIC_XLR308C:
+		c->cputype = CPU_XLR;
+		__cpu_name[cpu] = "Netlogic XLR";
+		break;
+
+	case PRID_IMP_NETLOGIC_XLS608:
+	case PRID_IMP_NETLOGIC_XLS408:
+	case PRID_IMP_NETLOGIC_XLS404:
+	case PRID_IMP_NETLOGIC_XLS208:
+	case PRID_IMP_NETLOGIC_XLS204:
+	case PRID_IMP_NETLOGIC_XLS108:
+	case PRID_IMP_NETLOGIC_XLS104:
+	case PRID_IMP_NETLOGIC_XLS616B:
+	case PRID_IMP_NETLOGIC_XLS608B:
+	case PRID_IMP_NETLOGIC_XLS416B:
+	case PRID_IMP_NETLOGIC_XLS412B:
+	case PRID_IMP_NETLOGIC_XLS408B:
+	case PRID_IMP_NETLOGIC_XLS404B:
+		c->cputype = CPU_XLR;
+		__cpu_name[cpu] = "Netlogic XLS";
+		break;
+
+	default:
+		printk(KERN_INFO "Unknown Netlogic chip id [%02x]!\n",
+		       c->processor_id);
+		c->cputype = CPU_XLR;
+		break;
+	}
+
+	c->isa_level = MIPS_CPU_ISA_M64R1;
+	c->tlbsize = ((read_c0_config1() >> 25) & 0x3f) + 1;
+}
+
 #ifdef CONFIG_64BIT
 /* For use by uaccess.h */
 u64 __ua_limit;
@@ -1035,6 +1107,9 @@
 	case PRID_COMP_INGENIC:
 		cpu_probe_ingenic(c, cpu);
 		break;
+	case PRID_COMP_NETLOGIC:
+		cpu_probe_netlogic(c, cpu);
+		break;
 	}
 
 	BUG_ON(!__cpu_name[cpu]);
diff -druN linux-2.6.39-libre/arch/mips/kernel/csrc-bcm1480.c linux-3.0-rc7-libre/arch/mips/kernel/csrc-bcm1480.c
--- linux-2.6.39-libre/arch/mips/kernel/csrc-bcm1480.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/mips/kernel/csrc-bcm1480.c	2011-07-11 19:51:52.000000000 -0400
@@ -49,6 +49,5 @@
 
 	plldiv = G_BCM1480_SYS_PLL_DIV(__raw_readq(IOADDR(A_SCD_SYSTEM_CFG)));
 	zbbus = ((plldiv >> 1) * 50000000) + ((plldiv & 1) * 25000000);
-	clocksource_set_clock(cs, zbbus);
-	clocksource_register(cs);
+	clocksource_register_hz(cs, zbbus);
 }
diff -druN linux-2.6.39-libre/arch/mips/kernel/csrc-ioasic.c linux-3.0-rc7-libre/arch/mips/kernel/csrc-ioasic.c
--- linux-2.6.39-libre/arch/mips/kernel/csrc-ioasic.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/mips/kernel/csrc-ioasic.c	2011-07-11 19:51:52.000000000 -0400
@@ -59,7 +59,5 @@
 	printk(KERN_INFO "I/O ASIC clock frequency %dHz\n", freq);
 
 	clocksource_dec.rating = 200 + freq / 10000000;
-	clocksource_set_clock(&clocksource_dec, freq);
-
-	clocksource_register(&clocksource_dec);
+	clocksource_register_hz(&clocksource_dec, freq);
 }
diff -druN linux-2.6.39-libre/arch/mips/kernel/csrc-powertv.c linux-3.0-rc7-libre/arch/mips/kernel/csrc-powertv.c
--- linux-2.6.39-libre/arch/mips/kernel/csrc-powertv.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/mips/kernel/csrc-powertv.c	2011-07-11 19:51:52.000000000 -0400
@@ -78,9 +78,7 @@
 
 	clocksource_mips.rating = 200 + mips_hpt_frequency / 10000000;
 
-	clocksource_set_clock(&clocksource_mips, mips_hpt_frequency);
-
-	clocksource_register(&clocksource_mips);
+	clocksource_register_hz(&clocksource_mips, mips_hpt_frequency);
 }
 
 /**
@@ -130,43 +128,16 @@
 /**
  * powertv_tim_c_clocksource_init - set up a clock source for the TIM_C clock
  *
- * The hard part here is coming up with a constant k and shift s such that
- * the 48-bit TIM_C value multiplied by k doesn't overflow and that value,
- * when shifted right by s, yields the corresponding number of nanoseconds.
  * We know that TIM_C counts at 27 MHz/8, so each cycle corresponds to
- * 1 / (27,000,000/8) seconds. Multiply that by a billion and you get the
- * number of nanoseconds. Since the TIM_C value has 48 bits and the math is
- * done in 64 bits, avoiding an overflow means that k must be less than
- * 64 - 48 = 16 bits.
+ * 1 / (27,000,000/8) seconds.
  */
 static void __init powertv_tim_c_clocksource_init(void)
 {
-	int			prescale;
-	unsigned long		dividend;
-	unsigned long		k;
-	int			s;
-	const int		max_k_bits = (64 - 48) - 1;
-	const unsigned long	billion = 1000000000;
 	const unsigned long	counts_per_second = 27000000 / 8;
 
-	prescale = BITS_PER_LONG - ilog2(billion) - 1;
-	dividend = billion << prescale;
-	k = dividend / counts_per_second;
-	s = ilog2(k) - max_k_bits;
-
-	if (s < 0)
-		s = prescale;
-
-	else {
-		k >>= s;
-		s += prescale;
-	}
-
-	clocksource_tim_c.mult = k;
-	clocksource_tim_c.shift = s;
 	clocksource_tim_c.rating = 200;
 
-	clocksource_register(&clocksource_tim_c);
+	clocksource_register_hz(&clocksource_tim_c, counts_per_second);
 	tim_c = (struct tim_c *) asic_reg_addr(tim_ch);
 }
 
diff -druN linux-2.6.39-libre/arch/mips/kernel/csrc-r4k.c linux-3.0-rc7-libre/arch/mips/kernel/csrc-r4k.c
--- linux-2.6.39-libre/arch/mips/kernel/csrc-r4k.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/mips/kernel/csrc-r4k.c	2011-07-11 19:51:52.000000000 -0400
@@ -30,9 +30,7 @@
 	/* Calculate a somewhat reasonable rating value */
 	clocksource_mips.rating = 200 + mips_hpt_frequency / 10000000;
 
-	clocksource_set_clock(&clocksource_mips, mips_hpt_frequency);
-
-	clocksource_register(&clocksource_mips);
+	clocksource_register_hz(&clocksource_mips, mips_hpt_frequency);
 
 	return 0;
 }
diff -druN linux-2.6.39-libre/arch/mips/kernel/csrc-sb1250.c linux-3.0-rc7-libre/arch/mips/kernel/csrc-sb1250.c
--- linux-2.6.39-libre/arch/mips/kernel/csrc-sb1250.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/mips/kernel/csrc-sb1250.c	2011-07-11 19:51:52.000000000 -0400
@@ -65,6 +65,5 @@
 		     IOADDR(A_SCD_TIMER_REGISTER(SB1250_HPT_NUM,
 						 R_SCD_TIMER_CFG)));
 
-	clocksource_set_clock(cs, V_SCD_TIMER_FREQ);
-	clocksource_register(cs);
+	clocksource_register_hz(cs, V_SCD_TIMER_FREQ);
 }
diff -druN linux-2.6.39-libre/arch/mips/kernel/entry.S linux-3.0-rc7-libre/arch/mips/kernel/entry.S
--- linux-2.6.39-libre/arch/mips/kernel/entry.S	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/mips/kernel/entry.S	2011-07-11 19:51:52.000000000 -0400
@@ -167,14 +167,13 @@
 FEXPORT(syscall_exit_work_partial)
 	SAVE_STATIC
 syscall_exit_work:
-	li	t0, _TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT
+	li	t0, _TIF_WORK_SYSCALL_EXIT
 	and	t0, a2			# a2 is preloaded with TI_FLAGS
 	beqz	t0, work_pending	# trace bit set?
-	local_irq_enable		# could let do_syscall_trace()
+	local_irq_enable		# could let syscall_trace_leave()
 					# call schedule() instead
 	move	a0, sp
-	li	a1, 1
-	jal	do_syscall_trace
+	jal	syscall_trace_leave
 	b	resume_userspace
 
 #if defined(CONFIG_CPU_MIPSR2) || defined(CONFIG_MIPS_MT)
diff -druN linux-2.6.39-libre/arch/mips/kernel/i8253.c linux-3.0-rc7-libre/arch/mips/kernel/i8253.c
--- linux-2.6.39-libre/arch/mips/kernel/i8253.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/mips/kernel/i8253.c	2011-07-11 19:51:52.000000000 -0400
@@ -125,87 +125,11 @@
 	setup_irq(0, &irq0);
 }
 
-/*
- * Since the PIT overflows every tick, its not very useful
- * to just read by itself. So use jiffies to emulate a free
- * running counter:
- */
-static cycle_t pit_read(struct clocksource *cs)
-{
-	unsigned long flags;
-	int count;
-	u32 jifs;
-	static int old_count;
-	static u32 old_jifs;
-
-	raw_spin_lock_irqsave(&i8253_lock, flags);
-	/*
-	 * Although our caller may have the read side of xtime_lock,
-	 * this is now a seqlock, and we are cheating in this routine
-	 * by having side effects on state that we cannot undo if
-	 * there is a collision on the seqlock and our caller has to
-	 * retry.  (Namely, old_jifs and old_count.)  So we must treat
-	 * jiffies as volatile despite the lock.  We read jiffies
-	 * before latching the timer count to guarantee that although
-	 * the jiffies value might be older than the count (that is,
-	 * the counter may underflow between the last point where
-	 * jiffies was incremented and the point where we latch the
-	 * count), it cannot be newer.
-	 */
-	jifs = jiffies;
-	outb_p(0x00, PIT_MODE);	/* latch the count ASAP */
-	count = inb_p(PIT_CH0);	/* read the latched count */
-	count |= inb_p(PIT_CH0) << 8;
-
-	/* VIA686a test code... reset the latch if count > max + 1 */
-	if (count > LATCH) {
-		outb_p(0x34, PIT_MODE);
-		outb_p(LATCH & 0xff, PIT_CH0);
-		outb(LATCH >> 8, PIT_CH0);
-		count = LATCH - 1;
-	}
-
-	/*
-	 * It's possible for count to appear to go the wrong way for a
-	 * couple of reasons:
-	 *
-	 *  1. The timer counter underflows, but we haven't handled the
-	 *     resulting interrupt and incremented jiffies yet.
-	 *  2. Hardware problem with the timer, not giving us continuous time,
-	 *     the counter does small "jumps" upwards on some Pentium systems,
-	 *     (see c't 95/10 page 335 for Neptun bug.)
-	 *
-	 * Previous attempts to handle these cases intelligently were
-	 * buggy, so we just do the simple thing now.
-	 */
-	if (count > old_count && jifs == old_jifs) {
-		count = old_count;
-	}
-	old_count = count;
-	old_jifs = jifs;
-
-	raw_spin_unlock_irqrestore(&i8253_lock, flags);
-
-	count = (LATCH - 1) - count;
-
-	return (cycle_t)(jifs * LATCH) + count;
-}
-
-static struct clocksource clocksource_pit = {
-	.name	= "pit",
-	.rating = 110,
-	.read	= pit_read,
-	.mask	= CLOCKSOURCE_MASK(32),
-	.mult	= 0,
-	.shift	= 20,
-};
-
 static int __init init_pit_clocksource(void)
 {
 	if (num_possible_cpus() > 1) /* PIT does not scale! */
 		return 0;
 
-	clocksource_pit.mult = clocksource_hz2mult(CLOCK_TICK_RATE, 20);
-	return clocksource_register(&clocksource_pit);
+	return clocksource_i8253_init();
 }
 arch_initcall(init_pit_clocksource);
diff -druN linux-2.6.39-libre/arch/mips/kernel/Makefile linux-3.0-rc7-libre/arch/mips/kernel/Makefile
--- linux-2.6.39-libre/arch/mips/kernel/Makefile	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/mips/kernel/Makefile	2011-07-11 19:51:52.000000000 -0400
@@ -52,6 +52,7 @@
 obj-$(CONFIG_CPU_TX49XX)	+= r4k_fpu.o r4k_switch.o
 obj-$(CONFIG_CPU_VR41XX)	+= r4k_fpu.o r4k_switch.o
 obj-$(CONFIG_CPU_CAVIUM_OCTEON)	+= octeon_switch.o
+obj-$(CONFIG_CPU_XLR)		+= r4k_fpu.o r4k_switch.o
 
 obj-$(CONFIG_SMP)		+= smp.o
 obj-$(CONFIG_SMP_UP)		+= smp-up.o
diff -druN linux-2.6.39-libre/arch/mips/kernel/octeon_switch.S linux-3.0-rc7-libre/arch/mips/kernel/octeon_switch.S
--- linux-2.6.39-libre/arch/mips/kernel/octeon_switch.S	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/mips/kernel/octeon_switch.S	2011-07-11 19:51:52.000000000 -0400
@@ -4,7 +4,7 @@
  * for more details.
  *
  * Copyright (C) 1994, 1995, 1996, 1998, 1999, 2002, 2003 Ralf Baechle
- * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
+ * Copyright (C) 1996 David S. Miller (davem@davemloft.net)
  * Copyright (C) 1994, 1995, 1996, by Andreas Busse
  * Copyright (C) 1999 Silicon Graphics, Inc.
  * Copyright (C) 2000 MIPS Technologies, Inc.
diff -druN linux-2.6.39-libre/arch/mips/kernel/prom.c linux-3.0-rc7-libre/arch/mips/kernel/prom.c
--- linux-2.6.39-libre/arch/mips/kernel/prom.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/mips/kernel/prom.c	2011-07-11 19:51:52.000000000 -0400
@@ -83,7 +83,8 @@
 	 * device-tree, including the platform type, initrd location and
 	 * size, and more ...
 	 */
-	of_scan_flat_dt(early_init_dt_scan_chosen, NULL);
+	of_scan_flat_dt(early_init_dt_scan_chosen, arcs_cmdline);
+
 
 	/* Scan memory nodes */
 	of_scan_flat_dt(early_init_dt_scan_root, NULL);
diff -druN linux-2.6.39-libre/arch/mips/kernel/ptrace.c linux-3.0-rc7-libre/arch/mips/kernel/ptrace.c
--- linux-2.6.39-libre/arch/mips/kernel/ptrace.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/mips/kernel/ptrace.c	2011-07-11 19:51:52.000000000 -0400
@@ -533,15 +533,10 @@
  * Notification of system call entry/exit
  * - triggered by current->work.syscall_trace
  */
-asmlinkage void do_syscall_trace(struct pt_regs *regs, int entryexit)
+asmlinkage void syscall_trace_enter(struct pt_regs *regs)
 {
 	/* do the secure computing check first */
-	if (!entryexit)
-		secure_computing(regs->regs[2]);
-
-	if (unlikely(current->audit_context) && entryexit)
-		audit_syscall_exit(AUDITSC_RESULT(regs->regs[7]),
-		                   -regs->regs[2]);
+	secure_computing(regs->regs[2]);
 
 	if (!(current->ptrace & PT_PTRACED))
 		goto out;
@@ -565,8 +560,40 @@
 	}
 
 out:
-	if (unlikely(current->audit_context) && !entryexit)
+	if (unlikely(current->audit_context))
 		audit_syscall_entry(audit_arch(), regs->regs[2],
 				    regs->regs[4], regs->regs[5],
 				    regs->regs[6], regs->regs[7]);
 }
+
+/*
+ * Notification of system call entry/exit
+ * - triggered by current->work.syscall_trace
+ */
+asmlinkage void syscall_trace_leave(struct pt_regs *regs)
+{
+	if (unlikely(current->audit_context))
+		audit_syscall_exit(AUDITSC_RESULT(regs->regs[7]),
+		                   -regs->regs[2]);
+
+	if (!(current->ptrace & PT_PTRACED))
+		return;
+
+	if (!test_thread_flag(TIF_SYSCALL_TRACE))
+		return;
+
+	/* 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));
+
+	/*
+	 * 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;
+	}
+}
diff -druN linux-2.6.39-libre/arch/mips/kernel/r2300_fpu.S linux-3.0-rc7-libre/arch/mips/kernel/r2300_fpu.S
--- linux-2.6.39-libre/arch/mips/kernel/r2300_fpu.S	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/mips/kernel/r2300_fpu.S	2011-07-11 19:51:52.000000000 -0400
@@ -6,7 +6,7 @@
  * Copyright (C) 1996, 1998 by Ralf Baechle
  *
  * Multi-arch abstraction and asm macros for easier reading:
- * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
+ * Copyright (C) 1996 David S. Miller (davem@davemloft.net)
  *
  * Further modifications to make this work:
  * Copyright (c) 1998 Harald Koerfgen
diff -druN linux-2.6.39-libre/arch/mips/kernel/r2300_switch.S linux-3.0-rc7-libre/arch/mips/kernel/r2300_switch.S
--- linux-2.6.39-libre/arch/mips/kernel/r2300_switch.S	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/mips/kernel/r2300_switch.S	2011-07-11 19:51:52.000000000 -0400
@@ -5,7 +5,7 @@
  * Copyright (C) 1994, 1995, 1996 by Andreas Busse
  *
  * Multi-cpu abstraction and macros for easier reading:
- * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
+ * Copyright (C) 1996 David S. Miller (davem@davemloft.net)
  *
  * Further modifications to make this work:
  * Copyright (c) 1998-2000 Harald Koerfgen
diff -druN linux-2.6.39-libre/arch/mips/kernel/r4k_fpu.S linux-3.0-rc7-libre/arch/mips/kernel/r4k_fpu.S
--- linux-2.6.39-libre/arch/mips/kernel/r4k_fpu.S	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/mips/kernel/r4k_fpu.S	2011-07-11 19:51:52.000000000 -0400
@@ -6,7 +6,7 @@
  * Copyright (C) 1996, 98, 99, 2000, 01 Ralf Baechle
  *
  * Multi-arch abstraction and asm macros for easier reading:
- * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
+ * Copyright (C) 1996 David S. Miller (davem@davemloft.net)
  *
  * Carsten Langgaard, carstenl@mips.com
  * Copyright (C) 2000 MIPS Technologies, Inc.
diff -druN linux-2.6.39-libre/arch/mips/kernel/r4k_switch.S linux-3.0-rc7-libre/arch/mips/kernel/r4k_switch.S
--- linux-2.6.39-libre/arch/mips/kernel/r4k_switch.S	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/mips/kernel/r4k_switch.S	2011-07-11 19:51:52.000000000 -0400
@@ -4,7 +4,7 @@
  * for more details.
  *
  * Copyright (C) 1994, 1995, 1996, 1998, 1999, 2002, 2003 Ralf Baechle
- * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
+ * Copyright (C) 1996 David S. Miller (davem@davemloft.net)
  * Copyright (C) 1994, 1995, 1996, by Andreas Busse
  * Copyright (C) 1999 Silicon Graphics, Inc.
  * Copyright (C) 2000 MIPS Technologies, Inc.
diff -druN linux-2.6.39-libre/arch/mips/kernel/r6000_fpu.S linux-3.0-rc7-libre/arch/mips/kernel/r6000_fpu.S
--- linux-2.6.39-libre/arch/mips/kernel/r6000_fpu.S	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/mips/kernel/r6000_fpu.S	2011-07-11 19:51:52.000000000 -0400
@@ -8,7 +8,7 @@
  * Copyright (C) 1996 by Ralf Baechle
  *
  * Multi-arch abstraction and asm macros for easier reading:
- * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
+ * Copyright (C) 1996 David S. Miller (davem@davemloft.net)
  */
 #include <asm/asm.h>
 #include <asm/fpregdef.h>
diff -druN linux-2.6.39-libre/arch/mips/kernel/scall32-o32.S linux-3.0-rc7-libre/arch/mips/kernel/scall32-o32.S
--- linux-2.6.39-libre/arch/mips/kernel/scall32-o32.S	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/mips/kernel/scall32-o32.S	2011-07-11 19:51:52.000000000 -0400
@@ -88,8 +88,7 @@
 	SAVE_STATIC
 	move	s0, t2
 	move	a0, sp
-	li	a1, 0
-	jal	do_syscall_trace
+	jal	syscall_trace_enter
 
 	move	t0, s0
 	RESTORE_STATIC
@@ -590,6 +589,7 @@
 	sys	sys_open_by_handle_at	3	/* 4340 */
 	sys	sys_clock_adjtime	2
 	sys	sys_syncfs		1
+	sys	sys_setns		2
 	.endm
 
 	/* We pre-compute the number of _instruction_ bytes needed to
diff -druN linux-2.6.39-libre/arch/mips/kernel/scall64-64.S linux-3.0-rc7-libre/arch/mips/kernel/scall64-64.S
--- linux-2.6.39-libre/arch/mips/kernel/scall64-64.S	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/mips/kernel/scall64-64.S	2011-07-11 19:51:52.000000000 -0400
@@ -91,8 +91,7 @@
 	SAVE_STATIC
 	move	s0, t2
 	move	a0, sp
-	li	a1, 0
-	jal	do_syscall_trace
+	jal	syscall_trace_enter
 
 	move	t0, s0
 	RESTORE_STATIC
@@ -429,4 +428,5 @@
 	PTR	sys_open_by_handle_at
 	PTR	sys_clock_adjtime		/* 5300 */
 	PTR	sys_syncfs
+	PTR	sys_setns
 	.size	sys_call_table,.-sys_call_table
diff -druN linux-2.6.39-libre/arch/mips/kernel/scall64-n32.S linux-3.0-rc7-libre/arch/mips/kernel/scall64-n32.S
--- linux-2.6.39-libre/arch/mips/kernel/scall64-n32.S	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/mips/kernel/scall64-n32.S	2011-07-11 19:51:52.000000000 -0400
@@ -89,8 +89,7 @@
 	SAVE_STATIC
 	move	s0, t2
 	move	a0, sp
-	li	a1, 0
-	jal	do_syscall_trace
+	jal	syscall_trace_enter
 
 	move	t0, s0
 	RESTORE_STATIC
@@ -429,4 +428,5 @@
 	PTR	sys_open_by_handle_at
 	PTR	compat_sys_clock_adjtime	/* 6305 */
 	PTR	sys_syncfs
+	PTR	sys_setns
 	.size	sysn32_call_table,.-sysn32_call_table
diff -druN linux-2.6.39-libre/arch/mips/kernel/scall64-o32.S linux-3.0-rc7-libre/arch/mips/kernel/scall64-o32.S
--- linux-2.6.39-libre/arch/mips/kernel/scall64-o32.S	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/mips/kernel/scall64-o32.S	2011-07-11 19:51:52.000000000 -0400
@@ -123,8 +123,7 @@
 
 	move	s0, t2			# Save syscall pointer
 	move	a0, sp
-	li	a1, 0
-	jal	do_syscall_trace
+	jal	syscall_trace_enter
 
 	move	t0, s0
 	RESTORE_STATIC
@@ -547,4 +546,5 @@
 	PTR	compat_sys_open_by_handle_at	/* 4340 */
 	PTR	compat_sys_clock_adjtime
 	PTR	sys_syncfs
+	PTR	sys_setns
 	.size	sys_call_table,.-sys_call_table
diff -druN linux-2.6.39-libre/arch/mips/kernel/smtc.c linux-3.0-rc7-libre/arch/mips/kernel/smtc.c
--- linux-2.6.39-libre/arch/mips/kernel/smtc.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/mips/kernel/smtc.c	2011-07-11 19:51:52.000000000 -0400
@@ -929,7 +929,7 @@
 
 static void ipi_resched_interrupt(void)
 {
-	/* Return from interrupt should be enough to cause scheduler check */
+	scheduler_ipi();
 }
 
 static void ipi_call_interrupt(void)
diff -druN linux-2.6.39-libre/arch/mips/kernel/syscall.c linux-3.0-rc7-libre/arch/mips/kernel/syscall.c
--- linux-2.6.39-libre/arch/mips/kernel/syscall.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/mips/kernel/syscall.c	2011-07-11 19:51:52.000000000 -0400
@@ -10,12 +10,9 @@
 #include <linux/capability.h>
 #include <linux/errno.h>
 #include <linux/linkage.h>
-#include <linux/mm.h>
 #include <linux/fs.h>
 #include <linux/smp.h>
-#include <linux/mman.h>
 #include <linux/ptrace.h>
-#include <linux/sched.h>
 #include <linux/string.h>
 #include <linux/syscalls.h>
 #include <linux/file.h>
@@ -25,11 +22,9 @@
 #include <linux/msg.h>
 #include <linux/shm.h>
 #include <linux/compiler.h>
-#include <linux/module.h>
 #include <linux/ipc.h>
 #include <linux/uaccess.h>
 #include <linux/slab.h>
-#include <linux/random.h>
 #include <linux/elf.h>
 
 #include <asm/asm.h>
@@ -66,121 +61,6 @@
 	return res;
 }
 
-unsigned long shm_align_mask = PAGE_SIZE - 1;	/* Sane caches */
-
-EXPORT_SYMBOL(shm_align_mask);
-
-#define COLOUR_ALIGN(addr,pgoff)				\
-	((((addr) + shm_align_mask) & ~shm_align_mask) +	\
-	 (((pgoff) << PAGE_SHIFT) & shm_align_mask))
-
-unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr,
-	unsigned long len, unsigned long pgoff, unsigned long flags)
-{
-	struct vm_area_struct * vmm;
-	int do_color_align;
-	unsigned long task_size;
-
-#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;
-
-	if (flags & MAP_FIXED) {
-		/* Even MAP_FIXED mappings must reside within task_size.  */
-		if (task_size - len < addr)
-			return -EINVAL;
-
-		/*
-		 * We do not accept a shared mapping if it would violate
-		 * cache aliasing constraints.
-		 */
-		if ((flags & MAP_SHARED) &&
-		    ((addr - (pgoff << PAGE_SHIFT)) & shm_align_mask))
-			return -EINVAL;
-		return addr;
-	}
-
-	do_color_align = 0;
-	if (filp || (flags & MAP_SHARED))
-		do_color_align = 1;
-	if (addr) {
-		if (do_color_align)
-			addr = COLOUR_ALIGN(addr, pgoff);
-		else
-			addr = PAGE_ALIGN(addr);
-		vmm = find_vma(current->mm, addr);
-		if (task_size - len >= addr &&
-		    (!vmm || addr + len <= vmm->vm_start))
-			return addr;
-	}
-	addr = current->mm->mmap_base;
-	if (do_color_align)
-		addr = COLOUR_ALIGN(addr, pgoff);
-	else
-		addr = PAGE_ALIGN(addr);
-
-	for (vmm = find_vma(current->mm, addr); ; vmm = vmm->vm_next) {
-		/* At this point:  (!vmm || addr < vmm->vm_end). */
-		if (task_size - len < addr)
-			return -ENOMEM;
-		if (!vmm || addr + len <= vmm->vm_start)
-			return addr;
-		addr = vmm->vm_end;
-		if (do_color_align)
-			addr = COLOUR_ALIGN(addr, pgoff);
-	}
-}
-
-void arch_pick_mmap_layout(struct mm_struct *mm)
-{
-	unsigned long random_factor = 0UL;
-
-	if (current->flags & PF_RANDOMIZE) {
-		random_factor = get_random_int();
-		random_factor = random_factor << PAGE_SHIFT;
-		if (TASK_IS_32BIT_ADDR)
-			random_factor &= 0xfffffful;
-		else
-			random_factor &= 0xffffffful;
-	}
-
-	mm->mmap_base = TASK_UNMAPPED_BASE + random_factor;
-	mm->get_unmapped_area = arch_get_unmapped_area;
-	mm->unmap_area = arch_unmap_area;
-}
-
-static inline unsigned long brk_rnd(void)
-{
-	unsigned long rnd = get_random_int();
-
-	rnd = rnd << PAGE_SHIFT;
-	/* 8MB for 32bit, 256MB for 64bit */
-	if (TASK_IS_32BIT_ADDR)
-		rnd = rnd & 0x7ffffful;
-	else
-		rnd = rnd & 0xffffffful;
-
-	return rnd;
-}
-
-unsigned long arch_randomize_brk(struct mm_struct *mm)
-{
-	unsigned long base = mm->brk;
-	unsigned long ret;
-
-	ret = PAGE_ALIGN(base + brk_rnd());
-
-	if (ret < mm->brk)
-		return mm->brk;
-
-	return ret;
-}
-
 SYSCALL_DEFINE6(mips_mmap, unsigned long, addr, unsigned long, len,
 	unsigned long, prot, unsigned long, flags, unsigned long,
 	fd, off_t, offset)
diff -druN linux-2.6.39-libre/arch/mips/kernel/vmlinux.lds.S linux-3.0-rc7-libre/arch/mips/kernel/vmlinux.lds.S
--- linux-2.6.39-libre/arch/mips/kernel/vmlinux.lds.S	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/mips/kernel/vmlinux.lds.S	2011-07-11 19:51:52.000000000 -0400
@@ -65,9 +65,11 @@
 	NOTES :text :note
 	.dummy : { *(.dummy) } :text
 
+	_sdata = .;			/* Start of data section */
 	RODATA
 
 	/* writeable */
+	_sdata = .;				/* Start of data section */
 	.data : {	/* Data */
 		. = . + DATAOFFSET;		/* for CONFIG_MAPPED_KERNEL */
 
@@ -116,7 +118,7 @@
 		EXIT_DATA
 	}
 
-	PERCPU(1 << CONFIG_MIPS_L1_CACHE_SHIFT, PAGE_SIZE)
+	PERCPU_SECTION(1 << CONFIG_MIPS_L1_CACHE_SHIFT)
 	. = ALIGN(PAGE_SIZE);
 	__init_end = .;
 	/* freed after init ends here */
diff -druN linux-2.6.39-libre/arch/mips/lantiq/clk.c linux-3.0-rc7-libre/arch/mips/lantiq/clk.c
--- linux-2.6.39-libre/arch/mips/lantiq/clk.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/mips/lantiq/clk.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,140 @@
+/*
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License version 2 as published
+ *  by the Free Software Foundation.
+ *
+ * Copyright (C) 2010 Thomas Langer <thomas.langer@lantiq.com>
+ * Copyright (C) 2010 John Crispin <blogic@openwrt.org>
+ */
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/list.h>
+
+#include <asm/time.h>
+#include <asm/irq.h>
+#include <asm/div64.h>
+
+#include <lantiq_soc.h>
+
+#include "clk.h"
+
+struct clk {
+	const char *name;
+	unsigned long rate;
+	unsigned long (*get_rate) (void);
+};
+
+static struct clk *cpu_clk;
+static int cpu_clk_cnt;
+
+/* lantiq socs have 3 static clocks */
+static struct clk cpu_clk_generic[] = {
+	{
+		.name = "cpu",
+		.get_rate = ltq_get_cpu_hz,
+	}, {
+		.name = "fpi",
+		.get_rate = ltq_get_fpi_hz,
+	}, {
+		.name = "io",
+		.get_rate = ltq_get_io_region_clock,
+	},
+};
+
+static struct resource ltq_cgu_resource = {
+	.name	= "cgu",
+	.start	= LTQ_CGU_BASE_ADDR,
+	.end	= LTQ_CGU_BASE_ADDR + LTQ_CGU_SIZE - 1,
+	.flags	= IORESOURCE_MEM,
+};
+
+/* remapped clock register range */
+void __iomem *ltq_cgu_membase;
+
+void clk_init(void)
+{
+	cpu_clk = cpu_clk_generic;
+	cpu_clk_cnt = ARRAY_SIZE(cpu_clk_generic);
+}
+
+static inline int clk_good(struct clk *clk)
+{
+	return clk && !IS_ERR(clk);
+}
+
+unsigned long clk_get_rate(struct clk *clk)
+{
+	if (unlikely(!clk_good(clk)))
+		return 0;
+
+	if (clk->rate != 0)
+		return clk->rate;
+
+	if (clk->get_rate != NULL)
+		return clk->get_rate();
+
+	return 0;
+}
+EXPORT_SYMBOL(clk_get_rate);
+
+struct clk *clk_get(struct device *dev, const char *id)
+{
+	int i;
+
+	for (i = 0; i < cpu_clk_cnt; i++)
+		if (!strcmp(id, cpu_clk[i].name))
+			return &cpu_clk[i];
+	BUG();
+	return ERR_PTR(-ENOENT);
+}
+EXPORT_SYMBOL(clk_get);
+
+void clk_put(struct clk *clk)
+{
+	/* not used */
+}
+EXPORT_SYMBOL(clk_put);
+
+static inline u32 ltq_get_counter_resolution(void)
+{
+	u32 res;
+
+	__asm__ __volatile__(
+		".set   push\n"
+		".set   mips32r2\n"
+		"rdhwr  %0, $3\n"
+		".set pop\n"
+		: "=&r" (res)
+		: /* no input */
+		: "memory");
+
+	return res;
+}
+
+void __init plat_time_init(void)
+{
+	struct clk *clk;
+
+	if (insert_resource(&iomem_resource, &ltq_cgu_resource) < 0)
+		panic("Failed to insert cgu memory\n");
+
+	if (request_mem_region(ltq_cgu_resource.start,
+			resource_size(&ltq_cgu_resource), "cgu") < 0)
+		panic("Failed to request cgu memory\n");
+
+	ltq_cgu_membase = ioremap_nocache(ltq_cgu_resource.start,
+				resource_size(&ltq_cgu_resource));
+	if (!ltq_cgu_membase) {
+		pr_err("Failed to remap cgu memory\n");
+		unreachable();
+	}
+	clk = clk_get(0, "cpu");
+	mips_hpt_frequency = clk_get_rate(clk) / ltq_get_counter_resolution();
+	write_c0_compare(read_c0_count());
+	clk_put(clk);
+}
diff -druN linux-2.6.39-libre/arch/mips/lantiq/clk.h linux-3.0-rc7-libre/arch/mips/lantiq/clk.h
--- linux-2.6.39-libre/arch/mips/lantiq/clk.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/mips/lantiq/clk.h	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,18 @@
+/*
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License version 2 as published
+ *  by the Free Software Foundation.
+ *
+ * Copyright (C) 2010 John Crispin <blogic@openwrt.org>
+ */
+
+#ifndef _LTQ_CLK_H__
+#define _LTQ_CLK_H__
+
+extern void clk_init(void);
+
+extern unsigned long ltq_get_cpu_hz(void);
+extern unsigned long ltq_get_fpi_hz(void);
+extern unsigned long ltq_get_io_region_clock(void);
+
+#endif
diff -druN linux-2.6.39-libre/arch/mips/lantiq/devices.c linux-3.0-rc7-libre/arch/mips/lantiq/devices.c
--- linux-2.6.39-libre/arch/mips/lantiq/devices.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/mips/lantiq/devices.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,122 @@
+/*
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License version 2 as published
+ *  by the Free Software Foundation.
+ *
+ *  Copyright (C) 2010 John Crispin <blogic@openwrt.org>
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/string.h>
+#include <linux/kernel.h>
+#include <linux/reboot.h>
+#include <linux/platform_device.h>
+#include <linux/leds.h>
+#include <linux/etherdevice.h>
+#include <linux/reboot.h>
+#include <linux/time.h>
+#include <linux/io.h>
+#include <linux/gpio.h>
+#include <linux/leds.h>
+
+#include <asm/bootinfo.h>
+#include <asm/irq.h>
+
+#include <lantiq_soc.h>
+
+#include "devices.h"
+
+/* nor flash */
+static struct resource ltq_nor_resource = {
+	.name	= "nor",
+	.start	= LTQ_FLASH_START,
+	.end	= LTQ_FLASH_START + LTQ_FLASH_MAX - 1,
+	.flags  = IORESOURCE_MEM,
+};
+
+static struct platform_device ltq_nor = {
+	.name		= "ltq_nor",
+	.resource	= &ltq_nor_resource,
+	.num_resources	= 1,
+};
+
+void __init ltq_register_nor(struct physmap_flash_data *data)
+{
+	ltq_nor.dev.platform_data = data;
+	platform_device_register(&ltq_nor);
+}
+
+/* watchdog */
+static struct resource ltq_wdt_resource = {
+	.name	= "watchdog",
+	.start  = LTQ_WDT_BASE_ADDR,
+	.end    = LTQ_WDT_BASE_ADDR + LTQ_WDT_SIZE - 1,
+	.flags  = IORESOURCE_MEM,
+};
+
+void __init ltq_register_wdt(void)
+{
+	platform_device_register_simple("ltq_wdt", 0, &ltq_wdt_resource, 1);
+}
+
+/* asc ports */
+static struct resource ltq_asc0_resources[] = {
+	{
+		.name	= "asc0",
+		.start  = LTQ_ASC0_BASE_ADDR,
+		.end    = LTQ_ASC0_BASE_ADDR + LTQ_ASC_SIZE - 1,
+		.flags  = IORESOURCE_MEM,
+	},
+	IRQ_RES(tx, LTQ_ASC_TIR(0)),
+	IRQ_RES(rx, LTQ_ASC_RIR(0)),
+	IRQ_RES(err, LTQ_ASC_EIR(0)),
+};
+
+static struct resource ltq_asc1_resources[] = {
+	{
+		.name	= "asc1",
+		.start  = LTQ_ASC1_BASE_ADDR,
+		.end    = LTQ_ASC1_BASE_ADDR + LTQ_ASC_SIZE - 1,
+		.flags  = IORESOURCE_MEM,
+	},
+	IRQ_RES(tx, LTQ_ASC_TIR(1)),
+	IRQ_RES(rx, LTQ_ASC_RIR(1)),
+	IRQ_RES(err, LTQ_ASC_EIR(1)),
+};
+
+void __init ltq_register_asc(int port)
+{
+	switch (port) {
+	case 0:
+		platform_device_register_simple("ltq_asc", 0,
+			ltq_asc0_resources, ARRAY_SIZE(ltq_asc0_resources));
+		break;
+	case 1:
+		platform_device_register_simple("ltq_asc", 1,
+			ltq_asc1_resources, ARRAY_SIZE(ltq_asc1_resources));
+		break;
+	default:
+		break;
+	}
+}
+
+#ifdef CONFIG_PCI
+/* pci */
+static struct platform_device ltq_pci = {
+	.name		= "ltq_pci",
+	.num_resources	= 0,
+};
+
+void __init ltq_register_pci(struct ltq_pci_data *data)
+{
+	ltq_pci.dev.platform_data = data;
+	platform_device_register(&ltq_pci);
+}
+#else
+void __init ltq_register_pci(struct ltq_pci_data *data)
+{
+	pr_err("kernel is compiled without PCI support\n");
+}
+#endif
diff -druN linux-2.6.39-libre/arch/mips/lantiq/devices.h linux-3.0-rc7-libre/arch/mips/lantiq/devices.h
--- linux-2.6.39-libre/arch/mips/lantiq/devices.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/mips/lantiq/devices.h	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,23 @@
+/*
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License version 2 as published
+ *  by the Free Software Foundation.
+ *
+ *  Copyright (C) 2010 John Crispin <blogic@openwrt.org>
+ */
+
+#ifndef _LTQ_DEVICES_H__
+#define _LTQ_DEVICES_H__
+
+#include <lantiq_platform.h>
+#include <linux/mtd/physmap.h>
+
+#define IRQ_RES(resname, irq) \
+	{.name = #resname, .start = (irq), .flags = IORESOURCE_IRQ}
+
+extern void ltq_register_nor(struct physmap_flash_data *data);
+extern void ltq_register_wdt(void);
+extern void ltq_register_asc(int port);
+extern void ltq_register_pci(struct ltq_pci_data *data);
+
+#endif
diff -druN linux-2.6.39-libre/arch/mips/lantiq/early_printk.c linux-3.0-rc7-libre/arch/mips/lantiq/early_printk.c
--- linux-2.6.39-libre/arch/mips/lantiq/early_printk.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/mips/lantiq/early_printk.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,33 @@
+/*
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License version 2 as published
+ *  by the Free Software Foundation.
+ *
+ *  Copyright (C) 2010 John Crispin <blogic@openwrt.org>
+ */
+
+#include <linux/init.h>
+#include <linux/cpu.h>
+
+#include <lantiq.h>
+#include <lantiq_soc.h>
+
+/* no ioremap possible at this early stage, lets use KSEG1 instead  */
+#define LTQ_ASC_BASE	KSEG1ADDR(LTQ_ASC1_BASE_ADDR)
+#define ASC_BUF		1024
+#define LTQ_ASC_FSTAT	((u32 *)(LTQ_ASC_BASE + 0x0048))
+#define LTQ_ASC_TBUF	((u32 *)(LTQ_ASC_BASE + 0x0020))
+#define TXMASK		0x3F00
+#define TXOFFSET	8
+
+void prom_putchar(char c)
+{
+	unsigned long flags;
+
+	local_irq_save(flags);
+	do { } while ((ltq_r32(LTQ_ASC_FSTAT) & TXMASK) >> TXOFFSET);
+	if (c == '\n')
+		ltq_w32('\r', LTQ_ASC_TBUF);
+	ltq_w32(c, LTQ_ASC_TBUF);
+	local_irq_restore(flags);
+}
diff -druN linux-2.6.39-libre/arch/mips/lantiq/irq.c linux-3.0-rc7-libre/arch/mips/lantiq/irq.c
--- linux-2.6.39-libre/arch/mips/lantiq/irq.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/mips/lantiq/irq.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,326 @@
+/*
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License version 2 as published
+ *  by the Free Software Foundation.
+ *
+ * Copyright (C) 2010 John Crispin <blogic@openwrt.org>
+ * Copyright (C) 2010 Thomas Langer <thomas.langer@lantiq.com>
+ */
+
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+
+#include <asm/bootinfo.h>
+#include <asm/irq_cpu.h>
+
+#include <lantiq_soc.h>
+#include <irq.h>
+
+/* register definitions */
+#define LTQ_ICU_IM0_ISR		0x0000
+#define LTQ_ICU_IM0_IER		0x0008
+#define LTQ_ICU_IM0_IOSR	0x0010
+#define LTQ_ICU_IM0_IRSR	0x0018
+#define LTQ_ICU_IM0_IMR		0x0020
+#define LTQ_ICU_IM1_ISR		0x0028
+#define LTQ_ICU_OFFSET		(LTQ_ICU_IM1_ISR - LTQ_ICU_IM0_ISR)
+
+#define LTQ_EIU_EXIN_C		0x0000
+#define LTQ_EIU_EXIN_INIC	0x0004
+#define LTQ_EIU_EXIN_INEN	0x000C
+
+/* irq numbers used by the external interrupt unit (EIU) */
+#define LTQ_EIU_IR0		(INT_NUM_IM4_IRL0 + 30)
+#define LTQ_EIU_IR1		(INT_NUM_IM3_IRL0 + 31)
+#define LTQ_EIU_IR2		(INT_NUM_IM1_IRL0 + 26)
+#define LTQ_EIU_IR3		INT_NUM_IM1_IRL0
+#define LTQ_EIU_IR4		(INT_NUM_IM1_IRL0 + 1)
+#define LTQ_EIU_IR5		(INT_NUM_IM1_IRL0 + 2)
+#define LTQ_EIU_IR6		(INT_NUM_IM2_IRL0 + 30)
+
+#define MAX_EIU			6
+
+/* irqs generated by device attached to the EBU need to be acked in
+ * a special manner
+ */
+#define LTQ_ICU_EBU_IRQ		22
+
+#define ltq_icu_w32(x, y)	ltq_w32((x), ltq_icu_membase + (y))
+#define ltq_icu_r32(x)		ltq_r32(ltq_icu_membase + (x))
+
+#define ltq_eiu_w32(x, y)	ltq_w32((x), ltq_eiu_membase + (y))
+#define ltq_eiu_r32(x)		ltq_r32(ltq_eiu_membase + (x))
+
+static unsigned short ltq_eiu_irq[MAX_EIU] = {
+	LTQ_EIU_IR0,
+	LTQ_EIU_IR1,
+	LTQ_EIU_IR2,
+	LTQ_EIU_IR3,
+	LTQ_EIU_IR4,
+	LTQ_EIU_IR5,
+};
+
+static struct resource ltq_icu_resource = {
+	.name	= "icu",
+	.start	= LTQ_ICU_BASE_ADDR,
+	.end	= LTQ_ICU_BASE_ADDR + LTQ_ICU_SIZE - 1,
+	.flags	= IORESOURCE_MEM,
+};
+
+static struct resource ltq_eiu_resource = {
+	.name	= "eiu",
+	.start	= LTQ_EIU_BASE_ADDR,
+	.end	= LTQ_EIU_BASE_ADDR + LTQ_ICU_SIZE - 1,
+	.flags	= IORESOURCE_MEM,
+};
+
+static void __iomem *ltq_icu_membase;
+static void __iomem *ltq_eiu_membase;
+
+void ltq_disable_irq(struct irq_data *d)
+{
+	u32 ier = LTQ_ICU_IM0_IER;
+	int irq_nr = d->irq - INT_NUM_IRQ0;
+
+	ier += LTQ_ICU_OFFSET * (irq_nr / INT_NUM_IM_OFFSET);
+	irq_nr %= INT_NUM_IM_OFFSET;
+	ltq_icu_w32(ltq_icu_r32(ier) & ~(1 << irq_nr), ier);
+}
+
+void ltq_mask_and_ack_irq(struct irq_data *d)
+{
+	u32 ier = LTQ_ICU_IM0_IER;
+	u32 isr = LTQ_ICU_IM0_ISR;
+	int irq_nr = d->irq - INT_NUM_IRQ0;
+
+	ier += LTQ_ICU_OFFSET * (irq_nr / INT_NUM_IM_OFFSET);
+	isr += LTQ_ICU_OFFSET * (irq_nr / INT_NUM_IM_OFFSET);
+	irq_nr %= INT_NUM_IM_OFFSET;
+	ltq_icu_w32(ltq_icu_r32(ier) & ~(1 << irq_nr), ier);
+	ltq_icu_w32((1 << irq_nr), isr);
+}
+
+static void ltq_ack_irq(struct irq_data *d)
+{
+	u32 isr = LTQ_ICU_IM0_ISR;
+	int irq_nr = d->irq - INT_NUM_IRQ0;
+
+	isr += LTQ_ICU_OFFSET * (irq_nr / INT_NUM_IM_OFFSET);
+	irq_nr %= INT_NUM_IM_OFFSET;
+	ltq_icu_w32((1 << irq_nr), isr);
+}
+
+void ltq_enable_irq(struct irq_data *d)
+{
+	u32 ier = LTQ_ICU_IM0_IER;
+	int irq_nr = d->irq - INT_NUM_IRQ0;
+
+	ier += LTQ_ICU_OFFSET  * (irq_nr / INT_NUM_IM_OFFSET);
+	irq_nr %= INT_NUM_IM_OFFSET;
+	ltq_icu_w32(ltq_icu_r32(ier) | (1 << irq_nr), ier);
+}
+
+static unsigned int ltq_startup_eiu_irq(struct irq_data *d)
+{
+	int i;
+	int irq_nr = d->irq - INT_NUM_IRQ0;
+
+	ltq_enable_irq(d);
+	for (i = 0; i < MAX_EIU; i++) {
+		if (irq_nr == ltq_eiu_irq[i]) {
+			/* low level - we should really handle set_type */
+			ltq_eiu_w32(ltq_eiu_r32(LTQ_EIU_EXIN_C) |
+				(0x6 << (i * 4)), LTQ_EIU_EXIN_C);
+			/* clear all pending */
+			ltq_eiu_w32(ltq_eiu_r32(LTQ_EIU_EXIN_INIC) & ~(1 << i),
+				LTQ_EIU_EXIN_INIC);
+			/* enable */
+			ltq_eiu_w32(ltq_eiu_r32(LTQ_EIU_EXIN_INEN) | (1 << i),
+				LTQ_EIU_EXIN_INEN);
+			break;
+		}
+	}
+
+	return 0;
+}
+
+static void ltq_shutdown_eiu_irq(struct irq_data *d)
+{
+	int i;
+	int irq_nr = d->irq - INT_NUM_IRQ0;
+
+	ltq_disable_irq(d);
+	for (i = 0; i < MAX_EIU; i++) {
+		if (irq_nr == ltq_eiu_irq[i]) {
+			/* disable */
+			ltq_eiu_w32(ltq_eiu_r32(LTQ_EIU_EXIN_INEN) & ~(1 << i),
+				LTQ_EIU_EXIN_INEN);
+			break;
+		}
+	}
+}
+
+static struct irq_chip ltq_irq_type = {
+	"icu",
+	.irq_enable = ltq_enable_irq,
+	.irq_disable = ltq_disable_irq,
+	.irq_unmask = ltq_enable_irq,
+	.irq_ack = ltq_ack_irq,
+	.irq_mask = ltq_disable_irq,
+	.irq_mask_ack = ltq_mask_and_ack_irq,
+};
+
+static struct irq_chip ltq_eiu_type = {
+	"eiu",
+	.irq_startup = ltq_startup_eiu_irq,
+	.irq_shutdown = ltq_shutdown_eiu_irq,
+	.irq_enable = ltq_enable_irq,
+	.irq_disable = ltq_disable_irq,
+	.irq_unmask = ltq_enable_irq,
+	.irq_ack = ltq_ack_irq,
+	.irq_mask = ltq_disable_irq,
+	.irq_mask_ack = ltq_mask_and_ack_irq,
+};
+
+static void ltq_hw_irqdispatch(int module)
+{
+	u32 irq;
+
+	irq = ltq_icu_r32(LTQ_ICU_IM0_IOSR + (module * LTQ_ICU_OFFSET));
+	if (irq == 0)
+		return;
+
+	/* silicon bug causes only the msb set to 1 to be valid. all
+	 * other bits might be bogus
+	 */
+	irq = __fls(irq);
+	do_IRQ((int)irq + INT_NUM_IM0_IRL0 + (INT_NUM_IM_OFFSET * module));
+
+	/* if this is a EBU irq, we need to ack it or get a deadlock */
+	if ((irq == LTQ_ICU_EBU_IRQ) && (module == 0))
+		ltq_ebu_w32(ltq_ebu_r32(LTQ_EBU_PCC_ISTAT) | 0x10,
+			LTQ_EBU_PCC_ISTAT);
+}
+
+#define DEFINE_HWx_IRQDISPATCH(x)					\
+	static void ltq_hw ## x ## _irqdispatch(void)			\
+	{								\
+		ltq_hw_irqdispatch(x);					\
+	}
+DEFINE_HWx_IRQDISPATCH(0)
+DEFINE_HWx_IRQDISPATCH(1)
+DEFINE_HWx_IRQDISPATCH(2)
+DEFINE_HWx_IRQDISPATCH(3)
+DEFINE_HWx_IRQDISPATCH(4)
+
+static void ltq_hw5_irqdispatch(void)
+{
+	do_IRQ(MIPS_CPU_TIMER_IRQ);
+}
+
+asmlinkage void plat_irq_dispatch(void)
+{
+	unsigned int pending = read_c0_status() & read_c0_cause() & ST0_IM;
+	unsigned int i;
+
+	if (pending & CAUSEF_IP7) {
+		do_IRQ(MIPS_CPU_TIMER_IRQ);
+		goto out;
+	} else {
+		for (i = 0; i < 5; i++) {
+			if (pending & (CAUSEF_IP2 << i)) {
+				ltq_hw_irqdispatch(i);
+				goto out;
+			}
+		}
+	}
+	pr_alert("Spurious IRQ: CAUSE=0x%08x\n", read_c0_status());
+
+out:
+	return;
+}
+
+static struct irqaction cascade = {
+	.handler = no_action,
+	.flags = IRQF_DISABLED,
+	.name = "cascade",
+};
+
+void __init arch_init_irq(void)
+{
+	int i;
+
+	if (insert_resource(&iomem_resource, &ltq_icu_resource) < 0)
+		panic("Failed to insert icu memory\n");
+
+	if (request_mem_region(ltq_icu_resource.start,
+			resource_size(&ltq_icu_resource), "icu") < 0)
+		panic("Failed to request icu memory\n");
+
+	ltq_icu_membase = ioremap_nocache(ltq_icu_resource.start,
+				resource_size(&ltq_icu_resource));
+	if (!ltq_icu_membase)
+		panic("Failed to remap icu memory\n");
+
+	if (insert_resource(&iomem_resource, &ltq_eiu_resource) < 0)
+		panic("Failed to insert eiu memory\n");
+
+	if (request_mem_region(ltq_eiu_resource.start,
+			resource_size(&ltq_eiu_resource), "eiu") < 0)
+		panic("Failed to request eiu memory\n");
+
+	ltq_eiu_membase = ioremap_nocache(ltq_eiu_resource.start,
+				resource_size(&ltq_eiu_resource));
+	if (!ltq_eiu_membase)
+		panic("Failed to remap eiu memory\n");
+
+	/* make sure all irqs are turned off by default */
+	for (i = 0; i < 5; i++)
+		ltq_icu_w32(0, LTQ_ICU_IM0_IER + (i * LTQ_ICU_OFFSET));
+
+	/* clear all possibly pending interrupts */
+	ltq_icu_w32(~0, LTQ_ICU_IM0_ISR + (i * LTQ_ICU_OFFSET));
+
+	mips_cpu_irq_init();
+
+	for (i = 2; i <= 6; i++)
+		setup_irq(i, &cascade);
+
+	if (cpu_has_vint) {
+		pr_info("Setting up vectored interrupts\n");
+		set_vi_handler(2, ltq_hw0_irqdispatch);
+		set_vi_handler(3, ltq_hw1_irqdispatch);
+		set_vi_handler(4, ltq_hw2_irqdispatch);
+		set_vi_handler(5, ltq_hw3_irqdispatch);
+		set_vi_handler(6, ltq_hw4_irqdispatch);
+		set_vi_handler(7, ltq_hw5_irqdispatch);
+	}
+
+	for (i = INT_NUM_IRQ0;
+		i <= (INT_NUM_IRQ0 + (5 * INT_NUM_IM_OFFSET)); i++)
+		if ((i == LTQ_EIU_IR0) || (i == LTQ_EIU_IR1) ||
+			(i == LTQ_EIU_IR2))
+			irq_set_chip_and_handler(i, &ltq_eiu_type,
+				handle_level_irq);
+		/* EIU3-5 only exist on ar9 and vr9 */
+		else if (((i == LTQ_EIU_IR3) || (i == LTQ_EIU_IR4) ||
+			(i == LTQ_EIU_IR5)) && (ltq_is_ar9() || ltq_is_vr9()))
+			irq_set_chip_and_handler(i, &ltq_eiu_type,
+				handle_level_irq);
+		else
+			irq_set_chip_and_handler(i, &ltq_irq_type,
+				handle_level_irq);
+
+#if !defined(CONFIG_MIPS_MT_SMP) && !defined(CONFIG_MIPS_MT_SMTC)
+	set_c0_status(IE_IRQ0 | IE_IRQ1 | IE_IRQ2 |
+		IE_IRQ3 | IE_IRQ4 | IE_IRQ5);
+#else
+	set_c0_status(IE_SW0 | IE_SW1 | IE_IRQ0 | IE_IRQ1 |
+		IE_IRQ2 | IE_IRQ3 | IE_IRQ4 | IE_IRQ5);
+#endif
+}
+
+unsigned int __cpuinit get_c0_compare_int(void)
+{
+	return CP0_LEGACY_COMPARE_IRQ;
+}
diff -druN linux-2.6.39-libre/arch/mips/lantiq/Kconfig linux-3.0-rc7-libre/arch/mips/lantiq/Kconfig
--- linux-2.6.39-libre/arch/mips/lantiq/Kconfig	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/mips/lantiq/Kconfig	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,23 @@
+if LANTIQ
+
+config SOC_TYPE_XWAY
+	bool
+	default n
+
+choice
+	prompt "SoC Type"
+	default SOC_XWAY
+
+config SOC_AMAZON_SE
+	bool "Amazon SE"
+	select SOC_TYPE_XWAY
+
+config SOC_XWAY
+	bool "XWAY"
+	select SOC_TYPE_XWAY
+	select HW_HAS_PCI
+endchoice
+
+source "arch/mips/lantiq/xway/Kconfig"
+
+endif
diff -druN linux-2.6.39-libre/arch/mips/lantiq/machtypes.h linux-3.0-rc7-libre/arch/mips/lantiq/machtypes.h
--- linux-2.6.39-libre/arch/mips/lantiq/machtypes.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/mips/lantiq/machtypes.h	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,20 @@
+/*
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License version 2 as published
+ *  by the Free Software Foundation.
+ *
+ *  Copyright (C) 2010 John Crispin <blogic@openwrt.org>
+ */
+
+#ifndef _LANTIQ_MACH_H__
+#define _LANTIQ_MACH_H__
+
+#include <asm/mips_machine.h>
+
+enum lantiq_mach_type {
+	LTQ_MACH_GENERIC = 0,
+	LTQ_MACH_EASY50712,	/* Danube evaluation board */
+	LTQ_MACH_EASY50601,	/* Amazon SE evaluation board */
+};
+
+#endif
diff -druN linux-2.6.39-libre/arch/mips/lantiq/Makefile linux-3.0-rc7-libre/arch/mips/lantiq/Makefile
--- linux-2.6.39-libre/arch/mips/lantiq/Makefile	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/mips/lantiq/Makefile	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,11 @@
+# Copyright (C) 2010 John Crispin <blogic@openwrt.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.
+
+obj-y := irq.o setup.o clk.o prom.o devices.o
+
+obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
+
+obj-$(CONFIG_SOC_TYPE_XWAY) += xway/
diff -druN linux-2.6.39-libre/arch/mips/lantiq/Platform linux-3.0-rc7-libre/arch/mips/lantiq/Platform
--- linux-2.6.39-libre/arch/mips/lantiq/Platform	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/mips/lantiq/Platform	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,8 @@
+#
+# Lantiq
+#
+
+platform-$(CONFIG_LANTIQ)	+= lantiq/
+cflags-$(CONFIG_LANTIQ)		+= -I$(srctree)/arch/mips/include/asm/mach-lantiq
+load-$(CONFIG_LANTIQ)		= 0xffffffff80002000
+cflags-$(CONFIG_SOC_TYPE_XWAY)	+= -I$(srctree)/arch/mips/include/asm/mach-lantiq/xway
diff -druN linux-2.6.39-libre/arch/mips/lantiq/prom.c linux-3.0-rc7-libre/arch/mips/lantiq/prom.c
--- linux-2.6.39-libre/arch/mips/lantiq/prom.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/mips/lantiq/prom.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,71 @@
+/*
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License version 2 as published
+ *  by the Free Software Foundation.
+ *
+ * Copyright (C) 2010 John Crispin <blogic@openwrt.org>
+ */
+
+#include <linux/module.h>
+#include <linux/clk.h>
+#include <asm/bootinfo.h>
+#include <asm/time.h>
+
+#include <lantiq.h>
+
+#include "prom.h"
+#include "clk.h"
+
+static struct ltq_soc_info soc_info;
+
+unsigned int ltq_get_cpu_ver(void)
+{
+	return soc_info.rev;
+}
+EXPORT_SYMBOL(ltq_get_cpu_ver);
+
+unsigned int ltq_get_soc_type(void)
+{
+	return soc_info.type;
+}
+EXPORT_SYMBOL(ltq_get_soc_type);
+
+const char *get_system_type(void)
+{
+	return soc_info.sys_type;
+}
+
+void prom_free_prom_memory(void)
+{
+}
+
+static void __init prom_init_cmdline(void)
+{
+	int argc = fw_arg0;
+	char **argv = (char **) KSEG1ADDR(fw_arg1);
+	int i;
+
+	for (i = 0; i < argc; i++) {
+		char *p = (char *)  KSEG1ADDR(argv[i]);
+
+		if (p && *p) {
+			strlcat(arcs_cmdline, p, sizeof(arcs_cmdline));
+			strlcat(arcs_cmdline, " ", sizeof(arcs_cmdline));
+		}
+	}
+}
+
+void __init prom_init(void)
+{
+	struct clk *clk;
+
+	ltq_soc_detect(&soc_info);
+	clk_init();
+	clk = clk_get(0, "cpu");
+	snprintf(soc_info.sys_type, LTQ_SYS_TYPE_LEN - 1, "%s rev1.%d",
+		soc_info.name, soc_info.rev);
+	clk_put(clk);
+	soc_info.sys_type[LTQ_SYS_TYPE_LEN - 1] = '\0';
+	pr_info("SoC: %s\n", soc_info.sys_type);
+	prom_init_cmdline();
+}
diff -druN linux-2.6.39-libre/arch/mips/lantiq/prom.h linux-3.0-rc7-libre/arch/mips/lantiq/prom.h
--- linux-2.6.39-libre/arch/mips/lantiq/prom.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/mips/lantiq/prom.h	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,25 @@
+/*
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License version 2 as published
+ *  by the Free Software Foundation.
+ *
+ * Copyright (C) 2010 John Crispin <blogic@openwrt.org>
+ */
+
+#ifndef _LTQ_PROM_H__
+#define _LTQ_PROM_H__
+
+#define LTQ_SYS_TYPE_LEN	0x100
+
+struct ltq_soc_info {
+	unsigned char *name;
+	unsigned int rev;
+	unsigned int partnum;
+	unsigned int type;
+	unsigned char sys_type[LTQ_SYS_TYPE_LEN];
+};
+
+extern void ltq_soc_detect(struct ltq_soc_info *i);
+extern void ltq_soc_setup(void);
+
+#endif
diff -druN linux-2.6.39-libre/arch/mips/lantiq/setup.c linux-3.0-rc7-libre/arch/mips/lantiq/setup.c
--- linux-2.6.39-libre/arch/mips/lantiq/setup.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/mips/lantiq/setup.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,66 @@
+/*
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License version 2 as published
+ *  by the Free Software Foundation.
+ *
+ * Copyright (C) 2010 John Crispin <blogic@openwrt.org>
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/io.h>
+#include <linux/ioport.h>
+#include <asm/bootinfo.h>
+
+#include <lantiq_soc.h>
+
+#include "machtypes.h"
+#include "devices.h"
+#include "prom.h"
+
+void __init plat_mem_setup(void)
+{
+	/* assume 16M as default incase uboot fails to pass proper ramsize */
+	unsigned long memsize = 16;
+	char **envp = (char **) KSEG1ADDR(fw_arg2);
+
+	ioport_resource.start = IOPORT_RESOURCE_START;
+	ioport_resource.end = IOPORT_RESOURCE_END;
+	iomem_resource.start = IOMEM_RESOURCE_START;
+	iomem_resource.end = IOMEM_RESOURCE_END;
+
+	set_io_port_base((unsigned long) KSEG1);
+
+	while (*envp) {
+		char *e = (char *)KSEG1ADDR(*envp);
+		if (!strncmp(e, "memsize=", 8)) {
+			e += 8;
+			if (strict_strtoul(e, 0, &memsize))
+				pr_warn("bad memsize specified\n");
+		}
+		envp++;
+	}
+	memsize *= 1024 * 1024;
+	add_memory_region(0x00000000, memsize, BOOT_MEM_RAM);
+}
+
+static int __init
+lantiq_setup(void)
+{
+	ltq_soc_setup();
+	mips_machine_setup();
+	return 0;
+}
+
+arch_initcall(lantiq_setup);
+
+static void __init
+lantiq_generic_init(void)
+{
+	/* Nothing to do */
+}
+
+MIPS_MACHINE(LTQ_MACH_GENERIC,
+	     "Generic",
+	     "Generic Lantiq based board",
+	     lantiq_generic_init);
diff -druN linux-2.6.39-libre/arch/mips/lantiq/xway/clk-ase.c linux-3.0-rc7-libre/arch/mips/lantiq/xway/clk-ase.c
--- linux-2.6.39-libre/arch/mips/lantiq/xway/clk-ase.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/mips/lantiq/xway/clk-ase.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,48 @@
+/*
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License version 2 as published
+ *  by the Free Software Foundation.
+ *
+ *  Copyright (C) 2011 John Crispin <blogic@openwrt.org>
+ */
+
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/clk.h>
+
+#include <asm/time.h>
+#include <asm/irq.h>
+#include <asm/div64.h>
+
+#include <lantiq_soc.h>
+
+/* cgu registers */
+#define LTQ_CGU_SYS	0x0010
+
+unsigned int ltq_get_io_region_clock(void)
+{
+	return CLOCK_133M;
+}
+EXPORT_SYMBOL(ltq_get_io_region_clock);
+
+unsigned int ltq_get_fpi_bus_clock(int fpi)
+{
+	return CLOCK_133M;
+}
+EXPORT_SYMBOL(ltq_get_fpi_bus_clock);
+
+unsigned int ltq_get_cpu_hz(void)
+{
+	if (ltq_cgu_r32(LTQ_CGU_SYS) & (1 << 5))
+		return CLOCK_266M;
+	else
+		return CLOCK_133M;
+}
+EXPORT_SYMBOL(ltq_get_cpu_hz);
+
+unsigned int ltq_get_fpi_hz(void)
+{
+	return CLOCK_133M;
+}
+EXPORT_SYMBOL(ltq_get_fpi_hz);
diff -druN linux-2.6.39-libre/arch/mips/lantiq/xway/clk-xway.c linux-3.0-rc7-libre/arch/mips/lantiq/xway/clk-xway.c
--- linux-2.6.39-libre/arch/mips/lantiq/xway/clk-xway.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/mips/lantiq/xway/clk-xway.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,223 @@
+/*
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License version 2 as published
+ *  by the Free Software Foundation.
+ *
+ *  Copyright (C) 2010 John Crispin <blogic@openwrt.org>
+ */
+
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/clk.h>
+
+#include <asm/time.h>
+#include <asm/irq.h>
+#include <asm/div64.h>
+
+#include <lantiq_soc.h>
+
+static unsigned int ltq_ram_clocks[] = {
+	CLOCK_167M, CLOCK_133M, CLOCK_111M, CLOCK_83M };
+#define DDR_HZ ltq_ram_clocks[ltq_cgu_r32(LTQ_CGU_SYS) & 0x3]
+
+#define BASIC_FREQUENCY_1	35328000
+#define BASIC_FREQUENCY_2	36000000
+#define BASIS_REQUENCY_USB	12000000
+
+#define GET_BITS(x, msb, lsb) \
+	(((x) & ((1 << ((msb) + 1)) - 1)) >> (lsb))
+
+#define LTQ_CGU_PLL0_CFG	0x0004
+#define LTQ_CGU_PLL1_CFG	0x0008
+#define LTQ_CGU_PLL2_CFG	0x000C
+#define LTQ_CGU_SYS		0x0010
+#define LTQ_CGU_UPDATE		0x0014
+#define LTQ_CGU_IF_CLK		0x0018
+#define LTQ_CGU_OSC_CON		0x001C
+#define LTQ_CGU_SMD		0x0020
+#define LTQ_CGU_CT1SR		0x0028
+#define LTQ_CGU_CT2SR		0x002C
+#define LTQ_CGU_PCMCR		0x0030
+#define LTQ_CGU_PCI_CR		0x0034
+#define LTQ_CGU_PD_PC		0x0038
+#define LTQ_CGU_FMR		0x003C
+
+#define CGU_PLL0_PHASE_DIVIDER_ENABLE	\
+	(ltq_cgu_r32(LTQ_CGU_PLL0_CFG) & (1 << 31))
+#define CGU_PLL0_BYPASS			\
+	(ltq_cgu_r32(LTQ_CGU_PLL0_CFG) & (1 << 30))
+#define CGU_PLL0_CFG_DSMSEL		\
+	(ltq_cgu_r32(LTQ_CGU_PLL0_CFG) & (1 << 28))
+#define CGU_PLL0_CFG_FRAC_EN		\
+	(ltq_cgu_r32(LTQ_CGU_PLL0_CFG) & (1 << 27))
+#define CGU_PLL1_SRC			\
+	(ltq_cgu_r32(LTQ_CGU_PLL1_CFG) & (1 << 31))
+#define CGU_PLL2_PHASE_DIVIDER_ENABLE	\
+	(ltq_cgu_r32(LTQ_CGU_PLL2_CFG) & (1 << 20))
+#define CGU_SYS_FPI_SEL			(1 << 6)
+#define CGU_SYS_DDR_SEL			0x3
+#define CGU_PLL0_SRC			(1 << 29)
+
+#define CGU_PLL0_CFG_PLLK	GET_BITS(ltq_cgu_r32(LTQ_CGU_PLL0_CFG), 26, 17)
+#define CGU_PLL0_CFG_PLLN	GET_BITS(ltq_cgu_r32(LTQ_CGU_PLL0_CFG), 12, 6)
+#define CGU_PLL0_CFG_PLLM	GET_BITS(ltq_cgu_r32(LTQ_CGU_PLL0_CFG), 5, 2)
+#define CGU_PLL2_SRC		GET_BITS(ltq_cgu_r32(LTQ_CGU_PLL2_CFG), 18, 17)
+#define CGU_PLL2_CFG_INPUT_DIV	GET_BITS(ltq_cgu_r32(LTQ_CGU_PLL2_CFG), 16, 13)
+
+static unsigned int ltq_get_pll0_fdiv(void);
+
+static inline unsigned int get_input_clock(int pll)
+{
+	switch (pll) {
+	case 0:
+		if (ltq_cgu_r32(LTQ_CGU_PLL0_CFG) & CGU_PLL0_SRC)
+			return BASIS_REQUENCY_USB;
+		else if (CGU_PLL0_PHASE_DIVIDER_ENABLE)
+			return BASIC_FREQUENCY_1;
+		else
+			return BASIC_FREQUENCY_2;
+	case 1:
+		if (CGU_PLL1_SRC)
+			return BASIS_REQUENCY_USB;
+		else if (CGU_PLL0_PHASE_DIVIDER_ENABLE)
+			return BASIC_FREQUENCY_1;
+		else
+			return BASIC_FREQUENCY_2;
+	case 2:
+		switch (CGU_PLL2_SRC) {
+		case 0:
+			return ltq_get_pll0_fdiv();
+		case 1:
+			return CGU_PLL2_PHASE_DIVIDER_ENABLE ?
+				BASIC_FREQUENCY_1 :
+				BASIC_FREQUENCY_2;
+		case 2:
+			return BASIS_REQUENCY_USB;
+		}
+	default:
+		return 0;
+	}
+}
+
+static inline unsigned int cal_dsm(int pll, unsigned int num, unsigned int den)
+{
+	u64 res, clock = get_input_clock(pll);
+
+	res = num * clock;
+	do_div(res, den);
+	return res;
+}
+
+static inline unsigned int mash_dsm(int pll, unsigned int M, unsigned int N,
+	unsigned int K)
+{
+	unsigned int num = ((N + 1) << 10) + K;
+	unsigned int den = (M + 1) << 10;
+
+	return cal_dsm(pll, num, den);
+}
+
+static inline unsigned int ssff_dsm_1(int pll, unsigned int M, unsigned int N,
+	unsigned int K)
+{
+	unsigned int num = ((N + 1) << 11) + K + 512;
+	unsigned int den = (M + 1) << 11;
+
+	return cal_dsm(pll, num, den);
+}
+
+static inline unsigned int ssff_dsm_2(int pll, unsigned int M, unsigned int N,
+	unsigned int K)
+{
+	unsigned int num = K >= 512 ?
+		((N + 1) << 12) + K - 512 : ((N + 1) << 12) + K + 3584;
+	unsigned int den = (M + 1) << 12;
+
+	return cal_dsm(pll, num, den);
+}
+
+static inline unsigned int dsm(int pll, unsigned int M, unsigned int N,
+	unsigned int K, unsigned int dsmsel, unsigned int phase_div_en)
+{
+	if (!dsmsel)
+		return mash_dsm(pll, M, N, K);
+	else if (!phase_div_en)
+		return mash_dsm(pll, M, N, K);
+	else
+		return ssff_dsm_2(pll, M, N, K);
+}
+
+static inline unsigned int ltq_get_pll0_fosc(void)
+{
+	if (CGU_PLL0_BYPASS)
+		return get_input_clock(0);
+	else
+		return !CGU_PLL0_CFG_FRAC_EN
+			? dsm(0, CGU_PLL0_CFG_PLLM, CGU_PLL0_CFG_PLLN, 0,
+				CGU_PLL0_CFG_DSMSEL,
+				CGU_PLL0_PHASE_DIVIDER_ENABLE)
+			: dsm(0, CGU_PLL0_CFG_PLLM, CGU_PLL0_CFG_PLLN,
+				CGU_PLL0_CFG_PLLK, CGU_PLL0_CFG_DSMSEL,
+				CGU_PLL0_PHASE_DIVIDER_ENABLE);
+}
+
+static unsigned int ltq_get_pll0_fdiv(void)
+{
+	unsigned int div = CGU_PLL2_CFG_INPUT_DIV + 1;
+
+	return (ltq_get_pll0_fosc() + (div >> 1)) / div;
+}
+
+unsigned int ltq_get_io_region_clock(void)
+{
+	unsigned int ret = ltq_get_pll0_fosc();
+
+	switch (ltq_cgu_r32(LTQ_CGU_PLL2_CFG) & CGU_SYS_DDR_SEL) {
+	default:
+	case 0:
+		return (ret + 1) / 2;
+	case 1:
+		return (ret * 2 + 2) / 5;
+	case 2:
+		return (ret + 1) / 3;
+	case 3:
+		return (ret + 2) / 4;
+	}
+}
+EXPORT_SYMBOL(ltq_get_io_region_clock);
+
+unsigned int ltq_get_fpi_bus_clock(int fpi)
+{
+	unsigned int ret = ltq_get_io_region_clock();
+
+	if ((fpi == 2) && (ltq_cgu_r32(LTQ_CGU_SYS) & CGU_SYS_FPI_SEL))
+		ret >>= 1;
+	return ret;
+}
+EXPORT_SYMBOL(ltq_get_fpi_bus_clock);
+
+unsigned int ltq_get_cpu_hz(void)
+{
+	switch (ltq_cgu_r32(LTQ_CGU_SYS) & 0xc) {
+	case 0:
+		return CLOCK_333M;
+	case 4:
+		return DDR_HZ;
+	case 8:
+		return DDR_HZ << 1;
+	default:
+		return DDR_HZ >> 1;
+	}
+}
+EXPORT_SYMBOL(ltq_get_cpu_hz);
+
+unsigned int ltq_get_fpi_hz(void)
+{
+	unsigned int ddr_clock = DDR_HZ;
+
+	if (ltq_cgu_r32(LTQ_CGU_SYS) & 0x40)
+		return ddr_clock >> 1;
+	return ddr_clock;
+}
+EXPORT_SYMBOL(ltq_get_fpi_hz);
diff -druN linux-2.6.39-libre/arch/mips/lantiq/xway/devices.c linux-3.0-rc7-libre/arch/mips/lantiq/xway/devices.c
--- linux-2.6.39-libre/arch/mips/lantiq/xway/devices.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/mips/lantiq/xway/devices.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,121 @@
+/*
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License version 2 as published
+ *  by the Free Software Foundation.
+ *
+ *  Copyright (C) 2010 John Crispin <blogic@openwrt.org>
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/string.h>
+#include <linux/mtd/physmap.h>
+#include <linux/kernel.h>
+#include <linux/reboot.h>
+#include <linux/platform_device.h>
+#include <linux/leds.h>
+#include <linux/etherdevice.h>
+#include <linux/reboot.h>
+#include <linux/time.h>
+#include <linux/io.h>
+#include <linux/gpio.h>
+#include <linux/leds.h>
+
+#include <asm/bootinfo.h>
+#include <asm/irq.h>
+
+#include <lantiq_soc.h>
+#include <lantiq_irq.h>
+#include <lantiq_platform.h>
+
+#include "devices.h"
+
+/* gpio */
+static struct resource ltq_gpio_resource[] = {
+	{
+		.name	= "gpio0",
+		.start  = LTQ_GPIO0_BASE_ADDR,
+		.end    = LTQ_GPIO0_BASE_ADDR + LTQ_GPIO_SIZE - 1,
+		.flags  = IORESOURCE_MEM,
+	}, {
+		.name	= "gpio1",
+		.start  = LTQ_GPIO1_BASE_ADDR,
+		.end    = LTQ_GPIO1_BASE_ADDR + LTQ_GPIO_SIZE - 1,
+		.flags  = IORESOURCE_MEM,
+	}, {
+		.name	= "gpio2",
+		.start  = LTQ_GPIO2_BASE_ADDR,
+		.end    = LTQ_GPIO2_BASE_ADDR + LTQ_GPIO_SIZE - 1,
+		.flags  = IORESOURCE_MEM,
+	}
+};
+
+void __init ltq_register_gpio(void)
+{
+	platform_device_register_simple("ltq_gpio", 0,
+		&ltq_gpio_resource[0], 1);
+	platform_device_register_simple("ltq_gpio", 1,
+		&ltq_gpio_resource[1], 1);
+
+	/* AR9 and VR9 have an extra gpio block */
+	if (ltq_is_ar9() || ltq_is_vr9()) {
+		platform_device_register_simple("ltq_gpio", 2,
+			&ltq_gpio_resource[2], 1);
+	}
+}
+
+/* serial to parallel conversion */
+static struct resource ltq_stp_resource = {
+	.name   = "stp",
+	.start  = LTQ_STP_BASE_ADDR,
+	.end    = LTQ_STP_BASE_ADDR + LTQ_STP_SIZE - 1,
+	.flags  = IORESOURCE_MEM,
+};
+
+void __init ltq_register_gpio_stp(void)
+{
+	platform_device_register_simple("ltq_stp", 0, &ltq_stp_resource, 1);
+}
+
+/* asc ports - amazon se has its own serial mapping */
+static struct resource ltq_ase_asc_resources[] = {
+	{
+		.name	= "asc0",
+		.start  = LTQ_ASC1_BASE_ADDR,
+		.end    = LTQ_ASC1_BASE_ADDR + LTQ_ASC_SIZE - 1,
+		.flags  = IORESOURCE_MEM,
+	},
+	IRQ_RES(tx, LTQ_ASC_ASE_TIR),
+	IRQ_RES(rx, LTQ_ASC_ASE_RIR),
+	IRQ_RES(err, LTQ_ASC_ASE_EIR),
+};
+
+void __init ltq_register_ase_asc(void)
+{
+	platform_device_register_simple("ltq_asc", 0,
+		ltq_ase_asc_resources, ARRAY_SIZE(ltq_ase_asc_resources));
+}
+
+/* ethernet */
+static struct resource ltq_etop_resources = {
+	.name	= "etop",
+	.start	= LTQ_ETOP_BASE_ADDR,
+	.end	= LTQ_ETOP_BASE_ADDR + LTQ_ETOP_SIZE - 1,
+	.flags	= IORESOURCE_MEM,
+};
+
+static struct platform_device ltq_etop = {
+	.name		= "ltq_etop",
+	.resource	= &ltq_etop_resources,
+	.num_resources	= 1,
+};
+
+void __init
+ltq_register_etop(struct ltq_eth_data *eth)
+{
+	if (eth) {
+		ltq_etop.dev.platform_data = eth;
+		platform_device_register(&ltq_etop);
+	}
+}
diff -druN linux-2.6.39-libre/arch/mips/lantiq/xway/devices.h linux-3.0-rc7-libre/arch/mips/lantiq/xway/devices.h
--- linux-2.6.39-libre/arch/mips/lantiq/xway/devices.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/mips/lantiq/xway/devices.h	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,20 @@
+/*
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License version 2 as published
+ *  by the Free Software Foundation.
+ *
+ *  Copyright (C) 2010 John Crispin <blogic@openwrt.org>
+ */
+
+#ifndef _LTQ_DEVICES_XWAY_H__
+#define _LTQ_DEVICES_XWAY_H__
+
+#include "../devices.h"
+#include <linux/phy.h>
+
+extern void ltq_register_gpio(void);
+extern void ltq_register_gpio_stp(void);
+extern void ltq_register_ase_asc(void);
+extern void ltq_register_etop(struct ltq_eth_data *eth);
+
+#endif
diff -druN linux-2.6.39-libre/arch/mips/lantiq/xway/dma.c linux-3.0-rc7-libre/arch/mips/lantiq/xway/dma.c
--- linux-2.6.39-libre/arch/mips/lantiq/xway/dma.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/mips/lantiq/xway/dma.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,253 @@
+/*
+ *   This program is free software; you can redistribute it and/or modify it
+ *   under the terms of the GNU General Public License version 2 as published
+ *   by the Free Software Foundation.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+ *
+ *   Copyright (C) 2011 John Crispin <blogic@openwrt.org>
+ */
+
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/dma-mapping.h>
+
+#include <lantiq_soc.h>
+#include <xway_dma.h>
+
+#define LTQ_DMA_CTRL		0x10
+#define LTQ_DMA_CPOLL		0x14
+#define LTQ_DMA_CS		0x18
+#define LTQ_DMA_CCTRL		0x1C
+#define LTQ_DMA_CDBA		0x20
+#define LTQ_DMA_CDLEN		0x24
+#define LTQ_DMA_CIS		0x28
+#define LTQ_DMA_CIE		0x2C
+#define LTQ_DMA_PS		0x40
+#define LTQ_DMA_PCTRL		0x44
+#define LTQ_DMA_IRNEN		0xf4
+
+#define DMA_DESCPT		BIT(3)		/* descriptor complete irq */
+#define DMA_TX			BIT(8)		/* TX channel direction */
+#define DMA_CHAN_ON		BIT(0)		/* channel on / off bit */
+#define DMA_PDEN		BIT(6)		/* enable packet drop */
+#define DMA_CHAN_RST		BIT(1)		/* channel on / off bit */
+#define DMA_RESET		BIT(0)		/* channel on / off bit */
+#define DMA_IRQ_ACK		0x7e		/* IRQ status register */
+#define DMA_POLL		BIT(31)		/* turn on channel polling */
+#define DMA_CLK_DIV4		BIT(6)		/* polling clock divider */
+#define DMA_2W_BURST		BIT(1)		/* 2 word burst length */
+#define DMA_MAX_CHANNEL		20		/* the soc has 20 channels */
+#define DMA_ETOP_ENDIANESS	(0xf << 8) /* endianess swap etop channels */
+#define DMA_WEIGHT	(BIT(17) | BIT(16))	/* default channel wheight */
+
+#define ltq_dma_r32(x)			ltq_r32(ltq_dma_membase + (x))
+#define ltq_dma_w32(x, y)		ltq_w32(x, ltq_dma_membase + (y))
+#define ltq_dma_w32_mask(x, y, z)	ltq_w32_mask(x, y, \
+						ltq_dma_membase + (z))
+
+static struct resource ltq_dma_resource = {
+	.name	= "dma",
+	.start	= LTQ_DMA_BASE_ADDR,
+	.end	= LTQ_DMA_BASE_ADDR + LTQ_DMA_SIZE - 1,
+	.flags  = IORESOURCE_MEM,
+};
+
+static void __iomem *ltq_dma_membase;
+
+void
+ltq_dma_enable_irq(struct ltq_dma_channel *ch)
+{
+	unsigned long flags;
+
+	local_irq_save(flags);
+	ltq_dma_w32(ch->nr, LTQ_DMA_CS);
+	ltq_dma_w32_mask(0, 1 << ch->nr, LTQ_DMA_IRNEN);
+	local_irq_restore(flags);
+}
+EXPORT_SYMBOL_GPL(ltq_dma_enable_irq);
+
+void
+ltq_dma_disable_irq(struct ltq_dma_channel *ch)
+{
+	unsigned long flags;
+
+	local_irq_save(flags);
+	ltq_dma_w32(ch->nr, LTQ_DMA_CS);
+	ltq_dma_w32_mask(1 << ch->nr, 0, LTQ_DMA_IRNEN);
+	local_irq_restore(flags);
+}
+EXPORT_SYMBOL_GPL(ltq_dma_disable_irq);
+
+void
+ltq_dma_ack_irq(struct ltq_dma_channel *ch)
+{
+	unsigned long flags;
+
+	local_irq_save(flags);
+	ltq_dma_w32(ch->nr, LTQ_DMA_CS);
+	ltq_dma_w32(DMA_IRQ_ACK, LTQ_DMA_CIS);
+	local_irq_restore(flags);
+}
+EXPORT_SYMBOL_GPL(ltq_dma_ack_irq);
+
+void
+ltq_dma_open(struct ltq_dma_channel *ch)
+{
+	unsigned long flag;
+
+	local_irq_save(flag);
+	ltq_dma_w32(ch->nr, LTQ_DMA_CS);
+	ltq_dma_w32_mask(0, DMA_CHAN_ON, LTQ_DMA_CCTRL);
+	ltq_dma_enable_irq(ch);
+	local_irq_restore(flag);
+}
+EXPORT_SYMBOL_GPL(ltq_dma_open);
+
+void
+ltq_dma_close(struct ltq_dma_channel *ch)
+{
+	unsigned long flag;
+
+	local_irq_save(flag);
+	ltq_dma_w32(ch->nr, LTQ_DMA_CS);
+	ltq_dma_w32_mask(DMA_CHAN_ON, 0, LTQ_DMA_CCTRL);
+	ltq_dma_disable_irq(ch);
+	local_irq_restore(flag);
+}
+EXPORT_SYMBOL_GPL(ltq_dma_close);
+
+static void
+ltq_dma_alloc(struct ltq_dma_channel *ch)
+{
+	unsigned long flags;
+
+	ch->desc = 0;
+	ch->desc_base = dma_alloc_coherent(NULL,
+				LTQ_DESC_NUM * LTQ_DESC_SIZE,
+				&ch->phys, GFP_ATOMIC);
+	memset(ch->desc_base, 0, LTQ_DESC_NUM * LTQ_DESC_SIZE);
+
+	local_irq_save(flags);
+	ltq_dma_w32(ch->nr, LTQ_DMA_CS);
+	ltq_dma_w32(ch->phys, LTQ_DMA_CDBA);
+	ltq_dma_w32(LTQ_DESC_NUM, LTQ_DMA_CDLEN);
+	ltq_dma_w32_mask(DMA_CHAN_ON, 0, LTQ_DMA_CCTRL);
+	wmb();
+	ltq_dma_w32_mask(0, DMA_CHAN_RST, LTQ_DMA_CCTRL);
+	while (ltq_dma_r32(LTQ_DMA_CCTRL) & DMA_CHAN_RST)
+		;
+	local_irq_restore(flags);
+}
+
+void
+ltq_dma_alloc_tx(struct ltq_dma_channel *ch)
+{
+	unsigned long flags;
+
+	ltq_dma_alloc(ch);
+
+	local_irq_save(flags);
+	ltq_dma_w32(DMA_DESCPT, LTQ_DMA_CIE);
+	ltq_dma_w32_mask(0, 1 << ch->nr, LTQ_DMA_IRNEN);
+	ltq_dma_w32(DMA_WEIGHT | DMA_TX, LTQ_DMA_CCTRL);
+	local_irq_restore(flags);
+}
+EXPORT_SYMBOL_GPL(ltq_dma_alloc_tx);
+
+void
+ltq_dma_alloc_rx(struct ltq_dma_channel *ch)
+{
+	unsigned long flags;
+
+	ltq_dma_alloc(ch);
+
+	local_irq_save(flags);
+	ltq_dma_w32(DMA_DESCPT, LTQ_DMA_CIE);
+	ltq_dma_w32_mask(0, 1 << ch->nr, LTQ_DMA_IRNEN);
+	ltq_dma_w32(DMA_WEIGHT, LTQ_DMA_CCTRL);
+	local_irq_restore(flags);
+}
+EXPORT_SYMBOL_GPL(ltq_dma_alloc_rx);
+
+void
+ltq_dma_free(struct ltq_dma_channel *ch)
+{
+	if (!ch->desc_base)
+		return;
+	ltq_dma_close(ch);
+	dma_free_coherent(NULL, LTQ_DESC_NUM * LTQ_DESC_SIZE,
+		ch->desc_base, ch->phys);
+}
+EXPORT_SYMBOL_GPL(ltq_dma_free);
+
+void
+ltq_dma_init_port(int p)
+{
+	ltq_dma_w32(p, LTQ_DMA_PS);
+	switch (p) {
+	case DMA_PORT_ETOP:
+		/*
+		 * Tell the DMA engine to swap the endianess of data frames and
+		 * drop packets if the channel arbitration fails.
+		 */
+		ltq_dma_w32_mask(0, DMA_ETOP_ENDIANESS | DMA_PDEN,
+			LTQ_DMA_PCTRL);
+		break;
+
+	case DMA_PORT_DEU:
+		ltq_dma_w32((DMA_2W_BURST << 4) | (DMA_2W_BURST << 2),
+			LTQ_DMA_PCTRL);
+		break;
+
+	default:
+		break;
+	}
+}
+EXPORT_SYMBOL_GPL(ltq_dma_init_port);
+
+int __init
+ltq_dma_init(void)
+{
+	int i;
+
+	/* insert and request the memory region */
+	if (insert_resource(&iomem_resource, &ltq_dma_resource) < 0)
+		panic("Failed to insert dma memory\n");
+
+	if (request_mem_region(ltq_dma_resource.start,
+			resource_size(&ltq_dma_resource), "dma") < 0)
+		panic("Failed to request dma memory\n");
+
+	/* remap dma register range */
+	ltq_dma_membase = ioremap_nocache(ltq_dma_resource.start,
+				resource_size(&ltq_dma_resource));
+	if (!ltq_dma_membase)
+		panic("Failed to remap dma memory\n");
+
+	/* power up and reset the dma engine */
+	ltq_pmu_enable(PMU_DMA);
+	ltq_dma_w32_mask(0, DMA_RESET, LTQ_DMA_CTRL);
+
+	/* disable all interrupts */
+	ltq_dma_w32(0, LTQ_DMA_IRNEN);
+
+	/* reset/configure each channel */
+	for (i = 0; i < DMA_MAX_CHANNEL; i++) {
+		ltq_dma_w32(i, LTQ_DMA_CS);
+		ltq_dma_w32(DMA_CHAN_RST, LTQ_DMA_CCTRL);
+		ltq_dma_w32(DMA_POLL | DMA_CLK_DIV4, LTQ_DMA_CPOLL);
+		ltq_dma_w32_mask(DMA_CHAN_ON, 0, LTQ_DMA_CCTRL);
+	}
+	return 0;
+}
+
+postcore_initcall(ltq_dma_init);
diff -druN linux-2.6.39-libre/arch/mips/lantiq/xway/ebu.c linux-3.0-rc7-libre/arch/mips/lantiq/xway/ebu.c
--- linux-2.6.39-libre/arch/mips/lantiq/xway/ebu.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/mips/lantiq/xway/ebu.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,53 @@
+/*
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License version 2 as published
+ *  by the Free Software Foundation.
+ *
+ *  EBU - the external bus unit attaches PCI, NOR and NAND
+ *
+ *  Copyright (C) 2010 John Crispin <blogic@openwrt.org>
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/version.h>
+#include <linux/ioport.h>
+
+#include <lantiq_soc.h>
+
+/* all access to the ebu must be locked */
+DEFINE_SPINLOCK(ebu_lock);
+EXPORT_SYMBOL_GPL(ebu_lock);
+
+static struct resource ltq_ebu_resource = {
+	.name	= "ebu",
+	.start	= LTQ_EBU_BASE_ADDR,
+	.end	= LTQ_EBU_BASE_ADDR + LTQ_EBU_SIZE - 1,
+	.flags	= IORESOURCE_MEM,
+};
+
+/* remapped base addr of the clock unit and external bus unit */
+void __iomem *ltq_ebu_membase;
+
+static int __init lantiq_ebu_init(void)
+{
+	/* insert and request the memory region */
+	if (insert_resource(&iomem_resource, &ltq_ebu_resource) < 0)
+		panic("Failed to insert ebu memory\n");
+
+	if (request_mem_region(ltq_ebu_resource.start,
+			resource_size(&ltq_ebu_resource), "ebu") < 0)
+		panic("Failed to request ebu memory\n");
+
+	/* remap ebu register range */
+	ltq_ebu_membase = ioremap_nocache(ltq_ebu_resource.start,
+				resource_size(&ltq_ebu_resource));
+	if (!ltq_ebu_membase)
+		panic("Failed to remap ebu memory\n");
+
+	/* make sure to unprotect the memory region where flash is located */
+	ltq_ebu_w32(ltq_ebu_r32(LTQ_EBU_BUSCON0) & ~EBU_WRDIS, LTQ_EBU_BUSCON0);
+	return 0;
+}
+
+postcore_initcall(lantiq_ebu_init);
diff -druN linux-2.6.39-libre/arch/mips/lantiq/xway/gpio.c linux-3.0-rc7-libre/arch/mips/lantiq/xway/gpio.c
--- linux-2.6.39-libre/arch/mips/lantiq/xway/gpio.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/mips/lantiq/xway/gpio.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,195 @@
+/*
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License version 2 as published
+ *  by the Free Software Foundation.
+ *
+ *  Copyright (C) 2010 John Crispin <blogic@openwrt.org>
+ */
+
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/gpio.h>
+#include <linux/ioport.h>
+#include <linux/io.h>
+
+#include <lantiq_soc.h>
+
+#define LTQ_GPIO_OUT		0x00
+#define LTQ_GPIO_IN		0x04
+#define LTQ_GPIO_DIR		0x08
+#define LTQ_GPIO_ALTSEL0	0x0C
+#define LTQ_GPIO_ALTSEL1	0x10
+#define LTQ_GPIO_OD		0x14
+
+#define PINS_PER_PORT		16
+#define MAX_PORTS		3
+
+#define ltq_gpio_getbit(m, r, p)	(!!(ltq_r32(m + r) & (1 << p)))
+#define ltq_gpio_setbit(m, r, p)	ltq_w32_mask(0, (1 << p), m + r)
+#define ltq_gpio_clearbit(m, r, p)	ltq_w32_mask((1 << p), 0, m + r)
+
+struct ltq_gpio {
+	void __iomem *membase;
+	struct gpio_chip chip;
+};
+
+static struct ltq_gpio ltq_gpio_port[MAX_PORTS];
+
+int gpio_to_irq(unsigned int gpio)
+{
+	return -EINVAL;
+}
+EXPORT_SYMBOL(gpio_to_irq);
+
+int irq_to_gpio(unsigned int gpio)
+{
+	return -EINVAL;
+}
+EXPORT_SYMBOL(irq_to_gpio);
+
+int ltq_gpio_request(unsigned int pin, unsigned int alt0,
+	unsigned int alt1, unsigned int dir, const char *name)
+{
+	int id = 0;
+
+	if (pin >= (MAX_PORTS * PINS_PER_PORT))
+		return -EINVAL;
+	if (gpio_request(pin, name)) {
+		pr_err("failed to setup lantiq gpio: %s\n", name);
+		return -EBUSY;
+	}
+	if (dir)
+		gpio_direction_output(pin, 1);
+	else
+		gpio_direction_input(pin);
+	while (pin >= PINS_PER_PORT) {
+		pin -= PINS_PER_PORT;
+		id++;
+	}
+	if (alt0)
+		ltq_gpio_setbit(ltq_gpio_port[id].membase,
+			LTQ_GPIO_ALTSEL0, pin);
+	else
+		ltq_gpio_clearbit(ltq_gpio_port[id].membase,
+			LTQ_GPIO_ALTSEL0, pin);
+	if (alt1)
+		ltq_gpio_setbit(ltq_gpio_port[id].membase,
+			LTQ_GPIO_ALTSEL1, pin);
+	else
+		ltq_gpio_clearbit(ltq_gpio_port[id].membase,
+			LTQ_GPIO_ALTSEL1, pin);
+	return 0;
+}
+EXPORT_SYMBOL(ltq_gpio_request);
+
+static void ltq_gpio_set(struct gpio_chip *chip, unsigned int offset, int value)
+{
+	struct ltq_gpio *ltq_gpio = container_of(chip, struct ltq_gpio, chip);
+
+	if (value)
+		ltq_gpio_setbit(ltq_gpio->membase, LTQ_GPIO_OUT, offset);
+	else
+		ltq_gpio_clearbit(ltq_gpio->membase, LTQ_GPIO_OUT, offset);
+}
+
+static int ltq_gpio_get(struct gpio_chip *chip, unsigned int offset)
+{
+	struct ltq_gpio *ltq_gpio = container_of(chip, struct ltq_gpio, chip);
+
+	return ltq_gpio_getbit(ltq_gpio->membase, LTQ_GPIO_IN, offset);
+}
+
+static int ltq_gpio_direction_input(struct gpio_chip *chip, unsigned int offset)
+{
+	struct ltq_gpio *ltq_gpio = container_of(chip, struct ltq_gpio, chip);
+
+	ltq_gpio_clearbit(ltq_gpio->membase, LTQ_GPIO_OD, offset);
+	ltq_gpio_clearbit(ltq_gpio->membase, LTQ_GPIO_DIR, offset);
+
+	return 0;
+}
+
+static int ltq_gpio_direction_output(struct gpio_chip *chip,
+	unsigned int offset, int value)
+{
+	struct ltq_gpio *ltq_gpio = container_of(chip, struct ltq_gpio, chip);
+
+	ltq_gpio_setbit(ltq_gpio->membase, LTQ_GPIO_OD, offset);
+	ltq_gpio_setbit(ltq_gpio->membase, LTQ_GPIO_DIR, offset);
+	ltq_gpio_set(chip, offset, value);
+
+	return 0;
+}
+
+static int ltq_gpio_req(struct gpio_chip *chip, unsigned offset)
+{
+	struct ltq_gpio *ltq_gpio = container_of(chip, struct ltq_gpio, chip);
+
+	ltq_gpio_clearbit(ltq_gpio->membase, LTQ_GPIO_ALTSEL0, offset);
+	ltq_gpio_clearbit(ltq_gpio->membase, LTQ_GPIO_ALTSEL1, offset);
+	return 0;
+}
+
+static int ltq_gpio_probe(struct platform_device *pdev)
+{
+	struct resource *res;
+
+	if (pdev->id >= MAX_PORTS) {
+		dev_err(&pdev->dev, "invalid gpio port %d\n",
+			pdev->id);
+		return -EINVAL;
+	}
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res) {
+		dev_err(&pdev->dev, "failed to get memory for gpio port %d\n",
+			pdev->id);
+		return -ENOENT;
+	}
+	res = devm_request_mem_region(&pdev->dev, res->start,
+		resource_size(res), dev_name(&pdev->dev));
+	if (!res) {
+		dev_err(&pdev->dev,
+			"failed to request memory for gpio port %d\n",
+			pdev->id);
+		return -EBUSY;
+	}
+	ltq_gpio_port[pdev->id].membase = devm_ioremap_nocache(&pdev->dev,
+		res->start, resource_size(res));
+	if (!ltq_gpio_port[pdev->id].membase) {
+		dev_err(&pdev->dev, "failed to remap memory for gpio port %d\n",
+			pdev->id);
+		return -ENOMEM;
+	}
+	ltq_gpio_port[pdev->id].chip.label = "ltq_gpio";
+	ltq_gpio_port[pdev->id].chip.direction_input = ltq_gpio_direction_input;
+	ltq_gpio_port[pdev->id].chip.direction_output =
+		ltq_gpio_direction_output;
+	ltq_gpio_port[pdev->id].chip.get = ltq_gpio_get;
+	ltq_gpio_port[pdev->id].chip.set = ltq_gpio_set;
+	ltq_gpio_port[pdev->id].chip.request = ltq_gpio_req;
+	ltq_gpio_port[pdev->id].chip.base = PINS_PER_PORT * pdev->id;
+	ltq_gpio_port[pdev->id].chip.ngpio = PINS_PER_PORT;
+	platform_set_drvdata(pdev, &ltq_gpio_port[pdev->id]);
+	return gpiochip_add(&ltq_gpio_port[pdev->id].chip);
+}
+
+static struct platform_driver
+ltq_gpio_driver = {
+	.probe = ltq_gpio_probe,
+	.driver = {
+		.name = "ltq_gpio",
+		.owner = THIS_MODULE,
+	},
+};
+
+int __init ltq_gpio_init(void)
+{
+	int ret = platform_driver_register(&ltq_gpio_driver);
+
+	if (ret)
+		pr_info("ltq_gpio : Error registering platfom driver!");
+	return ret;
+}
+
+postcore_initcall(ltq_gpio_init);
diff -druN linux-2.6.39-libre/arch/mips/lantiq/xway/gpio_ebu.c linux-3.0-rc7-libre/arch/mips/lantiq/xway/gpio_ebu.c
--- linux-2.6.39-libre/arch/mips/lantiq/xway/gpio_ebu.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/mips/lantiq/xway/gpio_ebu.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,126 @@
+/*
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License version 2 as published
+ *  by the Free Software Foundation.
+ *
+ *  Copyright (C) 2010 John Crispin <blogic@openwrt.org>
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/platform_device.h>
+#include <linux/mutex.h>
+#include <linux/gpio.h>
+#include <linux/io.h>
+
+#include <lantiq_soc.h>
+
+/*
+ * By attaching hardware latches to the EBU it is possible to create output
+ * only gpios. This driver configures a special memory address, which when
+ * written to outputs 16 bit to the latches.
+ */
+
+#define LTQ_EBU_BUSCON	0x1e7ff		/* 16 bit access, slowest timing */
+#define LTQ_EBU_WP	0x80000000	/* write protect bit */
+
+/* we keep a shadow value of the last value written to the ebu */
+static int ltq_ebu_gpio_shadow = 0x0;
+static void __iomem *ltq_ebu_gpio_membase;
+
+static void ltq_ebu_apply(void)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&ebu_lock, flags);
+	ltq_ebu_w32(LTQ_EBU_BUSCON, LTQ_EBU_BUSCON1);
+	*((__u16 *)ltq_ebu_gpio_membase) = ltq_ebu_gpio_shadow;
+	ltq_ebu_w32(LTQ_EBU_BUSCON | LTQ_EBU_WP, LTQ_EBU_BUSCON1);
+	spin_unlock_irqrestore(&ebu_lock, flags);
+}
+
+static void ltq_ebu_set(struct gpio_chip *chip, unsigned offset, int value)
+{
+	if (value)
+		ltq_ebu_gpio_shadow |= (1 << offset);
+	else
+		ltq_ebu_gpio_shadow &= ~(1 << offset);
+	ltq_ebu_apply();
+}
+
+static int ltq_ebu_direction_output(struct gpio_chip *chip, unsigned offset,
+	int value)
+{
+	ltq_ebu_set(chip, offset, value);
+
+	return 0;
+}
+
+static struct gpio_chip ltq_ebu_chip = {
+	.label = "ltq_ebu",
+	.direction_output = ltq_ebu_direction_output,
+	.set = ltq_ebu_set,
+	.base = 72,
+	.ngpio = 16,
+	.can_sleep = 1,
+	.owner = THIS_MODULE,
+};
+
+static int ltq_ebu_probe(struct platform_device *pdev)
+{
+	int ret = 0;
+	struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+
+	if (!res) {
+		dev_err(&pdev->dev, "failed to get memory resource\n");
+		return -ENOENT;
+	}
+
+	res = devm_request_mem_region(&pdev->dev, res->start,
+		resource_size(res), dev_name(&pdev->dev));
+	if (!res) {
+		dev_err(&pdev->dev, "failed to request memory resource\n");
+		return -EBUSY;
+	}
+
+	ltq_ebu_gpio_membase = devm_ioremap_nocache(&pdev->dev, res->start,
+		resource_size(res));
+	if (!ltq_ebu_gpio_membase) {
+		dev_err(&pdev->dev, "Failed to ioremap mem region\n");
+		return -ENOMEM;
+	}
+
+	/* grab the default shadow value passed form the platform code */
+	ltq_ebu_gpio_shadow = (unsigned int) pdev->dev.platform_data;
+
+	/* tell the ebu controller which memory address we will be using */
+	ltq_ebu_w32(pdev->resource->start | 0x1, LTQ_EBU_ADDRSEL1);
+
+	/* write protect the region */
+	ltq_ebu_w32(LTQ_EBU_BUSCON | LTQ_EBU_WP, LTQ_EBU_BUSCON1);
+
+	ret = gpiochip_add(&ltq_ebu_chip);
+	if (!ret)
+		ltq_ebu_apply();
+	return ret;
+}
+
+static struct platform_driver ltq_ebu_driver = {
+	.probe = ltq_ebu_probe,
+	.driver = {
+		.name = "ltq_ebu",
+		.owner = THIS_MODULE,
+	},
+};
+
+static int __init ltq_ebu_init(void)
+{
+	int ret = platform_driver_register(&ltq_ebu_driver);
+
+	if (ret)
+		pr_info("ltq_ebu : Error registering platfom driver!");
+	return ret;
+}
+
+postcore_initcall(ltq_ebu_init);
diff -druN linux-2.6.39-libre/arch/mips/lantiq/xway/gpio_stp.c linux-3.0-rc7-libre/arch/mips/lantiq/xway/gpio_stp.c
--- linux-2.6.39-libre/arch/mips/lantiq/xway/gpio_stp.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/mips/lantiq/xway/gpio_stp.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,157 @@
+/*
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License version 2 as published
+ *  by the Free Software Foundation.
+ *
+ *  Copyright (C) 2007 John Crispin <blogic@openwrt.org>
+ *
+ */
+
+#include <linux/slab.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/platform_device.h>
+#include <linux/mutex.h>
+#include <linux/io.h>
+#include <linux/gpio.h>
+
+#include <lantiq_soc.h>
+
+#define LTQ_STP_CON0		0x00
+#define LTQ_STP_CON1		0x04
+#define LTQ_STP_CPU0		0x08
+#define LTQ_STP_CPU1		0x0C
+#define LTQ_STP_AR		0x10
+
+#define LTQ_STP_CON_SWU		(1 << 31)
+#define LTQ_STP_2HZ		0
+#define LTQ_STP_4HZ		(1 << 23)
+#define LTQ_STP_8HZ		(2 << 23)
+#define LTQ_STP_10HZ		(3 << 23)
+#define LTQ_STP_SPEED_MASK	(0xf << 23)
+#define LTQ_STP_UPD_FPI		(1 << 31)
+#define LTQ_STP_UPD_MASK	(3 << 30)
+#define LTQ_STP_ADSL_SRC	(3 << 24)
+
+#define LTQ_STP_GROUP0		(1 << 0)
+
+#define LTQ_STP_RISING		0
+#define LTQ_STP_FALLING		(1 << 26)
+#define LTQ_STP_EDGE_MASK	(1 << 26)
+
+#define ltq_stp_r32(reg)	__raw_readl(ltq_stp_membase + reg)
+#define ltq_stp_w32(val, reg)	__raw_writel(val, ltq_stp_membase + reg)
+#define ltq_stp_w32_mask(clear, set, reg) \
+		ltq_w32((ltq_r32(ltq_stp_membase + reg) & ~(clear)) | (set), \
+		ltq_stp_membase + (reg))
+
+static int ltq_stp_shadow = 0xffff;
+static void __iomem *ltq_stp_membase;
+
+static void ltq_stp_set(struct gpio_chip *chip, unsigned offset, int value)
+{
+	if (value)
+		ltq_stp_shadow |= (1 << offset);
+	else
+		ltq_stp_shadow &= ~(1 << offset);
+	ltq_stp_w32(ltq_stp_shadow, LTQ_STP_CPU0);
+}
+
+static int ltq_stp_direction_output(struct gpio_chip *chip, unsigned offset,
+	int value)
+{
+	ltq_stp_set(chip, offset, value);
+
+	return 0;
+}
+
+static struct gpio_chip ltq_stp_chip = {
+	.label = "ltq_stp",
+	.direction_output = ltq_stp_direction_output,
+	.set = ltq_stp_set,
+	.base = 48,
+	.ngpio = 24,
+	.can_sleep = 1,
+	.owner = THIS_MODULE,
+};
+
+static int ltq_stp_hw_init(void)
+{
+	/* the 3 pins used to control the external stp */
+	ltq_gpio_request(4, 1, 0, 1, "stp-st");
+	ltq_gpio_request(5, 1, 0, 1, "stp-d");
+	ltq_gpio_request(6, 1, 0, 1, "stp-sh");
+
+	/* sane defaults */
+	ltq_stp_w32(0, LTQ_STP_AR);
+	ltq_stp_w32(0, LTQ_STP_CPU0);
+	ltq_stp_w32(0, LTQ_STP_CPU1);
+	ltq_stp_w32(LTQ_STP_CON_SWU, LTQ_STP_CON0);
+	ltq_stp_w32(0, LTQ_STP_CON1);
+
+	/* rising or falling edge */
+	ltq_stp_w32_mask(LTQ_STP_EDGE_MASK, LTQ_STP_FALLING, LTQ_STP_CON0);
+
+	/* per default stp 15-0 are set */
+	ltq_stp_w32_mask(0, LTQ_STP_GROUP0, LTQ_STP_CON1);
+
+	/* stp are update periodically by the FPI bus */
+	ltq_stp_w32_mask(LTQ_STP_UPD_MASK, LTQ_STP_UPD_FPI, LTQ_STP_CON1);
+
+	/* set stp update speed */
+	ltq_stp_w32_mask(LTQ_STP_SPEED_MASK, LTQ_STP_8HZ, LTQ_STP_CON1);
+
+	/* tell the hardware that pin (led) 0 and 1 are controlled
+	 *  by the dsl arc
+	 */
+	ltq_stp_w32_mask(0, LTQ_STP_ADSL_SRC, LTQ_STP_CON0);
+
+	ltq_pmu_enable(PMU_LED);
+	return 0;
+}
+
+static int __devinit ltq_stp_probe(struct platform_device *pdev)
+{
+	struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	int ret = 0;
+
+	if (!res)
+		return -ENOENT;
+	res = devm_request_mem_region(&pdev->dev, res->start,
+		resource_size(res), dev_name(&pdev->dev));
+	if (!res) {
+		dev_err(&pdev->dev, "failed to request STP memory\n");
+		return -EBUSY;
+	}
+	ltq_stp_membase = devm_ioremap_nocache(&pdev->dev, res->start,
+		resource_size(res));
+	if (!ltq_stp_membase) {
+		dev_err(&pdev->dev, "failed to remap STP memory\n");
+		return -ENOMEM;
+	}
+	ret = gpiochip_add(&ltq_stp_chip);
+	if (!ret)
+		ret = ltq_stp_hw_init();
+
+	return ret;
+}
+
+static struct platform_driver ltq_stp_driver = {
+	.probe = ltq_stp_probe,
+	.driver = {
+		.name = "ltq_stp",
+		.owner = THIS_MODULE,
+	},
+};
+
+int __init ltq_stp_init(void)
+{
+	int ret = platform_driver_register(&ltq_stp_driver);
+
+	if (ret)
+		pr_info("ltq_stp: error registering platfom driver");
+	return ret;
+}
+
+postcore_initcall(ltq_stp_init);
diff -druN linux-2.6.39-libre/arch/mips/lantiq/xway/Kconfig linux-3.0-rc7-libre/arch/mips/lantiq/xway/Kconfig
--- linux-2.6.39-libre/arch/mips/lantiq/xway/Kconfig	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/mips/lantiq/xway/Kconfig	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,23 @@
+if SOC_XWAY
+
+menu "MIPS Machine"
+
+config LANTIQ_MACH_EASY50712
+	bool "Easy50712 - Danube"
+	default y
+
+endmenu
+
+endif
+
+if SOC_AMAZON_SE
+
+menu "MIPS Machine"
+
+config LANTIQ_MACH_EASY50601
+	bool "Easy50601 - Amazon SE"
+	default y
+
+endmenu
+
+endif
diff -druN linux-2.6.39-libre/arch/mips/lantiq/xway/mach-easy50601.c linux-3.0-rc7-libre/arch/mips/lantiq/xway/mach-easy50601.c
--- linux-2.6.39-libre/arch/mips/lantiq/xway/mach-easy50601.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/mips/lantiq/xway/mach-easy50601.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,57 @@
+/*
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License version 2 as published
+ *  by the Free Software Foundation.
+ *
+ *  Copyright (C) 2010 John Crispin <blogic@openwrt.org>
+ */
+
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/physmap.h>
+#include <linux/input.h>
+
+#include <lantiq.h>
+
+#include "../machtypes.h"
+#include "devices.h"
+
+static struct mtd_partition easy50601_partitions[] = {
+	{
+		.name	= "uboot",
+		.offset	= 0x0,
+		.size	= 0x10000,
+	},
+	{
+		.name	= "uboot_env",
+		.offset	= 0x10000,
+		.size	= 0x10000,
+	},
+	{
+		.name	= "linux",
+		.offset	= 0x20000,
+		.size	= 0xE0000,
+	},
+	{
+		.name	= "rootfs",
+		.offset	= 0x100000,
+		.size	= 0x300000,
+	},
+};
+
+static struct physmap_flash_data easy50601_flash_data = {
+	.nr_parts	= ARRAY_SIZE(easy50601_partitions),
+	.parts		= easy50601_partitions,
+};
+
+static void __init easy50601_init(void)
+{
+	ltq_register_nor(&easy50601_flash_data);
+}
+
+MIPS_MACHINE(LTQ_MACH_EASY50601,
+			"EASY50601",
+			"EASY50601 Eval Board",
+			easy50601_init);
diff -druN linux-2.6.39-libre/arch/mips/lantiq/xway/mach-easy50712.c linux-3.0-rc7-libre/arch/mips/lantiq/xway/mach-easy50712.c
--- linux-2.6.39-libre/arch/mips/lantiq/xway/mach-easy50712.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/mips/lantiq/xway/mach-easy50712.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,74 @@
+/*
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License version 2 as published
+ *  by the Free Software Foundation.
+ *
+ *  Copyright (C) 2010 John Crispin <blogic@openwrt.org>
+ */
+
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/physmap.h>
+#include <linux/input.h>
+#include <linux/phy.h>
+
+#include <lantiq_soc.h>
+#include <irq.h>
+
+#include "../machtypes.h"
+#include "devices.h"
+
+static struct mtd_partition easy50712_partitions[] = {
+	{
+		.name	= "uboot",
+		.offset	= 0x0,
+		.size	= 0x10000,
+	},
+	{
+		.name	= "uboot_env",
+		.offset	= 0x10000,
+		.size	= 0x10000,
+	},
+	{
+		.name	= "linux",
+		.offset	= 0x20000,
+		.size	= 0xe0000,
+	},
+	{
+		.name	= "rootfs",
+		.offset	= 0x100000,
+		.size	= 0x300000,
+	},
+};
+
+static struct physmap_flash_data easy50712_flash_data = {
+	.nr_parts	= ARRAY_SIZE(easy50712_partitions),
+	.parts		= easy50712_partitions,
+};
+
+static struct ltq_pci_data ltq_pci_data = {
+	.clock	= PCI_CLOCK_INT,
+	.gpio	= PCI_GNT1 | PCI_REQ1,
+	.irq	= {
+		[14] = INT_NUM_IM0_IRL0 + 22,
+	},
+};
+
+static struct ltq_eth_data ltq_eth_data = {
+	.mii_mode = PHY_INTERFACE_MODE_MII,
+};
+
+static void __init easy50712_init(void)
+{
+	ltq_register_gpio_stp();
+	ltq_register_nor(&easy50712_flash_data);
+	ltq_register_pci(&ltq_pci_data);
+	ltq_register_etop(&ltq_eth_data);
+}
+
+MIPS_MACHINE(LTQ_MACH_EASY50712,
+	     "EASY50712",
+	     "EASY50712 Eval Board",
+	      easy50712_init);
diff -druN linux-2.6.39-libre/arch/mips/lantiq/xway/Makefile linux-3.0-rc7-libre/arch/mips/lantiq/xway/Makefile
--- linux-2.6.39-libre/arch/mips/lantiq/xway/Makefile	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/mips/lantiq/xway/Makefile	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,7 @@
+obj-y := pmu.o ebu.o reset.o gpio.o gpio_stp.o gpio_ebu.o devices.o dma.o
+
+obj-$(CONFIG_SOC_XWAY) += clk-xway.o prom-xway.o setup-xway.o
+obj-$(CONFIG_SOC_AMAZON_SE) += clk-ase.o prom-ase.o setup-ase.o
+
+obj-$(CONFIG_LANTIQ_MACH_EASY50712) += mach-easy50712.o
+obj-$(CONFIG_LANTIQ_MACH_EASY50601) += mach-easy50601.o
diff -druN linux-2.6.39-libre/arch/mips/lantiq/xway/pmu.c linux-3.0-rc7-libre/arch/mips/lantiq/xway/pmu.c
--- linux-2.6.39-libre/arch/mips/lantiq/xway/pmu.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/mips/lantiq/xway/pmu.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,70 @@
+/*
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License version 2 as published
+ *  by the Free Software Foundation.
+ *
+ *  Copyright (C) 2010 John Crispin <blogic@openwrt.org>
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/version.h>
+#include <linux/ioport.h>
+
+#include <lantiq_soc.h>
+
+/* PMU - the power management unit allows us to turn part of the core
+ * on and off
+ */
+
+/* the enable / disable registers */
+#define LTQ_PMU_PWDCR	0x1C
+#define LTQ_PMU_PWDSR	0x20
+
+#define ltq_pmu_w32(x, y)	ltq_w32((x), ltq_pmu_membase + (y))
+#define ltq_pmu_r32(x)		ltq_r32(ltq_pmu_membase + (x))
+
+static struct resource ltq_pmu_resource = {
+	.name	= "pmu",
+	.start	= LTQ_PMU_BASE_ADDR,
+	.end	= LTQ_PMU_BASE_ADDR + LTQ_PMU_SIZE - 1,
+	.flags	= IORESOURCE_MEM,
+};
+
+static void __iomem *ltq_pmu_membase;
+
+void ltq_pmu_enable(unsigned int module)
+{
+	int err = 1000000;
+
+	ltq_pmu_w32(ltq_pmu_r32(LTQ_PMU_PWDCR) & ~module, LTQ_PMU_PWDCR);
+	do {} while (--err && (ltq_pmu_r32(LTQ_PMU_PWDSR) & module));
+
+	if (!err)
+		panic("activating PMU module failed!\n");
+}
+EXPORT_SYMBOL(ltq_pmu_enable);
+
+void ltq_pmu_disable(unsigned int module)
+{
+	ltq_pmu_w32(ltq_pmu_r32(LTQ_PMU_PWDCR) | module, LTQ_PMU_PWDCR);
+}
+EXPORT_SYMBOL(ltq_pmu_disable);
+
+int __init ltq_pmu_init(void)
+{
+	if (insert_resource(&iomem_resource, &ltq_pmu_resource) < 0)
+		panic("Failed to insert pmu memory\n");
+
+	if (request_mem_region(ltq_pmu_resource.start,
+			resource_size(&ltq_pmu_resource), "pmu") < 0)
+		panic("Failed to request pmu memory\n");
+
+	ltq_pmu_membase = ioremap_nocache(ltq_pmu_resource.start,
+				resource_size(&ltq_pmu_resource));
+	if (!ltq_pmu_membase)
+		panic("Failed to remap pmu memory\n");
+	return 0;
+}
+
+core_initcall(ltq_pmu_init);
diff -druN linux-2.6.39-libre/arch/mips/lantiq/xway/prom-ase.c linux-3.0-rc7-libre/arch/mips/lantiq/xway/prom-ase.c
--- linux-2.6.39-libre/arch/mips/lantiq/xway/prom-ase.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/mips/lantiq/xway/prom-ase.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,39 @@
+/*
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License version 2 as published
+ *  by the Free Software Foundation.
+ *
+ *  Copyright (C) 2010 John Crispin <blogic@openwrt.org>
+ */
+
+#include <linux/module.h>
+#include <linux/clk.h>
+#include <asm/bootinfo.h>
+#include <asm/time.h>
+
+#include <lantiq_soc.h>
+
+#include "../prom.h"
+
+#define SOC_AMAZON_SE	"Amazon_SE"
+
+#define PART_SHIFT	12
+#define PART_MASK	0x0FFFFFFF
+#define REV_SHIFT	28
+#define REV_MASK	0xF0000000
+
+void __init ltq_soc_detect(struct ltq_soc_info *i)
+{
+	i->partnum = (ltq_r32(LTQ_MPS_CHIPID) & PART_MASK) >> PART_SHIFT;
+	i->rev = (ltq_r32(LTQ_MPS_CHIPID) & REV_MASK) >> REV_SHIFT;
+	switch (i->partnum) {
+	case SOC_ID_AMAZON_SE:
+		i->name = SOC_AMAZON_SE;
+		i->type = SOC_TYPE_AMAZON_SE;
+		break;
+
+	default:
+		unreachable();
+		break;
+	}
+}
diff -druN linux-2.6.39-libre/arch/mips/lantiq/xway/prom-xway.c linux-3.0-rc7-libre/arch/mips/lantiq/xway/prom-xway.c
--- linux-2.6.39-libre/arch/mips/lantiq/xway/prom-xway.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/mips/lantiq/xway/prom-xway.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,54 @@
+/*
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License version 2 as published
+ *  by the Free Software Foundation.
+ *
+ *  Copyright (C) 2010 John Crispin <blogic@openwrt.org>
+ */
+
+#include <linux/module.h>
+#include <linux/clk.h>
+#include <asm/bootinfo.h>
+#include <asm/time.h>
+
+#include <lantiq_soc.h>
+
+#include "../prom.h"
+
+#define SOC_DANUBE	"Danube"
+#define SOC_TWINPASS	"Twinpass"
+#define SOC_AR9		"AR9"
+
+#define PART_SHIFT	12
+#define PART_MASK	0x0FFFFFFF
+#define REV_SHIFT	28
+#define REV_MASK	0xF0000000
+
+void __init ltq_soc_detect(struct ltq_soc_info *i)
+{
+	i->partnum = (ltq_r32(LTQ_MPS_CHIPID) & PART_MASK) >> PART_SHIFT;
+	i->rev = (ltq_r32(LTQ_MPS_CHIPID) & REV_MASK) >> REV_SHIFT;
+	switch (i->partnum) {
+	case SOC_ID_DANUBE1:
+	case SOC_ID_DANUBE2:
+		i->name = SOC_DANUBE;
+		i->type = SOC_TYPE_DANUBE;
+		break;
+
+	case SOC_ID_TWINPASS:
+		i->name = SOC_TWINPASS;
+		i->type = SOC_TYPE_DANUBE;
+		break;
+
+	case SOC_ID_ARX188:
+	case SOC_ID_ARX168:
+	case SOC_ID_ARX182:
+		i->name = SOC_AR9;
+		i->type = SOC_TYPE_AR9;
+		break;
+
+	default:
+		unreachable();
+		break;
+	}
+}
diff -druN linux-2.6.39-libre/arch/mips/lantiq/xway/reset.c linux-3.0-rc7-libre/arch/mips/lantiq/xway/reset.c
--- linux-2.6.39-libre/arch/mips/lantiq/xway/reset.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/mips/lantiq/xway/reset.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,91 @@
+/*
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License version 2 as published
+ *  by the Free Software Foundation.
+ *
+ *  Copyright (C) 2010 John Crispin <blogic@openwrt.org>
+ */
+
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/ioport.h>
+#include <linux/pm.h>
+#include <linux/module.h>
+#include <asm/reboot.h>
+
+#include <lantiq_soc.h>
+
+#define ltq_rcu_w32(x, y)	ltq_w32((x), ltq_rcu_membase + (y))
+#define ltq_rcu_r32(x)		ltq_r32(ltq_rcu_membase + (x))
+
+/* register definitions */
+#define LTQ_RCU_RST		0x0010
+#define LTQ_RCU_RST_ALL		0x40000000
+
+#define LTQ_RCU_RST_STAT	0x0014
+#define LTQ_RCU_STAT_SHIFT	26
+
+static struct resource ltq_rcu_resource = {
+	.name   = "rcu",
+	.start  = LTQ_RCU_BASE_ADDR,
+	.end    = LTQ_RCU_BASE_ADDR + LTQ_RCU_SIZE - 1,
+	.flags  = IORESOURCE_MEM,
+};
+
+/* remapped base addr of the reset control unit */
+static void __iomem *ltq_rcu_membase;
+
+/* This function is used by the watchdog driver */
+int ltq_reset_cause(void)
+{
+	u32 val = ltq_rcu_r32(LTQ_RCU_RST_STAT);
+	return val >> LTQ_RCU_STAT_SHIFT;
+}
+EXPORT_SYMBOL_GPL(ltq_reset_cause);
+
+static void ltq_machine_restart(char *command)
+{
+	pr_notice("System restart\n");
+	local_irq_disable();
+	ltq_rcu_w32(ltq_rcu_r32(LTQ_RCU_RST) | LTQ_RCU_RST_ALL, LTQ_RCU_RST);
+	unreachable();
+}
+
+static void ltq_machine_halt(void)
+{
+	pr_notice("System halted.\n");
+	local_irq_disable();
+	unreachable();
+}
+
+static void ltq_machine_power_off(void)
+{
+	pr_notice("Please turn off the power now.\n");
+	local_irq_disable();
+	unreachable();
+}
+
+static int __init mips_reboot_setup(void)
+{
+	/* insert and request the memory region */
+	if (insert_resource(&iomem_resource, &ltq_rcu_resource) < 0)
+		panic("Failed to insert rcu memory\n");
+
+	if (request_mem_region(ltq_rcu_resource.start,
+			resource_size(&ltq_rcu_resource), "rcu") < 0)
+		panic("Failed to request rcu memory\n");
+
+	/* remap rcu register range */
+	ltq_rcu_membase = ioremap_nocache(ltq_rcu_resource.start,
+				resource_size(&ltq_rcu_resource));
+	if (!ltq_rcu_membase)
+		panic("Failed to remap rcu memory\n");
+
+	_machine_restart = ltq_machine_restart;
+	_machine_halt = ltq_machine_halt;
+	pm_power_off = ltq_machine_power_off;
+
+	return 0;
+}
+
+arch_initcall(mips_reboot_setup);
diff -druN linux-2.6.39-libre/arch/mips/lantiq/xway/setup-ase.c linux-3.0-rc7-libre/arch/mips/lantiq/xway/setup-ase.c
--- linux-2.6.39-libre/arch/mips/lantiq/xway/setup-ase.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/mips/lantiq/xway/setup-ase.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,19 @@
+/*
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License version 2 as published
+ *  by the Free Software Foundation.
+ *
+ *  Copyright (C) 2011 John Crispin <blogic@openwrt.org>
+ */
+
+#include <lantiq_soc.h>
+
+#include "../prom.h"
+#include "devices.h"
+
+void __init ltq_soc_setup(void)
+{
+	ltq_register_ase_asc();
+	ltq_register_gpio();
+	ltq_register_wdt();
+}
diff -druN linux-2.6.39-libre/arch/mips/lantiq/xway/setup-xway.c linux-3.0-rc7-libre/arch/mips/lantiq/xway/setup-xway.c
--- linux-2.6.39-libre/arch/mips/lantiq/xway/setup-xway.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/mips/lantiq/xway/setup-xway.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,20 @@
+/*
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License version 2 as published
+ *  by the Free Software Foundation.
+ *
+ *  Copyright (C) 2011 John Crispin <blogic@openwrt.org>
+ */
+
+#include <lantiq_soc.h>
+
+#include "../prom.h"
+#include "devices.h"
+
+void __init ltq_soc_setup(void)
+{
+	ltq_register_asc(0);
+	ltq_register_asc(1);
+	ltq_register_gpio();
+	ltq_register_wdt();
+}
diff -druN linux-2.6.39-libre/arch/mips/lib/Makefile linux-3.0-rc7-libre/arch/mips/lib/Makefile
--- linux-2.6.39-libre/arch/mips/lib/Makefile	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/mips/lib/Makefile	2011-07-11 19:51:52.000000000 -0400
@@ -28,6 +28,7 @@
 obj-$(CONFIG_CPU_TX49XX)	+= dump_tlb.o
 obj-$(CONFIG_CPU_VR41XX)	+= dump_tlb.o
 obj-$(CONFIG_CPU_CAVIUM_OCTEON)	+= dump_tlb.o
+obj-$(CONFIG_CPU_XLR)		+= dump_tlb.o
 
 # libgcc-style stuff needed in the kernel
 obj-y += ashldi3.o ashrdi3.o cmpdi2.o lshrdi3.o ucmpdi2.o
diff -druN linux-2.6.39-libre/arch/mips/loongson/common/cs5536/cs5536_mfgpt.c linux-3.0-rc7-libre/arch/mips/loongson/common/cs5536/cs5536_mfgpt.c
--- linux-2.6.39-libre/arch/mips/loongson/common/cs5536/cs5536_mfgpt.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/mips/loongson/common/cs5536/cs5536_mfgpt.c	2011-07-11 19:51:52.000000000 -0400
@@ -201,8 +201,6 @@
 	.rating = 120, /* Functional for real use, but not desired */
 	.read = mfgpt_read,
 	.mask = CLOCKSOURCE_MASK(32),
-	.mult = 0,
-	.shift = 22,
 };
 
 int __init init_mfgpt_clocksource(void)
@@ -210,8 +208,7 @@
 	if (num_possible_cpus() > 1)	/* MFGPT does not scale! */
 		return 0;
 
-	clocksource_mfgpt.mult = clocksource_hz2mult(MFGPT_TICK_RATE, 22);
-	return clocksource_register(&clocksource_mfgpt);
+	return clocksource_register_hz(&clocksource_mfgpt, MFGPT_TICK_RATE);
 }
 
 arch_initcall(init_mfgpt_clocksource);
diff -druN linux-2.6.39-libre/arch/mips/Makefile linux-3.0-rc7-libre/arch/mips/Makefile
--- linux-2.6.39-libre/arch/mips/Makefile	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/mips/Makefile	2011-07-11 19:51:52.000000000 -0400
@@ -191,6 +191,18 @@
 #
 include $(srctree)/arch/mips/Kbuild.platforms
 
+#
+# NETLOGIC SOC Common (common)
+#
+cflags-$(CONFIG_NLM_COMMON)		+= -I$(srctree)/arch/mips/include/asm/mach-netlogic
+cflags-$(CONFIG_NLM_COMMON)		+= -I$(srctree)/arch/mips/include/asm/netlogic
+
+#
+# NETLOGIC XLR/XLS SoC, Simulator and boards
+#
+core-$(CONFIG_NLM_XLR)      		+= arch/mips/netlogic/xlr/
+load-$(CONFIG_NLM_XLR_BOARD)		+= 0xffffffff84000000
+
 cflags-y			+= -I$(srctree)/arch/mips/include/asm/mach-generic
 drivers-$(CONFIG_PCI)		+= arch/mips/pci/
 
diff -druN linux-2.6.39-libre/arch/mips/mm/c-r3k.c linux-3.0-rc7-libre/arch/mips/mm/c-r3k.c
--- linux-2.6.39-libre/arch/mips/mm/c-r3k.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/mips/mm/c-r3k.c	2011-07-11 19:51:52.000000000 -0400
@@ -1,7 +1,7 @@
 /*
  * r2300.c: R2000 and R3000 specific mmu/cache code.
  *
- * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
+ * Copyright (C) 1996 David S. Miller (davem@davemloft.net)
  *
  * with a lot of changes to make this thing work for R3000s
  * Tx39XX R4k style caches added. HK
diff -druN linux-2.6.39-libre/arch/mips/mm/c-r4k.c linux-3.0-rc7-libre/arch/mips/mm/c-r4k.c
--- linux-2.6.39-libre/arch/mips/mm/c-r4k.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/mips/mm/c-r4k.c	2011-07-11 19:51:52.000000000 -0400
@@ -3,7 +3,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
+ * Copyright (C) 1996 David S. Miller (davem@davemloft.net)
  * Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 Ralf Baechle (ralf@gnu.org)
  * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
  */
@@ -1006,6 +1006,7 @@
 	case CPU_25KF:
 	case CPU_SB1:
 	case CPU_SB1A:
+	case CPU_XLR:
 		c->dcache.flags |= MIPS_CACHE_PINDEX;
 		break;
 
diff -druN linux-2.6.39-libre/arch/mips/mm/c-tx39.c linux-3.0-rc7-libre/arch/mips/mm/c-tx39.c
--- linux-2.6.39-libre/arch/mips/mm/c-tx39.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/mips/mm/c-tx39.c	2011-07-11 19:51:52.000000000 -0400
@@ -1,7 +1,7 @@
 /*
  * r2300.c: R2000 and R3000 specific mmu/cache code.
  *
- * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
+ * Copyright (C) 1996 David S. Miller (davem@davemloft.net)
  *
  * with a lot of changes to make this thing work for R3000s
  * Tx39XX R4k style caches added. HK
diff -druN linux-2.6.39-libre/arch/mips/mm/init.c linux-3.0-rc7-libre/arch/mips/mm/init.c
--- linux-2.6.39-libre/arch/mips/mm/init.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/mips/mm/init.c	2011-07-11 19:51:52.000000000 -0400
@@ -64,8 +64,6 @@
 
 #endif /* CONFIG_MIPS_MT_SMTC */
 
-DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
-
 /*
  * We have up to 8 empty zeroed pages so we can map one of the right colour
  * when needed.  This is necessary only on R4000 / R4400 SC and MC versions
diff -druN linux-2.6.39-libre/arch/mips/mm/Makefile linux-3.0-rc7-libre/arch/mips/mm/Makefile
--- linux-2.6.39-libre/arch/mips/mm/Makefile	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/mips/mm/Makefile	2011-07-11 19:51:52.000000000 -0400
@@ -3,7 +3,8 @@
 #
 
 obj-y				+= cache.o dma-default.o extable.o fault.o \
-				   init.o tlbex.o tlbex-fault.o uasm.o page.o
+				   init.o mmap.o tlbex.o tlbex-fault.o uasm.o \
+				   page.o
 
 obj-$(CONFIG_32BIT)		+= ioremap.o pgtable-32.o
 obj-$(CONFIG_64BIT)		+= pgtable-64.o
@@ -29,6 +30,7 @@
 obj-$(CONFIG_CPU_TX49XX)	+= c-r4k.o cex-gen.o tlb-r4k.o
 obj-$(CONFIG_CPU_VR41XX)	+= c-r4k.o cex-gen.o tlb-r4k.o
 obj-$(CONFIG_CPU_CAVIUM_OCTEON)	+= c-octeon.o cex-oct.o tlb-r4k.o
+obj-$(CONFIG_CPU_XLR)		+= c-r4k.o tlb-r4k.o cex-gen.o
 
 obj-$(CONFIG_IP22_CPU_SCACHE)	+= sc-ip22.o
 obj-$(CONFIG_R5000_CPU_SCACHE)  += sc-r5k.o
diff -druN linux-2.6.39-libre/arch/mips/mm/mmap.c linux-3.0-rc7-libre/arch/mips/mm/mmap.c
--- linux-2.6.39-libre/arch/mips/mm/mmap.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/mips/mm/mmap.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,122 @@
+/*
+ * 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) 2011 Wind River Systems,
+ *   written by Ralf Baechle <ralf@linux-mips.org>
+ */
+#include <linux/errno.h>
+#include <linux/mm.h>
+#include <linux/mman.h>
+#include <linux/module.h>
+#include <linux/random.h>
+#include <linux/sched.h>
+
+unsigned long shm_align_mask = PAGE_SIZE - 1;	/* Sane caches */
+
+EXPORT_SYMBOL(shm_align_mask);
+
+#define COLOUR_ALIGN(addr,pgoff)				\
+	((((addr) + shm_align_mask) & ~shm_align_mask) +	\
+	 (((pgoff) << PAGE_SHIFT) & shm_align_mask))
+
+unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr,
+	unsigned long len, unsigned long pgoff, unsigned long flags)
+{
+	struct vm_area_struct * vmm;
+	int do_color_align;
+
+	if (len > TASK_SIZE)
+		return -ENOMEM;
+
+	if (flags & MAP_FIXED) {
+		/* Even MAP_FIXED mappings must reside within TASK_SIZE.  */
+		if (TASK_SIZE - len < addr)
+			return -EINVAL;
+
+		/*
+		 * We do not accept a shared mapping if it would violate
+		 * cache aliasing constraints.
+		 */
+		if ((flags & MAP_SHARED) &&
+		    ((addr - (pgoff << PAGE_SHIFT)) & shm_align_mask))
+			return -EINVAL;
+		return addr;
+	}
+
+	do_color_align = 0;
+	if (filp || (flags & MAP_SHARED))
+		do_color_align = 1;
+	if (addr) {
+		if (do_color_align)
+			addr = COLOUR_ALIGN(addr, pgoff);
+		else
+			addr = PAGE_ALIGN(addr);
+		vmm = find_vma(current->mm, addr);
+		if (TASK_SIZE - len >= addr &&
+		    (!vmm || addr + len <= vmm->vm_start))
+			return addr;
+	}
+	addr = current->mm->mmap_base;
+	if (do_color_align)
+		addr = COLOUR_ALIGN(addr, pgoff);
+	else
+		addr = PAGE_ALIGN(addr);
+
+	for (vmm = find_vma(current->mm, addr); ; vmm = vmm->vm_next) {
+		/* At this point:  (!vmm || addr < vmm->vm_end). */
+		if (TASK_SIZE - len < addr)
+			return -ENOMEM;
+		if (!vmm || addr + len <= vmm->vm_start)
+			return addr;
+		addr = vmm->vm_end;
+		if (do_color_align)
+			addr = COLOUR_ALIGN(addr, pgoff);
+	}
+}
+
+void arch_pick_mmap_layout(struct mm_struct *mm)
+{
+	unsigned long random_factor = 0UL;
+
+	if (current->flags & PF_RANDOMIZE) {
+		random_factor = get_random_int();
+		random_factor = random_factor << PAGE_SHIFT;
+		if (TASK_IS_32BIT_ADDR)
+			random_factor &= 0xfffffful;
+		else
+			random_factor &= 0xffffffful;
+	}
+
+	mm->mmap_base = TASK_UNMAPPED_BASE + random_factor;
+	mm->get_unmapped_area = arch_get_unmapped_area;
+	mm->unmap_area = arch_unmap_area;
+}
+
+static inline unsigned long brk_rnd(void)
+{
+	unsigned long rnd = get_random_int();
+
+	rnd = rnd << PAGE_SHIFT;
+	/* 8MB for 32bit, 256MB for 64bit */
+	if (TASK_IS_32BIT_ADDR)
+		rnd = rnd & 0x7ffffful;
+	else
+		rnd = rnd & 0xffffffful;
+
+	return rnd;
+}
+
+unsigned long arch_randomize_brk(struct mm_struct *mm)
+{
+	unsigned long base = mm->brk;
+	unsigned long ret;
+
+	ret = PAGE_ALIGN(base + brk_rnd());
+
+	if (ret < mm->brk)
+		return mm->brk;
+
+	return ret;
+}
diff -druN linux-2.6.39-libre/arch/mips/mm/sc-ip22.c linux-3.0-rc7-libre/arch/mips/mm/sc-ip22.c
--- linux-2.6.39-libre/arch/mips/mm/sc-ip22.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/mips/mm/sc-ip22.c	2011-07-11 19:51:52.000000000 -0400
@@ -2,7 +2,7 @@
  * sc-ip22.c: Indy cache management functions.
  *
  * Copyright (C) 1997, 2001 Ralf Baechle (ralf@gnu.org),
- * derived from r4xx0.c by David S. Miller (dm@engr.sgi.com).
+ * derived from r4xx0.c by David S. Miller (davem@davemloft.net).
  */
 #include <linux/init.h>
 #include <linux/kernel.h>
diff -druN linux-2.6.39-libre/arch/mips/mm/sc-r5k.c linux-3.0-rc7-libre/arch/mips/mm/sc-r5k.c
--- linux-2.6.39-libre/arch/mips/mm/sc-r5k.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/mips/mm/sc-r5k.c	2011-07-11 19:51:52.000000000 -0400
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 1997, 2001 Ralf Baechle (ralf@gnu.org),
- * derived from r4xx0.c by David S. Miller (dm@engr.sgi.com).
+ * derived from r4xx0.c by David S. Miller (davem@davemloft.net).
  */
 #include <linux/init.h>
 #include <linux/kernel.h>
diff -druN linux-2.6.39-libre/arch/mips/mm/tlbex.c linux-3.0-rc7-libre/arch/mips/mm/tlbex.c
--- linux-2.6.39-libre/arch/mips/mm/tlbex.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/mips/mm/tlbex.c	2011-07-11 19:51:52.000000000 -0400
@@ -404,6 +404,7 @@
 	case CPU_5KC:
 	case CPU_TX49XX:
 	case CPU_PR4450:
+	case CPU_XLR:
 		uasm_i_nop(p);
 		tlbw(p);
 		break;
diff -druN linux-2.6.39-libre/arch/mips/mm/tlb-r3k.c linux-3.0-rc7-libre/arch/mips/mm/tlb-r3k.c
--- linux-2.6.39-libre/arch/mips/mm/tlb-r3k.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/mips/mm/tlb-r3k.c	2011-07-11 19:51:52.000000000 -0400
@@ -1,7 +1,7 @@
 /*
  * r2300.c: R2000 and R3000 specific mmu/cache code.
  *
- * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
+ * Copyright (C) 1996 David S. Miller (davem@davemloft.net)
  *
  * with a lot of changes to make this thing work for R3000s
  * Tx39XX R4k style caches added. HK
diff -druN linux-2.6.39-libre/arch/mips/mm/tlb-r4k.c linux-3.0-rc7-libre/arch/mips/mm/tlb-r4k.c
--- linux-2.6.39-libre/arch/mips/mm/tlb-r4k.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/mips/mm/tlb-r4k.c	2011-07-11 19:51:52.000000000 -0400
@@ -3,7 +3,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
+ * Copyright (C) 1996 David S. Miller (davem@davemloft.net)
  * Copyright (C) 1997, 1998, 1999, 2000 Ralf Baechle ralf@gnu.org
  * Carsten Langgaard, carstenl@mips.com
  * Copyright (C) 2002 MIPS Technologies, Inc.  All rights reserved.
diff -druN linux-2.6.39-libre/arch/mips/mm/tlb-r8k.c linux-3.0-rc7-libre/arch/mips/mm/tlb-r8k.c
--- linux-2.6.39-libre/arch/mips/mm/tlb-r8k.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/mips/mm/tlb-r8k.c	2011-07-11 19:51:52.000000000 -0400
@@ -3,7 +3,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
+ * Copyright (C) 1996 David S. Miller (davem@davemloft.net)
  * Copyright (C) 1997, 1998, 1999, 2000 Ralf Baechle ralf@gnu.org
  * Carsten Langgaard, carstenl@mips.com
  * Copyright (C) 2002 MIPS Technologies, Inc.  All rights reserved.
diff -druN linux-2.6.39-libre/arch/mips/mti-malta/malta-int.c linux-3.0-rc7-libre/arch/mips/mti-malta/malta-int.c
--- linux-2.6.39-libre/arch/mips/mti-malta/malta-int.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/mips/mti-malta/malta-int.c	2011-07-11 19:51:52.000000000 -0400
@@ -308,6 +308,8 @@
 
 static irqreturn_t ipi_resched_interrupt(int irq, void *dev_id)
 {
+	scheduler_ipi();
+
 	return IRQ_HANDLED;
 }
 
diff -druN linux-2.6.39-libre/arch/mips/netlogic/Kconfig linux-3.0-rc7-libre/arch/mips/netlogic/Kconfig
--- linux-2.6.39-libre/arch/mips/netlogic/Kconfig	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/mips/netlogic/Kconfig	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,5 @@
+config NLM_COMMON
+	bool
+
+config NLM_XLR
+	bool
diff -druN linux-2.6.39-libre/arch/mips/netlogic/xlr/irq.c linux-3.0-rc7-libre/arch/mips/netlogic/xlr/irq.c
--- linux-2.6.39-libre/arch/mips/netlogic/xlr/irq.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/mips/netlogic/xlr/irq.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,300 @@
+/*
+ * Copyright 2003-2011 NetLogic Microsystems, Inc. (NetLogic). 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 NetLogic
+ * license below:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NETLOGIC ``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 NETLOGIC OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/linkage.h>
+#include <linux/interrupt.h>
+#include <linux/spinlock.h>
+#include <linux/mm.h>
+
+#include <asm/mipsregs.h>
+
+#include <asm/netlogic/xlr/iomap.h>
+#include <asm/netlogic/xlr/pic.h>
+#include <asm/netlogic/xlr/xlr.h>
+
+#include <asm/netlogic/interrupt.h>
+#include <asm/netlogic/mips-extns.h>
+
+static u64 nlm_irq_mask;
+static DEFINE_SPINLOCK(nlm_pic_lock);
+
+static void xlr_pic_enable(struct irq_data *d)
+{
+	nlm_reg_t *mmio = netlogic_io_mmio(NETLOGIC_IO_PIC_OFFSET);
+	unsigned long flags;
+	nlm_reg_t reg;
+	int irq = d->irq;
+
+	WARN(!PIC_IRQ_IS_IRT(irq), "Bad irq %d", irq);
+
+	spin_lock_irqsave(&nlm_pic_lock, flags);
+	reg = netlogic_read_reg(mmio, PIC_IRT_1_BASE + irq - PIC_IRQ_BASE);
+	netlogic_write_reg(mmio, PIC_IRT_1_BASE + irq - PIC_IRQ_BASE,
+			  reg | (1 << 6) | (1 << 30) | (1 << 31));
+	spin_unlock_irqrestore(&nlm_pic_lock, flags);
+}
+
+static void xlr_pic_mask(struct irq_data *d)
+{
+	nlm_reg_t *mmio = netlogic_io_mmio(NETLOGIC_IO_PIC_OFFSET);
+	unsigned long flags;
+	nlm_reg_t reg;
+	int irq = d->irq;
+
+	WARN(!PIC_IRQ_IS_IRT(irq), "Bad irq %d", irq);
+
+	spin_lock_irqsave(&nlm_pic_lock, flags);
+	reg = netlogic_read_reg(mmio, PIC_IRT_1_BASE + irq - PIC_IRQ_BASE);
+	netlogic_write_reg(mmio, PIC_IRT_1_BASE + irq - PIC_IRQ_BASE,
+			  reg | (1 << 6) | (1 << 30) | (0 << 31));
+	spin_unlock_irqrestore(&nlm_pic_lock, flags);
+}
+
+#ifdef CONFIG_PCI
+/* Extra ACK needed for XLR on chip PCI controller */
+static void xlr_pci_ack(struct irq_data *d)
+{
+	nlm_reg_t *pci_mmio = netlogic_io_mmio(NETLOGIC_IO_PCIX_OFFSET);
+
+	netlogic_read_reg(pci_mmio, (0x140 >> 2));
+}
+
+/* Extra ACK needed for XLS on chip PCIe controller */
+static void xls_pcie_ack(struct irq_data *d)
+{
+	nlm_reg_t *pcie_mmio_le = netlogic_io_mmio(NETLOGIC_IO_PCIE_1_OFFSET);
+
+	switch (d->irq) {
+	case PIC_PCIE_LINK0_IRQ:
+		netlogic_write_reg(pcie_mmio_le, (0x90 >> 2), 0xffffffff);
+		break;
+	case PIC_PCIE_LINK1_IRQ:
+		netlogic_write_reg(pcie_mmio_le, (0x94 >> 2), 0xffffffff);
+		break;
+	case PIC_PCIE_LINK2_IRQ:
+		netlogic_write_reg(pcie_mmio_le, (0x190 >> 2), 0xffffffff);
+		break;
+	case PIC_PCIE_LINK3_IRQ:
+		netlogic_write_reg(pcie_mmio_le, (0x194 >> 2), 0xffffffff);
+		break;
+	}
+}
+
+/* For XLS B silicon, the 3,4 PCI interrupts are different */
+static void xls_pcie_ack_b(struct irq_data *d)
+{
+	nlm_reg_t *pcie_mmio_le = netlogic_io_mmio(NETLOGIC_IO_PCIE_1_OFFSET);
+
+	switch (d->irq) {
+	case PIC_PCIE_LINK0_IRQ:
+		netlogic_write_reg(pcie_mmio_le, (0x90 >> 2), 0xffffffff);
+		break;
+	case PIC_PCIE_LINK1_IRQ:
+		netlogic_write_reg(pcie_mmio_le, (0x94 >> 2), 0xffffffff);
+		break;
+	case PIC_PCIE_XLSB0_LINK2_IRQ:
+		netlogic_write_reg(pcie_mmio_le, (0x190 >> 2), 0xffffffff);
+		break;
+	case PIC_PCIE_XLSB0_LINK3_IRQ:
+		netlogic_write_reg(pcie_mmio_le, (0x194 >> 2), 0xffffffff);
+		break;
+	}
+}
+#endif
+
+static void xlr_pic_ack(struct irq_data *d)
+{
+	unsigned long flags;
+	nlm_reg_t *mmio;
+	int irq = d->irq;
+	void *hd = irq_data_get_irq_handler_data(d);
+
+	WARN(!PIC_IRQ_IS_IRT(irq), "Bad irq %d", irq);
+
+	if (hd) {
+		void (*extra_ack)(void *) = hd;
+		extra_ack(d);
+	}
+	mmio = netlogic_io_mmio(NETLOGIC_IO_PIC_OFFSET);
+	spin_lock_irqsave(&nlm_pic_lock, flags);
+	netlogic_write_reg(mmio, PIC_INT_ACK, (1 << (irq - PIC_IRQ_BASE)));
+	spin_unlock_irqrestore(&nlm_pic_lock, flags);
+}
+
+/*
+ * This chip definition handles interrupts routed thru the XLR
+ * hardware PIC, currently IRQs 8-39 are mapped to hardware intr
+ * 0-31 wired the XLR PIC
+ */
+static struct irq_chip xlr_pic = {
+	.name		= "XLR-PIC",
+	.irq_enable	= xlr_pic_enable,
+	.irq_mask	= xlr_pic_mask,
+	.irq_ack	= xlr_pic_ack,
+};
+
+static void rsvd_irq_handler(struct irq_data *d)
+{
+	WARN(d->irq >= PIC_IRQ_BASE, "Bad irq %d", d->irq);
+}
+
+/*
+ * Chip definition for CPU originated interrupts(timer, msg) and
+ * IPIs
+ */
+struct irq_chip nlm_cpu_intr = {
+	.name		= "XLR-CPU-INTR",
+	.irq_enable	= rsvd_irq_handler,
+	.irq_mask	= rsvd_irq_handler,
+	.irq_ack	= rsvd_irq_handler,
+};
+
+void __init init_xlr_irqs(void)
+{
+	nlm_reg_t *mmio = netlogic_io_mmio(NETLOGIC_IO_PIC_OFFSET);
+	uint32_t thread_mask = 1;
+	int level, i;
+
+	pr_info("Interrupt thread mask [%x]\n", thread_mask);
+	for (i = 0; i < PIC_NUM_IRTS; i++) {
+		level = PIC_IRQ_IS_EDGE_TRIGGERED(i);
+
+		/* Bind all PIC irqs to boot cpu */
+		netlogic_write_reg(mmio, PIC_IRT_0_BASE + i, thread_mask);
+
+		/*
+		 * Use local scheduling and high polarity for all IRTs
+		 * Invalidate all IRTs, by default
+		 */
+		netlogic_write_reg(mmio, PIC_IRT_1_BASE + i,
+				(level << 30) | (1 << 6) | (PIC_IRQ_BASE + i));
+	}
+
+	/* Make all IRQs as level triggered by default */
+	for (i = 0; i < NR_IRQS; i++) {
+		if (PIC_IRQ_IS_IRT(i))
+			irq_set_chip_and_handler(i, &xlr_pic, handle_level_irq);
+		else
+			irq_set_chip_and_handler(i, &nlm_cpu_intr,
+						handle_level_irq);
+	}
+#ifdef CONFIG_SMP
+	irq_set_chip_and_handler(IRQ_IPI_SMP_FUNCTION, &nlm_cpu_intr,
+			 nlm_smp_function_ipi_handler);
+	irq_set_chip_and_handler(IRQ_IPI_SMP_RESCHEDULE, &nlm_cpu_intr,
+			 nlm_smp_resched_ipi_handler);
+	nlm_irq_mask |=
+	    ((1ULL << IRQ_IPI_SMP_FUNCTION) | (1ULL << IRQ_IPI_SMP_RESCHEDULE));
+#endif
+
+#ifdef CONFIG_PCI
+	/*
+	 * For PCI interrupts, we need to ack the PIC controller too, overload
+	 * irq handler data to do this
+	 */
+	if (nlm_chip_is_xls()) {
+		if (nlm_chip_is_xls_b()) {
+			irq_set_handler_data(PIC_PCIE_LINK0_IRQ,
+							xls_pcie_ack_b);
+			irq_set_handler_data(PIC_PCIE_LINK1_IRQ,
+							xls_pcie_ack_b);
+			irq_set_handler_data(PIC_PCIE_XLSB0_LINK2_IRQ,
+							xls_pcie_ack_b);
+			irq_set_handler_data(PIC_PCIE_XLSB0_LINK3_IRQ,
+							xls_pcie_ack_b);
+		} else {
+			irq_set_handler_data(PIC_PCIE_LINK0_IRQ, xls_pcie_ack);
+			irq_set_handler_data(PIC_PCIE_LINK1_IRQ, xls_pcie_ack);
+			irq_set_handler_data(PIC_PCIE_LINK2_IRQ, xls_pcie_ack);
+			irq_set_handler_data(PIC_PCIE_LINK3_IRQ, xls_pcie_ack);
+		}
+	} else {
+		/* XLR PCI controller ACK */
+		irq_set_handler_data(PIC_PCIE_XLSB0_LINK3_IRQ, xlr_pci_ack);
+	}
+#endif
+	/* unmask all PIC related interrupts. If no handler is installed by the
+	 * drivers, it'll just ack the interrupt and return
+	 */
+	for (i = PIC_IRT_FIRST_IRQ; i <= PIC_IRT_LAST_IRQ; i++)
+		nlm_irq_mask |= (1ULL << i);
+
+	nlm_irq_mask |= (1ULL << IRQ_TIMER);
+}
+
+void __init arch_init_irq(void)
+{
+	/* Initialize the irq descriptors */
+	init_xlr_irqs();
+	write_c0_eimr(nlm_irq_mask);
+}
+
+void __cpuinit nlm_smp_irq_init(void)
+{
+	/* set interrupt mask for non-zero cpus */
+	write_c0_eimr(nlm_irq_mask);
+}
+
+asmlinkage void plat_irq_dispatch(void)
+{
+	uint64_t eirr;
+	int i;
+
+	eirr = read_c0_eirr() & read_c0_eimr();
+	if (!eirr)
+		return;
+
+	/* no need of EIRR here, writing compare clears interrupt */
+	if (eirr & (1 << IRQ_TIMER)) {
+		do_IRQ(IRQ_TIMER);
+		return;
+	}
+
+	/* use dcltz: optimize below code */
+	for (i = 63; i != -1; i--) {
+		if (eirr & (1ULL << i))
+			break;
+	}
+	if (i == -1) {
+		pr_err("no interrupt !!\n");
+		return;
+	}
+
+	/* Ack eirr */
+	write_c0_eirr(1ULL << i);
+
+	do_IRQ(i);
+}
diff -druN linux-2.6.39-libre/arch/mips/netlogic/xlr/Makefile linux-3.0-rc7-libre/arch/mips/netlogic/xlr/Makefile
--- linux-2.6.39-libre/arch/mips/netlogic/xlr/Makefile	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/mips/netlogic/xlr/Makefile	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,5 @@
+obj-y				+= setup.o platform.o irq.o setup.o time.o
+obj-$(CONFIG_SMP)		+= smp.o smpboot.o
+obj-$(CONFIG_EARLY_PRINTK)	+= xlr_console.o
+
+EXTRA_CFLAGS			+= -Werror
diff -druN linux-2.6.39-libre/arch/mips/netlogic/xlr/platform.c linux-3.0-rc7-libre/arch/mips/netlogic/xlr/platform.c
--- linux-2.6.39-libre/arch/mips/netlogic/xlr/platform.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/mips/netlogic/xlr/platform.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,98 @@
+/*
+ * Copyright 2011, Netlogic Microsystems.
+ * Copyright 2004, Matt Porter <mporter@kernel.crashing.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.
+ */
+
+#include <linux/device.h>
+#include <linux/platform_device.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/resource.h>
+#include <linux/serial_8250.h>
+#include <linux/serial_reg.h>
+
+#include <asm/netlogic/xlr/iomap.h>
+#include <asm/netlogic/xlr/pic.h>
+#include <asm/netlogic/xlr/xlr.h>
+
+unsigned int nlm_xlr_uart_in(struct uart_port *p, int offset)
+{
+	nlm_reg_t *mmio;
+	unsigned int value;
+
+	/* XLR uart does not need any mapping of regs */
+	mmio = (nlm_reg_t *)(p->membase + (offset << p->regshift));
+	value = netlogic_read_reg(mmio, 0);
+
+	/* See XLR/XLS errata */
+	if (offset == UART_MSR)
+		value ^= 0xF0;
+	else if (offset == UART_MCR)
+		value ^= 0x3;
+
+	return value;
+}
+
+void nlm_xlr_uart_out(struct uart_port *p, int offset, int value)
+{
+	nlm_reg_t *mmio;
+
+	/* XLR uart does not need any mapping of regs */
+	mmio = (nlm_reg_t *)(p->membase + (offset << p->regshift));
+
+	/* See XLR/XLS errata */
+	if (offset == UART_MSR)
+		value ^= 0xF0;
+	else if (offset == UART_MCR)
+		value ^= 0x3;
+
+	netlogic_write_reg(mmio, 0, value);
+}
+
+#define PORT(_irq)					\
+	{						\
+		.irq		= _irq,			\
+		.regshift	= 2,			\
+		.iotype		= UPIO_MEM32,		\
+		.flags		= (UPF_SKIP_TEST |	\
+			 UPF_FIXED_TYPE | UPF_BOOT_AUTOCONF),\
+		.uartclk	= PIC_CLKS_PER_SEC,	\
+		.type		= PORT_16550A,		\
+		.serial_in	= nlm_xlr_uart_in,	\
+		.serial_out	= nlm_xlr_uart_out,	\
+	}
+
+static struct plat_serial8250_port xlr_uart_data[] = {
+	PORT(PIC_UART_0_IRQ),
+	PORT(PIC_UART_1_IRQ),
+	{},
+};
+
+static struct platform_device uart_device = {
+	.name		= "serial8250",
+	.id		= PLAT8250_DEV_PLATFORM,
+	.dev = {
+		.platform_data = xlr_uart_data,
+	},
+};
+
+static int __init nlm_uart_init(void)
+{
+	nlm_reg_t *mmio;
+
+	mmio = netlogic_io_mmio(NETLOGIC_IO_UART_0_OFFSET);
+	xlr_uart_data[0].membase = (void __iomem *)mmio;
+	xlr_uart_data[0].mapbase = CPHYSADDR((unsigned long)mmio);
+
+	mmio = netlogic_io_mmio(NETLOGIC_IO_UART_1_OFFSET);
+	xlr_uart_data[1].membase = (void __iomem *)mmio;
+	xlr_uart_data[1].mapbase = CPHYSADDR((unsigned long)mmio);
+
+	return platform_device_register(&uart_device);
+}
+
+arch_initcall(nlm_uart_init);
diff -druN linux-2.6.39-libre/arch/mips/netlogic/xlr/setup.c linux-3.0-rc7-libre/arch/mips/netlogic/xlr/setup.c
--- linux-2.6.39-libre/arch/mips/netlogic/xlr/setup.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/mips/netlogic/xlr/setup.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,188 @@
+/*
+ * Copyright 2003-2011 NetLogic Microsystems, Inc. (NetLogic). 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 NetLogic
+ * license below:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NETLOGIC ``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 NETLOGIC OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <linux/kernel.h>
+#include <linux/serial_8250.h>
+#include <linux/pm.h>
+
+#include <asm/reboot.h>
+#include <asm/time.h>
+#include <asm/bootinfo.h>
+#include <asm/smp-ops.h>
+
+#include <asm/netlogic/interrupt.h>
+#include <asm/netlogic/psb-bootinfo.h>
+
+#include <asm/netlogic/xlr/xlr.h>
+#include <asm/netlogic/xlr/iomap.h>
+#include <asm/netlogic/xlr/pic.h>
+#include <asm/netlogic/xlr/gpio.h>
+
+unsigned long netlogic_io_base = (unsigned long)(DEFAULT_NETLOGIC_IO_BASE);
+unsigned long nlm_common_ebase = 0x0;
+struct psb_info nlm_prom_info;
+
+static void nlm_early_serial_setup(void)
+{
+	struct uart_port s;
+	nlm_reg_t *uart_base;
+
+	uart_base = netlogic_io_mmio(NETLOGIC_IO_UART_0_OFFSET);
+	memset(&s, 0, sizeof(s));
+	s.flags		= ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST;
+	s.iotype	= UPIO_MEM32;
+	s.regshift	= 2;
+	s.irq		= PIC_UART_0_IRQ;
+	s.uartclk	= PIC_CLKS_PER_SEC;
+	s.serial_in	= nlm_xlr_uart_in;
+	s.serial_out	= nlm_xlr_uart_out;
+	s.mapbase	= (unsigned long)uart_base;
+	s.membase	= (unsigned char __iomem *)uart_base;
+	early_serial_setup(&s);
+}
+
+static void nlm_linux_exit(void)
+{
+	nlm_reg_t *mmio;
+
+	mmio = netlogic_io_mmio(NETLOGIC_IO_GPIO_OFFSET);
+	/* trigger a chip reset by writing 1 to GPIO_SWRESET_REG */
+	netlogic_write_reg(mmio, NETLOGIC_GPIO_SWRESET_REG, 1);
+	for ( ; ; )
+		cpu_wait();
+}
+
+void __init plat_mem_setup(void)
+{
+	panic_timeout	= 5;
+	_machine_restart = (void (*)(char *))nlm_linux_exit;
+	_machine_halt	= nlm_linux_exit;
+	pm_power_off	= nlm_linux_exit;
+}
+
+const char *get_system_type(void)
+{
+	return "Netlogic XLR/XLS Series";
+}
+
+void __init prom_free_prom_memory(void)
+{
+	/* Nothing yet */
+}
+
+static void build_arcs_cmdline(int *argv)
+{
+	int i, remain, len;
+	char *arg;
+
+	remain = sizeof(arcs_cmdline) - 1;
+	arcs_cmdline[0] = '\0';
+	for (i = 0; argv[i] != 0; i++) {
+		arg = (char *)(long)argv[i];
+		len = strlen(arg);
+		if (len + 1 > remain)
+			break;
+		strcat(arcs_cmdline, arg);
+		strcat(arcs_cmdline, " ");
+		remain -=  len + 1;
+	}
+
+	/* Add the default options here */
+	if ((strstr(arcs_cmdline, "console=")) == NULL) {
+		arg = "console=ttyS0,38400 ";
+		len = strlen(arg);
+		if (len > remain)
+			goto fail;
+		strcat(arcs_cmdline, arg);
+		remain -= len;
+	}
+#ifdef CONFIG_BLK_DEV_INITRD
+	if ((strstr(arcs_cmdline, "rdinit=")) == NULL) {
+		arg = "rdinit=/sbin/init ";
+		len = strlen(arg);
+		if (len > remain)
+			goto fail;
+		strcat(arcs_cmdline, arg);
+		remain -= len;
+	}
+#endif
+	return;
+fail:
+	panic("Cannot add %s, command line too big!", arg);
+}
+
+static void prom_add_memory(void)
+{
+	struct nlm_boot_mem_map *bootm;
+	u64 start, size;
+	u64 pref_backup = 512;  /* avoid pref walking beyond end */
+	int i;
+
+	bootm = (void *)(long)nlm_prom_info.psb_mem_map;
+	for (i = 0; i < bootm->nr_map; i++) {
+		if (bootm->map[i].type != BOOT_MEM_RAM)
+			continue;
+		start = bootm->map[i].addr;
+		size   = bootm->map[i].size;
+
+		/* Work around for using bootloader mem */
+		if (i == 0 && start == 0 && size == 0x0c000000)
+			size = 0x0ff00000;
+
+		add_memory_region(start, size - pref_backup, BOOT_MEM_RAM);
+	}
+}
+
+void __init prom_init(void)
+{
+	int *argv, *envp;		/* passed as 32 bit ptrs */
+	struct psb_info *prom_infop;
+
+	/* truncate to 32 bit and sign extend all args */
+	argv = (int *)(long)(int)fw_arg1;
+	envp = (int *)(long)(int)fw_arg2;
+	prom_infop = (struct psb_info *)(long)(int)fw_arg3;
+
+	nlm_prom_info = *prom_infop;
+
+	nlm_early_serial_setup();
+	build_arcs_cmdline(argv);
+	nlm_common_ebase = read_c0_ebase() & (~((1 << 12) - 1));
+	prom_add_memory();
+
+#ifdef CONFIG_SMP
+	nlm_wakeup_secondary_cpus(nlm_prom_info.online_cpu_map);
+	register_smp_ops(&nlm_smp_ops);
+#endif
+}
diff -druN linux-2.6.39-libre/arch/mips/netlogic/xlr/smpboot.S linux-3.0-rc7-libre/arch/mips/netlogic/xlr/smpboot.S
--- linux-2.6.39-libre/arch/mips/netlogic/xlr/smpboot.S	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/mips/netlogic/xlr/smpboot.S	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,94 @@
+/*
+ * Copyright 2003-2011 NetLogic Microsystems, Inc. (NetLogic). 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 NetLogic
+ * license below:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NETLOGIC ``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 NETLOGIC OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <asm/asm.h>
+#include <asm/asm-offsets.h>
+#include <asm/regdef.h>
+#include <asm/mipsregs.h>
+
+
+/* Don't jump to linux function from Bootloader stack. Change it
+ * here. Kernel might allocate bootloader memory before all the CPUs are
+ * brought up (eg: Inode cache region) and we better don't overwrite this
+ * memory
+ */
+NESTED(prom_pre_boot_secondary_cpus, 16, sp)
+	.set	mips64
+	mfc0	t0, $15, 1	# read ebase
+	andi	t0, 0x1f	# t0 has the processor_id()
+	sll	t0, 2		# offset in cpu array
+
+	PTR_LA	t1, nlm_cpu_ready # mark CPU ready
+	PTR_ADDU t1, t0
+	li	t2, 1
+	sw	t2, 0(t1)
+
+	PTR_LA	t1, nlm_cpu_unblock
+	PTR_ADDU t1, t0
+1:	lw	t2, 0(t1)	# wait till unblocked
+	beqz	t2, 1b
+	nop
+
+	PTR_LA	t1, nlm_next_sp
+	PTR_L	sp, 0(t1)
+	PTR_LA	t1, nlm_next_gp
+	PTR_L	gp, 0(t1)
+
+	PTR_LA	t0, nlm_early_init_secondary
+	jalr	t0
+	nop
+
+	PTR_LA	t0, smp_bootstrap
+	jr	t0
+	nop
+END(prom_pre_boot_secondary_cpus)
+
+NESTED(nlm_boot_smp_nmi, 0, sp)
+	.set push
+	.set noat
+	.set mips64
+	.set noreorder
+
+	/* Clear the  NMI and BEV bits */
+	MFC0	k0, CP0_STATUS
+	li 	k1, 0xffb7ffff
+	and	k0, k0, k1
+	MTC0	k0, CP0_STATUS
+
+	PTR_LA  k1, secondary_entry_point
+	PTR_L	k0, 0(k1)
+	jr	k0
+	nop
+	.set pop
+END(nlm_boot_smp_nmi)
diff -druN linux-2.6.39-libre/arch/mips/netlogic/xlr/smp.c linux-3.0-rc7-libre/arch/mips/netlogic/xlr/smp.c
--- linux-2.6.39-libre/arch/mips/netlogic/xlr/smp.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/mips/netlogic/xlr/smp.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,225 @@
+/*
+ * Copyright 2003-2011 NetLogic Microsystems, Inc. (NetLogic). 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 NetLogic
+ * license below:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NETLOGIC ``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 NETLOGIC OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <linux/kernel.h>
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/smp.h>
+#include <linux/irq.h>
+
+#include <asm/mmu_context.h>
+
+#include <asm/netlogic/interrupt.h>
+#include <asm/netlogic/mips-extns.h>
+
+#include <asm/netlogic/xlr/iomap.h>
+#include <asm/netlogic/xlr/pic.h>
+#include <asm/netlogic/xlr/xlr.h>
+
+void core_send_ipi(int logical_cpu, unsigned int action)
+{
+	int cpu = cpu_logical_map(logical_cpu);
+	u32 tid = cpu & 0x3;
+	u32 pid = (cpu >> 2) & 0x07;
+	u32 ipi = (tid << 16) | (pid << 20);
+
+	if (action & SMP_CALL_FUNCTION)
+		ipi |= IRQ_IPI_SMP_FUNCTION;
+	else if (action & SMP_RESCHEDULE_YOURSELF)
+		ipi |= IRQ_IPI_SMP_RESCHEDULE;
+	else
+		return;
+
+	pic_send_ipi(ipi);
+}
+
+void nlm_send_ipi_single(int cpu, unsigned int action)
+{
+	core_send_ipi(cpu, action);
+}
+
+void nlm_send_ipi_mask(const struct cpumask *mask, unsigned int action)
+{
+	int cpu;
+
+	for_each_cpu(cpu, mask) {
+		core_send_ipi(cpu, action);
+	}
+}
+
+/* IRQ_IPI_SMP_FUNCTION Handler */
+void nlm_smp_function_ipi_handler(unsigned int irq, struct irq_desc *desc)
+{
+	smp_call_function_interrupt();
+}
+
+/* IRQ_IPI_SMP_RESCHEDULE  handler */
+void nlm_smp_resched_ipi_handler(unsigned int irq, struct irq_desc *desc)
+{
+	set_need_resched();
+}
+
+void nlm_common_ipi_handler(int irq, struct pt_regs *regs)
+{
+	if (irq == IRQ_IPI_SMP_FUNCTION) {
+		smp_call_function_interrupt();
+	} else {
+		/* Announce that we are for reschduling */
+		set_need_resched();
+	}
+}
+
+/*
+ * Called before going into mips code, early cpu init
+ */
+void nlm_early_init_secondary(void)
+{
+	write_c0_ebase((uint32_t)nlm_common_ebase);
+	/* TLB partition here later */
+}
+
+/*
+ * Code to run on secondary just after probing the CPU
+ */
+static void __cpuinit nlm_init_secondary(void)
+{
+	nlm_smp_irq_init();
+}
+
+void nlm_smp_finish(void)
+{
+#ifdef notyet
+	nlm_common_msgring_cpu_init();
+#endif
+}
+
+void nlm_cpus_done(void)
+{
+}
+
+/*
+ * Boot all other cpus in the system, initialize them, and bring them into
+ * the boot function
+ */
+int nlm_cpu_unblock[NR_CPUS];
+int nlm_cpu_ready[NR_CPUS];
+unsigned long nlm_next_gp;
+unsigned long nlm_next_sp;
+cpumask_t phys_cpu_present_map;
+
+void nlm_boot_secondary(int logical_cpu, struct task_struct *idle)
+{
+	unsigned long gp = (unsigned long)task_thread_info(idle);
+	unsigned long sp = (unsigned long)__KSTK_TOS(idle);
+	int cpu = cpu_logical_map(logical_cpu);
+
+	nlm_next_sp = sp;
+	nlm_next_gp = gp;
+
+	/* barrier */
+	__sync();
+	nlm_cpu_unblock[cpu] = 1;
+}
+
+void __init nlm_smp_setup(void)
+{
+	unsigned int boot_cpu;
+	int num_cpus, i;
+
+	boot_cpu = hard_smp_processor_id();
+	cpus_clear(phys_cpu_present_map);
+
+	cpu_set(boot_cpu, phys_cpu_present_map);
+	__cpu_number_map[boot_cpu] = 0;
+	__cpu_logical_map[0] = boot_cpu;
+	cpu_set(0, cpu_possible_map);
+
+	num_cpus = 1;
+	for (i = 0; i < NR_CPUS; i++) {
+		if (nlm_cpu_ready[i]) {
+			cpu_set(i, phys_cpu_present_map);
+			__cpu_number_map[i] = num_cpus;
+			__cpu_logical_map[num_cpus] = i;
+			cpu_set(num_cpus, cpu_possible_map);
+			++num_cpus;
+		}
+	}
+
+	pr_info("Phys CPU present map: %lx, possible map %lx\n",
+		(unsigned long)phys_cpu_present_map.bits[0],
+		(unsigned long)cpu_possible_map.bits[0]);
+
+	pr_info("Detected %i Slave CPU(s)\n", num_cpus);
+}
+
+void nlm_prepare_cpus(unsigned int max_cpus)
+{
+}
+
+struct plat_smp_ops nlm_smp_ops = {
+	.send_ipi_single	= nlm_send_ipi_single,
+	.send_ipi_mask		= nlm_send_ipi_mask,
+	.init_secondary		= nlm_init_secondary,
+	.smp_finish		= nlm_smp_finish,
+	.cpus_done		= nlm_cpus_done,
+	.boot_secondary		= nlm_boot_secondary,
+	.smp_setup		= nlm_smp_setup,
+	.prepare_cpus		= nlm_prepare_cpus,
+};
+
+unsigned long secondary_entry_point;
+
+int nlm_wakeup_secondary_cpus(u32 wakeup_mask)
+{
+	unsigned int tid, pid, ipi, i, boot_cpu;
+	void *reset_vec;
+
+	secondary_entry_point = (unsigned long)prom_pre_boot_secondary_cpus;
+	reset_vec = (void *)CKSEG1ADDR(0x1fc00000);
+	memcpy(reset_vec, nlm_boot_smp_nmi, 0x80);
+	boot_cpu = hard_smp_processor_id();
+
+	for (i = 0; i < NR_CPUS; i++) {
+		if (i == boot_cpu)
+			continue;
+		if (wakeup_mask & (1u << i)) {
+			tid = i & 0x3;
+			pid = (i >> 2) & 0x7;
+			ipi = (tid << 16) | (pid << 20) | (1 << 8);
+			pic_send_ipi(ipi);
+		}
+	}
+
+	return 0;
+}
diff -druN linux-2.6.39-libre/arch/mips/netlogic/xlr/time.c linux-3.0-rc7-libre/arch/mips/netlogic/xlr/time.c
--- linux-2.6.39-libre/arch/mips/netlogic/xlr/time.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/mips/netlogic/xlr/time.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2003-2011 NetLogic Microsystems, Inc. (NetLogic). 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 NetLogic
+ * license below:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NETLOGIC ``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 NETLOGIC OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <linux/init.h>
+
+#include <asm/time.h>
+#include <asm/netlogic/interrupt.h>
+#include <asm/netlogic/psb-bootinfo.h>
+
+unsigned int __cpuinit get_c0_compare_int(void)
+{
+	return IRQ_TIMER;
+}
+
+void __init plat_time_init(void)
+{
+	mips_hpt_frequency = nlm_prom_info.cpu_frequency;
+	pr_info("MIPS counter frequency [%ld]\n",
+		(unsigned long)mips_hpt_frequency);
+}
diff -druN linux-2.6.39-libre/arch/mips/netlogic/xlr/xlr_console.c linux-3.0-rc7-libre/arch/mips/netlogic/xlr/xlr_console.c
--- linux-2.6.39-libre/arch/mips/netlogic/xlr/xlr_console.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/mips/netlogic/xlr/xlr_console.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2003-2011 NetLogic Microsystems, Inc. (NetLogic). 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 NetLogic
+ * license below:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NETLOGIC ``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 NETLOGIC OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <linux/types.h>
+#include <asm/netlogic/xlr/iomap.h>
+
+void prom_putchar(char c)
+{
+	nlm_reg_t *mmio;
+
+	mmio = netlogic_io_mmio(NETLOGIC_IO_UART_0_OFFSET);
+	while (netlogic_read_reg(mmio, 0x5) == 0)
+		;
+	netlogic_write_reg(mmio, 0x0, c);
+}
diff -druN linux-2.6.39-libre/arch/mips/pci/Makefile linux-3.0-rc7-libre/arch/mips/pci/Makefile
--- linux-2.6.39-libre/arch/mips/pci/Makefile	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/mips/pci/Makefile	2011-07-11 19:51:52.000000000 -0400
@@ -41,6 +41,7 @@
 obj-$(CONFIG_SIBYTE_BCM112X)	+= fixup-sb1250.o pci-sb1250.o
 obj-$(CONFIG_SIBYTE_BCM1x80)	+= pci-bcm1480.o pci-bcm1480ht.o
 obj-$(CONFIG_SNI_RM)		+= fixup-sni.o ops-sni.o
+obj-$(CONFIG_SOC_XWAY)		+= pci-lantiq.o ops-lantiq.o
 obj-$(CONFIG_TANBAC_TB0219)	+= fixup-tb0219.o
 obj-$(CONFIG_TANBAC_TB0226)	+= fixup-tb0226.o
 obj-$(CONFIG_TANBAC_TB0287)	+= fixup-tb0287.o
@@ -55,6 +56,7 @@
 obj-$(CONFIG_WR_PPMC)		+= fixup-wrppmc.o
 obj-$(CONFIG_MIKROTIK_RB532)	+= pci-rc32434.o ops-rc32434.o fixup-rc32434.o
 obj-$(CONFIG_CPU_CAVIUM_OCTEON)	+= pci-octeon.o pcie-octeon.o
+obj-$(CONFIG_NLM_XLR)		+= pci-xlr.o
 
 ifdef CONFIG_PCI_MSI
 obj-$(CONFIG_CPU_CAVIUM_OCTEON)	+= msi-octeon.o
diff -druN linux-2.6.39-libre/arch/mips/pci/ops-lantiq.c linux-3.0-rc7-libre/arch/mips/pci/ops-lantiq.c
--- linux-2.6.39-libre/arch/mips/pci/ops-lantiq.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/mips/pci/ops-lantiq.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,116 @@
+/*
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License version 2 as published
+ *  by the Free Software Foundation.
+ *
+ *  Copyright (C) 2010 John Crispin <blogic@openwrt.org>
+ */
+
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/mm.h>
+#include <asm/addrspace.h>
+#include <linux/vmalloc.h>
+
+#include <lantiq_soc.h>
+
+#include "pci-lantiq.h"
+
+#define LTQ_PCI_CFG_BUSNUM_SHF 16
+#define LTQ_PCI_CFG_DEVNUM_SHF 11
+#define LTQ_PCI_CFG_FUNNUM_SHF 8
+
+#define PCI_ACCESS_READ  0
+#define PCI_ACCESS_WRITE 1
+
+static int ltq_pci_config_access(unsigned char access_type, struct pci_bus *bus,
+	unsigned int devfn, unsigned int where, u32 *data)
+{
+	unsigned long cfg_base;
+	unsigned long flags;
+	u32 temp;
+
+	/* we support slot from 0 to 15 dev_fn & 0x68 (AD29) is the
+	   SoC itself */
+	if ((bus->number != 0) || ((devfn & 0xf8) > 0x78)
+		|| ((devfn & 0xf8) == 0) || ((devfn & 0xf8) == 0x68))
+		return 1;
+
+	spin_lock_irqsave(&ebu_lock, flags);
+
+	cfg_base = (unsigned long) ltq_pci_mapped_cfg;
+	cfg_base |= (bus->number << LTQ_PCI_CFG_BUSNUM_SHF) | (devfn <<
+			LTQ_PCI_CFG_FUNNUM_SHF) | (where & ~0x3);
+
+	/* Perform access */
+	if (access_type == PCI_ACCESS_WRITE) {
+		ltq_w32(swab32(*data), ((u32 *)cfg_base));
+	} else {
+		*data = ltq_r32(((u32 *)(cfg_base)));
+		*data = swab32(*data);
+	}
+	wmb();
+
+	/* clean possible Master abort */
+	cfg_base = (unsigned long) ltq_pci_mapped_cfg;
+	cfg_base |= (0x0 << LTQ_PCI_CFG_FUNNUM_SHF) + 4;
+	temp = ltq_r32(((u32 *)(cfg_base)));
+	temp = swab32(temp);
+	cfg_base = (unsigned long) ltq_pci_mapped_cfg;
+	cfg_base |= (0x68 << LTQ_PCI_CFG_FUNNUM_SHF) + 4;
+	ltq_w32(temp, ((u32 *)cfg_base));
+
+	spin_unlock_irqrestore(&ebu_lock, flags);
+
+	if (((*data) == 0xffffffff) && (access_type == PCI_ACCESS_READ))
+		return 1;
+
+	return 0;
+}
+
+int ltq_pci_read_config_dword(struct pci_bus *bus, unsigned int devfn,
+	int where, int size, u32 *val)
+{
+	u32 data = 0;
+
+	if (ltq_pci_config_access(PCI_ACCESS_READ, bus, devfn, where, &data))
+		return PCIBIOS_DEVICE_NOT_FOUND;
+
+	if (size == 1)
+		*val = (data >> ((where & 3) << 3)) & 0xff;
+	else if (size == 2)
+		*val = (data >> ((where & 3) << 3)) & 0xffff;
+	else
+		*val = data;
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+int ltq_pci_write_config_dword(struct pci_bus *bus, unsigned int devfn,
+	int where, int size, u32 val)
+{
+	u32 data = 0;
+
+	if (size == 4) {
+		data = val;
+	} else {
+		if (ltq_pci_config_access(PCI_ACCESS_READ, bus,
+				devfn, where, &data))
+			return PCIBIOS_DEVICE_NOT_FOUND;
+
+		if (size == 1)
+			data = (data & ~(0xff << ((where & 3) << 3))) |
+				(val << ((where & 3) << 3));
+		else if (size == 2)
+			data = (data & ~(0xffff << ((where & 3) << 3))) |
+				(val << ((where & 3) << 3));
+	}
+
+	if (ltq_pci_config_access(PCI_ACCESS_WRITE, bus, devfn, where, &data))
+		return PCIBIOS_DEVICE_NOT_FOUND;
+
+	return PCIBIOS_SUCCESSFUL;
+}
diff -druN linux-2.6.39-libre/arch/mips/pci/pci-lantiq.c linux-3.0-rc7-libre/arch/mips/pci/pci-lantiq.c
--- linux-2.6.39-libre/arch/mips/pci/pci-lantiq.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/mips/pci/pci-lantiq.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,297 @@
+/*
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License version 2 as published
+ *  by the Free Software Foundation.
+ *
+ *  Copyright (C) 2010 John Crispin <blogic@openwrt.org>
+ */
+
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/mm.h>
+#include <linux/vmalloc.h>
+#include <linux/platform_device.h>
+
+#include <asm/pci.h>
+#include <asm/gpio.h>
+#include <asm/addrspace.h>
+
+#include <lantiq_soc.h>
+#include <lantiq_irq.h>
+#include <lantiq_platform.h>
+
+#include "pci-lantiq.h"
+
+#define LTQ_PCI_CFG_BASE		0x17000000
+#define LTQ_PCI_CFG_SIZE		0x00008000
+#define LTQ_PCI_MEM_BASE		0x18000000
+#define LTQ_PCI_MEM_SIZE		0x02000000
+#define LTQ_PCI_IO_BASE			0x1AE00000
+#define LTQ_PCI_IO_SIZE			0x00200000
+
+#define PCI_CR_FCI_ADDR_MAP0		0x00C0
+#define PCI_CR_FCI_ADDR_MAP1		0x00C4
+#define PCI_CR_FCI_ADDR_MAP2		0x00C8
+#define PCI_CR_FCI_ADDR_MAP3		0x00CC
+#define PCI_CR_FCI_ADDR_MAP4		0x00D0
+#define PCI_CR_FCI_ADDR_MAP5		0x00D4
+#define PCI_CR_FCI_ADDR_MAP6		0x00D8
+#define PCI_CR_FCI_ADDR_MAP7		0x00DC
+#define PCI_CR_CLK_CTRL			0x0000
+#define PCI_CR_PCI_MOD			0x0030
+#define PCI_CR_PC_ARB			0x0080
+#define PCI_CR_FCI_ADDR_MAP11hg		0x00E4
+#define PCI_CR_BAR11MASK		0x0044
+#define PCI_CR_BAR12MASK		0x0048
+#define PCI_CR_BAR13MASK		0x004C
+#define PCI_CS_BASE_ADDR1		0x0010
+#define PCI_CR_PCI_ADDR_MAP11		0x0064
+#define PCI_CR_FCI_BURST_LENGTH		0x00E8
+#define PCI_CR_PCI_EOI			0x002C
+#define PCI_CS_STS_CMD			0x0004
+
+#define PCI_MASTER0_REQ_MASK_2BITS	8
+#define PCI_MASTER1_REQ_MASK_2BITS	10
+#define PCI_MASTER2_REQ_MASK_2BITS	12
+#define INTERNAL_ARB_ENABLE_BIT		0
+
+#define LTQ_CGU_IFCCR		0x0018
+#define LTQ_CGU_PCICR		0x0034
+
+#define ltq_pci_w32(x, y)	ltq_w32((x), ltq_pci_membase + (y))
+#define ltq_pci_r32(x)		ltq_r32(ltq_pci_membase + (x))
+
+#define ltq_pci_cfg_w32(x, y)	ltq_w32((x), ltq_pci_mapped_cfg + (y))
+#define ltq_pci_cfg_r32(x)	ltq_r32(ltq_pci_mapped_cfg + (x))
+
+struct ltq_pci_gpio_map {
+	int pin;
+	int alt0;
+	int alt1;
+	int dir;
+	char *name;
+};
+
+/* the pci core can make use of the following gpios */
+static struct ltq_pci_gpio_map ltq_pci_gpio_map[] = {
+	{ 0, 1, 0, 0, "pci-exin0" },
+	{ 1, 1, 0, 0, "pci-exin1" },
+	{ 2, 1, 0, 0, "pci-exin2" },
+	{ 39, 1, 0, 0, "pci-exin3" },
+	{ 10, 1, 0, 0, "pci-exin4" },
+	{ 9, 1, 0, 0, "pci-exin5" },
+	{ 30, 1, 0, 1, "pci-gnt1" },
+	{ 23, 1, 0, 1, "pci-gnt2" },
+	{ 19, 1, 0, 1, "pci-gnt3" },
+	{ 38, 1, 0, 1, "pci-gnt4" },
+	{ 29, 1, 0, 0, "pci-req1" },
+	{ 31, 1, 0, 0, "pci-req2" },
+	{ 3, 1, 0, 0, "pci-req3" },
+	{ 37, 1, 0, 0, "pci-req4" },
+};
+
+__iomem void *ltq_pci_mapped_cfg;
+static __iomem void *ltq_pci_membase;
+
+int (*ltqpci_plat_dev_init)(struct pci_dev *dev) = NULL;
+
+/* Since the PCI REQ pins can be reused for other functionality, make it
+   possible to exclude those from interpretation by the PCI controller */
+static int ltq_pci_req_mask = 0xf;
+
+static int *ltq_pci_irq_map;
+
+struct pci_ops ltq_pci_ops = {
+	.read	= ltq_pci_read_config_dword,
+	.write	= ltq_pci_write_config_dword
+};
+
+static struct resource pci_io_resource = {
+	.name	= "pci io space",
+	.start	= LTQ_PCI_IO_BASE,
+	.end	= LTQ_PCI_IO_BASE + LTQ_PCI_IO_SIZE - 1,
+	.flags	= IORESOURCE_IO
+};
+
+static struct resource pci_mem_resource = {
+	.name	= "pci memory space",
+	.start	= LTQ_PCI_MEM_BASE,
+	.end	= LTQ_PCI_MEM_BASE + LTQ_PCI_MEM_SIZE - 1,
+	.flags	= IORESOURCE_MEM
+};
+
+static struct pci_controller ltq_pci_controller = {
+	.pci_ops	= &ltq_pci_ops,
+	.mem_resource	= &pci_mem_resource,
+	.mem_offset	= 0x00000000UL,
+	.io_resource	= &pci_io_resource,
+	.io_offset	= 0x00000000UL,
+};
+
+int pcibios_plat_dev_init(struct pci_dev *dev)
+{
+	if (ltqpci_plat_dev_init)
+		return ltqpci_plat_dev_init(dev);
+
+	return 0;
+}
+
+static u32 ltq_calc_bar11mask(void)
+{
+	u32 mem, bar11mask;
+
+	/* BAR11MASK value depends on available memory on system. */
+	mem = num_physpages * PAGE_SIZE;
+	bar11mask = (0x0ffffff0 & ~((1 << (fls(mem) - 1)) - 1)) | 8;
+
+	return bar11mask;
+}
+
+static void ltq_pci_setup_gpio(int gpio)
+{
+	int i;
+	for (i = 0; i < ARRAY_SIZE(ltq_pci_gpio_map); i++) {
+		if (gpio & (1 << i)) {
+			ltq_gpio_request(ltq_pci_gpio_map[i].pin,
+				ltq_pci_gpio_map[i].alt0,
+				ltq_pci_gpio_map[i].alt1,
+				ltq_pci_gpio_map[i].dir,
+				ltq_pci_gpio_map[i].name);
+		}
+	}
+	ltq_gpio_request(21, 0, 0, 1, "pci-reset");
+	ltq_pci_req_mask = (gpio >> PCI_REQ_SHIFT) & PCI_REQ_MASK;
+}
+
+static int __devinit ltq_pci_startup(struct ltq_pci_data *conf)
+{
+	u32 temp_buffer;
+
+	/* set clock to 33Mhz */
+	ltq_cgu_w32(ltq_cgu_r32(LTQ_CGU_IFCCR) & ~0xf00000, LTQ_CGU_IFCCR);
+	ltq_cgu_w32(ltq_cgu_r32(LTQ_CGU_IFCCR) | 0x800000, LTQ_CGU_IFCCR);
+
+	/* external or internal clock ? */
+	if (conf->clock) {
+		ltq_cgu_w32(ltq_cgu_r32(LTQ_CGU_IFCCR) & ~(1 << 16),
+			LTQ_CGU_IFCCR);
+		ltq_cgu_w32((1 << 30), LTQ_CGU_PCICR);
+	} else {
+		ltq_cgu_w32(ltq_cgu_r32(LTQ_CGU_IFCCR) | (1 << 16),
+			LTQ_CGU_IFCCR);
+		ltq_cgu_w32((1 << 31) | (1 << 30), LTQ_CGU_PCICR);
+	}
+
+	/* setup pci clock and gpis used by pci */
+	ltq_pci_setup_gpio(conf->gpio);
+
+	/* enable auto-switching between PCI and EBU */
+	ltq_pci_w32(0xa, PCI_CR_CLK_CTRL);
+
+	/* busy, i.e. configuration is not done, PCI access has to be retried */
+	ltq_pci_w32(ltq_pci_r32(PCI_CR_PCI_MOD) & ~(1 << 24), PCI_CR_PCI_MOD);
+	wmb();
+	/* BUS Master/IO/MEM access */
+	ltq_pci_cfg_w32(ltq_pci_cfg_r32(PCI_CS_STS_CMD) | 7, PCI_CS_STS_CMD);
+
+	/* enable external 2 PCI masters */
+	temp_buffer = ltq_pci_r32(PCI_CR_PC_ARB);
+	temp_buffer &= (~(ltq_pci_req_mask << 16));
+	/* enable internal arbiter */
+	temp_buffer |= (1 << INTERNAL_ARB_ENABLE_BIT);
+	/* enable internal PCI master reqest */
+	temp_buffer &= (~(3 << PCI_MASTER0_REQ_MASK_2BITS));
+
+	/* enable EBU request */
+	temp_buffer &= (~(3 << PCI_MASTER1_REQ_MASK_2BITS));
+
+	/* enable all external masters request */
+	temp_buffer &= (~(3 << PCI_MASTER2_REQ_MASK_2BITS));
+	ltq_pci_w32(temp_buffer, PCI_CR_PC_ARB);
+	wmb();
+
+	/* setup BAR memory regions */
+	ltq_pci_w32(0x18000000, PCI_CR_FCI_ADDR_MAP0);
+	ltq_pci_w32(0x18400000, PCI_CR_FCI_ADDR_MAP1);
+	ltq_pci_w32(0x18800000, PCI_CR_FCI_ADDR_MAP2);
+	ltq_pci_w32(0x18c00000, PCI_CR_FCI_ADDR_MAP3);
+	ltq_pci_w32(0x19000000, PCI_CR_FCI_ADDR_MAP4);
+	ltq_pci_w32(0x19400000, PCI_CR_FCI_ADDR_MAP5);
+	ltq_pci_w32(0x19800000, PCI_CR_FCI_ADDR_MAP6);
+	ltq_pci_w32(0x19c00000, PCI_CR_FCI_ADDR_MAP7);
+	ltq_pci_w32(0x1ae00000, PCI_CR_FCI_ADDR_MAP11hg);
+	ltq_pci_w32(ltq_calc_bar11mask(), PCI_CR_BAR11MASK);
+	ltq_pci_w32(0, PCI_CR_PCI_ADDR_MAP11);
+	ltq_pci_w32(0, PCI_CS_BASE_ADDR1);
+	/* both TX and RX endian swap are enabled */
+	ltq_pci_w32(ltq_pci_r32(PCI_CR_PCI_EOI) | 3, PCI_CR_PCI_EOI);
+	wmb();
+	ltq_pci_w32(ltq_pci_r32(PCI_CR_BAR12MASK) | 0x80000000,
+		PCI_CR_BAR12MASK);
+	ltq_pci_w32(ltq_pci_r32(PCI_CR_BAR13MASK) | 0x80000000,
+		PCI_CR_BAR13MASK);
+	/*use 8 dw burst length */
+	ltq_pci_w32(0x303, PCI_CR_FCI_BURST_LENGTH);
+	ltq_pci_w32(ltq_pci_r32(PCI_CR_PCI_MOD) | (1 << 24), PCI_CR_PCI_MOD);
+	wmb();
+
+	/* setup irq line */
+	ltq_ebu_w32(ltq_ebu_r32(LTQ_EBU_PCC_CON) | 0xc, LTQ_EBU_PCC_CON);
+	ltq_ebu_w32(ltq_ebu_r32(LTQ_EBU_PCC_IEN) | 0x10, LTQ_EBU_PCC_IEN);
+
+	/* toggle reset pin */
+	__gpio_set_value(21, 0);
+	wmb();
+	mdelay(1);
+	__gpio_set_value(21, 1);
+	return 0;
+}
+
+int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
+{
+	if (ltq_pci_irq_map[slot])
+		return ltq_pci_irq_map[slot];
+	printk(KERN_ERR "lq_pci: trying to map irq for unknown slot %d\n",
+		slot);
+
+	return 0;
+}
+
+static int __devinit ltq_pci_probe(struct platform_device *pdev)
+{
+	struct ltq_pci_data *ltq_pci_data =
+		(struct ltq_pci_data *) pdev->dev.platform_data;
+	pci_probe_only = 0;
+	ltq_pci_irq_map = ltq_pci_data->irq;
+	ltq_pci_membase = ioremap_nocache(PCI_CR_BASE_ADDR, PCI_CR_SIZE);
+	ltq_pci_mapped_cfg =
+		ioremap_nocache(LTQ_PCI_CFG_BASE, LTQ_PCI_CFG_BASE);
+	ltq_pci_controller.io_map_base =
+		(unsigned long)ioremap(LTQ_PCI_IO_BASE, LTQ_PCI_IO_SIZE - 1);
+	ltq_pci_startup(ltq_pci_data);
+	register_pci_controller(&ltq_pci_controller);
+
+	return 0;
+}
+
+static struct platform_driver
+ltq_pci_driver = {
+	.probe = ltq_pci_probe,
+	.driver = {
+		.name = "ltq_pci",
+		.owner = THIS_MODULE,
+	},
+};
+
+int __init pcibios_init(void)
+{
+	int ret = platform_driver_register(&ltq_pci_driver);
+	if (ret)
+		printk(KERN_INFO "ltq_pci: Error registering platfom driver!");
+	return ret;
+}
+
+arch_initcall(pcibios_init);
diff -druN linux-2.6.39-libre/arch/mips/pci/pci-lantiq.h linux-3.0-rc7-libre/arch/mips/pci/pci-lantiq.h
--- linux-2.6.39-libre/arch/mips/pci/pci-lantiq.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/mips/pci/pci-lantiq.h	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,18 @@
+/*
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License version 2 as published
+ *  by the Free Software Foundation.
+ *
+ *  Copyright (C) 2010 John Crispin <blogic@openwrt.org>
+ */
+
+#ifndef _LTQ_PCI_H__
+#define _LTQ_PCI_H__
+
+extern __iomem void *ltq_pci_mapped_cfg;
+extern int ltq_pci_read_config_dword(struct pci_bus *bus,
+	unsigned int devfn, int where, int size, u32 *val);
+extern int ltq_pci_write_config_dword(struct pci_bus *bus,
+	unsigned int devfn, int where, int size, u32 val);
+
+#endif
diff -druN linux-2.6.39-libre/arch/mips/pci/pci-xlr.c linux-3.0-rc7-libre/arch/mips/pci/pci-xlr.c
--- linux-2.6.39-libre/arch/mips/pci/pci-xlr.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/mips/pci/pci-xlr.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,214 @@
+/*
+ * Copyright 2003-2011 NetLogic Microsystems, Inc. (NetLogic). 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 NetLogic
+ * license below:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NETLOGIC ``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 NETLOGIC OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/console.h>
+
+#include <asm/io.h>
+
+#include <asm/netlogic/interrupt.h>
+#include <asm/netlogic/xlr/iomap.h>
+#include <asm/netlogic/xlr/pic.h>
+#include <asm/netlogic/xlr/xlr.h>
+
+static void *pci_config_base;
+
+#define	pci_cfg_addr(bus, devfn, off) (((bus) << 16) | ((devfn) << 8) | (off))
+
+/* PCI ops */
+static inline u32 pci_cfg_read_32bit(struct pci_bus *bus, unsigned int devfn,
+	int where)
+{
+	u32 data;
+	u32 *cfgaddr;
+
+	cfgaddr = (u32 *)(pci_config_base +
+			pci_cfg_addr(bus->number, devfn, where & ~3));
+	data = *cfgaddr;
+	return cpu_to_le32(data);
+}
+
+static inline void pci_cfg_write_32bit(struct pci_bus *bus, unsigned int devfn,
+	int where, u32 data)
+{
+	u32 *cfgaddr;
+
+	cfgaddr = (u32 *)(pci_config_base +
+			pci_cfg_addr(bus->number, devfn, where & ~3));
+	*cfgaddr = cpu_to_le32(data);
+}
+
+static int nlm_pcibios_read(struct pci_bus *bus, unsigned int devfn,
+	int where, int size, u32 *val)
+{
+	u32 data;
+
+	if ((size == 2) && (where & 1))
+		return PCIBIOS_BAD_REGISTER_NUMBER;
+	else if ((size == 4) && (where & 3))
+		return PCIBIOS_BAD_REGISTER_NUMBER;
+
+	data = pci_cfg_read_32bit(bus, devfn, where);
+
+	if (size == 1)
+		*val = (data >> ((where & 3) << 3)) & 0xff;
+	else if (size == 2)
+		*val = (data >> ((where & 3) << 3)) & 0xffff;
+	else
+		*val = data;
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+
+static int nlm_pcibios_write(struct pci_bus *bus, unsigned int devfn,
+		int where, int size, u32 val)
+{
+	u32 data;
+
+	if ((size == 2) && (where & 1))
+		return PCIBIOS_BAD_REGISTER_NUMBER;
+	else if ((size == 4) && (where & 3))
+		return PCIBIOS_BAD_REGISTER_NUMBER;
+
+	data = pci_cfg_read_32bit(bus, devfn, where);
+
+	if (size == 1)
+		data = (data & ~(0xff << ((where & 3) << 3))) |
+			(val << ((where & 3) << 3));
+	else if (size == 2)
+		data = (data & ~(0xffff << ((where & 3) << 3))) |
+			(val << ((where & 3) << 3));
+	else
+		data = val;
+
+	pci_cfg_write_32bit(bus, devfn, where, data);
+
+	return PCIBIOS_SUCCESSFUL;
+}
+
+struct pci_ops nlm_pci_ops = {
+	.read  = nlm_pcibios_read,
+	.write = nlm_pcibios_write
+};
+
+static struct resource nlm_pci_mem_resource = {
+	.name           = "XLR PCI MEM",
+	.start          = 0xd0000000UL,	/* 256MB PCI mem @ 0xd000_0000 */
+	.end            = 0xdfffffffUL,
+	.flags          = IORESOURCE_MEM,
+};
+
+static struct resource nlm_pci_io_resource = {
+	.name           = "XLR IO MEM",
+	.start          = 0x10000000UL,	/* 16MB PCI IO @ 0x1000_0000 */
+	.end            = 0x100fffffUL,
+	.flags          = IORESOURCE_IO,
+};
+
+struct pci_controller nlm_pci_controller = {
+	.index          = 0,
+	.pci_ops        = &nlm_pci_ops,
+	.mem_resource   = &nlm_pci_mem_resource,
+	.mem_offset     = 0x00000000UL,
+	.io_resource    = &nlm_pci_io_resource,
+	.io_offset      = 0x00000000UL,
+};
+
+int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
+{
+	if (!nlm_chip_is_xls())
+		return	PIC_PCIX_IRQ;	/* for XLR just one IRQ*/
+
+	/*
+	 * For XLS PCIe, there is an IRQ per Link, find out which
+	 * link the device is on to assign interrupts
+	*/
+	if (dev->bus->self == NULL)
+		return 0;
+
+	switch	(dev->bus->self->devfn) {
+	case 0x0:
+		return PIC_PCIE_LINK0_IRQ;
+	case 0x8:
+		return PIC_PCIE_LINK1_IRQ;
+	case 0x10:
+		if (nlm_chip_is_xls_b())
+			return PIC_PCIE_XLSB0_LINK2_IRQ;
+		else
+			return PIC_PCIE_LINK2_IRQ;
+	case 0x18:
+		if (nlm_chip_is_xls_b())
+			return PIC_PCIE_XLSB0_LINK3_IRQ;
+		else
+			return PIC_PCIE_LINK3_IRQ;
+	}
+	WARN(1, "Unexpected devfn %d\n", dev->bus->self->devfn);
+	return 0;
+}
+
+/* Do platform specific device initialization at pci_enable_device() time */
+int pcibios_plat_dev_init(struct pci_dev *dev)
+{
+	return 0;
+}
+
+static int __init pcibios_init(void)
+{
+	/* PSB assigns PCI resources */
+	pci_probe_only = 1;
+	pci_config_base = ioremap(DEFAULT_PCI_CONFIG_BASE, 16 << 20);
+
+	/* Extend IO port for memory mapped io */
+	ioport_resource.start =  0;
+	ioport_resource.end   = ~0;
+
+	set_io_port_base(CKSEG1);
+	nlm_pci_controller.io_map_base = CKSEG1;
+
+	pr_info("Registering XLR/XLS PCIX/PCIE Controller.\n");
+	register_pci_controller(&nlm_pci_controller);
+
+	return 0;
+}
+
+arch_initcall(pcibios_init);
+
+struct pci_fixup pcibios_fixups[] = {
+	{0}
+};
diff -druN linux-2.6.39-libre/arch/mips/pmc-sierra/yosemite/smp.c linux-3.0-rc7-libre/arch/mips/pmc-sierra/yosemite/smp.c
--- linux-2.6.39-libre/arch/mips/pmc-sierra/yosemite/smp.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/mips/pmc-sierra/yosemite/smp.c	2011-07-11 19:51:52.000000000 -0400
@@ -55,6 +55,8 @@
 
 		if (status & 0x2)
 			smp_call_function_interrupt();
+		if (status & 0x4)
+			scheduler_ipi();
 		break;
 
 	case 1:
@@ -63,6 +65,8 @@
 
 		if (status & 0x2)
 			smp_call_function_interrupt();
+		if (status & 0x4)
+			scheduler_ipi();
 		break;
 	}
 }
diff -druN linux-2.6.39-libre/arch/mips/sgi-ip22/ip22-hpc.c linux-3.0-rc7-libre/arch/mips/sgi-ip22/ip22-hpc.c
--- linux-2.6.39-libre/arch/mips/sgi-ip22/ip22-hpc.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/mips/sgi-ip22/ip22-hpc.c	2011-07-11 19:51:52.000000000 -0400
@@ -1,7 +1,7 @@
 /*
  * ip22-hpc.c: Routines for generic manipulation of the HPC controllers.
  *
- * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
+ * Copyright (C) 1996 David S. Miller (davem@davemloft.net)
  * Copyright (C) 1998 Ralf Baechle
  */
 
diff -druN linux-2.6.39-libre/arch/mips/sgi-ip22/ip22-int.c linux-3.0-rc7-libre/arch/mips/sgi-ip22/ip22-int.c
--- linux-2.6.39-libre/arch/mips/sgi-ip22/ip22-int.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/mips/sgi-ip22/ip22-int.c	2011-07-11 19:51:52.000000000 -0400
@@ -2,7 +2,7 @@
  * ip22-int.c: Routines for generic manipulation of the INT[23] ASIC
  *             found on INDY and Indigo2 workstations.
  *
- * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
+ * Copyright (C) 1996 David S. Miller (davem@davemloft.net)
  * Copyright (C) 1997, 1998 Ralf Baechle (ralf@gnu.org)
  * Copyright (C) 1999 Andrew R. Baker (andrewb@uab.edu)
  *                    - Indigo2 changes
diff -druN linux-2.6.39-libre/arch/mips/sgi-ip22/ip22-mc.c linux-3.0-rc7-libre/arch/mips/sgi-ip22/ip22-mc.c
--- linux-2.6.39-libre/arch/mips/sgi-ip22/ip22-mc.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/mips/sgi-ip22/ip22-mc.c	2011-07-11 19:51:52.000000000 -0400
@@ -1,7 +1,7 @@
 /*
  * ip22-mc.c: Routines for manipulating SGI Memory Controller.
  *
- * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
+ * Copyright (C) 1996 David S. Miller (davem@davemloft.net)
  * Copyright (C) 1999 Andrew R. Baker (andrewb@uab.edu) - Indigo2 changes
  * Copyright (C) 2003 Ladislav Michl  (ladis@linux-mips.org)
  * Copyright (C) 2004 Peter Fuerst    (pf@net.alphadv.de) - IP28
diff -druN linux-2.6.39-libre/arch/mips/sgi-ip22/ip22-setup.c linux-3.0-rc7-libre/arch/mips/sgi-ip22/ip22-setup.c
--- linux-2.6.39-libre/arch/mips/sgi-ip22/ip22-setup.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/mips/sgi-ip22/ip22-setup.c	2011-07-11 19:51:52.000000000 -0400
@@ -1,7 +1,7 @@
 /*
  * ip22-setup.c: SGI specific setup, including init of the feature struct.
  *
- * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
+ * Copyright (C) 1996 David S. Miller (davem@davemloft.net)
  * Copyright (C) 1997, 1998 Ralf Baechle (ralf@gnu.org)
  */
 #include <linux/init.h>
diff -druN linux-2.6.39-libre/arch/mips/sgi-ip27/ip27-irq.c linux-3.0-rc7-libre/arch/mips/sgi-ip27/ip27-irq.c
--- linux-2.6.39-libre/arch/mips/sgi-ip27/ip27-irq.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/mips/sgi-ip27/ip27-irq.c	2011-07-11 19:51:52.000000000 -0400
@@ -147,8 +147,10 @@
 #ifdef CONFIG_SMP
 	if (pend0 & (1UL << CPU_RESCHED_A_IRQ)) {
 		LOCAL_HUB_CLR_INTR(CPU_RESCHED_A_IRQ);
+		scheduler_ipi();
 	} else if (pend0 & (1UL << CPU_RESCHED_B_IRQ)) {
 		LOCAL_HUB_CLR_INTR(CPU_RESCHED_B_IRQ);
+		scheduler_ipi();
 	} else if (pend0 & (1UL << CPU_CALL_A_IRQ)) {
 		LOCAL_HUB_CLR_INTR(CPU_CALL_A_IRQ);
 		smp_call_function_interrupt();
diff -druN linux-2.6.39-libre/arch/mips/sgi-ip27/ip27-timer.c linux-3.0-rc7-libre/arch/mips/sgi-ip27/ip27-timer.c
--- linux-2.6.39-libre/arch/mips/sgi-ip27/ip27-timer.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/mips/sgi-ip27/ip27-timer.c	2011-07-11 19:51:52.000000000 -0400
@@ -66,18 +66,7 @@
 static void rt_set_mode(enum clock_event_mode mode,
 		struct clock_event_device *evt)
 {
-	switch (mode) {
-	case CLOCK_EVT_MODE_ONESHOT:
-		/* The only mode supported */
-		break;
-
-	case CLOCK_EVT_MODE_PERIODIC:
-	case CLOCK_EVT_MODE_UNUSED:
-	case CLOCK_EVT_MODE_SHUTDOWN:
-	case CLOCK_EVT_MODE_RESUME:
-		/* Nothing to do  */
-		break;
-	}
+	/* Nothing to do ...  */
 }
 
 int rt_timer_irq;
@@ -174,8 +163,7 @@
 {
 	struct clocksource *cs = &hub_rt_clocksource;
 
-	clocksource_set_clock(cs, CYCLES_PER_SEC);
-	clocksource_register(cs);
+	clocksource_register_hz(cs, CYCLES_PER_SEC);
 }
 
 void __init plat_time_init(void)
diff -druN linux-2.6.39-libre/arch/mips/sibyte/bcm1480/smp.c linux-3.0-rc7-libre/arch/mips/sibyte/bcm1480/smp.c
--- linux-2.6.39-libre/arch/mips/sibyte/bcm1480/smp.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/mips/sibyte/bcm1480/smp.c	2011-07-11 19:51:52.000000000 -0400
@@ -20,6 +20,7 @@
 #include <linux/delay.h>
 #include <linux/smp.h>
 #include <linux/kernel_stat.h>
+#include <linux/sched.h>
 
 #include <asm/mmu_context.h>
 #include <asm/io.h>
@@ -189,10 +190,8 @@
 	/* Clear the mailbox to clear the interrupt */
 	__raw_writeq(((u64)action)<<48, mailbox_0_clear_regs[cpu]);
 
-	/*
-	 * Nothing to do for SMP_RESCHEDULE_YOURSELF; returning from the
-	 * interrupt will do the reschedule for us
-	 */
+	if (action & SMP_RESCHEDULE_YOURSELF)
+		scheduler_ipi();
 
 	if (action & SMP_CALL_FUNCTION)
 		smp_call_function_interrupt();
diff -druN linux-2.6.39-libre/arch/mips/sibyte/sb1250/smp.c linux-3.0-rc7-libre/arch/mips/sibyte/sb1250/smp.c
--- linux-2.6.39-libre/arch/mips/sibyte/sb1250/smp.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/mips/sibyte/sb1250/smp.c	2011-07-11 19:51:52.000000000 -0400
@@ -21,6 +21,7 @@
 #include <linux/interrupt.h>
 #include <linux/smp.h>
 #include <linux/kernel_stat.h>
+#include <linux/sched.h>
 
 #include <asm/mmu_context.h>
 #include <asm/io.h>
@@ -177,10 +178,8 @@
 	/* Clear the mailbox to clear the interrupt */
 	____raw_writeq(((u64)action) << 48, mailbox_clear_regs[cpu]);
 
-	/*
-	 * Nothing to do for SMP_RESCHEDULE_YOURSELF; returning from the
-	 * interrupt will do the reschedule for us
-	 */
+	if (action & SMP_RESCHEDULE_YOURSELF)
+		scheduler_ipi();
 
 	if (action & SMP_CALL_FUNCTION)
 		smp_call_function_interrupt();
diff -druN linux-2.6.39-libre/arch/mips/txx9/generic/setup.c linux-3.0-rc7-libre/arch/mips/txx9/generic/setup.c
--- linux-2.6.39-libre/arch/mips/txx9/generic/setup.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/mips/txx9/generic/setup.c	2011-07-11 19:51:52.000000000 -0400
@@ -639,7 +639,6 @@
 		.flags = IORESOURCE_MEM,
 	};
 	struct platform_device *pdev;
-#ifdef CONFIG_MTD_PARTITIONS
 	static struct mtd_partition parts[2];
 	struct physmap_flash_data pdata_part;
 
@@ -658,7 +657,7 @@
 		pdata_part.parts = parts;
 		pdata = &pdata_part;
 	}
-#endif
+
 	pdev = platform_device_alloc("physmap-flash", no);
 	if (!pdev ||
 	    platform_device_add_resources(pdev, &res, 1) ||
diff -druN linux-2.6.39-libre/arch/mips/txx9/generic/setup_tx4939.c linux-3.0-rc7-libre/arch/mips/txx9/generic/setup_tx4939.c
--- linux-2.6.39-libre/arch/mips/txx9/generic/setup_tx4939.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/mips/txx9/generic/setup_tx4939.c	2011-07-11 19:51:52.000000000 -0400
@@ -318,19 +318,15 @@
 }
 
 #if defined(CONFIG_TC35815) || defined(CONFIG_TC35815_MODULE)
-static int tx4939_get_eth_speed(struct net_device *dev)
+static u32 tx4939_get_eth_speed(struct net_device *dev)
 {
-	struct ethtool_cmd cmd = { ETHTOOL_GSET };
-	int speed = 100;	/* default 100Mbps */
-	int err;
-	if (!dev->ethtool_ops || !dev->ethtool_ops->get_settings)
-		return speed;
-	err = dev->ethtool_ops->get_settings(dev, &cmd);
-	if (err < 0)
-		return speed;
-	speed = cmd.speed == SPEED_100 ? 100 : 10;
-	return speed;
+	struct ethtool_cmd cmd;
+	if (dev_ethtool_get_settings(dev, &cmd))
+		return 100;	/* default 100Mbps */
+
+	return ethtool_cmd_speed(&cmd);
 }
+
 static int tx4939_netdev_event(struct notifier_block *this,
 			       unsigned long event,
 			       void *ptr)
@@ -343,8 +339,7 @@
 		else if (dev->irq == TXX9_IRQ_BASE + TX4939_IR_ETH(1))
 			bit = TX4939_PCFG_SPEED1;
 		if (bit) {
-			int speed = tx4939_get_eth_speed(dev);
-			if (speed == 100)
+			if (tx4939_get_eth_speed(dev) == 100)
 				txx9_set64(&tx4939_ccfgptr->pcfg, bit);
 			else
 				txx9_clear64(&tx4939_ccfgptr->pcfg, bit);
diff -druN linux-2.6.39-libre/arch/mn10300/configs/asb2364_defconfig linux-3.0-rc7-libre/arch/mn10300/configs/asb2364_defconfig
--- linux-2.6.39-libre/arch/mn10300/configs/asb2364_defconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/mn10300/configs/asb2364_defconfig	2011-07-11 19:51:52.000000000 -0400
@@ -8,7 +8,6 @@
 CONFIG_TASK_IO_ACCOUNTING=y
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_CGROUPS=y
-CONFIG_CGROUP_NS=y
 CONFIG_CGROUP_FREEZER=y
 CONFIG_CGROUP_DEVICE=y
 CONFIG_CGROUP_CPUACCT=y
diff -druN linux-2.6.39-libre/arch/mn10300/include/asm/uaccess.h linux-3.0-rc7-libre/arch/mn10300/include/asm/uaccess.h
--- linux-2.6.39-libre/arch/mn10300/include/asm/uaccess.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/mn10300/include/asm/uaccess.h	2011-07-11 19:51:52.000000000 -0400
@@ -15,6 +15,7 @@
  * User space memory access functions
  */
 #include <linux/thread_info.h>
+#include <linux/kernel.h>
 #include <asm/page.h>
 #include <asm/errno.h>
 
diff -druN linux-2.6.39-libre/arch/mn10300/include/asm/unistd.h linux-3.0-rc7-libre/arch/mn10300/include/asm/unistd.h
--- linux-2.6.39-libre/arch/mn10300/include/asm/unistd.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/mn10300/include/asm/unistd.h	2011-07-11 19:51:52.000000000 -0400
@@ -349,10 +349,11 @@
 #define __NR_rt_tgsigqueueinfo	336
 #define __NR_perf_event_open	337
 #define __NR_recvmmsg		338
+#define __NR_setns		339
 
 #ifdef __KERNEL__
 
-#define NR_syscalls 339
+#define NR_syscalls 340
 
 /*
  * specify the deprecated syscalls we want to support on this arch
diff -druN linux-2.6.39-libre/arch/mn10300/Kconfig linux-3.0-rc7-libre/arch/mn10300/Kconfig
--- linux-2.6.39-libre/arch/mn10300/Kconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/mn10300/Kconfig	2011-07-11 19:51:52.000000000 -0400
@@ -44,9 +44,6 @@
 config GENERIC_CMOS_UPDATE
         def_bool n
 
-config GENERIC_FIND_NEXT_BIT
-	def_bool y
-
 config GENERIC_HWEIGHT
 	def_bool y
 
diff -druN linux-2.6.39-libre/arch/mn10300/kernel/entry.S linux-3.0-rc7-libre/arch/mn10300/kernel/entry.S
--- linux-2.6.39-libre/arch/mn10300/kernel/entry.S	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/mn10300/kernel/entry.S	2011-07-11 19:51:52.000000000 -0400
@@ -759,6 +759,7 @@
 	.long sys_rt_tgsigqueueinfo
 	.long sys_perf_event_open
 	.long sys_recvmmsg
+	.long sys_setns
 
 
 nr_syscalls=(.-sys_call_table)/4
diff -druN linux-2.6.39-libre/arch/mn10300/kernel/irq.c linux-3.0-rc7-libre/arch/mn10300/kernel/irq.c
--- linux-2.6.39-libre/arch/mn10300/kernel/irq.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/mn10300/kernel/irq.c	2011-07-11 19:51:52.000000000 -0400
@@ -87,7 +87,7 @@
 		tmp2 = GxICR(irq);
 
 		irq_affinity_online[irq] =
-			any_online_cpu(*d->affinity);
+			cpumask_any_and(d->affinity, cpu_online_mask);
 		CROSS_GxICR(irq, irq_affinity_online[irq]) =
 			(tmp & (GxICR_LEVEL | GxICR_ENABLE)) | GxICR_DETECT;
 		tmp = CROSS_GxICR(irq, irq_affinity_online[irq]);
@@ -124,7 +124,8 @@
 	} else {
 		tmp = GxICR(irq);
 
-		irq_affinity_online[irq] = any_online_cpu(*d->affinity);
+		irq_affinity_online[irq] = cpumask_any_and(d->affinity,
+							   cpu_online_mask);
 		CROSS_GxICR(irq, irq_affinity_online[irq]) = (tmp & GxICR_LEVEL) | GxICR_ENABLE | GxICR_DETECT;
 		tmp = CROSS_GxICR(irq, irq_affinity_online[irq]);
 	}
@@ -366,11 +367,11 @@
 		if (irqd_is_per_cpu(data))
 			continue;
 
-		if (cpu_isset(self, data->affinity) &&
-		    !cpus_intersects(irq_affinity[irq], cpu_online_map)) {
+		if (cpumask_test_cpu(self, &data->affinity) &&
+		    !cpumask_intersects(&irq_affinity[irq], cpu_online_mask)) {
 			int cpu_id;
-			cpu_id = first_cpu(cpu_online_map);
-			cpu_set(cpu_id, data->affinity);
+			cpu_id = cpumask_first(cpu_online_mask);
+			cpumask_set_cpu(cpu_id, &data->affinity);
 		}
 		/* We need to operate irq_affinity_online atomically. */
 		arch_local_cli_save(flags);
@@ -381,7 +382,8 @@
 			GxICR(irq) = x & GxICR_LEVEL;
 			tmp = GxICR(irq);
 
-			new = any_online_cpu(data->affinity);
+			new = cpumask_any_and(&data->affinity,
+					      cpu_online_mask);
 			irq_affinity_online[irq] = new;
 
 			CROSS_GxICR(irq, new) =
diff -druN linux-2.6.39-libre/arch/mn10300/kernel/smp.c linux-3.0-rc7-libre/arch/mn10300/kernel/smp.c
--- linux-2.6.39-libre/arch/mn10300/kernel/smp.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/mn10300/kernel/smp.c	2011-07-11 19:51:52.000000000 -0400
@@ -309,7 +309,7 @@
 	u16 tmp;
 
 	for (i = 0; i < NR_CPUS; i++) {
-		if (cpu_isset(i, *cpumask)) {
+		if (cpumask_test_cpu(i, cpumask)) {
 			/* send IPI */
 			tmp = CROSS_GxICR(irq, i);
 			CROSS_GxICR(irq, i) =
@@ -342,8 +342,8 @@
 {
 	cpumask_t cpumask;
 
-	cpumask = cpu_online_map;
-	cpu_clear(smp_processor_id(), cpumask);
+	cpumask_copy(&cpumask, cpu_online_mask);
+	cpumask_clear_cpu(smp_processor_id(), &cpumask);
 	send_IPI_mask(&cpumask, irq);
 }
 
@@ -393,8 +393,8 @@
 
 	data.func = func;
 	data.info = info;
-	data.started = cpu_online_map;
-	cpu_clear(smp_processor_id(), data.started);
+	cpumask_copy(&data.started, cpu_online_mask);
+	cpumask_clear_cpu(smp_processor_id(), &data.started);
 	data.wait = wait;
 	if (wait)
 		data.finished = data.started;
@@ -410,14 +410,14 @@
 	if (CALL_FUNCTION_NMI_IPI_TIMEOUT > 0) {
 		for (cnt = 0;
 		     cnt < CALL_FUNCTION_NMI_IPI_TIMEOUT &&
-			     !cpus_empty(data.started);
+			     !cpumask_empty(&data.started);
 		     cnt++)
 			mdelay(1);
 
 		if (wait && cnt < CALL_FUNCTION_NMI_IPI_TIMEOUT) {
 			for (cnt = 0;
 			     cnt < CALL_FUNCTION_NMI_IPI_TIMEOUT &&
-				     !cpus_empty(data.finished);
+				     !cpumask_empty(&data.finished);
 			     cnt++)
 				mdelay(1);
 		}
@@ -428,10 +428,10 @@
 	} else {
 		/* If timeout value is zero, wait until cpumask has been
 		 * cleared */
-		while (!cpus_empty(data.started))
+		while (!cpumask_empty(&data.started))
 			barrier();
 		if (wait)
-			while (!cpus_empty(data.finished))
+			while (!cpumask_empty(&data.finished))
 				barrier();
 	}
 
@@ -472,12 +472,12 @@
 #endif	/* CONFIG_GDBSTUB */
 
 	flags = arch_local_cli_save();
-	cpu_clear(smp_processor_id(), cpu_online_map);
+	set_cpu_online(smp_processor_id(), false);
 
 	while (!stopflag)
 		cpu_relax();
 
-	cpu_set(smp_processor_id(), cpu_online_map);
+	set_cpu_online(smp_processor_id(), true);
 	arch_local_irq_restore(flags);
 }
 
@@ -494,14 +494,11 @@
  * @irq: The interrupt number.
  * @dev_id: The device ID.
  *
- * We need do nothing here, since the scheduling will be effected on our way
- * back through entry.S.
- *
  * Returns IRQ_HANDLED to indicate we handled the interrupt successfully.
  */
 static irqreturn_t smp_reschedule_interrupt(int irq, void *dev_id)
 {
-	/* do nothing */
+	scheduler_ipi();
 	return IRQ_HANDLED;
 }
 
@@ -532,12 +529,13 @@
 	 * execute the function
 	 */
 	smp_mb();
-	cpu_clear(smp_processor_id(), nmi_call_data->started);
+	cpumask_clear_cpu(smp_processor_id(), &nmi_call_data->started);
 	(*func)(info);
 
 	if (wait) {
 		smp_mb();
-		cpu_clear(smp_processor_id(), nmi_call_data->finished);
+		cpumask_clear_cpu(smp_processor_id(),
+				  &nmi_call_data->finished);
 	}
 }
 
@@ -660,7 +658,7 @@
 {
 	smp_cpu_init();
 	smp_callin();
-	while (!cpu_isset(smp_processor_id(), smp_commenced_mask))
+	while (!cpumask_test_cpu(smp_processor_id(), &smp_commenced_mask))
 		cpu_relax();
 
 	local_flush_tlb();
@@ -783,13 +781,14 @@
 
 	if (send_status == 0) {
 		/* Allow AP to start initializing */
-		cpu_set(cpu_id, cpu_callout_map);
+		cpumask_set_cpu(cpu_id, &cpu_callout_map);
 
 		/* Wait for setting cpu_callin_map */
 		timeout = 0;
 		do {
 			udelay(1000);
-			callin_status = cpu_isset(cpu_id, cpu_callin_map);
+			callin_status = cpumask_test_cpu(cpu_id,
+							 &cpu_callin_map);
 		} while (callin_status == 0 && timeout++ < 5000);
 
 		if (callin_status == 0)
@@ -799,9 +798,9 @@
 	}
 
 	if (send_status == GxICR_REQUEST || callin_status == 0) {
-		cpu_clear(cpu_id, cpu_callout_map);
-		cpu_clear(cpu_id, cpu_callin_map);
-		cpu_clear(cpu_id, cpu_initialized);
+		cpumask_clear_cpu(cpu_id, &cpu_callout_map);
+		cpumask_clear_cpu(cpu_id, &cpu_callin_map);
+		cpumask_clear_cpu(cpu_id, &cpu_initialized);
 		cpucount--;
 		return 1;
 	}
@@ -836,7 +835,7 @@
 	cpu = smp_processor_id();
 	timeout = jiffies + (2 * HZ);
 
-	if (cpu_isset(cpu, cpu_callin_map)) {
+	if (cpumask_test_cpu(cpu, &cpu_callin_map)) {
 		printk(KERN_ERR "CPU#%d already present.\n", cpu);
 		BUG();
 	}
@@ -844,7 +843,7 @@
 
 	/* Wait for AP startup 2s total */
 	while (time_before(jiffies, timeout)) {
-		if (cpu_isset(cpu, cpu_callout_map))
+		if (cpumask_test_cpu(cpu, &cpu_callout_map))
 			break;
 		cpu_relax();
 	}
@@ -864,11 +863,11 @@
 	smp_store_cpu_info(cpu);
 
 	/* Allow the boot processor to continue */
-	cpu_set(cpu, cpu_callin_map);
+	cpumask_set_cpu(cpu, &cpu_callin_map);
 }
 
 /**
- * smp_online - Set cpu_online_map
+ * smp_online - Set cpu_online_mask
  */
 static void __init smp_online(void)
 {
@@ -878,7 +877,7 @@
 
 	local_irq_enable();
 
-	cpu_set(cpu, cpu_online_map);
+	set_cpu_online(cpu, true);
 	smp_wmb();
 }
 
@@ -895,13 +894,13 @@
 /*
  * smp_prepare_boot_cpu - Set up stuff for the boot processor.
  *
- * Set up the cpu_online_map, cpu_callout_map and cpu_callin_map of the boot
+ * Set up the cpu_online_mask, cpu_callout_map and cpu_callin_map of the boot
  * processor (CPU 0).
  */
 void __devinit smp_prepare_boot_cpu(void)
 {
-	cpu_set(0, cpu_callout_map);
-	cpu_set(0, cpu_callin_map);
+	cpumask_set_cpu(0, &cpu_callout_map);
+	cpumask_set_cpu(0, &cpu_callin_map);
 	current_thread_info()->cpu = 0;
 }
 
@@ -934,16 +933,16 @@
 		run_wakeup_cpu(cpu);
 #endif /* CONFIG_HOTPLUG_CPU */
 
-	cpu_set(cpu, smp_commenced_mask);
+	cpumask_set_cpu(cpu, &smp_commenced_mask);
 
 	/* Wait 5s total for a response */
 	for (timeout = 0 ; timeout < 5000 ; timeout++) {
-		if (cpu_isset(cpu, cpu_online_map))
+		if (cpu_online(cpu))
 			break;
 		udelay(1000);
 	}
 
-	BUG_ON(!cpu_isset(cpu, cpu_online_map));
+	BUG_ON(!cpu_online(cpu));
 	return 0;
 }
 
@@ -989,7 +988,7 @@
 		return -EBUSY;
 
 	migrate_irqs();
-	cpu_clear(cpu, current->active_mm->cpu_vm_mask);
+	cpumask_clear_cpu(cpu, &mm_cpumask(current->active_mm));
 	return 0;
 }
 
@@ -1094,13 +1093,13 @@
 	do {
 		mn10300_local_dcache_inv_range(start, end);
 		barrier();
-	} while (!cpus_empty(nmi_call_func_mask_data.started));
+	} while (!cpumask_empty(&nmi_call_func_mask_data.started));
 
 	if (wait) {
 		do {
 			mn10300_local_dcache_inv_range(start, end);
 			barrier();
-		} while (!cpus_empty(nmi_call_func_mask_data.finished));
+		} while (!cpumask_empty(&nmi_call_func_mask_data.finished));
 	}
 
 	spin_unlock(&smp_nmi_call_lock);
@@ -1111,9 +1110,9 @@
 {
 	unsigned int cpu = smp_processor_id();
 
-	cpu_set(cpu, cpu_callin_map);
+	cpumask_set_cpu(cpu, &cpu_callin_map);
 	local_flush_tlb();
-	cpu_set(cpu, cpu_online_map);
+	set_cpu_online(cpu, true);
 	smp_wmb();
 }
 
@@ -1144,8 +1143,9 @@
 static void run_sleep_cpu(unsigned int cpu)
 {
 	unsigned long flags;
-	cpumask_t cpumask = cpumask_of(cpu);
+	cpumask_t cpumask;
 
+	cpumask_copy(&cpumask, &cpumask_of(cpu));
 	flags = arch_local_cli_save();
 	hotplug_cpu_nmi_call_function(cpumask, prepare_sleep_cpu, NULL, 1);
 	hotplug_cpu_nmi_call_function(cpumask, sleep_cpu, NULL, 0);
diff -druN linux-2.6.39-libre/arch/mn10300/kernel/traps.c linux-3.0-rc7-libre/arch/mn10300/kernel/traps.c
--- linux-2.6.39-libre/arch/mn10300/kernel/traps.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/mn10300/kernel/traps.c	2011-07-11 19:51:52.000000000 -0400
@@ -28,7 +28,7 @@
 #include <linux/irq.h>
 #include <asm/processor.h>
 #include <asm/system.h>
-#include <asm/uaccess.h>
+#include <linux/uaccess.h>
 #include <asm/io.h>
 #include <asm/atomic.h>
 #include <asm/smp.h>
@@ -156,7 +156,7 @@
 
 	case EXCEP_TRAP:
 	case EXCEP_UNIMPINS:
-		if (get_user(opcode, (uint8_t __user *)regs->pc) != 0)
+		if (probe_kernel_read(&opcode, (u8 *)regs->pc, 1) < 0)
 			break;
 		if (opcode == 0xff) {
 			if (notify_die(DIE_BREAKPOINT, str, regs, code, 0, 0))
diff -druN linux-2.6.39-libre/arch/mn10300/kernel/vmlinux.lds.S linux-3.0-rc7-libre/arch/mn10300/kernel/vmlinux.lds.S
--- linux-2.6.39-libre/arch/mn10300/kernel/vmlinux.lds.S	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/mn10300/kernel/vmlinux.lds.S	2011-07-11 19:51:52.000000000 -0400
@@ -44,6 +44,7 @@
   RO_DATA(PAGE_SIZE)
 
   /* writeable */
+  _sdata = .;     /* Start of rw data section */
   RW_DATA_SECTION(32, PAGE_SIZE, THREAD_SIZE)
   _edata = .;
 
@@ -70,7 +71,7 @@
 	.exit.text : { EXIT_TEXT; }
 	.exit.data : { EXIT_DATA; }
 
-  PERCPU(32, PAGE_SIZE)
+  PERCPU_SECTION(32)
   . = ALIGN(PAGE_SIZE);
   __init_end = .;
   /* freed after init ends here */
diff -druN linux-2.6.39-libre/arch/mn10300/mm/cache-dbg-flush-by-reg.S linux-3.0-rc7-libre/arch/mn10300/mm/cache-dbg-flush-by-reg.S
--- linux-2.6.39-libre/arch/mn10300/mm/cache-dbg-flush-by-reg.S	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/mn10300/mm/cache-dbg-flush-by-reg.S	2011-07-11 19:51:52.000000000 -0400
@@ -120,14 +120,14 @@
 	# conditionally purge this line in all ways
 	mov	d1,(L1_CACHE_WAYDISP*0,a0)
 
-debugger_local_cache_flushinv_no_dcache:
+debugger_local_cache_flushinv_one_no_dcache:
 	#
 	# now try to flush the icache
 	#
 	mov	CHCTR,a0
 	movhu	(a0),d0
 	btst	CHCTR_ICEN,d0
-	beq	mn10300_local_icache_inv_range_reg_end
+	beq	debugger_local_cache_flushinv_one_end
 
 	LOCAL_CLI_SAVE(d1)
 
diff -druN linux-2.6.39-libre/arch/mn10300/mm/cache-smp.c linux-3.0-rc7-libre/arch/mn10300/mm/cache-smp.c
--- linux-2.6.39-libre/arch/mn10300/mm/cache-smp.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/mn10300/mm/cache-smp.c	2011-07-11 19:51:52.000000000 -0400
@@ -74,7 +74,7 @@
 		break;
 	}
 
-	cpu_clear(smp_processor_id(), smp_cache_ipi_map);
+	cpumask_clear_cpu(smp_processor_id(), &smp_cache_ipi_map);
 }
 
 /**
@@ -94,12 +94,12 @@
 	smp_cache_mask = opr_mask;
 	smp_cache_start = start;
 	smp_cache_end = end;
-	smp_cache_ipi_map = cpu_online_map;
-	cpu_clear(smp_processor_id(), smp_cache_ipi_map);
+	cpumask_copy(&smp_cache_ipi_map, cpu_online_mask);
+	cpumask_clear_cpu(smp_processor_id(), &smp_cache_ipi_map);
 
 	send_IPI_allbutself(FLUSH_CACHE_IPI);
 
-	while (!cpus_empty(smp_cache_ipi_map))
+	while (!cpumask_empty(&smp_cache_ipi_map))
 		/* nothing. lockup detection does not belong here */
 		mb();
 }
diff -druN linux-2.6.39-libre/arch/mn10300/mm/init.c linux-3.0-rc7-libre/arch/mn10300/mm/init.c
--- linux-2.6.39-libre/arch/mn10300/mm/init.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/mn10300/mm/init.c	2011-07-11 19:51:52.000000000 -0400
@@ -37,8 +37,6 @@
 #include <asm/tlb.h>
 #include <asm/sections.h>
 
-DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
-
 unsigned long highstart_pfn, highend_pfn;
 
 #ifdef CONFIG_MN10300_HAS_ATOMIC_OPS_UNIT
diff -druN linux-2.6.39-libre/arch/mn10300/mm/tlb-smp.c linux-3.0-rc7-libre/arch/mn10300/mm/tlb-smp.c
--- linux-2.6.39-libre/arch/mn10300/mm/tlb-smp.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/mn10300/mm/tlb-smp.c	2011-07-11 19:51:52.000000000 -0400
@@ -64,7 +64,7 @@
 
 	cpu_id = get_cpu();
 
-	if (!cpu_isset(cpu_id, flush_cpumask))
+	if (!cpumask_test_cpu(cpu_id, &flush_cpumask))
 		/* This was a BUG() but until someone can quote me the line
 		 * from the intel manual that guarantees an IPI to multiple
 		 * CPUs is retried _only_ on the erroring CPUs its staying as a
@@ -80,7 +80,7 @@
 		local_flush_tlb_page(flush_mm, flush_va);
 
 	smp_mb__before_clear_bit();
-	cpu_clear(cpu_id, flush_cpumask);
+	cpumask_clear_cpu(cpu_id, &flush_cpumask);
 	smp_mb__after_clear_bit();
 out:
 	put_cpu();
@@ -103,11 +103,11 @@
 	 * - we do not send IPIs to as-yet unbooted CPUs.
 	 */
 	BUG_ON(!mm);
-	BUG_ON(cpus_empty(cpumask));
-	BUG_ON(cpu_isset(smp_processor_id(), cpumask));
+	BUG_ON(cpumask_empty(&cpumask));
+	BUG_ON(cpumask_test_cpu(smp_processor_id(), &cpumask));
 
-	cpus_and(tmp, cpumask, cpu_online_map);
-	BUG_ON(!cpus_equal(cpumask, tmp));
+	cpumask_and(&tmp, &cpumask, cpu_online_mask);
+	BUG_ON(!cpumask_equal(&cpumask, &tmp));
 
 	/* I'm not happy about this global shared spinlock in the MM hot path,
 	 * but we'll see how contended it is.
@@ -128,7 +128,7 @@
 	/* FIXME: if NR_CPUS>=3, change send_IPI_mask */
 	smp_call_function(smp_flush_tlb, NULL, 1);
 
-	while (!cpus_empty(flush_cpumask))
+	while (!cpumask_empty(&flush_cpumask))
 		/* Lockup detection does not belong here */
 		smp_mb();
 
@@ -146,11 +146,11 @@
 	cpumask_t cpu_mask;
 
 	preempt_disable();
-	cpu_mask = mm->cpu_vm_mask;
-	cpu_clear(smp_processor_id(), cpu_mask);
+	cpumask_copy(&cpu_mask, mm_cpumask(mm));
+	cpumask_clear_cpu(smp_processor_id(), &cpu_mask);
 
 	local_flush_tlb();
-	if (!cpus_empty(cpu_mask))
+	if (!cpumask_empty(&cpu_mask))
 		flush_tlb_others(cpu_mask, mm, FLUSH_ALL);
 
 	preempt_enable();
@@ -165,11 +165,11 @@
 	cpumask_t cpu_mask;
 
 	preempt_disable();
-	cpu_mask = mm->cpu_vm_mask;
-	cpu_clear(smp_processor_id(), cpu_mask);
+	cpumask_copy(&cpu_mask, mm_cpumask(mm));
+	cpumask_clear_cpu(smp_processor_id(), &cpu_mask);
 
 	local_flush_tlb();
-	if (!cpus_empty(cpu_mask))
+	if (!cpumask_empty(&cpu_mask))
 		flush_tlb_others(cpu_mask, mm, FLUSH_ALL);
 
 	preempt_enable();
@@ -186,11 +186,11 @@
 	cpumask_t cpu_mask;
 
 	preempt_disable();
-	cpu_mask = mm->cpu_vm_mask;
-	cpu_clear(smp_processor_id(), cpu_mask);
+	cpumask_copy(&cpu_mask, mm_cpumask(mm));
+	cpumask_clear_cpu(smp_processor_id(), &cpu_mask);
 
 	local_flush_tlb_page(mm, va);
-	if (!cpus_empty(cpu_mask))
+	if (!cpumask_empty(&cpu_mask))
 		flush_tlb_others(cpu_mask, mm, va);
 
 	preempt_enable();
diff -druN linux-2.6.39-libre/arch/parisc/include/asm/cacheflush.h linux-3.0-rc7-libre/arch/parisc/include/asm/cacheflush.h
--- linux-2.6.39-libre/arch/parisc/include/asm/cacheflush.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/parisc/include/asm/cacheflush.h	2011-07-11 19:51:52.000000000 -0400
@@ -3,6 +3,7 @@
 
 #include <linux/mm.h>
 #include <linux/uaccess.h>
+#include <asm/tlbflush.h>
 
 /* The usual comment is "Caches aren't brain-dead on the <architecture>".
  * Unfortunately, that doesn't apply to PA-RISC. */
@@ -112,8 +113,10 @@
 static inline void
 flush_anon_page(struct vm_area_struct *vma, struct page *page, unsigned long vmaddr)
 {
-	if (PageAnon(page))
+	if (PageAnon(page)) {
+		flush_tlb_page(vma, vmaddr);
 		flush_dcache_page_asm(page_to_phys(page), vmaddr);
+	}
 }
 
 #ifdef CONFIG_DEBUG_RODATA
diff -druN linux-2.6.39-libre/arch/parisc/include/asm/mmzone.h linux-3.0-rc7-libre/arch/parisc/include/asm/mmzone.h
--- linux-2.6.39-libre/arch/parisc/include/asm/mmzone.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/parisc/include/asm/mmzone.h	2011-07-11 19:51:52.000000000 -0400
@@ -14,13 +14,6 @@
 
 #define NODE_DATA(nid)          (&node_data[nid].pg_data)
 
-#define node_start_pfn(nid)	(NODE_DATA(nid)->node_start_pfn)
-#define node_end_pfn(nid)						\
-({									\
-	pg_data_t *__pgdat = NODE_DATA(nid);				\
-	__pgdat->node_start_pfn + __pgdat->node_spanned_pages;		\
-})
-
 /* We have these possible memory map layouts:
  * Astro: 0-3.75, 67.75-68, 4-64
  * zx1: 0-1, 257-260, 4-256
diff -druN linux-2.6.39-libre/arch/parisc/include/asm/pgtable.h linux-3.0-rc7-libre/arch/parisc/include/asm/pgtable.h
--- linux-2.6.39-libre/arch/parisc/include/asm/pgtable.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/parisc/include/asm/pgtable.h	2011-07-11 19:51:52.000000000 -0400
@@ -177,7 +177,10 @@
 
 #define _PAGE_TABLE	(_PAGE_PRESENT | _PAGE_READ | _PAGE_WRITE |  _PAGE_DIRTY | _PAGE_ACCESSED)
 #define _PAGE_CHG_MASK	(PAGE_MASK | _PAGE_ACCESSED | _PAGE_DIRTY)
-#define _PAGE_KERNEL	(_PAGE_PRESENT | _PAGE_EXEC | _PAGE_READ | _PAGE_WRITE | _PAGE_DIRTY | _PAGE_ACCESSED)
+#define _PAGE_KERNEL_RO	(_PAGE_PRESENT | _PAGE_READ | _PAGE_DIRTY | _PAGE_ACCESSED)
+#define _PAGE_KERNEL_EXEC	(_PAGE_KERNEL_RO | _PAGE_EXEC)
+#define _PAGE_KERNEL_RWX	(_PAGE_KERNEL_EXEC | _PAGE_WRITE)
+#define _PAGE_KERNEL		(_PAGE_KERNEL_RO | _PAGE_WRITE)
 
 /* The pgd/pmd contains a ptr (in phys addr space); since all pgds/pmds
  * are page-aligned, we don't care about the PAGE_OFFSET bits, except
@@ -208,7 +211,9 @@
 #define PAGE_COPY       PAGE_EXECREAD
 #define PAGE_RWX        __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_WRITE | _PAGE_EXEC |_PAGE_ACCESSED)
 #define PAGE_KERNEL	__pgprot(_PAGE_KERNEL)
-#define PAGE_KERNEL_RO	__pgprot(_PAGE_KERNEL & ~_PAGE_WRITE)
+#define PAGE_KERNEL_EXEC	__pgprot(_PAGE_KERNEL_EXEC)
+#define PAGE_KERNEL_RWX	__pgprot(_PAGE_KERNEL_RWX)
+#define PAGE_KERNEL_RO	__pgprot(_PAGE_KERNEL_RO)
 #define PAGE_KERNEL_UNC	__pgprot(_PAGE_KERNEL | _PAGE_NO_CACHE)
 #define PAGE_GATEWAY    __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED | _PAGE_GATEWAY| _PAGE_READ)
 
diff -druN linux-2.6.39-libre/arch/parisc/include/asm/smp.h linux-3.0-rc7-libre/arch/parisc/include/asm/smp.h
--- linux-2.6.39-libre/arch/parisc/include/asm/smp.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/parisc/include/asm/smp.h	2011-07-11 19:51:52.000000000 -0400
@@ -33,15 +33,6 @@
 
 #endif /* !ASSEMBLY */
 
-/*
- *	This magic constant controls our willingness to transfer
- *      a process across CPUs. Such a transfer incurs cache and tlb
- *      misses. The current value is inherited from i386. Still needs
- *      to be tuned for parisc.
- */
- 
-#define PROC_CHANGE_PENALTY	15		/* Schedule penalty */
-
 #define raw_smp_processor_id()	(current_thread_info()->cpu)
 
 #else /* CONFIG_SMP */
diff -druN linux-2.6.39-libre/arch/parisc/include/asm/unistd.h linux-3.0-rc7-libre/arch/parisc/include/asm/unistd.h
--- linux-2.6.39-libre/arch/parisc/include/asm/unistd.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/parisc/include/asm/unistd.h	2011-07-11 19:51:52.000000000 -0400
@@ -814,8 +814,15 @@
 #define __NR_recvmmsg		(__NR_Linux + 319)
 #define __NR_accept4		(__NR_Linux + 320)
 #define __NR_prlimit64		(__NR_Linux + 321)
+#define __NR_fanotify_init	(__NR_Linux + 322)
+#define __NR_fanotify_mark	(__NR_Linux + 323)
+#define __NR_clock_adjtime	(__NR_Linux + 324)
+#define __NR_name_to_handle_at	(__NR_Linux + 325)
+#define __NR_open_by_handle_at	(__NR_Linux + 326)
+#define __NR_syncfs		(__NR_Linux + 327)
+#define __NR_setns		(__NR_Linux + 328)
 
-#define __NR_Linux_syscalls	(__NR_prlimit64 + 1)
+#define __NR_Linux_syscalls	(__NR_setns + 1)
 
 
 #define __IGNORE_select		/* newselect */
diff -druN linux-2.6.39-libre/arch/parisc/Kconfig linux-3.0-rc7-libre/arch/parisc/Kconfig
--- linux-2.6.39-libre/arch/parisc/Kconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/parisc/Kconfig	2011-07-11 19:51:52.000000000 -0400
@@ -47,14 +47,6 @@
 	bool
 	default n
 
-config GENERIC_FIND_NEXT_BIT
-	bool
-	default y
-
-config GENERIC_FIND_BIT_LE
-	bool
-	default y
-
 config GENERIC_BUG
 	bool
 	default y
diff -druN linux-2.6.39-libre/arch/parisc/kernel/cache.c linux-3.0-rc7-libre/arch/parisc/kernel/cache.c
--- linux-2.6.39-libre/arch/parisc/kernel/cache.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/parisc/kernel/cache.c	2011-07-11 19:51:52.000000000 -0400
@@ -304,10 +304,20 @@
 		offset = (pgoff - mpnt->vm_pgoff) << PAGE_SHIFT;
 		addr = mpnt->vm_start + offset;
 
+		/* The TLB is the engine of coherence on parisc: The
+		 * CPU is entitled to speculate any page with a TLB
+		 * mapping, so here we kill the mapping then flush the
+		 * page along a special flush only alias mapping.
+		 * This guarantees that the page is no-longer in the
+		 * cache for any process and nor may it be
+		 * speculatively read in (until the user or kernel
+		 * specifically accesses it, of course) */
+
+		flush_tlb_page(mpnt, addr);
 		if (old_addr == 0 || (old_addr & (SHMLBA - 1)) != (addr & (SHMLBA - 1))) {
 			__flush_cache_page(mpnt, addr, page_to_phys(page));
 			if (old_addr)
-				printk(KERN_ERR "INEQUIVALENT ALIASES 0x%lx and 0x%lx in file %s\n", old_addr, addr, mpnt->vm_file ? mpnt->vm_file->f_path.dentry->d_name.name : "(null)");
+				printk(KERN_ERR "INEQUIVALENT ALIASES 0x%lx and 0x%lx in file %s\n", old_addr, addr, mpnt->vm_file ? (char *)mpnt->vm_file->f_path.dentry->d_name.name : "(null)");
 			old_addr = addr;
 		}
 	}
@@ -499,6 +509,7 @@
 {
 	BUG_ON(!vma->vm_mm->context);
 
+	flush_tlb_page(vma, vmaddr);
 	__flush_cache_page(vma, vmaddr, page_to_phys(pfn_to_page(pfn)));
 
 }
diff -druN linux-2.6.39-libre/arch/parisc/kernel/entry.S linux-3.0-rc7-libre/arch/parisc/kernel/entry.S
--- linux-2.6.39-libre/arch/parisc/kernel/entry.S	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/parisc/kernel/entry.S	2011-07-11 19:51:52.000000000 -0400
@@ -692,6 +692,9 @@
 END(fault_vector_11)
 
 #endif
+	/* Fault vector is separately protected and *must* be on its own page */
+	.align		PAGE_SIZE
+ENTRY(end_fault_vector)
 
 	.import		handle_interruption,code
 	.import		do_cpu_irq_mask,code
diff -druN linux-2.6.39-libre/arch/parisc/kernel/head.S linux-3.0-rc7-libre/arch/parisc/kernel/head.S
--- linux-2.6.39-libre/arch/parisc/kernel/head.S	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/parisc/kernel/head.S	2011-07-11 19:51:52.000000000 -0400
@@ -106,8 +106,9 @@
 #endif
 
 
-	/* Now initialize the PTEs themselves */
-	ldo		0+_PAGE_KERNEL(%r0),%r3 /* Hardwired 0 phys addr start */
+	/* Now initialize the PTEs themselves.  We use RWX for
+	 * everything ... it will get remapped correctly later */
+	ldo		0+_PAGE_KERNEL_RWX(%r0),%r3 /* Hardwired 0 phys addr start */
 	ldi		(1<<(KERNEL_INITIAL_ORDER-PAGE_SHIFT)),%r11 /* PFN count */
 	load32		PA(pg0),%r1
 
diff -druN linux-2.6.39-libre/arch/parisc/kernel/module.c linux-3.0-rc7-libre/arch/parisc/kernel/module.c
--- linux-2.6.39-libre/arch/parisc/kernel/module.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/parisc/kernel/module.c	2011-07-11 19:51:52.000000000 -0400
@@ -61,8 +61,10 @@
 #include <linux/string.h>
 #include <linux/kernel.h>
 #include <linux/bug.h>
+#include <linux/mm.h>
 #include <linux/slab.h>
 
+#include <asm/pgtable.h>
 #include <asm/unwind.h>
 
 #if 0
@@ -214,7 +216,13 @@
 {
 	if (size == 0)
 		return NULL;
-	return vmalloc(size);
+	/* using RWX means less protection for modules, but it's
+	 * easier than trying to map the text, data, init_text and
+	 * init_data correctly */
+	return __vmalloc_node_range(size, 1, VMALLOC_START, VMALLOC_END,
+				    GFP_KERNEL | __GFP_HIGHMEM,
+				    PAGE_KERNEL_RWX, -1,
+				    __builtin_return_address(0));
 }
 
 #ifndef CONFIG_64BIT
diff -druN linux-2.6.39-libre/arch/parisc/kernel/pacache.S linux-3.0-rc7-libre/arch/parisc/kernel/pacache.S
--- linux-2.6.39-libre/arch/parisc/kernel/pacache.S	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/parisc/kernel/pacache.S	2011-07-11 19:51:52.000000000 -0400
@@ -817,10 +817,7 @@
 	.procend
 ENDPROC(purge_kernel_dcache_page)
 
-
-	.export flush_user_dcache_range_asm
-
-flush_user_dcache_range_asm:
+ENTRY(flush_user_dcache_range_asm)
 	.proc
 	.callinfo NO_CALLS
 	.entry
@@ -839,6 +836,7 @@
 	.exit
 
 	.procend
+ENDPROC(flush_user_dcache_range_asm)
 
 ENTRY(flush_kernel_dcache_range_asm)
 	.proc
diff -druN linux-2.6.39-libre/arch/parisc/kernel/smp.c linux-3.0-rc7-libre/arch/parisc/kernel/smp.c
--- linux-2.6.39-libre/arch/parisc/kernel/smp.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/parisc/kernel/smp.c	2011-07-11 19:51:52.000000000 -0400
@@ -155,10 +155,7 @@
 				
 			case IPI_RESCHEDULE:
 				smp_debug(100, KERN_DEBUG "CPU%d IPI_RESCHEDULE\n", this_cpu);
-				/*
-				 * Reschedule callback.  Everything to be
-				 * done is done by the interrupt return path.
-				 */
+				scheduler_ipi();
 				break;
 
 			case IPI_CALL_FUNC:
diff -druN linux-2.6.39-libre/arch/parisc/kernel/syscall_table.S linux-3.0-rc7-libre/arch/parisc/kernel/syscall_table.S
--- linux-2.6.39-libre/arch/parisc/kernel/syscall_table.S	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/parisc/kernel/syscall_table.S	2011-07-11 19:51:52.000000000 -0400
@@ -420,6 +420,13 @@
 	ENTRY_COMP(recvmmsg)
 	ENTRY_SAME(accept4)		/* 320 */
 	ENTRY_SAME(prlimit64)
+	ENTRY_SAME(fanotify_init)
+	ENTRY_COMP(fanotify_mark)
+	ENTRY_COMP(clock_adjtime)
+	ENTRY_SAME(name_to_handle_at)	/* 325 */
+	ENTRY_COMP(open_by_handle_at)
+	ENTRY_SAME(syncfs)
+	ENTRY_SAME(setns)
 
 	/* Nothing yet */
 
diff -druN linux-2.6.39-libre/arch/parisc/kernel/sys_parisc32.c linux-3.0-rc7-libre/arch/parisc/kernel/sys_parisc32.c
--- linux-2.6.39-libre/arch/parisc/kernel/sys_parisc32.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/parisc/kernel/sys_parisc32.c	2011-07-11 19:51:52.000000000 -0400
@@ -228,3 +228,11 @@
         return sys_fallocate(fd, mode, ((loff_t)offhi << 32) | offlo,
                              ((loff_t)lenhi << 32) | lenlo);
 }
+
+asmlinkage long compat_sys_fanotify_mark(int fan_fd, int flags, u32 mask_hi,
+					 u32 mask_lo, int fd,
+					 const char __user *pathname)
+{
+	return sys_fanotify_mark(fan_fd, flags, ((u64)mask_hi << 32) | mask_lo,
+				 fd, pathname);
+}
diff -druN linux-2.6.39-libre/arch/parisc/kernel/vmlinux.lds.S linux-3.0-rc7-libre/arch/parisc/kernel/vmlinux.lds.S
--- linux-2.6.39-libre/arch/parisc/kernel/vmlinux.lds.S	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/parisc/kernel/vmlinux.lds.S	2011-07-11 19:51:52.000000000 -0400
@@ -69,6 +69,9 @@
 	/* End of text section */
 	_etext = .;
 
+	/* Start of data section */
+	_sdata = .;
+
 	RODATA
 
 	/* writeable */
@@ -134,6 +137,7 @@
 	. = ALIGN(16384);
 	__init_begin = .;
 	INIT_TEXT_SECTION(16384)
+	. = ALIGN(PAGE_SIZE);
 	INIT_DATA_SECTION(16)
 	/* we have to discard exit text and such at runtime, not link time */
 	.exit.text :
@@ -145,7 +149,7 @@
 		EXIT_DATA
 	}
 
-	PERCPU(L1_CACHE_BYTES, PAGE_SIZE)
+	PERCPU_SECTION(L1_CACHE_BYTES)
 	. = ALIGN(PAGE_SIZE);
 	__init_end = .;
 	/* freed after init ends here */
diff -druN linux-2.6.39-libre/arch/parisc/mm/init.c linux-3.0-rc7-libre/arch/parisc/mm/init.c
--- linux-2.6.39-libre/arch/parisc/mm/init.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/parisc/mm/init.c	2011-07-11 19:51:52.000000000 -0400
@@ -31,8 +31,6 @@
 #include <asm/mmzone.h>
 #include <asm/sections.h>
 
-DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
-
 extern int  data_start;
 
 #ifdef CONFIG_DISCONTIGMEM
@@ -371,24 +369,158 @@
 	request_resource(&sysram_resources[0], &pdcdata_resource);
 }
 
+static void __init map_pages(unsigned long start_vaddr,
+			     unsigned long start_paddr, unsigned long size,
+			     pgprot_t pgprot, int force)
+{
+	pgd_t *pg_dir;
+	pmd_t *pmd;
+	pte_t *pg_table;
+	unsigned long end_paddr;
+	unsigned long start_pmd;
+	unsigned long start_pte;
+	unsigned long tmp1;
+	unsigned long tmp2;
+	unsigned long address;
+	unsigned long vaddr;
+	unsigned long ro_start;
+	unsigned long ro_end;
+	unsigned long fv_addr;
+	unsigned long gw_addr;
+	extern const unsigned long fault_vector_20;
+	extern void * const linux_gateway_page;
+
+	ro_start = __pa((unsigned long)_text);
+	ro_end   = __pa((unsigned long)&data_start);
+	fv_addr  = __pa((unsigned long)&fault_vector_20) & PAGE_MASK;
+	gw_addr  = __pa((unsigned long)&linux_gateway_page) & PAGE_MASK;
+
+	end_paddr = start_paddr + size;
+
+	pg_dir = pgd_offset_k(start_vaddr);
+
+#if PTRS_PER_PMD == 1
+	start_pmd = 0;
+#else
+	start_pmd = ((start_vaddr >> PMD_SHIFT) & (PTRS_PER_PMD - 1));
+#endif
+	start_pte = ((start_vaddr >> PAGE_SHIFT) & (PTRS_PER_PTE - 1));
+
+	address = start_paddr;
+	vaddr = start_vaddr;
+	while (address < end_paddr) {
+#if PTRS_PER_PMD == 1
+		pmd = (pmd_t *)__pa(pg_dir);
+#else
+		pmd = (pmd_t *)pgd_address(*pg_dir);
+
+		/*
+		 * pmd is physical at this point
+		 */
+
+		if (!pmd) {
+			pmd = (pmd_t *) alloc_bootmem_low_pages_node(NODE_DATA(0), PAGE_SIZE << PMD_ORDER);
+			pmd = (pmd_t *) __pa(pmd);
+		}
+
+		pgd_populate(NULL, pg_dir, __va(pmd));
+#endif
+		pg_dir++;
+
+		/* now change pmd to kernel virtual addresses */
+
+		pmd = (pmd_t *)__va(pmd) + start_pmd;
+		for (tmp1 = start_pmd; tmp1 < PTRS_PER_PMD; tmp1++, pmd++) {
+
+			/*
+			 * pg_table is physical at this point
+			 */
+
+			pg_table = (pte_t *)pmd_address(*pmd);
+			if (!pg_table) {
+				pg_table = (pte_t *)
+					alloc_bootmem_low_pages_node(NODE_DATA(0), PAGE_SIZE);
+				pg_table = (pte_t *) __pa(pg_table);
+			}
+
+			pmd_populate_kernel(NULL, pmd, __va(pg_table));
+
+			/* now change pg_table to kernel virtual addresses */
+
+			pg_table = (pte_t *) __va(pg_table) + start_pte;
+			for (tmp2 = start_pte; tmp2 < PTRS_PER_PTE; tmp2++, pg_table++) {
+				pte_t pte;
+
+				/*
+				 * Map the fault vector writable so we can
+				 * write the HPMC checksum.
+				 */
+				if (force)
+					pte =  __mk_pte(address, pgprot);
+				else if (core_kernel_text(vaddr) &&
+					 address != fv_addr)
+					pte = __mk_pte(address, PAGE_KERNEL_EXEC);
+				else
+#if defined(CONFIG_PARISC_PAGE_SIZE_4KB)
+				if (address >= ro_start && address < ro_end
+							&& address != fv_addr
+							&& address != gw_addr)
+					pte = __mk_pte(address, PAGE_KERNEL_RO);
+				else
+#endif
+					pte = __mk_pte(address, pgprot);
+
+				if (address >= end_paddr) {
+					if (force)
+						break;
+					else
+						pte_val(pte) = 0;
+				}
+
+				set_pte(pg_table, pte);
+
+				address += PAGE_SIZE;
+				vaddr += PAGE_SIZE;
+			}
+			start_pte = 0;
+
+			if (address >= end_paddr)
+			    break;
+		}
+		start_pmd = 0;
+	}
+}
+
 void free_initmem(void)
 {
 	unsigned long addr;
 	unsigned long init_begin = (unsigned long)__init_begin;
 	unsigned long init_end = (unsigned long)__init_end;
 
-#ifdef CONFIG_DEBUG_KERNEL
+	/* The init text pages are marked R-X.  We have to
+	 * flush the icache and mark them RW-
+	 *
+	 * This is tricky, because map_pages is in the init section.
+	 * Do a dummy remap of the data section first (the data
+	 * section is already PAGE_KERNEL) to pull in the TLB entries
+	 * for map_kernel */
+	map_pages(init_begin, __pa(init_begin), init_end - init_begin,
+		  PAGE_KERNEL_RWX, 1);
+	/* now remap at PAGE_KERNEL since the TLB is pre-primed to execute
+	 * map_pages */
+	map_pages(init_begin, __pa(init_begin), init_end - init_begin,
+		  PAGE_KERNEL, 1);
+
+	/* force the kernel to see the new TLB entries */
+	__flush_tlb_range(0, init_begin, init_end);
 	/* Attempt to catch anyone trying to execute code here
 	 * by filling the page with BRK insns.
 	 */
 	memset((void *)init_begin, 0x00, init_end - init_begin);
+	/* finally dump all the instructions which were cached, since the
+	 * pages are no-longer executable */
 	flush_icache_range(init_begin, init_end);
-#endif
 	
-	/* align __init_begin and __init_end to page size,
-	   ignoring linker script where we might have tried to save RAM */
-	init_begin = PAGE_ALIGN(init_begin);
-	init_end = PAGE_ALIGN(init_end);
 	for (addr = init_begin; addr < init_end; addr += PAGE_SIZE) {
 		ClearPageReserved(virt_to_page(addr));
 		init_page_count(virt_to_page(addr));
@@ -552,7 +684,7 @@
 	int shared = 0, cached = 0;
 
 	printk(KERN_INFO "Mem-info:\n");
-	show_free_areas();
+	show_free_areas(filter);
 #ifndef CONFIG_DISCONTIGMEM
 	i = max_mapnr;
 	while (i-- > 0) {
@@ -618,114 +750,6 @@
 #endif
 }
 
-
-static void __init map_pages(unsigned long start_vaddr, unsigned long start_paddr, unsigned long size, pgprot_t pgprot)
-{
-	pgd_t *pg_dir;
-	pmd_t *pmd;
-	pte_t *pg_table;
-	unsigned long end_paddr;
-	unsigned long start_pmd;
-	unsigned long start_pte;
-	unsigned long tmp1;
-	unsigned long tmp2;
-	unsigned long address;
-	unsigned long ro_start;
-	unsigned long ro_end;
-	unsigned long fv_addr;
-	unsigned long gw_addr;
-	extern const unsigned long fault_vector_20;
-	extern void * const linux_gateway_page;
-
-	ro_start = __pa((unsigned long)_text);
-	ro_end   = __pa((unsigned long)&data_start);
-	fv_addr  = __pa((unsigned long)&fault_vector_20) & PAGE_MASK;
-	gw_addr  = __pa((unsigned long)&linux_gateway_page) & PAGE_MASK;
-
-	end_paddr = start_paddr + size;
-
-	pg_dir = pgd_offset_k(start_vaddr);
-
-#if PTRS_PER_PMD == 1
-	start_pmd = 0;
-#else
-	start_pmd = ((start_vaddr >> PMD_SHIFT) & (PTRS_PER_PMD - 1));
-#endif
-	start_pte = ((start_vaddr >> PAGE_SHIFT) & (PTRS_PER_PTE - 1));
-
-	address = start_paddr;
-	while (address < end_paddr) {
-#if PTRS_PER_PMD == 1
-		pmd = (pmd_t *)__pa(pg_dir);
-#else
-		pmd = (pmd_t *)pgd_address(*pg_dir);
-
-		/*
-		 * pmd is physical at this point
-		 */
-
-		if (!pmd) {
-			pmd = (pmd_t *) alloc_bootmem_low_pages_node(NODE_DATA(0),PAGE_SIZE << PMD_ORDER);
-			pmd = (pmd_t *) __pa(pmd);
-		}
-
-		pgd_populate(NULL, pg_dir, __va(pmd));
-#endif
-		pg_dir++;
-
-		/* now change pmd to kernel virtual addresses */
-
-		pmd = (pmd_t *)__va(pmd) + start_pmd;
-		for (tmp1 = start_pmd; tmp1 < PTRS_PER_PMD; tmp1++,pmd++) {
-
-			/*
-			 * pg_table is physical at this point
-			 */
-
-			pg_table = (pte_t *)pmd_address(*pmd);
-			if (!pg_table) {
-				pg_table = (pte_t *)
-					alloc_bootmem_low_pages_node(NODE_DATA(0),PAGE_SIZE);
-				pg_table = (pte_t *) __pa(pg_table);
-			}
-
-			pmd_populate_kernel(NULL, pmd, __va(pg_table));
-
-			/* now change pg_table to kernel virtual addresses */
-
-			pg_table = (pte_t *) __va(pg_table) + start_pte;
-			for (tmp2 = start_pte; tmp2 < PTRS_PER_PTE; tmp2++,pg_table++) {
-				pte_t pte;
-
-				/*
-				 * Map the fault vector writable so we can
-				 * write the HPMC checksum.
-				 */
-#if defined(CONFIG_PARISC_PAGE_SIZE_4KB)
-				if (address >= ro_start && address < ro_end
-							&& address != fv_addr
-							&& address != gw_addr)
-				    pte = __mk_pte(address, PAGE_KERNEL_RO);
-				else
-#endif
-				    pte = __mk_pte(address, pgprot);
-
-				if (address >= end_paddr)
-					pte_val(pte) = 0;
-
-				set_pte(pg_table, pte);
-
-				address += PAGE_SIZE;
-			}
-			start_pte = 0;
-
-			if (address >= end_paddr)
-			    break;
-		}
-		start_pmd = 0;
-	}
-}
-
 /*
  * pagetable_init() sets up the page tables
  *
@@ -750,14 +774,14 @@
 		size = pmem_ranges[range].pages << PAGE_SHIFT;
 
 		map_pages((unsigned long)__va(start_paddr), start_paddr,
-			size, PAGE_KERNEL);
+			  size, PAGE_KERNEL, 0);
 	}
 
 #ifdef CONFIG_BLK_DEV_INITRD
 	if (initrd_end && initrd_end > mem_limit) {
 		printk(KERN_INFO "initrd: mapping %08lx-%08lx\n", initrd_start, initrd_end);
 		map_pages(initrd_start, __pa(initrd_start),
-			initrd_end - initrd_start, PAGE_KERNEL);
+			  initrd_end - initrd_start, PAGE_KERNEL, 0);
 	}
 #endif
 
@@ -782,7 +806,7 @@
 	 */
 
 	map_pages(linux_gateway_page_addr, __pa(&linux_gateway_page),
-		PAGE_SIZE, PAGE_GATEWAY);
+		  PAGE_SIZE, PAGE_GATEWAY, 1);
 }
 
 #ifdef CONFIG_HPUX
diff -druN linux-2.6.39-libre/arch/powerpc/boot/crt0.S linux-3.0-rc7-libre/arch/powerpc/boot/crt0.S
--- linux-2.6.39-libre/arch/powerpc/boot/crt0.S	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/boot/crt0.S	2011-07-11 19:51:52.000000000 -0400
@@ -6,16 +6,28 @@
  * as published by the Free Software Foundation; either version
  * 2 of the License, or (at your option) any later version.
  *
- * NOTE: this code runs in 32 bit mode and is packaged as ELF32.
+ * NOTE: this code runs in 32 bit mode, is position-independent,
+ * and is packaged as ELF32.
  */
 
 #include "ppc_asm.h"
 
 	.text
-	/* a procedure descriptor used when booting this as a COFF file */
+	/* A procedure descriptor used when booting this as a COFF file.
+	 * When making COFF, this comes first in the link and we're
+	 * linked at 0x500000.
+	 */
 	.globl	_zimage_start_opd
 _zimage_start_opd:
-	.long	_zimage_start, 0, 0, 0
+	.long	0x500000, 0, 0, 0
+
+p_start:	.long	_start
+p_etext:	.long	_etext
+p_bss_start:	.long	__bss_start
+p_end:		.long	_end
+
+	.weak	_platform_stack_top
+p_pstack:	.long	_platform_stack_top
 
 	.weak	_zimage_start
 	.globl	_zimage_start
@@ -24,37 +36,65 @@
 _zimage_start_lib:
 	/* Work out the offset between the address we were linked at
 	   and the address where we're running. */
-	bl	1f
-1:	mflr	r0
-	lis	r9,1b@ha
-	addi	r9,r9,1b@l
-	subf.	r0,r9,r0
-	beq	3f		/* if running at same address as linked */
+	bl	.+4
+p_base:	mflr	r10		/* r10 now points to runtime addr of p_base */
+	/* grab the link address of the dynamic section in r11 */
+	addis	r11,r10,(_GLOBAL_OFFSET_TABLE_-p_base)@ha
+	lwz	r11,(_GLOBAL_OFFSET_TABLE_-p_base)@l(r11)
+	cmpwi	r11,0
+	beq	3f		/* if not linked -pie */
+	/* get the runtime address of the dynamic section in r12 */
+	.weak	__dynamic_start
+	addis	r12,r10,(__dynamic_start-p_base)@ha
+	addi	r12,r12,(__dynamic_start-p_base)@l
+	subf	r11,r11,r12	/* runtime - linktime offset */
 
-	/* The .got2 section contains a list of addresses, so add
-	   the address offset onto each entry. */
-	lis	r9,__got2_start@ha
-	addi	r9,r9,__got2_start@l
-	lis	r8,__got2_end@ha
-	addi	r8,r8,__got2_end@l
-	subf.	r8,r9,r8
+	/* The dynamic section contains a series of tagged entries.
+	 * We need the RELA and RELACOUNT entries. */
+RELA = 7
+RELACOUNT = 0x6ffffff9
+	li	r9,0
+	li	r0,0
+9:	lwz	r8,0(r12)	/* get tag */
+	cmpwi	r8,0
+	beq	10f		/* end of list */
+	cmpwi	r8,RELA
+	bne	11f
+	lwz	r9,4(r12)	/* get RELA pointer in r9 */
+	b	12f
+11:	addis	r8,r8,(-RELACOUNT)@ha
+	cmpwi	r8,RELACOUNT@l
+	bne	12f
+	lwz	r0,4(r12)	/* get RELACOUNT value in r0 */
+12:	addi	r12,r12,8
+	b	9b
+
+	/* The relocation section contains a list of relocations.
+	 * We now do the R_PPC_RELATIVE ones, which point to words
+	 * which need to be initialized with addend + offset.
+	 * The R_PPC_RELATIVE ones come first and there are RELACOUNT
+	 * of them. */
+10:	/* skip relocation if we don't have both */
+	cmpwi	r0,0
 	beq	3f
-	srwi.	r8,r8,2
-	mtctr	r8
-	add	r9,r0,r9
-2:	lwz	r8,0(r9)
-	add	r8,r8,r0
-	stw	r8,0(r9)
-	addi	r9,r9,4
+	cmpwi	r9,0
+	beq	3f
+
+	add	r9,r9,r11	/* Relocate RELA pointer */
+	mtctr	r0
+2:	lbz	r0,4+3(r9)	/* ELF32_R_INFO(reloc->r_info) */
+	cmpwi	r0,22		/* R_PPC_RELATIVE */
+	bne	3f
+	lwz	r12,0(r9)	/* reloc->r_offset */
+	lwz	r0,8(r9)	/* reloc->r_addend */
+	add	r0,r0,r11
+	stwx	r0,r11,r12
+	addi	r9,r9,12
 	bdnz	2b
 
 	/* Do a cache flush for our text, in case the loader didn't */
-3:	lis	r9,_start@ha
-	addi	r9,r9,_start@l
-	add	r9,r0,r9
-	lis	r8,_etext@ha
-	addi	r8,r8,_etext@l
-	add	r8,r0,r8
+3:	lwz	r9,p_start-p_base(r10)	/* note: these are relocated now */
+	lwz	r8,p_etext-p_base(r10)
 4:	dcbf	r0,r9
 	icbi	r0,r9
 	addi	r9,r9,0x20
@@ -64,27 +104,19 @@
 	isync
 
 	/* Clear the BSS */
-	lis	r9,__bss_start@ha
-	addi	r9,r9,__bss_start@l
-	add	r9,r0,r9
-	lis	r8,_end@ha
-	addi	r8,r8,_end@l
-	add	r8,r0,r8
-	li	r10,0
-5:	stw	r10,0(r9)
+	lwz	r9,p_bss_start-p_base(r10)
+	lwz	r8,p_end-p_base(r10)
+	li	r0,0
+5:	stw	r0,0(r9)
 	addi	r9,r9,4
 	cmplw	cr0,r9,r8
 	blt	5b
 
 	/* Possibly set up a custom stack */
-.weak	_platform_stack_top
-	lis	r8,_platform_stack_top@ha
-	addi	r8,r8,_platform_stack_top@l
+	lwz	r8,p_pstack-p_base(r10)
 	cmpwi	r8,0
 	beq	6f
-	add	r8,r0,r8
 	lwz	r1,0(r8)
-	add	r1,r0,r1
 	li	r0,0
 	stwu	r0,-16(r1)	/* establish a stack frame */
 6:
diff -druN linux-2.6.39-libre/arch/powerpc/boot/dtc-src/.gitignore linux-3.0-rc7-libre/arch/powerpc/boot/dtc-src/.gitignore
--- linux-2.6.39-libre/arch/powerpc/boot/dtc-src/.gitignore	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/boot/dtc-src/.gitignore	1969-12-31 19:00:00.000000000 -0500
@@ -1,3 +0,0 @@
-dtc-lexer.lex.c
-dtc-parser.tab.c
-dtc-parser.tab.h
diff -druN linux-2.6.39-libre/arch/powerpc/boot/dts/canyonlands.dts linux-3.0-rc7-libre/arch/powerpc/boot/dts/canyonlands.dts
--- linux-2.6.39-libre/arch/powerpc/boot/dts/canyonlands.dts	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/boot/dts/canyonlands.dts	2011-07-11 19:51:52.000000000 -0400
@@ -530,5 +530,23 @@
 				0x0 0x0 0x0 0x3 &UIC3 0x12 0x4 /* swizzled int C */
 				0x0 0x0 0x0 0x4 &UIC3 0x13 0x4 /* swizzled int D */>;
 		};
+
+		MSI: ppc4xx-msi@C10000000 {
+			compatible = "amcc,ppc4xx-msi", "ppc4xx-msi";
+			reg = < 0xC 0x10000000 0x100>;
+			sdr-base = <0x36C>;
+			msi-data = <0x00000000>;
+			msi-mask = <0x44440000>;
+			interrupt-count = <3>;
+			interrupts = <0 1 2 3>;
+			interrupt-parent = <&UIC3>;
+			#interrupt-cells = <1>;
+			#address-cells = <0>;
+			#size-cells = <0>;
+			interrupt-map = <0 &UIC3 0x18 1
+					1 &UIC3 0x19 1
+					2 &UIC3 0x1A 1
+					3 &UIC3 0x1B 1>;
+		};
 	};
 };
diff -druN linux-2.6.39-libre/arch/powerpc/boot/dts/katmai.dts linux-3.0-rc7-libre/arch/powerpc/boot/dts/katmai.dts
--- linux-2.6.39-libre/arch/powerpc/boot/dts/katmai.dts	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/boot/dts/katmai.dts	2011-07-11 19:51:52.000000000 -0400
@@ -442,6 +442,24 @@
 				0x0 0x0 0x0 0x4 &UIC3 0xb 0x4 /* swizzled int D */>;
 		};
 
+		MSI: ppc4xx-msi@400300000 {
+				compatible = "amcc,ppc4xx-msi", "ppc4xx-msi";
+				reg = < 0x4 0x00300000 0x100>;
+				sdr-base = <0x3B0>;
+				msi-data = <0x00000000>;
+				msi-mask = <0x44440000>;
+				interrupt-count = <3>;
+				interrupts =<0 1 2 3>;
+				interrupt-parent = <&UIC0>;
+				#interrupt-cells = <1>;
+				#address-cells = <0>;
+				#size-cells = <0>;
+				interrupt-map = <0 &UIC0 0xC 1
+					1 &UIC0 0x0D 1
+					2 &UIC0 0x0E 1
+					3 &UIC0 0x0F 1>;
+		};
+
 		I2O: i2o@400100000 {
 			compatible = "ibm,i2o-440spe";
 			reg = <0x00000004 0x00100000 0x100>;
diff -druN linux-2.6.39-libre/arch/powerpc/boot/dts/kilauea.dts linux-3.0-rc7-libre/arch/powerpc/boot/dts/kilauea.dts
--- linux-2.6.39-libre/arch/powerpc/boot/dts/kilauea.dts	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/boot/dts/kilauea.dts	2011-07-11 19:51:52.000000000 -0400
@@ -403,5 +403,33 @@
 				0x0 0x0 0x0 0x3 &UIC2 0xd 0x4 /* swizzled int C */
 				0x0 0x0 0x0 0x4 &UIC2 0xe 0x4 /* swizzled int D */>;
 		};
+
+		MSI: ppc4xx-msi@C10000000 {
+			compatible = "amcc,ppc4xx-msi", "ppc4xx-msi";
+			reg = < 0x0 0xEF620000 0x100>;
+			sdr-base = <0x4B0>;
+			msi-data = <0x00000000>;
+			msi-mask = <0x44440000>;
+			interrupt-count = <12>;
+			interrupts = <0 1 2 3 4 5 6 7 8 9 0xA 0xB 0xC 0xD>;
+			interrupt-parent = <&UIC2>;
+			#interrupt-cells = <1>;
+			#address-cells = <0>;
+			#size-cells = <0>;
+			interrupt-map = <0 &UIC2 0x10 1
+					1 &UIC2 0x11 1
+					2 &UIC2 0x12 1
+					2 &UIC2 0x13 1
+					2 &UIC2 0x14 1
+					2 &UIC2 0x15 1
+					2 &UIC2 0x16 1
+					2 &UIC2 0x17 1
+					2 &UIC2 0x18 1
+					2 &UIC2 0x19 1
+					2 &UIC2 0x1A 1
+					2 &UIC2 0x1B 1
+					2 &UIC2 0x1C 1
+					3 &UIC2 0x1D 1>;
+		};
 	};
 };
diff -druN linux-2.6.39-libre/arch/powerpc/boot/dts/mpc8313erdb.dts linux-3.0-rc7-libre/arch/powerpc/boot/dts/mpc8313erdb.dts
--- linux-2.6.39-libre/arch/powerpc/boot/dts/mpc8313erdb.dts	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/boot/dts/mpc8313erdb.dts	2011-07-11 19:51:52.000000000 -0400
@@ -176,6 +176,19 @@
 			sleep = <&pmc 0x00300000>;
 		};
 
+		ptp_clock@24E00 {
+			compatible = "fsl,etsec-ptp";
+			reg = <0x24E00 0xB0>;
+			interrupts = <12 0x8 13 0x8>;
+			interrupt-parent = < &ipic >;
+			fsl,tclk-period = <10>;
+			fsl,tmr-prsc    = <100>;
+			fsl,tmr-add     = <0x999999A4>;
+			fsl,tmr-fiper1  = <0x3B9AC9F6>;
+			fsl,tmr-fiper2  = <0x00018696>;
+			fsl,max-adj     = <659999998>;
+		};
+
 		enet0: ethernet@24000 {
 			#address-cells = <1>;
 			#size-cells = <1>;
diff -druN linux-2.6.39-libre/arch/powerpc/boot/dts/mpc8572ds.dts linux-3.0-rc7-libre/arch/powerpc/boot/dts/mpc8572ds.dts
--- linux-2.6.39-libre/arch/powerpc/boot/dts/mpc8572ds.dts	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/boot/dts/mpc8572ds.dts	2011-07-11 19:51:52.000000000 -0400
@@ -324,6 +324,19 @@
 			};
 		};
 
+		ptp_clock@24E00 {
+			compatible = "fsl,etsec-ptp";
+			reg = <0x24E00 0xB0>;
+			interrupts = <68 2 69 2 70 2 71 2>;
+			interrupt-parent = < &mpic >;
+			fsl,tclk-period = <5>;
+			fsl,tmr-prsc = <200>;
+			fsl,tmr-add = <0xAAAAAAAB>;
+			fsl,tmr-fiper1 = <0x3B9AC9FB>;
+			fsl,tmr-fiper2 = <0x3B9AC9FB>;
+			fsl,max-adj = <499999999>;
+		};
+
 		enet0: ethernet@24000 {
 			#address-cells = <1>;
 			#size-cells = <1>;
diff -druN linux-2.6.39-libre/arch/powerpc/boot/dts/p1020rdb_camp_core0.dts linux-3.0-rc7-libre/arch/powerpc/boot/dts/p1020rdb_camp_core0.dts
--- linux-2.6.39-libre/arch/powerpc/boot/dts/p1020rdb_camp_core0.dts	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/powerpc/boot/dts/p1020rdb_camp_core0.dts	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,213 @@
+/*
+ * P1020 RDB  Core0 Device Tree Source in CAMP mode.
+ *
+ * In CAMP mode, each core needs to have its own dts. Only mpic and L2 cache
+ * can be shared, all the other devices must be assigned to one core only.
+ * This dts file allows core0 to have memory, l2, i2c, spi, gpio, tdm, dma, usb,
+ * eth1, eth2, sdhc, crypto, global-util, message, pci0, pci1, msi.
+ *
+ * Please note to add "-b 0" for core0's dts compiling.
+ *
+ * Copyright 2011 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/ "p1020si.dtsi"
+
+/ {
+	model = "fsl,P1020RDB";
+	compatible = "fsl,P1020RDB", "fsl,MPC85XXRDB-CAMP";
+
+	aliases {
+		ethernet1 = &enet1;
+		ethernet2 = &enet2;
+		serial0 = &serial0;
+		pci0 = &pci0;
+		pci1 = &pci1;
+	};
+
+	cpus {
+		PowerPC,P1020@1 {
+		status = "disabled";
+		};
+	};
+
+	memory {
+		device_type = "memory";
+	};
+
+	localbus@ffe05000 {
+		status = "disabled";
+	};
+
+	soc@ffe00000 {
+		i2c@3000 {
+			rtc@68 {
+				compatible = "dallas,ds1339";
+				reg = <0x68>;
+			};
+		};
+
+		serial1: serial@4600 {
+			status = "disabled";
+		};
+
+		spi@7000 {
+			fsl_m25p80@0 {
+				#address-cells = <1>;
+				#size-cells = <1>;
+				compatible = "fsl,espi-flash";
+				reg = <0>;
+				linux,modalias = "fsl_m25p80";
+				spi-max-frequency = <40000000>;
+
+				partition@0 {
+					/* 512KB for u-boot Bootloader Image */
+					reg = <0x0 0x00080000>;
+					label = "SPI (RO) U-Boot Image";
+					read-only;
+				};
+
+				partition@80000 {
+					/* 512KB for DTB Image */
+					reg = <0x00080000 0x00080000>;
+					label = "SPI (RO) DTB Image";
+					read-only;
+				};
+
+				partition@100000 {
+					/* 4MB for Linux Kernel Image */
+					reg = <0x00100000 0x00400000>;
+					label = "SPI (RO) Linux Kernel Image";
+					read-only;
+				};
+
+				partition@500000 {
+					/* 4MB for Compressed RFS Image */
+					reg = <0x00500000 0x00400000>;
+					label = "SPI (RO) Compressed RFS Image";
+					read-only;
+				};
+
+				partition@900000 {
+					/* 7MB for JFFS2 based RFS */
+					reg = <0x00900000 0x00700000>;
+					label = "SPI (RW) JFFS2 RFS";
+				};
+			};
+		};
+
+		mdio@24000 {
+			phy0: ethernet-phy@0 {
+				interrupt-parent = <&mpic>;
+				interrupts = <3 1>;
+				reg = <0x0>;
+			};
+			phy1: ethernet-phy@1 {
+				interrupt-parent = <&mpic>;
+				interrupts = <2 1>;
+				reg = <0x1>;
+			};
+		};
+
+		mdio@25000 {
+			tbi0: tbi-phy@11 {
+				reg = <0x11>;
+				device_type = "tbi-phy";
+			};
+		};
+
+		enet0: ethernet@b0000 {
+			status = "disabled";
+		};
+
+		enet1: ethernet@b1000 {
+			phy-handle = <&phy0>;
+			tbi-handle = <&tbi0>;
+			phy-connection-type = "sgmii";
+		};
+
+		enet2: ethernet@b2000 {
+			phy-handle = <&phy1>;
+			phy-connection-type = "rgmii-id";
+		};
+
+		usb@22000 {
+			phy_type = "ulpi";
+		};
+
+		/* USB2 is shared with localbus, so it must be disabled
+		   by default. We can't put 'status = "disabled";' here
+		   since U-Boot doesn't clear the status property when
+		   it enables USB2. OTOH, U-Boot does create a new node
+		   when there isn't any. So, just comment it out.
+		usb@23000 {
+			phy_type = "ulpi";
+		};
+		*/
+
+		mpic: pic@40000 {
+			protected-sources = <
+			42 29 30 34	/* serial1, enet0-queue-group0 */
+			17 18 24 45	/* enet0-queue-group1, crypto */
+			>;
+		};
+
+	};
+
+	pci0: pcie@ffe09000 {
+		ranges = <0x2000000 0x0 0xa0000000 0 0xa0000000 0x0 0x20000000
+			  0x1000000 0x0 0x00000000 0 0xffc10000 0x0 0x10000>;
+		interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
+		interrupt-map = <
+			/* IDSEL 0x0 */
+			0000 0x0 0x0 0x1 &mpic 0x4 0x1
+			0000 0x0 0x0 0x2 &mpic 0x5 0x1
+			0000 0x0 0x0 0x3 &mpic 0x6 0x1
+			0000 0x0 0x0 0x4 &mpic 0x7 0x1
+			>;
+		pcie@0 {
+			reg = <0x0 0x0 0x0 0x0 0x0>;
+			#size-cells = <2>;
+			#address-cells = <3>;
+			device_type = "pci";
+			ranges = <0x2000000 0x0 0xa0000000
+				  0x2000000 0x0 0xa0000000
+				  0x0 0x20000000
+
+				  0x1000000 0x0 0x0
+				  0x1000000 0x0 0x0
+				  0x0 0x100000>;
+		};
+	};
+
+	pci1: pcie@ffe0a000 {
+		ranges = <0x2000000 0x0 0x80000000 0 0x80000000 0x0 0x20000000
+			  0x1000000 0x0 0x00000000 0 0xffc00000 0x0 0x10000>;
+		interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
+		interrupt-map = <
+			/* IDSEL 0x0 */
+			0000 0x0 0x0 0x1 &mpic 0x0 0x1
+			0000 0x0 0x0 0x2 &mpic 0x1 0x1
+			0000 0x0 0x0 0x3 &mpic 0x2 0x1
+			0000 0x0 0x0 0x4 &mpic 0x3 0x1
+			>;
+		pcie@0 {
+			reg = <0x0 0x0 0x0 0x0 0x0>;
+			#size-cells = <2>;
+			#address-cells = <3>;
+			device_type = "pci";
+			ranges = <0x2000000 0x0 0x80000000
+				  0x2000000 0x0 0x80000000
+				  0x0 0x20000000
+
+				  0x1000000 0x0 0x0
+				  0x1000000 0x0 0x0
+				  0x0 0x100000>;
+		};
+	};
+};
diff -druN linux-2.6.39-libre/arch/powerpc/boot/dts/p1020rdb_camp_core1.dts linux-3.0-rc7-libre/arch/powerpc/boot/dts/p1020rdb_camp_core1.dts
--- linux-2.6.39-libre/arch/powerpc/boot/dts/p1020rdb_camp_core1.dts	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/powerpc/boot/dts/p1020rdb_camp_core1.dts	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,148 @@
+/*
+ * P1020 RDB Core1 Device Tree Source in CAMP mode.
+ *
+ * In CAMP mode, each core needs to have its own dts. Only mpic and L2 cache
+ * can be shared, all the other devices must be assigned to one core only.
+ * This dts allows core1 to have l2, eth0, crypto.
+ *
+ * Please note to add "-b 1" for core1's dts compiling.
+ *
+ * Copyright 2011 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/ "p1020si.dtsi"
+
+/ {
+	model = "fsl,P1020RDB";
+	compatible = "fsl,P1020RDB", "fsl,MPC85XXRDB-CAMP";
+
+	aliases {
+		ethernet0 = &enet0;
+		serial0 = &serial1;
+		};
+
+	cpus {
+		PowerPC,P1020@0 {
+		status = "disabled";
+		};
+	};
+
+	memory {
+		device_type = "memory";
+	};
+
+	localbus@ffe05000 {
+		status = "disabled";
+	};
+
+	soc@ffe00000 {
+		ecm-law@0 {
+			status = "disabled";
+		};
+
+		ecm@1000 {
+			status = "disabled";
+		};
+
+		memory-controller@2000 {
+			status = "disabled";
+		};
+
+		i2c@3000 {
+			status = "disabled";
+		};
+
+		i2c@3100 {
+			status = "disabled";
+		};
+
+		serial0: serial@4500 {
+			status = "disabled";
+		};
+
+		spi@7000 {
+			status = "disabled";
+		};
+
+		gpio: gpio-controller@f000 {
+			status = "disabled";
+		};
+
+		dma@21300 {
+			status = "disabled";
+		};
+
+		mdio@24000 {
+			status = "disabled";
+		};
+
+		mdio@25000 {
+			status = "disabled";
+		};
+
+		enet0: ethernet@b0000 {
+			fixed-link = <1 1 1000 0 0>;
+			phy-connection-type = "rgmii-id";
+
+		};
+
+		enet1: ethernet@b1000 {
+			status = "disabled";
+		};
+
+		enet2: ethernet@b2000 {
+			status = "disabled";
+		};
+
+		usb@22000 {
+			status = "disabled";
+		};
+
+		sdhci@2e000 {
+			status = "disabled";
+		};
+
+		mpic: pic@40000 {
+			protected-sources = <
+			16 		/* ecm, mem, L2, pci0, pci1 */
+			43 42 59	/* i2c, serial0, spi */
+			47 63 62 	/* gpio, tdm */
+			20 21 22 23	/* dma */
+			03 02 		/* mdio */
+			35 36 40	/* enet1-queue-group0 */
+			51 52 67	/* enet1-queue-group1 */
+			31 32 33	/* enet2-queue-group0 */
+			25 26 27	/* enet2-queue-group1 */
+			28 72 58 	/* usb, sdhci, crypto */
+			0xb0 0xb1 0xb2	/* message */
+			0xb3 0xb4 0xb5
+			0xb6 0xb7
+			0xe0 0xe1 0xe2	/* msi */
+			0xe3 0xe4 0xe5
+			0xe6 0xe7		/* sdhci, crypto , pci */
+			>;
+		};
+
+		msi@41600 {
+			status = "disabled";
+		};
+
+		global-utilities@e0000 {	//global utilities block
+			status = "disabled";
+		};
+
+	};
+
+	pci0: pcie@ffe09000 {
+		status = "disabled";
+	};
+
+	pci1: pcie@ffe0a000 {
+		status = "disabled";
+	};
+};
diff -druN linux-2.6.39-libre/arch/powerpc/boot/dts/p1020rdb.dts linux-3.0-rc7-libre/arch/powerpc/boot/dts/p1020rdb.dts
--- linux-2.6.39-libre/arch/powerpc/boot/dts/p1020rdb.dts	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/boot/dts/p1020rdb.dts	2011-07-11 19:51:52.000000000 -0400
@@ -9,12 +9,11 @@
  * option) any later version.
  */
 
-/dts-v1/;
+/include/ "p1020si.dtsi"
+
 / {
-	model = "fsl,P1020";
+	model = "fsl,P1020RDB";
 	compatible = "fsl,P1020RDB";
-	#address-cells = <2>;
-	#size-cells = <2>;
 
 	aliases {
 		serial0 = &serial0;
@@ -26,34 +25,11 @@
 		pci1 = &pci1;
 	};
 
-	cpus {
-		#address-cells = <1>;
-		#size-cells = <0>;
-
-		PowerPC,P1020@0 {
-			device_type = "cpu";
-			reg = <0x0>;
-			next-level-cache = <&L2>;
-		};
-
-		PowerPC,P1020@1 {
-			device_type = "cpu";
-			reg = <0x1>;
-			next-level-cache = <&L2>;
-		};
-	};
-
 	memory {
 		device_type = "memory";
 	};
 
 	localbus@ffe05000 {
-		#address-cells = <2>;
-		#size-cells = <1>;
-		compatible = "fsl,p1020-elbc", "fsl,elbc", "simple-bus";
-		reg = <0 0xffe05000 0 0x1000>;
-		interrupts = <19 2>;
-		interrupt-parent = <&mpic>;
 
 		/* NOR, NAND Flashes and Vitesse 5 port L2 switch */
 		ranges = <0x0 0x0 0x0 0xef000000 0x01000000
@@ -165,88 +141,14 @@
 	};
 
 	soc@ffe00000 {
-		#address-cells = <1>;
-		#size-cells = <1>;
-		device_type = "soc";
-		compatible = "fsl,p1020-immr", "simple-bus";
-		ranges = <0x0  0x0 0xffe00000 0x100000>;
-		bus-frequency = <0>;		// Filled out by uboot.
-
-		ecm-law@0 {
-			compatible = "fsl,ecm-law";
-			reg = <0x0 0x1000>;
-			fsl,num-laws = <12>;
-		};
-
-		ecm@1000 {
-			compatible = "fsl,p1020-ecm", "fsl,ecm";
-			reg = <0x1000 0x1000>;
-			interrupts = <16 2>;
-			interrupt-parent = <&mpic>;
-		};
-
-		memory-controller@2000 {
-			compatible = "fsl,p1020-memory-controller";
-			reg = <0x2000 0x1000>;
-			interrupt-parent = <&mpic>;
-			interrupts = <16 2>;
-		};
-
 		i2c@3000 {
-			#address-cells = <1>;
-			#size-cells = <0>;
-			cell-index = <0>;
-			compatible = "fsl-i2c";
-			reg = <0x3000 0x100>;
-			interrupts = <43 2>;
-			interrupt-parent = <&mpic>;
-			dfsrr;
 			rtc@68 {
 				compatible = "dallas,ds1339";
 				reg = <0x68>;
 			};
 		};
 
-		i2c@3100 {
-			#address-cells = <1>;
-			#size-cells = <0>;
-			cell-index = <1>;
-			compatible = "fsl-i2c";
-			reg = <0x3100 0x100>;
-			interrupts = <43 2>;
-			interrupt-parent = <&mpic>;
-			dfsrr;
-		};
-
-		serial0: serial@4500 {
-			cell-index = <0>;
-			device_type = "serial";
-			compatible = "ns16550";
-			reg = <0x4500 0x100>;
-			clock-frequency = <0>;
-			interrupts = <42 2>;
-			interrupt-parent = <&mpic>;
-		};
-
-		serial1: serial@4600 {
-			cell-index = <1>;
-			device_type = "serial";
-			compatible = "ns16550";
-			reg = <0x4600 0x100>;
-			clock-frequency = <0>;
-			interrupts = <42 2>;
-			interrupt-parent = <&mpic>;
-		};
-
 		spi@7000 {
-			cell-index = <0>;
-			#address-cells = <1>;
-			#size-cells = <0>;
-			compatible = "fsl,espi";
-			reg = <0x7000 0x1000>;
-			interrupts = <59 0x2>;
-			interrupt-parent = <&mpic>;
-			mode = "cpu";
 
 			fsl_m25p80@0 {
 				#address-cells = <1>;
@@ -294,66 +196,7 @@
 			};
 		};
 
-		gpio: gpio-controller@f000 {
-			#gpio-cells = <2>;
-			compatible = "fsl,mpc8572-gpio";
-			reg = <0xf000 0x100>;
-			interrupts = <47 0x2>;
-			interrupt-parent = <&mpic>;
-			gpio-controller;
-		};
-
-		L2: l2-cache-controller@20000 {
-			compatible = "fsl,p1020-l2-cache-controller";
-			reg = <0x20000 0x1000>;
-			cache-line-size = <32>;	// 32 bytes
-			cache-size = <0x40000>; // L2,256K
-			interrupt-parent = <&mpic>;
-			interrupts = <16 2>;
-		};
-
-		dma@21300 {
-			#address-cells = <1>;
-			#size-cells = <1>;
-			compatible = "fsl,eloplus-dma";
-			reg = <0x21300 0x4>;
-			ranges = <0x0 0x21100 0x200>;
-			cell-index = <0>;
-			dma-channel@0 {
-				compatible = "fsl,eloplus-dma-channel";
-				reg = <0x0 0x80>;
-				cell-index = <0>;
-				interrupt-parent = <&mpic>;
-				interrupts = <20 2>;
-			};
-			dma-channel@80 {
-				compatible = "fsl,eloplus-dma-channel";
-				reg = <0x80 0x80>;
-				cell-index = <1>;
-				interrupt-parent = <&mpic>;
-				interrupts = <21 2>;
-			};
-			dma-channel@100 {
-				compatible = "fsl,eloplus-dma-channel";
-				reg = <0x100 0x80>;
-				cell-index = <2>;
-				interrupt-parent = <&mpic>;
-				interrupts = <22 2>;
-			};
-			dma-channel@180 {
-				compatible = "fsl,eloplus-dma-channel";
-				reg = <0x180 0x80>;
-				cell-index = <3>;
-				interrupt-parent = <&mpic>;
-				interrupts = <23 2>;
-			};
-		};
-
 		mdio@24000 {
-			#address-cells = <1>;
-			#size-cells = <0>;
-			compatible = "fsl,etsec2-mdio";
-			reg = <0x24000 0x1000 0xb0030 0x4>;
 
 			phy0: ethernet-phy@0 {
 				interrupt-parent = <&mpic>;
@@ -369,10 +212,6 @@
 		};
 
 		mdio@25000 {
-			#address-cells = <1>;
-			#size-cells = <0>;
-			compatible = "fsl,etsec2-tbi";
-			reg = <0x25000 0x1000 0xb1030 0x4>;
 
 			tbi0: tbi-phy@11 {
 				reg = <0x11>;
@@ -381,97 +220,25 @@
 		};
 
 		enet0: ethernet@b0000 {
-			#address-cells = <1>;
-			#size-cells = <1>;
-			device_type = "network";
-			model = "eTSEC";
-			compatible = "fsl,etsec2";
-			fsl,num_rx_queues = <0x8>;
-			fsl,num_tx_queues = <0x8>;
-			local-mac-address = [ 00 00 00 00 00 00 ];
-			interrupt-parent = <&mpic>;
 			fixed-link = <1 1 1000 0 0>;
 			phy-connection-type = "rgmii-id";
 
-			queue-group@0 {
-				#address-cells = <1>;
-				#size-cells = <1>;
-				reg = <0xb0000 0x1000>;
-				interrupts = <29 2 30 2 34 2>;
-			};
-
-			queue-group@1 {
-				#address-cells = <1>;
-				#size-cells = <1>;
-				reg = <0xb4000 0x1000>;
-				interrupts = <17 2 18 2 24 2>;
-			};
 		};
 
 		enet1: ethernet@b1000 {
-			#address-cells = <1>;
-			#size-cells = <1>;
-			device_type = "network";
-			model = "eTSEC";
-			compatible = "fsl,etsec2";
-			fsl,num_rx_queues = <0x8>;
-			fsl,num_tx_queues = <0x8>;
-			local-mac-address = [ 00 00 00 00 00 00 ];
-			interrupt-parent = <&mpic>;
 			phy-handle = <&phy0>;
 			tbi-handle = <&tbi0>;
 			phy-connection-type = "sgmii";
 
-			queue-group@0 {
-				#address-cells = <1>;
-				#size-cells = <1>;
-				reg = <0xb1000 0x1000>;
-				interrupts = <35 2 36 2 40 2>;
-			};
-
-			queue-group@1 {
-				#address-cells = <1>;
-				#size-cells = <1>;
-				reg = <0xb5000 0x1000>;
-				interrupts = <51 2 52 2 67 2>;
-			};
 		};
 
 		enet2: ethernet@b2000 {
-			#address-cells = <1>;
-			#size-cells = <1>;
-			device_type = "network";
-			model = "eTSEC";
-			compatible = "fsl,etsec2";
-			fsl,num_rx_queues = <0x8>;
-			fsl,num_tx_queues = <0x8>;
-			local-mac-address = [ 00 00 00 00 00 00 ];
-			interrupt-parent = <&mpic>;
 			phy-handle = <&phy1>;
 			phy-connection-type = "rgmii-id";
 
-			queue-group@0 {
-				#address-cells = <1>;
-				#size-cells = <1>;
-				reg = <0xb2000 0x1000>;
-				interrupts = <31 2 32 2 33 2>;
-			};
-
-			queue-group@1 {
-				#address-cells = <1>;
-				#size-cells = <1>;
-				reg = <0xb6000 0x1000>;
-				interrupts = <25 2 26 2 27 2>;
-			};
 		};
 
 		usb@22000 {
-			#address-cells = <1>;
-			#size-cells = <0>;
-			compatible = "fsl-usb2-dr";
-			reg = <0x22000 0x1000>;
-			interrupt-parent = <&mpic>;
-			interrupts = <28 0x2>;
 			phy_type = "ulpi";
 		};
 
@@ -481,82 +248,23 @@
 		   it enables USB2. OTOH, U-Boot does create a new node
 		   when there isn't any. So, just comment it out.
 		usb@23000 {
-			#address-cells = <1>;
-			#size-cells = <0>;
-			compatible = "fsl-usb2-dr";
-			reg = <0x23000 0x1000>;
-			interrupt-parent = <&mpic>;
-			interrupts = <46 0x2>;
 			phy_type = "ulpi";
 		};
 		*/
 
-		sdhci@2e000 {
-			compatible = "fsl,p1020-esdhc", "fsl,esdhc";
-			reg = <0x2e000 0x1000>;
-			interrupts = <72 0x2>;
-			interrupt-parent = <&mpic>;
-			/* Filled in by U-Boot */
-			clock-frequency = <0>;
-		};
-
-		crypto@30000 {
-			compatible = "fsl,sec3.1", "fsl,sec3.0", "fsl,sec2.4",
-				     "fsl,sec2.2", "fsl,sec2.1", "fsl,sec2.0";
-			reg = <0x30000 0x10000>;
-			interrupts = <45 2 58 2>;
-			interrupt-parent = <&mpic>;
-			fsl,num-channels = <4>;
-			fsl,channel-fifo-len = <24>;
-			fsl,exec-units-mask = <0xbfe>;
-			fsl,descriptor-types-mask = <0x3ab0ebf>;
-		};
-
-		mpic: pic@40000 {
-			interrupt-controller;
-			#address-cells = <0>;
-			#interrupt-cells = <2>;
-			reg = <0x40000 0x40000>;
-			compatible = "chrp,open-pic";
-			device_type = "open-pic";
-		};
-
-		msi@41600 {
-			compatible = "fsl,p1020-msi", "fsl,mpic-msi";
-			reg = <0x41600 0x80>;
-			msi-available-ranges = <0 0x100>;
-			interrupts = <
-				0xe0 0
-				0xe1 0
-				0xe2 0
-				0xe3 0
-				0xe4 0
-				0xe5 0
-				0xe6 0
-				0xe7 0>;
-			interrupt-parent = <&mpic>;
-		};
-
-		global-utilities@e0000 {	//global utilities block
-			compatible = "fsl,p1020-guts";
-			reg = <0xe0000 0x1000>;
-			fsl,has-rstcr;
-		};
 	};
 
 	pci0: pcie@ffe09000 {
-		compatible = "fsl,mpc8548-pcie";
-		device_type = "pci";
-		#interrupt-cells = <1>;
-		#size-cells = <2>;
-		#address-cells = <3>;
-		reg = <0 0xffe09000 0 0x1000>;
-		bus-range = <0 255>;
 		ranges = <0x2000000 0x0 0xa0000000 0 0xa0000000 0x0 0x20000000
 			  0x1000000 0x0 0x00000000 0 0xffc10000 0x0 0x10000>;
-		clock-frequency = <33333333>;
-		interrupt-parent = <&mpic>;
-		interrupts = <16 2>;
+		interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
+		interrupt-map = <
+			/* IDSEL 0x0 */
+			0000 0x0 0x0 0x1 &mpic 0x4 0x1
+			0000 0x0 0x0 0x2 &mpic 0x5 0x1
+			0000 0x0 0x0 0x3 &mpic 0x6 0x1
+			0000 0x0 0x0 0x4 &mpic 0x7 0x1
+			>;
 		pcie@0 {
 			reg = <0x0 0x0 0x0 0x0 0x0>;
 			#size-cells = <2>;
@@ -573,18 +281,16 @@
 	};
 
 	pci1: pcie@ffe0a000 {
-		compatible = "fsl,mpc8548-pcie";
-		device_type = "pci";
-		#interrupt-cells = <1>;
-		#size-cells = <2>;
-		#address-cells = <3>;
-		reg = <0 0xffe0a000 0 0x1000>;
-		bus-range = <0 255>;
 		ranges = <0x2000000 0x0 0x80000000 0 0x80000000 0x0 0x20000000
 			  0x1000000 0x0 0x00000000 0 0xffc00000 0x0 0x10000>;
-		clock-frequency = <33333333>;
-		interrupt-parent = <&mpic>;
-		interrupts = <16 2>;
+		interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
+		interrupt-map = <
+			/* IDSEL 0x0 */
+			0000 0x0 0x0 0x1 &mpic 0x0 0x1
+			0000 0x0 0x0 0x2 &mpic 0x1 0x1
+			0000 0x0 0x0 0x3 &mpic 0x2 0x1
+			0000 0x0 0x0 0x4 &mpic 0x3 0x1
+			>;
 		pcie@0 {
 			reg = <0x0 0x0 0x0 0x0 0x0>;
 			#size-cells = <2>;
diff -druN linux-2.6.39-libre/arch/powerpc/boot/dts/p1020si.dtsi linux-3.0-rc7-libre/arch/powerpc/boot/dts/p1020si.dtsi
--- linux-2.6.39-libre/arch/powerpc/boot/dts/p1020si.dtsi	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/powerpc/boot/dts/p1020si.dtsi	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,377 @@
+/*
+ * P1020si Device Tree Source
+ *
+ * Copyright 2011 Freescale Semiconductor Inc.
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+/dts-v1/;
+/ {
+	compatible = "fsl,P1020";
+	#address-cells = <2>;
+	#size-cells = <2>;
+
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		PowerPC,P1020@0 {
+			device_type = "cpu";
+			reg = <0x0>;
+			next-level-cache = <&L2>;
+		};
+
+		PowerPC,P1020@1 {
+			device_type = "cpu";
+			reg = <0x1>;
+			next-level-cache = <&L2>;
+		};
+	};
+
+	localbus@ffe05000 {
+		#address-cells = <2>;
+		#size-cells = <1>;
+		compatible = "fsl,p1020-elbc", "fsl,elbc", "simple-bus";
+		reg = <0 0xffe05000 0 0x1000>;
+		interrupts = <19 2>;
+		interrupt-parent = <&mpic>;
+	};
+
+	soc@ffe00000 {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		device_type = "soc";
+		compatible = "fsl,p1020-immr", "simple-bus";
+		ranges = <0x0  0x0 0xffe00000 0x100000>;
+		bus-frequency = <0>;		// Filled out by uboot.
+
+		ecm-law@0 {
+			compatible = "fsl,ecm-law";
+			reg = <0x0 0x1000>;
+			fsl,num-laws = <12>;
+		};
+
+		ecm@1000 {
+			compatible = "fsl,p1020-ecm", "fsl,ecm";
+			reg = <0x1000 0x1000>;
+			interrupts = <16 2>;
+			interrupt-parent = <&mpic>;
+		};
+
+		memory-controller@2000 {
+			compatible = "fsl,p1020-memory-controller";
+			reg = <0x2000 0x1000>;
+			interrupt-parent = <&mpic>;
+			interrupts = <16 2>;
+		};
+
+		i2c@3000 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			cell-index = <0>;
+			compatible = "fsl-i2c";
+			reg = <0x3000 0x100>;
+			interrupts = <43 2>;
+			interrupt-parent = <&mpic>;
+			dfsrr;
+		};
+
+		i2c@3100 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			cell-index = <1>;
+			compatible = "fsl-i2c";
+			reg = <0x3100 0x100>;
+			interrupts = <43 2>;
+			interrupt-parent = <&mpic>;
+			dfsrr;
+		};
+
+		serial0: serial@4500 {
+			cell-index = <0>;
+			device_type = "serial";
+			compatible = "ns16550";
+			reg = <0x4500 0x100>;
+			clock-frequency = <0>;
+			interrupts = <42 2>;
+			interrupt-parent = <&mpic>;
+		};
+
+		serial1: serial@4600 {
+			cell-index = <1>;
+			device_type = "serial";
+			compatible = "ns16550";
+			reg = <0x4600 0x100>;
+			clock-frequency = <0>;
+			interrupts = <42 2>;
+			interrupt-parent = <&mpic>;
+		};
+
+		spi@7000 {
+			cell-index = <0>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "fsl,espi";
+			reg = <0x7000 0x1000>;
+			interrupts = <59 0x2>;
+			interrupt-parent = <&mpic>;
+			mode = "cpu";
+		};
+
+		gpio: gpio-controller@f000 {
+			#gpio-cells = <2>;
+			compatible = "fsl,mpc8572-gpio";
+			reg = <0xf000 0x100>;
+			interrupts = <47 0x2>;
+			interrupt-parent = <&mpic>;
+			gpio-controller;
+		};
+
+		L2: l2-cache-controller@20000 {
+			compatible = "fsl,p1020-l2-cache-controller";
+			reg = <0x20000 0x1000>;
+			cache-line-size = <32>;	// 32 bytes
+			cache-size = <0x40000>; // L2,256K
+			interrupt-parent = <&mpic>;
+			interrupts = <16 2>;
+		};
+
+		dma@21300 {
+			#address-cells = <1>;
+			#size-cells = <1>;
+			compatible = "fsl,eloplus-dma";
+			reg = <0x21300 0x4>;
+			ranges = <0x0 0x21100 0x200>;
+			cell-index = <0>;
+			dma-channel@0 {
+				compatible = "fsl,eloplus-dma-channel";
+				reg = <0x0 0x80>;
+				cell-index = <0>;
+				interrupt-parent = <&mpic>;
+				interrupts = <20 2>;
+			};
+			dma-channel@80 {
+				compatible = "fsl,eloplus-dma-channel";
+				reg = <0x80 0x80>;
+				cell-index = <1>;
+				interrupt-parent = <&mpic>;
+				interrupts = <21 2>;
+			};
+			dma-channel@100 {
+				compatible = "fsl,eloplus-dma-channel";
+				reg = <0x100 0x80>;
+				cell-index = <2>;
+				interrupt-parent = <&mpic>;
+				interrupts = <22 2>;
+			};
+			dma-channel@180 {
+				compatible = "fsl,eloplus-dma-channel";
+				reg = <0x180 0x80>;
+				cell-index = <3>;
+				interrupt-parent = <&mpic>;
+				interrupts = <23 2>;
+			};
+		};
+
+		mdio@24000 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "fsl,etsec2-mdio";
+			reg = <0x24000 0x1000 0xb0030 0x4>;
+
+		};
+
+		mdio@25000 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "fsl,etsec2-tbi";
+			reg = <0x25000 0x1000 0xb1030 0x4>;
+
+		};
+
+		enet0: ethernet@b0000 {
+			#address-cells = <1>;
+			#size-cells = <1>;
+			device_type = "network";
+			model = "eTSEC";
+			compatible = "fsl,etsec2";
+			fsl,num_rx_queues = <0x8>;
+			fsl,num_tx_queues = <0x8>;
+			local-mac-address = [ 00 00 00 00 00 00 ];
+			interrupt-parent = <&mpic>;
+
+			queue-group@0 {
+				#address-cells = <1>;
+				#size-cells = <1>;
+				reg = <0xb0000 0x1000>;
+				interrupts = <29 2 30 2 34 2>;
+			};
+
+			queue-group@1 {
+				#address-cells = <1>;
+				#size-cells = <1>;
+				reg = <0xb4000 0x1000>;
+				interrupts = <17 2 18 2 24 2>;
+			};
+		};
+
+		enet1: ethernet@b1000 {
+			#address-cells = <1>;
+			#size-cells = <1>;
+			device_type = "network";
+			model = "eTSEC";
+			compatible = "fsl,etsec2";
+			fsl,num_rx_queues = <0x8>;
+			fsl,num_tx_queues = <0x8>;
+			local-mac-address = [ 00 00 00 00 00 00 ];
+			interrupt-parent = <&mpic>;
+
+			queue-group@0 {
+				#address-cells = <1>;
+				#size-cells = <1>;
+				reg = <0xb1000 0x1000>;
+				interrupts = <35 2 36 2 40 2>;
+			};
+
+			queue-group@1 {
+				#address-cells = <1>;
+				#size-cells = <1>;
+				reg = <0xb5000 0x1000>;
+				interrupts = <51 2 52 2 67 2>;
+			};
+		};
+
+		enet2: ethernet@b2000 {
+			#address-cells = <1>;
+			#size-cells = <1>;
+			device_type = "network";
+			model = "eTSEC";
+			compatible = "fsl,etsec2";
+			fsl,num_rx_queues = <0x8>;
+			fsl,num_tx_queues = <0x8>;
+			local-mac-address = [ 00 00 00 00 00 00 ];
+			interrupt-parent = <&mpic>;
+
+			queue-group@0 {
+				#address-cells = <1>;
+				#size-cells = <1>;
+				reg = <0xb2000 0x1000>;
+				interrupts = <31 2 32 2 33 2>;
+			};
+
+			queue-group@1 {
+				#address-cells = <1>;
+				#size-cells = <1>;
+				reg = <0xb6000 0x1000>;
+				interrupts = <25 2 26 2 27 2>;
+			};
+		};
+
+		usb@22000 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "fsl-usb2-dr";
+			reg = <0x22000 0x1000>;
+			interrupt-parent = <&mpic>;
+			interrupts = <28 0x2>;
+		};
+
+		/* USB2 is shared with localbus, so it must be disabled
+		   by default. We can't put 'status = "disabled";' here
+		   since U-Boot doesn't clear the status property when
+		   it enables USB2. OTOH, U-Boot does create a new node
+		   when there isn't any. So, just comment it out.
+		usb@23000 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "fsl-usb2-dr";
+			reg = <0x23000 0x1000>;
+			interrupt-parent = <&mpic>;
+			interrupts = <46 0x2>;
+			phy_type = "ulpi";
+		};
+		*/
+
+		sdhci@2e000 {
+			compatible = "fsl,p1020-esdhc", "fsl,esdhc";
+			reg = <0x2e000 0x1000>;
+			interrupts = <72 0x2>;
+			interrupt-parent = <&mpic>;
+			/* Filled in by U-Boot */
+			clock-frequency = <0>;
+		};
+
+		crypto@30000 {
+			compatible = "fsl,sec3.1", "fsl,sec3.0", "fsl,sec2.4",
+				     "fsl,sec2.2", "fsl,sec2.1", "fsl,sec2.0";
+			reg = <0x30000 0x10000>;
+			interrupts = <45 2 58 2>;
+			interrupt-parent = <&mpic>;
+			fsl,num-channels = <4>;
+			fsl,channel-fifo-len = <24>;
+			fsl,exec-units-mask = <0xbfe>;
+			fsl,descriptor-types-mask = <0x3ab0ebf>;
+		};
+
+		mpic: pic@40000 {
+			interrupt-controller;
+			#address-cells = <0>;
+			#interrupt-cells = <2>;
+			reg = <0x40000 0x40000>;
+			compatible = "chrp,open-pic";
+			device_type = "open-pic";
+		};
+
+		msi@41600 {
+			compatible = "fsl,p1020-msi", "fsl,mpic-msi";
+			reg = <0x41600 0x80>;
+			msi-available-ranges = <0 0x100>;
+			interrupts = <
+				0xe0 0
+				0xe1 0
+				0xe2 0
+				0xe3 0
+				0xe4 0
+				0xe5 0
+				0xe6 0
+				0xe7 0>;
+			interrupt-parent = <&mpic>;
+		};
+
+		global-utilities@e0000 {	//global utilities block
+			compatible = "fsl,p1020-guts","fsl,p2020-guts";
+			reg = <0xe0000 0x1000>;
+			fsl,has-rstcr;
+		};
+	};
+
+	pci0: pcie@ffe09000 {
+		compatible = "fsl,mpc8548-pcie";
+		device_type = "pci";
+		#interrupt-cells = <1>;
+		#size-cells = <2>;
+		#address-cells = <3>;
+		reg = <0 0xffe09000 0 0x1000>;
+		bus-range = <0 255>;
+		clock-frequency = <33333333>;
+		interrupt-parent = <&mpic>;
+		interrupts = <16 2>;
+	};
+
+	pci1: pcie@ffe0a000 {
+		compatible = "fsl,mpc8548-pcie";
+		device_type = "pci";
+		#interrupt-cells = <1>;
+		#size-cells = <2>;
+		#address-cells = <3>;
+		reg = <0 0xffe0a000 0 0x1000>;
+		bus-range = <0 255>;
+		clock-frequency = <33333333>;
+		interrupt-parent = <&mpic>;
+		interrupts = <16 2>;
+	};
+};
diff -druN linux-2.6.39-libre/arch/powerpc/boot/dts/p1022ds.dts linux-3.0-rc7-libre/arch/powerpc/boot/dts/p1022ds.dts
--- linux-2.6.39-libre/arch/powerpc/boot/dts/p1022ds.dts	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/boot/dts/p1022ds.dts	2011-07-11 19:51:52.000000000 -0400
@@ -52,7 +52,7 @@
 		#size-cells = <1>;
 		compatible = "fsl,p1022-elbc", "fsl,elbc", "simple-bus";
 		reg = <0 0xffe05000 0 0x1000>;
-		interrupts = <19 2>;
+		interrupts = <19 2 0 0>;
 
 		ranges = <0x0 0x0 0xf 0xe8000000 0x08000000
 			  0x1 0x0 0xf 0xe0000000 0x08000000
@@ -157,7 +157,7 @@
 			 * IRQ8 is generated if the "EVENT" switch is pressed
 			 * and PX_CTL[EVESEL] is set to 00.
 			 */
-			interrupts = <8 8>;
+			interrupts = <8 8 0 0>;
 		};
 	};
 
@@ -178,13 +178,13 @@
 		ecm@1000 {
 			compatible = "fsl,p1022-ecm", "fsl,ecm";
 			reg = <0x1000 0x1000>;
-			interrupts = <16 2>;
+			interrupts = <16 2 0 0>;
 		};
 
 		memory-controller@2000 {
 			compatible = "fsl,p1022-memory-controller";
 			reg = <0x2000 0x1000>;
-			interrupts = <16 2>;
+			interrupts = <16 2 0 0>;
 		};
 
 		i2c@3000 {
@@ -193,7 +193,7 @@
 			cell-index = <0>;
 			compatible = "fsl-i2c";
 			reg = <0x3000 0x100>;
-			interrupts = <43 2>;
+			interrupts = <43 2 0 0>;
 			dfsrr;
 		};
 
@@ -203,14 +203,16 @@
 			cell-index = <1>;
 			compatible = "fsl-i2c";
 			reg = <0x3100 0x100>;
-			interrupts = <43 2>;
+			interrupts = <43 2 0 0>;
 			dfsrr;
 
 			wm8776:codec@1a {
 				compatible = "wlf,wm8776";
 				reg = <0x1a>;
-				/* MCLK source is a stand-alone oscillator */
-				clock-frequency = <12288000>;
+				/*
+				 * clock-frequency will be set by U-Boot if
+				 * the clock is enabled.
+				 */
 			};
 		};
 
@@ -220,7 +222,7 @@
 			compatible = "ns16550";
 			reg = <0x4500 0x100>;
 			clock-frequency = <0>;
-			interrupts = <42 2>;
+			interrupts = <42 2 0 0>;
 		};
 
 		serial1: serial@4600 {
@@ -229,7 +231,7 @@
 			compatible = "ns16550";
 			reg = <0x4600 0x100>;
 			clock-frequency = <0>;
-			interrupts = <42 2>;
+			interrupts = <42 2 0 0>;
 		};
 
 		spi@7000 {
@@ -238,7 +240,7 @@
 			#size-cells = <0>;
 			compatible = "fsl,espi";
 			reg = <0x7000 0x1000>;
-			interrupts = <59 0x2>;
+			interrupts = <59 0x2 0 0>;
 			espi,num-ss-bits = <4>;
 			mode = "cpu";
 
@@ -275,12 +277,13 @@
 			compatible = "fsl,mpc8610-ssi";
 			cell-index = <0>;
 			reg = <0x15000 0x100>;
-			interrupts = <75 2>;
+			interrupts = <75 2 0 0>;
 			fsl,mode = "i2s-slave";
 			codec-handle = <&wm8776>;
 			fsl,playback-dma = <&dma00>;
 			fsl,capture-dma = <&dma01>;
-			fsl,fifo-depth = <16>;
+			fsl,fifo-depth = <15>;
+			fsl,ssi-asynchronous;
 		};
 
 		dma@c300 {
@@ -294,25 +297,25 @@
 				compatible = "fsl,ssi-dma-channel";
 				reg = <0x0 0x80>;
 				cell-index = <0>;
-				interrupts = <76 2>;
+				interrupts = <76 2 0 0>;
 			};
 			dma01: dma-channel@80 {
 				compatible = "fsl,ssi-dma-channel";
 				reg = <0x80 0x80>;
 				cell-index = <1>;
-				interrupts = <77 2>;
+				interrupts = <77 2 0 0>;
 			};
 			dma-channel@100 {
 				compatible = "fsl,eloplus-dma-channel";
 				reg = <0x100 0x80>;
 				cell-index = <2>;
-				interrupts = <78 2>;
+				interrupts = <78 2 0 0>;
 			};
 			dma-channel@180 {
 				compatible = "fsl,eloplus-dma-channel";
 				reg = <0x180 0x80>;
 				cell-index = <3>;
-				interrupts = <79 2>;
+				interrupts = <79 2 0 0>;
 			};
 		};
 
@@ -320,7 +323,7 @@
 			#gpio-cells = <2>;
 			compatible = "fsl,mpc8572-gpio";
 			reg = <0xf000 0x100>;
-			interrupts = <47 0x2>;
+			interrupts = <47 0x2 0 0>;
 			gpio-controller;
 		};
 
@@ -329,7 +332,7 @@
 			reg = <0x20000 0x1000>;
 			cache-line-size = <32>;	// 32 bytes
 			cache-size = <0x40000>; // L2, 256K
-			interrupts = <16 2>;
+			interrupts = <16 2 0 0>;
 		};
 
 		dma@21300 {
@@ -343,25 +346,25 @@
 				compatible = "fsl,eloplus-dma-channel";
 				reg = <0x0 0x80>;
 				cell-index = <0>;
-				interrupts = <20 2>;
+				interrupts = <20 2 0 0>;
 			};
 			dma-channel@80 {
 				compatible = "fsl,eloplus-dma-channel";
 				reg = <0x80 0x80>;
 				cell-index = <1>;
-				interrupts = <21 2>;
+				interrupts = <21 2 0 0>;
 			};
 			dma-channel@100 {
 				compatible = "fsl,eloplus-dma-channel";
 				reg = <0x100 0x80>;
 				cell-index = <2>;
-				interrupts = <22 2>;
+				interrupts = <22 2 0 0>;
 			};
 			dma-channel@180 {
 				compatible = "fsl,eloplus-dma-channel";
 				reg = <0x180 0x80>;
 				cell-index = <3>;
-				interrupts = <23 2>;
+				interrupts = <23 2 0 0>;
 			};
 		};
 
@@ -370,7 +373,7 @@
 			#size-cells = <0>;
 			compatible = "fsl-usb2-dr";
 			reg = <0x22000 0x1000>;
-			interrupts = <28 0x2>;
+			interrupts = <28 0x2 0 0>;
 			phy_type = "ulpi";
 		};
 
@@ -381,11 +384,11 @@
 			reg = <0x24000 0x1000 0xb0030 0x4>;
 
 			phy0: ethernet-phy@0 {
-				interrupts = <3 1>;
+				interrupts = <3 1 0 0>;
 				reg = <0x1>;
 			};
 			phy1: ethernet-phy@1 {
-				interrupts = <9 1>;
+				interrupts = <9 1 0 0>;
 				reg = <0x2>;
 			};
 		};
@@ -416,13 +419,13 @@
 				#address-cells = <1>;
 				#size-cells = <1>;
 				reg = <0xB0000 0x1000>;
-				interrupts = <29 2 30 2 34 2>;
+				interrupts = <29 2 0 0 30 2 0 0 34 2 0 0>;
 			};
 			queue-group@1{
 				#address-cells = <1>;
 				#size-cells = <1>;
 				reg = <0xB4000 0x1000>;
-				interrupts = <17 2 18 2 24 2>;
+				interrupts = <17 2 0 0 18 2 0 0 24 2 0 0>;
 			};
 		};
 
@@ -443,20 +446,20 @@
 				#address-cells = <1>;
 				#size-cells = <1>;
 				reg = <0xB1000 0x1000>;
-				interrupts = <35 2 36 2 40 2>;
+				interrupts = <35 2 0 0 36 2 0 0 40 2 0 0>;
 			};
 			queue-group@1{
 				#address-cells = <1>;
 				#size-cells = <1>;
 				reg = <0xB5000 0x1000>;
-				interrupts = <51 2 52 2 67 2>;
+				interrupts = <51 2 0 0 52 2 0 0 67 2 0 0>;
 			};
 		};
 
 		sdhci@2e000 {
 			compatible = "fsl,p1022-esdhc", "fsl,esdhc";
 			reg = <0x2e000 0x1000>;
-			interrupts = <72 0x2>;
+			interrupts = <72 0x2 0 0>;
 			fsl,sdhci-auto-cmd12;
 			/* Filled in by U-Boot */
 			clock-frequency = <0>;
@@ -467,7 +470,7 @@
 				     "fsl,sec2.4", "fsl,sec2.2", "fsl,sec2.1",
 				     "fsl,sec2.0";
 			reg = <0x30000 0x10000>;
-			interrupts = <45 2 58 2>;
+			interrupts = <45 2 0 0 58 2 0 0>;
 			fsl,num-channels = <4>;
 			fsl,channel-fifo-len = <24>;
 			fsl,exec-units-mask = <0x97c>;
@@ -478,14 +481,14 @@
 			compatible = "fsl,p1022-sata", "fsl,pq-sata-v2";
 			reg = <0x18000 0x1000>;
 			cell-index = <1>;
-			interrupts = <74 0x2>;
+			interrupts = <74 0x2 0 0>;
 		};
 
 		sata@19000 {
 			compatible = "fsl,p1022-sata", "fsl,pq-sata-v2";
 			reg = <0x19000 0x1000>;
 			cell-index = <2>;
-			interrupts = <41 0x2>;
+			interrupts = <41 0x2 0 0>;
 		};
 
 		power@e0070{
@@ -496,21 +499,33 @@
 		display@10000 {
 			compatible = "fsl,diu", "fsl,p1022-diu";
 			reg = <0x10000 1000>;
-			interrupts = <64 2>;
+			interrupts = <64 2 0 0>;
 		};
 
 		timer@41100 {
 			compatible = "fsl,mpic-global-timer";
-			reg = <0x41100 0x204>;
-			interrupts = <0xf7 0x2>;
+			reg = <0x41100 0x100 0x41300 4>;
+			interrupts = <0 0 3 0
+			              1 0 3 0
+			              2 0 3 0
+			              3 0 3 0>;
+		};
+
+		timer@42100 {
+			compatible = "fsl,mpic-global-timer";
+			reg = <0x42100 0x100 0x42300 4>;
+			interrupts = <4 0 3 0
+			              5 0 3 0
+			              6 0 3 0
+			              7 0 3 0>;
 		};
 
 		mpic: pic@40000 {
 			interrupt-controller;
 			#address-cells = <0>;
-			#interrupt-cells = <2>;
+			#interrupt-cells = <4>;
 			reg = <0x40000 0x40000>;
-			compatible = "chrp,open-pic";
+			compatible = "fsl,mpic";
 			device_type = "open-pic";
 		};
 
@@ -519,14 +534,14 @@
 			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>;
+				0xe0 0 0 0
+				0xe1 0 0 0
+				0xe2 0 0 0
+				0xe3 0 0 0
+				0xe4 0 0 0
+				0xe5 0 0 0
+				0xe6 0 0 0
+				0xe7 0 0 0>;
 		};
 
 		global-utilities@e0000 {	//global utilities block
@@ -547,7 +562,7 @@
 		ranges = <0x2000000 0x0 0xa0000000 0xc 0x20000000 0x0 0x20000000
 			  0x1000000 0x0 0x00000000 0xf 0xffc10000 0x0 0x10000>;
 		clock-frequency = <33333333>;
-		interrupts = <16 2>;
+		interrupts = <16 2 0 0>;
 		interrupt-map-mask = <0xf800 0 0 7>;
 		interrupt-map = <
 			/* IDSEL 0x0 */
@@ -582,7 +597,7 @@
 		ranges = <0x2000000 0x0 0xc0000000 0xc 0x40000000 0x0 0x20000000
 			  0x1000000 0x0 0x00000000 0xf 0xffc20000 0x0 0x10000>;
 		clock-frequency = <33333333>;
-		interrupts = <16 2>;
+		interrupts = <16 2 0 0>;
 		interrupt-map-mask = <0xf800 0 0 7>;
 		interrupt-map = <
 			/* IDSEL 0x0 */
@@ -618,7 +633,7 @@
 		ranges = <0x2000000 0x0 0x80000000 0xc 0x00000000 0x0 0x20000000
 			  0x1000000 0x0 0x00000000 0xf 0xffc00000 0x0 0x10000>;
 		clock-frequency = <33333333>;
-		interrupts = <16 2>;
+		interrupts = <16 2 0 0>;
 		interrupt-map-mask = <0xf800 0 0 7>;
 		interrupt-map = <
 			/* IDSEL 0x0 */
diff -druN linux-2.6.39-libre/arch/powerpc/boot/dts/p2020ds.dts linux-3.0-rc7-libre/arch/powerpc/boot/dts/p2020ds.dts
--- linux-2.6.39-libre/arch/powerpc/boot/dts/p2020ds.dts	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/boot/dts/p2020ds.dts	2011-07-11 19:51:52.000000000 -0400
@@ -1,7 +1,7 @@
 /*
  * P2020 DS Device Tree Source
  *
- * Copyright 2009 Freescale Semiconductor Inc.
+ * Copyright 2009-2011 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
@@ -9,12 +9,11 @@
  * option) any later version.
  */
 
-/dts-v1/;
+/include/ "p2020si.dtsi"
+
 / {
-	model = "fsl,P2020";
+	model = "fsl,P2020DS";
 	compatible = "fsl,P2020DS";
-	#address-cells = <2>;
-	#size-cells = <2>;
 
 	aliases {
 		ethernet0 = &enet0;
@@ -27,35 +26,13 @@
 		pci2 = &pci2;
 	};
 
-	cpus {
-		#address-cells = <1>;
-		#size-cells = <0>;
-
-		PowerPC,P2020@0 {
-			device_type = "cpu";
-			reg = <0x0>;
-			next-level-cache = <&L2>;
-		};
-
-		PowerPC,P2020@1 {
-			device_type = "cpu";
-			reg = <0x1>;
-			next-level-cache = <&L2>;
-		};
-	};
 
 	memory {
 		device_type = "memory";
 	};
 
 	localbus@ffe05000 {
-		#address-cells = <2>;
-		#size-cells = <1>;
 		compatible = "fsl,elbc", "simple-bus";
-		reg = <0 0xffe05000 0 0x1000>;
-		interrupts = <19 2>;
-		interrupt-parent = <&mpic>;
-
 		ranges = <0x0 0x0 0x0 0xe8000000 0x08000000
 			  0x1 0x0 0x0 0xe0000000 0x08000000
 			  0x2 0x0 0x0 0xffa00000 0x00040000
@@ -158,352 +135,90 @@
 	};
 
 	soc@ffe00000 {
-		#address-cells = <1>;
-		#size-cells = <1>;
-		device_type = "soc";
-		compatible = "fsl,p2020-immr", "simple-bus";
-		ranges = <0x0 0 0xffe00000 0x100000>;
-		bus-frequency = <0>;		// Filled out by uboot.
 
-		ecm-law@0 {
-			compatible = "fsl,ecm-law";
-			reg = <0x0 0x1000>;
-			fsl,num-laws = <12>;
-		};
-
-		ecm@1000 {
-			compatible = "fsl,p2020-ecm", "fsl,ecm";
-			reg = <0x1000 0x1000>;
-			interrupts = <17 2>;
-			interrupt-parent = <&mpic>;
-		};
-
-		memory-controller@2000 {
-			compatible = "fsl,p2020-memory-controller";
-			reg = <0x2000 0x1000>;
-			interrupt-parent = <&mpic>;
-			interrupts = <18 2>;
-		};
-
-		i2c@3000 {
-			#address-cells = <1>;
-			#size-cells = <0>;
-			cell-index = <0>;
-			compatible = "fsl-i2c";
-			reg = <0x3000 0x100>;
-			interrupts = <43 2>;
-			interrupt-parent = <&mpic>;
-			dfsrr;
-		};
-
-		i2c@3100 {
-			#address-cells = <1>;
-			#size-cells = <0>;
-			cell-index = <1>;
-			compatible = "fsl-i2c";
-			reg = <0x3100 0x100>;
-			interrupts = <43 2>;
-			interrupt-parent = <&mpic>;
-			dfsrr;
-		};
-
-		serial0: serial@4500 {
-			cell-index = <0>;
-			device_type = "serial";
-			compatible = "ns16550";
-			reg = <0x4500 0x100>;
-			clock-frequency = <0>;
-			interrupts = <42 2>;
-			interrupt-parent = <&mpic>;
-		};
-
-		serial1: serial@4600 {
-			cell-index = <1>;
-			device_type = "serial";
-			compatible = "ns16550";
-			reg = <0x4600 0x100>;
-			clock-frequency = <0>;
-			interrupts = <42 2>;
-			interrupt-parent = <&mpic>;
-		};
-
-		spi@7000 {
-			compatible = "fsl,espi";
-			reg = <0x7000 0x1000>;
-			interrupts = <59 0x2>;
-			interrupt-parent = <&mpic>;
+		usb@22000 {
+			phy_type = "ulpi";
 		};
 
-		dma@c300 {
-			#address-cells = <1>;
-			#size-cells = <1>;
-			compatible = "fsl,eloplus-dma";
-			reg = <0xc300 0x4>;
-			ranges = <0x0 0xc100 0x200>;
-			cell-index = <1>;
-			dma-channel@0 {
-				compatible = "fsl,eloplus-dma-channel";
-				reg = <0x0 0x80>;
-				cell-index = <0>;
+		mdio@24520 {
+			phy0: ethernet-phy@0 {
 				interrupt-parent = <&mpic>;
-				interrupts = <76 2>;
+				interrupts = <3 1>;
+				reg = <0x0>;
 			};
-			dma-channel@80 {
-				compatible = "fsl,eloplus-dma-channel";
-				reg = <0x80 0x80>;
-				cell-index = <1>;
+			phy1: ethernet-phy@1 {
 				interrupt-parent = <&mpic>;
-				interrupts = <77 2>;
+				interrupts = <3 1>;
+				reg = <0x1>;
 			};
-			dma-channel@100 {
-				compatible = "fsl,eloplus-dma-channel";
-				reg = <0x100 0x80>;
-				cell-index = <2>;
+			phy2: ethernet-phy@2 {
 				interrupt-parent = <&mpic>;
-				interrupts = <78 2>;
+				interrupts = <3 1>;
+				reg = <0x2>;
 			};
-			dma-channel@180 {
-				compatible = "fsl,eloplus-dma-channel";
-				reg = <0x180 0x80>;
-				cell-index = <3>;
-				interrupt-parent = <&mpic>;
-				interrupts = <79 2>;
+			tbi0: tbi-phy@11 {
+				reg = <0x11>;
+				device_type = "tbi-phy";
 			};
-		};
 
-		gpio: gpio-controller@f000 {
-			#gpio-cells = <2>;
-			compatible = "fsl,mpc8572-gpio";
-			reg = <0xf000 0x100>;
-			interrupts = <47 0x2>;
-			interrupt-parent = <&mpic>;
-			gpio-controller;
 		};
 
-		L2: l2-cache-controller@20000 {
-			compatible = "fsl,p2020-l2-cache-controller";
-			reg = <0x20000 0x1000>;
-			cache-line-size = <32>;	// 32 bytes
-			cache-size = <0x80000>; // L2, 512k
-			interrupt-parent = <&mpic>;
-			interrupts = <16 2>;
+		mdio@25520 {
+			tbi1: tbi-phy@11 {
+				reg = <0x11>;
+				device_type = "tbi-phy";
+			};
 		};
 
-		dma@21300 {
-			#address-cells = <1>;
-			#size-cells = <1>;
-			compatible = "fsl,eloplus-dma";
-			reg = <0x21300 0x4>;
-			ranges = <0x0 0x21100 0x200>;
-			cell-index = <0>;
-			dma-channel@0 {
-				compatible = "fsl,eloplus-dma-channel";
-				reg = <0x0 0x80>;
-				cell-index = <0>;
-				interrupt-parent = <&mpic>;
-				interrupts = <20 2>;
-			};
-			dma-channel@80 {
-				compatible = "fsl,eloplus-dma-channel";
-				reg = <0x80 0x80>;
-				cell-index = <1>;
-				interrupt-parent = <&mpic>;
-				interrupts = <21 2>;
-			};
-			dma-channel@100 {
-				compatible = "fsl,eloplus-dma-channel";
-				reg = <0x100 0x80>;
-				cell-index = <2>;
-				interrupt-parent = <&mpic>;
-				interrupts = <22 2>;
-			};
-			dma-channel@180 {
-				compatible = "fsl,eloplus-dma-channel";
-				reg = <0x180 0x80>;
-				cell-index = <3>;
-				interrupt-parent = <&mpic>;
-				interrupts = <23 2>;
+		mdio@26520 {
+			tbi2: tbi-phy@11 {
+				reg = <0x11>;
+				device_type = "tbi-phy";
 			};
+
 		};
 
-		usb@22000 {
-			#address-cells = <1>;
-			#size-cells = <0>;
-			compatible = "fsl-usb2-dr";
-			reg = <0x22000 0x1000>;
-			interrupt-parent = <&mpic>;
-			interrupts = <28 0x2>;
-			phy_type = "ulpi";
+		ptp_clock@24E00 {
+			compatible = "fsl,etsec-ptp";
+			reg = <0x24E00 0xB0>;
+			interrupts = <68 2 69 2 70 2>;
+			interrupt-parent = < &mpic >;
+			fsl,tclk-period = <5>;
+			fsl,tmr-prsc = <200>;
+			fsl,tmr-add = <0xCCCCCCCD>;
+			fsl,tmr-fiper1 = <0x3B9AC9FB>;
+			fsl,tmr-fiper2 = <0x0001869B>;
+			fsl,max-adj = <249999999>;
 		};
 
 		enet0: ethernet@24000 {
-			#address-cells = <1>;
-			#size-cells = <1>;
-			cell-index = <0>;
-			device_type = "network";
-			model = "eTSEC";
-			compatible = "gianfar";
-			reg = <0x24000 0x1000>;
-			ranges = <0x0 0x24000 0x1000>;
-			local-mac-address = [ 00 00 00 00 00 00 ];
-			interrupts = <29 2 30 2 34 2>;
-			interrupt-parent = <&mpic>;
 			tbi-handle = <&tbi0>;
 			phy-handle = <&phy0>;
 			phy-connection-type = "rgmii-id";
-
-			mdio@520 {
-				#address-cells = <1>;
-				#size-cells = <0>;
-				compatible = "fsl,gianfar-mdio";
-				reg = <0x520 0x20>;
-
-				phy0: ethernet-phy@0 {
-					interrupt-parent = <&mpic>;
-					interrupts = <3 1>;
-					reg = <0x0>;
-				};
-				phy1: ethernet-phy@1 {
-					interrupt-parent = <&mpic>;
-					interrupts = <3 1>;
-					reg = <0x1>;
-				};
-				phy2: ethernet-phy@2 {
-					interrupt-parent = <&mpic>;
-					interrupts = <3 1>;
-					reg = <0x2>;
-				};
-				tbi0: tbi-phy@11 {
-					reg = <0x11>;
-					device_type = "tbi-phy";
-				};
-			};
 		};
 
 		enet1: ethernet@25000 {
-			#address-cells = <1>;
-			#size-cells = <1>;
-			cell-index = <1>;
-			device_type = "network";
-			model = "eTSEC";
-			compatible = "gianfar";
-			reg = <0x25000 0x1000>;
-			ranges = <0x0 0x25000 0x1000>;
-			local-mac-address = [ 00 00 00 00 00 00 ];
-			interrupts = <35 2 36 2 40 2>;
-			interrupt-parent = <&mpic>;
 			tbi-handle = <&tbi1>;
 			phy-handle = <&phy1>;
 			phy-connection-type = "rgmii-id";
 
-			mdio@520 {
-				#address-cells = <1>;
-				#size-cells = <0>;
-				compatible = "fsl,gianfar-tbi";
-				reg = <0x520 0x20>;
-
-				tbi1: tbi-phy@11 {
-					reg = <0x11>;
-					device_type = "tbi-phy";
-				};
-			};
 		};
 
 		enet2: ethernet@26000 {
-			#address-cells = <1>;
-			#size-cells = <1>;
-			cell-index = <2>;
-			device_type = "network";
-			model = "eTSEC";
-			compatible = "gianfar";
-			reg = <0x26000 0x1000>;
-			ranges = <0x0 0x26000 0x1000>;
-			local-mac-address = [ 00 00 00 00 00 00 ];
-			interrupts = <31 2 32 2 33 2>;
-			interrupt-parent = <&mpic>;
 			tbi-handle = <&tbi2>;
 			phy-handle = <&phy2>;
 			phy-connection-type = "rgmii-id";
-
-			mdio@520 {
-				#address-cells = <1>;
-				#size-cells = <0>;
-				compatible = "fsl,gianfar-tbi";
-				reg = <0x520 0x20>;
-
-				tbi2: tbi-phy@11 {
-					reg = <0x11>;
-					device_type = "tbi-phy";
-				};
-			};
-		};
-
-		sdhci@2e000 {
-			compatible = "fsl,p2020-esdhc", "fsl,esdhc";
-			reg = <0x2e000 0x1000>;
-			interrupts = <72 0x2>;
-			interrupt-parent = <&mpic>;
-			/* Filled in by U-Boot */
-			clock-frequency = <0>;
-		};
-
-		crypto@30000 {
-			compatible = "fsl,sec3.1", "fsl,sec3.0", "fsl,sec2.4",
-				     "fsl,sec2.2", "fsl,sec2.1", "fsl,sec2.0";
-			reg = <0x30000 0x10000>;
-			interrupts = <45 2 58 2>;
-			interrupt-parent = <&mpic>;
-			fsl,num-channels = <4>;
-			fsl,channel-fifo-len = <24>;
-			fsl,exec-units-mask = <0xbfe>;
-			fsl,descriptor-types-mask = <0x3ab0ebf>;
 		};
 
-		mpic: pic@40000 {
-			interrupt-controller;
-			#address-cells = <0>;
-			#interrupt-cells = <2>;
-			reg = <0x40000 0x40000>;
-			compatible = "chrp,open-pic";
-			device_type = "open-pic";
-		};
 
 		msi@41600 {
 			compatible = "fsl,mpic-msi";
-			reg = <0x41600 0x80>;
-			msi-available-ranges = <0 0x100>;
-			interrupts = <
-				0xe0 0
-				0xe1 0
-				0xe2 0
-				0xe3 0
-				0xe4 0
-				0xe5 0
-				0xe6 0
-				0xe7 0>;
-			interrupt-parent = <&mpic>;
-		};
-
-		global-utilities@e0000 {	//global utilities block
-			compatible = "fsl,p2020-guts";
-			reg = <0xe0000 0x1000>;
-			fsl,has-rstcr;
 		};
 	};
 
 	pci0: pcie@ffe08000 {
-		compatible = "fsl,mpc8548-pcie";
-		device_type = "pci";
-		#interrupt-cells = <1>;
-		#size-cells = <2>;
-		#address-cells = <3>;
-		reg = <0 0xffe08000 0 0x1000>;
-		bus-range = <0 255>;
 		ranges = <0x2000000 0x0 0x80000000 0 0x80000000 0x0 0x20000000
 			  0x1000000 0x0 0x00000000 0 0xffc00000 0x0 0x10000>;
-		clock-frequency = <33333333>;
-		interrupt-parent = <&mpic>;
-		interrupts = <24 2>;
 		interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
 		interrupt-map = <
 			/* IDSEL 0x0 */
@@ -528,18 +243,8 @@
 	};
 
 	pci1: pcie@ffe09000 {
-		compatible = "fsl,mpc8548-pcie";
-		device_type = "pci";
-		#interrupt-cells = <1>;
-		#size-cells = <2>;
-		#address-cells = <3>;
-		reg = <0 0xffe09000 0 0x1000>;
-		bus-range = <0 255>;
 		ranges = <0x2000000 0x0 0xa0000000 0 0xa0000000 0x0 0x20000000
 			  0x1000000 0x0 0x00000000 0 0xffc10000 0x0 0x10000>;
-		clock-frequency = <33333333>;
-		interrupt-parent = <&mpic>;
-		interrupts = <25 2>;
 		interrupt-map-mask = <0xff00 0x0 0x0 0x7>;
 		interrupt-map = <
 
@@ -667,18 +372,8 @@
 	};
 
 	pci2: pcie@ffe0a000 {
-		compatible = "fsl,mpc8548-pcie";
-		device_type = "pci";
-		#interrupt-cells = <1>;
-		#size-cells = <2>;
-		#address-cells = <3>;
-		reg = <0 0xffe0a000 0 0x1000>;
-		bus-range = <0 255>;
 		ranges = <0x2000000 0x0 0xc0000000 0 0xc0000000 0x0 0x20000000
 			  0x1000000 0x0 0x00000000 0 0xffc20000 0x0 0x10000>;
-		clock-frequency = <33333333>;
-		interrupt-parent = <&mpic>;
-		interrupts = <26 2>;
 		interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
 		interrupt-map = <
 			/* IDSEL 0x0 */
diff -druN linux-2.6.39-libre/arch/powerpc/boot/dts/p2020rdb_camp_core0.dts linux-3.0-rc7-libre/arch/powerpc/boot/dts/p2020rdb_camp_core0.dts
--- linux-2.6.39-libre/arch/powerpc/boot/dts/p2020rdb_camp_core0.dts	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/boot/dts/p2020rdb_camp_core0.dts	2011-07-11 19:51:52.000000000 -0400
@@ -14,12 +14,11 @@
  * option) any later version.
  */
 
-/dts-v1/;
+/include/ "p2020si.dtsi"
+
 / {
-	model = "fsl,P2020";
+	model = "fsl,P2020RDB";
 	compatible = "fsl,P2020RDB", "fsl,MPC85XXRDB-CAMP";
-	#address-cells = <2>;
-	#size-cells = <2>;
 
 	aliases {
 		ethernet1 = &enet1;
@@ -29,91 +28,33 @@
 	};
 
 	cpus {
-		#address-cells = <1>;
-		#size-cells = <0>;
-
-		PowerPC,P2020@0 {
-			device_type = "cpu";
-			reg = <0x0>;
-			next-level-cache = <&L2>;
+		PowerPC,P2020@1 {
+		status = "disabled";
 		};
+
 	};
 
 	memory {
 		device_type = "memory";
 	};
 
-	soc@ffe00000 {
-		#address-cells = <1>;
-		#size-cells = <1>;
-		device_type = "soc";
-		compatible = "fsl,p2020-immr", "simple-bus";
-		ranges = <0x0  0x0 0xffe00000 0x100000>;
-		bus-frequency = <0>;		// Filled out by uboot.
-
-		ecm-law@0 {
-			compatible = "fsl,ecm-law";
-			reg = <0x0 0x1000>;
-			fsl,num-laws = <12>;
-		};
-
-		ecm@1000 {
-			compatible = "fsl,p2020-ecm", "fsl,ecm";
-			reg = <0x1000 0x1000>;
-			interrupts = <17 2>;
-			interrupt-parent = <&mpic>;
-		};
-
-		memory-controller@2000 {
-			compatible = "fsl,p2020-memory-controller";
-			reg = <0x2000 0x1000>;
-			interrupt-parent = <&mpic>;
-			interrupts = <18 2>;
-		};
+	localbus@ffe05000 {
+		status = "disabled";
+	};
 
+	soc@ffe00000 {
 		i2c@3000 {
-			#address-cells = <1>;
-			#size-cells = <0>;
-			cell-index = <0>;
-			compatible = "fsl-i2c";
-			reg = <0x3000 0x100>;
-			interrupts = <43 2>;
-			interrupt-parent = <&mpic>;
-			dfsrr;
 			rtc@68 {
 				compatible = "dallas,ds1339";
 				reg = <0x68>;
 			};
 		};
 
-		i2c@3100 {
-			#address-cells = <1>;
-			#size-cells = <0>;
-			cell-index = <1>;
-			compatible = "fsl-i2c";
-			reg = <0x3100 0x100>;
-			interrupts = <43 2>;
-			interrupt-parent = <&mpic>;
-			dfsrr;
-		};
-
-		serial0: serial@4500 {
-			cell-index = <0>;
-			device_type = "serial";
-			compatible = "ns16550";
-			reg = <0x4500 0x100>;
-			clock-frequency = <0>;
+		serial1: serial@4600 {
+			status = "disabled";
 		};
 
 		spi@7000 {
-			cell-index = <0>;
-			#address-cells = <1>;
-			#size-cells = <0>;
-			compatible = "fsl,espi";
-			reg = <0x7000 0x1000>;
-			interrupts = <59 0x2>;
-			interrupt-parent = <&mpic>;
-			mode = "cpu";
 
 			fsl_m25p80@0 {
 				#address-cells = <1>;
@@ -161,76 +102,15 @@
 			};
 		};
 
-		gpio: gpio-controller@f000 {
-			#gpio-cells = <2>;
-			compatible = "fsl,mpc8572-gpio";
-			reg = <0xf000 0x100>;
-			interrupts = <47 0x2>;
-			interrupt-parent = <&mpic>;
-			gpio-controller;
-		};
-
-		L2: l2-cache-controller@20000 {
-			compatible = "fsl,p2020-l2-cache-controller";
-			reg = <0x20000 0x1000>;
-			cache-line-size = <32>;	// 32 bytes
-			cache-size = <0x80000>; // L2,512K
-			interrupt-parent = <&mpic>;
-			interrupts = <16 2>;
-		};
-
-		dma@21300 {
-			#address-cells = <1>;
-			#size-cells = <1>;
-			compatible = "fsl,eloplus-dma";
-			reg = <0x21300 0x4>;
-			ranges = <0x0 0x21100 0x200>;
-			cell-index = <0>;
-			dma-channel@0 {
-				compatible = "fsl,eloplus-dma-channel";
-				reg = <0x0 0x80>;
-				cell-index = <0>;
-				interrupt-parent = <&mpic>;
-				interrupts = <20 2>;
-			};
-			dma-channel@80 {
-				compatible = "fsl,eloplus-dma-channel";
-				reg = <0x80 0x80>;
-				cell-index = <1>;
-				interrupt-parent = <&mpic>;
-				interrupts = <21 2>;
-			};
-			dma-channel@100 {
-				compatible = "fsl,eloplus-dma-channel";
-				reg = <0x100 0x80>;
-				cell-index = <2>;
-				interrupt-parent = <&mpic>;
-				interrupts = <22 2>;
-			};
-			dma-channel@180 {
-				compatible = "fsl,eloplus-dma-channel";
-				reg = <0x180 0x80>;
-				cell-index = <3>;
-				interrupt-parent = <&mpic>;
-				interrupts = <23 2>;
-			};
+		dma@c300 {
+			status = "disabled";
 		};
 
 		usb@22000 {
-			#address-cells = <1>;
-			#size-cells = <0>;
-			compatible = "fsl-usb2-dr";
-			reg = <0x22000 0x1000>;
-			interrupt-parent = <&mpic>;
-			interrupts = <28 0x2>;
 			phy_type = "ulpi";
 		};
 
 		mdio@24520 {
-			#address-cells = <1>;
-			#size-cells = <0>;
-			compatible = "fsl,gianfar-mdio";
-			reg = <0x24520 0x20>;
 
 			phy0: ethernet-phy@0 {
 				interrupt-parent = <&mpic>;
@@ -245,29 +125,21 @@
 		};
 
 		mdio@25520 {
-			#address-cells = <1>;
-			#size-cells = <0>;
-			compatible = "fsl,gianfar-tbi";
-			reg = <0x26520 0x20>;
-
 			tbi0: tbi-phy@11 {
 				reg = <0x11>;
 				device_type = "tbi-phy";
 			};
 		};
 
+		mdio@26520 {
+			status = "disabled";
+		};
+
+		enet0: ethernet@24000 {
+			status = "disabled";
+		};
+
 		enet1: ethernet@25000 {
-			#address-cells = <1>;
-			#size-cells = <1>;
-			cell-index = <1>;
-			device_type = "network";
-			model = "eTSEC";
-			compatible = "gianfar";
-			reg = <0x25000 0x1000>;
-			ranges = <0x0 0x25000 0x1000>;
-			local-mac-address = [ 00 00 00 00 00 00 ];
-			interrupts = <35 2 36 2 40 2>;
-			interrupt-parent = <&mpic>;
 			tbi-handle = <&tbi0>;
 			phy-handle = <&phy0>;
 			phy-connection-type = "sgmii";
@@ -275,49 +147,12 @@
 		};
 
 		enet2: ethernet@26000 {
-			#address-cells = <1>;
-			#size-cells = <1>;
-			cell-index = <2>;
-			device_type = "network";
-			model = "eTSEC";
-			compatible = "gianfar";
-			reg = <0x26000 0x1000>;
-			ranges = <0x0 0x26000 0x1000>;
-			local-mac-address = [ 00 00 00 00 00 00 ];
-			interrupts = <31 2 32 2 33 2>;
-			interrupt-parent = <&mpic>;
 			phy-handle = <&phy1>;
 			phy-connection-type = "rgmii-id";
 		};
 
-		sdhci@2e000 {
-			compatible = "fsl,p2020-esdhc", "fsl,esdhc";
-			reg = <0x2e000 0x1000>;
-			interrupts = <72 0x2>;
-			interrupt-parent = <&mpic>;
-			/* Filled in by U-Boot */
-			clock-frequency = <0>;
-		};
-
-		crypto@30000 {
-			compatible = "fsl,sec3.1", "fsl,sec3.0", "fsl,sec2.4",
-				     "fsl,sec2.2", "fsl,sec2.1", "fsl,sec2.0";
-			reg = <0x30000 0x10000>;
-			interrupts = <45 2 58 2>;
-			interrupt-parent = <&mpic>;
-			fsl,num-channels = <4>;
-			fsl,channel-fifo-len = <24>;
-			fsl,exec-units-mask = <0xbfe>;
-			fsl,descriptor-types-mask = <0x3ab0ebf>;
-		};
 
 		mpic: pic@40000 {
-			interrupt-controller;
-			#address-cells = <0>;
-			#interrupt-cells = <2>;
-			reg = <0x40000 0x40000>;
-			compatible = "chrp,open-pic";
-			device_type = "open-pic";
 			protected-sources = <
 			42 76 77 78 79 /* serial1 , dma2 */
 			29 30 34 26 /* enet0, pci1 */
@@ -326,26 +161,28 @@
 			>;
 		};
 
-		global-utilities@e0000 {
-			compatible = "fsl,p2020-guts";
-			reg = <0xe0000 0x1000>;
-			fsl,has-rstcr;
+		msi@41600 {
+			status = "disabled";
 		};
+
+
 	};
 
-	pci0: pcie@ffe09000 {
-		compatible = "fsl,mpc8548-pcie";
-		device_type = "pci";
-		#interrupt-cells = <1>;
-		#size-cells = <2>;
-		#address-cells = <3>;
-		reg = <0 0xffe09000 0 0x1000>;
-		bus-range = <0 255>;
+	pci0: pcie@ffe08000 {
+		status = "disabled";
+	};
+
+	pci1: pcie@ffe09000 {
 		ranges = <0x2000000 0x0 0xa0000000 0 0xa0000000 0x0 0x20000000
 			  0x1000000 0x0 0x00000000 0 0xffc10000 0x0 0x10000>;
-		clock-frequency = <33333333>;
-		interrupt-parent = <&mpic>;
-		interrupts = <25 2>;
+		interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
+		interrupt-map = <
+			/* IDSEL 0x0 */
+			0000 0x0 0x0 0x1 &mpic 0x4 0x1
+			0000 0x0 0x0 0x2 &mpic 0x5 0x1
+			0000 0x0 0x0 0x3 &mpic 0x6 0x1
+			0000 0x0 0x0 0x4 &mpic 0x7 0x1
+			>;
 		pcie@0 {
 			reg = <0x0 0x0 0x0 0x0 0x0>;
 			#size-cells = <2>;
@@ -360,4 +197,8 @@
 				  0x0 0x100000>;
 		};
 	};
+
+	pci2: pcie@ffe0a000 {
+		status = "disabled";
+	};
 };
diff -druN linux-2.6.39-libre/arch/powerpc/boot/dts/p2020rdb_camp_core1.dts linux-3.0-rc7-libre/arch/powerpc/boot/dts/p2020rdb_camp_core1.dts
--- linux-2.6.39-libre/arch/powerpc/boot/dts/p2020rdb_camp_core1.dts	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/boot/dts/p2020rdb_camp_core1.dts	2011-07-11 19:51:52.000000000 -0400
@@ -15,27 +15,21 @@
  * option) any later version.
  */
 
-/dts-v1/;
+/include/ "p2020si.dtsi"
+
 / {
-	model = "fsl,P2020";
+	model = "fsl,P2020RDB";
 	compatible = "fsl,P2020RDB", "fsl,MPC85XXRDB-CAMP";
-	#address-cells = <2>;
-	#size-cells = <2>;
 
 	aliases {
 		ethernet0 = &enet0;
-		serial0 = &serial0;
+		serial0 = &serial1;
 		pci1 = &pci1;
 	};
 
 	cpus {
-		#address-cells = <1>;
-		#size-cells = <0>;
-
-		PowerPC,P2020@1 {
-			device_type = "cpu";
-			reg = <0x1>;
-			next-level-cache = <&L2>;
+		PowerPC,P2020@0 {
+		status = "disabled";
 		};
 	};
 
@@ -43,20 +37,37 @@
 		device_type = "memory";
 	};
 
+	localbus@ffe05000 {
+		status = "disabled";
+	};
+
 	soc@ffe00000 {
-		#address-cells = <1>;
-		#size-cells = <1>;
-		device_type = "soc";
-		compatible = "fsl,p2020-immr", "simple-bus";
-		ranges = <0x0  0x0 0xffe00000 0x100000>;
-		bus-frequency = <0>;		// Filled out by uboot.
+		ecm-law@0 {
+			status = "disabled";
+		};
 
-		serial0: serial@4600 {
-			cell-index = <1>;
-			device_type = "serial";
-			compatible = "ns16550";
-			reg = <0x4600 0x100>;
-			clock-frequency = <0>;
+		ecm@1000 {
+			status = "disabled";
+		};
+
+		memory-controller@2000 {
+			status = "disabled";
+		};
+
+		i2c@3000 {
+			status = "disabled";
+		};
+
+		i2c@3100 {
+			status = "disabled";
+		};
+
+		serial0: serial@4500 {
+			status = "disabled";
+		};
+
+		spi@7000 {
+			status = "disabled";
 		};
 
 		dma@c300 {
@@ -96,6 +107,10 @@
 			};
 		};
 
+		gpio: gpio-controller@f000 {
+			status = "disabled";
+		};
+
 		L2: l2-cache-controller@20000 {
 			compatible = "fsl,p2020-l2-cache-controller";
 			reg = <0x20000 0x1000>;
@@ -104,31 +119,49 @@
 			interrupt-parent = <&mpic>;
 		};
 
+		dma@21300 {
+			status = "disabled";
+		};
+
+		usb@22000 {
+			status = "disabled";
+		};
+
+		mdio@24520 {
+			status = "disabled";
+		};
+
+		mdio@25520 {
+			status = "disabled";
+		};
+
+		mdio@26520 {
+			status = "disabled";
+		};
 
 		enet0: ethernet@24000 {
-			#address-cells = <1>;
-			#size-cells = <1>;
-			cell-index = <0>;
-			device_type = "network";
-			model = "eTSEC";
-			compatible = "gianfar";
-			reg = <0x24000 0x1000>;
-			ranges = <0x0 0x24000 0x1000>;
-			local-mac-address = [ 00 00 00 00 00 00 ];
-			interrupts = <29 2 30 2 34 2>;
-			interrupt-parent = <&mpic>;
 			fixed-link = <1 1 1000 0 0>;
 			phy-connection-type = "rgmii-id";
 
 		};
 
+		enet1: ethernet@25000 {
+			status = "disabled";
+		};
+
+		enet2: ethernet@26000 {
+			status = "disabled";
+		};
+
+		sdhci@2e000 {
+			status = "disabled";
+		};
+
+		crypto@30000 {
+			status = "disabled";
+		};
+
 		mpic: pic@40000 {
-			interrupt-controller;
-			#address-cells = <0>;
-			#interrupt-cells = <2>;
-			reg = <0x40000 0x40000>;
-			compatible = "chrp,open-pic";
-			device_type = "open-pic";
 			protected-sources = <
 			17 18 43 42 59 47 /*ecm, mem, i2c, serial0, spi,gpio */
 			16 20 21 22 23 28 	/* L2, dma1, USB */
@@ -152,21 +185,32 @@
 				0xe7 0>;
 			interrupt-parent = <&mpic>;
 		};
+
+		global-utilities@e0000 {	//global utilities block
+			status = "disabled";
+		};
+
 	};
 
-	pci1: pcie@ffe0a000 {
-		compatible = "fsl,mpc8548-pcie";
-		device_type = "pci";
-		#interrupt-cells = <1>;
-		#size-cells = <2>;
-		#address-cells = <3>;
-		reg = <0 0xffe0a000 0 0x1000>;
-		bus-range = <0 255>;
+	pci0: pcie@ffe08000 {
+		status = "disabled";
+	};
+
+	pci1: pcie@ffe09000 {
+		status = "disabled";
+	};
+
+	pci2: pcie@ffe0a000 {
 		ranges = <0x2000000 0x0 0x80000000 0 0x80000000 0x0 0x20000000
 			  0x1000000 0x0 0x00000000 0 0xffc00000 0x0 0x10000>;
-		clock-frequency = <33333333>;
-		interrupt-parent = <&mpic>;
-		interrupts = <26 2>;
+		interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
+		interrupt-map = <
+			/* IDSEL 0x0 */
+			0000 0x0 0x0 0x1 &mpic 0x0 0x1
+			0000 0x0 0x0 0x2 &mpic 0x1 0x1
+			0000 0x0 0x0 0x3 &mpic 0x2 0x1
+			0000 0x0 0x0 0x4 &mpic 0x3 0x1
+			>;
 		pcie@0 {
 			reg = <0x0 0x0 0x0 0x0 0x0>;
 			#size-cells = <2>;
diff -druN linux-2.6.39-libre/arch/powerpc/boot/dts/p2020rdb.dts linux-3.0-rc7-libre/arch/powerpc/boot/dts/p2020rdb.dts
--- linux-2.6.39-libre/arch/powerpc/boot/dts/p2020rdb.dts	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/boot/dts/p2020rdb.dts	2011-07-11 19:51:52.000000000 -0400
@@ -9,12 +9,11 @@
  * option) any later version.
  */
 
-/dts-v1/;
+/include/ "p2020si.dtsi"
+
 / {
-	model = "fsl,P2020";
+	model = "fsl,P2020RDB";
 	compatible = "fsl,P2020RDB";
-	#address-cells = <2>;
-	#size-cells = <2>;
 
 	aliases {
 		ethernet0 = &enet0;
@@ -26,34 +25,11 @@
 		pci1 = &pci1;
 	};
 
-	cpus {
-		#address-cells = <1>;
-		#size-cells = <0>;
-
-		PowerPC,P2020@0 {
-			device_type = "cpu";
-			reg = <0x0>;
-			next-level-cache = <&L2>;
-		};
-
-		PowerPC,P2020@1 {
-			device_type = "cpu";
-			reg = <0x1>;
-			next-level-cache = <&L2>;
-		};
-	};
-
 	memory {
 		device_type = "memory";
 	};
 
 	localbus@ffe05000 {
-		#address-cells = <2>;
-		#size-cells = <1>;
-		compatible = "fsl,p2020-elbc", "fsl,elbc", "simple-bus";
-		reg = <0 0xffe05000 0 0x1000>;
-		interrupts = <19 2>;
-		interrupt-parent = <&mpic>;
 
 		/* NOR and NAND Flashes */
 		ranges = <0x0 0x0 0x0 0xef000000 0x01000000
@@ -165,90 +141,16 @@
 	};
 
 	soc@ffe00000 {
-		#address-cells = <1>;
-		#size-cells = <1>;
-		device_type = "soc";
-		compatible = "fsl,p2020-immr", "simple-bus";
-		ranges = <0x0  0x0 0xffe00000 0x100000>;
-		bus-frequency = <0>;		// Filled out by uboot.
-
-		ecm-law@0 {
-			compatible = "fsl,ecm-law";
-			reg = <0x0 0x1000>;
-			fsl,num-laws = <12>;
-		};
-
-		ecm@1000 {
-			compatible = "fsl,p2020-ecm", "fsl,ecm";
-			reg = <0x1000 0x1000>;
-			interrupts = <17 2>;
-			interrupt-parent = <&mpic>;
-		};
-
-		memory-controller@2000 {
-			compatible = "fsl,p2020-memory-controller";
-			reg = <0x2000 0x1000>;
-			interrupt-parent = <&mpic>;
-			interrupts = <18 2>;
-		};
-
 		i2c@3000 {
-			#address-cells = <1>;
-			#size-cells = <0>;
-			cell-index = <0>;
-			compatible = "fsl-i2c";
-			reg = <0x3000 0x100>;
-			interrupts = <43 2>;
-			interrupt-parent = <&mpic>;
-			dfsrr;
 			rtc@68 {
 				compatible = "dallas,ds1339";
 				reg = <0x68>;
 			};
 		};
 
-		i2c@3100 {
-			#address-cells = <1>;
-			#size-cells = <0>;
-			cell-index = <1>;
-			compatible = "fsl-i2c";
-			reg = <0x3100 0x100>;
-			interrupts = <43 2>;
-			interrupt-parent = <&mpic>;
-			dfsrr;
-		};
-
-		serial0: serial@4500 {
-			cell-index = <0>;
-			device_type = "serial";
-			compatible = "ns16550";
-			reg = <0x4500 0x100>;
-			clock-frequency = <0>;
-			interrupts = <42 2>;
-			interrupt-parent = <&mpic>;
-		};
-
-		serial1: serial@4600 {
-			cell-index = <1>;
-			device_type = "serial";
-			compatible = "ns16550";
-			reg = <0x4600 0x100>;
-			clock-frequency = <0>;
-			interrupts = <42 2>;
-			interrupt-parent = <&mpic>;
-		};
-
-		spi@7000 {
-			cell-index = <0>;
-			#address-cells = <1>;
-			#size-cells = <0>;
-			compatible = "fsl,espi";
-			reg = <0x7000 0x1000>;
-			interrupts = <59 0x2>;
-			interrupt-parent = <&mpic>;
-			mode = "cpu";
+	spi@7000 {
 
-			fsl_m25p80@0 {
+		fsl_m25p80@0 {
 				#address-cells = <1>;
 				#size-cells = <1>;
 				compatible = "fsl,espi-flash";
@@ -294,254 +196,81 @@
 			};
 		};
 
-		dma@c300 {
-			#address-cells = <1>;
-			#size-cells = <1>;
-			compatible = "fsl,eloplus-dma";
-			reg = <0xc300 0x4>;
-			ranges = <0x0 0xc100 0x200>;
-			cell-index = <1>;
-			dma-channel@0 {
-				compatible = "fsl,eloplus-dma-channel";
-				reg = <0x0 0x80>;
-				cell-index = <0>;
-				interrupt-parent = <&mpic>;
-				interrupts = <76 2>;
-			};
-			dma-channel@80 {
-				compatible = "fsl,eloplus-dma-channel";
-				reg = <0x80 0x80>;
-				cell-index = <1>;
-				interrupt-parent = <&mpic>;
-				interrupts = <77 2>;
-			};
-			dma-channel@100 {
-				compatible = "fsl,eloplus-dma-channel";
-				reg = <0x100 0x80>;
-				cell-index = <2>;
-				interrupt-parent = <&mpic>;
-				interrupts = <78 2>;
-			};
-			dma-channel@180 {
-				compatible = "fsl,eloplus-dma-channel";
-				reg = <0x180 0x80>;
-				cell-index = <3>;
-				interrupt-parent = <&mpic>;
-				interrupts = <79 2>;
-			};
+		usb@22000 {
+			phy_type = "ulpi";
 		};
 
-		gpio: gpio-controller@f000 {
-			#gpio-cells = <2>;
-			compatible = "fsl,mpc8572-gpio";
-			reg = <0xf000 0x100>;
-			interrupts = <47 0x2>;
-			interrupt-parent = <&mpic>;
-			gpio-controller;
+		mdio@24520 {
+			phy0: ethernet-phy@0 {
+				interrupt-parent = <&mpic>;
+				interrupts = <3 1>;
+				reg = <0x0>;
+				};
+			phy1: ethernet-phy@1 {
+				interrupt-parent = <&mpic>;
+				interrupts = <3 1>;
+				reg = <0x1>;
+				};
 		};
 
-		L2: l2-cache-controller@20000 {
-			compatible = "fsl,p2020-l2-cache-controller";
-			reg = <0x20000 0x1000>;
-			cache-line-size = <32>;	// 32 bytes
-			cache-size = <0x80000>; // L2,512K
-			interrupt-parent = <&mpic>;
-			interrupts = <16 2>;
+		mdio@25520 {
+			tbi0: tbi-phy@11 {
+				reg = <0x11>;
+				device_type = "tbi-phy";
+			};
 		};
 
-		dma@21300 {
-			#address-cells = <1>;
-			#size-cells = <1>;
-			compatible = "fsl,eloplus-dma";
-			reg = <0x21300 0x4>;
-			ranges = <0x0 0x21100 0x200>;
-			cell-index = <0>;
-			dma-channel@0 {
-				compatible = "fsl,eloplus-dma-channel";
-				reg = <0x0 0x80>;
-				cell-index = <0>;
-				interrupt-parent = <&mpic>;
-				interrupts = <20 2>;
-			};
-			dma-channel@80 {
-				compatible = "fsl,eloplus-dma-channel";
-				reg = <0x80 0x80>;
-				cell-index = <1>;
-				interrupt-parent = <&mpic>;
-				interrupts = <21 2>;
-			};
-			dma-channel@100 {
-				compatible = "fsl,eloplus-dma-channel";
-				reg = <0x100 0x80>;
-				cell-index = <2>;
-				interrupt-parent = <&mpic>;
-				interrupts = <22 2>;
-			};
-			dma-channel@180 {
-				compatible = "fsl,eloplus-dma-channel";
-				reg = <0x180 0x80>;
-				cell-index = <3>;
-				interrupt-parent = <&mpic>;
-				interrupts = <23 2>;
-			};
+		mdio@26520 {
+			status = "disabled";
 		};
 
-		usb@22000 {
-			#address-cells = <1>;
-			#size-cells = <0>;
-			compatible = "fsl-usb2-dr";
-			reg = <0x22000 0x1000>;
-			interrupt-parent = <&mpic>;
-			interrupts = <28 0x2>;
-			phy_type = "ulpi";
+		ptp_clock@24E00 {
+			compatible = "fsl,etsec-ptp";
+			reg = <0x24E00 0xB0>;
+			interrupts = <68 2 69 2 70 2>;
+			interrupt-parent = < &mpic >;
+			fsl,tclk-period = <5>;
+			fsl,tmr-prsc = <200>;
+			fsl,tmr-add = <0xCCCCCCCD>;
+			fsl,tmr-fiper1 = <0x3B9AC9FB>;
+			fsl,tmr-fiper2 = <0x0001869B>;
+			fsl,max-adj = <249999999>;
 		};
 
 		enet0: ethernet@24000 {
-			#address-cells = <1>;
-			#size-cells = <1>;
-			cell-index = <0>;
-			device_type = "network";
-			model = "eTSEC";
-			compatible = "gianfar";
-			reg = <0x24000 0x1000>;
-			ranges = <0x0 0x24000 0x1000>;
-			local-mac-address = [ 00 00 00 00 00 00 ];
-			interrupts = <29 2 30 2 34 2>;
-			interrupt-parent = <&mpic>;
 			fixed-link = <1 1 1000 0 0>;
 			phy-connection-type = "rgmii-id";
-
-			mdio@520 {
-				#address-cells = <1>;
-				#size-cells = <0>;
-				compatible = "fsl,gianfar-mdio";
-				reg = <0x520 0x20>;
-
-				phy0: ethernet-phy@0 {
-					interrupt-parent = <&mpic>;
-					interrupts = <3 1>;
-					reg = <0x0>;
-				};
-				phy1: ethernet-phy@1 {
-					interrupt-parent = <&mpic>;
-					interrupts = <3 1>;
-					reg = <0x1>;
-				};
-			};
 		};
 
 		enet1: ethernet@25000 {
-			#address-cells = <1>;
-			#size-cells = <1>;
-			cell-index = <1>;
-			device_type = "network";
-			model = "eTSEC";
-			compatible = "gianfar";
-			reg = <0x25000 0x1000>;
-			ranges = <0x0 0x25000 0x1000>;
-			local-mac-address = [ 00 00 00 00 00 00 ];
-			interrupts = <35 2 36 2 40 2>;
-			interrupt-parent = <&mpic>;
 			tbi-handle = <&tbi0>;
 			phy-handle = <&phy0>;
 			phy-connection-type = "sgmii";
-
-			mdio@520 {
-				#address-cells = <1>;
-				#size-cells = <0>;
-				compatible = "fsl,gianfar-tbi";
-				reg = <0x520 0x20>;
-
-				tbi0: tbi-phy@11 {
-					reg = <0x11>;
-					device_type = "tbi-phy";
-				};
-			};
 		};
 
 		enet2: ethernet@26000 {
-			#address-cells = <1>;
-			#size-cells = <1>;
-			cell-index = <2>;
-			device_type = "network";
-			model = "eTSEC";
-			compatible = "gianfar";
-			reg = <0x26000 0x1000>;
-			ranges = <0x0 0x26000 0x1000>;
-			local-mac-address = [ 00 00 00 00 00 00 ];
-			interrupts = <31 2 32 2 33 2>;
-			interrupt-parent = <&mpic>;
 			phy-handle = <&phy1>;
 			phy-connection-type = "rgmii-id";
 		};
 
-		sdhci@2e000 {
-			compatible = "fsl,p2020-esdhc", "fsl,esdhc";
-			reg = <0x2e000 0x1000>;
-			interrupts = <72 0x2>;
-			interrupt-parent = <&mpic>;
-			/* Filled in by U-Boot */
-			clock-frequency = <0>;
-		};
-
-		crypto@30000 {
-			compatible = "fsl,sec3.1", "fsl,sec3.0", "fsl,sec2.4",
-				     "fsl,sec2.2", "fsl,sec2.1", "fsl,sec2.0";
-			reg = <0x30000 0x10000>;
-			interrupts = <45 2 58 2>;
-			interrupt-parent = <&mpic>;
-			fsl,num-channels = <4>;
-			fsl,channel-fifo-len = <24>;
-			fsl,exec-units-mask = <0xbfe>;
-			fsl,descriptor-types-mask = <0x3ab0ebf>;
-		};
-
-		mpic: pic@40000 {
-			interrupt-controller;
-			#address-cells = <0>;
-			#interrupt-cells = <2>;
-			reg = <0x40000 0x40000>;
-			compatible = "chrp,open-pic";
-			device_type = "open-pic";
-		};
-
-		msi@41600 {
-			compatible = "fsl,p2020-msi", "fsl,mpic-msi";
-			reg = <0x41600 0x80>;
-			msi-available-ranges = <0 0x100>;
-			interrupts = <
-				0xe0 0
-				0xe1 0
-				0xe2 0
-				0xe3 0
-				0xe4 0
-				0xe5 0
-				0xe6 0
-				0xe7 0>;
-			interrupt-parent = <&mpic>;
-		};
+	};
 
-		global-utilities@e0000 {	//global utilities block
-			compatible = "fsl,p2020-guts";
-			reg = <0xe0000 0x1000>;
-			fsl,has-rstcr;
-		};
+	pci0: pcie@ffe08000 {
+		status = "disabled";
 	};
 
-	pci0: pcie@ffe09000 {
-		compatible = "fsl,mpc8548-pcie";
-		device_type = "pci";
-		#interrupt-cells = <1>;
-		#size-cells = <2>;
-		#address-cells = <3>;
-		reg = <0 0xffe09000 0 0x1000>;
-		bus-range = <0 255>;
+	pci1: pcie@ffe09000 {
 		ranges = <0x2000000 0x0 0xa0000000 0 0xa0000000 0x0 0x20000000
 			  0x1000000 0x0 0x00000000 0 0xffc10000 0x0 0x10000>;
-		clock-frequency = <33333333>;
-		interrupt-parent = <&mpic>;
-		interrupts = <25 2>;
-		pcie@0 {
+		interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
+		interrupt-map = <
+			/* IDSEL 0x0 */
+			0000 0x0 0x0 0x1 &mpic 0x4 0x1
+			0000 0x0 0x0 0x2 &mpic 0x5 0x1
+			0000 0x0 0x0 0x3 &mpic 0x6 0x1
+			0000 0x0 0x0 0x4 &mpic 0x7 0x1
+			>;
+			pcie@0 {
 			reg = <0x0 0x0 0x0 0x0 0x0>;
 			#size-cells = <2>;
 			#address-cells = <3>;
@@ -556,19 +285,17 @@
 		};
 	};
 
-	pci1: pcie@ffe0a000 {
-		compatible = "fsl,mpc8548-pcie";
-		device_type = "pci";
-		#interrupt-cells = <1>;
-		#size-cells = <2>;
-		#address-cells = <3>;
-		reg = <0 0xffe0a000 0 0x1000>;
-		bus-range = <0 255>;
+	pci2: pcie@ffe0a000 {
 		ranges = <0x2000000 0x0 0x80000000 0 0x80000000 0x0 0x20000000
 			  0x1000000 0x0 0x00000000 0 0xffc00000 0x0 0x10000>;
-		clock-frequency = <33333333>;
-		interrupt-parent = <&mpic>;
-		interrupts = <26 2>;
+		interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
+		interrupt-map = <
+			/* IDSEL 0x0 */
+			0000 0x0 0x0 0x1 &mpic 0x0 0x1
+			0000 0x0 0x0 0x2 &mpic 0x1 0x1
+			0000 0x0 0x0 0x3 &mpic 0x2 0x1
+			0000 0x0 0x0 0x4 &mpic 0x3 0x1
+			>;
 		pcie@0 {
 			reg = <0x0 0x0 0x0 0x0 0x0>;
 			#size-cells = <2>;
diff -druN linux-2.6.39-libre/arch/powerpc/boot/dts/p2020si.dtsi linux-3.0-rc7-libre/arch/powerpc/boot/dts/p2020si.dtsi
--- linux-2.6.39-libre/arch/powerpc/boot/dts/p2020si.dtsi	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/powerpc/boot/dts/p2020si.dtsi	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,382 @@
+/*
+ * P2020 Device Tree Source
+ *
+ * Copyright 2011 Freescale Semiconductor Inc.
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+/dts-v1/;
+/ {
+	compatible = "fsl,P2020";
+	#address-cells = <2>;
+	#size-cells = <2>;
+
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		PowerPC,P2020@0 {
+			device_type = "cpu";
+			reg = <0x0>;
+			next-level-cache = <&L2>;
+		};
+
+		PowerPC,P2020@1 {
+			device_type = "cpu";
+			reg = <0x1>;
+			next-level-cache = <&L2>;
+		};
+	};
+
+	localbus@ffe05000 {
+		#address-cells = <2>;
+		#size-cells = <1>;
+		compatible = "fsl,p2020-elbc", "fsl,elbc", "simple-bus";
+		reg = <0 0xffe05000 0 0x1000>;
+		interrupts = <19 2>;
+		interrupt-parent = <&mpic>;
+	};
+
+	soc@ffe00000 {
+		#address-cells = <1>;
+		#size-cells = <1>;
+		device_type = "soc";
+		compatible = "fsl,p2020-immr", "simple-bus";
+		ranges = <0x0  0x0 0xffe00000 0x100000>;
+		bus-frequency = <0>;		// Filled out by uboot.
+
+		ecm-law@0 {
+			compatible = "fsl,ecm-law";
+			reg = <0x0 0x1000>;
+			fsl,num-laws = <12>;
+		};
+
+		ecm@1000 {
+			compatible = "fsl,p2020-ecm", "fsl,ecm";
+			reg = <0x1000 0x1000>;
+			interrupts = <17 2>;
+			interrupt-parent = <&mpic>;
+		};
+
+		memory-controller@2000 {
+			compatible = "fsl,p2020-memory-controller";
+			reg = <0x2000 0x1000>;
+			interrupt-parent = <&mpic>;
+			interrupts = <18 2>;
+		};
+
+		i2c@3000 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			cell-index = <0>;
+			compatible = "fsl-i2c";
+			reg = <0x3000 0x100>;
+			interrupts = <43 2>;
+			interrupt-parent = <&mpic>;
+			dfsrr;
+		};
+
+		i2c@3100 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			cell-index = <1>;
+			compatible = "fsl-i2c";
+			reg = <0x3100 0x100>;
+			interrupts = <43 2>;
+			interrupt-parent = <&mpic>;
+			dfsrr;
+		};
+
+		serial0: serial@4500 {
+			cell-index = <0>;
+			device_type = "serial";
+			compatible = "ns16550";
+			reg = <0x4500 0x100>;
+			clock-frequency = <0>;
+			interrupts = <42 2>;
+			interrupt-parent = <&mpic>;
+		};
+
+		serial1: serial@4600 {
+			cell-index = <1>;
+			device_type = "serial";
+			compatible = "ns16550";
+			reg = <0x4600 0x100>;
+			clock-frequency = <0>;
+			interrupts = <42 2>;
+			interrupt-parent = <&mpic>;
+		};
+
+		spi@7000 {
+			cell-index = <0>;
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "fsl,espi";
+			reg = <0x7000 0x1000>;
+			interrupts = <59 0x2>;
+			interrupt-parent = <&mpic>;
+			mode = "cpu";
+		};
+
+		dma@c300 {
+			#address-cells = <1>;
+			#size-cells = <1>;
+			compatible = "fsl,eloplus-dma";
+			reg = <0xc300 0x4>;
+			ranges = <0x0 0xc100 0x200>;
+			cell-index = <1>;
+			dma-channel@0 {
+				compatible = "fsl,eloplus-dma-channel";
+				reg = <0x0 0x80>;
+				cell-index = <0>;
+				interrupt-parent = <&mpic>;
+				interrupts = <76 2>;
+			};
+			dma-channel@80 {
+				compatible = "fsl,eloplus-dma-channel";
+				reg = <0x80 0x80>;
+				cell-index = <1>;
+				interrupt-parent = <&mpic>;
+				interrupts = <77 2>;
+			};
+			dma-channel@100 {
+				compatible = "fsl,eloplus-dma-channel";
+				reg = <0x100 0x80>;
+				cell-index = <2>;
+				interrupt-parent = <&mpic>;
+				interrupts = <78 2>;
+			};
+			dma-channel@180 {
+				compatible = "fsl,eloplus-dma-channel";
+				reg = <0x180 0x80>;
+				cell-index = <3>;
+				interrupt-parent = <&mpic>;
+				interrupts = <79 2>;
+			};
+		};
+
+		gpio: gpio-controller@f000 {
+			#gpio-cells = <2>;
+			compatible = "fsl,mpc8572-gpio";
+			reg = <0xf000 0x100>;
+			interrupts = <47 0x2>;
+			interrupt-parent = <&mpic>;
+			gpio-controller;
+		};
+
+		L2: l2-cache-controller@20000 {
+			compatible = "fsl,p2020-l2-cache-controller";
+			reg = <0x20000 0x1000>;
+			cache-line-size = <32>;	// 32 bytes
+			cache-size = <0x80000>; // L2,512K
+			interrupt-parent = <&mpic>;
+			interrupts = <16 2>;
+		};
+
+		dma@21300 {
+			#address-cells = <1>;
+			#size-cells = <1>;
+			compatible = "fsl,eloplus-dma";
+			reg = <0x21300 0x4>;
+			ranges = <0x0 0x21100 0x200>;
+			cell-index = <0>;
+			dma-channel@0 {
+				compatible = "fsl,eloplus-dma-channel";
+				reg = <0x0 0x80>;
+				cell-index = <0>;
+				interrupt-parent = <&mpic>;
+				interrupts = <20 2>;
+			};
+			dma-channel@80 {
+				compatible = "fsl,eloplus-dma-channel";
+				reg = <0x80 0x80>;
+				cell-index = <1>;
+				interrupt-parent = <&mpic>;
+				interrupts = <21 2>;
+			};
+			dma-channel@100 {
+				compatible = "fsl,eloplus-dma-channel";
+				reg = <0x100 0x80>;
+				cell-index = <2>;
+				interrupt-parent = <&mpic>;
+				interrupts = <22 2>;
+			};
+			dma-channel@180 {
+				compatible = "fsl,eloplus-dma-channel";
+				reg = <0x180 0x80>;
+				cell-index = <3>;
+				interrupt-parent = <&mpic>;
+				interrupts = <23 2>;
+			};
+		};
+
+		usb@22000 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "fsl-usb2-dr";
+			reg = <0x22000 0x1000>;
+			interrupt-parent = <&mpic>;
+			interrupts = <28 0x2>;
+		};
+
+		mdio@24520 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "fsl,gianfar-mdio";
+			reg = <0x24520 0x20>;
+		};
+
+		mdio@25520 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "fsl,gianfar-tbi";
+			reg = <0x26520 0x20>;
+		};
+
+		mdio@26520 {
+			#address-cells = <1>;
+			#size-cells = <0>;
+			compatible = "fsl,gianfar-tbi";
+			reg = <0x520 0x20>;
+		};
+
+		enet0: ethernet@24000 {
+			#address-cells = <1>;
+			#size-cells = <1>;
+			cell-index = <0>;
+			device_type = "network";
+			model = "eTSEC";
+			compatible = "gianfar";
+			reg = <0x24000 0x1000>;
+			ranges = <0x0 0x24000 0x1000>;
+			local-mac-address = [ 00 00 00 00 00 00 ];
+			interrupts = <29 2 30 2 34 2>;
+			interrupt-parent = <&mpic>;
+		};
+
+		enet1: ethernet@25000 {
+			#address-cells = <1>;
+			#size-cells = <1>;
+			cell-index = <1>;
+			device_type = "network";
+			model = "eTSEC";
+			compatible = "gianfar";
+			reg = <0x25000 0x1000>;
+			ranges = <0x0 0x25000 0x1000>;
+			local-mac-address = [ 00 00 00 00 00 00 ];
+			interrupts = <35 2 36 2 40 2>;
+			interrupt-parent = <&mpic>;
+
+		};
+
+		enet2: ethernet@26000 {
+			#address-cells = <1>;
+			#size-cells = <1>;
+			cell-index = <2>;
+			device_type = "network";
+			model = "eTSEC";
+			compatible = "gianfar";
+			reg = <0x26000 0x1000>;
+			ranges = <0x0 0x26000 0x1000>;
+			local-mac-address = [ 00 00 00 00 00 00 ];
+			interrupts = <31 2 32 2 33 2>;
+			interrupt-parent = <&mpic>;
+
+		};
+
+		sdhci@2e000 {
+			compatible = "fsl,p2020-esdhc", "fsl,esdhc";
+			reg = <0x2e000 0x1000>;
+			interrupts = <72 0x2>;
+			interrupt-parent = <&mpic>;
+			/* Filled in by U-Boot */
+			clock-frequency = <0>;
+		};
+
+		crypto@30000 {
+			compatible = "fsl,sec3.1", "fsl,sec3.0", "fsl,sec2.4",
+				     "fsl,sec2.2", "fsl,sec2.1", "fsl,sec2.0";
+			reg = <0x30000 0x10000>;
+			interrupts = <45 2 58 2>;
+			interrupt-parent = <&mpic>;
+			fsl,num-channels = <4>;
+			fsl,channel-fifo-len = <24>;
+			fsl,exec-units-mask = <0xbfe>;
+			fsl,descriptor-types-mask = <0x3ab0ebf>;
+		};
+
+		mpic: pic@40000 {
+			interrupt-controller;
+			#address-cells = <0>;
+			#interrupt-cells = <2>;
+			reg = <0x40000 0x40000>;
+			compatible = "chrp,open-pic";
+			device_type = "open-pic";
+		};
+
+		msi@41600 {
+			compatible = "fsl,p2020-msi", "fsl,mpic-msi";
+			reg = <0x41600 0x80>;
+			msi-available-ranges = <0 0x100>;
+			interrupts = <
+				0xe0 0
+				0xe1 0
+				0xe2 0
+				0xe3 0
+				0xe4 0
+				0xe5 0
+				0xe6 0
+				0xe7 0>;
+			interrupt-parent = <&mpic>;
+		};
+
+		global-utilities@e0000 {	//global utilities block
+			compatible = "fsl,p2020-guts";
+			reg = <0xe0000 0x1000>;
+			fsl,has-rstcr;
+		};
+	};
+
+	pci0: pcie@ffe08000 {
+		compatible = "fsl,mpc8548-pcie";
+		device_type = "pci";
+		#interrupt-cells = <1>;
+		#size-cells = <2>;
+		#address-cells = <3>;
+		reg = <0 0xffe08000 0 0x1000>;
+		bus-range = <0 255>;
+		clock-frequency = <33333333>;
+		interrupt-parent = <&mpic>;
+		interrupts = <24 2>;
+	};
+
+	pci1: pcie@ffe09000 {
+		compatible = "fsl,mpc8548-pcie";
+		device_type = "pci";
+		#interrupt-cells = <1>;
+		#size-cells = <2>;
+		#address-cells = <3>;
+		reg = <0 0xffe09000 0 0x1000>;
+		bus-range = <0 255>;
+		clock-frequency = <33333333>;
+		interrupt-parent = <&mpic>;
+		interrupts = <25 2>;
+	};
+
+	pci2: pcie@ffe0a000 {
+		compatible = "fsl,mpc8548-pcie";
+		device_type = "pci";
+		#interrupt-cells = <1>;
+		#size-cells = <2>;
+		#address-cells = <3>;
+		reg = <0 0xffe0a000 0 0x1000>;
+		bus-range = <0 255>;
+		clock-frequency = <33333333>;
+		interrupt-parent = <&mpic>;
+		interrupts = <26 2>;
+	};
+};
diff -druN linux-2.6.39-libre/arch/powerpc/boot/dts/p4080ds.dts linux-3.0-rc7-libre/arch/powerpc/boot/dts/p4080ds.dts
--- linux-2.6.39-libre/arch/powerpc/boot/dts/p4080ds.dts	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/boot/dts/p4080ds.dts	2011-07-11 19:51:52.000000000 -0400
@@ -1,7 +1,7 @@
 /*
  * P4080DS Device Tree Source
  *
- * Copyright 2009 Freescale Semiconductor Inc.
+ * Copyright 2009-2011 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
@@ -33,6 +33,17 @@
 		dma1 = &dma1;
 		sdhc = &sdhc;
 
+		crypto = &crypto;
+		sec_jr0 = &sec_jr0;
+		sec_jr1 = &sec_jr1;
+		sec_jr2 = &sec_jr2;
+		sec_jr3 = &sec_jr3;
+		rtic_a = &rtic_a;
+		rtic_b = &rtic_b;
+		rtic_c = &rtic_c;
+		rtic_d = &rtic_d;
+		sec_mon = &sec_mon;
+
 		rio0 = &rapidio0;
 	};
 
@@ -410,6 +421,79 @@
 			dr_mode = "host";
 			phy_type = "ulpi";
 		};
+
+		crypto: crypto@300000 {
+			compatible = "fsl,sec-v4.0";
+			#address-cells = <1>;
+			#size-cells = <1>;
+			reg = <0x300000 0x10000>;
+			ranges = <0 0x300000 0x10000>;
+			interrupt-parent = <&mpic>;
+			interrupts = <92 2>;
+
+			sec_jr0: jr@1000 {
+				compatible = "fsl,sec-v4.0-job-ring";
+				reg = <0x1000 0x1000>;
+				interrupt-parent = <&mpic>;
+				interrupts = <88 2>;
+			};
+
+			sec_jr1: jr@2000 {
+				compatible = "fsl,sec-v4.0-job-ring";
+				reg = <0x2000 0x1000>;
+				interrupt-parent = <&mpic>;
+				interrupts = <89 2>;
+			};
+
+			sec_jr2: jr@3000 {
+				compatible = "fsl,sec-v4.0-job-ring";
+				reg = <0x3000 0x1000>;
+				interrupt-parent = <&mpic>;
+				interrupts = <90 2>;
+			};
+
+			sec_jr3: jr@4000 {
+				compatible = "fsl,sec-v4.0-job-ring";
+				reg = <0x4000 0x1000>;
+				interrupt-parent = <&mpic>;
+				interrupts = <91 2>;
+			};
+
+			rtic@6000 {
+				compatible = "fsl,sec-v4.0-rtic";
+				#address-cells = <1>;
+				#size-cells = <1>;
+				reg = <0x6000 0x100>;
+				ranges = <0x0 0x6100 0xe00>;
+
+				rtic_a: rtic-a@0 {
+					compatible = "fsl,sec-v4.0-rtic-memory";
+					reg = <0x00 0x20 0x100 0x80>;
+				};
+
+				rtic_b: rtic-b@20 {
+					compatible = "fsl,sec-v4.0-rtic-memory";
+					reg = <0x20 0x20 0x200 0x80>;
+				};
+
+				rtic_c: rtic-c@40 {
+					compatible = "fsl,sec-v4.0-rtic-memory";
+					reg = <0x40 0x20 0x300 0x80>;
+				};
+
+				rtic_d: rtic-d@60 {
+					compatible = "fsl,sec-v4.0-rtic-memory";
+					reg = <0x60 0x20 0x500 0x80>;
+				};
+			};
+		};
+
+		sec_mon: sec_mon@314000 {
+			compatible = "fsl,sec-v4.0-mon";
+			reg = <0x314000 0x1000>;
+			interrupt-parent = <&mpic>;
+			interrupts = <93 2>;
+		};
 	};
 
 	rapidio0: rapidio@ffe0c0000 {
diff -druN linux-2.6.39-libre/arch/powerpc/boot/dts/redwood.dts linux-3.0-rc7-libre/arch/powerpc/boot/dts/redwood.dts
--- linux-2.6.39-libre/arch/powerpc/boot/dts/redwood.dts	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/boot/dts/redwood.dts	2011-07-11 19:51:52.000000000 -0400
@@ -358,8 +358,28 @@
 				0x0 0x0 0x0 0x4 &UIC3 0xb 0x4 /* swizzled int D */>;
 		};
 
+		MSI: ppc4xx-msi@400300000 {
+				compatible = "amcc,ppc4xx-msi", "ppc4xx-msi";
+				reg = < 0x4 0x00300000 0x100
+					0x4 0x00300000 0x100>;
+				sdr-base = <0x3B0>;
+				msi-data = <0x00000000>;
+				msi-mask = <0x44440000>;
+				interrupt-count = <3>;
+				interrupts =<0 1 2 3>;
+				interrupt-parent = <&UIC0>;
+				#interrupt-cells = <1>;
+				#address-cells = <0>;
+				#size-cells = <0>;
+				interrupt-map = <0 &UIC0 0xC 1
+					1 &UIC0 0x0D 1
+					2 &UIC0 0x0E 1
+					3 &UIC0 0x0F 1>;
+		};
+
 	};
 
+
 	chosen {
 		linux,stdout-path = "/plb/opb/serial@ef600200";
 	};
diff -druN linux-2.6.39-libre/arch/powerpc/boot/epapr.c linux-3.0-rc7-libre/arch/powerpc/boot/epapr.c
--- linux-2.6.39-libre/arch/powerpc/boot/epapr.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/powerpc/boot/epapr.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,66 @@
+/*
+ * Bootwrapper for ePAPR compliant firmwares
+ *
+ * Copyright 2010 David Gibson <david@gibson.dropbear.id.au>, IBM Corporation.
+ *
+ * Based on earlier bootwrappers by:
+ * (c) Benjamin Herrenschmidt <benh@kernel.crashing.org>, IBM Corp,\
+ *   and
+ * Scott Wood <scottwood@freescale.com>
+ * Copyright (c) 2007 Freescale Semiconductor, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ */
+
+#include "ops.h"
+#include "stdio.h"
+#include "io.h"
+#include <libfdt.h>
+
+BSS_STACK(4096);
+
+#define EPAPR_SMAGIC	0x65504150
+#define EPAPR_EMAGIC	0x45504150
+
+static unsigned epapr_magic;
+static unsigned long ima_size;
+static unsigned long fdt_addr;
+
+static void platform_fixups(void)
+{
+	if ((epapr_magic != EPAPR_EMAGIC)
+	    && (epapr_magic != EPAPR_SMAGIC))
+		fatal("r6 contained 0x%08x instead of ePAPR magic number\n",
+		      epapr_magic);
+
+	if (ima_size < (unsigned long)_end)
+		printf("WARNING: Image loaded outside IMA!"
+		       " (_end=%p, ima_size=0x%lx)\n", _end, ima_size);
+	if (ima_size < fdt_addr)
+		printf("WARNING: Device tree address is outside IMA!"
+		       "(fdt_addr=0x%lx, ima_size=0x%lx)\n", fdt_addr,
+		       ima_size);
+	if (ima_size < fdt_addr + fdt_totalsize((void *)fdt_addr))
+		printf("WARNING: Device tree extends outside IMA!"
+		       " (fdt_addr=0x%lx, size=0x%x, ima_size=0x%lx\n",
+		       fdt_addr, fdt_totalsize((void *)fdt_addr), ima_size);
+}
+
+void platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
+		   unsigned long r6, unsigned long r7)
+{
+	epapr_magic = r6;
+	ima_size = r7;
+	fdt_addr = r3;
+
+	/* FIXME: we should process reserve entries */
+
+	simple_alloc_init(_end, ima_size - (unsigned long)_end, 32, 64);
+
+	fdt_init((void *)fdt_addr);
+
+	serial_console_init();
+	platform_ops.fixups = platform_fixups;
+}
diff -druN linux-2.6.39-libre/arch/powerpc/boot/.gitignore linux-3.0-rc7-libre/arch/powerpc/boot/.gitignore
--- linux-2.6.39-libre/arch/powerpc/boot/.gitignore	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/boot/.gitignore	2011-07-11 19:51:52.000000000 -0400
@@ -1,5 +1,4 @@
 addnote
-dtc
 empty.c
 hack-coff
 infblock.c
diff -druN linux-2.6.39-libre/arch/powerpc/boot/Makefile linux-3.0-rc7-libre/arch/powerpc/boot/Makefile
--- linux-2.6.39-libre/arch/powerpc/boot/Makefile	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/boot/Makefile	2011-07-11 19:51:52.000000000 -0400
@@ -69,7 +69,8 @@
 		cpm-serial.c stdlib.c mpc52xx-psc.c planetcore.c uartlite.c \
 		fsl-soc.c mpc8xx.c pq2.c ugecon.c
 src-plat := of.c cuboot-52xx.c cuboot-824x.c cuboot-83xx.c cuboot-85xx.c holly.c \
-		cuboot-ebony.c cuboot-hotfoot.c treeboot-ebony.c prpmc2800.c \
+		cuboot-ebony.c cuboot-hotfoot.c epapr.c treeboot-ebony.c \
+		prpmc2800.c \
 		ps3-head.S ps3-hvcall.S ps3.c treeboot-bamboo.c cuboot-8xx.c \
 		cuboot-pq2.c cuboot-sequoia.c treeboot-walnut.c \
 		cuboot-bamboo.c cuboot-mpc7448hpc2.c cuboot-taishan.c \
@@ -127,7 +128,7 @@
       cmd_bootas = $(CROSS32CC) -Wp,-MD,$(depfile) $(BOOTAFLAGS) -c -o $@ $<
 
 quiet_cmd_bootar = BOOTAR  $@
-      cmd_bootar = $(CROSS32AR) -cr $@.$$$$ $(filter-out FORCE,$^); mv $@.$$$$ $@
+      cmd_bootar = $(CROSS32AR) -cr$(KBUILD_ARFLAGS) $@.$$$$ $(filter-out FORCE,$^); mv $@.$$$$ $@
 
 $(obj-libfdt): $(obj)/%.o: $(srctree)/scripts/dtc/libfdt/%.c FORCE
 	$(call if_changed_dep,bootcc)
@@ -182,6 +183,7 @@
 image-$(CONFIG_PPC_PRPMC2800)		+= dtbImage.prpmc2800
 image-$(CONFIG_PPC_ISERIES)		+= zImage.iseries
 image-$(CONFIG_DEFAULT_UIMAGE)		+= uImage
+image-$(CONFIG_EPAPR_BOOT)		+= zImage.epapr
 
 #
 # Targets which embed a device tree blob
diff -druN linux-2.6.39-libre/arch/powerpc/boot/wrapper linux-3.0-rc7-libre/arch/powerpc/boot/wrapper
--- linux-2.6.39-libre/arch/powerpc/boot/wrapper	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/boot/wrapper	2011-07-11 19:51:52.000000000 -0400
@@ -39,6 +39,7 @@
 cacheit=
 binary=
 gzip=.gz
+pie=
 
 # cross-compilation prefix
 CROSS=
@@ -157,9 +158,10 @@
     platformo=$object/of.o
     ;;
 coff)
-    platformo=$object/of.o
+    platformo="$object/crt0.o $object/of.o"
     lds=$object/zImage.coff.lds
     link_address='0x500000'
+    pie=
     ;;
 miboot|uboot)
     # miboot and U-boot want just the bare bits, not an ELF binary
@@ -208,6 +210,7 @@
     ksection=.kernel:vmlinux.bin
     isection=.kernel:initrd
     link_address=''
+    pie=
     ;;
 ep88xc|ep405|ep8248e)
     platformo="$object/fixed-head.o $object/$platform.o"
@@ -244,6 +247,10 @@
 treeboot-iss4xx-mpic)
     platformo="$object/treeboot-iss4xx.o"
     ;;
+epapr)
+    link_address='0x20000000'
+    pie=-pie
+    ;;
 esac
 
 vmz="$tmpdir/`basename \"$kernel\"`.$ext"
@@ -251,7 +258,7 @@
     ${CROSS}objcopy $objflags "$kernel" "$vmz.$$"
 
     if [ -n "$gzip" ]; then
-        gzip -f -9 "$vmz.$$"
+        gzip -n -f -9 "$vmz.$$"
     fi
 
     if [ -n "$cacheit" ]; then
@@ -310,9 +317,9 @@
 
 if [ "$platform" != "miboot" ]; then
     if [ -n "$link_address" ] ; then
-        text_start="-Ttext $link_address --defsym _start=$link_address"
+        text_start="-Ttext $link_address"
     fi
-    ${CROSS}ld -m elf32ppc -T $lds $text_start -o "$ofile" \
+    ${CROSS}ld -m elf32ppc -T $lds $text_start $pie -o "$ofile" \
 	$platformo $tmp $object/wrapper.a
     rm $tmp
 fi
@@ -336,7 +343,7 @@
     $objbin/hack-coff "$ofile"
     ;;
 cuboot*)
-    gzip -f -9 "$ofile"
+    gzip -n -f -9 "$ofile"
     ${MKIMAGE} -A ppc -O linux -T kernel -C gzip -a "$base" -e "$entry" \
             $uboot_version -d "$ofile".gz "$ofile"
     ;;
@@ -383,6 +390,6 @@
 
     odir="$(dirname "$ofile.bin")"
     rm -f "$odir/otheros.bld"
-    gzip --force -9 --stdout "$ofile.bin" > "$odir/otheros.bld"
+    gzip -n --force -9 --stdout "$ofile.bin" > "$odir/otheros.bld"
     ;;
 esac
diff -druN linux-2.6.39-libre/arch/powerpc/boot/zImage.coff.lds.S linux-3.0-rc7-libre/arch/powerpc/boot/zImage.coff.lds.S
--- linux-2.6.39-libre/arch/powerpc/boot/zImage.coff.lds.S	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/boot/zImage.coff.lds.S	2011-07-11 19:51:52.000000000 -0400
@@ -3,13 +3,13 @@
 EXTERN(_zimage_start_opd)
 SECTIONS
 {
-  _start = .;
   .text      :
   {
+    _start = .;
     *(.text)
     *(.fixup)
+    _etext = .;
   }
-  _etext = .;
   . = ALIGN(4096);
   .data    :
   {
@@ -17,9 +17,7 @@
     *(.data*)
     *(__builtin_*)
     *(.sdata*)
-    __got2_start = .;
     *(.got2)
-    __got2_end = .;
 
     _dtb_start = .;
     *(.kernel:dtb)
diff -druN linux-2.6.39-libre/arch/powerpc/boot/zImage.lds.S linux-3.0-rc7-libre/arch/powerpc/boot/zImage.lds.S
--- linux-2.6.39-libre/arch/powerpc/boot/zImage.lds.S	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/boot/zImage.lds.S	2011-07-11 19:51:52.000000000 -0400
@@ -3,49 +3,64 @@
 EXTERN(_zimage_start)
 SECTIONS
 {
-  _start = .;
   .text      :
   {
+    _start = .;
     *(.text)
     *(.fixup)
+    _etext = .;
   }
-  _etext = .;
   . = ALIGN(4096);
   .data    :
   {
     *(.rodata*)
     *(.data*)
     *(.sdata*)
-    __got2_start = .;
     *(.got2)
-    __got2_end = .;
   }
+  .dynsym : { *(.dynsym) }
+  .dynstr : { *(.dynstr) }
+  .dynamic :
+  {
+    __dynamic_start = .;
+    *(.dynamic)
+  }
+  .hash : { *(.hash) }
+  .interp : { *(.interp) }
+  .rela.dyn : { *(.rela*) }
 
   . = ALIGN(8);
-  _dtb_start = .;
-  .kernel:dtb : { *(.kernel:dtb) }
-  _dtb_end = .;
-
-  . = ALIGN(4096);
-  _vmlinux_start =  .;
-  .kernel:vmlinux.strip : { *(.kernel:vmlinux.strip) }
-  _vmlinux_end =  .;
+  .kernel:dtb :
+  {
+    _dtb_start = .;
+    *(.kernel:dtb)
+    _dtb_end = .;
+  }
 
   . = ALIGN(4096);
-  _initrd_start =  .;
-  .kernel:initrd : { *(.kernel:initrd) }
-  _initrd_end =  .;
+  .kernel:vmlinux.strip :
+  {
+    _vmlinux_start =  .;
+    *(.kernel:vmlinux.strip)
+    _vmlinux_end =  .;
+  }
 
   . = ALIGN(4096);
-  _edata  =  .;
+  .kernel:initrd :
+  {
+    _initrd_start =  .;
+    *(.kernel:initrd)
+    _initrd_end =  .;
+  }
 
   . = ALIGN(4096);
-  __bss_start = .;
   .bss       :
   {
-   *(.sbss)
-   *(.bss)
+    _edata  =  .;
+    __bss_start = .;
+    *(.sbss)
+    *(.bss)
+    *(COMMON)
+    _end = . ;
   }
-  . = ALIGN(4096);
-  _end = . ;
 }
diff -druN linux-2.6.39-libre/arch/powerpc/configs/52xx/pcm030_defconfig linux-3.0-rc7-libre/arch/powerpc/configs/52xx/pcm030_defconfig
--- linux-2.6.39-libre/arch/powerpc/configs/52xx/pcm030_defconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/configs/52xx/pcm030_defconfig	2011-07-11 19:51:52.000000000 -0400
@@ -85,7 +85,7 @@
 CONFIG_USB_OHCI_HCD_PPC_OF_BE=y
 # CONFIG_USB_OHCI_HCD_PCI is not set
 CONFIG_USB_STORAGE=m
-CONFIG_RTC_CLASS=m
+CONFIG_RTC_CLASS=y
 CONFIG_RTC_DRV_PCF8563=m
 CONFIG_EXT2_FS=m
 CONFIG_EXT3_FS=m
diff -druN linux-2.6.39-libre/arch/powerpc/configs/83xx/mpc8313_rdb_defconfig linux-3.0-rc7-libre/arch/powerpc/configs/83xx/mpc8313_rdb_defconfig
--- linux-2.6.39-libre/arch/powerpc/configs/83xx/mpc8313_rdb_defconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/configs/83xx/mpc8313_rdb_defconfig	2011-07-11 19:51:52.000000000 -0400
@@ -104,7 +104,6 @@
 CONFIG_PARTITION_ADVANCED=y
 CONFIG_DEBUG_KERNEL=y
 CONFIG_DETECT_HUNG_TASK=y
-# CONFIG_DEBUG_BUGVERBOSE is not set
 # CONFIG_RCU_CPU_STALL_DETECTOR is not set
 CONFIG_SYSCTL_SYSCALL_CHECK=y
 CONFIG_CRYPTO_PCBC=m
diff -druN linux-2.6.39-libre/arch/powerpc/configs/83xx/mpc8315_rdb_defconfig linux-3.0-rc7-libre/arch/powerpc/configs/83xx/mpc8315_rdb_defconfig
--- linux-2.6.39-libre/arch/powerpc/configs/83xx/mpc8315_rdb_defconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/configs/83xx/mpc8315_rdb_defconfig	2011-07-11 19:51:52.000000000 -0400
@@ -101,7 +101,6 @@
 CONFIG_PARTITION_ADVANCED=y
 CONFIG_DEBUG_KERNEL=y
 CONFIG_DETECT_HUNG_TASK=y
-# CONFIG_DEBUG_BUGVERBOSE is not set
 # CONFIG_RCU_CPU_STALL_DETECTOR is not set
 CONFIG_SYSCTL_SYSCALL_CHECK=y
 CONFIG_CRYPTO_PCBC=m
diff -druN linux-2.6.39-libre/arch/powerpc/configs/85xx/mpc8540_ads_defconfig linux-3.0-rc7-libre/arch/powerpc/configs/85xx/mpc8540_ads_defconfig
--- linux-2.6.39-libre/arch/powerpc/configs/85xx/mpc8540_ads_defconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/configs/85xx/mpc8540_ads_defconfig	2011-07-11 19:51:52.000000000 -0400
@@ -58,7 +58,6 @@
 CONFIG_DEBUG_KERNEL=y
 CONFIG_DETECT_HUNG_TASK=y
 CONFIG_DEBUG_MUTEXES=y
-# CONFIG_DEBUG_BUGVERBOSE is not set
 # CONFIG_RCU_CPU_STALL_DETECTOR is not set
 CONFIG_SYSCTL_SYSCALL_CHECK=y
 # CONFIG_CRYPTO_ANSI_CPRNG is not set
diff -druN linux-2.6.39-libre/arch/powerpc/configs/85xx/mpc8560_ads_defconfig linux-3.0-rc7-libre/arch/powerpc/configs/85xx/mpc8560_ads_defconfig
--- linux-2.6.39-libre/arch/powerpc/configs/85xx/mpc8560_ads_defconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/configs/85xx/mpc8560_ads_defconfig	2011-07-11 19:51:52.000000000 -0400
@@ -59,7 +59,6 @@
 CONFIG_DEBUG_KERNEL=y
 CONFIG_DETECT_HUNG_TASK=y
 CONFIG_DEBUG_MUTEXES=y
-# CONFIG_DEBUG_BUGVERBOSE is not set
 # CONFIG_RCU_CPU_STALL_DETECTOR is not set
 CONFIG_SYSCTL_SYSCALL_CHECK=y
 # CONFIG_CRYPTO_ANSI_CPRNG is not set
diff -druN linux-2.6.39-libre/arch/powerpc/configs/85xx/mpc85xx_cds_defconfig linux-3.0-rc7-libre/arch/powerpc/configs/85xx/mpc85xx_cds_defconfig
--- linux-2.6.39-libre/arch/powerpc/configs/85xx/mpc85xx_cds_defconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/configs/85xx/mpc85xx_cds_defconfig	2011-07-11 19:51:52.000000000 -0400
@@ -63,7 +63,6 @@
 CONFIG_DEBUG_KERNEL=y
 CONFIG_DETECT_HUNG_TASK=y
 CONFIG_DEBUG_MUTEXES=y
-# CONFIG_DEBUG_BUGVERBOSE is not set
 # CONFIG_RCU_CPU_STALL_DETECTOR is not set
 CONFIG_SYSCTL_SYSCALL_CHECK=y
 # CONFIG_CRYPTO_ANSI_CPRNG is not set
diff -druN linux-2.6.39-libre/arch/powerpc/configs/86xx/mpc8641_hpcn_defconfig linux-3.0-rc7-libre/arch/powerpc/configs/86xx/mpc8641_hpcn_defconfig
--- linux-2.6.39-libre/arch/powerpc/configs/86xx/mpc8641_hpcn_defconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/configs/86xx/mpc8641_hpcn_defconfig	2011-07-11 19:51:52.000000000 -0400
@@ -168,7 +168,6 @@
 CONFIG_CRC_T10DIF=y
 CONFIG_DEBUG_KERNEL=y
 CONFIG_DETECT_HUNG_TASK=y
-# CONFIG_DEBUG_BUGVERBOSE is not set
 CONFIG_DEBUG_INFO=y
 # CONFIG_RCU_CPU_STALL_DETECTOR is not set
 CONFIG_SYSCTL_SYSCALL_CHECK=y
diff -druN linux-2.6.39-libre/arch/powerpc/configs/c2k_defconfig linux-3.0-rc7-libre/arch/powerpc/configs/c2k_defconfig
--- linux-2.6.39-libre/arch/powerpc/configs/c2k_defconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/configs/c2k_defconfig	2011-07-11 19:51:52.000000000 -0400
@@ -132,8 +132,8 @@
 CONFIG_NET_CLS_RSVP6=m
 CONFIG_NET_CLS_IND=y
 CONFIG_BT=m
-CONFIG_BT_L2CAP=m
-CONFIG_BT_SCO=m
+CONFIG_BT_L2CAP=y
+CONFIG_BT_SCO=y
 CONFIG_BT_RFCOMM=m
 CONFIG_BT_RFCOMM_TTY=y
 CONFIG_BT_BNEP=m
diff -druN linux-2.6.39-libre/arch/powerpc/configs/e55xx_smp_defconfig linux-3.0-rc7-libre/arch/powerpc/configs/e55xx_smp_defconfig
--- linux-2.6.39-libre/arch/powerpc/configs/e55xx_smp_defconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/configs/e55xx_smp_defconfig	2011-07-11 19:51:52.000000000 -0400
@@ -6,10 +6,10 @@
 CONFIG_EXPERIMENTAL=y
 CONFIG_SYSVIPC=y
 CONFIG_BSD_PROCESS_ACCT=y
+CONFIG_SPARSE_IRQ=y
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=14
-CONFIG_SYSFS_DEPRECATED_V2=y
 CONFIG_BLK_DEV_INITRD=y
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 CONFIG_EXPERT=y
@@ -25,8 +25,32 @@
 CONFIG_NO_HZ=y
 CONFIG_HIGH_RES_TIMERS=y
 CONFIG_BINFMT_MISC=m
-CONFIG_SPARSE_IRQ=y
 # CONFIG_PCI is not set
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_XFRM_USER=y
+CONFIG_NET_KEY=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_ADVANCED_ROUTER=y
+CONFIG_IP_MULTIPLE_TABLES=y
+CONFIG_IP_ROUTE_MULTIPATH=y
+CONFIG_IP_ROUTE_VERBOSE=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+CONFIG_IP_PNP_RARP=y
+CONFIG_NET_IPIP=y
+CONFIG_IP_MROUTE=y
+CONFIG_IP_PIMSM_V1=y
+CONFIG_IP_PIMSM_V2=y
+CONFIG_ARPD=y
+CONFIG_INET_ESP=y
+# CONFIG_INET_XFRM_MODE_BEET is not set
+# CONFIG_INET_LRO is not set
+CONFIG_IPV6=y
+CONFIG_IP_SCTP=m
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 CONFIG_PROC_DEVICETREE=y
 CONFIG_BLK_DEV_LOOP=y
@@ -34,6 +58,9 @@
 CONFIG_BLK_DEV_RAM_SIZE=131072
 CONFIG_MISC_DEVICES=y
 CONFIG_EEPROM_LEGACY=y
+CONFIG_NETDEVICES=y
+CONFIG_DUMMY=y
+CONFIG_NET_ETHERNET=y
 CONFIG_INPUT_FF_MEMLESS=m
 # CONFIG_INPUT_MOUSEDEV is not set
 # CONFIG_INPUT_KEYBOARD is not set
@@ -64,22 +91,14 @@
 CONFIG_NLS_UTF8=m
 CONFIG_CRC_T10DIF=y
 CONFIG_CRC_ITU_T=m
-CONFIG_LIBCRC32C=m
 CONFIG_FRAME_WARN=1024
 CONFIG_DEBUG_FS=y
 CONFIG_DEBUG_KERNEL=y
 CONFIG_DETECT_HUNG_TASK=y
-# CONFIG_DEBUG_BUGVERBOSE is not set
 CONFIG_DEBUG_INFO=y
 # CONFIG_RCU_CPU_STALL_DETECTOR is not set
 CONFIG_SYSCTL_SYSCALL_CHECK=y
 CONFIG_VIRQ_DEBUG=y
-CONFIG_CRYPTO=y
-CONFIG_CRYPTO_CBC=y
 CONFIG_CRYPTO_PCBC=m
-CONFIG_CRYPTO_HMAC=y
-CONFIG_CRYPTO_MD5=y
-CONFIG_CRYPTO_SHA1=m
-CONFIG_CRYPTO_DES=y
 # CONFIG_CRYPTO_ANSI_CPRNG is not set
 CONFIG_CRYPTO_DEV_TALITOS=y
diff -druN linux-2.6.39-libre/arch/powerpc/configs/mpc85xx_defconfig linux-3.0-rc7-libre/arch/powerpc/configs/mpc85xx_defconfig
--- linux-2.6.39-libre/arch/powerpc/configs/mpc85xx_defconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/configs/mpc85xx_defconfig	2011-07-11 19:51:52.000000000 -0400
@@ -204,7 +204,6 @@
 CONFIG_DEBUG_FS=y
 CONFIG_DEBUG_KERNEL=y
 CONFIG_DETECT_HUNG_TASK=y
-# CONFIG_DEBUG_BUGVERBOSE is not set
 CONFIG_DEBUG_INFO=y
 # CONFIG_RCU_CPU_STALL_DETECTOR is not set
 CONFIG_SYSCTL_SYSCALL_CHECK=y
diff -druN linux-2.6.39-libre/arch/powerpc/configs/mpc85xx_smp_defconfig linux-3.0-rc7-libre/arch/powerpc/configs/mpc85xx_smp_defconfig
--- linux-2.6.39-libre/arch/powerpc/configs/mpc85xx_smp_defconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/configs/mpc85xx_smp_defconfig	2011-07-11 19:51:52.000000000 -0400
@@ -206,7 +206,6 @@
 CONFIG_DEBUG_FS=y
 CONFIG_DEBUG_KERNEL=y
 CONFIG_DETECT_HUNG_TASK=y
-# CONFIG_DEBUG_BUGVERBOSE is not set
 CONFIG_DEBUG_INFO=y
 # CONFIG_RCU_CPU_STALL_DETECTOR is not set
 CONFIG_SYSCTL_SYSCALL_CHECK=y
diff -druN linux-2.6.39-libre/arch/powerpc/configs/mpc86xx_defconfig linux-3.0-rc7-libre/arch/powerpc/configs/mpc86xx_defconfig
--- linux-2.6.39-libre/arch/powerpc/configs/mpc86xx_defconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/configs/mpc86xx_defconfig	2011-07-11 19:51:52.000000000 -0400
@@ -171,7 +171,6 @@
 CONFIG_CRC_T10DIF=y
 CONFIG_DEBUG_KERNEL=y
 CONFIG_DETECT_HUNG_TASK=y
-# CONFIG_DEBUG_BUGVERBOSE is not set
 CONFIG_DEBUG_INFO=y
 # CONFIG_RCU_CPU_STALL_DETECTOR is not set
 CONFIG_SYSCTL_SYSCALL_CHECK=y
diff -druN linux-2.6.39-libre/arch/powerpc/configs/pmac32_defconfig linux-3.0-rc7-libre/arch/powerpc/configs/pmac32_defconfig
--- linux-2.6.39-libre/arch/powerpc/configs/pmac32_defconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/configs/pmac32_defconfig	2011-07-11 19:51:52.000000000 -0400
@@ -112,8 +112,8 @@
 CONFIG_IRDA_FAST_RR=y
 CONFIG_IRTTY_SIR=m
 CONFIG_BT=m
-CONFIG_BT_L2CAP=m
-CONFIG_BT_SCO=m
+CONFIG_BT_L2CAP=y
+CONFIG_BT_SCO=y
 CONFIG_BT_RFCOMM=m
 CONFIG_BT_RFCOMM_TTY=y
 CONFIG_BT_BNEP=m
diff -druN linux-2.6.39-libre/arch/powerpc/configs/ppc6xx_defconfig linux-3.0-rc7-libre/arch/powerpc/configs/ppc6xx_defconfig
--- linux-2.6.39-libre/arch/powerpc/configs/ppc6xx_defconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/configs/ppc6xx_defconfig	2011-07-11 19:51:52.000000000 -0400
@@ -10,7 +10,6 @@
 CONFIG_TASK_IO_ACCOUNTING=y
 CONFIG_AUDIT=y
 CONFIG_CGROUPS=y
-CONFIG_CGROUP_NS=y
 CONFIG_CGROUP_DEVICE=y
 CONFIG_CGROUP_CPUACCT=y
 CONFIG_RESOURCE_COUNTERS=y
@@ -351,8 +350,8 @@
 CONFIG_VIA_FIR=m
 CONFIG_MCS_FIR=m
 CONFIG_BT=m
-CONFIG_BT_L2CAP=m
-CONFIG_BT_SCO=m
+CONFIG_BT_L2CAP=y
+CONFIG_BT_SCO=y
 CONFIG_BT_RFCOMM=m
 CONFIG_BT_RFCOMM_TTY=y
 CONFIG_BT_BNEP=m
diff -druN linux-2.6.39-libre/arch/powerpc/configs/ps3_defconfig linux-3.0-rc7-libre/arch/powerpc/configs/ps3_defconfig
--- linux-2.6.39-libre/arch/powerpc/configs/ps3_defconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/configs/ps3_defconfig	2011-07-11 19:51:52.000000000 -0400
@@ -52,8 +52,8 @@
 # CONFIG_INET_DIAG is not set
 CONFIG_IPV6=y
 CONFIG_BT=m
-CONFIG_BT_L2CAP=m
-CONFIG_BT_SCO=m
+CONFIG_BT_L2CAP=y
+CONFIG_BT_SCO=y
 CONFIG_BT_RFCOMM=m
 CONFIG_BT_RFCOMM_TTY=y
 CONFIG_BT_BNEP=m
@@ -141,7 +141,7 @@
 # CONFIG_USB_EHCI_HCD_PPC_OF is not set
 CONFIG_USB_OHCI_HCD=m
 CONFIG_USB_STORAGE=m
-CONFIG_RTC_CLASS=m
+CONFIG_RTC_CLASS=y
 CONFIG_RTC_DRV_PS3=m
 CONFIG_EXT2_FS=m
 CONFIG_EXT3_FS=m
diff -druN linux-2.6.39-libre/arch/powerpc/configs/pseries_defconfig linux-3.0-rc7-libre/arch/powerpc/configs/pseries_defconfig
--- linux-2.6.39-libre/arch/powerpc/configs/pseries_defconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/configs/pseries_defconfig	2011-07-11 19:51:52.000000000 -0400
@@ -15,7 +15,6 @@
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_CGROUPS=y
-CONFIG_CGROUP_NS=y
 CONFIG_CGROUP_FREEZER=y
 CONFIG_CGROUP_DEVICE=y
 CONFIG_CPUSETS=y
@@ -146,12 +145,17 @@
 CONFIG_SCSI_CONSTANTS=y
 CONFIG_SCSI_FC_ATTRS=y
 CONFIG_SCSI_SAS_ATTRS=m
+CONFIG_SCSI_CXGB3_ISCSI=m
+CONFIG_SCSI_CXGB4_ISCSI=m
+CONFIG_SCSI_BNX2_ISCSI=m
+CONFIG_BE2ISCSI=m
 CONFIG_SCSI_IBMVSCSI=y
 CONFIG_SCSI_IBMVFC=m
 CONFIG_SCSI_SYM53C8XX_2=y
 CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=0
 CONFIG_SCSI_IPR=y
 CONFIG_SCSI_QLA_FC=m
+CONFIG_SCSI_QLA_ISCSI=m
 CONFIG_SCSI_LPFC=m
 CONFIG_ATA=y
 # CONFIG_ATA_SFF is not set
@@ -197,6 +201,8 @@
 CONFIG_MYRI10GE=m
 CONFIG_NETXEN_NIC=m
 CONFIG_MLX4_EN=m
+CONFIG_QLGE=m
+CONFIG_BE2NET=m
 CONFIG_PPP=m
 CONFIG_PPP_ASYNC=m
 CONFIG_PPP_SYNC_TTY=m
diff -druN linux-2.6.39-libre/arch/powerpc/include/asm/cputable.h linux-3.0-rc7-libre/arch/powerpc/include/asm/cputable.h
--- linux-2.6.39-libre/arch/powerpc/include/asm/cputable.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/include/asm/cputable.h	2011-07-11 19:51:52.000000000 -0400
@@ -157,6 +157,7 @@
 #define CPU_FTR_476_DD2			ASM_CONST(0x0000000000010000)
 #define CPU_FTR_NEED_COHERENT		ASM_CONST(0x0000000000020000)
 #define CPU_FTR_NO_BTIC			ASM_CONST(0x0000000000040000)
+#define CPU_FTR_DEBUG_LVL_EXC		ASM_CONST(0x0000000000080000)
 #define CPU_FTR_NODSISRALIGN		ASM_CONST(0x0000000000100000)
 #define CPU_FTR_PPC_LE			ASM_CONST(0x0000000000200000)
 #define CPU_FTR_REAL_LE			ASM_CONST(0x0000000000400000)
@@ -178,22 +179,18 @@
 #define LONG_ASM_CONST(x)		0
 #endif
 
-#define CPU_FTR_SLB			LONG_ASM_CONST(0x0000000100000000)
-#define CPU_FTR_16M_PAGE		LONG_ASM_CONST(0x0000000200000000)
-#define CPU_FTR_TLBIEL			LONG_ASM_CONST(0x0000000400000000)
+
+#define CPU_FTR_HVMODE_206		LONG_ASM_CONST(0x0000000800000000)
+#define CPU_FTR_CFAR			LONG_ASM_CONST(0x0000001000000000)
 #define CPU_FTR_IABR			LONG_ASM_CONST(0x0000002000000000)
 #define CPU_FTR_MMCRA			LONG_ASM_CONST(0x0000004000000000)
 #define CPU_FTR_CTRL			LONG_ASM_CONST(0x0000008000000000)
 #define CPU_FTR_SMT			LONG_ASM_CONST(0x0000010000000000)
-#define CPU_FTR_LOCKLESS_TLBIE		LONG_ASM_CONST(0x0000040000000000)
-#define CPU_FTR_CI_LARGE_PAGE		LONG_ASM_CONST(0x0000100000000000)
 #define CPU_FTR_PAUSE_ZERO		LONG_ASM_CONST(0x0000200000000000)
 #define CPU_FTR_PURR			LONG_ASM_CONST(0x0000400000000000)
 #define CPU_FTR_CELL_TB_BUG		LONG_ASM_CONST(0x0000800000000000)
 #define CPU_FTR_SPURR			LONG_ASM_CONST(0x0001000000000000)
 #define CPU_FTR_DSCR			LONG_ASM_CONST(0x0002000000000000)
-#define CPU_FTR_1T_SEGMENT		LONG_ASM_CONST(0x0004000000000000)
-#define CPU_FTR_NO_SLBIE_B		LONG_ASM_CONST(0x0008000000000000)
 #define CPU_FTR_VSX			LONG_ASM_CONST(0x0010000000000000)
 #define CPU_FTR_SAO			LONG_ASM_CONST(0x0020000000000000)
 #define CPU_FTR_CP_USE_DCBTZ		LONG_ASM_CONST(0x0040000000000000)
@@ -202,12 +199,14 @@
 #define CPU_FTR_STCX_CHECKS_ADDRESS	LONG_ASM_CONST(0x0200000000000000)
 #define CPU_FTR_POPCNTB			LONG_ASM_CONST(0x0400000000000000)
 #define CPU_FTR_POPCNTD			LONG_ASM_CONST(0x0800000000000000)
+#define CPU_FTR_ICSWX			LONG_ASM_CONST(0x1000000000000000)
 
 #ifndef __ASSEMBLY__
 
-#define CPU_FTR_PPCAS_ARCH_V2	(CPU_FTR_SLB | \
-				 CPU_FTR_TLBIEL | CPU_FTR_NOEXECUTE | \
-				 CPU_FTR_NODSISRALIGN | CPU_FTR_16M_PAGE)
+#define CPU_FTR_PPCAS_ARCH_V2	(CPU_FTR_NOEXECUTE | CPU_FTR_NODSISRALIGN)
+
+#define MMU_FTR_PPCAS_ARCH_V2 	(MMU_FTR_SLB | MMU_FTR_TLBIEL | \
+				 MMU_FTR_16M_PAGE)
 
 /* We only set the altivec features if the kernel was compiled with altivec
  * support
@@ -387,7 +386,8 @@
 	    CPU_FTR_DBELL)
 #define CPU_FTRS_E5500	(CPU_FTR_USE_TB | CPU_FTR_NODSISRALIGN | \
 	    CPU_FTR_L2CSR | CPU_FTR_LWSYNC | CPU_FTR_NOEXECUTE | \
-	    CPU_FTR_DBELL | CPU_FTR_POPCNTB | CPU_FTR_POPCNTD)
+	    CPU_FTR_DBELL | CPU_FTR_POPCNTB | CPU_FTR_POPCNTD | \
+	    CPU_FTR_DEBUG_LVL_EXC)
 #define CPU_FTRS_GENERIC_32	(CPU_FTR_COMMON | CPU_FTR_NODSISRALIGN)
 
 /* 64-bit CPUs */
@@ -407,44 +407,45 @@
 #define CPU_FTRS_POWER5	(CPU_FTR_USE_TB | CPU_FTR_LWSYNC | \
 	    CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | \
 	    CPU_FTR_MMCRA | CPU_FTR_SMT | \
-	    CPU_FTR_COHERENT_ICACHE | CPU_FTR_LOCKLESS_TLBIE | \
-	    CPU_FTR_PURR | CPU_FTR_STCX_CHECKS_ADDRESS | \
-	    CPU_FTR_POPCNTB)
+	    CPU_FTR_COHERENT_ICACHE | CPU_FTR_PURR | \
+	    CPU_FTR_STCX_CHECKS_ADDRESS | CPU_FTR_POPCNTB)
 #define CPU_FTRS_POWER6 (CPU_FTR_USE_TB | CPU_FTR_LWSYNC | \
 	    CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | \
 	    CPU_FTR_MMCRA | CPU_FTR_SMT | \
-	    CPU_FTR_COHERENT_ICACHE | CPU_FTR_LOCKLESS_TLBIE | \
+	    CPU_FTR_COHERENT_ICACHE | \
 	    CPU_FTR_PURR | CPU_FTR_SPURR | CPU_FTR_REAL_LE | \
 	    CPU_FTR_DSCR | CPU_FTR_UNALIGNED_LD_STD | \
-	    CPU_FTR_STCX_CHECKS_ADDRESS | CPU_FTR_POPCNTB)
+	    CPU_FTR_STCX_CHECKS_ADDRESS | CPU_FTR_POPCNTB | CPU_FTR_CFAR)
 #define CPU_FTRS_POWER7 (CPU_FTR_USE_TB | CPU_FTR_LWSYNC | \
-	    CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | \
+	    CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | CPU_FTR_HVMODE_206 |\
 	    CPU_FTR_MMCRA | CPU_FTR_SMT | \
-	    CPU_FTR_COHERENT_ICACHE | CPU_FTR_LOCKLESS_TLBIE | \
+	    CPU_FTR_COHERENT_ICACHE | \
 	    CPU_FTR_PURR | CPU_FTR_SPURR | CPU_FTR_REAL_LE | \
 	    CPU_FTR_DSCR | CPU_FTR_SAO  | CPU_FTR_ASYM_SMT | \
-	    CPU_FTR_STCX_CHECKS_ADDRESS | CPU_FTR_POPCNTB | CPU_FTR_POPCNTD)
+	    CPU_FTR_STCX_CHECKS_ADDRESS | CPU_FTR_POPCNTB | CPU_FTR_POPCNTD | \
+	    CPU_FTR_ICSWX | CPU_FTR_CFAR)
 #define CPU_FTRS_CELL	(CPU_FTR_USE_TB | CPU_FTR_LWSYNC | \
 	    CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | \
 	    CPU_FTR_ALTIVEC_COMP | CPU_FTR_MMCRA | CPU_FTR_SMT | \
-	    CPU_FTR_PAUSE_ZERO | CPU_FTR_CI_LARGE_PAGE | \
-	    CPU_FTR_CELL_TB_BUG | CPU_FTR_CP_USE_DCBTZ | \
+	    CPU_FTR_PAUSE_ZERO  | CPU_FTR_CELL_TB_BUG | CPU_FTR_CP_USE_DCBTZ | \
 	    CPU_FTR_UNALIGNED_LD_STD)
 #define CPU_FTRS_PA6T (CPU_FTR_USE_TB | CPU_FTR_LWSYNC | \
-	    CPU_FTR_PPCAS_ARCH_V2 | \
-	    CPU_FTR_ALTIVEC_COMP | CPU_FTR_CI_LARGE_PAGE | \
-	    CPU_FTR_PURR | CPU_FTR_REAL_LE | CPU_FTR_NO_SLBIE_B)
+	    CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_ALTIVEC_COMP | \
+	    CPU_FTR_PURR | CPU_FTR_REAL_LE)
 #define CPU_FTRS_COMPATIBLE	(CPU_FTR_USE_TB | CPU_FTR_PPCAS_ARCH_V2)
 
+#define CPU_FTRS_A2 (CPU_FTR_USE_TB | CPU_FTR_SMT | CPU_FTR_DBELL | \
+		     CPU_FTR_NOEXECUTE | CPU_FTR_NODSISRALIGN)
+
 #ifdef __powerpc64__
 #ifdef CONFIG_PPC_BOOK3E
-#define CPU_FTRS_POSSIBLE	(CPU_FTRS_E5500)
+#define CPU_FTRS_POSSIBLE	(CPU_FTRS_E5500 | CPU_FTRS_A2)
 #else
 #define CPU_FTRS_POSSIBLE	\
 	    (CPU_FTRS_POWER3 | CPU_FTRS_RS64 | CPU_FTRS_POWER4 |	\
 	    CPU_FTRS_PPC970 | CPU_FTRS_POWER5 | CPU_FTRS_POWER6 |	\
 	    CPU_FTRS_POWER7 | CPU_FTRS_CELL | CPU_FTRS_PA6T |		\
-	    CPU_FTR_1T_SEGMENT | CPU_FTR_VSX)
+	    CPU_FTR_VSX)
 #endif
 #else
 enum {
@@ -487,7 +488,7 @@
 
 #ifdef __powerpc64__
 #ifdef CONFIG_PPC_BOOK3E
-#define CPU_FTRS_ALWAYS		(CPU_FTRS_E5500)
+#define CPU_FTRS_ALWAYS		(CPU_FTRS_E5500 & CPU_FTRS_A2)
 #else
 #define CPU_FTRS_ALWAYS		\
 	    (CPU_FTRS_POWER3 & CPU_FTRS_RS64 & CPU_FTRS_POWER4 &	\
diff -druN linux-2.6.39-libre/arch/powerpc/include/asm/cputhreads.h linux-3.0-rc7-libre/arch/powerpc/include/asm/cputhreads.h
--- linux-2.6.39-libre/arch/powerpc/include/asm/cputhreads.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/include/asm/cputhreads.h	2011-07-11 19:51:52.000000000 -0400
@@ -37,16 +37,16 @@
  * This can typically be used for things like IPI for tlb invalidations
  * since those need to be done only once per core/TLB
  */
-static inline cpumask_t cpu_thread_mask_to_cores(cpumask_t threads)
+static inline cpumask_t cpu_thread_mask_to_cores(const struct cpumask *threads)
 {
 	cpumask_t	tmp, res;
 	int		i;
 
-	res = CPU_MASK_NONE;
+	cpumask_clear(&res);
 	for (i = 0; i < NR_CPUS; i += threads_per_core) {
-		cpus_shift_left(tmp, threads_core_mask, i);
-		if (cpus_intersects(threads, tmp))
-			cpu_set(i, res);
+		cpumask_shift_left(&tmp, &threads_core_mask, i);
+		if (cpumask_intersects(threads, &tmp))
+			cpumask_set_cpu(i, &res);
 	}
 	return res;
 }
@@ -58,7 +58,7 @@
 
 static inline cpumask_t cpu_online_cores_map(void)
 {
-	return cpu_thread_mask_to_cores(cpu_online_map);
+	return cpu_thread_mask_to_cores(cpu_online_mask);
 }
 
 #ifdef CONFIG_SMP
diff -druN linux-2.6.39-libre/arch/powerpc/include/asm/dbell.h linux-3.0-rc7-libre/arch/powerpc/include/asm/dbell.h
--- linux-2.6.39-libre/arch/powerpc/include/asm/dbell.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/include/asm/dbell.h	2011-07-11 19:51:52.000000000 -0400
@@ -27,9 +27,8 @@
 	PPC_G_DBELL_MC = 4,	/* guest mcheck doorbell */
 };
 
-extern void doorbell_message_pass(int target, int msg);
+extern void doorbell_cause_ipi(int cpu, unsigned long data);
 extern void doorbell_exception(struct pt_regs *regs);
-extern void doorbell_check_self(void);
 extern void doorbell_setup_this_cpu(void);
 
 static inline void ppc_msgsnd(enum ppc_dbell type, u32 flags, u32 tag)
diff -druN linux-2.6.39-libre/arch/powerpc/include/asm/emulated_ops.h linux-3.0-rc7-libre/arch/powerpc/include/asm/emulated_ops.h
--- linux-2.6.39-libre/arch/powerpc/include/asm/emulated_ops.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/include/asm/emulated_ops.h	2011-07-11 19:51:52.000000000 -0400
@@ -52,6 +52,10 @@
 #ifdef CONFIG_VSX
 	struct ppc_emulated_entry vsx;
 #endif
+#ifdef CONFIG_PPC64
+	struct ppc_emulated_entry mfdscr;
+	struct ppc_emulated_entry mtdscr;
+#endif
 } ppc_emulated;
 
 extern u32 ppc_warn_emulated;
diff -druN linux-2.6.39-libre/arch/powerpc/include/asm/exception-64s.h linux-3.0-rc7-libre/arch/powerpc/include/asm/exception-64s.h
--- linux-2.6.39-libre/arch/powerpc/include/asm/exception-64s.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/include/asm/exception-64s.h	2011-07-11 19:51:52.000000000 -0400
@@ -46,6 +46,7 @@
 #define EX_CCR		60
 #define EX_R3		64
 #define EX_LR		72
+#define EX_CFAR		80
 
 /*
  * We're short on space and time in the exception prolog, so we can't
@@ -56,30 +57,40 @@
 #define LOAD_HANDLER(reg, label)					\
 	addi	reg,reg,(label)-_stext;	/* virt addr of handler ... */
 
-#define EXCEPTION_PROLOG_1(area)				\
-	mfspr	r13,SPRN_SPRG_PACA;	/* get paca address into r13 */	\
+/* Exception register prefixes */
+#define EXC_HV	H
+#define EXC_STD
+
+#define EXCEPTION_PROLOG_1(area)					\
+	GET_PACA(r13);							\
 	std	r9,area+EX_R9(r13);	/* save r9 - r12 */		\
 	std	r10,area+EX_R10(r13);					\
 	std	r11,area+EX_R11(r13);					\
 	std	r12,area+EX_R12(r13);					\
-	mfspr	r9,SPRN_SPRG_SCRATCH0;					\
+	BEGIN_FTR_SECTION_NESTED(66);					\
+	mfspr	r10,SPRN_CFAR;						\
+	std	r10,area+EX_CFAR(r13);					\
+	END_FTR_SECTION_NESTED(CPU_FTR_CFAR, CPU_FTR_CFAR, 66);		\
+	GET_SCRATCH0(r9);						\
 	std	r9,area+EX_R13(r13);					\
 	mfcr	r9
 
-#define EXCEPTION_PROLOG_PSERIES_1(label)				\
+#define __EXCEPTION_PROLOG_PSERIES_1(label, h)				\
 	ld	r12,PACAKBASE(r13);	/* get high part of &label */	\
 	ld	r10,PACAKMSR(r13);	/* get MSR value for kernel */	\
-	mfspr	r11,SPRN_SRR0;		/* save SRR0 */			\
+	mfspr	r11,SPRN_##h##SRR0;	/* save SRR0 */			\
 	LOAD_HANDLER(r12,label)						\
-	mtspr	SPRN_SRR0,r12;						\
-	mfspr	r12,SPRN_SRR1;		/* and SRR1 */			\
-	mtspr	SPRN_SRR1,r10;						\
-	rfid;								\
+	mtspr	SPRN_##h##SRR0,r12;					\
+	mfspr	r12,SPRN_##h##SRR1;	/* and SRR1 */			\
+	mtspr	SPRN_##h##SRR1,r10;					\
+	h##rfid;							\
 	b	.	/* prevent speculative execution */
+#define EXCEPTION_PROLOG_PSERIES_1(label, h) \
+	__EXCEPTION_PROLOG_PSERIES_1(label, h)
 
-#define EXCEPTION_PROLOG_PSERIES(area, label)				\
+#define EXCEPTION_PROLOG_PSERIES(area, label, h)			\
 	EXCEPTION_PROLOG_1(area);					\
-	EXCEPTION_PROLOG_PSERIES_1(label);
+	EXCEPTION_PROLOG_PSERIES_1(label, h);
 
 /*
  * The common exception prolog is used for all except a few exceptions
@@ -98,10 +109,11 @@
 	beq-	1f;							   \
 	ld	r1,PACAKSAVE(r13);	/* kernel stack to use		*/ \
 1:	cmpdi	cr1,r1,0;		/* check if r1 is in userspace	*/ \
-	bge-	cr1,2f;			/* abort if it is		*/ \
-	b	3f;							   \
-2:	li	r1,(n);			/* will be reloaded later	*/ \
+	blt+	cr1,3f;			/* abort if it is		*/ \
+	li	r1,(n);			/* will be reloaded later	*/ \
 	sth	r1,PACA_TRAP_SAVE(r13);					   \
+	std	r3,area+EX_R3(r13);					   \
+	addi	r3,r13,area;		/* r3 -> where regs are saved*/	   \
 	b	bad_stack;						   \
 3:	std	r9,_CCR(r1);		/* save CR in stackframe	*/ \
 	std	r11,_NIP(r1);		/* save SRR0 in stackframe	*/ \
@@ -123,6 +135,10 @@
 	std	r9,GPR11(r1);						   \
 	std	r10,GPR12(r1);						   \
 	std	r11,GPR13(r1);						   \
+	BEGIN_FTR_SECTION_NESTED(66);					   \
+	ld	r10,area+EX_CFAR(r13);					   \
+	std	r10,ORIG_GPR3(r1);					   \
+	END_FTR_SECTION_NESTED(CPU_FTR_CFAR, CPU_FTR_CFAR, 66);		   \
 	ld	r2,PACATOC(r13);	/* get kernel TOC into r2	*/ \
 	mflr	r9;			/* save LR in stackframe	*/ \
 	std	r9,_LINK(r1);						   \
@@ -143,57 +159,62 @@
 /*
  * Exception vectors.
  */
-#define STD_EXCEPTION_PSERIES(n, label)			\
-	. = n;						\
+#define STD_EXCEPTION_PSERIES(loc, vec, label)		\
+	. = loc;					\
 	.globl label##_pSeries;				\
 label##_pSeries:					\
 	HMT_MEDIUM;					\
-	DO_KVM	n;					\
-	mtspr	SPRN_SPRG_SCRATCH0,r13;		/* save r13 */	\
-	EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, label##_common)
+	DO_KVM	vec;					\
+	SET_SCRATCH0(r13);		/* save r13 */		\
+	EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, label##_common, EXC_STD)
 
-#define HSTD_EXCEPTION_PSERIES(n, label)		\
-	. = n;						\
-	.globl label##_pSeries;				\
-label##_pSeries:					\
+#define STD_EXCEPTION_HV(loc, vec, label)		\
+	. = loc;					\
+	.globl label##_hv;				\
+label##_hv:						\
 	HMT_MEDIUM;					\
-	mtspr	SPRN_SPRG_SCRATCH0,r20;	/* save r20 */	\
-	mfspr	r20,SPRN_HSRR0;		/* copy HSRR0 to SRR0 */ \
-	mtspr	SPRN_SRR0,r20;				\
-	mfspr	r20,SPRN_HSRR1;		/* copy HSRR0 to SRR0 */ \
-	mtspr	SPRN_SRR1,r20;				\
-	mfspr	r20,SPRN_SPRG_SCRATCH0;	/* restore r20 */ \
-	mtspr	SPRN_SPRG_SCRATCH0,r13;		/* save r13 */	\
-	EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, label##_common)
-
+	DO_KVM	vec;					\
+	SET_SCRATCH0(r13);	/* save r13 */		\
+	EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, label##_common, EXC_HV)
 
-#define MASKABLE_EXCEPTION_PSERIES(n, label)				\
-	. = n;								\
-	.globl label##_pSeries;						\
-label##_pSeries:							\
+#define __MASKABLE_EXCEPTION_PSERIES(vec, label, h)			\
 	HMT_MEDIUM;							\
-	DO_KVM	n;							\
-	mtspr	SPRN_SPRG_SCRATCH0,r13;	/* save r13 */			\
-	mfspr	r13,SPRN_SPRG_PACA;	/* get paca address into r13 */	\
+	DO_KVM	vec;							\
+	SET_SCRATCH0(r13);    /* save r13 */				\
+	GET_PACA(r13);							\
 	std	r9,PACA_EXGEN+EX_R9(r13);	/* save r9, r10 */	\
 	std	r10,PACA_EXGEN+EX_R10(r13);				\
 	lbz	r10,PACASOFTIRQEN(r13);					\
 	mfcr	r9;							\
 	cmpwi	r10,0;							\
-	beq	masked_interrupt;					\
-	mfspr	r10,SPRN_SPRG_SCRATCH0;					\
+	beq	masked_##h##interrupt;					\
+	GET_SCRATCH0(r10);						\
 	std	r10,PACA_EXGEN+EX_R13(r13);				\
 	std	r11,PACA_EXGEN+EX_R11(r13);				\
 	std	r12,PACA_EXGEN+EX_R12(r13);				\
 	ld	r12,PACAKBASE(r13);	/* get high part of &label */	\
 	ld	r10,PACAKMSR(r13);	/* get MSR value for kernel */	\
-	mfspr	r11,SPRN_SRR0;		/* save SRR0 */			\
+	mfspr	r11,SPRN_##h##SRR0;	/* save SRR0 */			\
 	LOAD_HANDLER(r12,label##_common)				\
-	mtspr	SPRN_SRR0,r12;						\
-	mfspr	r12,SPRN_SRR1;		/* and SRR1 */			\
-	mtspr	SPRN_SRR1,r10;						\
-	rfid;								\
+	mtspr	SPRN_##h##SRR0,r12;					\
+	mfspr	r12,SPRN_##h##SRR1;	/* and SRR1 */			\
+	mtspr	SPRN_##h##SRR1,r10;					\
+	h##rfid;							\
 	b	.	/* prevent speculative execution */
+#define _MASKABLE_EXCEPTION_PSERIES(vec, label, h)			\
+	__MASKABLE_EXCEPTION_PSERIES(vec, label, h)
+
+#define MASKABLE_EXCEPTION_PSERIES(loc, vec, label)			\
+	. = loc;							\
+	.globl label##_pSeries;						\
+label##_pSeries:							\
+	_MASKABLE_EXCEPTION_PSERIES(vec, label, EXC_STD)
+
+#define MASKABLE_EXCEPTION_HV(loc, vec, label)				\
+	. = loc;							\
+	.globl label##_hv;						\
+label##_hv:								\
+	_MASKABLE_EXCEPTION_PSERIES(vec, label, EXC_HV)
 
 #ifdef CONFIG_PPC_ISERIES
 #define DISABLE_INTS				\
diff -druN linux-2.6.39-libre/arch/powerpc/include/asm/feature-fixups.h linux-3.0-rc7-libre/arch/powerpc/include/asm/feature-fixups.h
--- linux-2.6.39-libre/arch/powerpc/include/asm/feature-fixups.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/include/asm/feature-fixups.h	2011-07-11 19:51:52.000000000 -0400
@@ -49,7 +49,7 @@
 	FTR_ENTRY_OFFSET label##2b-label##5b;			\
 	FTR_ENTRY_OFFSET label##3b-label##5b;			\
 	FTR_ENTRY_OFFSET label##4b-label##5b;			\
-	.ifgt (label##4b-label##3b)-(label##2b-label##1b);	\
+	.ifgt (label##4b- label##3b)-(label##2b- label##1b);	\
 	.error "Feature section else case larger than body";	\
 	.endif;							\
 	.popsection;
@@ -146,6 +146,19 @@
 
 #ifndef __ASSEMBLY__
 
+#define ASM_FTR_IF(section_if, section_else, msk, val)	\
+	stringify_in_c(BEGIN_FTR_SECTION)			\
+	section_if "; "						\
+	stringify_in_c(FTR_SECTION_ELSE)			\
+	section_else "; "					\
+	stringify_in_c(ALT_FTR_SECTION_END((msk), (val)))
+
+#define ASM_FTR_IFSET(section_if, section_else, msk)	\
+	ASM_FTR_IF(section_if, section_else, (msk), (msk))
+
+#define ASM_FTR_IFCLR(section_if, section_else, msk)	\
+	ASM_FTR_IF(section_if, section_else, (msk), 0)
+
 #define ASM_MMU_FTR_IF(section_if, section_else, msk, val)	\
 	stringify_in_c(BEGIN_MMU_FTR_SECTION)			\
 	section_if "; "						\
diff -druN linux-2.6.39-libre/arch/powerpc/include/asm/firmware.h linux-3.0-rc7-libre/arch/powerpc/include/asm/firmware.h
--- linux-2.6.39-libre/arch/powerpc/include/asm/firmware.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/include/asm/firmware.h	2011-07-11 19:51:52.000000000 -0400
@@ -47,6 +47,7 @@
 #define FW_FEATURE_BEAT		ASM_CONST(0x0000000001000000)
 #define FW_FEATURE_CMO		ASM_CONST(0x0000000002000000)
 #define FW_FEATURE_VPHN		ASM_CONST(0x0000000004000000)
+#define FW_FEATURE_XCMO		ASM_CONST(0x0000000008000000)
 
 #ifndef __ASSEMBLY__
 
@@ -60,7 +61,7 @@
 		FW_FEATURE_VIO | FW_FEATURE_RDMA | FW_FEATURE_LLAN |
 		FW_FEATURE_BULK_REMOVE | FW_FEATURE_XDABR |
 		FW_FEATURE_MULTITCE | FW_FEATURE_SPLPAR | FW_FEATURE_LPAR |
-		FW_FEATURE_CMO | FW_FEATURE_VPHN,
+		FW_FEATURE_CMO | FW_FEATURE_VPHN | FW_FEATURE_XCMO,
 	FW_FEATURE_PSERIES_ALWAYS = 0,
 	FW_FEATURE_ISERIES_POSSIBLE = FW_FEATURE_ISERIES | FW_FEATURE_LPAR,
 	FW_FEATURE_ISERIES_ALWAYS = FW_FEATURE_ISERIES | FW_FEATURE_LPAR,
diff -druN linux-2.6.39-libre/arch/powerpc/include/asm/fsl_lbc.h linux-3.0-rc7-libre/arch/powerpc/include/asm/fsl_lbc.h
--- linux-2.6.39-libre/arch/powerpc/include/asm/fsl_lbc.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/include/asm/fsl_lbc.h	2011-07-11 19:51:52.000000000 -0400
@@ -157,6 +157,8 @@
 #define LBCR_EPAR_SHIFT    16
 #define LBCR_BMT   0x0000FF00
 #define LBCR_BMT_SHIFT      8
+#define LBCR_BMTPS 0x0000000F
+#define LBCR_BMTPS_SHIFT    0
 #define LBCR_INIT  0x00040000
 	__be32 lcrr;            /**< Clock Ratio Register */
 #define LCRR_DBYP    0x80000000
diff -druN linux-2.6.39-libre/arch/powerpc/include/asm/ftrace.h linux-3.0-rc7-libre/arch/powerpc/include/asm/ftrace.h
--- linux-2.6.39-libre/arch/powerpc/include/asm/ftrace.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/include/asm/ftrace.h	2011-07-11 19:51:52.000000000 -0400
@@ -60,4 +60,18 @@
 
 #endif
 
+#if defined(CONFIG_FTRACE_SYSCALLS) && defined(CONFIG_PPC64) && !defined(__ASSEMBLY__)
+#define ARCH_HAS_SYSCALL_MATCH_SYM_NAME
+static inline bool arch_syscall_match_sym_name(const char *sym, const char *name)
+{
+	/*
+	 * Compare the symbol name with the system call name. Skip the .sys or .SyS
+	 * prefix from the symbol name and the sys prefix from the system call name and
+	 * just match the rest. This is only needed on ppc64 since symbol names on
+	 * 32bit do not start with a period so the generic function will work.
+	 */
+	return !strcmp(sym + 4, name + 3);
+}
+#endif /* CONFIG_FTRACE_SYSCALLS && CONFIG_PPC64 && !__ASSEMBLY__ */
+
 #endif /* _ASM_POWERPC_FTRACE */
diff -druN linux-2.6.39-libre/arch/powerpc/include/asm/hvcall.h linux-3.0-rc7-libre/arch/powerpc/include/asm/hvcall.h
--- linux-2.6.39-libre/arch/powerpc/include/asm/hvcall.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/include/asm/hvcall.h	2011-07-11 19:51:52.000000000 -0400
@@ -102,6 +102,7 @@
 #define H_ANDCOND		(1UL<<(63-33))
 #define H_ICACHE_INVALIDATE	(1UL<<(63-40))	/* icbi, etc.  (ignored for IO pages) */
 #define H_ICACHE_SYNCHRONIZE	(1UL<<(63-41))	/* dcbst, icbi, etc (ignored for IO pages */
+#define H_COALESCE_CAND	(1UL<<(63-42))	/* page is a good candidate for coalescing */
 #define H_ZERO_PAGE		(1UL<<(63-48))	/* zero the page before mapping (ignored for IO pages) */
 #define H_COPY_PAGE		(1UL<<(63-49))
 #define H_N			(1UL<<(63-61))
@@ -234,7 +235,8 @@
 #define H_GET_MPP		0x2D4
 #define H_HOME_NODE_ASSOCIATIVITY 0x2EC
 #define H_BEST_ENERGY		0x2F4
-#define MAX_HCALL_OPCODE	H_BEST_ENERGY
+#define H_GET_MPP_X		0x314
+#define MAX_HCALL_OPCODE	H_GET_MPP_X
 
 #ifndef __ASSEMBLY__
 
@@ -312,6 +314,16 @@
 
 int h_get_mpp(struct hvcall_mpp_data *);
 
+struct hvcall_mpp_x_data {
+	unsigned long coalesced_bytes;
+	unsigned long pool_coalesced_bytes;
+	unsigned long pool_purr_cycles;
+	unsigned long pool_spurr_cycles;
+	unsigned long reserved[3];
+};
+
+int h_get_mpp_x(struct hvcall_mpp_x_data *mpp_x_data);
+
 #ifdef CONFIG_PPC_PSERIES
 extern int CMO_PrPSP;
 extern int CMO_SecPSP;
diff -druN linux-2.6.39-libre/arch/powerpc/include/asm/io_event_irq.h linux-3.0-rc7-libre/arch/powerpc/include/asm/io_event_irq.h
--- linux-2.6.39-libre/arch/powerpc/include/asm/io_event_irq.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/powerpc/include/asm/io_event_irq.h	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2010, 2011 Mark Nelson and Tseng-Hui (Frank) Lin, 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.
+ */
+
+#ifndef _ASM_POWERPC_IO_EVENT_IRQ_H
+#define _ASM_POWERPC_IO_EVENT_IRQ_H
+
+#include <linux/types.h>
+#include <linux/notifier.h>
+
+#define PSERIES_IOEI_RPC_MAX_LEN 216
+
+#define PSERIES_IOEI_TYPE_ERR_DETECTED		0x01
+#define PSERIES_IOEI_TYPE_ERR_RECOVERED		0x02
+#define PSERIES_IOEI_TYPE_EVENT			0x03
+#define PSERIES_IOEI_TYPE_RPC_PASS_THRU		0x04
+
+#define PSERIES_IOEI_SUBTYPE_NOT_APP		0x00
+#define PSERIES_IOEI_SUBTYPE_REBALANCE_REQ	0x01
+#define PSERIES_IOEI_SUBTYPE_NODE_ONLINE	0x03
+#define PSERIES_IOEI_SUBTYPE_NODE_OFFLINE	0x04
+#define PSERIES_IOEI_SUBTYPE_DUMP_SIZE_CHANGE	0x05
+#define PSERIES_IOEI_SUBTYPE_TORRENT_IRV_UPDATE	0x06
+#define PSERIES_IOEI_SUBTYPE_TORRENT_HFI_CFGED	0x07
+
+#define PSERIES_IOEI_SCOPE_NOT_APP		0x00
+#define PSERIES_IOEI_SCOPE_RIO_HUB		0x36
+#define PSERIES_IOEI_SCOPE_RIO_BRIDGE		0x37
+#define PSERIES_IOEI_SCOPE_PHB			0x38
+#define PSERIES_IOEI_SCOPE_EADS_GLOBAL		0x39
+#define PSERIES_IOEI_SCOPE_EADS_SLOT		0x3A
+#define PSERIES_IOEI_SCOPE_TORRENT_HUB		0x3B
+#define PSERIES_IOEI_SCOPE_SERVICE_PROC		0x51
+
+/* Platform Event Log Format, Version 6, data portition of IO event section */
+struct pseries_io_event {
+	uint8_t event_type;		/* 0x00 IO-Event Type		*/
+	uint8_t rpc_data_len;		/* 0x01 RPC data length		*/
+	uint8_t scope;			/* 0x02 Error/Event Scope	*/
+	uint8_t event_subtype;		/* 0x03 I/O-Event Sub-Type	*/
+	uint32_t drc_index;		/* 0x04 DRC Index		*/
+	uint8_t rpc_data[PSERIES_IOEI_RPC_MAX_LEN];
+					/* 0x08 RPC Data (0-216 bytes,	*/
+					/* padded to 4 bytes alignment)	*/
+};
+
+extern struct atomic_notifier_head pseries_ioei_notifier_list;
+
+#endif /* _ASM_POWERPC_IO_EVENT_IRQ_H */
diff -druN linux-2.6.39-libre/arch/powerpc/include/asm/io.h linux-3.0-rc7-libre/arch/powerpc/include/asm/io.h
--- linux-2.6.39-libre/arch/powerpc/include/asm/io.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/include/asm/io.h	2011-07-11 19:51:52.000000000 -0400
@@ -2,6 +2,8 @@
 #define _ASM_POWERPC_IO_H
 #ifdef __KERNEL__
 
+#define ARCH_HAS_IOREMAP_WC
+
 /*
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
@@ -481,10 +483,16 @@
 				_memcpy_fromio(dst,PCI_FIX_ADDR(src),n)
 #endif /* !CONFIG_EEH */
 
-#ifdef CONFIG_PPC_INDIRECT_IO
-#define DEF_PCI_HOOK(x)		x
+#ifdef CONFIG_PPC_INDIRECT_PIO
+#define DEF_PCI_HOOK_pio(x)	x
 #else
-#define DEF_PCI_HOOK(x)		NULL
+#define DEF_PCI_HOOK_pio(x)	NULL
+#endif
+
+#ifdef CONFIG_PPC_INDIRECT_MMIO
+#define DEF_PCI_HOOK_mem(x)	x
+#else
+#define DEF_PCI_HOOK_mem(x)	NULL
 #endif
 
 /* Structure containing all the hooks */
@@ -504,7 +512,7 @@
 #define DEF_PCI_AC_RET(name, ret, at, al, space, aa)		\
 static inline ret name at					\
 {								\
-	if (DEF_PCI_HOOK(ppc_pci_io.name) != NULL)		\
+	if (DEF_PCI_HOOK_##space(ppc_pci_io.name) != NULL)	\
 		return ppc_pci_io.name al;			\
 	return __do_##name al;					\
 }
@@ -512,7 +520,7 @@
 #define DEF_PCI_AC_NORET(name, at, al, space, aa)		\
 static inline void name at					\
 {								\
-	if (DEF_PCI_HOOK(ppc_pci_io.name) != NULL)		\
+	if (DEF_PCI_HOOK_##space(ppc_pci_io.name) != NULL)		\
 		ppc_pci_io.name al;				\
 	else							\
 		__do_##name al;					\
@@ -616,12 +624,13 @@
  * * ioremap is the standard one and provides non-cacheable guarded mappings
  *   and can be hooked by the platform via ppc_md
  *
- * * ioremap_flags allows to specify the page flags as an argument and can
- *   also be hooked by the platform via ppc_md. ioremap_prot is the exact
- *   same thing as ioremap_flags.
+ * * ioremap_prot allows to specify the page flags as an argument and can
+ *   also be hooked by the platform via ppc_md.
  *
  * * ioremap_nocache is identical to ioremap
  *
+ * * ioremap_wc enables write combining
+ *
  * * iounmap undoes such a mapping and can be hooked
  *
  * * __ioremap_at (and the pending __iounmap_at) are low level functions to
@@ -629,7 +638,7 @@
  *   currently be hooked. Must be page aligned.
  *
  * * __ioremap is the low level implementation used by ioremap and
- *   ioremap_flags and cannot be hooked (but can be used by a hook on one
+ *   ioremap_prot and cannot be hooked (but can be used by a hook on one
  *   of the previous ones)
  *
  * * __ioremap_caller is the same as above but takes an explicit caller
@@ -640,10 +649,10 @@
  *
  */
 extern void __iomem *ioremap(phys_addr_t address, unsigned long size);
-extern void __iomem *ioremap_flags(phys_addr_t address, unsigned long size,
-				   unsigned long flags);
+extern void __iomem *ioremap_prot(phys_addr_t address, unsigned long size,
+				  unsigned long flags);
+extern void __iomem *ioremap_wc(phys_addr_t address, unsigned long size);
 #define ioremap_nocache(addr, size)	ioremap((addr), (size))
-#define ioremap_prot(addr, size, prot)	ioremap_flags((addr), (size), (prot))
 
 extern void iounmap(volatile void __iomem *addr);
 
diff -druN linux-2.6.39-libre/arch/powerpc/include/asm/io-workarounds.h linux-3.0-rc7-libre/arch/powerpc/include/asm/io-workarounds.h
--- linux-2.6.39-libre/arch/powerpc/include/asm/io-workarounds.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/powerpc/include/asm/io-workarounds.h	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,48 @@
+/*
+ * Support PCI IO workaround
+ *
+ * (C) Copyright 2007-2008 TOSHIBA 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef _IO_WORKAROUNDS_H
+#define _IO_WORKAROUNDS_H
+
+#include <linux/io.h>
+#include <asm/pci-bridge.h>
+
+/* Bus info */
+struct iowa_bus {
+	struct pci_controller *phb;
+	struct ppc_pci_io *ops;
+	void   *private;
+};
+
+void __devinit iowa_register_bus(struct pci_controller *, struct ppc_pci_io *,
+				 int (*)(struct iowa_bus *, void *), void *);
+struct iowa_bus *iowa_mem_find_bus(const PCI_IO_ADDR);
+struct iowa_bus *iowa_pio_find_bus(unsigned long);
+
+extern struct ppc_pci_io spiderpci_ops;
+extern int spiderpci_iowa_init(struct iowa_bus *, void *);
+
+#define SPIDER_PCI_REG_BASE		0xd000
+#define SPIDER_PCI_REG_SIZE		0x1000
+#define SPIDER_PCI_VCI_CNTL_STAT	0x0110
+#define SPIDER_PCI_DUMMY_READ		0x0810
+#define SPIDER_PCI_DUMMY_READ_BASE	0x0814
+
+#endif /* _IO_WORKAROUNDS_H */
diff -druN linux-2.6.39-libre/arch/powerpc/include/asm/irq.h linux-3.0-rc7-libre/arch/powerpc/include/asm/irq.h
--- linux-2.6.39-libre/arch/powerpc/include/asm/irq.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/include/asm/irq.h	2011-07-11 19:51:52.000000000 -0400
@@ -88,9 +88,6 @@
 	/* Dispose of such a mapping */
 	void (*unmap)(struct irq_host *h, unsigned int virq);
 
-	/* Update of such a mapping  */
-	void (*remap)(struct irq_host *h, unsigned int virq, irq_hw_number_t hw);
-
 	/* Translate device-tree interrupt specifier from raw format coming
 	 * from the firmware to a irq_hw_number_t (interrupt line number) and
 	 * type (sense) that can be passed to set_irq_type(). In the absence
@@ -128,19 +125,10 @@
 	struct device_node	*of_node;
 };
 
-/* The main irq map itself is an array of NR_IRQ entries containing the
- * associate host and irq number. An entry with a host of NULL is free.
- * An entry can be allocated if it's free, the allocator always then sets
- * hwirq first to the host's invalid irq number and then fills ops.
- */
-struct irq_map_entry {
-	irq_hw_number_t	hwirq;
-	struct irq_host	*host;
-};
-
-extern struct irq_map_entry irq_map[NR_IRQS];
-
+struct irq_data;
+extern irq_hw_number_t irqd_to_hwirq(struct irq_data *d);
 extern irq_hw_number_t virq_to_hw(unsigned int virq);
+extern bool virq_is_host(unsigned int virq, struct irq_host *host);
 
 /**
  * irq_alloc_host - Allocate a new irq_host data structure
diff -druN linux-2.6.39-libre/arch/powerpc/include/asm/kexec.h linux-3.0-rc7-libre/arch/powerpc/include/asm/kexec.h
--- linux-2.6.39-libre/arch/powerpc/include/asm/kexec.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/include/asm/kexec.h	2011-07-11 19:51:52.000000000 -0400
@@ -76,7 +76,7 @@
 extern cpumask_t cpus_in_sr;
 static inline int kexec_sr_activated(int cpu)
 {
-	return cpu_isset(cpu,cpus_in_sr);
+	return cpumask_test_cpu(cpu, &cpus_in_sr);
 }
 
 struct kimage;
diff -druN linux-2.6.39-libre/arch/powerpc/include/asm/kvm_44x.h linux-3.0-rc7-libre/arch/powerpc/include/asm/kvm_44x.h
--- linux-2.6.39-libre/arch/powerpc/include/asm/kvm_44x.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/include/asm/kvm_44x.h	2011-07-11 19:51:52.000000000 -0400
@@ -61,7 +61,6 @@
 	return container_of(vcpu, struct kvmppc_vcpu_44x, vcpu);
 }
 
-void kvmppc_set_pid(struct kvm_vcpu *vcpu, u32 new_pid);
 void kvmppc_44x_tlb_put(struct kvm_vcpu *vcpu);
 void kvmppc_44x_tlb_load(struct kvm_vcpu *vcpu);
 
diff -druN linux-2.6.39-libre/arch/powerpc/include/asm/kvm_asm.h linux-3.0-rc7-libre/arch/powerpc/include/asm/kvm_asm.h
--- linux-2.6.39-libre/arch/powerpc/include/asm/kvm_asm.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/include/asm/kvm_asm.h	2011-07-11 19:51:52.000000000 -0400
@@ -59,6 +59,7 @@
 #define BOOK3S_INTERRUPT_INST_SEGMENT	0x480
 #define BOOK3S_INTERRUPT_EXTERNAL	0x500
 #define BOOK3S_INTERRUPT_EXTERNAL_LEVEL	0x501
+#define BOOK3S_INTERRUPT_EXTERNAL_HV	0x502
 #define BOOK3S_INTERRUPT_ALIGNMENT	0x600
 #define BOOK3S_INTERRUPT_PROGRAM	0x700
 #define BOOK3S_INTERRUPT_FP_UNAVAIL	0x800
diff -druN linux-2.6.39-libre/arch/powerpc/include/asm/kvm_book3s_asm.h linux-3.0-rc7-libre/arch/powerpc/include/asm/kvm_book3s_asm.h
--- linux-2.6.39-libre/arch/powerpc/include/asm/kvm_book3s_asm.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/include/asm/kvm_book3s_asm.h	2011-07-11 19:51:52.000000000 -0400
@@ -34,6 +34,7 @@
 	    (\intno == BOOK3S_INTERRUPT_DATA_SEGMENT) || \
 	    (\intno == BOOK3S_INTERRUPT_INST_SEGMENT) || \
 	    (\intno == BOOK3S_INTERRUPT_EXTERNAL) || \
+	    (\intno == BOOK3S_INTERRUPT_EXTERNAL_HV) || \
 	    (\intno == BOOK3S_INTERRUPT_ALIGNMENT) || \
 	    (\intno == BOOK3S_INTERRUPT_PROGRAM) || \
 	    (\intno == BOOK3S_INTERRUPT_FP_UNAVAIL) || \
diff -druN linux-2.6.39-libre/arch/powerpc/include/asm/kvm_e500.h linux-3.0-rc7-libre/arch/powerpc/include/asm/kvm_e500.h
--- linux-2.6.39-libre/arch/powerpc/include/asm/kvm_e500.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/include/asm/kvm_e500.h	2011-07-11 19:51:52.000000000 -0400
@@ -43,6 +43,7 @@
 
 	u32 host_pid[E500_PID_NUM];
 	u32 pid[E500_PID_NUM];
+	u32 svr;
 
 	u32 mas0;
 	u32 mas1;
@@ -58,6 +59,7 @@
 	u32 hid1;
 	u32 tlb0cfg;
 	u32 tlb1cfg;
+	u64 mcar;
 
 	struct kvm_vcpu vcpu;
 };
diff -druN linux-2.6.39-libre/arch/powerpc/include/asm/kvm.h linux-3.0-rc7-libre/arch/powerpc/include/asm/kvm.h
--- linux-2.6.39-libre/arch/powerpc/include/asm/kvm.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/include/asm/kvm.h	2011-07-11 19:51:52.000000000 -0400
@@ -45,6 +45,114 @@
 	__u64 gpr[32];
 };
 
+#define KVM_SREGS_E_IMPL_NONE	0
+#define KVM_SREGS_E_IMPL_FSL	1
+
+#define KVM_SREGS_E_FSL_PIDn	(1 << 0) /* PID1/PID2 */
+
+/*
+ * Feature bits indicate which sections of the sregs struct are valid,
+ * both in KVM_GET_SREGS and KVM_SET_SREGS.  On KVM_SET_SREGS, registers
+ * corresponding to unset feature bits will not be modified.  This allows
+ * restoring a checkpoint made without that feature, while keeping the
+ * default values of the new registers.
+ *
+ * KVM_SREGS_E_BASE contains:
+ * CSRR0/1 (refers to SRR2/3 on 40x)
+ * ESR
+ * DEAR
+ * MCSR
+ * TSR
+ * TCR
+ * DEC
+ * TB
+ * VRSAVE (USPRG0)
+ */
+#define KVM_SREGS_E_BASE		(1 << 0)
+
+/*
+ * KVM_SREGS_E_ARCH206 contains:
+ *
+ * PIR
+ * MCSRR0/1
+ * DECAR
+ * IVPR
+ */
+#define KVM_SREGS_E_ARCH206		(1 << 1)
+
+/*
+ * Contains EPCR, plus the upper half of 64-bit registers
+ * that are 32-bit on 32-bit implementations.
+ */
+#define KVM_SREGS_E_64			(1 << 2)
+
+#define KVM_SREGS_E_SPRG8		(1 << 3)
+#define KVM_SREGS_E_MCIVPR		(1 << 4)
+
+/*
+ * IVORs are used -- contains IVOR0-15, plus additional IVORs
+ * in combination with an appropriate feature bit.
+ */
+#define KVM_SREGS_E_IVOR		(1 << 5)
+
+/*
+ * Contains MAS0-4, MAS6-7, TLBnCFG, MMUCFG.
+ * Also TLBnPS if MMUCFG[MAVN] = 1.
+ */
+#define KVM_SREGS_E_ARCH206_MMU		(1 << 6)
+
+/* DBSR, DBCR, IAC, DAC, DVC */
+#define KVM_SREGS_E_DEBUG		(1 << 7)
+
+/* Enhanced debug -- DSRR0/1, SPRG9 */
+#define KVM_SREGS_E_ED			(1 << 8)
+
+/* Embedded Floating Point (SPE) -- IVOR32-34 if KVM_SREGS_E_IVOR */
+#define KVM_SREGS_E_SPE			(1 << 9)
+
+/* External Proxy (EXP) -- EPR */
+#define KVM_SREGS_EXP			(1 << 10)
+
+/* External PID (E.PD) -- EPSC/EPLC */
+#define KVM_SREGS_E_PD			(1 << 11)
+
+/* Processor Control (E.PC) -- IVOR36-37 if KVM_SREGS_E_IVOR */
+#define KVM_SREGS_E_PC			(1 << 12)
+
+/* Page table (E.PT) -- EPTCFG */
+#define KVM_SREGS_E_PT			(1 << 13)
+
+/* Embedded Performance Monitor (E.PM) -- IVOR35 if KVM_SREGS_E_IVOR */
+#define KVM_SREGS_E_PM			(1 << 14)
+
+/*
+ * Special updates:
+ *
+ * Some registers may change even while a vcpu is not running.
+ * To avoid losing these changes, by default these registers are
+ * not updated by KVM_SET_SREGS.  To force an update, set the bit
+ * in u.e.update_special corresponding to the register to be updated.
+ *
+ * The update_special field is zero on return from KVM_GET_SREGS.
+ *
+ * When restoring a checkpoint, the caller can set update_special
+ * to 0xffffffff to ensure that everything is restored, even new features
+ * that the caller doesn't know about.
+ */
+#define KVM_SREGS_E_UPDATE_MCSR		(1 << 0)
+#define KVM_SREGS_E_UPDATE_TSR		(1 << 1)
+#define KVM_SREGS_E_UPDATE_DEC		(1 << 2)
+#define KVM_SREGS_E_UPDATE_DBSR		(1 << 3)
+
+/*
+ * In KVM_SET_SREGS, reserved/pad fields must be left untouched from a
+ * previous KVM_GET_REGS.
+ *
+ * Unless otherwise indicated, setting any register with KVM_SET_SREGS
+ * directly sets its value.  It does not trigger any special semantics such
+ * as write-one-to-clear.  Calling KVM_SET_SREGS on an unmodified struct
+ * just received from KVM_GET_SREGS is always a no-op.
+ */
 struct kvm_sregs {
 	__u32 pvr;
 	union {
@@ -62,6 +170,82 @@
 				__u64 dbat[8]; 
 			} ppc32;
 		} s;
+		struct {
+			union {
+				struct { /* KVM_SREGS_E_IMPL_FSL */
+					__u32 features; /* KVM_SREGS_E_FSL_ */
+					__u32 svr;
+					__u64 mcar;
+					__u32 hid0;
+
+					/* KVM_SREGS_E_FSL_PIDn */
+					__u32 pid1, pid2;
+				} fsl;
+				__u8 pad[256];
+			} impl;
+
+			__u32 features; /* KVM_SREGS_E_ */
+			__u32 impl_id;	/* KVM_SREGS_E_IMPL_ */
+			__u32 update_special; /* KVM_SREGS_E_UPDATE_ */
+			__u32 pir;	/* read-only */
+			__u64 sprg8;
+			__u64 sprg9;	/* E.ED */
+			__u64 csrr0;
+			__u64 dsrr0;	/* E.ED */
+			__u64 mcsrr0;
+			__u32 csrr1;
+			__u32 dsrr1;	/* E.ED */
+			__u32 mcsrr1;
+			__u32 esr;
+			__u64 dear;
+			__u64 ivpr;
+			__u64 mcivpr;
+			__u64 mcsr;	/* KVM_SREGS_E_UPDATE_MCSR */
+
+			__u32 tsr;	/* KVM_SREGS_E_UPDATE_TSR */
+			__u32 tcr;
+			__u32 decar;
+			__u32 dec;	/* KVM_SREGS_E_UPDATE_DEC */
+
+			/*
+			 * Userspace can read TB directly, but the
+			 * value reported here is consistent with "dec".
+			 *
+			 * Read-only.
+			 */
+			__u64 tb;
+
+			__u32 dbsr;	/* KVM_SREGS_E_UPDATE_DBSR */
+			__u32 dbcr[3];
+			__u32 iac[4];
+			__u32 dac[2];
+			__u32 dvc[2];
+			__u8 num_iac;	/* read-only */
+			__u8 num_dac;	/* read-only */
+			__u8 num_dvc;	/* read-only */
+			__u8 pad;
+
+			__u32 epr;	/* EXP */
+			__u32 vrsave;	/* a.k.a. USPRG0 */
+			__u32 epcr;	/* KVM_SREGS_E_64 */
+
+			__u32 mas0;
+			__u32 mas1;
+			__u64 mas2;
+			__u64 mas7_3;
+			__u32 mas4;
+			__u32 mas6;
+
+			__u32 ivor_low[16]; /* IVOR0-15 */
+			__u32 ivor_high[18]; /* IVOR32+, plus room to expand */
+
+			__u32 mmucfg;	/* read-only */
+			__u32 eptcfg;	/* E.PT, read-only */
+			__u32 tlbcfg[4];/* read-only */
+			__u32 tlbps[4]; /* read-only */
+
+			__u32 eplc, epsc; /* E.PD */
+		} e;
 		__u8 pad[1020];
 	} u;
 };
diff -druN linux-2.6.39-libre/arch/powerpc/include/asm/kvm_host.h linux-3.0-rc7-libre/arch/powerpc/include/asm/kvm_host.h
--- linux-2.6.39-libre/arch/powerpc/include/asm/kvm_host.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/include/asm/kvm_host.h	2011-07-11 19:51:52.000000000 -0400
@@ -223,6 +223,7 @@
 	ulong hflags;
 	ulong guest_owned_ext;
 #endif
+	u32 vrsave; /* also USPRG0 */
 	u32 mmucr;
 	ulong sprg4;
 	ulong sprg5;
@@ -232,6 +233,9 @@
 	ulong csrr1;
 	ulong dsrr0;
 	ulong dsrr1;
+	ulong mcsrr0;
+	ulong mcsrr1;
+	ulong mcsr;
 	ulong esr;
 	u32 dec;
 	u32 decar;
@@ -255,6 +259,7 @@
 	u32 dbsr;
 
 #ifdef CONFIG_KVM_EXIT_TIMING
+	struct mutex exit_timing_lock;
 	struct kvmppc_exit_timing timing_exit;
 	struct kvmppc_exit_timing timing_last_enter;
 	u32 last_exit_type;
diff -druN linux-2.6.39-libre/arch/powerpc/include/asm/kvm_ppc.h linux-3.0-rc7-libre/arch/powerpc/include/asm/kvm_ppc.h
--- linux-2.6.39-libre/arch/powerpc/include/asm/kvm_ppc.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/include/asm/kvm_ppc.h	2011-07-11 19:51:52.000000000 -0400
@@ -61,6 +61,7 @@
                                       struct kvm_vcpu *vcpu);
 extern int kvmppc_emulate_mmio(struct kvm_run *run, struct kvm_vcpu *vcpu);
 extern void kvmppc_emulate_dec(struct kvm_vcpu *vcpu);
+extern u32 kvmppc_get_dec(struct kvm_vcpu *vcpu, u64 tb);
 
 /* Core-specific hooks */
 
@@ -142,4 +143,12 @@
 	return r;
 }
 
+void kvmppc_core_get_sregs(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs);
+int kvmppc_core_set_sregs(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs);
+
+void kvmppc_get_sregs_ivor(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs);
+int kvmppc_set_sregs_ivor(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs);
+
+void kvmppc_set_pid(struct kvm_vcpu *vcpu, u32 pid);
+
 #endif /* __POWERPC_KVM_PPC_H__ */
diff -druN linux-2.6.39-libre/arch/powerpc/include/asm/lppaca.h linux-3.0-rc7-libre/arch/powerpc/include/asm/lppaca.h
--- linux-2.6.39-libre/arch/powerpc/include/asm/lppaca.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/include/asm/lppaca.h	2011-07-11 19:51:52.000000000 -0400
@@ -210,6 +210,8 @@
 #define DISPATCH_LOG_BYTES	4096	/* bytes per cpu */
 #define N_DISPATCH_LOG		(DISPATCH_LOG_BYTES / sizeof(struct dtl_entry))
 
+extern struct kmem_cache *dtl_cache;
+
 /*
  * When CONFIG_VIRT_CPU_ACCOUNTING = y, the cpu accounting code controls
  * reading from the dispatch trace log.  If other code wants to consume
diff -druN linux-2.6.39-libre/arch/powerpc/include/asm/machdep.h linux-3.0-rc7-libre/arch/powerpc/include/asm/machdep.h
--- linux-2.6.39-libre/arch/powerpc/include/asm/machdep.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/include/asm/machdep.h	2011-07-11 19:51:52.000000000 -0400
@@ -29,21 +29,6 @@
 struct pci_controller;
 struct kimage;
 
-#ifdef CONFIG_SMP
-struct smp_ops_t {
-	void  (*message_pass)(int target, int msg);
-	int   (*probe)(void);
-	void  (*kick_cpu)(int nr);
-	void  (*setup_cpu)(int nr);
-	void  (*bringup_done)(void);
-	void  (*take_timebase)(void);
-	void  (*give_timebase)(void);
-	int   (*cpu_disable)(void);
-	void  (*cpu_die)(unsigned int nr);
-	int   (*cpu_bootable)(unsigned int nr);
-};
-#endif
-
 struct machdep_calls {
 	char		*name;
 #ifdef CONFIG_PPC64
@@ -267,6 +252,7 @@
 
 extern void e500_idle(void);
 extern void power4_idle(void);
+extern void power7_idle(void);
 extern void ppc6xx_idle(void);
 extern void book3e_idle(void);
 
@@ -311,12 +297,6 @@
 
 #endif /* CONFIG_PPC_PMAC */
 
-#ifdef CONFIG_SMP
-/* Poor default implementations */
-extern void __devinit smp_generic_give_timebase(void);
-extern void __devinit smp_generic_take_timebase(void);
-#endif /* CONFIG_SMP */
-
 
 /* Functions to produce codes on the leds.
  * The SRC code should be unique for the message category and should
diff -druN linux-2.6.39-libre/arch/powerpc/include/asm/mmu-book3e.h linux-3.0-rc7-libre/arch/powerpc/include/asm/mmu-book3e.h
--- linux-2.6.39-libre/arch/powerpc/include/asm/mmu-book3e.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/include/asm/mmu-book3e.h	2011-07-11 19:51:52.000000000 -0400
@@ -43,6 +43,7 @@
 #define MAS0_TLBSEL(x)		(((x) << 28) & 0x30000000)
 #define MAS0_ESEL(x)		(((x) << 16) & 0x0FFF0000)
 #define MAS0_NV(x)		((x) & 0x00000FFF)
+#define MAS0_ESEL_MASK		0x0FFF0000
 #define MAS0_HES		0x00004000
 #define MAS0_WQ_ALLWAYS		0x00000000
 #define MAS0_WQ_COND		0x00001000
@@ -137,6 +138,21 @@
 #define MMUCSR0_TLB2PS	0x00078000	/* TLB2 Page Size */
 #define MMUCSR0_TLB3PS	0x00780000	/* TLB3 Page Size */
 
+/* MMUCFG bits */
+#define MMUCFG_MAVN_NASK	0x00000003
+#define MMUCFG_MAVN_V1_0	0x00000000
+#define MMUCFG_MAVN_V2_0	0x00000001
+#define MMUCFG_NTLB_MASK	0x0000000c
+#define MMUCFG_NTLB_SHIFT	2
+#define MMUCFG_PIDSIZE_MASK	0x000007c0
+#define MMUCFG_PIDSIZE_SHIFT	6
+#define MMUCFG_TWC		0x00008000
+#define MMUCFG_LRAT		0x00010000
+#define MMUCFG_RASIZE_MASK	0x00fe0000
+#define MMUCFG_RASIZE_SHIFT	17
+#define MMUCFG_LPIDSIZE_MASK	0x0f000000
+#define MMUCFG_LPIDSIZE_SHIFT	24
+
 /* TLBnCFG encoding */
 #define TLBnCFG_N_ENTRY		0x00000fff	/* number of entries */
 #define TLBnCFG_HES		0x00002000	/* HW select supported */
@@ -229,6 +245,10 @@
 extern int mmu_linear_psize;
 extern int mmu_vmemmap_psize;
 
+#ifdef CONFIG_PPC64
+extern unsigned long linear_map_top;
+#endif
+
 #endif /* !__ASSEMBLY__ */
 
 #endif /* _ASM_POWERPC_MMU_BOOK3E_H_ */
diff -druN linux-2.6.39-libre/arch/powerpc/include/asm/mmu_context.h linux-3.0-rc7-libre/arch/powerpc/include/asm/mmu_context.h
--- linux-2.6.39-libre/arch/powerpc/include/asm/mmu_context.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/include/asm/mmu_context.h	2011-07-11 19:51:52.000000000 -0400
@@ -32,6 +32,10 @@
 extern void mmu_context_init(void);
 #endif
 
+extern void switch_cop(struct mm_struct *next);
+extern int use_cop(unsigned long acop, struct mm_struct *mm);
+extern void drop_cop(unsigned long acop, struct mm_struct *mm);
+
 /*
  * switch_mm is the entry point called from the architecture independent
  * code in kernel/sched.c
@@ -55,6 +59,12 @@
 	if (prev == next)
 		return;
 
+#ifdef CONFIG_PPC_ICSWX
+	/* Switch coprocessor context only if prev or next uses a coprocessor */
+	if (prev->context.acop || next->context.acop)
+		switch_cop(next);
+#endif /* CONFIG_PPC_ICSWX */
+
 	/* We must stop all altivec streams before changing the HW
 	 * context
 	 */
@@ -67,7 +77,7 @@
 	 * sub architectures.
 	 */
 #ifdef CONFIG_PPC_STD_MMU_64
-	if (cpu_has_feature(CPU_FTR_SLB))
+	if (mmu_has_feature(MMU_FTR_SLB))
 		switch_slb(tsk, next);
 	else
 		switch_stab(tsk, next);
diff -druN linux-2.6.39-libre/arch/powerpc/include/asm/mmu.h linux-3.0-rc7-libre/arch/powerpc/include/asm/mmu.h
--- linux-2.6.39-libre/arch/powerpc/include/asm/mmu.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/include/asm/mmu.h	2011-07-11 19:51:52.000000000 -0400
@@ -56,11 +56,6 @@
  */
 #define MMU_FTR_NEED_DTLB_SW_LRU	ASM_CONST(0x00200000)
 
-/* This indicates that the processor uses the ISA 2.06 server tlbie
- * mnemonics
- */
-#define MMU_FTR_TLBIE_206		ASM_CONST(0x00400000)
-
 /* Enable use of TLB reservation.  Processor should support tlbsrx.
  * instruction and MAS0[WQ].
  */
@@ -70,6 +65,53 @@
  */
 #define MMU_FTR_USE_PAIRED_MAS		ASM_CONST(0x01000000)
 
+/* MMU is SLB-based
+ */
+#define MMU_FTR_SLB			ASM_CONST(0x02000000)
+
+/* Support 16M large pages
+ */
+#define MMU_FTR_16M_PAGE		ASM_CONST(0x04000000)
+
+/* Supports TLBIEL variant
+ */
+#define MMU_FTR_TLBIEL			ASM_CONST(0x08000000)
+
+/* Supports tlbies w/o locking
+ */
+#define MMU_FTR_LOCKLESS_TLBIE		ASM_CONST(0x10000000)
+
+/* Large pages can be marked CI
+ */
+#define MMU_FTR_CI_LARGE_PAGE		ASM_CONST(0x20000000)
+
+/* 1T segments available
+ */
+#define MMU_FTR_1T_SEGMENT		ASM_CONST(0x40000000)
+
+/* Doesn't support the B bit (1T segment) in SLBIE
+ */
+#define MMU_FTR_NO_SLBIE_B		ASM_CONST(0x80000000)
+
+/* MMU feature bit sets for various CPUs */
+#define MMU_FTRS_DEFAULT_HPTE_ARCH_V2	\
+	MMU_FTR_HPTE_TABLE | MMU_FTR_PPCAS_ARCH_V2
+#define MMU_FTRS_POWER4		MMU_FTRS_DEFAULT_HPTE_ARCH_V2
+#define MMU_FTRS_PPC970		MMU_FTRS_POWER4
+#define MMU_FTRS_POWER5		MMU_FTRS_POWER4 | MMU_FTR_LOCKLESS_TLBIE
+#define MMU_FTRS_POWER6		MMU_FTRS_POWER4 | MMU_FTR_LOCKLESS_TLBIE
+#define MMU_FTRS_POWER7		MMU_FTRS_POWER4 | MMU_FTR_LOCKLESS_TLBIE
+#define MMU_FTRS_CELL		MMU_FTRS_DEFAULT_HPTE_ARCH_V2 | \
+				MMU_FTR_CI_LARGE_PAGE
+#define MMU_FTRS_PA6T		MMU_FTRS_DEFAULT_HPTE_ARCH_V2 | \
+				MMU_FTR_CI_LARGE_PAGE | MMU_FTR_NO_SLBIE_B
+#define MMU_FTRS_A2		MMU_FTR_TYPE_3E | MMU_FTR_USE_TLBILX | \
+				MMU_FTR_USE_TLBIVAX_BCAST | \
+				MMU_FTR_LOCK_BCAST_INVAL | \
+				MMU_FTR_USE_TLBRSRV | \
+				MMU_FTR_USE_PAIRED_MAS | \
+				MMU_FTR_TLBIEL | \
+				MMU_FTR_16M_PAGE
 #ifndef __ASSEMBLY__
 #include <asm/cputable.h>
 
diff -druN linux-2.6.39-libre/arch/powerpc/include/asm/mmu-hash64.h linux-3.0-rc7-libre/arch/powerpc/include/asm/mmu-hash64.h
--- linux-2.6.39-libre/arch/powerpc/include/asm/mmu-hash64.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/include/asm/mmu-hash64.h	2011-07-11 19:51:52.000000000 -0400
@@ -408,6 +408,7 @@
 #endif /* CONFIG_PPC_SUBPAGE_PROT */
 
 typedef unsigned long mm_context_id_t;
+struct spinlock;
 
 typedef struct {
 	mm_context_id_t id;
@@ -423,6 +424,11 @@
 #ifdef CONFIG_PPC_SUBPAGE_PROT
 	struct subpage_prot_table spt;
 #endif /* CONFIG_PPC_SUBPAGE_PROT */
+#ifdef CONFIG_PPC_ICSWX
+	struct spinlock *cop_lockp; /* guard acop and cop_pid */
+	unsigned long acop;	/* mask of enabled coprocessor types */
+	unsigned int cop_pid;	/* pid value used with coprocessors */
+#endif /* CONFIG_PPC_ICSWX */
 } mm_context_t;
 
 
diff -druN linux-2.6.39-libre/arch/powerpc/include/asm/mmzone.h linux-3.0-rc7-libre/arch/powerpc/include/asm/mmzone.h
--- linux-2.6.39-libre/arch/powerpc/include/asm/mmzone.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/include/asm/mmzone.h	2011-07-11 19:51:52.000000000 -0400
@@ -38,13 +38,6 @@
 #define memory_hotplug_max() memblock_end_of_DRAM()
 #endif
 
-/*
- * Following are macros that each numa implmentation must define.
- */
-
-#define node_start_pfn(nid)	(NODE_DATA(nid)->node_start_pfn)
-#define node_end_pfn(nid)	(NODE_DATA(nid)->node_end_pfn)
-
 #else
 #define memory_hotplug_max() memblock_end_of_DRAM()
 #endif /* CONFIG_NEED_MULTIPLE_NODES */
diff -druN linux-2.6.39-libre/arch/powerpc/include/asm/mpic.h linux-3.0-rc7-libre/arch/powerpc/include/asm/mpic.h
--- linux-2.6.39-libre/arch/powerpc/include/asm/mpic.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/include/asm/mpic.h	2011-07-11 19:51:52.000000000 -0400
@@ -3,7 +3,6 @@
 #ifdef __KERNEL__
 
 #include <linux/irq.h>
-#include <linux/sysdev.h>
 #include <asm/dcr.h>
 #include <asm/msi_bitmap.h>
 
@@ -263,6 +262,7 @@
 #ifdef CONFIG_SMP
 	struct irq_chip		hc_ipi;
 #endif
+	struct irq_chip		hc_tm;
 	const char		*name;
 	/* Flags */
 	unsigned int		flags;
@@ -281,7 +281,7 @@
 
 	/* vector numbers used for internal sources (ipi/timers) */
 	unsigned int		ipi_vecs[4];
-	unsigned int		timer_vecs[4];
+	unsigned int		timer_vecs[8];
 
 	/* Spurious vector to program into unused sources */
 	unsigned int		spurious_vec;
@@ -320,8 +320,6 @@
 	/* link */
 	struct mpic		*next;
 
-	struct sys_device	sysdev;
-
 #ifdef CONFIG_PM
 	struct mpic_irq_save	*save_data;
 #endif
@@ -371,6 +369,8 @@
  * NOTE: This flag trumps MPIC_WANTS_RESET.
  */
 #define MPIC_NO_RESET			0x00004000
+/* Freescale MPIC (compatible includes "fsl,mpic") */
+#define MPIC_FSL			0x00008000
 
 /* MPIC HW modification ID */
 #define MPIC_REGSET_MASK		0xf0000000
diff -druN linux-2.6.39-libre/arch/powerpc/include/asm/paca.h linux-3.0-rc7-libre/arch/powerpc/include/asm/paca.h
--- linux-2.6.39-libre/arch/powerpc/include/asm/paca.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/include/asm/paca.h	2011-07-11 19:51:52.000000000 -0400
@@ -92,9 +92,9 @@
 	 * Now, starting in cacheline 2, the exception save areas
 	 */
 	/* used for most interrupts/exceptions */
-	u64 exgen[10] __attribute__((aligned(0x80)));
-	u64 exmc[10];		/* used for machine checks */
-	u64 exslb[10];		/* used for SLB/segment table misses
+	u64 exgen[11] __attribute__((aligned(0x80)));
+	u64 exmc[11];		/* used for machine checks */
+	u64 exslb[11];		/* used for SLB/segment table misses
  				 * on the linear mapping */
 	/* SLB related definitions */
 	u16 vmalloc_sllp;
@@ -106,7 +106,8 @@
 	pgd_t *pgd;			/* Current PGD */
 	pgd_t *kernel_pgd;		/* Kernel PGD */
 	u64 exgen[8] __attribute__((aligned(0x80)));
-	u64 extlb[EX_TLB_SIZE*3] __attribute__((aligned(0x80)));
+	/* We can have up to 3 levels of reentrancy in the TLB miss handler */
+	u64 extlb[3][EX_TLB_SIZE / sizeof(u64)] __attribute__((aligned(0x80)));
 	u64 exmc[8];		/* used for machine checks */
 	u64 excrit[8];		/* used for crit interrupts */
 	u64 exdbg[8];		/* used for debug interrupts */
@@ -125,7 +126,7 @@
 	struct task_struct *__current;	/* Pointer to current */
 	u64 kstack;			/* Saved Kernel stack addr */
 	u64 stab_rr;			/* stab/slb round-robin counter */
-	u64 saved_r1;			/* r1 save for RTAS calls */
+	u64 saved_r1;			/* r1 save for RTAS calls or PM */
 	u64 saved_msr;			/* MSR saved here by enter_rtas */
 	u16 trap_save;			/* Used when bad stack is encountered */
 	u8 soft_enabled;		/* irq soft-enable flag */
diff -druN linux-2.6.39-libre/arch/powerpc/include/asm/page_64.h linux-3.0-rc7-libre/arch/powerpc/include/asm/page_64.h
--- linux-2.6.39-libre/arch/powerpc/include/asm/page_64.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/include/asm/page_64.h	2011-07-11 19:51:52.000000000 -0400
@@ -59,24 +59,7 @@
 	: "ctr", "memory");
 }
 
-extern void copy_4K_page(void *to, void *from);
-
-#ifdef CONFIG_PPC_64K_PAGES
-static inline void copy_page(void *to, void *from)
-{
-	unsigned int i;
-	for (i=0; i < (1 << (PAGE_SHIFT - 12)); i++) {
-		copy_4K_page(to, from);
-		to += 4096;
-		from += 4096;
-	}
-}
-#else /* CONFIG_PPC_64K_PAGES */
-static inline void copy_page(void *to, void *from)
-{
-	copy_4K_page(to, from);
-}
-#endif /* CONFIG_PPC_64K_PAGES */
+extern void copy_page(void *to, void *from);
 
 /* Log 2 of page table size */
 extern u64 ppc64_pft_size;
@@ -130,7 +113,7 @@
 extern void slice_set_range_psize(struct mm_struct *mm, unsigned long start,
 				  unsigned long len, unsigned int psize);
 
-#define slice_mm_new_context(mm)	((mm)->context.id == 0)
+#define slice_mm_new_context(mm)	((mm)->context.id == MMU_NO_CONTEXT)
 
 #endif /* __ASSEMBLY__ */
 #else
diff -druN linux-2.6.39-libre/arch/powerpc/include/asm/pgalloc.h linux-3.0-rc7-libre/arch/powerpc/include/asm/pgalloc.h
--- linux-2.6.39-libre/arch/powerpc/include/asm/pgalloc.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/include/asm/pgalloc.h	2011-07-11 19:51:52.000000000 -0400
@@ -31,14 +31,29 @@
 #endif
 
 #ifdef CONFIG_SMP
-extern void pgtable_free_tlb(struct mmu_gather *tlb, void *table, unsigned shift);
-extern void pte_free_finish(void);
+struct mmu_gather;
+extern void tlb_remove_table(struct mmu_gather *, void *);
+
+static inline void pgtable_free_tlb(struct mmu_gather *tlb, void *table, int shift)
+{
+	unsigned long pgf = (unsigned long)table;
+	BUG_ON(shift > MAX_PGTABLE_INDEX_SIZE);
+	pgf |= shift;
+	tlb_remove_table(tlb, (void *)pgf);
+}
+
+static inline void __tlb_remove_table(void *_table)
+{
+	void *table = (void *)((unsigned long)_table & ~MAX_PGTABLE_INDEX_SIZE);
+	unsigned shift = (unsigned long)_table & MAX_PGTABLE_INDEX_SIZE;
+
+	pgtable_free(table, shift);
+}
 #else /* CONFIG_SMP */
 static inline void pgtable_free_tlb(struct mmu_gather *tlb, void *table, unsigned shift)
 {
 	pgtable_free(table, shift);
 }
-static inline void pte_free_finish(void) { }
 #endif /* !CONFIG_SMP */
 
 static inline void __pte_free_tlb(struct mmu_gather *tlb, struct page *ptepage,
diff -druN linux-2.6.39-libre/arch/powerpc/include/asm/pgtable-ppc64.h linux-3.0-rc7-libre/arch/powerpc/include/asm/pgtable-ppc64.h
--- linux-2.6.39-libre/arch/powerpc/include/asm/pgtable-ppc64.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/include/asm/pgtable-ppc64.h	2011-07-11 19:51:52.000000000 -0400
@@ -257,21 +257,20 @@
 static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr,
 				      pte_t *ptep)
 {
-	unsigned long old;
 
-       	if ((pte_val(*ptep) & _PAGE_RW) == 0)
-       		return;
-	old = pte_update(mm, addr, ptep, _PAGE_RW, 0);
+	if ((pte_val(*ptep) & _PAGE_RW) == 0)
+		return;
+
+	pte_update(mm, addr, ptep, _PAGE_RW, 0);
 }
 
 static inline void huge_ptep_set_wrprotect(struct mm_struct *mm,
 					   unsigned long addr, pte_t *ptep)
 {
-	unsigned long old;
-
 	if ((pte_val(*ptep) & _PAGE_RW) == 0)
 		return;
-	old = pte_update(mm, addr, ptep, _PAGE_RW, 1);
+
+	pte_update(mm, addr, ptep, _PAGE_RW, 1);
 }
 
 /*
diff -druN linux-2.6.39-libre/arch/powerpc/include/asm/ppc_asm.h linux-3.0-rc7-libre/arch/powerpc/include/asm/ppc_asm.h
--- linux-2.6.39-libre/arch/powerpc/include/asm/ppc_asm.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/include/asm/ppc_asm.h	2011-07-11 19:51:52.000000000 -0400
@@ -170,6 +170,7 @@
 #define HMT_MEDIUM	or	2,2,2
 #define HMT_MEDIUM_HIGH or	5,5,5		# medium high priority
 #define HMT_HIGH	or	3,3,3
+#define HMT_EXTRA_HIGH	or	7,7,7		# power7 only
 
 #ifdef __KERNEL__
 #ifdef CONFIG_PPC64
diff -druN linux-2.6.39-libre/arch/powerpc/include/asm/ppc-opcode.h linux-3.0-rc7-libre/arch/powerpc/include/asm/ppc-opcode.h
--- linux-2.6.39-libre/arch/powerpc/include/asm/ppc-opcode.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/include/asm/ppc-opcode.h	2011-07-11 19:51:52.000000000 -0400
@@ -41,6 +41,10 @@
 #define PPC_INST_RFCI			0x4c000066
 #define PPC_INST_RFDI			0x4c00004e
 #define PPC_INST_RFMCI			0x4c00004c
+#define PPC_INST_MFSPR_DSCR		0x7c1102a6
+#define PPC_INST_MFSPR_DSCR_MASK	0xfc1fffff
+#define PPC_INST_MTSPR_DSCR		0x7c1103a6
+#define PPC_INST_MTSPR_DSCR_MASK	0xfc1fffff
 
 #define PPC_INST_STRING			0x7c00042a
 #define PPC_INST_STRING_MASK		0xfc0007fe
@@ -56,6 +60,17 @@
 #define PPC_INST_TLBSRX_DOT		0x7c0006a5
 #define PPC_INST_XXLOR			0xf0000510
 
+#define PPC_INST_NAP			0x4c000364
+#define PPC_INST_SLEEP			0x4c0003a4
+
+/* A2 specific instructions */
+#define PPC_INST_ERATWE			0x7c0001a6
+#define PPC_INST_ERATRE			0x7c000166
+#define PPC_INST_ERATILX		0x7c000066
+#define PPC_INST_ERATIVAX		0x7c000666
+#define PPC_INST_ERATSX			0x7c000126
+#define PPC_INST_ERATSX_DOT		0x7c000127
+
 /* macros to insert fields into opcodes */
 #define __PPC_RA(a)	(((a) & 0x1f) << 16)
 #define __PPC_RB(b)	(((b) & 0x1f) << 11)
@@ -67,6 +82,8 @@
 #define __PPC_XT(s)	__PPC_XS(s)
 #define __PPC_T_TLB(t)	(((t) & 0x3) << 21)
 #define __PPC_WC(w)	(((w) & 0x3) << 21)
+#define __PPC_WS(w)	(((w) & 0x1f) << 11)
+
 /*
  * Only use the larx hint bit on 64bit CPUs. e500v1/v2 based CPUs will treat a
  * larx with EH set as an illegal instruction.
@@ -113,6 +130,21 @@
 #define PPC_TLBIVAX(a,b)	stringify_in_c(.long PPC_INST_TLBIVAX | \
 					__PPC_RA(a) | __PPC_RB(b))
 
+#define PPC_ERATWE(s, a, w)	stringify_in_c(.long PPC_INST_ERATWE | \
+					__PPC_RS(s) | __PPC_RA(a) | __PPC_WS(w))
+#define PPC_ERATRE(s, a, w)	stringify_in_c(.long PPC_INST_ERATRE | \
+					__PPC_RS(s) | __PPC_RA(a) | __PPC_WS(w))
+#define PPC_ERATILX(t, a, b)	stringify_in_c(.long PPC_INST_ERATILX | \
+					__PPC_T_TLB(t) | __PPC_RA(a) | \
+					__PPC_RB(b))
+#define PPC_ERATIVAX(s, a, b)	stringify_in_c(.long PPC_INST_ERATIVAX | \
+					__PPC_RS(s) | __PPC_RA(a) | __PPC_RB(b))
+#define PPC_ERATSX(t, a, w)	stringify_in_c(.long PPC_INST_ERATSX | \
+					__PPC_RS(t) | __PPC_RA(a) | __PPC_RB(b))
+#define PPC_ERATSX_DOT(t, a, w)	stringify_in_c(.long PPC_INST_ERATSX_DOT | \
+					__PPC_RS(t) | __PPC_RA(a) | __PPC_RB(b))
+
+
 /*
  * Define what the VSX XX1 form instructions will look like, then add
  * the 128 bit load store instructions based on that.
@@ -126,4 +158,7 @@
 #define XXLOR(t, a, b)		stringify_in_c(.long PPC_INST_XXLOR | \
 					       VSX_XX3((t), (a), (b)))
 
+#define PPC_NAP			stringify_in_c(.long PPC_INST_NAP)
+#define PPC_SLEEP		stringify_in_c(.long PPC_INST_SLEEP)
+
 #endif /* _ASM_POWERPC_PPC_OPCODE_H */
diff -druN linux-2.6.39-libre/arch/powerpc/include/asm/processor.h linux-3.0-rc7-libre/arch/powerpc/include/asm/processor.h
--- linux-2.6.39-libre/arch/powerpc/include/asm/processor.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/include/asm/processor.h	2011-07-11 19:51:52.000000000 -0400
@@ -238,6 +238,10 @@
 #ifdef CONFIG_KVM_BOOK3S_32_HANDLER
 	void*		kvm_shadow_vcpu; /* KVM internal data */
 #endif /* CONFIG_KVM_BOOK3S_32_HANDLER */
+#ifdef CONFIG_PPC64
+	unsigned long	dscr;
+	int		dscr_inherit;
+#endif
 };
 
 #define ARCH_MIN_TASKALIGN 16
diff -druN linux-2.6.39-libre/arch/powerpc/include/asm/pSeries_reconfig.h linux-3.0-rc7-libre/arch/powerpc/include/asm/pSeries_reconfig.h
--- linux-2.6.39-libre/arch/powerpc/include/asm/pSeries_reconfig.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/include/asm/pSeries_reconfig.h	2011-07-11 19:51:52.000000000 -0400
@@ -18,13 +18,18 @@
 extern int pSeries_reconfig_notifier_register(struct notifier_block *);
 extern void pSeries_reconfig_notifier_unregister(struct notifier_block *);
 extern struct blocking_notifier_head pSeries_reconfig_chain;
+/* Not the best place to put this, will be fixed when we move some
+ * of the rtas suspend-me stuff to pseries */
+extern void pSeries_coalesce_init(void);
 #else /* !CONFIG_PPC_PSERIES */
 static inline int pSeries_reconfig_notifier_register(struct notifier_block *nb)
 {
 	return 0;
 }
 static inline void pSeries_reconfig_notifier_unregister(struct notifier_block *nb) { }
+static inline void pSeries_coalesce_init(void) { }
 #endif /* CONFIG_PPC_PSERIES */
 
+
 #endif /* __KERNEL__ */
 #endif /* _PPC64_PSERIES_RECONFIG_H */
diff -druN linux-2.6.39-libre/arch/powerpc/include/asm/pte-hash64-64k.h linux-3.0-rc7-libre/arch/powerpc/include/asm/pte-hash64-64k.h
--- linux-2.6.39-libre/arch/powerpc/include/asm/pte-hash64-64k.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/include/asm/pte-hash64-64k.h	2011-07-11 19:51:52.000000000 -0400
@@ -22,7 +22,7 @@
 #define _PAGE_HASHPTE	_PAGE_HPTE_SUB
 
 /* Note the full page bits must be in the same location as for normal
- * 4k pages as the same asssembly will be used to insert 64K pages
+ * 4k pages as the same assembly will be used to insert 64K pages
  * wether the kernel has CONFIG_PPC_64K_PAGES or not
  */
 #define _PAGE_F_SECOND  0x00008000 /* full page: hidx bits */
diff -druN linux-2.6.39-libre/arch/powerpc/include/asm/reg_a2.h linux-3.0-rc7-libre/arch/powerpc/include/asm/reg_a2.h
--- linux-2.6.39-libre/arch/powerpc/include/asm/reg_a2.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/powerpc/include/asm/reg_a2.h	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,165 @@
+/*
+ *  Register definitions specific to the A2 core
+ *
+ *  Copyright (C) 2008 Ben. Herrenschmidt (benh@kernel.crashing.org), IBM Corp.
+ *
+ *  This program is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU General Public License
+ *  as published by the Free Software Foundation; either version
+ *  2 of the License, or (at your option) any later version.
+ */
+
+#ifndef __ASM_POWERPC_REG_A2_H__
+#define __ASM_POWERPC_REG_A2_H__
+
+#define SPRN_TENSR	0x1b5
+#define SPRN_TENS	0x1b6	/* Thread ENable Set */
+#define SPRN_TENC	0x1b7	/* Thread ENable Clear */
+
+#define SPRN_A2_CCR0	0x3f0	/* Core Configuration Register 0 */
+#define SPRN_A2_CCR1	0x3f1	/* Core Configuration Register 1 */
+#define SPRN_A2_CCR2	0x3f2	/* Core Configuration Register 2 */
+#define SPRN_MMUCR0	0x3fc	/* MMU Control Register 0 */
+#define SPRN_MMUCR1	0x3fd	/* MMU Control Register 1 */
+#define SPRN_MMUCR2	0x3fe	/* MMU Control Register 2 */
+#define SPRN_MMUCR3	0x3ff	/* MMU Control Register 3 */
+
+#define SPRN_IAR	0x372
+
+#define SPRN_IUCR0	0x3f3
+#define IUCR0_ICBI_ACK	0x1000
+
+#define SPRN_XUCR0	0x3f6	/* Execution Unit Config Register 0 */
+
+#define A2_IERAT_SIZE	16
+#define A2_DERAT_SIZE	32
+
+/* A2 MMUCR0 bits */
+#define MMUCR0_ECL	0x80000000	/* Extended Class for TLB fills */
+#define MMUCR0_TID_NZ	0x40000000	/* TID is non-zero */
+#define MMUCR0_TS	0x10000000	/* Translation space for TLB fills */
+#define MMUCR0_TGS	0x20000000	/* Guest space for TLB fills */
+#define MMUCR0_TLBSEL	0x0c000000	/* TLB or ERAT target for TLB fills */
+#define MMUCR0_TLBSEL_U	0x00000000	/*  TLBSEL = UTLB */
+#define MMUCR0_TLBSEL_I	0x08000000	/*  TLBSEL = I-ERAT */
+#define MMUCR0_TLBSEL_D	0x0c000000	/*  TLBSEL = D-ERAT */
+#define MMUCR0_LOCKSRSH	0x02000000	/* Use TLB lock on tlbsx. */
+#define MMUCR0_TID_MASK	0x000000ff	/* TID field */
+
+/* A2 MMUCR1 bits */
+#define MMUCR1_IRRE		0x80000000	/* I-ERAT round robin enable */
+#define MMUCR1_DRRE		0x40000000	/* D-ERAT round robin enable */
+#define MMUCR1_REE		0x20000000	/* Reference Exception Enable*/
+#define MMUCR1_CEE		0x10000000	/* Change exception enable */
+#define MMUCR1_CSINV_ALL	0x00000000	/* Inval ERAT on all CS evts */
+#define MMUCR1_CSINV_NISYNC	0x04000000	/* Inval ERAT on all ex isync*/
+#define MMUCR1_CSINV_NEVER	0x0c000000	/* Don't inval ERAT on CS */
+#define MMUCR1_ICTID		0x00080000	/* IERAT class field as TID */
+#define MMUCR1_ITTID		0x00040000	/* IERAT thdid field as TID */
+#define MMUCR1_DCTID		0x00020000	/* DERAT class field as TID */
+#define MMUCR1_DTTID		0x00010000	/* DERAT thdid field as TID */
+#define MMUCR1_DCCD		0x00008000	/* DERAT class ignore */
+#define MMUCR1_TLBWE_BINV	0x00004000	/* back invalidate on tlbwe */
+
+/* A2 MMUCR2 bits */
+#define MMUCR2_PSSEL_SHIFT	4
+
+/* A2 MMUCR3 bits */
+#define MMUCR3_THID		0x0000000f	/* Thread ID */
+
+/* *** ERAT TLB bits definitions */
+#define TLB0_EPN_MASK		ASM_CONST(0xfffffffffffff000)
+#define TLB0_CLASS_MASK		ASM_CONST(0x0000000000000c00)
+#define TLB0_CLASS_00		ASM_CONST(0x0000000000000000)
+#define TLB0_CLASS_01		ASM_CONST(0x0000000000000400)
+#define TLB0_CLASS_10		ASM_CONST(0x0000000000000800)
+#define TLB0_CLASS_11		ASM_CONST(0x0000000000000c00)
+#define TLB0_V			ASM_CONST(0x0000000000000200)
+#define TLB0_X			ASM_CONST(0x0000000000000100)
+#define TLB0_SIZE_MASK		ASM_CONST(0x00000000000000f0)
+#define TLB0_SIZE_4K		ASM_CONST(0x0000000000000010)
+#define TLB0_SIZE_64K		ASM_CONST(0x0000000000000030)
+#define TLB0_SIZE_1M		ASM_CONST(0x0000000000000050)
+#define TLB0_SIZE_16M		ASM_CONST(0x0000000000000070)
+#define TLB0_SIZE_1G		ASM_CONST(0x00000000000000a0)
+#define TLB0_THDID_MASK		ASM_CONST(0x000000000000000f)
+#define TLB0_THDID_0		ASM_CONST(0x0000000000000001)
+#define TLB0_THDID_1		ASM_CONST(0x0000000000000002)
+#define TLB0_THDID_2		ASM_CONST(0x0000000000000004)
+#define TLB0_THDID_3		ASM_CONST(0x0000000000000008)
+#define TLB0_THDID_ALL		ASM_CONST(0x000000000000000f)
+
+#define TLB1_RESVATTR		ASM_CONST(0x00f0000000000000)
+#define TLB1_U0			ASM_CONST(0x0008000000000000)
+#define TLB1_U1			ASM_CONST(0x0004000000000000)
+#define TLB1_U2			ASM_CONST(0x0002000000000000)
+#define TLB1_U3			ASM_CONST(0x0001000000000000)
+#define TLB1_R			ASM_CONST(0x0000800000000000)
+#define TLB1_C			ASM_CONST(0x0000400000000000)
+#define TLB1_RPN_MASK		ASM_CONST(0x000003fffffff000)
+#define TLB1_W			ASM_CONST(0x0000000000000800)
+#define TLB1_I			ASM_CONST(0x0000000000000400)
+#define TLB1_M			ASM_CONST(0x0000000000000200)
+#define TLB1_G			ASM_CONST(0x0000000000000100)
+#define TLB1_E			ASM_CONST(0x0000000000000080)
+#define TLB1_VF			ASM_CONST(0x0000000000000040)
+#define TLB1_UX			ASM_CONST(0x0000000000000020)
+#define TLB1_SX			ASM_CONST(0x0000000000000010)
+#define TLB1_UW			ASM_CONST(0x0000000000000008)
+#define TLB1_SW			ASM_CONST(0x0000000000000004)
+#define TLB1_UR			ASM_CONST(0x0000000000000002)
+#define TLB1_SR			ASM_CONST(0x0000000000000001)
+
+#ifdef CONFIG_PPC_EARLY_DEBUG_WSP
+#define WSP_UART_PHYS	0xffc000c000
+/* This needs to be careful chosen to hit a !0 congruence class
+ * in the TLB since we bolt it in way 3, which is already occupied
+ * by our linear mapping primary bolted entry in CC 0.
+ */
+#define WSP_UART_VIRT	0xf000000000001000
+#endif
+
+/* A2 erativax attributes definitions */
+#define ERATIVAX_RS_IS_ALL		0x000
+#define ERATIVAX_RS_IS_TID		0x040
+#define ERATIVAX_RS_IS_CLASS		0x080
+#define ERATIVAX_RS_IS_FULLMATCH	0x0c0
+#define ERATIVAX_CLASS_00		0x000
+#define ERATIVAX_CLASS_01		0x010
+#define ERATIVAX_CLASS_10		0x020
+#define ERATIVAX_CLASS_11		0x030
+#define ERATIVAX_PSIZE_4K		(TLB_PSIZE_4K >> 1)
+#define ERATIVAX_PSIZE_64K		(TLB_PSIZE_64K >> 1)
+#define ERATIVAX_PSIZE_1M		(TLB_PSIZE_1M >> 1)
+#define ERATIVAX_PSIZE_16M		(TLB_PSIZE_16M >> 1)
+#define ERATIVAX_PSIZE_1G		(TLB_PSIZE_1G >> 1)
+
+/* A2 eratilx attributes definitions */
+#define ERATILX_T_ALL			0
+#define ERATILX_T_TID			1
+#define ERATILX_T_TGS			2
+#define ERATILX_T_FULLMATCH		3
+#define ERATILX_T_CLASS0		4
+#define ERATILX_T_CLASS1		5
+#define ERATILX_T_CLASS2		6
+#define ERATILX_T_CLASS3		7
+
+/* XUCR0 bits */
+#define XUCR0_TRACE_UM_T0		0x40000000	/* Thread 0 */
+#define XUCR0_TRACE_UM_T1		0x20000000	/* Thread 1 */
+#define XUCR0_TRACE_UM_T2		0x10000000	/* Thread 2 */
+#define XUCR0_TRACE_UM_T3		0x08000000	/* Thread 3 */
+
+/* A2 CCR0 register */
+#define A2_CCR0_PME_DISABLED		0x00000000
+#define A2_CCR0_PME_SLEEP		0x40000000
+#define A2_CCR0_PME_RVW			0x80000000
+#define A2_CCR0_PME_DISABLED2		0xc0000000
+
+/* A2 CCR2 register */
+#define A2_CCR2_ERAT_ONLY_MODE		0x00000001
+#define A2_CCR2_ENABLE_ICSWX		0x00000002
+#define A2_CCR2_ENABLE_PC		0x20000000
+#define A2_CCR2_ENABLE_TRACE		0x40000000
+
+#endif /* __ASM_POWERPC_REG_A2_H__ */
diff -druN linux-2.6.39-libre/arch/powerpc/include/asm/reg_booke.h linux-3.0-rc7-libre/arch/powerpc/include/asm/reg_booke.h
--- linux-2.6.39-libre/arch/powerpc/include/asm/reg_booke.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/include/asm/reg_booke.h	2011-07-11 19:51:52.000000000 -0400
@@ -27,10 +27,12 @@
 #define MSR_CM		(1<<31) /* Computation Mode (0=32-bit, 1=64-bit) */
 
 #if defined(CONFIG_PPC_BOOK3E_64)
+#define MSR_64BIT	MSR_CM
+
 #define MSR_		MSR_ME | MSR_CE
-#define MSR_KERNEL      MSR_ | MSR_CM
+#define MSR_KERNEL	MSR_ | MSR_64BIT
 #define MSR_USER32	MSR_ | MSR_PR | MSR_EE | MSR_DE
-#define MSR_USER64	MSR_USER32 | MSR_CM | MSR_DE
+#define MSR_USER64	MSR_USER32 | MSR_64BIT
 #elif defined (CONFIG_40x)
 #define MSR_KERNEL	(MSR_ME|MSR_RI|MSR_IR|MSR_DR|MSR_CE)
 #define MSR_USER	(MSR_KERNEL|MSR_PR|MSR_EE)
@@ -81,6 +83,10 @@
 #define SPRN_IVOR13	0x19D	/* Interrupt Vector Offset Register 13 */
 #define SPRN_IVOR14	0x19E	/* Interrupt Vector Offset Register 14 */
 #define SPRN_IVOR15	0x19F	/* Interrupt Vector Offset Register 15 */
+#define SPRN_IVOR38	0x1B0	/* Interrupt Vector Offset Register 38 */
+#define SPRN_IVOR39	0x1B1	/* Interrupt Vector Offset Register 39 */
+#define SPRN_IVOR40	0x1B2	/* Interrupt Vector Offset Register 40 */
+#define SPRN_IVOR41	0x1B3	/* Interrupt Vector Offset Register 41 */
 #define SPRN_SPEFSCR	0x200	/* SPE & Embedded FP Status & Control */
 #define SPRN_BBEAR	0x201	/* Branch Buffer Entry Address Register */
 #define SPRN_BBTAR	0x202	/* Branch Buffer Target Address Register */
diff -druN linux-2.6.39-libre/arch/powerpc/include/asm/reg.h linux-3.0-rc7-libre/arch/powerpc/include/asm/reg.h
--- linux-2.6.39-libre/arch/powerpc/include/asm/reg.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/include/asm/reg.h	2011-07-11 19:51:52.000000000 -0400
@@ -99,17 +99,23 @@
 #define MSR_LE		__MASK(MSR_LE_LG)	/* Little Endian */
 
 #if defined(CONFIG_PPC_BOOK3S_64)
+#define MSR_64BIT	MSR_SF
+
 /* Server variant */
 #define MSR_		MSR_ME | MSR_RI | MSR_IR | MSR_DR | MSR_ISF |MSR_HV
-#define MSR_KERNEL      MSR_ | MSR_SF
+#define MSR_KERNEL	MSR_ | MSR_64BIT
 #define MSR_USER32	MSR_ | MSR_PR | MSR_EE
-#define MSR_USER64	MSR_USER32 | MSR_SF
+#define MSR_USER64	MSR_USER32 | MSR_64BIT
 #elif defined(CONFIG_PPC_BOOK3S_32) || defined(CONFIG_8xx)
 /* Default MSR for kernel mode. */
 #define MSR_KERNEL	(MSR_ME|MSR_RI|MSR_IR|MSR_DR)
 #define MSR_USER	(MSR_KERNEL|MSR_PR|MSR_EE)
 #endif
 
+#ifndef MSR_64BIT
+#define MSR_64BIT	0
+#endif
+
 /* Floating Point Status and Control Register (FPSCR) Fields */
 #define FPSCR_FX	0x80000000	/* FPU exception summary */
 #define FPSCR_FEX	0x40000000	/* FPU enabled exception summary */
@@ -182,6 +188,8 @@
 
 #define SPRN_CTR	0x009	/* Count Register */
 #define SPRN_DSCR	0x11
+#define SPRN_CFAR	0x1c	/* Come From Address Register */
+#define SPRN_ACOP	0x1F	/* Available Coprocessor Register */
 #define SPRN_CTRLF	0x088
 #define SPRN_CTRLT	0x098
 #define   CTRL_CT	0xc0000000	/* current thread */
@@ -210,8 +218,43 @@
 #define SPRN_TBWL	0x11C	/* Time Base Lower Register (super, R/W) */
 #define SPRN_TBWU	0x11D	/* Time Base Upper Register (super, R/W) */
 #define SPRN_SPURR	0x134	/* Scaled PURR */
+#define SPRN_HSPRG0	0x130	/* Hypervisor Scratch 0 */
+#define SPRN_HSPRG1	0x131	/* Hypervisor Scratch 1 */
+#define SPRN_HDSISR     0x132
+#define SPRN_HDAR       0x133
+#define SPRN_HDEC	0x136	/* Hypervisor Decrementer */
 #define SPRN_HIOR	0x137	/* 970 Hypervisor interrupt offset */
+#define SPRN_RMOR	0x138	/* Real mode offset register */
+#define SPRN_HRMOR	0x139	/* Real mode offset register */
+#define SPRN_HSRR0	0x13A	/* Hypervisor Save/Restore 0 */
+#define SPRN_HSRR1	0x13B	/* Hypervisor Save/Restore 1 */
 #define SPRN_LPCR	0x13E	/* LPAR Control Register */
+#define   LPCR_VPM0	(1ul << (63-0))
+#define   LPCR_VPM1	(1ul << (63-1))
+#define   LPCR_ISL	(1ul << (63-2))
+#define   LPCR_DPFD_SH	(63-11)
+#define   LPCR_VRMA_L	(1ul << (63-12))
+#define   LPCR_VRMA_LP0	(1ul << (63-15))
+#define   LPCR_VRMA_LP1	(1ul << (63-16))
+#define   LPCR_RMLS    0x1C000000      /* impl dependent rmo limit sel */
+#define   LPCR_ILE     0x02000000      /* !HV irqs set MSR:LE */
+#define   LPCR_PECE	0x00007000	/* powersave exit cause enable */
+#define     LPCR_PECE0	0x00004000	/* ext. exceptions can cause exit */
+#define     LPCR_PECE1	0x00002000	/* decrementer can cause exit */
+#define     LPCR_PECE2	0x00001000	/* machine check etc can cause exit */
+#define   LPCR_MER	0x00000800	/* Mediated External Exception */
+#define   LPCR_LPES0   0x00000008      /* LPAR Env selector 0 */
+#define   LPCR_LPES1   0x00000004      /* LPAR Env selector 1 */
+#define   LPCR_RMI     0x00000002      /* real mode is cache inhibit */
+#define   LPCR_HDICE   0x00000001      /* Hyp Decr enable (HV,PR,EE) */
+#define SPRN_LPID	0x13F	/* Logical Partition Identifier */
+#define	SPRN_HMER	0x150	/* Hardware m? error recovery */
+#define	SPRN_HMEER	0x151	/* Hardware m? enable error recovery */
+#define	SPRN_HEIR	0x153	/* Hypervisor Emulated Instruction Register */
+#define SPRN_TLBINDEXR	0x154	/* P7 TLB control register */
+#define SPRN_TLBVPNR	0x155	/* P7 TLB control register */
+#define SPRN_TLBRPNR	0x156	/* P7 TLB control register */
+#define SPRN_TLBLPIDR	0x157	/* P7 TLB control register */
 #define SPRN_DBAT0L	0x219	/* Data BAT 0 Lower Register */
 #define SPRN_DBAT0U	0x218	/* Data BAT 0 Upper Register */
 #define SPRN_DBAT1L	0x21B	/* Data BAT 1 Lower Register */
@@ -434,16 +477,23 @@
 #define SPRN_SRR0	0x01A	/* Save/Restore Register 0 */
 #define SPRN_SRR1	0x01B	/* Save/Restore Register 1 */
 #define   SRR1_WAKEMASK		0x00380000 /* reason for wakeup */
-#define   SRR1_WAKERESET	0x00380000 /* System reset */
 #define   SRR1_WAKESYSERR	0x00300000 /* System error */
 #define   SRR1_WAKEEE		0x00200000 /* External interrupt */
 #define   SRR1_WAKEMT		0x00280000 /* mtctrl */
+#define	  SRR1_WAKEHMI		0x00280000 /* Hypervisor maintenance */
 #define   SRR1_WAKEDEC		0x00180000 /* Decrementer interrupt */
 #define   SRR1_WAKETHERM	0x00100000 /* Thermal management interrupt */
+#define	  SRR1_WAKERESET	0x00100000 /* System reset */
+#define	  SRR1_WAKESTATE	0x00030000 /* Powersave exit mask [46:47] */
+#define	  SRR1_WS_DEEPEST	0x00030000 /* Some resources not maintained,
+					  * may not be recoverable */
+#define	  SRR1_WS_DEEPER	0x00020000 /* Some resources not maintained */
+#define	  SRR1_WS_DEEP		0x00010000 /* All resources maintained */
 #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 */
 
@@ -673,12 +723,15 @@
  * SPRG usage:
  *
  * All 64-bit:
- *	- SPRG1 stores PACA pointer
+ *	- SPRG1 stores PACA pointer except 64-bit server in
+ *        HV mode in which case it is HSPRG0
  *
  * 64-bit server:
  *	- SPRG0 unused (reserved for HV on Power4)
  *	- SPRG2 scratch for exception vectors
  *	- SPRG3 unused (user visible)
+ *      - HSPRG0 stores PACA in HV mode
+ *      - HSPRG1 scratch for "HV" exceptions
  *
  * 64-bit embedded
  *	- SPRG0 generic exception scratch
@@ -741,6 +794,41 @@
 
 #ifdef CONFIG_PPC_BOOK3S_64
 #define SPRN_SPRG_SCRATCH0	SPRN_SPRG2
+#define SPRN_SPRG_HPACA		SPRN_HSPRG0
+#define SPRN_SPRG_HSCRATCH0	SPRN_HSPRG1
+
+#define GET_PACA(rX)					\
+	BEGIN_FTR_SECTION_NESTED(66);			\
+	mfspr	rX,SPRN_SPRG_PACA;			\
+	FTR_SECTION_ELSE_NESTED(66);			\
+	mfspr	rX,SPRN_SPRG_HPACA;			\
+	ALT_FTR_SECTION_END_NESTED_IFCLR(CPU_FTR_HVMODE_206, 66)
+
+#define SET_PACA(rX)					\
+	BEGIN_FTR_SECTION_NESTED(66);			\
+	mtspr	SPRN_SPRG_PACA,rX;			\
+	FTR_SECTION_ELSE_NESTED(66);			\
+	mtspr	SPRN_SPRG_HPACA,rX;			\
+	ALT_FTR_SECTION_END_NESTED_IFCLR(CPU_FTR_HVMODE_206, 66)
+
+#define GET_SCRATCH0(rX)				\
+	BEGIN_FTR_SECTION_NESTED(66);			\
+	mfspr	rX,SPRN_SPRG_SCRATCH0;			\
+	FTR_SECTION_ELSE_NESTED(66);			\
+	mfspr	rX,SPRN_SPRG_HSCRATCH0;			\
+	ALT_FTR_SECTION_END_NESTED_IFCLR(CPU_FTR_HVMODE_206, 66)
+
+#define SET_SCRATCH0(rX)				\
+	BEGIN_FTR_SECTION_NESTED(66);			\
+	mtspr	SPRN_SPRG_SCRATCH0,rX;			\
+	FTR_SECTION_ELSE_NESTED(66);			\
+	mtspr	SPRN_SPRG_HSCRATCH0,rX;			\
+	ALT_FTR_SECTION_END_NESTED_IFCLR(CPU_FTR_HVMODE_206, 66)
+
+#else /* CONFIG_PPC_BOOK3S_64 */
+#define GET_SCRATCH0(rX)	mfspr	rX,SPRN_SPRG_SCRATCH0
+#define SET_SCRATCH0(rX)	mtspr	SPRN_SPRG_SCRATCH0,rX
+
 #endif
 
 #ifdef CONFIG_PPC_BOOK3E_64
@@ -750,6 +838,10 @@
 #define SPRN_SPRG_TLB_EXFRAME	SPRN_SPRG2
 #define SPRN_SPRG_TLB_SCRATCH	SPRN_SPRG6
 #define SPRN_SPRG_GEN_SCRATCH	SPRN_SPRG0
+
+#define SET_PACA(rX)	mtspr	SPRN_SPRG_PACA,rX
+#define GET_PACA(rX)	mfspr	rX,SPRN_SPRG_PACA
+
 #endif
 
 #ifdef CONFIG_PPC_BOOK3S_32
@@ -800,6 +892,8 @@
 #define SPRN_SPRG_SCRATCH1	SPRN_SPRG1
 #endif
 
+
+
 /*
  * An mtfsf instruction with the L bit set. On CPUs that support this a
  * full 64bits of FPSCR is restored and on other CPUs the L bit is ignored.
@@ -894,6 +988,8 @@
 #define PV_POWER5p	0x003B
 #define PV_POWER7	0x003F
 #define PV_970FX	0x003C
+#define PV_POWER6	0x003E
+#define PV_POWER7	0x003F
 #define PV_630		0x0040
 #define PV_630p	0x0041
 #define PV_970MP	0x0044
diff -druN linux-2.6.39-libre/arch/powerpc/include/asm/rio.h linux-3.0-rc7-libre/arch/powerpc/include/asm/rio.h
--- linux-2.6.39-libre/arch/powerpc/include/asm/rio.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/include/asm/rio.h	2011-07-11 19:51:52.000000000 -0400
@@ -14,5 +14,10 @@
 #define ASM_PPC_RIO_H
 
 extern void platform_rio_init(void);
+#ifdef CONFIG_FSL_RIO
+extern int fsl_rio_mcheck_exception(struct pt_regs *);
+#else
+static inline int fsl_rio_mcheck_exception(struct pt_regs *regs) {return 0; }
+#endif
 
 #endif				/* ASM_PPC_RIO_H */
diff -druN linux-2.6.39-libre/arch/powerpc/include/asm/rtas.h linux-3.0-rc7-libre/arch/powerpc/include/asm/rtas.h
--- linux-2.6.39-libre/arch/powerpc/include/asm/rtas.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/include/asm/rtas.h	2011-07-11 19:51:52.000000000 -0400
@@ -158,7 +158,50 @@
 	unsigned long target:4;			/* Target of failed operation */
 	unsigned long type:8;			/* General event or error*/
 	unsigned long extended_log_length:32;	/* length in bytes */
-	unsigned char buffer[1];
+	unsigned char buffer[1];		/* Start of extended log */
+						/* Variable length.      */
+};
+
+#define RTAS_V6EXT_LOG_FORMAT_EVENT_LOG	14
+
+#define RTAS_V6EXT_COMPANY_ID_IBM	(('I' << 24) | ('B' << 16) | ('M' << 8))
+
+/* RTAS general extended event log, Version 6. The extended log starts
+ * from "buffer" field of struct rtas_error_log defined above.
+ */
+struct rtas_ext_event_log_v6 {
+	/* Byte 0 */
+	uint32_t log_valid:1;		/* 1:Log valid */
+	uint32_t unrecoverable_error:1;	/* 1:Unrecoverable error */
+	uint32_t recoverable_error:1;	/* 1:recoverable (correctable	*/
+					/*   or successfully retried)	*/
+	uint32_t degraded_operation:1;	/* 1:Unrecoverable err, bypassed*/
+					/*   - degraded operation (e.g.	*/
+					/*   CPU or mem taken off-line)	*/
+	uint32_t predictive_error:1;
+	uint32_t new_log:1;		/* 1:"New" log (Always 1 for	*/
+					/*   data returned from RTAS	*/
+	uint32_t big_endian:1;		/* 1: Big endian */
+	uint32_t :1;			/* reserved */
+	/* Byte 1 */
+	uint32_t :8;			/* reserved */
+	/* Byte 2 */
+	uint32_t powerpc_format:1;	/* Set to 1 (indicating log is	*/
+					/* in PowerPC format		*/
+	uint32_t :3;			/* reserved */
+	uint32_t log_format:4;		/* Log format indicator. Define	*/
+					/* format used for byte 12-2047	*/
+	/* Byte 3 */
+	uint32_t :8;			/* reserved */
+	/* Byte 4-11 */
+	uint8_t reserved[8];		/* reserved */
+	/* Byte 12-15 */
+	uint32_t company_id;		/* Company ID of the company	*/
+					/* that defines the format for	*/
+					/* the vendor specific log type	*/
+	/* Byte 16-end of log */
+	uint8_t vendor_log[1];		/* Start of vendor specific log	*/
+					/* Variable length.		*/
 };
 
 /*
diff -druN linux-2.6.39-libre/arch/powerpc/include/asm/scom.h linux-3.0-rc7-libre/arch/powerpc/include/asm/scom.h
--- linux-2.6.39-libre/arch/powerpc/include/asm/scom.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/powerpc/include/asm/scom.h	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,156 @@
+/*
+ * Copyright 2010 Benjamin Herrenschmidt, IBM Corp
+ *                <benh@kernel.crashing.org>
+ *     and        David Gibson, IBM Corporation.
+ *
+ *   This program is free software;  you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY;  without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
+ *   the GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program;  if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef _ASM_POWERPC_SCOM_H
+#define _ASM_POWERPC_SCOM_H
+
+#ifdef __KERNEL__
+#ifndef __ASSEMBLY__
+#ifdef CONFIG_PPC_SCOM
+
+/*
+ * The SCOM bus is a sideband bus used for accessing various internal
+ * registers of the processor or the chipset. The implementation details
+ * differ between processors and platforms, and the access method as
+ * well.
+ *
+ * This API allows to "map" ranges of SCOM register numbers associated
+ * with a given SCOM controller. The later must be represented by a
+ * device node, though some implementations might support NULL if there
+ * is no possible ambiguity
+ *
+ * Then, scom_read/scom_write can be used to accesses registers inside
+ * that range. The argument passed is a register number relative to
+ * the beginning of the range mapped.
+ */
+
+typedef void *scom_map_t;
+
+/* Value for an invalid SCOM map */
+#define SCOM_MAP_INVALID	(NULL)
+
+/* The scom_controller data structure is what the platform passes
+ * to the core code in scom_init, it provides the actual implementation
+ * of all the SCOM functions
+ */
+struct scom_controller {
+	scom_map_t (*map)(struct device_node *ctrl_dev, u64 reg, u64 count);
+	void (*unmap)(scom_map_t map);
+
+	u64 (*read)(scom_map_t map, u32 reg);
+	void (*write)(scom_map_t map, u32 reg, u64 value);
+};
+
+extern const struct scom_controller *scom_controller;
+
+/**
+ * scom_init - Initialize the SCOM backend, called by the platform
+ * @controller: The platform SCOM controller
+ */
+static inline void scom_init(const struct scom_controller *controller)
+{
+	scom_controller = controller;
+}
+
+/**
+ * scom_map_ok - Test is a SCOM mapping is successful
+ * @map: The result of scom_map to test
+ */
+static inline int scom_map_ok(scom_map_t map)
+{
+	return map != SCOM_MAP_INVALID;
+}
+
+/**
+ * scom_map - Map a block of SCOM registers
+ * @ctrl_dev: Device node of the SCOM controller
+ *            some implementations allow NULL here
+ * @reg: first SCOM register to map
+ * @count: Number of SCOM registers to map
+ */
+
+static inline scom_map_t scom_map(struct device_node *ctrl_dev,
+				  u64 reg, u64 count)
+{
+	return scom_controller->map(ctrl_dev, reg, count);
+}
+
+/**
+ * scom_find_parent - Find the SCOM controller for a device
+ * @dev: OF node of the device
+ *
+ * This is not meant for general usage, but in combination with
+ * scom_map() allows to map registers not represented by the
+ * device own scom-reg property. Useful for applying HW workarounds
+ * on things not properly represented in the device-tree for example.
+ */
+struct device_node *scom_find_parent(struct device_node *dev);
+
+
+/**
+ * scom_map_device - Map a device's block of SCOM registers
+ * @dev: OF node of the device
+ * @index: Register bank index (index in "scom-reg" property)
+ *
+ * This function will use the device-tree binding for SCOM which
+ * is to follow "scom-parent" properties until it finds a node with
+ * a "scom-controller" property to find the controller. It will then
+ * use the "scom-reg" property which is made of reg/count pairs,
+ * each of them having a size defined by the controller's #scom-cells
+ * property
+ */
+extern scom_map_t scom_map_device(struct device_node *dev, int index);
+
+
+/**
+ * scom_unmap - Unmap a block of SCOM registers
+ * @map: Result of scom_map is to be unmapped
+ */
+static inline void scom_unmap(scom_map_t map)
+{
+	if (scom_map_ok(map))
+		scom_controller->unmap(map);
+}
+
+/**
+ * scom_read - Read a SCOM register
+ * @map: Result of scom_map
+ * @reg: Register index within that map
+ */
+static inline u64 scom_read(scom_map_t map, u32 reg)
+{
+	return scom_controller->read(map, reg);
+}
+
+/**
+ * scom_write - Write to a SCOM register
+ * @map: Result of scom_map
+ * @reg: Register index within that map
+ * @value: Value to write
+ */
+static inline void scom_write(scom_map_t map, u32 reg, u64 value)
+{
+	scom_controller->write(map, reg, value);
+}
+
+#endif /* CONFIG_PPC_SCOM */
+#endif /* __ASSEMBLY__ */
+#endif /* __KERNEL__ */
+#endif /* _ASM_POWERPC_SCOM_H */
diff -druN linux-2.6.39-libre/arch/powerpc/include/asm/smp.h linux-3.0-rc7-libre/arch/powerpc/include/asm/smp.h
--- linux-2.6.39-libre/arch/powerpc/include/asm/smp.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/include/asm/smp.h	2011-07-11 19:51:52.000000000 -0400
@@ -20,6 +20,7 @@
 #include <linux/threads.h>
 #include <linux/cpumask.h>
 #include <linux/kernel.h>
+#include <linux/irqreturn.h>
 
 #ifndef __ASSEMBLY__
 
@@ -29,14 +30,32 @@
 #include <asm/percpu.h>
 
 extern int boot_cpuid;
+extern int boot_cpu_count;
 
 extern void cpu_die(void);
 
 #ifdef CONFIG_SMP
 
-extern void smp_send_debugger_break(int cpu);
-extern void smp_message_recv(int);
+struct smp_ops_t {
+	void  (*message_pass)(int cpu, int msg);
+#ifdef CONFIG_PPC_SMP_MUXED_IPI
+	void  (*cause_ipi)(int cpu, unsigned long data);
+#endif
+	int   (*probe)(void);
+	int   (*kick_cpu)(int nr);
+	void  (*setup_cpu)(int nr);
+	void  (*bringup_done)(void);
+	void  (*take_timebase)(void);
+	void  (*give_timebase)(void);
+	int   (*cpu_disable)(void);
+	void  (*cpu_die)(unsigned int nr);
+	int   (*cpu_bootable)(unsigned int nr);
+};
+
+extern void smp_send_debugger_break(void);
 extern void start_secondary_resume(void);
+extern void __devinit smp_generic_give_timebase(void);
+extern void __devinit smp_generic_take_timebase(void);
 
 DECLARE_PER_CPU(unsigned int, cpu_pvr);
 
@@ -93,13 +112,16 @@
 #define PPC_MSG_CALL_FUNC_SINGLE	2
 #define PPC_MSG_DEBUGGER_BREAK  3
 
-/*
- * irq controllers that have dedicated ipis per message and don't
- * need additional code in the action handler may use this
- */
+/* for irq controllers that have dedicated ipis per message (4) */
 extern int smp_request_message_ipi(int virq, int message);
 extern const char *smp_ipi_name[];
 
+/* for irq controllers with only a single ipi */
+extern void smp_muxed_ipi_set_data(int cpu, unsigned long data);
+extern void smp_muxed_ipi_message_pass(int cpu, int msg);
+extern void smp_muxed_ipi_resend(void);
+extern irqreturn_t smp_ipi_demux(void);
+
 void smp_init_iSeries(void);
 void smp_init_pSeries(void);
 void smp_init_cell(void);
@@ -149,7 +171,7 @@
 
 extern int smp_mpic_probe(void);
 extern void smp_mpic_setup_cpu(int cpu);
-extern void smp_generic_kick_cpu(int nr);
+extern int smp_generic_kick_cpu(int nr);
 
 extern void smp_generic_give_timebase(void);
 extern void smp_generic_take_timebase(void);
diff -druN linux-2.6.39-libre/arch/powerpc/include/asm/suspend.h linux-3.0-rc7-libre/arch/powerpc/include/asm/suspend.h
--- linux-2.6.39-libre/arch/powerpc/include/asm/suspend.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/include/asm/suspend.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,6 +0,0 @@
-#ifndef __ASM_POWERPC_SUSPEND_H
-#define __ASM_POWERPC_SUSPEND_H
-
-static inline int arch_prepare_suspend(void) { return 0; }
-
-#endif /* __ASM_POWERPC_SUSPEND_H */
diff -druN linux-2.6.39-libre/arch/powerpc/include/asm/syscall.h linux-3.0-rc7-libre/arch/powerpc/include/asm/syscall.h
--- linux-2.6.39-libre/arch/powerpc/include/asm/syscall.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/include/asm/syscall.h	2011-07-11 19:51:52.000000000 -0400
@@ -15,6 +15,11 @@
 
 #include <linux/sched.h>
 
+/* ftrace syscalls requires exporting the sys_call_table */
+#ifdef CONFIG_FTRACE_SYSCALLS
+extern const unsigned long *sys_call_table;
+#endif /* CONFIG_FTRACE_SYSCALLS */
+
 static inline long syscall_get_nr(struct task_struct *task,
 				  struct pt_regs *regs)
 {
diff -druN linux-2.6.39-libre/arch/powerpc/include/asm/systbl.h linux-3.0-rc7-libre/arch/powerpc/include/asm/systbl.h
--- linux-2.6.39-libre/arch/powerpc/include/asm/systbl.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/include/asm/systbl.h	2011-07-11 19:51:52.000000000 -0400
@@ -352,3 +352,5 @@
 COMPAT_SYS_SPU(open_by_handle_at)
 COMPAT_SYS_SPU(clock_adjtime)
 SYSCALL_SPU(syncfs)
+COMPAT_SYS_SPU(sendmmsg)
+SYSCALL_SPU(setns)
diff -druN linux-2.6.39-libre/arch/powerpc/include/asm/system.h linux-3.0-rc7-libre/arch/powerpc/include/asm/system.h
--- linux-2.6.39-libre/arch/powerpc/include/asm/system.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/include/asm/system.h	2011-07-11 19:51:52.000000000 -0400
@@ -219,8 +219,6 @@
 extern int init_bootmem_done;	/* set once bootmem is available */
 extern phys_addr_t memory_limit;
 extern unsigned long klimit;
-
-extern void *alloc_maybe_bootmem(size_t size, gfp_t mask);
 extern void *zalloc_maybe_bootmem(size_t size, gfp_t mask);
 
 extern int powersave_nap;	/* set if nap mode can be used in idle loop */
diff -druN linux-2.6.39-libre/arch/powerpc/include/asm/thread_info.h linux-3.0-rc7-libre/arch/powerpc/include/asm/thread_info.h
--- linux-2.6.39-libre/arch/powerpc/include/asm/thread_info.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/include/asm/thread_info.h	2011-07-11 19:51:52.000000000 -0400
@@ -110,7 +110,8 @@
 #define TIF_NOERROR		12	/* Force successful syscall return */
 #define TIF_NOTIFY_RESUME	13	/* callback before returning to user */
 #define TIF_FREEZE		14	/* Freezing for suspend */
-#define TIF_RUNLATCH		15	/* Is the runlatch enabled? */
+#define TIF_SYSCALL_TRACEPOINT	15	/* syscall tracepoint instrumentation */
+#define TIF_RUNLATCH		16	/* Is the runlatch enabled? */
 
 /* as above, but as bit values */
 #define _TIF_SYSCALL_TRACE	(1<<TIF_SYSCALL_TRACE)
@@ -127,8 +128,10 @@
 #define _TIF_NOERROR		(1<<TIF_NOERROR)
 #define _TIF_NOTIFY_RESUME	(1<<TIF_NOTIFY_RESUME)
 #define _TIF_FREEZE		(1<<TIF_FREEZE)
+#define _TIF_SYSCALL_TRACEPOINT	(1<<TIF_SYSCALL_TRACEPOINT)
 #define _TIF_RUNLATCH		(1<<TIF_RUNLATCH)
-#define _TIF_SYSCALL_T_OR_A	(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SECCOMP)
+#define _TIF_SYSCALL_T_OR_A	(_TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT | \
+				 _TIF_SECCOMP | _TIF_SYSCALL_TRACEPOINT)
 
 #define _TIF_USER_WORK_MASK	(_TIF_SIGPENDING | _TIF_NEED_RESCHED | \
 				 _TIF_NOTIFY_RESUME)
@@ -139,10 +142,12 @@
 #define TLF_NAPPING		0	/* idle thread enabled NAP mode */
 #define TLF_SLEEPING		1	/* suspend code enabled SLEEP mode */
 #define TLF_RESTORE_SIGMASK	2	/* Restore signal mask in do_signal */
+#define TLF_LAZY_MMU		3	/* tlb_batch is active */
 
 #define _TLF_NAPPING		(1 << TLF_NAPPING)
 #define _TLF_SLEEPING		(1 << TLF_SLEEPING)
 #define _TLF_RESTORE_SIGMASK	(1 << TLF_RESTORE_SIGMASK)
+#define _TLF_LAZY_MMU		(1 << TLF_LAZY_MMU)
 
 #ifndef __ASSEMBLY__
 #define HAVE_SET_RESTORE_SIGMASK	1
diff -druN linux-2.6.39-libre/arch/powerpc/include/asm/tlbflush.h linux-3.0-rc7-libre/arch/powerpc/include/asm/tlbflush.h
--- linux-2.6.39-libre/arch/powerpc/include/asm/tlbflush.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/include/asm/tlbflush.h	2011-07-11 19:51:52.000000000 -0400
@@ -79,6 +79,8 @@
 
 #elif defined(CONFIG_PPC_STD_MMU_64)
 
+#define MMU_NO_CONTEXT		0
+
 /*
  * TLB flushing for 64-bit hash-MMU CPUs
  */
diff -druN linux-2.6.39-libre/arch/powerpc/include/asm/udbg.h linux-3.0-rc7-libre/arch/powerpc/include/asm/udbg.h
--- linux-2.6.39-libre/arch/powerpc/include/asm/udbg.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/include/asm/udbg.h	2011-07-11 19:51:52.000000000 -0400
@@ -52,6 +52,7 @@
 extern void __init udbg_init_40x_realmode(void);
 extern void __init udbg_init_cpm(void);
 extern void __init udbg_init_usbgecko(void);
+extern void __init udbg_init_wsp(void);
 
 #endif /* __KERNEL__ */
 #endif /* _ASM_POWERPC_UDBG_H */
diff -druN linux-2.6.39-libre/arch/powerpc/include/asm/unistd.h linux-3.0-rc7-libre/arch/powerpc/include/asm/unistd.h
--- linux-2.6.39-libre/arch/powerpc/include/asm/unistd.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/include/asm/unistd.h	2011-07-11 19:51:52.000000000 -0400
@@ -371,10 +371,12 @@
 #define __NR_open_by_handle_at	346
 #define __NR_clock_adjtime	347
 #define __NR_syncfs		348
+#define __NR_sendmmsg		349
+#define __NR_setns		350
 
 #ifdef __KERNEL__
 
-#define __NR_syscalls		349
+#define __NR_syscalls		351
 
 #define __NR__exit __NR_exit
 #define NR_syscalls	__NR_syscalls
diff -druN linux-2.6.39-libre/arch/powerpc/include/asm/wsp.h linux-3.0-rc7-libre/arch/powerpc/include/asm/wsp.h
--- linux-2.6.39-libre/arch/powerpc/include/asm/wsp.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/powerpc/include/asm/wsp.h	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,14 @@
+/*
+ *  Copyright 2011 Michael Ellerman, IBM Corp.
+ *
+ *  This program is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU General Public License
+ *  as published by the Free Software Foundation; either version
+ *  2 of the License, or (at your option) any later version.
+ */
+#ifndef __ASM_POWERPC_WSP_H
+#define __ASM_POWERPC_WSP_H
+
+extern int wsp_get_chip_id(struct device_node *dn);
+
+#endif /* __ASM_POWERPC_WSP_H */
diff -druN linux-2.6.39-libre/arch/powerpc/include/asm/xics.h linux-3.0-rc7-libre/arch/powerpc/include/asm/xics.h
--- linux-2.6.39-libre/arch/powerpc/include/asm/xics.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/powerpc/include/asm/xics.h	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,142 @@
+/*
+ * Common definitions accross all variants of ICP and ICS interrupt
+ * controllers.
+ */
+
+#ifndef _XICS_H
+#define _XICS_H
+
+#include <linux/interrupt.h>
+
+#define XICS_IPI		2
+#define XICS_IRQ_SPURIOUS	0
+
+/* Want a priority other than 0.  Various HW issues require this. */
+#define	DEFAULT_PRIORITY	5
+
+/*
+ * Mark IPIs as higher priority so we can take them inside interrupts that
+ * arent marked IRQF_DISABLED
+ */
+#define IPI_PRIORITY		4
+
+/* The least favored priority */
+#define LOWEST_PRIORITY		0xFF
+
+/* The number of priorities defined above */
+#define MAX_NUM_PRIORITIES	3
+
+/* Native ICP */
+extern int icp_native_init(void);
+
+/* PAPR ICP */
+extern int icp_hv_init(void);
+
+/* ICP ops */
+struct icp_ops {
+	unsigned int (*get_irq)(void);
+	void (*eoi)(struct irq_data *d);
+	void (*set_priority)(unsigned char prio);
+	void (*teardown_cpu)(void);
+	void (*flush_ipi)(void);
+#ifdef CONFIG_SMP
+	void (*cause_ipi)(int cpu, unsigned long data);
+	irq_handler_t ipi_action;
+#endif
+};
+
+extern const struct icp_ops *icp_ops;
+
+/* Native ICS */
+extern int ics_native_init(void);
+
+/* RTAS ICS */
+extern int ics_rtas_init(void);
+
+/* ICS instance, hooked up to chip_data of an irq */
+struct ics {
+	struct list_head link;
+	int (*map)(struct ics *ics, unsigned int virq);
+	void (*mask_unknown)(struct ics *ics, unsigned long vec);
+	long (*get_server)(struct ics *ics, unsigned long vec);
+	int (*host_match)(struct ics *ics, struct device_node *node);
+	char data[];
+};
+
+/* Commons */
+extern unsigned int xics_default_server;
+extern unsigned int xics_default_distrib_server;
+extern unsigned int xics_interrupt_server_size;
+extern struct irq_host *xics_host;
+
+struct xics_cppr {
+	unsigned char stack[MAX_NUM_PRIORITIES];
+	int index;
+};
+
+DECLARE_PER_CPU(struct xics_cppr, xics_cppr);
+
+static inline void xics_push_cppr(unsigned int vec)
+{
+	struct xics_cppr *os_cppr = &__get_cpu_var(xics_cppr);
+
+	if (WARN_ON(os_cppr->index >= MAX_NUM_PRIORITIES - 1))
+		return;
+
+	if (vec == XICS_IPI)
+		os_cppr->stack[++os_cppr->index] = IPI_PRIORITY;
+	else
+		os_cppr->stack[++os_cppr->index] = DEFAULT_PRIORITY;
+}
+
+static inline unsigned char xics_pop_cppr(void)
+{
+	struct xics_cppr *os_cppr = &__get_cpu_var(xics_cppr);
+
+	if (WARN_ON(os_cppr->index < 1))
+		return LOWEST_PRIORITY;
+
+	return os_cppr->stack[--os_cppr->index];
+}
+
+static inline void xics_set_base_cppr(unsigned char cppr)
+{
+	struct xics_cppr *os_cppr = &__get_cpu_var(xics_cppr);
+
+	/* we only really want to set the priority when there's
+	 * just one cppr value on the stack
+	 */
+	WARN_ON(os_cppr->index != 0);
+
+	os_cppr->stack[0] = cppr;
+}
+
+static inline unsigned char xics_cppr_top(void)
+{
+	struct xics_cppr *os_cppr = &__get_cpu_var(xics_cppr);
+	
+	return os_cppr->stack[os_cppr->index];
+}
+
+DECLARE_PER_CPU_SHARED_ALIGNED(unsigned long, xics_ipi_message);
+
+extern void xics_init(void);
+extern void xics_setup_cpu(void);
+extern void xics_update_irq_servers(void);
+extern void xics_set_cpu_giq(unsigned int gserver, unsigned int join);
+extern void xics_mask_unknown_vec(unsigned int vec);
+extern irqreturn_t xics_ipi_dispatch(int cpu);
+extern int xics_smp_probe(void);
+extern void xics_register_ics(struct ics *ics);
+extern void xics_teardown_cpu(void);
+extern void xics_kexec_teardown_cpu(int secondary);
+extern void xics_migrate_irqs_away(void);
+#ifdef CONFIG_SMP
+extern int xics_get_irq_server(unsigned int virq, const struct cpumask *cpumask,
+			       unsigned int strict_check);
+#else
+#define xics_get_irq_server(virq, cpumask, strict_check) (xics_default_server)
+#endif
+
+
+#endif /* _XICS_H */
diff -druN linux-2.6.39-libre/arch/powerpc/Kconfig linux-3.0-rc7-libre/arch/powerpc/Kconfig
--- linux-2.6.39-libre/arch/powerpc/Kconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/Kconfig	2011-07-11 19:51:52.000000000 -0400
@@ -91,14 +91,6 @@
 	bool
 	default y
 
-config GENERIC_FIND_NEXT_BIT
-	bool
-	default y
-
-config GENERIC_FIND_BIT_LE
-	bool
-	default y
-
 config GENERIC_GPIO
 	bool
 	help
@@ -140,6 +132,8 @@
 	select IRQ_PER_CPU
 	select GENERIC_IRQ_SHOW
 	select GENERIC_IRQ_SHOW_LEVEL
+	select HAVE_RCU_TABLE_FREE if SMP
+	select HAVE_SYSCALL_TRACEPOINTS
 
 config EARLY_PRINTK
 	bool
@@ -193,6 +187,12 @@
 	default y if PMAC_APM_EMU
 	bool
 
+config EPAPR_BOOT
+	bool
+	help
+	  Used to allow a board to specify it wants an ePAPR compliant wrapper.
+	default n
+
 config DEFAULT_UIMAGE
 	bool
 	help
diff -druN linux-2.6.39-libre/arch/powerpc/Kconfig.debug linux-3.0-rc7-libre/arch/powerpc/Kconfig.debug
--- linux-2.6.39-libre/arch/powerpc/Kconfig.debug	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/Kconfig.debug	2011-07-11 19:51:52.000000000 -0400
@@ -35,27 +35,6 @@
 	  This option will cause messages to be printed if free stack space
 	  drops below a certain limit.
 
-config DEBUG_STACK_USAGE
-	bool "Stack utilization instrumentation"
-	depends on DEBUG_KERNEL
-	help
-	  Enables the display of the minimum amount of free stack which each
-	  task has ever had available in the sysrq-T and sysrq-P debug output.
-
-	  This option will slow down process creation somewhat.
-
-config DEBUG_PER_CPU_MAPS
-	bool "Debug access to per_cpu maps"
-	depends on DEBUG_KERNEL
-	depends on SMP
-	default n
-	---help---
-	  Say Y to verify that the per_cpu map being accessed has
-	  been setup.  Adds a fair amount of code to kernel memory
-	  and decreases performance.
-
-	  Say N if unsure.
-
 config HCALL_STATS
 	bool "Hypervisor call instrumentation"
 	depends on PPC_PSERIES && DEBUG_FS && TRACEPOINTS
@@ -267,6 +246,11 @@
 	  Select this to enable early debugging for Nintendo GameCube/Wii
 	  consoles via an external USB Gecko adapter.
 
+config PPC_EARLY_DEBUG_WSP
+	bool "Early debugging via WSP's internal UART"
+	depends on PPC_WSP
+	select PPC_UDBG_16550
+
 endchoice
 
 config PPC_EARLY_DEBUG_44x_PHYSLOW
diff -druN linux-2.6.39-libre/arch/powerpc/kernel/asm-offsets.c linux-3.0-rc7-libre/arch/powerpc/kernel/asm-offsets.c
--- linux-2.6.39-libre/arch/powerpc/kernel/asm-offsets.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/kernel/asm-offsets.c	2011-07-11 19:51:52.000000000 -0400
@@ -74,6 +74,7 @@
 	DEFINE(AUDITCONTEXT, offsetof(struct task_struct, audit_context));
 	DEFINE(SIGSEGV, SIGSEGV);
 	DEFINE(NMI_MASK, NMI_MASK);
+	DEFINE(THREAD_DSCR, offsetof(struct thread_struct, dscr));
 #else
 	DEFINE(THREAD_INFO, offsetof(struct task_struct, stack));
 #endif /* CONFIG_PPC64 */
@@ -395,6 +396,7 @@
 	DEFINE(VCPU_HOST_STACK, offsetof(struct kvm_vcpu, arch.host_stack));
 	DEFINE(VCPU_HOST_PID, offsetof(struct kvm_vcpu, arch.host_pid));
 	DEFINE(VCPU_GPRS, offsetof(struct kvm_vcpu, arch.gpr));
+	DEFINE(VCPU_VRSAVE, offsetof(struct kvm_vcpu, arch.vrsave));
 	DEFINE(VCPU_SPRG4, offsetof(struct kvm_vcpu, arch.sprg4));
 	DEFINE(VCPU_SPRG5, offsetof(struct kvm_vcpu, arch.sprg5));
 	DEFINE(VCPU_SPRG6, offsetof(struct kvm_vcpu, arch.sprg6));
diff -druN linux-2.6.39-libre/arch/powerpc/kernel/cpu_setup_a2.S linux-3.0-rc7-libre/arch/powerpc/kernel/cpu_setup_a2.S
--- linux-2.6.39-libre/arch/powerpc/kernel/cpu_setup_a2.S	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/powerpc/kernel/cpu_setup_a2.S	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,114 @@
+/*
+ *  A2 specific assembly support code
+ *
+ *  Copyright 2009 Ben Herrenschmidt, IBM Corp.
+ *
+ *  This program is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU General Public License
+ *  as published by the Free Software Foundation; either version
+ *  2 of the License, or (at your option) any later version.
+ */
+
+#include <asm/asm-offsets.h>
+#include <asm/ppc_asm.h>
+#include <asm/ppc-opcode.h>
+#include <asm/processor.h>
+#include <asm/reg_a2.h>
+#include <asm/reg.h>
+#include <asm/thread_info.h>
+
+/*
+ * Disable thdid and class fields in ERATs to bump PID to full 14 bits capacity.
+ * This also prevents external LPID accesses but that isn't a problem when not a
+ * guest. Under PV, this setting will be ignored and MMUCR will return the right
+ * number of PID bits we can use.
+ */
+#define MMUCR1_EXTEND_PID \
+	(MMUCR1_ICTID | MMUCR1_ITTID | MMUCR1_DCTID | \
+	 MMUCR1_DTTID | MMUCR1_DCCD)
+
+/*
+ * Use extended PIDs if enabled.
+ * Don't clear the ERATs on context sync events and enable I & D LRU.
+ * Enable ERAT back invalidate when tlbwe overwrites an entry.
+ */
+#define INITIAL_MMUCR1 \
+	(MMUCR1_EXTEND_PID | MMUCR1_CSINV_NEVER | MMUCR1_IRRE | \
+	 MMUCR1_DRRE | MMUCR1_TLBWE_BINV)
+
+_GLOBAL(__setup_cpu_a2)
+	/* Some of these are actually thread local and some are
+	 * core local but doing it always won't hurt
+	 */
+
+#ifdef CONFIG_PPC_WSP_COPRO
+	/* Make sure ACOP starts out as zero */
+	li	r3,0
+	mtspr   SPRN_ACOP,r3
+
+	/* Enable icswx instruction */
+	mfspr   r3,SPRN_A2_CCR2
+	ori     r3,r3,A2_CCR2_ENABLE_ICSWX
+	mtspr   SPRN_A2_CCR2,r3
+
+	/* Unmask all CTs in HACOP */
+	li      r3,-1
+	mtspr   SPRN_HACOP,r3
+#endif /* CONFIG_PPC_WSP_COPRO */
+
+	/* Enable doorbell */
+	mfspr   r3,SPRN_A2_CCR2
+	oris     r3,r3,A2_CCR2_ENABLE_PC@h
+	mtspr   SPRN_A2_CCR2,r3
+	isync
+
+	/* Setup CCR0 to disable power saving for now as it's busted
+	 * in the current implementations. Setup CCR1 to wake on
+	 * interrupts normally (we write the default value but who
+	 * knows what FW may have clobbered...)
+	 */
+	li	r3,0
+	mtspr	SPRN_A2_CCR0, r3
+	LOAD_REG_IMMEDIATE(r3,0x0f0f0f0f)
+	mtspr	SPRN_A2_CCR1, r3
+
+	/* Initialise MMUCR1 */
+	lis	r3,INITIAL_MMUCR1@h
+	ori	r3,r3,INITIAL_MMUCR1@l
+	mtspr	SPRN_MMUCR1,r3
+
+	/* Set MMUCR2 to enable 4K, 64K, 1M, 16M and 1G pages */
+	LOAD_REG_IMMEDIATE(r3, 0x000a7531)
+	mtspr	SPRN_MMUCR2,r3
+
+	/* Set MMUCR3 to write all thids bit to the TLB */
+	LOAD_REG_IMMEDIATE(r3, 0x0000000f)
+	mtspr	SPRN_MMUCR3,r3
+
+	/* Don't do ERAT stuff if running guest mode */
+	mfmsr	r3
+	andis.	r0,r3,MSR_GS@h
+	bne	1f
+
+	/* Now set the I-ERAT watermark to 15 */
+	lis	r4,(MMUCR0_TLBSEL_I|MMUCR0_ECL)@h
+	mtspr	SPRN_MMUCR0, r4
+	li	r4,A2_IERAT_SIZE-1
+	PPC_ERATWE(r4,r4,3)
+
+	/* Now set the D-ERAT watermark to 31 */
+	lis	r4,(MMUCR0_TLBSEL_D|MMUCR0_ECL)@h
+	mtspr	SPRN_MMUCR0, r4
+	li	r4,A2_DERAT_SIZE-1
+	PPC_ERATWE(r4,r4,3)
+
+	/* And invalidate the beast just in case. That won't get rid of
+	 * a bolted entry though it will be in LRU and so will go away eventually
+	 * but let's not bother for now
+	 */
+	PPC_ERATILX(0,0,0)
+1:
+	blr
+
+_GLOBAL(__restore_cpu_a2)
+	b	__setup_cpu_a2
diff -druN linux-2.6.39-libre/arch/powerpc/kernel/cpu_setup_fsl_booke.S linux-3.0-rc7-libre/arch/powerpc/kernel/cpu_setup_fsl_booke.S
--- linux-2.6.39-libre/arch/powerpc/kernel/cpu_setup_fsl_booke.S	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/kernel/cpu_setup_fsl_booke.S	2011-07-11 19:51:52.000000000 -0400
@@ -88,6 +88,9 @@
 	bl	__e500_dcache_setup
 #ifdef CONFIG_PPC_BOOK3E_64
 	bl	.__setup_base_ivors
+	bl	.setup_perfmon_ivor
+	bl	.setup_doorbell_ivors
+	bl	.setup_ehv_ivors
 #else
 	bl	__setup_e500mc_ivors
 #endif
diff -druN linux-2.6.39-libre/arch/powerpc/kernel/cpu_setup_power7.S linux-3.0-rc7-libre/arch/powerpc/kernel/cpu_setup_power7.S
--- linux-2.6.39-libre/arch/powerpc/kernel/cpu_setup_power7.S	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/powerpc/kernel/cpu_setup_power7.S	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,91 @@
+/*
+ * This file contains low level CPU setup functions.
+ *    Copyright (C) 2003 Benjamin Herrenschmidt (benh@kernel.crashing.org)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ *
+ */
+
+#include <asm/processor.h>
+#include <asm/page.h>
+#include <asm/cputable.h>
+#include <asm/ppc_asm.h>
+#include <asm/asm-offsets.h>
+#include <asm/cache.h>
+
+/* Entry: r3 = crap, r4 = ptr to cputable entry
+ *
+ * Note that we can be called twice for pseudo-PVRs
+ */
+_GLOBAL(__setup_cpu_power7)
+	mflr	r11
+	bl	__init_hvmode_206
+	mtlr	r11
+	beqlr
+	li	r0,0
+	mtspr	SPRN_LPID,r0
+	bl	__init_LPCR
+	bl	__init_TLB
+	mtlr	r11
+	blr
+
+_GLOBAL(__restore_cpu_power7)
+	mflr	r11
+	mfmsr	r3
+	rldicl.	r0,r3,4,63
+	beqlr
+	li	r0,0
+	mtspr	SPRN_LPID,r0
+	bl	__init_LPCR
+	bl	__init_TLB
+	mtlr	r11
+	blr
+
+__init_hvmode_206:
+	/* Disable CPU_FTR_HVMODE_206 and exit if MSR:HV is not set */
+	mfmsr	r3
+	rldicl.	r0,r3,4,63
+	bnelr
+	ld	r5,CPU_SPEC_FEATURES(r4)
+	LOAD_REG_IMMEDIATE(r6,CPU_FTR_HVMODE_206)
+	xor	r5,r5,r6
+	std	r5,CPU_SPEC_FEATURES(r4)
+	blr
+
+__init_LPCR:
+	/* Setup a sane LPCR:
+	 *
+	 *   LPES = 0b01 (HSRR0/1 used for 0x500)
+	 *   PECE = 0b111
+	 *   DPFD = 4
+	 *
+	 * Other bits untouched for now
+	 */
+	mfspr	r3,SPRN_LPCR
+	ori	r3,r3,(LPCR_LPES0|LPCR_LPES1)
+	xori	r3,r3, LPCR_LPES0
+	ori	r3,r3,(LPCR_PECE0|LPCR_PECE1|LPCR_PECE2)
+	li	r5,7
+	sldi	r5,r5,LPCR_DPFD_SH
+	andc	r3,r3,r5
+	li	r5,4
+	sldi	r5,r5,LPCR_DPFD_SH
+	or	r3,r3,r5
+	mtspr	SPRN_LPCR,r3
+	isync
+	blr
+
+__init_TLB:
+	/* Clear the TLB */
+	li	r6,128
+	mtctr	r6
+	li	r7,0xc00	/* IS field = 0b11 */
+	ptesync
+2:	tlbiel	r7
+	addi	r7,r7,0x1000
+	bdnz	2b
+	ptesync
+1:	blr
diff -druN linux-2.6.39-libre/arch/powerpc/kernel/cputable.c linux-3.0-rc7-libre/arch/powerpc/kernel/cputable.c
--- linux-2.6.39-libre/arch/powerpc/kernel/cputable.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/kernel/cputable.c	2011-07-11 19:51:52.000000000 -0400
@@ -62,10 +62,12 @@
 extern void __setup_cpu_ppc970(unsigned long offset, struct cpu_spec* spec);
 extern void __setup_cpu_ppc970MP(unsigned long offset, struct cpu_spec* spec);
 extern void __setup_cpu_pa6t(unsigned long offset, struct cpu_spec* spec);
+extern void __setup_cpu_a2(unsigned long offset, struct cpu_spec* spec);
 extern void __restore_cpu_pa6t(void);
 extern void __restore_cpu_ppc970(void);
 extern void __setup_cpu_power7(unsigned long offset, struct cpu_spec* spec);
 extern void __restore_cpu_power7(void);
+extern void __restore_cpu_a2(void);
 #endif /* CONFIG_PPC64 */
 #if defined(CONFIG_E500)
 extern void __setup_cpu_e5500(unsigned long offset, struct cpu_spec* spec);
@@ -199,7 +201,7 @@
 		.cpu_name		= "POWER4 (gp)",
 		.cpu_features		= CPU_FTRS_POWER4,
 		.cpu_user_features	= COMMON_USER_POWER4,
-		.mmu_features		= MMU_FTR_HPTE_TABLE,
+		.mmu_features		= MMU_FTRS_POWER4,
 		.icache_bsize		= 128,
 		.dcache_bsize		= 128,
 		.num_pmcs		= 8,
@@ -214,7 +216,7 @@
 		.cpu_name		= "POWER4+ (gq)",
 		.cpu_features		= CPU_FTRS_POWER4,
 		.cpu_user_features	= COMMON_USER_POWER4,
-		.mmu_features		= MMU_FTR_HPTE_TABLE,
+		.mmu_features		= MMU_FTRS_POWER4,
 		.icache_bsize		= 128,
 		.dcache_bsize		= 128,
 		.num_pmcs		= 8,
@@ -230,7 +232,7 @@
 		.cpu_features		= CPU_FTRS_PPC970,
 		.cpu_user_features	= COMMON_USER_POWER4 |
 			PPC_FEATURE_HAS_ALTIVEC_COMP,
-		.mmu_features		= MMU_FTR_HPTE_TABLE,
+		.mmu_features		= MMU_FTRS_PPC970,
 		.icache_bsize		= 128,
 		.dcache_bsize		= 128,
 		.num_pmcs		= 8,
@@ -248,7 +250,7 @@
 		.cpu_features		= CPU_FTRS_PPC970,
 		.cpu_user_features	= COMMON_USER_POWER4 |
 			PPC_FEATURE_HAS_ALTIVEC_COMP,
-		.mmu_features		= MMU_FTR_HPTE_TABLE,
+		.mmu_features		= MMU_FTRS_PPC970,
 		.icache_bsize		= 128,
 		.dcache_bsize		= 128,
 		.num_pmcs		= 8,
@@ -284,7 +286,7 @@
 		.cpu_features		= CPU_FTRS_PPC970,
 		.cpu_user_features	= COMMON_USER_POWER4 |
 			PPC_FEATURE_HAS_ALTIVEC_COMP,
-		.mmu_features		= MMU_FTR_HPTE_TABLE,
+		.mmu_features		= MMU_FTRS_PPC970,
 		.icache_bsize		= 128,
 		.dcache_bsize		= 128,
 		.num_pmcs		= 8,
@@ -302,7 +304,7 @@
 		.cpu_features		= CPU_FTRS_PPC970,
 		.cpu_user_features	= COMMON_USER_POWER4 |
 			PPC_FEATURE_HAS_ALTIVEC_COMP,
-		.mmu_features		= MMU_FTR_HPTE_TABLE,
+		.mmu_features		= MMU_FTRS_PPC970,
 		.icache_bsize		= 128,
 		.dcache_bsize		= 128,
 		.num_pmcs		= 8,
@@ -318,7 +320,7 @@
 		.cpu_name		= "POWER5 (gr)",
 		.cpu_features		= CPU_FTRS_POWER5,
 		.cpu_user_features	= COMMON_USER_POWER5,
-		.mmu_features		= MMU_FTR_HPTE_TABLE,
+		.mmu_features		= MMU_FTRS_POWER5,
 		.icache_bsize		= 128,
 		.dcache_bsize		= 128,
 		.num_pmcs		= 6,
@@ -338,7 +340,7 @@
 		.cpu_name		= "POWER5+ (gs)",
 		.cpu_features		= CPU_FTRS_POWER5,
 		.cpu_user_features	= COMMON_USER_POWER5_PLUS,
-		.mmu_features		= MMU_FTR_HPTE_TABLE,
+		.mmu_features		= MMU_FTRS_POWER5,
 		.icache_bsize		= 128,
 		.dcache_bsize		= 128,
 		.num_pmcs		= 6,
@@ -354,7 +356,7 @@
 		.cpu_name		= "POWER5+ (gs)",
 		.cpu_features		= CPU_FTRS_POWER5,
 		.cpu_user_features	= COMMON_USER_POWER5_PLUS,
-		.mmu_features		= MMU_FTR_HPTE_TABLE,
+		.mmu_features		= MMU_FTRS_POWER5,
 		.icache_bsize		= 128,
 		.dcache_bsize		= 128,
 		.num_pmcs		= 6,
@@ -371,7 +373,7 @@
 		.cpu_name		= "POWER5+",
 		.cpu_features		= CPU_FTRS_POWER5,
 		.cpu_user_features	= COMMON_USER_POWER5_PLUS,
-		.mmu_features		= MMU_FTR_HPTE_TABLE,
+		.mmu_features		= MMU_FTRS_POWER5,
 		.icache_bsize		= 128,
 		.dcache_bsize		= 128,
 		.oprofile_cpu_type	= "ppc64/ibm-compat-v1",
@@ -385,7 +387,7 @@
 		.cpu_features		= CPU_FTRS_POWER6,
 		.cpu_user_features	= COMMON_USER_POWER6 |
 			PPC_FEATURE_POWER6_EXT,
-		.mmu_features		= MMU_FTR_HPTE_TABLE,
+		.mmu_features		= MMU_FTRS_POWER6,
 		.icache_bsize		= 128,
 		.dcache_bsize		= 128,
 		.num_pmcs		= 6,
@@ -404,7 +406,7 @@
 		.cpu_name		= "POWER6 (architected)",
 		.cpu_features		= CPU_FTRS_POWER6,
 		.cpu_user_features	= COMMON_USER_POWER6,
-		.mmu_features		= MMU_FTR_HPTE_TABLE,
+		.mmu_features		= MMU_FTRS_POWER6,
 		.icache_bsize		= 128,
 		.dcache_bsize		= 128,
 		.oprofile_cpu_type	= "ppc64/ibm-compat-v1",
@@ -417,12 +419,13 @@
 		.cpu_name		= "POWER7 (architected)",
 		.cpu_features		= CPU_FTRS_POWER7,
 		.cpu_user_features	= COMMON_USER_POWER7,
-		.mmu_features		= MMU_FTR_HPTE_TABLE |
-			MMU_FTR_TLBIE_206,
+		.mmu_features		= MMU_FTRS_POWER7,
 		.icache_bsize		= 128,
 		.dcache_bsize		= 128,
 		.oprofile_type		= PPC_OPROFILE_POWER4,
 		.oprofile_cpu_type	= "ppc64/ibm-compat-v1",
+		.cpu_setup		= __setup_cpu_power7,
+		.cpu_restore		= __restore_cpu_power7,
 		.platform		= "power7",
 	},
 	{	/* Power7 */
@@ -431,14 +434,15 @@
 		.cpu_name		= "POWER7 (raw)",
 		.cpu_features		= CPU_FTRS_POWER7,
 		.cpu_user_features	= COMMON_USER_POWER7,
-		.mmu_features		= MMU_FTR_HPTE_TABLE |
-			MMU_FTR_TLBIE_206,
+		.mmu_features		= MMU_FTRS_POWER7,
 		.icache_bsize		= 128,
 		.dcache_bsize		= 128,
 		.num_pmcs		= 6,
 		.pmc_type		= PPC_PMC_IBM,
 		.oprofile_cpu_type	= "ppc64/power7",
 		.oprofile_type		= PPC_OPROFILE_POWER4,
+		.cpu_setup		= __setup_cpu_power7,
+		.cpu_restore		= __restore_cpu_power7,
 		.platform		= "power7",
 	},
 	{	/* Power7+ */
@@ -447,14 +451,15 @@
 		.cpu_name		= "POWER7+ (raw)",
 		.cpu_features		= CPU_FTRS_POWER7,
 		.cpu_user_features	= COMMON_USER_POWER7,
-		.mmu_features		= MMU_FTR_HPTE_TABLE |
-			MMU_FTR_TLBIE_206,
+		.mmu_features		= MMU_FTRS_POWER7,
 		.icache_bsize		= 128,
 		.dcache_bsize		= 128,
 		.num_pmcs		= 6,
 		.pmc_type		= PPC_PMC_IBM,
 		.oprofile_cpu_type	= "ppc64/power7",
 		.oprofile_type		= PPC_OPROFILE_POWER4,
+		.cpu_setup		= __setup_cpu_power7,
+		.cpu_restore		= __restore_cpu_power7,
 		.platform		= "power7+",
 	},
 	{	/* Cell Broadband Engine */
@@ -465,7 +470,7 @@
 		.cpu_user_features	= COMMON_USER_PPC64 |
 			PPC_FEATURE_CELL | PPC_FEATURE_HAS_ALTIVEC_COMP |
 			PPC_FEATURE_SMT,
-		.mmu_features		= MMU_FTR_HPTE_TABLE,
+		.mmu_features		= MMU_FTRS_CELL,
 		.icache_bsize		= 128,
 		.dcache_bsize		= 128,
 		.num_pmcs		= 4,
@@ -480,7 +485,7 @@
 		.cpu_name		= "PA6T",
 		.cpu_features		= CPU_FTRS_PA6T,
 		.cpu_user_features	= COMMON_USER_PA6T,
-		.mmu_features		= MMU_FTR_HPTE_TABLE,
+		.mmu_features		= MMU_FTRS_PA6T,
 		.icache_bsize		= 64,
 		.dcache_bsize		= 64,
 		.num_pmcs		= 6,
@@ -497,7 +502,7 @@
 		.cpu_name		= "POWER4 (compatible)",
 		.cpu_features		= CPU_FTRS_COMPATIBLE,
 		.cpu_user_features	= COMMON_USER_PPC64,
-		.mmu_features		= MMU_FTR_HPTE_TABLE,
+		.mmu_features		= MMU_FTRS_DEFAULT_HPTE_ARCH_V2,
 		.icache_bsize		= 128,
 		.dcache_bsize		= 128,
 		.num_pmcs		= 6,
@@ -1974,7 +1979,7 @@
 		.pvr_value		= 0x80240000,
 		.cpu_name		= "e5500",
 		.cpu_features		= CPU_FTRS_E5500,
-		.cpu_user_features	= COMMON_USER_BOOKE,
+		.cpu_user_features	= COMMON_USER_BOOKE | PPC_FEATURE_HAS_FPU,
 		.mmu_features		= MMU_FTR_TYPE_FSL_E | MMU_FTR_BIG_PHYS |
 			MMU_FTR_USE_TLBILX,
 		.icache_bsize		= 64,
@@ -2005,7 +2010,22 @@
 #endif /* CONFIG_PPC32 */
 #endif /* CONFIG_E500 */
 
-#ifdef CONFIG_PPC_BOOK3E_64
+#ifdef CONFIG_PPC_A2
+	{	/* Standard A2 (>= DD2) + FPU core */
+		.pvr_mask		= 0xffff0000,
+		.pvr_value		= 0x00480000,
+		.cpu_name		= "A2 (>= DD2)",
+		.cpu_features		= CPU_FTRS_A2,
+		.cpu_user_features	= COMMON_USER_PPC64,
+		.mmu_features		= MMU_FTRS_A2,
+		.icache_bsize		= 64,
+		.dcache_bsize		= 64,
+		.num_pmcs		= 0,
+		.cpu_setup		= __setup_cpu_a2,
+		.cpu_restore		= __restore_cpu_a2,
+		.machine_check		= machine_check_generic,
+		.platform		= "ppca2",
+	},
 	{	/* This is a default entry to get going, to be replaced by
 		 * a real one at some stage
 		 */
@@ -2026,7 +2046,7 @@
 		.machine_check		= machine_check_generic,
 		.platform		= "power6",
 	},
-#endif
+#endif /* CONFIG_PPC_A2 */
 };
 
 static struct cpu_spec the_cpu_spec;
diff -druN linux-2.6.39-libre/arch/powerpc/kernel/crash.c linux-3.0-rc7-libre/arch/powerpc/kernel/crash.c
--- linux-2.6.39-libre/arch/powerpc/kernel/crash.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/kernel/crash.c	2011-07-11 19:51:52.000000000 -0400
@@ -64,9 +64,9 @@
 		return;
 
 	hard_irq_disable();
-	if (!cpu_isset(cpu, cpus_in_crash))
+	if (!cpumask_test_cpu(cpu, &cpus_in_crash))
 		crash_save_cpu(regs, cpu);
-	cpu_set(cpu, cpus_in_crash);
+	cpumask_set_cpu(cpu, &cpus_in_crash);
 
 	/*
 	 * Entered via soft-reset - could be the kdump
@@ -77,8 +77,8 @@
 	 * Tell the kexec CPU that entered via soft-reset and ready
 	 * to go down.
 	 */
-	if (cpu_isset(cpu, cpus_in_sr)) {
-		cpu_clear(cpu, cpus_in_sr);
+	if (cpumask_test_cpu(cpu, &cpus_in_sr)) {
+		cpumask_clear_cpu(cpu, &cpus_in_sr);
 		atomic_inc(&enter_on_soft_reset);
 	}
 
@@ -87,7 +87,7 @@
 	 * This barrier is needed to make sure that all CPUs are stopped.
 	 * If not, soft-reset will be invoked to bring other CPUs.
 	 */
-	while (!cpu_isset(crashing_cpu, cpus_in_crash))
+	while (!cpumask_test_cpu(crashing_cpu, &cpus_in_crash))
 		cpu_relax();
 
 	if (ppc_md.kexec_cpu_down)
@@ -109,7 +109,7 @@
 {
 	unsigned int ncpus = num_online_cpus() - 1;/* Excluding the panic cpu */
 
-	cpu_clear(cpu, cpus_in_sr);
+	cpumask_clear_cpu(cpu, &cpus_in_sr);
 	while (atomic_read(&enter_on_soft_reset) != ncpus)
 		cpu_relax();
 }
@@ -132,7 +132,7 @@
 	 */
 	printk(KERN_EMERG "Sending IPI to other cpus...\n");
 	msecs = 10000;
-	while ((cpus_weight(cpus_in_crash) < ncpus) && (--msecs > 0)) {
+	while ((cpumask_weight(&cpus_in_crash) < ncpus) && (--msecs > 0)) {
 		cpu_relax();
 		mdelay(1);
 	}
@@ -144,52 +144,24 @@
 	 * user to do soft reset such that we get all.
 	 * Soft-reset will be used until better mechanism is implemented.
 	 */
-	if (cpus_weight(cpus_in_crash) < ncpus) {
+	if (cpumask_weight(&cpus_in_crash) < ncpus) {
 		printk(KERN_EMERG "done waiting: %d cpu(s) not responding\n",
-			ncpus - cpus_weight(cpus_in_crash));
+			ncpus - cpumask_weight(&cpus_in_crash));
 		printk(KERN_EMERG "Activate soft-reset to stop other cpu(s)\n");
-		cpus_in_sr = CPU_MASK_NONE;
+		cpumask_clear(&cpus_in_sr);
 		atomic_set(&enter_on_soft_reset, 0);
-		while (cpus_weight(cpus_in_crash) < ncpus)
+		while (cpumask_weight(&cpus_in_crash) < ncpus)
 			cpu_relax();
 	}
 	/*
 	 * Make sure all CPUs are entered via soft-reset if the kdump is
 	 * invoked using soft-reset.
 	 */
-	if (cpu_isset(cpu, cpus_in_sr))
+	if (cpumask_test_cpu(cpu, &cpus_in_sr))
 		crash_soft_reset_check(cpu);
 	/* Leave the IPI callback set */
 }
 
-/* wait for all the CPUs to hit real mode but timeout if they don't come in */
-#ifdef CONFIG_PPC_STD_MMU_64
-static void crash_kexec_wait_realmode(int cpu)
-{
-	unsigned int msecs;
-	int i;
-
-	msecs = 10000;
-	for (i=0; i < NR_CPUS && msecs > 0; i++) {
-		if (i == cpu)
-			continue;
-
-		while (paca[i].kexec_state < KEXEC_STATE_REAL_MODE) {
-			barrier();
-			if (!cpu_possible(i)) {
-				break;
-			}
-			if (!cpu_online(i)) {
-				break;
-			}
-			msecs--;
-			mdelay(1);
-		}
-	}
-	mb();
-}
-#endif	/* CONFIG_PPC_STD_MMU_64 */
-
 /*
  * This function will be called by secondary cpus or by kexec cpu
  * if soft-reset is activated to stop some CPUs.
@@ -210,7 +182,7 @@
 			 * exited using 'x'(exit and recover) or
 			 * kexec_should_crash() failed for all running tasks.
 			 */
-			cpu_clear(cpu, cpus_in_sr);
+			cpumask_clear_cpu(cpu, &cpus_in_sr);
 			local_irq_restore(flags);
 			return;
 		}
@@ -224,7 +196,7 @@
 		 * then start kexec boot.
 		 */
 		crash_soft_reset_check(cpu);
-		cpu_set(crashing_cpu, cpus_in_crash);
+		cpumask_set_cpu(crashing_cpu, &cpus_in_crash);
 		if (ppc_md.kexec_cpu_down)
 			ppc_md.kexec_cpu_down(1, 0);
 		machine_kexec(kexec_crash_image);
@@ -234,7 +206,6 @@
 }
 
 #else	/* ! CONFIG_SMP */
-static inline void crash_kexec_wait_realmode(int cpu) {}
 
 static void crash_kexec_prepare_cpus(int cpu)
 {
@@ -253,10 +224,40 @@
 
 void crash_kexec_secondary(struct pt_regs *regs)
 {
-	cpus_in_sr = CPU_MASK_NONE;
+	cpumask_clear(&cpus_in_sr);
 }
 #endif	/* CONFIG_SMP */
 
+/* wait for all the CPUs to hit real mode but timeout if they don't come in */
+#if defined(CONFIG_SMP) && defined(CONFIG_PPC_STD_MMU_64)
+static void crash_kexec_wait_realmode(int cpu)
+{
+	unsigned int msecs;
+	int i;
+
+	msecs = 10000;
+	for (i=0; i < nr_cpu_ids && msecs > 0; i++) {
+		if (i == cpu)
+			continue;
+
+		while (paca[i].kexec_state < KEXEC_STATE_REAL_MODE) {
+			barrier();
+			if (!cpu_possible(i)) {
+				break;
+			}
+			if (!cpu_online(i)) {
+				break;
+			}
+			msecs--;
+			mdelay(1);
+		}
+	}
+	mb();
+}
+#else
+static inline void crash_kexec_wait_realmode(int cpu) {}
+#endif	/* CONFIG_SMP && CONFIG_PPC_STD_MMU_64 */
+
 /*
  * Register a function to be called on shutdown.  Only use this if you
  * can't reset your device in the second kernel.
@@ -345,7 +346,7 @@
 	crashing_cpu = smp_processor_id();
 	crash_save_cpu(regs, crashing_cpu);
 	crash_kexec_prepare_cpus(crashing_cpu);
-	cpu_set(crashing_cpu, cpus_in_crash);
+	cpumask_set_cpu(crashing_cpu, &cpus_in_crash);
 	crash_kexec_wait_realmode(crashing_cpu);
 
 	machine_kexec_mask_interrupts();
diff -druN linux-2.6.39-libre/arch/powerpc/kernel/dbell.c linux-3.0-rc7-libre/arch/powerpc/kernel/dbell.c
--- linux-2.6.39-libre/arch/powerpc/kernel/dbell.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/kernel/dbell.c	2011-07-11 19:51:52.000000000 -0400
@@ -13,84 +13,35 @@
 #include <linux/kernel.h>
 #include <linux/smp.h>
 #include <linux/threads.h>
-#include <linux/percpu.h>
+#include <linux/hardirq.h>
 
 #include <asm/dbell.h>
 #include <asm/irq_regs.h>
 
 #ifdef CONFIG_SMP
-struct doorbell_cpu_info {
-	unsigned long	messages;	/* current messages bits */
-	unsigned int	tag;		/* tag value */
-};
-
-static DEFINE_PER_CPU(struct doorbell_cpu_info, doorbell_cpu_info);
-
 void doorbell_setup_this_cpu(void)
 {
-	struct doorbell_cpu_info *info = &__get_cpu_var(doorbell_cpu_info);
+	unsigned long tag = mfspr(SPRN_PIR) & 0x3fff;
 
-	info->messages = 0;
-	info->tag = mfspr(SPRN_PIR) & 0x3fff;
+	smp_muxed_ipi_set_data(smp_processor_id(), tag);
 }
 
-void doorbell_message_pass(int target, int msg)
+void doorbell_cause_ipi(int cpu, unsigned long data)
 {
-	struct doorbell_cpu_info *info;
-	int i;
-
-	if (target < NR_CPUS) {
-		info = &per_cpu(doorbell_cpu_info, target);
-		set_bit(msg, &info->messages);
-		ppc_msgsnd(PPC_DBELL, 0, info->tag);
-	}
-	else if (target == MSG_ALL_BUT_SELF) {
-		for_each_online_cpu(i) {
-			if (i == smp_processor_id())
-				continue;
-			info = &per_cpu(doorbell_cpu_info, i);
-			set_bit(msg, &info->messages);
-			ppc_msgsnd(PPC_DBELL, 0, info->tag);
-		}
-	}
-	else { /* target == MSG_ALL */
-		for_each_online_cpu(i) {
-			info = &per_cpu(doorbell_cpu_info, i);
-			set_bit(msg, &info->messages);
-		}
-		ppc_msgsnd(PPC_DBELL, PPC_DBELL_MSG_BRDCAST, 0);
-	}
+	ppc_msgsnd(PPC_DBELL, 0, data);
 }
 
 void doorbell_exception(struct pt_regs *regs)
 {
 	struct pt_regs *old_regs = set_irq_regs(regs);
-	struct doorbell_cpu_info *info = &__get_cpu_var(doorbell_cpu_info);
-	int msg;
-
-	/* Warning: regs can be NULL when called from irq enable */
 
-	if (!info->messages || (num_online_cpus() < 2))
-		goto out;
+	irq_enter();
 
-	for (msg = 0; msg < 4; msg++)
-		if (test_and_clear_bit(msg, &info->messages))
-			smp_message_recv(msg);
+	smp_ipi_demux();
 
-out:
+	irq_exit();
 	set_irq_regs(old_regs);
 }
-
-void doorbell_check_self(void)
-{
-	struct doorbell_cpu_info *info = &__get_cpu_var(doorbell_cpu_info);
-
-	if (!info->messages)
-		return;
-
-	ppc_msgsnd(PPC_DBELL, 0, info->tag);
-}
-
 #else /* CONFIG_SMP */
 void doorbell_exception(struct pt_regs *regs)
 {
diff -druN linux-2.6.39-libre/arch/powerpc/kernel/entry_64.S linux-3.0-rc7-libre/arch/powerpc/kernel/entry_64.S
--- linux-2.6.39-libre/arch/powerpc/kernel/entry_64.S	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/kernel/entry_64.S	2011-07-11 19:51:52.000000000 -0400
@@ -421,6 +421,12 @@
 	std	r24,THREAD_VRSAVE(r3)
 END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
 #endif /* CONFIG_ALTIVEC */
+#ifdef CONFIG_PPC64
+BEGIN_FTR_SECTION
+	mfspr	r25,SPRN_DSCR
+	std	r25,THREAD_DSCR(r3)
+END_FTR_SECTION_IFSET(CPU_FTR_DSCR)
+#endif
 	and.	r0,r0,r22
 	beq+	1f
 	andc	r22,r22,r0
@@ -462,10 +468,10 @@
   FTR_SECTION_ELSE_NESTED(95)
 	clrrdi	r6,r8,40	/* get its 1T ESID */
 	clrrdi	r9,r1,40	/* get current sp 1T ESID */
-  ALT_FTR_SECTION_END_NESTED_IFCLR(CPU_FTR_1T_SEGMENT, 95)
+  ALT_MMU_FTR_SECTION_END_NESTED_IFCLR(MMU_FTR_1T_SEGMENT, 95)
 FTR_SECTION_ELSE
 	b	2f
-ALT_FTR_SECTION_END_IFSET(CPU_FTR_SLB)
+ALT_MMU_FTR_SECTION_END_IFSET(MMU_FTR_SLB)
 	clrldi.	r0,r6,2		/* is new ESID c00000000? */
 	cmpd	cr1,r6,r9	/* or is new ESID the same as current ESID? */
 	cror	eq,4*cr1+eq,eq
@@ -479,7 +485,7 @@
 	li	r9,MMU_SEGSIZE_1T	/* insert B field */
 	oris	r6,r6,(MMU_SEGSIZE_1T << SLBIE_SSIZE_SHIFT)@h
 	rldimi	r7,r9,SLB_VSID_SSIZE_SHIFT,0
-END_FTR_SECTION_IFSET(CPU_FTR_1T_SEGMENT)
+END_MMU_FTR_SECTION_IFSET(MMU_FTR_1T_SEGMENT)
 
 	/* Update the last bolted SLB.  No write barriers are needed
 	 * here, provided we only update the current CPU's SLB shadow
@@ -491,7 +497,7 @@
 	std	r7,SLBSHADOW_STACKVSID(r9)  /* Save VSID */
 	std	r0,SLBSHADOW_STACKESID(r9)  /* Save ESID */
 
-	/* No need to check for CPU_FTR_NO_SLBIE_B here, since when
+	/* No need to check for MMU_FTR_NO_SLBIE_B here, since when
 	 * we have 1TB segments, the only CPUs known to have the errata
 	 * only support less than 1TB of system memory and we'll never
 	 * actually hit this code path.
@@ -522,6 +528,15 @@
 	mtspr	SPRN_VRSAVE,r0		/* if G4, restore VRSAVE reg */
 END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
 #endif /* CONFIG_ALTIVEC */
+#ifdef CONFIG_PPC64
+BEGIN_FTR_SECTION
+	ld	r0,THREAD_DSCR(r4)
+	cmpd	r0,r25
+	beq	1f
+	mtspr	SPRN_DSCR,r0
+1:	
+END_FTR_SECTION_IFSET(CPU_FTR_DSCR)
+#endif
 
 	/* r3-r13 are destroyed -- Cort */
 	REST_8GPRS(14, r1)
@@ -838,7 +853,7 @@
 
 _STATIC(rtas_return_loc)
 	/* relocation is off at this point */
-	mfspr	r4,SPRN_SPRG_PACA	/* Get PACA */
+	GET_PACA(r4)
 	clrldi	r4,r4,2			/* convert to realmode address */
 
 	bcl	20,31,$+4
@@ -869,7 +884,7 @@
 	REST_8GPRS(14, r1)		/* Restore the non-volatiles */
 	REST_10GPRS(22, r1)		/* ditto */
 
-	mfspr	r13,SPRN_SPRG_PACA
+	GET_PACA(r13)
 
 	ld	r4,_CCR(r1)
 	mtcr	r4
diff -druN linux-2.6.39-libre/arch/powerpc/kernel/exceptions-64e.S linux-3.0-rc7-libre/arch/powerpc/kernel/exceptions-64e.S
--- linux-2.6.39-libre/arch/powerpc/kernel/exceptions-64e.S	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/kernel/exceptions-64e.S	2011-07-11 19:51:52.000000000 -0400
@@ -17,6 +17,7 @@
 #include <asm/cputable.h>
 #include <asm/setup.h>
 #include <asm/thread_info.h>
+#include <asm/reg_a2.h>
 #include <asm/exception-64e.h>
 #include <asm/bug.h>
 #include <asm/irqflags.h>
@@ -252,9 +253,6 @@
 	.balign	0x1000
 	.globl interrupt_base_book3e
 interrupt_base_book3e:					/* fake trap */
-	/* Note: If real debug exceptions are supported by the HW, the vector
-	 * below will have to be patched up to point to an appropriate handler
-	 */
 	EXCEPTION_STUB(0x000, machine_check)		/* 0x0200 */
 	EXCEPTION_STUB(0x020, critical_input)		/* 0x0580 */
 	EXCEPTION_STUB(0x040, debug_crit)		/* 0x0d00 */
@@ -271,8 +269,13 @@
 	EXCEPTION_STUB(0x1a0, watchdog)			/* 0x09f0 */
 	EXCEPTION_STUB(0x1c0, data_tlb_miss)
 	EXCEPTION_STUB(0x1e0, instruction_tlb_miss)
+	EXCEPTION_STUB(0x260, perfmon)
 	EXCEPTION_STUB(0x280, doorbell)
 	EXCEPTION_STUB(0x2a0, doorbell_crit)
+	EXCEPTION_STUB(0x2c0, guest_doorbell)
+	EXCEPTION_STUB(0x2e0, guest_doorbell_crit)
+	EXCEPTION_STUB(0x300, hypercall)
+	EXCEPTION_STUB(0x320, ehpriv)
 
 	.globl interrupt_end_book3e
 interrupt_end_book3e:
@@ -454,6 +457,70 @@
 kernel_dbg_exc:
 	b	.	/* NYI */
 
+/* Debug exception as a debug interrupt*/
+	START_EXCEPTION(debug_debug);
+	DBG_EXCEPTION_PROLOG(0xd00, PROLOG_ADDITION_2REGS)
+
+	/*
+	 * If there is a single step or branch-taken exception in an
+	 * exception entry sequence, it was probably meant to apply to
+	 * the code where the exception occurred (since exception entry
+	 * doesn't turn off DE automatically).  We simulate the effect
+	 * of turning off DE on entry to an exception handler by turning
+	 * off DE in the DSRR1 value and clearing the debug status.
+	 */
+
+	mfspr	r14,SPRN_DBSR		/* check single-step/branch taken */
+	andis.	r15,r14,DBSR_IC@h
+	beq+	1f
+
+	LOAD_REG_IMMEDIATE(r14,interrupt_base_book3e)
+	LOAD_REG_IMMEDIATE(r15,interrupt_end_book3e)
+	cmpld	cr0,r10,r14
+	cmpld	cr1,r10,r15
+	blt+	cr0,1f
+	bge+	cr1,1f
+
+	/* here it looks like we got an inappropriate debug exception. */
+	lis	r14,DBSR_IC@h		/* clear the IC event */
+	rlwinm	r11,r11,0,~MSR_DE	/* clear DE in the DSRR1 value */
+	mtspr	SPRN_DBSR,r14
+	mtspr	SPRN_DSRR1,r11
+	lwz	r10,PACA_EXDBG+EX_CR(r13)	/* restore registers */
+	ld	r1,PACA_EXDBG+EX_R1(r13)
+	ld	r14,PACA_EXDBG+EX_R14(r13)
+	ld	r15,PACA_EXDBG+EX_R15(r13)
+	mtcr	r10
+	ld	r10,PACA_EXDBG+EX_R10(r13)	/* restore registers */
+	ld	r11,PACA_EXDBG+EX_R11(r13)
+	mfspr	r13,SPRN_SPRG_DBG_SCRATCH
+	rfdi
+
+	/* Normal debug exception */
+	/* XXX We only handle coming from userspace for now since we can't
+	 *     quite save properly an interrupted kernel state yet
+	 */
+1:	andi.	r14,r11,MSR_PR;		/* check for userspace again */
+	beq	kernel_dbg_exc;		/* if from kernel mode */
+
+	/* Now we mash up things to make it look like we are coming on a
+	 * normal exception
+	 */
+	mfspr	r15,SPRN_SPRG_DBG_SCRATCH
+	mtspr	SPRN_SPRG_GEN_SCRATCH,r15
+	mfspr	r14,SPRN_DBSR
+	EXCEPTION_COMMON(0xd00, PACA_EXDBG, INTS_DISABLE_ALL)
+	std	r14,_DSISR(r1)
+	addi	r3,r1,STACK_FRAME_OVERHEAD
+	mr	r4,r14
+	ld	r14,PACA_EXDBG+EX_R14(r13)
+	ld	r15,PACA_EXDBG+EX_R15(r13)
+	bl	.save_nvgprs
+	bl	.DebugException
+	b	.ret_from_except
+
+	MASKABLE_EXCEPTION(0x260, perfmon, .performance_monitor_exception, ACK_NONE)
+
 /* Doorbell interrupt */
 	MASKABLE_EXCEPTION(0x2070, doorbell, .doorbell_exception, ACK_NONE)
 
@@ -468,6 +535,11 @@
 //	b	ret_from_crit_except
 	b	.
 
+	MASKABLE_EXCEPTION(0x2c0, guest_doorbell, .unknown_exception, ACK_NONE)
+	MASKABLE_EXCEPTION(0x2e0, guest_doorbell_crit, .unknown_exception, ACK_NONE)
+	MASKABLE_EXCEPTION(0x310, hypercall, .unknown_exception, ACK_NONE)
+	MASKABLE_EXCEPTION(0x320, ehpriv, .unknown_exception, ACK_NONE)
+
 
 /*
  * An interrupt came in while soft-disabled; clear EE in SRR1,
@@ -587,7 +659,12 @@
 BAD_STACK_TRAMPOLINE(0x000)
 BAD_STACK_TRAMPOLINE(0x100)
 BAD_STACK_TRAMPOLINE(0x200)
+BAD_STACK_TRAMPOLINE(0x260)
+BAD_STACK_TRAMPOLINE(0x2c0)
+BAD_STACK_TRAMPOLINE(0x2e0)
 BAD_STACK_TRAMPOLINE(0x300)
+BAD_STACK_TRAMPOLINE(0x310)
+BAD_STACK_TRAMPOLINE(0x320)
 BAD_STACK_TRAMPOLINE(0x400)
 BAD_STACK_TRAMPOLINE(0x500)
 BAD_STACK_TRAMPOLINE(0x600)
@@ -864,8 +941,23 @@
 	 * that will have to be made dependent on whether we are running under
 	 * a hypervisor I suppose.
 	 */
-	ori	r3,r3,MAS0_HES | MAS0_WQ_ALLWAYS
-	mtspr	SPRN_MAS0,r3
+
+	/* BEWARE, MAGIC
+	 * This code is called as an ordinary function on the boot CPU. But to
+	 * avoid duplication, this code is also used in SCOM bringup of
+	 * secondary CPUs. We read the code between the initial_tlb_code_start
+	 * and initial_tlb_code_end labels one instruction at a time and RAM it
+	 * into the new core via SCOM. That doesn't process branches, so there
+	 * must be none between those two labels. It also means if this code
+	 * ever takes any parameters, the SCOM code must also be updated to
+	 * provide them.
+	 */
+	.globl a2_tlbinit_code_start
+a2_tlbinit_code_start:
+
+	ori	r11,r3,MAS0_WQ_ALLWAYS
+	oris	r11,r11,MAS0_ESEL(3)@h /* Use way 3: workaround A2 erratum 376 */
+	mtspr	SPRN_MAS0,r11
 	lis	r3,(MAS1_VALID | MAS1_IPROT)@h
 	ori	r3,r3,BOOK3E_PAGESZ_1GB << MAS1_TSIZE_SHIFT
 	mtspr	SPRN_MAS1,r3
@@ -879,18 +971,86 @@
 	/* Write the TLB entry */
 	tlbwe
 
+	.globl a2_tlbinit_after_linear_map
+a2_tlbinit_after_linear_map:
+
 	/* Now we branch the new virtual address mapped by this entry */
 	LOAD_REG_IMMEDIATE(r3,1f)
 	mtctr	r3
 	bctr
 
 1:	/* We are now running at PAGE_OFFSET, clean the TLB of everything
-	 * else (XXX we should scan for bolted crap from the firmware too)
+	 * else (including IPROTed things left by firmware)
+	 * r4 = TLBnCFG
+	 * r3 = current address (more or less)
 	 */
+
+	li	r5,0
+	mtspr	SPRN_MAS6,r5
+	tlbsx	0,r3
+
+	rlwinm	r9,r4,0,TLBnCFG_N_ENTRY
+	rlwinm	r10,r4,8,0xff
+	addi	r10,r10,-1	/* Get inner loop mask */
+
+	li	r3,1
+
+	mfspr	r5,SPRN_MAS1
+	rlwinm	r5,r5,0,(~(MAS1_VALID|MAS1_IPROT))
+
+	mfspr	r6,SPRN_MAS2
+	rldicr	r6,r6,0,51		/* Extract EPN */
+
+	mfspr	r7,SPRN_MAS0
+	rlwinm	r7,r7,0,0xffff0fff	/* Clear HES and WQ */
+
+	rlwinm	r8,r7,16,0xfff		/* Extract ESEL */
+
+2:	add	r4,r3,r8
+	and	r4,r4,r10
+
+	rlwimi	r7,r4,16,MAS0_ESEL_MASK
+
+	mtspr	SPRN_MAS0,r7
+	mtspr	SPRN_MAS1,r5
+	mtspr	SPRN_MAS2,r6
+	tlbwe
+
+	addi	r3,r3,1
+	and.	r4,r3,r10
+
+	bne	3f
+	addis	r6,r6,(1<<30)@h
+3:
+	cmpw	r3,r9
+	blt	2b
+
+	.globl  a2_tlbinit_after_iprot_flush
+a2_tlbinit_after_iprot_flush:
+
+#ifdef CONFIG_PPC_EARLY_DEBUG_WSP
+	/* Now establish early debug mappings if applicable */
+	/* Restore the MAS0 we used for linear mapping load */
+	mtspr	SPRN_MAS0,r11
+
+	lis	r3,(MAS1_VALID | MAS1_IPROT)@h
+	ori	r3,r3,(BOOK3E_PAGESZ_4K << MAS1_TSIZE_SHIFT)
+	mtspr	SPRN_MAS1,r3
+	LOAD_REG_IMMEDIATE(r3, WSP_UART_VIRT | MAS2_I | MAS2_G)
+	mtspr	SPRN_MAS2,r3
+	LOAD_REG_IMMEDIATE(r3, WSP_UART_PHYS | MAS3_SR | MAS3_SW)
+	mtspr	SPRN_MAS7_MAS3,r3
+	/* re-use the MAS8 value from the linear mapping */
+	tlbwe
+#endif /* CONFIG_PPC_EARLY_DEBUG_WSP */
+
 	PPC_TLBILX(0,0,0)
 	sync
 	isync
 
+	.globl a2_tlbinit_code_end
+a2_tlbinit_code_end:
+
 	/* We translate LR and return */
 	mflr	r3
 	tovirt(r3,r3)
@@ -1040,3 +1200,33 @@
 	sync
 
 	blr
+
+_GLOBAL(setup_perfmon_ivor)
+	SET_IVOR(35, 0x260) /* Performance Monitor */
+	blr
+
+_GLOBAL(setup_doorbell_ivors)
+	SET_IVOR(36, 0x280) /* Processor Doorbell */
+	SET_IVOR(37, 0x2a0) /* Processor Doorbell Crit */
+
+	/* Check MMUCFG[LPIDSIZE] to determine if we have category E.HV */
+	mfspr	r10,SPRN_MMUCFG
+	rlwinm.	r10,r10,0,MMUCFG_LPIDSIZE
+	beqlr
+
+	SET_IVOR(38, 0x2c0) /* Guest Processor Doorbell */
+	SET_IVOR(39, 0x2e0) /* Guest Processor Doorbell Crit/MC */
+	blr
+
+_GLOBAL(setup_ehv_ivors)
+	/*
+	 * We may be running as a guest and lack E.HV even on a chip
+	 * that normally has it.
+	 */
+	mfspr	r10,SPRN_MMUCFG
+	rlwinm.	r10,r10,0,MMUCFG_LPIDSIZE
+	beqlr
+
+	SET_IVOR(40, 0x300) /* Embedded Hypervisor System Call */
+	SET_IVOR(41, 0x320) /* Embedded Hypervisor Privilege */
+	blr
diff -druN linux-2.6.39-libre/arch/powerpc/kernel/exceptions-64s.S linux-3.0-rc7-libre/arch/powerpc/kernel/exceptions-64s.S
--- linux-2.6.39-libre/arch/powerpc/kernel/exceptions-64s.S	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/kernel/exceptions-64s.S	2011-07-11 19:51:52.000000000 -0400
@@ -37,23 +37,51 @@
 	.globl __start_interrupts
 __start_interrupts:
 
-	STD_EXCEPTION_PSERIES(0x100, system_reset)
+	.globl system_reset_pSeries;
+system_reset_pSeries:
+	HMT_MEDIUM;
+	DO_KVM	0x100;
+	SET_SCRATCH0(r13)
+#ifdef CONFIG_PPC_P7_NAP
+BEGIN_FTR_SECTION
+	/* Running native on arch 2.06 or later, check if we are
+	 * waking up from nap. We only handle no state loss and
+	 * supervisor state loss. We do -not- handle hypervisor
+	 * state loss at this time.
+	 */
+	mfspr	r13,SPRN_SRR1
+	rlwinm	r13,r13,47-31,30,31
+	cmpwi	cr0,r13,1
+	bne	1f
+	b	.power7_wakeup_noloss
+1:	cmpwi	cr0,r13,2
+	bne	1f
+	b	.power7_wakeup_loss
+	/* Total loss of HV state is fatal, we could try to use the
+	 * PIR to locate a PACA, then use an emergency stack etc...
+	 * but for now, let's just stay stuck here
+	 */
+1:	cmpwi	cr0,r13,3
+	beq	.
+END_FTR_SECTION_IFSET(CPU_FTR_HVMODE_206)
+#endif /* CONFIG_PPC_P7_NAP */
+	EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, system_reset_common, EXC_STD)
 
 	. = 0x200
 _machine_check_pSeries:
 	HMT_MEDIUM
 	DO_KVM	0x200
-	mtspr	SPRN_SPRG_SCRATCH0,r13		/* save r13 */
-	EXCEPTION_PROLOG_PSERIES(PACA_EXMC, machine_check_common)
+	SET_SCRATCH0(r13)
+	EXCEPTION_PROLOG_PSERIES(PACA_EXMC, machine_check_common, EXC_STD)
 
 	. = 0x300
 	.globl data_access_pSeries
 data_access_pSeries:
 	HMT_MEDIUM
 	DO_KVM	0x300
-	mtspr	SPRN_SPRG_SCRATCH0,r13
+	SET_SCRATCH0(r13)
 BEGIN_FTR_SECTION
-	mfspr	r13,SPRN_SPRG_PACA
+	GET_PACA(r13)
 	std	r9,PACA_EXSLB+EX_R9(r13)
 	std	r10,PACA_EXSLB+EX_R10(r13)
 	mfspr	r10,SPRN_DAR
@@ -67,22 +95,22 @@
 	std	r11,PACA_EXGEN+EX_R11(r13)
 	ld	r11,PACA_EXSLB+EX_R9(r13)
 	std	r12,PACA_EXGEN+EX_R12(r13)
-	mfspr	r12,SPRN_SPRG_SCRATCH0
+	GET_SCRATCH0(r12)
 	std	r10,PACA_EXGEN+EX_R10(r13)
 	std	r11,PACA_EXGEN+EX_R9(r13)
 	std	r12,PACA_EXGEN+EX_R13(r13)
-	EXCEPTION_PROLOG_PSERIES_1(data_access_common)
+	EXCEPTION_PROLOG_PSERIES_1(data_access_common, EXC_STD)
 FTR_SECTION_ELSE
-	EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, data_access_common)
-ALT_FTR_SECTION_END_IFCLR(CPU_FTR_SLB)
+	EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, data_access_common, EXC_STD)
+ALT_MMU_FTR_SECTION_END_IFCLR(MMU_FTR_SLB)
 
 	. = 0x380
 	.globl data_access_slb_pSeries
 data_access_slb_pSeries:
 	HMT_MEDIUM
 	DO_KVM	0x380
-	mtspr	SPRN_SPRG_SCRATCH0,r13
-	mfspr	r13,SPRN_SPRG_PACA		/* get paca address into r13 */
+	SET_SCRATCH0(r13)
+	GET_PACA(r13)
 	std	r3,PACA_EXSLB+EX_R3(r13)
 	mfspr	r3,SPRN_DAR
 	std	r9,PACA_EXSLB+EX_R9(r13)	/* save r9 - r12 */
@@ -95,7 +123,7 @@
 	std	r10,PACA_EXSLB+EX_R10(r13)
 	std	r11,PACA_EXSLB+EX_R11(r13)
 	std	r12,PACA_EXSLB+EX_R12(r13)
-	mfspr	r10,SPRN_SPRG_SCRATCH0
+	GET_SCRATCH0(r10)
 	std	r10,PACA_EXSLB+EX_R13(r13)
 	mfspr	r12,SPRN_SRR1		/* and SRR1 */
 #ifndef CONFIG_RELOCATABLE
@@ -113,15 +141,15 @@
 	bctr
 #endif
 
-	STD_EXCEPTION_PSERIES(0x400, instruction_access)
+	STD_EXCEPTION_PSERIES(0x400, 0x400, instruction_access)
 
 	. = 0x480
 	.globl instruction_access_slb_pSeries
 instruction_access_slb_pSeries:
 	HMT_MEDIUM
 	DO_KVM	0x480
-	mtspr	SPRN_SPRG_SCRATCH0,r13
-	mfspr	r13,SPRN_SPRG_PACA		/* get paca address into r13 */
+	SET_SCRATCH0(r13)
+	GET_PACA(r13)
 	std	r3,PACA_EXSLB+EX_R3(r13)
 	mfspr	r3,SPRN_SRR0		/* SRR0 is faulting address */
 	std	r9,PACA_EXSLB+EX_R9(r13)	/* save r9 - r12 */
@@ -134,7 +162,7 @@
 	std	r10,PACA_EXSLB+EX_R10(r13)
 	std	r11,PACA_EXSLB+EX_R11(r13)
 	std	r12,PACA_EXSLB+EX_R12(r13)
-	mfspr	r10,SPRN_SPRG_SCRATCH0
+	GET_SCRATCH0(r10)
 	std	r10,PACA_EXSLB+EX_R13(r13)
 	mfspr	r12,SPRN_SRR1		/* and SRR1 */
 #ifndef CONFIG_RELOCATABLE
@@ -147,13 +175,29 @@
 	bctr
 #endif
 
-	MASKABLE_EXCEPTION_PSERIES(0x500, hardware_interrupt)
-	STD_EXCEPTION_PSERIES(0x600, alignment)
-	STD_EXCEPTION_PSERIES(0x700, program_check)
-	STD_EXCEPTION_PSERIES(0x800, fp_unavailable)
-	MASKABLE_EXCEPTION_PSERIES(0x900, decrementer)
-	STD_EXCEPTION_PSERIES(0xa00, trap_0a)
-	STD_EXCEPTION_PSERIES(0xb00, trap_0b)
+	/* We open code these as we can't have a ". = x" (even with
+	 * x = "." within a feature section
+	 */
+	. = 0x500;
+	.globl hardware_interrupt_pSeries;
+	.globl hardware_interrupt_hv;
+hardware_interrupt_pSeries:
+hardware_interrupt_hv:
+	BEGIN_FTR_SECTION
+		_MASKABLE_EXCEPTION_PSERIES(0x500, hardware_interrupt, EXC_STD)
+	FTR_SECTION_ELSE
+		_MASKABLE_EXCEPTION_PSERIES(0x502, hardware_interrupt, EXC_HV)
+	ALT_FTR_SECTION_END_IFCLR(CPU_FTR_HVMODE_206)
+
+	STD_EXCEPTION_PSERIES(0x600, 0x600, alignment)
+	STD_EXCEPTION_PSERIES(0x700, 0x700, program_check)
+	STD_EXCEPTION_PSERIES(0x800, 0x800, fp_unavailable)
+
+	MASKABLE_EXCEPTION_PSERIES(0x900, 0x900, decrementer)
+	MASKABLE_EXCEPTION_HV(0x980, 0x980, decrementer)
+
+	STD_EXCEPTION_PSERIES(0xa00, 0xa00, trap_0a)
+	STD_EXCEPTION_PSERIES(0xb00, 0xb00, trap_0b)
 
 	. = 0xc00
 	.globl	system_call_pSeries
@@ -165,13 +209,13 @@
 	beq-	1f
 END_FTR_SECTION_IFSET(CPU_FTR_REAL_LE)
 	mr	r9,r13
-	mfspr	r13,SPRN_SPRG_PACA
+	GET_PACA(r13)
 	mfspr	r11,SPRN_SRR0
-	ld	r12,PACAKBASE(r13)
-	ld	r10,PACAKMSR(r13)
-	LOAD_HANDLER(r12, system_call_entry)
-	mtspr	SPRN_SRR0,r12
 	mfspr	r12,SPRN_SRR1
+	ld	r10,PACAKBASE(r13)
+	LOAD_HANDLER(r10, system_call_entry)
+	mtspr	SPRN_SRR0,r10
+	ld	r10,PACAKMSR(r13)
 	mtspr	SPRN_SRR1,r10
 	rfid
 	b	.	/* prevent speculative execution */
@@ -183,8 +227,21 @@
 	rfid		/* return to userspace */
 	b	.
 
-	STD_EXCEPTION_PSERIES(0xd00, single_step)
-	STD_EXCEPTION_PSERIES(0xe00, trap_0e)
+	STD_EXCEPTION_PSERIES(0xd00, 0xd00, single_step)
+
+	/* At 0xe??? we have a bunch of hypervisor exceptions, we branch
+	 * out of line to handle them
+	 */
+	. = 0xe00
+	b	h_data_storage_hv
+	. = 0xe20
+	b	h_instr_storage_hv
+	. = 0xe40
+	b	emulation_assist_hv
+	. = 0xe50
+	b	hmi_exception_hv
+	. = 0xe60
+	b	hmi_exception_hv
 
 	/* We need to deal with the Altivec unavailable exception
 	 * here which is at 0xf20, thus in the middle of the
@@ -193,39 +250,42 @@
 	 */
 performance_monitor_pSeries_1:
 	. = 0xf00
-	DO_KVM	0xf00
 	b	performance_monitor_pSeries
 
 altivec_unavailable_pSeries_1:
 	. = 0xf20
-	DO_KVM	0xf20
 	b	altivec_unavailable_pSeries
 
 vsx_unavailable_pSeries_1:
 	. = 0xf40
-	DO_KVM	0xf40
 	b	vsx_unavailable_pSeries
 
 #ifdef CONFIG_CBE_RAS
-	HSTD_EXCEPTION_PSERIES(0x1200, cbe_system_error)
+	STD_EXCEPTION_HV(0x1200, 0x1202, cbe_system_error)
 #endif /* CONFIG_CBE_RAS */
-	STD_EXCEPTION_PSERIES(0x1300, instruction_breakpoint)
+	STD_EXCEPTION_PSERIES(0x1300, 0x1300, instruction_breakpoint)
 #ifdef CONFIG_CBE_RAS
-	HSTD_EXCEPTION_PSERIES(0x1600, cbe_maintenance)
+	STD_EXCEPTION_HV(0x1600, 0x1602, cbe_maintenance)
 #endif /* CONFIG_CBE_RAS */
-	STD_EXCEPTION_PSERIES(0x1700, altivec_assist)
+	STD_EXCEPTION_PSERIES(0x1700, 0x1700, altivec_assist)
 #ifdef CONFIG_CBE_RAS
-	HSTD_EXCEPTION_PSERIES(0x1800, cbe_thermal)
+	STD_EXCEPTION_HV(0x1800, 0x1802, cbe_thermal)
 #endif /* CONFIG_CBE_RAS */
 
 	. = 0x3000
 
-/*** pSeries interrupt support ***/
+/*** Out of line interrupts support ***/
+
+	/* moved from 0xe00 */
+	STD_EXCEPTION_HV(., 0xe00, h_data_storage)
+	STD_EXCEPTION_HV(., 0xe20, h_instr_storage)
+	STD_EXCEPTION_HV(., 0xe40, emulation_assist)
+	STD_EXCEPTION_HV(., 0xe60, hmi_exception) /* need to flush cache ? */
 
 	/* moved from 0xf00 */
-	STD_EXCEPTION_PSERIES(., performance_monitor)
-	STD_EXCEPTION_PSERIES(., altivec_unavailable)
-	STD_EXCEPTION_PSERIES(., vsx_unavailable)
+	STD_EXCEPTION_PSERIES(., 0xf00, performance_monitor)
+	STD_EXCEPTION_PSERIES(., 0xf20, altivec_unavailable)
+	STD_EXCEPTION_PSERIES(., 0xf40, vsx_unavailable)
 
 /*
  * An interrupt came in while soft-disabled; clear EE in SRR1,
@@ -240,17 +300,30 @@
 	rotldi	r10,r10,16
 	mtspr	SPRN_SRR1,r10
 	ld	r10,PACA_EXGEN+EX_R10(r13)
-	mfspr	r13,SPRN_SPRG_SCRATCH0
+	GET_SCRATCH0(r13)
 	rfid
 	b	.
 
+masked_Hinterrupt:
+	stb	r10,PACAHARDIRQEN(r13)
+	mtcrf	0x80,r9
+	ld	r9,PACA_EXGEN+EX_R9(r13)
+	mfspr	r10,SPRN_HSRR1
+	rldicl	r10,r10,48,1		/* clear MSR_EE */
+	rotldi	r10,r10,16
+	mtspr	SPRN_HSRR1,r10
+	ld	r10,PACA_EXGEN+EX_R10(r13)
+	GET_SCRATCH0(r13)
+	hrfid
+	b	.
+
 	.align	7
 do_stab_bolted_pSeries:
 	std	r11,PACA_EXSLB+EX_R11(r13)
 	std	r12,PACA_EXSLB+EX_R12(r13)
-	mfspr	r10,SPRN_SPRG_SCRATCH0
+	GET_SCRATCH0(r10)
 	std	r10,PACA_EXSLB+EX_R13(r13)
-	EXCEPTION_PROLOG_PSERIES_1(.do_stab_bolted)
+	EXCEPTION_PROLOG_PSERIES_1(.do_stab_bolted, EXC_STD)
 
 #ifdef CONFIG_PPC_PSERIES
 /*
@@ -260,15 +333,15 @@
       .align 7
 system_reset_fwnmi:
 	HMT_MEDIUM
-	mtspr	SPRN_SPRG_SCRATCH0,r13		/* save r13 */
-	EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, system_reset_common)
+	SET_SCRATCH0(r13)		/* save r13 */
+	EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, system_reset_common, EXC_STD)
 
 	.globl machine_check_fwnmi
       .align 7
 machine_check_fwnmi:
 	HMT_MEDIUM
-	mtspr	SPRN_SPRG_SCRATCH0,r13		/* save r13 */
-	EXCEPTION_PROLOG_PSERIES(PACA_EXMC, machine_check_common)
+	SET_SCRATCH0(r13)		/* save r13 */
+	EXCEPTION_PROLOG_PSERIES(PACA_EXMC, machine_check_common, EXC_STD)
 
 #endif /* CONFIG_PPC_PSERIES */
 
@@ -282,7 +355,7 @@
 	std	r10,PACA_EXGEN+EX_R10(r13)
 	std	r11,PACA_EXGEN+EX_R11(r13)
 	std	r12,PACA_EXGEN+EX_R12(r13)
-	mfspr	r10,SPRG_SCRATCH0
+	GET_SCRATCH0(r10)
 	ld	r11,PACA_EXSLB+EX_R9(r13)
 	ld	r12,PACA_EXSLB+EX_R3(r13)
 	std	r10,PACA_EXGEN+EX_R13(r13)
@@ -342,6 +415,8 @@
 	STD_EXCEPTION_COMMON(0xb00, trap_0b, .unknown_exception)
 	STD_EXCEPTION_COMMON(0xd00, single_step, .single_step_exception)
 	STD_EXCEPTION_COMMON(0xe00, trap_0e, .unknown_exception)
+        STD_EXCEPTION_COMMON(0xe40, emulation_assist, .program_check_exception)
+        STD_EXCEPTION_COMMON(0xe60, hmi_exception, .unknown_exception)
 	STD_EXCEPTION_COMMON_IDLE(0xf00, performance_monitor, .performance_monitor_exception)
 	STD_EXCEPTION_COMMON(0x1300, instruction_breakpoint, .instruction_breakpoint_exception)
 #ifdef CONFIG_ALTIVEC
@@ -386,9 +461,24 @@
 	std	r12,_XER(r1)
 	SAVE_GPR(0,r1)
 	SAVE_GPR(2,r1)
-	SAVE_4GPRS(3,r1)
-	SAVE_2GPRS(7,r1)
-	SAVE_10GPRS(12,r1)
+	ld	r10,EX_R3(r3)
+	std	r10,GPR3(r1)
+	SAVE_GPR(4,r1)
+	SAVE_4GPRS(5,r1)
+	ld	r9,EX_R9(r3)
+	ld	r10,EX_R10(r3)
+	SAVE_2GPRS(9,r1)
+	ld	r9,EX_R11(r3)
+	ld	r10,EX_R12(r3)
+	ld	r11,EX_R13(r3)
+	std	r9,GPR11(r1)
+	std	r10,GPR12(r1)
+	std	r11,GPR13(r1)
+BEGIN_FTR_SECTION
+	ld	r10,EX_CFAR(r3)
+	std	r10,ORIG_GPR3(r1)
+END_FTR_SECTION_IFSET(CPU_FTR_CFAR)
+	SAVE_8GPRS(14,r1)
 	SAVE_10GPRS(22,r1)
 	lhz	r12,PACA_TRAP_SAVE(r13)
 	std	r12,_TRAP(r1)
@@ -397,6 +487,9 @@
 	li	r12,0
 	std	r12,0(r11)
 	ld	r2,PACATOC(r13)
+	ld	r11,exception_marker@toc(r2)
+	std	r12,RESULT(r1)
+	std	r11,STACK_FRAME_OVERHEAD-16(r1)
 1:	addi	r3,r1,STACK_FRAME_OVERHEAD
 	bl	.kernel_bad_stack
 	b	1b
@@ -419,6 +512,19 @@
 	li	r5,0x300
 	b	.do_hash_page	 	/* Try to handle as hpte fault */
 
+	.align  7
+        .globl  h_data_storage_common
+h_data_storage_common:
+        mfspr   r10,SPRN_HDAR
+        std     r10,PACA_EXGEN+EX_DAR(r13)
+        mfspr   r10,SPRN_HDSISR
+        stw     r10,PACA_EXGEN+EX_DSISR(r13)
+        EXCEPTION_PROLOG_COMMON(0xe00, PACA_EXGEN)
+        bl      .save_nvgprs
+        addi    r3,r1,STACK_FRAME_OVERHEAD
+        bl      .unknown_exception
+        b       .ret_from_except
+
 	.align	7
 	.globl instruction_access_common
 instruction_access_common:
@@ -428,6 +534,8 @@
 	li	r5,0x400
 	b	.do_hash_page		/* Try to handle as hpte fault */
 
+        STD_EXCEPTION_COMMON(0xe20, h_instr_storage, .unknown_exception)
+
 /*
  * Here is the common SLB miss user that is used when going to virtual
  * mode for SLB misses, that is currently not used
@@ -750,7 +858,7 @@
 BEGIN_FTR_SECTION
 	andis.	r0,r4,0x0020		/* Is it a segment table fault? */
 	bne-	do_ste_alloc		/* If so handle it */
-END_FTR_SECTION_IFCLR(CPU_FTR_SLB)
+END_MMU_FTR_SECTION_IFCLR(MMU_FTR_SLB)
 
 	clrrdi	r11,r1,THREAD_SHIFT
 	lwz	r0,TI_PREEMPT(r11)	/* If we're in an "NMI" */
diff -druN linux-2.6.39-libre/arch/powerpc/kernel/ftrace.c linux-3.0-rc7-libre/arch/powerpc/kernel/ftrace.c
--- linux-2.6.39-libre/arch/powerpc/kernel/ftrace.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/kernel/ftrace.c	2011-07-11 19:51:52.000000000 -0400
@@ -22,6 +22,7 @@
 #include <asm/cacheflush.h>
 #include <asm/code-patching.h>
 #include <asm/ftrace.h>
+#include <asm/syscall.h>
 
 
 #ifdef CONFIG_DYNAMIC_FTRACE
@@ -600,3 +601,10 @@
 	}
 }
 #endif /* CONFIG_FUNCTION_GRAPH_TRACER */
+
+#if defined(CONFIG_FTRACE_SYSCALLS) && defined(CONFIG_PPC64)
+unsigned long __init arch_syscall_addr(int nr)
+{
+	return sys_call_table[nr*2];
+}
+#endif /* CONFIG_FTRACE_SYSCALLS && CONFIG_PPC64 */
diff -druN linux-2.6.39-libre/arch/powerpc/kernel/head_32.S linux-3.0-rc7-libre/arch/powerpc/kernel/head_32.S
--- linux-2.6.39-libre/arch/powerpc/kernel/head_32.S	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/kernel/head_32.S	2011-07-11 19:51:52.000000000 -0400
@@ -805,19 +805,6 @@
 	blr
 
 #ifdef CONFIG_SMP
-#ifdef CONFIG_GEMINI
-	.globl	__secondary_start_gemini
-__secondary_start_gemini:
-        mfspr   r4,SPRN_HID0
-        ori     r4,r4,HID0_ICFI
-        li      r3,0
-        ori     r3,r3,HID0_ICE
-        andc    r4,r4,r3
-        mtspr   SPRN_HID0,r4
-        sync
-        b       __secondary_start
-#endif /* CONFIG_GEMINI */
-
 	.globl __secondary_start_mpc86xx
 __secondary_start_mpc86xx:
 	mfspr	r3, SPRN_PIR
@@ -890,15 +877,6 @@
 	mtspr	SPRN_SRR1,r4
 	SYNC
 	RFI
-
-_GLOBAL(start_secondary_resume)
-	/* Reset stack */
-	rlwinm	r1,r1,0,0,(31-THREAD_SHIFT)	/* current_thread_info() */
-	addi	r1,r1,THREAD_SIZE-STACK_FRAME_OVERHEAD
-	li	r3,0
-	std	r3,0(r1)		/* Zero the stack frame pointer	*/
-	bl	start_secondary
-	b	.
 #endif /* CONFIG_SMP */
 
 #ifdef CONFIG_KVM_BOOK3S_HANDLER
diff -druN linux-2.6.39-libre/arch/powerpc/kernel/head_64.S linux-3.0-rc7-libre/arch/powerpc/kernel/head_64.S
--- linux-2.6.39-libre/arch/powerpc/kernel/head_64.S	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/kernel/head_64.S	2011-07-11 19:51:52.000000000 -0400
@@ -147,6 +147,8 @@
 	mtctr	r4
 	mr	r3,r24
 	li	r4,0
+	/* Make sure that patched code is visible */
+	isync
 	bctr
 #else
 	BUG_OPCODE
@@ -216,19 +218,25 @@
 	 */
 	LOAD_REG_ADDR(r13, paca)	/* Load paca pointer		 */
 	ld	r13,0(r13)		/* Get base vaddr of paca array	 */
+#ifndef CONFIG_SMP
+	addi	r13,r13,PACA_SIZE	/* know r13 if used accidentally */
+	b	.kexec_wait		/* wait for next kernel if !SMP	 */
+#else
+	LOAD_REG_ADDR(r7, nr_cpu_ids)	/* Load nr_cpu_ids address       */
+	lwz	r7,0(r7)		/* also the max paca allocated 	 */
 	li	r5,0			/* logical cpu id                */
 1:	lhz	r6,PACAHWCPUID(r13)	/* Load HW procid from paca      */
 	cmpw	r6,r24			/* Compare to our id             */
 	beq	2f
 	addi	r13,r13,PACA_SIZE	/* Loop to next PACA on miss     */
 	addi	r5,r5,1
-	cmpwi	r5,NR_CPUS
+	cmpw	r5,r7			/* Check if more pacas exist     */
 	blt	1b
 
 	mr	r3,r24			/* not found, copy phys to r3	 */
 	b	.kexec_wait		/* next kernel might do better	 */
 
-2:	mtspr	SPRN_SPRG_PACA,r13	/* Save vaddr of paca in an SPRG */
+2:	SET_PACA(r13)
 #ifdef CONFIG_PPC_BOOK3E
 	addi	r12,r13,PACA_EXTLB	/* and TLB exc frame in another  */
 	mtspr	SPRN_SPRG_TLB_EXFRAME,r12
@@ -236,34 +244,39 @@
 
 	/* From now on, r24 is expected to be logical cpuid */
 	mr	r24,r5
-3:	HMT_LOW
-	lbz	r23,PACAPROCSTART(r13)	/* Test if this processor should */
-					/* start.			 */
-
-#ifndef CONFIG_SMP
-	b	3b			/* Never go on non-SMP		 */
-#else
-	cmpwi	0,r23,0
-	beq	3b			/* Loop until told to go	 */
-
-	sync				/* order paca.run and cur_cpu_spec */
 
 	/* See if we need to call a cpu state restore handler */
 	LOAD_REG_ADDR(r23, cur_cpu_spec)
 	ld	r23,0(r23)
 	ld	r23,CPU_SPEC_RESTORE(r23)
 	cmpdi	0,r23,0
-	beq	4f
+	beq	3f
 	ld	r23,0(r23)
 	mtctr	r23
 	bctrl
 
-4:	/* Create a temp kernel stack for use before relocation is on.	*/
+3:	LOAD_REG_ADDR(r3, boot_cpu_count) /* Decrement boot_cpu_count */
+	lwarx	r4,0,r3
+	subi	r4,r4,1
+	stwcx.	r4,0,r3
+	bne	3b
+	isync
+
+4:	HMT_LOW
+	lbz	r23,PACAPROCSTART(r13)	/* Test if this processor should */
+					/* start.			 */
+	cmpwi	0,r23,0
+	beq	4b			/* Loop until told to go	 */
+
+	sync				/* order paca.run and cur_cpu_spec */
+	isync				/* In case code patching happened */
+
+	/* Create a temp kernel stack for use before relocation is on.	*/
 	ld	r1,PACAEMERGSP(r13)
 	subi	r1,r1,STACK_FRAME_OVERHEAD
 
 	b	__secondary_start
-#endif
+#endif /* SMP */
 
 /*
  * Turn the MMU off.
@@ -534,7 +547,7 @@
 	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*/
+	SET_PACA(r13)			/* Save vaddr of paca in an SPRG*/
 
 	/* Mark interrupts soft and hard disabled (they might be enabled
 	 * in the PACA when doing hotplug)
@@ -645,7 +658,7 @@
 	oris	r11,r11,0x8000		/* CM bit set, we'll set ICM later */
 	mtmsr	r11
 #else /* CONFIG_PPC_BOOK3E */
-	li	r12,(MSR_SF | MSR_ISF)@highest
+	li	r12,(MSR_64BIT | MSR_ISF)@highest
 	sldi	r12,r12,48
 	or	r11,r11,r12
 	mtmsrd	r11
diff -druN linux-2.6.39-libre/arch/powerpc/kernel/idle_power7.S linux-3.0-rc7-libre/arch/powerpc/kernel/idle_power7.S
--- linux-2.6.39-libre/arch/powerpc/kernel/idle_power7.S	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/powerpc/kernel/idle_power7.S	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,97 @@
+/*
+ *  This file contains the power_save function for 970-family CPUs.
+ *
+ *  This program is free software; you can redistribute it and/or
+ *  modify it under the terms of the 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/threads.h>
+#include <asm/processor.h>
+#include <asm/page.h>
+#include <asm/cputable.h>
+#include <asm/thread_info.h>
+#include <asm/ppc_asm.h>
+#include <asm/asm-offsets.h>
+#include <asm/ppc-opcode.h>
+
+#undef DEBUG
+
+	.text
+
+_GLOBAL(power7_idle)
+	/* Now check if user or arch enabled NAP mode */
+	LOAD_REG_ADDRBASE(r3,powersave_nap)
+	lwz	r4,ADDROFF(powersave_nap)(r3)
+	cmpwi	0,r4,0
+	beqlr
+
+	/* NAP is a state loss, we create a regs frame on the
+	 * stack, fill it up with the state we care about and
+	 * stick a pointer to it in PACAR1. We really only
+	 * need to save PC, some CR bits and the NV GPRs,
+	 * but for now an interrupt frame will do.
+	 */
+	mflr	r0
+	std	r0,16(r1)
+	stdu	r1,-INT_FRAME_SIZE(r1)
+	std	r0,_LINK(r1)
+	std	r0,_NIP(r1)
+
+#ifndef CONFIG_SMP
+	/* Make sure FPU, VSX etc... are flushed as we may lose
+	 * state when going to nap mode
+	 */
+	bl	.discard_lazy_cpu_state
+#endif /* CONFIG_SMP */
+
+	/* Hard disable interrupts */
+	mfmsr	r9
+	rldicl	r9,r9,48,1
+	rotldi	r9,r9,16
+	mtmsrd	r9,1			/* hard-disable interrupts */
+	li	r0,0
+	stb	r0,PACASOFTIRQEN(r13)	/* we'll hard-enable shortly */
+	stb	r0,PACAHARDIRQEN(r13)
+
+	/* Continue saving state */
+	SAVE_GPR(2, r1)
+	SAVE_NVGPRS(r1)
+	mfcr	r3
+	std	r3,_CCR(r1)
+	std	r9,_MSR(r1)
+	std	r1,PACAR1(r13)
+
+	/* Magic NAP mode enter sequence */
+	std	r0,0(r1)
+	ptesync
+	ld	r0,0(r1)
+1:	cmp	cr0,r0,r0
+	bne	1b
+	PPC_NAP
+	b	.
+
+_GLOBAL(power7_wakeup_loss)
+	GET_PACA(r13)
+	ld	r1,PACAR1(r13)
+	REST_NVGPRS(r1)
+	REST_GPR(2, r1)
+	ld	r3,_CCR(r1)
+	ld	r4,_MSR(r1)
+	ld	r5,_NIP(r1)
+	addi	r1,r1,INT_FRAME_SIZE
+	mtcr	r3
+	mtspr	SPRN_SRR1,r4
+	mtspr	SPRN_SRR0,r5
+	rfid
+
+_GLOBAL(power7_wakeup_noloss)
+	GET_PACA(r13)
+	ld	r1,PACAR1(r13)
+	ld	r4,_MSR(r1)
+	ld	r5,_NIP(r1)
+	addi	r1,r1,INT_FRAME_SIZE
+	mtspr	SPRN_SRR1,r4
+	mtspr	SPRN_SRR0,r5
+	rfid
diff -druN linux-2.6.39-libre/arch/powerpc/kernel/io-workarounds.c linux-3.0-rc7-libre/arch/powerpc/kernel/io-workarounds.c
--- linux-2.6.39-libre/arch/powerpc/kernel/io-workarounds.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/powerpc/kernel/io-workarounds.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,188 @@
+/*
+ * Support PCI IO workaround
+ *
+ *  Copyright (C) 2006 Benjamin Herrenschmidt <benh@kernel.crashing.org>
+ *		       IBM, Corp.
+ *  (C) Copyright 2007-2008 TOSHIBA 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.
+ */
+#undef DEBUG
+
+#include <linux/kernel.h>
+
+#include <asm/io.h>
+#include <asm/machdep.h>
+#include <asm/pgtable.h>
+#include <asm/ppc-pci.h>
+#include <asm/io-workarounds.h>
+
+#define IOWA_MAX_BUS	8
+
+static struct iowa_bus iowa_busses[IOWA_MAX_BUS];
+static unsigned int iowa_bus_count;
+
+static struct iowa_bus *iowa_pci_find(unsigned long vaddr, unsigned long paddr)
+{
+	int i, j;
+	struct resource *res;
+	unsigned long vstart, vend;
+
+	for (i = 0; i < iowa_bus_count; i++) {
+		struct iowa_bus *bus = &iowa_busses[i];
+		struct pci_controller *phb = bus->phb;
+
+		if (vaddr) {
+			vstart = (unsigned long)phb->io_base_virt;
+			vend = vstart + phb->pci_io_size - 1;
+			if ((vaddr >= vstart) && (vaddr <= vend))
+				return bus;
+		}
+
+		if (paddr)
+			for (j = 0; j < 3; j++) {
+				res = &phb->mem_resources[j];
+				if (paddr >= res->start && paddr <= res->end)
+					return bus;
+			}
+	}
+
+	return NULL;
+}
+
+struct iowa_bus *iowa_mem_find_bus(const PCI_IO_ADDR addr)
+{
+	struct iowa_bus *bus;
+	int token;
+
+	token = PCI_GET_ADDR_TOKEN(addr);
+
+	if (token && token <= iowa_bus_count)
+		bus = &iowa_busses[token - 1];
+	else {
+		unsigned long vaddr, paddr;
+		pte_t *ptep;
+
+		vaddr = (unsigned long)PCI_FIX_ADDR(addr);
+		if (vaddr < PHB_IO_BASE || vaddr >= PHB_IO_END)
+			return NULL;
+
+		ptep = find_linux_pte(init_mm.pgd, vaddr);
+		if (ptep == NULL)
+			paddr = 0;
+		else
+			paddr = pte_pfn(*ptep) << PAGE_SHIFT;
+		bus = iowa_pci_find(vaddr, paddr);
+
+		if (bus == NULL)
+			return NULL;
+	}
+
+	return bus;
+}
+
+struct iowa_bus *iowa_pio_find_bus(unsigned long port)
+{
+	unsigned long vaddr = (unsigned long)pci_io_base + port;
+	return iowa_pci_find(vaddr, 0);
+}
+
+
+#define DEF_PCI_AC_RET(name, ret, at, al, space, aa)		\
+static ret iowa_##name at					\
+{								\
+	struct iowa_bus *bus;					\
+	bus = iowa_##space##_find_bus(aa);			\
+	if (bus && bus->ops && bus->ops->name)			\
+		return bus->ops->name al;			\
+	return __do_##name al;					\
+}
+
+#define DEF_PCI_AC_NORET(name, at, al, space, aa)		\
+static void iowa_##name at					\
+{								\
+	struct iowa_bus *bus;					\
+	bus = iowa_##space##_find_bus(aa);			\
+	if (bus && bus->ops && bus->ops->name) {		\
+		bus->ops->name al;				\
+		return;						\
+	}							\
+	__do_##name al;						\
+}
+
+#include <asm/io-defs.h>
+
+#undef DEF_PCI_AC_RET
+#undef DEF_PCI_AC_NORET
+
+static const struct ppc_pci_io __devinitconst iowa_pci_io = {
+
+#define DEF_PCI_AC_RET(name, ret, at, al, space, aa)	.name = iowa_##name,
+#define DEF_PCI_AC_NORET(name, at, al, space, aa)	.name = iowa_##name,
+
+#include <asm/io-defs.h>
+
+#undef DEF_PCI_AC_RET
+#undef DEF_PCI_AC_NORET
+
+};
+
+static void __iomem *iowa_ioremap(phys_addr_t addr, unsigned long size,
+				  unsigned long flags, void *caller)
+{
+	struct iowa_bus *bus;
+	void __iomem *res = __ioremap_caller(addr, size, flags, caller);
+	int busno;
+
+	bus = iowa_pci_find(0, (unsigned long)addr);
+	if (bus != NULL) {
+		busno = bus - iowa_busses;
+		PCI_SET_ADDR_TOKEN(res, busno + 1);
+	}
+	return res;
+}
+
+/* Enable IO workaround */
+static void __devinit io_workaround_init(void)
+{
+	static int io_workaround_inited;
+
+	if (io_workaround_inited)
+		return;
+	ppc_pci_io = iowa_pci_io;
+	ppc_md.ioremap = iowa_ioremap;
+	io_workaround_inited = 1;
+}
+
+/* Register new bus to support workaround */
+void __devinit iowa_register_bus(struct pci_controller *phb,
+			struct ppc_pci_io *ops,
+			int (*initfunc)(struct iowa_bus *, void *), void *data)
+{
+	struct iowa_bus *bus;
+	struct device_node *np = phb->dn;
+
+	io_workaround_init();
+
+	if (iowa_bus_count >= IOWA_MAX_BUS) {
+		pr_err("IOWA:Too many pci bridges, "
+		       "workarounds disabled for %s\n", np->full_name);
+		return;
+	}
+
+	bus = &iowa_busses[iowa_bus_count];
+	bus->phb = phb;
+	bus->ops = ops;
+	bus->private = data;
+
+	if (initfunc)
+		if ((*initfunc)(bus, data))
+			return;
+
+	iowa_bus_count++;
+
+	pr_debug("IOWA:[%d]Add bus, %s.\n", iowa_bus_count-1, np->full_name);
+}
+
diff -druN linux-2.6.39-libre/arch/powerpc/kernel/irq.c linux-3.0-rc7-libre/arch/powerpc/kernel/irq.c
--- linux-2.6.39-libre/arch/powerpc/kernel/irq.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/kernel/irq.c	2011-07-11 19:51:52.000000000 -0400
@@ -66,7 +66,6 @@
 #include <asm/ptrace.h>
 #include <asm/machdep.h>
 #include <asm/udbg.h>
-#include <asm/dbell.h>
 #include <asm/smp.h>
 
 #ifdef CONFIG_PPC64
@@ -160,7 +159,8 @@
 
 #if defined(CONFIG_BOOKE) && defined(CONFIG_SMP)
 	/* Check for pending doorbell interrupts and resend to ourself */
-	doorbell_check_self();
+	if (cpu_has_feature(CPU_FTR_DBELL))
+		smp_muxed_ipi_resend();
 #endif
 
 	/*
@@ -295,17 +295,20 @@
 	unsigned long saved_sp_limit;
 	struct irq_desc *desc;
 
+	desc = irq_to_desc(irq);
+	if (!desc)
+		return;
+
 	/* Switch to the irq stack to handle this */
 	curtp = current_thread_info();
 	irqtp = hardirq_ctx[smp_processor_id()];
 
 	if (curtp == irqtp) {
 		/* We're already on the irq stack, just handle it */
-		generic_handle_irq(irq);
+		desc->handle_irq(irq, desc);
 		return;
 	}
 
-	desc = irq_to_desc(irq);
 	saved_sp_limit = current->thread.ksp_limit;
 
 	irqtp->task = curtp->task;
@@ -397,24 +400,28 @@
 void exc_lvl_ctx_init(void)
 {
 	struct thread_info *tp;
-	int i, hw_cpu;
+	int i, cpu_nr;
 
 	for_each_possible_cpu(i) {
-		hw_cpu = get_hard_smp_processor_id(i);
-		memset((void *)critirq_ctx[hw_cpu], 0, THREAD_SIZE);
-		tp = critirq_ctx[hw_cpu];
-		tp->cpu = i;
+#ifdef CONFIG_PPC64
+		cpu_nr = i;
+#else
+		cpu_nr = get_hard_smp_processor_id(i);
+#endif
+		memset((void *)critirq_ctx[cpu_nr], 0, THREAD_SIZE);
+		tp = critirq_ctx[cpu_nr];
+		tp->cpu = cpu_nr;
 		tp->preempt_count = 0;
 
 #ifdef CONFIG_BOOKE
-		memset((void *)dbgirq_ctx[hw_cpu], 0, THREAD_SIZE);
-		tp = dbgirq_ctx[hw_cpu];
-		tp->cpu = i;
+		memset((void *)dbgirq_ctx[cpu_nr], 0, THREAD_SIZE);
+		tp = dbgirq_ctx[cpu_nr];
+		tp->cpu = cpu_nr;
 		tp->preempt_count = 0;
 
-		memset((void *)mcheckirq_ctx[hw_cpu], 0, THREAD_SIZE);
-		tp = mcheckirq_ctx[hw_cpu];
-		tp->cpu = i;
+		memset((void *)mcheckirq_ctx[cpu_nr], 0, THREAD_SIZE);
+		tp = mcheckirq_ctx[cpu_nr];
+		tp->cpu = cpu_nr;
 		tp->preempt_count = HARDIRQ_OFFSET;
 #endif
 	}
@@ -477,20 +484,41 @@
  * IRQ controller and virtual interrupts
  */
 
+/* The main irq map itself is an array of NR_IRQ entries containing the
+ * associate host and irq number. An entry with a host of NULL is free.
+ * An entry can be allocated if it's free, the allocator always then sets
+ * hwirq first to the host's invalid irq number and then fills ops.
+ */
+struct irq_map_entry {
+	irq_hw_number_t	hwirq;
+	struct irq_host	*host;
+};
+
 static LIST_HEAD(irq_hosts);
 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];
+static struct irq_map_entry irq_map[NR_IRQS];
 static unsigned int irq_virq_count = NR_IRQS;
 static struct irq_host *irq_default_host;
 
+irq_hw_number_t irqd_to_hwirq(struct irq_data *d)
+{
+	return irq_map[d->irq].hwirq;
+}
+EXPORT_SYMBOL_GPL(irqd_to_hwirq);
+
 irq_hw_number_t virq_to_hw(unsigned int virq)
 {
 	return irq_map[virq].hwirq;
 }
 EXPORT_SYMBOL_GPL(virq_to_hw);
 
+bool virq_is_host(unsigned int virq, struct irq_host *host)
+{
+	return irq_map[virq].host == host;
+}
+EXPORT_SYMBOL_GPL(virq_is_host);
+
 static int default_irq_host_match(struct irq_host *h, struct device_node *np)
 {
 	return h->of_node != NULL && h->of_node == np;
@@ -511,7 +539,7 @@
 	/* Allocate structure and revmap table if using linear mapping */
 	if (revmap_type == IRQ_HOST_MAP_LINEAR)
 		size += revmap_arg * sizeof(unsigned int);
-	host = zalloc_maybe_bootmem(size, GFP_KERNEL);
+	host = kzalloc(size, GFP_KERNEL);
 	if (host == NULL)
 		return NULL;
 
@@ -532,15 +560,8 @@
 	if (revmap_type == IRQ_HOST_MAP_LEGACY) {
 		if (irq_map[0].host != NULL) {
 			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
-			 * instead of the current cruft
-			 */
-			if (mem_init_done) {
-				of_node_put(host->of_node);
-				kfree(host);
-			}
+			of_node_put(host->of_node);
+			kfree(host);
 			return NULL;
 		}
 		irq_map[0].host = host;
@@ -561,14 +582,14 @@
 			irq_map[i].host = host;
 			smp_wmb();
 
-			/* Clear norequest flags */
-			irq_clear_status_flags(i, IRQ_NOREQUEST);
-
 			/* Legacy flags are left to default at this point,
 			 * one can then use irq_create_mapping() to
 			 * explicitly change them
 			 */
 			ops->map(host, i, i);
+
+			/* Clear norequest flags */
+			irq_clear_status_flags(i, IRQ_NOREQUEST);
 		}
 		break;
 	case IRQ_HOST_MAP_LINEAR:
@@ -579,6 +600,9 @@
 		smp_wmb();
 		host->revmap_data.linear.revmap = rmap;
 		break;
+	case IRQ_HOST_MAP_TREE:
+		INIT_RADIX_TREE(&host->revmap_data.tree, GFP_KERNEL);
+		break;
 	default:
 		break;
 	}
@@ -636,8 +660,6 @@
 		goto error;
 	}
 
-	irq_clear_status_flags(virq, IRQ_NOREQUEST);
-
 	/* map it */
 	smp_wmb();
 	irq_map[virq].hwirq = hwirq;
@@ -648,6 +670,8 @@
 		goto errdesc;
 	}
 
+	irq_clear_status_flags(virq, IRQ_NOREQUEST);
+
 	return 0;
 
 errdesc:
@@ -699,13 +723,9 @@
 	}
 	pr_debug("irq: -> using host @%p\n", host);
 
-	/* Check if mapping already exist, if it does, call
-	 * host->ops->map() to update the flags
-	 */
+	/* Check if mapping already exists */
 	virq = irq_find_mapping(host, hwirq);
 	if (virq != NO_IRQ) {
-		if (host->ops->remap)
-			host->ops->remap(host, virq, hwirq);
 		pr_debug("irq: -> existing mapping on virq %d\n", virq);
 		return virq;
 	}
@@ -786,14 +806,15 @@
 		return;
 
 	host = irq_map[virq].host;
-	WARN_ON (host == NULL);
-	if (host == NULL)
+	if (WARN_ON(host == NULL))
 		return;
 
 	/* Never unmap legacy interrupts */
 	if (host->revmap_type == IRQ_HOST_MAP_LEGACY)
 		return;
 
+	irq_set_status_flags(virq, IRQ_NOREQUEST);
+
 	/* remove chip and handler */
 	irq_set_chip_and_handler(virq, NULL, NULL);
 
@@ -813,13 +834,6 @@
 			host->revmap_data.linear.revmap[hwirq] = NO_IRQ;
 		break;
 	case IRQ_HOST_MAP_TREE:
-		/*
-		 * Check if radix tree allocated yet, if not then nothing to
-		 * remove.
-		 */
-		smp_rmb();
-		if (revmap_trees_allocated < 1)
-			break;
 		mutex_lock(&revmap_trees_mutex);
 		radix_tree_delete(&host->revmap_data.tree, hwirq);
 		mutex_unlock(&revmap_trees_mutex);
@@ -830,8 +844,6 @@
 	smp_mb();
 	irq_map[virq].hwirq = host->inval_irq;
 
-	irq_set_status_flags(virq, IRQ_NOREQUEST);
-
 	irq_free_descs(virq, 1);
 	/* Free it */
 	irq_free_virt(virq, 1);
@@ -877,21 +889,17 @@
 	struct irq_map_entry *ptr;
 	unsigned int virq;
 
-	WARN_ON(host->revmap_type != IRQ_HOST_MAP_TREE);
-
-	/*
-	 * Check if the radix tree exists and has bee initialized.
-	 * If not, we fallback to slow mode
-	 */
-	if (revmap_trees_allocated < 2)
+	if (WARN_ON_ONCE(host->revmap_type != IRQ_HOST_MAP_TREE))
 		return irq_find_mapping(host, hwirq);
 
-	/* Now try to resolve */
 	/*
-	 * No rcu_read_lock(ing) needed, the ptr returned can't go under us
-	 * as it's referencing an entry in the static irq_map table.
+	 * The ptr returned references the static global irq_map.
+	 * but freeing an irq can delete nodes along the path to
+	 * do the lookup via call_rcu.
 	 */
+	rcu_read_lock();
 	ptr = radix_tree_lookup(&host->revmap_data.tree, hwirq);
+	rcu_read_unlock();
 
 	/*
 	 * If found in radix tree, then fine.
@@ -909,16 +917,7 @@
 void irq_radix_revmap_insert(struct irq_host *host, unsigned int virq,
 			     irq_hw_number_t hwirq)
 {
-
-	WARN_ON(host->revmap_type != IRQ_HOST_MAP_TREE);
-
-	/*
-	 * Check if the radix tree exists yet.
-	 * If not, then the irq will be inserted into the tree when it gets
-	 * initialized.
-	 */
-	smp_rmb();
-	if (revmap_trees_allocated < 1)
+	if (WARN_ON(host->revmap_type != IRQ_HOST_MAP_TREE))
 		return;
 
 	if (virq != NO_IRQ) {
@@ -934,7 +933,8 @@
 {
 	unsigned int *revmap;
 
-	WARN_ON(host->revmap_type != IRQ_HOST_MAP_LINEAR);
+	if (WARN_ON_ONCE(host->revmap_type != IRQ_HOST_MAP_LINEAR))
+		return irq_find_mapping(host, hwirq);
 
 	/* Check revmap bounds */
 	if (unlikely(hwirq >= host->revmap_data.linear.size))
@@ -1007,14 +1007,23 @@
 	WARN_ON (virq < NUM_ISA_INTERRUPTS);
 	WARN_ON (count == 0 || (virq + count) > irq_virq_count);
 
+	if (virq < NUM_ISA_INTERRUPTS) {
+		if (virq + count < NUM_ISA_INTERRUPTS)
+			return;
+		count  =- NUM_ISA_INTERRUPTS - virq;
+		virq = NUM_ISA_INTERRUPTS;
+	}
+
+	if (count > irq_virq_count || virq > irq_virq_count - count) {
+		if (virq > irq_virq_count)
+			return;
+		count = irq_virq_count - virq;
+	}
+
 	raw_spin_lock_irqsave(&irq_big_lock, flags);
 	for (i = virq; i < (virq + count); i++) {
 		struct irq_host *host;
 
-		if (i < NUM_ISA_INTERRUPTS ||
-		    (virq + count) > irq_virq_count)
-			continue;
-
 		host = irq_map[i].host;
 		irq_map[i].hwirq = host->inval_irq;
 		smp_wmb();
@@ -1028,53 +1037,6 @@
 	return 0;
 }
 
-/* We need to create the radix trees late */
-static int irq_late_init(void)
-{
-	struct irq_host *h;
-	unsigned int i;
-
-	/*
-	 * No mutual exclusion with respect to accessors of the tree is needed
-	 * here as the synchronization is done via the state variable
-	 * revmap_trees_allocated.
-	 */
-	list_for_each_entry(h, &irq_hosts, link) {
-		if (h->revmap_type == IRQ_HOST_MAP_TREE)
-			INIT_RADIX_TREE(&h->revmap_data.tree, GFP_KERNEL);
-	}
-
-	/*
-	 * Make sure the radix trees inits are visible before setting
-	 * the flag
-	 */
-	smp_wmb();
-	revmap_trees_allocated = 1;
-
-	/*
-	 * Insert the reverse mapping for those interrupts already present
-	 * in irq_map[].
-	 */
-	mutex_lock(&revmap_trees_mutex);
-	for (i = 0; i < irq_virq_count; i++) {
-		if (irq_map[i].host &&
-		    (irq_map[i].host->revmap_type == IRQ_HOST_MAP_TREE))
-			radix_tree_insert(&irq_map[i].host->revmap_data.tree,
-					  irq_map[i].hwirq, &irq_map[i]);
-	}
-	mutex_unlock(&revmap_trees_mutex);
-
-	/*
-	 * Make sure the radix trees insertions are visible before setting
-	 * the flag
-	 */
-	smp_wmb();
-	revmap_trees_allocated = 2;
-
-	return 0;
-}
-arch_initcall(irq_late_init);
-
 #ifdef CONFIG_VIRQ_DEBUG
 static int virq_debug_show(struct seq_file *m, void *private)
 {
@@ -1082,10 +1044,11 @@
 	struct irq_desc *desc;
 	const char *p;
 	static const char none[] = "none";
+	void *data;
 	int i;
 
-	seq_printf(m, "%-5s  %-7s  %-15s  %s\n", "virq", "hwirq",
-		      "chip name", "host name");
+	seq_printf(m, "%-5s  %-7s  %-15s  %-18s  %s\n", "virq", "hwirq",
+		      "chip name", "chip data", "host name");
 
 	for (i = 1; i < nr_irqs; i++) {
 		desc = irq_to_desc(i);
@@ -1098,7 +1061,7 @@
 			struct irq_chip *chip;
 
 			seq_printf(m, "%5d  ", i);
-			seq_printf(m, "0x%05lx  ", virq_to_hw(i));
+			seq_printf(m, "0x%05lx  ", irq_map[i].hwirq);
 
 			chip = irq_desc_get_chip(desc);
 			if (chip && chip->name)
@@ -1107,6 +1070,9 @@
 				p = none;
 			seq_printf(m, "%-15s  ", p);
 
+			data = irq_desc_get_chip_data(desc);
+			seq_printf(m, "0x%16p  ", data);
+
 			if (irq_map[i].host && irq_map[i].host->of_node)
 				p = irq_map[i].host->of_node->full_name;
 			else
diff -druN linux-2.6.39-libre/arch/powerpc/kernel/kgdb.c linux-3.0-rc7-libre/arch/powerpc/kernel/kgdb.c
--- linux-2.6.39-libre/arch/powerpc/kernel/kgdb.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/kernel/kgdb.c	2011-07-11 19:51:52.000000000 -0400
@@ -109,7 +109,7 @@
 #ifdef CONFIG_SMP
 void kgdb_roundup_cpus(unsigned long flags)
 {
-	smp_send_debugger_break(MSG_ALL_BUT_SELF);
+	smp_send_debugger_break();
 }
 #endif
 
@@ -142,7 +142,7 @@
 		return 0;
 
 	/*
-	 * On Book E and perhaps other processsors, singlestep is handled on
+	 * On Book E and perhaps other processors, singlestep is handled on
 	 * the critical exception stack.  This causes current_thread_info()
 	 * to fail, since it it locates the thread_info by masking off
 	 * the low bits of the current stack pointer.  We work around
diff -druN linux-2.6.39-libre/arch/powerpc/kernel/lparcfg.c linux-3.0-rc7-libre/arch/powerpc/kernel/lparcfg.c
--- linux-2.6.39-libre/arch/powerpc/kernel/lparcfg.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/kernel/lparcfg.c	2011-07-11 19:51:52.000000000 -0400
@@ -132,34 +132,6 @@
 /*
  * Methods used to fetch LPAR data when running on a pSeries platform.
  */
-/**
- * h_get_mpp
- * H_GET_MPP hcall returns info in 7 parms
- */
-int h_get_mpp(struct hvcall_mpp_data *mpp_data)
-{
-	int rc;
-	unsigned long retbuf[PLPAR_HCALL9_BUFSIZE];
-
-	rc = plpar_hcall9(H_GET_MPP, retbuf);
-
-	mpp_data->entitled_mem = retbuf[0];
-	mpp_data->mapped_mem = retbuf[1];
-
-	mpp_data->group_num = (retbuf[2] >> 2 * 8) & 0xffff;
-	mpp_data->pool_num = retbuf[2] & 0xffff;
-
-	mpp_data->mem_weight = (retbuf[3] >> 7 * 8) & 0xff;
-	mpp_data->unallocated_mem_weight = (retbuf[3] >> 6 * 8) & 0xff;
-	mpp_data->unallocated_entitlement = retbuf[3] & 0xffffffffffff;
-
-	mpp_data->pool_size = retbuf[4];
-	mpp_data->loan_request = retbuf[5];
-	mpp_data->backing_mem = retbuf[6];
-
-	return rc;
-}
-EXPORT_SYMBOL(h_get_mpp);
 
 struct hvcall_ppp_data {
 	u64	entitlement;
@@ -345,6 +317,30 @@
 	seq_printf(m, "backing_memory=%ld bytes\n", mpp_data.backing_mem);
 }
 
+/**
+ * parse_mpp_x_data
+ * Parse out data returned from h_get_mpp_x
+ */
+static void parse_mpp_x_data(struct seq_file *m)
+{
+	struct hvcall_mpp_x_data mpp_x_data;
+
+	if (!firmware_has_feature(FW_FEATURE_XCMO))
+		return;
+	if (h_get_mpp_x(&mpp_x_data))
+		return;
+
+	seq_printf(m, "coalesced_bytes=%ld\n", mpp_x_data.coalesced_bytes);
+
+	if (mpp_x_data.pool_coalesced_bytes)
+		seq_printf(m, "pool_coalesced_bytes=%ld\n",
+			   mpp_x_data.pool_coalesced_bytes);
+	if (mpp_x_data.pool_purr_cycles)
+		seq_printf(m, "coalesce_pool_purr=%ld\n", mpp_x_data.pool_purr_cycles);
+	if (mpp_x_data.pool_spurr_cycles)
+		seq_printf(m, "coalesce_pool_spurr=%ld\n", mpp_x_data.pool_spurr_cycles);
+}
+
 #define SPLPAR_CHARACTERISTICS_TOKEN 20
 #define SPLPAR_MAXLENGTH 1026*(sizeof(char))
 
@@ -520,6 +516,7 @@
 		parse_system_parameter_string(m);
 		parse_ppp_data(m);
 		parse_mpp_data(m);
+		parse_mpp_x_data(m);
 		pseries_cmo_data(m);
 		splpar_dispatch_data(m);
 
diff -druN linux-2.6.39-libre/arch/powerpc/kernel/Makefile linux-3.0-rc7-libre/arch/powerpc/kernel/Makefile
--- linux-2.6.39-libre/arch/powerpc/kernel/Makefile	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/kernel/Makefile	2011-07-11 19:51:52.000000000 -0400
@@ -38,11 +38,14 @@
 				   paca.o nvram_64.o firmware.o
 obj-$(CONFIG_HAVE_HW_BREAKPOINT)	+= hw_breakpoint.o
 obj-$(CONFIG_PPC_BOOK3S_64)	+= cpu_setup_ppc970.o cpu_setup_pa6t.o
+obj-$(CONFIG_PPC_BOOK3S_64)	+= cpu_setup_power7.o
 obj64-$(CONFIG_RELOCATABLE)	+= reloc_64.o
 obj-$(CONFIG_PPC_BOOK3E_64)	+= exceptions-64e.o idle_book3e.o
+obj-$(CONFIG_PPC_A2)		+= cpu_setup_a2.o
 obj-$(CONFIG_PPC64)		+= vdso64/
 obj-$(CONFIG_ALTIVEC)		+= vecemu.o
 obj-$(CONFIG_PPC_970_NAP)	+= idle_power4.o
+obj-$(CONFIG_PPC_P7_NAP)	+= idle_power7.o
 obj-$(CONFIG_PPC_OF)		+= of_platform.o prom_parse.o
 obj-$(CONFIG_PPC_CLOCK)		+= clock.o
 procfs-y			:= proc_powerpc.o
@@ -75,7 +78,6 @@
 obj-$(CONFIG_PPC_BOOK3E_64)	+= dbell.o
 
 extra-y				:= head_$(CONFIG_WORD_SIZE).o
-extra-$(CONFIG_PPC_BOOK3E_32)	:= head_new_booke.o
 extra-$(CONFIG_40x)		:= head_40x.o
 extra-$(CONFIG_44x)		:= head_44x.o
 extra-$(CONFIG_FSL_BOOKE)	:= head_fsl_booke.o
@@ -103,8 +105,11 @@
 obj-$(CONFIG_AUDIT)		+= audit.o
 obj64-$(CONFIG_AUDIT)		+= compat_audit.o
 
+obj-$(CONFIG_PPC_IO_WORKAROUNDS)	+= io-workarounds.o
+
 obj-$(CONFIG_DYNAMIC_FTRACE)	+= ftrace.o
 obj-$(CONFIG_FUNCTION_GRAPH_TRACER)	+= ftrace.o
+obj-$(CONFIG_FTRACE_SYSCALLS)	+= ftrace.o
 obj-$(CONFIG_PERF_EVENTS)	+= perf_callchain.o
 
 obj-$(CONFIG_PPC_PERF_CTRS)	+= perf_event.o
diff -druN linux-2.6.39-libre/arch/powerpc/kernel/misc_32.S linux-3.0-rc7-libre/arch/powerpc/kernel/misc_32.S
--- linux-2.6.39-libre/arch/powerpc/kernel/misc_32.S	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/kernel/misc_32.S	2011-07-11 19:51:52.000000000 -0400
@@ -694,6 +694,17 @@
 	addi	r1,r1,16
 	blr
 
+#ifdef CONFIG_SMP
+_GLOBAL(start_secondary_resume)
+	/* Reset stack */
+	rlwinm	r1,r1,0,0,(31-THREAD_SHIFT)	/* current_thread_info() */
+	addi	r1,r1,THREAD_SIZE-STACK_FRAME_OVERHEAD
+	li	r3,0
+	stw	r3,0(r1)		/* Zero the stack frame pointer	*/
+	bl	start_secondary
+	b	.
+#endif /* CONFIG_SMP */
+	
 /*
  * This routine is just here to keep GCC happy - sigh...
  */
diff -druN linux-2.6.39-libre/arch/powerpc/kernel/misc_64.S linux-3.0-rc7-libre/arch/powerpc/kernel/misc_64.S
--- linux-2.6.39-libre/arch/powerpc/kernel/misc_64.S	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/kernel/misc_64.S	2011-07-11 19:51:52.000000000 -0400
@@ -462,7 +462,8 @@
  * wait for the flag to change, indicating this kernel is going away but
  * the slave code for the next one is at addresses 0 to 100.
  *
- * This is used by all slaves.
+ * This is used by all slaves, even those that did not find a matching
+ * paca in the secondary startup code.
  *
  * Physical (hardware) cpu id should be in r3.
  */
@@ -471,10 +472,6 @@
 1:	mflr	r5
 	addi	r5,r5,kexec_flag-1b
 
-	li	r4,KEXEC_STATE_REAL_MODE
-	stb	r4,PACAKEXECSTATE(r13)
-	SYNC
-
 99:	HMT_LOW
 #ifdef CONFIG_KEXEC		/* use no memory without kexec */
 	lwz	r4,0(r5)
@@ -499,11 +496,17 @@
  *
  * get phys id from paca
  * switch to real mode
+ * mark the paca as no longer used
  * join other cpus in kexec_wait(phys_id)
  */
 _GLOBAL(kexec_smp_wait)
 	lhz	r3,PACAHWCPUID(r13)
 	bl	real_mode
+
+	li	r4,KEXEC_STATE_REAL_MODE
+	stb	r4,PACAKEXECSTATE(r13)
+	SYNC
+
 	b	.kexec_wait
 
 /*
diff -druN linux-2.6.39-libre/arch/powerpc/kernel/paca.c linux-3.0-rc7-libre/arch/powerpc/kernel/paca.c
--- linux-2.6.39-libre/arch/powerpc/kernel/paca.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/kernel/paca.c	2011-07-11 19:51:52.000000000 -0400
@@ -7,7 +7,7 @@
  *      2 of the License, or (at your option) any later version.
  */
 
-#include <linux/threads.h>
+#include <linux/smp.h>
 #include <linux/module.h>
 #include <linux/memblock.h>
 
@@ -156,18 +156,29 @@
 /* Put the paca pointer into r13 and SPRG_PACA */
 void setup_paca(struct paca_struct *new_paca)
 {
+	/* Setup r13 */
 	local_paca = new_paca;
-	mtspr(SPRN_SPRG_PACA, local_paca);
+
 #ifdef CONFIG_PPC_BOOK3E
+	/* On Book3E, initialize the TLB miss exception frames */
 	mtspr(SPRN_SPRG_TLB_EXFRAME, local_paca->extlb);
+#else
+	/* In HV mode, we setup both HPACA and PACA to avoid problems
+	 * if we do a GET_PACA() before the feature fixups have been
+	 * applied
+	 */
+	if (cpu_has_feature(CPU_FTR_HVMODE_206))
+		mtspr(SPRN_SPRG_HPACA, local_paca);
 #endif
+	mtspr(SPRN_SPRG_PACA, local_paca);
+
 }
 
 static int __initdata paca_size;
 
 void __init allocate_pacas(void)
 {
-	int nr_cpus, cpu, limit;
+	int cpu, limit;
 
 	/*
 	 * We can't take SLB misses on the paca, and we want to access them
@@ -179,23 +190,18 @@
 	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_size = PAGE_ALIGN(sizeof(struct paca_struct) * nr_cpu_ids);
 
 	paca = __va(memblock_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);
+		paca_size, nr_cpu_ids, paca);
 
-	allocate_lppacas(nr_cpus, limit);
+	allocate_lppacas(nr_cpu_ids, limit);
 
 	/* Can't use for_each_*_cpu, as they aren't functional yet */
-	for (cpu = 0; cpu < nr_cpus; cpu++)
+	for (cpu = 0; cpu < nr_cpu_ids; cpu++)
 		initialise_paca(&paca[cpu], cpu);
 }
 
diff -druN linux-2.6.39-libre/arch/powerpc/kernel/pci_dn.c linux-3.0-rc7-libre/arch/powerpc/kernel/pci_dn.c
--- linux-2.6.39-libre/arch/powerpc/kernel/pci_dn.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/kernel/pci_dn.c	2011-07-11 19:51:52.000000000 -0400
@@ -43,10 +43,9 @@
 	const u32 *regs;
 	struct pci_dn *pdn;
 
-	pdn = alloc_maybe_bootmem(sizeof(*pdn), GFP_KERNEL);
+	pdn = zalloc_maybe_bootmem(sizeof(*pdn), GFP_KERNEL);
 	if (pdn == NULL)
 		return NULL;
-	memset(pdn, 0, sizeof(*pdn));
 	dn->data = pdn;
 	pdn->node = dn;
 	pdn->phb = phb;
diff -druN linux-2.6.39-libre/arch/powerpc/kernel/ppc_ksyms.c linux-3.0-rc7-libre/arch/powerpc/kernel/ppc_ksyms.c
--- linux-2.6.39-libre/arch/powerpc/kernel/ppc_ksyms.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/kernel/ppc_ksyms.c	2011-07-11 19:51:52.000000000 -0400
@@ -54,7 +54,6 @@
 extern int sys_sigreturn(struct pt_regs *regs);
 
 EXPORT_SYMBOL(clear_pages);
-EXPORT_SYMBOL(copy_page);
 EXPORT_SYMBOL(ISA_DMA_THRESHOLD);
 EXPORT_SYMBOL(DMA_MODE_READ);
 EXPORT_SYMBOL(DMA_MODE_WRITE);
@@ -88,9 +87,7 @@
 EXPORT_SYMBOL(__clear_user);
 EXPORT_SYMBOL(__strncpy_from_user);
 EXPORT_SYMBOL(__strnlen_user);
-#ifdef CONFIG_PPC64
-EXPORT_SYMBOL(copy_4K_page);
-#endif
+EXPORT_SYMBOL(copy_page);
 
 #if defined(CONFIG_PCI) && defined(CONFIG_PPC32)
 EXPORT_SYMBOL(isa_io_base);
diff -druN linux-2.6.39-libre/arch/powerpc/kernel/process.c linux-3.0-rc7-libre/arch/powerpc/kernel/process.c
--- linux-2.6.39-libre/arch/powerpc/kernel/process.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/kernel/process.c	2011-07-11 19:51:52.000000000 -0400
@@ -395,6 +395,9 @@
 	struct thread_struct *new_thread, *old_thread;
 	unsigned long flags;
 	struct task_struct *last;
+#ifdef CONFIG_PPC_BOOK3S_64
+	struct ppc64_tlb_batch *batch;
+#endif
 
 #ifdef CONFIG_SMP
 	/* avoid complexity of lazy save/restore of fpu
@@ -513,7 +516,17 @@
 		old_thread->accum_tb += (current_tb - start_tb);
 		new_thread->start_tb = current_tb;
 	}
-#endif
+#endif /* CONFIG_PPC64 */
+
+#ifdef CONFIG_PPC_BOOK3S_64
+	batch = &__get_cpu_var(ppc64_tlb_batch);
+	if (batch->active) {
+		current_thread_info()->local_flags |= _TLF_LAZY_MMU;
+		if (batch->index)
+			__flush_tlb_pending(batch);
+		batch->active = 0;
+	}
+#endif /* CONFIG_PPC_BOOK3S_64 */
 
 	local_irq_save(flags);
 
@@ -528,6 +541,14 @@
 	hard_irq_disable();
 	last = _switch(old_thread, new_thread);
 
+#ifdef CONFIG_PPC_BOOK3S_64
+	if (current_thread_info()->local_flags & _TLF_LAZY_MMU) {
+		current_thread_info()->local_flags &= ~_TLF_LAZY_MMU;
+		batch = &__get_cpu_var(ppc64_tlb_batch);
+		batch->active = 1;
+	}
+#endif /* CONFIG_PPC_BOOK3S_64 */
+
 	local_irq_restore(flags);
 
 	return last;
@@ -702,6 +723,8 @@
 /*
  * Copy a thread..
  */
+extern unsigned long dscr_default; /* defined in arch/powerpc/kernel/sysfs.c */
+
 int copy_thread(unsigned long clone_flags, unsigned long usp,
 		unsigned long unused, struct task_struct *p,
 		struct pt_regs *regs)
@@ -755,11 +778,11 @@
 				_ALIGN_UP(sizeof(struct thread_info), 16);
 
 #ifdef CONFIG_PPC_STD_MMU_64
-	if (cpu_has_feature(CPU_FTR_SLB)) {
+	if (mmu_has_feature(MMU_FTR_SLB)) {
 		unsigned long sp_vsid;
 		unsigned long llp = mmu_psize_defs[mmu_linear_psize].sllp;
 
-		if (cpu_has_feature(CPU_FTR_1T_SEGMENT))
+		if (mmu_has_feature(MMU_FTR_1T_SEGMENT))
 			sp_vsid = get_kernel_vsid(sp, MMU_SEGSIZE_1T)
 				<< SLB_VSID_SHIFT_1T;
 		else
@@ -769,6 +792,20 @@
 		p->thread.ksp_vsid = sp_vsid;
 	}
 #endif /* CONFIG_PPC_STD_MMU_64 */
+#ifdef CONFIG_PPC64 
+	if (cpu_has_feature(CPU_FTR_DSCR)) {
+		if (current->thread.dscr_inherit) {
+			p->thread.dscr_inherit = 1;
+			p->thread.dscr = current->thread.dscr;
+		} else if (0 != dscr_default) {
+			p->thread.dscr_inherit = 1;
+			p->thread.dscr = dscr_default;
+		} else {
+			p->thread.dscr_inherit = 0;
+			p->thread.dscr = 0;
+		}
+	}
+#endif
 
 	/*
 	 * The PPC64 ABI makes use of a TOC to contain function 
diff -druN linux-2.6.39-libre/arch/powerpc/kernel/prom.c linux-3.0-rc7-libre/arch/powerpc/kernel/prom.c
--- linux-2.6.39-libre/arch/powerpc/kernel/prom.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/kernel/prom.c	2011-07-11 19:51:52.000000000 -0400
@@ -68,6 +68,7 @@
 unsigned long tce_alloc_start, tce_alloc_end;
 u64 ppc64_rma_size;
 #endif
+static phys_addr_t first_memblock_size;
 
 static int __init early_parse_mem(char *p)
 {
@@ -81,11 +82,29 @@
 }
 early_param("mem", early_parse_mem);
 
+/*
+ * overlaps_initrd - check for overlap with page aligned extension of
+ * initrd.
+ */
+static inline int overlaps_initrd(unsigned long start, unsigned long size)
+{
+#ifdef CONFIG_BLK_DEV_INITRD
+	if (!initrd_start)
+		return 0;
+
+	return	(start + size) > _ALIGN_DOWN(initrd_start, PAGE_SIZE) &&
+			start <= _ALIGN_UP(initrd_end, PAGE_SIZE);
+#else
+	return 0;
+#endif
+}
+
 /**
  * move_device_tree - move tree to an unused area, if needed.
  *
  * The device tree may be allocated beyond our memory limit, or inside the
- * crash kernel region for kdump. If so, move it out of the way.
+ * crash kernel region for kdump, or within the page aligned range of initrd.
+ * If so, move it out of the way.
  */
 static void __init move_device_tree(void)
 {
@@ -98,7 +117,8 @@
 	size = be32_to_cpu(initial_boot_params->totalsize);
 
 	if ((memory_limit && (start + size) > PHYSICAL_START + memory_limit) ||
-			overlaps_crashkernel(start, size)) {
+			overlaps_crashkernel(start, size) ||
+			overlaps_initrd(start, size)) {
 		p = __va(memblock_alloc(size, PAGE_SIZE));
 		memcpy(p, initial_boot_params, size);
 		initial_boot_params = (struct boot_param_header *)p;
@@ -123,18 +143,19 @@
  */
 static struct ibm_pa_feature {
 	unsigned long	cpu_features;	/* CPU_FTR_xxx bit */
+	unsigned long	mmu_features;	/* MMU_FTR_xxx bit */
 	unsigned int	cpu_user_ftrs;	/* PPC_FEATURE_xxx bit */
 	unsigned char	pabyte;		/* byte number in ibm,pa-features */
 	unsigned char	pabit;		/* bit number (big-endian) */
 	unsigned char	invert;		/* if 1, pa bit set => clear feature */
 } ibm_pa_features[] __initdata = {
-	{0, PPC_FEATURE_HAS_MMU,	0, 0, 0},
-	{0, PPC_FEATURE_HAS_FPU,	0, 1, 0},
-	{CPU_FTR_SLB, 0,		0, 2, 0},
-	{CPU_FTR_CTRL, 0,		0, 3, 0},
-	{CPU_FTR_NOEXECUTE, 0,		0, 6, 0},
-	{CPU_FTR_NODSISRALIGN, 0,	1, 1, 1},
-	{CPU_FTR_CI_LARGE_PAGE, 0,	1, 2, 0},
+	{0, 0, PPC_FEATURE_HAS_MMU,	0, 0, 0},
+	{0, 0, PPC_FEATURE_HAS_FPU,	0, 1, 0},
+	{0, MMU_FTR_SLB, 0,		0, 2, 0},
+	{CPU_FTR_CTRL, 0, 0,		0, 3, 0},
+	{CPU_FTR_NOEXECUTE, 0, 0,	0, 6, 0},
+	{CPU_FTR_NODSISRALIGN, 0, 0,	1, 1, 1},
+	{0, MMU_FTR_CI_LARGE_PAGE, 0,	1, 2, 0},
 	{CPU_FTR_REAL_LE, PPC_FEATURE_TRUE_LE, 5, 0, 0},
 };
 
@@ -166,9 +187,11 @@
 		if (bit ^ fp->invert) {
 			cur_cpu_spec->cpu_features |= fp->cpu_features;
 			cur_cpu_spec->cpu_user_features |= fp->cpu_user_ftrs;
+			cur_cpu_spec->mmu_features |= fp->mmu_features;
 		} else {
 			cur_cpu_spec->cpu_features &= ~fp->cpu_features;
 			cur_cpu_spec->cpu_user_features &= ~fp->cpu_user_ftrs;
+			cur_cpu_spec->mmu_features &= ~fp->mmu_features;
 		}
 	}
 }
@@ -268,13 +291,13 @@
 					  const char *uname, int depth,
 					  void *data)
 {
-	static int logical_cpuid = 0;
 	char *type = of_get_flat_dt_prop(node, "device_type", NULL);
 	const u32 *prop;
 	const u32 *intserv;
 	int i, nthreads;
 	unsigned long len;
-	int found = 0;
+	int found = -1;
+	int found_thread = 0;
 
 	/* We are scanning "cpu" nodes only */
 	if (type == NULL || strcmp(type, "cpu") != 0)
@@ -298,11 +321,10 @@
 		 * 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;
+		if (initial_boot_params->version >= 2) {
+			if (intserv[i] == initial_boot_params->boot_cpuid_phys) {
+				found = boot_cpu_count;
+				found_thread = i;
 			}
 		} else {
 			/*
@@ -311,23 +333,20 @@
 			 * off secondary threads.
 			 */
 			if (of_get_flat_dt_prop(node,
-					"linux,boot-cpu", NULL) != NULL) {
-				found = 1;
-				break;
-			}
+					"linux,boot-cpu", NULL) != NULL)
+				found = boot_cpu_count;
 		}
-
 #ifdef CONFIG_SMP
 		/* logical cpu id is always 0 on UP kernels */
-		logical_cpuid++;
+		boot_cpu_count++;
 #endif
 	}
 
-	if (found) {
-		DBG("boot cpu: logical %d physical %d\n", logical_cpuid,
-			intserv[i]);
-		boot_cpuid = logical_cpuid;
-		set_hard_smp_processor_id(boot_cpuid, intserv[i]);
+	if (found >= 0) {
+		DBG("boot cpu: logical %d physical %d\n", found,
+			intserv[found_thread]);
+		boot_cpuid = found;
+		set_hard_smp_processor_id(found, intserv[found_thread]);
 
 		/*
 		 * PAPR defines "logical" PVR values for cpus that
@@ -509,11 +528,14 @@
 			size = 0x80000000ul - base;
 	}
 #endif
-
-	/* First MEMBLOCK added, do some special initializations */
-	if (memstart_addr == ~(phys_addr_t)0)
-		setup_initial_memory_limit(base, size);
-	memstart_addr = min((u64)memstart_addr, base);
+	/* Keep track of the beginning of memory -and- the size of
+	 * the very first block in the device-tree as it represents
+	 * the RMA on ppc64 server
+	 */
+	if (base < memstart_addr) {
+		memstart_addr = base;
+		first_memblock_size = size;
+	}
 
 	/* Add the chunk to the MEMBLOCK list */
 	memblock_add(base, size);
@@ -552,7 +574,9 @@
 #ifdef CONFIG_BLK_DEV_INITRD
 	/* then reserve the initrd, if any */
 	if (initrd_start && (initrd_end > initrd_start))
-		memblock_reserve(__pa(initrd_start), initrd_end - initrd_start);
+		memblock_reserve(_ALIGN_DOWN(__pa(initrd_start), PAGE_SIZE),
+			_ALIGN_UP(initrd_end, PAGE_SIZE) -
+			_ALIGN_DOWN(initrd_start, PAGE_SIZE));
 #endif /* CONFIG_BLK_DEV_INITRD */
 
 #ifdef CONFIG_PPC32
@@ -691,13 +715,14 @@
 	 * device-tree, including the platform type, initrd location and
 	 * size, TCE reserve, and more ...
 	 */
-	of_scan_flat_dt(early_init_dt_scan_chosen_ppc, NULL);
+	of_scan_flat_dt(early_init_dt_scan_chosen_ppc, cmd_line);
 
 	/* Scan memory nodes and rebuild MEMBLOCKs */
 	memblock_init();
 
 	of_scan_flat_dt(early_init_dt_scan_root, NULL);
 	of_scan_flat_dt(early_init_dt_scan_memory_ppc, NULL);
+	setup_initial_memory_limit(memstart_addr, first_memblock_size);
 
 	/* Save command line for /proc/cmdline and then parse parameters */
 	strlcpy(boot_command_line, cmd_line, COMMAND_LINE_SIZE);
diff -druN linux-2.6.39-libre/arch/powerpc/kernel/prom_init.c linux-3.0-rc7-libre/arch/powerpc/kernel/prom_init.c
--- linux-2.6.39-libre/arch/powerpc/kernel/prom_init.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/kernel/prom_init.c	2011-07-11 19:51:52.000000000 -0400
@@ -335,6 +335,7 @@
 	const char *p, *q, *s;
 	va_list args;
 	unsigned long v;
+	long vs;
 	struct prom_t *_prom = &RELOC(prom);
 
 	va_start(args, format);
@@ -368,12 +369,35 @@
 			v = va_arg(args, unsigned long);
 			prom_print_hex(v);
 			break;
+		case 'd':
+			++q;
+			vs = va_arg(args, int);
+			if (vs < 0) {
+				prom_print(RELOC("-"));
+				vs = -vs;
+			}
+			prom_print_dec(vs);
+			break;
 		case 'l':
 			++q;
-			if (*q == 'u') { /* '%lu' */
+			if (*q == 0)
+				break;
+			else if (*q == 'x') {
+				++q;
+				v = va_arg(args, unsigned long);
+				prom_print_hex(v);
+			} else if (*q == 'u') { /* '%lu' */
 				++q;
 				v = va_arg(args, unsigned long);
 				prom_print_dec(v);
+			} else if (*q == 'd') { /* %ld */
+				++q;
+				vs = va_arg(args, long);
+				if (vs < 0) {
+					prom_print(RELOC("-"));
+					vs = -vs;
+				}
+				prom_print_dec(vs);
 			}
 			break;
 		}
@@ -676,8 +700,10 @@
 #endif /* CONFIG_PCI_MSI */
 #ifdef CONFIG_PPC_SMLPAR
 #define OV5_CMO			0x80	/* Cooperative Memory Overcommitment */
+#define OV5_XCMO			0x40	/* Page Coalescing */
 #else
 #define OV5_CMO			0x00
+#define OV5_XCMO			0x00
 #endif
 #define OV5_TYPE1_AFFINITY	0x80	/* Type 1 NUMA affinity */
 
@@ -732,7 +758,7 @@
 	OV5_LPAR | OV5_SPLPAR | OV5_LARGE_PAGES | OV5_DRCONF_MEMORY |
 	OV5_DONATE_DEDICATE_CPU | OV5_MSI,
 	0,
-	OV5_CMO,
+	OV5_CMO | OV5_XCMO,
 	OV5_TYPE1_AFFINITY,
 	0,
 	0,
diff -druN linux-2.6.39-libre/arch/powerpc/kernel/ptrace.c linux-3.0-rc7-libre/arch/powerpc/kernel/ptrace.c
--- linux-2.6.39-libre/arch/powerpc/kernel/ptrace.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/kernel/ptrace.c	2011-07-11 19:51:52.000000000 -0400
@@ -29,6 +29,7 @@
 #include <linux/signal.h>
 #include <linux/seccomp.h>
 #include <linux/audit.h>
+#include <trace/syscall.h>
 #ifdef CONFIG_PPC32
 #include <linux/module.h>
 #endif
@@ -40,6 +41,9 @@
 #include <asm/pgtable.h>
 #include <asm/system.h>
 
+#define CREATE_TRACE_POINTS
+#include <trace/events/syscalls.h>
+
 /*
  * The parameter save area on the stack is used to store arguments being passed
  * to callee function and is located at fixed offset from stack pointer.
@@ -1710,6 +1714,9 @@
 		 */
 		ret = -1L;
 
+	if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT)))
+		trace_sys_enter(regs, regs->gpr[0]);
+
 	if (unlikely(current->audit_context)) {
 #ifdef CONFIG_PPC64
 		if (!is_32bit_task())
@@ -1738,6 +1745,9 @@
 		audit_syscall_exit((regs->ccr&0x10000000)?AUDITSC_FAILURE:AUDITSC_SUCCESS,
 				   regs->result);
 
+	if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT)))
+		trace_sys_exit(regs, regs->result);
+
 	step = test_thread_flag(TIF_SINGLESTEP);
 	if (step || test_thread_flag(TIF_SYSCALL_TRACE))
 		tracehook_report_syscall_exit(regs, step);
diff -druN linux-2.6.39-libre/arch/powerpc/kernel/rtas.c linux-3.0-rc7-libre/arch/powerpc/kernel/rtas.c
--- linux-2.6.39-libre/arch/powerpc/kernel/rtas.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/kernel/rtas.c	2011-07-11 19:51:52.000000000 -0400
@@ -42,6 +42,7 @@
 #include <asm/time.h>
 #include <asm/mmu.h>
 #include <asm/topology.h>
+#include <asm/pSeries_reconfig.h>
 
 struct rtas_t rtas = {
 	.lock = __ARCH_SPIN_LOCK_UNLOCKED
@@ -494,7 +495,7 @@
 
 	might_sleep();
 	ms = rtas_busy_delay_time(status);
-	if (ms)
+	if (ms && need_resched())
 		msleep(ms);
 
 	return ms;
@@ -731,6 +732,7 @@
 
 	atomic_set(&data->error, rc);
 	start_topology_update();
+	pSeries_coalesce_init();
 
 	if (wake_when_done) {
 		atomic_set(&data->done, 1);
diff -druN linux-2.6.39-libre/arch/powerpc/kernel/rtas-rtc.c linux-3.0-rc7-libre/arch/powerpc/kernel/rtas-rtc.c
--- linux-2.6.39-libre/arch/powerpc/kernel/rtas-rtc.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/kernel/rtas-rtc.c	2011-07-11 19:51:52.000000000 -0400
@@ -4,6 +4,7 @@
 #include <linux/init.h>
 #include <linux/rtc.h>
 #include <linux/delay.h>
+#include <linux/ratelimit.h>
 #include <asm/prom.h>
 #include <asm/rtas.h>
 #include <asm/time.h>
@@ -29,9 +30,10 @@
 		}
 	} while (wait_time && (get_tb() < max_wait_tb));
 
-	if (error != 0 && printk_ratelimit()) {
-		printk(KERN_WARNING "error: reading the clock failed (%d)\n",
-			error);
+	if (error != 0) {
+		printk_ratelimited(KERN_WARNING
+				   "error: reading the clock failed (%d)\n",
+				   error);
 		return 0;
 	}
 
@@ -55,19 +57,21 @@
 
 		wait_time = rtas_busy_delay_time(error);
 		if (wait_time) {
-			if (in_interrupt() && printk_ratelimit()) {
+			if (in_interrupt()) {
 				memset(rtc_tm, 0, sizeof(struct rtc_time));
-				printk(KERN_WARNING "error: reading clock"
-				       " would delay interrupt\n");
+				printk_ratelimited(KERN_WARNING
+						   "error: reading clock "
+						   "would delay interrupt\n");
 				return;	/* delay not allowed */
 			}
 			msleep(wait_time);
 		}
 	} while (wait_time && (get_tb() < max_wait_tb));
 
-        if (error != 0 && printk_ratelimit()) {
-                printk(KERN_WARNING "error: reading the clock failed (%d)\n",
-		       error);
+	if (error != 0) {
+		printk_ratelimited(KERN_WARNING
+				   "error: reading the clock failed (%d)\n",
+				   error);
 		return;
         }
 
@@ -99,9 +103,10 @@
 		}
 	} while (wait_time && (get_tb() < max_wait_tb));
 
-        if (error != 0 && printk_ratelimit())
-                printk(KERN_WARNING "error: setting the clock failed (%d)\n",
-		       error);
+	if (error != 0)
+		printk_ratelimited(KERN_WARNING
+				   "error: setting the clock failed (%d)\n",
+				   error);
 
         return 0;
 }
diff -druN linux-2.6.39-libre/arch/powerpc/kernel/setup_32.c linux-3.0-rc7-libre/arch/powerpc/kernel/setup_32.c
--- linux-2.6.39-libre/arch/powerpc/kernel/setup_32.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/kernel/setup_32.c	2011-07-11 19:51:52.000000000 -0400
@@ -48,6 +48,7 @@
 
 int boot_cpuid = -1;
 EXPORT_SYMBOL_GPL(boot_cpuid);
+int __initdata boot_cpu_count;
 int boot_cpuid_phys;
 
 int smp_hw_index[NR_CPUS];
diff -druN linux-2.6.39-libre/arch/powerpc/kernel/setup_64.c linux-3.0-rc7-libre/arch/powerpc/kernel/setup_64.c
--- linux-2.6.39-libre/arch/powerpc/kernel/setup_64.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/kernel/setup_64.c	2011-07-11 19:51:52.000000000 -0400
@@ -62,6 +62,7 @@
 #include <asm/udbg.h>
 #include <asm/kexec.h>
 #include <asm/mmu_context.h>
+#include <asm/code-patching.h>
 
 #include "setup.h"
 
@@ -72,6 +73,7 @@
 #endif
 
 int boot_cpuid = 0;
+int __initdata boot_cpu_count;
 u64 ppc64_pft_size;
 
 /* Pick defaults since we might want to patch instructions
@@ -233,6 +235,7 @@
 void smp_release_cpus(void)
 {
 	unsigned long *ptr;
+	int i;
 
 	DBG(" -> smp_release_cpus()\n");
 
@@ -245,7 +248,16 @@
 	ptr  = (unsigned long *)((unsigned long)&__secondary_hold_spinloop
 			- PHYSICAL_START);
 	*ptr = __pa(generic_secondary_smp_init);
-	mb();
+
+	/* And wait a bit for them to catch up */
+	for (i = 0; i < 100000; i++) {
+		mb();
+		HMT_low();
+		if (boot_cpu_count == 0)
+			break;
+		udelay(1);
+	}
+	DBG("boot_cpu_count = %d\n", boot_cpu_count);
 
 	DBG(" <- smp_release_cpus()\n");
 }
@@ -423,17 +435,30 @@
 	DBG(" <- setup_system()\n");
 }
 
-static u64 slb0_limit(void)
+/* This returns the limit below which memory accesses to the linear
+ * mapping are guarnateed not to cause a TLB or SLB miss. This is
+ * used to allocate interrupt or emergency stacks for which our
+ * exception entry path doesn't deal with being interrupted.
+ */
+static u64 safe_stack_limit(void)
 {
-	if (cpu_has_feature(CPU_FTR_1T_SEGMENT)) {
+#ifdef CONFIG_PPC_BOOK3E
+	/* Freescale BookE bolts the entire linear mapping */
+	if (mmu_has_feature(MMU_FTR_TYPE_FSL_E))
+		return linear_map_top;
+	/* Other BookE, we assume the first GB is bolted */
+	return 1ul << 30;
+#else
+	/* BookS, the first segment is bolted */
+	if (mmu_has_feature(MMU_FTR_1T_SEGMENT))
 		return 1UL << SID_SHIFT_1T;
-	}
 	return 1UL << SID_SHIFT;
+#endif
 }
 
 static void __init irqstack_early_init(void)
 {
-	u64 limit = slb0_limit();
+	u64 limit = safe_stack_limit();
 	unsigned int i;
 
 	/*
@@ -453,6 +478,9 @@
 #ifdef CONFIG_PPC_BOOK3E
 static void __init exc_lvl_early_init(void)
 {
+	extern unsigned int interrupt_base_book3e;
+	extern unsigned int exc_debug_debug_book3e;
+
 	unsigned int i;
 
 	for_each_possible_cpu(i) {
@@ -463,6 +491,10 @@
 		mcheckirq_ctx[i] = (struct thread_info *)
 			__va(memblock_alloc(THREAD_SIZE, THREAD_SIZE));
 	}
+
+	if (cpu_has_feature(CPU_FTR_DEBUG_LVL_EXC))
+		patch_branch(&interrupt_base_book3e + (0x040 / 4) + 1,
+			     (unsigned long)&exc_debug_debug_book3e, 0);
 }
 #else
 #define exc_lvl_early_init()
@@ -486,7 +518,7 @@
 	 * bringup, we need to get at them in real mode. This means they
 	 * must also be within the RMO region.
 	 */
-	limit = min(slb0_limit(), ppc64_rma_size);
+	limit = min(safe_stack_limit(), ppc64_rma_size);
 
 	for_each_possible_cpu(i) {
 		unsigned long sp;
diff -druN linux-2.6.39-libre/arch/powerpc/kernel/setup-common.c linux-3.0-rc7-libre/arch/powerpc/kernel/setup-common.c
--- linux-2.6.39-libre/arch/powerpc/kernel/setup-common.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/kernel/setup-common.c	2011-07-11 19:51:52.000000000 -0400
@@ -381,7 +381,7 @@
 	int i;
 
 	threads_per_core = tpc;
-	threads_core_mask = CPU_MASK_NONE;
+	cpumask_clear(&threads_core_mask);
 
 	/* This implementation only supports power of 2 number of threads
 	 * for simplicity and performance
@@ -390,7 +390,7 @@
 	BUG_ON(tpc != (1 << threads_shift));
 
 	for (i = 0; i < tpc; i++)
-		cpu_set(i, threads_core_mask);
+		cpumask_set_cpu(i, &threads_core_mask);
 
 	printk(KERN_INFO "CPU maps initialized for %d thread%s per core\n",
 	       tpc, tpc > 1 ? "s" : "");
@@ -404,7 +404,7 @@
  *                  cpu_present_mask
  *
  * Having the possible map set up early allows us to restrict allocations
- * of things like irqstacks to num_possible_cpus() rather than NR_CPUS.
+ * of things like irqstacks to nr_cpu_ids rather than NR_CPUS.
  *
  * We do not initialize the online map here; cpus set their own bits in
  * cpu_online_mask as they come up.
@@ -424,7 +424,7 @@
 
 	DBG("smp_setup_cpu_maps()\n");
 
-	while ((dn = of_find_node_by_type(dn, "cpu")) && cpu < NR_CPUS) {
+	while ((dn = of_find_node_by_type(dn, "cpu")) && cpu < nr_cpu_ids) {
 		const int *intserv;
 		int j, len;
 
@@ -443,7 +443,7 @@
 				intserv = &cpu;	/* assume logical == phys */
 		}
 
-		for (j = 0; j < nthreads && cpu < NR_CPUS; j++) {
+		for (j = 0; j < nthreads && cpu < nr_cpu_ids; j++) {
 			DBG("    thread %d -> cpu %d (hard id %d)\n",
 			    j, cpu, intserv[j]);
 			set_cpu_present(cpu, true);
@@ -483,12 +483,12 @@
 		if (cpu_has_feature(CPU_FTR_SMT))
 			maxcpus *= nthreads;
 
-		if (maxcpus > NR_CPUS) {
+		if (maxcpus > nr_cpu_ids) {
 			printk(KERN_WARNING
 			       "Partition configured for %d cpus, "
 			       "operating system maximum is %d.\n",
-			       maxcpus, NR_CPUS);
-			maxcpus = NR_CPUS;
+			       maxcpus, nr_cpu_ids);
+			maxcpus = nr_cpu_ids;
 		} else
 			printk(KERN_INFO "Partition configured for %d cpus.\n",
 			       maxcpus);
@@ -510,7 +510,7 @@
 	cpu_init_thread_core_maps(nthreads);
 
 	/* Now that possible cpus are set, set nr_cpu_ids for later use */
-	nr_cpu_ids = find_last_bit(cpumask_bits(cpu_possible_mask),NR_CPUS) + 1;
+	setup_nr_cpu_ids();
 
 	free_unused_pacas();
 }
@@ -602,6 +602,10 @@
 		 * name instead */
 		if (!np)
 			np = of_find_node_by_name(NULL, "8042");
+		if (np) {
+			of_i8042_kbd_irq = 1;
+			of_i8042_aux_irq = 12;
+		}
 		break;
 	case FDC_BASE: /* FDC1 */
 		np = of_find_node_by_type(NULL, "fdc");
diff -druN linux-2.6.39-libre/arch/powerpc/kernel/signal_32.c linux-3.0-rc7-libre/arch/powerpc/kernel/signal_32.c
--- linux-2.6.39-libre/arch/powerpc/kernel/signal_32.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/kernel/signal_32.c	2011-07-11 19:51:52.000000000 -0400
@@ -25,6 +25,7 @@
 #include <linux/errno.h>
 #include <linux/elf.h>
 #include <linux/ptrace.h>
+#include <linux/ratelimit.h>
 #ifdef CONFIG_PPC64
 #include <linux/syscalls.h>
 #include <linux/compat.h>
@@ -892,11 +893,12 @@
 	printk("badframe in handle_rt_signal, regs=%p frame=%p newsp=%lx\n",
 	       regs, frame, newsp);
 #endif
-	if (show_unhandled_signals && printk_ratelimit())
-		printk(KERN_INFO "%s[%d]: bad frame in handle_rt_signal32: "
-			"%p nip %08lx lr %08lx\n",
-			current->comm, current->pid,
-			addr, regs->nip, regs->link);
+	if (show_unhandled_signals)
+		printk_ratelimited(KERN_INFO
+				   "%s[%d]: bad frame in handle_rt_signal32: "
+				   "%p nip %08lx lr %08lx\n",
+				   current->comm, current->pid,
+				   addr, regs->nip, regs->link);
 
 	force_sigsegv(sig, current);
 	return 0;
@@ -1058,11 +1060,12 @@
 	return 0;
 
  bad:
-	if (show_unhandled_signals && printk_ratelimit())
-		printk(KERN_INFO "%s[%d]: bad frame in sys_rt_sigreturn: "
-			"%p nip %08lx lr %08lx\n",
-			current->comm, current->pid,
-			rt_sf, regs->nip, regs->link);
+	if (show_unhandled_signals)
+		printk_ratelimited(KERN_INFO
+				   "%s[%d]: bad frame in sys_rt_sigreturn: "
+				   "%p nip %08lx lr %08lx\n",
+				   current->comm, current->pid,
+				   rt_sf, regs->nip, regs->link);
 
 	force_sig(SIGSEGV, current);
 	return 0;
@@ -1149,12 +1152,12 @@
 	 * We kill the task with a SIGSEGV in this situation.
 	 */
 	if (do_setcontext(ctx, regs, 1)) {
-		if (show_unhandled_signals && printk_ratelimit())
-			printk(KERN_INFO "%s[%d]: bad frame in "
-				"sys_debug_setcontext: %p nip %08lx "
-				"lr %08lx\n",
-				current->comm, current->pid,
-				ctx, regs->nip, regs->link);
+		if (show_unhandled_signals)
+			printk_ratelimited(KERN_INFO "%s[%d]: bad frame in "
+					   "sys_debug_setcontext: %p nip %08lx "
+					   "lr %08lx\n",
+					   current->comm, current->pid,
+					   ctx, regs->nip, regs->link);
 
 		force_sig(SIGSEGV, current);
 		goto out;
@@ -1236,11 +1239,12 @@
 	printk("badframe in handle_signal, regs=%p frame=%p newsp=%lx\n",
 	       regs, frame, newsp);
 #endif
-	if (show_unhandled_signals && printk_ratelimit())
-		printk(KERN_INFO "%s[%d]: bad frame in handle_signal32: "
-			"%p nip %08lx lr %08lx\n",
-			current->comm, current->pid,
-			frame, regs->nip, regs->link);
+	if (show_unhandled_signals)
+		printk_ratelimited(KERN_INFO
+				   "%s[%d]: bad frame in handle_signal32: "
+				   "%p nip %08lx lr %08lx\n",
+				   current->comm, current->pid,
+				   frame, regs->nip, regs->link);
 
 	force_sigsegv(sig, current);
 	return 0;
@@ -1288,11 +1292,12 @@
 	return 0;
 
 badframe:
-	if (show_unhandled_signals && printk_ratelimit())
-		printk(KERN_INFO "%s[%d]: bad frame in sys_sigreturn: "
-			"%p nip %08lx lr %08lx\n",
-			current->comm, current->pid,
-			addr, regs->nip, regs->link);
+	if (show_unhandled_signals)
+		printk_ratelimited(KERN_INFO
+				   "%s[%d]: bad frame in sys_sigreturn: "
+				   "%p nip %08lx lr %08lx\n",
+				   current->comm, current->pid,
+				   addr, regs->nip, regs->link);
 
 	force_sig(SIGSEGV, current);
 	return 0;
diff -druN linux-2.6.39-libre/arch/powerpc/kernel/signal_64.c linux-3.0-rc7-libre/arch/powerpc/kernel/signal_64.c
--- linux-2.6.39-libre/arch/powerpc/kernel/signal_64.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/kernel/signal_64.c	2011-07-11 19:51:52.000000000 -0400
@@ -24,6 +24,7 @@
 #include <linux/elf.h>
 #include <linux/ptrace.h>
 #include <linux/module.h>
+#include <linux/ratelimit.h>
 
 #include <asm/sigcontext.h>
 #include <asm/ucontext.h>
@@ -380,10 +381,10 @@
 	printk("badframe in sys_rt_sigreturn, regs=%p uc=%p &uc->uc_mcontext=%p\n",
 	       regs, uc, &uc->uc_mcontext);
 #endif
-	if (show_unhandled_signals && printk_ratelimit())
-		printk(regs->msr & MSR_SF ? fmt64 : fmt32,
-			current->comm, current->pid, "rt_sigreturn",
-			(long)uc, regs->nip, regs->link);
+	if (show_unhandled_signals)
+		printk_ratelimited(regs->msr & MSR_64BIT ? fmt64 : fmt32,
+				   current->comm, current->pid, "rt_sigreturn",
+				   (long)uc, regs->nip, regs->link);
 
 	force_sig(SIGSEGV, current);
 	return 0;
@@ -468,10 +469,10 @@
 	printk("badframe in setup_rt_frame, regs=%p frame=%p newsp=%lx\n",
 	       regs, frame, newsp);
 #endif
-	if (show_unhandled_signals && printk_ratelimit())
-		printk(regs->msr & MSR_SF ? fmt64 : fmt32,
-			current->comm, current->pid, "setup_rt_frame",
-			(long)frame, regs->nip, regs->link);
+	if (show_unhandled_signals)
+		printk_ratelimited(regs->msr & MSR_64BIT ? fmt64 : fmt32,
+				   current->comm, current->pid, "setup_rt_frame",
+				   (long)frame, regs->nip, regs->link);
 
 	force_sigsegv(signr, current);
 	return 0;
diff -druN linux-2.6.39-libre/arch/powerpc/kernel/smp.c linux-3.0-rc7-libre/arch/powerpc/kernel/smp.c
--- linux-2.6.39-libre/arch/powerpc/kernel/smp.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/kernel/smp.c	2011-07-11 19:51:52.000000000 -0400
@@ -95,7 +95,7 @@
 static void (*crash_ipi_function_ptr)(struct pt_regs *) = NULL;
 
 #ifdef CONFIG_PPC64
-void __devinit smp_generic_kick_cpu(int nr)
+int __devinit smp_generic_kick_cpu(int nr)
 {
 	BUG_ON(nr < 0 || nr >= NR_CPUS);
 
@@ -106,37 +106,10 @@
 	 */
 	paca[nr].cpu_start = 1;
 	smp_mb();
-}
-#endif
 
-void smp_message_recv(int msg)
-{
-	switch(msg) {
-	case PPC_MSG_CALL_FUNCTION:
-		generic_smp_call_function_interrupt();
-		break;
-	case PPC_MSG_RESCHEDULE:
-		/* we notice need_resched on exit */
-		break;
-	case PPC_MSG_CALL_FUNC_SINGLE:
-		generic_smp_call_function_single_interrupt();
-		break;
-	case PPC_MSG_DEBUGGER_BREAK:
-		if (crash_ipi_function_ptr) {
-			crash_ipi_function_ptr(get_irq_regs());
-			break;
-		}
-#ifdef CONFIG_DEBUGGER
-		debugger_ipi(get_irq_regs());
-		break;
-#endif /* CONFIG_DEBUGGER */
-		/* FALLTHROUGH */
-	default:
-		printk("SMP %d: smp_message_recv(): unknown msg %d\n",
-		       smp_processor_id(), msg);
-		break;
-	}
+	return 0;
 }
+#endif
 
 static irqreturn_t call_function_action(int irq, void *data)
 {
@@ -146,7 +119,7 @@
 
 static irqreturn_t reschedule_action(int irq, void *data)
 {
-	/* we just need the return path side effect of checking need_resched */
+	scheduler_ipi();
 	return IRQ_HANDLED;
 }
 
@@ -158,7 +131,15 @@
 
 static irqreturn_t debug_ipi_action(int irq, void *data)
 {
-	smp_message_recv(PPC_MSG_DEBUGGER_BREAK);
+	if (crash_ipi_function_ptr) {
+		crash_ipi_function_ptr(get_irq_regs());
+		return IRQ_HANDLED;
+	}
+
+#ifdef CONFIG_DEBUGGER
+	debugger_ipi(get_irq_regs());
+#endif /* CONFIG_DEBUGGER */
+
 	return IRQ_HANDLED;
 }
 
@@ -197,6 +178,66 @@
 	return err;
 }
 
+#ifdef CONFIG_PPC_SMP_MUXED_IPI
+struct cpu_messages {
+	int messages;			/* current messages */
+	unsigned long data;		/* data for cause ipi */
+};
+static DEFINE_PER_CPU_SHARED_ALIGNED(struct cpu_messages, ipi_message);
+
+void smp_muxed_ipi_set_data(int cpu, unsigned long data)
+{
+	struct cpu_messages *info = &per_cpu(ipi_message, cpu);
+
+	info->data = data;
+}
+
+void smp_muxed_ipi_message_pass(int cpu, int msg)
+{
+	struct cpu_messages *info = &per_cpu(ipi_message, cpu);
+	char *message = (char *)&info->messages;
+
+	message[msg] = 1;
+	mb();
+	smp_ops->cause_ipi(cpu, info->data);
+}
+
+void smp_muxed_ipi_resend(void)
+{
+	struct cpu_messages *info = &__get_cpu_var(ipi_message);
+
+	if (info->messages)
+		smp_ops->cause_ipi(smp_processor_id(), info->data);
+}
+
+irqreturn_t smp_ipi_demux(void)
+{
+	struct cpu_messages *info = &__get_cpu_var(ipi_message);
+	unsigned int all;
+
+	mb();	/* order any irq clear */
+
+	do {
+		all = xchg_local(&info->messages, 0);
+
+#ifdef __BIG_ENDIAN
+		if (all & (1 << (24 - 8 * PPC_MSG_CALL_FUNCTION)))
+			generic_smp_call_function_interrupt();
+		if (all & (1 << (24 - 8 * PPC_MSG_RESCHEDULE)))
+			scheduler_ipi();
+		if (all & (1 << (24 - 8 * PPC_MSG_CALL_FUNC_SINGLE)))
+			generic_smp_call_function_single_interrupt();
+		if (all & (1 << (24 - 8 * PPC_MSG_DEBUGGER_BREAK)))
+			debug_ipi_action(0, NULL);
+#else
+#error Unsupported ENDIAN
+#endif
+	} while (info->messages);
+
+	return IRQ_HANDLED;
+}
+#endif /* CONFIG_PPC_SMP_MUXED_IPI */
+
 void smp_send_reschedule(int cpu)
 {
 	if (likely(smp_ops))
@@ -216,11 +257,18 @@
 		smp_ops->message_pass(cpu, PPC_MSG_CALL_FUNCTION);
 }
 
-#ifdef CONFIG_DEBUGGER
-void smp_send_debugger_break(int cpu)
+#if defined(CONFIG_DEBUGGER) || defined(CONFIG_KEXEC)
+void smp_send_debugger_break(void)
 {
-	if (likely(smp_ops))
-		smp_ops->message_pass(cpu, PPC_MSG_DEBUGGER_BREAK);
+	int cpu;
+	int me = raw_smp_processor_id();
+
+	if (unlikely(!smp_ops))
+		return;
+
+	for_each_online_cpu(cpu)
+		if (cpu != me)
+			smp_ops->message_pass(cpu, PPC_MSG_DEBUGGER_BREAK);
 }
 #endif
 
@@ -228,9 +276,9 @@
 void crash_send_ipi(void (*crash_ipi_callback)(struct pt_regs *))
 {
 	crash_ipi_function_ptr = crash_ipi_callback;
-	if (crash_ipi_callback && smp_ops) {
+	if (crash_ipi_callback) {
 		mb();
-		smp_ops->message_pass(MSG_ALL_BUT_SELF, PPC_MSG_DEBUGGER_BREAK);
+		smp_send_debugger_break();
 	}
 }
 #endif
@@ -410,8 +458,6 @@
 {
 	int rc, c;
 
-	secondary_ti = current_set[cpu];
-
 	if (smp_ops == NULL ||
 	    (smp_ops->cpu_bootable && !smp_ops->cpu_bootable(cpu)))
 		return -EINVAL;
@@ -421,6 +467,8 @@
 	if (rc)
 		return rc;
 
+	secondary_ti = current_set[cpu];
+
 	/* Make sure callin-map entry is 0 (can be leftover a CPU
 	 * hotplug
 	 */
@@ -434,7 +482,11 @@
 
 	/* wake up cpus */
 	DBG("smp: kicking cpu %d\n", cpu);
-	smp_ops->kick_cpu(cpu);
+	rc = smp_ops->kick_cpu(cpu);
+	if (rc) {
+		pr_err("smp: failed starting cpu %d (rc %d)\n", cpu, rc);
+		return rc;
+	}
 
 	/*
 	 * wait to see if the cpu made a callin (is actually up).
@@ -507,7 +559,7 @@
 }
 EXPORT_SYMBOL_GPL(cpu_first_thread_of_core);
 
-/* Must be called when no change can occur to cpu_present_map,
+/* Must be called when no change can occur to cpu_present_mask,
  * i.e. during cpu online or offline.
  */
 static struct device_node *cpu_to_l2cache(int cpu)
@@ -608,7 +660,7 @@
 	 * se we pin us down to CPU 0 for a short while
 	 */
 	alloc_cpumask_var(&old_mask, GFP_NOWAIT);
-	cpumask_copy(old_mask, &current->cpus_allowed);
+	cpumask_copy(old_mask, tsk_cpus_allowed(current));
 	set_cpus_allowed_ptr(current, cpumask_of(boot_cpuid));
 	
 	if (smp_ops && smp_ops->setup_cpu)
diff -druN linux-2.6.39-libre/arch/powerpc/kernel/swsusp.c linux-3.0-rc7-libre/arch/powerpc/kernel/swsusp.c
--- linux-2.6.39-libre/arch/powerpc/kernel/swsusp.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/kernel/swsusp.c	2011-07-11 19:51:52.000000000 -0400
@@ -10,7 +10,6 @@
  */
 
 #include <linux/sched.h>
-#include <asm/suspend.h>
 #include <asm/system.h>
 #include <asm/current.h>
 #include <asm/mmu_context.h>
diff -druN linux-2.6.39-libre/arch/powerpc/kernel/sysfs.c linux-3.0-rc7-libre/arch/powerpc/kernel/sysfs.c
--- linux-2.6.39-libre/arch/powerpc/kernel/sysfs.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/kernel/sysfs.c	2011-07-11 19:51:52.000000000 -0400
@@ -182,6 +182,41 @@
 static SYSDEV_ATTR(spurr, 0600, show_spurr, NULL);
 static SYSDEV_ATTR(dscr, 0600, show_dscr, store_dscr);
 static SYSDEV_ATTR(purr, 0600, show_purr, store_purr);
+
+unsigned long dscr_default = 0;
+EXPORT_SYMBOL(dscr_default);
+
+static ssize_t show_dscr_default(struct sysdev_class *class,
+		struct sysdev_class_attribute *attr, char *buf)
+{
+	return sprintf(buf, "%lx\n", dscr_default);
+}
+
+static ssize_t __used store_dscr_default(struct sysdev_class *class,
+		struct sysdev_class_attribute *attr, const char *buf,
+		size_t count)
+{
+	unsigned long val;
+	int ret = 0;
+	
+	ret = sscanf(buf, "%lx", &val);
+	if (ret != 1)
+		return -EINVAL;
+	dscr_default = val;
+
+	return count;
+}
+
+static SYSDEV_CLASS_ATTR(dscr_default, 0600,
+		show_dscr_default, store_dscr_default);
+
+static void sysfs_create_dscr_default(void)
+{
+	int err = 0;
+	if (cpu_has_feature(CPU_FTR_DSCR))
+		err = sysfs_create_file(&cpu_sysdev_class.kset.kobj,
+			&attr_dscr_default.attr);
+}
 #endif /* CONFIG_PPC64 */
 
 #ifdef HAS_PPC_PMC_PA6T
@@ -617,6 +652,9 @@
 		if (cpu_online(cpu))
 			register_cpu_online(cpu);
 	}
+#ifdef CONFIG_PPC64
+	sysfs_create_dscr_default();
+#endif /* CONFIG_PPC64 */
 
 	return 0;
 }
diff -druN linux-2.6.39-libre/arch/powerpc/kernel/traps.c linux-3.0-rc7-libre/arch/powerpc/kernel/traps.c
--- linux-2.6.39-libre/arch/powerpc/kernel/traps.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/kernel/traps.c	2011-07-11 19:51:52.000000000 -0400
@@ -34,6 +34,7 @@
 #include <linux/bug.h>
 #include <linux/kdebug.h>
 #include <linux/debugfs.h>
+#include <linux/ratelimit.h>
 
 #include <asm/emulated_ops.h>
 #include <asm/pgtable.h>
@@ -55,6 +56,7 @@
 #endif
 #include <asm/kexec.h>
 #include <asm/ppc-opcode.h>
+#include <asm/rio.h>
 
 #if defined(CONFIG_DEBUGGER) || defined(CONFIG_KEXEC)
 int (*__debugger)(struct pt_regs *regs) __read_mostly;
@@ -143,7 +145,6 @@
 #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;
@@ -197,12 +198,11 @@
 		if (die("Exception in kernel mode", regs, signr))
 			return;
 	} else if (show_unhandled_signals &&
-		    unhandled_signal(current, signr) &&
-		    printk_ratelimit()) {
-			printk(regs->msr & MSR_SF ? fmt64 : fmt32,
-				current->comm, current->pid, signr,
-				addr, regs->nip, regs->link, code);
-		}
+		   unhandled_signal(current, signr)) {
+		printk_ratelimited(regs->msr & MSR_64BIT ? fmt64 : fmt32,
+				   current->comm, current->pid, signr,
+				   addr, regs->nip, regs->link, code);
+	}
 
 	memset(&info, 0, sizeof(info));
 	info.si_signo = signr;
@@ -221,7 +221,7 @@
 	}
 
 #ifdef CONFIG_KEXEC
-	cpu_set(smp_processor_id(), cpus_in_sr);
+	cpumask_set_cpu(smp_processor_id(), &cpus_in_sr);
 #endif
 
 	die("System Reset", regs, SIGABRT);
@@ -425,6 +425,12 @@
 	unsigned long reason = mcsr;
 	int recoverable = 1;
 
+	if (reason & MCSR_LD) {
+		recoverable = fsl_rio_mcheck_exception(regs);
+		if (recoverable == 1)
+			goto silent_out;
+	}
+
 	printk("Machine check in kernel mode.\n");
 	printk("Caused by (from MCSR=%lx): ", reason);
 
@@ -500,6 +506,7 @@
 		       reason & MCSR_MEA ? "Effective" : "Physical", addr);
 	}
 
+silent_out:
 	mtspr(SPRN_MCSR, mcsr);
 	return mfspr(SPRN_MCSR) == 0 && recoverable;
 }
@@ -508,6 +515,11 @@
 {
 	unsigned long reason = get_mc_reason(regs);
 
+	if (reason & MCSR_BUS_RBERR) {
+		if (fsl_rio_mcheck_exception(regs))
+			return 1;
+	}
+
 	printk("Machine check in kernel mode.\n");
 	printk("Caused by (from MCSR=%lx): ", reason);
 
@@ -909,6 +921,26 @@
 		return emulate_isel(regs, instword);
 	}
 
+#ifdef CONFIG_PPC64
+	/* Emulate the mfspr rD, DSCR. */
+	if (((instword & PPC_INST_MFSPR_DSCR_MASK) == PPC_INST_MFSPR_DSCR) &&
+			cpu_has_feature(CPU_FTR_DSCR)) {
+		PPC_WARN_EMULATED(mfdscr, regs);
+		rd = (instword >> 21) & 0x1f;
+		regs->gpr[rd] = mfspr(SPRN_DSCR);
+		return 0;
+	}
+	/* Emulate the mtspr DSCR, rD. */
+	if (((instword & PPC_INST_MTSPR_DSCR_MASK) == PPC_INST_MTSPR_DSCR) &&
+			cpu_has_feature(CPU_FTR_DSCR)) {
+		PPC_WARN_EMULATED(mtdscr, regs);
+		rd = (instword >> 21) & 0x1f;
+		mtspr(SPRN_DSCR, regs->gpr[rd]);
+		current->thread.dscr_inherit = 1;
+		return 0;
+	}
+#endif
+
 	return -EINVAL;
 }
 
@@ -1310,9 +1342,8 @@
 	} else {
 		/* didn't recognize the instruction */
 		/* XXX quick hack for now: set the non-Java bit in the VSCR */
-		if (printk_ratelimit())
-			printk(KERN_ERR "Unrecognized altivec instruction "
-			       "in %s at %lx\n", current->comm, regs->nip);
+		printk_ratelimited(KERN_ERR "Unrecognized altivec instruction "
+				   "in %s at %lx\n", current->comm, regs->nip);
 		current->thread.vscr.u[3] |= 0x10000;
 	}
 }
@@ -1506,15 +1537,18 @@
 #ifdef CONFIG_VSX
 	WARN_EMULATED_SETUP(vsx),
 #endif
+#ifdef CONFIG_PPC64
+	WARN_EMULATED_SETUP(mfdscr),
+	WARN_EMULATED_SETUP(mtdscr),
+#endif
 };
 
 u32 ppc_warn_emulated;
 
 void ppc_warn_emulated_print(const char *type)
 {
-	if (printk_ratelimit())
-		pr_warning("%s used emulated %s instruction\n", current->comm,
-			   type);
+	pr_warn_ratelimited("%s used emulated %s instruction\n", current->comm,
+			    type);
 }
 
 static int __init ppc_warn_emulated_init(void)
diff -druN linux-2.6.39-libre/arch/powerpc/kernel/udbg_16550.c linux-3.0-rc7-libre/arch/powerpc/kernel/udbg_16550.c
--- linux-2.6.39-libre/arch/powerpc/kernel/udbg_16550.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/kernel/udbg_16550.c	2011-07-11 19:51:52.000000000 -0400
@@ -11,6 +11,7 @@
 #include <linux/types.h>
 #include <asm/udbg.h>
 #include <asm/io.h>
+#include <asm/reg_a2.h>
 
 extern u8 real_readb(volatile u8 __iomem  *addr);
 extern void real_writeb(u8 data, volatile u8 __iomem *addr);
@@ -298,3 +299,53 @@
 	udbg_getc_poll = NULL;
 }
 #endif /* CONFIG_PPC_EARLY_DEBUG_40x */
+
+#ifdef CONFIG_PPC_EARLY_DEBUG_WSP
+static void udbg_wsp_flush(void)
+{
+	if (udbg_comport) {
+		while ((readb(&udbg_comport->lsr) & LSR_THRE) == 0)
+			/* wait for idle */;
+	}
+}
+
+static void udbg_wsp_putc(char c)
+{
+	if (udbg_comport) {
+		if (c == '\n')
+			udbg_wsp_putc('\r');
+		udbg_wsp_flush();
+		writeb(c, &udbg_comport->thr); eieio();
+	}
+}
+
+static int udbg_wsp_getc(void)
+{
+	if (udbg_comport) {
+		while ((readb(&udbg_comport->lsr) & LSR_DR) == 0)
+			; /* wait for char */
+		return readb(&udbg_comport->rbr);
+	}
+	return -1;
+}
+
+static int udbg_wsp_getc_poll(void)
+{
+	if (udbg_comport)
+		if (readb(&udbg_comport->lsr) & LSR_DR)
+			return readb(&udbg_comport->rbr);
+	return -1;
+}
+
+void __init udbg_init_wsp(void)
+{
+	udbg_comport = (struct NS16550 __iomem *)WSP_UART_VIRT;
+
+	udbg_init_uart(udbg_comport, 57600, 50000000);
+
+	udbg_putc = udbg_wsp_putc;
+	udbg_flush = udbg_wsp_flush;
+	udbg_getc = udbg_wsp_getc;
+	udbg_getc_poll = udbg_wsp_getc_poll;
+}
+#endif /* CONFIG_PPC_EARLY_DEBUG_WSP */
diff -druN linux-2.6.39-libre/arch/powerpc/kernel/udbg.c linux-3.0-rc7-libre/arch/powerpc/kernel/udbg.c
--- linux-2.6.39-libre/arch/powerpc/kernel/udbg.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/kernel/udbg.c	2011-07-11 19:51:52.000000000 -0400
@@ -62,6 +62,8 @@
 	udbg_init_cpm();
 #elif defined(CONFIG_PPC_EARLY_DEBUG_USBGECKO)
 	udbg_init_usbgecko();
+#elif defined(CONFIG_PPC_EARLY_DEBUG_WSP)
+	udbg_init_wsp();
 #endif
 
 #ifdef CONFIG_PPC_EARLY_DEBUG
diff -druN linux-2.6.39-libre/arch/powerpc/kernel/vector.S linux-3.0-rc7-libre/arch/powerpc/kernel/vector.S
--- linux-2.6.39-libre/arch/powerpc/kernel/vector.S	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/kernel/vector.S	2011-07-11 19:51:52.000000000 -0400
@@ -102,7 +102,7 @@
 	MTMSRD(r5)			/* enable use of VMX now */
 	isync
 	PPC_LCMPI	0,r3,0
-	beqlr-				/* if no previous owner, done */
+	beqlr				/* if no previous owner, done */
 	addi	r3,r3,THREAD		/* want THREAD of task */
 	PPC_LL	r5,PT_REGS(r3)
 	PPC_LCMPI	0,r5,0
diff -druN linux-2.6.39-libre/arch/powerpc/kernel/vmlinux.lds.S linux-3.0-rc7-libre/arch/powerpc/kernel/vmlinux.lds.S
--- linux-2.6.39-libre/arch/powerpc/kernel/vmlinux.lds.S	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/kernel/vmlinux.lds.S	2011-07-11 19:51:52.000000000 -0400
@@ -160,7 +160,7 @@
 		INIT_RAM_FS
 	}
 
-	PERCPU(L1_CACHE_BYTES, PAGE_SIZE)
+	PERCPU_SECTION(L1_CACHE_BYTES)
 
 	. = ALIGN(8);
 	.machine.desc : AT(ADDR(.machine.desc) - LOAD_OFFSET) {
diff -druN linux-2.6.39-libre/arch/powerpc/kvm/44x.c linux-3.0-rc7-libre/arch/powerpc/kvm/44x.c
--- linux-2.6.39-libre/arch/powerpc/kvm/44x.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/kvm/44x.c	2011-07-11 19:51:52.000000000 -0400
@@ -107,6 +107,16 @@
 	return 0;
 }
 
+void kvmppc_core_get_sregs(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs)
+{
+	kvmppc_get_sregs_ivor(vcpu, sregs);
+}
+
+int kvmppc_core_set_sregs(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs)
+{
+	return kvmppc_set_sregs_ivor(vcpu, sregs);
+}
+
 struct kvm_vcpu *kvmppc_core_vcpu_create(struct kvm *kvm, unsigned int id)
 {
 	struct kvmppc_vcpu_44x *vcpu_44x;
diff -druN linux-2.6.39-libre/arch/powerpc/kvm/44x_emulate.c linux-3.0-rc7-libre/arch/powerpc/kvm/44x_emulate.c
--- linux-2.6.39-libre/arch/powerpc/kvm/44x_emulate.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/kvm/44x_emulate.c	2011-07-11 19:51:52.000000000 -0400
@@ -158,7 +158,6 @@
 		emulated = kvmppc_booke_emulate_mtspr(vcpu, sprn, rs);
 	}
 
-	kvmppc_set_exit_type(vcpu, EMULATED_MTSPR_EXITS);
 	return emulated;
 }
 
@@ -179,7 +178,6 @@
 		emulated = kvmppc_booke_emulate_mfspr(vcpu, sprn, rt);
 	}
 
-	kvmppc_set_exit_type(vcpu, EMULATED_MFSPR_EXITS);
 	return emulated;
 }
 
diff -druN linux-2.6.39-libre/arch/powerpc/kvm/book3s.c linux-3.0-rc7-libre/arch/powerpc/kvm/book3s.c
--- linux-2.6.39-libre/arch/powerpc/kvm/book3s.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/kvm/book3s.c	2011-07-11 19:51:52.000000000 -0400
@@ -236,7 +236,7 @@
 
 int kvmppc_core_pending_dec(struct kvm_vcpu *vcpu)
 {
-	return test_bit(BOOK3S_INTERRUPT_DECREMENTER >> 7, &vcpu->arch.pending_exceptions);
+	return test_bit(BOOK3S_IRQPRIO_DECREMENTER, &vcpu->arch.pending_exceptions);
 }
 
 void kvmppc_core_dequeue_dec(struct kvm_vcpu *vcpu)
diff -druN linux-2.6.39-libre/arch/powerpc/kvm/book3s_rmhandlers.S linux-3.0-rc7-libre/arch/powerpc/kvm/book3s_rmhandlers.S
--- linux-2.6.39-libre/arch/powerpc/kvm/book3s_rmhandlers.S	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/kvm/book3s_rmhandlers.S	2011-07-11 19:51:52.000000000 -0400
@@ -35,9 +35,7 @@
 
 #if defined(CONFIG_PPC_BOOK3S_64)
 
-#define LOAD_SHADOW_VCPU(reg)				\
-	mfspr	reg, SPRN_SPRG_PACA
-
+#define LOAD_SHADOW_VCPU(reg)	GET_PACA(reg)					
 #define SHADOW_VCPU_OFF		PACA_KVM_SVCPU
 #define MSR_NOIRQ		MSR_KERNEL & ~(MSR_IR | MSR_DR)
 #define FUNC(name) 		GLUE(.,name)
@@ -72,7 +70,7 @@
 .global kvmppc_trampoline_\intno
 kvmppc_trampoline_\intno:
 
-	mtspr	SPRN_SPRG_SCRATCH0, r13		/* Save r13 */
+	SET_SCRATCH0(r13)		/* Save r13 */
 
 	/*
 	 * First thing to do is to find out if we're coming
@@ -91,7 +89,7 @@
 	lwz	r12, (SHADOW_VCPU_OFF + SVCPU_SCRATCH1)(r13)
 	mtcr	r12
 	PPC_LL	r12, (SHADOW_VCPU_OFF + SVCPU_SCRATCH0)(r13)
-	mfspr	r13, SPRN_SPRG_SCRATCH0		/* r13 = original r13 */
+	GET_SCRATCH0(r13)			/* r13 = original r13 */
 	b	kvmppc_resume_\intno		/* Get back original handler */
 
 	/* Now we know we're handling a KVM guest */
@@ -114,6 +112,9 @@
 INTERRUPT_TRAMPOLINE	BOOK3S_INTERRUPT_DATA_STORAGE
 INTERRUPT_TRAMPOLINE	BOOK3S_INTERRUPT_INST_STORAGE
 INTERRUPT_TRAMPOLINE	BOOK3S_INTERRUPT_EXTERNAL
+#ifdef CONFIG_PPC_BOOK3S_64
+INTERRUPT_TRAMPOLINE	BOOK3S_INTERRUPT_EXTERNAL_HV
+#endif
 INTERRUPT_TRAMPOLINE	BOOK3S_INTERRUPT_ALIGNMENT
 INTERRUPT_TRAMPOLINE	BOOK3S_INTERRUPT_PROGRAM
 INTERRUPT_TRAMPOLINE	BOOK3S_INTERRUPT_FP_UNAVAIL
@@ -158,7 +159,7 @@
 	lwz	r12, (SHADOW_VCPU_OFF + SVCPU_SCRATCH1)(r13)
 	mtcr	r12
 	PPC_LL	r12, (SHADOW_VCPU_OFF + SVCPU_SCRATCH0)(r13)
-	mfspr	r13, SPRN_SPRG_SCRATCH0
+	GET_SCRATCH0(r13)
 
 	/* And get back into the code */
 	RFI
diff -druN linux-2.6.39-libre/arch/powerpc/kvm/book3s_segment.S linux-3.0-rc7-libre/arch/powerpc/kvm/book3s_segment.S
--- linux-2.6.39-libre/arch/powerpc/kvm/book3s_segment.S	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/kvm/book3s_segment.S	2011-07-11 19:51:52.000000000 -0400
@@ -155,14 +155,20 @@
 	PPC_LL	r2, (SHADOW_VCPU_OFF + SVCPU_HOST_R2)(r13)
 
 	/* Save guest PC and MSR */
-	mfsrr0	r3
+	andi.	r0,r12,0x2
+	beq	1f
+	mfspr	r3,SPRN_HSRR0
+	mfspr	r4,SPRN_HSRR1
+	andi.	r12,r12,0x3ffd
+	b	2f
+1:	mfsrr0	r3
 	mfsrr1	r4
-
+2:
 	PPC_STL	r3, (SHADOW_VCPU_OFF + SVCPU_PC)(r13)
 	PPC_STL	r4, (SHADOW_VCPU_OFF + SVCPU_SHADOW_SRR1)(r13)
 
 	/* Get scratch'ed off registers */
-	mfspr	r9, SPRN_SPRG_SCRATCH0
+	GET_SCRATCH0(r9)
 	PPC_LL	r8, (SHADOW_VCPU_OFF + SVCPU_SCRATCH0)(r13)
 	lwz	r7, (SHADOW_VCPU_OFF + SVCPU_SCRATCH1)(r13)
 
diff -druN linux-2.6.39-libre/arch/powerpc/kvm/booke.c linux-3.0-rc7-libre/arch/powerpc/kvm/booke.c
--- linux-2.6.39-libre/arch/powerpc/kvm/booke.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/kvm/booke.c	2011-07-11 19:51:52.000000000 -0400
@@ -569,6 +569,7 @@
 	kvmppc_set_msr(vcpu, regs->msr);
 	vcpu->arch.shared->srr0 = regs->srr0;
 	vcpu->arch.shared->srr1 = regs->srr1;
+	kvmppc_set_pid(vcpu, regs->pid);
 	vcpu->arch.shared->sprg0 = regs->sprg0;
 	vcpu->arch.shared->sprg1 = regs->sprg1;
 	vcpu->arch.shared->sprg2 = regs->sprg2;
@@ -584,16 +585,165 @@
 	return 0;
 }
 
+static void get_sregs_base(struct kvm_vcpu *vcpu,
+                           struct kvm_sregs *sregs)
+{
+	u64 tb = get_tb();
+
+	sregs->u.e.features |= KVM_SREGS_E_BASE;
+
+	sregs->u.e.csrr0 = vcpu->arch.csrr0;
+	sregs->u.e.csrr1 = vcpu->arch.csrr1;
+	sregs->u.e.mcsr = vcpu->arch.mcsr;
+	sregs->u.e.esr = vcpu->arch.esr;
+	sregs->u.e.dear = vcpu->arch.shared->dar;
+	sregs->u.e.tsr = vcpu->arch.tsr;
+	sregs->u.e.tcr = vcpu->arch.tcr;
+	sregs->u.e.dec = kvmppc_get_dec(vcpu, tb);
+	sregs->u.e.tb = tb;
+	sregs->u.e.vrsave = vcpu->arch.vrsave;
+}
+
+static int set_sregs_base(struct kvm_vcpu *vcpu,
+                          struct kvm_sregs *sregs)
+{
+	if (!(sregs->u.e.features & KVM_SREGS_E_BASE))
+		return 0;
+
+	vcpu->arch.csrr0 = sregs->u.e.csrr0;
+	vcpu->arch.csrr1 = sregs->u.e.csrr1;
+	vcpu->arch.mcsr = sregs->u.e.mcsr;
+	vcpu->arch.esr = sregs->u.e.esr;
+	vcpu->arch.shared->dar = sregs->u.e.dear;
+	vcpu->arch.vrsave = sregs->u.e.vrsave;
+	vcpu->arch.tcr = sregs->u.e.tcr;
+
+	if (sregs->u.e.update_special & KVM_SREGS_E_UPDATE_DEC)
+		vcpu->arch.dec = sregs->u.e.dec;
+
+	kvmppc_emulate_dec(vcpu);
+
+	if (sregs->u.e.update_special & KVM_SREGS_E_UPDATE_TSR) {
+		/*
+		 * FIXME: existing KVM timer handling is incomplete.
+		 * TSR cannot be read by the guest, and its value in
+		 * vcpu->arch is always zero.  For now, just handle
+		 * the case where the caller is trying to inject a
+		 * decrementer interrupt.
+		 */
+
+		if ((sregs->u.e.tsr & TSR_DIS) &&
+		    (vcpu->arch.tcr & TCR_DIE))
+			kvmppc_core_queue_dec(vcpu);
+	}
+
+	return 0;
+}
+
+static void get_sregs_arch206(struct kvm_vcpu *vcpu,
+                              struct kvm_sregs *sregs)
+{
+	sregs->u.e.features |= KVM_SREGS_E_ARCH206;
+
+	sregs->u.e.pir = 0;
+	sregs->u.e.mcsrr0 = vcpu->arch.mcsrr0;
+	sregs->u.e.mcsrr1 = vcpu->arch.mcsrr1;
+	sregs->u.e.decar = vcpu->arch.decar;
+	sregs->u.e.ivpr = vcpu->arch.ivpr;
+}
+
+static int set_sregs_arch206(struct kvm_vcpu *vcpu,
+                             struct kvm_sregs *sregs)
+{
+	if (!(sregs->u.e.features & KVM_SREGS_E_ARCH206))
+		return 0;
+
+	if (sregs->u.e.pir != 0)
+		return -EINVAL;
+
+	vcpu->arch.mcsrr0 = sregs->u.e.mcsrr0;
+	vcpu->arch.mcsrr1 = sregs->u.e.mcsrr1;
+	vcpu->arch.decar = sregs->u.e.decar;
+	vcpu->arch.ivpr = sregs->u.e.ivpr;
+
+	return 0;
+}
+
+void kvmppc_get_sregs_ivor(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs)
+{
+	sregs->u.e.features |= KVM_SREGS_E_IVOR;
+
+	sregs->u.e.ivor_low[0] = vcpu->arch.ivor[BOOKE_IRQPRIO_CRITICAL];
+	sregs->u.e.ivor_low[1] = vcpu->arch.ivor[BOOKE_IRQPRIO_MACHINE_CHECK];
+	sregs->u.e.ivor_low[2] = vcpu->arch.ivor[BOOKE_IRQPRIO_DATA_STORAGE];
+	sregs->u.e.ivor_low[3] = vcpu->arch.ivor[BOOKE_IRQPRIO_INST_STORAGE];
+	sregs->u.e.ivor_low[4] = vcpu->arch.ivor[BOOKE_IRQPRIO_EXTERNAL];
+	sregs->u.e.ivor_low[5] = vcpu->arch.ivor[BOOKE_IRQPRIO_ALIGNMENT];
+	sregs->u.e.ivor_low[6] = vcpu->arch.ivor[BOOKE_IRQPRIO_PROGRAM];
+	sregs->u.e.ivor_low[7] = vcpu->arch.ivor[BOOKE_IRQPRIO_FP_UNAVAIL];
+	sregs->u.e.ivor_low[8] = vcpu->arch.ivor[BOOKE_IRQPRIO_SYSCALL];
+	sregs->u.e.ivor_low[9] = vcpu->arch.ivor[BOOKE_IRQPRIO_AP_UNAVAIL];
+	sregs->u.e.ivor_low[10] = vcpu->arch.ivor[BOOKE_IRQPRIO_DECREMENTER];
+	sregs->u.e.ivor_low[11] = vcpu->arch.ivor[BOOKE_IRQPRIO_FIT];
+	sregs->u.e.ivor_low[12] = vcpu->arch.ivor[BOOKE_IRQPRIO_WATCHDOG];
+	sregs->u.e.ivor_low[13] = vcpu->arch.ivor[BOOKE_IRQPRIO_DTLB_MISS];
+	sregs->u.e.ivor_low[14] = vcpu->arch.ivor[BOOKE_IRQPRIO_ITLB_MISS];
+	sregs->u.e.ivor_low[15] = vcpu->arch.ivor[BOOKE_IRQPRIO_DEBUG];
+}
+
+int kvmppc_set_sregs_ivor(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs)
+{
+	if (!(sregs->u.e.features & KVM_SREGS_E_IVOR))
+		return 0;
+
+	vcpu->arch.ivor[BOOKE_IRQPRIO_CRITICAL] = sregs->u.e.ivor_low[0];
+	vcpu->arch.ivor[BOOKE_IRQPRIO_MACHINE_CHECK] = sregs->u.e.ivor_low[1];
+	vcpu->arch.ivor[BOOKE_IRQPRIO_DATA_STORAGE] = sregs->u.e.ivor_low[2];
+	vcpu->arch.ivor[BOOKE_IRQPRIO_INST_STORAGE] = sregs->u.e.ivor_low[3];
+	vcpu->arch.ivor[BOOKE_IRQPRIO_EXTERNAL] = sregs->u.e.ivor_low[4];
+	vcpu->arch.ivor[BOOKE_IRQPRIO_ALIGNMENT] = sregs->u.e.ivor_low[5];
+	vcpu->arch.ivor[BOOKE_IRQPRIO_PROGRAM] = sregs->u.e.ivor_low[6];
+	vcpu->arch.ivor[BOOKE_IRQPRIO_FP_UNAVAIL] = sregs->u.e.ivor_low[7];
+	vcpu->arch.ivor[BOOKE_IRQPRIO_SYSCALL] = sregs->u.e.ivor_low[8];
+	vcpu->arch.ivor[BOOKE_IRQPRIO_AP_UNAVAIL] = sregs->u.e.ivor_low[9];
+	vcpu->arch.ivor[BOOKE_IRQPRIO_DECREMENTER] = sregs->u.e.ivor_low[10];
+	vcpu->arch.ivor[BOOKE_IRQPRIO_FIT] = sregs->u.e.ivor_low[11];
+	vcpu->arch.ivor[BOOKE_IRQPRIO_WATCHDOG] = sregs->u.e.ivor_low[12];
+	vcpu->arch.ivor[BOOKE_IRQPRIO_DTLB_MISS] = sregs->u.e.ivor_low[13];
+	vcpu->arch.ivor[BOOKE_IRQPRIO_ITLB_MISS] = sregs->u.e.ivor_low[14];
+	vcpu->arch.ivor[BOOKE_IRQPRIO_DEBUG] = sregs->u.e.ivor_low[15];
+
+	return 0;
+}
+
 int kvm_arch_vcpu_ioctl_get_sregs(struct kvm_vcpu *vcpu,
                                   struct kvm_sregs *sregs)
 {
-	return -ENOTSUPP;
+	sregs->pvr = vcpu->arch.pvr;
+
+	get_sregs_base(vcpu, sregs);
+	get_sregs_arch206(vcpu, sregs);
+	kvmppc_core_get_sregs(vcpu, sregs);
+	return 0;
 }
 
 int kvm_arch_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu,
                                   struct kvm_sregs *sregs)
 {
-	return -ENOTSUPP;
+	int ret;
+
+	if (vcpu->arch.pvr != sregs->pvr)
+		return -EINVAL;
+
+	ret = set_sregs_base(vcpu, sregs);
+	if (ret < 0)
+		return ret;
+
+	ret = set_sregs_arch206(vcpu, sregs);
+	if (ret < 0)
+		return ret;
+
+	return kvmppc_core_set_sregs(vcpu, sregs);
 }
 
 int kvm_arch_vcpu_ioctl_get_fpu(struct kvm_vcpu *vcpu, struct kvm_fpu *fpu)
diff -druN linux-2.6.39-libre/arch/powerpc/kvm/booke_interrupts.S linux-3.0-rc7-libre/arch/powerpc/kvm/booke_interrupts.S
--- linux-2.6.39-libre/arch/powerpc/kvm/booke_interrupts.S	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/kvm/booke_interrupts.S	2011-07-11 19:51:52.000000000 -0400
@@ -380,7 +380,6 @@
 	 * because host interrupt handlers would get confused. */
 	lwz	r1, VCPU_GPR(r1)(r4)
 
-	/* XXX handle USPRG0 */
 	/* Host interrupt handlers may have clobbered these guest-readable
 	 * SPRGs, so we need to reload them here with the guest's values. */
 	lwz	r3, VCPU_SPRG4(r4)
diff -druN linux-2.6.39-libre/arch/powerpc/kvm/e500.c linux-3.0-rc7-libre/arch/powerpc/kvm/e500.c
--- linux-2.6.39-libre/arch/powerpc/kvm/e500.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/kvm/e500.c	2011-07-11 19:51:52.000000000 -0400
@@ -63,6 +63,7 @@
 
 	/* Registers init */
 	vcpu->arch.pvr = mfspr(SPRN_PVR);
+	vcpu_e500->svr = mfspr(SPRN_SVR);
 
 	/* Since booke kvm only support one core, update all vcpus' PIR to 0 */
 	vcpu->vcpu_id = 0;
@@ -96,6 +97,81 @@
 	return 0;
 }
 
+void kvmppc_core_get_sregs(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs)
+{
+	struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu);
+
+	sregs->u.e.features |= KVM_SREGS_E_ARCH206_MMU | KVM_SREGS_E_SPE |
+	                       KVM_SREGS_E_PM;
+	sregs->u.e.impl_id = KVM_SREGS_E_IMPL_FSL;
+
+	sregs->u.e.impl.fsl.features = 0;
+	sregs->u.e.impl.fsl.svr = vcpu_e500->svr;
+	sregs->u.e.impl.fsl.hid0 = vcpu_e500->hid0;
+	sregs->u.e.impl.fsl.mcar = vcpu_e500->mcar;
+
+	sregs->u.e.mas0 = vcpu_e500->mas0;
+	sregs->u.e.mas1 = vcpu_e500->mas1;
+	sregs->u.e.mas2 = vcpu_e500->mas2;
+	sregs->u.e.mas7_3 = ((u64)vcpu_e500->mas7 << 32) | vcpu_e500->mas3;
+	sregs->u.e.mas4 = vcpu_e500->mas4;
+	sregs->u.e.mas6 = vcpu_e500->mas6;
+
+	sregs->u.e.mmucfg = mfspr(SPRN_MMUCFG);
+	sregs->u.e.tlbcfg[0] = vcpu_e500->tlb0cfg;
+	sregs->u.e.tlbcfg[1] = vcpu_e500->tlb1cfg;
+	sregs->u.e.tlbcfg[2] = 0;
+	sregs->u.e.tlbcfg[3] = 0;
+
+	sregs->u.e.ivor_high[0] = vcpu->arch.ivor[BOOKE_IRQPRIO_SPE_UNAVAIL];
+	sregs->u.e.ivor_high[1] = vcpu->arch.ivor[BOOKE_IRQPRIO_SPE_FP_DATA];
+	sregs->u.e.ivor_high[2] = vcpu->arch.ivor[BOOKE_IRQPRIO_SPE_FP_ROUND];
+	sregs->u.e.ivor_high[3] =
+		vcpu->arch.ivor[BOOKE_IRQPRIO_PERFORMANCE_MONITOR];
+
+	kvmppc_get_sregs_ivor(vcpu, sregs);
+}
+
+int kvmppc_core_set_sregs(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs)
+{
+	struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu);
+
+	if (sregs->u.e.impl_id == KVM_SREGS_E_IMPL_FSL) {
+		vcpu_e500->svr = sregs->u.e.impl.fsl.svr;
+		vcpu_e500->hid0 = sregs->u.e.impl.fsl.hid0;
+		vcpu_e500->mcar = sregs->u.e.impl.fsl.mcar;
+	}
+
+	if (sregs->u.e.features & KVM_SREGS_E_ARCH206_MMU) {
+		vcpu_e500->mas0 = sregs->u.e.mas0;
+		vcpu_e500->mas1 = sregs->u.e.mas1;
+		vcpu_e500->mas2 = sregs->u.e.mas2;
+		vcpu_e500->mas7 = sregs->u.e.mas7_3 >> 32;
+		vcpu_e500->mas3 = (u32)sregs->u.e.mas7_3;
+		vcpu_e500->mas4 = sregs->u.e.mas4;
+		vcpu_e500->mas6 = sregs->u.e.mas6;
+	}
+
+	if (!(sregs->u.e.features & KVM_SREGS_E_IVOR))
+		return 0;
+
+	if (sregs->u.e.features & KVM_SREGS_E_SPE) {
+		vcpu->arch.ivor[BOOKE_IRQPRIO_SPE_UNAVAIL] =
+			sregs->u.e.ivor_high[0];
+		vcpu->arch.ivor[BOOKE_IRQPRIO_SPE_FP_DATA] =
+			sregs->u.e.ivor_high[1];
+		vcpu->arch.ivor[BOOKE_IRQPRIO_SPE_FP_ROUND] =
+			sregs->u.e.ivor_high[2];
+	}
+
+	if (sregs->u.e.features & KVM_SREGS_E_PM) {
+		vcpu->arch.ivor[BOOKE_IRQPRIO_PERFORMANCE_MONITOR] =
+			sregs->u.e.ivor_high[3];
+	}
+
+	return kvmppc_set_sregs_ivor(vcpu, sregs);
+}
+
 struct kvm_vcpu *kvmppc_core_vcpu_create(struct kvm *kvm, unsigned int id)
 {
 	struct kvmppc_vcpu_e500 *vcpu_e500;
diff -druN linux-2.6.39-libre/arch/powerpc/kvm/e500_emulate.c linux-3.0-rc7-libre/arch/powerpc/kvm/e500_emulate.c
--- linux-2.6.39-libre/arch/powerpc/kvm/e500_emulate.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/kvm/e500_emulate.c	2011-07-11 19:51:52.000000000 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2008 Freescale Semiconductor, Inc. All rights reserved.
+ * Copyright (C) 2008-2011 Freescale Semiconductor, Inc. All rights reserved.
  *
  * Author: Yu Liu, <yu.liu@freescale.com>
  *
@@ -78,8 +78,7 @@
 
 	switch (sprn) {
 	case SPRN_PID:
-		vcpu_e500->pid[0] = vcpu->arch.shadow_pid =
-			vcpu->arch.pid = spr_val;
+		kvmppc_set_pid(vcpu, spr_val);
 		break;
 	case SPRN_PID1:
 		vcpu_e500->pid[1] = spr_val; break;
@@ -175,6 +174,8 @@
 		kvmppc_set_gpr(vcpu, rt, vcpu_e500->hid0); break;
 	case SPRN_HID1:
 		kvmppc_set_gpr(vcpu, rt, vcpu_e500->hid1); break;
+	case SPRN_SVR:
+		kvmppc_set_gpr(vcpu, rt, vcpu_e500->svr); break;
 
 	case SPRN_MMUCSR0:
 		kvmppc_set_gpr(vcpu, rt, 0); break;
diff -druN linux-2.6.39-libre/arch/powerpc/kvm/e500_tlb.c linux-3.0-rc7-libre/arch/powerpc/kvm/e500_tlb.c
--- linux-2.6.39-libre/arch/powerpc/kvm/e500_tlb.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/kvm/e500_tlb.c	2011-07-11 19:51:52.000000000 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2008 Freescale Semiconductor, Inc. All rights reserved.
+ * Copyright (C) 2008-2011 Freescale Semiconductor, Inc. All rights reserved.
  *
  * Author: Yu Liu, yu.liu@freescale.com
  *
@@ -24,6 +24,7 @@
 #include "../mm/mmu_decl.h"
 #include "e500_tlb.h"
 #include "trace.h"
+#include "timing.h"
 
 #define to_htlb1_esel(esel) (tlb1_entry_num - (esel) - 1)
 
@@ -506,6 +507,7 @@
 		vcpu_e500->mas7 = 0;
 	}
 
+	kvmppc_set_exit_type(vcpu, EMULATED_TLBSX_EXITS);
 	return EMULATE_DONE;
 }
 
@@ -571,6 +573,7 @@
 		write_host_tlbe(vcpu_e500, stlbsel, sesel);
 	}
 
+	kvmppc_set_exit_type(vcpu, EMULATED_TLBWE_EXITS);
 	return EMULATE_DONE;
 }
 
@@ -672,6 +675,14 @@
 	return -1;
 }
 
+void kvmppc_set_pid(struct kvm_vcpu *vcpu, u32 pid)
+{
+	struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu);
+
+	vcpu_e500->pid[0] = vcpu->arch.shadow_pid =
+		vcpu->arch.pid = pid;
+}
+
 void kvmppc_e500_tlb_setup(struct kvmppc_vcpu_e500 *vcpu_e500)
 {
 	struct tlbe *tlbe;
diff -druN linux-2.6.39-libre/arch/powerpc/kvm/emulate.c linux-3.0-rc7-libre/arch/powerpc/kvm/emulate.c
--- linux-2.6.39-libre/arch/powerpc/kvm/emulate.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/kvm/emulate.c	2011-07-11 19:51:52.000000000 -0400
@@ -114,6 +114,12 @@
 	}
 }
 
+u32 kvmppc_get_dec(struct kvm_vcpu *vcpu, u64 tb)
+{
+	u64 jd = tb - vcpu->arch.dec_jiffies;
+	return vcpu->arch.dec - jd;
+}
+
 /* XXX to do:
  * lhax
  * lhaux
@@ -279,11 +285,8 @@
 
 			case SPRN_DEC:
 			{
-				u64 jd = get_tb() - vcpu->arch.dec_jiffies;
-				kvmppc_set_gpr(vcpu, rt, vcpu->arch.dec - jd);
-				pr_debug("mfDEC: %x - %llx = %lx\n",
-					 vcpu->arch.dec, jd,
-					 kvmppc_get_gpr(vcpu, rt));
+				kvmppc_set_gpr(vcpu, rt,
+					       kvmppc_get_dec(vcpu, get_tb()));
 				break;
 			}
 			default:
@@ -294,6 +297,7 @@
 				}
 				break;
 			}
+			kvmppc_set_exit_type(vcpu, EMULATED_MFSPR_EXITS);
 			break;
 
 		case OP_31_XOP_STHX:
@@ -363,6 +367,7 @@
 					printk("mtspr: unknown spr %x\n", sprn);
 				break;
 			}
+			kvmppc_set_exit_type(vcpu, EMULATED_MTSPR_EXITS);
 			break;
 
 		case OP_31_XOP_DCBI:
diff -druN linux-2.6.39-libre/arch/powerpc/kvm/powerpc.c linux-3.0-rc7-libre/arch/powerpc/kvm/powerpc.c
--- linux-2.6.39-libre/arch/powerpc/kvm/powerpc.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/kvm/powerpc.c	2011-07-11 19:51:52.000000000 -0400
@@ -175,7 +175,11 @@
 	int r;
 
 	switch (ext) {
+#ifdef CONFIG_BOOKE
+	case KVM_CAP_PPC_BOOKE_SREGS:
+#else
 	case KVM_CAP_PPC_SEGSTATE:
+#endif
 	case KVM_CAP_PPC_PAIRED_SINGLES:
 	case KVM_CAP_PPC_UNSET_IRQ:
 	case KVM_CAP_PPC_IRQ_LEVEL:
@@ -284,6 +288,10 @@
 	tasklet_init(&vcpu->arch.tasklet, kvmppc_decrementer_func, (ulong)vcpu);
 	vcpu->arch.dec_timer.function = kvmppc_decrementer_wakeup;
 
+#ifdef CONFIG_KVM_EXIT_TIMING
+	mutex_init(&vcpu->arch.exit_timing_lock);
+#endif
+
 	return 0;
 }
 
@@ -294,12 +302,25 @@
 
 void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
 {
+#ifdef CONFIG_BOOKE
+	/*
+	 * vrsave (formerly usprg0) isn't used by Linux, but may
+	 * be used by the guest.
+	 *
+	 * On non-booke this is associated with Altivec and
+	 * is handled by code in book3s.c.
+	 */
+	mtspr(SPRN_VRSAVE, vcpu->arch.vrsave);
+#endif
 	kvmppc_core_vcpu_load(vcpu, cpu);
 }
 
 void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu)
 {
 	kvmppc_core_vcpu_put(vcpu);
+#ifdef CONFIG_BOOKE
+	vcpu->arch.vrsave = mfspr(SPRN_VRSAVE);
+#endif
 }
 
 int kvm_arch_vcpu_ioctl_set_guest_debug(struct kvm_vcpu *vcpu,
diff -druN linux-2.6.39-libre/arch/powerpc/kvm/timing.c linux-3.0-rc7-libre/arch/powerpc/kvm/timing.c
--- linux-2.6.39-libre/arch/powerpc/kvm/timing.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/kvm/timing.c	2011-07-11 19:51:52.000000000 -0400
@@ -34,8 +34,8 @@
 {
 	int i;
 
-	/* pause guest execution to avoid concurrent updates */
-	mutex_lock(&vcpu->mutex);
+	/* Take a lock to avoid concurrent updates */
+	mutex_lock(&vcpu->arch.exit_timing_lock);
 
 	vcpu->arch.last_exit_type = 0xDEAD;
 	for (i = 0; i < __NUMBER_OF_KVM_EXIT_TYPES; i++) {
@@ -49,7 +49,7 @@
 	vcpu->arch.timing_exit.tv64 = 0;
 	vcpu->arch.timing_last_enter.tv64 = 0;
 
-	mutex_unlock(&vcpu->mutex);
+	mutex_unlock(&vcpu->arch.exit_timing_lock);
 }
 
 static void add_exit_timing(struct kvm_vcpu *vcpu, u64 duration, int type)
@@ -65,6 +65,8 @@
 		return;
 	}
 
+	mutex_lock(&vcpu->arch.exit_timing_lock);
+
 	vcpu->arch.timing_count_type[type]++;
 
 	/* sum */
@@ -93,6 +95,8 @@
 		vcpu->arch.timing_min_duration[type] = duration;
 	if (unlikely(duration > vcpu->arch.timing_max_duration[type]))
 		vcpu->arch.timing_max_duration[type] = duration;
+
+	mutex_unlock(&vcpu->arch.exit_timing_lock);
 }
 
 void kvmppc_update_timing_stats(struct kvm_vcpu *vcpu)
@@ -147,17 +151,30 @@
 {
 	struct kvm_vcpu *vcpu = m->private;
 	int i;
+	u64 min, max, sum, sum_quad;
 
 	seq_printf(m, "%s", "type	count	min	max	sum	sum_squared\n");
 
+
 	for (i = 0; i < __NUMBER_OF_KVM_EXIT_TYPES; i++) {
+
+		min = vcpu->arch.timing_min_duration[i];
+		do_div(min, tb_ticks_per_usec);
+		max = vcpu->arch.timing_max_duration[i];
+		do_div(max, tb_ticks_per_usec);
+		sum = vcpu->arch.timing_sum_duration[i];
+		do_div(sum, tb_ticks_per_usec);
+		sum_quad = vcpu->arch.timing_sum_quad_duration[i];
+		do_div(sum_quad, tb_ticks_per_usec);
+
 		seq_printf(m, "%12s	%10d	%10lld	%10lld	%20lld	%20lld\n",
 			kvm_exit_names[i],
 			vcpu->arch.timing_count_type[i],
-			vcpu->arch.timing_min_duration[i],
-			vcpu->arch.timing_max_duration[i],
-			vcpu->arch.timing_sum_duration[i],
-			vcpu->arch.timing_sum_quad_duration[i]);
+			min,
+			max,
+			sum,
+			sum_quad);
+
 	}
 	return 0;
 }
diff -druN linux-2.6.39-libre/arch/powerpc/lib/alloc.c linux-3.0-rc7-libre/arch/powerpc/lib/alloc.c
--- linux-2.6.39-libre/arch/powerpc/lib/alloc.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/lib/alloc.c	2011-07-11 19:51:52.000000000 -0400
@@ -6,14 +6,6 @@
 
 #include <asm/system.h>
 
-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;
diff -druN linux-2.6.39-libre/arch/powerpc/lib/copypage_64.S linux-3.0-rc7-libre/arch/powerpc/lib/copypage_64.S
--- linux-2.6.39-libre/arch/powerpc/lib/copypage_64.S	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/lib/copypage_64.S	2011-07-11 19:51:52.000000000 -0400
@@ -6,6 +6,7 @@
  * as published by the Free Software Foundation; either version
  * 2 of the License, or (at your option) any later version.
  */
+#include <asm/page.h>
 #include <asm/processor.h>
 #include <asm/ppc_asm.h>
 #include <asm/asm-offsets.h>
@@ -15,9 +16,9 @@
         .tc             ppc64_caches[TC],ppc64_caches
         .section        ".text"
 
-
-_GLOBAL(copy_4K_page)
-	li	r5,4096		/* 4K page size */
+_GLOBAL(copy_page)
+	lis	r5,PAGE_SIZE@h
+	ori	r5,r5,PAGE_SIZE@l
 BEGIN_FTR_SECTION
 	ld      r10,PPC64_CACHES@toc(r2)
 	lwz	r11,DCACHEL1LOGLINESIZE(r10)	/* log2 of cache line size */
diff -druN linux-2.6.39-libre/arch/powerpc/lib/devres.c linux-3.0-rc7-libre/arch/powerpc/lib/devres.c
--- linux-2.6.39-libre/arch/powerpc/lib/devres.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/lib/devres.c	2011-07-11 19:51:52.000000000 -0400
@@ -9,11 +9,11 @@
 
 #include <linux/device.h>	/* devres_*(), devm_ioremap_release() */
 #include <linux/gfp.h>
-#include <linux/io.h>		/* ioremap_flags() */
+#include <linux/io.h>		/* ioremap_prot() */
 #include <linux/module.h>	/* EXPORT_SYMBOL() */
 
 /**
- * devm_ioremap_prot - Managed ioremap_flags()
+ * devm_ioremap_prot - Managed ioremap_prot()
  * @dev: Generic device to remap IO address for
  * @offset: BUS offset to map
  * @size: Size of map
@@ -31,7 +31,7 @@
 	if (!ptr)
 		return NULL;
 
-	addr = ioremap_flags(offset, size, flags);
+	addr = ioremap_prot(offset, size, flags);
 	if (addr) {
 		*ptr = addr;
 		devres_add(dev, ptr);
diff -druN linux-2.6.39-libre/arch/powerpc/lib/sstep.c linux-3.0-rc7-libre/arch/powerpc/lib/sstep.c
--- linux-2.6.39-libre/arch/powerpc/lib/sstep.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/lib/sstep.c	2011-07-11 19:51:52.000000000 -0400
@@ -11,6 +11,7 @@
 #include <linux/kernel.h>
 #include <linux/kprobes.h>
 #include <linux/ptrace.h>
+#include <linux/prefetch.h>
 #include <asm/sstep.h>
 #include <asm/processor.h>
 #include <asm/uaccess.h>
@@ -45,6 +46,18 @@
 #endif
 
 /*
+ * Emulate the truncation of 64 bit values in 32-bit mode.
+ */
+static unsigned long truncate_if_32bit(unsigned long msr, unsigned long val)
+{
+#ifdef __powerpc64__
+	if ((msr & MSR_64BIT) == 0)
+		val &= 0xffffffffUL;
+#endif
+	return val;
+}
+
+/*
  * Determine whether a conditional branch instruction would branch.
  */
 static int __kprobes branch_taken(unsigned int instr, struct pt_regs *regs)
@@ -90,11 +103,8 @@
 		if (instr & 0x04000000)		/* update forms */
 			regs->gpr[ra] = ea;
 	}
-#ifdef __powerpc64__
-	if (!(regs->msr & MSR_SF))
-		ea &= 0xffffffffUL;
-#endif
-	return ea;
+
+	return truncate_if_32bit(regs->msr, ea);
 }
 
 #ifdef __powerpc64__
@@ -113,9 +123,8 @@
 		if ((instr & 3) == 1)		/* update forms */
 			regs->gpr[ra] = ea;
 	}
-	if (!(regs->msr & MSR_SF))
-		ea &= 0xffffffffUL;
-	return ea;
+
+	return truncate_if_32bit(regs->msr, ea);
 }
 #endif /* __powerpc64 */
 
@@ -136,11 +145,8 @@
 		if (do_update)		/* update forms */
 			regs->gpr[ra] = ea;
 	}
-#ifdef __powerpc64__
-	if (!(regs->msr & MSR_SF))
-		ea &= 0xffffffffUL;
-#endif
-	return ea;
+
+	return truncate_if_32bit(regs->msr, ea);
 }
 
 /*
@@ -466,7 +472,7 @@
 
 	regs->ccr = (regs->ccr & 0x0fffffff) | ((regs->xer >> 3) & 0x10000000);
 #ifdef __powerpc64__
-	if (!(regs->msr & MSR_SF))
+	if (!(regs->msr & MSR_64BIT))
 		val = (int) val;
 #endif
 	if (val < 0)
@@ -487,7 +493,7 @@
 		++val;
 	regs->gpr[rd] = val;
 #ifdef __powerpc64__
-	if (!(regs->msr & MSR_SF)) {
+	if (!(regs->msr & MSR_64BIT)) {
 		val = (unsigned int) val;
 		val1 = (unsigned int) val1;
 	}
@@ -570,8 +576,7 @@
 		if ((instr & 2) == 0)
 			imm += regs->nip;
 		regs->nip += 4;
-		if ((regs->msr & MSR_SF) == 0)
-			regs->nip &= 0xffffffffUL;
+		regs->nip = truncate_if_32bit(regs->msr, regs->nip);
 		if (instr & 1)
 			regs->link = regs->nip;
 		if (branch_taken(instr, regs))
@@ -604,13 +609,9 @@
 			imm -= 0x04000000;
 		if ((instr & 2) == 0)
 			imm += regs->nip;
-		if (instr & 1) {
-			regs->link = regs->nip + 4;
-			if ((regs->msr & MSR_SF) == 0)
-				regs->link &= 0xffffffffUL;
-		}
-		if ((regs->msr & MSR_SF) == 0)
-			imm &= 0xffffffffUL;
+		if (instr & 1)
+			regs->link = truncate_if_32bit(regs->msr, regs->nip + 4);
+		imm = truncate_if_32bit(regs->msr, imm);
 		regs->nip = imm;
 		return 1;
 	case 19:
@@ -618,11 +619,8 @@
 		case 16:	/* bclr */
 		case 528:	/* bcctr */
 			imm = (instr & 0x400)? regs->ctr: regs->link;
-			regs->nip += 4;
-			if ((regs->msr & MSR_SF) == 0) {
-				regs->nip &= 0xffffffffUL;
-				imm &= 0xffffffffUL;
-			}
+			regs->nip = truncate_if_32bit(regs->msr, regs->nip + 4);
+			imm = truncate_if_32bit(regs->msr, imm);
 			if (instr & 1)
 				regs->link = regs->nip;
 			if (branch_taken(instr, regs))
@@ -1616,11 +1614,7 @@
 		return 0;	/* invoke DSI if -EFAULT? */
 	}
  instr_done:
-	regs->nip += 4;
-#ifdef __powerpc64__
-	if ((regs->msr & MSR_SF) == 0)
-		regs->nip &= 0xffffffffUL;
-#endif
+	regs->nip = truncate_if_32bit(regs->msr, regs->nip + 4);
 	return 1;
 
  logical_done:
diff -druN linux-2.6.39-libre/arch/powerpc/mm/fault.c linux-3.0-rc7-libre/arch/powerpc/mm/fault.c
--- linux-2.6.39-libre/arch/powerpc/mm/fault.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/mm/fault.c	2011-07-11 19:51:52.000000000 -0400
@@ -31,6 +31,7 @@
 #include <linux/kdebug.h>
 #include <linux/perf_event.h>
 #include <linux/magic.h>
+#include <linux/ratelimit.h>
 
 #include <asm/firmware.h>
 #include <asm/page.h>
@@ -346,11 +347,10 @@
 		return 0;
 	}
 
-	if (is_exec && (error_code & DSISR_PROTFAULT)
-	    && printk_ratelimit())
-		printk(KERN_CRIT "kernel tried to execute NX-protected"
-		       " page (%lx) - exploit attempt? (uid: %d)\n",
-		       address, current_uid());
+	if (is_exec && (error_code & DSISR_PROTFAULT))
+		printk_ratelimited(KERN_CRIT "kernel tried to execute NX-protected"
+				   " page (%lx) - exploit attempt? (uid: %d)\n",
+				   address, current_uid());
 
 	return SIGSEGV;
 
diff -druN linux-2.6.39-libre/arch/powerpc/mm/hash_low_64.S linux-3.0-rc7-libre/arch/powerpc/mm/hash_low_64.S
--- linux-2.6.39-libre/arch/powerpc/mm/hash_low_64.S	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/mm/hash_low_64.S	2011-07-11 19:51:52.000000000 -0400
@@ -118,7 +118,7 @@
 BEGIN_FTR_SECTION
 	cmpdi	r9,0			/* check segment size */
 	bne	3f
-END_FTR_SECTION_IFSET(CPU_FTR_1T_SEGMENT)
+END_MMU_FTR_SECTION_IFSET(MMU_FTR_1T_SEGMENT)
 	/* Calc va and put it in r29 */
 	rldicr	r29,r5,28,63-28
 	rldicl	r3,r3,0,36
@@ -401,7 +401,7 @@
 BEGIN_FTR_SECTION
 	cmpdi	r9,0			/* check segment size */
 	bne	3f
-END_FTR_SECTION_IFSET(CPU_FTR_1T_SEGMENT)
+END_MMU_FTR_SECTION_IFSET(MMU_FTR_1T_SEGMENT)
 	/* Calc va and put it in r29 */
 	rldicr	r29,r5,28,63-28		/* r29 = (vsid << 28) */
 	rldicl	r3,r3,0,36		/* r3 = (ea & 0x0fffffff) */
@@ -715,7 +715,7 @@
 	andi.	r0,r31,_PAGE_NO_CACHE
 	/* If so, bail out and refault as a 4k page */
 	bne-	ht64_bail_ok
-END_FTR_SECTION_IFCLR(CPU_FTR_CI_LARGE_PAGE)
+END_MMU_FTR_SECTION_IFCLR(MMU_FTR_CI_LARGE_PAGE)
 	/* Prepare new PTE value (turn access RW into DIRTY, then
 	 * add BUSY and ACCESSED)
 	 */
@@ -736,7 +736,7 @@
 BEGIN_FTR_SECTION
 	cmpdi	r9,0			/* check segment size */
 	bne	3f
-END_FTR_SECTION_IFSET(CPU_FTR_1T_SEGMENT)
+END_MMU_FTR_SECTION_IFSET(MMU_FTR_1T_SEGMENT)
 	/* Calc va and put it in r29 */
 	rldicr	r29,r5,28,63-28
 	rldicl	r3,r3,0,36
diff -druN linux-2.6.39-libre/arch/powerpc/mm/hash_native_64.c linux-3.0-rc7-libre/arch/powerpc/mm/hash_native_64.c
--- linux-2.6.39-libre/arch/powerpc/mm/hash_native_64.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/mm/hash_native_64.c	2011-07-11 19:51:52.000000000 -0400
@@ -50,9 +50,8 @@
 	case MMU_PAGE_4K:
 		va &= ~0xffful;
 		va |= ssize << 8;
-		asm volatile(ASM_MMU_FTR_IFCLR("tlbie %0,0", PPC_TLBIE(%1,%0),
-					       %2)
-			     : : "r" (va), "r"(0), "i" (MMU_FTR_TLBIE_206)
+		asm volatile(ASM_FTR_IFCLR("tlbie %0,0", PPC_TLBIE(%1,%0), %2)
+			     : : "r" (va), "r"(0), "i" (CPU_FTR_HVMODE_206)
 			     : "memory");
 		break;
 	default:
@@ -61,9 +60,8 @@
 		va |= penc << 12;
 		va |= ssize << 8;
 		va |= 1; /* L */
-		asm volatile(ASM_MMU_FTR_IFCLR("tlbie %0,1", PPC_TLBIE(%1,%0),
-					       %2)
-			     : : "r" (va), "r"(0), "i" (MMU_FTR_TLBIE_206)
+		asm volatile(ASM_FTR_IFCLR("tlbie %0,1", PPC_TLBIE(%1,%0), %2)
+			     : : "r" (va), "r"(0), "i" (CPU_FTR_HVMODE_206)
 			     : "memory");
 		break;
 	}
@@ -98,8 +96,8 @@
 
 static inline void tlbie(unsigned long va, int psize, int ssize, int local)
 {
-	unsigned int use_local = local && cpu_has_feature(CPU_FTR_TLBIEL);
-	int lock_tlbie = !cpu_has_feature(CPU_FTR_LOCKLESS_TLBIE);
+	unsigned int use_local = local && mmu_has_feature(MMU_FTR_TLBIEL);
+	int lock_tlbie = !mmu_has_feature(MMU_FTR_LOCKLESS_TLBIE);
 
 	if (use_local)
 		use_local = mmu_psize_defs[psize].tlbiel;
@@ -503,7 +501,7 @@
 		} pte_iterate_hashed_end();
 	}
 
-	if (cpu_has_feature(CPU_FTR_TLBIEL) &&
+	if (mmu_has_feature(MMU_FTR_TLBIEL) &&
 	    mmu_psize_defs[psize].tlbiel && local) {
 		asm volatile("ptesync":::"memory");
 		for (i = 0; i < number; i++) {
@@ -517,7 +515,7 @@
 		}
 		asm volatile("ptesync":::"memory");
 	} else {
-		int lock_tlbie = !cpu_has_feature(CPU_FTR_LOCKLESS_TLBIE);
+		int lock_tlbie = !mmu_has_feature(MMU_FTR_LOCKLESS_TLBIE);
 
 		if (lock_tlbie)
 			raw_spin_lock(&native_tlbie_lock);
diff -druN linux-2.6.39-libre/arch/powerpc/mm/hash_utils_64.c linux-3.0-rc7-libre/arch/powerpc/mm/hash_utils_64.c
--- linux-2.6.39-libre/arch/powerpc/mm/hash_utils_64.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/mm/hash_utils_64.c	2011-07-11 19:51:52.000000000 -0400
@@ -53,6 +53,7 @@
 #include <asm/sections.h>
 #include <asm/spu.h>
 #include <asm/udbg.h>
+#include <asm/code-patching.h>
 
 #ifdef DEBUG
 #define DBG(fmt...) udbg_printf(fmt)
@@ -258,11 +259,11 @@
 	for (; size >= 4; size -= 4, ++prop) {
 		if (prop[0] == 40) {
 			DBG("1T segment support detected\n");
-			cur_cpu_spec->cpu_features |= CPU_FTR_1T_SEGMENT;
+			cur_cpu_spec->mmu_features |= MMU_FTR_1T_SEGMENT;
 			return 1;
 		}
 	}
-	cur_cpu_spec->cpu_features &= ~CPU_FTR_NO_SLBIE_B;
+	cur_cpu_spec->mmu_features &= ~MMU_FTR_NO_SLBIE_B;
 	return 0;
 }
 
@@ -288,7 +289,7 @@
 	if (prop != NULL) {
 		DBG("Page sizes from device-tree:\n");
 		size /= 4;
-		cur_cpu_spec->cpu_features &= ~(CPU_FTR_16M_PAGE);
+		cur_cpu_spec->mmu_features &= ~(MMU_FTR_16M_PAGE);
 		while(size > 0) {
 			unsigned int shift = prop[0];
 			unsigned int slbenc = prop[1];
@@ -316,7 +317,7 @@
 				break;
 			case 0x18:
 				idx = MMU_PAGE_16M;
-				cur_cpu_spec->cpu_features |= CPU_FTR_16M_PAGE;
+				cur_cpu_spec->mmu_features |= MMU_FTR_16M_PAGE;
 				break;
 			case 0x22:
 				idx = MMU_PAGE_16G;
@@ -411,7 +412,7 @@
 	 * Not in the device-tree, let's fallback on known size
 	 * list for 16M capable GP & GR
 	 */
-	if (cpu_has_feature(CPU_FTR_16M_PAGE))
+	if (mmu_has_feature(MMU_FTR_16M_PAGE))
 		memcpy(mmu_psize_defs, mmu_psize_defaults_gp,
 		       sizeof(mmu_psize_defaults_gp));
  found:
@@ -441,7 +442,7 @@
 		mmu_vmalloc_psize = MMU_PAGE_64K;
 		if (mmu_linear_psize == MMU_PAGE_4K)
 			mmu_linear_psize = MMU_PAGE_64K;
-		if (cpu_has_feature(CPU_FTR_CI_LARGE_PAGE)) {
+		if (mmu_has_feature(MMU_FTR_CI_LARGE_PAGE)) {
 			/*
 			 * Don't use 64k pages for ioremap on pSeries, since
 			 * that would stop us accessing the HEA ethernet.
@@ -547,15 +548,7 @@
 }
 #endif /* CONFIG_MEMORY_HOTPLUG */
 
-static inline void make_bl(unsigned int *insn_addr, void *func)
-{
-	unsigned long funcp = *((unsigned long *)func);
-	int offset = funcp - (unsigned long)insn_addr;
-
-	*insn_addr = (unsigned int)(0x48000001 | (offset & 0x03fffffc));
-	flush_icache_range((unsigned long)insn_addr, 4+
-			   (unsigned long)insn_addr);
-}
+#define FUNCTION_TEXT(A)	((*(unsigned long *)(A)))
 
 static void __init htab_finish_init(void)
 {
@@ -570,16 +563,33 @@
 	extern unsigned int *ht64_call_hpte_remove;
 	extern unsigned int *ht64_call_hpte_updatepp;
 
-	make_bl(ht64_call_hpte_insert1, ppc_md.hpte_insert);
-	make_bl(ht64_call_hpte_insert2, ppc_md.hpte_insert);
-	make_bl(ht64_call_hpte_remove, ppc_md.hpte_remove);
-	make_bl(ht64_call_hpte_updatepp, ppc_md.hpte_updatepp);
+	patch_branch(ht64_call_hpte_insert1,
+		FUNCTION_TEXT(ppc_md.hpte_insert),
+		BRANCH_SET_LINK);
+	patch_branch(ht64_call_hpte_insert2,
+		FUNCTION_TEXT(ppc_md.hpte_insert),
+		BRANCH_SET_LINK);
+	patch_branch(ht64_call_hpte_remove,
+		FUNCTION_TEXT(ppc_md.hpte_remove),
+		BRANCH_SET_LINK);
+	patch_branch(ht64_call_hpte_updatepp,
+		FUNCTION_TEXT(ppc_md.hpte_updatepp),
+		BRANCH_SET_LINK);
+
 #endif /* CONFIG_PPC_HAS_HASH_64K */
 
-	make_bl(htab_call_hpte_insert1, ppc_md.hpte_insert);
-	make_bl(htab_call_hpte_insert2, ppc_md.hpte_insert);
-	make_bl(htab_call_hpte_remove, ppc_md.hpte_remove);
-	make_bl(htab_call_hpte_updatepp, ppc_md.hpte_updatepp);
+	patch_branch(htab_call_hpte_insert1,
+		FUNCTION_TEXT(ppc_md.hpte_insert),
+		BRANCH_SET_LINK);
+	patch_branch(htab_call_hpte_insert2,
+		FUNCTION_TEXT(ppc_md.hpte_insert),
+		BRANCH_SET_LINK);
+	patch_branch(htab_call_hpte_remove,
+		FUNCTION_TEXT(ppc_md.hpte_remove),
+		BRANCH_SET_LINK);
+	patch_branch(htab_call_hpte_updatepp,
+		FUNCTION_TEXT(ppc_md.hpte_updatepp),
+		BRANCH_SET_LINK);
 }
 
 static void __init htab_initialize(void)
@@ -598,7 +608,7 @@
 	/* Initialize page sizes */
 	htab_init_page_sizes();
 
-	if (cpu_has_feature(CPU_FTR_1T_SEGMENT)) {
+	if (mmu_has_feature(MMU_FTR_1T_SEGMENT)) {
 		mmu_kernel_ssize = MMU_SEGSIZE_1T;
 		mmu_highuser_ssize = MMU_SEGSIZE_1T;
 		printk(KERN_INFO "Using 1TB segments\n");
@@ -739,7 +749,7 @@
 
 	/* Initialize stab / SLB management except on iSeries
 	 */
-	if (cpu_has_feature(CPU_FTR_SLB))
+	if (mmu_has_feature(MMU_FTR_SLB))
 		slb_initialize();
 	else if (!firmware_has_feature(FW_FEATURE_ISERIES))
 		stab_initialize(get_paca()->stab_real);
@@ -756,7 +766,7 @@
 	 * in real mode on pSeries and we want a virtual address on
 	 * iSeries anyway
 	 */
-	if (cpu_has_feature(CPU_FTR_SLB))
+	if (mmu_has_feature(MMU_FTR_SLB))
 		slb_initialize();
 	else
 		stab_initialize(get_paca()->stab_addr);
diff -druN linux-2.6.39-libre/arch/powerpc/mm/hugetlbpage.c linux-3.0-rc7-libre/arch/powerpc/mm/hugetlbpage.c
--- linux-2.6.39-libre/arch/powerpc/mm/hugetlbpage.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/mm/hugetlbpage.c	2011-07-11 19:51:52.000000000 -0400
@@ -529,7 +529,7 @@
 {
 	int psize;
 
-	if (!cpu_has_feature(CPU_FTR_16M_PAGE))
+	if (!mmu_has_feature(MMU_FTR_16M_PAGE))
 		return -ENODEV;
 
 	for (psize = 0; psize < MMU_PAGE_COUNT; ++psize) {
diff -druN linux-2.6.39-libre/arch/powerpc/mm/init_32.c linux-3.0-rc7-libre/arch/powerpc/mm/init_32.c
--- linux-2.6.39-libre/arch/powerpc/mm/init_32.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/mm/init_32.c	2011-07-11 19:51:52.000000000 -0400
@@ -223,21 +223,6 @@
 #undef FREESEC
 }
 
-#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++;
-	}
-}
-#endif
-
-
 #ifdef CONFIG_8xx /* No 8xx specific .c file to put that in ... */
 void setup_initial_memory_limit(phys_addr_t first_memblock_base,
 				phys_addr_t first_memblock_size)
diff -druN linux-2.6.39-libre/arch/powerpc/mm/init_64.c linux-3.0-rc7-libre/arch/powerpc/mm/init_64.c
--- linux-2.6.39-libre/arch/powerpc/mm/init_64.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/mm/init_64.c	2011-07-11 19:51:52.000000000 -0400
@@ -99,20 +99,6 @@
 		((unsigned long)__init_end - (unsigned long)__init_begin) >> 10);
 }
 
-#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++;
-	}
-}
-#endif
-
 static void pgd_ctor(void *addr)
 {
 	memset(addr, 0, PGD_TABLE_SIZE);
diff -druN linux-2.6.39-libre/arch/powerpc/mm/mem.c linux-3.0-rc7-libre/arch/powerpc/mm/mem.c
--- linux-2.6.39-libre/arch/powerpc/mm/mem.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/mm/mem.c	2011-07-11 19:51:52.000000000 -0400
@@ -382,6 +382,25 @@
 	mem_init_done = 1;
 }
 
+#ifdef CONFIG_BLK_DEV_INITRD
+void __init free_initrd_mem(unsigned long start, unsigned long end)
+{
+	if (start >= end)
+		return;
+
+	start = _ALIGN_DOWN(start, PAGE_SIZE);
+	end = _ALIGN_UP(end, PAGE_SIZE);
+	pr_info("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++;
+	}
+}
+#endif
+
 /*
  * This is called when a page has been modified by the kernel.
  * It just marks the page as not i-cache clean.  We do the i-cache
diff -druN linux-2.6.39-libre/arch/powerpc/mm/mmu_context_hash64.c linux-3.0-rc7-libre/arch/powerpc/mm/mmu_context_hash64.c
--- linux-2.6.39-libre/arch/powerpc/mm/mmu_context_hash64.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/mm/mmu_context_hash64.c	2011-07-11 19:51:52.000000000 -0400
@@ -20,9 +20,205 @@
 #include <linux/idr.h>
 #include <linux/module.h>
 #include <linux/gfp.h>
+#include <linux/slab.h>
 
 #include <asm/mmu_context.h>
 
+#ifdef CONFIG_PPC_ICSWX
+/*
+ * The processor and its L2 cache cause the icswx instruction to
+ * generate a COP_REQ transaction on PowerBus. The transaction has
+ * no address, and the processor does not perform an MMU access
+ * to authenticate the transaction. The command portion of the
+ * PowerBus COP_REQ transaction includes the LPAR_ID (LPID) and
+ * the coprocessor Process ID (PID), which the coprocessor compares
+ * to the authorized LPID and PID held in the coprocessor, to determine
+ * if the process is authorized to generate the transaction.
+ * The data of the COP_REQ transaction is 128-byte or less and is
+ * placed in cacheable memory on a 128-byte cache line boundary.
+ *
+ * The task to use a coprocessor should use use_cop() to allocate
+ * a coprocessor PID before executing icswx instruction. use_cop()
+ * also enables the coprocessor context switching. Drop_cop() is
+ * used to free the coprocessor PID.
+ *
+ * Example:
+ * Host Fabric Interface (HFI) is a PowerPC network coprocessor.
+ * Each HFI have multiple windows. Each HFI window serves as a
+ * network device sending to and receiving from HFI network.
+ * HFI immediate send function uses icswx instruction. The immediate
+ * send function allows small (single cache-line) packets be sent
+ * without using the regular HFI send FIFO and doorbell, which are
+ * much slower than immediate send.
+ *
+ * For each task intending to use HFI immediate send, the HFI driver
+ * calls use_cop() to obtain a coprocessor PID for the task.
+ * The HFI driver then allocate a free HFI window and save the
+ * coprocessor PID to the HFI window to allow the task to use the
+ * HFI window.
+ *
+ * The HFI driver repeatedly creates immediate send packets and
+ * issues icswx instruction to send data through the HFI window.
+ * The HFI compares the coprocessor PID in the CPU PID register
+ * to the PID held in the HFI window to determine if the transaction
+ * is allowed.
+ *
+ * When the task to release the HFI window, the HFI driver calls
+ * drop_cop() to release the coprocessor PID.
+ */
+
+#define COP_PID_NONE 0
+#define COP_PID_MIN (COP_PID_NONE + 1)
+#define COP_PID_MAX (0xFFFF)
+
+static DEFINE_SPINLOCK(mmu_context_acop_lock);
+static DEFINE_IDA(cop_ida);
+
+void switch_cop(struct mm_struct *next)
+{
+	mtspr(SPRN_PID, next->context.cop_pid);
+	mtspr(SPRN_ACOP, next->context.acop);
+}
+
+static int new_cop_pid(struct ida *ida, int min_id, int max_id,
+		       spinlock_t *lock)
+{
+	int index;
+	int err;
+
+again:
+	if (!ida_pre_get(ida, GFP_KERNEL))
+		return -ENOMEM;
+
+	spin_lock(lock);
+	err = ida_get_new_above(ida, min_id, &index);
+	spin_unlock(lock);
+
+	if (err == -EAGAIN)
+		goto again;
+	else if (err)
+		return err;
+
+	if (index > max_id) {
+		spin_lock(lock);
+		ida_remove(ida, index);
+		spin_unlock(lock);
+		return -ENOMEM;
+	}
+
+	return index;
+}
+
+static void sync_cop(void *arg)
+{
+	struct mm_struct *mm = arg;
+
+	if (mm == current->active_mm)
+		switch_cop(current->active_mm);
+}
+
+/**
+ * Start using a coprocessor.
+ * @acop: mask of coprocessor to be used.
+ * @mm: The mm the coprocessor to associate with. Most likely current mm.
+ *
+ * Return a positive PID if successful. Negative errno otherwise.
+ * The returned PID will be fed to the coprocessor to determine if an
+ * icswx transaction is authenticated.
+ */
+int use_cop(unsigned long acop, struct mm_struct *mm)
+{
+	int ret;
+
+	if (!cpu_has_feature(CPU_FTR_ICSWX))
+		return -ENODEV;
+
+	if (!mm || !acop)
+		return -EINVAL;
+
+	/* We need to make sure mm_users doesn't change */
+	down_read(&mm->mmap_sem);
+	spin_lock(mm->context.cop_lockp);
+
+	if (mm->context.cop_pid == COP_PID_NONE) {
+		ret = new_cop_pid(&cop_ida, COP_PID_MIN, COP_PID_MAX,
+				  &mmu_context_acop_lock);
+		if (ret < 0)
+			goto out;
+
+		mm->context.cop_pid = ret;
+	}
+	mm->context.acop |= acop;
+
+	sync_cop(mm);
+
+	/*
+	 * If this is a threaded process then there might be other threads
+	 * running. We need to send an IPI to force them to pick up any
+	 * change in PID and ACOP.
+	 */
+	if (atomic_read(&mm->mm_users) > 1)
+		smp_call_function(sync_cop, mm, 1);
+
+	ret = mm->context.cop_pid;
+
+out:
+	spin_unlock(mm->context.cop_lockp);
+	up_read(&mm->mmap_sem);
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(use_cop);
+
+/**
+ * Stop using a coprocessor.
+ * @acop: mask of coprocessor to be stopped.
+ * @mm: The mm the coprocessor associated with.
+ */
+void drop_cop(unsigned long acop, struct mm_struct *mm)
+{
+	int free_pid = COP_PID_NONE;
+
+	if (!cpu_has_feature(CPU_FTR_ICSWX))
+		return;
+
+	if (WARN_ON_ONCE(!mm))
+		return;
+
+	/* We need to make sure mm_users doesn't change */
+	down_read(&mm->mmap_sem);
+	spin_lock(mm->context.cop_lockp);
+
+	mm->context.acop &= ~acop;
+
+	if ((!mm->context.acop) && (mm->context.cop_pid != COP_PID_NONE)) {
+		free_pid = mm->context.cop_pid;
+		mm->context.cop_pid = COP_PID_NONE;
+	}
+
+	sync_cop(mm);
+
+	/*
+	 * If this is a threaded process then there might be other threads
+	 * running. We need to send an IPI to force them to pick up any
+	 * change in PID and ACOP.
+	 */
+	if (atomic_read(&mm->mm_users) > 1)
+		smp_call_function(sync_cop, mm, 1);
+
+	if (free_pid != COP_PID_NONE) {
+		spin_lock(&mmu_context_acop_lock);
+		ida_remove(&cop_ida, free_pid);
+		spin_unlock(&mmu_context_acop_lock);
+	}
+
+	spin_unlock(mm->context.cop_lockp);
+	up_read(&mm->mmap_sem);
+}
+EXPORT_SYMBOL_GPL(drop_cop);
+
+#endif /* CONFIG_PPC_ICSWX */
+
 static DEFINE_SPINLOCK(mmu_context_lock);
 static DEFINE_IDA(mmu_context_ida);
 
@@ -31,7 +227,6 @@
  * Each segment contains 2^28 bytes.  Each context maps 2^44 bytes,
  * so we can support 2^19-1 contexts (19 == 35 + 28 - 44).
  */
-#define NO_CONTEXT	0
 #define MAX_CONTEXT	((1UL << 19) - 1)
 
 int __init_new_context(void)
@@ -79,6 +274,16 @@
 		slice_set_user_psize(mm, mmu_virtual_psize);
 	subpage_prot_init_new_context(mm);
 	mm->context.id = index;
+#ifdef CONFIG_PPC_ICSWX
+	mm->context.cop_lockp = kmalloc(sizeof(spinlock_t), GFP_KERNEL);
+	if (!mm->context.cop_lockp) {
+		__destroy_context(index);
+		subpage_prot_free(mm);
+		mm->context.id = MMU_NO_CONTEXT;
+		return -ENOMEM;
+	}
+	spin_lock_init(mm->context.cop_lockp);
+#endif /* CONFIG_PPC_ICSWX */
 
 	return 0;
 }
@@ -93,7 +298,12 @@
 
 void destroy_context(struct mm_struct *mm)
 {
+#ifdef CONFIG_PPC_ICSWX
+	drop_cop(mm->context.acop, mm);
+	kfree(mm->context.cop_lockp);
+	mm->context.cop_lockp = NULL;
+#endif /* CONFIG_PPC_ICSWX */
 	__destroy_context(mm->context.id);
 	subpage_prot_free(mm);
-	mm->context.id = NO_CONTEXT;
+	mm->context.id = MMU_NO_CONTEXT;
 }
diff -druN linux-2.6.39-libre/arch/powerpc/mm/mmu_context_nohash.c linux-3.0-rc7-libre/arch/powerpc/mm/mmu_context_nohash.c
--- linux-2.6.39-libre/arch/powerpc/mm/mmu_context_nohash.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/mm/mmu_context_nohash.c	2011-07-11 19:51:52.000000000 -0400
@@ -338,12 +338,14 @@
 		return NOTIFY_OK;
 
 	switch (action) {
-	case CPU_ONLINE:
-	case CPU_ONLINE_FROZEN:
+	case CPU_UP_PREPARE:
+	case CPU_UP_PREPARE_FROZEN:
 		pr_devel("MMU: Allocating stale context map for CPU %d\n", cpu);
 		stale_map[cpu] = kzalloc(CTX_MAP_SIZE, GFP_KERNEL);
 		break;
 #ifdef CONFIG_HOTPLUG_CPU
+	case CPU_UP_CANCELED:
+	case CPU_UP_CANCELED_FROZEN:
 	case CPU_DEAD:
 	case CPU_DEAD_FROZEN:
 		pr_devel("MMU: Freeing stale context map for CPU %d\n", cpu);
@@ -407,7 +409,17 @@
 	} else if (mmu_has_feature(MMU_FTR_TYPE_47x)) {
 		first_context = 1;
 		last_context = 65535;
-	} else {
+	} else
+#ifdef CONFIG_PPC_BOOK3E_MMU
+	if (mmu_has_feature(MMU_FTR_TYPE_3E)) {
+		u32 mmucfg = mfspr(SPRN_MMUCFG);
+		u32 pid_bits = (mmucfg & MMUCFG_PIDSIZE_MASK)
+				>> MMUCFG_PIDSIZE_SHIFT;
+		first_context = 1;
+		last_context = (1UL << (pid_bits + 1)) - 1;
+	} else
+#endif
+	{
 		first_context = 1;
 		last_context = 255;
 	}
diff -druN linux-2.6.39-libre/arch/powerpc/mm/numa.c linux-3.0-rc7-libre/arch/powerpc/mm/numa.c
--- linux-2.6.39-libre/arch/powerpc/mm/numa.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/mm/numa.c	2011-07-11 19:51:52.000000000 -0400
@@ -311,14 +311,13 @@
 static int __init find_min_common_depth(void)
 {
 	int depth;
-	struct device_node *rtas_root;
 	struct device_node *chosen;
+	struct device_node *root;
 	const char *vec5;
 
-	rtas_root = of_find_node_by_path("/rtas");
-
-	if (!rtas_root)
-		return -1;
+	root = of_find_node_by_path("/rtas");
+	if (!root)
+		root = of_find_node_by_path("/");
 
 	/*
 	 * This property is a set of 32-bit integers, each representing
@@ -332,7 +331,7 @@
 	 * NUMA boundary and the following are progressively less significant
 	 * boundaries. There can be more than one level of NUMA.
 	 */
-	distance_ref_points = of_get_property(rtas_root,
+	distance_ref_points = of_get_property(root,
 					"ibm,associativity-reference-points",
 					&distance_ref_points_depth);
 
@@ -376,11 +375,11 @@
 		distance_ref_points_depth = MAX_DISTANCE_REF_POINTS;
 	}
 
-	of_node_put(rtas_root);
+	of_node_put(root);
 	return depth;
 
 err:
-	of_node_put(rtas_root);
+	of_node_put(root);
 	return -1;
 }
 
@@ -1453,7 +1452,7 @@
 	unsigned int associativity[VPHN_ASSOC_BUFSIZE] = {0};
 	struct sys_device *sysdev;
 
-	for_each_cpu_mask(cpu, cpu_associativity_changes_mask) {
+	for_each_cpu(cpu,&cpu_associativity_changes_mask) {
 		vphn_get_associativity(cpu, associativity);
 		nid = associativity_to_nid(associativity);
 
diff -druN linux-2.6.39-libre/arch/powerpc/mm/pgtable_32.c linux-3.0-rc7-libre/arch/powerpc/mm/pgtable_32.c
--- linux-2.6.39-libre/arch/powerpc/mm/pgtable_32.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/mm/pgtable_32.c	2011-07-11 19:51:52.000000000 -0400
@@ -133,7 +133,15 @@
 EXPORT_SYMBOL(ioremap);
 
 void __iomem *
-ioremap_flags(phys_addr_t addr, unsigned long size, unsigned long flags)
+ioremap_wc(phys_addr_t addr, unsigned long size)
+{
+	return __ioremap_caller(addr, size, _PAGE_NO_CACHE,
+				__builtin_return_address(0));
+}
+EXPORT_SYMBOL(ioremap_wc);
+
+void __iomem *
+ioremap_prot(phys_addr_t addr, unsigned long size, unsigned long flags)
 {
 	/* writeable implies dirty for kernel addresses */
 	if (flags & _PAGE_RW)
@@ -152,7 +160,7 @@
 
 	return __ioremap_caller(addr, size, flags, __builtin_return_address(0));
 }
-EXPORT_SYMBOL(ioremap_flags);
+EXPORT_SYMBOL(ioremap_prot);
 
 void __iomem *
 __ioremap(phys_addr_t addr, unsigned long size, unsigned long flags)
diff -druN linux-2.6.39-libre/arch/powerpc/mm/pgtable_64.c linux-3.0-rc7-libre/arch/powerpc/mm/pgtable_64.c
--- linux-2.6.39-libre/arch/powerpc/mm/pgtable_64.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/mm/pgtable_64.c	2011-07-11 19:51:52.000000000 -0400
@@ -255,7 +255,17 @@
 	return __ioremap_caller(addr, size, flags, caller);
 }
 
-void __iomem * ioremap_flags(phys_addr_t addr, unsigned long size,
+void __iomem * ioremap_wc(phys_addr_t addr, unsigned long size)
+{
+	unsigned long flags = _PAGE_NO_CACHE;
+	void *caller = __builtin_return_address(0);
+
+	if (ppc_md.ioremap)
+		return ppc_md.ioremap(addr, size, flags, caller);
+	return __ioremap_caller(addr, size, flags, caller);
+}
+
+void __iomem * ioremap_prot(phys_addr_t addr, unsigned long size,
 			     unsigned long flags)
 {
 	void *caller = __builtin_return_address(0);
@@ -311,7 +321,8 @@
 }
 
 EXPORT_SYMBOL(ioremap);
-EXPORT_SYMBOL(ioremap_flags);
+EXPORT_SYMBOL(ioremap_wc);
+EXPORT_SYMBOL(ioremap_prot);
 EXPORT_SYMBOL(__ioremap);
 EXPORT_SYMBOL(__ioremap_at);
 EXPORT_SYMBOL(iounmap);
diff -druN linux-2.6.39-libre/arch/powerpc/mm/pgtable.c linux-3.0-rc7-libre/arch/powerpc/mm/pgtable.c
--- linux-2.6.39-libre/arch/powerpc/mm/pgtable.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/mm/pgtable.c	2011-07-11 19:51:52.000000000 -0400
@@ -33,110 +33,6 @@
 
 #include "mmu_decl.h"
 
-DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
-
-#ifdef CONFIG_SMP
-
-/*
- * Handle batching of page table freeing on SMP. Page tables are
- * queued up and send to be freed later by RCU in order to avoid
- * freeing a page table page that is being walked without locks
- */
-
-static DEFINE_PER_CPU(struct pte_freelist_batch *, pte_freelist_cur);
-static unsigned long pte_freelist_forced_free;
-
-struct pte_freelist_batch
-{
-	struct rcu_head	rcu;
-	unsigned int	index;
-	unsigned long	tables[0];
-};
-
-#define PTE_FREELIST_SIZE \
-	((PAGE_SIZE - sizeof(struct pte_freelist_batch)) \
-	  / sizeof(unsigned long))
-
-static void pte_free_smp_sync(void *arg)
-{
-	/* Do nothing, just ensure we sync with all CPUs */
-}
-
-/* This is only called when we are critically out of memory
- * (and fail to get a page in pte_free_tlb).
- */
-static void pgtable_free_now(void *table, unsigned shift)
-{
-	pte_freelist_forced_free++;
-
-	smp_call_function(pte_free_smp_sync, NULL, 1);
-
-	pgtable_free(table, shift);
-}
-
-static void pte_free_rcu_callback(struct rcu_head *head)
-{
-	struct pte_freelist_batch *batch =
-		container_of(head, struct pte_freelist_batch, rcu);
-	unsigned int i;
-
-	for (i = 0; i < batch->index; i++) {
-		void *table = (void *)(batch->tables[i] & ~MAX_PGTABLE_INDEX_SIZE);
-		unsigned shift = batch->tables[i] & MAX_PGTABLE_INDEX_SIZE;
-
-		pgtable_free(table, shift);
-	}
-
-	free_page((unsigned long)batch);
-}
-
-static void pte_free_submit(struct pte_freelist_batch *batch)
-{
-	call_rcu_sched(&batch->rcu, pte_free_rcu_callback);
-}
-
-void pgtable_free_tlb(struct mmu_gather *tlb, void *table, unsigned shift)
-{
-	/* This is safe since tlb_gather_mmu has disabled preemption */
-	struct pte_freelist_batch **batchp = &__get_cpu_var(pte_freelist_cur);
-	unsigned long pgf;
-
-	if (atomic_read(&tlb->mm->mm_users) < 2 ||
-	    cpumask_equal(mm_cpumask(tlb->mm), cpumask_of(smp_processor_id()))){
-		pgtable_free(table, shift);
-		return;
-	}
-
-	if (*batchp == NULL) {
-		*batchp = (struct pte_freelist_batch *)__get_free_page(GFP_ATOMIC);
-		if (*batchp == NULL) {
-			pgtable_free_now(table, shift);
-			return;
-		}
-		(*batchp)->index = 0;
-	}
-	BUG_ON(shift > MAX_PGTABLE_INDEX_SIZE);
-	pgf = (unsigned long)table | shift;
-	(*batchp)->tables[(*batchp)->index++] = pgf;
-	if ((*batchp)->index == PTE_FREELIST_SIZE) {
-		pte_free_submit(*batchp);
-		*batchp = NULL;
-	}
-}
-
-void pte_free_finish(void)
-{
-	/* This is safe since tlb_gather_mmu has disabled preemption */
-	struct pte_freelist_batch **batchp = &__get_cpu_var(pte_freelist_cur);
-
-	if (*batchp == NULL)
-		return;
-	pte_free_submit(*batchp);
-	*batchp = NULL;
-}
-
-#endif /* CONFIG_SMP */
-
 static inline int is_exec_fault(void)
 {
 	return current->thread.regs && TRAP(current->thread.regs) == 0x400;
diff -druN linux-2.6.39-libre/arch/powerpc/mm/slb.c linux-3.0-rc7-libre/arch/powerpc/mm/slb.c
--- linux-2.6.39-libre/arch/powerpc/mm/slb.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/mm/slb.c	2011-07-11 19:51:52.000000000 -0400
@@ -24,6 +24,7 @@
 #include <asm/firmware.h>
 #include <linux/compiler.h>
 #include <asm/udbg.h>
+#include <asm/code-patching.h>
 
 
 extern void slb_allocate_realmode(unsigned long ea);
@@ -166,7 +167,7 @@
 	int esid_1t_count;
 
 	/* System is not 1T segment size capable. */
-	if (!cpu_has_feature(CPU_FTR_1T_SEGMENT))
+	if (!mmu_has_feature(MMU_FTR_1T_SEGMENT))
 		return (GET_ESID(addr1) == GET_ESID(addr2));
 
 	esid_1t_count = (((addr1 >> SID_SHIFT_1T) != 0) +
@@ -201,7 +202,7 @@
 	 */
 	hard_irq_disable();
 	offset = get_paca()->slb_cache_ptr;
-	if (!cpu_has_feature(CPU_FTR_NO_SLBIE_B) &&
+	if (!mmu_has_feature(MMU_FTR_NO_SLBIE_B) &&
 	    offset <= SLB_CACHE_ENTRIES) {
 		int i;
 		asm volatile("isync" : : : "memory");
@@ -249,9 +250,8 @@
 static inline void patch_slb_encoding(unsigned int *insn_addr,
 				      unsigned int immed)
 {
-	*insn_addr = (*insn_addr & 0xffff0000) | immed;
-	flush_icache_range((unsigned long)insn_addr, 4+
-			   (unsigned long)insn_addr);
+	int insn = (*insn_addr & 0xffff0000) | immed;
+	patch_instruction(insn_addr, insn);
 }
 
 void slb_set_size(u16 size)
diff -druN linux-2.6.39-libre/arch/powerpc/mm/slb_low.S linux-3.0-rc7-libre/arch/powerpc/mm/slb_low.S
--- linux-2.6.39-libre/arch/powerpc/mm/slb_low.S	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/mm/slb_low.S	2011-07-11 19:51:52.000000000 -0400
@@ -58,7 +58,7 @@
 	li	r11,0
 BEGIN_FTR_SECTION
 	b	slb_finish_load
-END_FTR_SECTION_IFCLR(CPU_FTR_1T_SEGMENT)
+END_MMU_FTR_SECTION_IFCLR(MMU_FTR_1T_SEGMENT)
 	b	slb_finish_load_1T
 
 1:
@@ -87,7 +87,7 @@
 6:
 BEGIN_FTR_SECTION
 	b	slb_finish_load
-END_FTR_SECTION_IFCLR(CPU_FTR_1T_SEGMENT)
+END_MMU_FTR_SECTION_IFCLR(MMU_FTR_1T_SEGMENT)
 	b	slb_finish_load_1T
 
 0:	/* user address: proto-VSID = context << 15 | ESID. First check
@@ -138,11 +138,11 @@
 	ld	r9,PACACONTEXTID(r13)
 BEGIN_FTR_SECTION
 	cmpldi	r10,0x1000
-END_FTR_SECTION_IFSET(CPU_FTR_1T_SEGMENT)
+END_MMU_FTR_SECTION_IFSET(MMU_FTR_1T_SEGMENT)
 	rldimi	r10,r9,USER_ESID_BITS,0
 BEGIN_FTR_SECTION
 	bge	slb_finish_load_1T
-END_FTR_SECTION_IFSET(CPU_FTR_1T_SEGMENT)
+END_MMU_FTR_SECTION_IFSET(MMU_FTR_1T_SEGMENT)
 	b	slb_finish_load
 
 8:	/* invalid EA */
diff -druN linux-2.6.39-libre/arch/powerpc/mm/stab.c linux-3.0-rc7-libre/arch/powerpc/mm/stab.c
--- linux-2.6.39-libre/arch/powerpc/mm/stab.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/mm/stab.c	2011-07-11 19:51:52.000000000 -0400
@@ -243,7 +243,7 @@
 {
 	int cpu;
 
-	if (cpu_has_feature(CPU_FTR_SLB))
+	if (mmu_has_feature(MMU_FTR_SLB))
 		return;
 
 	for_each_possible_cpu(cpu) {
diff -druN linux-2.6.39-libre/arch/powerpc/mm/tlb_hash32.c linux-3.0-rc7-libre/arch/powerpc/mm/tlb_hash32.c
--- linux-2.6.39-libre/arch/powerpc/mm/tlb_hash32.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/mm/tlb_hash32.c	2011-07-11 19:51:52.000000000 -0400
@@ -71,9 +71,6 @@
 		 */
 		_tlbia();
 	}
-
-	/* Push out batch of freed page tables */
-	pte_free_finish();
 }
 
 /*
diff -druN linux-2.6.39-libre/arch/powerpc/mm/tlb_hash64.c linux-3.0-rc7-libre/arch/powerpc/mm/tlb_hash64.c
--- linux-2.6.39-libre/arch/powerpc/mm/tlb_hash64.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/mm/tlb_hash64.c	2011-07-11 19:51:52.000000000 -0400
@@ -155,7 +155,7 @@
 
 void tlb_flush(struct mmu_gather *tlb)
 {
-	struct ppc64_tlb_batch *tlbbatch = &__get_cpu_var(ppc64_tlb_batch);
+	struct ppc64_tlb_batch *tlbbatch = &get_cpu_var(ppc64_tlb_batch);
 
 	/* If there's a TLB batch pending, then we must flush it because the
 	 * pages are going to be freed and we really don't want to have a CPU
@@ -164,8 +164,7 @@
 	if (tlbbatch->index)
 		__flush_tlb_pending(tlbbatch);
 
-	/* Push out batch of freed page tables */
-	pte_free_finish();
+	put_cpu_var(ppc64_tlb_batch);
 }
 
 /**
diff -druN linux-2.6.39-libre/arch/powerpc/mm/tlb_nohash.c linux-3.0-rc7-libre/arch/powerpc/mm/tlb_nohash.c
--- linux-2.6.39-libre/arch/powerpc/mm/tlb_nohash.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/mm/tlb_nohash.c	2011-07-11 19:51:52.000000000 -0400
@@ -299,9 +299,6 @@
 void tlb_flush(struct mmu_gather *tlb)
 {
 	flush_tlb_mm(tlb->mm);
-
-	/* Push out batch of freed page tables */
-	pte_free_finish();
 }
 
 /*
diff -druN linux-2.6.39-libre/arch/powerpc/oprofile/op_model_power4.c linux-3.0-rc7-libre/arch/powerpc/oprofile/op_model_power4.c
--- linux-2.6.39-libre/arch/powerpc/oprofile/op_model_power4.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/oprofile/op_model_power4.c	2011-07-11 19:51:52.000000000 -0400
@@ -261,6 +261,28 @@
 	return is_kernel;
 }
 
+static bool pmc_overflow(unsigned long val)
+{
+	if ((int)val < 0)
+		return true;
+
+	/*
+	 * Events on POWER7 can roll back if a speculative event doesn't
+	 * eventually complete. Unfortunately in some rare cases they will
+	 * raise a performance monitor exception. We need to catch this to
+	 * ensure we reset the PMC. In all cases the PMC will be 256 or less
+	 * cycles from overflow.
+	 *
+	 * We only do this if the first pass fails to find any overflowing
+	 * PMCs because a user might set a period of less than 256 and we
+	 * don't want to mistakenly reset them.
+	 */
+	if (__is_processor(PV_POWER7) && ((0x80000000 - val) <= 256))
+		return true;
+
+	return false;
+}
+
 static void power4_handle_interrupt(struct pt_regs *regs,
 				    struct op_counter_config *ctr)
 {
@@ -281,7 +303,7 @@
 
 	for (i = 0; i < cur_cpu_spec->num_pmcs; ++i) {
 		val = classic_ctr_read(i);
-		if (val < 0) {
+		if (pmc_overflow(val)) {
 			if (oprofile_running && ctr[i].enabled) {
 				oprofile_add_ext_sample(pc, regs, i, is_kernel);
 				classic_ctr_write(i, reset_value[i]);
diff -druN linux-2.6.39-libre/arch/powerpc/platforms/40x/Kconfig linux-3.0-rc7-libre/arch/powerpc/platforms/40x/Kconfig
--- linux-2.6.39-libre/arch/powerpc/platforms/40x/Kconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/platforms/40x/Kconfig	2011-07-11 19:51:52.000000000 -0400
@@ -57,6 +57,8 @@
 	select 405EX
 	select PPC40x_SIMPLE
 	select PPC4xx_PCI_EXPRESS
+	select PCI_MSI
+	select PPC4xx_MSI
 	help
 	  This option enables support for the AMCC PPC405EX evaluation board.
 
diff -druN linux-2.6.39-libre/arch/powerpc/platforms/44x/iss4xx.c linux-3.0-rc7-libre/arch/powerpc/platforms/44x/iss4xx.c
--- linux-2.6.39-libre/arch/powerpc/platforms/44x/iss4xx.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/platforms/44x/iss4xx.c	2011-07-11 19:51:52.000000000 -0400
@@ -87,7 +87,7 @@
 	mpic_setup_this_cpu();
 }
 
-static void __cpuinit smp_iss4xx_kick_cpu(int cpu)
+static int __cpuinit smp_iss4xx_kick_cpu(int cpu)
 {
 	struct device_node *cpunode = of_get_cpu_node(cpu, NULL);
 	const u64 *spin_table_addr_prop;
@@ -104,7 +104,7 @@
 					       NULL);
 	if (spin_table_addr_prop == NULL) {
 		pr_err("CPU%d: Can't start, missing cpu-release-addr !\n", cpu);
-		return;
+		return -ENOENT;
 	}
 
 	/* Assume it's mapped as part of the linear mapping. This is a bit
@@ -117,6 +117,8 @@
 	smp_wmb();
 	spin_table[1] = __pa(start_secondary_47x);
 	mb();
+
+	return 0;
 }
 
 static struct smp_ops_t iss_smp_ops = {
diff -druN linux-2.6.39-libre/arch/powerpc/platforms/44x/Kconfig linux-3.0-rc7-libre/arch/powerpc/platforms/44x/Kconfig
--- linux-2.6.39-libre/arch/powerpc/platforms/44x/Kconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/platforms/44x/Kconfig	2011-07-11 19:51:52.000000000 -0400
@@ -74,6 +74,8 @@
 	select 440SPe
 	select PCI
 	select PPC4xx_PCI_EXPRESS
+	select PCI_MSI
+	select PCC4xx_MSI
 	help
 	  This option enables support for the AMCC PPC440SPe evaluation board.
 
@@ -118,6 +120,8 @@
 	select 460EX
 	select PCI
 	select PPC4xx_PCI_EXPRESS
+	select PCI_MSI
+	select PPC4xx_MSI
 	select IBM_NEW_EMAC_RGMII
 	select IBM_NEW_EMAC_ZMII
 	help
@@ -144,6 +148,8 @@
 	select 460SX
 	select PCI
 	select PPC4xx_PCI_EXPRESS
+	select PCI_MSI
+	select PPC4xx_MSI
 	help
 	  This option enables support for the AMCC PPC460SX Redwood board.
 
diff -druN linux-2.6.39-libre/arch/powerpc/platforms/512x/mpc5121_ads_cpld.c linux-3.0-rc7-libre/arch/powerpc/platforms/512x/mpc5121_ads_cpld.c
--- linux-2.6.39-libre/arch/powerpc/platforms/512x/mpc5121_ads_cpld.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/platforms/512x/mpc5121_ads_cpld.c	2011-07-11 19:51:52.000000000 -0400
@@ -61,7 +61,7 @@
 static void
 cpld_mask_irq(struct irq_data *d)
 {
-	unsigned int cpld_irq = (unsigned int)irq_map[d->irq].hwirq;
+	unsigned int cpld_irq = (unsigned int)irqd_to_hwirq(d);
 	void __iomem *pic_mask = irq_to_pic_mask(cpld_irq);
 
 	out_8(pic_mask,
@@ -71,7 +71,7 @@
 static void
 cpld_unmask_irq(struct irq_data *d)
 {
-	unsigned int cpld_irq = (unsigned int)irq_map[d->irq].hwirq;
+	unsigned int cpld_irq = (unsigned int)irqd_to_hwirq(d);
 	void __iomem *pic_mask = irq_to_pic_mask(cpld_irq);
 
 	out_8(pic_mask,
@@ -97,7 +97,7 @@
 	status |= (ignore | mask);
 
 	if (status == 0xff)
-		return NO_IRQ_IGNORE;
+		return NO_IRQ;
 
 	cpld_irq = ffz(status) + offset;
 
@@ -109,14 +109,14 @@
 {
 	irq = cpld_pic_get_irq(0, PCI_IGNORE, &cpld_regs->pci_status,
 		&cpld_regs->pci_mask);
-	if (irq != NO_IRQ && irq != NO_IRQ_IGNORE) {
+	if (irq != NO_IRQ) {
 		generic_handle_irq(irq);
 		return;
 	}
 
 	irq = cpld_pic_get_irq(8, MISC_IGNORE, &cpld_regs->misc_status,
 		&cpld_regs->misc_mask);
-	if (irq != NO_IRQ && irq != NO_IRQ_IGNORE) {
+	if (irq != NO_IRQ) {
 		generic_handle_irq(irq);
 		return;
 	}
diff -druN linux-2.6.39-libre/arch/powerpc/platforms/52xx/media5200.c linux-3.0-rc7-libre/arch/powerpc/platforms/52xx/media5200.c
--- linux-2.6.39-libre/arch/powerpc/platforms/52xx/media5200.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/platforms/52xx/media5200.c	2011-07-11 19:51:52.000000000 -0400
@@ -56,7 +56,7 @@
 
 	spin_lock_irqsave(&media5200_irq.lock, flags);
 	val = in_be32(media5200_irq.regs + MEDIA5200_IRQ_ENABLE);
-	val |= 1 << (MEDIA5200_IRQ_SHIFT + irq_map[d->irq].hwirq);
+	val |= 1 << (MEDIA5200_IRQ_SHIFT + irqd_to_hwirq(d));
 	out_be32(media5200_irq.regs + MEDIA5200_IRQ_ENABLE, val);
 	spin_unlock_irqrestore(&media5200_irq.lock, flags);
 }
@@ -68,7 +68,7 @@
 
 	spin_lock_irqsave(&media5200_irq.lock, flags);
 	val = in_be32(media5200_irq.regs + MEDIA5200_IRQ_ENABLE);
-	val &= ~(1 << (MEDIA5200_IRQ_SHIFT + irq_map[d->irq].hwirq));
+	val &= ~(1 << (MEDIA5200_IRQ_SHIFT + irqd_to_hwirq(d)));
 	out_be32(media5200_irq.regs + MEDIA5200_IRQ_ENABLE, val);
 	spin_unlock_irqrestore(&media5200_irq.lock, flags);
 }
diff -druN linux-2.6.39-libre/arch/powerpc/platforms/52xx/mpc52xx_pic.c linux-3.0-rc7-libre/arch/powerpc/platforms/52xx/mpc52xx_pic.c
--- linux-2.6.39-libre/arch/powerpc/platforms/52xx/mpc52xx_pic.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/platforms/52xx/mpc52xx_pic.c	2011-07-11 19:51:52.000000000 -0400
@@ -157,48 +157,30 @@
  */
 static void mpc52xx_extirq_mask(struct irq_data *d)
 {
-	int irq;
-	int l2irq;
-
-	irq = irq_map[d->irq].hwirq;
-	l2irq = irq & MPC52xx_IRQ_L2_MASK;
-
+	int l2irq = irqd_to_hwirq(d) & MPC52xx_IRQ_L2_MASK;
 	io_be_clrbit(&intr->ctrl, 11 - l2irq);
 }
 
 static void mpc52xx_extirq_unmask(struct irq_data *d)
 {
-	int irq;
-	int l2irq;
-
-	irq = irq_map[d->irq].hwirq;
-	l2irq = irq & MPC52xx_IRQ_L2_MASK;
-
+	int l2irq = irqd_to_hwirq(d) & MPC52xx_IRQ_L2_MASK;
 	io_be_setbit(&intr->ctrl, 11 - l2irq);
 }
 
 static void mpc52xx_extirq_ack(struct irq_data *d)
 {
-	int irq;
-	int l2irq;
-
-	irq = irq_map[d->irq].hwirq;
-	l2irq = irq & MPC52xx_IRQ_L2_MASK;
-
+	int l2irq = irqd_to_hwirq(d) & MPC52xx_IRQ_L2_MASK;
 	io_be_setbit(&intr->ctrl, 27-l2irq);
 }
 
 static int mpc52xx_extirq_set_type(struct irq_data *d, unsigned int flow_type)
 {
 	u32 ctrl_reg, type;
-	int irq;
-	int l2irq;
+	int l2irq = irqd_to_hwirq(d) & MPC52xx_IRQ_L2_MASK;
 	void *handler = handle_level_irq;
 
-	irq = irq_map[d->irq].hwirq;
-	l2irq = irq & MPC52xx_IRQ_L2_MASK;
-
-	pr_debug("%s: irq=%x. l2=%d flow_type=%d\n", __func__, irq, l2irq, flow_type);
+	pr_debug("%s: irq=%x. l2=%d flow_type=%d\n", __func__,
+		(int) irqd_to_hwirq(d), l2irq, flow_type);
 
 	switch (flow_type) {
 	case IRQF_TRIGGER_HIGH: type = 0; break;
@@ -237,23 +219,13 @@
 
 static void mpc52xx_main_mask(struct irq_data *d)
 {
-	int irq;
-	int l2irq;
-
-	irq = irq_map[d->irq].hwirq;
-	l2irq = irq & MPC52xx_IRQ_L2_MASK;
-
+	int l2irq = irqd_to_hwirq(d) & MPC52xx_IRQ_L2_MASK;
 	io_be_setbit(&intr->main_mask, 16 - l2irq);
 }
 
 static void mpc52xx_main_unmask(struct irq_data *d)
 {
-	int irq;
-	int l2irq;
-
-	irq = irq_map[d->irq].hwirq;
-	l2irq = irq & MPC52xx_IRQ_L2_MASK;
-
+	int l2irq = irqd_to_hwirq(d) & MPC52xx_IRQ_L2_MASK;
 	io_be_clrbit(&intr->main_mask, 16 - l2irq);
 }
 
@@ -270,23 +242,13 @@
  */
 static void mpc52xx_periph_mask(struct irq_data *d)
 {
-	int irq;
-	int l2irq;
-
-	irq = irq_map[d->irq].hwirq;
-	l2irq = irq & MPC52xx_IRQ_L2_MASK;
-
+	int l2irq = irqd_to_hwirq(d) & MPC52xx_IRQ_L2_MASK;
 	io_be_setbit(&intr->per_mask, 31 - l2irq);
 }
 
 static void mpc52xx_periph_unmask(struct irq_data *d)
 {
-	int irq;
-	int l2irq;
-
-	irq = irq_map[d->irq].hwirq;
-	l2irq = irq & MPC52xx_IRQ_L2_MASK;
-
+	int l2irq = irqd_to_hwirq(d) & MPC52xx_IRQ_L2_MASK;
 	io_be_clrbit(&intr->per_mask, 31 - l2irq);
 }
 
@@ -303,34 +265,19 @@
  */
 static void mpc52xx_sdma_mask(struct irq_data *d)
 {
-	int irq;
-	int l2irq;
-
-	irq = irq_map[d->irq].hwirq;
-	l2irq = irq & MPC52xx_IRQ_L2_MASK;
-
+	int l2irq = irqd_to_hwirq(d) & MPC52xx_IRQ_L2_MASK;
 	io_be_setbit(&sdma->IntMask, l2irq);
 }
 
 static void mpc52xx_sdma_unmask(struct irq_data *d)
 {
-	int irq;
-	int l2irq;
-
-	irq = irq_map[d->irq].hwirq;
-	l2irq = irq & MPC52xx_IRQ_L2_MASK;
-
+	int l2irq = irqd_to_hwirq(d) & MPC52xx_IRQ_L2_MASK;
 	io_be_clrbit(&sdma->IntMask, l2irq);
 }
 
 static void mpc52xx_sdma_ack(struct irq_data *d)
 {
-	int irq;
-	int l2irq;
-
-	irq = irq_map[d->irq].hwirq;
-	l2irq = irq & MPC52xx_IRQ_L2_MASK;
-
+	int l2irq = irqd_to_hwirq(d) & MPC52xx_IRQ_L2_MASK;
 	out_be32(&sdma->IntPend, 1 << l2irq);
 }
 
@@ -539,7 +486,7 @@
 unsigned int mpc52xx_get_irq(void)
 {
 	u32 status;
-	int irq = NO_IRQ_IGNORE;
+	int irq;
 
 	status = in_be32(&intr->enc_status);
 	if (status & 0x00000400) {	/* critical */
@@ -562,6 +509,8 @@
 		} else {
 			irq |= (MPC52xx_IRQ_L1_PERP << MPC52xx_IRQ_L1_OFFSET);
 		}
+	} else {
+		return NO_IRQ;
 	}
 
 	return irq_linear_revmap(mpc52xx_irqhost, irq);
diff -druN linux-2.6.39-libre/arch/powerpc/platforms/82xx/pq2ads-pci-pic.c linux-3.0-rc7-libre/arch/powerpc/platforms/82xx/pq2ads-pci-pic.c
--- linux-2.6.39-libre/arch/powerpc/platforms/82xx/pq2ads-pci-pic.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/platforms/82xx/pq2ads-pci-pic.c	2011-07-11 19:51:52.000000000 -0400
@@ -42,7 +42,7 @@
 static void pq2ads_pci_mask_irq(struct irq_data *d)
 {
 	struct pq2ads_pci_pic *priv = irq_data_get_irq_chip_data(d);
-	int irq = NUM_IRQS - virq_to_hw(d->irq) - 1;
+	int irq = NUM_IRQS - irqd_to_hwirq(d) - 1;
 
 	if (irq != -1) {
 		unsigned long flags;
@@ -58,7 +58,7 @@
 static void pq2ads_pci_unmask_irq(struct irq_data *d)
 {
 	struct pq2ads_pci_pic *priv = irq_data_get_irq_chip_data(d);
-	int irq = NUM_IRQS - virq_to_hw(d->irq) - 1;
+	int irq = NUM_IRQS - irqd_to_hwirq(d) - 1;
 
 	if (irq != -1) {
 		unsigned long flags;
@@ -112,16 +112,8 @@
 	return 0;
 }
 
-static void pci_host_unmap(struct irq_host *h, unsigned int virq)
-{
-	/* remove chip and handler */
-	irq_set_chip_data(virq, NULL);
-	irq_set_chip(virq, NULL);
-}
-
 static struct irq_host_ops pci_pic_host_ops = {
 	.map = pci_pic_host_map,
-	.unmap = pci_host_unmap,
 };
 
 int __init pq2ads_pci_init_irq(void)
diff -druN linux-2.6.39-libre/arch/powerpc/platforms/85xx/smp.c linux-3.0-rc7-libre/arch/powerpc/platforms/85xx/smp.c
--- linux-2.6.39-libre/arch/powerpc/platforms/85xx/smp.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/platforms/85xx/smp.c	2011-07-11 19:51:52.000000000 -0400
@@ -41,7 +41,7 @@
 #define NUM_BOOT_ENTRY		8
 #define SIZE_BOOT_ENTRY		(NUM_BOOT_ENTRY * sizeof(u32))
 
-static void __init
+static int __init
 smp_85xx_kick_cpu(int nr)
 {
 	unsigned long flags;
@@ -60,7 +60,7 @@
 
 	if (cpu_rel_addr == NULL) {
 		printk(KERN_ERR "No cpu-release-addr for cpu %d\n", nr);
-		return;
+		return -ENOENT;
 	}
 
 	/*
@@ -107,6 +107,8 @@
 		iounmap(bptr_vaddr);
 
 	pr_debug("waited %d msecs for CPU #%d.\n", n, nr);
+
+	return 0;
 }
 
 static void __init
@@ -233,8 +235,10 @@
 		smp_85xx_ops.message_pass = smp_mpic_message_pass;
 	}
 
-	if (cpu_has_feature(CPU_FTR_DBELL))
-		smp_85xx_ops.message_pass = doorbell_message_pass;
+	if (cpu_has_feature(CPU_FTR_DBELL)) {
+		smp_85xx_ops.message_pass = smp_muxed_ipi_message_pass;
+		smp_85xx_ops.cause_ipi = doorbell_cause_ipi;
+	}
 
 	BUG_ON(!smp_85xx_ops.message_pass);
 
diff -druN linux-2.6.39-libre/arch/powerpc/platforms/85xx/socrates_fpga_pic.c linux-3.0-rc7-libre/arch/powerpc/platforms/85xx/socrates_fpga_pic.c
--- linux-2.6.39-libre/arch/powerpc/platforms/85xx/socrates_fpga_pic.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/platforms/85xx/socrates_fpga_pic.c	2011-07-11 19:51:52.000000000 -0400
@@ -48,8 +48,6 @@
 	[8] = {0, IRQ_TYPE_LEVEL_HIGH},
 };
 
-#define socrates_fpga_irq_to_hw(virq)    ((unsigned int)irq_map[virq].hwirq)
-
 static DEFINE_RAW_SPINLOCK(socrates_fpga_pic_lock);
 
 static void __iomem *socrates_fpga_pic_iobase;
@@ -110,11 +108,9 @@
 static void socrates_fpga_pic_ack(struct irq_data *d)
 {
 	unsigned long flags;
-	unsigned int hwirq, irq_line;
+	unsigned int irq_line, hwirq = irqd_to_hwirq(d);
 	uint32_t mask;
 
-	hwirq = socrates_fpga_irq_to_hw(d->irq);
-
 	irq_line = fpga_irqs[hwirq].irq_line;
 	raw_spin_lock_irqsave(&socrates_fpga_pic_lock, flags);
 	mask = socrates_fpga_pic_read(FPGA_PIC_IRQMASK(irq_line))
@@ -127,12 +123,10 @@
 static void socrates_fpga_pic_mask(struct irq_data *d)
 {
 	unsigned long flags;
-	unsigned int hwirq;
+	unsigned int hwirq = irqd_to_hwirq(d);
 	int irq_line;
 	u32 mask;
 
-	hwirq = socrates_fpga_irq_to_hw(d->irq);
-
 	irq_line = fpga_irqs[hwirq].irq_line;
 	raw_spin_lock_irqsave(&socrates_fpga_pic_lock, flags);
 	mask = socrates_fpga_pic_read(FPGA_PIC_IRQMASK(irq_line))
@@ -145,12 +139,10 @@
 static void socrates_fpga_pic_mask_ack(struct irq_data *d)
 {
 	unsigned long flags;
-	unsigned int hwirq;
+	unsigned int hwirq = irqd_to_hwirq(d);
 	int irq_line;
 	u32 mask;
 
-	hwirq = socrates_fpga_irq_to_hw(d->irq);
-
 	irq_line = fpga_irqs[hwirq].irq_line;
 	raw_spin_lock_irqsave(&socrates_fpga_pic_lock, flags);
 	mask = socrates_fpga_pic_read(FPGA_PIC_IRQMASK(irq_line))
@@ -164,12 +156,10 @@
 static void socrates_fpga_pic_unmask(struct irq_data *d)
 {
 	unsigned long flags;
-	unsigned int hwirq;
+	unsigned int hwirq = irqd_to_hwirq(d);
 	int irq_line;
 	u32 mask;
 
-	hwirq = socrates_fpga_irq_to_hw(d->irq);
-
 	irq_line = fpga_irqs[hwirq].irq_line;
 	raw_spin_lock_irqsave(&socrates_fpga_pic_lock, flags);
 	mask = socrates_fpga_pic_read(FPGA_PIC_IRQMASK(irq_line))
@@ -182,12 +172,10 @@
 static void socrates_fpga_pic_eoi(struct irq_data *d)
 {
 	unsigned long flags;
-	unsigned int hwirq;
+	unsigned int hwirq = irqd_to_hwirq(d);
 	int irq_line;
 	u32 mask;
 
-	hwirq = socrates_fpga_irq_to_hw(d->irq);
-
 	irq_line = fpga_irqs[hwirq].irq_line;
 	raw_spin_lock_irqsave(&socrates_fpga_pic_lock, flags);
 	mask = socrates_fpga_pic_read(FPGA_PIC_IRQMASK(irq_line))
@@ -201,12 +189,10 @@
 		unsigned int flow_type)
 {
 	unsigned long flags;
-	unsigned int hwirq;
+	unsigned int hwirq = irqd_to_hwirq(d);
 	int polarity;
 	u32 mask;
 
-	hwirq = socrates_fpga_irq_to_hw(d->irq);
-
 	if (fpga_irqs[hwirq].type != IRQ_TYPE_NONE)
 		return -EINVAL;
 
diff -druN linux-2.6.39-libre/arch/powerpc/platforms/86xx/gef_pic.c linux-3.0-rc7-libre/arch/powerpc/platforms/86xx/gef_pic.c
--- linux-2.6.39-libre/arch/powerpc/platforms/86xx/gef_pic.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/platforms/86xx/gef_pic.c	2011-07-11 19:51:52.000000000 -0400
@@ -46,8 +46,6 @@
 #define GEF_PIC_CPU0_MCP_MASK	GEF_PIC_MCP_MASK(0)
 #define GEF_PIC_CPU1_MCP_MASK	GEF_PIC_MCP_MASK(1)
 
-#define gef_irq_to_hw(virq)    ((unsigned int)irq_map[virq].hwirq)
-
 
 static DEFINE_RAW_SPINLOCK(gef_pic_lock);
 
@@ -113,11 +111,9 @@
 static void gef_pic_mask(struct irq_data *d)
 {
 	unsigned long flags;
-	unsigned int hwirq;
+	unsigned int hwirq = irqd_to_hwirq(d);
 	u32 mask;
 
-	hwirq = gef_irq_to_hw(d->irq);
-
 	raw_spin_lock_irqsave(&gef_pic_lock, flags);
 	mask = in_be32(gef_pic_irq_reg_base + GEF_PIC_INTR_MASK(0));
 	mask &= ~(1 << hwirq);
@@ -136,11 +132,9 @@
 static void gef_pic_unmask(struct irq_data *d)
 {
 	unsigned long flags;
-	unsigned int hwirq;
+	unsigned int hwirq = irqd_to_hwirq(d);
 	u32 mask;
 
-	hwirq = gef_irq_to_hw(d->irq);
-
 	raw_spin_lock_irqsave(&gef_pic_lock, flags);
 	mask = in_be32(gef_pic_irq_reg_base + GEF_PIC_INTR_MASK(0));
 	mask |= (1 << hwirq);
diff -druN linux-2.6.39-libre/arch/powerpc/platforms/86xx/mpc8610_hpcd.c linux-3.0-rc7-libre/arch/powerpc/platforms/86xx/mpc8610_hpcd.c
--- linux-2.6.39-libre/arch/powerpc/platforms/86xx/mpc8610_hpcd.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/platforms/86xx/mpc8610_hpcd.c	2011-07-11 19:51:52.000000000 -0400
@@ -66,7 +66,7 @@
 		return;
 	}
 
-	ret = request_irq(irq, mpc8610_sw9_irq, 0, "sw9/wakeup", NULL);
+	ret = request_irq(irq, mpc8610_sw9_irq, 0, "sw9:wakeup", NULL);
 	if (ret) {
 		pr_err("%s: can't request pixis event IRQ: %d\n",
 		       __func__, ret);
@@ -105,45 +105,77 @@
 
 #if defined(CONFIG_FB_FSL_DIU) || defined(CONFIG_FB_FSL_DIU_MODULE)
 
-static u32 get_busfreq(void)
-{
-	struct device_node *node;
+/*
+ * DIU Area Descriptor
+ *
+ * The MPC8610 reference manual shows the bits of the AD register in
+ * little-endian order, which causes the BLUE_C field to be split into two
+ * parts. To simplify the definition of the MAKE_AD() macro, we define the
+ * fields in big-endian order and byte-swap the result.
+ *
+ * So even though the registers don't look like they're in the
+ * same bit positions as they are on the P1022, the same value is written to
+ * the AD register on the MPC8610 and on the P1022.
+ */
+#define AD_BYTE_F		0x10000000
+#define AD_ALPHA_C_MASK		0x0E000000
+#define AD_ALPHA_C_SHIFT	25
+#define AD_BLUE_C_MASK		0x01800000
+#define AD_BLUE_C_SHIFT		23
+#define AD_GREEN_C_MASK		0x00600000
+#define AD_GREEN_C_SHIFT	21
+#define AD_RED_C_MASK		0x00180000
+#define AD_RED_C_SHIFT		19
+#define AD_PALETTE		0x00040000
+#define AD_PIXEL_S_MASK		0x00030000
+#define AD_PIXEL_S_SHIFT	16
+#define AD_COMP_3_MASK		0x0000F000
+#define AD_COMP_3_SHIFT		12
+#define AD_COMP_2_MASK		0x00000F00
+#define AD_COMP_2_SHIFT		8
+#define AD_COMP_1_MASK		0x000000F0
+#define AD_COMP_1_SHIFT		4
+#define AD_COMP_0_MASK		0x0000000F
+#define AD_COMP_0_SHIFT		0
 
-	u32 fs_busfreq = 0;
-	node = of_find_node_by_type(NULL, "cpu");
-	if (node) {
-		unsigned int size;
-		const unsigned int *prop =
-			of_get_property(node, "bus-frequency", &size);
-		if (prop)
-			fs_busfreq = *prop;
-		of_node_put(node);
-	};
-	return fs_busfreq;
-}
+#define MAKE_AD(alpha, red, blue, green, size, c0, c1, c2, c3) \
+	cpu_to_le32(AD_BYTE_F | (alpha << AD_ALPHA_C_SHIFT) | \
+	(blue << AD_BLUE_C_SHIFT) | (green << AD_GREEN_C_SHIFT) | \
+	(red << AD_RED_C_SHIFT) | (c3 << AD_COMP_3_SHIFT) | \
+	(c2 << AD_COMP_2_SHIFT) | (c1 << AD_COMP_1_SHIFT) | \
+	(c0 << AD_COMP_0_SHIFT) | (size << AD_PIXEL_S_SHIFT))
 
 unsigned int mpc8610hpcd_get_pixel_format(unsigned int bits_per_pixel,
 						int monitor_port)
 {
 	static const unsigned long pixelformat[][3] = {
-		{0x88882317, 0x88083218, 0x65052119},
-		{0x88883316, 0x88082219, 0x65053118},
+		{
+			MAKE_AD(3, 0, 2, 1, 3, 8, 8, 8, 8),
+			MAKE_AD(4, 2, 0, 1, 2, 8, 8, 8, 0),
+			MAKE_AD(4, 0, 2, 1, 1, 5, 6, 5, 0)
+		},
+		{
+			MAKE_AD(3, 2, 0, 1, 3, 8, 8, 8, 8),
+			MAKE_AD(4, 0, 2, 1, 2, 8, 8, 8, 0),
+			MAKE_AD(4, 2, 0, 1, 1, 5, 6, 5, 0)
+		},
 	};
-	unsigned int pix_fmt, arch_monitor;
+	unsigned int arch_monitor;
 
+	/* The DVI port is mis-wired on revision 1 of this board. */
 	arch_monitor = ((*pixis_arch == 0x01) && (monitor_port == 0))? 0 : 1;
-		/* DVI port for board version 0x01 */
 
-	if (bits_per_pixel == 32)
-		pix_fmt = pixelformat[arch_monitor][0];
-	else if (bits_per_pixel == 24)
-		pix_fmt = pixelformat[arch_monitor][1];
-	else if (bits_per_pixel == 16)
-		pix_fmt = pixelformat[arch_monitor][2];
-	else
-		pix_fmt = pixelformat[1][0];
-
-	return pix_fmt;
+	switch (bits_per_pixel) {
+	case 32:
+		return pixelformat[arch_monitor][0];
+	case 24:
+		return pixelformat[arch_monitor][1];
+	case 16:
+		return pixelformat[arch_monitor][2];
+	default:
+		pr_err("fsl-diu: unsupported pixel depth %u\n", bits_per_pixel);
+		return 0;
+	}
 }
 
 void mpc8610hpcd_set_gamma_table(int monitor_port, char *gamma_table_base)
@@ -190,8 +222,7 @@
 	}
 
 	/* Pixel Clock configuration */
-	pr_debug("DIU: Bus Frequency = %d\n", get_busfreq());
-	speed_ccb = get_busfreq();
+	speed_ccb = fsl_get_sys_freq();
 
 	/* Calculate the pixel clock with the smallest error */
 	/* calculate the following in steps to avoid overflow */
diff -druN linux-2.6.39-libre/arch/powerpc/platforms/86xx/mpc86xx_smp.c linux-3.0-rc7-libre/arch/powerpc/platforms/86xx/mpc86xx_smp.c
--- linux-2.6.39-libre/arch/powerpc/platforms/86xx/mpc86xx_smp.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/platforms/86xx/mpc86xx_smp.c	2011-07-11 19:51:52.000000000 -0400
@@ -56,7 +56,7 @@
 }
 
 
-static void __init
+static int __init
 smp_86xx_kick_cpu(int nr)
 {
 	unsigned int save_vector;
@@ -65,7 +65,7 @@
 	unsigned int *vector = (unsigned int *)(KERNELBASE + 0x100);
 
 	if (nr < 0 || nr >= NR_CPUS)
-		return;
+		return -ENOENT;
 
 	pr_debug("smp_86xx_kick_cpu: kick CPU #%d\n", nr);
 
@@ -92,6 +92,8 @@
 	local_irq_restore(flags);
 
 	pr_debug("wait CPU #%d for %d msecs.\n", nr, n);
+
+	return 0;
 }
 
 
diff -druN linux-2.6.39-libre/arch/powerpc/platforms/8xx/m8xx_setup.c linux-3.0-rc7-libre/arch/powerpc/platforms/8xx/m8xx_setup.c
--- linux-2.6.39-libre/arch/powerpc/platforms/8xx/m8xx_setup.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/platforms/8xx/m8xx_setup.c	2011-07-11 19:51:52.000000000 -0400
@@ -150,7 +150,7 @@
 	 */
 	cpu = of_find_node_by_type(NULL, "cpu");
 	virq= irq_of_parse_and_map(cpu, 0);
-	irq = irq_map[virq].hwirq;
+	irq = virq_to_hw(virq);
 
 	sys_tmr2 = immr_map(im_sit);
 	out_be16(&sys_tmr2->sit_tbscr, ((1 << (7 - (irq/2))) << 8) |
diff -druN linux-2.6.39-libre/arch/powerpc/platforms/cell/axon_msi.c linux-3.0-rc7-libre/arch/powerpc/platforms/cell/axon_msi.c
--- linux-2.6.39-libre/arch/powerpc/platforms/cell/axon_msi.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/platforms/cell/axon_msi.c	2011-07-11 19:51:52.000000000 -0400
@@ -113,7 +113,7 @@
 		pr_devel("axon_msi: woff %x roff %x msi %x\n",
 			  write_offset, msic->read_offset, msi);
 
-		if (msi < NR_IRQS && irq_map[msi].host == msic->irq_host) {
+		if (msi < NR_IRQS && irq_get_chip_data(msi) == msic) {
 			generic_handle_irq(msi);
 			msic->fifo_virt[idx] = cpu_to_le32(0xffffffff);
 		} else {
@@ -320,6 +320,7 @@
 static int msic_host_map(struct irq_host *h, unsigned int virq,
 			 irq_hw_number_t hw)
 {
+	irq_set_chip_data(virq, h->host_data);
 	irq_set_chip_and_handler(virq, &msic_irq_chip, handle_simple_irq);
 
 	return 0;
diff -druN linux-2.6.39-libre/arch/powerpc/platforms/cell/beat_interrupt.c linux-3.0-rc7-libre/arch/powerpc/platforms/cell/beat_interrupt.c
--- linux-2.6.39-libre/arch/powerpc/platforms/cell/beat_interrupt.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/platforms/cell/beat_interrupt.c	2011-07-11 19:51:52.000000000 -0400
@@ -148,16 +148,6 @@
 }
 
 /*
- * Update binding hardware IRQ number (hw) and Virtuql
- * IRQ number (virq). This is called only once for a given mapping.
- */
-static void beatic_pic_host_remap(struct irq_host *h, unsigned int virq,
-			       irq_hw_number_t hw)
-{
-	beat_construct_and_connect_irq_plug(virq, hw);
-}
-
-/*
  * Translate device-tree interrupt spec to irq_hw_number_t style (ulong),
  * to pass away to irq_create_mapping().
  *
@@ -184,7 +174,6 @@
 
 static struct irq_host_ops beatic_pic_host_ops = {
 	.map = beatic_pic_host_map,
-	.remap = beatic_pic_host_remap,
 	.unmap = beatic_pic_host_unmap,
 	.xlate = beatic_pic_host_xlate,
 	.match = beatic_pic_host_match,
@@ -257,22 +246,6 @@
 	irq_set_default_host(beatic_host);
 }
 
-#ifdef CONFIG_SMP
-
-/* Nullified to compile with SMP mode */
-void beatic_setup_cpu(int cpu)
-{
-}
-
-void beatic_cause_IPI(int cpu, int mesg)
-{
-}
-
-void beatic_request_IPIs(void)
-{
-}
-#endif /* CONFIG_SMP */
-
 void beatic_deinit_IRQ(void)
 {
 	int	i;
diff -druN linux-2.6.39-libre/arch/powerpc/platforms/cell/beat_interrupt.h linux-3.0-rc7-libre/arch/powerpc/platforms/cell/beat_interrupt.h
--- linux-2.6.39-libre/arch/powerpc/platforms/cell/beat_interrupt.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/platforms/cell/beat_interrupt.h	2011-07-11 19:51:52.000000000 -0400
@@ -24,9 +24,6 @@
 
 extern void beatic_init_IRQ(void);
 extern unsigned int beatic_get_irq(void);
-extern void beatic_cause_IPI(int cpu, int mesg);
-extern void beatic_request_IPIs(void);
-extern void beatic_setup_cpu(int);
 extern void beatic_deinit_IRQ(void);
 
 #endif
diff -druN linux-2.6.39-libre/arch/powerpc/platforms/cell/beat_smp.c linux-3.0-rc7-libre/arch/powerpc/platforms/cell/beat_smp.c
--- linux-2.6.39-libre/arch/powerpc/platforms/cell/beat_smp.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/platforms/cell/beat_smp.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,124 +0,0 @@
-/*
- * SMP support for Celleb platform. (Incomplete)
- *
- * (C) Copyright 2006 TOSHIBA CORPORATION
- *
- * This code is based on arch/powerpc/platforms/cell/smp.c:
- * Dave Engebretsen, Peter Bergner, and
- * Mike Corrigan {engebret|bergner|mikec}@us.ibm.com
- * Plus various changes from other IBM teams...
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You 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.
- */
-
-#undef DEBUG
-
-#include <linux/kernel.h>
-#include <linux/smp.h>
-#include <linux/interrupt.h>
-#include <linux/init.h>
-#include <linux/threads.h>
-#include <linux/cpu.h>
-
-#include <asm/irq.h>
-#include <asm/smp.h>
-#include <asm/machdep.h>
-#include <asm/udbg.h>
-
-#include "beat_interrupt.h"
-
-#ifdef DEBUG
-#define DBG(fmt...) udbg_printf(fmt)
-#else
-#define DBG(fmt...)
-#endif
-
-/*
- * The primary thread of each non-boot processor is recorded here before
- * smp init.
- */
-/* static cpumask_t of_spin_map; */
-
-/**
- * smp_startup_cpu() - start the given cpu
- *
- * At boot time, there is nothing to do for primary threads which were
- * started from Open Firmware.  For anything else, call RTAS with the
- * appropriate start location.
- *
- * Returns:
- *	0	- failure
- *	1	- success
- */
-static inline int __devinit smp_startup_cpu(unsigned int lcpu)
-{
-	return 0;
-}
-
-static void smp_beatic_message_pass(int target, int msg)
-{
-	unsigned int i;
-
-	if (target < NR_CPUS) {
-		beatic_cause_IPI(target, msg);
-	} else {
-		for_each_online_cpu(i) {
-			if (target == MSG_ALL_BUT_SELF
-			    && i == smp_processor_id())
-				continue;
-			beatic_cause_IPI(i, msg);
-		}
-	}
-}
-
-static int __init smp_beatic_probe(void)
-{
-	return cpus_weight(cpu_possible_map);
-}
-
-static void __devinit smp_beatic_setup_cpu(int cpu)
-{
-	beatic_setup_cpu(cpu);
-}
-
-static void __devinit smp_celleb_kick_cpu(int nr)
-{
-	BUG_ON(nr < 0 || nr >= NR_CPUS);
-
-	if (!smp_startup_cpu(nr))
-		return;
-}
-
-static int smp_celleb_cpu_bootable(unsigned int nr)
-{
-	return 1;
-}
-static struct smp_ops_t bpa_beatic_smp_ops = {
-	.message_pass	= smp_beatic_message_pass,
-	.probe		= smp_beatic_probe,
-	.kick_cpu	= smp_celleb_kick_cpu,
-	.setup_cpu	= smp_beatic_setup_cpu,
-	.cpu_bootable	= smp_celleb_cpu_bootable,
-};
-
-/* This is called very early */
-void __init smp_init_celleb(void)
-{
-	DBG(" -> smp_init_celleb()\n");
-
-	smp_ops = &bpa_beatic_smp_ops;
-
-	DBG(" <- smp_init_celleb()\n");
-}
diff -druN linux-2.6.39-libre/arch/powerpc/platforms/cell/cbe_regs.c linux-3.0-rc7-libre/arch/powerpc/platforms/cell/cbe_regs.c
--- linux-2.6.39-libre/arch/powerpc/platforms/cell/cbe_regs.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/platforms/cell/cbe_regs.c	2011-07-11 19:51:52.000000000 -0400
@@ -45,8 +45,8 @@
 	unsigned int cbe_id;
 } cbe_thread_map[NR_CPUS];
 
-static cpumask_t cbe_local_mask[MAX_CBE] = { [0 ... MAX_CBE-1] = CPU_MASK_NONE };
-static cpumask_t cbe_first_online_cpu = CPU_MASK_NONE;
+static cpumask_t cbe_local_mask[MAX_CBE] = { [0 ... MAX_CBE-1] = {CPU_BITS_NONE} };
+static cpumask_t cbe_first_online_cpu = { CPU_BITS_NONE };
 
 static struct cbe_regs_map *cbe_find_map(struct device_node *np)
 {
@@ -159,7 +159,8 @@
 
 u32 cbe_node_to_cpu(int node)
 {
-	return find_first_bit( (unsigned long *) &cbe_local_mask[node], sizeof(cpumask_t));
+	return cpumask_first(&cbe_local_mask[node]);
+
 }
 EXPORT_SYMBOL_GPL(cbe_node_to_cpu);
 
@@ -268,9 +269,9 @@
 				thread->regs = map;
 				thread->cbe_id = cbe_id;
 				map->be_node = thread->be_node;
-				cpu_set(i, cbe_local_mask[cbe_id]);
+				cpumask_set_cpu(i, &cbe_local_mask[cbe_id]);
 				if(thread->thread_id == 0)
-					cpu_set(i, cbe_first_online_cpu);
+					cpumask_set_cpu(i, &cbe_first_online_cpu);
 			}
 		}
 
diff -druN linux-2.6.39-libre/arch/powerpc/platforms/cell/celleb_pci.c linux-3.0-rc7-libre/arch/powerpc/platforms/cell/celleb_pci.c
--- linux-2.6.39-libre/arch/powerpc/platforms/cell/celleb_pci.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/platforms/cell/celleb_pci.c	2011-07-11 19:51:52.000000000 -0400
@@ -41,7 +41,6 @@
 #include <asm/pci-bridge.h>
 #include <asm/ppc-pci.h>
 
-#include "io-workarounds.h"
 #include "celleb_pci.h"
 
 #define MAX_PCI_DEVICES    32
@@ -320,7 +319,7 @@
 
 	size = 256;
 	config = &private->fake_config[devno][fn];
-	*config = alloc_maybe_bootmem(size, GFP_KERNEL);
+	*config = zalloc_maybe_bootmem(size, GFP_KERNEL);
 	if (*config == NULL) {
 		printk(KERN_ERR "PCI: "
 		       "not enough memory for fake configuration space\n");
@@ -331,7 +330,7 @@
 
 	size = sizeof(struct celleb_pci_resource);
 	res = &private->res[devno][fn];
-	*res = alloc_maybe_bootmem(size, GFP_KERNEL);
+	*res = zalloc_maybe_bootmem(size, GFP_KERNEL);
 	if (*res == NULL) {
 		printk(KERN_ERR
 		       "PCI: not enough memory for resource data space\n");
@@ -432,7 +431,7 @@
 static void __init celleb_alloc_private_mem(struct pci_controller *hose)
 {
 	hose->private_data =
-		alloc_maybe_bootmem(sizeof(struct celleb_pci_private),
+		zalloc_maybe_bootmem(sizeof(struct celleb_pci_private),
 			GFP_KERNEL);
 }
 
@@ -469,18 +468,6 @@
 	},
 };
 
-static int __init celleb_io_workaround_init(struct pci_controller *phb,
-					    struct celleb_phb_spec *phb_spec)
-{
-	if (phb_spec->ops) {
-		iowa_register_bus(phb, phb_spec->ops, phb_spec->iowa_init,
-				  phb_spec->iowa_data);
-		io_workaround_init();
-	}
-
-	return 0;
-}
-
 int __init celleb_setup_phb(struct pci_controller *phb)
 {
 	struct device_node *dev = phb->dn;
@@ -500,7 +487,11 @@
 	if (rc)
 		return 1;
 
-	return celleb_io_workaround_init(phb, phb_spec);
+	if (phb_spec->ops)
+		iowa_register_bus(phb, phb_spec->ops,
+				  phb_spec->iowa_init,
+				  phb_spec->iowa_data);
+	return 0;
 }
 
 int celleb_pci_probe_mode(struct pci_bus *bus)
diff -druN linux-2.6.39-libre/arch/powerpc/platforms/cell/celleb_pci.h linux-3.0-rc7-libre/arch/powerpc/platforms/cell/celleb_pci.h
--- linux-2.6.39-libre/arch/powerpc/platforms/cell/celleb_pci.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/platforms/cell/celleb_pci.h	2011-07-11 19:51:52.000000000 -0400
@@ -26,8 +26,9 @@
 #include <asm/pci-bridge.h>
 #include <asm/prom.h>
 #include <asm/ppc-pci.h>
+#include <asm/io-workarounds.h>
 
-#include "io-workarounds.h"
+struct iowa_bus;
 
 struct celleb_phb_spec {
 	int (*setup)(struct device_node *, struct pci_controller *);
diff -druN linux-2.6.39-libre/arch/powerpc/platforms/cell/celleb_setup.c linux-3.0-rc7-libre/arch/powerpc/platforms/cell/celleb_setup.c
--- linux-2.6.39-libre/arch/powerpc/platforms/cell/celleb_setup.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/platforms/cell/celleb_setup.c	2011-07-11 19:51:52.000000000 -0400
@@ -128,10 +128,6 @@
 	spu_management_ops	= &spu_management_of_ops;
 #endif
 
-#ifdef CONFIG_SMP
-	smp_init_celleb();
-#endif
-
 	celleb_setup_arch_common();
 }
 
diff -druN linux-2.6.39-libre/arch/powerpc/platforms/cell/interrupt.c linux-3.0-rc7-libre/arch/powerpc/platforms/cell/interrupt.c
--- linux-2.6.39-libre/arch/powerpc/platforms/cell/interrupt.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/platforms/cell/interrupt.c	2011-07-11 19:51:52.000000000 -0400
@@ -176,14 +176,14 @@
 #ifdef CONFIG_SMP
 
 /* Use the highest interrupt priorities for IPI */
-static inline int iic_ipi_to_irq(int ipi)
+static inline int iic_msg_to_irq(int msg)
 {
-	return IIC_IRQ_TYPE_IPI + 0xf - ipi;
+	return IIC_IRQ_TYPE_IPI + 0xf - msg;
 }
 
-void iic_cause_IPI(int cpu, int mesg)
+void iic_message_pass(int cpu, int msg)
 {
-	out_be64(&per_cpu(cpu_iic, cpu).regs->generate, (0xf - mesg) << 4);
+	out_be64(&per_cpu(cpu_iic, cpu).regs->generate, (0xf - msg) << 4);
 }
 
 struct irq_host *iic_get_irq_host(int node)
@@ -192,38 +192,31 @@
 }
 EXPORT_SYMBOL_GPL(iic_get_irq_host);
 
-static irqreturn_t iic_ipi_action(int irq, void *dev_id)
-{
-	int ipi = (int)(long)dev_id;
-
-	smp_message_recv(ipi);
-
-	return IRQ_HANDLED;
-}
-static void iic_request_ipi(int ipi, const char *name)
+static void iic_request_ipi(int msg)
 {
 	int virq;
 
-	virq = irq_create_mapping(iic_host, iic_ipi_to_irq(ipi));
+	virq = irq_create_mapping(iic_host, iic_msg_to_irq(msg));
 	if (virq == NO_IRQ) {
 		printk(KERN_ERR
-		       "iic: failed to map IPI %s\n", name);
+		       "iic: failed to map IPI %s\n", smp_ipi_name[msg]);
 		return;
 	}
-	if (request_irq(virq, iic_ipi_action, IRQF_DISABLED, name,
-			(void *)(long)ipi))
-		printk(KERN_ERR
-		       "iic: failed to request IPI %s\n", name);
+
+	/*
+	 * If smp_request_message_ipi encounters an error it will notify
+	 * the error.  If a message is not needed it will return non-zero.
+	 */
+	if (smp_request_message_ipi(virq, msg))
+		irq_dispose_mapping(virq);
 }
 
 void iic_request_IPIs(void)
 {
-	iic_request_ipi(PPC_MSG_CALL_FUNCTION, "IPI-call");
-	iic_request_ipi(PPC_MSG_RESCHEDULE, "IPI-resched");
-	iic_request_ipi(PPC_MSG_CALL_FUNC_SINGLE, "IPI-call-single");
-#ifdef CONFIG_DEBUGGER
-	iic_request_ipi(PPC_MSG_DEBUGGER_BREAK, "IPI-debug");
-#endif /* CONFIG_DEBUGGER */
+	iic_request_ipi(PPC_MSG_CALL_FUNCTION);
+	iic_request_ipi(PPC_MSG_RESCHEDULE);
+	iic_request_ipi(PPC_MSG_CALL_FUNC_SINGLE);
+	iic_request_ipi(PPC_MSG_DEBUGGER_BREAK);
 }
 
 #endif /* CONFIG_SMP */
diff -druN linux-2.6.39-libre/arch/powerpc/platforms/cell/interrupt.h linux-3.0-rc7-libre/arch/powerpc/platforms/cell/interrupt.h
--- linux-2.6.39-libre/arch/powerpc/platforms/cell/interrupt.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/platforms/cell/interrupt.h	2011-07-11 19:51:52.000000000 -0400
@@ -75,7 +75,7 @@
 };
 
 extern void iic_init_IRQ(void);
-extern void iic_cause_IPI(int cpu, int mesg);
+extern void iic_message_pass(int cpu, int msg);
 extern void iic_request_IPIs(void);
 extern void iic_setup_cpu(void);
 
diff -druN linux-2.6.39-libre/arch/powerpc/platforms/cell/io-workarounds.c linux-3.0-rc7-libre/arch/powerpc/platforms/cell/io-workarounds.c
--- linux-2.6.39-libre/arch/powerpc/platforms/cell/io-workarounds.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/platforms/cell/io-workarounds.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,185 +0,0 @@
-/*
- * Support PCI IO workaround
- *
- *  Copyright (C) 2006 Benjamin Herrenschmidt <benh@kernel.crashing.org>
- *		       IBM, Corp.
- *  (C) Copyright 2007-2008 TOSHIBA 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.
- */
-#undef DEBUG
-
-#include <linux/kernel.h>
-
-#include <asm/io.h>
-#include <asm/machdep.h>
-#include <asm/pgtable.h>
-#include <asm/ppc-pci.h>
-
-#include "io-workarounds.h"
-
-#define IOWA_MAX_BUS	8
-
-static struct iowa_bus iowa_busses[IOWA_MAX_BUS];
-static unsigned int iowa_bus_count;
-
-static struct iowa_bus *iowa_pci_find(unsigned long vaddr, unsigned long paddr)
-{
-	int i, j;
-	struct resource *res;
-	unsigned long vstart, vend;
-
-	for (i = 0; i < iowa_bus_count; i++) {
-		struct iowa_bus *bus = &iowa_busses[i];
-		struct pci_controller *phb = bus->phb;
-
-		if (vaddr) {
-			vstart = (unsigned long)phb->io_base_virt;
-			vend = vstart + phb->pci_io_size - 1;
-			if ((vaddr >= vstart) && (vaddr <= vend))
-				return bus;
-		}
-
-		if (paddr)
-			for (j = 0; j < 3; j++) {
-				res = &phb->mem_resources[j];
-				if (paddr >= res->start && paddr <= res->end)
-					return bus;
-			}
-	}
-
-	return NULL;
-}
-
-struct iowa_bus *iowa_mem_find_bus(const PCI_IO_ADDR addr)
-{
-	struct iowa_bus *bus;
-	int token;
-
-	token = PCI_GET_ADDR_TOKEN(addr);
-
-	if (token && token <= iowa_bus_count)
-		bus = &iowa_busses[token - 1];
-	else {
-		unsigned long vaddr, paddr;
-		pte_t *ptep;
-
-		vaddr = (unsigned long)PCI_FIX_ADDR(addr);
-		if (vaddr < PHB_IO_BASE || vaddr >= PHB_IO_END)
-			return NULL;
-
-		ptep = find_linux_pte(init_mm.pgd, vaddr);
-		if (ptep == NULL)
-			paddr = 0;
-		else
-			paddr = pte_pfn(*ptep) << PAGE_SHIFT;
-		bus = iowa_pci_find(vaddr, paddr);
-
-		if (bus == NULL)
-			return NULL;
-	}
-
-	return bus;
-}
-
-struct iowa_bus *iowa_pio_find_bus(unsigned long port)
-{
-	unsigned long vaddr = (unsigned long)pci_io_base + port;
-	return iowa_pci_find(vaddr, 0);
-}
-
-
-#define DEF_PCI_AC_RET(name, ret, at, al, space, aa)		\
-static ret iowa_##name at					\
-{								\
-	struct iowa_bus *bus;					\
-	bus = iowa_##space##_find_bus(aa);			\
-	if (bus && bus->ops && bus->ops->name)			\
-		return bus->ops->name al;			\
-	return __do_##name al;					\
-}
-
-#define DEF_PCI_AC_NORET(name, at, al, space, aa)		\
-static void iowa_##name at					\
-{								\
-	struct iowa_bus *bus;					\
-	bus = iowa_##space##_find_bus(aa);			\
-	if (bus && bus->ops && bus->ops->name) {		\
-		bus->ops->name al;				\
-		return;						\
-	}							\
-	__do_##name al;						\
-}
-
-#include <asm/io-defs.h>
-
-#undef DEF_PCI_AC_RET
-#undef DEF_PCI_AC_NORET
-
-static const struct ppc_pci_io __devinitconst iowa_pci_io = {
-
-#define DEF_PCI_AC_RET(name, ret, at, al, space, aa)	.name = iowa_##name,
-#define DEF_PCI_AC_NORET(name, at, al, space, aa)	.name = iowa_##name,
-
-#include <asm/io-defs.h>
-
-#undef DEF_PCI_AC_RET
-#undef DEF_PCI_AC_NORET
-
-};
-
-static void __iomem *iowa_ioremap(phys_addr_t addr, unsigned long size,
-				  unsigned long flags, void *caller)
-{
-	struct iowa_bus *bus;
-	void __iomem *res = __ioremap_caller(addr, size, flags, caller);
-	int busno;
-
-	bus = iowa_pci_find(0, (unsigned long)addr);
-	if (bus != NULL) {
-		busno = bus - iowa_busses;
-		PCI_SET_ADDR_TOKEN(res, busno + 1);
-	}
-	return res;
-}
-
-/* Regist new bus to support workaround */
-void __devinit iowa_register_bus(struct pci_controller *phb,
-			struct ppc_pci_io *ops,
-			int (*initfunc)(struct iowa_bus *, void *), void *data)
-{
-	struct iowa_bus *bus;
-	struct device_node *np = phb->dn;
-
-	if (iowa_bus_count >= IOWA_MAX_BUS) {
-		pr_err("IOWA:Too many pci bridges, "
-		       "workarounds disabled for %s\n", np->full_name);
-		return;
-	}
-
-	bus = &iowa_busses[iowa_bus_count];
-	bus->phb = phb;
-	bus->ops = ops;
-
-	if (initfunc)
-		if ((*initfunc)(bus, data))
-			return;
-
-	iowa_bus_count++;
-
-	pr_debug("IOWA:[%d]Add bus, %s.\n", iowa_bus_count-1, np->full_name);
-}
-
-/* enable IO workaround */
-void __devinit io_workaround_init(void)
-{
-	static int io_workaround_inited;
-
-	if (io_workaround_inited)
-		return;
-	ppc_pci_io = iowa_pci_io;
-	ppc_md.ioremap = iowa_ioremap;
-	io_workaround_inited = 1;
-}
diff -druN linux-2.6.39-libre/arch/powerpc/platforms/cell/io-workarounds.h linux-3.0-rc7-libre/arch/powerpc/platforms/cell/io-workarounds.h
--- linux-2.6.39-libre/arch/powerpc/platforms/cell/io-workarounds.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/platforms/cell/io-workarounds.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,49 +0,0 @@
-/*
- * Support PCI IO workaround
- *
- * (C) Copyright 2007-2008 TOSHIBA 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.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#ifndef _IO_WORKAROUNDS_H
-#define _IO_WORKAROUNDS_H
-
-#include <linux/io.h>
-#include <asm/pci-bridge.h>
-
-/* Bus info */
-struct iowa_bus {
-	struct pci_controller *phb;
-	struct ppc_pci_io *ops;
-	void   *private;
-};
-
-void __devinit io_workaround_init(void);
-void __devinit iowa_register_bus(struct pci_controller *, struct ppc_pci_io *,
-				 int (*)(struct iowa_bus *, void *), void *);
-struct iowa_bus *iowa_mem_find_bus(const PCI_IO_ADDR);
-struct iowa_bus *iowa_pio_find_bus(unsigned long);
-
-extern struct ppc_pci_io spiderpci_ops;
-extern int spiderpci_iowa_init(struct iowa_bus *, void *);
-
-#define SPIDER_PCI_REG_BASE		0xd000
-#define SPIDER_PCI_REG_SIZE		0x1000
-#define SPIDER_PCI_VCI_CNTL_STAT	0x0110
-#define SPIDER_PCI_DUMMY_READ		0x0810
-#define SPIDER_PCI_DUMMY_READ_BASE	0x0814
-
-#endif /* _IO_WORKAROUNDS_H */
diff -druN linux-2.6.39-libre/arch/powerpc/platforms/cell/Kconfig linux-3.0-rc7-libre/arch/powerpc/platforms/cell/Kconfig
--- linux-2.6.39-libre/arch/powerpc/platforms/cell/Kconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/platforms/cell/Kconfig	2011-07-11 19:51:52.000000000 -0400
@@ -6,7 +6,8 @@
 	bool
 	select PPC_CELL
 	select PPC_DCR_MMIO
-	select PPC_INDIRECT_IO
+	select PPC_INDIRECT_PIO
+	select PPC_INDIRECT_MMIO
 	select PPC_NATIVE
 	select PPC_RTAS
 	select IRQ_EDGE_EOI_HANDLER
@@ -15,6 +16,7 @@
 	bool
 	select PPC_CELL_COMMON
 	select MPIC
+	select PPC_IO_WORKAROUNDS
 	select IBM_NEW_EMAC_EMAC4
 	select IBM_NEW_EMAC_RGMII
 	select IBM_NEW_EMAC_ZMII #test only
diff -druN linux-2.6.39-libre/arch/powerpc/platforms/cell/Makefile linux-3.0-rc7-libre/arch/powerpc/platforms/cell/Makefile
--- linux-2.6.39-libre/arch/powerpc/platforms/cell/Makefile	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/platforms/cell/Makefile	2011-07-11 19:51:52.000000000 -0400
@@ -1,7 +1,7 @@
 obj-$(CONFIG_PPC_CELL_COMMON)		+= cbe_regs.o interrupt.o pervasive.o
 
 obj-$(CONFIG_PPC_CELL_NATIVE)		+= iommu.o setup.o spider-pic.o \
-					   pmu.o io-workarounds.o spider-pci.o
+					   pmu.o spider-pci.o
 obj-$(CONFIG_CBE_RAS)			+= ras.o
 
 obj-$(CONFIG_CBE_THERM)			+= cbe_thermal.o
@@ -39,11 +39,10 @@
 					   celleb_pci.o celleb_scc_epci.o \
 					   celleb_scc_pciex.o \
 					   celleb_scc_uhc.o \
-					   io-workarounds.o spider-pci.o \
-					   beat.o beat_htab.o beat_hvCall.o \
-					   beat_interrupt.o beat_iommu.o
+					   spider-pci.o beat.o beat_htab.o \
+					   beat_hvCall.o beat_interrupt.o \
+					   beat_iommu.o
 
-obj-$(CONFIG_SMP)			+= beat_smp.o
 obj-$(CONFIG_PPC_UDBG_BEAT)		+= beat_udbg.o
 obj-$(CONFIG_SERIAL_TXX9)		+= celleb_scc_sio.o
 obj-$(CONFIG_SPU_BASE)			+= beat_spu_priv1.o
diff -druN linux-2.6.39-libre/arch/powerpc/platforms/cell/qpace_setup.c linux-3.0-rc7-libre/arch/powerpc/platforms/cell/qpace_setup.c
--- linux-2.6.39-libre/arch/powerpc/platforms/cell/qpace_setup.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/platforms/cell/qpace_setup.c	2011-07-11 19:51:52.000000000 -0400
@@ -42,7 +42,6 @@
 #include "interrupt.h"
 #include "pervasive.h"
 #include "ras.h"
-#include "io-workarounds.h"
 
 static void qpace_show_cpuinfo(struct seq_file *m)
 {
diff -druN linux-2.6.39-libre/arch/powerpc/platforms/cell/setup.c linux-3.0-rc7-libre/arch/powerpc/platforms/cell/setup.c
--- linux-2.6.39-libre/arch/powerpc/platforms/cell/setup.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/platforms/cell/setup.c	2011-07-11 19:51:52.000000000 -0400
@@ -51,11 +51,11 @@
 #include <asm/udbg.h>
 #include <asm/mpic.h>
 #include <asm/cell-regs.h>
+#include <asm/io-workarounds.h>
 
 #include "interrupt.h"
 #include "pervasive.h"
 #include "ras.h"
-#include "io-workarounds.h"
 
 #ifdef DEBUG
 #define DBG(fmt...) udbg_printf(fmt)
@@ -136,8 +136,6 @@
 
 	iowa_register_bus(phb, &spiderpci_ops, &spiderpci_iowa_init,
 				  (void *)SPIDER_PCI_REG_BASE);
-	io_workaround_init();
-
 	return 0;
 }
 
diff -druN linux-2.6.39-libre/arch/powerpc/platforms/cell/smp.c linux-3.0-rc7-libre/arch/powerpc/platforms/cell/smp.c
--- linux-2.6.39-libre/arch/powerpc/platforms/cell/smp.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/platforms/cell/smp.c	2011-07-11 19:51:52.000000000 -0400
@@ -77,7 +77,7 @@
 	unsigned int pcpu;
 	int start_cpu;
 
-	if (cpu_isset(lcpu, of_spin_map))
+	if (cpumask_test_cpu(lcpu, &of_spin_map))
 		/* Already started by OF and sitting in spin loop */
 		return 1;
 
@@ -103,27 +103,11 @@
 	return 1;
 }
 
-static void smp_iic_message_pass(int target, int msg)
-{
-	unsigned int i;
-
-	if (target < NR_CPUS) {
-		iic_cause_IPI(target, msg);
-	} else {
-		for_each_online_cpu(i) {
-			if (target == MSG_ALL_BUT_SELF
-			    && i == smp_processor_id())
-				continue;
-			iic_cause_IPI(i, msg);
-		}
-	}
-}
-
 static int __init smp_iic_probe(void)
 {
 	iic_request_IPIs();
 
-	return cpus_weight(cpu_possible_map);
+	return cpumask_weight(cpu_possible_mask);
 }
 
 static void __devinit smp_cell_setup_cpu(int cpu)
@@ -137,12 +121,12 @@
 	mtspr(SPRN_DABRX, DABRX_KERNEL | DABRX_USER);
 }
 
-static void __devinit smp_cell_kick_cpu(int nr)
+static int __devinit smp_cell_kick_cpu(int nr)
 {
 	BUG_ON(nr < 0 || nr >= NR_CPUS);
 
 	if (!smp_startup_cpu(nr))
-		return;
+		return -ENOENT;
 
 	/*
 	 * The processor is currently spinning, waiting for the
@@ -150,6 +134,8 @@
 	 * the processor will continue on to secondary_start
 	 */
 	paca[nr].cpu_start = 1;
+
+	return 0;
 }
 
 static int smp_cell_cpu_bootable(unsigned int nr)
@@ -166,7 +152,7 @@
 	return 1;
 }
 static struct smp_ops_t bpa_iic_smp_ops = {
-	.message_pass	= smp_iic_message_pass,
+	.message_pass	= iic_message_pass,
 	.probe		= smp_iic_probe,
 	.kick_cpu	= smp_cell_kick_cpu,
 	.setup_cpu	= smp_cell_setup_cpu,
@@ -186,13 +172,12 @@
 	if (cpu_has_feature(CPU_FTR_SMT)) {
 		for_each_present_cpu(i) {
 			if (cpu_thread_in_core(i) == 0)
-				cpu_set(i, of_spin_map);
+				cpumask_set_cpu(i, &of_spin_map);
 		}
-	} else {
-		of_spin_map = cpu_present_map;
-	}
+	} else
+		cpumask_copy(&of_spin_map, cpu_present_mask);
 
-	cpu_clear(boot_cpuid, of_spin_map);
+	cpumask_clear_cpu(boot_cpuid, &of_spin_map);
 
 	/* Non-lpar has additional take/give timebase */
 	if (rtas_token("freeze-time-base") != RTAS_UNKNOWN_SERVICE) {
diff -druN linux-2.6.39-libre/arch/powerpc/platforms/cell/spider-pci.c linux-3.0-rc7-libre/arch/powerpc/platforms/cell/spider-pci.c
--- linux-2.6.39-libre/arch/powerpc/platforms/cell/spider-pci.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/platforms/cell/spider-pci.c	2011-07-11 19:51:52.000000000 -0400
@@ -27,8 +27,7 @@
 
 #include <asm/ppc-pci.h>
 #include <asm/pci-bridge.h>
-
-#include "io-workarounds.h"
+#include <asm/io-workarounds.h>
 
 #define SPIDER_PCI_DISABLE_PREFETCH
 
diff -druN linux-2.6.39-libre/arch/powerpc/platforms/cell/spider-pic.c linux-3.0-rc7-libre/arch/powerpc/platforms/cell/spider-pic.c
--- linux-2.6.39-libre/arch/powerpc/platforms/cell/spider-pic.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/platforms/cell/spider-pic.c	2011-07-11 19:51:52.000000000 -0400
@@ -68,9 +68,9 @@
 };
 static struct spider_pic spider_pics[SPIDER_CHIP_COUNT];
 
-static struct spider_pic *spider_virq_to_pic(unsigned int virq)
+static struct spider_pic *spider_irq_data_to_pic(struct irq_data *d)
 {
-	return irq_map[virq].host->host_data;
+	return irq_data_get_irq_chip_data(d);
 }
 
 static void __iomem *spider_get_irq_config(struct spider_pic *pic,
@@ -81,24 +81,24 @@
 
 static void spider_unmask_irq(struct irq_data *d)
 {
-	struct spider_pic *pic = spider_virq_to_pic(d->irq);
-	void __iomem *cfg = spider_get_irq_config(pic, irq_map[d->irq].hwirq);
+	struct spider_pic *pic = spider_irq_data_to_pic(d);
+	void __iomem *cfg = spider_get_irq_config(pic, irqd_to_hwirq(d));
 
 	out_be32(cfg, in_be32(cfg) | 0x30000000u);
 }
 
 static void spider_mask_irq(struct irq_data *d)
 {
-	struct spider_pic *pic = spider_virq_to_pic(d->irq);
-	void __iomem *cfg = spider_get_irq_config(pic, irq_map[d->irq].hwirq);
+	struct spider_pic *pic = spider_irq_data_to_pic(d);
+	void __iomem *cfg = spider_get_irq_config(pic, irqd_to_hwirq(d));
 
 	out_be32(cfg, in_be32(cfg) & ~0x30000000u);
 }
 
 static void spider_ack_irq(struct irq_data *d)
 {
-	struct spider_pic *pic = spider_virq_to_pic(d->irq);
-	unsigned int src = irq_map[d->irq].hwirq;
+	struct spider_pic *pic = spider_irq_data_to_pic(d);
+	unsigned int src = irqd_to_hwirq(d);
 
 	/* Reset edge detection logic if necessary
 	 */
@@ -116,8 +116,8 @@
 static int spider_set_irq_type(struct irq_data *d, unsigned int type)
 {
 	unsigned int sense = type & IRQ_TYPE_SENSE_MASK;
-	struct spider_pic *pic = spider_virq_to_pic(d->irq);
-	unsigned int hw = irq_map[d->irq].hwirq;
+	struct spider_pic *pic = spider_irq_data_to_pic(d);
+	unsigned int hw = irqd_to_hwirq(d);
 	void __iomem *cfg = spider_get_irq_config(pic, hw);
 	u32 old_mask;
 	u32 ic;
@@ -171,6 +171,7 @@
 static int spider_host_map(struct irq_host *h, unsigned int virq,
 			irq_hw_number_t hw)
 {
+	irq_set_chip_data(virq, h->host_data);
 	irq_set_chip_and_handler(virq, &spider_pic, handle_level_irq);
 
 	/* Set default irq type */
diff -druN linux-2.6.39-libre/arch/powerpc/platforms/cell/spu_base.c linux-3.0-rc7-libre/arch/powerpc/platforms/cell/spu_base.c
--- linux-2.6.39-libre/arch/powerpc/platforms/cell/spu_base.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/platforms/cell/spu_base.c	2011-07-11 19:51:52.000000000 -0400
@@ -32,6 +32,7 @@
 #include <linux/io.h>
 #include <linux/mutex.h>
 #include <linux/linux_logo.h>
+#include <linux/syscore_ops.h>
 #include <asm/spu.h>
 #include <asm/spu_priv1.h>
 #include <asm/spu_csa.h>
@@ -521,18 +522,8 @@
 }
 EXPORT_SYMBOL_GPL(spu_init_channels);
 
-static int spu_shutdown(struct sys_device *sysdev)
-{
-	struct spu *spu = container_of(sysdev, struct spu, sysdev);
-
-	spu_free_irqs(spu);
-	spu_destroy_spu(spu);
-	return 0;
-}
-
 static struct sysdev_class spu_sysdev_class = {
 	.name = "spu",
-	.shutdown = spu_shutdown,
 };
 
 int spu_add_sysdev_attr(struct sysdev_attribute *attr)
@@ -797,6 +788,22 @@
 }
 #endif
 
+static void spu_shutdown(void)
+{
+	struct spu *spu;
+
+	mutex_lock(&spu_full_list_mutex);
+	list_for_each_entry(spu, &spu_full_list, full_list) {
+		spu_free_irqs(spu);
+		spu_destroy_spu(spu);
+	}
+	mutex_unlock(&spu_full_list_mutex);
+}
+
+static struct syscore_ops spu_syscore_ops = {
+	.shutdown = spu_shutdown,
+};
+
 static int __init init_spu_base(void)
 {
 	int i, ret = 0;
@@ -830,6 +837,7 @@
 	crash_register_spus(&spu_full_list);
 	mutex_unlock(&spu_full_list_mutex);
 	spu_add_sysdev_attr(&attr_stat);
+	register_syscore_ops(&spu_syscore_ops);
 
 	spu_init_affinity();
 
diff -druN linux-2.6.39-libre/arch/powerpc/platforms/cell/spufs/sched.c linux-3.0-rc7-libre/arch/powerpc/platforms/cell/spufs/sched.c
--- linux-2.6.39-libre/arch/powerpc/platforms/cell/spufs/sched.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/platforms/cell/spufs/sched.c	2011-07-11 19:51:52.000000000 -0400
@@ -141,7 +141,7 @@
 	 * runqueue. The context will be rescheduled on the proper node
 	 * if it is timesliced or preempted.
 	 */
-	ctx->cpus_allowed = current->cpus_allowed;
+	cpumask_copy(&ctx->cpus_allowed, tsk_cpus_allowed(current));
 
 	/* Save the current cpu id for spu interrupt routing. */
 	ctx->last_ran = raw_smp_processor_id();
diff -druN linux-2.6.39-libre/arch/powerpc/platforms/chrp/smp.c linux-3.0-rc7-libre/arch/powerpc/platforms/chrp/smp.c
--- linux-2.6.39-libre/arch/powerpc/platforms/chrp/smp.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/platforms/chrp/smp.c	2011-07-11 19:51:52.000000000 -0400
@@ -30,10 +30,12 @@
 #include <asm/mpic.h>
 #include <asm/rtas.h>
 
-static void __devinit smp_chrp_kick_cpu(int nr)
+static int __devinit smp_chrp_kick_cpu(int nr)
 {
 	*(unsigned long *)KERNELBASE = nr;
 	asm volatile("dcbf 0,%0"::"r"(KERNELBASE):"memory");
+
+	return 0;
 }
 
 static void __devinit smp_chrp_setup_cpu(int cpu_nr)
diff -druN linux-2.6.39-libre/arch/powerpc/platforms/embedded6xx/flipper-pic.c linux-3.0-rc7-libre/arch/powerpc/platforms/embedded6xx/flipper-pic.c
--- linux-2.6.39-libre/arch/powerpc/platforms/embedded6xx/flipper-pic.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/platforms/embedded6xx/flipper-pic.c	2011-07-11 19:51:52.000000000 -0400
@@ -48,7 +48,7 @@
 
 static void flipper_pic_mask_and_ack(struct irq_data *d)
 {
-	int irq = virq_to_hw(d->irq);
+	int irq = irqd_to_hwirq(d);
 	void __iomem *io_base = irq_data_get_irq_chip_data(d);
 	u32 mask = 1 << irq;
 
@@ -59,7 +59,7 @@
 
 static void flipper_pic_ack(struct irq_data *d)
 {
-	int irq = virq_to_hw(d->irq);
+	int irq = irqd_to_hwirq(d);
 	void __iomem *io_base = irq_data_get_irq_chip_data(d);
 
 	/* this is at least needed for RSW */
@@ -68,7 +68,7 @@
 
 static void flipper_pic_mask(struct irq_data *d)
 {
-	int irq = virq_to_hw(d->irq);
+	int irq = irqd_to_hwirq(d);
 	void __iomem *io_base = irq_data_get_irq_chip_data(d);
 
 	clrbits32(io_base + FLIPPER_IMR, 1 << irq);
@@ -76,7 +76,7 @@
 
 static void flipper_pic_unmask(struct irq_data *d)
 {
-	int irq = virq_to_hw(d->irq);
+	int irq = irqd_to_hwirq(d);
 	void __iomem *io_base = irq_data_get_irq_chip_data(d);
 
 	setbits32(io_base + FLIPPER_IMR, 1 << irq);
@@ -107,12 +107,6 @@
 	return 0;
 }
 
-static void flipper_pic_unmap(struct irq_host *h, unsigned int irq)
-{
-	irq_set_chip_data(irq, NULL);
-	irq_set_chip(irq, NULL);
-}
-
 static int flipper_pic_match(struct irq_host *h, struct device_node *np)
 {
 	return 1;
@@ -121,7 +115,6 @@
 
 static struct irq_host_ops flipper_irq_host_ops = {
 	.map = flipper_pic_map,
-	.unmap = flipper_pic_unmap,
 	.match = flipper_pic_match,
 };
 
diff -druN linux-2.6.39-libre/arch/powerpc/platforms/embedded6xx/hlwd-pic.c linux-3.0-rc7-libre/arch/powerpc/platforms/embedded6xx/hlwd-pic.c
--- linux-2.6.39-libre/arch/powerpc/platforms/embedded6xx/hlwd-pic.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/platforms/embedded6xx/hlwd-pic.c	2011-07-11 19:51:52.000000000 -0400
@@ -43,7 +43,7 @@
 
 static void hlwd_pic_mask_and_ack(struct irq_data *d)
 {
-	int irq = virq_to_hw(d->irq);
+	int irq = irqd_to_hwirq(d);
 	void __iomem *io_base = irq_data_get_irq_chip_data(d);
 	u32 mask = 1 << irq;
 
@@ -53,7 +53,7 @@
 
 static void hlwd_pic_ack(struct irq_data *d)
 {
-	int irq = virq_to_hw(d->irq);
+	int irq = irqd_to_hwirq(d);
 	void __iomem *io_base = irq_data_get_irq_chip_data(d);
 
 	out_be32(io_base + HW_BROADWAY_ICR, 1 << irq);
@@ -61,7 +61,7 @@
 
 static void hlwd_pic_mask(struct irq_data *d)
 {
-	int irq = virq_to_hw(d->irq);
+	int irq = irqd_to_hwirq(d);
 	void __iomem *io_base = irq_data_get_irq_chip_data(d);
 
 	clrbits32(io_base + HW_BROADWAY_IMR, 1 << irq);
@@ -69,7 +69,7 @@
 
 static void hlwd_pic_unmask(struct irq_data *d)
 {
-	int irq = virq_to_hw(d->irq);
+	int irq = irqd_to_hwirq(d);
 	void __iomem *io_base = irq_data_get_irq_chip_data(d);
 
 	setbits32(io_base + HW_BROADWAY_IMR, 1 << irq);
@@ -100,15 +100,8 @@
 	return 0;
 }
 
-static void hlwd_pic_unmap(struct irq_host *h, unsigned int irq)
-{
-	irq_set_chip_data(irq, NULL);
-	irq_set_chip(irq, NULL);
-}
-
 static struct irq_host_ops hlwd_irq_host_ops = {
 	.map = hlwd_pic_map,
-	.unmap = hlwd_pic_unmap,
 };
 
 static unsigned int __hlwd_pic_get_irq(struct irq_host *h)
diff -druN linux-2.6.39-libre/arch/powerpc/platforms/iseries/exception.S linux-3.0-rc7-libre/arch/powerpc/platforms/iseries/exception.S
--- linux-2.6.39-libre/arch/powerpc/platforms/iseries/exception.S	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/platforms/iseries/exception.S	2011-07-11 19:51:52.000000000 -0400
@@ -31,6 +31,7 @@
 #include <asm/thread_info.h>
 #include <asm/ptrace.h>
 #include <asm/cputable.h>
+#include <asm/mmu.h>
 
 #include "exception.h"
 
@@ -60,29 +61,31 @@
 /* Spin on __secondary_hold_spinloop until it is updated by the boot cpu. */
 /* In the UP case we'll yield() later, and we will not access the paca anyway */
 #ifdef CONFIG_SMP
-1:
+iSeries_secondary_wait_paca:
 	HMT_LOW
 	LOAD_REG_ADDR(r23, __secondary_hold_spinloop)
 	ld	r23,0(r23)
-	sync
-	LOAD_REG_ADDR(r3,current_set)
-	sldi	r28,r24,3		/* get current_set[cpu#] */
-	ldx	r3,r3,r28
-	addi	r1,r3,THREAD_SIZE
-	subi	r1,r1,STACK_FRAME_OVERHEAD
 
-	cmpwi	0,r23,0			/* Keep poking the Hypervisor until */
-	bne	2f			/* we're released */
-	/* Let the Hypervisor know we are alive */
+	cmpdi	0,r23,0
+	bne	2f			/* go on when the master is ready */
+
+	/* Keep poking the Hypervisor until we're released */
 	/* 8002 is a call to HvCallCfg::getLps, a harmless Hypervisor function */
 	lis	r3,0x8002
 	rldicr	r3,r3,32,15		/* r0 = (r3 << 32) & 0xffff000000000000 */
 	li	r0,-1			/* r0=-1 indicates a Hypervisor call */
 	sc				/* Invoke the hypervisor via a system call */
-	b	1b
-#endif
+	b	iSeries_secondary_wait_paca
 
 2:
+	HMT_MEDIUM
+	sync
+
+	LOAD_REG_ADDR(r3, nr_cpu_ids)	/* get number of pacas allocated */
+	lwz	r3,0(r3)		/* nr_cpus= or NR_CPUS can limit */
+	cmpld	0,r24,r3		/* is our cpu number allocated? */
+	bge	iSeries_secondary_yield	/* no, yield forever */
+
 	/* Load our paca now that it's been allocated */
 	LOAD_REG_ADDR(r13, paca)
 	ld	r13,0(r13)
@@ -93,10 +96,24 @@
 	ori	r23,r23,MSR_RI
 	mtmsrd	r23			/* RI on */
 
-	HMT_LOW
-#ifdef CONFIG_SMP
+iSeries_secondary_smp_loop:
 	lbz	r23,PACAPROCSTART(r13)	/* Test if this processor
 					 * should start */
+	cmpwi	0,r23,0
+	bne	3f			/* go on when we are told */
+
+	HMT_LOW
+	/* Let the Hypervisor know we are alive */
+	/* 8002 is a call to HvCallCfg::getLps, a harmless Hypervisor function */
+	lis	r3,0x8002
+	rldicr	r3,r3,32,15		/* r0 = (r3 << 32) & 0xffff000000000000 */
+	li	r0,-1			/* r0=-1 indicates a Hypervisor call */
+	sc				/* Invoke the hypervisor via a system call */
+	mfspr	r13,SPRN_SPRG_PACA	/* Put r13 back ???? */
+	b	iSeries_secondary_smp_loop /* wait for signal to start */
+
+3:
+	HMT_MEDIUM
 	sync
 	LOAD_REG_ADDR(r3,current_set)
 	sldi	r28,r24,3		/* get current_set[cpu#] */
@@ -104,27 +121,22 @@
 	addi	r1,r3,THREAD_SIZE
 	subi	r1,r1,STACK_FRAME_OVERHEAD
 
-	cmpwi	0,r23,0
-	beq	iSeries_secondary_smp_loop	/* Loop until told to go */
 	b	__secondary_start		/* Loop until told to go */
-iSeries_secondary_smp_loop:
-	/* Let the Hypervisor know we are alive */
-	/* 8002 is a call to HvCallCfg::getLps, a harmless Hypervisor function */
-	lis	r3,0x8002
-	rldicr	r3,r3,32,15		/* r0 = (r3 << 32) & 0xffff000000000000 */
-#else /* CONFIG_SMP */
+#endif /* CONFIG_SMP */
+
+iSeries_secondary_yield:
 	/* Yield the processor.  This is required for non-SMP kernels
 		which are running on multi-threaded machines. */
+	HMT_LOW
 	lis	r3,0x8000
 	rldicr	r3,r3,32,15		/* r3 = (r3 << 32) & 0xffff000000000000 */
 	addi	r3,r3,18		/* r3 = 0x8000000000000012 which is "yield" */
 	li	r4,0			/* "yield timed" */
 	li	r5,-1			/* "yield forever" */
-#endif /* CONFIG_SMP */
 	li	r0,-1			/* r0=-1 indicates a Hypervisor call */
 	sc				/* Invoke the hypervisor via a system call */
 	mfspr	r13,SPRN_SPRG_PACA	/* Put r13 back ???? */
-	b	2b			/* If SMP not configured, secondaries
+	b	iSeries_secondary_yield	/* If SMP not configured, secondaries
 					 * loop forever */
 
 /***  ISeries-LPAR interrupt handlers ***/
@@ -157,7 +169,7 @@
 FTR_SECTION_ELSE
 	EXCEPTION_PROLOG_1(PACA_EXGEN)
 	EXCEPTION_PROLOG_ISERIES_1
-ALT_FTR_SECTION_END_IFCLR(CPU_FTR_SLB)
+ALT_MMU_FTR_SECTION_END_IFCLR(MMU_FTR_SLB)
 	b	data_access_common
 
 .do_stab_bolted_iSeries:
diff -druN linux-2.6.39-libre/arch/powerpc/platforms/iseries/irq.c linux-3.0-rc7-libre/arch/powerpc/platforms/iseries/irq.c
--- linux-2.6.39-libre/arch/powerpc/platforms/iseries/irq.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/platforms/iseries/irq.c	2011-07-11 19:51:52.000000000 -0400
@@ -42,7 +42,6 @@
 #include "irq.h"
 #include "pci.h"
 #include "call_pci.h"
-#include "smp.h"
 
 #ifdef CONFIG_PCI
 
@@ -171,7 +170,7 @@
 {
 	u32 bus, dev_id, function, mask;
 	const u32 sub_bus = 0;
-	unsigned int rirq = (unsigned int)irq_map[d->irq].hwirq;
+	unsigned int rirq = (unsigned int)irqd_to_hwirq(d);
 
 	/* The IRQ has already been locked by the caller */
 	bus = REAL_IRQ_TO_BUS(rirq);
@@ -188,7 +187,7 @@
 {
 	u32 bus, dev_id, function, mask;
 	const u32 sub_bus = 0;
-	unsigned int rirq = (unsigned int)irq_map[d->irq].hwirq;
+	unsigned int rirq = (unsigned int)irqd_to_hwirq(d);
 
 	bus = REAL_IRQ_TO_BUS(rirq);
 	function = REAL_IRQ_TO_FUNC(rirq);
@@ -234,7 +233,7 @@
 {
 	u32 bus, dev_id, function, mask;
 	const u32 sub_bus = 0;
-	unsigned int rirq = (unsigned int)irq_map[d->irq].hwirq;
+	unsigned int rirq = (unsigned int)irqd_to_hwirq(d);
 
 	/* irq should be locked by the caller */
 	bus = REAL_IRQ_TO_BUS(rirq);
@@ -257,7 +256,7 @@
 {
 	u32 bus, dev_id, function, mask;
 	const u32 sub_bus = 0;
-	unsigned int rirq = (unsigned int)irq_map[d->irq].hwirq;
+	unsigned int rirq = (unsigned int)irqd_to_hwirq(d);
 
 	/* The IRQ has already been locked by the caller */
 	bus = REAL_IRQ_TO_BUS(rirq);
@@ -271,7 +270,7 @@
 
 static void iseries_end_IRQ(struct irq_data *d)
 {
-	unsigned int rirq = (unsigned int)irq_map[d->irq].hwirq;
+	unsigned int rirq = (unsigned int)irqd_to_hwirq(d);
 
 	HvCallPci_eoi(REAL_IRQ_TO_BUS(rirq), REAL_IRQ_TO_SUBBUS(rirq),
 		(REAL_IRQ_TO_IDSEL(rirq) << 4) + REAL_IRQ_TO_FUNC(rirq));
@@ -316,7 +315,7 @@
 #ifdef CONFIG_SMP
 	if (get_lppaca()->int_dword.fields.ipi_cnt) {
 		get_lppaca()->int_dword.fields.ipi_cnt = 0;
-		iSeries_smp_message_recv();
+		smp_ipi_demux();
 	}
 #endif /* CONFIG_SMP */
 	if (hvlpevent_is_pending())
diff -druN linux-2.6.39-libre/arch/powerpc/platforms/iseries/Kconfig linux-3.0-rc7-libre/arch/powerpc/platforms/iseries/Kconfig
--- linux-2.6.39-libre/arch/powerpc/platforms/iseries/Kconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/platforms/iseries/Kconfig	2011-07-11 19:51:52.000000000 -0400
@@ -1,7 +1,9 @@
 config PPC_ISERIES
 	bool "IBM Legacy iSeries"
 	depends on PPC64 && PPC_BOOK3S
-	select PPC_INDIRECT_IO
+	select PPC_SMP_MUXED_IPI
+	select PPC_INDIRECT_PIO
+	select PPC_INDIRECT_MMIO
 	select PPC_PCI_CHOICE if EXPERT
 
 menu "iSeries device drivers"
diff -druN linux-2.6.39-libre/arch/powerpc/platforms/iseries/setup.c linux-3.0-rc7-libre/arch/powerpc/platforms/iseries/setup.c
--- linux-2.6.39-libre/arch/powerpc/platforms/iseries/setup.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/platforms/iseries/setup.c	2011-07-11 19:51:52.000000000 -0400
@@ -249,7 +249,7 @@
 	unsigned long i;
 	unsigned long mem_blocks = 0;
 
-	if (cpu_has_feature(CPU_FTR_SLB))
+	if (mmu_has_feature(MMU_FTR_SLB))
 		mem_blocks = iSeries_process_Regatta_mainstore_vpd(mb_array,
 				max_entries);
 	else
@@ -634,7 +634,7 @@
 
 	hpte_init_iSeries();
 	/* iSeries does not support 16M pages */
-	cur_cpu_spec->cpu_features &= ~CPU_FTR_16M_PAGE;
+	cur_cpu_spec->mmu_features &= ~MMU_FTR_16M_PAGE;
 
 	return 1;
 }
@@ -685,6 +685,11 @@
 	powerpc_firmware_features |= FW_FEATURE_ISERIES;
 	powerpc_firmware_features |= FW_FEATURE_LPAR;
 
+#ifdef CONFIG_SMP
+	/* On iSeries we know we can never have more than 64 cpus */
+	nr_cpu_ids = max(nr_cpu_ids, 64);
+#endif
+
 	iSeries_fixup_klimit();
 
 	/*
diff -druN linux-2.6.39-libre/arch/powerpc/platforms/iseries/smp.c linux-3.0-rc7-libre/arch/powerpc/platforms/iseries/smp.c
--- linux-2.6.39-libre/arch/powerpc/platforms/iseries/smp.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/platforms/iseries/smp.c	2011-07-11 19:51:52.000000000 -0400
@@ -42,57 +42,23 @@
 #include <asm/cputable.h>
 #include <asm/system.h>
 
-#include "smp.h"
-
-static unsigned long iSeries_smp_message[NR_CPUS];
-
-void iSeries_smp_message_recv(void)
-{
-	int cpu = smp_processor_id();
-	int msg;
-
-	if (num_online_cpus() < 2)
-		return;
-
-	for (msg = 0; msg < 4; msg++)
-		if (test_and_clear_bit(msg, &iSeries_smp_message[cpu]))
-			smp_message_recv(msg);
-}
-
-static inline void smp_iSeries_do_message(int cpu, int msg)
+static void smp_iSeries_cause_ipi(int cpu, unsigned long data)
 {
-	set_bit(msg, &iSeries_smp_message[cpu]);
 	HvCall_sendIPI(&(paca[cpu]));
 }
 
-static void smp_iSeries_message_pass(int target, int msg)
-{
-	int i;
-
-	if (target < NR_CPUS)
-		smp_iSeries_do_message(target, msg);
-	else {
-		for_each_online_cpu(i) {
-			if ((target == MSG_ALL_BUT_SELF) &&
-					(i == smp_processor_id()))
-				continue;
-			smp_iSeries_do_message(i, msg);
-		}
-	}
-}
-
 static int smp_iSeries_probe(void)
 {
 	return cpumask_weight(cpu_possible_mask);
 }
 
-static void smp_iSeries_kick_cpu(int nr)
+static int smp_iSeries_kick_cpu(int nr)
 {
 	BUG_ON((nr < 0) || (nr >= NR_CPUS));
 
 	/* Verify that our partition has a processor nr */
 	if (lppaca_of(nr).dyn_proc_status >= 2)
-		return;
+		return -ENOENT;
 
 	/* The processor is currently spinning, waiting
 	 * for the cpu_start field to become non-zero
@@ -100,6 +66,8 @@
 	 * continue on to secondary_start in iSeries_head.S
 	 */
 	paca[nr].cpu_start = 1;
+
+	return 0;
 }
 
 static void __devinit smp_iSeries_setup_cpu(int nr)
@@ -107,7 +75,8 @@
 }
 
 static struct smp_ops_t iSeries_smp_ops = {
-	.message_pass = smp_iSeries_message_pass,
+	.message_pass = smp_muxed_ipi_message_pass,
+	.cause_ipi    = smp_iSeries_cause_ipi,
 	.probe        = smp_iSeries_probe,
 	.kick_cpu     = smp_iSeries_kick_cpu,
 	.setup_cpu    = smp_iSeries_setup_cpu,
diff -druN linux-2.6.39-libre/arch/powerpc/platforms/iseries/smp.h linux-3.0-rc7-libre/arch/powerpc/platforms/iseries/smp.h
--- linux-2.6.39-libre/arch/powerpc/platforms/iseries/smp.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/platforms/iseries/smp.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,6 +0,0 @@
-#ifndef _PLATFORMS_ISERIES_SMP_H
-#define _PLATFORMS_ISERIES_SMP_H
-
-extern void iSeries_smp_message_recv(void);
-
-#endif	/* _PLATFORMS_ISERIES_SMP_H */
diff -druN linux-2.6.39-libre/arch/powerpc/platforms/Kconfig linux-3.0-rc7-libre/arch/powerpc/platforms/Kconfig
--- linux-2.6.39-libre/arch/powerpc/platforms/Kconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/platforms/Kconfig	2011-07-11 19:51:52.000000000 -0400
@@ -20,6 +20,7 @@
 source "arch/powerpc/platforms/44x/Kconfig"
 source "arch/powerpc/platforms/40x/Kconfig"
 source "arch/powerpc/platforms/amigaone/Kconfig"
+source "arch/powerpc/platforms/wsp/Kconfig"
 
 config KVM_GUEST
 	bool "KVM Guest support"
@@ -56,16 +57,19 @@
 	depends on PPC_RTAS
 	default n
 
+config PPC_SMP_MUXED_IPI
+	bool
+	help
+	  Select this opton if your platform supports SMP and your
+	  interrupt controller provides less than 4 interrupts to each
+	  cpu.	This will enable the generic code to multiplex the 4
+	  messages on to one ipi.
+
 config PPC_UDBG_BEAT
 	bool "BEAT based debug console"
 	depends on PPC_CELLEB
 	default n
 
-config XICS
-	depends on PPC_PSERIES
-	bool
-	default y
-
 config IPIC
 	bool
 	default n
@@ -147,14 +151,27 @@
 	bool
 	default n
 
+config PPC_P7_NAP
+	bool
+	default n
+
 config PPC_INDIRECT_IO
 	bool
 	select GENERIC_IOMAP
-	default n
+
+config PPC_INDIRECT_PIO
+	bool
+	select PPC_INDIRECT_IO
+
+config PPC_INDIRECT_MMIO
+	bool
+	select PPC_INDIRECT_IO
+
+config PPC_IO_WORKAROUNDS
+	bool
 
 config GENERIC_IOMAP
 	bool
-	default n
 
 source "drivers/cpufreq/Kconfig"
 
diff -druN linux-2.6.39-libre/arch/powerpc/platforms/Kconfig.cputype linux-3.0-rc7-libre/arch/powerpc/platforms/Kconfig.cputype
--- linux-2.6.39-libre/arch/powerpc/platforms/Kconfig.cputype	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/platforms/Kconfig.cputype	2011-07-11 19:51:52.000000000 -0400
@@ -73,6 +73,7 @@
 config PPC_BOOK3E_64
 	bool "Embedded processors"
 	select PPC_FPU # Make it a choice ?
+	select PPC_SMP_MUXED_IPI
 
 endchoice
 
@@ -107,6 +108,10 @@
 	depends on PPC64 && PPC_BOOK3S
 	def_bool y
 
+config PPC_A2
+	bool
+	depends on PPC_BOOK3E_64
+
 config TUNE_CELL
 	bool "Optimize for Cell Broadband Engine"
 	depends on PPC64 && PPC_BOOK3S
@@ -174,6 +179,7 @@
 config PPC_FSL_BOOK3E
 	bool
 	select FSL_EMB_PERFMON
+	select PPC_SMP_MUXED_IPI
 	default y if FSL_BOOKE
 
 config PTE_64BIT
@@ -226,6 +232,24 @@
 
 	  If in doubt, say Y here.
 
+config PPC_ICSWX
+	bool "Support for PowerPC icswx coprocessor instruction"
+	depends on POWER4
+	default n
+	---help---
+
+	  This option enables kernel support for the PowerPC Initiate
+	  Coprocessor Store Word (icswx) coprocessor instruction on POWER7
+	  or newer processors.
+
+	  This option is only useful if you have a processor that supports
+	  the icswx coprocessor instruction. It does not have any effect
+	  on processors without the icswx coprocessor instruction.
+
+	  This option slightly increases kernel memory usage.
+
+	  If in doubt, say N here.
+
 config SPE
 	bool "SPE Support"
 	depends on E200 || (E500 && !PPC_E500MC)
diff -druN linux-2.6.39-libre/arch/powerpc/platforms/Makefile linux-3.0-rc7-libre/arch/powerpc/platforms/Makefile
--- linux-2.6.39-libre/arch/powerpc/platforms/Makefile	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/platforms/Makefile	2011-07-11 19:51:52.000000000 -0400
@@ -22,3 +22,4 @@
 obj-$(CONFIG_PPC_PS3)		+= ps3/
 obj-$(CONFIG_EMBEDDED6xx)	+= embedded6xx/
 obj-$(CONFIG_AMIGAONE)		+= amigaone/
+obj-$(CONFIG_PPC_WSP)		+= wsp/
diff -druN linux-2.6.39-libre/arch/powerpc/platforms/powermac/Kconfig linux-3.0-rc7-libre/arch/powerpc/platforms/powermac/Kconfig
--- linux-2.6.39-libre/arch/powerpc/platforms/powermac/Kconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/platforms/powermac/Kconfig	2011-07-11 19:51:52.000000000 -0400
@@ -18,4 +18,13 @@
 	select PPC_970_NAP
 	default y
 
-
+config PPC_PMAC32_PSURGE
+	bool "Support for powersurge upgrade cards" if EXPERT
+	depends on SMP && PPC32 && PPC_PMAC
+	select PPC_SMP_MUXED_IPI
+	default y
+	help
+	  The powersurge cpu boards can be used in the generation
+	  of powermacs that have a socket for an upgradeable cpu card,
+	  including the 7500, 8500, 9500, 9600.  Support exists for
+	  both dual and quad socket upgrade cards.
diff -druN linux-2.6.39-libre/arch/powerpc/platforms/powermac/pic.c linux-3.0-rc7-libre/arch/powerpc/platforms/powermac/pic.c
--- linux-2.6.39-libre/arch/powerpc/platforms/powermac/pic.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/platforms/powermac/pic.c	2011-07-11 19:51:52.000000000 -0400
@@ -21,7 +21,7 @@
 #include <linux/signal.h>
 #include <linux/pci.h>
 #include <linux/interrupt.h>
-#include <linux/sysdev.h>
+#include <linux/syscore_ops.h>
 #include <linux/adb.h>
 #include <linux/pmu.h>
 #include <linux/module.h>
@@ -84,7 +84,7 @@
 
 static void pmac_mask_and_ack_irq(struct irq_data *d)
 {
-	unsigned int src = irq_map[d->irq].hwirq;
+	unsigned int src = irqd_to_hwirq(d);
         unsigned long bit = 1UL << (src & 0x1f);
         int i = src >> 5;
         unsigned long flags;
@@ -106,7 +106,7 @@
 
 static void pmac_ack_irq(struct irq_data *d)
 {
-	unsigned int src = irq_map[d->irq].hwirq;
+	unsigned int src = irqd_to_hwirq(d);
         unsigned long bit = 1UL << (src & 0x1f);
         int i = src >> 5;
         unsigned long flags;
@@ -152,7 +152,7 @@
 static unsigned int pmac_startup_irq(struct irq_data *d)
 {
 	unsigned long flags;
-	unsigned int src = irq_map[d->irq].hwirq;
+	unsigned int src = irqd_to_hwirq(d);
         unsigned long bit = 1UL << (src & 0x1f);
         int i = src >> 5;
 
@@ -169,7 +169,7 @@
 static void pmac_mask_irq(struct irq_data *d)
 {
 	unsigned long flags;
-	unsigned int src = irq_map[d->irq].hwirq;
+	unsigned int src = irqd_to_hwirq(d);
 
 	raw_spin_lock_irqsave(&pmac_pic_lock, flags);
         __clear_bit(src, ppc_cached_irq_mask);
@@ -180,7 +180,7 @@
 static void pmac_unmask_irq(struct irq_data *d)
 {
 	unsigned long flags;
-	unsigned int src = irq_map[d->irq].hwirq;
+	unsigned int src = irqd_to_hwirq(d);
 
 	raw_spin_lock_irqsave(&pmac_pic_lock, flags);
 	__set_bit(src, ppc_cached_irq_mask);
@@ -193,7 +193,7 @@
 	unsigned long flags;
 
 	raw_spin_lock_irqsave(&pmac_pic_lock, flags);
-	__pmac_retrigger(irq_map[d->irq].hwirq);
+	__pmac_retrigger(irqd_to_hwirq(d));
 	raw_spin_unlock_irqrestore(&pmac_pic_lock, flags);
 	return 1;
 }
@@ -239,15 +239,12 @@
 	unsigned long bits = 0;
 	unsigned long flags;
 
-#ifdef CONFIG_SMP
-	void psurge_smp_message_recv(void);
-
-       	/* IPI's are a hack on the powersurge -- Cort */
-       	if ( smp_processor_id() != 0 ) {
-		psurge_smp_message_recv();
-		return NO_IRQ_IGNORE;	/* ignore, already handled */
+#ifdef CONFIG_PPC_PMAC32_PSURGE
+	/* IPI's are a hack on the powersurge -- Cort */
+	if (smp_processor_id() != 0) {
+		return  psurge_secondary_virq;
         }
-#endif /* CONFIG_SMP */
+#endif /* CONFIG_PPC_PMAC32_PSURGE */
 	raw_spin_lock_irqsave(&pmac_pic_lock, flags);
 	for (irq = max_real_irqs; (irq -= 32) >= 0; ) {
 		int i = irq >> 5;
@@ -677,7 +674,7 @@
 	return viaint;
 }
 
-static int pmacpic_suspend(struct sys_device *sysdev, pm_message_t state)
+static int pmacpic_suspend(void)
 {
 	int viaint = pmacpic_find_viaint();
 
@@ -698,7 +695,7 @@
         return 0;
 }
 
-static int pmacpic_resume(struct sys_device *sysdev)
+static void pmacpic_resume(void)
 {
 	int i;
 
@@ -709,39 +706,20 @@
 	for (i = 0; i < max_real_irqs; ++i)
 		if (test_bit(i, sleep_save_mask))
 			pmac_unmask_irq(irq_get_irq_data(i));
-
-	return 0;
 }
 
-#endif /* CONFIG_PM && CONFIG_PPC32 */
-
-static struct sysdev_class pmacpic_sysclass = {
-	.name = "pmac_pic",
-};
-
-static struct sys_device device_pmacpic = {
-	.id		= 0,
-	.cls		= &pmacpic_sysclass,
-};
-
-static struct sysdev_driver driver_pmacpic = {
-#if defined(CONFIG_PM) && defined(CONFIG_PPC32)
-	.suspend	= &pmacpic_suspend,
-	.resume		= &pmacpic_resume,
-#endif /* CONFIG_PM && CONFIG_PPC32 */
+static struct syscore_ops pmacpic_syscore_ops = {
+	.suspend	= pmacpic_suspend,
+	.resume		= pmacpic_resume,
 };
 
-static int __init init_pmacpic_sysfs(void)
+static int __init init_pmacpic_syscore(void)
 {
-#ifdef CONFIG_PPC32
-	if (max_irqs == 0)
-		return -ENODEV;
-#endif
-	printk(KERN_DEBUG "Registering pmac pic with sysfs...\n");
-	sysdev_class_register(&pmacpic_sysclass);
-	sysdev_register(&device_pmacpic);
-	sysdev_driver_register(&pmacpic_sysclass, &driver_pmacpic);
+	if (pmac_irq_hw[0])
+		register_syscore_ops(&pmacpic_syscore_ops);
 	return 0;
 }
-machine_subsys_initcall(powermac, init_pmacpic_sysfs);
 
+machine_subsys_initcall(powermac, init_pmacpic_syscore);
+
+#endif /* CONFIG_PM && CONFIG_PPC32 */
diff -druN linux-2.6.39-libre/arch/powerpc/platforms/powermac/pic.h linux-3.0-rc7-libre/arch/powerpc/platforms/powermac/pic.h
--- linux-2.6.39-libre/arch/powerpc/platforms/powermac/pic.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/platforms/powermac/pic.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,11 +0,0 @@
-#ifndef __PPC_PLATFORMS_PMAC_PIC_H
-#define __PPC_PLATFORMS_PMAC_PIC_H
-
-#include <linux/irq.h>
-
-extern struct irq_chip pmac_pic;
-
-extern void pmac_pic_init(void);
-extern int pmac_get_irq(void);
-
-#endif /* __PPC_PLATFORMS_PMAC_PIC_H */
diff -druN linux-2.6.39-libre/arch/powerpc/platforms/powermac/pmac.h linux-3.0-rc7-libre/arch/powerpc/platforms/powermac/pmac.h
--- linux-2.6.39-libre/arch/powerpc/platforms/powermac/pmac.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/platforms/powermac/pmac.h	2011-07-11 19:51:52.000000000 -0400
@@ -33,6 +33,7 @@
 extern void pmac_check_ht_link(void);
 
 extern void pmac_setup_smp(void);
+extern int psurge_secondary_virq;
 extern void low_cpu_die(void) __attribute__((noreturn));
 
 extern int pmac_nvram_init(void);
diff -druN linux-2.6.39-libre/arch/powerpc/platforms/powermac/smp.c linux-3.0-rc7-libre/arch/powerpc/platforms/powermac/smp.c
--- linux-2.6.39-libre/arch/powerpc/platforms/powermac/smp.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/platforms/powermac/smp.c	2011-07-11 19:51:52.000000000 -0400
@@ -70,7 +70,7 @@
 static u64 timebase;
 static int tb_req;
 
-#ifdef CONFIG_PPC32
+#ifdef CONFIG_PPC_PMAC32_PSURGE
 
 /*
  * Powersurge (old powermac SMP) support.
@@ -124,6 +124,10 @@
 /* what sort of powersurge board we have */
 static int psurge_type = PSURGE_NONE;
 
+/* irq for secondary cpus to report */
+static struct irq_host *psurge_host;
+int psurge_secondary_virq;
+
 /*
  * Set and clear IPIs for powersurge.
  */
@@ -156,51 +160,52 @@
 /*
  * On powersurge (old SMP powermac architecture) we don't have
  * separate IPIs for separate messages like openpic does.  Instead
- * we have a bitmap for each processor, where a 1 bit means that
- * the corresponding message is pending for that processor.
- * Ideally each cpu's entry would be in a different cache line.
+ * use the generic demux helpers
  *  -- paulus.
  */
-static unsigned long psurge_smp_message[NR_CPUS];
-
-void psurge_smp_message_recv(void)
+static irqreturn_t psurge_ipi_intr(int irq, void *d)
 {
-	int cpu = smp_processor_id();
-	int msg;
-
-	/* clear interrupt */
-	psurge_clr_ipi(cpu);
+	psurge_clr_ipi(smp_processor_id());
+	smp_ipi_demux();
 
-	if (num_online_cpus() < 2)
-		return;
+	return IRQ_HANDLED;
+}
 
-	/* make sure there is a message there */
-	for (msg = 0; msg < 4; msg++)
-		if (test_and_clear_bit(msg, &psurge_smp_message[cpu]))
-			smp_message_recv(msg);
+static void smp_psurge_cause_ipi(int cpu, unsigned long data)
+{
+	psurge_set_ipi(cpu);
 }
 
-irqreturn_t psurge_primary_intr(int irq, void *d)
+static int psurge_host_map(struct irq_host *h, unsigned int virq,
+			 irq_hw_number_t hw)
 {
-	psurge_smp_message_recv();
-	return IRQ_HANDLED;
+	irq_set_chip_and_handler(virq, &dummy_irq_chip, handle_percpu_irq);
+
+	return 0;
 }
 
-static void smp_psurge_message_pass(int target, int msg)
+struct irq_host_ops psurge_host_ops = {
+	.map	= psurge_host_map,
+};
+
+static int psurge_secondary_ipi_init(void)
 {
-	int i;
+	int rc = -ENOMEM;
 
-	if (num_online_cpus() < 2)
-		return;
+	psurge_host = irq_alloc_host(NULL, IRQ_HOST_MAP_NOMAP, 0,
+		&psurge_host_ops, 0);
 
-	for_each_online_cpu(i) {
-		if (target == MSG_ALL
-		    || (target == MSG_ALL_BUT_SELF && i != smp_processor_id())
-		    || target == i) {
-			set_bit(msg, &psurge_smp_message[i]);
-			psurge_set_ipi(i);
-		}
-	}
+	if (psurge_host)
+		psurge_secondary_virq = irq_create_direct_mapping(psurge_host);
+
+	if (psurge_secondary_virq)
+		rc = request_irq(psurge_secondary_virq, psurge_ipi_intr,
+			IRQF_DISABLED|IRQF_PERCPU, "IPI", NULL);
+
+	if (rc)
+		pr_err("Failed to setup secondary cpu IPI\n");
+
+	return rc;
 }
 
 /*
@@ -311,6 +316,9 @@
 		ncpus = 2;
 	}
 
+	if (psurge_secondary_ipi_init())
+		return 1;
+
 	psurge_start = ioremap(PSURGE_START, 4);
 	psurge_pri_intr = ioremap(PSURGE_PRI_INTR, 4);
 
@@ -329,7 +337,7 @@
 	return ncpus;
 }
 
-static void __init smp_psurge_kick_cpu(int nr)
+static int __init smp_psurge_kick_cpu(int nr)
 {
 	unsigned long start = __pa(__secondary_start_pmac_0) + nr * 8;
 	unsigned long a, flags;
@@ -394,11 +402,13 @@
 		psurge_set_ipi(1);
 
 	if (ppc_md.progress) ppc_md.progress("smp_psurge_kick_cpu - done", 0x354);
+
+	return 0;
 }
 
 static struct irqaction psurge_irqaction = {
-	.handler = psurge_primary_intr,
-	.flags = IRQF_DISABLED,
+	.handler = psurge_ipi_intr,
+	.flags = IRQF_DISABLED|IRQF_PERCPU,
 	.name = "primary IPI",
 };
 
@@ -437,14 +447,15 @@
 
 /* PowerSurge-style Macs */
 struct smp_ops_t psurge_smp_ops = {
-	.message_pass	= smp_psurge_message_pass,
+	.message_pass	= smp_muxed_ipi_message_pass,
+	.cause_ipi	= smp_psurge_cause_ipi,
 	.probe		= smp_psurge_probe,
 	.kick_cpu	= smp_psurge_kick_cpu,
 	.setup_cpu	= smp_psurge_setup_cpu,
 	.give_timebase	= smp_psurge_give_timebase,
 	.take_timebase	= smp_psurge_take_timebase,
 };
-#endif /* CONFIG_PPC32 - actually powersurge support */
+#endif /* CONFIG_PPC_PMAC32_PSURGE */
 
 /*
  * Core 99 and later support
@@ -791,14 +802,14 @@
 	return ncpus;
 }
 
-static void __devinit smp_core99_kick_cpu(int nr)
+static int __devinit smp_core99_kick_cpu(int nr)
 {
 	unsigned int save_vector;
 	unsigned long target, flags;
 	unsigned int *vector = (unsigned int *)(PAGE_OFFSET+0x100);
 
 	if (nr < 0 || nr > 3)
-		return;
+		return -ENOENT;
 
 	if (ppc_md.progress)
 		ppc_md.progress("smp_core99_kick_cpu", 0x346);
@@ -830,6 +841,8 @@
 
 	local_irq_restore(flags);
 	if (ppc_md.progress) ppc_md.progress("smp_core99_kick_cpu done", 0x347);
+
+	return 0;
 }
 
 static void __devinit smp_core99_setup_cpu(int cpu_nr)
@@ -1002,7 +1015,7 @@
 		of_node_put(np);
 		smp_ops = &core99_smp_ops;
 	}
-#ifdef CONFIG_PPC32
+#ifdef CONFIG_PPC_PMAC32_PSURGE
 	else {
 		/* We have to set bits in cpu_possible_mask here since the
 		 * secondary CPU(s) aren't in the device tree. Various
@@ -1015,7 +1028,7 @@
 			set_cpu_possible(cpu, true);
 		smp_ops = &psurge_smp_ops;
 	}
-#endif /* CONFIG_PPC32 */
+#endif /* CONFIG_PPC_PMAC32_PSURGE */
 
 #ifdef CONFIG_HOTPLUG_CPU
 	ppc_md.cpu_die = pmac_cpu_die;
diff -druN linux-2.6.39-libre/arch/powerpc/platforms/ps3/interrupt.c linux-3.0-rc7-libre/arch/powerpc/platforms/ps3/interrupt.c
--- linux-2.6.39-libre/arch/powerpc/platforms/ps3/interrupt.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/platforms/ps3/interrupt.c	2011-07-11 19:51:52.000000000 -0400
@@ -197,7 +197,7 @@
 	result = irq_set_chip_data(*virq, pd);
 
 	if (result) {
-		pr_debug("%s:%d: set_irq_chip_data failed\n",
+		pr_debug("%s:%d: irq_set_chip_data failed\n",
 			__func__, __LINE__);
 		goto fail_set;
 	}
@@ -659,11 +659,6 @@
 static void dump_bmp(struct ps3_private* pd) {};
 #endif /* defined(DEBUG) */
 
-static void ps3_host_unmap(struct irq_host *h, unsigned int virq)
-{
-	irq_set_chip_data(virq, NULL);
-}
-
 static int ps3_host_map(struct irq_host *h, unsigned int virq,
 	irq_hw_number_t hwirq)
 {
@@ -683,7 +678,6 @@
 
 static struct irq_host_ops ps3_host_ops = {
 	.map = ps3_host_map,
-	.unmap = ps3_host_unmap,
 	.match = ps3_host_match,
 };
 
diff -druN linux-2.6.39-libre/arch/powerpc/platforms/ps3/smp.c linux-3.0-rc7-libre/arch/powerpc/platforms/ps3/smp.c
--- linux-2.6.39-libre/arch/powerpc/platforms/ps3/smp.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/platforms/ps3/smp.c	2011-07-11 19:51:52.000000000 -0400
@@ -39,7 +39,7 @@
 #define MSG_COUNT 4
 static DEFINE_PER_CPU(unsigned int [MSG_COUNT], ps3_ipi_virqs);
 
-static void do_message_pass(int target, int msg)
+static void ps3_smp_message_pass(int cpu, int msg)
 {
 	int result;
 	unsigned int virq;
@@ -49,28 +49,12 @@
 		return;
 	}
 
-	virq = per_cpu(ps3_ipi_virqs, target)[msg];
+	virq = per_cpu(ps3_ipi_virqs, cpu)[msg];
 	result = ps3_send_event_locally(virq);
 
 	if (result)
 		DBG("%s:%d: ps3_send_event_locally(%d, %d) failed"
-			" (%d)\n", __func__, __LINE__, target, msg, result);
-}
-
-static void ps3_smp_message_pass(int target, int msg)
-{
-	int cpu;
-
-	if (target < NR_CPUS)
-		do_message_pass(target, msg);
-	else if (target == MSG_ALL_BUT_SELF) {
-		for_each_online_cpu(cpu)
-			if (cpu != smp_processor_id())
-				do_message_pass(cpu, msg);
-	} else {
-		for_each_online_cpu(cpu)
-			do_message_pass(cpu, msg);
-	}
+			" (%d)\n", __func__, __LINE__, cpu, msg, result);
 }
 
 static int ps3_smp_probe(void)
diff -druN linux-2.6.39-libre/arch/powerpc/platforms/ps3/spu.c linux-3.0-rc7-libre/arch/powerpc/platforms/ps3/spu.c
--- linux-2.6.39-libre/arch/powerpc/platforms/ps3/spu.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/platforms/ps3/spu.c	2011-07-11 19:51:52.000000000 -0400
@@ -197,7 +197,7 @@
  * The current HV requires the spu shadow regs to be mapped with the
  * PTE page protection bits set as read-only (PP=3).  This implementation
  * uses the low level __ioremap() to bypass the page protection settings
- * inforced by ioremap_flags() to get the needed PTE bits set for the
+ * inforced by ioremap_prot() to get the needed PTE bits set for the
  * shadow regs.
  */
 
@@ -214,7 +214,7 @@
 		goto fail_ioremap;
 	}
 
-	spu->local_store = (__force void *)ioremap_flags(spu->local_store_phys,
+	spu->local_store = (__force void *)ioremap_prot(spu->local_store_phys,
 		LS_SIZE, _PAGE_NO_CACHE);
 
 	if (!spu->local_store) {
diff -druN linux-2.6.39-libre/arch/powerpc/platforms/pseries/dtl.c linux-3.0-rc7-libre/arch/powerpc/platforms/pseries/dtl.c
--- linux-2.6.39-libre/arch/powerpc/platforms/pseries/dtl.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/platforms/pseries/dtl.c	2011-07-11 19:51:52.000000000 -0400
@@ -52,10 +52,10 @@
 
 
 /*
- * Size of per-cpu log buffers. Default is just under 16 pages worth.
+ * Size of per-cpu log buffers. Firmware requires that the buffer does
+ * not cross a 4k boundary.
  */
-static int dtl_buf_entries = (16 * 85);
-
+static int dtl_buf_entries = N_DISPATCH_LOG;
 
 #ifdef CONFIG_VIRT_CPU_ACCOUNTING
 struct dtl_ring {
@@ -151,7 +151,7 @@
 
 	/* Register our dtl buffer with the hypervisor. The HV expects the
 	 * buffer size to be passed in the second word of the buffer */
-	((u32 *)dtl->buf)[1] = dtl->buf_entries * sizeof(struct dtl_entry);
+	((u32 *)dtl->buf)[1] = DISPATCH_LOG_BYTES;
 
 	hwcpu = get_hard_smp_processor_id(dtl->cpu);
 	addr = __pa(dtl->buf);
@@ -196,13 +196,15 @@
 	long int rc;
 	struct dtl_entry *buf = NULL;
 
+	if (!dtl_cache)
+		return -ENOMEM;
+
 	/* only allow one reader */
 	if (dtl->buf)
 		return -EBUSY;
 
 	n_entries = dtl_buf_entries;
-	buf = kmalloc_node(n_entries * sizeof(struct dtl_entry),
-			GFP_KERNEL, cpu_to_node(dtl->cpu));
+	buf = kmem_cache_alloc_node(dtl_cache, GFP_KERNEL, cpu_to_node(dtl->cpu));
 	if (!buf) {
 		printk(KERN_WARNING "%s: buffer alloc failed for cpu %d\n",
 				__func__, dtl->cpu);
@@ -223,7 +225,7 @@
 	spin_unlock(&dtl->lock);
 
 	if (rc)
-		kfree(buf);
+		kmem_cache_free(dtl_cache, buf);
 	return rc;
 }
 
@@ -231,7 +233,7 @@
 {
 	spin_lock(&dtl->lock);
 	dtl_stop(dtl);
-	kfree(dtl->buf);
+	kmem_cache_free(dtl_cache, dtl->buf);
 	dtl->buf = NULL;
 	dtl->buf_entries = 0;
 	spin_unlock(&dtl->lock);
@@ -365,7 +367,7 @@
 
 	event_mask_file = debugfs_create_x8("dtl_event_mask", 0600,
 				dtl_dir, &dtl_event_mask);
-	buf_entries_file = debugfs_create_u32("dtl_buf_entries", 0600,
+	buf_entries_file = debugfs_create_u32("dtl_buf_entries", 0400,
 				dtl_dir, &dtl_buf_entries);
 
 	if (!event_mask_file || !buf_entries_file) {
diff -druN linux-2.6.39-libre/arch/powerpc/platforms/pseries/eeh.c linux-3.0-rc7-libre/arch/powerpc/platforms/pseries/eeh.c
--- linux-2.6.39-libre/arch/powerpc/platforms/pseries/eeh.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/platforms/pseries/eeh.c	2011-07-11 19:51:52.000000000 -0400
@@ -93,6 +93,7 @@
 static int ibm_get_config_addr_info;
 static int ibm_get_config_addr_info2;
 static int ibm_configure_bridge;
+static int ibm_configure_pe;
 
 int eeh_subsystem_enabled;
 EXPORT_SYMBOL(eeh_subsystem_enabled);
@@ -261,6 +262,8 @@
 	pci_regs_buf[0] = 0;
 
 	rtas_pci_enable(pdn, EEH_THAW_MMIO);
+	rtas_configure_bridge(pdn);
+	eeh_restore_bars(pdn);
 	loglen = gather_pci_data(pdn, pci_regs_buf, EEH_PCI_REGS_LOG_LEN);
 
 	rtas_slot_error_detail(pdn, severity, pci_regs_buf, loglen);
@@ -448,6 +451,39 @@
 	raw_spin_unlock_irqrestore(&confirm_error_lock, flags);
 }
 
+void __eeh_set_pe_freset(struct device_node *parent, unsigned int *freset)
+{
+	struct device_node *dn;
+
+	for_each_child_of_node(parent, dn) {
+		if (PCI_DN(dn)) {
+
+			struct pci_dev *dev = PCI_DN(dn)->pcidev;
+
+			if (dev && dev->driver)
+				*freset |= dev->needs_freset;
+
+			__eeh_set_pe_freset(dn, freset);
+		}
+	}
+}
+
+void eeh_set_pe_freset(struct device_node *dn, unsigned int *freset)
+{
+	struct pci_dev *dev;
+	dn = find_device_pe(dn);
+
+	/* Back up one, since config addrs might be shared */
+	if (!pcibios_find_pci_bus(dn) && PCI_DN(dn->parent))
+		dn = dn->parent;
+
+	dev = PCI_DN(dn)->pcidev;
+	if (dev)
+		*freset |= dev->needs_freset;
+
+	__eeh_set_pe_freset(dn, freset);
+}
+
 /**
  * eeh_dn_check_failure - check if all 1's data is due to EEH slot freeze
  * @dn device node
@@ -692,15 +728,24 @@
 	if (pdn->eeh_pe_config_addr)
 		config_addr = pdn->eeh_pe_config_addr;
 
-	rc = rtas_call(ibm_set_slot_reset,4,1, NULL,
+	rc = rtas_call(ibm_set_slot_reset, 4, 1, NULL,
 	               config_addr,
 	               BUID_HI(pdn->phb->buid),
 	               BUID_LO(pdn->phb->buid),
 	               state);
-	if (rc)
-		printk (KERN_WARNING "EEH: Unable to reset the failed slot,"
-		        " (%d) #RST=%d dn=%s\n",
-		        rc, state, pdn->node->full_name);
+
+	/* Fundamental-reset not supported on this PE, try hot-reset */
+	if (rc == -8 && state == 3) {
+		rc = rtas_call(ibm_set_slot_reset, 4, 1, NULL,
+			       config_addr,
+			       BUID_HI(pdn->phb->buid),
+			       BUID_LO(pdn->phb->buid), 1);
+		if (rc)
+			printk(KERN_WARNING
+				"EEH: Unable to reset the failed slot,"
+				" #RST=%d dn=%s\n",
+				rc, pdn->node->full_name);
+	}
 }
 
 /**
@@ -736,18 +781,21 @@
 /**
  * rtas_set_slot_reset -- assert the pci #RST line for 1/4 second
  * @pdn: pci device node to be reset.
- *
- *  Return 0 if success, else a non-zero value.
  */
 
 static void __rtas_set_slot_reset(struct pci_dn *pdn)
 {
-	struct pci_dev *dev = pdn->pcidev;
+	unsigned int freset = 0;
 
-	/* Determine type of EEH reset required by device,
-	 * default hot reset or fundamental reset
-	 */
-	if (dev && dev->needs_freset)
+	/* Determine type of EEH reset required for
+	 * Partitionable Endpoint, a hot-reset (1)
+	 * or a fundamental reset (3).
+	 * A fundamental reset required by any device under
+	 * Partitionable Endpoint trumps hot-reset.
+  	 */
+	eeh_set_pe_freset(pdn->node, &freset);
+
+	if (freset)
 		rtas_pci_slot_reset(pdn, 3);
 	else
 		rtas_pci_slot_reset(pdn, 1);
@@ -895,13 +943,20 @@
 {
 	int config_addr;
 	int rc;
+	int token;
 
 	/* Use PE configuration address, if present */
 	config_addr = pdn->eeh_config_addr;
 	if (pdn->eeh_pe_config_addr)
 		config_addr = pdn->eeh_pe_config_addr;
 
-	rc = rtas_call(ibm_configure_bridge,3,1, NULL,
+	/* Use new configure-pe function, if supported */
+	if (ibm_configure_pe != RTAS_UNKNOWN_SERVICE)
+		token = ibm_configure_pe;
+	else
+		token = ibm_configure_bridge;
+
+	rc = rtas_call(token, 3, 1, NULL,
 	               config_addr,
 	               BUID_HI(pdn->phb->buid),
 	               BUID_LO(pdn->phb->buid));
@@ -1077,6 +1132,7 @@
 	ibm_get_config_addr_info = rtas_token("ibm,get-config-addr-info");
 	ibm_get_config_addr_info2 = rtas_token("ibm,get-config-addr-info2");
 	ibm_configure_bridge = rtas_token ("ibm,configure-bridge");
+	ibm_configure_pe = rtas_token("ibm,configure-pe");
 
 	if (ibm_set_eeh_option == RTAS_UNKNOWN_SERVICE)
 		return;
diff -druN linux-2.6.39-libre/arch/powerpc/platforms/pseries/eeh_driver.c linux-3.0-rc7-libre/arch/powerpc/platforms/pseries/eeh_driver.c
--- linux-2.6.39-libre/arch/powerpc/platforms/pseries/eeh_driver.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/platforms/pseries/eeh_driver.c	2011-07-11 19:51:52.000000000 -0400
@@ -328,7 +328,7 @@
 	struct pci_bus *frozen_bus;
 	int rc = 0;
 	enum pci_ers_result result = PCI_ERS_RESULT_NONE;
-	const char *location, *pci_str, *drv_str;
+	const char *location, *pci_str, *drv_str, *bus_pci_str, *bus_drv_str;
 
 	frozen_dn = find_device_pe(event->dn);
 	if (!frozen_dn) {
@@ -364,13 +364,8 @@
 	frozen_pdn = PCI_DN(frozen_dn);
 	frozen_pdn->eeh_freeze_count++;
 
-	if (frozen_pdn->pcidev) {
-		pci_str = pci_name (frozen_pdn->pcidev);
-		drv_str = pcid_name (frozen_pdn->pcidev);
-	} else {
-		pci_str = eeh_pci_name(event->dev);
-		drv_str = pcid_name (event->dev);
-	}
+	pci_str = eeh_pci_name(event->dev);
+	drv_str = pcid_name(event->dev);
 	
 	if (frozen_pdn->eeh_freeze_count > EEH_MAX_ALLOWED_FREEZES)
 		goto excess_failures;
@@ -378,8 +373,17 @@
 	printk(KERN_WARNING
 	   "EEH: This PCI device has failed %d times in the last hour:\n",
 		frozen_pdn->eeh_freeze_count);
+
+	if (frozen_pdn->pcidev) {
+		bus_pci_str = pci_name(frozen_pdn->pcidev);
+		bus_drv_str = pcid_name(frozen_pdn->pcidev);
+		printk(KERN_WARNING
+			"EEH: Bus location=%s driver=%s pci addr=%s\n",
+			location, bus_drv_str, bus_pci_str);
+	}
+
 	printk(KERN_WARNING
-		"EEH: location=%s driver=%s pci addr=%s\n",
+		"EEH: Device location=%s driver=%s pci addr=%s\n",
 		location, drv_str, pci_str);
 
 	/* Walk the various device drivers attached to this slot through
diff -druN linux-2.6.39-libre/arch/powerpc/platforms/pseries/hotplug-cpu.c linux-3.0-rc7-libre/arch/powerpc/platforms/pseries/hotplug-cpu.c
--- linux-2.6.39-libre/arch/powerpc/platforms/pseries/hotplug-cpu.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/platforms/pseries/hotplug-cpu.c	2011-07-11 19:51:52.000000000 -0400
@@ -19,6 +19,7 @@
  */
 
 #include <linux/kernel.h>
+#include <linux/interrupt.h>
 #include <linux/delay.h>
 #include <linux/cpu.h>
 #include <asm/system.h>
@@ -28,7 +29,7 @@
 #include <asm/machdep.h>
 #include <asm/vdso_datapage.h>
 #include <asm/pSeries_reconfig.h>
-#include "xics.h"
+#include <asm/xics.h>
 #include "plpar_wrappers.h"
 #include "offline_states.h"
 
@@ -280,7 +281,7 @@
 	}
 
 	for_each_cpu(cpu, tmp) {
-		BUG_ON(cpumask_test_cpu(cpu, cpu_present_mask));
+		BUG_ON(cpu_present(cpu));
 		set_cpu_present(cpu, true);
 		set_hard_smp_processor_id(cpu, *intserv++);
 	}
diff -druN linux-2.6.39-libre/arch/powerpc/platforms/pseries/io_event_irq.c linux-3.0-rc7-libre/arch/powerpc/platforms/pseries/io_event_irq.c
--- linux-2.6.39-libre/arch/powerpc/platforms/pseries/io_event_irq.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/powerpc/platforms/pseries/io_event_irq.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,231 @@
+/*
+ * Copyright 2010 2011 Mark Nelson and Tseng-Hui (Frank) Lin, 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/errno.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+#include <linux/of.h>
+#include <linux/list.h>
+#include <linux/notifier.h>
+
+#include <asm/machdep.h>
+#include <asm/rtas.h>
+#include <asm/irq.h>
+#include <asm/io_event_irq.h>
+
+#include "pseries.h"
+
+/*
+ * IO event interrupt is a mechanism provided by RTAS to return
+ * information about hardware error and non-error events. Device
+ * drivers can register their event handlers to receive events.
+ * Device drivers are expected to use atomic_notifier_chain_register()
+ * and atomic_notifier_chain_unregister() to register and unregister
+ * their event handlers. Since multiple IO event types and scopes
+ * share an IO event interrupt, the event handlers are called one
+ * by one until the IO event is claimed by one of the handlers.
+ * The event handlers are expected to return NOTIFY_OK if the
+ * event is handled by the event handler or NOTIFY_DONE if the
+ * event does not belong to the handler.
+ *
+ * Usage:
+ *
+ * Notifier function:
+ * #include <asm/io_event_irq.h>
+ * int event_handler(struct notifier_block *nb, unsigned long val, void *data) {
+ * 	p = (struct pseries_io_event_sect_data *) data;
+ * 	if (! is_my_event(p->scope, p->event_type)) return NOTIFY_DONE;
+ * 		:
+ * 		:
+ * 	return NOTIFY_OK;
+ * }
+ * struct notifier_block event_nb = {
+ * 	.notifier_call = event_handler,
+ * }
+ *
+ * Registration:
+ * atomic_notifier_chain_register(&pseries_ioei_notifier_list, &event_nb);
+ *
+ * Unregistration:
+ * atomic_notifier_chain_unregister(&pseries_ioei_notifier_list, &event_nb);
+ */
+
+ATOMIC_NOTIFIER_HEAD(pseries_ioei_notifier_list);
+EXPORT_SYMBOL_GPL(pseries_ioei_notifier_list);
+
+static int ioei_check_exception_token;
+
+/* pSeries event log format */
+
+/* Two bytes ASCII section IDs */
+#define PSERIES_ELOG_SECT_ID_PRIV_HDR		(('P' << 8) | 'H')
+#define PSERIES_ELOG_SECT_ID_USER_HDR		(('U' << 8) | 'H')
+#define PSERIES_ELOG_SECT_ID_PRIMARY_SRC	(('P' << 8) | 'S')
+#define PSERIES_ELOG_SECT_ID_EXTENDED_UH	(('E' << 8) | 'H')
+#define PSERIES_ELOG_SECT_ID_FAILING_MTMS	(('M' << 8) | 'T')
+#define PSERIES_ELOG_SECT_ID_SECONDARY_SRC	(('S' << 8) | 'S')
+#define PSERIES_ELOG_SECT_ID_DUMP_LOCATOR	(('D' << 8) | 'H')
+#define PSERIES_ELOG_SECT_ID_FW_ERROR		(('S' << 8) | 'W')
+#define PSERIES_ELOG_SECT_ID_IMPACT_PART_ID	(('L' << 8) | 'P')
+#define PSERIES_ELOG_SECT_ID_LOGIC_RESOURCE_ID	(('L' << 8) | 'R')
+#define PSERIES_ELOG_SECT_ID_HMC_ID		(('H' << 8) | 'M')
+#define PSERIES_ELOG_SECT_ID_EPOW		(('E' << 8) | 'P')
+#define PSERIES_ELOG_SECT_ID_IO_EVENT		(('I' << 8) | 'E')
+#define PSERIES_ELOG_SECT_ID_MANUFACT_INFO	(('M' << 8) | 'I')
+#define PSERIES_ELOG_SECT_ID_CALL_HOME		(('C' << 8) | 'H')
+#define PSERIES_ELOG_SECT_ID_USER_DEF		(('U' << 8) | 'D')
+
+/* Vendor specific Platform Event Log Format, Version 6, section header */
+struct pseries_elog_section {
+	uint16_t id;			/* 0x00 2-byte ASCII section ID	*/
+	uint16_t length;		/* 0x02 Section length in bytes	*/
+	uint8_t version;		/* 0x04 Section version		*/
+	uint8_t subtype;		/* 0x05 Section subtype		*/
+	uint16_t creator_component;	/* 0x06 Creator component ID	*/
+	uint8_t data[];			/* 0x08 Start of section data	*/
+};
+
+static char ioei_rtas_buf[RTAS_DATA_BUF_SIZE] __cacheline_aligned;
+
+/**
+ * Find data portion of a specific section in RTAS extended event log.
+ * @elog: RTAS error/event log.
+ * @sect_id: secsion ID.
+ *
+ * Return:
+ *	pointer to the section data of the specified section
+ *	NULL if not found
+ */
+static struct pseries_elog_section *find_xelog_section(struct rtas_error_log *elog,
+						       uint16_t sect_id)
+{
+	struct rtas_ext_event_log_v6 *xelog =
+		(struct rtas_ext_event_log_v6 *) elog->buffer;
+	struct pseries_elog_section *sect;
+	unsigned char *p, *log_end;
+
+	/* Check that we understand the format */
+	if (elog->extended_log_length < sizeof(struct rtas_ext_event_log_v6) ||
+	    xelog->log_format != RTAS_V6EXT_LOG_FORMAT_EVENT_LOG ||
+	    xelog->company_id != RTAS_V6EXT_COMPANY_ID_IBM)
+		return NULL;
+
+	log_end = elog->buffer + elog->extended_log_length;
+	p = xelog->vendor_log;
+	while (p < log_end) {
+		sect = (struct pseries_elog_section *)p;
+		if (sect->id == sect_id)
+			return sect;
+		p += sect->length;
+	}
+	return NULL;
+}
+
+/**
+ * Find the data portion of an IO Event section from event log.
+ * @elog: RTAS error/event log.
+ *
+ * Return:
+ * 	pointer to a valid IO event section data. NULL if not found.
+ */
+static struct pseries_io_event * ioei_find_event(struct rtas_error_log *elog)
+{
+	struct pseries_elog_section *sect;
+
+	/* We should only ever get called for io-event interrupts, but if
+	 * we do get called for another type then something went wrong so
+	 * make some noise about it.
+	 * RTAS_TYPE_IO only exists in extended event log version 6 or later.
+	 * No need to check event log version.
+	 */
+	if (unlikely(elog->type != RTAS_TYPE_IO)) {
+		printk_once(KERN_WARNING "io_event_irq: Unexpected event type %d",
+			    elog->type);
+		return NULL;
+	}
+
+	sect = find_xelog_section(elog, PSERIES_ELOG_SECT_ID_IO_EVENT);
+	if (unlikely(!sect)) {
+		printk_once(KERN_WARNING "io_event_irq: RTAS extended event "
+			    "log does not contain an IO Event section. "
+			    "Could be a bug in system firmware!\n");
+		return NULL;
+	}
+	return (struct pseries_io_event *) &sect->data;
+}
+
+/*
+ * PAPR:
+ * - check-exception returns the first found error or event and clear that
+ *   error or event so it is reported once.
+ * - Each interrupt returns one event. If a plateform chooses to report
+ *   multiple events through a single interrupt, it must ensure that the
+ *   interrupt remains asserted until check-exception has been used to
+ *   process all out-standing events for that interrupt.
+ *
+ * Implementation notes:
+ * - Events must be processed in the order they are returned. Hence,
+ *   sequential in nature.
+ * - The owner of an event is determined by combinations of scope,
+ *   event type, and sub-type. There is no easy way to pre-sort clients
+ *   by scope or event type alone. For example, Torrent ISR route change
+ *   event is reported with scope 0x00 (Not Applicatable) rather than
+ *   0x3B (Torrent-hub). It is better to let the clients to identify
+ *   who owns the the event.
+ */
+
+static irqreturn_t ioei_interrupt(int irq, void *dev_id)
+{
+	struct pseries_io_event *event;
+	int rtas_rc;
+
+	for (;;) {
+		rtas_rc = rtas_call(ioei_check_exception_token, 6, 1, NULL,
+				    RTAS_VECTOR_EXTERNAL_INTERRUPT,
+				    virq_to_hw(irq),
+				    RTAS_IO_EVENTS, 1 /* Time Critical */,
+				    __pa(ioei_rtas_buf),
+				    RTAS_DATA_BUF_SIZE);
+		if (rtas_rc != 0)
+			break;
+
+		event = ioei_find_event((struct rtas_error_log *)ioei_rtas_buf);
+		if (!event)
+			continue;
+
+		atomic_notifier_call_chain(&pseries_ioei_notifier_list,
+					   0, event);
+	}
+	return IRQ_HANDLED;
+}
+
+static int __init ioei_init(void)
+{
+	struct device_node *np;
+
+	ioei_check_exception_token = rtas_token("check-exception");
+	if (ioei_check_exception_token == RTAS_UNKNOWN_SERVICE) {
+		pr_warning("IO Event IRQ not supported on this system !\n");
+		return -ENODEV;
+	}
+	np = of_find_node_by_path("/event-sources/ibm,io-events");
+	if (np) {
+		request_event_sources_irqs(np, ioei_interrupt, "IO_EVENT");
+		of_node_put(np);
+	} else {
+		pr_err("io_event_irq: No ibm,io-events on system! "
+		       "IO Event interrupt disabled.\n");
+		return -ENODEV;
+	}
+	return 0;
+}
+machine_subsys_initcall(pseries, ioei_init);
+
diff -druN linux-2.6.39-libre/arch/powerpc/platforms/pseries/iommu.c linux-3.0-rc7-libre/arch/powerpc/platforms/pseries/iommu.c
--- linux-2.6.39-libre/arch/powerpc/platforms/pseries/iommu.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/platforms/pseries/iommu.c	2011-07-11 19:51:52.000000000 -0400
@@ -659,15 +659,18 @@
 {
 	struct dynamic_dma_window_prop *dwp;
 	struct property *win64;
-	const u32 *ddr_avail;
+	const u32 *ddw_avail;
 	u64 liobn;
 	int len, ret;
 
-	ddr_avail = of_get_property(np, "ibm,ddw-applicable", &len);
+	ddw_avail = of_get_property(np, "ibm,ddw-applicable", &len);
 	win64 = of_find_property(np, DIRECT64_PROPNAME, NULL);
-	if (!win64 || !ddr_avail || len < 3 * sizeof(u32))
+	if (!win64)
 		return;
 
+	if (!ddw_avail || len < 3 * sizeof(u32) || win64->length < sizeof(*dwp))
+		goto delprop;
+
 	dwp = win64->value;
 	liobn = (u64)be32_to_cpu(dwp->liobn);
 
@@ -681,28 +684,29 @@
 		pr_debug("%s successfully cleared tces in window.\n",
 			 np->full_name);
 
-	ret = rtas_call(ddr_avail[2], 1, 1, NULL, liobn);
+	ret = rtas_call(ddw_avail[2], 1, 1, NULL, liobn);
 	if (ret)
 		pr_warning("%s: failed to remove direct window: rtas returned "
 			"%d to ibm,remove-pe-dma-window(%x) %llx\n",
-			np->full_name, ret, ddr_avail[2], liobn);
+			np->full_name, ret, ddw_avail[2], liobn);
 	else
 		pr_debug("%s: successfully removed direct window: rtas returned "
 			"%d to ibm,remove-pe-dma-window(%x) %llx\n",
-			np->full_name, ret, ddr_avail[2], liobn);
-}
+			np->full_name, ret, ddw_avail[2], liobn);
 
+delprop:
+	ret = prom_remove_property(np, win64);
+	if (ret)
+		pr_warning("%s: failed to remove direct window property: %d\n",
+			np->full_name, ret);
+}
 
-static int dupe_ddw_if_already_created(struct pci_dev *dev, struct device_node *pdn)
+static u64 find_existing_ddw(struct device_node *pdn)
 {
-	struct device_node *dn;
-	struct pci_dn *pcidn;
 	struct direct_window *window;
 	const struct dynamic_dma_window_prop *direct64;
 	u64 dma_addr = 0;
 
-	dn = pci_device_to_OF_node(dev);
-	pcidn = PCI_DN(dn);
 	spin_lock(&direct_window_list_lock);
 	/* check if we already created a window and dupe that config if so */
 	list_for_each_entry(window, &direct_window_list, list) {
@@ -717,36 +721,40 @@
 	return dma_addr;
 }
 
-static u64 dupe_ddw_if_kexec(struct pci_dev *dev, struct device_node *pdn)
+static int find_existing_ddw_windows(void)
 {
-	struct device_node *dn;
-	struct pci_dn *pcidn;
 	int len;
+	struct device_node *pdn;
 	struct direct_window *window;
 	const struct dynamic_dma_window_prop *direct64;
-	u64 dma_addr = 0;
 
-	dn = pci_device_to_OF_node(dev);
-	pcidn = PCI_DN(dn);
-	direct64 = of_get_property(pdn, DIRECT64_PROPNAME, &len);
-	if (direct64) {
+	if (!firmware_has_feature(FW_FEATURE_LPAR))
+		return 0;
+
+	for_each_node_with_property(pdn, DIRECT64_PROPNAME) {
+		direct64 = of_get_property(pdn, DIRECT64_PROPNAME, &len);
+		if (!direct64)
+			continue;
+
 		window = kzalloc(sizeof(*window), GFP_KERNEL);
-		if (!window) {
+		if (!window || len < sizeof(struct dynamic_dma_window_prop)) {
+			kfree(window);
 			remove_ddw(pdn);
-		} else {
-			window->device = pdn;
-			window->prop = direct64;
-			spin_lock(&direct_window_list_lock);
-			list_add(&window->list, &direct_window_list);
-			spin_unlock(&direct_window_list_lock);
-			dma_addr = direct64->dma_base;
+			continue;
 		}
+
+		window->device = pdn;
+		window->prop = direct64;
+		spin_lock(&direct_window_list_lock);
+		list_add(&window->list, &direct_window_list);
+		spin_unlock(&direct_window_list_lock);
 	}
 
-	return dma_addr;
+	return 0;
 }
+machine_arch_initcall(pseries, find_existing_ddw_windows);
 
-static int query_ddw(struct pci_dev *dev, const u32 *ddr_avail,
+static int query_ddw(struct pci_dev *dev, const u32 *ddw_avail,
 			struct ddw_query_response *query)
 {
 	struct device_node *dn;
@@ -767,15 +775,15 @@
 	if (pcidn->eeh_pe_config_addr)
 		cfg_addr = pcidn->eeh_pe_config_addr;
 	buid = pcidn->phb->buid;
-	ret = rtas_call(ddr_avail[0], 3, 5, (u32 *)query,
+	ret = rtas_call(ddw_avail[0], 3, 5, (u32 *)query,
 		  cfg_addr, BUID_HI(buid), BUID_LO(buid));
 	dev_info(&dev->dev, "ibm,query-pe-dma-windows(%x) %x %x %x"
-		" returned %d\n", ddr_avail[0], cfg_addr, BUID_HI(buid),
+		" returned %d\n", ddw_avail[0], cfg_addr, BUID_HI(buid),
 		BUID_LO(buid), ret);
 	return ret;
 }
 
-static int create_ddw(struct pci_dev *dev, const u32 *ddr_avail,
+static int create_ddw(struct pci_dev *dev, const u32 *ddw_avail,
 			struct ddw_create_response *create, int page_shift,
 			int window_shift)
 {
@@ -800,12 +808,12 @@
 
 	do {
 		/* extra outputs are LIOBN and dma-addr (hi, lo) */
-		ret = rtas_call(ddr_avail[1], 5, 4, (u32 *)create, cfg_addr,
+		ret = rtas_call(ddw_avail[1], 5, 4, (u32 *)create, cfg_addr,
 				BUID_HI(buid), BUID_LO(buid), page_shift, window_shift);
 	} while (rtas_busy_delay(ret));
 	dev_info(&dev->dev,
 		"ibm,create-pe-dma-window(%x) %x %x %x %x %x returned %d "
-		"(liobn = 0x%x starting addr = %x %x)\n", ddr_avail[1],
+		"(liobn = 0x%x starting addr = %x %x)\n", ddw_avail[1],
 		 cfg_addr, BUID_HI(buid), BUID_LO(buid), page_shift,
 		 window_shift, ret, create->liobn, create->addr_hi, create->addr_lo);
 
@@ -831,18 +839,14 @@
 	int page_shift;
 	u64 dma_addr, max_addr;
 	struct device_node *dn;
-	const u32 *uninitialized_var(ddr_avail);
+	const u32 *uninitialized_var(ddw_avail);
 	struct direct_window *window;
-	struct property *uninitialized_var(win64);
+	struct property *win64;
 	struct dynamic_dma_window_prop *ddwprop;
 
 	mutex_lock(&direct_window_init_mutex);
 
-	dma_addr = dupe_ddw_if_already_created(dev, pdn);
-	if (dma_addr != 0)
-		goto out_unlock;
-
-	dma_addr = dupe_ddw_if_kexec(dev, pdn);
+	dma_addr = find_existing_ddw(pdn);
 	if (dma_addr != 0)
 		goto out_unlock;
 
@@ -854,8 +858,8 @@
 	 * for the given node in that order.
 	 * the property is actually in the parent, not the PE
 	 */
-	ddr_avail = of_get_property(pdn, "ibm,ddw-applicable", &len);
-	if (!ddr_avail || len < 3 * sizeof(u32))
+	ddw_avail = of_get_property(pdn, "ibm,ddw-applicable", &len);
+	if (!ddw_avail || len < 3 * sizeof(u32))
 		goto out_unlock;
 
        /*
@@ -865,7 +869,7 @@
 	 * of page sizes: supported and supported for migrate-dma.
 	 */
 	dn = pci_device_to_OF_node(dev);
-	ret = query_ddw(dev, ddr_avail, &query);
+	ret = query_ddw(dev, ddw_avail, &query);
 	if (ret != 0)
 		goto out_unlock;
 
@@ -907,13 +911,14 @@
 	}
 	win64->name = kstrdup(DIRECT64_PROPNAME, GFP_KERNEL);
 	win64->value = ddwprop = kmalloc(sizeof(*ddwprop), GFP_KERNEL);
+	win64->length = sizeof(*ddwprop);
 	if (!win64->name || !win64->value) {
 		dev_info(&dev->dev,
 			"couldn't allocate property name and value\n");
 		goto out_free_prop;
 	}
 
-	ret = create_ddw(dev, ddr_avail, &create, page_shift, len);
+	ret = create_ddw(dev, ddw_avail, &create, page_shift, len);
 	if (ret != 0)
 		goto out_free_prop;
 
@@ -1021,13 +1026,16 @@
 	const void *dma_window = NULL;
 	u64 dma_offset;
 
-	if (!dev->dma_mask || !dma_supported(dev, dma_mask))
+	if (!dev->dma_mask)
 		return -EIO;
 
+	if (!dev_is_pci(dev))
+		goto check_mask;
+
+	pdev = to_pci_dev(dev);
+
 	/* only attempt to use a new window if 64-bit DMA is requested */
 	if (!disable_ddw && dma_mask == DMA_BIT_MASK(64)) {
-		pdev = to_pci_dev(dev);
-
 		dn = pci_device_to_OF_node(pdev);
 		dev_dbg(dev, "node is %s\n", dn->full_name);
 
@@ -1054,12 +1062,17 @@
 		}
 	}
 
-	/* fall-through to iommu ops */
-	if (!ddw_enabled) {
-		dev_info(dev, "Using 32-bit DMA via iommu\n");
+	/* fall back on iommu ops, restore table pointer with ops */
+	if (!ddw_enabled && get_dma_ops(dev) != &dma_iommu_ops) {
+		dev_info(dev, "Restoring 32-bit DMA via iommu\n");
 		set_dma_ops(dev, &dma_iommu_ops);
+		pci_dma_dev_setup_pSeriesLP(pdev);
 	}
 
+check_mask:
+	if (!dma_supported(dev, dma_mask))
+		return -EIO;
+
 	*dev->dma_mask = dma_mask;
 	return 0;
 }
diff -druN linux-2.6.39-libre/arch/powerpc/platforms/pseries/Kconfig linux-3.0-rc7-libre/arch/powerpc/platforms/pseries/Kconfig
--- linux-2.6.39-libre/arch/powerpc/platforms/pseries/Kconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/platforms/pseries/Kconfig	2011-07-11 19:51:52.000000000 -0400
@@ -3,7 +3,10 @@
 	bool "IBM pSeries & new (POWER5-based) iSeries"
 	select MPIC
 	select PCI_MSI
-	select XICS
+	select PPC_XICS
+	select PPC_ICP_NATIVE
+	select PPC_ICP_HV
+	select PPC_ICS_RTAS
 	select PPC_I8259
 	select PPC_RTAS
 	select PPC_RTAS_DAEMON
@@ -47,6 +50,24 @@
 	tristate "Scanlog dump interface"
 	depends on RTAS_PROC && PPC_PSERIES
 
+config IO_EVENT_IRQ
+	bool "IO Event Interrupt support"
+	depends on PPC_PSERIES
+	default y
+	help
+	  Select this option, if you want to enable support for IO Event
+	  interrupts. IO event interrupt is a mechanism provided by RTAS
+	  to return information about hardware error and non-error events
+	  which may need OS attention. RTAS returns events for multiple
+	  event types and scopes. Device drivers can register their handlers
+	  to receive events.
+
+	  This option will only enable the IO event platform code. You
+	  will still need to enable or compile the actual drivers
+	  that use this infrastruture to handle IO event interrupts.
+
+	  Say Y if you are unsure.
+
 config LPARCFG
 	bool "LPAR Configuration Data"
 	depends on PPC_PSERIES || PPC_ISERIES
diff -druN linux-2.6.39-libre/arch/powerpc/platforms/pseries/kexec.c linux-3.0-rc7-libre/arch/powerpc/platforms/pseries/kexec.c
--- linux-2.6.39-libre/arch/powerpc/platforms/pseries/kexec.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/platforms/pseries/kexec.c	2011-07-11 19:51:52.000000000 -0400
@@ -7,15 +7,18 @@
  * 2 of the License, or (at your option) any later version.
  */
 
+#include <linux/kernel.h>
+#include <linux/interrupt.h>
+
 #include <asm/machdep.h>
 #include <asm/page.h>
 #include <asm/firmware.h>
 #include <asm/kexec.h>
 #include <asm/mpic.h>
+#include <asm/xics.h>
 #include <asm/smp.h>
 
 #include "pseries.h"
-#include "xics.h"
 #include "plpar_wrappers.h"
 
 static void pseries_kexec_cpu_down(int crash_shutdown, int secondary)
diff -druN linux-2.6.39-libre/arch/powerpc/platforms/pseries/lpar.c linux-3.0-rc7-libre/arch/powerpc/platforms/pseries/lpar.c
--- linux-2.6.39-libre/arch/powerpc/platforms/pseries/lpar.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/platforms/pseries/lpar.c	2011-07-11 19:51:52.000000000 -0400
@@ -329,6 +329,8 @@
 	/* Make pHyp happy */
 	if ((rflags & _PAGE_NO_CACHE) & !(rflags & _PAGE_WRITETHRU))
 		hpte_r &= ~_PAGE_COHERENT;
+	if (firmware_has_feature(FW_FEATURE_XCMO) && !(hpte_r & HPTE_R_N))
+		flags |= H_COALESCE_CAND;
 
 	lpar_rc = plpar_pte_enter(flags, hpte_group, hpte_v, hpte_r, &slot);
 	if (unlikely(lpar_rc == H_PTEG_FULL)) {
@@ -573,7 +575,7 @@
 	unsigned long i, pix, rc;
 	unsigned long flags = 0;
 	struct ppc64_tlb_batch *batch = &__get_cpu_var(ppc64_tlb_batch);
-	int lock_tlbie = !cpu_has_feature(CPU_FTR_LOCKLESS_TLBIE);
+	int lock_tlbie = !mmu_has_feature(MMU_FTR_LOCKLESS_TLBIE);
 	unsigned long param[9];
 	unsigned long va;
 	unsigned long hash, index, shift, hidx, slot;
@@ -771,3 +773,47 @@
 	local_irq_restore(flags);
 }
 #endif
+
+/**
+ * h_get_mpp
+ * H_GET_MPP hcall returns info in 7 parms
+ */
+int h_get_mpp(struct hvcall_mpp_data *mpp_data)
+{
+	int rc;
+	unsigned long retbuf[PLPAR_HCALL9_BUFSIZE];
+
+	rc = plpar_hcall9(H_GET_MPP, retbuf);
+
+	mpp_data->entitled_mem = retbuf[0];
+	mpp_data->mapped_mem = retbuf[1];
+
+	mpp_data->group_num = (retbuf[2] >> 2 * 8) & 0xffff;
+	mpp_data->pool_num = retbuf[2] & 0xffff;
+
+	mpp_data->mem_weight = (retbuf[3] >> 7 * 8) & 0xff;
+	mpp_data->unallocated_mem_weight = (retbuf[3] >> 6 * 8) & 0xff;
+	mpp_data->unallocated_entitlement = retbuf[3] & 0xffffffffffff;
+
+	mpp_data->pool_size = retbuf[4];
+	mpp_data->loan_request = retbuf[5];
+	mpp_data->backing_mem = retbuf[6];
+
+	return rc;
+}
+EXPORT_SYMBOL(h_get_mpp);
+
+int h_get_mpp_x(struct hvcall_mpp_x_data *mpp_x_data)
+{
+	int rc;
+	unsigned long retbuf[PLPAR_HCALL9_BUFSIZE] = { 0 };
+
+	rc = plpar_hcall9(H_GET_MPP_X, retbuf);
+
+	mpp_x_data->coalesced_bytes = retbuf[0];
+	mpp_x_data->pool_coalesced_bytes = retbuf[1];
+	mpp_x_data->pool_purr_cycles = retbuf[2];
+	mpp_x_data->pool_spurr_cycles = retbuf[3];
+
+	return rc;
+}
diff -druN linux-2.6.39-libre/arch/powerpc/platforms/pseries/Makefile linux-3.0-rc7-libre/arch/powerpc/platforms/pseries/Makefile
--- linux-2.6.39-libre/arch/powerpc/platforms/pseries/Makefile	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/platforms/pseries/Makefile	2011-07-11 19:51:52.000000000 -0400
@@ -5,7 +5,6 @@
 			   setup.o iommu.o event_sources.o ras.o \
 			   firmware.o power.o dlpar.o mobility.o
 obj-$(CONFIG_SMP)	+= smp.o
-obj-$(CONFIG_XICS)	+= xics.o
 obj-$(CONFIG_SCANLOG)	+= scanlog.o
 obj-$(CONFIG_EEH)	+= eeh.o eeh_cache.o eeh_driver.o eeh_event.o eeh_sysfs.o
 obj-$(CONFIG_KEXEC)	+= kexec.o
@@ -22,6 +21,7 @@
 obj-$(CONFIG_PHYP_DUMP)		+= phyp_dump.o
 obj-$(CONFIG_CMM)		+= cmm.o
 obj-$(CONFIG_DTL)		+= dtl.o
+obj-$(CONFIG_IO_EVENT_IRQ)	+= io_event_irq.o
 
 ifeq ($(CONFIG_PPC_PSERIES),y)
 obj-$(CONFIG_SUSPEND)		+= suspend.o
diff -druN linux-2.6.39-libre/arch/powerpc/platforms/pseries/plpar_wrappers.h linux-3.0-rc7-libre/arch/powerpc/platforms/pseries/plpar_wrappers.h
--- linux-2.6.39-libre/arch/powerpc/platforms/pseries/plpar_wrappers.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/platforms/pseries/plpar_wrappers.h	2011-07-11 19:51:52.000000000 -0400
@@ -270,31 +270,4 @@
 			lbuf[1]);
 }
 
-static inline long plpar_eoi(unsigned long xirr)
-{
-	return plpar_hcall_norets(H_EOI, xirr);
-}
-
-static inline long plpar_cppr(unsigned long cppr)
-{
-	return plpar_hcall_norets(H_CPPR, cppr);
-}
-
-static inline long plpar_ipi(unsigned long servernum, unsigned long mfrr)
-{
-	return plpar_hcall_norets(H_IPI, servernum, mfrr);
-}
-
-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, cppr);
-
-	*xirr_ret = retbuf[0];
-
-	return rc;
-}
-
 #endif /* _PSERIES_PLPAR_WRAPPERS_H */
diff -druN linux-2.6.39-libre/arch/powerpc/platforms/pseries/ras.c linux-3.0-rc7-libre/arch/powerpc/platforms/pseries/ras.c
--- linux-2.6.39-libre/arch/powerpc/platforms/pseries/ras.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/platforms/pseries/ras.c	2011-07-11 19:51:52.000000000 -0400
@@ -122,7 +122,7 @@
 
 	status = rtas_call(ras_check_exception_token, 6, 1, NULL,
 			   RTAS_VECTOR_EXTERNAL_INTERRUPT,
-			   irq_map[irq].hwirq,
+			   virq_to_hw(irq),
 			   RTAS_EPOW_WARNING | RTAS_POWERMGM_EVENTS,
 			   critical, __pa(&ras_log_buf),
 				rtas_get_error_log_max());
@@ -157,7 +157,7 @@
 
 	status = rtas_call(ras_check_exception_token, 6, 1, NULL,
 			   RTAS_VECTOR_EXTERNAL_INTERRUPT,
-			   irq_map[irq].hwirq,
+			   virq_to_hw(irq),
 			   RTAS_INTERNAL_ERROR, 1 /*Time Critical */,
 			   __pa(&ras_log_buf),
 				rtas_get_error_log_max());
@@ -227,7 +227,7 @@
 	struct rtas_error_log *h, *errhdr = NULL;
 
 	if (!VALID_FWNMI_BUFFER(regs->gpr[3])) {
-		printk(KERN_ERR "FWNMI: corrupt r3\n");
+		printk(KERN_ERR "FWNMI: corrupt r3 0x%016lx\n", regs->gpr[3]);
 		return NULL;
 	}
 
diff -druN linux-2.6.39-libre/arch/powerpc/platforms/pseries/setup.c linux-3.0-rc7-libre/arch/powerpc/platforms/pseries/setup.c
--- linux-2.6.39-libre/arch/powerpc/platforms/pseries/setup.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/platforms/pseries/setup.c	2011-07-11 19:51:52.000000000 -0400
@@ -53,9 +53,9 @@
 #include <asm/irq.h>
 #include <asm/time.h>
 #include <asm/nvram.h>
-#include "xics.h"
 #include <asm/pmc.h>
 #include <asm/mpic.h>
+#include <asm/xics.h>
 #include <asm/ppc-pci.h>
 #include <asm/i8259.h>
 #include <asm/udbg.h>
@@ -205,6 +205,9 @@
 		mpic_assign_isu(mpic, n, isuaddr);
 	}
 
+	/* Setup top-level get_irq */
+	ppc_md.get_irq = mpic_get_irq;
+
 	/* All ISUs are setup, complete initialization */
 	mpic_init(mpic);
 
@@ -214,7 +217,7 @@
 
 static void __init pseries_xics_init_IRQ(void)
 {
-	xics_init_IRQ();
+	xics_init();
 	pseries_setup_i8259_cascade();
 }
 
@@ -238,7 +241,6 @@
 		if (strstr(typep, "open-pic")) {
 			pSeries_mpic_node = of_node_get(np);
 			ppc_md.init_IRQ       = pseries_mpic_init_IRQ;
-			ppc_md.get_irq        = mpic_get_irq;
 			setup_kexec_cpu_down_mpic();
 			smp_init_pseries_mpic();
 			return;
@@ -276,6 +278,8 @@
 	.notifier_call = pci_dn_reconfig_notifier,
 };
 
+struct kmem_cache *dtl_cache;
+
 #ifdef CONFIG_VIRT_CPU_ACCOUNTING
 /*
  * Allocate space for the dispatch trace log for all possible cpus
@@ -287,18 +291,12 @@
 	int cpu, ret;
 	struct paca_struct *pp;
 	struct dtl_entry *dtl;
-	struct kmem_cache *dtl_cache;
 
 	if (!firmware_has_feature(FW_FEATURE_SPLPAR))
 		return 0;
 
-	dtl_cache = kmem_cache_create("dtl", DISPATCH_LOG_BYTES,
-						DISPATCH_LOG_BYTES, 0, NULL);
-	if (!dtl_cache) {
-		pr_warn("Failed to create dispatch trace log buffer cache\n");
-		pr_warn("Stolen time statistics will be unreliable\n");
+	if (!dtl_cache)
 		return 0;
-	}
 
 	for_each_possible_cpu(cpu) {
 		pp = &paca[cpu];
@@ -332,10 +330,27 @@
 
 	return 0;
 }
-
-early_initcall(alloc_dispatch_logs);
+#else /* !CONFIG_VIRT_CPU_ACCOUNTING */
+static inline int alloc_dispatch_logs(void)
+{
+	return 0;
+}
 #endif /* CONFIG_VIRT_CPU_ACCOUNTING */
 
+static int alloc_dispatch_log_kmem_cache(void)
+{
+	dtl_cache = kmem_cache_create("dtl", DISPATCH_LOG_BYTES,
+						DISPATCH_LOG_BYTES, 0, NULL);
+	if (!dtl_cache) {
+		pr_warn("Failed to create dispatch trace log buffer cache\n");
+		pr_warn("Stolen time statistics will be unreliable\n");
+		return 0;
+	}
+
+	return alloc_dispatch_logs();
+}
+early_initcall(alloc_dispatch_log_kmem_cache);
+
 static void __init pSeries_setup_arch(void)
 {
 	/* Discover PIC type and setup ppc_md accordingly */
@@ -403,6 +418,16 @@
 #define CMO_CHARACTERISTICS_TOKEN 44
 #define CMO_MAXLENGTH 1026
 
+void pSeries_coalesce_init(void)
+{
+	struct hvcall_mpp_x_data mpp_x_data;
+
+	if (firmware_has_feature(FW_FEATURE_CMO) && !h_get_mpp_x(&mpp_x_data))
+		powerpc_firmware_features |= FW_FEATURE_XCMO;
+	else
+		powerpc_firmware_features &= ~FW_FEATURE_XCMO;
+}
+
 /**
  * fw_cmo_feature_init - FW_FEATURE_CMO is not stored in ibm,hypertas-functions,
  * handle that here. (Stolen from parse_system_parameter_string)
@@ -472,6 +497,7 @@
 		pr_debug("CMO enabled, PrPSP=%d, SecPSP=%d\n", CMO_PrPSP,
 		         CMO_SecPSP);
 		powerpc_firmware_features |= FW_FEATURE_CMO;
+		pSeries_coalesce_init();
 	} else
 		pr_debug("CMO not enabled, PrPSP=%d, SecPSP=%d\n", CMO_PrPSP,
 		         CMO_SecPSP);
diff -druN linux-2.6.39-libre/arch/powerpc/platforms/pseries/smp.c linux-3.0-rc7-libre/arch/powerpc/platforms/pseries/smp.c
--- linux-2.6.39-libre/arch/powerpc/platforms/pseries/smp.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/platforms/pseries/smp.c	2011-07-11 19:51:52.000000000 -0400
@@ -44,10 +44,11 @@
 #include <asm/mpic.h>
 #include <asm/vdso_datapage.h>
 #include <asm/cputhreads.h>
+#include <asm/mpic.h>
+#include <asm/xics.h>
 
 #include "plpar_wrappers.h"
 #include "pseries.h"
-#include "xics.h"
 #include "offline_states.h"
 
 
@@ -136,7 +137,6 @@
 	return 1;
 }
 
-#ifdef CONFIG_XICS
 static void __devinit smp_xics_setup_cpu(int cpu)
 {
 	if (cpu != boot_cpuid)
@@ -151,14 +151,13 @@
 	set_default_offline_state(cpu);
 #endif
 }
-#endif /* CONFIG_XICS */
 
-static void __devinit smp_pSeries_kick_cpu(int nr)
+static int __devinit smp_pSeries_kick_cpu(int nr)
 {
 	BUG_ON(nr < 0 || nr >= NR_CPUS);
 
 	if (!smp_startup_cpu(nr))
-		return;
+		return -ENOENT;
 
 	/*
 	 * The processor is currently spinning, waiting for the
@@ -180,6 +179,8 @@
 						"Ret= %ld\n", nr, rc);
 	}
 #endif
+
+	return 0;
 }
 
 static int smp_pSeries_cpu_bootable(unsigned int nr)
@@ -197,23 +198,22 @@
 
 	return 1;
 }
-#ifdef CONFIG_MPIC
+
 static struct smp_ops_t pSeries_mpic_smp_ops = {
 	.message_pass	= smp_mpic_message_pass,
 	.probe		= smp_mpic_probe,
 	.kick_cpu	= smp_pSeries_kick_cpu,
 	.setup_cpu	= smp_mpic_setup_cpu,
 };
-#endif
-#ifdef CONFIG_XICS
+
 static struct smp_ops_t pSeries_xics_smp_ops = {
-	.message_pass	= smp_xics_message_pass,
-	.probe		= smp_xics_probe,
+	.message_pass	= smp_muxed_ipi_message_pass,
+	.cause_ipi	= NULL,	/* Filled at runtime by xics_smp_probe() */
+	.probe		= xics_smp_probe,
 	.kick_cpu	= smp_pSeries_kick_cpu,
 	.setup_cpu	= smp_xics_setup_cpu,
 	.cpu_bootable	= smp_pSeries_cpu_bootable,
 };
-#endif
 
 /* This is called very early */
 static void __init smp_init_pseries(void)
@@ -245,14 +245,12 @@
 	pr_debug(" <- smp_init_pSeries()\n");
 }
 
-#ifdef CONFIG_MPIC
 void __init smp_init_pseries_mpic(void)
 {
 	smp_ops = &pSeries_mpic_smp_ops;
 
 	smp_init_pseries();
 }
-#endif
 
 void __init smp_init_pseries_xics(void)
 {
diff -druN linux-2.6.39-libre/arch/powerpc/platforms/pseries/xics.c linux-3.0-rc7-libre/arch/powerpc/platforms/pseries/xics.c
--- linux-2.6.39-libre/arch/powerpc/platforms/pseries/xics.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/platforms/pseries/xics.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,949 +0,0 @@
-/*
- * arch/powerpc/platforms/pseries/xics.c
- *
- * Copyright 2000 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 <linux/threads.h>
-#include <linux/kernel.h>
-#include <linux/irq.h>
-#include <linux/smp.h>
-#include <linux/interrupt.h>
-#include <linux/init.h>
-#include <linux/radix-tree.h>
-#include <linux/cpu.h>
-#include <linux/msi.h>
-#include <linux/of.h>
-#include <linux/percpu.h>
-
-#include <asm/firmware.h>
-#include <asm/io.h>
-#include <asm/pgtable.h>
-#include <asm/smp.h>
-#include <asm/rtas.h>
-#include <asm/hvcall.h>
-#include <asm/machdep.h>
-
-#include "xics.h"
-#include "plpar_wrappers.h"
-
-static struct irq_host *xics_host;
-
-#define XICS_IPI		2
-#define XICS_IRQ_SPURIOUS	0
-
-/* Want a priority other than 0.  Various HW issues require this. */
-#define	DEFAULT_PRIORITY	5
-
-/*
- * Mark IPIs as higher priority so we can take them inside interrupts that
- * arent marked IRQF_DISABLED
- */
-#define IPI_PRIORITY		4
-
-/* The least favored priority */
-#define LOWEST_PRIORITY		0xFF
-
-/* The number of priorities defined above */
-#define MAX_NUM_PRIORITIES	3
-
-static unsigned int default_server = 0xFF;
-static unsigned int default_distrib_server = 0;
-static unsigned int interrupt_server_size = 8;
-
-/* RTAS service tokens */
-static int ibm_get_xive;
-static int ibm_set_xive;
-static int ibm_int_on;
-static int ibm_int_off;
-
-struct xics_cppr {
-	unsigned char stack[MAX_NUM_PRIORITIES];
-	int index;
-};
-
-static DEFINE_PER_CPU(struct xics_cppr, xics_cppr);
-
-/* Direct hardware low level accessors */
-
-/* The part of the interrupt presentation layer that we care about */
-struct xics_ipl {
-	union {
-		u32 word;
-		u8 bytes[4];
-	} xirr_poll;
-	union {
-		u32 word;
-		u8 bytes[4];
-	} xirr;
-	u32 dummy;
-	union {
-		u32 word;
-		u8 bytes[4];
-	} qirr;
-};
-
-static struct xics_ipl __iomem *xics_per_cpu[NR_CPUS];
-
-static inline unsigned int direct_xirr_info_get(void)
-{
-	int cpu = smp_processor_id();
-
-	return in_be32(&xics_per_cpu[cpu]->xirr.word);
-}
-
-static inline void direct_xirr_info_set(unsigned int value)
-{
-	int cpu = smp_processor_id();
-
-	out_be32(&xics_per_cpu[cpu]->xirr.word, value);
-}
-
-static inline void direct_cppr_info(u8 value)
-{
-	int cpu = smp_processor_id();
-
-	out_8(&xics_per_cpu[cpu]->xirr.bytes[0], value);
-}
-
-static inline void direct_qirr_info(int n_cpu, u8 value)
-{
-	out_8(&xics_per_cpu[n_cpu]->qirr.bytes[0], value);
-}
-
-
-/* LPAR low level accessors */
-
-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, cppr);
-	if (lpar_rc != H_SUCCESS)
-		panic(" bad return code xirr - rc = %lx\n", lpar_rc);
-	return (unsigned int)return_value;
-}
-
-static inline void lpar_xirr_info_set(unsigned int value)
-{
-	unsigned long lpar_rc;
-
-	lpar_rc = plpar_eoi(value);
-	if (lpar_rc != H_SUCCESS)
-		panic("bad return code EOI - rc = %ld, value=%x\n", lpar_rc,
-		      value);
-}
-
-static inline void lpar_cppr_info(u8 value)
-{
-	unsigned long lpar_rc;
-
-	lpar_rc = plpar_cppr(value);
-	if (lpar_rc != H_SUCCESS)
-		panic("bad return code cppr - rc = %lx\n", lpar_rc);
-}
-
-static inline void lpar_qirr_info(int n_cpu , u8 value)
-{
-	unsigned long lpar_rc;
-
-	lpar_rc = plpar_ipi(get_hard_smp_processor_id(n_cpu), value);
-	if (lpar_rc != H_SUCCESS)
-		panic("bad return code qirr - rc = %lx\n", lpar_rc);
-}
-
-
-/* Interface to generic irq subsystem */
-
-#ifdef CONFIG_SMP
-/*
- * For the moment we only implement delivery to all cpus or one cpu.
- *
- * If the requested affinity is cpu_all_mask, we set global affinity.
- * If not we set it to the first cpu in the mask, even if multiple cpus
- * are set. This is so things like irqbalance (which set core and package
- * wide affinities) do the right thing.
- */
-static int get_irq_server(unsigned int virq, const struct cpumask *cpumask,
-			  unsigned int strict_check)
-{
-
-	if (!distribute_irqs)
-		return default_server;
-
-	if (!cpumask_subset(cpu_possible_mask, cpumask)) {
-		int server = cpumask_first_and(cpu_online_mask, cpumask);
-
-		if (server < nr_cpu_ids)
-			return get_hard_smp_processor_id(server);
-
-		if (strict_check)
-			return -1;
-	}
-
-	/*
-	 * Workaround issue with some versions of JS20 firmware that
-	 * deliver interrupts to cpus which haven't been started. This
-	 * happens when using the maxcpus= boot option.
-	 */
-	if (cpumask_equal(cpu_online_mask, cpu_present_mask))
-		return default_distrib_server;
-
-	return default_server;
-}
-#else
-#define get_irq_server(virq, cpumask, strict_check) (default_server)
-#endif
-
-static void xics_unmask_irq(struct irq_data *d)
-{
-	unsigned int hwirq;
-	int call_status;
-	int server;
-
-	pr_devel("xics: unmask virq %d\n", d->irq);
-
-	hwirq = (unsigned int)irq_map[d->irq].hwirq;
-	pr_devel(" -> map to hwirq 0x%x\n", hwirq);
-	if (hwirq == XICS_IPI || hwirq == XICS_IRQ_SPURIOUS)
-		return;
-
-	server = get_irq_server(d->irq, d->affinity, 0);
-
-	call_status = rtas_call(ibm_set_xive, 3, 1, NULL, hwirq, server,
-				DEFAULT_PRIORITY);
-	if (call_status != 0) {
-		printk(KERN_ERR
-			"%s: ibm_set_xive irq %u server %x returned %d\n",
-			__func__, hwirq, server, call_status);
-		return;
-	}
-
-	/* Now unmask the interrupt (often a no-op) */
-	call_status = rtas_call(ibm_int_on, 1, 1, NULL, hwirq);
-	if (call_status != 0) {
-		printk(KERN_ERR "%s: ibm_int_on irq=%u returned %d\n",
-			__func__, hwirq, call_status);
-		return;
-	}
-}
-
-static unsigned int xics_startup(struct irq_data *d)
-{
-	/*
-	 * The generic MSI code returns with the interrupt disabled on the
-	 * card, using the MSI mask bits. Firmware doesn't appear to unmask
-	 * at that level, so we do it here by hand.
-	 */
-	if (d->msi_desc)
-		unmask_msi_irq(d);
-
-	/* unmask it */
-	xics_unmask_irq(d);
-	return 0;
-}
-
-static void xics_mask_real_irq(unsigned int hwirq)
-{
-	int call_status;
-
-	if (hwirq == XICS_IPI)
-		return;
-
-	call_status = rtas_call(ibm_int_off, 1, 1, NULL, hwirq);
-	if (call_status != 0) {
-		printk(KERN_ERR "%s: ibm_int_off irq=%u returned %d\n",
-			__func__, hwirq, call_status);
-		return;
-	}
-
-	/* Have to set XIVE to 0xff to be able to remove a slot */
-	call_status = rtas_call(ibm_set_xive, 3, 1, NULL, hwirq,
-				default_server, 0xff);
-	if (call_status != 0) {
-		printk(KERN_ERR "%s: ibm_set_xive(0xff) irq=%u returned %d\n",
-			__func__, hwirq, call_status);
-		return;
-	}
-}
-
-static void xics_mask_irq(struct irq_data *d)
-{
-	unsigned int hwirq;
-
-	pr_devel("xics: mask virq %d\n", d->irq);
-
-	hwirq = (unsigned int)irq_map[d->irq].hwirq;
-	if (hwirq == XICS_IPI || hwirq == XICS_IRQ_SPURIOUS)
-		return;
-	xics_mask_real_irq(hwirq);
-}
-
-static void xics_mask_unknown_vec(unsigned int vec)
-{
-	printk(KERN_ERR "Interrupt %u (real) is invalid, disabling it.\n", vec);
-	xics_mask_real_irq(vec);
-}
-
-static inline unsigned int xics_xirr_vector(unsigned int xirr)
-{
-	/*
-	 * The top byte is the old cppr, to be restored on EOI.
-	 * The remaining 24 bits are the vector.
-	 */
-	return xirr & 0x00ffffff;
-}
-
-static void push_cppr(unsigned int vec)
-{
-	struct xics_cppr *os_cppr = &__get_cpu_var(xics_cppr);
-
-	if (WARN_ON(os_cppr->index >= MAX_NUM_PRIORITIES - 1))
-		return;
-
-	if (vec == XICS_IPI)
-		os_cppr->stack[++os_cppr->index] = IPI_PRIORITY;
-	else
-		os_cppr->stack[++os_cppr->index] = DEFAULT_PRIORITY;
-}
-
-static unsigned int xics_get_irq_direct(void)
-{
-	unsigned int xirr = direct_xirr_info_get();
-	unsigned int vec = xics_xirr_vector(xirr);
-	unsigned int irq;
-
-	if (vec == XICS_IRQ_SPURIOUS)
-		return NO_IRQ;
-
-	irq = irq_radix_revmap_lookup(xics_host, vec);
-	if (likely(irq != NO_IRQ)) {
-		push_cppr(vec);
-		return irq;
-	}
-
-	/* We don't have a linux mapping, so have rtas mask it. */
-	xics_mask_unknown_vec(vec);
-
-	/* We might learn about it later, so EOI it */
-	direct_xirr_info_set(xirr);
-	return NO_IRQ;
-}
-
-static unsigned int xics_get_irq_lpar(void)
-{
-	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;
-
-	if (vec == XICS_IRQ_SPURIOUS)
-		return NO_IRQ;
-
-	irq = irq_radix_revmap_lookup(xics_host, vec);
-	if (likely(irq != NO_IRQ)) {
-		push_cppr(vec);
-		return irq;
-	}
-
-	/* We don't have a linux mapping, so have RTAS mask it. */
-	xics_mask_unknown_vec(vec);
-
-	/* We might learn about it later, so EOI it */
-	lpar_xirr_info_set(xirr);
-	return NO_IRQ;
-}
-
-static unsigned char pop_cppr(void)
-{
-	struct xics_cppr *os_cppr = &__get_cpu_var(xics_cppr);
-
-	if (WARN_ON(os_cppr->index < 1))
-		return LOWEST_PRIORITY;
-
-	return os_cppr->stack[--os_cppr->index];
-}
-
-static void xics_eoi_direct(struct irq_data *d)
-{
-	unsigned int hwirq = (unsigned int)irq_map[d->irq].hwirq;
-
-	iosync();
-	direct_xirr_info_set((pop_cppr() << 24) | hwirq);
-}
-
-static void xics_eoi_lpar(struct irq_data *d)
-{
-	unsigned int hwirq = (unsigned int)irq_map[d->irq].hwirq;
-
-	iosync();
-	lpar_xirr_info_set((pop_cppr() << 24) | hwirq);
-}
-
-static int
-xics_set_affinity(struct irq_data *d, const struct cpumask *cpumask, bool force)
-{
-	unsigned int hwirq;
-	int status;
-	int xics_status[2];
-	int irq_server;
-
-	hwirq = (unsigned int)irq_map[d->irq].hwirq;
-	if (hwirq == XICS_IPI || hwirq == XICS_IRQ_SPURIOUS)
-		return -1;
-
-	status = rtas_call(ibm_get_xive, 1, 3, xics_status, hwirq);
-
-	if (status) {
-		printk(KERN_ERR "%s: ibm,get-xive irq=%u returns %d\n",
-			__func__, hwirq, status);
-		return -1;
-	}
-
-	irq_server = get_irq_server(d->irq, cpumask, 1);
-	if (irq_server == -1) {
-		char cpulist[128];
-		cpumask_scnprintf(cpulist, sizeof(cpulist), cpumask);
-		printk(KERN_WARNING
-			"%s: No online cpus in the mask %s for irq %d\n",
-			__func__, cpulist, d->irq);
-		return -1;
-	}
-
-	status = rtas_call(ibm_set_xive, 3, 1, NULL,
-				hwirq, irq_server, xics_status[1]);
-
-	if (status) {
-		printk(KERN_ERR "%s: ibm,set-xive irq=%u returns %d\n",
-			__func__, hwirq, status);
-		return -1;
-	}
-
-	return 0;
-}
-
-static struct irq_chip xics_pic_direct = {
-	.name = "XICS",
-	.irq_startup = xics_startup,
-	.irq_mask = xics_mask_irq,
-	.irq_unmask = xics_unmask_irq,
-	.irq_eoi = xics_eoi_direct,
-	.irq_set_affinity = xics_set_affinity
-};
-
-static struct irq_chip xics_pic_lpar = {
-	.name = "XICS",
-	.irq_startup = xics_startup,
-	.irq_mask = xics_mask_irq,
-	.irq_unmask = xics_unmask_irq,
-	.irq_eoi = xics_eoi_lpar,
-	.irq_set_affinity = xics_set_affinity
-};
-
-
-/* Interface to arch irq controller subsystem layer */
-
-/* Points to the irq_chip we're actually using */
-static struct irq_chip *xics_irq_chip;
-
-static int xics_host_match(struct irq_host *h, struct device_node *node)
-{
-	/* IBM machines have interrupt parents of various funky types for things
-	 * like vdevices, events, etc... The trick we use here is to match
-	 * everything here except the legacy 8259 which is compatible "chrp,iic"
-	 */
-	return !of_device_is_compatible(node, "chrp,iic");
-}
-
-static int xics_host_map(struct irq_host *h, unsigned int virq,
-			 irq_hw_number_t hw)
-{
-	pr_devel("xics: map virq %d, hwirq 0x%lx\n", virq, hw);
-
-	/* Insert the interrupt mapping into the radix tree for fast lookup */
-	irq_radix_revmap_insert(xics_host, virq, hw);
-
-	irq_set_status_flags(virq, IRQ_LEVEL);
-	irq_set_chip_and_handler(virq, xics_irq_chip, handle_fasteoi_irq);
-	return 0;
-}
-
-static int xics_host_xlate(struct irq_host *h, struct device_node *ct,
-			   const u32 *intspec, unsigned int intsize,
-			   irq_hw_number_t *out_hwirq, unsigned int *out_flags)
-
-{
-	/* Current xics implementation translates everything
-	 * to level. It is not technically right for MSIs but this
-	 * is irrelevant at this point. We might get smarter in the future
-	 */
-	*out_hwirq = intspec[0];
-	*out_flags = IRQ_TYPE_LEVEL_LOW;
-
-	return 0;
-}
-
-static struct irq_host_ops xics_host_ops = {
-	.match = xics_host_match,
-	.map = xics_host_map,
-	.xlate = xics_host_xlate,
-};
-
-static void __init xics_init_host(void)
-{
-	if (firmware_has_feature(FW_FEATURE_LPAR))
-		xics_irq_chip = &xics_pic_lpar;
-	else
-		xics_irq_chip = &xics_pic_direct;
-
-	xics_host = irq_alloc_host(NULL, IRQ_HOST_MAP_TREE, 0, &xics_host_ops,
-				   XICS_IRQ_SPURIOUS);
-	BUG_ON(xics_host == NULL);
-	irq_set_default_host(xics_host);
-}
-
-
-/* Inter-processor interrupt support */
-
-#ifdef CONFIG_SMP
-/*
- * XICS only has a single IPI, so encode the messages per CPU
- */
-static DEFINE_PER_CPU_SHARED_ALIGNED(unsigned long, xics_ipi_message);
-
-static inline void smp_xics_do_message(int cpu, int msg)
-{
-	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);
-	else
-		direct_qirr_info(cpu, IPI_PRIORITY);
-}
-
-void smp_xics_message_pass(int target, int msg)
-{
-	unsigned int i;
-
-	if (target < NR_CPUS) {
-		smp_xics_do_message(target, msg);
-	} else {
-		for_each_online_cpu(i) {
-			if (target == MSG_ALL_BUT_SELF
-			    && i == smp_processor_id())
-				continue;
-			smp_xics_do_message(i, msg);
-		}
-	}
-}
-
-static irqreturn_t xics_ipi_dispatch(int cpu)
-{
-	unsigned long *tgt = &per_cpu(xics_ipi_message, cpu);
-
-	mb();	/* order mmio clearing qirr */
-	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, tgt)) {
-			smp_message_recv(PPC_MSG_RESCHEDULE);
-		}
-		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, tgt)) {
-			smp_message_recv(PPC_MSG_DEBUGGER_BREAK);
-		}
-#endif
-	}
-	return IRQ_HANDLED;
-}
-
-static irqreturn_t xics_ipi_action_direct(int irq, void *dev_id)
-{
-	int cpu = smp_processor_id();
-
-	direct_qirr_info(cpu, 0xff);
-
-	return xics_ipi_dispatch(cpu);
-}
-
-static irqreturn_t xics_ipi_action_lpar(int irq, void *dev_id)
-{
-	int cpu = smp_processor_id();
-
-	lpar_qirr_info(cpu, 0xff);
-
-	return xics_ipi_dispatch(cpu);
-}
-
-static void xics_request_ipi(void)
-{
-	unsigned int ipi;
-	int rc;
-
-	ipi = irq_create_mapping(xics_host, XICS_IPI);
-	BUG_ON(ipi == NO_IRQ);
-
-	/*
-	 * IPIs are marked IRQF_DISABLED as they must run with irqs
-	 * disabled
-	 */
-	irq_set_handler(ipi, handle_percpu_irq);
-	if (firmware_has_feature(FW_FEATURE_LPAR))
-		rc = request_irq(ipi, xics_ipi_action_lpar,
-				IRQF_DISABLED|IRQF_PERCPU, "IPI", NULL);
-	else
-		rc = request_irq(ipi, xics_ipi_action_direct,
-				IRQF_DISABLED|IRQF_PERCPU, "IPI", NULL);
-	BUG_ON(rc);
-}
-
-int __init smp_xics_probe(void)
-{
-	xics_request_ipi();
-
-	return cpumask_weight(cpu_possible_mask);
-}
-
-#endif /* CONFIG_SMP */
-
-
-/* Initialization */
-
-static void xics_update_irq_servers(void)
-{
-	int i, j;
-	struct device_node *np;
-	u32 ilen;
-	const u32 *ireg;
-	u32 hcpuid;
-
-	/* Find the server numbers for the boot cpu. */
-	np = of_get_cpu_node(boot_cpuid, NULL);
-	BUG_ON(!np);
-
-	ireg = of_get_property(np, "ibm,ppc-interrupt-gserver#s", &ilen);
-	if (!ireg) {
-		of_node_put(np);
-		return;
-	}
-
-	i = ilen / sizeof(int);
-	hcpuid = get_hard_smp_processor_id(boot_cpuid);
-
-	/* Global interrupt distribution server is specified in the last
-	 * entry of "ibm,ppc-interrupt-gserver#s" property. Get the last
-	 * entry fom this property for current boot cpu id and use it as
-	 * default distribution server
-	 */
-	for (j = 0; j < i; j += 2) {
-		if (ireg[j] == hcpuid) {
-			default_server = hcpuid;
-			default_distrib_server = ireg[j+1];
-		}
-	}
-
-	of_node_put(np);
-}
-
-static void __init xics_map_one_cpu(int hw_id, unsigned long addr,
-				     unsigned long size)
-{
-	int i;
-
-	/* This may look gross but it's good enough for now, we don't quite
-	 * have a hard -> linux processor id matching.
-	 */
-	for_each_possible_cpu(i) {
-		if (!cpu_present(i))
-			continue;
-		if (hw_id == get_hard_smp_processor_id(i)) {
-			xics_per_cpu[i] = ioremap(addr, size);
-			return;
-		}
-	}
-}
-
-static void __init xics_init_one_node(struct device_node *np,
-				      unsigned int *indx)
-{
-	unsigned int ilen;
-	const u32 *ireg;
-
-	/* This code does the theorically broken assumption that the interrupt
-	 * server numbers are the same as the hard CPU numbers.
-	 * This happens to be the case so far but we are playing with fire...
-	 * should be fixed one of these days. -BenH.
-	 */
-	ireg = of_get_property(np, "ibm,interrupt-server-ranges", NULL);
-
-	/* Do that ever happen ? we'll know soon enough... but even good'old
-	 * f80 does have that property ..
-	 */
-	WARN_ON(ireg == NULL);
-	if (ireg) {
-		/*
-		 * set node starting index for this node
-		 */
-		*indx = *ireg;
-	}
-	ireg = of_get_property(np, "reg", &ilen);
-	if (!ireg)
-		panic("xics_init_IRQ: can't find interrupt reg property");
-
-	while (ilen >= (4 * sizeof(u32))) {
-		unsigned long addr, size;
-
-		/* XXX Use proper OF parsing code here !!! */
-		addr = (unsigned long)*ireg++ << 32;
-		ilen -= sizeof(u32);
-		addr |= *ireg++;
-		ilen -= sizeof(u32);
-		size = (unsigned long)*ireg++ << 32;
-		ilen -= sizeof(u32);
-		size |= *ireg++;
-		ilen -= sizeof(u32);
-		xics_map_one_cpu(*indx, addr, size);
-		(*indx)++;
-	}
-}
-
-void __init xics_init_IRQ(void)
-{
-	struct device_node *np;
-	u32 indx = 0;
-	int found = 0;
-	const u32 *isize;
-
-	ppc64_boot_msg(0x20, "XICS Init");
-
-	ibm_get_xive = rtas_token("ibm,get-xive");
-	ibm_set_xive = rtas_token("ibm,set-xive");
-	ibm_int_on  = rtas_token("ibm,int-on");
-	ibm_int_off = rtas_token("ibm,int-off");
-
-	for_each_node_by_type(np, "PowerPC-External-Interrupt-Presentation") {
-		found = 1;
-		if (firmware_has_feature(FW_FEATURE_LPAR)) {
-			of_node_put(np);
-			break;
-			}
-		xics_init_one_node(np, &indx);
-	}
-	if (found == 0)
-		return;
-
-	/* get the bit size of server numbers */
-	found = 0;
-
-	for_each_compatible_node(np, NULL, "ibm,ppc-xics") {
-		isize = of_get_property(np, "ibm,interrupt-server#-size", NULL);
-
-		if (!isize)
-			continue;
-
-		if (!found) {
-			interrupt_server_size = *isize;
-			found = 1;
-		} else if (*isize != interrupt_server_size) {
-			printk(KERN_WARNING "XICS: "
-			       "mismatched ibm,interrupt-server#-size\n");
-			interrupt_server_size = max(*isize,
-						    interrupt_server_size);
-		}
-	}
-
-	xics_update_irq_servers();
-	xics_init_host();
-
-	if (firmware_has_feature(FW_FEATURE_LPAR))
-		ppc_md.get_irq = xics_get_irq_lpar;
-	else
-		ppc_md.get_irq = xics_get_irq_direct;
-
-	xics_setup_cpu();
-
-	ppc64_boot_msg(0x21, "XICS Done");
-}
-
-/* Cpu startup, shutdown, and hotplug */
-
-static void xics_set_cpu_priority(unsigned char cppr)
-{
-	struct xics_cppr *os_cppr = &__get_cpu_var(xics_cppr);
-
-	/*
-	 * we only really want to set the priority when there's
-	 * just one cppr value on the stack
-	 */
-	WARN_ON(os_cppr->index != 0);
-
-	os_cppr->stack[0] = cppr;
-
-	if (firmware_has_feature(FW_FEATURE_LPAR))
-		lpar_cppr_info(cppr);
-	else
-		direct_cppr_info(cppr);
-	iosync();
-}
-
-/* Have the calling processor join or leave the specified global queue */
-static void xics_set_cpu_giq(unsigned int gserver, unsigned int join)
-{
-	int index;
-	int status;
-
-	if (!rtas_indicator_present(GLOBAL_INTERRUPT_QUEUE, NULL))
-		return;
-
-	index = (1UL << interrupt_server_size) - 1 - gserver;
-
-	status = rtas_set_indicator_fast(GLOBAL_INTERRUPT_QUEUE, index, join);
-
-	WARN(status < 0, "set-indicator(%d, %d, %u) returned %d\n",
-	     GLOBAL_INTERRUPT_QUEUE, index, join, status);
-}
-
-void xics_setup_cpu(void)
-{
-	xics_set_cpu_priority(LOWEST_PRIORITY);
-
-	xics_set_cpu_giq(default_distrib_server, 1);
-}
-
-void xics_teardown_cpu(void)
-{
-	struct xics_cppr *os_cppr = &__get_cpu_var(xics_cppr);
-	int cpu = smp_processor_id();
-
-	/*
-	 * we have to reset the cppr index to 0 because we're
-	 * not going to return from the IPI
-	 */
-	os_cppr->index = 0;
-	xics_set_cpu_priority(0);
-
-	/* Clear any pending IPI request */
-	if (firmware_has_feature(FW_FEATURE_LPAR))
-		lpar_qirr_info(cpu, 0xff);
-	else
-		direct_qirr_info(cpu, 0xff);
-}
-
-void xics_kexec_teardown_cpu(int secondary)
-{
-	xics_teardown_cpu();
-
-	/*
-	 * we take the ipi irq but and never return so we
-	 * need to EOI the IPI, but want to leave our priority 0
-	 *
-	 * should we check all the other interrupts too?
-	 * should we be flagging idle loop instead?
-	 * or creating some task to be scheduled?
-	 */
-
-	if (firmware_has_feature(FW_FEATURE_LPAR))
-		lpar_xirr_info_set((0x00 << 24) | XICS_IPI);
-	else
-		direct_xirr_info_set((0x00 << 24) | XICS_IPI);
-
-	/*
-	 * Some machines need to have at least one cpu in the GIQ,
-	 * so leave the master cpu in the group.
-	 */
-	if (secondary)
-		xics_set_cpu_giq(default_distrib_server, 0);
-}
-
-#ifdef CONFIG_HOTPLUG_CPU
-
-/* Interrupts are disabled. */
-void xics_migrate_irqs_away(void)
-{
-	int cpu = smp_processor_id(), hw_cpu = hard_smp_processor_id();
-	int virq;
-
-	/* If we used to be the default server, move to the new "boot_cpuid" */
-	if (hw_cpu == default_server)
-		xics_update_irq_servers();
-
-	/* Reject any interrupt that was queued to us... */
-	xics_set_cpu_priority(0);
-
-	/* Remove ourselves from the global interrupt queue */
-	xics_set_cpu_giq(default_distrib_server, 0);
-
-	/* Allow IPIs again... */
-	xics_set_cpu_priority(DEFAULT_PRIORITY);
-
-	for_each_irq(virq) {
-		struct irq_desc *desc;
-		struct irq_chip *chip;
-		unsigned int hwirq;
-		int xics_status[2];
-		int status;
-		unsigned long flags;
-
-		/* We can't set affinity on ISA interrupts */
-		if (virq < NUM_ISA_INTERRUPTS)
-			continue;
-		if (irq_map[virq].host != xics_host)
-			continue;
-		hwirq = (unsigned int)irq_map[virq].hwirq;
-		/* We need to get IPIs still. */
-		if (hwirq == XICS_IPI || hwirq == XICS_IRQ_SPURIOUS)
-			continue;
-
-		desc = irq_to_desc(virq);
-
-		/* We only need to migrate enabled IRQS */
-		if (desc == NULL || desc->action == NULL)
-			continue;
-
-		chip = irq_desc_get_chip(desc);
-		if (chip == NULL || chip->irq_set_affinity == NULL)
-			continue;
-
-		raw_spin_lock_irqsave(&desc->lock, flags);
-
-		status = rtas_call(ibm_get_xive, 1, 3, xics_status, hwirq);
-		if (status) {
-			printk(KERN_ERR "%s: ibm,get-xive irq=%u returns %d\n",
-					__func__, hwirq, status);
-			goto unlock;
-		}
-
-		/*
-		 * We only support delivery to all cpus or to one cpu.
-		 * The irq has to be migrated only in the single cpu
-		 * case.
-		 */
-		if (xics_status[0] != hw_cpu)
-			goto unlock;
-
-		/* This is expected during cpu offline. */
-		if (cpu_online(cpu))
-			printk(KERN_WARNING "IRQ %u affinity broken off cpu %u\n",
-			       virq, cpu);
-
-		/* Reset affinity to all cpus */
-		cpumask_setall(desc->irq_data.affinity);
-		chip->irq_set_affinity(&desc->irq_data, cpu_all_mask, true);
-unlock:
-		raw_spin_unlock_irqrestore(&desc->lock, flags);
-	}
-}
-#endif
diff -druN linux-2.6.39-libre/arch/powerpc/platforms/pseries/xics.h linux-3.0-rc7-libre/arch/powerpc/platforms/pseries/xics.h
--- linux-2.6.39-libre/arch/powerpc/platforms/pseries/xics.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/platforms/pseries/xics.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,23 +0,0 @@
-/*
- * arch/powerpc/platforms/pseries/xics.h
- *
- * Copyright 2000 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.
- */
-
-#ifndef _POWERPC_KERNEL_XICS_H
-#define _POWERPC_KERNEL_XICS_H
-
-extern void xics_init_IRQ(void);
-extern void xics_setup_cpu(void);
-extern void xics_teardown_cpu(void);
-extern void xics_kexec_teardown_cpu(int secondary);
-extern void xics_migrate_irqs_away(void);
-extern int smp_xics_probe(void);
-extern void smp_xics_message_pass(int target, int msg);
-
-#endif /* _POWERPC_KERNEL_XICS_H */
diff -druN linux-2.6.39-libre/arch/powerpc/platforms/wsp/ics.c linux-3.0-rc7-libre/arch/powerpc/platforms/wsp/ics.c
--- linux-2.6.39-libre/arch/powerpc/platforms/wsp/ics.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/powerpc/platforms/wsp/ics.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,712 @@
+/*
+ * Copyright 2008-2011 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/cpu.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/kernel.h>
+#include <linux/msi.h>
+#include <linux/of.h>
+#include <linux/slab.h>
+#include <linux/smp.h>
+#include <linux/spinlock.h>
+#include <linux/types.h>
+
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/xics.h>
+
+#include "wsp.h"
+#include "ics.h"
+
+
+/* WSP ICS */
+
+struct wsp_ics {
+	struct ics ics;
+	struct device_node *dn;
+	void __iomem *regs;
+	spinlock_t lock;
+	unsigned long *bitmap;
+	u32 chip_id;
+	u32 lsi_base;
+	u32 lsi_count;
+	u64 hwirq_start;
+	u64 count;
+#ifdef CONFIG_SMP
+	int *hwirq_cpu_map;
+#endif
+};
+
+#define to_wsp_ics(ics)	container_of(ics, struct wsp_ics, ics)
+
+#define INT_SRC_LAYER_BUID_REG(base)	((base) + 0x00)
+#define IODA_TBL_ADDR_REG(base)		((base) + 0x18)
+#define IODA_TBL_DATA_REG(base)		((base) + 0x20)
+#define XIVE_UPDATE_REG(base)		((base) + 0x28)
+#define ICS_INT_CAPS_REG(base)		((base) + 0x30)
+
+#define TBL_AUTO_INCREMENT	((1UL << 63) | (1UL << 15))
+#define TBL_SELECT_XIST		(1UL << 48)
+#define TBL_SELECT_XIVT		(1UL << 49)
+
+#define IODA_IRQ(irq)		((irq) & (0x7FFULL))	/* HRM 5.1.3.4 */
+
+#define XIST_REQUIRED		0x8
+#define XIST_REJECTED		0x4
+#define XIST_PRESENTED		0x2
+#define XIST_PENDING		0x1
+
+#define XIVE_SERVER_SHIFT	42
+#define XIVE_SERVER_MASK	0xFFFFULL
+#define XIVE_PRIORITY_MASK	0xFFULL
+#define XIVE_PRIORITY_SHIFT	32
+#define XIVE_WRITE_ENABLE	(1ULL << 63)
+
+/*
+ * The docs refer to a 6 bit field called ChipID, which consists of a
+ * 3 bit NodeID and a 3 bit ChipID. On WSP the ChipID is always zero
+ * so we ignore it, and every where we use "chip id" in this code we
+ * mean the NodeID.
+ */
+#define WSP_ICS_CHIP_SHIFT		17
+
+
+static struct wsp_ics *ics_list;
+static int num_ics;
+
+/* ICS Source controller accessors */
+
+static u64 wsp_ics_get_xive(struct wsp_ics *ics, unsigned int irq)
+{
+	unsigned long flags;
+	u64 xive;
+
+	spin_lock_irqsave(&ics->lock, flags);
+	out_be64(IODA_TBL_ADDR_REG(ics->regs), TBL_SELECT_XIVT | IODA_IRQ(irq));
+	xive = in_be64(IODA_TBL_DATA_REG(ics->regs));
+	spin_unlock_irqrestore(&ics->lock, flags);
+
+	return xive;
+}
+
+static void wsp_ics_set_xive(struct wsp_ics *ics, unsigned int irq, u64 xive)
+{
+	xive &= ~XIVE_ADDR_MASK;
+	xive |= (irq & XIVE_ADDR_MASK);
+	xive |= XIVE_WRITE_ENABLE;
+
+	out_be64(XIVE_UPDATE_REG(ics->regs), xive);
+}
+
+static u64 xive_set_server(u64 xive, unsigned int server)
+{
+	u64 mask = ~(XIVE_SERVER_MASK << XIVE_SERVER_SHIFT);
+
+	xive &= mask;
+	xive |= (server & XIVE_SERVER_MASK) << XIVE_SERVER_SHIFT;
+
+	return xive;
+}
+
+static u64 xive_set_priority(u64 xive, unsigned int priority)
+{
+	u64 mask = ~(XIVE_PRIORITY_MASK << XIVE_PRIORITY_SHIFT);
+
+	xive &= mask;
+	xive |= (priority & XIVE_PRIORITY_MASK) << XIVE_PRIORITY_SHIFT;
+
+	return xive;
+}
+
+
+#ifdef CONFIG_SMP
+/* Find logical CPUs within mask on a given chip and store result in ret */
+void cpus_on_chip(int chip_id, cpumask_t *mask, cpumask_t *ret)
+{
+	int cpu, chip;
+	struct device_node *cpu_dn, *dn;
+	const u32 *prop;
+
+	cpumask_clear(ret);
+	for_each_cpu(cpu, mask) {
+		cpu_dn = of_get_cpu_node(cpu, NULL);
+		if (!cpu_dn)
+			continue;
+
+		prop = of_get_property(cpu_dn, "at-node", NULL);
+		if (!prop) {
+			of_node_put(cpu_dn);
+			continue;
+		}
+
+		dn = of_find_node_by_phandle(*prop);
+		of_node_put(cpu_dn);
+
+		chip = wsp_get_chip_id(dn);
+		if (chip == chip_id)
+			cpumask_set_cpu(cpu, ret);
+
+		of_node_put(dn);
+	}
+}
+
+/* Store a suitable CPU to handle a hwirq in the ics->hwirq_cpu_map cache */
+static int cache_hwirq_map(struct wsp_ics *ics, unsigned int hwirq,
+			   const cpumask_t *affinity)
+{
+	cpumask_var_t avail, newmask;
+	int ret = -ENOMEM, cpu, cpu_rover = 0, target;
+	int index = hwirq - ics->hwirq_start;
+	unsigned int nodeid;
+
+	BUG_ON(index < 0 || index >= ics->count);
+
+	if (!ics->hwirq_cpu_map)
+		return -ENOMEM;
+
+	if (!distribute_irqs) {
+		ics->hwirq_cpu_map[hwirq - ics->hwirq_start] = xics_default_server;
+		return 0;
+	}
+
+	/* Allocate needed CPU masks */
+	if (!alloc_cpumask_var(&avail, GFP_KERNEL))
+		goto ret;
+	if (!alloc_cpumask_var(&newmask, GFP_KERNEL))
+		goto freeavail;
+
+	/* Find PBus attached to the source of this IRQ */
+	nodeid = (hwirq >> WSP_ICS_CHIP_SHIFT) & 0x3; /* 12:14 */
+
+	/* Find CPUs that could handle this IRQ */
+	if (affinity)
+		cpumask_and(avail, cpu_online_mask, affinity);
+	else
+		cpumask_copy(avail, cpu_online_mask);
+
+	/* Narrow selection down to logical CPUs on the same chip */
+	cpus_on_chip(nodeid, avail, newmask);
+
+	/* Ensure we haven't narrowed it down to 0 */
+	if (unlikely(cpumask_empty(newmask))) {
+		if (unlikely(cpumask_empty(avail))) {
+			ret = -1;
+			goto out;
+		}
+		cpumask_copy(newmask, avail);
+	}
+
+	/* Choose a CPU out of those we narrowed it down to in round robin */
+	target = hwirq % cpumask_weight(newmask);
+	for_each_cpu(cpu, newmask) {
+		if (cpu_rover++ >= target) {
+			ics->hwirq_cpu_map[index] = get_hard_smp_processor_id(cpu);
+			ret = 0;
+			goto out;
+		}
+	}
+
+	/* Shouldn't happen */
+	WARN_ON(1);
+
+out:
+	free_cpumask_var(newmask);
+freeavail:
+	free_cpumask_var(avail);
+ret:
+	if (ret < 0) {
+		ics->hwirq_cpu_map[index] = cpumask_first(cpu_online_mask);
+		pr_warning("Error, falling hwirq 0x%x routing back to CPU %i\n",
+			   hwirq, ics->hwirq_cpu_map[index]);
+	}
+	return ret;
+}
+
+static void alloc_irq_map(struct wsp_ics *ics)
+{
+	int i;
+
+	ics->hwirq_cpu_map = kmalloc(sizeof(int) * ics->count, GFP_KERNEL);
+	if (!ics->hwirq_cpu_map) {
+		pr_warning("Allocate hwirq_cpu_map failed, "
+			   "IRQ balancing disabled\n");
+		return;
+	}
+
+	for (i=0; i < ics->count; i++)
+		ics->hwirq_cpu_map[i] = xics_default_server;
+}
+
+static int get_irq_server(struct wsp_ics *ics, unsigned int hwirq)
+{
+	int index = hwirq - ics->hwirq_start;
+
+	BUG_ON(index < 0 || index >= ics->count);
+
+	if (!ics->hwirq_cpu_map)
+		return xics_default_server;
+
+	return ics->hwirq_cpu_map[index];
+}
+#else /* !CONFIG_SMP */
+static int cache_hwirq_map(struct wsp_ics *ics, unsigned int hwirq,
+			   const cpumask_t *affinity)
+{
+	return 0;
+}
+
+static int get_irq_server(struct wsp_ics *ics, unsigned int hwirq)
+{
+	return xics_default_server;
+}
+
+static void alloc_irq_map(struct wsp_ics *ics) { }
+#endif
+
+static void wsp_chip_unmask_irq(struct irq_data *d)
+{
+	unsigned int hw_irq = (unsigned int)irqd_to_hwirq(d);
+	struct wsp_ics *ics;
+	int server;
+	u64 xive;
+
+	if (hw_irq == XICS_IPI || hw_irq == XICS_IRQ_SPURIOUS)
+		return;
+
+	ics = d->chip_data;
+	if (WARN_ON(!ics))
+		return;
+
+	server = get_irq_server(ics, hw_irq);
+
+	xive = wsp_ics_get_xive(ics, hw_irq);
+	xive = xive_set_server(xive, server);
+	xive = xive_set_priority(xive, DEFAULT_PRIORITY);
+	wsp_ics_set_xive(ics, hw_irq, xive);
+}
+
+static unsigned int wsp_chip_startup(struct irq_data *d)
+{
+	/* unmask it */
+	wsp_chip_unmask_irq(d);
+	return 0;
+}
+
+static void wsp_mask_real_irq(unsigned int hw_irq, struct wsp_ics *ics)
+{
+	u64 xive;
+
+	if (hw_irq == XICS_IPI)
+		return;
+
+	if (WARN_ON(!ics))
+		return;
+	xive = wsp_ics_get_xive(ics, hw_irq);
+	xive = xive_set_server(xive, xics_default_server);
+	xive = xive_set_priority(xive, LOWEST_PRIORITY);
+	wsp_ics_set_xive(ics, hw_irq, xive);
+}
+
+static void wsp_chip_mask_irq(struct irq_data *d)
+{
+	unsigned int hw_irq = (unsigned int)irqd_to_hwirq(d);
+	struct wsp_ics *ics = d->chip_data;
+
+	if (hw_irq == XICS_IPI || hw_irq == XICS_IRQ_SPURIOUS)
+		return;
+
+	wsp_mask_real_irq(hw_irq, ics);
+}
+
+static int wsp_chip_set_affinity(struct irq_data *d,
+				 const struct cpumask *cpumask, bool force)
+{
+	unsigned int hw_irq = (unsigned int)irqd_to_hwirq(d);
+	struct wsp_ics *ics;
+	int ret;
+	u64 xive;
+
+	if (hw_irq == XICS_IPI || hw_irq == XICS_IRQ_SPURIOUS)
+		return -1;
+
+	ics = d->chip_data;
+	if (WARN_ON(!ics))
+		return -1;
+	xive = wsp_ics_get_xive(ics, hw_irq);
+
+	/*
+	 * For the moment only implement delivery to all cpus or one cpu.
+	 * Get current irq_server for the given irq
+	 */
+	ret = cache_hwirq_map(ics, d->irq, cpumask);
+	if (ret == -1) {
+		char cpulist[128];
+		cpumask_scnprintf(cpulist, sizeof(cpulist), cpumask);
+		pr_warning("%s: No online cpus in the mask %s for irq %d\n",
+			   __func__, cpulist, d->irq);
+		return -1;
+	} else if (ret == -ENOMEM) {
+		pr_warning("%s: Out of memory\n", __func__);
+		return -1;
+	}
+
+	xive = xive_set_server(xive, get_irq_server(ics, hw_irq));
+	wsp_ics_set_xive(ics, hw_irq, xive);
+
+	return 0;
+}
+
+static struct irq_chip wsp_irq_chip = {
+	.name = "WSP ICS",
+	.irq_startup		= wsp_chip_startup,
+	.irq_mask		= wsp_chip_mask_irq,
+	.irq_unmask		= wsp_chip_unmask_irq,
+	.irq_set_affinity	= wsp_chip_set_affinity
+};
+
+static int wsp_ics_host_match(struct ics *ics, struct device_node *dn)
+{
+	/* All ICSs in the system implement a global irq number space,
+	 * so match against them all. */
+	return of_device_is_compatible(dn, "ibm,ppc-xics");
+}
+
+static int wsp_ics_match_hwirq(struct wsp_ics *wsp_ics, unsigned int hwirq)
+{
+	if (hwirq >= wsp_ics->hwirq_start &&
+	    hwirq <  wsp_ics->hwirq_start + wsp_ics->count)
+		return 1;
+
+	return 0;
+}
+
+static int wsp_ics_map(struct ics *ics, unsigned int virq)
+{
+	struct wsp_ics *wsp_ics = to_wsp_ics(ics);
+	unsigned int hw_irq = virq_to_hw(virq);
+	unsigned long flags;
+
+	if (!wsp_ics_match_hwirq(wsp_ics, hw_irq))
+		return -ENOENT;
+
+	irq_set_chip_and_handler(virq, &wsp_irq_chip, handle_fasteoi_irq);
+
+	irq_set_chip_data(virq, wsp_ics);
+
+	spin_lock_irqsave(&wsp_ics->lock, flags);
+	bitmap_allocate_region(wsp_ics->bitmap, hw_irq - wsp_ics->hwirq_start, 0);
+	spin_unlock_irqrestore(&wsp_ics->lock, flags);
+
+	return 0;
+}
+
+static void wsp_ics_mask_unknown(struct ics *ics, unsigned long hw_irq)
+{
+	struct wsp_ics *wsp_ics = to_wsp_ics(ics);
+
+	if (!wsp_ics_match_hwirq(wsp_ics, hw_irq))
+		return;
+
+	pr_err("%s: IRQ %lu (real) is invalid, disabling it.\n", __func__, hw_irq);
+	wsp_mask_real_irq(hw_irq, wsp_ics);
+}
+
+static long wsp_ics_get_server(struct ics *ics, unsigned long hw_irq)
+{
+	struct wsp_ics *wsp_ics = to_wsp_ics(ics);
+
+	if (!wsp_ics_match_hwirq(wsp_ics, hw_irq))
+		return -ENOENT;
+
+	return get_irq_server(wsp_ics, hw_irq);
+}
+
+/* HW Number allocation API */
+
+static struct wsp_ics *wsp_ics_find_dn_ics(struct device_node *dn)
+{
+	struct device_node *iparent;
+	int i;
+
+	iparent = of_irq_find_parent(dn);
+	if (!iparent) {
+		pr_err("wsp_ics: Failed to find interrupt parent!\n");
+		return NULL;
+	}
+
+	for(i = 0; i < num_ics; i++) {
+		if(ics_list[i].dn == iparent)
+			break;
+	}
+
+	if (i >= num_ics) {
+		pr_err("wsp_ics: Unable to find parent bitmap!\n");
+		return NULL;
+	}
+
+	return &ics_list[i];
+}
+
+int wsp_ics_alloc_irq(struct device_node *dn, int num)
+{
+	struct wsp_ics *ics;
+	int order, offset;
+
+	ics = wsp_ics_find_dn_ics(dn);
+	if (!ics)
+		return -ENODEV;
+
+	/* Fast, but overly strict if num isn't a power of two */
+	order = get_count_order(num);
+
+	spin_lock_irq(&ics->lock);
+	offset = bitmap_find_free_region(ics->bitmap, ics->count, order);
+	spin_unlock_irq(&ics->lock);
+
+	if (offset < 0)
+		return offset;
+
+	return offset + ics->hwirq_start;
+}
+
+void wsp_ics_free_irq(struct device_node *dn, unsigned int irq)
+{
+	struct wsp_ics *ics;
+
+	ics = wsp_ics_find_dn_ics(dn);
+	if (WARN_ON(!ics))
+		return;
+
+	spin_lock_irq(&ics->lock);
+	bitmap_release_region(ics->bitmap, irq, 0);
+	spin_unlock_irq(&ics->lock);
+}
+
+/* Initialisation */
+
+static int __init wsp_ics_bitmap_setup(struct wsp_ics *ics,
+				      struct device_node *dn)
+{
+	int len, i, j, size;
+	u32 start, count;
+	const u32 *p;
+
+	size = BITS_TO_LONGS(ics->count) * sizeof(long);
+	ics->bitmap = kzalloc(size, GFP_KERNEL);
+	if (!ics->bitmap) {
+		pr_err("wsp_ics: ENOMEM allocating IRQ bitmap!\n");
+		return -ENOMEM;
+	}
+
+	spin_lock_init(&ics->lock);
+
+	p = of_get_property(dn, "available-ranges", &len);
+	if (!p || !len) {
+		/* FIXME this should be a WARN() once mambo is updated */
+		pr_err("wsp_ics: No available-ranges defined for %s\n",
+			dn->full_name);
+		return 0;
+	}
+
+	if (len % (2 * sizeof(u32)) != 0) {
+		/* FIXME this should be a WARN() once mambo is updated */
+		pr_err("wsp_ics: Invalid available-ranges for %s\n",
+			dn->full_name);
+		return 0;
+	}
+
+	bitmap_fill(ics->bitmap, ics->count);
+
+	for (i = 0; i < len / sizeof(u32); i += 2) {
+		start = of_read_number(p + i, 1);
+		count = of_read_number(p + i + 1, 1);
+
+		pr_devel("%s: start: %d count: %d\n", __func__, start, count);
+
+		if ((start + count) > (ics->hwirq_start + ics->count) ||
+		     start < ics->hwirq_start) {
+			pr_err("wsp_ics: Invalid range! -> %d to %d\n",
+					start, start + count);
+			break;
+		}
+
+		for (j = 0; j < count; j++)
+			bitmap_release_region(ics->bitmap,
+				(start + j) - ics->hwirq_start, 0);
+	}
+
+	/* Ensure LSIs are not available for allocation */
+	bitmap_allocate_region(ics->bitmap, ics->lsi_base,
+			       get_count_order(ics->lsi_count));
+
+	return 0;
+}
+
+static int __init wsp_ics_setup(struct wsp_ics *ics, struct device_node *dn)
+{
+	u32 lsi_buid, msi_buid, msi_base, msi_count;
+	void __iomem *regs;
+	const u32 *p;
+	int rc, len, i;
+	u64 caps, buid;
+
+	p = of_get_property(dn, "interrupt-ranges", &len);
+	if (!p || len < (2 * sizeof(u32))) {
+		pr_err("wsp_ics: No/bad interrupt-ranges found on %s\n",
+			dn->full_name);
+		return -ENOENT;
+	}
+
+	if (len > (2 * sizeof(u32))) {
+		pr_err("wsp_ics: Multiple ics ranges not supported.\n");
+		return -EINVAL;
+	}
+
+	regs = of_iomap(dn, 0);
+	if (!regs) {
+		pr_err("wsp_ics: of_iomap(%s) failed\n", dn->full_name);
+		return -ENXIO;
+	}
+
+	ics->hwirq_start = of_read_number(p, 1);
+	ics->count = of_read_number(p + 1, 1);
+	ics->regs = regs;
+
+	ics->chip_id = wsp_get_chip_id(dn);
+	if (WARN_ON(ics->chip_id < 0))
+		ics->chip_id = 0;
+
+	/* Get some informations about the critter */
+	caps = in_be64(ICS_INT_CAPS_REG(ics->regs));
+	buid = in_be64(INT_SRC_LAYER_BUID_REG(ics->regs));
+	ics->lsi_count = caps >> 56;
+	msi_count = (caps >> 44) & 0x7ff;
+
+	/* Note: LSI BUID is 9 bits, but really only 3 are BUID and the
+	 * rest is mixed in the interrupt number. We store the whole
+	 * thing though
+	 */
+	lsi_buid = (buid >> 48) & 0x1ff;
+	ics->lsi_base = (ics->chip_id << WSP_ICS_CHIP_SHIFT) | lsi_buid << 5;
+	msi_buid = (buid >> 37) & 0x7;
+	msi_base = (ics->chip_id << WSP_ICS_CHIP_SHIFT) | msi_buid << 11;
+
+	pr_info("wsp_ics: Found %s\n", dn->full_name);
+	pr_info("wsp_ics:    irq range : 0x%06llx..0x%06llx\n",
+		ics->hwirq_start, ics->hwirq_start + ics->count - 1);
+	pr_info("wsp_ics:    %4d LSIs : 0x%06x..0x%06x\n",
+		ics->lsi_count, ics->lsi_base,
+		ics->lsi_base + ics->lsi_count - 1);
+	pr_info("wsp_ics:    %4d MSIs : 0x%06x..0x%06x\n",
+		msi_count, msi_base,
+		msi_base + msi_count - 1);
+
+	/* Let's check the HW config is sane */
+	if (ics->lsi_base < ics->hwirq_start ||
+	    (ics->lsi_base + ics->lsi_count) > (ics->hwirq_start + ics->count))
+		pr_warning("wsp_ics: WARNING ! LSIs out of interrupt-ranges !\n");
+	if (msi_base < ics->hwirq_start ||
+	    (msi_base + msi_count) > (ics->hwirq_start + ics->count))
+		pr_warning("wsp_ics: WARNING ! MSIs out of interrupt-ranges !\n");
+
+	/* We don't check for overlap between LSI and MSI, which will happen
+	 * if we use the same BUID, I'm not sure yet how legit that is.
+	 */
+
+	rc = wsp_ics_bitmap_setup(ics, dn);
+	if (rc) {
+		iounmap(regs);
+		return rc;
+	}
+
+	ics->dn = of_node_get(dn);
+	alloc_irq_map(ics);
+
+	for(i = 0; i < ics->count; i++)
+		wsp_mask_real_irq(ics->hwirq_start + i, ics);
+
+	ics->ics.map = wsp_ics_map;
+	ics->ics.mask_unknown = wsp_ics_mask_unknown;
+	ics->ics.get_server = wsp_ics_get_server;
+	ics->ics.host_match = wsp_ics_host_match;
+
+	xics_register_ics(&ics->ics);
+
+	return 0;
+}
+
+static void __init wsp_ics_set_default_server(void)
+{
+	struct device_node *np;
+	u32 hwid;
+
+	/* Find the server number for the boot cpu. */
+	np = of_get_cpu_node(boot_cpuid, NULL);
+	BUG_ON(!np);
+
+	hwid = get_hard_smp_processor_id(boot_cpuid);
+
+	pr_info("wsp_ics: default server is %#x, CPU %s\n", hwid, np->full_name);
+	xics_default_server = hwid;
+
+	of_node_put(np);
+}
+
+static int __init wsp_ics_init(void)
+{
+	struct device_node *dn;
+	struct wsp_ics *ics;
+	int rc, found;
+
+	wsp_ics_set_default_server();
+
+	found = 0;
+	for_each_compatible_node(dn, NULL, "ibm,ppc-xics")
+		found++;
+
+	if (found == 0) {
+		pr_err("wsp_ics: No ICS's found!\n");
+		return -ENODEV;
+	}
+
+	ics_list = kmalloc(sizeof(*ics) * found, GFP_KERNEL);
+	if (!ics_list) {
+		pr_err("wsp_ics: No memory for structs.\n");
+		return -ENOMEM;
+	}
+
+	num_ics = 0;
+	ics = ics_list;
+	for_each_compatible_node(dn, NULL, "ibm,wsp-xics") {
+		rc = wsp_ics_setup(ics, dn);
+		if (rc == 0) {
+			ics++;
+			num_ics++;
+		}
+	}
+
+	if (found != num_ics) {
+		pr_err("wsp_ics: Failed setting up %d ICS's\n",
+			found - num_ics);
+		return -1;
+	}
+
+	return 0;
+}
+
+void __init wsp_init_irq(void)
+{
+	wsp_ics_init();
+	xics_init();
+
+	/* We need to patch our irq chip's EOI to point to the right ICP */
+	wsp_irq_chip.irq_eoi = icp_ops->eoi;
+}
diff -druN linux-2.6.39-libre/arch/powerpc/platforms/wsp/ics.h linux-3.0-rc7-libre/arch/powerpc/platforms/wsp/ics.h
--- linux-2.6.39-libre/arch/powerpc/platforms/wsp/ics.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/powerpc/platforms/wsp/ics.h	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2009 IBM Corporation.
+ *
+ *  This program is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU General Public License
+ *  as published by the Free Software Foundation; either version
+ *  2 of the License, or (at your option) any later version.
+ */
+
+#ifndef __ICS_H
+#define __ICS_H
+
+#define XIVE_ADDR_MASK		0x7FFULL
+
+extern void wsp_init_irq(void);
+
+extern int wsp_ics_alloc_irq(struct device_node *dn, int num);
+extern void wsp_ics_free_irq(struct device_node *dn, unsigned int irq);
+
+#endif /* __ICS_H */
diff -druN linux-2.6.39-libre/arch/powerpc/platforms/wsp/Kconfig linux-3.0-rc7-libre/arch/powerpc/platforms/wsp/Kconfig
--- linux-2.6.39-libre/arch/powerpc/platforms/wsp/Kconfig	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/powerpc/platforms/wsp/Kconfig	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,28 @@
+config PPC_WSP
+	bool
+	default n
+
+menu "WSP platform selection"
+	depends on PPC_BOOK3E_64
+
+config PPC_PSR2
+	bool "PSR-2 platform"
+	select PPC_A2
+	select GENERIC_TBSYNC
+	select PPC_SCOM
+	select EPAPR_BOOT
+	select PPC_WSP
+	select PPC_XICS
+	select PPC_ICP_NATIVE
+	default y
+
+endmenu
+
+config PPC_A2_DD2
+	bool "Support for DD2 based A2/WSP systems"
+	depends on PPC_A2
+
+config WORKAROUND_ERRATUM_463
+	depends on PPC_A2_DD2
+	bool "Workaround erratum 463"
+	default y
diff -druN linux-2.6.39-libre/arch/powerpc/platforms/wsp/Makefile linux-3.0-rc7-libre/arch/powerpc/platforms/wsp/Makefile
--- linux-2.6.39-libre/arch/powerpc/platforms/wsp/Makefile	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/powerpc/platforms/wsp/Makefile	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,6 @@
+ccflags-y			+= -mno-minimal-toc
+
+obj-y				+= setup.o ics.o
+obj-$(CONFIG_PPC_PSR2)		+= psr2.o opb_pic.o
+obj-$(CONFIG_PPC_WSP)		+= scom_wsp.o
+obj-$(CONFIG_SMP)		+= smp.o scom_smp.o
diff -druN linux-2.6.39-libre/arch/powerpc/platforms/wsp/opb_pic.c linux-3.0-rc7-libre/arch/powerpc/platforms/wsp/opb_pic.c
--- linux-2.6.39-libre/arch/powerpc/platforms/wsp/opb_pic.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/powerpc/platforms/wsp/opb_pic.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,332 @@
+/*
+ * IBM Onboard Peripheral Bus Interrupt Controller
+ *
+ * Copyright 2010 Jack Miller, 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/interrupt.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/of.h>
+#include <linux/slab.h>
+#include <linux/time.h>
+
+#include <asm/reg_a2.h>
+#include <asm/irq.h>
+
+#define OPB_NR_IRQS 32
+
+#define OPB_MLSASIER	0x04    /* MLS Accumulated Status IER */
+#define OPB_MLSIR	0x50	/* MLS Interrupt Register */
+#define OPB_MLSIER	0x54	/* MLS Interrupt Enable Register */
+#define OPB_MLSIPR	0x58	/* MLS Interrupt Polarity Register */
+#define OPB_MLSIIR	0x5c	/* MLS Interrupt Inputs Register */
+
+static int opb_index = 0;
+
+struct opb_pic {
+	struct irq_host *host;
+	void *regs;
+	int index;
+	spinlock_t lock;
+};
+
+static u32 opb_in(struct opb_pic *opb, int offset)
+{
+	return in_be32(opb->regs + offset);
+}
+
+static void opb_out(struct opb_pic *opb, int offset, u32 val)
+{
+	out_be32(opb->regs + offset, val);
+}
+
+static void opb_unmask_irq(struct irq_data *d)
+{
+	struct opb_pic *opb;
+	unsigned long flags;
+	u32 ier, bitset;
+
+	opb = d->chip_data;
+	bitset = (1 << (31 - irqd_to_hwirq(d)));
+
+	spin_lock_irqsave(&opb->lock, flags);
+
+	ier = opb_in(opb, OPB_MLSIER);
+	opb_out(opb, OPB_MLSIER, ier | bitset);
+	ier = opb_in(opb, OPB_MLSIER);
+
+	spin_unlock_irqrestore(&opb->lock, flags);
+}
+
+static void opb_mask_irq(struct irq_data *d)
+{
+	struct opb_pic *opb;
+	unsigned long flags;
+	u32 ier, mask;
+
+	opb = d->chip_data;
+	mask = ~(1 << (31 - irqd_to_hwirq(d)));
+
+	spin_lock_irqsave(&opb->lock, flags);
+
+	ier = opb_in(opb, OPB_MLSIER);
+	opb_out(opb, OPB_MLSIER, ier & mask);
+	ier = opb_in(opb, OPB_MLSIER); // Flush posted writes
+
+	spin_unlock_irqrestore(&opb->lock, flags);
+}
+
+static void opb_ack_irq(struct irq_data *d)
+{
+	struct opb_pic *opb;
+	unsigned long flags;
+	u32 bitset;
+
+	opb = d->chip_data;
+	bitset = (1 << (31 - irqd_to_hwirq(d)));
+
+	spin_lock_irqsave(&opb->lock, flags);
+
+	opb_out(opb, OPB_MLSIR, bitset);
+	opb_in(opb, OPB_MLSIR); // Flush posted writes
+
+	spin_unlock_irqrestore(&opb->lock, flags);
+}
+
+static void opb_mask_ack_irq(struct irq_data *d)
+{
+	struct opb_pic *opb;
+	unsigned long flags;
+	u32 bitset;
+	u32 ier, ir;
+
+	opb = d->chip_data;
+	bitset = (1 << (31 - irqd_to_hwirq(d)));
+
+	spin_lock_irqsave(&opb->lock, flags);
+
+	ier = opb_in(opb, OPB_MLSIER);
+	opb_out(opb, OPB_MLSIER, ier & ~bitset);
+	ier = opb_in(opb, OPB_MLSIER); // Flush posted writes
+
+	opb_out(opb, OPB_MLSIR, bitset);
+	ir = opb_in(opb, OPB_MLSIR); // Flush posted writes
+
+	spin_unlock_irqrestore(&opb->lock, flags);
+}
+
+static int opb_set_irq_type(struct irq_data *d, unsigned int flow)
+{
+	struct opb_pic *opb;
+	unsigned long flags;
+	int invert, ipr, mask, bit;
+
+	opb = d->chip_data;
+
+	/* The only information we're interested in in the type is whether it's
+	 * a high or low trigger. For high triggered interrupts, the polarity
+	 * set for it in the MLS Interrupt Polarity Register is 0, for low
+	 * interrupts it's 1 so that the proper input in the MLS Interrupt Input
+	 * Register is interrupted as asserting the interrupt. */
+
+	switch (flow) {
+		case IRQ_TYPE_NONE:
+			opb_mask_irq(d);
+			return 0;
+
+		case IRQ_TYPE_LEVEL_HIGH:
+			invert = 0;
+			break;
+
+		case IRQ_TYPE_LEVEL_LOW:
+			invert = 1;
+			break;
+
+		default:
+			return -EINVAL;
+	}
+
+	bit = (1 << (31 - irqd_to_hwirq(d)));
+	mask = ~bit;
+
+	spin_lock_irqsave(&opb->lock, flags);
+
+	ipr = opb_in(opb, OPB_MLSIPR);
+	ipr = (ipr & mask) | (invert ? bit : 0);
+	opb_out(opb, OPB_MLSIPR, ipr);
+	ipr = opb_in(opb, OPB_MLSIPR);  // Flush posted writes
+
+	spin_unlock_irqrestore(&opb->lock, flags);
+
+	/* Record the type in the interrupt descriptor */
+	irqd_set_trigger_type(d, flow);
+
+	return 0;
+}
+
+static struct irq_chip opb_irq_chip = {
+	.name		= "OPB",
+	.irq_mask	= opb_mask_irq,
+	.irq_unmask	= opb_unmask_irq,
+	.irq_mask_ack	= opb_mask_ack_irq,
+	.irq_ack	= opb_ack_irq,
+	.irq_set_type	= opb_set_irq_type
+};
+
+static int opb_host_map(struct irq_host *host, unsigned int virq,
+		irq_hw_number_t hwirq)
+{
+	struct opb_pic *opb;
+
+	opb = host->host_data;
+
+	/* Most of the important stuff is handled by the generic host code, like
+	 * the lookup, so just attach some info to the virtual irq */
+
+	irq_set_chip_data(virq, opb);
+	irq_set_chip_and_handler(virq, &opb_irq_chip, handle_level_irq);
+	irq_set_irq_type(virq, IRQ_TYPE_NONE);
+
+	return 0;
+}
+
+static int opb_host_xlate(struct irq_host *host, struct device_node *dn,
+		const u32 *intspec, unsigned int intsize,
+		irq_hw_number_t *out_hwirq, unsigned int *out_type)
+{
+	/* Interrupt size must == 2 */
+	BUG_ON(intsize != 2);
+	*out_hwirq = intspec[0];
+	*out_type = intspec[1];
+	return 0;
+}
+
+static struct irq_host_ops opb_host_ops = {
+	.map = opb_host_map,
+	.xlate = opb_host_xlate,
+};
+
+irqreturn_t opb_irq_handler(int irq, void *private)
+{
+	struct opb_pic *opb;
+	u32 ir, src, subvirq;
+
+	opb = (struct opb_pic *) private;
+
+	/* Read the OPB MLS Interrupt Register for
+	 * asserted interrupts */
+	ir = opb_in(opb, OPB_MLSIR);
+	if (!ir)
+		return IRQ_NONE;
+
+	do {
+		/* Get 1 - 32 source, *NOT* bit */
+		src = 32 - ffs(ir);
+
+		/* Translate from the OPB's conception of interrupt number to
+		 * Linux's virtual IRQ */
+
+		subvirq = irq_linear_revmap(opb->host, src);
+
+		generic_handle_irq(subvirq);
+	} while ((ir = opb_in(opb, OPB_MLSIR)));
+
+	return IRQ_HANDLED;
+}
+
+struct opb_pic *opb_pic_init_one(struct device_node *dn)
+{
+	struct opb_pic *opb;
+	struct resource res;
+
+	if (of_address_to_resource(dn, 0, &res)) {
+		printk(KERN_ERR "opb: Couldn't translate resource\n");
+		return  NULL;
+	}
+
+	opb = kzalloc(sizeof(struct opb_pic), GFP_KERNEL);
+	if (!opb) {
+		printk(KERN_ERR "opb: Failed to allocate opb struct!\n");
+		return NULL;
+	}
+
+	/* Get access to the OPB MMIO registers */
+	opb->regs = ioremap(res.start + 0x10000, 0x1000);
+	if (!opb->regs) {
+		printk(KERN_ERR "opb: Failed to allocate register space!\n");
+		goto free_opb;
+	}
+
+	/* Allocate an irq host so that Linux knows that despite only
+	 * having one interrupt to issue, we're the controller for multiple
+	 * hardware IRQs, so later we can lookup their virtual IRQs. */
+
+	opb->host = irq_alloc_host(dn, IRQ_HOST_MAP_LINEAR,
+			OPB_NR_IRQS, &opb_host_ops, -1);
+
+	if (!opb->host) {
+		printk(KERN_ERR "opb: Failed to allocate IRQ host!\n");
+		goto free_regs;
+	}
+
+	opb->index = opb_index++;
+	spin_lock_init(&opb->lock);
+	opb->host->host_data = opb;
+
+	/* Disable all interrupts by default */
+	opb_out(opb, OPB_MLSASIER, 0);
+	opb_out(opb, OPB_MLSIER, 0);
+
+	/* ACK any interrupts left by FW */
+	opb_out(opb, OPB_MLSIR, 0xFFFFFFFF);
+
+	return opb;
+
+free_regs:
+	iounmap(opb->regs);
+free_opb:
+	kfree(opb);
+	return NULL;
+}
+
+void __init opb_pic_init(void)
+{
+	struct device_node *dn;
+	struct opb_pic *opb;
+	int virq;
+	int rc;
+
+	/* Call init_one for each OPB device */
+	for_each_compatible_node(dn, NULL, "ibm,opb") {
+
+		/* Fill in an OPB struct */
+		opb = opb_pic_init_one(dn);
+		if (!opb) {
+			printk(KERN_WARNING "opb: Failed to init node, skipped!\n");
+			continue;
+		}
+
+		/* Map / get opb's hardware virtual irq */
+		virq = irq_of_parse_and_map(dn, 0);
+		if (virq <= 0) {
+			printk("opb: irq_op_parse_and_map failed!\n");
+			continue;
+		}
+
+		/* Attach opb interrupt handler to new virtual IRQ */
+		rc = request_irq(virq, opb_irq_handler, 0, "OPB LS Cascade", opb);
+		if (rc) {
+			printk("opb: request_irq failed: %d\n", rc);
+			continue;
+		}
+
+		printk("OPB%d init with %d IRQs at %p\n", opb->index,
+				OPB_NR_IRQS, opb->regs);
+	}
+}
diff -druN linux-2.6.39-libre/arch/powerpc/platforms/wsp/psr2.c linux-3.0-rc7-libre/arch/powerpc/platforms/wsp/psr2.c
--- linux-2.6.39-libre/arch/powerpc/platforms/wsp/psr2.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/powerpc/platforms/wsp/psr2.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,95 @@
+/*
+ * Copyright 2008-2011, 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/delay.h>
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/of.h>
+#include <linux/smp.h>
+
+#include <asm/machdep.h>
+#include <asm/system.h>
+#include <asm/time.h>
+#include <asm/udbg.h>
+
+#include "ics.h"
+#include "wsp.h"
+
+
+static void psr2_spin(void)
+{
+	hard_irq_disable();
+	for (;;) ;
+}
+
+static void psr2_restart(char *cmd)
+{
+	psr2_spin();
+}
+
+static int psr2_probe_devices(void)
+{
+	struct device_node *np;
+
+	/* Our RTC is a ds1500. It seems to be programatically compatible
+	 * with the ds1511 for which we have a driver so let's use that
+	 */
+	np = of_find_compatible_node(NULL, NULL, "dallas,ds1500");
+	if (np != NULL) {
+		struct resource res;
+		if (of_address_to_resource(np, 0, &res) == 0)
+			platform_device_register_simple("ds1511", 0, &res, 1);
+	}
+	return 0;
+}
+machine_arch_initcall(psr2_md, psr2_probe_devices);
+
+static void __init psr2_setup_arch(void)
+{
+	/* init to some ~sane value until calibrate_delay() runs */
+	loops_per_jiffy = 50000000;
+
+	scom_init_wsp();
+
+	/* Setup SMP callback */
+#ifdef CONFIG_SMP
+	a2_setup_smp();
+#endif
+}
+
+static int __init psr2_probe(void)
+{
+	unsigned long root = of_get_flat_dt_root();
+
+	if (!of_flat_dt_is_compatible(root, "ibm,psr2"))
+		return 0;
+
+	return 1;
+}
+
+static void __init psr2_init_irq(void)
+{
+	wsp_init_irq();
+	opb_pic_init();
+}
+
+define_machine(psr2_md) {
+	.name			= "PSR2 A2",
+	.probe			= psr2_probe,
+	.setup_arch		= psr2_setup_arch,
+	.restart		= psr2_restart,
+	.power_off		= psr2_spin,
+	.halt			= psr2_spin,
+	.calibrate_decr		= generic_calibrate_decr,
+	.init_IRQ		= psr2_init_irq,
+	.progress		= udbg_progress,
+	.power_save		= book3e_idle,
+};
diff -druN linux-2.6.39-libre/arch/powerpc/platforms/wsp/scom_smp.c linux-3.0-rc7-libre/arch/powerpc/platforms/wsp/scom_smp.c
--- linux-2.6.39-libre/arch/powerpc/platforms/wsp/scom_smp.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/powerpc/platforms/wsp/scom_smp.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,427 @@
+/*
+ * SCOM support for A2 platforms
+ *
+ * Copyright 2007-2011 Benjamin Herrenschmidt, David Gibson,
+ *		       Michael Ellerman, IBM Corp.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/cpumask.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/spinlock.h>
+#include <linux/types.h>
+
+#include <asm/cputhreads.h>
+#include <asm/reg_a2.h>
+#include <asm/scom.h>
+#include <asm/udbg.h>
+
+#include "wsp.h"
+
+#define SCOM_RAMC		0x2a		/* Ram Command */
+#define SCOM_RAMC_TGT1_EXT	0x80000000
+#define SCOM_RAMC_SRC1_EXT	0x40000000
+#define SCOM_RAMC_SRC2_EXT	0x20000000
+#define SCOM_RAMC_SRC3_EXT	0x10000000
+#define SCOM_RAMC_ENABLE	0x00080000
+#define SCOM_RAMC_THREADSEL	0x00060000
+#define SCOM_RAMC_EXECUTE	0x00010000
+#define SCOM_RAMC_MSR_OVERRIDE	0x00008000
+#define SCOM_RAMC_MSR_PR	0x00004000
+#define SCOM_RAMC_MSR_GS	0x00002000
+#define SCOM_RAMC_FORCE		0x00001000
+#define SCOM_RAMC_FLUSH		0x00000800
+#define SCOM_RAMC_INTERRUPT	0x00000004
+#define SCOM_RAMC_ERROR		0x00000002
+#define SCOM_RAMC_DONE		0x00000001
+#define SCOM_RAMI		0x29		/* Ram Instruction */
+#define SCOM_RAMIC		0x28		/* Ram Instruction and Command */
+#define SCOM_RAMIC_INSN		0xffffffff00000000
+#define SCOM_RAMD		0x2d		/* Ram Data */
+#define SCOM_RAMDH		0x2e		/* Ram Data High */
+#define SCOM_RAMDL		0x2f		/* Ram Data Low */
+#define SCOM_PCCR0		0x33		/* PC Configuration Register 0 */
+#define SCOM_PCCR0_ENABLE_DEBUG	0x80000000
+#define SCOM_PCCR0_ENABLE_RAM	0x40000000
+#define SCOM_THRCTL		0x30		/* Thread Control and Status */
+#define SCOM_THRCTL_T0_STOP	0x80000000
+#define SCOM_THRCTL_T1_STOP	0x40000000
+#define SCOM_THRCTL_T2_STOP	0x20000000
+#define SCOM_THRCTL_T3_STOP	0x10000000
+#define SCOM_THRCTL_T0_STEP	0x08000000
+#define SCOM_THRCTL_T1_STEP	0x04000000
+#define SCOM_THRCTL_T2_STEP	0x02000000
+#define SCOM_THRCTL_T3_STEP	0x01000000
+#define SCOM_THRCTL_T0_RUN	0x00800000
+#define SCOM_THRCTL_T1_RUN	0x00400000
+#define SCOM_THRCTL_T2_RUN	0x00200000
+#define SCOM_THRCTL_T3_RUN	0x00100000
+#define SCOM_THRCTL_T0_PM	0x00080000
+#define SCOM_THRCTL_T1_PM	0x00040000
+#define SCOM_THRCTL_T2_PM	0x00020000
+#define SCOM_THRCTL_T3_PM	0x00010000
+#define SCOM_THRCTL_T0_UDE	0x00008000
+#define SCOM_THRCTL_T1_UDE	0x00004000
+#define SCOM_THRCTL_T2_UDE	0x00002000
+#define SCOM_THRCTL_T3_UDE	0x00001000
+#define SCOM_THRCTL_ASYNC_DIS	0x00000800
+#define SCOM_THRCTL_TB_DIS	0x00000400
+#define SCOM_THRCTL_DEC_DIS	0x00000200
+#define SCOM_THRCTL_AND		0x31		/* Thread Control and Status */
+#define SCOM_THRCTL_OR		0x32		/* Thread Control and Status */
+
+
+static DEFINE_PER_CPU(scom_map_t, scom_ptrs);
+
+static scom_map_t get_scom(int cpu, struct device_node *np, int *first_thread)
+{
+	scom_map_t scom = per_cpu(scom_ptrs, cpu);
+	int tcpu;
+
+	if (scom_map_ok(scom)) {
+		*first_thread = 0;
+		return scom;
+	}
+
+	*first_thread = 1;
+
+	scom = scom_map_device(np, 0);
+
+	for (tcpu = cpu_first_thread_sibling(cpu);
+	     tcpu <= cpu_last_thread_sibling(cpu); tcpu++)
+		per_cpu(scom_ptrs, tcpu) = scom;
+
+	/* Hack: for the boot core, this will actually get called on
+	 * the second thread up, not the first so our test above will
+	 * set first_thread incorrectly. */
+	if (cpu_first_thread_sibling(cpu) == 0)
+		*first_thread = 0;
+
+	return scom;
+}
+
+static int a2_scom_ram(scom_map_t scom, int thread, u32 insn, int extmask)
+{
+	u64 cmd, mask, val;
+	int n = 0;
+
+	cmd = ((u64)insn << 32) | (((u64)extmask & 0xf) << 28)
+		| ((u64)thread << 17) | SCOM_RAMC_ENABLE | SCOM_RAMC_EXECUTE;
+	mask = SCOM_RAMC_DONE | SCOM_RAMC_INTERRUPT | SCOM_RAMC_ERROR;
+
+	scom_write(scom, SCOM_RAMIC, cmd);
+
+	while (!((val = scom_read(scom, SCOM_RAMC)) & mask)) {
+		pr_devel("Waiting on RAMC = 0x%llx\n", val);
+		if (++n == 3) {
+			pr_err("RAMC timeout on instruction 0x%08x, thread %d\n",
+			       insn, thread);
+			return -1;
+		}
+	}
+
+	if (val & SCOM_RAMC_INTERRUPT) {
+		pr_err("RAMC interrupt on instruction 0x%08x, thread %d\n",
+		       insn, thread);
+		return -SCOM_RAMC_INTERRUPT;
+	}
+
+	if (val & SCOM_RAMC_ERROR) {
+		pr_err("RAMC error on instruction 0x%08x, thread %d\n",
+		       insn, thread);
+		return -SCOM_RAMC_ERROR;
+	}
+
+	return 0;
+}
+
+static int a2_scom_getgpr(scom_map_t scom, int thread, int gpr, int alt,
+			  u64 *out_gpr)
+{
+	int rc;
+
+	/* or rN, rN, rN */
+	u32 insn = 0x7c000378 | (gpr << 21) | (gpr << 16) | (gpr << 11);
+	rc = a2_scom_ram(scom, thread, insn, alt ? 0xf : 0x0);
+	if (rc)
+		return rc;
+
+	*out_gpr = scom_read(scom, SCOM_RAMD);
+
+	return 0;
+}
+
+static int a2_scom_getspr(scom_map_t scom, int thread, int spr, u64 *out_spr)
+{
+	int rc, sprhi, sprlo;
+	u32 insn;
+
+	sprhi = spr >> 5;
+	sprlo = spr & 0x1f;
+	insn = 0x7c2002a6 | (sprlo << 16) | (sprhi << 11); /* mfspr r1,spr */
+
+	if (spr == 0x0ff0)
+		insn = 0x7c2000a6; /* mfmsr r1 */
+
+	rc = a2_scom_ram(scom, thread, insn, 0xf);
+	if (rc)
+		return rc;
+	return a2_scom_getgpr(scom, thread, 1, 1, out_spr);
+}
+
+static int a2_scom_setgpr(scom_map_t scom, int thread, int gpr,
+			  int alt, u64 val)
+{
+	u32 lis = 0x3c000000 | (gpr << 21);
+	u32 li = 0x38000000 | (gpr << 21);
+	u32 oris = 0x64000000 | (gpr << 21) | (gpr << 16);
+	u32 ori = 0x60000000 | (gpr << 21) | (gpr << 16);
+	u32 rldicr32 = 0x780007c6 | (gpr << 21) | (gpr << 16);
+	u32 highest = val >> 48;
+	u32 higher = (val >> 32) & 0xffff;
+	u32 high = (val >> 16) & 0xffff;
+	u32 low = val & 0xffff;
+	int lext = alt ? 0x8 : 0x0;
+	int oext = alt ? 0xf : 0x0;
+	int rc = 0;
+
+	if (highest)
+		rc |= a2_scom_ram(scom, thread, lis | highest, lext);
+
+	if (higher) {
+		if (highest)
+			rc |= a2_scom_ram(scom, thread, oris | higher, oext);
+		else
+			rc |= a2_scom_ram(scom, thread, li | higher, lext);
+	}
+
+	if (highest || higher)
+		rc |= a2_scom_ram(scom, thread, rldicr32, oext);
+
+	if (high) {
+		if (highest || higher)
+			rc |= a2_scom_ram(scom, thread, oris | high, oext);
+		else
+			rc |= a2_scom_ram(scom, thread, lis | high, lext);
+	}
+
+	if (highest || higher || high)
+		rc |= a2_scom_ram(scom, thread, ori | low, oext);
+	else
+		rc |= a2_scom_ram(scom, thread, li | low, lext);
+
+	return rc;
+}
+
+static int a2_scom_setspr(scom_map_t scom, int thread, int spr, u64 val)
+{
+	int sprhi = spr >> 5;
+	int sprlo = spr & 0x1f;
+	/* mtspr spr, r1 */
+	u32 insn = 0x7c2003a6 | (sprlo << 16) | (sprhi << 11);
+
+	if (spr == 0x0ff0)
+		insn = 0x7c200124; /* mtmsr r1 */
+
+	if (a2_scom_setgpr(scom, thread, 1, 1, val))
+		return -1;
+
+	return a2_scom_ram(scom, thread, insn, 0xf);
+}
+
+static int a2_scom_initial_tlb(scom_map_t scom, int thread)
+{
+	extern u32 a2_tlbinit_code_start[], a2_tlbinit_code_end[];
+	extern u32 a2_tlbinit_after_iprot_flush[];
+	extern u32 a2_tlbinit_after_linear_map[];
+	u32 assoc, entries, i;
+	u64 epn, tlbcfg;
+	u32 *p;
+	int rc;
+
+	/* Invalidate all entries (including iprot) */
+
+	rc = a2_scom_getspr(scom, thread, SPRN_TLB0CFG, &tlbcfg);
+	if (rc)
+		goto scom_fail;
+	entries = tlbcfg & TLBnCFG_N_ENTRY;
+	assoc = (tlbcfg & TLBnCFG_ASSOC) >> 24;
+	epn = 0;
+
+	/* Set MMUCR2 to enable 4K, 64K, 1M, 16M and 1G pages */
+	a2_scom_setspr(scom, thread, SPRN_MMUCR2, 0x000a7531);
+	/* Set MMUCR3 to write all thids bit to the TLB */
+	a2_scom_setspr(scom, thread, SPRN_MMUCR3, 0x0000000f);
+
+	/* Set MAS1 for 1G page size, and MAS2 to our initial EPN */
+	a2_scom_setspr(scom, thread, SPRN_MAS1, MAS1_TSIZE(BOOK3E_PAGESZ_1GB));
+	a2_scom_setspr(scom, thread, SPRN_MAS2, epn);
+	for (i = 0; i < entries; i++) {
+
+		a2_scom_setspr(scom, thread, SPRN_MAS0, MAS0_ESEL(i % assoc));
+
+		/* tlbwe */
+		rc = a2_scom_ram(scom, thread, 0x7c0007a4, 0);
+		if (rc)
+			goto scom_fail;
+
+		/* Next entry is new address? */
+		if((i + 1) % assoc == 0) {
+			epn += (1 << 30);
+			a2_scom_setspr(scom, thread, SPRN_MAS2, epn);
+		}
+	}
+
+	/* Setup args for linear mapping */
+	rc = a2_scom_setgpr(scom, thread, 3, 0, MAS0_TLBSEL(0));
+	if (rc)
+		goto scom_fail;
+
+	/* Linear mapping */
+	for (p = a2_tlbinit_code_start; p < a2_tlbinit_after_linear_map; p++) {
+		rc = a2_scom_ram(scom, thread, *p, 0);
+		if (rc)
+			goto scom_fail;
+	}
+
+	/*
+	 * For the boot thread, between the linear mapping and the debug
+	 * mappings there is a loop to flush iprot mappings. Ramming doesn't do
+	 * branches, but the secondary threads don't need to be nearly as smart
+	 * (i.e. we don't need to worry about invalidating the mapping we're
+	 * standing on).
+	 */
+
+	/* Debug mappings. Expects r11 = MAS0 from linear map (set above) */
+	for (p = a2_tlbinit_after_iprot_flush; p < a2_tlbinit_code_end; p++) {
+		rc = a2_scom_ram(scom, thread, *p, 0);
+		if (rc)
+			goto scom_fail;
+	}
+
+scom_fail:
+	if (rc)
+		pr_err("Setting up initial TLB failed, err %d\n", rc);
+
+	if (rc == -SCOM_RAMC_INTERRUPT) {
+		/* Interrupt, dump some status */
+		int rc[10];
+		u64 iar, srr0, srr1, esr, mas0, mas1, mas2, mas7_3, mas8, ccr2;
+		rc[0] = a2_scom_getspr(scom, thread, SPRN_IAR, &iar);
+		rc[1] = a2_scom_getspr(scom, thread, SPRN_SRR0, &srr0);
+		rc[2] = a2_scom_getspr(scom, thread, SPRN_SRR1, &srr1);
+		rc[3] = a2_scom_getspr(scom, thread, SPRN_ESR, &esr);
+		rc[4] = a2_scom_getspr(scom, thread, SPRN_MAS0, &mas0);
+		rc[5] = a2_scom_getspr(scom, thread, SPRN_MAS1, &mas1);
+		rc[6] = a2_scom_getspr(scom, thread, SPRN_MAS2, &mas2);
+		rc[7] = a2_scom_getspr(scom, thread, SPRN_MAS7_MAS3, &mas7_3);
+		rc[8] = a2_scom_getspr(scom, thread, SPRN_MAS8, &mas8);
+		rc[9] = a2_scom_getspr(scom, thread, SPRN_A2_CCR2, &ccr2);
+		pr_err(" -> retreived IAR =0x%llx (err %d)\n", iar, rc[0]);
+		pr_err("    retreived SRR0=0x%llx (err %d)\n", srr0, rc[1]);
+		pr_err("    retreived SRR1=0x%llx (err %d)\n", srr1, rc[2]);
+		pr_err("    retreived ESR =0x%llx (err %d)\n", esr, rc[3]);
+		pr_err("    retreived MAS0=0x%llx (err %d)\n", mas0, rc[4]);
+		pr_err("    retreived MAS1=0x%llx (err %d)\n", mas1, rc[5]);
+		pr_err("    retreived MAS2=0x%llx (err %d)\n", mas2, rc[6]);
+		pr_err("    retreived MS73=0x%llx (err %d)\n", mas7_3, rc[7]);
+		pr_err("    retreived MAS8=0x%llx (err %d)\n", mas8, rc[8]);
+		pr_err("    retreived CCR2=0x%llx (err %d)\n", ccr2, rc[9]);
+	}
+
+	return rc;
+}
+
+int __devinit a2_scom_startup_cpu(unsigned int lcpu, int thr_idx,
+				  struct device_node *np)
+{
+	u64 init_iar, init_msr, init_ccr2;
+	unsigned long start_here;
+	int rc, core_setup;
+	scom_map_t scom;
+	u64 pccr0;
+
+	scom = get_scom(lcpu, np, &core_setup);
+	if (!scom) {
+		printk(KERN_ERR "Couldn't map SCOM for CPU%d\n", lcpu);
+		return -1;
+	}
+
+	pr_devel("Bringing up CPU%d using SCOM...\n", lcpu);
+
+	pccr0 = scom_read(scom, SCOM_PCCR0);
+	scom_write(scom, SCOM_PCCR0, pccr0 | SCOM_PCCR0_ENABLE_DEBUG |
+				     SCOM_PCCR0_ENABLE_RAM);
+
+	/* Stop the thead with THRCTL. If we are setting up the TLB we stop all
+	 * threads. We also disable asynchronous interrupts while RAMing.
+	 */
+	if (core_setup)
+		scom_write(scom, SCOM_THRCTL_OR,
+			      SCOM_THRCTL_T0_STOP |
+			      SCOM_THRCTL_T1_STOP |
+			      SCOM_THRCTL_T2_STOP |
+			      SCOM_THRCTL_T3_STOP |
+			      SCOM_THRCTL_ASYNC_DIS);
+	else
+		scom_write(scom, SCOM_THRCTL_OR, SCOM_THRCTL_T0_STOP >> thr_idx);
+
+	/* Flush its pipeline just in case */
+	scom_write(scom, SCOM_RAMC, ((u64)thr_idx << 17) |
+		      SCOM_RAMC_FLUSH | SCOM_RAMC_ENABLE);
+
+	a2_scom_getspr(scom, thr_idx, SPRN_IAR, &init_iar);
+	a2_scom_getspr(scom, thr_idx, 0x0ff0, &init_msr);
+	a2_scom_getspr(scom, thr_idx, SPRN_A2_CCR2, &init_ccr2);
+
+	/* Set MSR to MSR_CM (0x0ff0 is magic value for MSR_CM) */
+	rc = a2_scom_setspr(scom, thr_idx, 0x0ff0, MSR_CM);
+	if (rc) {
+		pr_err("Failed to set MSR ! err %d\n", rc);
+		return rc;
+	}
+
+	/* RAM in an sync/isync for the sake of it */
+	a2_scom_ram(scom, thr_idx, 0x7c0004ac, 0);
+	a2_scom_ram(scom, thr_idx, 0x4c00012c, 0);
+
+	if (core_setup) {
+		pr_devel("CPU%d is first thread in core, initializing TLB...\n",
+			 lcpu);
+		rc = a2_scom_initial_tlb(scom, thr_idx);
+		if (rc)
+			goto fail;
+	}
+
+	start_here = *(unsigned long *)(core_setup ? generic_secondary_smp_init
+					: generic_secondary_thread_init);
+	pr_devel("CPU%d entry point at 0x%lx...\n", lcpu, start_here);
+
+	rc |= a2_scom_setspr(scom, thr_idx, SPRN_IAR, start_here);
+	rc |= a2_scom_setgpr(scom, thr_idx, 3, 0,
+			     get_hard_smp_processor_id(lcpu));
+	/*
+	 * Tell book3e_secondary_core_init not to set up the TLB, we've
+	 * already done that.
+	 */
+	rc |= a2_scom_setgpr(scom, thr_idx, 4, 0, 1);
+
+	rc |= a2_scom_setspr(scom, thr_idx, SPRN_TENS, 0x1 << thr_idx);
+
+	scom_write(scom, SCOM_RAMC, 0);
+	scom_write(scom, SCOM_THRCTL_AND, ~(SCOM_THRCTL_T0_STOP >> thr_idx));
+	scom_write(scom, SCOM_PCCR0, pccr0);
+fail:
+	pr_devel("  SCOM initialization %s\n", rc ? "failed" : "succeeded");
+	if (rc) {
+		pr_err("Old IAR=0x%08llx MSR=0x%08llx CCR2=0x%08llx\n",
+		       init_iar, init_msr, init_ccr2);
+	}
+
+	return rc;
+}
diff -druN linux-2.6.39-libre/arch/powerpc/platforms/wsp/scom_wsp.c linux-3.0-rc7-libre/arch/powerpc/platforms/wsp/scom_wsp.c
--- linux-2.6.39-libre/arch/powerpc/platforms/wsp/scom_wsp.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/powerpc/platforms/wsp/scom_wsp.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,77 @@
+/*
+ *  SCOM backend for WSP
+ *
+ *  Copyright 2010 Benjamin Herrenschmidt, IBM Corp.
+ *
+ *  This program is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU General Public License
+ *  as published by the Free Software Foundation; either version
+ *  2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/cpumask.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/spinlock.h>
+#include <linux/types.h>
+
+#include <asm/cputhreads.h>
+#include <asm/reg_a2.h>
+#include <asm/scom.h>
+#include <asm/udbg.h>
+
+#include "wsp.h"
+
+
+static scom_map_t wsp_scom_map(struct device_node *dev, u64 reg, u64 count)
+{
+	struct resource r;
+	u64 xscom_addr;
+
+	if (!of_get_property(dev, "scom-controller", NULL)) {
+		pr_err("%s: device %s is not a SCOM controller\n",
+			__func__, dev->full_name);
+		return SCOM_MAP_INVALID;
+	}
+
+	if (of_address_to_resource(dev, 0, &r)) {
+		pr_debug("Failed to find SCOM controller address\n");
+		return 0;
+	}
+
+	/* Transform the SCOM address into an XSCOM offset */
+	xscom_addr = ((reg & 0x7f000000) >> 1) | ((reg & 0xfffff) << 3);
+
+	return (scom_map_t)ioremap(r.start + xscom_addr, count << 3);
+}
+
+static void wsp_scom_unmap(scom_map_t map)
+{
+	iounmap((void *)map);
+}
+
+static u64 wsp_scom_read(scom_map_t map, u32 reg)
+{
+	u64 __iomem *addr = (u64 __iomem *)map;
+
+	return in_be64(addr + reg);
+}
+
+static void wsp_scom_write(scom_map_t map, u32 reg, u64 value)
+{
+	u64 __iomem *addr = (u64 __iomem *)map;
+
+	return out_be64(addr + reg, value);
+}
+
+static const struct scom_controller wsp_scom_controller = {
+	.map	= wsp_scom_map,
+	.unmap	= wsp_scom_unmap,
+	.read	= wsp_scom_read,
+	.write	= wsp_scom_write
+};
+
+void scom_init_wsp(void)
+{
+	scom_init(&wsp_scom_controller);
+}
diff -druN linux-2.6.39-libre/arch/powerpc/platforms/wsp/setup.c linux-3.0-rc7-libre/arch/powerpc/platforms/wsp/setup.c
--- linux-2.6.39-libre/arch/powerpc/platforms/wsp/setup.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/powerpc/platforms/wsp/setup.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2010 Michael Ellerman, 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/kernel.h>
+#include <linux/of_platform.h>
+
+#include "wsp.h"
+
+/*
+ * Find chip-id by walking up device tree looking for ibm,wsp-chip-id property.
+ * Won't work for nodes that are not a descendant of a wsp node.
+ */
+int wsp_get_chip_id(struct device_node *dn)
+{
+	const u32 *p;
+	int rc;
+
+	/* Start looking at the specified node, not its parent */
+	dn = of_node_get(dn);
+	while (dn && !(p = of_get_property(dn, "ibm,wsp-chip-id", NULL)))
+		dn = of_get_next_parent(dn);
+
+	if (!dn)
+		return -1;
+
+	rc = *p;
+	of_node_put(dn);
+
+	return rc;
+}
diff -druN linux-2.6.39-libre/arch/powerpc/platforms/wsp/smp.c linux-3.0-rc7-libre/arch/powerpc/platforms/wsp/smp.c
--- linux-2.6.39-libre/arch/powerpc/platforms/wsp/smp.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/powerpc/platforms/wsp/smp.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,88 @@
+/*
+ *  SMP Support for A2 platforms
+ *
+ *  Copyright 2007 Benjamin Herrenschmidt, IBM Corp.
+ *
+ *  This program is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU General Public License
+ *  as published by the Free Software Foundation; either version
+ *  2 of the License, or (at your option) any later version.
+ *
+ */
+
+#include <linux/cpumask.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/of.h>
+#include <linux/smp.h>
+
+#include <asm/dbell.h>
+#include <asm/machdep.h>
+#include <asm/xics.h>
+
+#include "ics.h"
+#include "wsp.h"
+
+static void __devinit smp_a2_setup_cpu(int cpu)
+{
+	doorbell_setup_this_cpu();
+
+	if (cpu != boot_cpuid)
+		xics_setup_cpu();
+}
+
+int __devinit smp_a2_kick_cpu(int nr)
+{
+	const char *enable_method;
+	struct device_node *np;
+	int thr_idx;
+
+	if (nr < 0 || nr >= NR_CPUS)
+		return -ENOENT;
+
+	np = of_get_cpu_node(nr, &thr_idx);
+	if (!np)
+		return -ENODEV;
+
+	enable_method = of_get_property(np, "enable-method", NULL);
+	pr_devel("CPU%d has enable-method: \"%s\"\n", nr, enable_method);
+
+	if (!enable_method) {
+                printk(KERN_ERR "CPU%d has no enable-method\n", nr);
+		return -ENOENT;
+	} else if (strcmp(enable_method, "ibm,a2-scom") == 0) {
+		if (a2_scom_startup_cpu(nr, thr_idx, np))
+			return -1;
+	} else {
+		printk(KERN_ERR "CPU%d: Don't understand enable-method \"%s\"\n",
+                       nr, enable_method);
+		return -EINVAL;
+	}
+
+	/*
+	 * The processor is currently spinning, waiting for the
+	 * cpu_start field to become non-zero After we set cpu_start,
+	 * the processor will continue on to secondary_start
+	 */
+	paca[nr].cpu_start = 1;
+
+	return 0;
+}
+
+static int __init smp_a2_probe(void)
+{
+	return cpus_weight(cpu_possible_map);
+}
+
+static struct smp_ops_t a2_smp_ops = {
+	.message_pass	= smp_muxed_ipi_message_pass,
+	.cause_ipi	= doorbell_cause_ipi,
+	.probe		= smp_a2_probe,
+	.kick_cpu	= smp_a2_kick_cpu,
+	.setup_cpu	= smp_a2_setup_cpu,
+};
+
+void __init a2_setup_smp(void)
+{
+	smp_ops = &a2_smp_ops;
+}
diff -druN linux-2.6.39-libre/arch/powerpc/platforms/wsp/wsp.h linux-3.0-rc7-libre/arch/powerpc/platforms/wsp/wsp.h
--- linux-2.6.39-libre/arch/powerpc/platforms/wsp/wsp.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/powerpc/platforms/wsp/wsp.h	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,17 @@
+#ifndef __WSP_H
+#define __WSP_H
+
+#include <asm/wsp.h>
+
+extern void wsp_setup_pci(void);
+extern void scom_init_wsp(void);
+
+extern void a2_setup_smp(void);
+extern int a2_scom_startup_cpu(unsigned int lcpu, int thr_idx,
+			       struct device_node *np);
+int smp_a2_cpu_bootable(unsigned int nr);
+int __devinit smp_a2_kick_cpu(int nr);
+
+void opb_pic_init(void);
+
+#endif /*  __WSP_H */
diff -druN linux-2.6.39-libre/arch/powerpc/sysdev/axonram.c linux-3.0-rc7-libre/arch/powerpc/sysdev/axonram.c
--- linux-2.6.39-libre/arch/powerpc/sysdev/axonram.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/sysdev/axonram.c	2011-07-11 19:51:52.000000000 -0400
@@ -216,7 +216,7 @@
 			AXON_RAM_DEVICE_NAME, axon_ram_bank_id, bank->size >> 20);
 
 	bank->ph_addr = resource.start;
-	bank->io_addr = (unsigned long) ioremap_flags(
+	bank->io_addr = (unsigned long) ioremap_prot(
 			bank->ph_addr, bank->size, _PAGE_NO_CACHE);
 	if (bank->io_addr == 0) {
 		dev_err(&device->dev, "ioremap() failed\n");
diff -druN linux-2.6.39-libre/arch/powerpc/sysdev/cpm1.c linux-3.0-rc7-libre/arch/powerpc/sysdev/cpm1.c
--- linux-2.6.39-libre/arch/powerpc/sysdev/cpm1.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/sysdev/cpm1.c	2011-07-11 19:51:52.000000000 -0400
@@ -58,21 +58,21 @@
 
 static void cpm_mask_irq(struct irq_data *d)
 {
-	unsigned int cpm_vec = (unsigned int)irq_map[d->irq].hwirq;
+	unsigned int cpm_vec = (unsigned int)irqd_to_hwirq(d);
 
 	clrbits32(&cpic_reg->cpic_cimr, (1 << cpm_vec));
 }
 
 static void cpm_unmask_irq(struct irq_data *d)
 {
-	unsigned int cpm_vec = (unsigned int)irq_map[d->irq].hwirq;
+	unsigned int cpm_vec = (unsigned int)irqd_to_hwirq(d);
 
 	setbits32(&cpic_reg->cpic_cimr, (1 << cpm_vec));
 }
 
 static void cpm_end_irq(struct irq_data *d)
 {
-	unsigned int cpm_vec = (unsigned int)irq_map[d->irq].hwirq;
+	unsigned int cpm_vec = (unsigned int)irqd_to_hwirq(d);
 
 	out_be32(&cpic_reg->cpic_cisr, (1 << cpm_vec));
 }
@@ -157,7 +157,7 @@
 		goto end;
 
 	/* Initialize the CPM interrupt controller. */
-	hwirq = (unsigned int)irq_map[sirq].hwirq;
+	hwirq = (unsigned int)virq_to_hw(sirq);
 	out_be32(&cpic_reg->cpic_cicr,
 	    (CICR_SCD_SCC4 | CICR_SCC_SCC3 | CICR_SCB_SCC2 | CICR_SCA_SCC1) |
 		((hwirq/2) << 13) | CICR_HP_MASK);
diff -druN linux-2.6.39-libre/arch/powerpc/sysdev/cpm2_pic.c linux-3.0-rc7-libre/arch/powerpc/sysdev/cpm2_pic.c
--- linux-2.6.39-libre/arch/powerpc/sysdev/cpm2_pic.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/sysdev/cpm2_pic.c	2011-07-11 19:51:52.000000000 -0400
@@ -81,7 +81,7 @@
 static void cpm2_mask_irq(struct irq_data *d)
 {
 	int	bit, word;
-	unsigned int irq_nr = virq_to_hw(d->irq);
+	unsigned int irq_nr = irqd_to_hwirq(d);
 
 	bit = irq_to_siubit[irq_nr];
 	word = irq_to_siureg[irq_nr];
@@ -93,7 +93,7 @@
 static void cpm2_unmask_irq(struct irq_data *d)
 {
 	int	bit, word;
-	unsigned int irq_nr = virq_to_hw(d->irq);
+	unsigned int irq_nr = irqd_to_hwirq(d);
 
 	bit = irq_to_siubit[irq_nr];
 	word = irq_to_siureg[irq_nr];
@@ -105,7 +105,7 @@
 static void cpm2_ack(struct irq_data *d)
 {
 	int	bit, word;
-	unsigned int irq_nr = virq_to_hw(d->irq);
+	unsigned int irq_nr = irqd_to_hwirq(d);
 
 	bit = irq_to_siubit[irq_nr];
 	word = irq_to_siureg[irq_nr];
@@ -116,7 +116,7 @@
 static void cpm2_end_irq(struct irq_data *d)
 {
 	int	bit, word;
-	unsigned int irq_nr = virq_to_hw(d->irq);
+	unsigned int irq_nr = irqd_to_hwirq(d);
 
 	bit = irq_to_siubit[irq_nr];
 	word = irq_to_siureg[irq_nr];
@@ -133,7 +133,7 @@
 
 static int cpm2_set_irq_type(struct irq_data *d, unsigned int flow_type)
 {
-	unsigned int src = virq_to_hw(d->irq);
+	unsigned int src = irqd_to_hwirq(d);
 	unsigned int vold, vnew, edibit;
 
 	/* Port C interrupts are either IRQ_TYPE_EDGE_FALLING or
diff -druN linux-2.6.39-libre/arch/powerpc/sysdev/fsl_85xx_cache_sram.c linux-3.0-rc7-libre/arch/powerpc/sysdev/fsl_85xx_cache_sram.c
--- linux-2.6.39-libre/arch/powerpc/sysdev/fsl_85xx_cache_sram.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/sysdev/fsl_85xx_cache_sram.c	2011-07-11 19:51:52.000000000 -0400
@@ -106,10 +106,10 @@
 		goto out_free;
 	}
 
-	cache_sram->base_virt = ioremap_flags(cache_sram->base_phys,
+	cache_sram->base_virt = ioremap_prot(cache_sram->base_phys,
 				cache_sram->size, _PAGE_COHERENT | PAGE_KERNEL);
 	if (!cache_sram->base_virt) {
-		dev_err(&dev->dev, "%s: ioremap_flags failed\n",
+		dev_err(&dev->dev, "%s: ioremap_prot failed\n",
 				dev->dev.of_node->full_name);
 		ret = -ENOMEM;
 		goto out_release;
diff -druN linux-2.6.39-libre/arch/powerpc/sysdev/fsl_lbc.c linux-3.0-rc7-libre/arch/powerpc/sysdev/fsl_lbc.c
--- linux-2.6.39-libre/arch/powerpc/sysdev/fsl_lbc.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/sysdev/fsl_lbc.c	2011-07-11 19:51:52.000000000 -0400
@@ -184,7 +184,8 @@
 }
 EXPORT_SYMBOL(fsl_upm_run_pattern);
 
-static int __devinit fsl_lbc_ctrl_init(struct fsl_lbc_ctrl *ctrl)
+static int __devinit fsl_lbc_ctrl_init(struct fsl_lbc_ctrl *ctrl,
+				       struct device_node *node)
 {
 	struct fsl_lbc_regs __iomem *lbc = ctrl->regs;
 
@@ -195,8 +196,9 @@
 	out_be32(&lbc->lteccr, LTECCR_CLEAR);
 	out_be32(&lbc->ltedr, LTEDR_ENABLE);
 
-	/* Enable interrupts for any detected events */
-	out_be32(&lbc->lteir, LTEIR_ENABLE);
+	/* Set the monitor timeout value to the maximum for erratum A001 */
+	if (of_device_is_compatible(node, "fsl,elbc"))
+		clrsetbits_be32(&lbc->lbcr, LBCR_BMT, LBCR_BMTPS);
 
 	return 0;
 }
@@ -304,7 +306,7 @@
 
 	fsl_lbc_ctrl_dev->dev = &dev->dev;
 
-	ret = fsl_lbc_ctrl_init(fsl_lbc_ctrl_dev);
+	ret = fsl_lbc_ctrl_init(fsl_lbc_ctrl_dev, dev->dev.of_node);
 	if (ret < 0)
 		goto err;
 
@@ -317,6 +319,9 @@
 		goto err;
 	}
 
+	/* Enable interrupts for any detected events */
+	out_be32(&fsl_lbc_ctrl_dev->regs->lteir, LTEIR_ENABLE);
+
 	return 0;
 
 err:
diff -druN linux-2.6.39-libre/arch/powerpc/sysdev/fsl_msi.c linux-3.0-rc7-libre/arch/powerpc/sysdev/fsl_msi.c
--- linux-2.6.39-libre/arch/powerpc/sysdev/fsl_msi.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/sysdev/fsl_msi.c	2011-07-11 19:51:52.000000000 -0400
@@ -110,7 +110,7 @@
 	list_for_each_entry(entry, &pdev->msi_list, list) {
 		if (entry->irq == NO_IRQ)
 			continue;
-		msi_data = irq_get_handler_data(entry->irq);
+		msi_data = irq_get_chip_data(entry->irq);
 		irq_set_msi_desc(entry->irq, NULL);
 		msi_bitmap_free_hwirqs(&msi_data->bitmap,
 				       virq_to_hw(entry->irq), 1);
@@ -168,7 +168,7 @@
 			rc = -ENOSPC;
 			goto out_free;
 		}
-		irq_set_handler_data(virq, msi_data);
+		/* chip_data is msi_data via host->hostdata in host->map() */
 		irq_set_msi_desc(virq, entry);
 
 		fsl_compose_msi_msg(pdev, hwirq, &msg, msi_data);
@@ -193,7 +193,7 @@
 	u32 have_shift = 0;
 	struct fsl_msi_cascade_data *cascade_data;
 
-	cascade_data = (struct fsl_msi_cascade_data *)irq_get_handler_data(irq);
+	cascade_data = irq_get_handler_data(irq);
 	msi_data = cascade_data->msi_data;
 
 	raw_spin_lock(&desc->lock);
@@ -253,7 +253,7 @@
 
 static int fsl_of_msi_remove(struct platform_device *ofdev)
 {
-	struct fsl_msi *msi = ofdev->dev.platform_data;
+	struct fsl_msi *msi = platform_get_drvdata(ofdev);
 	int virq, i;
 	struct fsl_msi_cascade_data *cascade_data;
 
@@ -330,7 +330,7 @@
 		dev_err(&dev->dev, "No memory for MSI structure\n");
 		return -ENOMEM;
 	}
-	dev->dev.platform_data = msi;
+	platform_set_drvdata(dev, msi);
 
 	msi->irqhost = irq_alloc_host(dev->dev.of_node, IRQ_HOST_MAP_LINEAR,
 				      NR_MSI_IRQS, &fsl_msi_host_ops, 0);
diff -druN linux-2.6.39-libre/arch/powerpc/sysdev/fsl_rio.c linux-3.0-rc7-libre/arch/powerpc/sysdev/fsl_rio.c
--- linux-2.6.39-libre/arch/powerpc/sysdev/fsl_rio.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/sysdev/fsl_rio.c	2011-07-11 19:51:52.000000000 -0400
@@ -10,7 +10,7 @@
  * - Added Port-Write message handling
  * - Added Machine Check exception handling
  *
- * Copyright (C) 2007, 2008 Freescale Semiconductor, Inc.
+ * Copyright (C) 2007, 2008, 2010 Freescale Semiconductor, Inc.
  * Zhang Wei <wei.zhang@freescale.com>
  *
  * Copyright 2005 MontaVista Software, Inc.
@@ -47,15 +47,33 @@
 #define IRQ_RIO_RX(m)		(((struct rio_priv *)(m->priv))->rxirq)
 #define IRQ_RIO_PW(m)		(((struct rio_priv *)(m->priv))->pwirq)
 
+#define IPWSR_CLEAR		0x98
+#define OMSR_CLEAR		0x1cb3
+#define IMSR_CLEAR		0x491
+#define IDSR_CLEAR		0x91
+#define ODSR_CLEAR		0x1c00
+#define LTLEECSR_ENABLE_ALL	0xFFC000FC
+#define ESCSR_CLEAR		0x07120204
+
+#define RIO_PORT1_EDCSR		0x0640
+#define RIO_PORT2_EDCSR		0x0680
+#define RIO_PORT1_IECSR		0x10130
+#define RIO_PORT2_IECSR		0x101B0
+#define RIO_IM0SR		0x13064
+#define RIO_IM1SR		0x13164
+#define RIO_OM0SR		0x13004
+#define RIO_OM1SR		0x13104
+
 #define RIO_ATMU_REGS_OFFSET	0x10c00
 #define RIO_P_MSG_REGS_OFFSET	0x11000
 #define RIO_S_MSG_REGS_OFFSET	0x13000
 #define RIO_GCCSR		0x13c
 #define RIO_ESCSR		0x158
+#define RIO_PORT2_ESCSR		0x178
 #define RIO_CCSR		0x15c
 #define RIO_LTLEDCSR		0x0608
-#define  RIO_LTLEDCSR_IER	0x80000000
-#define  RIO_LTLEDCSR_PRT	0x01000000
+#define RIO_LTLEDCSR_IER	0x80000000
+#define RIO_LTLEDCSR_PRT	0x01000000
 #define RIO_LTLEECSR		0x060c
 #define RIO_EPWISR		0x10010
 #define RIO_ISR_AACR		0x10120
@@ -88,7 +106,10 @@
 #define RIO_IPWSR_PWD		0x00000008
 #define RIO_IPWSR_PWB		0x00000004
 
-#define RIO_EPWISR_PINT		0x80000000
+/* EPWISR Error match value */
+#define RIO_EPWISR_PINT1	0x80000000
+#define RIO_EPWISR_PINT2	0x40000000
+#define RIO_EPWISR_MU		0x00000002
 #define RIO_EPWISR_PW		0x00000001
 
 #define RIO_MSG_DESC_SIZE	32
@@ -260,35 +281,32 @@
 static void __iomem *rio_regs_win;
 
 #ifdef CONFIG_E500
-static int (*saved_mcheck_exception)(struct pt_regs *regs);
-
-static int fsl_rio_mcheck_exception(struct pt_regs *regs)
+int fsl_rio_mcheck_exception(struct pt_regs *regs)
 {
-	const struct exception_table_entry *entry = NULL;
-	unsigned long reason = mfspr(SPRN_MCSR);
+	const struct exception_table_entry *entry;
+	unsigned long reason;
 
-	if (reason & MCSR_BUS_RBERR) {
-		reason = in_be32((u32 *)(rio_regs_win + RIO_LTLEDCSR));
-		if (reason & (RIO_LTLEDCSR_IER | RIO_LTLEDCSR_PRT)) {
-			/* Check if we are prepared to handle this fault */
-			entry = search_exception_tables(regs->nip);
-			if (entry) {
-				pr_debug("RIO: %s - MC Exception handled\n",
-					 __func__);
-				out_be32((u32 *)(rio_regs_win + RIO_LTLEDCSR),
-					 0);
-				regs->msr |= MSR_RI;
-				regs->nip = entry->fixup;
-				return 1;
-			}
+	if (!rio_regs_win)
+		return 0;
+
+	reason = in_be32((u32 *)(rio_regs_win + RIO_LTLEDCSR));
+	if (reason & (RIO_LTLEDCSR_IER | RIO_LTLEDCSR_PRT)) {
+		/* Check if we are prepared to handle this fault */
+		entry = search_exception_tables(regs->nip);
+		if (entry) {
+			pr_debug("RIO: %s - MC Exception handled\n",
+				 __func__);
+			out_be32((u32 *)(rio_regs_win + RIO_LTLEDCSR),
+				 0);
+			regs->msr |= MSR_RI;
+			regs->nip = entry->fixup;
+			return 1;
 		}
 	}
 
-	if (saved_mcheck_exception)
-		return saved_mcheck_exception(regs);
-	else
-		return cur_cpu_spec->machine_check(regs);
+	return 0;
 }
+EXPORT_SYMBOL_GPL(fsl_rio_mcheck_exception);
 #endif
 
 /**
@@ -1064,6 +1082,40 @@
 	return rc;
 }
 
+static void port_error_handler(struct rio_mport *port, int offset)
+{
+	/*XXX: Error recovery is not implemented, we just clear errors */
+	out_be32((u32 *)(rio_regs_win + RIO_LTLEDCSR), 0);
+
+	if (offset == 0) {
+		out_be32((u32 *)(rio_regs_win + RIO_PORT1_EDCSR), 0);
+		out_be32((u32 *)(rio_regs_win + RIO_PORT1_IECSR), 0);
+		out_be32((u32 *)(rio_regs_win + RIO_ESCSR), ESCSR_CLEAR);
+	} else {
+		out_be32((u32 *)(rio_regs_win + RIO_PORT2_EDCSR), 0);
+		out_be32((u32 *)(rio_regs_win + RIO_PORT2_IECSR), 0);
+		out_be32((u32 *)(rio_regs_win + RIO_PORT2_ESCSR), ESCSR_CLEAR);
+	}
+}
+
+static void msg_unit_error_handler(struct rio_mport *port)
+{
+	struct rio_priv *priv = port->priv;
+
+	/*XXX: Error recovery is not implemented, we just clear errors */
+	out_be32((u32 *)(rio_regs_win + RIO_LTLEDCSR), 0);
+
+	out_be32((u32 *)(rio_regs_win + RIO_IM0SR), IMSR_CLEAR);
+	out_be32((u32 *)(rio_regs_win + RIO_IM1SR), IMSR_CLEAR);
+	out_be32((u32 *)(rio_regs_win + RIO_OM0SR), OMSR_CLEAR);
+	out_be32((u32 *)(rio_regs_win + RIO_OM1SR), OMSR_CLEAR);
+
+	out_be32(&priv->msg_regs->odsr, ODSR_CLEAR);
+	out_be32(&priv->msg_regs->dsr, IDSR_CLEAR);
+
+	out_be32(&priv->msg_regs->pwsr, IPWSR_CLEAR);
+}
+
 /**
  * fsl_rio_port_write_handler - MPC85xx port write interrupt handler
  * @irq: Linux interrupt number
@@ -1144,10 +1196,22 @@
 	}
 
 pw_done:
-	if (epwisr & RIO_EPWISR_PINT) {
+	if (epwisr & RIO_EPWISR_PINT1) {
 		tmp = in_be32(priv->regs_win + RIO_LTLEDCSR);
 		pr_debug("RIO_LTLEDCSR = 0x%x\n", tmp);
-		out_be32(priv->regs_win + RIO_LTLEDCSR, 0);
+		port_error_handler(port, 0);
+	}
+
+	if (epwisr & RIO_EPWISR_PINT2) {
+		tmp = in_be32(priv->regs_win + RIO_LTLEDCSR);
+		pr_debug("RIO_LTLEDCSR = 0x%x\n", tmp);
+		port_error_handler(port, 1);
+	}
+
+	if (epwisr & RIO_EPWISR_MU) {
+		tmp = in_be32(priv->regs_win + RIO_LTLEDCSR);
+		pr_debug("RIO_LTLEDCSR = 0x%x\n", tmp);
+		msg_unit_error_handler(port);
 	}
 
 	return IRQ_HANDLED;
@@ -1258,12 +1322,14 @@
 
 
 	/* Hook up port-write handler */
-	rc = request_irq(IRQ_RIO_PW(mport), fsl_rio_port_write_handler, 0,
-			 "port-write", (void *)mport);
+	rc = request_irq(IRQ_RIO_PW(mport), fsl_rio_port_write_handler,
+			IRQF_SHARED, "port-write", (void *)mport);
 	if (rc < 0) {
 		pr_err("MPC85xx RIO: unable to request inbound doorbell irq");
 		goto err_out;
 	}
+	/* Enable Error Interrupt */
+	out_be32((u32 *)(rio_regs_win + RIO_LTLEECSR), LTLEECSR_ENABLE_ALL);
 
 	INIT_WORK(&priv->pw_work, fsl_pw_dpc);
 	spin_lock_init(&priv->pw_fifo_lock);
@@ -1538,11 +1604,6 @@
 	fsl_rio_doorbell_init(port);
 	fsl_rio_port_write_init(port);
 
-#ifdef CONFIG_E500
-	saved_mcheck_exception = ppc_md.machine_check_exception;
-	ppc_md.machine_check_exception = fsl_rio_mcheck_exception;
-#endif
-
 	return 0;
 err:
 	iounmap(priv->regs_win);
diff -druN linux-2.6.39-libre/arch/powerpc/sysdev/i8259.c linux-3.0-rc7-libre/arch/powerpc/sysdev/i8259.c
--- linux-2.6.39-libre/arch/powerpc/sysdev/i8259.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/sysdev/i8259.c	2011-07-11 19:51:52.000000000 -0400
@@ -185,18 +185,6 @@
 	return 0;
 }
 
-static void i8259_host_unmap(struct irq_host *h, unsigned int virq)
-{
-	/* Make sure irq is masked in hardware */
-	i8259_mask_irq(irq_get_irq_data(virq));
-
-	/* remove chip and handler */
-	irq_set_chip_and_handler(virq, NULL, NULL);
-
-	/* Make sure it's completed */
-	synchronize_irq(virq);
-}
-
 static int i8259_host_xlate(struct irq_host *h, struct device_node *ct,
 			    const u32 *intspec, unsigned int intsize,
 			    irq_hw_number_t *out_hwirq, unsigned int *out_flags)
@@ -220,7 +208,6 @@
 static struct irq_host_ops i8259_host_ops = {
 	.match = i8259_host_match,
 	.map = i8259_host_map,
-	.unmap = i8259_host_unmap,
 	.xlate = i8259_host_xlate,
 };
 
diff -druN linux-2.6.39-libre/arch/powerpc/sysdev/ipic.c linux-3.0-rc7-libre/arch/powerpc/sysdev/ipic.c
--- linux-2.6.39-libre/arch/powerpc/sysdev/ipic.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/sysdev/ipic.c	2011-07-11 19:51:52.000000000 -0400
@@ -18,7 +18,7 @@
 #include <linux/stddef.h>
 #include <linux/sched.h>
 #include <linux/signal.h>
-#include <linux/sysdev.h>
+#include <linux/syscore_ops.h>
 #include <linux/device.h>
 #include <linux/bootmem.h>
 #include <linux/spinlock.h>
@@ -521,12 +521,10 @@
 	return primary_ipic;
 }
 
-#define ipic_irq_to_hw(virq)	((unsigned int)irq_map[virq].hwirq)
-
 static void ipic_unmask_irq(struct irq_data *d)
 {
 	struct ipic *ipic = ipic_from_irq(d->irq);
-	unsigned int src = ipic_irq_to_hw(d->irq);
+	unsigned int src = irqd_to_hwirq(d);
 	unsigned long flags;
 	u32 temp;
 
@@ -542,7 +540,7 @@
 static void ipic_mask_irq(struct irq_data *d)
 {
 	struct ipic *ipic = ipic_from_irq(d->irq);
-	unsigned int src = ipic_irq_to_hw(d->irq);
+	unsigned int src = irqd_to_hwirq(d);
 	unsigned long flags;
 	u32 temp;
 
@@ -562,7 +560,7 @@
 static void ipic_ack_irq(struct irq_data *d)
 {
 	struct ipic *ipic = ipic_from_irq(d->irq);
-	unsigned int src = ipic_irq_to_hw(d->irq);
+	unsigned int src = irqd_to_hwirq(d);
 	unsigned long flags;
 	u32 temp;
 
@@ -581,7 +579,7 @@
 static void ipic_mask_irq_and_ack(struct irq_data *d)
 {
 	struct ipic *ipic = ipic_from_irq(d->irq);
-	unsigned int src = ipic_irq_to_hw(d->irq);
+	unsigned int src = irqd_to_hwirq(d);
 	unsigned long flags;
 	u32 temp;
 
@@ -604,7 +602,7 @@
 static int ipic_set_irq_type(struct irq_data *d, unsigned int flow_type)
 {
 	struct ipic *ipic = ipic_from_irq(d->irq);
-	unsigned int src = ipic_irq_to_hw(d->irq);
+	unsigned int src = irqd_to_hwirq(d);
 	unsigned int vold, vnew, edibit;
 
 	if (flow_type == IRQ_TYPE_NONE)
@@ -793,7 +791,7 @@
 int ipic_set_priority(unsigned int virq, unsigned int priority)
 {
 	struct ipic *ipic = ipic_from_irq(virq);
-	unsigned int src = ipic_irq_to_hw(virq);
+	unsigned int src = virq_to_hw(virq);
 	u32 temp;
 
 	if (priority > 7)
@@ -821,7 +819,7 @@
 void ipic_set_highest_priority(unsigned int virq)
 {
 	struct ipic *ipic = ipic_from_irq(virq);
-	unsigned int src = ipic_irq_to_hw(virq);
+	unsigned int src = virq_to_hw(virq);
 	u32 temp;
 
 	temp = ipic_read(ipic->regs, IPIC_SICFR);
@@ -902,7 +900,7 @@
 	u32 sercr;
 } ipic_saved_state;
 
-static int ipic_suspend(struct sys_device *sdev, pm_message_t state)
+static int ipic_suspend(void)
 {
 	struct ipic *ipic = primary_ipic;
 
@@ -933,7 +931,7 @@
 	return 0;
 }
 
-static int ipic_resume(struct sys_device *sdev)
+static void ipic_resume(void)
 {
 	struct ipic *ipic = primary_ipic;
 
@@ -949,44 +947,26 @@
 	ipic_write(ipic->regs, IPIC_SECNR, ipic_saved_state.secnr);
 	ipic_write(ipic->regs, IPIC_SERMR, ipic_saved_state.sermr);
 	ipic_write(ipic->regs, IPIC_SERCR, ipic_saved_state.sercr);
-
-	return 0;
 }
 #else
 #define ipic_suspend NULL
 #define ipic_resume NULL
 #endif
 
-static struct sysdev_class ipic_sysclass = {
-	.name = "ipic",
+static struct syscore_ops ipic_syscore_ops = {
 	.suspend = ipic_suspend,
 	.resume = ipic_resume,
 };
 
-static struct sys_device device_ipic = {
-	.id		= 0,
-	.cls		= &ipic_sysclass,
-};
-
-static int __init init_ipic_sysfs(void)
+static int __init init_ipic_syscore(void)
 {
-	int rc;
-
 	if (!primary_ipic || !primary_ipic->regs)
 		return -ENODEV;
-	printk(KERN_DEBUG "Registering ipic with sysfs...\n");
 
-	rc = sysdev_class_register(&ipic_sysclass);
-	if (rc) {
-		printk(KERN_ERR "Failed registering ipic sys class\n");
-		return -ENODEV;
-	}
-	rc = sysdev_register(&device_ipic);
-	if (rc) {
-		printk(KERN_ERR "Failed registering ipic sys device\n");
-		return -ENODEV;
-	}
+	printk(KERN_DEBUG "Registering ipic system core operations\n");
+	register_syscore_ops(&ipic_syscore_ops);
+
 	return 0;
 }
 
-subsys_initcall(init_ipic_sysfs);
+subsys_initcall(init_ipic_syscore);
diff -druN linux-2.6.39-libre/arch/powerpc/sysdev/Kconfig linux-3.0-rc7-libre/arch/powerpc/sysdev/Kconfig
--- linux-2.6.39-libre/arch/powerpc/sysdev/Kconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/sysdev/Kconfig	2011-07-11 19:51:52.000000000 -0400
@@ -7,8 +7,25 @@
 	depends on PCI && 4xx
 	default n
 
+config PPC4xx_MSI
+	bool
+	depends on PCI_MSI
+	depends on PCI && 4xx
+	default n
+
 config PPC_MSI_BITMAP
 	bool
 	depends on PCI_MSI
 	default y if MPIC
 	default y if FSL_PCI
+	default y if PPC4xx_MSI
+
+source "arch/powerpc/sysdev/xics/Kconfig"
+
+config PPC_SCOM
+	bool
+
+config SCOM_DEBUGFS
+	bool "Expose SCOM controllers via debugfs"
+	depends on PPC_SCOM
+	default n
diff -druN linux-2.6.39-libre/arch/powerpc/sysdev/Makefile linux-3.0-rc7-libre/arch/powerpc/sysdev/Makefile
--- linux-2.6.39-libre/arch/powerpc/sysdev/Makefile	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/sysdev/Makefile	2011-07-11 19:51:52.000000000 -0400
@@ -41,6 +41,7 @@
 ifeq ($(CONFIG_PCI),y)
 obj-$(CONFIG_4xx)		+= ppc4xx_pci.o
 endif
+obj-$(CONFIG_PPC4xx_MSI)	+= ppc4xx_msi.o
 obj-$(CONFIG_PPC4xx_CPM)	+= ppc4xx_cpm.o
 obj-$(CONFIG_PPC4xx_GPIO)	+= ppc4xx_gpio.o
 
@@ -57,3 +58,9 @@
 ifeq ($(CONFIG_SUSPEND),y)
 obj-$(CONFIG_6xx)		+= 6xx-suspend.o
 endif
+
+obj-$(CONFIG_PPC_SCOM)		+= scom.o
+
+subdir-ccflags-$(CONFIG_PPC_WERROR) := -Werror
+
+obj-$(CONFIG_PPC_XICS)		+= xics/
diff -druN linux-2.6.39-libre/arch/powerpc/sysdev/mmio_nvram.c linux-3.0-rc7-libre/arch/powerpc/sysdev/mmio_nvram.c
--- linux-2.6.39-libre/arch/powerpc/sysdev/mmio_nvram.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/sysdev/mmio_nvram.c	2011-07-11 19:51:52.000000000 -0400
@@ -115,6 +115,8 @@
 	int ret;
 
 	nvram_node = of_find_node_by_type(NULL, "nvram");
+	if (!nvram_node)
+		nvram_node = of_find_compatible_node(NULL, NULL, "nvram");
 	if (!nvram_node) {
 		printk(KERN_WARNING "nvram: no node found in device-tree\n");
 		return -ENODEV;
diff -druN linux-2.6.39-libre/arch/powerpc/sysdev/mpc8xx_pic.c linux-3.0-rc7-libre/arch/powerpc/sysdev/mpc8xx_pic.c
--- linux-2.6.39-libre/arch/powerpc/sysdev/mpc8xx_pic.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/sysdev/mpc8xx_pic.c	2011-07-11 19:51:52.000000000 -0400
@@ -28,7 +28,7 @@
 static void mpc8xx_unmask_irq(struct irq_data *d)
 {
 	int	bit, word;
-	unsigned int irq_nr = (unsigned int)irq_map[d->irq].hwirq;
+	unsigned int irq_nr = (unsigned int)irqd_to_hwirq(d);
 
 	bit = irq_nr & 0x1f;
 	word = irq_nr >> 5;
@@ -40,7 +40,7 @@
 static void mpc8xx_mask_irq(struct irq_data *d)
 {
 	int	bit, word;
-	unsigned int irq_nr = (unsigned int)irq_map[d->irq].hwirq;
+	unsigned int irq_nr = (unsigned int)irqd_to_hwirq(d);
 
 	bit = irq_nr & 0x1f;
 	word = irq_nr >> 5;
@@ -52,7 +52,7 @@
 static void mpc8xx_ack(struct irq_data *d)
 {
 	int	bit;
-	unsigned int irq_nr = (unsigned int)irq_map[d->irq].hwirq;
+	unsigned int irq_nr = (unsigned int)irqd_to_hwirq(d);
 
 	bit = irq_nr & 0x1f;
 	out_be32(&siu_reg->sc_sipend, 1 << (31-bit));
@@ -61,7 +61,7 @@
 static void mpc8xx_end_irq(struct irq_data *d)
 {
 	int bit, word;
-	unsigned int irq_nr = (unsigned int)irq_map[d->irq].hwirq;
+	unsigned int irq_nr = (unsigned int)irqd_to_hwirq(d);
 
 	bit = irq_nr & 0x1f;
 	word = irq_nr >> 5;
@@ -73,7 +73,7 @@
 static int mpc8xx_set_irq_type(struct irq_data *d, unsigned int flow_type)
 {
 	if (flow_type & IRQ_TYPE_EDGE_FALLING) {
-		irq_hw_number_t hw = (unsigned int)irq_map[d->irq].hwirq;
+		irq_hw_number_t hw = (unsigned int)irqd_to_hwirq(d);
 		unsigned int siel = in_be32(&siu_reg->sc_siel);
 
 		/* only external IRQ senses are programmable */
diff -druN linux-2.6.39-libre/arch/powerpc/sysdev/mpc8xxx_gpio.c linux-3.0-rc7-libre/arch/powerpc/sysdev/mpc8xxx_gpio.c
--- linux-2.6.39-libre/arch/powerpc/sysdev/mpc8xxx_gpio.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/sysdev/mpc8xxx_gpio.c	2011-07-11 19:51:52.000000000 -0400
@@ -163,7 +163,7 @@
 
 	spin_lock_irqsave(&mpc8xxx_gc->lock, flags);
 
-	setbits32(mm->regs + GPIO_IMR, mpc8xxx_gpio2mask(virq_to_hw(d->irq)));
+	setbits32(mm->regs + GPIO_IMR, mpc8xxx_gpio2mask(irqd_to_hwirq(d)));
 
 	spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags);
 }
@@ -176,7 +176,7 @@
 
 	spin_lock_irqsave(&mpc8xxx_gc->lock, flags);
 
-	clrbits32(mm->regs + GPIO_IMR, mpc8xxx_gpio2mask(virq_to_hw(d->irq)));
+	clrbits32(mm->regs + GPIO_IMR, mpc8xxx_gpio2mask(irqd_to_hwirq(d)));
 
 	spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags);
 }
@@ -186,7 +186,7 @@
 	struct mpc8xxx_gpio_chip *mpc8xxx_gc = irq_data_get_irq_chip_data(d);
 	struct of_mm_gpio_chip *mm = &mpc8xxx_gc->mm_gc;
 
-	out_be32(mm->regs + GPIO_IER, mpc8xxx_gpio2mask(virq_to_hw(d->irq)));
+	out_be32(mm->regs + GPIO_IER, mpc8xxx_gpio2mask(irqd_to_hwirq(d)));
 }
 
 static int mpc8xxx_irq_set_type(struct irq_data *d, unsigned int flow_type)
@@ -199,14 +199,14 @@
 	case IRQ_TYPE_EDGE_FALLING:
 		spin_lock_irqsave(&mpc8xxx_gc->lock, flags);
 		setbits32(mm->regs + GPIO_ICR,
-			  mpc8xxx_gpio2mask(virq_to_hw(d->irq)));
+			  mpc8xxx_gpio2mask(irqd_to_hwirq(d)));
 		spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags);
 		break;
 
 	case IRQ_TYPE_EDGE_BOTH:
 		spin_lock_irqsave(&mpc8xxx_gc->lock, flags);
 		clrbits32(mm->regs + GPIO_ICR,
-			  mpc8xxx_gpio2mask(virq_to_hw(d->irq)));
+			  mpc8xxx_gpio2mask(irqd_to_hwirq(d)));
 		spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags);
 		break;
 
@@ -221,7 +221,7 @@
 {
 	struct mpc8xxx_gpio_chip *mpc8xxx_gc = irq_data_get_irq_chip_data(d);
 	struct of_mm_gpio_chip *mm = &mpc8xxx_gc->mm_gc;
-	unsigned long gpio = virq_to_hw(d->irq);
+	unsigned long gpio = irqd_to_hwirq(d);
 	void __iomem *reg;
 	unsigned int shift;
 	unsigned long flags;
diff -druN linux-2.6.39-libre/arch/powerpc/sysdev/mpic.c linux-3.0-rc7-libre/arch/powerpc/sysdev/mpic.c
--- linux-2.6.39-libre/arch/powerpc/sysdev/mpic.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/sysdev/mpic.c	2011-07-11 19:51:52.000000000 -0400
@@ -6,6 +6,7 @@
  *  with various broken implementations of this HW.
  *
  *  Copyright (C) 2004 Benjamin Herrenschmidt, IBM Corp.
+ *  Copyright 2010-2011 Freescale Semiconductor, 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
@@ -27,6 +28,8 @@
 #include <linux/spinlock.h>
 #include <linux/pci.h>
 #include <linux/slab.h>
+#include <linux/syscore_ops.h>
+#include <linux/ratelimit.h>
 
 #include <asm/ptrace.h>
 #include <asm/signal.h>
@@ -218,6 +221,28 @@
 	_mpic_write(mpic->reg_type, &mpic->gregs, offset, value);
 }
 
+static inline u32 _mpic_tm_read(struct mpic *mpic, unsigned int tm)
+{
+	unsigned int offset = MPIC_INFO(TIMER_VECTOR_PRI) +
+			      ((tm & 3) * MPIC_INFO(TIMER_STRIDE));
+
+	if (tm >= 4)
+		offset += 0x1000 / 4;
+
+	return _mpic_read(mpic->reg_type, &mpic->tmregs, offset);
+}
+
+static inline void _mpic_tm_write(struct mpic *mpic, unsigned int tm, u32 value)
+{
+	unsigned int offset = MPIC_INFO(TIMER_VECTOR_PRI) +
+			      ((tm & 3) * MPIC_INFO(TIMER_STRIDE));
+
+	if (tm >= 4)
+		offset += 0x1000 / 4;
+
+	_mpic_write(mpic->reg_type, &mpic->tmregs, offset, value);
+}
+
 static inline u32 _mpic_cpu_read(struct mpic *mpic, unsigned int reg)
 {
 	unsigned int cpu = mpic_processor_id(mpic);
@@ -268,6 +293,8 @@
 #define mpic_write(b,r,v)	_mpic_write(mpic->reg_type,&(b),(r),(v))
 #define mpic_ipi_read(i)	_mpic_ipi_read(mpic,(i))
 #define mpic_ipi_write(i,v)	_mpic_ipi_write(mpic,(i),(v))
+#define mpic_tm_read(i)		_mpic_tm_read(mpic,(i))
+#define mpic_tm_write(i,v)	_mpic_tm_write(mpic,(i),(v))
 #define mpic_cpu_read(i)	_mpic_cpu_read(mpic,(i))
 #define mpic_cpu_write(i,v)	_mpic_cpu_write(mpic,(i),(v))
 #define mpic_irq_read(s,r)	_mpic_irq_read(mpic,(s),(r))
@@ -607,8 +634,6 @@
 }
 #endif
 
-#define mpic_irq_to_hw(virq)	((unsigned int)irq_map[virq].hwirq)
-
 /* Find an mpic associated with a given linux interrupt */
 static struct mpic *mpic_find(unsigned int irq)
 {
@@ -621,11 +646,18 @@
 /* Determine if the linux irq is an IPI */
 static unsigned int mpic_is_ipi(struct mpic *mpic, unsigned int irq)
 {
-	unsigned int src = mpic_irq_to_hw(irq);
+	unsigned int src = virq_to_hw(irq);
 
 	return (src >= mpic->ipi_vecs[0] && src <= mpic->ipi_vecs[3]);
 }
 
+/* Determine if the linux irq is a timer */
+static unsigned int mpic_is_tm(struct mpic *mpic, unsigned int irq)
+{
+	unsigned int src = virq_to_hw(irq);
+
+	return (src >= mpic->timer_vecs[0] && src <= mpic->timer_vecs[7]);
+}
 
 /* Convert a cpu mask from logical to physical cpu numbers. */
 static inline u32 mpic_physmask(u32 cpumask)
@@ -633,7 +665,7 @@
 	int i;
 	u32 mask = 0;
 
-	for (i = 0; i < NR_CPUS; ++i, cpumask >>= 1)
+	for (i = 0; i < min(32, NR_CPUS); ++i, cpumask >>= 1)
 		mask |= (cpumask & 1) << get_hard_smp_processor_id(i);
 	return mask;
 }
@@ -674,7 +706,7 @@
 {
 	unsigned int loops = 100000;
 	struct mpic *mpic = mpic_from_irq_data(d);
-	unsigned int src = mpic_irq_to_hw(d->irq);
+	unsigned int src = irqd_to_hwirq(d);
 
 	DBG("%p: %s: enable_irq: %d (src %d)\n", mpic, mpic->name, d->irq, src);
 
@@ -695,7 +727,7 @@
 {
 	unsigned int loops = 100000;
 	struct mpic *mpic = mpic_from_irq_data(d);
-	unsigned int src = mpic_irq_to_hw(d->irq);
+	unsigned int src = irqd_to_hwirq(d);
 
 	DBG("%s: disable_irq: %d (src %d)\n", mpic->name, d->irq, src);
 
@@ -733,7 +765,7 @@
 static void mpic_unmask_ht_irq(struct irq_data *d)
 {
 	struct mpic *mpic = mpic_from_irq_data(d);
-	unsigned int src = mpic_irq_to_hw(d->irq);
+	unsigned int src = irqd_to_hwirq(d);
 
 	mpic_unmask_irq(d);
 
@@ -744,7 +776,7 @@
 static unsigned int mpic_startup_ht_irq(struct irq_data *d)
 {
 	struct mpic *mpic = mpic_from_irq_data(d);
-	unsigned int src = mpic_irq_to_hw(d->irq);
+	unsigned int src = irqd_to_hwirq(d);
 
 	mpic_unmask_irq(d);
 	mpic_startup_ht_interrupt(mpic, src, irqd_is_level_type(d));
@@ -755,7 +787,7 @@
 static void mpic_shutdown_ht_irq(struct irq_data *d)
 {
 	struct mpic *mpic = mpic_from_irq_data(d);
-	unsigned int src = mpic_irq_to_hw(d->irq);
+	unsigned int src = irqd_to_hwirq(d);
 
 	mpic_shutdown_ht_interrupt(mpic, src);
 	mpic_mask_irq(d);
@@ -764,7 +796,7 @@
 static void mpic_end_ht_irq(struct irq_data *d)
 {
 	struct mpic *mpic = mpic_from_irq_data(d);
-	unsigned int src = mpic_irq_to_hw(d->irq);
+	unsigned int src = irqd_to_hwirq(d);
 
 #ifdef DEBUG_IRQ
 	DBG("%s: end_irq: %d\n", mpic->name, d->irq);
@@ -785,7 +817,7 @@
 static void mpic_unmask_ipi(struct irq_data *d)
 {
 	struct mpic *mpic = mpic_from_ipi(d);
-	unsigned int src = mpic_irq_to_hw(d->irq) - mpic->ipi_vecs[0];
+	unsigned int src = virq_to_hw(d->irq) - mpic->ipi_vecs[0];
 
 	DBG("%s: enable_ipi: %d (ipi %d)\n", mpic->name, d->irq, src);
 	mpic_ipi_write(src, mpic_ipi_read(src) & ~MPIC_VECPRI_MASK);
@@ -812,27 +844,42 @@
 
 #endif /* CONFIG_SMP */
 
+static void mpic_unmask_tm(struct irq_data *d)
+{
+	struct mpic *mpic = mpic_from_irq_data(d);
+	unsigned int src = virq_to_hw(d->irq) - mpic->timer_vecs[0];
+
+	DBG("%s: enable_tm: %d (tm %d)\n", mpic->name, irq, src);
+	mpic_tm_write(src, mpic_tm_read(src) & ~MPIC_VECPRI_MASK);
+	mpic_tm_read(src);
+}
+
+static void mpic_mask_tm(struct irq_data *d)
+{
+	struct mpic *mpic = mpic_from_irq_data(d);
+	unsigned int src = virq_to_hw(d->irq) - mpic->timer_vecs[0];
+
+	mpic_tm_write(src, mpic_tm_read(src) | MPIC_VECPRI_MASK);
+	mpic_tm_read(src);
+}
+
 int mpic_set_affinity(struct irq_data *d, const struct cpumask *cpumask,
 		      bool force)
 {
 	struct mpic *mpic = mpic_from_irq_data(d);
-	unsigned int src = mpic_irq_to_hw(d->irq);
+	unsigned int src = irqd_to_hwirq(d);
 
 	if (mpic->flags & MPIC_SINGLE_DEST_CPU) {
 		int cpuid = irq_choose_cpu(cpumask);
 
 		mpic_irq_write(src, MPIC_INFO(IRQ_DESTINATION), 1 << cpuid);
 	} else {
-		cpumask_var_t tmp;
-
-		alloc_cpumask_var(&tmp, GFP_KERNEL);
+		u32 mask = cpumask_bits(cpumask)[0];
 
-		cpumask_and(tmp, cpumask, cpu_online_mask);
+		mask &= cpumask_bits(cpu_online_mask)[0];
 
 		mpic_irq_write(src, MPIC_INFO(IRQ_DESTINATION),
-			       mpic_physmask(cpumask_bits(tmp)[0]));
-
-		free_cpumask_var(tmp);
+			       mpic_physmask(mask));
 	}
 
 	return 0;
@@ -862,7 +909,7 @@
 int mpic_set_irq_type(struct irq_data *d, unsigned int flow_type)
 {
 	struct mpic *mpic = mpic_from_irq_data(d);
-	unsigned int src = mpic_irq_to_hw(d->irq);
+	unsigned int src = irqd_to_hwirq(d);
 	unsigned int vecpri, vold, vnew;
 
 	DBG("mpic: set_irq_type(mpic:@%p,virq:%d,src:0x%x,type:0x%x)\n",
@@ -898,7 +945,7 @@
 void mpic_set_vector(unsigned int virq, unsigned int vector)
 {
 	struct mpic *mpic = mpic_from_irq(virq);
-	unsigned int src = mpic_irq_to_hw(virq);
+	unsigned int src = virq_to_hw(virq);
 	unsigned int vecpri;
 
 	DBG("mpic: set_vector(mpic:@%p,virq:%d,src:%d,vector:0x%x)\n",
@@ -916,7 +963,7 @@
 void mpic_set_destination(unsigned int virq, unsigned int cpuid)
 {
 	struct mpic *mpic = mpic_from_irq(virq);
-	unsigned int src = mpic_irq_to_hw(virq);
+	unsigned int src = virq_to_hw(virq);
 
 	DBG("mpic: set_destination(mpic:@%p,virq:%d,src:%d,cpuid:0x%x)\n",
 	    mpic, virq, src, cpuid);
@@ -942,6 +989,12 @@
 };
 #endif /* CONFIG_SMP */
 
+static struct irq_chip mpic_tm_chip = {
+	.irq_mask	= mpic_mask_tm,
+	.irq_unmask	= mpic_unmask_tm,
+	.irq_eoi	= mpic_end_irq,
+};
+
 #ifdef CONFIG_MPIC_U3_HT_IRQS
 static struct irq_chip mpic_irq_ht_chip = {
 	.irq_startup	= mpic_startup_ht_irq,
@@ -985,6 +1038,16 @@
 	}
 #endif /* CONFIG_SMP */
 
+	if (hw >= mpic->timer_vecs[0] && hw <= mpic->timer_vecs[7]) {
+		WARN_ON(!(mpic->flags & MPIC_PRIMARY));
+
+		DBG("mpic: mapping as timer\n");
+		irq_set_chip_data(virq, mpic);
+		irq_set_chip_and_handler(virq, &mpic->hc_tm,
+					 handle_fasteoi_irq);
+		return 0;
+	}
+
 	if (hw >= mpic->irq_count)
 		return -EINVAL;
 
@@ -1025,6 +1088,7 @@
 			   irq_hw_number_t *out_hwirq, unsigned int *out_flags)
 
 {
+	struct mpic *mpic = h->host_data;
 	static unsigned char map_mpic_senses[4] = {
 		IRQ_TYPE_EDGE_RISING,
 		IRQ_TYPE_LEVEL_LOW,
@@ -1033,7 +1097,38 @@
 	};
 
 	*out_hwirq = intspec[0];
-	if (intsize > 1) {
+	if (intsize >= 4 && (mpic->flags & MPIC_FSL)) {
+		/*
+		 * Freescale MPIC with extended intspec:
+		 * First two cells are as usual.  Third specifies
+		 * an "interrupt type".  Fourth is type-specific data.
+		 *
+		 * See Documentation/devicetree/bindings/powerpc/fsl/mpic.txt
+		 */
+		switch (intspec[2]) {
+		case 0:
+		case 1: /* no EISR/EIMR support for now, treat as shared IRQ */
+			break;
+		case 2:
+			if (intspec[0] >= ARRAY_SIZE(mpic->ipi_vecs))
+				return -EINVAL;
+
+			*out_hwirq = mpic->ipi_vecs[intspec[0]];
+			break;
+		case 3:
+			if (intspec[0] >= ARRAY_SIZE(mpic->timer_vecs))
+				return -EINVAL;
+
+			*out_hwirq = mpic->timer_vecs[intspec[0]];
+			break;
+		default:
+			pr_debug("%s: unknown irq type %u\n",
+				 __func__, intspec[2]);
+			return -EINVAL;
+		}
+
+		*out_flags = map_mpic_senses[intspec[1] & 3];
+	} else if (intsize > 1) {
 		u32 mask = 0x3;
 
 		/* Apple invented a new race of encoding on machines with
@@ -1109,6 +1204,9 @@
 	mpic->hc_ipi.name = name;
 #endif /* CONFIG_SMP */
 
+	mpic->hc_tm = mpic_tm_chip;
+	mpic->hc_tm.name = name;
+
 	mpic->flags = flags;
 	mpic->isu_size = isu_size;
 	mpic->irq_count = irq_count;
@@ -1119,10 +1217,14 @@
 	else
 		intvec_top = 255;
 
-	mpic->timer_vecs[0] = intvec_top - 8;
-	mpic->timer_vecs[1] = intvec_top - 7;
-	mpic->timer_vecs[2] = intvec_top - 6;
-	mpic->timer_vecs[3] = intvec_top - 5;
+	mpic->timer_vecs[0] = intvec_top - 12;
+	mpic->timer_vecs[1] = intvec_top - 11;
+	mpic->timer_vecs[2] = intvec_top - 10;
+	mpic->timer_vecs[3] = intvec_top - 9;
+	mpic->timer_vecs[4] = intvec_top - 8;
+	mpic->timer_vecs[5] = intvec_top - 7;
+	mpic->timer_vecs[6] = intvec_top - 6;
+	mpic->timer_vecs[7] = intvec_top - 5;
 	mpic->ipi_vecs[0]   = intvec_top - 4;
 	mpic->ipi_vecs[1]   = intvec_top - 3;
 	mpic->ipi_vecs[2]   = intvec_top - 2;
@@ -1132,6 +1234,8 @@
 	/* Check for "big-endian" in device-tree */
 	if (node && of_get_property(node, "big-endian", NULL) != NULL)
 		mpic->flags |= MPIC_BIG_ENDIAN;
+	if (node && of_device_is_compatible(node, "fsl,mpic"))
+		mpic->flags |= MPIC_FSL;
 
 	/* Look for protected sources */
 	if (node) {
@@ -1323,15 +1427,17 @@
 	/* Set current processor priority to max */
 	mpic_cpu_write(MPIC_INFO(CPU_CURRENT_TASK_PRI), 0xf);
 
-	/* Initialize timers: just disable them all */
+	/* Initialize timers to our reserved vectors and mask them for now */
 	for (i = 0; i < 4; i++) {
 		mpic_write(mpic->tmregs,
 			   i * MPIC_INFO(TIMER_STRIDE) +
-			   MPIC_INFO(TIMER_DESTINATION), 0);
+			   MPIC_INFO(TIMER_DESTINATION),
+			   1 << hard_smp_processor_id());
 		mpic_write(mpic->tmregs,
 			   i * MPIC_INFO(TIMER_STRIDE) +
 			   MPIC_INFO(TIMER_VECTOR_PRI),
 			   MPIC_VECPRI_MASK |
+			   (9 << MPIC_VECPRI_PRIORITY_SHIFT) |
 			   (mpic->timer_vecs[0] + i));
 	}
 
@@ -1427,7 +1533,7 @@
 void mpic_irq_set_priority(unsigned int irq, unsigned int pri)
 {
 	struct mpic *mpic = mpic_find(irq);
-	unsigned int src = mpic_irq_to_hw(irq);
+	unsigned int src = virq_to_hw(irq);
 	unsigned long flags;
 	u32 reg;
 
@@ -1440,6 +1546,11 @@
 			~MPIC_VECPRI_PRIORITY_MASK;
 		mpic_ipi_write(src - mpic->ipi_vecs[0],
 			       reg | (pri << MPIC_VECPRI_PRIORITY_SHIFT));
+	} else if (mpic_is_tm(mpic, irq)) {
+		reg = mpic_tm_read(src - mpic->timer_vecs[0]) &
+			~MPIC_VECPRI_PRIORITY_MASK;
+		mpic_tm_write(src - mpic->timer_vecs[0],
+			      reg | (pri << MPIC_VECPRI_PRIORITY_SHIFT));
 	} else {
 		reg = mpic_irq_read(src, MPIC_INFO(IRQ_VECTOR_PRI))
 			& ~MPIC_VECPRI_PRIORITY_MASK;
@@ -1538,9 +1649,8 @@
 		return NO_IRQ;
 	}
 	if (unlikely(mpic->protected && test_bit(src, mpic->protected))) {
-		if (printk_ratelimit())
-			printk(KERN_WARNING "%s: Got protected source %d !\n",
-			       mpic->name, (int)src);
+		printk_ratelimited(KERN_WARNING "%s: Got protected source %d !\n",
+				   mpic->name, (int)src);
 		mpic_eoi(mpic);
 		return NO_IRQ;
 	}
@@ -1578,9 +1688,8 @@
 		return NO_IRQ;
 	}
 	if (unlikely(mpic->protected && test_bit(src, mpic->protected))) {
-		if (printk_ratelimit())
-			printk(KERN_WARNING "%s: Got protected source %d !\n",
-			       mpic->name, (int)src);
+		printk_ratelimited(KERN_WARNING "%s: Got protected source %d !\n",
+				   mpic->name, (int)src);
 		return NO_IRQ;
 	}
 
@@ -1619,46 +1728,28 @@
 	}
 }
 
-static void mpic_send_ipi(unsigned int ipi_no, const struct cpumask *cpu_mask)
+void smp_mpic_message_pass(int cpu, int msg)
 {
 	struct mpic *mpic = mpic_primary;
+	u32 physmask;
 
 	BUG_ON(mpic == NULL);
 
-#ifdef DEBUG_IPI
-	DBG("%s: send_ipi(ipi_no: %d)\n", mpic->name, ipi_no);
-#endif
-
-	mpic_cpu_write(MPIC_INFO(CPU_IPI_DISPATCH_0) +
-		       ipi_no * MPIC_INFO(CPU_IPI_DISPATCH_STRIDE),
-		       mpic_physmask(cpumask_bits(cpu_mask)[0]));
-}
-
-void smp_mpic_message_pass(int target, int msg)
-{
-	cpumask_var_t tmp;
-
 	/* make sure we're sending something that translates to an IPI */
 	if ((unsigned int)msg > 3) {
 		printk("SMP %d: smp_message_pass: unknown msg %d\n",
 		       smp_processor_id(), msg);
 		return;
 	}
-	switch (target) {
-	case MSG_ALL:
-		mpic_send_ipi(msg, cpu_online_mask);
-		break;
-	case MSG_ALL_BUT_SELF:
-		alloc_cpumask_var(&tmp, GFP_NOWAIT);
-		cpumask_andnot(tmp, cpu_online_mask,
-			       cpumask_of(smp_processor_id()));
-		mpic_send_ipi(msg, tmp);
-		free_cpumask_var(tmp);
-		break;
-	default:
-		mpic_send_ipi(msg, cpumask_of(target));
-		break;
-	}
+
+#ifdef DEBUG_IPI
+	DBG("%s: send_ipi(ipi_no: %d)\n", mpic->name, msg);
+#endif
+
+	physmask = 1 << get_hard_smp_processor_id(cpu);
+
+	mpic_cpu_write(MPIC_INFO(CPU_IPI_DISPATCH_0) +
+		       msg * MPIC_INFO(CPU_IPI_DISPATCH_STRIDE), physmask);
 }
 
 int __init smp_mpic_probe(void)
@@ -1702,9 +1793,8 @@
 #endif /* CONFIG_SMP */
 
 #ifdef CONFIG_PM
-static int mpic_suspend(struct sys_device *dev, pm_message_t state)
+static void mpic_suspend_one(struct mpic *mpic)
 {
-	struct mpic *mpic = container_of(dev, struct mpic, sysdev);
 	int i;
 
 	for (i = 0; i < mpic->num_sources; i++) {
@@ -1713,13 +1803,22 @@
 		mpic->save_data[i].dest =
 			mpic_irq_read(i, MPIC_INFO(IRQ_DESTINATION));
 	}
+}
+
+static int mpic_suspend(void)
+{
+	struct mpic *mpic = mpics;
+
+	while (mpic) {
+		mpic_suspend_one(mpic);
+		mpic = mpic->next;
+	}
 
 	return 0;
 }
 
-static int mpic_resume(struct sys_device *dev)
+static void mpic_resume_one(struct mpic *mpic)
 {
-	struct mpic *mpic = container_of(dev, struct mpic, sysdev);
 	int i;
 
 	for (i = 0; i < mpic->num_sources; i++) {
@@ -1746,33 +1845,28 @@
 	}
 #endif
 	} /* end for loop */
+}
 
-	return 0;
+static void mpic_resume(void)
+{
+	struct mpic *mpic = mpics;
+
+	while (mpic) {
+		mpic_resume_one(mpic);
+		mpic = mpic->next;
+	}
 }
-#endif
 
-static struct sysdev_class mpic_sysclass = {
-#ifdef CONFIG_PM
+static struct syscore_ops mpic_syscore_ops = {
 	.resume = mpic_resume,
 	.suspend = mpic_suspend,
-#endif
-	.name = "mpic",
 };
 
 static int mpic_init_sys(void)
 {
-	struct mpic *mpic = mpics;
-	int error, id = 0;
-
-	error = sysdev_class_register(&mpic_sysclass);
-
-	while (mpic && !error) {
-		mpic->sysdev.cls = &mpic_sysclass;
-		mpic->sysdev.id = id++;
-		error = sysdev_register(&mpic->sysdev);
-		mpic = mpic->next;
-	}
-	return error;
+	register_syscore_ops(&mpic_syscore_ops);
+	return 0;
 }
 
 device_initcall(mpic_init_sys);
+#endif
diff -druN linux-2.6.39-libre/arch/powerpc/sysdev/mv64x60_pic.c linux-3.0-rc7-libre/arch/powerpc/sysdev/mv64x60_pic.c
--- linux-2.6.39-libre/arch/powerpc/sysdev/mv64x60_pic.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/sysdev/mv64x60_pic.c	2011-07-11 19:51:52.000000000 -0400
@@ -78,7 +78,7 @@
 
 static void mv64x60_mask_low(struct irq_data *d)
 {
-	int level2 = irq_map[d->irq].hwirq & MV64x60_LEVEL2_MASK;
+	int level2 = irqd_to_hwirq(d) & MV64x60_LEVEL2_MASK;
 	unsigned long flags;
 
 	spin_lock_irqsave(&mv64x60_lock, flags);
@@ -91,7 +91,7 @@
 
 static void mv64x60_unmask_low(struct irq_data *d)
 {
-	int level2 = irq_map[d->irq].hwirq & MV64x60_LEVEL2_MASK;
+	int level2 = irqd_to_hwirq(d) & MV64x60_LEVEL2_MASK;
 	unsigned long flags;
 
 	spin_lock_irqsave(&mv64x60_lock, flags);
@@ -115,7 +115,7 @@
 
 static void mv64x60_mask_high(struct irq_data *d)
 {
-	int level2 = irq_map[d->irq].hwirq & MV64x60_LEVEL2_MASK;
+	int level2 = irqd_to_hwirq(d) & MV64x60_LEVEL2_MASK;
 	unsigned long flags;
 
 	spin_lock_irqsave(&mv64x60_lock, flags);
@@ -128,7 +128,7 @@
 
 static void mv64x60_unmask_high(struct irq_data *d)
 {
-	int level2 = irq_map[d->irq].hwirq & MV64x60_LEVEL2_MASK;
+	int level2 = irqd_to_hwirq(d) & MV64x60_LEVEL2_MASK;
 	unsigned long flags;
 
 	spin_lock_irqsave(&mv64x60_lock, flags);
@@ -152,7 +152,7 @@
 
 static void mv64x60_mask_gpp(struct irq_data *d)
 {
-	int level2 = irq_map[d->irq].hwirq & MV64x60_LEVEL2_MASK;
+	int level2 = irqd_to_hwirq(d) & MV64x60_LEVEL2_MASK;
 	unsigned long flags;
 
 	spin_lock_irqsave(&mv64x60_lock, flags);
@@ -165,7 +165,7 @@
 
 static void mv64x60_mask_ack_gpp(struct irq_data *d)
 {
-	int level2 = irq_map[d->irq].hwirq & MV64x60_LEVEL2_MASK;
+	int level2 = irqd_to_hwirq(d) & MV64x60_LEVEL2_MASK;
 	unsigned long flags;
 
 	spin_lock_irqsave(&mv64x60_lock, flags);
@@ -180,7 +180,7 @@
 
 static void mv64x60_unmask_gpp(struct irq_data *d)
 {
-	int level2 = irq_map[d->irq].hwirq & MV64x60_LEVEL2_MASK;
+	int level2 = irqd_to_hwirq(d) & MV64x60_LEVEL2_MASK;
 	unsigned long flags;
 
 	spin_lock_irqsave(&mv64x60_lock, flags);
diff -druN linux-2.6.39-libre/arch/powerpc/sysdev/ppc4xx_msi.c linux-3.0-rc7-libre/arch/powerpc/sysdev/ppc4xx_msi.c
--- linux-2.6.39-libre/arch/powerpc/sysdev/ppc4xx_msi.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/powerpc/sysdev/ppc4xx_msi.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,276 @@
+/*
+ * Adding PCI-E MSI support for PPC4XX SoCs.
+ *
+ * Copyright (c) 2010, Applied Micro Circuits Corporation
+ * Authors:	Tirumala R Marri <tmarri@apm.com>
+ *		Feng Kan <fkan@apm.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public 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/irq.h>
+#include <linux/bootmem.h>
+#include <linux/pci.h>
+#include <linux/msi.h>
+#include <linux/of_platform.h>
+#include <linux/interrupt.h>
+#include <asm/prom.h>
+#include <asm/hw_irq.h>
+#include <asm/ppc-pci.h>
+#include <boot/dcr.h>
+#include <asm/dcr-regs.h>
+#include <asm/msi_bitmap.h>
+
+#define PEIH_TERMADH	0x00
+#define PEIH_TERMADL	0x08
+#define PEIH_MSIED	0x10
+#define PEIH_MSIMK	0x18
+#define PEIH_MSIASS	0x20
+#define PEIH_FLUSH0	0x30
+#define PEIH_FLUSH1	0x38
+#define PEIH_CNTRST	0x48
+#define NR_MSI_IRQS	4
+
+struct ppc4xx_msi {
+	u32 msi_addr_lo;
+	u32 msi_addr_hi;
+	void __iomem *msi_regs;
+	int msi_virqs[NR_MSI_IRQS];
+	struct msi_bitmap bitmap;
+	struct device_node *msi_dev;
+};
+
+static struct ppc4xx_msi ppc4xx_msi;
+
+static int ppc4xx_msi_init_allocator(struct platform_device *dev,
+		struct ppc4xx_msi *msi_data)
+{
+	int err;
+
+	err = msi_bitmap_alloc(&msi_data->bitmap, NR_MSI_IRQS,
+			      dev->dev.of_node);
+	if (err)
+		return err;
+
+	err = msi_bitmap_reserve_dt_hwirqs(&msi_data->bitmap);
+	if (err < 0) {
+		msi_bitmap_free(&msi_data->bitmap);
+		return err;
+	}
+
+	return 0;
+}
+
+static int ppc4xx_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
+{
+	int int_no = -ENOMEM;
+	unsigned int virq;
+	struct msi_msg msg;
+	struct msi_desc *entry;
+	struct ppc4xx_msi *msi_data = &ppc4xx_msi;
+
+	list_for_each_entry(entry, &dev->msi_list, list) {
+		int_no = msi_bitmap_alloc_hwirqs(&msi_data->bitmap, 1);
+		if (int_no >= 0)
+			break;
+		if (int_no < 0) {
+			pr_debug("%s: fail allocating msi interrupt\n",
+					__func__);
+		}
+		virq = irq_of_parse_and_map(msi_data->msi_dev, int_no);
+		if (virq == NO_IRQ) {
+			dev_err(&dev->dev, "%s: fail mapping irq\n", __func__);
+			msi_bitmap_free_hwirqs(&msi_data->bitmap, int_no, 1);
+			return -ENOSPC;
+		}
+		dev_dbg(&dev->dev, "%s: virq = %d\n", __func__, virq);
+
+		/* Setup msi address space */
+		msg.address_hi = msi_data->msi_addr_hi;
+		msg.address_lo = msi_data->msi_addr_lo;
+
+		irq_set_msi_desc(virq, entry);
+		msg.data = int_no;
+		write_msi_msg(virq, &msg);
+	}
+	return 0;
+}
+
+void ppc4xx_teardown_msi_irqs(struct pci_dev *dev)
+{
+	struct msi_desc *entry;
+	struct ppc4xx_msi *msi_data = &ppc4xx_msi;
+
+	dev_dbg(&dev->dev, "PCIE-MSI: tearing down msi irqs\n");
+
+	list_for_each_entry(entry, &dev->msi_list, list) {
+		if (entry->irq == NO_IRQ)
+			continue;
+		irq_set_msi_desc(entry->irq, NULL);
+		msi_bitmap_free_hwirqs(&msi_data->bitmap,
+				virq_to_hw(entry->irq), 1);
+		irq_dispose_mapping(entry->irq);
+	}
+}
+
+static int ppc4xx_msi_check_device(struct pci_dev *pdev, int nvec, int type)
+{
+	dev_dbg(&pdev->dev, "PCIE-MSI:%s called. vec %x type %d\n",
+		__func__, nvec, type);
+	if (type == PCI_CAP_ID_MSIX)
+		pr_debug("ppc4xx msi: MSI-X untested, trying anyway.\n");
+
+	return 0;
+}
+
+static int ppc4xx_setup_pcieh_hw(struct platform_device *dev,
+				 struct resource res, struct ppc4xx_msi *msi)
+{
+	const u32 *msi_data;
+	const u32 *msi_mask;
+	const u32 *sdr_addr;
+	dma_addr_t msi_phys;
+	void *msi_virt;
+
+	sdr_addr = of_get_property(dev->dev.of_node, "sdr-base", NULL);
+	if (!sdr_addr)
+		return -1;
+
+	SDR0_WRITE(sdr_addr, (u64)res.start >> 32);	 /*HIGH addr */
+	SDR0_WRITE(sdr_addr + 1, res.start & 0xFFFFFFFF); /* Low addr */
+
+
+	msi->msi_dev = of_find_node_by_name(NULL, "ppc4xx-msi");
+	if (msi->msi_dev)
+		return -ENODEV;
+
+	msi->msi_regs = of_iomap(msi->msi_dev, 0);
+	if (!msi->msi_regs) {
+		dev_err(&dev->dev, "of_iomap problem failed\n");
+		return -ENOMEM;
+	}
+	dev_dbg(&dev->dev, "PCIE-MSI: msi register mapped 0x%x 0x%x\n",
+		(u32) (msi->msi_regs + PEIH_TERMADH), (u32) (msi->msi_regs));
+
+	msi_virt = dma_alloc_coherent(&dev->dev, 64, &msi_phys, GFP_KERNEL);
+	msi->msi_addr_hi = 0x0;
+	msi->msi_addr_lo = (u32) msi_phys;
+	dev_dbg(&dev->dev, "PCIE-MSI: msi address 0x%x\n", msi->msi_addr_lo);
+
+	/* Progam the Interrupt handler Termination addr registers */
+	out_be32(msi->msi_regs + PEIH_TERMADH, msi->msi_addr_hi);
+	out_be32(msi->msi_regs + PEIH_TERMADL, msi->msi_addr_lo);
+
+	msi_data = of_get_property(dev->dev.of_node, "msi-data", NULL);
+	if (!msi_data)
+		return -1;
+	msi_mask = of_get_property(dev->dev.of_node, "msi-mask", NULL);
+	if (!msi_mask)
+		return -1;
+	/* Program MSI Expected data and Mask bits */
+	out_be32(msi->msi_regs + PEIH_MSIED, *msi_data);
+	out_be32(msi->msi_regs + PEIH_MSIMK, *msi_mask);
+
+	return 0;
+}
+
+static int ppc4xx_of_msi_remove(struct platform_device *dev)
+{
+	struct ppc4xx_msi *msi = dev->dev.platform_data;
+	int i;
+	int virq;
+
+	for (i = 0; i < NR_MSI_IRQS; i++) {
+		virq = msi->msi_virqs[i];
+		if (virq != NO_IRQ)
+			irq_dispose_mapping(virq);
+	}
+
+	if (msi->bitmap.bitmap)
+		msi_bitmap_free(&msi->bitmap);
+	iounmap(msi->msi_regs);
+	of_node_put(msi->msi_dev);
+	kfree(msi);
+
+	return 0;
+}
+
+static int __devinit ppc4xx_msi_probe(struct platform_device *dev)
+{
+	struct ppc4xx_msi *msi;
+	struct resource res;
+	int err = 0;
+
+	msi = &ppc4xx_msi;/*keep the msi data for further use*/
+
+	dev_dbg(&dev->dev, "PCIE-MSI: Setting up MSI support...\n");
+
+	msi = kzalloc(sizeof(struct ppc4xx_msi), GFP_KERNEL);
+	if (!msi) {
+		dev_err(&dev->dev, "No memory for MSI structure\n");
+		return -ENOMEM;
+	}
+	dev->dev.platform_data = msi;
+
+	/* Get MSI ranges */
+	err = of_address_to_resource(dev->dev.of_node, 0, &res);
+	if (err) {
+		dev_err(&dev->dev, "%s resource error!\n",
+			dev->dev.of_node->full_name);
+		goto error_out;
+	}
+
+	if (ppc4xx_setup_pcieh_hw(dev, res, msi))
+		goto error_out;
+
+	err = ppc4xx_msi_init_allocator(dev, msi);
+	if (err) {
+		dev_err(&dev->dev, "Error allocating MSI bitmap\n");
+		goto error_out;
+	}
+
+	ppc_md.setup_msi_irqs = ppc4xx_setup_msi_irqs;
+	ppc_md.teardown_msi_irqs = ppc4xx_teardown_msi_irqs;
+	ppc_md.msi_check_device = ppc4xx_msi_check_device;
+	return err;
+
+error_out:
+	ppc4xx_of_msi_remove(dev);
+	return err;
+}
+static const struct of_device_id ppc4xx_msi_ids[] = {
+	{
+		.compatible = "amcc,ppc4xx-msi",
+	},
+	{}
+};
+static struct platform_driver ppc4xx_msi_driver = {
+	.probe = ppc4xx_msi_probe,
+	.remove = ppc4xx_of_msi_remove,
+	.driver = {
+		   .name = "ppc4xx-msi",
+		   .owner = THIS_MODULE,
+		   .of_match_table = ppc4xx_msi_ids,
+		   },
+
+};
+
+static __init int ppc4xx_msi_init(void)
+{
+	return platform_driver_register(&ppc4xx_msi_driver);
+}
+
+subsys_initcall(ppc4xx_msi_init);
diff -druN linux-2.6.39-libre/arch/powerpc/sysdev/qe_lib/qe_ic.c linux-3.0-rc7-libre/arch/powerpc/sysdev/qe_lib/qe_ic.c
--- linux-2.6.39-libre/arch/powerpc/sysdev/qe_lib/qe_ic.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/sysdev/qe_lib/qe_ic.c	2011-07-11 19:51:52.000000000 -0400
@@ -197,12 +197,10 @@
 	return irq_data_get_irq_chip_data(d);
 }
 
-#define virq_to_hw(virq)	((unsigned int)irq_map[virq].hwirq)
-
 static void qe_ic_unmask_irq(struct irq_data *d)
 {
 	struct qe_ic *qe_ic = qe_ic_from_irq_data(d);
-	unsigned int src = virq_to_hw(d->irq);
+	unsigned int src = irqd_to_hwirq(d);
 	unsigned long flags;
 	u32 temp;
 
@@ -218,7 +216,7 @@
 static void qe_ic_mask_irq(struct irq_data *d)
 {
 	struct qe_ic *qe_ic = qe_ic_from_irq_data(d);
-	unsigned int src = virq_to_hw(d->irq);
+	unsigned int src = irqd_to_hwirq(d);
 	unsigned long flags;
 	u32 temp;
 
diff -druN linux-2.6.39-libre/arch/powerpc/sysdev/scom.c linux-3.0-rc7-libre/arch/powerpc/sysdev/scom.c
--- linux-2.6.39-libre/arch/powerpc/sysdev/scom.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/powerpc/sysdev/scom.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,192 @@
+/*
+ * Copyright 2010 Benjamin Herrenschmidt, IBM Corp
+ *                <benh@kernel.crashing.org>
+ *     and        David Gibson, IBM Corporation.
+ *
+ *   This program is free software;  you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY;  without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
+ *   the GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program;  if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/kernel.h>
+#include <linux/debugfs.h>
+#include <linux/slab.h>
+#include <asm/prom.h>
+#include <asm/scom.h>
+
+const struct scom_controller *scom_controller;
+EXPORT_SYMBOL_GPL(scom_controller);
+
+struct device_node *scom_find_parent(struct device_node *node)
+{
+	struct device_node *par, *tmp;
+	const u32 *p;
+
+	for (par = of_node_get(node); par;) {
+		if (of_get_property(par, "scom-controller", NULL))
+			break;
+		p = of_get_property(par, "scom-parent", NULL);
+		tmp = par;
+		if (p == NULL)
+			par = of_get_parent(par);
+		else
+			par = of_find_node_by_phandle(*p);
+		of_node_put(tmp);
+	}
+	return par;
+}
+EXPORT_SYMBOL_GPL(scom_find_parent);
+
+scom_map_t scom_map_device(struct device_node *dev, int index)
+{
+	struct device_node *parent;
+	unsigned int cells, size;
+	const u32 *prop;
+	u64 reg, cnt;
+	scom_map_t ret;
+
+	parent = scom_find_parent(dev);
+
+	if (parent == NULL)
+		return 0;
+
+	prop = of_get_property(parent, "#scom-cells", NULL);
+	cells = prop ? *prop : 1;
+
+	prop = of_get_property(dev, "scom-reg", &size);
+	if (!prop)
+		return 0;
+	size >>= 2;
+
+	if (index >= (size / (2*cells)))
+		return 0;
+
+	reg = of_read_number(&prop[index * cells * 2], cells);
+	cnt = of_read_number(&prop[index * cells * 2 + cells], cells);
+
+	ret = scom_map(parent, reg, cnt);
+	of_node_put(parent);
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(scom_map_device);
+
+#ifdef CONFIG_SCOM_DEBUGFS
+struct scom_debug_entry {
+	struct device_node *dn;
+	unsigned long addr;
+	scom_map_t map;
+	spinlock_t lock;
+	char name[8];
+	struct debugfs_blob_wrapper blob;
+};
+
+static int scom_addr_set(void *data, u64 val)
+{
+	struct scom_debug_entry *ent = data;
+
+	ent->addr = 0;
+	scom_unmap(ent->map);
+
+	ent->map = scom_map(ent->dn, val, 1);
+	if (scom_map_ok(ent->map))
+		ent->addr = val;
+	else
+		return -EFAULT;
+
+	return 0;
+}
+
+static int scom_addr_get(void *data, u64 *val)
+{
+	struct scom_debug_entry *ent = data;
+	*val = ent->addr;
+	return 0;
+}
+DEFINE_SIMPLE_ATTRIBUTE(scom_addr_fops, scom_addr_get, scom_addr_set,
+			"0x%llx\n");
+
+static int scom_val_set(void *data, u64 val)
+{
+	struct scom_debug_entry *ent = data;
+
+	if (!scom_map_ok(ent->map))
+		return -EFAULT;
+
+	scom_write(ent->map, 0, val);
+
+	return 0;
+}
+
+static int scom_val_get(void *data, u64 *val)
+{
+	struct scom_debug_entry *ent = data;
+
+	if (!scom_map_ok(ent->map))
+		return -EFAULT;
+
+	*val = scom_read(ent->map, 0);
+	return 0;
+}
+DEFINE_SIMPLE_ATTRIBUTE(scom_val_fops, scom_val_get, scom_val_set,
+			"0x%llx\n");
+
+static int scom_debug_init_one(struct dentry *root, struct device_node *dn,
+			       int i)
+{
+	struct scom_debug_entry *ent;
+	struct dentry *dir;
+
+	ent = kzalloc(sizeof(*ent), GFP_KERNEL);
+	if (!ent)
+		return -ENOMEM;
+
+	ent->dn = of_node_get(dn);
+	ent->map = SCOM_MAP_INVALID;
+	spin_lock_init(&ent->lock);
+	snprintf(ent->name, 8, "scom%d", i);
+	ent->blob.data = dn->full_name;
+	ent->blob.size = strlen(dn->full_name);
+
+	dir = debugfs_create_dir(ent->name, root);
+	if (!dir) {
+		of_node_put(dn);
+		kfree(ent);
+		return -1;
+	}
+
+	debugfs_create_file("addr", 0600, dir, ent, &scom_addr_fops);
+	debugfs_create_file("value", 0600, dir, ent, &scom_val_fops);
+	debugfs_create_blob("path", 0400, dir, &ent->blob);
+
+	return 0;
+}
+
+static int scom_debug_init(void)
+{
+	struct device_node *dn;
+	struct dentry *root;
+	int i, rc;
+
+	root = debugfs_create_dir("scom", powerpc_debugfs_root);
+	if (!root)
+		return -1;
+
+	i = rc = 0;
+	for_each_node_with_property(dn, "scom-controller")
+		rc |= scom_debug_init_one(root, dn, i++);
+
+	return rc;
+}
+device_initcall(scom_debug_init);
+#endif /* CONFIG_SCOM_DEBUGFS */
diff -druN linux-2.6.39-libre/arch/powerpc/sysdev/uic.c linux-3.0-rc7-libre/arch/powerpc/sysdev/uic.c
--- linux-2.6.39-libre/arch/powerpc/sysdev/uic.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/sysdev/uic.c	2011-07-11 19:51:52.000000000 -0400
@@ -41,8 +41,6 @@
 #define UIC_VR		0x7
 #define UIC_VCR		0x8
 
-#define uic_irq_to_hw(virq)	(irq_map[virq].hwirq)
-
 struct uic *primary_uic;
 
 struct uic {
@@ -58,7 +56,7 @@
 static void uic_unmask_irq(struct irq_data *d)
 {
 	struct uic *uic = irq_data_get_irq_chip_data(d);
-	unsigned int src = uic_irq_to_hw(d->irq);
+	unsigned int src = irqd_to_hwirq(d);
 	unsigned long flags;
 	u32 er, sr;
 
@@ -76,7 +74,7 @@
 static void uic_mask_irq(struct irq_data *d)
 {
 	struct uic *uic = irq_data_get_irq_chip_data(d);
-	unsigned int src = uic_irq_to_hw(d->irq);
+	unsigned int src = irqd_to_hwirq(d);
 	unsigned long flags;
 	u32 er;
 
@@ -90,7 +88,7 @@
 static void uic_ack_irq(struct irq_data *d)
 {
 	struct uic *uic = irq_data_get_irq_chip_data(d);
-	unsigned int src = uic_irq_to_hw(d->irq);
+	unsigned int src = irqd_to_hwirq(d);
 	unsigned long flags;
 
 	spin_lock_irqsave(&uic->lock, flags);
@@ -101,7 +99,7 @@
 static void uic_mask_ack_irq(struct irq_data *d)
 {
 	struct uic *uic = irq_data_get_irq_chip_data(d);
-	unsigned int src = uic_irq_to_hw(d->irq);
+	unsigned int src = irqd_to_hwirq(d);
 	unsigned long flags;
 	u32 er, sr;
 
@@ -126,7 +124,7 @@
 static int uic_set_irq_type(struct irq_data *d, unsigned int flow_type)
 {
 	struct uic *uic = irq_data_get_irq_chip_data(d);
-	unsigned int src = uic_irq_to_hw(d->irq);
+	unsigned int src = irqd_to_hwirq(d);
 	unsigned long flags;
 	int trigger, polarity;
 	u32 tr, pr, mask;
diff -druN linux-2.6.39-libre/arch/powerpc/sysdev/xics/icp-hv.c linux-3.0-rc7-libre/arch/powerpc/sysdev/xics/icp-hv.c
--- linux-2.6.39-libre/arch/powerpc/sysdev/xics/icp-hv.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/powerpc/sysdev/xics/icp-hv.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,164 @@
+/*
+ * Copyright 2011 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 <linux/kernel.h>
+#include <linux/irq.h>
+#include <linux/smp.h>
+#include <linux/interrupt.h>
+#include <linux/init.h>
+#include <linux/cpu.h>
+#include <linux/of.h>
+
+#include <asm/smp.h>
+#include <asm/irq.h>
+#include <asm/errno.h>
+#include <asm/xics.h>
+#include <asm/io.h>
+#include <asm/hvcall.h>
+
+static inline unsigned int icp_hv_get_xirr(unsigned char cppr)
+{
+	unsigned long retbuf[PLPAR_HCALL_BUFSIZE];
+	long rc;
+
+	rc = plpar_hcall(H_XIRR, retbuf, cppr);
+	if (rc != H_SUCCESS)
+		panic(" bad return code xirr - rc = %lx\n", rc);
+	return (unsigned int)retbuf[0];
+}
+
+static inline void icp_hv_set_xirr(unsigned int value)
+{
+	long rc = plpar_hcall_norets(H_EOI, value);
+	if (rc != H_SUCCESS)
+		panic("bad return code EOI - rc = %ld, value=%x\n", rc, value);
+}
+
+static inline void icp_hv_set_cppr(u8 value)
+{
+	long rc = plpar_hcall_norets(H_CPPR, value);
+	if (rc != H_SUCCESS)
+		panic("bad return code cppr - rc = %lx\n", rc);
+}
+
+static inline void icp_hv_set_qirr(int n_cpu , u8 value)
+{
+	long rc = plpar_hcall_norets(H_IPI, get_hard_smp_processor_id(n_cpu),
+				     value);
+	if (rc != H_SUCCESS)
+		panic("bad return code qirr - rc = %lx\n", rc);
+}
+
+static void icp_hv_eoi(struct irq_data *d)
+{
+	unsigned int hw_irq = (unsigned int)irqd_to_hwirq(d);
+
+	iosync();
+	icp_hv_set_xirr((xics_pop_cppr() << 24) | hw_irq);
+}
+
+static void icp_hv_teardown_cpu(void)
+{
+	int cpu = smp_processor_id();
+
+	/* Clear any pending IPI */
+	icp_hv_set_qirr(cpu, 0xff);
+}
+
+static void icp_hv_flush_ipi(void)
+{
+	/* We take the ipi irq but and never return so we
+	 * need to EOI the IPI, but want to leave our priority 0
+	 *
+	 * should we check all the other interrupts too?
+	 * should we be flagging idle loop instead?
+	 * or creating some task to be scheduled?
+	 */
+
+	icp_hv_set_xirr((0x00 << 24) | XICS_IPI);
+}
+
+static unsigned int icp_hv_get_irq(void)
+{
+	unsigned int xirr = icp_hv_get_xirr(xics_cppr_top());
+	unsigned int vec = xirr & 0x00ffffff;
+	unsigned int irq;
+
+	if (vec == XICS_IRQ_SPURIOUS)
+		return NO_IRQ;
+
+	irq = irq_radix_revmap_lookup(xics_host, vec);
+	if (likely(irq != NO_IRQ)) {
+		xics_push_cppr(vec);
+		return irq;
+	}
+
+	/* We don't have a linux mapping, so have rtas mask it. */
+	xics_mask_unknown_vec(vec);
+
+	/* We might learn about it later, so EOI it */
+	icp_hv_set_xirr(xirr);
+
+	return NO_IRQ;
+}
+
+static void icp_hv_set_cpu_priority(unsigned char cppr)
+{
+	xics_set_base_cppr(cppr);
+	icp_hv_set_cppr(cppr);
+	iosync();
+}
+
+#ifdef CONFIG_SMP
+
+static void icp_hv_cause_ipi(int cpu, unsigned long data)
+{
+	icp_hv_set_qirr(cpu, IPI_PRIORITY);
+}
+
+static irqreturn_t icp_hv_ipi_action(int irq, void *dev_id)
+{
+	int cpu = smp_processor_id();
+
+	icp_hv_set_qirr(cpu, 0xff);
+
+	return smp_ipi_demux();
+}
+
+#endif /* CONFIG_SMP */
+
+static const struct icp_ops icp_hv_ops = {
+	.get_irq	= icp_hv_get_irq,
+	.eoi		= icp_hv_eoi,
+	.set_priority	= icp_hv_set_cpu_priority,
+	.teardown_cpu	= icp_hv_teardown_cpu,
+	.flush_ipi	= icp_hv_flush_ipi,
+#ifdef CONFIG_SMP
+	.ipi_action	= icp_hv_ipi_action,
+	.cause_ipi	= icp_hv_cause_ipi,
+#endif
+};
+
+int icp_hv_init(void)
+{
+	struct device_node *np;
+
+	np = of_find_compatible_node(NULL, NULL, "ibm,ppc-xicp");
+	if (!np)
+		np = of_find_node_by_type(NULL,
+				    "PowerPC-External-Interrupt-Presentation");
+	if (!np)
+		return -ENODEV;
+
+	icp_ops = &icp_hv_ops;
+
+	return 0;
+}
+
diff -druN linux-2.6.39-libre/arch/powerpc/sysdev/xics/icp-native.c linux-3.0-rc7-libre/arch/powerpc/sysdev/xics/icp-native.c
--- linux-2.6.39-libre/arch/powerpc/sysdev/xics/icp-native.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/powerpc/sysdev/xics/icp-native.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,293 @@
+/*
+ * Copyright 2011 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 <linux/kernel.h>
+#include <linux/irq.h>
+#include <linux/smp.h>
+#include <linux/interrupt.h>
+#include <linux/init.h>
+#include <linux/cpu.h>
+#include <linux/of.h>
+#include <linux/spinlock.h>
+
+#include <asm/prom.h>
+#include <asm/io.h>
+#include <asm/smp.h>
+#include <asm/irq.h>
+#include <asm/errno.h>
+#include <asm/xics.h>
+
+struct icp_ipl {
+	union {
+		u32 word;
+		u8 bytes[4];
+	} xirr_poll;
+	union {
+		u32 word;
+		u8 bytes[4];
+	} xirr;
+	u32 dummy;
+	union {
+		u32 word;
+		u8 bytes[4];
+	} qirr;
+	u32 link_a;
+	u32 link_b;
+	u32 link_c;
+};
+
+static struct icp_ipl __iomem *icp_native_regs[NR_CPUS];
+
+static inline unsigned int icp_native_get_xirr(void)
+{
+	int cpu = smp_processor_id();
+
+	return in_be32(&icp_native_regs[cpu]->xirr.word);
+}
+
+static inline void icp_native_set_xirr(unsigned int value)
+{
+	int cpu = smp_processor_id();
+
+	out_be32(&icp_native_regs[cpu]->xirr.word, value);
+}
+
+static inline void icp_native_set_cppr(u8 value)
+{
+	int cpu = smp_processor_id();
+
+	out_8(&icp_native_regs[cpu]->xirr.bytes[0], value);
+}
+
+static inline void icp_native_set_qirr(int n_cpu, u8 value)
+{
+	out_8(&icp_native_regs[n_cpu]->qirr.bytes[0], value);
+}
+
+static void icp_native_set_cpu_priority(unsigned char cppr)
+{
+	xics_set_base_cppr(cppr);
+	icp_native_set_cppr(cppr);
+	iosync();
+}
+
+static void icp_native_eoi(struct irq_data *d)
+{
+	unsigned int hw_irq = (unsigned int)irqd_to_hwirq(d);
+
+	iosync();
+	icp_native_set_xirr((xics_pop_cppr() << 24) | hw_irq);
+}
+
+static void icp_native_teardown_cpu(void)
+{
+	int cpu = smp_processor_id();
+
+	/* Clear any pending IPI */
+	icp_native_set_qirr(cpu, 0xff);
+}
+
+static void icp_native_flush_ipi(void)
+{
+	/* We take the ipi irq but and never return so we
+	 * need to EOI the IPI, but want to leave our priority 0
+	 *
+	 * should we check all the other interrupts too?
+	 * should we be flagging idle loop instead?
+	 * or creating some task to be scheduled?
+	 */
+
+	icp_native_set_xirr((0x00 << 24) | XICS_IPI);
+}
+
+static unsigned int icp_native_get_irq(void)
+{
+	unsigned int xirr = icp_native_get_xirr();
+	unsigned int vec = xirr & 0x00ffffff;
+	unsigned int irq;
+
+	if (vec == XICS_IRQ_SPURIOUS)
+		return NO_IRQ;
+
+	irq = irq_radix_revmap_lookup(xics_host, vec);
+	if (likely(irq != NO_IRQ)) {
+		xics_push_cppr(vec);
+		return irq;
+	}
+
+	/* We don't have a linux mapping, so have rtas mask it. */
+	xics_mask_unknown_vec(vec);
+
+	/* We might learn about it later, so EOI it */
+	icp_native_set_xirr(xirr);
+
+	return NO_IRQ;
+}
+
+#ifdef CONFIG_SMP
+
+static void icp_native_cause_ipi(int cpu, unsigned long data)
+{
+	icp_native_set_qirr(cpu, IPI_PRIORITY);
+}
+
+static irqreturn_t icp_native_ipi_action(int irq, void *dev_id)
+{
+	int cpu = smp_processor_id();
+
+	icp_native_set_qirr(cpu, 0xff);
+
+	return smp_ipi_demux();
+}
+
+#endif /* CONFIG_SMP */
+
+static int __init icp_native_map_one_cpu(int hw_id, unsigned long addr,
+					 unsigned long size)
+{
+	char *rname;
+	int i, cpu = -1;
+
+	/* This may look gross but it's good enough for now, we don't quite
+	 * have a hard -> linux processor id matching.
+	 */
+	for_each_possible_cpu(i) {
+		if (!cpu_present(i))
+			continue;
+		if (hw_id == get_hard_smp_processor_id(i)) {
+			cpu = i;
+			break;
+		}
+	}
+
+	/* Fail, skip that CPU. Don't print, it's normal, some XICS come up
+	 * with way more entries in there than you have CPUs
+	 */
+	if (cpu == -1)
+		return 0;
+
+	rname = kasprintf(GFP_KERNEL, "CPU %d [0x%x] Interrupt Presentation",
+			  cpu, hw_id);
+
+	if (!request_mem_region(addr, size, rname)) {
+		pr_warning("icp_native: Could not reserve ICP MMIO"
+			   " for CPU %d, interrupt server #0x%x\n",
+			   cpu, hw_id);
+		return -EBUSY;
+	}
+
+	icp_native_regs[cpu] = ioremap(addr, size);
+	if (!icp_native_regs[cpu]) {
+		pr_warning("icp_native: Failed ioremap for CPU %d, "
+			   "interrupt server #0x%x, addr %#lx\n",
+			   cpu, hw_id, addr);
+		release_mem_region(addr, size);
+		return -ENOMEM;
+	}
+	return 0;
+}
+
+static int __init icp_native_init_one_node(struct device_node *np,
+					   unsigned int *indx)
+{
+	unsigned int ilen;
+	const u32 *ireg;
+	int i;
+	int reg_tuple_size;
+	int num_servers = 0;
+
+	/* This code does the theorically broken assumption that the interrupt
+	 * server numbers are the same as the hard CPU numbers.
+	 * This happens to be the case so far but we are playing with fire...
+	 * should be fixed one of these days. -BenH.
+	 */
+	ireg = of_get_property(np, "ibm,interrupt-server-ranges", &ilen);
+
+	/* Do that ever happen ? we'll know soon enough... but even good'old
+	 * f80 does have that property ..
+	 */
+	WARN_ON((ireg == NULL) || (ilen != 2*sizeof(u32)));
+
+	if (ireg) {
+		*indx = of_read_number(ireg, 1);
+		if (ilen >= 2*sizeof(u32))
+			num_servers = of_read_number(ireg + 1, 1);
+	}
+
+	ireg = of_get_property(np, "reg", &ilen);
+	if (!ireg) {
+		pr_err("icp_native: Can't find interrupt reg property");
+		return -1;
+	}
+
+	reg_tuple_size = (of_n_addr_cells(np) + of_n_size_cells(np)) * 4;
+	if (((ilen % reg_tuple_size) != 0)
+	    || (num_servers && (num_servers != (ilen / reg_tuple_size)))) {
+		pr_err("icp_native: ICP reg len (%d) != num servers (%d)",
+		       ilen / reg_tuple_size, num_servers);
+		return -1;
+	}
+
+	for (i = 0; i < (ilen / reg_tuple_size); i++) {
+		struct resource r;
+		int err;
+
+		err = of_address_to_resource(np, i, &r);
+		if (err) {
+			pr_err("icp_native: Could not translate ICP MMIO"
+			       " for interrupt server 0x%x (%d)\n", *indx, err);
+			return -1;
+		}
+
+		if (icp_native_map_one_cpu(*indx, r.start, r.end - r.start))
+			return -1;
+
+		(*indx)++;
+	}
+	return 0;
+}
+
+static const struct icp_ops icp_native_ops = {
+	.get_irq	= icp_native_get_irq,
+	.eoi		= icp_native_eoi,
+	.set_priority	= icp_native_set_cpu_priority,
+	.teardown_cpu	= icp_native_teardown_cpu,
+	.flush_ipi	= icp_native_flush_ipi,
+#ifdef CONFIG_SMP
+	.ipi_action	= icp_native_ipi_action,
+	.cause_ipi	= icp_native_cause_ipi,
+#endif
+};
+
+int icp_native_init(void)
+{
+	struct device_node *np;
+	u32 indx = 0;
+	int found = 0;
+
+	for_each_compatible_node(np, NULL, "ibm,ppc-xicp")
+		if (icp_native_init_one_node(np, &indx) == 0)
+			found = 1;
+	if (!found) {
+		for_each_node_by_type(np,
+			"PowerPC-External-Interrupt-Presentation") {
+				if (icp_native_init_one_node(np, &indx) == 0)
+					found = 1;
+		}
+	}
+
+	if (found == 0)
+		return -ENODEV;
+
+	icp_ops = &icp_native_ops;
+
+	return 0;
+}
diff -druN linux-2.6.39-libre/arch/powerpc/sysdev/xics/ics-rtas.c linux-3.0-rc7-libre/arch/powerpc/sysdev/xics/ics-rtas.c
--- linux-2.6.39-libre/arch/powerpc/sysdev/xics/ics-rtas.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/powerpc/sysdev/xics/ics-rtas.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,240 @@
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/irq.h>
+#include <linux/smp.h>
+#include <linux/interrupt.h>
+#include <linux/init.h>
+#include <linux/cpu.h>
+#include <linux/of.h>
+#include <linux/spinlock.h>
+#include <linux/msi.h>
+
+#include <asm/prom.h>
+#include <asm/smp.h>
+#include <asm/machdep.h>
+#include <asm/irq.h>
+#include <asm/errno.h>
+#include <asm/xics.h>
+#include <asm/rtas.h>
+
+/* RTAS service tokens */
+static int ibm_get_xive;
+static int ibm_set_xive;
+static int ibm_int_on;
+static int ibm_int_off;
+
+static int ics_rtas_map(struct ics *ics, unsigned int virq);
+static void ics_rtas_mask_unknown(struct ics *ics, unsigned long vec);
+static long ics_rtas_get_server(struct ics *ics, unsigned long vec);
+static int ics_rtas_host_match(struct ics *ics, struct device_node *node);
+
+/* Only one global & state struct ics */
+static struct ics ics_rtas = {
+	.map		= ics_rtas_map,
+	.mask_unknown	= ics_rtas_mask_unknown,
+	.get_server	= ics_rtas_get_server,
+	.host_match	= ics_rtas_host_match,
+};
+
+static void ics_rtas_unmask_irq(struct irq_data *d)
+{
+	unsigned int hw_irq = (unsigned int)irqd_to_hwirq(d);
+	int call_status;
+	int server;
+
+	pr_devel("xics: unmask virq %d [hw 0x%x]\n", d->irq, hw_irq);
+
+	if (hw_irq == XICS_IPI || hw_irq == XICS_IRQ_SPURIOUS)
+		return;
+
+	server = xics_get_irq_server(d->irq, d->affinity, 0);
+
+	call_status = rtas_call(ibm_set_xive, 3, 1, NULL, hw_irq, server,
+				DEFAULT_PRIORITY);
+	if (call_status != 0) {
+		printk(KERN_ERR
+			"%s: ibm_set_xive irq %u server %x returned %d\n",
+			__func__, hw_irq, server, call_status);
+		return;
+	}
+
+	/* Now unmask the interrupt (often a no-op) */
+	call_status = rtas_call(ibm_int_on, 1, 1, NULL, hw_irq);
+	if (call_status != 0) {
+		printk(KERN_ERR "%s: ibm_int_on irq=%u returned %d\n",
+			__func__, hw_irq, call_status);
+		return;
+	}
+}
+
+static unsigned int ics_rtas_startup(struct irq_data *d)
+{
+#ifdef CONFIG_PCI_MSI
+	/*
+	 * The generic MSI code returns with the interrupt disabled on the
+	 * card, using the MSI mask bits. Firmware doesn't appear to unmask
+	 * at that level, so we do it here by hand.
+	 */
+	if (d->msi_desc)
+		unmask_msi_irq(d);
+#endif
+	/* unmask it */
+	ics_rtas_unmask_irq(d);
+	return 0;
+}
+
+static void ics_rtas_mask_real_irq(unsigned int hw_irq)
+{
+	int call_status;
+
+	if (hw_irq == XICS_IPI)
+		return;
+
+	call_status = rtas_call(ibm_int_off, 1, 1, NULL, hw_irq);
+	if (call_status != 0) {
+		printk(KERN_ERR "%s: ibm_int_off irq=%u returned %d\n",
+			__func__, hw_irq, call_status);
+		return;
+	}
+
+	/* Have to set XIVE to 0xff to be able to remove a slot */
+	call_status = rtas_call(ibm_set_xive, 3, 1, NULL, hw_irq,
+				xics_default_server, 0xff);
+	if (call_status != 0) {
+		printk(KERN_ERR "%s: ibm_set_xive(0xff) irq=%u returned %d\n",
+			__func__, hw_irq, call_status);
+		return;
+	}
+}
+
+static void ics_rtas_mask_irq(struct irq_data *d)
+{
+	unsigned int hw_irq = (unsigned int)irqd_to_hwirq(d);
+
+	pr_devel("xics: mask virq %d [hw 0x%x]\n", d->irq, hw_irq);
+
+	if (hw_irq == XICS_IPI || hw_irq == XICS_IRQ_SPURIOUS)
+		return;
+	ics_rtas_mask_real_irq(hw_irq);
+}
+
+static int ics_rtas_set_affinity(struct irq_data *d,
+				 const struct cpumask *cpumask,
+				 bool force)
+{
+	unsigned int hw_irq = (unsigned int)irqd_to_hwirq(d);
+	int status;
+	int xics_status[2];
+	int irq_server;
+
+	if (hw_irq == XICS_IPI || hw_irq == XICS_IRQ_SPURIOUS)
+		return -1;
+
+	status = rtas_call(ibm_get_xive, 1, 3, xics_status, hw_irq);
+
+	if (status) {
+		printk(KERN_ERR "%s: ibm,get-xive irq=%u returns %d\n",
+			__func__, hw_irq, status);
+		return -1;
+	}
+
+	irq_server = xics_get_irq_server(d->irq, cpumask, 1);
+	if (irq_server == -1) {
+		char cpulist[128];
+		cpumask_scnprintf(cpulist, sizeof(cpulist), cpumask);
+		printk(KERN_WARNING
+			"%s: No online cpus in the mask %s for irq %d\n",
+			__func__, cpulist, d->irq);
+		return -1;
+	}
+
+	status = rtas_call(ibm_set_xive, 3, 1, NULL,
+			   hw_irq, irq_server, xics_status[1]);
+
+	if (status) {
+		printk(KERN_ERR "%s: ibm,set-xive irq=%u returns %d\n",
+			__func__, hw_irq, status);
+		return -1;
+	}
+
+	return IRQ_SET_MASK_OK;
+}
+
+static struct irq_chip ics_rtas_irq_chip = {
+	.name = "XICS",
+	.irq_startup = ics_rtas_startup,
+	.irq_mask = ics_rtas_mask_irq,
+	.irq_unmask = ics_rtas_unmask_irq,
+	.irq_eoi = NULL, /* Patched at init time */
+	.irq_set_affinity = ics_rtas_set_affinity
+};
+
+static int ics_rtas_map(struct ics *ics, unsigned int virq)
+{
+	unsigned int hw_irq = (unsigned int)virq_to_hw(virq);
+	int status[2];
+	int rc;
+
+	if (WARN_ON(hw_irq == XICS_IPI || hw_irq == XICS_IRQ_SPURIOUS))
+		return -EINVAL;
+
+	/* Check if RTAS knows about this interrupt */
+	rc = rtas_call(ibm_get_xive, 1, 3, status, hw_irq);
+	if (rc)
+		return -ENXIO;
+
+	irq_set_chip_and_handler(virq, &ics_rtas_irq_chip, handle_fasteoi_irq);
+	irq_set_chip_data(virq, &ics_rtas);
+
+	return 0;
+}
+
+static void ics_rtas_mask_unknown(struct ics *ics, unsigned long vec)
+{
+	ics_rtas_mask_real_irq(vec);
+}
+
+static long ics_rtas_get_server(struct ics *ics, unsigned long vec)
+{
+	int rc, status[2];
+
+	rc = rtas_call(ibm_get_xive, 1, 3, status, vec);
+	if (rc)
+		return -1;
+	return status[0];
+}
+
+static int ics_rtas_host_match(struct ics *ics, struct device_node *node)
+{
+	/* IBM machines have interrupt parents of various funky types for things
+	 * like vdevices, events, etc... The trick we use here is to match
+	 * everything here except the legacy 8259 which is compatible "chrp,iic"
+	 */
+	return !of_device_is_compatible(node, "chrp,iic");
+}
+
+int ics_rtas_init(void)
+{
+	ibm_get_xive = rtas_token("ibm,get-xive");
+	ibm_set_xive = rtas_token("ibm,set-xive");
+	ibm_int_on  = rtas_token("ibm,int-on");
+	ibm_int_off = rtas_token("ibm,int-off");
+
+	/* We enable the RTAS "ICS" if RTAS is present with the
+	 * appropriate tokens
+	 */
+	if (ibm_get_xive == RTAS_UNKNOWN_SERVICE ||
+	    ibm_set_xive == RTAS_UNKNOWN_SERVICE)
+		return -ENODEV;
+
+	/* We need to patch our irq chip's EOI to point to the
+	 * right ICP
+	 */
+	ics_rtas_irq_chip.irq_eoi = icp_ops->eoi;
+
+	/* Register ourselves */
+	xics_register_ics(&ics_rtas);
+
+	return 0;
+}
+
diff -druN linux-2.6.39-libre/arch/powerpc/sysdev/xics/Kconfig linux-3.0-rc7-libre/arch/powerpc/sysdev/xics/Kconfig
--- linux-2.6.39-libre/arch/powerpc/sysdev/xics/Kconfig	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/powerpc/sysdev/xics/Kconfig	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,13 @@
+config PPC_XICS
+       def_bool n
+       select PPC_SMP_MUXED_IPI
+
+config PPC_ICP_NATIVE
+       def_bool n
+
+config PPC_ICP_HV
+       def_bool n
+
+config PPC_ICS_RTAS
+       def_bool n
+
diff -druN linux-2.6.39-libre/arch/powerpc/sysdev/xics/Makefile linux-3.0-rc7-libre/arch/powerpc/sysdev/xics/Makefile
--- linux-2.6.39-libre/arch/powerpc/sysdev/xics/Makefile	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/powerpc/sysdev/xics/Makefile	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,6 @@
+subdir-ccflags-$(CONFIG_PPC_WERROR) := -Werror
+
+obj-y				+= xics-common.o
+obj-$(CONFIG_PPC_ICP_NATIVE)	+= icp-native.o
+obj-$(CONFIG_PPC_ICP_HV)	+= icp-hv.o
+obj-$(CONFIG_PPC_ICS_RTAS)	+= ics-rtas.o
diff -druN linux-2.6.39-libre/arch/powerpc/sysdev/xics/xics-common.c linux-3.0-rc7-libre/arch/powerpc/sysdev/xics/xics-common.c
--- linux-2.6.39-libre/arch/powerpc/sysdev/xics/xics-common.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/powerpc/sysdev/xics/xics-common.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,443 @@
+/*
+ * Copyright 2011 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 <linux/threads.h>
+#include <linux/kernel.h>
+#include <linux/irq.h>
+#include <linux/debugfs.h>
+#include <linux/smp.h>
+#include <linux/interrupt.h>
+#include <linux/seq_file.h>
+#include <linux/init.h>
+#include <linux/cpu.h>
+#include <linux/of.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+
+#include <asm/prom.h>
+#include <asm/io.h>
+#include <asm/smp.h>
+#include <asm/machdep.h>
+#include <asm/irq.h>
+#include <asm/errno.h>
+#include <asm/rtas.h>
+#include <asm/xics.h>
+#include <asm/firmware.h>
+
+/* Globals common to all ICP/ICS implementations */
+const struct icp_ops	*icp_ops;
+
+unsigned int xics_default_server		= 0xff;
+unsigned int xics_default_distrib_server	= 0;
+unsigned int xics_interrupt_server_size		= 8;
+
+DEFINE_PER_CPU(struct xics_cppr, xics_cppr);
+
+struct irq_host *xics_host;
+
+static LIST_HEAD(ics_list);
+
+void xics_update_irq_servers(void)
+{
+	int i, j;
+	struct device_node *np;
+	u32 ilen;
+	const u32 *ireg;
+	u32 hcpuid;
+
+	/* Find the server numbers for the boot cpu. */
+	np = of_get_cpu_node(boot_cpuid, NULL);
+	BUG_ON(!np);
+
+	hcpuid = get_hard_smp_processor_id(boot_cpuid);
+	xics_default_server = xics_default_distrib_server = hcpuid;
+
+	pr_devel("xics: xics_default_server = 0x%x\n", xics_default_server);
+
+	ireg = of_get_property(np, "ibm,ppc-interrupt-gserver#s", &ilen);
+	if (!ireg) {
+		of_node_put(np);
+		return;
+	}
+
+	i = ilen / sizeof(int);
+
+	/* Global interrupt distribution server is specified in the last
+	 * entry of "ibm,ppc-interrupt-gserver#s" property. Get the last
+	 * entry fom this property for current boot cpu id and use it as
+	 * default distribution server
+	 */
+	for (j = 0; j < i; j += 2) {
+		if (ireg[j] == hcpuid) {
+			xics_default_distrib_server = ireg[j+1];
+			break;
+		}
+	}
+	pr_devel("xics: xics_default_distrib_server = 0x%x\n",
+		 xics_default_distrib_server);
+	of_node_put(np);
+}
+
+/* GIQ stuff, currently only supported on RTAS setups, will have
+ * to be sorted properly for bare metal
+ */
+void xics_set_cpu_giq(unsigned int gserver, unsigned int join)
+{
+#ifdef CONFIG_PPC_RTAS
+	int index;
+	int status;
+
+	if (!rtas_indicator_present(GLOBAL_INTERRUPT_QUEUE, NULL))
+		return;
+
+	index = (1UL << xics_interrupt_server_size) - 1 - gserver;
+
+	status = rtas_set_indicator_fast(GLOBAL_INTERRUPT_QUEUE, index, join);
+
+	WARN(status < 0, "set-indicator(%d, %d, %u) returned %d\n",
+	     GLOBAL_INTERRUPT_QUEUE, index, join, status);
+#endif
+}
+
+void xics_setup_cpu(void)
+{
+	icp_ops->set_priority(LOWEST_PRIORITY);
+
+	xics_set_cpu_giq(xics_default_distrib_server, 1);
+}
+
+void xics_mask_unknown_vec(unsigned int vec)
+{
+	struct ics *ics;
+
+	pr_err("Interrupt 0x%x (real) is invalid, disabling it.\n", vec);
+
+	list_for_each_entry(ics, &ics_list, link)
+		ics->mask_unknown(ics, vec);
+}
+
+
+#ifdef CONFIG_SMP
+
+static void xics_request_ipi(void)
+{
+	unsigned int ipi;
+
+	ipi = irq_create_mapping(xics_host, XICS_IPI);
+	BUG_ON(ipi == NO_IRQ);
+
+	/*
+	 * IPIs are marked IRQF_DISABLED as they must run with irqs
+	 * disabled, and PERCPU.  The handler was set in map.
+	 */
+	BUG_ON(request_irq(ipi, icp_ops->ipi_action,
+			   IRQF_DISABLED|IRQF_PERCPU, "IPI", NULL));
+}
+
+int __init xics_smp_probe(void)
+{
+	/* Setup cause_ipi callback  based on which ICP is used */
+	smp_ops->cause_ipi = icp_ops->cause_ipi;
+
+	/* Register all the IPIs */
+	xics_request_ipi();
+
+	return cpumask_weight(cpu_possible_mask);
+}
+
+#endif /* CONFIG_SMP */
+
+void xics_teardown_cpu(void)
+{
+	struct xics_cppr *os_cppr = &__get_cpu_var(xics_cppr);
+
+	/*
+	 * we have to reset the cppr index to 0 because we're
+	 * not going to return from the IPI
+	 */
+	os_cppr->index = 0;
+	icp_ops->set_priority(0);
+	icp_ops->teardown_cpu();
+}
+
+void xics_kexec_teardown_cpu(int secondary)
+{
+	xics_teardown_cpu();
+
+	icp_ops->flush_ipi();
+
+	/*
+	 * Some machines need to have at least one cpu in the GIQ,
+	 * so leave the master cpu in the group.
+	 */
+	if (secondary)
+		xics_set_cpu_giq(xics_default_distrib_server, 0);
+}
+
+
+#ifdef CONFIG_HOTPLUG_CPU
+
+/* Interrupts are disabled. */
+void xics_migrate_irqs_away(void)
+{
+	int cpu = smp_processor_id(), hw_cpu = hard_smp_processor_id();
+	unsigned int irq, virq;
+
+	/* If we used to be the default server, move to the new "boot_cpuid" */
+	if (hw_cpu == xics_default_server)
+		xics_update_irq_servers();
+
+	/* Reject any interrupt that was queued to us... */
+	icp_ops->set_priority(0);
+
+	/* Remove ourselves from the global interrupt queue */
+	xics_set_cpu_giq(xics_default_distrib_server, 0);
+
+	/* Allow IPIs again... */
+	icp_ops->set_priority(DEFAULT_PRIORITY);
+
+	for_each_irq(virq) {
+		struct irq_desc *desc;
+		struct irq_chip *chip;
+		long server;
+		unsigned long flags;
+		struct ics *ics;
+
+		/* We can't set affinity on ISA interrupts */
+		if (virq < NUM_ISA_INTERRUPTS)
+			continue;
+		if (!virq_is_host(virq, xics_host))
+			continue;
+		irq = (unsigned int)virq_to_hw(virq);
+		/* We need to get IPIs still. */
+		if (irq == XICS_IPI || irq == XICS_IRQ_SPURIOUS)
+			continue;
+		desc = irq_to_desc(virq);
+		/* We only need to migrate enabled IRQS */
+		if (!desc || !desc->action)
+			continue;
+		chip = irq_desc_get_chip(desc);
+		if (!chip || !chip->irq_set_affinity)
+			continue;
+
+		raw_spin_lock_irqsave(&desc->lock, flags);
+
+		/* Locate interrupt server */
+		server = -1;
+		ics = irq_get_chip_data(virq);
+		if (ics)
+			server = ics->get_server(ics, irq);
+		if (server < 0) {
+			printk(KERN_ERR "%s: Can't find server for irq %d\n",
+			       __func__, irq);
+			goto unlock;
+		}
+
+		/* We only support delivery to all cpus or to one cpu.
+		 * The irq has to be migrated only in the single cpu
+		 * case.
+		 */
+		if (server != hw_cpu)
+			goto unlock;
+
+		/* This is expected during cpu offline. */
+		if (cpu_online(cpu))
+			pr_warning("IRQ %u affinity broken off cpu %u\n",
+			       virq, cpu);
+
+		/* Reset affinity to all cpus */
+		raw_spin_unlock_irqrestore(&desc->lock, flags);
+		irq_set_affinity(virq, cpu_all_mask);
+		continue;
+unlock:
+		raw_spin_unlock_irqrestore(&desc->lock, flags);
+	}
+}
+#endif /* CONFIG_HOTPLUG_CPU */
+
+#ifdef CONFIG_SMP
+/*
+ * For the moment we only implement delivery to all cpus or one cpu.
+ *
+ * If the requested affinity is cpu_all_mask, we set global affinity.
+ * If not we set it to the first cpu in the mask, even if multiple cpus
+ * are set. This is so things like irqbalance (which set core and package
+ * wide affinities) do the right thing.
+ *
+ * We need to fix this to implement support for the links
+ */
+int xics_get_irq_server(unsigned int virq, const struct cpumask *cpumask,
+			unsigned int strict_check)
+{
+
+	if (!distribute_irqs)
+		return xics_default_server;
+
+	if (!cpumask_subset(cpu_possible_mask, cpumask)) {
+		int server = cpumask_first_and(cpu_online_mask, cpumask);
+
+		if (server < nr_cpu_ids)
+			return get_hard_smp_processor_id(server);
+
+		if (strict_check)
+			return -1;
+	}
+
+	/*
+	 * Workaround issue with some versions of JS20 firmware that
+	 * deliver interrupts to cpus which haven't been started. This
+	 * happens when using the maxcpus= boot option.
+	 */
+	if (cpumask_equal(cpu_online_mask, cpu_present_mask))
+		return xics_default_distrib_server;
+
+	return xics_default_server;
+}
+#endif /* CONFIG_SMP */
+
+static int xics_host_match(struct irq_host *h, struct device_node *node)
+{
+	struct ics *ics;
+
+	list_for_each_entry(ics, &ics_list, link)
+		if (ics->host_match(ics, node))
+			return 1;
+
+	return 0;
+}
+
+/* Dummies */
+static void xics_ipi_unmask(struct irq_data *d) { }
+static void xics_ipi_mask(struct irq_data *d) { }
+
+static struct irq_chip xics_ipi_chip = {
+	.name = "XICS",
+	.irq_eoi = NULL, /* Patched at init time */
+	.irq_mask = xics_ipi_mask,
+	.irq_unmask = xics_ipi_unmask,
+};
+
+static int xics_host_map(struct irq_host *h, unsigned int virq,
+			 irq_hw_number_t hw)
+{
+	struct ics *ics;
+
+	pr_devel("xics: map virq %d, hwirq 0x%lx\n", virq, hw);
+
+	/* Insert the interrupt mapping into the radix tree for fast lookup */
+	irq_radix_revmap_insert(xics_host, virq, hw);
+
+	/* They aren't all level sensitive but we just don't really know */
+	irq_set_status_flags(virq, IRQ_LEVEL);
+
+	/* Don't call into ICS for IPIs */
+	if (hw == XICS_IPI) {
+		irq_set_chip_and_handler(virq, &xics_ipi_chip,
+					 handle_percpu_irq);
+		return 0;
+	}
+
+	/* Let the ICS setup the chip data */
+	list_for_each_entry(ics, &ics_list, link)
+		if (ics->map(ics, virq) == 0)
+			return 0;
+
+	return -EINVAL;
+}
+
+static int xics_host_xlate(struct irq_host *h, struct device_node *ct,
+			   const u32 *intspec, unsigned int intsize,
+			   irq_hw_number_t *out_hwirq, unsigned int *out_flags)
+
+{
+	/* Current xics implementation translates everything
+	 * to level. It is not technically right for MSIs but this
+	 * is irrelevant at this point. We might get smarter in the future
+	 */
+	*out_hwirq = intspec[0];
+	*out_flags = IRQ_TYPE_LEVEL_LOW;
+
+	return 0;
+}
+
+static struct irq_host_ops xics_host_ops = {
+	.match = xics_host_match,
+	.map = xics_host_map,
+	.xlate = xics_host_xlate,
+};
+
+static void __init xics_init_host(void)
+{
+	xics_host = irq_alloc_host(NULL, IRQ_HOST_MAP_TREE, 0, &xics_host_ops,
+				   XICS_IRQ_SPURIOUS);
+	BUG_ON(xics_host == NULL);
+	irq_set_default_host(xics_host);
+}
+
+void __init xics_register_ics(struct ics *ics)
+{
+	list_add(&ics->link, &ics_list);
+}
+
+static void __init xics_get_server_size(void)
+{
+	struct device_node *np;
+	const u32 *isize;
+
+	/* We fetch the interrupt server size from the first ICS node
+	 * we find if any
+	 */
+	np = of_find_compatible_node(NULL, NULL, "ibm,ppc-xics");
+	if (!np)
+		return;
+	isize = of_get_property(np, "ibm,interrupt-server#-size", NULL);
+	if (!isize)
+		return;
+	xics_interrupt_server_size = *isize;
+	of_node_put(np);
+}
+
+void __init xics_init(void)
+{
+	int rc = -1;
+
+	/* Fist locate ICP */
+#ifdef CONFIG_PPC_ICP_HV
+	if (firmware_has_feature(FW_FEATURE_LPAR))
+		rc = icp_hv_init();
+#endif
+#ifdef CONFIG_PPC_ICP_NATIVE
+	if (rc < 0)
+		rc = icp_native_init();
+#endif
+	if (rc < 0) {
+		pr_warning("XICS: Cannot find a Presentation Controller !\n");
+		return;
+	}
+
+	/* Copy get_irq callback over to ppc_md */
+	ppc_md.get_irq = icp_ops->get_irq;
+
+	/* Patch up IPI chip EOI */
+	xics_ipi_chip.irq_eoi = icp_ops->eoi;
+
+	/* Now locate ICS */
+#ifdef CONFIG_PPC_ICS_RTAS
+	rc = ics_rtas_init();
+#endif
+	if (rc < 0)
+		pr_warning("XICS: Cannot find a Source Controller !\n");
+
+	/* Initialize common bits */
+	xics_get_server_size();
+	xics_update_irq_servers();
+	xics_init_host();
+	xics_setup_cpu();
+}
diff -druN linux-2.6.39-libre/arch/powerpc/sysdev/xilinx_intc.c linux-3.0-rc7-libre/arch/powerpc/sysdev/xilinx_intc.c
--- linux-2.6.39-libre/arch/powerpc/sysdev/xilinx_intc.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/sysdev/xilinx_intc.c	2011-07-11 19:51:52.000000000 -0400
@@ -71,7 +71,7 @@
  */
 static void xilinx_intc_mask(struct irq_data *d)
 {
-	int irq = virq_to_hw(d->irq);
+	int irq = irqd_to_hwirq(d);
 	void * regs = irq_data_get_irq_chip_data(d);
 	pr_debug("mask: %d\n", irq);
 	out_be32(regs + XINTC_CIE, 1 << irq);
@@ -87,7 +87,7 @@
  */
 static void xilinx_intc_level_unmask(struct irq_data *d)
 {
-	int irq = virq_to_hw(d->irq);
+	int irq = irqd_to_hwirq(d);
 	void * regs = irq_data_get_irq_chip_data(d);
 	pr_debug("unmask: %d\n", irq);
 	out_be32(regs + XINTC_SIE, 1 << irq);
@@ -112,7 +112,7 @@
  */
 static void xilinx_intc_edge_unmask(struct irq_data *d)
 {
-	int irq = virq_to_hw(d->irq);
+	int irq = irqd_to_hwirq(d);
 	void *regs = irq_data_get_irq_chip_data(d);
 	pr_debug("unmask: %d\n", irq);
 	out_be32(regs + XINTC_SIE, 1 << irq);
@@ -120,7 +120,7 @@
 
 static void xilinx_intc_edge_ack(struct irq_data *d)
 {
-	int irq = virq_to_hw(d->irq);
+	int irq = irqd_to_hwirq(d);
 	void * regs = irq_data_get_irq_chip_data(d);
 	pr_debug("ack: %d\n", irq);
 	out_be32(regs + XINTC_IAR, 1 << irq);
diff -druN linux-2.6.39-libre/arch/powerpc/xmon/xmon.c linux-3.0-rc7-libre/arch/powerpc/xmon/xmon.c
--- linux-2.6.39-libre/arch/powerpc/xmon/xmon.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/powerpc/xmon/xmon.c	2011-07-11 19:51:52.000000000 -0400
@@ -334,7 +334,7 @@
 
 int cpus_are_in_xmon(void)
 {
-	return !cpus_empty(cpus_in_xmon);
+	return !cpumask_empty(&cpus_in_xmon);
 }
 #endif
 
@@ -373,7 +373,7 @@
 
 #ifdef CONFIG_SMP
 	cpu = smp_processor_id();
-	if (cpu_isset(cpu, cpus_in_xmon)) {
+	if (cpumask_test_cpu(cpu, &cpus_in_xmon)) {
 		get_output_lock();
 		excprint(regs);
 		printf("cpu 0x%x: Exception %lx %s in xmon, "
@@ -396,10 +396,10 @@
 	}
 
 	xmon_fault_jmp[cpu] = recurse_jmp;
-	cpu_set(cpu, cpus_in_xmon);
+	cpumask_set_cpu(cpu, &cpus_in_xmon);
 
 	bp = NULL;
-	if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) == (MSR_IR|MSR_SF))
+	if ((regs->msr & (MSR_IR|MSR_PR|MSR_64BIT)) == (MSR_IR|MSR_64BIT))
 		bp = at_breakpoint(regs->nip);
 	if (bp || unrecoverable_excp(regs))
 		fromipi = 0;
@@ -437,10 +437,10 @@
 		xmon_owner = cpu;
 		mb();
 		if (ncpus > 1) {
-			smp_send_debugger_break(MSG_ALL_BUT_SELF);
+			smp_send_debugger_break();
 			/* wait for other cpus to come in */
 			for (timeout = 100000000; timeout != 0; --timeout) {
-				if (cpus_weight(cpus_in_xmon) >= ncpus)
+				if (cpumask_weight(&cpus_in_xmon) >= ncpus)
 					break;
 				barrier();
 			}
@@ -484,7 +484,7 @@
 		}
 	}
  leave:
-	cpu_clear(cpu, cpus_in_xmon);
+	cpumask_clear_cpu(cpu, &cpus_in_xmon);
 	xmon_fault_jmp[cpu] = NULL;
 #else
 	/* UP is simple... */
@@ -529,7 +529,7 @@
 		}
 	}
 #else
-	if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) == (MSR_IR|MSR_SF)) {
+	if ((regs->msr & (MSR_IR|MSR_PR|MSR_64BIT)) == (MSR_IR|MSR_64BIT)) {
 		bp = at_breakpoint(regs->nip);
 		if (bp != NULL) {
 			int stepped = emulate_step(regs, bp->instr[0]);
@@ -578,7 +578,7 @@
 	struct bpt *bp;
 	unsigned long offset;
 
-	if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) != (MSR_IR|MSR_SF))
+	if ((regs->msr & (MSR_IR|MSR_PR|MSR_64BIT)) != (MSR_IR|MSR_64BIT))
 		return 0;
 
 	/* Are we at the trap at bp->instr[1] for some bp? */
@@ -609,7 +609,7 @@
 
 static int xmon_dabr_match(struct pt_regs *regs)
 {
-	if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) != (MSR_IR|MSR_SF))
+	if ((regs->msr & (MSR_IR|MSR_PR|MSR_64BIT)) != (MSR_IR|MSR_64BIT))
 		return 0;
 	if (dabr.enabled == 0)
 		return 0;
@@ -619,7 +619,7 @@
 
 static int xmon_iabr_match(struct pt_regs *regs)
 {
-	if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) != (MSR_IR|MSR_SF))
+	if ((regs->msr & (MSR_IR|MSR_PR|MSR_64BIT)) != (MSR_IR|MSR_64BIT))
 		return 0;
 	if (iabr == NULL)
 		return 0;
@@ -630,7 +630,7 @@
 static int xmon_ipi(struct pt_regs *regs)
 {
 #ifdef CONFIG_SMP
-	if (in_xmon && !cpu_isset(smp_processor_id(), cpus_in_xmon))
+	if (in_xmon && !cpumask_test_cpu(smp_processor_id(), &cpus_in_xmon))
 		xmon_core(regs, 1);
 #endif
 	return 0;
@@ -644,7 +644,7 @@
 	if (in_xmon && catch_memory_errors)
 		handle_fault(regs);	/* doesn't return */
 
-	if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) == (MSR_IR|MSR_SF)) {
+	if ((regs->msr & (MSR_IR|MSR_PR|MSR_64BIT)) == (MSR_IR|MSR_64BIT)) {
 		bp = in_breakpoint_table(regs->nip, &offset);
 		if (bp != NULL) {
 			regs->nip = bp->address + offset;
@@ -929,7 +929,7 @@
 	int stepped;
 
 	/* check we are in 64-bit kernel mode, translation enabled */
-	if ((regs->msr & (MSR_SF|MSR_PR|MSR_IR)) == (MSR_SF|MSR_IR)) {
+	if ((regs->msr & (MSR_64BIT|MSR_PR|MSR_IR)) == (MSR_64BIT|MSR_IR)) {
 		if (mread(regs->nip, &instr, 4) == 4) {
 			stepped = emulate_step(regs, instr);
 			if (stepped < 0) {
@@ -976,7 +976,7 @@
 		printf("cpus stopped:");
 		count = 0;
 		for (cpu = 0; cpu < NR_CPUS; ++cpu) {
-			if (cpu_isset(cpu, cpus_in_xmon)) {
+			if (cpumask_test_cpu(cpu, &cpus_in_xmon)) {
 				if (count == 0)
 					printf(" %x", cpu);
 				++count;
@@ -992,7 +992,7 @@
 		return 0;
 	}
 	/* try to switch to cpu specified */
-	if (!cpu_isset(cpu, cpus_in_xmon)) {
+	if (!cpumask_test_cpu(cpu, &cpus_in_xmon)) {
 		printf("cpu 0x%x isn't in xmon\n", cpu);
 		return 0;
 	}
@@ -1497,6 +1497,10 @@
 #endif
 	printf("pc  = ");
 	xmon_print_symbol(fp->nip, " ", "\n");
+	if (TRAP(fp) != 0xc00 && cpu_has_feature(CPU_FTR_CFAR)) {
+		printf("cfar= ");
+		xmon_print_symbol(fp->orig_gpr3, " ", "\n");
+	}
 	printf("lr  = ");
 	xmon_print_symbol(fp->link, " ", "\n");
 	printf("msr = "REG"   cr  = %.8lx\n", fp->msr, fp->ccr);
@@ -2663,7 +2667,7 @@
 
 void dump_segments(void)
 {
-	if (cpu_has_feature(CPU_FTR_SLB))
+	if (mmu_has_feature(MMU_FTR_SLB))
 		dump_slb();
 	else
 		dump_stab();
diff -druN linux-2.6.39-libre/arch/s390/appldata/appldata_base.c linux-3.0-rc7-libre/arch/s390/appldata/appldata_base.c
--- linux-2.6.39-libre/arch/s390/appldata/appldata_base.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/s390/appldata/appldata_base.c	2011-07-11 19:51:52.000000000 -0400
@@ -130,9 +130,7 @@
 {
 	struct list_head *lh;
 	struct appldata_ops *ops;
-	int i;
 
-	i = 0;
 	get_online_cpus();
 	mutex_lock(&appldata_ops_mutex);
 	list_for_each(lh, &appldata_ops_list) {
diff -druN linux-2.6.39-libre/arch/s390/appldata/appldata_mem.c linux-3.0-rc7-libre/arch/s390/appldata/appldata_mem.c
--- linux-2.6.39-libre/arch/s390/appldata/appldata_mem.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/s390/appldata/appldata_mem.c	2011-07-11 19:51:52.000000000 -0400
@@ -92,9 +92,7 @@
 	mem_data->pswpin     = ev[PSWPIN];
 	mem_data->pswpout    = ev[PSWPOUT];
 	mem_data->pgalloc    = ev[PGALLOC_NORMAL];
-#ifdef CONFIG_ZONE_DMA
 	mem_data->pgalloc    += ev[PGALLOC_DMA];
-#endif
 	mem_data->pgfault    = ev[PGFAULT];
 	mem_data->pgmajfault = ev[PGMAJFAULT];
 
diff -druN linux-2.6.39-libre/arch/s390/crypto/aes_s390.c linux-3.0-rc7-libre/arch/s390/crypto/aes_s390.c
--- linux-2.6.39-libre/arch/s390/crypto/aes_s390.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/s390/crypto/aes_s390.c	2011-07-11 19:51:52.000000000 -0400
@@ -31,7 +31,8 @@
 #define AES_KEYLEN_192		2
 #define AES_KEYLEN_256		4
 
-static char keylen_flag = 0;
+static u8 *ctrblk;
+static char keylen_flag;
 
 struct s390_aes_ctx {
 	u8 iv[AES_BLOCK_SIZE];
@@ -45,6 +46,24 @@
 	} fallback;
 };
 
+struct pcc_param {
+	u8 key[32];
+	u8 tweak[16];
+	u8 block[16];
+	u8 bit[16];
+	u8 xts[16];
+};
+
+struct s390_xts_ctx {
+	u8 key[32];
+	u8 xts_param[16];
+	struct pcc_param pcc;
+	long enc;
+	long dec;
+	int key_len;
+	struct crypto_blkcipher *fallback;
+};
+
 /*
  * Check if the key_len is supported by the HW.
  * Returns 0 if it is, a positive number if it is not and software fallback is
@@ -504,15 +523,337 @@
 	}
 };
 
+static int xts_fallback_setkey(struct crypto_tfm *tfm, const u8 *key,
+				   unsigned int len)
+{
+	struct s390_xts_ctx *xts_ctx = crypto_tfm_ctx(tfm);
+	unsigned int ret;
+
+	xts_ctx->fallback->base.crt_flags &= ~CRYPTO_TFM_REQ_MASK;
+	xts_ctx->fallback->base.crt_flags |= (tfm->crt_flags &
+			CRYPTO_TFM_REQ_MASK);
+
+	ret = crypto_blkcipher_setkey(xts_ctx->fallback, key, len);
+	if (ret) {
+		tfm->crt_flags &= ~CRYPTO_TFM_RES_MASK;
+		tfm->crt_flags |= (xts_ctx->fallback->base.crt_flags &
+				CRYPTO_TFM_RES_MASK);
+	}
+	return ret;
+}
+
+static int xts_fallback_decrypt(struct blkcipher_desc *desc,
+		struct scatterlist *dst, struct scatterlist *src,
+		unsigned int nbytes)
+{
+	struct s390_xts_ctx *xts_ctx = crypto_blkcipher_ctx(desc->tfm);
+	struct crypto_blkcipher *tfm;
+	unsigned int ret;
+
+	tfm = desc->tfm;
+	desc->tfm = xts_ctx->fallback;
+
+	ret = crypto_blkcipher_decrypt_iv(desc, dst, src, nbytes);
+
+	desc->tfm = tfm;
+	return ret;
+}
+
+static int xts_fallback_encrypt(struct blkcipher_desc *desc,
+		struct scatterlist *dst, struct scatterlist *src,
+		unsigned int nbytes)
+{
+	struct s390_xts_ctx *xts_ctx = crypto_blkcipher_ctx(desc->tfm);
+	struct crypto_blkcipher *tfm;
+	unsigned int ret;
+
+	tfm = desc->tfm;
+	desc->tfm = xts_ctx->fallback;
+
+	ret = crypto_blkcipher_encrypt_iv(desc, dst, src, nbytes);
+
+	desc->tfm = tfm;
+	return ret;
+}
+
+static int xts_aes_set_key(struct crypto_tfm *tfm, const u8 *in_key,
+			   unsigned int key_len)
+{
+	struct s390_xts_ctx *xts_ctx = crypto_tfm_ctx(tfm);
+	u32 *flags = &tfm->crt_flags;
+
+	switch (key_len) {
+	case 32:
+		xts_ctx->enc = KM_XTS_128_ENCRYPT;
+		xts_ctx->dec = KM_XTS_128_DECRYPT;
+		memcpy(xts_ctx->key + 16, in_key, 16);
+		memcpy(xts_ctx->pcc.key + 16, in_key + 16, 16);
+		break;
+	case 48:
+		xts_ctx->enc = 0;
+		xts_ctx->dec = 0;
+		xts_fallback_setkey(tfm, in_key, key_len);
+		break;
+	case 64:
+		xts_ctx->enc = KM_XTS_256_ENCRYPT;
+		xts_ctx->dec = KM_XTS_256_DECRYPT;
+		memcpy(xts_ctx->key, in_key, 32);
+		memcpy(xts_ctx->pcc.key, in_key + 32, 32);
+		break;
+	default:
+		*flags |= CRYPTO_TFM_RES_BAD_KEY_LEN;
+		return -EINVAL;
+	}
+	xts_ctx->key_len = key_len;
+	return 0;
+}
+
+static int xts_aes_crypt(struct blkcipher_desc *desc, long func,
+			 struct s390_xts_ctx *xts_ctx,
+			 struct blkcipher_walk *walk)
+{
+	unsigned int offset = (xts_ctx->key_len >> 1) & 0x10;
+	int ret = blkcipher_walk_virt(desc, walk);
+	unsigned int nbytes = walk->nbytes;
+	unsigned int n;
+	u8 *in, *out;
+	void *param;
+
+	if (!nbytes)
+		goto out;
+
+	memset(xts_ctx->pcc.block, 0, sizeof(xts_ctx->pcc.block));
+	memset(xts_ctx->pcc.bit, 0, sizeof(xts_ctx->pcc.bit));
+	memset(xts_ctx->pcc.xts, 0, sizeof(xts_ctx->pcc.xts));
+	memcpy(xts_ctx->pcc.tweak, walk->iv, sizeof(xts_ctx->pcc.tweak));
+	param = xts_ctx->pcc.key + offset;
+	ret = crypt_s390_pcc(func, param);
+	BUG_ON(ret < 0);
+
+	memcpy(xts_ctx->xts_param, xts_ctx->pcc.xts, 16);
+	param = xts_ctx->key + offset;
+	do {
+		/* only use complete blocks */
+		n = nbytes & ~(AES_BLOCK_SIZE - 1);
+		out = walk->dst.virt.addr;
+		in = walk->src.virt.addr;
+
+		ret = crypt_s390_km(func, param, out, in, n);
+		BUG_ON(ret < 0 || ret != n);
+
+		nbytes &= AES_BLOCK_SIZE - 1;
+		ret = blkcipher_walk_done(desc, walk, nbytes);
+	} while ((nbytes = walk->nbytes));
+out:
+	return ret;
+}
+
+static int xts_aes_encrypt(struct blkcipher_desc *desc,
+			   struct scatterlist *dst, struct scatterlist *src,
+			   unsigned int nbytes)
+{
+	struct s390_xts_ctx *xts_ctx = crypto_blkcipher_ctx(desc->tfm);
+	struct blkcipher_walk walk;
+
+	if (unlikely(xts_ctx->key_len == 48))
+		return xts_fallback_encrypt(desc, dst, src, nbytes);
+
+	blkcipher_walk_init(&walk, dst, src, nbytes);
+	return xts_aes_crypt(desc, xts_ctx->enc, xts_ctx, &walk);
+}
+
+static int xts_aes_decrypt(struct blkcipher_desc *desc,
+			   struct scatterlist *dst, struct scatterlist *src,
+			   unsigned int nbytes)
+{
+	struct s390_xts_ctx *xts_ctx = crypto_blkcipher_ctx(desc->tfm);
+	struct blkcipher_walk walk;
+
+	if (unlikely(xts_ctx->key_len == 48))
+		return xts_fallback_decrypt(desc, dst, src, nbytes);
+
+	blkcipher_walk_init(&walk, dst, src, nbytes);
+	return xts_aes_crypt(desc, xts_ctx->dec, xts_ctx, &walk);
+}
+
+static int xts_fallback_init(struct crypto_tfm *tfm)
+{
+	const char *name = tfm->__crt_alg->cra_name;
+	struct s390_xts_ctx *xts_ctx = crypto_tfm_ctx(tfm);
+
+	xts_ctx->fallback = crypto_alloc_blkcipher(name, 0,
+			CRYPTO_ALG_ASYNC | CRYPTO_ALG_NEED_FALLBACK);
+
+	if (IS_ERR(xts_ctx->fallback)) {
+		pr_err("Allocating XTS fallback algorithm %s failed\n",
+		       name);
+		return PTR_ERR(xts_ctx->fallback);
+	}
+	return 0;
+}
+
+static void xts_fallback_exit(struct crypto_tfm *tfm)
+{
+	struct s390_xts_ctx *xts_ctx = crypto_tfm_ctx(tfm);
+
+	crypto_free_blkcipher(xts_ctx->fallback);
+	xts_ctx->fallback = NULL;
+}
+
+static struct crypto_alg xts_aes_alg = {
+	.cra_name		=	"xts(aes)",
+	.cra_driver_name	=	"xts-aes-s390",
+	.cra_priority		=	CRYPT_S390_COMPOSITE_PRIORITY,
+	.cra_flags		=	CRYPTO_ALG_TYPE_BLKCIPHER |
+					CRYPTO_ALG_NEED_FALLBACK,
+	.cra_blocksize		=	AES_BLOCK_SIZE,
+	.cra_ctxsize		=	sizeof(struct s390_xts_ctx),
+	.cra_type		=	&crypto_blkcipher_type,
+	.cra_module		=	THIS_MODULE,
+	.cra_list		=	LIST_HEAD_INIT(xts_aes_alg.cra_list),
+	.cra_init		=	xts_fallback_init,
+	.cra_exit		=	xts_fallback_exit,
+	.cra_u			=	{
+		.blkcipher = {
+			.min_keysize		=	2 * AES_MIN_KEY_SIZE,
+			.max_keysize		=	2 * AES_MAX_KEY_SIZE,
+			.ivsize			=	AES_BLOCK_SIZE,
+			.setkey			=	xts_aes_set_key,
+			.encrypt		=	xts_aes_encrypt,
+			.decrypt		=	xts_aes_decrypt,
+		}
+	}
+};
+
+static int ctr_aes_set_key(struct crypto_tfm *tfm, const u8 *in_key,
+			   unsigned int key_len)
+{
+	struct s390_aes_ctx *sctx = crypto_tfm_ctx(tfm);
+
+	switch (key_len) {
+	case 16:
+		sctx->enc = KMCTR_AES_128_ENCRYPT;
+		sctx->dec = KMCTR_AES_128_DECRYPT;
+		break;
+	case 24:
+		sctx->enc = KMCTR_AES_192_ENCRYPT;
+		sctx->dec = KMCTR_AES_192_DECRYPT;
+		break;
+	case 32:
+		sctx->enc = KMCTR_AES_256_ENCRYPT;
+		sctx->dec = KMCTR_AES_256_DECRYPT;
+		break;
+	}
+
+	return aes_set_key(tfm, in_key, key_len);
+}
+
+static int ctr_aes_crypt(struct blkcipher_desc *desc, long func,
+			 struct s390_aes_ctx *sctx, struct blkcipher_walk *walk)
+{
+	int ret = blkcipher_walk_virt_block(desc, walk, AES_BLOCK_SIZE);
+	unsigned int i, n, nbytes;
+	u8 buf[AES_BLOCK_SIZE];
+	u8 *out, *in;
+
+	if (!walk->nbytes)
+		return ret;
+
+	memcpy(ctrblk, walk->iv, AES_BLOCK_SIZE);
+	while ((nbytes = walk->nbytes) >= AES_BLOCK_SIZE) {
+		out = walk->dst.virt.addr;
+		in = walk->src.virt.addr;
+		while (nbytes >= AES_BLOCK_SIZE) {
+			/* only use complete blocks, max. PAGE_SIZE */
+			n = (nbytes > PAGE_SIZE) ? PAGE_SIZE :
+						 nbytes & ~(AES_BLOCK_SIZE - 1);
+			for (i = AES_BLOCK_SIZE; i < n; i += AES_BLOCK_SIZE) {
+				memcpy(ctrblk + i, ctrblk + i - AES_BLOCK_SIZE,
+				       AES_BLOCK_SIZE);
+				crypto_inc(ctrblk + i, AES_BLOCK_SIZE);
+			}
+			ret = crypt_s390_kmctr(func, sctx->key, out, in, n, ctrblk);
+			BUG_ON(ret < 0 || ret != n);
+			if (n > AES_BLOCK_SIZE)
+				memcpy(ctrblk, ctrblk + n - AES_BLOCK_SIZE,
+				       AES_BLOCK_SIZE);
+			crypto_inc(ctrblk, AES_BLOCK_SIZE);
+			out += n;
+			in += n;
+			nbytes -= n;
+		}
+		ret = blkcipher_walk_done(desc, walk, nbytes);
+	}
+	/*
+	 * final block may be < AES_BLOCK_SIZE, copy only nbytes
+	 */
+	if (nbytes) {
+		out = walk->dst.virt.addr;
+		in = walk->src.virt.addr;
+		ret = crypt_s390_kmctr(func, sctx->key, buf, in,
+				       AES_BLOCK_SIZE, ctrblk);
+		BUG_ON(ret < 0 || ret != AES_BLOCK_SIZE);
+		memcpy(out, buf, nbytes);
+		crypto_inc(ctrblk, AES_BLOCK_SIZE);
+		ret = blkcipher_walk_done(desc, walk, 0);
+	}
+	memcpy(walk->iv, ctrblk, AES_BLOCK_SIZE);
+	return ret;
+}
+
+static int ctr_aes_encrypt(struct blkcipher_desc *desc,
+			   struct scatterlist *dst, struct scatterlist *src,
+			   unsigned int nbytes)
+{
+	struct s390_aes_ctx *sctx = crypto_blkcipher_ctx(desc->tfm);
+	struct blkcipher_walk walk;
+
+	blkcipher_walk_init(&walk, dst, src, nbytes);
+	return ctr_aes_crypt(desc, sctx->enc, sctx, &walk);
+}
+
+static int ctr_aes_decrypt(struct blkcipher_desc *desc,
+			   struct scatterlist *dst, struct scatterlist *src,
+			   unsigned int nbytes)
+{
+	struct s390_aes_ctx *sctx = crypto_blkcipher_ctx(desc->tfm);
+	struct blkcipher_walk walk;
+
+	blkcipher_walk_init(&walk, dst, src, nbytes);
+	return ctr_aes_crypt(desc, sctx->dec, sctx, &walk);
+}
+
+static struct crypto_alg ctr_aes_alg = {
+	.cra_name		=	"ctr(aes)",
+	.cra_driver_name	=	"ctr-aes-s390",
+	.cra_priority		=	CRYPT_S390_COMPOSITE_PRIORITY,
+	.cra_flags		=	CRYPTO_ALG_TYPE_BLKCIPHER,
+	.cra_blocksize		=	1,
+	.cra_ctxsize		=	sizeof(struct s390_aes_ctx),
+	.cra_type		=	&crypto_blkcipher_type,
+	.cra_module		=	THIS_MODULE,
+	.cra_list		=	LIST_HEAD_INIT(ctr_aes_alg.cra_list),
+	.cra_u			=	{
+		.blkcipher = {
+			.min_keysize		=	AES_MIN_KEY_SIZE,
+			.max_keysize		=	AES_MAX_KEY_SIZE,
+			.ivsize			=	AES_BLOCK_SIZE,
+			.setkey			=	ctr_aes_set_key,
+			.encrypt		=	ctr_aes_encrypt,
+			.decrypt		=	ctr_aes_decrypt,
+		}
+	}
+};
+
 static int __init aes_s390_init(void)
 {
 	int ret;
 
-	if (crypt_s390_func_available(KM_AES_128_ENCRYPT))
+	if (crypt_s390_func_available(KM_AES_128_ENCRYPT, CRYPT_S390_MSA))
 		keylen_flag |= AES_KEYLEN_128;
-	if (crypt_s390_func_available(KM_AES_192_ENCRYPT))
+	if (crypt_s390_func_available(KM_AES_192_ENCRYPT, CRYPT_S390_MSA))
 		keylen_flag |= AES_KEYLEN_192;
-	if (crypt_s390_func_available(KM_AES_256_ENCRYPT))
+	if (crypt_s390_func_available(KM_AES_256_ENCRYPT, CRYPT_S390_MSA))
 		keylen_flag |= AES_KEYLEN_256;
 
 	if (!keylen_flag)
@@ -535,9 +876,40 @@
 	if (ret)
 		goto cbc_aes_err;
 
+	if (crypt_s390_func_available(KM_XTS_128_ENCRYPT,
+			CRYPT_S390_MSA | CRYPT_S390_MSA4) &&
+	    crypt_s390_func_available(KM_XTS_256_ENCRYPT,
+			CRYPT_S390_MSA | CRYPT_S390_MSA4)) {
+		ret = crypto_register_alg(&xts_aes_alg);
+		if (ret)
+			goto xts_aes_err;
+	}
+
+	if (crypt_s390_func_available(KMCTR_AES_128_ENCRYPT,
+				CRYPT_S390_MSA | CRYPT_S390_MSA4) &&
+	    crypt_s390_func_available(KMCTR_AES_192_ENCRYPT,
+				CRYPT_S390_MSA | CRYPT_S390_MSA4) &&
+	    crypt_s390_func_available(KMCTR_AES_256_ENCRYPT,
+				CRYPT_S390_MSA | CRYPT_S390_MSA4)) {
+		ctrblk = (u8 *) __get_free_page(GFP_KERNEL);
+		if (!ctrblk) {
+			ret = -ENOMEM;
+			goto ctr_aes_err;
+		}
+		ret = crypto_register_alg(&ctr_aes_alg);
+		if (ret) {
+			free_page((unsigned long) ctrblk);
+			goto ctr_aes_err;
+		}
+	}
+
 out:
 	return ret;
 
+ctr_aes_err:
+	crypto_unregister_alg(&xts_aes_alg);
+xts_aes_err:
+	crypto_unregister_alg(&cbc_aes_alg);
 cbc_aes_err:
 	crypto_unregister_alg(&ecb_aes_alg);
 ecb_aes_err:
@@ -548,6 +920,9 @@
 
 static void __exit aes_s390_fini(void)
 {
+	crypto_unregister_alg(&ctr_aes_alg);
+	free_page((unsigned long) ctrblk);
+	crypto_unregister_alg(&xts_aes_alg);
 	crypto_unregister_alg(&cbc_aes_alg);
 	crypto_unregister_alg(&ecb_aes_alg);
 	crypto_unregister_alg(&aes_alg);
diff -druN linux-2.6.39-libre/arch/s390/crypto/crypt_s390.h linux-3.0-rc7-libre/arch/s390/crypto/crypt_s390.h
--- linux-2.6.39-libre/arch/s390/crypto/crypt_s390.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/s390/crypto/crypt_s390.h	2011-07-11 19:51:52.000000000 -0400
@@ -24,13 +24,18 @@
 #define CRYPT_S390_PRIORITY 300
 #define CRYPT_S390_COMPOSITE_PRIORITY 400
 
+#define CRYPT_S390_MSA	0x1
+#define CRYPT_S390_MSA3	0x2
+#define CRYPT_S390_MSA4	0x4
+
 /* s390 cryptographic operations */
 enum crypt_s390_operations {
 	CRYPT_S390_KM   = 0x0100,
 	CRYPT_S390_KMC  = 0x0200,
 	CRYPT_S390_KIMD = 0x0300,
 	CRYPT_S390_KLMD = 0x0400,
-	CRYPT_S390_KMAC = 0x0500
+	CRYPT_S390_KMAC = 0x0500,
+	CRYPT_S390_KMCTR = 0x0600
 };
 
 /*
@@ -51,6 +56,10 @@
 	KM_AES_192_DECRYPT  = CRYPT_S390_KM | 0x13 | 0x80,
 	KM_AES_256_ENCRYPT  = CRYPT_S390_KM | 0x14,
 	KM_AES_256_DECRYPT  = CRYPT_S390_KM | 0x14 | 0x80,
+	KM_XTS_128_ENCRYPT  = CRYPT_S390_KM | 0x32,
+	KM_XTS_128_DECRYPT  = CRYPT_S390_KM | 0x32 | 0x80,
+	KM_XTS_256_ENCRYPT  = CRYPT_S390_KM | 0x34,
+	KM_XTS_256_DECRYPT  = CRYPT_S390_KM | 0x34 | 0x80,
 };
 
 /*
@@ -75,6 +84,26 @@
 };
 
 /*
+ * function codes for KMCTR (CIPHER MESSAGE WITH COUNTER)
+ * instruction
+ */
+enum crypt_s390_kmctr_func {
+	KMCTR_QUERY            = CRYPT_S390_KMCTR | 0x0,
+	KMCTR_DEA_ENCRYPT      = CRYPT_S390_KMCTR | 0x1,
+	KMCTR_DEA_DECRYPT      = CRYPT_S390_KMCTR | 0x1 | 0x80,
+	KMCTR_TDEA_128_ENCRYPT = CRYPT_S390_KMCTR | 0x2,
+	KMCTR_TDEA_128_DECRYPT = CRYPT_S390_KMCTR | 0x2 | 0x80,
+	KMCTR_TDEA_192_ENCRYPT = CRYPT_S390_KMCTR | 0x3,
+	KMCTR_TDEA_192_DECRYPT = CRYPT_S390_KMCTR | 0x3 | 0x80,
+	KMCTR_AES_128_ENCRYPT  = CRYPT_S390_KMCTR | 0x12,
+	KMCTR_AES_128_DECRYPT  = CRYPT_S390_KMCTR | 0x12 | 0x80,
+	KMCTR_AES_192_ENCRYPT  = CRYPT_S390_KMCTR | 0x13,
+	KMCTR_AES_192_DECRYPT  = CRYPT_S390_KMCTR | 0x13 | 0x80,
+	KMCTR_AES_256_ENCRYPT  = CRYPT_S390_KMCTR | 0x14,
+	KMCTR_AES_256_DECRYPT  = CRYPT_S390_KMCTR | 0x14 | 0x80,
+};
+
+/*
  * function codes for KIMD (COMPUTE INTERMEDIATE MESSAGE DIGEST)
  * instruction
  */
@@ -83,6 +112,7 @@
 	KIMD_SHA_1   = CRYPT_S390_KIMD | 1,
 	KIMD_SHA_256 = CRYPT_S390_KIMD | 2,
 	KIMD_SHA_512 = CRYPT_S390_KIMD | 3,
+	KIMD_GHASH   = CRYPT_S390_KIMD | 65,
 };
 
 /*
@@ -284,6 +314,45 @@
 }
 
 /**
+ * crypt_s390_kmctr:
+ * @func: the function code passed to KMCTR; see crypt_s390_kmctr_func
+ * @param: address of parameter block; see POP for details on each func
+ * @dest: address of destination memory area
+ * @src: address of source memory area
+ * @src_len: length of src operand in bytes
+ * @counter: address of counter value
+ *
+ * Executes the KMCTR (CIPHER MESSAGE WITH COUNTER) operation of the CPU.
+ *
+ * Returns -1 for failure, 0 for the query func, number of processed
+ * bytes for encryption/decryption funcs
+ */
+static inline int crypt_s390_kmctr(long func, void *param, u8 *dest,
+				 const u8 *src, long src_len, u8 *counter)
+{
+	register long __func asm("0") = func & CRYPT_S390_FUNC_MASK;
+	register void *__param asm("1") = param;
+	register const u8 *__src asm("2") = src;
+	register long __src_len asm("3") = src_len;
+	register u8 *__dest asm("4") = dest;
+	register u8 *__ctr asm("6") = counter;
+	int ret = -1;
+
+	asm volatile(
+		"0:	.insn	rrf,0xb92d0000,%3,%1,%4,0 \n" /* KMCTR opcode */
+		"1:	brc	1,0b \n" /* handle partial completion */
+		"	la	%0,0\n"
+		"2:\n"
+		EX_TABLE(0b,2b) EX_TABLE(1b,2b)
+		: "+d" (ret), "+a" (__src), "+d" (__src_len), "+a" (__dest),
+		  "+a" (__ctr)
+		: "d" (__func), "a" (__param) : "cc", "memory");
+	if (ret < 0)
+		return ret;
+	return (func & CRYPT_S390_FUNC_MASK) ? src_len - __src_len : __src_len;
+}
+
+/**
  * crypt_s390_func_available:
  * @func: the function code of the specific function; 0 if op in general
  *
@@ -291,13 +360,17 @@
  *
  * Returns 1 if func available; 0 if func or op in general not available
  */
-static inline int crypt_s390_func_available(int func)
+static inline int crypt_s390_func_available(int func,
+					    unsigned int facility_mask)
 {
 	unsigned char status[16];
 	int ret;
 
-	/* check if CPACF facility (bit 17) is available */
-	if (!test_facility(17))
+	if (facility_mask & CRYPT_S390_MSA && !test_facility(17))
+		return 0;
+	if (facility_mask & CRYPT_S390_MSA3 && !test_facility(76))
+		return 0;
+	if (facility_mask & CRYPT_S390_MSA4 && !test_facility(77))
 		return 0;
 
 	switch (func & CRYPT_S390_OP_MASK) {
@@ -316,6 +389,10 @@
 	case CRYPT_S390_KMAC:
 		ret = crypt_s390_kmac(KMAC_QUERY, &status, NULL, 0);
 		break;
+	case CRYPT_S390_KMCTR:
+		ret = crypt_s390_kmctr(KMCTR_QUERY, &status, NULL, NULL, 0,
+				       NULL);
+		break;
 	default:
 		return 0;
 	}
@@ -326,4 +403,31 @@
 	return (status[func >> 3] & (0x80 >> (func & 7))) != 0;
 }
 
+/**
+ * crypt_s390_pcc:
+ * @func: the function code passed to KM; see crypt_s390_km_func
+ * @param: address of parameter block; see POP for details on each func
+ *
+ * Executes the PCC (PERFORM CRYPTOGRAPHIC COMPUTATION) operation of the CPU.
+ *
+ * Returns -1 for failure, 0 for success.
+ */
+static inline int crypt_s390_pcc(long func, void *param)
+{
+	register long __func asm("0") = func & 0x7f; /* encrypt or decrypt */
+	register void *__param asm("1") = param;
+	int ret = -1;
+
+	asm volatile(
+		"0:	.insn	rre,0xb92c0000,0,0 \n" /* PCC opcode */
+		"1:	brc	1,0b \n" /* handle partial completion */
+		"	la	%0,0\n"
+		"2:\n"
+		EX_TABLE(0b,2b) EX_TABLE(1b,2b)
+		: "+d" (ret)
+		: "d" (__func), "a" (__param) : "cc", "memory");
+	return ret;
+}
+
+
 #endif	/* _CRYPTO_ARCH_S390_CRYPT_S390_H */
diff -druN linux-2.6.39-libre/arch/s390/crypto/des_check_key.c linux-3.0-rc7-libre/arch/s390/crypto/des_check_key.c
--- linux-2.6.39-libre/arch/s390/crypto/des_check_key.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/s390/crypto/des_check_key.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,132 +0,0 @@
-/*
- * Cryptographic API.
- *
- * Function for checking keys for the DES and Tripple DES Encryption
- * algorithms.
- *
- * Originally released as descore by Dana L. How <how@isl.stanford.edu>.
- * Modified by Raimar Falke <rf13@inf.tu-dresden.de> for the Linux-Kernel.
- * Derived from Cryptoapi and Nettle implementations, adapted for in-place
- * scatterlist interface.  Changed LGPL to GPL per section 3 of the LGPL.
- *
- * s390 Version:
- *   Copyright IBM Corp. 2003
- *   Author(s): Thomas Spatzier
- *		Jan Glauber (jan.glauber@de.ibm.com)
- *
- * Derived from "crypto/des.c"
- *   Copyright (c) 1992 Dana L. How.
- *   Copyright (c) Raimar Falke <rf13@inf.tu-dresden.de>
- *   Copyright (c) Gisle Sflensminde <gisle@ii.uib.no>
- *   Copyright (C) 2001 Niels Mvller.
- *   Copyright (c) 2002 James Morris <jmorris@intercode.com.au>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- */
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/errno.h>
-#include <linux/crypto.h>
-#include "crypto_des.h"
-
-#define ROR(d,c,o)	((d) = (d) >> (c) | (d) << (o))
-
-static const u8 parity[] = {
-	8,1,0,8,0,8,8,0,0,8,8,0,8,0,2,8,0,8,8,0,8,0,0,8,8,0,0,8,0,8,8,3,
-	0,8,8,0,8,0,0,8,8,0,0,8,0,8,8,0,8,0,0,8,0,8,8,0,0,8,8,0,8,0,0,8,
-	0,8,8,0,8,0,0,8,8,0,0,8,0,8,8,0,8,0,0,8,0,8,8,0,0,8,8,0,8,0,0,8,
-	8,0,0,8,0,8,8,0,0,8,8,0,8,0,0,8,0,8,8,0,8,0,0,8,8,0,0,8,0,8,8,0,
-	0,8,8,0,8,0,0,8,8,0,0,8,0,8,8,0,8,0,0,8,0,8,8,0,0,8,8,0,8,0,0,8,
-	8,0,0,8,0,8,8,0,0,8,8,0,8,0,0,8,0,8,8,0,8,0,0,8,8,0,0,8,0,8,8,0,
-	8,0,0,8,0,8,8,0,0,8,8,0,8,0,0,8,0,8,8,0,8,0,0,8,8,0,0,8,0,8,8,0,
-	4,8,8,0,8,0,0,8,8,0,0,8,0,8,8,0,8,5,0,8,0,8,8,0,0,8,8,0,8,0,6,8,
-};
-
-/*
- * RFC2451: Weak key checks SHOULD be performed.
- */
-int
-crypto_des_check_key(const u8 *key, unsigned int keylen, u32 *flags)
-{
-	u32 n, w;
-
-	n  = parity[key[0]]; n <<= 4;
-	n |= parity[key[1]]; n <<= 4;
-	n |= parity[key[2]]; n <<= 4;
-	n |= parity[key[3]]; n <<= 4;
-	n |= parity[key[4]]; n <<= 4;
-	n |= parity[key[5]]; n <<= 4;
-	n |= parity[key[6]]; n <<= 4;
-	n |= parity[key[7]];
-	w = 0x88888888L;
-
-	if ((*flags & CRYPTO_TFM_REQ_WEAK_KEY)
-	    && !((n - (w >> 3)) & w)) {  /* 1 in 10^10 keys passes this test */
-		if (n < 0x41415151) {
-			if (n < 0x31312121) {
-				if (n < 0x14141515) {
-					/* 01 01 01 01 01 01 01 01 */
-					if (n == 0x11111111) goto weak;
-					/* 01 1F 01 1F 01 0E 01 0E */
-					if (n == 0x13131212) goto weak;
-				} else {
-					/* 01 E0 01 E0 01 F1 01 F1 */
-					if (n == 0x14141515) goto weak;
-					/* 01 FE 01 FE 01 FE 01 FE */
-					if (n == 0x16161616) goto weak;
-				}
-			} else {
-				if (n < 0x34342525) {
-					/* 1F 01 1F 01 0E 01 0E 01 */
-					if (n == 0x31312121) goto weak;
-					/* 1F 1F 1F 1F 0E 0E 0E 0E (?) */
-					if (n == 0x33332222) goto weak;
-				} else {
-					/* 1F E0 1F E0 0E F1 0E F1 */
-					if (n == 0x34342525) goto weak;
-					/* 1F FE 1F FE 0E FE 0E FE */
-					if (n == 0x36362626) goto weak;
-				}
-			}
-		} else {
-			if (n < 0x61616161) {
-				if (n < 0x44445555) {
-					/* E0 01 E0 01 F1 01 F1 01 */
-					if (n == 0x41415151) goto weak;
-					/* E0 1F E0 1F F1 0E F1 0E */
-					if (n == 0x43435252) goto weak;
-				} else {
-					/* E0 E0 E0 E0 F1 F1 F1 F1 (?) */
-					if (n == 0x44445555) goto weak;
-					/* E0 FE E0 FE F1 FE F1 FE */
-					if (n == 0x46465656) goto weak;
-				}
-			} else {
-				if (n < 0x64646565) {
-					/* FE 01 FE 01 FE 01 FE 01 */
-					if (n == 0x61616161) goto weak;
-					/* FE 1F FE 1F FE 0E FE 0E */
-					if (n == 0x63636262) goto weak;
-				} else {
-					/* FE E0 FE E0 FE F1 FE F1 */
-					if (n == 0x64646565) goto weak;
-					/* FE FE FE FE FE FE FE FE */
-					if (n == 0x66666666) goto weak;
-				}
-			}
-		}
-	}
-	return 0;
-weak:
-	*flags |= CRYPTO_TFM_RES_WEAK_KEY;
-	return -EINVAL;
-}
-
-EXPORT_SYMBOL(crypto_des_check_key);
-
-MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("Key Check function for DES &  DES3 Cipher Algorithms");
diff -druN linux-2.6.39-libre/arch/s390/crypto/des_s390.c linux-3.0-rc7-libre/arch/s390/crypto/des_s390.c
--- linux-2.6.39-libre/arch/s390/crypto/des_s390.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/s390/crypto/des_s390.c	2011-07-11 19:51:52.000000000 -0400
@@ -3,7 +3,7 @@
  *
  * s390 implementation of the DES Cipher Algorithm.
  *
- * Copyright IBM Corp. 2003,2007
+ * Copyright IBM Corp. 2003,2011
  * Author(s): Thomas Spatzier
  *	      Jan Glauber (jan.glauber@de.ibm.com)
  *
@@ -22,22 +22,19 @@
 
 #include "crypt_s390.h"
 
-#define DES3_192_KEY_SIZE	(3 * DES_KEY_SIZE)
+#define DES3_KEY_SIZE	(3 * DES_KEY_SIZE)
 
-struct crypt_s390_des_ctx {
-	u8 iv[DES_BLOCK_SIZE];
-	u8 key[DES_KEY_SIZE];
-};
+static u8 *ctrblk;
 
-struct crypt_s390_des3_192_ctx {
+struct s390_des_ctx {
 	u8 iv[DES_BLOCK_SIZE];
-	u8 key[DES3_192_KEY_SIZE];
+	u8 key[DES3_KEY_SIZE];
 };
 
 static int des_setkey(struct crypto_tfm *tfm, const u8 *key,
-		      unsigned int keylen)
+		      unsigned int key_len)
 {
-	struct crypt_s390_des_ctx *dctx = crypto_tfm_ctx(tfm);
+	struct s390_des_ctx *ctx = crypto_tfm_ctx(tfm);
 	u32 *flags = &tfm->crt_flags;
 	u32 tmp[DES_EXPKEY_WORDS];
 
@@ -47,22 +44,22 @@
 		return -EINVAL;
 	}
 
-	memcpy(dctx->key, key, keylen);
+	memcpy(ctx->key, key, key_len);
 	return 0;
 }
 
 static void des_encrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in)
 {
-	struct crypt_s390_des_ctx *dctx = crypto_tfm_ctx(tfm);
+	struct s390_des_ctx *ctx = crypto_tfm_ctx(tfm);
 
-	crypt_s390_km(KM_DEA_ENCRYPT, dctx->key, out, in, DES_BLOCK_SIZE);
+	crypt_s390_km(KM_DEA_ENCRYPT, ctx->key, out, in, DES_BLOCK_SIZE);
 }
 
 static void des_decrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in)
 {
-	struct crypt_s390_des_ctx *dctx = crypto_tfm_ctx(tfm);
+	struct s390_des_ctx *ctx = crypto_tfm_ctx(tfm);
 
-	crypt_s390_km(KM_DEA_DECRYPT, dctx->key, out, in, DES_BLOCK_SIZE);
+	crypt_s390_km(KM_DEA_DECRYPT, ctx->key, out, in, DES_BLOCK_SIZE);
 }
 
 static struct crypto_alg des_alg = {
@@ -71,7 +68,7 @@
 	.cra_priority		=	CRYPT_S390_PRIORITY,
 	.cra_flags		=	CRYPTO_ALG_TYPE_CIPHER,
 	.cra_blocksize		=	DES_BLOCK_SIZE,
-	.cra_ctxsize		=	sizeof(struct crypt_s390_des_ctx),
+	.cra_ctxsize		=	sizeof(struct s390_des_ctx),
 	.cra_module		=	THIS_MODULE,
 	.cra_list		=	LIST_HEAD_INIT(des_alg.cra_list),
 	.cra_u			=	{
@@ -86,7 +83,7 @@
 };
 
 static int ecb_desall_crypt(struct blkcipher_desc *desc, long func,
-			    void *param, struct blkcipher_walk *walk)
+			    u8 *key, struct blkcipher_walk *walk)
 {
 	int ret = blkcipher_walk_virt(desc, walk);
 	unsigned int nbytes;
@@ -97,7 +94,7 @@
 		u8 *out = walk->dst.virt.addr;
 		u8 *in = walk->src.virt.addr;
 
-		ret = crypt_s390_km(func, param, out, in, n);
+		ret = crypt_s390_km(func, key, out, in, n);
 		BUG_ON((ret < 0) || (ret != n));
 
 		nbytes &= DES_BLOCK_SIZE - 1;
@@ -108,7 +105,7 @@
 }
 
 static int cbc_desall_crypt(struct blkcipher_desc *desc, long func,
-			    void *param, struct blkcipher_walk *walk)
+			    u8 *iv, struct blkcipher_walk *walk)
 {
 	int ret = blkcipher_walk_virt(desc, walk);
 	unsigned int nbytes = walk->nbytes;
@@ -116,20 +113,20 @@
 	if (!nbytes)
 		goto out;
 
-	memcpy(param, walk->iv, DES_BLOCK_SIZE);
+	memcpy(iv, walk->iv, DES_BLOCK_SIZE);
 	do {
 		/* only use complete blocks */
 		unsigned int n = nbytes & ~(DES_BLOCK_SIZE - 1);
 		u8 *out = walk->dst.virt.addr;
 		u8 *in = walk->src.virt.addr;
 
-		ret = crypt_s390_kmc(func, param, out, in, n);
+		ret = crypt_s390_kmc(func, iv, out, in, n);
 		BUG_ON((ret < 0) || (ret != n));
 
 		nbytes &= DES_BLOCK_SIZE - 1;
 		ret = blkcipher_walk_done(desc, walk, nbytes);
 	} while ((nbytes = walk->nbytes));
-	memcpy(walk->iv, param, DES_BLOCK_SIZE);
+	memcpy(walk->iv, iv, DES_BLOCK_SIZE);
 
 out:
 	return ret;
@@ -139,22 +136,22 @@
 			   struct scatterlist *dst, struct scatterlist *src,
 			   unsigned int nbytes)
 {
-	struct crypt_s390_des_ctx *sctx = crypto_blkcipher_ctx(desc->tfm);
+	struct s390_des_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
 	struct blkcipher_walk walk;
 
 	blkcipher_walk_init(&walk, dst, src, nbytes);
-	return ecb_desall_crypt(desc, KM_DEA_ENCRYPT, sctx->key, &walk);
+	return ecb_desall_crypt(desc, KM_DEA_ENCRYPT, ctx->key, &walk);
 }
 
 static int ecb_des_decrypt(struct blkcipher_desc *desc,
 			   struct scatterlist *dst, struct scatterlist *src,
 			   unsigned int nbytes)
 {
-	struct crypt_s390_des_ctx *sctx = crypto_blkcipher_ctx(desc->tfm);
+	struct s390_des_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
 	struct blkcipher_walk walk;
 
 	blkcipher_walk_init(&walk, dst, src, nbytes);
-	return ecb_desall_crypt(desc, KM_DEA_DECRYPT, sctx->key, &walk);
+	return ecb_desall_crypt(desc, KM_DEA_DECRYPT, ctx->key, &walk);
 }
 
 static struct crypto_alg ecb_des_alg = {
@@ -163,7 +160,7 @@
 	.cra_priority		=	CRYPT_S390_COMPOSITE_PRIORITY,
 	.cra_flags		=	CRYPTO_ALG_TYPE_BLKCIPHER,
 	.cra_blocksize		=	DES_BLOCK_SIZE,
-	.cra_ctxsize		=	sizeof(struct crypt_s390_des_ctx),
+	.cra_ctxsize		=	sizeof(struct s390_des_ctx),
 	.cra_type		=	&crypto_blkcipher_type,
 	.cra_module		=	THIS_MODULE,
 	.cra_list		=	LIST_HEAD_INIT(ecb_des_alg.cra_list),
@@ -182,22 +179,22 @@
 			   struct scatterlist *dst, struct scatterlist *src,
 			   unsigned int nbytes)
 {
-	struct crypt_s390_des_ctx *sctx = crypto_blkcipher_ctx(desc->tfm);
+	struct s390_des_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
 	struct blkcipher_walk walk;
 
 	blkcipher_walk_init(&walk, dst, src, nbytes);
-	return cbc_desall_crypt(desc, KMC_DEA_ENCRYPT, sctx->iv, &walk);
+	return cbc_desall_crypt(desc, KMC_DEA_ENCRYPT, ctx->iv, &walk);
 }
 
 static int cbc_des_decrypt(struct blkcipher_desc *desc,
 			   struct scatterlist *dst, struct scatterlist *src,
 			   unsigned int nbytes)
 {
-	struct crypt_s390_des_ctx *sctx = crypto_blkcipher_ctx(desc->tfm);
+	struct s390_des_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
 	struct blkcipher_walk walk;
 
 	blkcipher_walk_init(&walk, dst, src, nbytes);
-	return cbc_desall_crypt(desc, KMC_DEA_DECRYPT, sctx->iv, &walk);
+	return cbc_desall_crypt(desc, KMC_DEA_DECRYPT, ctx->iv, &walk);
 }
 
 static struct crypto_alg cbc_des_alg = {
@@ -206,7 +203,7 @@
 	.cra_priority		=	CRYPT_S390_COMPOSITE_PRIORITY,
 	.cra_flags		=	CRYPTO_ALG_TYPE_BLKCIPHER,
 	.cra_blocksize		=	DES_BLOCK_SIZE,
-	.cra_ctxsize		=	sizeof(struct crypt_s390_des_ctx),
+	.cra_ctxsize		=	sizeof(struct s390_des_ctx),
 	.cra_type		=	&crypto_blkcipher_type,
 	.cra_module		=	THIS_MODULE,
 	.cra_list		=	LIST_HEAD_INIT(cbc_des_alg.cra_list),
@@ -235,10 +232,10 @@
  *   property.
  *
  */
-static int des3_192_setkey(struct crypto_tfm *tfm, const u8 *key,
-			   unsigned int keylen)
+static int des3_setkey(struct crypto_tfm *tfm, const u8 *key,
+		       unsigned int key_len)
 {
-	struct crypt_s390_des3_192_ctx *dctx = crypto_tfm_ctx(tfm);
+	struct s390_des_ctx *ctx = crypto_tfm_ctx(tfm);
 	u32 *flags = &tfm->crt_flags;
 
 	if (!(memcmp(key, &key[DES_KEY_SIZE], DES_KEY_SIZE) &&
@@ -248,141 +245,276 @@
 		*flags |= CRYPTO_TFM_RES_WEAK_KEY;
 		return -EINVAL;
 	}
-	memcpy(dctx->key, key, keylen);
+	memcpy(ctx->key, key, key_len);
 	return 0;
 }
 
-static void des3_192_encrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
+static void des3_encrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
 {
-	struct crypt_s390_des3_192_ctx *dctx = crypto_tfm_ctx(tfm);
+	struct s390_des_ctx *ctx = crypto_tfm_ctx(tfm);
 
-	crypt_s390_km(KM_TDEA_192_ENCRYPT, dctx->key, dst, (void*)src,
-		      DES_BLOCK_SIZE);
+	crypt_s390_km(KM_TDEA_192_ENCRYPT, ctx->key, dst, src, DES_BLOCK_SIZE);
 }
 
-static void des3_192_decrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
+static void des3_decrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
 {
-	struct crypt_s390_des3_192_ctx *dctx = crypto_tfm_ctx(tfm);
+	struct s390_des_ctx *ctx = crypto_tfm_ctx(tfm);
 
-	crypt_s390_km(KM_TDEA_192_DECRYPT, dctx->key, dst, (void*)src,
-		      DES_BLOCK_SIZE);
+	crypt_s390_km(KM_TDEA_192_DECRYPT, ctx->key, dst, src, DES_BLOCK_SIZE);
 }
 
-static struct crypto_alg des3_192_alg = {
+static struct crypto_alg des3_alg = {
 	.cra_name		=	"des3_ede",
 	.cra_driver_name	=	"des3_ede-s390",
 	.cra_priority		=	CRYPT_S390_PRIORITY,
 	.cra_flags		=	CRYPTO_ALG_TYPE_CIPHER,
 	.cra_blocksize		=	DES_BLOCK_SIZE,
-	.cra_ctxsize		=	sizeof(struct crypt_s390_des3_192_ctx),
+	.cra_ctxsize		=	sizeof(struct s390_des_ctx),
 	.cra_module		=	THIS_MODULE,
-	.cra_list		=	LIST_HEAD_INIT(des3_192_alg.cra_list),
+	.cra_list		=	LIST_HEAD_INIT(des3_alg.cra_list),
 	.cra_u			=	{
 		.cipher = {
-			.cia_min_keysize	=	DES3_192_KEY_SIZE,
-			.cia_max_keysize	=	DES3_192_KEY_SIZE,
-			.cia_setkey		=	des3_192_setkey,
-			.cia_encrypt		=	des3_192_encrypt,
-			.cia_decrypt		=	des3_192_decrypt,
+			.cia_min_keysize	=	DES3_KEY_SIZE,
+			.cia_max_keysize	=	DES3_KEY_SIZE,
+			.cia_setkey		=	des3_setkey,
+			.cia_encrypt		=	des3_encrypt,
+			.cia_decrypt		=	des3_decrypt,
 		}
 	}
 };
 
-static int ecb_des3_192_encrypt(struct blkcipher_desc *desc,
-				struct scatterlist *dst,
-				struct scatterlist *src, unsigned int nbytes)
+static int ecb_des3_encrypt(struct blkcipher_desc *desc,
+			    struct scatterlist *dst, struct scatterlist *src,
+			    unsigned int nbytes)
 {
-	struct crypt_s390_des3_192_ctx *sctx = crypto_blkcipher_ctx(desc->tfm);
+	struct s390_des_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
 	struct blkcipher_walk walk;
 
 	blkcipher_walk_init(&walk, dst, src, nbytes);
-	return ecb_desall_crypt(desc, KM_TDEA_192_ENCRYPT, sctx->key, &walk);
+	return ecb_desall_crypt(desc, KM_TDEA_192_ENCRYPT, ctx->key, &walk);
 }
 
-static int ecb_des3_192_decrypt(struct blkcipher_desc *desc,
-				struct scatterlist *dst,
-				struct scatterlist *src, unsigned int nbytes)
+static int ecb_des3_decrypt(struct blkcipher_desc *desc,
+			    struct scatterlist *dst, struct scatterlist *src,
+			    unsigned int nbytes)
 {
-	struct crypt_s390_des3_192_ctx *sctx = crypto_blkcipher_ctx(desc->tfm);
+	struct s390_des_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
 	struct blkcipher_walk walk;
 
 	blkcipher_walk_init(&walk, dst, src, nbytes);
-	return ecb_desall_crypt(desc, KM_TDEA_192_DECRYPT, sctx->key, &walk);
+	return ecb_desall_crypt(desc, KM_TDEA_192_DECRYPT, ctx->key, &walk);
 }
 
-static struct crypto_alg ecb_des3_192_alg = {
+static struct crypto_alg ecb_des3_alg = {
 	.cra_name		=	"ecb(des3_ede)",
 	.cra_driver_name	=	"ecb-des3_ede-s390",
 	.cra_priority		=	CRYPT_S390_COMPOSITE_PRIORITY,
 	.cra_flags		=	CRYPTO_ALG_TYPE_BLKCIPHER,
 	.cra_blocksize		=	DES_BLOCK_SIZE,
-	.cra_ctxsize		=	sizeof(struct crypt_s390_des3_192_ctx),
+	.cra_ctxsize		=	sizeof(struct s390_des_ctx),
 	.cra_type		=	&crypto_blkcipher_type,
 	.cra_module		=	THIS_MODULE,
 	.cra_list		=	LIST_HEAD_INIT(
-						ecb_des3_192_alg.cra_list),
+						ecb_des3_alg.cra_list),
 	.cra_u			=	{
 		.blkcipher = {
-			.min_keysize		=	DES3_192_KEY_SIZE,
-			.max_keysize		=	DES3_192_KEY_SIZE,
-			.setkey			=	des3_192_setkey,
-			.encrypt		=	ecb_des3_192_encrypt,
-			.decrypt		=	ecb_des3_192_decrypt,
+			.min_keysize		=	DES3_KEY_SIZE,
+			.max_keysize		=	DES3_KEY_SIZE,
+			.setkey			=	des3_setkey,
+			.encrypt		=	ecb_des3_encrypt,
+			.decrypt		=	ecb_des3_decrypt,
 		}
 	}
 };
 
-static int cbc_des3_192_encrypt(struct blkcipher_desc *desc,
-				struct scatterlist *dst,
-				struct scatterlist *src, unsigned int nbytes)
+static int cbc_des3_encrypt(struct blkcipher_desc *desc,
+			    struct scatterlist *dst, struct scatterlist *src,
+			    unsigned int nbytes)
 {
-	struct crypt_s390_des3_192_ctx *sctx = crypto_blkcipher_ctx(desc->tfm);
+	struct s390_des_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
 	struct blkcipher_walk walk;
 
 	blkcipher_walk_init(&walk, dst, src, nbytes);
-	return cbc_desall_crypt(desc, KMC_TDEA_192_ENCRYPT, sctx->iv, &walk);
+	return cbc_desall_crypt(desc, KMC_TDEA_192_ENCRYPT, ctx->iv, &walk);
 }
 
-static int cbc_des3_192_decrypt(struct blkcipher_desc *desc,
-				struct scatterlist *dst,
-				struct scatterlist *src, unsigned int nbytes)
+static int cbc_des3_decrypt(struct blkcipher_desc *desc,
+			    struct scatterlist *dst, struct scatterlist *src,
+			    unsigned int nbytes)
 {
-	struct crypt_s390_des3_192_ctx *sctx = crypto_blkcipher_ctx(desc->tfm);
+	struct s390_des_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
 	struct blkcipher_walk walk;
 
 	blkcipher_walk_init(&walk, dst, src, nbytes);
-	return cbc_desall_crypt(desc, KMC_TDEA_192_DECRYPT, sctx->iv, &walk);
+	return cbc_desall_crypt(desc, KMC_TDEA_192_DECRYPT, ctx->iv, &walk);
 }
 
-static struct crypto_alg cbc_des3_192_alg = {
+static struct crypto_alg cbc_des3_alg = {
 	.cra_name		=	"cbc(des3_ede)",
 	.cra_driver_name	=	"cbc-des3_ede-s390",
 	.cra_priority		=	CRYPT_S390_COMPOSITE_PRIORITY,
 	.cra_flags		=	CRYPTO_ALG_TYPE_BLKCIPHER,
 	.cra_blocksize		=	DES_BLOCK_SIZE,
-	.cra_ctxsize		=	sizeof(struct crypt_s390_des3_192_ctx),
+	.cra_ctxsize		=	sizeof(struct s390_des_ctx),
 	.cra_type		=	&crypto_blkcipher_type,
 	.cra_module		=	THIS_MODULE,
 	.cra_list		=	LIST_HEAD_INIT(
-						cbc_des3_192_alg.cra_list),
+						cbc_des3_alg.cra_list),
 	.cra_u			=	{
 		.blkcipher = {
-			.min_keysize		=	DES3_192_KEY_SIZE,
-			.max_keysize		=	DES3_192_KEY_SIZE,
+			.min_keysize		=	DES3_KEY_SIZE,
+			.max_keysize		=	DES3_KEY_SIZE,
 			.ivsize			=	DES_BLOCK_SIZE,
-			.setkey			=	des3_192_setkey,
-			.encrypt		=	cbc_des3_192_encrypt,
-			.decrypt		=	cbc_des3_192_decrypt,
+			.setkey			=	des3_setkey,
+			.encrypt		=	cbc_des3_encrypt,
+			.decrypt		=	cbc_des3_decrypt,
 		}
 	}
 };
 
-static int des_s390_init(void)
+static int ctr_desall_crypt(struct blkcipher_desc *desc, long func,
+			    struct s390_des_ctx *ctx, struct blkcipher_walk *walk)
+{
+	int ret = blkcipher_walk_virt_block(desc, walk, DES_BLOCK_SIZE);
+	unsigned int i, n, nbytes;
+	u8 buf[DES_BLOCK_SIZE];
+	u8 *out, *in;
+
+	memcpy(ctrblk, walk->iv, DES_BLOCK_SIZE);
+	while ((nbytes = walk->nbytes) >= DES_BLOCK_SIZE) {
+		out = walk->dst.virt.addr;
+		in = walk->src.virt.addr;
+		while (nbytes >= DES_BLOCK_SIZE) {
+			/* align to block size, max. PAGE_SIZE */
+			n = (nbytes > PAGE_SIZE) ? PAGE_SIZE :
+				nbytes & ~(DES_BLOCK_SIZE - 1);
+			for (i = DES_BLOCK_SIZE; i < n; i += DES_BLOCK_SIZE) {
+				memcpy(ctrblk + i, ctrblk + i - DES_BLOCK_SIZE,
+				       DES_BLOCK_SIZE);
+				crypto_inc(ctrblk + i, DES_BLOCK_SIZE);
+			}
+			ret = crypt_s390_kmctr(func, ctx->key, out, in, n, ctrblk);
+			BUG_ON((ret < 0) || (ret != n));
+			if (n > DES_BLOCK_SIZE)
+				memcpy(ctrblk, ctrblk + n - DES_BLOCK_SIZE,
+				       DES_BLOCK_SIZE);
+			crypto_inc(ctrblk, DES_BLOCK_SIZE);
+			out += n;
+			in += n;
+			nbytes -= n;
+		}
+		ret = blkcipher_walk_done(desc, walk, nbytes);
+	}
+
+	/* final block may be < DES_BLOCK_SIZE, copy only nbytes */
+	if (nbytes) {
+		out = walk->dst.virt.addr;
+		in = walk->src.virt.addr;
+		ret = crypt_s390_kmctr(func, ctx->key, buf, in,
+				       DES_BLOCK_SIZE, ctrblk);
+		BUG_ON(ret < 0 || ret != DES_BLOCK_SIZE);
+		memcpy(out, buf, nbytes);
+		crypto_inc(ctrblk, DES_BLOCK_SIZE);
+		ret = blkcipher_walk_done(desc, walk, 0);
+	}
+	memcpy(walk->iv, ctrblk, DES_BLOCK_SIZE);
+	return ret;
+}
+
+static int ctr_des_encrypt(struct blkcipher_desc *desc,
+			   struct scatterlist *dst, struct scatterlist *src,
+			   unsigned int nbytes)
+{
+	struct s390_des_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
+	struct blkcipher_walk walk;
+
+	blkcipher_walk_init(&walk, dst, src, nbytes);
+	return ctr_desall_crypt(desc, KMCTR_DEA_ENCRYPT, ctx, &walk);
+}
+
+static int ctr_des_decrypt(struct blkcipher_desc *desc,
+			   struct scatterlist *dst, struct scatterlist *src,
+			   unsigned int nbytes)
+{
+	struct s390_des_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
+	struct blkcipher_walk walk;
+
+	blkcipher_walk_init(&walk, dst, src, nbytes);
+	return ctr_desall_crypt(desc, KMCTR_DEA_DECRYPT, ctx, &walk);
+}
+
+static struct crypto_alg ctr_des_alg = {
+	.cra_name		=	"ctr(des)",
+	.cra_driver_name	=	"ctr-des-s390",
+	.cra_priority		=	CRYPT_S390_COMPOSITE_PRIORITY,
+	.cra_flags		=	CRYPTO_ALG_TYPE_BLKCIPHER,
+	.cra_blocksize		=	1,
+	.cra_ctxsize		=	sizeof(struct s390_des_ctx),
+	.cra_type		=	&crypto_blkcipher_type,
+	.cra_module		=	THIS_MODULE,
+	.cra_list		=	LIST_HEAD_INIT(ctr_des_alg.cra_list),
+	.cra_u			=	{
+		.blkcipher = {
+			.min_keysize		=	DES_KEY_SIZE,
+			.max_keysize		=	DES_KEY_SIZE,
+			.ivsize			=	DES_BLOCK_SIZE,
+			.setkey			=	des_setkey,
+			.encrypt		=	ctr_des_encrypt,
+			.decrypt		=	ctr_des_decrypt,
+		}
+	}
+};
+
+static int ctr_des3_encrypt(struct blkcipher_desc *desc,
+			    struct scatterlist *dst, struct scatterlist *src,
+			    unsigned int nbytes)
+{
+	struct s390_des_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
+	struct blkcipher_walk walk;
+
+	blkcipher_walk_init(&walk, dst, src, nbytes);
+	return ctr_desall_crypt(desc, KMCTR_TDEA_192_ENCRYPT, ctx, &walk);
+}
+
+static int ctr_des3_decrypt(struct blkcipher_desc *desc,
+			    struct scatterlist *dst, struct scatterlist *src,
+			    unsigned int nbytes)
+{
+	struct s390_des_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
+	struct blkcipher_walk walk;
+
+	blkcipher_walk_init(&walk, dst, src, nbytes);
+	return ctr_desall_crypt(desc, KMCTR_TDEA_192_DECRYPT, ctx, &walk);
+}
+
+static struct crypto_alg ctr_des3_alg = {
+	.cra_name		=	"ctr(des3_ede)",
+	.cra_driver_name	=	"ctr-des3_ede-s390",
+	.cra_priority		=	CRYPT_S390_COMPOSITE_PRIORITY,
+	.cra_flags		=	CRYPTO_ALG_TYPE_BLKCIPHER,
+	.cra_blocksize		=	1,
+	.cra_ctxsize		=	sizeof(struct s390_des_ctx),
+	.cra_type		=	&crypto_blkcipher_type,
+	.cra_module		=	THIS_MODULE,
+	.cra_list		=	LIST_HEAD_INIT(ctr_des3_alg.cra_list),
+	.cra_u			=	{
+		.blkcipher = {
+			.min_keysize		=	DES3_KEY_SIZE,
+			.max_keysize		=	DES3_KEY_SIZE,
+			.ivsize			=	DES_BLOCK_SIZE,
+			.setkey			=	des3_setkey,
+			.encrypt		=	ctr_des3_encrypt,
+			.decrypt		=	ctr_des3_decrypt,
+		}
+	}
+};
+
+static int __init des_s390_init(void)
 {
 	int ret;
 
-	if (!crypt_s390_func_available(KM_DEA_ENCRYPT) ||
-	    !crypt_s390_func_available(KM_TDEA_192_ENCRYPT))
+	if (!crypt_s390_func_available(KM_DEA_ENCRYPT, CRYPT_S390_MSA) ||
+	    !crypt_s390_func_available(KM_TDEA_192_ENCRYPT, CRYPT_S390_MSA))
 		return -EOPNOTSUPP;
 
 	ret = crypto_register_alg(&des_alg);
@@ -394,23 +526,46 @@
 	ret = crypto_register_alg(&cbc_des_alg);
 	if (ret)
 		goto cbc_des_err;
-	ret = crypto_register_alg(&des3_192_alg);
+	ret = crypto_register_alg(&des3_alg);
 	if (ret)
-		goto des3_192_err;
-	ret = crypto_register_alg(&ecb_des3_192_alg);
+		goto des3_err;
+	ret = crypto_register_alg(&ecb_des3_alg);
 	if (ret)
-		goto ecb_des3_192_err;
-	ret = crypto_register_alg(&cbc_des3_192_alg);
+		goto ecb_des3_err;
+	ret = crypto_register_alg(&cbc_des3_alg);
 	if (ret)
-		goto cbc_des3_192_err;
+		goto cbc_des3_err;
+
+	if (crypt_s390_func_available(KMCTR_DEA_ENCRYPT,
+			CRYPT_S390_MSA | CRYPT_S390_MSA4) &&
+	    crypt_s390_func_available(KMCTR_TDEA_192_ENCRYPT,
+			CRYPT_S390_MSA | CRYPT_S390_MSA4)) {
+		ret = crypto_register_alg(&ctr_des_alg);
+		if (ret)
+			goto ctr_des_err;
+		ret = crypto_register_alg(&ctr_des3_alg);
+		if (ret)
+			goto ctr_des3_err;
+		ctrblk = (u8 *) __get_free_page(GFP_KERNEL);
+		if (!ctrblk) {
+			ret = -ENOMEM;
+			goto ctr_mem_err;
+		}
+	}
 out:
 	return ret;
 
-cbc_des3_192_err:
-	crypto_unregister_alg(&ecb_des3_192_alg);
-ecb_des3_192_err:
-	crypto_unregister_alg(&des3_192_alg);
-des3_192_err:
+ctr_mem_err:
+	crypto_unregister_alg(&ctr_des3_alg);
+ctr_des3_err:
+	crypto_unregister_alg(&ctr_des_alg);
+ctr_des_err:
+	crypto_unregister_alg(&cbc_des3_alg);
+cbc_des3_err:
+	crypto_unregister_alg(&ecb_des3_alg);
+ecb_des3_err:
+	crypto_unregister_alg(&des3_alg);
+des3_err:
 	crypto_unregister_alg(&cbc_des_alg);
 cbc_des_err:
 	crypto_unregister_alg(&ecb_des_alg);
@@ -422,9 +577,14 @@
 
 static void __exit des_s390_exit(void)
 {
-	crypto_unregister_alg(&cbc_des3_192_alg);
-	crypto_unregister_alg(&ecb_des3_192_alg);
-	crypto_unregister_alg(&des3_192_alg);
+	if (ctrblk) {
+		crypto_unregister_alg(&ctr_des_alg);
+		crypto_unregister_alg(&ctr_des3_alg);
+		free_page((unsigned long) ctrblk);
+	}
+	crypto_unregister_alg(&cbc_des3_alg);
+	crypto_unregister_alg(&ecb_des3_alg);
+	crypto_unregister_alg(&des3_alg);
 	crypto_unregister_alg(&cbc_des_alg);
 	crypto_unregister_alg(&ecb_des_alg);
 	crypto_unregister_alg(&des_alg);
diff -druN linux-2.6.39-libre/arch/s390/crypto/ghash_s390.c linux-3.0-rc7-libre/arch/s390/crypto/ghash_s390.c
--- linux-2.6.39-libre/arch/s390/crypto/ghash_s390.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/s390/crypto/ghash_s390.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,162 @@
+/*
+ * Cryptographic API.
+ *
+ * s390 implementation of the GHASH algorithm for GCM (Galois/Counter Mode).
+ *
+ * Copyright IBM Corp. 2011
+ * Author(s): Gerald Schaefer <gerald.schaefer@de.ibm.com>
+ */
+
+#include <crypto/internal/hash.h>
+#include <linux/module.h>
+
+#include "crypt_s390.h"
+
+#define GHASH_BLOCK_SIZE	16
+#define GHASH_DIGEST_SIZE	16
+
+struct ghash_ctx {
+	u8 icv[16];
+	u8 key[16];
+};
+
+struct ghash_desc_ctx {
+	u8 buffer[GHASH_BLOCK_SIZE];
+	u32 bytes;
+};
+
+static int ghash_init(struct shash_desc *desc)
+{
+	struct ghash_desc_ctx *dctx = shash_desc_ctx(desc);
+
+	memset(dctx, 0, sizeof(*dctx));
+
+	return 0;
+}
+
+static int ghash_setkey(struct crypto_shash *tfm,
+			const u8 *key, unsigned int keylen)
+{
+	struct ghash_ctx *ctx = crypto_shash_ctx(tfm);
+
+	if (keylen != GHASH_BLOCK_SIZE) {
+		crypto_shash_set_flags(tfm, CRYPTO_TFM_RES_BAD_KEY_LEN);
+		return -EINVAL;
+	}
+
+	memcpy(ctx->key, key, GHASH_BLOCK_SIZE);
+	memset(ctx->icv, 0, GHASH_BLOCK_SIZE);
+
+	return 0;
+}
+
+static int ghash_update(struct shash_desc *desc,
+			 const u8 *src, unsigned int srclen)
+{
+	struct ghash_desc_ctx *dctx = shash_desc_ctx(desc);
+	struct ghash_ctx *ctx = crypto_shash_ctx(desc->tfm);
+	unsigned int n;
+	u8 *buf = dctx->buffer;
+	int ret;
+
+	if (dctx->bytes) {
+		u8 *pos = buf + (GHASH_BLOCK_SIZE - dctx->bytes);
+
+		n = min(srclen, dctx->bytes);
+		dctx->bytes -= n;
+		srclen -= n;
+
+		memcpy(pos, src, n);
+		src += n;
+
+		if (!dctx->bytes) {
+			ret = crypt_s390_kimd(KIMD_GHASH, ctx, buf,
+					      GHASH_BLOCK_SIZE);
+			BUG_ON(ret != GHASH_BLOCK_SIZE);
+		}
+	}
+
+	n = srclen & ~(GHASH_BLOCK_SIZE - 1);
+	if (n) {
+		ret = crypt_s390_kimd(KIMD_GHASH, ctx, src, n);
+		BUG_ON(ret != n);
+		src += n;
+		srclen -= n;
+	}
+
+	if (srclen) {
+		dctx->bytes = GHASH_BLOCK_SIZE - srclen;
+		memcpy(buf, src, srclen);
+	}
+
+	return 0;
+}
+
+static void ghash_flush(struct ghash_ctx *ctx, struct ghash_desc_ctx *dctx)
+{
+	u8 *buf = dctx->buffer;
+	int ret;
+
+	if (dctx->bytes) {
+		u8 *pos = buf + (GHASH_BLOCK_SIZE - dctx->bytes);
+
+		memset(pos, 0, dctx->bytes);
+
+		ret = crypt_s390_kimd(KIMD_GHASH, ctx, buf, GHASH_BLOCK_SIZE);
+		BUG_ON(ret != GHASH_BLOCK_SIZE);
+	}
+
+	dctx->bytes = 0;
+}
+
+static int ghash_final(struct shash_desc *desc, u8 *dst)
+{
+	struct ghash_desc_ctx *dctx = shash_desc_ctx(desc);
+	struct ghash_ctx *ctx = crypto_shash_ctx(desc->tfm);
+
+	ghash_flush(ctx, dctx);
+	memcpy(dst, ctx->icv, GHASH_BLOCK_SIZE);
+
+	return 0;
+}
+
+static struct shash_alg ghash_alg = {
+	.digestsize	= GHASH_DIGEST_SIZE,
+	.init		= ghash_init,
+	.update		= ghash_update,
+	.final		= ghash_final,
+	.setkey		= ghash_setkey,
+	.descsize	= sizeof(struct ghash_desc_ctx),
+	.base		= {
+		.cra_name		= "ghash",
+		.cra_driver_name	= "ghash-s390",
+		.cra_priority		= CRYPT_S390_PRIORITY,
+		.cra_flags		= CRYPTO_ALG_TYPE_SHASH,
+		.cra_blocksize		= GHASH_BLOCK_SIZE,
+		.cra_ctxsize		= sizeof(struct ghash_ctx),
+		.cra_module		= THIS_MODULE,
+		.cra_list		= LIST_HEAD_INIT(ghash_alg.base.cra_list),
+	},
+};
+
+static int __init ghash_mod_init(void)
+{
+	if (!crypt_s390_func_available(KIMD_GHASH,
+				       CRYPT_S390_MSA | CRYPT_S390_MSA4))
+		return -EOPNOTSUPP;
+
+	return crypto_register_shash(&ghash_alg);
+}
+
+static void __exit ghash_mod_exit(void)
+{
+	crypto_unregister_shash(&ghash_alg);
+}
+
+module_init(ghash_mod_init);
+module_exit(ghash_mod_exit);
+
+MODULE_ALIAS("ghash");
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("GHASH Message Digest Algorithm, s390 implementation");
diff -druN linux-2.6.39-libre/arch/s390/crypto/Makefile linux-3.0-rc7-libre/arch/s390/crypto/Makefile
--- linux-2.6.39-libre/arch/s390/crypto/Makefile	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/s390/crypto/Makefile	2011-07-11 19:51:52.000000000 -0400
@@ -8,3 +8,4 @@
 obj-$(CONFIG_CRYPTO_DES_S390) += des_s390.o
 obj-$(CONFIG_CRYPTO_AES_S390) += aes_s390.o
 obj-$(CONFIG_S390_PRNG) += prng.o
+obj-$(CONFIG_CRYPTO_GHASH_S390) += ghash_s390.o
diff -druN linux-2.6.39-libre/arch/s390/crypto/prng.c linux-3.0-rc7-libre/arch/s390/crypto/prng.c
--- linux-2.6.39-libre/arch/s390/crypto/prng.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/s390/crypto/prng.c	2011-07-11 19:51:52.000000000 -0400
@@ -166,7 +166,7 @@
 	int ret;
 
 	/* check if the CPU has a PRNG */
-	if (!crypt_s390_func_available(KMC_PRNG))
+	if (!crypt_s390_func_available(KMC_PRNG, CRYPT_S390_MSA))
 		return -EOPNOTSUPP;
 
 	if (prng_chunk_size < 8)
diff -druN linux-2.6.39-libre/arch/s390/crypto/sha1_s390.c linux-3.0-rc7-libre/arch/s390/crypto/sha1_s390.c
--- linux-2.6.39-libre/arch/s390/crypto/sha1_s390.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/s390/crypto/sha1_s390.c	2011-07-11 19:51:52.000000000 -0400
@@ -90,7 +90,7 @@
 
 static int __init sha1_s390_init(void)
 {
-	if (!crypt_s390_func_available(KIMD_SHA_1))
+	if (!crypt_s390_func_available(KIMD_SHA_1, CRYPT_S390_MSA))
 		return -EOPNOTSUPP;
 	return crypto_register_shash(&alg);
 }
diff -druN linux-2.6.39-libre/arch/s390/crypto/sha256_s390.c linux-3.0-rc7-libre/arch/s390/crypto/sha256_s390.c
--- linux-2.6.39-libre/arch/s390/crypto/sha256_s390.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/s390/crypto/sha256_s390.c	2011-07-11 19:51:52.000000000 -0400
@@ -86,7 +86,7 @@
 
 static int sha256_s390_init(void)
 {
-	if (!crypt_s390_func_available(KIMD_SHA_256))
+	if (!crypt_s390_func_available(KIMD_SHA_256, CRYPT_S390_MSA))
 		return -EOPNOTSUPP;
 
 	return crypto_register_shash(&alg);
diff -druN linux-2.6.39-libre/arch/s390/crypto/sha512_s390.c linux-3.0-rc7-libre/arch/s390/crypto/sha512_s390.c
--- linux-2.6.39-libre/arch/s390/crypto/sha512_s390.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/s390/crypto/sha512_s390.c	2011-07-11 19:51:52.000000000 -0400
@@ -132,7 +132,7 @@
 {
 	int ret;
 
-	if (!crypt_s390_func_available(KIMD_SHA_512))
+	if (!crypt_s390_func_available(KIMD_SHA_512, CRYPT_S390_MSA))
 		return -EOPNOTSUPP;
 	if ((ret = crypto_register_shash(&sha512_alg)) < 0)
 		goto out;
diff -druN linux-2.6.39-libre/arch/s390/hypfs/hypfs.h linux-3.0-rc7-libre/arch/s390/hypfs/hypfs.h
--- linux-2.6.39-libre/arch/s390/hypfs/hypfs.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/s390/hypfs/hypfs.h	2011-07-11 19:51:52.000000000 -0400
@@ -47,7 +47,7 @@
 	void			*buf;
 	void			*buf_free_ptr;
 	size_t			size;
-	struct hypfs_dbfs_file	*dbfs_file;;
+	struct hypfs_dbfs_file	*dbfs_file;
 	struct kref		kref;
 };
 
diff -druN linux-2.6.39-libre/arch/s390/include/asm/bitops.h linux-3.0-rc7-libre/arch/s390/include/asm/bitops.h
--- linux-2.6.39-libre/arch/s390/include/asm/bitops.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/s390/include/asm/bitops.h	2011-07-11 19:51:52.000000000 -0400
@@ -621,6 +621,7 @@
 	bits = __ffz_word(bytes*8, __load_ulong_be(addr, bytes));
 	return (bits < size) ? bits : size;
 }
+#define find_first_zero_bit find_first_zero_bit
 
 /**
  * find_first_bit - find the first set bit in a memory region
@@ -641,6 +642,7 @@
 	bits = __ffs_word(bytes*8, __load_ulong_be(addr, bytes));
 	return (bits < size) ? bits : size;
 }
+#define find_first_bit find_first_bit
 
 /**
  * find_next_zero_bit - find the first zero bit in a memory region
@@ -677,6 +679,7 @@
 	}
 	return offset + find_first_zero_bit(p, size);
 }
+#define find_next_zero_bit find_next_zero_bit
 
 /**
  * find_next_bit - find the first set bit in a memory region
@@ -713,6 +716,7 @@
 	}
 	return offset + find_first_bit(p, size);
 }
+#define find_next_bit find_next_bit
 
 /*
  * Every architecture must define this function. It's the fastest
@@ -742,41 +746,6 @@
  *    23 22 21 20 19 18 17 16 31 30 29 28 27 26 25 24
  */
 
-static inline void __set_bit_le(unsigned long nr, void *addr)
-{
-	__set_bit(nr ^ (__BITOPS_WORDSIZE - 8), addr);
-}
-
-static inline void __clear_bit_le(unsigned long nr, void *addr)
-{
-	__clear_bit(nr ^ (__BITOPS_WORDSIZE - 8), addr);
-}
-
-static inline int __test_and_set_bit_le(unsigned long nr, void *addr)
-{
-	return __test_and_set_bit(nr ^ (__BITOPS_WORDSIZE - 8), addr);
-}
-
-static inline int test_and_set_bit_le(unsigned long nr, void *addr)
-{
-	return test_and_set_bit(nr ^ (__BITOPS_WORDSIZE - 8), addr);
-}
-
-static inline int __test_and_clear_bit_le(unsigned long nr, void *addr)
-{
-	return __test_and_clear_bit(nr ^ (__BITOPS_WORDSIZE - 8), addr);
-}
-
-static inline int test_and_clear_bit_le(unsigned long nr, void *addr)
-{
-	return test_and_clear_bit(nr ^ (__BITOPS_WORDSIZE - 8), addr);
-}
-
-static inline int test_bit_le(unsigned long nr, const void *addr)
-{
-	return test_bit(nr ^ (__BITOPS_WORDSIZE - 8), addr);
-}
-
 static inline int find_first_zero_bit_le(void *vaddr, unsigned int size)
 {
 	unsigned long bytes, bits;
@@ -787,6 +756,7 @@
 	bits = __ffz_word(bytes*8, __load_ulong_le(vaddr, bytes));
 	return (bits < size) ? bits : size;
 }
+#define find_first_zero_bit_le find_first_zero_bit_le
 
 static inline int find_next_zero_bit_le(void *vaddr, unsigned long size,
 					  unsigned long offset)
@@ -816,6 +786,7 @@
         }
 	return offset + find_first_zero_bit_le(p, size);
 }
+#define find_next_zero_bit_le find_next_zero_bit_le
 
 static inline unsigned long find_first_bit_le(void *vaddr, unsigned long size)
 {
@@ -827,6 +798,7 @@
 	bits = __ffs_word(bytes*8, __load_ulong_le(vaddr, bytes));
 	return (bits < size) ? bits : size;
 }
+#define find_first_bit_le find_first_bit_le
 
 static inline int find_next_bit_le(void *vaddr, unsigned long size,
 				     unsigned long offset)
@@ -856,6 +828,9 @@
 	}
 	return offset + find_first_bit_le(p, size);
 }
+#define find_next_bit_le find_next_bit_le
+
+#include <asm-generic/bitops/le.h>
 
 #define ext2_set_bit_atomic(lock, nr, addr)	\
 	test_and_set_bit_le(nr, addr)
diff -druN linux-2.6.39-libre/arch/s390/include/asm/cacheflush.h linux-3.0-rc7-libre/arch/s390/include/asm/cacheflush.h
--- linux-2.6.39-libre/arch/s390/include/asm/cacheflush.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/s390/include/asm/cacheflush.h	2011-07-11 19:51:52.000000000 -0400
@@ -11,5 +11,6 @@
 int set_memory_ro(unsigned long addr, int numpages);
 int set_memory_rw(unsigned long addr, int numpages);
 int set_memory_nx(unsigned long addr, int numpages);
+int set_memory_x(unsigned long addr, int numpages);
 
 #endif /* _S390_CACHEFLUSH_H */
diff -druN linux-2.6.39-libre/arch/s390/include/asm/cmpxchg.h linux-3.0-rc7-libre/arch/s390/include/asm/cmpxchg.h
--- linux-2.6.39-libre/arch/s390/include/asm/cmpxchg.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/s390/include/asm/cmpxchg.h	2011-07-11 19:51:52.000000000 -0400
@@ -167,7 +167,6 @@
 #ifdef CONFIG_64BIT
 #define cmpxchg64(ptr, o, n)						\
 ({									\
-	BUILD_BUG_ON(sizeof(*(ptr)) != 8);				\
 	cmpxchg((ptr), (o), (n));					\
 })
 #else /* CONFIG_64BIT */
diff -druN linux-2.6.39-libre/arch/s390/include/asm/delay.h linux-3.0-rc7-libre/arch/s390/include/asm/delay.h
--- linux-2.6.39-libre/arch/s390/include/asm/delay.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/s390/include/asm/delay.h	2011-07-11 19:51:52.000000000 -0400
@@ -14,10 +14,12 @@
 #ifndef _S390_DELAY_H
 #define _S390_DELAY_H
 
-extern void __udelay(unsigned long long usecs);
-extern void udelay_simple(unsigned long long usecs);
-extern void __delay(unsigned long loops);
+void __ndelay(unsigned long long nsecs);
+void __udelay(unsigned long long usecs);
+void udelay_simple(unsigned long long usecs);
+void __delay(unsigned long loops);
 
+#define ndelay(n) __ndelay((unsigned long long) (n))
 #define udelay(n) __udelay((unsigned long long) (n))
 #define mdelay(n) __udelay((unsigned long long) (n) * 1000)
 
diff -druN linux-2.6.39-libre/arch/s390/include/asm/elf.h linux-3.0-rc7-libre/arch/s390/include/asm/elf.h
--- linux-2.6.39-libre/arch/s390/include/asm/elf.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/s390/include/asm/elf.h	2011-07-11 19:51:52.000000000 -0400
@@ -196,18 +196,6 @@
 } while (0)
 #endif /* __s390x__ */
 
-/*
- * An executable for which elf_read_implies_exec() returns TRUE will
- * have the READ_IMPLIES_EXEC personality flag set automatically.
- */
-#define elf_read_implies_exec(ex, executable_stack)	\
-({							\
-	if (current->mm->context.noexec &&		\
-	    executable_stack != EXSTACK_DISABLE_X)	\
-		disable_noexec(current->mm, current);	\
-	current->mm->context.noexec == 0;		\
-})
-
 #define STACK_RND_MASK	0x7ffUL
 
 #define ARCH_DLINFO							    \
diff -druN linux-2.6.39-libre/arch/s390/include/asm/ftrace.h linux-3.0-rc7-libre/arch/s390/include/asm/ftrace.h
--- linux-2.6.39-libre/arch/s390/include/asm/ftrace.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/s390/include/asm/ftrace.h	2011-07-11 19:51:52.000000000 -0400
@@ -11,15 +11,13 @@
 
 #ifdef CONFIG_64BIT
 #define MCOUNT_INSN_SIZE  12
-#define MCOUNT_OFFSET	   8
 #else
 #define MCOUNT_INSN_SIZE  20
-#define MCOUNT_OFFSET	   4
 #endif
 
 static inline unsigned long ftrace_call_adjust(unsigned long addr)
 {
-	return addr - MCOUNT_OFFSET;
+	return addr;
 }
 
 #endif /* __ASSEMBLY__ */
diff -druN linux-2.6.39-libre/arch/s390/include/asm/hugetlb.h linux-3.0-rc7-libre/arch/s390/include/asm/hugetlb.h
--- linux-2.6.39-libre/arch/s390/include/asm/hugetlb.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/s390/include/asm/hugetlb.h	2011-07-11 19:51:52.000000000 -0400
@@ -111,21 +111,10 @@
 {
 	pmd_t *pmdp = (pmd_t *) ptep;
 
-	if (!MACHINE_HAS_IDTE) {
-		__pmd_csp(pmdp);
-		if (mm->context.noexec) {
-			pmdp = get_shadow_table(pmdp);
-			__pmd_csp(pmdp);
-		}
-		return;
-	}
-
-	__pmd_idte(address, pmdp);
-	if (mm->context.noexec) {
-		pmdp = get_shadow_table(pmdp);
+	if (MACHINE_HAS_IDTE)
 		__pmd_idte(address, pmdp);
-	}
-	return;
+	else
+		__pmd_csp(pmdp);
 }
 
 #define huge_ptep_set_access_flags(__vma, __addr, __ptep, __entry, __dirty) \
diff -druN linux-2.6.39-libre/arch/s390/include/asm/irq.h linux-3.0-rc7-libre/arch/s390/include/asm/irq.h
--- linux-2.6.39-libre/arch/s390/include/asm/irq.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/s390/include/asm/irq.h	2011-07-11 19:51:52.000000000 -0400
@@ -2,6 +2,7 @@
 #define _ASM_IRQ_H
 
 #include <linux/hardirq.h>
+#include <linux/types.h>
 
 enum interruption_class {
 	EXTERNAL_INTERRUPT,
@@ -15,6 +16,7 @@
 	EXTINT_VRT,
 	EXTINT_SCP,
 	EXTINT_IUC,
+	EXTINT_CPM,
 	IOINT_QAI,
 	IOINT_QDI,
 	IOINT_DAS,
@@ -30,4 +32,11 @@
 	NR_IRQS,
 };
 
+typedef void (*ext_int_handler_t)(unsigned int, unsigned int, unsigned long);
+
+int register_external_interrupt(u16 code, ext_int_handler_t handler);
+int unregister_external_interrupt(u16 code, ext_int_handler_t handler);
+void service_subclass_irq_register(void);
+void service_subclass_irq_unregister(void);
+
 #endif /* _ASM_IRQ_H */
diff -druN linux-2.6.39-libre/arch/s390/include/asm/jump_label.h linux-3.0-rc7-libre/arch/s390/include/asm/jump_label.h
--- linux-2.6.39-libre/arch/s390/include/asm/jump_label.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/s390/include/asm/jump_label.h	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,37 @@
+#ifndef _ASM_S390_JUMP_LABEL_H
+#define _ASM_S390_JUMP_LABEL_H
+
+#include <linux/types.h>
+
+#define JUMP_LABEL_NOP_SIZE 6
+
+#ifdef CONFIG_64BIT
+#define ASM_PTR ".quad"
+#define ASM_ALIGN ".balign 8"
+#else
+#define ASM_PTR ".long"
+#define ASM_ALIGN ".balign 4"
+#endif
+
+static __always_inline bool arch_static_branch(struct jump_label_key *key)
+{
+	asm goto("0:	brcl 0,0\n"
+		".pushsection __jump_table, \"aw\"\n"
+		ASM_ALIGN "\n"
+		ASM_PTR " 0b, %l[label], %0\n"
+		".popsection\n"
+		: : "X" (key) : : label);
+	return false;
+label:
+	return true;
+}
+
+typedef unsigned long jump_label_t;
+
+struct jump_entry {
+	jump_label_t code;
+	jump_label_t target;
+	jump_label_t key;
+};
+
+#endif
diff -druN linux-2.6.39-libre/arch/s390/include/asm/lowcore.h linux-3.0-rc7-libre/arch/s390/include/asm/lowcore.h
--- linux-2.6.39-libre/arch/s390/include/asm/lowcore.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/s390/include/asm/lowcore.h	2011-07-11 19:51:52.000000000 -0400
@@ -124,7 +124,7 @@
 	/* Address space pointer. */
 	__u32	kernel_asce;			/* 0x02ac */
 	__u32	user_asce;			/* 0x02b0 */
-	__u32	user_exec_asce;			/* 0x02b4 */
+	__u32	current_pid;			/* 0x02b4 */
 
 	/* SMP info area */
 	__u32	cpu_nr;				/* 0x02b8 */
@@ -255,7 +255,7 @@
 	/* Address space pointer. */
 	__u64	kernel_asce;			/* 0x0310 */
 	__u64	user_asce;			/* 0x0318 */
-	__u64	user_exec_asce;			/* 0x0320 */
+	__u64	current_pid;			/* 0x0320 */
 
 	/* SMP info area */
 	__u32	cpu_nr;				/* 0x0328 */
diff -druN linux-2.6.39-libre/arch/s390/include/asm/mmu_context.h linux-3.0-rc7-libre/arch/s390/include/asm/mmu_context.h
--- linux-2.6.39-libre/arch/s390/include/asm/mmu_context.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/s390/include/asm/mmu_context.h	2011-07-11 19:51:52.000000000 -0400
@@ -35,11 +35,9 @@
 		 * and if has_pgste is set, it will create extended page
 		 * tables.
 		 */
-		mm->context.noexec = 0;
 		mm->context.has_pgste = 1;
 		mm->context.alloc_pgste = 1;
 	} else {
-		mm->context.noexec = (user_mode == SECONDARY_SPACE_MODE);
 		mm->context.has_pgste = 0;
 		mm->context.alloc_pgste = 0;
 	}
@@ -63,10 +61,8 @@
 	S390_lowcore.user_asce = mm->context.asce_bits | __pa(pgd);
 	if (user_mode != HOME_SPACE_MODE) {
 		/* Load primary space page table origin. */
-		pgd = mm->context.noexec ? get_shadow_table(pgd) : pgd;
-		S390_lowcore.user_exec_asce = mm->context.asce_bits | __pa(pgd);
 		asm volatile(LCTL_OPCODE" 1,1,%0\n"
-			     : : "m" (S390_lowcore.user_exec_asce) );
+			     : : "m" (S390_lowcore.user_asce) );
 	} else
 		/* Load home space page table origin. */
 		asm volatile(LCTL_OPCODE" 13,13,%0"
diff -druN linux-2.6.39-libre/arch/s390/include/asm/mmu.h linux-3.0-rc7-libre/arch/s390/include/asm/mmu.h
--- linux-2.6.39-libre/arch/s390/include/asm/mmu.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/s390/include/asm/mmu.h	2011-07-11 19:51:52.000000000 -0400
@@ -5,19 +5,18 @@
 	atomic_t attach_count;
 	unsigned int flush_mm;
 	spinlock_t list_lock;
-	struct list_head crst_list;
 	struct list_head pgtable_list;
 	unsigned long asce_bits;
 	unsigned long asce_limit;
 	unsigned long vdso_base;
-	int noexec;
-	int has_pgste;	 /* The mmu context has extended page tables */
-	int alloc_pgste; /* cloned contexts will have extended page tables */
+	/* Cloned contexts will be created with extended page tables. */
+	unsigned int alloc_pgste:1;
+	/* The mmu context has extended page tables. */
+	unsigned int has_pgste:1;
 } mm_context_t;
 
 #define INIT_MM_CONTEXT(name)						      \
 	.context.list_lock    = __SPIN_LOCK_UNLOCKED(name.context.list_lock), \
-	.context.crst_list    = LIST_HEAD_INIT(name.context.crst_list),	      \
 	.context.pgtable_list = LIST_HEAD_INIT(name.context.pgtable_list),
 
 #endif
diff -druN linux-2.6.39-libre/arch/s390/include/asm/page.h linux-3.0-rc7-libre/arch/s390/include/asm/page.h
--- linux-2.6.39-libre/arch/s390/include/asm/page.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/s390/include/asm/page.h	2011-07-11 19:51:52.000000000 -0400
@@ -90,6 +90,7 @@
  */
 
 typedef struct { unsigned long pgprot; } pgprot_t;
+typedef struct { unsigned long pgste; } pgste_t;
 typedef struct { unsigned long pte; } pte_t;
 typedef struct { unsigned long pmd; } pmd_t;
 typedef struct { unsigned long pud; } pud_t;
@@ -97,18 +98,21 @@
 typedef pte_t *pgtable_t;
 
 #define pgprot_val(x)	((x).pgprot)
+#define pgste_val(x)	((x).pgste)
 #define pte_val(x)	((x).pte)
 #define pmd_val(x)	((x).pmd)
 #define pud_val(x)	((x).pud)
 #define pgd_val(x)      ((x).pgd)
 
+#define __pgste(x)	((pgste_t) { (x) } )
 #define __pte(x)        ((pte_t) { (x) } )
 #define __pmd(x)        ((pmd_t) { (x) } )
+#define __pud(x)	((pud_t) { (x) } )
 #define __pgd(x)        ((pgd_t) { (x) } )
 #define __pgprot(x)     ((pgprot_t) { (x) } )
 
-static inline void
-page_set_storage_key(unsigned long addr, unsigned int skey, int mapped)
+static inline void page_set_storage_key(unsigned long addr,
+					unsigned char skey, int mapped)
 {
 	if (!mapped)
 		asm volatile(".insn rrf,0xb22b0000,%0,%1,8,0"
@@ -117,15 +121,59 @@
 		asm volatile("sske %0,%1" : : "d" (skey), "a" (addr));
 }
 
-static inline unsigned int
-page_get_storage_key(unsigned long addr)
+static inline unsigned char page_get_storage_key(unsigned long addr)
 {
-	unsigned int skey;
+	unsigned char skey;
 
-	asm volatile("iske %0,%1" : "=d" (skey) : "a" (addr), "0" (0));
+	asm volatile("iske %0,%1" : "=d" (skey) : "a" (addr));
 	return skey;
 }
 
+static inline int page_reset_referenced(unsigned long addr)
+{
+	unsigned int ipm;
+
+	asm volatile(
+		"	rrbe	0,%1\n"
+		"	ipm	%0\n"
+		: "=d" (ipm) : "a" (addr) : "cc");
+	return !!(ipm & 0x20000000);
+}
+
+/* Bits int the storage key */
+#define _PAGE_CHANGED		0x02	/* HW changed bit		*/
+#define _PAGE_REFERENCED	0x04	/* HW referenced bit		*/
+#define _PAGE_FP_BIT		0x08	/* HW fetch protection bit	*/
+#define _PAGE_ACC_BITS		0xf0	/* HW access control bits	*/
+
+/*
+ * Test and clear dirty bit in storage key.
+ * We can't clear the changed bit atomically. This is a potential
+ * race against modification of the referenced bit. This function
+ * should therefore only be called if it is not mapped in any
+ * address space.
+ */
+#define __HAVE_ARCH_PAGE_TEST_AND_CLEAR_DIRTY
+static inline int page_test_and_clear_dirty(unsigned long pfn, int mapped)
+{
+	unsigned char skey;
+
+	skey = page_get_storage_key(pfn << PAGE_SHIFT);
+	if (!(skey & _PAGE_CHANGED))
+		return 0;
+	page_set_storage_key(pfn << PAGE_SHIFT, skey & ~_PAGE_CHANGED, mapped);
+	return 1;
+}
+
+/*
+ * Test and clear referenced bit in storage key.
+ */
+#define __HAVE_ARCH_PAGE_TEST_AND_CLEAR_YOUNG
+static inline int page_test_and_clear_young(unsigned long pfn)
+{
+	return page_reset_referenced(pfn << PAGE_SHIFT);
+}
+
 struct page;
 void arch_free_page(struct page *page, int order);
 void arch_alloc_page(struct page *page, int order);
diff -druN linux-2.6.39-libre/arch/s390/include/asm/percpu.h linux-3.0-rc7-libre/arch/s390/include/asm/percpu.h
--- linux-2.6.39-libre/arch/s390/include/asm/percpu.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/s390/include/asm/percpu.h	2011-07-11 19:51:52.000000000 -0400
@@ -1,6 +1,9 @@
 #ifndef __ARCH_S390_PERCPU__
 #define __ARCH_S390_PERCPU__
 
+#include <linux/preempt.h>
+#include <asm/cmpxchg.h>
+
 /*
  * s390 uses its own implementation for per cpu data, the offset of
  * the cpu local data area is cached in the cpu's lowcore memory.
@@ -16,6 +19,71 @@
 #define ARCH_NEEDS_WEAK_PER_CPU
 #endif
 
+#define arch_irqsafe_cpu_to_op(pcp, val, op)				\
+do {									\
+	typedef typeof(pcp) pcp_op_T__;					\
+	pcp_op_T__ old__, new__, prev__;				\
+	pcp_op_T__ *ptr__;						\
+	preempt_disable();						\
+	ptr__ = __this_cpu_ptr(&(pcp));					\
+	prev__ = *ptr__;						\
+	do {								\
+		old__ = prev__;						\
+		new__ = old__ op (val);					\
+		switch (sizeof(*ptr__)) {				\
+		case 8:							\
+			prev__ = cmpxchg64(ptr__, old__, new__);	\
+			break;						\
+		default:						\
+			prev__ = cmpxchg(ptr__, old__, new__);		\
+		}							\
+	} while (prev__ != old__);					\
+	preempt_enable();						\
+} while (0)
+
+#define irqsafe_cpu_add_1(pcp, val) arch_irqsafe_cpu_to_op(pcp, val, +)
+#define irqsafe_cpu_add_2(pcp, val) arch_irqsafe_cpu_to_op(pcp, val, +)
+#define irqsafe_cpu_add_4(pcp, val) arch_irqsafe_cpu_to_op(pcp, val, +)
+#define irqsafe_cpu_add_8(pcp, val) arch_irqsafe_cpu_to_op(pcp, val, +)
+
+#define irqsafe_cpu_and_1(pcp, val) arch_irqsafe_cpu_to_op(pcp, val, &)
+#define irqsafe_cpu_and_2(pcp, val) arch_irqsafe_cpu_to_op(pcp, val, &)
+#define irqsafe_cpu_and_4(pcp, val) arch_irqsafe_cpu_to_op(pcp, val, &)
+#define irqsafe_cpu_and_8(pcp, val) arch_irqsafe_cpu_to_op(pcp, val, &)
+
+#define irqsafe_cpu_or_1(pcp, val) arch_irqsafe_cpu_to_op(pcp, val, |)
+#define irqsafe_cpu_or_2(pcp, val) arch_irqsafe_cpu_to_op(pcp, val, |)
+#define irqsafe_cpu_or_4(pcp, val) arch_irqsafe_cpu_to_op(pcp, val, |)
+#define irqsafe_cpu_or_8(pcp, val) arch_irqsafe_cpu_to_op(pcp, val, |)
+
+#define irqsafe_cpu_xor_1(pcp, val) arch_irqsafe_cpu_to_op(pcp, val, ^)
+#define irqsafe_cpu_xor_2(pcp, val) arch_irqsafe_cpu_to_op(pcp, val, ^)
+#define irqsafe_cpu_xor_4(pcp, val) arch_irqsafe_cpu_to_op(pcp, val, ^)
+#define irqsafe_cpu_xor_8(pcp, val) arch_irqsafe_cpu_to_op(pcp, val, ^)
+
+#define arch_irqsafe_cpu_cmpxchg(pcp, oval, nval)			\
+({									\
+	typedef typeof(pcp) pcp_op_T__;					\
+	pcp_op_T__ ret__;						\
+	pcp_op_T__ *ptr__;						\
+	preempt_disable();						\
+	ptr__ = __this_cpu_ptr(&(pcp));					\
+	switch (sizeof(*ptr__)) {					\
+	case 8:								\
+		ret__ = cmpxchg64(ptr__, oval, nval);			\
+		break;							\
+	default:							\
+		ret__ = cmpxchg(ptr__, oval, nval);			\
+	}								\
+	preempt_enable();						\
+	ret__;								\
+})
+
+#define irqsafe_cpu_cmpxchg_1(pcp, oval, nval) arch_irqsafe_cpu_cmpxchg(pcp, oval, nval)
+#define irqsafe_cpu_cmpxchg_2(pcp, oval, nval) arch_irqsafe_cpu_cmpxchg(pcp, oval, nval)
+#define irqsafe_cpu_cmpxchg_4(pcp, oval, nval) arch_irqsafe_cpu_cmpxchg(pcp, oval, nval)
+#define irqsafe_cpu_cmpxchg_8(pcp, oval, nval) arch_irqsafe_cpu_cmpxchg(pcp, oval, nval)
+
 #include <asm-generic/percpu.h>
 
 #endif /* __ARCH_S390_PERCPU__ */
diff -druN linux-2.6.39-libre/arch/s390/include/asm/pgalloc.h linux-3.0-rc7-libre/arch/s390/include/asm/pgalloc.h
--- linux-2.6.39-libre/arch/s390/include/asm/pgalloc.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/s390/include/asm/pgalloc.h	2011-07-11 19:51:52.000000000 -0400
@@ -17,16 +17,15 @@
 #include <linux/gfp.h>
 #include <linux/mm.h>
 
-#define check_pgt_cache()	do {} while (0)
-
-unsigned long *crst_table_alloc(struct mm_struct *, int);
+unsigned long *crst_table_alloc(struct mm_struct *);
 void crst_table_free(struct mm_struct *, unsigned long *);
-void crst_table_free_rcu(struct mm_struct *, unsigned long *);
 
 unsigned long *page_table_alloc(struct mm_struct *);
 void page_table_free(struct mm_struct *, unsigned long *);
-void page_table_free_rcu(struct mm_struct *, unsigned long *);
-void disable_noexec(struct mm_struct *, struct task_struct *);
+#ifdef CONFIG_HAVE_RCU_TABLE_FREE
+void page_table_free_rcu(struct mmu_gather *, unsigned long *);
+void __tlb_remove_table(void *_table);
+#endif
 
 static inline void clear_table(unsigned long *s, unsigned long val, size_t n)
 {
@@ -50,9 +49,6 @@
 static inline void crst_table_init(unsigned long *crst, unsigned long entry)
 {
 	clear_table(crst, entry, sizeof(unsigned long)*2048);
-	crst = get_shadow_table(crst);
-	if (crst)
-		clear_table(crst, entry, sizeof(unsigned long)*2048);
 }
 
 #ifndef __s390x__
@@ -69,10 +65,7 @@
 #define pmd_free(mm, x)				do { } while (0)
 
 #define pgd_populate(mm, pgd, pud)		BUG()
-#define pgd_populate_kernel(mm, pgd, pud)	BUG()
-
 #define pud_populate(mm, pud, pmd)		BUG()
-#define pud_populate_kernel(mm, pud, pmd)	BUG()
 
 #else /* __s390x__ */
 
@@ -90,7 +83,7 @@
 
 static inline pud_t *pud_alloc_one(struct mm_struct *mm, unsigned long address)
 {
-	unsigned long *table = crst_table_alloc(mm, mm->context.noexec);
+	unsigned long *table = crst_table_alloc(mm);
 	if (table)
 		crst_table_init(table, _REGION3_ENTRY_EMPTY);
 	return (pud_t *) table;
@@ -99,43 +92,21 @@
 
 static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long vmaddr)
 {
-	unsigned long *table = crst_table_alloc(mm, mm->context.noexec);
+	unsigned long *table = crst_table_alloc(mm);
 	if (table)
 		crst_table_init(table, _SEGMENT_ENTRY_EMPTY);
 	return (pmd_t *) table;
 }
 #define pmd_free(mm, pmd) crst_table_free(mm, (unsigned long *) pmd)
 
-static inline void pgd_populate_kernel(struct mm_struct *mm,
-				       pgd_t *pgd, pud_t *pud)
-{
-	pgd_val(*pgd) = _REGION2_ENTRY | __pa(pud);
-}
-
 static inline void pgd_populate(struct mm_struct *mm, pgd_t *pgd, pud_t *pud)
 {
-	pgd_populate_kernel(mm, pgd, pud);
-	if (mm->context.noexec) {
-		pgd = get_shadow_table(pgd);
-		pud = get_shadow_table(pud);
-		pgd_populate_kernel(mm, pgd, pud);
-	}
-}
-
-static inline void pud_populate_kernel(struct mm_struct *mm,
-				       pud_t *pud, pmd_t *pmd)
-{
-	pud_val(*pud) = _REGION3_ENTRY | __pa(pmd);
+	pgd_val(*pgd) = _REGION2_ENTRY | __pa(pud);
 }
 
 static inline void pud_populate(struct mm_struct *mm, pud_t *pud, pmd_t *pmd)
 {
-	pud_populate_kernel(mm, pud, pmd);
-	if (mm->context.noexec) {
-		pud = get_shadow_table(pud);
-		pmd = get_shadow_table(pmd);
-		pud_populate_kernel(mm, pud, pmd);
-	}
+	pud_val(*pud) = _REGION3_ENTRY | __pa(pmd);
 }
 
 #endif /* __s390x__ */
@@ -143,29 +114,19 @@
 static inline pgd_t *pgd_alloc(struct mm_struct *mm)
 {
 	spin_lock_init(&mm->context.list_lock);
-	INIT_LIST_HEAD(&mm->context.crst_list);
 	INIT_LIST_HEAD(&mm->context.pgtable_list);
-	return (pgd_t *)
-		crst_table_alloc(mm, user_mode == SECONDARY_SPACE_MODE);
+	return (pgd_t *) crst_table_alloc(mm);
 }
 #define pgd_free(mm, pgd) crst_table_free(mm, (unsigned long *) pgd)
 
-static inline void pmd_populate_kernel(struct mm_struct *mm,
-				       pmd_t *pmd, pte_t *pte)
-{
-	pmd_val(*pmd) = _SEGMENT_ENTRY + __pa(pte);
-}
-
 static inline void pmd_populate(struct mm_struct *mm,
 				pmd_t *pmd, pgtable_t pte)
 {
-	pmd_populate_kernel(mm, pmd, pte);
-	if (mm->context.noexec) {
-		pmd = get_shadow_table(pmd);
-		pmd_populate_kernel(mm, pmd, pte + PTRS_PER_PTE);
-	}
+	pmd_val(*pmd) = _SEGMENT_ENTRY + __pa(pte);
 }
 
+#define pmd_populate_kernel(mm, pmd, pte) pmd_populate(mm, pmd, pte)
+
 #define pmd_pgtable(pmd) \
 	(pgtable_t)(pmd_val(pmd) & -sizeof(pte_t)*PTRS_PER_PTE)
 
diff -druN linux-2.6.39-libre/arch/s390/include/asm/pgtable.h linux-3.0-rc7-libre/arch/s390/include/asm/pgtable.h
--- linux-2.6.39-libre/arch/s390/include/asm/pgtable.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/s390/include/asm/pgtable.h	2011-07-11 19:51:52.000000000 -0400
@@ -31,9 +31,8 @@
 #ifndef __ASSEMBLY__
 #include <linux/sched.h>
 #include <linux/mm_types.h>
-#include <asm/bitops.h>
 #include <asm/bug.h>
-#include <asm/processor.h>
+#include <asm/page.h>
 
 extern pgd_t swapper_pg_dir[] __attribute__ ((aligned (4096)));
 extern void paging_init(void);
@@ -243,11 +242,13 @@
 /* Software bits in the page table entry */
 #define _PAGE_SWT	0x001		/* SW pte type bit t */
 #define _PAGE_SWX	0x002		/* SW pte type bit x */
-#define _PAGE_SPECIAL	0x004		/* SW associated with special page */
+#define _PAGE_SWC	0x004		/* SW pte changed bit (for KVM) */
+#define _PAGE_SWR	0x008		/* SW pte referenced bit (for KVM) */
+#define _PAGE_SPECIAL	0x010		/* SW associated with special page */
 #define __HAVE_ARCH_PTE_SPECIAL
 
 /* Set of bits not changed in pte_modify */
-#define _PAGE_CHG_MASK	(PAGE_MASK | _PAGE_SPECIAL)
+#define _PAGE_CHG_MASK	(PAGE_MASK | _PAGE_SPECIAL | _PAGE_SWC | _PAGE_SWR)
 
 /* Six different types of pages. */
 #define _PAGE_TYPE_EMPTY	0x400
@@ -256,8 +257,6 @@
 #define _PAGE_TYPE_FILE		0x601	/* bit 0x002 is used for offset !! */
 #define _PAGE_TYPE_RO		0x200
 #define _PAGE_TYPE_RW		0x000
-#define _PAGE_TYPE_EX_RO	0x202
-#define _PAGE_TYPE_EX_RW	0x002
 
 /*
  * Only four types for huge pages, using the invalid bit and protection bit
@@ -287,8 +286,6 @@
  * _PAGE_TYPE_FILE	11?1   ->   11?1
  * _PAGE_TYPE_RO	0100   ->   1100
  * _PAGE_TYPE_RW	0000   ->   1000
- * _PAGE_TYPE_EX_RO	0110   ->   1110
- * _PAGE_TYPE_EX_RW	0010   ->   1010
  *
  * pte_none is true for bits combinations 1000, 1010, 1100, 1110
  * pte_present is true for bits combinations 0000, 0010, 0100, 0110, 1001
@@ -296,16 +293,6 @@
  * swap pte is 1011 and 0001, 0011, 0101, 0111 are invalid.
  */
 
-/* Page status table bits for virtualization */
-#define RCP_PCL_BIT	55
-#define RCP_HR_BIT	54
-#define RCP_HC_BIT	53
-#define RCP_GR_BIT	50
-#define RCP_GC_BIT	49
-
-/* User dirty bit for KVM's migration feature */
-#define KVM_UD_BIT	47
-
 #ifndef __s390x__
 
 /* Bits in the segment table address-space-control-element */
@@ -325,6 +312,19 @@
 #define _SEGMENT_ENTRY		(_SEGMENT_ENTRY_PTL)
 #define _SEGMENT_ENTRY_EMPTY	(_SEGMENT_ENTRY_INV)
 
+/* Page status table bits for virtualization */
+#define RCP_ACC_BITS	0xf0000000UL
+#define RCP_FP_BIT	0x08000000UL
+#define RCP_PCL_BIT	0x00800000UL
+#define RCP_HR_BIT	0x00400000UL
+#define RCP_HC_BIT	0x00200000UL
+#define RCP_GR_BIT	0x00040000UL
+#define RCP_GC_BIT	0x00020000UL
+
+/* User dirty / referenced bit for KVM's migration feature */
+#define KVM_UR_BIT	0x00008000UL
+#define KVM_UC_BIT	0x00004000UL
+
 #else /* __s390x__ */
 
 /* Bits in the segment/region table address-space-control-element */
@@ -367,6 +367,19 @@
 #define _SEGMENT_ENTRY_LARGE	0x400	/* STE-format control, large page   */
 #define _SEGMENT_ENTRY_CO	0x100	/* change-recording override   */
 
+/* Page status table bits for virtualization */
+#define RCP_ACC_BITS	0xf000000000000000UL
+#define RCP_FP_BIT	0x0800000000000000UL
+#define RCP_PCL_BIT	0x0080000000000000UL
+#define RCP_HR_BIT	0x0040000000000000UL
+#define RCP_HC_BIT	0x0020000000000000UL
+#define RCP_GR_BIT	0x0004000000000000UL
+#define RCP_GC_BIT	0x0002000000000000UL
+
+/* User dirty / referenced bit for KVM's migration feature */
+#define KVM_UR_BIT	0x0000800000000000UL
+#define KVM_UC_BIT	0x0000400000000000UL
+
 #endif /* __s390x__ */
 
 /*
@@ -377,85 +390,54 @@
 #define _ASCE_USER_BITS		(_ASCE_SPACE_SWITCH | _ASCE_PRIVATE_SPACE | \
 				 _ASCE_ALT_EVENT)
 
-/* Bits int the storage key */
-#define _PAGE_CHANGED    0x02          /* HW changed bit                   */
-#define _PAGE_REFERENCED 0x04          /* HW referenced bit                */
-
 /*
  * Page protection definitions.
  */
 #define PAGE_NONE	__pgprot(_PAGE_TYPE_NONE)
 #define PAGE_RO		__pgprot(_PAGE_TYPE_RO)
 #define PAGE_RW		__pgprot(_PAGE_TYPE_RW)
-#define PAGE_EX_RO	__pgprot(_PAGE_TYPE_EX_RO)
-#define PAGE_EX_RW	__pgprot(_PAGE_TYPE_EX_RW)
 
 #define PAGE_KERNEL	PAGE_RW
 #define PAGE_COPY	PAGE_RO
 
 /*
- * Dependent on the EXEC_PROTECT option s390 can do execute protection.
- * Write permission always implies read permission. In theory with a
- * primary/secondary page table execute only can be implemented but
- * it would cost an additional bit in the pte to distinguish all the
- * different pte types. To avoid that execute permission currently
- * implies read permission as well.
+ * On s390 the page table entry has an invalid bit and a read-only bit.
+ * Read permission implies execute permission and write permission
+ * implies read permission.
  */
          /*xwr*/
 #define __P000	PAGE_NONE
 #define __P001	PAGE_RO
 #define __P010	PAGE_RO
 #define __P011	PAGE_RO
-#define __P100	PAGE_EX_RO
-#define __P101	PAGE_EX_RO
-#define __P110	PAGE_EX_RO
-#define __P111	PAGE_EX_RO
+#define __P100	PAGE_RO
+#define __P101	PAGE_RO
+#define __P110	PAGE_RO
+#define __P111	PAGE_RO
 
 #define __S000	PAGE_NONE
 #define __S001	PAGE_RO
 #define __S010	PAGE_RW
 #define __S011	PAGE_RW
-#define __S100	PAGE_EX_RO
-#define __S101	PAGE_EX_RO
-#define __S110	PAGE_EX_RW
-#define __S111	PAGE_EX_RW
-
-#ifndef __s390x__
-# define PxD_SHADOW_SHIFT	1
-#else /* __s390x__ */
-# define PxD_SHADOW_SHIFT	2
-#endif /* __s390x__ */
+#define __S100	PAGE_RO
+#define __S101	PAGE_RO
+#define __S110	PAGE_RW
+#define __S111	PAGE_RW
 
-static inline void *get_shadow_table(void *table)
+static inline int mm_exclusive(struct mm_struct *mm)
 {
-	unsigned long addr, offset;
-	struct page *page;
-
-	addr = (unsigned long) table;
-	offset = addr & ((PAGE_SIZE << PxD_SHADOW_SHIFT) - 1);
-	page = virt_to_page((void *)(addr ^ offset));
-	return (void *)(addr_t)(page->index ? (page->index | offset) : 0UL);
+	return likely(mm == current->active_mm &&
+		      atomic_read(&mm->context.attach_count) <= 1);
 }
 
-/*
- * Certain architectures need to do special things when PTEs
- * within a page table are directly modified.  Thus, the following
- * hook is made available.
- */
-static inline void set_pte_at(struct mm_struct *mm, unsigned long addr,
-			      pte_t *ptep, pte_t entry)
+static inline int mm_has_pgste(struct mm_struct *mm)
 {
-	*ptep = entry;
-	if (mm->context.noexec) {
-		if (!(pte_val(entry) & _PAGE_INVALID) &&
-		    (pte_val(entry) & _PAGE_SWX))
-			pte_val(entry) |= _PAGE_RO;
-		else
-			pte_val(entry) = _PAGE_TYPE_EMPTY;
-		ptep[PTRS_PER_PTE] = entry;
-	}
+#ifdef CONFIG_PGSTE
+	if (unlikely(mm->context.has_pgste))
+		return 1;
+#endif
+	return 0;
 }
-
 /*
  * pgd/pmd/pte query functions
  */
@@ -568,55 +550,130 @@
 }
 
 #define __HAVE_ARCH_PTE_SAME
-#define pte_same(a,b)  (pte_val(a) == pte_val(b))
+static inline int pte_same(pte_t a, pte_t b)
+{
+	return pte_val(a) == pte_val(b);
+}
 
-static inline void rcp_lock(pte_t *ptep)
+static inline pgste_t pgste_get_lock(pte_t *ptep)
 {
+	unsigned long new = 0;
 #ifdef CONFIG_PGSTE
-	unsigned long *pgste = (unsigned long *) (ptep + PTRS_PER_PTE);
+	unsigned long old;
+
 	preempt_disable();
-	while (test_and_set_bit(RCP_PCL_BIT, pgste))
-		;
+	asm(
+		"	lg	%0,%2\n"
+		"0:	lgr	%1,%0\n"
+		"	nihh	%0,0xff7f\n"	/* clear RCP_PCL_BIT in old */
+		"	oihh	%1,0x0080\n"	/* set RCP_PCL_BIT in new */
+		"	csg	%0,%1,%2\n"
+		"	jl	0b\n"
+		: "=&d" (old), "=&d" (new), "=Q" (ptep[PTRS_PER_PTE])
+		: "Q" (ptep[PTRS_PER_PTE]) : "cc");
 #endif
+	return __pgste(new);
 }
 
-static inline void rcp_unlock(pte_t *ptep)
+static inline void pgste_set_unlock(pte_t *ptep, pgste_t pgste)
 {
 #ifdef CONFIG_PGSTE
-	unsigned long *pgste = (unsigned long *) (ptep + PTRS_PER_PTE);
-	clear_bit(RCP_PCL_BIT, pgste);
+	asm(
+		"	nihh	%1,0xff7f\n"	/* clear RCP_PCL_BIT */
+		"	stg	%1,%0\n"
+		: "=Q" (ptep[PTRS_PER_PTE])
+		: "d" (pgste_val(pgste)), "Q" (ptep[PTRS_PER_PTE]) : "cc");
 	preempt_enable();
 #endif
 }
 
-/* forward declaration for SetPageUptodate in page-flags.h*/
-static inline void page_clear_dirty(struct page *page, int mapped);
-#include <linux/page-flags.h>
-
-static inline void ptep_rcp_copy(pte_t *ptep)
+static inline pgste_t pgste_update_all(pte_t *ptep, pgste_t pgste)
 {
 #ifdef CONFIG_PGSTE
-	struct page *page = virt_to_page(pte_val(*ptep));
-	unsigned int skey;
-	unsigned long *pgste = (unsigned long *) (ptep + PTRS_PER_PTE);
+	unsigned long address, bits;
+	unsigned char skey;
 
-	skey = page_get_storage_key(page_to_phys(page));
-	if (skey & _PAGE_CHANGED) {
-		set_bit_simple(RCP_GC_BIT, pgste);
-		set_bit_simple(KVM_UD_BIT, pgste);
-	}
-	if (skey & _PAGE_REFERENCED)
-		set_bit_simple(RCP_GR_BIT, pgste);
-	if (test_and_clear_bit_simple(RCP_HC_BIT, pgste)) {
-		SetPageDirty(page);
-		set_bit_simple(KVM_UD_BIT, pgste);
+	address = pte_val(*ptep) & PAGE_MASK;
+	skey = page_get_storage_key(address);
+	bits = skey & (_PAGE_CHANGED | _PAGE_REFERENCED);
+	/* Clear page changed & referenced bit in the storage key */
+	if (bits) {
+		skey ^= bits;
+		page_set_storage_key(address, skey, 1);
 	}
-	if (test_and_clear_bit_simple(RCP_HR_BIT, pgste))
-		SetPageReferenced(page);
+	/* Transfer page changed & referenced bit to guest bits in pgste */
+	pgste_val(pgste) |= bits << 48;		/* RCP_GR_BIT & RCP_GC_BIT */
+	/* Get host changed & referenced bits from pgste */
+	bits |= (pgste_val(pgste) & (RCP_HR_BIT | RCP_HC_BIT)) >> 52;
+	/* Clear host bits in pgste. */
+	pgste_val(pgste) &= ~(RCP_HR_BIT | RCP_HC_BIT);
+	pgste_val(pgste) &= ~(RCP_ACC_BITS | RCP_FP_BIT);
+	/* Copy page access key and fetch protection bit to pgste */
+	pgste_val(pgste) |=
+		(unsigned long) (skey & (_PAGE_ACC_BITS | _PAGE_FP_BIT)) << 56;
+	/* Transfer changed and referenced to kvm user bits */
+	pgste_val(pgste) |= bits << 45;		/* KVM_UR_BIT & KVM_UC_BIT */
+	/* Transfer changed & referenced to pte sofware bits */
+	pte_val(*ptep) |= bits << 1;		/* _PAGE_SWR & _PAGE_SWC */
+#endif
+	return pgste;
+
+}
+
+static inline pgste_t pgste_update_young(pte_t *ptep, pgste_t pgste)
+{
+#ifdef CONFIG_PGSTE
+	int young;
+
+	young = page_reset_referenced(pte_val(*ptep) & PAGE_MASK);
+	/* Transfer page referenced bit to pte software bit (host view) */
+	if (young || (pgste_val(pgste) & RCP_HR_BIT))
+		pte_val(*ptep) |= _PAGE_SWR;
+	/* Clear host referenced bit in pgste. */
+	pgste_val(pgste) &= ~RCP_HR_BIT;
+	/* Transfer page referenced bit to guest bit in pgste */
+	pgste_val(pgste) |= (unsigned long) young << 50; /* set RCP_GR_BIT */
+#endif
+	return pgste;
+
+}
+
+static inline void pgste_set_pte(pte_t *ptep, pgste_t pgste)
+{
+#ifdef CONFIG_PGSTE
+	unsigned long address;
+	unsigned long okey, nkey;
+
+	address = pte_val(*ptep) & PAGE_MASK;
+	okey = nkey = page_get_storage_key(address);
+	nkey &= ~(_PAGE_ACC_BITS | _PAGE_FP_BIT);
+	/* Set page access key and fetch protection bit from pgste */
+	nkey |= (pgste_val(pgste) & (RCP_ACC_BITS | RCP_FP_BIT)) >> 56;
+	if (okey != nkey)
+		page_set_storage_key(address, nkey, 1);
 #endif
 }
 
 /*
+ * Certain architectures need to do special things when PTEs
+ * within a page table are directly modified.  Thus, the following
+ * hook is made available.
+ */
+static inline void set_pte_at(struct mm_struct *mm, unsigned long addr,
+			      pte_t *ptep, pte_t entry)
+{
+	pgste_t pgste;
+
+	if (mm_has_pgste(mm)) {
+		pgste = pgste_get_lock(ptep);
+		pgste_set_pte(ptep, pgste);
+		*ptep = entry;
+		pgste_set_unlock(ptep, pgste);
+	} else
+		*ptep = entry;
+}
+
+/*
  * query functions pte_write/pte_dirty/pte_young only work if
  * pte_present() is true. Undefined behaviour if not..
  */
@@ -627,19 +684,19 @@
 
 static inline int pte_dirty(pte_t pte)
 {
-	/* A pte is neither clean nor dirty on s/390. The dirty bit
-	 * is in the storage key. See page_test_and_clear_dirty for
-	 * details.
-	 */
+#ifdef CONFIG_PGSTE
+	if (pte_val(pte) & _PAGE_SWC)
+		return 1;
+#endif
 	return 0;
 }
 
 static inline int pte_young(pte_t pte)
 {
-	/* A pte is neither young nor old on s/390. The young bit
-	 * is in the storage key. See page_test_and_clear_young for
-	 * details.
-	 */
+#ifdef CONFIG_PGSTE
+	if (pte_val(pte) & _PAGE_SWR)
+		return 1;
+#endif
 	return 0;
 }
 
@@ -647,64 +704,30 @@
  * pgd/pmd/pte modification functions
  */
 
-#ifndef __s390x__
-
-#define pgd_clear(pgd)		do { } while (0)
-#define pud_clear(pud)		do { } while (0)
-
-#else /* __s390x__ */
-
-static inline void pgd_clear_kernel(pgd_t * pgd)
+static inline void pgd_clear(pgd_t *pgd)
 {
+#ifdef __s390x__
 	if ((pgd_val(*pgd) & _REGION_ENTRY_TYPE_MASK) == _REGION_ENTRY_TYPE_R2)
 		pgd_val(*pgd) = _REGION2_ENTRY_EMPTY;
+#endif
 }
 
-static inline void pgd_clear(pgd_t * pgd)
-{
-	pgd_t *shadow = get_shadow_table(pgd);
-
-	pgd_clear_kernel(pgd);
-	if (shadow)
-		pgd_clear_kernel(shadow);
-}
-
-static inline void pud_clear_kernel(pud_t *pud)
+static inline void pud_clear(pud_t *pud)
 {
+#ifdef __s390x__
 	if ((pud_val(*pud) & _REGION_ENTRY_TYPE_MASK) == _REGION_ENTRY_TYPE_R3)
 		pud_val(*pud) = _REGION3_ENTRY_EMPTY;
+#endif
 }
 
-static inline void pud_clear(pud_t *pud)
-{
-	pud_t *shadow = get_shadow_table(pud);
-
-	pud_clear_kernel(pud);
-	if (shadow)
-		pud_clear_kernel(shadow);
-}
-
-#endif /* __s390x__ */
-
-static inline void pmd_clear_kernel(pmd_t * pmdp)
+static inline void pmd_clear(pmd_t *pmdp)
 {
 	pmd_val(*pmdp) = _SEGMENT_ENTRY_EMPTY;
 }
 
-static inline void pmd_clear(pmd_t *pmd)
-{
-	pmd_t *shadow = get_shadow_table(pmd);
-
-	pmd_clear_kernel(pmd);
-	if (shadow)
-		pmd_clear_kernel(shadow);
-}
-
 static inline void pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
 {
 	pte_val(*ptep) = _PAGE_TYPE_EMPTY;
-	if (mm->context.noexec)
-		pte_val(ptep[PTRS_PER_PTE]) = _PAGE_TYPE_EMPTY;
 }
 
 /*
@@ -734,35 +757,27 @@
 
 static inline pte_t pte_mkclean(pte_t pte)
 {
-	/* The only user of pte_mkclean is the fork() code.
-	   We must *not* clear the *physical* page dirty bit
-	   just because fork() wants to clear the dirty bit in
-	   *one* of the page's mappings.  So we just do nothing. */
+#ifdef CONFIG_PGSTE
+	pte_val(pte) &= ~_PAGE_SWC;
+#endif
 	return pte;
 }
 
 static inline pte_t pte_mkdirty(pte_t pte)
 {
-	/* We do not explicitly set the dirty bit because the
-	 * sske instruction is slow. It is faster to let the
-	 * next instruction set the dirty bit.
-	 */
 	return pte;
 }
 
 static inline pte_t pte_mkold(pte_t pte)
 {
-	/* S/390 doesn't keep its dirty/referenced bit in the pte.
-	 * There is no point in clearing the real referenced bit.
-	 */
+#ifdef CONFIG_PGSTE
+	pte_val(pte) &= ~_PAGE_SWR;
+#endif
 	return pte;
 }
 
 static inline pte_t pte_mkyoung(pte_t pte)
 {
-	/* S/390 doesn't keep its dirty/referenced bit in the pte.
-	 * There is no point in setting the real referenced bit.
-	 */
 	return pte;
 }
 
@@ -800,62 +815,60 @@
 }
 #endif
 
-#ifdef CONFIG_PGSTE
 /*
- * Get (and clear) the user dirty bit for a PTE.
+ * Get (and clear) the user dirty bit for a pte.
  */
-static inline int kvm_s390_test_and_clear_page_dirty(struct mm_struct *mm,
-						     pte_t *ptep)
+static inline int ptep_test_and_clear_user_dirty(struct mm_struct *mm,
+						 pte_t *ptep)
 {
-	int dirty;
-	unsigned long *pgste;
-	struct page *page;
-	unsigned int skey;
+	pgste_t pgste;
+	int dirty = 0;
 
-	if (!mm->context.has_pgste)
-		return -EINVAL;
-	rcp_lock(ptep);
-	pgste = (unsigned long *) (ptep + PTRS_PER_PTE);
-	page = virt_to_page(pte_val(*ptep));
-	skey = page_get_storage_key(page_to_phys(page));
-	if (skey & _PAGE_CHANGED) {
-		set_bit_simple(RCP_GC_BIT, pgste);
-		set_bit_simple(KVM_UD_BIT, pgste);
-	}
-	if (test_and_clear_bit_simple(RCP_HC_BIT, pgste)) {
-		SetPageDirty(page);
-		set_bit_simple(KVM_UD_BIT, pgste);
+	if (mm_has_pgste(mm)) {
+		pgste = pgste_get_lock(ptep);
+		pgste = pgste_update_all(ptep, pgste);
+		dirty = !!(pgste_val(pgste) & KVM_UC_BIT);
+		pgste_val(pgste) &= ~KVM_UC_BIT;
+		pgste_set_unlock(ptep, pgste);
+		return dirty;
 	}
-	dirty = test_and_clear_bit_simple(KVM_UD_BIT, pgste);
-	if (skey & _PAGE_CHANGED)
-		page_clear_dirty(page, 1);
-	rcp_unlock(ptep);
 	return dirty;
 }
-#endif
+
+/*
+ * Get (and clear) the user referenced bit for a pte.
+ */
+static inline int ptep_test_and_clear_user_young(struct mm_struct *mm,
+						 pte_t *ptep)
+{
+	pgste_t pgste;
+	int young = 0;
+
+	if (mm_has_pgste(mm)) {
+		pgste = pgste_get_lock(ptep);
+		pgste = pgste_update_young(ptep, pgste);
+		young = !!(pgste_val(pgste) & KVM_UR_BIT);
+		pgste_val(pgste) &= ~KVM_UR_BIT;
+		pgste_set_unlock(ptep, pgste);
+	}
+	return young;
+}
 
 #define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_YOUNG
 static inline int ptep_test_and_clear_young(struct vm_area_struct *vma,
 					    unsigned long addr, pte_t *ptep)
 {
-#ifdef CONFIG_PGSTE
-	unsigned long physpage;
-	int young;
-	unsigned long *pgste;
-
-	if (!vma->vm_mm->context.has_pgste)
-		return 0;
-	physpage = pte_val(*ptep) & PAGE_MASK;
-	pgste = (unsigned long *) (ptep + PTRS_PER_PTE);
+	pgste_t pgste;
+	pte_t pte;
 
-	young = ((page_get_storage_key(physpage) & _PAGE_REFERENCED) != 0);
-	rcp_lock(ptep);
-	if (young)
-		set_bit_simple(RCP_GR_BIT, pgste);
-	young |= test_and_clear_bit_simple(RCP_HR_BIT, pgste);
-	rcp_unlock(ptep);
-	return young;
-#endif
+	if (mm_has_pgste(vma->vm_mm)) {
+		pgste = pgste_get_lock(ptep);
+		pgste = pgste_update_young(ptep, pgste);
+		pte = *ptep;
+		*ptep = pte_mkold(pte);
+		pgste_set_unlock(ptep, pgste);
+		return pte_young(pte);
+	}
 	return 0;
 }
 
@@ -867,10 +880,7 @@
 	 * On s390 reference bits are in storage key and never in TLB
 	 * With virtualization we handle the reference bit, without we
 	 * we can simply return */
-#ifdef CONFIG_PGSTE
 	return ptep_test_and_clear_young(vma, address, ptep);
-#endif
-	return 0;
 }
 
 static inline void __ptep_ipte(unsigned long address, pte_t *ptep)
@@ -890,25 +900,6 @@
 	}
 }
 
-static inline void ptep_invalidate(struct mm_struct *mm,
-				   unsigned long address, pte_t *ptep)
-{
-	if (mm->context.has_pgste) {
-		rcp_lock(ptep);
-		__ptep_ipte(address, ptep);
-		ptep_rcp_copy(ptep);
-		pte_val(*ptep) = _PAGE_TYPE_EMPTY;
-		rcp_unlock(ptep);
-		return;
-	}
-	__ptep_ipte(address, ptep);
-	pte_val(*ptep) = _PAGE_TYPE_EMPTY;
-	if (mm->context.noexec) {
-		__ptep_ipte(address, ptep + PTRS_PER_PTE);
-		pte_val(*(ptep + PTRS_PER_PTE)) = _PAGE_TYPE_EMPTY;
-	}
-}
-
 /*
  * This is hard to understand. ptep_get_and_clear and ptep_clear_flush
  * both clear the TLB for the unmapped pte. The reason is that
@@ -923,24 +914,72 @@
  * is a nop.
  */
 #define __HAVE_ARCH_PTEP_GET_AND_CLEAR
-#define ptep_get_and_clear(__mm, __address, __ptep)			\
-({									\
-	pte_t __pte = *(__ptep);					\
-	(__mm)->context.flush_mm = 1;					\
-	if (atomic_read(&(__mm)->context.attach_count) > 1 ||		\
-	    (__mm) != current->active_mm)				\
-		ptep_invalidate(__mm, __address, __ptep);		\
-	else								\
-		pte_clear((__mm), (__address), (__ptep));		\
-	__pte;								\
-})
+static inline pte_t ptep_get_and_clear(struct mm_struct *mm,
+				       unsigned long address, pte_t *ptep)
+{
+	pgste_t pgste;
+	pte_t pte;
+
+	mm->context.flush_mm = 1;
+	if (mm_has_pgste(mm))
+		pgste = pgste_get_lock(ptep);
+
+	pte = *ptep;
+	if (!mm_exclusive(mm))
+		__ptep_ipte(address, ptep);
+	pte_val(*ptep) = _PAGE_TYPE_EMPTY;
+
+	if (mm_has_pgste(mm)) {
+		pgste = pgste_update_all(&pte, pgste);
+		pgste_set_unlock(ptep, pgste);
+	}
+	return pte;
+}
+
+#define __HAVE_ARCH_PTEP_MODIFY_PROT_TRANSACTION
+static inline pte_t ptep_modify_prot_start(struct mm_struct *mm,
+					   unsigned long address,
+					   pte_t *ptep)
+{
+	pte_t pte;
+
+	mm->context.flush_mm = 1;
+	if (mm_has_pgste(mm))
+		pgste_get_lock(ptep);
+
+	pte = *ptep;
+	if (!mm_exclusive(mm))
+		__ptep_ipte(address, ptep);
+	return pte;
+}
+
+static inline void ptep_modify_prot_commit(struct mm_struct *mm,
+					   unsigned long address,
+					   pte_t *ptep, pte_t pte)
+{
+	*ptep = pte;
+	if (mm_has_pgste(mm))
+		pgste_set_unlock(ptep, *(pgste_t *)(ptep + PTRS_PER_PTE));
+}
 
 #define __HAVE_ARCH_PTEP_CLEAR_FLUSH
 static inline pte_t ptep_clear_flush(struct vm_area_struct *vma,
 				     unsigned long address, pte_t *ptep)
 {
-	pte_t pte = *ptep;
-	ptep_invalidate(vma->vm_mm, address, ptep);
+	pgste_t pgste;
+	pte_t pte;
+
+	if (mm_has_pgste(vma->vm_mm))
+		pgste = pgste_get_lock(ptep);
+
+	pte = *ptep;
+	__ptep_ipte(address, ptep);
+	pte_val(*ptep) = _PAGE_TYPE_EMPTY;
+
+	if (mm_has_pgste(vma->vm_mm)) {
+		pgste = pgste_update_all(&pte, pgste);
+		pgste_set_unlock(ptep, pgste);
+	}
 	return pte;
 }
 
@@ -953,76 +992,67 @@
  */
 #define __HAVE_ARCH_PTEP_GET_AND_CLEAR_FULL
 static inline pte_t ptep_get_and_clear_full(struct mm_struct *mm,
-					    unsigned long addr,
+					    unsigned long address,
 					    pte_t *ptep, int full)
 {
-	pte_t pte = *ptep;
+	pgste_t pgste;
+	pte_t pte;
 
-	if (full)
-		pte_clear(mm, addr, ptep);
-	else
-		ptep_invalidate(mm, addr, ptep);
+	if (mm_has_pgste(mm))
+		pgste = pgste_get_lock(ptep);
+
+	pte = *ptep;
+	if (!full)
+		__ptep_ipte(address, ptep);
+	pte_val(*ptep) = _PAGE_TYPE_EMPTY;
+
+	if (mm_has_pgste(mm)) {
+		pgste = pgste_update_all(&pte, pgste);
+		pgste_set_unlock(ptep, pgste);
+	}
 	return pte;
 }
 
 #define __HAVE_ARCH_PTEP_SET_WRPROTECT
-#define ptep_set_wrprotect(__mm, __addr, __ptep)			\
-({									\
-	pte_t __pte = *(__ptep);					\
-	if (pte_write(__pte)) {						\
-		(__mm)->context.flush_mm = 1;				\
-		if (atomic_read(&(__mm)->context.attach_count) > 1 ||	\
-		    (__mm) != current->active_mm)			\
-			ptep_invalidate(__mm, __addr, __ptep);		\
-		set_pte_at(__mm, __addr, __ptep, pte_wrprotect(__pte));	\
-	}								\
-})
+static inline pte_t ptep_set_wrprotect(struct mm_struct *mm,
+				       unsigned long address, pte_t *ptep)
+{
+	pgste_t pgste;
+	pte_t pte = *ptep;
 
-#define __HAVE_ARCH_PTEP_SET_ACCESS_FLAGS
-#define ptep_set_access_flags(__vma, __addr, __ptep, __entry, __dirty)	\
-({									\
-	int __changed = !pte_same(*(__ptep), __entry);			\
-	if (__changed) {						\
-		ptep_invalidate((__vma)->vm_mm, __addr, __ptep);	\
-		set_pte_at((__vma)->vm_mm, __addr, __ptep, __entry);	\
-	}								\
-	__changed;							\
-})
+	if (pte_write(pte)) {
+		mm->context.flush_mm = 1;
+		if (mm_has_pgste(mm))
+			pgste = pgste_get_lock(ptep);
 
-/*
- * Test and clear dirty bit in storage key.
- * We can't clear the changed bit atomically. This is a potential
- * race against modification of the referenced bit. This function
- * should therefore only be called if it is not mapped in any
- * address space.
- */
-#define __HAVE_ARCH_PAGE_TEST_DIRTY
-static inline int page_test_dirty(struct page *page)
-{
-	return (page_get_storage_key(page_to_phys(page)) & _PAGE_CHANGED) != 0;
-}
+		if (!mm_exclusive(mm))
+			__ptep_ipte(address, ptep);
+		*ptep = pte_wrprotect(pte);
 
-#define __HAVE_ARCH_PAGE_CLEAR_DIRTY
-static inline void page_clear_dirty(struct page *page, int mapped)
-{
-	page_set_storage_key(page_to_phys(page), PAGE_DEFAULT_KEY, mapped);
+		if (mm_has_pgste(mm))
+			pgste_set_unlock(ptep, pgste);
+	}
+	return pte;
 }
 
-/*
- * Test and clear referenced bit in storage key.
- */
-#define __HAVE_ARCH_PAGE_TEST_AND_CLEAR_YOUNG
-static inline int page_test_and_clear_young(struct page *page)
+#define __HAVE_ARCH_PTEP_SET_ACCESS_FLAGS
+static inline int ptep_set_access_flags(struct vm_area_struct *vma,
+					unsigned long address, pte_t *ptep,
+					pte_t entry, int dirty)
 {
-	unsigned long physpage = page_to_phys(page);
-	int ccode;
+	pgste_t pgste;
 
-	asm volatile(
-		"	rrbe	0,%1\n"
-		"	ipm	%0\n"
-		"	srl	%0,28\n"
-		: "=d" (ccode) : "a" (physpage) : "cc" );
-	return ccode & 2;
+	if (pte_same(*ptep, entry))
+		return 0;
+	if (mm_has_pgste(vma->vm_mm))
+		pgste = pgste_get_lock(ptep);
+
+	__ptep_ipte(address, ptep);
+	*ptep = entry;
+
+	if (mm_has_pgste(vma->vm_mm))
+		pgste_set_unlock(ptep, pgste);
+	return 1;
 }
 
 /*
diff -druN linux-2.6.39-libre/arch/s390/include/asm/processor.h linux-3.0-rc7-libre/arch/s390/include/asm/processor.h
--- linux-2.6.39-libre/arch/s390/include/asm/processor.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/s390/include/asm/processor.h	2011-07-11 19:51:52.000000000 -0400
@@ -84,6 +84,7 @@
 	struct per_event per_event;	/* Cause of the last PER trap */
         /* pfault_wait is used to block the process on a pfault event */
 	unsigned long pfault_wait;
+	struct list_head list;
 };
 
 typedef struct thread_struct thread_struct;
diff -druN linux-2.6.39-libre/arch/s390/include/asm/qdio.h linux-3.0-rc7-libre/arch/s390/include/asm/qdio.h
--- linux-2.6.39-libre/arch/s390/include/asm/qdio.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/s390/include/asm/qdio.h	2011-07-11 19:51:52.000000000 -0400
@@ -139,110 +139,47 @@
 	struct slibe slibe[QDIO_MAX_BUFFERS_PER_Q];
 } __attribute__ ((packed, aligned(2048)));
 
-/**
- * struct sbal_flags - storage block address list flags
- * @last: last entry
- * @cont: contiguous storage
- * @frag: fragmentation
- */
-struct sbal_flags {
-	u8	: 1;
-	u8 last : 1;
-	u8 cont : 1;
-	u8	: 1;
-	u8 frag : 2;
-	u8	: 2;
-} __attribute__ ((packed));
-
-#define SBAL_FLAGS_FIRST_FRAG		0x04000000UL
-#define SBAL_FLAGS_MIDDLE_FRAG		0x08000000UL
-#define SBAL_FLAGS_LAST_FRAG		0x0c000000UL
-#define SBAL_FLAGS_LAST_ENTRY		0x40000000UL
-#define SBAL_FLAGS_CONTIGUOUS		0x20000000UL
+#define SBAL_EFLAGS_LAST_ENTRY		0x40
+#define SBAL_EFLAGS_CONTIGUOUS		0x20
+#define SBAL_EFLAGS_FIRST_FRAG		0x04
+#define SBAL_EFLAGS_MIDDLE_FRAG		0x08
+#define SBAL_EFLAGS_LAST_FRAG		0x0c
+#define SBAL_EFLAGS_MASK		0x6f
 
-#define SBAL_FLAGS0_DATA_CONTINUATION	0x20UL
+#define SBAL_SFLAGS0_PCI_REQ		0x40
+#define SBAL_SFLAGS0_DATA_CONTINUATION	0x20
 
 /* Awesome OpenFCP extensions */
-#define SBAL_FLAGS0_TYPE_STATUS		0x00UL
-#define SBAL_FLAGS0_TYPE_WRITE		0x08UL
-#define SBAL_FLAGS0_TYPE_READ		0x10UL
-#define SBAL_FLAGS0_TYPE_WRITE_READ	0x18UL
-#define SBAL_FLAGS0_MORE_SBALS		0x04UL
-#define SBAL_FLAGS0_COMMAND		0x02UL
-#define SBAL_FLAGS0_LAST_SBAL		0x00UL
-#define SBAL_FLAGS0_ONLY_SBAL		SBAL_FLAGS0_COMMAND
-#define SBAL_FLAGS0_MIDDLE_SBAL		SBAL_FLAGS0_MORE_SBALS
-#define SBAL_FLAGS0_FIRST_SBAL SBAL_FLAGS0_MORE_SBALS | SBAL_FLAGS0_COMMAND
-#define SBAL_FLAGS0_PCI			0x40
-
-/**
- * struct sbal_sbalf_0 - sbal flags for sbale 0
- * @pci: PCI indicator
- * @cont: data continuation
- * @sbtype: storage-block type (FCP)
- */
-struct sbal_sbalf_0 {
-	u8	  : 1;
-	u8 pci	  : 1;
-	u8 cont   : 1;
-	u8 sbtype : 2;
-	u8	  : 3;
-} __attribute__ ((packed));
-
-/**
- * struct sbal_sbalf_1 - sbal flags for sbale 1
- * @key: storage key
- */
-struct sbal_sbalf_1 {
-	u8     : 4;
-	u8 key : 4;
-} __attribute__ ((packed));
-
-/**
- * struct sbal_sbalf_14 - sbal flags for sbale 14
- * @erridx: error index
- */
-struct sbal_sbalf_14 {
-	u8	  : 4;
-	u8 erridx : 4;
-} __attribute__ ((packed));
-
-/**
- * struct sbal_sbalf_15 - sbal flags for sbale 15
- * @reason: reason for error state
- */
-struct sbal_sbalf_15 {
-	u8 reason;
-} __attribute__ ((packed));
-
-/**
- * union sbal_sbalf - storage block address list flags
- * @i0: sbalf0
- * @i1: sbalf1
- * @i14: sbalf14
- * @i15: sblaf15
- * @value: raw value
- */
-union sbal_sbalf {
-	struct sbal_sbalf_0  i0;
-	struct sbal_sbalf_1  i1;
-	struct sbal_sbalf_14 i14;
-	struct sbal_sbalf_15 i15;
-	u8 value;
-};
+#define SBAL_SFLAGS0_TYPE_STATUS	0x00
+#define SBAL_SFLAGS0_TYPE_WRITE		0x08
+#define SBAL_SFLAGS0_TYPE_READ		0x10
+#define SBAL_SFLAGS0_TYPE_WRITE_READ	0x18
+#define SBAL_SFLAGS0_MORE_SBALS		0x04
+#define SBAL_SFLAGS0_COMMAND		0x02
+#define SBAL_SFLAGS0_LAST_SBAL		0x00
+#define SBAL_SFLAGS0_ONLY_SBAL		SBAL_SFLAGS0_COMMAND
+#define SBAL_SFLAGS0_MIDDLE_SBAL	SBAL_SFLAGS0_MORE_SBALS
+#define SBAL_SFLAGS0_FIRST_SBAL (SBAL_SFLAGS0_MORE_SBALS | SBAL_SFLAGS0_COMMAND)
 
 /**
  * struct qdio_buffer_element - SBAL entry
- * @flags: flags
+ * @eflags: SBAL entry flags
+ * @scount: SBAL count
+ * @sflags: whole SBAL flags
  * @length: length
  * @addr: address
 */
 struct qdio_buffer_element {
-	u32 flags;
+	u8 eflags;
+	/* private: */
+	u8 res1;
+	/* public: */
+	u8 scount;
+	u8 sflags;
 	u32 length;
 #ifdef CONFIG_32BIT
 	/* private: */
-	void *reserved;
+	void *res2;
 	/* public: */
 #endif
 	void *addr;
diff -druN linux-2.6.39-libre/arch/s390/include/asm/s390_ext.h linux-3.0-rc7-libre/arch/s390/include/asm/s390_ext.h
--- linux-2.6.39-libre/arch/s390/include/asm/s390_ext.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/s390/include/asm/s390_ext.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,17 +0,0 @@
-/*
- *    Copyright IBM Corp. 1999,2010
- *    Author(s): Holger Smolinski <Holger.Smolinski@de.ibm.com>,
- *		 Martin Schwidefsky <schwidefsky@de.ibm.com>,
- */
-
-#ifndef _S390_EXTINT_H
-#define _S390_EXTINT_H
-
-#include <linux/types.h>
-
-typedef void (*ext_int_handler_t)(unsigned int, unsigned int, unsigned long);
-
-int register_external_interrupt(__u16 code, ext_int_handler_t handler);
-int unregister_external_interrupt(__u16 code, ext_int_handler_t handler);
-
-#endif /* _S390_EXTINT_H */
diff -druN linux-2.6.39-libre/arch/s390/include/asm/suspend.h linux-3.0-rc7-libre/arch/s390/include/asm/suspend.h
--- linux-2.6.39-libre/arch/s390/include/asm/suspend.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/s390/include/asm/suspend.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,10 +0,0 @@
-#ifndef __ASM_S390_SUSPEND_H
-#define __ASM_S390_SUSPEND_H
-
-static inline int arch_prepare_suspend(void)
-{
-	return 0;
-}
-
-#endif
-
diff -druN linux-2.6.39-libre/arch/s390/include/asm/tlbflush.h linux-3.0-rc7-libre/arch/s390/include/asm/tlbflush.h
--- linux-2.6.39-libre/arch/s390/include/asm/tlbflush.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/s390/include/asm/tlbflush.h	2011-07-11 19:51:52.000000000 -0400
@@ -50,7 +50,7 @@
 	/*
 	 * If the process only ran on the local cpu, do a local flush.
 	 */
-	local_cpumask = cpumask_of_cpu(smp_processor_id());
+	cpumask_copy(&local_cpumask, cpumask_of(smp_processor_id()));
 	if (cpumask_equal(mm_cpumask(mm), &local_cpumask))
 		__tlb_flush_local();
 	else
@@ -80,16 +80,11 @@
 	 * on all cpus instead of doing a local flush if the mm
 	 * only ran on the local cpu.
 	 */
-	if (MACHINE_HAS_IDTE) {
-		if (mm->context.noexec)
-			__tlb_flush_idte((unsigned long)
-					 get_shadow_table(mm->pgd) |
-					 mm->context.asce_bits);
+	if (MACHINE_HAS_IDTE)
 		__tlb_flush_idte((unsigned long) mm->pgd |
 				 mm->context.asce_bits);
-		return;
-	}
-	__tlb_flush_full(mm);
+	else
+		__tlb_flush_full(mm);
 }
 
 static inline void __tlb_flush_mm_cond(struct mm_struct * mm)
diff -druN linux-2.6.39-libre/arch/s390/include/asm/tlb.h linux-3.0-rc7-libre/arch/s390/include/asm/tlb.h
--- linux-2.6.39-libre/arch/s390/include/asm/tlb.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/s390/include/asm/tlb.h	2011-07-11 19:51:52.000000000 -0400
@@ -26,68 +26,73 @@
 #include <linux/swap.h>
 #include <asm/processor.h>
 #include <asm/pgalloc.h>
-#include <asm/smp.h>
 #include <asm/tlbflush.h>
 
-#ifndef CONFIG_SMP
-#define TLB_NR_PTRS	1
-#else
-#define TLB_NR_PTRS	508
-#endif
-
 struct mmu_gather {
 	struct mm_struct *mm;
+#ifdef CONFIG_HAVE_RCU_TABLE_FREE
+	struct mmu_table_batch *batch;
+#endif
 	unsigned int fullmm;
-	unsigned int nr_ptes;
-	unsigned int nr_pxds;
-	void *array[TLB_NR_PTRS];
+	unsigned int need_flush;
 };
 
-DECLARE_PER_CPU(struct mmu_gather, mmu_gathers);
+#ifdef CONFIG_HAVE_RCU_TABLE_FREE
+struct mmu_table_batch {
+	struct rcu_head		rcu;
+	unsigned int		nr;
+	void			*tables[0];
+};
 
-static inline struct mmu_gather *tlb_gather_mmu(struct mm_struct *mm,
-						unsigned int full_mm_flush)
-{
-	struct mmu_gather *tlb = &get_cpu_var(mmu_gathers);
+#define MAX_TABLE_BATCH		\
+	((PAGE_SIZE - sizeof(struct mmu_table_batch)) / sizeof(void *))
 
+extern void tlb_table_flush(struct mmu_gather *tlb);
+extern void tlb_remove_table(struct mmu_gather *tlb, void *table);
+#endif
+
+static inline void tlb_gather_mmu(struct mmu_gather *tlb,
+				  struct mm_struct *mm,
+				  unsigned int full_mm_flush)
+{
 	tlb->mm = mm;
 	tlb->fullmm = full_mm_flush;
-	tlb->nr_ptes = 0;
-	tlb->nr_pxds = TLB_NR_PTRS;
+	tlb->need_flush = 0;
+#ifdef CONFIG_HAVE_RCU_TABLE_FREE
+	tlb->batch = NULL;
+#endif
 	if (tlb->fullmm)
 		__tlb_flush_mm(mm);
-	return tlb;
 }
 
-static inline void tlb_flush_mmu(struct mmu_gather *tlb,
-				 unsigned long start, unsigned long end)
+static inline void tlb_flush_mmu(struct mmu_gather *tlb)
 {
-	if (!tlb->fullmm && (tlb->nr_ptes > 0 || tlb->nr_pxds < TLB_NR_PTRS))
-		__tlb_flush_mm(tlb->mm);
-	while (tlb->nr_ptes > 0)
-		page_table_free_rcu(tlb->mm, tlb->array[--tlb->nr_ptes]);
-	while (tlb->nr_pxds < TLB_NR_PTRS)
-		crst_table_free_rcu(tlb->mm, tlb->array[tlb->nr_pxds++]);
+	if (!tlb->need_flush)
+		return;
+	tlb->need_flush = 0;
+	__tlb_flush_mm(tlb->mm);
+#ifdef CONFIG_HAVE_RCU_TABLE_FREE
+	tlb_table_flush(tlb);
+#endif
 }
 
 static inline void tlb_finish_mmu(struct mmu_gather *tlb,
 				  unsigned long start, unsigned long end)
 {
-	tlb_flush_mmu(tlb, start, end);
-
-	rcu_table_freelist_finish();
-
-	/* keep the page table cache within bounds */
-	check_pgt_cache();
-
-	put_cpu_var(mmu_gathers);
+	tlb_flush_mmu(tlb);
 }
 
 /*
  * Release the page cache reference for a pte removed by
- * tlb_ptep_clear_flush. In both flush modes the tlb fo a page cache page
+ * tlb_ptep_clear_flush. In both flush modes the tlb for a page cache page
  * has already been freed, so just do free_page_and_swap_cache.
  */
+static inline int __tlb_remove_page(struct mmu_gather *tlb, struct page *page)
+{
+	free_page_and_swap_cache(page);
+	return 1; /* avoid calling tlb_flush_mmu */
+}
+
 static inline void tlb_remove_page(struct mmu_gather *tlb, struct page *page)
 {
 	free_page_and_swap_cache(page);
@@ -100,12 +105,11 @@
 static inline void pte_free_tlb(struct mmu_gather *tlb, pgtable_t pte,
 				unsigned long address)
 {
-	if (!tlb->fullmm) {
-		tlb->array[tlb->nr_ptes++] = pte;
-		if (tlb->nr_ptes >= tlb->nr_pxds)
-			tlb_flush_mmu(tlb, 0, 0);
-	} else
-		page_table_free(tlb->mm, (unsigned long *) pte);
+#ifdef CONFIG_HAVE_RCU_TABLE_FREE
+	if (!tlb->fullmm)
+		return page_table_free_rcu(tlb, (unsigned long *) pte);
+#endif
+	page_table_free(tlb->mm, (unsigned long *) pte);
 }
 
 /*
@@ -121,12 +125,11 @@
 #ifdef __s390x__
 	if (tlb->mm->context.asce_limit <= (1UL << 31))
 		return;
-	if (!tlb->fullmm) {
-		tlb->array[--tlb->nr_pxds] = pmd;
-		if (tlb->nr_ptes >= tlb->nr_pxds)
-			tlb_flush_mmu(tlb, 0, 0);
-	} else
-		crst_table_free(tlb->mm, (unsigned long *) pmd);
+#ifdef CONFIG_HAVE_RCU_TABLE_FREE
+	if (!tlb->fullmm)
+		return tlb_remove_table(tlb, pmd);
+#endif
+	crst_table_free(tlb->mm, (unsigned long *) pmd);
 #endif
 }
 
@@ -143,12 +146,11 @@
 #ifdef __s390x__
 	if (tlb->mm->context.asce_limit <= (1UL << 42))
 		return;
-	if (!tlb->fullmm) {
-		tlb->array[--tlb->nr_pxds] = pud;
-		if (tlb->nr_ptes >= tlb->nr_pxds)
-			tlb_flush_mmu(tlb, 0, 0);
-	} else
-		crst_table_free(tlb->mm, (unsigned long *) pud);
+#ifdef CONFIG_HAVE_RCU_TABLE_FREE
+	if (!tlb->fullmm)
+		return tlb_remove_table(tlb, pud);
+#endif
+	crst_table_free(tlb->mm, (unsigned long *) pud);
 #endif
 }
 
diff -druN linux-2.6.39-libre/arch/s390/include/asm/topology.h linux-3.0-rc7-libre/arch/s390/include/asm/topology.h
--- linux-2.6.39-libre/arch/s390/include/asm/topology.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/s390/include/asm/topology.h	2011-07-11 19:51:52.000000000 -0400
@@ -7,7 +7,7 @@
 extern unsigned char cpu_core_id[NR_CPUS];
 extern cpumask_t cpu_core_map[NR_CPUS];
 
-static inline const struct cpumask *cpu_coregroup_mask(unsigned int cpu)
+static inline const struct cpumask *cpu_coregroup_mask(int cpu)
 {
 	return &cpu_core_map[cpu];
 }
@@ -21,7 +21,7 @@
 extern unsigned char cpu_book_id[NR_CPUS];
 extern cpumask_t cpu_book_map[NR_CPUS];
 
-static inline const struct cpumask *cpu_book_mask(unsigned int cpu)
+static inline const struct cpumask *cpu_book_mask(int cpu)
 {
 	return &cpu_book_map[cpu];
 }
diff -druN linux-2.6.39-libre/arch/s390/include/asm/uaccess.h linux-3.0-rc7-libre/arch/s390/include/asm/uaccess.h
--- linux-2.6.39-libre/arch/s390/include/asm/uaccess.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/s390/include/asm/uaccess.h	2011-07-11 19:51:52.000000000 -0400
@@ -49,12 +49,13 @@
 
 #define segment_eq(a,b) ((a).ar4 == (b).ar4)
 
+#define __access_ok(addr, size)	\
+({				\
+	__chk_user_ptr(addr);	\
+	1;			\
+})
 
-static inline int __access_ok(const void __user *addr, unsigned long size)
-{
-	return 1;
-}
-#define access_ok(type,addr,size) __access_ok(addr,size)
+#define access_ok(type, addr, size) __access_ok(addr, size)
 
 /*
  * The exception table consists of pairs of addresses: the first is the
diff -druN linux-2.6.39-libre/arch/s390/include/asm/unistd.h linux-3.0-rc7-libre/arch/s390/include/asm/unistd.h
--- linux-2.6.39-libre/arch/s390/include/asm/unistd.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/s390/include/asm/unistd.h	2011-07-11 19:51:52.000000000 -0400
@@ -276,7 +276,8 @@
 #define __NR_open_by_handle_at	336
 #define __NR_clock_adjtime	337
 #define __NR_syncfs		338
-#define NR_syscalls 339
+#define __NR_setns		339
+#define NR_syscalls 340
 
 /* 
  * There are some system calls that are not present on 64 bit, some
@@ -385,6 +386,7 @@
 
 /* Ignore system calls that are also reachable via sys_socket */
 #define __IGNORE_recvmmsg
+#define __IGNORE_sendmmsg
 
 #define __ARCH_WANT_IPC_PARSE_VERSION
 #define __ARCH_WANT_OLD_READDIR
diff -druN linux-2.6.39-libre/arch/s390/Kconfig linux-3.0-rc7-libre/arch/s390/Kconfig
--- linux-2.6.39-libre/arch/s390/Kconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/s390/Kconfig	2011-07-11 19:51:52.000000000 -0400
@@ -2,7 +2,7 @@
 	def_bool y
 
 config ZONE_DMA
-	def_bool y if 64BIT
+	def_bool y
 
 config LOCKDEP_SUPPORT
 	def_bool y
@@ -88,6 +88,8 @@
 	select HAVE_KERNEL_XZ
 	select HAVE_GET_USER_PAGES_FAST
 	select HAVE_ARCH_MUTEX_CPU_RELAX
+	select HAVE_ARCH_JUMP_LABEL if !MARCH_G5
+	select HAVE_RCU_TABLE_FREE if SMP
 	select ARCH_INLINE_SPIN_TRYLOCK
 	select ARCH_INLINE_SPIN_TRYLOCK_BH
 	select ARCH_INLINE_SPIN_LOCK
@@ -229,17 +231,6 @@
 config AUDIT_ARCH
 	def_bool y
 
-config S390_EXEC_PROTECT
-	def_bool y
-	prompt "Data execute protection"
-	help
-	  This option allows to enable a buffer overflow protection for user
-	  space programs and it also selects the addressing mode option above.
-	  The kernel parameter noexec=on will enable this feature and also
-	  switch the addressing modes, default is disabled. Enabling this (via
-	  kernel parameter) on machines earlier than IBM System z9 this will
-	  reduce system performance.
-
 comment "Code generation options"
 
 choice
@@ -588,6 +579,7 @@
 	def_bool y
 	prompt "s390 guest support for KVM (EXPERIMENTAL)"
 	depends on 64BIT && EXPERIMENTAL
+	select VIRTUALIZATION
 	select VIRTIO
 	select VIRTIO_RING
 	select VIRTIO_CONSOLE
diff -druN linux-2.6.39-libre/arch/s390/kernel/asm-offsets.c linux-3.0-rc7-libre/arch/s390/kernel/asm-offsets.c
--- linux-2.6.39-libre/arch/s390/kernel/asm-offsets.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/s390/kernel/asm-offsets.c	2011-07-11 19:51:52.000000000 -0400
@@ -124,13 +124,11 @@
 	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_CURRENT_PID, offsetof(struct _lowcore, current_pid));
 	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_INT_CLOCK, offsetof(struct _lowcore, int_clock));
 	DEFINE(__LC_MCCK_CLOCK, offsetof(struct _lowcore, mcck_clock));
 	DEFINE(__LC_MACHINE_FLAGS, offsetof(struct _lowcore, machine_flags));
diff -druN linux-2.6.39-libre/arch/s390/kernel/compat_wrapper.S linux-3.0-rc7-libre/arch/s390/kernel/compat_wrapper.S
--- linux-2.6.39-libre/arch/s390/kernel/compat_wrapper.S	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/s390/kernel/compat_wrapper.S	2011-07-11 19:51:52.000000000 -0400
@@ -1904,3 +1904,9 @@
 sys_syncfs_wrapper:
 	lgfr	%r2,%r2			# int
 	jg	sys_syncfs
+
+	.globl	sys_setns_wrapper
+sys_setns_wrapper:
+	lgfr	%r2,%r2			# int
+	lgfr	%r3,%r3			# int
+	jg	sys_setns
diff -druN linux-2.6.39-libre/arch/s390/kernel/dis.c linux-3.0-rc7-libre/arch/s390/kernel/dis.c
--- linux-2.6.39-libre/arch/s390/kernel/dis.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/s390/kernel/dis.c	2011-07-11 19:51:52.000000000 -0400
@@ -30,9 +30,9 @@
 #include <asm/atomic.h>
 #include <asm/mathemu.h>
 #include <asm/cpcmd.h>
-#include <asm/s390_ext.h>
 #include <asm/lowcore.h>
 #include <asm/debug.h>
+#include <asm/irq.h>
 
 #ifndef CONFIG_64BIT
 #define ONELONG "%08lx: "
diff -druN linux-2.6.39-libre/arch/s390/kernel/entry64.S linux-3.0-rc7-libre/arch/s390/kernel/entry64.S
--- linux-2.6.39-libre/arch/s390/kernel/entry64.S	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/s390/kernel/entry64.S	2011-07-11 19:51:52.000000000 -0400
@@ -220,6 +220,7 @@
 	lctl	%c4,%c4,__TASK_pid(%r3)		# load pid to control reg. 4
 	lmg	%r6,%r15,__SF_GPRS(%r15)	# load gprs of next task
 	stg	%r3,__LC_CURRENT		# store task struct of next
+	mvc	__LC_CURRENT_PID+4(4,%r0),__TASK_pid(%r3) # store pid of next
 	stg	%r5,__LC_THREAD_INFO		# store thread info of next
 	aghi	%r5,STACK_SIZE			# end of kernel stack of next
 	stg	%r5,__LC_KERNEL_STACK		# store end of kernel stack
diff -druN linux-2.6.39-libre/arch/s390/kernel/entry.S linux-3.0-rc7-libre/arch/s390/kernel/entry.S
--- linux-2.6.39-libre/arch/s390/kernel/entry.S	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/s390/kernel/entry.S	2011-07-11 19:51:52.000000000 -0400
@@ -212,6 +212,7 @@
 	lctl	%c4,%c4,__TASK_pid(%r3)		# load pid to control reg. 4
 	lm	%r6,%r15,__SF_GPRS(%r15)	# load gprs of next task
 	st	%r3,__LC_CURRENT		# store task struct of next
+	mvc	__LC_CURRENT_PID(4,%r0),__TASK_pid(%r3)	# store pid of next
 	st	%r5,__LC_THREAD_INFO		# store thread info of next
 	ahi	%r5,STACK_SIZE			# end of kernel stack of next
 	st	%r5,__LC_KERNEL_STACK		# store end of kernel stack
diff -druN linux-2.6.39-libre/arch/s390/kernel/irq.c linux-3.0-rc7-libre/arch/s390/kernel/irq.c
--- linux-2.6.39-libre/arch/s390/kernel/irq.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/s390/kernel/irq.c	2011-07-11 19:51:52.000000000 -0400
@@ -1,19 +1,28 @@
 /*
- *    Copyright IBM Corp. 2004,2010
- *    Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com),
- *		 Thomas Spatzier (tspat@de.ibm.com)
+ *    Copyright IBM Corp. 2004,2011
+ *    Author(s): Martin Schwidefsky <schwidefsky@de.ibm.com>,
+ *		 Holger Smolinski <Holger.Smolinski@de.ibm.com>,
+ *		 Thomas Spatzier <tspat@de.ibm.com>,
  *
  * This file contains interrupt related functions.
  */
 
-#include <linux/module.h>
-#include <linux/kernel.h>
 #include <linux/kernel_stat.h>
 #include <linux/interrupt.h>
 #include <linux/seq_file.h>
-#include <linux/cpu.h>
 #include <linux/proc_fs.h>
 #include <linux/profile.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/ftrace.h>
+#include <linux/errno.h>
+#include <linux/slab.h>
+#include <linux/cpu.h>
+#include <asm/irq_regs.h>
+#include <asm/cputime.h>
+#include <asm/lowcore.h>
+#include <asm/irq.h>
+#include "entry.h"
 
 struct irq_class {
 	char *name;
@@ -32,6 +41,7 @@
 	{.name = "VRT", .desc = "[EXT] Virtio" },
 	{.name = "SCP", .desc = "[EXT] Service Call" },
 	{.name = "IUC", .desc = "[EXT] IUCV" },
+	{.name = "CPM", .desc = "[EXT] CPU Measurement" },
 	{.name = "QAI", .desc = "[I/O] QDIO Adapter Interrupt" },
 	{.name = "QDI", .desc = "[I/O] QDIO Interrupt" },
 	{.name = "DAS", .desc = "[I/O] DASD" },
@@ -81,8 +91,7 @@
  * For compatibilty only. S/390 specific setup of interrupts et al. is done
  * much later in init_channel_subsystem().
  */
-void __init
-init_IRQ(void)
+void __init init_IRQ(void)
 {
 	/* nothing... */
 }
@@ -133,3 +142,116 @@
 	create_prof_cpu_mask(root_irq_dir);
 }
 #endif
+
+/*
+ * ext_int_hash[index] is the start of the list for all external interrupts
+ * that hash to this index. With the current set of external interrupts
+ * (0x1202 external call, 0x1004 cpu timer, 0x2401 hwc console, 0x4000
+ * iucv and 0x2603 pfault) this is always the first element.
+ */
+
+struct ext_int_info {
+	struct ext_int_info *next;
+	ext_int_handler_t handler;
+	u16 code;
+};
+
+static struct ext_int_info *ext_int_hash[256];
+
+static inline int ext_hash(u16 code)
+{
+	return (code + (code >> 9)) & 0xff;
+}
+
+int register_external_interrupt(u16 code, ext_int_handler_t handler)
+{
+	struct ext_int_info *p;
+	int index;
+
+	p = kmalloc(sizeof(*p), GFP_ATOMIC);
+	if (!p)
+		return -ENOMEM;
+	p->code = code;
+	p->handler = handler;
+	index = ext_hash(code);
+	p->next = ext_int_hash[index];
+	ext_int_hash[index] = p;
+	return 0;
+}
+EXPORT_SYMBOL(register_external_interrupt);
+
+int unregister_external_interrupt(u16 code, ext_int_handler_t handler)
+{
+	struct ext_int_info *p, *q;
+	int index;
+
+	index = ext_hash(code);
+	q = NULL;
+	p = ext_int_hash[index];
+	while (p) {
+		if (p->code == code && p->handler == handler)
+			break;
+		q = p;
+		p = p->next;
+	}
+	if (!p)
+		return -ENOENT;
+	if (q)
+		q->next = p->next;
+	else
+		ext_int_hash[index] = p->next;
+	kfree(p);
+	return 0;
+}
+EXPORT_SYMBOL(unregister_external_interrupt);
+
+void __irq_entry do_extint(struct pt_regs *regs, unsigned int ext_int_code,
+			   unsigned int param32, unsigned long param64)
+{
+	struct pt_regs *old_regs;
+	unsigned short code;
+	struct ext_int_info *p;
+	int index;
+
+	code = (unsigned short) ext_int_code;
+	old_regs = set_irq_regs(regs);
+	s390_idle_check(regs, S390_lowcore.int_clock,
+			S390_lowcore.async_enter_timer);
+	irq_enter();
+	if (S390_lowcore.int_clock >= S390_lowcore.clock_comparator)
+		/* Serve timer interrupts first. */
+		clock_comparator_work();
+	kstat_cpu(smp_processor_id()).irqs[EXTERNAL_INTERRUPT]++;
+	if (code != 0x1004)
+		__get_cpu_var(s390_idle).nohz_delay = 1;
+	index = ext_hash(code);
+	for (p = ext_int_hash[index]; p; p = p->next) {
+		if (likely(p->code == code))
+			p->handler(ext_int_code, param32, param64);
+	}
+	irq_exit();
+	set_irq_regs(old_regs);
+}
+
+static DEFINE_SPINLOCK(sc_irq_lock);
+static int sc_irq_refcount;
+
+void service_subclass_irq_register(void)
+{
+	spin_lock(&sc_irq_lock);
+	if (!sc_irq_refcount)
+		ctl_set_bit(0, 9);
+	sc_irq_refcount++;
+	spin_unlock(&sc_irq_lock);
+}
+EXPORT_SYMBOL(service_subclass_irq_register);
+
+void service_subclass_irq_unregister(void)
+{
+	spin_lock(&sc_irq_lock);
+	sc_irq_refcount--;
+	if (!sc_irq_refcount)
+		ctl_clear_bit(0, 9);
+	spin_unlock(&sc_irq_lock);
+}
+EXPORT_SYMBOL(service_subclass_irq_unregister);
diff -druN linux-2.6.39-libre/arch/s390/kernel/jump_label.c linux-3.0-rc7-libre/arch/s390/kernel/jump_label.c
--- linux-2.6.39-libre/arch/s390/kernel/jump_label.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/s390/kernel/jump_label.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,59 @@
+/*
+ * Jump label s390 support
+ *
+ * Copyright IBM Corp. 2011
+ * Author(s): Jan Glauber <jang@linux.vnet.ibm.com>
+ */
+#include <linux/module.h>
+#include <linux/uaccess.h>
+#include <linux/stop_machine.h>
+#include <linux/jump_label.h>
+#include <asm/ipl.h>
+
+#ifdef HAVE_JUMP_LABEL
+
+struct insn {
+	u16 opcode;
+	s32 offset;
+} __packed;
+
+struct insn_args {
+	unsigned long *target;
+	struct insn *insn;
+	ssize_t size;
+};
+
+static int __arch_jump_label_transform(void *data)
+{
+	struct insn_args *args = data;
+	int rc;
+
+	rc = probe_kernel_write(args->target, args->insn, args->size);
+	WARN_ON_ONCE(rc < 0);
+	return 0;
+}
+
+void arch_jump_label_transform(struct jump_entry *entry,
+			       enum jump_label_type type)
+{
+	struct insn_args args;
+	struct insn insn;
+
+	if (type == JUMP_LABEL_ENABLE) {
+		/* brcl 15,offset */
+		insn.opcode = 0xc0f4;
+		insn.offset = (entry->target - entry->code) >> 1;
+	} else {
+		/* brcl 0,0 */
+		insn.opcode = 0xc004;
+		insn.offset = 0;
+	}
+
+	args.target = (void *) entry->code;
+	args.insn = &insn;
+	args.size = JUMP_LABEL_NOP_SIZE;
+
+	stop_machine(__arch_jump_label_transform, &args, NULL);
+}
+
+#endif
diff -druN linux-2.6.39-libre/arch/s390/kernel/Makefile linux-3.0-rc7-libre/arch/s390/kernel/Makefile
--- linux-2.6.39-libre/arch/s390/kernel/Makefile	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/s390/kernel/Makefile	2011-07-11 19:51:52.000000000 -0400
@@ -20,10 +20,10 @@
 
 CFLAGS_sysinfo.o += -Iinclude/math-emu -Iarch/s390/math-emu -w
 
-obj-y	:=  bitmap.o traps.o time.o process.o base.o early.o setup.o \
-	    processor.o sys_s390.o ptrace.o signal.o cpcmd.o ebcdic.o \
-	    s390_ext.o debug.o irq.o ipl.o dis.o diag.o mem_detect.o \
-	    vdso.o vtime.o sysinfo.o nmi.o sclp.o
+obj-y	:=  bitmap.o traps.o time.o process.o base.o early.o setup.o vtime.o \
+	    processor.o sys_s390.o ptrace.o signal.o cpcmd.o ebcdic.o nmi.o \
+	    debug.o irq.o ipl.o dis.o diag.o mem_detect.o sclp.o vdso.o \
+	    sysinfo.o jump_label.o
 
 obj-y	+= $(if $(CONFIG_64BIT),entry64.o,entry.o)
 obj-y	+= $(if $(CONFIG_64BIT),reipl64.o,reipl.o)
diff -druN linux-2.6.39-libre/arch/s390/kernel/process.c linux-3.0-rc7-libre/arch/s390/kernel/process.c
--- linux-2.6.39-libre/arch/s390/kernel/process.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/s390/kernel/process.c	2011-07-11 19:51:52.000000000 -0400
@@ -9,41 +9,26 @@
 
 #include <linux/compiler.h>
 #include <linux/cpu.h>
-#include <linux/errno.h>
 #include <linux/sched.h>
 #include <linux/kernel.h>
 #include <linux/mm.h>
-#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/vmalloc.h>
-#include <linux/user.h>
 #include <linux/interrupt.h>
-#include <linux/delay.h>
-#include <linux/reboot.h>
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/notifier.h>
 #include <linux/tick.h>
-#include <linux/elfcore.h>
-#include <linux/kernel_stat.h>
 #include <linux/personality.h>
 #include <linux/syscalls.h>
 #include <linux/compat.h>
 #include <linux/kprobes.h>
 #include <linux/random.h>
-#include <asm/compat.h>
-#include <asm/uaccess.h>
-#include <asm/pgtable.h>
+#include <linux/module.h>
 #include <asm/system.h>
 #include <asm/io.h>
 #include <asm/processor.h>
 #include <asm/irq.h>
 #include <asm/timer.h>
 #include <asm/nmi.h>
+#include <asm/compat.h>
 #include <asm/smp.h>
 #include "entry.h"
 
diff -druN linux-2.6.39-libre/arch/s390/kernel/s390_ext.c linux-3.0-rc7-libre/arch/s390/kernel/s390_ext.c
--- linux-2.6.39-libre/arch/s390/kernel/s390_ext.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/s390/kernel/s390_ext.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,108 +0,0 @@
-/*
- *    Copyright IBM Corp. 1999,2010
- *    Author(s): Holger Smolinski <Holger.Smolinski@de.ibm.com>,
- *		 Martin Schwidefsky <schwidefsky@de.ibm.com>,
- */
-
-#include <linux/kernel_stat.h>
-#include <linux/interrupt.h>
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/ftrace.h>
-#include <linux/errno.h>
-#include <linux/slab.h>
-#include <asm/s390_ext.h>
-#include <asm/irq_regs.h>
-#include <asm/cputime.h>
-#include <asm/lowcore.h>
-#include <asm/irq.h>
-#include "entry.h"
-
-struct ext_int_info {
-	struct ext_int_info *next;
-	ext_int_handler_t handler;
-	__u16 code;
-};
-
-/*
- * ext_int_hash[index] is the start of the list for all external interrupts
- * that hash to this index. With the current set of external interrupts 
- * (0x1202 external call, 0x1004 cpu timer, 0x2401 hwc console, 0x4000
- * iucv and 0x2603 pfault) this is always the first element. 
- */
-static struct ext_int_info *ext_int_hash[256];
-
-static inline int ext_hash(__u16 code)
-{
-	return (code + (code >> 9)) & 0xff;
-}
-
-int register_external_interrupt(__u16 code, ext_int_handler_t handler)
-{
-	struct ext_int_info *p;
-	int index;
-
-	p = kmalloc(sizeof(*p), GFP_ATOMIC);
-	if (!p)
-		return -ENOMEM;
-	p->code = code;
-	p->handler = handler;
-	index = ext_hash(code);
-	p->next = ext_int_hash[index];
-	ext_int_hash[index] = p;
-	return 0;
-}
-EXPORT_SYMBOL(register_external_interrupt);
-
-int unregister_external_interrupt(__u16 code, ext_int_handler_t handler)
-{
-	struct ext_int_info *p, *q;
-	int index;
-
-	index = ext_hash(code);
-	q = NULL;
-	p = ext_int_hash[index];
-	while (p) {
-		if (p->code == code && p->handler == handler)
-			break;
-		q = p;
-		p = p->next;
-	}
-	if (!p)
-		return -ENOENT;
-	if (q)
-		q->next = p->next;
-	else
-		ext_int_hash[index] = p->next;
-	kfree(p);
-	return 0;
-}
-EXPORT_SYMBOL(unregister_external_interrupt);
-
-void __irq_entry do_extint(struct pt_regs *regs, unsigned int ext_int_code,
-			   unsigned int param32, unsigned long param64)
-{
-	struct pt_regs *old_regs;
-	unsigned short code;
-	struct ext_int_info *p;
-	int index;
-
-	code = (unsigned short) ext_int_code;
-	old_regs = set_irq_regs(regs);
-	s390_idle_check(regs, S390_lowcore.int_clock,
-			S390_lowcore.async_enter_timer);
-	irq_enter();
-	if (S390_lowcore.int_clock >= S390_lowcore.clock_comparator)
-		/* Serve timer interrupts first. */
-		clock_comparator_work();
-	kstat_cpu(smp_processor_id()).irqs[EXTERNAL_INTERRUPT]++;
-	if (code != 0x1004)
-		__get_cpu_var(s390_idle).nohz_delay = 1;
-	index = ext_hash(code);
-	for (p = ext_int_hash[index]; p; p = p->next) {
-		if (likely(p->code == code))
-			p->handler(ext_int_code, param32, param64);
-	}
-	irq_exit();
-	set_irq_regs(old_regs);
-}
diff -druN linux-2.6.39-libre/arch/s390/kernel/setup.c linux-3.0-rc7-libre/arch/s390/kernel/setup.c
--- linux-2.6.39-libre/arch/s390/kernel/setup.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/s390/kernel/setup.c	2011-07-11 19:51:52.000000000 -0400
@@ -305,8 +305,7 @@
  */
 static int __init early_parse_switch_amode(char *p)
 {
-	if (user_mode != SECONDARY_SPACE_MODE)
-		user_mode = PRIMARY_SPACE_MODE;
+	user_mode = PRIMARY_SPACE_MODE;
 	return 0;
 }
 early_param("switch_amode", early_parse_switch_amode);
@@ -315,10 +314,6 @@
 {
 	if (p && strcmp(p, "primary") == 0)
 		user_mode = PRIMARY_SPACE_MODE;
-#ifdef CONFIG_S390_EXEC_PROTECT
-	else if (p && strcmp(p, "secondary") == 0)
-		user_mode = SECONDARY_SPACE_MODE;
-#endif
 	else if (!p || strcmp(p, "home") == 0)
 		user_mode = HOME_SPACE_MODE;
 	else
@@ -327,31 +322,9 @@
 }
 early_param("user_mode", early_parse_user_mode);
 
-#ifdef CONFIG_S390_EXEC_PROTECT
-/*
- * Enable execute protection?
- */
-static int __init early_parse_noexec(char *p)
-{
-	if (!strncmp(p, "off", 3))
-		return 0;
-	user_mode = SECONDARY_SPACE_MODE;
-	return 0;
-}
-early_param("noexec", early_parse_noexec);
-#endif /* CONFIG_S390_EXEC_PROTECT */
-
 static void setup_addressing_mode(void)
 {
-	if (user_mode == SECONDARY_SPACE_MODE) {
-		if (set_amode_and_uaccess(PSW_ASC_SECONDARY,
-					  PSW32_ASC_SECONDARY))
-			pr_info("Execute protection active, "
-				"mvcos available\n");
-		else
-			pr_info("Execute protection active, "
-				"mvcos not available\n");
-	} else if (user_mode == PRIMARY_SPACE_MODE) {
+	if (user_mode == PRIMARY_SPACE_MODE) {
 		if (set_amode_and_uaccess(PSW_ASC_PRIMARY, PSW32_ASC_PRIMARY))
 			pr_info("Address spaces switched, "
 				"mvcos available\n");
diff -druN linux-2.6.39-libre/arch/s390/kernel/smp.c linux-3.0-rc7-libre/arch/s390/kernel/smp.c
--- linux-2.6.39-libre/arch/s390/kernel/smp.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/s390/kernel/smp.c	2011-07-11 19:51:52.000000000 -0400
@@ -44,7 +44,6 @@
 #include <asm/sigp.h>
 #include <asm/pgalloc.h>
 #include <asm/irq.h>
-#include <asm/s390_ext.h>
 #include <asm/cpcmd.h>
 #include <asm/tlbflush.h>
 #include <asm/timer.h>
@@ -165,12 +164,12 @@
 	kstat_cpu(smp_processor_id()).irqs[EXTINT_IPI]++;
 	/*
 	 * handle bit signal external calls
-	 *
-	 * For the ec_schedule signal we have to do nothing. All the work
-	 * is done automatically when we return from the interrupt.
 	 */
 	bits = xchg(&S390_lowcore.ext_call_fast, 0);
 
+	if (test_bit(ec_schedule, &bits))
+		scheduler_ipi();
+
 	if (test_bit(ec_call_function, &bits))
 		generic_smp_call_function_interrupt();
 
@@ -263,7 +262,7 @@
 
 	memset(&parms.orvals, 0, sizeof(parms.orvals));
 	memset(&parms.andvals, 0xff, sizeof(parms.andvals));
-	parms.orvals[cr] = 1 << bit;
+	parms.orvals[cr] = 1UL << bit;
 	on_each_cpu(smp_ctl_bit_callback, &parms, 1);
 }
 EXPORT_SYMBOL(smp_ctl_set_bit);
@@ -277,7 +276,7 @@
 
 	memset(&parms.orvals, 0, sizeof(parms.orvals));
 	memset(&parms.andvals, 0xff, sizeof(parms.andvals));
-	parms.andvals[cr] = ~(1L << bit);
+	parms.andvals[cr] = ~(1UL << bit);
 	on_each_cpu(smp_ctl_bit_callback, &parms, 1);
 }
 EXPORT_SYMBOL(smp_ctl_clear_bit);
@@ -335,7 +334,7 @@
 		smp_cpu_polarization[logical_cpu] = POLARIZATION_UNKNWN;
 		if (!cpu_stopped(logical_cpu))
 			continue;
-		cpu_set(logical_cpu, cpu_present_map);
+		set_cpu_present(logical_cpu, true);
 		smp_cpu_state[logical_cpu] = CPU_STATE_CONFIGURED;
 		logical_cpu = cpumask_next(logical_cpu, &avail);
 		if (logical_cpu >= nr_cpu_ids)
@@ -367,7 +366,7 @@
 			continue;
 		__cpu_logical_map[logical_cpu] = cpu_id;
 		smp_cpu_polarization[logical_cpu] = POLARIZATION_UNKNWN;
-		cpu_set(logical_cpu, cpu_present_map);
+		set_cpu_present(logical_cpu, true);
 		if (cpu >= info->configured)
 			smp_cpu_state[logical_cpu] = CPU_STATE_STANDBY;
 		else
@@ -385,7 +384,7 @@
 {
 	cpumask_t avail;
 
-	cpus_xor(avail, cpu_possible_map, cpu_present_map);
+	cpumask_xor(&avail, cpu_possible_mask, cpu_present_mask);
 	if (smp_use_sigp_detection)
 		return smp_rescan_cpus_sigp(avail);
 	else
@@ -467,7 +466,7 @@
 	notify_cpu_starting(smp_processor_id());
 	/* Mark this cpu as online */
 	ipi_call_lock();
-	cpu_set(smp_processor_id(), cpu_online_map);
+	set_cpu_online(smp_processor_id(), true);
 	ipi_call_unlock();
 	/* Switch on interrupts */
 	local_irq_enable();
@@ -644,7 +643,7 @@
 	struct ec_creg_mask_parms cr_parms;
 	int cpu = smp_processor_id();
 
-	cpu_clear(cpu, cpu_online_map);
+	set_cpu_online(cpu, false);
 
 	/* Disable pfault pseudo page faults on this cpu. */
 	pfault_fini();
@@ -654,8 +653,8 @@
 
 	/* disable all external interrupts */
 	cr_parms.orvals[0] = 0;
-	cr_parms.andvals[0] = ~(1 << 15 | 1 << 14 | 1 << 13 | 1 << 12 |
-				1 << 11 | 1 << 10 | 1 <<  6 | 1 <<  4);
+	cr_parms.andvals[0] = ~(1 << 15 | 1 << 14 | 1 << 13 | 1 << 11 |
+				1 << 10 | 1 <<	9 | 1 <<  6 | 1 <<  4);
 	/* disable all I/O interrupts */
 	cr_parms.orvals[6] = 0;
 	cr_parms.andvals[6] = ~(1 << 31 | 1 << 30 | 1 << 29 | 1 << 28 |
@@ -681,7 +680,7 @@
 	atomic_dec(&init_mm.context.attach_count);
 }
 
-void cpu_die(void)
+void __noreturn cpu_die(void)
 {
 	idle_task_exit();
 	while (sigp(smp_processor_id(), sigp_stop) == sigp_busy)
@@ -738,8 +737,8 @@
 	BUG_ON(smp_processor_id() != 0);
 
 	current_thread_info()->cpu = 0;
-	cpu_set(0, cpu_present_map);
-	cpu_set(0, cpu_online_map);
+	set_cpu_present(0, true);
+	set_cpu_online(0, true);
 	S390_lowcore.percpu_offset = __per_cpu_offset[0];
 	current_set[0] = current;
 	smp_cpu_state[0] = CPU_STATE_CONFIGURED;
@@ -1016,21 +1015,21 @@
 
 	get_online_cpus();
 	mutex_lock(&smp_cpu_state_mutex);
-	newcpus = cpu_present_map;
+	cpumask_copy(&newcpus, cpu_present_mask);
 	rc = __smp_rescan_cpus();
 	if (rc)
 		goto out;
-	cpus_andnot(newcpus, cpu_present_map, newcpus);
-	for_each_cpu_mask(cpu, newcpus) {
+	cpumask_andnot(&newcpus, cpu_present_mask, &newcpus);
+	for_each_cpu(cpu, &newcpus) {
 		rc = smp_add_present_cpu(cpu);
 		if (rc)
-			cpu_clear(cpu, cpu_present_map);
+			set_cpu_present(cpu, false);
 	}
 	rc = 0;
 out:
 	mutex_unlock(&smp_cpu_state_mutex);
 	put_online_cpus();
-	if (!cpus_empty(newcpus))
+	if (!cpumask_empty(&newcpus))
 		topology_schedule_update();
 	return rc;
 }
diff -druN linux-2.6.39-libre/arch/s390/kernel/syscalls.S linux-3.0-rc7-libre/arch/s390/kernel/syscalls.S
--- linux-2.6.39-libre/arch/s390/kernel/syscalls.S	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/s390/kernel/syscalls.S	2011-07-11 19:51:52.000000000 -0400
@@ -347,3 +347,4 @@
 SYSCALL(sys_open_by_handle_at,sys_open_by_handle_at,compat_sys_open_by_handle_at_wrapper)
 SYSCALL(sys_clock_adjtime,sys_clock_adjtime,compat_sys_clock_adjtime_wrapper)
 SYSCALL(sys_syncfs,sys_syncfs,sys_syncfs_wrapper)
+SYSCALL(sys_setns,sys_setns,sys_setns_wrapper)
diff -druN linux-2.6.39-libre/arch/s390/kernel/time.c linux-3.0-rc7-libre/arch/s390/kernel/time.c
--- linux-2.6.39-libre/arch/s390/kernel/time.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/s390/kernel/time.c	2011-07-11 19:51:52.000000000 -0400
@@ -41,7 +41,6 @@
 #include <linux/kprobes.h>
 #include <asm/uaccess.h>
 #include <asm/delay.h>
-#include <asm/s390_ext.h>
 #include <asm/div64.h>
 #include <asm/vdso.h>
 #include <asm/irq.h>
@@ -810,7 +809,7 @@
 	etr_sync.etr_port = port;
 	get_online_cpus();
 	atomic_set(&etr_sync.cpus, num_online_cpus() - 1);
-	rc = stop_machine(etr_sync_clock, &etr_sync, &cpu_online_map);
+	rc = stop_machine(etr_sync_clock, &etr_sync, cpu_online_mask);
 	put_online_cpus();
 	return rc;
 }
@@ -1579,7 +1578,7 @@
 	memset(&stp_sync, 0, sizeof(stp_sync));
 	get_online_cpus();
 	atomic_set(&stp_sync.cpus, num_online_cpus() - 1);
-	stop_machine(stp_sync_clock, &stp_sync, &cpu_online_map);
+	stop_machine(stp_sync_clock, &stp_sync, cpu_online_mask);
 	put_online_cpus();
 
 	if (!check_sync_clock())
diff -druN linux-2.6.39-libre/arch/s390/kernel/topology.c linux-3.0-rc7-libre/arch/s390/kernel/topology.c
--- linux-2.6.39-libre/arch/s390/kernel/topology.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/s390/kernel/topology.c	2011-07-11 19:51:52.000000000 -0400
@@ -17,7 +17,6 @@
 #include <linux/smp.h>
 #include <linux/cpuset.h>
 #include <asm/delay.h>
-#include <asm/s390_ext.h>
 
 #define PTF_HORIZONTAL	(0UL)
 #define PTF_VERTICAL	(1UL)
@@ -52,20 +51,20 @@
 {
 	cpumask_t mask;
 
-	cpus_clear(mask);
+	cpumask_clear(&mask);
 	if (!topology_enabled || !MACHINE_HAS_TOPOLOGY) {
 		cpumask_copy(&mask, cpumask_of(cpu));
 		return mask;
 	}
 	while (info) {
-		if (cpu_isset(cpu, info->mask)) {
+		if (cpumask_test_cpu(cpu, &info->mask)) {
 			mask = info->mask;
 			break;
 		}
 		info = info->next;
 	}
-	if (cpus_empty(mask))
-		mask = cpumask_of_cpu(cpu);
+	if (cpumask_empty(&mask))
+		cpumask_copy(&mask, cpumask_of(cpu));
 	return mask;
 }
 
@@ -85,10 +84,10 @@
 			if (cpu_logical_map(lcpu) != rcpu)
 				continue;
 #ifdef CONFIG_SCHED_BOOK
-			cpu_set(lcpu, book->mask);
+			cpumask_set_cpu(lcpu, &book->mask);
 			cpu_book_id[lcpu] = book->id;
 #endif
-			cpu_set(lcpu, core->mask);
+			cpumask_set_cpu(lcpu, &core->mask);
 			cpu_core_id[lcpu] = core->id;
 			smp_cpu_polarization[lcpu] = tl_cpu->pp;
 		}
@@ -101,13 +100,13 @@
 
 	info = &core_info;
 	while (info) {
-		cpus_clear(info->mask);
+		cpumask_clear(&info->mask);
 		info = info->next;
 	}
 #ifdef CONFIG_SCHED_BOOK
 	info = &book_info;
 	while (info) {
-		cpus_clear(info->mask);
+		cpumask_clear(&info->mask);
 		info = info->next;
 	}
 #endif
diff -druN linux-2.6.39-libre/arch/s390/kernel/traps.c linux-3.0-rc7-libre/arch/s390/kernel/traps.c
--- linux-2.6.39-libre/arch/s390/kernel/traps.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/s390/kernel/traps.c	2011-07-11 19:51:52.000000000 -0400
@@ -39,7 +39,6 @@
 #include <asm/atomic.h>
 #include <asm/mathemu.h>
 #include <asm/cpcmd.h>
-#include <asm/s390_ext.h>
 #include <asm/lowcore.h>
 #include <asm/debug.h>
 #include "entry.h"
diff -druN linux-2.6.39-libre/arch/s390/kernel/vdso32/Makefile linux-3.0-rc7-libre/arch/s390/kernel/vdso32/Makefile
--- linux-2.6.39-libre/arch/s390/kernel/vdso32/Makefile	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/s390/kernel/vdso32/Makefile	2011-07-11 19:51:52.000000000 -0400
@@ -22,6 +22,9 @@
 extra-y += vdso32.lds
 CPPFLAGS_vdso32.lds += -P -C -U$(ARCH)
 
+# Disable gcov profiling for VDSO code
+GCOV_PROFILE := n
+
 # Force dependency (incbin is bad)
 $(obj)/vdso32_wrapper.o : $(obj)/vdso32.so
 
diff -druN linux-2.6.39-libre/arch/s390/kernel/vdso64/Makefile linux-3.0-rc7-libre/arch/s390/kernel/vdso64/Makefile
--- linux-2.6.39-libre/arch/s390/kernel/vdso64/Makefile	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/s390/kernel/vdso64/Makefile	2011-07-11 19:51:52.000000000 -0400
@@ -22,6 +22,9 @@
 extra-y += vdso64.lds
 CPPFLAGS_vdso64.lds += -P -C -U$(ARCH)
 
+# Disable gcov profiling for VDSO code
+GCOV_PROFILE := n
+
 # Force dependency (incbin is bad)
 $(obj)/vdso64_wrapper.o : $(obj)/vdso64.so
 
diff -druN linux-2.6.39-libre/arch/s390/kernel/vmlinux.lds.S linux-3.0-rc7-libre/arch/s390/kernel/vmlinux.lds.S
--- linux-2.6.39-libre/arch/s390/kernel/vmlinux.lds.S	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/s390/kernel/vmlinux.lds.S	2011-07-11 19:51:52.000000000 -0400
@@ -77,7 +77,7 @@
 	. = ALIGN(PAGE_SIZE);
 	INIT_DATA_SECTION(0x100)
 
-	PERCPU(0x100, PAGE_SIZE)
+	PERCPU_SECTION(0x100)
 	. = ALIGN(PAGE_SIZE);
 	__init_end = .;		/* freed after init ends here */
 
diff -druN linux-2.6.39-libre/arch/s390/kernel/vtime.c linux-3.0-rc7-libre/arch/s390/kernel/vtime.c
--- linux-2.6.39-libre/arch/s390/kernel/vtime.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/s390/kernel/vtime.c	2011-07-11 19:51:52.000000000 -0400
@@ -22,10 +22,10 @@
 #include <linux/cpu.h>
 #include <linux/kprobes.h>
 
-#include <asm/s390_ext.h>
 #include <asm/timer.h>
 #include <asm/irq_regs.h>
 #include <asm/cputime.h>
+#include <asm/irq.h>
 
 static DEFINE_PER_CPU(struct vtimer_queue, virt_cpu_timer);
 
diff -druN linux-2.6.39-libre/arch/s390/kvm/kvm-s390.c linux-3.0-rc7-libre/arch/s390/kvm/kvm-s390.c
--- linux-2.6.39-libre/arch/s390/kvm/kvm-s390.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/s390/kvm/kvm-s390.c	2011-07-11 19:51:52.000000000 -0400
@@ -731,6 +731,7 @@
 	}
 	memcpy(facilities, S390_lowcore.stfle_fac_list, 16);
 	facilities[0] &= 0xff00fff3f47c0000ULL;
+	facilities[1] &= 0x201c000000000000ULL;
 	return 0;
 }
 
diff -druN linux-2.6.39-libre/arch/s390/kvm/sie64a.S linux-3.0-rc7-libre/arch/s390/kvm/sie64a.S
--- linux-2.6.39-libre/arch/s390/kvm/sie64a.S	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/s390/kvm/sie64a.S	2011-07-11 19:51:52.000000000 -0400
@@ -93,4 +93,6 @@
 
 	.section __ex_table,"a"
 	.quad	sie_inst,sie_err
+	.quad	sie_exit,sie_err
+	.quad	sie_reenter,sie_err
 	.previous
diff -druN linux-2.6.39-libre/arch/s390/lib/delay.c linux-3.0-rc7-libre/arch/s390/lib/delay.c
--- linux-2.6.39-libre/arch/s390/lib/delay.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/s390/lib/delay.c	2011-07-11 19:51:52.000000000 -0400
@@ -12,6 +12,7 @@
 #include <linux/module.h>
 #include <linux/irqflags.h>
 #include <linux/interrupt.h>
+#include <asm/div64.h>
 
 void __delay(unsigned long loops)
 {
@@ -116,3 +117,17 @@
 	while (get_clock() < end)
 		cpu_relax();
 }
+
+void __ndelay(unsigned long long nsecs)
+{
+	u64 end;
+
+	nsecs <<= 9;
+	do_div(nsecs, 125);
+	end = get_clock() + nsecs;
+	if (nsecs & ~0xfffUL)
+		__udelay(nsecs >> 12);
+	while (get_clock() < end)
+		barrier();
+}
+EXPORT_SYMBOL(__ndelay);
diff -druN linux-2.6.39-libre/arch/s390/mm/extmem.c linux-3.0-rc7-libre/arch/s390/mm/extmem.c
--- linux-2.6.39-libre/arch/s390/mm/extmem.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/s390/mm/extmem.c	2011-07-11 19:51:52.000000000 -0400
@@ -412,6 +412,7 @@
 	struct dcss_segment *seg;
 	int rc, diag_cc;
 
+	start_addr = end_addr = 0;
 	seg = kmalloc(sizeof(*seg), GFP_KERNEL | GFP_DMA);
 	if (seg == NULL) {
 		rc = -ENOMEM;
@@ -573,6 +574,7 @@
 	unsigned long start_addr, end_addr, dummy;
 	int rc, diag_cc;
 
+	start_addr = end_addr = 0;
 	mutex_lock(&dcss_lock);
 	seg = segment_by_name (name);
 	if (seg == NULL) {
@@ -681,8 +683,6 @@
 segment_save(char *name)
 {
 	struct dcss_segment *seg;
-	int startpfn = 0;
-	int endpfn = 0;
 	char cmd1[160];
 	char cmd2[80];
 	int i, response;
@@ -698,8 +698,6 @@
 		goto out;
 	}
 
-	startpfn = seg->start_addr >> PAGE_SHIFT;
-	endpfn = (seg->end) >> PAGE_SHIFT;
 	sprintf(cmd1, "DEFSEG %s", name);
 	for (i=0; i<seg->segcnt; i++) {
 		sprintf(cmd1+strlen(cmd1), " %lX-%lX %s",
diff -druN linux-2.6.39-libre/arch/s390/mm/fault.c linux-3.0-rc7-libre/arch/s390/mm/fault.c
--- linux-2.6.39-libre/arch/s390/mm/fault.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/s390/mm/fault.c	2011-07-11 19:51:52.000000000 -0400
@@ -34,7 +34,7 @@
 #include <asm/asm-offsets.h>
 #include <asm/system.h>
 #include <asm/pgtable.h>
-#include <asm/s390_ext.h>
+#include <asm/irq.h>
 #include <asm/mmu_context.h>
 #include <asm/compat.h>
 #include "../kernel/entry.h"
@@ -225,33 +225,6 @@
 	force_sig_info(SIGBUS, &si, tsk);
 }
 
-#ifdef CONFIG_S390_EXEC_PROTECT
-static noinline int signal_return(struct pt_regs *regs, long int_code,
-				  unsigned long trans_exc_code)
-{
-	u16 instruction;
-	int rc;
-
-	rc = __get_user(instruction, (u16 __user *) regs->psw.addr);
-
-	if (!rc && instruction == 0x0a77) {
-		clear_tsk_thread_flag(current, TIF_PER_TRAP);
-		if (is_compat_task())
-			sys32_sigreturn();
-		else
-			sys_sigreturn();
-	} else if (!rc && instruction == 0x0aad) {
-		clear_tsk_thread_flag(current, TIF_PER_TRAP);
-		if (is_compat_task())
-			sys32_rt_sigreturn();
-		else
-			sys_rt_sigreturn();
-	} else
-		do_sigsegv(regs, int_code, SEGV_MAPERR, trans_exc_code);
-	return 0;
-}
-#endif /* CONFIG_S390_EXEC_PROTECT */
-
 static noinline void do_fault_error(struct pt_regs *regs, long int_code,
 				    unsigned long trans_exc_code, int fault)
 {
@@ -259,13 +232,6 @@
 
 	switch (fault) {
 	case VM_FAULT_BADACCESS:
-#ifdef CONFIG_S390_EXEC_PROTECT
-		if ((regs->psw.mask & PSW_MASK_ASC) == PSW_ASC_SECONDARY &&
-		    (trans_exc_code & 3) == 0) {
-			signal_return(regs, int_code, trans_exc_code);
-			break;
-		}
-#endif /* CONFIG_S390_EXEC_PROTECT */
 	case VM_FAULT_BADMAP:
 		/* Bad memory access. Check if it is kernel or user space. */
 		if (regs->psw.mask & PSW_MASK_PSTATE) {
@@ -279,9 +245,12 @@
 		do_no_context(regs, int_code, trans_exc_code);
 		break;
 	default: /* fault & VM_FAULT_ERROR */
-		if (fault & VM_FAULT_OOM)
-			pagefault_out_of_memory();
-		else if (fault & VM_FAULT_SIGBUS) {
+		if (fault & VM_FAULT_OOM) {
+			if (!(regs->psw.mask & PSW_MASK_PSTATE))
+				do_no_context(regs, int_code, trans_exc_code);
+			else
+				pagefault_out_of_memory();
+		} else if (fault & VM_FAULT_SIGBUS) {
 			/* Kernel mode? Handle exceptions or die */
 			if (!(regs->psw.mask & PSW_MASK_PSTATE))
 				do_no_context(regs, int_code, trans_exc_code);
@@ -311,7 +280,8 @@
 	struct mm_struct *mm;
 	struct vm_area_struct *vma;
 	unsigned long address;
-	int fault, write;
+	unsigned int flags;
+	int fault;
 
 	if (notify_page_fault(regs))
 		return 0;
@@ -330,6 +300,10 @@
 
 	address = trans_exc_code & __FAIL_ADDR_MASK;
 	perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS, 1, 0, regs, address);
+	flags = FAULT_FLAG_ALLOW_RETRY;
+	if (access == VM_WRITE || (trans_exc_code & store_indication) == 0x400)
+		flags |= FAULT_FLAG_WRITE;
+retry:
 	down_read(&mm->mmap_sem);
 
 	fault = VM_FAULT_BADMAP;
@@ -359,21 +333,31 @@
 	 * make sure we exit gracefully rather than endlessly redo
 	 * the fault.
 	 */
-	write = (access == VM_WRITE ||
-		 (trans_exc_code & store_indication) == 0x400) ?
-		FAULT_FLAG_WRITE : 0;
-	fault = handle_mm_fault(mm, vma, address, write);
+	fault = handle_mm_fault(mm, vma, address, flags);
 	if (unlikely(fault & VM_FAULT_ERROR))
 		goto out_up;
 
-	if (fault & VM_FAULT_MAJOR) {
-		tsk->maj_flt++;
-		perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MAJ, 1, 0,
-				     regs, address);
-	} else {
-		tsk->min_flt++;
-		perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MIN, 1, 0,
-				     regs, address);
+	/*
+	 * Major/minor page fault accounting is only done on the
+	 * initial attempt. If we go through a retry, it is extremely
+	 * likely that the page will be found in page cache at that point.
+	 */
+	if (flags & FAULT_FLAG_ALLOW_RETRY) {
+		if (fault & VM_FAULT_MAJOR) {
+			tsk->maj_flt++;
+			perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MAJ, 1, 0,
+				      regs, address);
+		} else {
+			tsk->min_flt++;
+			perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MIN, 1, 0,
+				      regs, address);
+		}
+		if (fault & VM_FAULT_RETRY) {
+			/* Clear FAULT_FLAG_ALLOW_RETRY to avoid any risk
+			 * of starvation. */
+			flags &= ~FAULT_FLAG_ALLOW_RETRY;
+			goto retry;
+		}
 	}
 	/*
 	 * The instruction that caused the program check will
@@ -414,11 +398,6 @@
 	int access, fault;
 
 	access = VM_READ | VM_EXEC | VM_WRITE;
-#ifdef CONFIG_S390_EXEC_PROTECT
-	if ((regs->psw.mask & PSW_MASK_ASC) == PSW_ASC_SECONDARY &&
-	    (trans_exc_code & 3) == 0)
-		access = VM_EXEC;
-#endif
 	fault = do_exception(regs, access, trans_exc_code);
 	if (unlikely(fault))
 		do_fault_error(regs, pgm_int_code & 255, trans_exc_code, fault);
@@ -468,10 +447,9 @@
 	access = write ? VM_WRITE : VM_READ;
 	fault = do_exception(&regs, access, uaddr | 2);
 	if (unlikely(fault)) {
-		if (fault & VM_FAULT_OOM) {
-			pagefault_out_of_memory();
-			fault = 0;
-		} else if (fault & VM_FAULT_SIGBUS)
+		if (fault & VM_FAULT_OOM)
+			return -EFAULT;
+		else if (fault & VM_FAULT_SIGBUS)
 			do_sigbus(&regs, pgm_int_code, uaddr);
 	}
 	return fault ? -EFAULT : 0;
@@ -491,22 +469,28 @@
 
 __setup("nopfault", nopfault);
 
-typedef struct {
-	__u16 refdiagc;
-	__u16 reffcode;
-	__u16 refdwlen;
-	__u16 refversn;
-	__u64 refgaddr;
-	__u64 refselmk;
-	__u64 refcmpmk;
-	__u64 reserved;
-} __attribute__ ((packed, aligned(8))) pfault_refbk_t;
+struct pfault_refbk {
+	u16 refdiagc;
+	u16 reffcode;
+	u16 refdwlen;
+	u16 refversn;
+	u64 refgaddr;
+	u64 refselmk;
+	u64 refcmpmk;
+	u64 reserved;
+} __attribute__ ((packed, aligned(8)));
 
 int pfault_init(void)
 {
-	pfault_refbk_t refbk =
-		{ 0x258, 0, 5, 2, __LC_CURRENT, 1ULL << 48, 1ULL << 48,
-		  __PF_RES_FIELD };
+	struct pfault_refbk refbk = {
+		.refdiagc = 0x258,
+		.reffcode = 0,
+		.refdwlen = 5,
+		.refversn = 2,
+		.refgaddr = __LC_CURRENT_PID,
+		.refselmk = 1ULL << 48,
+		.refcmpmk = 1ULL << 48,
+		.reserved = __PF_RES_FIELD };
         int rc;
 
 	if (!MACHINE_IS_VM || pfault_disable)
@@ -518,18 +502,20 @@
 		"2:\n"
 		EX_TABLE(0b,1b)
 		: "=d" (rc) : "a" (&refbk), "m" (refbk) : "cc");
-        __ctl_set_bit(0, 9);
         return rc;
 }
 
 void pfault_fini(void)
 {
-	pfault_refbk_t refbk =
-	{ 0x258, 1, 5, 2, 0ULL, 0ULL, 0ULL, 0ULL };
+	struct pfault_refbk refbk = {
+		.refdiagc = 0x258,
+		.reffcode = 1,
+		.refdwlen = 5,
+		.refversn = 2,
+	};
 
 	if (!MACHINE_IS_VM || pfault_disable)
 		return;
-	__ctl_clear_bit(0,9);
 	asm volatile(
 		"	diag	%0,0,0x258\n"
 		"0:\n"
@@ -537,11 +523,15 @@
 		: : "a" (&refbk), "m" (refbk) : "cc");
 }
 
+static DEFINE_SPINLOCK(pfault_lock);
+static LIST_HEAD(pfault_list);
+
 static void pfault_interrupt(unsigned int ext_int_code,
 			     unsigned int param32, unsigned long param64)
 {
 	struct task_struct *tsk;
 	__u16 subcode;
+	pid_t pid;
 
 	/*
 	 * Get the external interruption subcode & pfault
@@ -553,44 +543,79 @@
 	if ((subcode & 0xff00) != __SUBCODE_MASK)
 		return;
 	kstat_cpu(smp_processor_id()).irqs[EXTINT_PFL]++;
-
-	/*
-	 * Get the token (= address of the task structure of the affected task).
-	 */
-#ifdef CONFIG_64BIT
-	tsk = (struct task_struct *) param64;
-#else
-	tsk = (struct task_struct *) param32;
-#endif
-
+	if (subcode & 0x0080) {
+		/* Get the token (= pid of the affected task). */
+		pid = sizeof(void *) == 4 ? param32 : param64;
+		rcu_read_lock();
+		tsk = find_task_by_pid_ns(pid, &init_pid_ns);
+		if (tsk)
+			get_task_struct(tsk);
+		rcu_read_unlock();
+		if (!tsk)
+			return;
+	} else {
+		tsk = current;
+	}
+	spin_lock(&pfault_lock);
 	if (subcode & 0x0080) {
 		/* signal bit is set -> a page has been swapped in by VM */
-		if (xchg(&tsk->thread.pfault_wait, -1) != 0) {
+		if (tsk->thread.pfault_wait == 1) {
 			/* Initial interrupt was faster than the completion
 			 * interrupt. pfault_wait is valid. Set pfault_wait
 			 * back to zero and wake up the process. This can
 			 * safely be done because the task is still sleeping
 			 * and can't produce new pfaults. */
 			tsk->thread.pfault_wait = 0;
+			list_del(&tsk->thread.list);
 			wake_up_process(tsk);
-			put_task_struct(tsk);
+		} else {
+			/* Completion interrupt was faster than initial
+			 * interrupt. Set pfault_wait to -1 so the initial
+			 * interrupt doesn't put the task to sleep. */
+			tsk->thread.pfault_wait = -1;
 		}
+		put_task_struct(tsk);
 	} else {
 		/* signal bit not set -> a real page is missing. */
-		get_task_struct(tsk);
-		set_task_state(tsk, TASK_UNINTERRUPTIBLE);
-		if (xchg(&tsk->thread.pfault_wait, 1) != 0) {
+		if (tsk->thread.pfault_wait == -1) {
 			/* Completion interrupt was faster than the initial
-			 * interrupt (swapped in a -1 for pfault_wait). Set
-			 * pfault_wait back to zero and exit. This can be
-			 * done safely because tsk is running in kernel 
-			 * mode and can't produce new pfaults. */
+			 * interrupt (pfault_wait == -1). Set pfault_wait
+			 * back to zero and exit. */
 			tsk->thread.pfault_wait = 0;
-			set_task_state(tsk, TASK_RUNNING);
-			put_task_struct(tsk);
-		} else
+		} else {
+			/* Initial interrupt arrived before completion
+			 * interrupt. Let the task sleep. */
+			tsk->thread.pfault_wait = 1;
+			list_add(&tsk->thread.list, &pfault_list);
+			set_task_state(tsk, TASK_UNINTERRUPTIBLE);
 			set_tsk_need_resched(tsk);
+		}
+	}
+	spin_unlock(&pfault_lock);
+}
+
+static int __cpuinit pfault_cpu_notify(struct notifier_block *self,
+				       unsigned long action, void *hcpu)
+{
+	struct thread_struct *thread, *next;
+	struct task_struct *tsk;
+
+	switch (action) {
+	case CPU_DEAD:
+	case CPU_DEAD_FROZEN:
+		spin_lock_irq(&pfault_lock);
+		list_for_each_entry_safe(thread, next, &pfault_list, list) {
+			thread->pfault_wait = 0;
+			list_del(&thread->list);
+			tsk = container_of(thread, struct task_struct, thread);
+			wake_up_process(tsk);
+		}
+		spin_unlock_irq(&pfault_lock);
+		break;
+	default:
+		break;
 	}
+	return NOTIFY_OK;
 }
 
 static int __init pfault_irq_init(void)
@@ -599,22 +624,22 @@
 
 	if (!MACHINE_IS_VM)
 		return 0;
-	/*
-	 * Try to get pfault pseudo page faults going.
-	 */
 	rc = register_external_interrupt(0x2603, pfault_interrupt);
-	if (rc) {
-		pfault_disable = 1;
-		return rc;
-	}
-	if (pfault_init() == 0)
-		return 0;
+	if (rc)
+		goto out_extint;
+	rc = pfault_init() == 0 ? 0 : -EOPNOTSUPP;
+	if (rc)
+		goto out_pfault;
+	service_subclass_irq_register();
+	hotcpu_notifier(pfault_cpu_notify, 0);
+	return 0;
 
-	/* Tough luck, no pfault. */
-	pfault_disable = 1;
+out_pfault:
 	unregister_external_interrupt(0x2603, pfault_interrupt);
-	return 0;
+out_extint:
+	pfault_disable = 1;
+	return rc;
 }
 early_initcall(pfault_irq_init);
 
-#endif
+#endif /* CONFIG_PFAULT */
diff -druN linux-2.6.39-libre/arch/s390/mm/hugetlbpage.c linux-3.0-rc7-libre/arch/s390/mm/hugetlbpage.c
--- linux-2.6.39-libre/arch/s390/mm/hugetlbpage.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/s390/mm/hugetlbpage.c	2011-07-11 19:51:52.000000000 -0400
@@ -13,7 +13,6 @@
 				   pte_t *pteptr, pte_t pteval)
 {
 	pmd_t *pmdp = (pmd_t *) pteptr;
-	pte_t shadow_pteval = pteval;
 	unsigned long mask;
 
 	if (!MACHINE_HAS_HPAGE) {
@@ -21,18 +20,9 @@
 		mask = pte_val(pteval) &
 				(_SEGMENT_ENTRY_INV | _SEGMENT_ENTRY_RO);
 		pte_val(pteval) = (_SEGMENT_ENTRY + __pa(pteptr)) | mask;
-		if (mm->context.noexec) {
-			pteptr += PTRS_PER_PTE;
-			pte_val(shadow_pteval) =
-					(_SEGMENT_ENTRY + __pa(pteptr)) | mask;
-		}
 	}
 
 	pmd_val(*pmdp) = pte_val(pteval);
-	if (mm->context.noexec) {
-		pmdp = get_shadow_table(pmdp);
-		pmd_val(*pmdp) = pte_val(shadow_pteval);
-	}
 }
 
 int arch_prepare_hugepage(struct page *page)
diff -druN linux-2.6.39-libre/arch/s390/mm/init.c linux-3.0-rc7-libre/arch/s390/mm/init.c
--- linux-2.6.39-libre/arch/s390/mm/init.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/s390/mm/init.c	2011-07-11 19:51:52.000000000 -0400
@@ -119,9 +119,7 @@
 	sparse_memory_present_with_active_regions(MAX_NUMNODES);
 	sparse_init();
 	memset(max_zone_pfns, 0, sizeof(max_zone_pfns));
-#ifdef CONFIG_ZONE_DMA
 	max_zone_pfns[ZONE_DMA] = PFN_DOWN(MAX_DMA_ADDRESS);
-#endif
 	max_zone_pfns[ZONE_NORMAL] = max_low_pfn;
 	free_area_init_nodes(max_zone_pfns);
 	fault_init();
@@ -175,7 +173,8 @@
 		pmd = pmd_offset(pud, address);
 		pte = pte_offset_kernel(pmd, address);
 		if (!enable) {
-			ptep_invalidate(&init_mm, address, pte);
+			__ptep_ipte(address, pte);
+			pte_val(*pte) = _PAGE_TYPE_EMPTY;
 			continue;
 		}
 		*pte = mk_pte_phys(address, __pgprot(_PAGE_TYPE_RW));
diff -druN linux-2.6.39-libre/arch/s390/mm/maccess.c linux-3.0-rc7-libre/arch/s390/mm/maccess.c
--- linux-2.6.39-libre/arch/s390/mm/maccess.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/s390/mm/maccess.c	2011-07-11 19:51:52.000000000 -0400
@@ -19,7 +19,7 @@
  * using the stura instruction.
  * Returns the number of bytes copied or -EFAULT.
  */
-static long probe_kernel_write_odd(void *dst, void *src, size_t size)
+static long probe_kernel_write_odd(void *dst, const void *src, size_t size)
 {
 	unsigned long count, aligned;
 	int offset, mask;
@@ -45,7 +45,7 @@
 	return rc ? rc : count;
 }
 
-long probe_kernel_write(void *dst, void *src, size_t size)
+long probe_kernel_write(void *dst, const void *src, size_t size)
 {
 	long copied = 0;
 
diff -druN linux-2.6.39-libre/arch/s390/mm/pageattr.c linux-3.0-rc7-libre/arch/s390/mm/pageattr.c
--- linux-2.6.39-libre/arch/s390/mm/pageattr.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/s390/mm/pageattr.c	2011-07-11 19:51:52.000000000 -0400
@@ -28,7 +28,7 @@
 
 		pte = *ptep;
 		pte = set(pte);
-		ptep_invalidate(&init_mm, addr, ptep);
+		__ptep_ipte(addr, ptep);
 		*ptep = pte;
 		addr += PAGE_SIZE;
 	}
@@ -54,3 +54,8 @@
 	return 0;
 }
 EXPORT_SYMBOL_GPL(set_memory_nx);
+
+int set_memory_x(unsigned long addr, int numpages)
+{
+	return 0;
+}
diff -druN linux-2.6.39-libre/arch/s390/mm/pgtable.c linux-3.0-rc7-libre/arch/s390/mm/pgtable.c
--- linux-2.6.39-libre/arch/s390/mm/pgtable.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/s390/mm/pgtable.c	2011-07-11 19:51:52.000000000 -0400
@@ -24,93 +24,12 @@
 #include <asm/tlbflush.h>
 #include <asm/mmu_context.h>
 
-struct rcu_table_freelist {
-	struct rcu_head rcu;
-	struct mm_struct *mm;
-	unsigned int pgt_index;
-	unsigned int crst_index;
-	unsigned long *table[0];
-};
-
-#define RCU_FREELIST_SIZE \
-	((PAGE_SIZE - sizeof(struct rcu_table_freelist)) \
-	  / sizeof(unsigned long))
-
-DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
-static DEFINE_PER_CPU(struct rcu_table_freelist *, rcu_table_freelist);
-
-static void __page_table_free(struct mm_struct *mm, unsigned long *table);
-static void __crst_table_free(struct mm_struct *mm, unsigned long *table);
-
-static struct rcu_table_freelist *rcu_table_freelist_get(struct mm_struct *mm)
-{
-	struct rcu_table_freelist **batchp = &__get_cpu_var(rcu_table_freelist);
-	struct rcu_table_freelist *batch = *batchp;
-
-	if (batch)
-		return batch;
-	batch = (struct rcu_table_freelist *) __get_free_page(GFP_ATOMIC);
-	if (batch) {
-		batch->mm = mm;
-		batch->pgt_index = 0;
-		batch->crst_index = RCU_FREELIST_SIZE;
-		*batchp = batch;
-	}
-	return batch;
-}
-
-static void rcu_table_freelist_callback(struct rcu_head *head)
-{
-	struct rcu_table_freelist *batch =
-		container_of(head, struct rcu_table_freelist, rcu);
-
-	while (batch->pgt_index > 0)
-		__page_table_free(batch->mm, batch->table[--batch->pgt_index]);
-	while (batch->crst_index < RCU_FREELIST_SIZE)
-		__crst_table_free(batch->mm, batch->table[batch->crst_index++]);
-	free_page((unsigned long) batch);
-}
-
-void rcu_table_freelist_finish(void)
-{
-	struct rcu_table_freelist *batch = __get_cpu_var(rcu_table_freelist);
-
-	if (!batch)
-		return;
-	call_rcu(&batch->rcu, rcu_table_freelist_callback);
-	__get_cpu_var(rcu_table_freelist) = NULL;
-}
-
-static void smp_sync(void *arg)
-{
-}
-
 #ifndef CONFIG_64BIT
 #define ALLOC_ORDER	1
-#define TABLES_PER_PAGE	4
-#define FRAG_MASK	15UL
-#define SECOND_HALVES	10UL
-
-void clear_table_pgstes(unsigned long *table)
-{
-	clear_table(table, _PAGE_TYPE_EMPTY, PAGE_SIZE/4);
-	memset(table + 256, 0, PAGE_SIZE/4);
-	clear_table(table + 512, _PAGE_TYPE_EMPTY, PAGE_SIZE/4);
-	memset(table + 768, 0, PAGE_SIZE/4);
-}
-
+#define FRAG_MASK	0x0f
 #else
 #define ALLOC_ORDER	2
-#define TABLES_PER_PAGE	2
-#define FRAG_MASK	3UL
-#define SECOND_HALVES	2UL
-
-void clear_table_pgstes(unsigned long *table)
-{
-	clear_table(table, _PAGE_TYPE_EMPTY, PAGE_SIZE/2);
-	memset(table + 256, 0, PAGE_SIZE/2);
-}
-
+#define FRAG_MASK	0x03
 #endif
 
 unsigned long VMALLOC_START = VMALLOC_END - VMALLOC_SIZE;
@@ -125,68 +44,18 @@
 }
 early_param("vmalloc", parse_vmalloc);
 
-unsigned long *crst_table_alloc(struct mm_struct *mm, int noexec)
+unsigned long *crst_table_alloc(struct mm_struct *mm)
 {
 	struct page *page = alloc_pages(GFP_KERNEL, ALLOC_ORDER);
 
 	if (!page)
 		return NULL;
-	page->index = 0;
-	if (noexec) {
-		struct page *shadow = alloc_pages(GFP_KERNEL, ALLOC_ORDER);
-		if (!shadow) {
-			__free_pages(page, ALLOC_ORDER);
-			return NULL;
-		}
-		page->index = page_to_phys(shadow);
-	}
-	spin_lock_bh(&mm->context.list_lock);
-	list_add(&page->lru, &mm->context.crst_list);
-	spin_unlock_bh(&mm->context.list_lock);
 	return (unsigned long *) page_to_phys(page);
 }
 
-static void __crst_table_free(struct mm_struct *mm, unsigned long *table)
-{
-	unsigned long *shadow = get_shadow_table(table);
-
-	if (shadow)
-		free_pages((unsigned long) shadow, ALLOC_ORDER);
-	free_pages((unsigned long) table, ALLOC_ORDER);
-}
-
 void crst_table_free(struct mm_struct *mm, unsigned long *table)
 {
-	struct page *page = virt_to_page(table);
-
-	spin_lock_bh(&mm->context.list_lock);
-	list_del(&page->lru);
-	spin_unlock_bh(&mm->context.list_lock);
-	__crst_table_free(mm, table);
-}
-
-void crst_table_free_rcu(struct mm_struct *mm, unsigned long *table)
-{
-	struct rcu_table_freelist *batch;
-	struct page *page = virt_to_page(table);
-
-	spin_lock_bh(&mm->context.list_lock);
-	list_del(&page->lru);
-	spin_unlock_bh(&mm->context.list_lock);
-	if (atomic_read(&mm->mm_users) < 2 &&
-	    cpumask_equal(mm_cpumask(mm), cpumask_of(smp_processor_id()))) {
-		__crst_table_free(mm, table);
-		return;
-	}
-	batch = rcu_table_freelist_get(mm);
-	if (!batch) {
-		smp_call_function(smp_sync, NULL, 1);
-		__crst_table_free(mm, table);
-		return;
-	}
-	batch->table[--batch->crst_index] = table;
-	if (batch->pgt_index >= batch->crst_index)
-		rcu_table_freelist_finish();
+	free_pages((unsigned long) table, ALLOC_ORDER);
 }
 
 #ifdef CONFIG_64BIT
@@ -197,7 +66,7 @@
 
 	BUG_ON(limit > (1UL << 53));
 repeat:
-	table = crst_table_alloc(mm, mm->context.noexec);
+	table = crst_table_alloc(mm);
 	if (!table)
 		return -ENOMEM;
 	spin_lock_bh(&mm->page_table_lock);
@@ -264,140 +133,175 @@
 }
 #endif
 
+static inline unsigned int atomic_xor_bits(atomic_t *v, unsigned int bits)
+{
+	unsigned int old, new;
+
+	do {
+		old = atomic_read(v);
+		new = old ^ bits;
+	} while (atomic_cmpxchg(v, old, new) != old);
+	return new;
+}
+
 /*
  * page table entry allocation/free routines.
  */
+#ifdef CONFIG_PGSTE
+static inline unsigned long *page_table_alloc_pgste(struct mm_struct *mm)
+{
+	struct page *page;
+	unsigned long *table;
+
+	page = alloc_page(GFP_KERNEL|__GFP_REPEAT);
+	if (!page)
+		return NULL;
+	pgtable_page_ctor(page);
+	atomic_set(&page->_mapcount, 3);
+	table = (unsigned long *) page_to_phys(page);
+	clear_table(table, _PAGE_TYPE_EMPTY, PAGE_SIZE/2);
+	clear_table(table + PTRS_PER_PTE, 0, PAGE_SIZE/2);
+	return table;
+}
+
+static inline void page_table_free_pgste(unsigned long *table)
+{
+	struct page *page;
+
+	page = pfn_to_page(__pa(table) >> PAGE_SHIFT);
+	pgtable_page_ctor(page);
+	atomic_set(&page->_mapcount, -1);
+	__free_page(page);
+}
+#endif
+
 unsigned long *page_table_alloc(struct mm_struct *mm)
 {
 	struct page *page;
 	unsigned long *table;
-	unsigned long bits;
+	unsigned int mask, bit;
 
-	bits = (mm->context.noexec || mm->context.has_pgste) ? 3UL : 1UL;
+#ifdef CONFIG_PGSTE
+	if (mm_has_pgste(mm))
+		return page_table_alloc_pgste(mm);
+#endif
+	/* Allocate fragments of a 4K page as 1K/2K page table */
 	spin_lock_bh(&mm->context.list_lock);
-	page = NULL;
+	mask = FRAG_MASK;
 	if (!list_empty(&mm->context.pgtable_list)) {
 		page = list_first_entry(&mm->context.pgtable_list,
 					struct page, lru);
-		if ((page->flags & FRAG_MASK) == ((1UL << TABLES_PER_PAGE) - 1))
-			page = NULL;
+		table = (unsigned long *) page_to_phys(page);
+		mask = atomic_read(&page->_mapcount);
+		mask = mask | (mask >> 4);
 	}
-	if (!page) {
+	if ((mask & FRAG_MASK) == FRAG_MASK) {
 		spin_unlock_bh(&mm->context.list_lock);
 		page = alloc_page(GFP_KERNEL|__GFP_REPEAT);
 		if (!page)
 			return NULL;
 		pgtable_page_ctor(page);
-		page->flags &= ~FRAG_MASK;
+		atomic_set(&page->_mapcount, 1);
 		table = (unsigned long *) page_to_phys(page);
-		if (mm->context.has_pgste)
-			clear_table_pgstes(table);
-		else
-			clear_table(table, _PAGE_TYPE_EMPTY, PAGE_SIZE);
+		clear_table(table, _PAGE_TYPE_EMPTY, PAGE_SIZE);
 		spin_lock_bh(&mm->context.list_lock);
 		list_add(&page->lru, &mm->context.pgtable_list);
+	} else {
+		for (bit = 1; mask & bit; bit <<= 1)
+			table += PTRS_PER_PTE;
+		mask = atomic_xor_bits(&page->_mapcount, bit);
+		if ((mask & FRAG_MASK) == FRAG_MASK)
+			list_del(&page->lru);
 	}
-	table = (unsigned long *) page_to_phys(page);
-	while (page->flags & bits) {
-		table += 256;
-		bits <<= 1;
-	}
-	page->flags |= bits;
-	if ((page->flags & FRAG_MASK) == ((1UL << TABLES_PER_PAGE) - 1))
-		list_move_tail(&page->lru, &mm->context.pgtable_list);
 	spin_unlock_bh(&mm->context.list_lock);
 	return table;
 }
 
-static void __page_table_free(struct mm_struct *mm, unsigned long *table)
+void page_table_free(struct mm_struct *mm, unsigned long *table)
 {
 	struct page *page;
-	unsigned long bits;
+	unsigned int bit, mask;
 
-	bits = ((unsigned long) table) & 15;
-	table = (unsigned long *)(((unsigned long) table) ^ bits);
+#ifdef CONFIG_PGSTE
+	if (mm_has_pgste(mm))
+		return page_table_free_pgste(table);
+#endif
+	/* Free 1K/2K page table fragment of a 4K page */
 	page = pfn_to_page(__pa(table) >> PAGE_SHIFT);
-	page->flags ^= bits;
-	if (!(page->flags & FRAG_MASK)) {
+	bit = 1 << ((__pa(table) & ~PAGE_MASK)/(PTRS_PER_PTE*sizeof(pte_t)));
+	spin_lock_bh(&mm->context.list_lock);
+	if ((atomic_read(&page->_mapcount) & FRAG_MASK) != FRAG_MASK)
+		list_del(&page->lru);
+	mask = atomic_xor_bits(&page->_mapcount, bit);
+	if (mask & FRAG_MASK)
+		list_add(&page->lru, &mm->context.pgtable_list);
+	spin_unlock_bh(&mm->context.list_lock);
+	if (mask == 0) {
 		pgtable_page_dtor(page);
+		atomic_set(&page->_mapcount, -1);
 		__free_page(page);
 	}
 }
 
-void page_table_free(struct mm_struct *mm, unsigned long *table)
+#ifdef CONFIG_HAVE_RCU_TABLE_FREE
+
+static void __page_table_free_rcu(void *table, unsigned bit)
 {
 	struct page *page;
-	unsigned long bits;
 
-	bits = (mm->context.noexec || mm->context.has_pgste) ? 3UL : 1UL;
-	bits <<= (__pa(table) & (PAGE_SIZE - 1)) / 256 / sizeof(unsigned long);
+#ifdef CONFIG_PGSTE
+	if (bit == FRAG_MASK)
+		return page_table_free_pgste(table);
+#endif
+	/* Free 1K/2K page table fragment of a 4K page */
 	page = pfn_to_page(__pa(table) >> PAGE_SHIFT);
-	spin_lock_bh(&mm->context.list_lock);
-	page->flags ^= bits;
-	if (page->flags & FRAG_MASK) {
-		/* Page now has some free pgtable fragments. */
-		if (!list_empty(&page->lru))
-			list_move(&page->lru, &mm->context.pgtable_list);
-		page = NULL;
-	} else
-		/* All fragments of the 4K page have been freed. */
-		list_del(&page->lru);
-	spin_unlock_bh(&mm->context.list_lock);
-	if (page) {
+	if (atomic_xor_bits(&page->_mapcount, bit) == 0) {
 		pgtable_page_dtor(page);
+		atomic_set(&page->_mapcount, -1);
 		__free_page(page);
 	}
 }
 
-void page_table_free_rcu(struct mm_struct *mm, unsigned long *table)
+void page_table_free_rcu(struct mmu_gather *tlb, unsigned long *table)
 {
-	struct rcu_table_freelist *batch;
+	struct mm_struct *mm;
 	struct page *page;
-	unsigned long bits;
+	unsigned int bit, mask;
 
-	if (atomic_read(&mm->mm_users) < 2 &&
-	    cpumask_equal(mm_cpumask(mm), cpumask_of(smp_processor_id()))) {
-		page_table_free(mm, table);
-		return;
-	}
-	batch = rcu_table_freelist_get(mm);
-	if (!batch) {
-		smp_call_function(smp_sync, NULL, 1);
-		page_table_free(mm, table);
+	mm = tlb->mm;
+#ifdef CONFIG_PGSTE
+	if (mm_has_pgste(mm)) {
+		table = (unsigned long *) (__pa(table) | FRAG_MASK);
+		tlb_remove_table(tlb, table);
 		return;
 	}
-	bits = (mm->context.noexec || mm->context.has_pgste) ? 3UL : 1UL;
-	bits <<= (__pa(table) & (PAGE_SIZE - 1)) / 256 / sizeof(unsigned long);
+#endif
+	bit = 1 << ((__pa(table) & ~PAGE_MASK) / (PTRS_PER_PTE*sizeof(pte_t)));
 	page = pfn_to_page(__pa(table) >> PAGE_SHIFT);
 	spin_lock_bh(&mm->context.list_lock);
-	/* Delayed freeing with rcu prevents reuse of pgtable fragments */
-	list_del_init(&page->lru);
+	if ((atomic_read(&page->_mapcount) & FRAG_MASK) != FRAG_MASK)
+		list_del(&page->lru);
+	mask = atomic_xor_bits(&page->_mapcount, bit | (bit << 4));
+	if (mask & FRAG_MASK)
+		list_add_tail(&page->lru, &mm->context.pgtable_list);
 	spin_unlock_bh(&mm->context.list_lock);
-	table = (unsigned long *)(((unsigned long) table) | bits);
-	batch->table[batch->pgt_index++] = table;
-	if (batch->pgt_index >= batch->crst_index)
-		rcu_table_freelist_finish();
+	table = (unsigned long *) (__pa(table) | (bit << 4));
+	tlb_remove_table(tlb, table);
 }
 
-void disable_noexec(struct mm_struct *mm, struct task_struct *tsk)
+void __tlb_remove_table(void *_table)
 {
-	struct page *page;
+	void *table = (void *)((unsigned long) _table & PAGE_MASK);
+	unsigned type = (unsigned long) _table & ~PAGE_MASK;
 
-	spin_lock_bh(&mm->context.list_lock);
-	/* Free shadow region and segment tables. */
-	list_for_each_entry(page, &mm->context.crst_list, lru)
-		if (page->index) {
-			free_pages((unsigned long) page->index, ALLOC_ORDER);
-			page->index = 0;
-		}
-	/* "Free" second halves of page tables. */
-	list_for_each_entry(page, &mm->context.pgtable_list, lru)
-		page->flags &= ~SECOND_HALVES;
-	spin_unlock_bh(&mm->context.list_lock);
-	mm->context.noexec = 0;
-	update_mm(mm, tsk);
+	if (type)
+		__page_table_free_rcu(table, type);
+	else
+		free_pages((unsigned long) table, ALLOC_ORDER);
 }
 
+#endif
+
 /*
  * switch on pgstes for its userspace process (for kvm)
  */
@@ -411,7 +315,7 @@
 		return -EINVAL;
 
 	/* Do we have pgstes? if yes, we are done */
-	if (tsk->mm->context.has_pgste)
+	if (mm_has_pgste(tsk->mm))
 		return 0;
 
 	/* lets check if we are allowed to replace the mm */
diff -druN linux-2.6.39-libre/arch/s390/mm/vmem.c linux-3.0-rc7-libre/arch/s390/mm/vmem.c
--- linux-2.6.39-libre/arch/s390/mm/vmem.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/s390/mm/vmem.c	2011-07-11 19:51:52.000000000 -0400
@@ -95,7 +95,7 @@
 			pu_dir = vmem_pud_alloc();
 			if (!pu_dir)
 				goto out;
-			pgd_populate_kernel(&init_mm, pg_dir, pu_dir);
+			pgd_populate(&init_mm, pg_dir, pu_dir);
 		}
 
 		pu_dir = pud_offset(pg_dir, address);
@@ -103,7 +103,7 @@
 			pm_dir = vmem_pmd_alloc();
 			if (!pm_dir)
 				goto out;
-			pud_populate_kernel(&init_mm, pu_dir, pm_dir);
+			pud_populate(&init_mm, pu_dir, pm_dir);
 		}
 
 		pte = mk_pte_phys(address, __pgprot(ro ? _PAGE_RO : 0));
@@ -123,7 +123,7 @@
 			pt_dir = vmem_pte_alloc();
 			if (!pt_dir)
 				goto out;
-			pmd_populate_kernel(&init_mm, pm_dir, pt_dir);
+			pmd_populate(&init_mm, pm_dir, pt_dir);
 		}
 
 		pt_dir = pte_offset_kernel(pm_dir, address);
@@ -159,7 +159,7 @@
 			continue;
 
 		if (pmd_huge(*pm_dir)) {
-			pmd_clear_kernel(pm_dir);
+			pmd_clear(pm_dir);
 			address += HPAGE_SIZE - PAGE_SIZE;
 			continue;
 		}
@@ -192,7 +192,7 @@
 			pu_dir = vmem_pud_alloc();
 			if (!pu_dir)
 				goto out;
-			pgd_populate_kernel(&init_mm, pg_dir, pu_dir);
+			pgd_populate(&init_mm, pg_dir, pu_dir);
 		}
 
 		pu_dir = pud_offset(pg_dir, address);
@@ -200,7 +200,7 @@
 			pm_dir = vmem_pmd_alloc();
 			if (!pm_dir)
 				goto out;
-			pud_populate_kernel(&init_mm, pu_dir, pm_dir);
+			pud_populate(&init_mm, pu_dir, pm_dir);
 		}
 
 		pm_dir = pmd_offset(pu_dir, address);
@@ -208,7 +208,7 @@
 			pt_dir = vmem_pte_alloc();
 			if (!pt_dir)
 				goto out;
-			pmd_populate_kernel(&init_mm, pm_dir, pt_dir);
+			pmd_populate(&init_mm, pm_dir, pt_dir);
 		}
 
 		pt_dir = pte_offset_kernel(pm_dir, address);
diff -druN linux-2.6.39-libre/arch/s390/oprofile/hwsampler.c linux-3.0-rc7-libre/arch/s390/oprofile/hwsampler.c
--- linux-2.6.39-libre/arch/s390/oprofile/hwsampler.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/s390/oprofile/hwsampler.c	2011-07-11 19:51:52.000000000 -0400
@@ -5,6 +5,7 @@
  * Author: Heinz Graalfs <graalfs@de.ibm.com>
  */
 
+#include <linux/kernel_stat.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/smp.h>
@@ -18,7 +19,7 @@
 #include <linux/oprofile.h>
 
 #include <asm/lowcore.h>
-#include <asm/s390_ext.h>
+#include <asm/irq.h>
 
 #include "hwsampler.h"
 
@@ -579,7 +580,7 @@
 {
 	/* We do not have sampler space available for all possible CPUs.
 	   All CPUs should be online when hw sampling is activated. */
-	return NOTIFY_BAD;
+	return (hws_state <= HWS_DEALLOCATED) ? NOTIFY_OK : NOTIFY_BAD;
 }
 
 static struct notifier_block hws_cpu_notifier = {
@@ -674,17 +675,11 @@
 static void hws_ext_handler(unsigned int ext_int_code,
 			    unsigned int param32, unsigned long param64)
 {
-	int cpu;
 	struct hws_cpu_buffer *cb;
 
-	cpu = smp_processor_id();
-	cb = &per_cpu(sampler_cpu_buffer, cpu);
-
-	atomic_xchg(
-			&cb->ext_params,
-			atomic_read(&cb->ext_params)
-				| S390_lowcore.ext_params);
-
+	kstat_cpu(smp_processor_id()).irqs[EXTINT_CPM]++;
+	cb = &__get_cpu_var(sampler_cpu_buffer);
+	atomic_xchg(&cb->ext_params, atomic_read(&cb->ext_params) | param32);
 	if (hws_wq)
 		queue_work(hws_wq, &cb->worker);
 }
@@ -764,7 +759,7 @@
 	if (!sdbt || !*sdbt)
 		return -EINVAL;
 
-	if (ext_params & EI_IEA)
+	if (ext_params & EI_PRA)
 		cb->req_alert++;
 
 	if (ext_params & EI_LSDA)
@@ -1009,7 +1004,7 @@
 	if (hws_state != HWS_STOPPED)
 		goto deallocate_exit;
 
-	smp_ctl_clear_bit(0, 5); /* set bit 58 CR0 off */
+	ctl_clear_bit(0, 5); /* set bit 58 CR0 off */
 	deallocate_sdbt();
 
 	hws_state = HWS_DEALLOCATED;
@@ -1123,7 +1118,7 @@
 		mutex_lock(&hws_sem);
 
 		if (hws_state == HWS_STOPPED) {
-			smp_ctl_clear_bit(0, 5); /* set bit 58 CR0 off */
+			ctl_clear_bit(0, 5); /* set bit 58 CR0 off */
 			deallocate_sdbt();
 		}
 		if (hws_wq) {
@@ -1198,7 +1193,7 @@
 	hws_oom = 1;
 	hws_flush_all = 0;
 	/* now let them in, 1407 CPUMF external interrupts */
-	smp_ctl_set_bit(0, 5); /* set CR0 bit 58 */
+	ctl_set_bit(0, 5); /* set CR0 bit 58 */
 
 	return 0;
 }
diff -druN linux-2.6.39-libre/arch/s390/oprofile/init.c linux-3.0-rc7-libre/arch/s390/oprofile/init.c
--- linux-2.6.39-libre/arch/s390/oprofile/init.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/s390/oprofile/init.c	2011-07-11 19:51:52.000000000 -0400
@@ -25,7 +25,7 @@
 
 #include "hwsampler.h"
 
-#define DEFAULT_INTERVAL	4096
+#define DEFAULT_INTERVAL	4127518
 
 #define DEFAULT_SDBT_BLOCKS	1
 #define DEFAULT_SDB_BLOCKS	511
@@ -151,6 +151,12 @@
 	if (oprofile_max_interval == 0)
 		return -ENODEV;
 
+	/* The initial value should be sane */
+	if (oprofile_hw_interval < oprofile_min_interval)
+		oprofile_hw_interval = oprofile_min_interval;
+	if (oprofile_hw_interval > oprofile_max_interval)
+		oprofile_hw_interval = oprofile_max_interval;
+
 	if (oprofile_timer_init(ops))
 		return -ENODEV;
 
diff -druN linux-2.6.39-libre/arch/score/Kconfig linux-3.0-rc7-libre/arch/score/Kconfig
--- linux-2.6.39-libre/arch/score/Kconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/score/Kconfig	2011-07-11 19:51:52.000000000 -0400
@@ -43,9 +43,6 @@
 config RWSEM_GENERIC_SPINLOCK
 	def_bool y
 
-config GENERIC_FIND_NEXT_BIT
-	def_bool y
-
 config GENERIC_HWEIGHT
 	def_bool y
 
diff -druN linux-2.6.39-libre/arch/score/Kconfig.debug linux-3.0-rc7-libre/arch/score/Kconfig.debug
--- linux-2.6.39-libre/arch/score/Kconfig.debug	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/score/Kconfig.debug	2011-07-11 19:51:52.000000000 -0400
@@ -16,15 +16,6 @@
 	  other cases you can specify kernel args so that you don't have
 	  to set them up in board prom initialization routines.
 
-config DEBUG_STACK_USAGE
-	bool "Enable stack utilization instrumentation"
-	depends on DEBUG_KERNEL
-	help
-	  Enables the display of the minimum amount of free stack which each
-	  task has ever had available in the sysrq-T and sysrq-P debug output.
-
-	  This option will slow down process creation somewhat.
-
 config RUNTIME_DEBUG
 	bool "Enable run-time debugging"
 	depends on DEBUG_KERNEL
diff -druN linux-2.6.39-libre/arch/score/mm/init.c linux-3.0-rc7-libre/arch/score/mm/init.c
--- linux-2.6.39-libre/arch/score/mm/init.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/score/mm/init.c	2011-07-11 19:51:52.000000000 -0400
@@ -38,8 +38,6 @@
 #include <asm/sections.h>
 #include <asm/tlb.h>
 
-DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
-
 unsigned long empty_zero_page;
 EXPORT_SYMBOL_GPL(empty_zero_page);
 
diff -druN linux-2.6.39-libre/arch/sh/boards/mach-ap325rxa/setup.c linux-3.0-rc7-libre/arch/sh/boards/mach-ap325rxa/setup.c
--- linux-2.6.39-libre/arch/sh/boards/mach-ap325rxa/setup.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/sh/boards/mach-ap325rxa/setup.c	2011-07-11 19:51:52.000000000 -0400
@@ -359,37 +359,31 @@
 	.priv		= &camera_info,
 };
 
-static void dummy_release(struct device *dev)
+static struct platform_device *camera_device;
+
+static void ap325rxa_camera_release(struct device *dev)
 {
+	soc_camera_platform_release(&camera_device);
 }
 
-static struct platform_device camera_device = {
-	.name		= "soc_camera_platform",
-	.dev		= {
-		.platform_data	= &camera_info,
-		.release	= dummy_release,
-	},
-};
-
 static int ap325rxa_camera_add(struct soc_camera_link *icl,
 			       struct device *dev)
 {
-	if (icl != &camera_link || camera_probe() <= 0)
-		return -ENODEV;
+	int ret = soc_camera_platform_add(icl, dev, &camera_device, &camera_link,
+					  ap325rxa_camera_release, 0);
+	if (ret < 0)
+		return ret;
 
-	camera_info.dev = dev;
+	ret = camera_probe();
+	if (ret < 0)
+		soc_camera_platform_del(icl, camera_device, &camera_link);
 
-	return platform_device_register(&camera_device);
+	return ret;
 }
 
 static void ap325rxa_camera_del(struct soc_camera_link *icl)
 {
-	if (icl != &camera_link)
-		return;
-
-	platform_device_unregister(&camera_device);
-	memset(&camera_device.dev.kobj, 0,
-	       sizeof(camera_device.dev.kobj));
+	soc_camera_platform_del(icl, camera_device, &camera_link);
 }
 #endif /* CONFIG_I2C */
 
diff -druN linux-2.6.39-libre/arch/sh/boards/mach-ecovec24/setup.c linux-3.0-rc7-libre/arch/sh/boards/mach-ecovec24/setup.c
--- linux-2.6.39-libre/arch/sh/boards/mach-ecovec24/setup.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/sh/boards/mach-ecovec24/setup.c	2011-07-11 19:51:52.000000000 -0400
@@ -20,6 +20,7 @@
 #include <linux/io.h>
 #include <linux/delay.h>
 #include <linux/usb/r8a66597.h>
+#include <linux/usb/renesas_usbhs.h>
 #include <linux/i2c.h>
 #include <linux/i2c/tsc2007.h>
 #include <linux/spi/spi.h>
@@ -232,6 +233,52 @@
 	.resource	= usb1_common_resources,
 };
 
+/*
+ * USBHS
+ */
+static int usbhs_get_id(struct platform_device *pdev)
+{
+	return gpio_get_value(GPIO_PTB3);
+}
+
+static struct renesas_usbhs_platform_info usbhs_info = {
+	.platform_callback = {
+		.get_id		= usbhs_get_id,
+	},
+	.driver_param = {
+		.buswait_bwait		= 4,
+		.detection_delay	= 5,
+	},
+};
+
+static struct resource usbhs_resources[] = {
+	[0] = {
+		.start	= 0xa4d90000,
+		.end	= 0xa4d90124 - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= 66,
+		.end	= 66,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device usbhs_device = {
+	.name	= "renesas_usbhs",
+	.id	= 1,
+	.dev = {
+		.dma_mask		= NULL,         /*  not use dma */
+		.coherent_dma_mask	= 0xffffffff,
+		.platform_data		= &usbhs_info,
+	},
+	.num_resources	= ARRAY_SIZE(usbhs_resources),
+	.resource	= usbhs_resources,
+	.archdata = {
+		.hwblk_id = HWBLK_USB1,
+	},
+};
+
 /* LCDC */
 const static struct fb_videomode ecovec_lcd_modes[] = {
 	{
@@ -482,7 +529,7 @@
 	.irq		= IRQ0,
 };
 
-#if defined(CONFIG_MMC_TMIO) || defined(CONFIG_MMC_TMIO_MODULE)
+#if defined(CONFIG_MMC_SDHI) || defined(CONFIG_MMC_SDHI_MODULE)
 /* SDHI0 */
 static void sdhi0_set_pwr(struct platform_device *pdev, int state)
 {
@@ -522,7 +569,7 @@
 	},
 };
 
-#if !defined(CONFIG_MMC_SH_MMCIF)
+#if !defined(CONFIG_MMC_SH_MMCIF) && !defined(CONFIG_MMC_SH_MMCIF_MODULE)
 /* SDHI1 */
 static void sdhi1_set_pwr(struct platform_device *pdev, int state)
 {
@@ -836,7 +883,7 @@
 	},
 };
 
-#if defined(CONFIG_MMC_SH_MMCIF)
+#if defined(CONFIG_MMC_SH_MMCIF) || defined(CONFIG_MMC_SH_MMCIF_MODULE)
 /* SH_MMCIF */
 static void mmcif_set_pwr(struct platform_device *pdev, int state)
 {
@@ -885,6 +932,9 @@
 	},
 	.num_resources	= ARRAY_SIZE(sh_mmcif_resources),
 	.resource	= sh_mmcif_resources,
+	.archdata = {
+		.hwblk_id = HWBLK_MMC,
+	},
 };
 #endif
 
@@ -894,13 +944,14 @@
 	&sh_eth_device,
 	&usb0_host_device,
 	&usb1_common_device,
+	&usbhs_device,
 	&lcdc_device,
 	&ceu0_device,
 	&ceu1_device,
 	&keysc_device,
-#if defined(CONFIG_MMC_TMIO) || defined(CONFIG_MMC_TMIO_MODULE)
+#if defined(CONFIG_MMC_SDHI) || defined(CONFIG_MMC_SDHI_MODULE)
 	&sdhi0_device,
-#if !defined(CONFIG_MMC_SH_MMCIF)
+#if !defined(CONFIG_MMC_SH_MMCIF) && !defined(CONFIG_MMC_SH_MMCIF_MODULE)
 	&sdhi1_device,
 #endif
 #else
@@ -912,7 +963,7 @@
 	&fsi_device,
 	&irda_device,
 	&vou_device,
-#if defined(CONFIG_MMC_SH_MMCIF)
+#if defined(CONFIG_MMC_SH_MMCIF) || defined(CONFIG_MMC_SH_MMCIF_MODULE)
 	&sh_mmcif_device,
 #endif
 };
@@ -1180,7 +1231,7 @@
 	gpio_direction_input(GPIO_PTR5);
 	gpio_direction_input(GPIO_PTR6);
 
-#if defined(CONFIG_MMC_TMIO) || defined(CONFIG_MMC_TMIO_MODULE)
+#if defined(CONFIG_MMC_SDHI) || defined(CONFIG_MMC_SDHI_MODULE)
 	/* enable SDHI0 on CN11 (needs DS2.4 set to ON) */
 	gpio_request(GPIO_FN_SDHI0CD,  NULL);
 	gpio_request(GPIO_FN_SDHI0WP,  NULL);
@@ -1193,7 +1244,7 @@
 	gpio_request(GPIO_PTB6, NULL);
 	gpio_direction_output(GPIO_PTB6, 0);
 
-#if !defined(CONFIG_MMC_SH_MMCIF)
+#if !defined(CONFIG_MMC_SH_MMCIF) && !defined(CONFIG_MMC_SH_MMCIF_MODULE)
 	/* enable SDHI1 on CN12 (needs DS2.6,7 set to ON,OFF) */
 	gpio_request(GPIO_FN_SDHI1CD,  NULL);
 	gpio_request(GPIO_FN_SDHI1WP,  NULL);
@@ -1284,7 +1335,7 @@
 	gpio_request(GPIO_PTU5, NULL);
 	gpio_direction_output(GPIO_PTU5, 0);
 
-#if defined(CONFIG_MMC_SH_MMCIF)
+#if defined(CONFIG_MMC_SH_MMCIF) || defined(CONFIG_MMC_SH_MMCIF_MODULE)
 	/* enable MMCIF (needs DS2.6,7 set to OFF,ON) */
 	gpio_request(GPIO_FN_MMC_D7, NULL);
 	gpio_request(GPIO_FN_MMC_D6, NULL);
diff -druN linux-2.6.39-libre/arch/sh/boot/compressed/Makefile linux-3.0-rc7-libre/arch/sh/boot/compressed/Makefile
--- linux-2.6.39-libre/arch/sh/boot/compressed/Makefile	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/sh/boot/compressed/Makefile	2011-07-11 19:51:52.000000000 -0400
@@ -27,8 +27,6 @@
 			$(CONFIG_BOOT_LINK_OFFSET)]')
 endif
 
-LIBGCC	:= $(shell $(CC) $(KBUILD_CFLAGS) -print-libgcc-file-name)
-
 ifeq ($(CONFIG_MCOUNT),y)
 ORIG_CFLAGS := $(KBUILD_CFLAGS)
 KBUILD_CFLAGS = $(subst -pg, , $(ORIG_CFLAGS))
@@ -37,7 +35,25 @@
 LDFLAGS_vmlinux := --oformat $(ld-bfd) -Ttext $(IMAGE_OFFSET) -e startup \
 		   -T $(obj)/../../kernel/vmlinux.lds
 
-$(obj)/vmlinux: $(OBJECTS) $(obj)/piggy.o $(LIBGCC) FORCE
+#
+# Pull in the necessary libgcc bits from the in-kernel implementation.
+#
+lib1funcs-$(CONFIG_SUPERH32)	:= ashiftrt.S ashldi3.c ashrsi3.S ashlsi3.S \
+				   lshrsi3.S
+lib1funcs-obj			:= \
+	$(addsuffix .o, $(basename $(addprefix $(obj)/, $(lib1funcs-y))))
+
+lib1funcs-dir		:= $(srctree)/arch/$(SRCARCH)/lib
+ifeq ($(BITS),64)
+	lib1funcs-dir 	:= $(addsuffix $(BITS), $(lib1funcs-dir))
+endif
+
+KBUILD_CFLAGS += -I$(lib1funcs-dir)
+
+$(addprefix $(obj)/,$(lib1funcs-y)): $(obj)/%: $(lib1funcs-dir)/% FORCE
+	$(call cmd,shipped)
+
+$(obj)/vmlinux: $(OBJECTS) $(obj)/piggy.o $(lib1funcs-obj) FORCE
 	$(call if_changed,ld)
 	@:
 
diff -druN linux-2.6.39-libre/arch/sh/configs/apsh4ad0a_defconfig linux-3.0-rc7-libre/arch/sh/configs/apsh4ad0a_defconfig
--- linux-2.6.39-libre/arch/sh/configs/apsh4ad0a_defconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/sh/configs/apsh4ad0a_defconfig	2011-07-11 19:51:52.000000000 -0400
@@ -7,7 +7,6 @@
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_CGROUPS=y
-CONFIG_CGROUP_NS=y
 CONFIG_CGROUP_FREEZER=y
 CONFIG_CGROUP_DEVICE=y
 CONFIG_CGROUP_CPUACCT=y
@@ -48,7 +47,6 @@
 CONFIG_BINFMT_MISC=y
 CONFIG_PM=y
 CONFIG_PM_DEBUG=y
-CONFIG_PM_VERBOSE=y
 CONFIG_PM_RUNTIME=y
 CONFIG_CPU_IDLE=y
 CONFIG_NET=y
diff -druN linux-2.6.39-libre/arch/sh/configs/ecovec24_defconfig linux-3.0-rc7-libre/arch/sh/configs/ecovec24_defconfig
--- linux-2.6.39-libre/arch/sh/configs/ecovec24_defconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/sh/configs/ecovec24_defconfig	2011-07-11 19:51:52.000000000 -0400
@@ -115,7 +115,7 @@
 CONFIG_USB_FILE_STORAGE=m
 CONFIG_MMC=y
 CONFIG_MMC_SPI=y
-CONFIG_MMC_TMIO=y
+CONFIG_MMC_SDHI=y
 CONFIG_RTC_CLASS=y
 CONFIG_RTC_DRV_RS5C372=y
 CONFIG_UIO=y
diff -druN linux-2.6.39-libre/arch/sh/configs/sdk7786_defconfig linux-3.0-rc7-libre/arch/sh/configs/sdk7786_defconfig
--- linux-2.6.39-libre/arch/sh/configs/sdk7786_defconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/sh/configs/sdk7786_defconfig	2011-07-11 19:51:52.000000000 -0400
@@ -12,7 +12,6 @@
 CONFIG_IKCONFIG_PROC=y
 CONFIG_CGROUPS=y
 CONFIG_CGROUP_DEBUG=y
-CONFIG_CGROUP_NS=y
 CONFIG_CGROUP_FREEZER=y
 CONFIG_CGROUP_DEVICE=y
 CONFIG_CPUSETS=y
@@ -83,7 +82,6 @@
 CONFIG_BINFMT_MISC=y
 CONFIG_PM=y
 CONFIG_PM_DEBUG=y
-CONFIG_PM_VERBOSE=y
 CONFIG_PM_RUNTIME=y
 CONFIG_CPU_IDLE=y
 CONFIG_NET=y
diff -druN linux-2.6.39-libre/arch/sh/configs/se7206_defconfig linux-3.0-rc7-libre/arch/sh/configs/se7206_defconfig
--- linux-2.6.39-libre/arch/sh/configs/se7206_defconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/sh/configs/se7206_defconfig	2011-07-11 19:51:52.000000000 -0400
@@ -8,7 +8,6 @@
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_CGROUPS=y
 CONFIG_CGROUP_DEBUG=y
-CONFIG_CGROUP_NS=y
 CONFIG_CGROUP_DEVICE=y
 CONFIG_CGROUP_CPUACCT=y
 CONFIG_RESOURCE_COUNTERS=y
diff -druN linux-2.6.39-libre/arch/sh/configs/sh7757lcr_defconfig linux-3.0-rc7-libre/arch/sh/configs/sh7757lcr_defconfig
--- linux-2.6.39-libre/arch/sh/configs/sh7757lcr_defconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/sh/configs/sh7757lcr_defconfig	2011-07-11 19:51:52.000000000 -0400
@@ -9,7 +9,6 @@
 CONFIG_TASK_IO_ACCOUNTING=y
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_BLK_DEV_INITRD=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 # CONFIG_SYSCTL_SYSCALL is not set
 CONFIG_KALLSYMS_ALL=y
 CONFIG_SLAB=y
@@ -39,8 +38,6 @@
 CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
 # CONFIG_FW_LOADER is not set
 CONFIG_MTD=y
-CONFIG_MTD_CONCAT=y
-CONFIG_MTD_PARTITIONS=y
 CONFIG_MTD_CHAR=y
 CONFIG_MTD_BLOCK=y
 CONFIG_MTD_M25P80=y
@@ -56,21 +53,22 @@
 # CONFIG_KEYBOARD_ATKBD is not set
 # CONFIG_MOUSE_PS2 is not set
 # CONFIG_SERIO is not set
+# CONFIG_LEGACY_PTYS is not set
 CONFIG_SERIAL_SH_SCI=y
 CONFIG_SERIAL_SH_SCI_NR_UARTS=3
 CONFIG_SERIAL_SH_SCI_CONSOLE=y
-# CONFIG_LEGACY_PTYS is not set
 # CONFIG_HW_RANDOM is not set
 CONFIG_SPI=y
 CONFIG_SPI_SH=y
 # CONFIG_HWMON is not set
-CONFIG_MFD_SH_MOBILE_SDHI=y
 CONFIG_USB=y
 CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_EHCI_SH=y
 CONFIG_USB_OHCI_HCD=y
+CONFIG_USB_OHCI_SH=y
 CONFIG_USB_STORAGE=y
 CONFIG_MMC=y
-CONFIG_MMC_TMIO=y
+CONFIG_MMC_SDHI=y
 CONFIG_MMC_SH_MMCIF=y
 CONFIG_EXT2_FS=y
 CONFIG_EXT3_FS=y
diff -druN linux-2.6.39-libre/arch/sh/configs/shx3_defconfig linux-3.0-rc7-libre/arch/sh/configs/shx3_defconfig
--- linux-2.6.39-libre/arch/sh/configs/shx3_defconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/sh/configs/shx3_defconfig	2011-07-11 19:51:52.000000000 -0400
@@ -9,7 +9,6 @@
 CONFIG_IKCONFIG_PROC=y
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_CGROUPS=y
-CONFIG_CGROUP_NS=y
 CONFIG_CGROUP_FREEZER=y
 CONFIG_CGROUP_DEVICE=y
 CONFIG_CGROUP_CPUACCT=y
diff -druN linux-2.6.39-libre/arch/sh/configs/titan_defconfig linux-3.0-rc7-libre/arch/sh/configs/titan_defconfig
--- linux-2.6.39-libre/arch/sh/configs/titan_defconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/sh/configs/titan_defconfig	2011-07-11 19:51:52.000000000 -0400
@@ -227,7 +227,7 @@
 CONFIG_USB_SERIAL_GENERIC=y
 CONFIG_USB_SERIAL_ARK3116=m
 CONFIG_USB_SERIAL_PL2303=m
-CONFIG_RTC_CLASS=m
+CONFIG_RTC_CLASS=y
 CONFIG_RTC_DRV_SH=m
 CONFIG_EXT2_FS=y
 CONFIG_EXT3_FS=y
diff -druN linux-2.6.39-libre/arch/sh/configs/urquell_defconfig linux-3.0-rc7-libre/arch/sh/configs/urquell_defconfig
--- linux-2.6.39-libre/arch/sh/configs/urquell_defconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/sh/configs/urquell_defconfig	2011-07-11 19:51:52.000000000 -0400
@@ -9,7 +9,6 @@
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_CGROUPS=y
 CONFIG_CGROUP_DEBUG=y
-CONFIG_CGROUP_NS=y
 CONFIG_CGROUP_FREEZER=y
 CONFIG_CGROUP_DEVICE=y
 CONFIG_CPUSETS=y
diff -druN linux-2.6.39-libre/arch/sh/drivers/pci/fixups-se7751.c linux-3.0-rc7-libre/arch/sh/drivers/pci/fixups-se7751.c
--- linux-2.6.39-libre/arch/sh/drivers/pci/fixups-se7751.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/sh/drivers/pci/fixups-se7751.c	2011-07-11 19:51:52.000000000 -0400
@@ -6,7 +6,7 @@
 #include <linux/io.h>
 #include "pci-sh4.h"
 
-int __init pcibios_map_platform_irq(u8 slot, u8 pin)
+int __init pcibios_map_platform_irq(struct pci_dev *, u8 slot, u8 pin)
 {
         switch (slot) {
         case 0: return 13;
diff -druN linux-2.6.39-libre/arch/sh/include/asm/cmpxchg-grb.h linux-3.0-rc7-libre/arch/sh/include/asm/cmpxchg-grb.h
--- linux-2.6.39-libre/arch/sh/include/asm/cmpxchg-grb.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/sh/include/asm/cmpxchg-grb.h	2011-07-11 19:51:52.000000000 -0400
@@ -15,8 +15,9 @@
 		"   mov.l   %2,   @%1     \n\t" /* store new value */
 		"1: mov     r1,   r15     \n\t" /* LOGOUT */
 		: "=&r" (retval),
-		  "+r"  (m)
-		: "r"   (val)
+		  "+r"  (m),
+		  "+r"  (val)		/* inhibit r15 overloading */
+		:
 		: "memory", "r0", "r1");
 
 	return retval;
@@ -36,8 +37,9 @@
 		"   mov.b   %2,   @%1     \n\t" /* store new value */
 		"1: mov     r1,   r15     \n\t" /* LOGOUT */
 		: "=&r" (retval),
-		  "+r"  (m)
-		: "r"   (val)
+		  "+r"  (m),
+		  "+r"  (val)		/* inhibit r15 overloading */
+		:
 		: "memory" , "r0", "r1");
 
 	return retval;
@@ -54,13 +56,14 @@
 		"   nop                   \n\t"
 		"   mov    r15,   r1      \n\t" /* r1 = saved sp */
 		"   mov    #-8,   r15     \n\t" /* LOGIN */
-		"   mov.l  @%1,   %0      \n\t" /* load  old value */
-		"   cmp/eq  %0,   %2      \n\t"
+		"   mov.l  @%3,   %0      \n\t" /* load  old value */
+		"   cmp/eq  %0,   %1      \n\t"
 		"   bf            1f      \n\t" /* if not equal */
-		"   mov.l   %3,   @%1     \n\t" /* store new value */
+		"   mov.l   %2,   @%3     \n\t" /* store new value */
 		"1: mov     r1,   r15     \n\t" /* LOGOUT */
-		: "=&r" (retval)
-		:  "r"  (m), "r"  (old), "r"  (new)
+		: "=&r" (retval),
+		  "+r"  (old), "+r"  (new) /* old or new can be r15 */
+		:  "r"  (m)
 		: "memory" , "r0", "r1", "t");
 
 	return retval;
diff -druN linux-2.6.39-libre/arch/sh/include/asm/kgdb.h linux-3.0-rc7-libre/arch/sh/include/asm/kgdb.h
--- linux-2.6.39-libre/arch/sh/include/asm/kgdb.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/sh/include/asm/kgdb.h	2011-07-11 19:51:52.000000000 -0400
@@ -34,5 +34,6 @@
 
 #define CACHE_FLUSH_IS_SAFE	1
 #define BREAK_INSTR_SIZE	2
+#define GDB_ADJUSTS_BREAK_OFFSET
 
 #endif /* __ASM_SH_KGDB_H */
diff -druN linux-2.6.39-libre/arch/sh/include/asm/mmzone.h linux-3.0-rc7-libre/arch/sh/include/asm/mmzone.h
--- linux-2.6.39-libre/arch/sh/include/asm/mmzone.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/sh/include/asm/mmzone.h	2011-07-11 19:51:52.000000000 -0400
@@ -9,10 +9,6 @@
 extern struct pglist_data *node_data[];
 #define NODE_DATA(nid)		(node_data[nid])
 
-#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)
-
 static inline int pfn_to_nid(unsigned long pfn)
 {
 	int nid;
diff -druN linux-2.6.39-libre/arch/sh/include/asm/pgtable.h linux-3.0-rc7-libre/arch/sh/include/asm/pgtable.h
--- linux-2.6.39-libre/arch/sh/include/asm/pgtable.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/sh/include/asm/pgtable.h	2011-07-11 19:51:52.000000000 -0400
@@ -18,6 +18,7 @@
 #include <asm/pgtable-2level.h>
 #endif
 #include <asm/page.h>
+#include <asm/mmu.h>
 
 #ifndef __ASSEMBLY__
 #include <asm/addrspace.h>
diff -druN linux-2.6.39-libre/arch/sh/include/asm/processor_64.h linux-3.0-rc7-libre/arch/sh/include/asm/processor_64.h
--- linux-2.6.39-libre/arch/sh/include/asm/processor_64.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/sh/include/asm/processor_64.h	2011-07-11 19:51:52.000000000 -0400
@@ -150,7 +150,6 @@
 #define SR_USER (SR_MMU | SR_FD)
 
 #define start_thread(_regs, new_pc, new_sp)			\
-	set_fs(USER_DS);					\
 	_regs->sr = SR_USER;	/* User mode. */		\
 	_regs->pc = new_pc - 4;	/* Compensate syscall exit */	\
 	_regs->pc |= 1;		/* Set SHmedia ! */		\
diff -druN linux-2.6.39-libre/arch/sh/include/asm/ptrace.h linux-3.0-rc7-libre/arch/sh/include/asm/ptrace.h
--- linux-2.6.39-libre/arch/sh/include/asm/ptrace.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/sh/include/asm/ptrace.h	2011-07-11 19:51:52.000000000 -0400
@@ -40,9 +40,10 @@
 #include <asm/system.h>
 
 #define user_mode(regs)			(((regs)->sr & 0x40000000)==0)
-#define user_stack_pointer(_regs)	((unsigned long)(_regs)->regs[15])
 #define kernel_stack_pointer(_regs)	((unsigned long)(_regs)->regs[15])
-#define instruction_pointer(regs)	((unsigned long)(regs)->pc)
+
+#define GET_FP(regs)	((regs)->regs[14])
+#define GET_USP(regs)	((regs)->regs[15])
 
 extern void show_regs(struct pt_regs *);
 
@@ -132,13 +133,16 @@
 
 static inline unsigned long profile_pc(struct pt_regs *regs)
 {
-	unsigned long pc = instruction_pointer(regs);
+	unsigned long pc = regs->pc;
 
 	if (virt_addr_uncached(pc))
 		return CAC_ADDR(pc);
 
 	return pc;
 }
+#define profile_pc profile_pc
+
+#include <asm-generic/ptrace.h>
 #endif /* __KERNEL__ */
 
 #endif /* __ASM_SH_PTRACE_H */
diff -druN linux-2.6.39-libre/arch/sh/include/asm/stacktrace.h linux-3.0-rc7-libre/arch/sh/include/asm/stacktrace.h
--- linux-2.6.39-libre/arch/sh/include/asm/stacktrace.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/sh/include/asm/stacktrace.h	2011-07-11 19:51:52.000000000 -0400
@@ -10,9 +10,6 @@
 /* Generic stack tracer with callbacks */
 
 struct stacktrace_ops {
-	void (*warning)(void *data, char *msg);
-	/* msg must contain %s for the symbol */
-	void (*warning_symbol)(void *data, char *msg, unsigned long symbol);
 	void (*address)(void *data, unsigned long address, int reliable);
 	/* On negative return stop dumping */
 	int (*stack)(void *data, char *name);
diff -druN linux-2.6.39-libre/arch/sh/include/asm/suspend.h linux-3.0-rc7-libre/arch/sh/include/asm/suspend.h
--- linux-2.6.39-libre/arch/sh/include/asm/suspend.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/sh/include/asm/suspend.h	2011-07-11 19:51:52.000000000 -0400
@@ -3,7 +3,6 @@
 
 #ifndef __ASSEMBLY__
 #include <linux/notifier.h>
-static inline int arch_prepare_suspend(void) { return 0; }
 
 #include <asm/ptrace.h>
 
diff -druN linux-2.6.39-libre/arch/sh/include/asm/tlb.h linux-3.0-rc7-libre/arch/sh/include/asm/tlb.h
--- linux-2.6.39-libre/arch/sh/include/asm/tlb.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/sh/include/asm/tlb.h	2011-07-11 19:51:52.000000000 -0400
@@ -9,6 +9,7 @@
 #include <linux/pagemap.h>
 
 #ifdef CONFIG_MMU
+#include <linux/swap.h>
 #include <asm/pgalloc.h>
 #include <asm/tlbflush.h>
 #include <asm/mmu_context.h>
@@ -23,8 +24,6 @@
 	unsigned long		start, end;
 };
 
-DECLARE_PER_CPU(struct mmu_gather, mmu_gathers);
-
 static inline void init_tlb_gather(struct mmu_gather *tlb)
 {
 	tlb->start = TASK_SIZE;
@@ -36,17 +35,13 @@
 	}
 }
 
-static inline struct mmu_gather *
-tlb_gather_mmu(struct mm_struct *mm, unsigned int full_mm_flush)
+static inline void
+tlb_gather_mmu(struct mmu_gather *tlb, struct mm_struct *mm, unsigned int full_mm_flush)
 {
-	struct mmu_gather *tlb = &get_cpu_var(mmu_gathers);
-
 	tlb->mm = mm;
 	tlb->fullmm = full_mm_flush;
 
 	init_tlb_gather(tlb);
-
-	return tlb;
 }
 
 static inline void
@@ -57,8 +52,6 @@
 
 	/* keep the page table cache within bounds */
 	check_pgt_cache();
-
-	put_cpu_var(mmu_gathers);
 }
 
 static inline void
@@ -91,7 +84,21 @@
 	}
 }
 
-#define tlb_remove_page(tlb,page)	free_page_and_swap_cache(page)
+static inline void tlb_flush_mmu(struct mmu_gather *tlb)
+{
+}
+
+static inline int __tlb_remove_page(struct mmu_gather *tlb, struct page *page)
+{
+	free_page_and_swap_cache(page);
+	return 1; /* avoid calling tlb_flush_mmu */
+}
+
+static inline void tlb_remove_page(struct mmu_gather *tlb, struct page *page)
+{
+	__tlb_remove_page(tlb, page);
+}
+
 #define pte_free_tlb(tlb, ptep, addr)	pte_free((tlb)->mm, ptep)
 #define pmd_free_tlb(tlb, pmdp, addr)	pmd_free((tlb)->mm, pmdp)
 #define pud_free_tlb(tlb, pudp, addr)	pud_free((tlb)->mm, pudp)
diff -druN linux-2.6.39-libre/arch/sh/include/asm/unistd_32.h linux-3.0-rc7-libre/arch/sh/include/asm/unistd_32.h
--- linux-2.6.39-libre/arch/sh/include/asm/unistd_32.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/sh/include/asm/unistd_32.h	2011-07-11 19:51:52.000000000 -0400
@@ -373,8 +373,10 @@
 #define __NR_open_by_handle_at	360
 #define __NR_clock_adjtime	361
 #define __NR_syncfs		362
+#define __NR_sendmmsg		363
+#define __NR_setns		364
 
-#define NR_syscalls 363
+#define NR_syscalls 365
 
 #ifdef __KERNEL__
 
diff -druN linux-2.6.39-libre/arch/sh/include/asm/unistd_64.h linux-3.0-rc7-libre/arch/sh/include/asm/unistd_64.h
--- linux-2.6.39-libre/arch/sh/include/asm/unistd_64.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/sh/include/asm/unistd_64.h	2011-07-11 19:51:52.000000000 -0400
@@ -394,10 +394,12 @@
 #define __NR_open_by_handle_at	371
 #define __NR_clock_adjtime	372
 #define __NR_syncfs		373
+#define __NR_sendmmsg		374
+#define __NR_setns		375
 
 #ifdef __KERNEL__
 
-#define NR_syscalls 374
+#define NR_syscalls 376
 
 #define __ARCH_WANT_IPC_PARSE_VERSION
 #define __ARCH_WANT_OLD_READDIR
diff -druN linux-2.6.39-libre/arch/sh/include/cpu-sh4/cpu/sh7722.h linux-3.0-rc7-libre/arch/sh/include/cpu-sh4/cpu/sh7722.h
--- linux-2.6.39-libre/arch/sh/include/cpu-sh4/cpu/sh7722.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/sh/include/cpu-sh4/cpu/sh7722.h	2011-07-11 19:51:52.000000000 -0400
@@ -236,6 +236,7 @@
 };
 
 enum {
+	SHDMA_SLAVE_INVALID,
 	SHDMA_SLAVE_SCIF0_TX,
 	SHDMA_SLAVE_SCIF0_RX,
 	SHDMA_SLAVE_SCIF1_TX,
diff -druN linux-2.6.39-libre/arch/sh/include/cpu-sh4/cpu/sh7724.h linux-3.0-rc7-libre/arch/sh/include/cpu-sh4/cpu/sh7724.h
--- linux-2.6.39-libre/arch/sh/include/cpu-sh4/cpu/sh7724.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/sh/include/cpu-sh4/cpu/sh7724.h	2011-07-11 19:51:52.000000000 -0400
@@ -285,6 +285,7 @@
 };
 
 enum {
+	SHDMA_SLAVE_INVALID,
 	SHDMA_SLAVE_SCIF0_TX,
 	SHDMA_SLAVE_SCIF0_RX,
 	SHDMA_SLAVE_SCIF1_TX,
@@ -297,6 +298,14 @@
 	SHDMA_SLAVE_SCIF4_RX,
 	SHDMA_SLAVE_SCIF5_TX,
 	SHDMA_SLAVE_SCIF5_RX,
+	SHDMA_SLAVE_USB0D0_TX,
+	SHDMA_SLAVE_USB0D0_RX,
+	SHDMA_SLAVE_USB0D1_TX,
+	SHDMA_SLAVE_USB0D1_RX,
+	SHDMA_SLAVE_USB1D0_TX,
+	SHDMA_SLAVE_USB1D0_RX,
+	SHDMA_SLAVE_USB1D1_TX,
+	SHDMA_SLAVE_USB1D1_RX,
 	SHDMA_SLAVE_SDHI0_TX,
 	SHDMA_SLAVE_SDHI0_RX,
 	SHDMA_SLAVE_SDHI1_TX,
diff -druN linux-2.6.39-libre/arch/sh/include/cpu-sh4/cpu/sh7757.h linux-3.0-rc7-libre/arch/sh/include/cpu-sh4/cpu/sh7757.h
--- linux-2.6.39-libre/arch/sh/include/cpu-sh4/cpu/sh7757.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/sh/include/cpu-sh4/cpu/sh7757.h	2011-07-11 19:51:52.000000000 -0400
@@ -252,6 +252,7 @@
 };
 
 enum {
+	SHDMA_SLAVE_INVALID,
 	SHDMA_SLAVE_SDHI_TX,
 	SHDMA_SLAVE_SDHI_RX,
 	SHDMA_SLAVE_MMCIF_TX,
diff -druN linux-2.6.39-libre/arch/sh/Kconfig linux-3.0-rc7-libre/arch/sh/Kconfig
--- linux-2.6.39-libre/arch/sh/Kconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/sh/Kconfig	2011-07-11 19:51:52.000000000 -0400
@@ -21,10 +21,10 @@
 	select HAVE_REGS_AND_STACK_ACCESS_API
 	select HAVE_GENERIC_HARDIRQS
 	select HAVE_SPARSE_IRQ
+	select IRQ_FORCED_THREADING
 	select RTC_LIB
 	select GENERIC_ATOMIC64
 	select GENERIC_IRQ_SHOW
-	select ARCH_NO_SYSDEV_OPS
 	help
 	  The SuperH is a RISC processor targeted for use in embedded systems
 	  and consumer electronics; it was also used in the Sega Dreamcast
@@ -71,12 +71,6 @@
 	def_bool y
 	depends on SUPERH64
 
-config GENERIC_FIND_NEXT_BIT
-	def_bool y
-
-config GENERIC_FIND_BIT_LE
-	def_bool y
-
 config GENERIC_HWEIGHT
 	def_bool y
 
@@ -167,7 +161,7 @@
 
 config NO_IOPORT
 	def_bool !PCI
-	depends on !SH_CAYMAN && !SH_SH4202_MICRODEV
+	depends on !SH_CAYMAN && !SH_SH4202_MICRODEV && !SH_SHMIN
 
 config IO_TRAPPED
 	bool
@@ -354,6 +348,7 @@
 	select SYS_SUPPORTS_CMT
 	select ARCH_WANT_OPTIONAL_GPIOLIB
 	select USB_ARCH_HAS_OHCI
+	select USB_OHCI_SH if USB_OHCI_HCD
 	help
 	  Select SH7720 if you have a SH3-DSP SH7720 CPU.
 
@@ -363,6 +358,7 @@
 	select CPU_HAS_DSP
 	select SYS_SUPPORTS_CMT
 	select USB_ARCH_HAS_OHCI
+	select USB_OHCI_SH if USB_OHCI_HCD
 	help
 	  Select SH7721 if you have a SH3-DSP SH7721 CPU.
 
@@ -446,6 +442,7 @@
 	bool "Support SH7763 processor"
 	select CPU_SH4A
 	select USB_ARCH_HAS_OHCI
+	select USB_OHCI_SH if USB_OHCI_HCD
 	help
 	  Select SH7763 if you have a SH4A SH7763(R5S77631) CPU.
 
@@ -473,7 +470,9 @@
 	select GENERIC_CLOCKEVENTS_BROADCAST if SMP
 	select ARCH_WANT_OPTIONAL_GPIOLIB
 	select USB_ARCH_HAS_OHCI
+	select USB_OHCI_SH if USB_OHCI_HCD
 	select USB_ARCH_HAS_EHCI
+	select USB_EHCI_SH if USB_EHCI_HCD
 
 config CPU_SUBTYPE_SHX3
 	bool "Support SH-X3 processor"
diff -druN linux-2.6.39-libre/arch/sh/Kconfig.debug linux-3.0-rc7-libre/arch/sh/Kconfig.debug
--- linux-2.6.39-libre/arch/sh/Kconfig.debug	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/sh/Kconfig.debug	2011-07-11 19:51:52.000000000 -0400
@@ -28,15 +28,6 @@
 	  every function call and will therefore incur a major
 	  performance hit. Most users should say N.
 
-config DEBUG_STACK_USAGE
-	bool "Stack utilization instrumentation"
-	depends on DEBUG_KERNEL
-	help
-	  Enables the display of the minimum amount of free stack which each
-	  task has ever had available in the sysrq-T and sysrq-P debug output.
-
-	  This option will slow down process creation somewhat.
-
 config 4KSTACKS
 	bool "Use 4Kb for kernel stacks instead of 8Kb"
 	depends on DEBUG_KERNEL && (MMU || BROKEN) && !PAGE_SIZE_64KB
diff -druN linux-2.6.39-libre/arch/sh/kernel/cpu/Makefile linux-3.0-rc7-libre/arch/sh/kernel/cpu/Makefile
--- linux-2.6.39-libre/arch/sh/kernel/cpu/Makefile	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/sh/kernel/cpu/Makefile	2011-07-11 19:51:52.000000000 -0400
@@ -17,7 +17,5 @@
 
 obj-$(CONFIG_SH_ADC)		+= adc.o
 obj-$(CONFIG_SH_CLK_CPG_LEGACY)	+= 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 proc.o
+obj-y	+= irq/ init.o clock.o fpu.o hwblk.o proc.o
diff -druN linux-2.6.39-libre/arch/sh/kernel/cpu/sh4/sq.c linux-3.0-rc7-libre/arch/sh/kernel/cpu/sh4/sq.c
--- linux-2.6.39-libre/arch/sh/kernel/cpu/sh4/sq.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/sh/kernel/cpu/sh4/sq.c	2011-07-11 19:51:52.000000000 -0400
@@ -20,6 +20,7 @@
 #include <linux/vmalloc.h>
 #include <linux/mm.h>
 #include <linux/io.h>
+#include <linux/prefetch.h>
 #include <asm/page.h>
 #include <asm/cacheflush.h>
 #include <cpu/sq.h>
diff -druN linux-2.6.39-libre/arch/sh/kernel/cpu/sh4a/setup-sh7724.c linux-3.0-rc7-libre/arch/sh/kernel/cpu/sh4a/setup-sh7724.c
--- linux-2.6.39-libre/arch/sh/kernel/cpu/sh4a/setup-sh7724.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/sh/kernel/cpu/sh4a/setup-sh7724.c	2011-07-11 19:51:52.000000000 -0400
@@ -93,6 +93,46 @@
 		.chcr		= DM_INC | SM_FIX | 0x800 | TS_INDEX2VAL(XMIT_SZ_8BIT),
 		.mid_rid	= 0x36,
 	}, {
+		.slave_id	= SHDMA_SLAVE_USB0D0_TX,
+		.addr		= 0xA4D80100,
+		.chcr		= DM_FIX | SM_INC | 0x800 | TS_INDEX2VAL(XMIT_SZ_32BIT),
+		.mid_rid	= 0x73,
+	}, {
+		.slave_id	= SHDMA_SLAVE_USB0D0_RX,
+		.addr		= 0xA4D80100,
+		.chcr		= DM_INC | SM_FIX | 0x800 | TS_INDEX2VAL(XMIT_SZ_32BIT),
+		.mid_rid	= 0x73,
+	}, {
+		.slave_id	= SHDMA_SLAVE_USB0D1_TX,
+		.addr		= 0xA4D80120,
+		.chcr		= DM_FIX | SM_INC | 0x800 | TS_INDEX2VAL(XMIT_SZ_32BIT),
+		.mid_rid	= 0x77,
+	}, {
+		.slave_id	= SHDMA_SLAVE_USB0D1_RX,
+		.addr		= 0xA4D80120,
+		.chcr		= DM_INC | SM_FIX | 0x800 | TS_INDEX2VAL(XMIT_SZ_32BIT),
+		.mid_rid	= 0x77,
+	}, {
+		.slave_id	= SHDMA_SLAVE_USB1D0_TX,
+		.addr		= 0xA4D90100,
+		.chcr		= DM_FIX | SM_INC | 0x800 | TS_INDEX2VAL(XMIT_SZ_32BIT),
+		.mid_rid	= 0xab,
+	}, {
+		.slave_id	= SHDMA_SLAVE_USB1D0_RX,
+		.addr		= 0xA4D90100,
+		.chcr		= DM_INC | SM_FIX | 0x800 | TS_INDEX2VAL(XMIT_SZ_32BIT),
+		.mid_rid	= 0xab,
+	}, {
+		.slave_id	= SHDMA_SLAVE_USB1D1_TX,
+		.addr		= 0xA4D90120,
+		.chcr		= DM_FIX | SM_INC | 0x800 | TS_INDEX2VAL(XMIT_SZ_32BIT),
+		.mid_rid	= 0xaf,
+	}, {
+		.slave_id	= SHDMA_SLAVE_USB1D1_RX,
+		.addr		= 0xA4D90120,
+		.chcr		= DM_INC | SM_FIX | 0x800 | TS_INDEX2VAL(XMIT_SZ_32BIT),
+		.mid_rid	= 0xaf,
+	}, {
 		.slave_id	= SHDMA_SLAVE_SDHI0_TX,
 		.addr		= 0x04ce0030,
 		.chcr		= DM_FIX | SM_INC | 0x800 | TS_INDEX2VAL(XMIT_SZ_16BIT),
diff -druN linux-2.6.39-libre/arch/sh/kernel/cpu/sh4a/setup-sh7757.c linux-3.0-rc7-libre/arch/sh/kernel/cpu/sh4a/setup-sh7757.c
--- linux-2.6.39-libre/arch/sh/kernel/cpu/sh4a/setup-sh7757.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/sh/kernel/cpu/sh4a/setup-sh7757.c	2011-07-11 19:51:52.000000000 -0400
@@ -183,7 +183,7 @@
 	{
 		.slave_id	= SHDMA_SLAVE_SCIF2_RX,
 		.addr		= 0x1f4b0014,
-		.chcr		= SM_INC | 0x800 | 0x40000000 |
+		.chcr		= DM_INC | 0x800 | 0x40000000 |
 				  TS_INDEX2VAL(XMIT_SZ_8BIT),
 		.mid_rid	= 0x22,
 	},
@@ -197,7 +197,7 @@
 	{
 		.slave_id	= SHDMA_SLAVE_SCIF3_RX,
 		.addr		= 0x1f4c0014,
-		.chcr		= SM_INC | 0x800 | 0x40000000 |
+		.chcr		= DM_INC | 0x800 | 0x40000000 |
 				  TS_INDEX2VAL(XMIT_SZ_8BIT),
 		.mid_rid	= 0x2a,
 	},
@@ -211,7 +211,7 @@
 	{
 		.slave_id	= SHDMA_SLAVE_SCIF4_RX,
 		.addr		= 0x1f4d0014,
-		.chcr		= SM_INC | 0x800 | 0x40000000 |
+		.chcr		= DM_INC | 0x800 | 0x40000000 |
 				  TS_INDEX2VAL(XMIT_SZ_8BIT),
 		.mid_rid	= 0x42,
 	},
@@ -228,7 +228,7 @@
 	{
 		.slave_id	= SHDMA_SLAVE_RIIC0_RX,
 		.addr		= 0x1e500013,
-		.chcr		= SM_INC | 0x800 | 0x40000000 |
+		.chcr		= DM_INC | 0x800 | 0x40000000 |
 				  TS_INDEX2VAL(XMIT_SZ_8BIT),
 		.mid_rid	= 0x22,
 	},
@@ -242,7 +242,7 @@
 	{
 		.slave_id	= SHDMA_SLAVE_RIIC1_RX,
 		.addr		= 0x1e510013,
-		.chcr		= SM_INC | 0x800 | 0x40000000 |
+		.chcr		= DM_INC | 0x800 | 0x40000000 |
 				  TS_INDEX2VAL(XMIT_SZ_8BIT),
 		.mid_rid	= 0x2a,
 	},
@@ -256,7 +256,7 @@
 	{
 		.slave_id	= SHDMA_SLAVE_RIIC2_RX,
 		.addr		= 0x1e520013,
-		.chcr		= SM_INC | 0x800 | 0x40000000 |
+		.chcr		= DM_INC | 0x800 | 0x40000000 |
 				  TS_INDEX2VAL(XMIT_SZ_8BIT),
 		.mid_rid	= 0xa2,
 	},
@@ -265,12 +265,12 @@
 		.addr		= 0x1e530012,
 		.chcr		= SM_INC | 0x800 | 0x40000000 |
 				  TS_INDEX2VAL(XMIT_SZ_8BIT),
-		.mid_rid	= 0xab,
+		.mid_rid	= 0xa9,
 	},
 	{
 		.slave_id	= SHDMA_SLAVE_RIIC3_RX,
 		.addr		= 0x1e530013,
-		.chcr		= SM_INC | 0x800 | 0x40000000 |
+		.chcr		= DM_INC | 0x800 | 0x40000000 |
 				  TS_INDEX2VAL(XMIT_SZ_8BIT),
 		.mid_rid	= 0xaf,
 	},
@@ -279,14 +279,14 @@
 		.addr		= 0x1e540012,
 		.chcr		= SM_INC | 0x800 | 0x40000000 |
 				  TS_INDEX2VAL(XMIT_SZ_8BIT),
-		.mid_rid	= 0xc1,
+		.mid_rid	= 0xc5,
 	},
 	{
 		.slave_id	= SHDMA_SLAVE_RIIC4_RX,
 		.addr		= 0x1e540013,
-		.chcr		= SM_INC | 0x800 | 0x40000000 |
+		.chcr		= DM_INC | 0x800 | 0x40000000 |
 				  TS_INDEX2VAL(XMIT_SZ_8BIT),
-		.mid_rid	= 0xc2,
+		.mid_rid	= 0xc6,
 	},
 };
 
@@ -301,7 +301,7 @@
 	{
 		.slave_id	= SHDMA_SLAVE_RIIC5_RX,
 		.addr		= 0x1e550013,
-		.chcr		= SM_INC | 0x800 | 0x40000000 |
+		.chcr		= DM_INC | 0x800 | 0x40000000 |
 				  TS_INDEX2VAL(XMIT_SZ_8BIT),
 		.mid_rid	= 0x22,
 	},
@@ -315,7 +315,7 @@
 	{
 		.slave_id	= SHDMA_SLAVE_RIIC6_RX,
 		.addr		= 0x1e560013,
-		.chcr		= SM_INC | 0x800 | 0x40000000 |
+		.chcr		= DM_INC | 0x800 | 0x40000000 |
 				  TS_INDEX2VAL(XMIT_SZ_8BIT),
 		.mid_rid	= 0x2a,
 	},
@@ -329,7 +329,7 @@
 	{
 		.slave_id	= SHDMA_SLAVE_RIIC7_RX,
 		.addr		= 0x1e570013,
-		.chcr		= SM_INC | 0x800 | 0x40000000 |
+		.chcr		= DM_INC | 0x800 | 0x40000000 |
 				  TS_INDEX2VAL(XMIT_SZ_8BIT),
 		.mid_rid	= 0x42,
 	},
@@ -343,7 +343,7 @@
 	{
 		.slave_id	= SHDMA_SLAVE_RIIC8_RX,
 		.addr		= 0x1e580013,
-		.chcr		= SM_INC | 0x800 | 0x40000000 |
+		.chcr		= DM_INC | 0x800 | 0x40000000 |
 				  TS_INDEX2VAL(XMIT_SZ_8BIT),
 		.mid_rid	= 0x46,
 	},
@@ -357,7 +357,7 @@
 	{
 		.slave_id	= SHDMA_SLAVE_RIIC9_RX,
 		.addr		= 0x1e590013,
-		.chcr		= SM_INC | 0x800 | 0x40000000 |
+		.chcr		= DM_INC | 0x800 | 0x40000000 |
 				  TS_INDEX2VAL(XMIT_SZ_8BIT),
 		.mid_rid	= 0x52,
 	},
@@ -659,6 +659,54 @@
 	.resource	= spi0_resources,
 };
 
+static struct resource usb_ehci_resources[] = {
+	[0] = {
+		.start	= 0xfe4f1000,
+		.end	= 0xfe4f10ff,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= 57,
+		.end	= 57,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device usb_ehci_device = {
+	.name		= "sh_ehci",
+	.id		= -1,
+	.dev = {
+		.dma_mask = &usb_ehci_device.dev.coherent_dma_mask,
+		.coherent_dma_mask = DMA_BIT_MASK(32),
+	},
+	.num_resources	= ARRAY_SIZE(usb_ehci_resources),
+	.resource	= usb_ehci_resources,
+};
+
+static struct resource usb_ohci_resources[] = {
+	[0] = {
+		.start	= 0xfe4f1800,
+		.end	= 0xfe4f18ff,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= 57,
+		.end	= 57,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device usb_ohci_device = {
+	.name		= "sh_ohci",
+	.id		= -1,
+	.dev = {
+		.dma_mask = &usb_ohci_device.dev.coherent_dma_mask,
+		.coherent_dma_mask = DMA_BIT_MASK(32),
+	},
+	.num_resources	= ARRAY_SIZE(usb_ohci_resources),
+	.resource	= usb_ohci_resources,
+};
+
 static struct platform_device *sh7757_devices[] __initdata = {
 	&scif2_device,
 	&scif3_device,
@@ -670,6 +718,8 @@
 	&dma2_device,
 	&dma3_device,
 	&spi0_device,
+	&usb_ehci_device,
+	&usb_ohci_device,
 };
 
 static int __init sh7757_devices_setup(void)
@@ -1039,13 +1089,13 @@
 
 /* Support for external interrupt pins in IRQ mode */
 static struct intc_vect vectors_irq0123[] __initdata = {
-	INTC_VECT(IRQ0, 0x240), INTC_VECT(IRQ1, 0x280),
-	INTC_VECT(IRQ2, 0x2c0), INTC_VECT(IRQ3, 0x300),
+	INTC_VECT(IRQ0, 0x200), INTC_VECT(IRQ1, 0x240),
+	INTC_VECT(IRQ2, 0x280), INTC_VECT(IRQ3, 0x2c0),
 };
 
 static struct intc_vect vectors_irq4567[] __initdata = {
-	INTC_VECT(IRQ4, 0x340), INTC_VECT(IRQ5, 0x380),
-	INTC_VECT(IRQ6, 0x3c0), INTC_VECT(IRQ7, 0x200),
+	INTC_VECT(IRQ4, 0x300), INTC_VECT(IRQ5, 0x340),
+	INTC_VECT(IRQ6, 0x380), INTC_VECT(IRQ7, 0x3c0),
 };
 
 static struct intc_sense_reg sense_registers[] __initdata = {
@@ -1079,14 +1129,14 @@
 };
 
 static struct intc_vect vectors_irl4567[] __initdata = {
-	INTC_VECT(IRL4_LLLL, 0xb00), INTC_VECT(IRL4_LLLH, 0xb20),
-	INTC_VECT(IRL4_LLHL, 0xb40), INTC_VECT(IRL4_LLHH, 0xb60),
-	INTC_VECT(IRL4_LHLL, 0xb80), INTC_VECT(IRL4_LHLH, 0xba0),
-	INTC_VECT(IRL4_LHHL, 0xbc0), INTC_VECT(IRL4_LHHH, 0xbe0),
-	INTC_VECT(IRL4_HLLL, 0xc00), INTC_VECT(IRL4_HLLH, 0xc20),
-	INTC_VECT(IRL4_HLHL, 0xc40), INTC_VECT(IRL4_HLHH, 0xc60),
-	INTC_VECT(IRL4_HHLL, 0xc80), INTC_VECT(IRL4_HHLH, 0xca0),
-	INTC_VECT(IRL4_HHHL, 0xcc0),
+	INTC_VECT(IRL4_LLLL, 0x200), INTC_VECT(IRL4_LLLH, 0x220),
+	INTC_VECT(IRL4_LLHL, 0x240), INTC_VECT(IRL4_LLHH, 0x260),
+	INTC_VECT(IRL4_LHLL, 0x280), INTC_VECT(IRL4_LHLH, 0x2a0),
+	INTC_VECT(IRL4_LHHL, 0x2c0), INTC_VECT(IRL4_LHHH, 0x2e0),
+	INTC_VECT(IRL4_HLLL, 0x300), INTC_VECT(IRL4_HLLH, 0x320),
+	INTC_VECT(IRL4_HLHL, 0x340), INTC_VECT(IRL4_HLHH, 0x360),
+	INTC_VECT(IRL4_HHLL, 0x380), INTC_VECT(IRL4_HHLH, 0x3a0),
+	INTC_VECT(IRL4_HHHL, 0x3c0),
 };
 
 static DECLARE_INTC_DESC(intc_desc_irl0123, "sh7757-irl0123", vectors_irl0123,
diff -druN linux-2.6.39-libre/arch/sh/kernel/cpu/shmobile/pm_runtime.c linux-3.0-rc7-libre/arch/sh/kernel/cpu/shmobile/pm_runtime.c
--- linux-2.6.39-libre/arch/sh/kernel/cpu/shmobile/pm_runtime.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/sh/kernel/cpu/shmobile/pm_runtime.c	2011-07-11 19:51:52.000000000 -0400
@@ -139,7 +139,7 @@
 	queue_work(pm_wq, &hwblk_work);
 }
 
-int platform_pm_runtime_suspend(struct device *dev)
+static int default_platform_runtime_suspend(struct device *dev)
 {
 	struct platform_device *pdev = to_platform_device(dev);
 	struct pdev_archdata *ad = &pdev->archdata;
@@ -147,7 +147,7 @@
 	int hwblk = ad->hwblk_id;
 	int ret = 0;
 
-	dev_dbg(dev, "platform_pm_runtime_suspend() [%d]\n", hwblk);
+	dev_dbg(dev, "%s() [%d]\n", __func__, hwblk);
 
 	/* ignore off-chip platform devices */
 	if (!hwblk)
@@ -157,7 +157,7 @@
 	might_sleep();
 
 	/* catch misconfigured drivers not starting with resume */
-	if (test_bit(PDEV_ARCHDATA_FLAG_INIT, &pdev->archdata.flags)) {
+	if (test_bit(PDEV_ARCHDATA_FLAG_INIT, &ad->flags)) {
 		ret = -EINVAL;
 		goto out;
 	}
@@ -170,8 +170,8 @@
 
 	/* put device on idle list */
 	spin_lock_irqsave(&hwblk_lock, flags);
-	list_add_tail(&pdev->archdata.entry, &hwblk_idle_list);
-	__set_bit(PDEV_ARCHDATA_FLAG_IDLE, &pdev->archdata.flags);
+	list_add_tail(&ad->entry, &hwblk_idle_list);
+	__set_bit(PDEV_ARCHDATA_FLAG_IDLE, &ad->flags);
 	spin_unlock_irqrestore(&hwblk_lock, flags);
 
 	/* increase idle count */
@@ -183,20 +183,20 @@
 	mutex_unlock(&ad->mutex);
 
 out:
-	dev_dbg(dev, "platform_pm_runtime_suspend() [%d] returns %d\n",
-		hwblk, ret);
+	dev_dbg(dev, "%s() [%d] returns %d\n",
+		 __func__, hwblk, ret);
 
 	return ret;
 }
 
-int platform_pm_runtime_resume(struct device *dev)
+static int default_platform_runtime_resume(struct device *dev)
 {
 	struct platform_device *pdev = to_platform_device(dev);
 	struct pdev_archdata *ad = &pdev->archdata;
 	int hwblk = ad->hwblk_id;
 	int ret = 0;
 
-	dev_dbg(dev, "platform_pm_runtime_resume() [%d]\n", hwblk);
+	dev_dbg(dev, "%s() [%d]\n", __func__, hwblk);
 
 	/* ignore off-chip platform devices */
 	if (!hwblk)
@@ -228,19 +228,19 @@
 	 */
 	mutex_unlock(&ad->mutex);
 out:
-	dev_dbg(dev, "platform_pm_runtime_resume() [%d] returns %d\n",
-		hwblk, ret);
+	dev_dbg(dev, "%s() [%d] returns %d\n",
+		__func__, hwblk, ret);
 
 	return ret;
 }
 
-int platform_pm_runtime_idle(struct device *dev)
+static int default_platform_runtime_idle(struct device *dev)
 {
 	struct platform_device *pdev = to_platform_device(dev);
 	int hwblk = pdev->archdata.hwblk_id;
 	int ret = 0;
 
-	dev_dbg(dev, "platform_pm_runtime_idle() [%d]\n", hwblk);
+	dev_dbg(dev, "%s() [%d]\n", __func__, hwblk);
 
 	/* ignore off-chip platform devices */
 	if (!hwblk)
@@ -252,10 +252,19 @@
 	/* suspend synchronously to disable clocks immediately */
 	ret = pm_runtime_suspend(dev);
 out:
-	dev_dbg(dev, "platform_pm_runtime_idle() [%d] done!\n", hwblk);
+	dev_dbg(dev, "%s() [%d] done!\n", __func__, hwblk);
 	return ret;
 }
 
+static struct dev_power_domain default_power_domain = {
+	.ops = {
+		.runtime_suspend = default_platform_runtime_suspend,
+		.runtime_resume = default_platform_runtime_resume,
+		.runtime_idle = default_platform_runtime_idle,
+		USE_PLATFORM_PM_SLEEP_OPS
+	},
+};
+
 static int platform_bus_notify(struct notifier_block *nb,
 			       unsigned long action, void *data)
 {
@@ -276,6 +285,7 @@
 		hwblk_disable(hwblk_info, hwblk);
 		/* make sure driver re-inits itself once */
 		__set_bit(PDEV_ARCHDATA_FLAG_INIT, &pdev->archdata.flags);
+		dev->pwr_domain = &default_power_domain;
 		break;
 	/* TODO: add BUS_NOTIFY_BIND_DRIVER and increase idle count */
 	case BUS_NOTIFY_BOUND_DRIVER:
@@ -289,6 +299,7 @@
 		__set_bit(PDEV_ARCHDATA_FLAG_INIT, &pdev->archdata.flags);
 		break;
 	case BUS_NOTIFY_DEL_DEVICE:
+		dev->pwr_domain = NULL;
 		break;
 	}
 	return 0;
diff -druN linux-2.6.39-libre/arch/sh/kernel/dumpstack.c linux-3.0-rc7-libre/arch/sh/kernel/dumpstack.c
--- linux-2.6.39-libre/arch/sh/kernel/dumpstack.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/sh/kernel/dumpstack.c	2011-07-11 19:51:52.000000000 -0400
@@ -69,19 +69,6 @@
 	}
 }
 
-static void
-print_trace_warning_symbol(void *data, char *msg, unsigned long symbol)
-{
-	printk(data);
-	print_symbol(msg, symbol);
-	printk("\n");
-}
-
-static void print_trace_warning(void *data, char *msg)
-{
-	printk("%s%s\n", (char *)data, msg);
-}
-
 static int print_trace_stack(void *data, char *name)
 {
 	printk("%s <%s> ", (char *)data, name);
@@ -98,8 +85,6 @@
 }
 
 static const struct stacktrace_ops print_trace_ops = {
-	.warning = print_trace_warning,
-	.warning_symbol = print_trace_warning_symbol,
 	.stack = print_trace_stack,
 	.address = print_trace_address,
 };
diff -druN linux-2.6.39-libre/arch/sh/kernel/irq.c linux-3.0-rc7-libre/arch/sh/kernel/irq.c
--- linux-2.6.39-libre/arch/sh/kernel/irq.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/sh/kernel/irq.c	2011-07-11 19:51:52.000000000 -0400
@@ -13,6 +13,7 @@
 #include <linux/seq_file.h>
 #include <linux/ftrace.h>
 #include <linux/delay.h>
+#include <linux/ratelimit.h>
 #include <asm/processor.h>
 #include <asm/machvec.h>
 #include <asm/uaccess.h>
@@ -268,9 +269,8 @@
 			unsigned int newcpu = cpumask_any_and(data->affinity,
 							      cpu_online_mask);
 			if (newcpu >= nr_cpu_ids) {
-				if (printk_ratelimit())
-					printk(KERN_INFO "IRQ%u no longer affine to CPU%u\n",
-					       irq, cpu);
+				pr_info_ratelimited("IRQ%u no longer affine to CPU%u\n",
+						    irq, cpu);
 
 				cpumask_setall(data->affinity);
 				newcpu = cpumask_any_and(data->affinity,
diff -druN linux-2.6.39-libre/arch/sh/kernel/module.c linux-3.0-rc7-libre/arch/sh/kernel/module.c
--- linux-2.6.39-libre/arch/sh/kernel/module.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/sh/kernel/module.c	2011-07-11 19:51:52.000000000 -0400
@@ -93,6 +93,8 @@
 #endif
 
 		switch (ELF32_R_TYPE(rel[i].r_info)) {
+		case R_SH_NONE:
+			break;
 		case R_SH_DIR32:
 			value = get_unaligned(location);
 			value += relocation;
diff -druN linux-2.6.39-libre/arch/sh/kernel/perf_callchain.c linux-3.0-rc7-libre/arch/sh/kernel/perf_callchain.c
--- linux-2.6.39-libre/arch/sh/kernel/perf_callchain.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/sh/kernel/perf_callchain.c	2011-07-11 19:51:52.000000000 -0400
@@ -14,16 +14,6 @@
 #include <asm/unwinder.h>
 #include <asm/ptrace.h>
 
-
-static void callchain_warning(void *data, char *msg)
-{
-}
-
-static void
-callchain_warning_symbol(void *data, char *msg, unsigned long symbol)
-{
-}
-
 static int callchain_stack(void *data, char *name)
 {
 	return 0;
@@ -38,8 +28,6 @@
 }
 
 static const struct stacktrace_ops callchain_ops = {
-	.warning	= callchain_warning,
-	.warning_symbol	= callchain_warning_symbol,
 	.stack		= callchain_stack,
 	.address	= callchain_address,
 };
diff -druN linux-2.6.39-libre/arch/sh/kernel/process_32.c linux-3.0-rc7-libre/arch/sh/kernel/process_32.c
--- linux-2.6.39-libre/arch/sh/kernel/process_32.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/sh/kernel/process_32.c	2011-07-11 19:51:52.000000000 -0400
@@ -21,6 +21,7 @@
 #include <linux/fs.h>
 #include <linux/ftrace.h>
 #include <linux/hw_breakpoint.h>
+#include <linux/prefetch.h>
 #include <asm/uaccess.h>
 #include <asm/mmu_context.h>
 #include <asm/system.h>
@@ -101,8 +102,6 @@
 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;
diff -druN linux-2.6.39-libre/arch/sh/kernel/smp.c linux-3.0-rc7-libre/arch/sh/kernel/smp.c
--- linux-2.6.39-libre/arch/sh/kernel/smp.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/sh/kernel/smp.c	2011-07-11 19:51:52.000000000 -0400
@@ -20,6 +20,7 @@
 #include <linux/module.h>
 #include <linux/cpu.h>
 #include <linux/interrupt.h>
+#include <linux/sched.h>
 #include <asm/atomic.h>
 #include <asm/processor.h>
 #include <asm/system.h>
@@ -323,6 +324,7 @@
 		generic_smp_call_function_interrupt();
 		break;
 	case SMP_MSG_RESCHEDULE:
+		scheduler_ipi();
 		break;
 	case SMP_MSG_FUNCTION_SINGLE:
 		generic_smp_call_function_single_interrupt();
diff -druN linux-2.6.39-libre/arch/sh/kernel/stacktrace.c linux-3.0-rc7-libre/arch/sh/kernel/stacktrace.c
--- linux-2.6.39-libre/arch/sh/kernel/stacktrace.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/sh/kernel/stacktrace.c	2011-07-11 19:51:52.000000000 -0400
@@ -17,15 +17,6 @@
 #include <asm/ptrace.h>
 #include <asm/stacktrace.h>
 
-static void save_stack_warning(void *data, char *msg)
-{
-}
-
-static void
-save_stack_warning_symbol(void *data, char *msg, unsigned long symbol)
-{
-}
-
 static int save_stack_stack(void *data, char *name)
 {
 	return 0;
@@ -51,8 +42,6 @@
 }
 
 static const struct stacktrace_ops save_stack_ops = {
-	.warning = save_stack_warning,
-	.warning_symbol = save_stack_warning_symbol,
 	.stack = save_stack_stack,
 	.address = save_stack_address,
 };
@@ -88,8 +77,6 @@
 }
 
 static const struct stacktrace_ops save_stack_ops_nosched = {
-	.warning = save_stack_warning,
-	.warning_symbol = save_stack_warning_symbol,
 	.stack = save_stack_stack,
 	.address = save_stack_address_nosched,
 };
diff -druN linux-2.6.39-libre/arch/sh/kernel/syscalls_32.S linux-3.0-rc7-libre/arch/sh/kernel/syscalls_32.S
--- linux-2.6.39-libre/arch/sh/kernel/syscalls_32.S	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/sh/kernel/syscalls_32.S	2011-07-11 19:51:52.000000000 -0400
@@ -380,3 +380,5 @@
 	.long sys_open_by_handle_at	/* 360 */
 	.long sys_clock_adjtime
 	.long sys_syncfs
+	.long sys_sendmmsg
+	.long sys_setns
diff -druN linux-2.6.39-libre/arch/sh/kernel/syscalls_64.S linux-3.0-rc7-libre/arch/sh/kernel/syscalls_64.S
--- linux-2.6.39-libre/arch/sh/kernel/syscalls_64.S	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/sh/kernel/syscalls_64.S	2011-07-11 19:51:52.000000000 -0400
@@ -400,3 +400,5 @@
 	.long sys_open_by_handle_at
 	.long sys_clock_adjtime
 	.long sys_syncfs
+	.long sys_sendmmsg
+	.long sys_setns			/* 375 */
diff -druN linux-2.6.39-libre/arch/sh/kernel/traps_32.c linux-3.0-rc7-libre/arch/sh/kernel/traps_32.c
--- linux-2.6.39-libre/arch/sh/kernel/traps_32.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/sh/kernel/traps_32.c	2011-07-11 19:51:52.000000000 -0400
@@ -87,7 +87,6 @@
 	bust_spinlocks(1);
 
 	printk("%s: %04lx [#%d]\n", str, err & 0xffff, ++die_counter);
-	sysfs_printk_last_file();
 	print_modules();
 	show_regs(regs);
 
diff -druN linux-2.6.39-libre/arch/sh/kernel/vmlinux.lds.S linux-3.0-rc7-libre/arch/sh/kernel/vmlinux.lds.S
--- linux-2.6.39-libre/arch/sh/kernel/vmlinux.lds.S	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/sh/kernel/vmlinux.lds.S	2011-07-11 19:51:52.000000000 -0400
@@ -66,7 +66,7 @@
 		__machvec_end = .;
 	}
 
-	PERCPU(L1_CACHE_BYTES, PAGE_SIZE)
+	PERCPU_SECTION(L1_CACHE_BYTES)
 
 	/*
 	 * .exit.text is discarded at runtime, not link time, to deal with
diff -druN linux-2.6.39-libre/arch/sh/mm/alignment.c linux-3.0-rc7-libre/arch/sh/mm/alignment.c
--- linux-2.6.39-libre/arch/sh/mm/alignment.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/sh/mm/alignment.c	2011-07-11 19:51:52.000000000 -0400
@@ -13,6 +13,7 @@
 #include <linux/seq_file.h>
 #include <linux/proc_fs.h>
 #include <linux/uaccess.h>
+#include <linux/ratelimit.h>
 #include <asm/alignment.h>
 #include <asm/processor.h>
 
@@ -95,13 +96,13 @@
 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 "
+	if (user_mode(regs) && (se_usermode & UM_WARN))
+		pr_notice_ratelimited("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 "
+	else if (se_kernmode_warn)
+		pr_notice_ratelimited("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);
diff -druN linux-2.6.39-libre/arch/sh/mm/cache-debugfs.c linux-3.0-rc7-libre/arch/sh/mm/cache-debugfs.c
--- linux-2.6.39-libre/arch/sh/mm/cache-debugfs.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/sh/mm/cache-debugfs.c	2011-07-11 19:51:52.000000000 -0400
@@ -26,9 +26,9 @@
 {
 	unsigned int cache_type = (unsigned int)file->private;
 	struct cache_info *cache;
-	unsigned int waysize, way, cache_size;
-	unsigned long ccr, base;
-	static unsigned long addrstart = 0;
+	unsigned int waysize, way;
+	unsigned long ccr;
+	unsigned long addrstart = 0;
 
 	/*
 	 * Go uncached immediately so we don't skew the results any
@@ -45,28 +45,13 @@
 	}
 
 	if (cache_type == CACHE_TYPE_DCACHE) {
-		base = CACHE_OC_ADDRESS_ARRAY;
+		addrstart = CACHE_OC_ADDRESS_ARRAY;
 		cache = &current_cpu_data.dcache;
 	} else {
-		base = CACHE_IC_ADDRESS_ARRAY;
+		addrstart = CACHE_IC_ADDRESS_ARRAY;
 		cache = &current_cpu_data.icache;
 	}
 
-	/*
-	 * Due to the amount of data written out (depending on the cache size),
-	 * we may be iterated over multiple times. In this case, keep track of
-	 * the entry position in addrstart, and rewind it when we've hit the
-	 * end of the cache.
-	 *
-	 * Likewise, the same code is used for multiple caches, so care must
-	 * be taken for bouncing addrstart back and forth so the appropriate
-	 * cache is hit.
-	 */
-	cache_size = cache->ways * cache->sets * cache->linesz;
-	if (((addrstart & 0xff000000) != base) ||
-	     (addrstart & 0x00ffffff) > cache_size)
-		addrstart = base;
-
 	waysize = cache->sets;
 
 	/*
diff -druN linux-2.6.39-libre/arch/sh/mm/consistent.c linux-3.0-rc7-libre/arch/sh/mm/consistent.c
--- linux-2.6.39-libre/arch/sh/mm/consistent.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/sh/mm/consistent.c	2011-07-11 19:51:52.000000000 -0400
@@ -82,7 +82,7 @@
 	void *addr;
 
 	addr = __in_29bit_mode() ?
-	       (void *)P1SEGADDR((unsigned long)vaddr) : vaddr;
+	       (void *)CAC_ADDR((unsigned long)vaddr) : vaddr;
 
 	switch (direction) {
 	case DMA_FROM_DEVICE:		/* invalidate only */
diff -druN linux-2.6.39-libre/arch/sh/mm/init.c linux-3.0-rc7-libre/arch/sh/mm/init.c
--- linux-2.6.39-libre/arch/sh/mm/init.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/sh/mm/init.c	2011-07-11 19:51:52.000000000 -0400
@@ -28,7 +28,6 @@
 #include <asm/cache.h>
 #include <asm/sizes.h>
 
-DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
 pgd_t swapper_pg_dir[PTRS_PER_PGD];
 
 void __init generic_mem_init(void)
diff -druN linux-2.6.39-libre/arch/sh/oprofile/backtrace.c linux-3.0-rc7-libre/arch/sh/oprofile/backtrace.c
--- linux-2.6.39-libre/arch/sh/oprofile/backtrace.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/sh/oprofile/backtrace.c	2011-07-11 19:51:52.000000000 -0400
@@ -23,17 +23,6 @@
 #include <asm/sections.h>
 #include <asm/stacktrace.h>
 
-static void backtrace_warning_symbol(void *data, char *msg,
-				     unsigned long symbol)
-{
-	/* Ignore warnings */
-}
-
-static void backtrace_warning(void *data, char *msg)
-{
-	/* Ignore warnings */
-}
-
 static int backtrace_stack(void *data, char *name)
 {
 	/* Yes, we want all stacks */
@@ -49,8 +38,6 @@
 }
 
 static struct stacktrace_ops backtrace_ops = {
-	.warning = backtrace_warning,
-	.warning_symbol = backtrace_warning_symbol,
 	.stack = backtrace_stack,
 	.address = backtrace_address,
 };
diff -druN linux-2.6.39-libre/arch/sparc/include/asm/cpudata_32.h linux-3.0-rc7-libre/arch/sparc/include/asm/cpudata_32.h
--- linux-2.6.39-libre/arch/sparc/include/asm/cpudata_32.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/sparc/include/asm/cpudata_32.h	2011-07-11 19:51:52.000000000 -0400
@@ -16,6 +16,10 @@
 	unsigned long clock_tick;
 	unsigned int multiplier;
 	unsigned int counter;
+#ifdef CONFIG_SMP
+	unsigned int irq_resched_count;
+	unsigned int irq_call_count;
+#endif
 	int prom_node;
 	int mid;
 	int next;
@@ -23,5 +27,6 @@
 
 DECLARE_PER_CPU(cpuinfo_sparc, __cpu_data);
 #define cpu_data(__cpu) per_cpu(__cpu_data, (__cpu))
+#define local_cpu_data() __get_cpu_var(__cpu_data)
 
 #endif /* _SPARC_CPUDATA_H */
diff -druN linux-2.6.39-libre/arch/sparc/include/asm/floppy_32.h linux-3.0-rc7-libre/arch/sparc/include/asm/floppy_32.h
--- linux-2.6.39-libre/arch/sparc/include/asm/floppy_32.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/sparc/include/asm/floppy_32.h	2011-07-11 19:51:52.000000000 -0400
@@ -138,7 +138,7 @@
 		return sun_fdc->data_82072;
 	case 7: /* FD_DIR */
 		return sun_read_dir();
-	};
+	}
 	panic("sun_82072_fd_inb: How did I get here?");
 }
 
@@ -161,7 +161,7 @@
 	case 4: /* FD_STATUS */
 		sun_fdc->status_82072 = value;
 		break;
-	};
+	}
 	return;
 }
 
@@ -186,7 +186,7 @@
 		return sun_fdc->data_82077;
 	case 7: /* FD_DIR */
 		return sun_read_dir();
-	};
+	}
 	panic("sun_82077_fd_inb: How did I get here?");
 }
 
@@ -212,7 +212,7 @@
 	case 3: /* FD_TDR */
 		sun_fdc->tapectl_82077 = value;
 		break;
-	};
+	}
 	return;
 }
 
@@ -281,28 +281,27 @@
 	pdma_areasize = pdma_size;
 }
 
-/* Our low-level entry point in arch/sparc/kernel/entry.S */
-extern int sparc_floppy_request_irq(int irq, unsigned long flags,
-				    irq_handler_t irq_handler);
+extern int sparc_floppy_request_irq(unsigned int irq,
+                                    irq_handler_t irq_handler);
 
 static int sun_fd_request_irq(void)
 {
 	static int once = 0;
-	int error;
 
-	if(!once) {
+	if (!once) {
 		once = 1;
-		error = sparc_floppy_request_irq(FLOPPY_IRQ,
-						 IRQF_DISABLED,
-						 floppy_interrupt);
-		return ((error == 0) ? 0 : -1);
-	} else return 0;
+		return sparc_floppy_request_irq(FLOPPY_IRQ, floppy_interrupt);
+	} else {
+		return 0;
+	}
 }
 
 static struct linux_prom_registers fd_regs[2];
 
 static int sun_floppy_init(void)
 {
+	struct platform_device *op;
+	struct device_node *dp;
 	char state[128];
 	phandle tnode, fd_node;
 	int num_regs;
@@ -310,7 +309,6 @@
 
 	use_virtual_dma = 1;
 
-	FLOPPY_IRQ = 11;
 	/* Forget it if we aren't on a machine that could possibly
 	 * ever have a floppy drive.
 	 */
@@ -349,6 +347,26 @@
 	sun_fdc = (struct sun_flpy_controller *)
 	    of_ioremap(&r, 0, fd_regs[0].reg_size, "floppy");
 
+	/* Look up irq in platform_device.
+	 * We try "SUNW,fdtwo" and "fd"
+	 */
+	for_each_node_by_name(dp, "SUNW,fdtwo") {
+		op = of_find_device_by_node(dp);
+		if (op)
+			break;
+	}
+	if (!op) {
+		for_each_node_by_name(dp, "fd") {
+			op = of_find_device_by_node(dp);
+			if (op)
+				break;
+		}
+	}
+	if (!op)
+		goto no_sun_fdc;
+
+	FLOPPY_IRQ = op->archdata.irqs[0];
+
 	/* Last minute sanity check... */
 	if(sun_fdc->status_82072 == 0xff) {
 		sun_fdc = NULL;
diff -druN linux-2.6.39-libre/arch/sparc/include/asm/floppy_64.h linux-3.0-rc7-libre/arch/sparc/include/asm/floppy_64.h
--- linux-2.6.39-libre/arch/sparc/include/asm/floppy_64.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/sparc/include/asm/floppy_64.h	2011-07-11 19:51:52.000000000 -0400
@@ -111,7 +111,7 @@
 	case 7: /* FD_DIR */
 		/* XXX: Is DCL on 0x80 in sun4m? */
 		return sbus_readb(&sun_fdc->dir_82077);
-	};
+	}
 	panic("sun_82072_fd_inb: How did I get here?");
 }
 
@@ -135,7 +135,7 @@
 	case 4: /* FD_STATUS */
 		sbus_writeb(value, &sun_fdc->status_82077);
 		break;
-	};
+	}
 	return;
 }
 
diff -druN linux-2.6.39-libre/arch/sparc/include/asm/io.h linux-3.0-rc7-libre/arch/sparc/include/asm/io.h
--- linux-2.6.39-libre/arch/sparc/include/asm/io.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/sparc/include/asm/io.h	2011-07-11 19:51:52.000000000 -0400
@@ -5,4 +5,17 @@
 #else
 #include <asm/io_32.h>
 #endif
+
+/*
+ * Defines used for both SPARC32 and SPARC64
+ */
+
+/* Big endian versions of memory read/write routines */
+#define readb_be(__addr)	__raw_readb(__addr)
+#define readw_be(__addr)	__raw_readw(__addr)
+#define readl_be(__addr)	__raw_readl(__addr)
+#define writeb_be(__b, __addr)	__raw_writeb(__b, __addr)
+#define writel_be(__w, __addr)	__raw_writel(__w, __addr)
+#define writew_be(__l, __addr)	__raw_writew(__l, __addr)
+
 #endif
diff -druN linux-2.6.39-libre/arch/sparc/include/asm/irq_32.h linux-3.0-rc7-libre/arch/sparc/include/asm/irq_32.h
--- linux-2.6.39-libre/arch/sparc/include/asm/irq_32.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/sparc/include/asm/irq_32.h	2011-07-11 19:51:52.000000000 -0400
@@ -6,7 +6,11 @@
 #ifndef _SPARC_IRQ_H
 #define _SPARC_IRQ_H
 
-#define NR_IRQS    16
+/* Allocated number of logical irq numbers.
+ * sun4d boxes (ss2000e) should be OK with ~32.
+ * Be on the safe side and make room for 64
+ */
+#define NR_IRQS    64
 
 #include <linux/interrupt.h>
 
diff -druN linux-2.6.39-libre/arch/sparc/include/asm/jump_label.h linux-3.0-rc7-libre/arch/sparc/include/asm/jump_label.h
--- linux-2.6.39-libre/arch/sparc/include/asm/jump_label.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/sparc/include/asm/jump_label.h	2011-07-11 19:51:52.000000000 -0400
@@ -7,17 +7,20 @@
 
 #define JUMP_LABEL_NOP_SIZE 4
 
-#define JUMP_LABEL(key, label)					\
-	do {							\
-		asm goto("1:\n\t"				\
-			 "nop\n\t"				\
-			 "nop\n\t"				\
-			 ".pushsection __jump_table,  \"a\"\n\t"\
-			 ".align 4\n\t"				\
-			 ".word 1b, %l[" #label "], %c0\n\t"	\
-			 ".popsection \n\t"			\
-			 : :  "i" (key) :  : label);\
-	} while (0)
+static __always_inline bool arch_static_branch(struct jump_label_key *key)
+{
+		asm goto("1:\n\t"
+			 "nop\n\t"
+			 "nop\n\t"
+			 ".pushsection __jump_table,  \"aw\"\n\t"
+			 ".align 4\n\t"
+			 ".word 1b, %l[l_yes], %c0\n\t"
+			 ".popsection \n\t"
+			 : :  "i" (key) : : l_yes);
+	return false;
+l_yes:
+	return true;
+}
 
 #endif /* __KERNEL__ */
 
diff -druN linux-2.6.39-libre/arch/sparc/include/asm/leon.h linux-3.0-rc7-libre/arch/sparc/include/asm/leon.h
--- linux-2.6.39-libre/arch/sparc/include/asm/leon.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/sparc/include/asm/leon.h	2011-07-11 19:51:52.000000000 -0400
@@ -52,29 +52,6 @@
 #define LEON_DIAGF_VALID	0x2000
 #define LEON_DIAGF_VALID_SHIFT	13
 
-/*
- *  Interrupt Sources
- *
- *  The interrupt source numbers directly map to the trap type and to
- *  the bits used in the Interrupt Clear, Interrupt Force, Interrupt Mask,
- *  and the Interrupt Pending Registers.
- */
-#define LEON_INTERRUPT_CORRECTABLE_MEMORY_ERROR	1
-#define LEON_INTERRUPT_UART_1_RX_TX		2
-#define LEON_INTERRUPT_UART_0_RX_TX		3
-#define LEON_INTERRUPT_EXTERNAL_0		4
-#define LEON_INTERRUPT_EXTERNAL_1		5
-#define LEON_INTERRUPT_EXTERNAL_2		6
-#define LEON_INTERRUPT_EXTERNAL_3		7
-#define LEON_INTERRUPT_TIMER1			8
-#define LEON_INTERRUPT_TIMER2			9
-#define LEON_INTERRUPT_EMPTY1			10
-#define LEON_INTERRUPT_EMPTY2			11
-#define LEON_INTERRUPT_OPEN_ETH			12
-#define LEON_INTERRUPT_EMPTY4			13
-#define LEON_INTERRUPT_EMPTY5			14
-#define LEON_INTERRUPT_EMPTY6			15
-
 /* irq masks */
 #define LEON_HARD_INT(x)	(1 << (x))	/* irq 0-15 */
 #define LEON_IRQMASK_R		0x0000fffe	/* bit 15- 1 of lregs.irqmask */
@@ -183,7 +160,6 @@
 /* macro access for leon_readnobuffer_reg() */
 #define LEON_BYPASSCACHE_LOAD_VA(x) leon_readnobuffer_reg((unsigned long)(x))
 
-extern void sparc_leon_eirq_register(int eirq);
 extern void leon_init(void);
 extern void leon_switch_mm(void);
 extern void leon_init_IRQ(void);
@@ -239,8 +215,8 @@
 #endif /*!__ASSEMBLY__*/
 
 #ifdef CONFIG_SMP
-# define LEON3_IRQ_RESCHEDULE		13
-# define LEON3_IRQ_TICKER		(leon_percpu_timer_dev[0].irq)
+# define LEON3_IRQ_IPI_DEFAULT		13
+# define LEON3_IRQ_TICKER		(leon3_ticker_irq)
 # define LEON3_IRQ_CROSS_CALL		15
 #endif
 
@@ -339,9 +315,12 @@
 #include <linux/interrupt.h>
 
 struct device_node;
-extern int sparc_leon_eirq_get(int eirq, int cpu);
-extern irqreturn_t sparc_leon_eirq_isr(int dummy, void *dev_id);
-extern void sparc_leon_eirq_register(int eirq);
+extern unsigned int leon_build_device_irq(unsigned int real_irq,
+					   irq_flow_handler_t flow_handler,
+					   const char *name, int do_ack);
+extern void leon_update_virq_handling(unsigned int virq,
+			      irq_flow_handler_t flow_handler,
+			      const char *name, int do_ack);
 extern void leon_clear_clock_irq(void);
 extern void leon_load_profile_irq(int cpu, unsigned int limit);
 extern void leon_init_timers(irq_handler_t counter_fn);
@@ -358,6 +337,7 @@
 extern int leon_flush_needed(void);
 extern void leon_switch_mm(void);
 extern int srmmu_swprobe_trace;
+extern int leon3_ticker_irq;
 
 #ifdef CONFIG_SMP
 extern int leon_smp_nrcpus(void);
@@ -366,17 +346,19 @@
 extern void leon_boot_cpus(void);
 extern int leon_boot_one_cpu(int i);
 void leon_init_smp(void);
-extern void cpu_probe(void);
 extern void cpu_idle(void);
 extern void init_IRQ(void);
 extern void cpu_panic(void);
 extern int __leon_processor_id(void);
 void leon_enable_irq_cpu(unsigned int irq_nr, unsigned int cpu);
+extern irqreturn_t leon_percpu_timer_interrupt(int irq, void *unused);
 
-extern unsigned int real_irq_entry[], smpleon_ticker[];
+extern unsigned int real_irq_entry[];
+extern unsigned int smpleon_ipi[];
 extern unsigned int patchme_maybe_smp_msg[];
 extern unsigned int t_nmi[], linux_trap_ipi15_leon[];
 extern unsigned int linux_trap_ipi15_sun4m[];
+extern int leon_ipi_irq;
 
 #endif /* CONFIG_SMP */
 
diff -druN linux-2.6.39-libre/arch/sparc/include/asm/leon_pci.h linux-3.0-rc7-libre/arch/sparc/include/asm/leon_pci.h
--- linux-2.6.39-libre/arch/sparc/include/asm/leon_pci.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/sparc/include/asm/leon_pci.h	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,21 @@
+/*
+ * asm/leon_pci.h
+ *
+ * Copyright (C) 2011 Aeroflex Gaisler AB, Daniel Hellstrom
+ */
+
+#ifndef _ASM_LEON_PCI_H_
+#define _ASM_LEON_PCI_H_
+
+/* PCI related definitions */
+struct leon_pci_info {
+	struct pci_ops *ops;
+	struct resource	io_space;
+	struct resource	mem_space;
+	int (*map_irq)(struct pci_dev *dev, u8 slot, u8 pin);
+};
+
+extern void leon_pci_init(struct platform_device *ofdev,
+				struct leon_pci_info *info);
+
+#endif /* _ASM_LEON_PCI_H_ */
diff -druN linux-2.6.39-libre/arch/sparc/include/asm/mmzone.h linux-3.0-rc7-libre/arch/sparc/include/asm/mmzone.h
--- linux-2.6.39-libre/arch/sparc/include/asm/mmzone.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/sparc/include/asm/mmzone.h	2011-07-11 19:51:52.000000000 -0400
@@ -8,8 +8,6 @@
 extern struct pglist_data *node_data[];
 
 #define NODE_DATA(nid)		(node_data[nid])
-#define node_start_pfn(nid)	(NODE_DATA(nid)->node_start_pfn)
-#define node_end_pfn(nid)	(NODE_DATA(nid)->node_end_pfn)
 
 extern int numa_cpu_lookup_table[];
 extern cpumask_t numa_cpumask_lookup_table[];
diff -druN linux-2.6.39-libre/arch/sparc/include/asm/pci_32.h linux-3.0-rc7-libre/arch/sparc/include/asm/pci_32.h
--- linux-2.6.39-libre/arch/sparc/include/asm/pci_32.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/sparc/include/asm/pci_32.h	2011-07-11 19:51:52.000000000 -0400
@@ -47,7 +47,31 @@
 
 #endif /* __KERNEL__ */
 
+#ifndef CONFIG_LEON_PCI
 /* generic pci stuff */
 #include <asm-generic/pci.h>
+#else
+/*
+ * On LEON PCI Memory space is mapped 1:1 with physical address space.
+ *
+ * I/O space is located at low 64Kbytes in PCI I/O space. The I/O addresses
+ * are converted into CPU addresses to virtual addresses that are mapped with
+ * MMU to the PCI Host PCI I/O space window which are translated to the low
+ * 64Kbytes by the Host controller.
+ */
+
+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 int pci_get_legacy_ide_irq(struct pci_dev *dev, int channel)
+{
+	return PCI_IRQ_NONE;
+}
+#endif
 
 #endif /* __SPARC_PCI_H */
diff -druN linux-2.6.39-libre/arch/sparc/include/asm/pcic.h linux-3.0-rc7-libre/arch/sparc/include/asm/pcic.h
--- linux-2.6.39-libre/arch/sparc/include/asm/pcic.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/sparc/include/asm/pcic.h	2011-07-11 19:51:52.000000000 -0400
@@ -29,11 +29,17 @@
 	int			pcic_imdim;
 };
 
-extern int pcic_probe(void);
-/* Erm... MJ redefined pcibios_present() so that it does not work early. */
+#ifdef CONFIG_PCIC_PCI
 extern int pcic_present(void);
+extern int pcic_probe(void);
+extern void pci_time_init(void);
 extern void sun4m_pci_init_IRQ(void);
-
+#else
+static inline int pcic_present(void) { return 0; }
+static inline int pcic_probe(void) { return 0; }
+static inline void pci_time_init(void) {}
+static inline void sun4m_pci_init_IRQ(void) {}
+#endif
 #endif
 
 /* Size of PCI I/O space which we relocate. */
diff -druN linux-2.6.39-libre/arch/sparc/include/asm/pgalloc_64.h linux-3.0-rc7-libre/arch/sparc/include/asm/pgalloc_64.h
--- linux-2.6.39-libre/arch/sparc/include/asm/pgalloc_64.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/sparc/include/asm/pgalloc_64.h	2011-07-11 19:51:52.000000000 -0400
@@ -78,4 +78,7 @@
 	quicklist_trim(0, NULL, 25, 16);
 }
 
+#define __pte_free_tlb(tlb, pte, addr)	pte_free((tlb)->mm, pte)
+#define __pmd_free_tlb(tlb, pmd, addr)	pmd_free((tlb)->mm, pmd)
+
 #endif /* _SPARC64_PGALLOC_H */
diff -druN linux-2.6.39-libre/arch/sparc/include/asm/pgtable_32.h linux-3.0-rc7-libre/arch/sparc/include/asm/pgtable_32.h
--- linux-2.6.39-libre/arch/sparc/include/asm/pgtable_32.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/sparc/include/asm/pgtable_32.h	2011-07-11 19:51:52.000000000 -0400
@@ -8,6 +8,8 @@
  *  Copyright (C) 1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
  */
 
+#include <linux/const.h>
+
 #ifndef __ASSEMBLY__
 #include <asm-generic/4level-fixup.h>
 
@@ -456,9 +458,9 @@
 
 #endif /* !(__ASSEMBLY__) */
 
-#define VMALLOC_START           0xfe600000
+#define VMALLOC_START           _AC(0xfe600000,UL)
 /* XXX Alter this when I get around to fixing sun4c - Anton */
-#define VMALLOC_END             0xffc00000
+#define VMALLOC_END             _AC(0xffc00000,UL)
 
 
 /* We provide our own get_unmapped_area to cope with VA holes for userland */
diff -druN linux-2.6.39-libre/arch/sparc/include/asm/pgtable_64.h linux-3.0-rc7-libre/arch/sparc/include/asm/pgtable_64.h
--- linux-2.6.39-libre/arch/sparc/include/asm/pgtable_64.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/sparc/include/asm/pgtable_64.h	2011-07-11 19:51:52.000000000 -0400
@@ -655,9 +655,11 @@
 #define pte_unmap(pte)			do { } while (0)
 
 /* Actual page table PTE updates.  */
-extern void tlb_batch_add(struct mm_struct *mm, unsigned long vaddr, pte_t *ptep, pte_t orig);
+extern void tlb_batch_add(struct mm_struct *mm, unsigned long vaddr,
+			  pte_t *ptep, pte_t orig, int fullmm);
 
-static inline void set_pte_at(struct mm_struct *mm, unsigned long addr, pte_t *ptep, pte_t pte)
+static inline void __set_pte_at(struct mm_struct *mm, unsigned long addr,
+			     pte_t *ptep, pte_t pte, int fullmm)
 {
 	pte_t orig = *ptep;
 
@@ -670,12 +672,19 @@
 	 *             and SUN4V pte layout, so this inline test is fine.
 	 */
 	if (likely(mm != &init_mm) && (pte_val(orig) & _PAGE_VALID))
-		tlb_batch_add(mm, addr, ptep, orig);
+		tlb_batch_add(mm, addr, ptep, orig, fullmm);
 }
 
+#define set_pte_at(mm,addr,ptep,pte)	\
+	__set_pte_at((mm), (addr), (ptep), (pte), 0)
+
 #define pte_clear(mm,addr,ptep)		\
 	set_pte_at((mm), (addr), (ptep), __pte(0UL))
 
+#define __HAVE_ARCH_PTE_CLEAR_NOT_PRESENT_FULL
+#define pte_clear_not_present_full(mm,addr,ptep,fullmm)	\
+	__set_pte_at((mm), (addr), (ptep), __pte(0UL), (fullmm))
+
 #ifdef DCACHE_ALIASING_POSSIBLE
 #define __HAVE_ARCH_MOVE_PTE
 #define move_pte(pte, prot, old_addr, new_addr)				\
@@ -699,6 +708,9 @@
 extern void paging_init(void);
 extern unsigned long find_ecache_flush_span(unsigned long size);
 
+struct seq_file;
+extern void mmu_info(struct seq_file *);
+
 /* These do nothing with the way I have things setup. */
 #define mmu_lockarea(vaddr, len)		(vaddr)
 #define mmu_unlockarea(vaddr, len)		do { } while(0)
diff -druN linux-2.6.39-libre/arch/sparc/include/asm/setup.h linux-3.0-rc7-libre/arch/sparc/include/asm/setup.h
--- linux-2.6.39-libre/arch/sparc/include/asm/setup.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/sparc/include/asm/setup.h	2011-07-11 19:51:52.000000000 -0400
@@ -11,4 +11,16 @@
 # define COMMAND_LINE_SIZE 256
 #endif
 
+#ifdef __KERNEL__
+
+#ifdef CONFIG_SPARC32
+/* The CPU that was used for booting
+ * Only sun4d + leon may have boot_cpu_id != 0
+ */
+extern unsigned char boot_cpu_id;
+extern unsigned char boot_cpu_id4;
+#endif
+
+#endif /* __KERNEL__ */
+
 #endif /* _SPARC_SETUP_H */
diff -druN linux-2.6.39-libre/arch/sparc/include/asm/smp_32.h linux-3.0-rc7-libre/arch/sparc/include/asm/smp_32.h
--- linux-2.6.39-libre/arch/sparc/include/asm/smp_32.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/sparc/include/asm/smp_32.h	2011-07-11 19:51:52.000000000 -0400
@@ -50,42 +50,38 @@
 void smp_boot_cpus(void);
 void smp_store_cpu_info(int);
 
+void smp_resched_interrupt(void);
+void smp_call_function_single_interrupt(void);
+void smp_call_function_interrupt(void);
+
 struct seq_file;
 void smp_bogo(struct seq_file *);
 void smp_info(struct seq_file *);
 
 BTFIXUPDEF_CALL(void, smp_cross_call, smpfunc_t, cpumask_t, unsigned long, unsigned long, unsigned long, unsigned long)
 BTFIXUPDEF_CALL(int, __hard_smp_processor_id, void)
+BTFIXUPDEF_CALL(void, smp_ipi_resched, int);
+BTFIXUPDEF_CALL(void, smp_ipi_single, int);
+BTFIXUPDEF_CALL(void, smp_ipi_mask_one, int);
 BTFIXUPDEF_BLACKBOX(hard_smp_processor_id)
 BTFIXUPDEF_BLACKBOX(load_current)
 
 #define smp_cross_call(func,mask,arg1,arg2,arg3,arg4) BTFIXUP_CALL(smp_cross_call)(func,mask,arg1,arg2,arg3,arg4)
 
-static inline void xc0(smpfunc_t func) { smp_cross_call(func, cpu_online_map, 0, 0, 0, 0); }
+static inline void xc0(smpfunc_t func) { smp_cross_call(func, *cpu_online_mask, 0, 0, 0, 0); }
 static inline void xc1(smpfunc_t func, unsigned long arg1)
-{ smp_cross_call(func, cpu_online_map, arg1, 0, 0, 0); }
+{ smp_cross_call(func, *cpu_online_mask, arg1, 0, 0, 0); }
 static inline void xc2(smpfunc_t func, unsigned long arg1, unsigned long arg2)
-{ smp_cross_call(func, cpu_online_map, arg1, arg2, 0, 0); }
+{ smp_cross_call(func, *cpu_online_mask, arg1, arg2, 0, 0); }
 static inline void xc3(smpfunc_t func, unsigned long arg1, unsigned long arg2,
 			   unsigned long arg3)
-{ smp_cross_call(func, cpu_online_map, arg1, arg2, arg3, 0); }
+{ smp_cross_call(func, *cpu_online_mask, arg1, arg2, arg3, 0); }
 static inline void xc4(smpfunc_t func, unsigned long arg1, unsigned long arg2,
 			   unsigned long arg3, unsigned long arg4)
-{ smp_cross_call(func, cpu_online_map, arg1, arg2, arg3, arg4); }
-
-static inline int smp_call_function(void (*func)(void *info), void *info, int wait)
-{
-	xc1((smpfunc_t)func, (unsigned long)info);
-	return 0;
-}
+{ smp_cross_call(func, *cpu_online_mask, arg1, arg2, arg3, arg4); }
 
-static inline int smp_call_function_single(int cpuid, void (*func) (void *info),
-					   void *info, int wait)
-{
-	smp_cross_call((smpfunc_t)func, cpumask_of_cpu(cpuid),
-		       (unsigned long) info, 0, 0, 0);
-	return 0;
-}
+extern void arch_send_call_function_single_ipi(int cpu);
+extern void arch_send_call_function_ipi_mask(const struct cpumask *mask);
 
 static inline int cpu_logical_map(int cpu)
 {
@@ -135,6 +131,11 @@
 		__asm__ __volatile__("lda [%g0] ASI_M_VIKING_TMP1, %0\n\t"
 				     "nop; nop" :
 				     "=&r" (cpuid));
+		     - leon
+		__asm__ __volatile__(	"rd %asr17, %0\n\t"
+					"srl %0, 0x1c, %0\n\t"
+					"nop\n\t" :
+					"=&r" (cpuid));
 	   See btfixup.h and btfixupprep.c to understand how a blackbox works.
 	 */
 	__asm__ __volatile__("sethi %%hi(___b_hard_smp_processor_id), %0\n\t"
diff -druN linux-2.6.39-libre/arch/sparc/include/asm/smp_64.h linux-3.0-rc7-libre/arch/sparc/include/asm/smp_64.h
--- linux-2.6.39-libre/arch/sparc/include/asm/smp_64.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/sparc/include/asm/smp_64.h	2011-07-11 19:51:52.000000000 -0400
@@ -49,6 +49,10 @@
 
 extern void smp_fetch_global_regs(void);
 
+struct seq_file;
+void smp_bogo(struct seq_file *);
+void smp_info(struct seq_file *);
+
 #ifdef CONFIG_HOTPLUG_CPU
 extern int __cpu_disable(void);
 extern void __cpu_die(unsigned int cpu);
diff -druN linux-2.6.39-libre/arch/sparc/include/asm/spinlock_32.h linux-3.0-rc7-libre/arch/sparc/include/asm/spinlock_32.h
--- linux-2.6.39-libre/arch/sparc/include/asm/spinlock_32.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/sparc/include/asm/spinlock_32.h	2011-07-11 19:51:52.000000000 -0400
@@ -9,6 +9,7 @@
 #ifndef __ASSEMBLY__
 
 #include <asm/psr.h>
+#include <asm/processor.h> /* for cpu_relax */
 
 #define arch_spin_is_locked(lock) (*((volatile unsigned char *)(lock)) != 0)
 
diff -druN linux-2.6.39-libre/arch/sparc/include/asm/system_32.h linux-3.0-rc7-libre/arch/sparc/include/asm/system_32.h
--- linux-2.6.39-libre/arch/sparc/include/asm/system_32.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/sparc/include/asm/system_32.h	2011-07-11 19:51:52.000000000 -0400
@@ -15,11 +15,6 @@
 
 #include <linux/irqflags.h>
 
-static inline unsigned int probe_irq_mask(unsigned long val)
-{
-	return 0;
-}
-
 /*
  * Sparc (general) CPU types
  */
@@ -225,7 +220,7 @@
 	switch (size) {
 	case 4:
 		return xchg_u32(ptr, x);
-	};
+	}
 	__xchg_called_with_bad_pointer();
 	return x;
 }
diff -druN linux-2.6.39-libre/arch/sparc/include/asm/system_64.h linux-3.0-rc7-libre/arch/sparc/include/asm/system_64.h
--- linux-2.6.39-libre/arch/sparc/include/asm/system_64.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/sparc/include/asm/system_64.h	2011-07-11 19:51:52.000000000 -0400
@@ -29,10 +29,6 @@
 /* This cannot ever be a sun4c :) That's just history. */
 #define ARCH_SUN4C 0
 
-extern const char *sparc_cpu_type;
-extern const char *sparc_fpu_type;
-extern const char *sparc_pmu_type;
-
 extern char reboot_command[];
 
 /* These are here in an effort to more fully work around Spitfire Errata
@@ -238,7 +234,7 @@
 		return xchg32(ptr, x);
 	case 8:
 		return xchg64(ptr, x);
-	};
+	}
 	__xchg_called_with_bad_pointer();
 	return x;
 }
diff -druN linux-2.6.39-libre/arch/sparc/include/asm/tlb_64.h linux-3.0-rc7-libre/arch/sparc/include/asm/tlb_64.h
--- linux-2.6.39-libre/arch/sparc/include/asm/tlb_64.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/sparc/include/asm/tlb_64.h	2011-07-11 19:51:52.000000000 -0400
@@ -7,66 +7,11 @@
 #include <asm/tlbflush.h>
 #include <asm/mmu_context.h>
 
-#define TLB_BATCH_NR	192
-
-/*
- * For UP we don't need to worry about TLB flush
- * and page free order so much..
- */
-#ifdef CONFIG_SMP
-  #define FREE_PTE_NR	506
-  #define tlb_fast_mode(bp) ((bp)->pages_nr == ~0U)
-#else
-  #define FREE_PTE_NR	1
-  #define tlb_fast_mode(bp) 1
-#endif
-
-struct mmu_gather {
-	struct mm_struct *mm;
-	unsigned int pages_nr;
-	unsigned int need_flush;
-	unsigned int fullmm;
-	unsigned int tlb_nr;
-	unsigned long vaddrs[TLB_BATCH_NR];
-	struct page *pages[FREE_PTE_NR];
-};
-
-DECLARE_PER_CPU(struct mmu_gather, mmu_gathers);
-
 #ifdef CONFIG_SMP
 extern void smp_flush_tlb_pending(struct mm_struct *,
 				  unsigned long, unsigned long *);
 #endif
 
-extern void __flush_tlb_pending(unsigned long, unsigned long, unsigned long *);
-extern void flush_tlb_pending(void);
-
-static inline struct mmu_gather *tlb_gather_mmu(struct mm_struct *mm, unsigned int full_mm_flush)
-{
-	struct mmu_gather *mp = &get_cpu_var(mmu_gathers);
-
-	BUG_ON(mp->tlb_nr);
-
-	mp->mm = mm;
-	mp->pages_nr = num_online_cpus() > 1 ? 0U : ~0U;
-	mp->fullmm = full_mm_flush;
-
-	return mp;
-}
-
-
-static inline void tlb_flush_mmu(struct mmu_gather *mp)
-{
-	if (!mp->fullmm)
-		flush_tlb_pending();
-	if (mp->need_flush) {
-		free_pages_and_swap_cache(mp->pages, mp->pages_nr);
-		mp->pages_nr = 0;
-		mp->need_flush = 0;
-	}
-
-}
-
 #ifdef CONFIG_SMP
 extern void smp_flush_tlb_mm(struct mm_struct *mm);
 #define do_flush_tlb_mm(mm) smp_flush_tlb_mm(mm)
@@ -74,38 +19,14 @@
 #define do_flush_tlb_mm(mm) __flush_tlb_mm(CTX_HWBITS(mm->context), SECONDARY_CONTEXT)
 #endif
 
-static inline void tlb_finish_mmu(struct mmu_gather *mp, unsigned long start, unsigned long end)
-{
-	tlb_flush_mmu(mp);
-
-	if (mp->fullmm)
-		mp->fullmm = 0;
-
-	/* keep the page table cache within bounds */
-	check_pgt_cache();
-
-	put_cpu_var(mmu_gathers);
-}
-
-static inline void tlb_remove_page(struct mmu_gather *mp, struct page *page)
-{
-	if (tlb_fast_mode(mp)) {
-		free_page_and_swap_cache(page);
-		return;
-	}
-	mp->need_flush = 1;
-	mp->pages[mp->pages_nr++] = page;
-	if (mp->pages_nr >= FREE_PTE_NR)
-		tlb_flush_mmu(mp);
-}
-
-#define tlb_remove_tlb_entry(mp,ptep,addr) do { } while (0)
-#define pte_free_tlb(mp, ptepage, addr) pte_free((mp)->mm, ptepage)
-#define pmd_free_tlb(mp, pmdp, addr) pmd_free((mp)->mm, pmdp)
-#define pud_free_tlb(tlb,pudp, addr) __pud_free_tlb(tlb,pudp,addr)
+extern void __flush_tlb_pending(unsigned long, unsigned long, unsigned long *);
+extern void flush_tlb_pending(void);
 
-#define tlb_migrate_finish(mm)	do { } while (0)
 #define tlb_start_vma(tlb, vma) do { } while (0)
 #define tlb_end_vma(tlb, vma)	do { } while (0)
+#define __tlb_remove_tlb_entry(tlb, ptep, address) do { } while (0)
+#define tlb_flush(tlb)	flush_tlb_pending()
+
+#include <asm-generic/tlb.h>
 
 #endif /* _SPARC64_TLB_H */
diff -druN linux-2.6.39-libre/arch/sparc/include/asm/tlbflush_64.h linux-3.0-rc7-libre/arch/sparc/include/asm/tlbflush_64.h
--- linux-2.6.39-libre/arch/sparc/include/asm/tlbflush_64.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/sparc/include/asm/tlbflush_64.h	2011-07-11 19:51:52.000000000 -0400
@@ -5,9 +5,17 @@
 #include <asm/mmu_context.h>
 
 /* TSB flush operations. */
-struct mmu_gather;
+
+#define TLB_BATCH_NR	192
+
+struct tlb_batch {
+	struct mm_struct *mm;
+	unsigned long tlb_nr;
+	unsigned long vaddrs[TLB_BATCH_NR];
+};
+
 extern void flush_tsb_kernel_range(unsigned long start, unsigned long end);
-extern void flush_tsb_user(struct mmu_gather *mp);
+extern void flush_tsb_user(struct tlb_batch *tb);
 
 /* TLB flush operations. */
 
diff -druN linux-2.6.39-libre/arch/sparc/include/asm/topology_64.h linux-3.0-rc7-libre/arch/sparc/include/asm/topology_64.h
--- linux-2.6.39-libre/arch/sparc/include/asm/topology_64.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/sparc/include/asm/topology_64.h	2011-07-11 19:51:52.000000000 -0400
@@ -65,6 +65,10 @@
 #define smt_capable()				(sparc64_multi_core)
 #endif /* CONFIG_SMP */
 
-#define cpu_coregroup_mask(cpu)			(&cpu_core_map[cpu])
+extern cpumask_t cpu_core_map[NR_CPUS];
+static inline const struct cpumask *cpu_coregroup_mask(int cpu)
+{
+        return &cpu_core_map[cpu];
+}
 
 #endif /* _ASM_SPARC64_TOPOLOGY_H */
diff -druN linux-2.6.39-libre/arch/sparc/include/asm/unistd.h linux-3.0-rc7-libre/arch/sparc/include/asm/unistd.h
--- linux-2.6.39-libre/arch/sparc/include/asm/unistd.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/sparc/include/asm/unistd.h	2011-07-11 19:51:52.000000000 -0400
@@ -404,8 +404,10 @@
 #define __NR_open_by_handle_at	333
 #define __NR_clock_adjtime	334
 #define __NR_syncfs		335
+#define __NR_sendmmsg		336
+#define __NR_setns		337
 
-#define NR_syscalls		336
+#define NR_syscalls		338
 
 #ifdef __32bit_syscall_numbers__
 /* Sparc 32-bit only has the "setresuid32", "getresuid32" variants,
diff -druN linux-2.6.39-libre/arch/sparc/include/asm/winmacro.h linux-3.0-rc7-libre/arch/sparc/include/asm/winmacro.h
--- linux-2.6.39-libre/arch/sparc/include/asm/winmacro.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/sparc/include/asm/winmacro.h	2011-07-11 19:51:52.000000000 -0400
@@ -103,6 +103,7 @@
         st       %scratch, [%cur_reg + TI_W_SAVED];
 
 #ifdef CONFIG_SMP
+/* Results of LOAD_CURRENT() after BTFIXUP for SUN4M, SUN4D & LEON (comments) */
 #define LOAD_CURRENT4M(dest_reg, idreg) \
         rd       %tbr, %idreg; \
 	sethi    %hi(current_set), %dest_reg; \
@@ -118,6 +119,14 @@
 	or	%dest_reg, %lo(C_LABEL(current_set)), %dest_reg; \
 	ld	[%idreg + %dest_reg], %dest_reg;
 
+#define LOAD_CURRENT_LEON(dest_reg, idreg)			\
+	rd	%asr17, %idreg;					\
+	sethi	%hi(current_set), %dest_reg;			\
+	srl	%idreg, 0x1c, %idreg;				\
+	or	%dest_reg, %lo(current_set), %dest_reg;		\
+	sll	%idreg, 0x2, %idreg;				\
+	ld	[%idreg + %dest_reg], %dest_reg;
+
 /* Blackbox - take care with this... - check smp4m and smp4d before changing this. */
 #define LOAD_CURRENT(dest_reg, idreg) 					\
 	sethi	 %hi(___b_load_current), %idreg;			\
diff -druN linux-2.6.39-libre/arch/sparc/Kconfig linux-3.0-rc7-libre/arch/sparc/Kconfig
--- linux-2.6.39-libre/arch/sparc/Kconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/sparc/Kconfig	2011-07-11 19:51:52.000000000 -0400
@@ -25,6 +25,9 @@
 	select HAVE_DMA_ATTRS
 	select HAVE_DMA_API_DEBUG
 	select HAVE_ARCH_JUMP_LABEL
+	select HAVE_GENERIC_HARDIRQS
+	select GENERIC_IRQ_SHOW
+	select USE_GENERIC_SMP_HELPERS if SMP
 
 config SPARC32
 	def_bool !64BIT
@@ -43,15 +46,12 @@
 	select HAVE_DYNAMIC_FTRACE
 	select HAVE_FTRACE_MCOUNT_RECORD
 	select HAVE_SYSCALL_TRACEPOINTS
-	select USE_GENERIC_SMP_HELPERS if SMP
 	select RTC_DRV_CMOS
 	select RTC_DRV_BQ4802
 	select RTC_DRV_SUN4V
 	select RTC_DRV_STARFIRE
 	select HAVE_PERF_EVENTS
 	select PERF_USE_VMALLOC
-	select HAVE_GENERIC_HARDIRQS
-	select GENERIC_IRQ_SHOW
 	select IRQ_PREFLOW_FASTEOI
 
 config ARCH_DEFCONFIG
@@ -189,14 +189,6 @@
 	bool
 	default y if SPARC64
 
-config GENERIC_FIND_NEXT_BIT
-	bool
-	default y
-
-config GENERIC_FIND_BIT_LE
-	bool
-	default y
-
 config GENERIC_HWEIGHT
 	bool
 	default y if !ULTRA_HAS_POPULATION_COUNT
@@ -535,6 +527,23 @@
 config PCI_SYSCALL
 	def_bool PCI
 
+config PCIC_PCI
+	bool
+	depends on PCI && SPARC32 && !SPARC_LEON
+	default y
+
+config LEON_PCI
+	bool
+	depends on PCI && SPARC_LEON
+	default y
+
+config GRPCI2
+	bool "GRPCI2 Host Bridge Support"
+	depends on LEON_PCI
+	default y
+	help
+	  Say Y here to include the GRPCI2 Host Bridge Driver.
+
 source "drivers/pci/Kconfig"
 
 source "drivers/pcmcia/Kconfig"
diff -druN linux-2.6.39-libre/arch/sparc/Kconfig.debug linux-3.0-rc7-libre/arch/sparc/Kconfig.debug
--- linux-2.6.39-libre/arch/sparc/Kconfig.debug	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/sparc/Kconfig.debug	2011-07-11 19:51:52.000000000 -0400
@@ -6,15 +6,6 @@
 
 source "lib/Kconfig.debug"
 
-config DEBUG_STACK_USAGE
-	bool "Enable stack utilization instrumentation"
-	depends on DEBUG_KERNEL
-	help
-	  Enables the display of the minimum amount of free stack which each
-	  task has ever had available in the sysrq-T and sysrq-P debug output.
-
-	  This option will slow down process creation somewhat.
-
 config DEBUG_DCFLUSH
 	bool "D-cache flush debugging"
 	depends on SPARC64 && DEBUG_KERNEL
diff -druN linux-2.6.39-libre/arch/sparc/kernel/apc.c linux-3.0-rc7-libre/arch/sparc/kernel/apc.c
--- linux-2.6.39-libre/arch/sparc/kernel/apc.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/sparc/kernel/apc.c	2011-07-11 19:51:52.000000000 -0400
@@ -123,7 +123,7 @@
 
 	default:
 		return -EINVAL;
-	};
+	}
 
 	return 0;
 }
diff -druN linux-2.6.39-libre/arch/sparc/kernel/auxio_32.c linux-3.0-rc7-libre/arch/sparc/kernel/auxio_32.c
--- linux-2.6.39-libre/arch/sparc/kernel/auxio_32.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/sparc/kernel/auxio_32.c	2011-07-11 19:51:52.000000000 -0400
@@ -101,7 +101,7 @@
 		break;
 	default:
 		panic("Can't set AUXIO register on this machine.");
-	};
+	}
 	spin_unlock_irqrestore(&auxio_lock, flags);
 }
 EXPORT_SYMBOL(set_auxio);
diff -druN linux-2.6.39-libre/arch/sparc/kernel/chmc.c linux-3.0-rc7-libre/arch/sparc/kernel/chmc.c
--- linux-2.6.39-libre/arch/sparc/kernel/chmc.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/sparc/kernel/chmc.c	2011-07-11 19:51:52.000000000 -0400
@@ -664,7 +664,7 @@
 	case 0x0:
 		bp->interleave = 16;
 		break;
-	};
+	}
 
 	/* UK[10] is reserved, and UK[11] is not set for the SDRAM
 	 * bank size definition.
diff -druN linux-2.6.39-libre/arch/sparc/kernel/cpu.c linux-3.0-rc7-libre/arch/sparc/kernel/cpu.c
--- linux-2.6.39-libre/arch/sparc/kernel/cpu.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/sparc/kernel/cpu.c	2011-07-11 19:51:52.000000000 -0400
@@ -4,6 +4,7 @@
  * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
  */
 
+#include <linux/seq_file.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/init.h>
@@ -11,7 +12,9 @@
 #include <linux/threads.h>
 
 #include <asm/spitfire.h>
+#include <asm/pgtable.h>
 #include <asm/oplib.h>
+#include <asm/setup.h>
 #include <asm/page.h>
 #include <asm/head.h>
 #include <asm/psr.h>
@@ -23,6 +26,9 @@
 DEFINE_PER_CPU(cpuinfo_sparc, __cpu_data) = { 0 };
 EXPORT_PER_CPU_SYMBOL(__cpu_data);
 
+int ncpus_probed;
+unsigned int fsr_storage;
+
 struct cpu_info {
 	int psr_vers;
 	const char *name;
@@ -247,13 +253,12 @@
  * machine type value into consideration too.  I will fix this.
  */
 
-const char *sparc_cpu_type;
-const char *sparc_fpu_type;
+static const char *sparc_cpu_type;
+static const char *sparc_fpu_type;
 const char *sparc_pmu_type;
 
-unsigned int fsr_storage;
 
-static void set_cpu_and_fpu(int psr_impl, int psr_vers, int fpu_vers)
+static void __init set_cpu_and_fpu(int psr_impl, int psr_vers, int fpu_vers)
 {
 	const struct manufacturer_info *manuf;
 	int i;
@@ -313,7 +318,123 @@
 }
 
 #ifdef CONFIG_SPARC32
-void __cpuinit cpu_probe(void)
+static int show_cpuinfo(struct seq_file *m, void *__unused)
+{
+	seq_printf(m,
+		   "cpu\t\t: %s\n"
+		   "fpu\t\t: %s\n"
+		   "promlib\t\t: Version %d Revision %d\n"
+		   "prom\t\t: %d.%d\n"
+		   "type\t\t: %s\n"
+		   "ncpus probed\t: %d\n"
+		   "ncpus active\t: %d\n"
+#ifndef CONFIG_SMP
+		   "CPU0Bogo\t: %lu.%02lu\n"
+		   "CPU0ClkTck\t: %ld\n"
+#endif
+		   ,
+		   sparc_cpu_type,
+		   sparc_fpu_type ,
+		   romvec->pv_romvers,
+		   prom_rev,
+		   romvec->pv_printrev >> 16,
+		   romvec->pv_printrev & 0xffff,
+		   &cputypval[0],
+		   ncpus_probed,
+		   num_online_cpus()
+#ifndef CONFIG_SMP
+		   , cpu_data(0).udelay_val/(500000/HZ),
+		   (cpu_data(0).udelay_val/(5000/HZ)) % 100,
+		   cpu_data(0).clock_tick
+#endif
+		);
+
+#ifdef CONFIG_SMP
+	smp_bogo(m);
+#endif
+	mmu_info(m);
+#ifdef CONFIG_SMP
+	smp_info(m);
+#endif
+	return 0;
+}
+#endif /* CONFIG_SPARC32 */
+
+#ifdef CONFIG_SPARC64
+unsigned int dcache_parity_tl1_occurred;
+unsigned int icache_parity_tl1_occurred;
+
+
+static int show_cpuinfo(struct seq_file *m, void *__unused)
+{
+	seq_printf(m,
+		   "cpu\t\t: %s\n"
+		   "fpu\t\t: %s\n"
+		   "pmu\t\t: %s\n"
+		   "prom\t\t: %s\n"
+		   "type\t\t: %s\n"
+		   "ncpus probed\t: %d\n"
+		   "ncpus active\t: %d\n"
+		   "D$ parity tl1\t: %u\n"
+		   "I$ parity tl1\t: %u\n"
+#ifndef CONFIG_SMP
+		   "Cpu0ClkTck\t: %016lx\n"
+#endif
+		   ,
+		   sparc_cpu_type,
+		   sparc_fpu_type,
+		   sparc_pmu_type,
+		   prom_version,
+		   ((tlb_type == hypervisor) ?
+		    "sun4v" :
+		    "sun4u"),
+		   ncpus_probed,
+		   num_online_cpus(),
+		   dcache_parity_tl1_occurred,
+		   icache_parity_tl1_occurred
+#ifndef CONFIG_SMP
+		   , cpu_data(0).clock_tick
+#endif
+		);
+#ifdef CONFIG_SMP
+	smp_bogo(m);
+#endif
+	mmu_info(m);
+#ifdef CONFIG_SMP
+	smp_info(m);
+#endif
+	return 0;
+}
+#endif /* CONFIG_SPARC64 */
+
+static void *c_start(struct seq_file *m, loff_t *pos)
+{
+	/* The pointer we are returning is arbitrary,
+	 * it just has to be non-NULL and not IS_ERR
+	 * in the success case.
+	 */
+	return *pos == 0 ? &c_start : NULL;
+}
+
+static void *c_next(struct seq_file *m, void *v, loff_t *pos)
+{
+	++*pos;
+	return c_start(m, pos);
+}
+
+static void c_stop(struct seq_file *m, void *v)
+{
+}
+
+const struct seq_operations cpuinfo_op = {
+	.start =c_start,
+	.next =	c_next,
+	.stop =	c_stop,
+	.show =	show_cpuinfo,
+};
+
+#ifdef CONFIG_SPARC32
+static int __init cpu_type_probe(void)
 {
 	int psr_impl, psr_vers, fpu_vers;
 	int psr;
@@ -332,8 +453,12 @@
 	put_psr(psr);
 
 	set_cpu_and_fpu(psr_impl, psr_vers, fpu_vers);
+
+	return 0;
 }
-#else
+#endif /* CONFIG_SPARC32 */
+
+#ifdef CONFIG_SPARC64
 static void __init sun4v_cpu_probe(void)
 {
 	switch (sun4v_chip_type) {
@@ -374,6 +499,6 @@
 	}
 	return 0;
 }
+#endif /* CONFIG_SPARC64 */
 
 early_initcall(cpu_type_probe);
-#endif
diff -druN linux-2.6.39-libre/arch/sparc/kernel/cpumap.c linux-3.0-rc7-libre/arch/sparc/kernel/cpumap.c
--- linux-2.6.39-libre/arch/sparc/kernel/cpumap.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/sparc/kernel/cpumap.c	2011-07-11 19:51:52.000000000 -0400
@@ -202,7 +202,7 @@
 	new_tree->total_nodes = n;
 	memcpy(&new_tree->level, tmp_level, sizeof(tmp_level));
 
-	prev_cpu = cpu = first_cpu(cpu_online_map);
+	prev_cpu = cpu = cpumask_first(cpu_online_mask);
 
 	/* Initialize all levels in the tree with the first CPU */
 	for (level = CPUINFO_LVL_PROC; level >= CPUINFO_LVL_ROOT; level--) {
@@ -381,7 +381,7 @@
 	}
 
 	/* Impossible, since num_online_cpus() <= num_possible_cpus() */
-	return first_cpu(cpu_online_map);
+	return cpumask_first(cpu_online_mask);
 }
 
 static int _map_to_cpu(unsigned int index)
diff -druN linux-2.6.39-libre/arch/sparc/kernel/devices.c linux-3.0-rc7-libre/arch/sparc/kernel/devices.c
--- linux-2.6.39-libre/arch/sparc/kernel/devices.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/sparc/kernel/devices.c	2011-07-11 19:51:52.000000000 -0400
@@ -20,7 +20,6 @@
 #include <asm/system.h>
 #include <asm/cpudata.h>
 
-extern void cpu_probe(void);
 extern void clock_stop_probe(void); /* tadpole.c */
 extern void sun4c_probe_memerr_reg(void);
 
@@ -115,7 +114,7 @@
 
 void __init device_scan(void)
 {
-	prom_printf("Booting Linux...\n");
+	printk(KERN_NOTICE "Booting Linux...\n");
 
 #ifndef CONFIG_SMP
 	{
@@ -133,7 +132,6 @@
 	}
 #endif /* !CONFIG_SMP */
 
-	cpu_probe();
 	{
 		extern void auxio_probe(void);
 		extern void auxio_power_probe(void);
diff -druN linux-2.6.39-libre/arch/sparc/kernel/ds.c linux-3.0-rc7-libre/arch/sparc/kernel/ds.c
--- linux-2.6.39-libre/arch/sparc/kernel/ds.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/sparc/kernel/ds.c	2011-07-11 19:51:52.000000000 -0400
@@ -497,7 +497,7 @@
 	tag->num_records = ncpus;
 
 	i = 0;
-	for_each_cpu_mask(cpu, *mask) {
+	for_each_cpu(cpu, mask) {
 		ent[i].cpu = cpu;
 		ent[i].result = DR_CPU_RES_OK;
 		ent[i].stat = default_stat;
@@ -534,7 +534,7 @@
 	int resp_len, ncpus, cpu;
 	unsigned long flags;
 
-	ncpus = cpus_weight(*mask);
+	ncpus = cpumask_weight(mask);
 	resp_len = dr_cpu_size_response(ncpus);
 	resp = kzalloc(resp_len, GFP_KERNEL);
 	if (!resp)
@@ -547,7 +547,7 @@
 	mdesc_populate_present_mask(mask);
 	mdesc_fill_in_cpu_data(mask);
 
-	for_each_cpu_mask(cpu, *mask) {
+	for_each_cpu(cpu, mask) {
 		int err;
 
 		printk(KERN_INFO "ds-%llu: Starting cpu %d...\n",
@@ -593,7 +593,7 @@
 	int resp_len, ncpus, cpu;
 	unsigned long flags;
 
-	ncpus = cpus_weight(*mask);
+	ncpus = cpumask_weight(mask);
 	resp_len = dr_cpu_size_response(ncpus);
 	resp = kzalloc(resp_len, GFP_KERNEL);
 	if (!resp)
@@ -603,7 +603,7 @@
 			     resp_len, ncpus, mask,
 			     DR_CPU_STAT_UNCONFIGURED);
 
-	for_each_cpu_mask(cpu, *mask) {
+	for_each_cpu(cpu, mask) {
 		int err;
 
 		printk(KERN_INFO "ds-%llu: Shutting down cpu %d...\n",
@@ -649,13 +649,13 @@
 
 	purge_dups(cpu_list, tag->num_records);
 
-	cpus_clear(mask);
+	cpumask_clear(&mask);
 	for (i = 0; i < tag->num_records; i++) {
 		if (cpu_list[i] == CPU_SENTINEL)
 			continue;
 
 		if (cpu_list[i] < nr_cpu_ids)
-			cpu_set(cpu_list[i], mask);
+			cpumask_set_cpu(cpu_list[i], &mask);
 	}
 
 	if (tag->type == DR_CPU_CONFIGURE)
diff -druN linux-2.6.39-libre/arch/sparc/kernel/entry.S linux-3.0-rc7-libre/arch/sparc/kernel/entry.S
--- linux-2.6.39-libre/arch/sparc/kernel/entry.S	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/sparc/kernel/entry.S	2011-07-11 19:51:52.000000000 -0400
@@ -229,7 +229,7 @@
 #ifdef CONFIG_SMP
 	.globl	patchme_maybe_smp_msg
 
-	cmp	%l7, 12
+	cmp	%l7, 11
 patchme_maybe_smp_msg:
 	bgu	maybe_smp4m_msg
 	 nop
@@ -269,19 +269,22 @@
 	/* Here is where we check for possible SMP IPI passed to us
 	 * on some level other than 15 which is the NMI and only used
 	 * for cross calls.  That has a separate entry point below.
+	 *
+	 * IPIs are sent on Level 12, 13 and 14. See IRQ_IPI_*.
 	 */
 maybe_smp4m_msg:
 	GET_PROCESSOR4M_ID(o3)
 	sethi	%hi(sun4m_irq_percpu), %l5
 	sll	%o3, 2, %o3
 	or	%l5, %lo(sun4m_irq_percpu), %o5
-	sethi	%hi(0x40000000), %o2
+	sethi	%hi(0x70000000), %o2	! Check all soft-IRQs
 	ld	[%o5 + %o3], %o1
 	ld	[%o1 + 0x00], %o3	! sun4m_irq_percpu[cpu]->pending
 	andcc	%o3, %o2, %g0
 	be,a	smp4m_ticker
 	 cmp	%l7, 14
-	st	%o2, [%o1 + 0x04]	! sun4m_irq_percpu[cpu]->clear=0x40000000
+	/* Soft-IRQ IPI */
+	st	%o2, [%o1 + 0x04]	! sun4m_irq_percpu[cpu]->clear=0x70000000
 	WRITE_PAUSE
 	ld	[%o1 + 0x00], %g0	! sun4m_irq_percpu[cpu]->pending
 	WRITE_PAUSE
@@ -290,9 +293,27 @@
 	WRITE_PAUSE
 	wr	%l4, PSR_ET, %psr
 	WRITE_PAUSE
-	call	smp_reschedule_irq
+	sll	%o3, 28, %o2		! shift for simpler checks below
+maybe_smp4m_msg_check_single:
+	andcc	%o2, 0x1, %g0
+	beq,a	maybe_smp4m_msg_check_mask
+	 andcc	%o2, 0x2, %g0
+	call	smp_call_function_single_interrupt
 	 nop
-
+	andcc	%o2, 0x2, %g0
+maybe_smp4m_msg_check_mask:
+	beq,a	maybe_smp4m_msg_check_resched
+	 andcc	%o2, 0x4, %g0
+	call	smp_call_function_interrupt
+	 nop
+	andcc	%o2, 0x4, %g0
+maybe_smp4m_msg_check_resched:
+	/* rescheduling is done in RESTORE_ALL regardless, but incr stats */
+	beq,a	maybe_smp4m_msg_out
+	 nop
+	call	smp_resched_interrupt
+	 nop
+maybe_smp4m_msg_out:
 	RESTORE_ALL
 
 	.align	4
@@ -401,18 +422,18 @@
 1:	b,a	1b
 
 #ifdef CONFIG_SPARC_LEON
-
-	.globl	smpleon_ticker
-	/* SMP per-cpu ticker interrupts are handled specially. */
-smpleon_ticker:
+	.globl	smpleon_ipi
+	.extern leon_ipi_interrupt
+	/* SMP per-cpu IPI interrupts are handled specially. */
+smpleon_ipi:
         SAVE_ALL
 	or	%l0, PSR_PIL, %g2
 	wr	%g2, 0x0, %psr
 	WRITE_PAUSE
 	wr	%g2, PSR_ET, %psr
 	WRITE_PAUSE
-	call	leon_percpu_timer_interrupt
-	 add	%sp, STACKFRAME_SZ, %o0
+	call	leonsmp_ipi_interrupt
+	 add	%sp, STACKFRAME_SZ, %o1 ! pt_regs
 	wr	%l0, PSR_ET, %psr
 	WRITE_PAUSE
 	RESTORE_ALL
@@ -1583,7 +1604,7 @@
 	retl
 	 nop
 
-#ifdef CONFIG_PCI
+#ifdef CONFIG_PCIC_PCI
 #include <asm/pcic.h>
 
 	.align	4
@@ -1629,7 +1650,7 @@
 	 rd	%psr, %l0
 	.word	0
 
-#endif /* CONFIG_PCI */
+#endif /* CONFIG_PCIC_PCI */
 
 	.globl	flushw_all
 flushw_all:
diff -druN linux-2.6.39-libre/arch/sparc/kernel/head_32.S linux-3.0-rc7-libre/arch/sparc/kernel/head_32.S
--- linux-2.6.39-libre/arch/sparc/kernel/head_32.S	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/sparc/kernel/head_32.S	2011-07-11 19:51:52.000000000 -0400
@@ -810,31 +810,25 @@
 got_prop:
 #ifdef CONFIG_SPARC_LEON
 	        /* no cpu-type check is needed, it is a SPARC-LEON */
-#ifdef CONFIG_SMP
-		ba leon_smp_init
-		 nop
 
-		.global leon_smp_init
-leon_smp_init:
-		sethi	%hi(boot_cpu_id), %g1    ! master always 0
-		stb	%g0, [%g1 + %lo(boot_cpu_id)]
-		sethi	%hi(boot_cpu_id4), %g1   ! master always 0
-		stb	%g0, [%g1 + %lo(boot_cpu_id4)]
+		sethi	%hi(boot_cpu_id), %g2	! boot-cpu index
 
-		rd     %asr17,%g1
-		srl    %g1,28,%g1
+#ifdef CONFIG_SMP
+		ldub	[%g2 + %lo(boot_cpu_id)], %g1
+		cmp	%g1, 0xff		! unset means first CPU
+		bne	leon_smp_cpu_startup	! continue only with master
+		 nop
+#endif
+		/* Get CPU-ID from most significant 4-bit of ASR17 */
+		rd     %asr17, %g1
+		srl    %g1, 28, %g1
 
-		cmp %g0,%g1
-		 beq sun4c_continue_boot         !continue with master
-		nop
+		/* Update boot_cpu_id only on boot cpu */
+		stub	%g1, [%g2 + %lo(boot_cpu_id)]
 
-		ba leon_smp_cpu_startup
-		 nop
-#else
 		ba sun4c_continue_boot
 		 nop
 #endif
-#endif
 		set	cputypval, %o2
 		ldub	[%o2 + 0x4], %l1
 
@@ -893,9 +887,6 @@
 	sta     %g4, [%g0] ASI_M_VIKING_TMP1
 	sethi	%hi(boot_cpu_id), %g5
 	stb	%g4, [%g5 + %lo(boot_cpu_id)]
-	sll	%g4, 2, %g4
-	sethi	%hi(boot_cpu_id4), %g5
-	stb	%g4, [%g5 + %lo(boot_cpu_id4)]
 #endif
 
 	/* Fall through to sun4m_init */
@@ -1024,14 +1015,28 @@
 		bl	1b
 		 add	%o0, 0x1, %o0
 
+		/* If boot_cpu_id has not been setup by machine specific
+		 * init-code above we default it to zero.
+		 */
+		sethi	%hi(boot_cpu_id), %g2
+		ldub	[%g2 + %lo(boot_cpu_id)], %g3
+		cmp	%g3, 0xff
+		bne	1f
+		 nop
+		mov	%g0, %g3
+		stub	%g3, [%g2 + %lo(boot_cpu_id)]
+
+1:		/* boot_cpu_id set. calculate boot_cpu_id4 = boot_cpu_id*4 */
+		sll	%g3, 2, %g3
+		sethi	%hi(boot_cpu_id4), %g2
+		stub	%g3, [%g2 + %lo(boot_cpu_id4)]
+
 		/* Initialize the uwinmask value for init task just in case.
 		 * But first make current_set[boot_cpu_id] point to something useful.
 		 */
 		set	init_thread_union, %g6
 		set	current_set, %g2
 #ifdef CONFIG_SMP
-		sethi	%hi(boot_cpu_id4), %g3
-		ldub	[%g3 + %lo(boot_cpu_id4)], %g3
 		st	%g6, [%g2]
 		add	%g2, %g3, %g2
 #endif
diff -druN linux-2.6.39-libre/arch/sparc/kernel/ioport.c linux-3.0-rc7-libre/arch/sparc/kernel/ioport.c
--- linux-2.6.39-libre/arch/sparc/kernel/ioport.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/sparc/kernel/ioport.c	2011-07-11 19:51:52.000000000 -0400
@@ -50,10 +50,15 @@
 #include <asm/io-unit.h>
 #include <asm/leon.h>
 
+/* This function must make sure that caches and memory are coherent after DMA
+ * On LEON systems without cache snooping it flushes the entire D-CACHE.
+ */
 #ifndef CONFIG_SPARC_LEON
-#define mmu_inval_dma_area(p, l)	/* Anton pulled it out for 2.4.0-xx */
+static inline void dma_make_coherent(unsigned long pa, unsigned long len)
+{
+}
 #else
-static inline void mmu_inval_dma_area(void *va, unsigned long len)
+static inline void dma_make_coherent(unsigned long pa, unsigned long len)
 {
 	if (!sparc_leon3_snooping_enabled())
 		leon_flush_dcache_all();
@@ -284,7 +289,6 @@
 		printk("sbus_alloc_consistent: cannot occupy 0x%lx", len_total);
 		goto err_nova;
 	}
-	mmu_inval_dma_area((void *)va, len_total);
 
 	// XXX The mmu_map_dma_area does this for us below, see comments.
 	// sparc_mapiorange(0, virt_to_phys(va), res->start, len_total);
@@ -336,7 +340,6 @@
 	release_resource(res);
 	kfree(res);
 
-	/* mmu_inval_dma_area(va, n); */ /* it's consistent, isn't it */
 	pgv = virt_to_page(p);
 	mmu_unmap_dma_area(dev, ba, n);
 
@@ -463,7 +466,6 @@
 		printk("pci_alloc_consistent: cannot occupy 0x%lx", len_total);
 		goto err_nova;
 	}
-	mmu_inval_dma_area(va, len_total);
 	sparc_mapiorange(0, virt_to_phys(va), res->start, len_total);
 
 	*pba = virt_to_phys(va); /* equals virt_to_bus (R.I.P.) for us. */
@@ -489,7 +491,6 @@
 				dma_addr_t ba)
 {
 	struct resource *res;
-	void *pgp;
 
 	if ((res = _sparc_find_resource(&_sparc_dvma,
 	    (unsigned long)p)) == NULL) {
@@ -509,14 +510,12 @@
 		return;
 	}
 
-	pgp = phys_to_virt(ba);	/* bus_to_virt actually */
-	mmu_inval_dma_area(pgp, n);
+	dma_make_coherent(ba, n);
 	sparc_unmapiorange((unsigned long)p, n);
 
 	release_resource(res);
 	kfree(res);
-
-	free_pages((unsigned long)pgp, get_order(n));
+	free_pages((unsigned long)phys_to_virt(ba), get_order(n));
 }
 
 /*
@@ -535,7 +534,7 @@
 			     enum dma_data_direction dir, struct dma_attrs *attrs)
 {
 	if (dir != PCI_DMA_TODEVICE)
-		mmu_inval_dma_area(phys_to_virt(ba), PAGE_ALIGN(size));
+		dma_make_coherent(ba, PAGE_ALIGN(size));
 }
 
 /* Map a set of buffers described by scatterlist in streaming
@@ -562,8 +561,7 @@
 
 	/* IIep is write-through, not flushing. */
 	for_each_sg(sgl, sg, nents, n) {
-		BUG_ON(page_address(sg_page(sg)) == NULL);
-		sg->dma_address = virt_to_phys(sg_virt(sg));
+		sg->dma_address = sg_phys(sg);
 		sg->dma_length = sg->length;
 	}
 	return nents;
@@ -582,9 +580,7 @@
 
 	if (dir != PCI_DMA_TODEVICE) {
 		for_each_sg(sgl, sg, nents, n) {
-			BUG_ON(page_address(sg_page(sg)) == NULL);
-			mmu_inval_dma_area(page_address(sg_page(sg)),
-					   PAGE_ALIGN(sg->length));
+			dma_make_coherent(sg_phys(sg), PAGE_ALIGN(sg->length));
 		}
 	}
 }
@@ -603,8 +599,7 @@
 				      size_t size, enum dma_data_direction dir)
 {
 	if (dir != PCI_DMA_TODEVICE) {
-		mmu_inval_dma_area(phys_to_virt(ba),
-				   PAGE_ALIGN(size));
+		dma_make_coherent(ba, PAGE_ALIGN(size));
 	}
 }
 
@@ -612,8 +607,7 @@
 					 size_t size, enum dma_data_direction dir)
 {
 	if (dir != PCI_DMA_TODEVICE) {
-		mmu_inval_dma_area(phys_to_virt(ba),
-				   PAGE_ALIGN(size));
+		dma_make_coherent(ba, PAGE_ALIGN(size));
 	}
 }
 
@@ -631,9 +625,7 @@
 
 	if (dir != PCI_DMA_TODEVICE) {
 		for_each_sg(sgl, sg, nents, n) {
-			BUG_ON(page_address(sg_page(sg)) == NULL);
-			mmu_inval_dma_area(page_address(sg_page(sg)),
-					   PAGE_ALIGN(sg->length));
+			dma_make_coherent(sg_phys(sg), PAGE_ALIGN(sg->length));
 		}
 	}
 }
@@ -646,9 +638,7 @@
 
 	if (dir != PCI_DMA_TODEVICE) {
 		for_each_sg(sgl, sg, nents, n) {
-			BUG_ON(page_address(sg_page(sg)) == NULL);
-			mmu_inval_dma_area(page_address(sg_page(sg)),
-					   PAGE_ALIGN(sg->length));
+			dma_make_coherent(sg_phys(sg), PAGE_ALIGN(sg->length));
 		}
 	}
 }
diff -druN linux-2.6.39-libre/arch/sparc/kernel/irq_32.c linux-3.0-rc7-libre/arch/sparc/kernel/irq_32.c
--- linux-2.6.39-libre/arch/sparc/kernel/irq_32.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/sparc/kernel/irq_32.c	2011-07-11 19:51:52.000000000 -0400
@@ -15,6 +15,7 @@
 #include <linux/seq_file.h>
 
 #include <asm/cacheflush.h>
+#include <asm/cpudata.h>
 #include <asm/pcic.h>
 #include <asm/leon.h>
 
@@ -101,284 +102,173 @@
  * directed CPU interrupts using the existing enable/disable irq code
  * with tweaks.
  *
+ * Sun4d complicates things even further.  IRQ numbers are arbitrary
+ * 32-bit values in that case.  Since this is similar to sparc64,
+ * we adopt a virtual IRQ numbering scheme as is done there.
+ * Virutal interrupt numbers are allocated by build_irq().  So NR_IRQS
+ * just becomes a limit of how many interrupt sources we can handle in
+ * a single system.  Even fully loaded SS2000 machines top off at
+ * about 32 interrupt sources or so, therefore a NR_IRQS value of 64
+ * is more than enough.
+  *
+ * We keep a map of per-PIL enable interrupts.  These get wired
+ * up via the irq_chip->startup() method which gets invoked by
+ * the generic IRQ layer during request_irq().
  */
 
 
+/* Table of allocated irqs. Unused entries has irq == 0 */
+static struct irq_bucket irq_table[NR_IRQS];
+/* Protect access to irq_table */
+static DEFINE_SPINLOCK(irq_table_lock);
 
-/*
- * Dave Redman (djhr@tadpole.co.uk)
- *
- * There used to be extern calls and hard coded values here.. very sucky!
- * instead, because some of the devices attach very early, I do something
- * equally sucky but at least we'll never try to free statically allocated
- * space or call kmalloc before kmalloc_init :(.
- *
- * In fact it's the timer10 that attaches first.. then timer14
- * then kmalloc_init is called.. then the tty interrupts attach.
- * hmmm....
- *
- */
-#define MAX_STATIC_ALLOC	4
-struct irqaction static_irqaction[MAX_STATIC_ALLOC];
-int static_irq_count;
-
-static struct {
-	struct irqaction *action;
-	int flags;
-} sparc_irq[NR_IRQS];
-#define SPARC_IRQ_INPROGRESS 1
-
-/* Used to protect the IRQ action lists */
-DEFINE_SPINLOCK(irq_action_lock);
+/* Map between the irq identifier used in hw to the irq_bucket. */
+struct irq_bucket *irq_map[SUN4D_MAX_IRQ];
+/* Protect access to irq_map */
+static DEFINE_SPINLOCK(irq_map_lock);
 
-int show_interrupts(struct seq_file *p, void *v)
+/* Allocate a new irq from the irq_table */
+unsigned int irq_alloc(unsigned int real_irq, unsigned int pil)
 {
-	int i = *(loff_t *)v;
-	struct irqaction *action;
 	unsigned long flags;
-#ifdef CONFIG_SMP
-	int j;
-#endif
+	unsigned int i;
 
-	if (sparc_cpu_model == sun4d)
-		return show_sun4d_interrupts(p, v);
+	spin_lock_irqsave(&irq_table_lock, flags);
+	for (i = 1; i < NR_IRQS; i++) {
+		if (irq_table[i].real_irq == real_irq && irq_table[i].pil == pil)
+			goto found;
+	}
+
+	for (i = 1; i < NR_IRQS; i++) {
+		if (!irq_table[i].irq)
+			break;
+	}
 
-	spin_lock_irqsave(&irq_action_lock, flags);
 	if (i < NR_IRQS) {
-		action = sparc_irq[i].action;
-		if (!action)
-			goto out_unlock;
-		seq_printf(p, "%3d: ", i);
-#ifndef CONFIG_SMP
-		seq_printf(p, "%10u ", kstat_irqs(i));
-#else
-		for_each_online_cpu(j) {
-			seq_printf(p, "%10u ",
-				    kstat_cpu(j).irqs[i]);
-		}
-#endif
-		seq_printf(p, " %c %s",
-			(action->flags & IRQF_DISABLED) ? '+' : ' ',
-			action->name);
-		for (action = action->next; action; action = action->next) {
-			seq_printf(p, ",%s %s",
-				(action->flags & IRQF_DISABLED) ? " +" : "",
-				action->name);
-		}
-		seq_putc(p, '\n');
+		irq_table[i].real_irq = real_irq;
+		irq_table[i].irq = i;
+		irq_table[i].pil = pil;
+	} else {
+		printk(KERN_ERR "IRQ: Out of virtual IRQs.\n");
+		i = 0;
 	}
-out_unlock:
-	spin_unlock_irqrestore(&irq_action_lock, flags);
-	return 0;
+found:
+	spin_unlock_irqrestore(&irq_table_lock, flags);
+
+	return i;
 }
 
-void free_irq(unsigned int irq, void *dev_id)
+/* Based on a single pil handler_irq may need to call several
+ * interrupt handlers. Use irq_map as entry to irq_table,
+ * and let each entry in irq_table point to the next entry.
+ */
+void irq_link(unsigned int irq)
 {
-	struct irqaction *action;
-	struct irqaction **actionp;
+	struct irq_bucket *p;
 	unsigned long flags;
-	unsigned int cpu_irq;
-
-	if (sparc_cpu_model == sun4d) {
-		sun4d_free_irq(irq, dev_id);
-		return;
-	}
-	cpu_irq = irq & (NR_IRQS - 1);
-	if (cpu_irq > 14) {  /* 14 irq levels on the sparc */
-		printk(KERN_ERR "Trying to free bogus IRQ %d\n", irq);
-		return;
-	}
-
-	spin_lock_irqsave(&irq_action_lock, flags);
+	unsigned int pil;
 
-	actionp = &sparc_irq[cpu_irq].action;
-	action = *actionp;
+	BUG_ON(irq >= NR_IRQS);
 
-	if (!action->handler) {
-		printk(KERN_ERR "Trying to free free IRQ%d\n", irq);
-		goto out_unlock;
-	}
-	if (dev_id) {
-		for (; action; action = action->next) {
-			if (action->dev_id == dev_id)
-				break;
-			actionp = &action->next;
-		}
-		if (!action) {
-			printk(KERN_ERR "Trying to free free shared IRQ%d\n",
-			       irq);
-			goto out_unlock;
-		}
-	} else if (action->flags & IRQF_SHARED) {
-		printk(KERN_ERR "Trying to free shared IRQ%d with NULL device ID\n",
-		       irq);
-		goto out_unlock;
-	}
-	if (action->flags & SA_STATIC_ALLOC) {
-		/*
-		 * This interrupt is marked as specially allocated
-		 * so it is a bad idea to free it.
-		 */
-		printk(KERN_ERR "Attempt to free statically allocated IRQ%d (%s)\n",
-		       irq, action->name);
-		goto out_unlock;
-	}
+	spin_lock_irqsave(&irq_map_lock, flags);
 
-	*actionp = action->next;
+	p = &irq_table[irq];
+	pil = p->pil;
+	BUG_ON(pil > SUN4D_MAX_IRQ);
+	p->next = irq_map[pil];
+	irq_map[pil] = p;
 
-	spin_unlock_irqrestore(&irq_action_lock, flags);
+	spin_unlock_irqrestore(&irq_map_lock, flags);
+}
 
-	synchronize_irq(irq);
+void irq_unlink(unsigned int irq)
+{
+	struct irq_bucket *p, **pnext;
+	unsigned long flags;
 
-	spin_lock_irqsave(&irq_action_lock, flags);
+	BUG_ON(irq >= NR_IRQS);
 
-	kfree(action);
+	spin_lock_irqsave(&irq_map_lock, flags);
 
-	if (!sparc_irq[cpu_irq].action)
-		__disable_irq(irq);
+	p = &irq_table[irq];
+	BUG_ON(p->pil > SUN4D_MAX_IRQ);
+	pnext = &irq_map[p->pil];
+	while (*pnext != p)
+		pnext = &(*pnext)->next;
+	*pnext = p->next;
 
-out_unlock:
-	spin_unlock_irqrestore(&irq_action_lock, flags);
+	spin_unlock_irqrestore(&irq_map_lock, flags);
 }
-EXPORT_SYMBOL(free_irq);
-
-/*
- * This is called when we want to synchronize with
- * interrupts. We may for example tell a device to
- * stop sending interrupts: but to make sure there
- * are no interrupts that are executing on another
- * CPU we need to call this function.
- */
-#ifdef CONFIG_SMP
-void synchronize_irq(unsigned int irq)
-{
-	unsigned int cpu_irq;
 
-	cpu_irq = irq & (NR_IRQS - 1);
-	while (sparc_irq[cpu_irq].flags & SPARC_IRQ_INPROGRESS)
-		cpu_relax();
-}
-EXPORT_SYMBOL(synchronize_irq);
-#endif /* SMP */
 
-void unexpected_irq(int irq, void *dev_id, struct pt_regs *regs)
+/* /proc/interrupts printing */
+int arch_show_interrupts(struct seq_file *p, int prec)
 {
-	int i;
-	struct irqaction *action;
-	unsigned int cpu_irq;
-
-	cpu_irq = irq & (NR_IRQS - 1);
-	action = sparc_irq[cpu_irq].action;
+	int j;
 
-	printk(KERN_ERR "IO device interrupt, irq = %d\n", irq);
-	printk(KERN_ERR "PC = %08lx NPC = %08lx FP=%08lx\n", regs->pc,
-		    regs->npc, regs->u_regs[14]);
-	if (action) {
-		printk(KERN_ERR "Expecting: ");
-		for (i = 0; i < 16; i++)
-			if (action->handler)
-				printk(KERN_CONT "[%s:%d:0x%x] ", action->name,
-				       i, (unsigned int)action->handler);
-	}
-	printk(KERN_ERR "AIEEE\n");
-	panic("bogus interrupt received");
+#ifdef CONFIG_SMP
+	seq_printf(p, "RES: ");
+	for_each_online_cpu(j)
+		seq_printf(p, "%10u ", cpu_data(j).irq_resched_count);
+	seq_printf(p, "     IPI rescheduling interrupts\n");
+	seq_printf(p, "CAL: ");
+	for_each_online_cpu(j)
+		seq_printf(p, "%10u ", cpu_data(j).irq_call_count);
+	seq_printf(p, "     IPI function call interrupts\n");
+#endif
+	seq_printf(p, "NMI: ");
+	for_each_online_cpu(j)
+		seq_printf(p, "%10u ", cpu_data(j).counter);
+	seq_printf(p, "     Non-maskable interrupts\n");
+	return 0;
 }
 
-void handler_irq(int pil, struct pt_regs *regs)
+void handler_irq(unsigned int pil, struct pt_regs *regs)
 {
 	struct pt_regs *old_regs;
-	struct irqaction *action;
-	int cpu = smp_processor_id();
+	struct irq_bucket *p;
 
+	BUG_ON(pil > 15);
 	old_regs = set_irq_regs(regs);
 	irq_enter();
-	disable_pil_irq(pil);
-#ifdef CONFIG_SMP
-	/* Only rotate on lower priority IRQs (scsi, ethernet, etc.). */
-	if ((sparc_cpu_model==sun4m) && (pil < 10))
-		smp4m_irq_rotate(cpu);
-#endif
-	action = sparc_irq[pil].action;
-	sparc_irq[pil].flags |= SPARC_IRQ_INPROGRESS;
-	kstat_cpu(cpu).irqs[pil]++;
-	do {
-		if (!action || !action->handler)
-			unexpected_irq(pil, NULL, regs);
-		action->handler(pil, action->dev_id);
-		action = action->next;
-	} while (action);
-	sparc_irq[pil].flags &= ~SPARC_IRQ_INPROGRESS;
-	enable_pil_irq(pil);
+
+	p = irq_map[pil];
+	while (p) {
+		struct irq_bucket *next = p->next;
+
+		generic_handle_irq(p->irq);
+		p = next;
+	}
 	irq_exit();
 	set_irq_regs(old_regs);
 }
 
 #if defined(CONFIG_BLK_DEV_FD) || defined(CONFIG_BLK_DEV_FD_MODULE)
+static unsigned int floppy_irq;
 
-/*
- * Fast IRQs on the Sparc can only have one routine attached to them,
- * thus no sharing possible.
- */
-static int request_fast_irq(unsigned int irq,
-			    void (*handler)(void),
-			    unsigned long irqflags, const char *devname)
+int sparc_floppy_request_irq(unsigned int irq, irq_handler_t irq_handler)
 {
-	struct irqaction *action;
-	unsigned long flags;
 	unsigned int cpu_irq;
-	int ret;
+	int err;
+
 #if defined CONFIG_SMP && !defined CONFIG_SPARC_LEON
 	struct tt_entry *trap_table;
 #endif
-	cpu_irq = irq & (NR_IRQS - 1);
-	if (cpu_irq > 14) {
-		ret = -EINVAL;
-		goto out;
-	}
-	if (!handler) {
-		ret = -EINVAL;
-		goto out;
-	}
-
-	spin_lock_irqsave(&irq_action_lock, flags);
-
-	action = sparc_irq[cpu_irq].action;
-	if (action) {
-		if (action->flags & IRQF_SHARED)
-			panic("Trying to register fast irq when already shared.\n");
-		if (irqflags & IRQF_SHARED)
-			panic("Trying to register fast irq as shared.\n");
 
-		/* Anyway, someone already owns it so cannot be made fast. */
-		printk(KERN_ERR "request_fast_irq: Trying to register yet already owned.\n");
-		ret = -EBUSY;
-		goto out_unlock;
-	}
+	err = request_irq(irq, irq_handler, 0, "floppy", NULL);
+	if (err)
+		return -1;
 
-	/*
-	 * If this is flagged as statically allocated then we use our
-	 * private struct which is never freed.
-	 */
-	if (irqflags & SA_STATIC_ALLOC) {
-		if (static_irq_count < MAX_STATIC_ALLOC)
-			action = &static_irqaction[static_irq_count++];
-		else
-			printk(KERN_ERR "Fast IRQ%d (%s) SA_STATIC_ALLOC failed using kmalloc\n",
-			       irq, devname);
-	}
+	/* Save for later use in floppy interrupt handler */
+	floppy_irq = irq;
 
-	if (action == NULL)
-		action = kmalloc(sizeof(struct irqaction), GFP_ATOMIC);
-	if (!action) {
-		ret = -ENOMEM;
-		goto out_unlock;
-	}
+	cpu_irq = (irq & (NR_IRQS - 1));
 
 	/* Dork with trap table if we get this far. */
 #define INSTANTIATE(table) \
 	table[SP_TRAP_IRQ1+(cpu_irq-1)].inst_one = SPARC_RD_PSR_L0; \
 	table[SP_TRAP_IRQ1+(cpu_irq-1)].inst_two = \
-		SPARC_BRANCH((unsigned long) handler, \
+		SPARC_BRANCH((unsigned long) floppy_hardint, \
 			     (unsigned long) &table[SP_TRAP_IRQ1+(cpu_irq-1)].inst_two);\
 	table[SP_TRAP_IRQ1+(cpu_irq-1)].inst_three = SPARC_RD_WIM_L3; \
 	table[SP_TRAP_IRQ1+(cpu_irq-1)].inst_four = SPARC_NOP;
@@ -399,22 +289,9 @@
 	 * writing we have no CPU-neutral interface to fine-grained flushes.
 	 */
 	flush_cache_all();
-
-	action->flags = irqflags;
-	action->name = devname;
-	action->dev_id = NULL;
-	action->next = NULL;
-
-	sparc_irq[cpu_irq].action = action;
-
-	__enable_irq(irq);
-
-	ret = 0;
-out_unlock:
-	spin_unlock_irqrestore(&irq_action_lock, flags);
-out:
-	return ret;
+	return 0;
 }
+EXPORT_SYMBOL(sparc_floppy_request_irq);
 
 /*
  * These variables are used to access state from the assembler
@@ -440,154 +317,23 @@
 unsigned long pdma_areasize;
 EXPORT_SYMBOL(pdma_areasize);
 
-static irq_handler_t floppy_irq_handler;
-
+/* Use the generic irq support to call floppy_interrupt
+ * which was setup using request_irq() in sparc_floppy_request_irq().
+ * We only have one floppy interrupt so we do not need to check
+ * for additional handlers being wired up by irq_link()
+ */
 void sparc_floppy_irq(int irq, void *dev_id, struct pt_regs *regs)
 {
 	struct pt_regs *old_regs;
-	int cpu = smp_processor_id();
 
 	old_regs = set_irq_regs(regs);
-	disable_pil_irq(irq);
 	irq_enter();
-	kstat_cpu(cpu).irqs[irq]++;
-	floppy_irq_handler(irq, dev_id);
+	generic_handle_irq(floppy_irq);
 	irq_exit();
-	enable_pil_irq(irq);
 	set_irq_regs(old_regs);
-	/*
-	 * XXX Eek, it's totally changed with preempt_count() and such
-	 * if (softirq_pending(cpu))
-	 *	do_softirq();
-	 */
-}
-
-int sparc_floppy_request_irq(int irq, unsigned long flags,
-			     irq_handler_t irq_handler)
-{
-	floppy_irq_handler = irq_handler;
-	return request_fast_irq(irq, floppy_hardint, flags, "floppy");
 }
-EXPORT_SYMBOL(sparc_floppy_request_irq);
-
 #endif
 
-int request_irq(unsigned int irq,
-		irq_handler_t handler,
-		unsigned long irqflags, const char *devname, void *dev_id)
-{
-	struct irqaction *action, **actionp;
-	unsigned long flags;
-	unsigned int cpu_irq;
-	int ret;
-
-	if (sparc_cpu_model == sun4d)
-		return sun4d_request_irq(irq, handler, irqflags, devname, dev_id);
-
-	cpu_irq = irq & (NR_IRQS - 1);
-	if (cpu_irq > 14) {
-		ret = -EINVAL;
-		goto out;
-	}
-	if (!handler) {
-		ret = -EINVAL;
-		goto out;
-	}
-
-	spin_lock_irqsave(&irq_action_lock, flags);
-
-	actionp = &sparc_irq[cpu_irq].action;
-	action = *actionp;
-	if (action) {
-		if (!(action->flags & IRQF_SHARED) || !(irqflags & IRQF_SHARED)) {
-			ret = -EBUSY;
-			goto out_unlock;
-		}
-		if ((action->flags & IRQF_DISABLED) != (irqflags & IRQF_DISABLED)) {
-			printk(KERN_ERR "Attempt to mix fast and slow interrupts on IRQ%d denied\n",
-			       irq);
-			ret = -EBUSY;
-			goto out_unlock;
-		}
-		for ( ; action; action = *actionp)
-			actionp = &action->next;
-	}
-
-	/* If this is flagged as statically allocated then we use our
-	 * private struct which is never freed.
-	 */
-	if (irqflags & SA_STATIC_ALLOC) {
-		if (static_irq_count < MAX_STATIC_ALLOC)
-			action = &static_irqaction[static_irq_count++];
-		else
-			printk(KERN_ERR "Request for IRQ%d (%s) SA_STATIC_ALLOC failed using kmalloc\n",
-			       irq, devname);
-	}
-	if (action == NULL)
-		action = kmalloc(sizeof(struct irqaction), GFP_ATOMIC);
-	if (!action) {
-		ret = -ENOMEM;
-		goto out_unlock;
-	}
-
-	action->handler = handler;
-	action->flags = irqflags;
-	action->name = devname;
-	action->next = NULL;
-	action->dev_id = dev_id;
-
-	*actionp = action;
-
-	__enable_irq(irq);
-
-	ret = 0;
-out_unlock:
-	spin_unlock_irqrestore(&irq_action_lock, flags);
-out:
-	return ret;
-}
-EXPORT_SYMBOL(request_irq);
-
-void disable_irq_nosync(unsigned int irq)
-{
-	__disable_irq(irq);
-}
-EXPORT_SYMBOL(disable_irq_nosync);
-
-void disable_irq(unsigned int irq)
-{
-	__disable_irq(irq);
-}
-EXPORT_SYMBOL(disable_irq);
-
-void enable_irq(unsigned int irq)
-{
-	__enable_irq(irq);
-}
-EXPORT_SYMBOL(enable_irq);
-
-/*
- * We really don't need these at all on the Sparc.  We only have
- * stubs here because they are exported to modules.
- */
-unsigned long probe_irq_on(void)
-{
-	return 0;
-}
-EXPORT_SYMBOL(probe_irq_on);
-
-int probe_irq_off(unsigned long mask)
-{
-	return 0;
-}
-EXPORT_SYMBOL(probe_irq_off);
-
-static unsigned int build_device_irq(struct platform_device *op,
-                                     unsigned int real_irq)
-{
-	return real_irq;
-}
-
 /* djhr
  * This could probably be made indirect too and assigned in the CPU
  * bits of the code. That would be much nicer I think and would also
@@ -598,8 +344,6 @@
 
 void __init init_IRQ(void)
 {
-	sparc_irq_config.build_device_irq = build_device_irq;
-
 	switch (sparc_cpu_model) {
 	case sun4c:
 	case sun4:
@@ -607,14 +351,11 @@
 		break;
 
 	case sun4m:
-#ifdef CONFIG_PCI
 		pcic_probe();
-		if (pcic_present()) {
+		if (pcic_present())
 			sun4m_pci_init_IRQ();
-			break;
-		}
-#endif
-		sun4m_init_IRQ();
+		else
+			sun4m_init_IRQ();
 		break;
 
 	case sun4d:
@@ -632,9 +373,3 @@
 	btfixup();
 }
 
-#ifdef CONFIG_PROC_FS
-void init_irq_proc(void)
-{
-	/* For now, nothing... */
-}
-#endif /* CONFIG_PROC_FS */
diff -druN linux-2.6.39-libre/arch/sparc/kernel/irq_64.c linux-3.0-rc7-libre/arch/sparc/kernel/irq_64.c
--- linux-2.6.39-libre/arch/sparc/kernel/irq_64.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/sparc/kernel/irq_64.c	2011-07-11 19:51:52.000000000 -0400
@@ -224,13 +224,13 @@
 	int cpuid;
 
 	cpumask_copy(&mask, affinity);
-	if (cpus_equal(mask, cpu_online_map)) {
+	if (cpumask_equal(&mask, cpu_online_mask)) {
 		cpuid = map_to_cpu(irq);
 	} else {
 		cpumask_t tmp;
 
-		cpus_and(tmp, cpu_online_map, mask);
-		cpuid = cpus_empty(tmp) ? map_to_cpu(irq) : first_cpu(tmp);
+		cpumask_and(&tmp, cpu_online_mask, &mask);
+		cpuid = cpumask_empty(&tmp) ? map_to_cpu(irq) : cpumask_first(&tmp);
 	}
 
 	return cpuid;
diff -druN linux-2.6.39-libre/arch/sparc/kernel/irq.h linux-3.0-rc7-libre/arch/sparc/kernel/irq.h
--- linux-2.6.39-libre/arch/sparc/kernel/irq.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/sparc/kernel/irq.h	2011-07-11 19:51:52.000000000 -0400
@@ -2,6 +2,23 @@
 
 #include <asm/btfixup.h>
 
+struct irq_bucket {
+        struct irq_bucket *next;
+        unsigned int real_irq;
+        unsigned int irq;
+        unsigned int pil;
+};
+
+#define SUN4D_MAX_BOARD 10
+#define SUN4D_MAX_IRQ ((SUN4D_MAX_BOARD + 2) << 5)
+
+/* Map between the irq identifier used in hw to the
+ * irq_bucket. The map is sufficient large to hold
+ * the sun4d hw identifiers.
+ */
+extern struct irq_bucket *irq_map[SUN4D_MAX_IRQ];
+
+
 /* sun4m specific type definitions */
 
 /* This maps direct to CPU specific interrupt registers */
@@ -35,6 +52,10 @@
 };
 extern struct sparc_irq_config sparc_irq_config;
 
+unsigned int irq_alloc(unsigned int real_irq, unsigned int pil);
+void irq_link(unsigned int irq);
+void irq_unlink(unsigned int irq);
+void handler_irq(unsigned int pil, struct pt_regs *regs);
 
 /* Dave Redman (djhr@tadpole.co.uk)
  * changed these to function pointers.. it saves cycles and will allow
@@ -44,33 +65,9 @@
  * Changed these to btfixup entities... It saves cycles :)
  */
 
-BTFIXUPDEF_CALL(void, disable_irq, unsigned int)
-BTFIXUPDEF_CALL(void, enable_irq, unsigned int)
-BTFIXUPDEF_CALL(void, disable_pil_irq, unsigned int)
-BTFIXUPDEF_CALL(void, enable_pil_irq, unsigned int)
 BTFIXUPDEF_CALL(void, clear_clock_irq, void)
 BTFIXUPDEF_CALL(void, load_profile_irq, int, unsigned int)
 
-static inline void __disable_irq(unsigned int irq)
-{
-	BTFIXUP_CALL(disable_irq)(irq);
-}
-
-static inline void __enable_irq(unsigned int irq)
-{
-	BTFIXUP_CALL(enable_irq)(irq);
-}
-
-static inline void disable_pil_irq(unsigned int irq)
-{
-	BTFIXUP_CALL(disable_pil_irq)(irq);
-}
-
-static inline void enable_pil_irq(unsigned int irq)
-{
-	BTFIXUP_CALL(enable_pil_irq)(irq);
-}
-
 static inline void clear_clock_irq(void)
 {
 	BTFIXUP_CALL(clear_clock_irq)();
@@ -89,4 +86,10 @@
 #define set_cpu_int(cpu,level) BTFIXUP_CALL(set_cpu_int)(cpu,level)
 #define clear_cpu_int(cpu,level) BTFIXUP_CALL(clear_cpu_int)(cpu,level)
 #define set_irq_udt(cpu) BTFIXUP_CALL(set_irq_udt)(cpu)
+
+/* All SUN4D IPIs are sent on this IRQ, may be shared with hard IRQs */
+#define SUN4D_IPI_IRQ 14
+
+extern void sun4d_ipi_interrupt(void);
+
 #endif
diff -druN linux-2.6.39-libre/arch/sparc/kernel/kernel.h linux-3.0-rc7-libre/arch/sparc/kernel/kernel.h
--- linux-2.6.39-libre/arch/sparc/kernel/kernel.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/sparc/kernel/kernel.h	2011-07-11 19:51:52.000000000 -0400
@@ -6,11 +6,9 @@
 #include <asm/traps.h>
 
 /* cpu.c */
-extern const char *sparc_cpu_type;
 extern const char *sparc_pmu_type;
-extern const char *sparc_fpu_type;
-
 extern unsigned int fsr_storage;
+extern int ncpus_probed;
 
 #ifdef CONFIG_SPARC32
 /* cpu.c */
@@ -37,6 +35,7 @@
 extern unsigned int lvl14_resolution;
 
 extern void sun4m_init_IRQ(void);
+extern void sun4m_unmask_profile_irq(void);
 extern void sun4m_clear_profile_irq(int cpu);
 
 /* sun4d_irq.c */
diff -druN linux-2.6.39-libre/arch/sparc/kernel/leon_kernel.c linux-3.0-rc7-libre/arch/sparc/kernel/leon_kernel.c
--- linux-2.6.39-libre/arch/sparc/kernel/leon_kernel.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/sparc/kernel/leon_kernel.c	2011-07-11 19:51:52.000000000 -0400
@@ -19,53 +19,70 @@
 #include <asm/leon_amba.h>
 #include <asm/traps.h>
 #include <asm/cacheflush.h>
+#include <asm/smp.h>
+#include <asm/setup.h>
 
 #include "prom.h"
 #include "irq.h"
 
 struct leon3_irqctrl_regs_map *leon3_irqctrl_regs; /* interrupt controller base address */
 struct leon3_gptimer_regs_map *leon3_gptimer_regs; /* timer controller base address */
-struct amba_apb_device leon_percpu_timer_dev[16];
 
 int leondebug_irq_disable;
 int leon_debug_irqout;
 static int dummy_master_l10_counter;
 unsigned long amba_system_id;
+static DEFINE_SPINLOCK(leon_irq_lock);
 
 unsigned long leon3_gptimer_irq; /* interrupt controller irq number */
 unsigned long leon3_gptimer_idx; /* Timer Index (0..6) within Timer Core */
+int leon3_ticker_irq; /* Timer ticker IRQ */
 unsigned int sparc_leon_eirq;
-#define LEON_IMASK ((&leon3_irqctrl_regs->mask[0]))
+#define LEON_IMASK(cpu) (&leon3_irqctrl_regs->mask[cpu])
+#define LEON_IACK (&leon3_irqctrl_regs->iclear)
+#define LEON_DO_ACK_HW 1
 
-/* Return the IRQ of the pending IRQ on the extended IRQ controller */
-int sparc_leon_eirq_get(int eirq, int cpu)
+/* Return the last ACKed IRQ by the Extended IRQ controller. It has already
+ * been (automatically) ACKed when the CPU takes the trap.
+ */
+static inline unsigned int leon_eirq_get(int cpu)
 {
 	return LEON3_BYPASS_LOAD_PA(&leon3_irqctrl_regs->intid[cpu]) & 0x1f;
 }
 
-irqreturn_t sparc_leon_eirq_isr(int dummy, void *dev_id)
+/* Handle one or multiple IRQs from the extended interrupt controller */
+static void leon_handle_ext_irq(unsigned int irq, struct irq_desc *desc)
 {
-	printk(KERN_ERR "sparc_leon_eirq_isr: ERROR EXTENDED IRQ\n");
-	return IRQ_HANDLED;
+	unsigned int eirq;
+	int cpu = sparc_leon3_cpuid();
+
+	eirq = leon_eirq_get(cpu);
+	if ((eirq & 0x10) && irq_map[eirq]->irq) /* bit4 tells if IRQ happened */
+		generic_handle_irq(irq_map[eirq]->irq);
 }
 
 /* The extended IRQ controller has been found, this function registers it */
-void sparc_leon_eirq_register(int eirq)
+void leon_eirq_setup(unsigned int eirq)
 {
-	int irq;
-
-	/* Register a "BAD" handler for this interrupt, it should never happen */
-	irq = request_irq(eirq, sparc_leon_eirq_isr,
-			  (IRQF_DISABLED | SA_STATIC_ALLOC), "extirq", NULL);
+	unsigned long mask, oldmask;
+	unsigned int veirq;
 
-	if (irq) {
-		printk(KERN_ERR
-		       "sparc_leon_eirq_register: unable to attach IRQ%d\n",
-		       eirq);
-	} else {
-		sparc_leon_eirq = eirq;
+	if (eirq < 1 || eirq > 0xf) {
+		printk(KERN_ERR "LEON EXT IRQ NUMBER BAD: %d\n", eirq);
+		return;
 	}
 
+	veirq = leon_build_device_irq(eirq, leon_handle_ext_irq, "extirq", 0);
+
+	/*
+	 * Unmask the Extended IRQ, the IRQs routed through the Ext-IRQ
+	 * controller have a mask-bit of their own, so this is safe.
+	 */
+	irq_link(veirq);
+	mask = 1 << eirq;
+	oldmask = LEON3_BYPASS_LOAD_PA(LEON_IMASK(boot_cpu_id));
+	LEON3_BYPASS_STORE_PA(LEON_IMASK(boot_cpu_id), (oldmask | mask));
+	sparc_leon_eirq = eirq;
 }
 
 static inline unsigned long get_irqmask(unsigned int irq)
@@ -83,35 +100,166 @@
 	return mask;
 }
 
-static void leon_enable_irq(unsigned int irq_nr)
+#ifdef CONFIG_SMP
+static int irq_choose_cpu(const struct cpumask *affinity)
 {
-	unsigned long mask, flags;
-	mask = get_irqmask(irq_nr);
-	local_irq_save(flags);
-	LEON3_BYPASS_STORE_PA(LEON_IMASK,
-			      (LEON3_BYPASS_LOAD_PA(LEON_IMASK) | (mask)));
-	local_irq_restore(flags);
+	cpumask_t mask;
+
+	cpus_and(mask, cpu_online_map, *affinity);
+	if (cpus_equal(mask, cpu_online_map) || cpus_empty(mask))
+		return boot_cpu_id;
+	else
+		return first_cpu(mask);
 }
+#else
+#define irq_choose_cpu(affinity) boot_cpu_id
+#endif
 
-static void leon_disable_irq(unsigned int irq_nr)
+static int leon_set_affinity(struct irq_data *data, const struct cpumask *dest,
+			     bool force)
 {
-	unsigned long mask, flags;
-	mask = get_irqmask(irq_nr);
-	local_irq_save(flags);
-	LEON3_BYPASS_STORE_PA(LEON_IMASK,
-			      (LEON3_BYPASS_LOAD_PA(LEON_IMASK) & ~(mask)));
-	local_irq_restore(flags);
+	unsigned long mask, oldmask, flags;
+	int oldcpu, newcpu;
+
+	mask = (unsigned long)data->chip_data;
+	oldcpu = irq_choose_cpu(data->affinity);
+	newcpu = irq_choose_cpu(dest);
+
+	if (oldcpu == newcpu)
+		goto out;
+
+	/* unmask on old CPU first before enabling on the selected CPU */
+	spin_lock_irqsave(&leon_irq_lock, flags);
+	oldmask = LEON3_BYPASS_LOAD_PA(LEON_IMASK(oldcpu));
+	LEON3_BYPASS_STORE_PA(LEON_IMASK(oldcpu), (oldmask & ~mask));
+	oldmask = LEON3_BYPASS_LOAD_PA(LEON_IMASK(newcpu));
+	LEON3_BYPASS_STORE_PA(LEON_IMASK(newcpu), (oldmask | mask));
+	spin_unlock_irqrestore(&leon_irq_lock, flags);
+out:
+	return IRQ_SET_MASK_OK;
+}
+
+static void leon_unmask_irq(struct irq_data *data)
+{
+	unsigned long mask, oldmask, flags;
+	int cpu;
+
+	mask = (unsigned long)data->chip_data;
+	cpu = irq_choose_cpu(data->affinity);
+	spin_lock_irqsave(&leon_irq_lock, flags);
+	oldmask = LEON3_BYPASS_LOAD_PA(LEON_IMASK(cpu));
+	LEON3_BYPASS_STORE_PA(LEON_IMASK(cpu), (oldmask | mask));
+	spin_unlock_irqrestore(&leon_irq_lock, flags);
+}
+
+static void leon_mask_irq(struct irq_data *data)
+{
+	unsigned long mask, oldmask, flags;
+	int cpu;
+
+	mask = (unsigned long)data->chip_data;
+	cpu = irq_choose_cpu(data->affinity);
+	spin_lock_irqsave(&leon_irq_lock, flags);
+	oldmask = LEON3_BYPASS_LOAD_PA(LEON_IMASK(cpu));
+	LEON3_BYPASS_STORE_PA(LEON_IMASK(cpu), (oldmask & ~mask));
+	spin_unlock_irqrestore(&leon_irq_lock, flags);
+}
+
+static unsigned int leon_startup_irq(struct irq_data *data)
+{
+	irq_link(data->irq);
+	leon_unmask_irq(data);
+	return 0;
+}
+
+static void leon_shutdown_irq(struct irq_data *data)
+{
+	leon_mask_irq(data);
+	irq_unlink(data->irq);
+}
+
+/* Used by external level sensitive IRQ handlers on the LEON: ACK IRQ ctrl */
+static void leon_eoi_irq(struct irq_data *data)
+{
+	unsigned long mask = (unsigned long)data->chip_data;
+
+	if (mask & LEON_DO_ACK_HW)
+		LEON3_BYPASS_STORE_PA(LEON_IACK, mask & ~LEON_DO_ACK_HW);
+}
+
+static struct irq_chip leon_irq = {
+	.name			= "leon",
+	.irq_startup		= leon_startup_irq,
+	.irq_shutdown		= leon_shutdown_irq,
+	.irq_mask		= leon_mask_irq,
+	.irq_unmask		= leon_unmask_irq,
+	.irq_eoi		= leon_eoi_irq,
+	.irq_set_affinity	= leon_set_affinity,
+};
+
+/*
+ * Build a LEON IRQ for the edge triggered LEON IRQ controller:
+ *  Edge (normal) IRQ           - handle_simple_irq, ack=DONT-CARE, never ack
+ *  Level IRQ (PCI|Level-GPIO)  - handle_fasteoi_irq, ack=1, ack after ISR
+ *  Per-CPU Edge                - handle_percpu_irq, ack=0
+ */
+unsigned int leon_build_device_irq(unsigned int real_irq,
+				    irq_flow_handler_t flow_handler,
+				    const char *name, int do_ack)
+{
+	unsigned int irq;
+	unsigned long mask;
+
+	irq = 0;
+	mask = get_irqmask(real_irq);
+	if (mask == 0)
+		goto out;
+
+	irq = irq_alloc(real_irq, real_irq);
+	if (irq == 0)
+		goto out;
+
+	if (do_ack)
+		mask |= LEON_DO_ACK_HW;
+
+	irq_set_chip_and_handler_name(irq, &leon_irq,
+				      flow_handler, name);
+	irq_set_chip_data(irq, (void *)mask);
+
+out:
+	return irq;
+}
 
+static unsigned int _leon_build_device_irq(struct platform_device *op,
+					   unsigned int real_irq)
+{
+	return leon_build_device_irq(real_irq, handle_simple_irq, "edge", 0);
+}
+
+void leon_update_virq_handling(unsigned int virq,
+			      irq_flow_handler_t flow_handler,
+			      const char *name, int do_ack)
+{
+	unsigned long mask = (unsigned long)irq_get_chip_data(virq);
+
+	mask &= ~LEON_DO_ACK_HW;
+	if (do_ack)
+		mask |= LEON_DO_ACK_HW;
+
+	irq_set_chip_and_handler_name(virq, &leon_irq,
+				      flow_handler, name);
+	irq_set_chip_data(virq, (void *)mask);
 }
 
 void __init leon_init_timers(irq_handler_t counter_fn)
 {
-	int irq;
+	int irq, eirq;
 	struct device_node *rootnp, *np, *nnp;
 	struct property *pp;
 	int len;
-	int cpu, icsel;
+	int icsel;
 	int ampopts;
+	int err;
 
 	leondebug_irq_disable = 0;
 	leon_debug_irqout = 0;
@@ -173,98 +321,101 @@
 			leon3_gptimer_irq = *(unsigned int *)pp->value;
 	} while (0);
 
-	if (leon3_gptimer_regs && leon3_irqctrl_regs && leon3_gptimer_irq) {
-		LEON3_BYPASS_STORE_PA(
-			&leon3_gptimer_regs->e[leon3_gptimer_idx].val, 0);
-		LEON3_BYPASS_STORE_PA(
-			&leon3_gptimer_regs->e[leon3_gptimer_idx].rld,
-			(((1000000 / HZ) - 1)));
-		LEON3_BYPASS_STORE_PA(
+	if (!(leon3_gptimer_regs && leon3_irqctrl_regs && leon3_gptimer_irq))
+		goto bad;
+
+	LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[leon3_gptimer_idx].val, 0);
+	LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[leon3_gptimer_idx].rld,
+				(((1000000 / HZ) - 1)));
+	LEON3_BYPASS_STORE_PA(
 			&leon3_gptimer_regs->e[leon3_gptimer_idx].ctrl, 0);
 
 #ifdef CONFIG_SMP
-		leon_percpu_timer_dev[0].start = (int)leon3_gptimer_regs;
-		leon_percpu_timer_dev[0].irq = leon3_gptimer_irq + 1 +
-					       leon3_gptimer_idx;
+	leon3_ticker_irq = leon3_gptimer_irq + 1 + leon3_gptimer_idx;
 
-		if (!(LEON3_BYPASS_LOAD_PA(&leon3_gptimer_regs->config) &
-		      (1<<LEON3_GPTIMER_SEPIRQ))) {
-			prom_printf("irq timer not configured with separate irqs\n");
-			BUG();
-		}
+	if (!(LEON3_BYPASS_LOAD_PA(&leon3_gptimer_regs->config) &
+	      (1<<LEON3_GPTIMER_SEPIRQ))) {
+		printk(KERN_ERR "timer not configured with separate irqs\n");
+		BUG();
+	}
 
-		LEON3_BYPASS_STORE_PA(
-			&leon3_gptimer_regs->e[leon3_gptimer_idx+1].val, 0);
-		LEON3_BYPASS_STORE_PA(
-			&leon3_gptimer_regs->e[leon3_gptimer_idx+1].rld,
-			(((1000000/HZ) - 1)));
-		LEON3_BYPASS_STORE_PA(
-			&leon3_gptimer_regs->e[leon3_gptimer_idx+1].ctrl, 0);
-# endif
+	LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[leon3_gptimer_idx+1].val,
+				0);
+	LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[leon3_gptimer_idx+1].rld,
+				(((1000000/HZ) - 1)));
+	LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[leon3_gptimer_idx+1].ctrl,
+				0);
+#endif
 
-		/*
-		 * The IRQ controller may (if implemented) consist of multiple
-		 * IRQ controllers, each mapped on a 4Kb boundary.
-		 * Each CPU may be routed to different IRQCTRLs, however
-		 * we assume that all CPUs (in SMP system) is routed to the
-		 * same IRQ Controller, and for non-SMP only one IRQCTRL is
-		 * accessed anyway.
-		 * In AMP systems, Linux must run on CPU0 for the time being.
-		 */
-		cpu = sparc_leon3_cpuid();
-		icsel = LEON3_BYPASS_LOAD_PA(&leon3_irqctrl_regs->icsel[cpu/8]);
-		icsel = (icsel >> ((7 - (cpu&0x7)) * 4)) & 0xf;
-		leon3_irqctrl_regs += icsel;
-	} else {
-		goto bad;
-	}
+	/*
+	 * The IRQ controller may (if implemented) consist of multiple
+	 * IRQ controllers, each mapped on a 4Kb boundary.
+	 * Each CPU may be routed to different IRQCTRLs, however
+	 * we assume that all CPUs (in SMP system) is routed to the
+	 * same IRQ Controller, and for non-SMP only one IRQCTRL is
+	 * accessed anyway.
+	 * In AMP systems, Linux must run on CPU0 for the time being.
+	 */
+	icsel = LEON3_BYPASS_LOAD_PA(&leon3_irqctrl_regs->icsel[boot_cpu_id/8]);
+	icsel = (icsel >> ((7 - (boot_cpu_id&0x7)) * 4)) & 0xf;
+	leon3_irqctrl_regs += icsel;
 
-	irq = request_irq(leon3_gptimer_irq+leon3_gptimer_idx,
-			  counter_fn,
-			  (IRQF_DISABLED | SA_STATIC_ALLOC), "timer", NULL);
+	/* Mask all IRQs on boot-cpu IRQ controller */
+	LEON3_BYPASS_STORE_PA(&leon3_irqctrl_regs->mask[boot_cpu_id], 0);
 
-	if (irq) {
-		printk(KERN_ERR "leon_time_init: unable to attach IRQ%d\n",
-		       LEON_INTERRUPT_TIMER1);
+	/* Probe extended IRQ controller */
+	eirq = (LEON3_BYPASS_LOAD_PA(&leon3_irqctrl_regs->mpstatus)
+		>> 16) & 0xf;
+	if (eirq != 0)
+		leon_eirq_setup(eirq);
+
+	irq = _leon_build_device_irq(NULL, leon3_gptimer_irq+leon3_gptimer_idx);
+	err = request_irq(irq, counter_fn, IRQF_TIMER, "timer", NULL);
+	if (err) {
+		printk(KERN_ERR "unable to attach timer IRQ%d\n", irq);
 		prom_halt();
 	}
 
-# ifdef CONFIG_SMP
+#ifdef CONFIG_SMP
 	{
 		unsigned long flags;
-		struct tt_entry *trap_table = &sparc_ttable[SP_TRAP_IRQ1 + (leon_percpu_timer_dev[0].irq - 1)];
 
-		/* For SMP we use the level 14 ticker, however the bootup code
-		 * has copied the firmwares level 14 vector into boot cpu's
-		 * trap table, we must fix this now or we get squashed.
+		/*
+		 * In SMP, sun4m adds a IPI handler to IRQ trap handler that
+		 * LEON never must take, sun4d and LEON overwrites the branch
+		 * with a NOP.
 		 */
 		local_irq_save(flags);
-
 		patchme_maybe_smp_msg[0] = 0x01000000; /* NOP out the branch */
-
-		/* Adjust so that we jump directly to smpleon_ticker */
-		trap_table->inst_three += smpleon_ticker - real_irq_entry;
-
 		local_flush_cache_all();
 		local_irq_restore(flags);
 	}
-# endif
+#endif
 
-	if (leon3_gptimer_regs) {
-		LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[leon3_gptimer_idx].ctrl,
-				      LEON3_GPTIMER_EN |
-				      LEON3_GPTIMER_RL |
-				      LEON3_GPTIMER_LD | LEON3_GPTIMER_IRQEN);
+	LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[leon3_gptimer_idx].ctrl,
+			      LEON3_GPTIMER_EN |
+			      LEON3_GPTIMER_RL |
+			      LEON3_GPTIMER_LD |
+			      LEON3_GPTIMER_IRQEN);
 
 #ifdef CONFIG_SMP
-		LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[leon3_gptimer_idx+1].ctrl,
-				      LEON3_GPTIMER_EN |
-				      LEON3_GPTIMER_RL |
-				      LEON3_GPTIMER_LD |
-				      LEON3_GPTIMER_IRQEN);
-#endif
-
+	/* Install per-cpu IRQ handler for broadcasted ticker */
+	irq = leon_build_device_irq(leon3_ticker_irq, handle_percpu_irq,
+				    "per-cpu", 0);
+	err = request_irq(irq, leon_percpu_timer_interrupt,
+			  IRQF_PERCPU | IRQF_TIMER, "ticker",
+			  NULL);
+	if (err) {
+		printk(KERN_ERR "unable to attach ticker IRQ%d\n", irq);
+		prom_halt();
 	}
+
+	LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[leon3_gptimer_idx+1].ctrl,
+			      LEON3_GPTIMER_EN |
+			      LEON3_GPTIMER_RL |
+			      LEON3_GPTIMER_LD |
+			      LEON3_GPTIMER_IRQEN);
+#endif
 	return;
 bad:
 	printk(KERN_ERR "No Timer/irqctrl found\n");
@@ -281,9 +432,6 @@
 	BUG();
 }
 
-
-
-
 void __init leon_trans_init(struct device_node *dp)
 {
 	if (strcmp(dp->type, "cpu") == 0 && strcmp(dp->name, "<NULL>") == 0) {
@@ -337,22 +485,18 @@
 {
 	unsigned long mask, flags, *addr;
 	mask = get_irqmask(irq_nr);
-	local_irq_save(flags);
-	addr = (unsigned long *)&(leon3_irqctrl_regs->mask[cpu]);
-	LEON3_BYPASS_STORE_PA(addr, (LEON3_BYPASS_LOAD_PA(addr) | (mask)));
-	local_irq_restore(flags);
+	spin_lock_irqsave(&leon_irq_lock, flags);
+	addr = (unsigned long *)LEON_IMASK(cpu);
+	LEON3_BYPASS_STORE_PA(addr, (LEON3_BYPASS_LOAD_PA(addr) | mask));
+	spin_unlock_irqrestore(&leon_irq_lock, flags);
 }
 
 #endif
 
 void __init leon_init_IRQ(void)
 {
-	sparc_irq_config.init_timers = leon_init_timers;
-
-	BTFIXUPSET_CALL(enable_irq, leon_enable_irq, BTFIXUPCALL_NORM);
-	BTFIXUPSET_CALL(disable_irq, leon_disable_irq, BTFIXUPCALL_NORM);
-	BTFIXUPSET_CALL(enable_pil_irq, leon_enable_irq, BTFIXUPCALL_NORM);
-	BTFIXUPSET_CALL(disable_pil_irq, leon_disable_irq, BTFIXUPCALL_NORM);
+	sparc_irq_config.init_timers      = leon_init_timers;
+	sparc_irq_config.build_device_irq = _leon_build_device_irq;
 
 	BTFIXUPSET_CALL(clear_clock_irq, leon_clear_clock_irq,
 			BTFIXUPCALL_NORM);
diff -druN linux-2.6.39-libre/arch/sparc/kernel/leon_pci.c linux-3.0-rc7-libre/arch/sparc/kernel/leon_pci.c
--- linux-2.6.39-libre/arch/sparc/kernel/leon_pci.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/sparc/kernel/leon_pci.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,253 @@
+/*
+ * leon_pci.c: LEON Host PCI support
+ *
+ * Copyright (C) 2011 Aeroflex Gaisler AB, Daniel Hellstrom
+ *
+ * Code is partially derived from pcic.c
+ */
+
+#include <linux/of_device.h>
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <asm/leon.h>
+#include <asm/leon_pci.h>
+
+/* The LEON architecture does not rely on a BIOS or bootloader to setup
+ * PCI for us. The Linux generic routines are used to setup resources,
+ * reset values of confuration-space registers settings ae preseved.
+ */
+void leon_pci_init(struct platform_device *ofdev, struct leon_pci_info *info)
+{
+	struct pci_bus *root_bus;
+
+	root_bus = pci_scan_bus_parented(&ofdev->dev, 0, info->ops, info);
+	if (root_bus) {
+		root_bus->resource[0] = &info->io_space;
+		root_bus->resource[1] = &info->mem_space;
+		root_bus->resource[2] = NULL;
+
+		/* Init all PCI devices into PCI tree */
+		pci_bus_add_devices(root_bus);
+
+		/* Setup IRQs of all devices using custom routines */
+		pci_fixup_irqs(pci_common_swizzle, info->map_irq);
+
+		/* Assign devices with resources */
+		pci_assign_unassigned_resources();
+	}
+}
+
+/* PCI Memory and Prefetchable Memory is direct-mapped. However I/O Space is
+ * accessed through a Window which is translated to low 64KB in PCI space, the
+ * first 4KB is not used so 60KB is available.
+ *
+ * This function is used by generic code to translate resource addresses into
+ * PCI addresses.
+ */
+void pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region,
+			     struct resource *res)
+{
+	struct leon_pci_info *info = dev->bus->sysdata;
+
+	region->start = res->start;
+	region->end = res->end;
+
+	if (res->flags & IORESOURCE_IO) {
+		region->start -= (info->io_space.start - 0x1000);
+		region->end -= (info->io_space.start - 0x1000);
+	}
+}
+EXPORT_SYMBOL(pcibios_resource_to_bus);
+
+/* see pcibios_resource_to_bus() comment */
+void pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res,
+			     struct pci_bus_region *region)
+{
+	struct leon_pci_info *info = dev->bus->sysdata;
+
+	res->start = region->start;
+	res->end = region->end;
+
+	if (res->flags & IORESOURCE_IO) {
+		res->start += (info->io_space.start - 0x1000);
+		res->end += (info->io_space.start - 0x1000);
+	}
+}
+EXPORT_SYMBOL(pcibios_bus_to_resource);
+
+void __devinit pcibios_fixup_bus(struct pci_bus *pbus)
+{
+	struct leon_pci_info *info = pbus->sysdata;
+	struct pci_dev *dev;
+	int i, has_io, has_mem;
+	u16 cmd;
+
+	/* Generic PCI bus probing sets these to point at
+	 * &io{port,mem}_resouce which is wrong for us.
+	 */
+	if (pbus->self == NULL) {
+		pbus->resource[0] = &info->io_space;
+		pbus->resource[1] = &info->mem_space;
+		pbus->resource[2] = NULL;
+	}
+
+	list_for_each_entry(dev, &pbus->devices, bus_list) {
+		/*
+		 * We can not rely on that the bootloader has enabled I/O
+		 * or memory access to PCI devices. Instead we enable it here
+		 * if the device has BARs of respective type.
+		 */
+		has_io = has_mem = 0;
+		for (i = 0; i < PCI_ROM_RESOURCE; i++) {
+			unsigned long f = dev->resource[i].flags;
+			if (f & IORESOURCE_IO)
+				has_io = 1;
+			else if (f & IORESOURCE_MEM)
+				has_mem = 1;
+		}
+		/* ROM BARs are mapped into 32-bit memory space */
+		if (dev->resource[PCI_ROM_RESOURCE].end != 0) {
+			dev->resource[PCI_ROM_RESOURCE].flags |=
+							IORESOURCE_ROM_ENABLE;
+			has_mem = 1;
+		}
+		pci_bus_read_config_word(pbus, dev->devfn, PCI_COMMAND, &cmd);
+		if (has_io && !(cmd & PCI_COMMAND_IO)) {
+#ifdef CONFIG_PCI_DEBUG
+			printk(KERN_INFO "LEONPCI: Enabling I/O for dev %s\n",
+					 pci_name(dev));
+#endif
+			cmd |= PCI_COMMAND_IO;
+			pci_bus_write_config_word(pbus, dev->devfn, PCI_COMMAND,
+									cmd);
+		}
+		if (has_mem && !(cmd & PCI_COMMAND_MEMORY)) {
+#ifdef CONFIG_PCI_DEBUG
+			printk(KERN_INFO "LEONPCI: Enabling MEMORY for dev"
+					 "%s\n", pci_name(dev));
+#endif
+			cmd |= PCI_COMMAND_MEMORY;
+			pci_bus_write_config_word(pbus, dev->devfn, PCI_COMMAND,
+									cmd);
+		}
+	}
+}
+
+/*
+ * Other archs parse arguments here.
+ */
+char * __devinit pcibios_setup(char *str)
+{
+	return str;
+}
+
+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)
+{
+	return pci_enable_resources(dev, mask);
+}
+
+struct device_node *pci_device_to_OF_node(struct pci_dev *pdev)
+{
+	/*
+	 * Currently the OpenBoot nodes are not connected with the PCI device,
+	 * this is because the LEON PROM does not create PCI nodes. Eventually
+	 * this will change and the same approach as pcic.c can be used to
+	 * match PROM nodes with pci devices.
+	 */
+	return NULL;
+}
+EXPORT_SYMBOL(pci_device_to_OF_node);
+
+void __devinit pcibios_update_irq(struct pci_dev *dev, int irq)
+{
+#ifdef CONFIG_PCI_DEBUG
+	printk(KERN_DEBUG "LEONPCI: Assigning IRQ %02d to %s\n", irq,
+		pci_name(dev));
+#endif
+	pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq);
+}
+
+/* in/out routines taken from pcic.c
+ *
+ * This probably belongs here rather than ioport.c because
+ * we do not want this crud linked into SBus kernels.
+ * Also, think for a moment about likes of floppy.c that
+ * include architecture specific parts. They may want to redefine ins/outs.
+ *
+ * We do not use horrible macros here because we want to
+ * advance pointer by sizeof(size).
+ */
+void outsb(unsigned long addr, const void *src, unsigned long count)
+{
+	while (count) {
+		count -= 1;
+		outb(*(const char *)src, addr);
+		src += 1;
+		/* addr += 1; */
+	}
+}
+EXPORT_SYMBOL(outsb);
+
+void outsw(unsigned long addr, const void *src, unsigned long count)
+{
+	while (count) {
+		count -= 2;
+		outw(*(const short *)src, addr);
+		src += 2;
+		/* addr += 2; */
+	}
+}
+EXPORT_SYMBOL(outsw);
+
+void outsl(unsigned long addr, const void *src, unsigned long count)
+{
+	while (count) {
+		count -= 4;
+		outl(*(const long *)src, addr);
+		src += 4;
+		/* addr += 4; */
+	}
+}
+EXPORT_SYMBOL(outsl);
+
+void insb(unsigned long addr, void *dst, unsigned long count)
+{
+	while (count) {
+		count -= 1;
+		*(unsigned char *)dst = inb(addr);
+		dst += 1;
+		/* addr += 1; */
+	}
+}
+EXPORT_SYMBOL(insb);
+
+void insw(unsigned long addr, void *dst, unsigned long count)
+{
+	while (count) {
+		count -= 2;
+		*(unsigned short *)dst = inw(addr);
+		dst += 2;
+		/* addr += 2; */
+	}
+}
+EXPORT_SYMBOL(insw);
+
+void insl(unsigned long addr, void *dst, unsigned long count)
+{
+	while (count) {
+		count -= 4;
+		/*
+		 * XXX I am sure we are in for an unaligned trap here.
+		 */
+		*(unsigned long *)dst = inl(addr);
+		dst += 4;
+		/* addr += 4; */
+	}
+}
+EXPORT_SYMBOL(insl);
diff -druN linux-2.6.39-libre/arch/sparc/kernel/leon_pci_grpci2.c linux-3.0-rc7-libre/arch/sparc/kernel/leon_pci_grpci2.c
--- linux-2.6.39-libre/arch/sparc/kernel/leon_pci_grpci2.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/sparc/kernel/leon_pci_grpci2.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,897 @@
+/*
+ * leon_pci_grpci2.c: GRPCI2 Host PCI driver
+ *
+ * Copyright (C) 2011 Aeroflex Gaisler AB, Daniel Hellstrom
+ *
+ */
+
+#include <linux/of_device.h>
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/delay.h>
+#include <linux/module.h>
+#include <asm/io.h>
+#include <asm/leon.h>
+#include <asm/vaddrs.h>
+#include <asm/sections.h>
+#include <asm/leon_pci.h>
+
+#include "irq.h"
+
+struct grpci2_barcfg {
+	unsigned long pciadr;	/* PCI Space Address */
+	unsigned long ahbadr;	/* PCI Base address mapped to this AHB addr */
+};
+
+/* Device Node Configuration options:
+ *  - barcfgs    : Custom Configuration of Host's 6 target BARs
+ *  - irq_mask   : Limit which PCI interrupts are enabled
+ *  - do_reset   : Force PCI Reset on startup
+ *
+ * barcfgs
+ * =======
+ *
+ * Optional custom Target BAR configuration (see struct grpci2_barcfg). All
+ * addresses are physical. Array always contains 6 elements (len=2*4*6 bytes)
+ *
+ * -1 means not configured (let host driver do default setup).
+ *
+ * [i*2+0] = PCI Address of BAR[i] on target interface
+ * [i*2+1] = Accessing PCI address of BAR[i] result in this AMBA address
+ *
+ *
+ * irq_mask
+ * ========
+ *
+ * Limit which PCI interrupts are enabled. 0=Disable, 1=Enable. By default
+ * all are enabled. Use this when PCI interrupt pins are floating on PCB.
+ * int, len=4.
+ *  bit0 = PCI INTA#
+ *  bit1 = PCI INTB#
+ *  bit2 = PCI INTC#
+ *  bit3 = PCI INTD#
+ *
+ *
+ * reset
+ * =====
+ *
+ * Force PCI reset on startup. int, len=4
+ */
+
+/* Enable Debugging Configuration Space Access */
+#undef GRPCI2_DEBUG_CFGACCESS
+
+/*
+ * GRPCI2 APB Register MAP
+ */
+struct grpci2_regs {
+	unsigned int ctrl;		/* 0x00 Control */
+	unsigned int sts_cap;		/* 0x04 Status / Capabilities */
+	int res1;			/* 0x08 */
+	unsigned int io_map;		/* 0x0C I/O Map address */
+	unsigned int dma_ctrl;		/* 0x10 DMA */
+	unsigned int dma_bdbase;	/* 0x14 DMA */
+	int res2[2];			/* 0x18 */
+	unsigned int bars[6];		/* 0x20 read-only PCI BARs */
+	int res3[2];			/* 0x38 */
+	unsigned int ahbmst_map[16];	/* 0x40 AHB->PCI Map per AHB Master */
+
+	/* PCI Trace Buffer Registers (OPTIONAL) */
+	unsigned int t_ctrl;		/* 0x80 */
+	unsigned int t_cnt;		/* 0x84 */
+	unsigned int t_adpat;		/* 0x88 */
+	unsigned int t_admask;		/* 0x8C */
+	unsigned int t_sigpat;		/* 0x90 */
+	unsigned int t_sigmask;		/* 0x94 */
+	unsigned int t_adstate;		/* 0x98 */
+	unsigned int t_sigstate;	/* 0x9C */
+};
+
+#define REGLOAD(a)	(be32_to_cpu(__raw_readl(&(a))))
+#define REGSTORE(a, v)	(__raw_writel(cpu_to_be32(v), &(a)))
+
+#define CTRL_BUS_BIT 16
+
+#define CTRL_RESET (1<<31)
+#define CTRL_SI (1<<27)
+#define CTRL_PE (1<<26)
+#define CTRL_EI (1<<25)
+#define CTRL_ER (1<<24)
+#define CTRL_BUS (0xff<<CTRL_BUS_BIT)
+#define CTRL_HOSTINT 0xf
+
+#define STS_HOST_BIT	31
+#define STS_MST_BIT	30
+#define STS_TAR_BIT	29
+#define STS_DMA_BIT	28
+#define STS_DI_BIT	27
+#define STS_HI_BIT	26
+#define STS_IRQMODE_BIT	24
+#define STS_TRACE_BIT	23
+#define STS_CFGERRVALID_BIT 20
+#define STS_CFGERR_BIT	19
+#define STS_INTTYPE_BIT	12
+#define STS_INTSTS_BIT	8
+#define STS_FDEPTH_BIT	2
+#define STS_FNUM_BIT	0
+
+#define STS_HOST	(1<<STS_HOST_BIT)
+#define STS_MST		(1<<STS_MST_BIT)
+#define STS_TAR		(1<<STS_TAR_BIT)
+#define STS_DMA		(1<<STS_DMA_BIT)
+#define STS_DI		(1<<STS_DI_BIT)
+#define STS_HI		(1<<STS_HI_BIT)
+#define STS_IRQMODE	(0x3<<STS_IRQMODE_BIT)
+#define STS_TRACE	(1<<STS_TRACE_BIT)
+#define STS_CFGERRVALID	(1<<STS_CFGERRVALID_BIT)
+#define STS_CFGERR	(1<<STS_CFGERR_BIT)
+#define STS_INTTYPE	(0x3f<<STS_INTTYPE_BIT)
+#define STS_INTSTS	(0xf<<STS_INTSTS_BIT)
+#define STS_FDEPTH	(0x7<<STS_FDEPTH_BIT)
+#define STS_FNUM	(0x3<<STS_FNUM_BIT)
+
+#define STS_ISYSERR	(1<<17)
+#define STS_IDMA	(1<<16)
+#define STS_IDMAERR	(1<<15)
+#define STS_IMSTABRT	(1<<14)
+#define STS_ITGTABRT	(1<<13)
+#define STS_IPARERR	(1<<12)
+
+#define STS_ERR_IRQ (STS_ISYSERR | STS_IMSTABRT | STS_ITGTABRT | STS_IPARERR)
+
+struct grpci2_bd_chan {
+	unsigned int ctrl;	/* 0x00 DMA Control */
+	unsigned int nchan;	/* 0x04 Next DMA Channel Address */
+	unsigned int nbd;	/* 0x08 Next Data Descriptor in chan */
+	unsigned int res;	/* 0x0C Reserved */
+};
+
+#define BD_CHAN_EN		0x80000000
+#define BD_CHAN_TYPE		0x00300000
+#define BD_CHAN_BDCNT		0x0000ffff
+#define BD_CHAN_EN_BIT		31
+#define BD_CHAN_TYPE_BIT	20
+#define BD_CHAN_BDCNT_BIT	0
+
+struct grpci2_bd_data {
+	unsigned int ctrl;	/* 0x00 DMA Data Control */
+	unsigned int pci_adr;	/* 0x04 PCI Start Address */
+	unsigned int ahb_adr;	/* 0x08 AHB Start address */
+	unsigned int next;	/* 0x0C Next Data Descriptor in chan */
+};
+
+#define BD_DATA_EN		0x80000000
+#define BD_DATA_IE		0x40000000
+#define BD_DATA_DR		0x20000000
+#define BD_DATA_TYPE		0x00300000
+#define BD_DATA_ER		0x00080000
+#define BD_DATA_LEN		0x0000ffff
+#define BD_DATA_EN_BIT		31
+#define BD_DATA_IE_BIT		30
+#define BD_DATA_DR_BIT		29
+#define BD_DATA_TYPE_BIT	20
+#define BD_DATA_ER_BIT		19
+#define BD_DATA_LEN_BIT		0
+
+/* GRPCI2 Capability */
+struct grpci2_cap_first {
+	unsigned int ctrl;
+	unsigned int pci2ahb_map[6];
+	unsigned int ext2ahb_map;
+	unsigned int io_map;
+	unsigned int pcibar_size[6];
+};
+#define CAP9_CTRL_OFS 0
+#define CAP9_BAR_OFS 0x4
+#define CAP9_IOMAP_OFS 0x20
+#define CAP9_BARSIZE_OFS 0x24
+
+struct grpci2_priv {
+	struct leon_pci_info	info; /* must be on top of this structure */
+	struct grpci2_regs	*regs;
+	char			irq;
+	char			irq_mode; /* IRQ Mode from CAPSTS REG */
+	char			bt_enabled;
+	char			do_reset;
+	char			irq_mask;
+	u32			pciid; /* PCI ID of Host */
+	unsigned char		irq_map[4];
+
+	/* Virtual IRQ numbers */
+	unsigned int		virq_err;
+	unsigned int		virq_dma;
+
+	/* AHB PCI Windows */
+	unsigned long		pci_area;	/* MEMORY */
+	unsigned long		pci_area_end;
+	unsigned long		pci_io;		/* I/O */
+	unsigned long		pci_conf;	/* CONFIGURATION */
+	unsigned long		pci_conf_end;
+	unsigned long		pci_io_va;
+
+	struct grpci2_barcfg	tgtbars[6];
+};
+
+DEFINE_SPINLOCK(grpci2_dev_lock);
+struct grpci2_priv *grpci2priv;
+
+int grpci2_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+	struct grpci2_priv *priv = dev->bus->sysdata;
+	int irq_group;
+
+	/* Use default IRQ decoding on PCI BUS0 according slot numbering */
+	irq_group = slot & 0x3;
+	pin = ((pin - 1) + irq_group) & 0x3;
+
+	return priv->irq_map[pin];
+}
+
+static int grpci2_cfg_r32(struct grpci2_priv *priv, unsigned int bus,
+				unsigned int devfn, int where, u32 *val)
+{
+	unsigned int *pci_conf;
+	unsigned long flags;
+	u32 tmp;
+
+	if (where & 0x3)
+		return -EINVAL;
+
+	if (bus == 0 && PCI_SLOT(devfn) != 0)
+		devfn += (0x8 * 6);
+
+	/* Select bus */
+	spin_lock_irqsave(&grpci2_dev_lock, flags);
+	REGSTORE(priv->regs->ctrl, (REGLOAD(priv->regs->ctrl) & ~(0xff << 16)) |
+				   (bus << 16));
+	spin_unlock_irqrestore(&grpci2_dev_lock, flags);
+
+	/* clear old status */
+	REGSTORE(priv->regs->sts_cap, (STS_CFGERR | STS_CFGERRVALID));
+
+	pci_conf = (unsigned int *) (priv->pci_conf |
+						(devfn << 8) | (where & 0xfc));
+	tmp = LEON3_BYPASS_LOAD_PA(pci_conf);
+
+	/* Wait until GRPCI2 signals that CFG access is done, it should be
+	 * done instantaneously unless a DMA operation is ongoing...
+	 */
+	while ((REGLOAD(priv->regs->sts_cap) & STS_CFGERRVALID) == 0)
+		;
+
+	if (REGLOAD(priv->regs->sts_cap) & STS_CFGERR) {
+		*val = 0xffffffff;
+	} else {
+		/* Bus always little endian (unaffected by byte-swapping) */
+		*val = flip_dword(tmp);
+	}
+
+	return 0;
+}
+
+static int grpci2_cfg_r16(struct grpci2_priv *priv, unsigned int bus,
+				unsigned int devfn, int where, u32 *val)
+{
+	u32 v;
+	int ret;
+
+	if (where & 0x1)
+		return -EINVAL;
+	ret = grpci2_cfg_r32(priv, bus, devfn, where & ~0x3, &v);
+	*val = 0xffff & (v >> (8 * (where & 0x3)));
+	return ret;
+}
+
+static int grpci2_cfg_r8(struct grpci2_priv *priv, unsigned int bus,
+				unsigned int devfn, int where, u32 *val)
+{
+	u32 v;
+	int ret;
+
+	ret = grpci2_cfg_r32(priv, bus, devfn, where & ~0x3, &v);
+	*val = 0xff & (v >> (8 * (where & 3)));
+
+	return ret;
+}
+
+static int grpci2_cfg_w32(struct grpci2_priv *priv, unsigned int bus,
+				unsigned int devfn, int where, u32 val)
+{
+	unsigned int *pci_conf;
+	unsigned long flags;
+
+	if (where & 0x3)
+		return -EINVAL;
+
+	if (bus == 0 && PCI_SLOT(devfn) != 0)
+		devfn += (0x8 * 6);
+
+	/* Select bus */
+	spin_lock_irqsave(&grpci2_dev_lock, flags);
+	REGSTORE(priv->regs->ctrl, (REGLOAD(priv->regs->ctrl) & ~(0xff << 16)) |
+				   (bus << 16));
+	spin_unlock_irqrestore(&grpci2_dev_lock, flags);
+
+	/* clear old status */
+	REGSTORE(priv->regs->sts_cap, (STS_CFGERR | STS_CFGERRVALID));
+
+	pci_conf = (unsigned int *) (priv->pci_conf |
+						(devfn << 8) | (where & 0xfc));
+	LEON3_BYPASS_STORE_PA(pci_conf, flip_dword(val));
+
+	/* Wait until GRPCI2 signals that CFG access is done, it should be
+	 * done instantaneously unless a DMA operation is ongoing...
+	 */
+	while ((REGLOAD(priv->regs->sts_cap) & STS_CFGERRVALID) == 0)
+		;
+
+	return 0;
+}
+
+static int grpci2_cfg_w16(struct grpci2_priv *priv, unsigned int bus,
+				unsigned int devfn, int where, u32 val)
+{
+	int ret;
+	u32 v;
+
+	if (where & 0x1)
+		return -EINVAL;
+	ret = grpci2_cfg_r32(priv, bus, devfn, where&~3, &v);
+	if (ret)
+		return ret;
+	v = (v & ~(0xffff << (8 * (where & 0x3)))) |
+	    ((0xffff & val) << (8 * (where & 0x3)));
+	return grpci2_cfg_w32(priv, bus, devfn, where & ~0x3, v);
+}
+
+static int grpci2_cfg_w8(struct grpci2_priv *priv, unsigned int bus,
+				unsigned int devfn, int where, u32 val)
+{
+	int ret;
+	u32 v;
+
+	ret = grpci2_cfg_r32(priv, bus, devfn, where & ~0x3, &v);
+	if (ret != 0)
+		return ret;
+	v = (v & ~(0xff << (8 * (where & 0x3)))) |
+	    ((0xff & val) << (8 * (where & 0x3)));
+	return grpci2_cfg_w32(priv, bus, devfn, where & ~0x3, v);
+}
+
+/* Read from Configuration Space. When entering here the PCI layer has taken
+ * the pci_lock spinlock and IRQ is off.
+ */
+static int grpci2_read_config(struct pci_bus *bus, unsigned int devfn,
+			      int where, int size, u32 *val)
+{
+	struct grpci2_priv *priv = grpci2priv;
+	unsigned int busno = bus->number;
+	int ret;
+
+	if (PCI_SLOT(devfn) > 15 || (PCI_SLOT(devfn) == 0 && busno == 0)) {
+		*val = ~0;
+		return 0;
+	}
+
+	switch (size) {
+	case 1:
+		ret = grpci2_cfg_r8(priv, busno, devfn, where, val);
+		break;
+	case 2:
+		ret = grpci2_cfg_r16(priv, busno, devfn, where, val);
+		break;
+	case 4:
+		ret = grpci2_cfg_r32(priv, busno, devfn, where, val);
+		break;
+	default:
+		ret = -EINVAL;
+		break;
+	}
+
+#ifdef GRPCI2_DEBUG_CFGACCESS
+	printk(KERN_INFO "grpci2_read_config: [%02x:%02x:%x] ofs=%d val=%x "
+		"size=%d\n", busno, PCI_SLOT(devfn), PCI_FUNC(devfn), where,
+		*val, size);
+#endif
+
+	return ret;
+}
+
+/* Write to Configuration Space. When entering here the PCI layer has taken
+ * the pci_lock spinlock and IRQ is off.
+ */
+static int grpci2_write_config(struct pci_bus *bus, unsigned int devfn,
+			       int where, int size, u32 val)
+{
+	struct grpci2_priv *priv = grpci2priv;
+	unsigned int busno = bus->number;
+
+	if (PCI_SLOT(devfn) > 15 || (PCI_SLOT(devfn) == 0 && busno == 0))
+		return 0;
+
+#ifdef GRPCI2_DEBUG_CFGACCESS
+	printk(KERN_INFO "grpci2_write_config: [%02x:%02x:%x] ofs=%d size=%d "
+		"val=%x\n", busno, PCI_SLOT(devfn), PCI_FUNC(devfn),
+		where, size, val);
+#endif
+
+	switch (size) {
+	default:
+		return -EINVAL;
+	case 1:
+		return grpci2_cfg_w8(priv, busno, devfn, where, val);
+	case 2:
+		return grpci2_cfg_w16(priv, busno, devfn, where, val);
+	case 4:
+		return grpci2_cfg_w32(priv, busno, devfn, where, val);
+	}
+}
+
+static struct pci_ops grpci2_ops = {
+	.read =		grpci2_read_config,
+	.write =	grpci2_write_config,
+};
+
+/* GENIRQ IRQ chip implementation for GRPCI2 irqmode=0..2. In configuration
+ * 3 where all PCI Interrupts has a separate IRQ on the system IRQ controller
+ * this is not needed and the standard IRQ controller can be used.
+ */
+
+static void grpci2_mask_irq(struct irq_data *data)
+{
+	unsigned long flags;
+	unsigned int irqidx;
+	struct grpci2_priv *priv = grpci2priv;
+
+	irqidx = (unsigned int)data->chip_data - 1;
+	if (irqidx > 3) /* only mask PCI interrupts here */
+		return;
+
+	spin_lock_irqsave(&grpci2_dev_lock, flags);
+	REGSTORE(priv->regs->ctrl, REGLOAD(priv->regs->ctrl) & ~(1 << irqidx));
+	spin_unlock_irqrestore(&grpci2_dev_lock, flags);
+}
+
+static void grpci2_unmask_irq(struct irq_data *data)
+{
+	unsigned long flags;
+	unsigned int irqidx;
+	struct grpci2_priv *priv = grpci2priv;
+
+	irqidx = (unsigned int)data->chip_data - 1;
+	if (irqidx > 3) /* only unmask PCI interrupts here */
+		return;
+
+	spin_lock_irqsave(&grpci2_dev_lock, flags);
+	REGSTORE(priv->regs->ctrl, REGLOAD(priv->regs->ctrl) | (1 << irqidx));
+	spin_unlock_irqrestore(&grpci2_dev_lock, flags);
+}
+
+static unsigned int grpci2_startup_irq(struct irq_data *data)
+{
+	grpci2_unmask_irq(data);
+	return 0;
+}
+
+static void grpci2_shutdown_irq(struct irq_data *data)
+{
+	grpci2_mask_irq(data);
+}
+
+static struct irq_chip grpci2_irq = {
+	.name		= "grpci2",
+	.irq_startup	= grpci2_startup_irq,
+	.irq_shutdown	= grpci2_shutdown_irq,
+	.irq_mask	= grpci2_mask_irq,
+	.irq_unmask	= grpci2_unmask_irq,
+};
+
+/* Handle one or multiple IRQs from the PCI core */
+static void grpci2_pci_flow_irq(unsigned int irq, struct irq_desc *desc)
+{
+	struct grpci2_priv *priv = grpci2priv;
+	int i, ack = 0;
+	unsigned int ctrl, sts_cap, pci_ints;
+
+	ctrl = REGLOAD(priv->regs->ctrl);
+	sts_cap = REGLOAD(priv->regs->sts_cap);
+
+	/* Error Interrupt? */
+	if (sts_cap & STS_ERR_IRQ) {
+		generic_handle_irq(priv->virq_err);
+		ack = 1;
+	}
+
+	/* PCI Interrupt? */
+	pci_ints = ((~sts_cap) >> STS_INTSTS_BIT) & ctrl & CTRL_HOSTINT;
+	if (pci_ints) {
+		/* Call respective PCI Interrupt handler */
+		for (i = 0; i < 4; i++) {
+			if (pci_ints & (1 << i))
+				generic_handle_irq(priv->irq_map[i]);
+		}
+		ack = 1;
+	}
+
+	/*
+	 * Decode DMA Interrupt only when shared with Err and PCI INTX#, when
+	 * the DMA is a unique IRQ the DMA interrupts doesn't end up here, they
+	 * goes directly to DMA ISR.
+	 */
+	if ((priv->irq_mode == 0) && (sts_cap & (STS_IDMA | STS_IDMAERR))) {
+		generic_handle_irq(priv->virq_dma);
+		ack = 1;
+	}
+
+	/*
+	 * Call "first level" IRQ chip end-of-irq handler. It will ACK LEON IRQ
+	 * Controller, this must be done after IRQ sources have been handled to
+	 * avoid double IRQ generation
+	 */
+	if (ack)
+		desc->irq_data.chip->irq_eoi(&desc->irq_data);
+}
+
+/* Create a virtual IRQ */
+static unsigned int grpci2_build_device_irq(unsigned int irq)
+{
+	unsigned int virq = 0, pil;
+
+	pil = 1 << 8;
+	virq = irq_alloc(irq, pil);
+	if (virq == 0)
+		goto out;
+
+	irq_set_chip_and_handler_name(virq, &grpci2_irq, handle_simple_irq,
+				      "pcilvl");
+	irq_set_chip_data(virq, (void *)irq);
+
+out:
+	return virq;
+}
+
+void grpci2_hw_init(struct grpci2_priv *priv)
+{
+	u32 ahbadr, pciadr, bar_sz, capptr, io_map, data;
+	struct grpci2_regs *regs = priv->regs;
+	int i;
+	struct grpci2_barcfg *barcfg = priv->tgtbars;
+
+	/* Reset any earlier setup */
+	if (priv->do_reset) {
+		printk(KERN_INFO "GRPCI2: Resetting PCI bus\n");
+		REGSTORE(regs->ctrl, CTRL_RESET);
+		ssleep(1); /* Wait for boards to settle */
+	}
+	REGSTORE(regs->ctrl, 0);
+	REGSTORE(regs->sts_cap, ~0); /* Clear Status */
+	REGSTORE(regs->dma_ctrl, 0);
+	REGSTORE(regs->dma_bdbase, 0);
+
+	/* Translate I/O accesses to 0, I/O Space always @ PCI low 64Kbytes */
+	REGSTORE(regs->io_map, REGLOAD(regs->io_map) & 0x0000ffff);
+
+	/* set 1:1 mapping between AHB -> PCI memory space, for all Masters
+	 * Each AHB master has it's own mapping registers. Max 16 AHB masters.
+	 */
+	for (i = 0; i < 16; i++)
+		REGSTORE(regs->ahbmst_map[i], priv->pci_area);
+
+	/* Get the GRPCI2 Host PCI ID */
+	grpci2_cfg_r32(priv, 0, 0, PCI_VENDOR_ID, &priv->pciid);
+
+	/* Get address to first (always defined) capability structure */
+	grpci2_cfg_r8(priv, 0, 0, PCI_CAPABILITY_LIST, &capptr);
+
+	/* Enable/Disable Byte twisting */
+	grpci2_cfg_r32(priv, 0, 0, capptr+CAP9_IOMAP_OFS, &io_map);
+	io_map = (io_map & ~0x1) | (priv->bt_enabled ? 1 : 0);
+	grpci2_cfg_w32(priv, 0, 0, capptr+CAP9_IOMAP_OFS, io_map);
+
+	/* Setup the Host's PCI Target BARs for other peripherals to access,
+	 * and do DMA to the host's memory. The target BARs can be sized and
+	 * enabled individually.
+	 *
+	 * User may set custom target BARs, but default is:
+	 * The first BARs is used to map kernel low (DMA is part of normal
+	 * region on sparc which is SRMMU_MAXMEM big) main memory 1:1 to the
+	 * PCI bus, the other BARs are disabled. We assume that the first BAR
+	 * is always available.
+	 */
+	for (i = 0; i < 6; i++) {
+		if (barcfg[i].pciadr != ~0 && barcfg[i].ahbadr != ~0) {
+			/* Target BARs must have the proper alignment */
+			ahbadr = barcfg[i].ahbadr;
+			pciadr = barcfg[i].pciadr;
+			bar_sz = ((pciadr - 1) & ~pciadr) + 1;
+		} else {
+			if (i == 0) {
+				/* Map main memory */
+				bar_sz = 0xf0000008; /* 256MB prefetchable */
+				ahbadr = 0xf0000000 & (u32)__pa(PAGE_ALIGN(
+					(unsigned long) &_end));
+				pciadr = ahbadr;
+			} else {
+				bar_sz = 0;
+				ahbadr = 0;
+				pciadr = 0;
+			}
+		}
+		grpci2_cfg_w32(priv, 0, 0, capptr+CAP9_BARSIZE_OFS+i*4, bar_sz);
+		grpci2_cfg_w32(priv, 0, 0, PCI_BASE_ADDRESS_0+i*4, pciadr);
+		grpci2_cfg_w32(priv, 0, 0, capptr+CAP9_BAR_OFS+i*4, ahbadr);
+		printk(KERN_INFO "        TGT BAR[%d]: 0x%08x (PCI)-> 0x%08x\n",
+			i, pciadr, ahbadr);
+	}
+
+	/* set as bus master and enable pci memory responses */
+	grpci2_cfg_r32(priv, 0, 0, PCI_COMMAND, &data);
+	data |= (PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER);
+	grpci2_cfg_w32(priv, 0, 0, PCI_COMMAND, data);
+
+	/* Enable Error respone (CPU-TRAP) on illegal memory access. */
+	REGSTORE(regs->ctrl, CTRL_ER | CTRL_PE);
+}
+
+static irqreturn_t grpci2_jump_interrupt(int irq, void *arg)
+{
+	printk(KERN_ERR "GRPCI2: Jump IRQ happened\n");
+	return IRQ_NONE;
+}
+
+/* Handle GRPCI2 Error Interrupt */
+static irqreturn_t grpci2_err_interrupt(int irq, void *arg)
+{
+	struct grpci2_priv *priv = arg;
+	struct grpci2_regs *regs = priv->regs;
+	unsigned int status;
+
+	status = REGLOAD(regs->sts_cap);
+	if ((status & STS_ERR_IRQ) == 0)
+		return IRQ_NONE;
+
+	if (status & STS_IPARERR)
+		printk(KERN_ERR "GRPCI2: Parity Error\n");
+
+	if (status & STS_ITGTABRT)
+		printk(KERN_ERR "GRPCI2: Target Abort\n");
+
+	if (status & STS_IMSTABRT)
+		printk(KERN_ERR "GRPCI2: Master Abort\n");
+
+	if (status & STS_ISYSERR)
+		printk(KERN_ERR "GRPCI2: System Error\n");
+
+	/* Clear handled INT TYPE IRQs */
+	REGSTORE(regs->sts_cap, status & STS_ERR_IRQ);
+
+	return IRQ_HANDLED;
+}
+
+static int __devinit grpci2_of_probe(struct platform_device *ofdev)
+{
+	struct grpci2_regs *regs;
+	struct grpci2_priv *priv;
+	int err, i, len;
+	const int *tmp;
+	unsigned int capability;
+
+	if (grpci2priv) {
+		printk(KERN_ERR "GRPCI2: only one GRPCI2 core supported\n");
+		return -ENODEV;
+	}
+
+	if (ofdev->num_resources < 3) {
+		printk(KERN_ERR "GRPCI2: not enough APB/AHB resources\n");
+		return -EIO;
+	}
+
+	/* Find Device Address */
+	regs = of_ioremap(&ofdev->resource[0], 0,
+			  resource_size(&ofdev->resource[0]),
+			  "grlib-grpci2 regs");
+	if (regs == NULL) {
+		printk(KERN_ERR "GRPCI2: ioremap failed\n");
+		return -EIO;
+	}
+
+	/*
+	 * Check that we're in Host Slot and that we can act as a Host Bridge
+	 * and not only as target.
+	 */
+	capability = REGLOAD(regs->sts_cap);
+	if ((capability & STS_HOST) || !(capability & STS_MST)) {
+		printk(KERN_INFO "GRPCI2: not in host system slot\n");
+		err = -EIO;
+		goto err1;
+	}
+
+	priv = grpci2priv = kzalloc(sizeof(struct grpci2_priv), GFP_KERNEL);
+	if (grpci2priv == NULL) {
+		err = -ENOMEM;
+		goto err1;
+	}
+	memset(grpci2priv, 0, sizeof(*grpci2priv));
+	priv->regs = regs;
+	priv->irq = ofdev->archdata.irqs[0]; /* BASE IRQ */
+	priv->irq_mode = (capability & STS_IRQMODE) >> STS_IRQMODE_BIT;
+
+	printk(KERN_INFO "GRPCI2: host found at %p, irq%d\n", regs, priv->irq);
+
+	/* Byte twisting should be made configurable from kernel command line */
+	priv->bt_enabled = 1;
+
+	/* Let user do custom Target BAR assignment */
+	tmp = of_get_property(ofdev->dev.of_node, "barcfg", &len);
+	if (tmp && (len == 2*4*6))
+		memcpy(priv->tgtbars, tmp, 2*4*6);
+	else
+		memset(priv->tgtbars, -1, 2*4*6);
+
+	/* Limit IRQ unmasking in irq_mode 2 and 3 */
+	tmp = of_get_property(ofdev->dev.of_node, "irq_mask", &len);
+	if (tmp && (len == 4))
+		priv->do_reset = *tmp;
+	else
+		priv->irq_mask = 0xf;
+
+	/* Optional PCI reset. Force PCI reset on startup */
+	tmp = of_get_property(ofdev->dev.of_node, "reset", &len);
+	if (tmp && (len == 4))
+		priv->do_reset = *tmp;
+	else
+		priv->do_reset = 0;
+
+	/* Find PCI Memory, I/O and Configuration Space Windows */
+	priv->pci_area = ofdev->resource[1].start;
+	priv->pci_area_end = ofdev->resource[1].end+1;
+	priv->pci_io = ofdev->resource[2].start;
+	priv->pci_conf = ofdev->resource[2].start + 0x10000;
+	priv->pci_conf_end = priv->pci_conf + 0x10000;
+	priv->pci_io_va = (unsigned long)ioremap(priv->pci_io, 0x10000);
+	if (!priv->pci_io_va) {
+		err = -EIO;
+		goto err2;
+	}
+
+	printk(KERN_INFO
+		"GRPCI2: MEMORY SPACE [0x%08lx - 0x%08lx]\n"
+		"        I/O    SPACE [0x%08lx - 0x%08lx]\n"
+		"        CONFIG SPACE [0x%08lx - 0x%08lx]\n",
+		priv->pci_area, priv->pci_area_end-1,
+		priv->pci_io, priv->pci_conf-1,
+		priv->pci_conf, priv->pci_conf_end-1);
+
+	/*
+	 * I/O Space resources in I/O Window mapped into Virtual Adr Space
+	 * We never use low 4KB because some devices seem have problems using
+	 * address 0.
+	 */
+	memset(&priv->info.io_space, 0, sizeof(struct resource));
+	priv->info.io_space.name = "GRPCI2 PCI I/O Space";
+	priv->info.io_space.start = priv->pci_io_va + 0x1000;
+	priv->info.io_space.end = priv->pci_io_va + 0x10000 - 1;
+	priv->info.io_space.flags = IORESOURCE_IO;
+
+	/*
+	 * GRPCI2 has no prefetchable memory, map everything as
+	 * non-prefetchable memory
+	 */
+	memset(&priv->info.mem_space, 0, sizeof(struct resource));
+	priv->info.mem_space.name = "GRPCI2 PCI MEM Space";
+	priv->info.mem_space.start = priv->pci_area;
+	priv->info.mem_space.end = priv->pci_area_end - 1;
+	priv->info.mem_space.flags = IORESOURCE_MEM;
+
+	if (request_resource(&iomem_resource, &priv->info.mem_space) < 0)
+		goto err3;
+	if (request_resource(&ioport_resource, &priv->info.io_space) < 0)
+		goto err4;
+
+	grpci2_hw_init(priv);
+
+	/*
+	 * Get PCI Interrupt to System IRQ mapping and setup IRQ handling
+	 * Error IRQ always on PCI INTA.
+	 */
+	if (priv->irq_mode < 2) {
+		/* All PCI interrupts are shared using the same system IRQ */
+		leon_update_virq_handling(priv->irq, grpci2_pci_flow_irq,
+					 "pcilvl", 0);
+
+		priv->irq_map[0] = grpci2_build_device_irq(1);
+		priv->irq_map[1] = grpci2_build_device_irq(2);
+		priv->irq_map[2] = grpci2_build_device_irq(3);
+		priv->irq_map[3] = grpci2_build_device_irq(4);
+
+		priv->virq_err = grpci2_build_device_irq(5);
+		if (priv->irq_mode & 1)
+			priv->virq_dma = ofdev->archdata.irqs[1];
+		else
+			priv->virq_dma = grpci2_build_device_irq(6);
+
+		/* Enable IRQs on LEON IRQ controller */
+		err = request_irq(priv->irq, grpci2_jump_interrupt, 0,
+					"GRPCI2_JUMP", priv);
+		if (err)
+			printk(KERN_ERR "GRPCI2: ERR IRQ request failed\n");
+	} else {
+		/* All PCI interrupts have an unique IRQ interrupt */
+		for (i = 0; i < 4; i++) {
+			/* Make LEON IRQ layer handle level IRQ by acking */
+			leon_update_virq_handling(ofdev->archdata.irqs[i],
+						 handle_fasteoi_irq, "pcilvl",
+						 1);
+			priv->irq_map[i] = ofdev->archdata.irqs[i];
+		}
+		priv->virq_err = priv->irq_map[0];
+		if (priv->irq_mode & 1)
+			priv->virq_dma = ofdev->archdata.irqs[4];
+		else
+			priv->virq_dma = priv->irq_map[0];
+
+		/* Unmask all PCI interrupts, request_irq will not do that */
+		REGSTORE(regs->ctrl, REGLOAD(regs->ctrl)|(priv->irq_mask&0xf));
+	}
+
+	/* Setup IRQ handler for non-configuration space access errors */
+	err = request_irq(priv->virq_err, grpci2_err_interrupt, IRQF_SHARED,
+				"GRPCI2_ERR", priv);
+	if (err) {
+		printk(KERN_DEBUG "GRPCI2: ERR VIRQ request failed: %d\n", err);
+		goto err5;
+	}
+
+	/*
+	 * Enable Error Interrupts. PCI interrupts are unmasked once request_irq
+	 * is called by the PCI Device drivers
+	 */
+	REGSTORE(regs->ctrl, REGLOAD(regs->ctrl) | CTRL_EI | CTRL_SI);
+
+	/* Init common layer and scan buses */
+	priv->info.ops = &grpci2_ops;
+	priv->info.map_irq = grpci2_map_irq;
+	leon_pci_init(ofdev, &priv->info);
+
+	return 0;
+
+err5:
+	release_resource(&priv->info.io_space);
+err4:
+	release_resource(&priv->info.mem_space);
+err3:
+	err = -ENOMEM;
+	iounmap((void *)priv->pci_io_va);
+err2:
+	kfree(priv);
+err1:
+	of_iounmap(&ofdev->resource[0], regs,
+		resource_size(&ofdev->resource[0]));
+	return err;
+}
+
+static struct of_device_id grpci2_of_match[] = {
+	{
+	 .name = "GAISLER_GRPCI2",
+	 },
+	{
+	 .name = "01_07c",
+	 },
+	{},
+};
+
+static struct platform_driver grpci2_of_driver = {
+	.driver = {
+		.name = "grpci2",
+		.owner = THIS_MODULE,
+		.of_match_table = grpci2_of_match,
+	},
+	.probe = grpci2_of_probe,
+};
+
+static int __init grpci2_init(void)
+{
+	return platform_driver_register(&grpci2_of_driver);
+}
+
+subsys_initcall(grpci2_init);
diff -druN linux-2.6.39-libre/arch/sparc/kernel/leon_smp.c linux-3.0-rc7-libre/arch/sparc/kernel/leon_smp.c
--- linux-2.6.39-libre/arch/sparc/kernel/leon_smp.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/sparc/kernel/leon_smp.c	2011-07-11 19:51:52.000000000 -0400
@@ -14,6 +14,7 @@
 #include <linux/smp.h>
 #include <linux/interrupt.h>
 #include <linux/kernel_stat.h>
+#include <linux/of.h>
 #include <linux/init.h>
 #include <linux/spinlock.h>
 #include <linux/mm.h>
@@ -29,6 +30,7 @@
 #include <asm/ptrace.h>
 #include <asm/atomic.h>
 #include <asm/irq_regs.h>
+#include <asm/traps.h>
 
 #include <asm/delay.h>
 #include <asm/irq.h>
@@ -50,9 +52,12 @@
 extern ctxd_t *srmmu_ctx_table_phys;
 static int smp_processors_ready;
 extern volatile unsigned long cpu_callin_map[NR_CPUS];
-extern unsigned char boot_cpu_id;
 extern cpumask_t smp_commenced_mask;
 void __init leon_configure_cache_smp(void);
+static void leon_ipi_init(void);
+
+/* IRQ number of LEON IPIs */
+int leon_ipi_irq = LEON3_IRQ_IPI_DEFAULT;
 
 static inline unsigned long do_swap(volatile unsigned long *ptr,
 				    unsigned long val)
@@ -94,8 +99,6 @@
 	local_flush_cache_all();
 	local_flush_tlb_all();
 
-	cpu_probe();
-
 	/* Fix idle thread fields. */
 	__asm__ __volatile__("ld [%0], %%g6\n\t" : : "r"(&current_set[cpuid])
 			     : "memory" /* paranoid */);
@@ -104,11 +107,11 @@
 	atomic_inc(&init_mm.mm_count);
 	current->active_mm = &init_mm;
 
-	while (!cpu_isset(cpuid, smp_commenced_mask))
+	while (!cpumask_test_cpu(cpuid, &smp_commenced_mask))
 		mb();
 
 	local_irq_enable();
-	cpu_set(cpuid, cpu_online_map);
+	set_cpu_online(cpuid, true);
 }
 
 /*
@@ -179,13 +182,16 @@
 	int nrcpu = leon_smp_nrcpus();
 	int me = smp_processor_id();
 
+	/* Setup IPI */
+	leon_ipi_init();
+
 	printk(KERN_INFO "%d:(%d:%d) cpus mpirq at 0x%x\n", (unsigned int)me,
 	       (unsigned int)nrcpu, (unsigned int)NR_CPUS,
 	       (unsigned int)&(leon3_irqctrl_regs->mpstatus));
 
 	leon_enable_irq_cpu(LEON3_IRQ_CROSS_CALL, me);
 	leon_enable_irq_cpu(LEON3_IRQ_TICKER, me);
-	leon_enable_irq_cpu(LEON3_IRQ_RESCHEDULE, me);
+	leon_enable_irq_cpu(leon_ipi_irq, me);
 
 	leon_smp_setbroadcast(1 << LEON3_IRQ_TICKER);
 
@@ -220,6 +226,10 @@
 	       (unsigned int)&leon3_irqctrl_regs->mpstatus);
 	local_flush_cache_all();
 
+	/* Make sure all IRQs are of from the start for this new CPU */
+	LEON_BYPASS_STORE_PA(&leon3_irqctrl_regs->mask[i], 0);
+
+	/* Wake one CPU */
 	LEON_BYPASS_STORE_PA(&(leon3_irqctrl_regs->mpstatus), 1 << i);
 
 	/* wheee... it's going... */
@@ -236,7 +246,7 @@
 	} else {
 		leon_enable_irq_cpu(LEON3_IRQ_CROSS_CALL, i);
 		leon_enable_irq_cpu(LEON3_IRQ_TICKER, i);
-		leon_enable_irq_cpu(LEON3_IRQ_RESCHEDULE, i);
+		leon_enable_irq_cpu(leon_ipi_irq, i);
 	}
 
 	local_flush_cache_all();
@@ -262,21 +272,21 @@
 	local_flush_cache_all();
 
 	/* Free unneeded trap tables */
-	if (!cpu_isset(1, cpu_present_map)) {
+	if (!cpu_present(1)) {
 		ClearPageReserved(virt_to_page(&trapbase_cpu1));
 		init_page_count(virt_to_page(&trapbase_cpu1));
 		free_page((unsigned long)&trapbase_cpu1);
 		totalram_pages++;
 		num_physpages++;
 	}
-	if (!cpu_isset(2, cpu_present_map)) {
+	if (!cpu_present(2)) {
 		ClearPageReserved(virt_to_page(&trapbase_cpu2));
 		init_page_count(virt_to_page(&trapbase_cpu2));
 		free_page((unsigned long)&trapbase_cpu2);
 		totalram_pages++;
 		num_physpages++;
 	}
-	if (!cpu_isset(3, cpu_present_map)) {
+	if (!cpu_present(3)) {
 		ClearPageReserved(virt_to_page(&trapbase_cpu3));
 		init_page_count(virt_to_page(&trapbase_cpu3));
 		free_page((unsigned long)&trapbase_cpu3);
@@ -292,6 +302,99 @@
 {
 }
 
+struct leon_ipi_work {
+	int single;
+	int msk;
+	int resched;
+};
+
+static DEFINE_PER_CPU_SHARED_ALIGNED(struct leon_ipi_work, leon_ipi_work);
+
+/* Initialize IPIs on the LEON, in order to save IRQ resources only one IRQ
+ * is used for all three types of IPIs.
+ */
+static void __init leon_ipi_init(void)
+{
+	int cpu, len;
+	struct leon_ipi_work *work;
+	struct property *pp;
+	struct device_node *rootnp;
+	struct tt_entry *trap_table;
+	unsigned long flags;
+
+	/* Find IPI IRQ or stick with default value */
+	rootnp = of_find_node_by_path("/ambapp0");
+	if (rootnp) {
+		pp = of_find_property(rootnp, "ipi_num", &len);
+		if (pp && (*(int *)pp->value))
+			leon_ipi_irq = *(int *)pp->value;
+	}
+	printk(KERN_INFO "leon: SMP IPIs at IRQ %d\n", leon_ipi_irq);
+
+	/* Adjust so that we jump directly to smpleon_ipi */
+	local_irq_save(flags);
+	trap_table = &sparc_ttable[SP_TRAP_IRQ1 + (leon_ipi_irq - 1)];
+	trap_table->inst_three += smpleon_ipi - real_irq_entry;
+	local_flush_cache_all();
+	local_irq_restore(flags);
+
+	for_each_possible_cpu(cpu) {
+		work = &per_cpu(leon_ipi_work, cpu);
+		work->single = work->msk = work->resched = 0;
+	}
+}
+
+static void leon_ipi_single(int cpu)
+{
+	struct leon_ipi_work *work = &per_cpu(leon_ipi_work, cpu);
+
+	/* Mark work */
+	work->single = 1;
+
+	/* Generate IRQ on the CPU */
+	set_cpu_int(cpu, leon_ipi_irq);
+}
+
+static void leon_ipi_mask_one(int cpu)
+{
+	struct leon_ipi_work *work = &per_cpu(leon_ipi_work, cpu);
+
+	/* Mark work */
+	work->msk = 1;
+
+	/* Generate IRQ on the CPU */
+	set_cpu_int(cpu, leon_ipi_irq);
+}
+
+static void leon_ipi_resched(int cpu)
+{
+	struct leon_ipi_work *work = &per_cpu(leon_ipi_work, cpu);
+
+	/* Mark work */
+	work->resched = 1;
+
+	/* Generate IRQ on the CPU (any IRQ will cause resched) */
+	set_cpu_int(cpu, leon_ipi_irq);
+}
+
+void leonsmp_ipi_interrupt(void)
+{
+	struct leon_ipi_work *work = &__get_cpu_var(leon_ipi_work);
+
+	if (work->single) {
+		work->single = 0;
+		smp_call_function_single_interrupt();
+	}
+	if (work->msk) {
+		work->msk = 0;
+		smp_call_function_interrupt();
+	}
+	if (work->resched) {
+		work->resched = 0;
+		smp_resched_interrupt();
+	}
+}
+
 static struct smp_funcall {
 	smpfunc_t func;
 	unsigned long arg1;
@@ -337,10 +440,10 @@
 		{
 			register int i;
 
-			cpu_clear(smp_processor_id(), mask);
-			cpus_and(mask, cpu_online_map, mask);
+			cpumask_clear_cpu(smp_processor_id(), &mask);
+			cpumask_and(&mask, cpu_online_mask, &mask);
 			for (i = 0; i <= high; i++) {
-				if (cpu_isset(i, mask)) {
+				if (cpumask_test_cpu(i, &mask)) {
 					ccall_info.processors_in[i] = 0;
 					ccall_info.processors_out[i] = 0;
 					set_cpu_int(i, LEON3_IRQ_CROSS_CALL);
@@ -354,7 +457,7 @@
 
 			i = 0;
 			do {
-				if (!cpu_isset(i, mask))
+				if (!cpumask_test_cpu(i, &mask))
 					continue;
 
 				while (!ccall_info.processors_in[i])
@@ -363,7 +466,7 @@
 
 			i = 0;
 			do {
-				if (!cpu_isset(i, mask))
+				if (!cpumask_test_cpu(i, &mask))
 					continue;
 
 				while (!ccall_info.processors_out[i])
@@ -386,27 +489,23 @@
 	ccall_info.processors_out[i] = 1;
 }
 
-void leon_percpu_timer_interrupt(struct pt_regs *regs)
+irqreturn_t leon_percpu_timer_interrupt(int irq, void *unused)
 {
-	struct pt_regs *old_regs;
 	int cpu = smp_processor_id();
 
-	old_regs = set_irq_regs(regs);
-
 	leon_clear_profile_irq(cpu);
 
 	profile_tick(CPU_PROFILING);
 
 	if (!--prof_counter(cpu)) {
-		int user = user_mode(regs);
+		int user = user_mode(get_irq_regs());
 
-		irq_enter();
 		update_process_times(user);
-		irq_exit();
 
 		prof_counter(cpu) = prof_multiplier(cpu);
 	}
-	set_irq_regs(old_regs);
+
+	return IRQ_HANDLED;
 }
 
 static void __init smp_setup_percpu_timer(void)
@@ -449,6 +548,9 @@
 	BTFIXUPSET_CALL(smp_cross_call, leon_cross_call, BTFIXUPCALL_NORM);
 	BTFIXUPSET_CALL(__hard_smp_processor_id, __leon_processor_id,
 			BTFIXUPCALL_NORM);
+	BTFIXUPSET_CALL(smp_ipi_resched, leon_ipi_resched, BTFIXUPCALL_NORM);
+	BTFIXUPSET_CALL(smp_ipi_single, leon_ipi_single, BTFIXUPCALL_NORM);
+	BTFIXUPSET_CALL(smp_ipi_mask_one, leon_ipi_mask_one, BTFIXUPCALL_NORM);
 }
 
 #endif /* CONFIG_SPARC_LEON */
diff -druN linux-2.6.39-libre/arch/sparc/kernel/Makefile linux-3.0-rc7-libre/arch/sparc/kernel/Makefile
--- linux-2.6.39-libre/arch/sparc/kernel/Makefile	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/sparc/kernel/Makefile	2011-07-11 19:51:52.000000000 -0400
@@ -71,13 +71,11 @@
 obj-$(CONFIG_SPARC64)	+= nmi.o
 obj-$(CONFIG_SPARC64_SMP) += cpumap.o
 
-# sparc32 do not use GENERIC_HARDIRQS but uses the generic devres implementation
-obj-$(CONFIG_SPARC32)     += devres.o
-devres-y                  := ../../../kernel/irq/devres.o
-
 obj-y                     += dma.o
 
-obj-$(CONFIG_SPARC32_PCI) += pcic.o
+obj-$(CONFIG_PCIC_PCI)    += pcic.o
+obj-$(CONFIG_LEON_PCI)    += leon_pci.o
+obj-$(CONFIG_GRPCI2)      += leon_pci_grpci2.o
 
 obj-$(CONFIG_SMP)         += trampoline_$(BITS).o smp_$(BITS).o
 obj-$(CONFIG_SPARC32_SMP) += sun4m_smp.o sun4d_smp.o leon_smp.o
diff -druN linux-2.6.39-libre/arch/sparc/kernel/mdesc.c linux-3.0-rc7-libre/arch/sparc/kernel/mdesc.c
--- linux-2.6.39-libre/arch/sparc/kernel/mdesc.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/sparc/kernel/mdesc.c	2011-07-11 19:51:52.000000000 -0400
@@ -768,7 +768,7 @@
 			       cpuid, NR_CPUS);
 			continue;
 		}
-		if (!cpu_isset(cpuid, *mask))
+		if (!cpumask_test_cpu(cpuid, mask))
 			continue;
 #endif
 
diff -druN linux-2.6.39-libre/arch/sparc/kernel/module.c linux-3.0-rc7-libre/arch/sparc/kernel/module.c
--- linux-2.6.39-libre/arch/sparc/kernel/module.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/sparc/kernel/module.c	2011-07-11 19:51:52.000000000 -0400
@@ -214,7 +214,7 @@
 			       me->name,
 			       (int) (ELF_R_TYPE(rel[i].r_info) & 0xff));
 			return -ENOEXEC;
-		};
+		}
 	}
 	return 0;
 }
diff -druN linux-2.6.39-libre/arch/sparc/kernel/of_device_64.c linux-3.0-rc7-libre/arch/sparc/kernel/of_device_64.c
--- linux-2.6.39-libre/arch/sparc/kernel/of_device_64.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/sparc/kernel/of_device_64.c	2011-07-11 19:51:52.000000000 -0400
@@ -622,8 +622,9 @@
 out:
 	nid = of_node_to_nid(dp);
 	if (nid != -1) {
-		cpumask_t numa_mask = *cpumask_of_node(nid);
+		cpumask_t numa_mask;
 
+		cpumask_copy(&numa_mask, cpumask_of_node(nid));
 		irq_set_affinity(irq, &numa_mask);
 	}
 
diff -druN linux-2.6.39-libre/arch/sparc/kernel/pcic.c linux-3.0-rc7-libre/arch/sparc/kernel/pcic.c
--- linux-2.6.39-libre/arch/sparc/kernel/pcic.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/sparc/kernel/pcic.c	2011-07-11 19:51:52.000000000 -0400
@@ -164,6 +164,9 @@
 volatile int pcic_speculative;
 volatile int pcic_trapped;
 
+/* forward */
+unsigned int pcic_build_device_irq(struct platform_device *op,
+                                   unsigned int real_irq);
 
 #define CONFIG_CMD(bus, device_fn, where) (0x80000000 | (((unsigned int)bus) << 16) | (((unsigned int)device_fn) << 8) | (where & ~3))
 
@@ -523,6 +526,7 @@
 pcic_fill_irq(struct linux_pcic *pcic, struct pci_dev *dev, int node)
 {
 	struct pcic_ca2irq *p;
+	unsigned int real_irq;
 	int i, ivec;
 	char namebuf[64];
 
@@ -551,26 +555,25 @@
 	i = p->pin;
 	if (i >= 0 && i < 4) {
 		ivec = readw(pcic->pcic_regs+PCI_INT_SELECT_LO);
-		dev->irq = ivec >> (i << 2) & 0xF;
+		real_irq = ivec >> (i << 2) & 0xF;
 	} else if (i >= 4 && i < 8) {
 		ivec = readw(pcic->pcic_regs+PCI_INT_SELECT_HI);
-		dev->irq = ivec >> ((i-4) << 2) & 0xF;
+		real_irq = ivec >> ((i-4) << 2) & 0xF;
 	} else {					/* Corrupted map */
 		printk("PCIC: BAD PIN %d\n", i); for (;;) {}
 	}
 /* P3 */ /* printk("PCIC: device %s pin %d ivec 0x%x irq %x\n", namebuf, i, ivec, dev->irq); */
 
-	/*
-	 * dev->irq=0 means PROM did not bother to program the upper
+	/* real_irq means PROM did not bother to program the upper
 	 * half of PCIC. This happens on JS-E with PROM 3.11, for instance.
 	 */
-	if (dev->irq == 0 || p->force) {
+	if (real_irq == 0 || p->force) {
 		if (p->irq == 0 || p->irq >= 15) {	/* Corrupted map */
 			printk("PCIC: BAD IRQ %d\n", p->irq); for (;;) {}
 		}
 		printk("PCIC: setting irq %d at pin %d for device %02x:%02x\n",
 		    p->irq, p->pin, dev->bus->number, dev->devfn);
-		dev->irq = p->irq;
+		real_irq = p->irq;
 
 		i = p->pin;
 		if (i >= 4) {
@@ -584,7 +587,8 @@
 			ivec |= p->irq << (i << 2);
 			writew(ivec, pcic->pcic_regs+PCI_INT_SELECT_LO);
 		}
- 	}
+	}
+	dev->irq = pcic_build_device_irq(NULL, real_irq);
 }
 
 /*
@@ -729,6 +733,7 @@
 	struct linux_pcic *pcic = &pcic0;
 	unsigned long v;
 	int timer_irq, irq;
+	int err;
 
 	do_arch_gettimeoffset = pci_gettimeoffset;
 
@@ -740,9 +745,10 @@
 	timer_irq = PCI_COUNTER_IRQ_SYS(v);
 	writel (PCI_COUNTER_IRQ_SET(timer_irq, 0),
 		pcic->pcic_regs+PCI_COUNTER_IRQ);
-	irq = request_irq(timer_irq, pcic_timer_handler,
-			  (IRQF_DISABLED | SA_STATIC_ALLOC), "timer", NULL);
-	if (irq) {
+	irq = pcic_build_device_irq(NULL, timer_irq);
+	err = request_irq(irq, pcic_timer_handler,
+			  IRQF_TIMER, "timer", NULL);
+	if (err) {
 		prom_printf("time_init: unable to attach IRQ%d\n", timer_irq);
 		prom_halt();
 	}
@@ -803,50 +809,73 @@
 	return 1 << irq_nr;
 }
 
-static void pcic_disable_irq(unsigned int irq_nr)
+static void pcic_mask_irq(struct irq_data *data)
 {
 	unsigned long mask, flags;
 
-	mask = get_irqmask(irq_nr);
+	mask = (unsigned long)data->chip_data;
 	local_irq_save(flags);
 	writel(mask, pcic0.pcic_regs+PCI_SYS_INT_TARGET_MASK_SET);
 	local_irq_restore(flags);
 }
 
-static void pcic_enable_irq(unsigned int irq_nr)
+static void pcic_unmask_irq(struct irq_data *data)
 {
 	unsigned long mask, flags;
 
-	mask = get_irqmask(irq_nr);
+	mask = (unsigned long)data->chip_data;
 	local_irq_save(flags);
 	writel(mask, pcic0.pcic_regs+PCI_SYS_INT_TARGET_MASK_CLEAR);
 	local_irq_restore(flags);
 }
 
-static void pcic_load_profile_irq(int cpu, unsigned int limit)
+static unsigned int pcic_startup_irq(struct irq_data *data)
 {
-	printk("PCIC: unimplemented code: FILE=%s LINE=%d", __FILE__, __LINE__);
+	irq_link(data->irq);
+	pcic_unmask_irq(data);
+	return 0;
 }
 
-/* We assume the caller has disabled local interrupts when these are called,
- * or else very bizarre behavior will result.
- */
-static void pcic_disable_pil_irq(unsigned int pil)
+static struct irq_chip pcic_irq = {
+	.name		= "pcic",
+	.irq_startup	= pcic_startup_irq,
+	.irq_mask	= pcic_mask_irq,
+	.irq_unmask	= pcic_unmask_irq,
+};
+
+unsigned int pcic_build_device_irq(struct platform_device *op,
+                                   unsigned int real_irq)
 {
-	writel(get_irqmask(pil), pcic0.pcic_regs+PCI_SYS_INT_TARGET_MASK_SET);
+	unsigned int irq;
+	unsigned long mask;
+
+	irq = 0;
+	mask = get_irqmask(real_irq);
+	if (mask == 0)
+		goto out;
+
+	irq = irq_alloc(real_irq, real_irq);
+	if (irq == 0)
+		goto out;
+
+	irq_set_chip_and_handler_name(irq, &pcic_irq,
+	                              handle_level_irq, "PCIC");
+	irq_set_chip_data(irq, (void *)mask);
+
+out:
+	return irq;
 }
 
-static void pcic_enable_pil_irq(unsigned int pil)
+
+static void pcic_load_profile_irq(int cpu, unsigned int limit)
 {
-	writel(get_irqmask(pil), pcic0.pcic_regs+PCI_SYS_INT_TARGET_MASK_CLEAR);
+	printk("PCIC: unimplemented code: FILE=%s LINE=%d", __FILE__, __LINE__);
 }
 
 void __init sun4m_pci_init_IRQ(void)
 {
-	BTFIXUPSET_CALL(enable_irq, pcic_enable_irq, BTFIXUPCALL_NORM);
-	BTFIXUPSET_CALL(disable_irq, pcic_disable_irq, BTFIXUPCALL_NORM);
-	BTFIXUPSET_CALL(enable_pil_irq, pcic_enable_pil_irq, BTFIXUPCALL_NORM);
-	BTFIXUPSET_CALL(disable_pil_irq, pcic_disable_pil_irq, BTFIXUPCALL_NORM);
+	sparc_irq_config.build_device_irq = pcic_build_device_irq;
+
 	BTFIXUPSET_CALL(clear_clock_irq, pcic_clear_clock_irq, BTFIXUPCALL_NORM);
 	BTFIXUPSET_CALL(load_profile_irq, pcic_load_profile_irq, BTFIXUPCALL_NORM);
 }
diff -druN linux-2.6.39-libre/arch/sparc/kernel/pci_common.c linux-3.0-rc7-libre/arch/sparc/kernel/pci_common.c
--- linux-2.6.39-libre/arch/sparc/kernel/pci_common.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/sparc/kernel/pci_common.c	2011-07-11 19:51:52.000000000 -0400
@@ -281,7 +281,7 @@
 	case 4:
 		*value = ret & 0xffffffff;
 		break;
-	};
+	}
 
 
 	return PCIBIOS_SUCCESSFUL;
@@ -456,7 +456,7 @@
 
 		default:
 			break;
-		};
+		}
 	}
 
 	if (!saw_io || !saw_mem) {
diff -druN linux-2.6.39-libre/arch/sparc/kernel/pci_msi.c linux-3.0-rc7-libre/arch/sparc/kernel/pci_msi.c
--- linux-2.6.39-libre/arch/sparc/kernel/pci_msi.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/sparc/kernel/pci_msi.c	2011-07-11 19:51:52.000000000 -0400
@@ -284,8 +284,9 @@
 
 	nid = pbm->numa_node;
 	if (nid != -1) {
-		cpumask_t numa_mask = *cpumask_of_node(nid);
+		cpumask_t numa_mask;
 
+		cpumask_copy(&numa_mask, cpumask_of_node(nid));
 		irq_set_affinity(irq, &numa_mask);
 	}
 	err = request_irq(irq, sparc64_msiq_interrupt, 0,
diff -druN linux-2.6.39-libre/arch/sparc/kernel/pci_schizo.c linux-3.0-rc7-libre/arch/sparc/kernel/pci_schizo.c
--- linux-2.6.39-libre/arch/sparc/kernel/pci_schizo.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/sparc/kernel/pci_schizo.c	2011-07-11 19:51:52.000000000 -0400
@@ -264,7 +264,7 @@
 		default:
 			type_string = "ECC Error";
 			break;
-		};
+		}
 		printk("%s: IOMMU Error, type[%s]\n",
 		       pbm->name, type_string);
 
@@ -319,7 +319,7 @@
 			default:
 				type_string = "ECC Error";
 				break;
-			};
+			}
 			printk("%s: IOMMU TAG(%d)[error(%s) ctx(%x) wr(%d) str(%d) "
 			       "sz(%dK) vpg(%08lx)]\n",
 			       pbm->name, i, type_string,
@@ -1328,7 +1328,7 @@
 	default:
 		chipset_name = "SCHIZO";
 		break;
-	};
+	}
 
 	/* For SCHIZO, three OBP regs:
 	 * 1) PBM controller regs
diff -druN linux-2.6.39-libre/arch/sparc/kernel/perf_event.c linux-3.0-rc7-libre/arch/sparc/kernel/perf_event.c
--- linux-2.6.39-libre/arch/sparc/kernel/perf_event.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/sparc/kernel/perf_event.c	2011-07-11 19:51:52.000000000 -0400
@@ -26,6 +26,7 @@
 #include <asm/nmi.h>
 #include <asm/pcr.h>
 
+#include "kernel.h"
 #include "kstack.h"
 
 /* Sparc64 chips have two performance counters, 32-bits each, with
diff -druN linux-2.6.39-libre/arch/sparc/kernel/process_32.c linux-3.0-rc7-libre/arch/sparc/kernel/process_32.c
--- linux-2.6.39-libre/arch/sparc/kernel/process_32.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/sparc/kernel/process_32.c	2011-07-11 19:51:52.000000000 -0400
@@ -128,8 +128,16 @@
         set_thread_flag(TIF_POLLING_NRFLAG);
 	/* endless idle loop with no priority at all */
 	while(1) {
-		while (!need_resched())
-			cpu_relax();
+#ifdef CONFIG_SPARC_LEON
+		if (pm_idle) {
+			while (!need_resched())
+				(*pm_idle)();
+		} else
+#endif
+		{
+			while (!need_resched())
+				cpu_relax();
+		}
 		preempt_enable_no_resched();
 		schedule();
 		preempt_disable();
diff -druN linux-2.6.39-libre/arch/sparc/kernel/prom_32.c linux-3.0-rc7-libre/arch/sparc/kernel/prom_32.c
--- linux-2.6.39-libre/arch/sparc/kernel/prom_32.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/sparc/kernel/prom_32.c	2011-07-11 19:51:52.000000000 -0400
@@ -326,7 +326,6 @@
 			of_console_options = NULL;
 	}
 
-	prom_printf(msg, of_console_path);
 	printk(msg, of_console_path);
 }
 
diff -druN linux-2.6.39-libre/arch/sparc/kernel/prom_irqtrans.c linux-3.0-rc7-libre/arch/sparc/kernel/prom_irqtrans.c
--- linux-2.6.39-libre/arch/sparc/kernel/prom_irqtrans.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/sparc/kernel/prom_irqtrans.c	2011-07-11 19:51:52.000000000 -0400
@@ -694,7 +694,7 @@
 		case 3:
 			iclr = reg_base + SYSIO_ICLR_SLOT3;
 			break;
-		};
+		}
 
 		iclr += ((unsigned long)sbus_level - 1UL) * 8UL;
 	}
diff -druN linux-2.6.39-libre/arch/sparc/kernel/psycho_common.c linux-3.0-rc7-libre/arch/sparc/kernel/psycho_common.c
--- linux-2.6.39-libre/arch/sparc/kernel/psycho_common.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/sparc/kernel/psycho_common.c	2011-07-11 19:51:52.000000000 -0400
@@ -228,7 +228,7 @@
 		default:
 			type_str = "ECC Error";
 			break;
-		};
+		}
 		printk(KERN_ERR "%s: IOMMU Error, type[%s]\n",
 		       pbm->name, type_str);
 
diff -druN linux-2.6.39-libre/arch/sparc/kernel/sbus.c linux-3.0-rc7-libre/arch/sparc/kernel/sbus.c
--- linux-2.6.39-libre/arch/sparc/kernel/sbus.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/sparc/kernel/sbus.c	2011-07-11 19:51:52.000000000 -0400
@@ -97,7 +97,7 @@
 
 	default:
 		return;
-	};
+	}
 
 	val = upa_readq(cfg_reg);
 	if (val & (1UL << 14UL)) {
@@ -244,7 +244,7 @@
 		case 3:
 			iclr = reg_base + SYSIO_ICLR_SLOT3;
 			break;
-		};
+		}
 
 		iclr += ((unsigned long)sbus_level - 1UL) * 8UL;
 	}
diff -druN linux-2.6.39-libre/arch/sparc/kernel/setup_32.c linux-3.0-rc7-libre/arch/sparc/kernel/setup_32.c
--- linux-2.6.39-libre/arch/sparc/kernel/setup_32.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/sparc/kernel/setup_32.c	2011-07-11 19:51:52.000000000 -0400
@@ -82,7 +82,7 @@
 			     "nop\n\t" : : "r" (&trapbase));
 
 	prom_printf("PROM SYNC COMMAND...\n");
-	show_free_areas();
+	show_free_areas(0);
 	if(current->pid != 0) {
 		local_irq_enable();
 		sys_sync();
@@ -103,16 +103,20 @@
 /* Exported for mm/init.c:paging_init. */
 unsigned long cmdline_memory_size __initdata = 0;
 
+/* which CPU booted us (0xff = not set) */
+unsigned char boot_cpu_id = 0xff; /* 0xff will make it into DATA section... */
+unsigned char boot_cpu_id4; /* boot_cpu_id << 2 */
+
 static void
 prom_console_write(struct console *con, const char *s, unsigned n)
 {
 	prom_write(s, n);
 }
 
-static struct console prom_debug_console = {
-	.name =		"debug",
+static struct console prom_early_console = {
+	.name =		"earlyprom",
 	.write =	prom_console_write,
-	.flags =	CON_PRINTBUFFER,
+	.flags =	CON_PRINTBUFFER | CON_BOOT,
 	.index =	-1,
 };
 
@@ -133,8 +137,7 @@
 		prom_halt();
 		break;
 	case 'p':
-		/* Use PROM debug console. */
-		register_console(&prom_debug_console);
+		/* Just ignore, this behavior is now the default.  */
 		break;
 	default:
 		printk("Unknown boot switch (-%c)\n", c);
@@ -215,6 +218,10 @@
 	strcpy(boot_command_line, *cmdline_p);
 	parse_early_param();
 
+	boot_flags_init(*cmdline_p);
+
+	register_console(&prom_early_console);
+
 	/* Set sparc_cpu_model */
 	sparc_cpu_model = sun_unknown;
 	if (!strcmp(&cputypval[0], "sun4 "))
@@ -260,12 +267,11 @@
 	default:
 		printk("UNKNOWN!\n");
 		break;
-	};
+	}
 
 #ifdef CONFIG_DUMMY_CONSOLE
 	conswitchp = &dummy_con;
 #endif
-	boot_flags_init(*cmdline_p);
 
 	idprom_init();
 	if (ARCH_SUN4C)
@@ -311,75 +317,6 @@
 	smp_setup_cpu_possible_map();
 }
 
-static int ncpus_probed;
-
-static int show_cpuinfo(struct seq_file *m, void *__unused)
-{
-	seq_printf(m,
-		   "cpu\t\t: %s\n"
-		   "fpu\t\t: %s\n"
-		   "promlib\t\t: Version %d Revision %d\n"
-		   "prom\t\t: %d.%d\n"
-		   "type\t\t: %s\n"
-		   "ncpus probed\t: %d\n"
-		   "ncpus active\t: %d\n"
-#ifndef CONFIG_SMP
-		   "CPU0Bogo\t: %lu.%02lu\n"
-		   "CPU0ClkTck\t: %ld\n"
-#endif
-		   ,
-		   sparc_cpu_type,
-		   sparc_fpu_type ,
-		   romvec->pv_romvers,
-		   prom_rev,
-		   romvec->pv_printrev >> 16,
-		   romvec->pv_printrev & 0xffff,
-		   &cputypval[0],
-		   ncpus_probed,
-		   num_online_cpus()
-#ifndef CONFIG_SMP
-		   , cpu_data(0).udelay_val/(500000/HZ),
-		   (cpu_data(0).udelay_val/(5000/HZ)) % 100,
-		   cpu_data(0).clock_tick
-#endif
-		);
-
-#ifdef CONFIG_SMP
-	smp_bogo(m);
-#endif
-	mmu_info(m);
-#ifdef CONFIG_SMP
-	smp_info(m);
-#endif
-	return 0;
-}
-
-static void *c_start(struct seq_file *m, loff_t *pos)
-{
-	/* The pointer we are returning is arbitrary,
-	 * it just has to be non-NULL and not IS_ERR
-	 * in the success case.
-	 */
-	return *pos == 0 ? &c_start : NULL;
-}
-
-static void *c_next(struct seq_file *m, void *v, loff_t *pos)
-{
-	++*pos;
-	return c_start(m, pos);
-}
-
-static void c_stop(struct seq_file *m, void *v)
-{
-}
-
-const struct seq_operations cpuinfo_op = {
-	.start =c_start,
-	.next =	c_next,
-	.stop =	c_stop,
-	.show =	show_cpuinfo,
-};
-
 extern int stop_a_enabled;
 
 void sun_do_break(void)
diff -druN linux-2.6.39-libre/arch/sparc/kernel/setup_64.c linux-3.0-rc7-libre/arch/sparc/kernel/setup_64.c
--- linux-2.6.39-libre/arch/sparc/kernel/setup_64.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/sparc/kernel/setup_64.c	2011-07-11 19:51:52.000000000 -0400
@@ -209,7 +209,7 @@
 		default:
 			prom_printf("Unknown cpu type, halting.\n");
 			prom_halt();
-		};
+		}
 
 		*(unsigned int *) (addr +  0) = insns[0];
 		wmb();
@@ -339,84 +339,6 @@
 	paging_init();
 }
 
-/* BUFFER is PAGE_SIZE bytes long. */
-
-extern void smp_info(struct seq_file *);
-extern void smp_bogo(struct seq_file *);
-extern void mmu_info(struct seq_file *);
-
-unsigned int dcache_parity_tl1_occurred;
-unsigned int icache_parity_tl1_occurred;
-
-int ncpus_probed;
-
-static int show_cpuinfo(struct seq_file *m, void *__unused)
-{
-	seq_printf(m, 
-		   "cpu\t\t: %s\n"
-		   "fpu\t\t: %s\n"
-		   "pmu\t\t: %s\n"
-		   "prom\t\t: %s\n"
-		   "type\t\t: %s\n"
-		   "ncpus probed\t: %d\n"
-		   "ncpus active\t: %d\n"
-		   "D$ parity tl1\t: %u\n"
-		   "I$ parity tl1\t: %u\n"
-#ifndef CONFIG_SMP
-		   "Cpu0ClkTck\t: %016lx\n"
-#endif
-		   ,
-		   sparc_cpu_type,
-		   sparc_fpu_type,
-		   sparc_pmu_type,
-		   prom_version,
-		   ((tlb_type == hypervisor) ?
-		    "sun4v" :
-		    "sun4u"),
-		   ncpus_probed,
-		   num_online_cpus(),
-		   dcache_parity_tl1_occurred,
-		   icache_parity_tl1_occurred
-#ifndef CONFIG_SMP
-		   , cpu_data(0).clock_tick
-#endif
-		);
-#ifdef CONFIG_SMP
-	smp_bogo(m);
-#endif
-	mmu_info(m);
-#ifdef CONFIG_SMP
-	smp_info(m);
-#endif
-	return 0;
-}
-
-static void *c_start(struct seq_file *m, loff_t *pos)
-{
-	/* The pointer we are returning is arbitrary,
-	 * it just has to be non-NULL and not IS_ERR
-	 * in the success case.
-	 */
-	return *pos == 0 ? &c_start : NULL;
-}
-
-static void *c_next(struct seq_file *m, void *v, loff_t *pos)
-{
-	++*pos;
-	return c_start(m, pos);
-}
-
-static void c_stop(struct seq_file *m, void *v)
-{
-}
-
-const struct seq_operations cpuinfo_op = {
-	.start =c_start,
-	.next =	c_next,
-	.stop =	c_stop,
-	.show =	show_cpuinfo,
-};
-
 extern int stop_a_enabled;
 
 void sun_do_break(void)
diff -druN linux-2.6.39-libre/arch/sparc/kernel/smp_32.c linux-3.0-rc7-libre/arch/sparc/kernel/smp_32.c
--- linux-2.6.39-libre/arch/sparc/kernel/smp_32.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/sparc/kernel/smp_32.c	2011-07-11 19:51:52.000000000 -0400
@@ -37,8 +37,6 @@
 #include "irq.h"
 
 volatile unsigned long cpu_callin_map[NR_CPUS] __cpuinitdata = {0,};
-unsigned char boot_cpu_id = 0;
-unsigned char boot_cpu_id4 = 0; /* boot_cpu_id << 2 */
 
 cpumask_t smp_commenced_mask = CPU_MASK_NONE;
 
@@ -116,7 +114,7 @@
 		printk("UNKNOWN!\n");
 		BUG();
 		break;
-	};
+	}
 }
 
 void cpu_panic(void)
@@ -129,13 +127,58 @@
 
 void smp_send_reschedule(int cpu)
 {
-	/* See sparc64 */
+	/*
+	 * CPU model dependent way of implementing IPI generation targeting
+	 * a single CPU. The trap handler needs only to do trap entry/return
+	 * to call schedule.
+	 */
+	BTFIXUP_CALL(smp_ipi_resched)(cpu);
 }
 
 void smp_send_stop(void)
 {
 }
 
+void arch_send_call_function_single_ipi(int cpu)
+{
+	/* trigger one IPI single call on one CPU */
+	BTFIXUP_CALL(smp_ipi_single)(cpu);
+}
+
+void arch_send_call_function_ipi_mask(const struct cpumask *mask)
+{
+	int cpu;
+
+	/* trigger IPI mask call on each CPU */
+	for_each_cpu(cpu, mask)
+		BTFIXUP_CALL(smp_ipi_mask_one)(cpu);
+}
+
+void smp_resched_interrupt(void)
+{
+	irq_enter();
+	scheduler_ipi();
+	local_cpu_data().irq_resched_count++;
+	irq_exit();
+	/* re-schedule routine called by interrupt return code. */
+}
+
+void smp_call_function_single_interrupt(void)
+{
+	irq_enter();
+	generic_smp_call_function_single_interrupt();
+	local_cpu_data().irq_call_count++;
+	irq_exit();
+}
+
+void smp_call_function_interrupt(void)
+{
+	irq_enter();
+	generic_smp_call_function_interrupt();
+	local_cpu_data().irq_call_count++;
+	irq_exit();
+}
+
 void smp_flush_cache_all(void)
 {
 	xc0((smpfunc_t) BTFIXUP_CALL(local_flush_cache_all));
@@ -151,9 +194,10 @@
 void smp_flush_cache_mm(struct mm_struct *mm)
 {
 	if(mm->context != NO_CONTEXT) {
-		cpumask_t cpu_mask = *mm_cpumask(mm);
-		cpu_clear(smp_processor_id(), cpu_mask);
-		if (!cpus_empty(cpu_mask))
+		cpumask_t cpu_mask;
+		cpumask_copy(&cpu_mask, mm_cpumask(mm));
+		cpumask_clear_cpu(smp_processor_id(), &cpu_mask);
+		if (!cpumask_empty(&cpu_mask))
 			xc1((smpfunc_t) BTFIXUP_CALL(local_flush_cache_mm), (unsigned long) mm);
 		local_flush_cache_mm(mm);
 	}
@@ -162,9 +206,10 @@
 void smp_flush_tlb_mm(struct mm_struct *mm)
 {
 	if(mm->context != NO_CONTEXT) {
-		cpumask_t cpu_mask = *mm_cpumask(mm);
-		cpu_clear(smp_processor_id(), cpu_mask);
-		if (!cpus_empty(cpu_mask)) {
+		cpumask_t cpu_mask;
+		cpumask_copy(&cpu_mask, mm_cpumask(mm));
+		cpumask_clear_cpu(smp_processor_id(), &cpu_mask);
+		if (!cpumask_empty(&cpu_mask)) {
 			xc1((smpfunc_t) BTFIXUP_CALL(local_flush_tlb_mm), (unsigned long) mm);
 			if(atomic_read(&mm->mm_users) == 1 && current->active_mm == mm)
 				cpumask_copy(mm_cpumask(mm),
@@ -180,9 +225,10 @@
 	struct mm_struct *mm = vma->vm_mm;
 
 	if (mm->context != NO_CONTEXT) {
-		cpumask_t cpu_mask = *mm_cpumask(mm);
-		cpu_clear(smp_processor_id(), cpu_mask);
-		if (!cpus_empty(cpu_mask))
+		cpumask_t cpu_mask;
+		cpumask_copy(&cpu_mask, mm_cpumask(mm));
+		cpumask_clear_cpu(smp_processor_id(), &cpu_mask);
+		if (!cpumask_empty(&cpu_mask))
 			xc3((smpfunc_t) BTFIXUP_CALL(local_flush_cache_range), (unsigned long) vma, start, end);
 		local_flush_cache_range(vma, start, end);
 	}
@@ -194,9 +240,10 @@
 	struct mm_struct *mm = vma->vm_mm;
 
 	if (mm->context != NO_CONTEXT) {
-		cpumask_t cpu_mask = *mm_cpumask(mm);
-		cpu_clear(smp_processor_id(), cpu_mask);
-		if (!cpus_empty(cpu_mask))
+		cpumask_t cpu_mask;
+		cpumask_copy(&cpu_mask, mm_cpumask(mm));
+		cpumask_clear_cpu(smp_processor_id(), &cpu_mask);
+		if (!cpumask_empty(&cpu_mask))
 			xc3((smpfunc_t) BTFIXUP_CALL(local_flush_tlb_range), (unsigned long) vma, start, end);
 		local_flush_tlb_range(vma, start, end);
 	}
@@ -207,9 +254,10 @@
 	struct mm_struct *mm = vma->vm_mm;
 
 	if(mm->context != NO_CONTEXT) {
-		cpumask_t cpu_mask = *mm_cpumask(mm);
-		cpu_clear(smp_processor_id(), cpu_mask);
-		if (!cpus_empty(cpu_mask))
+		cpumask_t cpu_mask;
+		cpumask_copy(&cpu_mask, mm_cpumask(mm));
+		cpumask_clear_cpu(smp_processor_id(), &cpu_mask);
+		if (!cpumask_empty(&cpu_mask))
 			xc2((smpfunc_t) BTFIXUP_CALL(local_flush_cache_page), (unsigned long) vma, page);
 		local_flush_cache_page(vma, page);
 	}
@@ -220,19 +268,15 @@
 	struct mm_struct *mm = vma->vm_mm;
 
 	if(mm->context != NO_CONTEXT) {
-		cpumask_t cpu_mask = *mm_cpumask(mm);
-		cpu_clear(smp_processor_id(), cpu_mask);
-		if (!cpus_empty(cpu_mask))
+		cpumask_t cpu_mask;
+		cpumask_copy(&cpu_mask, mm_cpumask(mm));
+		cpumask_clear_cpu(smp_processor_id(), &cpu_mask);
+		if (!cpumask_empty(&cpu_mask))
 			xc2((smpfunc_t) BTFIXUP_CALL(local_flush_tlb_page), (unsigned long) vma, page);
 		local_flush_tlb_page(vma, page);
 	}
 }
 
-void smp_reschedule_irq(void)
-{
-	set_need_resched();
-}
-
 void smp_flush_page_to_ram(unsigned long page)
 {
 	/* Current theory is that those who call this are the one's
@@ -249,9 +293,10 @@
 
 void smp_flush_sig_insns(struct mm_struct *mm, unsigned long insn_addr)
 {
-	cpumask_t cpu_mask = *mm_cpumask(mm);
-	cpu_clear(smp_processor_id(), cpu_mask);
-	if (!cpus_empty(cpu_mask))
+	cpumask_t cpu_mask;
+	cpumask_copy(&cpu_mask, mm_cpumask(mm));
+	cpumask_clear_cpu(smp_processor_id(), &cpu_mask);
+	if (!cpumask_empty(&cpu_mask))
 		xc2((smpfunc_t) BTFIXUP_CALL(local_flush_sig_insns), (unsigned long) mm, insn_addr);
 	local_flush_sig_insns(mm, insn_addr);
 }
@@ -329,7 +374,7 @@
 		printk("UNKNOWN!\n");
 		BUG();
 		break;
-	};
+	}
 }
 
 /* Set this up early so that things like the scheduler can init
@@ -402,10 +447,10 @@
 		printk("UNKNOWN!\n");
 		BUG();
 		break;
-	};
+	}
 
 	if (!ret) {
-		cpu_set(cpu, smp_commenced_mask);
+		cpumask_set_cpu(cpu, &smp_commenced_mask);
 		while (!cpu_online(cpu))
 			mb();
 	}
diff -druN linux-2.6.39-libre/arch/sparc/kernel/smp_64.c linux-3.0-rc7-libre/arch/sparc/kernel/smp_64.c
--- linux-2.6.39-libre/arch/sparc/kernel/smp_64.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/sparc/kernel/smp_64.c	2011-07-11 19:51:52.000000000 -0400
@@ -121,11 +121,11 @@
 	/* inform the notifiers about the new cpu */
 	notify_cpu_starting(cpuid);
 
-	while (!cpu_isset(cpuid, smp_commenced_mask))
+	while (!cpumask_test_cpu(cpuid, &smp_commenced_mask))
 		rmb();
 
 	ipi_call_lock_irq();
-	cpu_set(cpuid, cpu_online_map);
+	set_cpu_online(cpuid, true);
 	ipi_call_unlock_irq();
 
 	/* idle thread is expected to have preempt disabled */
@@ -785,7 +785,7 @@
 
 /* Send cross call to all processors mentioned in MASK_P
  * except self.  Really, there are only two cases currently,
- * "&cpu_online_map" and "&mm->cpu_vm_mask".
+ * "cpu_online_mask" and "mm_cpumask(mm)".
  */
 static void smp_cross_call_masked(unsigned long *func, u32 ctx, u64 data1, u64 data2, const cpumask_t *mask)
 {
@@ -797,7 +797,7 @@
 /* Send cross call to all processors except self. */
 static void smp_cross_call(unsigned long *func, u32 ctx, u64 data1, u64 data2)
 {
-	smp_cross_call_masked(func, ctx, data1, data2, &cpu_online_map);
+	smp_cross_call_masked(func, ctx, data1, data2, cpu_online_mask);
 }
 
 extern unsigned long xcall_sync_tick;
@@ -805,7 +805,7 @@
 static void smp_start_sync_tick_client(int cpu)
 {
 	xcall_deliver((u64) &xcall_sync_tick, 0, 0,
-		      &cpumask_of_cpu(cpu));
+		      cpumask_of(cpu));
 }
 
 extern unsigned long xcall_call_function;
@@ -820,7 +820,7 @@
 void arch_send_call_function_single_ipi(int cpu)
 {
 	xcall_deliver((u64) &xcall_call_function_single, 0, 0,
-		      &cpumask_of_cpu(cpu));
+		      cpumask_of(cpu));
 }
 
 void __irq_entry smp_call_function_client(int irq, struct pt_regs *regs)
@@ -918,7 +918,7 @@
 		}
 		if (data0) {
 			xcall_deliver(data0, __pa(pg_addr),
-				      (u64) pg_addr, &cpumask_of_cpu(cpu));
+				      (u64) pg_addr, cpumask_of(cpu));
 #ifdef CONFIG_DEBUG_DCFLUSH
 			atomic_inc(&dcpage_flushes_xcall);
 #endif
@@ -954,7 +954,7 @@
 	}
 	if (data0) {
 		xcall_deliver(data0, __pa(pg_addr),
-			      (u64) pg_addr, &cpu_online_map);
+			      (u64) pg_addr, cpu_online_mask);
 #ifdef CONFIG_DEBUG_DCFLUSH
 		atomic_inc(&dcpage_flushes_xcall);
 #endif
@@ -1197,32 +1197,32 @@
 	for_each_present_cpu(i) {
 		unsigned int j;
 
-		cpus_clear(cpu_core_map[i]);
+		cpumask_clear(&cpu_core_map[i]);
 		if (cpu_data(i).core_id == 0) {
-			cpu_set(i, cpu_core_map[i]);
+			cpumask_set_cpu(i, &cpu_core_map[i]);
 			continue;
 		}
 
 		for_each_present_cpu(j) {
 			if (cpu_data(i).core_id ==
 			    cpu_data(j).core_id)
-				cpu_set(j, cpu_core_map[i]);
+				cpumask_set_cpu(j, &cpu_core_map[i]);
 		}
 	}
 
 	for_each_present_cpu(i) {
 		unsigned int j;
 
-		cpus_clear(per_cpu(cpu_sibling_map, i));
+		cpumask_clear(&per_cpu(cpu_sibling_map, i));
 		if (cpu_data(i).proc_id == -1) {
-			cpu_set(i, per_cpu(cpu_sibling_map, i));
+			cpumask_set_cpu(i, &per_cpu(cpu_sibling_map, i));
 			continue;
 		}
 
 		for_each_present_cpu(j) {
 			if (cpu_data(i).proc_id ==
 			    cpu_data(j).proc_id)
-				cpu_set(j, per_cpu(cpu_sibling_map, i));
+				cpumask_set_cpu(j, &per_cpu(cpu_sibling_map, i));
 		}
 	}
 }
@@ -1232,10 +1232,10 @@
 	int ret = smp_boot_one_cpu(cpu);
 
 	if (!ret) {
-		cpu_set(cpu, smp_commenced_mask);
-		while (!cpu_isset(cpu, cpu_online_map))
+		cpumask_set_cpu(cpu, &smp_commenced_mask);
+		while (!cpu_online(cpu))
 			mb();
-		if (!cpu_isset(cpu, cpu_online_map)) {
+		if (!cpu_online(cpu)) {
 			ret = -ENODEV;
 		} else {
 			/* On SUN4V, writes to %tick and %stick are
@@ -1269,7 +1269,7 @@
 				tb->nonresum_mondo_pa, 0);
 	}
 
-	cpu_clear(cpu, smp_commenced_mask);
+	cpumask_clear_cpu(cpu, &smp_commenced_mask);
 	membar_safe("#Sync");
 
 	local_irq_disable();
@@ -1290,13 +1290,13 @@
 	cpuinfo_sparc *c;
 	int i;
 
-	for_each_cpu_mask(i, cpu_core_map[cpu])
-		cpu_clear(cpu, cpu_core_map[i]);
-	cpus_clear(cpu_core_map[cpu]);
+	for_each_cpu(i, &cpu_core_map[cpu])
+		cpumask_clear_cpu(cpu, &cpu_core_map[i]);
+	cpumask_clear(&cpu_core_map[cpu]);
 
-	for_each_cpu_mask(i, per_cpu(cpu_sibling_map, cpu))
-		cpu_clear(cpu, per_cpu(cpu_sibling_map, i));
-	cpus_clear(per_cpu(cpu_sibling_map, cpu));
+	for_each_cpu(i, &per_cpu(cpu_sibling_map, cpu))
+		cpumask_clear_cpu(cpu, &per_cpu(cpu_sibling_map, i));
+	cpumask_clear(&per_cpu(cpu_sibling_map, cpu));
 
 	c = &cpu_data(cpu);
 
@@ -1313,7 +1313,7 @@
 	local_irq_disable();
 
 	ipi_call_lock();
-	cpu_clear(cpu, cpu_online_map);
+	set_cpu_online(cpu, false);
 	ipi_call_unlock();
 
 	cpu_map_rebuild();
@@ -1327,11 +1327,11 @@
 
 	for (i = 0; i < 100; i++) {
 		smp_rmb();
-		if (!cpu_isset(cpu, smp_commenced_mask))
+		if (!cpumask_test_cpu(cpu, &smp_commenced_mask))
 			break;
 		msleep(100);
 	}
-	if (cpu_isset(cpu, smp_commenced_mask)) {
+	if (cpumask_test_cpu(cpu, &smp_commenced_mask)) {
 		printk(KERN_ERR "CPU %u didn't die...\n", cpu);
 	} else {
 #if defined(CONFIG_SUN_LDOMS)
@@ -1341,7 +1341,7 @@
 		do {
 			hv_err = sun4v_cpu_stop(cpu);
 			if (hv_err == HV_EOK) {
-				cpu_clear(cpu, cpu_present_map);
+				set_cpu_present(cpu, false);
 				break;
 			}
 		} while (--limit > 0);
@@ -1362,12 +1362,13 @@
 void smp_send_reschedule(int cpu)
 {
 	xcall_deliver((u64) &xcall_receive_signal, 0, 0,
-		      &cpumask_of_cpu(cpu));
+		      cpumask_of(cpu));
 }
 
 void __irq_entry smp_receive_signal_client(int irq, struct pt_regs *regs)
 {
 	clear_softint(1 << irq);
+	scheduler_ipi();
 }
 
 /* This is a nop because we capture all other cpus
diff -druN linux-2.6.39-libre/arch/sparc/kernel/sun4c_irq.c linux-3.0-rc7-libre/arch/sparc/kernel/sun4c_irq.c
--- linux-2.6.39-libre/arch/sparc/kernel/sun4c_irq.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/sparc/kernel/sun4c_irq.c	2011-07-11 19:51:52.000000000 -0400
@@ -65,62 +65,94 @@
  */
 unsigned char __iomem *interrupt_enable;
 
-static void sun4c_disable_irq(unsigned int irq_nr)
+static void sun4c_mask_irq(struct irq_data *data)
 {
-	unsigned long flags;
-	unsigned char current_mask, new_mask;
+	unsigned long mask = (unsigned long)data->chip_data;
 
-	local_irq_save(flags);
-	irq_nr &= (NR_IRQS - 1);
-	current_mask = sbus_readb(interrupt_enable);
-	switch (irq_nr) {
-	case 1:
-		new_mask = ((current_mask) & (~(SUN4C_INT_E1)));
-		break;
-	case 8:
-		new_mask = ((current_mask) & (~(SUN4C_INT_E8)));
-		break;
-	case 10:
-		new_mask = ((current_mask) & (~(SUN4C_INT_E10)));
-		break;
-	case 14:
-		new_mask = ((current_mask) & (~(SUN4C_INT_E14)));
-		break;
-	default:
+	if (mask) {
+		unsigned long flags;
+
+		local_irq_save(flags);
+		mask = sbus_readb(interrupt_enable) & ~mask;
+		sbus_writeb(mask, interrupt_enable);
 		local_irq_restore(flags);
-		return;
 	}
-	sbus_writeb(new_mask, interrupt_enable);
-	local_irq_restore(flags);
 }
 
-static void sun4c_enable_irq(unsigned int irq_nr)
+static void sun4c_unmask_irq(struct irq_data *data)
 {
-	unsigned long flags;
-	unsigned char current_mask, new_mask;
+	unsigned long mask = (unsigned long)data->chip_data;
 
-	local_irq_save(flags);
-	irq_nr &= (NR_IRQS - 1);
-	current_mask = sbus_readb(interrupt_enable);
-	switch (irq_nr) {
-	case 1:
-		new_mask = ((current_mask) | SUN4C_INT_E1);
-		break;
-	case 8:
-		new_mask = ((current_mask) | SUN4C_INT_E8);
-		break;
-	case 10:
-		new_mask = ((current_mask) | SUN4C_INT_E10);
-		break;
-	case 14:
-		new_mask = ((current_mask) | SUN4C_INT_E14);
-		break;
-	default:
+	if (mask) {
+		unsigned long flags;
+
+		local_irq_save(flags);
+		mask = sbus_readb(interrupt_enable) | mask;
+		sbus_writeb(mask, interrupt_enable);
 		local_irq_restore(flags);
-		return;
 	}
-	sbus_writeb(new_mask, interrupt_enable);
-	local_irq_restore(flags);
+}
+
+static unsigned int sun4c_startup_irq(struct irq_data *data)
+{
+	irq_link(data->irq);
+	sun4c_unmask_irq(data);
+
+	return 0;
+}
+
+static void sun4c_shutdown_irq(struct irq_data *data)
+{
+	sun4c_mask_irq(data);
+	irq_unlink(data->irq);
+}
+
+static struct irq_chip sun4c_irq = {
+	.name		= "sun4c",
+	.irq_startup	= sun4c_startup_irq,
+	.irq_shutdown	= sun4c_shutdown_irq,
+	.irq_mask	= sun4c_mask_irq,
+	.irq_unmask	= sun4c_unmask_irq,
+};
+
+static unsigned int sun4c_build_device_irq(struct platform_device *op,
+					   unsigned int real_irq)
+{
+	 unsigned int irq;
+
+	if (real_irq >= 16) {
+		prom_printf("Bogus sun4c IRQ %u\n", real_irq);
+		prom_halt();
+	}
+
+	irq = irq_alloc(real_irq, real_irq);
+	if (irq) {
+		unsigned long mask = 0UL;
+
+		switch (real_irq) {
+		case 1:
+			mask = SUN4C_INT_E1;
+			break;
+		case 8:
+			mask = SUN4C_INT_E8;
+			break;
+		case 10:
+			mask = SUN4C_INT_E10;
+			break;
+		case 14:
+			mask = SUN4C_INT_E14;
+			break;
+		default:
+			/* All the rest are either always enabled,
+			 * or are for signalling software interrupts.
+			 */
+			break;
+		}
+		irq_set_chip_and_handler_name(irq, &sun4c_irq,
+		                              handle_level_irq, "level");
+		irq_set_chip_data(irq, (void *)mask);
+	}
+	return irq;
 }
 
 struct sun4c_timer_info {
@@ -144,8 +176,9 @@
 
 static void __init sun4c_init_timers(irq_handler_t counter_fn)
 {
-	const struct linux_prom_irqs *irq;
+	const struct linux_prom_irqs *prom_irqs;
 	struct device_node *dp;
+	unsigned int irq;
 	const u32 *addr;
 	int err;
 
@@ -163,9 +196,9 @@
 
 	sun4c_timers = (void __iomem *) (unsigned long) addr[0];
 
-	irq = of_get_property(dp, "intr", NULL);
+	prom_irqs = of_get_property(dp, "intr", NULL);
 	of_node_put(dp);
-	if (!irq) {
+	if (!prom_irqs) {
 		prom_printf("sun4c_init_timers: No intr property\n");
 		prom_halt();
 	}
@@ -178,15 +211,15 @@
 
 	master_l10_counter = &sun4c_timers->l10_count;
 
-	err = request_irq(irq[0].pri, counter_fn,
-			  (IRQF_DISABLED | SA_STATIC_ALLOC),
-			  "timer", NULL);
+	irq = sun4c_build_device_irq(NULL, prom_irqs[0].pri);
+	err = request_irq(irq, counter_fn, IRQF_TIMER, "timer", NULL);
 	if (err) {
 		prom_printf("sun4c_init_timers: request_irq() fails with %d\n", err);
 		prom_halt();
 	}
 
-	sun4c_disable_irq(irq[1].pri);
+	/* disable timer interrupt */
+	sun4c_mask_irq(irq_get_irq_data(irq));
 }
 
 #ifdef CONFIG_SMP
@@ -215,14 +248,11 @@
 
 	interrupt_enable = (void __iomem *) (unsigned long) addr[0];
 
-	BTFIXUPSET_CALL(enable_irq, sun4c_enable_irq, BTFIXUPCALL_NORM);
-	BTFIXUPSET_CALL(disable_irq, sun4c_disable_irq, BTFIXUPCALL_NORM);
-	BTFIXUPSET_CALL(enable_pil_irq, sun4c_enable_irq, BTFIXUPCALL_NORM);
-	BTFIXUPSET_CALL(disable_pil_irq, sun4c_disable_irq, BTFIXUPCALL_NORM);
 	BTFIXUPSET_CALL(clear_clock_irq, sun4c_clear_clock_irq, BTFIXUPCALL_NORM);
 	BTFIXUPSET_CALL(load_profile_irq, sun4c_load_profile_irq, BTFIXUPCALL_NOP);
 
-	sparc_irq_config.init_timers = sun4c_init_timers;
+	sparc_irq_config.init_timers      = sun4c_init_timers;
+	sparc_irq_config.build_device_irq = sun4c_build_device_irq;
 
 #ifdef CONFIG_SMP
 	BTFIXUPSET_CALL(set_cpu_int, sun4c_nop, BTFIXUPCALL_NOP);
diff -druN linux-2.6.39-libre/arch/sparc/kernel/sun4d_irq.c linux-3.0-rc7-libre/arch/sparc/kernel/sun4d_irq.c
--- linux-2.6.39-libre/arch/sparc/kernel/sun4d_irq.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/sparc/kernel/sun4d_irq.c	2011-07-11 19:51:52.000000000 -0400
@@ -14,6 +14,7 @@
 #include <asm/io.h>
 #include <asm/sbi.h>
 #include <asm/cacheflush.h>
+#include <asm/setup.h>
 
 #include "kernel.h"
 #include "irq.h"
@@ -22,22 +23,20 @@
  * cpu local.  CPU local interrupts cover the timer interrupts
  * and whatnot, and we encode those as normal PILs between
  * 0 and 15.
- *
- * SBUS interrupts are encoded integers including the board number
- * (plus one), the SBUS level, and the SBUS slot number.  Sun4D
- * IRQ dispatch is done by:
- *
- * 1) Reading the BW local interrupt table in order to get the bus
- *    interrupt mask.
- *
- *    This table is indexed by SBUS interrupt level which can be
- *    derived from the PIL we got interrupted on.
- *
- * 2) For each bus showing interrupt pending from #1, read the
- *    SBI interrupt state register.  This will indicate which slots
- *    have interrupts pending for that SBUS interrupt level.
+ * SBUS interrupts are encodes as a combination of board, level and slot.
  */
 
+struct sun4d_handler_data {
+	unsigned int cpuid;    /* target cpu */
+	unsigned int real_irq; /* interrupt level */
+};
+
+
+static unsigned int sun4d_encode_irq(int board, int lvl, int slot)
+{
+	return (board + 1) << 5 | (lvl << 2) | slot;
+}
+
 struct sun4d_timer_regs {
 	u32	l10_timer_limit;
 	u32	l10_cur_countx;
@@ -48,17 +47,12 @@
 
 static struct sun4d_timer_regs __iomem *sun4d_timers;
 
-#define TIMER_IRQ	10
-
-#define MAX_STATIC_ALLOC	4
-static unsigned char sbus_tid[32];
-
-static struct irqaction *irq_action[NR_IRQS];
+#define SUN4D_TIMER_IRQ        10
 
-static struct sbus_action {
-	struct irqaction *action;
-	/* For SMP this needs to be extended */
-} *sbus_actions;
+/* Specify which cpu handle interrupts from which board.
+ * Index is board - value is cpu.
+ */
+static unsigned char board_to_cpu[32];
 
 static int pil_to_sbus[] = {
 	0,
@@ -79,152 +73,77 @@
 	0,
 };
 
-static int sbus_to_pil[] = {
-	0,
-	2,
-	3,
-	5,
-	7,
-	9,
-	11,
-	13,
-};
-
-static int nsbi;
-
 /* Exported for sun4d_smp.c */
 DEFINE_SPINLOCK(sun4d_imsk_lock);
 
-int show_sun4d_interrupts(struct seq_file *p, void *v)
+/* SBUS interrupts are encoded integers including the board number
+ * (plus one), the SBUS level, and the SBUS slot number.  Sun4D
+ * IRQ dispatch is done by:
+ *
+ * 1) Reading the BW local interrupt table in order to get the bus
+ *    interrupt mask.
+ *
+ *    This table is indexed by SBUS interrupt level which can be
+ *    derived from the PIL we got interrupted on.
+ *
+ * 2) For each bus showing interrupt pending from #1, read the
+ *    SBI interrupt state register.  This will indicate which slots
+ *    have interrupts pending for that SBUS interrupt level.
+ *
+ * 3) Call the genreric IRQ support.
+ */
+static void sun4d_sbus_handler_irq(int sbusl)
 {
-	int i = *(loff_t *) v, j = 0, k = 0, sbusl;
-	struct irqaction *action;
-	unsigned long flags;
-#ifdef CONFIG_SMP
-	int x;
-#endif
+	unsigned int bus_mask;
+	unsigned int sbino, slot;
+	unsigned int sbil;
 
-	spin_lock_irqsave(&irq_action_lock, flags);
-	if (i < NR_IRQS) {
-		sbusl = pil_to_sbus[i];
-		if (!sbusl) {
-			action = *(i + irq_action);
-			if (!action)
-				goto out_unlock;
-		} else {
-			for (j = 0; j < nsbi; j++) {
-				for (k = 0; k < 4; k++)
-					action = sbus_actions[(j << 5) + (sbusl << 2) + k].action;
-					if (action)
-						goto found_it;
-			}
-			goto out_unlock;
-		}
-found_it:	seq_printf(p, "%3d: ", i);
-#ifndef CONFIG_SMP
-		seq_printf(p, "%10u ", kstat_irqs(i));
-#else
-		for_each_online_cpu(x)
-			seq_printf(p, "%10u ",
-			       kstat_cpu(cpu_logical_map(x)).irqs[i]);
-#endif
-		seq_printf(p, "%c %s",
-			(action->flags & IRQF_DISABLED) ? '+' : ' ',
-			action->name);
-		action = action->next;
-		for (;;) {
-			for (; action; action = action->next) {
-				seq_printf(p, ",%s %s",
-					(action->flags & IRQF_DISABLED) ? " +" : "",
-					action->name);
-			}
-			if (!sbusl)
-				break;
-			k++;
-			if (k < 4) {
-				action = sbus_actions[(j << 5) + (sbusl << 2) + k].action;
-			} else {
-				j++;
-				if (j == nsbi)
-					break;
-				k = 0;
-				action = sbus_actions[(j << 5) + (sbusl << 2)].action;
-			}
-		}
-		seq_putc(p, '\n');
-	}
-out_unlock:
-	spin_unlock_irqrestore(&irq_action_lock, flags);
-	return 0;
-}
+	bus_mask = bw_get_intr_mask(sbusl) & 0x3ffff;
+	bw_clear_intr_mask(sbusl, bus_mask);
 
-void sun4d_free_irq(unsigned int irq, void *dev_id)
-{
-	struct irqaction *action, **actionp;
-	struct irqaction *tmp = NULL;
-	unsigned long flags;
+	sbil = (sbusl << 2);
+	/* Loop for each pending SBI */
+	for (sbino = 0; bus_mask; sbino++, bus_mask >>= 1) {
+		unsigned int idx, mask;
 
-	spin_lock_irqsave(&irq_action_lock, flags);
-	if (irq < 15)
-		actionp = irq + irq_action;
-	else
-		actionp = &(sbus_actions[irq - (1 << 5)].action);
-	action = *actionp;
-	if (!action) {
-		printk(KERN_ERR "Trying to free free IRQ%d\n", irq);
-		goto out_unlock;
-	}
-	if (dev_id) {
-		for (; action; action = action->next) {
-			if (action->dev_id == dev_id)
-				break;
-			tmp = action;
-		}
-		if (!action) {
-			printk(KERN_ERR "Trying to free free shared IRQ%d\n",
-			       irq);
-			goto out_unlock;
-		}
-	} else if (action->flags & IRQF_SHARED) {
-		printk(KERN_ERR "Trying to free shared IRQ%d with NULL device ID\n",
-		       irq);
-		goto out_unlock;
-	}
-	if (action->flags & SA_STATIC_ALLOC) {
-		/*
-		 * This interrupt is marked as specially allocated
-		 * so it is a bad idea to free it.
+		if (!(bus_mask & 1))
+			continue;
+		/* XXX This seems to ACK the irq twice.  acquire_sbi()
+		 * XXX uses swap, therefore this writes 0xf << sbil,
+		 * XXX then later release_sbi() will write the individual
+		 * XXX bits which were set again.
 		 */
-		printk(KERN_ERR "Attempt to free statically allocated IRQ%d (%s)\n",
-		       irq, action->name);
-		goto out_unlock;
-	}
-
-	if (tmp)
-		tmp->next = action->next;
-	else
-		*actionp = action->next;
-
-	spin_unlock_irqrestore(&irq_action_lock, flags);
+		mask = acquire_sbi(SBI2DEVID(sbino), 0xf << sbil);
+		mask &= (0xf << sbil);
 
-	synchronize_irq(irq);
+		/* Loop for each pending SBI slot */
+		slot = (1 << sbil);
+		for (idx = 0; mask != 0; idx++, slot <<= 1) {
+			unsigned int pil;
+			struct irq_bucket *p;
 
-	spin_lock_irqsave(&irq_action_lock, flags);
+			if (!(mask & slot))
+				continue;
 
-	kfree(action);
+			mask &= ~slot;
+			pil = sun4d_encode_irq(sbino, sbusl, idx);
 
-	if (!(*actionp))
-		__disable_irq(irq);
+			p = irq_map[pil];
+			while (p) {
+				struct irq_bucket *next;
 
-out_unlock:
-	spin_unlock_irqrestore(&irq_action_lock, flags);
+				next = p->next;
+				generic_handle_irq(p->irq);
+				p = next;
+			}
+			release_sbi(SBI2DEVID(sbino), slot);
+		}
+	}
 }
 
 void sun4d_handler_irq(int pil, struct pt_regs *regs)
 {
 	struct pt_regs *old_regs;
-	struct irqaction *action;
-	int cpu = smp_processor_id();
 	/* SBUS IRQ level (1 - 7) */
 	int sbusl = pil_to_sbus[pil];
 
@@ -233,160 +152,96 @@
 
 	cc_set_iclr(1 << pil);
 
+#ifdef CONFIG_SMP
+	/*
+	 * Check IPI data structures after IRQ has been cleared. Hard and Soft
+	 * IRQ can happen at the same time, so both cases are always handled.
+	 */
+	if (pil == SUN4D_IPI_IRQ)
+		sun4d_ipi_interrupt();
+#endif
+
 	old_regs = set_irq_regs(regs);
 	irq_enter();
-	kstat_cpu(cpu).irqs[pil]++;
-	if (!sbusl) {
-		action = *(pil + irq_action);
-		if (!action)
-			unexpected_irq(pil, NULL, regs);
-		do {
-			action->handler(pil, action->dev_id);
-			action = action->next;
-		} while (action);
-	} else {
-		int bus_mask = bw_get_intr_mask(sbusl) & 0x3ffff;
-		int sbino;
-		struct sbus_action *actionp;
-		unsigned mask, slot;
-		int sbil = (sbusl << 2);
-
-		bw_clear_intr_mask(sbusl, bus_mask);
+	if (sbusl == 0) {
+		/* cpu interrupt */
+		struct irq_bucket *p;
 
-		/* Loop for each pending SBI */
-		for (sbino = 0; bus_mask; sbino++, bus_mask >>= 1)
-			if (bus_mask & 1) {
-				mask = acquire_sbi(SBI2DEVID(sbino), 0xf << sbil);
-				mask &= (0xf << sbil);
-				actionp = sbus_actions + (sbino << 5) + (sbil);
-				/* Loop for each pending SBI slot */
-				for (slot = (1 << sbil); mask; slot <<= 1, actionp++)
-					if (mask & slot) {
-						mask &= ~slot;
-						action = actionp->action;
+		p = irq_map[pil];
+		while (p) {
+			struct irq_bucket *next;
 
-						if (!action)
-							unexpected_irq(pil, NULL, regs);
-						do {
-							action->handler(pil, action->dev_id);
-							action = action->next;
-						} while (action);
-						release_sbi(SBI2DEVID(sbino), slot);
-					}
-			}
+			next = p->next;
+			generic_handle_irq(p->irq);
+			p = next;
+		}
+	} else {
+		/* SBUS interrupt */
+		sun4d_sbus_handler_irq(sbusl);
 	}
 	irq_exit();
 	set_irq_regs(old_regs);
 }
 
-int sun4d_request_irq(unsigned int irq,
-		irq_handler_t handler,
-		unsigned long irqflags, const char *devname, void *dev_id)
+
+static void sun4d_mask_irq(struct irq_data *data)
 {
-	struct irqaction *action, *tmp = NULL, **actionp;
+	struct sun4d_handler_data *handler_data = data->handler_data;
+	unsigned int real_irq;
+#ifdef CONFIG_SMP
+	int cpuid = handler_data->cpuid;
 	unsigned long flags;
-	int ret;
-
-	if (irq > 14 && irq < (1 << 5)) {
-		ret = -EINVAL;
-		goto out;
-	}
-
-	if (!handler) {
-		ret = -EINVAL;
-		goto out;
-	}
-
-	spin_lock_irqsave(&irq_action_lock, flags);
-
-	if (irq >= (1 << 5))
-		actionp = &(sbus_actions[irq - (1 << 5)].action);
-	else
-		actionp = irq + irq_action;
-	action = *actionp;
-
-	if (action) {
-		if ((action->flags & IRQF_SHARED) && (irqflags & IRQF_SHARED)) {
-			for (tmp = action; tmp->next; tmp = tmp->next)
-				/* find last entry - tmp used below */;
-		} else {
-			ret = -EBUSY;
-			goto out_unlock;
-		}
-		if ((action->flags & IRQF_DISABLED) ^ (irqflags & IRQF_DISABLED)) {
-			printk(KERN_ERR "Attempt to mix fast and slow interrupts on IRQ%d denied\n",
-			       irq);
-			ret = -EBUSY;
-			goto out_unlock;
-		}
-		action = NULL;		/* Or else! */
-	}
-
-	/* If this is flagged as statically allocated then we use our
-	 * private struct which is never freed.
-	 */
-	if (irqflags & SA_STATIC_ALLOC) {
-		if (static_irq_count < MAX_STATIC_ALLOC)
-			action = &static_irqaction[static_irq_count++];
-		else
-			printk(KERN_ERR "Request for IRQ%d (%s) SA_STATIC_ALLOC failed using kmalloc\n",
-			       irq, devname);
-	}
-
-	if (action == NULL)
-		action = kmalloc(sizeof(struct irqaction), GFP_ATOMIC);
-
-	if (!action) {
-		ret = -ENOMEM;
-		goto out_unlock;
-	}
-
-	action->handler = handler;
-	action->flags = irqflags;
-	action->name = devname;
-	action->next = NULL;
-	action->dev_id = dev_id;
-
-	if (tmp)
-		tmp->next = action;
-	else
-		*actionp = action;
-
-	__enable_irq(irq);
-
-	ret = 0;
-out_unlock:
-	spin_unlock_irqrestore(&irq_action_lock, flags);
-out:
-	return ret;
+#endif
+	real_irq = handler_data->real_irq;
+#ifdef CONFIG_SMP
+	spin_lock_irqsave(&sun4d_imsk_lock, flags);
+	cc_set_imsk_other(cpuid, cc_get_imsk_other(cpuid) | (1 << real_irq));
+	spin_unlock_irqrestore(&sun4d_imsk_lock, flags);
+#else
+	cc_set_imsk(cc_get_imsk() | (1 << real_irq));
+#endif
 }
 
-static void sun4d_disable_irq(unsigned int irq)
+static void sun4d_unmask_irq(struct irq_data *data)
 {
-	int tid = sbus_tid[(irq >> 5) - 1];
+	struct sun4d_handler_data *handler_data = data->handler_data;
+	unsigned int real_irq;
+#ifdef CONFIG_SMP
+	int cpuid = handler_data->cpuid;
 	unsigned long flags;
+#endif
+	real_irq = handler_data->real_irq;
 
-	if (irq < NR_IRQS)
-		return;
-
+#ifdef CONFIG_SMP
 	spin_lock_irqsave(&sun4d_imsk_lock, flags);
-	cc_set_imsk_other(tid, cc_get_imsk_other(tid) | (1 << sbus_to_pil[(irq >> 2) & 7]));
+	cc_set_imsk_other(cpuid, cc_get_imsk_other(cpuid) & ~(1 << real_irq));
 	spin_unlock_irqrestore(&sun4d_imsk_lock, flags);
+#else
+	cc_set_imsk(cc_get_imsk() & ~(1 << real_irq));
+#endif
 }
 
-static void sun4d_enable_irq(unsigned int irq)
+static unsigned int sun4d_startup_irq(struct irq_data *data)
 {
-	int tid = sbus_tid[(irq >> 5) - 1];
-	unsigned long flags;
-
-	if (irq < NR_IRQS)
-		return;
+	irq_link(data->irq);
+	sun4d_unmask_irq(data);
+	return 0;
+}
 
-	spin_lock_irqsave(&sun4d_imsk_lock, flags);
-	cc_set_imsk_other(tid, cc_get_imsk_other(tid) & ~(1 << sbus_to_pil[(irq >> 2) & 7]));
-	spin_unlock_irqrestore(&sun4d_imsk_lock, flags);
+static void sun4d_shutdown_irq(struct irq_data *data)
+{
+	sun4d_mask_irq(data);
+	irq_unlink(data->irq);
 }
 
+struct irq_chip sun4d_irq = {
+	.name		= "sun4d",
+	.irq_startup	= sun4d_startup_irq,
+	.irq_shutdown	= sun4d_shutdown_irq,
+	.irq_unmask	= sun4d_unmask_irq,
+	.irq_mask	= sun4d_mask_irq,
+};
+
 #ifdef CONFIG_SMP
 static void sun4d_set_cpu_int(int cpu, int level)
 {
@@ -413,7 +268,7 @@
 	for_each_node_by_name(dp, "sbi") {
 		int devid = of_getintprop_default(dp, "device-id", 0);
 		int board = of_getintprop_default(dp, "board#", 0);
-		sbus_tid[board] = cpuid;
+		board_to_cpu[board] = cpuid;
 		set_sbi_tid(devid, cpuid << 3);
 	}
 	printk(KERN_ERR "All sbus IRQs directed to CPU%d\n", cpuid);
@@ -440,25 +295,68 @@
 	}
 }
 
+unsigned int _sun4d_build_device_irq(unsigned int real_irq,
+                                     unsigned int pil,
+                                     unsigned int board)
+{
+	struct sun4d_handler_data *handler_data;
+	unsigned int irq;
+
+	irq = irq_alloc(real_irq, pil);
+	if (irq == 0) {
+		prom_printf("IRQ: allocate for %d %d %d failed\n",
+			real_irq, pil, board);
+		goto err_out;
+	}
+
+	handler_data = irq_get_handler_data(irq);
+	if (unlikely(handler_data))
+		goto err_out;
+
+	handler_data = kzalloc(sizeof(struct sun4d_handler_data), GFP_ATOMIC);
+	if (unlikely(!handler_data)) {
+		prom_printf("IRQ: kzalloc(sun4d_handler_data) failed.\n");
+		prom_halt();
+	}
+	handler_data->cpuid    = board_to_cpu[board];
+	handler_data->real_irq = real_irq;
+	irq_set_chip_and_handler_name(irq, &sun4d_irq,
+	                              handle_level_irq, "level");
+	irq_set_handler_data(irq, handler_data);
+
+err_out:
+	return irq;
+}
+
+
+
 unsigned int sun4d_build_device_irq(struct platform_device *op,
                                     unsigned int real_irq)
 {
-	static int pil_to_sbus[] = {
-		0, 0, 1, 2, 0, 3, 0, 4, 0, 5, 0, 6, 0, 7, 0, 0,
-	};
 	struct device_node *dp = op->dev.of_node;
-	struct device_node *io_unit, *sbi = dp->parent;
+	struct device_node *board_parent, *bus = dp->parent;
+	char *bus_connection;
 	const struct linux_prom_registers *regs;
+	unsigned int pil;
+	unsigned int irq;
 	int board, slot;
 	int sbusl;
 
-	while (sbi) {
-		if (!strcmp(sbi->name, "sbi"))
+	irq = real_irq;
+	while (bus) {
+		if (!strcmp(bus->name, "sbi")) {
+			bus_connection = "io-unit";
 			break;
+		}
 
-		sbi = sbi->parent;
+		if (!strcmp(bus->name, "bootbus")) {
+			bus_connection = "cpu-unit";
+			break;
+		}
+
+		bus = bus->parent;
 	}
-	if (!sbi)
+	if (!bus)
 		goto err_out;
 
 	regs = of_get_property(dp, "reg", NULL);
@@ -468,28 +366,39 @@
 	slot = regs->which_io;
 
 	/*
-	 *  If SBI's parent is not io-unit or the io-unit lacks
-	 * a "board#" property, something is very wrong.
+	 * If Bus nodes parent is not io-unit/cpu-unit or the io-unit/cpu-unit
+	 * lacks a "board#" property, something is very wrong.
 	 */
-	if (!sbi->parent || strcmp(sbi->parent->name, "io-unit")) {
-		printk("%s: Error, parent is not io-unit.\n", sbi->full_name);
+	if (!bus->parent || strcmp(bus->parent->name, bus_connection)) {
+		printk(KERN_ERR "%s: Error, parent is not %s.\n",
+			bus->full_name, bus_connection);
 		goto err_out;
 	}
-	io_unit = sbi->parent;
-	board = of_getintprop_default(io_unit, "board#", -1);
+	board_parent = bus->parent;
+	board = of_getintprop_default(board_parent, "board#", -1);
 	if (board == -1) {
-		printk("%s: Error, lacks board# property.\n", io_unit->full_name);
+		printk(KERN_ERR "%s: Error, lacks board# property.\n",
+			board_parent->full_name);
 		goto err_out;
 	}
 
 	sbusl = pil_to_sbus[real_irq];
 	if (sbusl)
-		return (((board + 1) << 5) + (sbusl << 2) + slot);
+		pil = sun4d_encode_irq(board, sbusl, slot);
+	else
+		pil = real_irq;
 
+	irq = _sun4d_build_device_irq(real_irq, pil, board);
 err_out:
-	return real_irq;
+	return irq;
+}
+
+unsigned int sun4d_build_timer_irq(unsigned int board, unsigned int real_irq)
+{
+	return _sun4d_build_device_irq(real_irq, real_irq, board);
 }
 
+
 static void __init sun4d_fixup_trap_table(void)
 {
 #ifdef CONFIG_SMP
@@ -518,8 +427,10 @@
 {
 	struct device_node *dp;
 	struct resource res;
+	unsigned int irq;
 	const u32 *reg;
 	int err;
+	int board;
 
 	dp = of_find_node_by_name(NULL, "cpu-unit");
 	if (!dp) {
@@ -532,12 +443,19 @@
 	 * bootbus.
 	 */
 	reg = of_get_property(dp, "reg", NULL);
-	of_node_put(dp);
 	if (!reg) {
 		prom_printf("sun4d_init_timers: No reg property\n");
 		prom_halt();
 	}
 
+	board = of_getintprop_default(dp, "board#", -1);
+	if (board == -1) {
+		prom_printf("sun4d_init_timers: No board# property on cpu-unit\n");
+		prom_halt();
+	}
+
+	of_node_put(dp);
+
 	res.start = reg[1];
 	res.end = reg[2] - 1;
 	res.flags = reg[0] & 0xff;
@@ -552,9 +470,8 @@
 
 	master_l10_counter = &sun4d_timers->l10_cur_count;
 
-	err = request_irq(TIMER_IRQ, counter_fn,
-			  (IRQF_DISABLED | SA_STATIC_ALLOC),
-			  "timer", NULL);
+	irq = sun4d_build_timer_irq(board, SUN4D_TIMER_IRQ);
+	err = request_irq(irq, counter_fn, IRQF_TIMER, "timer", NULL);
 	if (err) {
 		prom_printf("sun4d_init_timers: request_irq() failed with %d\n",
 		             err);
@@ -567,27 +484,16 @@
 void __init sun4d_init_sbi_irq(void)
 {
 	struct device_node *dp;
-	int target_cpu = 0;
+	int target_cpu;
 
-#ifdef CONFIG_SMP
 	target_cpu = boot_cpu_id;
-#endif
-
-	nsbi = 0;
-	for_each_node_by_name(dp, "sbi")
-		nsbi++;
-	sbus_actions = kzalloc(nsbi * 8 * 4 * sizeof(struct sbus_action), GFP_ATOMIC);
-	if (!sbus_actions) {
-		prom_printf("SUN4D: Cannot allocate sbus_actions, halting.\n");
-		prom_halt();
-	}
 	for_each_node_by_name(dp, "sbi") {
 		int devid = of_getintprop_default(dp, "device-id", 0);
 		int board = of_getintprop_default(dp, "board#", 0);
 		unsigned int mask;
 
 		set_sbi_tid(devid, target_cpu << 3);
-		sbus_tid[board] = target_cpu;
+		board_to_cpu[board] = target_cpu;
 
 		/* Get rid of pending irqs from PROM */
 		mask = acquire_sbi(devid, 0xffffffff);
@@ -603,12 +509,10 @@
 {
 	local_irq_disable();
 
-	BTFIXUPSET_CALL(enable_irq, sun4d_enable_irq, BTFIXUPCALL_NORM);
-	BTFIXUPSET_CALL(disable_irq, sun4d_disable_irq, BTFIXUPCALL_NORM);
 	BTFIXUPSET_CALL(clear_clock_irq, sun4d_clear_clock_irq, BTFIXUPCALL_NORM);
 	BTFIXUPSET_CALL(load_profile_irq, sun4d_load_profile_irq, BTFIXUPCALL_NORM);
 
-	sparc_irq_config.init_timers = sun4d_init_timers;
+	sparc_irq_config.init_timers      = sun4d_init_timers;
 	sparc_irq_config.build_device_irq = sun4d_build_device_irq;
 
 #ifdef CONFIG_SMP
diff -druN linux-2.6.39-libre/arch/sparc/kernel/sun4d_smp.c linux-3.0-rc7-libre/arch/sparc/kernel/sun4d_smp.c
--- linux-2.6.39-libre/arch/sparc/kernel/sun4d_smp.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/sparc/kernel/sun4d_smp.c	2011-07-11 19:51:52.000000000 -0400
@@ -32,6 +32,7 @@
 	return val;
 }
 
+static void smp4d_ipi_init(void);
 static void smp_setup_percpu_timer(void);
 
 static unsigned char cpu_leds[32];
@@ -80,8 +81,6 @@
 	local_flush_cache_all();
 	local_flush_tlb_all();
 
-	cpu_probe();
-
 	while ((unsigned long)current_set[cpuid] < PAGE_OFFSET)
 		barrier();
 
@@ -105,7 +104,7 @@
 
 	local_irq_enable();	/* We don't allow PIL 14 yet */
 
-	while (!cpu_isset(cpuid, smp_commenced_mask))
+	while (!cpumask_test_cpu(cpuid, &smp_commenced_mask))
 		barrier();
 
 	spin_lock_irqsave(&sun4d_imsk_lock, flags);
@@ -120,6 +119,7 @@
  */
 void __init smp4d_boot_cpus(void)
 {
+	smp4d_ipi_init();
 	if (boot_cpu_id)
 		current_set[0] = NULL;
 	smp_setup_percpu_timer();
@@ -191,6 +191,80 @@
 	sun4d_distribute_irqs();
 }
 
+/* Memory structure giving interrupt handler information about IPI generated */
+struct sun4d_ipi_work {
+	int single;
+	int msk;
+	int resched;
+};
+
+static DEFINE_PER_CPU_SHARED_ALIGNED(struct sun4d_ipi_work, sun4d_ipi_work);
+
+/* Initialize IPIs on the SUN4D SMP machine */
+static void __init smp4d_ipi_init(void)
+{
+	int cpu;
+	struct sun4d_ipi_work *work;
+
+	printk(KERN_INFO "smp4d: setup IPI at IRQ %d\n", SUN4D_IPI_IRQ);
+
+	for_each_possible_cpu(cpu) {
+		work = &per_cpu(sun4d_ipi_work, cpu);
+		work->single = work->msk = work->resched = 0;
+	}
+}
+
+void sun4d_ipi_interrupt(void)
+{
+	struct sun4d_ipi_work *work = &__get_cpu_var(sun4d_ipi_work);
+
+	if (work->single) {
+		work->single = 0;
+		smp_call_function_single_interrupt();
+	}
+	if (work->msk) {
+		work->msk = 0;
+		smp_call_function_interrupt();
+	}
+	if (work->resched) {
+		work->resched = 0;
+		smp_resched_interrupt();
+	}
+}
+
+static void smp4d_ipi_single(int cpu)
+{
+	struct sun4d_ipi_work *work = &per_cpu(sun4d_ipi_work, cpu);
+
+	/* Mark work */
+	work->single = 1;
+
+	/* Generate IRQ on the CPU */
+	sun4d_send_ipi(cpu, SUN4D_IPI_IRQ);
+}
+
+static void smp4d_ipi_mask_one(int cpu)
+{
+	struct sun4d_ipi_work *work = &per_cpu(sun4d_ipi_work, cpu);
+
+	/* Mark work */
+	work->msk = 1;
+
+	/* Generate IRQ on the CPU */
+	sun4d_send_ipi(cpu, SUN4D_IPI_IRQ);
+}
+
+static void smp4d_ipi_resched(int cpu)
+{
+	struct sun4d_ipi_work *work = &per_cpu(sun4d_ipi_work, cpu);
+
+	/* Mark work */
+	work->resched = 1;
+
+	/* Generate IRQ on the CPU (any IRQ will cause resched) */
+	sun4d_send_ipi(cpu, SUN4D_IPI_IRQ);
+}
+
 static struct smp_funcall {
 	smpfunc_t func;
 	unsigned long arg1;
@@ -239,10 +313,10 @@
 		{
 			register int i;
 
-			cpu_clear(smp_processor_id(), mask);
-			cpus_and(mask, cpu_online_map, mask);
+			cpumask_clear_cpu(smp_processor_id(), &mask);
+			cpumask_and(&mask, cpu_online_mask, &mask);
 			for (i = 0; i <= high; i++) {
-				if (cpu_isset(i, mask)) {
+				if (cpumask_test_cpu(i, &mask)) {
 					ccall_info.processors_in[i] = 0;
 					ccall_info.processors_out[i] = 0;
 					sun4d_send_ipi(i, IRQ_CROSS_CALL);
@@ -255,7 +329,7 @@
 
 			i = 0;
 			do {
-				if (!cpu_isset(i, mask))
+				if (!cpumask_test_cpu(i, &mask))
 					continue;
 				while (!ccall_info.processors_in[i])
 					barrier();
@@ -263,7 +337,7 @@
 
 			i = 0;
 			do {
-				if (!cpu_isset(i, mask))
+				if (!cpumask_test_cpu(i, &mask))
 					continue;
 				while (!ccall_info.processors_out[i])
 					barrier();
@@ -356,6 +430,9 @@
 	BTFIXUPSET_BLACKBOX(load_current, smp4d_blackbox_current);
 	BTFIXUPSET_CALL(smp_cross_call, smp4d_cross_call, BTFIXUPCALL_NORM);
 	BTFIXUPSET_CALL(__hard_smp_processor_id, __smp4d_processor_id, BTFIXUPCALL_NORM);
+	BTFIXUPSET_CALL(smp_ipi_resched, smp4d_ipi_resched, BTFIXUPCALL_NORM);
+	BTFIXUPSET_CALL(smp_ipi_single, smp4d_ipi_single, BTFIXUPCALL_NORM);
+	BTFIXUPSET_CALL(smp_ipi_mask_one, smp4d_ipi_mask_one, BTFIXUPCALL_NORM);
 
 	for (i = 0; i < NR_CPUS; i++) {
 		ccall_info.processors_in[i] = 1;
diff -druN linux-2.6.39-libre/arch/sparc/kernel/sun4m_irq.c linux-3.0-rc7-libre/arch/sparc/kernel/sun4m_irq.c
--- linux-2.6.39-libre/arch/sparc/kernel/sun4m_irq.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/sparc/kernel/sun4m_irq.c	2011-07-11 19:51:52.000000000 -0400
@@ -100,6 +100,11 @@
 struct sun4m_irq_percpu __iomem *sun4m_irq_percpu[SUN4M_NCPUS];
 struct sun4m_irq_global __iomem *sun4m_irq_global;
 
+struct sun4m_handler_data {
+	bool    percpu;
+	long    mask;
+};
+
 /* Dave Redman (djhr@tadpole.co.uk)
  * The sun4m interrupt registers.
  */
@@ -142,9 +147,9 @@
 #define	OBP_INT_LEVEL_VME	0x40
 
 #define SUN4M_TIMER_IRQ         (OBP_INT_LEVEL_ONBOARD | 10)
-#define SUM4M_PROFILE_IRQ       (OBP_INT_LEVEL_ONBOARD | 14)
+#define SUN4M_PROFILE_IRQ       (OBP_INT_LEVEL_ONBOARD | 14)
 
-static unsigned long irq_mask[0x50] = {
+static unsigned long sun4m_imask[0x50] = {
 	/* 0x00 - SMP */
 	0,  SUN4M_SOFT_INT(1),
 	SUN4M_SOFT_INT(2),  SUN4M_SOFT_INT(3),
@@ -169,7 +174,7 @@
 	SUN4M_INT_VIDEO, SUN4M_INT_MODULE,
 	SUN4M_INT_REALTIME, SUN4M_INT_FLOPPY,
 	(SUN4M_INT_SERIAL | SUN4M_INT_KBDMS),
-	SUN4M_INT_AUDIO, 0, SUN4M_INT_MODULE_ERR,
+	SUN4M_INT_AUDIO, SUN4M_INT_E14, SUN4M_INT_MODULE_ERR,
 	/* 0x30 - sbus */
 	0, 0, SUN4M_INT_SBUS(0), SUN4M_INT_SBUS(1),
 	0, SUN4M_INT_SBUS(2), 0, SUN4M_INT_SBUS(3),
@@ -182,105 +187,110 @@
 	0, SUN4M_INT_VME(6), 0, 0
 };
 
-static unsigned long sun4m_get_irqmask(unsigned int irq)
+static void sun4m_mask_irq(struct irq_data *data)
 {
-	unsigned long mask;
-
-	if (irq < 0x50)
-		mask = irq_mask[irq];
-	else
-		mask = 0;
+	struct sun4m_handler_data *handler_data = data->handler_data;
+	int cpu = smp_processor_id();
 
-	if (!mask)
-		printk(KERN_ERR "sun4m_get_irqmask: IRQ%d has no valid mask!\n",
-		       irq);
+	if (handler_data->mask) {
+		unsigned long flags;
 
-	return mask;
+		local_irq_save(flags);
+		if (handler_data->percpu) {
+			sbus_writel(handler_data->mask, &sun4m_irq_percpu[cpu]->set);
+		} else {
+			sbus_writel(handler_data->mask, &sun4m_irq_global->mask_set);
+		}
+		local_irq_restore(flags);
+	}
 }
 
-static void sun4m_disable_irq(unsigned int irq_nr)
+static void sun4m_unmask_irq(struct irq_data *data)
 {
-	unsigned long mask, flags;
+	struct sun4m_handler_data *handler_data = data->handler_data;
 	int cpu = smp_processor_id();
 
-	mask = sun4m_get_irqmask(irq_nr);
-	local_irq_save(flags);
-	if (irq_nr > 15)
-		sbus_writel(mask, &sun4m_irq_global->mask_set);
-	else
-		sbus_writel(mask, &sun4m_irq_percpu[cpu]->set);
-	local_irq_restore(flags);
-}
-
-static void sun4m_enable_irq(unsigned int irq_nr)
-{
-	unsigned long mask, flags;
-	int cpu = smp_processor_id();
+	if (handler_data->mask) {
+		unsigned long flags;
 
-	/* Dreadful floppy hack. When we use 0x2b instead of
-	 * 0x0b the system blows (it starts to whistle!).
-	 * So we continue to use 0x0b. Fixme ASAP. --P3
-	 */
-	if (irq_nr != 0x0b) {
-		mask = sun4m_get_irqmask(irq_nr);
 		local_irq_save(flags);
-		if (irq_nr > 15)
-			sbus_writel(mask, &sun4m_irq_global->mask_clear);
-		else
-			sbus_writel(mask, &sun4m_irq_percpu[cpu]->clear);
-		local_irq_restore(flags);
-	} else {
-		local_irq_save(flags);
-		sbus_writel(SUN4M_INT_FLOPPY, &sun4m_irq_global->mask_clear);
+		if (handler_data->percpu) {
+			sbus_writel(handler_data->mask, &sun4m_irq_percpu[cpu]->clear);
+		} else {
+			sbus_writel(handler_data->mask, &sun4m_irq_global->mask_clear);
+		}
 		local_irq_restore(flags);
 	}
 }
 
-static unsigned long cpu_pil_to_imask[16] = {
-/*0*/	0x00000000,
-/*1*/	0x00000000,
-/*2*/	SUN4M_INT_SBUS(0) | SUN4M_INT_VME(0),
-/*3*/	SUN4M_INT_SBUS(1) | SUN4M_INT_VME(1),
-/*4*/	SUN4M_INT_SCSI,
-/*5*/	SUN4M_INT_SBUS(2) | SUN4M_INT_VME(2),
-/*6*/	SUN4M_INT_ETHERNET,
-/*7*/	SUN4M_INT_SBUS(3) | SUN4M_INT_VME(3),
-/*8*/	SUN4M_INT_VIDEO,
-/*9*/	SUN4M_INT_SBUS(4) | SUN4M_INT_VME(4) | SUN4M_INT_MODULE_ERR,
-/*10*/	SUN4M_INT_REALTIME,
-/*11*/	SUN4M_INT_SBUS(5) | SUN4M_INT_VME(5) | SUN4M_INT_FLOPPY,
-/*12*/	SUN4M_INT_SERIAL  | SUN4M_INT_KBDMS,
-/*13*/	SUN4M_INT_SBUS(6) | SUN4M_INT_VME(6) | SUN4M_INT_AUDIO,
-/*14*/	SUN4M_INT_E14,
-/*15*/	SUN4M_INT_ERROR,
-};
+static unsigned int sun4m_startup_irq(struct irq_data *data)
+{
+	irq_link(data->irq);
+	sun4m_unmask_irq(data);
+	return 0;
+}
 
-/* We assume the caller has disabled local interrupts when these are called,
- * or else very bizarre behavior will result.
- */
-static void sun4m_disable_pil_irq(unsigned int pil)
+static void sun4m_shutdown_irq(struct irq_data *data)
 {
-	sbus_writel(cpu_pil_to_imask[pil], &sun4m_irq_global->mask_set);
+	sun4m_mask_irq(data);
+	irq_unlink(data->irq);
 }
 
-static void sun4m_enable_pil_irq(unsigned int pil)
+static struct irq_chip sun4m_irq = {
+	.name		= "sun4m",
+	.irq_startup	= sun4m_startup_irq,
+	.irq_shutdown	= sun4m_shutdown_irq,
+	.irq_mask	= sun4m_mask_irq,
+	.irq_unmask	= sun4m_unmask_irq,
+};
+
+
+static unsigned int sun4m_build_device_irq(struct platform_device *op,
+					   unsigned int real_irq)
 {
-	sbus_writel(cpu_pil_to_imask[pil], &sun4m_irq_global->mask_clear);
+	struct sun4m_handler_data *handler_data;
+	unsigned int irq;
+	unsigned int pil;
+
+	if (real_irq >= OBP_INT_LEVEL_VME) {
+		prom_printf("Bogus sun4m IRQ %u\n", real_irq);
+		prom_halt();
+	}
+	pil = (real_irq & 0xf);
+	irq = irq_alloc(real_irq, pil);
+
+	if (irq == 0)
+		goto out;
+
+	handler_data = irq_get_handler_data(irq);
+	if (unlikely(handler_data))
+		goto out;
+
+	handler_data = kzalloc(sizeof(struct sun4m_handler_data), GFP_ATOMIC);
+	if (unlikely(!handler_data)) {
+		prom_printf("IRQ: kzalloc(sun4m_handler_data) failed.\n");
+		prom_halt();
+	}
+
+	handler_data->mask = sun4m_imask[real_irq];
+	handler_data->percpu = real_irq < OBP_INT_LEVEL_ONBOARD;
+	irq_set_chip_and_handler_name(irq, &sun4m_irq,
+	                              handle_level_irq, "level");
+	irq_set_handler_data(irq, handler_data);
+
+out:
+	return irq;
 }
 
 #ifdef CONFIG_SMP
 static void sun4m_send_ipi(int cpu, int level)
 {
-	unsigned long mask = sun4m_get_irqmask(level);
-
-	sbus_writel(mask, &sun4m_irq_percpu[cpu]->set);
+	sbus_writel(SUN4M_SOFT_INT(level), &sun4m_irq_percpu[cpu]->set);
 }
 
 static void sun4m_clear_ipi(int cpu, int level)
 {
-	unsigned long mask = sun4m_get_irqmask(level);
-
-	sbus_writel(mask, &sun4m_irq_percpu[cpu]->clear);
+	sbus_writel(SUN4M_SOFT_INT(level), &sun4m_irq_percpu[cpu]->clear);
 }
 
 static void sun4m_set_udt(int cpu)
@@ -343,7 +353,15 @@
 	prom_halt();
 }
 
-/* Exported for sun4m_smp.c */
+void sun4m_unmask_profile_irq(void)
+{
+	unsigned long flags;
+
+	local_irq_save(flags);
+	sbus_writel(sun4m_imask[SUN4M_PROFILE_IRQ], &sun4m_irq_global->mask_clear);
+	local_irq_restore(flags);
+}
+
 void sun4m_clear_profile_irq(int cpu)
 {
 	sbus_readl(&timers_percpu[cpu]->l14_limit);
@@ -358,6 +376,7 @@
 {
 	struct device_node *dp = of_find_node_by_name(NULL, "counter");
 	int i, err, len, num_cpu_timers;
+	unsigned int irq;
 	const u32 *addr;
 
 	if (!dp) {
@@ -384,8 +403,9 @@
 
 	master_l10_counter = &timers_global->l10_count;
 
-	err = request_irq(SUN4M_TIMER_IRQ, counter_fn,
-			  (IRQF_DISABLED | SA_STATIC_ALLOC), "timer", NULL);
+	irq = sun4m_build_device_irq(NULL, SUN4M_TIMER_IRQ);
+
+	err = request_irq(irq, counter_fn, IRQF_TIMER, "timer", NULL);
 	if (err) {
 		printk(KERN_ERR "sun4m_init_timers: Register IRQ error %d.\n",
 			err);
@@ -452,14 +472,11 @@
 	if (num_cpu_iregs == 4)
 		sbus_writel(0, &sun4m_irq_global->interrupt_target);
 
-	BTFIXUPSET_CALL(enable_irq, sun4m_enable_irq, BTFIXUPCALL_NORM);
-	BTFIXUPSET_CALL(disable_irq, sun4m_disable_irq, BTFIXUPCALL_NORM);
-	BTFIXUPSET_CALL(enable_pil_irq, sun4m_enable_pil_irq, BTFIXUPCALL_NORM);
-	BTFIXUPSET_CALL(disable_pil_irq, sun4m_disable_pil_irq, BTFIXUPCALL_NORM);
 	BTFIXUPSET_CALL(clear_clock_irq, sun4m_clear_clock_irq, BTFIXUPCALL_NORM);
 	BTFIXUPSET_CALL(load_profile_irq, sun4m_load_profile_irq, BTFIXUPCALL_NORM);
 
 	sparc_irq_config.init_timers = sun4m_init_timers;
+	sparc_irq_config.build_device_irq = sun4m_build_device_irq;
 
 #ifdef CONFIG_SMP
 	BTFIXUPSET_CALL(set_cpu_int, sun4m_send_ipi, BTFIXUPCALL_NORM);
diff -druN linux-2.6.39-libre/arch/sparc/kernel/sun4m_smp.c linux-3.0-rc7-libre/arch/sparc/kernel/sun4m_smp.c
--- linux-2.6.39-libre/arch/sparc/kernel/sun4m_smp.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/sparc/kernel/sun4m_smp.c	2011-07-11 19:51:52.000000000 -0400
@@ -15,6 +15,9 @@
 #include "irq.h"
 #include "kernel.h"
 
+#define IRQ_IPI_SINGLE		12
+#define IRQ_IPI_MASK		13
+#define IRQ_IPI_RESCHED		14
 #define IRQ_CROSS_CALL		15
 
 static inline unsigned long
@@ -26,6 +29,7 @@
 	return val;
 }
 
+static void smp4m_ipi_init(void);
 static void smp_setup_percpu_timer(void);
 
 void __cpuinit smp4m_callin(void)
@@ -59,8 +63,6 @@
 	local_flush_cache_all();
 	local_flush_tlb_all();
 
-	cpu_probe();
-
 	/* Fix idle thread fields. */
 	__asm__ __volatile__("ld [%0], %%g6\n\t"
 			     : : "r" (&current_set[cpuid])
@@ -70,7 +72,7 @@
 	atomic_inc(&init_mm.mm_count);
 	current->active_mm = &init_mm;
 
-	while (!cpu_isset(cpuid, smp_commenced_mask))
+	while (!cpumask_test_cpu(cpuid, &smp_commenced_mask))
 		mb();
 
 	local_irq_enable();
@@ -83,6 +85,7 @@
  */
 void __init smp4m_boot_cpus(void)
 {
+	smp4m_ipi_init();
 	smp_setup_percpu_timer();
 	local_flush_cache_all();
 }
@@ -150,18 +153,25 @@
 	/* Ok, they are spinning and ready to go. */
 }
 
-/* At each hardware IRQ, we get this called to forward IRQ reception
- * to the next processor.  The caller must disable the IRQ level being
- * serviced globally so that there are no double interrupts received.
- *
- * XXX See sparc64 irq.c.
- */
-void smp4m_irq_rotate(int cpu)
+
+/* Initialize IPIs on the SUN4M SMP machine */
+static void __init smp4m_ipi_init(void)
 {
-	int next = cpu_data(cpu).next;
+}
 
-	if (next != cpu)
-		set_irq_udt(next);
+static void smp4m_ipi_resched(int cpu)
+{
+	set_cpu_int(cpu, IRQ_IPI_RESCHED);
+}
+
+static void smp4m_ipi_single(int cpu)
+{
+	set_cpu_int(cpu, IRQ_IPI_SINGLE);
+}
+
+static void smp4m_ipi_mask_one(int cpu)
+{
+	set_cpu_int(cpu, IRQ_IPI_MASK);
 }
 
 static struct smp_funcall {
@@ -199,10 +209,10 @@
 		{
 			register int i;
 
-			cpu_clear(smp_processor_id(), mask);
-			cpus_and(mask, cpu_online_map, mask);
+			cpumask_clear_cpu(smp_processor_id(), &mask);
+			cpumask_and(&mask, cpu_online_mask, &mask);
 			for (i = 0; i < ncpus; i++) {
-				if (cpu_isset(i, mask)) {
+				if (cpumask_test_cpu(i, &mask)) {
 					ccall_info.processors_in[i] = 0;
 					ccall_info.processors_out[i] = 0;
 					set_cpu_int(i, IRQ_CROSS_CALL);
@@ -218,7 +228,7 @@
 
 			i = 0;
 			do {
-				if (!cpu_isset(i, mask))
+				if (!cpumask_test_cpu(i, &mask))
 					continue;
 				while (!ccall_info.processors_in[i])
 					barrier();
@@ -226,7 +236,7 @@
 
 			i = 0;
 			do {
-				if (!cpu_isset(i, mask))
+				if (!cpumask_test_cpu(i, &mask))
 					continue;
 				while (!ccall_info.processors_out[i])
 					barrier();
@@ -277,7 +287,7 @@
 	load_profile_irq(cpu, lvl14_resolution);
 
 	if (cpu == boot_cpu_id)
-		enable_pil_irq(14);
+		sun4m_unmask_profile_irq();
 }
 
 static void __init smp4m_blackbox_id(unsigned *addr)
@@ -306,4 +316,7 @@
 	BTFIXUPSET_BLACKBOX(load_current, smp4m_blackbox_current);
 	BTFIXUPSET_CALL(smp_cross_call, smp4m_cross_call, BTFIXUPCALL_NORM);
 	BTFIXUPSET_CALL(__hard_smp_processor_id, __smp4m_processor_id, BTFIXUPCALL_NORM);
+	BTFIXUPSET_CALL(smp_ipi_resched, smp4m_ipi_resched, BTFIXUPCALL_NORM);
+	BTFIXUPSET_CALL(smp_ipi_single, smp4m_ipi_single, BTFIXUPCALL_NORM);
+	BTFIXUPSET_CALL(smp_ipi_mask_one, smp4m_ipi_mask_one, BTFIXUPCALL_NORM);
 }
diff -druN linux-2.6.39-libre/arch/sparc/kernel/sysfs.c linux-3.0-rc7-libre/arch/sparc/kernel/sysfs.c
--- linux-2.6.39-libre/arch/sparc/kernel/sysfs.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/sparc/kernel/sysfs.c	2011-07-11 19:51:52.000000000 -0400
@@ -103,9 +103,10 @@
 			        unsigned long (*func)(unsigned long),
 				unsigned long arg)
 {
-	cpumask_t old_affinity = current->cpus_allowed;
+	cpumask_t old_affinity;
 	unsigned long ret;
 
+	cpumask_copy(&old_affinity, tsk_cpus_allowed(current));
 	/* should return -EINVAL to userspace */
 	if (set_cpus_allowed_ptr(current, cpumask_of(cpu)))
 		return 0;
diff -druN linux-2.6.39-libre/arch/sparc/kernel/sys_sparc32.c linux-3.0-rc7-libre/arch/sparc/kernel/sys_sparc32.c
--- linux-2.6.39-libre/arch/sparc/kernel/sys_sparc32.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/sparc/kernel/sys_sparc32.c	2011-07-11 19:51:52.000000000 -0400
@@ -109,7 +109,7 @@
 
 	default:
 		return -ENOSYS;
-	};
+	}
 
 	return -ENOSYS;
 }
diff -druN linux-2.6.39-libre/arch/sparc/kernel/sys_sparc_64.c linux-3.0-rc7-libre/arch/sparc/kernel/sys_sparc_64.c
--- linux-2.6.39-libre/arch/sparc/kernel/sys_sparc_64.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/sparc/kernel/sys_sparc_64.c	2011-07-11 19:51:52.000000000 -0400
@@ -460,7 +460,7 @@
 		default:
 			err = -ENOSYS;
 			goto out;
-		};
+		}
 	}
 	if (call <= MSGCTL) {
 		switch (call) {
@@ -481,7 +481,7 @@
 		default:
 			err = -ENOSYS;
 			goto out;
-		};
+		}
 	}
 	if (call <= SHMCTL) {
 		switch (call) {
@@ -507,7 +507,7 @@
 		default:
 			err = -ENOSYS;
 			goto out;
-		};
+		}
 	} else {
 		err = -ENOSYS;
 	}
diff -druN linux-2.6.39-libre/arch/sparc/kernel/systbls_32.S linux-3.0-rc7-libre/arch/sparc/kernel/systbls_32.S
--- linux-2.6.39-libre/arch/sparc/kernel/systbls_32.S	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/sparc/kernel/systbls_32.S	2011-07-11 19:51:52.000000000 -0400
@@ -84,4 +84,4 @@
 /*320*/	.long sys_dup3, sys_pipe2, sys_inotify_init1, sys_accept4, sys_preadv
 /*325*/	.long sys_pwritev, sys_rt_tgsigqueueinfo, sys_perf_event_open, sys_recvmmsg, sys_fanotify_init
 /*330*/	.long sys_fanotify_mark, sys_prlimit64, sys_name_to_handle_at, sys_open_by_handle_at, sys_clock_adjtime
-/*335*/	.long sys_syncfs
+/*335*/	.long sys_syncfs, sys_sendmmsg, sys_setns
diff -druN linux-2.6.39-libre/arch/sparc/kernel/systbls_64.S linux-3.0-rc7-libre/arch/sparc/kernel/systbls_64.S
--- linux-2.6.39-libre/arch/sparc/kernel/systbls_64.S	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/sparc/kernel/systbls_64.S	2011-07-11 19:51:52.000000000 -0400
@@ -85,7 +85,7 @@
 /*320*/	.word sys_dup3, sys_pipe2, sys_inotify_init1, sys_accept4, compat_sys_preadv
 	.word compat_sys_pwritev, compat_sys_rt_tgsigqueueinfo, sys_perf_event_open, compat_sys_recvmmsg, sys_fanotify_init
 /*330*/	.word sys32_fanotify_mark, sys_prlimit64, sys_name_to_handle_at, compat_sys_open_by_handle_at, compat_sys_clock_adjtime
-	.word sys_syncfs
+	.word sys_syncfs, compat_sys_sendmmsg, sys_setns
 
 #endif /* CONFIG_COMPAT */
 
@@ -162,4 +162,4 @@
 /*320*/	.word sys_dup3, sys_pipe2, sys_inotify_init1, sys_accept4, sys_preadv
 	.word sys_pwritev, sys_rt_tgsigqueueinfo, sys_perf_event_open, sys_recvmmsg, sys_fanotify_init
 /*330*/	.word sys_fanotify_mark, sys_prlimit64, sys_name_to_handle_at, sys_open_by_handle_at, sys_clock_adjtime
-	.word sys_syncfs
+	.word sys_syncfs, sys_sendmmsg, sys_setns
diff -druN linux-2.6.39-libre/arch/sparc/kernel/time_32.c linux-3.0-rc7-libre/arch/sparc/kernel/time_32.c
--- linux-2.6.39-libre/arch/sparc/kernel/time_32.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/sparc/kernel/time_32.c	2011-07-11 19:51:52.000000000 -0400
@@ -228,14 +228,10 @@
 
 void __init time_init(void)
 {
-#ifdef CONFIG_PCI
-	extern void pci_time_init(void);
-	if (pcic_present()) {
+	if (pcic_present())
 		pci_time_init();
-		return;
-	}
-#endif
-	sbus_time_init();
+	else
+		sbus_time_init();
 }
 
 
diff -druN linux-2.6.39-libre/arch/sparc/kernel/time_64.c linux-3.0-rc7-libre/arch/sparc/kernel/time_64.c
--- linux-2.6.39-libre/arch/sparc/kernel/time_64.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/sparc/kernel/time_64.c	2011-07-11 19:51:52.000000000 -0400
@@ -708,7 +708,7 @@
 	case CLOCK_EVT_MODE_UNUSED:
 		WARN_ON(1);
 		break;
-	};
+	}
 }
 
 static struct clock_event_device sparc64_clockevent = {
diff -druN linux-2.6.39-libre/arch/sparc/kernel/traps_64.c linux-3.0-rc7-libre/arch/sparc/kernel/traps_64.c
--- linux-2.6.39-libre/arch/sparc/kernel/traps_64.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/sparc/kernel/traps_64.c	2011-07-11 19:51:52.000000000 -0400
@@ -1804,7 +1804,7 @@
 		return "warning resumable";
 	default:
 		return "unknown";
-	};
+	}
 }
 
 static void sun4v_log_error(struct pt_regs *regs, struct sun4v_error_entry *ent, int cpu, const char *pfx, atomic_t *ocnt)
diff -druN linux-2.6.39-libre/arch/sparc/kernel/unaligned_64.c linux-3.0-rc7-libre/arch/sparc/kernel/unaligned_64.c
--- linux-2.6.39-libre/arch/sparc/kernel/unaligned_64.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/sparc/kernel/unaligned_64.c	2011-07-11 19:51:52.000000000 -0400
@@ -211,7 +211,7 @@
 		default:
 			BUG();
 			break;
-		};
+		}
 	}
 	return __do_int_store(dst_addr, size, src_val, asi);
 }
@@ -328,7 +328,7 @@
 		case ASI_SNFL:
 			asi &= ~0x08;
 			break;
-		};
+		}
 		switch (dir) {
 		case load:
 			reg_addr = fetch_reg_addr(((insn>>25)&0x1f), regs);
@@ -351,7 +351,7 @@
 				default:
 					BUG();
 					break;
-				};
+				}
 				*reg_addr = val_in;
 			}
 			break;
diff -druN linux-2.6.39-libre/arch/sparc/kernel/us2e_cpufreq.c linux-3.0-rc7-libre/arch/sparc/kernel/us2e_cpufreq.c
--- linux-2.6.39-libre/arch/sparc/kernel/us2e_cpufreq.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/sparc/kernel/us2e_cpufreq.c	2011-07-11 19:51:52.000000000 -0400
@@ -176,7 +176,7 @@
 
 	default:
 		BUG();
-	};
+	}
 }
 
 static unsigned long index_to_divisor(unsigned int index)
@@ -199,7 +199,7 @@
 
 	default:
 		BUG();
-	};
+	}
 }
 
 static unsigned long estar_to_divisor(unsigned long estar)
@@ -224,7 +224,7 @@
 		break;
 	default:
 		BUG();
-	};
+	}
 
 	return ret;
 }
@@ -237,7 +237,7 @@
 	if (!cpu_online(cpu))
 		return 0;
 
-	cpus_allowed = current->cpus_allowed;
+	cpumask_copy(&cpus_allowed, tsk_cpus_allowed(current));
 	set_cpus_allowed_ptr(current, cpumask_of(cpu));
 
 	clock_tick = sparc64_get_clock_tick(cpu) / 1000;
@@ -258,7 +258,7 @@
 	if (!cpu_online(cpu))
 		return;
 
-	cpus_allowed = current->cpus_allowed;
+	cpumask_copy(&cpus_allowed, tsk_cpus_allowed(current));
 	set_cpus_allowed_ptr(current, cpumask_of(cpu));
 
 	new_freq = clock_tick = sparc64_get_clock_tick(cpu) / 1000;
diff -druN linux-2.6.39-libre/arch/sparc/kernel/us3_cpufreq.c linux-3.0-rc7-libre/arch/sparc/kernel/us3_cpufreq.c
--- linux-2.6.39-libre/arch/sparc/kernel/us3_cpufreq.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/sparc/kernel/us3_cpufreq.c	2011-07-11 19:51:52.000000000 -0400
@@ -71,7 +71,7 @@
 		break;
 	default:
 		BUG();
-	};
+	}
 
 	return ret;
 }
@@ -85,7 +85,7 @@
 	if (!cpu_online(cpu))
 		return 0;
 
-	cpus_allowed = current->cpus_allowed;
+	cpumask_copy(&cpus_allowed, tsk_cpus_allowed(current));
 	set_cpus_allowed_ptr(current, cpumask_of(cpu));
 
 	reg = read_safari_cfg();
@@ -105,7 +105,7 @@
 	if (!cpu_online(cpu))
 		return;
 
-	cpus_allowed = current->cpus_allowed;
+	cpumask_copy(&cpus_allowed, tsk_cpus_allowed(current));
 	set_cpus_allowed_ptr(current, cpumask_of(cpu));
 
 	new_freq = sparc64_get_clock_tick(cpu) / 1000;
@@ -125,7 +125,7 @@
 
 	default:
 		BUG();
-	};
+	}
 
 	reg = read_safari_cfg();
 
diff -druN linux-2.6.39-libre/arch/sparc/kernel/viohs.c linux-3.0-rc7-libre/arch/sparc/kernel/viohs.c
--- linux-2.6.39-libre/arch/sparc/kernel/viohs.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/sparc/kernel/viohs.c	2011-07-11 19:51:52.000000000 -0400
@@ -363,7 +363,7 @@
 
 	default:
 		return handshake_failure(vio);
-	};
+	}
 }
 
 static int process_attr(struct vio_driver_state *vio, void *pkt)
diff -druN linux-2.6.39-libre/arch/sparc/kernel/visemul.c linux-3.0-rc7-libre/arch/sparc/kernel/visemul.c
--- linux-2.6.39-libre/arch/sparc/kernel/visemul.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/sparc/kernel/visemul.c	2011-07-11 19:51:52.000000000 -0400
@@ -334,7 +334,7 @@
 		left = edge32_tab_l[(rs1 >> 2) & 0x1].left;
 		right = edge32_tab_l[(rs2 >> 2) & 0x1].right;
 		break;
-	};
+	}
 
 	if ((rs1 & ~0x7UL) == (rs2 & ~0x7UL))
 		rd_val = right & left;
@@ -360,7 +360,7 @@
 		tstate = regs->tstate & ~(TSTATE_XCC | TSTATE_ICC);
 		regs->tstate = tstate | (ccr << 32UL);
 	}
-	};
+	}
 }
 
 static void array(struct pt_regs *regs, unsigned int insn, unsigned int opf)
@@ -392,7 +392,7 @@
 
 	case ARRAY32_OPF:
 		rd_val <<= 2;
-	};
+	}
 
 	store_reg(regs, rd_val, RD(insn));
 }
@@ -577,7 +577,7 @@
 		*fpd_regaddr(f, RD(insn)) = rd_val;
 		break;
 	}
-	};
+	}
 }
 
 static void pmul(struct pt_regs *regs, unsigned int insn, unsigned int opf)
@@ -693,7 +693,7 @@
 		*fpd_regaddr(f, RD(insn)) = rd_val;
 		break;
 	}
-	};
+	}
 }
 
 static void pcmp(struct pt_regs *regs, unsigned int insn, unsigned int opf)
@@ -786,7 +786,7 @@
 				rd_val |= 1 << i;
 		}
 		break;
-	};
+	}
 
 	maybe_flush_windows(0, 0, RD(insn), 0);
 	store_reg(regs, rd_val, RD(insn));
@@ -885,7 +885,7 @@
 	case BSHUFFLE_OPF:
 		bshuffle(regs, insn);
 		break;
-	};
+	}
 
 	regs->tpc = regs->tnpc;
 	regs->tnpc += 4;
diff -druN linux-2.6.39-libre/arch/sparc/kernel/vmlinux.lds.S linux-3.0-rc7-libre/arch/sparc/kernel/vmlinux.lds.S
--- linux-2.6.39-libre/arch/sparc/kernel/vmlinux.lds.S	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/sparc/kernel/vmlinux.lds.S	2011-07-11 19:51:52.000000000 -0400
@@ -108,7 +108,7 @@
 		__sun4v_2insn_patch_end = .;
 	}
 
-	PERCPU(SMP_CACHE_BYTES, PAGE_SIZE)
+	PERCPU_SECTION(SMP_CACHE_BYTES)
 
 	. = ALIGN(PAGE_SIZE);
 	__init_end = .;
diff -druN linux-2.6.39-libre/arch/sparc/lib/Makefile linux-3.0-rc7-libre/arch/sparc/lib/Makefile
--- linux-2.6.39-libre/arch/sparc/lib/Makefile	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/sparc/lib/Makefile	2011-07-11 19:51:52.000000000 -0400
@@ -15,7 +15,6 @@
 lib-$(CONFIG_SPARC32) += copy_user.o locks.o
 lib-y                 += atomic_$(BITS).o
 lib-$(CONFIG_SPARC32) += lshrdi3.o ashldi3.o
-lib-$(CONFIG_SPARC32) += rwsem_32.o
 lib-$(CONFIG_SPARC32) += muldi3.o bitext.o cmpdi2.o
 
 lib-$(CONFIG_SPARC64) += copy_page.o clear_page.o bzero.o
diff -druN linux-2.6.39-libre/arch/sparc/lib/rwsem_32.S linux-3.0-rc7-libre/arch/sparc/lib/rwsem_32.S
--- linux-2.6.39-libre/arch/sparc/lib/rwsem_32.S	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/sparc/lib/rwsem_32.S	1969-12-31 19:00:00.000000000 -0500
@@ -1,204 +0,0 @@
-/*
- * Assembly part of rw semaphores.
- *
- * Copyright (C) 1999 Jakub Jelinek (jakub@redhat.com)
- */
-
-#include <asm/ptrace.h>
-#include <asm/psr.h>
-
-	.section .sched.text, "ax"
-	.align	4
-
-	.globl		___down_read
-___down_read:
-	rd		%psr, %g3
-	nop
-	nop
-	nop
-	or		%g3, PSR_PIL, %g7
-	wr		%g7, 0, %psr
-	nop
-	nop
-	nop
-#ifdef CONFIG_SMP
-1:	ldstub		[%g1 + 4], %g7
-	tst		%g7
-	bne		1b
-	 ld		[%g1], %g7
-	sub		%g7, 1, %g7
-	st		%g7, [%g1]
-	stb		%g0, [%g1 + 4]
-#else
-	ld		[%g1], %g7
-	sub		%g7, 1, %g7
-	st		%g7, [%g1]
-#endif
-	wr		%g3, 0, %psr
-	add		%g7, 1, %g7
-	nop
-	nop
-	subcc		%g7, 1, %g7
-	bneg		3f
-	 nop
-2:	jmpl		%o7, %g0
-	 mov		%g4, %o7
-3:	save		%sp, -64, %sp
-	mov		%g1, %l1
-	mov		%g4, %l4
-	bcs		4f
-	 mov		%g5, %l5
-	call		down_read_failed
-	 mov		%l1, %o0
-	mov		%l1, %g1
-	mov		%l4, %g4
-	ba		___down_read
-	 restore	%l5, %g0, %g5
-4:	call		down_read_failed_biased
-	 mov		%l1, %o0
-	mov		%l1, %g1
-	mov		%l4, %g4
-	ba		2b
-	 restore	%l5, %g0, %g5
-
-	.globl		___down_write
-___down_write:
-	rd		%psr, %g3
-	nop
-	nop
-	nop
-	or		%g3, PSR_PIL, %g7
-	wr		%g7, 0, %psr
-	sethi		%hi(0x01000000), %g2
-	nop
-	nop
-#ifdef CONFIG_SMP
-1:	ldstub		[%g1 + 4], %g7
-	tst		%g7
-	bne		1b
-	 ld		[%g1], %g7
-	sub		%g7, %g2, %g7
-	st		%g7, [%g1]
-	stb		%g0, [%g1 + 4]
-#else
-	ld		[%g1], %g7
-	sub		%g7, %g2, %g7
-	st		%g7, [%g1]
-#endif
-	wr		%g3, 0, %psr
-	add		%g7, %g2, %g7
-	nop
-	nop
-	subcc		%g7, %g2, %g7
-	bne		3f
-	 nop
-2:	jmpl		%o7, %g0
-	 mov		%g4, %o7
-3:	save		%sp, -64, %sp
-	mov		%g1, %l1
-	mov		%g4, %l4
-	bcs		4f
-	 mov		%g5, %l5
-	call		down_write_failed
-	 mov		%l1, %o0
-	mov		%l1, %g1
-	mov		%l4, %g4
-	ba		___down_write
-	 restore	%l5, %g0, %g5
-4:	call		down_write_failed_biased
-	 mov		%l1, %o0
-	mov		%l1, %g1
-	mov		%l4, %g4
-	ba		2b
-	 restore	%l5, %g0, %g5
-
-	.text
-	.globl		___up_read
-___up_read:
-	rd		%psr, %g3
-	nop
-	nop
-	nop
-	or		%g3, PSR_PIL, %g7
-	wr		%g7, 0, %psr
-	nop
-	nop
-	nop
-#ifdef CONFIG_SMP
-1:	ldstub		[%g1 + 4], %g7
-	tst		%g7
-	bne		1b
-	 ld		[%g1], %g7
-	add		%g7, 1, %g7
-	st		%g7, [%g1]
-	stb		%g0, [%g1 + 4]
-#else
-	ld		[%g1], %g7
-	add		%g7, 1, %g7
-	st		%g7, [%g1]
-#endif
-	wr		%g3, 0, %psr
-	nop
-	nop
-	nop
-	cmp		%g7, 0
-	be		3f
-	 nop
-2:	jmpl		%o7, %g0
-	 mov		%g4, %o7
-3:	save		%sp, -64, %sp
-	mov		%g1, %l1
-	mov		%g4, %l4
-	mov		%g5, %l5
-	clr		%o1
-	call		__rwsem_wake
-	 mov		%l1, %o0
-	mov		%l1, %g1
-	mov		%l4, %g4
-	ba		2b
-	 restore	%l5, %g0, %g5
-
-	.globl		___up_write
-___up_write:
-	rd		%psr, %g3
-	nop
-	nop
-	nop
-	or		%g3, PSR_PIL, %g7
-	wr		%g7, 0, %psr
-	sethi		%hi(0x01000000), %g2
-	nop
-	nop
-#ifdef CONFIG_SMP
-1:	ldstub		[%g1 + 4], %g7
-	tst		%g7
-	bne		1b
-	 ld		[%g1], %g7
-	add		%g7, %g2, %g7
-	st		%g7, [%g1]
-	stb		%g0, [%g1 + 4]
-#else
-	ld		[%g1], %g7
-	add		%g7, %g2, %g7
-	st		%g7, [%g1]
-#endif
-	wr		%g3, 0, %psr
-	sub		%g7, %g2, %g7
-	nop
-	nop
-	addcc		%g7, %g2, %g7
-	bcs		3f
-	 nop
-2:	jmpl		%o7, %g0
-	 mov		%g4, %o7
-3:	save		%sp, -64, %sp
-	mov		%g1, %l1
-	mov		%g4, %l4
-	mov		%g5, %l5
-	mov		%g7, %o1
-	call		__rwsem_wake
-	 mov		%l1, %o0
-	mov		%l1, %g1
-	mov		%l4, %g4
-	ba		2b
-	 restore	%l5, %g0, %g5
diff -druN linux-2.6.39-libre/arch/sparc/mm/fault_32.c linux-3.0-rc7-libre/arch/sparc/mm/fault_32.c
--- linux-2.6.39-libre/arch/sparc/mm/fault_32.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/sparc/mm/fault_32.c	2011-07-11 19:51:52.000000000 -0400
@@ -135,7 +135,7 @@
 
 	default:
 		break;
-	};
+	}
 
 	memset(&regs, 0, sizeof (regs));
 	regs.pc = pc;
diff -druN linux-2.6.39-libre/arch/sparc/mm/init_32.c linux-3.0-rc7-libre/arch/sparc/mm/init_32.c
--- linux-2.6.39-libre/arch/sparc/mm/init_32.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/sparc/mm/init_32.c	2011-07-11 19:51:52.000000000 -0400
@@ -37,8 +37,6 @@
 #include <asm/prom.h>
 #include <asm/leon.h>
 
-DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
-
 unsigned long *sparc_valid_addr_bitmap;
 EXPORT_SYMBOL(sparc_valid_addr_bitmap);
 
@@ -78,7 +76,7 @@
 void show_mem(unsigned int filter)
 {
 	printk("Mem-info:\n");
-	show_free_areas();
+	show_free_areas(filter);
 	printk("Free swap:       %6ldkB\n",
 	       nr_swap_pages << (PAGE_SHIFT-10));
 	printk("%ld pages of RAM\n", totalram_pages);
@@ -342,7 +340,7 @@
 		prom_printf("paging_init: sparc_cpu_model = %d\n", sparc_cpu_model);
 		prom_printf("paging_init: Halting...\n");
 		prom_halt();
-	};
+	}
 
 	/* Initialize the protection map with non-constant, MMU dependent values. */
 	protection_map[0] = PAGE_NONE;
diff -druN linux-2.6.39-libre/arch/sparc/mm/init_64.c linux-3.0-rc7-libre/arch/sparc/mm/init_64.c
--- linux-2.6.39-libre/arch/sparc/mm/init_64.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/sparc/mm/init_64.c	2011-07-11 19:51:52.000000000 -0400
@@ -862,7 +862,7 @@
 	for (i = 0; i < NR_CPUS; i++)
 		numa_cpu_lookup_table[i] = 0;
 
-	numa_cpumask_lookup_table[0] = CPU_MASK_ALL;
+	cpumask_setall(&numa_cpumask_lookup_table[0]);
 }
 
 #ifdef CONFIG_NEED_MULTIPLE_NODES
@@ -1080,7 +1080,7 @@
 {
 	u64 arc;
 
-	cpus_clear(*mask);
+	cpumask_clear(mask);
 
 	mdesc_for_each_arc(arc, md, grp, MDESC_ARC_TYPE_BACK) {
 		u64 target = mdesc_arc_target(md, arc);
@@ -1091,7 +1091,7 @@
 			continue;
 		id = mdesc_get_property(md, target, "id", NULL);
 		if (*id < nr_cpu_ids)
-			cpu_set(*id, *mask);
+			cpumask_set_cpu(*id, mask);
 	}
 }
 
@@ -1153,13 +1153,13 @@
 
 	numa_parse_mdesc_group_cpus(md, grp, &mask);
 
-	for_each_cpu_mask(cpu, mask)
+	for_each_cpu(cpu, &mask)
 		numa_cpu_lookup_table[cpu] = index;
-	numa_cpumask_lookup_table[index] = mask;
+	cpumask_copy(&numa_cpumask_lookup_table[index], &mask);
 
 	if (numa_debug) {
 		printk(KERN_INFO "NUMA GROUP[%d]: cpus [ ", index);
-		for_each_cpu_mask(cpu, mask)
+		for_each_cpu(cpu, &mask)
 			printk("%d ", cpu);
 		printk("]\n");
 	}
@@ -1218,7 +1218,7 @@
 	index = 0;
 	for_each_present_cpu(cpu) {
 		numa_cpu_lookup_table[cpu] = index;
-		numa_cpumask_lookup_table[index] = cpumask_of_cpu(cpu);
+		cpumask_copy(&numa_cpumask_lookup_table[index], cpumask_of(cpu));
 		node_masks[index].mask = ~((1UL << 36UL) - 1UL);
 		node_masks[index].val = cpu << 36UL;
 
@@ -1625,7 +1625,7 @@
 		ktsb_descr[0].pgsz_idx = HV_PGSZ_IDX_4MB;
 		ktsb_descr[0].pgsz_mask = HV_PGSZ_MASK_4MB;
 		break;
-	};
+	}
 
 	ktsb_descr[0].assoc = 1;
 	ktsb_descr[0].num_ttes = KERNEL_TSB_NENTRIES;
@@ -2266,7 +2266,7 @@
 			return _PAGE_SZ512K_4V;
 		case 4 * 1024 * 1024:
 			return _PAGE_SZ4MB_4V;
-		};
+		}
 	} else {
 		switch (sz) {
 		case 8 * 1024:
@@ -2278,7 +2278,7 @@
 			return _PAGE_SZ512K_4U;
 		case 4 * 1024 * 1024:
 			return _PAGE_SZ4MB_4U;
-		};
+		}
 	}
 }
 
diff -druN linux-2.6.39-libre/arch/sparc/mm/srmmu.c linux-3.0-rc7-libre/arch/sparc/mm/srmmu.c
--- linux-2.6.39-libre/arch/sparc/mm/srmmu.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/sparc/mm/srmmu.c	2011-07-11 19:51:52.000000000 -0400
@@ -1665,7 +1665,7 @@
 	default:
 		srmmu_modtype = Swift_ok;
 		break;
-	};
+	}
 
 	BTFIXUPSET_CALL(flush_cache_all, swift_flush_cache_all, BTFIXUPCALL_NORM);
 	BTFIXUPSET_CALL(flush_cache_mm, swift_flush_cache_mm, BTFIXUPCALL_NORM);
@@ -2069,7 +2069,7 @@
 			/* Some other Cypress revision, assume a 605. */
 			init_cypress_605(mod_rev);
 			break;
-		};
+		}
 		return;
 	}
 	
diff -druN linux-2.6.39-libre/arch/sparc/mm/sun4c.c linux-3.0-rc7-libre/arch/sparc/mm/sun4c.c
--- linux-2.6.39-libre/arch/sparc/mm/sun4c.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/sparc/mm/sun4c.c	2011-07-11 19:51:52.000000000 -0400
@@ -318,7 +318,7 @@
 		prom_printf("probe_vac: Didn't expect vac-linesize of %d, halting\n",
 			    sun4c_vacinfo.linesize);
 		prom_halt();
-	};
+	}
 
 	sun4c_flush_all();
 	sun4c_enable_vac();
@@ -364,7 +364,7 @@
 			prom_printf("Unhandled number of segmaps: %d\n",
 				    num_segmaps);
 			prom_halt();
-	};
+	}
 	switch (num_contexts) {
 		case 8:
 			/* Default, nothing to do. */
@@ -377,7 +377,7 @@
 			prom_printf("Unhandled number of contexts: %d\n",
 				    num_contexts);
 			prom_halt();
-	};
+	}
 
 	if (sun4c_vacinfo.do_hwflushes != 0) {
 		PATCH_INSN(vac_hwflush_patch1_on, vac_hwflush_patch1);
@@ -394,7 +394,7 @@
 			prom_printf("Impossible VAC linesize %d, halting...\n",
 				    sun4c_vacinfo.linesize);
 			prom_halt();
-		};
+		}
 	}
 }
 
diff -druN linux-2.6.39-libre/arch/sparc/mm/tlb.c linux-3.0-rc7-libre/arch/sparc/mm/tlb.c
--- linux-2.6.39-libre/arch/sparc/mm/tlb.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/sparc/mm/tlb.c	2011-07-11 19:51:52.000000000 -0400
@@ -19,33 +19,34 @@
 
 /* Heavily inspired by the ppc64 code.  */
 
-DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
+static DEFINE_PER_CPU(struct tlb_batch, tlb_batch);
 
 void flush_tlb_pending(void)
 {
-	struct mmu_gather *mp = &get_cpu_var(mmu_gathers);
+	struct tlb_batch *tb = &get_cpu_var(tlb_batch);
 
-	if (mp->tlb_nr) {
-		flush_tsb_user(mp);
+	if (tb->tlb_nr) {
+		flush_tsb_user(tb);
 
-		if (CTX_VALID(mp->mm->context)) {
+		if (CTX_VALID(tb->mm->context)) {
 #ifdef CONFIG_SMP
-			smp_flush_tlb_pending(mp->mm, mp->tlb_nr,
-					      &mp->vaddrs[0]);
+			smp_flush_tlb_pending(tb->mm, tb->tlb_nr,
+					      &tb->vaddrs[0]);
 #else
-			__flush_tlb_pending(CTX_HWBITS(mp->mm->context),
-					    mp->tlb_nr, &mp->vaddrs[0]);
+			__flush_tlb_pending(CTX_HWBITS(tb->mm->context),
+					    tb->tlb_nr, &tb->vaddrs[0]);
 #endif
 		}
-		mp->tlb_nr = 0;
+		tb->tlb_nr = 0;
 	}
 
-	put_cpu_var(mmu_gathers);
+	put_cpu_var(tlb_batch);
 }
 
-void tlb_batch_add(struct mm_struct *mm, unsigned long vaddr, pte_t *ptep, pte_t orig)
+void tlb_batch_add(struct mm_struct *mm, unsigned long vaddr,
+		   pte_t *ptep, pte_t orig, int fullmm)
 {
-	struct mmu_gather *mp = &__get_cpu_var(mmu_gathers);
+	struct tlb_batch *tb = &get_cpu_var(tlb_batch);
 	unsigned long nr;
 
 	vaddr &= PAGE_MASK;
@@ -77,21 +78,25 @@
 
 no_cache_flush:
 
-	if (mp->fullmm)
+	if (fullmm) {
+		put_cpu_var(tlb_batch);
 		return;
+	}
 
-	nr = mp->tlb_nr;
+	nr = tb->tlb_nr;
 
-	if (unlikely(nr != 0 && mm != mp->mm)) {
+	if (unlikely(nr != 0 && mm != tb->mm)) {
 		flush_tlb_pending();
 		nr = 0;
 	}
 
 	if (nr == 0)
-		mp->mm = mm;
+		tb->mm = mm;
 
-	mp->vaddrs[nr] = vaddr;
-	mp->tlb_nr = ++nr;
+	tb->vaddrs[nr] = vaddr;
+	tb->tlb_nr = ++nr;
 	if (nr >= TLB_BATCH_NR)
 		flush_tlb_pending();
+
+	put_cpu_var(tlb_batch);
 }
diff -druN linux-2.6.39-libre/arch/sparc/mm/tsb.c linux-3.0-rc7-libre/arch/sparc/mm/tsb.c
--- linux-2.6.39-libre/arch/sparc/mm/tsb.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/sparc/mm/tsb.c	2011-07-11 19:51:52.000000000 -0400
@@ -47,12 +47,13 @@
 	}
 }
 
-static void __flush_tsb_one(struct mmu_gather *mp, unsigned long hash_shift, unsigned long tsb, unsigned long nentries)
+static void __flush_tsb_one(struct tlb_batch *tb, unsigned long hash_shift,
+			    unsigned long tsb, unsigned long nentries)
 {
 	unsigned long i;
 
-	for (i = 0; i < mp->tlb_nr; i++) {
-		unsigned long v = mp->vaddrs[i];
+	for (i = 0; i < tb->tlb_nr; i++) {
+		unsigned long v = tb->vaddrs[i];
 		unsigned long tag, ent, hash;
 
 		v &= ~0x1UL;
@@ -65,9 +66,9 @@
 	}
 }
 
-void flush_tsb_user(struct mmu_gather *mp)
+void flush_tsb_user(struct tlb_batch *tb)
 {
-	struct mm_struct *mm = mp->mm;
+	struct mm_struct *mm = tb->mm;
 	unsigned long nentries, base, flags;
 
 	spin_lock_irqsave(&mm->context.lock, flags);
@@ -76,7 +77,7 @@
 	nentries = mm->context.tsb_block[MM_TSB_BASE].tsb_nentries;
 	if (tlb_type == cheetah_plus || tlb_type == hypervisor)
 		base = __pa(base);
-	__flush_tsb_one(mp, PAGE_SHIFT, base, nentries);
+	__flush_tsb_one(tb, PAGE_SHIFT, base, nentries);
 
 #ifdef CONFIG_HUGETLB_PAGE
 	if (mm->context.tsb_block[MM_TSB_HUGE].tsb) {
@@ -84,7 +85,7 @@
 		nentries = mm->context.tsb_block[MM_TSB_HUGE].tsb_nentries;
 		if (tlb_type == cheetah_plus || tlb_type == hypervisor)
 			base = __pa(base);
-		__flush_tsb_one(mp, HPAGE_SHIFT, base, nentries);
+		__flush_tsb_one(tb, HPAGE_SHIFT, base, nentries);
 	}
 #endif
 	spin_unlock_irqrestore(&mm->context.lock, flags);
@@ -179,7 +180,7 @@
 		printk(KERN_ERR "TSB[%s:%d]: Impossible TSB size %lu, killing process.\n",
 		       current->comm, current->pid, tsb_bytes);
 		do_exit(SIGSEGV);
-	};
+	}
 	tte |= pte_sz_bits(page_sz);
 
 	if (tlb_type == cheetah_plus || tlb_type == hypervisor) {
@@ -214,7 +215,7 @@
 #endif
 		default:
 			BUG();
-		};
+		}
 		hp->assoc = 1;
 		hp->num_ttes = tsb_bytes / 16;
 		hp->ctx_idx = 0;
@@ -229,7 +230,7 @@
 #endif
 		default:
 			BUG();
-		};
+		}
 		hp->tsb_base = tsb_paddr;
 		hp->resv = 0;
 	}
diff -druN linux-2.6.39-libre/arch/sparc/prom/console_32.c linux-3.0-rc7-libre/arch/sparc/prom/console_32.c
--- linux-2.6.39-libre/arch/sparc/prom/console_32.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/sparc/prom/console_32.c	2011-07-11 19:51:52.000000000 -0400
@@ -38,7 +38,7 @@
 		break;
 	default:
 		break;
-	};
+	}
 	restore_current();
 	spin_unlock_irqrestore(&prom_lock, flags);
 	return i; /* Ugh, we could spin forever on unsupported proms ;( */
diff -druN linux-2.6.39-libre/arch/sparc/prom/init_32.c linux-3.0-rc7-libre/arch/sparc/prom/init_32.c
--- linux-2.6.39-libre/arch/sparc/prom/init_32.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/sparc/prom/init_32.c	2011-07-11 19:51:52.000000000 -0400
@@ -53,7 +53,7 @@
 			    romvec->pv_romvers);
 		prom_halt();
 		break;
-	};
+	}
 
 	prom_rev = romvec->pv_plugin_revision;
 	prom_prev = romvec->pv_printrev;
diff -druN linux-2.6.39-libre/arch/sparc/prom/mp.c linux-3.0-rc7-libre/arch/sparc/prom/mp.c
--- linux-2.6.39-libre/arch/sparc/prom/mp.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/sparc/prom/mp.c	2011-07-11 19:51:52.000000000 -0400
@@ -35,7 +35,7 @@
 	case PROM_V3:
 		ret = (*(romvec->v3_cpustart))(cpunode, (int) ctable_reg, ctx, pc);
 		break;
-	};
+	}
 	restore_current();
 	spin_unlock_irqrestore(&prom_lock, flags);
 
diff -druN linux-2.6.39-libre/arch/tile/configs/tile_defconfig linux-3.0-rc7-libre/arch/tile/configs/tile_defconfig
--- linux-2.6.39-libre/arch/tile/configs/tile_defconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/tile/configs/tile_defconfig	1969-12-31 19:00:00.000000000 -0500
@@ -1,71 +0,0 @@
-CONFIG_EXPERIMENTAL=y
-# CONFIG_SWAP is not set
-CONFIG_SYSVIPC=y
-CONFIG_BLK_DEV_INITRD=y
-CONFIG_INITRAMFS_SOURCE="usr/contents.txt"
-CONFIG_EXPERT=y
-# CONFIG_COMPAT_BRK is not set
-CONFIG_PROFILING=y
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-# CONFIG_BLK_DEV_BSG is not set
-# CONFIG_IOSCHED_DEADLINE is not set
-# CONFIG_IOSCHED_CFQ is not set
-CONFIG_NO_HZ=y
-CONFIG_HIGH_RES_TIMERS=y
-CONFIG_HZ_100=y
-CONFIG_NET=y
-CONFIG_PACKET=y
-CONFIG_UNIX=y
-CONFIG_INET=y
-CONFIG_IP_MULTICAST=y
-# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
-# CONFIG_INET_XFRM_MODE_TUNNEL is not set
-# CONFIG_INET_LRO is not set
-# CONFIG_INET_DIAG is not set
-CONFIG_IPV6=y
-# CONFIG_WIRELESS is not set
-CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
-CONFIG_SCSI=y
-CONFIG_BLK_DEV_SD=y
-CONFIG_SCSI_CONSTANTS=y
-CONFIG_SCSI_LOGGING=y
-CONFIG_NETDEVICES=y
-CONFIG_TUN=y
-# CONFIG_NETDEV_10000 is not set
-# CONFIG_WLAN is not set
-# CONFIG_INPUT_MOUSEDEV is not set
-# CONFIG_INPUT_KEYBOARD is not set
-# CONFIG_INPUT_MOUSE is not set
-# CONFIG_SERIO is not set
-# CONFIG_VT is not set
-# CONFIG_LEGACY_PTYS is not set
-# CONFIG_HW_RANDOM is not set
-CONFIG_WATCHDOG=y
-CONFIG_WATCHDOG_NOWAYOUT=y
-# CONFIG_HID_SUPPORT is not set
-CONFIG_RTC_CLASS=y
-# CONFIG_RTC_INTF_SYSFS is not set
-# CONFIG_RTC_INTF_PROC is not set
-CONFIG_EXT2_FS=y
-CONFIG_EXT3_FS=y
-# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
-CONFIG_FUSE_FS=y
-CONFIG_MSDOS_FS=y
-CONFIG_VFAT_FS=m
-CONFIG_TMPFS=y
-CONFIG_HUGETLBFS=y
-CONFIG_NFS_FS=m
-CONFIG_NFS_V3=y
-CONFIG_NLS_CODEPAGE_437=y
-CONFIG_NLS_ISO8859_1=y
-CONFIG_FRAME_WARN=2048
-CONFIG_MAGIC_SYSRQ=y
-CONFIG_DEBUG_KERNEL=y
-CONFIG_DETECT_HUNG_TASK=y
-CONFIG_DEBUG_SPINLOCK_SLEEP=y
-CONFIG_DEBUG_INFO=y
-CONFIG_DEBUG_VM=y
-# CONFIG_RCU_CPU_STALL_DETECTOR is not set
-CONFIG_DEBUG_STACKOVERFLOW=y
-CONFIG_DEBUG_EXTRA_FLAGS="-femit-struct-debug-baseonly"
diff -druN linux-2.6.39-libre/arch/tile/configs/tilegx_defconfig linux-3.0-rc7-libre/arch/tile/configs/tilegx_defconfig
--- linux-2.6.39-libre/arch/tile/configs/tilegx_defconfig	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/tile/configs/tilegx_defconfig	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,1833 @@
+#
+# Automatically generated make config: don't edit
+# Linux/tilegx 2.6.39-rc5 Kernel Configuration
+# Wed May  4 11:08:04 2011
+#
+CONFIG_TILE=y
+CONFIG_MMU=y
+CONFIG_GENERIC_CSUM=y
+CONFIG_SEMAPHORE_SLEEPERS=y
+CONFIG_HAVE_ARCH_ALLOC_REMAP=y
+CONFIG_HAVE_SETUP_PER_CPU_AREA=y
+CONFIG_NEED_PER_CPU_PAGE_FIRST_CHUNK=y
+CONFIG_SYS_SUPPORTS_HUGETLBFS=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_DEFAULT_MIGRATION_COST=10000000
+CONFIG_ARCH_SUPPORTS_OPTIMIZED_INLINING=y
+CONFIG_ARCH_PHYS_ADDR_T_64BIT=y
+CONFIG_ARCH_DMA_ADDR_T_64BIT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_ARCH_DISCONTIGMEM_ENABLE=y
+CONFIG_ARCH_DISCONTIGMEM_DEFAULT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_STRICT_DEVMEM=y
+CONFIG_SMP=y
+# CONFIG_DEBUG_COPY_FROM_USER is not set
+CONFIG_HVC_TILE=y
+CONFIG_TILEGX=y
+CONFIG_64BIT=y
+CONFIG_ARCH_DEFCONFIG="arch/tile/configs/tilegx_defconfig"
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_CROSS_COMPILE=""
+CONFIG_LOCALVERSION=""
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_POSIX_MQUEUE_SYSCTL=y
+CONFIG_BSD_PROCESS_ACCT=y
+CONFIG_BSD_PROCESS_ACCT_V3=y
+# CONFIG_FHANDLE is not set
+CONFIG_TASKSTATS=y
+CONFIG_TASK_DELAY_ACCT=y
+CONFIG_TASK_XACCT=y
+CONFIG_TASK_IO_ACCOUNTING=y
+CONFIG_AUDIT=y
+CONFIG_HAVE_GENERIC_HARDIRQS=y
+
+#
+# IRQ subsystem
+#
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_GENERIC_IRQ_SHOW=y
+CONFIG_GENERIC_PENDING_IRQ=y
+
+#
+# RCU Subsystem
+#
+CONFIG_TREE_RCU=y
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=64
+# CONFIG_RCU_FANOUT_EXACT is not set
+# CONFIG_RCU_FAST_NO_HZ is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_IKCONFIG is not set
+CONFIG_LOG_BUF_SHIFT=19
+CONFIG_CGROUPS=y
+CONFIG_CGROUP_DEBUG=y
+CONFIG_CGROUP_NS=y
+# CONFIG_CGROUP_FREEZER is not set
+CONFIG_CGROUP_DEVICE=y
+CONFIG_CPUSETS=y
+CONFIG_PROC_PID_CPUSET=y
+CONFIG_CGROUP_CPUACCT=y
+CONFIG_RESOURCE_COUNTERS=y
+CONFIG_CGROUP_MEM_RES_CTLR=y
+CONFIG_CGROUP_MEM_RES_CTLR_SWAP=y
+CONFIG_CGROUP_MEM_RES_CTLR_SWAP_ENABLED=y
+CONFIG_CGROUP_SCHED=y
+CONFIG_FAIR_GROUP_SCHED=y
+CONFIG_RT_GROUP_SCHED=y
+CONFIG_BLK_CGROUP=y
+# CONFIG_DEBUG_BLK_CGROUP 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_SCHED_AUTOGROUP is not set
+CONFIG_MM_OWNER=y
+# CONFIG_SYSFS_DEPRECATED is not set
+CONFIG_RELAY=y
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE="usr/contents.txt"
+CONFIG_INITRAMFS_ROOT_UID=0
+CONFIG_INITRAMFS_ROOT_GID=0
+CONFIG_RD_GZIP=y
+# CONFIG_RD_BZIP2 is not set
+# CONFIG_RD_LZMA is not set
+# CONFIG_RD_XZ is not set
+# CONFIG_RD_LZO is not set
+CONFIG_INITRAMFS_COMPRESSION_NONE=y
+# CONFIG_INITRAMFS_COMPRESSION_GZIP is not set
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
+CONFIG_EXPERT=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_AIO=y
+CONFIG_EMBEDDED=y
+
+#
+# Kernel Performance Events And Counters
+#
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_PCI_QUIRKS=y
+CONFIG_SLUB_DEBUG=y
+# CONFIG_COMPAT_BRK is not set
+# CONFIG_SLAB is not set
+CONFIG_SLUB=y
+# CONFIG_SLOB is not set
+CONFIG_PROFILING=y
+CONFIG_USE_GENERIC_SMP_HELPERS=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_GCOV_KERNEL 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=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_STOP_MACHINE=y
+CONFIG_BLOCK=y
+CONFIG_BLK_DEV_BSG=y
+CONFIG_BLK_DEV_INTEGRITY=y
+# CONFIG_BLK_DEV_THROTTLING is not set
+CONFIG_BLOCK_COMPAT=y
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_CFQ_GROUP_IOSCHED=y
+# CONFIG_DEFAULT_DEADLINE is not set
+CONFIG_DEFAULT_CFQ=y
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
+CONFIG_PADATA=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=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
+
+#
+# Tilera-specific configuration
+#
+CONFIG_NR_CPUS=100
+CONFIG_TICK_ONESHOT=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+CONFIG_HZ_100=y
+# CONFIG_HZ_250 is not set
+# CONFIG_HZ_300 is not set
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=100
+CONFIG_SCHED_HRTICK=y
+# CONFIG_KEXEC is not set
+CONFIG_COMPAT=y
+CONFIG_SYSVIPC_COMPAT=y
+# CONFIG_HIGHMEM is not set
+CONFIG_NUMA=y
+CONFIG_NODES_SHIFT=2
+CONFIG_PAGE_OFFSET=0xC0000000
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_DISCONTIGMEM_MANUAL=y
+CONFIG_DISCONTIGMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+CONFIG_NEED_MULTIPLE_NODES=y
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_COMPACTION is not set
+CONFIG_MIGRATION=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_CMDLINE_BOOL is not set
+CONFIG_VMALLOC_RESERVE=0x1000000
+CONFIG_HARDWALL=y
+CONFIG_KERNEL_PL=1
+
+#
+# Bus options
+#
+CONFIG_PCI=y
+CONFIG_PCI_DOMAINS=y
+# CONFIG_NO_IOMEM is not set
+# CONFIG_NO_IOPORT is not set
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+CONFIG_PCI_DEBUG=y
+# CONFIG_PCI_STUB is not set
+# CONFIG_PCI_IOV is not set
+# CONFIG_HOTPLUG_PCI is not set
+
+#
+# Executable file formats
+#
+CONFIG_KCORE_ELF=y
+CONFIG_BINFMT_ELF=y
+CONFIG_COMPAT_BINFMT_ELF=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+# CONFIG_HAVE_AOUT is not set
+CONFIG_BINFMT_MISC=y
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=y
+CONFIG_XFRM_SUB_POLICY=y
+CONFIG_XFRM_MIGRATE=y
+CONFIG_XFRM_STATISTICS=y
+CONFIG_XFRM_IPCOMP=m
+CONFIG_NET_KEY=m
+CONFIG_NET_KEY_MIGRATE=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_ADVANCED_ROUTER=y
+# CONFIG_IP_FIB_TRIE_STATS is not set
+CONFIG_IP_MULTIPLE_TABLES=y
+CONFIG_IP_ROUTE_MULTIPATH=y
+CONFIG_IP_ROUTE_VERBOSE=y
+CONFIG_IP_ROUTE_CLASSID=y
+# CONFIG_IP_PNP is not set
+CONFIG_NET_IPIP=m
+# CONFIG_NET_IPGRE_DEMUX is not set
+CONFIG_IP_MROUTE=y
+# CONFIG_IP_MROUTE_MULTIPLE_TABLES is not set
+CONFIG_IP_PIMSM_V1=y
+CONFIG_IP_PIMSM_V2=y
+# CONFIG_ARPD is not set
+CONFIG_SYN_COOKIES=y
+CONFIG_INET_AH=m
+CONFIG_INET_ESP=m
+CONFIG_INET_IPCOMP=m
+CONFIG_INET_XFRM_TUNNEL=m
+CONFIG_INET_TUNNEL=m
+CONFIG_INET_XFRM_MODE_TRANSPORT=m
+CONFIG_INET_XFRM_MODE_TUNNEL=m
+CONFIG_INET_XFRM_MODE_BEET=m
+CONFIG_INET_LRO=y
+CONFIG_INET_DIAG=m
+CONFIG_INET_TCP_DIAG=m
+CONFIG_TCP_CONG_ADVANCED=y
+CONFIG_TCP_CONG_BIC=m
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_TCP_CONG_WESTWOOD=m
+CONFIG_TCP_CONG_HTCP=m
+CONFIG_TCP_CONG_HSTCP=m
+CONFIG_TCP_CONG_HYBLA=m
+CONFIG_TCP_CONG_VEGAS=m
+CONFIG_TCP_CONG_SCALABLE=m
+CONFIG_TCP_CONG_LP=m
+CONFIG_TCP_CONG_VENO=m
+CONFIG_TCP_CONG_YEAH=m
+CONFIG_TCP_CONG_ILLINOIS=m
+CONFIG_DEFAULT_CUBIC=y
+# CONFIG_DEFAULT_RENO is not set
+CONFIG_DEFAULT_TCP_CONG="cubic"
+CONFIG_TCP_MD5SIG=y
+CONFIG_IPV6=y
+CONFIG_IPV6_PRIVACY=y
+CONFIG_IPV6_ROUTER_PREF=y
+CONFIG_IPV6_ROUTE_INFO=y
+CONFIG_IPV6_OPTIMISTIC_DAD=y
+CONFIG_INET6_AH=m
+CONFIG_INET6_ESP=m
+CONFIG_INET6_IPCOMP=m
+CONFIG_IPV6_MIP6=m
+CONFIG_INET6_XFRM_TUNNEL=m
+CONFIG_INET6_TUNNEL=m
+CONFIG_INET6_XFRM_MODE_TRANSPORT=m
+CONFIG_INET6_XFRM_MODE_TUNNEL=m
+CONFIG_INET6_XFRM_MODE_BEET=m
+CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m
+CONFIG_IPV6_SIT=m
+# CONFIG_IPV6_SIT_6RD is not set
+CONFIG_IPV6_NDISC_NODETYPE=y
+CONFIG_IPV6_TUNNEL=m
+CONFIG_IPV6_MULTIPLE_TABLES=y
+# CONFIG_IPV6_SUBTREES is not set
+CONFIG_IPV6_MROUTE=y
+# CONFIG_IPV6_MROUTE_MULTIPLE_TABLES is not set
+CONFIG_IPV6_PIMSM_V2=y
+CONFIG_NETLABEL=y
+CONFIG_NETWORK_SECMARK=y
+# CONFIG_NETWORK_PHY_TIMESTAMPING 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=y
+CONFIG_NF_CONNTRACK_MARK=y
+CONFIG_NF_CONNTRACK_SECMARK=y
+CONFIG_NF_CONNTRACK_ZONES=y
+CONFIG_NF_CONNTRACK_EVENTS=y
+# CONFIG_NF_CONNTRACK_TIMESTAMP is not set
+CONFIG_NF_CT_PROTO_DCCP=m
+CONFIG_NF_CT_PROTO_GRE=m
+CONFIG_NF_CT_PROTO_SCTP=m
+CONFIG_NF_CT_PROTO_UDPLITE=m
+CONFIG_NF_CONNTRACK_AMANDA=m
+CONFIG_NF_CONNTRACK_FTP=m
+CONFIG_NF_CONNTRACK_H323=m
+CONFIG_NF_CONNTRACK_IRC=m
+CONFIG_NF_CONNTRACK_BROADCAST=m
+CONFIG_NF_CONNTRACK_NETBIOS_NS=m
+# CONFIG_NF_CONNTRACK_SNMP 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 is not set
+CONFIG_NETFILTER_TPROXY=m
+CONFIG_NETFILTER_XTABLES=y
+
+#
+# Xtables combined modules
+#
+CONFIG_NETFILTER_XT_MARK=m
+CONFIG_NETFILTER_XT_CONNMARK=m
+
+#
+# Xtables targets
+#
+# CONFIG_NETFILTER_XT_TARGET_AUDIT is not set
+# CONFIG_NETFILTER_XT_TARGET_CHECKSUM is not set
+CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
+CONFIG_NETFILTER_XT_TARGET_CONNMARK=m
+CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=m
+CONFIG_NETFILTER_XT_TARGET_CT=m
+CONFIG_NETFILTER_XT_TARGET_DSCP=m
+CONFIG_NETFILTER_XT_TARGET_HL=m
+CONFIG_NETFILTER_XT_TARGET_IDLETIMER=m
+CONFIG_NETFILTER_XT_TARGET_MARK=m
+CONFIG_NETFILTER_XT_TARGET_NFLOG=m
+CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
+CONFIG_NETFILTER_XT_TARGET_NOTRACK=m
+CONFIG_NETFILTER_XT_TARGET_RATEEST=m
+CONFIG_NETFILTER_XT_TARGET_TEE=m
+CONFIG_NETFILTER_XT_TARGET_TPROXY=m
+CONFIG_NETFILTER_XT_TARGET_TRACE=m
+CONFIG_NETFILTER_XT_TARGET_SECMARK=m
+CONFIG_NETFILTER_XT_TARGET_TCPMSS=m
+CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=m
+
+#
+# Xtables matches
+#
+# CONFIG_NETFILTER_XT_MATCH_ADDRTYPE is not set
+CONFIG_NETFILTER_XT_MATCH_CLUSTER=m
+CONFIG_NETFILTER_XT_MATCH_COMMENT=m
+CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m
+CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m
+CONFIG_NETFILTER_XT_MATCH_CONNMARK=m
+CONFIG_NETFILTER_XT_MATCH_CONNTRACK=y
+# CONFIG_NETFILTER_XT_MATCH_CPU is not set
+CONFIG_NETFILTER_XT_MATCH_DCCP=m
+# CONFIG_NETFILTER_XT_MATCH_DEVGROUP is not set
+CONFIG_NETFILTER_XT_MATCH_DSCP=m
+CONFIG_NETFILTER_XT_MATCH_ESP=m
+CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m
+CONFIG_NETFILTER_XT_MATCH_HELPER=m
+CONFIG_NETFILTER_XT_MATCH_HL=m
+CONFIG_NETFILTER_XT_MATCH_IPRANGE=m
+CONFIG_NETFILTER_XT_MATCH_IPVS=m
+CONFIG_NETFILTER_XT_MATCH_LENGTH=m
+CONFIG_NETFILTER_XT_MATCH_LIMIT=m
+CONFIG_NETFILTER_XT_MATCH_MAC=m
+CONFIG_NETFILTER_XT_MATCH_MARK=m
+CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m
+CONFIG_NETFILTER_XT_MATCH_OSF=m
+CONFIG_NETFILTER_XT_MATCH_OWNER=m
+CONFIG_NETFILTER_XT_MATCH_POLICY=m
+CONFIG_NETFILTER_XT_MATCH_PHYSDEV=m
+CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m
+CONFIG_NETFILTER_XT_MATCH_QUOTA=m
+CONFIG_NETFILTER_XT_MATCH_RATEEST=m
+CONFIG_NETFILTER_XT_MATCH_REALM=m
+CONFIG_NETFILTER_XT_MATCH_RECENT=m
+CONFIG_NETFILTER_XT_MATCH_SCTP=m
+CONFIG_NETFILTER_XT_MATCH_SOCKET=m
+CONFIG_NETFILTER_XT_MATCH_STATE=y
+CONFIG_NETFILTER_XT_MATCH_STATISTIC=m
+CONFIG_NETFILTER_XT_MATCH_STRING=m
+CONFIG_NETFILTER_XT_MATCH_TCPMSS=m
+CONFIG_NETFILTER_XT_MATCH_TIME=m
+CONFIG_NETFILTER_XT_MATCH_U32=m
+# CONFIG_IP_SET is not set
+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 is not set
+# CONFIG_IP_VS_SH is not set
+CONFIG_IP_VS_SED=m
+CONFIG_IP_VS_NQ=m
+
+#
+# IPVS application helper
+#
+# CONFIG_IP_VS_NFCT is not set
+# CONFIG_IP_VS_PE_SIP is not set
+
+#
+# IP: Netfilter Configuration
+#
+CONFIG_NF_DEFRAG_IPV4=y
+CONFIG_NF_CONNTRACK_IPV4=y
+# CONFIG_NF_CONNTRACK_PROC_COMPAT is not set
+CONFIG_IP_NF_QUEUE=m
+CONFIG_IP_NF_IPTABLES=y
+CONFIG_IP_NF_MATCH_AH=m
+CONFIG_IP_NF_MATCH_ECN=m
+CONFIG_IP_NF_MATCH_TTL=m
+CONFIG_IP_NF_FILTER=y
+CONFIG_IP_NF_TARGET_REJECT=y
+CONFIG_IP_NF_TARGET_LOG=m
+CONFIG_IP_NF_TARGET_ULOG=m
+# CONFIG_NF_NAT is not set
+CONFIG_IP_NF_MANGLE=m
+# CONFIG_IP_NF_TARGET_CLUSTERIP is not set
+CONFIG_IP_NF_TARGET_ECN=m
+CONFIG_IP_NF_TARGET_TTL=m
+CONFIG_IP_NF_RAW=m
+CONFIG_IP_NF_SECURITY=m
+CONFIG_IP_NF_ARPTABLES=m
+CONFIG_IP_NF_ARPFILTER=m
+CONFIG_IP_NF_ARP_MANGLE=m
+
+#
+# IPv6: Netfilter Configuration
+#
+CONFIG_NF_DEFRAG_IPV6=m
+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_IP6_NF_SECURITY=m
+CONFIG_BRIDGE_NF_EBTABLES=m
+CONFIG_BRIDGE_EBT_BROUTE=m
+CONFIG_BRIDGE_EBT_T_FILTER=m
+CONFIG_BRIDGE_EBT_T_NAT=m
+CONFIG_BRIDGE_EBT_802_3=m
+CONFIG_BRIDGE_EBT_AMONG=m
+CONFIG_BRIDGE_EBT_ARP=m
+CONFIG_BRIDGE_EBT_IP=m
+CONFIG_BRIDGE_EBT_IP6=m
+CONFIG_BRIDGE_EBT_LIMIT=m
+CONFIG_BRIDGE_EBT_MARK=m
+CONFIG_BRIDGE_EBT_PKTTYPE=m
+CONFIG_BRIDGE_EBT_STP=m
+CONFIG_BRIDGE_EBT_VLAN=m
+CONFIG_BRIDGE_EBT_ARPREPLY=m
+CONFIG_BRIDGE_EBT_DNAT=m
+CONFIG_BRIDGE_EBT_MARK_T=m
+CONFIG_BRIDGE_EBT_REDIRECT=m
+CONFIG_BRIDGE_EBT_SNAT=m
+CONFIG_BRIDGE_EBT_LOG=m
+CONFIG_BRIDGE_EBT_ULOG=m
+CONFIG_BRIDGE_EBT_NFLOG=m
+# 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_RDS=m
+CONFIG_RDS_TCP=m
+# CONFIG_RDS_DEBUG is not set
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_L2TP is not set
+CONFIG_STP=m
+CONFIG_GARP=m
+CONFIG_BRIDGE=m
+CONFIG_BRIDGE_IGMP_SNOOPING=y
+CONFIG_NET_DSA=y
+CONFIG_NET_DSA_TAG_DSA=y
+CONFIG_NET_DSA_TAG_EDSA=y
+CONFIG_NET_DSA_TAG_TRAILER=y
+CONFIG_NET_DSA_MV88E6XXX=y
+CONFIG_NET_DSA_MV88E6060=y
+CONFIG_NET_DSA_MV88E6XXX_NEED_PPU=y
+CONFIG_NET_DSA_MV88E6131=y
+CONFIG_NET_DSA_MV88E6123_61_65=y
+CONFIG_VLAN_8021Q=m
+CONFIG_VLAN_8021Q_GVRP=y
+# CONFIG_DECNET is not set
+CONFIG_LLC=m
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+CONFIG_PHONET=m
+# CONFIG_IEEE802154 is not set
+CONFIG_NET_SCHED=y
+
+#
+# Queueing/Scheduling
+#
+CONFIG_NET_SCH_CBQ=m
+CONFIG_NET_SCH_HTB=m
+CONFIG_NET_SCH_HFSC=m
+CONFIG_NET_SCH_PRIO=m
+CONFIG_NET_SCH_MULTIQ=m
+CONFIG_NET_SCH_RED=m
+# CONFIG_NET_SCH_SFB is not set
+CONFIG_NET_SCH_SFQ=m
+CONFIG_NET_SCH_TEQL=m
+CONFIG_NET_SCH_TBF=m
+CONFIG_NET_SCH_GRED=m
+CONFIG_NET_SCH_DSMARK=m
+CONFIG_NET_SCH_NETEM=m
+CONFIG_NET_SCH_DRR=m
+# CONFIG_NET_SCH_MQPRIO is not set
+# CONFIG_NET_SCH_CHOKE is not set
+CONFIG_NET_SCH_INGRESS=m
+
+#
+# Classification
+#
+CONFIG_NET_CLS=y
+CONFIG_NET_CLS_BASIC=m
+CONFIG_NET_CLS_TCINDEX=m
+CONFIG_NET_CLS_ROUTE4=m
+CONFIG_NET_CLS_FW=m
+CONFIG_NET_CLS_U32=m
+CONFIG_CLS_U32_PERF=y
+CONFIG_CLS_U32_MARK=y
+CONFIG_NET_CLS_RSVP=m
+CONFIG_NET_CLS_RSVP6=m
+CONFIG_NET_CLS_FLOW=m
+CONFIG_NET_CLS_CGROUP=y
+CONFIG_NET_EMATCH=y
+CONFIG_NET_EMATCH_STACK=32
+CONFIG_NET_EMATCH_CMP=m
+CONFIG_NET_EMATCH_NBYTE=m
+CONFIG_NET_EMATCH_U32=m
+CONFIG_NET_EMATCH_META=m
+CONFIG_NET_EMATCH_TEXT=m
+CONFIG_NET_CLS_ACT=y
+CONFIG_NET_ACT_POLICE=m
+CONFIG_NET_ACT_GACT=m
+CONFIG_GACT_PROB=y
+CONFIG_NET_ACT_MIRRED=m
+CONFIG_NET_ACT_IPT=m
+CONFIG_NET_ACT_NAT=m
+CONFIG_NET_ACT_PEDIT=m
+CONFIG_NET_ACT_SIMP=m
+CONFIG_NET_ACT_SKBEDIT=m
+# CONFIG_NET_ACT_CSUM is not set
+CONFIG_NET_CLS_IND=y
+CONFIG_NET_SCH_FIFO=y
+CONFIG_DCB=y
+CONFIG_DNS_RESOLVER=y
+# CONFIG_BATMAN_ADV is not set
+CONFIG_RPS=y
+CONFIG_RFS_ACCEL=y
+CONFIG_XPS=y
+
+#
+# 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
+# CONFIG_CAIF is not set
+# CONFIG_CEPH_LIB 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=y
+# CONFIG_FIRMWARE_IN_KERNEL is not set
+CONFIG_EXTRA_FIRMWARE=""
+# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_DEBUG_DEVRES is not set
+# CONFIG_SYS_HYPERVISOR is not set
+CONFIG_CONNECTOR=y
+CONFIG_PROC_EVENTS=y
+# CONFIG_MTD 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=m
+# CONFIG_BLK_DEV_DRBD is not set
+# CONFIG_BLK_DEV_NBD is not set
+CONFIG_BLK_DEV_SX8=m
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=16384
+# CONFIG_BLK_DEV_XIP is not set
+# CONFIG_CDROM_PKTCDVD is not set
+CONFIG_ATA_OVER_ETH=y
+# CONFIG_BLK_DEV_RBD is not set
+# CONFIG_SENSORS_LIS3LV02D 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_APDS9802ALS is not set
+# CONFIG_ISL29003 is not set
+# CONFIG_ISL29020 is not set
+# CONFIG_SENSORS_TSL2550 is not set
+# CONFIG_SENSORS_BH1780 is not set
+# CONFIG_SENSORS_BH1770 is not set
+# CONFIG_SENSORS_APDS990X is not set
+# CONFIG_HMC6352 is not set
+# CONFIG_DS1682 is not set
+# CONFIG_BMP085 is not set
+# CONFIG_PCH_PHUB is not set
+# CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_AT24 is not set
+# CONFIG_EEPROM_LEGACY is not set
+# CONFIG_EEPROM_MAX6875 is not set
+# CONFIG_EEPROM_93CX6 is not set
+# CONFIG_CB710_CORE is not set
+
+#
+# Texas Instruments shared transport line discipline
+#
+# CONFIG_SENSORS_LIS3_I2C is not set
+
+#
+# SCSI device support
+#
+CONFIG_SCSI_MOD=m
+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=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=m
+# CONFIG_CHR_DEV_ST is not set
+# CONFIG_CHR_DEV_OSST is not set
+# CONFIG_BLK_DEV_SR is not set
+# CONFIG_CHR_DEV_SG is not set
+# CONFIG_CHR_DEV_SCH is not set
+# CONFIG_SCSI_MULTI_LUN is not set
+CONFIG_SCSI_CONSTANTS=y
+CONFIG_SCSI_LOGGING=y
+# CONFIG_SCSI_SCAN_ASYNC is not set
+CONFIG_SCSI_WAIT_SCAN=m
+
+#
+# SCSI Transports
+#
+# CONFIG_SCSI_SPI_ATTRS is not set
+# CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
+CONFIG_SCSI_SAS_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_ISCSI_BOOT_SYSFS is not set
+# CONFIG_SCSI_CXGB3_ISCSI is not set
+# CONFIG_SCSI_CXGB4_ISCSI is not set
+# CONFIG_SCSI_BNX2_ISCSI is not set
+# CONFIG_SCSI_BNX2X_FCOE 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_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_DEBUG is not set
+# CONFIG_SCSI_PMCRAID is not set
+# CONFIG_SCSI_PM8001 is not set
+# CONFIG_SCSI_SRP is not set
+# CONFIG_SCSI_BFA_FC is not set
+# CONFIG_SCSI_LOWLEVEL_PCMCIA is not set
+# CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
+CONFIG_ATA=m
+# CONFIG_ATA_NONSTANDARD is not set
+CONFIG_ATA_VERBOSE_ERROR=y
+CONFIG_SATA_PMP=y
+
+#
+# Controllers with non-SFF native interface
+#
+# CONFIG_SATA_AHCI is not set
+# CONFIG_SATA_AHCI_PLATFORM is not set
+# CONFIG_SATA_INIC162X is not set
+# CONFIG_SATA_ACARD_AHCI is not set
+CONFIG_SATA_SIL24=m
+CONFIG_ATA_SFF=y
+
+#
+# SFF controllers with custom DMA interface
+#
+# CONFIG_PDC_ADMA is not set
+# CONFIG_SATA_QSTOR is not set
+# CONFIG_SATA_SX4 is not set
+CONFIG_ATA_BMDMA=y
+
+#
+# SATA SFF controllers with BMDMA
+#
+# CONFIG_ATA_PIIX is not set
+# CONFIG_SATA_MV is not set
+# CONFIG_SATA_NV is not set
+# CONFIG_SATA_PROMISE is not set
+# CONFIG_SATA_SIL is not set
+# CONFIG_SATA_SIS is not set
+# CONFIG_SATA_SVW is not set
+# CONFIG_SATA_ULI is not set
+# CONFIG_SATA_VIA is not set
+# CONFIG_SATA_VITESSE is not set
+
+#
+# PATA SFF controllers with BMDMA
+#
+# CONFIG_PATA_ALI is not set
+# CONFIG_PATA_AMD is not set
+# CONFIG_PATA_ARASAN_CF is not set
+# CONFIG_PATA_ARTOP is not set
+# CONFIG_PATA_ATIIXP is not set
+# CONFIG_PATA_ATP867X is not set
+# CONFIG_PATA_CMD64X is not set
+# CONFIG_PATA_CS5520 is not set
+# CONFIG_PATA_CS5530 is not set
+# CONFIG_PATA_CS5536 is not set
+# CONFIG_PATA_CYPRESS is not set
+# CONFIG_PATA_EFAR 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_IT8213 is not set
+# CONFIG_PATA_IT821X is not set
+# CONFIG_PATA_JMICRON is not set
+# CONFIG_PATA_MARVELL is not set
+# CONFIG_PATA_NETCELL is not set
+# CONFIG_PATA_NINJA32 is not set
+# CONFIG_PATA_NS87415 is not set
+# CONFIG_PATA_OLDPIIX 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_SC1200 is not set
+# CONFIG_PATA_SCH 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_TRIFLEX is not set
+# CONFIG_PATA_VIA is not set
+# CONFIG_PATA_WINBOND is not set
+
+#
+# PIO-only SFF controllers
+#
+# CONFIG_PATA_CMD640_PCI is not set
+# CONFIG_PATA_MPIIX is not set
+# CONFIG_PATA_NS87410 is not set
+# CONFIG_PATA_OPTI is not set
+# CONFIG_PATA_PLATFORM is not set
+# CONFIG_PATA_RZ1000 is not set
+
+#
+# Generic fallback / legacy drivers
+#
+# CONFIG_ATA_GENERIC is not set
+# CONFIG_PATA_LEGACY is not set
+CONFIG_MD=y
+CONFIG_BLK_DEV_MD=y
+CONFIG_MD_AUTODETECT=y
+CONFIG_MD_LINEAR=m
+CONFIG_MD_RAID0=m
+CONFIG_MD_RAID1=m
+CONFIG_MD_RAID10=m
+CONFIG_MD_RAID456=m
+CONFIG_MULTICORE_RAID456=y
+# CONFIG_MD_MULTIPATH is not set
+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_RAID is not set
+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_DM_FLAKEY is not set
+# CONFIG_TARGET_CORE is not set
+# CONFIG_FUSION is not set
+
+#
+# IEEE 1394 (FireWire) support
+#
+# CONFIG_FIREWIRE is not set
+# CONFIG_FIREWIRE_NOSY is not set
+# CONFIG_I2O is not set
+CONFIG_NETDEVICES=y
+CONFIG_IFB=m
+CONFIG_DUMMY=m
+CONFIG_BONDING=m
+CONFIG_MACVLAN=m
+CONFIG_MACVTAP=m
+# CONFIG_EQUALIZER is not set
+CONFIG_TUN=y
+CONFIG_VETH=m
+# CONFIG_ARCNET is not set
+# CONFIG_MII 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_BCM63XX_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 is not set
+CONFIG_NETDEV_1000=y
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+# CONFIG_E1000 is not set
+CONFIG_E1000E=m
+# CONFIG_IP1000 is not set
+# CONFIG_IGB is not set
+# CONFIG_IGBVF is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_R8169 is not set
+# CONFIG_SIS190 is not set
+# CONFIG_SKGE is not set
+# CONFIG_SKY2 is not set
+# CONFIG_VIA_VELOCITY is not set
+# CONFIG_TIGON3 is not set
+# CONFIG_BNX2 is not set
+# CONFIG_CNIC is not set
+# CONFIG_QLA3XXX is not set
+# CONFIG_ATL1 is not set
+# CONFIG_ATL1E is not set
+# CONFIG_ATL1C is not set
+# CONFIG_JME is not set
+# CONFIG_STMMAC_ETH is not set
+# CONFIG_PCH_GBE is not set
+# CONFIG_NETDEV_10000 is not set
+# CONFIG_TR is not set
+# CONFIG_WLAN is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
+# CONFIG_WAN is not set
+
+#
+# CAIF transport drivers
+#
+# CONFIG_TILE_NET 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 is not set
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+# CONFIG_VT is not set
+CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+# CONFIG_NOZOMI is not set
+# CONFIG_N_GSM is not set
+CONFIG_DEVKMEM=y
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+# CONFIG_SERIAL_MFD_HSU is not set
+# CONFIG_SERIAL_JSM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
+# CONFIG_SERIAL_ALTERA_JTAGUART is not set
+# CONFIG_SERIAL_ALTERA_UART is not set
+# CONFIG_SERIAL_PCH_UART is not set
+# CONFIG_TTY_PRINTK is not set
+CONFIG_HVC_DRIVER=y
+# CONFIG_IPMI_HANDLER is not set
+CONFIG_HW_RANDOM=y
+CONFIG_HW_RANDOM_TIMERIOMEM=m
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+
+#
+# PCMCIA character devices
+#
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+CONFIG_DEVPORT=y
+# CONFIG_RAMOOPS is not set
+CONFIG_I2C=y
+CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_COMPAT=y
+CONFIG_I2C_CHARDEV=y
+# CONFIG_I2C_MUX is not set
+CONFIG_I2C_HELPER_AUTO=y
+
+#
+# I2C Hardware Bus support
+#
+
+#
+# PC SMBus host controller drivers
+#
+# CONFIG_I2C_ALI1535 is not set
+# CONFIG_I2C_ALI1563 is not set
+# CONFIG_I2C_ALI15X3 is not set
+# CONFIG_I2C_AMD756 is not set
+# CONFIG_I2C_AMD8111 is not set
+# CONFIG_I2C_I801 is not set
+# CONFIG_I2C_ISCH is not set
+# CONFIG_I2C_PIIX4 is not set
+# CONFIG_I2C_NFORCE2 is not set
+# CONFIG_I2C_SIS5595 is not set
+# CONFIG_I2C_SIS630 is not set
+# CONFIG_I2C_SIS96X is not set
+# CONFIG_I2C_VIA is not set
+# CONFIG_I2C_VIAPRO is not set
+
+#
+# I2C system bus drivers (mostly embedded / system-on-chip)
+#
+# CONFIG_I2C_INTEL_MID is not set
+# CONFIG_I2C_OCORES is not set
+# CONFIG_I2C_PCA_PLATFORM is not set
+# CONFIG_I2C_PXA_PCI is not set
+# CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_XILINX is not set
+# CONFIG_I2C_EG20T 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_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 is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
+
+#
+# PPS generators support
+#
+# 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
+CONFIG_MFD_SUPPORT=y
+# 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_TPS6105X is not set
+# CONFIG_TPS6507X is not set
+# CONFIG_TWL4030_CORE is not set
+# CONFIG_MFD_STMPE is not set
+# CONFIG_MFD_TC3589X 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_MAX8997 is not set
+# CONFIG_MFD_MAX8998 is not set
+# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM831X_I2C is not set
+# CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_WM8994 is not set
+# CONFIG_MFD_PCF50633 is not set
+# CONFIG_ABX500_CORE is not set
+# CONFIG_LPC_SCH is not set
+# CONFIG_MFD_RDC321X is not set
+# CONFIG_MFD_JANZ_CMODIO is not set
+# CONFIG_MFD_VX855 is not set
+# CONFIG_MFD_WL1273_CORE is not set
+# CONFIG_REGULATOR is not set
+# CONFIG_MEDIA_SUPPORT is not set
+
+#
+# Graphics support
+#
+# CONFIG_VGA_ARB is not set
+# CONFIG_DRM is not set
+# CONFIG_STUB_POULSBO is not set
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
+# CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+# CONFIG_SOUND is not set
+# CONFIG_HID_SUPPORT is not set
+# CONFIG_USB_SUPPORT is not set
+# CONFIG_UWB is not set
+# CONFIG_MMC is not set
+# CONFIG_MEMSTICK is not set
+# CONFIG_NEW_LEDS is not set
+# CONFIG_NFC_DEVICES is not set
+# CONFIG_ACCESSIBILITY is not set
+# CONFIG_INFINIBAND is not set
+# CONFIG_EDAC is not set
+CONFIG_RTC_LIB=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_HCTOSYS=y
+CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
+# CONFIG_RTC_DEBUG is not set
+
+#
+# RTC interfaces
+#
+CONFIG_RTC_INTF_SYSFS=y
+CONFIG_RTC_INTF_PROC=y
+CONFIG_RTC_INTF_DEV=y
+# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
+# CONFIG_RTC_DRV_TEST is not set
+
+#
+# I2C RTC drivers
+#
+# CONFIG_RTC_DRV_DS1307 is not set
+# CONFIG_RTC_DRV_DS1374 is not set
+# CONFIG_RTC_DRV_DS1672 is not set
+# CONFIG_RTC_DRV_DS3232 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_ISL12022 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_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_TILE=y
+# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
+# CONFIG_UIO is not set
+# CONFIG_STAGING is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XATTR=y
+CONFIG_EXT2_FS_POSIX_ACL=y
+CONFIG_EXT2_FS_SECURITY=y
+CONFIG_EXT2_FS_XIP=y
+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_FS_XIP=y
+CONFIG_JBD=y
+# CONFIG_JBD_DEBUG is not set
+CONFIG_JBD2=y
+CONFIG_JBD2_DEBUG=y
+CONFIG_FS_MBCACHE=y
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_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=m
+CONFIG_GFS2_FS_LOCKING_DLM=y
+# CONFIG_OCFS2_FS is not set
+CONFIG_BTRFS_FS=m
+CONFIG_BTRFS_FS_POSIX_ACL=y
+# CONFIG_NILFS2_FS is not set
+CONFIG_FS_POSIX_ACL=y
+CONFIG_EXPORTFS=y
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
+CONFIG_DNOTIFY=y
+CONFIG_INOTIFY_USER=y
+# CONFIG_FANOTIFY is not set
+CONFIG_QUOTA=y
+CONFIG_QUOTA_NETLINK_INTERFACE=y
+# CONFIG_PRINT_QUOTA_WARNING is not set
+# CONFIG_QUOTA_DEBUG is not set
+CONFIG_QUOTA_TREE=y
+# CONFIG_QFMT_V1 is not set
+CONFIG_QFMT_V2=y
+CONFIG_QUOTACTL=y
+# CONFIG_AUTOFS4_FS is not set
+CONFIG_FUSE_FS=y
+CONFIG_CUSE=m
+CONFIG_GENERIC_ACL=y
+
+#
+# Caches
+#
+CONFIG_FSCACHE=m
+CONFIG_FSCACHE_STATS=y
+# CONFIG_FSCACHE_HISTOGRAM is not set
+# CONFIG_FSCACHE_DEBUG is not set
+# CONFIG_FSCACHE_OBJECT_LIST is not set
+CONFIG_CACHEFILES=m
+# CONFIG_CACHEFILES_DEBUG is not set
+# CONFIG_CACHEFILES_HISTOGRAM is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+CONFIG_ISO9660_FS=m
+CONFIG_JOLIET=y
+CONFIG_ZISOFS=y
+CONFIG_UDF_FS=m
+CONFIG_UDF_NLS=y
+
+#
+# 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="ascii"
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_KCORE=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+CONFIG_TMPFS_POSIX_ACL=y
+CONFIG_HUGETLBFS=y
+CONFIG_HUGETLB_PAGE=y
+CONFIG_CONFIGFS_FS=m
+CONFIG_MISC_FILESYSTEMS=y
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+CONFIG_ECRYPT_FS=m
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_LOGFS is not set
+CONFIG_CRAMFS=m
+CONFIG_SQUASHFS=m
+# CONFIG_SQUASHFS_XATTR is not set
+# CONFIG_SQUASHFS_LZO is not set
+# CONFIG_SQUASHFS_XZ is not set
+# 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_PSTORE 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_NFS_V4_1=y
+CONFIG_PNFS_FILE_LAYOUT=m
+CONFIG_NFS_FSCACHE=y
+# CONFIG_NFS_USE_LEGACY_DNS is not set
+CONFIG_NFS_USE_KERNEL_DNS=y
+# CONFIG_NFS_USE_NEW_IDMAPPER is not set
+CONFIG_NFSD=m
+CONFIG_NFSD_DEPRECATED=y
+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_NFS_ACL_SUPPORT=m
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=m
+CONFIG_SUNRPC_GSS=m
+CONFIG_RPCSEC_GSS_KRB5=m
+# 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_UPCALL=y
+CONFIG_CIFS_XATTR=y
+CONFIG_CIFS_POSIX=y
+# CONFIG_CIFS_DEBUG2 is not set
+CONFIG_CIFS_DFS_UPCALL=y
+CONFIG_CIFS_FSCACHE=y
+# CONFIG_CIFS_ACL is not set
+CONFIG_CIFS_EXPERIMENTAL=y
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+CONFIG_OSF_PARTITION=y
+CONFIG_AMIGA_PARTITION=y
+# 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 is not set
+CONFIG_SGI_PARTITION=y
+# CONFIG_ULTRIX_PARTITION is not set
+CONFIG_SUN_PARTITION=y
+CONFIG_KARMA_PARTITION=y
+CONFIG_EFI_PARTITION=y
+# CONFIG_SYSV68_PARTITION is not set
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="utf8"
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_CODEPAGE_737=m
+CONFIG_NLS_CODEPAGE_775=m
+CONFIG_NLS_CODEPAGE_850=m
+CONFIG_NLS_CODEPAGE_852=m
+CONFIG_NLS_CODEPAGE_855=m
+CONFIG_NLS_CODEPAGE_857=m
+CONFIG_NLS_CODEPAGE_860=m
+CONFIG_NLS_CODEPAGE_861=m
+CONFIG_NLS_CODEPAGE_862=m
+CONFIG_NLS_CODEPAGE_863=m
+CONFIG_NLS_CODEPAGE_864=m
+CONFIG_NLS_CODEPAGE_865=m
+CONFIG_NLS_CODEPAGE_866=m
+CONFIG_NLS_CODEPAGE_869=m
+CONFIG_NLS_CODEPAGE_936=m
+CONFIG_NLS_CODEPAGE_950=m
+CONFIG_NLS_CODEPAGE_932=m
+CONFIG_NLS_CODEPAGE_949=m
+CONFIG_NLS_CODEPAGE_874=m
+CONFIG_NLS_ISO8859_8=m
+CONFIG_NLS_CODEPAGE_1250=m
+CONFIG_NLS_CODEPAGE_1251=m
+CONFIG_NLS_ASCII=y
+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=m
+CONFIG_DLM_DEBUG=y
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_DEFAULT_MESSAGE_LOGLEVEL=4
+# CONFIG_ENABLE_WARN_DEPRECATED is not set
+CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_FRAME_WARN=2048
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_STRIP_ASM_SYMS=y
+# CONFIG_UNUSED_SYMBOLS is not set
+CONFIG_DEBUG_FS=y
+CONFIG_HEADERS_CHECK=y
+# CONFIG_DEBUG_SECTION_MISMATCH is not set
+CONFIG_DEBUG_KERNEL=y
+CONFIG_DEBUG_SHIRQ=y
+CONFIG_LOCKUP_DETECTOR=y
+# CONFIG_HARDLOCKUP_DETECTOR is not set
+# CONFIG_BOOTPARAM_HARDLOCKUP_PANIC is not set
+CONFIG_BOOTPARAM_HARDLOCKUP_PANIC_VALUE=0
+# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
+CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
+CONFIG_DETECT_HUNG_TASK=y
+# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set
+CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0
+CONFIG_SCHED_DEBUG=y
+CONFIG_SCHEDSTATS=y
+CONFIG_TIMER_STATS=y
+# CONFIG_DEBUG_OBJECTS is not set
+# CONFIG_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_SPARSE_RCU_POINTER is not set
+# CONFIG_LOCK_STAT is not set
+CONFIG_DEBUG_SPINLOCK_SLEEP=y
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+CONFIG_STACKTRACE=y
+# CONFIG_DEBUG_KOBJECT is not set
+CONFIG_DEBUG_INFO=y
+CONFIG_DEBUG_INFO_REDUCED=y
+CONFIG_DEBUG_VM=y
+# CONFIG_DEBUG_WRITECOUNT is not set
+CONFIG_DEBUG_MEMORY_INIT=y
+CONFIG_DEBUG_LIST=y
+# CONFIG_TEST_LIST_SORT is not set
+# CONFIG_DEBUG_SG is not set
+# CONFIG_DEBUG_NOTIFIERS is not set
+CONFIG_DEBUG_CREDENTIALS=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=y
+# CONFIG_LKDTM is not set
+# CONFIG_FAULT_INJECTION is not set
+# CONFIG_SYSCTL_SYSCALL_CHECK is not set
+# CONFIG_DEBUG_PAGEALLOC is not set
+CONFIG_TRACING_SUPPORT=y
+CONFIG_FTRACE=y
+# CONFIG_IRQSOFF_TRACER is not set
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_ENABLE_DEFAULT_TRACERS is not set
+CONFIG_BRANCH_PROFILE_NONE=y
+# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
+# CONFIG_PROFILE_ALL_BRANCHES is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_BUILD_DOCSRC is not set
+CONFIG_DYNAMIC_DEBUG=y
+# CONFIG_ATOMIC64_SELFTEST is not set
+CONFIG_ASYNC_RAID6_TEST=m
+# CONFIG_SAMPLES is not set
+# CONFIG_TEST_KSTRTOX is not set
+CONFIG_EARLY_PRINTK=y
+CONFIG_DEBUG_STACKOVERFLOW=y
+# CONFIG_DEBUG_STACK_USAGE is not set
+CONFIG_DEBUG_EXTRA_FLAGS=""
+
+#
+# Security options
+#
+CONFIG_KEYS=y
+CONFIG_KEYS_DEBUG_PROC_KEYS=y
+# CONFIG_SECURITY_DMESG_RESTRICT is not set
+CONFIG_SECURITY=y
+CONFIG_SECURITYFS=y
+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_SECURITY_APPARMOR is not set
+# CONFIG_IMA is not set
+CONFIG_DEFAULT_SECURITY_SELINUX=y
+# CONFIG_DEFAULT_SECURITY_DAC is not set
+CONFIG_DEFAULT_SECURITY="selinux"
+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_ALGAPI=y
+CONFIG_CRYPTO_ALGAPI2=y
+CONFIG_CRYPTO_AEAD=m
+CONFIG_CRYPTO_AEAD2=y
+CONFIG_CRYPTO_BLKCIPHER=m
+CONFIG_CRYPTO_BLKCIPHER2=y
+CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_HASH2=y
+CONFIG_CRYPTO_RNG=m
+CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_PCOMP=m
+CONFIG_CRYPTO_PCOMP2=y
+CONFIG_CRYPTO_MANAGER=y
+CONFIG_CRYPTO_MANAGER2=y
+CONFIG_CRYPTO_MANAGER_DISABLE_TESTS=y
+CONFIG_CRYPTO_GF128MUL=m
+CONFIG_CRYPTO_NULL=m
+CONFIG_CRYPTO_PCRYPT=m
+CONFIG_CRYPTO_WORKQUEUE=y
+CONFIG_CRYPTO_CRYPTD=m
+CONFIG_CRYPTO_AUTHENC=m
+CONFIG_CRYPTO_TEST=m
+
+#
+# Authenticated Encryption with Associated Data
+#
+CONFIG_CRYPTO_CCM=m
+CONFIG_CRYPTO_GCM=m
+CONFIG_CRYPTO_SEQIV=m
+
+#
+# Block modes
+#
+CONFIG_CRYPTO_CBC=m
+CONFIG_CRYPTO_CTR=m
+CONFIG_CRYPTO_CTS=m
+CONFIG_CRYPTO_ECB=m
+CONFIG_CRYPTO_LRW=m
+CONFIG_CRYPTO_PCBC=m
+CONFIG_CRYPTO_XTS=m
+
+#
+# Hash modes
+#
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_XCBC=m
+CONFIG_CRYPTO_VMAC=m
+
+#
+# Digest
+#
+CONFIG_CRYPTO_CRC32C=y
+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=y
+CONFIG_CRYPTO_SHA256=m
+CONFIG_CRYPTO_SHA512=m
+CONFIG_CRYPTO_TGR192=m
+CONFIG_CRYPTO_WP512=m
+
+#
+# Ciphers
+#
+CONFIG_CRYPTO_AES=m
+CONFIG_CRYPTO_ANUBIS=m
+CONFIG_CRYPTO_ARC4=m
+CONFIG_CRYPTO_BLOWFISH=m
+CONFIG_CRYPTO_CAMELLIA=m
+CONFIG_CRYPTO_CAST5=m
+CONFIG_CRYPTO_CAST6=m
+CONFIG_CRYPTO_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=m
+CONFIG_CRYPTO_LZO=m
+
+#
+# Random Number Generation
+#
+CONFIG_CRYPTO_ANSI_CPRNG=m
+# CONFIG_CRYPTO_USER_API_HASH is not set
+# CONFIG_CRYPTO_USER_API_SKCIPHER is not set
+CONFIG_CRYPTO_HW=y
+CONFIG_CRYPTO_DEV_HIFN_795X=m
+CONFIG_CRYPTO_DEV_HIFN_795X_RNG=y
+# CONFIG_BINARY_PRINTF is not set
+
+#
+# Library routines
+#
+CONFIG_RAID6_PQ=m
+CONFIG_BITREVERSE=y
+CONFIG_GENERIC_FIND_FIRST_BIT=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_GENERIC_FIND_LAST_BIT=y
+# CONFIG_CRC_CCITT is not set
+CONFIG_CRC16=y
+CONFIG_CRC_T10DIF=y
+CONFIG_CRC_ITU_T=m
+CONFIG_CRC32=y
+# CONFIG_CRC7 is not set
+CONFIG_LIBCRC32C=m
+CONFIG_AUDIT_GENERIC=y
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=m
+CONFIG_LZO_COMPRESS=m
+CONFIG_LZO_DECOMPRESS=m
+# CONFIG_XZ_DEC is not set
+# CONFIG_XZ_DEC_BCJ is not set
+CONFIG_DECOMPRESS_GZIP=y
+CONFIG_TEXTSEARCH=y
+CONFIG_TEXTSEARCH_KMP=m
+CONFIG_TEXTSEARCH_BM=m
+CONFIG_TEXTSEARCH_FSM=m
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
+CONFIG_CPU_RMAP=y
+CONFIG_NLATTR=y
+# CONFIG_AVERAGE is not set
+# CONFIG_VIRTUALIZATION is not set
diff -druN linux-2.6.39-libre/arch/tile/configs/tilepro_defconfig linux-3.0-rc7-libre/arch/tile/configs/tilepro_defconfig
--- linux-2.6.39-libre/arch/tile/configs/tilepro_defconfig	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/tile/configs/tilepro_defconfig	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,1163 @@
+#
+# Automatically generated make config: don't edit
+# Linux/tile 2.6.39-rc5 Kernel Configuration
+# Tue May  3 09:15:02 2011
+#
+CONFIG_TILE=y
+CONFIG_MMU=y
+CONFIG_GENERIC_CSUM=y
+CONFIG_SEMAPHORE_SLEEPERS=y
+CONFIG_HAVE_ARCH_ALLOC_REMAP=y
+CONFIG_HAVE_SETUP_PER_CPU_AREA=y
+CONFIG_NEED_PER_CPU_PAGE_FIRST_CHUNK=y
+CONFIG_SYS_SUPPORTS_HUGETLBFS=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_DEFAULT_MIGRATION_COST=10000000
+CONFIG_ARCH_SUPPORTS_OPTIMIZED_INLINING=y
+CONFIG_ARCH_PHYS_ADDR_T_64BIT=y
+CONFIG_ARCH_DMA_ADDR_T_64BIT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_ARCH_DISCONTIGMEM_ENABLE=y
+CONFIG_ARCH_DISCONTIGMEM_DEFAULT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_STRICT_DEVMEM=y
+CONFIG_SMP=y
+# CONFIG_DEBUG_COPY_FROM_USER is not set
+CONFIG_HVC_TILE=y
+# CONFIG_TILEGX is not set
+CONFIG_ARCH_DEFCONFIG="arch/tile/configs/tile_defconfig"
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_CROSS_COMPILE=""
+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_FHANDLE=y
+# CONFIG_TASKSTATS is not set
+# CONFIG_AUDIT is not set
+CONFIG_HAVE_GENERIC_HARDIRQS=y
+
+#
+# IRQ subsystem
+#
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_GENERIC_IRQ_SHOW=y
+CONFIG_GENERIC_PENDING_IRQ=y
+
+#
+# RCU Subsystem
+#
+CONFIG_TREE_RCU=y
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
+# CONFIG_RCU_FAST_NO_HZ 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_NAMESPACES is not set
+# CONFIG_SCHED_AUTOGROUP is not set
+# CONFIG_SYSFS_DEPRECATED is not set
+# CONFIG_RELAY is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE="usr/contents.txt"
+CONFIG_INITRAMFS_ROOT_UID=0
+CONFIG_INITRAMFS_ROOT_GID=0
+CONFIG_RD_GZIP=y
+# CONFIG_RD_BZIP2 is not set
+# CONFIG_RD_LZMA is not set
+# CONFIG_RD_XZ is not set
+# CONFIG_RD_LZO is not set
+CONFIG_INITRAMFS_COMPRESSION_NONE=y
+# CONFIG_INITRAMFS_COMPRESSION_GZIP is not set
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
+CONFIG_EXPERT=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_AIO=y
+CONFIG_EMBEDDED=y
+
+#
+# Kernel Performance Events And Counters
+#
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_PCI_QUIRKS=y
+CONFIG_SLUB_DEBUG=y
+# CONFIG_COMPAT_BRK is not set
+# CONFIG_SLAB is not set
+CONFIG_SLUB=y
+# CONFIG_SLOB is not set
+CONFIG_PROFILING=y
+CONFIG_USE_GENERIC_SMP_HELPERS=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_STOP_MACHINE=y
+CONFIG_BLOCK=y
+CONFIG_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_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=y
+
+#
+# Tilera-specific configuration
+#
+CONFIG_NR_CPUS=64
+CONFIG_TICK_ONESHOT=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+CONFIG_HZ_100=y
+# CONFIG_HZ_250 is not set
+# CONFIG_HZ_300 is not set
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=100
+CONFIG_SCHED_HRTICK=y
+# CONFIG_KEXEC is not set
+CONFIG_HIGHMEM=y
+CONFIG_NUMA=y
+CONFIG_NODES_SHIFT=2
+# CONFIG_VMSPLIT_3_75G is not set
+# CONFIG_VMSPLIT_3_5G is not set
+CONFIG_VMSPLIT_3G=y
+# CONFIG_VMSPLIT_2_75G is not set
+# CONFIG_VMSPLIT_2_5G is not set
+# CONFIG_VMSPLIT_2_25G is not set
+# CONFIG_VMSPLIT_2G is not set
+# CONFIG_VMSPLIT_1G is not set
+CONFIG_PAGE_OFFSET=0xC0000000
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_DISCONTIGMEM_MANUAL=y
+CONFIG_DISCONTIGMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+CONFIG_NEED_MULTIPLE_NODES=y
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_COMPACTION is not set
+CONFIG_MIGRATION=y
+CONFIG_PHYS_ADDR_T_64BIT=y
+CONFIG_ZONE_DMA_FLAG=0
+CONFIG_BOUNCE=y
+CONFIG_VIRT_TO_BUS=y
+# CONFIG_KSM is not set
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
+# CONFIG_CMDLINE_BOOL is not set
+CONFIG_VMALLOC_RESERVE=0x1000000
+CONFIG_HARDWALL=y
+CONFIG_KERNEL_PL=1
+
+#
+# Bus options
+#
+CONFIG_PCI=y
+CONFIG_PCI_DOMAINS=y
+# CONFIG_NO_IOMEM is not set
+# CONFIG_NO_IOPORT is not set
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+# CONFIG_PCI_DEBUG is not set
+# CONFIG_PCI_STUB is not set
+# CONFIG_PCI_IOV is not set
+# CONFIG_HOTPLUG_PCI is not set
+
+#
+# Executable file formats
+#
+CONFIG_KCORE_ELF=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_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_NET_KEY is not set
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+# CONFIG_IP_PNP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE_DEMUX 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=y
+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+CONFIG_INET_XFRM_MODE_BEET=y
+# CONFIG_INET_LRO is not set
+# CONFIG_INET_DIAG is not set
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+CONFIG_IPV6=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_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_MROUTE is not set
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETWORK_PHY_TIMESTAMPING 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_L2TP 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
+# CONFIG_BATMAN_ADV is not set
+CONFIG_RPS=y
+CONFIG_RFS_ACCEL=y
+CONFIG_XPS=y
+
+#
+# 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
+# CONFIG_CAIF is not set
+# CONFIG_CEPH_LIB 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 is not set
+# CONFIG_PARPORT is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_UMEM is not set
+# CONFIG_BLK_DEV_COW_COMMON is not set
+# CONFIG_BLK_DEV_LOOP is not set
+
+#
+# DRBD disabled because PROC_FS, INET or CONNECTOR not selected
+#
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_SX8 is not set
+# CONFIG_BLK_DEV_RAM is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+# CONFIG_BLK_DEV_RBD is not set
+# CONFIG_SENSORS_LIS3LV02D 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_PCH_PHUB is not set
+# CONFIG_C2PORT is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_93CX6 is not set
+# CONFIG_CB710_CORE is not set
+
+#
+# Texas Instruments shared transport line discipline
+#
+
+#
+# SCSI device support
+#
+CONFIG_SCSI_MOD=y
+# 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=y
+CONFIG_SCSI_LOGGING=y
+# CONFIG_SCSI_SCAN_ASYNC is not set
+CONFIG_SCSI_WAIT_SCAN=m
+
+#
+# SCSI Transports
+#
+# CONFIG_SCSI_SPI_ATTRS is not set
+# CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
+# CONFIG_SCSI_SAS_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_ISCSI_BOOT_SYSFS is not set
+# CONFIG_SCSI_CXGB3_ISCSI is not set
+# CONFIG_SCSI_CXGB4_ISCSI is not set
+# CONFIG_SCSI_BNX2_ISCSI is not set
+# CONFIG_SCSI_BNX2X_FCOE 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_STEX is not set
+# CONFIG_SCSI_SYM53C8XX_2 is not set
+# CONFIG_SCSI_QLOGIC_1280 is not set
+# CONFIG_SCSI_QLA_FC is not set
+# CONFIG_SCSI_QLA_ISCSI is not set
+# CONFIG_SCSI_LPFC is not set
+# CONFIG_SCSI_DC395x is not set
+# CONFIG_SCSI_DC390T is not set
+# CONFIG_SCSI_NSP32 is not set
+# CONFIG_SCSI_DEBUG is not set
+# CONFIG_SCSI_PMCRAID is not set
+# CONFIG_SCSI_PM8001 is not set
+# CONFIG_SCSI_SRP is not set
+# CONFIG_SCSI_BFA_FC is not set
+# CONFIG_SCSI_LOWLEVEL_PCMCIA is not set
+# CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
+# CONFIG_ATA is not set
+# CONFIG_MD is not set
+# CONFIG_TARGET_CORE is not set
+# CONFIG_FUSION is not set
+
+#
+# IEEE 1394 (FireWire) support
+#
+# CONFIG_FIREWIRE is not set
+# CONFIG_FIREWIRE_NOSY 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=y
+# CONFIG_VETH is not set
+# CONFIG_ARCNET is not set
+# CONFIG_MII is not set
+# CONFIG_PHYLIB is not set
+# CONFIG_NET_ETHERNET is not set
+CONFIG_NETDEV_1000=y
+# CONFIG_ACENIC is not set
+# CONFIG_DL2K is not set
+# CONFIG_E1000 is not set
+# CONFIG_E1000E is not set
+# CONFIG_IP1000 is not set
+# CONFIG_IGB is not set
+# CONFIG_IGBVF is not set
+# CONFIG_NS83820 is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_R8169 is not set
+# CONFIG_SIS190 is not set
+# CONFIG_SKGE is not set
+# CONFIG_SKY2 is not set
+# CONFIG_VIA_VELOCITY is not set
+# CONFIG_TIGON3 is not set
+# CONFIG_BNX2 is not set
+# CONFIG_CNIC is not set
+# CONFIG_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_STMMAC_ETH is not set
+# CONFIG_PCH_GBE is not set
+# CONFIG_NETDEV_10000 is not set
+# CONFIG_TR is not set
+# CONFIG_WLAN is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
+# CONFIG_WAN is not set
+
+#
+# CAIF transport drivers
+#
+CONFIG_TILE_NET=y
+# 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 is not set
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+# CONFIG_VT is not set
+CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+# CONFIG_NOZOMI is not set
+# CONFIG_N_GSM is not set
+CONFIG_DEVKMEM=y
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+# CONFIG_SERIAL_MFD_HSU is not set
+# CONFIG_SERIAL_JSM is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
+# CONFIG_SERIAL_ALTERA_JTAGUART is not set
+# CONFIG_SERIAL_ALTERA_UART is not set
+# CONFIG_SERIAL_PCH_UART is not set
+# CONFIG_TTY_PRINTK is not set
+CONFIG_HVC_DRIVER=y
+# CONFIG_IPMI_HANDLER is not set
+# CONFIG_HW_RANDOM is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+
+#
+# PCMCIA character devices
+#
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+CONFIG_DEVPORT=y
+# CONFIG_RAMOOPS is not set
+# CONFIG_I2C is not set
+# CONFIG_SPI is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
+
+#
+# PPS generators support
+#
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
+CONFIG_HWMON=y
+# CONFIG_HWMON_VID is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
+
+#
+# Native drivers
+#
+# CONFIG_SENSORS_I5K_AMB is not set
+# CONFIG_SENSORS_F71805F is not set
+# CONFIG_SENSORS_F71882FG is not set
+# CONFIG_SENSORS_IT87 is not set
+# CONFIG_SENSORS_PC87360 is not set
+# CONFIG_SENSORS_PC87427 is not set
+# CONFIG_SENSORS_SIS5595 is not set
+# CONFIG_SENSORS_SMSC47M1 is not set
+# CONFIG_SENSORS_SMSC47B397 is not set
+# CONFIG_SENSORS_SCH5627 is not set
+# CONFIG_SENSORS_VIA686A is not set
+# CONFIG_SENSORS_VT1211 is not set
+# CONFIG_SENSORS_VT8231 is not set
+# CONFIG_SENSORS_W83627HF is not set
+# CONFIG_SENSORS_W83627EHF is not set
+# CONFIG_THERMAL is not set
+CONFIG_WATCHDOG=y
+CONFIG_WATCHDOG_NOWAYOUT=y
+
+#
+# Watchdog Device Drivers
+#
+# CONFIG_SOFT_WATCHDOG is not set
+# CONFIG_ALIM7101_WDT is not set
+
+#
+# PCI-based Watchdog Cards
+#
+# CONFIG_PCIPCWATCHDOG is not set
+# CONFIG_WDTPCI is not set
+CONFIG_SSB_POSSIBLE=y
+
+#
+# Sonics Silicon Backplane
+#
+# CONFIG_SSB is not set
+CONFIG_MFD_SUPPORT=y
+# 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_ABX500_CORE is not set
+# CONFIG_LPC_SCH is not set
+# CONFIG_MFD_RDC321X is not set
+# CONFIG_MFD_JANZ_CMODIO is not set
+# CONFIG_MFD_VX855 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_STUB_POULSBO is not set
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
+# CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+# CONFIG_SOUND is not set
+# CONFIG_HID_SUPPORT is not set
+CONFIG_USB_SUPPORT=y
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB_ARCH_HAS_EHCI=y
+# CONFIG_USB is not set
+# CONFIG_USB_OTG_WHITELIST is not set
+# CONFIG_USB_OTG_BLACKLIST_HUB is not set
+
+#
+# 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
+# CONFIG_NFC_DEVICES is not set
+# CONFIG_ACCESSIBILITY is not set
+# CONFIG_INFINIBAND is not set
+CONFIG_EDAC=y
+
+#
+# Reporting subsystems
+#
+# CONFIG_EDAC_DEBUG is not set
+CONFIG_EDAC_MM_EDAC=y
+CONFIG_EDAC_TILE=y
+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 is not set
+# CONFIG_RTC_INTF_PROC is not set
+CONFIG_RTC_INTF_DEV=y
+# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
+# CONFIG_RTC_DRV_TEST is not set
+
+#
+# SPI RTC drivers
+#
+
+#
+# Platform RTC drivers
+#
+# CONFIG_RTC_DRV_DS1286 is not set
+# CONFIG_RTC_DRV_DS1511 is not set
+# CONFIG_RTC_DRV_DS1553 is not set
+# CONFIG_RTC_DRV_DS1742 is not set
+# CONFIG_RTC_DRV_STK17TA8 is not set
+# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_M48T35 is not set
+# CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_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_TILE=y
+# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
+# CONFIG_UIO is not set
+# CONFIG_STAGING is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
+CONFIG_EXT3_FS=y
+# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
+CONFIG_EXT3_FS_XATTR=y
+# CONFIG_EXT3_FS_POSIX_ACL is not set
+# CONFIG_EXT3_FS_SECURITY is not set
+# CONFIG_EXT4_FS is not set
+CONFIG_JBD=y
+CONFIG_FS_MBCACHE=y
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
+CONFIG_EXPORTFS=y
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
+CONFIG_DNOTIFY=y
+CONFIG_INOTIFY_USER=y
+# CONFIG_FANOTIFY is not set
+# CONFIG_QUOTA is not set
+# CONFIG_QUOTACTL is not set
+# CONFIG_AUTOFS4_FS is not set
+CONFIG_FUSE_FS=y
+# CONFIG_CUSE is not set
+
+#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=y
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=m
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+# CONFIG_PROC_KCORE 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_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_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
+# CONFIG_PSTORE 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_CEPH_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="iso8859-1"
+CONFIG_NLS_CODEPAGE_437=y
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+# CONFIG_NLS_ASCII is not set
+CONFIG_NLS_ISO8859_1=y
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+# CONFIG_NLS_UTF8 is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_DEFAULT_MESSAGE_LOGLEVEL=4
+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_SECTION_MISMATCH is not set
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_SHIRQ is not set
+# CONFIG_LOCKUP_DETECTOR is not set
+# CONFIG_HARDLOCKUP_DETECTOR is not set
+CONFIG_DETECT_HUNG_TASK=y
+# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set
+CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0
+CONFIG_SCHED_DEBUG=y
+# CONFIG_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_SPARSE_RCU_POINTER is not set
+# CONFIG_LOCK_STAT is not set
+CONFIG_DEBUG_SPINLOCK_SLEEP=y
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+CONFIG_STACKTRACE=y
+# CONFIG_DEBUG_KOBJECT is not set
+# CONFIG_DEBUG_HIGHMEM is not set
+CONFIG_DEBUG_INFO=y
+# CONFIG_DEBUG_INFO_REDUCED 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_TEST_LIST_SORT is not set
+# CONFIG_DEBUG_SG is not set
+# CONFIG_DEBUG_NOTIFIERS is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
+# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
+# CONFIG_FAULT_INJECTION is not set
+# CONFIG_SYSCTL_SYSCALL_CHECK is not set
+# CONFIG_DEBUG_PAGEALLOC is not set
+CONFIG_TRACING_SUPPORT=y
+CONFIG_FTRACE=y
+# CONFIG_IRQSOFF_TRACER is not set
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_ENABLE_DEFAULT_TRACERS is not set
+CONFIG_BRANCH_PROFILE_NONE=y
+# CONFIG_PROFILE_ANNOTATED_BRANCHES is not set
+# CONFIG_PROFILE_ALL_BRANCHES is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_ATOMIC64_SELFTEST is not set
+# CONFIG_SAMPLES is not set
+# CONFIG_TEST_KSTRTOX is not set
+CONFIG_EARLY_PRINTK=y
+CONFIG_DEBUG_STACKOVERFLOW=y
+# CONFIG_DEBUG_STACK_USAGE is not set
+CONFIG_DEBUG_EXTRA_FLAGS="-femit-struct-debug-baseonly"
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY_DMESG_RESTRICT is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS 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=m
+CONFIG_CRYPTO_ALGAPI2=m
+CONFIG_CRYPTO_RNG=m
+CONFIG_CRYPTO_RNG2=m
+# CONFIG_CRYPTO_MANAGER is not set
+# CONFIG_CRYPTO_MANAGER2 is not set
+# CONFIG_CRYPTO_GF128MUL is not set
+# CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_PCRYPT 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=m
+# CONFIG_CRYPTO_ANUBIS is not set
+# CONFIG_CRYPTO_ARC4 is not set
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+# CONFIG_CRYPTO_DES is not set
+# CONFIG_CRYPTO_FCRYPT is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_SALSA20 is not set
+# CONFIG_CRYPTO_SEED is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+
+#
+# Compression
+#
+# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_ZLIB is not set
+# CONFIG_CRYPTO_LZO is not set
+
+#
+# Random Number Generation
+#
+CONFIG_CRYPTO_ANSI_CPRNG=m
+# CONFIG_CRYPTO_USER_API_HASH is not set
+# CONFIG_CRYPTO_USER_API_SKCIPHER is not set
+CONFIG_CRYPTO_HW=y
+# CONFIG_CRYPTO_DEV_HIFN_795X is not set
+# CONFIG_BINARY_PRINTF is not set
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+CONFIG_GENERIC_FIND_FIRST_BIT=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_GENERIC_FIND_LAST_BIT=y
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
+# CONFIG_CRC_T10DIF 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_XZ_DEC is not set
+# CONFIG_XZ_DEC_BCJ is not set
+CONFIG_DECOMPRESS_GZIP=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
+CONFIG_CPU_RMAP=y
+CONFIG_NLATTR=y
+# CONFIG_AVERAGE is not set
+CONFIG_HAVE_KVM=y
+# CONFIG_VIRTUALIZATION is not set
diff -druN linux-2.6.39-libre/arch/tile/include/arch/chip_tilegx.h linux-3.0-rc7-libre/arch/tile/include/arch/chip_tilegx.h
--- linux-2.6.39-libre/arch/tile/include/arch/chip_tilegx.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/tile/include/arch/chip_tilegx.h	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,258 @@
+/*
+ * Copyright 2011 Tilera 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, version 2.
+ *
+ *   This program is distributed in the hope that it will be useful, but
+ *   WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
+ *   NON INFRINGEMENT.  See the GNU General Public License for
+ *   more details.
+ */
+
+/*
+ * @file
+ * Global header file.
+ * This header file specifies defines for TILE-Gx.
+ */
+
+#ifndef __ARCH_CHIP_H__
+#define __ARCH_CHIP_H__
+
+/** Specify chip version.
+ * When possible, prefer the CHIP_xxx symbols below for future-proofing.
+ * This is intended for cross-compiling; native compilation should
+ * use the predefined __tile_chip__ symbol.
+ */
+#define TILE_CHIP 10
+
+/** Specify chip revision.
+ * This provides for the case of a respin of a particular chip type;
+ * the normal value for this symbol is "0".
+ * This is intended for cross-compiling; native compilation should
+ * use the predefined __tile_chip_rev__ symbol.
+ */
+#define TILE_CHIP_REV 0
+
+/** The name of this architecture. */
+#define CHIP_ARCH_NAME "tilegx"
+
+/** The ELF e_machine type for binaries for this chip. */
+#define CHIP_ELF_TYPE() EM_TILEGX
+
+/** The alternate ELF e_machine type for binaries for this chip. */
+#define CHIP_COMPAT_ELF_TYPE() 0x2597
+
+/** What is the native word size of the machine? */
+#define CHIP_WORD_SIZE() 64
+
+/** How many bits of a virtual address are used. Extra bits must be
+ * the sign extension of the low bits.
+ */
+#define CHIP_VA_WIDTH() 42
+
+/** How many bits are in a physical address? */
+#define CHIP_PA_WIDTH() 40
+
+/** Size of the L2 cache, in bytes. */
+#define CHIP_L2_CACHE_SIZE() 262144
+
+/** Log size of an L2 cache line in bytes. */
+#define CHIP_L2_LOG_LINE_SIZE() 6
+
+/** Size of an L2 cache line, in bytes. */
+#define CHIP_L2_LINE_SIZE() (1 << CHIP_L2_LOG_LINE_SIZE())
+
+/** Associativity of the L2 cache. */
+#define CHIP_L2_ASSOC() 8
+
+/** Size of the L1 data cache, in bytes. */
+#define CHIP_L1D_CACHE_SIZE() 32768
+
+/** Log size of an L1 data cache line in bytes. */
+#define CHIP_L1D_LOG_LINE_SIZE() 6
+
+/** Size of an L1 data cache line, in bytes. */
+#define CHIP_L1D_LINE_SIZE() (1 << CHIP_L1D_LOG_LINE_SIZE())
+
+/** Associativity of the L1 data cache. */
+#define CHIP_L1D_ASSOC() 2
+
+/** Size of the L1 instruction cache, in bytes. */
+#define CHIP_L1I_CACHE_SIZE() 32768
+
+/** Log size of an L1 instruction cache line in bytes. */
+#define CHIP_L1I_LOG_LINE_SIZE() 6
+
+/** Size of an L1 instruction cache line, in bytes. */
+#define CHIP_L1I_LINE_SIZE() (1 << CHIP_L1I_LOG_LINE_SIZE())
+
+/** Associativity of the L1 instruction cache. */
+#define CHIP_L1I_ASSOC() 2
+
+/** Stride with which flush instructions must be issued. */
+#define CHIP_FLUSH_STRIDE() CHIP_L2_LINE_SIZE()
+
+/** Stride with which inv instructions must be issued. */
+#define CHIP_INV_STRIDE() CHIP_L2_LINE_SIZE()
+
+/** Stride with which finv instructions must be issued. */
+#define CHIP_FINV_STRIDE() CHIP_L2_LINE_SIZE()
+
+/** Can the local cache coherently cache data that is homed elsewhere? */
+#define CHIP_HAS_COHERENT_LOCAL_CACHE() 1
+
+/** How many simultaneous outstanding victims can the L2 cache have? */
+#define CHIP_MAX_OUTSTANDING_VICTIMS() 128
+
+/** Does the TLB support the NC and NOALLOC bits? */
+#define CHIP_HAS_NC_AND_NOALLOC_BITS() 1
+
+/** Does the chip support hash-for-home caching? */
+#define CHIP_HAS_CBOX_HOME_MAP() 1
+
+/** Number of entries in the chip's home map tables. */
+#define CHIP_CBOX_HOME_MAP_SIZE() 128
+
+/** Do uncacheable requests miss in the cache regardless of whether
+ * there is matching data? */
+#define CHIP_HAS_ENFORCED_UNCACHEABLE_REQUESTS() 1
+
+/** Does the mf instruction wait for victims? */
+#define CHIP_HAS_MF_WAITS_FOR_VICTIMS() 0
+
+/** Does the chip have an "inv" instruction that doesn't also flush? */
+#define CHIP_HAS_INV() 1
+
+/** Does the chip have a "wh64" instruction? */
+#define CHIP_HAS_WH64() 1
+
+/** Does this chip have a 'dword_align' instruction? */
+#define CHIP_HAS_DWORD_ALIGN() 0
+
+/** Number of performance counters. */
+#define CHIP_PERFORMANCE_COUNTERS() 4
+
+/** Does this chip have auxiliary performance counters? */
+#define CHIP_HAS_AUX_PERF_COUNTERS() 1
+
+/** Is the CBOX_MSR1 SPR supported? */
+#define CHIP_HAS_CBOX_MSR1() 0
+
+/** Is the TILE_RTF_HWM SPR supported? */
+#define CHIP_HAS_TILE_RTF_HWM() 1
+
+/** Is the TILE_WRITE_PENDING SPR supported? */
+#define CHIP_HAS_TILE_WRITE_PENDING() 0
+
+/** Is the PROC_STATUS SPR supported? */
+#define CHIP_HAS_PROC_STATUS_SPR() 1
+
+/** Is the DSTREAM_PF SPR supported? */
+#define CHIP_HAS_DSTREAM_PF() 1
+
+/** Log of the number of mshims we have. */
+#define CHIP_LOG_NUM_MSHIMS() 2
+
+/** Are the bases of the interrupt vector areas fixed? */
+#define CHIP_HAS_FIXED_INTVEC_BASE() 0
+
+/** Are the interrupt masks split up into 2 SPRs? */
+#define CHIP_HAS_SPLIT_INTR_MASK() 0
+
+/** Is the cycle count split up into 2 SPRs? */
+#define CHIP_HAS_SPLIT_CYCLE() 0
+
+/** Does the chip have a static network? */
+#define CHIP_HAS_SN() 0
+
+/** Does the chip have a static network processor? */
+#define CHIP_HAS_SN_PROC() 0
+
+/** Size of the L1 static network processor instruction cache, in bytes. */
+/* #define CHIP_L1SNI_CACHE_SIZE() -- does not apply to chip 10 */
+
+/** Does the chip have DMA support in each tile? */
+#define CHIP_HAS_TILE_DMA() 0
+
+/** Does the chip have the second revision of the directly accessible
+ *  dynamic networks?  This encapsulates a number of characteristics,
+ *  including the absence of the catch-all, the absence of inline message
+ *  tags, the absence of support for network context-switching, and so on.
+ */
+#define CHIP_HAS_REV1_XDN() 1
+
+/** Does the chip have cmpexch and similar (fetchadd, exch, etc.)? */
+#define CHIP_HAS_CMPEXCH() 1
+
+/** Does the chip have memory-mapped I/O support? */
+#define CHIP_HAS_MMIO() 1
+
+/** Does the chip have post-completion interrupts? */
+#define CHIP_HAS_POST_COMPLETION_INTERRUPTS() 1
+
+/** Does the chip have native single step support? */
+#define CHIP_HAS_SINGLE_STEP() 1
+
+#ifndef __OPEN_SOURCE__  /* features only relevant to hypervisor-level code */
+
+/** How many entries are present in the instruction TLB? */
+#define CHIP_ITLB_ENTRIES() 16
+
+/** How many entries are present in the data TLB? */
+#define CHIP_DTLB_ENTRIES() 32
+
+/** How many MAF entries does the XAUI shim have? */
+#define CHIP_XAUI_MAF_ENTRIES() 32
+
+/** Does the memory shim have a source-id table? */
+#define CHIP_HAS_MSHIM_SRCID_TABLE() 0
+
+/** Does the L1 instruction cache clear on reset? */
+#define CHIP_HAS_L1I_CLEAR_ON_RESET() 1
+
+/** Does the chip come out of reset with valid coordinates on all tiles?
+ * Note that if defined, this also implies that the upper left is 1,1.
+ */
+#define CHIP_HAS_VALID_TILE_COORD_RESET() 1
+
+/** Does the chip have unified packet formats? */
+#define CHIP_HAS_UNIFIED_PACKET_FORMATS() 1
+
+/** Does the chip support write reordering? */
+#define CHIP_HAS_WRITE_REORDERING() 1
+
+/** Does the chip support Y-X routing as well as X-Y? */
+#define CHIP_HAS_Y_X_ROUTING() 1
+
+/** Is INTCTRL_3 managed with the correct MPL? */
+#define CHIP_HAS_INTCTRL_3_STATUS_FIX() 1
+
+/** Is it possible to configure the chip to be big-endian? */
+#define CHIP_HAS_BIG_ENDIAN_CONFIG() 1
+
+/** Is the CACHE_RED_WAY_OVERRIDDEN SPR supported? */
+#define CHIP_HAS_CACHE_RED_WAY_OVERRIDDEN() 0
+
+/** Is the DIAG_TRACE_WAY SPR supported? */
+#define CHIP_HAS_DIAG_TRACE_WAY() 0
+
+/** Is the MEM_STRIPE_CONFIG SPR supported? */
+#define CHIP_HAS_MEM_STRIPE_CONFIG() 1
+
+/** Are the TLB_PERF SPRs supported? */
+#define CHIP_HAS_TLB_PERF() 1
+
+/** Is the VDN_SNOOP_SHIM_CTL SPR supported? */
+#define CHIP_HAS_VDN_SNOOP_SHIM_CTL() 0
+
+/** Does the chip support rev1 DMA packets? */
+#define CHIP_HAS_REV1_DMA_PACKETS() 1
+
+/** Does the chip have an IPI shim? */
+#define CHIP_HAS_IPI() 1
+
+#endif /* !__OPEN_SOURCE__ */
+#endif /* __ARCH_CHIP_H__ */
diff -druN linux-2.6.39-libre/arch/tile/include/arch/icache.h linux-3.0-rc7-libre/arch/tile/include/arch/icache.h
--- linux-2.6.39-libre/arch/tile/include/arch/icache.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/tile/include/arch/icache.h	2011-07-11 19:51:52.000000000 -0400
@@ -16,7 +16,7 @@
 /**
  * @file
  *
- * Support for invalidating bytes in the instruction
+ * Support for invalidating bytes in the instruction cache.
  */
 
 #ifndef __ARCH_ICACHE_H__
@@ -30,11 +30,10 @@
  *
  * @param addr The start of memory to be invalidated.
  * @param size The number of bytes to be invalidated.
- * @param page_size The system's page size, typically the PAGE_SIZE constant
- * in sys/page.h.  This value must be a power of two no larger
- * than the page containing the code to be invalidated. If the value
- * is smaller than the actual page size, this function will still
- * work, but may run slower than necessary.
+ * @param page_size The system's page size, e.g. getpagesize() in userspace.
+ * This value must be a power of two no larger than the page containing
+ * the code to be invalidated. If the value is smaller than the actual page
+ * size, this function will still work, but may run slower than necessary.
  */
 static __inline void
 invalidate_icache(const void* addr, unsigned long size,
diff -druN linux-2.6.39-libre/arch/tile/include/arch/interrupts_64.h linux-3.0-rc7-libre/arch/tile/include/arch/interrupts_64.h
--- linux-2.6.39-libre/arch/tile/include/arch/interrupts_64.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/tile/include/arch/interrupts_64.h	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,276 @@
+/*
+ * Copyright 2011 Tilera 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, version 2.
+ *
+ *   This program is distributed in the hope that it will be useful, but
+ *   WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
+ *   NON INFRINGEMENT.  See the GNU General Public License for
+ *   more details.
+ */
+
+#ifndef __ARCH_INTERRUPTS_H__
+#define __ARCH_INTERRUPTS_H__
+
+/** Mask for an interrupt. */
+#ifdef __ASSEMBLER__
+/* Note: must handle breaking interrupts into high and low words manually. */
+#define INT_MASK(intno) (1 << (intno))
+#else
+#define INT_MASK(intno) (1ULL << (intno))
+#endif
+
+
+/** Where a given interrupt executes */
+#define INTERRUPT_VECTOR(i, pl) (0xFC000000 + ((pl) << 24) + ((i) << 8))
+
+/** Where to store a vector for a given interrupt. */
+#define USER_INTERRUPT_VECTOR(i) INTERRUPT_VECTOR(i, 0)
+
+/** The base address of user-level interrupts. */
+#define USER_INTERRUPT_VECTOR_BASE INTERRUPT_VECTOR(0, 0)
+
+
+/** Additional synthetic interrupt. */
+#define INT_BREAKPOINT (63)
+
+#define INT_MEM_ERROR    0
+#define INT_SINGLE_STEP_3    1
+#define INT_SINGLE_STEP_2    2
+#define INT_SINGLE_STEP_1    3
+#define INT_SINGLE_STEP_0    4
+#define INT_IDN_COMPLETE    5
+#define INT_UDN_COMPLETE    6
+#define INT_ITLB_MISS    7
+#define INT_ILL    8
+#define INT_GPV    9
+#define INT_IDN_ACCESS   10
+#define INT_UDN_ACCESS   11
+#define INT_SWINT_3   12
+#define INT_SWINT_2   13
+#define INT_SWINT_1   14
+#define INT_SWINT_0   15
+#define INT_ILL_TRANS   16
+#define INT_UNALIGN_DATA   17
+#define INT_DTLB_MISS   18
+#define INT_DTLB_ACCESS   19
+#define INT_IDN_FIREWALL   20
+#define INT_UDN_FIREWALL   21
+#define INT_TILE_TIMER   22
+#define INT_AUX_TILE_TIMER   23
+#define INT_IDN_TIMER   24
+#define INT_UDN_TIMER   25
+#define INT_IDN_AVAIL   26
+#define INT_UDN_AVAIL   27
+#define INT_IPI_3   28
+#define INT_IPI_2   29
+#define INT_IPI_1   30
+#define INT_IPI_0   31
+#define INT_PERF_COUNT   32
+#define INT_AUX_PERF_COUNT   33
+#define INT_INTCTRL_3   34
+#define INT_INTCTRL_2   35
+#define INT_INTCTRL_1   36
+#define INT_INTCTRL_0   37
+#define INT_BOOT_ACCESS   38
+#define INT_WORLD_ACCESS   39
+#define INT_I_ASID   40
+#define INT_D_ASID   41
+#define INT_DOUBLE_FAULT   42
+
+#define NUM_INTERRUPTS 43
+
+#ifndef __ASSEMBLER__
+#define QUEUED_INTERRUPTS ( \
+    INT_MASK(INT_MEM_ERROR) | \
+    INT_MASK(INT_IDN_COMPLETE) | \
+    INT_MASK(INT_UDN_COMPLETE) | \
+    INT_MASK(INT_IDN_FIREWALL) | \
+    INT_MASK(INT_UDN_FIREWALL) | \
+    INT_MASK(INT_TILE_TIMER) | \
+    INT_MASK(INT_AUX_TILE_TIMER) | \
+    INT_MASK(INT_IDN_TIMER) | \
+    INT_MASK(INT_UDN_TIMER) | \
+    INT_MASK(INT_IDN_AVAIL) | \
+    INT_MASK(INT_UDN_AVAIL) | \
+    INT_MASK(INT_IPI_3) | \
+    INT_MASK(INT_IPI_2) | \
+    INT_MASK(INT_IPI_1) | \
+    INT_MASK(INT_IPI_0) | \
+    INT_MASK(INT_PERF_COUNT) | \
+    INT_MASK(INT_AUX_PERF_COUNT) | \
+    INT_MASK(INT_INTCTRL_3) | \
+    INT_MASK(INT_INTCTRL_2) | \
+    INT_MASK(INT_INTCTRL_1) | \
+    INT_MASK(INT_INTCTRL_0) | \
+    INT_MASK(INT_BOOT_ACCESS) | \
+    INT_MASK(INT_WORLD_ACCESS) | \
+    INT_MASK(INT_I_ASID) | \
+    INT_MASK(INT_D_ASID) | \
+    INT_MASK(INT_DOUBLE_FAULT) | \
+    0)
+#define NONQUEUED_INTERRUPTS ( \
+    INT_MASK(INT_SINGLE_STEP_3) | \
+    INT_MASK(INT_SINGLE_STEP_2) | \
+    INT_MASK(INT_SINGLE_STEP_1) | \
+    INT_MASK(INT_SINGLE_STEP_0) | \
+    INT_MASK(INT_ITLB_MISS) | \
+    INT_MASK(INT_ILL) | \
+    INT_MASK(INT_GPV) | \
+    INT_MASK(INT_IDN_ACCESS) | \
+    INT_MASK(INT_UDN_ACCESS) | \
+    INT_MASK(INT_SWINT_3) | \
+    INT_MASK(INT_SWINT_2) | \
+    INT_MASK(INT_SWINT_1) | \
+    INT_MASK(INT_SWINT_0) | \
+    INT_MASK(INT_ILL_TRANS) | \
+    INT_MASK(INT_UNALIGN_DATA) | \
+    INT_MASK(INT_DTLB_MISS) | \
+    INT_MASK(INT_DTLB_ACCESS) | \
+    0)
+#define CRITICAL_MASKED_INTERRUPTS ( \
+    INT_MASK(INT_MEM_ERROR) | \
+    INT_MASK(INT_SINGLE_STEP_3) | \
+    INT_MASK(INT_SINGLE_STEP_2) | \
+    INT_MASK(INT_SINGLE_STEP_1) | \
+    INT_MASK(INT_SINGLE_STEP_0) | \
+    INT_MASK(INT_IDN_COMPLETE) | \
+    INT_MASK(INT_UDN_COMPLETE) | \
+    INT_MASK(INT_IDN_FIREWALL) | \
+    INT_MASK(INT_UDN_FIREWALL) | \
+    INT_MASK(INT_TILE_TIMER) | \
+    INT_MASK(INT_AUX_TILE_TIMER) | \
+    INT_MASK(INT_IDN_TIMER) | \
+    INT_MASK(INT_UDN_TIMER) | \
+    INT_MASK(INT_IDN_AVAIL) | \
+    INT_MASK(INT_UDN_AVAIL) | \
+    INT_MASK(INT_IPI_3) | \
+    INT_MASK(INT_IPI_2) | \
+    INT_MASK(INT_IPI_1) | \
+    INT_MASK(INT_IPI_0) | \
+    INT_MASK(INT_PERF_COUNT) | \
+    INT_MASK(INT_AUX_PERF_COUNT) | \
+    INT_MASK(INT_INTCTRL_3) | \
+    INT_MASK(INT_INTCTRL_2) | \
+    INT_MASK(INT_INTCTRL_1) | \
+    INT_MASK(INT_INTCTRL_0) | \
+    0)
+#define CRITICAL_UNMASKED_INTERRUPTS ( \
+    INT_MASK(INT_ITLB_MISS) | \
+    INT_MASK(INT_ILL) | \
+    INT_MASK(INT_GPV) | \
+    INT_MASK(INT_IDN_ACCESS) | \
+    INT_MASK(INT_UDN_ACCESS) | \
+    INT_MASK(INT_SWINT_3) | \
+    INT_MASK(INT_SWINT_2) | \
+    INT_MASK(INT_SWINT_1) | \
+    INT_MASK(INT_SWINT_0) | \
+    INT_MASK(INT_ILL_TRANS) | \
+    INT_MASK(INT_UNALIGN_DATA) | \
+    INT_MASK(INT_DTLB_MISS) | \
+    INT_MASK(INT_DTLB_ACCESS) | \
+    INT_MASK(INT_BOOT_ACCESS) | \
+    INT_MASK(INT_WORLD_ACCESS) | \
+    INT_MASK(INT_I_ASID) | \
+    INT_MASK(INT_D_ASID) | \
+    INT_MASK(INT_DOUBLE_FAULT) | \
+    0)
+#define MASKABLE_INTERRUPTS ( \
+    INT_MASK(INT_MEM_ERROR) | \
+    INT_MASK(INT_SINGLE_STEP_3) | \
+    INT_MASK(INT_SINGLE_STEP_2) | \
+    INT_MASK(INT_SINGLE_STEP_1) | \
+    INT_MASK(INT_SINGLE_STEP_0) | \
+    INT_MASK(INT_IDN_COMPLETE) | \
+    INT_MASK(INT_UDN_COMPLETE) | \
+    INT_MASK(INT_IDN_FIREWALL) | \
+    INT_MASK(INT_UDN_FIREWALL) | \
+    INT_MASK(INT_TILE_TIMER) | \
+    INT_MASK(INT_AUX_TILE_TIMER) | \
+    INT_MASK(INT_IDN_TIMER) | \
+    INT_MASK(INT_UDN_TIMER) | \
+    INT_MASK(INT_IDN_AVAIL) | \
+    INT_MASK(INT_UDN_AVAIL) | \
+    INT_MASK(INT_IPI_3) | \
+    INT_MASK(INT_IPI_2) | \
+    INT_MASK(INT_IPI_1) | \
+    INT_MASK(INT_IPI_0) | \
+    INT_MASK(INT_PERF_COUNT) | \
+    INT_MASK(INT_AUX_PERF_COUNT) | \
+    INT_MASK(INT_INTCTRL_3) | \
+    INT_MASK(INT_INTCTRL_2) | \
+    INT_MASK(INT_INTCTRL_1) | \
+    INT_MASK(INT_INTCTRL_0) | \
+    0)
+#define UNMASKABLE_INTERRUPTS ( \
+    INT_MASK(INT_ITLB_MISS) | \
+    INT_MASK(INT_ILL) | \
+    INT_MASK(INT_GPV) | \
+    INT_MASK(INT_IDN_ACCESS) | \
+    INT_MASK(INT_UDN_ACCESS) | \
+    INT_MASK(INT_SWINT_3) | \
+    INT_MASK(INT_SWINT_2) | \
+    INT_MASK(INT_SWINT_1) | \
+    INT_MASK(INT_SWINT_0) | \
+    INT_MASK(INT_ILL_TRANS) | \
+    INT_MASK(INT_UNALIGN_DATA) | \
+    INT_MASK(INT_DTLB_MISS) | \
+    INT_MASK(INT_DTLB_ACCESS) | \
+    INT_MASK(INT_BOOT_ACCESS) | \
+    INT_MASK(INT_WORLD_ACCESS) | \
+    INT_MASK(INT_I_ASID) | \
+    INT_MASK(INT_D_ASID) | \
+    INT_MASK(INT_DOUBLE_FAULT) | \
+    0)
+#define SYNC_INTERRUPTS ( \
+    INT_MASK(INT_SINGLE_STEP_3) | \
+    INT_MASK(INT_SINGLE_STEP_2) | \
+    INT_MASK(INT_SINGLE_STEP_1) | \
+    INT_MASK(INT_SINGLE_STEP_0) | \
+    INT_MASK(INT_IDN_COMPLETE) | \
+    INT_MASK(INT_UDN_COMPLETE) | \
+    INT_MASK(INT_ITLB_MISS) | \
+    INT_MASK(INT_ILL) | \
+    INT_MASK(INT_GPV) | \
+    INT_MASK(INT_IDN_ACCESS) | \
+    INT_MASK(INT_UDN_ACCESS) | \
+    INT_MASK(INT_SWINT_3) | \
+    INT_MASK(INT_SWINT_2) | \
+    INT_MASK(INT_SWINT_1) | \
+    INT_MASK(INT_SWINT_0) | \
+    INT_MASK(INT_ILL_TRANS) | \
+    INT_MASK(INT_UNALIGN_DATA) | \
+    INT_MASK(INT_DTLB_MISS) | \
+    INT_MASK(INT_DTLB_ACCESS) | \
+    0)
+#define NON_SYNC_INTERRUPTS ( \
+    INT_MASK(INT_MEM_ERROR) | \
+    INT_MASK(INT_IDN_FIREWALL) | \
+    INT_MASK(INT_UDN_FIREWALL) | \
+    INT_MASK(INT_TILE_TIMER) | \
+    INT_MASK(INT_AUX_TILE_TIMER) | \
+    INT_MASK(INT_IDN_TIMER) | \
+    INT_MASK(INT_UDN_TIMER) | \
+    INT_MASK(INT_IDN_AVAIL) | \
+    INT_MASK(INT_UDN_AVAIL) | \
+    INT_MASK(INT_IPI_3) | \
+    INT_MASK(INT_IPI_2) | \
+    INT_MASK(INT_IPI_1) | \
+    INT_MASK(INT_IPI_0) | \
+    INT_MASK(INT_PERF_COUNT) | \
+    INT_MASK(INT_AUX_PERF_COUNT) | \
+    INT_MASK(INT_INTCTRL_3) | \
+    INT_MASK(INT_INTCTRL_2) | \
+    INT_MASK(INT_INTCTRL_1) | \
+    INT_MASK(INT_INTCTRL_0) | \
+    INT_MASK(INT_BOOT_ACCESS) | \
+    INT_MASK(INT_WORLD_ACCESS) | \
+    INT_MASK(INT_I_ASID) | \
+    INT_MASK(INT_D_ASID) | \
+    INT_MASK(INT_DOUBLE_FAULT) | \
+    0)
+#endif /* !__ASSEMBLER__ */
+#endif /* !__ARCH_INTERRUPTS_H__ */
diff -druN linux-2.6.39-libre/arch/tile/include/arch/spr_def_64.h linux-3.0-rc7-libre/arch/tile/include/arch/spr_def_64.h
--- linux-2.6.39-libre/arch/tile/include/arch/spr_def_64.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/tile/include/arch/spr_def_64.h	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,173 @@
+/*
+ * Copyright 2011 Tilera 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, version 2.
+ *
+ *   This program is distributed in the hope that it will be useful, but
+ *   WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
+ *   NON INFRINGEMENT.  See the GNU General Public License for
+ *   more details.
+ */
+
+#ifndef __DOXYGEN__
+
+#ifndef __ARCH_SPR_DEF_H__
+#define __ARCH_SPR_DEF_H__
+
+#define SPR_AUX_PERF_COUNT_0 0x2105
+#define SPR_AUX_PERF_COUNT_1 0x2106
+#define SPR_AUX_PERF_COUNT_CTL 0x2107
+#define SPR_AUX_PERF_COUNT_STS 0x2108
+#define SPR_CMPEXCH_VALUE 0x2780
+#define SPR_CYCLE 0x2781
+#define SPR_DONE 0x2705
+#define SPR_DSTREAM_PF 0x2706
+#define SPR_EVENT_BEGIN 0x2782
+#define SPR_EVENT_END 0x2783
+#define SPR_EX_CONTEXT_0_0 0x2580
+#define SPR_EX_CONTEXT_0_1 0x2581
+#define SPR_EX_CONTEXT_0_1__PL_SHIFT 0
+#define SPR_EX_CONTEXT_0_1__PL_RMASK 0x3
+#define SPR_EX_CONTEXT_0_1__PL_MASK  0x3
+#define SPR_EX_CONTEXT_0_1__ICS_SHIFT 2
+#define SPR_EX_CONTEXT_0_1__ICS_RMASK 0x1
+#define SPR_EX_CONTEXT_0_1__ICS_MASK  0x4
+#define SPR_EX_CONTEXT_1_0 0x2480
+#define SPR_EX_CONTEXT_1_1 0x2481
+#define SPR_EX_CONTEXT_1_1__PL_SHIFT 0
+#define SPR_EX_CONTEXT_1_1__PL_RMASK 0x3
+#define SPR_EX_CONTEXT_1_1__PL_MASK  0x3
+#define SPR_EX_CONTEXT_1_1__ICS_SHIFT 2
+#define SPR_EX_CONTEXT_1_1__ICS_RMASK 0x1
+#define SPR_EX_CONTEXT_1_1__ICS_MASK  0x4
+#define SPR_EX_CONTEXT_2_0 0x2380
+#define SPR_EX_CONTEXT_2_1 0x2381
+#define SPR_EX_CONTEXT_2_1__PL_SHIFT 0
+#define SPR_EX_CONTEXT_2_1__PL_RMASK 0x3
+#define SPR_EX_CONTEXT_2_1__PL_MASK  0x3
+#define SPR_EX_CONTEXT_2_1__ICS_SHIFT 2
+#define SPR_EX_CONTEXT_2_1__ICS_RMASK 0x1
+#define SPR_EX_CONTEXT_2_1__ICS_MASK  0x4
+#define SPR_FAIL 0x2707
+#define SPR_ILL_TRANS_REASON__I_STREAM_VA_RMASK 0x1
+#define SPR_INTCTRL_0_STATUS 0x2505
+#define SPR_INTCTRL_1_STATUS 0x2405
+#define SPR_INTCTRL_2_STATUS 0x2305
+#define SPR_INTERRUPT_CRITICAL_SECTION 0x2708
+#define SPR_INTERRUPT_MASK_0 0x2506
+#define SPR_INTERRUPT_MASK_1 0x2406
+#define SPR_INTERRUPT_MASK_2 0x2306
+#define SPR_INTERRUPT_MASK_RESET_0 0x2507
+#define SPR_INTERRUPT_MASK_RESET_1 0x2407
+#define SPR_INTERRUPT_MASK_RESET_2 0x2307
+#define SPR_INTERRUPT_MASK_SET_0 0x2508
+#define SPR_INTERRUPT_MASK_SET_1 0x2408
+#define SPR_INTERRUPT_MASK_SET_2 0x2308
+#define SPR_INTERRUPT_VECTOR_BASE_0 0x2509
+#define SPR_INTERRUPT_VECTOR_BASE_1 0x2409
+#define SPR_INTERRUPT_VECTOR_BASE_2 0x2309
+#define SPR_INTERRUPT_VECTOR_BASE_3 0x2209
+#define SPR_IPI_EVENT_0 0x1f05
+#define SPR_IPI_EVENT_1 0x1e05
+#define SPR_IPI_EVENT_2 0x1d05
+#define SPR_IPI_EVENT_RESET_0 0x1f06
+#define SPR_IPI_EVENT_RESET_1 0x1e06
+#define SPR_IPI_EVENT_RESET_2 0x1d06
+#define SPR_IPI_EVENT_SET_0 0x1f07
+#define SPR_IPI_EVENT_SET_1 0x1e07
+#define SPR_IPI_EVENT_SET_2 0x1d07
+#define SPR_IPI_MASK_0 0x1f08
+#define SPR_IPI_MASK_1 0x1e08
+#define SPR_IPI_MASK_2 0x1d08
+#define SPR_IPI_MASK_RESET_0 0x1f09
+#define SPR_IPI_MASK_RESET_1 0x1e09
+#define SPR_IPI_MASK_RESET_2 0x1d09
+#define SPR_IPI_MASK_SET_0 0x1f0a
+#define SPR_IPI_MASK_SET_1 0x1e0a
+#define SPR_IPI_MASK_SET_2 0x1d0a
+#define SPR_MPL_AUX_TILE_TIMER_SET_0 0x1700
+#define SPR_MPL_AUX_TILE_TIMER_SET_1 0x1701
+#define SPR_MPL_AUX_TILE_TIMER_SET_2 0x1702
+#define SPR_MPL_INTCTRL_0_SET_0 0x2500
+#define SPR_MPL_INTCTRL_0_SET_1 0x2501
+#define SPR_MPL_INTCTRL_0_SET_2 0x2502
+#define SPR_MPL_INTCTRL_1_SET_0 0x2400
+#define SPR_MPL_INTCTRL_1_SET_1 0x2401
+#define SPR_MPL_INTCTRL_1_SET_2 0x2402
+#define SPR_MPL_INTCTRL_2_SET_0 0x2300
+#define SPR_MPL_INTCTRL_2_SET_1 0x2301
+#define SPR_MPL_INTCTRL_2_SET_2 0x2302
+#define SPR_MPL_UDN_ACCESS_SET_0 0x0b00
+#define SPR_MPL_UDN_ACCESS_SET_1 0x0b01
+#define SPR_MPL_UDN_ACCESS_SET_2 0x0b02
+#define SPR_MPL_UDN_AVAIL_SET_0 0x1b00
+#define SPR_MPL_UDN_AVAIL_SET_1 0x1b01
+#define SPR_MPL_UDN_AVAIL_SET_2 0x1b02
+#define SPR_MPL_UDN_COMPLETE_SET_0 0x0600
+#define SPR_MPL_UDN_COMPLETE_SET_1 0x0601
+#define SPR_MPL_UDN_COMPLETE_SET_2 0x0602
+#define SPR_MPL_UDN_FIREWALL_SET_0 0x1500
+#define SPR_MPL_UDN_FIREWALL_SET_1 0x1501
+#define SPR_MPL_UDN_FIREWALL_SET_2 0x1502
+#define SPR_MPL_UDN_TIMER_SET_0 0x1900
+#define SPR_MPL_UDN_TIMER_SET_1 0x1901
+#define SPR_MPL_UDN_TIMER_SET_2 0x1902
+#define SPR_MPL_WORLD_ACCESS_SET_0 0x2700
+#define SPR_MPL_WORLD_ACCESS_SET_1 0x2701
+#define SPR_MPL_WORLD_ACCESS_SET_2 0x2702
+#define SPR_PASS 0x2709
+#define SPR_PERF_COUNT_0 0x2005
+#define SPR_PERF_COUNT_1 0x2006
+#define SPR_PERF_COUNT_CTL 0x2007
+#define SPR_PERF_COUNT_DN_CTL 0x2008
+#define SPR_PERF_COUNT_STS 0x2009
+#define SPR_PROC_STATUS 0x2784
+#define SPR_SIM_CONTROL 0x2785
+#define SPR_SINGLE_STEP_CONTROL_0 0x0405
+#define SPR_SINGLE_STEP_CONTROL_0__CANCELED_MASK  0x1
+#define SPR_SINGLE_STEP_CONTROL_0__INHIBIT_MASK  0x2
+#define SPR_SINGLE_STEP_CONTROL_1 0x0305
+#define SPR_SINGLE_STEP_CONTROL_1__CANCELED_MASK  0x1
+#define SPR_SINGLE_STEP_CONTROL_1__INHIBIT_MASK  0x2
+#define SPR_SINGLE_STEP_CONTROL_2 0x0205
+#define SPR_SINGLE_STEP_CONTROL_2__CANCELED_MASK  0x1
+#define SPR_SINGLE_STEP_CONTROL_2__INHIBIT_MASK  0x2
+#define SPR_SINGLE_STEP_EN_0_0 0x250a
+#define SPR_SINGLE_STEP_EN_0_1 0x240a
+#define SPR_SINGLE_STEP_EN_0_2 0x230a
+#define SPR_SINGLE_STEP_EN_1_0 0x250b
+#define SPR_SINGLE_STEP_EN_1_1 0x240b
+#define SPR_SINGLE_STEP_EN_1_2 0x230b
+#define SPR_SINGLE_STEP_EN_2_0 0x250c
+#define SPR_SINGLE_STEP_EN_2_1 0x240c
+#define SPR_SINGLE_STEP_EN_2_2 0x230c
+#define SPR_SYSTEM_SAVE_0_0 0x2582
+#define SPR_SYSTEM_SAVE_0_1 0x2583
+#define SPR_SYSTEM_SAVE_0_2 0x2584
+#define SPR_SYSTEM_SAVE_0_3 0x2585
+#define SPR_SYSTEM_SAVE_1_0 0x2482
+#define SPR_SYSTEM_SAVE_1_1 0x2483
+#define SPR_SYSTEM_SAVE_1_2 0x2484
+#define SPR_SYSTEM_SAVE_1_3 0x2485
+#define SPR_SYSTEM_SAVE_2_0 0x2382
+#define SPR_SYSTEM_SAVE_2_1 0x2383
+#define SPR_SYSTEM_SAVE_2_2 0x2384
+#define SPR_SYSTEM_SAVE_2_3 0x2385
+#define SPR_TILE_COORD 0x270b
+#define SPR_TILE_RTF_HWM 0x270c
+#define SPR_TILE_TIMER_CONTROL 0x1605
+#define SPR_UDN_AVAIL_EN 0x1b05
+#define SPR_UDN_DATA_AVAIL 0x0b80
+#define SPR_UDN_DEADLOCK_TIMEOUT 0x1906
+#define SPR_UDN_DEMUX_COUNT_0 0x0b05
+#define SPR_UDN_DEMUX_COUNT_1 0x0b06
+#define SPR_UDN_DEMUX_COUNT_2 0x0b07
+#define SPR_UDN_DEMUX_COUNT_3 0x0b08
+#define SPR_UDN_DIRECTION_PROTECT 0x1505
+
+#endif /* !defined(__ARCH_SPR_DEF_H__) */
+
+#endif /* !defined(__DOXYGEN__) */
diff -druN linux-2.6.39-libre/arch/tile/include/arch/spr_def.h linux-3.0-rc7-libre/arch/tile/include/arch/spr_def.h
--- linux-2.6.39-libre/arch/tile/include/arch/spr_def.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/tile/include/arch/spr_def.h	2011-07-11 19:51:52.000000000 -0400
@@ -12,6 +12,15 @@
  *   more details.
  */
 
+/* Include the proper base SPR definition file. */
+#ifdef __tilegx__
+#include <arch/spr_def_64.h>
+#else
+#include <arch/spr_def_32.h>
+#endif
+
+#ifdef __KERNEL__
+
 /*
  * In addition to including the proper base SPR definition file, depending
  * on machine architecture, this file defines several macros which allow
@@ -29,7 +38,6 @@
 #define _concat4(a, b, c, d)  __concat4(a, b, c, d)
 
 #ifdef __tilegx__
-#include <arch/spr_def_64.h>
 
 /* TILE-Gx dependent, protection-level dependent SPRs. */
 
@@ -65,7 +73,6 @@
 	_concat4(INT_SINGLE_STEP_, CONFIG_KERNEL_PL,,)
 
 #else
-#include <arch/spr_def_32.h>
 
 /* TILEPro dependent, protection-level dependent SPRs. */
 
@@ -102,3 +109,5 @@
 	_concat4(SPR_INTCTRL_, CONFIG_KERNEL_PL, _STATUS,)
 #define INT_INTCTRL_K \
 	_concat4(INT_INTCTRL_, CONFIG_KERNEL_PL,,)
+
+#endif /* __KERNEL__ */
diff -druN linux-2.6.39-libre/arch/tile/include/asm/atomic_32.h linux-3.0-rc7-libre/arch/tile/include/asm/atomic_32.h
--- linux-2.6.39-libre/arch/tile/include/asm/atomic_32.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/tile/include/asm/atomic_32.h	2011-07-11 19:51:52.000000000 -0400
@@ -110,16 +110,6 @@
 	_atomic_xchg(v, n);
 }
 
-#define xchg(ptr, x) ((typeof(*(ptr))) \
-  ((sizeof(*(ptr)) == sizeof(atomic_t)) ? \
-   atomic_xchg((atomic_t *)(ptr), (long)(x)) : \
-   __xchg_called_with_bad_pointer()))
-
-#define cmpxchg(ptr, o, n) ((typeof(*(ptr))) \
-  ((sizeof(*(ptr)) == sizeof(atomic_t)) ? \
-   atomic_cmpxchg((atomic_t *)(ptr), (long)(o), (long)(n)) : \
-   __cmpxchg_called_with_bad_pointer()))
-
 /* A 64bit atomic type */
 
 typedef struct {
diff -druN linux-2.6.39-libre/arch/tile/include/asm/atomic_64.h linux-3.0-rc7-libre/arch/tile/include/asm/atomic_64.h
--- linux-2.6.39-libre/arch/tile/include/asm/atomic_64.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/tile/include/asm/atomic_64.h	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,156 @@
+/*
+ * Copyright 2011 Tilera 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, version 2.
+ *
+ *   This program is distributed in the hope that it will be useful, but
+ *   WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
+ *   NON INFRINGEMENT.  See the GNU General Public License for
+ *   more details.
+ *
+ * Do not include directly; use <asm/atomic.h>.
+ */
+
+#ifndef _ASM_TILE_ATOMIC_64_H
+#define _ASM_TILE_ATOMIC_64_H
+
+#ifndef __ASSEMBLY__
+
+#include <arch/spr_def.h>
+
+/* First, the 32-bit atomic ops that are "real" on our 64-bit platform. */
+
+#define atomic_set(v, i) ((v)->counter = (i))
+
+/*
+ * The smp_mb() operations throughout are to support the fact that
+ * Linux requires memory barriers before and after the operation,
+ * on any routine which updates memory and returns a value.
+ */
+
+static inline int atomic_cmpxchg(atomic_t *v, int o, int n)
+{
+	int val;
+	__insn_mtspr(SPR_CMPEXCH_VALUE, o);
+	smp_mb();  /* barrier for proper semantics */
+	val = __insn_cmpexch4((void *)&v->counter, n);
+	smp_mb();  /* barrier for proper semantics */
+	return val;
+}
+
+static inline int atomic_xchg(atomic_t *v, int n)
+{
+	int val;
+	smp_mb();  /* barrier for proper semantics */
+	val = __insn_exch4((void *)&v->counter, n);
+	smp_mb();  /* barrier for proper semantics */
+	return val;
+}
+
+static inline void atomic_add(int i, atomic_t *v)
+{
+	__insn_fetchadd4((void *)&v->counter, i);
+}
+
+static inline int atomic_add_return(int i, atomic_t *v)
+{
+	int val;
+	smp_mb();  /* barrier for proper semantics */
+	val = __insn_fetchadd4((void *)&v->counter, i) + i;
+	barrier();  /* the "+ i" above will wait on memory */
+	return val;
+}
+
+static inline int atomic_add_unless(atomic_t *v, int a, int u)
+{
+	int guess, oldval = v->counter;
+	do {
+		if (oldval == u)
+			break;
+		guess = oldval;
+		oldval = atomic_cmpxchg(v, guess, guess + a);
+	} while (guess != oldval);
+	return oldval != u;
+}
+
+/* Now the true 64-bit operations. */
+
+#define ATOMIC64_INIT(i)	{ (i) }
+
+#define atomic64_read(v)		((v)->counter)
+#define atomic64_set(v, i) ((v)->counter = (i))
+
+static inline long atomic64_cmpxchg(atomic64_t *v, long o, long n)
+{
+	long val;
+	smp_mb();  /* barrier for proper semantics */
+	__insn_mtspr(SPR_CMPEXCH_VALUE, o);
+	val = __insn_cmpexch((void *)&v->counter, n);
+	smp_mb();  /* barrier for proper semantics */
+	return val;
+}
+
+static inline long atomic64_xchg(atomic64_t *v, long n)
+{
+	long val;
+	smp_mb();  /* barrier for proper semantics */
+	val = __insn_exch((void *)&v->counter, n);
+	smp_mb();  /* barrier for proper semantics */
+	return val;
+}
+
+static inline void atomic64_add(long i, atomic64_t *v)
+{
+	__insn_fetchadd((void *)&v->counter, i);
+}
+
+static inline long atomic64_add_return(long i, atomic64_t *v)
+{
+	int val;
+	smp_mb();  /* barrier for proper semantics */
+	val = __insn_fetchadd((void *)&v->counter, i) + i;
+	barrier();  /* the "+ i" above will wait on memory */
+	return val;
+}
+
+static inline long atomic64_add_unless(atomic64_t *v, long a, long u)
+{
+	long guess, oldval = v->counter;
+	do {
+		if (oldval == u)
+			break;
+		guess = oldval;
+		oldval = atomic64_cmpxchg(v, guess, guess + a);
+	} while (guess != oldval);
+	return oldval != u;
+}
+
+#define atomic64_sub_return(i, v)	atomic64_add_return(-(i), (v))
+#define atomic64_sub(i, v)		atomic64_add(-(i), (v))
+#define atomic64_inc_return(v)		atomic64_add_return(1, (v))
+#define atomic64_dec_return(v)		atomic64_sub_return(1, (v))
+#define atomic64_inc(v)			atomic64_add(1, (v))
+#define atomic64_dec(v)			atomic64_sub(1, (v))
+
+#define atomic64_inc_and_test(v)	(atomic64_inc_return(v) == 0)
+#define atomic64_dec_and_test(v)	(atomic64_dec_return(v) == 0)
+#define atomic64_sub_and_test(i, v)	(atomic64_sub_return((i), (v)) == 0)
+#define atomic64_add_negative(i, v)	(atomic64_add_return((i), (v)) < 0)
+
+#define atomic64_inc_not_zero(v)	atomic64_add_unless((v), 1, 0)
+
+/* Atomic dec and inc don't implement barrier, so provide them if needed. */
+#define smp_mb__before_atomic_dec()	smp_mb()
+#define smp_mb__after_atomic_dec()	smp_mb()
+#define smp_mb__before_atomic_inc()	smp_mb()
+#define smp_mb__after_atomic_inc()	smp_mb()
+
+/* Define this to indicate that cmpxchg is an efficient operation. */
+#define __HAVE_ARCH_CMPXCHG
+
+#endif /* !__ASSEMBLY__ */
+
+#endif /* _ASM_TILE_ATOMIC_64_H */
diff -druN linux-2.6.39-libre/arch/tile/include/asm/atomic.h linux-3.0-rc7-libre/arch/tile/include/asm/atomic.h
--- linux-2.6.39-libre/arch/tile/include/asm/atomic.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/tile/include/asm/atomic.h	2011-07-11 19:51:52.000000000 -0400
@@ -130,17 +130,52 @@
  */
 #define atomic_inc_not_zero(v)		atomic_add_unless((v), 1, 0)
 
-
-/*
- * We define xchg() and cmpxchg() in the included headers.
- * Note that we do not define __HAVE_ARCH_CMPXCHG, since that would imply
- * that cmpxchg() is an efficient operation, which is not particularly true.
- */
-
 /* Nonexistent functions intended to cause link errors. */
 extern unsigned long __xchg_called_with_bad_pointer(void);
 extern unsigned long __cmpxchg_called_with_bad_pointer(void);
 
+#define xchg(ptr, x)							\
+	({								\
+		typeof(*(ptr)) __x;					\
+		switch (sizeof(*(ptr))) {				\
+		case 4:							\
+			__x = (typeof(__x))(typeof(__x-__x))atomic_xchg( \
+				(atomic_t *)(ptr),			\
+				(u32)(typeof((x)-(x)))(x));		\
+			break;						\
+		case 8:							\
+			__x = (typeof(__x))(typeof(__x-__x))atomic64_xchg( \
+				(atomic64_t *)(ptr),			\
+				(u64)(typeof((x)-(x)))(x));		\
+			break;						\
+		default:						\
+			__xchg_called_with_bad_pointer();		\
+		}							\
+		__x;							\
+	})
+
+#define cmpxchg(ptr, o, n)						\
+	({								\
+		typeof(*(ptr)) __x;					\
+		switch (sizeof(*(ptr))) {				\
+		case 4:							\
+			__x = (typeof(__x))(typeof(__x-__x))atomic_cmpxchg( \
+				(atomic_t *)(ptr),			\
+				(u32)(typeof((o)-(o)))(o),		\
+				(u32)(typeof((n)-(n)))(n));		\
+			break;						\
+		case 8:							\
+			__x = (typeof(__x))(typeof(__x-__x))atomic64_cmpxchg( \
+				(atomic64_t *)(ptr),			\
+				(u64)(typeof((o)-(o)))(o),		\
+				(u64)(typeof((n)-(n)))(n));		\
+			break;						\
+		default:						\
+			__cmpxchg_called_with_bad_pointer();		\
+		}							\
+		__x;							\
+	})
+
 #define tas(ptr) (xchg((ptr), 1))
 
 #endif /* __ASSEMBLY__ */
diff -druN linux-2.6.39-libre/arch/tile/include/asm/backtrace.h linux-3.0-rc7-libre/arch/tile/include/asm/backtrace.h
--- linux-2.6.39-libre/arch/tile/include/asm/backtrace.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/tile/include/asm/backtrace.h	2011-07-11 19:51:52.000000000 -0400
@@ -12,80 +12,41 @@
  *   more details.
  */
 
-#ifndef _TILE_BACKTRACE_H
-#define _TILE_BACKTRACE_H
-
-
+#ifndef _ASM_TILE_BACKTRACE_H
+#define _ASM_TILE_BACKTRACE_H
 
 #include <linux/types.h>
 
-#include <arch/chip.h>
-
-#if defined(__tile__)
-typedef unsigned long VirtualAddress;
-#elif CHIP_VA_WIDTH() > 32
-typedef unsigned long long VirtualAddress;
-#else
-typedef unsigned int VirtualAddress;
-#endif
-
-
-/** Reads 'size' bytes from 'address' and writes the data to 'result'.
+/* Reads 'size' bytes from 'address' and writes the data to 'result'.
  * Returns true if successful, else false (e.g. memory not readable).
  */
 typedef bool (*BacktraceMemoryReader)(void *result,
-				      VirtualAddress address,
+				      unsigned long address,
 				      unsigned int size,
 				      void *extra);
 
 typedef struct {
-	/** Current PC. */
-	VirtualAddress pc;
+	/* Current PC. */
+	unsigned long pc;
 
-	/** Current stack pointer value. */
-	VirtualAddress sp;
+	/* Current stack pointer value. */
+	unsigned long sp;
 
-	/** Current frame pointer value (i.e. caller's stack pointer) */
-	VirtualAddress fp;
+	/* Current frame pointer value (i.e. caller's stack pointer) */
+	unsigned long fp;
 
-	/** Internal use only: caller's PC for first frame. */
-	VirtualAddress initial_frame_caller_pc;
+	/* Internal use only: caller's PC for first frame. */
+	unsigned long initial_frame_caller_pc;
 
-	/** Internal use only: callback to read memory. */
+	/* Internal use only: callback to read memory. */
 	BacktraceMemoryReader read_memory_func;
 
-	/** Internal use only: arbitrary argument to read_memory_func. */
+	/* Internal use only: arbitrary argument to read_memory_func. */
 	void *read_memory_func_extra;
 
 } BacktraceIterator;
 
 
-/** Initializes a backtracer to start from the given location.
- *
- * If the frame pointer cannot be determined it is set to -1.
- *
- * @param state The state to be filled in.
- * @param read_memory_func A callback that reads memory. If NULL, a default
- *        value is provided.
- * @param read_memory_func_extra An arbitrary argument to read_memory_func.
- * @param pc The current PC.
- * @param lr The current value of the 'lr' register.
- * @param sp The current value of the 'sp' register.
- * @param r52 The current value of the 'r52' register.
- */
-extern void backtrace_init(BacktraceIterator *state,
-			   BacktraceMemoryReader read_memory_func,
-			   void *read_memory_func_extra,
-			   VirtualAddress pc, VirtualAddress lr,
-			   VirtualAddress sp, VirtualAddress r52);
-
-
-/** Advances the backtracing state to the calling frame, returning
- * true iff successful.
- */
-extern bool backtrace_next(BacktraceIterator *state);
-
-
 typedef enum {
 
 	/* We have no idea what the caller's pc is. */
@@ -138,7 +99,7 @@
 };
 
 
-/** Internal constants used to define 'info' operands. */
+/* Internal constants used to define 'info' operands. */
 enum {
 	/* 0 and 1 are reserved, as are all negative numbers. */
 
@@ -147,13 +108,10 @@
 	CALLER_SP_IN_R52_BASE = 4,
 
 	CALLER_SP_OFFSET_BASE = 8,
-
-	/* Marks the entry point of certain functions. */
-	ENTRY_POINT_INFO_OP = 16
 };
 
 
-/** Current backtracer state describing where it thinks the caller is. */
+/* Current backtracer state describing where it thinks the caller is. */
 typedef struct {
 	/*
 	 * Public fields
@@ -192,7 +150,13 @@
 
 } CallerLocation;
 
+extern void backtrace_init(BacktraceIterator *state,
+                          BacktraceMemoryReader read_memory_func,
+                          void *read_memory_func_extra,
+                          unsigned long pc, unsigned long lr,
+                          unsigned long sp, unsigned long r52);
 
 
+extern bool backtrace_next(BacktraceIterator *state);
 
-#endif /* _TILE_BACKTRACE_H */
+#endif /* _ASM_TILE_BACKTRACE_H */
diff -druN linux-2.6.39-libre/arch/tile/include/asm/bitops_32.h linux-3.0-rc7-libre/arch/tile/include/asm/bitops_32.h
--- linux-2.6.39-libre/arch/tile/include/asm/bitops_32.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/tile/include/asm/bitops_32.h	2011-07-11 19:51:52.000000000 -0400
@@ -126,7 +126,6 @@
 #define smp_mb__before_clear_bit()	smp_mb()
 #define smp_mb__after_clear_bit()	do {} while (0)
 
-#include <asm-generic/bitops/non-atomic.h>
 #include <asm-generic/bitops/ext2-atomic.h>
 
 #endif /* _ASM_TILE_BITOPS_32_H */
diff -druN linux-2.6.39-libre/arch/tile/include/asm/bitops_64.h linux-3.0-rc7-libre/arch/tile/include/asm/bitops_64.h
--- linux-2.6.39-libre/arch/tile/include/asm/bitops_64.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/tile/include/asm/bitops_64.h	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,105 @@
+/*
+ * Copyright 2011 Tilera 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, version 2.
+ *
+ *   This program is distributed in the hope that it will be useful, but
+ *   WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
+ *   NON INFRINGEMENT.  See the GNU General Public License for
+ *   more details.
+ */
+
+#ifndef _ASM_TILE_BITOPS_64_H
+#define _ASM_TILE_BITOPS_64_H
+
+#include <linux/compiler.h>
+#include <asm/atomic.h>
+#include <asm/system.h>
+
+/* See <asm/bitops.h> for API comments. */
+
+static inline void set_bit(unsigned nr, volatile unsigned long *addr)
+{
+	unsigned long mask = (1UL << (nr % BITS_PER_LONG));
+	__insn_fetchor((void *)(addr + nr / BITS_PER_LONG), mask);
+}
+
+static inline void clear_bit(unsigned nr, volatile unsigned long *addr)
+{
+	unsigned long mask = (1UL << (nr % BITS_PER_LONG));
+	__insn_fetchand((void *)(addr + nr / BITS_PER_LONG), ~mask);
+}
+
+#define smp_mb__before_clear_bit()	smp_mb()
+#define smp_mb__after_clear_bit()	smp_mb()
+
+
+static inline void change_bit(unsigned nr, volatile unsigned long *addr)
+{
+	unsigned long old, mask = (1UL << (nr % BITS_PER_LONG));
+	long guess, oldval;
+	addr += nr / BITS_PER_LONG;
+	old = *addr;
+	do {
+		guess = oldval;
+		oldval = atomic64_cmpxchg((atomic64_t *)addr,
+					  guess, guess ^ mask);
+	} while (guess != oldval);
+}
+
+
+/*
+ * The test_and_xxx_bit() routines require a memory fence before we
+ * start the operation, and after the operation completes.  We use
+ * smp_mb() before, and rely on the "!= 0" comparison, plus a compiler
+ * barrier(), to block until the atomic op is complete.
+ */
+
+static inline int test_and_set_bit(unsigned nr, volatile unsigned long *addr)
+{
+	int val;
+	unsigned long mask = (1UL << (nr % BITS_PER_LONG));
+	smp_mb();  /* barrier for proper semantics */
+	val = (__insn_fetchor((void *)(addr + nr / BITS_PER_LONG), mask)
+	       & mask) != 0;
+	barrier();
+	return val;
+}
+
+
+static inline int test_and_clear_bit(unsigned nr, volatile unsigned long *addr)
+{
+	int val;
+	unsigned long mask = (1UL << (nr % BITS_PER_LONG));
+	smp_mb();  /* barrier for proper semantics */
+	val = (__insn_fetchand((void *)(addr + nr / BITS_PER_LONG), ~mask)
+	       & mask) != 0;
+	barrier();
+	return val;
+}
+
+
+static inline int test_and_change_bit(unsigned nr,
+				      volatile unsigned long *addr)
+{
+	unsigned long mask = (1UL << (nr % BITS_PER_LONG));
+	long guess, oldval = *addr;
+	addr += nr / BITS_PER_LONG;
+	oldval = *addr;
+	do {
+		guess = oldval;
+		oldval = atomic64_cmpxchg((atomic64_t *)addr,
+					  guess, guess ^ mask);
+	} while (guess != oldval);
+	return (oldval & mask) != 0;
+}
+
+#define ext2_set_bit_atomic(lock, nr, addr)			\
+	test_and_set_bit((nr), (unsigned long *)(addr))
+#define ext2_clear_bit_atomic(lock, nr, addr)			\
+	test_and_clear_bit((nr), (unsigned long *)(addr))
+
+#endif /* _ASM_TILE_BITOPS_64_H */
diff -druN linux-2.6.39-libre/arch/tile/include/asm/bitops.h linux-3.0-rc7-libre/arch/tile/include/asm/bitops.h
--- linux-2.6.39-libre/arch/tile/include/asm/bitops.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/tile/include/asm/bitops.h	2011-07-11 19:51:52.000000000 -0400
@@ -122,6 +122,7 @@
 #include <asm-generic/bitops/lock.h>
 #include <asm-generic/bitops/find.h>
 #include <asm-generic/bitops/sched.h>
+#include <asm-generic/bitops/non-atomic.h>
 #include <asm-generic/bitops/le.h>
 
 #endif /* _ASM_TILE_BITOPS_H */
diff -druN linux-2.6.39-libre/arch/tile/include/asm/cacheflush.h linux-3.0-rc7-libre/arch/tile/include/asm/cacheflush.h
--- linux-2.6.39-libre/arch/tile/include/asm/cacheflush.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/tile/include/asm/cacheflush.h	2011-07-11 19:51:52.000000000 -0400
@@ -116,22 +116,28 @@
 }
 
 
-/* Invalidate a VA range, then memory fence. */
+/* Invalidate a VA range and wait for it to be complete. */
 static inline void inv_buffer(void *buffer, size_t size)
 {
 	__inv_buffer(buffer, size);
-	mb_incoherent();
+	mb();
 }
 
-/* Flush a VA range, then memory fence. */
-static inline void flush_buffer(void *buffer, size_t size)
+/*
+ * Flush a locally-homecached VA range and wait for the evicted
+ * cachelines to hit memory.
+ */
+static inline void flush_buffer_local(void *buffer, size_t size)
 {
 	__flush_buffer(buffer, size);
 	mb_incoherent();
 }
 
-/* Flush & invalidate a VA range, then memory fence. */
-static inline void finv_buffer(void *buffer, size_t size)
+/*
+ * Flush and invalidate a locally-homecached VA range and wait for the
+ * evicted cachelines to hit memory.
+ */
+static inline void finv_buffer_local(void *buffer, size_t size)
 {
 	__finv_buffer(buffer, size);
 	mb_incoherent();
diff -druN linux-2.6.39-libre/arch/tile/include/asm/compat.h linux-3.0-rc7-libre/arch/tile/include/asm/compat.h
--- linux-2.6.39-libre/arch/tile/include/asm/compat.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/tile/include/asm/compat.h	2011-07-11 19:51:52.000000000 -0400
@@ -215,8 +215,8 @@
 struct compat_siginfo;
 struct compat_sigaltstack;
 long compat_sys_execve(const char __user *path,
-		       const compat_uptr_t __user *argv,
-		       const compat_uptr_t __user *envp, struct pt_regs *);
+		       compat_uptr_t __user *argv,
+		       compat_uptr_t __user *envp, struct pt_regs *);
 long compat_sys_rt_sigaction(int sig, struct compat_sigaction __user *act,
 			     struct compat_sigaction __user *oact,
 			     size_t sigsetsize);
diff -druN linux-2.6.39-libre/arch/tile/include/asm/dma-mapping.h linux-3.0-rc7-libre/arch/tile/include/asm/dma-mapping.h
--- linux-2.6.39-libre/arch/tile/include/asm/dma-mapping.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/tile/include/asm/dma-mapping.h	2011-07-11 19:51:52.000000000 -0400
@@ -65,7 +65,8 @@
 extern void dma_sync_single_range_for_device(struct device *, dma_addr_t,
 					     unsigned long offset, size_t,
 					     enum dma_data_direction);
-extern void dma_cache_sync(void *vaddr, size_t, enum dma_data_direction);
+extern void dma_cache_sync(struct device *dev, void *vaddr, size_t,
+			   enum dma_data_direction);
 
 static inline int
 dma_mapping_error(struct device *dev, dma_addr_t dma_addr)
diff -druN linux-2.6.39-libre/arch/tile/include/asm/fb.h linux-3.0-rc7-libre/arch/tile/include/asm/fb.h
--- linux-2.6.39-libre/arch/tile/include/asm/fb.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/tile/include/asm/fb.h	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1 @@
+#include <asm-generic/fb.h>
diff -druN linux-2.6.39-libre/arch/tile/include/asm/hardwall.h linux-3.0-rc7-libre/arch/tile/include/asm/hardwall.h
--- linux-2.6.39-libre/arch/tile/include/asm/hardwall.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/tile/include/asm/hardwall.h	2011-07-11 19:51:52.000000000 -0400
@@ -40,6 +40,10 @@
 #define HARDWALL_DEACTIVATE \
  _IO(HARDWALL_IOCTL_BASE, _HARDWALL_DEACTIVATE)
 
+#define _HARDWALL_GET_ID 4
+#define HARDWALL_GET_ID \
+ _IO(HARDWALL_IOCTL_BASE, _HARDWALL_GET_ID)
+
 #ifndef __KERNEL__
 
 /* This is the canonical name expected by userspace. */
@@ -47,9 +51,14 @@
 
 #else
 
-/* Hook for /proc/tile/hardwall. */
-struct seq_file;
-int proc_tile_hardwall_show(struct seq_file *sf, void *v);
+/* /proc hooks for hardwall. */
+struct proc_dir_entry;
+#ifdef CONFIG_HARDWALL
+void proc_tile_hardwall_init(struct proc_dir_entry *root);
+int proc_pid_hardwall(struct task_struct *task, char *buffer);
+#else
+static inline void proc_tile_hardwall_init(struct proc_dir_entry *root) {}
+#endif
 
 #endif
 
diff -druN linux-2.6.39-libre/arch/tile/include/asm/io.h linux-3.0-rc7-libre/arch/tile/include/asm/io.h
--- linux-2.6.39-libre/arch/tile/include/asm/io.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/tile/include/asm/io.h	2011-07-11 19:51:52.000000000 -0400
@@ -52,6 +52,7 @@
 #endif
 
 #define ioremap_nocache(physaddr, size)		ioremap(physaddr, size)
+#define ioremap_wc(physaddr, size)		ioremap(physaddr, size)
 #define ioremap_writethrough(physaddr, size)	ioremap(physaddr, size)
 #define ioremap_fullcache(physaddr, size)	ioremap(physaddr, size)
 
@@ -161,6 +162,15 @@
 #define iowrite32 writel
 #define iowrite64 writeq
 
+static inline void memset_io(void *dst, int val, size_t len)
+{
+	int x;
+	BUG_ON((unsigned long)dst & 0x3);
+	val = (val & 0xff) * 0x01010101;
+	for (x = 0; x < len; x += 4)
+		writel(val, dst + x);
+}
+
 static inline void memcpy_fromio(void *dst, const volatile void __iomem *src,
 				 size_t len)
 {
@@ -269,6 +279,11 @@
 	ioport_panic();
 }
 
+#define ioread16be(addr)	be16_to_cpu(ioread16(addr))
+#define ioread32be(addr)	be32_to_cpu(ioread32(addr))
+#define iowrite16be(v, addr)	iowrite16(be16_to_cpu(v), (addr))
+#define iowrite32be(v, addr)	iowrite32(be32_to_cpu(v), (addr))
+
 #define ioread8_rep(p, dst, count) \
 	insb((unsigned long) (p), (dst), (count))
 #define ioread16_rep(p, dst, count) \
@@ -283,4 +298,7 @@
 #define iowrite32_rep(p, src, count) \
 	outsl((unsigned long) (p), (src), (count))
 
+#define virt_to_bus     virt_to_phys
+#define bus_to_virt     phys_to_virt
+
 #endif /* _ASM_TILE_IO_H */
diff -druN linux-2.6.39-libre/arch/tile/include/asm/irq.h linux-3.0-rc7-libre/arch/tile/include/asm/irq.h
--- linux-2.6.39-libre/arch/tile/include/asm/irq.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/tile/include/asm/irq.h	2011-07-11 19:51:52.000000000 -0400
@@ -23,6 +23,8 @@
 /* IRQ numbers used for linux IPIs. */
 #define IRQ_RESCHEDULE 1
 
+#define irq_canonicalize(irq)   (irq)
+
 void ack_bad_irq(unsigned int irq);
 
 /*
diff -druN linux-2.6.39-libre/arch/tile/include/asm/mmu_context.h linux-3.0-rc7-libre/arch/tile/include/asm/mmu_context.h
--- linux-2.6.39-libre/arch/tile/include/asm/mmu_context.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/tile/include/asm/mmu_context.h	2011-07-11 19:51:52.000000000 -0400
@@ -100,8 +100,8 @@
 		__get_cpu_var(current_asid) = asid;
 
 		/* Clear cpu from the old mm, and set it in the new one. */
-		cpumask_clear_cpu(cpu, &prev->cpu_vm_mask);
-		cpumask_set_cpu(cpu, &next->cpu_vm_mask);
+		cpumask_clear_cpu(cpu, mm_cpumask(prev));
+		cpumask_set_cpu(cpu, mm_cpumask(next));
 
 		/* Re-load page tables */
 		install_page_table(next->pgd, asid);
diff -druN linux-2.6.39-libre/arch/tile/include/asm/mmzone.h linux-3.0-rc7-libre/arch/tile/include/asm/mmzone.h
--- linux-2.6.39-libre/arch/tile/include/asm/mmzone.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/tile/include/asm/mmzone.h	2011-07-11 19:51:52.000000000 -0400
@@ -40,17 +40,6 @@
 	return highbits_to_node[__pfn_to_highbits(pfn)];
 }
 
-/*
- * Following are macros that each numa implmentation must define.
- */
-
-#define node_start_pfn(nid)	(NODE_DATA(nid)->node_start_pfn)
-#define node_end_pfn(nid)						\
-({									\
-	pg_data_t *__pgdat = NODE_DATA(nid);				\
-	__pgdat->node_start_pfn + __pgdat->node_spanned_pages;		\
-})
-
 #define kern_addr_valid(kaddr)	virt_addr_valid((void *)kaddr)
 
 static inline int pfn_valid(int pfn)
diff -druN linux-2.6.39-libre/arch/tile/include/asm/opcode_constants_64.h linux-3.0-rc7-libre/arch/tile/include/asm/opcode_constants_64.h
--- linux-2.6.39-libre/arch/tile/include/asm/opcode_constants_64.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/tile/include/asm/opcode_constants_64.h	2011-07-11 19:51:52.000000000 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright 2010 Tilera Corporation. All Rights Reserved.
+ * Copyright 2011 Tilera 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
@@ -19,462 +19,591 @@
 #define _TILE_OPCODE_CONSTANTS_H
 enum
 {
-  ADDBS_U_SPECIAL_0_OPCODE_X0 = 98,
-  ADDBS_U_SPECIAL_0_OPCODE_X1 = 68,
-  ADDB_SPECIAL_0_OPCODE_X0 = 1,
-  ADDB_SPECIAL_0_OPCODE_X1 = 1,
-  ADDHS_SPECIAL_0_OPCODE_X0 = 99,
-  ADDHS_SPECIAL_0_OPCODE_X1 = 69,
-  ADDH_SPECIAL_0_OPCODE_X0 = 2,
-  ADDH_SPECIAL_0_OPCODE_X1 = 2,
-  ADDIB_IMM_0_OPCODE_X0 = 1,
-  ADDIB_IMM_0_OPCODE_X1 = 1,
-  ADDIH_IMM_0_OPCODE_X0 = 2,
-  ADDIH_IMM_0_OPCODE_X1 = 2,
-  ADDI_IMM_0_OPCODE_X0 = 3,
-  ADDI_IMM_0_OPCODE_X1 = 3,
-  ADDI_IMM_1_OPCODE_SN = 1,
-  ADDI_OPCODE_Y0 = 9,
-  ADDI_OPCODE_Y1 = 7,
-  ADDLIS_OPCODE_X0 = 1,
-  ADDLIS_OPCODE_X1 = 2,
-  ADDLI_OPCODE_X0 = 2,
-  ADDLI_OPCODE_X1 = 3,
-  ADDS_SPECIAL_0_OPCODE_X0 = 96,
-  ADDS_SPECIAL_0_OPCODE_X1 = 66,
-  ADD_SPECIAL_0_OPCODE_X0 = 3,
-  ADD_SPECIAL_0_OPCODE_X1 = 3,
-  ADD_SPECIAL_0_OPCODE_Y0 = 0,
-  ADD_SPECIAL_0_OPCODE_Y1 = 0,
-  ADIFFB_U_SPECIAL_0_OPCODE_X0 = 4,
-  ADIFFH_SPECIAL_0_OPCODE_X0 = 5,
-  ANDI_IMM_0_OPCODE_X0 = 1,
-  ANDI_IMM_0_OPCODE_X1 = 4,
-  ANDI_OPCODE_Y0 = 10,
-  ANDI_OPCODE_Y1 = 8,
-  AND_SPECIAL_0_OPCODE_X0 = 6,
-  AND_SPECIAL_0_OPCODE_X1 = 4,
-  AND_SPECIAL_2_OPCODE_Y0 = 0,
-  AND_SPECIAL_2_OPCODE_Y1 = 0,
-  AULI_OPCODE_X0 = 3,
-  AULI_OPCODE_X1 = 4,
-  AVGB_U_SPECIAL_0_OPCODE_X0 = 7,
-  AVGH_SPECIAL_0_OPCODE_X0 = 8,
-  BBNST_BRANCH_OPCODE_X1 = 15,
-  BBNS_BRANCH_OPCODE_X1 = 14,
-  BBNS_OPCODE_SN = 63,
-  BBST_BRANCH_OPCODE_X1 = 13,
-  BBS_BRANCH_OPCODE_X1 = 12,
-  BBS_OPCODE_SN = 62,
-  BGEZT_BRANCH_OPCODE_X1 = 7,
-  BGEZ_BRANCH_OPCODE_X1 = 6,
-  BGEZ_OPCODE_SN = 61,
-  BGZT_BRANCH_OPCODE_X1 = 5,
-  BGZ_BRANCH_OPCODE_X1 = 4,
-  BGZ_OPCODE_SN = 58,
-  BITX_UN_0_SHUN_0_OPCODE_X0 = 1,
-  BITX_UN_0_SHUN_0_OPCODE_Y0 = 1,
-  BLEZT_BRANCH_OPCODE_X1 = 11,
-  BLEZ_BRANCH_OPCODE_X1 = 10,
-  BLEZ_OPCODE_SN = 59,
-  BLZT_BRANCH_OPCODE_X1 = 9,
-  BLZ_BRANCH_OPCODE_X1 = 8,
-  BLZ_OPCODE_SN = 60,
-  BNZT_BRANCH_OPCODE_X1 = 3,
-  BNZ_BRANCH_OPCODE_X1 = 2,
-  BNZ_OPCODE_SN = 57,
-  BPT_NOREG_RR_IMM_0_OPCODE_SN = 1,
-  BRANCH_OPCODE_X1 = 5,
-  BYTEX_UN_0_SHUN_0_OPCODE_X0 = 2,
-  BYTEX_UN_0_SHUN_0_OPCODE_Y0 = 2,
-  BZT_BRANCH_OPCODE_X1 = 1,
-  BZ_BRANCH_OPCODE_X1 = 0,
-  BZ_OPCODE_SN = 56,
-  CLZ_UN_0_SHUN_0_OPCODE_X0 = 3,
-  CLZ_UN_0_SHUN_0_OPCODE_Y0 = 3,
-  CRC32_32_SPECIAL_0_OPCODE_X0 = 9,
-  CRC32_8_SPECIAL_0_OPCODE_X0 = 10,
-  CTZ_UN_0_SHUN_0_OPCODE_X0 = 4,
-  CTZ_UN_0_SHUN_0_OPCODE_Y0 = 4,
-  DRAIN_UN_0_SHUN_0_OPCODE_X1 = 1,
-  DTLBPR_UN_0_SHUN_0_OPCODE_X1 = 2,
-  DWORD_ALIGN_SPECIAL_0_OPCODE_X0 = 95,
-  FINV_UN_0_SHUN_0_OPCODE_X1 = 3,
-  FLUSH_UN_0_SHUN_0_OPCODE_X1 = 4,
-  FNOP_NOREG_RR_IMM_0_OPCODE_SN = 3,
-  FNOP_UN_0_SHUN_0_OPCODE_X0 = 5,
-  FNOP_UN_0_SHUN_0_OPCODE_X1 = 5,
-  FNOP_UN_0_SHUN_0_OPCODE_Y0 = 5,
-  FNOP_UN_0_SHUN_0_OPCODE_Y1 = 1,
-  HALT_NOREG_RR_IMM_0_OPCODE_SN = 0,
-  ICOH_UN_0_SHUN_0_OPCODE_X1 = 6,
-  ILL_UN_0_SHUN_0_OPCODE_X1 = 7,
-  ILL_UN_0_SHUN_0_OPCODE_Y1 = 2,
-  IMM_0_OPCODE_SN = 0,
-  IMM_0_OPCODE_X0 = 4,
-  IMM_0_OPCODE_X1 = 6,
-  IMM_1_OPCODE_SN = 1,
-  IMM_OPCODE_0_X0 = 5,
-  INTHB_SPECIAL_0_OPCODE_X0 = 11,
-  INTHB_SPECIAL_0_OPCODE_X1 = 5,
-  INTHH_SPECIAL_0_OPCODE_X0 = 12,
-  INTHH_SPECIAL_0_OPCODE_X1 = 6,
-  INTLB_SPECIAL_0_OPCODE_X0 = 13,
-  INTLB_SPECIAL_0_OPCODE_X1 = 7,
-  INTLH_SPECIAL_0_OPCODE_X0 = 14,
-  INTLH_SPECIAL_0_OPCODE_X1 = 8,
-  INV_UN_0_SHUN_0_OPCODE_X1 = 8,
-  IRET_UN_0_SHUN_0_OPCODE_X1 = 9,
-  JALB_OPCODE_X1 = 13,
-  JALF_OPCODE_X1 = 12,
-  JALRP_SPECIAL_0_OPCODE_X1 = 9,
-  JALRR_IMM_1_OPCODE_SN = 3,
-  JALR_RR_IMM_0_OPCODE_SN = 5,
-  JALR_SPECIAL_0_OPCODE_X1 = 10,
-  JB_OPCODE_X1 = 11,
-  JF_OPCODE_X1 = 10,
-  JRP_SPECIAL_0_OPCODE_X1 = 11,
-  JRR_IMM_1_OPCODE_SN = 2,
-  JR_RR_IMM_0_OPCODE_SN = 4,
-  JR_SPECIAL_0_OPCODE_X1 = 12,
-  LBADD_IMM_0_OPCODE_X1 = 22,
-  LBADD_U_IMM_0_OPCODE_X1 = 23,
-  LB_OPCODE_Y2 = 0,
-  LB_UN_0_SHUN_0_OPCODE_X1 = 10,
-  LB_U_OPCODE_Y2 = 1,
-  LB_U_UN_0_SHUN_0_OPCODE_X1 = 11,
-  LHADD_IMM_0_OPCODE_X1 = 24,
-  LHADD_U_IMM_0_OPCODE_X1 = 25,
-  LH_OPCODE_Y2 = 2,
-  LH_UN_0_SHUN_0_OPCODE_X1 = 12,
-  LH_U_OPCODE_Y2 = 3,
-  LH_U_UN_0_SHUN_0_OPCODE_X1 = 13,
-  LNK_SPECIAL_0_OPCODE_X1 = 13,
-  LWADD_IMM_0_OPCODE_X1 = 26,
-  LWADD_NA_IMM_0_OPCODE_X1 = 27,
-  LW_NA_UN_0_SHUN_0_OPCODE_X1 = 24,
-  LW_OPCODE_Y2 = 4,
-  LW_UN_0_SHUN_0_OPCODE_X1 = 14,
-  MAXB_U_SPECIAL_0_OPCODE_X0 = 15,
-  MAXB_U_SPECIAL_0_OPCODE_X1 = 14,
-  MAXH_SPECIAL_0_OPCODE_X0 = 16,
-  MAXH_SPECIAL_0_OPCODE_X1 = 15,
-  MAXIB_U_IMM_0_OPCODE_X0 = 4,
-  MAXIB_U_IMM_0_OPCODE_X1 = 5,
-  MAXIH_IMM_0_OPCODE_X0 = 5,
-  MAXIH_IMM_0_OPCODE_X1 = 6,
-  MFSPR_IMM_0_OPCODE_X1 = 7,
-  MF_UN_0_SHUN_0_OPCODE_X1 = 15,
-  MINB_U_SPECIAL_0_OPCODE_X0 = 17,
-  MINB_U_SPECIAL_0_OPCODE_X1 = 16,
-  MINH_SPECIAL_0_OPCODE_X0 = 18,
-  MINH_SPECIAL_0_OPCODE_X1 = 17,
-  MINIB_U_IMM_0_OPCODE_X0 = 6,
-  MINIB_U_IMM_0_OPCODE_X1 = 8,
-  MINIH_IMM_0_OPCODE_X0 = 7,
-  MINIH_IMM_0_OPCODE_X1 = 9,
-  MM_OPCODE_X0 = 6,
-  MM_OPCODE_X1 = 7,
-  MNZB_SPECIAL_0_OPCODE_X0 = 19,
-  MNZB_SPECIAL_0_OPCODE_X1 = 18,
-  MNZH_SPECIAL_0_OPCODE_X0 = 20,
-  MNZH_SPECIAL_0_OPCODE_X1 = 19,
-  MNZ_SPECIAL_0_OPCODE_X0 = 21,
-  MNZ_SPECIAL_0_OPCODE_X1 = 20,
-  MNZ_SPECIAL_1_OPCODE_Y0 = 0,
-  MNZ_SPECIAL_1_OPCODE_Y1 = 1,
-  MOVEI_IMM_1_OPCODE_SN = 0,
-  MOVE_RR_IMM_0_OPCODE_SN = 8,
-  MTSPR_IMM_0_OPCODE_X1 = 10,
-  MULHHA_SS_SPECIAL_0_OPCODE_X0 = 22,
-  MULHHA_SS_SPECIAL_7_OPCODE_Y0 = 0,
-  MULHHA_SU_SPECIAL_0_OPCODE_X0 = 23,
-  MULHHA_UU_SPECIAL_0_OPCODE_X0 = 24,
-  MULHHA_UU_SPECIAL_7_OPCODE_Y0 = 1,
-  MULHHSA_UU_SPECIAL_0_OPCODE_X0 = 25,
-  MULHH_SS_SPECIAL_0_OPCODE_X0 = 26,
-  MULHH_SS_SPECIAL_6_OPCODE_Y0 = 0,
-  MULHH_SU_SPECIAL_0_OPCODE_X0 = 27,
-  MULHH_UU_SPECIAL_0_OPCODE_X0 = 28,
-  MULHH_UU_SPECIAL_6_OPCODE_Y0 = 1,
-  MULHLA_SS_SPECIAL_0_OPCODE_X0 = 29,
-  MULHLA_SU_SPECIAL_0_OPCODE_X0 = 30,
-  MULHLA_US_SPECIAL_0_OPCODE_X0 = 31,
-  MULHLA_UU_SPECIAL_0_OPCODE_X0 = 32,
-  MULHLSA_UU_SPECIAL_0_OPCODE_X0 = 33,
-  MULHLSA_UU_SPECIAL_5_OPCODE_Y0 = 0,
-  MULHL_SS_SPECIAL_0_OPCODE_X0 = 34,
-  MULHL_SU_SPECIAL_0_OPCODE_X0 = 35,
-  MULHL_US_SPECIAL_0_OPCODE_X0 = 36,
-  MULHL_UU_SPECIAL_0_OPCODE_X0 = 37,
-  MULLLA_SS_SPECIAL_0_OPCODE_X0 = 38,
-  MULLLA_SS_SPECIAL_7_OPCODE_Y0 = 2,
-  MULLLA_SU_SPECIAL_0_OPCODE_X0 = 39,
-  MULLLA_UU_SPECIAL_0_OPCODE_X0 = 40,
-  MULLLA_UU_SPECIAL_7_OPCODE_Y0 = 3,
-  MULLLSA_UU_SPECIAL_0_OPCODE_X0 = 41,
-  MULLL_SS_SPECIAL_0_OPCODE_X0 = 42,
-  MULLL_SS_SPECIAL_6_OPCODE_Y0 = 2,
-  MULLL_SU_SPECIAL_0_OPCODE_X0 = 43,
-  MULLL_UU_SPECIAL_0_OPCODE_X0 = 44,
-  MULLL_UU_SPECIAL_6_OPCODE_Y0 = 3,
-  MVNZ_SPECIAL_0_OPCODE_X0 = 45,
-  MVNZ_SPECIAL_1_OPCODE_Y0 = 1,
-  MVZ_SPECIAL_0_OPCODE_X0 = 46,
-  MVZ_SPECIAL_1_OPCODE_Y0 = 2,
-  MZB_SPECIAL_0_OPCODE_X0 = 47,
-  MZB_SPECIAL_0_OPCODE_X1 = 21,
-  MZH_SPECIAL_0_OPCODE_X0 = 48,
-  MZH_SPECIAL_0_OPCODE_X1 = 22,
-  MZ_SPECIAL_0_OPCODE_X0 = 49,
-  MZ_SPECIAL_0_OPCODE_X1 = 23,
-  MZ_SPECIAL_1_OPCODE_Y0 = 3,
-  MZ_SPECIAL_1_OPCODE_Y1 = 2,
-  NAP_UN_0_SHUN_0_OPCODE_X1 = 16,
-  NOP_NOREG_RR_IMM_0_OPCODE_SN = 2,
-  NOP_UN_0_SHUN_0_OPCODE_X0 = 6,
-  NOP_UN_0_SHUN_0_OPCODE_X1 = 17,
-  NOP_UN_0_SHUN_0_OPCODE_Y0 = 6,
-  NOP_UN_0_SHUN_0_OPCODE_Y1 = 3,
-  NOREG_RR_IMM_0_OPCODE_SN = 0,
-  NOR_SPECIAL_0_OPCODE_X0 = 50,
-  NOR_SPECIAL_0_OPCODE_X1 = 24,
-  NOR_SPECIAL_2_OPCODE_Y0 = 1,
-  NOR_SPECIAL_2_OPCODE_Y1 = 1,
-  ORI_IMM_0_OPCODE_X0 = 8,
-  ORI_IMM_0_OPCODE_X1 = 11,
-  ORI_OPCODE_Y0 = 11,
-  ORI_OPCODE_Y1 = 9,
-  OR_SPECIAL_0_OPCODE_X0 = 51,
-  OR_SPECIAL_0_OPCODE_X1 = 25,
-  OR_SPECIAL_2_OPCODE_Y0 = 2,
-  OR_SPECIAL_2_OPCODE_Y1 = 2,
-  PACKBS_U_SPECIAL_0_OPCODE_X0 = 103,
-  PACKBS_U_SPECIAL_0_OPCODE_X1 = 73,
-  PACKHB_SPECIAL_0_OPCODE_X0 = 52,
-  PACKHB_SPECIAL_0_OPCODE_X1 = 26,
-  PACKHS_SPECIAL_0_OPCODE_X0 = 102,
-  PACKHS_SPECIAL_0_OPCODE_X1 = 72,
-  PACKLB_SPECIAL_0_OPCODE_X0 = 53,
-  PACKLB_SPECIAL_0_OPCODE_X1 = 27,
-  PCNT_UN_0_SHUN_0_OPCODE_X0 = 7,
-  PCNT_UN_0_SHUN_0_OPCODE_Y0 = 7,
-  RLI_SHUN_0_OPCODE_X0 = 1,
-  RLI_SHUN_0_OPCODE_X1 = 1,
-  RLI_SHUN_0_OPCODE_Y0 = 1,
-  RLI_SHUN_0_OPCODE_Y1 = 1,
-  RL_SPECIAL_0_OPCODE_X0 = 54,
-  RL_SPECIAL_0_OPCODE_X1 = 28,
-  RL_SPECIAL_3_OPCODE_Y0 = 0,
-  RL_SPECIAL_3_OPCODE_Y1 = 0,
-  RR_IMM_0_OPCODE_SN = 0,
-  S1A_SPECIAL_0_OPCODE_X0 = 55,
-  S1A_SPECIAL_0_OPCODE_X1 = 29,
-  S1A_SPECIAL_0_OPCODE_Y0 = 1,
-  S1A_SPECIAL_0_OPCODE_Y1 = 1,
-  S2A_SPECIAL_0_OPCODE_X0 = 56,
-  S2A_SPECIAL_0_OPCODE_X1 = 30,
-  S2A_SPECIAL_0_OPCODE_Y0 = 2,
-  S2A_SPECIAL_0_OPCODE_Y1 = 2,
-  S3A_SPECIAL_0_OPCODE_X0 = 57,
-  S3A_SPECIAL_0_OPCODE_X1 = 31,
-  S3A_SPECIAL_5_OPCODE_Y0 = 1,
-  S3A_SPECIAL_5_OPCODE_Y1 = 1,
-  SADAB_U_SPECIAL_0_OPCODE_X0 = 58,
-  SADAH_SPECIAL_0_OPCODE_X0 = 59,
-  SADAH_U_SPECIAL_0_OPCODE_X0 = 60,
-  SADB_U_SPECIAL_0_OPCODE_X0 = 61,
-  SADH_SPECIAL_0_OPCODE_X0 = 62,
-  SADH_U_SPECIAL_0_OPCODE_X0 = 63,
-  SBADD_IMM_0_OPCODE_X1 = 28,
-  SB_OPCODE_Y2 = 5,
-  SB_SPECIAL_0_OPCODE_X1 = 32,
-  SEQB_SPECIAL_0_OPCODE_X0 = 64,
-  SEQB_SPECIAL_0_OPCODE_X1 = 33,
-  SEQH_SPECIAL_0_OPCODE_X0 = 65,
-  SEQH_SPECIAL_0_OPCODE_X1 = 34,
-  SEQIB_IMM_0_OPCODE_X0 = 9,
-  SEQIB_IMM_0_OPCODE_X1 = 12,
-  SEQIH_IMM_0_OPCODE_X0 = 10,
-  SEQIH_IMM_0_OPCODE_X1 = 13,
-  SEQI_IMM_0_OPCODE_X0 = 11,
-  SEQI_IMM_0_OPCODE_X1 = 14,
-  SEQI_OPCODE_Y0 = 12,
-  SEQI_OPCODE_Y1 = 10,
-  SEQ_SPECIAL_0_OPCODE_X0 = 66,
-  SEQ_SPECIAL_0_OPCODE_X1 = 35,
-  SEQ_SPECIAL_5_OPCODE_Y0 = 2,
-  SEQ_SPECIAL_5_OPCODE_Y1 = 2,
-  SHADD_IMM_0_OPCODE_X1 = 29,
-  SHL8II_IMM_0_OPCODE_SN = 3,
-  SHLB_SPECIAL_0_OPCODE_X0 = 67,
-  SHLB_SPECIAL_0_OPCODE_X1 = 36,
-  SHLH_SPECIAL_0_OPCODE_X0 = 68,
-  SHLH_SPECIAL_0_OPCODE_X1 = 37,
-  SHLIB_SHUN_0_OPCODE_X0 = 2,
-  SHLIB_SHUN_0_OPCODE_X1 = 2,
-  SHLIH_SHUN_0_OPCODE_X0 = 3,
-  SHLIH_SHUN_0_OPCODE_X1 = 3,
-  SHLI_SHUN_0_OPCODE_X0 = 4,
-  SHLI_SHUN_0_OPCODE_X1 = 4,
-  SHLI_SHUN_0_OPCODE_Y0 = 2,
-  SHLI_SHUN_0_OPCODE_Y1 = 2,
-  SHL_SPECIAL_0_OPCODE_X0 = 69,
-  SHL_SPECIAL_0_OPCODE_X1 = 38,
-  SHL_SPECIAL_3_OPCODE_Y0 = 1,
-  SHL_SPECIAL_3_OPCODE_Y1 = 1,
-  SHR1_RR_IMM_0_OPCODE_SN = 9,
-  SHRB_SPECIAL_0_OPCODE_X0 = 70,
-  SHRB_SPECIAL_0_OPCODE_X1 = 39,
-  SHRH_SPECIAL_0_OPCODE_X0 = 71,
-  SHRH_SPECIAL_0_OPCODE_X1 = 40,
-  SHRIB_SHUN_0_OPCODE_X0 = 5,
-  SHRIB_SHUN_0_OPCODE_X1 = 5,
-  SHRIH_SHUN_0_OPCODE_X0 = 6,
-  SHRIH_SHUN_0_OPCODE_X1 = 6,
-  SHRI_SHUN_0_OPCODE_X0 = 7,
-  SHRI_SHUN_0_OPCODE_X1 = 7,
-  SHRI_SHUN_0_OPCODE_Y0 = 3,
-  SHRI_SHUN_0_OPCODE_Y1 = 3,
-  SHR_SPECIAL_0_OPCODE_X0 = 72,
-  SHR_SPECIAL_0_OPCODE_X1 = 41,
-  SHR_SPECIAL_3_OPCODE_Y0 = 2,
-  SHR_SPECIAL_3_OPCODE_Y1 = 2,
-  SHUN_0_OPCODE_X0 = 7,
-  SHUN_0_OPCODE_X1 = 8,
-  SHUN_0_OPCODE_Y0 = 13,
-  SHUN_0_OPCODE_Y1 = 11,
-  SH_OPCODE_Y2 = 6,
-  SH_SPECIAL_0_OPCODE_X1 = 42,
-  SLTB_SPECIAL_0_OPCODE_X0 = 73,
-  SLTB_SPECIAL_0_OPCODE_X1 = 43,
-  SLTB_U_SPECIAL_0_OPCODE_X0 = 74,
-  SLTB_U_SPECIAL_0_OPCODE_X1 = 44,
-  SLTEB_SPECIAL_0_OPCODE_X0 = 75,
-  SLTEB_SPECIAL_0_OPCODE_X1 = 45,
-  SLTEB_U_SPECIAL_0_OPCODE_X0 = 76,
-  SLTEB_U_SPECIAL_0_OPCODE_X1 = 46,
-  SLTEH_SPECIAL_0_OPCODE_X0 = 77,
-  SLTEH_SPECIAL_0_OPCODE_X1 = 47,
-  SLTEH_U_SPECIAL_0_OPCODE_X0 = 78,
-  SLTEH_U_SPECIAL_0_OPCODE_X1 = 48,
-  SLTE_SPECIAL_0_OPCODE_X0 = 79,
-  SLTE_SPECIAL_0_OPCODE_X1 = 49,
-  SLTE_SPECIAL_4_OPCODE_Y0 = 0,
-  SLTE_SPECIAL_4_OPCODE_Y1 = 0,
-  SLTE_U_SPECIAL_0_OPCODE_X0 = 80,
-  SLTE_U_SPECIAL_0_OPCODE_X1 = 50,
-  SLTE_U_SPECIAL_4_OPCODE_Y0 = 1,
-  SLTE_U_SPECIAL_4_OPCODE_Y1 = 1,
-  SLTH_SPECIAL_0_OPCODE_X0 = 81,
-  SLTH_SPECIAL_0_OPCODE_X1 = 51,
-  SLTH_U_SPECIAL_0_OPCODE_X0 = 82,
-  SLTH_U_SPECIAL_0_OPCODE_X1 = 52,
-  SLTIB_IMM_0_OPCODE_X0 = 12,
-  SLTIB_IMM_0_OPCODE_X1 = 15,
-  SLTIB_U_IMM_0_OPCODE_X0 = 13,
-  SLTIB_U_IMM_0_OPCODE_X1 = 16,
-  SLTIH_IMM_0_OPCODE_X0 = 14,
-  SLTIH_IMM_0_OPCODE_X1 = 17,
-  SLTIH_U_IMM_0_OPCODE_X0 = 15,
-  SLTIH_U_IMM_0_OPCODE_X1 = 18,
-  SLTI_IMM_0_OPCODE_X0 = 16,
-  SLTI_IMM_0_OPCODE_X1 = 19,
-  SLTI_OPCODE_Y0 = 14,
-  SLTI_OPCODE_Y1 = 12,
-  SLTI_U_IMM_0_OPCODE_X0 = 17,
-  SLTI_U_IMM_0_OPCODE_X1 = 20,
-  SLTI_U_OPCODE_Y0 = 15,
-  SLTI_U_OPCODE_Y1 = 13,
-  SLT_SPECIAL_0_OPCODE_X0 = 83,
-  SLT_SPECIAL_0_OPCODE_X1 = 53,
-  SLT_SPECIAL_4_OPCODE_Y0 = 2,
-  SLT_SPECIAL_4_OPCODE_Y1 = 2,
-  SLT_U_SPECIAL_0_OPCODE_X0 = 84,
-  SLT_U_SPECIAL_0_OPCODE_X1 = 54,
-  SLT_U_SPECIAL_4_OPCODE_Y0 = 3,
-  SLT_U_SPECIAL_4_OPCODE_Y1 = 3,
-  SNEB_SPECIAL_0_OPCODE_X0 = 85,
-  SNEB_SPECIAL_0_OPCODE_X1 = 55,
-  SNEH_SPECIAL_0_OPCODE_X0 = 86,
-  SNEH_SPECIAL_0_OPCODE_X1 = 56,
-  SNE_SPECIAL_0_OPCODE_X0 = 87,
-  SNE_SPECIAL_0_OPCODE_X1 = 57,
-  SNE_SPECIAL_5_OPCODE_Y0 = 3,
-  SNE_SPECIAL_5_OPCODE_Y1 = 3,
-  SPECIAL_0_OPCODE_X0 = 0,
-  SPECIAL_0_OPCODE_X1 = 1,
-  SPECIAL_0_OPCODE_Y0 = 1,
-  SPECIAL_0_OPCODE_Y1 = 1,
-  SPECIAL_1_OPCODE_Y0 = 2,
-  SPECIAL_1_OPCODE_Y1 = 2,
-  SPECIAL_2_OPCODE_Y0 = 3,
-  SPECIAL_2_OPCODE_Y1 = 3,
-  SPECIAL_3_OPCODE_Y0 = 4,
-  SPECIAL_3_OPCODE_Y1 = 4,
-  SPECIAL_4_OPCODE_Y0 = 5,
-  SPECIAL_4_OPCODE_Y1 = 5,
-  SPECIAL_5_OPCODE_Y0 = 6,
-  SPECIAL_5_OPCODE_Y1 = 6,
-  SPECIAL_6_OPCODE_Y0 = 7,
-  SPECIAL_7_OPCODE_Y0 = 8,
-  SRAB_SPECIAL_0_OPCODE_X0 = 88,
-  SRAB_SPECIAL_0_OPCODE_X1 = 58,
-  SRAH_SPECIAL_0_OPCODE_X0 = 89,
-  SRAH_SPECIAL_0_OPCODE_X1 = 59,
-  SRAIB_SHUN_0_OPCODE_X0 = 8,
-  SRAIB_SHUN_0_OPCODE_X1 = 8,
-  SRAIH_SHUN_0_OPCODE_X0 = 9,
-  SRAIH_SHUN_0_OPCODE_X1 = 9,
-  SRAI_SHUN_0_OPCODE_X0 = 10,
-  SRAI_SHUN_0_OPCODE_X1 = 10,
-  SRAI_SHUN_0_OPCODE_Y0 = 4,
-  SRAI_SHUN_0_OPCODE_Y1 = 4,
-  SRA_SPECIAL_0_OPCODE_X0 = 90,
-  SRA_SPECIAL_0_OPCODE_X1 = 60,
-  SRA_SPECIAL_3_OPCODE_Y0 = 3,
-  SRA_SPECIAL_3_OPCODE_Y1 = 3,
-  SUBBS_U_SPECIAL_0_OPCODE_X0 = 100,
-  SUBBS_U_SPECIAL_0_OPCODE_X1 = 70,
-  SUBB_SPECIAL_0_OPCODE_X0 = 91,
-  SUBB_SPECIAL_0_OPCODE_X1 = 61,
-  SUBHS_SPECIAL_0_OPCODE_X0 = 101,
-  SUBHS_SPECIAL_0_OPCODE_X1 = 71,
-  SUBH_SPECIAL_0_OPCODE_X0 = 92,
-  SUBH_SPECIAL_0_OPCODE_X1 = 62,
-  SUBS_SPECIAL_0_OPCODE_X0 = 97,
-  SUBS_SPECIAL_0_OPCODE_X1 = 67,
-  SUB_SPECIAL_0_OPCODE_X0 = 93,
-  SUB_SPECIAL_0_OPCODE_X1 = 63,
-  SUB_SPECIAL_0_OPCODE_Y0 = 3,
-  SUB_SPECIAL_0_OPCODE_Y1 = 3,
-  SWADD_IMM_0_OPCODE_X1 = 30,
-  SWINT0_UN_0_SHUN_0_OPCODE_X1 = 18,
-  SWINT1_UN_0_SHUN_0_OPCODE_X1 = 19,
-  SWINT2_UN_0_SHUN_0_OPCODE_X1 = 20,
-  SWINT3_UN_0_SHUN_0_OPCODE_X1 = 21,
-  SW_OPCODE_Y2 = 7,
-  SW_SPECIAL_0_OPCODE_X1 = 64,
-  TBLIDXB0_UN_0_SHUN_0_OPCODE_X0 = 8,
-  TBLIDXB0_UN_0_SHUN_0_OPCODE_Y0 = 8,
-  TBLIDXB1_UN_0_SHUN_0_OPCODE_X0 = 9,
-  TBLIDXB1_UN_0_SHUN_0_OPCODE_Y0 = 9,
-  TBLIDXB2_UN_0_SHUN_0_OPCODE_X0 = 10,
-  TBLIDXB2_UN_0_SHUN_0_OPCODE_Y0 = 10,
-  TBLIDXB3_UN_0_SHUN_0_OPCODE_X0 = 11,
-  TBLIDXB3_UN_0_SHUN_0_OPCODE_Y0 = 11,
-  TNS_UN_0_SHUN_0_OPCODE_X1 = 22,
-  UN_0_SHUN_0_OPCODE_X0 = 11,
-  UN_0_SHUN_0_OPCODE_X1 = 11,
-  UN_0_SHUN_0_OPCODE_Y0 = 5,
-  UN_0_SHUN_0_OPCODE_Y1 = 5,
-  WH64_UN_0_SHUN_0_OPCODE_X1 = 23,
-  XORI_IMM_0_OPCODE_X0 = 2,
-  XORI_IMM_0_OPCODE_X1 = 21,
-  XOR_SPECIAL_0_OPCODE_X0 = 94,
-  XOR_SPECIAL_0_OPCODE_X1 = 65,
-  XOR_SPECIAL_2_OPCODE_Y0 = 3,
-  XOR_SPECIAL_2_OPCODE_Y1 = 3
+  ADDI_IMM8_OPCODE_X0 = 1,
+  ADDI_IMM8_OPCODE_X1 = 1,
+  ADDI_OPCODE_Y0 = 0,
+  ADDI_OPCODE_Y1 = 1,
+  ADDLI_OPCODE_X0 = 1,
+  ADDLI_OPCODE_X1 = 0,
+  ADDXI_IMM8_OPCODE_X0 = 2,
+  ADDXI_IMM8_OPCODE_X1 = 2,
+  ADDXI_OPCODE_Y0 = 1,
+  ADDXI_OPCODE_Y1 = 2,
+  ADDXLI_OPCODE_X0 = 2,
+  ADDXLI_OPCODE_X1 = 1,
+  ADDXSC_RRR_0_OPCODE_X0 = 1,
+  ADDXSC_RRR_0_OPCODE_X1 = 1,
+  ADDX_RRR_0_OPCODE_X0 = 2,
+  ADDX_RRR_0_OPCODE_X1 = 2,
+  ADDX_RRR_0_OPCODE_Y0 = 0,
+  ADDX_SPECIAL_0_OPCODE_Y1 = 0,
+  ADD_RRR_0_OPCODE_X0 = 3,
+  ADD_RRR_0_OPCODE_X1 = 3,
+  ADD_RRR_0_OPCODE_Y0 = 1,
+  ADD_SPECIAL_0_OPCODE_Y1 = 1,
+  ANDI_IMM8_OPCODE_X0 = 3,
+  ANDI_IMM8_OPCODE_X1 = 3,
+  ANDI_OPCODE_Y0 = 2,
+  ANDI_OPCODE_Y1 = 3,
+  AND_RRR_0_OPCODE_X0 = 4,
+  AND_RRR_0_OPCODE_X1 = 4,
+  AND_RRR_5_OPCODE_Y0 = 0,
+  AND_RRR_5_OPCODE_Y1 = 0,
+  BEQZT_BRANCH_OPCODE_X1 = 16,
+  BEQZ_BRANCH_OPCODE_X1 = 17,
+  BFEXTS_BF_OPCODE_X0 = 4,
+  BFEXTU_BF_OPCODE_X0 = 5,
+  BFINS_BF_OPCODE_X0 = 6,
+  BF_OPCODE_X0 = 3,
+  BGEZT_BRANCH_OPCODE_X1 = 18,
+  BGEZ_BRANCH_OPCODE_X1 = 19,
+  BGTZT_BRANCH_OPCODE_X1 = 20,
+  BGTZ_BRANCH_OPCODE_X1 = 21,
+  BLBCT_BRANCH_OPCODE_X1 = 22,
+  BLBC_BRANCH_OPCODE_X1 = 23,
+  BLBST_BRANCH_OPCODE_X1 = 24,
+  BLBS_BRANCH_OPCODE_X1 = 25,
+  BLEZT_BRANCH_OPCODE_X1 = 26,
+  BLEZ_BRANCH_OPCODE_X1 = 27,
+  BLTZT_BRANCH_OPCODE_X1 = 28,
+  BLTZ_BRANCH_OPCODE_X1 = 29,
+  BNEZT_BRANCH_OPCODE_X1 = 30,
+  BNEZ_BRANCH_OPCODE_X1 = 31,
+  BRANCH_OPCODE_X1 = 2,
+  CMOVEQZ_RRR_0_OPCODE_X0 = 5,
+  CMOVEQZ_RRR_4_OPCODE_Y0 = 0,
+  CMOVNEZ_RRR_0_OPCODE_X0 = 6,
+  CMOVNEZ_RRR_4_OPCODE_Y0 = 1,
+  CMPEQI_IMM8_OPCODE_X0 = 4,
+  CMPEQI_IMM8_OPCODE_X1 = 4,
+  CMPEQI_OPCODE_Y0 = 3,
+  CMPEQI_OPCODE_Y1 = 4,
+  CMPEQ_RRR_0_OPCODE_X0 = 7,
+  CMPEQ_RRR_0_OPCODE_X1 = 5,
+  CMPEQ_RRR_3_OPCODE_Y0 = 0,
+  CMPEQ_RRR_3_OPCODE_Y1 = 2,
+  CMPEXCH4_RRR_0_OPCODE_X1 = 6,
+  CMPEXCH_RRR_0_OPCODE_X1 = 7,
+  CMPLES_RRR_0_OPCODE_X0 = 8,
+  CMPLES_RRR_0_OPCODE_X1 = 8,
+  CMPLES_RRR_2_OPCODE_Y0 = 0,
+  CMPLES_RRR_2_OPCODE_Y1 = 0,
+  CMPLEU_RRR_0_OPCODE_X0 = 9,
+  CMPLEU_RRR_0_OPCODE_X1 = 9,
+  CMPLEU_RRR_2_OPCODE_Y0 = 1,
+  CMPLEU_RRR_2_OPCODE_Y1 = 1,
+  CMPLTSI_IMM8_OPCODE_X0 = 5,
+  CMPLTSI_IMM8_OPCODE_X1 = 5,
+  CMPLTSI_OPCODE_Y0 = 4,
+  CMPLTSI_OPCODE_Y1 = 5,
+  CMPLTS_RRR_0_OPCODE_X0 = 10,
+  CMPLTS_RRR_0_OPCODE_X1 = 10,
+  CMPLTS_RRR_2_OPCODE_Y0 = 2,
+  CMPLTS_RRR_2_OPCODE_Y1 = 2,
+  CMPLTUI_IMM8_OPCODE_X0 = 6,
+  CMPLTUI_IMM8_OPCODE_X1 = 6,
+  CMPLTU_RRR_0_OPCODE_X0 = 11,
+  CMPLTU_RRR_0_OPCODE_X1 = 11,
+  CMPLTU_RRR_2_OPCODE_Y0 = 3,
+  CMPLTU_RRR_2_OPCODE_Y1 = 3,
+  CMPNE_RRR_0_OPCODE_X0 = 12,
+  CMPNE_RRR_0_OPCODE_X1 = 12,
+  CMPNE_RRR_3_OPCODE_Y0 = 1,
+  CMPNE_RRR_3_OPCODE_Y1 = 3,
+  CMULAF_RRR_0_OPCODE_X0 = 13,
+  CMULA_RRR_0_OPCODE_X0 = 14,
+  CMULFR_RRR_0_OPCODE_X0 = 15,
+  CMULF_RRR_0_OPCODE_X0 = 16,
+  CMULHR_RRR_0_OPCODE_X0 = 17,
+  CMULH_RRR_0_OPCODE_X0 = 18,
+  CMUL_RRR_0_OPCODE_X0 = 19,
+  CNTLZ_UNARY_OPCODE_X0 = 1,
+  CNTLZ_UNARY_OPCODE_Y0 = 1,
+  CNTTZ_UNARY_OPCODE_X0 = 2,
+  CNTTZ_UNARY_OPCODE_Y0 = 2,
+  CRC32_32_RRR_0_OPCODE_X0 = 20,
+  CRC32_8_RRR_0_OPCODE_X0 = 21,
+  DBLALIGN2_RRR_0_OPCODE_X0 = 22,
+  DBLALIGN2_RRR_0_OPCODE_X1 = 13,
+  DBLALIGN4_RRR_0_OPCODE_X0 = 23,
+  DBLALIGN4_RRR_0_OPCODE_X1 = 14,
+  DBLALIGN6_RRR_0_OPCODE_X0 = 24,
+  DBLALIGN6_RRR_0_OPCODE_X1 = 15,
+  DBLALIGN_RRR_0_OPCODE_X0 = 25,
+  DRAIN_UNARY_OPCODE_X1 = 1,
+  DTLBPR_UNARY_OPCODE_X1 = 2,
+  EXCH4_RRR_0_OPCODE_X1 = 16,
+  EXCH_RRR_0_OPCODE_X1 = 17,
+  FDOUBLE_ADDSUB_RRR_0_OPCODE_X0 = 26,
+  FDOUBLE_ADD_FLAGS_RRR_0_OPCODE_X0 = 27,
+  FDOUBLE_MUL_FLAGS_RRR_0_OPCODE_X0 = 28,
+  FDOUBLE_PACK1_RRR_0_OPCODE_X0 = 29,
+  FDOUBLE_PACK2_RRR_0_OPCODE_X0 = 30,
+  FDOUBLE_SUB_FLAGS_RRR_0_OPCODE_X0 = 31,
+  FDOUBLE_UNPACK_MAX_RRR_0_OPCODE_X0 = 32,
+  FDOUBLE_UNPACK_MIN_RRR_0_OPCODE_X0 = 33,
+  FETCHADD4_RRR_0_OPCODE_X1 = 18,
+  FETCHADDGEZ4_RRR_0_OPCODE_X1 = 19,
+  FETCHADDGEZ_RRR_0_OPCODE_X1 = 20,
+  FETCHADD_RRR_0_OPCODE_X1 = 21,
+  FETCHAND4_RRR_0_OPCODE_X1 = 22,
+  FETCHAND_RRR_0_OPCODE_X1 = 23,
+  FETCHOR4_RRR_0_OPCODE_X1 = 24,
+  FETCHOR_RRR_0_OPCODE_X1 = 25,
+  FINV_UNARY_OPCODE_X1 = 3,
+  FLUSHWB_UNARY_OPCODE_X1 = 4,
+  FLUSH_UNARY_OPCODE_X1 = 5,
+  FNOP_UNARY_OPCODE_X0 = 3,
+  FNOP_UNARY_OPCODE_X1 = 6,
+  FNOP_UNARY_OPCODE_Y0 = 3,
+  FNOP_UNARY_OPCODE_Y1 = 8,
+  FSINGLE_ADD1_RRR_0_OPCODE_X0 = 34,
+  FSINGLE_ADDSUB2_RRR_0_OPCODE_X0 = 35,
+  FSINGLE_MUL1_RRR_0_OPCODE_X0 = 36,
+  FSINGLE_MUL2_RRR_0_OPCODE_X0 = 37,
+  FSINGLE_PACK1_UNARY_OPCODE_X0 = 4,
+  FSINGLE_PACK1_UNARY_OPCODE_Y0 = 4,
+  FSINGLE_PACK2_RRR_0_OPCODE_X0 = 38,
+  FSINGLE_SUB1_RRR_0_OPCODE_X0 = 39,
+  ICOH_UNARY_OPCODE_X1 = 7,
+  ILL_UNARY_OPCODE_X1 = 8,
+  ILL_UNARY_OPCODE_Y1 = 9,
+  IMM8_OPCODE_X0 = 4,
+  IMM8_OPCODE_X1 = 3,
+  INV_UNARY_OPCODE_X1 = 9,
+  IRET_UNARY_OPCODE_X1 = 10,
+  JALRP_UNARY_OPCODE_X1 = 11,
+  JALRP_UNARY_OPCODE_Y1 = 10,
+  JALR_UNARY_OPCODE_X1 = 12,
+  JALR_UNARY_OPCODE_Y1 = 11,
+  JAL_JUMP_OPCODE_X1 = 0,
+  JRP_UNARY_OPCODE_X1 = 13,
+  JRP_UNARY_OPCODE_Y1 = 12,
+  JR_UNARY_OPCODE_X1 = 14,
+  JR_UNARY_OPCODE_Y1 = 13,
+  JUMP_OPCODE_X1 = 4,
+  J_JUMP_OPCODE_X1 = 1,
+  LD1S_ADD_IMM8_OPCODE_X1 = 7,
+  LD1S_OPCODE_Y2 = 0,
+  LD1S_UNARY_OPCODE_X1 = 15,
+  LD1U_ADD_IMM8_OPCODE_X1 = 8,
+  LD1U_OPCODE_Y2 = 1,
+  LD1U_UNARY_OPCODE_X1 = 16,
+  LD2S_ADD_IMM8_OPCODE_X1 = 9,
+  LD2S_OPCODE_Y2 = 2,
+  LD2S_UNARY_OPCODE_X1 = 17,
+  LD2U_ADD_IMM8_OPCODE_X1 = 10,
+  LD2U_OPCODE_Y2 = 3,
+  LD2U_UNARY_OPCODE_X1 = 18,
+  LD4S_ADD_IMM8_OPCODE_X1 = 11,
+  LD4S_OPCODE_Y2 = 1,
+  LD4S_UNARY_OPCODE_X1 = 19,
+  LD4U_ADD_IMM8_OPCODE_X1 = 12,
+  LD4U_OPCODE_Y2 = 2,
+  LD4U_UNARY_OPCODE_X1 = 20,
+  LDNA_UNARY_OPCODE_X1 = 21,
+  LDNT1S_ADD_IMM8_OPCODE_X1 = 13,
+  LDNT1S_UNARY_OPCODE_X1 = 22,
+  LDNT1U_ADD_IMM8_OPCODE_X1 = 14,
+  LDNT1U_UNARY_OPCODE_X1 = 23,
+  LDNT2S_ADD_IMM8_OPCODE_X1 = 15,
+  LDNT2S_UNARY_OPCODE_X1 = 24,
+  LDNT2U_ADD_IMM8_OPCODE_X1 = 16,
+  LDNT2U_UNARY_OPCODE_X1 = 25,
+  LDNT4S_ADD_IMM8_OPCODE_X1 = 17,
+  LDNT4S_UNARY_OPCODE_X1 = 26,
+  LDNT4U_ADD_IMM8_OPCODE_X1 = 18,
+  LDNT4U_UNARY_OPCODE_X1 = 27,
+  LDNT_ADD_IMM8_OPCODE_X1 = 19,
+  LDNT_UNARY_OPCODE_X1 = 28,
+  LD_ADD_IMM8_OPCODE_X1 = 20,
+  LD_OPCODE_Y2 = 3,
+  LD_UNARY_OPCODE_X1 = 29,
+  LNK_UNARY_OPCODE_X1 = 30,
+  LNK_UNARY_OPCODE_Y1 = 14,
+  LWNA_ADD_IMM8_OPCODE_X1 = 21,
+  MFSPR_IMM8_OPCODE_X1 = 22,
+  MF_UNARY_OPCODE_X1 = 31,
+  MM_BF_OPCODE_X0 = 7,
+  MNZ_RRR_0_OPCODE_X0 = 40,
+  MNZ_RRR_0_OPCODE_X1 = 26,
+  MNZ_RRR_4_OPCODE_Y0 = 2,
+  MNZ_RRR_4_OPCODE_Y1 = 2,
+  MODE_OPCODE_YA2 = 1,
+  MODE_OPCODE_YB2 = 2,
+  MODE_OPCODE_YC2 = 3,
+  MTSPR_IMM8_OPCODE_X1 = 23,
+  MULAX_RRR_0_OPCODE_X0 = 41,
+  MULAX_RRR_3_OPCODE_Y0 = 2,
+  MULA_HS_HS_RRR_0_OPCODE_X0 = 42,
+  MULA_HS_HS_RRR_9_OPCODE_Y0 = 0,
+  MULA_HS_HU_RRR_0_OPCODE_X0 = 43,
+  MULA_HS_LS_RRR_0_OPCODE_X0 = 44,
+  MULA_HS_LU_RRR_0_OPCODE_X0 = 45,
+  MULA_HU_HU_RRR_0_OPCODE_X0 = 46,
+  MULA_HU_HU_RRR_9_OPCODE_Y0 = 1,
+  MULA_HU_LS_RRR_0_OPCODE_X0 = 47,
+  MULA_HU_LU_RRR_0_OPCODE_X0 = 48,
+  MULA_LS_LS_RRR_0_OPCODE_X0 = 49,
+  MULA_LS_LS_RRR_9_OPCODE_Y0 = 2,
+  MULA_LS_LU_RRR_0_OPCODE_X0 = 50,
+  MULA_LU_LU_RRR_0_OPCODE_X0 = 51,
+  MULA_LU_LU_RRR_9_OPCODE_Y0 = 3,
+  MULX_RRR_0_OPCODE_X0 = 52,
+  MULX_RRR_3_OPCODE_Y0 = 3,
+  MUL_HS_HS_RRR_0_OPCODE_X0 = 53,
+  MUL_HS_HS_RRR_8_OPCODE_Y0 = 0,
+  MUL_HS_HU_RRR_0_OPCODE_X0 = 54,
+  MUL_HS_LS_RRR_0_OPCODE_X0 = 55,
+  MUL_HS_LU_RRR_0_OPCODE_X0 = 56,
+  MUL_HU_HU_RRR_0_OPCODE_X0 = 57,
+  MUL_HU_HU_RRR_8_OPCODE_Y0 = 1,
+  MUL_HU_LS_RRR_0_OPCODE_X0 = 58,
+  MUL_HU_LU_RRR_0_OPCODE_X0 = 59,
+  MUL_LS_LS_RRR_0_OPCODE_X0 = 60,
+  MUL_LS_LS_RRR_8_OPCODE_Y0 = 2,
+  MUL_LS_LU_RRR_0_OPCODE_X0 = 61,
+  MUL_LU_LU_RRR_0_OPCODE_X0 = 62,
+  MUL_LU_LU_RRR_8_OPCODE_Y0 = 3,
+  MZ_RRR_0_OPCODE_X0 = 63,
+  MZ_RRR_0_OPCODE_X1 = 27,
+  MZ_RRR_4_OPCODE_Y0 = 3,
+  MZ_RRR_4_OPCODE_Y1 = 3,
+  NAP_UNARY_OPCODE_X1 = 32,
+  NOP_UNARY_OPCODE_X0 = 5,
+  NOP_UNARY_OPCODE_X1 = 33,
+  NOP_UNARY_OPCODE_Y0 = 5,
+  NOP_UNARY_OPCODE_Y1 = 15,
+  NOR_RRR_0_OPCODE_X0 = 64,
+  NOR_RRR_0_OPCODE_X1 = 28,
+  NOR_RRR_5_OPCODE_Y0 = 1,
+  NOR_RRR_5_OPCODE_Y1 = 1,
+  ORI_IMM8_OPCODE_X0 = 7,
+  ORI_IMM8_OPCODE_X1 = 24,
+  OR_RRR_0_OPCODE_X0 = 65,
+  OR_RRR_0_OPCODE_X1 = 29,
+  OR_RRR_5_OPCODE_Y0 = 2,
+  OR_RRR_5_OPCODE_Y1 = 2,
+  PCNT_UNARY_OPCODE_X0 = 6,
+  PCNT_UNARY_OPCODE_Y0 = 6,
+  REVBITS_UNARY_OPCODE_X0 = 7,
+  REVBITS_UNARY_OPCODE_Y0 = 7,
+  REVBYTES_UNARY_OPCODE_X0 = 8,
+  REVBYTES_UNARY_OPCODE_Y0 = 8,
+  ROTLI_SHIFT_OPCODE_X0 = 1,
+  ROTLI_SHIFT_OPCODE_X1 = 1,
+  ROTLI_SHIFT_OPCODE_Y0 = 0,
+  ROTLI_SHIFT_OPCODE_Y1 = 0,
+  ROTL_RRR_0_OPCODE_X0 = 66,
+  ROTL_RRR_0_OPCODE_X1 = 30,
+  ROTL_RRR_6_OPCODE_Y0 = 0,
+  ROTL_RRR_6_OPCODE_Y1 = 0,
+  RRR_0_OPCODE_X0 = 5,
+  RRR_0_OPCODE_X1 = 5,
+  RRR_0_OPCODE_Y0 = 5,
+  RRR_0_OPCODE_Y1 = 6,
+  RRR_1_OPCODE_Y0 = 6,
+  RRR_1_OPCODE_Y1 = 7,
+  RRR_2_OPCODE_Y0 = 7,
+  RRR_2_OPCODE_Y1 = 8,
+  RRR_3_OPCODE_Y0 = 8,
+  RRR_3_OPCODE_Y1 = 9,
+  RRR_4_OPCODE_Y0 = 9,
+  RRR_4_OPCODE_Y1 = 10,
+  RRR_5_OPCODE_Y0 = 10,
+  RRR_5_OPCODE_Y1 = 11,
+  RRR_6_OPCODE_Y0 = 11,
+  RRR_6_OPCODE_Y1 = 12,
+  RRR_7_OPCODE_Y0 = 12,
+  RRR_7_OPCODE_Y1 = 13,
+  RRR_8_OPCODE_Y0 = 13,
+  RRR_9_OPCODE_Y0 = 14,
+  SHIFT_OPCODE_X0 = 6,
+  SHIFT_OPCODE_X1 = 6,
+  SHIFT_OPCODE_Y0 = 15,
+  SHIFT_OPCODE_Y1 = 14,
+  SHL16INSLI_OPCODE_X0 = 7,
+  SHL16INSLI_OPCODE_X1 = 7,
+  SHL1ADDX_RRR_0_OPCODE_X0 = 67,
+  SHL1ADDX_RRR_0_OPCODE_X1 = 31,
+  SHL1ADDX_RRR_7_OPCODE_Y0 = 1,
+  SHL1ADDX_RRR_7_OPCODE_Y1 = 1,
+  SHL1ADD_RRR_0_OPCODE_X0 = 68,
+  SHL1ADD_RRR_0_OPCODE_X1 = 32,
+  SHL1ADD_RRR_1_OPCODE_Y0 = 0,
+  SHL1ADD_RRR_1_OPCODE_Y1 = 0,
+  SHL2ADDX_RRR_0_OPCODE_X0 = 69,
+  SHL2ADDX_RRR_0_OPCODE_X1 = 33,
+  SHL2ADDX_RRR_7_OPCODE_Y0 = 2,
+  SHL2ADDX_RRR_7_OPCODE_Y1 = 2,
+  SHL2ADD_RRR_0_OPCODE_X0 = 70,
+  SHL2ADD_RRR_0_OPCODE_X1 = 34,
+  SHL2ADD_RRR_1_OPCODE_Y0 = 1,
+  SHL2ADD_RRR_1_OPCODE_Y1 = 1,
+  SHL3ADDX_RRR_0_OPCODE_X0 = 71,
+  SHL3ADDX_RRR_0_OPCODE_X1 = 35,
+  SHL3ADDX_RRR_7_OPCODE_Y0 = 3,
+  SHL3ADDX_RRR_7_OPCODE_Y1 = 3,
+  SHL3ADD_RRR_0_OPCODE_X0 = 72,
+  SHL3ADD_RRR_0_OPCODE_X1 = 36,
+  SHL3ADD_RRR_1_OPCODE_Y0 = 2,
+  SHL3ADD_RRR_1_OPCODE_Y1 = 2,
+  SHLI_SHIFT_OPCODE_X0 = 2,
+  SHLI_SHIFT_OPCODE_X1 = 2,
+  SHLI_SHIFT_OPCODE_Y0 = 1,
+  SHLI_SHIFT_OPCODE_Y1 = 1,
+  SHLXI_SHIFT_OPCODE_X0 = 3,
+  SHLXI_SHIFT_OPCODE_X1 = 3,
+  SHLX_RRR_0_OPCODE_X0 = 73,
+  SHLX_RRR_0_OPCODE_X1 = 37,
+  SHL_RRR_0_OPCODE_X0 = 74,
+  SHL_RRR_0_OPCODE_X1 = 38,
+  SHL_RRR_6_OPCODE_Y0 = 1,
+  SHL_RRR_6_OPCODE_Y1 = 1,
+  SHRSI_SHIFT_OPCODE_X0 = 4,
+  SHRSI_SHIFT_OPCODE_X1 = 4,
+  SHRSI_SHIFT_OPCODE_Y0 = 2,
+  SHRSI_SHIFT_OPCODE_Y1 = 2,
+  SHRS_RRR_0_OPCODE_X0 = 75,
+  SHRS_RRR_0_OPCODE_X1 = 39,
+  SHRS_RRR_6_OPCODE_Y0 = 2,
+  SHRS_RRR_6_OPCODE_Y1 = 2,
+  SHRUI_SHIFT_OPCODE_X0 = 5,
+  SHRUI_SHIFT_OPCODE_X1 = 5,
+  SHRUI_SHIFT_OPCODE_Y0 = 3,
+  SHRUI_SHIFT_OPCODE_Y1 = 3,
+  SHRUXI_SHIFT_OPCODE_X0 = 6,
+  SHRUXI_SHIFT_OPCODE_X1 = 6,
+  SHRUX_RRR_0_OPCODE_X0 = 76,
+  SHRUX_RRR_0_OPCODE_X1 = 40,
+  SHRU_RRR_0_OPCODE_X0 = 77,
+  SHRU_RRR_0_OPCODE_X1 = 41,
+  SHRU_RRR_6_OPCODE_Y0 = 3,
+  SHRU_RRR_6_OPCODE_Y1 = 3,
+  SHUFFLEBYTES_RRR_0_OPCODE_X0 = 78,
+  ST1_ADD_IMM8_OPCODE_X1 = 25,
+  ST1_OPCODE_Y2 = 0,
+  ST1_RRR_0_OPCODE_X1 = 42,
+  ST2_ADD_IMM8_OPCODE_X1 = 26,
+  ST2_OPCODE_Y2 = 1,
+  ST2_RRR_0_OPCODE_X1 = 43,
+  ST4_ADD_IMM8_OPCODE_X1 = 27,
+  ST4_OPCODE_Y2 = 2,
+  ST4_RRR_0_OPCODE_X1 = 44,
+  STNT1_ADD_IMM8_OPCODE_X1 = 28,
+  STNT1_RRR_0_OPCODE_X1 = 45,
+  STNT2_ADD_IMM8_OPCODE_X1 = 29,
+  STNT2_RRR_0_OPCODE_X1 = 46,
+  STNT4_ADD_IMM8_OPCODE_X1 = 30,
+  STNT4_RRR_0_OPCODE_X1 = 47,
+  STNT_ADD_IMM8_OPCODE_X1 = 31,
+  STNT_RRR_0_OPCODE_X1 = 48,
+  ST_ADD_IMM8_OPCODE_X1 = 32,
+  ST_OPCODE_Y2 = 3,
+  ST_RRR_0_OPCODE_X1 = 49,
+  SUBXSC_RRR_0_OPCODE_X0 = 79,
+  SUBXSC_RRR_0_OPCODE_X1 = 50,
+  SUBX_RRR_0_OPCODE_X0 = 80,
+  SUBX_RRR_0_OPCODE_X1 = 51,
+  SUBX_RRR_0_OPCODE_Y0 = 2,
+  SUBX_RRR_0_OPCODE_Y1 = 2,
+  SUB_RRR_0_OPCODE_X0 = 81,
+  SUB_RRR_0_OPCODE_X1 = 52,
+  SUB_RRR_0_OPCODE_Y0 = 3,
+  SUB_RRR_0_OPCODE_Y1 = 3,
+  SWINT0_UNARY_OPCODE_X1 = 34,
+  SWINT1_UNARY_OPCODE_X1 = 35,
+  SWINT2_UNARY_OPCODE_X1 = 36,
+  SWINT3_UNARY_OPCODE_X1 = 37,
+  TBLIDXB0_UNARY_OPCODE_X0 = 9,
+  TBLIDXB0_UNARY_OPCODE_Y0 = 9,
+  TBLIDXB1_UNARY_OPCODE_X0 = 10,
+  TBLIDXB1_UNARY_OPCODE_Y0 = 10,
+  TBLIDXB2_UNARY_OPCODE_X0 = 11,
+  TBLIDXB2_UNARY_OPCODE_Y0 = 11,
+  TBLIDXB3_UNARY_OPCODE_X0 = 12,
+  TBLIDXB3_UNARY_OPCODE_Y0 = 12,
+  UNARY_RRR_0_OPCODE_X0 = 82,
+  UNARY_RRR_0_OPCODE_X1 = 53,
+  UNARY_RRR_1_OPCODE_Y0 = 3,
+  UNARY_RRR_1_OPCODE_Y1 = 3,
+  V1ADDI_IMM8_OPCODE_X0 = 8,
+  V1ADDI_IMM8_OPCODE_X1 = 33,
+  V1ADDUC_RRR_0_OPCODE_X0 = 83,
+  V1ADDUC_RRR_0_OPCODE_X1 = 54,
+  V1ADD_RRR_0_OPCODE_X0 = 84,
+  V1ADD_RRR_0_OPCODE_X1 = 55,
+  V1ADIFFU_RRR_0_OPCODE_X0 = 85,
+  V1AVGU_RRR_0_OPCODE_X0 = 86,
+  V1CMPEQI_IMM8_OPCODE_X0 = 9,
+  V1CMPEQI_IMM8_OPCODE_X1 = 34,
+  V1CMPEQ_RRR_0_OPCODE_X0 = 87,
+  V1CMPEQ_RRR_0_OPCODE_X1 = 56,
+  V1CMPLES_RRR_0_OPCODE_X0 = 88,
+  V1CMPLES_RRR_0_OPCODE_X1 = 57,
+  V1CMPLEU_RRR_0_OPCODE_X0 = 89,
+  V1CMPLEU_RRR_0_OPCODE_X1 = 58,
+  V1CMPLTSI_IMM8_OPCODE_X0 = 10,
+  V1CMPLTSI_IMM8_OPCODE_X1 = 35,
+  V1CMPLTS_RRR_0_OPCODE_X0 = 90,
+  V1CMPLTS_RRR_0_OPCODE_X1 = 59,
+  V1CMPLTUI_IMM8_OPCODE_X0 = 11,
+  V1CMPLTUI_IMM8_OPCODE_X1 = 36,
+  V1CMPLTU_RRR_0_OPCODE_X0 = 91,
+  V1CMPLTU_RRR_0_OPCODE_X1 = 60,
+  V1CMPNE_RRR_0_OPCODE_X0 = 92,
+  V1CMPNE_RRR_0_OPCODE_X1 = 61,
+  V1DDOTPUA_RRR_0_OPCODE_X0 = 161,
+  V1DDOTPUSA_RRR_0_OPCODE_X0 = 93,
+  V1DDOTPUS_RRR_0_OPCODE_X0 = 94,
+  V1DDOTPU_RRR_0_OPCODE_X0 = 162,
+  V1DOTPA_RRR_0_OPCODE_X0 = 95,
+  V1DOTPUA_RRR_0_OPCODE_X0 = 163,
+  V1DOTPUSA_RRR_0_OPCODE_X0 = 96,
+  V1DOTPUS_RRR_0_OPCODE_X0 = 97,
+  V1DOTPU_RRR_0_OPCODE_X0 = 164,
+  V1DOTP_RRR_0_OPCODE_X0 = 98,
+  V1INT_H_RRR_0_OPCODE_X0 = 99,
+  V1INT_H_RRR_0_OPCODE_X1 = 62,
+  V1INT_L_RRR_0_OPCODE_X0 = 100,
+  V1INT_L_RRR_0_OPCODE_X1 = 63,
+  V1MAXUI_IMM8_OPCODE_X0 = 12,
+  V1MAXUI_IMM8_OPCODE_X1 = 37,
+  V1MAXU_RRR_0_OPCODE_X0 = 101,
+  V1MAXU_RRR_0_OPCODE_X1 = 64,
+  V1MINUI_IMM8_OPCODE_X0 = 13,
+  V1MINUI_IMM8_OPCODE_X1 = 38,
+  V1MINU_RRR_0_OPCODE_X0 = 102,
+  V1MINU_RRR_0_OPCODE_X1 = 65,
+  V1MNZ_RRR_0_OPCODE_X0 = 103,
+  V1MNZ_RRR_0_OPCODE_X1 = 66,
+  V1MULTU_RRR_0_OPCODE_X0 = 104,
+  V1MULUS_RRR_0_OPCODE_X0 = 105,
+  V1MULU_RRR_0_OPCODE_X0 = 106,
+  V1MZ_RRR_0_OPCODE_X0 = 107,
+  V1MZ_RRR_0_OPCODE_X1 = 67,
+  V1SADAU_RRR_0_OPCODE_X0 = 108,
+  V1SADU_RRR_0_OPCODE_X0 = 109,
+  V1SHLI_SHIFT_OPCODE_X0 = 7,
+  V1SHLI_SHIFT_OPCODE_X1 = 7,
+  V1SHL_RRR_0_OPCODE_X0 = 110,
+  V1SHL_RRR_0_OPCODE_X1 = 68,
+  V1SHRSI_SHIFT_OPCODE_X0 = 8,
+  V1SHRSI_SHIFT_OPCODE_X1 = 8,
+  V1SHRS_RRR_0_OPCODE_X0 = 111,
+  V1SHRS_RRR_0_OPCODE_X1 = 69,
+  V1SHRUI_SHIFT_OPCODE_X0 = 9,
+  V1SHRUI_SHIFT_OPCODE_X1 = 9,
+  V1SHRU_RRR_0_OPCODE_X0 = 112,
+  V1SHRU_RRR_0_OPCODE_X1 = 70,
+  V1SUBUC_RRR_0_OPCODE_X0 = 113,
+  V1SUBUC_RRR_0_OPCODE_X1 = 71,
+  V1SUB_RRR_0_OPCODE_X0 = 114,
+  V1SUB_RRR_0_OPCODE_X1 = 72,
+  V2ADDI_IMM8_OPCODE_X0 = 14,
+  V2ADDI_IMM8_OPCODE_X1 = 39,
+  V2ADDSC_RRR_0_OPCODE_X0 = 115,
+  V2ADDSC_RRR_0_OPCODE_X1 = 73,
+  V2ADD_RRR_0_OPCODE_X0 = 116,
+  V2ADD_RRR_0_OPCODE_X1 = 74,
+  V2ADIFFS_RRR_0_OPCODE_X0 = 117,
+  V2AVGS_RRR_0_OPCODE_X0 = 118,
+  V2CMPEQI_IMM8_OPCODE_X0 = 15,
+  V2CMPEQI_IMM8_OPCODE_X1 = 40,
+  V2CMPEQ_RRR_0_OPCODE_X0 = 119,
+  V2CMPEQ_RRR_0_OPCODE_X1 = 75,
+  V2CMPLES_RRR_0_OPCODE_X0 = 120,
+  V2CMPLES_RRR_0_OPCODE_X1 = 76,
+  V2CMPLEU_RRR_0_OPCODE_X0 = 121,
+  V2CMPLEU_RRR_0_OPCODE_X1 = 77,
+  V2CMPLTSI_IMM8_OPCODE_X0 = 16,
+  V2CMPLTSI_IMM8_OPCODE_X1 = 41,
+  V2CMPLTS_RRR_0_OPCODE_X0 = 122,
+  V2CMPLTS_RRR_0_OPCODE_X1 = 78,
+  V2CMPLTUI_IMM8_OPCODE_X0 = 17,
+  V2CMPLTUI_IMM8_OPCODE_X1 = 42,
+  V2CMPLTU_RRR_0_OPCODE_X0 = 123,
+  V2CMPLTU_RRR_0_OPCODE_X1 = 79,
+  V2CMPNE_RRR_0_OPCODE_X0 = 124,
+  V2CMPNE_RRR_0_OPCODE_X1 = 80,
+  V2DOTPA_RRR_0_OPCODE_X0 = 125,
+  V2DOTP_RRR_0_OPCODE_X0 = 126,
+  V2INT_H_RRR_0_OPCODE_X0 = 127,
+  V2INT_H_RRR_0_OPCODE_X1 = 81,
+  V2INT_L_RRR_0_OPCODE_X0 = 128,
+  V2INT_L_RRR_0_OPCODE_X1 = 82,
+  V2MAXSI_IMM8_OPCODE_X0 = 18,
+  V2MAXSI_IMM8_OPCODE_X1 = 43,
+  V2MAXS_RRR_0_OPCODE_X0 = 129,
+  V2MAXS_RRR_0_OPCODE_X1 = 83,
+  V2MINSI_IMM8_OPCODE_X0 = 19,
+  V2MINSI_IMM8_OPCODE_X1 = 44,
+  V2MINS_RRR_0_OPCODE_X0 = 130,
+  V2MINS_RRR_0_OPCODE_X1 = 84,
+  V2MNZ_RRR_0_OPCODE_X0 = 131,
+  V2MNZ_RRR_0_OPCODE_X1 = 85,
+  V2MULFSC_RRR_0_OPCODE_X0 = 132,
+  V2MULS_RRR_0_OPCODE_X0 = 133,
+  V2MULTS_RRR_0_OPCODE_X0 = 134,
+  V2MZ_RRR_0_OPCODE_X0 = 135,
+  V2MZ_RRR_0_OPCODE_X1 = 86,
+  V2PACKH_RRR_0_OPCODE_X0 = 136,
+  V2PACKH_RRR_0_OPCODE_X1 = 87,
+  V2PACKL_RRR_0_OPCODE_X0 = 137,
+  V2PACKL_RRR_0_OPCODE_X1 = 88,
+  V2PACKUC_RRR_0_OPCODE_X0 = 138,
+  V2PACKUC_RRR_0_OPCODE_X1 = 89,
+  V2SADAS_RRR_0_OPCODE_X0 = 139,
+  V2SADAU_RRR_0_OPCODE_X0 = 140,
+  V2SADS_RRR_0_OPCODE_X0 = 141,
+  V2SADU_RRR_0_OPCODE_X0 = 142,
+  V2SHLI_SHIFT_OPCODE_X0 = 10,
+  V2SHLI_SHIFT_OPCODE_X1 = 10,
+  V2SHLSC_RRR_0_OPCODE_X0 = 143,
+  V2SHLSC_RRR_0_OPCODE_X1 = 90,
+  V2SHL_RRR_0_OPCODE_X0 = 144,
+  V2SHL_RRR_0_OPCODE_X1 = 91,
+  V2SHRSI_SHIFT_OPCODE_X0 = 11,
+  V2SHRSI_SHIFT_OPCODE_X1 = 11,
+  V2SHRS_RRR_0_OPCODE_X0 = 145,
+  V2SHRS_RRR_0_OPCODE_X1 = 92,
+  V2SHRUI_SHIFT_OPCODE_X0 = 12,
+  V2SHRUI_SHIFT_OPCODE_X1 = 12,
+  V2SHRU_RRR_0_OPCODE_X0 = 146,
+  V2SHRU_RRR_0_OPCODE_X1 = 93,
+  V2SUBSC_RRR_0_OPCODE_X0 = 147,
+  V2SUBSC_RRR_0_OPCODE_X1 = 94,
+  V2SUB_RRR_0_OPCODE_X0 = 148,
+  V2SUB_RRR_0_OPCODE_X1 = 95,
+  V4ADDSC_RRR_0_OPCODE_X0 = 149,
+  V4ADDSC_RRR_0_OPCODE_X1 = 96,
+  V4ADD_RRR_0_OPCODE_X0 = 150,
+  V4ADD_RRR_0_OPCODE_X1 = 97,
+  V4INT_H_RRR_0_OPCODE_X0 = 151,
+  V4INT_H_RRR_0_OPCODE_X1 = 98,
+  V4INT_L_RRR_0_OPCODE_X0 = 152,
+  V4INT_L_RRR_0_OPCODE_X1 = 99,
+  V4PACKSC_RRR_0_OPCODE_X0 = 153,
+  V4PACKSC_RRR_0_OPCODE_X1 = 100,
+  V4SHLSC_RRR_0_OPCODE_X0 = 154,
+  V4SHLSC_RRR_0_OPCODE_X1 = 101,
+  V4SHL_RRR_0_OPCODE_X0 = 155,
+  V4SHL_RRR_0_OPCODE_X1 = 102,
+  V4SHRS_RRR_0_OPCODE_X0 = 156,
+  V4SHRS_RRR_0_OPCODE_X1 = 103,
+  V4SHRU_RRR_0_OPCODE_X0 = 157,
+  V4SHRU_RRR_0_OPCODE_X1 = 104,
+  V4SUBSC_RRR_0_OPCODE_X0 = 158,
+  V4SUBSC_RRR_0_OPCODE_X1 = 105,
+  V4SUB_RRR_0_OPCODE_X0 = 159,
+  V4SUB_RRR_0_OPCODE_X1 = 106,
+  WH64_UNARY_OPCODE_X1 = 38,
+  XORI_IMM8_OPCODE_X0 = 20,
+  XORI_IMM8_OPCODE_X1 = 45,
+  XOR_RRR_0_OPCODE_X0 = 160,
+  XOR_RRR_0_OPCODE_X1 = 107,
+  XOR_RRR_5_OPCODE_Y0 = 3,
+  XOR_RRR_5_OPCODE_Y1 = 3
 };
 
 #endif /* !_TILE_OPCODE_CONSTANTS_H */
diff -druN linux-2.6.39-libre/arch/tile/include/asm/opcode-tile_32.h linux-3.0-rc7-libre/arch/tile/include/asm/opcode-tile_32.h
--- linux-2.6.39-libre/arch/tile/include/asm/opcode-tile_32.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/tile/include/asm/opcode-tile_32.h	2011-07-11 19:51:52.000000000 -0400
@@ -1502,5 +1502,12 @@
                            decoded[TILE_MAX_INSTRUCTIONS_PER_BUNDLE]);
 
 
+/* Given a set of bundle bits and a specific pipe, returns which
+ * instruction the bundle contains in that pipe.
+ */
+extern const struct tile_opcode *
+find_opcode(tile_bundle_bits bits, tile_pipeline pipe);
+
+
 
 #endif /* opcode_tile_h */
diff -druN linux-2.6.39-libre/arch/tile/include/asm/opcode-tile_64.h linux-3.0-rc7-libre/arch/tile/include/asm/opcode-tile_64.h
--- linux-2.6.39-libre/arch/tile/include/asm/opcode-tile_64.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/tile/include/asm/opcode-tile_64.h	2011-07-11 19:51:52.000000000 -0400
@@ -5,863 +5,711 @@
 #ifndef opcode_tile_h
 #define opcode_tile_h
 
-typedef unsigned long long tile_bundle_bits;
+typedef unsigned long long tilegx_bundle_bits;
 
 
 enum
 {
-  TILE_MAX_OPERANDS = 5 /* mm */
+  TILEGX_MAX_OPERANDS = 4 /* bfexts */
 };
 
 typedef enum
 {
-  TILE_OPC_BPT,
-  TILE_OPC_INFO,
-  TILE_OPC_INFOL,
-  TILE_OPC_J,
-  TILE_OPC_JAL,
-  TILE_OPC_MOVE,
-  TILE_OPC_MOVE_SN,
-  TILE_OPC_MOVEI,
-  TILE_OPC_MOVEI_SN,
-  TILE_OPC_MOVELI,
-  TILE_OPC_MOVELI_SN,
-  TILE_OPC_MOVELIS,
-  TILE_OPC_PREFETCH,
-  TILE_OPC_RAISE,
-  TILE_OPC_ADD,
-  TILE_OPC_ADD_SN,
-  TILE_OPC_ADDB,
-  TILE_OPC_ADDB_SN,
-  TILE_OPC_ADDBS_U,
-  TILE_OPC_ADDBS_U_SN,
-  TILE_OPC_ADDH,
-  TILE_OPC_ADDH_SN,
-  TILE_OPC_ADDHS,
-  TILE_OPC_ADDHS_SN,
-  TILE_OPC_ADDI,
-  TILE_OPC_ADDI_SN,
-  TILE_OPC_ADDIB,
-  TILE_OPC_ADDIB_SN,
-  TILE_OPC_ADDIH,
-  TILE_OPC_ADDIH_SN,
-  TILE_OPC_ADDLI,
-  TILE_OPC_ADDLI_SN,
-  TILE_OPC_ADDLIS,
-  TILE_OPC_ADDS,
-  TILE_OPC_ADDS_SN,
-  TILE_OPC_ADIFFB_U,
-  TILE_OPC_ADIFFB_U_SN,
-  TILE_OPC_ADIFFH,
-  TILE_OPC_ADIFFH_SN,
-  TILE_OPC_AND,
-  TILE_OPC_AND_SN,
-  TILE_OPC_ANDI,
-  TILE_OPC_ANDI_SN,
-  TILE_OPC_AULI,
-  TILE_OPC_AVGB_U,
-  TILE_OPC_AVGB_U_SN,
-  TILE_OPC_AVGH,
-  TILE_OPC_AVGH_SN,
-  TILE_OPC_BBNS,
-  TILE_OPC_BBNS_SN,
-  TILE_OPC_BBNST,
-  TILE_OPC_BBNST_SN,
-  TILE_OPC_BBS,
-  TILE_OPC_BBS_SN,
-  TILE_OPC_BBST,
-  TILE_OPC_BBST_SN,
-  TILE_OPC_BGEZ,
-  TILE_OPC_BGEZ_SN,
-  TILE_OPC_BGEZT,
-  TILE_OPC_BGEZT_SN,
-  TILE_OPC_BGZ,
-  TILE_OPC_BGZ_SN,
-  TILE_OPC_BGZT,
-  TILE_OPC_BGZT_SN,
-  TILE_OPC_BITX,
-  TILE_OPC_BITX_SN,
-  TILE_OPC_BLEZ,
-  TILE_OPC_BLEZ_SN,
-  TILE_OPC_BLEZT,
-  TILE_OPC_BLEZT_SN,
-  TILE_OPC_BLZ,
-  TILE_OPC_BLZ_SN,
-  TILE_OPC_BLZT,
-  TILE_OPC_BLZT_SN,
-  TILE_OPC_BNZ,
-  TILE_OPC_BNZ_SN,
-  TILE_OPC_BNZT,
-  TILE_OPC_BNZT_SN,
-  TILE_OPC_BYTEX,
-  TILE_OPC_BYTEX_SN,
-  TILE_OPC_BZ,
-  TILE_OPC_BZ_SN,
-  TILE_OPC_BZT,
-  TILE_OPC_BZT_SN,
-  TILE_OPC_CLZ,
-  TILE_OPC_CLZ_SN,
-  TILE_OPC_CRC32_32,
-  TILE_OPC_CRC32_32_SN,
-  TILE_OPC_CRC32_8,
-  TILE_OPC_CRC32_8_SN,
-  TILE_OPC_CTZ,
-  TILE_OPC_CTZ_SN,
-  TILE_OPC_DRAIN,
-  TILE_OPC_DTLBPR,
-  TILE_OPC_DWORD_ALIGN,
-  TILE_OPC_DWORD_ALIGN_SN,
-  TILE_OPC_FINV,
-  TILE_OPC_FLUSH,
-  TILE_OPC_FNOP,
-  TILE_OPC_ICOH,
-  TILE_OPC_ILL,
-  TILE_OPC_INTHB,
-  TILE_OPC_INTHB_SN,
-  TILE_OPC_INTHH,
-  TILE_OPC_INTHH_SN,
-  TILE_OPC_INTLB,
-  TILE_OPC_INTLB_SN,
-  TILE_OPC_INTLH,
-  TILE_OPC_INTLH_SN,
-  TILE_OPC_INV,
-  TILE_OPC_IRET,
-  TILE_OPC_JALB,
-  TILE_OPC_JALF,
-  TILE_OPC_JALR,
-  TILE_OPC_JALRP,
-  TILE_OPC_JB,
-  TILE_OPC_JF,
-  TILE_OPC_JR,
-  TILE_OPC_JRP,
-  TILE_OPC_LB,
-  TILE_OPC_LB_SN,
-  TILE_OPC_LB_U,
-  TILE_OPC_LB_U_SN,
-  TILE_OPC_LBADD,
-  TILE_OPC_LBADD_SN,
-  TILE_OPC_LBADD_U,
-  TILE_OPC_LBADD_U_SN,
-  TILE_OPC_LH,
-  TILE_OPC_LH_SN,
-  TILE_OPC_LH_U,
-  TILE_OPC_LH_U_SN,
-  TILE_OPC_LHADD,
-  TILE_OPC_LHADD_SN,
-  TILE_OPC_LHADD_U,
-  TILE_OPC_LHADD_U_SN,
-  TILE_OPC_LNK,
-  TILE_OPC_LNK_SN,
-  TILE_OPC_LW,
-  TILE_OPC_LW_SN,
-  TILE_OPC_LW_NA,
-  TILE_OPC_LW_NA_SN,
-  TILE_OPC_LWADD,
-  TILE_OPC_LWADD_SN,
-  TILE_OPC_LWADD_NA,
-  TILE_OPC_LWADD_NA_SN,
-  TILE_OPC_MAXB_U,
-  TILE_OPC_MAXB_U_SN,
-  TILE_OPC_MAXH,
-  TILE_OPC_MAXH_SN,
-  TILE_OPC_MAXIB_U,
-  TILE_OPC_MAXIB_U_SN,
-  TILE_OPC_MAXIH,
-  TILE_OPC_MAXIH_SN,
-  TILE_OPC_MF,
-  TILE_OPC_MFSPR,
-  TILE_OPC_MINB_U,
-  TILE_OPC_MINB_U_SN,
-  TILE_OPC_MINH,
-  TILE_OPC_MINH_SN,
-  TILE_OPC_MINIB_U,
-  TILE_OPC_MINIB_U_SN,
-  TILE_OPC_MINIH,
-  TILE_OPC_MINIH_SN,
-  TILE_OPC_MM,
-  TILE_OPC_MNZ,
-  TILE_OPC_MNZ_SN,
-  TILE_OPC_MNZB,
-  TILE_OPC_MNZB_SN,
-  TILE_OPC_MNZH,
-  TILE_OPC_MNZH_SN,
-  TILE_OPC_MTSPR,
-  TILE_OPC_MULHH_SS,
-  TILE_OPC_MULHH_SS_SN,
-  TILE_OPC_MULHH_SU,
-  TILE_OPC_MULHH_SU_SN,
-  TILE_OPC_MULHH_UU,
-  TILE_OPC_MULHH_UU_SN,
-  TILE_OPC_MULHHA_SS,
-  TILE_OPC_MULHHA_SS_SN,
-  TILE_OPC_MULHHA_SU,
-  TILE_OPC_MULHHA_SU_SN,
-  TILE_OPC_MULHHA_UU,
-  TILE_OPC_MULHHA_UU_SN,
-  TILE_OPC_MULHHSA_UU,
-  TILE_OPC_MULHHSA_UU_SN,
-  TILE_OPC_MULHL_SS,
-  TILE_OPC_MULHL_SS_SN,
-  TILE_OPC_MULHL_SU,
-  TILE_OPC_MULHL_SU_SN,
-  TILE_OPC_MULHL_US,
-  TILE_OPC_MULHL_US_SN,
-  TILE_OPC_MULHL_UU,
-  TILE_OPC_MULHL_UU_SN,
-  TILE_OPC_MULHLA_SS,
-  TILE_OPC_MULHLA_SS_SN,
-  TILE_OPC_MULHLA_SU,
-  TILE_OPC_MULHLA_SU_SN,
-  TILE_OPC_MULHLA_US,
-  TILE_OPC_MULHLA_US_SN,
-  TILE_OPC_MULHLA_UU,
-  TILE_OPC_MULHLA_UU_SN,
-  TILE_OPC_MULHLSA_UU,
-  TILE_OPC_MULHLSA_UU_SN,
-  TILE_OPC_MULLL_SS,
-  TILE_OPC_MULLL_SS_SN,
-  TILE_OPC_MULLL_SU,
-  TILE_OPC_MULLL_SU_SN,
-  TILE_OPC_MULLL_UU,
-  TILE_OPC_MULLL_UU_SN,
-  TILE_OPC_MULLLA_SS,
-  TILE_OPC_MULLLA_SS_SN,
-  TILE_OPC_MULLLA_SU,
-  TILE_OPC_MULLLA_SU_SN,
-  TILE_OPC_MULLLA_UU,
-  TILE_OPC_MULLLA_UU_SN,
-  TILE_OPC_MULLLSA_UU,
-  TILE_OPC_MULLLSA_UU_SN,
-  TILE_OPC_MVNZ,
-  TILE_OPC_MVNZ_SN,
-  TILE_OPC_MVZ,
-  TILE_OPC_MVZ_SN,
-  TILE_OPC_MZ,
-  TILE_OPC_MZ_SN,
-  TILE_OPC_MZB,
-  TILE_OPC_MZB_SN,
-  TILE_OPC_MZH,
-  TILE_OPC_MZH_SN,
-  TILE_OPC_NAP,
-  TILE_OPC_NOP,
-  TILE_OPC_NOR,
-  TILE_OPC_NOR_SN,
-  TILE_OPC_OR,
-  TILE_OPC_OR_SN,
-  TILE_OPC_ORI,
-  TILE_OPC_ORI_SN,
-  TILE_OPC_PACKBS_U,
-  TILE_OPC_PACKBS_U_SN,
-  TILE_OPC_PACKHB,
-  TILE_OPC_PACKHB_SN,
-  TILE_OPC_PACKHS,
-  TILE_OPC_PACKHS_SN,
-  TILE_OPC_PACKLB,
-  TILE_OPC_PACKLB_SN,
-  TILE_OPC_PCNT,
-  TILE_OPC_PCNT_SN,
-  TILE_OPC_RL,
-  TILE_OPC_RL_SN,
-  TILE_OPC_RLI,
-  TILE_OPC_RLI_SN,
-  TILE_OPC_S1A,
-  TILE_OPC_S1A_SN,
-  TILE_OPC_S2A,
-  TILE_OPC_S2A_SN,
-  TILE_OPC_S3A,
-  TILE_OPC_S3A_SN,
-  TILE_OPC_SADAB_U,
-  TILE_OPC_SADAB_U_SN,
-  TILE_OPC_SADAH,
-  TILE_OPC_SADAH_SN,
-  TILE_OPC_SADAH_U,
-  TILE_OPC_SADAH_U_SN,
-  TILE_OPC_SADB_U,
-  TILE_OPC_SADB_U_SN,
-  TILE_OPC_SADH,
-  TILE_OPC_SADH_SN,
-  TILE_OPC_SADH_U,
-  TILE_OPC_SADH_U_SN,
-  TILE_OPC_SB,
-  TILE_OPC_SBADD,
-  TILE_OPC_SEQ,
-  TILE_OPC_SEQ_SN,
-  TILE_OPC_SEQB,
-  TILE_OPC_SEQB_SN,
-  TILE_OPC_SEQH,
-  TILE_OPC_SEQH_SN,
-  TILE_OPC_SEQI,
-  TILE_OPC_SEQI_SN,
-  TILE_OPC_SEQIB,
-  TILE_OPC_SEQIB_SN,
-  TILE_OPC_SEQIH,
-  TILE_OPC_SEQIH_SN,
-  TILE_OPC_SH,
-  TILE_OPC_SHADD,
-  TILE_OPC_SHL,
-  TILE_OPC_SHL_SN,
-  TILE_OPC_SHLB,
-  TILE_OPC_SHLB_SN,
-  TILE_OPC_SHLH,
-  TILE_OPC_SHLH_SN,
-  TILE_OPC_SHLI,
-  TILE_OPC_SHLI_SN,
-  TILE_OPC_SHLIB,
-  TILE_OPC_SHLIB_SN,
-  TILE_OPC_SHLIH,
-  TILE_OPC_SHLIH_SN,
-  TILE_OPC_SHR,
-  TILE_OPC_SHR_SN,
-  TILE_OPC_SHRB,
-  TILE_OPC_SHRB_SN,
-  TILE_OPC_SHRH,
-  TILE_OPC_SHRH_SN,
-  TILE_OPC_SHRI,
-  TILE_OPC_SHRI_SN,
-  TILE_OPC_SHRIB,
-  TILE_OPC_SHRIB_SN,
-  TILE_OPC_SHRIH,
-  TILE_OPC_SHRIH_SN,
-  TILE_OPC_SLT,
-  TILE_OPC_SLT_SN,
-  TILE_OPC_SLT_U,
-  TILE_OPC_SLT_U_SN,
-  TILE_OPC_SLTB,
-  TILE_OPC_SLTB_SN,
-  TILE_OPC_SLTB_U,
-  TILE_OPC_SLTB_U_SN,
-  TILE_OPC_SLTE,
-  TILE_OPC_SLTE_SN,
-  TILE_OPC_SLTE_U,
-  TILE_OPC_SLTE_U_SN,
-  TILE_OPC_SLTEB,
-  TILE_OPC_SLTEB_SN,
-  TILE_OPC_SLTEB_U,
-  TILE_OPC_SLTEB_U_SN,
-  TILE_OPC_SLTEH,
-  TILE_OPC_SLTEH_SN,
-  TILE_OPC_SLTEH_U,
-  TILE_OPC_SLTEH_U_SN,
-  TILE_OPC_SLTH,
-  TILE_OPC_SLTH_SN,
-  TILE_OPC_SLTH_U,
-  TILE_OPC_SLTH_U_SN,
-  TILE_OPC_SLTI,
-  TILE_OPC_SLTI_SN,
-  TILE_OPC_SLTI_U,
-  TILE_OPC_SLTI_U_SN,
-  TILE_OPC_SLTIB,
-  TILE_OPC_SLTIB_SN,
-  TILE_OPC_SLTIB_U,
-  TILE_OPC_SLTIB_U_SN,
-  TILE_OPC_SLTIH,
-  TILE_OPC_SLTIH_SN,
-  TILE_OPC_SLTIH_U,
-  TILE_OPC_SLTIH_U_SN,
-  TILE_OPC_SNE,
-  TILE_OPC_SNE_SN,
-  TILE_OPC_SNEB,
-  TILE_OPC_SNEB_SN,
-  TILE_OPC_SNEH,
-  TILE_OPC_SNEH_SN,
-  TILE_OPC_SRA,
-  TILE_OPC_SRA_SN,
-  TILE_OPC_SRAB,
-  TILE_OPC_SRAB_SN,
-  TILE_OPC_SRAH,
-  TILE_OPC_SRAH_SN,
-  TILE_OPC_SRAI,
-  TILE_OPC_SRAI_SN,
-  TILE_OPC_SRAIB,
-  TILE_OPC_SRAIB_SN,
-  TILE_OPC_SRAIH,
-  TILE_OPC_SRAIH_SN,
-  TILE_OPC_SUB,
-  TILE_OPC_SUB_SN,
-  TILE_OPC_SUBB,
-  TILE_OPC_SUBB_SN,
-  TILE_OPC_SUBBS_U,
-  TILE_OPC_SUBBS_U_SN,
-  TILE_OPC_SUBH,
-  TILE_OPC_SUBH_SN,
-  TILE_OPC_SUBHS,
-  TILE_OPC_SUBHS_SN,
-  TILE_OPC_SUBS,
-  TILE_OPC_SUBS_SN,
-  TILE_OPC_SW,
-  TILE_OPC_SWADD,
-  TILE_OPC_SWINT0,
-  TILE_OPC_SWINT1,
-  TILE_OPC_SWINT2,
-  TILE_OPC_SWINT3,
-  TILE_OPC_TBLIDXB0,
-  TILE_OPC_TBLIDXB0_SN,
-  TILE_OPC_TBLIDXB1,
-  TILE_OPC_TBLIDXB1_SN,
-  TILE_OPC_TBLIDXB2,
-  TILE_OPC_TBLIDXB2_SN,
-  TILE_OPC_TBLIDXB3,
-  TILE_OPC_TBLIDXB3_SN,
-  TILE_OPC_TNS,
-  TILE_OPC_TNS_SN,
-  TILE_OPC_WH64,
-  TILE_OPC_XOR,
-  TILE_OPC_XOR_SN,
-  TILE_OPC_XORI,
-  TILE_OPC_XORI_SN,
-  TILE_OPC_NONE
-} tile_mnemonic;
+  TILEGX_OPC_BPT,
+  TILEGX_OPC_INFO,
+  TILEGX_OPC_INFOL,
+  TILEGX_OPC_MOVE,
+  TILEGX_OPC_MOVEI,
+  TILEGX_OPC_MOVELI,
+  TILEGX_OPC_PREFETCH,
+  TILEGX_OPC_PREFETCH_ADD_L1,
+  TILEGX_OPC_PREFETCH_ADD_L1_FAULT,
+  TILEGX_OPC_PREFETCH_ADD_L2,
+  TILEGX_OPC_PREFETCH_ADD_L2_FAULT,
+  TILEGX_OPC_PREFETCH_ADD_L3,
+  TILEGX_OPC_PREFETCH_ADD_L3_FAULT,
+  TILEGX_OPC_PREFETCH_L1,
+  TILEGX_OPC_PREFETCH_L1_FAULT,
+  TILEGX_OPC_PREFETCH_L2,
+  TILEGX_OPC_PREFETCH_L2_FAULT,
+  TILEGX_OPC_PREFETCH_L3,
+  TILEGX_OPC_PREFETCH_L3_FAULT,
+  TILEGX_OPC_RAISE,
+  TILEGX_OPC_ADD,
+  TILEGX_OPC_ADDI,
+  TILEGX_OPC_ADDLI,
+  TILEGX_OPC_ADDX,
+  TILEGX_OPC_ADDXI,
+  TILEGX_OPC_ADDXLI,
+  TILEGX_OPC_ADDXSC,
+  TILEGX_OPC_AND,
+  TILEGX_OPC_ANDI,
+  TILEGX_OPC_BEQZ,
+  TILEGX_OPC_BEQZT,
+  TILEGX_OPC_BFEXTS,
+  TILEGX_OPC_BFEXTU,
+  TILEGX_OPC_BFINS,
+  TILEGX_OPC_BGEZ,
+  TILEGX_OPC_BGEZT,
+  TILEGX_OPC_BGTZ,
+  TILEGX_OPC_BGTZT,
+  TILEGX_OPC_BLBC,
+  TILEGX_OPC_BLBCT,
+  TILEGX_OPC_BLBS,
+  TILEGX_OPC_BLBST,
+  TILEGX_OPC_BLEZ,
+  TILEGX_OPC_BLEZT,
+  TILEGX_OPC_BLTZ,
+  TILEGX_OPC_BLTZT,
+  TILEGX_OPC_BNEZ,
+  TILEGX_OPC_BNEZT,
+  TILEGX_OPC_CLZ,
+  TILEGX_OPC_CMOVEQZ,
+  TILEGX_OPC_CMOVNEZ,
+  TILEGX_OPC_CMPEQ,
+  TILEGX_OPC_CMPEQI,
+  TILEGX_OPC_CMPEXCH,
+  TILEGX_OPC_CMPEXCH4,
+  TILEGX_OPC_CMPLES,
+  TILEGX_OPC_CMPLEU,
+  TILEGX_OPC_CMPLTS,
+  TILEGX_OPC_CMPLTSI,
+  TILEGX_OPC_CMPLTU,
+  TILEGX_OPC_CMPLTUI,
+  TILEGX_OPC_CMPNE,
+  TILEGX_OPC_CMUL,
+  TILEGX_OPC_CMULA,
+  TILEGX_OPC_CMULAF,
+  TILEGX_OPC_CMULF,
+  TILEGX_OPC_CMULFR,
+  TILEGX_OPC_CMULH,
+  TILEGX_OPC_CMULHR,
+  TILEGX_OPC_CRC32_32,
+  TILEGX_OPC_CRC32_8,
+  TILEGX_OPC_CTZ,
+  TILEGX_OPC_DBLALIGN,
+  TILEGX_OPC_DBLALIGN2,
+  TILEGX_OPC_DBLALIGN4,
+  TILEGX_OPC_DBLALIGN6,
+  TILEGX_OPC_DRAIN,
+  TILEGX_OPC_DTLBPR,
+  TILEGX_OPC_EXCH,
+  TILEGX_OPC_EXCH4,
+  TILEGX_OPC_FDOUBLE_ADD_FLAGS,
+  TILEGX_OPC_FDOUBLE_ADDSUB,
+  TILEGX_OPC_FDOUBLE_MUL_FLAGS,
+  TILEGX_OPC_FDOUBLE_PACK1,
+  TILEGX_OPC_FDOUBLE_PACK2,
+  TILEGX_OPC_FDOUBLE_SUB_FLAGS,
+  TILEGX_OPC_FDOUBLE_UNPACK_MAX,
+  TILEGX_OPC_FDOUBLE_UNPACK_MIN,
+  TILEGX_OPC_FETCHADD,
+  TILEGX_OPC_FETCHADD4,
+  TILEGX_OPC_FETCHADDGEZ,
+  TILEGX_OPC_FETCHADDGEZ4,
+  TILEGX_OPC_FETCHAND,
+  TILEGX_OPC_FETCHAND4,
+  TILEGX_OPC_FETCHOR,
+  TILEGX_OPC_FETCHOR4,
+  TILEGX_OPC_FINV,
+  TILEGX_OPC_FLUSH,
+  TILEGX_OPC_FLUSHWB,
+  TILEGX_OPC_FNOP,
+  TILEGX_OPC_FSINGLE_ADD1,
+  TILEGX_OPC_FSINGLE_ADDSUB2,
+  TILEGX_OPC_FSINGLE_MUL1,
+  TILEGX_OPC_FSINGLE_MUL2,
+  TILEGX_OPC_FSINGLE_PACK1,
+  TILEGX_OPC_FSINGLE_PACK2,
+  TILEGX_OPC_FSINGLE_SUB1,
+  TILEGX_OPC_ICOH,
+  TILEGX_OPC_ILL,
+  TILEGX_OPC_INV,
+  TILEGX_OPC_IRET,
+  TILEGX_OPC_J,
+  TILEGX_OPC_JAL,
+  TILEGX_OPC_JALR,
+  TILEGX_OPC_JALRP,
+  TILEGX_OPC_JR,
+  TILEGX_OPC_JRP,
+  TILEGX_OPC_LD,
+  TILEGX_OPC_LD1S,
+  TILEGX_OPC_LD1S_ADD,
+  TILEGX_OPC_LD1U,
+  TILEGX_OPC_LD1U_ADD,
+  TILEGX_OPC_LD2S,
+  TILEGX_OPC_LD2S_ADD,
+  TILEGX_OPC_LD2U,
+  TILEGX_OPC_LD2U_ADD,
+  TILEGX_OPC_LD4S,
+  TILEGX_OPC_LD4S_ADD,
+  TILEGX_OPC_LD4U,
+  TILEGX_OPC_LD4U_ADD,
+  TILEGX_OPC_LD_ADD,
+  TILEGX_OPC_LDNA,
+  TILEGX_OPC_LDNA_ADD,
+  TILEGX_OPC_LDNT,
+  TILEGX_OPC_LDNT1S,
+  TILEGX_OPC_LDNT1S_ADD,
+  TILEGX_OPC_LDNT1U,
+  TILEGX_OPC_LDNT1U_ADD,
+  TILEGX_OPC_LDNT2S,
+  TILEGX_OPC_LDNT2S_ADD,
+  TILEGX_OPC_LDNT2U,
+  TILEGX_OPC_LDNT2U_ADD,
+  TILEGX_OPC_LDNT4S,
+  TILEGX_OPC_LDNT4S_ADD,
+  TILEGX_OPC_LDNT4U,
+  TILEGX_OPC_LDNT4U_ADD,
+  TILEGX_OPC_LDNT_ADD,
+  TILEGX_OPC_LNK,
+  TILEGX_OPC_MF,
+  TILEGX_OPC_MFSPR,
+  TILEGX_OPC_MM,
+  TILEGX_OPC_MNZ,
+  TILEGX_OPC_MTSPR,
+  TILEGX_OPC_MUL_HS_HS,
+  TILEGX_OPC_MUL_HS_HU,
+  TILEGX_OPC_MUL_HS_LS,
+  TILEGX_OPC_MUL_HS_LU,
+  TILEGX_OPC_MUL_HU_HU,
+  TILEGX_OPC_MUL_HU_LS,
+  TILEGX_OPC_MUL_HU_LU,
+  TILEGX_OPC_MUL_LS_LS,
+  TILEGX_OPC_MUL_LS_LU,
+  TILEGX_OPC_MUL_LU_LU,
+  TILEGX_OPC_MULA_HS_HS,
+  TILEGX_OPC_MULA_HS_HU,
+  TILEGX_OPC_MULA_HS_LS,
+  TILEGX_OPC_MULA_HS_LU,
+  TILEGX_OPC_MULA_HU_HU,
+  TILEGX_OPC_MULA_HU_LS,
+  TILEGX_OPC_MULA_HU_LU,
+  TILEGX_OPC_MULA_LS_LS,
+  TILEGX_OPC_MULA_LS_LU,
+  TILEGX_OPC_MULA_LU_LU,
+  TILEGX_OPC_MULAX,
+  TILEGX_OPC_MULX,
+  TILEGX_OPC_MZ,
+  TILEGX_OPC_NAP,
+  TILEGX_OPC_NOP,
+  TILEGX_OPC_NOR,
+  TILEGX_OPC_OR,
+  TILEGX_OPC_ORI,
+  TILEGX_OPC_PCNT,
+  TILEGX_OPC_REVBITS,
+  TILEGX_OPC_REVBYTES,
+  TILEGX_OPC_ROTL,
+  TILEGX_OPC_ROTLI,
+  TILEGX_OPC_SHL,
+  TILEGX_OPC_SHL16INSLI,
+  TILEGX_OPC_SHL1ADD,
+  TILEGX_OPC_SHL1ADDX,
+  TILEGX_OPC_SHL2ADD,
+  TILEGX_OPC_SHL2ADDX,
+  TILEGX_OPC_SHL3ADD,
+  TILEGX_OPC_SHL3ADDX,
+  TILEGX_OPC_SHLI,
+  TILEGX_OPC_SHLX,
+  TILEGX_OPC_SHLXI,
+  TILEGX_OPC_SHRS,
+  TILEGX_OPC_SHRSI,
+  TILEGX_OPC_SHRU,
+  TILEGX_OPC_SHRUI,
+  TILEGX_OPC_SHRUX,
+  TILEGX_OPC_SHRUXI,
+  TILEGX_OPC_SHUFFLEBYTES,
+  TILEGX_OPC_ST,
+  TILEGX_OPC_ST1,
+  TILEGX_OPC_ST1_ADD,
+  TILEGX_OPC_ST2,
+  TILEGX_OPC_ST2_ADD,
+  TILEGX_OPC_ST4,
+  TILEGX_OPC_ST4_ADD,
+  TILEGX_OPC_ST_ADD,
+  TILEGX_OPC_STNT,
+  TILEGX_OPC_STNT1,
+  TILEGX_OPC_STNT1_ADD,
+  TILEGX_OPC_STNT2,
+  TILEGX_OPC_STNT2_ADD,
+  TILEGX_OPC_STNT4,
+  TILEGX_OPC_STNT4_ADD,
+  TILEGX_OPC_STNT_ADD,
+  TILEGX_OPC_SUB,
+  TILEGX_OPC_SUBX,
+  TILEGX_OPC_SUBXSC,
+  TILEGX_OPC_SWINT0,
+  TILEGX_OPC_SWINT1,
+  TILEGX_OPC_SWINT2,
+  TILEGX_OPC_SWINT3,
+  TILEGX_OPC_TBLIDXB0,
+  TILEGX_OPC_TBLIDXB1,
+  TILEGX_OPC_TBLIDXB2,
+  TILEGX_OPC_TBLIDXB3,
+  TILEGX_OPC_V1ADD,
+  TILEGX_OPC_V1ADDI,
+  TILEGX_OPC_V1ADDUC,
+  TILEGX_OPC_V1ADIFFU,
+  TILEGX_OPC_V1AVGU,
+  TILEGX_OPC_V1CMPEQ,
+  TILEGX_OPC_V1CMPEQI,
+  TILEGX_OPC_V1CMPLES,
+  TILEGX_OPC_V1CMPLEU,
+  TILEGX_OPC_V1CMPLTS,
+  TILEGX_OPC_V1CMPLTSI,
+  TILEGX_OPC_V1CMPLTU,
+  TILEGX_OPC_V1CMPLTUI,
+  TILEGX_OPC_V1CMPNE,
+  TILEGX_OPC_V1DDOTPU,
+  TILEGX_OPC_V1DDOTPUA,
+  TILEGX_OPC_V1DDOTPUS,
+  TILEGX_OPC_V1DDOTPUSA,
+  TILEGX_OPC_V1DOTP,
+  TILEGX_OPC_V1DOTPA,
+  TILEGX_OPC_V1DOTPU,
+  TILEGX_OPC_V1DOTPUA,
+  TILEGX_OPC_V1DOTPUS,
+  TILEGX_OPC_V1DOTPUSA,
+  TILEGX_OPC_V1INT_H,
+  TILEGX_OPC_V1INT_L,
+  TILEGX_OPC_V1MAXU,
+  TILEGX_OPC_V1MAXUI,
+  TILEGX_OPC_V1MINU,
+  TILEGX_OPC_V1MINUI,
+  TILEGX_OPC_V1MNZ,
+  TILEGX_OPC_V1MULTU,
+  TILEGX_OPC_V1MULU,
+  TILEGX_OPC_V1MULUS,
+  TILEGX_OPC_V1MZ,
+  TILEGX_OPC_V1SADAU,
+  TILEGX_OPC_V1SADU,
+  TILEGX_OPC_V1SHL,
+  TILEGX_OPC_V1SHLI,
+  TILEGX_OPC_V1SHRS,
+  TILEGX_OPC_V1SHRSI,
+  TILEGX_OPC_V1SHRU,
+  TILEGX_OPC_V1SHRUI,
+  TILEGX_OPC_V1SUB,
+  TILEGX_OPC_V1SUBUC,
+  TILEGX_OPC_V2ADD,
+  TILEGX_OPC_V2ADDI,
+  TILEGX_OPC_V2ADDSC,
+  TILEGX_OPC_V2ADIFFS,
+  TILEGX_OPC_V2AVGS,
+  TILEGX_OPC_V2CMPEQ,
+  TILEGX_OPC_V2CMPEQI,
+  TILEGX_OPC_V2CMPLES,
+  TILEGX_OPC_V2CMPLEU,
+  TILEGX_OPC_V2CMPLTS,
+  TILEGX_OPC_V2CMPLTSI,
+  TILEGX_OPC_V2CMPLTU,
+  TILEGX_OPC_V2CMPLTUI,
+  TILEGX_OPC_V2CMPNE,
+  TILEGX_OPC_V2DOTP,
+  TILEGX_OPC_V2DOTPA,
+  TILEGX_OPC_V2INT_H,
+  TILEGX_OPC_V2INT_L,
+  TILEGX_OPC_V2MAXS,
+  TILEGX_OPC_V2MAXSI,
+  TILEGX_OPC_V2MINS,
+  TILEGX_OPC_V2MINSI,
+  TILEGX_OPC_V2MNZ,
+  TILEGX_OPC_V2MULFSC,
+  TILEGX_OPC_V2MULS,
+  TILEGX_OPC_V2MULTS,
+  TILEGX_OPC_V2MZ,
+  TILEGX_OPC_V2PACKH,
+  TILEGX_OPC_V2PACKL,
+  TILEGX_OPC_V2PACKUC,
+  TILEGX_OPC_V2SADAS,
+  TILEGX_OPC_V2SADAU,
+  TILEGX_OPC_V2SADS,
+  TILEGX_OPC_V2SADU,
+  TILEGX_OPC_V2SHL,
+  TILEGX_OPC_V2SHLI,
+  TILEGX_OPC_V2SHLSC,
+  TILEGX_OPC_V2SHRS,
+  TILEGX_OPC_V2SHRSI,
+  TILEGX_OPC_V2SHRU,
+  TILEGX_OPC_V2SHRUI,
+  TILEGX_OPC_V2SUB,
+  TILEGX_OPC_V2SUBSC,
+  TILEGX_OPC_V4ADD,
+  TILEGX_OPC_V4ADDSC,
+  TILEGX_OPC_V4INT_H,
+  TILEGX_OPC_V4INT_L,
+  TILEGX_OPC_V4PACKSC,
+  TILEGX_OPC_V4SHL,
+  TILEGX_OPC_V4SHLSC,
+  TILEGX_OPC_V4SHRS,
+  TILEGX_OPC_V4SHRU,
+  TILEGX_OPC_V4SUB,
+  TILEGX_OPC_V4SUBSC,
+  TILEGX_OPC_WH64,
+  TILEGX_OPC_XOR,
+  TILEGX_OPC_XORI,
+  TILEGX_OPC_NONE
+} tilegx_mnemonic;
 
 /* 64-bit pattern for a { bpt ; nop } bundle. */
-#define TILE_BPT_BUNDLE 0x400b3cae70166000ULL
+#define TILEGX_BPT_BUNDLE 0x286a44ae51485000ULL
 
 
-#define TILE_ELF_MACHINE_CODE EM_TILEPRO
+#define TILE_ELF_MACHINE_CODE EM_TILE64
 
-#define TILE_ELF_NAME "elf32-tilepro"
+#define TILE_ELF_NAME "elf32-tile64"
 
 
 static __inline unsigned int
-get_BrOff_SN(tile_bundle_bits num)
+get_BFEnd_X0(tilegx_bundle_bits num)
 {
   const unsigned int n = (unsigned int)num;
-  return (((n >> 0)) & 0x3ff);
+  return (((n >> 12)) & 0x3f);
 }
 
 static __inline unsigned int
-get_BrOff_X1(tile_bundle_bits n)
+get_BFOpcodeExtension_X0(tilegx_bundle_bits num)
 {
-  return (((unsigned int)(n >> 43)) & 0x00007fff) |
-         (((unsigned int)(n >> 20)) & 0x00018000);
+  const unsigned int n = (unsigned int)num;
+  return (((n >> 24)) & 0xf);
 }
 
 static __inline unsigned int
-get_BrType_X1(tile_bundle_bits n)
+get_BFStart_X0(tilegx_bundle_bits num)
 {
-  return (((unsigned int)(n >> 31)) & 0xf);
+  const unsigned int n = (unsigned int)num;
+  return (((n >> 18)) & 0x3f);
 }
 
 static __inline unsigned int
-get_Dest_Imm8_X1(tile_bundle_bits n)
+get_BrOff_X1(tilegx_bundle_bits n)
 {
   return (((unsigned int)(n >> 31)) & 0x0000003f) |
-         (((unsigned int)(n >> 43)) & 0x000000c0);
+         (((unsigned int)(n >> 37)) & 0x0001ffc0);
 }
 
 static __inline unsigned int
-get_Dest_SN(tile_bundle_bits num)
+get_BrType_X1(tilegx_bundle_bits n)
 {
-  const unsigned int n = (unsigned int)num;
-  return (((n >> 2)) & 0x3);
+  return (((unsigned int)(n >> 54)) & 0x1f);
 }
 
 static __inline unsigned int
-get_Dest_X0(tile_bundle_bits num)
+get_Dest_Imm8_X1(tilegx_bundle_bits n)
+{
+  return (((unsigned int)(n >> 31)) & 0x0000003f) |
+         (((unsigned int)(n >> 43)) & 0x000000c0);
+}
+
+static __inline unsigned int
+get_Dest_X0(tilegx_bundle_bits num)
 {
   const unsigned int n = (unsigned int)num;
   return (((n >> 0)) & 0x3f);
 }
 
 static __inline unsigned int
-get_Dest_X1(tile_bundle_bits n)
+get_Dest_X1(tilegx_bundle_bits n)
 {
   return (((unsigned int)(n >> 31)) & 0x3f);
 }
 
 static __inline unsigned int
-get_Dest_Y0(tile_bundle_bits num)
+get_Dest_Y0(tilegx_bundle_bits num)
 {
   const unsigned int n = (unsigned int)num;
   return (((n >> 0)) & 0x3f);
 }
 
 static __inline unsigned int
-get_Dest_Y1(tile_bundle_bits n)
+get_Dest_Y1(tilegx_bundle_bits n)
 {
   return (((unsigned int)(n >> 31)) & 0x3f);
 }
 
 static __inline unsigned int
-get_Imm16_X0(tile_bundle_bits num)
+get_Imm16_X0(tilegx_bundle_bits num)
 {
   const unsigned int n = (unsigned int)num;
   return (((n >> 12)) & 0xffff);
 }
 
 static __inline unsigned int
-get_Imm16_X1(tile_bundle_bits n)
+get_Imm16_X1(tilegx_bundle_bits n)
 {
   return (((unsigned int)(n >> 43)) & 0xffff);
 }
 
 static __inline unsigned int
-get_Imm8_SN(tile_bundle_bits num)
-{
-  const unsigned int n = (unsigned int)num;
-  return (((n >> 0)) & 0xff);
-}
-
-static __inline unsigned int
-get_Imm8_X0(tile_bundle_bits num)
+get_Imm8OpcodeExtension_X0(tilegx_bundle_bits num)
 {
   const unsigned int n = (unsigned int)num;
-  return (((n >> 12)) & 0xff);
+  return (((n >> 20)) & 0xff);
 }
 
 static __inline unsigned int
-get_Imm8_X1(tile_bundle_bits n)
+get_Imm8OpcodeExtension_X1(tilegx_bundle_bits n)
 {
-  return (((unsigned int)(n >> 43)) & 0xff);
+  return (((unsigned int)(n >> 51)) & 0xff);
 }
 
 static __inline unsigned int
-get_Imm8_Y0(tile_bundle_bits num)
+get_Imm8_X0(tilegx_bundle_bits num)
 {
   const unsigned int n = (unsigned int)num;
   return (((n >> 12)) & 0xff);
 }
 
 static __inline unsigned int
-get_Imm8_Y1(tile_bundle_bits n)
+get_Imm8_X1(tilegx_bundle_bits n)
 {
   return (((unsigned int)(n >> 43)) & 0xff);
 }
 
 static __inline unsigned int
-get_ImmOpcodeExtension_X0(tile_bundle_bits num)
-{
-  const unsigned int n = (unsigned int)num;
-  return (((n >> 20)) & 0x7f);
-}
-
-static __inline unsigned int
-get_ImmOpcodeExtension_X1(tile_bundle_bits n)
-{
-  return (((unsigned int)(n >> 51)) & 0x7f);
-}
-
-static __inline unsigned int
-get_ImmRROpcodeExtension_SN(tile_bundle_bits num)
+get_Imm8_Y0(tilegx_bundle_bits num)
 {
   const unsigned int n = (unsigned int)num;
-  return (((n >> 8)) & 0x3);
-}
-
-static __inline unsigned int
-get_JOffLong_X1(tile_bundle_bits n)
-{
-  return (((unsigned int)(n >> 43)) & 0x00007fff) |
-         (((unsigned int)(n >> 20)) & 0x00018000) |
-         (((unsigned int)(n >> 14)) & 0x001e0000) |
-         (((unsigned int)(n >> 16)) & 0x07e00000) |
-         (((unsigned int)(n >> 31)) & 0x18000000);
-}
-
-static __inline unsigned int
-get_JOff_X1(tile_bundle_bits n)
-{
-  return (((unsigned int)(n >> 43)) & 0x00007fff) |
-         (((unsigned int)(n >> 20)) & 0x00018000) |
-         (((unsigned int)(n >> 14)) & 0x001e0000) |
-         (((unsigned int)(n >> 16)) & 0x07e00000) |
-         (((unsigned int)(n >> 31)) & 0x08000000);
-}
-
-static __inline unsigned int
-get_MF_Imm15_X1(tile_bundle_bits n)
-{
-  return (((unsigned int)(n >> 37)) & 0x00003fff) |
-         (((unsigned int)(n >> 44)) & 0x00004000);
+  return (((n >> 12)) & 0xff);
 }
 
 static __inline unsigned int
-get_MMEnd_X0(tile_bundle_bits num)
+get_Imm8_Y1(tilegx_bundle_bits n)
 {
-  const unsigned int n = (unsigned int)num;
-  return (((n >> 18)) & 0x1f);
+  return (((unsigned int)(n >> 43)) & 0xff);
 }
 
 static __inline unsigned int
-get_MMEnd_X1(tile_bundle_bits n)
+get_JumpOff_X1(tilegx_bundle_bits n)
 {
-  return (((unsigned int)(n >> 49)) & 0x1f);
+  return (((unsigned int)(n >> 31)) & 0x7ffffff);
 }
 
 static __inline unsigned int
-get_MMStart_X0(tile_bundle_bits num)
+get_JumpOpcodeExtension_X1(tilegx_bundle_bits n)
 {
-  const unsigned int n = (unsigned int)num;
-  return (((n >> 23)) & 0x1f);
+  return (((unsigned int)(n >> 58)) & 0x1);
 }
 
 static __inline unsigned int
-get_MMStart_X1(tile_bundle_bits n)
+get_MF_Imm14_X1(tilegx_bundle_bits n)
 {
-  return (((unsigned int)(n >> 54)) & 0x1f);
+  return (((unsigned int)(n >> 37)) & 0x3fff);
 }
 
 static __inline unsigned int
-get_MT_Imm15_X1(tile_bundle_bits n)
+get_MT_Imm14_X1(tilegx_bundle_bits n)
 {
   return (((unsigned int)(n >> 31)) & 0x0000003f) |
-         (((unsigned int)(n >> 37)) & 0x00003fc0) |
-         (((unsigned int)(n >> 44)) & 0x00004000);
-}
-
-static __inline unsigned int
-get_Mode(tile_bundle_bits n)
-{
-  return (((unsigned int)(n >> 63)) & 0x1);
-}
-
-static __inline unsigned int
-get_NoRegOpcodeExtension_SN(tile_bundle_bits num)
-{
-  const unsigned int n = (unsigned int)num;
-  return (((n >> 0)) & 0xf);
+         (((unsigned int)(n >> 37)) & 0x00003fc0);
 }
 
 static __inline unsigned int
-get_Opcode_SN(tile_bundle_bits num)
+get_Mode(tilegx_bundle_bits n)
 {
-  const unsigned int n = (unsigned int)num;
-  return (((n >> 10)) & 0x3f);
+  return (((unsigned int)(n >> 62)) & 0x3);
 }
 
 static __inline unsigned int
-get_Opcode_X0(tile_bundle_bits num)
+get_Opcode_X0(tilegx_bundle_bits num)
 {
   const unsigned int n = (unsigned int)num;
   return (((n >> 28)) & 0x7);
 }
 
 static __inline unsigned int
-get_Opcode_X1(tile_bundle_bits n)
+get_Opcode_X1(tilegx_bundle_bits n)
 {
-  return (((unsigned int)(n >> 59)) & 0xf);
+  return (((unsigned int)(n >> 59)) & 0x7);
 }
 
 static __inline unsigned int
-get_Opcode_Y0(tile_bundle_bits num)
+get_Opcode_Y0(tilegx_bundle_bits num)
 {
   const unsigned int n = (unsigned int)num;
   return (((n >> 27)) & 0xf);
 }
 
 static __inline unsigned int
-get_Opcode_Y1(tile_bundle_bits n)
-{
-  return (((unsigned int)(n >> 59)) & 0xf);
-}
-
-static __inline unsigned int
-get_Opcode_Y2(tile_bundle_bits n)
+get_Opcode_Y1(tilegx_bundle_bits n)
 {
-  return (((unsigned int)(n >> 56)) & 0x7);
+  return (((unsigned int)(n >> 58)) & 0xf);
 }
 
 static __inline unsigned int
-get_RROpcodeExtension_SN(tile_bundle_bits num)
+get_Opcode_Y2(tilegx_bundle_bits n)
 {
-  const unsigned int n = (unsigned int)num;
-  return (((n >> 4)) & 0xf);
+  return (((n >> 26)) & 0x00000001) |
+         (((unsigned int)(n >> 56)) & 0x00000002);
 }
 
 static __inline unsigned int
-get_RRROpcodeExtension_X0(tile_bundle_bits num)
+get_RRROpcodeExtension_X0(tilegx_bundle_bits num)
 {
   const unsigned int n = (unsigned int)num;
-  return (((n >> 18)) & 0x1ff);
+  return (((n >> 18)) & 0x3ff);
 }
 
 static __inline unsigned int
-get_RRROpcodeExtension_X1(tile_bundle_bits n)
+get_RRROpcodeExtension_X1(tilegx_bundle_bits n)
 {
-  return (((unsigned int)(n >> 49)) & 0x1ff);
+  return (((unsigned int)(n >> 49)) & 0x3ff);
 }
 
 static __inline unsigned int
-get_RRROpcodeExtension_Y0(tile_bundle_bits num)
+get_RRROpcodeExtension_Y0(tilegx_bundle_bits num)
 {
   const unsigned int n = (unsigned int)num;
   return (((n >> 18)) & 0x3);
 }
 
 static __inline unsigned int
-get_RRROpcodeExtension_Y1(tile_bundle_bits n)
+get_RRROpcodeExtension_Y1(tilegx_bundle_bits n)
 {
   return (((unsigned int)(n >> 49)) & 0x3);
 }
 
 static __inline unsigned int
-get_RouteOpcodeExtension_SN(tile_bundle_bits num)
-{
-  const unsigned int n = (unsigned int)num;
-  return (((n >> 0)) & 0x3ff);
-}
-
-static __inline unsigned int
-get_S_X0(tile_bundle_bits num)
+get_ShAmt_X0(tilegx_bundle_bits num)
 {
   const unsigned int n = (unsigned int)num;
-  return (((n >> 27)) & 0x1);
+  return (((n >> 12)) & 0x3f);
 }
 
 static __inline unsigned int
-get_S_X1(tile_bundle_bits n)
+get_ShAmt_X1(tilegx_bundle_bits n)
 {
-  return (((unsigned int)(n >> 58)) & 0x1);
+  return (((unsigned int)(n >> 43)) & 0x3f);
 }
 
 static __inline unsigned int
-get_ShAmt_X0(tile_bundle_bits num)
+get_ShAmt_Y0(tilegx_bundle_bits num)
 {
   const unsigned int n = (unsigned int)num;
-  return (((n >> 12)) & 0x1f);
+  return (((n >> 12)) & 0x3f);
 }
 
 static __inline unsigned int
-get_ShAmt_X1(tile_bundle_bits n)
+get_ShAmt_Y1(tilegx_bundle_bits n)
 {
-  return (((unsigned int)(n >> 43)) & 0x1f);
+  return (((unsigned int)(n >> 43)) & 0x3f);
 }
 
 static __inline unsigned int
-get_ShAmt_Y0(tile_bundle_bits num)
+get_ShiftOpcodeExtension_X0(tilegx_bundle_bits num)
 {
   const unsigned int n = (unsigned int)num;
-  return (((n >> 12)) & 0x1f);
+  return (((n >> 18)) & 0x3ff);
 }
 
 static __inline unsigned int
-get_ShAmt_Y1(tile_bundle_bits n)
+get_ShiftOpcodeExtension_X1(tilegx_bundle_bits n)
 {
-  return (((unsigned int)(n >> 43)) & 0x1f);
+  return (((unsigned int)(n >> 49)) & 0x3ff);
 }
 
 static __inline unsigned int
-get_SrcA_X0(tile_bundle_bits num)
+get_ShiftOpcodeExtension_Y0(tilegx_bundle_bits num)
 {
   const unsigned int n = (unsigned int)num;
-  return (((n >> 6)) & 0x3f);
+  return (((n >> 18)) & 0x3);
 }
 
 static __inline unsigned int
-get_SrcA_X1(tile_bundle_bits n)
+get_ShiftOpcodeExtension_Y1(tilegx_bundle_bits n)
 {
-  return (((unsigned int)(n >> 37)) & 0x3f);
+  return (((unsigned int)(n >> 49)) & 0x3);
 }
 
 static __inline unsigned int
-get_SrcA_Y0(tile_bundle_bits num)
+get_SrcA_X0(tilegx_bundle_bits num)
 {
   const unsigned int n = (unsigned int)num;
   return (((n >> 6)) & 0x3f);
 }
 
 static __inline unsigned int
-get_SrcA_Y1(tile_bundle_bits n)
+get_SrcA_X1(tilegx_bundle_bits n)
 {
   return (((unsigned int)(n >> 37)) & 0x3f);
 }
 
 static __inline unsigned int
-get_SrcA_Y2(tile_bundle_bits n)
+get_SrcA_Y0(tilegx_bundle_bits num)
 {
-  return (((n >> 26)) & 0x00000001) |
-         (((unsigned int)(n >> 50)) & 0x0000003e);
+  const unsigned int n = (unsigned int)num;
+  return (((n >> 6)) & 0x3f);
 }
 
 static __inline unsigned int
-get_SrcBDest_Y2(tile_bundle_bits num)
+get_SrcA_Y1(tilegx_bundle_bits n)
 {
-  const unsigned int n = (unsigned int)num;
-  return (((n >> 20)) & 0x3f);
+  return (((unsigned int)(n >> 37)) & 0x3f);
 }
 
 static __inline unsigned int
-get_SrcB_X0(tile_bundle_bits num)
+get_SrcA_Y2(tilegx_bundle_bits num)
 {
   const unsigned int n = (unsigned int)num;
-  return (((n >> 12)) & 0x3f);
+  return (((n >> 20)) & 0x3f);
 }
 
 static __inline unsigned int
-get_SrcB_X1(tile_bundle_bits n)
+get_SrcBDest_Y2(tilegx_bundle_bits n)
 {
-  return (((unsigned int)(n >> 43)) & 0x3f);
+  return (((unsigned int)(n >> 51)) & 0x3f);
 }
 
 static __inline unsigned int
-get_SrcB_Y0(tile_bundle_bits num)
+get_SrcB_X0(tilegx_bundle_bits num)
 {
   const unsigned int n = (unsigned int)num;
   return (((n >> 12)) & 0x3f);
 }
 
 static __inline unsigned int
-get_SrcB_Y1(tile_bundle_bits n)
+get_SrcB_X1(tilegx_bundle_bits n)
 {
   return (((unsigned int)(n >> 43)) & 0x3f);
 }
 
 static __inline unsigned int
-get_Src_SN(tile_bundle_bits num)
-{
-  const unsigned int n = (unsigned int)num;
-  return (((n >> 0)) & 0x3);
-}
-
-static __inline unsigned int
-get_UnOpcodeExtension_X0(tile_bundle_bits num)
-{
-  const unsigned int n = (unsigned int)num;
-  return (((n >> 12)) & 0x1f);
-}
-
-static __inline unsigned int
-get_UnOpcodeExtension_X1(tile_bundle_bits n)
-{
-  return (((unsigned int)(n >> 43)) & 0x1f);
-}
-
-static __inline unsigned int
-get_UnOpcodeExtension_Y0(tile_bundle_bits num)
+get_SrcB_Y0(tilegx_bundle_bits num)
 {
   const unsigned int n = (unsigned int)num;
-  return (((n >> 12)) & 0x1f);
+  return (((n >> 12)) & 0x3f);
 }
 
 static __inline unsigned int
-get_UnOpcodeExtension_Y1(tile_bundle_bits n)
+get_SrcB_Y1(tilegx_bundle_bits n)
 {
-  return (((unsigned int)(n >> 43)) & 0x1f);
+  return (((unsigned int)(n >> 43)) & 0x3f);
 }
 
 static __inline unsigned int
-get_UnShOpcodeExtension_X0(tile_bundle_bits num)
+get_UnaryOpcodeExtension_X0(tilegx_bundle_bits num)
 {
   const unsigned int n = (unsigned int)num;
-  return (((n >> 17)) & 0x3ff);
+  return (((n >> 12)) & 0x3f);
 }
 
 static __inline unsigned int
-get_UnShOpcodeExtension_X1(tile_bundle_bits n)
+get_UnaryOpcodeExtension_X1(tilegx_bundle_bits n)
 {
-  return (((unsigned int)(n >> 48)) & 0x3ff);
+  return (((unsigned int)(n >> 43)) & 0x3f);
 }
 
 static __inline unsigned int
-get_UnShOpcodeExtension_Y0(tile_bundle_bits num)
+get_UnaryOpcodeExtension_Y0(tilegx_bundle_bits num)
 {
   const unsigned int n = (unsigned int)num;
-  return (((n >> 17)) & 0x7);
+  return (((n >> 12)) & 0x3f);
 }
 
 static __inline unsigned int
-get_UnShOpcodeExtension_Y1(tile_bundle_bits n)
+get_UnaryOpcodeExtension_Y1(tilegx_bundle_bits n)
 {
-  return (((unsigned int)(n >> 48)) & 0x7);
+  return (((unsigned int)(n >> 43)) & 0x3f);
 }
 
 
@@ -874,546 +722,441 @@
 
 
 
-static __inline tile_bundle_bits
-create_BrOff_SN(int num)
+static __inline tilegx_bundle_bits
+create_BFEnd_X0(int num)
 {
   const unsigned int n = (unsigned int)num;
-  return ((n & 0x3ff) << 0);
+  return ((n & 0x3f) << 12);
 }
 
-static __inline tile_bundle_bits
-create_BrOff_X1(int num)
+static __inline tilegx_bundle_bits
+create_BFOpcodeExtension_X0(int num)
 {
   const unsigned int n = (unsigned int)num;
-  return (((tile_bundle_bits)(n & 0x00007fff)) << 43) |
-         (((tile_bundle_bits)(n & 0x00018000)) << 20);
+  return ((n & 0xf) << 24);
 }
 
-static __inline tile_bundle_bits
-create_BrType_X1(int num)
+static __inline tilegx_bundle_bits
+create_BFStart_X0(int num)
 {
   const unsigned int n = (unsigned int)num;
-  return (((tile_bundle_bits)(n & 0xf)) << 31);
+  return ((n & 0x3f) << 18);
 }
 
-static __inline tile_bundle_bits
-create_Dest_Imm8_X1(int num)
+static __inline tilegx_bundle_bits
+create_BrOff_X1(int num)
 {
   const unsigned int n = (unsigned int)num;
-  return (((tile_bundle_bits)(n & 0x0000003f)) << 31) |
-         (((tile_bundle_bits)(n & 0x000000c0)) << 43);
+  return (((tilegx_bundle_bits)(n & 0x0000003f)) << 31) |
+         (((tilegx_bundle_bits)(n & 0x0001ffc0)) << 37);
 }
 
-static __inline tile_bundle_bits
-create_Dest_SN(int num)
+static __inline tilegx_bundle_bits
+create_BrType_X1(int num)
 {
   const unsigned int n = (unsigned int)num;
-  return ((n & 0x3) << 2);
+  return (((tilegx_bundle_bits)(n & 0x1f)) << 54);
 }
 
-static __inline tile_bundle_bits
+static __inline tilegx_bundle_bits
+create_Dest_Imm8_X1(int num)
+{
+  const unsigned int n = (unsigned int)num;
+  return (((tilegx_bundle_bits)(n & 0x0000003f)) << 31) |
+         (((tilegx_bundle_bits)(n & 0x000000c0)) << 43);
+}
+
+static __inline tilegx_bundle_bits
 create_Dest_X0(int num)
 {
   const unsigned int n = (unsigned int)num;
   return ((n & 0x3f) << 0);
 }
 
-static __inline tile_bundle_bits
+static __inline tilegx_bundle_bits
 create_Dest_X1(int num)
 {
   const unsigned int n = (unsigned int)num;
-  return (((tile_bundle_bits)(n & 0x3f)) << 31);
+  return (((tilegx_bundle_bits)(n & 0x3f)) << 31);
 }
 
-static __inline tile_bundle_bits
+static __inline tilegx_bundle_bits
 create_Dest_Y0(int num)
 {
   const unsigned int n = (unsigned int)num;
   return ((n & 0x3f) << 0);
 }
 
-static __inline tile_bundle_bits
+static __inline tilegx_bundle_bits
 create_Dest_Y1(int num)
 {
   const unsigned int n = (unsigned int)num;
-  return (((tile_bundle_bits)(n & 0x3f)) << 31);
+  return (((tilegx_bundle_bits)(n & 0x3f)) << 31);
 }
 
-static __inline tile_bundle_bits
+static __inline tilegx_bundle_bits
 create_Imm16_X0(int num)
 {
   const unsigned int n = (unsigned int)num;
   return ((n & 0xffff) << 12);
 }
 
-static __inline tile_bundle_bits
+static __inline tilegx_bundle_bits
 create_Imm16_X1(int num)
 {
   const unsigned int n = (unsigned int)num;
-  return (((tile_bundle_bits)(n & 0xffff)) << 43);
+  return (((tilegx_bundle_bits)(n & 0xffff)) << 43);
 }
 
-static __inline tile_bundle_bits
-create_Imm8_SN(int num)
+static __inline tilegx_bundle_bits
+create_Imm8OpcodeExtension_X0(int num)
 {
   const unsigned int n = (unsigned int)num;
-  return ((n & 0xff) << 0);
+  return ((n & 0xff) << 20);
 }
 
-static __inline tile_bundle_bits
+static __inline tilegx_bundle_bits
+create_Imm8OpcodeExtension_X1(int num)
+{
+  const unsigned int n = (unsigned int)num;
+  return (((tilegx_bundle_bits)(n & 0xff)) << 51);
+}
+
+static __inline tilegx_bundle_bits
 create_Imm8_X0(int num)
 {
   const unsigned int n = (unsigned int)num;
   return ((n & 0xff) << 12);
 }
 
-static __inline tile_bundle_bits
+static __inline tilegx_bundle_bits
 create_Imm8_X1(int num)
 {
   const unsigned int n = (unsigned int)num;
-  return (((tile_bundle_bits)(n & 0xff)) << 43);
+  return (((tilegx_bundle_bits)(n & 0xff)) << 43);
 }
 
-static __inline tile_bundle_bits
+static __inline tilegx_bundle_bits
 create_Imm8_Y0(int num)
 {
   const unsigned int n = (unsigned int)num;
   return ((n & 0xff) << 12);
 }
 
-static __inline tile_bundle_bits
+static __inline tilegx_bundle_bits
 create_Imm8_Y1(int num)
 {
   const unsigned int n = (unsigned int)num;
-  return (((tile_bundle_bits)(n & 0xff)) << 43);
-}
-
-static __inline tile_bundle_bits
-create_ImmOpcodeExtension_X0(int num)
-{
-  const unsigned int n = (unsigned int)num;
-  return ((n & 0x7f) << 20);
-}
-
-static __inline tile_bundle_bits
-create_ImmOpcodeExtension_X1(int num)
-{
-  const unsigned int n = (unsigned int)num;
-  return (((tile_bundle_bits)(n & 0x7f)) << 51);
-}
-
-static __inline tile_bundle_bits
-create_ImmRROpcodeExtension_SN(int num)
-{
-  const unsigned int n = (unsigned int)num;
-  return ((n & 0x3) << 8);
-}
-
-static __inline tile_bundle_bits
-create_JOffLong_X1(int num)
-{
-  const unsigned int n = (unsigned int)num;
-  return (((tile_bundle_bits)(n & 0x00007fff)) << 43) |
-         (((tile_bundle_bits)(n & 0x00018000)) << 20) |
-         (((tile_bundle_bits)(n & 0x001e0000)) << 14) |
-         (((tile_bundle_bits)(n & 0x07e00000)) << 16) |
-         (((tile_bundle_bits)(n & 0x18000000)) << 31);
-}
-
-static __inline tile_bundle_bits
-create_JOff_X1(int num)
-{
-  const unsigned int n = (unsigned int)num;
-  return (((tile_bundle_bits)(n & 0x00007fff)) << 43) |
-         (((tile_bundle_bits)(n & 0x00018000)) << 20) |
-         (((tile_bundle_bits)(n & 0x001e0000)) << 14) |
-         (((tile_bundle_bits)(n & 0x07e00000)) << 16) |
-         (((tile_bundle_bits)(n & 0x08000000)) << 31);
-}
-
-static __inline tile_bundle_bits
-create_MF_Imm15_X1(int num)
-{
-  const unsigned int n = (unsigned int)num;
-  return (((tile_bundle_bits)(n & 0x00003fff)) << 37) |
-         (((tile_bundle_bits)(n & 0x00004000)) << 44);
-}
-
-static __inline tile_bundle_bits
-create_MMEnd_X0(int num)
-{
-  const unsigned int n = (unsigned int)num;
-  return ((n & 0x1f) << 18);
+  return (((tilegx_bundle_bits)(n & 0xff)) << 43);
 }
 
-static __inline tile_bundle_bits
-create_MMEnd_X1(int num)
+static __inline tilegx_bundle_bits
+create_JumpOff_X1(int num)
 {
   const unsigned int n = (unsigned int)num;
-  return (((tile_bundle_bits)(n & 0x1f)) << 49);
+  return (((tilegx_bundle_bits)(n & 0x7ffffff)) << 31);
 }
 
-static __inline tile_bundle_bits
-create_MMStart_X0(int num)
+static __inline tilegx_bundle_bits
+create_JumpOpcodeExtension_X1(int num)
 {
   const unsigned int n = (unsigned int)num;
-  return ((n & 0x1f) << 23);
+  return (((tilegx_bundle_bits)(n & 0x1)) << 58);
 }
 
-static __inline tile_bundle_bits
-create_MMStart_X1(int num)
+static __inline tilegx_bundle_bits
+create_MF_Imm14_X1(int num)
 {
   const unsigned int n = (unsigned int)num;
-  return (((tile_bundle_bits)(n & 0x1f)) << 54);
+  return (((tilegx_bundle_bits)(n & 0x3fff)) << 37);
 }
 
-static __inline tile_bundle_bits
-create_MT_Imm15_X1(int num)
+static __inline tilegx_bundle_bits
+create_MT_Imm14_X1(int num)
 {
   const unsigned int n = (unsigned int)num;
-  return (((tile_bundle_bits)(n & 0x0000003f)) << 31) |
-         (((tile_bundle_bits)(n & 0x00003fc0)) << 37) |
-         (((tile_bundle_bits)(n & 0x00004000)) << 44);
+  return (((tilegx_bundle_bits)(n & 0x0000003f)) << 31) |
+         (((tilegx_bundle_bits)(n & 0x00003fc0)) << 37);
 }
 
-static __inline tile_bundle_bits
+static __inline tilegx_bundle_bits
 create_Mode(int num)
 {
   const unsigned int n = (unsigned int)num;
-  return (((tile_bundle_bits)(n & 0x1)) << 63);
-}
-
-static __inline tile_bundle_bits
-create_NoRegOpcodeExtension_SN(int num)
-{
-  const unsigned int n = (unsigned int)num;
-  return ((n & 0xf) << 0);
-}
-
-static __inline tile_bundle_bits
-create_Opcode_SN(int num)
-{
-  const unsigned int n = (unsigned int)num;
-  return ((n & 0x3f) << 10);
+  return (((tilegx_bundle_bits)(n & 0x3)) << 62);
 }
 
-static __inline tile_bundle_bits
+static __inline tilegx_bundle_bits
 create_Opcode_X0(int num)
 {
   const unsigned int n = (unsigned int)num;
   return ((n & 0x7) << 28);
 }
 
-static __inline tile_bundle_bits
+static __inline tilegx_bundle_bits
 create_Opcode_X1(int num)
 {
   const unsigned int n = (unsigned int)num;
-  return (((tile_bundle_bits)(n & 0xf)) << 59);
+  return (((tilegx_bundle_bits)(n & 0x7)) << 59);
 }
 
-static __inline tile_bundle_bits
+static __inline tilegx_bundle_bits
 create_Opcode_Y0(int num)
 {
   const unsigned int n = (unsigned int)num;
   return ((n & 0xf) << 27);
 }
 
-static __inline tile_bundle_bits
+static __inline tilegx_bundle_bits
 create_Opcode_Y1(int num)
 {
   const unsigned int n = (unsigned int)num;
-  return (((tile_bundle_bits)(n & 0xf)) << 59);
+  return (((tilegx_bundle_bits)(n & 0xf)) << 58);
 }
 
-static __inline tile_bundle_bits
+static __inline tilegx_bundle_bits
 create_Opcode_Y2(int num)
 {
   const unsigned int n = (unsigned int)num;
-  return (((tile_bundle_bits)(n & 0x7)) << 56);
-}
-
-static __inline tile_bundle_bits
-create_RROpcodeExtension_SN(int num)
-{
-  const unsigned int n = (unsigned int)num;
-  return ((n & 0xf) << 4);
+  return ((n & 0x00000001) << 26) |
+         (((tilegx_bundle_bits)(n & 0x00000002)) << 56);
 }
 
-static __inline tile_bundle_bits
+static __inline tilegx_bundle_bits
 create_RRROpcodeExtension_X0(int num)
 {
   const unsigned int n = (unsigned int)num;
-  return ((n & 0x1ff) << 18);
+  return ((n & 0x3ff) << 18);
 }
 
-static __inline tile_bundle_bits
+static __inline tilegx_bundle_bits
 create_RRROpcodeExtension_X1(int num)
 {
   const unsigned int n = (unsigned int)num;
-  return (((tile_bundle_bits)(n & 0x1ff)) << 49);
+  return (((tilegx_bundle_bits)(n & 0x3ff)) << 49);
 }
 
-static __inline tile_bundle_bits
+static __inline tilegx_bundle_bits
 create_RRROpcodeExtension_Y0(int num)
 {
   const unsigned int n = (unsigned int)num;
   return ((n & 0x3) << 18);
 }
 
-static __inline tile_bundle_bits
+static __inline tilegx_bundle_bits
 create_RRROpcodeExtension_Y1(int num)
 {
   const unsigned int n = (unsigned int)num;
-  return (((tile_bundle_bits)(n & 0x3)) << 49);
+  return (((tilegx_bundle_bits)(n & 0x3)) << 49);
 }
 
-static __inline tile_bundle_bits
-create_RouteOpcodeExtension_SN(int num)
+static __inline tilegx_bundle_bits
+create_ShAmt_X0(int num)
 {
   const unsigned int n = (unsigned int)num;
-  return ((n & 0x3ff) << 0);
+  return ((n & 0x3f) << 12);
 }
 
-static __inline tile_bundle_bits
-create_S_X0(int num)
+static __inline tilegx_bundle_bits
+create_ShAmt_X1(int num)
 {
   const unsigned int n = (unsigned int)num;
-  return ((n & 0x1) << 27);
+  return (((tilegx_bundle_bits)(n & 0x3f)) << 43);
 }
 
-static __inline tile_bundle_bits
-create_S_X1(int num)
+static __inline tilegx_bundle_bits
+create_ShAmt_Y0(int num)
 {
   const unsigned int n = (unsigned int)num;
-  return (((tile_bundle_bits)(n & 0x1)) << 58);
+  return ((n & 0x3f) << 12);
 }
 
-static __inline tile_bundle_bits
-create_ShAmt_X0(int num)
+static __inline tilegx_bundle_bits
+create_ShAmt_Y1(int num)
 {
   const unsigned int n = (unsigned int)num;
-  return ((n & 0x1f) << 12);
+  return (((tilegx_bundle_bits)(n & 0x3f)) << 43);
 }
 
-static __inline tile_bundle_bits
-create_ShAmt_X1(int num)
+static __inline tilegx_bundle_bits
+create_ShiftOpcodeExtension_X0(int num)
 {
   const unsigned int n = (unsigned int)num;
-  return (((tile_bundle_bits)(n & 0x1f)) << 43);
+  return ((n & 0x3ff) << 18);
 }
 
-static __inline tile_bundle_bits
-create_ShAmt_Y0(int num)
+static __inline tilegx_bundle_bits
+create_ShiftOpcodeExtension_X1(int num)
 {
   const unsigned int n = (unsigned int)num;
-  return ((n & 0x1f) << 12);
+  return (((tilegx_bundle_bits)(n & 0x3ff)) << 49);
 }
 
-static __inline tile_bundle_bits
-create_ShAmt_Y1(int num)
+static __inline tilegx_bundle_bits
+create_ShiftOpcodeExtension_Y0(int num)
 {
   const unsigned int n = (unsigned int)num;
-  return (((tile_bundle_bits)(n & 0x1f)) << 43);
+  return ((n & 0x3) << 18);
 }
 
-static __inline tile_bundle_bits
+static __inline tilegx_bundle_bits
+create_ShiftOpcodeExtension_Y1(int num)
+{
+  const unsigned int n = (unsigned int)num;
+  return (((tilegx_bundle_bits)(n & 0x3)) << 49);
+}
+
+static __inline tilegx_bundle_bits
 create_SrcA_X0(int num)
 {
   const unsigned int n = (unsigned int)num;
   return ((n & 0x3f) << 6);
 }
 
-static __inline tile_bundle_bits
+static __inline tilegx_bundle_bits
 create_SrcA_X1(int num)
 {
   const unsigned int n = (unsigned int)num;
-  return (((tile_bundle_bits)(n & 0x3f)) << 37);
+  return (((tilegx_bundle_bits)(n & 0x3f)) << 37);
 }
 
-static __inline tile_bundle_bits
+static __inline tilegx_bundle_bits
 create_SrcA_Y0(int num)
 {
   const unsigned int n = (unsigned int)num;
   return ((n & 0x3f) << 6);
 }
 
-static __inline tile_bundle_bits
+static __inline tilegx_bundle_bits
 create_SrcA_Y1(int num)
 {
   const unsigned int n = (unsigned int)num;
-  return (((tile_bundle_bits)(n & 0x3f)) << 37);
+  return (((tilegx_bundle_bits)(n & 0x3f)) << 37);
 }
 
-static __inline tile_bundle_bits
+static __inline tilegx_bundle_bits
 create_SrcA_Y2(int num)
 {
   const unsigned int n = (unsigned int)num;
-  return ((n & 0x00000001) << 26) |
-         (((tile_bundle_bits)(n & 0x0000003e)) << 50);
+  return ((n & 0x3f) << 20);
 }
 
-static __inline tile_bundle_bits
+static __inline tilegx_bundle_bits
 create_SrcBDest_Y2(int num)
 {
   const unsigned int n = (unsigned int)num;
-  return ((n & 0x3f) << 20);
+  return (((tilegx_bundle_bits)(n & 0x3f)) << 51);
 }
 
-static __inline tile_bundle_bits
+static __inline tilegx_bundle_bits
 create_SrcB_X0(int num)
 {
   const unsigned int n = (unsigned int)num;
   return ((n & 0x3f) << 12);
 }
 
-static __inline tile_bundle_bits
+static __inline tilegx_bundle_bits
 create_SrcB_X1(int num)
 {
   const unsigned int n = (unsigned int)num;
-  return (((tile_bundle_bits)(n & 0x3f)) << 43);
+  return (((tilegx_bundle_bits)(n & 0x3f)) << 43);
 }
 
-static __inline tile_bundle_bits
+static __inline tilegx_bundle_bits
 create_SrcB_Y0(int num)
 {
   const unsigned int n = (unsigned int)num;
   return ((n & 0x3f) << 12);
 }
 
-static __inline tile_bundle_bits
+static __inline tilegx_bundle_bits
 create_SrcB_Y1(int num)
 {
   const unsigned int n = (unsigned int)num;
-  return (((tile_bundle_bits)(n & 0x3f)) << 43);
-}
-
-static __inline tile_bundle_bits
-create_Src_SN(int num)
-{
-  const unsigned int n = (unsigned int)num;
-  return ((n & 0x3) << 0);
-}
-
-static __inline tile_bundle_bits
-create_UnOpcodeExtension_X0(int num)
-{
-  const unsigned int n = (unsigned int)num;
-  return ((n & 0x1f) << 12);
-}
-
-static __inline tile_bundle_bits
-create_UnOpcodeExtension_X1(int num)
-{
-  const unsigned int n = (unsigned int)num;
-  return (((tile_bundle_bits)(n & 0x1f)) << 43);
-}
-
-static __inline tile_bundle_bits
-create_UnOpcodeExtension_Y0(int num)
-{
-  const unsigned int n = (unsigned int)num;
-  return ((n & 0x1f) << 12);
-}
-
-static __inline tile_bundle_bits
-create_UnOpcodeExtension_Y1(int num)
-{
-  const unsigned int n = (unsigned int)num;
-  return (((tile_bundle_bits)(n & 0x1f)) << 43);
+  return (((tilegx_bundle_bits)(n & 0x3f)) << 43);
 }
 
-static __inline tile_bundle_bits
-create_UnShOpcodeExtension_X0(int num)
+static __inline tilegx_bundle_bits
+create_UnaryOpcodeExtension_X0(int num)
 {
   const unsigned int n = (unsigned int)num;
-  return ((n & 0x3ff) << 17);
+  return ((n & 0x3f) << 12);
 }
 
-static __inline tile_bundle_bits
-create_UnShOpcodeExtension_X1(int num)
+static __inline tilegx_bundle_bits
+create_UnaryOpcodeExtension_X1(int num)
 {
   const unsigned int n = (unsigned int)num;
-  return (((tile_bundle_bits)(n & 0x3ff)) << 48);
+  return (((tilegx_bundle_bits)(n & 0x3f)) << 43);
 }
 
-static __inline tile_bundle_bits
-create_UnShOpcodeExtension_Y0(int num)
+static __inline tilegx_bundle_bits
+create_UnaryOpcodeExtension_Y0(int num)
 {
   const unsigned int n = (unsigned int)num;
-  return ((n & 0x7) << 17);
+  return ((n & 0x3f) << 12);
 }
 
-static __inline tile_bundle_bits
-create_UnShOpcodeExtension_Y1(int num)
+static __inline tilegx_bundle_bits
+create_UnaryOpcodeExtension_Y1(int num)
 {
   const unsigned int n = (unsigned int)num;
-  return (((tile_bundle_bits)(n & 0x7)) << 48);
+  return (((tilegx_bundle_bits)(n & 0x3f)) << 43);
 }
 
 
-
 typedef enum
 {
-  TILE_PIPELINE_X0,
-  TILE_PIPELINE_X1,
-  TILE_PIPELINE_Y0,
-  TILE_PIPELINE_Y1,
-  TILE_PIPELINE_Y2,
-} tile_pipeline;
+  TILEGX_PIPELINE_X0,
+  TILEGX_PIPELINE_X1,
+  TILEGX_PIPELINE_Y0,
+  TILEGX_PIPELINE_Y1,
+  TILEGX_PIPELINE_Y2,
+} tilegx_pipeline;
 
-#define tile_is_x_pipeline(p) ((int)(p) <= (int)TILE_PIPELINE_X1)
+#define tilegx_is_x_pipeline(p) ((int)(p) <= (int)TILEGX_PIPELINE_X1)
 
 typedef enum
 {
-  TILE_OP_TYPE_REGISTER,
-  TILE_OP_TYPE_IMMEDIATE,
-  TILE_OP_TYPE_ADDRESS,
-  TILE_OP_TYPE_SPR
-} tile_operand_type;
+  TILEGX_OP_TYPE_REGISTER,
+  TILEGX_OP_TYPE_IMMEDIATE,
+  TILEGX_OP_TYPE_ADDRESS,
+  TILEGX_OP_TYPE_SPR
+} tilegx_operand_type;
 
-/* This is the bit that determines if a bundle is in the Y encoding. */
-#define TILE_BUNDLE_Y_ENCODING_MASK ((tile_bundle_bits)1 << 63)
+/* These are the bits that determine if a bundle is in the X encoding. */
+#define TILEGX_BUNDLE_MODE_MASK ((tilegx_bundle_bits)3 << 62)
 
 enum
 {
   /* Maximum number of instructions in a bundle (2 for X, 3 for Y). */
-  TILE_MAX_INSTRUCTIONS_PER_BUNDLE = 3,
+  TILEGX_MAX_INSTRUCTIONS_PER_BUNDLE = 3,
 
   /* How many different pipeline encodings are there? X0, X1, Y0, Y1, Y2. */
-  TILE_NUM_PIPELINE_ENCODINGS = 5,
+  TILEGX_NUM_PIPELINE_ENCODINGS = 5,
 
-  /* Log base 2 of TILE_BUNDLE_SIZE_IN_BYTES. */
-  TILE_LOG2_BUNDLE_SIZE_IN_BYTES = 3,
+  /* Log base 2 of TILEGX_BUNDLE_SIZE_IN_BYTES. */
+  TILEGX_LOG2_BUNDLE_SIZE_IN_BYTES = 3,
 
   /* Instructions take this many bytes. */
-  TILE_BUNDLE_SIZE_IN_BYTES = 1 << TILE_LOG2_BUNDLE_SIZE_IN_BYTES,
+  TILEGX_BUNDLE_SIZE_IN_BYTES = 1 << TILEGX_LOG2_BUNDLE_SIZE_IN_BYTES,
 
-  /* Log base 2 of TILE_BUNDLE_ALIGNMENT_IN_BYTES. */
-  TILE_LOG2_BUNDLE_ALIGNMENT_IN_BYTES = 3,
+  /* Log base 2 of TILEGX_BUNDLE_ALIGNMENT_IN_BYTES. */
+  TILEGX_LOG2_BUNDLE_ALIGNMENT_IN_BYTES = 3,
 
   /* Bundles should be aligned modulo this number of bytes. */
-  TILE_BUNDLE_ALIGNMENT_IN_BYTES =
-    (1 << TILE_LOG2_BUNDLE_ALIGNMENT_IN_BYTES),
-
-  /* Log base 2 of TILE_SN_INSTRUCTION_SIZE_IN_BYTES. */
-  TILE_LOG2_SN_INSTRUCTION_SIZE_IN_BYTES = 1,
-
-  /* Static network instructions take this many bytes. */
-  TILE_SN_INSTRUCTION_SIZE_IN_BYTES =
-    (1 << TILE_LOG2_SN_INSTRUCTION_SIZE_IN_BYTES),
+  TILEGX_BUNDLE_ALIGNMENT_IN_BYTES =
+    (1 << TILEGX_LOG2_BUNDLE_ALIGNMENT_IN_BYTES),
 
   /* Number of registers (some are magic, such as network I/O). */
-  TILE_NUM_REGISTERS = 64,
-
-  /* Number of static network registers. */
-  TILE_NUM_SN_REGISTERS = 4
+  TILEGX_NUM_REGISTERS = 64,
 };
 
 
-struct tile_operand
+struct tilegx_operand
 {
   /* Is this operand a register, immediate or address? */
-  tile_operand_type type;
+  tilegx_operand_type type;
 
   /* The default relocation type for this operand.  */
   signed int default_reloc : 16;
@@ -1437,27 +1180,27 @@
   unsigned int rightshift : 2;
 
   /* Return the bits for this operand to be ORed into an existing bundle. */
-  tile_bundle_bits (*insert) (int op);
+  tilegx_bundle_bits (*insert) (int op);
 
   /* Extract this operand and return it. */
-  unsigned int (*extract) (tile_bundle_bits bundle);
+  unsigned int (*extract) (tilegx_bundle_bits bundle);
 };
 
 
-extern const struct tile_operand tile_operands[];
+extern const struct tilegx_operand tilegx_operands[];
 
 /* One finite-state machine per pipe for rapid instruction decoding. */
 extern const unsigned short * const
-tile_bundle_decoder_fsms[TILE_NUM_PIPELINE_ENCODINGS];
+tilegx_bundle_decoder_fsms[TILEGX_NUM_PIPELINE_ENCODINGS];
 
 
-struct tile_opcode
+struct tilegx_opcode
 {
   /* The opcode mnemonic, e.g. "add" */
   const char *name;
 
   /* The enum value for this mnemonic. */
-  tile_mnemonic mnemonic;
+  tilegx_mnemonic mnemonic;
 
   /* A bit mask of which of the five pipes this instruction
      is compatible with:
@@ -1478,29 +1221,28 @@
   unsigned char can_bundle;
 
   /* The description of the operands. Each of these is an
-   * index into the tile_operands[] table. */
-  unsigned char operands[TILE_NUM_PIPELINE_ENCODINGS][TILE_MAX_OPERANDS];
+   * index into the tilegx_operands[] table. */
+  unsigned char operands[TILEGX_NUM_PIPELINE_ENCODINGS][TILEGX_MAX_OPERANDS];
 
 };
 
-extern const struct tile_opcode tile_opcodes[];
-
+extern const struct tilegx_opcode tilegx_opcodes[];
 
 /* Used for non-textual disassembly into structs. */
-struct tile_decoded_instruction
+struct tilegx_decoded_instruction
 {
-  const struct tile_opcode *opcode;
-  const struct tile_operand *operands[TILE_MAX_OPERANDS];
-  int operand_values[TILE_MAX_OPERANDS];
+  const struct tilegx_opcode *opcode;
+  const struct tilegx_operand *operands[TILEGX_MAX_OPERANDS];
+  long long operand_values[TILEGX_MAX_OPERANDS];
 };
 
 
 /* Disassemble a bundle into a struct for machine processing. */
-extern int parse_insn_tile(tile_bundle_bits bits,
-                           unsigned int pc,
-                           struct tile_decoded_instruction
-                           decoded[TILE_MAX_INSTRUCTIONS_PER_BUNDLE]);
+extern int parse_insn_tilegx(tilegx_bundle_bits bits,
+                             unsigned long long pc,
+                             struct tilegx_decoded_instruction
+                             decoded[TILEGX_MAX_INSTRUCTIONS_PER_BUNDLE]);
 
 
 
-#endif /* opcode_tile_h */
+#endif /* opcode_tilegx_h */
diff -druN linux-2.6.39-libre/arch/tile/include/asm/page.h linux-3.0-rc7-libre/arch/tile/include/asm/page.h
--- linux-2.6.39-libre/arch/tile/include/asm/page.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/tile/include/asm/page.h	2011-07-11 19:51:52.000000000 -0400
@@ -16,7 +16,8 @@
 #define _ASM_TILE_PAGE_H
 
 #include <linux/const.h>
-#include <hv/pagesize.h>
+#include <hv/hypervisor.h>
+#include <arch/chip.h>
 
 /* PAGE_SHIFT and HPAGE_SHIFT determine the page sizes. */
 #define PAGE_SHIFT	HV_LOG2_PAGE_SIZE_SMALL
@@ -28,8 +29,6 @@
 #define PAGE_MASK	(~(PAGE_SIZE - 1))
 #define HPAGE_MASK	(~(HPAGE_SIZE - 1))
 
-#ifdef __KERNEL__
-
 /*
  * If the Kconfig doesn't specify, set a maximum zone order that
  * is enough so that we can create huge pages from small pages given
@@ -39,9 +38,6 @@
 #define CONFIG_FORCE_MAX_ZONEORDER (HPAGE_SHIFT - PAGE_SHIFT + 1)
 #endif
 
-#include <hv/hypervisor.h>
-#include <arch/chip.h>
-
 #ifndef __ASSEMBLY__
 
 #include <linux/types.h>
@@ -91,6 +87,10 @@
 /* Must be a macro since it is used to create constants. */
 #define __pgprot(val) hv_pte(val)
 
+/* Rarely-used initializers, typically with a "zero" value. */
+#define __pte(x) hv_pte(x)
+#define __pgd(x) hv_pte(x)
+
 static inline u64 pgprot_val(pgprot_t pgprot)
 {
 	return hv_pte_val(pgprot);
@@ -110,6 +110,8 @@
 
 typedef HV_PTE pmd_t;
 
+#define __pmd(x) hv_pte(x)
+
 static inline u64 pmd_val(pmd_t pmd)
 {
 	return hv_pte_val(pmd);
@@ -318,7 +320,7 @@
 
 /* Provide as macros since these require some other headers included. */
 #define page_to_pa(page) ((phys_addr_t)(page_to_pfn(page)) << PAGE_SHIFT)
-#define virt_to_page(kaddr) pfn_to_page(kaddr_to_pfn(kaddr))
+#define virt_to_page(kaddr) pfn_to_page(kaddr_to_pfn((void *)(kaddr)))
 #define page_to_virt(page) pfn_to_kaddr(page_to_pfn(page))
 
 struct mm_struct;
@@ -331,6 +333,4 @@
 
 #include <asm-generic/memory_model.h>
 
-#endif /* __KERNEL__ */
-
 #endif /* _ASM_TILE_PAGE_H */
diff -druN linux-2.6.39-libre/arch/tile/include/asm/parport.h linux-3.0-rc7-libre/arch/tile/include/asm/parport.h
--- linux-2.6.39-libre/arch/tile/include/asm/parport.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/tile/include/asm/parport.h	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1 @@
+#include <asm-generic/parport.h>
diff -druN linux-2.6.39-libre/arch/tile/include/asm/pci.h linux-3.0-rc7-libre/arch/tile/include/asm/pci.h
--- linux-2.6.39-libre/arch/tile/include/asm/pci.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/tile/include/asm/pci.h	2011-07-11 19:51:52.000000000 -0400
@@ -46,7 +46,8 @@
  */
 #define PCI_DMA_BUS_IS_PHYS     1
 
-int __init tile_pci_init(void);
+int __devinit tile_pci_init(void);
+int __devinit pcibios_init(void);
 
 void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long max);
 static inline void pci_iounmap(struct pci_dev *dev, void __iomem *addr) {}
diff -druN linux-2.6.39-libre/arch/tile/include/asm/pgtable_64.h linux-3.0-rc7-libre/arch/tile/include/asm/pgtable_64.h
--- linux-2.6.39-libre/arch/tile/include/asm/pgtable_64.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/tile/include/asm/pgtable_64.h	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,175 @@
+/*
+ * Copyright 2011 Tilera 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, version 2.
+ *
+ *   This program is distributed in the hope that it will be useful, but
+ *   WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
+ *   NON INFRINGEMENT.  See the GNU General Public License for
+ *   more details.
+ *
+ */
+
+#ifndef _ASM_TILE_PGTABLE_64_H
+#define _ASM_TILE_PGTABLE_64_H
+
+/* The level-0 page table breaks the address space into 32-bit chunks. */
+#define PGDIR_SHIFT	HV_LOG2_L1_SPAN
+#define PGDIR_SIZE	HV_L1_SPAN
+#define PGDIR_MASK	(~(PGDIR_SIZE-1))
+#define PTRS_PER_PGD	HV_L0_ENTRIES
+#define SIZEOF_PGD	(PTRS_PER_PGD * sizeof(pgd_t))
+
+/*
+ * The level-1 index is defined by the huge page size.  A PMD is composed
+ * of PTRS_PER_PMD pgd_t's and is the middle level of the page table.
+ */
+#define PMD_SHIFT	HV_LOG2_PAGE_SIZE_LARGE
+#define PMD_SIZE	HV_PAGE_SIZE_LARGE
+#define PMD_MASK	(~(PMD_SIZE-1))
+#define PTRS_PER_PMD	(1 << (PGDIR_SHIFT - PMD_SHIFT))
+#define SIZEOF_PMD	(PTRS_PER_PMD * sizeof(pmd_t))
+
+/*
+ * The level-2 index is defined by the difference between the huge
+ * page size and the normal page size.  A PTE is composed of
+ * PTRS_PER_PTE pte_t's and is the bottom level of the page table.
+ * Note that the hypervisor docs use PTE for what we call pte_t, so
+ * this nomenclature is somewhat confusing.
+ */
+#define PTRS_PER_PTE (1 << (HV_LOG2_PAGE_SIZE_LARGE - HV_LOG2_PAGE_SIZE_SMALL))
+#define SIZEOF_PTE	(PTRS_PER_PTE * sizeof(pte_t))
+
+/*
+ * Align the vmalloc area to an L2 page table, and leave a guard page
+ * at the beginning and end.  The vmalloc code also puts in an internal
+ * guard page between each allocation.
+ */
+#define _VMALLOC_END	HUGE_VMAP_BASE
+#define VMALLOC_END	(_VMALLOC_END - PAGE_SIZE)
+#define VMALLOC_START	(_VMALLOC_START + PAGE_SIZE)
+
+#define HUGE_VMAP_END	(HUGE_VMAP_BASE + PGDIR_SIZE)
+
+#ifndef __ASSEMBLY__
+
+/* We have no pud since we are a three-level page table. */
+#include <asm-generic/pgtable-nopud.h>
+
+static inline int pud_none(pud_t pud)
+{
+	return pud_val(pud) == 0;
+}
+
+static inline int pud_present(pud_t pud)
+{
+	return pud_val(pud) & _PAGE_PRESENT;
+}
+
+#define pmd_ERROR(e) \
+	pr_err("%s:%d: bad pmd 0x%016llx.\n", __FILE__, __LINE__, pmd_val(e))
+
+static inline void pud_clear(pud_t *pudp)
+{
+	__pte_clear(&pudp->pgd);
+}
+
+static inline int pud_bad(pud_t pud)
+{
+	return ((pud_val(pud) & _PAGE_ALL) != _PAGE_TABLE);
+}
+
+/* Return the page-table frame number (ptfn) that a pud_t points at. */
+#define pud_ptfn(pud) hv_pte_get_ptfn((pud).pgd)
+
+/*
+ * A given kernel pud_t maps to a kernel pmd_t table at a specific
+ * virtual address.  Since kernel pmd_t tables can be aligned at
+ * sub-page granularity, this macro can return non-page-aligned
+ * pointers, despite its name.
+ */
+#define pud_page_vaddr(pud) \
+	(__va((phys_addr_t)pud_ptfn(pud) << HV_LOG2_PAGE_TABLE_ALIGN))
+
+/*
+ * A pud_t points to a pmd_t array.  Since we can have multiple per
+ * page, we don't have a one-to-one mapping of pud_t's to pages.
+ */
+#define pud_page(pud) pfn_to_page(HV_PTFN_TO_PFN(pud_ptfn(pud)))
+
+static inline unsigned long pud_index(unsigned long address)
+{
+	return (address >> PUD_SHIFT) & (PTRS_PER_PUD - 1);
+}
+
+#define pmd_offset(pud, address) \
+	((pmd_t *)pud_page_vaddr(*(pud)) + pmd_index(address))
+
+static inline void __set_pmd(pmd_t *pmdp, pmd_t pmdval)
+{
+	set_pte(pmdp, pmdval);
+}
+
+/* Create a pmd from a PTFN and pgprot. */
+static inline pmd_t ptfn_pmd(unsigned long ptfn, pgprot_t prot)
+{
+	return hv_pte_set_ptfn(prot, ptfn);
+}
+
+/* Return the page-table frame number (ptfn) that a pmd_t points at. */
+static inline unsigned long pmd_ptfn(pmd_t pmd)
+{
+	return hv_pte_get_ptfn(pmd);
+}
+
+static inline void pmd_clear(pmd_t *pmdp)
+{
+	__pte_clear(pmdp);
+}
+
+/* Normalize an address to having the correct high bits set. */
+#define pgd_addr_normalize pgd_addr_normalize
+static inline unsigned long pgd_addr_normalize(unsigned long addr)
+{
+	return ((long)addr << (CHIP_WORD_SIZE() - CHIP_VA_WIDTH())) >>
+		(CHIP_WORD_SIZE() - CHIP_VA_WIDTH());
+}
+
+/* We don't define any pgds for these addresses. */
+static inline int pgd_addr_invalid(unsigned long addr)
+{
+	return addr >= MEM_HV_START ||
+		(addr > MEM_LOW_END && addr < MEM_HIGH_START);
+}
+
+/*
+ * Use atomic instructions to provide atomicity against the hypervisor.
+ */
+#define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_YOUNG
+static inline int ptep_test_and_clear_young(struct vm_area_struct *vma,
+					    unsigned long addr, pte_t *ptep)
+{
+	return (__insn_fetchand(&ptep->val, ~HV_PTE_ACCESSED) >>
+		HV_PTE_INDEX_ACCESSED) & 0x1;
+}
+
+#define __HAVE_ARCH_PTEP_SET_WRPROTECT
+static inline void ptep_set_wrprotect(struct mm_struct *mm,
+				      unsigned long addr, pte_t *ptep)
+{
+	__insn_fetchand(&ptep->val, ~HV_PTE_WRITABLE);
+}
+
+#define __HAVE_ARCH_PTEP_GET_AND_CLEAR
+static inline pte_t ptep_get_and_clear(struct mm_struct *mm,
+				       unsigned long addr, pte_t *ptep)
+{
+	return hv_pte(__insn_exch(&ptep->val, 0UL));
+}
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* _ASM_TILE_PGTABLE_64_H */
diff -druN linux-2.6.39-libre/arch/tile/include/asm/processor.h linux-3.0-rc7-libre/arch/tile/include/asm/processor.h
--- linux-2.6.39-libre/arch/tile/include/asm/processor.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/tile/include/asm/processor.h	2011-07-11 19:51:52.000000000 -0400
@@ -215,6 +215,8 @@
 
 extern int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags);
 
+extern int do_work_pending(struct pt_regs *regs, u32 flags);
+
 
 /*
  * Return saved (kernel) PC of a blocked thread.
@@ -255,10 +257,6 @@
 	barrier();
 }
 
-struct siginfo;
-extern void arch_coredump_signal(struct siginfo *, struct pt_regs *);
-#define arch_coredump_signal arch_coredump_signal
-
 /* Info on this processor (see fs/proc/cpuinfo.c) */
 struct seq_operations;
 extern const struct seq_operations cpuinfo_op;
@@ -269,9 +267,6 @@
 /* Data on which physical memory controller corresponds to which NUMA node. */
 extern int node_controller[];
 
-/* Do we dump information to the console when a user application crashes? */
-extern int show_crashinfo;
-
 #if CHIP_HAS_CBOX_HOME_MAP()
 /* Does the heap allocator return hash-for-home pages by default? */
 extern int hash_default;
diff -druN linux-2.6.39-libre/arch/tile/include/asm/serial.h linux-3.0-rc7-libre/arch/tile/include/asm/serial.h
--- linux-2.6.39-libre/arch/tile/include/asm/serial.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/tile/include/asm/serial.h	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1 @@
+#include <asm-generic/serial.h>
diff -druN linux-2.6.39-libre/arch/tile/include/asm/signal.h linux-3.0-rc7-libre/arch/tile/include/asm/signal.h
--- linux-2.6.39-libre/arch/tile/include/asm/signal.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/tile/include/asm/signal.h	2011-07-11 19:51:52.000000000 -0400
@@ -28,6 +28,10 @@
 int restore_sigcontext(struct pt_regs *, struct sigcontext __user *);
 int setup_sigcontext(struct sigcontext __user *, struct pt_regs *);
 void do_signal(struct pt_regs *regs);
+void signal_fault(const char *type, struct pt_regs *,
+		  void __user *frame, int sig);
+void trace_unhandled_signal(const char *type, struct pt_regs *regs,
+			    unsigned long address, int signo);
 #endif
 
 #endif /* _ASM_TILE_SIGNAL_H */
diff -druN linux-2.6.39-libre/arch/tile/include/asm/spinlock_64.h linux-3.0-rc7-libre/arch/tile/include/asm/spinlock_64.h
--- linux-2.6.39-libre/arch/tile/include/asm/spinlock_64.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/tile/include/asm/spinlock_64.h	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,161 @@
+/*
+ * Copyright 2011 Tilera 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, version 2.
+ *
+ *   This program is distributed in the hope that it will be useful, but
+ *   WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
+ *   NON INFRINGEMENT.  See the GNU General Public License for
+ *   more details.
+ *
+ * 64-bit SMP ticket spinlocks, allowing only a single CPU anywhere
+ * (the type definitions are in asm/spinlock_types.h)
+ */
+
+#ifndef _ASM_TILE_SPINLOCK_64_H
+#define _ASM_TILE_SPINLOCK_64_H
+
+/* Shifts and masks for the various fields in "lock". */
+#define __ARCH_SPIN_CURRENT_SHIFT	17
+#define __ARCH_SPIN_NEXT_MASK		0x7fff
+#define __ARCH_SPIN_NEXT_OVERFLOW	0x8000
+
+/*
+ * Return the "current" portion of a ticket lock value,
+ * i.e. the number that currently owns the lock.
+ */
+static inline int arch_spin_current(u32 val)
+{
+	return val >> __ARCH_SPIN_CURRENT_SHIFT;
+}
+
+/*
+ * Return the "next" portion of a ticket lock value,
+ * i.e. the number that the next task to try to acquire the lock will get.
+ */
+static inline int arch_spin_next(u32 val)
+{
+	return val & __ARCH_SPIN_NEXT_MASK;
+}
+
+/* The lock is locked if a task would have to wait to get it. */
+static inline int arch_spin_is_locked(arch_spinlock_t *lock)
+{
+	u32 val = lock->lock;
+	return arch_spin_current(val) != arch_spin_next(val);
+}
+
+/* Bump the current ticket so the next task owns the lock. */
+static inline void arch_spin_unlock(arch_spinlock_t *lock)
+{
+	wmb();  /* guarantee anything modified under the lock is visible */
+	__insn_fetchadd4(&lock->lock, 1U << __ARCH_SPIN_CURRENT_SHIFT);
+}
+
+void arch_spin_unlock_wait(arch_spinlock_t *lock);
+
+void arch_spin_lock_slow(arch_spinlock_t *lock, u32 val);
+
+/* Grab the "next" ticket number and bump it atomically.
+ * If the current ticket is not ours, go to the slow path.
+ * We also take the slow path if the "next" value overflows.
+ */
+static inline void arch_spin_lock(arch_spinlock_t *lock)
+{
+	u32 val = __insn_fetchadd4(&lock->lock, 1);
+	u32 ticket = val & (__ARCH_SPIN_NEXT_MASK | __ARCH_SPIN_NEXT_OVERFLOW);
+	if (unlikely(arch_spin_current(val) != ticket))
+		arch_spin_lock_slow(lock, ticket);
+}
+
+/* Try to get the lock, and return whether we succeeded. */
+int arch_spin_trylock(arch_spinlock_t *lock);
+
+/* We cannot take an interrupt after getting a ticket, so don't enable them. */
+#define arch_spin_lock_flags(lock, flags) arch_spin_lock(lock)
+
+/*
+ * Read-write spinlocks, allowing multiple readers
+ * but only one writer.
+ *
+ * We use fetchadd() for readers, and fetchor() with the sign bit
+ * for writers.
+ */
+
+#define __WRITE_LOCK_BIT (1 << 31)
+
+static inline int arch_write_val_locked(int val)
+{
+	return val < 0;  /* Optimize "val & __WRITE_LOCK_BIT". */
+}
+
+/**
+ * read_can_lock - would read_trylock() succeed?
+ * @lock: the rwlock in question.
+ */
+static inline int arch_read_can_lock(arch_rwlock_t *rw)
+{
+	return !arch_write_val_locked(rw->lock);
+}
+
+/**
+ * write_can_lock - would write_trylock() succeed?
+ * @lock: the rwlock in question.
+ */
+static inline int arch_write_can_lock(arch_rwlock_t *rw)
+{
+	return rw->lock == 0;
+}
+
+extern void __read_lock_failed(arch_rwlock_t *rw);
+
+static inline void arch_read_lock(arch_rwlock_t *rw)
+{
+	u32 val = __insn_fetchaddgez4(&rw->lock, 1);
+	if (unlikely(arch_write_val_locked(val)))
+		__read_lock_failed(rw);
+}
+
+extern void __write_lock_failed(arch_rwlock_t *rw, u32 val);
+
+static inline void arch_write_lock(arch_rwlock_t *rw)
+{
+	u32 val = __insn_fetchor4(&rw->lock, __WRITE_LOCK_BIT);
+	if (unlikely(val != 0))
+		__write_lock_failed(rw, val);
+}
+
+static inline void arch_read_unlock(arch_rwlock_t *rw)
+{
+	__insn_mf();
+	__insn_fetchadd4(&rw->lock, -1);
+}
+
+static inline void arch_write_unlock(arch_rwlock_t *rw)
+{
+	__insn_mf();
+	rw->lock = 0;
+}
+
+static inline int arch_read_trylock(arch_rwlock_t *rw)
+{
+	return !arch_write_val_locked(__insn_fetchaddgez4(&rw->lock, 1));
+}
+
+static inline int arch_write_trylock(arch_rwlock_t *rw)
+{
+	u32 val = __insn_fetchor4(&rw->lock, __WRITE_LOCK_BIT);
+	if (likely(val == 0))
+		return 1;
+	if (!arch_write_val_locked(val))
+		__insn_fetchand4(&rw->lock, ~__WRITE_LOCK_BIT);
+	return 0;
+}
+
+#define arch_read_lock_flags(lock, flags) arch_read_lock(lock)
+#define arch_write_lock_flags(lock, flags) arch_write_lock(lock)
+
+#endif /* _ASM_TILE_SPINLOCK_64_H */
diff -druN linux-2.6.39-libre/arch/tile/include/asm/stat.h linux-3.0-rc7-libre/arch/tile/include/asm/stat.h
--- linux-2.6.39-libre/arch/tile/include/asm/stat.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/tile/include/asm/stat.h	2011-07-11 19:51:52.000000000 -0400
@@ -1,4 +1,4 @@
-#ifdef CONFIG_COMPAT
+#if defined(__KERNEL__) && defined(CONFIG_COMPAT)
 #define __ARCH_WANT_STAT64	/* Used for compat_sys_stat64() etc. */
 #endif
 #include <asm-generic/stat.h>
diff -druN linux-2.6.39-libre/arch/tile/include/asm/swab.h linux-3.0-rc7-libre/arch/tile/include/asm/swab.h
--- linux-2.6.39-libre/arch/tile/include/asm/swab.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/tile/include/asm/swab.h	2011-07-11 19:51:52.000000000 -0400
@@ -18,12 +18,6 @@
 /* Tile gcc is always >= 4.3.0, so we use __builtin_bswap. */
 #define __arch_swab32(x) __builtin_bswap32(x)
 #define __arch_swab64(x) __builtin_bswap64(x)
-
-/* Use the variant that is natural for the wordsize. */
-#ifdef CONFIG_64BIT
-#define __arch_swab16(x) (__builtin_bswap64(x) >> 48)
-#else
 #define __arch_swab16(x) (__builtin_bswap32(x) >> 16)
-#endif
 
 #endif /* _ASM_TILE_SWAB_H */
diff -druN linux-2.6.39-libre/arch/tile/include/asm/thread_info.h linux-3.0-rc7-libre/arch/tile/include/asm/thread_info.h
--- linux-2.6.39-libre/arch/tile/include/asm/thread_info.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/tile/include/asm/thread_info.h	2011-07-11 19:51:52.000000000 -0400
@@ -125,6 +125,7 @@
 #define TIF_SYSCALL_AUDIT	5	/* syscall auditing active */
 #define TIF_SECCOMP		6	/* secure computing */
 #define TIF_MEMDIE		7	/* OOM killer at work */
+#define TIF_NOTIFY_RESUME	8	/* callback before returning to user */
 
 #define _TIF_SIGPENDING		(1<<TIF_SIGPENDING)
 #define _TIF_NEED_RESCHED	(1<<TIF_NEED_RESCHED)
@@ -134,10 +135,12 @@
 #define _TIF_SYSCALL_AUDIT	(1<<TIF_SYSCALL_AUDIT)
 #define _TIF_SECCOMP		(1<<TIF_SECCOMP)
 #define _TIF_MEMDIE		(1<<TIF_MEMDIE)
+#define _TIF_NOTIFY_RESUME	(1<<TIF_NOTIFY_RESUME)
 
 /* Work to do on any return to user space. */
 #define _TIF_ALLWORK_MASK \
-  (_TIF_SIGPENDING|_TIF_NEED_RESCHED|_TIF_SINGLESTEP|_TIF_ASYNC_TLB)
+  (_TIF_SIGPENDING|_TIF_NEED_RESCHED|_TIF_SINGLESTEP|\
+   _TIF_ASYNC_TLB|_TIF_NOTIFY_RESUME)
 
 /*
  * Thread-synchronous status.
diff -druN linux-2.6.39-libre/arch/tile/include/asm/topology.h linux-3.0-rc7-libre/arch/tile/include/asm/topology.h
--- linux-2.6.39-libre/arch/tile/include/asm/topology.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/tile/include/asm/topology.h	2011-07-11 19:51:52.000000000 -0400
@@ -44,25 +44,64 @@
 /* For now, use numa node -1 for global allocation. */
 #define pcibus_to_node(bus)		((void)(bus), -1)
 
+/*
+ * TILE architecture has many cores integrated in one processor, so we need
+ * setup bigger balance_interval for both CPU/NODE scheduling domains to
+ * reduce process scheduling costs.
+ */
+
+/* sched_domains SD_CPU_INIT for TILE architecture */
+#define SD_CPU_INIT (struct sched_domain) {				\
+	.min_interval		= 4,					\
+	.max_interval		= 128,					\
+	.busy_factor		= 64,					\
+	.imbalance_pct		= 125,					\
+	.cache_nice_tries	= 1,					\
+	.busy_idx		= 2,					\
+	.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_SHARE_PKG_RESOURCES		\
+				| 0*SD_SERIALIZE			\
+				,					\
+	.last_balance		= jiffies,				\
+	.balance_interval	= 32,					\
+}
+
 /* sched_domains SD_NODE_INIT for TILE architecture */
-#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		= 2,			\
-	.wake_idx		= 1,			\
-	.flags			= SD_LOAD_BALANCE	\
-				| SD_BALANCE_NEWIDLE	\
-				| SD_BALANCE_EXEC	\
-				| SD_BALANCE_FORK	\
-				| SD_WAKE_AFFINE	\
-				| SD_SERIALIZE,		\
-	.last_balance		= jiffies,		\
-	.balance_interval	= 1,			\
+#define SD_NODE_INIT (struct sched_domain) {				\
+	.min_interval		= 16,					\
+	.max_interval		= 512,					\
+	.busy_factor		= 32,					\
+	.imbalance_pct		= 125,					\
+	.cache_nice_tries	= 1,					\
+	.busy_idx		= 3,					\
+	.idle_idx		= 1,					\
+	.newidle_idx		= 2,					\
+	.wake_idx		= 1,					\
+	.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_SHARE_PKG_RESOURCES		\
+				| 1*SD_SERIALIZE			\
+				,					\
+	.last_balance		= jiffies,				\
+	.balance_interval	= 128,					\
 }
 
 /* By definition, we create nodes based on online memory. */
diff -druN linux-2.6.39-libre/arch/tile/include/asm/traps.h linux-3.0-rc7-libre/arch/tile/include/asm/traps.h
--- linux-2.6.39-libre/arch/tile/include/asm/traps.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/tile/include/asm/traps.h	2011-07-11 19:51:52.000000000 -0400
@@ -15,10 +15,14 @@
 #ifndef _ASM_TILE_TRAPS_H
 #define _ASM_TILE_TRAPS_H
 
+#include <arch/chip.h>
+
 /* mm/fault.c */
 void do_page_fault(struct pt_regs *, int fault_num,
 		   unsigned long address, unsigned long write);
+#if CHIP_HAS_TILE_DMA() || CHIP_HAS_SN_PROC()
 void do_async_page_fault(struct pt_regs *);
+#endif
 
 #ifndef __tilegx__
 /*
diff -druN linux-2.6.39-libre/arch/tile/include/asm/unistd.h linux-3.0-rc7-libre/arch/tile/include/asm/unistd.h
--- linux-2.6.39-libre/arch/tile/include/asm/unistd.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/tile/include/asm/unistd.h	2011-07-11 19:51:52.000000000 -0400
@@ -15,7 +15,7 @@
 #if !defined(_ASM_TILE_UNISTD_H) || defined(__SYSCALL)
 #define _ASM_TILE_UNISTD_H
 
-#ifndef __LP64__
+#if !defined(__LP64__) || defined(__SYSCALL_COMPAT)
 /* Use the flavor of this syscall that matches the 32-bit API better. */
 #define __ARCH_WANT_SYNC_FILE_RANGE2
 #endif
diff -druN linux-2.6.39-libre/arch/tile/include/asm/vga.h linux-3.0-rc7-libre/arch/tile/include/asm/vga.h
--- linux-2.6.39-libre/arch/tile/include/asm/vga.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/tile/include/asm/vga.h	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2010 Tilera 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, version 2.
+ *
+ *   This program is distributed in the hope that it will be useful, but
+ *   WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
+ *   NON INFRINGEMENT.  See the GNU General Public License for
+ *   more details.
+ *
+ * Access to VGA videoram.
+ */
+
+#ifndef _ASM_TILE_VGA_H
+#define _ASM_TILE_VGA_H
+
+#include <asm/io.h>
+
+#define VT_BUF_HAVE_RW
+
+static inline void scr_writew(u16 val, volatile u16 *addr)
+{
+	__raw_writew(val, (volatile u16 __iomem *) addr);
+}
+
+static inline u16 scr_readw(volatile const u16 *addr)
+{
+	return __raw_readw((volatile const u16 __iomem *) addr);
+}
+
+#define vga_readb(a)	readb((u8 __iomem *)(a))
+#define vga_writeb(v,a)	writeb(v, (u8 __iomem *)(a))
+
+#define VGA_MAP_MEM(x,s)	((unsigned long) ioremap(x, s))
+
+#endif
diff -druN linux-2.6.39-libre/arch/tile/include/hv/hypervisor.h linux-3.0-rc7-libre/arch/tile/include/hv/hypervisor.h
--- linux-2.6.39-libre/arch/tile/include/hv/hypervisor.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/tile/include/hv/hypervisor.h	2011-07-11 19:51:52.000000000 -0400
@@ -22,8 +22,6 @@
 
 #include <arch/chip.h>
 
-#include <hv/pagesize.h>
-
 /* Linux builds want unsigned long constants, but assembler wants numbers */
 #ifdef __ASSEMBLER__
 /** One, for assembler */
@@ -44,11 +42,21 @@
  */
 #define HV_L1_SPAN (__HV_SIZE_ONE << HV_LOG2_L1_SPAN)
 
+/** The log2 of the size of small pages, in bytes. This value should
+ * be verified at runtime by calling hv_sysconf(HV_SYSCONF_PAGE_SIZE_SMALL).
+ */
+#define HV_LOG2_PAGE_SIZE_SMALL 16
+
 /** The size of small pages, in bytes. This value should be verified
  * at runtime by calling hv_sysconf(HV_SYSCONF_PAGE_SIZE_SMALL).
  */
 #define HV_PAGE_SIZE_SMALL (__HV_SIZE_ONE << HV_LOG2_PAGE_SIZE_SMALL)
 
+/** The log2 of the size of large pages, in bytes. This value should be
+ * verified at runtime by calling hv_sysconf(HV_SYSCONF_PAGE_SIZE_LARGE).
+ */
+#define HV_LOG2_PAGE_SIZE_LARGE 24
+
 /** The size of large pages, in bytes. This value should be verified
  * at runtime by calling hv_sysconf(HV_SYSCONF_PAGE_SIZE_LARGE).
  */
diff -druN linux-2.6.39-libre/arch/tile/include/hv/pagesize.h linux-3.0-rc7-libre/arch/tile/include/hv/pagesize.h
--- linux-2.6.39-libre/arch/tile/include/hv/pagesize.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/tile/include/hv/pagesize.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,32 +0,0 @@
-/*
- * Copyright 2010 Tilera 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, version 2.
- *
- *   This program is distributed in the hope that it will be useful, but
- *   WITHOUT ANY WARRANTY; without even the implied warranty of
- *   MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
- *   NON INFRINGEMENT.  See the GNU General Public License for
- *   more details.
- */
-
-/**
- * @file pagesize.h
- */
-
-#ifndef _HV_PAGESIZE_H
-#define _HV_PAGESIZE_H
-
-/** The log2 of the size of small pages, in bytes. This value should
- * be verified at runtime by calling hv_sysconf(HV_SYSCONF_PAGE_SIZE_SMALL).
- */
-#define HV_LOG2_PAGE_SIZE_SMALL 16
-
-/** The log2 of the size of large pages, in bytes. This value should be
- * verified at runtime by calling hv_sysconf(HV_SYSCONF_PAGE_SIZE_LARGE).
- */
-#define HV_LOG2_PAGE_SIZE_LARGE 24
-
-#endif /* _HV_PAGESIZE_H */
diff -druN linux-2.6.39-libre/arch/tile/Kconfig linux-3.0-rc7-libre/arch/tile/Kconfig
--- linux-2.6.39-libre/arch/tile/Kconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/tile/Kconfig	2011-07-11 19:51:52.000000000 -0400
@@ -5,13 +5,13 @@
 	def_bool y
 	select HAVE_KVM if !TILEGX
 	select GENERIC_FIND_FIRST_BIT
-	select GENERIC_FIND_NEXT_BIT
 	select USE_GENERIC_SMP_HELPERS
 	select CC_OPTIMIZE_FOR_SIZE
 	select HAVE_GENERIC_HARDIRQS
 	select GENERIC_IRQ_PROBE
 	select GENERIC_PENDING_IRQ if SMP
 	select GENERIC_IRQ_SHOW
+	select SYS_HYPERVISOR
 
 # FIXME: investigate whether we need/want these options.
 #	select HAVE_IOREMAP_PROT
@@ -339,6 +339,14 @@
 
 source "drivers/pci/Kconfig"
 
+config HOTPLUG
+	bool "Support for hot-pluggable devices"
+	---help---
+	  Say Y here if you want to plug devices into your computer while
+	  the system is running, and be able to use them quickly.  In many
+	  cases, the devices can likewise be unplugged at any time too.
+	  One well-known example of this is USB.
+
 source "drivers/pci/hotplug/Kconfig"
 
 endmenu
diff -druN linux-2.6.39-libre/arch/tile/Kconfig.debug linux-3.0-rc7-libre/arch/tile/Kconfig.debug
--- linux-2.6.39-libre/arch/tile/Kconfig.debug	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/tile/Kconfig.debug	2011-07-11 19:51:52.000000000 -0400
@@ -21,15 +21,6 @@
 	  This option will cause messages to be printed if free stack space
 	  drops below a certain limit.
 
-config DEBUG_STACK_USAGE
-	bool "Stack utilization instrumentation"
-	depends on DEBUG_KERNEL
-	help
-	  Enables the display of the minimum amount of free stack which each
-	  task has ever had available in the sysrq-T and sysrq-P debug output.
-
-	  This option will slow down process creation somewhat.
-
 config DEBUG_EXTRA_FLAGS
 	string "Additional compiler arguments when building with '-g'"
 	depends on DEBUG_INFO
diff -druN linux-2.6.39-libre/arch/tile/kernel/backtrace.c linux-3.0-rc7-libre/arch/tile/kernel/backtrace.c
--- linux-2.6.39-libre/arch/tile/kernel/backtrace.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/tile/kernel/backtrace.c	2011-07-11 19:51:52.000000000 -0400
@@ -14,19 +14,11 @@
 
 #include <linux/kernel.h>
 #include <linux/string.h>
-
 #include <asm/backtrace.h>
-
-#include <arch/chip.h>
-
 #include <asm/opcode-tile.h>
+#include <arch/abi.h>
 
-
-#define TREG_SP 54
-#define TREG_LR 55
-
-
-#if TILE_CHIP >= 10
+#ifdef __tilegx__
 #define tile_bundle_bits tilegx_bundle_bits
 #define TILE_MAX_INSTRUCTIONS_PER_BUNDLE TILEGX_MAX_INSTRUCTIONS_PER_BUNDLE
 #define TILE_BUNDLE_ALIGNMENT_IN_BYTES TILEGX_BUNDLE_ALIGNMENT_IN_BYTES
@@ -47,7 +39,7 @@
 typedef int bt_int_reg_t;
 #endif
 
-/** A decoded bundle used for backtracer analysis. */
+/* A decoded bundle used for backtracer analysis. */
 struct BacktraceBundle {
 	tile_bundle_bits bits;
 	int num_insns;
@@ -56,23 +48,7 @@
 };
 
 
-/* This implementation only makes sense for native tools. */
-/** Default function to read memory. */
-static bool bt_read_memory(void *result, VirtualAddress addr,
-			   unsigned int size, void *extra)
-{
-	/* FIXME: this should do some horrible signal stuff to catch
-	 * SEGV cleanly and fail.
-	 *
-	 * Or else the caller should do the setjmp for efficiency.
-	 */
-
-	memcpy(result, (const void *)addr, size);
-	return true;
-}
-
-
-/** Locates an instruction inside the given bundle that
+/* Locates an instruction inside the given bundle that
  * has the specified mnemonic, and whose first 'num_operands_to_match'
  * operands exactly match those in 'operand_values'.
  */
@@ -107,13 +83,13 @@
 	return NULL;
 }
 
-/** Does this bundle contain an 'iret' instruction? */
+/* Does this bundle contain an 'iret' instruction? */
 static inline bool bt_has_iret(const struct BacktraceBundle *bundle)
 {
 	return find_matching_insn(bundle, TILE_OPC_IRET, NULL, 0) != NULL;
 }
 
-/** Does this bundle contain an 'addi sp, sp, OFFSET' or
+/* Does this bundle contain an 'addi sp, sp, OFFSET' or
  * 'addli sp, sp, OFFSET' instruction, and if so, what is OFFSET?
  */
 static bool bt_has_addi_sp(const struct BacktraceBundle *bundle, int *adjust)
@@ -124,7 +100,7 @@
 		find_matching_insn(bundle, TILE_OPC_ADDI, vals, 2);
 	if (insn == NULL)
 		insn = find_matching_insn(bundle, TILE_OPC_ADDLI, vals, 2);
-#if TILE_CHIP >= 10
+#ifdef __tilegx__
 	if (insn == NULL)
 		insn = find_matching_insn(bundle, TILEGX_OPC_ADDXLI, vals, 2);
 	if (insn == NULL)
@@ -137,7 +113,7 @@
 	return true;
 }
 
-/** Does this bundle contain any 'info OP' or 'infol OP'
+/* Does this bundle contain any 'info OP' or 'infol OP'
  * instruction, and if so, what are their OP?  Note that OP is interpreted
  * as an unsigned value by this code since that's what the caller wants.
  * Returns the number of info ops found.
@@ -161,7 +137,7 @@
 	return num_ops;
 }
 
-/** Does this bundle contain a jrp instruction, and if so, to which
+/* Does this bundle contain a jrp instruction, and if so, to which
  * register is it jumping?
  */
 static bool bt_has_jrp(const struct BacktraceBundle *bundle, int *target_reg)
@@ -175,7 +151,7 @@
 	return true;
 }
 
-/** Does this bundle modify the specified register in any way? */
+/* Does this bundle modify the specified register in any way? */
 static bool bt_modifies_reg(const struct BacktraceBundle *bundle, int reg)
 {
 	int i, j;
@@ -195,34 +171,34 @@
 	return false;
 }
 
-/** Does this bundle modify sp? */
+/* Does this bundle modify sp? */
 static inline bool bt_modifies_sp(const struct BacktraceBundle *bundle)
 {
 	return bt_modifies_reg(bundle, TREG_SP);
 }
 
-/** Does this bundle modify lr? */
+/* Does this bundle modify lr? */
 static inline bool bt_modifies_lr(const struct BacktraceBundle *bundle)
 {
 	return bt_modifies_reg(bundle, TREG_LR);
 }
 
-/** Does this bundle contain the instruction 'move fp, sp'? */
+/* Does this bundle contain the instruction 'move fp, sp'? */
 static inline bool bt_has_move_r52_sp(const struct BacktraceBundle *bundle)
 {
 	static const int vals[2] = { 52, TREG_SP };
 	return find_matching_insn(bundle, TILE_OPC_MOVE, vals, 2) != NULL;
 }
 
-/** Does this bundle contain a store of lr to sp? */
+/* Does this bundle contain a store of lr to sp? */
 static inline bool bt_has_sw_sp_lr(const struct BacktraceBundle *bundle)
 {
 	static const int vals[2] = { TREG_SP, TREG_LR };
 	return find_matching_insn(bundle, OPCODE_STORE, vals, 2) != NULL;
 }
 
-#if TILE_CHIP >= 10
-/** Track moveli values placed into registers. */
+#ifdef __tilegx__
+/* Track moveli values placed into registers. */
 static inline void bt_update_moveli(const struct BacktraceBundle *bundle,
 				    int moveli_args[])
 {
@@ -238,7 +214,7 @@
 	}
 }
 
-/** Does this bundle contain an 'add sp, sp, reg' instruction
+/* Does this bundle contain an 'add sp, sp, reg' instruction
  * from a register that we saw a moveli into, and if so, what
  * is the value in the register?
  */
@@ -260,11 +236,11 @@
 }
 #endif
 
-/** Locates the caller's PC and SP for a program starting at the
+/* Locates the caller's PC and SP for a program starting at the
  * given address.
  */
 static void find_caller_pc_and_caller_sp(CallerLocation *location,
-					 const VirtualAddress start_pc,
+					 const unsigned long start_pc,
 					 BacktraceMemoryReader read_memory_func,
 					 void *read_memory_func_extra)
 {
@@ -288,9 +264,9 @@
 	tile_bundle_bits prefetched_bundles[32];
 	int num_bundles_prefetched = 0;
 	int next_bundle = 0;
-	VirtualAddress pc;
+	unsigned long pc;
 
-#if TILE_CHIP >= 10
+#ifdef __tilegx__
 	/* Naively try to track moveli values to support addx for -m32. */
 	int moveli_args[TILEGX_NUM_REGISTERS] = { 0 };
 #endif
@@ -369,10 +345,6 @@
 					/* Weird; reserved value, ignore it. */
 					continue;
 				}
-				if (info_operand & ENTRY_POINT_INFO_OP)	{
-					/* This info op is ignored by the backtracer. */
-					continue;
-				}
 
 				/* Skip info ops which are not in the
 				 * "one_ago" mode we want right now.
@@ -453,7 +425,7 @@
 		if (!sp_determined) {
 			int adjust;
 			if (bt_has_addi_sp(&bundle, &adjust)
-#if TILE_CHIP >= 10
+#ifdef __tilegx__
 			    || bt_has_add_sp(&bundle, &adjust, moveli_args)
 #endif
 				) {
@@ -504,7 +476,7 @@
 				}
 			}
 
-#if TILE_CHIP >= 10
+#ifdef __tilegx__
 			/* Track moveli arguments for -m32 mode. */
 			bt_update_moveli(&bundle, moveli_args);
 #endif
@@ -546,18 +518,26 @@
 	}
 }
 
+/* Initializes a backtracer to start from the given location.
+ *
+ * If the frame pointer cannot be determined it is set to -1.
+ *
+ * state: The state to be filled in.
+ * read_memory_func: A callback that reads memory.
+ * read_memory_func_extra: An arbitrary argument to read_memory_func.
+ * pc: The current PC.
+ * lr: The current value of the 'lr' register.
+ * sp: The current value of the 'sp' register.
+ * r52: The current value of the 'r52' register.
+ */
 void backtrace_init(BacktraceIterator *state,
 		    BacktraceMemoryReader read_memory_func,
 		    void *read_memory_func_extra,
-		    VirtualAddress pc, VirtualAddress lr,
-		    VirtualAddress sp, VirtualAddress r52)
+		    unsigned long pc, unsigned long lr,
+		    unsigned long sp, unsigned long r52)
 {
 	CallerLocation location;
-	VirtualAddress fp, initial_frame_caller_pc;
-
-	if (read_memory_func == NULL) {
-		read_memory_func = bt_read_memory;
-	}
+	unsigned long fp, initial_frame_caller_pc;
 
 	/* Find out where we are in the initial frame. */
 	find_caller_pc_and_caller_sp(&location, pc,
@@ -630,12 +610,15 @@
 /* Handle the case where the register holds more bits than the VA. */
 static bool valid_addr_reg(bt_int_reg_t reg)
 {
-	return ((VirtualAddress)reg == reg);
+	return ((unsigned long)reg == reg);
 }
 
+/* Advances the backtracing state to the calling frame, returning
+ * true iff successful.
+ */
 bool backtrace_next(BacktraceIterator *state)
 {
-	VirtualAddress next_fp, next_pc;
+	unsigned long next_fp, next_pc;
 	bt_int_reg_t next_frame[2];
 
 	if (state->fp == -1) {
diff -druN linux-2.6.39-libre/arch/tile/kernel/compat.c linux-3.0-rc7-libre/arch/tile/kernel/compat.c
--- linux-2.6.39-libre/arch/tile/kernel/compat.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/tile/kernel/compat.c	2011-07-11 19:51:52.000000000 -0400
@@ -135,26 +135,15 @@
 
 /* Provide the compat syscall number to call mapping. */
 #undef __SYSCALL
-#define __SYSCALL(nr, call) [nr] = (compat_##call),
+#define __SYSCALL(nr, call) [nr] = (call),
 
 /* The generic versions of these don't work for Tile. */
 #define compat_sys_msgrcv tile_compat_sys_msgrcv
 #define compat_sys_msgsnd tile_compat_sys_msgsnd
 
 /* See comments in sys.c */
-#define compat_sys_fadvise64 sys32_fadvise64
 #define compat_sys_fadvise64_64 sys32_fadvise64_64
 #define compat_sys_readahead sys32_readahead
-#define compat_sys_sync_file_range compat_sys_sync_file_range2
-
-/* We leverage the "struct stat64" type for 32-bit time_t/nsec. */
-#define compat_sys_stat64 sys_stat64
-#define compat_sys_lstat64 sys_lstat64
-#define compat_sys_fstat64 sys_fstat64
-#define compat_sys_fstatat64 sys_fstatat64
-
-/* The native sys_ptrace dynamically handles compat binaries. */
-#define compat_sys_ptrace sys_ptrace
 
 /* Call the trampolines to manage pt_regs where necessary. */
 #define compat_sys_execve _compat_sys_execve
diff -druN linux-2.6.39-libre/arch/tile/kernel/compat_signal.c linux-3.0-rc7-libre/arch/tile/kernel/compat_signal.c
--- linux-2.6.39-libre/arch/tile/kernel/compat_signal.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/tile/kernel/compat_signal.c	2011-07-11 19:51:52.000000000 -0400
@@ -317,7 +317,7 @@
 	return 0;
 
 badframe:
-	force_sig(SIGSEGV, current);
+	signal_fault("bad sigreturn frame", regs, frame, 0);
 	return 0;
 }
 
@@ -431,6 +431,6 @@
 	return 0;
 
 give_sigsegv:
-	force_sigsegv(sig, current);
+	signal_fault("bad setup frame", regs, frame, sig);
 	return -EFAULT;
 }
diff -druN linux-2.6.39-libre/arch/tile/kernel/futex_64.S linux-3.0-rc7-libre/arch/tile/kernel/futex_64.S
--- linux-2.6.39-libre/arch/tile/kernel/futex_64.S	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/tile/kernel/futex_64.S	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2011 Tilera 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, version 2.
+ *
+ *   This program is distributed in the hope that it will be useful, but
+ *   WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
+ *   NON INFRINGEMENT.  See the GNU General Public License for
+ *   more details.
+ *
+ * Atomically access user memory, but use MMU to avoid propagating
+ * kernel exceptions.
+ */
+
+#include <linux/linkage.h>
+#include <asm/errno.h>
+#include <asm/futex.h>
+#include <asm/page.h>
+#include <asm/processor.h>
+
+/*
+ * Provide a set of atomic memory operations supporting <asm/futex.h>.
+ *
+ * r0: user address to manipulate
+ * r1: new value to write, or for cmpxchg, old value to compare against
+ * r2: (cmpxchg only) new value to write
+ *
+ * Return __get_user struct, r0 with value, r1 with error.
+ */
+#define FUTEX_OP(name, ...) \
+STD_ENTRY(futex_##name)			\
+	__VA_ARGS__;			\
+	{				\
+	 move   r1, zero;		\
+	 jrp    lr			\
+	};				\
+	STD_ENDPROC(futex_##name);	\
+	.pushsection __ex_table,"a";	\
+	.quad 1b, get_user_fault;	\
+	.popsection
+
+	.pushsection .fixup,"ax"
+get_user_fault:
+	{ movei r1, -EFAULT; jrp lr }
+	ENDPROC(get_user_fault)
+	.popsection
+
+FUTEX_OP(cmpxchg, mtspr CMPEXCH_VALUE, r1; 1: cmpexch4 r0, r0, r2)
+FUTEX_OP(set, 1: exch4 r0, r0, r1)
+FUTEX_OP(add, 1: fetchadd4 r0, r0, r1)
+FUTEX_OP(or, 1: fetchor4 r0, r0, r1)
+FUTEX_OP(andn, nor r1, r1, zero; 1: fetchand4 r0, r0, r1)
diff -druN linux-2.6.39-libre/arch/tile/kernel/hardwall.c linux-3.0-rc7-libre/arch/tile/kernel/hardwall.c
--- linux-2.6.39-libre/arch/tile/kernel/hardwall.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/tile/kernel/hardwall.c	2011-07-11 19:51:52.000000000 -0400
@@ -40,16 +40,25 @@
 struct hardwall_info {
 	struct list_head list;             /* "rectangles" list */
 	struct list_head task_head;        /* head of tasks in this hardwall */
+	struct cpumask cpumask;            /* cpus in the rectangle */
 	int ulhc_x;                        /* upper left hand corner x coord */
 	int ulhc_y;                        /* upper left hand corner y coord */
 	int width;                         /* rectangle width */
 	int height;                        /* rectangle height */
+	int id;                            /* integer id for this hardwall */
 	int teardown_in_progress;          /* are we tearing this one down? */
 };
 
 /* Currently allocated hardwall rectangles */
 static LIST_HEAD(rectangles);
 
+/* /proc/tile/hardwall */
+static struct proc_dir_entry *hardwall_proc_dir;
+
+/* Functions to manage files in /proc/tile/hardwall. */
+static void hardwall_add_proc(struct hardwall_info *rect);
+static void hardwall_remove_proc(struct hardwall_info *rect);
+
 /*
  * Guard changes to the hardwall data structures.
  * This could be finer grained (e.g. one lock for the list of hardwall
@@ -105,6 +114,8 @@
 	r->ulhc_y = cpu_y(ulhc);
 	r->width = cpu_x(lrhc) - r->ulhc_x + 1;
 	r->height = cpu_y(lrhc) - r->ulhc_y + 1;
+	cpumask_copy(&r->cpumask, mask);
+	r->id = ulhc;   /* The ulhc cpu id can be the hardwall id. */
 
 	/* Width and height must be positive */
 	if (r->width <= 0 || r->height <= 0)
@@ -268,12 +279,10 @@
 	found_processes = 0;
 	list_for_each_entry(p, &rect->task_head, thread.hardwall_list) {
 		BUG_ON(p->thread.hardwall != rect);
-		if (p->sighand) {
+		if (!(p->flags & PF_EXITING)) {
 			found_processes = 1;
 			pr_notice("hardwall: killing %d\n", p->pid);
-			spin_lock(&p->sighand->siglock);
-			__group_send_sig_info(info.si_signo, &info, p);
-			spin_unlock(&p->sighand->siglock);
+			do_send_sig_info(info.si_signo, &info, p, false);
 		}
 	}
 	if (!found_processes)
@@ -390,6 +399,9 @@
 	/* Set up appropriate hardwalling on all affected cpus. */
 	hardwall_setup(rect);
 
+	/* Create a /proc/tile/hardwall entry. */
+	hardwall_add_proc(rect);
+
 	return rect;
 }
 
@@ -647,6 +659,9 @@
 	/* Restart switch and disable firewall. */
 	on_each_cpu_mask(&mask, restart_udn_switch, NULL, 1);
 
+	/* Remove the /proc/tile/hardwall entry. */
+	hardwall_remove_proc(rect);
+
 	/* Now free the rectangle from the list. */
 	spin_lock_irqsave(&hardwall_lock, flags);
 	BUG_ON(!list_empty(&rect->task_head));
@@ -656,35 +671,57 @@
 }
 
 
-/*
- * Dump hardwall state via /proc; initialized in arch/tile/sys/proc.c.
- */
-int proc_tile_hardwall_show(struct seq_file *sf, void *v)
+static int hardwall_proc_show(struct seq_file *sf, void *v)
 {
-	struct hardwall_info *r;
-
-	if (udn_disabled) {
-		seq_printf(sf, "%dx%d 0,0 pids:\n", smp_width, smp_height);
-		return 0;
-	}
+	struct hardwall_info *rect = sf->private;
+	char buf[256];
 
-	spin_lock_irq(&hardwall_lock);
-	list_for_each_entry(r, &rectangles, list) {
-		struct task_struct *p;
-		seq_printf(sf, "%dx%d %d,%d pids:",
-			   r->width, r->height, r->ulhc_x, r->ulhc_y);
-		list_for_each_entry(p, &r->task_head, thread.hardwall_list) {
-			unsigned int cpu = cpumask_first(&p->cpus_allowed);
-			unsigned int x = cpu % smp_width;
-			unsigned int y = cpu / smp_width;
-			seq_printf(sf, " %d@%d,%d", p->pid, x, y);
-		}
-		seq_printf(sf, "\n");
-	}
-	spin_unlock_irq(&hardwall_lock);
+	int rc = cpulist_scnprintf(buf, sizeof(buf), &rect->cpumask);
+	buf[rc++] = '\n';
+	seq_write(sf, buf, rc);
 	return 0;
 }
 
+static int hardwall_proc_open(struct inode *inode,
+			      struct file *file)
+{
+	return single_open(file, hardwall_proc_show, PDE(inode)->data);
+}
+
+static const struct file_operations hardwall_proc_fops = {
+	.open		= hardwall_proc_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
+static void hardwall_add_proc(struct hardwall_info *rect)
+{
+	char buf[64];
+	snprintf(buf, sizeof(buf), "%d", rect->id);
+	proc_create_data(buf, 0444, hardwall_proc_dir,
+			 &hardwall_proc_fops, rect);
+}
+
+static void hardwall_remove_proc(struct hardwall_info *rect)
+{
+	char buf[64];
+	snprintf(buf, sizeof(buf), "%d", rect->id);
+	remove_proc_entry(buf, hardwall_proc_dir);
+}
+
+int proc_pid_hardwall(struct task_struct *task, char *buffer)
+{
+	struct hardwall_info *rect = task->thread.hardwall;
+	return rect ? sprintf(buffer, "%d\n", rect->id) : 0;
+}
+
+void proc_tile_hardwall_init(struct proc_dir_entry *root)
+{
+	if (!udn_disabled)
+		hardwall_proc_dir = proc_mkdir("hardwall", root);
+}
+
 
 /*
  * Character device support via ioctl/close.
@@ -718,6 +755,9 @@
 			return -EINVAL;
 		return hardwall_deactivate(current);
 
+	case _HARDWALL_GET_ID:
+		return rect ? rect->id : -EINVAL;
+
 	default:
 		return -EINVAL;
 	}
diff -druN linux-2.6.39-libre/arch/tile/kernel/head_64.S linux-3.0-rc7-libre/arch/tile/kernel/head_64.S
--- linux-2.6.39-libre/arch/tile/kernel/head_64.S	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/tile/kernel/head_64.S	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,269 @@
+/*
+ * Copyright 2011 Tilera 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, version 2.
+ *
+ *   This program is distributed in the hope that it will be useful, but
+ *   WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
+ *   NON INFRINGEMENT.  See the GNU General Public License for
+ *   more details.
+ *
+ * TILE startup code.
+ */
+
+#include <linux/linkage.h>
+#include <linux/init.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/thread_info.h>
+#include <asm/processor.h>
+#include <asm/asm-offsets.h>
+#include <hv/hypervisor.h>
+#include <arch/chip.h>
+#include <arch/spr_def.h>
+
+/*
+ * This module contains the entry code for kernel images. It performs the
+ * minimal setup needed to call the generic C routines.
+ */
+
+	__HEAD
+ENTRY(_start)
+	/* Notify the hypervisor of what version of the API we want */
+	{
+	  movei r1, TILE_CHIP
+	  movei r2, TILE_CHIP_REV
+	}
+	{
+	  moveli r0, _HV_VERSION
+	  jal hv_init
+	}
+	/* Get a reasonable default ASID in r0 */
+	{
+	  move r0, zero
+	  jal hv_inquire_asid
+	}
+
+	/*
+	 * Install the default page table.  The relocation required to
+	 * statically define the table is a bit too complex, so we have
+	 * to plug in the pointer from the L0 to the L1 table by hand.
+	 * We only do this on the first cpu to boot, though, since the
+	 * other CPUs should see a properly-constructed page table.
+	 */
+	{
+	  v4int_l r2, zero, r0    /* ASID for hv_install_context */
+	  moveli r4, hw1_last(swapper_pgprot - PAGE_OFFSET)
+	}
+	{
+	  shl16insli r4, r4, hw0(swapper_pgprot - PAGE_OFFSET)
+	}
+	{
+	  ld r1, r4               /* access_pte for hv_install_context */
+	}
+	{
+	  moveli r0, hw1_last(.Lsv_data_pmd - PAGE_OFFSET)
+	  moveli r6, hw1_last(temp_data_pmd - PAGE_OFFSET)
+	}
+	{
+	  /* After initializing swapper_pgprot, HV_PTE_GLOBAL is set. */
+	  bfextu r7, r1, HV_PTE_INDEX_GLOBAL, HV_PTE_INDEX_GLOBAL
+	  inv r4
+	}
+	bnez r7, .Lno_write
+	{
+	  shl16insli r0, r0, hw0(.Lsv_data_pmd - PAGE_OFFSET)
+	  shl16insli r6, r6, hw0(temp_data_pmd - PAGE_OFFSET)
+	}
+	{
+	  /* Cut off the low bits of the PT address. */
+	  shrui r6, r6, HV_LOG2_PAGE_TABLE_ALIGN
+	  /* Start with our access pte. */
+	  move r5, r1
+	}
+	{
+	  /* Stuff the address into the page table pointer slot of the PTE. */
+	  bfins r5, r6, HV_PTE_INDEX_PTFN, \
+			HV_PTE_INDEX_PTFN + HV_PTE_PTFN_BITS - 1
+	}
+	{
+	  /* Store the L0 data PTE. */
+	  st r0, r5
+	  addli r6, r6, (temp_code_pmd - temp_data_pmd) >> \
+			HV_LOG2_PAGE_TABLE_ALIGN
+	}
+	{
+	  addli r0, r0, .Lsv_code_pmd - .Lsv_data_pmd
+	  bfins r5, r6, HV_PTE_INDEX_PTFN, \
+			HV_PTE_INDEX_PTFN + HV_PTE_PTFN_BITS - 1
+	}
+	/* Store the L0 code PTE. */
+	st r0, r5
+
+.Lno_write:
+	moveli lr, hw2_last(1f)
+	{
+	  shl16insli lr, lr, hw1(1f)
+	  moveli r0, hw1_last(swapper_pg_dir - PAGE_OFFSET)
+	}
+	{
+	  shl16insli lr, lr, hw0(1f)
+	  shl16insli r0, r0, hw0(swapper_pg_dir - PAGE_OFFSET)
+	}
+	{
+	  move r3, zero
+	  j hv_install_context
+	}
+1:
+
+	/* Install the interrupt base. */
+	moveli r0, hw2_last(MEM_SV_START)
+	shl16insli r0, r0, hw1(MEM_SV_START)
+	shl16insli r0, r0, hw0(MEM_SV_START)
+	mtspr SPR_INTERRUPT_VECTOR_BASE_K, r0
+
+	/*
+	 * Get our processor number and save it away in SAVE_K_0.
+	 * Extract stuff from the topology structure: r4 = y, r6 = x,
+	 * r5 = width.  FIXME: consider whether we want to just make these
+	 * 64-bit values (and if so fix smp_topology write below, too).
+	 */
+	jal hv_inquire_topology
+	{
+	  v4int_l r5, zero, r1    /* r5 = width */
+	  shrui r4, r0, 32        /* r4 = y */
+	}
+	{
+	  v4int_l r6, zero, r0    /* r6 = x */
+	  mul_lu_lu r4, r4, r5
+	}
+	{
+	  add r4, r4, r6          /* r4 == cpu == y*width + x */
+	}
+
+#ifdef CONFIG_SMP
+	/*
+	 * Load up our per-cpu offset.  When the first (master) tile
+	 * boots, this value is still zero, so we will load boot_pc
+	 * with start_kernel, and boot_sp with init_stack + THREAD_SIZE.
+	 * The master tile initializes the per-cpu offset array, so that
+	 * when subsequent (secondary) tiles boot, they will instead load
+	 * from their per-cpu versions of boot_sp and boot_pc.
+	 */
+	moveli r5, hw2_last(__per_cpu_offset)
+	shl16insli r5, r5, hw1(__per_cpu_offset)
+	shl16insli r5, r5, hw0(__per_cpu_offset)
+	shl3add r5, r4, r5
+	ld r5, r5
+	bnez r5, 1f
+
+	/*
+	 * Save the width and height to the smp_topology variable
+	 * for later use.
+	 */
+	moveli r0, hw2_last(smp_topology + HV_TOPOLOGY_WIDTH_OFFSET)
+	shl16insli r0, r0, hw1(smp_topology + HV_TOPOLOGY_WIDTH_OFFSET)
+	shl16insli r0, r0, hw0(smp_topology + HV_TOPOLOGY_WIDTH_OFFSET)
+	st r0, r1
+1:
+#else
+	move r5, zero
+#endif
+
+	/* Load and go with the correct pc and sp. */
+	{
+	  moveli r1, hw2_last(boot_sp)
+	  moveli r0, hw2_last(boot_pc)
+	}
+	{
+	  shl16insli r1, r1, hw1(boot_sp)
+	  shl16insli r0, r0, hw1(boot_pc)
+	}
+	{
+	  shl16insli r1, r1, hw0(boot_sp)
+	  shl16insli r0, r0, hw0(boot_pc)
+	}
+	{
+	  add r1, r1, r5
+	  add r0, r0, r5
+	}
+	ld r0, r0
+	ld sp, r1
+	or r4, sp, r4
+	mtspr SPR_SYSTEM_SAVE_K_0, r4  /* save ksp0 + cpu */
+	addi sp, sp, -STACK_TOP_DELTA
+	{
+	  move lr, zero   /* stop backtraces in the called function */
+	  jr r0
+	}
+	ENDPROC(_start)
+
+__PAGE_ALIGNED_BSS
+	.align PAGE_SIZE
+ENTRY(empty_zero_page)
+	.fill PAGE_SIZE,1,0
+	END(empty_zero_page)
+
+	.macro PTE cpa, bits1
+	.quad HV_PTE_PAGE | HV_PTE_DIRTY | HV_PTE_PRESENT | HV_PTE_ACCESSED |\
+	      HV_PTE_GLOBAL | (HV_PTE_MODE_CACHE_NO_L3 << HV_PTE_INDEX_MODE) |\
+	      (\bits1) | (HV_CPA_TO_PFN(\cpa) << HV_PTE_INDEX_PFN)
+	.endm
+
+__PAGE_ALIGNED_DATA
+	.align PAGE_SIZE
+ENTRY(swapper_pg_dir)
+	.org swapper_pg_dir + HV_L0_INDEX(PAGE_OFFSET) * HV_PTE_SIZE
+.Lsv_data_pmd:
+	.quad 0  /* PTE temp_data_pmd - PAGE_OFFSET, 0 */
+	.org swapper_pg_dir + HV_L0_INDEX(MEM_SV_START) * HV_PTE_SIZE
+.Lsv_code_pmd:
+	.quad 0  /* PTE temp_code_pmd - PAGE_OFFSET, 0 */
+	.org swapper_pg_dir + HV_L0_SIZE
+	END(swapper_pg_dir)
+
+	.align HV_PAGE_TABLE_ALIGN
+ENTRY(temp_data_pmd)
+	/*
+	 * We fill the PAGE_OFFSET pmd with huge pages with
+	 * VA = PA + PAGE_OFFSET.  We remap things with more precise access
+	 * permissions later.
+	 */
+	.set addr, 0
+	.rept HV_L1_ENTRIES
+	PTE addr, HV_PTE_READABLE | HV_PTE_WRITABLE
+	.set addr, addr + HV_PAGE_SIZE_LARGE
+	.endr
+	.org temp_data_pmd + HV_L1_SIZE
+	END(temp_data_pmd)
+
+	.align HV_PAGE_TABLE_ALIGN
+ENTRY(temp_code_pmd)
+	/*
+	 * We fill the MEM_SV_START pmd with huge pages with
+	 * VA = PA + PAGE_OFFSET.  We remap things with more precise access
+	 * permissions later.
+	 */
+	.set addr, 0
+	.rept HV_L1_ENTRIES
+	PTE addr, HV_PTE_READABLE | HV_PTE_EXECUTABLE
+	.set addr, addr + HV_PAGE_SIZE_LARGE
+	.endr
+	.org temp_code_pmd + HV_L1_SIZE
+	END(temp_code_pmd)
+
+	/*
+	 * Isolate swapper_pgprot to its own cache line, since each cpu
+	 * starting up will read it using VA-is-PA and local homing.
+	 * This would otherwise likely conflict with other data on the cache
+	 * line, once we have set its permanent home in the page tables.
+	 */
+	__INITDATA
+	.align CHIP_L2_LINE_SIZE()
+ENTRY(swapper_pgprot)
+	.quad HV_PTE_PRESENT | (HV_PTE_MODE_CACHE_NO_L3 << HV_PTE_INDEX_MODE)
+	.align CHIP_L2_LINE_SIZE()
+	END(swapper_pgprot)
diff -druN linux-2.6.39-libre/arch/tile/kernel/intvec_32.S linux-3.0-rc7-libre/arch/tile/kernel/intvec_32.S
--- linux-2.6.39-libre/arch/tile/kernel/intvec_32.S	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/tile/kernel/intvec_32.S	2011-07-11 19:51:52.000000000 -0400
@@ -851,14 +851,27 @@
 	/* Check to see if there is any work to do before returning to user. */
 	{
 	 addi   r29, r32, THREAD_INFO_FLAGS_OFFSET
-	 moveli r28, lo16(_TIF_ALLWORK_MASK)
+	 moveli r1, lo16(_TIF_ALLWORK_MASK)
 	}
 	{
 	 lw     r29, r29
-	 auli   r28, r28, ha16(_TIF_ALLWORK_MASK)
+	 auli   r1, r1, ha16(_TIF_ALLWORK_MASK)
 	}
-	and     r28, r29, r28
-	bnz     r28, .Lwork_pending
+	and     r1, r29, r1
+	bzt     r1, .Lrestore_all
+
+	/*
+	 * Make sure we have all the registers saved for signal
+	 * handling or single-step.  Call out to C code to figure out
+	 * exactly what we need to do for each flag bit, then if
+	 * necessary, reload the flags and recheck.
+	 */
+	push_extra_callee_saves r0
+	{
+	 PTREGS_PTR(r0, PTREGS_OFFSET_BASE)
+	 jal    do_work_pending
+	}
+	bnz     r0, .Lresume_userspace
 
 	/*
 	 * In the NMI case we
@@ -1099,99 +1112,6 @@
 	pop_reg r50
 	pop_reg r51, sp, PTREGS_OFFSET_REG(29) - PTREGS_OFFSET_REG(51)
 	j .Lcontinue_restore_regs
-
-.Lwork_pending:
-	/* Mask the reschedule flag */
-	andi    r28, r29, _TIF_NEED_RESCHED
-
-	{
-	 /*
-	  * If the NEED_RESCHED flag is called, we call schedule(), which
-	  * may drop this context right here and go do something else.
-	  * On return, jump back to .Lresume_userspace and recheck.
-	  */
-	 bz     r28, .Lasync_tlb
-
-	 /* Mask the async-tlb flag */
-	 andi   r28, r29, _TIF_ASYNC_TLB
-	}
-
-	jal     schedule
-	FEEDBACK_REENTER(interrupt_return)
-
-	/* Reload the flags and check again */
-	j       .Lresume_userspace
-
-.Lasync_tlb:
-	{
-	 bz     r28, .Lneed_sigpending
-
-	 /* Mask the sigpending flag */
-	 andi   r28, r29, _TIF_SIGPENDING
-	}
-
-	PTREGS_PTR(r0, PTREGS_OFFSET_BASE)
-	jal     do_async_page_fault
-	FEEDBACK_REENTER(interrupt_return)
-
-	/*
-	 * Go restart the "resume userspace" process.  We may have
-	 * fired a signal, and we need to disable interrupts again.
-	 */
-	j       .Lresume_userspace
-
-.Lneed_sigpending:
-	/*
-	 * At this point we are either doing signal handling or single-step,
-	 * so either way make sure we have all the registers saved.
-	 */
-	push_extra_callee_saves r0
-
-	{
-	 /* If no signal pending, skip to singlestep check */
-	 bz     r28, .Lneed_singlestep
-
-	 /* Mask the singlestep flag */
-	 andi   r28, r29, _TIF_SINGLESTEP
-	}
-
-	jal     do_signal
-	FEEDBACK_REENTER(interrupt_return)
-
-	/* Reload the flags and check again */
-	j       .Lresume_userspace
-
-.Lneed_singlestep:
-	{
-	 /* Get a pointer to the EX1 field */
-	 PTREGS_PTR(r29, PTREGS_OFFSET_EX1)
-
-	 /* If we get here, our bit must be set. */
-	 bz     r28, .Lwork_confusion
-	}
-	/* If we are in priv mode, don't single step */
-	lw      r28, r29
-	andi    r28, r28, SPR_EX_CONTEXT_1_1__PL_MASK  /* mask off ICS */
-	bnz     r28, .Lrestore_all
-
-	/* Allow interrupts within the single step code */
-	TRACE_IRQS_ON  /* Note: clobbers registers r0-r29 */
-	IRQ_ENABLE(r20, r21)
-
-	/* try to single-step the current instruction */
-	PTREGS_PTR(r0, PTREGS_OFFSET_BASE)
-	jal     single_step_once
-	FEEDBACK_REENTER(interrupt_return)
-
-	/* Re-disable interrupts.  TRACE_IRQS_OFF in .Lrestore_all. */
-	IRQ_DISABLE(r20,r21)
-
-	j       .Lrestore_all
-
-.Lwork_confusion:
-	move    r0, r28
-	panic   "thread_info allwork flags unhandled on userspace resume: %#x"
-
 	STD_ENDPROC(interrupt_return)
 
 	/*
@@ -1550,7 +1470,10 @@
  * We place it in the __HEAD section to ensure it is relatively
  * near to the intvec_SWINT_1 code (reachable by a conditional branch).
  *
- * Must match register usage in do_page_fault().
+ * Our use of ATOMIC_LOCK_REG here must match do_page_fault_ics().
+ *
+ * As we do in lib/atomic_asm_32.S, we bypass a store if the value we
+ * would store is the same as the value we just loaded.
  */
 	__HEAD
 	.align 64
@@ -1611,17 +1534,7 @@
 	{
 	 shri	r20, r25, 32 - ATOMIC_HASH_L1_SHIFT
 	 slt_u  r23, r0, r23
-
-	 /*
-	  * Ensure that the TLB is loaded before we take out the lock.
-	  * On TILEPro, this will start fetching the value all the way
-	  * into our L1 as well (and if it gets modified before we
-	  * grab the lock, it will be invalidated from our cache
-	  * before we reload it).  On tile64, we'll start fetching it
-	  * into our L1 if we're the home, and if we're not, we'll
-	  * still at least start fetching it into the home's L2.
-	  */
-	 lw	r26, r0
+	 lw	r26, r0  /* see comment in the "#else" for the "lw r26". */
 	}
 	{
 	 s2a    r21, r20, r21
@@ -1637,18 +1550,9 @@
 	 bbs    r23, .Lcmpxchg64
 	 andi   r23, r0, 7       /* Precompute alignment for cmpxchg64. */
 	}
-
 	{
-	 /*
-	  * We very carefully align the code that actually runs with
-	  * the lock held (nine bundles) so that we know it is all in
-	  * the icache when we start.  This instruction (the jump) is
-	  * at the start of the first cache line, address zero mod 64;
-	  * we jump to somewhere in the second cache line to issue the
-	  * tns, then jump back to finish up.
-	  */
 	 s2a	ATOMIC_LOCK_REG_NAME, r25, r21
-	 j      .Lcmpxchg32_tns
+	 j      .Lcmpxchg32_tns   /* see comment in the #else for the jump. */
 	}
 
 #else /* ATOMIC_LOCKS_FOUND_VIA_TABLE() */
@@ -1713,24 +1617,25 @@
 	{
 	 /*
 	  * We very carefully align the code that actually runs with
-	  * the lock held (nine bundles) so that we know it is all in
+	  * the lock held (twelve bundles) so that we know it is all in
 	  * the icache when we start.  This instruction (the jump) is
 	  * at the start of the first cache line, address zero mod 64;
-	  * we jump to somewhere in the second cache line to issue the
-	  * tns, then jump back to finish up.
+	  * we jump to the very end of the second cache line to get that
+	  * line loaded in the icache, then fall through to issue the tns
+	  * in the third cache line, at which point it's all cached.
+	  * Note that is for performance, not correctness.
 	  */
 	 j      .Lcmpxchg32_tns
 	}
 
 #endif /* ATOMIC_LOCKS_FOUND_VIA_TABLE() */
 
-	ENTRY(__sys_cmpxchg_grab_lock)
+/* Symbol for do_page_fault_ics() to use to compare against the PC. */
+.global __sys_cmpxchg_grab_lock
+__sys_cmpxchg_grab_lock:
 
 	/*
 	 * Perform the actual cmpxchg or atomic_update.
-	 * Note that the system <arch/atomic.h> header relies on
-	 * atomic_update() to always perform an "mf", so don't make
-	 * it optional or conditional without modifying that code.
 	 */
 .Ldo_cmpxchg32:
 	{
@@ -1748,10 +1653,13 @@
 	}
 	{
 	 mvnz	r24, r23, r25    /* Use atomic_update value if appropriate. */
-	 bbns   r22, .Lcmpxchg32_mismatch
+	 bbns   r22, .Lcmpxchg32_nostore
 	}
+	seq     r22, r24, r21    /* Are we storing the value we loaded? */
+	bbs     r22, .Lcmpxchg32_nostore
 	sw      r0, r24
 
+	/* The following instruction is the start of the second cache line. */
 	/* Do slow mtspr here so the following "mf" waits less. */
 	{
 	 move   sp, r27
@@ -1759,7 +1667,6 @@
 	}
 	mf
 
-	/* The following instruction is the start of the second cache line. */
 	{
 	 move   r0, r21
 	 sw     ATOMIC_LOCK_REG_NAME, zero
@@ -1767,7 +1674,7 @@
 	iret
 
 	/* Duplicated code here in the case where we don't overlap "mf" */
-.Lcmpxchg32_mismatch:
+.Lcmpxchg32_nostore:
 	{
 	 move   r0, r21
 	 sw     ATOMIC_LOCK_REG_NAME, zero
@@ -1783,8 +1690,6 @@
 	 * and for 64-bit cmpxchg.  We provide it as a macro and put
 	 * it into both versions.  We can't share the code literally
 	 * since it depends on having the right branch-back address.
-	 * Note that the first few instructions should share the cache
-	 * line with the second half of the actual locked code.
 	 */
 	.macro  cmpxchg_lock, bitwidth
 
@@ -1810,7 +1715,7 @@
 	}
 	/*
 	 * The preceding instruction is the last thing that must be
-	 * on the second cache line.
+	 * hot in the icache before we do the "tns" above.
 	 */
 
 #ifdef CONFIG_SMP
@@ -1841,6 +1746,12 @@
 	.endm
 
 .Lcmpxchg32_tns:
+	/*
+	 * This is the last instruction on the second cache line.
+	 * The nop here loads the second line, then we fall through
+	 * to the tns to load the third line before we take the lock.
+	 */
+	nop
 	cmpxchg_lock 32
 
 	/*
diff -druN linux-2.6.39-libre/arch/tile/kernel/intvec_64.S linux-3.0-rc7-libre/arch/tile/kernel/intvec_64.S
--- linux-2.6.39-libre/arch/tile/kernel/intvec_64.S	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/tile/kernel/intvec_64.S	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,1231 @@
+/*
+ * Copyright 2011 Tilera 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, version 2.
+ *
+ *   This program is distributed in the hope that it will be useful, but
+ *   WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
+ *   NON INFRINGEMENT.  See the GNU General Public License for
+ *   more details.
+ *
+ * Linux interrupt vectors.
+ */
+
+#include <linux/linkage.h>
+#include <linux/errno.h>
+#include <linux/unistd.h>
+#include <asm/ptrace.h>
+#include <asm/thread_info.h>
+#include <asm/irqflags.h>
+#include <asm/asm-offsets.h>
+#include <asm/types.h>
+#include <hv/hypervisor.h>
+#include <arch/abi.h>
+#include <arch/interrupts.h>
+#include <arch/spr_def.h>
+
+#ifdef CONFIG_PREEMPT
+# error "No support for kernel preemption currently"
+#endif
+
+#define PTREGS_PTR(reg, ptreg) addli reg, sp, C_ABI_SAVE_AREA_SIZE + (ptreg)
+
+#define PTREGS_OFFSET_SYSCALL PTREGS_OFFSET_REG(TREG_SYSCALL_NR)
+
+
+	.macro  push_reg reg, ptr=sp, delta=-8
+	{
+	 st     \ptr, \reg
+	 addli  \ptr, \ptr, \delta
+	}
+	.endm
+
+	.macro  pop_reg reg, ptr=sp, delta=8
+	{
+	 ld     \reg, \ptr
+	 addli  \ptr, \ptr, \delta
+	}
+	.endm
+
+	.macro  pop_reg_zero reg, zreg, ptr=sp, delta=8
+	{
+	 move   \zreg, zero
+	 ld     \reg, \ptr
+	 addi   \ptr, \ptr, \delta
+	}
+	.endm
+
+	.macro  push_extra_callee_saves reg
+	PTREGS_PTR(\reg, PTREGS_OFFSET_REG(51))
+	push_reg r51, \reg
+	push_reg r50, \reg
+	push_reg r49, \reg
+	push_reg r48, \reg
+	push_reg r47, \reg
+	push_reg r46, \reg
+	push_reg r45, \reg
+	push_reg r44, \reg
+	push_reg r43, \reg
+	push_reg r42, \reg
+	push_reg r41, \reg
+	push_reg r40, \reg
+	push_reg r39, \reg
+	push_reg r38, \reg
+	push_reg r37, \reg
+	push_reg r36, \reg
+	push_reg r35, \reg
+	push_reg r34, \reg, PTREGS_OFFSET_BASE - PTREGS_OFFSET_REG(34)
+	.endm
+
+	.macro  panic str
+	.pushsection .rodata, "a"
+1:
+	.asciz  "\str"
+	.popsection
+	{
+	 moveli r0, hw2_last(1b)
+	}
+	{
+	 shl16insli r0, r0, hw1(1b)
+	}
+	{
+	 shl16insli r0, r0, hw0(1b)
+	 jal    panic
+	}
+	.endm
+
+
+#ifdef __COLLECT_LINKER_FEEDBACK__
+	.pushsection .text.intvec_feedback,"ax"
+intvec_feedback:
+	.popsection
+#endif
+
+	/*
+	 * Default interrupt handler.
+	 *
+	 * vecnum is where we'll put this code.
+	 * c_routine is the C routine we'll call.
+	 *
+	 * The C routine is passed two arguments:
+	 * - A pointer to the pt_regs state.
+	 * - The interrupt vector number.
+	 *
+	 * The "processing" argument specifies the code for processing
+	 * the interrupt. Defaults to "handle_interrupt".
+	 */
+	.macro  int_hand vecnum, vecname, c_routine, processing=handle_interrupt
+	.org    (\vecnum << 8)
+intvec_\vecname:
+	/* Temporarily save a register so we have somewhere to work. */
+
+	mtspr   SPR_SYSTEM_SAVE_K_1, r0
+	mfspr   r0, SPR_EX_CONTEXT_K_1
+
+	andi    r0, r0, SPR_EX_CONTEXT_1_1__PL_MASK  /* mask off ICS */
+
+	.ifc    \vecnum, INT_DOUBLE_FAULT
+	/*
+	 * For double-faults from user-space, fall through to the normal
+	 * register save and stack setup path.  Otherwise, it's the
+	 * hypervisor giving us one last chance to dump diagnostics, and we
+	 * branch to the kernel_double_fault routine to do so.
+	 */
+	beqz    r0, 1f
+	j       _kernel_double_fault
+1:
+	.else
+	/*
+	 * If we're coming from user-space, then set sp to the top of
+	 * the kernel stack.  Otherwise, assume sp is already valid.
+	 */
+	{
+	 bnez   r0, 0f
+	 move   r0, sp
+	}
+	.endif
+
+	.ifc    \c_routine, do_page_fault
+	/*
+	 * The page_fault handler may be downcalled directly by the
+	 * hypervisor even when Linux is running and has ICS set.
+	 *
+	 * In this case the contents of EX_CONTEXT_K_1 reflect the
+	 * previous fault and can't be relied on to choose whether or
+	 * not to reinitialize the stack pointer.  So we add a test
+	 * to see whether SYSTEM_SAVE_K_2 has the high bit set,
+	 * and if so we don't reinitialize sp, since we must be coming
+	 * from Linux.  (In fact the precise case is !(val & ~1),
+	 * but any Linux PC has to have the high bit set.)
+	 *
+	 * Note that the hypervisor *always* sets SYSTEM_SAVE_K_2 for
+	 * any path that turns into a downcall to one of our TLB handlers.
+	 *
+	 * FIXME: if we end up never using this path, perhaps we should
+	 * prevent the hypervisor from generating downcalls in this case.
+	 * The advantage of getting a downcall is we can panic in Linux.
+	 */
+	mfspr   r0, SPR_SYSTEM_SAVE_K_2
+	{
+	 bltz   r0, 0f    /* high bit in S_S_1_2 is for a PC to use */
+	 move   r0, sp
+	}
+	.endif
+
+
+	/*
+	 * SYSTEM_SAVE_K_0 holds the cpu number in the low bits, and
+	 * the current stack top in the higher bits.  So we recover
+	 * our stack top by just masking off the low bits, then
+	 * point sp at the top aligned address on the actual stack page.
+	 */
+	mfspr   r0, SPR_SYSTEM_SAVE_K_0
+	mm      r0, zero, LOG2_THREAD_SIZE, 63
+
+0:
+	/*
+	 * Align the stack mod 64 so we can properly predict what
+	 * cache lines we need to write-hint to reduce memory fetch
+	 * latency as we enter the kernel.  The layout of memory is
+	 * as follows, with cache line 0 at the lowest VA, and cache
+	 * line 8 just below the r0 value this "andi" computes.
+	 * Note that we never write to cache line 8, and we skip
+	 * cache lines 1-3 for syscalls.
+	 *
+	 *    cache line 8: ptregs padding (two words)
+	 *    cache line 7: sp, lr, pc, ex1, faultnum, orig_r0, flags, cmpexch
+	 *    cache line 6: r46...r53 (tp)
+	 *    cache line 5: r38...r45
+	 *    cache line 4: r30...r37
+	 *    cache line 3: r22...r29
+	 *    cache line 2: r14...r21
+	 *    cache line 1: r6...r13
+	 *    cache line 0: 2 x frame, r0..r5
+	 */
+	andi    r0, r0, -64
+
+	/*
+	 * Push the first four registers on the stack, so that we can set
+	 * them to vector-unique values before we jump to the common code.
+	 *
+	 * Registers are pushed on the stack as a struct pt_regs,
+	 * with the sp initially just above the struct, and when we're
+	 * done, sp points to the base of the struct, minus
+	 * C_ABI_SAVE_AREA_SIZE, so we can directly jal to C code.
+	 *
+	 * This routine saves just the first four registers, plus the
+	 * stack context so we can do proper backtracing right away,
+	 * and defers to handle_interrupt to save the rest.
+	 * The backtracer needs pc, ex1, lr, sp, r52, and faultnum.
+	 */
+	addli   r0, r0, PTREGS_OFFSET_LR - (PTREGS_SIZE + KSTK_PTREGS_GAP)
+	wh64    r0   /* cache line 7 */
+	{
+	 st     r0, lr
+	 addli  r0, r0, PTREGS_OFFSET_SP - PTREGS_OFFSET_LR
+	}
+	{
+	 st     r0, sp
+	 addli  sp, r0, PTREGS_OFFSET_REG(52) - PTREGS_OFFSET_SP
+	}
+	wh64    sp   /* cache line 6 */
+	{
+	 st     sp, r52
+	 addli  sp, sp, PTREGS_OFFSET_REG(1) - PTREGS_OFFSET_REG(52)
+	}
+	wh64    sp   /* cache line 0 */
+	{
+	 st     sp, r1
+	 addli  sp, sp, PTREGS_OFFSET_REG(2) - PTREGS_OFFSET_REG(1)
+	}
+	{
+	 st     sp, r2
+	 addli  sp, sp, PTREGS_OFFSET_REG(3) - PTREGS_OFFSET_REG(2)
+	}
+	{
+	 st     sp, r3
+	 addli  sp, sp, PTREGS_OFFSET_PC - PTREGS_OFFSET_REG(3)
+	}
+	mfspr   r0, SPR_EX_CONTEXT_K_0
+	.ifc \processing,handle_syscall
+	/*
+	 * Bump the saved PC by one bundle so that when we return, we won't
+	 * execute the same swint instruction again.  We need to do this while
+	 * we're in the critical section.
+	 */
+	addi    r0, r0, 8
+	.endif
+	{
+	 st     sp, r0
+	 addli  sp, sp, PTREGS_OFFSET_EX1 - PTREGS_OFFSET_PC
+	}
+	mfspr   r0, SPR_EX_CONTEXT_K_1
+	{
+	 st     sp, r0
+	 addi   sp, sp, PTREGS_OFFSET_FAULTNUM - PTREGS_OFFSET_EX1
+	/*
+	 * Use r0 for syscalls so it's a temporary; use r1 for interrupts
+	 * so that it gets passed through unchanged to the handler routine.
+	 * Note that the .if conditional confusingly spans bundles.
+	 */
+	 .ifc \processing,handle_syscall
+	 movei  r0, \vecnum
+	}
+	{
+	 st     sp, r0
+	 .else
+	 movei  r1, \vecnum
+	}
+	{
+	 st     sp, r1
+	 .endif
+	 addli  sp, sp, PTREGS_OFFSET_REG(0) - PTREGS_OFFSET_FAULTNUM
+	}
+	mfspr   r0, SPR_SYSTEM_SAVE_K_1    /* Original r0 */
+	{
+	 st     sp, r0
+	 addi   sp, sp, -PTREGS_OFFSET_REG(0) - 8
+	}
+	{
+	 st     sp, zero        /* write zero into "Next SP" frame pointer */
+	 addi   sp, sp, -8      /* leave SP pointing at bottom of frame */
+	}
+	.ifc \processing,handle_syscall
+	j       handle_syscall
+	.else
+	/* Capture per-interrupt SPR context to registers. */
+	.ifc \c_routine, do_page_fault
+	mfspr   r2, SPR_SYSTEM_SAVE_K_3   /* address of page fault */
+	mfspr   r3, SPR_SYSTEM_SAVE_K_2   /* info about page fault */
+	.else
+	.ifc \vecnum, INT_ILL_TRANS
+	mfspr   r2, ILL_TRANS_REASON
+	.else
+	.ifc \vecnum, INT_DOUBLE_FAULT
+	mfspr   r2, SPR_SYSTEM_SAVE_K_2   /* double fault info from HV */
+	.else
+	.ifc \c_routine, do_trap
+	mfspr   r2, GPV_REASON
+	.else
+	.ifc \c_routine, op_handle_perf_interrupt
+	mfspr   r2, PERF_COUNT_STS
+#if CHIP_HAS_AUX_PERF_COUNTERS()
+	.else
+	.ifc \c_routine, op_handle_aux_perf_interrupt
+	mfspr   r2, AUX_PERF_COUNT_STS
+	.endif
+#endif
+	.endif
+	.endif
+	.endif
+	.endif
+	.endif
+	/* Put function pointer in r0 */
+	moveli  r0, hw2_last(\c_routine)
+	shl16insli r0, r0, hw1(\c_routine)
+	{
+	 shl16insli r0, r0, hw0(\c_routine)
+	 j       \processing
+	}
+	.endif
+	ENDPROC(intvec_\vecname)
+
+#ifdef __COLLECT_LINKER_FEEDBACK__
+	.pushsection .text.intvec_feedback,"ax"
+	.org    (\vecnum << 5)
+	FEEDBACK_ENTER_EXPLICIT(intvec_\vecname, .intrpt1, 1 << 8)
+	jrp     lr
+	.popsection
+#endif
+
+	.endm
+
+
+	/*
+	 * Save the rest of the registers that we didn't save in the actual
+	 * vector itself.  We can't use r0-r10 inclusive here.
+	 */
+	.macro  finish_interrupt_save, function
+
+	/* If it's a syscall, save a proper orig_r0, otherwise just zero. */
+	PTREGS_PTR(r52, PTREGS_OFFSET_ORIG_R0)
+	{
+	 .ifc \function,handle_syscall
+	 st     r52, r0
+	 .else
+	 st     r52, zero
+	 .endif
+	 PTREGS_PTR(r52, PTREGS_OFFSET_TP)
+	}
+	st      r52, tp
+	{
+	 mfspr  tp, CMPEXCH_VALUE
+	 PTREGS_PTR(r52, PTREGS_OFFSET_CMPEXCH)
+	}
+
+	/*
+	 * For ordinary syscalls, we save neither caller- nor callee-
+	 * save registers, since the syscall invoker doesn't expect the
+	 * caller-saves to be saved, and the called kernel functions will
+	 * take care of saving the callee-saves for us.
+	 *
+	 * For interrupts we save just the caller-save registers.  Saving
+	 * them is required (since the "caller" can't save them).  Again,
+	 * the called kernel functions will restore the callee-save
+	 * registers for us appropriately.
+	 *
+	 * On return, we normally restore nothing special for syscalls,
+	 * and just the caller-save registers for interrupts.
+	 *
+	 * However, there are some important caveats to all this:
+	 *
+	 * - We always save a few callee-save registers to give us
+	 *   some scratchpad registers to carry across function calls.
+	 *
+	 * - fork/vfork/etc require us to save all the callee-save
+	 *   registers, which we do in PTREGS_SYSCALL_ALL_REGS, below.
+	 *
+	 * - We always save r0..r5 and r10 for syscalls, since we need
+	 *   to reload them a bit later for the actual kernel call, and
+	 *   since we might need them for -ERESTARTNOINTR, etc.
+	 *
+	 * - Before invoking a signal handler, we save the unsaved
+	 *   callee-save registers so they are visible to the
+	 *   signal handler or any ptracer.
+	 *
+	 * - If the unsaved callee-save registers are modified, we set
+	 *   a bit in pt_regs so we know to reload them from pt_regs
+	 *   and not just rely on the kernel function unwinding.
+	 *   (Done for ptrace register writes and SA_SIGINFO handler.)
+	 */
+	{
+	 st     r52, tp
+	 PTREGS_PTR(r52, PTREGS_OFFSET_REG(33))
+	}
+	wh64    r52    /* cache line 4 */
+	push_reg r33, r52
+	push_reg r32, r52
+	push_reg r31, r52
+	.ifc \function,handle_syscall
+	push_reg r30, r52, PTREGS_OFFSET_SYSCALL - PTREGS_OFFSET_REG(30)
+	push_reg TREG_SYSCALL_NR_NAME, r52, \
+	  PTREGS_OFFSET_REG(5) - PTREGS_OFFSET_SYSCALL
+	.else
+
+	push_reg r30, r52, PTREGS_OFFSET_REG(29) - PTREGS_OFFSET_REG(30)
+	wh64    r52   /* cache line 3 */
+	push_reg r29, r52
+	push_reg r28, r52
+	push_reg r27, r52
+	push_reg r26, r52
+	push_reg r25, r52
+	push_reg r24, r52
+	push_reg r23, r52
+	push_reg r22, r52
+	wh64    r52   /* cache line 2 */
+	push_reg r21, r52
+	push_reg r20, r52
+	push_reg r19, r52
+	push_reg r18, r52
+	push_reg r17, r52
+	push_reg r16, r52
+	push_reg r15, r52
+	push_reg r14, r52
+	wh64    r52   /* cache line 1 */
+	push_reg r13, r52
+	push_reg r12, r52
+	push_reg r11, r52
+	push_reg r10, r52
+	push_reg r9, r52
+	push_reg r8, r52
+	push_reg r7, r52
+	push_reg r6, r52
+
+	.endif
+
+	push_reg r5, r52
+	st      r52, r4
+
+	/* Load tp with our per-cpu offset. */
+#ifdef CONFIG_SMP
+	{
+	 mfspr  r20, SPR_SYSTEM_SAVE_K_0
+	 moveli r21, hw2_last(__per_cpu_offset)
+	}
+	{
+	 shl16insli r21, r21, hw1(__per_cpu_offset)
+	 bfextu r20, r20, 0, LOG2_THREAD_SIZE-1
+	}
+	shl16insli r21, r21, hw0(__per_cpu_offset)
+	shl3add r20, r20, r21
+	ld      tp, r20
+#else
+	move    tp, zero
+#endif
+
+	/*
+	 * If we will be returning to the kernel, we will need to
+	 * reset the interrupt masks to the state they had before.
+	 * Set DISABLE_IRQ in flags iff we came from PL1 with irqs disabled.
+	 */
+	mfspr   r32, SPR_EX_CONTEXT_K_1
+	{
+	 andi   r32, r32, SPR_EX_CONTEXT_1_1__PL_MASK  /* mask off ICS */
+	 PTREGS_PTR(r21, PTREGS_OFFSET_FLAGS)
+	}
+	beqzt   r32, 1f       /* zero if from user space */
+	IRQS_DISABLED(r32)    /* zero if irqs enabled */
+#if PT_FLAGS_DISABLE_IRQ != 1
+# error Value of IRQS_DISABLED used to set PT_FLAGS_DISABLE_IRQ; fix
+#endif
+1:
+	.ifnc \function,handle_syscall
+	/* Record the fact that we saved the caller-save registers above. */
+	ori     r32, r32, PT_FLAGS_CALLER_SAVES
+	.endif
+	st      r21, r32
+
+#ifdef __COLLECT_LINKER_FEEDBACK__
+	/*
+	 * Notify the feedback routines that we were in the
+	 * appropriate fixed interrupt vector area.  Note that we
+	 * still have ICS set at this point, so we can't invoke any
+	 * atomic operations or we will panic.  The feedback
+	 * routines internally preserve r0..r10 and r30 up.
+	 */
+	.ifnc \function,handle_syscall
+	shli    r20, r1, 5
+	.else
+	moveli  r20, INT_SWINT_1 << 5
+	.endif
+	moveli  r21, hw2_last(intvec_feedback)
+	shl16insli r21, r21, hw1(intvec_feedback)
+	shl16insli r21, r21, hw0(intvec_feedback)
+	add     r20, r20, r21
+	jalr    r20
+
+	/* And now notify the feedback routines that we are here. */
+	FEEDBACK_ENTER(\function)
+#endif
+
+	/*
+	 * we've captured enough state to the stack (including in
+	 * particular our EX_CONTEXT state) that we can now release
+	 * the interrupt critical section and replace it with our
+	 * standard "interrupts disabled" mask value.  This allows
+	 * synchronous interrupts (and profile interrupts) to punch
+	 * through from this point onwards.
+	 */
+	.ifc \function,handle_nmi
+	IRQ_DISABLE_ALL(r20)
+	.else
+	IRQ_DISABLE(r20, r21)
+	.endif
+	mtspr   INTERRUPT_CRITICAL_SECTION, zero
+
+	/*
+	 * Prepare the first 256 stack bytes to be rapidly accessible
+	 * without having to fetch the background data.
+	 */
+	addi    r52, sp, -64
+	{
+	 wh64   r52
+	 addi   r52, r52, -64
+	}
+	{
+	 wh64   r52
+	 addi   r52, r52, -64
+	}
+	{
+	 wh64   r52
+	 addi   r52, r52, -64
+	}
+	wh64    r52
+
+#ifdef CONFIG_TRACE_IRQFLAGS
+	.ifnc \function,handle_nmi
+	/*
+	 * We finally have enough state set up to notify the irq
+	 * tracing code that irqs were disabled on entry to the handler.
+	 * The TRACE_IRQS_OFF call clobbers registers r0-r29.
+	 * For syscalls, we already have the register state saved away
+	 * on the stack, so we don't bother to do any register saves here,
+	 * and later we pop the registers back off the kernel stack.
+	 * For interrupt handlers, save r0-r3 in callee-saved registers.
+	 */
+	.ifnc \function,handle_syscall
+	{ move r30, r0; move r31, r1 }
+	{ move r32, r2; move r33, r3 }
+	.endif
+	TRACE_IRQS_OFF
+	.ifnc \function,handle_syscall
+	{ move r0, r30; move r1, r31 }
+	{ move r2, r32; move r3, r33 }
+	.endif
+	.endif
+#endif
+
+	.endm
+
+	/*
+	 * Redispatch a downcall.
+	 */
+	.macro  dc_dispatch vecnum, vecname
+	.org    (\vecnum << 8)
+intvec_\vecname:
+	j       hv_downcall_dispatch
+	ENDPROC(intvec_\vecname)
+	.endm
+
+	/*
+	 * Common code for most interrupts.  The C function we're eventually
+	 * going to is in r0, and the faultnum is in r1; the original
+	 * values for those registers are on the stack.
+	 */
+	.pushsection .text.handle_interrupt,"ax"
+handle_interrupt:
+	finish_interrupt_save handle_interrupt
+
+	/* Jump to the C routine; it should enable irqs as soon as possible. */
+	{
+	 jalr   r0
+	 PTREGS_PTR(r0, PTREGS_OFFSET_BASE)
+	}
+	FEEDBACK_REENTER(handle_interrupt)
+	{
+	 movei  r30, 0   /* not an NMI */
+	 j      interrupt_return
+	}
+	STD_ENDPROC(handle_interrupt)
+
+/*
+ * This routine takes a boolean in r30 indicating if this is an NMI.
+ * If so, we also expect a boolean in r31 indicating whether to
+ * re-enable the oprofile interrupts.
+ */
+STD_ENTRY(interrupt_return)
+	/* If we're resuming to kernel space, don't check thread flags. */
+	{
+	 bnez   r30, .Lrestore_all  /* NMIs don't special-case user-space */
+	 PTREGS_PTR(r29, PTREGS_OFFSET_EX1)
+	}
+	ld      r29, r29
+	andi    r29, r29, SPR_EX_CONTEXT_1_1__PL_MASK  /* mask off ICS */
+	{
+	 beqzt  r29, .Lresume_userspace
+	 PTREGS_PTR(r29, PTREGS_OFFSET_PC)
+	}
+
+	/* If we're resuming to _cpu_idle_nap, bump PC forward by 8. */
+	moveli  r27, hw2_last(_cpu_idle_nap)
+	{
+	 ld     r28, r29
+	 shl16insli r27, r27, hw1(_cpu_idle_nap)
+	}
+	{
+	 shl16insli r27, r27, hw0(_cpu_idle_nap)
+	}
+	{
+	 cmpeq  r27, r27, r28
+	}
+	{
+	 blbc   r27, .Lrestore_all
+	 addi   r28, r28, 8
+	}
+	st      r29, r28
+	j       .Lrestore_all
+
+.Lresume_userspace:
+	FEEDBACK_REENTER(interrupt_return)
+
+	/*
+	 * Disable interrupts so as to make sure we don't
+	 * miss an interrupt that sets any of the thread flags (like
+	 * need_resched or sigpending) between sampling and the iret.
+	 * Routines like schedule() or do_signal() may re-enable
+	 * interrupts before returning.
+	 */
+	IRQ_DISABLE(r20, r21)
+	TRACE_IRQS_OFF  /* Note: clobbers registers r0-r29 */
+
+	/* Get base of stack in r32; note r30/31 are used as arguments here. */
+	GET_THREAD_INFO(r32)
+
+
+	/* Check to see if there is any work to do before returning to user. */
+	{
+	 addi   r29, r32, THREAD_INFO_FLAGS_OFFSET
+	 moveli r1, hw1_last(_TIF_ALLWORK_MASK)
+	}
+	{
+	 ld     r29, r29
+	 shl16insli r1, r1, hw0(_TIF_ALLWORK_MASK)
+	}
+	and     r1, r29, r1
+	beqzt   r1, .Lrestore_all
+
+	/*
+	 * Make sure we have all the registers saved for signal
+	 * handling or single-step.  Call out to C code to figure out
+	 * exactly what we need to do for each flag bit, then if
+	 * necessary, reload the flags and recheck.
+	 */
+	push_extra_callee_saves r0
+	{
+	 PTREGS_PTR(r0, PTREGS_OFFSET_BASE)
+	 jal    do_work_pending
+	}
+	bnez    r0, .Lresume_userspace
+
+	/*
+	 * In the NMI case we
+	 * omit the call to single_process_check_nohz, which normally checks
+	 * to see if we should start or stop the scheduler tick, because
+	 * we can't call arbitrary Linux code from an NMI context.
+	 * We always call the homecache TLB deferral code to re-trigger
+	 * the deferral mechanism.
+	 *
+	 * The other chunk of responsibility this code has is to reset the
+	 * interrupt masks appropriately to reset irqs and NMIs.  We have
+	 * to call TRACE_IRQS_OFF and TRACE_IRQS_ON to support all the
+	 * lockdep-type stuff, but we can't set ICS until afterwards, since
+	 * ICS can only be used in very tight chunks of code to avoid
+	 * tripping over various assertions that it is off.
+	 */
+.Lrestore_all:
+	PTREGS_PTR(r0, PTREGS_OFFSET_EX1)
+	{
+	 ld      r0, r0
+	 PTREGS_PTR(r32, PTREGS_OFFSET_FLAGS)
+	}
+	{
+	 andi   r0, r0, SPR_EX_CONTEXT_1_1__PL_MASK
+	 ld     r32, r32
+	}
+	bnez    r0, 1f
+	j       2f
+#if PT_FLAGS_DISABLE_IRQ != 1
+# error Assuming PT_FLAGS_DISABLE_IRQ == 1 so we can use blbct below
+#endif
+1:	blbct   r32, 2f
+	IRQ_DISABLE(r20,r21)
+	TRACE_IRQS_OFF
+	movei   r0, 1
+	mtspr   INTERRUPT_CRITICAL_SECTION, r0
+	beqzt   r30, .Lrestore_regs
+	j       3f
+2:	TRACE_IRQS_ON
+	movei   r0, 1
+	mtspr   INTERRUPT_CRITICAL_SECTION, r0
+	IRQ_ENABLE(r20, r21)
+	beqzt   r30, .Lrestore_regs
+3:
+
+
+	/*
+	 * We now commit to returning from this interrupt, since we will be
+	 * doing things like setting EX_CONTEXT SPRs and unwinding the stack
+	 * frame.  No calls should be made to any other code after this point.
+	 * This code should only be entered with ICS set.
+	 * r32 must still be set to ptregs.flags.
+	 * We launch loads to each cache line separately first, so we can
+	 * get some parallelism out of the memory subsystem.
+	 * We start zeroing caller-saved registers throughout, since
+	 * that will save some cycles if this turns out to be a syscall.
+	 */
+.Lrestore_regs:
+	FEEDBACK_REENTER(interrupt_return)   /* called from elsewhere */
+
+	/*
+	 * Rotate so we have one high bit and one low bit to test.
+	 * - low bit says whether to restore all the callee-saved registers,
+	 *   or just r30-r33, and r52 up.
+	 * - high bit (i.e. sign bit) says whether to restore all the
+	 *   caller-saved registers, or just r0.
+	 */
+#if PT_FLAGS_CALLER_SAVES != 2 || PT_FLAGS_RESTORE_REGS != 4
+# error Rotate trick does not work :-)
+#endif
+	{
+	 rotli  r20, r32, 62
+	 PTREGS_PTR(sp, PTREGS_OFFSET_REG(0))
+	}
+
+	/*
+	 * Load cache lines 0, 4, 6 and 7, in that order, then use
+	 * the last loaded value, which makes it likely that the other
+	 * cache lines have also loaded, at which point we should be
+	 * able to safely read all the remaining words on those cache
+	 * lines without waiting for the memory subsystem.
+	 */
+	pop_reg r0, sp, PTREGS_OFFSET_REG(30) - PTREGS_OFFSET_REG(0)
+	pop_reg r30, sp, PTREGS_OFFSET_REG(52) - PTREGS_OFFSET_REG(30)
+	pop_reg_zero r52, r3, sp, PTREGS_OFFSET_CMPEXCH - PTREGS_OFFSET_REG(52)
+	pop_reg_zero r21, r27, sp, PTREGS_OFFSET_EX1 - PTREGS_OFFSET_CMPEXCH
+	pop_reg_zero lr, r2, sp, PTREGS_OFFSET_PC - PTREGS_OFFSET_EX1
+	{
+	 mtspr  CMPEXCH_VALUE, r21
+	 move   r4, zero
+	}
+	pop_reg r21, sp, PTREGS_OFFSET_REG(31) - PTREGS_OFFSET_PC
+	{
+	 mtspr  SPR_EX_CONTEXT_K_1, lr
+	 andi   lr, lr, SPR_EX_CONTEXT_1_1__PL_MASK  /* mask off ICS */
+	}
+	{
+	 mtspr  SPR_EX_CONTEXT_K_0, r21
+	 move   r5, zero
+	}
+
+	/* Restore callee-saveds that we actually use. */
+	pop_reg_zero r31, r6
+	pop_reg_zero r32, r7
+	pop_reg_zero r33, r8, sp, PTREGS_OFFSET_REG(29) - PTREGS_OFFSET_REG(33)
+
+	/*
+	 * If we modified other callee-saveds, restore them now.
+	 * This is rare, but could be via ptrace or signal handler.
+	 */
+	{
+	 move   r9, zero
+	 blbs   r20, .Lrestore_callees
+	}
+.Lcontinue_restore_regs:
+
+	/* Check if we're returning from a syscall. */
+	{
+	 move   r10, zero
+	 bltzt  r20, 1f  /* no, so go restore callee-save registers */
+	}
+
+	/*
+	 * Check if we're returning to userspace.
+	 * Note that if we're not, we don't worry about zeroing everything.
+	 */
+	{
+	 addli  sp, sp, PTREGS_OFFSET_LR - PTREGS_OFFSET_REG(29)
+	 bnez   lr, .Lkernel_return
+	}
+
+	/*
+	 * On return from syscall, we've restored r0 from pt_regs, but we
+	 * clear the remainder of the caller-saved registers.  We could
+	 * restore the syscall arguments, but there's not much point,
+	 * and it ensures user programs aren't trying to use the
+	 * caller-saves if we clear them, as well as avoiding leaking
+	 * kernel pointers into userspace.
+	 */
+	pop_reg_zero lr, r11, sp, PTREGS_OFFSET_TP - PTREGS_OFFSET_LR
+	pop_reg_zero tp, r12, sp, PTREGS_OFFSET_SP - PTREGS_OFFSET_TP
+	{
+	 ld     sp, sp
+	 move   r13, zero
+	 move   r14, zero
+	}
+	{ move r15, zero; move r16, zero }
+	{ move r17, zero; move r18, zero }
+	{ move r19, zero; move r20, zero }
+	{ move r21, zero; move r22, zero }
+	{ move r23, zero; move r24, zero }
+	{ move r25, zero; move r26, zero }
+
+	/* Set r1 to errno if we are returning an error, otherwise zero. */
+	{
+	 moveli r29, 4096
+	 sub    r1, zero, r0
+	}
+	{
+	 move   r28, zero
+	 cmpltu r29, r1, r29
+	}
+	{
+	 mnz    r1, r29, r1
+	 move   r29, zero
+	}
+	iret
+
+	/*
+	 * Not a syscall, so restore caller-saved registers.
+	 * First kick off loads for cache lines 1-3, which we're touching
+	 * for the first time here.
+	 */
+	.align 64
+1:	pop_reg r29, sp, PTREGS_OFFSET_REG(21) - PTREGS_OFFSET_REG(29)
+	pop_reg r21, sp, PTREGS_OFFSET_REG(13) - PTREGS_OFFSET_REG(21)
+	pop_reg r13, sp, PTREGS_OFFSET_REG(1) - PTREGS_OFFSET_REG(13)
+	pop_reg r1
+	pop_reg r2
+	pop_reg r3
+	pop_reg r4
+	pop_reg r5
+	pop_reg r6
+	pop_reg r7
+	pop_reg r8
+	pop_reg r9
+	pop_reg r10
+	pop_reg r11
+	pop_reg r12, sp, 16
+	/* r13 already restored above */
+	pop_reg r14
+	pop_reg r15
+	pop_reg r16
+	pop_reg r17
+	pop_reg r18
+	pop_reg r19
+	pop_reg r20, sp, 16
+	/* r21 already restored above */
+	pop_reg r22
+	pop_reg r23
+	pop_reg r24
+	pop_reg r25
+	pop_reg r26
+	pop_reg r27
+	pop_reg r28, sp, PTREGS_OFFSET_LR - PTREGS_OFFSET_REG(28)
+	/* r29 already restored above */
+	bnez    lr, .Lkernel_return
+	pop_reg lr, sp, PTREGS_OFFSET_TP - PTREGS_OFFSET_LR
+	pop_reg tp, sp, PTREGS_OFFSET_SP - PTREGS_OFFSET_TP
+	ld      sp, sp
+	iret
+
+	/*
+	 * We can't restore tp when in kernel mode, since a thread might
+	 * have migrated from another cpu and brought a stale tp value.
+	 */
+.Lkernel_return:
+	pop_reg lr, sp, PTREGS_OFFSET_SP - PTREGS_OFFSET_LR
+	ld      sp, sp
+	iret
+
+	/* Restore callee-saved registers from r34 to r51. */
+.Lrestore_callees:
+	addli  sp, sp, PTREGS_OFFSET_REG(34) - PTREGS_OFFSET_REG(29)
+	pop_reg r34
+	pop_reg r35
+	pop_reg r36
+	pop_reg r37
+	pop_reg r38
+	pop_reg r39
+	pop_reg r40
+	pop_reg r41
+	pop_reg r42
+	pop_reg r43
+	pop_reg r44
+	pop_reg r45
+	pop_reg r46
+	pop_reg r47
+	pop_reg r48
+	pop_reg r49
+	pop_reg r50
+	pop_reg r51, sp, PTREGS_OFFSET_REG(29) - PTREGS_OFFSET_REG(51)
+	j .Lcontinue_restore_regs
+	STD_ENDPROC(interrupt_return)
+
+	/*
+	 * "NMI" interrupts mask ALL interrupts before calling the
+	 * handler, and don't check thread flags, etc., on the way
+	 * back out.  In general, the only things we do here for NMIs
+	 * are register save/restore and dataplane kernel-TLB management.
+	 * We don't (for example) deal with start/stop of the sched tick.
+	 */
+	.pushsection .text.handle_nmi,"ax"
+handle_nmi:
+	finish_interrupt_save handle_nmi
+	{
+	 jalr   r0
+	 PTREGS_PTR(r0, PTREGS_OFFSET_BASE)
+	}
+	FEEDBACK_REENTER(handle_nmi)
+	{
+	 movei  r30, 1
+	 move   r31, r0
+	}
+	j       interrupt_return
+	STD_ENDPROC(handle_nmi)
+
+	/*
+	 * Parallel code for syscalls to handle_interrupt.
+	 */
+	.pushsection .text.handle_syscall,"ax"
+handle_syscall:
+	finish_interrupt_save handle_syscall
+
+	/* Enable irqs. */
+	TRACE_IRQS_ON
+	IRQ_ENABLE(r20, r21)
+
+	/* Bump the counter for syscalls made on this tile. */
+	moveli r20, hw2_last(irq_stat + IRQ_CPUSTAT_SYSCALL_COUNT_OFFSET)
+	shl16insli r20, r20, hw1(irq_stat + IRQ_CPUSTAT_SYSCALL_COUNT_OFFSET)
+	shl16insli r20, r20, hw0(irq_stat + IRQ_CPUSTAT_SYSCALL_COUNT_OFFSET)
+	add     r20, r20, tp
+	ld4s    r21, r20
+	addi    r21, r21, 1
+	st4     r20, r21
+
+	/* Trace syscalls, if requested. */
+	GET_THREAD_INFO(r31)
+	addi	r31, r31, THREAD_INFO_FLAGS_OFFSET
+	ld	r30, r31
+	andi    r30, r30, _TIF_SYSCALL_TRACE
+	{
+	 addi   r30, r31, THREAD_INFO_STATUS_OFFSET - THREAD_INFO_FLAGS_OFFSET
+	 beqzt	r30, .Lrestore_syscall_regs
+	}
+	jal	do_syscall_trace
+	FEEDBACK_REENTER(handle_syscall)
+
+	/*
+	 * We always reload our registers from the stack at this
+	 * point.  They might be valid, if we didn't build with
+	 * TRACE_IRQFLAGS, and this isn't a dataplane tile, and we're not
+	 * doing syscall tracing, but there are enough cases now that it
+	 * seems simplest just to do the reload unconditionally.
+	 */
+.Lrestore_syscall_regs:
+	{
+	 ld     r30, r30
+	 PTREGS_PTR(r11, PTREGS_OFFSET_REG(0))
+	}
+	pop_reg r0,  r11
+	pop_reg r1,  r11
+	pop_reg r2,  r11
+	pop_reg r3,  r11
+	pop_reg r4,  r11
+	pop_reg r5,  r11, PTREGS_OFFSET_SYSCALL - PTREGS_OFFSET_REG(5)
+	{
+	 ld     TREG_SYSCALL_NR_NAME, r11
+	 moveli r21, __NR_syscalls
+	}
+
+	/* Ensure that the syscall number is within the legal range. */
+	{
+	 moveli r20, hw2(sys_call_table)
+	 blbs   r30, .Lcompat_syscall
+	}
+	{
+	 cmpltu r21, TREG_SYSCALL_NR_NAME, r21
+	 shl16insli r20, r20, hw1(sys_call_table)
+	}
+	{
+	 blbc   r21, .Linvalid_syscall
+	 shl16insli r20, r20, hw0(sys_call_table)
+	}
+.Lload_syscall_pointer:
+	shl3add r20, TREG_SYSCALL_NR_NAME, r20
+	ld      r20, r20
+
+	/* Jump to syscall handler. */
+	jalr    r20
+.Lhandle_syscall_link: /* value of "lr" after "jalr r20" above */
+
+	/*
+	 * Write our r0 onto the stack so it gets restored instead
+	 * of whatever the user had there before.
+	 * In compat mode, sign-extend r0 before storing it.
+	 */
+	{
+	 PTREGS_PTR(r29, PTREGS_OFFSET_REG(0))
+	 blbct  r30, 1f
+	}
+	addxi   r0, r0, 0
+1:	st      r29, r0
+
+.Lsyscall_sigreturn_skip:
+	FEEDBACK_REENTER(handle_syscall)
+
+	/* Do syscall trace again, if requested. */
+	ld	r30, r31
+	andi    r30, r30, _TIF_SYSCALL_TRACE
+	beqzt	r30, 1f
+	jal	do_syscall_trace
+	FEEDBACK_REENTER(handle_syscall)
+1:	j       .Lresume_userspace   /* jump into middle of interrupt_return */
+
+.Lcompat_syscall:
+	/*
+	 * Load the base of the compat syscall table in r20, and
+	 * range-check the syscall number (duplicated from 64-bit path).
+	 * Sign-extend all the user's passed arguments to make them consistent.
+	 * Also save the original "r(n)" values away in "r(11+n)" in
+	 * case the syscall table entry wants to validate them.
+	 */
+	moveli  r20, hw2(compat_sys_call_table)
+	{
+	 cmpltu r21, TREG_SYSCALL_NR_NAME, r21
+	 shl16insli r20, r20, hw1(compat_sys_call_table)
+	}
+	{
+	 blbc   r21, .Linvalid_syscall
+	 shl16insli r20, r20, hw0(compat_sys_call_table)
+	}
+	{ move r11, r0; addxi r0, r0, 0 }
+	{ move r12, r1; addxi r1, r1, 0 }
+	{ move r13, r2; addxi r2, r2, 0 }
+	{ move r14, r3; addxi r3, r3, 0 }
+	{ move r15, r4; addxi r4, r4, 0 }
+	{ move r16, r5; addxi r5, r5, 0 }
+	j .Lload_syscall_pointer
+
+.Linvalid_syscall:
+	/* Report an invalid syscall back to the user program */
+	{
+	 PTREGS_PTR(r29, PTREGS_OFFSET_REG(0))
+	 movei  r28, -ENOSYS
+	}
+	st      r29, r28
+	j       .Lresume_userspace   /* jump into middle of interrupt_return */
+	STD_ENDPROC(handle_syscall)
+
+	/* Return the address for oprofile to suppress in backtraces. */
+STD_ENTRY_SECTION(handle_syscall_link_address, .text.handle_syscall)
+	lnk     r0
+	{
+	 addli  r0, r0, .Lhandle_syscall_link - .
+	 jrp    lr
+	}
+	STD_ENDPROC(handle_syscall_link_address)
+
+STD_ENTRY(ret_from_fork)
+	jal     sim_notify_fork
+	jal     schedule_tail
+	FEEDBACK_REENTER(ret_from_fork)
+	j       .Lresume_userspace
+	STD_ENDPROC(ret_from_fork)
+
+/* Various stub interrupt handlers and syscall handlers */
+
+STD_ENTRY_LOCAL(_kernel_double_fault)
+	mfspr   r1, SPR_EX_CONTEXT_K_0
+	move    r2, lr
+	move    r3, sp
+	move    r4, r52
+	addi    sp, sp, -C_ABI_SAVE_AREA_SIZE
+	j       kernel_double_fault
+	STD_ENDPROC(_kernel_double_fault)
+
+STD_ENTRY_LOCAL(bad_intr)
+	mfspr   r2, SPR_EX_CONTEXT_K_0
+	panic   "Unhandled interrupt %#x: PC %#lx"
+	STD_ENDPROC(bad_intr)
+
+/* Put address of pt_regs in reg and jump. */
+#define PTREGS_SYSCALL(x, reg)                          \
+	STD_ENTRY(_##x);                                \
+	{                                               \
+	 PTREGS_PTR(reg, PTREGS_OFFSET_BASE);           \
+	 j      x                                       \
+	};                                              \
+	STD_ENDPROC(_##x)
+
+/*
+ * Special-case sigreturn to not write r0 to the stack on return.
+ * This is technically more efficient, but it also avoids difficulties
+ * in the 64-bit OS when handling 32-bit compat code, since we must not
+ * sign-extend r0 for the sigreturn return-value case.
+ */
+#define PTREGS_SYSCALL_SIGRETURN(x, reg)                \
+	STD_ENTRY(_##x);                                \
+	addli   lr, lr, .Lsyscall_sigreturn_skip - .Lhandle_syscall_link; \
+	{                                               \
+	 PTREGS_PTR(reg, PTREGS_OFFSET_BASE);           \
+	 j      x                                       \
+	};                                              \
+	STD_ENDPROC(_##x)
+
+PTREGS_SYSCALL(sys_execve, r3)
+PTREGS_SYSCALL(sys_sigaltstack, r2)
+PTREGS_SYSCALL_SIGRETURN(sys_rt_sigreturn, r0)
+#ifdef CONFIG_COMPAT
+PTREGS_SYSCALL(compat_sys_execve, r3)
+PTREGS_SYSCALL(compat_sys_sigaltstack, r2)
+PTREGS_SYSCALL_SIGRETURN(compat_sys_rt_sigreturn, r0)
+#endif
+
+/* Save additional callee-saves to pt_regs, put address in r4 and jump. */
+STD_ENTRY(_sys_clone)
+	push_extra_callee_saves r4
+	j       sys_clone
+	STD_ENDPROC(_sys_clone)
+
+/* The single-step support may need to read all the registers. */
+int_unalign:
+	push_extra_callee_saves r0
+	j       do_trap
+
+/* Include .intrpt1 array of interrupt vectors */
+	.section ".intrpt1", "ax"
+
+#define op_handle_perf_interrupt bad_intr
+#define op_handle_aux_perf_interrupt bad_intr
+
+#ifndef CONFIG_HARDWALL
+#define do_hardwall_trap bad_intr
+#endif
+
+	int_hand     INT_MEM_ERROR, MEM_ERROR, bad_intr
+	int_hand     INT_SINGLE_STEP_3, SINGLE_STEP_3, bad_intr
+#if CONFIG_KERNEL_PL == 2
+	int_hand     INT_SINGLE_STEP_2, SINGLE_STEP_2, gx_singlestep_handle
+	int_hand     INT_SINGLE_STEP_1, SINGLE_STEP_1, bad_intr
+#else
+	int_hand     INT_SINGLE_STEP_2, SINGLE_STEP_2, bad_intr
+	int_hand     INT_SINGLE_STEP_1, SINGLE_STEP_1, gx_singlestep_handle
+#endif
+	int_hand     INT_SINGLE_STEP_0, SINGLE_STEP_0, bad_intr
+	int_hand     INT_IDN_COMPLETE, IDN_COMPLETE, bad_intr
+	int_hand     INT_UDN_COMPLETE, UDN_COMPLETE, bad_intr
+	int_hand     INT_ITLB_MISS, ITLB_MISS, do_page_fault
+	int_hand     INT_ILL, ILL, do_trap
+	int_hand     INT_GPV, GPV, do_trap
+	int_hand     INT_IDN_ACCESS, IDN_ACCESS, do_trap
+	int_hand     INT_UDN_ACCESS, UDN_ACCESS, do_trap
+	int_hand     INT_SWINT_3, SWINT_3, do_trap
+	int_hand     INT_SWINT_2, SWINT_2, do_trap
+	int_hand     INT_SWINT_1, SWINT_1, SYSCALL, handle_syscall
+	int_hand     INT_SWINT_0, SWINT_0, do_trap
+	int_hand     INT_ILL_TRANS, ILL_TRANS, do_trap
+	int_hand     INT_UNALIGN_DATA, UNALIGN_DATA, int_unalign
+	int_hand     INT_DTLB_MISS, DTLB_MISS, do_page_fault
+	int_hand     INT_DTLB_ACCESS, DTLB_ACCESS, do_page_fault
+	int_hand     INT_IDN_FIREWALL, IDN_FIREWALL, bad_intr
+	int_hand     INT_UDN_FIREWALL, UDN_FIREWALL, do_hardwall_trap
+	int_hand     INT_TILE_TIMER, TILE_TIMER, do_timer_interrupt
+	int_hand     INT_IDN_TIMER, IDN_TIMER, bad_intr
+	int_hand     INT_UDN_TIMER, UDN_TIMER, bad_intr
+	int_hand     INT_IDN_AVAIL, IDN_AVAIL, bad_intr
+	int_hand     INT_UDN_AVAIL, UDN_AVAIL, bad_intr
+	int_hand     INT_IPI_3, IPI_3, bad_intr
+#if CONFIG_KERNEL_PL == 2
+	int_hand     INT_IPI_2, IPI_2, tile_dev_intr
+	int_hand     INT_IPI_1, IPI_1, bad_intr
+#else
+	int_hand     INT_IPI_2, IPI_2, bad_intr
+	int_hand     INT_IPI_1, IPI_1, tile_dev_intr
+#endif
+	int_hand     INT_IPI_0, IPI_0, bad_intr
+	int_hand     INT_PERF_COUNT, PERF_COUNT, \
+		     op_handle_perf_interrupt, handle_nmi
+	int_hand     INT_AUX_PERF_COUNT, AUX_PERF_COUNT, \
+		     op_handle_perf_interrupt, handle_nmi
+	int_hand     INT_INTCTRL_3, INTCTRL_3, bad_intr
+#if CONFIG_KERNEL_PL == 2
+	dc_dispatch  INT_INTCTRL_2, INTCTRL_2
+	int_hand     INT_INTCTRL_1, INTCTRL_1, bad_intr
+#else
+	int_hand     INT_INTCTRL_2, INTCTRL_2, bad_intr
+	dc_dispatch  INT_INTCTRL_1, INTCTRL_1
+#endif
+	int_hand     INT_INTCTRL_0, INTCTRL_0, bad_intr
+	int_hand     INT_MESSAGE_RCV_DWNCL, MESSAGE_RCV_DWNCL, \
+		     hv_message_intr
+	int_hand     INT_DEV_INTR_DWNCL, DEV_INTR_DWNCL, bad_intr
+	int_hand     INT_I_ASID, I_ASID, bad_intr
+	int_hand     INT_D_ASID, D_ASID, bad_intr
+	int_hand     INT_DOUBLE_FAULT, DOUBLE_FAULT, do_trap
+
+	/* Synthetic interrupt delivered only by the simulator */
+	int_hand     INT_BREAKPOINT, BREAKPOINT, do_breakpoint
diff -druN linux-2.6.39-libre/arch/tile/kernel/Makefile linux-3.0-rc7-libre/arch/tile/kernel/Makefile
--- linux-2.6.39-libre/arch/tile/kernel/Makefile	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/tile/kernel/Makefile	2011-07-11 19:51:52.000000000 -0400
@@ -5,7 +5,7 @@
 extra-y := vmlinux.lds head_$(BITS).o
 obj-y := backtrace.o entry.o init_task.o irq.o messaging.o \
 	pci-dma.o proc.o process.o ptrace.o reboot.o \
-	setup.o signal.o single_step.o stack.o sys.o time.o traps.o \
+	setup.o signal.o single_step.o stack.o sys.o sysfs.o time.o traps.o \
 	intvec_$(BITS).o regs_$(BITS).o tile-desc_$(BITS).o
 
 obj-$(CONFIG_HARDWALL)		+= hardwall.o
diff -druN linux-2.6.39-libre/arch/tile/kernel/module.c linux-3.0-rc7-libre/arch/tile/kernel/module.c
--- linux-2.6.39-libre/arch/tile/kernel/module.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/tile/kernel/module.c	2011-07-11 19:51:52.000000000 -0400
@@ -22,6 +22,7 @@
 #include <linux/kernel.h>
 #include <asm/opcode-tile.h>
 #include <asm/pgtable.h>
+#include <asm/homecache.h>
 
 #ifdef __tilegx__
 # define Elf_Rela Elf64_Rela
@@ -86,8 +87,13 @@
 void module_free(struct module *mod, void *module_region)
 {
 	vfree(module_region);
+
+	/* Globally flush the L1 icache. */
+	flush_remote(0, HV_FLUSH_EVICT_L1I, cpu_online_mask,
+		     0, 0, 0, NULL, NULL, 0);
+
 	/*
-	 * FIXME: If module_region == mod->init_region, trim exception
+	 * FIXME: If module_region == mod->module_init, trim exception
 	 * table entries.
 	 */
 }
diff -druN linux-2.6.39-libre/arch/tile/kernel/pci.c linux-3.0-rc7-libre/arch/tile/kernel/pci.c
--- linux-2.6.39-libre/arch/tile/kernel/pci.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/tile/kernel/pci.c	2011-07-11 19:51:52.000000000 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright 2010 Tilera Corporation. All Rights Reserved.
+ * Copyright 2011 Tilera 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
@@ -59,6 +59,7 @@
 
 static struct pci_controller controllers[TILE_NUM_PCIE];
 static int num_controllers;
+static int pci_scan_flags[TILE_NUM_PCIE];
 
 static struct pci_ops tile_cfg_ops;
 
@@ -79,7 +80,7 @@
  * controller_id is the controller number, config type is 0 or 1 for
  * config0 or config1 operations.
  */
-static int __init tile_pcie_open(int controller_id, int config_type)
+static int __devinit tile_pcie_open(int controller_id, int config_type)
 {
 	char filename[32];
 	int fd;
@@ -95,7 +96,7 @@
 /*
  * Get the IRQ numbers from the HV and set up the handlers for them.
  */
-static int __init tile_init_irqs(int controller_id,
+static int __devinit tile_init_irqs(int controller_id,
 				 struct pci_controller *controller)
 {
 	char filename[32];
@@ -139,71 +140,74 @@
  *
  * Returns the number of controllers discovered.
  */
-int __init tile_pci_init(void)
+int __devinit tile_pci_init(void)
 {
 	int i;
 
 	pr_info("PCI: Searching for controllers...\n");
 
+	/* Re-init number of PCIe controllers to support hot-plug feature. */
+	num_controllers = 0;
+
 	/* Do any configuration we need before using the PCIe */
 
 	for (i = 0; i < TILE_NUM_PCIE; i++) {
-		int hv_cfg_fd0 = -1;
-		int hv_cfg_fd1 = -1;
-		int hv_mem_fd = -1;
-		char name[32];
-		struct pci_controller *controller;
-
 		/*
-		 * Open the fd to the HV.  If it fails then this
-		 * device doesn't exist.
+		 * To see whether we need a real config op based on
+		 * the results of pcibios_init(), to support PCIe hot-plug.
 		 */
-		hv_cfg_fd0 = tile_pcie_open(i, 0);
-		if (hv_cfg_fd0 < 0)
-			continue;
-		hv_cfg_fd1 = tile_pcie_open(i, 1);
-		if (hv_cfg_fd1 < 0) {
-			pr_err("PCI: Couldn't open config fd to HV "
-			    "for controller %d\n", i);
-			goto err_cont;
-		}
+		if (pci_scan_flags[i] == 0) {
+			int hv_cfg_fd0 = -1;
+			int hv_cfg_fd1 = -1;
+			int hv_mem_fd = -1;
+			char name[32];
+			struct pci_controller *controller;
 
-		sprintf(name, "pcie/%d/mem", i);
-		hv_mem_fd = hv_dev_open((HV_VirtAddr)name, 0);
-		if (hv_mem_fd < 0) {
-			pr_err("PCI: Could not open mem fd to HV!\n");
-			goto err_cont;
-		}
+			/*
+			 * Open the fd to the HV.  If it fails then this
+			 * device doesn't exist.
+			 */
+			hv_cfg_fd0 = tile_pcie_open(i, 0);
+			if (hv_cfg_fd0 < 0)
+				continue;
+			hv_cfg_fd1 = tile_pcie_open(i, 1);
+			if (hv_cfg_fd1 < 0) {
+				pr_err("PCI: Couldn't open config fd to HV "
+				    "for controller %d\n", i);
+				goto err_cont;
+			}
 
-		pr_info("PCI: Found PCI controller #%d\n", i);
+			sprintf(name, "pcie/%d/mem", i);
+			hv_mem_fd = hv_dev_open((HV_VirtAddr)name, 0);
+			if (hv_mem_fd < 0) {
+				pr_err("PCI: Could not open mem fd to HV!\n");
+				goto err_cont;
+			}
 
-		controller = &controllers[num_controllers];
+			pr_info("PCI: Found PCI controller #%d\n", i);
 
-		if (tile_init_irqs(i, controller)) {
-			pr_err("PCI: Could not initialize "
-			       "IRQs, aborting.\n");
-			goto err_cont;
-		}
+			controller = &controllers[i];
 
-		controller->index = num_controllers;
-		controller->hv_cfg_fd[0] = hv_cfg_fd0;
-		controller->hv_cfg_fd[1] = hv_cfg_fd1;
-		controller->hv_mem_fd = hv_mem_fd;
-		controller->first_busno = 0;
-		controller->last_busno = 0xff;
-		controller->ops = &tile_cfg_ops;
+			controller->index = i;
+			controller->hv_cfg_fd[0] = hv_cfg_fd0;
+			controller->hv_cfg_fd[1] = hv_cfg_fd1;
+			controller->hv_mem_fd = hv_mem_fd;
+			controller->first_busno = 0;
+			controller->last_busno = 0xff;
+			controller->ops = &tile_cfg_ops;
 
-		num_controllers++;
-		continue;
+			num_controllers++;
+			continue;
 
 err_cont:
-		if (hv_cfg_fd0 >= 0)
-			hv_dev_close(hv_cfg_fd0);
-		if (hv_cfg_fd1 >= 0)
-			hv_dev_close(hv_cfg_fd1);
-		if (hv_mem_fd >= 0)
-			hv_dev_close(hv_mem_fd);
-		continue;
+			if (hv_cfg_fd0 >= 0)
+				hv_dev_close(hv_cfg_fd0);
+			if (hv_cfg_fd1 >= 0)
+				hv_dev_close(hv_cfg_fd1);
+			if (hv_mem_fd >= 0)
+				hv_dev_close(hv_mem_fd);
+			continue;
+		}
 	}
 
 	/*
@@ -232,7 +236,7 @@
 }
 
 
-static void __init fixup_read_and_payload_sizes(void)
+static void __devinit fixup_read_and_payload_sizes(void)
 {
 	struct pci_dev *dev = NULL;
 	int smallest_max_payload = 0x1; /* Tile maxes out at 256 bytes. */
@@ -282,7 +286,7 @@
  * The controllers have been set up by the time we get here, by a call to
  * tile_pci_init.
  */
-static int __init pcibios_init(void)
+int __devinit pcibios_init(void)
 {
 	int i;
 
@@ -296,25 +300,36 @@
 	mdelay(250);
 
 	/* Scan all of the recorded PCI controllers.  */
-	for (i = 0; i < num_controllers; i++) {
-		struct pci_controller *controller = &controllers[i];
-		struct pci_bus *bus;
-
-		pr_info("PCI: initializing controller #%d\n", i);
-
+	for (i = 0; i < TILE_NUM_PCIE; i++) {
 		/*
-		 * This comes from the generic Linux PCI driver.
-		 *
-		 * It reads the PCI tree for this bus into the Linux
-		 * data structures.
-		 *
-		 * This is inlined in linux/pci.h and calls into
-		 * pci_scan_bus_parented() in probe.c.
+		 * Do real pcibios init ops if the controller is initialized
+		 * by tile_pci_init() successfully and not initialized by
+		 * pcibios_init() yet to support PCIe hot-plug.
 		 */
-		bus = pci_scan_bus(0, controller->ops, controller);
-		controller->root_bus = bus;
-		controller->last_busno = bus->subordinate;
+		if (pci_scan_flags[i] == 0 && controllers[i].ops != NULL) {
+			struct pci_controller *controller = &controllers[i];
+			struct pci_bus *bus;
+
+			if (tile_init_irqs(i, controller)) {
+				pr_err("PCI: Could not initialize IRQs\n");
+				continue;
+			}
+
+			pr_info("PCI: initializing controller #%d\n", i);
 
+			/*
+			 * This comes from the generic Linux PCI driver.
+			 *
+			 * It reads the PCI tree for this bus into the Linux
+			 * data structures.
+			 *
+			 * This is inlined in linux/pci.h and calls into
+			 * pci_scan_bus_parented() in probe.c.
+			 */
+			bus = pci_scan_bus(0, controller->ops, controller);
+			controller->root_bus = bus;
+			controller->last_busno = bus->subordinate;
+		}
 	}
 
 	/* Do machine dependent PCI interrupt routing */
@@ -326,34 +341,45 @@
 	 * It allocates all of the resources (I/O memory, etc)
 	 * associated with the devices read in above.
 	 */
-
 	pci_assign_unassigned_resources();
 
 	/* Configure the max_read_size and max_payload_size values. */
 	fixup_read_and_payload_sizes();
 
 	/* Record the I/O resources in the PCI controller structure. */
-	for (i = 0; i < num_controllers; i++) {
-		struct pci_bus *root_bus = controllers[i].root_bus;
-		struct pci_bus *next_bus;
-		struct pci_dev *dev;
+	for (i = 0; i < TILE_NUM_PCIE; i++) {
+		/*
+		 * Do real pcibios init ops if the controller is initialized
+		 * by tile_pci_init() successfully and not initialized by
+		 * pcibios_init() yet to support PCIe hot-plug.
+		 */
+		if (pci_scan_flags[i] == 0 && controllers[i].ops != NULL) {
+			struct pci_bus *root_bus = controllers[i].root_bus;
+			struct pci_bus *next_bus;
+			struct pci_dev *dev;
 
-		list_for_each_entry(dev, &root_bus->devices, bus_list) {
-			/* Find the PCI host controller, ie. the 1st bridge. */
-			if ((dev->class >> 8) == PCI_CLASS_BRIDGE_PCI &&
-				(PCI_SLOT(dev->devfn) == 0)) {
-				next_bus = dev->subordinate;
-				controllers[i].mem_resources[0] =
-					*next_bus->resource[0];
-				controllers[i].mem_resources[1] =
-					 *next_bus->resource[1];
-				controllers[i].mem_resources[2] =
-					 *next_bus->resource[2];
+			list_for_each_entry(dev, &root_bus->devices, bus_list) {
+				/*
+				 * Find the PCI host controller, ie. the 1st
+				 * bridge.
+				 */
+				if ((dev->class >> 8) == PCI_CLASS_BRIDGE_PCI &&
+					(PCI_SLOT(dev->devfn) == 0)) {
+					next_bus = dev->subordinate;
+					controllers[i].mem_resources[0] =
+						*next_bus->resource[0];
+					controllers[i].mem_resources[1] =
+						 *next_bus->resource[1];
+					controllers[i].mem_resources[2] =
+						 *next_bus->resource[2];
 
-				break;
+					/* Setup flags. */
+					pci_scan_flags[i] = 1;
+
+					break;
+				}
 			}
 		}
-
 	}
 
 	return 0;
@@ -381,7 +407,7 @@
 /*
  * This is called from the generic Linux layer.
  */
-void __init pcibios_update_irq(struct pci_dev *dev, int irq)
+void __devinit pcibios_update_irq(struct pci_dev *dev, int irq)
 {
 	pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq);
 }
diff -druN linux-2.6.39-libre/arch/tile/kernel/pci-dma.c linux-3.0-rc7-libre/arch/tile/kernel/pci-dma.c
--- linux-2.6.39-libre/arch/tile/kernel/pci-dma.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/tile/kernel/pci-dma.c	2011-07-11 19:51:52.000000000 -0400
@@ -244,7 +244,7 @@
  * dma_alloc_noncoherent() returns non-cacheable memory, so there's no
  * need to do any flushing here.
  */
-void dma_cache_sync(void *vaddr, size_t size,
+void dma_cache_sync(struct device *dev, void *vaddr, size_t size,
 		    enum dma_data_direction direction)
 {
 }
diff -druN linux-2.6.39-libre/arch/tile/kernel/proc.c linux-3.0-rc7-libre/arch/tile/kernel/proc.c
--- linux-2.6.39-libre/arch/tile/kernel/proc.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/tile/kernel/proc.c	2011-07-11 19:51:52.000000000 -0400
@@ -27,6 +27,7 @@
 #include <asm/processor.h>
 #include <asm/sections.h>
 #include <asm/homecache.h>
+#include <asm/hardwall.h>
 #include <arch/chip.h>
 
 
@@ -88,3 +89,75 @@
 	.stop	= c_stop,
 	.show	= show_cpuinfo,
 };
+
+/*
+ * Support /proc/tile directory
+ */
+
+static int __init proc_tile_init(void)
+{
+	struct proc_dir_entry *root = proc_mkdir("tile", NULL);
+	if (root == NULL)
+		return 0;
+
+	proc_tile_hardwall_init(root);
+
+	return 0;
+}
+
+arch_initcall(proc_tile_init);
+
+/*
+ * Support /proc/sys/tile directory
+ */
+
+#ifndef __tilegx__  /* FIXME: GX: no support for unaligned access yet */
+static ctl_table unaligned_subtable[] = {
+	{
+		.procname	= "enabled",
+		.data		= &unaligned_fixup,
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= &proc_dointvec
+	},
+	{
+		.procname	= "printk",
+		.data		= &unaligned_printk,
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= &proc_dointvec
+	},
+	{
+		.procname	= "count",
+		.data		= &unaligned_fixup_count,
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= &proc_dointvec
+	},
+	{}
+};
+
+static ctl_table unaligned_table[] = {
+	{
+		.procname	= "unaligned_fixup",
+		.mode		= 0555,
+		.child		= unaligned_subtable
+	},
+	{}
+};
+#endif
+
+static struct ctl_path tile_path[] = {
+	{ .procname = "tile" },
+	{ }
+};
+
+static int __init proc_sys_tile_init(void)
+{
+#ifndef __tilegx__  /* FIXME: GX: no support for unaligned access yet */
+	register_sysctl_paths(tile_path, unaligned_table);
+#endif
+	return 0;
+}
+
+arch_initcall(proc_sys_tile_init);
diff -druN linux-2.6.39-libre/arch/tile/kernel/process.c linux-3.0-rc7-libre/arch/tile/kernel/process.c
--- linux-2.6.39-libre/arch/tile/kernel/process.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/tile/kernel/process.c	2011-07-11 19:51:52.000000000 -0400
@@ -25,10 +25,13 @@
 #include <linux/hardirq.h>
 #include <linux/syscalls.h>
 #include <linux/kernel.h>
+#include <linux/tracehook.h>
+#include <linux/signal.h>
 #include <asm/system.h>
 #include <asm/stack.h>
 #include <asm/homecache.h>
 #include <asm/syscalls.h>
+#include <asm/traps.h>
 #ifdef CONFIG_HARDWALL
 #include <asm/hardwall.h>
 #endif
@@ -546,6 +549,51 @@
 	return __switch_to(prev, next, next_current_ksp0(next));
 }
 
+/*
+ * This routine is called on return from interrupt if any of the
+ * TIF_WORK_MASK flags are set in thread_info->flags.  It is
+ * entered with interrupts disabled so we don't miss an event
+ * that modified the thread_info flags.  If any flag is set, we
+ * handle it and return, and the calling assembly code will
+ * re-disable interrupts, reload the thread flags, and call back
+ * if more flags need to be handled.
+ *
+ * We return whether we need to check the thread_info flags again
+ * or not.  Note that we don't clear TIF_SINGLESTEP here, so it's
+ * important that it be tested last, and then claim that we don't
+ * need to recheck the flags.
+ */
+int do_work_pending(struct pt_regs *regs, u32 thread_info_flags)
+{
+	if (thread_info_flags & _TIF_NEED_RESCHED) {
+		schedule();
+		return 1;
+	}
+#if CHIP_HAS_TILE_DMA() || CHIP_HAS_SN_PROC()
+	if (thread_info_flags & _TIF_ASYNC_TLB) {
+		do_async_page_fault(regs);
+		return 1;
+	}
+#endif
+	if (thread_info_flags & _TIF_SIGPENDING) {
+		do_signal(regs);
+		return 1;
+	}
+	if (thread_info_flags & _TIF_NOTIFY_RESUME) {
+		clear_thread_flag(TIF_NOTIFY_RESUME);
+		tracehook_notify_resume(regs);
+		if (current->replacement_session_keyring)
+			key_replace_session_keyring();
+		return 1;
+	}
+	if (thread_info_flags & _TIF_SINGLESTEP) {
+		if ((regs->ex1 & SPR_EX_CONTEXT_1_1__PL_MASK) == 0)
+			single_step_once(regs);
+		return 0;
+	}
+	panic("work_pending: bad flags %#x\n", thread_info_flags);
+}
+
 /* Note there is an implicit fifth argument if (clone_flags & CLONE_SETTLS). */
 SYSCALL_DEFINE5(clone, unsigned long, clone_flags, unsigned long, newsp,
 		void __user *, parent_tidptr, void __user *, child_tidptr,
@@ -582,8 +630,8 @@
 
 #ifdef CONFIG_COMPAT
 long compat_sys_execve(const char __user *path,
-		       const compat_uptr_t __user *argv,
-		       const compat_uptr_t __user *envp,
+		       compat_uptr_t __user *argv,
+		       compat_uptr_t __user *envp,
 		       struct pt_regs *regs)
 {
 	long error;
diff -druN linux-2.6.39-libre/arch/tile/kernel/regs_64.S linux-3.0-rc7-libre/arch/tile/kernel/regs_64.S
--- linux-2.6.39-libre/arch/tile/kernel/regs_64.S	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/tile/kernel/regs_64.S	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,145 @@
+/*
+ * Copyright 2011 Tilera 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, version 2.
+ *
+ *   This program is distributed in the hope that it will be useful, but
+ *   WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
+ *   NON INFRINGEMENT.  See the GNU General Public License for
+ *   more details.
+ */
+
+#include <linux/linkage.h>
+#include <asm/system.h>
+#include <asm/ptrace.h>
+#include <asm/asm-offsets.h>
+#include <arch/spr_def.h>
+#include <asm/processor.h>
+
+/*
+ * See <asm/system.h>; called with prev and next task_struct pointers.
+ * "prev" is returned in r0 for _switch_to and also for ret_from_fork.
+ *
+ * We want to save pc/sp in "prev", and get the new pc/sp from "next".
+ * We also need to save all the callee-saved registers on the stack.
+ *
+ * Intel enables/disables access to the hardware cycle counter in
+ * seccomp (secure computing) environments if necessary, based on
+ * has_secure_computing().  We might want to do this at some point,
+ * though it would require virtualizing the other SPRs under WORLD_ACCESS.
+ *
+ * Since we're saving to the stack, we omit sp from this list.
+ * And for parallels with other architectures, we save lr separately,
+ * in the thread_struct itself (as the "pc" field).
+ *
+ * This code also needs to be aligned with process.c copy_thread()
+ */
+
+#if CALLEE_SAVED_REGS_COUNT != 24
+# error Mismatch between <asm/system.h> and kernel/entry.S
+#endif
+#define FRAME_SIZE ((2 + CALLEE_SAVED_REGS_COUNT) * 8)
+
+#define SAVE_REG(r) { st r12, r; addi r12, r12, 8 }
+#define LOAD_REG(r) { ld r, r12; addi r12, r12, 8 }
+#define FOR_EACH_CALLEE_SAVED_REG(f)					\
+							f(r30); f(r31); \
+	f(r32); f(r33); f(r34); f(r35);	f(r36); f(r37); f(r38); f(r39); \
+	f(r40); f(r41); f(r42); f(r43); f(r44); f(r45); f(r46); f(r47); \
+	f(r48); f(r49); f(r50); f(r51); f(r52);
+
+STD_ENTRY_SECTION(__switch_to, .sched.text)
+	{
+	  move r10, sp
+	  st sp, lr
+	}
+	{
+	  addli r11, sp, -FRAME_SIZE + 8
+	  addli sp, sp, -FRAME_SIZE
+	}
+	{
+	  st r11, r10
+	  addli r4, r1, TASK_STRUCT_THREAD_KSP_OFFSET
+	}
+	{
+	  ld r13, r4   /* Load new sp to a temp register early. */
+	  addi r12, sp, 16
+	}
+	FOR_EACH_CALLEE_SAVED_REG(SAVE_REG)
+	addli r3, r0, TASK_STRUCT_THREAD_KSP_OFFSET
+	{
+	  st r3, sp
+	  addli r3, r0, TASK_STRUCT_THREAD_PC_OFFSET
+	}
+	{
+	  st r3, lr
+	  addli r4, r1, TASK_STRUCT_THREAD_PC_OFFSET
+	}
+	{
+	  ld lr, r4
+	  addi r12, r13, 16
+	}
+	{
+	  /* Update sp and ksp0 simultaneously to avoid backtracer warnings. */
+	  move sp, r13
+	  mtspr SPR_SYSTEM_SAVE_K_0, r2
+	}
+	FOR_EACH_CALLEE_SAVED_REG(LOAD_REG)
+.L__switch_to_pc:
+	{
+	  addli sp, sp, FRAME_SIZE
+	  jrp lr   /* r0 is still valid here, so return it */
+	}
+	STD_ENDPROC(__switch_to)
+
+/* Return a suitable address for the backtracer for suspended threads */
+STD_ENTRY_SECTION(get_switch_to_pc, .sched.text)
+	lnk r0
+	{
+	  addli r0, r0, .L__switch_to_pc - .
+	  jrp lr
+	}
+	STD_ENDPROC(get_switch_to_pc)
+
+STD_ENTRY(get_pt_regs)
+	.irp reg, r0, r1, r2, r3, r4, r5, r6, r7, \
+		 r8, r9, r10, r11, r12, r13, r14, r15, \
+		 r16, r17, r18, r19, r20, r21, r22, r23, \
+		 r24, r25, r26, r27, r28, r29, r30, r31, \
+		 r32, r33, r34, r35, r36, r37, r38, r39, \
+		 r40, r41, r42, r43, r44, r45, r46, r47, \
+		 r48, r49, r50, r51, r52, tp, sp
+	{
+	 st r0, \reg
+	 addi r0, r0, 8
+	}
+	.endr
+	{
+	 st r0, lr
+	 addi r0, r0, PTREGS_OFFSET_PC - PTREGS_OFFSET_LR
+	}
+	lnk r1
+	{
+	 st r0, r1
+	 addi r0, r0, PTREGS_OFFSET_EX1 - PTREGS_OFFSET_PC
+	}
+	mfspr r1, INTERRUPT_CRITICAL_SECTION
+	shli r1, r1, SPR_EX_CONTEXT_1_1__ICS_SHIFT
+	ori r1, r1, KERNEL_PL
+	{
+	 st r0, r1
+	 addi r0, r0, PTREGS_OFFSET_FAULTNUM - PTREGS_OFFSET_EX1
+	}
+	{
+	 st r0, zero       /* clear faultnum */
+	 addi r0, r0, PTREGS_OFFSET_ORIG_R0 - PTREGS_OFFSET_FAULTNUM
+	}
+	{
+	 st r0, zero       /* clear orig_r0 */
+	 addli r0, r0, -PTREGS_OFFSET_ORIG_R0    /* restore r0 to base */
+	}
+	jrp lr
+	STD_ENDPROC(get_pt_regs)
diff -druN linux-2.6.39-libre/arch/tile/kernel/setup.c linux-3.0-rc7-libre/arch/tile/kernel/setup.c
--- linux-2.6.39-libre/arch/tile/kernel/setup.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/tile/kernel/setup.c	2011-07-11 19:51:52.000000000 -0400
@@ -912,6 +912,8 @@
 #endif
 }
 
+#ifdef CONFIG_BLK_DEV_INITRD
+
 static int __initdata set_initramfs_file;
 static char __initdata initramfs_file[128] = "initramfs.cpio.gz";
 
@@ -969,6 +971,10 @@
 	free_bootmem(__pa(begin), end - begin);
 }
 
+#else
+static inline void load_hv_initrd(void) {}
+#endif /* CONFIG_BLK_DEV_INITRD */
+
 static void __init validate_hv(void)
 {
 	/*
diff -druN linux-2.6.39-libre/arch/tile/kernel/signal.c linux-3.0-rc7-libre/arch/tile/kernel/signal.c
--- linux-2.6.39-libre/arch/tile/kernel/signal.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/tile/kernel/signal.c	2011-07-11 19:51:52.000000000 -0400
@@ -39,7 +39,6 @@
 
 #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
 
-
 SYSCALL_DEFINE3(sigaltstack, const stack_t __user *, uss,
 		stack_t __user *, uoss, struct pt_regs *, regs)
 {
@@ -78,6 +77,13 @@
 	return err;
 }
 
+void signal_fault(const char *type, struct pt_regs *regs,
+		  void __user *frame, int sig)
+{
+	trace_unhandled_signal(type, regs, (unsigned long)frame, SIGSEGV);
+	force_sigsegv(sig, current);
+}
+
 /* The assembly shim for this function arranges to ignore the return value. */
 SYSCALL_DEFINE1(rt_sigreturn, struct pt_regs *, regs)
 {
@@ -105,7 +111,7 @@
 	return 0;
 
 badframe:
-	force_sig(SIGSEGV, current);
+	signal_fault("bad sigreturn frame", regs, frame, 0);
 	return 0;
 }
 
@@ -231,7 +237,7 @@
 	return 0;
 
 give_sigsegv:
-	force_sigsegv(sig, current);
+	signal_fault("bad setup frame", regs, frame, sig);
 	return -EFAULT;
 }
 
@@ -245,7 +251,6 @@
 {
 	int ret;
 
-
 	/* Are we from a system call? */
 	if (regs->faultnum == INT_SWINT_1) {
 		/* If so, check system call restarting.. */
@@ -363,3 +368,118 @@
 	/* Avoid double syscall restart if there are nested signals. */
 	regs->faultnum = INT_SWINT_1_SIGRETURN;
 }
+
+int show_unhandled_signals = 1;
+
+static int __init crashinfo(char *str)
+{
+	unsigned long val;
+	const char *word;
+
+	if (*str == '\0')
+		val = 2;
+	else if (*str != '=' || strict_strtoul(++str, 0, &val) != 0)
+		return 0;
+	show_unhandled_signals = val;
+	switch (show_unhandled_signals) {
+	case 0:
+		word = "No";
+		break;
+	case 1:
+		word = "One-line";
+		break;
+	default:
+		word = "Detailed";
+		break;
+	}
+	pr_info("%s crash reports will be generated on the console\n", word);
+	return 1;
+}
+__setup("crashinfo", crashinfo);
+
+static void dump_mem(void __user *address)
+{
+	void __user *addr;
+	enum { region_size = 256, bytes_per_line = 16 };
+	int i, j, k;
+	int found_readable_mem = 0;
+
+	pr_err("\n");
+	if (!access_ok(VERIFY_READ, address, 1)) {
+		pr_err("Not dumping at address 0x%lx (kernel address)\n",
+		       (unsigned long)address);
+		return;
+	}
+
+	addr = (void __user *)
+		(((unsigned long)address & -bytes_per_line) - region_size/2);
+	if (addr > address)
+		addr = NULL;
+	for (i = 0; i < region_size;
+	     addr += bytes_per_line, i += bytes_per_line) {
+		unsigned char buf[bytes_per_line];
+		char line[100];
+		if (copy_from_user(buf, addr, bytes_per_line))
+			continue;
+		if (!found_readable_mem) {
+			pr_err("Dumping memory around address 0x%lx:\n",
+			       (unsigned long)address);
+			found_readable_mem = 1;
+		}
+		j = sprintf(line, REGFMT":", (unsigned long)addr);
+		for (k = 0; k < bytes_per_line; ++k)
+			j += sprintf(&line[j], " %02x", buf[k]);
+		pr_err("%s\n", line);
+	}
+	if (!found_readable_mem)
+		pr_err("No readable memory around address 0x%lx\n",
+		       (unsigned long)address);
+}
+
+void trace_unhandled_signal(const char *type, struct pt_regs *regs,
+			    unsigned long address, int sig)
+{
+	struct task_struct *tsk = current;
+
+	if (show_unhandled_signals == 0)
+		return;
+
+	/* If the signal is handled, don't show it here. */
+	if (!is_global_init(tsk)) {
+		void __user *handler =
+			tsk->sighand->action[sig-1].sa.sa_handler;
+		if (handler != SIG_IGN && handler != SIG_DFL)
+			return;
+	}
+
+	/* Rate-limit the one-line output, not the detailed output. */
+	if (show_unhandled_signals <= 1 && !printk_ratelimit())
+		return;
+
+	printk("%s%s[%d]: %s at %lx pc "REGFMT" signal %d",
+	       task_pid_nr(tsk) > 1 ? KERN_INFO : KERN_EMERG,
+	       tsk->comm, task_pid_nr(tsk), type, address, regs->pc, sig);
+
+	print_vma_addr(KERN_CONT " in ", regs->pc);
+
+	printk(KERN_CONT "\n");
+
+	if (show_unhandled_signals > 1) {
+		switch (sig) {
+		case SIGILL:
+		case SIGFPE:
+		case SIGSEGV:
+		case SIGBUS:
+			pr_err("User crash: signal %d,"
+			       " trap %ld, address 0x%lx\n",
+			       sig, regs->faultnum, address);
+			show_regs(regs);
+			dump_mem((void __user *)address);
+			break;
+		default:
+			pr_err("User crash: signal %d, trap %ld\n",
+			       sig, regs->faultnum);
+			break;
+		}
+	}
+}
diff -druN linux-2.6.39-libre/arch/tile/kernel/single_step.c linux-3.0-rc7-libre/arch/tile/kernel/single_step.c
--- linux-2.6.39-libre/arch/tile/kernel/single_step.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/tile/kernel/single_step.c	2011-07-11 19:51:52.000000000 -0400
@@ -186,6 +186,8 @@
 			.si_code = SEGV_MAPERR,
 			.si_addr = addr
 		};
+		trace_unhandled_signal("segfault", regs,
+				       (unsigned long)addr, SIGSEGV);
 		force_sig_info(info.si_signo, &info, current);
 		return (tile_bundle_bits) 0;
 	}
@@ -196,6 +198,8 @@
 			.si_code = BUS_ADRALN,
 			.si_addr = addr
 		};
+		trace_unhandled_signal("unaligned trap", regs,
+				       (unsigned long)addr, SIGBUS);
 		force_sig_info(info.si_signo, &info, current);
 		return (tile_bundle_bits) 0;
 	}
@@ -318,6 +322,14 @@
 "    .popsection\n"
 	);
 
+	/*
+	 * Enable interrupts here to allow touching userspace and the like.
+	 * The callers expect this: do_trap() already has interrupts
+	 * enabled, and do_work_pending() handles functions that enable
+	 * interrupts internally.
+	 */
+	local_irq_enable();
+
 	if (state == NULL) {
 		/* allocate a page of writable, executable memory */
 		state = kmalloc(sizeof(struct single_step_state), GFP_KERNEL);
diff -druN linux-2.6.39-libre/arch/tile/kernel/smp.c linux-3.0-rc7-libre/arch/tile/kernel/smp.c
--- linux-2.6.39-libre/arch/tile/kernel/smp.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/tile/kernel/smp.c	2011-07-11 19:51:52.000000000 -0400
@@ -189,12 +189,8 @@
 /* Called when smp_send_reschedule() triggers IRQ_RESCHEDULE. */
 static irqreturn_t handle_reschedule_ipi(int irq, void *token)
 {
-	/*
-	 * Nothing to do here; when we return from interrupt, the
-	 * rescheduling will occur there. But do bump the interrupt
-	 * profiler count in the meantime.
-	 */
 	__get_cpu_var(irq_stat).irq_resched_count++;
+	scheduler_ipi();
 
 	return IRQ_HANDLED;
 }
diff -druN linux-2.6.39-libre/arch/tile/kernel/stack.c linux-3.0-rc7-libre/arch/tile/kernel/stack.c
--- linux-2.6.39-libre/arch/tile/kernel/stack.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/tile/kernel/stack.c	2011-07-11 19:51:52.000000000 -0400
@@ -36,7 +36,7 @@
 #define KBT_LOOP	3  /* Backtrace entered a loop */
 
 /* Is address on the specified kernel stack? */
-static int in_kernel_stack(struct KBacktraceIterator *kbt, VirtualAddress sp)
+static int in_kernel_stack(struct KBacktraceIterator *kbt, unsigned long sp)
 {
 	ulong kstack_base = (ulong) kbt->task->stack;
 	if (kstack_base == 0)  /* corrupt task pointer; just follow stack... */
@@ -45,7 +45,7 @@
 }
 
 /* Is address valid for reading? */
-static int valid_address(struct KBacktraceIterator *kbt, VirtualAddress address)
+static int valid_address(struct KBacktraceIterator *kbt, unsigned long address)
 {
 	HV_PTE *l1_pgtable = kbt->pgtable;
 	HV_PTE *l2_pgtable;
@@ -97,7 +97,7 @@
 }
 
 /* Callback for backtracer; basically a glorified memcpy */
-static bool read_memory_func(void *result, VirtualAddress address,
+static bool read_memory_func(void *result, unsigned long address,
 			     unsigned int size, void *vkbt)
 {
 	int retval;
@@ -124,7 +124,7 @@
 {
 	const char *fault = NULL;  /* happy compiler */
 	char fault_buf[64];
-	VirtualAddress sp = kbt->it.sp;
+	unsigned long sp = kbt->it.sp;
 	struct pt_regs *p;
 
 	if (!in_kernel_stack(kbt, sp))
@@ -163,7 +163,7 @@
 }
 
 /* Is the pc pointing to a sigreturn trampoline? */
-static int is_sigreturn(VirtualAddress pc)
+static int is_sigreturn(unsigned long pc)
 {
 	return (pc == VDSO_BASE);
 }
@@ -260,7 +260,7 @@
 void KBacktraceIterator_init(struct KBacktraceIterator *kbt,
 			     struct task_struct *t, struct pt_regs *regs)
 {
-	VirtualAddress pc, lr, sp, r52;
+	unsigned long pc, lr, sp, r52;
 	int is_current;
 
 	/*
@@ -331,7 +331,7 @@
 
 void KBacktraceIterator_next(struct KBacktraceIterator *kbt)
 {
-	VirtualAddress old_pc = kbt->it.pc, old_sp = kbt->it.sp;
+	unsigned long old_pc = kbt->it.pc, old_sp = kbt->it.sp;
 	kbt->new_context = 0;
 	if (!backtrace_next(&kbt->it) && !KBacktraceIterator_restart(kbt)) {
 		kbt->end = KBT_DONE;
diff -druN linux-2.6.39-libre/arch/tile/kernel/sys.c linux-3.0-rc7-libre/arch/tile/kernel/sys.c
--- linux-2.6.39-libre/arch/tile/kernel/sys.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/tile/kernel/sys.c	2011-07-11 19:51:52.000000000 -0400
@@ -56,13 +56,6 @@
 	return sys_readahead(fd, ((loff_t)offset_hi << 32) | offset_lo, count);
 }
 
-long sys32_fadvise64(int fd, u32 offset_lo, u32 offset_hi,
-		     u32 len, int advice)
-{
-	return sys_fadvise64_64(fd, ((loff_t)offset_hi << 32) | offset_lo,
-				len, advice);
-}
-
 int sys32_fadvise64_64(int fd, u32 offset_lo, u32 offset_hi,
 		       u32 len_lo, u32 len_hi, int advice)
 {
@@ -103,10 +96,8 @@
 
 #ifndef __tilegx__
 /* See comments at the top of the file. */
-#define sys_fadvise64 sys32_fadvise64
 #define sys_fadvise64_64 sys32_fadvise64_64
 #define sys_readahead sys32_readahead
-#define sys_sync_file_range sys_sync_file_range2
 #endif
 
 /* Call the trampolines to manage pt_regs where necessary. */
diff -druN linux-2.6.39-libre/arch/tile/kernel/sysfs.c linux-3.0-rc7-libre/arch/tile/kernel/sysfs.c
--- linux-2.6.39-libre/arch/tile/kernel/sysfs.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/tile/kernel/sysfs.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,185 @@
+/*
+ * Copyright 2011 Tilera 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, version 2.
+ *
+ *   This program is distributed in the hope that it will be useful, but
+ *   WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
+ *   NON INFRINGEMENT.  See the GNU General Public License for
+ *   more details.
+ *
+ * /sys entry support.
+ */
+
+#include <linux/sysdev.h>
+#include <linux/cpu.h>
+#include <linux/slab.h>
+#include <linux/smp.h>
+#include <hv/hypervisor.h>
+
+/* Return a string queried from the hypervisor, truncated to page size. */
+static ssize_t get_hv_confstr(char *page, int query)
+{
+	ssize_t n = hv_confstr(query, (unsigned long)page, PAGE_SIZE - 1);
+	n = n < 0 ? 0 : min(n, (ssize_t)PAGE_SIZE - 1) - 1;
+	if (n)
+		page[n++] = '\n';
+	page[n] = '\0';
+	return n;
+}
+
+static ssize_t chip_width_show(struct sysdev_class *dev,
+			       struct sysdev_class_attribute *attr,
+			       char *page)
+{
+	return sprintf(page, "%u\n", smp_width);
+}
+static SYSDEV_CLASS_ATTR(chip_width, 0444, chip_width_show, NULL);
+
+static ssize_t chip_height_show(struct sysdev_class *dev,
+				struct sysdev_class_attribute *attr,
+				char *page)
+{
+	return sprintf(page, "%u\n", smp_height);
+}
+static SYSDEV_CLASS_ATTR(chip_height, 0444, chip_height_show, NULL);
+
+static ssize_t chip_serial_show(struct sysdev_class *dev,
+				struct sysdev_class_attribute *attr,
+				char *page)
+{
+	return get_hv_confstr(page, HV_CONFSTR_CHIP_SERIAL_NUM);
+}
+static SYSDEV_CLASS_ATTR(chip_serial, 0444, chip_serial_show, NULL);
+
+static ssize_t chip_revision_show(struct sysdev_class *dev,
+				  struct sysdev_class_attribute *attr,
+				  char *page)
+{
+	return get_hv_confstr(page, HV_CONFSTR_CHIP_REV);
+}
+static SYSDEV_CLASS_ATTR(chip_revision, 0444, chip_revision_show, NULL);
+
+
+static ssize_t type_show(struct sysdev_class *dev,
+			    struct sysdev_class_attribute *attr,
+			    char *page)
+{
+	return sprintf(page, "tilera\n");
+}
+static SYSDEV_CLASS_ATTR(type, 0444, type_show, NULL);
+
+#define HV_CONF_ATTR(name, conf)					\
+	static ssize_t name ## _show(struct sysdev_class *dev,		\
+				     struct sysdev_class_attribute *attr, \
+				     char *page)			\
+	{								\
+		return get_hv_confstr(page, conf);			\
+	}								\
+	static SYSDEV_CLASS_ATTR(name, 0444, name ## _show, NULL);
+
+HV_CONF_ATTR(version,		HV_CONFSTR_HV_SW_VER)
+HV_CONF_ATTR(config_version,	HV_CONFSTR_HV_CONFIG_VER)
+
+HV_CONF_ATTR(board_part,	HV_CONFSTR_BOARD_PART_NUM)
+HV_CONF_ATTR(board_serial,	HV_CONFSTR_BOARD_SERIAL_NUM)
+HV_CONF_ATTR(board_revision,	HV_CONFSTR_BOARD_REV)
+HV_CONF_ATTR(board_description,	HV_CONFSTR_BOARD_DESC)
+HV_CONF_ATTR(mezz_part,		HV_CONFSTR_MEZZ_PART_NUM)
+HV_CONF_ATTR(mezz_serial,	HV_CONFSTR_MEZZ_SERIAL_NUM)
+HV_CONF_ATTR(mezz_revision,	HV_CONFSTR_MEZZ_REV)
+HV_CONF_ATTR(mezz_description,	HV_CONFSTR_MEZZ_DESC)
+HV_CONF_ATTR(switch_control,	HV_CONFSTR_SWITCH_CONTROL)
+
+static struct attribute *board_attrs[] = {
+	&attr_board_part.attr,
+	&attr_board_serial.attr,
+	&attr_board_revision.attr,
+	&attr_board_description.attr,
+	&attr_mezz_part.attr,
+	&attr_mezz_serial.attr,
+	&attr_mezz_revision.attr,
+	&attr_mezz_description.attr,
+	&attr_switch_control.attr,
+	NULL
+};
+
+static struct attribute_group board_attr_group = {
+	.name   = "board",
+	.attrs  = board_attrs,
+};
+
+
+static struct bin_attribute hvconfig_bin;
+
+static ssize_t
+hvconfig_bin_read(struct file *filp, struct kobject *kobj,
+		  struct bin_attribute *bin_attr,
+		  char *buf, loff_t off, size_t count)
+{
+	static size_t size;
+
+	/* Lazily learn the true size (minus the trailing NUL). */
+	if (size == 0)
+		size = hv_confstr(HV_CONFSTR_HV_CONFIG, 0, 0) - 1;
+
+	/* Check and adjust input parameters. */
+	if (off > size)
+		return -EINVAL;
+	if (count > size - off)
+		count = size - off;
+
+	if (count) {
+		/* Get a copy of the hvc and copy out the relevant portion. */
+		char *hvc;
+
+		size = off + count;
+		hvc = kmalloc(size, GFP_KERNEL);
+		if (hvc == NULL)
+			return -ENOMEM;
+		hv_confstr(HV_CONFSTR_HV_CONFIG, (unsigned long)hvc, size);
+		memcpy(buf, hvc + off, count);
+		kfree(hvc);
+	}
+
+	return count;
+}
+
+static int __init create_sysfs_entries(void)
+{
+	struct sysdev_class *cls = &cpu_sysdev_class;
+	int err = 0;
+
+#define create_cpu_attr(name)						\
+	if (!err)							\
+		err = sysfs_create_file(&cls->kset.kobj, &attr_##name.attr);
+	create_cpu_attr(chip_width);
+	create_cpu_attr(chip_height);
+	create_cpu_attr(chip_serial);
+	create_cpu_attr(chip_revision);
+
+#define create_hv_attr(name)						\
+	if (!err)							\
+		err = sysfs_create_file(hypervisor_kobj, &attr_##name.attr);
+	create_hv_attr(type);
+	create_hv_attr(version);
+	create_hv_attr(config_version);
+
+	if (!err)
+		err = sysfs_create_group(hypervisor_kobj, &board_attr_group);
+
+	if (!err) {
+		sysfs_bin_attr_init(&hvconfig_bin);
+		hvconfig_bin.attr.name = "hvconfig";
+		hvconfig_bin.attr.mode = S_IRUGO;
+		hvconfig_bin.read = hvconfig_bin_read;
+		hvconfig_bin.size = PAGE_SIZE;
+		err = sysfs_create_bin_file(hypervisor_kobj, &hvconfig_bin);
+	}
+
+	return err;
+}
+subsys_initcall(create_sysfs_entries);
diff -druN linux-2.6.39-libre/arch/tile/kernel/tile-desc_32.c linux-3.0-rc7-libre/arch/tile/kernel/tile-desc_32.c
--- linux-2.6.39-libre/arch/tile/kernel/tile-desc_32.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/tile/kernel/tile-desc_32.c	2011-07-11 19:51:52.000000000 -0400
@@ -2413,12 +2413,13 @@
 
 
 
-/* Given a set of bundle bits and the lookup FSM for a specific pipe,
- * returns which instruction the bundle contains in that pipe.
+/* Given a set of bundle bits and a specific pipe, returns which
+ * instruction the bundle contains in that pipe.
  */
-static const struct tile_opcode *
-find_opcode(tile_bundle_bits bits, const unsigned short *table)
+const struct tile_opcode *
+find_opcode(tile_bundle_bits bits, tile_pipeline pipe)
 {
+  const unsigned short *table = tile_bundle_decoder_fsms[pipe];
   int index = 0;
 
   while (1)
@@ -2465,7 +2466,7 @@
     int i;
 
     d = &decoded[num_instructions++];
-    opc = find_opcode (bits, tile_bundle_decoder_fsms[pipe]);
+    opc = find_opcode (bits, (tile_pipeline)pipe);
     d->opcode = opc;
 
     /* Decode each operand, sign extending, etc. as appropriate. */
diff -druN linux-2.6.39-libre/arch/tile/kernel/tile-desc_64.c linux-3.0-rc7-libre/arch/tile/kernel/tile-desc_64.c
--- linux-2.6.39-libre/arch/tile/kernel/tile-desc_64.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/tile/kernel/tile-desc_64.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,2200 @@
+/* This define is BFD_RELOC_##x for real bfd, or -1 for everyone else. */
+#define BFD_RELOC(x) -1
+
+/* Special registers. */
+#define TREG_LR 55
+#define TREG_SN 56
+#define TREG_ZERO 63
+
+/* FIXME: Rename this. */
+#include <asm/opcode-tile_64.h>
+
+#include <linux/stddef.h>
+
+const struct tilegx_opcode tilegx_opcodes[334] =
+{
+ { "bpt", TILEGX_OPC_BPT, 0x2, 0, TREG_ZERO, 0,
+    { { 0, }, {  }, { 0, }, { 0, }, { 0, } },
+  },
+  { "info", TILEGX_OPC_INFO, 0xf, 1, TREG_ZERO, 1,
+    { { 0 }, { 1 }, { 2 }, { 3 }, { 0, } },
+  },
+  { "infol", TILEGX_OPC_INFOL, 0x3, 1, TREG_ZERO, 1,
+    { { 4 }, { 5 }, { 0, }, { 0, }, { 0, } },
+  },
+  { "move", TILEGX_OPC_MOVE, 0xf, 2, TREG_ZERO, 1,
+    { { 6, 7 }, { 8, 9 }, { 10, 11 }, { 12, 13 }, { 0, } },
+  },
+  { "movei", TILEGX_OPC_MOVEI, 0xf, 2, TREG_ZERO, 1,
+    { { 6, 0 }, { 8, 1 }, { 10, 2 }, { 12, 3 }, { 0, } },
+  },
+  { "moveli", TILEGX_OPC_MOVELI, 0x3, 2, TREG_ZERO, 1,
+    { { 6, 4 }, { 8, 5 }, { 0, }, { 0, }, { 0, } },
+  },
+  { "prefetch", TILEGX_OPC_PREFETCH, 0x12, 1, TREG_ZERO, 1,
+    { { 0, }, { 9 }, { 0, }, { 0, }, { 14 } },
+  },
+  { "prefetch_add_l1", TILEGX_OPC_PREFETCH_ADD_L1, 0x2, 2, TREG_ZERO, 1,
+    { { 0, }, { 15, 1 }, { 0, }, { 0, }, { 0, } },
+  },
+  { "prefetch_add_l1_fault", TILEGX_OPC_PREFETCH_ADD_L1_FAULT, 0x2, 2, TREG_ZERO, 1,
+    { { 0, }, { 15, 1 }, { 0, }, { 0, }, { 0, } },
+  },
+  { "prefetch_add_l2", TILEGX_OPC_PREFETCH_ADD_L2, 0x2, 2, TREG_ZERO, 1,
+    { { 0, }, { 15, 1 }, { 0, }, { 0, }, { 0, } },
+  },
+  { "prefetch_add_l2_fault", TILEGX_OPC_PREFETCH_ADD_L2_FAULT, 0x2, 2, TREG_ZERO, 1,
+    { { 0, }, { 15, 1 }, { 0, }, { 0, }, { 0, } },
+  },
+  { "prefetch_add_l3", TILEGX_OPC_PREFETCH_ADD_L3, 0x2, 2, TREG_ZERO, 1,
+    { { 0, }, { 15, 1 }, { 0, }, { 0, }, { 0, } },
+  },
+  { "prefetch_add_l3_fault", TILEGX_OPC_PREFETCH_ADD_L3_FAULT, 0x2, 2, TREG_ZERO, 1,
+    { { 0, }, { 15, 1 }, { 0, }, { 0, }, { 0, } },
+  },
+  { "prefetch_l1", TILEGX_OPC_PREFETCH_L1, 0x12, 1, TREG_ZERO, 1,
+    { { 0, }, { 9 }, { 0, }, { 0, }, { 14 } },
+  },
+  { "prefetch_l1_fault", TILEGX_OPC_PREFETCH_L1_FAULT, 0x12, 1, TREG_ZERO, 1,
+    { { 0, }, { 9 }, { 0, }, { 0, }, { 14 } },
+  },
+  { "prefetch_l2", TILEGX_OPC_PREFETCH_L2, 0x12, 1, TREG_ZERO, 1,
+    { { 0, }, { 9 }, { 0, }, { 0, }, { 14 } },
+  },
+  { "prefetch_l2_fault", TILEGX_OPC_PREFETCH_L2_FAULT, 0x12, 1, TREG_ZERO, 1,
+    { { 0, }, { 9 }, { 0, }, { 0, }, { 14 } },
+  },
+  { "prefetch_l3", TILEGX_OPC_PREFETCH_L3, 0x12, 1, TREG_ZERO, 1,
+    { { 0, }, { 9 }, { 0, }, { 0, }, { 14 } },
+  },
+  { "prefetch_l3_fault", TILEGX_OPC_PREFETCH_L3_FAULT, 0x12, 1, TREG_ZERO, 1,
+    { { 0, }, { 9 }, { 0, }, { 0, }, { 14 } },
+  },
+  { "raise", TILEGX_OPC_RAISE, 0x2, 0, TREG_ZERO, 1,
+    { { 0, }, {  }, { 0, }, { 0, }, { 0, } },
+  },
+  { "add", TILEGX_OPC_ADD, 0xf, 3, TREG_ZERO, 1,
+    { { 6, 7, 16 }, { 8, 9, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } },
+  },
+  { "addi", TILEGX_OPC_ADDI, 0xf, 3, TREG_ZERO, 1,
+    { { 6, 7, 0 }, { 8, 9, 1 }, { 10, 11, 2 }, { 12, 13, 3 }, { 0, } },
+  },
+  { "addli", TILEGX_OPC_ADDLI, 0x3, 3, TREG_ZERO, 1,
+    { { 6, 7, 4 }, { 8, 9, 5 }, { 0, }, { 0, }, { 0, } },
+  },
+  { "addx", TILEGX_OPC_ADDX, 0xf, 3, TREG_ZERO, 1,
+    { { 6, 7, 16 }, { 8, 9, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } },
+  },
+  { "addxi", TILEGX_OPC_ADDXI, 0xf, 3, TREG_ZERO, 1,
+    { { 6, 7, 0 }, { 8, 9, 1 }, { 10, 11, 2 }, { 12, 13, 3 }, { 0, } },
+  },
+  { "addxli", TILEGX_OPC_ADDXLI, 0x3, 3, TREG_ZERO, 1,
+    { { 6, 7, 4 }, { 8, 9, 5 }, { 0, }, { 0, }, { 0, } },
+  },
+  { "addxsc", TILEGX_OPC_ADDXSC, 0x3, 3, TREG_ZERO, 1,
+    { { 6, 7, 16 }, { 8, 9, 17 }, { 0, }, { 0, }, { 0, } },
+  },
+  { "and", TILEGX_OPC_AND, 0xf, 3, TREG_ZERO, 1,
+    { { 6, 7, 16 }, { 8, 9, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } },
+  },
+  { "andi", TILEGX_OPC_ANDI, 0xf, 3, TREG_ZERO, 1,
+    { { 6, 7, 0 }, { 8, 9, 1 }, { 10, 11, 2 }, { 12, 13, 3 }, { 0, } },
+  },
+  { "beqz", TILEGX_OPC_BEQZ, 0x2, 2, TREG_ZERO, 1,
+    { { 0, }, { 9, 20 }, { 0, }, { 0, }, { 0, } },
+  },
+  { "beqzt", TILEGX_OPC_BEQZT, 0x2, 2, TREG_ZERO, 1,
+    { { 0, }, { 9, 20 }, { 0, }, { 0, }, { 0, } },
+  },
+  { "bfexts", TILEGX_OPC_BFEXTS, 0x1, 4, TREG_ZERO, 1,
+    { { 6, 7, 21, 22 }, { 0, }, { 0, }, { 0, }, { 0, } },
+  },
+  { "bfextu", TILEGX_OPC_BFEXTU, 0x1, 4, TREG_ZERO, 1,
+    { { 6, 7, 21, 22 }, { 0, }, { 0, }, { 0, }, { 0, } },
+  },
+  { "bfins", TILEGX_OPC_BFINS, 0x1, 4, TREG_ZERO, 1,
+    { { 23, 7, 21, 22 }, { 0, }, { 0, }, { 0, }, { 0, } },
+  },
+  { "bgez", TILEGX_OPC_BGEZ, 0x2, 2, TREG_ZERO, 1,
+    { { 0, }, { 9, 20 }, { 0, }, { 0, }, { 0, } },
+  },
+  { "bgezt", TILEGX_OPC_BGEZT, 0x2, 2, TREG_ZERO, 1,
+    { { 0, }, { 9, 20 }, { 0, }, { 0, }, { 0, } },
+  },
+  { "bgtz", TILEGX_OPC_BGTZ, 0x2, 2, TREG_ZERO, 1,
+    { { 0, }, { 9, 20 }, { 0, }, { 0, }, { 0, } },
+  },
+  { "bgtzt", TILEGX_OPC_BGTZT, 0x2, 2, TREG_ZERO, 1,
+    { { 0, }, { 9, 20 }, { 0, }, { 0, }, { 0, } },
+  },
+  { "blbc", TILEGX_OPC_BLBC, 0x2, 2, TREG_ZERO, 1,
+    { { 0, }, { 9, 20 }, { 0, }, { 0, }, { 0, } },
+  },
+  { "blbct", TILEGX_OPC_BLBCT, 0x2, 2, TREG_ZERO, 1,
+    { { 0, }, { 9, 20 }, { 0, }, { 0, }, { 0, } },
+  },
+  { "blbs", TILEGX_OPC_BLBS, 0x2, 2, TREG_ZERO, 1,
+    { { 0, }, { 9, 20 }, { 0, }, { 0, }, { 0, } },
+  },
+  { "blbst", TILEGX_OPC_BLBST, 0x2, 2, TREG_ZERO, 1,
+    { { 0, }, { 9, 20 }, { 0, }, { 0, }, { 0, } },
+  },
+  { "blez", TILEGX_OPC_BLEZ, 0x2, 2, TREG_ZERO, 1,
+    { { 0, }, { 9, 20 }, { 0, }, { 0, }, { 0, } },
+  },
+  { "blezt", TILEGX_OPC_BLEZT, 0x2, 2, TREG_ZERO, 1,
+    { { 0, }, { 9, 20 }, { 0, }, { 0, }, { 0, } },
+  },
+  { "bltz", TILEGX_OPC_BLTZ, 0x2, 2, TREG_ZERO, 1,
+    { { 0, }, { 9, 20 }, { 0, }, { 0, }, { 0, } },
+  },
+  { "bltzt", TILEGX_OPC_BLTZT, 0x2, 2, TREG_ZERO, 1,
+    { { 0, }, { 9, 20 }, { 0, }, { 0, }, { 0, } },
+  },
+  { "bnez", TILEGX_OPC_BNEZ, 0x2, 2, TREG_ZERO, 1,
+    { { 0, }, { 9, 20 }, { 0, }, { 0, }, { 0, } },
+  },
+  { "bnezt", TILEGX_OPC_BNEZT, 0x2, 2, TREG_ZERO, 1,
+    { { 0, }, { 9, 20 }, { 0, }, { 0, }, { 0, } },
+  },
+  { "clz", TILEGX_OPC_CLZ, 0x5, 2, TREG_ZERO, 1,
+    { { 6, 7 }, { 0, }, { 10, 11 }, { 0, }, { 0, } },
+  },
+  { "cmoveqz", TILEGX_OPC_CMOVEQZ, 0x5, 3, TREG_ZERO, 1,
+    { { 23, 7, 16 }, { 0, }, { 24, 11, 18 }, { 0, }, { 0, } },
+  },
+  { "cmovnez", TILEGX_OPC_CMOVNEZ, 0x5, 3, TREG_ZERO, 1,
+    { { 23, 7, 16 }, { 0, }, { 24, 11, 18 }, { 0, }, { 0, } },
+  },
+  { "cmpeq", TILEGX_OPC_CMPEQ, 0xf, 3, TREG_ZERO, 1,
+    { { 6, 7, 16 }, { 8, 9, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } },
+  },
+  { "cmpeqi", TILEGX_OPC_CMPEQI, 0xf, 3, TREG_ZERO, 1,
+    { { 6, 7, 0 }, { 8, 9, 1 }, { 10, 11, 2 }, { 12, 13, 3 }, { 0, } },
+  },
+  { "cmpexch", TILEGX_OPC_CMPEXCH, 0x2, 3, TREG_ZERO, 1,
+    { { 0, }, { 8, 9, 17 }, { 0, }, { 0, }, { 0, } },
+  },
+  { "cmpexch4", TILEGX_OPC_CMPEXCH4, 0x2, 3, TREG_ZERO, 1,
+    { { 0, }, { 8, 9, 17 }, { 0, }, { 0, }, { 0, } },
+  },
+  { "cmples", TILEGX_OPC_CMPLES, 0xf, 3, TREG_ZERO, 1,
+    { { 6, 7, 16 }, { 8, 9, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } },
+  },
+  { "cmpleu", TILEGX_OPC_CMPLEU, 0xf, 3, TREG_ZERO, 1,
+    { { 6, 7, 16 }, { 8, 9, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } },
+  },
+  { "cmplts", TILEGX_OPC_CMPLTS, 0xf, 3, TREG_ZERO, 1,
+    { { 6, 7, 16 }, { 8, 9, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } },
+  },
+  { "cmpltsi", TILEGX_OPC_CMPLTSI, 0xf, 3, TREG_ZERO, 1,
+    { { 6, 7, 0 }, { 8, 9, 1 }, { 10, 11, 2 }, { 12, 13, 3 }, { 0, } },
+  },
+  { "cmpltu", TILEGX_OPC_CMPLTU, 0xf, 3, TREG_ZERO, 1,
+    { { 6, 7, 16 }, { 8, 9, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } },
+  },
+  { "cmpltui", TILEGX_OPC_CMPLTUI, 0x3, 3, TREG_ZERO, 1,
+    { { 6, 7, 0 }, { 8, 9, 1 }, { 0, }, { 0, }, { 0, } },
+  },
+  { "cmpne", TILEGX_OPC_CMPNE, 0xf, 3, TREG_ZERO, 1,
+    { { 6, 7, 16 }, { 8, 9, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } },
+  },
+  { "cmul", TILEGX_OPC_CMUL, 0x1, 3, TREG_ZERO, 1,
+    { { 6, 7, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+  },
+  { "cmula", TILEGX_OPC_CMULA, 0x1, 3, TREG_ZERO, 1,
+    { { 23, 7, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+  },
+  { "cmulaf", TILEGX_OPC_CMULAF, 0x1, 3, TREG_ZERO, 1,
+    { { 23, 7, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+  },
+  { "cmulf", TILEGX_OPC_CMULF, 0x1, 3, TREG_ZERO, 1,
+    { { 6, 7, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+  },
+  { "cmulfr", TILEGX_OPC_CMULFR, 0x1, 3, TREG_ZERO, 1,
+    { { 6, 7, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+  },
+  { "cmulh", TILEGX_OPC_CMULH, 0x1, 3, TREG_ZERO, 1,
+    { { 6, 7, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+  },
+  { "cmulhr", TILEGX_OPC_CMULHR, 0x1, 3, TREG_ZERO, 1,
+    { { 6, 7, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+  },
+  { "crc32_32", TILEGX_OPC_CRC32_32, 0x1, 3, TREG_ZERO, 1,
+    { { 6, 7, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+  },
+  { "crc32_8", TILEGX_OPC_CRC32_8, 0x1, 3, TREG_ZERO, 1,
+    { { 6, 7, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+  },
+  { "ctz", TILEGX_OPC_CTZ, 0x5, 2, TREG_ZERO, 1,
+    { { 6, 7 }, { 0, }, { 10, 11 }, { 0, }, { 0, } },
+  },
+  { "dblalign", TILEGX_OPC_DBLALIGN, 0x1, 3, TREG_ZERO, 1,
+    { { 23, 7, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+  },
+  { "dblalign2", TILEGX_OPC_DBLALIGN2, 0x3, 3, TREG_ZERO, 1,
+    { { 6, 7, 16 }, { 8, 9, 17 }, { 0, }, { 0, }, { 0, } },
+  },
+  { "dblalign4", TILEGX_OPC_DBLALIGN4, 0x3, 3, TREG_ZERO, 1,
+    { { 6, 7, 16 }, { 8, 9, 17 }, { 0, }, { 0, }, { 0, } },
+  },
+  { "dblalign6", TILEGX_OPC_DBLALIGN6, 0x3, 3, TREG_ZERO, 1,
+    { { 6, 7, 16 }, { 8, 9, 17 }, { 0, }, { 0, }, { 0, } },
+  },
+  { "drain", TILEGX_OPC_DRAIN, 0x2, 0, TREG_ZERO, 0,
+    { { 0, }, {  }, { 0, }, { 0, }, { 0, } },
+  },
+  { "dtlbpr", TILEGX_OPC_DTLBPR, 0x2, 1, TREG_ZERO, 1,
+    { { 0, }, { 9 }, { 0, }, { 0, }, { 0, } },
+  },
+  { "exch", TILEGX_OPC_EXCH, 0x2, 3, TREG_ZERO, 1,
+    { { 0, }, { 8, 9, 17 }, { 0, }, { 0, }, { 0, } },
+  },
+  { "exch4", TILEGX_OPC_EXCH4, 0x2, 3, TREG_ZERO, 1,
+    { { 0, }, { 8, 9, 17 }, { 0, }, { 0, }, { 0, } },
+  },
+  { "fdouble_add_flags", TILEGX_OPC_FDOUBLE_ADD_FLAGS, 0x1, 3, TREG_ZERO, 1,
+    { { 6, 7, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+  },
+  { "fdouble_addsub", TILEGX_OPC_FDOUBLE_ADDSUB, 0x1, 3, TREG_ZERO, 1,
+    { { 23, 7, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+  },
+  { "fdouble_mul_flags", TILEGX_OPC_FDOUBLE_MUL_FLAGS, 0x1, 3, TREG_ZERO, 1,
+    { { 6, 7, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+  },
+  { "fdouble_pack1", TILEGX_OPC_FDOUBLE_PACK1, 0x1, 3, TREG_ZERO, 1,
+    { { 6, 7, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+  },
+  { "fdouble_pack2", TILEGX_OPC_FDOUBLE_PACK2, 0x1, 3, TREG_ZERO, 1,
+    { { 23, 7, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+  },
+  { "fdouble_sub_flags", TILEGX_OPC_FDOUBLE_SUB_FLAGS, 0x1, 3, TREG_ZERO, 1,
+    { { 6, 7, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+  },
+  { "fdouble_unpack_max", TILEGX_OPC_FDOUBLE_UNPACK_MAX, 0x1, 3, TREG_ZERO, 1,
+    { { 6, 7, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+  },
+  { "fdouble_unpack_min", TILEGX_OPC_FDOUBLE_UNPACK_MIN, 0x1, 3, TREG_ZERO, 1,
+    { { 6, 7, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+  },
+  { "fetchadd", TILEGX_OPC_FETCHADD, 0x2, 3, TREG_ZERO, 1,
+    { { 0, }, { 8, 9, 17 }, { 0, }, { 0, }, { 0, } },
+  },
+  { "fetchadd4", TILEGX_OPC_FETCHADD4, 0x2, 3, TREG_ZERO, 1,
+    { { 0, }, { 8, 9, 17 }, { 0, }, { 0, }, { 0, } },
+  },
+  { "fetchaddgez", TILEGX_OPC_FETCHADDGEZ, 0x2, 3, TREG_ZERO, 1,
+    { { 0, }, { 8, 9, 17 }, { 0, }, { 0, }, { 0, } },
+  },
+  { "fetchaddgez4", TILEGX_OPC_FETCHADDGEZ4, 0x2, 3, TREG_ZERO, 1,
+    { { 0, }, { 8, 9, 17 }, { 0, }, { 0, }, { 0, } },
+  },
+  { "fetchand", TILEGX_OPC_FETCHAND, 0x2, 3, TREG_ZERO, 1,
+    { { 0, }, { 8, 9, 17 }, { 0, }, { 0, }, { 0, } },
+  },
+  { "fetchand4", TILEGX_OPC_FETCHAND4, 0x2, 3, TREG_ZERO, 1,
+    { { 0, }, { 8, 9, 17 }, { 0, }, { 0, }, { 0, } },
+  },
+  { "fetchor", TILEGX_OPC_FETCHOR, 0x2, 3, TREG_ZERO, 1,
+    { { 0, }, { 8, 9, 17 }, { 0, }, { 0, }, { 0, } },
+  },
+  { "fetchor4", TILEGX_OPC_FETCHOR4, 0x2, 3, TREG_ZERO, 1,
+    { { 0, }, { 8, 9, 17 }, { 0, }, { 0, }, { 0, } },
+  },
+  { "finv", TILEGX_OPC_FINV, 0x2, 1, TREG_ZERO, 1,
+    { { 0, }, { 9 }, { 0, }, { 0, }, { 0, } },
+  },
+  { "flush", TILEGX_OPC_FLUSH, 0x2, 1, TREG_ZERO, 1,
+    { { 0, }, { 9 }, { 0, }, { 0, }, { 0, } },
+  },
+  { "flushwb", TILEGX_OPC_FLUSHWB, 0x2, 0, TREG_ZERO, 1,
+    { { 0, }, {  }, { 0, }, { 0, }, { 0, } },
+  },
+  { "fnop", TILEGX_OPC_FNOP, 0xf, 0, TREG_ZERO, 1,
+    { {  }, {  }, {  }, {  }, { 0, } },
+  },
+  { "fsingle_add1", TILEGX_OPC_FSINGLE_ADD1, 0x1, 3, TREG_ZERO, 1,
+    { { 6, 7, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+  },
+  { "fsingle_addsub2", TILEGX_OPC_FSINGLE_ADDSUB2, 0x1, 3, TREG_ZERO, 1,
+    { { 23, 7, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+  },
+  { "fsingle_mul1", TILEGX_OPC_FSINGLE_MUL1, 0x1, 3, TREG_ZERO, 1,
+    { { 6, 7, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+  },
+  { "fsingle_mul2", TILEGX_OPC_FSINGLE_MUL2, 0x1, 3, TREG_ZERO, 1,
+    { { 6, 7, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+  },
+  { "fsingle_pack1", TILEGX_OPC_FSINGLE_PACK1, 0x5, 2, TREG_ZERO, 1,
+    { { 6, 7 }, { 0, }, { 10, 11 }, { 0, }, { 0, } },
+  },
+  { "fsingle_pack2", TILEGX_OPC_FSINGLE_PACK2, 0x1, 3, TREG_ZERO, 1,
+    { { 6, 7, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+  },
+  { "fsingle_sub1", TILEGX_OPC_FSINGLE_SUB1, 0x1, 3, TREG_ZERO, 1,
+    { { 6, 7, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+  },
+  { "icoh", TILEGX_OPC_ICOH, 0x2, 1, TREG_ZERO, 1,
+    { { 0, }, { 9 }, { 0, }, { 0, }, { 0, } },
+  },
+  { "ill", TILEGX_OPC_ILL, 0xa, 0, TREG_ZERO, 1,
+    { { 0, }, {  }, { 0, }, {  }, { 0, } },
+  },
+  { "inv", TILEGX_OPC_INV, 0x2, 1, TREG_ZERO, 1,
+    { { 0, }, { 9 }, { 0, }, { 0, }, { 0, } },
+  },
+  { "iret", TILEGX_OPC_IRET, 0x2, 0, TREG_ZERO, 1,
+    { { 0, }, {  }, { 0, }, { 0, }, { 0, } },
+  },
+  { "j", TILEGX_OPC_J, 0x2, 1, TREG_ZERO, 1,
+    { { 0, }, { 25 }, { 0, }, { 0, }, { 0, } },
+  },
+  { "jal", TILEGX_OPC_JAL, 0x2, 1, TREG_LR, 1,
+    { { 0, }, { 25 }, { 0, }, { 0, }, { 0, } },
+  },
+  { "jalr", TILEGX_OPC_JALR, 0xa, 1, TREG_LR, 1,
+    { { 0, }, { 9 }, { 0, }, { 13 }, { 0, } },
+  },
+  { "jalrp", TILEGX_OPC_JALRP, 0xa, 1, TREG_LR, 1,
+    { { 0, }, { 9 }, { 0, }, { 13 }, { 0, } },
+  },
+  { "jr", TILEGX_OPC_JR, 0xa, 1, TREG_ZERO, 1,
+    { { 0, }, { 9 }, { 0, }, { 13 }, { 0, } },
+  },
+  { "jrp", TILEGX_OPC_JRP, 0xa, 1, TREG_ZERO, 1,
+    { { 0, }, { 9 }, { 0, }, { 13 }, { 0, } },
+  },
+  { "ld", TILEGX_OPC_LD, 0x12, 2, TREG_ZERO, 1,
+    { { 0, }, { 8, 9 }, { 0, }, { 0, }, { 26, 14 } },
+  },
+  { "ld1s", TILEGX_OPC_LD1S, 0x12, 2, TREG_ZERO, 1,
+    { { 0, }, { 8, 9 }, { 0, }, { 0, }, { 26, 14 } },
+  },
+  { "ld1s_add", TILEGX_OPC_LD1S_ADD, 0x2, 3, TREG_ZERO, 1,
+    { { 0, }, { 8, 15, 1 }, { 0, }, { 0, }, { 0, } },
+  },
+  { "ld1u", TILEGX_OPC_LD1U, 0x12, 2, TREG_ZERO, 1,
+    { { 0, }, { 8, 9 }, { 0, }, { 0, }, { 26, 14 } },
+  },
+  { "ld1u_add", TILEGX_OPC_LD1U_ADD, 0x2, 3, TREG_ZERO, 1,
+    { { 0, }, { 8, 15, 1 }, { 0, }, { 0, }, { 0, } },
+  },
+  { "ld2s", TILEGX_OPC_LD2S, 0x12, 2, TREG_ZERO, 1,
+    { { 0, }, { 8, 9 }, { 0, }, { 0, }, { 26, 14 } },
+  },
+  { "ld2s_add", TILEGX_OPC_LD2S_ADD, 0x2, 3, TREG_ZERO, 1,
+    { { 0, }, { 8, 15, 1 }, { 0, }, { 0, }, { 0, } },
+  },
+  { "ld2u", TILEGX_OPC_LD2U, 0x12, 2, TREG_ZERO, 1,
+    { { 0, }, { 8, 9 }, { 0, }, { 0, }, { 26, 14 } },
+  },
+  { "ld2u_add", TILEGX_OPC_LD2U_ADD, 0x2, 3, TREG_ZERO, 1,
+    { { 0, }, { 8, 15, 1 }, { 0, }, { 0, }, { 0, } },
+  },
+  { "ld4s", TILEGX_OPC_LD4S, 0x12, 2, TREG_ZERO, 1,
+    { { 0, }, { 8, 9 }, { 0, }, { 0, }, { 26, 14 } },
+  },
+  { "ld4s_add", TILEGX_OPC_LD4S_ADD, 0x2, 3, TREG_ZERO, 1,
+    { { 0, }, { 8, 15, 1 }, { 0, }, { 0, }, { 0, } },
+  },
+  { "ld4u", TILEGX_OPC_LD4U, 0x12, 2, TREG_ZERO, 1,
+    { { 0, }, { 8, 9 }, { 0, }, { 0, }, { 26, 14 } },
+  },
+  { "ld4u_add", TILEGX_OPC_LD4U_ADD, 0x2, 3, TREG_ZERO, 1,
+    { { 0, }, { 8, 15, 1 }, { 0, }, { 0, }, { 0, } },
+  },
+  { "ld_add", TILEGX_OPC_LD_ADD, 0x2, 3, TREG_ZERO, 1,
+    { { 0, }, { 8, 15, 1 }, { 0, }, { 0, }, { 0, } },
+  },
+  { "ldna", TILEGX_OPC_LDNA, 0x2, 2, TREG_ZERO, 1,
+    { { 0, }, { 8, 9 }, { 0, }, { 0, }, { 0, } },
+  },
+  { "ldna_add", TILEGX_OPC_LDNA_ADD, 0x2, 3, TREG_ZERO, 1,
+    { { 0, }, { 8, 15, 1 }, { 0, }, { 0, }, { 0, } },
+  },
+  { "ldnt", TILEGX_OPC_LDNT, 0x2, 2, TREG_ZERO, 1,
+    { { 0, }, { 8, 9 }, { 0, }, { 0, }, { 0, } },
+  },
+  { "ldnt1s", TILEGX_OPC_LDNT1S, 0x2, 2, TREG_ZERO, 1,
+    { { 0, }, { 8, 9 }, { 0, }, { 0, }, { 0, } },
+  },
+  { "ldnt1s_add", TILEGX_OPC_LDNT1S_ADD, 0x2, 3, TREG_ZERO, 1,
+    { { 0, }, { 8, 15, 1 }, { 0, }, { 0, }, { 0, } },
+  },
+  { "ldnt1u", TILEGX_OPC_LDNT1U, 0x2, 2, TREG_ZERO, 1,
+    { { 0, }, { 8, 9 }, { 0, }, { 0, }, { 0, } },
+  },
+  { "ldnt1u_add", TILEGX_OPC_LDNT1U_ADD, 0x2, 3, TREG_ZERO, 1,
+    { { 0, }, { 8, 15, 1 }, { 0, }, { 0, }, { 0, } },
+  },
+  { "ldnt2s", TILEGX_OPC_LDNT2S, 0x2, 2, TREG_ZERO, 1,
+    { { 0, }, { 8, 9 }, { 0, }, { 0, }, { 0, } },
+  },
+  { "ldnt2s_add", TILEGX_OPC_LDNT2S_ADD, 0x2, 3, TREG_ZERO, 1,
+    { { 0, }, { 8, 15, 1 }, { 0, }, { 0, }, { 0, } },
+  },
+  { "ldnt2u", TILEGX_OPC_LDNT2U, 0x2, 2, TREG_ZERO, 1,
+    { { 0, }, { 8, 9 }, { 0, }, { 0, }, { 0, } },
+  },
+  { "ldnt2u_add", TILEGX_OPC_LDNT2U_ADD, 0x2, 3, TREG_ZERO, 1,
+    { { 0, }, { 8, 15, 1 }, { 0, }, { 0, }, { 0, } },
+  },
+  { "ldnt4s", TILEGX_OPC_LDNT4S, 0x2, 2, TREG_ZERO, 1,
+    { { 0, }, { 8, 9 }, { 0, }, { 0, }, { 0, } },
+  },
+  { "ldnt4s_add", TILEGX_OPC_LDNT4S_ADD, 0x2, 3, TREG_ZERO, 1,
+    { { 0, }, { 8, 15, 1 }, { 0, }, { 0, }, { 0, } },
+  },
+  { "ldnt4u", TILEGX_OPC_LDNT4U, 0x2, 2, TREG_ZERO, 1,
+    { { 0, }, { 8, 9 }, { 0, }, { 0, }, { 0, } },
+  },
+  { "ldnt4u_add", TILEGX_OPC_LDNT4U_ADD, 0x2, 3, TREG_ZERO, 1,
+    { { 0, }, { 8, 15, 1 }, { 0, }, { 0, }, { 0, } },
+  },
+  { "ldnt_add", TILEGX_OPC_LDNT_ADD, 0x2, 3, TREG_ZERO, 1,
+    { { 0, }, { 8, 15, 1 }, { 0, }, { 0, }, { 0, } },
+  },
+  { "lnk", TILEGX_OPC_LNK, 0xa, 1, TREG_ZERO, 1,
+    { { 0, }, { 8 }, { 0, }, { 12 }, { 0, } },
+  },
+  { "mf", TILEGX_OPC_MF, 0x2, 0, TREG_ZERO, 1,
+    { { 0, }, {  }, { 0, }, { 0, }, { 0, } },
+  },
+  { "mfspr", TILEGX_OPC_MFSPR, 0x2, 2, TREG_ZERO, 1,
+    { { 0, }, { 8, 27 }, { 0, }, { 0, }, { 0, } },
+  },
+  { "mm", TILEGX_OPC_MM, 0x1, 4, TREG_ZERO, 1,
+    { { 23, 7, 21, 22 }, { 0, }, { 0, }, { 0, }, { 0, } },
+  },
+  { "mnz", TILEGX_OPC_MNZ, 0xf, 3, TREG_ZERO, 1,
+    { { 6, 7, 16 }, { 8, 9, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } },
+  },
+  { "mtspr", TILEGX_OPC_MTSPR, 0x2, 2, TREG_ZERO, 1,
+    { { 0, }, { 28, 9 }, { 0, }, { 0, }, { 0, } },
+  },
+  { "mul_hs_hs", TILEGX_OPC_MUL_HS_HS, 0x5, 3, TREG_ZERO, 1,
+    { { 6, 7, 16 }, { 0, }, { 10, 11, 18 }, { 0, }, { 0, } },
+  },
+  { "mul_hs_hu", TILEGX_OPC_MUL_HS_HU, 0x1, 3, TREG_ZERO, 1,
+    { { 6, 7, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+  },
+  { "mul_hs_ls", TILEGX_OPC_MUL_HS_LS, 0x1, 3, TREG_ZERO, 1,
+    { { 6, 7, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+  },
+  { "mul_hs_lu", TILEGX_OPC_MUL_HS_LU, 0x1, 3, TREG_ZERO, 1,
+    { { 6, 7, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+  },
+  { "mul_hu_hu", TILEGX_OPC_MUL_HU_HU, 0x5, 3, TREG_ZERO, 1,
+    { { 6, 7, 16 }, { 0, }, { 10, 11, 18 }, { 0, }, { 0, } },
+  },
+  { "mul_hu_ls", TILEGX_OPC_MUL_HU_LS, 0x1, 3, TREG_ZERO, 1,
+    { { 6, 7, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+  },
+  { "mul_hu_lu", TILEGX_OPC_MUL_HU_LU, 0x1, 3, TREG_ZERO, 1,
+    { { 6, 7, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+  },
+  { "mul_ls_ls", TILEGX_OPC_MUL_LS_LS, 0x5, 3, TREG_ZERO, 1,
+    { { 6, 7, 16 }, { 0, }, { 10, 11, 18 }, { 0, }, { 0, } },
+  },
+  { "mul_ls_lu", TILEGX_OPC_MUL_LS_LU, 0x1, 3, TREG_ZERO, 1,
+    { { 6, 7, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+  },
+  { "mul_lu_lu", TILEGX_OPC_MUL_LU_LU, 0x5, 3, TREG_ZERO, 1,
+    { { 6, 7, 16 }, { 0, }, { 10, 11, 18 }, { 0, }, { 0, } },
+  },
+  { "mula_hs_hs", TILEGX_OPC_MULA_HS_HS, 0x5, 3, TREG_ZERO, 1,
+    { { 23, 7, 16 }, { 0, }, { 24, 11, 18 }, { 0, }, { 0, } },
+  },
+  { "mula_hs_hu", TILEGX_OPC_MULA_HS_HU, 0x1, 3, TREG_ZERO, 1,
+    { { 23, 7, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+  },
+  { "mula_hs_ls", TILEGX_OPC_MULA_HS_LS, 0x1, 3, TREG_ZERO, 1,
+    { { 23, 7, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+  },
+  { "mula_hs_lu", TILEGX_OPC_MULA_HS_LU, 0x1, 3, TREG_ZERO, 1,
+    { { 23, 7, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+  },
+  { "mula_hu_hu", TILEGX_OPC_MULA_HU_HU, 0x5, 3, TREG_ZERO, 1,
+    { { 23, 7, 16 }, { 0, }, { 24, 11, 18 }, { 0, }, { 0, } },
+  },
+  { "mula_hu_ls", TILEGX_OPC_MULA_HU_LS, 0x1, 3, TREG_ZERO, 1,
+    { { 23, 7, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+  },
+  { "mula_hu_lu", TILEGX_OPC_MULA_HU_LU, 0x1, 3, TREG_ZERO, 1,
+    { { 23, 7, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+  },
+  { "mula_ls_ls", TILEGX_OPC_MULA_LS_LS, 0x5, 3, TREG_ZERO, 1,
+    { { 23, 7, 16 }, { 0, }, { 24, 11, 18 }, { 0, }, { 0, } },
+  },
+  { "mula_ls_lu", TILEGX_OPC_MULA_LS_LU, 0x1, 3, TREG_ZERO, 1,
+    { { 23, 7, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+  },
+  { "mula_lu_lu", TILEGX_OPC_MULA_LU_LU, 0x5, 3, TREG_ZERO, 1,
+    { { 23, 7, 16 }, { 0, }, { 24, 11, 18 }, { 0, }, { 0, } },
+  },
+  { "mulax", TILEGX_OPC_MULAX, 0x5, 3, TREG_ZERO, 1,
+    { { 23, 7, 16 }, { 0, }, { 24, 11, 18 }, { 0, }, { 0, } },
+  },
+  { "mulx", TILEGX_OPC_MULX, 0x5, 3, TREG_ZERO, 1,
+    { { 6, 7, 16 }, { 0, }, { 10, 11, 18 }, { 0, }, { 0, } },
+  },
+  { "mz", TILEGX_OPC_MZ, 0xf, 3, TREG_ZERO, 1,
+    { { 6, 7, 16 }, { 8, 9, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } },
+  },
+  { "nap", TILEGX_OPC_NAP, 0x2, 0, TREG_ZERO, 0,
+    { { 0, }, {  }, { 0, }, { 0, }, { 0, } },
+  },
+  { "nop", TILEGX_OPC_NOP, 0xf, 0, TREG_ZERO, 1,
+    { {  }, {  }, {  }, {  }, { 0, } },
+  },
+  { "nor", TILEGX_OPC_NOR, 0xf, 3, TREG_ZERO, 1,
+    { { 6, 7, 16 }, { 8, 9, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } },
+  },
+  { "or", TILEGX_OPC_OR, 0xf, 3, TREG_ZERO, 1,
+    { { 6, 7, 16 }, { 8, 9, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } },
+  },
+  { "ori", TILEGX_OPC_ORI, 0x3, 3, TREG_ZERO, 1,
+    { { 6, 7, 0 }, { 8, 9, 1 }, { 0, }, { 0, }, { 0, } },
+  },
+  { "pcnt", TILEGX_OPC_PCNT, 0x5, 2, TREG_ZERO, 1,
+    { { 6, 7 }, { 0, }, { 10, 11 }, { 0, }, { 0, } },
+  },
+  { "revbits", TILEGX_OPC_REVBITS, 0x5, 2, TREG_ZERO, 1,
+    { { 6, 7 }, { 0, }, { 10, 11 }, { 0, }, { 0, } },
+  },
+  { "revbytes", TILEGX_OPC_REVBYTES, 0x5, 2, TREG_ZERO, 1,
+    { { 6, 7 }, { 0, }, { 10, 11 }, { 0, }, { 0, } },
+  },
+  { "rotl", TILEGX_OPC_ROTL, 0xf, 3, TREG_ZERO, 1,
+    { { 6, 7, 16 }, { 8, 9, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } },
+  },
+  { "rotli", TILEGX_OPC_ROTLI, 0xf, 3, TREG_ZERO, 1,
+    { { 6, 7, 29 }, { 8, 9, 30 }, { 10, 11, 31 }, { 12, 13, 32 }, { 0, } },
+  },
+  { "shl", TILEGX_OPC_SHL, 0xf, 3, TREG_ZERO, 1,
+    { { 6, 7, 16 }, { 8, 9, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } },
+  },
+  { "shl16insli", TILEGX_OPC_SHL16INSLI, 0x3, 3, TREG_ZERO, 1,
+    { { 6, 7, 4 }, { 8, 9, 5 }, { 0, }, { 0, }, { 0, } },
+  },
+  { "shl1add", TILEGX_OPC_SHL1ADD, 0xf, 3, TREG_ZERO, 1,
+    { { 6, 7, 16 }, { 8, 9, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } },
+  },
+  { "shl1addx", TILEGX_OPC_SHL1ADDX, 0xf, 3, TREG_ZERO, 1,
+    { { 6, 7, 16 }, { 8, 9, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } },
+  },
+  { "shl2add", TILEGX_OPC_SHL2ADD, 0xf, 3, TREG_ZERO, 1,
+    { { 6, 7, 16 }, { 8, 9, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } },
+  },
+  { "shl2addx", TILEGX_OPC_SHL2ADDX, 0xf, 3, TREG_ZERO, 1,
+    { { 6, 7, 16 }, { 8, 9, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } },
+  },
+  { "shl3add", TILEGX_OPC_SHL3ADD, 0xf, 3, TREG_ZERO, 1,
+    { { 6, 7, 16 }, { 8, 9, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } },
+  },
+  { "shl3addx", TILEGX_OPC_SHL3ADDX, 0xf, 3, TREG_ZERO, 1,
+    { { 6, 7, 16 }, { 8, 9, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } },
+  },
+  { "shli", TILEGX_OPC_SHLI, 0xf, 3, TREG_ZERO, 1,
+    { { 6, 7, 29 }, { 8, 9, 30 }, { 10, 11, 31 }, { 12, 13, 32 }, { 0, } },
+  },
+  { "shlx", TILEGX_OPC_SHLX, 0x3, 3, TREG_ZERO, 1,
+    { { 6, 7, 16 }, { 8, 9, 17 }, { 0, }, { 0, }, { 0, } },
+  },
+  { "shlxi", TILEGX_OPC_SHLXI, 0x3, 3, TREG_ZERO, 1,
+    { { 6, 7, 29 }, { 8, 9, 30 }, { 0, }, { 0, }, { 0, } },
+  },
+  { "shrs", TILEGX_OPC_SHRS, 0xf, 3, TREG_ZERO, 1,
+    { { 6, 7, 16 }, { 8, 9, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } },
+  },
+  { "shrsi", TILEGX_OPC_SHRSI, 0xf, 3, TREG_ZERO, 1,
+    { { 6, 7, 29 }, { 8, 9, 30 }, { 10, 11, 31 }, { 12, 13, 32 }, { 0, } },
+  },
+  { "shru", TILEGX_OPC_SHRU, 0xf, 3, TREG_ZERO, 1,
+    { { 6, 7, 16 }, { 8, 9, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } },
+  },
+  { "shrui", TILEGX_OPC_SHRUI, 0xf, 3, TREG_ZERO, 1,
+    { { 6, 7, 29 }, { 8, 9, 30 }, { 10, 11, 31 }, { 12, 13, 32 }, { 0, } },
+  },
+  { "shrux", TILEGX_OPC_SHRUX, 0x3, 3, TREG_ZERO, 1,
+    { { 6, 7, 16 }, { 8, 9, 17 }, { 0, }, { 0, }, { 0, } },
+  },
+  { "shruxi", TILEGX_OPC_SHRUXI, 0x3, 3, TREG_ZERO, 1,
+    { { 6, 7, 29 }, { 8, 9, 30 }, { 0, }, { 0, }, { 0, } },
+  },
+  { "shufflebytes", TILEGX_OPC_SHUFFLEBYTES, 0x1, 3, TREG_ZERO, 1,
+    { { 23, 7, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+  },
+  { "st", TILEGX_OPC_ST, 0x12, 2, TREG_ZERO, 1,
+    { { 0, }, { 9, 17 }, { 0, }, { 0, }, { 14, 33 } },
+  },
+  { "st1", TILEGX_OPC_ST1, 0x12, 2, TREG_ZERO, 1,
+    { { 0, }, { 9, 17 }, { 0, }, { 0, }, { 14, 33 } },
+  },
+  { "st1_add", TILEGX_OPC_ST1_ADD, 0x2, 3, TREG_ZERO, 1,
+    { { 0, }, { 15, 17, 34 }, { 0, }, { 0, }, { 0, } },
+  },
+  { "st2", TILEGX_OPC_ST2, 0x12, 2, TREG_ZERO, 1,
+    { { 0, }, { 9, 17 }, { 0, }, { 0, }, { 14, 33 } },
+  },
+  { "st2_add", TILEGX_OPC_ST2_ADD, 0x2, 3, TREG_ZERO, 1,
+    { { 0, }, { 15, 17, 34 }, { 0, }, { 0, }, { 0, } },
+  },
+  { "st4", TILEGX_OPC_ST4, 0x12, 2, TREG_ZERO, 1,
+    { { 0, }, { 9, 17 }, { 0, }, { 0, }, { 14, 33 } },
+  },
+  { "st4_add", TILEGX_OPC_ST4_ADD, 0x2, 3, TREG_ZERO, 1,
+    { { 0, }, { 15, 17, 34 }, { 0, }, { 0, }, { 0, } },
+  },
+  { "st_add", TILEGX_OPC_ST_ADD, 0x2, 3, TREG_ZERO, 1,
+    { { 0, }, { 15, 17, 34 }, { 0, }, { 0, }, { 0, } },
+  },
+  { "stnt", TILEGX_OPC_STNT, 0x2, 2, TREG_ZERO, 1,
+    { { 0, }, { 9, 17 }, { 0, }, { 0, }, { 0, } },
+  },
+  { "stnt1", TILEGX_OPC_STNT1, 0x2, 2, TREG_ZERO, 1,
+    { { 0, }, { 9, 17 }, { 0, }, { 0, }, { 0, } },
+  },
+  { "stnt1_add", TILEGX_OPC_STNT1_ADD, 0x2, 3, TREG_ZERO, 1,
+    { { 0, }, { 15, 17, 34 }, { 0, }, { 0, }, { 0, } },
+  },
+  { "stnt2", TILEGX_OPC_STNT2, 0x2, 2, TREG_ZERO, 1,
+    { { 0, }, { 9, 17 }, { 0, }, { 0, }, { 0, } },
+  },
+  { "stnt2_add", TILEGX_OPC_STNT2_ADD, 0x2, 3, TREG_ZERO, 1,
+    { { 0, }, { 15, 17, 34 }, { 0, }, { 0, }, { 0, } },
+  },
+  { "stnt4", TILEGX_OPC_STNT4, 0x2, 2, TREG_ZERO, 1,
+    { { 0, }, { 9, 17 }, { 0, }, { 0, }, { 0, } },
+  },
+  { "stnt4_add", TILEGX_OPC_STNT4_ADD, 0x2, 3, TREG_ZERO, 1,
+    { { 0, }, { 15, 17, 34 }, { 0, }, { 0, }, { 0, } },
+  },
+  { "stnt_add", TILEGX_OPC_STNT_ADD, 0x2, 3, TREG_ZERO, 1,
+    { { 0, }, { 15, 17, 34 }, { 0, }, { 0, }, { 0, } },
+  },
+  { "sub", TILEGX_OPC_SUB, 0xf, 3, TREG_ZERO, 1,
+    { { 6, 7, 16 }, { 8, 9, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } },
+  },
+  { "subx", TILEGX_OPC_SUBX, 0xf, 3, TREG_ZERO, 1,
+    { { 6, 7, 16 }, { 8, 9, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } },
+  },
+  { "subxsc", TILEGX_OPC_SUBXSC, 0x3, 3, TREG_ZERO, 1,
+    { { 6, 7, 16 }, { 8, 9, 17 }, { 0, }, { 0, }, { 0, } },
+  },
+  { "swint0", TILEGX_OPC_SWINT0, 0x2, 0, TREG_ZERO, 0,
+    { { 0, }, {  }, { 0, }, { 0, }, { 0, } },
+  },
+  { "swint1", TILEGX_OPC_SWINT1, 0x2, 0, TREG_ZERO, 0,
+    { { 0, }, {  }, { 0, }, { 0, }, { 0, } },
+  },
+  { "swint2", TILEGX_OPC_SWINT2, 0x2, 0, TREG_ZERO, 0,
+    { { 0, }, {  }, { 0, }, { 0, }, { 0, } },
+  },
+  { "swint3", TILEGX_OPC_SWINT3, 0x2, 0, TREG_ZERO, 0,
+    { { 0, }, {  }, { 0, }, { 0, }, { 0, } },
+  },
+  { "tblidxb0", TILEGX_OPC_TBLIDXB0, 0x5, 2, TREG_ZERO, 1,
+    { { 23, 7 }, { 0, }, { 24, 11 }, { 0, }, { 0, } },
+  },
+  { "tblidxb1", TILEGX_OPC_TBLIDXB1, 0x5, 2, TREG_ZERO, 1,
+    { { 23, 7 }, { 0, }, { 24, 11 }, { 0, }, { 0, } },
+  },
+  { "tblidxb2", TILEGX_OPC_TBLIDXB2, 0x5, 2, TREG_ZERO, 1,
+    { { 23, 7 }, { 0, }, { 24, 11 }, { 0, }, { 0, } },
+  },
+  { "tblidxb3", TILEGX_OPC_TBLIDXB3, 0x5, 2, TREG_ZERO, 1,
+    { { 23, 7 }, { 0, }, { 24, 11 }, { 0, }, { 0, } },
+  },
+  { "v1add", TILEGX_OPC_V1ADD, 0x3, 3, TREG_ZERO, 1,
+    { { 6, 7, 16 }, { 8, 9, 17 }, { 0, }, { 0, }, { 0, } },
+  },
+  { "v1addi", TILEGX_OPC_V1ADDI, 0x3, 3, TREG_ZERO, 1,
+    { { 6, 7, 0 }, { 8, 9, 1 }, { 0, }, { 0, }, { 0, } },
+  },
+  { "v1adduc", TILEGX_OPC_V1ADDUC, 0x3, 3, TREG_ZERO, 1,
+    { { 6, 7, 16 }, { 8, 9, 17 }, { 0, }, { 0, }, { 0, } },
+  },
+  { "v1adiffu", TILEGX_OPC_V1ADIFFU, 0x1, 3, TREG_ZERO, 1,
+    { { 6, 7, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+  },
+  { "v1avgu", TILEGX_OPC_V1AVGU, 0x1, 3, TREG_ZERO, 1,
+    { { 6, 7, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+  },
+  { "v1cmpeq", TILEGX_OPC_V1CMPEQ, 0x3, 3, TREG_ZERO, 1,
+    { { 6, 7, 16 }, { 8, 9, 17 }, { 0, }, { 0, }, { 0, } },
+  },
+  { "v1cmpeqi", TILEGX_OPC_V1CMPEQI, 0x3, 3, TREG_ZERO, 1,
+    { { 6, 7, 0 }, { 8, 9, 1 }, { 0, }, { 0, }, { 0, } },
+  },
+  { "v1cmples", TILEGX_OPC_V1CMPLES, 0x3, 3, TREG_ZERO, 1,
+    { { 6, 7, 16 }, { 8, 9, 17 }, { 0, }, { 0, }, { 0, } },
+  },
+  { "v1cmpleu", TILEGX_OPC_V1CMPLEU, 0x3, 3, TREG_ZERO, 1,
+    { { 6, 7, 16 }, { 8, 9, 17 }, { 0, }, { 0, }, { 0, } },
+  },
+  { "v1cmplts", TILEGX_OPC_V1CMPLTS, 0x3, 3, TREG_ZERO, 1,
+    { { 6, 7, 16 }, { 8, 9, 17 }, { 0, }, { 0, }, { 0, } },
+  },
+  { "v1cmpltsi", TILEGX_OPC_V1CMPLTSI, 0x3, 3, TREG_ZERO, 1,
+    { { 6, 7, 0 }, { 8, 9, 1 }, { 0, }, { 0, }, { 0, } },
+  },
+  { "v1cmpltu", TILEGX_OPC_V1CMPLTU, 0x3, 3, TREG_ZERO, 1,
+    { { 6, 7, 16 }, { 8, 9, 17 }, { 0, }, { 0, }, { 0, } },
+  },
+  { "v1cmpltui", TILEGX_OPC_V1CMPLTUI, 0x3, 3, TREG_ZERO, 1,
+    { { 6, 7, 0 }, { 8, 9, 1 }, { 0, }, { 0, }, { 0, } },
+  },
+  { "v1cmpne", TILEGX_OPC_V1CMPNE, 0x3, 3, TREG_ZERO, 1,
+    { { 6, 7, 16 }, { 8, 9, 17 }, { 0, }, { 0, }, { 0, } },
+  },
+  { "v1ddotpu", TILEGX_OPC_V1DDOTPU, 0x1, 3, TREG_ZERO, 1,
+    { { 6, 7, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+  },
+  { "v1ddotpua", TILEGX_OPC_V1DDOTPUA, 0x1, 3, TREG_ZERO, 1,
+    { { 23, 7, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+  },
+  { "v1ddotpus", TILEGX_OPC_V1DDOTPUS, 0x1, 3, TREG_ZERO, 1,
+    { { 6, 7, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+  },
+  { "v1ddotpusa", TILEGX_OPC_V1DDOTPUSA, 0x1, 3, TREG_ZERO, 1,
+    { { 23, 7, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+  },
+  { "v1dotp", TILEGX_OPC_V1DOTP, 0x1, 3, TREG_ZERO, 1,
+    { { 6, 7, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+  },
+  { "v1dotpa", TILEGX_OPC_V1DOTPA, 0x1, 3, TREG_ZERO, 1,
+    { { 23, 7, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+  },
+  { "v1dotpu", TILEGX_OPC_V1DOTPU, 0x1, 3, TREG_ZERO, 1,
+    { { 6, 7, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+  },
+  { "v1dotpua", TILEGX_OPC_V1DOTPUA, 0x1, 3, TREG_ZERO, 1,
+    { { 23, 7, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+  },
+  { "v1dotpus", TILEGX_OPC_V1DOTPUS, 0x1, 3, TREG_ZERO, 1,
+    { { 6, 7, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+  },
+  { "v1dotpusa", TILEGX_OPC_V1DOTPUSA, 0x1, 3, TREG_ZERO, 1,
+    { { 23, 7, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+  },
+  { "v1int_h", TILEGX_OPC_V1INT_H, 0x3, 3, TREG_ZERO, 1,
+    { { 6, 7, 16 }, { 8, 9, 17 }, { 0, }, { 0, }, { 0, } },
+  },
+  { "v1int_l", TILEGX_OPC_V1INT_L, 0x3, 3, TREG_ZERO, 1,
+    { { 6, 7, 16 }, { 8, 9, 17 }, { 0, }, { 0, }, { 0, } },
+  },
+  { "v1maxu", TILEGX_OPC_V1MAXU, 0x3, 3, TREG_ZERO, 1,
+    { { 6, 7, 16 }, { 8, 9, 17 }, { 0, }, { 0, }, { 0, } },
+  },
+  { "v1maxui", TILEGX_OPC_V1MAXUI, 0x3, 3, TREG_ZERO, 1,
+    { { 6, 7, 0 }, { 8, 9, 1 }, { 0, }, { 0, }, { 0, } },
+  },
+  { "v1minu", TILEGX_OPC_V1MINU, 0x3, 3, TREG_ZERO, 1,
+    { { 6, 7, 16 }, { 8, 9, 17 }, { 0, }, { 0, }, { 0, } },
+  },
+  { "v1minui", TILEGX_OPC_V1MINUI, 0x3, 3, TREG_ZERO, 1,
+    { { 6, 7, 0 }, { 8, 9, 1 }, { 0, }, { 0, }, { 0, } },
+  },
+  { "v1mnz", TILEGX_OPC_V1MNZ, 0x3, 3, TREG_ZERO, 1,
+    { { 6, 7, 16 }, { 8, 9, 17 }, { 0, }, { 0, }, { 0, } },
+  },
+  { "v1multu", TILEGX_OPC_V1MULTU, 0x1, 3, TREG_ZERO, 1,
+    { { 6, 7, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+  },
+  { "v1mulu", TILEGX_OPC_V1MULU, 0x1, 3, TREG_ZERO, 1,
+    { { 6, 7, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+  },
+  { "v1mulus", TILEGX_OPC_V1MULUS, 0x1, 3, TREG_ZERO, 1,
+    { { 6, 7, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+  },
+  { "v1mz", TILEGX_OPC_V1MZ, 0x3, 3, TREG_ZERO, 1,
+    { { 6, 7, 16 }, { 8, 9, 17 }, { 0, }, { 0, }, { 0, } },
+  },
+  { "v1sadau", TILEGX_OPC_V1SADAU, 0x1, 3, TREG_ZERO, 1,
+    { { 23, 7, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+  },
+  { "v1sadu", TILEGX_OPC_V1SADU, 0x1, 3, TREG_ZERO, 1,
+    { { 6, 7, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+  },
+  { "v1shl", TILEGX_OPC_V1SHL, 0x3, 3, TREG_ZERO, 1,
+    { { 6, 7, 16 }, { 8, 9, 17 }, { 0, }, { 0, }, { 0, } },
+  },
+  { "v1shli", TILEGX_OPC_V1SHLI, 0x3, 3, TREG_ZERO, 1,
+    { { 6, 7, 29 }, { 8, 9, 30 }, { 0, }, { 0, }, { 0, } },
+  },
+  { "v1shrs", TILEGX_OPC_V1SHRS, 0x3, 3, TREG_ZERO, 1,
+    { { 6, 7, 16 }, { 8, 9, 17 }, { 0, }, { 0, }, { 0, } },
+  },
+  { "v1shrsi", TILEGX_OPC_V1SHRSI, 0x3, 3, TREG_ZERO, 1,
+    { { 6, 7, 29 }, { 8, 9, 30 }, { 0, }, { 0, }, { 0, } },
+  },
+  { "v1shru", TILEGX_OPC_V1SHRU, 0x3, 3, TREG_ZERO, 1,
+    { { 6, 7, 16 }, { 8, 9, 17 }, { 0, }, { 0, }, { 0, } },
+  },
+  { "v1shrui", TILEGX_OPC_V1SHRUI, 0x3, 3, TREG_ZERO, 1,
+    { { 6, 7, 29 }, { 8, 9, 30 }, { 0, }, { 0, }, { 0, } },
+  },
+  { "v1sub", TILEGX_OPC_V1SUB, 0x3, 3, TREG_ZERO, 1,
+    { { 6, 7, 16 }, { 8, 9, 17 }, { 0, }, { 0, }, { 0, } },
+  },
+  { "v1subuc", TILEGX_OPC_V1SUBUC, 0x3, 3, TREG_ZERO, 1,
+    { { 6, 7, 16 }, { 8, 9, 17 }, { 0, }, { 0, }, { 0, } },
+  },
+  { "v2add", TILEGX_OPC_V2ADD, 0x3, 3, TREG_ZERO, 1,
+    { { 6, 7, 16 }, { 8, 9, 17 }, { 0, }, { 0, }, { 0, } },
+  },
+  { "v2addi", TILEGX_OPC_V2ADDI, 0x3, 3, TREG_ZERO, 1,
+    { { 6, 7, 0 }, { 8, 9, 1 }, { 0, }, { 0, }, { 0, } },
+  },
+  { "v2addsc", TILEGX_OPC_V2ADDSC, 0x3, 3, TREG_ZERO, 1,
+    { { 6, 7, 16 }, { 8, 9, 17 }, { 0, }, { 0, }, { 0, } },
+  },
+  { "v2adiffs", TILEGX_OPC_V2ADIFFS, 0x1, 3, TREG_ZERO, 1,
+    { { 6, 7, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+  },
+  { "v2avgs", TILEGX_OPC_V2AVGS, 0x1, 3, TREG_ZERO, 1,
+    { { 6, 7, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+  },
+  { "v2cmpeq", TILEGX_OPC_V2CMPEQ, 0x3, 3, TREG_ZERO, 1,
+    { { 6, 7, 16 }, { 8, 9, 17 }, { 0, }, { 0, }, { 0, } },
+  },
+  { "v2cmpeqi", TILEGX_OPC_V2CMPEQI, 0x3, 3, TREG_ZERO, 1,
+    { { 6, 7, 0 }, { 8, 9, 1 }, { 0, }, { 0, }, { 0, } },
+  },
+  { "v2cmples", TILEGX_OPC_V2CMPLES, 0x3, 3, TREG_ZERO, 1,
+    { { 6, 7, 16 }, { 8, 9, 17 }, { 0, }, { 0, }, { 0, } },
+  },
+  { "v2cmpleu", TILEGX_OPC_V2CMPLEU, 0x3, 3, TREG_ZERO, 1,
+    { { 6, 7, 16 }, { 8, 9, 17 }, { 0, }, { 0, }, { 0, } },
+  },
+  { "v2cmplts", TILEGX_OPC_V2CMPLTS, 0x3, 3, TREG_ZERO, 1,
+    { { 6, 7, 16 }, { 8, 9, 17 }, { 0, }, { 0, }, { 0, } },
+  },
+  { "v2cmpltsi", TILEGX_OPC_V2CMPLTSI, 0x3, 3, TREG_ZERO, 1,
+    { { 6, 7, 0 }, { 8, 9, 1 }, { 0, }, { 0, }, { 0, } },
+  },
+  { "v2cmpltu", TILEGX_OPC_V2CMPLTU, 0x3, 3, TREG_ZERO, 1,
+    { { 6, 7, 16 }, { 8, 9, 17 }, { 0, }, { 0, }, { 0, } },
+  },
+  { "v2cmpltui", TILEGX_OPC_V2CMPLTUI, 0x3, 3, TREG_ZERO, 1,
+    { { 6, 7, 0 }, { 8, 9, 1 }, { 0, }, { 0, }, { 0, } },
+  },
+  { "v2cmpne", TILEGX_OPC_V2CMPNE, 0x3, 3, TREG_ZERO, 1,
+    { { 6, 7, 16 }, { 8, 9, 17 }, { 0, }, { 0, }, { 0, } },
+  },
+  { "v2dotp", TILEGX_OPC_V2DOTP, 0x1, 3, TREG_ZERO, 1,
+    { { 6, 7, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+  },
+  { "v2dotpa", TILEGX_OPC_V2DOTPA, 0x1, 3, TREG_ZERO, 1,
+    { { 23, 7, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+  },
+  { "v2int_h", TILEGX_OPC_V2INT_H, 0x3, 3, TREG_ZERO, 1,
+    { { 6, 7, 16 }, { 8, 9, 17 }, { 0, }, { 0, }, { 0, } },
+  },
+  { "v2int_l", TILEGX_OPC_V2INT_L, 0x3, 3, TREG_ZERO, 1,
+    { { 6, 7, 16 }, { 8, 9, 17 }, { 0, }, { 0, }, { 0, } },
+  },
+  { "v2maxs", TILEGX_OPC_V2MAXS, 0x3, 3, TREG_ZERO, 1,
+    { { 6, 7, 16 }, { 8, 9, 17 }, { 0, }, { 0, }, { 0, } },
+  },
+  { "v2maxsi", TILEGX_OPC_V2MAXSI, 0x3, 3, TREG_ZERO, 1,
+    { { 6, 7, 0 }, { 8, 9, 1 }, { 0, }, { 0, }, { 0, } },
+  },
+  { "v2mins", TILEGX_OPC_V2MINS, 0x3, 3, TREG_ZERO, 1,
+    { { 6, 7, 16 }, { 8, 9, 17 }, { 0, }, { 0, }, { 0, } },
+  },
+  { "v2minsi", TILEGX_OPC_V2MINSI, 0x3, 3, TREG_ZERO, 1,
+    { { 6, 7, 0 }, { 8, 9, 1 }, { 0, }, { 0, }, { 0, } },
+  },
+  { "v2mnz", TILEGX_OPC_V2MNZ, 0x3, 3, TREG_ZERO, 1,
+    { { 6, 7, 16 }, { 8, 9, 17 }, { 0, }, { 0, }, { 0, } },
+  },
+  { "v2mulfsc", TILEGX_OPC_V2MULFSC, 0x1, 3, TREG_ZERO, 1,
+    { { 6, 7, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+  },
+  { "v2muls", TILEGX_OPC_V2MULS, 0x1, 3, TREG_ZERO, 1,
+    { { 6, 7, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+  },
+  { "v2mults", TILEGX_OPC_V2MULTS, 0x1, 3, TREG_ZERO, 1,
+    { { 6, 7, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+  },
+  { "v2mz", TILEGX_OPC_V2MZ, 0x3, 3, TREG_ZERO, 1,
+    { { 6, 7, 16 }, { 8, 9, 17 }, { 0, }, { 0, }, { 0, } },
+  },
+  { "v2packh", TILEGX_OPC_V2PACKH, 0x3, 3, TREG_ZERO, 1,
+    { { 6, 7, 16 }, { 8, 9, 17 }, { 0, }, { 0, }, { 0, } },
+  },
+  { "v2packl", TILEGX_OPC_V2PACKL, 0x3, 3, TREG_ZERO, 1,
+    { { 6, 7, 16 }, { 8, 9, 17 }, { 0, }, { 0, }, { 0, } },
+  },
+  { "v2packuc", TILEGX_OPC_V2PACKUC, 0x3, 3, TREG_ZERO, 1,
+    { { 6, 7, 16 }, { 8, 9, 17 }, { 0, }, { 0, }, { 0, } },
+  },
+  { "v2sadas", TILEGX_OPC_V2SADAS, 0x1, 3, TREG_ZERO, 1,
+    { { 23, 7, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+  },
+  { "v2sadau", TILEGX_OPC_V2SADAU, 0x1, 3, TREG_ZERO, 1,
+    { { 23, 7, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+  },
+  { "v2sads", TILEGX_OPC_V2SADS, 0x1, 3, TREG_ZERO, 1,
+    { { 6, 7, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+  },
+  { "v2sadu", TILEGX_OPC_V2SADU, 0x1, 3, TREG_ZERO, 1,
+    { { 6, 7, 16 }, { 0, }, { 0, }, { 0, }, { 0, } },
+  },
+  { "v2shl", TILEGX_OPC_V2SHL, 0x3, 3, TREG_ZERO, 1,
+    { { 6, 7, 16 }, { 8, 9, 17 }, { 0, }, { 0, }, { 0, } },
+  },
+  { "v2shli", TILEGX_OPC_V2SHLI, 0x3, 3, TREG_ZERO, 1,
+    { { 6, 7, 29 }, { 8, 9, 30 }, { 0, }, { 0, }, { 0, } },
+  },
+  { "v2shlsc", TILEGX_OPC_V2SHLSC, 0x3, 3, TREG_ZERO, 1,
+    { { 6, 7, 16 }, { 8, 9, 17 }, { 0, }, { 0, }, { 0, } },
+  },
+  { "v2shrs", TILEGX_OPC_V2SHRS, 0x3, 3, TREG_ZERO, 1,
+    { { 6, 7, 16 }, { 8, 9, 17 }, { 0, }, { 0, }, { 0, } },
+  },
+  { "v2shrsi", TILEGX_OPC_V2SHRSI, 0x3, 3, TREG_ZERO, 1,
+    { { 6, 7, 29 }, { 8, 9, 30 }, { 0, }, { 0, }, { 0, } },
+  },
+  { "v2shru", TILEGX_OPC_V2SHRU, 0x3, 3, TREG_ZERO, 1,
+    { { 6, 7, 16 }, { 8, 9, 17 }, { 0, }, { 0, }, { 0, } },
+  },
+  { "v2shrui", TILEGX_OPC_V2SHRUI, 0x3, 3, TREG_ZERO, 1,
+    { { 6, 7, 29 }, { 8, 9, 30 }, { 0, }, { 0, }, { 0, } },
+  },
+  { "v2sub", TILEGX_OPC_V2SUB, 0x3, 3, TREG_ZERO, 1,
+    { { 6, 7, 16 }, { 8, 9, 17 }, { 0, }, { 0, }, { 0, } },
+  },
+  { "v2subsc", TILEGX_OPC_V2SUBSC, 0x3, 3, TREG_ZERO, 1,
+    { { 6, 7, 16 }, { 8, 9, 17 }, { 0, }, { 0, }, { 0, } },
+  },
+  { "v4add", TILEGX_OPC_V4ADD, 0x3, 3, TREG_ZERO, 1,
+    { { 6, 7, 16 }, { 8, 9, 17 }, { 0, }, { 0, }, { 0, } },
+  },
+  { "v4addsc", TILEGX_OPC_V4ADDSC, 0x3, 3, TREG_ZERO, 1,
+    { { 6, 7, 16 }, { 8, 9, 17 }, { 0, }, { 0, }, { 0, } },
+  },
+  { "v4int_h", TILEGX_OPC_V4INT_H, 0x3, 3, TREG_ZERO, 1,
+    { { 6, 7, 16 }, { 8, 9, 17 }, { 0, }, { 0, }, { 0, } },
+  },
+  { "v4int_l", TILEGX_OPC_V4INT_L, 0x3, 3, TREG_ZERO, 1,
+    { { 6, 7, 16 }, { 8, 9, 17 }, { 0, }, { 0, }, { 0, } },
+  },
+  { "v4packsc", TILEGX_OPC_V4PACKSC, 0x3, 3, TREG_ZERO, 1,
+    { { 6, 7, 16 }, { 8, 9, 17 }, { 0, }, { 0, }, { 0, } },
+  },
+  { "v4shl", TILEGX_OPC_V4SHL, 0x3, 3, TREG_ZERO, 1,
+    { { 6, 7, 16 }, { 8, 9, 17 }, { 0, }, { 0, }, { 0, } },
+  },
+  { "v4shlsc", TILEGX_OPC_V4SHLSC, 0x3, 3, TREG_ZERO, 1,
+    { { 6, 7, 16 }, { 8, 9, 17 }, { 0, }, { 0, }, { 0, } },
+  },
+  { "v4shrs", TILEGX_OPC_V4SHRS, 0x3, 3, TREG_ZERO, 1,
+    { { 6, 7, 16 }, { 8, 9, 17 }, { 0, }, { 0, }, { 0, } },
+  },
+  { "v4shru", TILEGX_OPC_V4SHRU, 0x3, 3, TREG_ZERO, 1,
+    { { 6, 7, 16 }, { 8, 9, 17 }, { 0, }, { 0, }, { 0, } },
+  },
+  { "v4sub", TILEGX_OPC_V4SUB, 0x3, 3, TREG_ZERO, 1,
+    { { 6, 7, 16 }, { 8, 9, 17 }, { 0, }, { 0, }, { 0, } },
+  },
+  { "v4subsc", TILEGX_OPC_V4SUBSC, 0x3, 3, TREG_ZERO, 1,
+    { { 6, 7, 16 }, { 8, 9, 17 }, { 0, }, { 0, }, { 0, } },
+  },
+  { "wh64", TILEGX_OPC_WH64, 0x2, 1, TREG_ZERO, 1,
+    { { 0, }, { 9 }, { 0, }, { 0, }, { 0, } },
+  },
+  { "xor", TILEGX_OPC_XOR, 0xf, 3, TREG_ZERO, 1,
+    { { 6, 7, 16 }, { 8, 9, 17 }, { 10, 11, 18 }, { 12, 13, 19 }, { 0, } },
+  },
+  { "xori", TILEGX_OPC_XORI, 0x3, 3, TREG_ZERO, 1,
+    { { 6, 7, 0 }, { 8, 9, 1 }, { 0, }, { 0, }, { 0, } },
+  },
+  { NULL, TILEGX_OPC_NONE, 0, 0, TREG_ZERO, 0, { { 0, } },
+  }
+};
+#define BITFIELD(start, size) ((start) | (((1 << (size)) - 1) << 6))
+#define CHILD(array_index) (TILEGX_OPC_NONE + (array_index))
+
+static const unsigned short decode_X0_fsm[936] =
+{
+  BITFIELD(22, 9) /* index 0 */,
+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+  CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513),
+  CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513),
+  CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513),
+  CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513),
+  CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513),
+  CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513),
+  CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513),
+  CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513),
+  CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513),
+  CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513),
+  CHILD(513), CHILD(513), CHILD(513), CHILD(513), TILEGX_OPC_ADDXLI,
+  TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI,
+  TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI,
+  TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI,
+  TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI,
+  TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI,
+  TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI,
+  TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI,
+  TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI,
+  TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI,
+  TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI,
+  TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI,
+  TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI,
+  TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI,
+  TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI,
+  TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI,
+  TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_NONE,
+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_BFEXTS,
+  TILEGX_OPC_BFEXTS, TILEGX_OPC_BFEXTS, TILEGX_OPC_BFEXTS, TILEGX_OPC_BFEXTU,
+  TILEGX_OPC_BFEXTU, TILEGX_OPC_BFEXTU, TILEGX_OPC_BFEXTU, TILEGX_OPC_BFINS,
+  TILEGX_OPC_BFINS, TILEGX_OPC_BFINS, TILEGX_OPC_BFINS, TILEGX_OPC_MM,
+  TILEGX_OPC_MM, TILEGX_OPC_MM, TILEGX_OPC_MM, TILEGX_OPC_NONE,
+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, CHILD(528), CHILD(578),
+  CHILD(583), CHILD(588), CHILD(593), CHILD(598), TILEGX_OPC_NONE,
+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+  TILEGX_OPC_NONE, CHILD(603), CHILD(620), CHILD(637), CHILD(654), CHILD(671),
+  CHILD(703), CHILD(797), CHILD(814), CHILD(831), CHILD(848), CHILD(865),
+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+  TILEGX_OPC_NONE, CHILD(889), TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+  TILEGX_OPC_NONE, CHILD(906), CHILD(906), CHILD(906), CHILD(906), CHILD(906),
+  CHILD(906), CHILD(906), CHILD(906), CHILD(906), CHILD(906), CHILD(906),
+  CHILD(906), CHILD(906), CHILD(906), CHILD(906), CHILD(906), CHILD(906),
+  CHILD(906), CHILD(906), CHILD(906), CHILD(906), CHILD(906), CHILD(906),
+  CHILD(906), CHILD(906), CHILD(906), CHILD(906), CHILD(906), CHILD(906),
+  CHILD(906), CHILD(906), CHILD(906), CHILD(906), CHILD(906), CHILD(906),
+  CHILD(906), CHILD(906), CHILD(906), CHILD(906), CHILD(906), CHILD(906),
+  CHILD(906), CHILD(906), CHILD(906), CHILD(906), CHILD(906), CHILD(906),
+  CHILD(906), CHILD(906), CHILD(906), CHILD(906), CHILD(906), CHILD(906),
+  CHILD(906), CHILD(906), CHILD(906), CHILD(906), CHILD(906), CHILD(906),
+  CHILD(906), CHILD(906), CHILD(906), CHILD(906), CHILD(906),
+  BITFIELD(6, 2) /* index 513 */,
+  TILEGX_OPC_ADDLI, TILEGX_OPC_ADDLI, TILEGX_OPC_ADDLI, CHILD(518),
+  BITFIELD(8, 2) /* index 518 */,
+  TILEGX_OPC_ADDLI, TILEGX_OPC_ADDLI, TILEGX_OPC_ADDLI, CHILD(523),
+  BITFIELD(10, 2) /* index 523 */,
+  TILEGX_OPC_ADDLI, TILEGX_OPC_ADDLI, TILEGX_OPC_ADDLI, TILEGX_OPC_MOVELI,
+  BITFIELD(20, 2) /* index 528 */,
+  TILEGX_OPC_NONE, CHILD(533), TILEGX_OPC_ADDXI, CHILD(548),
+  BITFIELD(6, 2) /* index 533 */,
+  TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, CHILD(538),
+  BITFIELD(8, 2) /* index 538 */,
+  TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, CHILD(543),
+  BITFIELD(10, 2) /* index 543 */,
+  TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, TILEGX_OPC_MOVEI,
+  BITFIELD(0, 2) /* index 548 */,
+  TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, CHILD(553),
+  BITFIELD(2, 2) /* index 553 */,
+  TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, CHILD(558),
+  BITFIELD(4, 2) /* index 558 */,
+  TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, CHILD(563),
+  BITFIELD(6, 2) /* index 563 */,
+  TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, CHILD(568),
+  BITFIELD(8, 2) /* index 568 */,
+  TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, CHILD(573),
+  BITFIELD(10, 2) /* index 573 */,
+  TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_INFO,
+  BITFIELD(20, 2) /* index 578 */,
+  TILEGX_OPC_CMPEQI, TILEGX_OPC_CMPLTSI, TILEGX_OPC_CMPLTUI, TILEGX_OPC_ORI,
+  BITFIELD(20, 2) /* index 583 */,
+  TILEGX_OPC_V1ADDI, TILEGX_OPC_V1CMPEQI, TILEGX_OPC_V1CMPLTSI,
+  TILEGX_OPC_V1CMPLTUI,
+  BITFIELD(20, 2) /* index 588 */,
+  TILEGX_OPC_V1MAXUI, TILEGX_OPC_V1MINUI, TILEGX_OPC_V2ADDI,
+  TILEGX_OPC_V2CMPEQI,
+  BITFIELD(20, 2) /* index 593 */,
+  TILEGX_OPC_V2CMPLTSI, TILEGX_OPC_V2CMPLTUI, TILEGX_OPC_V2MAXSI,
+  TILEGX_OPC_V2MINSI,
+  BITFIELD(20, 2) /* index 598 */,
+  TILEGX_OPC_XORI, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+  BITFIELD(18, 4) /* index 603 */,
+  TILEGX_OPC_NONE, TILEGX_OPC_ADDXSC, TILEGX_OPC_ADDX, TILEGX_OPC_ADD,
+  TILEGX_OPC_AND, TILEGX_OPC_CMOVEQZ, TILEGX_OPC_CMOVNEZ, TILEGX_OPC_CMPEQ,
+  TILEGX_OPC_CMPLES, TILEGX_OPC_CMPLEU, TILEGX_OPC_CMPLTS, TILEGX_OPC_CMPLTU,
+  TILEGX_OPC_CMPNE, TILEGX_OPC_CMULAF, TILEGX_OPC_CMULA, TILEGX_OPC_CMULFR,
+  BITFIELD(18, 4) /* index 620 */,
+  TILEGX_OPC_CMULF, TILEGX_OPC_CMULHR, TILEGX_OPC_CMULH, TILEGX_OPC_CMUL,
+  TILEGX_OPC_CRC32_32, TILEGX_OPC_CRC32_8, TILEGX_OPC_DBLALIGN2,
+  TILEGX_OPC_DBLALIGN4, TILEGX_OPC_DBLALIGN6, TILEGX_OPC_DBLALIGN,
+  TILEGX_OPC_FDOUBLE_ADDSUB, TILEGX_OPC_FDOUBLE_ADD_FLAGS,
+  TILEGX_OPC_FDOUBLE_MUL_FLAGS, TILEGX_OPC_FDOUBLE_PACK1,
+  TILEGX_OPC_FDOUBLE_PACK2, TILEGX_OPC_FDOUBLE_SUB_FLAGS,
+  BITFIELD(18, 4) /* index 637 */,
+  TILEGX_OPC_FDOUBLE_UNPACK_MAX, TILEGX_OPC_FDOUBLE_UNPACK_MIN,
+  TILEGX_OPC_FSINGLE_ADD1, TILEGX_OPC_FSINGLE_ADDSUB2,
+  TILEGX_OPC_FSINGLE_MUL1, TILEGX_OPC_FSINGLE_MUL2, TILEGX_OPC_FSINGLE_PACK2,
+  TILEGX_OPC_FSINGLE_SUB1, TILEGX_OPC_MNZ, TILEGX_OPC_MULAX,
+  TILEGX_OPC_MULA_HS_HS, TILEGX_OPC_MULA_HS_HU, TILEGX_OPC_MULA_HS_LS,
+  TILEGX_OPC_MULA_HS_LU, TILEGX_OPC_MULA_HU_HU, TILEGX_OPC_MULA_HU_LS,
+  BITFIELD(18, 4) /* index 654 */,
+  TILEGX_OPC_MULA_HU_LU, TILEGX_OPC_MULA_LS_LS, TILEGX_OPC_MULA_LS_LU,
+  TILEGX_OPC_MULA_LU_LU, TILEGX_OPC_MULX, TILEGX_OPC_MUL_HS_HS,
+  TILEGX_OPC_MUL_HS_HU, TILEGX_OPC_MUL_HS_LS, TILEGX_OPC_MUL_HS_LU,
+  TILEGX_OPC_MUL_HU_HU, TILEGX_OPC_MUL_HU_LS, TILEGX_OPC_MUL_HU_LU,
+  TILEGX_OPC_MUL_LS_LS, TILEGX_OPC_MUL_LS_LU, TILEGX_OPC_MUL_LU_LU,
+  TILEGX_OPC_MZ,
+  BITFIELD(18, 4) /* index 671 */,
+  TILEGX_OPC_NOR, CHILD(688), TILEGX_OPC_ROTL, TILEGX_OPC_SHL1ADDX,
+  TILEGX_OPC_SHL1ADD, TILEGX_OPC_SHL2ADDX, TILEGX_OPC_SHL2ADD,
+  TILEGX_OPC_SHL3ADDX, TILEGX_OPC_SHL3ADD, TILEGX_OPC_SHLX, TILEGX_OPC_SHL,
+  TILEGX_OPC_SHRS, TILEGX_OPC_SHRUX, TILEGX_OPC_SHRU, TILEGX_OPC_SHUFFLEBYTES,
+  TILEGX_OPC_SUBXSC,
+  BITFIELD(12, 2) /* index 688 */,
+  TILEGX_OPC_OR, TILEGX_OPC_OR, TILEGX_OPC_OR, CHILD(693),
+  BITFIELD(14, 2) /* index 693 */,
+  TILEGX_OPC_OR, TILEGX_OPC_OR, TILEGX_OPC_OR, CHILD(698),
+  BITFIELD(16, 2) /* index 698 */,
+  TILEGX_OPC_OR, TILEGX_OPC_OR, TILEGX_OPC_OR, TILEGX_OPC_MOVE,
+  BITFIELD(18, 4) /* index 703 */,
+  TILEGX_OPC_SUBX, TILEGX_OPC_SUB, CHILD(720), TILEGX_OPC_V1ADDUC,
+  TILEGX_OPC_V1ADD, TILEGX_OPC_V1ADIFFU, TILEGX_OPC_V1AVGU,
+  TILEGX_OPC_V1CMPEQ, TILEGX_OPC_V1CMPLES, TILEGX_OPC_V1CMPLEU,
+  TILEGX_OPC_V1CMPLTS, TILEGX_OPC_V1CMPLTU, TILEGX_OPC_V1CMPNE,
+  TILEGX_OPC_V1DDOTPUSA, TILEGX_OPC_V1DDOTPUS, TILEGX_OPC_V1DOTPA,
+  BITFIELD(12, 4) /* index 720 */,
+  TILEGX_OPC_NONE, CHILD(737), CHILD(742), CHILD(747), CHILD(752), CHILD(757),
+  CHILD(762), CHILD(767), CHILD(772), CHILD(777), CHILD(782), CHILD(787),
+  CHILD(792), TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+  BITFIELD(16, 2) /* index 737 */,
+  TILEGX_OPC_CLZ, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+  BITFIELD(16, 2) /* index 742 */,
+  TILEGX_OPC_CTZ, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+  BITFIELD(16, 2) /* index 747 */,
+  TILEGX_OPC_FNOP, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+  BITFIELD(16, 2) /* index 752 */,
+  TILEGX_OPC_FSINGLE_PACK1, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+  BITFIELD(16, 2) /* index 757 */,
+  TILEGX_OPC_NOP, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+  BITFIELD(16, 2) /* index 762 */,
+  TILEGX_OPC_PCNT, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+  BITFIELD(16, 2) /* index 767 */,
+  TILEGX_OPC_REVBITS, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+  BITFIELD(16, 2) /* index 772 */,
+  TILEGX_OPC_REVBYTES, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+  BITFIELD(16, 2) /* index 777 */,
+  TILEGX_OPC_TBLIDXB0, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+  BITFIELD(16, 2) /* index 782 */,
+  TILEGX_OPC_TBLIDXB1, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+  BITFIELD(16, 2) /* index 787 */,
+  TILEGX_OPC_TBLIDXB2, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+  BITFIELD(16, 2) /* index 792 */,
+  TILEGX_OPC_TBLIDXB3, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+  BITFIELD(18, 4) /* index 797 */,
+  TILEGX_OPC_V1DOTPUSA, TILEGX_OPC_V1DOTPUS, TILEGX_OPC_V1DOTP,
+  TILEGX_OPC_V1INT_H, TILEGX_OPC_V1INT_L, TILEGX_OPC_V1MAXU,
+  TILEGX_OPC_V1MINU, TILEGX_OPC_V1MNZ, TILEGX_OPC_V1MULTU, TILEGX_OPC_V1MULUS,
+  TILEGX_OPC_V1MULU, TILEGX_OPC_V1MZ, TILEGX_OPC_V1SADAU, TILEGX_OPC_V1SADU,
+  TILEGX_OPC_V1SHL, TILEGX_OPC_V1SHRS,
+  BITFIELD(18, 4) /* index 814 */,
+  TILEGX_OPC_V1SHRU, TILEGX_OPC_V1SUBUC, TILEGX_OPC_V1SUB, TILEGX_OPC_V2ADDSC,
+  TILEGX_OPC_V2ADD, TILEGX_OPC_V2ADIFFS, TILEGX_OPC_V2AVGS,
+  TILEGX_OPC_V2CMPEQ, TILEGX_OPC_V2CMPLES, TILEGX_OPC_V2CMPLEU,
+  TILEGX_OPC_V2CMPLTS, TILEGX_OPC_V2CMPLTU, TILEGX_OPC_V2CMPNE,
+  TILEGX_OPC_V2DOTPA, TILEGX_OPC_V2DOTP, TILEGX_OPC_V2INT_H,
+  BITFIELD(18, 4) /* index 831 */,
+  TILEGX_OPC_V2INT_L, TILEGX_OPC_V2MAXS, TILEGX_OPC_V2MINS, TILEGX_OPC_V2MNZ,
+  TILEGX_OPC_V2MULFSC, TILEGX_OPC_V2MULS, TILEGX_OPC_V2MULTS, TILEGX_OPC_V2MZ,
+  TILEGX_OPC_V2PACKH, TILEGX_OPC_V2PACKL, TILEGX_OPC_V2PACKUC,
+  TILEGX_OPC_V2SADAS, TILEGX_OPC_V2SADAU, TILEGX_OPC_V2SADS,
+  TILEGX_OPC_V2SADU, TILEGX_OPC_V2SHLSC,
+  BITFIELD(18, 4) /* index 848 */,
+  TILEGX_OPC_V2SHL, TILEGX_OPC_V2SHRS, TILEGX_OPC_V2SHRU, TILEGX_OPC_V2SUBSC,
+  TILEGX_OPC_V2SUB, TILEGX_OPC_V4ADDSC, TILEGX_OPC_V4ADD, TILEGX_OPC_V4INT_H,
+  TILEGX_OPC_V4INT_L, TILEGX_OPC_V4PACKSC, TILEGX_OPC_V4SHLSC,
+  TILEGX_OPC_V4SHL, TILEGX_OPC_V4SHRS, TILEGX_OPC_V4SHRU, TILEGX_OPC_V4SUBSC,
+  TILEGX_OPC_V4SUB,
+  BITFIELD(18, 3) /* index 865 */,
+  CHILD(874), CHILD(877), CHILD(880), CHILD(883), CHILD(886), TILEGX_OPC_NONE,
+  TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+  BITFIELD(21, 1) /* index 874 */,
+  TILEGX_OPC_XOR, TILEGX_OPC_NONE,
+  BITFIELD(21, 1) /* index 877 */,
+  TILEGX_OPC_V1DDOTPUA, TILEGX_OPC_NONE,
+  BITFIELD(21, 1) /* index 880 */,
+  TILEGX_OPC_V1DDOTPU, TILEGX_OPC_NONE,
+  BITFIELD(21, 1) /* index 883 */,
+  TILEGX_OPC_V1DOTPUA, TILEGX_OPC_NONE,
+  BITFIELD(21, 1) /* index 886 */,
+  TILEGX_OPC_V1DOTPU, TILEGX_OPC_NONE,
+  BITFIELD(18, 4) /* index 889 */,
+  TILEGX_OPC_NONE, TILEGX_OPC_ROTLI, TILEGX_OPC_SHLI, TILEGX_OPC_SHLXI,
+  TILEGX_OPC_SHRSI, TILEGX_OPC_SHRUI, TILEGX_OPC_SHRUXI, TILEGX_OPC_V1SHLI,
+  TILEGX_OPC_V1SHRSI, TILEGX_OPC_V1SHRUI, TILEGX_OPC_V2SHLI,
+  TILEGX_OPC_V2SHRSI, TILEGX_OPC_V2SHRUI, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+  TILEGX_OPC_NONE,
+  BITFIELD(0, 2) /* index 906 */,
+  TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI,
+  CHILD(911),
+  BITFIELD(2, 2) /* index 911 */,
+  TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI,
+  CHILD(916),
+  BITFIELD(4, 2) /* index 916 */,
+  TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI,
+  CHILD(921),
+  BITFIELD(6, 2) /* index 921 */,
+  TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI,
+  CHILD(926),
+  BITFIELD(8, 2) /* index 926 */,
+  TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI,
+  CHILD(931),
+  BITFIELD(10, 2) /* index 931 */,
+  TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI,
+  TILEGX_OPC_INFOL,
+};
+
+static const unsigned short decode_X1_fsm[1206] =
+{
+  BITFIELD(53, 9) /* index 0 */,
+  CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513),
+  CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513),
+  CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513),
+  CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513),
+  CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513),
+  CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513),
+  CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513),
+  CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513),
+  CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513),
+  CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513), CHILD(513),
+  CHILD(513), CHILD(513), CHILD(513), CHILD(513), TILEGX_OPC_ADDXLI,
+  TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI,
+  TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI,
+  TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI,
+  TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI,
+  TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI,
+  TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI,
+  TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI,
+  TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI,
+  TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI,
+  TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI,
+  TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI,
+  TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI,
+  TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI,
+  TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI,
+  TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI,
+  TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_ADDXLI, TILEGX_OPC_NONE,
+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_BEQZT,
+  TILEGX_OPC_BEQZT, TILEGX_OPC_BEQZ, TILEGX_OPC_BEQZ, TILEGX_OPC_BGEZT,
+  TILEGX_OPC_BGEZT, TILEGX_OPC_BGEZ, TILEGX_OPC_BGEZ, TILEGX_OPC_BGTZT,
+  TILEGX_OPC_BGTZT, TILEGX_OPC_BGTZ, TILEGX_OPC_BGTZ, TILEGX_OPC_BLBCT,
+  TILEGX_OPC_BLBCT, TILEGX_OPC_BLBC, TILEGX_OPC_BLBC, TILEGX_OPC_BLBST,
+  TILEGX_OPC_BLBST, TILEGX_OPC_BLBS, TILEGX_OPC_BLBS, TILEGX_OPC_BLEZT,
+  TILEGX_OPC_BLEZT, TILEGX_OPC_BLEZ, TILEGX_OPC_BLEZ, TILEGX_OPC_BLTZT,
+  TILEGX_OPC_BLTZT, TILEGX_OPC_BLTZ, TILEGX_OPC_BLTZ, TILEGX_OPC_BNEZT,
+  TILEGX_OPC_BNEZT, TILEGX_OPC_BNEZ, TILEGX_OPC_BNEZ, CHILD(528), CHILD(578),
+  CHILD(598), CHILD(663), CHILD(683), CHILD(688), CHILD(693), CHILD(698),
+  CHILD(703), CHILD(708), CHILD(713), CHILD(718), TILEGX_OPC_NONE,
+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_JAL,
+  TILEGX_OPC_JAL, TILEGX_OPC_JAL, TILEGX_OPC_JAL, TILEGX_OPC_JAL,
+  TILEGX_OPC_JAL, TILEGX_OPC_JAL, TILEGX_OPC_JAL, TILEGX_OPC_JAL,
+  TILEGX_OPC_JAL, TILEGX_OPC_JAL, TILEGX_OPC_JAL, TILEGX_OPC_JAL,
+  TILEGX_OPC_JAL, TILEGX_OPC_JAL, TILEGX_OPC_JAL, TILEGX_OPC_JAL,
+  TILEGX_OPC_JAL, TILEGX_OPC_JAL, TILEGX_OPC_JAL, TILEGX_OPC_JAL,
+  TILEGX_OPC_JAL, TILEGX_OPC_JAL, TILEGX_OPC_JAL, TILEGX_OPC_JAL,
+  TILEGX_OPC_JAL, TILEGX_OPC_JAL, TILEGX_OPC_JAL, TILEGX_OPC_JAL,
+  TILEGX_OPC_JAL, TILEGX_OPC_JAL, TILEGX_OPC_JAL, TILEGX_OPC_J, TILEGX_OPC_J,
+  TILEGX_OPC_J, TILEGX_OPC_J, TILEGX_OPC_J, TILEGX_OPC_J, TILEGX_OPC_J,
+  TILEGX_OPC_J, TILEGX_OPC_J, TILEGX_OPC_J, TILEGX_OPC_J, TILEGX_OPC_J,
+  TILEGX_OPC_J, TILEGX_OPC_J, TILEGX_OPC_J, TILEGX_OPC_J, TILEGX_OPC_J,
+  TILEGX_OPC_J, TILEGX_OPC_J, TILEGX_OPC_J, TILEGX_OPC_J, TILEGX_OPC_J,
+  TILEGX_OPC_J, TILEGX_OPC_J, TILEGX_OPC_J, TILEGX_OPC_J, TILEGX_OPC_J,
+  TILEGX_OPC_J, TILEGX_OPC_J, TILEGX_OPC_J, TILEGX_OPC_J, TILEGX_OPC_J,
+  CHILD(723), CHILD(740), CHILD(772), CHILD(789), CHILD(1108), CHILD(1125),
+  CHILD(1142), TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, CHILD(1159), TILEGX_OPC_NONE,
+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, CHILD(1176), CHILD(1176), CHILD(1176),
+  CHILD(1176), CHILD(1176), CHILD(1176), CHILD(1176), CHILD(1176),
+  CHILD(1176), CHILD(1176), CHILD(1176), CHILD(1176), CHILD(1176),
+  CHILD(1176), CHILD(1176), CHILD(1176), CHILD(1176), CHILD(1176),
+  CHILD(1176), CHILD(1176), CHILD(1176), CHILD(1176), CHILD(1176),
+  CHILD(1176), CHILD(1176), CHILD(1176), CHILD(1176), CHILD(1176),
+  CHILD(1176), CHILD(1176), CHILD(1176), CHILD(1176), CHILD(1176),
+  CHILD(1176), CHILD(1176), CHILD(1176), CHILD(1176), CHILD(1176),
+  CHILD(1176), CHILD(1176), CHILD(1176), CHILD(1176), CHILD(1176),
+  CHILD(1176), CHILD(1176), CHILD(1176), CHILD(1176), CHILD(1176),
+  CHILD(1176), CHILD(1176), CHILD(1176), CHILD(1176), CHILD(1176),
+  CHILD(1176), CHILD(1176), CHILD(1176), CHILD(1176), CHILD(1176),
+  CHILD(1176), CHILD(1176), CHILD(1176), CHILD(1176), CHILD(1176),
+  CHILD(1176),
+  BITFIELD(37, 2) /* index 513 */,
+  TILEGX_OPC_ADDLI, TILEGX_OPC_ADDLI, TILEGX_OPC_ADDLI, CHILD(518),
+  BITFIELD(39, 2) /* index 518 */,
+  TILEGX_OPC_ADDLI, TILEGX_OPC_ADDLI, TILEGX_OPC_ADDLI, CHILD(523),
+  BITFIELD(41, 2) /* index 523 */,
+  TILEGX_OPC_ADDLI, TILEGX_OPC_ADDLI, TILEGX_OPC_ADDLI, TILEGX_OPC_MOVELI,
+  BITFIELD(51, 2) /* index 528 */,
+  TILEGX_OPC_NONE, CHILD(533), TILEGX_OPC_ADDXI, CHILD(548),
+  BITFIELD(37, 2) /* index 533 */,
+  TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, CHILD(538),
+  BITFIELD(39, 2) /* index 538 */,
+  TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, CHILD(543),
+  BITFIELD(41, 2) /* index 543 */,
+  TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, TILEGX_OPC_MOVEI,
+  BITFIELD(31, 2) /* index 548 */,
+  TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, CHILD(553),
+  BITFIELD(33, 2) /* index 553 */,
+  TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, CHILD(558),
+  BITFIELD(35, 2) /* index 558 */,
+  TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, CHILD(563),
+  BITFIELD(37, 2) /* index 563 */,
+  TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, CHILD(568),
+  BITFIELD(39, 2) /* index 568 */,
+  TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, CHILD(573),
+  BITFIELD(41, 2) /* index 573 */,
+  TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_INFO,
+  BITFIELD(51, 2) /* index 578 */,
+  TILEGX_OPC_CMPEQI, TILEGX_OPC_CMPLTSI, TILEGX_OPC_CMPLTUI, CHILD(583),
+  BITFIELD(31, 2) /* index 583 */,
+  TILEGX_OPC_LD1S_ADD, TILEGX_OPC_LD1S_ADD, TILEGX_OPC_LD1S_ADD, CHILD(588),
+  BITFIELD(33, 2) /* index 588 */,
+  TILEGX_OPC_LD1S_ADD, TILEGX_OPC_LD1S_ADD, TILEGX_OPC_LD1S_ADD, CHILD(593),
+  BITFIELD(35, 2) /* index 593 */,
+  TILEGX_OPC_LD1S_ADD, TILEGX_OPC_LD1S_ADD, TILEGX_OPC_LD1S_ADD,
+  TILEGX_OPC_PREFETCH_ADD_L1_FAULT,
+  BITFIELD(51, 2) /* index 598 */,
+  CHILD(603), CHILD(618), CHILD(633), CHILD(648),
+  BITFIELD(31, 2) /* index 603 */,
+  TILEGX_OPC_LD1U_ADD, TILEGX_OPC_LD1U_ADD, TILEGX_OPC_LD1U_ADD, CHILD(608),
+  BITFIELD(33, 2) /* index 608 */,
+  TILEGX_OPC_LD1U_ADD, TILEGX_OPC_LD1U_ADD, TILEGX_OPC_LD1U_ADD, CHILD(613),
+  BITFIELD(35, 2) /* index 613 */,
+  TILEGX_OPC_LD1U_ADD, TILEGX_OPC_LD1U_ADD, TILEGX_OPC_LD1U_ADD,
+  TILEGX_OPC_PREFETCH_ADD_L1,
+  BITFIELD(31, 2) /* index 618 */,
+  TILEGX_OPC_LD2S_ADD, TILEGX_OPC_LD2S_ADD, TILEGX_OPC_LD2S_ADD, CHILD(623),
+  BITFIELD(33, 2) /* index 623 */,
+  TILEGX_OPC_LD2S_ADD, TILEGX_OPC_LD2S_ADD, TILEGX_OPC_LD2S_ADD, CHILD(628),
+  BITFIELD(35, 2) /* index 628 */,
+  TILEGX_OPC_LD2S_ADD, TILEGX_OPC_LD2S_ADD, TILEGX_OPC_LD2S_ADD,
+  TILEGX_OPC_PREFETCH_ADD_L2_FAULT,
+  BITFIELD(31, 2) /* index 633 */,
+  TILEGX_OPC_LD2U_ADD, TILEGX_OPC_LD2U_ADD, TILEGX_OPC_LD2U_ADD, CHILD(638),
+  BITFIELD(33, 2) /* index 638 */,
+  TILEGX_OPC_LD2U_ADD, TILEGX_OPC_LD2U_ADD, TILEGX_OPC_LD2U_ADD, CHILD(643),
+  BITFIELD(35, 2) /* index 643 */,
+  TILEGX_OPC_LD2U_ADD, TILEGX_OPC_LD2U_ADD, TILEGX_OPC_LD2U_ADD,
+  TILEGX_OPC_PREFETCH_ADD_L2,
+  BITFIELD(31, 2) /* index 648 */,
+  TILEGX_OPC_LD4S_ADD, TILEGX_OPC_LD4S_ADD, TILEGX_OPC_LD4S_ADD, CHILD(653),
+  BITFIELD(33, 2) /* index 653 */,
+  TILEGX_OPC_LD4S_ADD, TILEGX_OPC_LD4S_ADD, TILEGX_OPC_LD4S_ADD, CHILD(658),
+  BITFIELD(35, 2) /* index 658 */,
+  TILEGX_OPC_LD4S_ADD, TILEGX_OPC_LD4S_ADD, TILEGX_OPC_LD4S_ADD,
+  TILEGX_OPC_PREFETCH_ADD_L3_FAULT,
+  BITFIELD(51, 2) /* index 663 */,
+  CHILD(668), TILEGX_OPC_LDNT1S_ADD, TILEGX_OPC_LDNT1U_ADD,
+  TILEGX_OPC_LDNT2S_ADD,
+  BITFIELD(31, 2) /* index 668 */,
+  TILEGX_OPC_LD4U_ADD, TILEGX_OPC_LD4U_ADD, TILEGX_OPC_LD4U_ADD, CHILD(673),
+  BITFIELD(33, 2) /* index 673 */,
+  TILEGX_OPC_LD4U_ADD, TILEGX_OPC_LD4U_ADD, TILEGX_OPC_LD4U_ADD, CHILD(678),
+  BITFIELD(35, 2) /* index 678 */,
+  TILEGX_OPC_LD4U_ADD, TILEGX_OPC_LD4U_ADD, TILEGX_OPC_LD4U_ADD,
+  TILEGX_OPC_PREFETCH_ADD_L3,
+  BITFIELD(51, 2) /* index 683 */,
+  TILEGX_OPC_LDNT2U_ADD, TILEGX_OPC_LDNT4S_ADD, TILEGX_OPC_LDNT4U_ADD,
+  TILEGX_OPC_LDNT_ADD,
+  BITFIELD(51, 2) /* index 688 */,
+  TILEGX_OPC_LD_ADD, TILEGX_OPC_LDNA_ADD, TILEGX_OPC_MFSPR, TILEGX_OPC_MTSPR,
+  BITFIELD(51, 2) /* index 693 */,
+  TILEGX_OPC_ORI, TILEGX_OPC_ST1_ADD, TILEGX_OPC_ST2_ADD, TILEGX_OPC_ST4_ADD,
+  BITFIELD(51, 2) /* index 698 */,
+  TILEGX_OPC_STNT1_ADD, TILEGX_OPC_STNT2_ADD, TILEGX_OPC_STNT4_ADD,
+  TILEGX_OPC_STNT_ADD,
+  BITFIELD(51, 2) /* index 703 */,
+  TILEGX_OPC_ST_ADD, TILEGX_OPC_V1ADDI, TILEGX_OPC_V1CMPEQI,
+  TILEGX_OPC_V1CMPLTSI,
+  BITFIELD(51, 2) /* index 708 */,
+  TILEGX_OPC_V1CMPLTUI, TILEGX_OPC_V1MAXUI, TILEGX_OPC_V1MINUI,
+  TILEGX_OPC_V2ADDI,
+  BITFIELD(51, 2) /* index 713 */,
+  TILEGX_OPC_V2CMPEQI, TILEGX_OPC_V2CMPLTSI, TILEGX_OPC_V2CMPLTUI,
+  TILEGX_OPC_V2MAXSI,
+  BITFIELD(51, 2) /* index 718 */,
+  TILEGX_OPC_V2MINSI, TILEGX_OPC_XORI, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+  BITFIELD(49, 4) /* index 723 */,
+  TILEGX_OPC_NONE, TILEGX_OPC_ADDXSC, TILEGX_OPC_ADDX, TILEGX_OPC_ADD,
+  TILEGX_OPC_AND, TILEGX_OPC_CMPEQ, TILEGX_OPC_CMPEXCH4, TILEGX_OPC_CMPEXCH,
+  TILEGX_OPC_CMPLES, TILEGX_OPC_CMPLEU, TILEGX_OPC_CMPLTS, TILEGX_OPC_CMPLTU,
+  TILEGX_OPC_CMPNE, TILEGX_OPC_DBLALIGN2, TILEGX_OPC_DBLALIGN4,
+  TILEGX_OPC_DBLALIGN6,
+  BITFIELD(49, 4) /* index 740 */,
+  TILEGX_OPC_EXCH4, TILEGX_OPC_EXCH, TILEGX_OPC_FETCHADD4,
+  TILEGX_OPC_FETCHADDGEZ4, TILEGX_OPC_FETCHADDGEZ, TILEGX_OPC_FETCHADD,
+  TILEGX_OPC_FETCHAND4, TILEGX_OPC_FETCHAND, TILEGX_OPC_FETCHOR4,
+  TILEGX_OPC_FETCHOR, TILEGX_OPC_MNZ, TILEGX_OPC_MZ, TILEGX_OPC_NOR,
+  CHILD(757), TILEGX_OPC_ROTL, TILEGX_OPC_SHL1ADDX,
+  BITFIELD(43, 2) /* index 757 */,
+  TILEGX_OPC_OR, TILEGX_OPC_OR, TILEGX_OPC_OR, CHILD(762),
+  BITFIELD(45, 2) /* index 762 */,
+  TILEGX_OPC_OR, TILEGX_OPC_OR, TILEGX_OPC_OR, CHILD(767),
+  BITFIELD(47, 2) /* index 767 */,
+  TILEGX_OPC_OR, TILEGX_OPC_OR, TILEGX_OPC_OR, TILEGX_OPC_MOVE,
+  BITFIELD(49, 4) /* index 772 */,
+  TILEGX_OPC_SHL1ADD, TILEGX_OPC_SHL2ADDX, TILEGX_OPC_SHL2ADD,
+  TILEGX_OPC_SHL3ADDX, TILEGX_OPC_SHL3ADD, TILEGX_OPC_SHLX, TILEGX_OPC_SHL,
+  TILEGX_OPC_SHRS, TILEGX_OPC_SHRUX, TILEGX_OPC_SHRU, TILEGX_OPC_ST1,
+  TILEGX_OPC_ST2, TILEGX_OPC_ST4, TILEGX_OPC_STNT1, TILEGX_OPC_STNT2,
+  TILEGX_OPC_STNT4,
+  BITFIELD(46, 7) /* index 789 */,
+  TILEGX_OPC_STNT, TILEGX_OPC_STNT, TILEGX_OPC_STNT, TILEGX_OPC_STNT,
+  TILEGX_OPC_STNT, TILEGX_OPC_STNT, TILEGX_OPC_STNT, TILEGX_OPC_STNT,
+  TILEGX_OPC_ST, TILEGX_OPC_ST, TILEGX_OPC_ST, TILEGX_OPC_ST, TILEGX_OPC_ST,
+  TILEGX_OPC_ST, TILEGX_OPC_ST, TILEGX_OPC_ST, TILEGX_OPC_SUBXSC,
+  TILEGX_OPC_SUBXSC, TILEGX_OPC_SUBXSC, TILEGX_OPC_SUBXSC, TILEGX_OPC_SUBXSC,
+  TILEGX_OPC_SUBXSC, TILEGX_OPC_SUBXSC, TILEGX_OPC_SUBXSC, TILEGX_OPC_SUBX,
+  TILEGX_OPC_SUBX, TILEGX_OPC_SUBX, TILEGX_OPC_SUBX, TILEGX_OPC_SUBX,
+  TILEGX_OPC_SUBX, TILEGX_OPC_SUBX, TILEGX_OPC_SUBX, TILEGX_OPC_SUB,
+  TILEGX_OPC_SUB, TILEGX_OPC_SUB, TILEGX_OPC_SUB, TILEGX_OPC_SUB,
+  TILEGX_OPC_SUB, TILEGX_OPC_SUB, TILEGX_OPC_SUB, CHILD(918), CHILD(927),
+  CHILD(1006), CHILD(1090), CHILD(1099), TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+  TILEGX_OPC_NONE, TILEGX_OPC_V1ADDUC, TILEGX_OPC_V1ADDUC, TILEGX_OPC_V1ADDUC,
+  TILEGX_OPC_V1ADDUC, TILEGX_OPC_V1ADDUC, TILEGX_OPC_V1ADDUC,
+  TILEGX_OPC_V1ADDUC, TILEGX_OPC_V1ADDUC, TILEGX_OPC_V1ADD, TILEGX_OPC_V1ADD,
+  TILEGX_OPC_V1ADD, TILEGX_OPC_V1ADD, TILEGX_OPC_V1ADD, TILEGX_OPC_V1ADD,
+  TILEGX_OPC_V1ADD, TILEGX_OPC_V1ADD, TILEGX_OPC_V1CMPEQ, TILEGX_OPC_V1CMPEQ,
+  TILEGX_OPC_V1CMPEQ, TILEGX_OPC_V1CMPEQ, TILEGX_OPC_V1CMPEQ,
+  TILEGX_OPC_V1CMPEQ, TILEGX_OPC_V1CMPEQ, TILEGX_OPC_V1CMPEQ,
+  TILEGX_OPC_V1CMPLES, TILEGX_OPC_V1CMPLES, TILEGX_OPC_V1CMPLES,
+  TILEGX_OPC_V1CMPLES, TILEGX_OPC_V1CMPLES, TILEGX_OPC_V1CMPLES,
+  TILEGX_OPC_V1CMPLES, TILEGX_OPC_V1CMPLES, TILEGX_OPC_V1CMPLEU,
+  TILEGX_OPC_V1CMPLEU, TILEGX_OPC_V1CMPLEU, TILEGX_OPC_V1CMPLEU,
+  TILEGX_OPC_V1CMPLEU, TILEGX_OPC_V1CMPLEU, TILEGX_OPC_V1CMPLEU,
+  TILEGX_OPC_V1CMPLEU, TILEGX_OPC_V1CMPLTS, TILEGX_OPC_V1CMPLTS,
+  TILEGX_OPC_V1CMPLTS, TILEGX_OPC_V1CMPLTS, TILEGX_OPC_V1CMPLTS,
+  TILEGX_OPC_V1CMPLTS, TILEGX_OPC_V1CMPLTS, TILEGX_OPC_V1CMPLTS,
+  TILEGX_OPC_V1CMPLTU, TILEGX_OPC_V1CMPLTU, TILEGX_OPC_V1CMPLTU,
+  TILEGX_OPC_V1CMPLTU, TILEGX_OPC_V1CMPLTU, TILEGX_OPC_V1CMPLTU,
+  TILEGX_OPC_V1CMPLTU, TILEGX_OPC_V1CMPLTU, TILEGX_OPC_V1CMPNE,
+  TILEGX_OPC_V1CMPNE, TILEGX_OPC_V1CMPNE, TILEGX_OPC_V1CMPNE,
+  TILEGX_OPC_V1CMPNE, TILEGX_OPC_V1CMPNE, TILEGX_OPC_V1CMPNE,
+  TILEGX_OPC_V1CMPNE, TILEGX_OPC_V1INT_H, TILEGX_OPC_V1INT_H,
+  TILEGX_OPC_V1INT_H, TILEGX_OPC_V1INT_H, TILEGX_OPC_V1INT_H,
+  TILEGX_OPC_V1INT_H, TILEGX_OPC_V1INT_H, TILEGX_OPC_V1INT_H,
+  TILEGX_OPC_V1INT_L, TILEGX_OPC_V1INT_L, TILEGX_OPC_V1INT_L,
+  TILEGX_OPC_V1INT_L, TILEGX_OPC_V1INT_L, TILEGX_OPC_V1INT_L,
+  TILEGX_OPC_V1INT_L, TILEGX_OPC_V1INT_L,
+  BITFIELD(43, 3) /* index 918 */,
+  TILEGX_OPC_NONE, TILEGX_OPC_DRAIN, TILEGX_OPC_DTLBPR, TILEGX_OPC_FINV,
+  TILEGX_OPC_FLUSHWB, TILEGX_OPC_FLUSH, TILEGX_OPC_FNOP, TILEGX_OPC_ICOH,
+  BITFIELD(43, 3) /* index 927 */,
+  CHILD(936), TILEGX_OPC_INV, TILEGX_OPC_IRET, TILEGX_OPC_JALRP,
+  TILEGX_OPC_JALR, TILEGX_OPC_JRP, TILEGX_OPC_JR, CHILD(991),
+  BITFIELD(31, 2) /* index 936 */,
+  CHILD(941), CHILD(966), TILEGX_OPC_ILL, TILEGX_OPC_ILL,
+  BITFIELD(33, 2) /* index 941 */,
+  TILEGX_OPC_ILL, TILEGX_OPC_ILL, TILEGX_OPC_ILL, CHILD(946),
+  BITFIELD(35, 2) /* index 946 */,
+  TILEGX_OPC_ILL, CHILD(951), TILEGX_OPC_ILL, TILEGX_OPC_ILL,
+  BITFIELD(37, 2) /* index 951 */,
+  TILEGX_OPC_ILL, CHILD(956), TILEGX_OPC_ILL, TILEGX_OPC_ILL,
+  BITFIELD(39, 2) /* index 956 */,
+  TILEGX_OPC_ILL, CHILD(961), TILEGX_OPC_ILL, TILEGX_OPC_ILL,
+  BITFIELD(41, 2) /* index 961 */,
+  TILEGX_OPC_ILL, TILEGX_OPC_ILL, TILEGX_OPC_BPT, TILEGX_OPC_ILL,
+  BITFIELD(33, 2) /* index 966 */,
+  TILEGX_OPC_ILL, TILEGX_OPC_ILL, TILEGX_OPC_ILL, CHILD(971),
+  BITFIELD(35, 2) /* index 971 */,
+  TILEGX_OPC_ILL, CHILD(976), TILEGX_OPC_ILL, TILEGX_OPC_ILL,
+  BITFIELD(37, 2) /* index 976 */,
+  TILEGX_OPC_ILL, CHILD(981), TILEGX_OPC_ILL, TILEGX_OPC_ILL,
+  BITFIELD(39, 2) /* index 981 */,
+  TILEGX_OPC_ILL, CHILD(986), TILEGX_OPC_ILL, TILEGX_OPC_ILL,
+  BITFIELD(41, 2) /* index 986 */,
+  TILEGX_OPC_ILL, TILEGX_OPC_ILL, TILEGX_OPC_RAISE, TILEGX_OPC_ILL,
+  BITFIELD(31, 2) /* index 991 */,
+  TILEGX_OPC_LD1S, TILEGX_OPC_LD1S, TILEGX_OPC_LD1S, CHILD(996),
+  BITFIELD(33, 2) /* index 996 */,
+  TILEGX_OPC_LD1S, TILEGX_OPC_LD1S, TILEGX_OPC_LD1S, CHILD(1001),
+  BITFIELD(35, 2) /* index 1001 */,
+  TILEGX_OPC_LD1S, TILEGX_OPC_LD1S, TILEGX_OPC_LD1S,
+  TILEGX_OPC_PREFETCH_L1_FAULT,
+  BITFIELD(43, 3) /* index 1006 */,
+  CHILD(1015), CHILD(1030), CHILD(1045), CHILD(1060), CHILD(1075),
+  TILEGX_OPC_LDNA, TILEGX_OPC_LDNT1S, TILEGX_OPC_LDNT1U,
+  BITFIELD(31, 2) /* index 1015 */,
+  TILEGX_OPC_LD1U, TILEGX_OPC_LD1U, TILEGX_OPC_LD1U, CHILD(1020),
+  BITFIELD(33, 2) /* index 1020 */,
+  TILEGX_OPC_LD1U, TILEGX_OPC_LD1U, TILEGX_OPC_LD1U, CHILD(1025),
+  BITFIELD(35, 2) /* index 1025 */,
+  TILEGX_OPC_LD1U, TILEGX_OPC_LD1U, TILEGX_OPC_LD1U, TILEGX_OPC_PREFETCH,
+  BITFIELD(31, 2) /* index 1030 */,
+  TILEGX_OPC_LD2S, TILEGX_OPC_LD2S, TILEGX_OPC_LD2S, CHILD(1035),
+  BITFIELD(33, 2) /* index 1035 */,
+  TILEGX_OPC_LD2S, TILEGX_OPC_LD2S, TILEGX_OPC_LD2S, CHILD(1040),
+  BITFIELD(35, 2) /* index 1040 */,
+  TILEGX_OPC_LD2S, TILEGX_OPC_LD2S, TILEGX_OPC_LD2S,
+  TILEGX_OPC_PREFETCH_L2_FAULT,
+  BITFIELD(31, 2) /* index 1045 */,
+  TILEGX_OPC_LD2U, TILEGX_OPC_LD2U, TILEGX_OPC_LD2U, CHILD(1050),
+  BITFIELD(33, 2) /* index 1050 */,
+  TILEGX_OPC_LD2U, TILEGX_OPC_LD2U, TILEGX_OPC_LD2U, CHILD(1055),
+  BITFIELD(35, 2) /* index 1055 */,
+  TILEGX_OPC_LD2U, TILEGX_OPC_LD2U, TILEGX_OPC_LD2U, TILEGX_OPC_PREFETCH_L2,
+  BITFIELD(31, 2) /* index 1060 */,
+  TILEGX_OPC_LD4S, TILEGX_OPC_LD4S, TILEGX_OPC_LD4S, CHILD(1065),
+  BITFIELD(33, 2) /* index 1065 */,
+  TILEGX_OPC_LD4S, TILEGX_OPC_LD4S, TILEGX_OPC_LD4S, CHILD(1070),
+  BITFIELD(35, 2) /* index 1070 */,
+  TILEGX_OPC_LD4S, TILEGX_OPC_LD4S, TILEGX_OPC_LD4S,
+  TILEGX_OPC_PREFETCH_L3_FAULT,
+  BITFIELD(31, 2) /* index 1075 */,
+  TILEGX_OPC_LD4U, TILEGX_OPC_LD4U, TILEGX_OPC_LD4U, CHILD(1080),
+  BITFIELD(33, 2) /* index 1080 */,
+  TILEGX_OPC_LD4U, TILEGX_OPC_LD4U, TILEGX_OPC_LD4U, CHILD(1085),
+  BITFIELD(35, 2) /* index 1085 */,
+  TILEGX_OPC_LD4U, TILEGX_OPC_LD4U, TILEGX_OPC_LD4U, TILEGX_OPC_PREFETCH_L3,
+  BITFIELD(43, 3) /* index 1090 */,
+  TILEGX_OPC_LDNT2S, TILEGX_OPC_LDNT2U, TILEGX_OPC_LDNT4S, TILEGX_OPC_LDNT4U,
+  TILEGX_OPC_LDNT, TILEGX_OPC_LD, TILEGX_OPC_LNK, TILEGX_OPC_MF,
+  BITFIELD(43, 3) /* index 1099 */,
+  TILEGX_OPC_NAP, TILEGX_OPC_NOP, TILEGX_OPC_SWINT0, TILEGX_OPC_SWINT1,
+  TILEGX_OPC_SWINT2, TILEGX_OPC_SWINT3, TILEGX_OPC_WH64, TILEGX_OPC_NONE,
+  BITFIELD(49, 4) /* index 1108 */,
+  TILEGX_OPC_V1MAXU, TILEGX_OPC_V1MINU, TILEGX_OPC_V1MNZ, TILEGX_OPC_V1MZ,
+  TILEGX_OPC_V1SHL, TILEGX_OPC_V1SHRS, TILEGX_OPC_V1SHRU, TILEGX_OPC_V1SUBUC,
+  TILEGX_OPC_V1SUB, TILEGX_OPC_V2ADDSC, TILEGX_OPC_V2ADD, TILEGX_OPC_V2CMPEQ,
+  TILEGX_OPC_V2CMPLES, TILEGX_OPC_V2CMPLEU, TILEGX_OPC_V2CMPLTS,
+  TILEGX_OPC_V2CMPLTU,
+  BITFIELD(49, 4) /* index 1125 */,
+  TILEGX_OPC_V2CMPNE, TILEGX_OPC_V2INT_H, TILEGX_OPC_V2INT_L,
+  TILEGX_OPC_V2MAXS, TILEGX_OPC_V2MINS, TILEGX_OPC_V2MNZ, TILEGX_OPC_V2MZ,
+  TILEGX_OPC_V2PACKH, TILEGX_OPC_V2PACKL, TILEGX_OPC_V2PACKUC,
+  TILEGX_OPC_V2SHLSC, TILEGX_OPC_V2SHL, TILEGX_OPC_V2SHRS, TILEGX_OPC_V2SHRU,
+  TILEGX_OPC_V2SUBSC, TILEGX_OPC_V2SUB,
+  BITFIELD(49, 4) /* index 1142 */,
+  TILEGX_OPC_V4ADDSC, TILEGX_OPC_V4ADD, TILEGX_OPC_V4INT_H,
+  TILEGX_OPC_V4INT_L, TILEGX_OPC_V4PACKSC, TILEGX_OPC_V4SHLSC,
+  TILEGX_OPC_V4SHL, TILEGX_OPC_V4SHRS, TILEGX_OPC_V4SHRU, TILEGX_OPC_V4SUBSC,
+  TILEGX_OPC_V4SUB, TILEGX_OPC_XOR, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+  TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+  BITFIELD(49, 4) /* index 1159 */,
+  TILEGX_OPC_NONE, TILEGX_OPC_ROTLI, TILEGX_OPC_SHLI, TILEGX_OPC_SHLXI,
+  TILEGX_OPC_SHRSI, TILEGX_OPC_SHRUI, TILEGX_OPC_SHRUXI, TILEGX_OPC_V1SHLI,
+  TILEGX_OPC_V1SHRSI, TILEGX_OPC_V1SHRUI, TILEGX_OPC_V2SHLI,
+  TILEGX_OPC_V2SHRSI, TILEGX_OPC_V2SHRUI, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+  TILEGX_OPC_NONE,
+  BITFIELD(31, 2) /* index 1176 */,
+  TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI,
+  CHILD(1181),
+  BITFIELD(33, 2) /* index 1181 */,
+  TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI,
+  CHILD(1186),
+  BITFIELD(35, 2) /* index 1186 */,
+  TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI,
+  CHILD(1191),
+  BITFIELD(37, 2) /* index 1191 */,
+  TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI,
+  CHILD(1196),
+  BITFIELD(39, 2) /* index 1196 */,
+  TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI,
+  CHILD(1201),
+  BITFIELD(41, 2) /* index 1201 */,
+  TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI, TILEGX_OPC_SHL16INSLI,
+  TILEGX_OPC_INFOL,
+};
+
+static const unsigned short decode_Y0_fsm[178] =
+{
+  BITFIELD(27, 4) /* index 0 */,
+  CHILD(17), TILEGX_OPC_ADDXI, CHILD(32), TILEGX_OPC_CMPEQI,
+  TILEGX_OPC_CMPLTSI, CHILD(62), CHILD(67), CHILD(118), CHILD(123),
+  CHILD(128), CHILD(133), CHILD(153), CHILD(158), CHILD(163), CHILD(168),
+  CHILD(173),
+  BITFIELD(6, 2) /* index 17 */,
+  TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, CHILD(22),
+  BITFIELD(8, 2) /* index 22 */,
+  TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, CHILD(27),
+  BITFIELD(10, 2) /* index 27 */,
+  TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, TILEGX_OPC_MOVEI,
+  BITFIELD(0, 2) /* index 32 */,
+  TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, CHILD(37),
+  BITFIELD(2, 2) /* index 37 */,
+  TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, CHILD(42),
+  BITFIELD(4, 2) /* index 42 */,
+  TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, CHILD(47),
+  BITFIELD(6, 2) /* index 47 */,
+  TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, CHILD(52),
+  BITFIELD(8, 2) /* index 52 */,
+  TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, CHILD(57),
+  BITFIELD(10, 2) /* index 57 */,
+  TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_INFO,
+  BITFIELD(18, 2) /* index 62 */,
+  TILEGX_OPC_ADDX, TILEGX_OPC_ADD, TILEGX_OPC_SUBX, TILEGX_OPC_SUB,
+  BITFIELD(15, 5) /* index 67 */,
+  TILEGX_OPC_SHL1ADD, TILEGX_OPC_SHL1ADD, TILEGX_OPC_SHL1ADD,
+  TILEGX_OPC_SHL1ADD, TILEGX_OPC_SHL1ADD, TILEGX_OPC_SHL1ADD,
+  TILEGX_OPC_SHL1ADD, TILEGX_OPC_SHL1ADD, TILEGX_OPC_SHL2ADD,
+  TILEGX_OPC_SHL2ADD, TILEGX_OPC_SHL2ADD, TILEGX_OPC_SHL2ADD,
+  TILEGX_OPC_SHL2ADD, TILEGX_OPC_SHL2ADD, TILEGX_OPC_SHL2ADD,
+  TILEGX_OPC_SHL2ADD, TILEGX_OPC_SHL3ADD, TILEGX_OPC_SHL3ADD,
+  TILEGX_OPC_SHL3ADD, TILEGX_OPC_SHL3ADD, TILEGX_OPC_SHL3ADD,
+  TILEGX_OPC_SHL3ADD, TILEGX_OPC_SHL3ADD, TILEGX_OPC_SHL3ADD, CHILD(100),
+  CHILD(109), TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+  BITFIELD(12, 3) /* index 100 */,
+  TILEGX_OPC_NONE, TILEGX_OPC_CLZ, TILEGX_OPC_CTZ, TILEGX_OPC_FNOP,
+  TILEGX_OPC_FSINGLE_PACK1, TILEGX_OPC_NOP, TILEGX_OPC_PCNT,
+  TILEGX_OPC_REVBITS,
+  BITFIELD(12, 3) /* index 109 */,
+  TILEGX_OPC_REVBYTES, TILEGX_OPC_TBLIDXB0, TILEGX_OPC_TBLIDXB1,
+  TILEGX_OPC_TBLIDXB2, TILEGX_OPC_TBLIDXB3, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+  TILEGX_OPC_NONE,
+  BITFIELD(18, 2) /* index 118 */,
+  TILEGX_OPC_CMPLES, TILEGX_OPC_CMPLEU, TILEGX_OPC_CMPLTS, TILEGX_OPC_CMPLTU,
+  BITFIELD(18, 2) /* index 123 */,
+  TILEGX_OPC_CMPEQ, TILEGX_OPC_CMPNE, TILEGX_OPC_MULAX, TILEGX_OPC_MULX,
+  BITFIELD(18, 2) /* index 128 */,
+  TILEGX_OPC_CMOVEQZ, TILEGX_OPC_CMOVNEZ, TILEGX_OPC_MNZ, TILEGX_OPC_MZ,
+  BITFIELD(18, 2) /* index 133 */,
+  TILEGX_OPC_AND, TILEGX_OPC_NOR, CHILD(138), TILEGX_OPC_XOR,
+  BITFIELD(12, 2) /* index 138 */,
+  TILEGX_OPC_OR, TILEGX_OPC_OR, TILEGX_OPC_OR, CHILD(143),
+  BITFIELD(14, 2) /* index 143 */,
+  TILEGX_OPC_OR, TILEGX_OPC_OR, TILEGX_OPC_OR, CHILD(148),
+  BITFIELD(16, 2) /* index 148 */,
+  TILEGX_OPC_OR, TILEGX_OPC_OR, TILEGX_OPC_OR, TILEGX_OPC_MOVE,
+  BITFIELD(18, 2) /* index 153 */,
+  TILEGX_OPC_ROTL, TILEGX_OPC_SHL, TILEGX_OPC_SHRS, TILEGX_OPC_SHRU,
+  BITFIELD(18, 2) /* index 158 */,
+  TILEGX_OPC_NONE, TILEGX_OPC_SHL1ADDX, TILEGX_OPC_SHL2ADDX,
+  TILEGX_OPC_SHL3ADDX,
+  BITFIELD(18, 2) /* index 163 */,
+  TILEGX_OPC_MUL_HS_HS, TILEGX_OPC_MUL_HU_HU, TILEGX_OPC_MUL_LS_LS,
+  TILEGX_OPC_MUL_LU_LU,
+  BITFIELD(18, 2) /* index 168 */,
+  TILEGX_OPC_MULA_HS_HS, TILEGX_OPC_MULA_HU_HU, TILEGX_OPC_MULA_LS_LS,
+  TILEGX_OPC_MULA_LU_LU,
+  BITFIELD(18, 2) /* index 173 */,
+  TILEGX_OPC_ROTLI, TILEGX_OPC_SHLI, TILEGX_OPC_SHRSI, TILEGX_OPC_SHRUI,
+};
+
+static const unsigned short decode_Y1_fsm[167] =
+{
+  BITFIELD(58, 4) /* index 0 */,
+  TILEGX_OPC_NONE, CHILD(17), TILEGX_OPC_ADDXI, CHILD(32), TILEGX_OPC_CMPEQI,
+  TILEGX_OPC_CMPLTSI, CHILD(62), CHILD(67), CHILD(117), CHILD(122),
+  CHILD(127), CHILD(132), CHILD(152), CHILD(157), CHILD(162), TILEGX_OPC_NONE,
+  BITFIELD(37, 2) /* index 17 */,
+  TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, CHILD(22),
+  BITFIELD(39, 2) /* index 22 */,
+  TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, CHILD(27),
+  BITFIELD(41, 2) /* index 27 */,
+  TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, TILEGX_OPC_ADDI, TILEGX_OPC_MOVEI,
+  BITFIELD(31, 2) /* index 32 */,
+  TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, CHILD(37),
+  BITFIELD(33, 2) /* index 37 */,
+  TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, CHILD(42),
+  BITFIELD(35, 2) /* index 42 */,
+  TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, CHILD(47),
+  BITFIELD(37, 2) /* index 47 */,
+  TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, CHILD(52),
+  BITFIELD(39, 2) /* index 52 */,
+  TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, CHILD(57),
+  BITFIELD(41, 2) /* index 57 */,
+  TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_ANDI, TILEGX_OPC_INFO,
+  BITFIELD(49, 2) /* index 62 */,
+  TILEGX_OPC_ADDX, TILEGX_OPC_ADD, TILEGX_OPC_SUBX, TILEGX_OPC_SUB,
+  BITFIELD(47, 4) /* index 67 */,
+  TILEGX_OPC_SHL1ADD, TILEGX_OPC_SHL1ADD, TILEGX_OPC_SHL1ADD,
+  TILEGX_OPC_SHL1ADD, TILEGX_OPC_SHL2ADD, TILEGX_OPC_SHL2ADD,
+  TILEGX_OPC_SHL2ADD, TILEGX_OPC_SHL2ADD, TILEGX_OPC_SHL3ADD,
+  TILEGX_OPC_SHL3ADD, TILEGX_OPC_SHL3ADD, TILEGX_OPC_SHL3ADD, CHILD(84),
+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_NONE,
+  BITFIELD(43, 3) /* index 84 */,
+  CHILD(93), CHILD(96), CHILD(99), CHILD(102), CHILD(105), CHILD(108),
+  CHILD(111), CHILD(114),
+  BITFIELD(46, 1) /* index 93 */,
+  TILEGX_OPC_NONE, TILEGX_OPC_FNOP,
+  BITFIELD(46, 1) /* index 96 */,
+  TILEGX_OPC_NONE, TILEGX_OPC_ILL,
+  BITFIELD(46, 1) /* index 99 */,
+  TILEGX_OPC_NONE, TILEGX_OPC_JALRP,
+  BITFIELD(46, 1) /* index 102 */,
+  TILEGX_OPC_NONE, TILEGX_OPC_JALR,
+  BITFIELD(46, 1) /* index 105 */,
+  TILEGX_OPC_NONE, TILEGX_OPC_JRP,
+  BITFIELD(46, 1) /* index 108 */,
+  TILEGX_OPC_NONE, TILEGX_OPC_JR,
+  BITFIELD(46, 1) /* index 111 */,
+  TILEGX_OPC_NONE, TILEGX_OPC_LNK,
+  BITFIELD(46, 1) /* index 114 */,
+  TILEGX_OPC_NONE, TILEGX_OPC_NOP,
+  BITFIELD(49, 2) /* index 117 */,
+  TILEGX_OPC_CMPLES, TILEGX_OPC_CMPLEU, TILEGX_OPC_CMPLTS, TILEGX_OPC_CMPLTU,
+  BITFIELD(49, 2) /* index 122 */,
+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_CMPEQ, TILEGX_OPC_CMPNE,
+  BITFIELD(49, 2) /* index 127 */,
+  TILEGX_OPC_NONE, TILEGX_OPC_NONE, TILEGX_OPC_MNZ, TILEGX_OPC_MZ,
+  BITFIELD(49, 2) /* index 132 */,
+  TILEGX_OPC_AND, TILEGX_OPC_NOR, CHILD(137), TILEGX_OPC_XOR,
+  BITFIELD(43, 2) /* index 137 */,
+  TILEGX_OPC_OR, TILEGX_OPC_OR, TILEGX_OPC_OR, CHILD(142),
+  BITFIELD(45, 2) /* index 142 */,
+  TILEGX_OPC_OR, TILEGX_OPC_OR, TILEGX_OPC_OR, CHILD(147),
+  BITFIELD(47, 2) /* index 147 */,
+  TILEGX_OPC_OR, TILEGX_OPC_OR, TILEGX_OPC_OR, TILEGX_OPC_MOVE,
+  BITFIELD(49, 2) /* index 152 */,
+  TILEGX_OPC_ROTL, TILEGX_OPC_SHL, TILEGX_OPC_SHRS, TILEGX_OPC_SHRU,
+  BITFIELD(49, 2) /* index 157 */,
+  TILEGX_OPC_NONE, TILEGX_OPC_SHL1ADDX, TILEGX_OPC_SHL2ADDX,
+  TILEGX_OPC_SHL3ADDX,
+  BITFIELD(49, 2) /* index 162 */,
+  TILEGX_OPC_ROTLI, TILEGX_OPC_SHLI, TILEGX_OPC_SHRSI, TILEGX_OPC_SHRUI,
+};
+
+static const unsigned short decode_Y2_fsm[118] =
+{
+  BITFIELD(62, 2) /* index 0 */,
+  TILEGX_OPC_NONE, CHILD(5), CHILD(66), CHILD(109),
+  BITFIELD(55, 3) /* index 5 */,
+  CHILD(14), CHILD(14), CHILD(14), CHILD(17), CHILD(40), CHILD(40), CHILD(40),
+  CHILD(43),
+  BITFIELD(26, 1) /* index 14 */,
+  TILEGX_OPC_LD1S, TILEGX_OPC_LD1U,
+  BITFIELD(26, 1) /* index 17 */,
+  CHILD(20), CHILD(30),
+  BITFIELD(51, 2) /* index 20 */,
+  TILEGX_OPC_LD1S, TILEGX_OPC_LD1S, TILEGX_OPC_LD1S, CHILD(25),
+  BITFIELD(53, 2) /* index 25 */,
+  TILEGX_OPC_LD1S, TILEGX_OPC_LD1S, TILEGX_OPC_LD1S,
+  TILEGX_OPC_PREFETCH_L1_FAULT,
+  BITFIELD(51, 2) /* index 30 */,
+  TILEGX_OPC_LD1U, TILEGX_OPC_LD1U, TILEGX_OPC_LD1U, CHILD(35),
+  BITFIELD(53, 2) /* index 35 */,
+  TILEGX_OPC_LD1U, TILEGX_OPC_LD1U, TILEGX_OPC_LD1U, TILEGX_OPC_PREFETCH,
+  BITFIELD(26, 1) /* index 40 */,
+  TILEGX_OPC_LD2S, TILEGX_OPC_LD2U,
+  BITFIELD(26, 1) /* index 43 */,
+  CHILD(46), CHILD(56),
+  BITFIELD(51, 2) /* index 46 */,
+  TILEGX_OPC_LD2S, TILEGX_OPC_LD2S, TILEGX_OPC_LD2S, CHILD(51),
+  BITFIELD(53, 2) /* index 51 */,
+  TILEGX_OPC_LD2S, TILEGX_OPC_LD2S, TILEGX_OPC_LD2S,
+  TILEGX_OPC_PREFETCH_L2_FAULT,
+  BITFIELD(51, 2) /* index 56 */,
+  TILEGX_OPC_LD2U, TILEGX_OPC_LD2U, TILEGX_OPC_LD2U, CHILD(61),
+  BITFIELD(53, 2) /* index 61 */,
+  TILEGX_OPC_LD2U, TILEGX_OPC_LD2U, TILEGX_OPC_LD2U, TILEGX_OPC_PREFETCH_L2,
+  BITFIELD(56, 2) /* index 66 */,
+  CHILD(71), CHILD(74), CHILD(90), CHILD(93),
+  BITFIELD(26, 1) /* index 71 */,
+  TILEGX_OPC_NONE, TILEGX_OPC_LD4S,
+  BITFIELD(26, 1) /* index 74 */,
+  TILEGX_OPC_NONE, CHILD(77),
+  BITFIELD(51, 2) /* index 77 */,
+  TILEGX_OPC_LD4S, TILEGX_OPC_LD4S, TILEGX_OPC_LD4S, CHILD(82),
+  BITFIELD(53, 2) /* index 82 */,
+  TILEGX_OPC_LD4S, TILEGX_OPC_LD4S, TILEGX_OPC_LD4S, CHILD(87),
+  BITFIELD(55, 1) /* index 87 */,
+  TILEGX_OPC_LD4S, TILEGX_OPC_PREFETCH_L3_FAULT,
+  BITFIELD(26, 1) /* index 90 */,
+  TILEGX_OPC_LD4U, TILEGX_OPC_LD,
+  BITFIELD(26, 1) /* index 93 */,
+  CHILD(96), TILEGX_OPC_LD,
+  BITFIELD(51, 2) /* index 96 */,
+  TILEGX_OPC_LD4U, TILEGX_OPC_LD4U, TILEGX_OPC_LD4U, CHILD(101),
+  BITFIELD(53, 2) /* index 101 */,
+  TILEGX_OPC_LD4U, TILEGX_OPC_LD4U, TILEGX_OPC_LD4U, CHILD(106),
+  BITFIELD(55, 1) /* index 106 */,
+  TILEGX_OPC_LD4U, TILEGX_OPC_PREFETCH_L3,
+  BITFIELD(26, 1) /* index 109 */,
+  CHILD(112), CHILD(115),
+  BITFIELD(57, 1) /* index 112 */,
+  TILEGX_OPC_ST1, TILEGX_OPC_ST4,
+  BITFIELD(57, 1) /* index 115 */,
+  TILEGX_OPC_ST2, TILEGX_OPC_ST,
+};
+
+#undef BITFIELD
+#undef CHILD
+const unsigned short * const
+tilegx_bundle_decoder_fsms[TILEGX_NUM_PIPELINE_ENCODINGS] =
+{
+  decode_X0_fsm,
+  decode_X1_fsm,
+  decode_Y0_fsm,
+  decode_Y1_fsm,
+  decode_Y2_fsm
+};
+const struct tilegx_operand tilegx_operands[35] =
+{
+  {
+    TILEGX_OP_TYPE_IMMEDIATE, BFD_RELOC(TILEGX_IMM8_X0),
+    8, 1, 0, 0, 0, 0,
+    create_Imm8_X0, get_Imm8_X0
+  },
+  {
+    TILEGX_OP_TYPE_IMMEDIATE, BFD_RELOC(TILEGX_IMM8_X1),
+    8, 1, 0, 0, 0, 0,
+    create_Imm8_X1, get_Imm8_X1
+  },
+  {
+    TILEGX_OP_TYPE_IMMEDIATE, BFD_RELOC(TILEGX_IMM8_Y0),
+    8, 1, 0, 0, 0, 0,
+    create_Imm8_Y0, get_Imm8_Y0
+  },
+  {
+    TILEGX_OP_TYPE_IMMEDIATE, BFD_RELOC(TILEGX_IMM8_Y1),
+    8, 1, 0, 0, 0, 0,
+    create_Imm8_Y1, get_Imm8_Y1
+  },
+  {
+    TILEGX_OP_TYPE_IMMEDIATE, BFD_RELOC(TILEGX_IMM16_X0_HW0_LAST),
+    16, 1, 0, 0, 0, 0,
+    create_Imm16_X0, get_Imm16_X0
+  },
+  {
+    TILEGX_OP_TYPE_IMMEDIATE, BFD_RELOC(TILEGX_IMM16_X1_HW0_LAST),
+    16, 1, 0, 0, 0, 0,
+    create_Imm16_X1, get_Imm16_X1
+  },
+  {
+    TILEGX_OP_TYPE_REGISTER, BFD_RELOC(NONE),
+    6, 0, 0, 1, 0, 0,
+    create_Dest_X0, get_Dest_X0
+  },
+  {
+    TILEGX_OP_TYPE_REGISTER, BFD_RELOC(NONE),
+    6, 0, 1, 0, 0, 0,
+    create_SrcA_X0, get_SrcA_X0
+  },
+  {
+    TILEGX_OP_TYPE_REGISTER, BFD_RELOC(NONE),
+    6, 0, 0, 1, 0, 0,
+    create_Dest_X1, get_Dest_X1
+  },
+  {
+    TILEGX_OP_TYPE_REGISTER, BFD_RELOC(NONE),
+    6, 0, 1, 0, 0, 0,
+    create_SrcA_X1, get_SrcA_X1
+  },
+  {
+    TILEGX_OP_TYPE_REGISTER, BFD_RELOC(NONE),
+    6, 0, 0, 1, 0, 0,
+    create_Dest_Y0, get_Dest_Y0
+  },
+  {
+    TILEGX_OP_TYPE_REGISTER, BFD_RELOC(NONE),
+    6, 0, 1, 0, 0, 0,
+    create_SrcA_Y0, get_SrcA_Y0
+  },
+  {
+    TILEGX_OP_TYPE_REGISTER, BFD_RELOC(NONE),
+    6, 0, 0, 1, 0, 0,
+    create_Dest_Y1, get_Dest_Y1
+  },
+  {
+    TILEGX_OP_TYPE_REGISTER, BFD_RELOC(NONE),
+    6, 0, 1, 0, 0, 0,
+    create_SrcA_Y1, get_SrcA_Y1
+  },
+  {
+    TILEGX_OP_TYPE_REGISTER, BFD_RELOC(NONE),
+    6, 0, 1, 0, 0, 0,
+    create_SrcA_Y2, get_SrcA_Y2
+  },
+  {
+    TILEGX_OP_TYPE_REGISTER, BFD_RELOC(NONE),
+    6, 0, 1, 1, 0, 0,
+    create_SrcA_X1, get_SrcA_X1
+  },
+  {
+    TILEGX_OP_TYPE_REGISTER, BFD_RELOC(NONE),
+    6, 0, 1, 0, 0, 0,
+    create_SrcB_X0, get_SrcB_X0
+  },
+  {
+    TILEGX_OP_TYPE_REGISTER, BFD_RELOC(NONE),
+    6, 0, 1, 0, 0, 0,
+    create_SrcB_X1, get_SrcB_X1
+  },
+  {
+    TILEGX_OP_TYPE_REGISTER, BFD_RELOC(NONE),
+    6, 0, 1, 0, 0, 0,
+    create_SrcB_Y0, get_SrcB_Y0
+  },
+  {
+    TILEGX_OP_TYPE_REGISTER, BFD_RELOC(NONE),
+    6, 0, 1, 0, 0, 0,
+    create_SrcB_Y1, get_SrcB_Y1
+  },
+  {
+    TILEGX_OP_TYPE_ADDRESS, BFD_RELOC(TILEGX_BROFF_X1),
+    17, 1, 0, 0, 1, TILEGX_LOG2_BUNDLE_ALIGNMENT_IN_BYTES,
+    create_BrOff_X1, get_BrOff_X1
+  },
+  {
+    TILEGX_OP_TYPE_IMMEDIATE, BFD_RELOC(NONE),
+    6, 0, 0, 0, 0, 0,
+    create_BFStart_X0, get_BFStart_X0
+  },
+  {
+    TILEGX_OP_TYPE_IMMEDIATE, BFD_RELOC(NONE),
+    6, 0, 0, 0, 0, 0,
+    create_BFEnd_X0, get_BFEnd_X0
+  },
+  {
+    TILEGX_OP_TYPE_REGISTER, BFD_RELOC(NONE),
+    6, 0, 1, 1, 0, 0,
+    create_Dest_X0, get_Dest_X0
+  },
+  {
+    TILEGX_OP_TYPE_REGISTER, BFD_RELOC(NONE),
+    6, 0, 1, 1, 0, 0,
+    create_Dest_Y0, get_Dest_Y0
+  },
+  {
+    TILEGX_OP_TYPE_ADDRESS, BFD_RELOC(TILEGX_JUMPOFF_X1),
+    27, 1, 0, 0, 1, TILEGX_LOG2_BUNDLE_ALIGNMENT_IN_BYTES,
+    create_JumpOff_X1, get_JumpOff_X1
+  },
+  {
+    TILEGX_OP_TYPE_REGISTER, BFD_RELOC(NONE),
+    6, 0, 0, 1, 0, 0,
+    create_SrcBDest_Y2, get_SrcBDest_Y2
+  },
+  {
+    TILEGX_OP_TYPE_SPR, BFD_RELOC(TILEGX_MF_IMM14_X1),
+    14, 0, 0, 0, 0, 0,
+    create_MF_Imm14_X1, get_MF_Imm14_X1
+  },
+  {
+    TILEGX_OP_TYPE_SPR, BFD_RELOC(TILEGX_MT_IMM14_X1),
+    14, 0, 0, 0, 0, 0,
+    create_MT_Imm14_X1, get_MT_Imm14_X1
+  },
+  {
+    TILEGX_OP_TYPE_IMMEDIATE, BFD_RELOC(TILEGX_SHAMT_X0),
+    6, 0, 0, 0, 0, 0,
+    create_ShAmt_X0, get_ShAmt_X0
+  },
+  {
+    TILEGX_OP_TYPE_IMMEDIATE, BFD_RELOC(TILEGX_SHAMT_X1),
+    6, 0, 0, 0, 0, 0,
+    create_ShAmt_X1, get_ShAmt_X1
+  },
+  {
+    TILEGX_OP_TYPE_IMMEDIATE, BFD_RELOC(TILEGX_SHAMT_Y0),
+    6, 0, 0, 0, 0, 0,
+    create_ShAmt_Y0, get_ShAmt_Y0
+  },
+  {
+    TILEGX_OP_TYPE_IMMEDIATE, BFD_RELOC(TILEGX_SHAMT_Y1),
+    6, 0, 0, 0, 0, 0,
+    create_ShAmt_Y1, get_ShAmt_Y1
+  },
+  {
+    TILEGX_OP_TYPE_REGISTER, BFD_RELOC(NONE),
+    6, 0, 1, 0, 0, 0,
+    create_SrcBDest_Y2, get_SrcBDest_Y2
+  },
+  {
+    TILEGX_OP_TYPE_IMMEDIATE, BFD_RELOC(TILEGX_DEST_IMM8_X1),
+    8, 1, 0, 0, 0, 0,
+    create_Dest_Imm8_X1, get_Dest_Imm8_X1
+  }
+};
+
+
+
+
+/* Given a set of bundle bits and the lookup FSM for a specific pipe,
+ * returns which instruction the bundle contains in that pipe.
+ */
+static const struct tilegx_opcode *
+find_opcode(tilegx_bundle_bits bits, const unsigned short *table)
+{
+  int index = 0;
+
+  while (1)
+  {
+    unsigned short bitspec = table[index];
+    unsigned int bitfield =
+      ((unsigned int)(bits >> (bitspec & 63))) & (bitspec >> 6);
+
+    unsigned short next = table[index + 1 + bitfield];
+    if (next <= TILEGX_OPC_NONE)
+      return &tilegx_opcodes[next];
+
+    index = next - TILEGX_OPC_NONE;
+  }
+}
+
+
+int
+parse_insn_tilegx(tilegx_bundle_bits bits,
+                  unsigned long long pc,
+                  struct tilegx_decoded_instruction
+                  decoded[TILEGX_MAX_INSTRUCTIONS_PER_BUNDLE])
+{
+  int num_instructions = 0;
+  int pipe;
+
+  int min_pipe, max_pipe;
+  if ((bits & TILEGX_BUNDLE_MODE_MASK) == 0)
+  {
+    min_pipe = TILEGX_PIPELINE_X0;
+    max_pipe = TILEGX_PIPELINE_X1;
+  }
+  else
+  {
+    min_pipe = TILEGX_PIPELINE_Y0;
+    max_pipe = TILEGX_PIPELINE_Y2;
+  }
+
+  /* For each pipe, find an instruction that fits. */
+  for (pipe = min_pipe; pipe <= max_pipe; pipe++)
+  {
+    const struct tilegx_opcode *opc;
+    struct tilegx_decoded_instruction *d;
+    int i;
+
+    d = &decoded[num_instructions++];
+    opc = find_opcode (bits, tilegx_bundle_decoder_fsms[pipe]);
+    d->opcode = opc;
+
+    /* Decode each operand, sign extending, etc. as appropriate. */
+    for (i = 0; i < opc->num_operands; i++)
+    {
+      const struct tilegx_operand *op =
+        &tilegx_operands[opc->operands[pipe][i]];
+      int raw_opval = op->extract (bits);
+      long long opval;
+
+      if (op->is_signed)
+      {
+        /* Sign-extend the operand. */
+        int shift = (int)((sizeof(int) * 8) - op->num_bits);
+        raw_opval = (raw_opval << shift) >> shift;
+      }
+
+      /* Adjust PC-relative scaled branch offsets. */
+      if (op->type == TILEGX_OP_TYPE_ADDRESS)
+        opval = (raw_opval * TILEGX_BUNDLE_SIZE_IN_BYTES) + pc;
+      else
+        opval = raw_opval;
+
+      /* Record the final value. */
+      d->operands[i] = op;
+      d->operand_values[i] = opval;
+    }
+  }
+
+  return num_instructions;
+}
diff -druN linux-2.6.39-libre/arch/tile/kernel/time.c linux-3.0-rc7-libre/arch/tile/kernel/time.c
--- linux-2.6.39-libre/arch/tile/kernel/time.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/tile/kernel/time.c	2011-07-11 19:51:52.000000000 -0400
@@ -22,6 +22,7 @@
 #include <linux/sched.h>
 #include <linux/smp.h>
 #include <linux/delay.h>
+#include <linux/module.h>
 #include <asm/irq_regs.h>
 #include <asm/traps.h>
 #include <hv/hypervisor.h>
@@ -56,6 +57,7 @@
 
 	return (((cycles_t)high) << 32) | low;
 }
+EXPORT_SYMBOL(get_cycles);
 #endif
 
 /*
diff -druN linux-2.6.39-libre/arch/tile/kernel/tlb.c linux-3.0-rc7-libre/arch/tile/kernel/tlb.c
--- linux-2.6.39-libre/arch/tile/kernel/tlb.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/tile/kernel/tlb.c	2011-07-11 19:51:52.000000000 -0400
@@ -34,13 +34,13 @@
 {
 	HV_Remote_ASID asids[NR_CPUS];
 	int i = 0, cpu;
-	for_each_cpu(cpu, &mm->cpu_vm_mask) {
+	for_each_cpu(cpu, mm_cpumask(mm)) {
 		HV_Remote_ASID *asid = &asids[i++];
 		asid->y = cpu / smp_topology.width;
 		asid->x = cpu % smp_topology.width;
 		asid->asid = per_cpu(current_asid, cpu);
 	}
-	flush_remote(0, HV_FLUSH_EVICT_L1I, &mm->cpu_vm_mask,
+	flush_remote(0, HV_FLUSH_EVICT_L1I, mm_cpumask(mm),
 		     0, 0, 0, NULL, asids, i);
 }
 
@@ -54,8 +54,8 @@
 {
 	unsigned long size = hv_page_size(vma);
 	int cache = (vma->vm_flags & VM_EXEC) ? HV_FLUSH_EVICT_L1I : 0;
-	flush_remote(0, cache, &mm->cpu_vm_mask,
-		     va, size, size, &mm->cpu_vm_mask, NULL, 0);
+	flush_remote(0, cache, mm_cpumask(mm),
+		     va, size, size, mm_cpumask(mm), NULL, 0);
 }
 
 void flush_tlb_page(const struct vm_area_struct *vma, unsigned long va)
@@ -70,8 +70,8 @@
 	unsigned long size = hv_page_size(vma);
 	struct mm_struct *mm = vma->vm_mm;
 	int cache = (vma->vm_flags & VM_EXEC) ? HV_FLUSH_EVICT_L1I : 0;
-	flush_remote(0, cache, &mm->cpu_vm_mask, start, end - start, size,
-		     &mm->cpu_vm_mask, NULL, 0);
+	flush_remote(0, cache, mm_cpumask(mm), start, end - start, size,
+		     mm_cpumask(mm), NULL, 0);
 }
 
 void flush_tlb_all(void)
diff -druN linux-2.6.39-libre/arch/tile/kernel/traps.c linux-3.0-rc7-libre/arch/tile/kernel/traps.c
--- linux-2.6.39-libre/arch/tile/kernel/traps.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/tile/kernel/traps.c	2011-07-11 19:51:52.000000000 -0400
@@ -308,6 +308,7 @@
 	info.si_addr = (void __user *)address;
 	if (signo == SIGILL)
 		info.si_trapno = fault_num;
+	trace_unhandled_signal("trap", regs, address, signo);
 	force_sig_info(signo, &info, current);
 }
 
diff -druN linux-2.6.39-libre/arch/tile/kernel/vmlinux.lds.S linux-3.0-rc7-libre/arch/tile/kernel/vmlinux.lds.S
--- linux-2.6.39-libre/arch/tile/kernel/vmlinux.lds.S	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/tile/kernel/vmlinux.lds.S	2011-07-11 19:51:52.000000000 -0400
@@ -60,7 +60,7 @@
   . = ALIGN(PAGE_SIZE);
   VMLINUX_SYMBOL(_sinitdata) = .;
   INIT_DATA_SECTION(16) :data =0
-  PERCPU(L2_CACHE_BYTES, PAGE_SIZE)
+  PERCPU_SECTION(L2_CACHE_BYTES)
   . = ALIGN(PAGE_SIZE);
   VMLINUX_SYMBOL(_einitdata) = .;
 
diff -druN linux-2.6.39-libre/arch/tile/lib/atomic_asm_32.S linux-3.0-rc7-libre/arch/tile/lib/atomic_asm_32.S
--- linux-2.6.39-libre/arch/tile/lib/atomic_asm_32.S	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/tile/lib/atomic_asm_32.S	2011-07-11 19:51:52.000000000 -0400
@@ -59,7 +59,7 @@
  * bad kernel addresses).
  *
  * Note that if the value we would store is the same as what we
- * loaded, we bypass the load.  Other platforms with true atomics can
+ * loaded, we bypass the store.  Other platforms with true atomics can
  * make the guarantee that a non-atomic __clear_bit(), for example,
  * can safely race with an atomic test_and_set_bit(); this example is
  * from bit_spinlock.h in slub_lock() / slub_unlock().  We can't do
diff -druN linux-2.6.39-libre/arch/tile/lib/cacheflush.c linux-3.0-rc7-libre/arch/tile/lib/cacheflush.c
--- linux-2.6.39-libre/arch/tile/lib/cacheflush.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/tile/lib/cacheflush.c	2011-07-11 19:51:52.000000000 -0400
@@ -15,6 +15,7 @@
 #include <asm/page.h>
 #include <asm/cacheflush.h>
 #include <arch/icache.h>
+#include <arch/spr_def.h>
 
 
 void __flush_icache_range(unsigned long start, unsigned long end)
@@ -39,6 +40,18 @@
 	char *p, *base;
 	size_t step_size, load_count;
 	const unsigned long STRIPE_WIDTH = 8192;
+#ifdef __tilegx__
+	/*
+	 * On TILE-Gx, we must disable the dstream prefetcher before doing
+	 * a cache flush; otherwise, we could end up with data in the cache
+	 * that we don't want there.  Note that normally we'd do an mf
+	 * after the SPR write to disabling the prefetcher, but we do one
+	 * below, before any further loads, so there's no need to do it
+	 * here.
+	 */
+	uint_reg_t old_dstream_pf = __insn_mfspr(SPR_DSTREAM_PF);
+	__insn_mtspr(SPR_DSTREAM_PF, 0);
+#endif
 
 	/*
 	 * Flush and invalidate the buffer out of the local L1/L2
@@ -122,4 +135,9 @@
 
 	/* Wait for the load+inv's (and thus finvs) to have completed. */
 	__insn_mf();
+
+#ifdef __tilegx__
+	/* Reenable the prefetcher. */
+	__insn_mtspr(SPR_DSTREAM_PF, old_dstream_pf);
+#endif
 }
diff -druN linux-2.6.39-libre/arch/tile/lib/memchr_64.c linux-3.0-rc7-libre/arch/tile/lib/memchr_64.c
--- linux-2.6.39-libre/arch/tile/lib/memchr_64.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/tile/lib/memchr_64.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,71 @@
+/*
+ * Copyright 2011 Tilera 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, version 2.
+ *
+ *   This program is distributed in the hope that it will be useful, but
+ *   WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
+ *   NON INFRINGEMENT.  See the GNU General Public License for
+ *   more details.
+ */
+
+#include <linux/types.h>
+#include <linux/string.h>
+#include <linux/module.h>
+
+void *memchr(const void *s, int c, size_t n)
+{
+	const uint64_t *last_word_ptr;
+	const uint64_t *p;
+	const char *last_byte_ptr;
+	uintptr_t s_int;
+	uint64_t goal, before_mask, v, bits;
+	char *ret;
+
+	if (__builtin_expect(n == 0, 0)) {
+		/* Don't dereference any memory if the array is empty. */
+		return NULL;
+	}
+
+	/* Get an aligned pointer. */
+	s_int = (uintptr_t) s;
+	p = (const uint64_t *)(s_int & -8);
+
+	/* Create eight copies of the byte for which we are looking. */
+	goal = 0x0101010101010101ULL * (uint8_t) c;
+
+	/* Read the first word, but munge it so that bytes before the array
+	 * will not match goal.
+	 *
+	 * Note that this shift count expression works because we know
+	 * shift counts are taken mod 64.
+	 */
+	before_mask = (1ULL << (s_int << 3)) - 1;
+	v = (*p | before_mask) ^ (goal & before_mask);
+
+	/* Compute the address of the last byte. */
+	last_byte_ptr = (const char *)s + n - 1;
+
+	/* Compute the address of the word containing the last byte. */
+	last_word_ptr = (const uint64_t *)((uintptr_t) last_byte_ptr & -8);
+
+	while ((bits = __insn_v1cmpeq(v, goal)) == 0) {
+		if (__builtin_expect(p == last_word_ptr, 0)) {
+			/* We already read the last word in the array,
+			 * so give up.
+			 */
+			return NULL;
+		}
+		v = *++p;
+	}
+
+	/* We found a match, but it might be in a byte past the end
+	 * of the array.
+	 */
+	ret = ((char *)p) + (__insn_ctz(bits) >> 3);
+	return (ret <= last_byte_ptr) ? ret : NULL;
+}
+EXPORT_SYMBOL(memchr);
diff -druN linux-2.6.39-libre/arch/tile/lib/memcpy_64.c linux-3.0-rc7-libre/arch/tile/lib/memcpy_64.c
--- linux-2.6.39-libre/arch/tile/lib/memcpy_64.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/tile/lib/memcpy_64.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,220 @@
+/*
+ * Copyright 2011 Tilera 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, version 2.
+ *
+ *   This program is distributed in the hope that it will be useful, but
+ *   WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
+ *   NON INFRINGEMENT.  See the GNU General Public License for
+ *   more details.
+ */
+
+#include <linux/types.h>
+#include <linux/string.h>
+#include <linux/module.h>
+#define __memcpy memcpy
+/* EXPORT_SYMBOL() is in arch/tile/lib/exports.c since this should be asm. */
+
+/* Must be 8 bytes in size. */
+#define word_t uint64_t
+
+#if CHIP_L2_LINE_SIZE() != 64 && CHIP_L2_LINE_SIZE() != 128
+#error "Assumes 64 or 128 byte line size"
+#endif
+
+/* How many cache lines ahead should we prefetch? */
+#define PREFETCH_LINES_AHEAD 3
+
+/*
+ * Provide "base versions" of load and store for the normal code path.
+ * The kernel provides other versions for userspace copies.
+ */
+#define ST(p, v) (*(p) = (v))
+#define LD(p) (*(p))
+
+#ifndef USERCOPY_FUNC
+#define ST1 ST
+#define ST2 ST
+#define ST4 ST
+#define ST8 ST
+#define LD1 LD
+#define LD2 LD
+#define LD4 LD
+#define LD8 LD
+#define RETVAL dstv
+void *memcpy(void *__restrict dstv, const void *__restrict srcv, size_t n)
+#else
+/*
+ * Special kernel version will provide implementation of the LDn/STn
+ * macros to return a count of uncopied bytes due to mm fault.
+ */
+#define RETVAL 0
+int USERCOPY_FUNC(void *__restrict dstv, const void *__restrict srcv, size_t n)
+#endif
+{
+	char *__restrict dst1 = (char *)dstv;
+	const char *__restrict src1 = (const char *)srcv;
+	const char *__restrict src1_end;
+	const char *__restrict prefetch;
+	word_t *__restrict dst8;    /* 8-byte pointer to destination memory. */
+	word_t final; /* Final bytes to write to trailing word, if any */
+	long i;
+
+	if (n < 16) {
+		for (; n; n--)
+			ST1(dst1++, LD1(src1++));
+		return RETVAL;
+	}
+
+	/*
+	 * Locate the end of source memory we will copy.  Don't
+	 * prefetch past this.
+	 */
+	src1_end = src1 + n - 1;
+
+	/* Prefetch ahead a few cache lines, but not past the end. */
+	prefetch = src1;
+	for (i = 0; i < PREFETCH_LINES_AHEAD; i++) {
+		__insn_prefetch(prefetch);
+		prefetch += CHIP_L2_LINE_SIZE();
+		prefetch = (prefetch > src1_end) ? prefetch : src1;
+	}
+
+	/* Copy bytes until dst is word-aligned. */
+	for (; (uintptr_t)dst1 & (sizeof(word_t) - 1); n--)
+		ST1(dst1++, LD1(src1++));
+
+	/* 8-byte pointer to destination memory. */
+	dst8 = (word_t *)dst1;
+
+	if (__builtin_expect((uintptr_t)src1 & (sizeof(word_t) - 1), 0)) {
+		/*
+		 * Misaligned copy.  Copy 8 bytes at a time, but don't
+		 * bother with other fanciness.
+		 *
+		 * TODO: Consider prefetching and using wh64 as well.
+		 */
+
+		/* Create an aligned src8. */
+		const word_t *__restrict src8 =
+			(const word_t *)((uintptr_t)src1 & -sizeof(word_t));
+		word_t b;
+
+		word_t a = LD8(src8++);
+		for (; n >= sizeof(word_t); n -= sizeof(word_t)) {
+			b = LD8(src8++);
+			a = __insn_dblalign(a, b, src1);
+			ST8(dst8++, a);
+			a = b;
+		}
+
+		if (n == 0)
+			return RETVAL;
+
+		b = ((const char *)src8 <= src1_end) ? *src8 : 0;
+
+		/*
+		 * Final source bytes to write to trailing partial
+		 * word, if any.
+		 */
+		final = __insn_dblalign(a, b, src1);
+	} else {
+		/* Aligned copy. */
+
+		const word_t* __restrict src8 = (const word_t *)src1;
+
+		/* src8 and dst8 are both word-aligned. */
+		if (n >= CHIP_L2_LINE_SIZE()) {
+			/* Copy until 'dst' is cache-line-aligned. */
+			for (; (uintptr_t)dst8 & (CHIP_L2_LINE_SIZE() - 1);
+			     n -= sizeof(word_t))
+				ST8(dst8++, LD8(src8++));
+
+			for (; n >= CHIP_L2_LINE_SIZE(); ) {
+				__insn_wh64(dst8);
+
+				/*
+				 * Prefetch and advance to next line
+				 * to prefetch, but don't go past the end
+				 */
+				__insn_prefetch(prefetch);
+				prefetch += CHIP_L2_LINE_SIZE();
+				prefetch = (prefetch > src1_end) ? prefetch :
+					(const char *)src8;
+
+				/*
+				 * Copy an entire cache line.  Manually
+				 * unrolled to avoid idiosyncracies of
+				 * compiler unrolling.
+				 */
+#define COPY_WORD(offset) ({ ST8(dst8+offset, LD8(src8+offset)); n -= 8; })
+				COPY_WORD(0);
+				COPY_WORD(1);
+				COPY_WORD(2);
+				COPY_WORD(3);
+				COPY_WORD(4);
+				COPY_WORD(5);
+				COPY_WORD(6);
+				COPY_WORD(7);
+#if CHIP_L2_LINE_SIZE() == 128
+				COPY_WORD(8);
+				COPY_WORD(9);
+				COPY_WORD(10);
+				COPY_WORD(11);
+				COPY_WORD(12);
+				COPY_WORD(13);
+				COPY_WORD(14);
+				COPY_WORD(15);
+#elif CHIP_L2_LINE_SIZE() != 64
+# error Fix code that assumes particular L2 cache line sizes
+#endif
+
+				dst8 += CHIP_L2_LINE_SIZE() / sizeof(word_t);
+				src8 += CHIP_L2_LINE_SIZE() / sizeof(word_t);
+			}
+		}
+
+		for (; n >= sizeof(word_t); n -= sizeof(word_t))
+			ST8(dst8++, LD8(src8++));
+
+		if (__builtin_expect(n == 0, 1))
+			return RETVAL;
+
+		final = LD8(src8);
+	}
+
+	/* n != 0 if we get here.  Write out any trailing bytes. */
+	dst1 = (char *)dst8;
+	if (n & 4) {
+		ST4((uint32_t *)dst1, final);
+		dst1 += 4;
+		final >>= 32;
+		n &= 3;
+	}
+	if (n & 2) {
+		ST2((uint16_t *)dst1, final);
+		dst1 += 2;
+		final >>= 16;
+		n &= 1;
+	}
+	if (n)
+		ST1((uint8_t *)dst1, final);
+
+	return RETVAL;
+}
+
+
+#ifdef USERCOPY_FUNC
+#undef ST1
+#undef ST2
+#undef ST4
+#undef ST8
+#undef LD1
+#undef LD2
+#undef LD4
+#undef LD8
+#undef USERCOPY_FUNC
+#endif
diff -druN linux-2.6.39-libre/arch/tile/lib/memcpy_user_64.c linux-3.0-rc7-libre/arch/tile/lib/memcpy_user_64.c
--- linux-2.6.39-libre/arch/tile/lib/memcpy_user_64.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/tile/lib/memcpy_user_64.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,86 @@
+/*
+ * Copyright 2011 Tilera 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, version 2.
+ *
+ *   This program is distributed in the hope that it will be useful, but
+ *   WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
+ *   NON INFRINGEMENT.  See the GNU General Public License for
+ *   more details.
+ *
+ * Do memcpy(), but trap and return "n" when a load or store faults.
+ *
+ * Note: this idiom only works when memcpy() compiles to a leaf function.
+ * If "sp" is updated during memcpy, the "jrp lr" will be incorrect.
+ *
+ * Also note that we are capturing "n" from the containing scope here.
+ */
+
+#define _ST(p, inst, v)						\
+	({							\
+		asm("1: " #inst " %0, %1;"			\
+		    ".pushsection .coldtext.memcpy,\"ax\";"	\
+		    "2: { move r0, %2; jrp lr };"		\
+		    ".section __ex_table,\"a\";"		\
+		    ".quad 1b, 2b;"				\
+		    ".popsection"				\
+		    : "=m" (*(p)) : "r" (v), "r" (n));		\
+	})
+
+#define _LD(p, inst)						\
+	({							\
+		unsigned long __v;				\
+		asm("1: " #inst " %0, %1;"			\
+		    ".pushsection .coldtext.memcpy,\"ax\";"	\
+		    "2: { move r0, %2; jrp lr };"		\
+		    ".section __ex_table,\"a\";"		\
+		    ".quad 1b, 2b;"				\
+		    ".popsection"				\
+		    : "=r" (__v) : "m" (*(p)), "r" (n));	\
+		__v;						\
+	})
+
+#define USERCOPY_FUNC __copy_to_user_inatomic
+#define ST1(p, v) _ST((p), st1, (v))
+#define ST2(p, v) _ST((p), st2, (v))
+#define ST4(p, v) _ST((p), st4, (v))
+#define ST8(p, v) _ST((p), st, (v))
+#define LD1 LD
+#define LD2 LD
+#define LD4 LD
+#define LD8 LD
+#include "memcpy_64.c"
+
+#define USERCOPY_FUNC __copy_from_user_inatomic
+#define ST1 ST
+#define ST2 ST
+#define ST4 ST
+#define ST8 ST
+#define LD1(p) _LD((p), ld1u)
+#define LD2(p) _LD((p), ld2u)
+#define LD4(p) _LD((p), ld4u)
+#define LD8(p) _LD((p), ld)
+#include "memcpy_64.c"
+
+#define USERCOPY_FUNC __copy_in_user_inatomic
+#define ST1(p, v) _ST((p), st1, (v))
+#define ST2(p, v) _ST((p), st2, (v))
+#define ST4(p, v) _ST((p), st4, (v))
+#define ST8(p, v) _ST((p), st, (v))
+#define LD1(p) _LD((p), ld1u)
+#define LD2(p) _LD((p), ld2u)
+#define LD4(p) _LD((p), ld4u)
+#define LD8(p) _LD((p), ld)
+#include "memcpy_64.c"
+
+unsigned long __copy_from_user_zeroing(void *to, const void __user *from,
+				       unsigned long n)
+{
+	unsigned long rc = __copy_from_user_inatomic(to, from, n);
+	if (unlikely(rc))
+		memset(to + n - rc, 0, rc);
+	return rc;
+}
diff -druN linux-2.6.39-libre/arch/tile/lib/memset_64.c linux-3.0-rc7-libre/arch/tile/lib/memset_64.c
--- linux-2.6.39-libre/arch/tile/lib/memset_64.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/tile/lib/memset_64.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,145 @@
+/*
+ * Copyright 2011 Tilera 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, version 2.
+ *
+ *   This program is distributed in the hope that it will be useful, but
+ *   WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
+ *   NON INFRINGEMENT.  See the GNU General Public License for
+ *   more details.
+ */
+
+#include <arch/chip.h>
+
+#include <linux/types.h>
+#include <linux/string.h>
+#include <linux/module.h>
+
+#undef memset
+
+void *memset(void *s, int c, size_t n)
+{
+	uint64_t *out64;
+	int n64, to_align64;
+	uint64_t v64;
+	uint8_t *out8 = s;
+
+	/* Experimentation shows that a trivial tight loop is a win up until
+	 * around a size of 20, where writing a word at a time starts to win.
+	 */
+#define BYTE_CUTOFF 20
+
+#if BYTE_CUTOFF < 7
+	/* This must be at least at least this big, or some code later
+	 * on doesn't work.
+	 */
+#error "BYTE_CUTOFF is too small"
+#endif
+
+	if (n < BYTE_CUTOFF) {
+		/* Strangely, this turns out to be the tightest way to
+		 * write this loop.
+		 */
+		if (n != 0) {
+			do {
+				/* Strangely, combining these into one line
+				 * performs worse.
+				 */
+				*out8 = c;
+				out8++;
+			} while (--n != 0);
+		}
+
+		return s;
+	}
+
+	/* Align 'out8'. We know n >= 7 so this won't write past the end. */
+	while (((uintptr_t) out8 & 7) != 0) {
+		*out8++ = c;
+		--n;
+	}
+
+	/* Align 'n'. */
+	while (n & 7)
+		out8[--n] = c;
+
+	out64 = (uint64_t *) out8;
+	n64 = n >> 3;
+
+	/* Tile input byte out to 64 bits. */
+	/* KLUDGE */
+	v64 = 0x0101010101010101ULL * (uint8_t)c;
+
+	/* This must be at least 8 or the following loop doesn't work. */
+#define CACHE_LINE_SIZE_IN_DOUBLEWORDS (CHIP_L2_LINE_SIZE() / 8)
+
+	/* Determine how many words we need to emit before the 'out32'
+	 * pointer becomes aligned modulo the cache line size.
+	 */
+	to_align64 = (-((uintptr_t)out64 >> 3)) &
+		(CACHE_LINE_SIZE_IN_DOUBLEWORDS - 1);
+
+	/* Only bother aligning and using wh64 if there is at least
+	 * one full cache line to process.  This check also prevents
+	 * overrunning the end of the buffer with alignment words.
+	 */
+	if (to_align64 <= n64 - CACHE_LINE_SIZE_IN_DOUBLEWORDS) {
+		int lines_left;
+
+		/* Align out64 mod the cache line size so we can use wh64. */
+		n64 -= to_align64;
+		for (; to_align64 != 0; to_align64--) {
+			*out64 = v64;
+			out64++;
+		}
+
+		/* Use unsigned divide to turn this into a right shift. */
+		lines_left = (unsigned)n64 / CACHE_LINE_SIZE_IN_DOUBLEWORDS;
+
+		do {
+			/* Only wh64 a few lines at a time, so we don't
+			 * exceed the maximum number of victim lines.
+			 */
+			int x = ((lines_left < CHIP_MAX_OUTSTANDING_VICTIMS())
+				  ? lines_left
+				  : CHIP_MAX_OUTSTANDING_VICTIMS());
+			uint64_t *wh = out64;
+			int i = x;
+			int j;
+
+			lines_left -= x;
+
+			do {
+				__insn_wh64(wh);
+				wh += CACHE_LINE_SIZE_IN_DOUBLEWORDS;
+			} while (--i);
+
+			for (j = x * (CACHE_LINE_SIZE_IN_DOUBLEWORDS / 4);
+			     j != 0; j--) {
+				*out64++ = v64;
+				*out64++ = v64;
+				*out64++ = v64;
+				*out64++ = v64;
+			}
+		} while (lines_left != 0);
+
+		/* We processed all full lines above, so only this many
+		 * words remain to be processed.
+		 */
+		n64 &= CACHE_LINE_SIZE_IN_DOUBLEWORDS - 1;
+	}
+
+	/* Now handle any leftover values. */
+	if (n64 != 0) {
+		do {
+			*out64 = v64;
+			out64++;
+		} while (--n64 != 0);
+	}
+
+	return s;
+}
+EXPORT_SYMBOL(memset);
diff -druN linux-2.6.39-libre/arch/tile/lib/spinlock_64.c linux-3.0-rc7-libre/arch/tile/lib/spinlock_64.c
--- linux-2.6.39-libre/arch/tile/lib/spinlock_64.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/tile/lib/spinlock_64.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,104 @@
+/*
+ * Copyright 2011 Tilera 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, version 2.
+ *
+ *   This program is distributed in the hope that it will be useful, but
+ *   WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
+ *   NON INFRINGEMENT.  See the GNU General Public License for
+ *   more details.
+ */
+
+#include <linux/spinlock.h>
+#include <linux/module.h>
+#include <asm/processor.h>
+
+#include "spinlock_common.h"
+
+/*
+ * Read the spinlock value without allocating in our cache and without
+ * causing an invalidation to another cpu with a copy of the cacheline.
+ * This is important when we are spinning waiting for the lock.
+ */
+static inline u32 arch_spin_read_noalloc(void *lock)
+{
+	return atomic_cmpxchg((atomic_t *)lock, -1, -1);
+}
+
+/*
+ * Wait until the high bits (current) match my ticket.
+ * If we notice the overflow bit set on entry, we clear it.
+ */
+void arch_spin_lock_slow(arch_spinlock_t *lock, u32 my_ticket)
+{
+	if (unlikely(my_ticket & __ARCH_SPIN_NEXT_OVERFLOW)) {
+		__insn_fetchand4(&lock->lock, ~__ARCH_SPIN_NEXT_OVERFLOW);
+		my_ticket &= ~__ARCH_SPIN_NEXT_OVERFLOW;
+	}
+
+	for (;;) {
+		u32 val = arch_spin_read_noalloc(lock);
+		u32 delta = my_ticket - arch_spin_current(val);
+		if (delta == 0)
+			return;
+		relax((128 / CYCLES_PER_RELAX_LOOP) * delta);
+	}
+}
+EXPORT_SYMBOL(arch_spin_lock_slow);
+
+/*
+ * Check the lock to see if it is plausible, and try to get it with cmpxchg().
+ */
+int arch_spin_trylock(arch_spinlock_t *lock)
+{
+	u32 val = arch_spin_read_noalloc(lock);
+	if (unlikely(arch_spin_current(val) != arch_spin_next(val)))
+		return 0;
+	return cmpxchg(&lock->lock, val, (val + 1) & ~__ARCH_SPIN_NEXT_OVERFLOW)
+		== val;
+}
+EXPORT_SYMBOL(arch_spin_trylock);
+
+void arch_spin_unlock_wait(arch_spinlock_t *lock)
+{
+	u32 iterations = 0;
+	while (arch_spin_is_locked(lock))
+		delay_backoff(iterations++);
+}
+EXPORT_SYMBOL(arch_spin_unlock_wait);
+
+/*
+ * If the read lock fails due to a writer, we retry periodically
+ * until the value is positive and we write our incremented reader count.
+ */
+void __read_lock_failed(arch_rwlock_t *rw)
+{
+	u32 val;
+	int iterations = 0;
+	do {
+		delay_backoff(iterations++);
+		val = __insn_fetchaddgez4(&rw->lock, 1);
+	} while (unlikely(arch_write_val_locked(val)));
+}
+EXPORT_SYMBOL(__read_lock_failed);
+
+/*
+ * If we failed because there were readers, clear the "writer" bit
+ * so we don't block additional readers.  Otherwise, there was another
+ * writer anyway, so our "fetchor" made no difference.  Then wait,
+ * issuing periodic fetchor instructions, till we get the lock.
+ */
+void __write_lock_failed(arch_rwlock_t *rw, u32 val)
+{
+	int iterations = 0;
+	do {
+		if (!arch_write_val_locked(val))
+			val = __insn_fetchand4(&rw->lock, ~__WRITE_LOCK_BIT);
+		delay_backoff(iterations++);
+		val = __insn_fetchor4(&rw->lock, __WRITE_LOCK_BIT);
+	} while (val != 0);
+}
+EXPORT_SYMBOL(__write_lock_failed);
diff -druN linux-2.6.39-libre/arch/tile/lib/strchr_64.c linux-3.0-rc7-libre/arch/tile/lib/strchr_64.c
--- linux-2.6.39-libre/arch/tile/lib/strchr_64.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/tile/lib/strchr_64.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,67 @@
+/*
+ * Copyright 2011 Tilera 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, version 2.
+ *
+ *   This program is distributed in the hope that it will be useful, but
+ *   WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
+ *   NON INFRINGEMENT.  See the GNU General Public License for
+ *   more details.
+ */
+
+#include <linux/types.h>
+#include <linux/string.h>
+#include <linux/module.h>
+
+#undef strchr
+
+char *strchr(const char *s, int c)
+{
+	int z, g;
+
+	/* Get an aligned pointer. */
+	const uintptr_t s_int = (uintptr_t) s;
+	const uint64_t *p = (const uint64_t *)(s_int & -8);
+
+	/* Create eight copies of the byte for which we are looking. */
+	const uint64_t goal = 0x0101010101010101ULL * (uint8_t) c;
+
+	/* Read the first aligned word, but force bytes before the string to
+	 * match neither zero nor goal (we make sure the high bit of each
+	 * byte is 1, and the low 7 bits are all the opposite of the goal
+	 * byte).
+	 *
+	 * Note that this shift count expression works because we know shift
+	 * counts are taken mod 64.
+	 */
+	const uint64_t before_mask = (1ULL << (s_int << 3)) - 1;
+	uint64_t v = (*p | before_mask) ^
+		(goal & __insn_v1shrsi(before_mask, 1));
+
+	uint64_t zero_matches, goal_matches;
+	while (1) {
+		/* Look for a terminating '\0'. */
+		zero_matches = __insn_v1cmpeqi(v, 0);
+
+		/* Look for the goal byte. */
+		goal_matches = __insn_v1cmpeq(v, goal);
+
+		if (__builtin_expect((zero_matches | goal_matches) != 0, 0))
+			break;
+
+		v = *++p;
+	}
+
+	z = __insn_ctz(zero_matches);
+	g = __insn_ctz(goal_matches);
+
+	/* If we found c before '\0' we got a match. Note that if c == '\0'
+	 * then g == z, and we correctly return the address of the '\0'
+	 * rather than NULL.
+	 */
+	return (g <= z) ? ((char *)p) + (g >> 3) : NULL;
+}
+EXPORT_SYMBOL(strchr);
diff -druN linux-2.6.39-libre/arch/tile/lib/strlen_64.c linux-3.0-rc7-libre/arch/tile/lib/strlen_64.c
--- linux-2.6.39-libre/arch/tile/lib/strlen_64.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/tile/lib/strlen_64.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2011 Tilera 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, version 2.
+ *
+ *   This program is distributed in the hope that it will be useful, but
+ *   WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
+ *   NON INFRINGEMENT.  See the GNU General Public License for
+ *   more details.
+ */
+
+#include <linux/types.h>
+#include <linux/string.h>
+#include <linux/module.h>
+
+#undef strlen
+
+size_t strlen(const char *s)
+{
+	/* Get an aligned pointer. */
+	const uintptr_t s_int = (uintptr_t) s;
+	const uint64_t *p = (const uint64_t *)(s_int & -8);
+
+	/* Read the first word, but force bytes before the string to be nonzero.
+	 * This expression works because we know shift counts are taken mod 64.
+	 */
+	uint64_t v = *p | ((1ULL << (s_int << 3)) - 1);
+
+	uint64_t bits;
+	while ((bits = __insn_v1cmpeqi(v, 0)) == 0)
+		v = *++p;
+
+	return ((const char *)p) + (__insn_ctz(bits) >> 3) - s;
+}
+EXPORT_SYMBOL(strlen);
diff -druN linux-2.6.39-libre/arch/tile/lib/usercopy_64.S linux-3.0-rc7-libre/arch/tile/lib/usercopy_64.S
--- linux-2.6.39-libre/arch/tile/lib/usercopy_64.S	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/tile/lib/usercopy_64.S	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,196 @@
+/*
+ * Copyright 2011 Tilera 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, version 2.
+ *
+ *   This program is distributed in the hope that it will be useful, but
+ *   WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
+ *   NON INFRINGEMENT.  See the GNU General Public License for
+ *   more details.
+ */
+
+#include <linux/linkage.h>
+#include <asm/errno.h>
+#include <asm/cache.h>
+#include <arch/chip.h>
+
+/* Access user memory, but use MMU to avoid propagating kernel exceptions. */
+
+	.pushsection .fixup,"ax"
+
+get_user_fault:
+	{ movei r1, -EFAULT; move r0, zero }
+	jrp lr
+	ENDPROC(get_user_fault)
+
+put_user_fault:
+	{ movei r0, -EFAULT; jrp lr }
+	ENDPROC(put_user_fault)
+
+	.popsection
+
+/*
+ * __get_user_N functions take a pointer in r0, and return 0 in r1
+ * on success, with the value in r0; or else -EFAULT in r1.
+ */
+#define __get_user_N(bytes, LOAD) \
+	STD_ENTRY(__get_user_##bytes); \
+1:	{ LOAD r0, r0; move r1, zero }; \
+	jrp lr; \
+	STD_ENDPROC(__get_user_##bytes); \
+	.pushsection __ex_table,"a"; \
+	.quad 1b, get_user_fault; \
+	.popsection
+
+__get_user_N(1, ld1u)
+__get_user_N(2, ld2u)
+__get_user_N(4, ld4u)
+__get_user_N(8, ld)
+
+/*
+ * __put_user_N functions take a value in r0 and a pointer in r1,
+ * and return 0 in r0 on success or -EFAULT on failure.
+ */
+#define __put_user_N(bytes, STORE) \
+	STD_ENTRY(__put_user_##bytes); \
+1:	{ STORE r1, r0; move r0, zero }; \
+	jrp lr; \
+	STD_ENDPROC(__put_user_##bytes); \
+	.pushsection __ex_table,"a"; \
+	.quad 1b, put_user_fault; \
+	.popsection
+
+__put_user_N(1, st1)
+__put_user_N(2, st2)
+__put_user_N(4, st4)
+__put_user_N(8, st)
+
+/*
+ * strnlen_user_asm takes the pointer in r0, and the length bound in r1.
+ * It returns the length, including the terminating NUL, or zero on exception.
+ * If length is greater than the bound, returns one plus the bound.
+ */
+STD_ENTRY(strnlen_user_asm)
+	{ beqz r1, 2f; addi r3, r0, -1 }  /* bias down to include NUL */
+1:      { ld1u r4, r0; addi r1, r1, -1 }
+	beqz r4, 2f
+	{ bnezt r1, 1b; addi r0, r0, 1 }
+2:      { sub r0, r0, r3; jrp lr }
+	STD_ENDPROC(strnlen_user_asm)
+	.pushsection .fixup,"ax"
+strnlen_user_fault:
+	{ move r0, zero; jrp lr }
+	ENDPROC(strnlen_user_fault)
+	.section __ex_table,"a"
+	.quad 1b, strnlen_user_fault
+	.popsection
+
+/*
+ * strncpy_from_user_asm takes the kernel target pointer in r0,
+ * the userspace source pointer in r1, and the length bound (including
+ * the trailing NUL) in r2.  On success, it returns the string length
+ * (not including the trailing NUL), or -EFAULT on failure.
+ */
+STD_ENTRY(strncpy_from_user_asm)
+	{ beqz r2, 2f; move r3, r0 }
+1:      { ld1u r4, r1; addi r1, r1, 1; addi r2, r2, -1 }
+	{ st1 r0, r4; addi r0, r0, 1 }
+	beqz r2, 2f
+	bnezt r4, 1b
+	addi r0, r0, -1   /* don't count the trailing NUL */
+2:      { sub r0, r0, r3; jrp lr }
+	STD_ENDPROC(strncpy_from_user_asm)
+	.pushsection .fixup,"ax"
+strncpy_from_user_fault:
+	{ movei r0, -EFAULT; jrp lr }
+	ENDPROC(strncpy_from_user_fault)
+	.section __ex_table,"a"
+	.quad 1b, strncpy_from_user_fault
+	.popsection
+
+/*
+ * clear_user_asm takes the user target address in r0 and the
+ * number of bytes to zero in r1.
+ * It returns the number of uncopiable bytes (hopefully zero) in r0.
+ * Note that we don't use a separate .fixup section here since we fall
+ * through into the "fixup" code as the last straight-line bundle anyway.
+ */
+STD_ENTRY(clear_user_asm)
+	{ beqz r1, 2f; or r2, r0, r1 }
+	andi r2, r2, 7
+	beqzt r2, .Lclear_aligned_user_asm
+1:      { st1 r0, zero; addi r0, r0, 1; addi r1, r1, -1 }
+	bnezt r1, 1b
+2:      { move r0, r1; jrp lr }
+	.pushsection __ex_table,"a"
+	.quad 1b, 2b
+	.popsection
+
+.Lclear_aligned_user_asm:
+1:      { st r0, zero; addi r0, r0, 8; addi r1, r1, -8 }
+	bnezt r1, 1b
+2:      { move r0, r1; jrp lr }
+	STD_ENDPROC(clear_user_asm)
+	.pushsection __ex_table,"a"
+	.quad 1b, 2b
+	.popsection
+
+/*
+ * flush_user_asm takes the user target address in r0 and the
+ * number of bytes to flush in r1.
+ * It returns the number of unflushable bytes (hopefully zero) in r0.
+ */
+STD_ENTRY(flush_user_asm)
+	beqz r1, 2f
+	{ movei r2, L2_CACHE_BYTES; add r1, r0, r1 }
+	{ sub r2, zero, r2; addi r1, r1, L2_CACHE_BYTES-1 }
+	{ and r0, r0, r2; and r1, r1, r2 }
+	{ sub r1, r1, r0 }
+1:      { flush r0; addi r1, r1, -CHIP_FLUSH_STRIDE() }
+	{ addi r0, r0, CHIP_FLUSH_STRIDE(); bnezt r1, 1b }
+2:      { move r0, r1; jrp lr }
+	STD_ENDPROC(flush_user_asm)
+	.pushsection __ex_table,"a"
+	.quad 1b, 2b
+	.popsection
+
+/*
+ * inv_user_asm takes the user target address in r0 and the
+ * number of bytes to invalidate in r1.
+ * It returns the number of not inv'able bytes (hopefully zero) in r0.
+ */
+STD_ENTRY(inv_user_asm)
+	beqz r1, 2f
+	{ movei r2, L2_CACHE_BYTES; add r1, r0, r1 }
+	{ sub r2, zero, r2; addi r1, r1, L2_CACHE_BYTES-1 }
+	{ and r0, r0, r2; and r1, r1, r2 }
+	{ sub r1, r1, r0 }
+1:      { inv r0; addi r1, r1, -CHIP_INV_STRIDE() }
+	{ addi r0, r0, CHIP_INV_STRIDE(); bnezt r1, 1b }
+2:      { move r0, r1; jrp lr }
+	STD_ENDPROC(inv_user_asm)
+	.pushsection __ex_table,"a"
+	.quad 1b, 2b
+	.popsection
+
+/*
+ * finv_user_asm takes the user target address in r0 and the
+ * number of bytes to flush-invalidate in r1.
+ * It returns the number of not finv'able bytes (hopefully zero) in r0.
+ */
+STD_ENTRY(finv_user_asm)
+	beqz r1, 2f
+	{ movei r2, L2_CACHE_BYTES; add r1, r0, r1 }
+	{ sub r2, zero, r2; addi r1, r1, L2_CACHE_BYTES-1 }
+	{ and r0, r0, r2; and r1, r1, r2 }
+	{ sub r1, r1, r0 }
+1:      { finv r0; addi r1, r1, -CHIP_FINV_STRIDE() }
+	{ addi r0, r0, CHIP_FINV_STRIDE(); bnezt r1, 1b }
+2:      { move r0, r1; jrp lr }
+	STD_ENDPROC(finv_user_asm)
+	.pushsection __ex_table,"a"
+	.quad 1b, 2b
+	.popsection
diff -druN linux-2.6.39-libre/arch/tile/mm/fault.c linux-3.0-rc7-libre/arch/tile/mm/fault.c
--- linux-2.6.39-libre/arch/tile/mm/fault.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/tile/mm/fault.c	2011-07-11 19:51:52.000000000 -0400
@@ -43,8 +43,11 @@
 
 #include <arch/interrupts.h>
 
-static noinline void force_sig_info_fault(int si_signo, int si_code,
-	unsigned long address, int fault_num, struct task_struct *tsk)
+static noinline void force_sig_info_fault(const char *type, int si_signo,
+					  int si_code, unsigned long address,
+					  int fault_num,
+					  struct task_struct *tsk,
+					  struct pt_regs *regs)
 {
 	siginfo_t info;
 
@@ -59,6 +62,7 @@
 	info.si_code = si_code;
 	info.si_addr = (void __user *)address;
 	info.si_trapno = fault_num;
+	trace_unhandled_signal(type, regs, address, si_signo);
 	force_sig_info(si_signo, &info, tsk);
 }
 
@@ -71,11 +75,12 @@
 		struct pt_regs *, regs)
 {
 	if (address >= PAGE_OFFSET)
-		force_sig_info_fault(SIGSEGV, SEGV_MAPERR, address,
-				     INT_DTLB_MISS, current);
+		force_sig_info_fault("atomic segfault", SIGSEGV, SEGV_MAPERR,
+				     address, INT_DTLB_MISS, current, regs);
 	else
-		force_sig_info_fault(SIGBUS, BUS_ADRALN, address,
-				     INT_UNALIGN_DATA, current);
+		force_sig_info_fault("atomic alignment fault", SIGBUS,
+				     BUS_ADRALN, address,
+				     INT_UNALIGN_DATA, current, regs);
 
 	/*
 	 * Adjust pc to point at the actual instruction, which is unusual
@@ -471,8 +476,8 @@
 		 */
 		local_irq_enable();
 
-		force_sig_info_fault(SIGSEGV, si_code, address,
-				     fault_num, tsk);
+		force_sig_info_fault("segfault", SIGSEGV, si_code, address,
+				     fault_num, tsk, regs);
 		return 0;
 	}
 
@@ -547,7 +552,8 @@
 	if (is_kernel_mode)
 		goto no_context;
 
-	force_sig_info_fault(SIGBUS, BUS_ADRERR, address, fault_num, tsk);
+	force_sig_info_fault("bus error", SIGBUS, BUS_ADRERR, address,
+			     fault_num, tsk, regs);
 	return 0;
 }
 
@@ -732,6 +738,7 @@
 		panic("Bad fault number %d in do_page_fault", fault_num);
 	}
 
+#if CHIP_HAS_TILE_DMA() || CHIP_HAS_SN_PROC()
 	if (EX1_PL(regs->ex1) != USER_PL) {
 		struct async_tlb *async;
 		switch (fault_num) {
@@ -775,6 +782,7 @@
 			return;
 		}
 	}
+#endif
 
 	handle_page_fault(regs, fault_num, is_page_fault, address, write);
 }
@@ -801,8 +809,6 @@
 				  async->address, async->is_write);
 	}
 }
-#endif /* CHIP_HAS_TILE_DMA() || CHIP_HAS_SN_PROC() */
-
 
 /*
  * This routine effectively re-issues asynchronous page faults
@@ -824,6 +830,8 @@
 	handle_async_page_fault(regs, &current->thread.sn_async_tlb);
 #endif
 }
+#endif /* CHIP_HAS_TILE_DMA() || CHIP_HAS_SN_PROC() */
+
 
 void vmalloc_sync_all(void)
 {
diff -druN linux-2.6.39-libre/arch/tile/mm/init.c linux-3.0-rc7-libre/arch/tile/mm/init.c
--- linux-2.6.39-libre/arch/tile/mm/init.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/tile/mm/init.c	2011-07-11 19:51:52.000000000 -0400
@@ -60,8 +60,6 @@
 EXPORT_SYMBOL(VMALLOC_RESERVE);
 #endif
 
-DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
-
 /* Create an L2 page table */
 static pte_t * __init alloc_pte(void)
 {
diff -druN linux-2.6.39-libre/arch/tile/mm/migrate_64.S linux-3.0-rc7-libre/arch/tile/mm/migrate_64.S
--- linux-2.6.39-libre/arch/tile/mm/migrate_64.S	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/tile/mm/migrate_64.S	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,187 @@
+/*
+ * Copyright 2011 Tilera 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, version 2.
+ *
+ *   This program is distributed in the hope that it will be useful, but
+ *   WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
+ *   NON INFRINGEMENT.  See the GNU General Public License for
+ *   more details.
+ *
+ * This routine is a helper for migrating the home of a set of pages to
+ * a new cpu.  See the documentation in homecache.c for more information.
+ */
+
+#include <linux/linkage.h>
+#include <linux/threads.h>
+#include <asm/page.h>
+#include <asm/thread_info.h>
+#include <asm/types.h>
+#include <asm/asm-offsets.h>
+#include <hv/hypervisor.h>
+
+	.text
+
+/*
+ * First, some definitions that apply to all the code in the file.
+ */
+
+/* Locals (caller-save) */
+#define r_tmp		r10
+#define r_save_sp	r11
+
+/* What we save where in the stack frame; must include all callee-saves. */
+#define FRAME_SP	8
+#define FRAME_R30	16
+#define FRAME_R31	24
+#define FRAME_R32	32
+#define FRAME_R33	40
+#define FRAME_SIZE	48
+
+
+
+
+/*
+ * On entry:
+ *
+ *   r0 the new context PA to install (moved to r_context)
+ *   r1 PTE to use for context access (moved to r_access)
+ *   r2 ASID to use for new context (moved to r_asid)
+ *   r3 pointer to cpumask with just this cpu set in it (r_my_cpumask)
+ */
+
+/* Arguments (caller-save) */
+#define r_context_in	r0
+#define r_access_in	r1
+#define r_asid_in	r2
+#define r_my_cpumask	r3
+
+/* Locals (callee-save); must not be more than FRAME_xxx above. */
+#define r_save_ics	r30
+#define r_context	r31
+#define r_access	r32
+#define r_asid		r33
+
+/*
+ * Caller-save locals and frame constants are the same as
+ * for homecache_migrate_stack_and_flush.
+ */
+
+STD_ENTRY(flush_and_install_context)
+	/*
+	 * Create a stack frame; we can't touch it once we flush the
+	 * cache until we install the new page table and flush the TLB.
+	 */
+	{
+	 move r_save_sp, sp
+	 st sp, lr
+	 addi sp, sp, -FRAME_SIZE
+	}
+	addi r_tmp, sp, FRAME_SP
+	{
+	 st r_tmp, r_save_sp
+	 addi r_tmp, sp, FRAME_R30
+	}
+	{
+	 st r_tmp, r30
+	 addi r_tmp, sp, FRAME_R31
+	}
+	{
+	 st r_tmp, r31
+	 addi r_tmp, sp, FRAME_R32
+	}
+	{
+	 st r_tmp, r32
+	 addi r_tmp, sp, FRAME_R33
+	}
+	st r_tmp, r33
+
+	/* Move some arguments to callee-save registers. */
+	{
+	 move r_context, r_context_in
+	 move r_access, r_access_in
+	}
+	move r_asid, r_asid_in
+
+	/* Disable interrupts, since we can't use our stack. */
+	{
+	 mfspr r_save_ics, INTERRUPT_CRITICAL_SECTION
+	 movei r_tmp, 1
+	}
+	mtspr INTERRUPT_CRITICAL_SECTION, r_tmp
+
+	/* First, flush our L2 cache. */
+	{
+	 move r0, zero  /* cache_pa */
+	 moveli r1, hw2_last(HV_FLUSH_EVICT_L2)  /* cache_control */
+	}
+	{
+	 shl16insli r1, r1, hw1(HV_FLUSH_EVICT_L2)
+	 move r2, r_my_cpumask  /* cache_cpumask */
+	}
+	{
+	 shl16insli r1, r1, hw0(HV_FLUSH_EVICT_L2)
+	 move r3, zero  /* tlb_va */
+	}
+	{
+	 move r4, zero  /* tlb_length */
+	 move r5, zero  /* tlb_pgsize */
+	}
+	{
+	 move r6, zero  /* tlb_cpumask */
+	 move r7, zero  /* asids */
+	}
+	{
+	 move r8, zero  /* asidcount */
+	 jal hv_flush_remote
+	}
+	bnez r0, 1f
+
+	/* Now install the new page table. */
+	{
+	 move r0, r_context
+	 move r1, r_access
+	}
+	{
+	 move r2, r_asid
+	 movei r3, HV_CTX_DIRECTIO
+	}
+	jal hv_install_context
+	bnez r0, 1f
+
+	/* Finally, flush the TLB. */
+	{
+	 movei r0, 0   /* preserve_global */
+	 jal hv_flush_all
+	}
+
+1:      /* Reset interrupts back how they were before. */
+	mtspr INTERRUPT_CRITICAL_SECTION, r_save_ics
+
+	/* Restore the callee-saved registers and return. */
+	addli lr, sp, FRAME_SIZE
+	{
+	 ld lr, lr
+	 addli r_tmp, sp, FRAME_R30
+	}
+	{
+	 ld r30, r_tmp
+	 addli r_tmp, sp, FRAME_R31
+	}
+	{
+	 ld r31, r_tmp
+	 addli r_tmp, sp, FRAME_R32
+	}
+	{
+	 ld r32, r_tmp
+	 addli r_tmp, sp, FRAME_R33
+	}
+	{
+	 ld r33, r_tmp
+	 addi sp, sp, FRAME_SIZE
+	}
+	jrp lr
+	STD_ENDPROC(flush_and_install_context)
diff -druN linux-2.6.39-libre/arch/um/drivers/Makefile linux-3.0-rc7-libre/arch/um/drivers/Makefile
--- linux-2.6.39-libre/arch/um/drivers/Makefile	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/um/drivers/Makefile	2011-07-11 19:51:52.000000000 -0400
@@ -9,7 +9,7 @@
 slip-objs := slip_kern.o slip_user.o
 slirp-objs := slirp_kern.o slirp_user.o
 daemon-objs := daemon_kern.o daemon_user.o
-mcast-objs := mcast_kern.o mcast_user.o
+umcast-objs := umcast_kern.o umcast_user.o
 net-objs := net_kern.o net_user.o
 mconsole-objs := mconsole_kern.o mconsole_user.o
 hostaudio-objs := hostaudio_kern.o
@@ -44,7 +44,7 @@
 obj-$(CONFIG_UML_NET_SLIRP) += slirp.o slip_common.o
 obj-$(CONFIG_UML_NET_DAEMON) += daemon.o 
 obj-$(CONFIG_UML_NET_VDE) += vde.o
-obj-$(CONFIG_UML_NET_MCAST) += mcast.o 
+obj-$(CONFIG_UML_NET_MCAST) += umcast.o
 obj-$(CONFIG_UML_NET_PCAP) += pcap.o
 obj-$(CONFIG_UML_NET) += net.o 
 obj-$(CONFIG_MCONSOLE) += mconsole.o
diff -druN linux-2.6.39-libre/arch/um/drivers/mcast.h linux-3.0-rc7-libre/arch/um/drivers/mcast.h
--- linux-2.6.39-libre/arch/um/drivers/mcast.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/um/drivers/mcast.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,24 +0,0 @@
-/* 
- * Copyright (C) 2001 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
- * Licensed under the GPL
- */
-
-#ifndef __DRIVERS_MCAST_H
-#define __DRIVERS_MCAST_H
-
-#include "net_user.h"
-
-struct mcast_data {
-	char *addr;
-	unsigned short port;
-	void *mcast_addr;
-	int ttl;
-	void *dev;
-};
-
-extern const struct net_user_info mcast_user_info;
-
-extern int mcast_user_write(int fd, void *buf, int len, 
-			    struct mcast_data *pri);
-
-#endif
diff -druN linux-2.6.39-libre/arch/um/drivers/mcast_kern.c linux-3.0-rc7-libre/arch/um/drivers/mcast_kern.c
--- linux-2.6.39-libre/arch/um/drivers/mcast_kern.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/um/drivers/mcast_kern.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,120 +0,0 @@
-/*
- * user-mode-linux networking multicast transport
- * Copyright (C) 2001 by Harald Welte <laforge@gnumonks.org>
- * Copyright (C) 2001 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
- *
- * based on the existing uml-networking code, which is
- * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org) and
- * James Leu (jleu@mindspring.net).
- * Copyright (C) 2001 by various other people who didn't put their name here.
- *
- * Licensed under the GPL.
- */
-
-#include "linux/init.h"
-#include <linux/netdevice.h>
-#include "mcast.h"
-#include "net_kern.h"
-
-struct mcast_init {
-	char *addr;
-	int port;
-	int ttl;
-};
-
-static void mcast_init(struct net_device *dev, void *data)
-{
-	struct uml_net_private *pri;
-	struct mcast_data *dpri;
-	struct mcast_init *init = data;
-
-	pri = netdev_priv(dev);
-	dpri = (struct mcast_data *) pri->user;
-	dpri->addr = init->addr;
-	dpri->port = init->port;
-	dpri->ttl = init->ttl;
-	dpri->dev = dev;
-
-	printk("mcast backend multicast address: %s:%u, TTL:%u\n",
-	       dpri->addr, dpri->port, dpri->ttl);
-}
-
-static int mcast_read(int fd, struct sk_buff *skb, struct uml_net_private *lp)
-{
-	return net_recvfrom(fd, skb_mac_header(skb),
-			    skb->dev->mtu + ETH_HEADER_OTHER);
-}
-
-static int mcast_write(int fd, struct sk_buff *skb, struct uml_net_private *lp)
-{
-	return mcast_user_write(fd, skb->data, skb->len,
-				(struct mcast_data *) &lp->user);
-}
-
-static const struct net_kern_info mcast_kern_info = {
-	.init			= mcast_init,
-	.protocol		= eth_protocol,
-	.read			= mcast_read,
-	.write			= mcast_write,
-};
-
-static int mcast_setup(char *str, char **mac_out, void *data)
-{
-	struct mcast_init *init = data;
-	char *port_str = NULL, *ttl_str = NULL, *remain;
-	char *last;
-
-	*init = ((struct mcast_init)
-		{ .addr 	= "239.192.168.1",
-		  .port 	= 1102,
-		  .ttl 		= 1 });
-
-	remain = split_if_spec(str, mac_out, &init->addr, &port_str, &ttl_str,
-			       NULL);
-	if (remain != NULL) {
-		printk(KERN_ERR "mcast_setup - Extra garbage on "
-		       "specification : '%s'\n", remain);
-		return 0;
-	}
-
-	if (port_str != NULL) {
-		init->port = simple_strtoul(port_str, &last, 10);
-		if ((*last != '\0') || (last == port_str)) {
-			printk(KERN_ERR "mcast_setup - Bad port : '%s'\n",
-			       port_str);
-			return 0;
-		}
-	}
-
-	if (ttl_str != NULL) {
-		init->ttl = simple_strtoul(ttl_str, &last, 10);
-		if ((*last != '\0') || (last == ttl_str)) {
-			printk(KERN_ERR "mcast_setup - Bad ttl : '%s'\n",
-			       ttl_str);
-			return 0;
-		}
-	}
-
-	printk(KERN_INFO "Configured mcast device: %s:%u-%u\n", init->addr,
-	       init->port, init->ttl);
-
-	return 1;
-}
-
-static struct transport mcast_transport = {
-	.list 		= LIST_HEAD_INIT(mcast_transport.list),
-	.name 		= "mcast",
-	.setup  	= mcast_setup,
-	.user 		= &mcast_user_info,
-	.kern 		= &mcast_kern_info,
-	.private_size 	= sizeof(struct mcast_data),
-	.setup_size 	= sizeof(struct mcast_init),
-};
-
-static int register_mcast(void)
-{
-	register_transport(&mcast_transport);
-	return 0;
-}
-
-late_initcall(register_mcast);
diff -druN linux-2.6.39-libre/arch/um/drivers/mcast_user.c linux-3.0-rc7-libre/arch/um/drivers/mcast_user.c
--- linux-2.6.39-libre/arch/um/drivers/mcast_user.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/um/drivers/mcast_user.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,165 +0,0 @@
-/*
- * user-mode-linux networking multicast transport
- * Copyright (C) 2001 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
- * Copyright (C) 2001 by Harald Welte <laforge@gnumonks.org>
- *
- * based on the existing uml-networking code, which is
- * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org) and
- * James Leu (jleu@mindspring.net).
- * Copyright (C) 2001 by various other people who didn't put their name here.
- *
- * Licensed under the GPL.
- *
- */
-
-#include <unistd.h>
-#include <errno.h>
-#include <netinet/in.h>
-#include "kern_constants.h"
-#include "mcast.h"
-#include "net_user.h"
-#include "um_malloc.h"
-#include "user.h"
-
-static struct sockaddr_in *new_addr(char *addr, unsigned short port)
-{
-	struct sockaddr_in *sin;
-
-	sin = uml_kmalloc(sizeof(struct sockaddr_in), UM_GFP_KERNEL);
-	if (sin == NULL) {
-		printk(UM_KERN_ERR "new_addr: allocation of sockaddr_in "
-		       "failed\n");
-		return NULL;
-	}
-	sin->sin_family = AF_INET;
-	sin->sin_addr.s_addr = in_aton(addr);
-	sin->sin_port = htons(port);
-	return sin;
-}
-
-static int mcast_user_init(void *data, void *dev)
-{
-	struct mcast_data *pri = data;
-
-	pri->mcast_addr = new_addr(pri->addr, pri->port);
-	pri->dev = dev;
-	return 0;
-}
-
-static void mcast_remove(void *data)
-{
-	struct mcast_data *pri = data;
-
-	kfree(pri->mcast_addr);
-	pri->mcast_addr = NULL;
-}
-
-static int mcast_open(void *data)
-{
-	struct mcast_data *pri = data;
-	struct sockaddr_in *sin = pri->mcast_addr;
-	struct ip_mreq mreq;
-	int fd, yes = 1, err = -EINVAL;
-
-
-	if ((sin->sin_addr.s_addr == 0) || (sin->sin_port == 0))
-		goto out;
-
-	fd = socket(AF_INET, SOCK_DGRAM, 0);
-
-	if (fd < 0) {
-		err = -errno;
-		printk(UM_KERN_ERR "mcast_open : data socket failed, "
-		       "errno = %d\n", errno);
-		goto out;
-	}
-
-	if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)) < 0) {
-		err = -errno;
-		printk(UM_KERN_ERR "mcast_open: SO_REUSEADDR failed, "
-		       "errno = %d\n", errno);
-		goto out_close;
-	}
-
-	/* set ttl according to config */
-	if (setsockopt(fd, SOL_IP, IP_MULTICAST_TTL, &pri->ttl,
-		       sizeof(pri->ttl)) < 0) {
-		err = -errno;
-		printk(UM_KERN_ERR "mcast_open: IP_MULTICAST_TTL failed, "
-		       "error = %d\n", errno);
-		goto out_close;
-	}
-
-	/* set LOOP, so data does get fed back to local sockets */
-	if (setsockopt(fd, SOL_IP, IP_MULTICAST_LOOP, &yes, sizeof(yes)) < 0) {
-		err = -errno;
-		printk(UM_KERN_ERR "mcast_open: IP_MULTICAST_LOOP failed, "
-		       "error = %d\n", errno);
-		goto out_close;
-	}
-
-	/* bind socket to mcast address */
-	if (bind(fd, (struct sockaddr *) sin, sizeof(*sin)) < 0) {
-		err = -errno;
-		printk(UM_KERN_ERR "mcast_open : data bind failed, "
-		       "errno = %d\n", errno);
-		goto out_close;
-	}
-
-	/* subscribe to the multicast group */
-	mreq.imr_multiaddr.s_addr = sin->sin_addr.s_addr;
-	mreq.imr_interface.s_addr = 0;
-	if (setsockopt(fd, SOL_IP, IP_ADD_MEMBERSHIP,
-		       &mreq, sizeof(mreq)) < 0) {
-		err = -errno;
-		printk(UM_KERN_ERR "mcast_open: IP_ADD_MEMBERSHIP failed, "
-		       "error = %d\n", errno);
-		printk(UM_KERN_ERR "There appears not to be a multicast-"
-		       "capable network interface on the host.\n");
-		printk(UM_KERN_ERR "eth0 should be configured in order to use "
-		       "the multicast transport.\n");
-		goto out_close;
-	}
-
-	return fd;
-
- out_close:
-	close(fd);
- out:
-	return err;
-}
-
-static void mcast_close(int fd, void *data)
-{
-	struct ip_mreq mreq;
-	struct mcast_data *pri = data;
-	struct sockaddr_in *sin = pri->mcast_addr;
-
-	mreq.imr_multiaddr.s_addr = sin->sin_addr.s_addr;
-	mreq.imr_interface.s_addr = 0;
-	if (setsockopt(fd, SOL_IP, IP_DROP_MEMBERSHIP,
-		       &mreq, sizeof(mreq)) < 0) {
-		printk(UM_KERN_ERR "mcast_open: IP_DROP_MEMBERSHIP failed, "
-		       "error = %d\n", errno);
-	}
-
-	close(fd);
-}
-
-int mcast_user_write(int fd, void *buf, int len, struct mcast_data *pri)
-{
-	struct sockaddr_in *data_addr = pri->mcast_addr;
-
-	return net_sendto(fd, buf, len, data_addr, sizeof(*data_addr));
-}
-
-const struct net_user_info mcast_user_info = {
-	.init		= mcast_user_init,
-	.open		= mcast_open,
-	.close	 	= mcast_close,
-	.remove	 	= mcast_remove,
-	.add_address	= NULL,
-	.delete_address = NULL,
-	.mtu		= ETH_MAX_PACKET,
-	.max_packet	= ETH_MAX_PACKET + ETH_HEADER_OTHER,
-};
diff -druN linux-2.6.39-libre/arch/um/drivers/mmapper_kern.c linux-3.0-rc7-libre/arch/um/drivers/mmapper_kern.c
--- linux-2.6.39-libre/arch/um/drivers/mmapper_kern.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/um/drivers/mmapper_kern.c	2011-07-11 19:51:52.000000000 -0400
@@ -116,7 +116,7 @@
 	if (err) {
 		printk(KERN_ERR "mmapper - misc_register failed, err = %d\n",
 		       err);
-		return err;;
+		return err;
 	}
 	return 0;
 }
diff -druN linux-2.6.39-libre/arch/um/drivers/umcast.h linux-3.0-rc7-libre/arch/um/drivers/umcast.h
--- linux-2.6.39-libre/arch/um/drivers/umcast.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/um/drivers/umcast.h	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2001 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
+ * Licensed under the GPL
+ */
+
+#ifndef __DRIVERS_UMCAST_H
+#define __DRIVERS_UMCAST_H
+
+#include "net_user.h"
+
+struct umcast_data {
+	char *addr;
+	unsigned short lport;
+	unsigned short rport;
+	void *listen_addr;
+	void *remote_addr;
+	int ttl;
+	int unicast;
+	void *dev;
+};
+
+extern const struct net_user_info umcast_user_info;
+
+extern int umcast_user_write(int fd, void *buf, int len,
+			     struct umcast_data *pri);
+
+#endif
diff -druN linux-2.6.39-libre/arch/um/drivers/umcast_kern.c linux-3.0-rc7-libre/arch/um/drivers/umcast_kern.c
--- linux-2.6.39-libre/arch/um/drivers/umcast_kern.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/um/drivers/umcast_kern.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,188 @@
+/*
+ * user-mode-linux networking multicast transport
+ * Copyright (C) 2001 by Harald Welte <laforge@gnumonks.org>
+ * Copyright (C) 2001 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
+ *
+ * based on the existing uml-networking code, which is
+ * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org) and
+ * James Leu (jleu@mindspring.net).
+ * Copyright (C) 2001 by various other people who didn't put their name here.
+ *
+ * Licensed under the GPL.
+ */
+
+#include "linux/init.h"
+#include <linux/netdevice.h>
+#include "umcast.h"
+#include "net_kern.h"
+
+struct umcast_init {
+	char *addr;
+	int lport;
+	int rport;
+	int ttl;
+	bool unicast;
+};
+
+static void umcast_init(struct net_device *dev, void *data)
+{
+	struct uml_net_private *pri;
+	struct umcast_data *dpri;
+	struct umcast_init *init = data;
+
+	pri = netdev_priv(dev);
+	dpri = (struct umcast_data *) pri->user;
+	dpri->addr = init->addr;
+	dpri->lport = init->lport;
+	dpri->rport = init->rport;
+	dpri->unicast = init->unicast;
+	dpri->ttl = init->ttl;
+	dpri->dev = dev;
+
+	if (dpri->unicast) {
+		printk(KERN_INFO "ucast backend address: %s:%u listen port: "
+		       "%u\n", dpri->addr, dpri->rport, dpri->lport);
+	} else {
+		printk(KERN_INFO "mcast backend multicast address: %s:%u, "
+		       "TTL:%u\n", dpri->addr, dpri->lport, dpri->ttl);
+	}
+}
+
+static int umcast_read(int fd, struct sk_buff *skb, struct uml_net_private *lp)
+{
+	return net_recvfrom(fd, skb_mac_header(skb),
+			    skb->dev->mtu + ETH_HEADER_OTHER);
+}
+
+static int umcast_write(int fd, struct sk_buff *skb, struct uml_net_private *lp)
+{
+	return umcast_user_write(fd, skb->data, skb->len,
+				(struct umcast_data *) &lp->user);
+}
+
+static const struct net_kern_info umcast_kern_info = {
+	.init			= umcast_init,
+	.protocol		= eth_protocol,
+	.read			= umcast_read,
+	.write			= umcast_write,
+};
+
+static int mcast_setup(char *str, char **mac_out, void *data)
+{
+	struct umcast_init *init = data;
+	char *port_str = NULL, *ttl_str = NULL, *remain;
+	char *last;
+
+	*init = ((struct umcast_init)
+		{ .addr	= "239.192.168.1",
+		  .lport	= 1102,
+		  .ttl	= 1 });
+
+	remain = split_if_spec(str, mac_out, &init->addr, &port_str, &ttl_str,
+			       NULL);
+	if (remain != NULL) {
+		printk(KERN_ERR "mcast_setup - Extra garbage on "
+		       "specification : '%s'\n", remain);
+		return 0;
+	}
+
+	if (port_str != NULL) {
+		init->lport = simple_strtoul(port_str, &last, 10);
+		if ((*last != '\0') || (last == port_str)) {
+			printk(KERN_ERR "mcast_setup - Bad port : '%s'\n",
+			       port_str);
+			return 0;
+		}
+	}
+
+	if (ttl_str != NULL) {
+		init->ttl = simple_strtoul(ttl_str, &last, 10);
+		if ((*last != '\0') || (last == ttl_str)) {
+			printk(KERN_ERR "mcast_setup - Bad ttl : '%s'\n",
+			       ttl_str);
+			return 0;
+		}
+	}
+
+	init->unicast = false;
+	init->rport = init->lport;
+
+	printk(KERN_INFO "Configured mcast device: %s:%u-%u\n", init->addr,
+	       init->lport, init->ttl);
+
+	return 1;
+}
+
+static int ucast_setup(char *str, char **mac_out, void *data)
+{
+	struct umcast_init *init = data;
+	char *lport_str = NULL, *rport_str = NULL, *remain;
+	char *last;
+
+	*init = ((struct umcast_init)
+		{ .addr		= "",
+		  .lport	= 1102,
+		  .rport	= 1102 });
+
+	remain = split_if_spec(str, mac_out, &init->addr,
+			       &lport_str, &rport_str, NULL);
+	if (remain != NULL) {
+		printk(KERN_ERR "ucast_setup - Extra garbage on "
+		       "specification : '%s'\n", remain);
+		return 0;
+	}
+
+	if (lport_str != NULL) {
+		init->lport = simple_strtoul(lport_str, &last, 10);
+		if ((*last != '\0') || (last == lport_str)) {
+			printk(KERN_ERR "ucast_setup - Bad listen port : "
+			       "'%s'\n", lport_str);
+			return 0;
+		}
+	}
+
+	if (rport_str != NULL) {
+		init->rport = simple_strtoul(rport_str, &last, 10);
+		if ((*last != '\0') || (last == rport_str)) {
+			printk(KERN_ERR "ucast_setup - Bad remote port : "
+			       "'%s'\n", rport_str);
+			return 0;
+		}
+	}
+
+	init->unicast = true;
+
+	printk(KERN_INFO "Configured ucast device: :%u -> %s:%u\n",
+	       init->lport, init->addr, init->rport);
+
+	return 1;
+}
+
+static struct transport mcast_transport = {
+	.list	= LIST_HEAD_INIT(mcast_transport.list),
+	.name	= "mcast",
+	.setup	= mcast_setup,
+	.user	= &umcast_user_info,
+	.kern	= &umcast_kern_info,
+	.private_size	= sizeof(struct umcast_data),
+	.setup_size	= sizeof(struct umcast_init),
+};
+
+static struct transport ucast_transport = {
+	.list	= LIST_HEAD_INIT(ucast_transport.list),
+	.name	= "ucast",
+	.setup	= ucast_setup,
+	.user	= &umcast_user_info,
+	.kern	= &umcast_kern_info,
+	.private_size	= sizeof(struct umcast_data),
+	.setup_size	= sizeof(struct umcast_init),
+};
+
+static int register_umcast(void)
+{
+	register_transport(&mcast_transport);
+	register_transport(&ucast_transport);
+	return 0;
+}
+
+late_initcall(register_umcast);
diff -druN linux-2.6.39-libre/arch/um/drivers/umcast_user.c linux-3.0-rc7-libre/arch/um/drivers/umcast_user.c
--- linux-2.6.39-libre/arch/um/drivers/umcast_user.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/um/drivers/umcast_user.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,186 @@
+/*
+ * user-mode-linux networking multicast transport
+ * Copyright (C) 2001 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
+ * Copyright (C) 2001 by Harald Welte <laforge@gnumonks.org>
+ *
+ * based on the existing uml-networking code, which is
+ * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org) and
+ * James Leu (jleu@mindspring.net).
+ * Copyright (C) 2001 by various other people who didn't put their name here.
+ *
+ * Licensed under the GPL.
+ *
+ */
+
+#include <unistd.h>
+#include <errno.h>
+#include <netinet/in.h>
+#include "kern_constants.h"
+#include "umcast.h"
+#include "net_user.h"
+#include "um_malloc.h"
+#include "user.h"
+
+static struct sockaddr_in *new_addr(char *addr, unsigned short port)
+{
+	struct sockaddr_in *sin;
+
+	sin = uml_kmalloc(sizeof(struct sockaddr_in), UM_GFP_KERNEL);
+	if (sin == NULL) {
+		printk(UM_KERN_ERR "new_addr: allocation of sockaddr_in "
+		       "failed\n");
+		return NULL;
+	}
+	sin->sin_family = AF_INET;
+	if (addr)
+		sin->sin_addr.s_addr = in_aton(addr);
+	else
+		sin->sin_addr.s_addr = INADDR_ANY;
+	sin->sin_port = htons(port);
+	return sin;
+}
+
+static int umcast_user_init(void *data, void *dev)
+{
+	struct umcast_data *pri = data;
+
+	pri->remote_addr = new_addr(pri->addr, pri->rport);
+	if (pri->unicast)
+		pri->listen_addr = new_addr(NULL, pri->lport);
+	else
+		pri->listen_addr = pri->remote_addr;
+	pri->dev = dev;
+	return 0;
+}
+
+static void umcast_remove(void *data)
+{
+	struct umcast_data *pri = data;
+
+	kfree(pri->listen_addr);
+	if (pri->unicast)
+		kfree(pri->remote_addr);
+	pri->listen_addr = pri->remote_addr = NULL;
+}
+
+static int umcast_open(void *data)
+{
+	struct umcast_data *pri = data;
+	struct sockaddr_in *lsin = pri->listen_addr;
+	struct sockaddr_in *rsin = pri->remote_addr;
+	struct ip_mreq mreq;
+	int fd, yes = 1, err = -EINVAL;
+
+
+	if ((!pri->unicast && lsin->sin_addr.s_addr == 0) ||
+	    (rsin->sin_addr.s_addr == 0) ||
+	    (lsin->sin_port == 0) || (rsin->sin_port == 0))
+		goto out;
+
+	fd = socket(AF_INET, SOCK_DGRAM, 0);
+
+	if (fd < 0) {
+		err = -errno;
+		printk(UM_KERN_ERR "umcast_open : data socket failed, "
+		       "errno = %d\n", errno);
+		goto out;
+	}
+
+	if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)) < 0) {
+		err = -errno;
+		printk(UM_KERN_ERR "umcast_open: SO_REUSEADDR failed, "
+		       "errno = %d\n", errno);
+		goto out_close;
+	}
+
+	if (!pri->unicast) {
+		/* set ttl according to config */
+		if (setsockopt(fd, SOL_IP, IP_MULTICAST_TTL, &pri->ttl,
+			       sizeof(pri->ttl)) < 0) {
+			err = -errno;
+			printk(UM_KERN_ERR "umcast_open: IP_MULTICAST_TTL "
+			       "failed, error = %d\n", errno);
+			goto out_close;
+		}
+
+		/* set LOOP, so data does get fed back to local sockets */
+		if (setsockopt(fd, SOL_IP, IP_MULTICAST_LOOP,
+			       &yes, sizeof(yes)) < 0) {
+			err = -errno;
+			printk(UM_KERN_ERR "umcast_open: IP_MULTICAST_LOOP "
+			       "failed, error = %d\n", errno);
+			goto out_close;
+		}
+	}
+
+	/* bind socket to the address */
+	if (bind(fd, (struct sockaddr *) lsin, sizeof(*lsin)) < 0) {
+		err = -errno;
+		printk(UM_KERN_ERR "umcast_open : data bind failed, "
+		       "errno = %d\n", errno);
+		goto out_close;
+	}
+
+	if (!pri->unicast) {
+		/* subscribe to the multicast group */
+		mreq.imr_multiaddr.s_addr = lsin->sin_addr.s_addr;
+		mreq.imr_interface.s_addr = 0;
+		if (setsockopt(fd, SOL_IP, IP_ADD_MEMBERSHIP,
+			       &mreq, sizeof(mreq)) < 0) {
+			err = -errno;
+			printk(UM_KERN_ERR "umcast_open: IP_ADD_MEMBERSHIP "
+			       "failed, error = %d\n", errno);
+			printk(UM_KERN_ERR "There appears not to be a "
+			       "multicast-capable network interface on the "
+			       "host.\n");
+			printk(UM_KERN_ERR "eth0 should be configured in order "
+			       "to use the multicast transport.\n");
+			goto out_close;
+		}
+	}
+
+	return fd;
+
+ out_close:
+	close(fd);
+ out:
+	return err;
+}
+
+static void umcast_close(int fd, void *data)
+{
+	struct umcast_data *pri = data;
+
+	if (!pri->unicast) {
+		struct ip_mreq mreq;
+		struct sockaddr_in *lsin = pri->listen_addr;
+
+		mreq.imr_multiaddr.s_addr = lsin->sin_addr.s_addr;
+		mreq.imr_interface.s_addr = 0;
+		if (setsockopt(fd, SOL_IP, IP_DROP_MEMBERSHIP,
+			       &mreq, sizeof(mreq)) < 0) {
+			printk(UM_KERN_ERR "umcast_close: IP_DROP_MEMBERSHIP "
+			       "failed, error = %d\n", errno);
+		}
+	}
+
+	close(fd);
+}
+
+int umcast_user_write(int fd, void *buf, int len, struct umcast_data *pri)
+{
+	struct sockaddr_in *data_addr = pri->remote_addr;
+
+	return net_sendto(fd, buf, len, data_addr, sizeof(*data_addr));
+}
+
+const struct net_user_info umcast_user_info = {
+	.init	= umcast_user_init,
+	.open	= umcast_open,
+	.close	= umcast_close,
+	.remove	= umcast_remove,
+	.add_address	= NULL,
+	.delete_address = NULL,
+	.mtu	= ETH_MAX_PACKET,
+	.max_packet	= ETH_MAX_PACKET + ETH_HEADER_OTHER,
+};
diff -druN linux-2.6.39-libre/arch/um/drivers/xterm.c linux-3.0-rc7-libre/arch/um/drivers/xterm.c
--- linux-2.6.39-libre/arch/um/drivers/xterm.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/um/drivers/xterm.c	2011-07-11 19:51:52.000000000 -0400
@@ -90,7 +90,7 @@
 	int pid, fd, new, err;
 	char title[256], file[] = "/tmp/xterm-pipeXXXXXX";
 	char *argv[] = { terminal_emulator, title_switch, title, exec_switch,
-			 "/usr/lib/uml/port-helper", "-uml-socket",
+			 OS_LIB_PATH "/uml/port-helper", "-uml-socket",
 			 file, NULL };
 
 	if (access(argv[4], X_OK) < 0)
diff -druN linux-2.6.39-libre/arch/um/include/asm/common.lds.S linux-3.0-rc7-libre/arch/um/include/asm/common.lds.S
--- linux-2.6.39-libre/arch/um/include/asm/common.lds.S	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/um/include/asm/common.lds.S	2011-07-11 19:51:52.000000000 -0400
@@ -42,7 +42,7 @@
 	INIT_SETUP(0)
   }
 
-  PERCPU(32, 32)
+  PERCPU_SECTION(32)
 	
   .initcall.init : {
 	INIT_CALLS
diff -druN linux-2.6.39-libre/arch/um/include/asm/percpu.h linux-3.0-rc7-libre/arch/um/include/asm/percpu.h
--- linux-2.6.39-libre/arch/um/include/asm/percpu.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/um/include/asm/percpu.h	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,6 @@
+#ifndef __UM_PERCPU_H
+#define __UM_PERCPU_H
+
+#include <asm-generic/percpu.h>
+
+#endif /* __UM_PERCPU_H */
diff -druN linux-2.6.39-libre/arch/um/include/asm/processor-generic.h linux-3.0-rc7-libre/arch/um/include/asm/processor-generic.h
--- linux-2.6.39-libre/arch/um/include/asm/processor-generic.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/um/include/asm/processor-generic.h	2011-07-11 19:51:52.000000000 -0400
@@ -14,6 +14,8 @@
 #include "registers.h"
 #include "sysdep/archsetjmp.h"
 
+#include <linux/prefetch.h>
+
 struct mm_struct;
 
 struct thread_struct {
diff -druN linux-2.6.39-libre/arch/um/include/asm/smp.h linux-3.0-rc7-libre/arch/um/include/asm/smp.h
--- linux-2.6.39-libre/arch/um/include/asm/smp.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/um/include/asm/smp.h	2011-07-11 19:51:52.000000000 -0400
@@ -11,7 +11,6 @@
 
 #define cpu_logical_map(n) (n)
 #define cpu_number_map(n) (n)
-#define PROC_CHANGE_PENALTY	15 /* Pick a number, any number */
 extern int hard_smp_processor_id(void);
 #define NO_PROC_ID -1
 
diff -druN linux-2.6.39-libre/arch/um/include/asm/tlb.h linux-3.0-rc7-libre/arch/um/include/asm/tlb.h
--- linux-2.6.39-libre/arch/um/include/asm/tlb.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/um/include/asm/tlb.h	2011-07-11 19:51:52.000000000 -0400
@@ -22,9 +22,6 @@
 	unsigned int		fullmm; /* non-zero means full mm flush */
 };
 
-/* Users of the generic TLB shootdown code must declare this storage space. */
-DECLARE_PER_CPU(struct mmu_gather, mmu_gathers);
-
 static inline void __tlb_remove_tlb_entry(struct mmu_gather *tlb, pte_t *ptep,
 					  unsigned long address)
 {
@@ -47,27 +44,20 @@
 	}
 }
 
-/* tlb_gather_mmu
- *	Return a pointer to an initialized struct mmu_gather.
- */
-static inline struct mmu_gather *
-tlb_gather_mmu(struct mm_struct *mm, unsigned int full_mm_flush)
+static inline void
+tlb_gather_mmu(struct mmu_gather *tlb, struct mm_struct *mm, unsigned int full_mm_flush)
 {
-	struct mmu_gather *tlb = &get_cpu_var(mmu_gathers);
-
 	tlb->mm = mm;
 	tlb->fullmm = full_mm_flush;
 
 	init_tlb_gather(tlb);
-
-	return tlb;
 }
 
 extern void flush_tlb_mm_range(struct mm_struct *mm, unsigned long start,
 			       unsigned long end);
 
 static inline void
-tlb_flush_mmu(struct mmu_gather *tlb, unsigned long start, unsigned long end)
+tlb_flush_mmu(struct mmu_gather *tlb)
 {
 	if (!tlb->need_flush)
 		return;
@@ -83,12 +73,10 @@
 static inline void
 tlb_finish_mmu(struct mmu_gather *tlb, unsigned long start, unsigned long end)
 {
-	tlb_flush_mmu(tlb, start, end);
+	tlb_flush_mmu(tlb);
 
 	/* keep the page table cache within bounds */
 	check_pgt_cache();
-
-	put_cpu_var(mmu_gathers);
 }
 
 /* tlb_remove_page
@@ -96,11 +84,16 @@
  *	while handling the additional races in SMP caused by other CPUs
  *	caching valid mappings in their TLBs.
  */
-static inline void tlb_remove_page(struct mmu_gather *tlb, struct page *page)
+static inline int __tlb_remove_page(struct mmu_gather *tlb, struct page *page)
 {
 	tlb->need_flush = 1;
 	free_page_and_swap_cache(page);
-	return;
+	return 1; /* avoid calling tlb_flush_mmu */
+}
+
+static inline void tlb_remove_page(struct mmu_gather *tlb, struct page *page)
+{
+	__tlb_remove_page(tlb, page);
 }
 
 /**
diff -druN linux-2.6.39-libre/arch/um/include/shared/os.h linux-3.0-rc7-libre/arch/um/include/shared/os.h
--- linux-2.6.39-libre/arch/um/include/shared/os.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/um/include/shared/os.h	2011-07-11 19:51:52.000000000 -0400
@@ -29,6 +29,12 @@
 #define OS_ACC_R_OK    4       /* Test for read permission.  */
 #define OS_ACC_RW_OK   (OS_ACC_W_OK | OS_ACC_R_OK) /* Test for RW permission */
 
+#ifdef CONFIG_64BIT
+#define OS_LIB_PATH	"/usr/lib64/"
+#else
+#define OS_LIB_PATH	"/usr/lib/"
+#endif
+
 /*
  * types taken from stat_file() in hostfs_user.c
  * (if they are wrong here, they are wrong there...).
@@ -238,6 +244,7 @@
 extern void setup_machinename(char *machine_out);
 extern void setup_hostinfo(char *buf, int len);
 extern void os_dump_core(void) __attribute__ ((noreturn));
+extern void um_early_printk(const char *s, unsigned int n);
 
 /* time.c */
 extern void idle_sleep(unsigned long long nsecs);
diff -druN linux-2.6.39-libre/arch/um/Kconfig.debug linux-3.0-rc7-libre/arch/um/Kconfig.debug
--- linux-2.6.39-libre/arch/um/Kconfig.debug	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/um/Kconfig.debug	2011-07-11 19:51:52.000000000 -0400
@@ -28,13 +28,13 @@
 	  If you're involved in UML kernel development and want to use gcov,
 	  say Y.  If you're unsure, say N.
 
-config DEBUG_STACK_USAGE
-	bool "Stack utilization instrumentation"
-	default N
-	help
-	  Track the maximum kernel stack usage - this will look at each
-	  kernel stack at process exit and log it if it's the deepest
-	  stack seen so far.
+config EARLY_PRINTK
+	bool "Early printk"
+	default y
+	---help---
+	  Write kernel log output directly to stdout.
+
+	  This is useful for kernel debugging when your machine crashes very
+	  early before the console code is initialized.
 
-	  This option will slow down process creation and destruction somewhat.
 endmenu
diff -druN linux-2.6.39-libre/arch/um/Kconfig.x86 linux-3.0-rc7-libre/arch/um/Kconfig.x86
--- linux-2.6.39-libre/arch/um/Kconfig.x86	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/um/Kconfig.x86	2011-07-11 19:51:52.000000000 -0400
@@ -15,7 +15,6 @@
 config UML_X86
 	def_bool y
 	select GENERIC_FIND_FIRST_BIT
-	select GENERIC_FIND_NEXT_BIT
 
 config 64BIT
 	bool
@@ -29,10 +28,10 @@
 	def_bool 64BIT
 
 config RWSEM_XCHGADD_ALGORITHM
-	def_bool X86_XADD
+	def_bool X86_XADD && 64BIT
 
 config RWSEM_GENERIC_SPINLOCK
-	def_bool !X86_XADD
+	def_bool !RWSEM_XCHGADD_ALGORITHM
 
 config 3_LEVEL_PGTABLES
 	bool "Three-level pagetables (EXPERIMENTAL)" if !64BIT
diff -druN linux-2.6.39-libre/arch/um/kernel/early_printk.c linux-3.0-rc7-libre/arch/um/kernel/early_printk.c
--- linux-2.6.39-libre/arch/um/kernel/early_printk.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/um/kernel/early_printk.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2011 Richard Weinberger <richrd@nod.at>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/console.h>
+#include <linux/init.h>
+#include "os.h"
+
+static void early_console_write(struct console *con, const char *s, unsigned int n)
+{
+	um_early_printk(s, n);
+}
+
+static struct console early_console = {
+	.name = "earlycon",
+	.write = early_console_write,
+	.flags = CON_BOOT,
+	.index = -1,
+};
+
+static int __init setup_early_printk(char *buf)
+{
+	register_console(&early_console);
+
+	return 0;
+}
+
+early_param("earlyprintk", setup_early_printk);
diff -druN linux-2.6.39-libre/arch/um/kernel/Makefile linux-3.0-rc7-libre/arch/um/kernel/Makefile
--- linux-2.6.39-libre/arch/um/kernel/Makefile	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/um/kernel/Makefile	2011-07-11 19:51:52.000000000 -0400
@@ -17,6 +17,7 @@
 obj-$(CONFIG_BLK_DEV_INITRD) += initrd.o
 obj-$(CONFIG_GPROF)	+= gprof_syms.o
 obj-$(CONFIG_GCOV)	+= gmon_syms.o
+obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
 
 USER_OBJS := config.o
 
diff -druN linux-2.6.39-libre/arch/um/kernel/smp.c linux-3.0-rc7-libre/arch/um/kernel/smp.c
--- linux-2.6.39-libre/arch/um/kernel/smp.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/um/kernel/smp.c	2011-07-11 19:51:52.000000000 -0400
@@ -7,9 +7,6 @@
 #include "asm/pgalloc.h"
 #include "asm/tlb.h"
 
-/* For some reason, mmu_gathers are referenced when CONFIG_SMP is off. */
-DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
-
 #ifdef CONFIG_SMP
 
 #include "linux/sched.h"
@@ -173,7 +170,7 @@
 			break;
 
 		case 'R':
-			set_tsk_need_resched(current);
+			scheduler_ipi();
 			break;
 
 		case 'S':
diff -druN linux-2.6.39-libre/arch/um/kernel/trap.c linux-3.0-rc7-libre/arch/um/kernel/trap.c
--- linux-2.6.39-libre/arch/um/kernel/trap.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/um/kernel/trap.c	2011-07-11 19:51:52.000000000 -0400
@@ -113,6 +113,27 @@
 	return 0;
 }
 
+static void show_segv_info(struct uml_pt_regs *regs)
+{
+	struct task_struct *tsk = current;
+	struct faultinfo *fi = UPT_FAULTINFO(regs);
+
+	if (!unhandled_signal(tsk, SIGSEGV))
+		return;
+
+	if (!printk_ratelimit())
+		return;
+
+	printk("%s%s[%d]: segfault at %lx ip %p sp %p error %x",
+		task_pid_nr(tsk) > 1 ? KERN_INFO : KERN_EMERG,
+		tsk->comm, task_pid_nr(tsk), FAULT_ADDRESS(*fi),
+		(void *)UPT_IP(regs), (void *)UPT_SP(regs),
+		fi->error_code);
+
+	print_vma_addr(KERN_CONT " in ", UPT_IP(regs));
+	printk(KERN_CONT "\n");
+}
+
 static void bad_segv(struct faultinfo fi, unsigned long ip)
 {
 	struct siginfo si;
@@ -141,6 +162,7 @@
 	struct faultinfo * fi = UPT_FAULTINFO(regs);
 
 	if (UPT_IS_USER(regs) && !SEGV_IS_FIXABLE(fi)) {
+		show_segv_info(regs);
 		bad_segv(*fi, UPT_IP(regs));
 		return;
 	}
@@ -202,6 +224,8 @@
 		      address, ip);
 	}
 
+	show_segv_info(regs);
+
 	if (err == -EACCES) {
 		si.si_signo = SIGBUS;
 		si.si_errno = 0;
diff -druN linux-2.6.39-libre/arch/um/os-Linux/main.c linux-3.0-rc7-libre/arch/um/os-Linux/main.c
--- linux-2.6.39-libre/arch/um/os-Linux/main.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/um/os-Linux/main.c	2011-07-11 19:51:52.000000000 -0400
@@ -78,7 +78,7 @@
 	}
 }
 
-#define UML_LIB_PATH	":/usr/lib/uml"
+#define UML_LIB_PATH	":" OS_LIB_PATH "/uml"
 
 static void setup_env_path(void)
 {
@@ -142,7 +142,6 @@
 	 */
 	install_fatal_handler(SIGINT);
 	install_fatal_handler(SIGTERM);
-	install_fatal_handler(SIGHUP);
 
 	scan_elf_aux(envp);
 
diff -druN linux-2.6.39-libre/arch/um/os-Linux/process.c linux-3.0-rc7-libre/arch/um/os-Linux/process.c
--- linux-2.6.39-libre/arch/um/os-Linux/process.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/um/os-Linux/process.c	2011-07-11 19:51:52.000000000 -0400
@@ -253,6 +253,7 @@
 		    SA_ONSTACK | SA_RESTART, SIGUSR1, SIGIO, SIGWINCH, SIGALRM,
 		    SIGVTALRM, -1);
 	signal(SIGWINCH, SIG_IGN);
+	signal(SIGTERM, SIG_DFL);
 }
 
 int run_kernel_thread(int (*fn)(void *), void *arg, jmp_buf **jmp_ptr)
diff -druN linux-2.6.39-libre/arch/um/os-Linux/util.c linux-3.0-rc7-libre/arch/um/os-Linux/util.c
--- linux-2.6.39-libre/arch/um/os-Linux/util.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/um/os-Linux/util.c	2011-07-11 19:51:52.000000000 -0400
@@ -139,3 +139,8 @@
 
 	uml_abort();
 }
+
+void um_early_printk(const char *s, unsigned int n)
+{
+	printf("%.*s", n, s);
+}
diff -druN linux-2.6.39-libre/arch/unicore32/boot/compressed/Makefile linux-3.0-rc7-libre/arch/unicore32/boot/compressed/Makefile
--- linux-2.6.39-libre/arch/unicore32/boot/compressed/Makefile	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/unicore32/boot/compressed/Makefile	2011-07-11 19:51:52.000000000 -0400
@@ -59,7 +59,7 @@
 # We now have a PIC decompressor implementation.  Decompressors running
 # from RAM should not define ZTEXTADDR.  Decompressors running directly
 # from ROM or Flash must define ZTEXTADDR (preferably via the config)
-ZTEXTADDR	:= 0
+ZTEXTADDR	:= 0x03000000
 ZBSSADDR	:= ALIGN(4)
 
 SEDFLAGS_lds	= s/TEXT_START/$(ZTEXTADDR)/;s/BSS_START/$(ZBSSADDR)/
diff -druN linux-2.6.39-libre/arch/unicore32/configs/debug_defconfig linux-3.0-rc7-libre/arch/unicore32/configs/debug_defconfig
--- linux-2.6.39-libre/arch/unicore32/configs/debug_defconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/unicore32/configs/debug_defconfig	1969-12-31 19:00:00.000000000 -0500
@@ -1,215 +0,0 @@
-### General setup
-CONFIG_EXPERIMENTAL=y
-CONFIG_LOCALVERSION="-debug"
-CONFIG_SWAP=y
-CONFIG_SYSVIPC=y
-CONFIG_POSIX_MQUEUE=y
-CONFIG_HOTPLUG=y
-#	Initial RAM filesystem and RAM disk (initramfs/initrd) support
-#CONFIG_BLK_DEV_INITRD=y
-#CONFIG_INITRAMFS_SOURCE="arch/unicore/ramfs/ramfs_config"
-
-### Enable loadable module support
-CONFIG_MODULES=n
-CONFIG_MODULE_UNLOAD=y
-
-### System Type
-CONFIG_ARCH_PUV3=y
-#	Board Selection
-CONFIG_PUV3_NB0916=y
-#	Processor Features
-CONFIG_CPU_DCACHE_LINE_DISABLE=y
-CONFIG_CPU_TLB_SINGLE_ENTRY_DISABLE=n
-
-### Bus support
-CONFIG_PCI=y
-CONFIG_PCI_LEGACY=n
-
-### Boot options
-#	for debug, adding: earlyprintk=ocd,keep initcall_debug
-#	others support: test_suspend=mem root=/dev/sda
-#	hibernate support: resume=/dev/sda3
-CONFIG_CMDLINE="earlyprintk=ocd,keep ignore_loglevel"
-# TODO: mem=512M video=unifb:1024x600-16@75
-# for nfs: root=/dev/nfs rw nfsroot=192.168.10.88:/home/udb/nfs/,rsize=1024,wsize=1024
-#	ip=192.168.10.83:192.168.10.88:192.168.10.1:255.255.255.0::eth0:off
-CONFIG_CMDLINE_FORCE=y
-
-### Power management options
-CONFIG_PM=y
-CONFIG_HIBERNATION=y
-CONFIG_PM_STD_PARTITION="/dev/sda3"
-CONFIG_CPU_FREQ=n
-CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE=y
-
-### Networking support
-CONFIG_NET=y
-#	Networking options
-CONFIG_PACKET=m
-CONFIG_UNIX=m
-#	TCP/IP networking
-CONFIG_INET=y
-CONFIG_IP_MULTICAST=y
-CONFIG_IP_PNP=y
-CONFIG_IPV6=n
-#	Wireless
-CONFIG_WIRELESS=y
-CONFIG_WIRELESS_EXT=y
-CONFIG_MAC80211=m
-
-### PKUnity SoC Features
-CONFIG_USB_WLAN_HED_AQ3=n
-CONFIG_USB_CMMB_INNOFIDEI=n
-CONFIG_I2C_BATTERY_BQ27200=n
-CONFIG_I2C_EEPROM_AT24=n
-CONFIG_LCD_BACKLIGHT=n
-
-CONFIG_PUV3_RTC=y
-CONFIG_PUV3_UMAL=y
-CONFIG_PUV3_MUSB=n
-CONFIG_PUV3_AC97=n
-CONFIG_PUV3_NAND=n
-CONFIG_PUV3_MMC=n
-CONFIG_PUV3_UART=n
-
-### Device Drivers
-#	Memory Technology Device (MTD) support
-CONFIG_MTD=m
-CONFIG_MTD_UBI=m
-CONFIG_MTD_PARTITIONS=y
-CONFIG_MTD_CHAR=m
-CONFIG_MTD_BLKDEVS=m
-#	RAM/ROM/Flash chip drivers
-CONFIG_MTD_CFI=m
-CONFIG_MTD_JEDECPROBE=m
-CONFIG_MTD_CFI_AMDSTD=m
-#	Mapping drivers for chip access
-CONFIG_MTD_PHYSMAP=m
-
-#	Block devices
-CONFIG_BLK_DEV_LOOP=m
-
-#	SCSI device support
-CONFIG_SCSI=y
-CONFIG_BLK_DEV_SD=y
-CONFIG_BLK_DEV_SR=m
-CONFIG_CHR_DEV_SG=m
-
-#	Serial ATA (prod) and Parallel ATA (experimental) drivers
-CONFIG_ATA=y
-CONFIG_SATA_VIA=y
-
-#	Network device support
-CONFIG_NETDEVICES=y
-CONFIG_NET_ETHERNET=y
-CONFIG_NETDEV_1000=y
-#	Wireless LAN
-CONFIG_WLAN_80211=n
-CONFIG_RT2X00=n
-CONFIG_RT73USB=n
-
-#	Input device support
-CONFIG_INPUT_EVDEV=m
-#	Keyboards
-CONFIG_KEYBOARD_GPIO=m
-
-#	I2C support
-CONFIG_I2C=y
-CONFIG_I2C_PUV3=y
-
-#	Hardware Monitoring support
-#CONFIG_SENSORS_LM75=m
-#	Generic Thermal sysfs driver
-#CONFIG_THERMAL=m
-#CONFIG_THERMAL_HWMON=y
-
-#	Multimedia support
-CONFIG_MEDIA_SUPPORT=n
-CONFIG_VIDEO_DEV=n
-CONFIG_USB_VIDEO_CLASS=n
-
-#	Graphics support
-CONFIG_FB=y
-CONFIG_FB_PUV3_UNIGFX=y
-#	Console display driver support
-CONFIG_VGA_CONSOLE=n
-CONFIG_FRAMEBUFFER_CONSOLE=y
-CONFIG_FONTS=y
-CONFIG_FONT_8x8=y
-CONFIG_FONT_8x16=y
-#	Bootup logo
-CONFIG_LOGO=n
-
-#	Sound card support
-CONFIG_SOUND=m
-#	Advanced Linux Sound Architecture
-CONFIG_SND=m
-CONFIG_SND_MIXER_OSS=m
-CONFIG_SND_PCM_OSS=m
-
-#	USB support
-CONFIG_USB_ARCH_HAS_HCD=n
-CONFIG_USB=n
-CONFIG_USB_DEVICEFS=n
-CONFIG_USB_PRINTER=n
-CONFIG_USB_STORAGE=n
-#	Inventra Highspeed Dual Role Controller
-CONFIG_USB_MUSB_HDRC=n
-
-#	LED Support
-CONFIG_NEW_LEDS=y
-CONFIG_LEDS_CLASS=y
-CONFIG_LEDS_GPIO=y
-#	LED Triggers
-CONFIG_LEDS_TRIGGERS=y
-CONFIG_LEDS_TRIGGER_TIMER=y
-CONFIG_LEDS_TRIGGER_IDE_DISK=y
-CONFIG_LEDS_TRIGGER_HEARTBEAT=y
-
-#	Real Time Clock
-CONFIG_RTC_LIB=m
-CONFIG_RTC_CLASS=m
-
-### File systems
-CONFIG_EXT2_FS=m
-CONFIG_EXT3_FS=y
-CONFIG_EXT4_FS=y
-CONFIG_FUSE_FS=m
-#	CD-ROM/DVD Filesystems
-CONFIG_ISO9660_FS=m
-CONFIG_JOLIET=y
-CONFIG_UDF_FS=m
-#	DOS/FAT/NT Filesystems
-CONFIG_VFAT_FS=m
-#	Pseudo filesystems
-CONFIG_PROC_FS=y
-CONFIG_SYSFS=y
-CONFIG_TMPFS=y
-#	Miscellaneous filesystems
-CONFIG_MISC_FILESYSTEMS=y
-CONFIG_JFFS2_FS=m
-CONFIG_UBIFS_FS=m
-#	Network File Systems
-CONFIG_NETWORK_FILESYSTEMS=y
-CONFIG_NFS_FS=y
-CONFIG_NFS_V3=y
-CONFIG_ROOT_NFS=y
-#	Partition Types
-CONFIG_PARTITION_ADVANCED=y
-CONFIG_MSDOS_PARTITION=y
-#	Native language support
-CONFIG_NLS=y
-CONFIG_NLS_CODEPAGE_437=m
-CONFIG_NLS_CODEPAGE_936=m
-CONFIG_NLS_ISO8859_1=m
-CONFIG_NLS_UTF8=m
-
-### Kernel hacking
-CONFIG_FRAME_WARN=8096
-CONFIG_MAGIC_SYSRQ=y
-CONFIG_DEBUG_KERNEL=y
-CONFIG_PROVE_LOCKING=n
-CONFIG_DEBUG_BUGVERBOSE=y
-CONFIG_FRAME_POINTER=y
-CONFIG_DEBUG_LL=y
-
diff -druN linux-2.6.39-libre/arch/unicore32/configs/unicore32_defconfig linux-3.0-rc7-libre/arch/unicore32/configs/unicore32_defconfig
--- linux-2.6.39-libre/arch/unicore32/configs/unicore32_defconfig	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/unicore32/configs/unicore32_defconfig	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,215 @@
+### General setup
+CONFIG_EXPERIMENTAL=y
+CONFIG_LOCALVERSION="-unicore32"
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_HOTPLUG=y
+#	Initial RAM filesystem and RAM disk (initramfs/initrd) support
+#CONFIG_BLK_DEV_INITRD=y
+#CONFIG_INITRAMFS_SOURCE="arch/unicore/ramfs/ramfs_config"
+
+### Enable loadable module support
+CONFIG_MODULES=n
+CONFIG_MODULE_UNLOAD=y
+
+### System Type
+CONFIG_ARCH_PUV3=y
+#	Board Selection
+CONFIG_PUV3_NB0916=y
+#	Processor Features
+CONFIG_CPU_DCACHE_LINE_DISABLE=y
+CONFIG_CPU_TLB_SINGLE_ENTRY_DISABLE=n
+
+### Bus support
+CONFIG_PCI=y
+CONFIG_PCI_LEGACY=n
+
+### Boot options
+#	for debug, adding: earlyprintk=ocd,keep initcall_debug
+#	others support: test_suspend=mem root=/dev/sda
+#	hibernate support: resume=/dev/sda3
+CONFIG_CMDLINE="earlyprintk=ocd,keep ignore_loglevel"
+# TODO: mem=512M video=unifb:1024x600-16@75
+# for nfs: root=/dev/nfs rw nfsroot=192.168.10.88:/home/udb/nfs/,rsize=1024,wsize=1024
+#	ip=192.168.10.83:192.168.10.88:192.168.10.1:255.255.255.0::eth0:off
+CONFIG_CMDLINE_FORCE=y
+
+### Power management options
+CONFIG_PM=y
+CONFIG_HIBERNATION=y
+CONFIG_PM_STD_PARTITION="/dev/sda3"
+CONFIG_CPU_FREQ=n
+CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE=y
+
+### Networking support
+CONFIG_NET=y
+#	Networking options
+CONFIG_PACKET=m
+CONFIG_UNIX=m
+#	TCP/IP networking
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_PNP=y
+CONFIG_IPV6=n
+#	Wireless
+CONFIG_WIRELESS=y
+CONFIG_WIRELESS_EXT=y
+CONFIG_MAC80211=m
+
+### PKUnity SoC Features
+CONFIG_USB_WLAN_HED_AQ3=n
+CONFIG_USB_CMMB_INNOFIDEI=n
+CONFIG_I2C_BATTERY_BQ27200=n
+CONFIG_I2C_EEPROM_AT24=n
+CONFIG_LCD_BACKLIGHT=n
+
+CONFIG_PUV3_UMAL=y
+CONFIG_PUV3_MUSB=n
+CONFIG_PUV3_AC97=n
+CONFIG_PUV3_NAND=n
+CONFIG_PUV3_MMC=n
+CONFIG_PUV3_UART=n
+
+### Device Drivers
+#	Memory Technology Device (MTD) support
+CONFIG_MTD=m
+CONFIG_MTD_UBI=m
+CONFIG_MTD_PARTITIONS=y
+CONFIG_MTD_CHAR=m
+CONFIG_MTD_BLKDEVS=m
+#	RAM/ROM/Flash chip drivers
+CONFIG_MTD_CFI=m
+CONFIG_MTD_JEDECPROBE=m
+CONFIG_MTD_CFI_AMDSTD=m
+#	Mapping drivers for chip access
+CONFIG_MTD_PHYSMAP=m
+
+#	Block devices
+CONFIG_BLK_DEV_LOOP=m
+
+#	SCSI device support
+CONFIG_SCSI=y
+CONFIG_BLK_DEV_SD=y
+CONFIG_BLK_DEV_SR=m
+CONFIG_CHR_DEV_SG=m
+
+#	Serial ATA (prod) and Parallel ATA (experimental) drivers
+CONFIG_ATA=y
+CONFIG_SATA_VIA=y
+
+#	Network device support
+CONFIG_NETDEVICES=y
+CONFIG_NET_ETHERNET=y
+CONFIG_NETDEV_1000=y
+#	Wireless LAN
+CONFIG_WLAN_80211=n
+CONFIG_RT2X00=n
+CONFIG_RT73USB=n
+
+#	Input device support
+CONFIG_INPUT_EVDEV=m
+#	Keyboards
+CONFIG_KEYBOARD_GPIO=m
+
+#	I2C support
+CONFIG_I2C=y
+CONFIG_I2C_PUV3=y
+
+#	Hardware Monitoring support
+#CONFIG_SENSORS_LM75=m
+#	Generic Thermal sysfs driver
+#CONFIG_THERMAL=m
+#CONFIG_THERMAL_HWMON=y
+
+#	Multimedia support
+CONFIG_MEDIA_SUPPORT=n
+CONFIG_VIDEO_DEV=n
+CONFIG_USB_VIDEO_CLASS=n
+
+#	Graphics support
+CONFIG_FB=y
+CONFIG_FB_PUV3_UNIGFX=y
+#	Console display driver support
+CONFIG_VGA_CONSOLE=n
+CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_FONTS=y
+CONFIG_FONT_8x8=y
+CONFIG_FONT_8x16=y
+#	Bootup logo
+CONFIG_LOGO=n
+
+#	Sound card support
+CONFIG_SOUND=m
+#	Advanced Linux Sound Architecture
+CONFIG_SND=m
+CONFIG_SND_MIXER_OSS=m
+CONFIG_SND_PCM_OSS=m
+
+#	USB support
+CONFIG_USB_ARCH_HAS_HCD=n
+CONFIG_USB=n
+CONFIG_USB_DEVICEFS=n
+CONFIG_USB_PRINTER=n
+CONFIG_USB_STORAGE=n
+#	Inventra Highspeed Dual Role Controller
+CONFIG_USB_MUSB_HDRC=n
+
+#	LED Support
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+CONFIG_LEDS_GPIO=y
+#	LED Triggers
+CONFIG_LEDS_TRIGGERS=y
+CONFIG_LEDS_TRIGGER_TIMER=y
+CONFIG_LEDS_TRIGGER_IDE_DISK=y
+CONFIG_LEDS_TRIGGER_HEARTBEAT=y
+
+#	Real Time Clock
+CONFIG_RTC_LIB=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_PUV3=y
+
+### File systems
+CONFIG_EXT2_FS=m
+CONFIG_EXT3_FS=y
+CONFIG_EXT4_FS=y
+CONFIG_FUSE_FS=m
+#	CD-ROM/DVD Filesystems
+CONFIG_ISO9660_FS=m
+CONFIG_JOLIET=y
+CONFIG_UDF_FS=m
+#	DOS/FAT/NT Filesystems
+CONFIG_VFAT_FS=m
+#	Pseudo filesystems
+CONFIG_PROC_FS=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+#	Miscellaneous filesystems
+CONFIG_MISC_FILESYSTEMS=y
+CONFIG_JFFS2_FS=m
+CONFIG_UBIFS_FS=m
+#	Network File Systems
+CONFIG_NETWORK_FILESYSTEMS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+CONFIG_ROOT_NFS=y
+#	Partition Types
+CONFIG_PARTITION_ADVANCED=y
+CONFIG_MSDOS_PARTITION=y
+#	Native language support
+CONFIG_NLS=y
+CONFIG_NLS_CODEPAGE_437=m
+CONFIG_NLS_CODEPAGE_936=m
+CONFIG_NLS_ISO8859_1=m
+CONFIG_NLS_UTF8=m
+
+### Kernel hacking
+CONFIG_FRAME_WARN=8096
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_DEBUG_KERNEL=y
+CONFIG_PROVE_LOCKING=n
+CONFIG_DEBUG_BUGVERBOSE=y
+CONFIG_FRAME_POINTER=y
+CONFIG_DEBUG_LL=y
+
diff -druN linux-2.6.39-libre/arch/unicore32/include/asm/Kbuild linux-3.0-rc7-libre/arch/unicore32/include/asm/Kbuild
--- linux-2.6.39-libre/arch/unicore32/include/asm/Kbuild	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/unicore32/include/asm/Kbuild	2011-07-11 19:51:52.000000000 -0400
@@ -1,2 +1,61 @@
 include include/asm-generic/Kbuild.asm
 
+generic-y += atomic.h
+generic-y += auxvec.h
+generic-y += bitsperlong.h
+generic-y += bug.h
+generic-y += bugs.h
+generic-y += cputime.h
+generic-y += current.h
+generic-y += device.h
+generic-y += div64.h
+generic-y += emergency-restart.h
+generic-y += errno.h
+generic-y += fb.h
+generic-y += fcntl.h
+generic-y += ftrace.h
+generic-y += futex.h
+generic-y += hardirq.h
+generic-y += hw_irq.h
+generic-y += ioctl.h
+generic-y += ioctls.h
+generic-y += ipcbuf.h
+generic-y += irq_regs.h
+generic-y += kdebug.h
+generic-y += kmap_types.h
+generic-y += local.h
+generic-y += mman.h
+generic-y += module.h
+generic-y += msgbuf.h
+generic-y += param.h
+generic-y += parport.h
+generic-y += percpu.h
+generic-y += poll.h
+generic-y += posix_types.h
+generic-y += resource.h
+generic-y += scatterlist.h
+generic-y += sections.h
+generic-y += segment.h
+generic-y += sembuf.h
+generic-y += serial.h
+generic-y += setup.h
+generic-y += shmbuf.h
+generic-y += shmparam.h
+generic-y += siginfo.h
+generic-y += signal.h
+generic-y += sizes.h
+generic-y += socket.h
+generic-y += sockios.h
+generic-y += stat.h
+generic-y += statfs.h
+generic-y += swab.h
+generic-y += syscalls.h
+generic-y += termbits.h
+generic-y += termios.h
+generic-y += topology.h
+generic-y += types.h
+generic-y += ucontext.h
+generic-y += unaligned.h
+generic-y += user.h
+generic-y += vga.h
+generic-y += xor.h
diff -druN linux-2.6.39-libre/arch/unicore32/include/asm/suspend.h linux-3.0-rc7-libre/arch/unicore32/include/asm/suspend.h
--- linux-2.6.39-libre/arch/unicore32/include/asm/suspend.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/unicore32/include/asm/suspend.h	2011-07-11 19:51:52.000000000 -0400
@@ -14,7 +14,6 @@
 #define __UNICORE_SUSPEND_H__
 
 #ifndef __ASSEMBLY__
-static inline int arch_prepare_suspend(void) { return 0; }
 
 #include <asm/ptrace.h>
 
diff -druN linux-2.6.39-libre/arch/unicore32/Kconfig linux-3.0-rc7-libre/arch/unicore32/Kconfig
--- linux-2.6.39-libre/arch/unicore32/Kconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/unicore32/Kconfig	2011-07-11 19:51:52.000000000 -0400
@@ -231,10 +231,6 @@
 	help
 	  Enable support for NB0916 PWM controllers
 
-config PUV3_RTC
-	tristate "PKUnity v3 RTC Support"
-	depends on !ARCH_FPGA
-
 if PUV3_NB0916
 
 menu "PKUnity NetBook-0916 Features"
diff -druN linux-2.6.39-libre/arch/unicore32/Kconfig.debug linux-3.0-rc7-libre/arch/unicore32/Kconfig.debug
--- linux-2.6.39-libre/arch/unicore32/Kconfig.debug	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/unicore32/Kconfig.debug	2011-07-11 19:51:52.000000000 -0400
@@ -27,13 +27,6 @@
 	  with klogd/syslogd or the X server. You should normally N here,
 	  unless you want to debug such a crash.
 
-config DEBUG_STACK_USAGE
-	bool "Enable stack utilization instrumentation"
-	depends on DEBUG_KERNEL
-	help
-	  Enables the display of the minimum amount of free stack which each
-	  task has ever had available in the sysrq-T output.
-
 # These options are only for real kernel hackers who want to get their hands dirty.
 config DEBUG_LL
 	bool "Kernel low-level debugging functions"
diff -druN linux-2.6.39-libre/arch/unicore32/kernel/irq.c linux-3.0-rc7-libre/arch/unicore32/kernel/irq.c
--- linux-2.6.39-libre/arch/unicore32/kernel/irq.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/unicore32/kernel/irq.c	2011-07-11 19:51:52.000000000 -0400
@@ -23,7 +23,7 @@
 #include <linux/list.h>
 #include <linux/kallsyms.h>
 #include <linux/proc_fs.h>
-#include <linux/sysdev.h>
+#include <linux/syscore_ops.h>
 #include <linux/gpio.h>
 
 #include <asm/system.h>
@@ -237,7 +237,7 @@
 	unsigned int	iccr;
 } puv3_irq_state;
 
-static int puv3_irq_suspend(struct sys_device *dev, pm_message_t state)
+static int puv3_irq_suspend(void)
 {
 	struct puv3_irq_state *st = &puv3_irq_state;
 
@@ -265,7 +265,7 @@
 	return 0;
 }
 
-static int puv3_irq_resume(struct sys_device *dev)
+static void puv3_irq_resume(void)
 {
 	struct puv3_irq_state *st = &puv3_irq_state;
 
@@ -278,27 +278,20 @@
 
 		writel(st->icmr, INTC_ICMR);
 	}
-	return 0;
 }
 
-static struct sysdev_class puv3_irq_sysclass = {
-	.name		= "pkunity-irq",
+static struct syscore_ops puv3_irq_syscore_ops = {
 	.suspend	= puv3_irq_suspend,
 	.resume		= puv3_irq_resume,
 };
 
-static struct sys_device puv3_irq_device = {
-	.id		= 0,
-	.cls		= &puv3_irq_sysclass,
-};
-
-static int __init puv3_irq_init_devicefs(void)
+static int __init puv3_irq_init_syscore(void)
 {
-	sysdev_class_register(&puv3_irq_sysclass);
-	return sysdev_register(&puv3_irq_device);
+	register_syscore_ops(&puv3_irq_syscore_ops);
+	return 0;
 }
 
-device_initcall(puv3_irq_init_devicefs);
+device_initcall(puv3_irq_init_syscore);
 
 void __init init_IRQ(void)
 {
diff -druN linux-2.6.39-libre/arch/unicore32/kernel/Makefile linux-3.0-rc7-libre/arch/unicore32/kernel/Makefile
--- linux-2.6.39-libre/arch/unicore32/kernel/Makefile	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/unicore32/kernel/Makefile	2011-07-11 19:51:52.000000000 -0400
@@ -16,7 +16,6 @@
 obj-$(CONFIG_ARCH_PUV3)		+= clock.o irq.o time.o
 
 obj-$(CONFIG_PUV3_GPIO)		+= gpio.o
-obj-$(CONFIG_PUV3_RTC)		+= rtc.o
 obj-$(CONFIG_PUV3_PWM)		+= pwm.o
 obj-$(CONFIG_PUV3_PM)		+= pm.o sleep.o
 obj-$(CONFIG_HIBERNATION)	+= hibernate.o hibernate_asm.o
diff -druN linux-2.6.39-libre/arch/unicore32/kernel/rtc.c linux-3.0-rc7-libre/arch/unicore32/kernel/rtc.c
--- linux-2.6.39-libre/arch/unicore32/kernel/rtc.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/unicore32/kernel/rtc.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,371 +0,0 @@
-/*
- * linux/arch/unicore32/kernel/rtc.c
- *
- * Code specific to PKUnity SoC and UniCore ISA
- *
- *	Maintained by GUAN Xue-tao <gxt@mprc.pku.edu.cn>
- *	Copyright (C) 2001-2010 Guan Xuetao
- *
- * This program is free software; you can redistribute it 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/fs.h>
-#include <linux/string.h>
-#include <linux/init.h>
-#include <linux/platform_device.h>
-#include <linux/interrupt.h>
-#include <linux/rtc.h>
-#include <linux/bcd.h>
-#include <linux/clk.h>
-#include <linux/log2.h>
-#include <linux/slab.h>
-#include <linux/uaccess.h>
-#include <linux/io.h>
-
-#include <asm/irq.h>
-#include <mach/hardware.h>
-
-static struct resource *puv3_rtc_mem;
-
-static int puv3_rtc_alarmno = IRQ_RTCAlarm;
-static int puv3_rtc_tickno  = IRQ_RTC;
-
-static DEFINE_SPINLOCK(puv3_rtc_pie_lock);
-
-/* IRQ Handlers */
-
-static irqreturn_t puv3_rtc_alarmirq(int irq, void *id)
-{
-	struct rtc_device *rdev = id;
-
-	writel(readl(RTC_RTSR) | RTC_RTSR_AL, RTC_RTSR);
-	rtc_update_irq(rdev, 1, RTC_AF | RTC_IRQF);
-	return IRQ_HANDLED;
-}
-
-static irqreturn_t puv3_rtc_tickirq(int irq, void *id)
-{
-	struct rtc_device *rdev = id;
-
-	writel(readl(RTC_RTSR) | RTC_RTSR_HZ, RTC_RTSR);
-	rtc_update_irq(rdev, 1, RTC_PF | RTC_IRQF);
-	return IRQ_HANDLED;
-}
-
-/* Update control registers */
-static void puv3_rtc_setaie(int to)
-{
-	unsigned int tmp;
-
-	pr_debug("%s: aie=%d\n", __func__, to);
-
-	tmp = readl(RTC_RTSR) & ~RTC_RTSR_ALE;
-
-	if (to)
-		tmp |= RTC_RTSR_ALE;
-
-	writel(tmp, RTC_RTSR);
-}
-
-static int puv3_rtc_setpie(struct device *dev, int enabled)
-{
-	unsigned int tmp;
-
-	pr_debug("%s: pie=%d\n", __func__, enabled);
-
-	spin_lock_irq(&puv3_rtc_pie_lock);
-	tmp = readl(RTC_RTSR) & ~RTC_RTSR_HZE;
-
-	if (enabled)
-		tmp |= RTC_RTSR_HZE;
-
-	writel(tmp, RTC_RTSR);
-	spin_unlock_irq(&puv3_rtc_pie_lock);
-
-	return 0;
-}
-
-/* Time read/write */
-
-static int puv3_rtc_gettime(struct device *dev, struct rtc_time *rtc_tm)
-{
-	rtc_time_to_tm(readl(RTC_RCNR), rtc_tm);
-
-	pr_debug("read time %02x.%02x.%02x %02x/%02x/%02x\n",
-		 rtc_tm->tm_year, rtc_tm->tm_mon, rtc_tm->tm_mday,
-		 rtc_tm->tm_hour, rtc_tm->tm_min, rtc_tm->tm_sec);
-
-	return 0;
-}
-
-static int puv3_rtc_settime(struct device *dev, struct rtc_time *tm)
-{
-	unsigned long rtc_count = 0;
-
-	pr_debug("set time %02d.%02d.%02d %02d/%02d/%02d\n",
-		 tm->tm_year, tm->tm_mon, tm->tm_mday,
-		 tm->tm_hour, tm->tm_min, tm->tm_sec);
-
-	rtc_tm_to_time(tm, &rtc_count);
-	writel(rtc_count, RTC_RCNR);
-
-	return 0;
-}
-
-static int puv3_rtc_getalarm(struct device *dev, struct rtc_wkalrm *alrm)
-{
-	struct rtc_time *alm_tm = &alrm->time;
-
-	rtc_time_to_tm(readl(RTC_RTAR), alm_tm);
-
-	alrm->enabled = readl(RTC_RTSR) & RTC_RTSR_ALE;
-
-	pr_debug("read alarm %02x %02x.%02x.%02x %02x/%02x/%02x\n",
-		 alrm->enabled,
-		 alm_tm->tm_year, alm_tm->tm_mon, alm_tm->tm_mday,
-		 alm_tm->tm_hour, alm_tm->tm_min, alm_tm->tm_sec);
-
-	return 0;
-}
-
-static int puv3_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm)
-{
-	struct rtc_time *tm = &alrm->time;
-	unsigned long rtcalarm_count = 0;
-
-	pr_debug("puv3_rtc_setalarm: %d, %02x/%02x/%02x %02x.%02x.%02x\n",
-		 alrm->enabled,
-		 tm->tm_mday & 0xff, tm->tm_mon & 0xff, tm->tm_year & 0xff,
-		 tm->tm_hour & 0xff, tm->tm_min & 0xff, tm->tm_sec);
-
-	rtc_tm_to_time(tm, &rtcalarm_count);
-	writel(rtcalarm_count, RTC_RTAR);
-
-	puv3_rtc_setaie(alrm->enabled);
-
-	if (alrm->enabled)
-		enable_irq_wake(puv3_rtc_alarmno);
-	else
-		disable_irq_wake(puv3_rtc_alarmno);
-
-	return 0;
-}
-
-static int puv3_rtc_proc(struct device *dev, struct seq_file *seq)
-{
-	seq_printf(seq, "periodic_IRQ\t: %s\n",
-		     (readl(RTC_RTSR) & RTC_RTSR_HZE) ? "yes" : "no");
-	return 0;
-}
-
-static int puv3_rtc_open(struct device *dev)
-{
-	struct platform_device *pdev = to_platform_device(dev);
-	struct rtc_device *rtc_dev = platform_get_drvdata(pdev);
-	int ret;
-
-	ret = request_irq(puv3_rtc_alarmno, puv3_rtc_alarmirq,
-			  IRQF_DISABLED,  "pkunity-rtc alarm", rtc_dev);
-
-	if (ret) {
-		dev_err(dev, "IRQ%d error %d\n", puv3_rtc_alarmno, ret);
-		return ret;
-	}
-
-	ret = request_irq(puv3_rtc_tickno, puv3_rtc_tickirq,
-			  IRQF_DISABLED,  "pkunity-rtc tick", rtc_dev);
-
-	if (ret) {
-		dev_err(dev, "IRQ%d error %d\n", puv3_rtc_tickno, ret);
-		goto tick_err;
-	}
-
-	return ret;
-
- tick_err:
-	free_irq(puv3_rtc_alarmno, rtc_dev);
-	return ret;
-}
-
-static void puv3_rtc_release(struct device *dev)
-{
-	struct platform_device *pdev = to_platform_device(dev);
-	struct rtc_device *rtc_dev = platform_get_drvdata(pdev);
-
-	/* do not clear AIE here, it may be needed for wake */
-
-	puv3_rtc_setpie(dev, 0);
-	free_irq(puv3_rtc_alarmno, rtc_dev);
-	free_irq(puv3_rtc_tickno, rtc_dev);
-}
-
-static const struct rtc_class_ops puv3_rtcops = {
-	.open		= puv3_rtc_open,
-	.release	= puv3_rtc_release,
-	.read_time	= puv3_rtc_gettime,
-	.set_time	= puv3_rtc_settime,
-	.read_alarm	= puv3_rtc_getalarm,
-	.set_alarm	= puv3_rtc_setalarm,
-	.proc	        = puv3_rtc_proc,
-};
-
-static void puv3_rtc_enable(struct platform_device *pdev, int en)
-{
-	if (!en) {
-		writel(readl(RTC_RTSR) & ~RTC_RTSR_HZE, RTC_RTSR);
-	} else {
-		/* re-enable the device, and check it is ok */
-
-		if ((readl(RTC_RTSR) & RTC_RTSR_HZE) == 0) {
-			dev_info(&pdev->dev, "rtc disabled, re-enabling\n");
-			writel(readl(RTC_RTSR) | RTC_RTSR_HZE, RTC_RTSR);
-		}
-	}
-}
-
-static int puv3_rtc_remove(struct platform_device *dev)
-{
-	struct rtc_device *rtc = platform_get_drvdata(dev);
-
-	platform_set_drvdata(dev, NULL);
-	rtc_device_unregister(rtc);
-
-	puv3_rtc_setpie(&dev->dev, 0);
-	puv3_rtc_setaie(0);
-
-	release_resource(puv3_rtc_mem);
-	kfree(puv3_rtc_mem);
-
-	return 0;
-}
-
-static int puv3_rtc_probe(struct platform_device *pdev)
-{
-	struct rtc_device *rtc;
-	struct resource *res;
-	int ret;
-
-	pr_debug("%s: probe=%p\n", __func__, pdev);
-
-	/* find the IRQs */
-
-	puv3_rtc_tickno = platform_get_irq(pdev, 1);
-	if (puv3_rtc_tickno < 0) {
-		dev_err(&pdev->dev, "no irq for rtc tick\n");
-		return -ENOENT;
-	}
-
-	puv3_rtc_alarmno = platform_get_irq(pdev, 0);
-	if (puv3_rtc_alarmno < 0) {
-		dev_err(&pdev->dev, "no irq for alarm\n");
-		return -ENOENT;
-	}
-
-	pr_debug("PKUnity_rtc: tick irq %d, alarm irq %d\n",
-		 puv3_rtc_tickno, puv3_rtc_alarmno);
-
-	/* get the memory region */
-
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	if (res == NULL) {
-		dev_err(&pdev->dev, "failed to get memory region resource\n");
-		return -ENOENT;
-	}
-
-	puv3_rtc_mem = request_mem_region(res->start,
-					 res->end-res->start+1,
-					 pdev->name);
-
-	if (puv3_rtc_mem == NULL) {
-		dev_err(&pdev->dev, "failed to reserve memory region\n");
-		ret = -ENOENT;
-		goto err_nores;
-	}
-
-	puv3_rtc_enable(pdev, 1);
-
-	/* register RTC and exit */
-
-	rtc = rtc_device_register("pkunity", &pdev->dev, &puv3_rtcops,
-				  THIS_MODULE);
-
-	if (IS_ERR(rtc)) {
-		dev_err(&pdev->dev, "cannot attach rtc\n");
-		ret = PTR_ERR(rtc);
-		goto err_nortc;
-	}
-
-	/* platform setup code should have handled this; sigh */
-	if (!device_can_wakeup(&pdev->dev))
-		device_init_wakeup(&pdev->dev, 1);
-
-	platform_set_drvdata(pdev, rtc);
-	return 0;
-
- err_nortc:
-	puv3_rtc_enable(pdev, 0);
-	release_resource(puv3_rtc_mem);
-
- err_nores:
-	return ret;
-}
-
-#ifdef CONFIG_PM
-
-/* RTC Power management control */
-
-static int ticnt_save;
-
-static int puv3_rtc_suspend(struct platform_device *pdev, pm_message_t state)
-{
-	/* save RTAR for anyone using periodic interrupts */
-	ticnt_save = readl(RTC_RTAR);
-	puv3_rtc_enable(pdev, 0);
-	return 0;
-}
-
-static int puv3_rtc_resume(struct platform_device *pdev)
-{
-	puv3_rtc_enable(pdev, 1);
-	writel(ticnt_save, RTC_RTAR);
-	return 0;
-}
-#else
-#define puv3_rtc_suspend NULL
-#define puv3_rtc_resume  NULL
-#endif
-
-static struct platform_driver puv3_rtcdrv = {
-	.probe		= puv3_rtc_probe,
-	.remove		= __devexit_p(puv3_rtc_remove),
-	.suspend	= puv3_rtc_suspend,
-	.resume		= puv3_rtc_resume,
-	.driver		= {
-		.name	= "PKUnity-v3-RTC",
-		.owner	= THIS_MODULE,
-	}
-};
-
-static char __initdata banner[] = "PKUnity-v3 RTC, (c) 2009 PKUnity Co.\n";
-
-static int __init puv3_rtc_init(void)
-{
-	printk(banner);
-	return platform_driver_register(&puv3_rtcdrv);
-}
-
-static void __exit puv3_rtc_exit(void)
-{
-	platform_driver_unregister(&puv3_rtcdrv);
-}
-
-module_init(puv3_rtc_init);
-module_exit(puv3_rtc_exit);
-
-MODULE_DESCRIPTION("RTC Driver for the PKUnity v3 chip");
-MODULE_AUTHOR("Hu Dongliang");
-MODULE_LICENSE("GPL v2");
-
diff -druN linux-2.6.39-libre/arch/unicore32/kernel/traps.c linux-3.0-rc7-libre/arch/unicore32/kernel/traps.c
--- linux-2.6.39-libre/arch/unicore32/kernel/traps.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/unicore32/kernel/traps.c	2011-07-11 19:51:52.000000000 -0400
@@ -192,7 +192,6 @@
 
 	printk(KERN_EMERG "Internal error: %s: %x [#%d]\n",
 	       str, err, ++die_counter);
-	sysfs_printk_last_file();
 
 	/* trap and error numbers are mostly meaningless on UniCore */
 	ret = notify_die(DIE_OOPS, str, regs, err, tsk->thread.trap_no, \
diff -druN linux-2.6.39-libre/arch/unicore32/kernel/vmlinux.lds.S linux-3.0-rc7-libre/arch/unicore32/kernel/vmlinux.lds.S
--- linux-2.6.39-libre/arch/unicore32/kernel/vmlinux.lds.S	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/unicore32/kernel/vmlinux.lds.S	2011-07-11 19:51:52.000000000 -0400
@@ -30,7 +30,7 @@
 	HEAD_TEXT_SECTION
 	INIT_TEXT_SECTION(PAGE_SIZE)
 	INIT_DATA_SECTION(16)
-	PERCPU(L1_CACHE_BYTES, PAGE_SIZE)
+	PERCPU_SECTION(L1_CACHE_BYTES)
 	__init_end = .;
 
 	_stext = .;
diff -druN linux-2.6.39-libre/arch/unicore32/Makefile linux-3.0-rc7-libre/arch/unicore32/Makefile
--- linux-2.6.39-libre/arch/unicore32/Makefile	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/unicore32/Makefile	2011-07-11 19:51:52.000000000 -0400
@@ -40,42 +40,10 @@
 
 libs-y			+= arch/unicore32/lib/
 
-ASM_GENERATED_DIR	:= $(srctree)/arch/unicore32/include/generated
-LINUXINCLUDE		+= -I$(ASM_GENERATED_DIR)
-
-ASM_GENERIC_HEADERS	:= atomic.h auxvec.h
-ASM_GENERIC_HEADERS	+= bitsperlong.h bug.h bugs.h
-ASM_GENERIC_HEADERS	+= cputime.h current.h
-ASM_GENERIC_HEADERS	+= device.h div64.h
-ASM_GENERIC_HEADERS	+= emergency-restart.h errno.h
-ASM_GENERIC_HEADERS	+= fb.h fcntl.h ftrace.h futex.h
-ASM_GENERIC_HEADERS	+= hardirq.h hw_irq.h
-ASM_GENERIC_HEADERS	+= ioctl.h ioctls.h ipcbuf.h irq_regs.h
-ASM_GENERIC_HEADERS	+= kdebug.h kmap_types.h
-ASM_GENERIC_HEADERS	+= local.h
-ASM_GENERIC_HEADERS	+= mman.h module.h msgbuf.h
-ASM_GENERIC_HEADERS	+= param.h parport.h percpu.h poll.h posix_types.h
-ASM_GENERIC_HEADERS	+= resource.h
-ASM_GENERIC_HEADERS	+= scatterlist.h sections.h segment.h sembuf.h serial.h
-ASM_GENERIC_HEADERS	+= setup.h shmbuf.h shmparam.h
-ASM_GENERIC_HEADERS	+= siginfo.h signal.h sizes.h
-ASM_GENERIC_HEADERS	+= socket.h sockios.h stat.h statfs.h swab.h syscalls.h
-ASM_GENERIC_HEADERS	+= termbits.h termios.h topology.h types.h
-ASM_GENERIC_HEADERS	+= ucontext.h unaligned.h user.h
-ASM_GENERIC_HEADERS	+= vga.h
-ASM_GENERIC_HEADERS	+= xor.h
-
-archprepare:
-ifneq ($(ASM_GENERATED_DIR), $(wildcard $(ASM_GENERATED_DIR)))
-	$(Q)mkdir -p $(ASM_GENERATED_DIR)/asm
-	$(Q)$(foreach a, $(ASM_GENERIC_HEADERS),	\
-		echo '#include <asm-generic/$a>'	\
-			> $(ASM_GENERATED_DIR)/asm/$a; )
-endif
-
 boot			:= arch/unicore32/boot
 
-# Default target when executing plain make
+# Default defconfig and target when executing plain make
+KBUILD_DEFCONFIG	:= $(ARCH)_defconfig
 KBUILD_IMAGE		:= zImage
 
 all:	$(KBUILD_IMAGE)
@@ -83,8 +51,6 @@
 zImage Image uImage: vmlinux
 	$(Q)$(MAKE) $(build)=$(boot) $(boot)/$@
 
-MRPROPER_DIRS		+= $(ASM_GENERATED_DIR)
-
 archclean:
 	$(Q)$(MAKE) $(clean)=$(boot)
 
diff -druN linux-2.6.39-libre/arch/unicore32/mm/init.c linux-3.0-rc7-libre/arch/unicore32/mm/init.c
--- linux-2.6.39-libre/arch/unicore32/mm/init.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/unicore32/mm/init.c	2011-07-11 19:51:52.000000000 -0400
@@ -62,7 +62,7 @@
 	struct meminfo *mi = &meminfo;
 
 	printk(KERN_DEFAULT "Mem-info:\n");
-	show_free_areas();
+	show_free_areas(filter);
 
 	for_each_bank(i, mi) {
 		struct membank *bank = &mi->bank[i];
diff -druN linux-2.6.39-libre/arch/unicore32/mm/mmu.c linux-3.0-rc7-libre/arch/unicore32/mm/mmu.c
--- linux-2.6.39-libre/arch/unicore32/mm/mmu.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/unicore32/mm/mmu.c	2011-07-11 19:51:52.000000000 -0400
@@ -30,8 +30,6 @@
 
 #include "mm.h"
 
-DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
-
 /*
  * empty_zero_page is a special page that is used for
  * zero-initialized data and COW.
diff -druN linux-2.6.39-libre/arch/x86/configs/i386_defconfig linux-3.0-rc7-libre/arch/x86/configs/i386_defconfig
--- linux-2.6.39-libre/arch/x86/configs/i386_defconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/configs/i386_defconfig	2011-07-11 19:51:52.000000000 -0400
@@ -10,7 +10,6 @@
 CONFIG_AUDIT=y
 CONFIG_LOG_BUF_SHIFT=18
 CONFIG_CGROUPS=y
-CONFIG_CGROUP_NS=y
 CONFIG_CGROUP_FREEZER=y
 CONFIG_CPUSETS=y
 CONFIG_CGROUP_CPUACCT=y
diff -druN linux-2.6.39-libre/arch/x86/configs/x86_64_defconfig linux-3.0-rc7-libre/arch/x86/configs/x86_64_defconfig
--- linux-2.6.39-libre/arch/x86/configs/x86_64_defconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/configs/x86_64_defconfig	2011-07-11 19:51:52.000000000 -0400
@@ -11,7 +11,6 @@
 CONFIG_AUDIT=y
 CONFIG_LOG_BUF_SHIFT=18
 CONFIG_CGROUPS=y
-CONFIG_CGROUP_NS=y
 CONFIG_CGROUP_FREEZER=y
 CONFIG_CPUSETS=y
 CONFIG_CGROUP_CPUACCT=y
diff -druN linux-2.6.39-libre/arch/x86/crypto/aesni-intel_glue.c linux-3.0-rc7-libre/arch/x86/crypto/aesni-intel_glue.c
--- linux-2.6.39-libre/arch/x86/crypto/aesni-intel_glue.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/crypto/aesni-intel_glue.c	2011-07-11 19:51:52.000000000 -0400
@@ -94,6 +94,10 @@
 			      const u8 *in, unsigned int len, u8 *iv);
 asmlinkage void aesni_cbc_dec(struct crypto_aes_ctx *ctx, u8 *out,
 			      const u8 *in, unsigned int len, u8 *iv);
+
+int crypto_fpu_init(void);
+void crypto_fpu_exit(void);
+
 #ifdef CONFIG_X86_64
 asmlinkage void aesni_ctr_enc(struct crypto_aes_ctx *ctx, u8 *out,
 			      const u8 *in, unsigned int len, u8 *iv);
@@ -1257,6 +1261,8 @@
 		return -ENODEV;
 	}
 
+	if ((err = crypto_fpu_init()))
+		goto fpu_err;
 	if ((err = crypto_register_alg(&aesni_alg)))
 		goto aes_err;
 	if ((err = crypto_register_alg(&__aesni_alg)))
@@ -1334,6 +1340,7 @@
 __aes_err:
 	crypto_unregister_alg(&aesni_alg);
 aes_err:
+fpu_err:
 	return err;
 }
 
@@ -1363,6 +1370,8 @@
 	crypto_unregister_alg(&blk_ecb_alg);
 	crypto_unregister_alg(&__aesni_alg);
 	crypto_unregister_alg(&aesni_alg);
+
+	crypto_fpu_exit();
 }
 
 module_init(aesni_init);
diff -druN linux-2.6.39-libre/arch/x86/crypto/fpu.c linux-3.0-rc7-libre/arch/x86/crypto/fpu.c
--- linux-2.6.39-libre/arch/x86/crypto/fpu.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/crypto/fpu.c	2011-07-11 19:51:52.000000000 -0400
@@ -150,18 +150,12 @@
 	.module = THIS_MODULE,
 };
 
-static int __init crypto_fpu_module_init(void)
+int __init crypto_fpu_init(void)
 {
 	return crypto_register_template(&crypto_fpu_tmpl);
 }
 
-static void __exit crypto_fpu_module_exit(void)
+void __exit crypto_fpu_exit(void)
 {
 	crypto_unregister_template(&crypto_fpu_tmpl);
 }
-
-module_init(crypto_fpu_module_init);
-module_exit(crypto_fpu_module_exit);
-
-MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("FPU block cipher wrapper");
diff -druN linux-2.6.39-libre/arch/x86/crypto/Makefile linux-3.0-rc7-libre/arch/x86/crypto/Makefile
--- linux-2.6.39-libre/arch/x86/crypto/Makefile	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/crypto/Makefile	2011-07-11 19:51:52.000000000 -0400
@@ -2,8 +2,6 @@
 # Arch-specific CryptoAPI modules.
 #
 
-obj-$(CONFIG_CRYPTO_FPU) += fpu.o
-
 obj-$(CONFIG_CRYPTO_AES_586) += aes-i586.o
 obj-$(CONFIG_CRYPTO_TWOFISH_586) += twofish-i586.o
 obj-$(CONFIG_CRYPTO_SALSA20_586) += salsa20-i586.o
@@ -24,6 +22,6 @@
 twofish-x86_64-y := twofish-x86_64-asm_64.o twofish_glue.o
 salsa20-x86_64-y := salsa20-x86_64-asm_64.o salsa20_glue.o
 
-aesni-intel-y := aesni-intel_asm.o aesni-intel_glue.o
+aesni-intel-y := aesni-intel_asm.o aesni-intel_glue.o fpu.o
 
 ghash-clmulni-intel-y := ghash-clmulni-intel_asm.o ghash-clmulni-intel_glue.o
diff -druN linux-2.6.39-libre/arch/x86/ia32/ia32entry.S linux-3.0-rc7-libre/arch/x86/ia32/ia32entry.S
--- linux-2.6.39-libre/arch/x86/ia32/ia32entry.S	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/ia32/ia32entry.S	2011-07-11 19:51:52.000000000 -0400
@@ -848,4 +848,6 @@
 	.quad compat_sys_open_by_handle_at
 	.quad compat_sys_clock_adjtime
 	.quad sys_syncfs
+	.quad compat_sys_sendmmsg	/* 345 */
+	.quad sys_setns
 ia32_syscall_end:
diff -druN linux-2.6.39-libre/arch/x86/include/asm/acpi.h linux-3.0-rc7-libre/arch/x86/include/asm/acpi.h
--- linux-2.6.39-libre/arch/x86/include/asm/acpi.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/include/asm/acpi.h	2011-07-11 19:51:52.000000000 -0400
@@ -139,7 +139,7 @@
 	    boot_cpu_data.x86_model <= 0x05 &&
 	    boot_cpu_data.x86_mask < 0x0A)
 		return 1;
-	else if (c1e_detected)
+	else if (amd_e400_c1e_detected)
 		return 1;
 	else
 		return max_cstate;
@@ -183,8 +183,6 @@
 
 #define ARCH_HAS_POWER_INIT	1
 
-struct bootnode;
-
 #ifdef CONFIG_ACPI_NUMA
 extern int acpi_numa;
 extern int x86_acpi_numa_init(void);
diff -druN linux-2.6.39-libre/arch/x86/include/asm/alternative-asm.h linux-3.0-rc7-libre/arch/x86/include/asm/alternative-asm.h
--- linux-2.6.39-libre/arch/x86/include/asm/alternative-asm.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/include/asm/alternative-asm.h	2011-07-11 19:51:52.000000000 -0400
@@ -15,4 +15,13 @@
 	.endm
 #endif
 
+.macro altinstruction_entry orig alt feature orig_len alt_len
+	.align 8
+	.quad \orig
+	.quad \alt
+	.word \feature
+	.byte \orig_len
+	.byte \alt_len
+.endm
+
 #endif  /*  __ASSEMBLY__  */
diff -druN linux-2.6.39-libre/arch/x86/include/asm/alternative.h linux-3.0-rc7-libre/arch/x86/include/asm/alternative.h
--- linux-2.6.39-libre/arch/x86/include/asm/alternative.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/include/asm/alternative.h	2011-07-11 19:51:52.000000000 -0400
@@ -4,7 +4,6 @@
 #include <linux/types.h>
 #include <linux/stddef.h>
 #include <linux/stringify.h>
-#include <linux/jump_label.h>
 #include <asm/asm.h>
 
 /*
@@ -191,12 +190,4 @@
 extern void *text_poke_smp(void *addr, const void *opcode, size_t len);
 extern void text_poke_smp_batch(struct text_poke_param *params, int n);
 
-#if defined(CONFIG_DYNAMIC_FTRACE) || defined(HAVE_JUMP_LABEL)
-#define IDEAL_NOP_SIZE_5 5
-extern unsigned char ideal_nop5[IDEAL_NOP_SIZE_5];
-extern void arch_init_ideal_nop5(void);
-#else
-static inline void arch_init_ideal_nop5(void) {}
-#endif
-
 #endif /* _ASM_X86_ALTERNATIVE_H */
diff -druN linux-2.6.39-libre/arch/x86/include/asm/amd_iommu_proto.h linux-3.0-rc7-libre/arch/x86/include/asm/amd_iommu_proto.h
--- linux-2.6.39-libre/arch/x86/include/asm/amd_iommu_proto.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/include/asm/amd_iommu_proto.h	2011-07-11 19:51:52.000000000 -0400
@@ -19,13 +19,12 @@
 #ifndef _ASM_X86_AMD_IOMMU_PROTO_H
 #define _ASM_X86_AMD_IOMMU_PROTO_H
 
-struct amd_iommu;
+#include <asm/amd_iommu_types.h>
 
 extern int amd_iommu_init_dma_ops(void);
 extern int amd_iommu_init_passthrough(void);
+extern irqreturn_t amd_iommu_int_thread(int irq, void *data);
 extern irqreturn_t amd_iommu_int_handler(int irq, void *data);
-extern void amd_iommu_flush_all_domains(void);
-extern void amd_iommu_flush_all_devices(void);
 extern void amd_iommu_apply_erratum_63(u16 devid);
 extern void amd_iommu_reset_cmd_buffer(struct amd_iommu *iommu);
 extern int amd_iommu_init_devices(void);
@@ -44,4 +43,12 @@
 	       (pdev->device == PCI_DEVICE_ID_RD890_IOMMU);
 }
 
+static inline bool iommu_feature(struct amd_iommu *iommu, u64 f)
+{
+	if (!(iommu->cap & (1 << IOMMU_CAP_EFR)))
+		return false;
+
+	return !!(iommu->features & f);
+}
+
 #endif /* _ASM_X86_AMD_IOMMU_PROTO_H  */
diff -druN linux-2.6.39-libre/arch/x86/include/asm/amd_iommu_types.h linux-3.0-rc7-libre/arch/x86/include/asm/amd_iommu_types.h
--- linux-2.6.39-libre/arch/x86/include/asm/amd_iommu_types.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/include/asm/amd_iommu_types.h	2011-07-11 19:51:52.000000000 -0400
@@ -68,12 +68,25 @@
 #define MMIO_CONTROL_OFFSET     0x0018
 #define MMIO_EXCL_BASE_OFFSET   0x0020
 #define MMIO_EXCL_LIMIT_OFFSET  0x0028
+#define MMIO_EXT_FEATURES	0x0030
 #define MMIO_CMD_HEAD_OFFSET	0x2000
 #define MMIO_CMD_TAIL_OFFSET	0x2008
 #define MMIO_EVT_HEAD_OFFSET	0x2010
 #define MMIO_EVT_TAIL_OFFSET	0x2018
 #define MMIO_STATUS_OFFSET	0x2020
 
+
+/* Extended Feature Bits */
+#define FEATURE_PREFETCH	(1ULL<<0)
+#define FEATURE_PPR		(1ULL<<1)
+#define FEATURE_X2APIC		(1ULL<<2)
+#define FEATURE_NX		(1ULL<<3)
+#define FEATURE_GT		(1ULL<<4)
+#define FEATURE_IA		(1ULL<<6)
+#define FEATURE_GA		(1ULL<<7)
+#define FEATURE_HE		(1ULL<<8)
+#define FEATURE_PC		(1ULL<<9)
+
 /* MMIO status bits */
 #define MMIO_STATUS_COM_WAIT_INT_MASK	0x04
 
@@ -113,7 +126,9 @@
 /* command specific defines */
 #define CMD_COMPL_WAIT          0x01
 #define CMD_INV_DEV_ENTRY       0x02
-#define CMD_INV_IOMMU_PAGES     0x03
+#define CMD_INV_IOMMU_PAGES	0x03
+#define CMD_INV_IOTLB_PAGES	0x04
+#define CMD_INV_ALL		0x08
 
 #define CMD_COMPL_WAIT_STORE_MASK	0x01
 #define CMD_COMPL_WAIT_INT_MASK		0x02
@@ -215,6 +230,8 @@
 #define IOMMU_PTE_IR (1ULL << 61)
 #define IOMMU_PTE_IW (1ULL << 62)
 
+#define DTE_FLAG_IOTLB	0x01
+
 #define IOMMU_PAGE_MASK (((1ULL << 52) - 1) & ~0xfffULL)
 #define IOMMU_PTE_PRESENT(pte) ((pte) & IOMMU_PTE_P)
 #define IOMMU_PTE_PAGE(pte) (phys_to_virt((pte) & IOMMU_PAGE_MASK))
@@ -227,6 +244,7 @@
 /* IOMMU capabilities */
 #define IOMMU_CAP_IOTLB   24
 #define IOMMU_CAP_NPCACHE 26
+#define IOMMU_CAP_EFR     27
 
 #define MAX_DOMAIN_ID 65536
 
@@ -249,6 +267,8 @@
 
 /* global flag if IOMMUs cache non-present entries */
 extern bool amd_iommu_np_cache;
+/* Only true if all IOMMUs support device IOTLBs */
+extern bool amd_iommu_iotlb_sup;
 
 /*
  * Make iterating over all IOMMUs easier
@@ -371,6 +391,9 @@
 	/* flags read from acpi table */
 	u8 acpi_flags;
 
+	/* Extended features */
+	u64 features;
+
 	/*
 	 * Capability pointer. There could be more than one IOMMU per PCI
 	 * device function if there are more than one AMD IOMMU capability
@@ -409,9 +432,6 @@
 	/* if one, we need to send a completion wait command */
 	bool need_sync;
 
-	/* becomes true if a command buffer reset is running */
-	bool reset_in_progress;
-
 	/* default dma_ops domain for that IOMMU */
 	struct dma_ops_domain *default_dom;
 
diff -druN linux-2.6.39-libre/arch/x86/include/asm/amd_nb.h linux-3.0-rc7-libre/arch/x86/include/asm/amd_nb.h
--- linux-2.6.39-libre/arch/x86/include/asm/amd_nb.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/include/asm/amd_nb.h	2011-07-11 19:51:52.000000000 -0400
@@ -11,7 +11,6 @@
 
 extern const struct pci_device_id amd_nb_misc_ids[];
 extern const struct amd_nb_bus_dev_range amd_nb_bus_dev_ranges[];
-struct bootnode;
 
 extern bool early_is_amd_nb(u32 value);
 extern int amd_cache_northbridges(void);
diff -druN linux-2.6.39-libre/arch/x86/include/asm/apb_timer.h linux-3.0-rc7-libre/arch/x86/include/asm/apb_timer.h
--- linux-2.6.39-libre/arch/x86/include/asm/apb_timer.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/include/asm/apb_timer.h	2011-07-11 19:51:52.000000000 -0400
@@ -62,7 +62,7 @@
 #else /* CONFIG_APB_TIMER */
 
 static inline unsigned long apbt_quick_calibrate(void) {return 0; }
-static inline void apbt_time_init(void) {return 0; }
+static inline void apbt_time_init(void) { }
 
 #endif
 #endif /* ASM_X86_APBT_H */
diff -druN linux-2.6.39-libre/arch/x86/include/asm/apic.h linux-3.0-rc7-libre/arch/x86/include/asm/apic.h
--- linux-2.6.39-libre/arch/x86/include/asm/apic.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/include/asm/apic.h	2011-07-11 19:51:52.000000000 -0400
@@ -363,7 +363,12 @@
 	 */
 	int (*x86_32_early_logical_apicid)(int cpu);
 
-	/* determine CPU -> NUMA node mapping */
+	/*
+	 * Optional method called from setup_local_APIC() after logical
+	 * apicid is guaranteed to be known to initialize apicid -> node
+	 * mapping if NUMA initialization hasn't done so already.  Don't
+	 * add new users.
+	 */
 	int (*x86_32_numa_cpu_node)(int cpu);
 #endif
 };
@@ -376,6 +381,26 @@
 extern struct apic *apic;
 
 /*
+ * APIC drivers are probed based on how they are listed in the .apicdrivers
+ * section. So the order is important and enforced by the ordering
+ * of different apic driver files in the Makefile.
+ *
+ * For the files having two apic drivers, we use apic_drivers()
+ * to enforce the order with in them.
+ */
+#define apic_driver(sym)					\
+	static struct apic *__apicdrivers_##sym __used		\
+	__aligned(sizeof(struct apic *))			\
+	__section(.apicdrivers) = { &sym }
+
+#define apic_drivers(sym1, sym2)					\
+	static struct apic *__apicdrivers_##sym1##sym2[2] __used	\
+	__aligned(sizeof(struct apic *))				\
+	__section(.apicdrivers) = { &sym1, &sym2 }
+
+extern struct apic *__apicdrivers[], *__apicdrivers_end[];
+
+/*
  * APIC functionality to boot other CPUs - only used on SMP:
  */
 #ifdef CONFIG_SMP
@@ -453,15 +478,10 @@
 #define DEFAULT_TRAMPOLINE_PHYS_HIGH		0x469
 
 #ifdef CONFIG_X86_64
-extern struct apic apic_flat;
-extern struct apic apic_physflat;
-extern struct apic apic_x2apic_cluster;
-extern struct apic apic_x2apic_phys;
 extern int default_acpi_madt_oem_check(char *, char *);
 
 extern void apic_send_IPI_self(int vector);
 
-extern struct apic apic_x2apic_uv_x;
 DECLARE_PER_CPU(int, x2apic_extra_bits);
 
 extern int default_cpu_present_to_apicid(int mps_cpu);
@@ -475,7 +495,7 @@
 	return;
 }
 
-extern void generic_bigsmp_probe(void);
+extern struct apic *generic_bigsmp_probe(void);
 
 
 #ifdef CONFIG_X86_LOCAL_APIC
@@ -511,8 +531,6 @@
 
 #ifdef CONFIG_X86_32
 
-extern struct apic apic_default;
-
 static inline int noop_x86_32_early_logical_apicid(int cpu)
 {
 	return BAD_APICID;
@@ -537,8 +555,6 @@
 	return cpuid_apic >> index_msb;
 }
 
-extern int default_x86_32_numa_cpu_node(int cpu);
-
 #endif
 
 static inline unsigned int
diff -druN linux-2.6.39-libre/arch/x86/include/asm/bios_ebda.h linux-3.0-rc7-libre/arch/x86/include/asm/bios_ebda.h
--- linux-2.6.39-libre/arch/x86/include/asm/bios_ebda.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/include/asm/bios_ebda.h	2011-07-11 19:51:52.000000000 -0400
@@ -4,16 +4,40 @@
 #include <asm/io.h>
 
 /*
- * there is a real-mode segmented pointer pointing to the
- * 4K EBDA area at 0x40E.
+ * Returns physical address of EBDA.  Returns 0 if there is no EBDA.
  */
 static inline unsigned int get_bios_ebda(void)
 {
+	/*
+	 * There is a real-mode segmented pointer pointing to the
+	 * 4K EBDA area at 0x40E.
+	 */
 	unsigned int address = *(unsigned short *)phys_to_virt(0x40E);
 	address <<= 4;
 	return address;	/* 0 means none */
 }
 
+/*
+ * Return the sanitized length of the EBDA in bytes, if it exists.
+ */
+static inline unsigned int get_bios_ebda_length(void)
+{
+	unsigned int address;
+	unsigned int length;
+
+	address = get_bios_ebda();
+	if (!address)
+		return 0;
+
+	/* EBDA length is byte 0 of the EBDA (stored in KiB) */
+	length = *(unsigned char *)phys_to_virt(address);
+	length <<= 10;
+
+	/* Trim the length if it extends beyond 640KiB */
+	length = min_t(unsigned int, (640 * 1024) - address, length);
+	return length;
+}
+
 void reserve_ebda_region(void);
 
 #ifdef CONFIG_X86_CHECK_BIOS_CORRUPTION
diff -druN linux-2.6.39-libre/arch/x86/include/asm/cpufeature.h linux-3.0-rc7-libre/arch/x86/include/asm/cpufeature.h
--- linux-2.6.39-libre/arch/x86/include/asm/cpufeature.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/include/asm/cpufeature.h	2011-07-11 19:51:52.000000000 -0400
@@ -125,7 +125,7 @@
 #define X86_FEATURE_OSXSAVE	(4*32+27) /* "" XSAVE enabled in the OS */
 #define X86_FEATURE_AVX		(4*32+28) /* Advanced Vector Extensions */
 #define X86_FEATURE_F16C	(4*32+29) /* 16-bit fp conversions */
-#define X86_FEATURE_RDRND	(4*32+30) /* The RDRAND instruction */
+#define X86_FEATURE_RDRAND	(4*32+30) /* The RDRAND instruction */
 #define X86_FEATURE_HYPERVISOR	(4*32+31) /* Running on a hypervisor */
 
 /* VIA/Cyrix/Centaur-defined CPU features, CPUID level 0xC0000001, word 5 */
@@ -195,6 +195,8 @@
 
 /* Intel-defined CPU features, CPUID level 0x00000007:0 (ebx), word 9 */
 #define X86_FEATURE_FSGSBASE	(9*32+ 0) /* {RD/WR}{FS/GS}BASE instructions*/
+#define X86_FEATURE_SMEP	(9*32+ 7) /* Supervisor Mode Execution Protection */
+#define X86_FEATURE_ERMS	(9*32+ 9) /* Enhanced REP MOVSB/STOSB */
 
 #if defined(__KERNEL__) && !defined(__ASSEMBLY__)
 
@@ -207,8 +209,7 @@
 #define test_cpu_cap(c, bit)						\
 	 test_bit(bit, (unsigned long *)((c)->x86_capability))
 
-#define cpu_has(c, bit)							\
-	(__builtin_constant_p(bit) &&					\
+#define REQUIRED_MASK_BIT_SET(bit)					\
 	 ( (((bit)>>5)==0 && (1UL<<((bit)&31) & REQUIRED_MASK0)) ||	\
 	   (((bit)>>5)==1 && (1UL<<((bit)&31) & REQUIRED_MASK1)) ||	\
 	   (((bit)>>5)==2 && (1UL<<((bit)&31) & REQUIRED_MASK2)) ||	\
@@ -218,10 +219,16 @@
 	   (((bit)>>5)==6 && (1UL<<((bit)&31) & REQUIRED_MASK6)) ||	\
 	   (((bit)>>5)==7 && (1UL<<((bit)&31) & REQUIRED_MASK7)) ||	\
 	   (((bit)>>5)==8 && (1UL<<((bit)&31) & REQUIRED_MASK8)) ||	\
-	   (((bit)>>5)==9 && (1UL<<((bit)&31) & REQUIRED_MASK9)) )	\
-	  ? 1 :								\
+	   (((bit)>>5)==9 && (1UL<<((bit)&31) & REQUIRED_MASK9)) )
+
+#define cpu_has(c, bit)							\
+	(__builtin_constant_p(bit) && REQUIRED_MASK_BIT_SET(bit) ? 1 :	\
 	 test_cpu_cap(c, bit))
 
+#define this_cpu_has(bit)						\
+	(__builtin_constant_p(bit) && REQUIRED_MASK_BIT_SET(bit) ? 1 : 	\
+	 x86_this_cpu_test_bit(bit, (unsigned long *)&cpu_info.x86_capability))
+
 #define boot_cpu_has(bit)	cpu_has(&boot_cpu_data, bit)
 
 #define set_cpu_cap(c, bit)	set_bit(bit, (unsigned long *)((c)->x86_capability))
diff -druN linux-2.6.39-libre/arch/x86/include/asm/desc.h linux-3.0-rc7-libre/arch/x86/include/asm/desc.h
--- linux-2.6.39-libre/arch/x86/include/asm/desc.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/include/asm/desc.h	2011-07-11 19:51:52.000000000 -0400
@@ -4,30 +4,33 @@
 #include <asm/desc_defs.h>
 #include <asm/ldt.h>
 #include <asm/mmu.h>
+
 #include <linux/smp.h>
 
-static inline void fill_ldt(struct desc_struct *desc,
-			    const struct user_desc *info)
+static inline void fill_ldt(struct desc_struct *desc, const struct user_desc *info)
 {
-	desc->limit0 = info->limit & 0x0ffff;
-	desc->base0 = info->base_addr & 0x0000ffff;
+	desc->limit0		= info->limit & 0x0ffff;
 
-	desc->base1 = (info->base_addr & 0x00ff0000) >> 16;
-	desc->type = (info->read_exec_only ^ 1) << 1;
-	desc->type |= info->contents << 2;
-	desc->s = 1;
-	desc->dpl = 0x3;
-	desc->p = info->seg_not_present ^ 1;
-	desc->limit = (info->limit & 0xf0000) >> 16;
-	desc->avl = info->useable;
-	desc->d = info->seg_32bit;
-	desc->g = info->limit_in_pages;
-	desc->base2 = (info->base_addr & 0xff000000) >> 24;
+	desc->base0		= (info->base_addr & 0x0000ffff);
+	desc->base1		= (info->base_addr & 0x00ff0000) >> 16;
+
+	desc->type		= (info->read_exec_only ^ 1) << 1;
+	desc->type	       |= info->contents << 2;
+
+	desc->s			= 1;
+	desc->dpl		= 0x3;
+	desc->p			= info->seg_not_present ^ 1;
+	desc->limit		= (info->limit & 0xf0000) >> 16;
+	desc->avl		= info->useable;
+	desc->d			= info->seg_32bit;
+	desc->g			= info->limit_in_pages;
+
+	desc->base2		= (info->base_addr & 0xff000000) >> 24;
 	/*
 	 * Don't allow setting of the lm bit. It is useless anyway
 	 * because 64bit system calls require __USER_CS:
 	 */
-	desc->l = 0;
+	desc->l			= 0;
 }
 
 extern struct desc_ptr idt_descr;
@@ -36,6 +39,7 @@
 struct gdt_page {
 	struct desc_struct gdt[GDT_ENTRIES];
 } __attribute__((aligned(PAGE_SIZE)));
+
 DECLARE_PER_CPU_PAGE_ALIGNED(struct gdt_page, gdt_page);
 
 static inline struct desc_struct *get_cpu_gdt_table(unsigned int cpu)
@@ -48,16 +52,16 @@
 static inline void pack_gate(gate_desc *gate, unsigned type, unsigned long func,
 			     unsigned dpl, unsigned ist, unsigned seg)
 {
-	gate->offset_low = PTR_LOW(func);
-	gate->segment = __KERNEL_CS;
-	gate->ist = ist;
-	gate->p = 1;
-	gate->dpl = dpl;
-	gate->zero0 = 0;
-	gate->zero1 = 0;
-	gate->type = type;
-	gate->offset_middle = PTR_MIDDLE(func);
-	gate->offset_high = PTR_HIGH(func);
+	gate->offset_low	= PTR_LOW(func);
+	gate->segment		= __KERNEL_CS;
+	gate->ist		= ist;
+	gate->p			= 1;
+	gate->dpl		= dpl;
+	gate->zero0		= 0;
+	gate->zero1		= 0;
+	gate->type		= type;
+	gate->offset_middle	= PTR_MIDDLE(func);
+	gate->offset_high	= PTR_HIGH(func);
 }
 
 #else
@@ -66,8 +70,7 @@
 			     unsigned short seg)
 {
 	gate->a = (seg << 16) | (base & 0xffff);
-	gate->b = (base & 0xffff0000) |
-		  (((0x80 | type | (dpl << 5)) & 0xff) << 8);
+	gate->b = (base & 0xffff0000) | (((0x80 | type | (dpl << 5)) & 0xff) << 8);
 }
 
 #endif
@@ -75,31 +78,29 @@
 static inline int desc_empty(const void *ptr)
 {
 	const u32 *desc = ptr;
+
 	return !(desc[0] | desc[1]);
 }
 
 #ifdef CONFIG_PARAVIRT
 #include <asm/paravirt.h>
 #else
-#define load_TR_desc() native_load_tr_desc()
-#define load_gdt(dtr) native_load_gdt(dtr)
-#define load_idt(dtr) native_load_idt(dtr)
-#define load_tr(tr) asm volatile("ltr %0"::"m" (tr))
-#define load_ldt(ldt) asm volatile("lldt %0"::"m" (ldt))
+#define load_TR_desc()				native_load_tr_desc()
+#define load_gdt(dtr)				native_load_gdt(dtr)
+#define load_idt(dtr)				native_load_idt(dtr)
+#define load_tr(tr)				asm volatile("ltr %0"::"m" (tr))
+#define load_ldt(ldt)				asm volatile("lldt %0"::"m" (ldt))
 
-#define store_gdt(dtr) native_store_gdt(dtr)
-#define store_idt(dtr) native_store_idt(dtr)
-#define store_tr(tr) (tr = native_store_tr())
+#define store_gdt(dtr)				native_store_gdt(dtr)
+#define store_idt(dtr)				native_store_idt(dtr)
+#define store_tr(tr)				(tr = native_store_tr())
 
-#define load_TLS(t, cpu) native_load_tls(t, cpu)
-#define set_ldt native_set_ldt
+#define load_TLS(t, cpu)			native_load_tls(t, cpu)
+#define set_ldt					native_set_ldt
 
-#define write_ldt_entry(dt, entry, desc)	\
-	native_write_ldt_entry(dt, entry, desc)
-#define write_gdt_entry(dt, entry, desc, type)		\
-	native_write_gdt_entry(dt, entry, desc, type)
-#define write_idt_entry(dt, entry, g)		\
-	native_write_idt_entry(dt, entry, g)
+#define write_ldt_entry(dt, entry, desc)	native_write_ldt_entry(dt, entry, desc)
+#define write_gdt_entry(dt, entry, desc, type)	native_write_gdt_entry(dt, entry, desc, type)
+#define write_idt_entry(dt, entry, g)		native_write_idt_entry(dt, entry, g)
 
 static inline void paravirt_alloc_ldt(struct desc_struct *ldt, unsigned entries)
 {
@@ -112,33 +113,27 @@
 
 #define store_ldt(ldt) asm("sldt %0" : "=m"(ldt))
 
-static inline void native_write_idt_entry(gate_desc *idt, int entry,
-					  const gate_desc *gate)
+static inline void native_write_idt_entry(gate_desc *idt, int entry, const gate_desc *gate)
 {
 	memcpy(&idt[entry], gate, sizeof(*gate));
 }
 
-static inline void native_write_ldt_entry(struct desc_struct *ldt, int entry,
-					  const void *desc)
+static inline void native_write_ldt_entry(struct desc_struct *ldt, int entry, const void *desc)
 {
 	memcpy(&ldt[entry], desc, 8);
 }
 
-static inline void native_write_gdt_entry(struct desc_struct *gdt, int entry,
-					  const void *desc, int type)
+static inline void
+native_write_gdt_entry(struct desc_struct *gdt, int entry, const void *desc, int type)
 {
 	unsigned int size;
+
 	switch (type) {
-	case DESC_TSS:
-		size = sizeof(tss_desc);
-		break;
-	case DESC_LDT:
-		size = sizeof(ldt_desc);
-		break;
-	default:
-		size = sizeof(struct desc_struct);
-		break;
+	case DESC_TSS:	size = sizeof(tss_desc);	break;
+	case DESC_LDT:	size = sizeof(ldt_desc);	break;
+	default:	size = sizeof(*gdt);		break;
 	}
+
 	memcpy(&gdt[entry], desc, size);
 }
 
@@ -154,20 +149,21 @@
 }
 
 
-static inline void set_tssldt_descriptor(void *d, unsigned long addr,
-					 unsigned type, unsigned size)
+static inline void set_tssldt_descriptor(void *d, unsigned long addr, unsigned type, unsigned size)
 {
 #ifdef CONFIG_X86_64
 	struct ldttss_desc64 *desc = d;
+
 	memset(desc, 0, sizeof(*desc));
-	desc->limit0 = size & 0xFFFF;
-	desc->base0 = PTR_LOW(addr);
-	desc->base1 = PTR_MIDDLE(addr) & 0xFF;
-	desc->type = type;
-	desc->p = 1;
-	desc->limit1 = (size >> 16) & 0xF;
-	desc->base2 = (PTR_MIDDLE(addr) >> 8) & 0xFF;
-	desc->base3 = PTR_HIGH(addr);
+
+	desc->limit0		= size & 0xFFFF;
+	desc->base0		= PTR_LOW(addr);
+	desc->base1		= PTR_MIDDLE(addr) & 0xFF;
+	desc->type		= type;
+	desc->p			= 1;
+	desc->limit1		= (size >> 16) & 0xF;
+	desc->base2		= (PTR_MIDDLE(addr) >> 8) & 0xFF;
+	desc->base3		= PTR_HIGH(addr);
 #else
 	pack_descriptor((struct desc_struct *)d, addr, size, 0x80 | type, 0);
 #endif
@@ -237,14 +233,16 @@
 static inline unsigned long native_store_tr(void)
 {
 	unsigned long tr;
+
 	asm volatile("str %0":"=r" (tr));
+
 	return tr;
 }
 
 static inline void native_load_tls(struct thread_struct *t, unsigned int cpu)
 {
-	unsigned int i;
 	struct desc_struct *gdt = get_cpu_gdt_table(cpu);
+	unsigned int i;
 
 	for (i = 0; i < GDT_ENTRY_TLS_ENTRIES; i++)
 		gdt[GDT_ENTRY_TLS_MIN + i] = t->tls_array[i];
@@ -313,6 +311,7 @@
 			     unsigned dpl, unsigned ist, unsigned seg)
 {
 	gate_desc s;
+
 	pack_gate(&s, type, (unsigned long)addr, dpl, ist, seg);
 	/*
 	 * does not need to be atomic because it is only done once at
@@ -343,8 +342,9 @@
 		set_bit(vector, used_vectors);
 		if (first_system_vector > vector)
 			first_system_vector = vector;
-	} else
+	} else {
 		BUG();
+	}
 }
 
 static inline void alloc_intr_gate(unsigned int n, void *addr)
diff -druN linux-2.6.39-libre/arch/x86/include/asm/dma.h linux-3.0-rc7-libre/arch/x86/include/asm/dma.h
--- linux-2.6.39-libre/arch/x86/include/asm/dma.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/include/asm/dma.h	2011-07-11 19:51:52.000000000 -0400
@@ -69,22 +69,18 @@
 
 #define MAX_DMA_CHANNELS	8
 
-#ifdef CONFIG_X86_32
-
-/* The maximum address that we can perform a DMA transfer to on this platform */
-#define MAX_DMA_ADDRESS      (PAGE_OFFSET + 0x1000000)
-
-#else
-
 /* 16MB ISA DMA zone */
 #define MAX_DMA_PFN   ((16 * 1024 * 1024) >> PAGE_SHIFT)
 
 /* 4GB broken PCI/AGP hardware bus master zone */
 #define MAX_DMA32_PFN ((4UL * 1024 * 1024 * 1024) >> PAGE_SHIFT)
 
+#ifdef CONFIG_X86_32
+/* The maximum address that we can perform a DMA transfer to on this platform */
+#define MAX_DMA_ADDRESS      (PAGE_OFFSET + 0x1000000)
+#else
 /* Compat define for old dma zone */
 #define MAX_DMA_ADDRESS ((unsigned long)__va(MAX_DMA_PFN << PAGE_SHIFT))
-
 #endif
 
 /* 8237 DMA controllers */
diff -druN linux-2.6.39-libre/arch/x86/include/asm/efi.h linux-3.0-rc7-libre/arch/x86/include/asm/efi.h
--- linux-2.6.39-libre/arch/x86/include/asm/efi.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/include/asm/efi.h	2011-07-11 19:51:52.000000000 -0400
@@ -90,6 +90,7 @@
 #endif /* CONFIG_X86_32 */
 
 extern int add_efi_memmap;
+extern void efi_set_executable(efi_memory_desc_t *md, bool executable);
 extern void efi_memblock_x86_reserve_range(void);
 extern void efi_call_phys_prelog(void);
 extern void efi_call_phys_epilog(void);
diff -druN linux-2.6.39-libre/arch/x86/include/asm/ftrace.h linux-3.0-rc7-libre/arch/x86/include/asm/ftrace.h
--- linux-2.6.39-libre/arch/x86/include/asm/ftrace.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/include/asm/ftrace.h	2011-07-11 19:51:52.000000000 -0400
@@ -38,11 +38,10 @@
 static inline unsigned long ftrace_call_adjust(unsigned long addr)
 {
 	/*
-	 * call mcount is "e8 <4 byte offset>"
-	 * The addr points to the 4 byte offset and the caller of this
-	 * function wants the pointer to e8. Simply subtract one.
+	 * addr is the address of the mcount call instruction.
+	 * recordmcount does the necessary offset calculation.
 	 */
-	return addr - 1;
+	return addr;
 }
 
 #ifdef CONFIG_DYNAMIC_FTRACE
diff -druN linux-2.6.39-libre/arch/x86/include/asm/i8253.h linux-3.0-rc7-libre/arch/x86/include/asm/i8253.h
--- linux-2.6.39-libre/arch/x86/include/asm/i8253.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/include/asm/i8253.h	2011-07-11 19:51:52.000000000 -0400
@@ -6,6 +6,8 @@
 #define PIT_CH0			0x40
 #define PIT_CH2			0x42
 
+#define PIT_LATCH	LATCH
+
 extern raw_spinlock_t i8253_lock;
 
 extern struct clock_event_device *global_clock_event;
diff -druN linux-2.6.39-libre/arch/x86/include/asm/idle.h linux-3.0-rc7-libre/arch/x86/include/asm/idle.h
--- linux-2.6.39-libre/arch/x86/include/asm/idle.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/include/asm/idle.h	2011-07-11 19:51:52.000000000 -0400
@@ -16,6 +16,6 @@
 static inline void exit_idle(void) { }
 #endif /* CONFIG_X86_64 */
 
-void c1e_remove_cpu(int cpu);
+void amd_e400_remove_cpu(int cpu);
 
 #endif /* _ASM_X86_IDLE_H */
diff -druN linux-2.6.39-libre/arch/x86/include/asm/io_apic.h linux-3.0-rc7-libre/arch/x86/include/asm/io_apic.h
--- linux-2.6.39-libre/arch/x86/include/asm/io_apic.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/include/asm/io_apic.h	2011-07-11 19:51:52.000000000 -0400
@@ -105,12 +105,12 @@
  * # of IO-APICs and # of IRQ routing registers
  */
 extern int nr_ioapics;
-extern int nr_ioapic_registers[MAX_IO_APICS];
 
-#define MP_MAX_IOAPIC_PIN 127
+extern int mpc_ioapic_id(int ioapic);
+extern unsigned int mpc_ioapic_addr(int ioapic);
+extern struct mp_ioapic_gsi *mp_ioapic_gsi_routing(int ioapic);
 
-/* I/O APIC entries */
-extern struct mpc_ioapic mp_ioapics[MAX_IO_APICS];
+#define MP_MAX_IOAPIC_PIN 127
 
 /* # of MP IRQ source entries */
 extern int mp_irq_entries;
@@ -152,11 +152,9 @@
 
 int io_apic_setup_irq_pin_once(unsigned int irq, int node, struct io_apic_irq_attr *attr);
 
-extern struct IO_APIC_route_entry **alloc_ioapic_entries(void);
-extern void free_ioapic_entries(struct IO_APIC_route_entry **ioapic_entries);
-extern int save_IO_APIC_setup(struct IO_APIC_route_entry **ioapic_entries);
-extern void mask_IO_APIC_setup(struct IO_APIC_route_entry **ioapic_entries);
-extern int restore_IO_APIC_setup(struct IO_APIC_route_entry **ioapic_entries);
+extern int save_ioapic_entries(void);
+extern void mask_ioapic_entries(void);
+extern int restore_ioapic_entries(void);
 
 extern int get_nr_irqs_gsi(void);
 
@@ -192,19 +190,13 @@
 static inline int io_apic_set_pci_routing(struct device *dev, int irq,
 		 struct io_apic_irq_attr *irq_attr) { return 0; }
 
-static inline struct IO_APIC_route_entry **alloc_ioapic_entries(void)
-{
-	return NULL;
-}
-
-static inline void free_ioapic_entries(struct IO_APIC_route_entry **ent) { }
-static inline int save_IO_APIC_setup(struct IO_APIC_route_entry **ent)
+static inline int save_ioapic_entries(void)
 {
 	return -ENOMEM;
 }
 
-static inline void mask_IO_APIC_setup(struct IO_APIC_route_entry **ent) { }
-static inline int restore_IO_APIC_setup(struct IO_APIC_route_entry **ent)
+static inline void mask_ioapic_entries(void) { }
+static inline int restore_ioapic_entries(void)
 {
 	return -ENOMEM;
 }
diff -druN linux-2.6.39-libre/arch/x86/include/asm/io.h linux-3.0-rc7-libre/arch/x86/include/asm/io.h
--- linux-2.6.39-libre/arch/x86/include/asm/io.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/include/asm/io.h	2011-07-11 19:51:52.000000000 -0400
@@ -38,7 +38,6 @@
 
 #include <linux/string.h>
 #include <linux/compiler.h>
-#include <asm-generic/int-ll64.h>
 #include <asm/page.h>
 
 #include <xen/xen.h>
@@ -87,27 +86,6 @@
 build_mmio_read(readq, "q", unsigned long, "=r", :"memory")
 build_mmio_write(writeq, "q", unsigned long, "r", :"memory")
 
-#else
-
-static inline __u64 readq(const volatile void __iomem *addr)
-{
-	const volatile u32 __iomem *p = addr;
-	u32 low, high;
-
-	low = readl(p);
-	high = readl(p + 1);
-
-	return low + ((u64)high << 32);
-}
-
-static inline void writeq(__u64 val, volatile void __iomem *addr)
-{
-	writel(val, addr);
-	writel(val >> 32, addr+4);
-}
-
-#endif
-
 #define readq_relaxed(a)	readq(a)
 
 #define __raw_readq(a)		readq(a)
@@ -117,6 +95,8 @@
 #define readq			readq
 #define writeq			writeq
 
+#endif
+
 /**
  *	virt_to_phys	-	map virtual addresses to physical
  *	@address: address to remap
diff -druN linux-2.6.39-libre/arch/x86/include/asm/jump_label.h linux-3.0-rc7-libre/arch/x86/include/asm/jump_label.h
--- linux-2.6.39-libre/arch/x86/include/asm/jump_label.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/include/asm/jump_label.h	2011-07-11 19:51:52.000000000 -0400
@@ -5,20 +5,25 @@
 
 #include <linux/types.h>
 #include <asm/nops.h>
+#include <asm/asm.h>
 
 #define JUMP_LABEL_NOP_SIZE 5
 
-# define JUMP_LABEL_INITIAL_NOP ".byte 0xe9 \n\t .long 0\n\t"
+#define JUMP_LABEL_INITIAL_NOP ".byte 0xe9 \n\t .long 0\n\t"
 
-# define JUMP_LABEL(key, label)					\
-	do {							\
-		asm goto("1:"					\
-			JUMP_LABEL_INITIAL_NOP			\
-			".pushsection __jump_table,  \"aw\" \n\t"\
-			_ASM_PTR "1b, %l[" #label "], %c0 \n\t" \
-			".popsection \n\t"			\
-			: :  "i" (key) :  : label);		\
-	} while (0)
+static __always_inline bool arch_static_branch(struct jump_label_key *key)
+{
+	asm goto("1:"
+		JUMP_LABEL_INITIAL_NOP
+		".pushsection __jump_table,  \"aw\" \n\t"
+		_ASM_ALIGN "\n\t"
+		_ASM_PTR "1b, %l[l_yes], %c0 \n\t"
+		".popsection \n\t"
+		: :  "i" (key) : : l_yes);
+	return false;
+l_yes:
+	return true;
+}
 
 #endif /* __KERNEL__ */
 
diff -druN linux-2.6.39-libre/arch/x86/include/asm/kgdb.h linux-3.0-rc7-libre/arch/x86/include/asm/kgdb.h
--- linux-2.6.39-libre/arch/x86/include/asm/kgdb.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/include/asm/kgdb.h	2011-07-11 19:51:52.000000000 -0400
@@ -77,6 +77,7 @@
 }
 #define BREAK_INSTR_SIZE	1
 #define CACHE_FLUSH_IS_SAFE	1
+#define GDB_ADJUSTS_BREAK_OFFSET
 
 extern int kgdb_ll_trap(int cmd, const char *str,
 			struct pt_regs *regs, long err, int trap, int sig);
diff -druN linux-2.6.39-libre/arch/x86/include/asm/kvm_emulate.h linux-3.0-rc7-libre/arch/x86/include/asm/kvm_emulate.h
--- linux-2.6.39-libre/arch/x86/include/asm/kvm_emulate.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/include/asm/kvm_emulate.h	2011-07-11 19:51:52.000000000 -0400
@@ -14,6 +14,8 @@
 #include <asm/desc_defs.h>
 
 struct x86_emulate_ctxt;
+enum x86_intercept;
+enum x86_intercept_stage;
 
 struct x86_exception {
 	u8 vector;
@@ -24,6 +26,24 @@
 };
 
 /*
+ * This struct is used to carry enough information from the instruction
+ * decoder to main KVM so that a decision can be made whether the
+ * instruction needs to be intercepted or not.
+ */
+struct x86_instruction_info {
+	u8  intercept;          /* which intercept                      */
+	u8  rep_prefix;         /* rep prefix?                          */
+	u8  modrm_mod;		/* mod part of modrm			*/
+	u8  modrm_reg;          /* index of register used               */
+	u8  modrm_rm;		/* rm part of modrm			*/
+	u64 src_val;            /* value of source operand              */
+	u8  src_bytes;          /* size of source operand               */
+	u8  dst_bytes;          /* size of destination operand          */
+	u8  ad_bytes;           /* size of src/dst address              */
+	u64 next_rip;           /* rip following the instruction        */
+};
+
+/*
  * x86_emulate_ops:
  *
  * These operations represent the instruction emulator's interface to memory.
@@ -62,6 +82,7 @@
 #define X86EMUL_RETRY_INSTR     3 /* retry the instruction for some reason */
 #define X86EMUL_CMPXCHG_FAILED  4 /* cmpxchg did not see expected value */
 #define X86EMUL_IO_NEEDED       5 /* IO is needed to complete emulation */
+#define X86EMUL_INTERCEPTED     6 /* Intercepted by nested VMCB/VMCS */
 
 struct x86_emulate_ops {
 	/*
@@ -71,8 +92,9 @@
 	 *  @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,
+	int (*read_std)(struct x86_emulate_ctxt *ctxt,
+			unsigned long addr, void *val,
+			unsigned int bytes,
 			struct x86_exception *fault);
 
 	/*
@@ -82,8 +104,8 @@
 	 *  @val:   [OUT] Value write to memory, zero-extended to 'u_long'.
 	 *  @bytes: [IN ] Number of bytes to write to memory.
 	 */
-	int (*write_std)(unsigned long addr, void *val,
-			 unsigned int bytes, struct kvm_vcpu *vcpu,
+	int (*write_std)(struct x86_emulate_ctxt *ctxt,
+			 unsigned long addr, void *val, unsigned int bytes,
 			 struct x86_exception *fault);
 	/*
 	 * fetch: Read bytes of standard (non-emulated/special) memory.
@@ -92,8 +114,8 @@
 	 *  @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,
+	int (*fetch)(struct x86_emulate_ctxt *ctxt,
+		     unsigned long addr, void *val, unsigned int bytes,
 		     struct x86_exception *fault);
 
 	/*
@@ -102,11 +124,9 @@
 	 *  @val:   [OUT] Value read from memory, zero-extended to 'u_long'.
 	 *  @bytes: [IN ] Number of bytes to read from memory.
 	 */
-	int (*read_emulated)(unsigned long addr,
-			     void *val,
-			     unsigned int bytes,
-			     struct x86_exception *fault,
-			     struct kvm_vcpu *vcpu);
+	int (*read_emulated)(struct x86_emulate_ctxt *ctxt,
+			     unsigned long addr, void *val, unsigned int bytes,
+			     struct x86_exception *fault);
 
 	/*
 	 * write_emulated: Write bytes to emulated/special memory area.
@@ -115,11 +135,10 @@
 	 *                required).
 	 *  @bytes: [IN ] Number of bytes to write to memory.
 	 */
-	int (*write_emulated)(unsigned long addr,
-			      const void *val,
+	int (*write_emulated)(struct x86_emulate_ctxt *ctxt,
+			      unsigned long addr, const void *val,
 			      unsigned int bytes,
-			      struct x86_exception *fault,
-			      struct kvm_vcpu *vcpu);
+			      struct x86_exception *fault);
 
 	/*
 	 * cmpxchg_emulated: Emulate an atomic (LOCKed) CMPXCHG operation on an
@@ -129,40 +148,54 @@
 	 *  @new:   [IN ] Value to write to @addr.
 	 *  @bytes: [IN ] Number of bytes to access using CMPXCHG.
 	 */
-	int (*cmpxchg_emulated)(unsigned long addr,
+	int (*cmpxchg_emulated)(struct x86_emulate_ctxt *ctxt,
+				unsigned long addr,
 				const void *old,
 				const void *new,
 				unsigned int bytes,
-				struct x86_exception *fault,
-				struct kvm_vcpu *vcpu);
+				struct x86_exception *fault);
+	void (*invlpg)(struct x86_emulate_ctxt *ctxt, ulong addr);
 
-	int (*pio_in_emulated)(int size, unsigned short port, void *val,
-			       unsigned int count, struct kvm_vcpu *vcpu);
+	int (*pio_in_emulated)(struct x86_emulate_ctxt *ctxt,
+			       int size, unsigned short port, void *val,
+			       unsigned int count);
 
-	int (*pio_out_emulated)(int size, unsigned short port, const void *val,
-				unsigned int count, struct kvm_vcpu *vcpu);
+	int (*pio_out_emulated)(struct x86_emulate_ctxt *ctxt,
+				int size, unsigned short port, const void *val,
+				unsigned int count);
 
-	bool (*get_cached_descriptor)(struct desc_struct *desc, u32 *base3,
-				      int seg, struct kvm_vcpu *vcpu);
-	void (*set_cached_descriptor)(struct desc_struct *desc, u32 base3,
-				      int seg, struct kvm_vcpu *vcpu);
-	u16 (*get_segment_selector)(int seg, struct kvm_vcpu *vcpu);
-	void (*set_segment_selector)(u16 sel, int seg, struct kvm_vcpu *vcpu);
-	unsigned long (*get_cached_segment_base)(int seg, struct kvm_vcpu *vcpu);
-	void (*get_gdt)(struct desc_ptr *dt, struct kvm_vcpu *vcpu);
-	void (*get_idt)(struct desc_ptr *dt, struct kvm_vcpu *vcpu);
-	ulong (*get_cr)(int cr, struct kvm_vcpu *vcpu);
-	int (*set_cr)(int cr, ulong val, struct kvm_vcpu *vcpu);
-	int (*cpl)(struct kvm_vcpu *vcpu);
-	int (*get_dr)(int dr, unsigned long *dest, struct kvm_vcpu *vcpu);
-	int (*set_dr)(int dr, unsigned long value, struct kvm_vcpu *vcpu);
-	int (*set_msr)(struct kvm_vcpu *vcpu, u32 msr_index, u64 data);
-	int (*get_msr)(struct kvm_vcpu *vcpu, u32 msr_index, u64 *pdata);
+	bool (*get_segment)(struct x86_emulate_ctxt *ctxt, u16 *selector,
+			    struct desc_struct *desc, u32 *base3, int seg);
+	void (*set_segment)(struct x86_emulate_ctxt *ctxt, u16 selector,
+			    struct desc_struct *desc, u32 base3, int seg);
+	unsigned long (*get_cached_segment_base)(struct x86_emulate_ctxt *ctxt,
+						 int seg);
+	void (*get_gdt)(struct x86_emulate_ctxt *ctxt, struct desc_ptr *dt);
+	void (*get_idt)(struct x86_emulate_ctxt *ctxt, struct desc_ptr *dt);
+	void (*set_gdt)(struct x86_emulate_ctxt *ctxt, struct desc_ptr *dt);
+	void (*set_idt)(struct x86_emulate_ctxt *ctxt, struct desc_ptr *dt);
+	ulong (*get_cr)(struct x86_emulate_ctxt *ctxt, int cr);
+	int (*set_cr)(struct x86_emulate_ctxt *ctxt, int cr, ulong val);
+	int (*cpl)(struct x86_emulate_ctxt *ctxt);
+	int (*get_dr)(struct x86_emulate_ctxt *ctxt, int dr, ulong *dest);
+	int (*set_dr)(struct x86_emulate_ctxt *ctxt, int dr, ulong value);
+	int (*set_msr)(struct x86_emulate_ctxt *ctxt, u32 msr_index, u64 data);
+	int (*get_msr)(struct x86_emulate_ctxt *ctxt, u32 msr_index, u64 *pdata);
+	void (*halt)(struct x86_emulate_ctxt *ctxt);
+	void (*wbinvd)(struct x86_emulate_ctxt *ctxt);
+	int (*fix_hypercall)(struct x86_emulate_ctxt *ctxt);
+	void (*get_fpu)(struct x86_emulate_ctxt *ctxt); /* disables preempt */
+	void (*put_fpu)(struct x86_emulate_ctxt *ctxt); /* reenables preempt */
+	int (*intercept)(struct x86_emulate_ctxt *ctxt,
+			 struct x86_instruction_info *info,
+			 enum x86_intercept_stage stage);
 };
 
+typedef u32 __attribute__((vector_size(16))) sse128_t;
+
 /* Type, address-of, and value of an instruction's operand. */
 struct operand {
-	enum { OP_REG, OP_MEM, OP_IMM, OP_NONE } type;
+	enum { OP_REG, OP_MEM, OP_IMM, OP_XMM, OP_NONE } type;
 	unsigned int bytes;
 	union {
 		unsigned long orig_val;
@@ -174,11 +207,13 @@
 			ulong ea;
 			unsigned seg;
 		} mem;
+		unsigned xmm;
 	} addr;
 	union {
 		unsigned long val;
 		u64 val64;
 		char valptr[sizeof(unsigned long) + 2];
+		sse128_t vec_val;
 	};
 };
 
@@ -197,6 +232,7 @@
 struct decode_cache {
 	u8 twobyte;
 	u8 b;
+	u8 intercept;
 	u8 lock_prefix;
 	u8 rep_prefix;
 	u8 op_bytes;
@@ -209,6 +245,7 @@
 	u8 seg_override;
 	unsigned int d;
 	int (*execute)(struct x86_emulate_ctxt *ctxt);
+	int (*check_perm)(struct x86_emulate_ctxt *ctxt);
 	unsigned long regs[NR_VCPU_REGS];
 	unsigned long eip;
 	/* modrm */
@@ -227,17 +264,15 @@
 	struct x86_emulate_ops *ops;
 
 	/* Register state before/after emulation. */
-	struct kvm_vcpu *vcpu;
-
 	unsigned long eflags;
 	unsigned long eip; /* eip before instruction emulation */
 	/* Emulated execution mode, represented by an X86EMUL_MODE value. */
 	int mode;
-	u32 cs_base;
 
 	/* interruptibility state, as a result of execution of STI or MOV SS */
 	int interruptibility;
 
+	bool guest_mode; /* guest running a nested guest */
 	bool perm_ok; /* do not check permissions if true */
 	bool only_vendor_specific_insn;
 
@@ -249,8 +284,8 @@
 };
 
 /* Repeat String Operation Prefix */
-#define REPE_PREFIX	1
-#define REPNE_PREFIX	2
+#define REPE_PREFIX	0xf3
+#define REPNE_PREFIX	0xf2
 
 /* Execution mode, passed to the emulator. */
 #define X86EMUL_MODE_REAL     0	/* Real mode.             */
@@ -259,6 +294,69 @@
 #define X86EMUL_MODE_PROT32   4	/* 32-bit protected mode. */
 #define X86EMUL_MODE_PROT64   8	/* 64-bit (long) mode.    */
 
+/* any protected mode   */
+#define X86EMUL_MODE_PROT     (X86EMUL_MODE_PROT16|X86EMUL_MODE_PROT32| \
+			       X86EMUL_MODE_PROT64)
+
+enum x86_intercept_stage {
+	X86_ICTP_NONE = 0,   /* Allow zero-init to not match anything */
+	X86_ICPT_PRE_EXCEPT,
+	X86_ICPT_POST_EXCEPT,
+	X86_ICPT_POST_MEMACCESS,
+};
+
+enum x86_intercept {
+	x86_intercept_none,
+	x86_intercept_cr_read,
+	x86_intercept_cr_write,
+	x86_intercept_clts,
+	x86_intercept_lmsw,
+	x86_intercept_smsw,
+	x86_intercept_dr_read,
+	x86_intercept_dr_write,
+	x86_intercept_lidt,
+	x86_intercept_sidt,
+	x86_intercept_lgdt,
+	x86_intercept_sgdt,
+	x86_intercept_lldt,
+	x86_intercept_sldt,
+	x86_intercept_ltr,
+	x86_intercept_str,
+	x86_intercept_rdtsc,
+	x86_intercept_rdpmc,
+	x86_intercept_pushf,
+	x86_intercept_popf,
+	x86_intercept_cpuid,
+	x86_intercept_rsm,
+	x86_intercept_iret,
+	x86_intercept_intn,
+	x86_intercept_invd,
+	x86_intercept_pause,
+	x86_intercept_hlt,
+	x86_intercept_invlpg,
+	x86_intercept_invlpga,
+	x86_intercept_vmrun,
+	x86_intercept_vmload,
+	x86_intercept_vmsave,
+	x86_intercept_vmmcall,
+	x86_intercept_stgi,
+	x86_intercept_clgi,
+	x86_intercept_skinit,
+	x86_intercept_rdtscp,
+	x86_intercept_icebp,
+	x86_intercept_wbinvd,
+	x86_intercept_monitor,
+	x86_intercept_mwait,
+	x86_intercept_rdmsr,
+	x86_intercept_wrmsr,
+	x86_intercept_in,
+	x86_intercept_ins,
+	x86_intercept_out,
+	x86_intercept_outs,
+
+	nr_x86_intercepts
+};
+
 /* Host execution mode. */
 #if defined(CONFIG_X86_32)
 #define X86EMUL_MODE_HOST X86EMUL_MODE_PROT32
@@ -270,6 +368,7 @@
 #define EMULATION_FAILED -1
 #define EMULATION_OK 0
 #define EMULATION_RESTART 1
+#define EMULATION_INTERCEPTED 2
 int x86_emulate_insn(struct x86_emulate_ctxt *ctxt);
 int emulator_task_switch(struct x86_emulate_ctxt *ctxt,
 			 u16 tss_selector, int reason,
diff -druN linux-2.6.39-libre/arch/x86/include/asm/kvm_host.h linux-3.0-rc7-libre/arch/x86/include/asm/kvm_host.h
--- linux-2.6.39-libre/arch/x86/include/asm/kvm_host.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/include/asm/kvm_host.h	2011-07-11 19:51:52.000000000 -0400
@@ -30,14 +30,30 @@
 #define KVM_MEMORY_SLOTS 32
 /* memory slots that does not exposed to userspace */
 #define KVM_PRIVATE_MEM_SLOTS 4
+#define KVM_MMIO_SIZE 16
 
 #define KVM_PIO_PAGE_OFFSET 1
 #define KVM_COALESCED_MMIO_PAGE_OFFSET 2
 
+#define CR0_RESERVED_BITS                                               \
+	(~(unsigned long)(X86_CR0_PE | X86_CR0_MP | X86_CR0_EM | X86_CR0_TS \
+			  | X86_CR0_ET | X86_CR0_NE | X86_CR0_WP | X86_CR0_AM \
+			  | X86_CR0_NW | X86_CR0_CD | X86_CR0_PG))
+
 #define CR3_PAE_RESERVED_BITS ((X86_CR3_PWT | X86_CR3_PCD) - 1)
 #define CR3_NONPAE_RESERVED_BITS ((PAGE_SIZE-1) & ~(X86_CR3_PWT | X86_CR3_PCD))
 #define CR3_L_MODE_RESERVED_BITS (CR3_NONPAE_RESERVED_BITS |	\
 				  0xFFFFFF0000000000ULL)
+#define CR4_RESERVED_BITS                                               \
+	(~(unsigned long)(X86_CR4_VME | X86_CR4_PVI | X86_CR4_TSD | X86_CR4_DE\
+			  | X86_CR4_PSE | X86_CR4_PAE | X86_CR4_MCE     \
+			  | X86_CR4_PGE | X86_CR4_PCE | X86_CR4_OSFXSR  \
+			  | X86_CR4_OSXSAVE \
+			  | X86_CR4_OSXMMEXCPT | X86_CR4_VMXE))
+
+#define CR8_RESERVED_BITS (~(unsigned long)X86_CR8_TPR)
+
+
 
 #define INVALID_PAGE (~(hpa_t)0)
 #define VALID_PAGE(x) ((x) != INVALID_PAGE)
@@ -118,6 +134,9 @@
 enum kvm_reg_ex {
 	VCPU_EXREG_PDPTR = NR_VCPU_REGS,
 	VCPU_EXREG_CR3,
+	VCPU_EXREG_RFLAGS,
+	VCPU_EXREG_CPL,
+	VCPU_EXREG_SEGMENTS,
 };
 
 enum {
@@ -256,7 +275,7 @@
 			 struct kvm_mmu_page *sp);
 	void (*invlpg)(struct kvm_vcpu *vcpu, gva_t gva);
 	void (*update_pte)(struct kvm_vcpu *vcpu, struct kvm_mmu_page *sp,
-			u64 *spte, const void *pte, unsigned long mmu_seq);
+			   u64 *spte, const void *pte);
 	hpa_t root_hpa;
 	int root_level;
 	int shadow_root_level;
@@ -340,7 +359,6 @@
 	struct fpu guest_fpu;
 	u64 xcr0;
 
-	gva_t mmio_fault_cr2;
 	struct kvm_pio_request pio;
 	void *pio_data;
 
@@ -367,18 +385,22 @@
 	/* emulate context */
 
 	struct x86_emulate_ctxt emulate_ctxt;
+	bool emulate_regs_need_sync_to_vcpu;
+	bool emulate_regs_need_sync_from_vcpu;
 
 	gpa_t time;
 	struct pvclock_vcpu_time_info hv_clock;
 	unsigned int hw_tsc_khz;
 	unsigned int time_offset;
 	struct page *time_page;
-	u64 last_host_tsc;
 	u64 last_guest_tsc;
 	u64 last_kernel_ns;
 	u64 last_tsc_nsec;
 	u64 last_tsc_write;
+	u32 virtual_tsc_khz;
 	bool tsc_catchup;
+	u32  tsc_catchup_mult;
+	s8   tsc_catchup_shift;
 
 	bool nmi_pending;
 	bool nmi_injected;
@@ -448,9 +470,6 @@
 	u64 last_tsc_nsec;
 	u64 last_tsc_offset;
 	u64 last_tsc_write;
-	u32 virtual_tsc_khz;
-	u32 virtual_tsc_mult;
-	s8 virtual_tsc_shift;
 
 	struct kvm_xen_hvm_config xen_hvm_config;
 
@@ -502,6 +521,8 @@
 	u32 nmi_injections;
 };
 
+struct x86_instruction_info;
+
 struct kvm_x86_ops {
 	int (*cpu_has_kvm_support)(void);          /* __init */
 	int (*disabled_by_bios)(void);             /* __init */
@@ -586,9 +607,17 @@
 
 	bool (*has_wbinvd_exit)(void);
 
+	void (*set_tsc_khz)(struct kvm_vcpu *vcpu, u32 user_tsc_khz);
 	void (*write_tsc_offset)(struct kvm_vcpu *vcpu, u64 offset);
 
+	u64 (*compute_tsc_offset)(struct kvm_vcpu *vcpu, u64 target_tsc);
+
 	void (*get_exit_info)(struct kvm_vcpu *vcpu, u64 *info1, u64 *info2);
+
+	int (*check_intercept)(struct kvm_vcpu *vcpu,
+			       struct x86_instruction_info *info,
+			       enum x86_intercept_stage stage);
+
 	const struct trace_print_flags *exit_reasons_str;
 };
 
@@ -627,6 +656,13 @@
 
 extern bool tdp_enabled;
 
+/* control of guest tsc rate supported? */
+extern bool kvm_has_tsc_control;
+/* minimum supported tsc_khz for guests */
+extern u32  kvm_min_guest_tsc_khz;
+/* maximum supported tsc_khz for guests */
+extern u32  kvm_max_guest_tsc_khz;
+
 enum emulation_result {
 	EMULATE_DONE,       /* no further processing */
 	EMULATE_DO_MMIO,      /* kvm_run filled with mmio request */
@@ -645,9 +681,6 @@
 	return x86_emulate_instruction(vcpu, 0, emulation_type, NULL, 0);
 }
 
-void realmode_lgdt(struct kvm_vcpu *vcpu, u16 size, unsigned long address);
-void realmode_lidt(struct kvm_vcpu *vcpu, u16 size, unsigned long address);
-
 void kvm_enable_efer_bits(u64);
 int kvm_get_msr(struct kvm_vcpu *vcpu, u32 msr_index, u64 *data);
 int kvm_set_msr(struct kvm_vcpu *vcpu, u32 msr_index, u64 data);
@@ -657,8 +690,6 @@
 int kvm_fast_pio_out(struct kvm_vcpu *vcpu, int size, unsigned short port);
 void kvm_emulate_cpuid(struct kvm_vcpu *vcpu);
 int kvm_emulate_halt(struct kvm_vcpu *vcpu);
-int emulate_invlpg(struct kvm_vcpu *vcpu, gva_t address);
-int emulate_clts(struct kvm_vcpu *vcpu);
 int kvm_emulate_wbinvd(struct kvm_vcpu *vcpu);
 
 void kvm_get_segment(struct kvm_vcpu *vcpu, struct kvm_segment *var, int seg);
@@ -721,8 +752,6 @@
 
 int kvm_emulate_hypercall(struct kvm_vcpu *vcpu);
 
-int kvm_fix_hypercall(struct kvm_vcpu *vcpu);
-
 int kvm_mmu_page_fault(struct kvm_vcpu *vcpu, gva_t gva, u32 error_code,
 		       void *insn, int insn_len);
 void kvm_mmu_invlpg(struct kvm_vcpu *vcpu, gva_t gva);
diff -druN linux-2.6.39-libre/arch/x86/include/asm/linkage.h linux-3.0-rc7-libre/arch/x86/include/asm/linkage.h
--- linux-2.6.39-libre/arch/x86/include/asm/linkage.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/include/asm/linkage.h	2011-07-11 19:51:52.000000000 -0400
@@ -8,11 +8,6 @@
 
 #ifdef CONFIG_X86_32
 #define asmlinkage CPP_ASMLINKAGE __attribute__((regparm(0)))
-/*
- * For 32-bit UML - mark functions implemented in assembly that use
- * regparm input parameters:
- */
-#define asmregparm __attribute__((regparm(3)))
 
 /*
  * Make sure the compiler doesn't do anything stupid with the
diff -druN linux-2.6.39-libre/arch/x86/include/asm/mce.h linux-3.0-rc7-libre/arch/x86/include/asm/mce.h
--- linux-2.6.39-libre/arch/x86/include/asm/mce.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/include/asm/mce.h	2011-07-11 19:51:52.000000000 -0400
@@ -142,8 +142,6 @@
 static inline void enable_p5_mce(void) {}
 #endif
 
-extern void (*x86_mce_decode_callback)(struct mce *m);
-
 void mce_setup(struct mce *m);
 void mce_log(struct mce *m);
 DECLARE_PER_CPU(struct sys_device, mce_dev);
diff -druN linux-2.6.39-libre/arch/x86/include/asm/memblock.h linux-3.0-rc7-libre/arch/x86/include/asm/memblock.h
--- linux-2.6.39-libre/arch/x86/include/asm/memblock.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/include/asm/memblock.h	2011-07-11 19:51:52.000000000 -0400
@@ -4,7 +4,6 @@
 #define ARCH_DISCARD_MEMBLOCK
 
 u64 memblock_x86_find_in_range_size(u64 start, u64 *sizep, u64 align);
-void memblock_x86_to_bootmem(u64 start, u64 end);
 
 void memblock_x86_reserve_range(u64 start, u64 end, char *name);
 void memblock_x86_free_range(u64 start, u64 end);
@@ -19,5 +18,6 @@
 u64 memblock_x86_find_in_range_node(int nid, u64 start, u64 end, u64 size, u64 align);
 u64 memblock_x86_free_memory_in_range(u64 addr, u64 limit);
 u64 memblock_x86_memory_in_range(u64 addr, u64 limit);
+bool memblock_x86_check_reserved_size(u64 *addrp, u64 *sizep, u64 align);
 
 #endif
diff -druN linux-2.6.39-libre/arch/x86/include/asm/mmu.h linux-3.0-rc7-libre/arch/x86/include/asm/mmu.h
--- linux-2.6.39-libre/arch/x86/include/asm/mmu.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/include/asm/mmu.h	2011-07-11 19:51:52.000000000 -0400
@@ -11,14 +11,14 @@
 typedef struct {
 	void *ldt;
 	int size;
-	struct mutex lock;
-	void *vdso;
 
 #ifdef CONFIG_X86_64
 	/* True if mm supports a task running in 32 bit compatibility mode. */
 	unsigned short ia32_compat;
 #endif
 
+	struct mutex lock;
+	void *vdso;
 } mm_context_t;
 
 #ifdef CONFIG_SMP
diff -druN linux-2.6.39-libre/arch/x86/include/asm/mmzone_32.h linux-3.0-rc7-libre/arch/x86/include/asm/mmzone_32.h
--- linux-2.6.39-libre/arch/x86/include/asm/mmzone_32.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/include/asm/mmzone_32.h	2011-07-11 19:51:52.000000000 -0400
@@ -13,31 +13,11 @@
 #define NODE_DATA(nid)	(node_data[nid])
 
 #include <asm/numaq.h>
-/* summit or generic arch */
-#include <asm/srat.h>
-
-extern int get_memcfg_numa_flat(void);
-/*
- * This allows any one NUMA architecture to be compiled
- * for, and still fall back to the flat function if it
- * fails.
- */
-static inline void get_memcfg_numa(void)
-{
-
-	if (get_memcfg_numaq())
-		return;
-	if (get_memcfg_from_srat())
-		return;
-	get_memcfg_numa_flat();
-}
 
 extern void resume_map_numa_kva(pgd_t *pgd);
 
 #else /* !CONFIG_NUMA */
 
-#define get_memcfg_numa get_memcfg_numa_flat
-
 static inline void resume_map_numa_kva(pgd_t *pgd) {}
 
 #endif /* CONFIG_NUMA */
@@ -68,17 +48,6 @@
 #endif
 }
 
-/*
- * Following are macros that each numa implmentation must define.
- */
-
-#define node_start_pfn(nid)	(NODE_DATA(nid)->node_start_pfn)
-#define node_end_pfn(nid)						\
-({									\
-	pg_data_t *__pgdat = NODE_DATA(nid);				\
-	__pgdat->node_start_pfn + __pgdat->node_spanned_pages;		\
-})
-
 static inline int pfn_valid(int pfn)
 {
 	int nid = pfn_to_nid(pfn);
@@ -88,6 +57,8 @@
 	return 0;
 }
 
+#define early_pfn_valid(pfn)	pfn_valid((pfn))
+
 #endif /* CONFIG_DISCONTIGMEM */
 
 #ifdef CONFIG_NEED_MULTIPLE_NODES
diff -druN linux-2.6.39-libre/arch/x86/include/asm/mmzone_64.h linux-3.0-rc7-libre/arch/x86/include/asm/mmzone_64.h
--- linux-2.6.39-libre/arch/x86/include/asm/mmzone_64.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/include/asm/mmzone_64.h	2011-07-11 19:51:52.000000000 -0400
@@ -4,40 +4,14 @@
 #ifndef _ASM_X86_MMZONE_64_H
 #define _ASM_X86_MMZONE_64_H
 
-
 #ifdef CONFIG_NUMA
 
 #include <linux/mmdebug.h>
-
 #include <asm/smp.h>
 
-/* Simple perfect hash to map physical addresses to node numbers */
-struct memnode {
-	int shift;
-	unsigned int mapsize;
-	s16 *map;
-	s16 embedded_map[64 - 8];
-} ____cacheline_aligned; /* total size = 128 bytes */
-extern struct memnode memnode;
-#define memnode_shift memnode.shift
-#define memnodemap memnode.map
-#define memnodemapsize memnode.mapsize
-
 extern struct pglist_data *node_data[];
 
-static inline __attribute__((pure)) int phys_to_nid(unsigned long addr)
-{
-	unsigned nid;
-	VIRTUAL_BUG_ON(!memnodemap);
-	nid = memnodemap[addr >> memnode_shift];
-	VIRTUAL_BUG_ON(nid >= MAX_NUMNODES || !node_data[nid]);
-	return nid;
-}
-
 #define NODE_DATA(nid)		(node_data[nid])
 
-#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)
 #endif
 #endif /* _ASM_X86_MMZONE_64_H */
diff -druN linux-2.6.39-libre/arch/x86/include/asm/module.h linux-3.0-rc7-libre/arch/x86/include/asm/module.h
--- linux-2.6.39-libre/arch/x86/include/asm/module.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/include/asm/module.h	2011-07-11 19:51:52.000000000 -0400
@@ -35,7 +35,7 @@
 #define MODULE_PROC_FAMILY "K7 "
 #elif defined CONFIG_MK8
 #define MODULE_PROC_FAMILY "K8 "
-#elif defined CONFIG_X86_ELAN
+#elif defined CONFIG_MELAN
 #define MODULE_PROC_FAMILY "ELAN "
 #elif defined CONFIG_MCRUSOE
 #define MODULE_PROC_FAMILY "CRUSOE "
diff -druN linux-2.6.39-libre/arch/x86/include/asm/msr-index.h linux-3.0-rc7-libre/arch/x86/include/asm/msr-index.h
--- linux-2.6.39-libre/arch/x86/include/asm/msr-index.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/include/asm/msr-index.h	2011-07-11 19:51:52.000000000 -0400
@@ -118,6 +118,7 @@
    complete list. */
 
 #define MSR_AMD64_PATCH_LEVEL		0x0000008b
+#define MSR_AMD64_TSC_RATIO		0xc0000104
 #define MSR_AMD64_NB_CFG		0xc001001f
 #define MSR_AMD64_PATCH_LOADER		0xc0010020
 #define MSR_AMD64_OSVW_ID_LENGTH	0xc0010140
diff -druN linux-2.6.39-libre/arch/x86/include/asm/nops.h linux-3.0-rc7-libre/arch/x86/include/asm/nops.h
--- linux-2.6.39-libre/arch/x86/include/asm/nops.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/include/asm/nops.h	2011-07-11 19:51:52.000000000 -0400
@@ -1,7 +1,13 @@
 #ifndef _ASM_X86_NOPS_H
 #define _ASM_X86_NOPS_H
 
-/* Define nops for use with alternative() */
+/*
+ * Define nops for use with alternative() and for tracing.
+ *
+ * *_NOP5_ATOMIC must be a single instruction.
+ */
+
+#define NOP_DS_PREFIX 0x3e
 
 /* generic versions from gas
    1: nop
@@ -13,14 +19,15 @@
    6: leal 0x00000000(%esi),%esi
    7: leal 0x00000000(,%esi,1),%esi
 */
-#define GENERIC_NOP1 ".byte 0x90\n"
-#define GENERIC_NOP2 ".byte 0x89,0xf6\n"
-#define GENERIC_NOP3 ".byte 0x8d,0x76,0x00\n"
-#define GENERIC_NOP4 ".byte 0x8d,0x74,0x26,0x00\n"
-#define GENERIC_NOP5 GENERIC_NOP1 GENERIC_NOP4
-#define GENERIC_NOP6 ".byte 0x8d,0xb6,0x00,0x00,0x00,0x00\n"
-#define GENERIC_NOP7 ".byte 0x8d,0xb4,0x26,0x00,0x00,0x00,0x00\n"
-#define GENERIC_NOP8 GENERIC_NOP1 GENERIC_NOP7
+#define GENERIC_NOP1 0x90
+#define GENERIC_NOP2 0x89,0xf6
+#define GENERIC_NOP3 0x8d,0x76,0x00
+#define GENERIC_NOP4 0x8d,0x74,0x26,0x00
+#define GENERIC_NOP5 GENERIC_NOP1,GENERIC_NOP4
+#define GENERIC_NOP6 0x8d,0xb6,0x00,0x00,0x00,0x00
+#define GENERIC_NOP7 0x8d,0xb4,0x26,0x00,0x00,0x00,0x00
+#define GENERIC_NOP8 GENERIC_NOP1,GENERIC_NOP7
+#define GENERIC_NOP5_ATOMIC NOP_DS_PREFIX,GENERIC_NOP4
 
 /* Opteron 64bit nops
    1: nop
@@ -29,13 +36,14 @@
    4: osp osp osp nop
 */
 #define K8_NOP1 GENERIC_NOP1
-#define K8_NOP2	".byte 0x66,0x90\n"
-#define K8_NOP3	".byte 0x66,0x66,0x90\n"
-#define K8_NOP4	".byte 0x66,0x66,0x66,0x90\n"
-#define K8_NOP5	K8_NOP3 K8_NOP2
-#define K8_NOP6	K8_NOP3 K8_NOP3
-#define K8_NOP7	K8_NOP4 K8_NOP3
-#define K8_NOP8	K8_NOP4 K8_NOP4
+#define K8_NOP2	0x66,K8_NOP1
+#define K8_NOP3	0x66,K8_NOP2
+#define K8_NOP4	0x66,K8_NOP3
+#define K8_NOP5	K8_NOP3,K8_NOP2
+#define K8_NOP6	K8_NOP3,K8_NOP3
+#define K8_NOP7	K8_NOP4,K8_NOP3
+#define K8_NOP8	K8_NOP4,K8_NOP4
+#define K8_NOP5_ATOMIC 0x66,K8_NOP4
 
 /* K7 nops
    uses eax dependencies (arbitrary choice)
@@ -47,13 +55,14 @@
    7: leal 0x00000000(,%eax,1),%eax
 */
 #define K7_NOP1	GENERIC_NOP1
-#define K7_NOP2	".byte 0x8b,0xc0\n"
-#define K7_NOP3	".byte 0x8d,0x04,0x20\n"
-#define K7_NOP4	".byte 0x8d,0x44,0x20,0x00\n"
-#define K7_NOP5	K7_NOP4 ASM_NOP1
-#define K7_NOP6	".byte 0x8d,0x80,0,0,0,0\n"
-#define K7_NOP7	".byte 0x8D,0x04,0x05,0,0,0,0\n"
-#define K7_NOP8	K7_NOP7 ASM_NOP1
+#define K7_NOP2	0x8b,0xc0
+#define K7_NOP3	0x8d,0x04,0x20
+#define K7_NOP4	0x8d,0x44,0x20,0x00
+#define K7_NOP5	K7_NOP4,K7_NOP1
+#define K7_NOP6	0x8d,0x80,0,0,0,0
+#define K7_NOP7	0x8D,0x04,0x05,0,0,0,0
+#define K7_NOP8	K7_NOP7,K7_NOP1
+#define K7_NOP5_ATOMIC NOP_DS_PREFIX,K7_NOP4
 
 /* P6 nops
    uses eax dependencies (Intel-recommended choice)
@@ -69,52 +78,65 @@
 	There is kernel code that depends on this.
 */
 #define P6_NOP1	GENERIC_NOP1
-#define P6_NOP2	".byte 0x66,0x90\n"
-#define P6_NOP3	".byte 0x0f,0x1f,0x00\n"
-#define P6_NOP4	".byte 0x0f,0x1f,0x40,0\n"
-#define P6_NOP5	".byte 0x0f,0x1f,0x44,0x00,0\n"
-#define P6_NOP6	".byte 0x66,0x0f,0x1f,0x44,0x00,0\n"
-#define P6_NOP7	".byte 0x0f,0x1f,0x80,0,0,0,0\n"
-#define P6_NOP8	".byte 0x0f,0x1f,0x84,0x00,0,0,0,0\n"
+#define P6_NOP2	0x66,0x90
+#define P6_NOP3	0x0f,0x1f,0x00
+#define P6_NOP4	0x0f,0x1f,0x40,0
+#define P6_NOP5	0x0f,0x1f,0x44,0x00,0
+#define P6_NOP6	0x66,0x0f,0x1f,0x44,0x00,0
+#define P6_NOP7	0x0f,0x1f,0x80,0,0,0,0
+#define P6_NOP8	0x0f,0x1f,0x84,0x00,0,0,0,0
+#define P6_NOP5_ATOMIC P6_NOP5
+
+#define _ASM_MK_NOP(x) ".byte " __stringify(x) "\n"
 
 #if defined(CONFIG_MK7)
-#define ASM_NOP1 K7_NOP1
-#define ASM_NOP2 K7_NOP2
-#define ASM_NOP3 K7_NOP3
-#define ASM_NOP4 K7_NOP4
-#define ASM_NOP5 K7_NOP5
-#define ASM_NOP6 K7_NOP6
-#define ASM_NOP7 K7_NOP7
-#define ASM_NOP8 K7_NOP8
+#define ASM_NOP1 _ASM_MK_NOP(K7_NOP1)
+#define ASM_NOP2 _ASM_MK_NOP(K7_NOP2)
+#define ASM_NOP3 _ASM_MK_NOP(K7_NOP3)
+#define ASM_NOP4 _ASM_MK_NOP(K7_NOP4)
+#define ASM_NOP5 _ASM_MK_NOP(K7_NOP5)
+#define ASM_NOP6 _ASM_MK_NOP(K7_NOP6)
+#define ASM_NOP7 _ASM_MK_NOP(K7_NOP7)
+#define ASM_NOP8 _ASM_MK_NOP(K7_NOP8)
+#define ASM_NOP5_ATOMIC _ASM_MK_NOP(K7_NOP5_ATOMIC)
 #elif defined(CONFIG_X86_P6_NOP)
-#define ASM_NOP1 P6_NOP1
-#define ASM_NOP2 P6_NOP2
-#define ASM_NOP3 P6_NOP3
-#define ASM_NOP4 P6_NOP4
-#define ASM_NOP5 P6_NOP5
-#define ASM_NOP6 P6_NOP6
-#define ASM_NOP7 P6_NOP7
-#define ASM_NOP8 P6_NOP8
+#define ASM_NOP1 _ASM_MK_NOP(P6_NOP1)
+#define ASM_NOP2 _ASM_MK_NOP(P6_NOP2)
+#define ASM_NOP3 _ASM_MK_NOP(P6_NOP3)
+#define ASM_NOP4 _ASM_MK_NOP(P6_NOP4)
+#define ASM_NOP5 _ASM_MK_NOP(P6_NOP5)
+#define ASM_NOP6 _ASM_MK_NOP(P6_NOP6)
+#define ASM_NOP7 _ASM_MK_NOP(P6_NOP7)
+#define ASM_NOP8 _ASM_MK_NOP(P6_NOP8)
+#define ASM_NOP5_ATOMIC _ASM_MK_NOP(P6_NOP5_ATOMIC)
 #elif defined(CONFIG_X86_64)
-#define ASM_NOP1 K8_NOP1
-#define ASM_NOP2 K8_NOP2
-#define ASM_NOP3 K8_NOP3
-#define ASM_NOP4 K8_NOP4
-#define ASM_NOP5 K8_NOP5
-#define ASM_NOP6 K8_NOP6
-#define ASM_NOP7 K8_NOP7
-#define ASM_NOP8 K8_NOP8
+#define ASM_NOP1 _ASM_MK_NOP(K8_NOP1)
+#define ASM_NOP2 _ASM_MK_NOP(K8_NOP2)
+#define ASM_NOP3 _ASM_MK_NOP(K8_NOP3)
+#define ASM_NOP4 _ASM_MK_NOP(K8_NOP4)
+#define ASM_NOP5 _ASM_MK_NOP(K8_NOP5)
+#define ASM_NOP6 _ASM_MK_NOP(K8_NOP6)
+#define ASM_NOP7 _ASM_MK_NOP(K8_NOP7)
+#define ASM_NOP8 _ASM_MK_NOP(K8_NOP8)
+#define ASM_NOP5_ATOMIC _ASM_MK_NOP(K8_NOP5_ATOMIC)
 #else
-#define ASM_NOP1 GENERIC_NOP1
-#define ASM_NOP2 GENERIC_NOP2
-#define ASM_NOP3 GENERIC_NOP3
-#define ASM_NOP4 GENERIC_NOP4
-#define ASM_NOP5 GENERIC_NOP5
-#define ASM_NOP6 GENERIC_NOP6
-#define ASM_NOP7 GENERIC_NOP7
-#define ASM_NOP8 GENERIC_NOP8
+#define ASM_NOP1 _ASM_MK_NOP(GENERIC_NOP1)
+#define ASM_NOP2 _ASM_MK_NOP(GENERIC_NOP2)
+#define ASM_NOP3 _ASM_MK_NOP(GENERIC_NOP3)
+#define ASM_NOP4 _ASM_MK_NOP(GENERIC_NOP4)
+#define ASM_NOP5 _ASM_MK_NOP(GENERIC_NOP5)
+#define ASM_NOP6 _ASM_MK_NOP(GENERIC_NOP6)
+#define ASM_NOP7 _ASM_MK_NOP(GENERIC_NOP7)
+#define ASM_NOP8 _ASM_MK_NOP(GENERIC_NOP8)
+#define ASM_NOP5_ATOMIC _ASM_MK_NOP(GENERIC_NOP5_ATOMIC)
 #endif
 
 #define ASM_NOP_MAX 8
+#define NOP_ATOMIC5 (ASM_NOP_MAX+1)	/* Entry for the 5-byte atomic NOP */
+
+#ifndef __ASSEMBLY__
+extern const unsigned char * const *ideal_nops;
+extern void arch_init_ideal_nops(void);
+#endif
 
 #endif /* _ASM_X86_NOPS_H */
diff -druN linux-2.6.39-libre/arch/x86/include/asm/numa_32.h linux-3.0-rc7-libre/arch/x86/include/asm/numa_32.h
--- linux-2.6.39-libre/arch/x86/include/asm/numa_32.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/include/asm/numa_32.h	2011-07-11 19:51:52.000000000 -0400
@@ -1,16 +1,6 @@
 #ifndef _ASM_X86_NUMA_32_H
 #define _ASM_X86_NUMA_32_H
 
-extern int numa_off;
-
-extern int pxm_to_nid(int pxm);
-
-#ifdef CONFIG_NUMA
-extern int __cpuinit numa_cpu_node(int cpu);
-#else	/* CONFIG_NUMA */
-static inline int numa_cpu_node(int cpu)		{ return NUMA_NO_NODE; }
-#endif	/* CONFIG_NUMA */
-
 #ifdef CONFIG_HIGHMEM
 extern void set_highmem_pages_init(void);
 #else
diff -druN linux-2.6.39-libre/arch/x86/include/asm/numa_64.h linux-3.0-rc7-libre/arch/x86/include/asm/numa_64.h
--- linux-2.6.39-libre/arch/x86/include/asm/numa_64.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/include/asm/numa_64.h	2011-07-11 19:51:52.000000000 -0400
@@ -1,42 +1,6 @@
 #ifndef _ASM_X86_NUMA_64_H
 #define _ASM_X86_NUMA_64_H
 
-#include <linux/nodemask.h>
-
-struct bootnode {
-	u64 start;
-	u64 end;
-};
-
-#define ZONE_ALIGN (1UL << (MAX_ORDER+PAGE_SHIFT))
-
-extern int numa_off;
-
 extern unsigned long numa_free_all_bootmem(void);
-extern void setup_node_bootmem(int nodeid, unsigned long start,
-			       unsigned long end);
-
-#ifdef CONFIG_NUMA
-/*
- * Too small node sizes may confuse the VM badly. Usually they
- * result from BIOS bugs. So dont recognize nodes as standalone
- * NUMA entities that have less than this amount of RAM listed:
- */
-#define NODE_MIN_SIZE (4*1024*1024)
-
-extern nodemask_t numa_nodes_parsed __initdata;
-
-extern int __cpuinit numa_cpu_node(int cpu);
-extern int __init numa_add_memblk(int nodeid, u64 start, u64 end);
-extern void __init numa_set_distance(int from, int to, int distance);
-
-#ifdef CONFIG_NUMA_EMU
-#define FAKE_NODE_MIN_SIZE	((u64)32 << 20)
-#define FAKE_NODE_MIN_HASH_MASK	(~(FAKE_NODE_MIN_SIZE - 1UL))
-void numa_emu_cmdline(char *);
-#endif /* CONFIG_NUMA_EMU */
-#else
-static inline int numa_cpu_node(int cpu)		{ return NUMA_NO_NODE; }
-#endif
 
 #endif /* _ASM_X86_NUMA_64_H */
diff -druN linux-2.6.39-libre/arch/x86/include/asm/numa.h linux-3.0-rc7-libre/arch/x86/include/asm/numa.h
--- linux-2.6.39-libre/arch/x86/include/asm/numa.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/include/asm/numa.h	2011-07-11 19:51:52.000000000 -0400
@@ -1,12 +1,24 @@
 #ifndef _ASM_X86_NUMA_H
 #define _ASM_X86_NUMA_H
 
+#include <linux/nodemask.h>
+
 #include <asm/topology.h>
 #include <asm/apicdef.h>
 
 #ifdef CONFIG_NUMA
 
 #define NR_NODE_MEMBLKS		(MAX_NUMNODES*2)
+#define ZONE_ALIGN (1UL << (MAX_ORDER+PAGE_SHIFT))
+
+/*
+ * Too small node sizes may confuse the VM badly. Usually they
+ * result from BIOS bugs. So dont recognize nodes as standalone
+ * NUMA entities that have less than this amount of RAM listed:
+ */
+#define NODE_MIN_SIZE (4*1024*1024)
+
+extern int numa_off;
 
 /*
  * __apicid_to_node[] stores the raw mapping between physical apicid and
@@ -17,15 +29,27 @@
  * numa_cpu_node().
  */
 extern s16 __apicid_to_node[MAX_LOCAL_APIC];
+extern nodemask_t numa_nodes_parsed __initdata;
+
+extern int __init numa_add_memblk(int nodeid, u64 start, u64 end);
+extern void __init numa_set_distance(int from, int to, int distance);
 
 static inline void set_apicid_to_node(int apicid, s16 node)
 {
 	__apicid_to_node[apicid] = node;
 }
+
+extern int __cpuinit numa_cpu_node(int cpu);
+
 #else	/* CONFIG_NUMA */
 static inline void set_apicid_to_node(int apicid, s16 node)
 {
 }
+
+static inline int numa_cpu_node(int cpu)
+{
+	return NUMA_NO_NODE;
+}
 #endif	/* CONFIG_NUMA */
 
 #ifdef CONFIG_X86_32
@@ -37,14 +61,12 @@
 #ifdef CONFIG_NUMA
 extern void __cpuinit numa_set_node(int cpu, int node);
 extern void __cpuinit numa_clear_node(int cpu);
-extern void __init numa_init_array(void);
 extern void __init init_cpu_to_node(void);
 extern void __cpuinit numa_add_cpu(int cpu);
 extern void __cpuinit numa_remove_cpu(int cpu);
 #else	/* CONFIG_NUMA */
 static inline void numa_set_node(int cpu, int node)	{ }
 static inline void numa_clear_node(int cpu)		{ }
-static inline void numa_init_array(void)		{ }
 static inline void init_cpu_to_node(void)		{ }
 static inline void numa_add_cpu(int cpu)		{ }
 static inline void numa_remove_cpu(int cpu)		{ }
@@ -54,4 +76,10 @@
 void debug_cpumask_set_cpu(int cpu, int node, bool enable);
 #endif
 
+#ifdef CONFIG_NUMA_EMU
+#define FAKE_NODE_MIN_SIZE	((u64)32 << 20)
+#define FAKE_NODE_MIN_HASH_MASK	(~(FAKE_NODE_MIN_SIZE - 1UL))
+void numa_emu_cmdline(char *);
+#endif /* CONFIG_NUMA_EMU */
+
 #endif	/* _ASM_X86_NUMA_H */
diff -druN linux-2.6.39-libre/arch/x86/include/asm/numaq.h linux-3.0-rc7-libre/arch/x86/include/asm/numaq.h
--- linux-2.6.39-libre/arch/x86/include/asm/numaq.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/include/asm/numaq.h	2011-07-11 19:51:52.000000000 -0400
@@ -29,7 +29,7 @@
 #ifdef CONFIG_X86_NUMAQ
 
 extern int found_numaq;
-extern int get_memcfg_numaq(void);
+extern int numaq_numa_init(void);
 extern int pci_numaq_init(void);
 
 extern void *xquad_portio;
@@ -166,11 +166,6 @@
 
 void numaq_tsc_disable(void);
 
-#else
-static inline int get_memcfg_numaq(void)
-{
-	return 0;
-}
 #endif /* CONFIG_X86_NUMAQ */
 #endif /* _ASM_X86_NUMAQ_H */
 
diff -druN linux-2.6.39-libre/arch/x86/include/asm/olpc_ofw.h linux-3.0-rc7-libre/arch/x86/include/asm/olpc_ofw.h
--- linux-2.6.39-libre/arch/x86/include/asm/olpc_ofw.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/include/asm/olpc_ofw.h	2011-07-11 19:51:52.000000000 -0400
@@ -26,15 +26,12 @@
 /* check if OFW was detected during boot */
 extern bool olpc_ofw_present(void);
 
+extern void olpc_dt_build_devicetree(void);
+
 #else /* !CONFIG_OLPC */
 static inline void olpc_ofw_detect(void) { }
 static inline void setup_olpc_ofw_pgd(void) { }
-#endif /* !CONFIG_OLPC */
-
-#ifdef CONFIG_OF_PROMTREE
-extern void olpc_dt_build_devicetree(void);
-#else
 static inline void olpc_dt_build_devicetree(void) { }
-#endif
+#endif /* !CONFIG_OLPC */
 
 #endif /* _ASM_X86_OLPC_OFW_H */
diff -druN linux-2.6.39-libre/arch/x86/include/asm/pci.h linux-3.0-rc7-libre/arch/x86/include/asm/pci.h
--- linux-2.6.39-libre/arch/x86/include/asm/pci.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/include/asm/pci.h	2011-07-11 19:51:52.000000000 -0400
@@ -135,8 +135,6 @@
 #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 -druN linux-2.6.39-libre/arch/x86/include/asm/percpu.h linux-3.0-rc7-libre/arch/x86/include/asm/percpu.h
--- linux-2.6.39-libre/arch/x86/include/asm/percpu.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/include/asm/percpu.h	2011-07-11 19:51:52.000000000 -0400
@@ -509,6 +509,11 @@
  * it in software.  The address used in the cmpxchg16 instruction must be
  * aligned to a 16 byte boundary.
  */
+#ifdef CONFIG_SMP
+#define CMPXCHG16B_EMU_CALL "call this_cpu_cmpxchg16b_emu\n\t" ASM_NOP3
+#else
+#define CMPXCHG16B_EMU_CALL "call this_cpu_cmpxchg16b_emu\n\t" ASM_NOP2
+#endif
 #define percpu_cmpxchg16b_double(pcp1, o1, o2, n1, n2)			\
 ({									\
 	char __ret;							\
@@ -517,7 +522,7 @@
 	typeof(o2) __o2 = o2;						\
 	typeof(o2) __n2 = n2;						\
 	typeof(o2) __dummy;						\
-	alternative_io("call this_cpu_cmpxchg16b_emu\n\t" P6_NOP4,	\
+	alternative_io(CMPXCHG16B_EMU_CALL,				\
 		       "cmpxchg16b " __percpu_prefix "(%%rsi)\n\tsetz %0\n\t",	\
 		       X86_FEATURE_CX16,				\
 		       ASM_OUTPUT2("=a"(__ret), "=d"(__dummy)),		\
@@ -542,6 +547,33 @@
 	old__;								\
 })
 
+static __always_inline int x86_this_cpu_constant_test_bit(unsigned int nr,
+                        const unsigned long __percpu *addr)
+{
+	unsigned long __percpu *a = (unsigned long *)addr + nr / BITS_PER_LONG;
+
+	return ((1UL << (nr % BITS_PER_LONG)) & percpu_read(*a)) != 0;
+}
+
+static inline int x86_this_cpu_variable_test_bit(int nr,
+                        const unsigned long __percpu *addr)
+{
+	int oldbit;
+
+	asm volatile("bt "__percpu_arg(2)",%1\n\t"
+			"sbb %0,%0"
+			: "=r" (oldbit)
+			: "m" (*(unsigned long *)addr), "Ir" (nr));
+
+	return oldbit;
+}
+
+#define x86_this_cpu_test_bit(nr, addr)			\
+	(__builtin_constant_p((nr))			\
+	 ? x86_this_cpu_constant_test_bit((nr), (addr))	\
+	 : x86_this_cpu_variable_test_bit((nr), (addr)))
+
+
 #include <asm-generic/percpu.h>
 
 /* We can use this directly for local CPU (faster). */
diff -druN linux-2.6.39-libre/arch/x86/include/asm/probe_roms.h linux-3.0-rc7-libre/arch/x86/include/asm/probe_roms.h
--- linux-2.6.39-libre/arch/x86/include/asm/probe_roms.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/x86/include/asm/probe_roms.h	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,8 @@
+#ifndef _PROBE_ROMS_H_
+#define _PROBE_ROMS_H_
+struct pci_dev;
+
+extern void __iomem *pci_map_biosrom(struct pci_dev *pdev);
+extern void pci_unmap_biosrom(void __iomem *rom);
+extern size_t pci_biosrom_size(struct pci_dev *pdev);
+#endif
diff -druN linux-2.6.39-libre/arch/x86/include/asm/processor-flags.h linux-3.0-rc7-libre/arch/x86/include/asm/processor-flags.h
--- linux-2.6.39-libre/arch/x86/include/asm/processor-flags.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/include/asm/processor-flags.h	2011-07-11 19:51:52.000000000 -0400
@@ -60,6 +60,7 @@
 #define X86_CR4_OSXMMEXCPT 0x00000400 /* enable unmasked SSE exceptions */
 #define X86_CR4_VMXE	0x00002000 /* enable VMX virtualization */
 #define X86_CR4_OSXSAVE 0x00040000 /* enable xsave and xrestore */
+#define X86_CR4_SMEP	0x00100000 /* enable SMEP support */
 
 /*
  * x86-64 Task Priority Register, CR8
diff -druN linux-2.6.39-libre/arch/x86/include/asm/processor.h linux-3.0-rc7-libre/arch/x86/include/asm/processor.h
--- linux-2.6.39-libre/arch/x86/include/asm/processor.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/include/asm/processor.h	2011-07-11 19:51:52.000000000 -0400
@@ -754,10 +754,10 @@
 extern void mwait_idle_with_hints(unsigned long eax, unsigned long ecx);
 
 extern void select_idle_routine(const struct cpuinfo_x86 *c);
-extern void init_c1e_mask(void);
+extern void init_amd_e400_c1e_mask(void);
 
 extern unsigned long		boot_option_idle_override;
-extern bool			c1e_detected;
+extern bool			amd_e400_c1e_detected;
 
 enum idle_boot_override {IDLE_NO_OVERRIDE=0, IDLE_HALT, IDLE_NOMWAIT,
 			 IDLE_POLL, IDLE_FORCE_MWAIT};
diff -druN linux-2.6.39-libre/arch/x86/include/asm/ptrace.h linux-3.0-rc7-libre/arch/x86/include/asm/ptrace.h
--- linux-2.6.39-libre/arch/x86/include/asm/ptrace.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/include/asm/ptrace.h	2011-07-11 19:51:52.000000000 -0400
@@ -136,6 +136,7 @@
 struct task_struct;
 
 extern unsigned long profile_pc(struct pt_regs *regs);
+#define profile_pc profile_pc
 
 extern unsigned long
 convert_ip_to_linear(struct task_struct *child, struct pt_regs *regs);
@@ -202,20 +203,11 @@
 #endif
 }
 
-static inline unsigned long instruction_pointer(struct pt_regs *regs)
-{
-	return regs->ip;
-}
-
-static inline unsigned long frame_pointer(struct pt_regs *regs)
-{
-	return regs->bp;
-}
+#define GET_IP(regs) ((regs)->ip)
+#define GET_FP(regs) ((regs)->bp)
+#define GET_USP(regs) ((regs)->sp)
 
-static inline unsigned long user_stack_pointer(struct pt_regs *regs)
-{
-	return regs->sp;
-}
+#include <asm-generic/ptrace.h>
 
 /* Query offset/name of register from its name/offset */
 extern int regs_query_register_offset(const char *name);
diff -druN linux-2.6.39-libre/arch/x86/include/asm/pvclock.h linux-3.0-rc7-libre/arch/x86/include/asm/pvclock.h
--- linux-2.6.39-libre/arch/x86/include/asm/pvclock.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/include/asm/pvclock.h	2011-07-11 19:51:52.000000000 -0400
@@ -22,6 +22,8 @@
 	u64 product;
 #ifdef __i386__
 	u32 tmp1, tmp2;
+#else
+	ulong tmp;
 #endif
 
 	if (shift < 0)
@@ -42,8 +44,11 @@
 		: "a" ((u32)delta), "1" ((u32)(delta >> 32)), "2" (mul_frac) );
 #elif defined(__x86_64__)
 	__asm__ (
-		"mul %%rdx ; shrd $32,%%rdx,%%rax"
-		: "=a" (product) : "0" (delta), "d" ((u64)mul_frac) );
+		"mul %[mul_frac] ; shrd $32, %[hi], %[lo]"
+		: [lo]"=a"(product),
+		  [hi]"=d"(tmp)
+		: "0"(delta),
+		  [mul_frac]"rm"((u64)mul_frac));
 #else
 #error implement me!
 #endif
diff -druN linux-2.6.39-libre/arch/x86/include/asm/setup.h linux-3.0-rc7-libre/arch/x86/include/asm/setup.h
--- linux-2.6.39-libre/arch/x86/include/asm/setup.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/include/asm/setup.h	2011-07-11 19:51:52.000000000 -0400
@@ -88,7 +88,7 @@
  * executable.)
  */
 #define RESERVE_BRK(name,sz)						\
-	static void __section(.discard.text) __used			\
+	static void __section(.discard.text) __used notrace		\
 	__brk_reservation_fn_##name##__(void) {				\
 		asm volatile (						\
 			".pushsection .brk_reservation,\"aw\",@nobits;" \
@@ -104,10 +104,10 @@
 	type *name;					\
 	RESERVE_BRK(name, sizeof(type) * entries)
 
+extern void probe_roms(void);
 #ifdef __i386__
 
 void __init i386_start_kernel(void);
-extern void probe_roms(void);
 
 #else
 void __init x86_64_start_kernel(char *real_mode);
diff -druN linux-2.6.39-libre/arch/x86/include/asm/srat.h linux-3.0-rc7-libre/arch/x86/include/asm/srat.h
--- linux-2.6.39-libre/arch/x86/include/asm/srat.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/include/asm/srat.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,39 +0,0 @@
-/*
- * Some of the code in this file has been gleaned from the 64 bit
- * discontigmem support code base.
- *
- * Copyright (C) 2002, IBM Corp.
- *
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
- * NON INFRINGEMENT.  See the GNU General Public License for more
- * details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * Send feedback to Pat Gaughen <gone@us.ibm.com>
- */
-
-#ifndef _ASM_X86_SRAT_H
-#define _ASM_X86_SRAT_H
-
-#ifdef CONFIG_ACPI_NUMA
-extern int get_memcfg_from_srat(void);
-#else
-static inline int get_memcfg_from_srat(void)
-{
-	return 0;
-}
-#endif
-
-#endif /* _ASM_X86_SRAT_H */
diff -druN linux-2.6.39-libre/arch/x86/include/asm/stacktrace.h linux-3.0-rc7-libre/arch/x86/include/asm/stacktrace.h
--- linux-2.6.39-libre/arch/x86/include/asm/stacktrace.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/include/asm/stacktrace.h	2011-07-11 19:51:52.000000000 -0400
@@ -37,9 +37,6 @@
 /* Generic stack tracer with callbacks */
 
 struct stacktrace_ops {
-	void (*warning)(void *data, char *msg);
-	/* msg must contain %s for the symbol */
-	void (*warning_symbol)(void *data, char *msg, unsigned long symbol);
 	void (*address)(void *data, unsigned long address, int reliable);
 	/* On negative return stop dumping */
 	int (*stack)(void *data, char *name);
diff -druN linux-2.6.39-libre/arch/x86/include/asm/suspend_32.h linux-3.0-rc7-libre/arch/x86/include/asm/suspend_32.h
--- linux-2.6.39-libre/arch/x86/include/asm/suspend_32.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/include/asm/suspend_32.h	2011-07-11 19:51:52.000000000 -0400
@@ -9,8 +9,6 @@
 #include <asm/desc.h>
 #include <asm/i387.h>
 
-static inline int arch_prepare_suspend(void) { return 0; }
-
 /* image of the saved processor state */
 struct saved_context {
 	u16 es, fs, gs, ss;
diff -druN linux-2.6.39-libre/arch/x86/include/asm/suspend_64.h linux-3.0-rc7-libre/arch/x86/include/asm/suspend_64.h
--- linux-2.6.39-libre/arch/x86/include/asm/suspend_64.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/include/asm/suspend_64.h	2011-07-11 19:51:52.000000000 -0400
@@ -9,11 +9,6 @@
 #include <asm/desc.h>
 #include <asm/i387.h>
 
-static inline int arch_prepare_suspend(void)
-{
-	return 0;
-}
-
 /*
  * Image of the saved processor state, used by the low level ACPI suspend to
  * RAM code and by the low level hibernation code.
diff -druN linux-2.6.39-libre/arch/x86/include/asm/system.h linux-3.0-rc7-libre/arch/x86/include/asm/system.h
--- linux-2.6.39-libre/arch/x86/include/asm/system.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/include/asm/system.h	2011-07-11 19:51:52.000000000 -0400
@@ -303,24 +303,81 @@
 #ifdef CONFIG_PARAVIRT
 #include <asm/paravirt.h>
 #else
-#define read_cr0()	(native_read_cr0())
-#define write_cr0(x)	(native_write_cr0(x))
-#define read_cr2()	(native_read_cr2())
-#define write_cr2(x)	(native_write_cr2(x))
-#define read_cr3()	(native_read_cr3())
-#define write_cr3(x)	(native_write_cr3(x))
-#define read_cr4()	(native_read_cr4())
-#define read_cr4_safe()	(native_read_cr4_safe())
-#define write_cr4(x)	(native_write_cr4(x))
-#define wbinvd()	(native_wbinvd())
+
+static inline unsigned long read_cr0(void)
+{
+	return native_read_cr0();
+}
+
+static inline void write_cr0(unsigned long x)
+{
+	native_write_cr0(x);
+}
+
+static inline unsigned long read_cr2(void)
+{
+	return native_read_cr2();
+}
+
+static inline void write_cr2(unsigned long x)
+{
+	native_write_cr2(x);
+}
+
+static inline unsigned long read_cr3(void)
+{
+	return native_read_cr3();
+}
+
+static inline void write_cr3(unsigned long x)
+{
+	native_write_cr3(x);
+}
+
+static inline unsigned long read_cr4(void)
+{
+	return native_read_cr4();
+}
+
+static inline unsigned long read_cr4_safe(void)
+{
+	return native_read_cr4_safe();
+}
+
+static inline void write_cr4(unsigned long x)
+{
+	native_write_cr4(x);
+}
+
+static inline void wbinvd(void)
+{
+	native_wbinvd();
+}
+
 #ifdef CONFIG_X86_64
-#define read_cr8()	(native_read_cr8())
-#define write_cr8(x)	(native_write_cr8(x))
-#define load_gs_index   native_load_gs_index
+
+static inline unsigned long read_cr8(void)
+{
+	return native_read_cr8();
+}
+
+static inline void write_cr8(unsigned long x)
+{
+	native_write_cr8(x);
+}
+
+static inline void load_gs_index(unsigned selector)
+{
+	native_load_gs_index(selector);
+}
+
 #endif
 
 /* Clear the 'TS' bit */
-#define clts()		(native_clts())
+static inline void clts(void)
+{
+	native_clts();
+}
 
 #endif/* CONFIG_PARAVIRT */
 
diff -druN linux-2.6.39-libre/arch/x86/include/asm/topology.h linux-3.0-rc7-libre/arch/x86/include/asm/topology.h
--- linux-2.6.39-libre/arch/x86/include/asm/topology.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/include/asm/topology.h	2011-07-11 19:51:52.000000000 -0400
@@ -93,19 +93,11 @@
 #define pcibus_to_node(bus) __pcibus_to_node(bus)
 
 #ifdef CONFIG_X86_32
-extern unsigned long node_start_pfn[];
-extern unsigned long node_end_pfn[];
-extern unsigned long node_remap_size[];
-#define node_has_online_mem(nid) (node_start_pfn[nid] != node_end_pfn[nid])
-
 # define SD_CACHE_NICE_TRIES	1
 # define SD_IDLE_IDX		1
-
 #else
-
 # define SD_CACHE_NICE_TRIES	2
 # define SD_IDLE_IDX		2
-
 #endif
 
 /* sched_domains SD_NODE_INIT for NUMA machines */
diff -druN linux-2.6.39-libre/arch/x86/include/asm/tsc.h linux-3.0-rc7-libre/arch/x86/include/asm/tsc.h
--- linux-2.6.39-libre/arch/x86/include/asm/tsc.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/include/asm/tsc.h	2011-07-11 19:51:52.000000000 -0400
@@ -51,6 +51,10 @@
 extern int check_tsc_unstable(void);
 extern unsigned long native_calibrate_tsc(void);
 
+#ifdef CONFIG_X86_64
+extern cycles_t vread_tsc(void);
+#endif
+
 /*
  * Boot-time check whether the TSCs are synchronized across
  * all CPUs/cores:
diff -druN linux-2.6.39-libre/arch/x86/include/asm/uaccess_32.h linux-3.0-rc7-libre/arch/x86/include/asm/uaccess_32.h
--- linux-2.6.39-libre/arch/x86/include/asm/uaccess_32.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/include/asm/uaccess_32.h	2011-07-11 19:51:52.000000000 -0400
@@ -6,7 +6,6 @@
  */
 #include <linux/errno.h>
 #include <linux/thread_info.h>
-#include <linux/prefetch.h>
 #include <linux/string.h>
 #include <asm/asm.h>
 #include <asm/page.h>
diff -druN linux-2.6.39-libre/arch/x86/include/asm/uaccess_64.h linux-3.0-rc7-libre/arch/x86/include/asm/uaccess_64.h
--- linux-2.6.39-libre/arch/x86/include/asm/uaccess_64.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/include/asm/uaccess_64.h	2011-07-11 19:51:52.000000000 -0400
@@ -6,7 +6,6 @@
  */
 #include <linux/compiler.h>
 #include <linux/errno.h>
-#include <linux/prefetch.h>
 #include <linux/lockdep.h>
 #include <asm/alternative.h>
 #include <asm/cpufeature.h>
diff -druN linux-2.6.39-libre/arch/x86/include/asm/uaccess.h linux-3.0-rc7-libre/arch/x86/include/asm/uaccess.h
--- linux-2.6.39-libre/arch/x86/include/asm/uaccess.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/include/asm/uaccess.h	2011-07-11 19:51:52.000000000 -0400
@@ -6,7 +6,6 @@
 #include <linux/errno.h>
 #include <linux/compiler.h>
 #include <linux/thread_info.h>
-#include <linux/prefetch.h>
 #include <linux/string.h>
 #include <asm/asm.h>
 #include <asm/page.h>
@@ -42,7 +41,7 @@
  * Returns 0 if the range is valid, nonzero otherwise.
  *
  * This is equivalent to the following test:
- * (u33)addr + (u33)size >= (u33)current->addr_limit.seg (u65 for x86_64)
+ * (u33)addr + (u33)size > (u33)current->addr_limit.seg (u65 for x86_64)
  *
  * This needs 33-bit (65-bit for x86_64) arithmetic. We have a carry...
  */
diff -druN linux-2.6.39-libre/arch/x86/include/asm/unistd_32.h linux-3.0-rc7-libre/arch/x86/include/asm/unistd_32.h
--- linux-2.6.39-libre/arch/x86/include/asm/unistd_32.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/include/asm/unistd_32.h	2011-07-11 19:51:52.000000000 -0400
@@ -350,10 +350,12 @@
 #define __NR_open_by_handle_at  342
 #define __NR_clock_adjtime	343
 #define __NR_syncfs             344
+#define __NR_sendmmsg		345
+#define __NR_setns		346
 
 #ifdef __KERNEL__
 
-#define NR_syscalls 345
+#define NR_syscalls 347
 
 #define __ARCH_WANT_IPC_PARSE_VERSION
 #define __ARCH_WANT_OLD_READDIR
diff -druN linux-2.6.39-libre/arch/x86/include/asm/unistd_64.h linux-3.0-rc7-libre/arch/x86/include/asm/unistd_64.h
--- linux-2.6.39-libre/arch/x86/include/asm/unistd_64.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/include/asm/unistd_64.h	2011-07-11 19:51:52.000000000 -0400
@@ -677,6 +677,10 @@
 __SYSCALL(__NR_clock_adjtime, sys_clock_adjtime)
 #define __NR_syncfs                             306
 __SYSCALL(__NR_syncfs, sys_syncfs)
+#define __NR_sendmmsg				307
+__SYSCALL(__NR_sendmmsg, sys_sendmmsg)
+#define __NR_setns				308
+__SYSCALL(__NR_setns, sys_setns)
 
 #ifndef __NO_STUBS
 #define __ARCH_WANT_OLD_READDIR
diff -druN linux-2.6.39-libre/arch/x86/include/asm/uv/uv_bau.h linux-3.0-rc7-libre/arch/x86/include/asm/uv/uv_bau.h
--- linux-2.6.39-libre/arch/x86/include/asm/uv/uv_bau.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/include/asm/uv/uv_bau.h	2011-07-11 19:51:52.000000000 -0400
@@ -5,7 +5,7 @@
  *
  * SGI UV Broadcast Assist Unit definitions
  *
- * Copyright (C) 2008 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 2008-2011 Silicon Graphics, Inc. All rights reserved.
  */
 
 #ifndef _ASM_X86_UV_UV_BAU_H
@@ -35,17 +35,20 @@
 
 #define MAX_CPUS_PER_UVHUB		64
 #define MAX_CPUS_PER_SOCKET		32
-#define UV_ADP_SIZE			64 /* hardware-provided max. */
-#define UV_CPUS_PER_ACT_STATUS		32 /* hardware-provided max. */
-#define UV_ITEMS_PER_DESCRIPTOR		8
+#define ADP_SZ				64 /* hardware-provided max. */
+#define UV_CPUS_PER_AS			32 /* hardware-provided max. */
+#define ITEMS_PER_DESC			8
 /* the 'throttle' to prevent the hardware stay-busy bug */
 #define MAX_BAU_CONCURRENT		3
 #define UV_ACT_STATUS_MASK		0x3
 #define UV_ACT_STATUS_SIZE		2
 #define UV_DISTRIBUTION_SIZE		256
 #define UV_SW_ACK_NPENDING		8
-#define UV_NET_ENDPOINT_INTD		0x38
-#define UV_DESC_BASE_PNODE_SHIFT	49
+#define UV1_NET_ENDPOINT_INTD		0x38
+#define UV2_NET_ENDPOINT_INTD		0x28
+#define UV_NET_ENDPOINT_INTD		(is_uv1_hub() ?			\
+			UV1_NET_ENDPOINT_INTD : UV2_NET_ENDPOINT_INTD)
+#define UV_DESC_PSHIFT			49
 #define UV_PAYLOADQ_PNODE_SHIFT		49
 #define UV_PTC_BASENAME			"sgi_uv/ptc_statistics"
 #define UV_BAU_BASENAME			"sgi_uv/bau_tunables"
@@ -53,29 +56,64 @@
 #define UV_BAU_TUNABLES_FILE		"bau_tunables"
 #define WHITESPACE			" \t\n"
 #define uv_physnodeaddr(x)		((__pa((unsigned long)(x)) & uv_mmask))
-#define UV_ENABLE_INTD_SOFT_ACK_MODE_SHIFT 15
-#define UV_INTD_SOFT_ACK_TIMEOUT_PERIOD_SHIFT 16
-#define UV_INTD_SOFT_ACK_TIMEOUT_PERIOD 0x0000000009UL
+#define cpubit_isset(cpu, bau_local_cpumask) \
+	test_bit((cpu), (bau_local_cpumask).bits)
+
 /* [19:16] SOFT_ACK timeout period  19: 1 is urgency 7  17:16 1 is multiplier */
-#define BAU_MISC_CONTROL_MULT_MASK 3
+/*
+ * UV2: Bit 19 selects between
+ *  (0): 10 microsecond timebase and
+ *  (1): 80 microseconds
+ *  we're using 655us, similar to UV1: 65 units of 10us
+ */
+#define UV1_INTD_SOFT_ACK_TIMEOUT_PERIOD (9UL)
+#define UV2_INTD_SOFT_ACK_TIMEOUT_PERIOD (65*10UL)
 
-#define UVH_AGING_PRESCALE_SEL 0x000000b000UL
+#define UV_INTD_SOFT_ACK_TIMEOUT_PERIOD	(is_uv1_hub() ?			\
+		UV1_INTD_SOFT_ACK_TIMEOUT_PERIOD :			\
+		UV2_INTD_SOFT_ACK_TIMEOUT_PERIOD)
+
+#define BAU_MISC_CONTROL_MULT_MASK	3
+
+#define UVH_AGING_PRESCALE_SEL		0x000000b000UL
 /* [30:28] URGENCY_7  an index into a table of times */
-#define BAU_URGENCY_7_SHIFT 28
-#define BAU_URGENCY_7_MASK 7
+#define BAU_URGENCY_7_SHIFT		28
+#define BAU_URGENCY_7_MASK		7
 
-#define UVH_TRANSACTION_TIMEOUT 0x000000b200UL
+#define UVH_TRANSACTION_TIMEOUT		0x000000b200UL
 /* [45:40] BAU - BAU transaction timeout select - a multiplier */
-#define BAU_TRANS_SHIFT 40
-#define BAU_TRANS_MASK 0x3f
+#define BAU_TRANS_SHIFT			40
+#define BAU_TRANS_MASK			0x3f
+
+/*
+ * shorten some awkward names
+ */
+#define AS_PUSH_SHIFT UVH_LB_BAU_SB_ACTIVATION_CONTROL_PUSH_SHFT
+#define SOFTACK_MSHIFT UVH_LB_BAU_MISC_CONTROL_ENABLE_INTD_SOFT_ACK_MODE_SHFT
+#define SOFTACK_PSHIFT UVH_LB_BAU_MISC_CONTROL_INTD_SOFT_ACK_TIMEOUT_PERIOD_SHFT
+#define SOFTACK_TIMEOUT_PERIOD UV_INTD_SOFT_ACK_TIMEOUT_PERIOD
+#define write_gmmr	uv_write_global_mmr64
+#define write_lmmr	uv_write_local_mmr
+#define read_lmmr	uv_read_local_mmr
+#define read_gmmr	uv_read_global_mmr64
 
 /*
  * bits in UVH_LB_BAU_SB_ACTIVATION_STATUS_0/1
  */
-#define DESC_STATUS_IDLE		0
-#define DESC_STATUS_ACTIVE		1
-#define DESC_STATUS_DESTINATION_TIMEOUT	2
-#define DESC_STATUS_SOURCE_TIMEOUT	3
+#define DS_IDLE				0
+#define DS_ACTIVE			1
+#define DS_DESTINATION_TIMEOUT		2
+#define DS_SOURCE_TIMEOUT		3
+/*
+ * bits put together from HRP_LB_BAU_SB_ACTIVATION_STATUS_0/1/2
+ * values 1 and 5 will not occur
+ */
+#define UV2H_DESC_IDLE			0
+#define UV2H_DESC_DEST_TIMEOUT		2
+#define UV2H_DESC_DEST_STRONG_NACK	3
+#define UV2H_DESC_BUSY			4
+#define UV2H_DESC_SOURCE_TIMEOUT	6
+#define UV2H_DESC_DEST_PUT_ERR		7
 
 /*
  * delay for 'plugged' timeout retries, in microseconds
@@ -86,15 +124,24 @@
  * threshholds at which to use IPI to free resources
  */
 /* after this # consecutive 'plugged' timeouts, use IPI to release resources */
-#define PLUGSB4RESET 100
+#define PLUGSB4RESET			100
 /* after this many consecutive timeouts, use IPI to release resources */
-#define TIMEOUTSB4RESET 1
+#define TIMEOUTSB4RESET			1
 /* at this number uses of IPI to release resources, giveup the request */
-#define IPI_RESET_LIMIT 1
+#define IPI_RESET_LIMIT			1
 /* after this # consecutive successes, bump up the throttle if it was lowered */
-#define COMPLETE_THRESHOLD 5
+#define COMPLETE_THRESHOLD		5
 
-#define UV_LB_SUBNODEID 0x10
+#define UV_LB_SUBNODEID			0x10
+
+/* these two are the same for UV1 and UV2: */
+#define UV_SA_SHFT UVH_LB_BAU_MISC_CONTROL_INTD_SOFT_ACK_TIMEOUT_PERIOD_SHFT
+#define UV_SA_MASK UVH_LB_BAU_MISC_CONTROL_INTD_SOFT_ACK_TIMEOUT_PERIOD_MASK
+/* 4 bits of software ack period */
+#define UV2_ACK_MASK			0x7UL
+#define UV2_ACK_UNITS_SHFT		3
+#define UV2_LEG_SHFT UV2H_LB_BAU_MISC_CONTROL_USE_LEGACY_DESCRIPTOR_FORMATS_SHFT
+#define UV2_EXT_SHFT UV2H_LB_BAU_MISC_CONTROL_ENABLE_EXTENDED_SB_STATUS_SHFT
 
 /*
  * number of entries in the destination side payload queue
@@ -115,9 +162,16 @@
 /*
  * tuning the action when the numalink network is extremely delayed
  */
-#define CONGESTED_RESPONSE_US 1000 /* 'long' response time, in microseconds */
-#define CONGESTED_REPS 10 /* long delays averaged over this many broadcasts */
-#define CONGESTED_PERIOD 30 /* time for the bau to be disabled, in seconds */
+#define CONGESTED_RESPONSE_US		1000	/* 'long' response time, in
+						   microseconds */
+#define CONGESTED_REPS			10	/* long delays averaged over
+						   this many broadcasts */
+#define CONGESTED_PERIOD		30	/* time for the bau to be
+						   disabled, in seconds */
+/* see msg_type: */
+#define MSG_NOOP			0
+#define MSG_REGULAR			1
+#define MSG_RETRY			2
 
 /*
  * Distribution: 32 bytes (256 bits) (bytes 0-0x1f of descriptor)
@@ -129,8 +183,8 @@
  * 'base_dest_nasid' field of the header corresponds to the
  * destination nodeID associated with that specified bit.
  */
-struct bau_target_uvhubmask {
-	unsigned long bits[BITS_TO_LONGS(UV_DISTRIBUTION_SIZE)];
+struct bau_targ_hubmask {
+	unsigned long		bits[BITS_TO_LONGS(UV_DISTRIBUTION_SIZE)];
 };
 
 /*
@@ -139,7 +193,7 @@
  *  enough bits for max. cpu's per uvhub)
  */
 struct bau_local_cpumask {
-	unsigned long bits;
+	unsigned long		bits;
 };
 
 /*
@@ -160,14 +214,14 @@
  * The payload is software-defined for INTD transactions
  */
 struct bau_msg_payload {
-	unsigned long address;		/* signifies a page or all TLB's
-						of the cpu */
+	unsigned long	address;		/* signifies a page or all
+						   TLB's of the cpu */
 	/* 64 bits */
-	unsigned short sending_cpu;	/* filled in by sender */
+	unsigned short	sending_cpu;		/* filled in by sender */
 	/* 16 bits */
-	unsigned short acknowledge_count;/* filled in by destination */
+	unsigned short	acknowledge_count;	/* filled in by destination */
 	/* 16 bits */
-	unsigned int reserved1:32;	/* not usable */
+	unsigned int	reserved1:32;		/* not usable */
 };
 
 
@@ -176,93 +230,96 @@
  * see table 4.2.3.0.1 in broacast_assist spec.
  */
 struct bau_msg_header {
-	unsigned int dest_subnodeid:6;	/* must be 0x10, for the LB */
+	unsigned int	dest_subnodeid:6;	/* must be 0x10, for the LB */
 	/* bits 5:0 */
-	unsigned int base_dest_nasid:15; /* nasid of the */
-	/* bits 20:6 */			  /* first bit in uvhub map */
-	unsigned int command:8;	/* message type */
+	unsigned int	base_dest_nasid:15;	/* nasid of the first bit */
+	/* bits 20:6 */				/* in uvhub map */
+	unsigned int	command:8;		/* message type */
 	/* bits 28:21 */
-				/* 0x38: SN3net EndPoint Message */
-	unsigned int rsvd_1:3;	/* must be zero */
+	/* 0x38: SN3net EndPoint Message */
+	unsigned int	rsvd_1:3;		/* must be zero */
 	/* bits 31:29 */
-				/* int will align on 32 bits */
-	unsigned int rsvd_2:9;	/* must be zero */
+	/* int will align on 32 bits */
+	unsigned int	rsvd_2:9;		/* must be zero */
 	/* bits 40:32 */
-				/* Suppl_A is 56-41 */
-	unsigned int sequence:16;/* message sequence number */
-	/* bits 56:41 */	/* becomes bytes 16-17 of msg */
-				/* Address field (96:57) is never used as an
-				   address (these are address bits 42:3) */
+	/* Suppl_A is 56-41 */
+	unsigned int	sequence:16;		/* message sequence number */
+	/* bits 56:41 */			/* becomes bytes 16-17 of msg */
+						/* Address field (96:57) is
+						   never used as an address
+						   (these are address bits
+						   42:3) */
 
-	unsigned int rsvd_3:1;	/* must be zero */
+	unsigned int	rsvd_3:1;		/* must be zero */
 	/* bit 57 */
-				/* address bits 27:4 are payload */
+	/* address bits 27:4 are payload */
 	/* these next 24  (58-81) bits become bytes 12-14 of msg */
-
 	/* bits 65:58 land in byte 12 */
-	unsigned int replied_to:1;/* sent as 0 by the source to byte 12 */
+	unsigned int	replied_to:1;		/* sent as 0 by the source to
+						   byte 12 */
 	/* bit 58 */
-	unsigned int msg_type:3; /* software type of the message*/
+	unsigned int	msg_type:3;		/* software type of the
+						   message */
 	/* bits 61:59 */
-	unsigned int canceled:1; /* message canceled, resource to be freed*/
+	unsigned int	canceled:1;		/* message canceled, resource
+						   is to be freed*/
 	/* bit 62 */
-	unsigned int payload_1a:1;/* not currently used */
+	unsigned int	payload_1a:1;		/* not currently used */
 	/* bit 63 */
-	unsigned int payload_1b:2;/* not currently used */
+	unsigned int	payload_1b:2;		/* not currently used */
 	/* bits 65:64 */
 
 	/* bits 73:66 land in byte 13 */
-	unsigned int payload_1ca:6;/* not currently used */
+	unsigned int	payload_1ca:6;		/* not currently used */
 	/* bits 71:66 */
-	unsigned int payload_1c:2;/* not currently used */
+	unsigned int	payload_1c:2;		/* not currently used */
 	/* bits 73:72 */
 
 	/* bits 81:74 land in byte 14 */
-	unsigned int payload_1d:6;/* not currently used */
+	unsigned int	payload_1d:6;		/* not currently used */
 	/* bits 79:74 */
-	unsigned int payload_1e:2;/* not currently used */
+	unsigned int	payload_1e:2;		/* not currently used */
 	/* bits 81:80 */
 
-	unsigned int rsvd_4:7;	/* must be zero */
+	unsigned int	rsvd_4:7;		/* must be zero */
 	/* bits 88:82 */
-	unsigned int sw_ack_flag:1;/* software acknowledge flag */
+	unsigned int	swack_flag:1;		/* software acknowledge flag */
 	/* bit 89 */
-				/* INTD trasactions at destination are to
-				   wait for software acknowledge */
-	unsigned int rsvd_5:6;	/* must be zero */
+						/* INTD trasactions at
+						   destination are to wait for
+						   software acknowledge */
+	unsigned int	rsvd_5:6;		/* must be zero */
 	/* bits 95:90 */
-	unsigned int rsvd_6:5;	/* must be zero */
+	unsigned int	rsvd_6:5;		/* must be zero */
 	/* bits 100:96 */
-	unsigned int int_both:1;/* if 1, interrupt both sockets on the uvhub */
+	unsigned int	int_both:1;		/* if 1, interrupt both sockets
+						   on the uvhub */
 	/* bit 101*/
-	unsigned int fairness:3;/* usually zero */
+	unsigned int	fairness:3;		/* usually zero */
 	/* bits 104:102 */
-	unsigned int multilevel:1;	/* multi-level multicast format */
+	unsigned int	multilevel:1;		/* multi-level multicast
+						   format */
 	/* bit 105 */
-				/* 0 for TLB: endpoint multi-unicast messages */
-	unsigned int chaining:1;/* next descriptor is part of this activation*/
+	/* 0 for TLB: endpoint multi-unicast messages */
+	unsigned int	chaining:1;		/* next descriptor is part of
+						   this activation*/
 	/* bit 106 */
-	unsigned int rsvd_7:21;	/* must be zero */
+	unsigned int	rsvd_7:21;		/* must be zero */
 	/* bits 127:107 */
 };
 
-/* see msg_type: */
-#define MSG_NOOP 0
-#define MSG_REGULAR 1
-#define MSG_RETRY 2
-
 /*
  * The activation descriptor:
  * The format of the message to send, plus all accompanying control
  * Should be 64 bytes
  */
 struct bau_desc {
-	struct bau_target_uvhubmask distribution;
+	struct bau_targ_hubmask	distribution;
 	/*
 	 * message template, consisting of header and payload:
 	 */
-	struct bau_msg_header header;
-	struct bau_msg_payload payload;
+	struct bau_msg_header		header;
+	struct bau_msg_payload		payload;
 };
 /*
  *   -payload--    ---------header------
@@ -281,59 +338,51 @@
  * are 32 bytes (2 micropackets) (256 bits) in length, but contain only 17
  * bytes of usable data, including the sw ack vector in byte 15 (bits 127:120)
  * (12 bytes come from bau_msg_payload, 3 from payload_1, 2 from
- *  sw_ack_vector and payload_2)
+ *  swack_vec and payload_2)
  * "Enabling Software Acknowledgment mode (see Section 4.3.3 Software
  *  Acknowledge Processing) also selects 32 byte (17 bytes usable) payload
  *  operation."
  */
-struct bau_payload_queue_entry {
-	unsigned long address;		/* signifies a page or all TLB's
-						of the cpu */
+struct bau_pq_entry {
+	unsigned long	address;	/* signifies a page or all TLB's
+					   of the cpu */
 	/* 64 bits, bytes 0-7 */
-
-	unsigned short sending_cpu;	/* cpu that sent the message */
+	unsigned short	sending_cpu;	/* cpu that sent the message */
 	/* 16 bits, bytes 8-9 */
-
-	unsigned short acknowledge_count; /* filled in by destination */
+	unsigned short	acknowledge_count; /* filled in by destination */
 	/* 16 bits, bytes 10-11 */
-
 	/* these next 3 bytes come from bits 58-81 of the message header */
-	unsigned short replied_to:1;    /* sent as 0 by the source */
-	unsigned short msg_type:3;      /* software message type */
-	unsigned short canceled:1;      /* sent as 0 by the source */
-	unsigned short unused1:3;       /* not currently using */
+	unsigned short	replied_to:1;	/* sent as 0 by the source */
+	unsigned short	msg_type:3;	/* software message type */
+	unsigned short	canceled:1;	/* sent as 0 by the source */
+	unsigned short	unused1:3;	/* not currently using */
 	/* byte 12 */
-
-	unsigned char unused2a;		/* not currently using */
+	unsigned char	unused2a;	/* not currently using */
 	/* byte 13 */
-	unsigned char unused2;		/* not currently using */
+	unsigned char	unused2;	/* not currently using */
 	/* byte 14 */
-
-	unsigned char sw_ack_vector;	/* filled in by the hardware */
+	unsigned char	swack_vec;	/* filled in by the hardware */
 	/* byte 15 (bits 127:120) */
-
-	unsigned short sequence;	/* message sequence number */
+	unsigned short	sequence;	/* message sequence number */
 	/* bytes 16-17 */
-	unsigned char unused4[2];	/* not currently using bytes 18-19 */
+	unsigned char	unused4[2];	/* not currently using bytes 18-19 */
 	/* bytes 18-19 */
-
-	int number_of_cpus;		/* filled in at destination */
+	int		number_of_cpus;	/* filled in at destination */
 	/* 32 bits, bytes 20-23 (aligned) */
-
-	unsigned char unused5[8];       /* not using */
+	unsigned char	unused5[8];	/* not using */
 	/* bytes 24-31 */
 };
 
 struct msg_desc {
-	struct bau_payload_queue_entry *msg;
-	int msg_slot;
-	int sw_ack_slot;
-	struct bau_payload_queue_entry *va_queue_first;
-	struct bau_payload_queue_entry *va_queue_last;
+	struct bau_pq_entry	*msg;
+	int			msg_slot;
+	int			swack_slot;
+	struct bau_pq_entry	*queue_first;
+	struct bau_pq_entry	*queue_last;
 };
 
 struct reset_args {
-	int sender;
+	int			sender;
 };
 
 /*
@@ -341,112 +390,226 @@
  */
 struct ptc_stats {
 	/* sender statistics */
-	unsigned long s_giveup; /* number of fall backs to IPI-style flushes */
-	unsigned long s_requestor; /* number of shootdown requests */
-	unsigned long s_stimeout; /* source side timeouts */
-	unsigned long s_dtimeout; /* destination side timeouts */
-	unsigned long s_time; /* time spent in sending side */
-	unsigned long s_retriesok; /* successful retries */
-	unsigned long s_ntargcpu; /* total number of cpu's targeted */
-	unsigned long s_ntargself; /* times the sending cpu was targeted */
-	unsigned long s_ntarglocals; /* targets of cpus on the local blade */
-	unsigned long s_ntargremotes; /* targets of cpus on remote blades */
-	unsigned long s_ntarglocaluvhub; /* targets of the local hub */
-	unsigned long s_ntargremoteuvhub; /* remotes hubs targeted */
-	unsigned long s_ntarguvhub; /* total number of uvhubs targeted */
-	unsigned long s_ntarguvhub16; /* number of times target hubs >= 16*/
-	unsigned long s_ntarguvhub8; /* number of times target hubs >= 8 */
-	unsigned long s_ntarguvhub4; /* number of times target hubs >= 4 */
-	unsigned long s_ntarguvhub2; /* number of times target hubs >= 2 */
-	unsigned long s_ntarguvhub1; /* number of times target hubs == 1 */
-	unsigned long s_resets_plug; /* ipi-style resets from plug state */
-	unsigned long s_resets_timeout; /* ipi-style resets from timeouts */
-	unsigned long s_busy; /* status stayed busy past s/w timer */
-	unsigned long s_throttles; /* waits in throttle */
-	unsigned long s_retry_messages; /* retry broadcasts */
-	unsigned long s_bau_reenabled; /* for bau enable/disable */
-	unsigned long s_bau_disabled; /* for bau enable/disable */
+	unsigned long	s_giveup;		/* number of fall backs to
+						   IPI-style flushes */
+	unsigned long	s_requestor;		/* number of shootdown
+						   requests */
+	unsigned long	s_stimeout;		/* source side timeouts */
+	unsigned long	s_dtimeout;		/* destination side timeouts */
+	unsigned long	s_time;			/* time spent in sending side */
+	unsigned long	s_retriesok;		/* successful retries */
+	unsigned long	s_ntargcpu;		/* total number of cpu's
+						   targeted */
+	unsigned long	s_ntargself;		/* times the sending cpu was
+						   targeted */
+	unsigned long	s_ntarglocals;		/* targets of cpus on the local
+						   blade */
+	unsigned long	s_ntargremotes;		/* targets of cpus on remote
+						   blades */
+	unsigned long	s_ntarglocaluvhub;	/* targets of the local hub */
+	unsigned long	s_ntargremoteuvhub;	/* remotes hubs targeted */
+	unsigned long	s_ntarguvhub;		/* total number of uvhubs
+						   targeted */
+	unsigned long	s_ntarguvhub16;		/* number of times target
+						   hubs >= 16*/
+	unsigned long	s_ntarguvhub8;		/* number of times target
+						   hubs >= 8 */
+	unsigned long	s_ntarguvhub4;		/* number of times target
+						   hubs >= 4 */
+	unsigned long	s_ntarguvhub2;		/* number of times target
+						   hubs >= 2 */
+	unsigned long	s_ntarguvhub1;		/* number of times target
+						   hubs == 1 */
+	unsigned long	s_resets_plug;		/* ipi-style resets from plug
+						   state */
+	unsigned long	s_resets_timeout;	/* ipi-style resets from
+						   timeouts */
+	unsigned long	s_busy;			/* status stayed busy past
+						   s/w timer */
+	unsigned long	s_throttles;		/* waits in throttle */
+	unsigned long	s_retry_messages;	/* retry broadcasts */
+	unsigned long	s_bau_reenabled;	/* for bau enable/disable */
+	unsigned long	s_bau_disabled;		/* for bau enable/disable */
 	/* destination statistics */
-	unsigned long d_alltlb; /* times all tlb's on this cpu were flushed */
-	unsigned long d_onetlb; /* times just one tlb on this cpu was flushed */
-	unsigned long d_multmsg; /* interrupts with multiple messages */
-	unsigned long d_nomsg; /* interrupts with no message */
-	unsigned long d_time; /* time spent on destination side */
-	unsigned long d_requestee; /* number of messages processed */
-	unsigned long d_retries; /* number of retry messages processed */
-	unsigned long d_canceled; /* number of messages canceled by retries */
-	unsigned long d_nocanceled; /* retries that found nothing to cancel */
-	unsigned long d_resets; /* number of ipi-style requests processed */
-	unsigned long d_rcanceled; /* number of messages canceled by resets */
+	unsigned long	d_alltlb;		/* times all tlb's on this
+						   cpu were flushed */
+	unsigned long	d_onetlb;		/* times just one tlb on this
+						   cpu was flushed */
+	unsigned long	d_multmsg;		/* interrupts with multiple
+						   messages */
+	unsigned long	d_nomsg;		/* interrupts with no message */
+	unsigned long	d_time;			/* time spent on destination
+						   side */
+	unsigned long	d_requestee;		/* number of messages
+						   processed */
+	unsigned long	d_retries;		/* number of retry messages
+						   processed */
+	unsigned long	d_canceled;		/* number of messages canceled
+						   by retries */
+	unsigned long	d_nocanceled;		/* retries that found nothing
+						   to cancel */
+	unsigned long	d_resets;		/* number of ipi-style requests
+						   processed */
+	unsigned long	d_rcanceled;		/* number of messages canceled
+						   by resets */
+};
+
+struct tunables {
+	int			*tunp;
+	int			deflt;
 };
 
 struct hub_and_pnode {
-	short uvhub;
-	short pnode;
+	short			uvhub;
+	short			pnode;
 };
+
+struct socket_desc {
+	short			num_cpus;
+	short			cpu_number[MAX_CPUS_PER_SOCKET];
+};
+
+struct uvhub_desc {
+	unsigned short		socket_mask;
+	short			num_cpus;
+	short			uvhub;
+	short			pnode;
+	struct socket_desc	socket[2];
+};
+
 /*
  * one per-cpu; to locate the software tables
  */
 struct bau_control {
-	struct bau_desc *descriptor_base;
-	struct bau_payload_queue_entry *va_queue_first;
-	struct bau_payload_queue_entry *va_queue_last;
-	struct bau_payload_queue_entry *bau_msg_head;
-	struct bau_control *uvhub_master;
-	struct bau_control *socket_master;
-	struct ptc_stats *statp;
-	unsigned long timeout_interval;
-	unsigned long set_bau_on_time;
-	atomic_t active_descriptor_count;
-	int plugged_tries;
-	int timeout_tries;
-	int ipi_attempts;
-	int conseccompletes;
-	int baudisabled;
-	int set_bau_off;
-	short cpu;
-	short osnode;
-	short uvhub_cpu;
-	short uvhub;
-	short cpus_in_socket;
-	short cpus_in_uvhub;
-	short partition_base_pnode;
-	unsigned short message_number;
-	unsigned short uvhub_quiesce;
-	short socket_acknowledge_count[DEST_Q_SIZE];
-	cycles_t send_message;
-	spinlock_t uvhub_lock;
-	spinlock_t queue_lock;
+	struct bau_desc		*descriptor_base;
+	struct bau_pq_entry	*queue_first;
+	struct bau_pq_entry	*queue_last;
+	struct bau_pq_entry	*bau_msg_head;
+	struct bau_control	*uvhub_master;
+	struct bau_control	*socket_master;
+	struct ptc_stats	*statp;
+	unsigned long		timeout_interval;
+	unsigned long		set_bau_on_time;
+	atomic_t		active_descriptor_count;
+	int			plugged_tries;
+	int			timeout_tries;
+	int			ipi_attempts;
+	int			conseccompletes;
+	int			baudisabled;
+	int			set_bau_off;
+	short			cpu;
+	short			osnode;
+	short			uvhub_cpu;
+	short			uvhub;
+	short			cpus_in_socket;
+	short			cpus_in_uvhub;
+	short			partition_base_pnode;
+	unsigned short		message_number;
+	unsigned short		uvhub_quiesce;
+	short			socket_acknowledge_count[DEST_Q_SIZE];
+	cycles_t		send_message;
+	spinlock_t		uvhub_lock;
+	spinlock_t		queue_lock;
 	/* tunables */
-	int max_bau_concurrent;
-	int max_bau_concurrent_constant;
-	int plugged_delay;
-	int plugsb4reset;
-	int timeoutsb4reset;
-	int ipi_reset_limit;
-	int complete_threshold;
-	int congested_response_us;
-	int congested_reps;
-	int congested_period;
-	cycles_t period_time;
-	long period_requests;
-	struct hub_and_pnode *target_hub_and_pnode;
+	int			max_concurr;
+	int			max_concurr_const;
+	int			plugged_delay;
+	int			plugsb4reset;
+	int			timeoutsb4reset;
+	int			ipi_reset_limit;
+	int			complete_threshold;
+	int			cong_response_us;
+	int			cong_reps;
+	int			cong_period;
+	cycles_t		period_time;
+	long			period_requests;
+	struct hub_and_pnode	*thp;
 };
 
-static inline int bau_uvhub_isset(int uvhub, struct bau_target_uvhubmask *dstp)
+static unsigned long read_mmr_uv2_status(void)
+{
+	return read_lmmr(UV2H_LB_BAU_SB_ACTIVATION_STATUS_2);
+}
+
+static void write_mmr_data_broadcast(int pnode, unsigned long mmr_image)
+{
+	write_gmmr(pnode, UVH_BAU_DATA_BROADCAST, mmr_image);
+}
+
+static void write_mmr_descriptor_base(int pnode, unsigned long mmr_image)
+{
+	write_gmmr(pnode, UVH_LB_BAU_SB_DESCRIPTOR_BASE, mmr_image);
+}
+
+static void write_mmr_activation(unsigned long index)
+{
+	write_lmmr(UVH_LB_BAU_SB_ACTIVATION_CONTROL, index);
+}
+
+static void write_gmmr_activation(int pnode, unsigned long mmr_image)
+{
+	write_gmmr(pnode, UVH_LB_BAU_SB_ACTIVATION_CONTROL, mmr_image);
+}
+
+static void write_mmr_payload_first(int pnode, unsigned long mmr_image)
+{
+	write_gmmr(pnode, UVH_LB_BAU_INTD_PAYLOAD_QUEUE_FIRST, mmr_image);
+}
+
+static void write_mmr_payload_tail(int pnode, unsigned long mmr_image)
+{
+	write_gmmr(pnode, UVH_LB_BAU_INTD_PAYLOAD_QUEUE_TAIL, mmr_image);
+}
+
+static void write_mmr_payload_last(int pnode, unsigned long mmr_image)
+{
+	write_gmmr(pnode, UVH_LB_BAU_INTD_PAYLOAD_QUEUE_LAST, mmr_image);
+}
+
+static void write_mmr_misc_control(int pnode, unsigned long mmr_image)
+{
+	write_gmmr(pnode, UVH_LB_BAU_MISC_CONTROL, mmr_image);
+}
+
+static unsigned long read_mmr_misc_control(int pnode)
+{
+	return read_gmmr(pnode, UVH_LB_BAU_MISC_CONTROL);
+}
+
+static void write_mmr_sw_ack(unsigned long mr)
+{
+	uv_write_local_mmr(UVH_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE_ALIAS, mr);
+}
+
+static unsigned long read_mmr_sw_ack(void)
+{
+	return read_lmmr(UVH_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE);
+}
+
+static unsigned long read_gmmr_sw_ack(int pnode)
+{
+	return read_gmmr(pnode, UVH_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE);
+}
+
+static void write_mmr_data_config(int pnode, unsigned long mr)
+{
+	uv_write_global_mmr64(pnode, UVH_BAU_DATA_CONFIG, mr);
+}
+
+static inline int bau_uvhub_isset(int uvhub, struct bau_targ_hubmask *dstp)
 {
 	return constant_test_bit(uvhub, &dstp->bits[0]);
 }
-static inline void bau_uvhub_set(int pnode, struct bau_target_uvhubmask *dstp)
+static inline void bau_uvhub_set(int pnode, struct bau_targ_hubmask *dstp)
 {
 	__set_bit(pnode, &dstp->bits[0]);
 }
-static inline void bau_uvhubs_clear(struct bau_target_uvhubmask *dstp,
+static inline void bau_uvhubs_clear(struct bau_targ_hubmask *dstp,
 				    int nbits)
 {
 	bitmap_zero(&dstp->bits[0], nbits);
 }
-static inline int bau_uvhub_weight(struct bau_target_uvhubmask *dstp)
+static inline int bau_uvhub_weight(struct bau_targ_hubmask *dstp)
 {
 	return bitmap_weight((unsigned long *)&dstp->bits[0],
 				UV_DISTRIBUTION_SIZE);
@@ -457,9 +620,6 @@
 	bitmap_zero(&dstp->bits, nbits);
 }
 
-#define cpubit_isset(cpu, bau_local_cpumask) \
-	test_bit((cpu), (bau_local_cpumask).bits)
-
 extern void uv_bau_message_intr1(void);
 extern void uv_bau_timeout_intr1(void);
 
@@ -467,7 +627,7 @@
 	short counter;
 };
 
-/**
+/*
  * atomic_read_short - read a short atomic variable
  * @v: pointer of type atomic_short
  *
@@ -478,14 +638,14 @@
 	return v->counter;
 }
 
-/**
- * atomic_add_short_return - add and return a short int
+/*
+ * atom_asr - add and return a short int
  * @i: short value to add
  * @v: pointer of type atomic_short
  *
  * Atomically adds @i to @v and returns @i + @v
  */
-static inline int atomic_add_short_return(short i, struct atomic_short *v)
+static inline int atom_asr(short i, struct atomic_short *v)
 {
 	short __i = i;
 	asm volatile(LOCK_PREFIX "xaddw %0, %1"
@@ -494,4 +654,26 @@
 	return i + __i;
 }
 
+/*
+ * conditionally add 1 to *v, unless *v is >= u
+ * return 0 if we cannot add 1 to *v because it is >= u
+ * return 1 if we can add 1 to *v because it is < u
+ * the add is atomic
+ *
+ * This is close to atomic_add_unless(), but this allows the 'u' value
+ * to be lowered below the current 'v'.  atomic_add_unless can only stop
+ * on equal.
+ */
+static inline int atomic_inc_unless_ge(spinlock_t *lock, atomic_t *v, int u)
+{
+	spin_lock(lock);
+	if (atomic_read(v) >= u) {
+		spin_unlock(lock);
+		return 0;
+	}
+	atomic_inc(v);
+	spin_unlock(lock);
+	return 1;
+}
+
 #endif /* _ASM_X86_UV_UV_BAU_H */
diff -druN linux-2.6.39-libre/arch/x86/include/asm/uv/uv_hub.h linux-3.0-rc7-libre/arch/x86/include/asm/uv/uv_hub.h
--- linux-2.6.39-libre/arch/x86/include/asm/uv/uv_hub.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/include/asm/uv/uv_hub.h	2011-07-11 19:51:52.000000000 -0400
@@ -77,8 +77,9 @@
  *
  *		1111110000000000
  *		5432109876543210
- *		pppppppppplc0cch	Nehalem-EX
- *		ppppppppplcc0cch	Westmere-EX
+ *		pppppppppplc0cch	Nehalem-EX (12 bits in hdw reg)
+ *		ppppppppplcc0cch	Westmere-EX (12 bits in hdw reg)
+ *		pppppppppppcccch	SandyBridge (15 bits in hdw reg)
  *		sssssssssss
  *
  *			p  = pnode bits
@@ -87,7 +88,7 @@
  *			h  = hyperthread
  *			s  = bits that are in the SOCKET_ID CSR
  *
- *	Note: Processor only supports 12 bits in the APICID register. The ACPI
+ *	Note: Processor may support fewer bits in the APICID register. The ACPI
  *	      tables hold all 16 bits. Software needs to be aware of this.
  *
  *	      Unless otherwise specified, all references to APICID refer to
@@ -138,6 +139,8 @@
 	unsigned long		global_mmr_base;
 	unsigned long		gpa_mask;
 	unsigned int		gnode_extra;
+	unsigned char		hub_revision;
+	unsigned char		apic_pnode_shift;
 	unsigned long		gnode_upper;
 	unsigned long		lowmem_remap_top;
 	unsigned long		lowmem_remap_base;
@@ -149,13 +152,31 @@
 	unsigned char		m_val;
 	unsigned char		n_val;
 	struct uv_scir_s	scir;
-	unsigned char		apic_pnode_shift;
 };
 
 DECLARE_PER_CPU(struct uv_hub_info_s, __uv_hub_info);
 #define uv_hub_info		(&__get_cpu_var(__uv_hub_info))
 #define uv_cpu_hub_info(cpu)	(&per_cpu(__uv_hub_info, cpu))
 
+/*
+ * Hub revisions less than UV2_HUB_REVISION_BASE are UV1 hubs. All UV2
+ * hubs have revision numbers greater than or equal to UV2_HUB_REVISION_BASE.
+ * This is a software convention - NOT the hardware revision numbers in
+ * the hub chip.
+ */
+#define UV1_HUB_REVISION_BASE		1
+#define UV2_HUB_REVISION_BASE		3
+
+static inline int is_uv1_hub(void)
+{
+	return uv_hub_info->hub_revision < UV2_HUB_REVISION_BASE;
+}
+
+static inline int is_uv2_hub(void)
+{
+	return uv_hub_info->hub_revision >= UV2_HUB_REVISION_BASE;
+}
+
 union uvh_apicid {
     unsigned long       v;
     struct uvh_apicid_s {
@@ -180,11 +201,25 @@
 #define UV_PNODE_TO_GNODE(p)		((p) |uv_hub_info->gnode_extra)
 #define UV_PNODE_TO_NASID(p)		(UV_PNODE_TO_GNODE(p) << 1)
 
-#define UV_LOCAL_MMR_BASE		0xf4000000UL
-#define UV_GLOBAL_MMR32_BASE		0xf8000000UL
+#define UV1_LOCAL_MMR_BASE		0xf4000000UL
+#define UV1_GLOBAL_MMR32_BASE		0xf8000000UL
+#define UV1_LOCAL_MMR_SIZE		(64UL * 1024 * 1024)
+#define UV1_GLOBAL_MMR32_SIZE		(64UL * 1024 * 1024)
+
+#define UV2_LOCAL_MMR_BASE		0xfa000000UL
+#define UV2_GLOBAL_MMR32_BASE		0xfc000000UL
+#define UV2_LOCAL_MMR_SIZE		(32UL * 1024 * 1024)
+#define UV2_GLOBAL_MMR32_SIZE		(32UL * 1024 * 1024)
+
+#define UV_LOCAL_MMR_BASE		(is_uv1_hub() ? UV1_LOCAL_MMR_BASE     \
+						: UV2_LOCAL_MMR_BASE)
+#define UV_GLOBAL_MMR32_BASE		(is_uv1_hub() ? UV1_GLOBAL_MMR32_BASE  \
+						: UV2_GLOBAL_MMR32_BASE)
+#define UV_LOCAL_MMR_SIZE		(is_uv1_hub() ? UV1_LOCAL_MMR_SIZE :   \
+						UV2_LOCAL_MMR_SIZE)
+#define UV_GLOBAL_MMR32_SIZE		(is_uv1_hub() ? UV1_GLOBAL_MMR32_SIZE :\
+						UV2_GLOBAL_MMR32_SIZE)
 #define UV_GLOBAL_MMR64_BASE		(uv_hub_info->global_mmr_base)
-#define UV_LOCAL_MMR_SIZE		(64UL * 1024 * 1024)
-#define UV_GLOBAL_MMR32_SIZE		(64UL * 1024 * 1024)
 
 #define UV_GLOBAL_GRU_MMR_BASE		0x4000000
 
@@ -301,6 +336,17 @@
 }
 
 /*
+ * Convert an apicid to the socket number on the blade
+ */
+static inline int uv_apicid_to_socket(int apicid)
+{
+	if (is_uv1_hub())
+		return (apicid >> (uv_hub_info->apic_pnode_shift - 1)) & 1;
+	else
+		return 0;
+}
+
+/*
  * Access global MMRs using the low memory MMR32 space. This region supports
  * faster MMR access but not all MMRs are accessible in this space.
  */
@@ -519,14 +565,13 @@
 
 /*
  * Get the minimum revision number of the hub chips within the partition.
- *     1 - initial rev 1.0 silicon
- *     2 - rev 2.0 production silicon
+ *     1 - UV1 rev 1.0 initial silicon
+ *     2 - UV1 rev 2.0 production silicon
+ *     3 - UV2 rev 1.0 initial silicon
  */
 static inline int uv_get_min_hub_revision_id(void)
 {
-	extern int uv_min_hub_revision_id;
-
-	return uv_min_hub_revision_id;
+	return uv_hub_info->hub_revision;
 }
 
 #endif /* CONFIG_X86_64 */
diff -druN linux-2.6.39-libre/arch/x86/include/asm/uv/uv_mmrs.h linux-3.0-rc7-libre/arch/x86/include/asm/uv/uv_mmrs.h
--- linux-2.6.39-libre/arch/x86/include/asm/uv/uv_mmrs.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/include/asm/uv/uv_mmrs.h	2011-07-11 19:51:52.000000000 -0400
@@ -11,13 +11,64 @@
 #ifndef _ASM_X86_UV_UV_MMRS_H
 #define _ASM_X86_UV_UV_MMRS_H
 
+/*
+ * This file contains MMR definitions for both UV1 & UV2 hubs.
+ *
+ * In general, MMR addresses and structures are identical on both hubs.
+ * These MMRs are identified as:
+ *	#define UVH_xxx		<address>
+ *	union uvh_xxx {
+ *		unsigned long       v;
+ *		struct uvh_int_cmpd_s {
+ *		} s;
+ *	};
+ *
+ * If the MMR exists on both hub type but has different addresses or
+ * contents, the MMR definition is similar to:
+ *	#define UV1H_xxx	<uv1 address>
+ *	#define UV2H_xxx	<uv2address>
+ *	#define UVH_xxx		(is_uv1_hub() ? UV1H_xxx : UV2H_xxx)
+ *	union uvh_xxx {
+ *		unsigned long       v;
+ *		struct uv1h_int_cmpd_s {	 (Common fields only)
+ *		} s;
+ *		struct uv1h_int_cmpd_s {	 (Full UV1 definition)
+ *		} s1;
+ *		struct uv2h_int_cmpd_s {	 (Full UV2 definition)
+ *		} s2;
+ *	};
+ *
+ * Only essential difference are enumerated. For example, if the address is
+ * the same for both UV1 & UV2, only a single #define is generated. Likewise,
+ * if the contents is the same for both hubs, only the "s" structure is
+ * generated.
+ *
+ * If the MMR exists on ONLY 1 type of hub, no generic definition is
+ * generated:
+ *	#define UVnH_xxx	<uvn address>
+ *	union uvnh_xxx {
+ *		unsigned long       v;
+ *		struct uvh_int_cmpd_s {
+ *		} sn;
+ *	};
+ */
+
 #define UV_MMR_ENABLE		(1UL << 63)
 
+#define UV1_HUB_PART_NUMBER	0x88a5
+#define UV2_HUB_PART_NUMBER	0x8eb8
+
+/* Compat: if this #define is present, UV headers support UV2 */
+#define UV2_HUB_IS_SUPPORTED	1
+
+/* KABI compat: if this #define is present, KABI hacks are present */
+#define UV2_HUB_KABI_HACKS	1
+
 /* ========================================================================= */
 /*                          UVH_BAU_DATA_BROADCAST                           */
 /* ========================================================================= */
 #define UVH_BAU_DATA_BROADCAST 0x61688UL
-#define UVH_BAU_DATA_BROADCAST_32 0x0440
+#define UVH_BAU_DATA_BROADCAST_32 0x440
 
 #define UVH_BAU_DATA_BROADCAST_ENABLE_SHFT 0
 #define UVH_BAU_DATA_BROADCAST_ENABLE_MASK 0x0000000000000001UL
@@ -34,7 +85,7 @@
 /*                           UVH_BAU_DATA_CONFIG                             */
 /* ========================================================================= */
 #define UVH_BAU_DATA_CONFIG 0x61680UL
-#define UVH_BAU_DATA_CONFIG_32 0x0438
+#define UVH_BAU_DATA_CONFIG_32 0x438
 
 #define UVH_BAU_DATA_CONFIG_VECTOR_SHFT 0
 #define UVH_BAU_DATA_CONFIG_VECTOR_MASK 0x00000000000000ffUL
@@ -73,125 +124,245 @@
 /*                           UVH_EVENT_OCCURRED0                             */
 /* ========================================================================= */
 #define UVH_EVENT_OCCURRED0 0x70000UL
-#define UVH_EVENT_OCCURRED0_32 0x005e8
+#define UVH_EVENT_OCCURRED0_32 0x5e8
+
+#define UV1H_EVENT_OCCURRED0_LB_HCERR_SHFT 0
+#define UV1H_EVENT_OCCURRED0_LB_HCERR_MASK 0x0000000000000001UL
+#define UV1H_EVENT_OCCURRED0_GR0_HCERR_SHFT 1
+#define UV1H_EVENT_OCCURRED0_GR0_HCERR_MASK 0x0000000000000002UL
+#define UV1H_EVENT_OCCURRED0_GR1_HCERR_SHFT 2
+#define UV1H_EVENT_OCCURRED0_GR1_HCERR_MASK 0x0000000000000004UL
+#define UV1H_EVENT_OCCURRED0_LH_HCERR_SHFT 3
+#define UV1H_EVENT_OCCURRED0_LH_HCERR_MASK 0x0000000000000008UL
+#define UV1H_EVENT_OCCURRED0_RH_HCERR_SHFT 4
+#define UV1H_EVENT_OCCURRED0_RH_HCERR_MASK 0x0000000000000010UL
+#define UV1H_EVENT_OCCURRED0_XN_HCERR_SHFT 5
+#define UV1H_EVENT_OCCURRED0_XN_HCERR_MASK 0x0000000000000020UL
+#define UV1H_EVENT_OCCURRED0_SI_HCERR_SHFT 6
+#define UV1H_EVENT_OCCURRED0_SI_HCERR_MASK 0x0000000000000040UL
+#define UV1H_EVENT_OCCURRED0_LB_AOERR0_SHFT 7
+#define UV1H_EVENT_OCCURRED0_LB_AOERR0_MASK 0x0000000000000080UL
+#define UV1H_EVENT_OCCURRED0_GR0_AOERR0_SHFT 8
+#define UV1H_EVENT_OCCURRED0_GR0_AOERR0_MASK 0x0000000000000100UL
+#define UV1H_EVENT_OCCURRED0_GR1_AOERR0_SHFT 9
+#define UV1H_EVENT_OCCURRED0_GR1_AOERR0_MASK 0x0000000000000200UL
+#define UV1H_EVENT_OCCURRED0_LH_AOERR0_SHFT 10
+#define UV1H_EVENT_OCCURRED0_LH_AOERR0_MASK 0x0000000000000400UL
+#define UV1H_EVENT_OCCURRED0_RH_AOERR0_SHFT 11
+#define UV1H_EVENT_OCCURRED0_RH_AOERR0_MASK 0x0000000000000800UL
+#define UV1H_EVENT_OCCURRED0_XN_AOERR0_SHFT 12
+#define UV1H_EVENT_OCCURRED0_XN_AOERR0_MASK 0x0000000000001000UL
+#define UV1H_EVENT_OCCURRED0_SI_AOERR0_SHFT 13
+#define UV1H_EVENT_OCCURRED0_SI_AOERR0_MASK 0x0000000000002000UL
+#define UV1H_EVENT_OCCURRED0_LB_AOERR1_SHFT 14
+#define UV1H_EVENT_OCCURRED0_LB_AOERR1_MASK 0x0000000000004000UL
+#define UV1H_EVENT_OCCURRED0_GR0_AOERR1_SHFT 15
+#define UV1H_EVENT_OCCURRED0_GR0_AOERR1_MASK 0x0000000000008000UL
+#define UV1H_EVENT_OCCURRED0_GR1_AOERR1_SHFT 16
+#define UV1H_EVENT_OCCURRED0_GR1_AOERR1_MASK 0x0000000000010000UL
+#define UV1H_EVENT_OCCURRED0_LH_AOERR1_SHFT 17
+#define UV1H_EVENT_OCCURRED0_LH_AOERR1_MASK 0x0000000000020000UL
+#define UV1H_EVENT_OCCURRED0_RH_AOERR1_SHFT 18
+#define UV1H_EVENT_OCCURRED0_RH_AOERR1_MASK 0x0000000000040000UL
+#define UV1H_EVENT_OCCURRED0_XN_AOERR1_SHFT 19
+#define UV1H_EVENT_OCCURRED0_XN_AOERR1_MASK 0x0000000000080000UL
+#define UV1H_EVENT_OCCURRED0_SI_AOERR1_SHFT 20
+#define UV1H_EVENT_OCCURRED0_SI_AOERR1_MASK 0x0000000000100000UL
+#define UV1H_EVENT_OCCURRED0_RH_VPI_INT_SHFT 21
+#define UV1H_EVENT_OCCURRED0_RH_VPI_INT_MASK 0x0000000000200000UL
+#define UV1H_EVENT_OCCURRED0_SYSTEM_SHUTDOWN_INT_SHFT 22
+#define UV1H_EVENT_OCCURRED0_SYSTEM_SHUTDOWN_INT_MASK 0x0000000000400000UL
+#define UV1H_EVENT_OCCURRED0_LB_IRQ_INT_0_SHFT 23
+#define UV1H_EVENT_OCCURRED0_LB_IRQ_INT_0_MASK 0x0000000000800000UL
+#define UV1H_EVENT_OCCURRED0_LB_IRQ_INT_1_SHFT 24
+#define UV1H_EVENT_OCCURRED0_LB_IRQ_INT_1_MASK 0x0000000001000000UL
+#define UV1H_EVENT_OCCURRED0_LB_IRQ_INT_2_SHFT 25
+#define UV1H_EVENT_OCCURRED0_LB_IRQ_INT_2_MASK 0x0000000002000000UL
+#define UV1H_EVENT_OCCURRED0_LB_IRQ_INT_3_SHFT 26
+#define UV1H_EVENT_OCCURRED0_LB_IRQ_INT_3_MASK 0x0000000004000000UL
+#define UV1H_EVENT_OCCURRED0_LB_IRQ_INT_4_SHFT 27
+#define UV1H_EVENT_OCCURRED0_LB_IRQ_INT_4_MASK 0x0000000008000000UL
+#define UV1H_EVENT_OCCURRED0_LB_IRQ_INT_5_SHFT 28
+#define UV1H_EVENT_OCCURRED0_LB_IRQ_INT_5_MASK 0x0000000010000000UL
+#define UV1H_EVENT_OCCURRED0_LB_IRQ_INT_6_SHFT 29
+#define UV1H_EVENT_OCCURRED0_LB_IRQ_INT_6_MASK 0x0000000020000000UL
+#define UV1H_EVENT_OCCURRED0_LB_IRQ_INT_7_SHFT 30
+#define UV1H_EVENT_OCCURRED0_LB_IRQ_INT_7_MASK 0x0000000040000000UL
+#define UV1H_EVENT_OCCURRED0_LB_IRQ_INT_8_SHFT 31
+#define UV1H_EVENT_OCCURRED0_LB_IRQ_INT_8_MASK 0x0000000080000000UL
+#define UV1H_EVENT_OCCURRED0_LB_IRQ_INT_9_SHFT 32
+#define UV1H_EVENT_OCCURRED0_LB_IRQ_INT_9_MASK 0x0000000100000000UL
+#define UV1H_EVENT_OCCURRED0_LB_IRQ_INT_10_SHFT 33
+#define UV1H_EVENT_OCCURRED0_LB_IRQ_INT_10_MASK 0x0000000200000000UL
+#define UV1H_EVENT_OCCURRED0_LB_IRQ_INT_11_SHFT 34
+#define UV1H_EVENT_OCCURRED0_LB_IRQ_INT_11_MASK 0x0000000400000000UL
+#define UV1H_EVENT_OCCURRED0_LB_IRQ_INT_12_SHFT 35
+#define UV1H_EVENT_OCCURRED0_LB_IRQ_INT_12_MASK 0x0000000800000000UL
+#define UV1H_EVENT_OCCURRED0_LB_IRQ_INT_13_SHFT 36
+#define UV1H_EVENT_OCCURRED0_LB_IRQ_INT_13_MASK 0x0000001000000000UL
+#define UV1H_EVENT_OCCURRED0_LB_IRQ_INT_14_SHFT 37
+#define UV1H_EVENT_OCCURRED0_LB_IRQ_INT_14_MASK 0x0000002000000000UL
+#define UV1H_EVENT_OCCURRED0_LB_IRQ_INT_15_SHFT 38
+#define UV1H_EVENT_OCCURRED0_LB_IRQ_INT_15_MASK 0x0000004000000000UL
+#define UV1H_EVENT_OCCURRED0_L1_NMI_INT_SHFT 39
+#define UV1H_EVENT_OCCURRED0_L1_NMI_INT_MASK 0x0000008000000000UL
+#define UV1H_EVENT_OCCURRED0_STOP_CLOCK_SHFT 40
+#define UV1H_EVENT_OCCURRED0_STOP_CLOCK_MASK 0x0000010000000000UL
+#define UV1H_EVENT_OCCURRED0_ASIC_TO_L1_SHFT 41
+#define UV1H_EVENT_OCCURRED0_ASIC_TO_L1_MASK 0x0000020000000000UL
+#define UV1H_EVENT_OCCURRED0_L1_TO_ASIC_SHFT 42
+#define UV1H_EVENT_OCCURRED0_L1_TO_ASIC_MASK 0x0000040000000000UL
+#define UV1H_EVENT_OCCURRED0_LTC_INT_SHFT 43
+#define UV1H_EVENT_OCCURRED0_LTC_INT_MASK 0x0000080000000000UL
+#define UV1H_EVENT_OCCURRED0_LA_SEQ_TRIGGER_SHFT 44
+#define UV1H_EVENT_OCCURRED0_LA_SEQ_TRIGGER_MASK 0x0000100000000000UL
+#define UV1H_EVENT_OCCURRED0_IPI_INT_SHFT 45
+#define UV1H_EVENT_OCCURRED0_IPI_INT_MASK 0x0000200000000000UL
+#define UV1H_EVENT_OCCURRED0_EXTIO_INT0_SHFT 46
+#define UV1H_EVENT_OCCURRED0_EXTIO_INT0_MASK 0x0000400000000000UL
+#define UV1H_EVENT_OCCURRED0_EXTIO_INT1_SHFT 47
+#define UV1H_EVENT_OCCURRED0_EXTIO_INT1_MASK 0x0000800000000000UL
+#define UV1H_EVENT_OCCURRED0_EXTIO_INT2_SHFT 48
+#define UV1H_EVENT_OCCURRED0_EXTIO_INT2_MASK 0x0001000000000000UL
+#define UV1H_EVENT_OCCURRED0_EXTIO_INT3_SHFT 49
+#define UV1H_EVENT_OCCURRED0_EXTIO_INT3_MASK 0x0002000000000000UL
+#define UV1H_EVENT_OCCURRED0_PROFILE_INT_SHFT 50
+#define UV1H_EVENT_OCCURRED0_PROFILE_INT_MASK 0x0004000000000000UL
+#define UV1H_EVENT_OCCURRED0_RTC0_SHFT 51
+#define UV1H_EVENT_OCCURRED0_RTC0_MASK 0x0008000000000000UL
+#define UV1H_EVENT_OCCURRED0_RTC1_SHFT 52
+#define UV1H_EVENT_OCCURRED0_RTC1_MASK 0x0010000000000000UL
+#define UV1H_EVENT_OCCURRED0_RTC2_SHFT 53
+#define UV1H_EVENT_OCCURRED0_RTC2_MASK 0x0020000000000000UL
+#define UV1H_EVENT_OCCURRED0_RTC3_SHFT 54
+#define UV1H_EVENT_OCCURRED0_RTC3_MASK 0x0040000000000000UL
+#define UV1H_EVENT_OCCURRED0_BAU_DATA_SHFT 55
+#define UV1H_EVENT_OCCURRED0_BAU_DATA_MASK 0x0080000000000000UL
+#define UV1H_EVENT_OCCURRED0_POWER_MANAGEMENT_REQ_SHFT 56
+#define UV1H_EVENT_OCCURRED0_POWER_MANAGEMENT_REQ_MASK 0x0100000000000000UL
+
+#define UV2H_EVENT_OCCURRED0_LB_HCERR_SHFT 0
+#define UV2H_EVENT_OCCURRED0_LB_HCERR_MASK 0x0000000000000001UL
+#define UV2H_EVENT_OCCURRED0_QP_HCERR_SHFT 1
+#define UV2H_EVENT_OCCURRED0_QP_HCERR_MASK 0x0000000000000002UL
+#define UV2H_EVENT_OCCURRED0_RH_HCERR_SHFT 2
+#define UV2H_EVENT_OCCURRED0_RH_HCERR_MASK 0x0000000000000004UL
+#define UV2H_EVENT_OCCURRED0_LH0_HCERR_SHFT 3
+#define UV2H_EVENT_OCCURRED0_LH0_HCERR_MASK 0x0000000000000008UL
+#define UV2H_EVENT_OCCURRED0_LH1_HCERR_SHFT 4
+#define UV2H_EVENT_OCCURRED0_LH1_HCERR_MASK 0x0000000000000010UL
+#define UV2H_EVENT_OCCURRED0_GR0_HCERR_SHFT 5
+#define UV2H_EVENT_OCCURRED0_GR0_HCERR_MASK 0x0000000000000020UL
+#define UV2H_EVENT_OCCURRED0_GR1_HCERR_SHFT 6
+#define UV2H_EVENT_OCCURRED0_GR1_HCERR_MASK 0x0000000000000040UL
+#define UV2H_EVENT_OCCURRED0_NI0_HCERR_SHFT 7
+#define UV2H_EVENT_OCCURRED0_NI0_HCERR_MASK 0x0000000000000080UL
+#define UV2H_EVENT_OCCURRED0_NI1_HCERR_SHFT 8
+#define UV2H_EVENT_OCCURRED0_NI1_HCERR_MASK 0x0000000000000100UL
+#define UV2H_EVENT_OCCURRED0_LB_AOERR0_SHFT 9
+#define UV2H_EVENT_OCCURRED0_LB_AOERR0_MASK 0x0000000000000200UL
+#define UV2H_EVENT_OCCURRED0_QP_AOERR0_SHFT 10
+#define UV2H_EVENT_OCCURRED0_QP_AOERR0_MASK 0x0000000000000400UL
+#define UV2H_EVENT_OCCURRED0_RH_AOERR0_SHFT 11
+#define UV2H_EVENT_OCCURRED0_RH_AOERR0_MASK 0x0000000000000800UL
+#define UV2H_EVENT_OCCURRED0_LH0_AOERR0_SHFT 12
+#define UV2H_EVENT_OCCURRED0_LH0_AOERR0_MASK 0x0000000000001000UL
+#define UV2H_EVENT_OCCURRED0_LH1_AOERR0_SHFT 13
+#define UV2H_EVENT_OCCURRED0_LH1_AOERR0_MASK 0x0000000000002000UL
+#define UV2H_EVENT_OCCURRED0_GR0_AOERR0_SHFT 14
+#define UV2H_EVENT_OCCURRED0_GR0_AOERR0_MASK 0x0000000000004000UL
+#define UV2H_EVENT_OCCURRED0_GR1_AOERR0_SHFT 15
+#define UV2H_EVENT_OCCURRED0_GR1_AOERR0_MASK 0x0000000000008000UL
+#define UV2H_EVENT_OCCURRED0_XB_AOERR0_SHFT 16
+#define UV2H_EVENT_OCCURRED0_XB_AOERR0_MASK 0x0000000000010000UL
+#define UV2H_EVENT_OCCURRED0_RT_AOERR0_SHFT 17
+#define UV2H_EVENT_OCCURRED0_RT_AOERR0_MASK 0x0000000000020000UL
+#define UV2H_EVENT_OCCURRED0_NI0_AOERR0_SHFT 18
+#define UV2H_EVENT_OCCURRED0_NI0_AOERR0_MASK 0x0000000000040000UL
+#define UV2H_EVENT_OCCURRED0_NI1_AOERR0_SHFT 19
+#define UV2H_EVENT_OCCURRED0_NI1_AOERR0_MASK 0x0000000000080000UL
+#define UV2H_EVENT_OCCURRED0_LB_AOERR1_SHFT 20
+#define UV2H_EVENT_OCCURRED0_LB_AOERR1_MASK 0x0000000000100000UL
+#define UV2H_EVENT_OCCURRED0_QP_AOERR1_SHFT 21
+#define UV2H_EVENT_OCCURRED0_QP_AOERR1_MASK 0x0000000000200000UL
+#define UV2H_EVENT_OCCURRED0_RH_AOERR1_SHFT 22
+#define UV2H_EVENT_OCCURRED0_RH_AOERR1_MASK 0x0000000000400000UL
+#define UV2H_EVENT_OCCURRED0_LH0_AOERR1_SHFT 23
+#define UV2H_EVENT_OCCURRED0_LH0_AOERR1_MASK 0x0000000000800000UL
+#define UV2H_EVENT_OCCURRED0_LH1_AOERR1_SHFT 24
+#define UV2H_EVENT_OCCURRED0_LH1_AOERR1_MASK 0x0000000001000000UL
+#define UV2H_EVENT_OCCURRED0_GR0_AOERR1_SHFT 25
+#define UV2H_EVENT_OCCURRED0_GR0_AOERR1_MASK 0x0000000002000000UL
+#define UV2H_EVENT_OCCURRED0_GR1_AOERR1_SHFT 26
+#define UV2H_EVENT_OCCURRED0_GR1_AOERR1_MASK 0x0000000004000000UL
+#define UV2H_EVENT_OCCURRED0_XB_AOERR1_SHFT 27
+#define UV2H_EVENT_OCCURRED0_XB_AOERR1_MASK 0x0000000008000000UL
+#define UV2H_EVENT_OCCURRED0_RT_AOERR1_SHFT 28
+#define UV2H_EVENT_OCCURRED0_RT_AOERR1_MASK 0x0000000010000000UL
+#define UV2H_EVENT_OCCURRED0_NI0_AOERR1_SHFT 29
+#define UV2H_EVENT_OCCURRED0_NI0_AOERR1_MASK 0x0000000020000000UL
+#define UV2H_EVENT_OCCURRED0_NI1_AOERR1_SHFT 30
+#define UV2H_EVENT_OCCURRED0_NI1_AOERR1_MASK 0x0000000040000000UL
+#define UV2H_EVENT_OCCURRED0_SYSTEM_SHUTDOWN_INT_SHFT 31
+#define UV2H_EVENT_OCCURRED0_SYSTEM_SHUTDOWN_INT_MASK 0x0000000080000000UL
+#define UV2H_EVENT_OCCURRED0_LB_IRQ_INT_0_SHFT 32
+#define UV2H_EVENT_OCCURRED0_LB_IRQ_INT_0_MASK 0x0000000100000000UL
+#define UV2H_EVENT_OCCURRED0_LB_IRQ_INT_1_SHFT 33
+#define UV2H_EVENT_OCCURRED0_LB_IRQ_INT_1_MASK 0x0000000200000000UL
+#define UV2H_EVENT_OCCURRED0_LB_IRQ_INT_2_SHFT 34
+#define UV2H_EVENT_OCCURRED0_LB_IRQ_INT_2_MASK 0x0000000400000000UL
+#define UV2H_EVENT_OCCURRED0_LB_IRQ_INT_3_SHFT 35
+#define UV2H_EVENT_OCCURRED0_LB_IRQ_INT_3_MASK 0x0000000800000000UL
+#define UV2H_EVENT_OCCURRED0_LB_IRQ_INT_4_SHFT 36
+#define UV2H_EVENT_OCCURRED0_LB_IRQ_INT_4_MASK 0x0000001000000000UL
+#define UV2H_EVENT_OCCURRED0_LB_IRQ_INT_5_SHFT 37
+#define UV2H_EVENT_OCCURRED0_LB_IRQ_INT_5_MASK 0x0000002000000000UL
+#define UV2H_EVENT_OCCURRED0_LB_IRQ_INT_6_SHFT 38
+#define UV2H_EVENT_OCCURRED0_LB_IRQ_INT_6_MASK 0x0000004000000000UL
+#define UV2H_EVENT_OCCURRED0_LB_IRQ_INT_7_SHFT 39
+#define UV2H_EVENT_OCCURRED0_LB_IRQ_INT_7_MASK 0x0000008000000000UL
+#define UV2H_EVENT_OCCURRED0_LB_IRQ_INT_8_SHFT 40
+#define UV2H_EVENT_OCCURRED0_LB_IRQ_INT_8_MASK 0x0000010000000000UL
+#define UV2H_EVENT_OCCURRED0_LB_IRQ_INT_9_SHFT 41
+#define UV2H_EVENT_OCCURRED0_LB_IRQ_INT_9_MASK 0x0000020000000000UL
+#define UV2H_EVENT_OCCURRED0_LB_IRQ_INT_10_SHFT 42
+#define UV2H_EVENT_OCCURRED0_LB_IRQ_INT_10_MASK 0x0000040000000000UL
+#define UV2H_EVENT_OCCURRED0_LB_IRQ_INT_11_SHFT 43
+#define UV2H_EVENT_OCCURRED0_LB_IRQ_INT_11_MASK 0x0000080000000000UL
+#define UV2H_EVENT_OCCURRED0_LB_IRQ_INT_12_SHFT 44
+#define UV2H_EVENT_OCCURRED0_LB_IRQ_INT_12_MASK 0x0000100000000000UL
+#define UV2H_EVENT_OCCURRED0_LB_IRQ_INT_13_SHFT 45
+#define UV2H_EVENT_OCCURRED0_LB_IRQ_INT_13_MASK 0x0000200000000000UL
+#define UV2H_EVENT_OCCURRED0_LB_IRQ_INT_14_SHFT 46
+#define UV2H_EVENT_OCCURRED0_LB_IRQ_INT_14_MASK 0x0000400000000000UL
+#define UV2H_EVENT_OCCURRED0_LB_IRQ_INT_15_SHFT 47
+#define UV2H_EVENT_OCCURRED0_LB_IRQ_INT_15_MASK 0x0000800000000000UL
+#define UV2H_EVENT_OCCURRED0_L1_NMI_INT_SHFT 48
+#define UV2H_EVENT_OCCURRED0_L1_NMI_INT_MASK 0x0001000000000000UL
+#define UV2H_EVENT_OCCURRED0_STOP_CLOCK_SHFT 49
+#define UV2H_EVENT_OCCURRED0_STOP_CLOCK_MASK 0x0002000000000000UL
+#define UV2H_EVENT_OCCURRED0_ASIC_TO_L1_SHFT 50
+#define UV2H_EVENT_OCCURRED0_ASIC_TO_L1_MASK 0x0004000000000000UL
+#define UV2H_EVENT_OCCURRED0_L1_TO_ASIC_SHFT 51
+#define UV2H_EVENT_OCCURRED0_L1_TO_ASIC_MASK 0x0008000000000000UL
+#define UV2H_EVENT_OCCURRED0_LA_SEQ_TRIGGER_SHFT 52
+#define UV2H_EVENT_OCCURRED0_LA_SEQ_TRIGGER_MASK 0x0010000000000000UL
+#define UV2H_EVENT_OCCURRED0_IPI_INT_SHFT 53
+#define UV2H_EVENT_OCCURRED0_IPI_INT_MASK 0x0020000000000000UL
+#define UV2H_EVENT_OCCURRED0_EXTIO_INT0_SHFT 54
+#define UV2H_EVENT_OCCURRED0_EXTIO_INT0_MASK 0x0040000000000000UL
+#define UV2H_EVENT_OCCURRED0_EXTIO_INT1_SHFT 55
+#define UV2H_EVENT_OCCURRED0_EXTIO_INT1_MASK 0x0080000000000000UL
+#define UV2H_EVENT_OCCURRED0_EXTIO_INT2_SHFT 56
+#define UV2H_EVENT_OCCURRED0_EXTIO_INT2_MASK 0x0100000000000000UL
+#define UV2H_EVENT_OCCURRED0_EXTIO_INT3_SHFT 57
+#define UV2H_EVENT_OCCURRED0_EXTIO_INT3_MASK 0x0200000000000000UL
+#define UV2H_EVENT_OCCURRED0_PROFILE_INT_SHFT 58
+#define UV2H_EVENT_OCCURRED0_PROFILE_INT_MASK 0x0400000000000000UL
 
-#define UVH_EVENT_OCCURRED0_LB_HCERR_SHFT 0
-#define UVH_EVENT_OCCURRED0_LB_HCERR_MASK 0x0000000000000001UL
-#define UVH_EVENT_OCCURRED0_GR0_HCERR_SHFT 1
-#define UVH_EVENT_OCCURRED0_GR0_HCERR_MASK 0x0000000000000002UL
-#define UVH_EVENT_OCCURRED0_GR1_HCERR_SHFT 2
-#define UVH_EVENT_OCCURRED0_GR1_HCERR_MASK 0x0000000000000004UL
-#define UVH_EVENT_OCCURRED0_LH_HCERR_SHFT 3
-#define UVH_EVENT_OCCURRED0_LH_HCERR_MASK 0x0000000000000008UL
-#define UVH_EVENT_OCCURRED0_RH_HCERR_SHFT 4
-#define UVH_EVENT_OCCURRED0_RH_HCERR_MASK 0x0000000000000010UL
-#define UVH_EVENT_OCCURRED0_XN_HCERR_SHFT 5
-#define UVH_EVENT_OCCURRED0_XN_HCERR_MASK 0x0000000000000020UL
-#define UVH_EVENT_OCCURRED0_SI_HCERR_SHFT 6
-#define UVH_EVENT_OCCURRED0_SI_HCERR_MASK 0x0000000000000040UL
-#define UVH_EVENT_OCCURRED0_LB_AOERR0_SHFT 7
-#define UVH_EVENT_OCCURRED0_LB_AOERR0_MASK 0x0000000000000080UL
-#define UVH_EVENT_OCCURRED0_GR0_AOERR0_SHFT 8
-#define UVH_EVENT_OCCURRED0_GR0_AOERR0_MASK 0x0000000000000100UL
-#define UVH_EVENT_OCCURRED0_GR1_AOERR0_SHFT 9
-#define UVH_EVENT_OCCURRED0_GR1_AOERR0_MASK 0x0000000000000200UL
-#define UVH_EVENT_OCCURRED0_LH_AOERR0_SHFT 10
-#define UVH_EVENT_OCCURRED0_LH_AOERR0_MASK 0x0000000000000400UL
-#define UVH_EVENT_OCCURRED0_RH_AOERR0_SHFT 11
-#define UVH_EVENT_OCCURRED0_RH_AOERR0_MASK 0x0000000000000800UL
-#define UVH_EVENT_OCCURRED0_XN_AOERR0_SHFT 12
-#define UVH_EVENT_OCCURRED0_XN_AOERR0_MASK 0x0000000000001000UL
-#define UVH_EVENT_OCCURRED0_SI_AOERR0_SHFT 13
-#define UVH_EVENT_OCCURRED0_SI_AOERR0_MASK 0x0000000000002000UL
-#define UVH_EVENT_OCCURRED0_LB_AOERR1_SHFT 14
-#define UVH_EVENT_OCCURRED0_LB_AOERR1_MASK 0x0000000000004000UL
-#define UVH_EVENT_OCCURRED0_GR0_AOERR1_SHFT 15
-#define UVH_EVENT_OCCURRED0_GR0_AOERR1_MASK 0x0000000000008000UL
-#define UVH_EVENT_OCCURRED0_GR1_AOERR1_SHFT 16
-#define UVH_EVENT_OCCURRED0_GR1_AOERR1_MASK 0x0000000000010000UL
-#define UVH_EVENT_OCCURRED0_LH_AOERR1_SHFT 17
-#define UVH_EVENT_OCCURRED0_LH_AOERR1_MASK 0x0000000000020000UL
-#define UVH_EVENT_OCCURRED0_RH_AOERR1_SHFT 18
-#define UVH_EVENT_OCCURRED0_RH_AOERR1_MASK 0x0000000000040000UL
-#define UVH_EVENT_OCCURRED0_XN_AOERR1_SHFT 19
-#define UVH_EVENT_OCCURRED0_XN_AOERR1_MASK 0x0000000000080000UL
-#define UVH_EVENT_OCCURRED0_SI_AOERR1_SHFT 20
-#define UVH_EVENT_OCCURRED0_SI_AOERR1_MASK 0x0000000000100000UL
-#define UVH_EVENT_OCCURRED0_RH_VPI_INT_SHFT 21
-#define UVH_EVENT_OCCURRED0_RH_VPI_INT_MASK 0x0000000000200000UL
-#define UVH_EVENT_OCCURRED0_SYSTEM_SHUTDOWN_INT_SHFT 22
-#define UVH_EVENT_OCCURRED0_SYSTEM_SHUTDOWN_INT_MASK 0x0000000000400000UL
-#define UVH_EVENT_OCCURRED0_LB_IRQ_INT_0_SHFT 23
-#define UVH_EVENT_OCCURRED0_LB_IRQ_INT_0_MASK 0x0000000000800000UL
-#define UVH_EVENT_OCCURRED0_LB_IRQ_INT_1_SHFT 24
-#define UVH_EVENT_OCCURRED0_LB_IRQ_INT_1_MASK 0x0000000001000000UL
-#define UVH_EVENT_OCCURRED0_LB_IRQ_INT_2_SHFT 25
-#define UVH_EVENT_OCCURRED0_LB_IRQ_INT_2_MASK 0x0000000002000000UL
-#define UVH_EVENT_OCCURRED0_LB_IRQ_INT_3_SHFT 26
-#define UVH_EVENT_OCCURRED0_LB_IRQ_INT_3_MASK 0x0000000004000000UL
-#define UVH_EVENT_OCCURRED0_LB_IRQ_INT_4_SHFT 27
-#define UVH_EVENT_OCCURRED0_LB_IRQ_INT_4_MASK 0x0000000008000000UL
-#define UVH_EVENT_OCCURRED0_LB_IRQ_INT_5_SHFT 28
-#define UVH_EVENT_OCCURRED0_LB_IRQ_INT_5_MASK 0x0000000010000000UL
-#define UVH_EVENT_OCCURRED0_LB_IRQ_INT_6_SHFT 29
-#define UVH_EVENT_OCCURRED0_LB_IRQ_INT_6_MASK 0x0000000020000000UL
-#define UVH_EVENT_OCCURRED0_LB_IRQ_INT_7_SHFT 30
-#define UVH_EVENT_OCCURRED0_LB_IRQ_INT_7_MASK 0x0000000040000000UL
-#define UVH_EVENT_OCCURRED0_LB_IRQ_INT_8_SHFT 31
-#define UVH_EVENT_OCCURRED0_LB_IRQ_INT_8_MASK 0x0000000080000000UL
-#define UVH_EVENT_OCCURRED0_LB_IRQ_INT_9_SHFT 32
-#define UVH_EVENT_OCCURRED0_LB_IRQ_INT_9_MASK 0x0000000100000000UL
-#define UVH_EVENT_OCCURRED0_LB_IRQ_INT_10_SHFT 33
-#define UVH_EVENT_OCCURRED0_LB_IRQ_INT_10_MASK 0x0000000200000000UL
-#define UVH_EVENT_OCCURRED0_LB_IRQ_INT_11_SHFT 34
-#define UVH_EVENT_OCCURRED0_LB_IRQ_INT_11_MASK 0x0000000400000000UL
-#define UVH_EVENT_OCCURRED0_LB_IRQ_INT_12_SHFT 35
-#define UVH_EVENT_OCCURRED0_LB_IRQ_INT_12_MASK 0x0000000800000000UL
-#define UVH_EVENT_OCCURRED0_LB_IRQ_INT_13_SHFT 36
-#define UVH_EVENT_OCCURRED0_LB_IRQ_INT_13_MASK 0x0000001000000000UL
-#define UVH_EVENT_OCCURRED0_LB_IRQ_INT_14_SHFT 37
-#define UVH_EVENT_OCCURRED0_LB_IRQ_INT_14_MASK 0x0000002000000000UL
-#define UVH_EVENT_OCCURRED0_LB_IRQ_INT_15_SHFT 38
-#define UVH_EVENT_OCCURRED0_LB_IRQ_INT_15_MASK 0x0000004000000000UL
-#define UVH_EVENT_OCCURRED0_L1_NMI_INT_SHFT 39
-#define UVH_EVENT_OCCURRED0_L1_NMI_INT_MASK 0x0000008000000000UL
-#define UVH_EVENT_OCCURRED0_STOP_CLOCK_SHFT 40
-#define UVH_EVENT_OCCURRED0_STOP_CLOCK_MASK 0x0000010000000000UL
-#define UVH_EVENT_OCCURRED0_ASIC_TO_L1_SHFT 41
-#define UVH_EVENT_OCCURRED0_ASIC_TO_L1_MASK 0x0000020000000000UL
-#define UVH_EVENT_OCCURRED0_L1_TO_ASIC_SHFT 42
-#define UVH_EVENT_OCCURRED0_L1_TO_ASIC_MASK 0x0000040000000000UL
-#define UVH_EVENT_OCCURRED0_LTC_INT_SHFT 43
-#define UVH_EVENT_OCCURRED0_LTC_INT_MASK 0x0000080000000000UL
-#define UVH_EVENT_OCCURRED0_LA_SEQ_TRIGGER_SHFT 44
-#define UVH_EVENT_OCCURRED0_LA_SEQ_TRIGGER_MASK 0x0000100000000000UL
-#define UVH_EVENT_OCCURRED0_IPI_INT_SHFT 45
-#define UVH_EVENT_OCCURRED0_IPI_INT_MASK 0x0000200000000000UL
-#define UVH_EVENT_OCCURRED0_EXTIO_INT0_SHFT 46
-#define UVH_EVENT_OCCURRED0_EXTIO_INT0_MASK 0x0000400000000000UL
-#define UVH_EVENT_OCCURRED0_EXTIO_INT1_SHFT 47
-#define UVH_EVENT_OCCURRED0_EXTIO_INT1_MASK 0x0000800000000000UL
-#define UVH_EVENT_OCCURRED0_EXTIO_INT2_SHFT 48
-#define UVH_EVENT_OCCURRED0_EXTIO_INT2_MASK 0x0001000000000000UL
-#define UVH_EVENT_OCCURRED0_EXTIO_INT3_SHFT 49
-#define UVH_EVENT_OCCURRED0_EXTIO_INT3_MASK 0x0002000000000000UL
-#define UVH_EVENT_OCCURRED0_PROFILE_INT_SHFT 50
-#define UVH_EVENT_OCCURRED0_PROFILE_INT_MASK 0x0004000000000000UL
-#define UVH_EVENT_OCCURRED0_RTC0_SHFT 51
-#define UVH_EVENT_OCCURRED0_RTC0_MASK 0x0008000000000000UL
-#define UVH_EVENT_OCCURRED0_RTC1_SHFT 52
-#define UVH_EVENT_OCCURRED0_RTC1_MASK 0x0010000000000000UL
-#define UVH_EVENT_OCCURRED0_RTC2_SHFT 53
-#define UVH_EVENT_OCCURRED0_RTC2_MASK 0x0020000000000000UL
-#define UVH_EVENT_OCCURRED0_RTC3_SHFT 54
-#define UVH_EVENT_OCCURRED0_RTC3_MASK 0x0040000000000000UL
-#define UVH_EVENT_OCCURRED0_BAU_DATA_SHFT 55
-#define UVH_EVENT_OCCURRED0_BAU_DATA_MASK 0x0080000000000000UL
-#define UVH_EVENT_OCCURRED0_POWER_MANAGEMENT_REQ_SHFT 56
-#define UVH_EVENT_OCCURRED0_POWER_MANAGEMENT_REQ_MASK 0x0100000000000000UL
 union uvh_event_occurred0_u {
     unsigned long	v;
-    struct uvh_event_occurred0_s {
+    struct uv1h_event_occurred0_s {
 	unsigned long	lb_hcerr             :  1;  /* RW, W1C */
 	unsigned long	gr0_hcerr            :  1;  /* RW, W1C */
 	unsigned long	gr1_hcerr            :  1;  /* RW, W1C */
@@ -250,14 +421,76 @@
 	unsigned long	bau_data             :  1;  /* RW, W1C */
 	unsigned long	power_management_req :  1;  /* RW, W1C */
 	unsigned long	rsvd_57_63           :  7;  /*    */
-    } s;
+    } s1;
+    struct uv2h_event_occurred0_s {
+	unsigned long	lb_hcerr            :  1;  /* RW */
+	unsigned long	qp_hcerr            :  1;  /* RW */
+	unsigned long	rh_hcerr            :  1;  /* RW */
+	unsigned long	lh0_hcerr           :  1;  /* RW */
+	unsigned long	lh1_hcerr           :  1;  /* RW */
+	unsigned long	gr0_hcerr           :  1;  /* RW */
+	unsigned long	gr1_hcerr           :  1;  /* RW */
+	unsigned long	ni0_hcerr           :  1;  /* RW */
+	unsigned long	ni1_hcerr           :  1;  /* RW */
+	unsigned long	lb_aoerr0           :  1;  /* RW */
+	unsigned long	qp_aoerr0           :  1;  /* RW */
+	unsigned long	rh_aoerr0           :  1;  /* RW */
+	unsigned long	lh0_aoerr0          :  1;  /* RW */
+	unsigned long	lh1_aoerr0          :  1;  /* RW */
+	unsigned long	gr0_aoerr0          :  1;  /* RW */
+	unsigned long	gr1_aoerr0          :  1;  /* RW */
+	unsigned long	xb_aoerr0           :  1;  /* RW */
+	unsigned long	rt_aoerr0           :  1;  /* RW */
+	unsigned long	ni0_aoerr0          :  1;  /* RW */
+	unsigned long	ni1_aoerr0          :  1;  /* RW */
+	unsigned long	lb_aoerr1           :  1;  /* RW */
+	unsigned long	qp_aoerr1           :  1;  /* RW */
+	unsigned long	rh_aoerr1           :  1;  /* RW */
+	unsigned long	lh0_aoerr1          :  1;  /* RW */
+	unsigned long	lh1_aoerr1          :  1;  /* RW */
+	unsigned long	gr0_aoerr1          :  1;  /* RW */
+	unsigned long	gr1_aoerr1          :  1;  /* RW */
+	unsigned long	xb_aoerr1           :  1;  /* RW */
+	unsigned long	rt_aoerr1           :  1;  /* RW */
+	unsigned long	ni0_aoerr1          :  1;  /* RW */
+	unsigned long	ni1_aoerr1          :  1;  /* RW */
+	unsigned long	system_shutdown_int :  1;  /* RW */
+	unsigned long	lb_irq_int_0        :  1;  /* RW */
+	unsigned long	lb_irq_int_1        :  1;  /* RW */
+	unsigned long	lb_irq_int_2        :  1;  /* RW */
+	unsigned long	lb_irq_int_3        :  1;  /* RW */
+	unsigned long	lb_irq_int_4        :  1;  /* RW */
+	unsigned long	lb_irq_int_5        :  1;  /* RW */
+	unsigned long	lb_irq_int_6        :  1;  /* RW */
+	unsigned long	lb_irq_int_7        :  1;  /* RW */
+	unsigned long	lb_irq_int_8        :  1;  /* RW */
+	unsigned long	lb_irq_int_9        :  1;  /* RW */
+	unsigned long	lb_irq_int_10       :  1;  /* RW */
+	unsigned long	lb_irq_int_11       :  1;  /* RW */
+	unsigned long	lb_irq_int_12       :  1;  /* RW */
+	unsigned long	lb_irq_int_13       :  1;  /* RW */
+	unsigned long	lb_irq_int_14       :  1;  /* RW */
+	unsigned long	lb_irq_int_15       :  1;  /* RW */
+	unsigned long	l1_nmi_int          :  1;  /* RW */
+	unsigned long	stop_clock          :  1;  /* RW */
+	unsigned long	asic_to_l1          :  1;  /* RW */
+	unsigned long	l1_to_asic          :  1;  /* RW */
+	unsigned long	la_seq_trigger      :  1;  /* RW */
+	unsigned long	ipi_int             :  1;  /* RW */
+	unsigned long	extio_int0          :  1;  /* RW */
+	unsigned long	extio_int1          :  1;  /* RW */
+	unsigned long	extio_int2          :  1;  /* RW */
+	unsigned long	extio_int3          :  1;  /* RW */
+	unsigned long	profile_int         :  1;  /* RW */
+	unsigned long	rsvd_59_63          :  5;  /*    */
+    } s2;
 };
 
 /* ========================================================================= */
 /*                        UVH_EVENT_OCCURRED0_ALIAS                          */
 /* ========================================================================= */
 #define UVH_EVENT_OCCURRED0_ALIAS 0x0000000000070008UL
-#define UVH_EVENT_OCCURRED0_ALIAS_32 0x005f0
+#define UVH_EVENT_OCCURRED0_ALIAS_32 0x5f0
 
 /* ========================================================================= */
 /*                         UVH_GR0_TLB_INT0_CONFIG                           */
@@ -432,8 +665,16 @@
 /* ========================================================================= */
 #define UVH_INT_CMPC 0x22100UL
 
-#define UVH_INT_CMPC_REAL_TIME_CMPC_SHFT 0
-#define UVH_INT_CMPC_REAL_TIME_CMPC_MASK 0x00ffffffffffffffUL
+#define UV1H_INT_CMPC_REAL_TIME_CMPC_SHFT	0
+#define UV2H_INT_CMPC_REAL_TIME_CMPC_SHFT	0
+#define UVH_INT_CMPC_REAL_TIME_CMPC_SHFT	(is_uv1_hub() ?		\
+			UV1H_INT_CMPC_REAL_TIME_CMPC_SHFT :	\
+			UV2H_INT_CMPC_REAL_TIME_CMPC_SHFT)
+#define UV1H_INT_CMPC_REAL_TIME_CMPC_MASK	0xffffffffffffffUL
+#define UV2H_INT_CMPC_REAL_TIME_CMPC_MASK	0xffffffffffffffUL
+#define UVH_INT_CMPC_REAL_TIME_CMPC_MASK	(is_uv1_hub() ?		\
+			UV1H_INT_CMPC_REAL_TIME_CMPC_MASK :	\
+			UV2H_INT_CMPC_REAL_TIME_CMPC_MASK)
 
 union uvh_int_cmpc_u {
     unsigned long	v;
@@ -448,8 +689,16 @@
 /* ========================================================================= */
 #define UVH_INT_CMPD 0x22180UL
 
-#define UVH_INT_CMPD_REAL_TIME_CMPD_SHFT 0
-#define UVH_INT_CMPD_REAL_TIME_CMPD_MASK 0x00ffffffffffffffUL
+#define UV1H_INT_CMPD_REAL_TIME_CMPD_SHFT	0
+#define UV2H_INT_CMPD_REAL_TIME_CMPD_SHFT	0
+#define UVH_INT_CMPD_REAL_TIME_CMPD_SHFT	(is_uv1_hub() ?		\
+			UV1H_INT_CMPD_REAL_TIME_CMPD_SHFT :	\
+			UV2H_INT_CMPD_REAL_TIME_CMPD_SHFT)
+#define UV1H_INT_CMPD_REAL_TIME_CMPD_MASK	0xffffffffffffffUL
+#define UV2H_INT_CMPD_REAL_TIME_CMPD_MASK	0xffffffffffffffUL
+#define UVH_INT_CMPD_REAL_TIME_CMPD_MASK	(is_uv1_hub() ?		\
+			UV1H_INT_CMPD_REAL_TIME_CMPD_MASK :	\
+			UV2H_INT_CMPD_REAL_TIME_CMPD_MASK)
 
 union uvh_int_cmpd_u {
     unsigned long	v;
@@ -463,7 +712,7 @@
 /*                               UVH_IPI_INT                                 */
 /* ========================================================================= */
 #define UVH_IPI_INT 0x60500UL
-#define UVH_IPI_INT_32 0x0348
+#define UVH_IPI_INT_32 0x348
 
 #define UVH_IPI_INT_VECTOR_SHFT 0
 #define UVH_IPI_INT_VECTOR_MASK 0x00000000000000ffUL
@@ -493,7 +742,7 @@
 /*                   UVH_LB_BAU_INTD_PAYLOAD_QUEUE_FIRST                     */
 /* ========================================================================= */
 #define UVH_LB_BAU_INTD_PAYLOAD_QUEUE_FIRST 0x320050UL
-#define UVH_LB_BAU_INTD_PAYLOAD_QUEUE_FIRST_32 0x009c0
+#define UVH_LB_BAU_INTD_PAYLOAD_QUEUE_FIRST_32 0x9c0
 
 #define UVH_LB_BAU_INTD_PAYLOAD_QUEUE_FIRST_ADDRESS_SHFT 4
 #define UVH_LB_BAU_INTD_PAYLOAD_QUEUE_FIRST_ADDRESS_MASK 0x000007fffffffff0UL
@@ -515,7 +764,7 @@
 /*                    UVH_LB_BAU_INTD_PAYLOAD_QUEUE_LAST                     */
 /* ========================================================================= */
 #define UVH_LB_BAU_INTD_PAYLOAD_QUEUE_LAST 0x320060UL
-#define UVH_LB_BAU_INTD_PAYLOAD_QUEUE_LAST_32 0x009c8
+#define UVH_LB_BAU_INTD_PAYLOAD_QUEUE_LAST_32 0x9c8
 
 #define UVH_LB_BAU_INTD_PAYLOAD_QUEUE_LAST_ADDRESS_SHFT 4
 #define UVH_LB_BAU_INTD_PAYLOAD_QUEUE_LAST_ADDRESS_MASK 0x000007fffffffff0UL
@@ -533,7 +782,7 @@
 /*                    UVH_LB_BAU_INTD_PAYLOAD_QUEUE_TAIL                     */
 /* ========================================================================= */
 #define UVH_LB_BAU_INTD_PAYLOAD_QUEUE_TAIL 0x320070UL
-#define UVH_LB_BAU_INTD_PAYLOAD_QUEUE_TAIL_32 0x009d0
+#define UVH_LB_BAU_INTD_PAYLOAD_QUEUE_TAIL_32 0x9d0
 
 #define UVH_LB_BAU_INTD_PAYLOAD_QUEUE_TAIL_ADDRESS_SHFT 4
 #define UVH_LB_BAU_INTD_PAYLOAD_QUEUE_TAIL_ADDRESS_MASK 0x000007fffffffff0UL
@@ -551,7 +800,7 @@
 /*                   UVH_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE                    */
 /* ========================================================================= */
 #define UVH_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE 0x320080UL
-#define UVH_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE_32 0x0a68
+#define UVH_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE_32 0xa68
 
 #define UVH_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE_PENDING_0_SHFT 0
 #define UVH_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE_PENDING_0_MASK 0x0000000000000001UL
@@ -585,6 +834,7 @@
 #define UVH_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE_TIMEOUT_6_MASK 0x0000000000004000UL
 #define UVH_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE_TIMEOUT_7_SHFT 15
 #define UVH_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE_TIMEOUT_7_MASK 0x0000000000008000UL
+
 union uvh_lb_bau_intd_software_acknowledge_u {
     unsigned long	v;
     struct uvh_lb_bau_intd_software_acknowledge_s {
@@ -612,13 +862,13 @@
 /*                UVH_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE_ALIAS                 */
 /* ========================================================================= */
 #define UVH_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE_ALIAS 0x0000000000320088UL
-#define UVH_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE_ALIAS_32 0x0a70
+#define UVH_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE_ALIAS_32 0xa70
 
 /* ========================================================================= */
 /*                         UVH_LB_BAU_MISC_CONTROL                           */
 /* ========================================================================= */
 #define UVH_LB_BAU_MISC_CONTROL 0x320170UL
-#define UVH_LB_BAU_MISC_CONTROL_32 0x00a10
+#define UVH_LB_BAU_MISC_CONTROL_32 0xa10
 
 #define UVH_LB_BAU_MISC_CONTROL_REJECTION_DELAY_SHFT 0
 #define UVH_LB_BAU_MISC_CONTROL_REJECTION_DELAY_MASK 0x00000000000000ffUL
@@ -628,8 +878,8 @@
 #define UVH_LB_BAU_MISC_CONTROL_FORCE_BROADCAST_MASK 0x0000000000000200UL
 #define UVH_LB_BAU_MISC_CONTROL_FORCE_LOCK_NOP_SHFT 10
 #define UVH_LB_BAU_MISC_CONTROL_FORCE_LOCK_NOP_MASK 0x0000000000000400UL
-#define UVH_LB_BAU_MISC_CONTROL_CSI_AGENT_PRESENCE_VECTOR_SHFT 11
-#define UVH_LB_BAU_MISC_CONTROL_CSI_AGENT_PRESENCE_VECTOR_MASK 0x0000000000003800UL
+#define UVH_LB_BAU_MISC_CONTROL_QPI_AGENT_PRESENCE_VECTOR_SHFT 11
+#define UVH_LB_BAU_MISC_CONTROL_QPI_AGENT_PRESENCE_VECTOR_MASK 0x0000000000003800UL
 #define UVH_LB_BAU_MISC_CONTROL_DESCRIPTOR_FETCH_MODE_SHFT 14
 #define UVH_LB_BAU_MISC_CONTROL_DESCRIPTOR_FETCH_MODE_MASK 0x0000000000004000UL
 #define UVH_LB_BAU_MISC_CONTROL_ENABLE_INTD_SOFT_ACK_MODE_SHFT 15
@@ -650,8 +900,86 @@
 #define UVH_LB_BAU_MISC_CONTROL_USE_INCOMING_PRIORITY_MASK 0x0000000008000000UL
 #define UVH_LB_BAU_MISC_CONTROL_ENABLE_PROGRAMMED_INITIAL_PRIORITY_SHFT 28
 #define UVH_LB_BAU_MISC_CONTROL_ENABLE_PROGRAMMED_INITIAL_PRIORITY_MASK 0x0000000010000000UL
-#define UVH_LB_BAU_MISC_CONTROL_FUN_SHFT 48
-#define UVH_LB_BAU_MISC_CONTROL_FUN_MASK 0xffff000000000000UL
+
+#define UV1H_LB_BAU_MISC_CONTROL_REJECTION_DELAY_SHFT 0
+#define UV1H_LB_BAU_MISC_CONTROL_REJECTION_DELAY_MASK 0x00000000000000ffUL
+#define UV1H_LB_BAU_MISC_CONTROL_APIC_MODE_SHFT 8
+#define UV1H_LB_BAU_MISC_CONTROL_APIC_MODE_MASK 0x0000000000000100UL
+#define UV1H_LB_BAU_MISC_CONTROL_FORCE_BROADCAST_SHFT 9
+#define UV1H_LB_BAU_MISC_CONTROL_FORCE_BROADCAST_MASK 0x0000000000000200UL
+#define UV1H_LB_BAU_MISC_CONTROL_FORCE_LOCK_NOP_SHFT 10
+#define UV1H_LB_BAU_MISC_CONTROL_FORCE_LOCK_NOP_MASK 0x0000000000000400UL
+#define UV1H_LB_BAU_MISC_CONTROL_QPI_AGENT_PRESENCE_VECTOR_SHFT 11
+#define UV1H_LB_BAU_MISC_CONTROL_QPI_AGENT_PRESENCE_VECTOR_MASK 0x0000000000003800UL
+#define UV1H_LB_BAU_MISC_CONTROL_DESCRIPTOR_FETCH_MODE_SHFT 14
+#define UV1H_LB_BAU_MISC_CONTROL_DESCRIPTOR_FETCH_MODE_MASK 0x0000000000004000UL
+#define UV1H_LB_BAU_MISC_CONTROL_ENABLE_INTD_SOFT_ACK_MODE_SHFT 15
+#define UV1H_LB_BAU_MISC_CONTROL_ENABLE_INTD_SOFT_ACK_MODE_MASK 0x0000000000008000UL
+#define UV1H_LB_BAU_MISC_CONTROL_INTD_SOFT_ACK_TIMEOUT_PERIOD_SHFT 16
+#define UV1H_LB_BAU_MISC_CONTROL_INTD_SOFT_ACK_TIMEOUT_PERIOD_MASK 0x00000000000f0000UL
+#define UV1H_LB_BAU_MISC_CONTROL_ENABLE_DUAL_MAPPING_MODE_SHFT 20
+#define UV1H_LB_BAU_MISC_CONTROL_ENABLE_DUAL_MAPPING_MODE_MASK 0x0000000000100000UL
+#define UV1H_LB_BAU_MISC_CONTROL_VGA_IO_PORT_DECODE_ENABLE_SHFT 21
+#define UV1H_LB_BAU_MISC_CONTROL_VGA_IO_PORT_DECODE_ENABLE_MASK 0x0000000000200000UL
+#define UV1H_LB_BAU_MISC_CONTROL_VGA_IO_PORT_16_BIT_DECODE_SHFT 22
+#define UV1H_LB_BAU_MISC_CONTROL_VGA_IO_PORT_16_BIT_DECODE_MASK 0x0000000000400000UL
+#define UV1H_LB_BAU_MISC_CONTROL_SUPPRESS_DEST_REGISTRATION_SHFT 23
+#define UV1H_LB_BAU_MISC_CONTROL_SUPPRESS_DEST_REGISTRATION_MASK 0x0000000000800000UL
+#define UV1H_LB_BAU_MISC_CONTROL_PROGRAMMED_INITIAL_PRIORITY_SHFT 24
+#define UV1H_LB_BAU_MISC_CONTROL_PROGRAMMED_INITIAL_PRIORITY_MASK 0x0000000007000000UL
+#define UV1H_LB_BAU_MISC_CONTROL_USE_INCOMING_PRIORITY_SHFT 27
+#define UV1H_LB_BAU_MISC_CONTROL_USE_INCOMING_PRIORITY_MASK 0x0000000008000000UL
+#define UV1H_LB_BAU_MISC_CONTROL_ENABLE_PROGRAMMED_INITIAL_PRIORITY_SHFT 28
+#define UV1H_LB_BAU_MISC_CONTROL_ENABLE_PROGRAMMED_INITIAL_PRIORITY_MASK 0x0000000010000000UL
+#define UV1H_LB_BAU_MISC_CONTROL_FUN_SHFT 48
+#define UV1H_LB_BAU_MISC_CONTROL_FUN_MASK 0xffff000000000000UL
+
+#define UV2H_LB_BAU_MISC_CONTROL_REJECTION_DELAY_SHFT 0
+#define UV2H_LB_BAU_MISC_CONTROL_REJECTION_DELAY_MASK 0x00000000000000ffUL
+#define UV2H_LB_BAU_MISC_CONTROL_APIC_MODE_SHFT 8
+#define UV2H_LB_BAU_MISC_CONTROL_APIC_MODE_MASK 0x0000000000000100UL
+#define UV2H_LB_BAU_MISC_CONTROL_FORCE_BROADCAST_SHFT 9
+#define UV2H_LB_BAU_MISC_CONTROL_FORCE_BROADCAST_MASK 0x0000000000000200UL
+#define UV2H_LB_BAU_MISC_CONTROL_FORCE_LOCK_NOP_SHFT 10
+#define UV2H_LB_BAU_MISC_CONTROL_FORCE_LOCK_NOP_MASK 0x0000000000000400UL
+#define UV2H_LB_BAU_MISC_CONTROL_QPI_AGENT_PRESENCE_VECTOR_SHFT 11
+#define UV2H_LB_BAU_MISC_CONTROL_QPI_AGENT_PRESENCE_VECTOR_MASK 0x0000000000003800UL
+#define UV2H_LB_BAU_MISC_CONTROL_DESCRIPTOR_FETCH_MODE_SHFT 14
+#define UV2H_LB_BAU_MISC_CONTROL_DESCRIPTOR_FETCH_MODE_MASK 0x0000000000004000UL
+#define UV2H_LB_BAU_MISC_CONTROL_ENABLE_INTD_SOFT_ACK_MODE_SHFT 15
+#define UV2H_LB_BAU_MISC_CONTROL_ENABLE_INTD_SOFT_ACK_MODE_MASK 0x0000000000008000UL
+#define UV2H_LB_BAU_MISC_CONTROL_INTD_SOFT_ACK_TIMEOUT_PERIOD_SHFT 16
+#define UV2H_LB_BAU_MISC_CONTROL_INTD_SOFT_ACK_TIMEOUT_PERIOD_MASK 0x00000000000f0000UL
+#define UV2H_LB_BAU_MISC_CONTROL_ENABLE_DUAL_MAPPING_MODE_SHFT 20
+#define UV2H_LB_BAU_MISC_CONTROL_ENABLE_DUAL_MAPPING_MODE_MASK 0x0000000000100000UL
+#define UV2H_LB_BAU_MISC_CONTROL_VGA_IO_PORT_DECODE_ENABLE_SHFT 21
+#define UV2H_LB_BAU_MISC_CONTROL_VGA_IO_PORT_DECODE_ENABLE_MASK 0x0000000000200000UL
+#define UV2H_LB_BAU_MISC_CONTROL_VGA_IO_PORT_16_BIT_DECODE_SHFT 22
+#define UV2H_LB_BAU_MISC_CONTROL_VGA_IO_PORT_16_BIT_DECODE_MASK 0x0000000000400000UL
+#define UV2H_LB_BAU_MISC_CONTROL_SUPPRESS_DEST_REGISTRATION_SHFT 23
+#define UV2H_LB_BAU_MISC_CONTROL_SUPPRESS_DEST_REGISTRATION_MASK 0x0000000000800000UL
+#define UV2H_LB_BAU_MISC_CONTROL_PROGRAMMED_INITIAL_PRIORITY_SHFT 24
+#define UV2H_LB_BAU_MISC_CONTROL_PROGRAMMED_INITIAL_PRIORITY_MASK 0x0000000007000000UL
+#define UV2H_LB_BAU_MISC_CONTROL_USE_INCOMING_PRIORITY_SHFT 27
+#define UV2H_LB_BAU_MISC_CONTROL_USE_INCOMING_PRIORITY_MASK 0x0000000008000000UL
+#define UV2H_LB_BAU_MISC_CONTROL_ENABLE_PROGRAMMED_INITIAL_PRIORITY_SHFT 28
+#define UV2H_LB_BAU_MISC_CONTROL_ENABLE_PROGRAMMED_INITIAL_PRIORITY_MASK 0x0000000010000000UL
+#define UV2H_LB_BAU_MISC_CONTROL_ENABLE_AUTOMATIC_APIC_MODE_SELECTION_SHFT 29
+#define UV2H_LB_BAU_MISC_CONTROL_ENABLE_AUTOMATIC_APIC_MODE_SELECTION_MASK 0x0000000020000000UL
+#define UV2H_LB_BAU_MISC_CONTROL_APIC_MODE_STATUS_SHFT 30
+#define UV2H_LB_BAU_MISC_CONTROL_APIC_MODE_STATUS_MASK 0x0000000040000000UL
+#define UV2H_LB_BAU_MISC_CONTROL_SUPPRESS_INTERRUPTS_TO_SELF_SHFT 31
+#define UV2H_LB_BAU_MISC_CONTROL_SUPPRESS_INTERRUPTS_TO_SELF_MASK 0x0000000080000000UL
+#define UV2H_LB_BAU_MISC_CONTROL_ENABLE_LOCK_BASED_SYSTEM_FLUSH_SHFT 32
+#define UV2H_LB_BAU_MISC_CONTROL_ENABLE_LOCK_BASED_SYSTEM_FLUSH_MASK 0x0000000100000000UL
+#define UV2H_LB_BAU_MISC_CONTROL_ENABLE_EXTENDED_SB_STATUS_SHFT 33
+#define UV2H_LB_BAU_MISC_CONTROL_ENABLE_EXTENDED_SB_STATUS_MASK 0x0000000200000000UL
+#define UV2H_LB_BAU_MISC_CONTROL_SUPPRESS_INT_PRIO_UDT_TO_SELF_SHFT 34
+#define UV2H_LB_BAU_MISC_CONTROL_SUPPRESS_INT_PRIO_UDT_TO_SELF_MASK 0x0000000400000000UL
+#define UV2H_LB_BAU_MISC_CONTROL_USE_LEGACY_DESCRIPTOR_FORMATS_SHFT 35
+#define UV2H_LB_BAU_MISC_CONTROL_USE_LEGACY_DESCRIPTOR_FORMATS_MASK 0x0000000800000000UL
+#define UV2H_LB_BAU_MISC_CONTROL_FUN_SHFT 48
+#define UV2H_LB_BAU_MISC_CONTROL_FUN_MASK 0xffff000000000000UL
 
 union uvh_lb_bau_misc_control_u {
     unsigned long	v;
@@ -660,7 +988,25 @@
 	unsigned long	apic_mode                          :  1;  /* RW */
 	unsigned long	force_broadcast                    :  1;  /* RW */
 	unsigned long	force_lock_nop                     :  1;  /* RW */
-	unsigned long	csi_agent_presence_vector          :  3;  /* RW */
+	unsigned long	qpi_agent_presence_vector          :  3;  /* RW */
+	unsigned long	descriptor_fetch_mode              :  1;  /* RW */
+	unsigned long	enable_intd_soft_ack_mode          :  1;  /* RW */
+	unsigned long	intd_soft_ack_timeout_period       :  4;  /* RW */
+	unsigned long	enable_dual_mapping_mode           :  1;  /* RW */
+	unsigned long	vga_io_port_decode_enable          :  1;  /* RW */
+	unsigned long	vga_io_port_16_bit_decode          :  1;  /* RW */
+	unsigned long	suppress_dest_registration         :  1;  /* RW */
+	unsigned long	programmed_initial_priority        :  3;  /* RW */
+	unsigned long	use_incoming_priority              :  1;  /* RW */
+	unsigned long	enable_programmed_initial_priority :  1;  /* RW */
+	unsigned long	rsvd_29_63    : 35;
+    } s;
+    struct uv1h_lb_bau_misc_control_s {
+	unsigned long	rejection_delay                    :  8;  /* RW */
+	unsigned long	apic_mode                          :  1;  /* RW */
+	unsigned long	force_broadcast                    :  1;  /* RW */
+	unsigned long	force_lock_nop                     :  1;  /* RW */
+	unsigned long	qpi_agent_presence_vector          :  3;  /* RW */
 	unsigned long	descriptor_fetch_mode              :  1;  /* RW */
 	unsigned long	enable_intd_soft_ack_mode          :  1;  /* RW */
 	unsigned long	intd_soft_ack_timeout_period       :  4;  /* RW */
@@ -673,14 +1019,40 @@
 	unsigned long	enable_programmed_initial_priority :  1;  /* RW */
 	unsigned long	rsvd_29_47                         : 19;  /*    */
 	unsigned long	fun                                : 16;  /* RW */
-    } s;
+    } s1;
+    struct uv2h_lb_bau_misc_control_s {
+	unsigned long	rejection_delay                      :  8;  /* RW */
+	unsigned long	apic_mode                            :  1;  /* RW */
+	unsigned long	force_broadcast                      :  1;  /* RW */
+	unsigned long	force_lock_nop                       :  1;  /* RW */
+	unsigned long	qpi_agent_presence_vector            :  3;  /* RW */
+	unsigned long	descriptor_fetch_mode                :  1;  /* RW */
+	unsigned long	enable_intd_soft_ack_mode            :  1;  /* RW */
+	unsigned long	intd_soft_ack_timeout_period         :  4;  /* RW */
+	unsigned long	enable_dual_mapping_mode             :  1;  /* RW */
+	unsigned long	vga_io_port_decode_enable            :  1;  /* RW */
+	unsigned long	vga_io_port_16_bit_decode            :  1;  /* RW */
+	unsigned long	suppress_dest_registration           :  1;  /* RW */
+	unsigned long	programmed_initial_priority          :  3;  /* RW */
+	unsigned long	use_incoming_priority                :  1;  /* RW */
+	unsigned long	enable_programmed_initial_priority   :  1;  /* RW */
+	unsigned long	enable_automatic_apic_mode_selection :  1;  /* RW */
+	unsigned long	apic_mode_status                     :  1;  /* RO */
+	unsigned long	suppress_interrupts_to_self          :  1;  /* RW */
+	unsigned long	enable_lock_based_system_flush       :  1;  /* RW */
+	unsigned long	enable_extended_sb_status            :  1;  /* RW */
+	unsigned long	suppress_int_prio_udt_to_self        :  1;  /* RW */
+	unsigned long	use_legacy_descriptor_formats        :  1;  /* RW */
+	unsigned long	rsvd_36_47                           : 12;  /*    */
+	unsigned long	fun                                  : 16;  /* RW */
+    } s2;
 };
 
 /* ========================================================================= */
 /*                     UVH_LB_BAU_SB_ACTIVATION_CONTROL                      */
 /* ========================================================================= */
 #define UVH_LB_BAU_SB_ACTIVATION_CONTROL 0x320020UL
-#define UVH_LB_BAU_SB_ACTIVATION_CONTROL_32 0x009a8
+#define UVH_LB_BAU_SB_ACTIVATION_CONTROL_32 0x9a8
 
 #define UVH_LB_BAU_SB_ACTIVATION_CONTROL_INDEX_SHFT 0
 #define UVH_LB_BAU_SB_ACTIVATION_CONTROL_INDEX_MASK 0x000000000000003fUL
@@ -703,7 +1075,7 @@
 /*                    UVH_LB_BAU_SB_ACTIVATION_STATUS_0                      */
 /* ========================================================================= */
 #define UVH_LB_BAU_SB_ACTIVATION_STATUS_0 0x320030UL
-#define UVH_LB_BAU_SB_ACTIVATION_STATUS_0_32 0x009b0
+#define UVH_LB_BAU_SB_ACTIVATION_STATUS_0_32 0x9b0
 
 #define UVH_LB_BAU_SB_ACTIVATION_STATUS_0_STATUS_SHFT 0
 #define UVH_LB_BAU_SB_ACTIVATION_STATUS_0_STATUS_MASK 0xffffffffffffffffUL
@@ -719,7 +1091,7 @@
 /*                    UVH_LB_BAU_SB_ACTIVATION_STATUS_1                      */
 /* ========================================================================= */
 #define UVH_LB_BAU_SB_ACTIVATION_STATUS_1 0x320040UL
-#define UVH_LB_BAU_SB_ACTIVATION_STATUS_1_32 0x009b8
+#define UVH_LB_BAU_SB_ACTIVATION_STATUS_1_32 0x9b8
 
 #define UVH_LB_BAU_SB_ACTIVATION_STATUS_1_STATUS_SHFT 0
 #define UVH_LB_BAU_SB_ACTIVATION_STATUS_1_STATUS_MASK 0xffffffffffffffffUL
@@ -735,7 +1107,7 @@
 /*                      UVH_LB_BAU_SB_DESCRIPTOR_BASE                        */
 /* ========================================================================= */
 #define UVH_LB_BAU_SB_DESCRIPTOR_BASE 0x320010UL
-#define UVH_LB_BAU_SB_DESCRIPTOR_BASE_32 0x009a0
+#define UVH_LB_BAU_SB_DESCRIPTOR_BASE_32 0x9a0
 
 #define UVH_LB_BAU_SB_DESCRIPTOR_BASE_PAGE_ADDRESS_SHFT 12
 #define UVH_LB_BAU_SB_DESCRIPTOR_BASE_PAGE_ADDRESS_MASK 0x000007fffffff000UL
@@ -754,23 +1126,6 @@
 };
 
 /* ========================================================================= */
-/*                   UVH_LB_TARGET_PHYSICAL_APIC_ID_MASK                     */
-/* ========================================================================= */
-#define UVH_LB_TARGET_PHYSICAL_APIC_ID_MASK 0x320130UL
-#define UVH_LB_TARGET_PHYSICAL_APIC_ID_MASK_32 0x009f0
-
-#define UVH_LB_TARGET_PHYSICAL_APIC_ID_MASK_BIT_ENABLES_SHFT 0
-#define UVH_LB_TARGET_PHYSICAL_APIC_ID_MASK_BIT_ENABLES_MASK 0x00000000ffffffffUL
-
-union uvh_lb_target_physical_apic_id_mask_u {
-	unsigned long v;
-	struct uvh_lb_target_physical_apic_id_mask_s {
-		unsigned long bit_enables : 32;  /* RW */
-		unsigned long rsvd_32_63  : 32;  /*    */
-	} s;
-};
-
-/* ========================================================================= */
 /*                               UVH_NODE_ID                                 */
 /* ========================================================================= */
 #define UVH_NODE_ID 0x0UL
@@ -785,10 +1140,36 @@
 #define UVH_NODE_ID_REVISION_MASK 0x00000000f0000000UL
 #define UVH_NODE_ID_NODE_ID_SHFT 32
 #define UVH_NODE_ID_NODE_ID_MASK 0x00007fff00000000UL
-#define UVH_NODE_ID_NODES_PER_BIT_SHFT 48
-#define UVH_NODE_ID_NODES_PER_BIT_MASK 0x007f000000000000UL
-#define UVH_NODE_ID_NI_PORT_SHFT 56
-#define UVH_NODE_ID_NI_PORT_MASK 0x0f00000000000000UL
+
+#define UV1H_NODE_ID_FORCE1_SHFT 0
+#define UV1H_NODE_ID_FORCE1_MASK 0x0000000000000001UL
+#define UV1H_NODE_ID_MANUFACTURER_SHFT 1
+#define UV1H_NODE_ID_MANUFACTURER_MASK 0x0000000000000ffeUL
+#define UV1H_NODE_ID_PART_NUMBER_SHFT 12
+#define UV1H_NODE_ID_PART_NUMBER_MASK 0x000000000ffff000UL
+#define UV1H_NODE_ID_REVISION_SHFT 28
+#define UV1H_NODE_ID_REVISION_MASK 0x00000000f0000000UL
+#define UV1H_NODE_ID_NODE_ID_SHFT 32
+#define UV1H_NODE_ID_NODE_ID_MASK 0x00007fff00000000UL
+#define UV1H_NODE_ID_NODES_PER_BIT_SHFT 48
+#define UV1H_NODE_ID_NODES_PER_BIT_MASK 0x007f000000000000UL
+#define UV1H_NODE_ID_NI_PORT_SHFT 56
+#define UV1H_NODE_ID_NI_PORT_MASK 0x0f00000000000000UL
+
+#define UV2H_NODE_ID_FORCE1_SHFT 0
+#define UV2H_NODE_ID_FORCE1_MASK 0x0000000000000001UL
+#define UV2H_NODE_ID_MANUFACTURER_SHFT 1
+#define UV2H_NODE_ID_MANUFACTURER_MASK 0x0000000000000ffeUL
+#define UV2H_NODE_ID_PART_NUMBER_SHFT 12
+#define UV2H_NODE_ID_PART_NUMBER_MASK 0x000000000ffff000UL
+#define UV2H_NODE_ID_REVISION_SHFT 28
+#define UV2H_NODE_ID_REVISION_MASK 0x00000000f0000000UL
+#define UV2H_NODE_ID_NODE_ID_SHFT 32
+#define UV2H_NODE_ID_NODE_ID_MASK 0x00007fff00000000UL
+#define UV2H_NODE_ID_NODES_PER_BIT_SHFT 50
+#define UV2H_NODE_ID_NODES_PER_BIT_MASK 0x01fc000000000000UL
+#define UV2H_NODE_ID_NI_PORT_SHFT 57
+#define UV2H_NODE_ID_NI_PORT_MASK 0x3e00000000000000UL
 
 union uvh_node_id_u {
     unsigned long	v;
@@ -798,12 +1179,31 @@
 	unsigned long	part_number   : 16;  /* RO */
 	unsigned long	revision      :  4;  /* RO */
 	unsigned long	node_id       : 15;  /* RW */
+	unsigned long	rsvd_47_63    : 17;
+    } s;
+    struct uv1h_node_id_s {
+	unsigned long	force1        :  1;  /* RO */
+	unsigned long	manufacturer  : 11;  /* RO */
+	unsigned long	part_number   : 16;  /* RO */
+	unsigned long	revision      :  4;  /* RO */
+	unsigned long	node_id       : 15;  /* RW */
 	unsigned long	rsvd_47       :  1;  /*    */
 	unsigned long	nodes_per_bit :  7;  /* RW */
 	unsigned long	rsvd_55       :  1;  /*    */
 	unsigned long	ni_port       :  4;  /* RO */
 	unsigned long	rsvd_60_63    :  4;  /*    */
-    } s;
+    } s1;
+    struct uv2h_node_id_s {
+	unsigned long	force1        :  1;  /* RO */
+	unsigned long	manufacturer  : 11;  /* RO */
+	unsigned long	part_number   : 16;  /* RO */
+	unsigned long	revision      :  4;  /* RO */
+	unsigned long	node_id       : 15;  /* RW */
+	unsigned long	rsvd_47_49    :  3;  /*    */
+	unsigned long	nodes_per_bit :  7;  /* RO */
+	unsigned long	ni_port       :  5;  /* RO */
+	unsigned long	rsvd_62_63    :  2;  /*    */
+    } s2;
 };
 
 /* ========================================================================= */
@@ -954,18 +1354,38 @@
 #define UVH_RH_GAM_CONFIG_MMR_M_SKT_MASK 0x000000000000003fUL
 #define UVH_RH_GAM_CONFIG_MMR_N_SKT_SHFT 6
 #define UVH_RH_GAM_CONFIG_MMR_N_SKT_MASK 0x00000000000003c0UL
-#define UVH_RH_GAM_CONFIG_MMR_MMIOL_CFG_SHFT 12
-#define UVH_RH_GAM_CONFIG_MMR_MMIOL_CFG_MASK 0x0000000000001000UL
+
+#define UV1H_RH_GAM_CONFIG_MMR_M_SKT_SHFT 0
+#define UV1H_RH_GAM_CONFIG_MMR_M_SKT_MASK 0x000000000000003fUL
+#define UV1H_RH_GAM_CONFIG_MMR_N_SKT_SHFT 6
+#define UV1H_RH_GAM_CONFIG_MMR_N_SKT_MASK 0x00000000000003c0UL
+#define UV1H_RH_GAM_CONFIG_MMR_MMIOL_CFG_SHFT 12
+#define UV1H_RH_GAM_CONFIG_MMR_MMIOL_CFG_MASK 0x0000000000001000UL
+
+#define UV2H_RH_GAM_CONFIG_MMR_M_SKT_SHFT 0
+#define UV2H_RH_GAM_CONFIG_MMR_M_SKT_MASK 0x000000000000003fUL
+#define UV2H_RH_GAM_CONFIG_MMR_N_SKT_SHFT 6
+#define UV2H_RH_GAM_CONFIG_MMR_N_SKT_MASK 0x00000000000003c0UL
 
 union uvh_rh_gam_config_mmr_u {
     unsigned long	v;
     struct uvh_rh_gam_config_mmr_s {
 	unsigned long	m_skt     :  6;  /* RW */
 	unsigned long	n_skt     :  4;  /* RW */
+	unsigned long	rsvd_10_63    : 54;
+    } s;
+    struct uv1h_rh_gam_config_mmr_s {
+	unsigned long	m_skt     :  6;  /* RW */
+	unsigned long	n_skt     :  4;  /* RW */
 	unsigned long	rsvd_10_11:  2;  /*    */
 	unsigned long	mmiol_cfg :  1;  /* RW */
 	unsigned long	rsvd_13_63: 51;  /*    */
-    } s;
+    } s1;
+    struct uv2h_rh_gam_config_mmr_s {
+	unsigned long	m_skt :  6;  /* RW */
+	unsigned long	n_skt :  4;  /* RW */
+	unsigned long	rsvd_10_63: 54;  /*    */
+    } s2;
 };
 
 /* ========================================================================= */
@@ -975,25 +1395,49 @@
 
 #define UVH_RH_GAM_GRU_OVERLAY_CONFIG_MMR_BASE_SHFT 28
 #define UVH_RH_GAM_GRU_OVERLAY_CONFIG_MMR_BASE_MASK 0x00003ffff0000000UL
-#define UVH_RH_GAM_GRU_OVERLAY_CONFIG_MMR_GR4_SHFT 48
-#define UVH_RH_GAM_GRU_OVERLAY_CONFIG_MMR_GR4_MASK 0x0001000000000000UL
-#define UVH_RH_GAM_GRU_OVERLAY_CONFIG_MMR_N_GRU_SHFT 52
-#define UVH_RH_GAM_GRU_OVERLAY_CONFIG_MMR_N_GRU_MASK 0x00f0000000000000UL
-#define UVH_RH_GAM_GRU_OVERLAY_CONFIG_MMR_ENABLE_SHFT 63
-#define UVH_RH_GAM_GRU_OVERLAY_CONFIG_MMR_ENABLE_MASK 0x8000000000000000UL
+
+#define UV1H_RH_GAM_GRU_OVERLAY_CONFIG_MMR_BASE_SHFT 28
+#define UV1H_RH_GAM_GRU_OVERLAY_CONFIG_MMR_BASE_MASK 0x00003ffff0000000UL
+#define UV1H_RH_GAM_GRU_OVERLAY_CONFIG_MMR_GR4_SHFT 48
+#define UV1H_RH_GAM_GRU_OVERLAY_CONFIG_MMR_GR4_MASK 0x0001000000000000UL
+#define UV1H_RH_GAM_GRU_OVERLAY_CONFIG_MMR_N_GRU_SHFT 52
+#define UV1H_RH_GAM_GRU_OVERLAY_CONFIG_MMR_N_GRU_MASK 0x00f0000000000000UL
+#define UV1H_RH_GAM_GRU_OVERLAY_CONFIG_MMR_ENABLE_SHFT 63
+#define UV1H_RH_GAM_GRU_OVERLAY_CONFIG_MMR_ENABLE_MASK 0x8000000000000000UL
+
+#define UV2H_RH_GAM_GRU_OVERLAY_CONFIG_MMR_BASE_SHFT 28
+#define UV2H_RH_GAM_GRU_OVERLAY_CONFIG_MMR_BASE_MASK 0x00003ffff0000000UL
+#define UV2H_RH_GAM_GRU_OVERLAY_CONFIG_MMR_N_GRU_SHFT 52
+#define UV2H_RH_GAM_GRU_OVERLAY_CONFIG_MMR_N_GRU_MASK 0x00f0000000000000UL
+#define UV2H_RH_GAM_GRU_OVERLAY_CONFIG_MMR_ENABLE_SHFT 63
+#define UV2H_RH_GAM_GRU_OVERLAY_CONFIG_MMR_ENABLE_MASK 0x8000000000000000UL
 
 union uvh_rh_gam_gru_overlay_config_mmr_u {
     unsigned long	v;
     struct uvh_rh_gam_gru_overlay_config_mmr_s {
 	unsigned long	rsvd_0_27: 28;  /*    */
 	unsigned long	base   : 18;  /* RW */
+	unsigned long	rsvd_46_62    : 17;
+	unsigned long	enable :  1;  /* RW */
+    } s;
+    struct uv1h_rh_gam_gru_overlay_config_mmr_s {
+	unsigned long	rsvd_0_27: 28;  /*    */
+	unsigned long	base   : 18;  /* RW */
 	unsigned long	rsvd_46_47:  2;  /*    */
 	unsigned long	gr4    :  1;  /* RW */
 	unsigned long	rsvd_49_51:  3;  /*    */
 	unsigned long	n_gru  :  4;  /* RW */
 	unsigned long	rsvd_56_62:  7;  /*    */
 	unsigned long	enable :  1;  /* RW */
-    } s;
+    } s1;
+    struct uv2h_rh_gam_gru_overlay_config_mmr_s {
+	unsigned long	rsvd_0_27: 28;  /*    */
+	unsigned long	base   : 18;  /* RW */
+	unsigned long	rsvd_46_51:  6;  /*    */
+	unsigned long	n_gru  :  4;  /* RW */
+	unsigned long	rsvd_56_62:  7;  /*    */
+	unsigned long	enable :  1;  /* RW */
+    } s2;
 };
 
 /* ========================================================================= */
@@ -1001,25 +1445,42 @@
 /* ========================================================================= */
 #define UVH_RH_GAM_MMIOH_OVERLAY_CONFIG_MMR 0x1600030UL
 
-#define UVH_RH_GAM_MMIOH_OVERLAY_CONFIG_MMR_BASE_SHFT 30
-#define UVH_RH_GAM_MMIOH_OVERLAY_CONFIG_MMR_BASE_MASK 0x00003fffc0000000UL
-#define UVH_RH_GAM_MMIOH_OVERLAY_CONFIG_MMR_M_IO_SHFT 46
-#define UVH_RH_GAM_MMIOH_OVERLAY_CONFIG_MMR_M_IO_MASK 0x000fc00000000000UL
-#define UVH_RH_GAM_MMIOH_OVERLAY_CONFIG_MMR_N_IO_SHFT 52
-#define UVH_RH_GAM_MMIOH_OVERLAY_CONFIG_MMR_N_IO_MASK 0x00f0000000000000UL
-#define UVH_RH_GAM_MMIOH_OVERLAY_CONFIG_MMR_ENABLE_SHFT 63
-#define UVH_RH_GAM_MMIOH_OVERLAY_CONFIG_MMR_ENABLE_MASK 0x8000000000000000UL
+#define UV1H_RH_GAM_MMIOH_OVERLAY_CONFIG_MMR_BASE_SHFT 30
+#define UV1H_RH_GAM_MMIOH_OVERLAY_CONFIG_MMR_BASE_MASK 0x00003fffc0000000UL
+#define UV1H_RH_GAM_MMIOH_OVERLAY_CONFIG_MMR_M_IO_SHFT 46
+#define UV1H_RH_GAM_MMIOH_OVERLAY_CONFIG_MMR_M_IO_MASK 0x000fc00000000000UL
+#define UV1H_RH_GAM_MMIOH_OVERLAY_CONFIG_MMR_N_IO_SHFT 52
+#define UV1H_RH_GAM_MMIOH_OVERLAY_CONFIG_MMR_N_IO_MASK 0x00f0000000000000UL
+#define UV1H_RH_GAM_MMIOH_OVERLAY_CONFIG_MMR_ENABLE_SHFT 63
+#define UV1H_RH_GAM_MMIOH_OVERLAY_CONFIG_MMR_ENABLE_MASK 0x8000000000000000UL
+
+#define UV2H_RH_GAM_MMIOH_OVERLAY_CONFIG_MMR_BASE_SHFT 27
+#define UV2H_RH_GAM_MMIOH_OVERLAY_CONFIG_MMR_BASE_MASK 0x00003ffff8000000UL
+#define UV2H_RH_GAM_MMIOH_OVERLAY_CONFIG_MMR_M_IO_SHFT 46
+#define UV2H_RH_GAM_MMIOH_OVERLAY_CONFIG_MMR_M_IO_MASK 0x000fc00000000000UL
+#define UV2H_RH_GAM_MMIOH_OVERLAY_CONFIG_MMR_N_IO_SHFT 52
+#define UV2H_RH_GAM_MMIOH_OVERLAY_CONFIG_MMR_N_IO_MASK 0x00f0000000000000UL
+#define UV2H_RH_GAM_MMIOH_OVERLAY_CONFIG_MMR_ENABLE_SHFT 63
+#define UV2H_RH_GAM_MMIOH_OVERLAY_CONFIG_MMR_ENABLE_MASK 0x8000000000000000UL
 
 union uvh_rh_gam_mmioh_overlay_config_mmr_u {
     unsigned long	v;
-    struct uvh_rh_gam_mmioh_overlay_config_mmr_s {
+    struct uv1h_rh_gam_mmioh_overlay_config_mmr_s {
 	unsigned long	rsvd_0_29: 30;  /*    */
 	unsigned long	base   : 16;  /* RW */
 	unsigned long	m_io   :  6;  /* RW */
 	unsigned long	n_io   :  4;  /* RW */
 	unsigned long	rsvd_56_62:  7;  /*    */
 	unsigned long	enable :  1;  /* RW */
-    } s;
+    } s1;
+    struct uv2h_rh_gam_mmioh_overlay_config_mmr_s {
+	unsigned long	rsvd_0_26: 27;  /*    */
+	unsigned long	base   : 19;  /* RW */
+	unsigned long	m_io   :  6;  /* RW */
+	unsigned long	n_io   :  4;  /* RW */
+	unsigned long	rsvd_56_62:  7;  /*    */
+	unsigned long	enable :  1;  /* RW */
+    } s2;
 };
 
 /* ========================================================================= */
@@ -1029,20 +1490,40 @@
 
 #define UVH_RH_GAM_MMR_OVERLAY_CONFIG_MMR_BASE_SHFT 26
 #define UVH_RH_GAM_MMR_OVERLAY_CONFIG_MMR_BASE_MASK 0x00003ffffc000000UL
-#define UVH_RH_GAM_MMR_OVERLAY_CONFIG_MMR_DUAL_HUB_SHFT 46
-#define UVH_RH_GAM_MMR_OVERLAY_CONFIG_MMR_DUAL_HUB_MASK 0x0000400000000000UL
-#define UVH_RH_GAM_MMR_OVERLAY_CONFIG_MMR_ENABLE_SHFT 63
-#define UVH_RH_GAM_MMR_OVERLAY_CONFIG_MMR_ENABLE_MASK 0x8000000000000000UL
+
+#define UV1H_RH_GAM_MMR_OVERLAY_CONFIG_MMR_BASE_SHFT 26
+#define UV1H_RH_GAM_MMR_OVERLAY_CONFIG_MMR_BASE_MASK 0x00003ffffc000000UL
+#define UV1H_RH_GAM_MMR_OVERLAY_CONFIG_MMR_DUAL_HUB_SHFT 46
+#define UV1H_RH_GAM_MMR_OVERLAY_CONFIG_MMR_DUAL_HUB_MASK 0x0000400000000000UL
+#define UV1H_RH_GAM_MMR_OVERLAY_CONFIG_MMR_ENABLE_SHFT 63
+#define UV1H_RH_GAM_MMR_OVERLAY_CONFIG_MMR_ENABLE_MASK 0x8000000000000000UL
+
+#define UV2H_RH_GAM_MMR_OVERLAY_CONFIG_MMR_BASE_SHFT 26
+#define UV2H_RH_GAM_MMR_OVERLAY_CONFIG_MMR_BASE_MASK 0x00003ffffc000000UL
+#define UV2H_RH_GAM_MMR_OVERLAY_CONFIG_MMR_ENABLE_SHFT 63
+#define UV2H_RH_GAM_MMR_OVERLAY_CONFIG_MMR_ENABLE_MASK 0x8000000000000000UL
 
 union uvh_rh_gam_mmr_overlay_config_mmr_u {
     unsigned long	v;
     struct uvh_rh_gam_mmr_overlay_config_mmr_s {
 	unsigned long	rsvd_0_25: 26;  /*    */
 	unsigned long	base     : 20;  /* RW */
+	unsigned long	rsvd_46_62    : 17;
+	unsigned long	enable   :  1;  /* RW */
+    } s;
+    struct uv1h_rh_gam_mmr_overlay_config_mmr_s {
+	unsigned long	rsvd_0_25: 26;  /*    */
+	unsigned long	base     : 20;  /* RW */
 	unsigned long	dual_hub :  1;  /* RW */
 	unsigned long	rsvd_47_62: 16;  /*    */
 	unsigned long	enable   :  1;  /* RW */
-    } s;
+    } s1;
+    struct uv2h_rh_gam_mmr_overlay_config_mmr_s {
+	unsigned long	rsvd_0_25: 26;  /*    */
+	unsigned long	base   : 20;  /* RW */
+	unsigned long	rsvd_46_62: 17;  /*    */
+	unsigned long	enable :  1;  /* RW */
+    } s2;
 };
 
 /* ========================================================================= */
@@ -1103,10 +1584,11 @@
 /*                               UVH_SCRATCH5                                */
 /* ========================================================================= */
 #define UVH_SCRATCH5 0x2d0200UL
-#define UVH_SCRATCH5_32 0x00778
+#define UVH_SCRATCH5_32 0x778
 
 #define UVH_SCRATCH5_SCRATCH5_SHFT 0
 #define UVH_SCRATCH5_SCRATCH5_MASK 0xffffffffffffffffUL
+
 union uvh_scratch5_u {
     unsigned long	v;
     struct uvh_scratch5_s {
@@ -1114,4 +1596,154 @@
     } s;
 };
 
+/* ========================================================================= */
+/*                           UV2H_EVENT_OCCURRED2                            */
+/* ========================================================================= */
+#define UV2H_EVENT_OCCURRED2 0x70100UL
+#define UV2H_EVENT_OCCURRED2_32 0xb68
+
+#define UV2H_EVENT_OCCURRED2_RTC_0_SHFT 0
+#define UV2H_EVENT_OCCURRED2_RTC_0_MASK 0x0000000000000001UL
+#define UV2H_EVENT_OCCURRED2_RTC_1_SHFT 1
+#define UV2H_EVENT_OCCURRED2_RTC_1_MASK 0x0000000000000002UL
+#define UV2H_EVENT_OCCURRED2_RTC_2_SHFT 2
+#define UV2H_EVENT_OCCURRED2_RTC_2_MASK 0x0000000000000004UL
+#define UV2H_EVENT_OCCURRED2_RTC_3_SHFT 3
+#define UV2H_EVENT_OCCURRED2_RTC_3_MASK 0x0000000000000008UL
+#define UV2H_EVENT_OCCURRED2_RTC_4_SHFT 4
+#define UV2H_EVENT_OCCURRED2_RTC_4_MASK 0x0000000000000010UL
+#define UV2H_EVENT_OCCURRED2_RTC_5_SHFT 5
+#define UV2H_EVENT_OCCURRED2_RTC_5_MASK 0x0000000000000020UL
+#define UV2H_EVENT_OCCURRED2_RTC_6_SHFT 6
+#define UV2H_EVENT_OCCURRED2_RTC_6_MASK 0x0000000000000040UL
+#define UV2H_EVENT_OCCURRED2_RTC_7_SHFT 7
+#define UV2H_EVENT_OCCURRED2_RTC_7_MASK 0x0000000000000080UL
+#define UV2H_EVENT_OCCURRED2_RTC_8_SHFT 8
+#define UV2H_EVENT_OCCURRED2_RTC_8_MASK 0x0000000000000100UL
+#define UV2H_EVENT_OCCURRED2_RTC_9_SHFT 9
+#define UV2H_EVENT_OCCURRED2_RTC_9_MASK 0x0000000000000200UL
+#define UV2H_EVENT_OCCURRED2_RTC_10_SHFT 10
+#define UV2H_EVENT_OCCURRED2_RTC_10_MASK 0x0000000000000400UL
+#define UV2H_EVENT_OCCURRED2_RTC_11_SHFT 11
+#define UV2H_EVENT_OCCURRED2_RTC_11_MASK 0x0000000000000800UL
+#define UV2H_EVENT_OCCURRED2_RTC_12_SHFT 12
+#define UV2H_EVENT_OCCURRED2_RTC_12_MASK 0x0000000000001000UL
+#define UV2H_EVENT_OCCURRED2_RTC_13_SHFT 13
+#define UV2H_EVENT_OCCURRED2_RTC_13_MASK 0x0000000000002000UL
+#define UV2H_EVENT_OCCURRED2_RTC_14_SHFT 14
+#define UV2H_EVENT_OCCURRED2_RTC_14_MASK 0x0000000000004000UL
+#define UV2H_EVENT_OCCURRED2_RTC_15_SHFT 15
+#define UV2H_EVENT_OCCURRED2_RTC_15_MASK 0x0000000000008000UL
+#define UV2H_EVENT_OCCURRED2_RTC_16_SHFT 16
+#define UV2H_EVENT_OCCURRED2_RTC_16_MASK 0x0000000000010000UL
+#define UV2H_EVENT_OCCURRED2_RTC_17_SHFT 17
+#define UV2H_EVENT_OCCURRED2_RTC_17_MASK 0x0000000000020000UL
+#define UV2H_EVENT_OCCURRED2_RTC_18_SHFT 18
+#define UV2H_EVENT_OCCURRED2_RTC_18_MASK 0x0000000000040000UL
+#define UV2H_EVENT_OCCURRED2_RTC_19_SHFT 19
+#define UV2H_EVENT_OCCURRED2_RTC_19_MASK 0x0000000000080000UL
+#define UV2H_EVENT_OCCURRED2_RTC_20_SHFT 20
+#define UV2H_EVENT_OCCURRED2_RTC_20_MASK 0x0000000000100000UL
+#define UV2H_EVENT_OCCURRED2_RTC_21_SHFT 21
+#define UV2H_EVENT_OCCURRED2_RTC_21_MASK 0x0000000000200000UL
+#define UV2H_EVENT_OCCURRED2_RTC_22_SHFT 22
+#define UV2H_EVENT_OCCURRED2_RTC_22_MASK 0x0000000000400000UL
+#define UV2H_EVENT_OCCURRED2_RTC_23_SHFT 23
+#define UV2H_EVENT_OCCURRED2_RTC_23_MASK 0x0000000000800000UL
+#define UV2H_EVENT_OCCURRED2_RTC_24_SHFT 24
+#define UV2H_EVENT_OCCURRED2_RTC_24_MASK 0x0000000001000000UL
+#define UV2H_EVENT_OCCURRED2_RTC_25_SHFT 25
+#define UV2H_EVENT_OCCURRED2_RTC_25_MASK 0x0000000002000000UL
+#define UV2H_EVENT_OCCURRED2_RTC_26_SHFT 26
+#define UV2H_EVENT_OCCURRED2_RTC_26_MASK 0x0000000004000000UL
+#define UV2H_EVENT_OCCURRED2_RTC_27_SHFT 27
+#define UV2H_EVENT_OCCURRED2_RTC_27_MASK 0x0000000008000000UL
+#define UV2H_EVENT_OCCURRED2_RTC_28_SHFT 28
+#define UV2H_EVENT_OCCURRED2_RTC_28_MASK 0x0000000010000000UL
+#define UV2H_EVENT_OCCURRED2_RTC_29_SHFT 29
+#define UV2H_EVENT_OCCURRED2_RTC_29_MASK 0x0000000020000000UL
+#define UV2H_EVENT_OCCURRED2_RTC_30_SHFT 30
+#define UV2H_EVENT_OCCURRED2_RTC_30_MASK 0x0000000040000000UL
+#define UV2H_EVENT_OCCURRED2_RTC_31_SHFT 31
+#define UV2H_EVENT_OCCURRED2_RTC_31_MASK 0x0000000080000000UL
+
+union uv2h_event_occurred2_u {
+    unsigned long	v;
+    struct uv2h_event_occurred2_s {
+	unsigned long	rtc_0  :  1;  /* RW */
+	unsigned long	rtc_1  :  1;  /* RW */
+	unsigned long	rtc_2  :  1;  /* RW */
+	unsigned long	rtc_3  :  1;  /* RW */
+	unsigned long	rtc_4  :  1;  /* RW */
+	unsigned long	rtc_5  :  1;  /* RW */
+	unsigned long	rtc_6  :  1;  /* RW */
+	unsigned long	rtc_7  :  1;  /* RW */
+	unsigned long	rtc_8  :  1;  /* RW */
+	unsigned long	rtc_9  :  1;  /* RW */
+	unsigned long	rtc_10 :  1;  /* RW */
+	unsigned long	rtc_11 :  1;  /* RW */
+	unsigned long	rtc_12 :  1;  /* RW */
+	unsigned long	rtc_13 :  1;  /* RW */
+	unsigned long	rtc_14 :  1;  /* RW */
+	unsigned long	rtc_15 :  1;  /* RW */
+	unsigned long	rtc_16 :  1;  /* RW */
+	unsigned long	rtc_17 :  1;  /* RW */
+	unsigned long	rtc_18 :  1;  /* RW */
+	unsigned long	rtc_19 :  1;  /* RW */
+	unsigned long	rtc_20 :  1;  /* RW */
+	unsigned long	rtc_21 :  1;  /* RW */
+	unsigned long	rtc_22 :  1;  /* RW */
+	unsigned long	rtc_23 :  1;  /* RW */
+	unsigned long	rtc_24 :  1;  /* RW */
+	unsigned long	rtc_25 :  1;  /* RW */
+	unsigned long	rtc_26 :  1;  /* RW */
+	unsigned long	rtc_27 :  1;  /* RW */
+	unsigned long	rtc_28 :  1;  /* RW */
+	unsigned long	rtc_29 :  1;  /* RW */
+	unsigned long	rtc_30 :  1;  /* RW */
+	unsigned long	rtc_31 :  1;  /* RW */
+	unsigned long	rsvd_32_63: 32;  /*    */
+    } s1;
+};
+
+/* ========================================================================= */
+/*                        UV2H_EVENT_OCCURRED2_ALIAS                         */
+/* ========================================================================= */
+#define UV2H_EVENT_OCCURRED2_ALIAS 0x70108UL
+#define UV2H_EVENT_OCCURRED2_ALIAS_32 0xb70
+
+/* ========================================================================= */
+/*                    UV2H_LB_BAU_SB_ACTIVATION_STATUS_2                     */
+/* ========================================================================= */
+#define UV2H_LB_BAU_SB_ACTIVATION_STATUS_2 0x320130UL
+#define UV2H_LB_BAU_SB_ACTIVATION_STATUS_2_32 0x9f0
+
+#define UV2H_LB_BAU_SB_ACTIVATION_STATUS_2_AUX_ERROR_SHFT 0
+#define UV2H_LB_BAU_SB_ACTIVATION_STATUS_2_AUX_ERROR_MASK 0xffffffffffffffffUL
+
+union uv2h_lb_bau_sb_activation_status_2_u {
+    unsigned long	v;
+    struct uv2h_lb_bau_sb_activation_status_2_s {
+	unsigned long	aux_error : 64;  /* RW */
+    } s1;
+};
+
+/* ========================================================================= */
+/*                   UV1H_LB_TARGET_PHYSICAL_APIC_ID_MASK                    */
+/* ========================================================================= */
+#define UV1H_LB_TARGET_PHYSICAL_APIC_ID_MASK 0x320130UL
+#define UV1H_LB_TARGET_PHYSICAL_APIC_ID_MASK_32 0x9f0
+
+#define UV1H_LB_TARGET_PHYSICAL_APIC_ID_MASK_BIT_ENABLES_SHFT 0
+#define UV1H_LB_TARGET_PHYSICAL_APIC_ID_MASK_BIT_ENABLES_MASK 0x00000000ffffffffUL
+
+union uv1h_lb_target_physical_apic_id_mask_u {
+    unsigned long	v;
+    struct uv1h_lb_target_physical_apic_id_mask_s {
+	unsigned long	bit_enables : 32;  /* RW */
+	unsigned long	rsvd_32_63  : 32;  /*    */
+    } s1;
+};
+
+
 #endif /* __ASM_UV_MMRS_X86_H__ */
diff -druN linux-2.6.39-libre/arch/x86/include/asm/vdso.h linux-3.0-rc7-libre/arch/x86/include/asm/vdso.h
--- linux-2.6.39-libre/arch/x86/include/asm/vdso.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/include/asm/vdso.h	2011-07-11 19:51:52.000000000 -0400
@@ -1,20 +1,6 @@
 #ifndef _ASM_X86_VDSO_H
 #define _ASM_X86_VDSO_H
 
-#ifdef CONFIG_X86_64
-extern const char VDSO64_PRELINK[];
-
-/*
- * Given a pointer to the vDSO image, find the pointer to VDSO64_name
- * as that symbol is defined in the vDSO sources or linker script.
- */
-#define VDSO64_SYMBOL(base, name)					\
-({									\
-	extern const char VDSO64_##name[];				\
-	(void *)(VDSO64_##name - VDSO64_PRELINK + (unsigned long)(base)); \
-})
-#endif
-
 #if defined CONFIG_X86_32 || defined CONFIG_COMPAT
 extern const char VDSO32_PRELINK[];
 
diff -druN linux-2.6.39-libre/arch/x86/include/asm/vgtod.h linux-3.0-rc7-libre/arch/x86/include/asm/vgtod.h
--- linux-2.6.39-libre/arch/x86/include/asm/vgtod.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/include/asm/vgtod.h	2011-07-11 19:51:52.000000000 -0400
@@ -23,8 +23,6 @@
 	struct timespec wall_to_monotonic;
 	struct timespec wall_time_coarse;
 };
-extern struct vsyscall_gtod_data __vsyscall_gtod_data
-__section_vsyscall_gtod_data;
 extern struct vsyscall_gtod_data vsyscall_gtod_data;
 
 #endif /* _ASM_X86_VGTOD_H */
diff -druN linux-2.6.39-libre/arch/x86/include/asm/vsyscall.h linux-3.0-rc7-libre/arch/x86/include/asm/vsyscall.h
--- linux-2.6.39-libre/arch/x86/include/asm/vsyscall.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/include/asm/vsyscall.h	2011-07-11 19:51:52.000000000 -0400
@@ -16,27 +16,19 @@
 #ifdef __KERNEL__
 #include <linux/seqlock.h>
 
-#define __section_vgetcpu_mode __attribute__ ((unused, __section__ (".vgetcpu_mode"), aligned(16)))
-#define __section_jiffies __attribute__ ((unused, __section__ (".jiffies"), aligned(16)))
-
 /* Definitions for CONFIG_GENERIC_TIME definitions */
-#define __section_vsyscall_gtod_data __attribute__ \
-	((unused, __section__ (".vsyscall_gtod_data"),aligned(16)))
-#define __section_vsyscall_clock __attribute__ \
-	((unused, __section__ (".vsyscall_clock"),aligned(16)))
 #define __vsyscall_fn \
 	__attribute__ ((unused, __section__(".vsyscall_fn"))) notrace
 
 #define VGETCPU_RDTSCP	1
 #define VGETCPU_LSL	2
 
-extern int __vgetcpu_mode;
-extern volatile unsigned long __jiffies;
-
 /* kernel space (writeable) */
 extern int vgetcpu_mode;
 extern struct timezone sys_tz;
 
+#include <asm/vvar.h>
+
 extern void map_vsyscall(void);
 
 #endif /* __KERNEL__ */
diff -druN linux-2.6.39-libre/arch/x86/include/asm/vvar.h linux-3.0-rc7-libre/arch/x86/include/asm/vvar.h
--- linux-2.6.39-libre/arch/x86/include/asm/vvar.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/x86/include/asm/vvar.h	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,52 @@
+/*
+ * vvar.h: Shared vDSO/kernel variable declarations
+ * Copyright (c) 2011 Andy Lutomirski
+ * Subject to the GNU General Public License, version 2
+ *
+ * A handful of variables are accessible (read-only) from userspace
+ * code in the vsyscall page and the vdso.  They are declared here.
+ * Some other file must define them with DEFINE_VVAR.
+ *
+ * In normal kernel code, they are used like any other variable.
+ * In user code, they are accessed through the VVAR macro.
+ *
+ * Each of these variables lives in the vsyscall page, and each
+ * one needs a unique offset within the little piece of the page
+ * reserved for vvars.  Specify that offset in DECLARE_VVAR.
+ * (There are 896 bytes available.  If you mess up, the linker will
+ * catch it.)
+ */
+
+/* Offset of vars within vsyscall page */
+#define VSYSCALL_VARS_OFFSET (3072 + 128)
+
+#if defined(__VVAR_KERNEL_LDS)
+
+/* The kernel linker script defines its own magic to put vvars in the
+ * right place.
+ */
+#define DECLARE_VVAR(offset, type, name) \
+	EMIT_VVAR(name, VSYSCALL_VARS_OFFSET + offset)
+
+#else
+
+#define DECLARE_VVAR(offset, type, name)				\
+	static type const * const vvaraddr_ ## name =			\
+		(void *)(VSYSCALL_START + VSYSCALL_VARS_OFFSET + (offset));
+
+#define DEFINE_VVAR(type, name)						\
+	type __vvar_ ## name						\
+	__attribute__((section(".vsyscall_var_" #name), aligned(16)))
+
+#define VVAR(name) (*vvaraddr_ ## name)
+
+#endif
+
+/* DECLARE_VVAR(offset, type, name) */
+
+DECLARE_VVAR(0, volatile unsigned long, jiffies)
+DECLARE_VVAR(8, int, vgetcpu_mode)
+DECLARE_VVAR(128, struct vsyscall_gtod_data, vsyscall_gtod_data)
+
+#undef DECLARE_VVAR
+#undef VSYSCALL_VARS_OFFSET
diff -druN linux-2.6.39-libre/arch/x86/include/asm/x2apic.h linux-3.0-rc7-libre/arch/x86/include/asm/x2apic.h
--- linux-2.6.39-libre/arch/x86/include/asm/x2apic.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/x86/include/asm/x2apic.h	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,62 @@
+/*
+ * Common bits for X2APIC cluster/physical modes.
+ */
+
+#ifndef _ASM_X86_X2APIC_H
+#define _ASM_X86_X2APIC_H
+
+#include <asm/apic.h>
+#include <asm/ipi.h>
+#include <linux/cpumask.h>
+
+/*
+ * Need to use more than cpu 0, because we need more vectors
+ * when MSI-X are used.
+ */
+static const struct cpumask *x2apic_target_cpus(void)
+{
+	return cpu_online_mask;
+}
+
+static int x2apic_apic_id_registered(void)
+{
+	return 1;
+}
+
+/*
+ * For now each logical cpu is in its own vector allocation domain.
+ */
+static void x2apic_vector_allocation_domain(int cpu, struct cpumask *retmask)
+{
+	cpumask_clear(retmask);
+	cpumask_set_cpu(cpu, retmask);
+}
+
+static void
+__x2apic_send_IPI_dest(unsigned int apicid, int vector, unsigned int dest)
+{
+	unsigned long cfg = __prepare_ICR(0, vector, dest);
+	native_x2apic_icr_write(cfg, apicid);
+}
+
+static unsigned int x2apic_get_apic_id(unsigned long id)
+{
+	return id;
+}
+
+static unsigned long x2apic_set_apic_id(unsigned int id)
+{
+	return id;
+}
+
+static int x2apic_phys_pkg_id(int initial_apicid, int index_msb)
+{
+	return initial_apicid >> index_msb;
+}
+
+static void x2apic_send_IPI_self(int vector)
+{
+	apic_write(APIC_SELF_IPI, vector);
+}
+
+#endif /* _ASM_X86_X2APIC_H */
diff -druN linux-2.6.39-libre/arch/x86/include/asm/xen/hypercall.h linux-3.0-rc7-libre/arch/x86/include/asm/xen/hypercall.h
--- linux-2.6.39-libre/arch/x86/include/asm/xen/hypercall.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/include/asm/xen/hypercall.h	2011-07-11 19:51:52.000000000 -0400
@@ -447,6 +447,13 @@
        return _hypercall2(unsigned long, hvm_op, op, arg);
 }
 
+static inline int
+HYPERVISOR_tmem_op(
+	struct tmem_op *op)
+{
+	return _hypercall1(int, tmem_op, op);
+}
+
 static inline void
 MULTI_fpu_taskswitch(struct multicall_entry *mcl, int set)
 {
diff -druN linux-2.6.39-libre/arch/x86/include/asm/xen/page.h linux-3.0-rc7-libre/arch/x86/include/asm/xen/page.h
--- linux-2.6.39-libre/arch/x86/include/asm/xen/page.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/include/asm/xen/page.h	2011-07-11 19:51:52.000000000 -0400
@@ -47,8 +47,9 @@
 extern unsigned long set_phys_range_identity(unsigned long pfn_s,
 					     unsigned long pfn_e);
 
-extern int m2p_add_override(unsigned long mfn, struct page *page);
-extern int m2p_remove_override(struct page *page);
+extern int m2p_add_override(unsigned long mfn, struct page *page,
+			    bool clear_pte);
+extern int m2p_remove_override(struct page *page, bool clear_pte);
 extern struct page *m2p_find_override(unsigned long mfn);
 extern unsigned long m2p_find_override_pfn(unsigned long mfn, unsigned long pfn);
 
diff -druN linux-2.6.39-libre/arch/x86/include/asm/xen/pci.h linux-3.0-rc7-libre/arch/x86/include/asm/xen/pci.h
--- linux-2.6.39-libre/arch/x86/include/asm/xen/pci.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/include/asm/xen/pci.h	2011-07-11 19:51:52.000000000 -0400
@@ -15,10 +15,26 @@
 #endif
 #if defined(CONFIG_XEN_DOM0)
 void __init xen_setup_pirqs(void);
+int xen_find_device_domain_owner(struct pci_dev *dev);
+int xen_register_device_domain_owner(struct pci_dev *dev, uint16_t domain);
+int xen_unregister_device_domain_owner(struct pci_dev *dev);
 #else
 static inline void __init xen_setup_pirqs(void)
 {
 }
+static inline int xen_find_device_domain_owner(struct pci_dev *dev)
+{
+	return -1;
+}
+static inline int xen_register_device_domain_owner(struct pci_dev *dev,
+						   uint16_t domain)
+{
+	return -1;
+}
+static inline int xen_unregister_device_domain_owner(struct pci_dev *dev)
+{
+	return -1;
+}
 #endif
 
 #if defined(CONFIG_PCI_MSI)
diff -druN linux-2.6.39-libre/arch/x86/Kbuild linux-3.0-rc7-libre/arch/x86/Kbuild
--- linux-2.6.39-libre/arch/x86/Kbuild	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/Kbuild	2011-07-11 19:51:52.000000000 -0400
@@ -15,3 +15,4 @@
 obj-$(CONFIG_IA32_EMULATION) += ia32/
 
 obj-y += platform/
+obj-y += net/
diff -druN linux-2.6.39-libre/arch/x86/Kconfig linux-3.0-rc7-libre/arch/x86/Kconfig
--- linux-2.6.39-libre/arch/x86/Kconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/Kconfig	2011-07-11 19:51:52.000000000 -0400
@@ -8,6 +8,7 @@
 
 config X86_32
 	def_bool !64BIT
+	select CLKSRC_I8253
 
 config X86_64
 	def_bool 64BIT
@@ -16,8 +17,6 @@
 config X86
 	def_bool y
 	select HAVE_AOUT if X86_32
-	select HAVE_READQ
-	select HAVE_WRITEQ
 	select HAVE_UNSTABLE_SCHED_CLOCK
 	select HAVE_IDE
 	select HAVE_OPROFILE
@@ -65,13 +64,12 @@
 	select HAVE_GENERIC_HARDIRQS
 	select HAVE_SPARSE_IRQ
 	select GENERIC_FIND_FIRST_BIT
-	select GENERIC_FIND_NEXT_BIT
 	select GENERIC_IRQ_PROBE
 	select GENERIC_PENDING_IRQ if SMP
 	select GENERIC_IRQ_SHOW
 	select IRQ_FORCED_THREADING
 	select USE_GENERIC_SMP_HELPERS if SMP
-	select ARCH_NO_SYSDEV_OPS
+	select HAVE_BPF_JIT if (X86_64 && NET)
 
 config INSTRUCTION_DECODER
 	def_bool (KPROBES || PERF_EVENTS)
@@ -112,7 +110,14 @@
 	def_bool y
 
 config ZONE_DMA
-	def_bool y
+	bool "DMA memory allocation support" if EXPERT
+	default y
+	help
+	  DMA memory allocation support allows devices with less than 32-bit
+	  addressing to allocate within the first 16MB of address space.
+	  Disable if no such devices will be used.
+
+	  If unsure, say Y.
 
 config SBUS
 	bool
@@ -365,17 +370,6 @@
 # Following is an alphabetically sorted list of 32 bit extended platforms
 # Please maintain the alphabetic order if and when there are additions
 
-config X86_ELAN
-	bool "AMD Elan"
-	depends on X86_32
-	depends on X86_EXTENDED_PLATFORM
-	---help---
-	  Select this for an AMD Elan processor.
-
-	  Do not use this option for K6/Athlon/Opteron processors!
-
-	  If unsure, choose "PC-compatible" instead.
-
 config X86_INTEL_CE
 	bool "CE4100 TV platform"
 	depends on PCI
@@ -690,6 +684,7 @@
 	bool "AMD IOMMU support"
 	select SWIOTLB
 	select PCI_MSI
+	select PCI_IOV
 	depends on X86_64 && PCI && ACPI
 	---help---
 	  With this option you can enable support for AMD IOMMU hardware in
@@ -919,6 +914,7 @@
 
 config I8K
 	tristate "Dell laptop support"
+	select HWMON
 	---help---
 	  This adds a driver to safely access the System Management Mode
 	  of the CPU on the Dell Inspiron 8000. The System Management Mode
@@ -1174,7 +1170,7 @@
 config AMD_NUMA
 	def_bool y
 	prompt "Old style AMD Opteron NUMA detection"
-	depends on X86_64 && NUMA && PCI
+	depends on NUMA && PCI
 	---help---
 	  Enable AMD NUMA node topology detection.  You should say Y here if
 	  you have a multi processor AMD system. This uses an old method to
@@ -1201,7 +1197,7 @@
 
 config NUMA_EMU
 	bool "NUMA emulation"
-	depends on X86_64 && NUMA
+	depends on NUMA
 	---help---
 	  Enable NUMA emulation. A flat machine will be split
 	  into virtual nodes when booted with "numa=fake=N", where N is the
@@ -1223,6 +1219,10 @@
 	def_bool y
 	depends on X86_32 && NUMA
 
+config HAVE_ARCH_ALLOC_REMAP
+	def_bool y
+	depends on X86_32 && NUMA
+
 config ARCH_HAVE_MEMORY_PRESENT
 	def_bool y
 	depends on X86_32 && DISCONTIGMEM
@@ -1231,13 +1231,9 @@
 	def_bool y
 	depends on X86_32 && (DISCONTIGMEM || SPARSEMEM)
 
-config HAVE_ARCH_ALLOC_REMAP
-	def_bool y
-	depends on X86_32 && NUMA
-
 config ARCH_FLATMEM_ENABLE
 	def_bool y
-	depends on X86_32 && ARCH_SELECT_MEMORY_MODEL && !NUMA
+	depends on X86_32 && !NUMA
 
 config ARCH_DISCONTIGMEM_ENABLE
 	def_bool y
@@ -1247,20 +1243,16 @@
 	def_bool y
 	depends on NUMA && X86_32
 
-config ARCH_PROC_KCORE_TEXT
-	def_bool y
-	depends on X86_64 && PROC_KCORE
-
-config ARCH_SPARSEMEM_DEFAULT
-	def_bool y
-	depends on X86_64
-
 config ARCH_SPARSEMEM_ENABLE
 	def_bool y
 	depends on X86_64 || NUMA || (EXPERIMENTAL && X86_32) || X86_32_NON_STANDARD
 	select SPARSEMEM_STATIC if X86_32
 	select SPARSEMEM_VMEMMAP_ENABLE if X86_64
 
+config ARCH_SPARSEMEM_DEFAULT
+	def_bool y
+	depends on X86_64
+
 config ARCH_SELECT_MEMORY_MODEL
 	def_bool y
 	depends on ARCH_SPARSEMEM_ENABLE
@@ -1269,6 +1261,10 @@
 	def_bool X86_64
 	depends on MEMORY_HOTPLUG
 
+config ARCH_PROC_KCORE_TEXT
+	def_bool y
+	depends on X86_64 && PROC_KCORE
+
 config ILLEGAL_POINTER_VALUE
        hex
        default 0 if X86_32
@@ -1703,10 +1699,6 @@
 	def_bool y
 	depends on MEMORY_HOTPLUG
 
-config HAVE_ARCH_EARLY_PFN_TO_NID
-	def_bool X86_64
-	depends on NUMA
-
 config USE_PERCPU_NUMA_NODE_ID
 	def_bool y
 	depends on NUMA
@@ -1848,7 +1840,7 @@
 
 endif # APM
 
-source "arch/x86/kernel/cpu/cpufreq/Kconfig"
+source "drivers/cpufreq/Kconfig"
 
 source "drivers/cpuidle/Kconfig"
 
@@ -2076,7 +2068,7 @@
 	depends on !X86_PAE
 	select GPIOLIB
 	select OF
-	select OF_PROMTREE if PROC_DEVICETREE
+	select OF_PROMTREE
 	---help---
 	  Add support for detecting the unique features of the OLPC
 	  XO hardware.
diff -druN linux-2.6.39-libre/arch/x86/Kconfig.cpu linux-3.0-rc7-libre/arch/x86/Kconfig.cpu
--- linux-2.6.39-libre/arch/x86/Kconfig.cpu	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/Kconfig.cpu	2011-07-11 19:51:52.000000000 -0400
@@ -1,6 +1,4 @@
 # Put here option for CPU selection and depending optimization
-if !X86_ELAN
-
 choice
 	prompt "Processor family"
 	default M686 if X86_32
@@ -203,6 +201,14 @@
 	  stores for this CPU, which can increase performance of some
 	  operations.
 
+config MELAN
+	bool "AMD Elan"
+	depends on X86_32
+	---help---
+	  Select this for an AMD Elan processor.
+
+	  Do not use this option for K6/Athlon/Opteron processors!
+
 config MGEODEGX1
 	bool "GeodeGX1"
 	depends on X86_32
@@ -292,8 +298,6 @@
 	  This is really intended for distributors who need more
 	  generic optimizations.
 
-endif
-
 #
 # Define implied options from the CPU selection here
 config X86_INTERNODE_CACHE_SHIFT
@@ -312,7 +316,7 @@
 	int
 	default "7" if MPENTIUM4 || MPSC
 	default "6" if MK7 || MK8 || MPENTIUMM || MCORE2 || MATOM || MVIAC7 || X86_GENERIC || GENERIC_CPU
-	default "4" if X86_ELAN || M486 || M386 || MGEODEGX1
+	default "4" if MELAN || M486 || M386 || MGEODEGX1
 	default "5" if MWINCHIP3D || MWINCHIPC6 || MCRUSOE || MEFFICEON || MCYRIXIII || MK6 || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || M586 || MVIAC3_2 || MGEODE_LX
 
 config X86_XADD
@@ -358,7 +362,7 @@
 
 config X86_ALIGNMENT_16
 	def_bool y
-	depends on MWINCHIP3D || MWINCHIPC6 || MCYRIXIII || X86_ELAN || MK6 || M586MMX || M586TSC || M586 || M486 || MVIAC3_2 || MGEODEGX1
+	depends on MWINCHIP3D || MWINCHIPC6 || MCYRIXIII || MELAN || MK6 || M586MMX || M586TSC || M586 || M486 || MVIAC3_2 || MGEODEGX1
 
 config X86_INTEL_USERCOPY
 	def_bool y
diff -druN linux-2.6.39-libre/arch/x86/Kconfig.debug linux-3.0-rc7-libre/arch/x86/Kconfig.debug
--- linux-2.6.39-libre/arch/x86/Kconfig.debug	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/Kconfig.debug	2011-07-11 19:51:52.000000000 -0400
@@ -66,26 +66,6 @@
 	  This option will cause messages to be printed if free stack space
 	  drops below a certain limit.
 
-config DEBUG_STACK_USAGE
-	bool "Stack utilization instrumentation"
-	depends on DEBUG_KERNEL
-	---help---
-	  Enables the display of the minimum amount of free stack which each
-	  task has ever had available in the sysrq-T and sysrq-P debug output.
-
-	  This option will slow down process creation somewhat.
-
-config DEBUG_PER_CPU_MAPS
-	bool "Debug access to per_cpu maps"
-	depends on DEBUG_KERNEL
-	depends on SMP
-	---help---
-	  Say Y to verify that the per_cpu map being accessed has
-	  been setup.  Adds a fair amount of code to kernel memory
-	  and decreases performance.
-
-	  Say N if unsure.
-
 config X86_PTDUMP
 	bool "Export kernel pagetable layout to userspace via debugfs"
 	depends on DEBUG_KERNEL
diff -druN linux-2.6.39-libre/arch/x86/kernel/acpi/boot.c linux-3.0-rc7-libre/arch/x86/kernel/acpi/boot.c
--- linux-2.6.39-libre/arch/x86/kernel/acpi/boot.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/kernel/acpi/boot.c	2011-07-11 19:51:52.000000000 -0400
@@ -970,7 +970,7 @@
 	mp_irq.irqflag = (trigger << 2) | polarity;
 	mp_irq.srcbus = MP_ISA_BUS;
 	mp_irq.srcbusirq = bus_irq;	/* IRQ */
-	mp_irq.dstapic = mp_ioapics[ioapic].apicid; /* APIC ID */
+	mp_irq.dstapic = mpc_ioapic_id(ioapic); /* APIC ID */
 	mp_irq.dstirq = pin;	/* INTIN# */
 
 	mp_save_irq(&mp_irq);
@@ -1021,7 +1021,7 @@
 		if (ioapic < 0)
 			continue;
 		pin = mp_find_ioapic_pin(ioapic, gsi);
-		dstapic = mp_ioapics[ioapic].apicid;
+		dstapic = mpc_ioapic_id(ioapic);
 
 		for (idx = 0; idx < mp_irq_entries; idx++) {
 			struct mpc_intsrc *irq = mp_irqs + idx;
@@ -1082,7 +1082,7 @@
 	mp_irq.srcbus = number;
 	mp_irq.srcbusirq = (((devfn >> 3) & 0x1f) << 2) | ((pin - 1) & 3);
 	ioapic = mp_find_ioapic(gsi);
-	mp_irq.dstapic = mp_ioapics[ioapic].apicid;
+	mp_irq.dstapic = mpc_ioapic_id(ioapic);
 	mp_irq.dstirq = mp_find_ioapic_pin(ioapic, gsi);
 
 	mp_save_irq(&mp_irq);
@@ -1113,7 +1113,7 @@
 
 	if (ioapic_pin > MP_MAX_IOAPIC_PIN) {
 		printk(KERN_ERR "Invalid reference to IOAPIC pin "
-		       "%d-%d\n", mp_ioapics[ioapic].apicid,
+		       "%d-%d\n", mpc_ioapic_id(ioapic),
 		       ioapic_pin);
 		return gsi;
 	}
diff -druN linux-2.6.39-libre/arch/x86/kernel/acpi/realmode/wakeup.h linux-3.0-rc7-libre/arch/x86/kernel/acpi/realmode/wakeup.h
--- linux-2.6.39-libre/arch/x86/kernel/acpi/realmode/wakeup.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/kernel/acpi/realmode/wakeup.h	2011-07-11 19:51:52.000000000 -0400
@@ -21,6 +21,9 @@
 	u32 pmode_efer_low;	/* Protected mode EFER */
 	u32 pmode_efer_high;
 	u64 pmode_gdt;
+	u32 pmode_misc_en_low;	/* Protected mode MISC_ENABLE */
+	u32 pmode_misc_en_high;
+	u32 pmode_behavior;	/* Wakeup routine behavior flags */
 	u32 realmode_flags;
 	u32 real_magic;
 	u16 trampoline_segment;	/* segment with trampoline code, 64-bit only */
@@ -39,4 +42,7 @@
 #define WAKEUP_HEADER_SIGNATURE 0x51ee1111
 #define WAKEUP_END_SIGNATURE	0x65a22c82
 
+/* Wakeup behavior bits */
+#define WAKEUP_BEHAVIOR_RESTORE_MISC_ENABLE     0
+
 #endif /* ARCH_X86_KERNEL_ACPI_RM_WAKEUP_H */
diff -druN linux-2.6.39-libre/arch/x86/kernel/acpi/realmode/wakeup.S linux-3.0-rc7-libre/arch/x86/kernel/acpi/realmode/wakeup.S
--- linux-2.6.39-libre/arch/x86/kernel/acpi/realmode/wakeup.S	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/kernel/acpi/realmode/wakeup.S	2011-07-11 19:51:52.000000000 -0400
@@ -28,6 +28,8 @@
 pmode_cr4:	.long	0	/* Saved %cr4 */
 pmode_efer:	.quad	0	/* Saved EFER */
 pmode_gdt:	.quad	0
+pmode_misc_en:	.quad	0	/* Saved MISC_ENABLE MSR */
+pmode_behavior:	.long	0	/* Wakeup behavior flags */
 realmode_flags:	.long	0
 real_magic:	.long	0
 trampoline_segment:	.word 0
@@ -91,6 +93,18 @@
 	/* Call the C code */
 	calll	main
 
+	/* Restore MISC_ENABLE before entering protected mode, in case
+	   BIOS decided to clear XD_DISABLE during S3. */
+	movl	pmode_behavior, %eax
+	btl	$WAKEUP_BEHAVIOR_RESTORE_MISC_ENABLE, %eax
+	jnc	1f
+
+	movl	pmode_misc_en, %eax
+	movl	pmode_misc_en + 4, %edx
+	movl	$MSR_IA32_MISC_ENABLE, %ecx
+	wrmsr
+1:
+
 	/* Do any other stuff... */
 
 #ifndef CONFIG_64BIT
diff -druN linux-2.6.39-libre/arch/x86/kernel/acpi/sleep.c linux-3.0-rc7-libre/arch/x86/kernel/acpi/sleep.c
--- linux-2.6.39-libre/arch/x86/kernel/acpi/sleep.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/kernel/acpi/sleep.c	2011-07-11 19:51:52.000000000 -0400
@@ -77,6 +77,12 @@
 
 	header->pmode_cr0 = read_cr0();
 	header->pmode_cr4 = read_cr4_safe();
+	header->pmode_behavior = 0;
+	if (!rdmsr_safe(MSR_IA32_MISC_ENABLE,
+			&header->pmode_misc_en_low,
+			&header->pmode_misc_en_high))
+		header->pmode_behavior |=
+			(1 << WAKEUP_BEHAVIOR_RESTORE_MISC_ENABLE);
 	header->realmode_flags = acpi_realmode_flags;
 	header->real_magic = 0x12345678;
 
@@ -112,11 +118,6 @@
 #ifdef CONFIG_HIBERNATION
 		if (strncmp(str, "s4_nohwsig", 10) == 0)
 			acpi_no_s4_hw_signature();
-		if (strncmp(str, "s4_nonvs", 8) == 0) {
-			pr_warning("ACPI: acpi_sleep=s4_nonvs is deprecated, "
-					"please use acpi_sleep=nonvs instead");
-			acpi_nvs_nosave();
-		}
 #endif
 		if (strncmp(str, "nonvs", 5) == 0)
 			acpi_nvs_nosave();
diff -druN linux-2.6.39-libre/arch/x86/kernel/alternative.c linux-3.0-rc7-libre/arch/x86/kernel/alternative.c
--- linux-2.6.39-libre/arch/x86/kernel/alternative.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/kernel/alternative.c	2011-07-11 19:51:52.000000000 -0400
@@ -67,17 +67,30 @@
 #define DPRINTK(fmt, args...) if (debug_alternative) \
 	printk(KERN_DEBUG fmt, args)
 
+/*
+ * Each GENERIC_NOPX is of X bytes, and defined as an array of bytes
+ * that correspond to that nop. Getting from one nop to the next, we
+ * add to the array the offset that is equal to the sum of all sizes of
+ * nops preceding the one we are after.
+ *
+ * Note: The GENERIC_NOP5_ATOMIC is at the end, as it breaks the
+ * nice symmetry of sizes of the previous nops.
+ */
 #if defined(GENERIC_NOP1) && !defined(CONFIG_X86_64)
-/* Use inline assembly to define this because the nops are defined
-   as inline assembly strings in the include files and we cannot
-   get them easily into strings. */
-asm("\t" __stringify(__INITRODATA_OR_MODULE) "\nintelnops: "
-	GENERIC_NOP1 GENERIC_NOP2 GENERIC_NOP3 GENERIC_NOP4 GENERIC_NOP5 GENERIC_NOP6
-	GENERIC_NOP7 GENERIC_NOP8
-    "\t.previous");
-extern const unsigned char intelnops[];
-static const unsigned char *const __initconst_or_module
-intel_nops[ASM_NOP_MAX+1] = {
+static const unsigned char intelnops[] =
+{
+	GENERIC_NOP1,
+	GENERIC_NOP2,
+	GENERIC_NOP3,
+	GENERIC_NOP4,
+	GENERIC_NOP5,
+	GENERIC_NOP6,
+	GENERIC_NOP7,
+	GENERIC_NOP8,
+	GENERIC_NOP5_ATOMIC
+};
+static const unsigned char * const intel_nops[ASM_NOP_MAX+2] =
+{
 	NULL,
 	intelnops,
 	intelnops + 1,
@@ -87,17 +100,25 @@
 	intelnops + 1 + 2 + 3 + 4 + 5,
 	intelnops + 1 + 2 + 3 + 4 + 5 + 6,
 	intelnops + 1 + 2 + 3 + 4 + 5 + 6 + 7,
+	intelnops + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8,
 };
 #endif
 
 #ifdef K8_NOP1
-asm("\t" __stringify(__INITRODATA_OR_MODULE) "\nk8nops: "
-	K8_NOP1 K8_NOP2 K8_NOP3 K8_NOP4 K8_NOP5 K8_NOP6
-	K8_NOP7 K8_NOP8
-    "\t.previous");
-extern const unsigned char k8nops[];
-static const unsigned char *const __initconst_or_module
-k8_nops[ASM_NOP_MAX+1] = {
+static const unsigned char k8nops[] =
+{
+	K8_NOP1,
+	K8_NOP2,
+	K8_NOP3,
+	K8_NOP4,
+	K8_NOP5,
+	K8_NOP6,
+	K8_NOP7,
+	K8_NOP8,
+	K8_NOP5_ATOMIC
+};
+static const unsigned char * const k8_nops[ASM_NOP_MAX+2] =
+{
 	NULL,
 	k8nops,
 	k8nops + 1,
@@ -107,17 +128,25 @@
 	k8nops + 1 + 2 + 3 + 4 + 5,
 	k8nops + 1 + 2 + 3 + 4 + 5 + 6,
 	k8nops + 1 + 2 + 3 + 4 + 5 + 6 + 7,
+	k8nops + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8,
 };
 #endif
 
 #if defined(K7_NOP1) && !defined(CONFIG_X86_64)
-asm("\t" __stringify(__INITRODATA_OR_MODULE) "\nk7nops: "
-	K7_NOP1 K7_NOP2 K7_NOP3 K7_NOP4 K7_NOP5 K7_NOP6
-	K7_NOP7 K7_NOP8
-    "\t.previous");
-extern const unsigned char k7nops[];
-static const unsigned char *const __initconst_or_module
-k7_nops[ASM_NOP_MAX+1] = {
+static const unsigned char k7nops[] =
+{
+	K7_NOP1,
+	K7_NOP2,
+	K7_NOP3,
+	K7_NOP4,
+	K7_NOP5,
+	K7_NOP6,
+	K7_NOP7,
+	K7_NOP8,
+	K7_NOP5_ATOMIC
+};
+static const unsigned char * const k7_nops[ASM_NOP_MAX+2] =
+{
 	NULL,
 	k7nops,
 	k7nops + 1,
@@ -127,17 +156,25 @@
 	k7nops + 1 + 2 + 3 + 4 + 5,
 	k7nops + 1 + 2 + 3 + 4 + 5 + 6,
 	k7nops + 1 + 2 + 3 + 4 + 5 + 6 + 7,
+	k7nops + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8,
 };
 #endif
 
 #ifdef P6_NOP1
-asm("\t" __stringify(__INITRODATA_OR_MODULE) "\np6nops: "
-	P6_NOP1 P6_NOP2 P6_NOP3 P6_NOP4 P6_NOP5 P6_NOP6
-	P6_NOP7 P6_NOP8
-    "\t.previous");
-extern const unsigned char p6nops[];
-static const unsigned char *const __initconst_or_module
-p6_nops[ASM_NOP_MAX+1] = {
+static const unsigned char  __initconst_or_module p6nops[] =
+{
+	P6_NOP1,
+	P6_NOP2,
+	P6_NOP3,
+	P6_NOP4,
+	P6_NOP5,
+	P6_NOP6,
+	P6_NOP7,
+	P6_NOP8,
+	P6_NOP5_ATOMIC
+};
+static const unsigned char * const p6_nops[ASM_NOP_MAX+2] =
+{
 	NULL,
 	p6nops,
 	p6nops + 1,
@@ -147,47 +184,65 @@
 	p6nops + 1 + 2 + 3 + 4 + 5,
 	p6nops + 1 + 2 + 3 + 4 + 5 + 6,
 	p6nops + 1 + 2 + 3 + 4 + 5 + 6 + 7,
+	p6nops + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8,
 };
 #endif
 
+/* Initialize these to a safe default */
 #ifdef CONFIG_X86_64
+const unsigned char * const *ideal_nops = p6_nops;
+#else
+const unsigned char * const *ideal_nops = intel_nops;
+#endif
 
-extern char __vsyscall_0;
-static const unsigned char *const *__init_or_module find_nop_table(void)
+void __init arch_init_ideal_nops(void)
 {
-	if (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL &&
-	    boot_cpu_has(X86_FEATURE_NOPL))
-		return p6_nops;
-	else
-		return k8_nops;
-}
-
-#else /* CONFIG_X86_64 */
+	switch (boot_cpu_data.x86_vendor) {
+	case X86_VENDOR_INTEL:
+		/*
+		 * Due to a decoder implementation quirk, some
+		 * specific Intel CPUs actually perform better with
+		 * the "k8_nops" than with the SDM-recommended NOPs.
+		 */
+		if (boot_cpu_data.x86 == 6 &&
+		    boot_cpu_data.x86_model >= 0x0f &&
+		    boot_cpu_data.x86_model != 0x1c &&
+		    boot_cpu_data.x86_model != 0x26 &&
+		    boot_cpu_data.x86_model != 0x27 &&
+		    boot_cpu_data.x86_model < 0x30) {
+			ideal_nops = k8_nops;
+		} else if (boot_cpu_has(X86_FEATURE_NOPL)) {
+			   ideal_nops = p6_nops;
+		} else {
+#ifdef CONFIG_X86_64
+			ideal_nops = k8_nops;
+#else
+			ideal_nops = intel_nops;
+#endif
+		}
 
-static const unsigned char *const *__init_or_module find_nop_table(void)
-{
-	if (boot_cpu_has(X86_FEATURE_K8))
-		return k8_nops;
-	else if (boot_cpu_has(X86_FEATURE_K7))
-		return k7_nops;
-	else if (boot_cpu_has(X86_FEATURE_NOPL))
-		return p6_nops;
-	else
-		return intel_nops;
+	default:
+#ifdef CONFIG_X86_64
+		ideal_nops = k8_nops;
+#else
+		if (boot_cpu_has(X86_FEATURE_K8))
+			ideal_nops = k8_nops;
+		else if (boot_cpu_has(X86_FEATURE_K7))
+			ideal_nops = k7_nops;
+		else
+			ideal_nops = intel_nops;
+#endif
+	}
 }
 
-#endif /* CONFIG_X86_64 */
-
 /* Use this to add nops to a buffer, then text_poke the whole buffer. */
 static void __init_or_module add_nops(void *insns, unsigned int len)
 {
-	const unsigned char *const *noptable = find_nop_table();
-
 	while (len > 0) {
 		unsigned int noplen = len;
 		if (noplen > ASM_NOP_MAX)
 			noplen = ASM_NOP_MAX;
-		memcpy(insns, noptable[noplen], noplen);
+		memcpy(insns, ideal_nops[noplen], noplen);
 		insns += noplen;
 		len -= noplen;
 	}
@@ -195,6 +250,7 @@
 
 extern struct alt_instr __alt_instructions[], __alt_instructions_end[];
 extern s32 __smp_locks[], __smp_locks_end[];
+extern char __vsyscall_0;
 void *text_poke_early(void *addr, const void *opcode, size_t len);
 
 /* Replace instructions with better alternatives for this CPU type.
@@ -210,6 +266,15 @@
 	u8 insnbuf[MAX_PATCH_LEN];
 
 	DPRINTK("%s: alt table %p -> %p\n", __func__, start, end);
+	/*
+	 * The scan order should be from start to end. A later scanned
+	 * alternative code can overwrite a previous scanned alternative code.
+	 * Some kernel functions (e.g. memcpy, memset, etc) use this order to
+	 * patch code.
+	 *
+	 * So be careful if you want to change the scan order to any other
+	 * order.
+	 */
 	for (a = start; a < end; a++) {
 		u8 *instr = a->instr;
 		BUG_ON(a->replacementlen > a->instrlen);
@@ -678,29 +743,3 @@
 	wrote_text = 0;
 	__stop_machine(stop_machine_text_poke, (void *)&tpp, NULL);
 }
-
-#if defined(CONFIG_DYNAMIC_FTRACE) || defined(HAVE_JUMP_LABEL)
-
-#ifdef CONFIG_X86_64
-unsigned char ideal_nop5[5] = { 0x66, 0x66, 0x66, 0x66, 0x90 };
-#else
-unsigned char ideal_nop5[5] = { 0x3e, 0x8d, 0x74, 0x26, 0x00 };
-#endif
-
-void __init arch_init_ideal_nop5(void)
-{
-	/*
-	 * There is no good nop for all x86 archs.  This selection
-	 * algorithm should be unified with the one in find_nop_table(),
-	 * but this should be good enough for now.
-	 *
-	 * For cases other than the ones below, use the safe (as in
-	 * always functional) defaults above.
-	 */
-#ifdef CONFIG_X86_64
-	/* Don't use these on 32 bits due to broken virtualizers */
-	if (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL)
-		memcpy(ideal_nop5, p6_nops[5], 5);
-#endif
-}
-#endif
diff -druN linux-2.6.39-libre/arch/x86/kernel/amd_gart_64.c linux-3.0-rc7-libre/arch/x86/kernel/amd_gart_64.c
--- linux-2.6.39-libre/arch/x86/kernel/amd_gart_64.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/x86/kernel/amd_gart_64.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,898 @@
+/*
+ * Dynamic DMA mapping support for AMD Hammer.
+ *
+ * Use the integrated AGP GART in the Hammer northbridge as an IOMMU for PCI.
+ * This allows to use PCI devices that only support 32bit addresses on systems
+ * with more than 4GB.
+ *
+ * See Documentation/PCI/PCI-DMA-mapping.txt for the interface specification.
+ *
+ * Copyright 2002 Andi Kleen, SuSE Labs.
+ * Subject to the GNU General Public License v2 only.
+ */
+
+#include <linux/types.h>
+#include <linux/ctype.h>
+#include <linux/agp_backend.h>
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/sched.h>
+#include <linux/string.h>
+#include <linux/spinlock.h>
+#include <linux/pci.h>
+#include <linux/module.h>
+#include <linux/topology.h>
+#include <linux/interrupt.h>
+#include <linux/bitmap.h>
+#include <linux/kdebug.h>
+#include <linux/scatterlist.h>
+#include <linux/iommu-helper.h>
+#include <linux/syscore_ops.h>
+#include <linux/io.h>
+#include <linux/gfp.h>
+#include <asm/atomic.h>
+#include <asm/mtrr.h>
+#include <asm/pgtable.h>
+#include <asm/proto.h>
+#include <asm/iommu.h>
+#include <asm/gart.h>
+#include <asm/cacheflush.h>
+#include <asm/swiotlb.h>
+#include <asm/dma.h>
+#include <asm/amd_nb.h>
+#include <asm/x86_init.h>
+#include <asm/iommu_table.h>
+
+static unsigned long iommu_bus_base;	/* GART remapping area (physical) */
+static unsigned long iommu_size;	/* size of remapping area bytes */
+static unsigned long iommu_pages;	/* .. and in pages */
+
+static u32 *iommu_gatt_base;		/* Remapping table */
+
+static dma_addr_t bad_dma_addr;
+
+/*
+ * If this is disabled the IOMMU will use an optimized flushing strategy
+ * of only flushing when an mapping is reused. With it true the GART is
+ * flushed for every mapping. Problem is that doing the lazy flush seems
+ * to trigger bugs with some popular PCI cards, in particular 3ware (but
+ * has been also also seen with Qlogic at least).
+ */
+static int iommu_fullflush = 1;
+
+/* Allocation bitmap for the remapping area: */
+static DEFINE_SPINLOCK(iommu_bitmap_lock);
+/* Guarded by iommu_bitmap_lock: */
+static unsigned long *iommu_gart_bitmap;
+
+static u32 gart_unmapped_entry;
+
+#define GPTE_VALID    1
+#define GPTE_COHERENT 2
+#define GPTE_ENCODE(x) \
+	(((x) & 0xfffff000) | (((x) >> 32) << 4) | GPTE_VALID | GPTE_COHERENT)
+#define GPTE_DECODE(x) (((x) & 0xfffff000) | (((u64)(x) & 0xff0) << 28))
+
+#define EMERGENCY_PAGES 32 /* = 128KB */
+
+#ifdef CONFIG_AGP
+#define AGPEXTERN extern
+#else
+#define AGPEXTERN
+#endif
+
+/* GART can only remap to physical addresses < 1TB */
+#define GART_MAX_PHYS_ADDR	(1ULL << 40)
+
+/* backdoor interface to AGP driver */
+AGPEXTERN int agp_memory_reserved;
+AGPEXTERN __u32 *agp_gatt_table;
+
+static unsigned long next_bit;  /* protected by iommu_bitmap_lock */
+static bool need_flush;		/* global flush state. set for each gart wrap */
+
+static unsigned long alloc_iommu(struct device *dev, int size,
+				 unsigned long align_mask)
+{
+	unsigned long offset, flags;
+	unsigned long boundary_size;
+	unsigned long base_index;
+
+	base_index = ALIGN(iommu_bus_base & dma_get_seg_boundary(dev),
+			   PAGE_SIZE) >> PAGE_SHIFT;
+	boundary_size = ALIGN((u64)dma_get_seg_boundary(dev) + 1,
+			      PAGE_SIZE) >> PAGE_SHIFT;
+
+	spin_lock_irqsave(&iommu_bitmap_lock, flags);
+	offset = iommu_area_alloc(iommu_gart_bitmap, iommu_pages, next_bit,
+				  size, base_index, boundary_size, align_mask);
+	if (offset == -1) {
+		need_flush = true;
+		offset = iommu_area_alloc(iommu_gart_bitmap, iommu_pages, 0,
+					  size, base_index, boundary_size,
+					  align_mask);
+	}
+	if (offset != -1) {
+		next_bit = offset+size;
+		if (next_bit >= iommu_pages) {
+			next_bit = 0;
+			need_flush = true;
+		}
+	}
+	if (iommu_fullflush)
+		need_flush = true;
+	spin_unlock_irqrestore(&iommu_bitmap_lock, flags);
+
+	return offset;
+}
+
+static void free_iommu(unsigned long offset, int size)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&iommu_bitmap_lock, flags);
+	bitmap_clear(iommu_gart_bitmap, offset, size);
+	if (offset >= next_bit)
+		next_bit = offset + size;
+	spin_unlock_irqrestore(&iommu_bitmap_lock, flags);
+}
+
+/*
+ * Use global flush state to avoid races with multiple flushers.
+ */
+static void flush_gart(void)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&iommu_bitmap_lock, flags);
+	if (need_flush) {
+		amd_flush_garts();
+		need_flush = false;
+	}
+	spin_unlock_irqrestore(&iommu_bitmap_lock, flags);
+}
+
+#ifdef CONFIG_IOMMU_LEAK
+/* Debugging aid for drivers that don't free their IOMMU tables */
+static int leak_trace;
+static int iommu_leak_pages = 20;
+
+static void dump_leak(void)
+{
+	static int dump;
+
+	if (dump)
+		return;
+	dump = 1;
+
+	show_stack(NULL, NULL);
+	debug_dma_dump_mappings(NULL);
+}
+#endif
+
+static void iommu_full(struct device *dev, size_t size, int dir)
+{
+	/*
+	 * Ran out of IOMMU space for this operation. This is very bad.
+	 * Unfortunately the drivers cannot handle this operation properly.
+	 * Return some non mapped prereserved space in the aperture and
+	 * let the Northbridge deal with it. This will result in garbage
+	 * in the IO operation. When the size exceeds the prereserved space
+	 * memory corruption will occur or random memory will be DMAed
+	 * out. Hopefully no network devices use single mappings that big.
+	 */
+
+	dev_err(dev, "PCI-DMA: Out of IOMMU space for %lu bytes\n", size);
+
+	if (size > PAGE_SIZE*EMERGENCY_PAGES) {
+		if (dir == PCI_DMA_FROMDEVICE || dir == PCI_DMA_BIDIRECTIONAL)
+			panic("PCI-DMA: Memory would be corrupted\n");
+		if (dir == PCI_DMA_TODEVICE || dir == PCI_DMA_BIDIRECTIONAL)
+			panic(KERN_ERR
+				"PCI-DMA: Random memory would be DMAed\n");
+	}
+#ifdef CONFIG_IOMMU_LEAK
+	dump_leak();
+#endif
+}
+
+static inline int
+need_iommu(struct device *dev, unsigned long addr, size_t size)
+{
+	return force_iommu || !dma_capable(dev, addr, size);
+}
+
+static inline int
+nonforced_iommu(struct device *dev, unsigned long addr, size_t size)
+{
+	return !dma_capable(dev, addr, size);
+}
+
+/* Map a single continuous physical area into the IOMMU.
+ * Caller needs to check if the iommu is needed and flush.
+ */
+static dma_addr_t dma_map_area(struct device *dev, dma_addr_t phys_mem,
+				size_t size, int dir, unsigned long align_mask)
+{
+	unsigned long npages = iommu_num_pages(phys_mem, size, PAGE_SIZE);
+	unsigned long iommu_page;
+	int i;
+
+	if (unlikely(phys_mem + size > GART_MAX_PHYS_ADDR))
+		return bad_dma_addr;
+
+	iommu_page = alloc_iommu(dev, npages, align_mask);
+	if (iommu_page == -1) {
+		if (!nonforced_iommu(dev, phys_mem, size))
+			return phys_mem;
+		if (panic_on_overflow)
+			panic("dma_map_area overflow %lu bytes\n", size);
+		iommu_full(dev, size, dir);
+		return bad_dma_addr;
+	}
+
+	for (i = 0; i < npages; i++) {
+		iommu_gatt_base[iommu_page + i] = GPTE_ENCODE(phys_mem);
+		phys_mem += PAGE_SIZE;
+	}
+	return iommu_bus_base + iommu_page*PAGE_SIZE + (phys_mem & ~PAGE_MASK);
+}
+
+/* Map a single area into the IOMMU */
+static dma_addr_t gart_map_page(struct device *dev, struct page *page,
+				unsigned long offset, size_t size,
+				enum dma_data_direction dir,
+				struct dma_attrs *attrs)
+{
+	unsigned long bus;
+	phys_addr_t paddr = page_to_phys(page) + offset;
+
+	if (!dev)
+		dev = &x86_dma_fallback_dev;
+
+	if (!need_iommu(dev, paddr, size))
+		return paddr;
+
+	bus = dma_map_area(dev, paddr, size, dir, 0);
+	flush_gart();
+
+	return bus;
+}
+
+/*
+ * Free a DMA mapping.
+ */
+static void gart_unmap_page(struct device *dev, dma_addr_t dma_addr,
+			    size_t size, enum dma_data_direction dir,
+			    struct dma_attrs *attrs)
+{
+	unsigned long iommu_page;
+	int npages;
+	int i;
+
+	if (dma_addr < iommu_bus_base + EMERGENCY_PAGES*PAGE_SIZE ||
+	    dma_addr >= iommu_bus_base + iommu_size)
+		return;
+
+	iommu_page = (dma_addr - iommu_bus_base)>>PAGE_SHIFT;
+	npages = iommu_num_pages(dma_addr, size, PAGE_SIZE);
+	for (i = 0; i < npages; i++) {
+		iommu_gatt_base[iommu_page + i] = gart_unmapped_entry;
+	}
+	free_iommu(iommu_page, npages);
+}
+
+/*
+ * Wrapper for pci_unmap_single working with scatterlists.
+ */
+static void gart_unmap_sg(struct device *dev, struct scatterlist *sg, int nents,
+			  enum dma_data_direction dir, struct dma_attrs *attrs)
+{
+	struct scatterlist *s;
+	int i;
+
+	for_each_sg(sg, s, nents, i) {
+		if (!s->dma_length || !s->length)
+			break;
+		gart_unmap_page(dev, s->dma_address, s->dma_length, dir, NULL);
+	}
+}
+
+/* Fallback for dma_map_sg in case of overflow */
+static int dma_map_sg_nonforce(struct device *dev, struct scatterlist *sg,
+			       int nents, int dir)
+{
+	struct scatterlist *s;
+	int i;
+
+#ifdef CONFIG_IOMMU_DEBUG
+	pr_debug("dma_map_sg overflow\n");
+#endif
+
+	for_each_sg(sg, s, nents, i) {
+		unsigned long addr = sg_phys(s);
+
+		if (nonforced_iommu(dev, addr, s->length)) {
+			addr = dma_map_area(dev, addr, s->length, dir, 0);
+			if (addr == bad_dma_addr) {
+				if (i > 0)
+					gart_unmap_sg(dev, sg, i, dir, NULL);
+				nents = 0;
+				sg[0].dma_length = 0;
+				break;
+			}
+		}
+		s->dma_address = addr;
+		s->dma_length = s->length;
+	}
+	flush_gart();
+
+	return nents;
+}
+
+/* Map multiple scatterlist entries continuous into the first. */
+static int __dma_map_cont(struct device *dev, struct scatterlist *start,
+			  int nelems, struct scatterlist *sout,
+			  unsigned long pages)
+{
+	unsigned long iommu_start = alloc_iommu(dev, pages, 0);
+	unsigned long iommu_page = iommu_start;
+	struct scatterlist *s;
+	int i;
+
+	if (iommu_start == -1)
+		return -1;
+
+	for_each_sg(start, s, nelems, i) {
+		unsigned long pages, addr;
+		unsigned long phys_addr = s->dma_address;
+
+		BUG_ON(s != start && s->offset);
+		if (s == start) {
+			sout->dma_address = iommu_bus_base;
+			sout->dma_address += iommu_page*PAGE_SIZE + s->offset;
+			sout->dma_length = s->length;
+		} else {
+			sout->dma_length += s->length;
+		}
+
+		addr = phys_addr;
+		pages = iommu_num_pages(s->offset, s->length, PAGE_SIZE);
+		while (pages--) {
+			iommu_gatt_base[iommu_page] = GPTE_ENCODE(addr);
+			addr += PAGE_SIZE;
+			iommu_page++;
+		}
+	}
+	BUG_ON(iommu_page - iommu_start != pages);
+
+	return 0;
+}
+
+static inline int
+dma_map_cont(struct device *dev, struct scatterlist *start, int nelems,
+	     struct scatterlist *sout, unsigned long pages, int need)
+{
+	if (!need) {
+		BUG_ON(nelems != 1);
+		sout->dma_address = start->dma_address;
+		sout->dma_length = start->length;
+		return 0;
+	}
+	return __dma_map_cont(dev, start, nelems, sout, pages);
+}
+
+/*
+ * DMA map all entries in a scatterlist.
+ * Merge chunks that have page aligned sizes into a continuous mapping.
+ */
+static int gart_map_sg(struct device *dev, struct scatterlist *sg, int nents,
+		       enum dma_data_direction dir, struct dma_attrs *attrs)
+{
+	struct scatterlist *s, *ps, *start_sg, *sgmap;
+	int need = 0, nextneed, i, out, start;
+	unsigned long pages = 0;
+	unsigned int seg_size;
+	unsigned int max_seg_size;
+
+	if (nents == 0)
+		return 0;
+
+	if (!dev)
+		dev = &x86_dma_fallback_dev;
+
+	out		= 0;
+	start		= 0;
+	start_sg	= sg;
+	sgmap		= sg;
+	seg_size	= 0;
+	max_seg_size	= dma_get_max_seg_size(dev);
+	ps		= NULL; /* shut up gcc */
+
+	for_each_sg(sg, s, nents, i) {
+		dma_addr_t addr = sg_phys(s);
+
+		s->dma_address = addr;
+		BUG_ON(s->length == 0);
+
+		nextneed = need_iommu(dev, addr, s->length);
+
+		/* Handle the previous not yet processed entries */
+		if (i > start) {
+			/*
+			 * Can only merge when the last chunk ends on a
+			 * page boundary and the new one doesn't have an
+			 * offset.
+			 */
+			if (!iommu_merge || !nextneed || !need || s->offset ||
+			    (s->length + seg_size > max_seg_size) ||
+			    (ps->offset + ps->length) % PAGE_SIZE) {
+				if (dma_map_cont(dev, start_sg, i - start,
+						 sgmap, pages, need) < 0)
+					goto error;
+				out++;
+
+				seg_size	= 0;
+				sgmap		= sg_next(sgmap);
+				pages		= 0;
+				start		= i;
+				start_sg	= s;
+			}
+		}
+
+		seg_size += s->length;
+		need = nextneed;
+		pages += iommu_num_pages(s->offset, s->length, PAGE_SIZE);
+		ps = s;
+	}
+	if (dma_map_cont(dev, start_sg, i - start, sgmap, pages, need) < 0)
+		goto error;
+	out++;
+	flush_gart();
+	if (out < nents) {
+		sgmap = sg_next(sgmap);
+		sgmap->dma_length = 0;
+	}
+	return out;
+
+error:
+	flush_gart();
+	gart_unmap_sg(dev, sg, out, dir, NULL);
+
+	/* When it was forced or merged try again in a dumb way */
+	if (force_iommu || iommu_merge) {
+		out = dma_map_sg_nonforce(dev, sg, nents, dir);
+		if (out > 0)
+			return out;
+	}
+	if (panic_on_overflow)
+		panic("dma_map_sg: overflow on %lu pages\n", pages);
+
+	iommu_full(dev, pages << PAGE_SHIFT, dir);
+	for_each_sg(sg, s, nents, i)
+		s->dma_address = bad_dma_addr;
+	return 0;
+}
+
+/* allocate and map a coherent mapping */
+static void *
+gart_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_addr,
+		    gfp_t flag)
+{
+	dma_addr_t paddr;
+	unsigned long align_mask;
+	struct page *page;
+
+	if (force_iommu && !(flag & GFP_DMA)) {
+		flag &= ~(__GFP_DMA | __GFP_HIGHMEM | __GFP_DMA32);
+		page = alloc_pages(flag | __GFP_ZERO, get_order(size));
+		if (!page)
+			return NULL;
+
+		align_mask = (1UL << get_order(size)) - 1;
+		paddr = dma_map_area(dev, page_to_phys(page), size,
+				     DMA_BIDIRECTIONAL, align_mask);
+
+		flush_gart();
+		if (paddr != bad_dma_addr) {
+			*dma_addr = paddr;
+			return page_address(page);
+		}
+		__free_pages(page, get_order(size));
+	} else
+		return dma_generic_alloc_coherent(dev, size, dma_addr, flag);
+
+	return NULL;
+}
+
+/* free a coherent mapping */
+static void
+gart_free_coherent(struct device *dev, size_t size, void *vaddr,
+		   dma_addr_t dma_addr)
+{
+	gart_unmap_page(dev, dma_addr, size, DMA_BIDIRECTIONAL, NULL);
+	free_pages((unsigned long)vaddr, get_order(size));
+}
+
+static int gart_mapping_error(struct device *dev, dma_addr_t dma_addr)
+{
+	return (dma_addr == bad_dma_addr);
+}
+
+static int no_agp;
+
+static __init unsigned long check_iommu_size(unsigned long aper, u64 aper_size)
+{
+	unsigned long a;
+
+	if (!iommu_size) {
+		iommu_size = aper_size;
+		if (!no_agp)
+			iommu_size /= 2;
+	}
+
+	a = aper + iommu_size;
+	iommu_size -= round_up(a, PMD_PAGE_SIZE) - a;
+
+	if (iommu_size < 64*1024*1024) {
+		pr_warning(
+			"PCI-DMA: Warning: Small IOMMU %luMB."
+			" Consider increasing the AGP aperture in BIOS\n",
+				iommu_size >> 20);
+	}
+
+	return iommu_size;
+}
+
+static __init unsigned read_aperture(struct pci_dev *dev, u32 *size)
+{
+	unsigned aper_size = 0, aper_base_32, aper_order;
+	u64 aper_base;
+
+	pci_read_config_dword(dev, AMD64_GARTAPERTUREBASE, &aper_base_32);
+	pci_read_config_dword(dev, AMD64_GARTAPERTURECTL, &aper_order);
+	aper_order = (aper_order >> 1) & 7;
+
+	aper_base = aper_base_32 & 0x7fff;
+	aper_base <<= 25;
+
+	aper_size = (32 * 1024 * 1024) << aper_order;
+	if (aper_base + aper_size > 0x100000000UL || !aper_size)
+		aper_base = 0;
+
+	*size = aper_size;
+	return aper_base;
+}
+
+static void enable_gart_translations(void)
+{
+	int i;
+
+	if (!amd_nb_has_feature(AMD_NB_GART))
+		return;
+
+	for (i = 0; i < amd_nb_num(); i++) {
+		struct pci_dev *dev = node_to_amd_nb(i)->misc;
+
+		enable_gart_translation(dev, __pa(agp_gatt_table));
+	}
+
+	/* Flush the GART-TLB to remove stale entries */
+	amd_flush_garts();
+}
+
+/*
+ * If fix_up_north_bridges is set, the north bridges have to be fixed up on
+ * resume in the same way as they are handled in gart_iommu_hole_init().
+ */
+static bool fix_up_north_bridges;
+static u32 aperture_order;
+static u32 aperture_alloc;
+
+void set_up_gart_resume(u32 aper_order, u32 aper_alloc)
+{
+	fix_up_north_bridges = true;
+	aperture_order = aper_order;
+	aperture_alloc = aper_alloc;
+}
+
+static void gart_fixup_northbridges(void)
+{
+	int i;
+
+	if (!fix_up_north_bridges)
+		return;
+
+	if (!amd_nb_has_feature(AMD_NB_GART))
+		return;
+
+	pr_info("PCI-DMA: Restoring GART aperture settings\n");
+
+	for (i = 0; i < amd_nb_num(); i++) {
+		struct pci_dev *dev = node_to_amd_nb(i)->misc;
+
+		/*
+		 * Don't enable translations just yet.  That is the next
+		 * step.  Restore the pre-suspend aperture settings.
+		 */
+		gart_set_size_and_enable(dev, aperture_order);
+		pci_write_config_dword(dev, AMD64_GARTAPERTUREBASE, aperture_alloc >> 25);
+	}
+}
+
+static void gart_resume(void)
+{
+	pr_info("PCI-DMA: Resuming GART IOMMU\n");
+
+	gart_fixup_northbridges();
+
+	enable_gart_translations();
+}
+
+static struct syscore_ops gart_syscore_ops = {
+	.resume		= gart_resume,
+
+};
+
+/*
+ * Private Northbridge GATT initialization in case we cannot use the
+ * AGP driver for some reason.
+ */
+static __init int init_amd_gatt(struct agp_kern_info *info)
+{
+	unsigned aper_size, gatt_size, new_aper_size;
+	unsigned aper_base, new_aper_base;
+	struct pci_dev *dev;
+	void *gatt;
+	int i;
+
+	pr_info("PCI-DMA: Disabling AGP.\n");
+
+	aper_size = aper_base = info->aper_size = 0;
+	dev = NULL;
+	for (i = 0; i < amd_nb_num(); i++) {
+		dev = node_to_amd_nb(i)->misc;
+		new_aper_base = read_aperture(dev, &new_aper_size);
+		if (!new_aper_base)
+			goto nommu;
+
+		if (!aper_base) {
+			aper_size = new_aper_size;
+			aper_base = new_aper_base;
+		}
+		if (aper_size != new_aper_size || aper_base != new_aper_base)
+			goto nommu;
+	}
+	if (!aper_base)
+		goto nommu;
+
+	info->aper_base = aper_base;
+	info->aper_size = aper_size >> 20;
+
+	gatt_size = (aper_size >> PAGE_SHIFT) * sizeof(u32);
+	gatt = (void *)__get_free_pages(GFP_KERNEL | __GFP_ZERO,
+					get_order(gatt_size));
+	if (!gatt)
+		panic("Cannot allocate GATT table");
+	if (set_memory_uc((unsigned long)gatt, gatt_size >> PAGE_SHIFT))
+		panic("Could not set GART PTEs to uncacheable pages");
+
+	agp_gatt_table = gatt;
+
+	register_syscore_ops(&gart_syscore_ops);
+
+	flush_gart();
+
+	pr_info("PCI-DMA: aperture base @ %x size %u KB\n",
+	       aper_base, aper_size>>10);
+
+	return 0;
+
+ nommu:
+	/* Should not happen anymore */
+	pr_warning("PCI-DMA: More than 4GB of RAM and no IOMMU\n"
+	       "falling back to iommu=soft.\n");
+	return -1;
+}
+
+static struct dma_map_ops gart_dma_ops = {
+	.map_sg				= gart_map_sg,
+	.unmap_sg			= gart_unmap_sg,
+	.map_page			= gart_map_page,
+	.unmap_page			= gart_unmap_page,
+	.alloc_coherent			= gart_alloc_coherent,
+	.free_coherent			= gart_free_coherent,
+	.mapping_error			= gart_mapping_error,
+};
+
+static void gart_iommu_shutdown(void)
+{
+	struct pci_dev *dev;
+	int i;
+
+	/* don't shutdown it if there is AGP installed */
+	if (!no_agp)
+		return;
+
+	if (!amd_nb_has_feature(AMD_NB_GART))
+		return;
+
+	for (i = 0; i < amd_nb_num(); i++) {
+		u32 ctl;
+
+		dev = node_to_amd_nb(i)->misc;
+		pci_read_config_dword(dev, AMD64_GARTAPERTURECTL, &ctl);
+
+		ctl &= ~GARTEN;
+
+		pci_write_config_dword(dev, AMD64_GARTAPERTURECTL, ctl);
+	}
+}
+
+int __init gart_iommu_init(void)
+{
+	struct agp_kern_info info;
+	unsigned long iommu_start;
+	unsigned long aper_base, aper_size;
+	unsigned long start_pfn, end_pfn;
+	unsigned long scratch;
+	long i;
+
+	if (!amd_nb_has_feature(AMD_NB_GART))
+		return 0;
+
+#ifndef CONFIG_AGP_AMD64
+	no_agp = 1;
+#else
+	/* Makefile puts PCI initialization via subsys_initcall first. */
+	/* Add other AMD AGP bridge drivers here */
+	no_agp = no_agp ||
+		(agp_amd64_init() < 0) ||
+		(agp_copy_info(agp_bridge, &info) < 0);
+#endif
+
+	if (no_iommu ||
+	    (!force_iommu && max_pfn <= MAX_DMA32_PFN) ||
+	    !gart_iommu_aperture ||
+	    (no_agp && init_amd_gatt(&info) < 0)) {
+		if (max_pfn > MAX_DMA32_PFN) {
+			pr_warning("More than 4GB of memory but GART IOMMU not available.\n");
+			pr_warning("falling back to iommu=soft.\n");
+		}
+		return 0;
+	}
+
+	/* need to map that range */
+	aper_size	= info.aper_size << 20;
+	aper_base	= info.aper_base;
+	end_pfn		= (aper_base>>PAGE_SHIFT) + (aper_size>>PAGE_SHIFT);
+
+	if (end_pfn > max_low_pfn_mapped) {
+		start_pfn = (aper_base>>PAGE_SHIFT);
+		init_memory_mapping(start_pfn<<PAGE_SHIFT, end_pfn<<PAGE_SHIFT);
+	}
+
+	pr_info("PCI-DMA: using GART IOMMU.\n");
+	iommu_size = check_iommu_size(info.aper_base, aper_size);
+	iommu_pages = iommu_size >> PAGE_SHIFT;
+
+	iommu_gart_bitmap = (void *) __get_free_pages(GFP_KERNEL | __GFP_ZERO,
+						      get_order(iommu_pages/8));
+	if (!iommu_gart_bitmap)
+		panic("Cannot allocate iommu bitmap\n");
+
+#ifdef CONFIG_IOMMU_LEAK
+	if (leak_trace) {
+		int ret;
+
+		ret = dma_debug_resize_entries(iommu_pages);
+		if (ret)
+			pr_debug("PCI-DMA: Cannot trace all the entries\n");
+	}
+#endif
+
+	/*
+	 * Out of IOMMU space handling.
+	 * Reserve some invalid pages at the beginning of the GART.
+	 */
+	bitmap_set(iommu_gart_bitmap, 0, EMERGENCY_PAGES);
+
+	pr_info("PCI-DMA: Reserving %luMB of IOMMU area in the AGP aperture\n",
+	       iommu_size >> 20);
+
+	agp_memory_reserved	= iommu_size;
+	iommu_start		= aper_size - iommu_size;
+	iommu_bus_base		= info.aper_base + iommu_start;
+	bad_dma_addr		= iommu_bus_base;
+	iommu_gatt_base		= agp_gatt_table + (iommu_start>>PAGE_SHIFT);
+
+	/*
+	 * Unmap the IOMMU part of the GART. The alias of the page is
+	 * always mapped with cache enabled and there is no full cache
+	 * coherency across the GART remapping. The unmapping avoids
+	 * automatic prefetches from the CPU allocating cache lines in
+	 * there. All CPU accesses are done via the direct mapping to
+	 * the backing memory. The GART address is only used by PCI
+	 * devices.
+	 */
+	set_memory_np((unsigned long)__va(iommu_bus_base),
+				iommu_size >> PAGE_SHIFT);
+	/*
+	 * Tricky. The GART table remaps the physical memory range,
+	 * so the CPU wont notice potential aliases and if the memory
+	 * is remapped to UC later on, we might surprise the PCI devices
+	 * with a stray writeout of a cacheline. So play it sure and
+	 * do an explicit, full-scale wbinvd() _after_ having marked all
+	 * the pages as Not-Present:
+	 */
+	wbinvd();
+
+	/*
+	 * Now all caches are flushed and we can safely enable
+	 * GART hardware.  Doing it early leaves the possibility
+	 * of stale cache entries that can lead to GART PTE
+	 * errors.
+	 */
+	enable_gart_translations();
+
+	/*
+	 * Try to workaround a bug (thanks to BenH):
+	 * Set unmapped entries to a scratch page instead of 0.
+	 * Any prefetches that hit unmapped entries won't get an bus abort
+	 * then. (P2P bridge may be prefetching on DMA reads).
+	 */
+	scratch = get_zeroed_page(GFP_KERNEL);
+	if (!scratch)
+		panic("Cannot allocate iommu scratch page");
+	gart_unmapped_entry = GPTE_ENCODE(__pa(scratch));
+	for (i = EMERGENCY_PAGES; i < iommu_pages; i++)
+		iommu_gatt_base[i] = gart_unmapped_entry;
+
+	flush_gart();
+	dma_ops = &gart_dma_ops;
+	x86_platform.iommu_shutdown = gart_iommu_shutdown;
+	swiotlb = 0;
+
+	return 0;
+}
+
+void __init gart_parse_options(char *p)
+{
+	int arg;
+
+#ifdef CONFIG_IOMMU_LEAK
+	if (!strncmp(p, "leak", 4)) {
+		leak_trace = 1;
+		p += 4;
+		if (*p == '=')
+			++p;
+		if (isdigit(*p) && get_option(&p, &arg))
+			iommu_leak_pages = arg;
+	}
+#endif
+	if (isdigit(*p) && get_option(&p, &arg))
+		iommu_size = arg;
+	if (!strncmp(p, "fullflush", 9))
+		iommu_fullflush = 1;
+	if (!strncmp(p, "nofullflush", 11))
+		iommu_fullflush = 0;
+	if (!strncmp(p, "noagp", 5))
+		no_agp = 1;
+	if (!strncmp(p, "noaperture", 10))
+		fix_aperture = 0;
+	/* duplicated from pci-dma.c */
+	if (!strncmp(p, "force", 5))
+		gart_iommu_aperture_allowed = 1;
+	if (!strncmp(p, "allowed", 7))
+		gart_iommu_aperture_allowed = 1;
+	if (!strncmp(p, "memaper", 7)) {
+		fallback_aper_force = 1;
+		p += 7;
+		if (*p == '=') {
+			++p;
+			if (get_option(&p, &arg))
+				fallback_aper_order = arg;
+		}
+	}
+}
+IOMMU_INIT_POST(gart_iommu_hole_init);
diff -druN linux-2.6.39-libre/arch/x86/kernel/amd_iommu.c linux-3.0-rc7-libre/arch/x86/kernel/amd_iommu.c
--- linux-2.6.39-libre/arch/x86/kernel/amd_iommu.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/kernel/amd_iommu.c	2011-07-11 19:51:52.000000000 -0400
@@ -18,6 +18,7 @@
  */
 
 #include <linux/pci.h>
+#include <linux/pci-ats.h>
 #include <linux/bitmap.h>
 #include <linux/slab.h>
 #include <linux/debugfs.h>
@@ -25,16 +26,18 @@
 #include <linux/dma-mapping.h>
 #include <linux/iommu-helper.h>
 #include <linux/iommu.h>
+#include <linux/delay.h>
 #include <asm/proto.h>
 #include <asm/iommu.h>
 #include <asm/gart.h>
+#include <asm/dma.h>
 #include <asm/amd_iommu_proto.h>
 #include <asm/amd_iommu_types.h>
 #include <asm/amd_iommu.h>
 
 #define CMD_SET_TYPE(cmd, t) ((cmd)->data[1] |= ((t) << 28))
 
-#define EXIT_LOOP_COUNT 10000000
+#define LOOP_TIMEOUT	100000
 
 static DEFINE_RWLOCK(amd_iommu_devtable_lock);
 
@@ -57,7 +60,6 @@
 	u32 data[4];
 };
 
-static void reset_iommu_command_buffer(struct amd_iommu *iommu);
 static void update_domain(struct protection_domain *domain);
 
 /****************************************************************************
@@ -153,6 +155,10 @@
 	pdev = pci_get_bus_and_slot(PCI_BUS(alias), alias & 0xff);
 	if (pdev)
 		dev_data->alias = &pdev->dev;
+	else {
+		kfree(dev_data);
+		return -ENOTSUPP;
+	}
 
 	atomic_set(&dev_data->bind, 0);
 
@@ -162,6 +168,20 @@
 	return 0;
 }
 
+static void iommu_ignore_device(struct device *dev)
+{
+	u16 devid, alias;
+
+	devid = get_device_id(dev);
+	alias = amd_iommu_alias_table[devid];
+
+	memset(&amd_iommu_dev_table[devid], 0, sizeof(struct dev_table_entry));
+	memset(&amd_iommu_dev_table[alias], 0, sizeof(struct dev_table_entry));
+
+	amd_iommu_rlookup_table[devid] = NULL;
+	amd_iommu_rlookup_table[alias] = NULL;
+}
+
 static void iommu_uninit_device(struct device *dev)
 {
 	kfree(dev->archdata.iommu);
@@ -191,7 +211,9 @@
 			continue;
 
 		ret = iommu_init_device(&pdev->dev);
-		if (ret)
+		if (ret == -ENOTSUPP)
+			iommu_ignore_device(&pdev->dev);
+		else if (ret)
 			goto out_free;
 	}
 
@@ -322,8 +344,6 @@
 		break;
 	case EVENT_TYPE_ILL_CMD:
 		printk("ILLEGAL_COMMAND_ERROR address=0x%016llx]\n", address);
-		iommu->reset_in_progress = true;
-		reset_iommu_command_buffer(iommu);
 		dump_command(address);
 		break;
 	case EVENT_TYPE_CMD_HARD_ERR:
@@ -367,7 +387,7 @@
 	spin_unlock_irqrestore(&iommu->lock, flags);
 }
 
-irqreturn_t amd_iommu_int_handler(int irq, void *data)
+irqreturn_t amd_iommu_int_thread(int irq, void *data)
 {
 	struct amd_iommu *iommu;
 
@@ -377,192 +397,300 @@
 	return IRQ_HANDLED;
 }
 
+irqreturn_t amd_iommu_int_handler(int irq, void *data)
+{
+	return IRQ_WAKE_THREAD;
+}
+
 /****************************************************************************
  *
  * IOMMU command queuing functions
  *
  ****************************************************************************/
 
-/*
- * Writes the command to the IOMMUs command buffer and informs the
- * hardware about the new command. Must be called with iommu->lock held.
- */
-static int __iommu_queue_command(struct amd_iommu *iommu, struct iommu_cmd *cmd)
+static int wait_on_sem(volatile u64 *sem)
+{
+	int i = 0;
+
+	while (*sem == 0 && i < LOOP_TIMEOUT) {
+		udelay(1);
+		i += 1;
+	}
+
+	if (i == LOOP_TIMEOUT) {
+		pr_alert("AMD-Vi: Completion-Wait loop timed out\n");
+		return -EIO;
+	}
+
+	return 0;
+}
+
+static void copy_cmd_to_buffer(struct amd_iommu *iommu,
+			       struct iommu_cmd *cmd,
+			       u32 tail)
 {
-	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));
-	tail = (tail + sizeof(*cmd)) % iommu->cmd_buf_size;
-	head = readl(iommu->mmio_base + MMIO_CMD_HEAD_OFFSET);
-	if (tail == head)
-		return -ENOMEM;
+	tail   = (tail + sizeof(*cmd)) % iommu->cmd_buf_size;
+
+	/* Copy command to buffer */
+	memcpy(target, cmd, sizeof(*cmd));
+
+	/* Tell the IOMMU about it */
 	writel(tail, iommu->mmio_base + MMIO_CMD_TAIL_OFFSET);
+}
 
-	return 0;
+static void build_completion_wait(struct iommu_cmd *cmd, u64 address)
+{
+	WARN_ON(address & 0x7ULL);
+
+	memset(cmd, 0, sizeof(*cmd));
+	cmd->data[0] = lower_32_bits(__pa(address)) | CMD_COMPL_WAIT_STORE_MASK;
+	cmd->data[1] = upper_32_bits(__pa(address));
+	cmd->data[2] = 1;
+	CMD_SET_TYPE(cmd, CMD_COMPL_WAIT);
+}
+
+static void build_inv_dte(struct iommu_cmd *cmd, u16 devid)
+{
+	memset(cmd, 0, sizeof(*cmd));
+	cmd->data[0] = devid;
+	CMD_SET_TYPE(cmd, CMD_INV_DEV_ENTRY);
+}
+
+static void build_inv_iommu_pages(struct iommu_cmd *cmd, u64 address,
+				  size_t size, u16 domid, int pde)
+{
+	u64 pages;
+	int s;
+
+	pages = iommu_num_pages(address, size, PAGE_SIZE);
+	s     = 0;
+
+	if (pages > 1) {
+		/*
+		 * If we have to flush more than one page, flush all
+		 * TLB entries for this domain
+		 */
+		address = CMD_INV_IOMMU_ALL_PAGES_ADDRESS;
+		s = 1;
+	}
+
+	address &= PAGE_MASK;
+
+	memset(cmd, 0, sizeof(*cmd));
+	cmd->data[1] |= domid;
+	cmd->data[2]  = lower_32_bits(address);
+	cmd->data[3]  = upper_32_bits(address);
+	CMD_SET_TYPE(cmd, CMD_INV_IOMMU_PAGES);
+	if (s) /* size bit - we flush more than one 4kb page */
+		cmd->data[2] |= CMD_INV_IOMMU_PAGES_SIZE_MASK;
+	if (pde) /* PDE bit - we wan't flush everything not only the PTEs */
+		cmd->data[2] |= CMD_INV_IOMMU_PAGES_PDE_MASK;
+}
+
+static void build_inv_iotlb_pages(struct iommu_cmd *cmd, u16 devid, int qdep,
+				  u64 address, size_t size)
+{
+	u64 pages;
+	int s;
+
+	pages = iommu_num_pages(address, size, PAGE_SIZE);
+	s     = 0;
+
+	if (pages > 1) {
+		/*
+		 * If we have to flush more than one page, flush all
+		 * TLB entries for this domain
+		 */
+		address = CMD_INV_IOMMU_ALL_PAGES_ADDRESS;
+		s = 1;
+	}
+
+	address &= PAGE_MASK;
+
+	memset(cmd, 0, sizeof(*cmd));
+	cmd->data[0]  = devid;
+	cmd->data[0] |= (qdep & 0xff) << 24;
+	cmd->data[1]  = devid;
+	cmd->data[2]  = lower_32_bits(address);
+	cmd->data[3]  = upper_32_bits(address);
+	CMD_SET_TYPE(cmd, CMD_INV_IOTLB_PAGES);
+	if (s)
+		cmd->data[2] |= CMD_INV_IOMMU_PAGES_SIZE_MASK;
+}
+
+static void build_inv_all(struct iommu_cmd *cmd)
+{
+	memset(cmd, 0, sizeof(*cmd));
+	CMD_SET_TYPE(cmd, CMD_INV_ALL);
 }
 
 /*
- * General queuing function for commands. Takes iommu->lock and calls
- * __iommu_queue_command().
+ * Writes the command to the IOMMUs command buffer and informs the
+ * hardware about the new command.
  */
 static int iommu_queue_command(struct amd_iommu *iommu, struct iommu_cmd *cmd)
 {
+	u32 left, tail, head, next_tail;
 	unsigned long flags;
-	int ret;
 
+	WARN_ON(iommu->cmd_buf_size & CMD_BUFFER_UNINITIALIZED);
+
+again:
 	spin_lock_irqsave(&iommu->lock, flags);
-	ret = __iommu_queue_command(iommu, cmd);
-	if (!ret)
-		iommu->need_sync = true;
-	spin_unlock_irqrestore(&iommu->lock, flags);
 
-	return ret;
-}
+	head      = readl(iommu->mmio_base + MMIO_CMD_HEAD_OFFSET);
+	tail      = readl(iommu->mmio_base + MMIO_CMD_TAIL_OFFSET);
+	next_tail = (tail + sizeof(*cmd)) % iommu->cmd_buf_size;
+	left      = (head - next_tail) % iommu->cmd_buf_size;
 
-/*
- * This function waits until an IOMMU has completed a completion
- * wait command
- */
-static void __iommu_wait_for_completion(struct amd_iommu *iommu)
-{
-	int ready = 0;
-	unsigned status = 0;
-	unsigned long i = 0;
+	if (left <= 2) {
+		struct iommu_cmd sync_cmd;
+		volatile u64 sem = 0;
+		int ret;
 
-	INC_STATS_COUNTER(compl_wait);
+		build_completion_wait(&sync_cmd, (u64)&sem);
+		copy_cmd_to_buffer(iommu, &sync_cmd, tail);
 
-	while (!ready && (i < EXIT_LOOP_COUNT)) {
-		++i;
-		/* wait for the bit to become one */
-		status = readl(iommu->mmio_base + MMIO_STATUS_OFFSET);
-		ready = status & MMIO_STATUS_COM_WAIT_INT_MASK;
+		spin_unlock_irqrestore(&iommu->lock, flags);
+
+		if ((ret = wait_on_sem(&sem)) != 0)
+			return ret;
+
+		goto again;
 	}
 
-	/* set bit back to zero */
-	status &= ~MMIO_STATUS_COM_WAIT_INT_MASK;
-	writel(status, iommu->mmio_base + MMIO_STATUS_OFFSET);
+	copy_cmd_to_buffer(iommu, cmd, tail);
 
-	if (unlikely(i == EXIT_LOOP_COUNT))
-		iommu->reset_in_progress = true;
+	/* We need to sync now to make sure all commands are processed */
+	iommu->need_sync = true;
+
+	spin_unlock_irqrestore(&iommu->lock, flags);
+
+	return 0;
 }
 
 /*
  * This function queues a completion wait command into the command
  * buffer of an IOMMU
  */
-static int __iommu_completion_wait(struct amd_iommu *iommu)
+static int iommu_completion_wait(struct amd_iommu *iommu)
 {
 	struct iommu_cmd cmd;
+	volatile u64 sem = 0;
+	int ret;
 
-	 memset(&cmd, 0, sizeof(cmd));
-	 cmd.data[0] = CMD_COMPL_WAIT_INT_MASK;
-	 CMD_SET_TYPE(&cmd, CMD_COMPL_WAIT);
+	if (!iommu->need_sync)
+		return 0;
 
-	 return __iommu_queue_command(iommu, &cmd);
+	build_completion_wait(&cmd, (u64)&sem);
+
+	ret = iommu_queue_command(iommu, &cmd);
+	if (ret)
+		return ret;
+
+	return wait_on_sem(&sem);
 }
 
-/*
- * This function is called whenever we need to ensure that the IOMMU has
- * completed execution of all commands we sent. It sends a
- * COMPLETION_WAIT command and waits for it to finish. The IOMMU informs
- * us about that by writing a value to a physical address we pass with
- * the command.
- */
-static int iommu_completion_wait(struct amd_iommu *iommu)
+static int iommu_flush_dte(struct amd_iommu *iommu, u16 devid)
 {
-	int ret = 0;
-	unsigned long flags;
-
-	spin_lock_irqsave(&iommu->lock, flags);
+	struct iommu_cmd cmd;
 
-	if (!iommu->need_sync)
-		goto out;
+	build_inv_dte(&cmd, devid);
 
-	ret = __iommu_completion_wait(iommu);
+	return iommu_queue_command(iommu, &cmd);
+}
 
-	iommu->need_sync = false;
+static void iommu_flush_dte_all(struct amd_iommu *iommu)
+{
+	u32 devid;
 
-	if (ret)
-		goto out;
+	for (devid = 0; devid <= 0xffff; ++devid)
+		iommu_flush_dte(iommu, devid);
 
-	__iommu_wait_for_completion(iommu);
+	iommu_completion_wait(iommu);
+}
 
-out:
-	spin_unlock_irqrestore(&iommu->lock, flags);
+/*
+ * This function uses heavy locking and may disable irqs for some time. But
+ * this is no issue because it is only called during resume.
+ */
+static void iommu_flush_tlb_all(struct amd_iommu *iommu)
+{
+	u32 dom_id;
 
-	if (iommu->reset_in_progress)
-		reset_iommu_command_buffer(iommu);
+	for (dom_id = 0; dom_id <= 0xffff; ++dom_id) {
+		struct iommu_cmd cmd;
+		build_inv_iommu_pages(&cmd, 0, CMD_INV_IOMMU_ALL_PAGES_ADDRESS,
+				      dom_id, 1);
+		iommu_queue_command(iommu, &cmd);
+	}
 
-	return 0;
+	iommu_completion_wait(iommu);
 }
 
-static void iommu_flush_complete(struct protection_domain *domain)
+static void iommu_flush_all(struct amd_iommu *iommu)
 {
-	int i;
+	struct iommu_cmd cmd;
 
-	for (i = 0; i < amd_iommus_present; ++i) {
-		if (!domain->dev_iommu[i])
-			continue;
+	build_inv_all(&cmd);
 
-		/*
-		 * Devices of this domain are behind this IOMMU
-		 * We need to wait for completion of all commands.
-		 */
-		iommu_completion_wait(amd_iommus[i]);
+	iommu_queue_command(iommu, &cmd);
+	iommu_completion_wait(iommu);
+}
+
+void iommu_flush_all_caches(struct amd_iommu *iommu)
+{
+	if (iommu_feature(iommu, FEATURE_IA)) {
+		iommu_flush_all(iommu);
+	} else {
+		iommu_flush_dte_all(iommu);
+		iommu_flush_tlb_all(iommu);
 	}
 }
 
 /*
- * Command send function for invalidating a device table entry
+ * Command send function for flushing on-device TLB
  */
-static int iommu_flush_device(struct device *dev)
+static int device_flush_iotlb(struct device *dev, u64 address, size_t size)
 {
+	struct pci_dev *pdev = to_pci_dev(dev);
 	struct amd_iommu *iommu;
 	struct iommu_cmd cmd;
 	u16 devid;
+	int qdep;
 
+	qdep  = pci_ats_queue_depth(pdev);
 	devid = get_device_id(dev);
 	iommu = amd_iommu_rlookup_table[devid];
 
-	/* Build command */
-	memset(&cmd, 0, sizeof(cmd));
-	CMD_SET_TYPE(&cmd, CMD_INV_DEV_ENTRY);
-	cmd.data[0] = devid;
+	build_inv_iotlb_pages(&cmd, devid, qdep, address, size);
 
 	return iommu_queue_command(iommu, &cmd);
 }
 
-static void __iommu_build_inv_iommu_pages(struct iommu_cmd *cmd, u64 address,
-					  u16 domid, int pde, int s)
-{
-	memset(cmd, 0, sizeof(*cmd));
-	address &= PAGE_MASK;
-	CMD_SET_TYPE(cmd, CMD_INV_IOMMU_PAGES);
-	cmd->data[1] |= domid;
-	cmd->data[2] = lower_32_bits(address);
-	cmd->data[3] = upper_32_bits(address);
-	if (s) /* size bit - we flush more than one 4kb page */
-		cmd->data[2] |= CMD_INV_IOMMU_PAGES_SIZE_MASK;
-	if (pde) /* PDE bit - we wan't flush everything not only the PTEs */
-		cmd->data[2] |= CMD_INV_IOMMU_PAGES_PDE_MASK;
-}
-
 /*
- * Generic command send function for invalidaing TLB entries
+ * Command send function for invalidating a device table entry
  */
-static int iommu_queue_inv_iommu_pages(struct amd_iommu *iommu,
-		u64 address, u16 domid, int pde, int s)
+static int device_flush_dte(struct device *dev)
 {
-	struct iommu_cmd cmd;
+	struct amd_iommu *iommu;
+	struct pci_dev *pdev;
+	u16 devid;
 	int ret;
 
-	__iommu_build_inv_iommu_pages(&cmd, address, domid, pde, s);
+	pdev  = to_pci_dev(dev);
+	devid = get_device_id(dev);
+	iommu = amd_iommu_rlookup_table[devid];
 
-	ret = iommu_queue_command(iommu, &cmd);
+	ret = iommu_flush_dte(iommu, devid);
+	if (ret)
+		return ret;
+
+	if (pci_ats_enabled(pdev))
+		ret = device_flush_iotlb(dev, 0, ~0UL);
 
 	return ret;
 }
@@ -572,23 +700,14 @@
  * It invalidates a single PTE if the range to flush is within a single
  * page. Otherwise it flushes the whole TLB of the IOMMU.
  */
-static void __iommu_flush_pages(struct protection_domain *domain,
-				u64 address, size_t size, int pde)
+static void __domain_flush_pages(struct protection_domain *domain,
+				 u64 address, size_t size, int pde)
 {
-	int s = 0, i;
-	unsigned long pages = iommu_num_pages(address, size, PAGE_SIZE);
-
-	address &= PAGE_MASK;
-
-	if (pages > 1) {
-		/*
-		 * If we have to flush more than one page, flush all
-		 * TLB entries for this domain
-		 */
-		address = CMD_INV_IOMMU_ALL_PAGES_ADDRESS;
-		s = 1;
-	}
+	struct iommu_dev_data *dev_data;
+	struct iommu_cmd cmd;
+	int ret = 0, i;
 
+	build_inv_iommu_pages(&cmd, address, size, domain->id, pde);
 
 	for (i = 0; i < amd_iommus_present; ++i) {
 		if (!domain->dev_iommu[i])
@@ -598,101 +717,70 @@
 		 * Devices of this domain are behind this IOMMU
 		 * We need a TLB flush
 		 */
-		iommu_queue_inv_iommu_pages(amd_iommus[i], address,
-					    domain->id, pde, s);
+		ret |= iommu_queue_command(amd_iommus[i], &cmd);
 	}
 
-	return;
+	list_for_each_entry(dev_data, &domain->dev_list, list) {
+		struct pci_dev *pdev = to_pci_dev(dev_data->dev);
+
+		if (!pci_ats_enabled(pdev))
+			continue;
+
+		ret |= device_flush_iotlb(dev_data->dev, address, size);
+	}
+
+	WARN_ON(ret);
 }
 
-static void iommu_flush_pages(struct protection_domain *domain,
-			     u64 address, size_t size)
+static void domain_flush_pages(struct protection_domain *domain,
+			       u64 address, size_t size)
 {
-	__iommu_flush_pages(domain, address, size, 0);
+	__domain_flush_pages(domain, address, size, 0);
 }
 
 /* Flush the whole IO/TLB for a given protection domain */
-static void iommu_flush_tlb(struct protection_domain *domain)
+static void domain_flush_tlb(struct protection_domain *domain)
 {
-	__iommu_flush_pages(domain, 0, CMD_INV_IOMMU_ALL_PAGES_ADDRESS, 0);
+	__domain_flush_pages(domain, 0, CMD_INV_IOMMU_ALL_PAGES_ADDRESS, 0);
 }
 
 /* Flush the whole IO/TLB for a given protection domain - including PDE */
-static void iommu_flush_tlb_pde(struct protection_domain *domain)
-{
-	__iommu_flush_pages(domain, 0, CMD_INV_IOMMU_ALL_PAGES_ADDRESS, 1);
-}
-
-
-/*
- * This function flushes the DTEs for all devices in domain
- */
-static void iommu_flush_domain_devices(struct protection_domain *domain)
+static void domain_flush_tlb_pde(struct protection_domain *domain)
 {
-	struct iommu_dev_data *dev_data;
-	unsigned long flags;
-
-	spin_lock_irqsave(&domain->lock, flags);
-
-	list_for_each_entry(dev_data, &domain->dev_list, list)
-		iommu_flush_device(dev_data->dev);
-
-	spin_unlock_irqrestore(&domain->lock, flags);
+	__domain_flush_pages(domain, 0, CMD_INV_IOMMU_ALL_PAGES_ADDRESS, 1);
 }
 
-static void iommu_flush_all_domain_devices(void)
+static void domain_flush_complete(struct protection_domain *domain)
 {
-	struct protection_domain *domain;
-	unsigned long flags;
+	int i;
 
-	spin_lock_irqsave(&amd_iommu_pd_lock, flags);
+	for (i = 0; i < amd_iommus_present; ++i) {
+		if (!domain->dev_iommu[i])
+			continue;
 
-	list_for_each_entry(domain, &amd_iommu_pd_list, list) {
-		iommu_flush_domain_devices(domain);
-		iommu_flush_complete(domain);
+		/*
+		 * Devices of this domain are behind this IOMMU
+		 * We need to wait for completion of all commands.
+		 */
+		iommu_completion_wait(amd_iommus[i]);
 	}
-
-	spin_unlock_irqrestore(&amd_iommu_pd_lock, flags);
 }
 
-void amd_iommu_flush_all_devices(void)
-{
-	iommu_flush_all_domain_devices();
-}
 
 /*
- * This function uses heavy locking and may disable irqs for some time. But
- * this is no issue because it is only called during resume.
+ * This function flushes the DTEs for all devices in domain
  */
-void amd_iommu_flush_all_domains(void)
+static void domain_flush_devices(struct protection_domain *domain)
 {
-	struct protection_domain *domain;
+	struct iommu_dev_data *dev_data;
 	unsigned long flags;
 
-	spin_lock_irqsave(&amd_iommu_pd_lock, flags);
-
-	list_for_each_entry(domain, &amd_iommu_pd_list, list) {
-		spin_lock(&domain->lock);
-		iommu_flush_tlb_pde(domain);
-		iommu_flush_complete(domain);
-		spin_unlock(&domain->lock);
-	}
-
-	spin_unlock_irqrestore(&amd_iommu_pd_lock, flags);
-}
-
-static void reset_iommu_command_buffer(struct amd_iommu *iommu)
-{
-	pr_err("AMD-Vi: Resetting IOMMU command buffer\n");
-
-	if (iommu->reset_in_progress)
-		panic("AMD-Vi: ILLEGAL_COMMAND_ERROR while resetting command buffer\n");
+	spin_lock_irqsave(&domain->lock, flags);
 
-	amd_iommu_reset_cmd_buffer(iommu);
-	amd_iommu_flush_all_devices();
-	amd_iommu_flush_all_domains();
+	list_for_each_entry(dev_data, &domain->dev_list, list)
+		device_flush_dte(dev_data->dev);
 
-	iommu->reset_in_progress = false;
+	spin_unlock_irqrestore(&domain->lock, flags);
 }
 
 /****************************************************************************
@@ -1410,17 +1498,22 @@
 	return domain->flags & PD_DMA_OPS_MASK;
 }
 
-static void set_dte_entry(u16 devid, struct protection_domain *domain)
+static void set_dte_entry(u16 devid, struct protection_domain *domain, bool ats)
 {
 	u64 pte_root = virt_to_phys(domain->pt_root);
+	u32 flags = 0;
 
 	pte_root |= (domain->mode & DEV_ENTRY_MODE_MASK)
 		    << DEV_ENTRY_MODE_SHIFT;
 	pte_root |= IOMMU_PTE_IR | IOMMU_PTE_IW | IOMMU_PTE_P | IOMMU_PTE_TV;
 
-	amd_iommu_dev_table[devid].data[2] = domain->id;
-	amd_iommu_dev_table[devid].data[1] = upper_32_bits(pte_root);
-	amd_iommu_dev_table[devid].data[0] = lower_32_bits(pte_root);
+	if (ats)
+		flags |= DTE_FLAG_IOTLB;
+
+	amd_iommu_dev_table[devid].data[3] |= flags;
+	amd_iommu_dev_table[devid].data[2]  = domain->id;
+	amd_iommu_dev_table[devid].data[1]  = upper_32_bits(pte_root);
+	amd_iommu_dev_table[devid].data[0]  = lower_32_bits(pte_root);
 }
 
 static void clear_dte_entry(u16 devid)
@@ -1437,23 +1530,29 @@
 {
 	struct iommu_dev_data *dev_data;
 	struct amd_iommu *iommu;
+	struct pci_dev *pdev;
+	bool ats = false;
 	u16 devid;
 
 	devid    = get_device_id(dev);
 	iommu    = amd_iommu_rlookup_table[devid];
 	dev_data = get_dev_data(dev);
+	pdev     = to_pci_dev(dev);
+
+	if (amd_iommu_iotlb_sup)
+		ats = pci_ats_enabled(pdev);
 
 	/* Update data structures */
 	dev_data->domain = domain;
 	list_add(&dev_data->list, &domain->dev_list);
-	set_dte_entry(devid, domain);
+	set_dte_entry(devid, domain, ats);
 
 	/* Do reference counting */
 	domain->dev_iommu[iommu->index] += 1;
 	domain->dev_cnt                 += 1;
 
 	/* Flush the DTE entry */
-	iommu_flush_device(dev);
+	device_flush_dte(dev);
 }
 
 static void do_detach(struct device *dev)
@@ -1476,7 +1575,7 @@
 	clear_dte_entry(devid);
 
 	/* Flush the DTE entry */
-	iommu_flush_device(dev);
+	device_flush_dte(dev);
 }
 
 /*
@@ -1539,9 +1638,13 @@
 static int attach_device(struct device *dev,
 			 struct protection_domain *domain)
 {
+	struct pci_dev *pdev = to_pci_dev(dev);
 	unsigned long flags;
 	int ret;
 
+	if (amd_iommu_iotlb_sup)
+		pci_enable_ats(pdev, PAGE_SHIFT);
+
 	write_lock_irqsave(&amd_iommu_devtable_lock, flags);
 	ret = __attach_device(dev, domain);
 	write_unlock_irqrestore(&amd_iommu_devtable_lock, flags);
@@ -1551,7 +1654,7 @@
 	 * left the caches in the IOMMU dirty. So we have to flush
 	 * here to evict all dirty stuff.
 	 */
-	iommu_flush_tlb_pde(domain);
+	domain_flush_tlb_pde(domain);
 
 	return ret;
 }
@@ -1598,12 +1701,16 @@
  */
 static void detach_device(struct device *dev)
 {
+	struct pci_dev *pdev = to_pci_dev(dev);
 	unsigned long flags;
 
 	/* lock device table */
 	write_lock_irqsave(&amd_iommu_devtable_lock, flags);
 	__detach_device(dev);
 	write_unlock_irqrestore(&amd_iommu_devtable_lock, flags);
+
+	if (amd_iommu_iotlb_sup && pci_ats_enabled(pdev))
+		pci_disable_ats(pdev);
 }
 
 /*
@@ -1615,10 +1722,9 @@
 	struct protection_domain *dom;
 	struct iommu_dev_data *dev_data, *alias_data;
 	unsigned long flags;
-	u16 devid, alias;
+	u16 devid;
 
 	devid      = get_device_id(dev);
-	alias      = amd_iommu_alias_table[devid];
 	dev_data   = get_dev_data(dev);
 	alias_data = get_dev_data(dev_data->alias);
 	if (!alias_data)
@@ -1692,7 +1798,7 @@
 		goto out;
 	}
 
-	iommu_flush_device(dev);
+	device_flush_dte(dev);
 	iommu_completion_wait(iommu);
 
 out:
@@ -1753,8 +1859,9 @@
 	struct iommu_dev_data *dev_data;
 
 	list_for_each_entry(dev_data, &domain->dev_list, list) {
+		struct pci_dev *pdev = to_pci_dev(dev_data->dev);
 		u16 devid = get_device_id(dev_data->dev);
-		set_dte_entry(devid, domain);
+		set_dte_entry(devid, domain, pci_ats_enabled(pdev));
 	}
 }
 
@@ -1764,8 +1871,9 @@
 		return;
 
 	update_device_table(domain);
-	iommu_flush_domain_devices(domain);
-	iommu_flush_tlb_pde(domain);
+
+	domain_flush_devices(domain);
+	domain_flush_tlb_pde(domain);
 
 	domain->updated = false;
 }
@@ -1924,10 +2032,10 @@
 	ADD_STATS_COUNTER(alloced_io_mem, size);
 
 	if (unlikely(dma_dom->need_flush && !amd_iommu_unmap_flush)) {
-		iommu_flush_tlb(&dma_dom->domain);
+		domain_flush_tlb(&dma_dom->domain);
 		dma_dom->need_flush = false;
 	} else if (unlikely(amd_iommu_np_cache))
-		iommu_flush_pages(&dma_dom->domain, address, size);
+		domain_flush_pages(&dma_dom->domain, address, size);
 
 out:
 	return address;
@@ -1976,7 +2084,7 @@
 	dma_ops_free_addresses(dma_dom, dma_addr, pages);
 
 	if (amd_iommu_unmap_flush || dma_dom->need_flush) {
-		iommu_flush_pages(&dma_dom->domain, flush_addr, size);
+		domain_flush_pages(&dma_dom->domain, flush_addr, size);
 		dma_dom->need_flush = false;
 	}
 }
@@ -2012,7 +2120,7 @@
 	if (addr == DMA_ERROR_CODE)
 		goto out;
 
-	iommu_flush_complete(domain);
+	domain_flush_complete(domain);
 
 out:
 	spin_unlock_irqrestore(&domain->lock, flags);
@@ -2039,7 +2147,7 @@
 
 	__unmap_single(domain->priv, dma_addr, size, dir);
 
-	iommu_flush_complete(domain);
+	domain_flush_complete(domain);
 
 	spin_unlock_irqrestore(&domain->lock, flags);
 }
@@ -2104,7 +2212,7 @@
 			goto unmap;
 	}
 
-	iommu_flush_complete(domain);
+	domain_flush_complete(domain);
 
 out:
 	spin_unlock_irqrestore(&domain->lock, flags);
@@ -2150,7 +2258,7 @@
 		s->dma_address = s->dma_length = 0;
 	}
 
-	iommu_flush_complete(domain);
+	domain_flush_complete(domain);
 
 	spin_unlock_irqrestore(&domain->lock, flags);
 }
@@ -2200,7 +2308,7 @@
 		goto out_free;
 	}
 
-	iommu_flush_complete(domain);
+	domain_flush_complete(domain);
 
 	spin_unlock_irqrestore(&domain->lock, flags);
 
@@ -2232,7 +2340,7 @@
 
 	__unmap_single(domain->priv, dma_addr, size, DMA_BIDIRECTIONAL);
 
-	iommu_flush_complete(domain);
+	domain_flush_complete(domain);
 
 	spin_unlock_irqrestore(&domain->lock, flags);
 
@@ -2296,6 +2404,23 @@
 	.dma_supported = amd_iommu_dma_supported,
 };
 
+static unsigned device_dma_ops_init(void)
+{
+	struct pci_dev *pdev = NULL;
+	unsigned unhandled = 0;
+
+	for_each_pci_dev(pdev) {
+		if (!check_device(&pdev->dev)) {
+			unhandled += 1;
+			continue;
+		}
+
+		pdev->dev.archdata.dma_ops = &amd_iommu_dma_ops;
+	}
+
+	return unhandled;
+}
+
 /*
  * The function which clues the AMD IOMMU driver into dma_ops.
  */
@@ -2308,7 +2433,7 @@
 int __init amd_iommu_init_dma_ops(void)
 {
 	struct amd_iommu *iommu;
-	int ret;
+	int ret, unhandled;
 
 	/*
 	 * first allocate a default protection domain for every IOMMU we
@@ -2334,7 +2459,11 @@
 	swiotlb = 0;
 
 	/* Make the driver finally visible to the drivers */
-	dma_ops = &amd_iommu_dma_ops;
+	unhandled = device_dma_ops_init();
+	if (unhandled && max_pfn > MAX_DMA32_PFN) {
+		/* There are unhandled devices - initialize swiotlb for them */
+		swiotlb = 1;
+	}
 
 	amd_iommu_stats_init();
 
@@ -2476,7 +2605,7 @@
 	if (!iommu)
 		return;
 
-	iommu_flush_device(dev);
+	device_flush_dte(dev);
 	iommu_completion_wait(iommu);
 }
 
@@ -2542,7 +2671,7 @@
 	unmap_size = iommu_unmap_page(domain, iova, page_size);
 	mutex_unlock(&domain->api_lock);
 
-	iommu_flush_tlb_pde(domain);
+	domain_flush_tlb_pde(domain);
 
 	return get_order(unmap_size);
 }
diff -druN linux-2.6.39-libre/arch/x86/kernel/amd_iommu_init.c linux-3.0-rc7-libre/arch/x86/kernel/amd_iommu_init.c
--- linux-2.6.39-libre/arch/x86/kernel/amd_iommu_init.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/kernel/amd_iommu_init.c	2011-07-11 19:51:52.000000000 -0400
@@ -137,6 +137,7 @@
 
 /* IOMMUs have a non-present cache? */
 bool amd_iommu_np_cache __read_mostly;
+bool amd_iommu_iotlb_sup __read_mostly = true;
 
 /*
  * The ACPI table parsing functions set this variable on an error
@@ -180,6 +181,12 @@
 static u32 alias_table_size;	/* size of the alias table */
 static u32 rlookup_table_size;	/* size if the rlookup table */
 
+/*
+ * This function flushes all internal caches of
+ * the IOMMU used by this driver.
+ */
+extern void iommu_flush_all_caches(struct amd_iommu *iommu);
+
 static inline void update_last_devid(u16 devid)
 {
 	if (devid > amd_iommu_last_bdf)
@@ -293,9 +300,23 @@
 /* Function to enable the hardware */
 static void iommu_enable(struct amd_iommu *iommu)
 {
-	printk(KERN_INFO "AMD-Vi: Enabling IOMMU at %s cap 0x%hx\n",
+	static const char * const feat_str[] = {
+		"PreF", "PPR", "X2APIC", "NX", "GT", "[5]",
+		"IA", "GA", "HE", "PC", NULL
+	};
+	int i;
+
+	printk(KERN_INFO "AMD-Vi: Enabling IOMMU at %s cap 0x%hx",
 	       dev_name(&iommu->dev->dev), iommu->cap_ptr);
 
+	if (iommu->cap & (1 << IOMMU_CAP_EFR)) {
+		printk(KERN_CONT " extended features: ");
+		for (i = 0; feat_str[i]; ++i)
+			if (iommu_feature(iommu, (1ULL << i)))
+				printk(KERN_CONT " %s", feat_str[i]);
+	}
+	printk(KERN_CONT "\n");
+
 	iommu_feature_enable(iommu, CONTROL_IOMMU_EN);
 }
 
@@ -651,7 +672,7 @@
 static void __init init_iommu_from_pci(struct amd_iommu *iommu)
 {
 	int cap_ptr = iommu->cap_ptr;
-	u32 range, misc;
+	u32 range, misc, low, high;
 	int i, j;
 
 	pci_read_config_dword(iommu->dev, cap_ptr + MMIO_CAP_HDR_OFFSET,
@@ -667,6 +688,15 @@
 					MMIO_GET_LD(range));
 	iommu->evt_msi_num = MMIO_MSI_NUM(misc);
 
+	if (!(iommu->cap & (1 << IOMMU_CAP_IOTLB)))
+		amd_iommu_iotlb_sup = false;
+
+	/* read extended feature bits */
+	low  = readl(iommu->mmio_base + MMIO_EXT_FEATURES);
+	high = readl(iommu->mmio_base + MMIO_EXT_FEATURES + 4);
+
+	iommu->features = ((u64)high << 32) | low;
+
 	if (!is_rd890_iommu(iommu->dev))
 		return;
 
@@ -701,8 +731,8 @@
 {
 	u8 *p = (u8 *)h;
 	u8 *end = p, flags = 0;
-	u16 dev_i, devid = 0, devid_start = 0, devid_to = 0;
-	u32 ext_flags = 0;
+	u16 devid = 0, devid_start = 0, devid_to = 0;
+	u32 dev_i, ext_flags = 0;
 	bool alias = false;
 	struct ivhd_entry *e;
 
@@ -857,7 +887,7 @@
 /* Initializes the device->iommu mapping for the driver */
 static int __init init_iommu_devices(struct amd_iommu *iommu)
 {
-	u16 i;
+	u32 i;
 
 	for (i = iommu->first_device; i <= iommu->last_device; ++i)
 		set_iommu_for_device(iommu, i);
@@ -1004,10 +1034,11 @@
 	if (pci_enable_msi(iommu->dev))
 		return 1;
 
-	r = request_irq(iommu->dev->irq, amd_iommu_int_handler,
-			IRQF_SAMPLE_RANDOM,
-			"AMD-Vi",
-			NULL);
+	r = request_threaded_irq(iommu->dev->irq,
+				 amd_iommu_int_handler,
+				 amd_iommu_int_thread,
+				 0, "AMD-Vi",
+				 iommu->dev);
 
 	if (r) {
 		pci_disable_msi(iommu->dev);
@@ -1146,7 +1177,7 @@
  */
 static void init_device_table(void)
 {
-	u16 devid;
+	u32 devid;
 
 	for (devid = 0; devid <= amd_iommu_last_bdf; ++devid) {
 		set_dev_entry_bit(devid, DEV_ENTRY_VALID);
@@ -1244,6 +1275,7 @@
 		iommu_set_exclusion_range(iommu);
 		iommu_init_msi(iommu);
 		iommu_enable(iommu);
+		iommu_flush_all_caches(iommu);
 	}
 }
 
@@ -1274,8 +1306,8 @@
 	 * we have to flush after the IOMMUs are enabled because a
 	 * disabled IOMMU will never execute the commands we send
 	 */
-	amd_iommu_flush_all_devices();
-	amd_iommu_flush_all_domains();
+	for_each_iommu(iommu)
+		iommu_flush_all_caches(iommu);
 }
 
 static int amd_iommu_suspend(void)
diff -druN linux-2.6.39-libre/arch/x86/kernel/apb_timer.c linux-3.0-rc7-libre/arch/x86/kernel/apb_timer.c
--- linux-2.6.39-libre/arch/x86/kernel/apb_timer.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/kernel/apb_timer.c	2011-07-11 19:51:52.000000000 -0400
@@ -177,7 +177,6 @@
 	.rating		= APBT_CLOCKSOURCE_RATING,
 	.read		= apbt_read_clocksource,
 	.mask		= APBT_MASK,
-	.shift		= APBT_SHIFT,
 	.flags		= CLOCK_SOURCE_IS_CONTINUOUS,
 	.resume		= apbt_restart_clocksource,
 };
@@ -543,14 +542,7 @@
 	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);
+	clocksource_register_khz(&clocksource_apbt, (u32)apbt_freq*1000);
 
 	return 0;
 }
diff -druN linux-2.6.39-libre/arch/x86/kernel/aperture_64.c linux-3.0-rc7-libre/arch/x86/kernel/aperture_64.c
--- linux-2.6.39-libre/arch/x86/kernel/aperture_64.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/kernel/aperture_64.c	2011-07-11 19:51:52.000000000 -0400
@@ -30,6 +30,22 @@
 #include <asm/amd_nb.h>
 #include <asm/x86_init.h>
 
+/*
+ * Using 512M as goal, in case kexec will load kernel_big
+ * that will do the on-position decompress, and could overlap with
+ * with the gart aperture that is used.
+ * Sequence:
+ * kernel_small
+ * ==> kexec (with kdump trigger path or gart still enabled)
+ * ==> kernel_small (gart area become e820_reserved)
+ * ==> kexec (with kdump trigger path or gart still enabled)
+ * ==> kerne_big (uncompressed size will be big than 64M or 128M)
+ * So don't use 512M below as gart iommu, leave the space for kernel
+ * code for safe.
+ */
+#define GART_MIN_ADDR	(512ULL << 20)
+#define GART_MAX_ADDR	(1ULL   << 32)
+
 int gart_iommu_aperture;
 int gart_iommu_aperture_disabled __initdata;
 int gart_iommu_aperture_allowed __initdata;
@@ -70,21 +86,9 @@
 	 * memory. Unfortunately we cannot move it up because that would
 	 * make the IOMMU useless.
 	 */
-	/*
-	 * using 512M as goal, in case kexec will load kernel_big
-	 * that will do the on position decompress, and  could overlap with
-	 * that position with gart that is used.
-	 * sequende:
-	 * kernel_small
-	 * ==> kexec (with kdump trigger path or previous doesn't shutdown gart)
-	 * ==> kernel_small(gart area become e820_reserved)
-	 * ==> kexec (with kdump trigger path or previous doesn't shutdown gart)
-	 * ==> kerne_big (uncompressed size will be big than 64M or 128M)
-	 * so don't use 512M below as gart iommu, leave the space for kernel
-	 * code for safe
-	 */
-	addr = memblock_find_in_range(0, 1ULL<<32, aper_size, 512ULL<<20);
-	if (addr == MEMBLOCK_ERROR || addr + aper_size > 0xffffffff) {
+	addr = memblock_find_in_range(GART_MIN_ADDR, GART_MAX_ADDR,
+				      aper_size, aper_size);
+	if (addr == MEMBLOCK_ERROR || addr + aper_size > GART_MAX_ADDR) {
 		printk(KERN_ERR
 			"Cannot allocate aperture memory hole (%lx,%uK)\n",
 				addr, aper_size>>10);
diff -druN linux-2.6.39-libre/arch/x86/kernel/apic/apic.c linux-3.0-rc7-libre/arch/x86/kernel/apic/apic.c
--- linux-2.6.39-libre/arch/x86/kernel/apic/apic.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/kernel/apic/apic.c	2011-07-11 19:51:52.000000000 -0400
@@ -390,7 +390,8 @@
 
 /*
  * If mask=1, the LVT entry does not generate interrupts while mask=0
- * enables the vector. See also the BKDGs.
+ * enables the vector. See also the BKDGs. Must be called with
+ * preemption disabled.
  */
 
 int setup_APIC_eilvt(u8 offset, u8 vector, u8 msg_type, u8 mask)
@@ -505,7 +506,7 @@
 {
 	struct clock_event_device *levt = &__get_cpu_var(lapic_events);
 
-	if (cpu_has(__this_cpu_ptr(&cpu_info), X86_FEATURE_ARAT)) {
+	if (this_cpu_has(X86_FEATURE_ARAT)) {
 		lapic_clockevent.features &= ~CLOCK_EVT_FEAT_C3STOP;
 		/* Make LAPIC timer preferrable over percpu HPET */
 		lapic_clockevent.rating = 150;
@@ -1237,6 +1238,17 @@
 	/* always use the value from LDR */
 	early_per_cpu(x86_cpu_to_logical_apicid, cpu) =
 		logical_smp_processor_id();
+
+	/*
+	 * Some NUMA implementations (NUMAQ) don't initialize apicid to
+	 * node mapping during NUMA init.  Now that logical apicid is
+	 * guaranteed to be known, give it another chance.  This is already
+	 * a bit too late - percpu allocation has already happened without
+	 * proper NUMA affinity.
+	 */
+	if (apic->x86_32_numa_cpu_node)
+		set_apicid_to_node(early_per_cpu(x86_cpu_to_apicid, cpu),
+				   apic->x86_32_numa_cpu_node(cpu));
 #endif
 
 	/*
@@ -1450,7 +1462,6 @@
 void __init enable_IR_x2apic(void)
 {
 	unsigned long flags;
-	struct IO_APIC_route_entry **ioapic_entries;
 	int ret, x2apic_enabled = 0;
 	int dmar_table_init_ret;
 
@@ -1458,13 +1469,7 @@
 	if (dmar_table_init_ret && !x2apic_supported())
 		return;
 
-	ioapic_entries = alloc_ioapic_entries();
-	if (!ioapic_entries) {
-		pr_err("Allocate ioapic_entries failed\n");
-		goto out;
-	}
-
-	ret = save_IO_APIC_setup(ioapic_entries);
+	ret = save_ioapic_entries();
 	if (ret) {
 		pr_info("Saving IO-APIC state failed: %d\n", ret);
 		goto out;
@@ -1472,7 +1477,7 @@
 
 	local_irq_save(flags);
 	legacy_pic->mask_all();
-	mask_IO_APIC_setup(ioapic_entries);
+	mask_ioapic_entries();
 
 	if (dmar_table_init_ret)
 		ret = 0;
@@ -1503,14 +1508,11 @@
 
 nox2apic:
 	if (!ret) /* IR enabling failed */
-		restore_IO_APIC_setup(ioapic_entries);
+		restore_ioapic_entries();
 	legacy_pic->restore_mask();
 	local_irq_restore(flags);
 
 out:
-	if (ioapic_entries)
-		free_ioapic_entries(ioapic_entries);
-
 	if (x2apic_enabled)
 		return;
 
@@ -1812,30 +1814,41 @@
  */
 void smp_error_interrupt(struct pt_regs *regs)
 {
-	u32 v, v1;
+	u32 v0, v1;
+	u32 i = 0;
+	static const char * const error_interrupt_reason[] = {
+		"Send CS error",		/* APIC Error Bit 0 */
+		"Receive CS error",		/* APIC Error Bit 1 */
+		"Send accept error",		/* APIC Error Bit 2 */
+		"Receive accept error",		/* APIC Error Bit 3 */
+		"Redirectable IPI",		/* APIC Error Bit 4 */
+		"Send illegal vector",		/* APIC Error Bit 5 */
+		"Received illegal vector",	/* APIC Error Bit 6 */
+		"Illegal register address",	/* APIC Error Bit 7 */
+	};
 
 	exit_idle();
 	irq_enter();
 	/* First tickle the hardware, only then report what went on. -- REW */
-	v = apic_read(APIC_ESR);
+	v0 = apic_read(APIC_ESR);
 	apic_write(APIC_ESR, 0);
 	v1 = apic_read(APIC_ESR);
 	ack_APIC_irq();
 	atomic_inc(&irq_err_count);
 
-	/*
-	 * Here is what the APIC error bits mean:
-	 * 0: Send CS error
-	 * 1: Receive CS error
-	 * 2: Send accept error
-	 * 3: Receive accept error
-	 * 4: Reserved
-	 * 5: Send illegal vector
-	 * 6: Received illegal vector
-	 * 7: Illegal register address
-	 */
-	pr_debug("APIC error on CPU%d: %02x(%02x)\n",
-		smp_processor_id(), v , v1);
+	apic_printk(APIC_DEBUG, KERN_DEBUG "APIC error on CPU%d: %02x(%02x)",
+		    smp_processor_id(), v0 , v1);
+
+	v1 = v1 & 0xff;
+	while (v1) {
+		if (v1 & 0x1)
+			apic_printk(APIC_DEBUG, KERN_CONT " : %s", error_interrupt_reason[i]);
+		i++;
+		v1 >>= 1;
+	};
+
+	apic_printk(APIC_DEBUG, KERN_CONT "\n");
+
 	irq_exit();
 }
 
@@ -2003,21 +2016,6 @@
 	apic_write(APIC_LDR, val);
 }
 
-#ifdef CONFIG_X86_32
-int default_x86_32_numa_cpu_node(int cpu)
-{
-#ifdef CONFIG_NUMA
-	int apicid = early_per_cpu(x86_cpu_to_apicid, cpu);
-
-	if (apicid != BAD_APICID)
-		return __apicid_to_node[apicid];
-	return NUMA_NO_NODE;
-#else
-	return 0;
-#endif
-}
-#endif
-
 /*
  * Power management
  */
@@ -2088,28 +2086,20 @@
 {
 	unsigned int l, h;
 	unsigned long flags;
-	int maxlvt, ret;
-	struct IO_APIC_route_entry **ioapic_entries = NULL;
+	int maxlvt;
 
 	if (!apic_pm_state.active)
 		return;
 
 	local_irq_save(flags);
 	if (intr_remapping_enabled) {
-		ioapic_entries = alloc_ioapic_entries();
-		if (!ioapic_entries) {
-			WARN(1, "Alloc ioapic_entries in lapic resume failed.");
-			goto restore;
-		}
-
-		ret = save_IO_APIC_setup(ioapic_entries);
-		if (ret) {
-			WARN(1, "Saving IO-APIC state failed: %d\n", ret);
-			free_ioapic_entries(ioapic_entries);
-			goto restore;
-		}
-
-		mask_IO_APIC_setup(ioapic_entries);
+		/*
+		 * IO-APIC and PIC have their own resume routines.
+		 * We just mask them here to make sure the interrupt
+		 * subsystem is completely quiet while we enable x2apic
+		 * and interrupt-remapping.
+		 */
+		mask_ioapic_entries();
 		legacy_pic->mask_all();
 	}
 
@@ -2152,13 +2142,9 @@
 	apic_write(APIC_ESR, 0);
 	apic_read(APIC_ESR);
 
-	if (intr_remapping_enabled) {
+	if (intr_remapping_enabled)
 		reenable_intr_remapping(x2apic_mode);
-		legacy_pic->restore_mask();
-		restore_IO_APIC_setup(ioapic_entries);
-		free_ioapic_entries(ioapic_entries);
-	}
-restore:
+
 	local_irq_restore(flags);
 }
 
diff -druN linux-2.6.39-libre/arch/x86/kernel/apic/apic_flat_64.c linux-3.0-rc7-libre/arch/x86/kernel/apic/apic_flat_64.c
--- linux-2.6.39-libre/arch/x86/kernel/apic/apic_flat_64.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/kernel/apic/apic_flat_64.c	2011-07-11 19:51:52.000000000 -0400
@@ -16,6 +16,7 @@
 #include <linux/ctype.h>
 #include <linux/init.h>
 #include <linux/hardirq.h>
+#include <linux/module.h>
 #include <asm/smp.h>
 #include <asm/apic.h>
 #include <asm/ipi.h>
@@ -24,6 +25,12 @@
 #include <acpi/acpi_bus.h>
 #endif
 
+static struct apic apic_physflat;
+static struct apic apic_flat;
+
+struct apic __read_mostly *apic = &apic_flat;
+EXPORT_SYMBOL_GPL(apic);
+
 static int flat_acpi_madt_oem_check(char *oem_id, char *oem_table_id)
 {
 	return 1;
@@ -164,7 +171,7 @@
 	return initial_apic_id >> index_msb;
 }
 
-struct apic apic_flat =  {
+static struct apic apic_flat =  {
 	.name				= "flat",
 	.probe				= NULL,
 	.acpi_madt_oem_check		= flat_acpi_madt_oem_check,
@@ -312,10 +319,18 @@
 	return per_cpu(x86_cpu_to_apicid, cpu);
 }
 
-struct apic apic_physflat =  {
+static int physflat_probe(void)
+{
+	if (apic == &apic_physflat || num_possible_cpus() > 8)
+		return 1;
+
+	return 0;
+}
+
+static struct apic apic_physflat =  {
 
 	.name				= "physical flat",
-	.probe				= NULL,
+	.probe				= physflat_probe,
 	.acpi_madt_oem_check		= physflat_acpi_madt_oem_check,
 	.apic_id_registered		= flat_apic_id_registered,
 
@@ -369,3 +384,8 @@
 	.wait_icr_idle			= native_apic_wait_icr_idle,
 	.safe_wait_icr_idle		= native_safe_apic_wait_icr_idle,
 };
+
+/*
+ * We need to check for physflat first, so this order is important.
+ */
+apic_drivers(apic_physflat, apic_flat);
diff -druN linux-2.6.39-libre/arch/x86/kernel/apic/apic_noop.c linux-3.0-rc7-libre/arch/x86/kernel/apic/apic_noop.c
--- linux-2.6.39-libre/arch/x86/kernel/apic/apic_noop.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/kernel/apic/apic_noop.c	2011-07-11 19:51:52.000000000 -0400
@@ -119,14 +119,6 @@
 	WARN_ON_ONCE(cpu_has_apic && !disable_apic);
 }
 
-#ifdef CONFIG_X86_32
-static int noop_x86_32_numa_cpu_node(int cpu)
-{
-	/* we're always on node 0 */
-	return 0;
-}
-#endif
-
 struct apic apic_noop = {
 	.name				= "noop",
 	.probe				= noop_probe,
@@ -195,6 +187,5 @@
 
 #ifdef CONFIG_X86_32
 	.x86_32_early_logical_apicid	= noop_x86_32_early_logical_apicid,
-	.x86_32_numa_cpu_node		= noop_x86_32_numa_cpu_node,
 #endif
 };
diff -druN linux-2.6.39-libre/arch/x86/kernel/apic/bigsmp_32.c linux-3.0-rc7-libre/arch/x86/kernel/apic/bigsmp_32.c
--- linux-2.6.39-libre/arch/x86/kernel/apic/bigsmp_32.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/kernel/apic/bigsmp_32.c	2011-07-11 19:51:52.000000000 -0400
@@ -193,7 +193,7 @@
 	return dmi_bigsmp;
 }
 
-struct apic apic_bigsmp = {
+static struct apic apic_bigsmp = {
 
 	.name				= "bigsmp",
 	.probe				= probe_bigsmp,
@@ -253,5 +253,14 @@
 	.safe_wait_icr_idle		= native_safe_apic_wait_icr_idle,
 
 	.x86_32_early_logical_apicid	= bigsmp_early_logical_apicid,
-	.x86_32_numa_cpu_node		= default_x86_32_numa_cpu_node,
 };
+
+struct apic * __init generic_bigsmp_probe(void)
+{
+	if (probe_bigsmp())
+		return &apic_bigsmp;
+
+	return NULL;
+}
+
+apic_driver(apic_bigsmp);
diff -druN linux-2.6.39-libre/arch/x86/kernel/apic/es7000_32.c linux-3.0-rc7-libre/arch/x86/kernel/apic/es7000_32.c
--- linux-2.6.39-libre/arch/x86/kernel/apic/es7000_32.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/kernel/apic/es7000_32.c	2011-07-11 19:51:52.000000000 -0400
@@ -510,11 +510,6 @@
 		nr_ioapics, cpumask_bits(es7000_target_cpus())[0]);
 }
 
-static int es7000_numa_cpu_node(int cpu)
-{
-	return 0;
-}
-
 static int es7000_cpu_present_to_apicid(int mps_cpu)
 {
 	if (!mps_cpu)
@@ -625,7 +620,7 @@
 }
 
 /* We've been warned by a false positive warning.Use __refdata to keep calm. */
-struct apic __refdata apic_es7000_cluster = {
+static struct apic __refdata apic_es7000_cluster = {
 
 	.name				= "es7000",
 	.probe				= probe_es7000,
@@ -688,10 +683,9 @@
 	.safe_wait_icr_idle		= native_safe_apic_wait_icr_idle,
 
 	.x86_32_early_logical_apicid	= es7000_early_logical_apicid,
-	.x86_32_numa_cpu_node		= es7000_numa_cpu_node,
 };
 
-struct apic __refdata apic_es7000 = {
+static struct apic __refdata apic_es7000 = {
 
 	.name				= "es7000",
 	.probe				= probe_es7000,
@@ -752,5 +746,10 @@
 	.safe_wait_icr_idle		= native_safe_apic_wait_icr_idle,
 
 	.x86_32_early_logical_apicid	= es7000_early_logical_apicid,
-	.x86_32_numa_cpu_node		= es7000_numa_cpu_node,
 };
+
+/*
+ * Need to check for es7000 followed by es7000_cluster, so this order
+ * in apic_drivers is important.
+ */
+apic_drivers(apic_es7000, apic_es7000_cluster);
diff -druN linux-2.6.39-libre/arch/x86/kernel/apic/hw_nmi.c linux-3.0-rc7-libre/arch/x86/kernel/apic/hw_nmi.c
--- linux-2.6.39-libre/arch/x86/kernel/apic/hw_nmi.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/kernel/apic/hw_nmi.c	2011-07-11 19:51:52.000000000 -0400
@@ -19,9 +19,9 @@
 #include <linux/delay.h>
 
 #ifdef CONFIG_HARDLOCKUP_DETECTOR
-u64 hw_nmi_get_sample_period(void)
+u64 hw_nmi_get_sample_period(int watchdog_thresh)
 {
-	return (u64)(cpu_khz) * 1000 * 60;
+	return (u64)(cpu_khz) * 1000 * watchdog_thresh;
 }
 #endif
 
diff -druN linux-2.6.39-libre/arch/x86/kernel/apic/io_apic.c linux-3.0-rc7-libre/arch/x86/kernel/apic/io_apic.c
--- linux-2.6.39-libre/arch/x86/kernel/apic/io_apic.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/kernel/apic/io_apic.c	2011-07-11 19:51:52.000000000 -0400
@@ -76,17 +76,40 @@
 static DEFINE_RAW_SPINLOCK(ioapic_lock);
 static DEFINE_RAW_SPINLOCK(vector_lock);
 
-/*
- * # of IRQ routing registers
- */
-int nr_ioapic_registers[MAX_IO_APICS];
+static struct ioapic {
+	/*
+	 * # of IRQ routing registers
+	 */
+	int nr_registers;
+	/*
+	 * Saved state during suspend/resume, or while enabling intr-remap.
+	 */
+	struct IO_APIC_route_entry *saved_registers;
+	/* I/O APIC config */
+	struct mpc_ioapic mp_config;
+	/* IO APIC gsi routing info */
+	struct mp_ioapic_gsi  gsi_config;
+	DECLARE_BITMAP(pin_programmed, MP_MAX_IOAPIC_PIN + 1);
+} ioapics[MAX_IO_APICS];
 
-/* I/O APIC entries */
-struct mpc_ioapic mp_ioapics[MAX_IO_APICS];
-int nr_ioapics;
+#define mpc_ioapic_ver(id)		ioapics[id].mp_config.apicver
 
-/* IO APIC gsi routing info */
-struct mp_ioapic_gsi  mp_gsi_routing[MAX_IO_APICS];
+int mpc_ioapic_id(int id)
+{
+	return ioapics[id].mp_config.apicid;
+}
+
+unsigned int mpc_ioapic_addr(int id)
+{
+	return ioapics[id].mp_config.apicaddr;
+}
+
+struct mp_ioapic_gsi *mp_ioapic_gsi_routing(int id)
+{
+	return &ioapics[id].gsi_config;
+}
+
+int nr_ioapics;
 
 /* The one past the highest gsi number used */
 u32 gsi_top;
@@ -179,6 +202,14 @@
 		io_apic_irqs = ~0UL;
 	}
 
+	for (i = 0; i < nr_ioapics; i++) {
+		ioapics[i].saved_registers =
+			kzalloc(sizeof(struct IO_APIC_route_entry) *
+				ioapics[i].nr_registers, GFP_KERNEL);
+		if (!ioapics[i].saved_registers)
+			pr_err("IOAPIC %d: suspend/resume impossible!\n", i);
+	}
+
 	cfg = irq_cfgx;
 	count = ARRAY_SIZE(irq_cfgx);
 	node = cpu_to_node(0);
@@ -297,7 +328,7 @@
 static __attribute_const__ struct io_apic __iomem *io_apic_base(int idx)
 {
 	return (void __iomem *) __fix_to_virt(FIX_IO_APIC_BASE_0 + idx)
-		+ (mp_ioapics[idx].apicaddr & ~PAGE_MASK);
+		+ (mpc_ioapic_addr(idx) & ~PAGE_MASK);
 }
 
 static inline void io_apic_eoi(unsigned int apic, unsigned int vector)
@@ -573,7 +604,7 @@
 	int apic, pin;
 
 	for (apic = 0; apic < nr_ioapics; apic++)
-		for (pin = 0; pin < nr_ioapic_registers[apic]; pin++)
+		for (pin = 0; pin < ioapics[apic].nr_registers; pin++)
 			clear_IO_APIC_pin(apic, pin);
 }
 
@@ -615,74 +646,43 @@
 __setup("pirq=", ioapic_pirq_setup);
 #endif /* CONFIG_X86_32 */
 
-struct IO_APIC_route_entry **alloc_ioapic_entries(void)
-{
-	int apic;
-	struct IO_APIC_route_entry **ioapic_entries;
-
-	ioapic_entries = kzalloc(sizeof(*ioapic_entries) * nr_ioapics,
-				GFP_KERNEL);
-	if (!ioapic_entries)
-		return 0;
-
-	for (apic = 0; apic < nr_ioapics; apic++) {
-		ioapic_entries[apic] =
-			kzalloc(sizeof(struct IO_APIC_route_entry) *
-				nr_ioapic_registers[apic], GFP_KERNEL);
-		if (!ioapic_entries[apic])
-			goto nomem;
-	}
-
-	return ioapic_entries;
-
-nomem:
-	while (--apic >= 0)
-		kfree(ioapic_entries[apic]);
-	kfree(ioapic_entries);
-
-	return 0;
-}
-
 /*
  * Saves all the IO-APIC RTE's
  */
-int save_IO_APIC_setup(struct IO_APIC_route_entry **ioapic_entries)
+int save_ioapic_entries(void)
 {
 	int apic, pin;
-
-	if (!ioapic_entries)
-		return -ENOMEM;
+	int err = 0;
 
 	for (apic = 0; apic < nr_ioapics; apic++) {
-		if (!ioapic_entries[apic])
-			return -ENOMEM;
+		if (!ioapics[apic].saved_registers) {
+			err = -ENOMEM;
+			continue;
+		}
 
-		for (pin = 0; pin < nr_ioapic_registers[apic]; pin++)
-			ioapic_entries[apic][pin] =
+		for (pin = 0; pin < ioapics[apic].nr_registers; pin++)
+			ioapics[apic].saved_registers[pin] =
 				ioapic_read_entry(apic, pin);
 	}
 
-	return 0;
+	return err;
 }
 
 /*
  * Mask all IO APIC entries.
  */
-void mask_IO_APIC_setup(struct IO_APIC_route_entry **ioapic_entries)
+void mask_ioapic_entries(void)
 {
 	int apic, pin;
 
-	if (!ioapic_entries)
-		return;
-
 	for (apic = 0; apic < nr_ioapics; apic++) {
-		if (!ioapic_entries[apic])
-			break;
+		if (!ioapics[apic].saved_registers)
+			continue;
 
-		for (pin = 0; pin < nr_ioapic_registers[apic]; pin++) {
+		for (pin = 0; pin < ioapics[apic].nr_registers; pin++) {
 			struct IO_APIC_route_entry entry;
 
-			entry = ioapic_entries[apic][pin];
+			entry = ioapics[apic].saved_registers[pin];
 			if (!entry.mask) {
 				entry.mask = 1;
 				ioapic_write_entry(apic, pin, entry);
@@ -692,36 +692,23 @@
 }
 
 /*
- * Restore IO APIC entries which was saved in ioapic_entries.
+ * Restore IO APIC entries which was saved in the ioapic structure.
  */
-int restore_IO_APIC_setup(struct IO_APIC_route_entry **ioapic_entries)
+int restore_ioapic_entries(void)
 {
 	int apic, pin;
 
-	if (!ioapic_entries)
-		return -ENOMEM;
-
 	for (apic = 0; apic < nr_ioapics; apic++) {
-		if (!ioapic_entries[apic])
-			return -ENOMEM;
+		if (!ioapics[apic].saved_registers)
+			continue;
 
-		for (pin = 0; pin < nr_ioapic_registers[apic]; pin++)
+		for (pin = 0; pin < ioapics[apic].nr_registers; pin++)
 			ioapic_write_entry(apic, pin,
-					ioapic_entries[apic][pin]);
+					   ioapics[apic].saved_registers[pin]);
 	}
 	return 0;
 }
 
-void free_ioapic_entries(struct IO_APIC_route_entry **ioapic_entries)
-{
-	int apic;
-
-	for (apic = 0; apic < nr_ioapics; apic++)
-		kfree(ioapic_entries[apic]);
-
-	kfree(ioapic_entries);
-}
-
 /*
  * Find the IRQ entry number of a certain pin.
  */
@@ -731,7 +718,7 @@
 
 	for (i = 0; i < mp_irq_entries; i++)
 		if (mp_irqs[i].irqtype == type &&
-		    (mp_irqs[i].dstapic == mp_ioapics[apic].apicid ||
+		    (mp_irqs[i].dstapic == mpc_ioapic_id(apic) ||
 		     mp_irqs[i].dstapic == MP_APIC_ALL) &&
 		    mp_irqs[i].dstirq == pin)
 			return i;
@@ -773,7 +760,7 @@
 	if (i < mp_irq_entries) {
 		int apic;
 		for(apic = 0; apic < nr_ioapics; apic++) {
-			if (mp_ioapics[apic].apicid == mp_irqs[i].dstapic)
+			if (mpc_ioapic_id(apic) == mp_irqs[i].dstapic)
 				return apic;
 		}
 	}
@@ -942,6 +929,7 @@
 {
 	int irq;
 	int bus = mp_irqs[idx].srcbus;
+	struct mp_ioapic_gsi *gsi_cfg = mp_ioapic_gsi_routing(apic);
 
 	/*
 	 * Debugging check, we are in big trouble if this message pops up!
@@ -952,7 +940,7 @@
 	if (test_bit(bus, mp_bus_not_pci)) {
 		irq = mp_irqs[idx].srcbusirq;
 	} else {
-		u32 gsi = mp_gsi_routing[apic].gsi_base + pin;
+		u32 gsi = gsi_cfg->gsi_base + pin;
 
 		if (gsi >= NR_IRQS_LEGACY)
 			irq = gsi;
@@ -1003,7 +991,7 @@
 		int lbus = mp_irqs[i].srcbus;
 
 		for (apic = 0; apic < nr_ioapics; apic++)
-			if (mp_ioapics[apic].apicid == mp_irqs[i].dstapic ||
+			if (mpc_ioapic_id(apic) == mp_irqs[i].dstapic ||
 			    mp_irqs[i].dstapic == MP_APIC_ALL)
 				break;
 
@@ -1222,7 +1210,7 @@
 	int apic, idx, pin;
 
 	for (apic = 0; apic < nr_ioapics; apic++) {
-		for (pin = 0; pin < nr_ioapic_registers[apic]; pin++) {
+		for (pin = 0; pin < ioapics[apic].nr_registers; pin++) {
 			idx = find_irq_entry(apic, pin, mp_INT);
 			if ((idx != -1) && (irq == pin_2_irq(idx, apic, pin)))
 				return irq_trigger(idx);
@@ -1350,14 +1338,14 @@
 	apic_printk(APIC_VERBOSE,KERN_DEBUG
 		    "IOAPIC[%d]: Set routing entry (%d-%d -> 0x%x -> "
 		    "IRQ %d Mode:%i Active:%i)\n",
-		    apic_id, mp_ioapics[apic_id].apicid, pin, cfg->vector,
+		    apic_id, mpc_ioapic_id(apic_id), pin, cfg->vector,
 		    irq, trigger, polarity);
 
 
-	if (setup_ioapic_entry(mp_ioapics[apic_id].apicid, irq, &entry,
+	if (setup_ioapic_entry(mpc_ioapic_id(apic_id), irq, &entry,
 			       dest, trigger, polarity, cfg->vector, pin)) {
 		printk("Failed to setup ioapic entry for ioapic  %d, pin %d\n",
-		       mp_ioapics[apic_id].apicid, pin);
+		       mpc_ioapic_id(apic_id), pin);
 		__clear_irq_vector(irq, cfg);
 		return;
 	}
@@ -1369,17 +1357,13 @@
 	ioapic_write_entry(apic_id, pin, entry);
 }
 
-static struct {
-	DECLARE_BITMAP(pin_programmed, MP_MAX_IOAPIC_PIN + 1);
-} mp_ioapic_routing[MAX_IO_APICS];
-
 static bool __init io_apic_pin_not_connected(int idx, int apic_id, int pin)
 {
 	if (idx != -1)
 		return false;
 
 	apic_printk(APIC_VERBOSE, KERN_DEBUG " apic %d pin %d not connected\n",
-		    mp_ioapics[apic_id].apicid, pin);
+		    mpc_ioapic_id(apic_id), pin);
 	return true;
 }
 
@@ -1389,7 +1373,7 @@
 	struct io_apic_irq_attr attr;
 	unsigned int pin, irq;
 
-	for (pin = 0; pin < nr_ioapic_registers[apic_id]; pin++) {
+	for (pin = 0; pin < ioapics[apic_id].nr_registers; pin++) {
 		idx = find_irq_entry(apic_id, pin, mp_INT);
 		if (io_apic_pin_not_connected(idx, apic_id, pin))
 			continue;
@@ -1511,7 +1495,7 @@
 	printk(KERN_DEBUG "number of MP IRQ sources: %d.\n", mp_irq_entries);
 	for (i = 0; i < nr_ioapics; i++)
 		printk(KERN_DEBUG "number of IO-APIC #%d registers: %d.\n",
-		       mp_ioapics[i].apicid, nr_ioapic_registers[i]);
+		       mpc_ioapic_id(i), ioapics[i].nr_registers);
 
 	/*
 	 * We are a bit conservative about what we expect.  We have to
@@ -1531,7 +1515,7 @@
 	raw_spin_unlock_irqrestore(&ioapic_lock, flags);
 
 	printk("\n");
-	printk(KERN_DEBUG "IO APIC #%d......\n", mp_ioapics[apic].apicid);
+	printk(KERN_DEBUG "IO APIC #%d......\n", mpc_ioapic_id(apic));
 	printk(KERN_DEBUG ".... register #00: %08X\n", reg_00.raw);
 	printk(KERN_DEBUG ".......    : physical APIC id: %02X\n", reg_00.bits.ID);
 	printk(KERN_DEBUG ".......    : Delivery Type: %X\n", reg_00.bits.delivery_type);
@@ -1825,7 +1809,7 @@
 	for(apic = 0; apic < nr_ioapics; apic++) {
 		int pin;
 		/* See if any of the pins is in ExtINT mode */
-		for (pin = 0; pin < nr_ioapic_registers[apic]; pin++) {
+		for (pin = 0; pin < ioapics[apic].nr_registers; pin++) {
 			struct IO_APIC_route_entry entry;
 			entry = ioapic_read_entry(apic, pin);
 
@@ -1949,14 +1933,14 @@
 		reg_00.raw = io_apic_read(apic_id, 0);
 		raw_spin_unlock_irqrestore(&ioapic_lock, flags);
 
-		old_id = mp_ioapics[apic_id].apicid;
+		old_id = mpc_ioapic_id(apic_id);
 
-		if (mp_ioapics[apic_id].apicid >= get_physical_broadcast()) {
+		if (mpc_ioapic_id(apic_id) >= get_physical_broadcast()) {
 			printk(KERN_ERR "BIOS bug, IO-APIC#%d ID is %d in the MPC table!...\n",
-				apic_id, mp_ioapics[apic_id].apicid);
+				apic_id, mpc_ioapic_id(apic_id));
 			printk(KERN_ERR "... fixing up to %d. (tell your hw vendor)\n",
 				reg_00.bits.ID);
-			mp_ioapics[apic_id].apicid = reg_00.bits.ID;
+			ioapics[apic_id].mp_config.apicid = reg_00.bits.ID;
 		}
 
 		/*
@@ -1965,9 +1949,9 @@
 		 * 'stuck on smp_invalidate_needed IPI wait' messages.
 		 */
 		if (apic->check_apicid_used(&phys_id_present_map,
-					mp_ioapics[apic_id].apicid)) {
+					    mpc_ioapic_id(apic_id))) {
 			printk(KERN_ERR "BIOS bug, IO-APIC#%d ID %d is already used!...\n",
-				apic_id, mp_ioapics[apic_id].apicid);
+				apic_id, mpc_ioapic_id(apic_id));
 			for (i = 0; i < get_physical_broadcast(); i++)
 				if (!physid_isset(i, phys_id_present_map))
 					break;
@@ -1976,13 +1960,14 @@
 			printk(KERN_ERR "... fixing up to %d. (tell your hw vendor)\n",
 				i);
 			physid_set(i, phys_id_present_map);
-			mp_ioapics[apic_id].apicid = i;
+			ioapics[apic_id].mp_config.apicid = i;
 		} else {
 			physid_mask_t tmp;
-			apic->apicid_to_cpu_present(mp_ioapics[apic_id].apicid, &tmp);
+			apic->apicid_to_cpu_present(mpc_ioapic_id(apic_id),
+						    &tmp);
 			apic_printk(APIC_VERBOSE, "Setting %d in the "
 					"phys_id_present_map\n",
-					mp_ioapics[apic_id].apicid);
+					mpc_ioapic_id(apic_id));
 			physids_or(phys_id_present_map, phys_id_present_map, tmp);
 		}
 
@@ -1990,24 +1975,24 @@
 		 * We need to adjust the IRQ routing table
 		 * if the ID changed.
 		 */
-		if (old_id != mp_ioapics[apic_id].apicid)
+		if (old_id != mpc_ioapic_id(apic_id))
 			for (i = 0; i < mp_irq_entries; i++)
 				if (mp_irqs[i].dstapic == old_id)
 					mp_irqs[i].dstapic
-						= mp_ioapics[apic_id].apicid;
+						= mpc_ioapic_id(apic_id);
 
 		/*
 		 * Update the ID register according to the right value
 		 * from the MPC table if they are different.
 		 */
-		if (mp_ioapics[apic_id].apicid == reg_00.bits.ID)
+		if (mpc_ioapic_id(apic_id) == reg_00.bits.ID)
 			continue;
 
 		apic_printk(APIC_VERBOSE, KERN_INFO
 			"...changing IO-APIC physical APIC ID to %d ...",
-			mp_ioapics[apic_id].apicid);
+			mpc_ioapic_id(apic_id));
 
-		reg_00.bits.ID = mp_ioapics[apic_id].apicid;
+		reg_00.bits.ID = mpc_ioapic_id(apic_id);
 		raw_spin_lock_irqsave(&ioapic_lock, flags);
 		io_apic_write(apic_id, 0, reg_00.raw);
 		raw_spin_unlock_irqrestore(&ioapic_lock, flags);
@@ -2018,7 +2003,7 @@
 		raw_spin_lock_irqsave(&ioapic_lock, flags);
 		reg_00.raw = io_apic_read(apic_id, 0);
 		raw_spin_unlock_irqrestore(&ioapic_lock, flags);
-		if (reg_00.bits.ID != mp_ioapics[apic_id].apicid)
+		if (reg_00.bits.ID != mpc_ioapic_id(apic_id))
 			printk("could not set ID!\n");
 		else
 			apic_printk(APIC_VERBOSE, " ok.\n");
@@ -2404,7 +2389,7 @@
 
 	raw_spin_lock_irqsave(&ioapic_lock, flags);
 	for_each_irq_pin(entry, cfg->irq_2_pin) {
-		if (mp_ioapics[entry->apic].apicver >= 0x20) {
+		if (mpc_ioapic_ver(entry->apic) >= 0x20) {
 			/*
 			 * Intr-remapping uses pin number as the virtual vector
 			 * in the RTE. Actual vector is programmed in
@@ -2918,49 +2903,19 @@
 
 late_initcall(io_apic_bug_finalize);
 
-static struct IO_APIC_route_entry *ioapic_saved_data[MAX_IO_APICS];
-
-static void suspend_ioapic(int ioapic_id)
-{
-	struct IO_APIC_route_entry *saved_data = ioapic_saved_data[ioapic_id];
-	int i;
-
-	if (!saved_data)
-		return;
-
-	for (i = 0; i < nr_ioapic_registers[ioapic_id]; i++)
-		saved_data[i] = ioapic_read_entry(ioapic_id, i);
-}
-
-static int ioapic_suspend(void)
-{
-	int ioapic_id;
-
-	for (ioapic_id = 0; ioapic_id < nr_ioapics; ioapic_id++)
-		suspend_ioapic(ioapic_id);
-
-	return 0;
-}
-
-static void resume_ioapic(int ioapic_id)
+static void resume_ioapic_id(int ioapic_id)
 {
-	struct IO_APIC_route_entry *saved_data = ioapic_saved_data[ioapic_id];
 	unsigned long flags;
 	union IO_APIC_reg_00 reg_00;
-	int i;
 
-	if (!saved_data)
-		return;
 
 	raw_spin_lock_irqsave(&ioapic_lock, flags);
 	reg_00.raw = io_apic_read(ioapic_id, 0);
-	if (reg_00.bits.ID != mp_ioapics[ioapic_id].apicid) {
-		reg_00.bits.ID = mp_ioapics[ioapic_id].apicid;
+	if (reg_00.bits.ID != mpc_ioapic_id(ioapic_id)) {
+		reg_00.bits.ID = mpc_ioapic_id(ioapic_id);
 		io_apic_write(ioapic_id, 0, reg_00.raw);
 	}
 	raw_spin_unlock_irqrestore(&ioapic_lock, flags);
-	for (i = 0; i < nr_ioapic_registers[ioapic_id]; i++)
-		ioapic_write_entry(ioapic_id, i, saved_data[i]);
 }
 
 static void ioapic_resume(void)
@@ -2968,28 +2923,18 @@
 	int ioapic_id;
 
 	for (ioapic_id = nr_ioapics - 1; ioapic_id >= 0; ioapic_id--)
-		resume_ioapic(ioapic_id);
+		resume_ioapic_id(ioapic_id);
+
+	restore_ioapic_entries();
 }
 
 static struct syscore_ops ioapic_syscore_ops = {
-	.suspend = ioapic_suspend,
+	.suspend = save_ioapic_entries,
 	.resume = ioapic_resume,
 };
 
 static int __init ioapic_init_ops(void)
 {
-	int i;
-
-	for (i = 0; i < nr_ioapics; i++) {
-		unsigned int size;
-
-		size = nr_ioapic_registers[i]
-			* sizeof(struct IO_APIC_route_entry);
-		ioapic_saved_data[i] = kzalloc(size, GFP_KERNEL);
-		if (!ioapic_saved_data[i])
-			pr_err("IOAPIC %d: suspend/resume impossible!\n", i);
-	}
-
 	register_syscore_ops(&ioapic_syscore_ops);
 
 	return 0;
@@ -3592,14 +3537,14 @@
 	int ret;
 
 	/* Avoid redundant programming */
-	if (test_bit(pin, mp_ioapic_routing[id].pin_programmed)) {
+	if (test_bit(pin, ioapics[id].pin_programmed)) {
 		pr_debug("Pin %d-%d already programmed\n",
-			 mp_ioapics[id].apicid, pin);
+			 mpc_ioapic_id(id), pin);
 		return 0;
 	}
 	ret = io_apic_setup_irq_pin(irq, node, attr);
 	if (!ret)
-		set_bit(pin, mp_ioapic_routing[id].pin_programmed);
+		set_bit(pin, ioapics[id].pin_programmed);
 	return ret;
 }
 
@@ -3764,8 +3709,7 @@
 
 	bitmap_zero(used, 256);
 	for (i = 0; i < nr_ioapics; i++) {
-		struct mpc_ioapic *ia = &mp_ioapics[i];
-		__set_bit(ia->apicid, used);
+		__set_bit(mpc_ioapic_id(i), used);
 	}
 	if (!test_bit(id, used))
 		return id;
@@ -3825,7 +3769,7 @@
 		return;
 
 	for (ioapic = 0; ioapic < nr_ioapics; ioapic++)
-	for (pin = 0; pin < nr_ioapic_registers[ioapic]; pin++) {
+	for (pin = 0; pin < ioapics[ioapic].nr_registers; pin++) {
 		irq_entry = find_irq_entry(ioapic, pin, mp_INT);
 		if (irq_entry == -1)
 			continue;
@@ -3896,7 +3840,7 @@
 	ioapic_res = ioapic_setup_resources(nr_ioapics);
 	for (i = 0; i < nr_ioapics; i++) {
 		if (smp_found_config) {
-			ioapic_phys = mp_ioapics[i].apicaddr;
+			ioapic_phys = mpc_ioapic_addr(i);
 #ifdef CONFIG_X86_32
 			if (!ioapic_phys) {
 				printk(KERN_ERR
@@ -3956,8 +3900,9 @@
 
 	/* Find the IOAPIC that manages this GSI. */
 	for (i = 0; i < nr_ioapics; i++) {
-		if ((gsi >= mp_gsi_routing[i].gsi_base)
-		    && (gsi <= mp_gsi_routing[i].gsi_end))
+		struct mp_ioapic_gsi *gsi_cfg = mp_ioapic_gsi_routing(i);
+		if ((gsi >= gsi_cfg->gsi_base)
+		    && (gsi <= gsi_cfg->gsi_end))
 			return i;
 	}
 
@@ -3967,12 +3912,16 @@
 
 int mp_find_ioapic_pin(int ioapic, u32 gsi)
 {
+	struct mp_ioapic_gsi *gsi_cfg;
+
 	if (WARN_ON(ioapic == -1))
 		return -1;
-	if (WARN_ON(gsi > mp_gsi_routing[ioapic].gsi_end))
+
+	gsi_cfg = mp_ioapic_gsi_routing(ioapic);
+	if (WARN_ON(gsi > gsi_cfg->gsi_end))
 		return -1;
 
-	return gsi - mp_gsi_routing[ioapic].gsi_base;
+	return gsi - gsi_cfg->gsi_base;
 }
 
 static __init int bad_ioapic(unsigned long address)
@@ -3994,40 +3943,42 @@
 {
 	int idx = 0;
 	int entries;
+	struct mp_ioapic_gsi *gsi_cfg;
 
 	if (bad_ioapic(address))
 		return;
 
 	idx = nr_ioapics;
 
-	mp_ioapics[idx].type = MP_IOAPIC;
-	mp_ioapics[idx].flags = MPC_APIC_USABLE;
-	mp_ioapics[idx].apicaddr = address;
+	ioapics[idx].mp_config.type = MP_IOAPIC;
+	ioapics[idx].mp_config.flags = MPC_APIC_USABLE;
+	ioapics[idx].mp_config.apicaddr = address;
 
 	set_fixmap_nocache(FIX_IO_APIC_BASE_0 + idx, address);
-	mp_ioapics[idx].apicid = io_apic_unique_id(id);
-	mp_ioapics[idx].apicver = io_apic_get_version(idx);
+	ioapics[idx].mp_config.apicid = io_apic_unique_id(id);
+	ioapics[idx].mp_config.apicver = io_apic_get_version(idx);
 
 	/*
 	 * Build basic GSI lookup table to facilitate gsi->io_apic lookups
 	 * and to prevent reprogramming of IOAPIC pins (PCI GSIs).
 	 */
 	entries = io_apic_get_redir_entries(idx);
-	mp_gsi_routing[idx].gsi_base = gsi_base;
-	mp_gsi_routing[idx].gsi_end = gsi_base + entries - 1;
+	gsi_cfg = mp_ioapic_gsi_routing(idx);
+	gsi_cfg->gsi_base = gsi_base;
+	gsi_cfg->gsi_end = gsi_base + entries - 1;
 
 	/*
 	 * The number of IO-APIC IRQ registers (== #pins):
 	 */
-	nr_ioapic_registers[idx] = entries;
+	ioapics[idx].nr_registers = entries;
 
-	if (mp_gsi_routing[idx].gsi_end >= gsi_top)
-		gsi_top = mp_gsi_routing[idx].gsi_end + 1;
+	if (gsi_cfg->gsi_end >= gsi_top)
+		gsi_top = gsi_cfg->gsi_end + 1;
 
 	printk(KERN_INFO "IOAPIC[%d]: apic_id %d, version %d, address 0x%x, "
-	       "GSI %d-%d\n", idx, mp_ioapics[idx].apicid,
-	       mp_ioapics[idx].apicver, mp_ioapics[idx].apicaddr,
-	       mp_gsi_routing[idx].gsi_base, mp_gsi_routing[idx].gsi_end);
+	       "GSI %d-%d\n", idx, mpc_ioapic_id(idx),
+	       mpc_ioapic_ver(idx), mpc_ioapic_addr(idx),
+	       gsi_cfg->gsi_base, gsi_cfg->gsi_end);
 
 	nr_ioapics++;
 }
diff -druN linux-2.6.39-libre/arch/x86/kernel/apic/Makefile linux-3.0-rc7-libre/arch/x86/kernel/apic/Makefile
--- linux-2.6.39-libre/arch/x86/kernel/apic/Makefile	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/kernel/apic/Makefile	2011-07-11 19:51:52.000000000 -0400
@@ -2,20 +2,25 @@
 # Makefile for local APIC drivers and for the IO-APIC code
 #
 
-obj-$(CONFIG_X86_LOCAL_APIC)	+= apic.o apic_noop.o probe_$(BITS).o ipi.o
+obj-$(CONFIG_X86_LOCAL_APIC)	+= apic.o apic_noop.o ipi.o
 obj-y				+= hw_nmi.o
 
 obj-$(CONFIG_X86_IO_APIC)	+= io_apic.o
 obj-$(CONFIG_SMP)		+= ipi.o
 
 ifeq ($(CONFIG_X86_64),y)
-obj-y				+= apic_flat_64.o
-obj-$(CONFIG_X86_X2APIC)	+= x2apic_cluster.o
-obj-$(CONFIG_X86_X2APIC)	+= x2apic_phys.o
+# APIC probe will depend on the listing order here
 obj-$(CONFIG_X86_UV)		+= x2apic_uv_x.o
+obj-$(CONFIG_X86_X2APIC)	+= x2apic_phys.o
+obj-$(CONFIG_X86_X2APIC)	+= x2apic_cluster.o
+obj-y				+= apic_flat_64.o
 endif
 
-obj-$(CONFIG_X86_BIGSMP)	+= bigsmp_32.o
+# APIC probe will depend on the listing order here
 obj-$(CONFIG_X86_NUMAQ)		+= numaq_32.o
-obj-$(CONFIG_X86_ES7000)	+= es7000_32.o
 obj-$(CONFIG_X86_SUMMIT)	+= summit_32.o
+obj-$(CONFIG_X86_BIGSMP)	+= bigsmp_32.o
+obj-$(CONFIG_X86_ES7000)	+= es7000_32.o
+
+# For 32bit, probe_32 need to be listed last
+obj-$(CONFIG_X86_LOCAL_APIC)	+= probe_$(BITS).o
diff -druN linux-2.6.39-libre/arch/x86/kernel/apic/numaq_32.c linux-3.0-rc7-libre/arch/x86/kernel/apic/numaq_32.c
--- linux-2.6.39-libre/arch/x86/kernel/apic/numaq_32.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/kernel/apic/numaq_32.c	2011-07-11 19:51:52.000000000 -0400
@@ -48,8 +48,6 @@
 #include <asm/e820.h>
 #include <asm/ipi.h>
 
-#define	MB_TO_PAGES(addr)		((addr) << (20 - PAGE_SHIFT))
-
 int found_numaq;
 
 /*
@@ -79,31 +77,20 @@
 static inline void numaq_register_node(int node, struct sys_cfg_data *scd)
 {
 	struct eachquadmem *eq = scd->eq + node;
+	u64 start = (u64)(eq->hi_shrd_mem_start - eq->priv_mem_size) << 20;
+	u64 end = (u64)(eq->hi_shrd_mem_start + eq->hi_shrd_mem_size) << 20;
+	int ret;
 
-	node_set_online(node);
-
-	/* Convert to pages */
-	node_start_pfn[node] =
-		 MB_TO_PAGES(eq->hi_shrd_mem_start - eq->priv_mem_size);
-
-	node_end_pfn[node] =
-		 MB_TO_PAGES(eq->hi_shrd_mem_start + eq->hi_shrd_mem_size);
-
-	memblock_x86_register_active_regions(node, node_start_pfn[node],
-						node_end_pfn[node]);
-
-	memory_present(node, node_start_pfn[node], node_end_pfn[node]);
-
-	node_remap_size[node] = node_memmap_size_bytes(node,
-					node_start_pfn[node],
-					node_end_pfn[node]);
+	node_set(node, numa_nodes_parsed);
+	ret = numa_add_memblk(node, start, end);
+	BUG_ON(ret < 0);
 }
 
 /*
  * Function: smp_dump_qct()
  *
  * Description: gets memory layout from the quad config table.  This
- * function also updates node_online_map with the nodes (quads) present.
+ * function also updates numa_nodes_parsed with the nodes (quads) present.
  */
 static void __init smp_dump_qct(void)
 {
@@ -112,7 +99,6 @@
 
 	scd = (void *)__va(SYS_CFG_DATA_PRIV_ADDR);
 
-	nodes_clear(node_online_map);
 	for_each_node(node) {
 		if (scd->quads_present31_0 & (1 << node))
 			numaq_register_node(node, scd);
@@ -282,14 +268,14 @@
 	}
 }
 
-int __init get_memcfg_numaq(void)
+int __init numaq_numa_init(void)
 {
 	early_check_numaq();
 	if (!found_numaq)
-		return 0;
+		return -ENOENT;
 	smp_dump_qct();
 
-	return 1;
+	return 0;
 }
 
 #define NUMAQ_APIC_DFR_VALUE	(APIC_DFR_CLUSTER)
@@ -486,8 +472,8 @@
 		(u_long) xquad_portio, (u_long) num_quads*XQUAD_PORTIO_QUAD);
 }
 
-/* Use __refdata to keep false positive warning calm.	*/
-struct apic __refdata apic_numaq = {
+/* Use __refdata to keep false positive warning calm.  */
+static struct apic __refdata apic_numaq = {
 
 	.name				= "NUMAQ",
 	.probe				= probe_numaq,
@@ -551,3 +537,5 @@
 	.x86_32_early_logical_apicid	= noop_x86_32_early_logical_apicid,
 	.x86_32_numa_cpu_node		= numaq_numa_cpu_node,
 };
+
+apic_driver(apic_numaq);
diff -druN linux-2.6.39-libre/arch/x86/kernel/apic/probe_32.c linux-3.0-rc7-libre/arch/x86/kernel/apic/probe_32.c
--- linux-2.6.39-libre/arch/x86/kernel/apic/probe_32.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/kernel/apic/probe_32.c	2011-07-11 19:51:52.000000000 -0400
@@ -52,31 +52,6 @@
 }
 late_initcall(print_ipi_mode);
 
-void __init default_setup_apic_routing(void)
-{
-	int version = apic_version[boot_cpu_physical_apicid];
-
-	if (num_possible_cpus() > 8) {
-		switch (boot_cpu_data.x86_vendor) {
-		case X86_VENDOR_INTEL:
-			if (!APIC_XAPIC(version)) {
-				def_to_bigsmp = 0;
-				break;
-			}
-			/* If P4 and above fall through */
-		case X86_VENDOR_AMD:
-			def_to_bigsmp = 1;
-		}
-	}
-
-#ifdef CONFIG_X86_BIGSMP
-	generic_bigsmp_probe();
-#endif
-
-	if (apic->setup_apic_routing)
-		apic->setup_apic_routing();
-}
-
 static int default_x86_32_early_logical_apicid(int cpu)
 {
 	return 1 << cpu;
@@ -112,7 +87,7 @@
 	return 1;
 }
 
-struct apic apic_default = {
+static struct apic apic_default = {
 
 	.name				= "default",
 	.probe				= probe_default,
@@ -172,47 +147,24 @@
 	.safe_wait_icr_idle		= native_safe_apic_wait_icr_idle,
 
 	.x86_32_early_logical_apicid	= default_x86_32_early_logical_apicid,
-	.x86_32_numa_cpu_node		= default_x86_32_numa_cpu_node,
 };
 
-extern struct apic apic_numaq;
-extern struct apic apic_summit;
-extern struct apic apic_bigsmp;
-extern struct apic apic_es7000;
-extern struct apic apic_es7000_cluster;
+apic_driver(apic_default);
 
 struct apic *apic = &apic_default;
 EXPORT_SYMBOL_GPL(apic);
 
-static struct apic *apic_probe[] __initdata = {
-#ifdef CONFIG_X86_NUMAQ
-	&apic_numaq,
-#endif
-#ifdef CONFIG_X86_SUMMIT
-	&apic_summit,
-#endif
-#ifdef CONFIG_X86_BIGSMP
-	&apic_bigsmp,
-#endif
-#ifdef CONFIG_X86_ES7000
-	&apic_es7000,
-	&apic_es7000_cluster,
-#endif
-	&apic_default,	/* must be last */
-	NULL,
-};
-
 static int cmdline_apic __initdata;
 static int __init parse_apic(char *arg)
 {
-	int i;
+	struct apic **drv;
 
 	if (!arg)
 		return -EINVAL;
 
-	for (i = 0; apic_probe[i]; i++) {
-		if (!strcmp(apic_probe[i]->name, arg)) {
-			apic = apic_probe[i];
+	for (drv = __apicdrivers; drv < __apicdrivers_end; drv++) {
+		if (!strcmp((*drv)->name, arg)) {
+			apic = *drv;
 			cmdline_apic = 1;
 			return 0;
 		}
@@ -223,38 +175,58 @@
 }
 early_param("apic", parse_apic);
 
-void __init generic_bigsmp_probe(void)
+void __init default_setup_apic_routing(void)
 {
+	int version = apic_version[boot_cpu_physical_apicid];
+
+	if (num_possible_cpus() > 8) {
+		switch (boot_cpu_data.x86_vendor) {
+		case X86_VENDOR_INTEL:
+			if (!APIC_XAPIC(version)) {
+				def_to_bigsmp = 0;
+				break;
+			}
+			/* If P4 and above fall through */
+		case X86_VENDOR_AMD:
+			def_to_bigsmp = 1;
+		}
+	}
+
 #ifdef CONFIG_X86_BIGSMP
 	/*
-	 * This routine is used to switch to bigsmp mode when
+	 * This is used to switch to bigsmp mode when
 	 * - There is no apic= option specified by the user
 	 * - generic_apic_probe() has chosen apic_default as the sub_arch
 	 * - we find more than 8 CPUs in acpi LAPIC listing with xAPIC support
 	 */
 
 	if (!cmdline_apic && apic == &apic_default) {
-		if (apic_bigsmp.probe()) {
-			apic = &apic_bigsmp;
+		struct apic *bigsmp = generic_bigsmp_probe();
+		if (bigsmp) {
+			apic = bigsmp;
 			printk(KERN_INFO "Overriding APIC driver with %s\n",
 			       apic->name);
 		}
 	}
 #endif
+
+	if (apic->setup_apic_routing)
+		apic->setup_apic_routing();
 }
 
 void __init generic_apic_probe(void)
 {
 	if (!cmdline_apic) {
-		int i;
-		for (i = 0; apic_probe[i]; i++) {
-			if (apic_probe[i]->probe()) {
-				apic = apic_probe[i];
+		struct apic **drv;
+
+		for (drv = __apicdrivers; drv < __apicdrivers_end; drv++) {
+			if ((*drv)->probe()) {
+				apic = *drv;
 				break;
 			}
 		}
 		/* Not visible without early console */
-		if (!apic_probe[i])
+		if (drv == __apicdrivers_end)
 			panic("Didn't find an APIC driver");
 	}
 	printk(KERN_INFO "Using APIC driver %s\n", apic->name);
@@ -265,16 +237,16 @@
 int __init
 generic_mps_oem_check(struct mpc_table *mpc, char *oem, char *productid)
 {
-	int i;
+	struct apic **drv;
 
-	for (i = 0; apic_probe[i]; ++i) {
-		if (!apic_probe[i]->mps_oem_check)
+	for (drv = __apicdrivers; drv < __apicdrivers_end; drv++) {
+		if (!((*drv)->mps_oem_check))
 			continue;
-		if (!apic_probe[i]->mps_oem_check(mpc, oem, productid))
+		if (!(*drv)->mps_oem_check(mpc, oem, productid))
 			continue;
 
 		if (!cmdline_apic) {
-			apic = apic_probe[i];
+			apic = *drv;
 			printk(KERN_INFO "Switched to APIC driver `%s'.\n",
 			       apic->name);
 		}
@@ -285,16 +257,16 @@
 
 int __init default_acpi_madt_oem_check(char *oem_id, char *oem_table_id)
 {
-	int i;
+	struct apic **drv;
 
-	for (i = 0; apic_probe[i]; ++i) {
-		if (!apic_probe[i]->acpi_madt_oem_check)
+	for (drv = __apicdrivers; drv < __apicdrivers_end; drv++) {
+		if (!(*drv)->acpi_madt_oem_check)
 			continue;
-		if (!apic_probe[i]->acpi_madt_oem_check(oem_id, oem_table_id))
+		if (!(*drv)->acpi_madt_oem_check(oem_id, oem_table_id))
 			continue;
 
 		if (!cmdline_apic) {
-			apic = apic_probe[i];
+			apic = *drv;
 			printk(KERN_INFO "Switched to APIC driver `%s'.\n",
 			       apic->name);
 		}
diff -druN linux-2.6.39-libre/arch/x86/kernel/apic/probe_64.c linux-3.0-rc7-libre/arch/x86/kernel/apic/probe_64.c
--- linux-2.6.39-libre/arch/x86/kernel/apic/probe_64.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/kernel/apic/probe_64.c	2011-07-11 19:51:52.000000000 -0400
@@ -23,27 +23,6 @@
 #include <asm/ipi.h>
 #include <asm/setup.h>
 
-extern struct apic apic_flat;
-extern struct apic apic_physflat;
-extern struct apic apic_x2xpic_uv_x;
-extern struct apic apic_x2apic_phys;
-extern struct apic apic_x2apic_cluster;
-
-struct apic __read_mostly *apic = &apic_flat;
-EXPORT_SYMBOL_GPL(apic);
-
-static struct apic *apic_probe[] __initdata = {
-#ifdef CONFIG_X86_UV
-	&apic_x2apic_uv_x,
-#endif
-#ifdef CONFIG_X86_X2APIC
-	&apic_x2apic_phys,
-	&apic_x2apic_cluster,
-#endif
-	&apic_physflat,
-	NULL,
-};
-
 static int apicid_phys_pkg_id(int initial_apic_id, int index_msb)
 {
 	return hard_smp_processor_id() >> index_msb;
@@ -54,26 +33,20 @@
  */
 void __init default_setup_apic_routing(void)
 {
+	struct apic **drv;
 
 	enable_IR_x2apic();
 
-#ifdef CONFIG_X86_X2APIC
-	if (x2apic_mode
-#ifdef CONFIG_X86_UV
-		       && apic != &apic_x2apic_uv_x
-#endif
-		       ) {
-		if (x2apic_phys)
-			apic = &apic_x2apic_phys;
-		else
-			apic = &apic_x2apic_cluster;
+	for (drv = __apicdrivers; drv < __apicdrivers_end; drv++) {
+		if ((*drv)->probe && (*drv)->probe()) {
+			if (apic != *drv) {
+				apic = *drv;
+				pr_info("Switched APIC routing to %s.\n",
+					apic->name);
+			}
+			break;
+		}
 	}
-#endif
-
-	if (apic == &apic_flat && num_possible_cpus() > 8)
-			apic = &apic_physflat;
-
-	printk(KERN_INFO "Setting APIC routing to %s\n", apic->name);
 
 	if (is_vsmp_box()) {
 		/* need to update phys_pkg_id */
@@ -90,13 +63,15 @@
 
 int __init default_acpi_madt_oem_check(char *oem_id, char *oem_table_id)
 {
-	int i;
+	struct apic **drv;
 
-	for (i = 0; apic_probe[i]; ++i) {
-		if (apic_probe[i]->acpi_madt_oem_check(oem_id, oem_table_id)) {
-			apic = apic_probe[i];
-			printk(KERN_INFO "Setting APIC routing to %s.\n",
-				apic->name);
+	for (drv = __apicdrivers; drv < __apicdrivers_end; drv++) {
+		if ((*drv)->acpi_madt_oem_check(oem_id, oem_table_id)) {
+			if (apic != *drv) {
+				apic = *drv;
+				pr_info("Setting APIC routing to %s.\n",
+					apic->name);
+			}
 			return 1;
 		}
 	}
diff -druN linux-2.6.39-libre/arch/x86/kernel/apic/summit_32.c linux-3.0-rc7-libre/arch/x86/kernel/apic/summit_32.c
--- linux-2.6.39-libre/arch/x86/kernel/apic/summit_32.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/kernel/apic/summit_32.c	2011-07-11 19:51:52.000000000 -0400
@@ -491,7 +491,7 @@
 }
 #endif
 
-struct apic apic_summit = {
+static struct apic apic_summit = {
 
 	.name				= "summit",
 	.probe				= probe_summit,
@@ -551,5 +551,6 @@
 	.safe_wait_icr_idle		= native_safe_apic_wait_icr_idle,
 
 	.x86_32_early_logical_apicid	= summit_early_logical_apicid,
-	.x86_32_numa_cpu_node		= default_x86_32_numa_cpu_node,
 };
+
+apic_driver(apic_summit);
diff -druN linux-2.6.39-libre/arch/x86/kernel/apic/x2apic_cluster.c linux-3.0-rc7-libre/arch/x86/kernel/apic/x2apic_cluster.c
--- linux-2.6.39-libre/arch/x86/kernel/apic/x2apic_cluster.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/kernel/apic/x2apic_cluster.c	2011-07-11 19:51:52.000000000 -0400
@@ -5,118 +5,95 @@
 #include <linux/ctype.h>
 #include <linux/init.h>
 #include <linux/dmar.h>
+#include <linux/cpu.h>
 
 #include <asm/smp.h>
-#include <asm/apic.h>
-#include <asm/ipi.h>
+#include <asm/x2apic.h>
 
 static DEFINE_PER_CPU(u32, x86_cpu_to_logical_apicid);
+static DEFINE_PER_CPU(cpumask_var_t, cpus_in_cluster);
+static DEFINE_PER_CPU(cpumask_var_t, ipi_mask);
 
 static int x2apic_acpi_madt_oem_check(char *oem_id, char *oem_table_id)
 {
 	return x2apic_enabled();
 }
 
-/*
- * need to use more than cpu 0, because we need more vectors when
- * MSI-X are used.
- */
-static const struct cpumask *x2apic_target_cpus(void)
-{
-	return cpu_online_mask;
-}
-
-/*
- * for now each logical cpu is in its own vector allocation domain.
- */
-static void x2apic_vector_allocation_domain(int cpu, struct cpumask *retmask)
+static inline u32 x2apic_cluster(int cpu)
 {
-	cpumask_clear(retmask);
-	cpumask_set_cpu(cpu, retmask);
+	return per_cpu(x86_cpu_to_logical_apicid, cpu) >> 16;
 }
 
 static void
- __x2apic_send_IPI_dest(unsigned int apicid, int vector, unsigned int dest)
+__x2apic_send_IPI_mask(const struct cpumask *mask, int vector, int apic_dest)
 {
-	unsigned long cfg;
+	struct cpumask *cpus_in_cluster_ptr;
+	struct cpumask *ipi_mask_ptr;
+	unsigned int cpu, this_cpu;
+	unsigned long flags;
+	u32 dest;
 
-	cfg = __prepare_ICR(0, vector, dest);
+	x2apic_wrmsr_fence();
+
+	local_irq_save(flags);
+
+	this_cpu = smp_processor_id();
 
 	/*
-	 * send the IPI.
+	 * We are to modify mask, so we need an own copy
+	 * and be sure it's manipulated with irq off.
 	 */
-	native_x2apic_icr_write(cfg, apicid);
-}
+	ipi_mask_ptr = __raw_get_cpu_var(ipi_mask);
+	cpumask_copy(ipi_mask_ptr, mask);
 
-/*
- * for now, we send the IPI's one by one in the cpumask.
- * TBD: Based on the cpu mask, we can send the IPI's to the cluster group
- * at once. We have 16 cpu's in a cluster. This will minimize IPI register
- * writes.
- */
-static void x2apic_send_IPI_mask(const struct cpumask *mask, int vector)
-{
-	unsigned long query_cpu;
-	unsigned long flags;
+	/*
+	 * The idea is to send one IPI per cluster.
+	 */
+	for_each_cpu(cpu, ipi_mask_ptr) {
+		unsigned long i;
 
-	x2apic_wrmsr_fence();
+		cpus_in_cluster_ptr = per_cpu(cpus_in_cluster, cpu);
+		dest = 0;
 
-	local_irq_save(flags);
-	for_each_cpu(query_cpu, mask) {
-		__x2apic_send_IPI_dest(
-			per_cpu(x86_cpu_to_logical_apicid, query_cpu),
-			vector, apic->dest_logical);
+		/* Collect cpus in cluster. */
+		for_each_cpu_and(i, ipi_mask_ptr, cpus_in_cluster_ptr) {
+			if (apic_dest == APIC_DEST_ALLINC || i != this_cpu)
+				dest |= per_cpu(x86_cpu_to_logical_apicid, i);
+		}
+
+		if (!dest)
+			continue;
+
+		__x2apic_send_IPI_dest(dest, vector, apic->dest_logical);
+		/*
+		 * Cluster sibling cpus should be discared now so
+		 * we would not send IPI them second time.
+		 */
+		cpumask_andnot(ipi_mask_ptr, ipi_mask_ptr, cpus_in_cluster_ptr);
 	}
+
 	local_irq_restore(flags);
 }
 
+static void x2apic_send_IPI_mask(const struct cpumask *mask, int vector)
+{
+	__x2apic_send_IPI_mask(mask, vector, APIC_DEST_ALLINC);
+}
+
 static void
  x2apic_send_IPI_mask_allbutself(const struct cpumask *mask, int vector)
 {
-	unsigned long this_cpu = smp_processor_id();
-	unsigned long query_cpu;
-	unsigned long flags;
-
-	x2apic_wrmsr_fence();
-
-	local_irq_save(flags);
-	for_each_cpu(query_cpu, mask) {
-		if (query_cpu == this_cpu)
-			continue;
-		__x2apic_send_IPI_dest(
-				per_cpu(x86_cpu_to_logical_apicid, query_cpu),
-				vector, apic->dest_logical);
-	}
-	local_irq_restore(flags);
+	__x2apic_send_IPI_mask(mask, vector, APIC_DEST_ALLBUT);
 }
 
 static void x2apic_send_IPI_allbutself(int vector)
 {
-	unsigned long this_cpu = smp_processor_id();
-	unsigned long query_cpu;
-	unsigned long flags;
-
-	x2apic_wrmsr_fence();
-
-	local_irq_save(flags);
-	for_each_online_cpu(query_cpu) {
-		if (query_cpu == this_cpu)
-			continue;
-		__x2apic_send_IPI_dest(
-				per_cpu(x86_cpu_to_logical_apicid, query_cpu),
-				vector, apic->dest_logical);
-	}
-	local_irq_restore(flags);
+	__x2apic_send_IPI_mask(cpu_online_mask, vector, APIC_DEST_ALLBUT);
 }
 
 static void x2apic_send_IPI_all(int vector)
 {
-	x2apic_send_IPI_mask(cpu_online_mask, vector);
-}
-
-static int x2apic_apic_id_registered(void)
-{
-	return 1;
+	__x2apic_send_IPI_mask(cpu_online_mask, vector, APIC_DEST_ALLINC);
 }
 
 static unsigned int x2apic_cpu_mask_to_apicid(const struct cpumask *cpumask)
@@ -151,43 +128,90 @@
 	return per_cpu(x86_cpu_to_logical_apicid, cpu);
 }
 
-static unsigned int x2apic_cluster_phys_get_apic_id(unsigned long x)
+static void init_x2apic_ldr(void)
 {
-	unsigned int id;
+	unsigned int this_cpu = smp_processor_id();
+	unsigned int cpu;
 
-	id = x;
-	return id;
+	per_cpu(x86_cpu_to_logical_apicid, this_cpu) = apic_read(APIC_LDR);
+
+	__cpu_set(this_cpu, per_cpu(cpus_in_cluster, this_cpu));
+	for_each_online_cpu(cpu) {
+		if (x2apic_cluster(this_cpu) != x2apic_cluster(cpu))
+			continue;
+		__cpu_set(this_cpu, per_cpu(cpus_in_cluster, cpu));
+		__cpu_set(cpu, per_cpu(cpus_in_cluster, this_cpu));
+	}
 }
 
-static unsigned long set_apic_id(unsigned int id)
+ /*
+  * At CPU state changes, update the x2apic cluster sibling info.
+  */
+static int __cpuinit
+update_clusterinfo(struct notifier_block *nfb, unsigned long action, void *hcpu)
 {
-	unsigned long x;
+	unsigned int this_cpu = (unsigned long)hcpu;
+	unsigned int cpu;
+	int err = 0;
 
-	x = id;
-	return x;
-}
+	switch (action) {
+	case CPU_UP_PREPARE:
+		if (!zalloc_cpumask_var(&per_cpu(cpus_in_cluster, this_cpu),
+					GFP_KERNEL)) {
+			err = -ENOMEM;
+		} else if (!zalloc_cpumask_var(&per_cpu(ipi_mask, this_cpu),
+					       GFP_KERNEL)) {
+			free_cpumask_var(per_cpu(cpus_in_cluster, this_cpu));
+			err = -ENOMEM;
+		}
+		break;
+	case CPU_UP_CANCELED:
+	case CPU_UP_CANCELED_FROZEN:
+	case CPU_DEAD:
+		for_each_online_cpu(cpu) {
+			if (x2apic_cluster(this_cpu) != x2apic_cluster(cpu))
+				continue;
+			__cpu_clear(this_cpu, per_cpu(cpus_in_cluster, cpu));
+			__cpu_clear(cpu, per_cpu(cpus_in_cluster, this_cpu));
+		}
+		free_cpumask_var(per_cpu(cpus_in_cluster, this_cpu));
+		free_cpumask_var(per_cpu(ipi_mask, this_cpu));
+		break;
+	}
 
-static int x2apic_cluster_phys_pkg_id(int initial_apicid, int index_msb)
-{
-	return initial_apicid >> index_msb;
+	return notifier_from_errno(err);
 }
 
-static void x2apic_send_IPI_self(int vector)
-{
-	apic_write(APIC_SELF_IPI, vector);
-}
+static struct notifier_block __refdata x2apic_cpu_notifier = {
+	.notifier_call = update_clusterinfo,
+};
 
-static void init_x2apic_ldr(void)
+static int x2apic_init_cpu_notifier(void)
 {
 	int cpu = smp_processor_id();
 
-	per_cpu(x86_cpu_to_logical_apicid, cpu) = apic_read(APIC_LDR);
+	zalloc_cpumask_var(&per_cpu(cpus_in_cluster, cpu), GFP_KERNEL);
+	zalloc_cpumask_var(&per_cpu(ipi_mask, cpu), GFP_KERNEL);
+
+	BUG_ON(!per_cpu(cpus_in_cluster, cpu) || !per_cpu(ipi_mask, cpu));
+
+	__cpu_set(cpu, per_cpu(cpus_in_cluster, cpu));
+	register_hotcpu_notifier(&x2apic_cpu_notifier);
+	return 1;
 }
 
-struct apic apic_x2apic_cluster = {
+static int x2apic_cluster_probe(void)
+{
+	if (x2apic_mode)
+		return x2apic_init_cpu_notifier();
+	else
+		return 0;
+}
+
+static struct apic apic_x2apic_cluster = {
 
 	.name				= "cluster x2apic",
-	.probe				= NULL,
+	.probe				= x2apic_cluster_probe,
 	.acpi_madt_oem_check		= x2apic_acpi_madt_oem_check,
 	.apic_id_registered		= x2apic_apic_id_registered,
 
@@ -211,11 +235,11 @@
 	.setup_portio_remap		= NULL,
 	.check_phys_apicid_present	= default_check_phys_apicid_present,
 	.enable_apic_mode		= NULL,
-	.phys_pkg_id			= x2apic_cluster_phys_pkg_id,
+	.phys_pkg_id			= x2apic_phys_pkg_id,
 	.mps_oem_check			= NULL,
 
-	.get_apic_id			= x2apic_cluster_phys_get_apic_id,
-	.set_apic_id			= set_apic_id,
+	.get_apic_id			= x2apic_get_apic_id,
+	.set_apic_id			= x2apic_set_apic_id,
 	.apic_id_mask			= 0xFFFFFFFFu,
 
 	.cpu_mask_to_apicid		= x2apic_cpu_mask_to_apicid,
@@ -240,3 +264,5 @@
 	.wait_icr_idle			= native_x2apic_wait_icr_idle,
 	.safe_wait_icr_idle		= native_safe_x2apic_wait_icr_idle,
 };
+
+apic_driver(apic_x2apic_cluster);
diff -druN linux-2.6.39-libre/arch/x86/kernel/apic/x2apic_phys.c linux-3.0-rc7-libre/arch/x86/kernel/apic/x2apic_phys.c
--- linux-2.6.39-libre/arch/x86/kernel/apic/x2apic_phys.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/kernel/apic/x2apic_phys.c	2011-07-11 19:51:52.000000000 -0400
@@ -7,11 +7,12 @@
 #include <linux/dmar.h>
 
 #include <asm/smp.h>
-#include <asm/apic.h>
-#include <asm/ipi.h>
+#include <asm/x2apic.h>
 
 int x2apic_phys;
 
+static struct apic apic_x2apic_phys;
+
 static int set_x2apic_phys_mode(char *arg)
 {
 	x2apic_phys = 1;
@@ -27,94 +28,46 @@
 		return 0;
 }
 
-/*
- * need to use more than cpu 0, because we need more vectors when
- * MSI-X are used.
- */
-static const struct cpumask *x2apic_target_cpus(void)
-{
-	return cpu_online_mask;
-}
-
-static void x2apic_vector_allocation_domain(int cpu, struct cpumask *retmask)
-{
-	cpumask_clear(retmask);
-	cpumask_set_cpu(cpu, retmask);
-}
-
-static void __x2apic_send_IPI_dest(unsigned int apicid, int vector,
-				   unsigned int dest)
-{
-	unsigned long cfg;
-
-	cfg = __prepare_ICR(0, vector, dest);
-
-	/*
-	 * send the IPI.
-	 */
-	native_x2apic_icr_write(cfg, apicid);
-}
-
-static void x2apic_send_IPI_mask(const struct cpumask *mask, int vector)
+static void
+__x2apic_send_IPI_mask(const struct cpumask *mask, int vector, int apic_dest)
 {
 	unsigned long query_cpu;
+	unsigned long this_cpu;
 	unsigned long flags;
 
 	x2apic_wrmsr_fence();
 
 	local_irq_save(flags);
+
+	this_cpu = smp_processor_id();
 	for_each_cpu(query_cpu, mask) {
+		if (apic_dest == APIC_DEST_ALLBUT && this_cpu == query_cpu)
+			continue;
 		__x2apic_send_IPI_dest(per_cpu(x86_cpu_to_apicid, query_cpu),
 				       vector, APIC_DEST_PHYSICAL);
 	}
 	local_irq_restore(flags);
 }
 
+static void x2apic_send_IPI_mask(const struct cpumask *mask, int vector)
+{
+	__x2apic_send_IPI_mask(mask, vector, APIC_DEST_ALLINC);
+}
+
 static void
  x2apic_send_IPI_mask_allbutself(const struct cpumask *mask, int vector)
 {
-	unsigned long this_cpu = smp_processor_id();
-	unsigned long query_cpu;
-	unsigned long flags;
-
-	x2apic_wrmsr_fence();
-
-	local_irq_save(flags);
-	for_each_cpu(query_cpu, mask) {
-		if (query_cpu != this_cpu)
-			__x2apic_send_IPI_dest(
-				per_cpu(x86_cpu_to_apicid, query_cpu),
-				vector, APIC_DEST_PHYSICAL);
-	}
-	local_irq_restore(flags);
+	__x2apic_send_IPI_mask(mask, vector, APIC_DEST_ALLBUT);
 }
 
 static void x2apic_send_IPI_allbutself(int vector)
 {
-	unsigned long this_cpu = smp_processor_id();
-	unsigned long query_cpu;
-	unsigned long flags;
-
-	x2apic_wrmsr_fence();
-
-	local_irq_save(flags);
-	for_each_online_cpu(query_cpu) {
-		if (query_cpu == this_cpu)
-			continue;
-		__x2apic_send_IPI_dest(per_cpu(x86_cpu_to_apicid, query_cpu),
-				       vector, APIC_DEST_PHYSICAL);
-	}
-	local_irq_restore(flags);
+	__x2apic_send_IPI_mask(cpu_online_mask, vector, APIC_DEST_ALLBUT);
 }
 
 static void x2apic_send_IPI_all(int vector)
 {
-	x2apic_send_IPI_mask(cpu_online_mask, vector);
-}
-
-static int x2apic_apic_id_registered(void)
-{
-	return 1;
+	__x2apic_send_IPI_mask(cpu_online_mask, vector, APIC_DEST_ALLINC);
 }
 
 static unsigned int x2apic_cpu_mask_to_apicid(const struct cpumask *cpumask)
@@ -149,34 +102,22 @@
 	return per_cpu(x86_cpu_to_apicid, cpu);
 }
 
-static unsigned int x2apic_phys_get_apic_id(unsigned long x)
-{
-	return x;
-}
-
-static unsigned long set_apic_id(unsigned int id)
-{
-	return id;
-}
-
-static int x2apic_phys_pkg_id(int initial_apicid, int index_msb)
+static void init_x2apic_ldr(void)
 {
-	return initial_apicid >> index_msb;
 }
 
-static void x2apic_send_IPI_self(int vector)
+static int x2apic_phys_probe(void)
 {
-	apic_write(APIC_SELF_IPI, vector);
-}
+	if (x2apic_mode && x2apic_phys)
+		return 1;
 
-static void init_x2apic_ldr(void)
-{
+	return apic == &apic_x2apic_phys;
 }
 
-struct apic apic_x2apic_phys = {
+static struct apic apic_x2apic_phys = {
 
 	.name				= "physical x2apic",
-	.probe				= NULL,
+	.probe				= x2apic_phys_probe,
 	.acpi_madt_oem_check		= x2apic_acpi_madt_oem_check,
 	.apic_id_registered		= x2apic_apic_id_registered,
 
@@ -203,8 +144,8 @@
 	.phys_pkg_id			= x2apic_phys_pkg_id,
 	.mps_oem_check			= NULL,
 
-	.get_apic_id			= x2apic_phys_get_apic_id,
-	.set_apic_id			= set_apic_id,
+	.get_apic_id			= x2apic_get_apic_id,
+	.set_apic_id			= x2apic_set_apic_id,
 	.apic_id_mask			= 0xFFFFFFFFu,
 
 	.cpu_mask_to_apicid		= x2apic_cpu_mask_to_apicid,
@@ -229,3 +170,5 @@
 	.wait_icr_idle			= native_x2apic_wait_icr_idle,
 	.safe_wait_icr_idle		= native_safe_x2apic_wait_icr_idle,
 };
+
+apic_driver(apic_x2apic_phys);
diff -druN linux-2.6.39-libre/arch/x86/kernel/apic/x2apic_uv_x.c linux-3.0-rc7-libre/arch/x86/kernel/apic/x2apic_uv_x.c
--- linux-2.6.39-libre/arch/x86/kernel/apic/x2apic_uv_x.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/kernel/apic/x2apic_uv_x.c	2011-07-11 19:51:52.000000000 -0400
@@ -58,6 +58,8 @@
 EXPORT_SYMBOL_GPL(uv_apicid_hibits);
 static DEFINE_SPINLOCK(uv_nmi_lock);
 
+static struct apic apic_x2apic_uv_x;
+
 static unsigned long __init uv_early_read_mmr(unsigned long addr)
 {
 	unsigned long val, *mmr;
@@ -89,6 +91,10 @@
 	m_n_config.v = uv_early_read_mmr(UVH_RH_GAM_CONFIG_MMR);
 	uv_min_hub_revision_id = node_id.s.revision;
 
+	if (node_id.s.part_number == UV2_HUB_PART_NUMBER)
+		uv_min_hub_revision_id += UV2_HUB_REVISION_BASE - 1;
+
+	uv_hub_info->hub_revision = uv_min_hub_revision_id;
 	pnode = (node_id.s.node_id >> 1) & ((1 << m_n_config.s.n_skt) - 1);
 	return pnode;
 }
@@ -110,17 +116,25 @@
  */
 static void __init uv_set_apicid_hibit(void)
 {
-	union uvh_lb_target_physical_apic_id_mask_u apicid_mask;
+	union uv1h_lb_target_physical_apic_id_mask_u apicid_mask;
 
-	apicid_mask.v = uv_early_read_mmr(UVH_LB_TARGET_PHYSICAL_APIC_ID_MASK);
-	uv_apicid_hibits = apicid_mask.s.bit_enables & UV_APICID_HIBIT_MASK;
+	if (is_uv1_hub()) {
+		apicid_mask.v =
+			uv_early_read_mmr(UV1H_LB_TARGET_PHYSICAL_APIC_ID_MASK);
+		uv_apicid_hibits =
+			apicid_mask.s1.bit_enables & UV_APICID_HIBIT_MASK;
+	}
 }
 
 static int __init uv_acpi_madt_oem_check(char *oem_id, char *oem_table_id)
 {
-	int pnodeid;
+	int pnodeid, is_uv1, is_uv2;
 
-	if (!strcmp(oem_id, "SGI")) {
+	is_uv1 = !strcmp(oem_id, "SGI");
+	is_uv2 = !strcmp(oem_id, "SGI2");
+	if (is_uv1 || is_uv2) {
+		uv_hub_info->hub_revision =
+			is_uv1 ? UV1_HUB_REVISION_BASE : UV2_HUB_REVISION_BASE;
 		pnodeid = early_get_pnodeid();
 		early_get_apic_pnode_shift();
 		x86_platform.is_untracked_pat_range =  uv_is_untracked_pat_range;
@@ -326,10 +340,15 @@
 	apic_write(APIC_SELF_IPI, vector);
 }
 
-struct apic __refdata apic_x2apic_uv_x = {
+static int uv_probe(void)
+{
+	return apic == &apic_x2apic_uv_x;
+}
+
+static struct apic __refdata apic_x2apic_uv_x = {
 
 	.name				= "UV large system",
-	.probe				= NULL,
+	.probe				= uv_probe,
 	.acpi_madt_oem_check		= uv_acpi_madt_oem_check,
 	.apic_id_registered		= uv_apic_id_registered,
 
@@ -477,12 +496,19 @@
 static __init void map_mmioh_high(int max_pnode)
 {
 	union uvh_rh_gam_mmioh_overlay_config_mmr_u mmioh;
-	int shift = UVH_RH_GAM_MMIOH_OVERLAY_CONFIG_MMR_BASE_SHFT;
+	int shift;
 
 	mmioh.v = uv_read_local_mmr(UVH_RH_GAM_MMIOH_OVERLAY_CONFIG_MMR);
-	if (mmioh.s.enable)
-		map_high("MMIOH", mmioh.s.base, shift, mmioh.s.m_io,
+	if (is_uv1_hub() && mmioh.s1.enable) {
+		shift = UV1H_RH_GAM_MMIOH_OVERLAY_CONFIG_MMR_BASE_SHFT;
+		map_high("MMIOH", mmioh.s1.base, shift, mmioh.s1.m_io,
 			max_pnode, map_uc);
+	}
+	if (is_uv2_hub() && mmioh.s2.enable) {
+		shift = UV2H_RH_GAM_MMIOH_OVERLAY_CONFIG_MMR_BASE_SHFT;
+		map_high("MMIOH", mmioh.s2.base, shift, mmioh.s2.m_io,
+			max_pnode, map_uc);
+	}
 }
 
 static __init void map_low_mmrs(void)
@@ -606,14 +632,14 @@
 
 /* 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)
+		      unsigned int command_bits, u32 flags)
 {
 	int domain, bus, rc;
 
-	PR_DEVEL("devfn %x decode %d cmd %x chg_brdg %d\n",
-			pdev->devfn, decode, command_bits, change_bridge);
+	PR_DEVEL("devfn %x decode %d cmd %x flags %d\n",
+			pdev->devfn, decode, command_bits, flags);
 
-	if (!change_bridge)
+	if (!(flags & PCI_VGA_STATE_CHANGE_BRIDGE))
 		return 0;
 
 	if ((command_bits & PCI_COMMAND_IO) == 0)
@@ -729,13 +755,14 @@
 	unsigned long mmr_base, present, paddr;
 	unsigned short pnode_mask, pnode_io_mask;
 
+	printk(KERN_INFO "UV: Found %s hub\n", is_uv1_hub() ? "UV1" : "UV2");
 	map_low_mmrs();
 
 	m_n_config.v = uv_read_local_mmr(UVH_RH_GAM_CONFIG_MMR );
 	m_val = m_n_config.s.m_skt;
 	n_val = m_n_config.s.n_skt;
 	mmioh.v = uv_read_local_mmr(UVH_RH_GAM_MMIOH_OVERLAY_CONFIG_MMR);
-	n_io = mmioh.s.n_io;
+	n_io = is_uv1_hub() ? mmioh.s1.n_io : mmioh.s2.n_io;
 	mmr_base =
 	    uv_read_local_mmr(UVH_RH_GAM_MMR_OVERLAY_CONFIG_MMR) &
 	    ~UV_MMR_ENABLE;
@@ -804,6 +831,8 @@
 		 */
 		uv_cpu_hub_info(cpu)->pnode_mask = pnode_mask;
 		uv_cpu_hub_info(cpu)->apic_pnode_shift = uvh_apicid.s.pnode_shift;
+		uv_cpu_hub_info(cpu)->hub_revision = uv_hub_info->hub_revision;
+
 		pnode = uv_apicid_to_pnode(apicid);
 		blade = boot_pnode_to_blade(pnode);
 		lcpu = uv_blade_info[blade].nr_possible_cpus;
@@ -859,3 +888,5 @@
 	if (is_kdump_kernel())
 		reboot_type = BOOT_ACPI;
 }
+
+apic_driver(apic_x2apic_uv_x);
diff -druN linux-2.6.39-libre/arch/x86/kernel/apm_32.c linux-3.0-rc7-libre/arch/x86/kernel/apm_32.c
--- linux-2.6.39-libre/arch/x86/kernel/apm_32.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/kernel/apm_32.c	2011-07-11 19:51:52.000000000 -0400
@@ -361,6 +361,7 @@
  * idle percentage above which bios idle calls are done
  */
 #ifdef CONFIG_APM_CPU_IDLE
+#warning deprecated CONFIG_APM_CPU_IDLE will be deleted in 2012
 #define DEFAULT_IDLE_THRESHOLD	95
 #else
 #define DEFAULT_IDLE_THRESHOLD	100
@@ -904,6 +905,7 @@
 	unsigned int jiffies_since_last_check = jiffies - last_jiffies;
 	unsigned int bucket;
 
+	WARN_ONCE(1, "deprecated apm_cpu_idle will be deleted in 2012");
 recalc:
 	if (jiffies_since_last_check > IDLE_CALC_LIMIT) {
 		use_apm_idle = 0;
@@ -1238,7 +1240,6 @@
 	dpm_suspend_noirq(PMSG_SUSPEND);
 
 	local_irq_disable();
-	sysdev_suspend(PMSG_SUSPEND);
 	syscore_suspend();
 
 	local_irq_enable();
@@ -1258,7 +1259,6 @@
 	err = (err == APM_SUCCESS) ? 0 : -EIO;
 
 	syscore_resume();
-	sysdev_resume();
 	local_irq_enable();
 
 	dpm_resume_noirq(PMSG_RESUME);
@@ -1282,7 +1282,6 @@
 	dpm_suspend_noirq(PMSG_SUSPEND);
 
 	local_irq_disable();
-	sysdev_suspend(PMSG_SUSPEND);
 	syscore_suspend();
 	local_irq_enable();
 
@@ -1292,7 +1291,6 @@
 
 	local_irq_disable();
 	syscore_resume();
-	sysdev_resume();
 	local_irq_enable();
 
 	dpm_resume_noirq(PMSG_RESUME);
diff -druN linux-2.6.39-libre/arch/x86/kernel/cpu/amd.c linux-3.0-rc7-libre/arch/x86/kernel/cpu/amd.c
--- linux-2.6.39-libre/arch/x86/kernel/cpu/amd.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/kernel/cpu/amd.c	2011-07-11 19:51:52.000000000 -0400
@@ -612,8 +612,11 @@
 	}
 #endif
 
-	/* As a rule processors have APIC timer running in deep C states */
-	if (c->x86 > 0xf && !cpu_has_amd_erratum(amd_erratum_400))
+	/*
+	 * Family 0x12 and above processors have APIC timer
+	 * running in deep C states.
+	 */
+	if (c->x86 > 0x11)
 		set_cpu_cap(c, X86_FEATURE_ARAT);
 
 	/*
@@ -629,10 +632,13 @@
 		 * Fixes: https://bugzilla.kernel.org/show_bug.cgi?id=33012
 		 */
 		u64 mask;
+		int err;
 
-		rdmsrl(MSR_AMD64_MCx_MASK(4), mask);
-		mask |= (1 << 10);
-		wrmsrl(MSR_AMD64_MCx_MASK(4), mask);
+		err = rdmsrl_safe(MSR_AMD64_MCx_MASK(4), &mask);
+		if (err == 0) {
+			mask |= (1 << 10);
+			checking_wrmsrl(MSR_AMD64_MCx_MASK(4), mask);
+		}
 	}
 }
 
diff -druN linux-2.6.39-libre/arch/x86/kernel/cpu/bugs.c linux-3.0-rc7-libre/arch/x86/kernel/cpu/bugs.c
--- linux-2.6.39-libre/arch/x86/kernel/cpu/bugs.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/kernel/cpu/bugs.c	2011-07-11 19:51:52.000000000 -0400
@@ -19,6 +19,7 @@
 
 static int __init no_halt(char *s)
 {
+	WARN_ONCE(1, "\"no-hlt\" is deprecated, please use \"idle=poll\"\n");
 	boot_cpu_data.hlt_works_ok = 0;
 	return 1;
 }
diff -druN linux-2.6.39-libre/arch/x86/kernel/cpu/common.c linux-3.0-rc7-libre/arch/x86/kernel/cpu/common.c
--- linux-2.6.39-libre/arch/x86/kernel/cpu/common.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/kernel/cpu/common.c	2011-07-11 19:51:52.000000000 -0400
@@ -254,6 +254,25 @@
 }
 #endif
 
+static int disable_smep __cpuinitdata;
+static __init int setup_disable_smep(char *arg)
+{
+	disable_smep = 1;
+	return 1;
+}
+__setup("nosmep", setup_disable_smep);
+
+static __cpuinit void setup_smep(struct cpuinfo_x86 *c)
+{
+	if (cpu_has(c, X86_FEATURE_SMEP)) {
+		if (unlikely(disable_smep)) {
+			setup_clear_cpu_cap(X86_FEATURE_SMEP);
+			clear_in_cr4(X86_CR4_SMEP);
+		} else
+			set_in_cr4(X86_CR4_SMEP);
+	}
+}
+
 /*
  * Some CPU features depend on higher CPUID levels, which may not always
  * be available due to CPUID level capping or broken virtualization
@@ -458,13 +477,6 @@
 	if (smp_num_siblings <= 1)
 		goto out;
 
-	if (smp_num_siblings > nr_cpu_ids) {
-		pr_warning("CPU: Unsupported number of siblings %d",
-			   smp_num_siblings);
-		smp_num_siblings = 1;
-		return;
-	}
-
 	index_msb = get_count_order(smp_num_siblings);
 	c->phys_proc_id = apic->phys_pkg_id(c->initial_apicid, index_msb);
 
@@ -565,8 +577,7 @@
 
 		cpuid_count(0x00000007, 0, &eax, &ebx, &ecx, &edx);
 
-		if (eax > 0)
-			c->x86_capability[9] = ebx;
+		c->x86_capability[9] = ebx;
 	}
 
 	/* AMD-defined flags: level 0x80000001 */
@@ -668,6 +679,8 @@
 	c->cpu_index = 0;
 #endif
 	filter_cpuid_features(c, false);
+
+	setup_smep(c);
 }
 
 void __init early_cpu_init(void)
@@ -753,6 +766,8 @@
 #endif
 	}
 
+	setup_smep(c);
+
 	get_model_name(c); /* Default name */
 
 	detect_nopl(c);
@@ -887,7 +902,7 @@
 void __init identify_boot_cpu(void)
 {
 	identify_cpu(&boot_cpu_data);
-	init_c1e_mask();
+	init_amd_e400_c1e_mask();
 #ifdef CONFIG_X86_32
 	sysenter_setup();
 	enable_sep_cpu();
diff -druN linux-2.6.39-libre/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c linux-3.0-rc7-libre/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c
--- linux-2.6.39-libre/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,776 +0,0 @@
-/*
- * acpi-cpufreq.c - ACPI Processor P-States Driver
- *
- *  Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com>
- *  Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
- *  Copyright (C) 2002 - 2004 Dominik Brodowski <linux@brodo.de>
- *  Copyright (C) 2006       Denis Sadykov <denis.m.sadykov@intel.com>
- *
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or (at
- *  your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful, but
- *  WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *  General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License along
- *  with this program; if not, write to the Free Software Foundation, Inc.,
- *  59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
- *
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/smp.h>
-#include <linux/sched.h>
-#include <linux/cpufreq.h>
-#include <linux/compiler.h>
-#include <linux/dmi.h>
-#include <linux/slab.h>
-
-#include <linux/acpi.h>
-#include <linux/io.h>
-#include <linux/delay.h>
-#include <linux/uaccess.h>
-
-#include <acpi/processor.h>
-
-#include <asm/msr.h>
-#include <asm/processor.h>
-#include <asm/cpufeature.h>
-#include "mperf.h"
-
-#define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, \
-		"acpi-cpufreq", msg)
-
-MODULE_AUTHOR("Paul Diefenbaugh, Dominik Brodowski");
-MODULE_DESCRIPTION("ACPI Processor P-States Driver");
-MODULE_LICENSE("GPL");
-
-enum {
-	UNDEFINED_CAPABLE = 0,
-	SYSTEM_INTEL_MSR_CAPABLE,
-	SYSTEM_IO_CAPABLE,
-};
-
-#define INTEL_MSR_RANGE		(0xffff)
-
-struct acpi_cpufreq_data {
-	struct acpi_processor_performance *acpi_data;
-	struct cpufreq_frequency_table *freq_table;
-	unsigned int resume;
-	unsigned int cpu_feature;
-};
-
-static DEFINE_PER_CPU(struct acpi_cpufreq_data *, acfreq_data);
-
-/* acpi_perf_data is a pointer to percpu data. */
-static struct acpi_processor_performance __percpu *acpi_perf_data;
-
-static struct cpufreq_driver acpi_cpufreq_driver;
-
-static unsigned int acpi_pstate_strict;
-
-static int check_est_cpu(unsigned int cpuid)
-{
-	struct cpuinfo_x86 *cpu = &cpu_data(cpuid);
-
-	return cpu_has(cpu, X86_FEATURE_EST);
-}
-
-static unsigned extract_io(u32 value, struct acpi_cpufreq_data *data)
-{
-	struct acpi_processor_performance *perf;
-	int i;
-
-	perf = data->acpi_data;
-
-	for (i = 0; i < perf->state_count; i++) {
-		if (value == perf->states[i].status)
-			return data->freq_table[i].frequency;
-	}
-	return 0;
-}
-
-static unsigned extract_msr(u32 msr, struct acpi_cpufreq_data *data)
-{
-	int i;
-	struct acpi_processor_performance *perf;
-
-	msr &= INTEL_MSR_RANGE;
-	perf = data->acpi_data;
-
-	for (i = 0; data->freq_table[i].frequency != CPUFREQ_TABLE_END; i++) {
-		if (msr == perf->states[data->freq_table[i].index].status)
-			return data->freq_table[i].frequency;
-	}
-	return data->freq_table[0].frequency;
-}
-
-static unsigned extract_freq(u32 val, struct acpi_cpufreq_data *data)
-{
-	switch (data->cpu_feature) {
-	case SYSTEM_INTEL_MSR_CAPABLE:
-		return extract_msr(val, data);
-	case SYSTEM_IO_CAPABLE:
-		return extract_io(val, data);
-	default:
-		return 0;
-	}
-}
-
-struct msr_addr {
-	u32 reg;
-};
-
-struct io_addr {
-	u16 port;
-	u8 bit_width;
-};
-
-struct drv_cmd {
-	unsigned int type;
-	const struct cpumask *mask;
-	union {
-		struct msr_addr msr;
-		struct io_addr io;
-	} addr;
-	u32 val;
-};
-
-/* Called via smp_call_function_single(), on the target CPU */
-static void do_drv_read(void *_cmd)
-{
-	struct drv_cmd *cmd = _cmd;
-	u32 h;
-
-	switch (cmd->type) {
-	case SYSTEM_INTEL_MSR_CAPABLE:
-		rdmsr(cmd->addr.msr.reg, cmd->val, h);
-		break;
-	case SYSTEM_IO_CAPABLE:
-		acpi_os_read_port((acpi_io_address)cmd->addr.io.port,
-				&cmd->val,
-				(u32)cmd->addr.io.bit_width);
-		break;
-	default:
-		break;
-	}
-}
-
-/* Called via smp_call_function_many(), on the target CPUs */
-static void do_drv_write(void *_cmd)
-{
-	struct drv_cmd *cmd = _cmd;
-	u32 lo, hi;
-
-	switch (cmd->type) {
-	case SYSTEM_INTEL_MSR_CAPABLE:
-		rdmsr(cmd->addr.msr.reg, lo, hi);
-		lo = (lo & ~INTEL_MSR_RANGE) | (cmd->val & INTEL_MSR_RANGE);
-		wrmsr(cmd->addr.msr.reg, lo, hi);
-		break;
-	case SYSTEM_IO_CAPABLE:
-		acpi_os_write_port((acpi_io_address)cmd->addr.io.port,
-				cmd->val,
-				(u32)cmd->addr.io.bit_width);
-		break;
-	default:
-		break;
-	}
-}
-
-static void drv_read(struct drv_cmd *cmd)
-{
-	int err;
-	cmd->val = 0;
-
-	err = smp_call_function_any(cmd->mask, do_drv_read, cmd, 1);
-	WARN_ON_ONCE(err);	/* smp_call_function_any() was buggy? */
-}
-
-static void drv_write(struct drv_cmd *cmd)
-{
-	int this_cpu;
-
-	this_cpu = get_cpu();
-	if (cpumask_test_cpu(this_cpu, cmd->mask))
-		do_drv_write(cmd);
-	smp_call_function_many(cmd->mask, do_drv_write, cmd, 1);
-	put_cpu();
-}
-
-static u32 get_cur_val(const struct cpumask *mask)
-{
-	struct acpi_processor_performance *perf;
-	struct drv_cmd cmd;
-
-	if (unlikely(cpumask_empty(mask)))
-		return 0;
-
-	switch (per_cpu(acfreq_data, cpumask_first(mask))->cpu_feature) {
-	case SYSTEM_INTEL_MSR_CAPABLE:
-		cmd.type = SYSTEM_INTEL_MSR_CAPABLE;
-		cmd.addr.msr.reg = MSR_IA32_PERF_STATUS;
-		break;
-	case SYSTEM_IO_CAPABLE:
-		cmd.type = SYSTEM_IO_CAPABLE;
-		perf = per_cpu(acfreq_data, cpumask_first(mask))->acpi_data;
-		cmd.addr.io.port = perf->control_register.address;
-		cmd.addr.io.bit_width = perf->control_register.bit_width;
-		break;
-	default:
-		return 0;
-	}
-
-	cmd.mask = mask;
-	drv_read(&cmd);
-
-	dprintk("get_cur_val = %u\n", cmd.val);
-
-	return cmd.val;
-}
-
-static unsigned int get_cur_freq_on_cpu(unsigned int cpu)
-{
-	struct acpi_cpufreq_data *data = per_cpu(acfreq_data, cpu);
-	unsigned int freq;
-	unsigned int cached_freq;
-
-	dprintk("get_cur_freq_on_cpu (%d)\n", cpu);
-
-	if (unlikely(data == NULL ||
-		     data->acpi_data == NULL || data->freq_table == NULL)) {
-		return 0;
-	}
-
-	cached_freq = data->freq_table[data->acpi_data->state].frequency;
-	freq = extract_freq(get_cur_val(cpumask_of(cpu)), data);
-	if (freq != cached_freq) {
-		/*
-		 * The dreaded BIOS frequency change behind our back.
-		 * Force set the frequency on next target call.
-		 */
-		data->resume = 1;
-	}
-
-	dprintk("cur freq = %u\n", freq);
-
-	return freq;
-}
-
-static unsigned int check_freqs(const struct cpumask *mask, unsigned int freq,
-				struct acpi_cpufreq_data *data)
-{
-	unsigned int cur_freq;
-	unsigned int i;
-
-	for (i = 0; i < 100; i++) {
-		cur_freq = extract_freq(get_cur_val(mask), data);
-		if (cur_freq == freq)
-			return 1;
-		udelay(10);
-	}
-	return 0;
-}
-
-static int acpi_cpufreq_target(struct cpufreq_policy *policy,
-			       unsigned int target_freq, unsigned int relation)
-{
-	struct acpi_cpufreq_data *data = per_cpu(acfreq_data, policy->cpu);
-	struct acpi_processor_performance *perf;
-	struct cpufreq_freqs freqs;
-	struct drv_cmd cmd;
-	unsigned int next_state = 0; /* Index into freq_table */
-	unsigned int next_perf_state = 0; /* Index into perf table */
-	unsigned int i;
-	int result = 0;
-
-	dprintk("acpi_cpufreq_target %d (%d)\n", target_freq, policy->cpu);
-
-	if (unlikely(data == NULL ||
-	     data->acpi_data == NULL || data->freq_table == NULL)) {
-		return -ENODEV;
-	}
-
-	perf = data->acpi_data;
-	result = cpufreq_frequency_table_target(policy,
-						data->freq_table,
-						target_freq,
-						relation, &next_state);
-	if (unlikely(result)) {
-		result = -ENODEV;
-		goto out;
-	}
-
-	next_perf_state = data->freq_table[next_state].index;
-	if (perf->state == next_perf_state) {
-		if (unlikely(data->resume)) {
-			dprintk("Called after resume, resetting to P%d\n",
-				next_perf_state);
-			data->resume = 0;
-		} else {
-			dprintk("Already at target state (P%d)\n",
-				next_perf_state);
-			goto out;
-		}
-	}
-
-	switch (data->cpu_feature) {
-	case SYSTEM_INTEL_MSR_CAPABLE:
-		cmd.type = SYSTEM_INTEL_MSR_CAPABLE;
-		cmd.addr.msr.reg = MSR_IA32_PERF_CTL;
-		cmd.val = (u32) perf->states[next_perf_state].control;
-		break;
-	case SYSTEM_IO_CAPABLE:
-		cmd.type = SYSTEM_IO_CAPABLE;
-		cmd.addr.io.port = perf->control_register.address;
-		cmd.addr.io.bit_width = perf->control_register.bit_width;
-		cmd.val = (u32) perf->states[next_perf_state].control;
-		break;
-	default:
-		result = -ENODEV;
-		goto out;
-	}
-
-	/* cpufreq holds the hotplug lock, so we are safe from here on */
-	if (policy->shared_type != CPUFREQ_SHARED_TYPE_ANY)
-		cmd.mask = policy->cpus;
-	else
-		cmd.mask = cpumask_of(policy->cpu);
-
-	freqs.old = perf->states[perf->state].core_frequency * 1000;
-	freqs.new = data->freq_table[next_state].frequency;
-	for_each_cpu(i, policy->cpus) {
-		freqs.cpu = i;
-		cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
-	}
-
-	drv_write(&cmd);
-
-	if (acpi_pstate_strict) {
-		if (!check_freqs(cmd.mask, freqs.new, data)) {
-			dprintk("acpi_cpufreq_target failed (%d)\n",
-				policy->cpu);
-			result = -EAGAIN;
-			goto out;
-		}
-	}
-
-	for_each_cpu(i, policy->cpus) {
-		freqs.cpu = i;
-		cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
-	}
-	perf->state = next_perf_state;
-
-out:
-	return result;
-}
-
-static int acpi_cpufreq_verify(struct cpufreq_policy *policy)
-{
-	struct acpi_cpufreq_data *data = per_cpu(acfreq_data, policy->cpu);
-
-	dprintk("acpi_cpufreq_verify\n");
-
-	return cpufreq_frequency_table_verify(policy, data->freq_table);
-}
-
-static unsigned long
-acpi_cpufreq_guess_freq(struct acpi_cpufreq_data *data, unsigned int cpu)
-{
-	struct acpi_processor_performance *perf = data->acpi_data;
-
-	if (cpu_khz) {
-		/* search the closest match to cpu_khz */
-		unsigned int i;
-		unsigned long freq;
-		unsigned long freqn = perf->states[0].core_frequency * 1000;
-
-		for (i = 0; i < (perf->state_count-1); i++) {
-			freq = freqn;
-			freqn = perf->states[i+1].core_frequency * 1000;
-			if ((2 * cpu_khz) > (freqn + freq)) {
-				perf->state = i;
-				return freq;
-			}
-		}
-		perf->state = perf->state_count-1;
-		return freqn;
-	} else {
-		/* assume CPU is at P0... */
-		perf->state = 0;
-		return perf->states[0].core_frequency * 1000;
-	}
-}
-
-static void free_acpi_perf_data(void)
-{
-	unsigned int i;
-
-	/* Freeing a NULL pointer is OK, and alloc_percpu zeroes. */
-	for_each_possible_cpu(i)
-		free_cpumask_var(per_cpu_ptr(acpi_perf_data, i)
-				 ->shared_cpu_map);
-	free_percpu(acpi_perf_data);
-}
-
-/*
- * acpi_cpufreq_early_init - initialize ACPI P-States library
- *
- * Initialize the ACPI P-States library (drivers/acpi/processor_perflib.c)
- * in order to determine correct frequency and voltage pairings. We can
- * do _PDC and _PSD and find out the processor dependency for the
- * actual init that will happen later...
- */
-static int __init acpi_cpufreq_early_init(void)
-{
-	unsigned int i;
-	dprintk("acpi_cpufreq_early_init\n");
-
-	acpi_perf_data = alloc_percpu(struct acpi_processor_performance);
-	if (!acpi_perf_data) {
-		dprintk("Memory allocation error for acpi_perf_data.\n");
-		return -ENOMEM;
-	}
-	for_each_possible_cpu(i) {
-		if (!zalloc_cpumask_var_node(
-			&per_cpu_ptr(acpi_perf_data, i)->shared_cpu_map,
-			GFP_KERNEL, cpu_to_node(i))) {
-
-			/* Freeing a NULL pointer is OK: alloc_percpu zeroes. */
-			free_acpi_perf_data();
-			return -ENOMEM;
-		}
-	}
-
-	/* Do initialization in ACPI core */
-	acpi_processor_preregister_performance(acpi_perf_data);
-	return 0;
-}
-
-#ifdef CONFIG_SMP
-/*
- * Some BIOSes do SW_ANY coordination internally, either set it up in hw
- * or do it in BIOS firmware and won't inform about it to OS. If not
- * detected, this has a side effect of making CPU run at a different speed
- * than OS intended it to run at. Detect it and handle it cleanly.
- */
-static int bios_with_sw_any_bug;
-
-static int sw_any_bug_found(const struct dmi_system_id *d)
-{
-	bios_with_sw_any_bug = 1;
-	return 0;
-}
-
-static const struct dmi_system_id sw_any_bug_dmi_table[] = {
-	{
-		.callback = sw_any_bug_found,
-		.ident = "Supermicro Server X6DLP",
-		.matches = {
-			DMI_MATCH(DMI_SYS_VENDOR, "Supermicro"),
-			DMI_MATCH(DMI_BIOS_VERSION, "080010"),
-			DMI_MATCH(DMI_PRODUCT_NAME, "X6DLP"),
-		},
-	},
-	{ }
-};
-
-static int acpi_cpufreq_blacklist(struct cpuinfo_x86 *c)
-{
-	/* Intel Xeon Processor 7100 Series Specification Update
-	 * http://www.intel.com/Assets/PDF/specupdate/314554.pdf
-	 * AL30: A Machine Check Exception (MCE) Occurring during an
-	 * Enhanced Intel SpeedStep Technology Ratio Change May Cause
-	 * Both Processor Cores to Lock Up. */
-	if (c->x86_vendor == X86_VENDOR_INTEL) {
-		if ((c->x86 == 15) &&
-		    (c->x86_model == 6) &&
-		    (c->x86_mask == 8)) {
-			printk(KERN_INFO "acpi-cpufreq: Intel(R) "
-			    "Xeon(R) 7100 Errata AL30, processors may "
-			    "lock up on frequency changes: disabling "
-			    "acpi-cpufreq.\n");
-			return -ENODEV;
-		    }
-		}
-	return 0;
-}
-#endif
-
-static int acpi_cpufreq_cpu_init(struct cpufreq_policy *policy)
-{
-	unsigned int i;
-	unsigned int valid_states = 0;
-	unsigned int cpu = policy->cpu;
-	struct acpi_cpufreq_data *data;
-	unsigned int result = 0;
-	struct cpuinfo_x86 *c = &cpu_data(policy->cpu);
-	struct acpi_processor_performance *perf;
-#ifdef CONFIG_SMP
-	static int blacklisted;
-#endif
-
-	dprintk("acpi_cpufreq_cpu_init\n");
-
-#ifdef CONFIG_SMP
-	if (blacklisted)
-		return blacklisted;
-	blacklisted = acpi_cpufreq_blacklist(c);
-	if (blacklisted)
-		return blacklisted;
-#endif
-
-	data = kzalloc(sizeof(struct acpi_cpufreq_data), GFP_KERNEL);
-	if (!data)
-		return -ENOMEM;
-
-	data->acpi_data = per_cpu_ptr(acpi_perf_data, cpu);
-	per_cpu(acfreq_data, cpu) = data;
-
-	if (cpu_has(c, X86_FEATURE_CONSTANT_TSC))
-		acpi_cpufreq_driver.flags |= CPUFREQ_CONST_LOOPS;
-
-	result = acpi_processor_register_performance(data->acpi_data, cpu);
-	if (result)
-		goto err_free;
-
-	perf = data->acpi_data;
-	policy->shared_type = perf->shared_type;
-
-	/*
-	 * Will let policy->cpus know about dependency only when software
-	 * coordination is required.
-	 */
-	if (policy->shared_type == CPUFREQ_SHARED_TYPE_ALL ||
-	    policy->shared_type == CPUFREQ_SHARED_TYPE_ANY) {
-		cpumask_copy(policy->cpus, perf->shared_cpu_map);
-	}
-	cpumask_copy(policy->related_cpus, perf->shared_cpu_map);
-
-#ifdef CONFIG_SMP
-	dmi_check_system(sw_any_bug_dmi_table);
-	if (bios_with_sw_any_bug && cpumask_weight(policy->cpus) == 1) {
-		policy->shared_type = CPUFREQ_SHARED_TYPE_ALL;
-		cpumask_copy(policy->cpus, cpu_core_mask(cpu));
-	}
-#endif
-
-	/* capability check */
-	if (perf->state_count <= 1) {
-		dprintk("No P-States\n");
-		result = -ENODEV;
-		goto err_unreg;
-	}
-
-	if (perf->control_register.space_id != perf->status_register.space_id) {
-		result = -ENODEV;
-		goto err_unreg;
-	}
-
-	switch (perf->control_register.space_id) {
-	case ACPI_ADR_SPACE_SYSTEM_IO:
-		dprintk("SYSTEM IO addr space\n");
-		data->cpu_feature = SYSTEM_IO_CAPABLE;
-		break;
-	case ACPI_ADR_SPACE_FIXED_HARDWARE:
-		dprintk("HARDWARE addr space\n");
-		if (!check_est_cpu(cpu)) {
-			result = -ENODEV;
-			goto err_unreg;
-		}
-		data->cpu_feature = SYSTEM_INTEL_MSR_CAPABLE;
-		break;
-	default:
-		dprintk("Unknown addr space %d\n",
-			(u32) (perf->control_register.space_id));
-		result = -ENODEV;
-		goto err_unreg;
-	}
-
-	data->freq_table = kmalloc(sizeof(struct cpufreq_frequency_table) *
-		    (perf->state_count+1), GFP_KERNEL);
-	if (!data->freq_table) {
-		result = -ENOMEM;
-		goto err_unreg;
-	}
-
-	/* detect transition latency */
-	policy->cpuinfo.transition_latency = 0;
-	for (i = 0; i < perf->state_count; i++) {
-		if ((perf->states[i].transition_latency * 1000) >
-		    policy->cpuinfo.transition_latency)
-			policy->cpuinfo.transition_latency =
-			    perf->states[i].transition_latency * 1000;
-	}
-
-	/* Check for high latency (>20uS) from buggy BIOSes, like on T42 */
-	if (perf->control_register.space_id == ACPI_ADR_SPACE_FIXED_HARDWARE &&
-	    policy->cpuinfo.transition_latency > 20 * 1000) {
-		policy->cpuinfo.transition_latency = 20 * 1000;
-		printk_once(KERN_INFO
-			    "P-state transition latency capped at 20 uS\n");
-	}
-
-	/* table init */
-	for (i = 0; i < perf->state_count; i++) {
-		if (i > 0 && perf->states[i].core_frequency >=
-		    data->freq_table[valid_states-1].frequency / 1000)
-			continue;
-
-		data->freq_table[valid_states].index = i;
-		data->freq_table[valid_states].frequency =
-		    perf->states[i].core_frequency * 1000;
-		valid_states++;
-	}
-	data->freq_table[valid_states].frequency = CPUFREQ_TABLE_END;
-	perf->state = 0;
-
-	result = cpufreq_frequency_table_cpuinfo(policy, data->freq_table);
-	if (result)
-		goto err_freqfree;
-
-	if (perf->states[0].core_frequency * 1000 != policy->cpuinfo.max_freq)
-		printk(KERN_WARNING FW_WARN "P-state 0 is not max freq\n");
-
-	switch (perf->control_register.space_id) {
-	case ACPI_ADR_SPACE_SYSTEM_IO:
-		/* Current speed is unknown and not detectable by IO port */
-		policy->cur = acpi_cpufreq_guess_freq(data, policy->cpu);
-		break;
-	case ACPI_ADR_SPACE_FIXED_HARDWARE:
-		acpi_cpufreq_driver.get = get_cur_freq_on_cpu;
-		policy->cur = get_cur_freq_on_cpu(cpu);
-		break;
-	default:
-		break;
-	}
-
-	/* notify BIOS that we exist */
-	acpi_processor_notify_smm(THIS_MODULE);
-
-	/* Check for APERF/MPERF support in hardware */
-	if (cpu_has(c, X86_FEATURE_APERFMPERF))
-		acpi_cpufreq_driver.getavg = cpufreq_get_measured_perf;
-
-	dprintk("CPU%u - ACPI performance management activated.\n", cpu);
-	for (i = 0; i < perf->state_count; i++)
-		dprintk("     %cP%d: %d MHz, %d mW, %d uS\n",
-			(i == perf->state ? '*' : ' '), i,
-			(u32) perf->states[i].core_frequency,
-			(u32) perf->states[i].power,
-			(u32) perf->states[i].transition_latency);
-
-	cpufreq_frequency_table_get_attr(data->freq_table, policy->cpu);
-
-	/*
-	 * the first call to ->target() should result in us actually
-	 * writing something to the appropriate registers.
-	 */
-	data->resume = 1;
-
-	return result;
-
-err_freqfree:
-	kfree(data->freq_table);
-err_unreg:
-	acpi_processor_unregister_performance(perf, cpu);
-err_free:
-	kfree(data);
-	per_cpu(acfreq_data, cpu) = NULL;
-
-	return result;
-}
-
-static int acpi_cpufreq_cpu_exit(struct cpufreq_policy *policy)
-{
-	struct acpi_cpufreq_data *data = per_cpu(acfreq_data, policy->cpu);
-
-	dprintk("acpi_cpufreq_cpu_exit\n");
-
-	if (data) {
-		cpufreq_frequency_table_put_attr(policy->cpu);
-		per_cpu(acfreq_data, policy->cpu) = NULL;
-		acpi_processor_unregister_performance(data->acpi_data,
-						      policy->cpu);
-		kfree(data->freq_table);
-		kfree(data);
-	}
-
-	return 0;
-}
-
-static int acpi_cpufreq_resume(struct cpufreq_policy *policy)
-{
-	struct acpi_cpufreq_data *data = per_cpu(acfreq_data, policy->cpu);
-
-	dprintk("acpi_cpufreq_resume\n");
-
-	data->resume = 1;
-
-	return 0;
-}
-
-static struct freq_attr *acpi_cpufreq_attr[] = {
-	&cpufreq_freq_attr_scaling_available_freqs,
-	NULL,
-};
-
-static struct cpufreq_driver acpi_cpufreq_driver = {
-	.verify		= acpi_cpufreq_verify,
-	.target		= acpi_cpufreq_target,
-	.bios_limit	= acpi_processor_get_bios_limit,
-	.init		= acpi_cpufreq_cpu_init,
-	.exit		= acpi_cpufreq_cpu_exit,
-	.resume		= acpi_cpufreq_resume,
-	.name		= "acpi-cpufreq",
-	.owner		= THIS_MODULE,
-	.attr		= acpi_cpufreq_attr,
-};
-
-static int __init acpi_cpufreq_init(void)
-{
-	int ret;
-
-	if (acpi_disabled)
-		return 0;
-
-	dprintk("acpi_cpufreq_init\n");
-
-	ret = acpi_cpufreq_early_init();
-	if (ret)
-		return ret;
-
-	ret = cpufreq_register_driver(&acpi_cpufreq_driver);
-	if (ret)
-		free_acpi_perf_data();
-
-	return ret;
-}
-
-static void __exit acpi_cpufreq_exit(void)
-{
-	dprintk("acpi_cpufreq_exit\n");
-
-	cpufreq_unregister_driver(&acpi_cpufreq_driver);
-
-	free_percpu(acpi_perf_data);
-}
-
-module_param(acpi_pstate_strict, uint, 0644);
-MODULE_PARM_DESC(acpi_pstate_strict,
-	"value 0 or non-zero. non-zero -> strict ACPI checks are "
-	"performed during frequency changes.");
-
-late_initcall(acpi_cpufreq_init);
-module_exit(acpi_cpufreq_exit);
-
-MODULE_ALIAS("acpi");
diff -druN linux-2.6.39-libre/arch/x86/kernel/cpu/cpufreq/cpufreq-nforce2.c linux-3.0-rc7-libre/arch/x86/kernel/cpu/cpufreq/cpufreq-nforce2.c
--- linux-2.6.39-libre/arch/x86/kernel/cpu/cpufreq/cpufreq-nforce2.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/kernel/cpu/cpufreq/cpufreq-nforce2.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,446 +0,0 @@
-/*
- * (C) 2004-2006  Sebastian Witt <se.witt@gmx.net>
- *
- *  Licensed under the terms of the GNU GPL License version 2.
- *  Based upon reverse engineered information
- *
- *  BIG FAT DISCLAIMER: Work in progress code. Possibly *dangerous*
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/init.h>
-#include <linux/cpufreq.h>
-#include <linux/pci.h>
-#include <linux/delay.h>
-
-#define NFORCE2_XTAL 25
-#define NFORCE2_BOOTFSB 0x48
-#define NFORCE2_PLLENABLE 0xa8
-#define NFORCE2_PLLREG 0xa4
-#define NFORCE2_PLLADR 0xa0
-#define NFORCE2_PLL(mul, div) (0x100000 | (mul << 8) | div)
-
-#define NFORCE2_MIN_FSB 50
-#define NFORCE2_SAFE_DISTANCE 50
-
-/* Delay in ms between FSB changes */
-/* #define NFORCE2_DELAY 10 */
-
-/*
- * nforce2_chipset:
- * FSB is changed using the chipset
- */
-static struct pci_dev *nforce2_dev;
-
-/* fid:
- * multiplier * 10
- */
-static int fid;
-
-/* min_fsb, max_fsb:
- * minimum and maximum FSB (= FSB at boot time)
- */
-static int min_fsb;
-static int max_fsb;
-
-MODULE_AUTHOR("Sebastian Witt <se.witt@gmx.net>");
-MODULE_DESCRIPTION("nForce2 FSB changing cpufreq driver");
-MODULE_LICENSE("GPL");
-
-module_param(fid, int, 0444);
-module_param(min_fsb, int, 0444);
-
-MODULE_PARM_DESC(fid, "CPU multiplier to use (11.5 = 115)");
-MODULE_PARM_DESC(min_fsb,
-		"Minimum FSB to use, if not defined: current FSB - 50");
-
-#define PFX "cpufreq-nforce2: "
-#define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, \
-		"cpufreq-nforce2", msg)
-
-/**
- * nforce2_calc_fsb - calculate FSB
- * @pll: PLL value
- *
- *   Calculates FSB from PLL value
- */
-static int nforce2_calc_fsb(int pll)
-{
-	unsigned char mul, div;
-
-	mul = (pll >> 8) & 0xff;
-	div = pll & 0xff;
-
-	if (div > 0)
-		return NFORCE2_XTAL * mul / div;
-
-	return 0;
-}
-
-/**
- * nforce2_calc_pll - calculate PLL value
- * @fsb: FSB
- *
- *   Calculate PLL value for given FSB
- */
-static int nforce2_calc_pll(unsigned int fsb)
-{
-	unsigned char xmul, xdiv;
-	unsigned char mul = 0, div = 0;
-	int tried = 0;
-
-	/* Try to calculate multiplier and divider up to 4 times */
-	while (((mul == 0) || (div == 0)) && (tried <= 3)) {
-		for (xdiv = 2; xdiv <= 0x80; xdiv++)
-			for (xmul = 1; xmul <= 0xfe; xmul++)
-				if (nforce2_calc_fsb(NFORCE2_PLL(xmul, xdiv)) ==
-				    fsb + tried) {
-					mul = xmul;
-					div = xdiv;
-				}
-		tried++;
-	}
-
-	if ((mul == 0) || (div == 0))
-		return -1;
-
-	return NFORCE2_PLL(mul, div);
-}
-
-/**
- * nforce2_write_pll - write PLL value to chipset
- * @pll: PLL value
- *
- *   Writes new FSB PLL value to chipset
- */
-static void nforce2_write_pll(int pll)
-{
-	int temp;
-
-	/* Set the pll addr. to 0x00 */
-	pci_write_config_dword(nforce2_dev, NFORCE2_PLLADR, 0);
-
-	/* Now write the value in all 64 registers */
-	for (temp = 0; temp <= 0x3f; temp++)
-		pci_write_config_dword(nforce2_dev, NFORCE2_PLLREG, pll);
-
-	return;
-}
-
-/**
- * nforce2_fsb_read - Read FSB
- *
- *   Read FSB from chipset
- *   If bootfsb != 0, return FSB at boot-time
- */
-static unsigned int nforce2_fsb_read(int bootfsb)
-{
-	struct pci_dev *nforce2_sub5;
-	u32 fsb, temp = 0;
-
-	/* Get chipset boot FSB from subdevice 5 (FSB at boot-time) */
-	nforce2_sub5 = pci_get_subsys(PCI_VENDOR_ID_NVIDIA, 0x01EF,
-				PCI_ANY_ID, PCI_ANY_ID, NULL);
-	if (!nforce2_sub5)
-		return 0;
-
-	pci_read_config_dword(nforce2_sub5, NFORCE2_BOOTFSB, &fsb);
-	fsb /= 1000000;
-
-	/* Check if PLL register is already set */
-	pci_read_config_byte(nforce2_dev, NFORCE2_PLLENABLE, (u8 *)&temp);
-
-	if (bootfsb || !temp)
-		return fsb;
-
-	/* Use PLL register FSB value */
-	pci_read_config_dword(nforce2_dev, NFORCE2_PLLREG, &temp);
-	fsb = nforce2_calc_fsb(temp);
-
-	return fsb;
-}
-
-/**
- * nforce2_set_fsb - set new FSB
- * @fsb: New FSB
- *
- *   Sets new FSB
- */
-static int nforce2_set_fsb(unsigned int fsb)
-{
-	u32 temp = 0;
-	unsigned int tfsb;
-	int diff;
-	int pll = 0;
-
-	if ((fsb > max_fsb) || (fsb < NFORCE2_MIN_FSB)) {
-		printk(KERN_ERR PFX "FSB %d is out of range!\n", fsb);
-		return -EINVAL;
-	}
-
-	tfsb = nforce2_fsb_read(0);
-	if (!tfsb) {
-		printk(KERN_ERR PFX "Error while reading the FSB\n");
-		return -EINVAL;
-	}
-
-	/* First write? Then set actual value */
-	pci_read_config_byte(nforce2_dev, NFORCE2_PLLENABLE, (u8 *)&temp);
-	if (!temp) {
-		pll = nforce2_calc_pll(tfsb);
-
-		if (pll < 0)
-			return -EINVAL;
-
-		nforce2_write_pll(pll);
-	}
-
-	/* Enable write access */
-	temp = 0x01;
-	pci_write_config_byte(nforce2_dev, NFORCE2_PLLENABLE, (u8)temp);
-
-	diff = tfsb - fsb;
-
-	if (!diff)
-		return 0;
-
-	while ((tfsb != fsb) && (tfsb <= max_fsb) && (tfsb >= min_fsb)) {
-		if (diff < 0)
-			tfsb++;
-		else
-			tfsb--;
-
-		/* Calculate the PLL reg. value */
-		pll = nforce2_calc_pll(tfsb);
-		if (pll == -1)
-			return -EINVAL;
-
-		nforce2_write_pll(pll);
-#ifdef NFORCE2_DELAY
-		mdelay(NFORCE2_DELAY);
-#endif
-	}
-
-	temp = 0x40;
-	pci_write_config_byte(nforce2_dev, NFORCE2_PLLADR, (u8)temp);
-
-	return 0;
-}
-
-/**
- * nforce2_get - get the CPU frequency
- * @cpu: CPU number
- *
- * Returns the CPU frequency
- */
-static unsigned int nforce2_get(unsigned int cpu)
-{
-	if (cpu)
-		return 0;
-	return nforce2_fsb_read(0) * fid * 100;
-}
-
-/**
- * nforce2_target - set a new CPUFreq policy
- * @policy: new policy
- * @target_freq: the target frequency
- * @relation: how that frequency relates to achieved frequency
- *  (CPUFREQ_RELATION_L or CPUFREQ_RELATION_H)
- *
- * Sets a new CPUFreq policy.
- */
-static int nforce2_target(struct cpufreq_policy *policy,
-			  unsigned int target_freq, unsigned int relation)
-{
-/*        unsigned long         flags; */
-	struct cpufreq_freqs freqs;
-	unsigned int target_fsb;
-
-	if ((target_freq > policy->max) || (target_freq < policy->min))
-		return -EINVAL;
-
-	target_fsb = target_freq / (fid * 100);
-
-	freqs.old = nforce2_get(policy->cpu);
-	freqs.new = target_fsb * fid * 100;
-	freqs.cpu = 0;		/* Only one CPU on nForce2 platforms */
-
-	if (freqs.old == freqs.new)
-		return 0;
-
-	dprintk("Old CPU frequency %d kHz, new %d kHz\n",
-	       freqs.old, freqs.new);
-
-	cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
-
-	/* Disable IRQs */
-	/* local_irq_save(flags); */
-
-	if (nforce2_set_fsb(target_fsb) < 0)
-		printk(KERN_ERR PFX "Changing FSB to %d failed\n",
-			target_fsb);
-	else
-		dprintk("Changed FSB successfully to %d\n",
-			target_fsb);
-
-	/* Enable IRQs */
-	/* local_irq_restore(flags); */
-
-	cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
-
-	return 0;
-}
-
-/**
- * nforce2_verify - verifies a new CPUFreq policy
- * @policy: new policy
- */
-static int nforce2_verify(struct cpufreq_policy *policy)
-{
-	unsigned int fsb_pol_max;
-
-	fsb_pol_max = policy->max / (fid * 100);
-
-	if (policy->min < (fsb_pol_max * fid * 100))
-		policy->max = (fsb_pol_max + 1) * fid * 100;
-
-	cpufreq_verify_within_limits(policy,
-				     policy->cpuinfo.min_freq,
-				     policy->cpuinfo.max_freq);
-	return 0;
-}
-
-static int nforce2_cpu_init(struct cpufreq_policy *policy)
-{
-	unsigned int fsb;
-	unsigned int rfid;
-
-	/* capability check */
-	if (policy->cpu != 0)
-		return -ENODEV;
-
-	/* Get current FSB */
-	fsb = nforce2_fsb_read(0);
-
-	if (!fsb)
-		return -EIO;
-
-	/* FIX: Get FID from CPU */
-	if (!fid) {
-		if (!cpu_khz) {
-			printk(KERN_WARNING PFX
-			"cpu_khz not set, can't calculate multiplier!\n");
-			return -ENODEV;
-		}
-
-		fid = cpu_khz / (fsb * 100);
-		rfid = fid % 5;
-
-		if (rfid) {
-			if (rfid > 2)
-				fid += 5 - rfid;
-			else
-				fid -= rfid;
-		}
-	}
-
-	printk(KERN_INFO PFX "FSB currently at %i MHz, FID %d.%d\n", fsb,
-	       fid / 10, fid % 10);
-
-	/* Set maximum FSB to FSB at boot time */
-	max_fsb = nforce2_fsb_read(1);
-
-	if (!max_fsb)
-		return -EIO;
-
-	if (!min_fsb)
-		min_fsb = max_fsb - NFORCE2_SAFE_DISTANCE;
-
-	if (min_fsb < NFORCE2_MIN_FSB)
-		min_fsb = NFORCE2_MIN_FSB;
-
-	/* cpuinfo and default policy values */
-	policy->cpuinfo.min_freq = min_fsb * fid * 100;
-	policy->cpuinfo.max_freq = max_fsb * fid * 100;
-	policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL;
-	policy->cur = nforce2_get(policy->cpu);
-	policy->min = policy->cpuinfo.min_freq;
-	policy->max = policy->cpuinfo.max_freq;
-
-	return 0;
-}
-
-static int nforce2_cpu_exit(struct cpufreq_policy *policy)
-{
-	return 0;
-}
-
-static struct cpufreq_driver nforce2_driver = {
-	.name = "nforce2",
-	.verify = nforce2_verify,
-	.target = nforce2_target,
-	.get = nforce2_get,
-	.init = nforce2_cpu_init,
-	.exit = nforce2_cpu_exit,
-	.owner = THIS_MODULE,
-};
-
-/**
- * nforce2_detect_chipset - detect the Southbridge which contains FSB PLL logic
- *
- * Detects nForce2 A2 and C1 stepping
- *
- */
-static int nforce2_detect_chipset(void)
-{
-	nforce2_dev = pci_get_subsys(PCI_VENDOR_ID_NVIDIA,
-					PCI_DEVICE_ID_NVIDIA_NFORCE2,
-					PCI_ANY_ID, PCI_ANY_ID, NULL);
-
-	if (nforce2_dev == NULL)
-		return -ENODEV;
-
-	printk(KERN_INFO PFX "Detected nForce2 chipset revision %X\n",
-	       nforce2_dev->revision);
-	printk(KERN_INFO PFX
-	       "FSB changing is maybe unstable and can lead to "
-	       "crashes and data loss.\n");
-
-	return 0;
-}
-
-/**
- * nforce2_init - initializes the nForce2 CPUFreq driver
- *
- * Initializes the nForce2 FSB support. Returns -ENODEV on unsupported
- * devices, -EINVAL on problems during initiatization, and zero on
- * success.
- */
-static int __init nforce2_init(void)
-{
-	/* TODO: do we need to detect the processor? */
-
-	/* detect chipset */
-	if (nforce2_detect_chipset()) {
-		printk(KERN_INFO PFX "No nForce2 chipset.\n");
-		return -ENODEV;
-	}
-
-	return cpufreq_register_driver(&nforce2_driver);
-}
-
-/**
- * nforce2_exit - unregisters cpufreq module
- *
- *   Unregisters nForce2 FSB change support.
- */
-static void __exit nforce2_exit(void)
-{
-	cpufreq_unregister_driver(&nforce2_driver);
-}
-
-module_init(nforce2_init);
-module_exit(nforce2_exit);
-
diff -druN linux-2.6.39-libre/arch/x86/kernel/cpu/cpufreq/elanfreq.c linux-3.0-rc7-libre/arch/x86/kernel/cpu/cpufreq/elanfreq.c
--- linux-2.6.39-libre/arch/x86/kernel/cpu/cpufreq/elanfreq.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/kernel/cpu/cpufreq/elanfreq.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,309 +0,0 @@
-/*
- *	elanfreq:	cpufreq driver for the AMD ELAN family
- *
- *	(c) Copyright 2002 Robert Schwebel <r.schwebel@pengutronix.de>
- *
- *	Parts of this code are (c) Sven Geggus <sven@geggus.net>
- *
- *      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.
- *
- *	2002-02-13: - initial revision for 2.4.18-pre9 by Robert Schwebel
- *
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/init.h>
-
-#include <linux/delay.h>
-#include <linux/cpufreq.h>
-
-#include <asm/msr.h>
-#include <linux/timex.h>
-#include <linux/io.h>
-
-#define REG_CSCIR 0x22		/* Chip Setup and Control Index Register    */
-#define REG_CSCDR 0x23		/* Chip Setup and Control Data  Register    */
-
-/* Module parameter */
-static int max_freq;
-
-struct s_elan_multiplier {
-	int clock;		/* frequency in kHz                         */
-	int val40h;		/* PMU Force Mode register                  */
-	int val80h;		/* CPU Clock Speed Register                 */
-};
-
-/*
- * It is important that the frequencies
- * are listed in ascending order here!
- */
-static struct s_elan_multiplier elan_multiplier[] = {
-	{1000,	0x02,	0x18},
-	{2000,	0x02,	0x10},
-	{4000,	0x02,	0x08},
-	{8000,	0x00,	0x00},
-	{16000,	0x00,	0x02},
-	{33000,	0x00,	0x04},
-	{66000,	0x01,	0x04},
-	{99000,	0x01,	0x05}
-};
-
-static struct cpufreq_frequency_table elanfreq_table[] = {
-	{0,	1000},
-	{1,	2000},
-	{2,	4000},
-	{3,	8000},
-	{4,	16000},
-	{5,	33000},
-	{6,	66000},
-	{7,	99000},
-	{0,	CPUFREQ_TABLE_END},
-};
-
-
-/**
- *	elanfreq_get_cpu_frequency: determine current cpu speed
- *
- *	Finds out at which frequency the CPU of the Elan SOC runs
- *	at the moment. Frequencies from 1 to 33 MHz are generated
- *	the normal way, 66 and 99 MHz are called "Hyperspeed Mode"
- *	and have the rest of the chip running with 33 MHz.
- */
-
-static unsigned int elanfreq_get_cpu_frequency(unsigned int cpu)
-{
-	u8 clockspeed_reg;    /* Clock Speed Register */
-
-	local_irq_disable();
-	outb_p(0x80, REG_CSCIR);
-	clockspeed_reg = inb_p(REG_CSCDR);
-	local_irq_enable();
-
-	if ((clockspeed_reg & 0xE0) == 0xE0)
-		return 0;
-
-	/* Are we in CPU clock multiplied mode (66/99 MHz)? */
-	if ((clockspeed_reg & 0xE0) == 0xC0) {
-		if ((clockspeed_reg & 0x01) == 0)
-			return 66000;
-		else
-			return 99000;
-	}
-
-	/* 33 MHz is not 32 MHz... */
-	if ((clockspeed_reg & 0xE0) == 0xA0)
-		return 33000;
-
-	return (1<<((clockspeed_reg & 0xE0) >> 5)) * 1000;
-}
-
-
-/**
- *	elanfreq_set_cpu_frequency: Change the CPU core frequency
- *	@cpu: cpu number
- *	@freq: frequency in kHz
- *
- *	This function takes a frequency value and changes the CPU frequency
- *	according to this. Note that the frequency has to be checked by
- *	elanfreq_validatespeed() for correctness!
- *
- *	There is no return value.
- */
-
-static void elanfreq_set_cpu_state(unsigned int state)
-{
-	struct cpufreq_freqs    freqs;
-
-	freqs.old = elanfreq_get_cpu_frequency(0);
-	freqs.new = elan_multiplier[state].clock;
-	freqs.cpu = 0; /* elanfreq.c is UP only driver */
-
-	cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
-
-	printk(KERN_INFO "elanfreq: attempting to set frequency to %i kHz\n",
-			elan_multiplier[state].clock);
-
-
-	/*
-	 * Access to the Elan's internal registers is indexed via
-	 * 0x22: Chip Setup & Control Register Index Register (CSCI)
-	 * 0x23: Chip Setup & Control Register Data  Register (CSCD)
-	 *
-	 */
-
-	/*
-	 * 0x40 is the Power Management Unit's Force Mode Register.
-	 * Bit 6 enables Hyperspeed Mode (66/100 MHz core frequency)
-	 */
-
-	local_irq_disable();
-	outb_p(0x40, REG_CSCIR);		/* Disable hyperspeed mode */
-	outb_p(0x00, REG_CSCDR);
-	local_irq_enable();		/* wait till internal pipelines and */
-	udelay(1000);			/* buffers have cleaned up          */
-
-	local_irq_disable();
-
-	/* now, set the CPU clock speed register (0x80) */
-	outb_p(0x80, REG_CSCIR);
-	outb_p(elan_multiplier[state].val80h, REG_CSCDR);
-
-	/* now, the hyperspeed bit in PMU Force Mode Register (0x40) */
-	outb_p(0x40, REG_CSCIR);
-	outb_p(elan_multiplier[state].val40h, REG_CSCDR);
-	udelay(10000);
-	local_irq_enable();
-
-	cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
-};
-
-
-/**
- *	elanfreq_validatespeed: test if frequency range is valid
- *	@policy: the policy to validate
- *
- *	This function checks if a given frequency range in kHz is valid
- *	for the hardware supported by the driver.
- */
-
-static int elanfreq_verify(struct cpufreq_policy *policy)
-{
-	return cpufreq_frequency_table_verify(policy, &elanfreq_table[0]);
-}
-
-static int elanfreq_target(struct cpufreq_policy *policy,
-			    unsigned int target_freq,
-			    unsigned int relation)
-{
-	unsigned int newstate = 0;
-
-	if (cpufreq_frequency_table_target(policy, &elanfreq_table[0],
-				target_freq, relation, &newstate))
-		return -EINVAL;
-
-	elanfreq_set_cpu_state(newstate);
-
-	return 0;
-}
-
-
-/*
- *	Module init and exit code
- */
-
-static int elanfreq_cpu_init(struct cpufreq_policy *policy)
-{
-	struct cpuinfo_x86 *c = &cpu_data(0);
-	unsigned int i;
-	int result;
-
-	/* capability check */
-	if ((c->x86_vendor != X86_VENDOR_AMD) ||
-	    (c->x86 != 4) || (c->x86_model != 10))
-		return -ENODEV;
-
-	/* max freq */
-	if (!max_freq)
-		max_freq = elanfreq_get_cpu_frequency(0);
-
-	/* table init */
-	for (i = 0; (elanfreq_table[i].frequency != CPUFREQ_TABLE_END); i++) {
-		if (elanfreq_table[i].frequency > max_freq)
-			elanfreq_table[i].frequency = CPUFREQ_ENTRY_INVALID;
-	}
-
-	/* cpuinfo and default policy values */
-	policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL;
-	policy->cur = elanfreq_get_cpu_frequency(0);
-
-	result = cpufreq_frequency_table_cpuinfo(policy, elanfreq_table);
-	if (result)
-		return result;
-
-	cpufreq_frequency_table_get_attr(elanfreq_table, policy->cpu);
-	return 0;
-}
-
-
-static int elanfreq_cpu_exit(struct cpufreq_policy *policy)
-{
-	cpufreq_frequency_table_put_attr(policy->cpu);
-	return 0;
-}
-
-
-#ifndef MODULE
-/**
- * elanfreq_setup - elanfreq command line parameter parsing
- *
- * elanfreq command line parameter.  Use:
- *  elanfreq=66000
- * to set the maximum CPU frequency to 66 MHz. Note that in
- * case you do not give this boot parameter, the maximum
- * frequency will fall back to _current_ CPU frequency which
- * might be lower. If you build this as a module, use the
- * max_freq module parameter instead.
- */
-static int __init elanfreq_setup(char *str)
-{
-	max_freq = simple_strtoul(str, &str, 0);
-	printk(KERN_WARNING "You're using the deprecated elanfreq command line option. Use elanfreq.max_freq instead, please!\n");
-	return 1;
-}
-__setup("elanfreq=", elanfreq_setup);
-#endif
-
-
-static struct freq_attr *elanfreq_attr[] = {
-	&cpufreq_freq_attr_scaling_available_freqs,
-	NULL,
-};
-
-
-static struct cpufreq_driver elanfreq_driver = {
-	.get		= elanfreq_get_cpu_frequency,
-	.verify		= elanfreq_verify,
-	.target		= elanfreq_target,
-	.init		= elanfreq_cpu_init,
-	.exit		= elanfreq_cpu_exit,
-	.name		= "elanfreq",
-	.owner		= THIS_MODULE,
-	.attr		= elanfreq_attr,
-};
-
-
-static int __init elanfreq_init(void)
-{
-	struct cpuinfo_x86 *c = &cpu_data(0);
-
-	/* Test if we have the right hardware */
-	if ((c->x86_vendor != X86_VENDOR_AMD) ||
-		(c->x86 != 4) || (c->x86_model != 10)) {
-		printk(KERN_INFO "elanfreq: error: no Elan processor found!\n");
-		return -ENODEV;
-	}
-	return cpufreq_register_driver(&elanfreq_driver);
-}
-
-
-static void __exit elanfreq_exit(void)
-{
-	cpufreq_unregister_driver(&elanfreq_driver);
-}
-
-
-module_param(max_freq, int, 0444);
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Robert Schwebel <r.schwebel@pengutronix.de>, "
-		"Sven Geggus <sven@geggus.net>");
-MODULE_DESCRIPTION("cpufreq driver for AMD's Elan CPUs");
-
-module_init(elanfreq_init);
-module_exit(elanfreq_exit);
diff -druN linux-2.6.39-libre/arch/x86/kernel/cpu/cpufreq/e_powersaver.c linux-3.0-rc7-libre/arch/x86/kernel/cpu/cpufreq/e_powersaver.c
--- linux-2.6.39-libre/arch/x86/kernel/cpu/cpufreq/e_powersaver.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/kernel/cpu/cpufreq/e_powersaver.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,367 +0,0 @@
-/*
- *  Based on documentation provided by Dave Jones. Thanks!
- *
- *  Licensed under the terms of the GNU GPL License version 2.
- *
- *  BIG FAT DISCLAIMER: Work in progress code. Possibly *dangerous*
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/cpufreq.h>
-#include <linux/ioport.h>
-#include <linux/slab.h>
-#include <linux/timex.h>
-#include <linux/io.h>
-#include <linux/delay.h>
-
-#include <asm/msr.h>
-#include <asm/tsc.h>
-
-#define EPS_BRAND_C7M	0
-#define EPS_BRAND_C7	1
-#define EPS_BRAND_EDEN	2
-#define EPS_BRAND_C3	3
-#define EPS_BRAND_C7D	4
-
-struct eps_cpu_data {
-	u32 fsb;
-	struct cpufreq_frequency_table freq_table[];
-};
-
-static struct eps_cpu_data *eps_cpu[NR_CPUS];
-
-
-static unsigned int eps_get(unsigned int cpu)
-{
-	struct eps_cpu_data *centaur;
-	u32 lo, hi;
-
-	if (cpu)
-		return 0;
-	centaur = eps_cpu[cpu];
-	if (centaur == NULL)
-		return 0;
-
-	/* Return current frequency */
-	rdmsr(MSR_IA32_PERF_STATUS, lo, hi);
-	return centaur->fsb * ((lo >> 8) & 0xff);
-}
-
-static int eps_set_state(struct eps_cpu_data *centaur,
-			 unsigned int cpu,
-			 u32 dest_state)
-{
-	struct cpufreq_freqs freqs;
-	u32 lo, hi;
-	int err = 0;
-	int i;
-
-	freqs.old = eps_get(cpu);
-	freqs.new = centaur->fsb * ((dest_state >> 8) & 0xff);
-	freqs.cpu = cpu;
-	cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
-
-	/* Wait while CPU is busy */
-	rdmsr(MSR_IA32_PERF_STATUS, lo, hi);
-	i = 0;
-	while (lo & ((1 << 16) | (1 << 17))) {
-		udelay(16);
-		rdmsr(MSR_IA32_PERF_STATUS, lo, hi);
-		i++;
-		if (unlikely(i > 64)) {
-			err = -ENODEV;
-			goto postchange;
-		}
-	}
-	/* Set new multiplier and voltage */
-	wrmsr(MSR_IA32_PERF_CTL, dest_state & 0xffff, 0);
-	/* Wait until transition end */
-	i = 0;
-	do {
-		udelay(16);
-		rdmsr(MSR_IA32_PERF_STATUS, lo, hi);
-		i++;
-		if (unlikely(i > 64)) {
-			err = -ENODEV;
-			goto postchange;
-		}
-	} while (lo & ((1 << 16) | (1 << 17)));
-
-	/* Return current frequency */
-postchange:
-	rdmsr(MSR_IA32_PERF_STATUS, lo, hi);
-	freqs.new = centaur->fsb * ((lo >> 8) & 0xff);
-
-#ifdef DEBUG
-	{
-	u8 current_multiplier, current_voltage;
-
-	/* Print voltage and multiplier */
-	rdmsr(MSR_IA32_PERF_STATUS, lo, hi);
-	current_voltage = lo & 0xff;
-	printk(KERN_INFO "eps: Current voltage = %dmV\n",
-		current_voltage * 16 + 700);
-	current_multiplier = (lo >> 8) & 0xff;
-	printk(KERN_INFO "eps: Current multiplier = %d\n",
-		current_multiplier);
-	}
-#endif
-	cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
-	return err;
-}
-
-static int eps_target(struct cpufreq_policy *policy,
-			       unsigned int target_freq,
-			       unsigned int relation)
-{
-	struct eps_cpu_data *centaur;
-	unsigned int newstate = 0;
-	unsigned int cpu = policy->cpu;
-	unsigned int dest_state;
-	int ret;
-
-	if (unlikely(eps_cpu[cpu] == NULL))
-		return -ENODEV;
-	centaur = eps_cpu[cpu];
-
-	if (unlikely(cpufreq_frequency_table_target(policy,
-			&eps_cpu[cpu]->freq_table[0],
-			target_freq,
-			relation,
-			&newstate))) {
-		return -EINVAL;
-	}
-
-	/* Make frequency transition */
-	dest_state = centaur->freq_table[newstate].index & 0xffff;
-	ret = eps_set_state(centaur, cpu, dest_state);
-	if (ret)
-		printk(KERN_ERR "eps: Timeout!\n");
-	return ret;
-}
-
-static int eps_verify(struct cpufreq_policy *policy)
-{
-	return cpufreq_frequency_table_verify(policy,
-			&eps_cpu[policy->cpu]->freq_table[0]);
-}
-
-static int eps_cpu_init(struct cpufreq_policy *policy)
-{
-	unsigned int i;
-	u32 lo, hi;
-	u64 val;
-	u8 current_multiplier, current_voltage;
-	u8 max_multiplier, max_voltage;
-	u8 min_multiplier, min_voltage;
-	u8 brand = 0;
-	u32 fsb;
-	struct eps_cpu_data *centaur;
-	struct cpuinfo_x86 *c = &cpu_data(0);
-	struct cpufreq_frequency_table *f_table;
-	int k, step, voltage;
-	int ret;
-	int states;
-
-	if (policy->cpu != 0)
-		return -ENODEV;
-
-	/* Check brand */
-	printk(KERN_INFO "eps: Detected VIA ");
-
-	switch (c->x86_model) {
-	case 10:
-		rdmsr(0x1153, lo, hi);
-		brand = (((lo >> 2) ^ lo) >> 18) & 3;
-		printk(KERN_CONT "Model A ");
-		break;
-	case 13:
-		rdmsr(0x1154, lo, hi);
-		brand = (((lo >> 4) ^ (lo >> 2))) & 0x000000ff;
-		printk(KERN_CONT "Model D ");
-		break;
-	}
-
-	switch (brand) {
-	case EPS_BRAND_C7M:
-		printk(KERN_CONT "C7-M\n");
-		break;
-	case EPS_BRAND_C7:
-		printk(KERN_CONT "C7\n");
-		break;
-	case EPS_BRAND_EDEN:
-		printk(KERN_CONT "Eden\n");
-		break;
-	case EPS_BRAND_C7D:
-		printk(KERN_CONT "C7-D\n");
-		break;
-	case EPS_BRAND_C3:
-		printk(KERN_CONT "C3\n");
-		return -ENODEV;
-		break;
-	}
-	/* Enable Enhanced PowerSaver */
-	rdmsrl(MSR_IA32_MISC_ENABLE, val);
-	if (!(val & MSR_IA32_MISC_ENABLE_ENHANCED_SPEEDSTEP)) {
-		val |= MSR_IA32_MISC_ENABLE_ENHANCED_SPEEDSTEP;
-		wrmsrl(MSR_IA32_MISC_ENABLE, val);
-		/* Can be locked at 0 */
-		rdmsrl(MSR_IA32_MISC_ENABLE, val);
-		if (!(val & MSR_IA32_MISC_ENABLE_ENHANCED_SPEEDSTEP)) {
-			printk(KERN_INFO "eps: Can't enable Enhanced PowerSaver\n");
-			return -ENODEV;
-		}
-	}
-
-	/* Print voltage and multiplier */
-	rdmsr(MSR_IA32_PERF_STATUS, lo, hi);
-	current_voltage = lo & 0xff;
-	printk(KERN_INFO "eps: Current voltage = %dmV\n",
-			current_voltage * 16 + 700);
-	current_multiplier = (lo >> 8) & 0xff;
-	printk(KERN_INFO "eps: Current multiplier = %d\n", current_multiplier);
-
-	/* Print limits */
-	max_voltage = hi & 0xff;
-	printk(KERN_INFO "eps: Highest voltage = %dmV\n",
-			max_voltage * 16 + 700);
-	max_multiplier = (hi >> 8) & 0xff;
-	printk(KERN_INFO "eps: Highest multiplier = %d\n", max_multiplier);
-	min_voltage = (hi >> 16) & 0xff;
-	printk(KERN_INFO "eps: Lowest voltage = %dmV\n",
-			min_voltage * 16 + 700);
-	min_multiplier = (hi >> 24) & 0xff;
-	printk(KERN_INFO "eps: Lowest multiplier = %d\n", min_multiplier);
-
-	/* Sanity checks */
-	if (current_multiplier == 0 || max_multiplier == 0
-	    || min_multiplier == 0)
-		return -EINVAL;
-	if (current_multiplier > max_multiplier
-	    || max_multiplier <= min_multiplier)
-		return -EINVAL;
-	if (current_voltage > 0x1f || max_voltage > 0x1f)
-		return -EINVAL;
-	if (max_voltage < min_voltage)
-		return -EINVAL;
-
-	/* Calc FSB speed */
-	fsb = cpu_khz / current_multiplier;
-	/* Calc number of p-states supported */
-	if (brand == EPS_BRAND_C7M)
-		states = max_multiplier - min_multiplier + 1;
-	else
-		states = 2;
-
-	/* Allocate private data and frequency table for current cpu */
-	centaur = kzalloc(sizeof(struct eps_cpu_data)
-		    + (states + 1) * sizeof(struct cpufreq_frequency_table),
-		    GFP_KERNEL);
-	if (!centaur)
-		return -ENOMEM;
-	eps_cpu[0] = centaur;
-
-	/* Copy basic values */
-	centaur->fsb = fsb;
-
-	/* Fill frequency and MSR value table */
-	f_table = &centaur->freq_table[0];
-	if (brand != EPS_BRAND_C7M) {
-		f_table[0].frequency = fsb * min_multiplier;
-		f_table[0].index = (min_multiplier << 8) | min_voltage;
-		f_table[1].frequency = fsb * max_multiplier;
-		f_table[1].index = (max_multiplier << 8) | max_voltage;
-		f_table[2].frequency = CPUFREQ_TABLE_END;
-	} else {
-		k = 0;
-		step = ((max_voltage - min_voltage) * 256)
-			/ (max_multiplier - min_multiplier);
-		for (i = min_multiplier; i <= max_multiplier; i++) {
-			voltage = (k * step) / 256 + min_voltage;
-			f_table[k].frequency = fsb * i;
-			f_table[k].index = (i << 8) | voltage;
-			k++;
-		}
-		f_table[k].frequency = CPUFREQ_TABLE_END;
-	}
-
-	policy->cpuinfo.transition_latency = 140000; /* 844mV -> 700mV in ns */
-	policy->cur = fsb * current_multiplier;
-
-	ret = cpufreq_frequency_table_cpuinfo(policy, &centaur->freq_table[0]);
-	if (ret) {
-		kfree(centaur);
-		return ret;
-	}
-
-	cpufreq_frequency_table_get_attr(&centaur->freq_table[0], policy->cpu);
-	return 0;
-}
-
-static int eps_cpu_exit(struct cpufreq_policy *policy)
-{
-	unsigned int cpu = policy->cpu;
-	struct eps_cpu_data *centaur;
-	u32 lo, hi;
-
-	if (eps_cpu[cpu] == NULL)
-		return -ENODEV;
-	centaur = eps_cpu[cpu];
-
-	/* Get max frequency */
-	rdmsr(MSR_IA32_PERF_STATUS, lo, hi);
-	/* Set max frequency */
-	eps_set_state(centaur, cpu, hi & 0xffff);
-	/* Bye */
-	cpufreq_frequency_table_put_attr(policy->cpu);
-	kfree(eps_cpu[cpu]);
-	eps_cpu[cpu] = NULL;
-	return 0;
-}
-
-static struct freq_attr *eps_attr[] = {
-	&cpufreq_freq_attr_scaling_available_freqs,
-	NULL,
-};
-
-static struct cpufreq_driver eps_driver = {
-	.verify		= eps_verify,
-	.target		= eps_target,
-	.init		= eps_cpu_init,
-	.exit		= eps_cpu_exit,
-	.get		= eps_get,
-	.name		= "e_powersaver",
-	.owner		= THIS_MODULE,
-	.attr		= eps_attr,
-};
-
-static int __init eps_init(void)
-{
-	struct cpuinfo_x86 *c = &cpu_data(0);
-
-	/* This driver will work only on Centaur C7 processors with
-	 * Enhanced SpeedStep/PowerSaver registers */
-	if (c->x86_vendor != X86_VENDOR_CENTAUR
-	    || c->x86 != 6 || c->x86_model < 10)
-		return -ENODEV;
-	if (!cpu_has(c, X86_FEATURE_EST))
-		return -ENODEV;
-
-	if (cpufreq_register_driver(&eps_driver))
-		return -EINVAL;
-	return 0;
-}
-
-static void __exit eps_exit(void)
-{
-	cpufreq_unregister_driver(&eps_driver);
-}
-
-MODULE_AUTHOR("Rafal Bilski <rafalbilski@interia.pl>");
-MODULE_DESCRIPTION("Enhanced PowerSaver driver for VIA C7 CPU's.");
-MODULE_LICENSE("GPL");
-
-module_init(eps_init);
-module_exit(eps_exit);
diff -druN linux-2.6.39-libre/arch/x86/kernel/cpu/cpufreq/gx-suspmod.c linux-3.0-rc7-libre/arch/x86/kernel/cpu/cpufreq/gx-suspmod.c
--- linux-2.6.39-libre/arch/x86/kernel/cpu/cpufreq/gx-suspmod.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/kernel/cpu/cpufreq/gx-suspmod.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,517 +0,0 @@
-/*
- *	Cyrix MediaGX and NatSemi Geode Suspend Modulation
- *	(C) 2002 Zwane Mwaikambo <zwane@commfireservices.com>
- *	(C) 2002 Hiroshi Miura   <miura@da-cha.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
- *      version 2 as published by the Free Software Foundation
- *
- *      The author(s) of this software shall not be held liable for damages
- *      of any nature resulting due to the use of this software. This
- *      software is provided AS-IS with no warranties.
- *
- * Theoretical note:
- *
- *	(see Geode(tm) CS5530 manual (rev.4.1) page.56)
- *
- *	CPU frequency control on NatSemi Geode GX1/GXLV processor and CS55x0
- *	are based on Suspend Modulation.
- *
- *	Suspend Modulation works by asserting and de-asserting the SUSP# pin
- *	to CPU(GX1/GXLV) for configurable durations. When asserting SUSP#
- *	the CPU enters an idle state. GX1 stops its core clock when SUSP# is
- *	asserted then power consumption is reduced.
- *
- *	Suspend Modulation's OFF/ON duration are configurable
- *	with 'Suspend Modulation OFF Count Register'
- *	and 'Suspend Modulation ON Count Register'.
- *	These registers are 8bit counters that represent the number of
- *	32us intervals which the SUSP# pin is asserted(ON)/de-asserted(OFF)
- *	to the processor.
- *
- *	These counters define a ratio which is the effective frequency
- *	of operation of the system.
- *
- *			       OFF Count
- *	F_eff = Fgx * ----------------------
- *	                OFF Count + ON Count
- *
- *	0 <= On Count, Off Count <= 255
- *
- *	From these limits, we can get register values
- *
- *	off_duration + on_duration <= MAX_DURATION
- *	on_duration = off_duration * (stock_freq - freq) / freq
- *
- *      off_duration  =  (freq * DURATION) / stock_freq
- *      on_duration = DURATION - off_duration
- *
- *
- *---------------------------------------------------------------------------
- *
- * ChangeLog:
- *	Dec. 12, 2003	Hiroshi Miura <miura@da-cha.org>
- *		- fix on/off register mistake
- *		- fix cpu_khz calc when it stops cpu modulation.
- *
- *	Dec. 11, 2002	Hiroshi Miura <miura@da-cha.org>
- *		- rewrite for Cyrix MediaGX Cx5510/5520 and
- *		  NatSemi Geode Cs5530(A).
- *
- *	Jul. ??, 2002  Zwane Mwaikambo <zwane@commfireservices.com>
- *		- cs5530_mod patch for 2.4.19-rc1.
- *
- *---------------------------------------------------------------------------
- *
- * Todo
- *	Test on machines with 5510, 5530, 5530A
- */
-
-/************************************************************************
- *			Suspend Modulation - Definitions		*
- ************************************************************************/
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/smp.h>
-#include <linux/cpufreq.h>
-#include <linux/pci.h>
-#include <linux/errno.h>
-#include <linux/slab.h>
-
-#include <asm/processor-cyrix.h>
-
-/* PCI config registers, all at F0 */
-#define PCI_PMER1	0x80	/* power management enable register 1 */
-#define PCI_PMER2	0x81	/* power management enable register 2 */
-#define PCI_PMER3	0x82	/* power management enable register 3 */
-#define PCI_IRQTC	0x8c	/* irq speedup timer counter register:typical 2 to 4ms */
-#define PCI_VIDTC	0x8d	/* video speedup timer counter register: typical 50 to 100ms */
-#define PCI_MODOFF	0x94	/* suspend modulation OFF counter register, 1 = 32us */
-#define PCI_MODON	0x95	/* suspend modulation ON counter register */
-#define PCI_SUSCFG	0x96	/* suspend configuration register */
-
-/* PMER1 bits */
-#define GPM		(1<<0)	/* global power management */
-#define GIT		(1<<1)	/* globally enable PM device idle timers */
-#define GTR		(1<<2)	/* globally enable IO traps */
-#define IRQ_SPDUP	(1<<3)	/* disable clock throttle during interrupt handling */
-#define VID_SPDUP	(1<<4)	/* disable clock throttle during vga video handling */
-
-/* SUSCFG bits */
-#define SUSMOD		(1<<0)	/* enable/disable suspend modulation */
-/* the below is supported only with cs5530 (after rev.1.2)/cs5530A */
-#define SMISPDUP	(1<<1)	/* select how SMI re-enable suspend modulation: */
-				/* IRQTC timer or read SMI speedup disable reg.(F1BAR[08-09h]) */
-#define SUSCFG		(1<<2)	/* enable powering down a GXLV processor. "Special 3Volt Suspend" mode */
-/* the below is supported only with cs5530A */
-#define PWRSVE_ISA	(1<<3)	/* stop ISA clock  */
-#define PWRSVE		(1<<4)	/* active idle */
-
-struct gxfreq_params {
-	u8 on_duration;
-	u8 off_duration;
-	u8 pci_suscfg;
-	u8 pci_pmer1;
-	u8 pci_pmer2;
-	struct pci_dev *cs55x0;
-};
-
-static struct gxfreq_params *gx_params;
-static int stock_freq;
-
-/* PCI bus clock - defaults to 30.000 if cpu_khz is not available */
-static int pci_busclk;
-module_param(pci_busclk, int, 0444);
-
-/* maximum duration for which the cpu may be suspended
- * (32us * MAX_DURATION). If no parameter is given, this defaults
- * to 255.
- * Note that this leads to a maximum of 8 ms(!) where the CPU clock
- * is suspended -- processing power is just 0.39% of what it used to be,
- * though. 781.25 kHz(!) for a 200 MHz processor -- wow. */
-static int max_duration = 255;
-module_param(max_duration, int, 0444);
-
-/* For the default policy, we want at least some processing power
- * - let's say 5%. (min = maxfreq / POLICY_MIN_DIV)
- */
-#define POLICY_MIN_DIV 20
-
-
-#define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, \
-		"gx-suspmod", msg)
-
-/**
- * we can detect a core multipiler from dir0_lsb
- * from GX1 datasheet p.56,
- *	MULT[3:0]:
- *	0000 = SYSCLK multiplied by 4 (test only)
- *	0001 = SYSCLK multiplied by 10
- *	0010 = SYSCLK multiplied by 4
- *	0011 = SYSCLK multiplied by 6
- *	0100 = SYSCLK multiplied by 9
- *	0101 = SYSCLK multiplied by 5
- *	0110 = SYSCLK multiplied by 7
- *	0111 = SYSCLK multiplied by 8
- *              of 33.3MHz
- **/
-static int gx_freq_mult[16] = {
-		4, 10, 4, 6, 9, 5, 7, 8,
-		0, 0, 0, 0, 0, 0, 0, 0
-};
-
-
-/****************************************************************
- *	Low Level chipset interface				*
- ****************************************************************/
-static struct pci_device_id gx_chipset_tbl[] __initdata = {
-	{ PCI_VDEVICE(CYRIX, PCI_DEVICE_ID_CYRIX_5530_LEGACY), },
-	{ PCI_VDEVICE(CYRIX, PCI_DEVICE_ID_CYRIX_5520), },
-	{ PCI_VDEVICE(CYRIX, PCI_DEVICE_ID_CYRIX_5510), },
-	{ 0, },
-};
-
-static void gx_write_byte(int reg, int value)
-{
-	pci_write_config_byte(gx_params->cs55x0, reg, value);
-}
-
-/**
- * gx_detect_chipset:
- *
- **/
-static __init struct pci_dev *gx_detect_chipset(void)
-{
-	struct pci_dev *gx_pci = NULL;
-
-	/* check if CPU is a MediaGX or a Geode. */
-	if ((boot_cpu_data.x86_vendor != X86_VENDOR_NSC) &&
-	    (boot_cpu_data.x86_vendor != X86_VENDOR_CYRIX)) {
-		dprintk("error: no MediaGX/Geode processor found!\n");
-		return NULL;
-	}
-
-	/* detect which companion chip is used */
-	for_each_pci_dev(gx_pci) {
-		if ((pci_match_id(gx_chipset_tbl, gx_pci)) != NULL)
-			return gx_pci;
-	}
-
-	dprintk("error: no supported chipset found!\n");
-	return NULL;
-}
-
-/**
- * gx_get_cpuspeed:
- *
- * Finds out at which efficient frequency the Cyrix MediaGX/NatSemi
- * Geode CPU runs.
- */
-static unsigned int gx_get_cpuspeed(unsigned int cpu)
-{
-	if ((gx_params->pci_suscfg & SUSMOD) == 0)
-		return stock_freq;
-
-	return (stock_freq * gx_params->off_duration)
-		/ (gx_params->on_duration + gx_params->off_duration);
-}
-
-/**
- *      gx_validate_speed:
- *      determine current cpu speed
- *
- **/
-
-static unsigned int gx_validate_speed(unsigned int khz, u8 *on_duration,
-		u8 *off_duration)
-{
-	unsigned int i;
-	u8 tmp_on, tmp_off;
-	int old_tmp_freq = stock_freq;
-	int tmp_freq;
-
-	*off_duration = 1;
-	*on_duration = 0;
-
-	for (i = max_duration; i > 0; i--) {
-		tmp_off = ((khz * i) / stock_freq) & 0xff;
-		tmp_on = i - tmp_off;
-		tmp_freq = (stock_freq * tmp_off) / i;
-		/* if this relation is closer to khz, use this. If it's equal,
-		 * prefer it, too - lower latency */
-		if (abs(tmp_freq - khz) <= abs(old_tmp_freq - khz)) {
-			*on_duration = tmp_on;
-			*off_duration = tmp_off;
-			old_tmp_freq = tmp_freq;
-		}
-	}
-
-	return old_tmp_freq;
-}
-
-
-/**
- * gx_set_cpuspeed:
- * set cpu speed in khz.
- **/
-
-static void gx_set_cpuspeed(unsigned int khz)
-{
-	u8 suscfg, pmer1;
-	unsigned int new_khz;
-	unsigned long flags;
-	struct cpufreq_freqs freqs;
-
-	freqs.cpu = 0;
-	freqs.old = gx_get_cpuspeed(0);
-
-	new_khz = gx_validate_speed(khz, &gx_params->on_duration,
-			&gx_params->off_duration);
-
-	freqs.new = new_khz;
-
-	cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
-	local_irq_save(flags);
-
-
-
-	if (new_khz != stock_freq) {
-		/* if new khz == 100% of CPU speed, it is special case */
-		switch (gx_params->cs55x0->device) {
-		case PCI_DEVICE_ID_CYRIX_5530_LEGACY:
-			pmer1 = gx_params->pci_pmer1 | IRQ_SPDUP | VID_SPDUP;
-			/* FIXME: need to test other values -- Zwane,Miura */
-			/* typical 2 to 4ms */
-			gx_write_byte(PCI_IRQTC, 4);
-			/* typical 50 to 100ms */
-			gx_write_byte(PCI_VIDTC, 100);
-			gx_write_byte(PCI_PMER1, pmer1);
-
-			if (gx_params->cs55x0->revision < 0x10) {
-				/* CS5530(rev 1.2, 1.3) */
-				suscfg = gx_params->pci_suscfg|SUSMOD;
-			} else {
-				/* CS5530A,B.. */
-				suscfg = gx_params->pci_suscfg|SUSMOD|PWRSVE;
-			}
-			break;
-		case PCI_DEVICE_ID_CYRIX_5520:
-		case PCI_DEVICE_ID_CYRIX_5510:
-			suscfg = gx_params->pci_suscfg | SUSMOD;
-			break;
-		default:
-			local_irq_restore(flags);
-			dprintk("fatal: try to set unknown chipset.\n");
-			return;
-		}
-	} else {
-		suscfg = gx_params->pci_suscfg & ~(SUSMOD);
-		gx_params->off_duration = 0;
-		gx_params->on_duration = 0;
-		dprintk("suspend modulation disabled: cpu runs 100%% speed.\n");
-	}
-
-	gx_write_byte(PCI_MODOFF, gx_params->off_duration);
-	gx_write_byte(PCI_MODON, gx_params->on_duration);
-
-	gx_write_byte(PCI_SUSCFG, suscfg);
-	pci_read_config_byte(gx_params->cs55x0, PCI_SUSCFG, &suscfg);
-
-	local_irq_restore(flags);
-
-	gx_params->pci_suscfg = suscfg;
-
-	cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
-
-	dprintk("suspend modulation w/ duration of ON:%d us, OFF:%d us\n",
-		gx_params->on_duration * 32, gx_params->off_duration * 32);
-	dprintk("suspend modulation w/ clock speed: %d kHz.\n", freqs.new);
-}
-
-/****************************************************************
- *             High level functions                             *
- ****************************************************************/
-
-/*
- *	cpufreq_gx_verify: test if frequency range is valid
- *
- *	This function checks if a given frequency range in kHz is valid
- *      for the hardware supported by the driver.
- */
-
-static int cpufreq_gx_verify(struct cpufreq_policy *policy)
-{
-	unsigned int tmp_freq = 0;
-	u8 tmp1, tmp2;
-
-	if (!stock_freq || !policy)
-		return -EINVAL;
-
-	policy->cpu = 0;
-	cpufreq_verify_within_limits(policy, (stock_freq / max_duration),
-			stock_freq);
-
-	/* it needs to be assured that at least one supported frequency is
-	 * within policy->min and policy->max. If it is not, policy->max
-	 * needs to be increased until one freuqency is supported.
-	 * policy->min may not be decreased, though. This way we guarantee a
-	 * specific processing capacity.
-	 */
-	tmp_freq = gx_validate_speed(policy->min, &tmp1, &tmp2);
-	if (tmp_freq < policy->min)
-		tmp_freq += stock_freq / max_duration;
-	policy->min = tmp_freq;
-	if (policy->min > policy->max)
-		policy->max = tmp_freq;
-	tmp_freq = gx_validate_speed(policy->max, &tmp1, &tmp2);
-	if (tmp_freq > policy->max)
-		tmp_freq -= stock_freq / max_duration;
-	policy->max = tmp_freq;
-	if (policy->max < policy->min)
-		policy->max = policy->min;
-	cpufreq_verify_within_limits(policy, (stock_freq / max_duration),
-			stock_freq);
-
-	return 0;
-}
-
-/*
- *      cpufreq_gx_target:
- *
- */
-static int cpufreq_gx_target(struct cpufreq_policy *policy,
-			     unsigned int target_freq,
-			     unsigned int relation)
-{
-	u8 tmp1, tmp2;
-	unsigned int tmp_freq;
-
-	if (!stock_freq || !policy)
-		return -EINVAL;
-
-	policy->cpu = 0;
-
-	tmp_freq = gx_validate_speed(target_freq, &tmp1, &tmp2);
-	while (tmp_freq < policy->min) {
-		tmp_freq += stock_freq / max_duration;
-		tmp_freq = gx_validate_speed(tmp_freq, &tmp1, &tmp2);
-	}
-	while (tmp_freq > policy->max) {
-		tmp_freq -= stock_freq / max_duration;
-		tmp_freq = gx_validate_speed(tmp_freq, &tmp1, &tmp2);
-	}
-
-	gx_set_cpuspeed(tmp_freq);
-
-	return 0;
-}
-
-static int cpufreq_gx_cpu_init(struct cpufreq_policy *policy)
-{
-	unsigned int maxfreq, curfreq;
-
-	if (!policy || policy->cpu != 0)
-		return -ENODEV;
-
-	/* determine maximum frequency */
-	if (pci_busclk)
-		maxfreq = pci_busclk * gx_freq_mult[getCx86(CX86_DIR1) & 0x0f];
-	else if (cpu_khz)
-		maxfreq = cpu_khz;
-	else
-		maxfreq = 30000 * gx_freq_mult[getCx86(CX86_DIR1) & 0x0f];
-
-	stock_freq = maxfreq;
-	curfreq = gx_get_cpuspeed(0);
-
-	dprintk("cpu max frequency is %d.\n", maxfreq);
-	dprintk("cpu current frequency is %dkHz.\n", curfreq);
-
-	/* setup basic struct for cpufreq API */
-	policy->cpu = 0;
-
-	if (max_duration < POLICY_MIN_DIV)
-		policy->min = maxfreq / max_duration;
-	else
-		policy->min = maxfreq / POLICY_MIN_DIV;
-	policy->max = maxfreq;
-	policy->cur = curfreq;
-	policy->cpuinfo.min_freq = maxfreq / max_duration;
-	policy->cpuinfo.max_freq = maxfreq;
-	policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL;
-
-	return 0;
-}
-
-/*
- * cpufreq_gx_init:
- *   MediaGX/Geode GX initialize cpufreq driver
- */
-static struct cpufreq_driver gx_suspmod_driver = {
-	.get		= gx_get_cpuspeed,
-	.verify		= cpufreq_gx_verify,
-	.target		= cpufreq_gx_target,
-	.init		= cpufreq_gx_cpu_init,
-	.name		= "gx-suspmod",
-	.owner		= THIS_MODULE,
-};
-
-static int __init cpufreq_gx_init(void)
-{
-	int ret;
-	struct gxfreq_params *params;
-	struct pci_dev *gx_pci;
-
-	/* Test if we have the right hardware */
-	gx_pci = gx_detect_chipset();
-	if (gx_pci == NULL)
-		return -ENODEV;
-
-	/* check whether module parameters are sane */
-	if (max_duration > 0xff)
-		max_duration = 0xff;
-
-	dprintk("geode suspend modulation available.\n");
-
-	params = kzalloc(sizeof(struct gxfreq_params), GFP_KERNEL);
-	if (params == NULL)
-		return -ENOMEM;
-
-	params->cs55x0 = gx_pci;
-	gx_params = params;
-
-	/* keep cs55x0 configurations */
-	pci_read_config_byte(params->cs55x0, PCI_SUSCFG, &(params->pci_suscfg));
-	pci_read_config_byte(params->cs55x0, PCI_PMER1, &(params->pci_pmer1));
-	pci_read_config_byte(params->cs55x0, PCI_PMER2, &(params->pci_pmer2));
-	pci_read_config_byte(params->cs55x0, PCI_MODON, &(params->on_duration));
-	pci_read_config_byte(params->cs55x0, PCI_MODOFF,
-			&(params->off_duration));
-
-	ret = cpufreq_register_driver(&gx_suspmod_driver);
-	if (ret) {
-		kfree(params);
-		return ret;                   /* register error! */
-	}
-
-	return 0;
-}
-
-static void __exit cpufreq_gx_exit(void)
-{
-	cpufreq_unregister_driver(&gx_suspmod_driver);
-	pci_dev_put(gx_params->cs55x0);
-	kfree(gx_params);
-}
-
-MODULE_AUTHOR("Hiroshi Miura <miura@da-cha.org>");
-MODULE_DESCRIPTION("Cpufreq driver for Cyrix MediaGX and NatSemi Geode");
-MODULE_LICENSE("GPL");
-
-module_init(cpufreq_gx_init);
-module_exit(cpufreq_gx_exit);
-
diff -druN linux-2.6.39-libre/arch/x86/kernel/cpu/cpufreq/Kconfig linux-3.0-rc7-libre/arch/x86/kernel/cpu/cpufreq/Kconfig
--- linux-2.6.39-libre/arch/x86/kernel/cpu/cpufreq/Kconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/kernel/cpu/cpufreq/Kconfig	1969-12-31 19:00:00.000000000 -0500
@@ -1,266 +0,0 @@
-#
-# CPU Frequency scaling
-#
-
-menu "CPU Frequency scaling"
-
-source "drivers/cpufreq/Kconfig"
-
-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
-	depends on ACPI_PROCESSOR
-	help
-	  This driver adds a CPUFreq driver which utilizes the ACPI
-	  Processor Performance States.
-	  This driver also supports Intel Enhanced Speedstep.
-
-	  To compile this driver as a module, choose M here: the
-	  module will be called acpi-cpufreq.
-
-	  For details, take a look at <file:Documentation/cpu-freq/>.
-
-	  If in doubt, say N.
-
-config ELAN_CPUFREQ
-	tristate "AMD Elan SC400 and SC410"
-	select CPU_FREQ_TABLE
-	depends on X86_ELAN
-	---help---
-	  This adds the CPUFreq driver for AMD Elan SC400 and SC410
-	  processors.
-
-	  You need to specify the processor maximum speed as boot
-	  parameter: elanfreq=maxspeed (in kHz) or as module
-	  parameter "max_freq".
-
-	  For details, take a look at <file:Documentation/cpu-freq/>.
-
-	  If in doubt, say N.
-
-config SC520_CPUFREQ
-	tristate "AMD Elan SC520"
-	select CPU_FREQ_TABLE
-	depends on X86_ELAN
-	---help---
-	  This adds the CPUFreq driver for AMD Elan SC520 processor.
-
-	  For details, take a look at <file:Documentation/cpu-freq/>.
-
-	  If in doubt, say N.
-
-
-config X86_POWERNOW_K6
-	tristate "AMD Mobile K6-2/K6-3 PowerNow!"
-	select CPU_FREQ_TABLE
-	depends on X86_32
-	help
-	  This adds the CPUFreq driver for mobile AMD K6-2+ and mobile
-	  AMD K6-3+ processors.
-
-	  For details, take a look at <file:Documentation/cpu-freq/>.
-
-	  If in doubt, say N.
-
-config X86_POWERNOW_K7
-	tristate "AMD Mobile Athlon/Duron PowerNow!"
-	select CPU_FREQ_TABLE
-	depends on X86_32
-	help
-	  This adds the CPUFreq driver for mobile AMD K7 mobile processors.
-
-	  For details, take a look at <file:Documentation/cpu-freq/>.
-
-	  If in doubt, say N.
-
-config X86_POWERNOW_K7_ACPI
-	bool
-	depends on X86_POWERNOW_K7 && ACPI_PROCESSOR
-	depends on !(X86_POWERNOW_K7 = y && ACPI_PROCESSOR = m)
-	depends on X86_32
-	default y
-
-config X86_POWERNOW_K8
-	tristate "AMD Opteron/Athlon64 PowerNow!"
-	select CPU_FREQ_TABLE
-	depends on ACPI && ACPI_PROCESSOR
-	help
-	  This adds the CPUFreq driver for K8/K10 Opteron/Athlon64 processors.
-
-	  To compile this driver as a module, choose M here: the
-	  module will be called powernow-k8.
-
-	  For details, take a look at <file:Documentation/cpu-freq/>.
-
-config X86_GX_SUSPMOD
-	tristate "Cyrix MediaGX/NatSemi Geode Suspend Modulation"
-	depends on X86_32 && PCI
-	help
-	 This add the CPUFreq driver for NatSemi Geode processors which
-	 support suspend modulation.
-
-	 For details, take a look at <file:Documentation/cpu-freq/>.
-
-	 If in doubt, say N.
-
-config X86_SPEEDSTEP_CENTRINO
-	tristate "Intel Enhanced SpeedStep (deprecated)"
-	select CPU_FREQ_TABLE
-	select X86_SPEEDSTEP_CENTRINO_TABLE if X86_32
-	depends on X86_32 || (X86_64 && ACPI_PROCESSOR)
-	help
-	  This is deprecated and this functionality is now merged into
-	  acpi_cpufreq (X86_ACPI_CPUFREQ). Use that driver instead of
-	  speedstep_centrino.
-	  This adds the CPUFreq driver for Enhanced SpeedStep enabled
-	  mobile CPUs.  This means Intel Pentium M (Centrino) CPUs
-	  or 64bit enabled Intel Xeons.
-
-	  To compile this driver as a module, choose M here: the
-	  module will be called speedstep-centrino.
-
-	  For details, take a look at <file:Documentation/cpu-freq/>.
-
-	  If in doubt, say N.
-
-config X86_SPEEDSTEP_CENTRINO_TABLE
-	bool "Built-in tables for Banias CPUs"
-	depends on X86_32 && X86_SPEEDSTEP_CENTRINO
-	default y
-	help
-	  Use built-in tables for Banias CPUs if ACPI encoding
-	  is not available.
-
-	  If in doubt, say N.
-
-config X86_SPEEDSTEP_ICH
-	tristate "Intel Speedstep on ICH-M chipsets (ioport interface)"
-	select CPU_FREQ_TABLE
-	depends on X86_32
-	help
-	  This adds the CPUFreq driver for certain mobile Intel Pentium III
-	  (Coppermine), all mobile Intel Pentium III-M (Tualatin) and all
-	  mobile Intel Pentium 4 P4-M on systems which have an Intel ICH2,
-	  ICH3 or ICH4 southbridge.
-
-	  For details, take a look at <file:Documentation/cpu-freq/>.
-
-	  If in doubt, say N.
-
-config X86_SPEEDSTEP_SMI
-	tristate "Intel SpeedStep on 440BX/ZX/MX chipsets (SMI interface)"
-	select CPU_FREQ_TABLE
-	depends on X86_32 && EXPERIMENTAL
-	help
-	  This adds the CPUFreq driver for certain mobile Intel Pentium III
-	  (Coppermine), all mobile Intel Pentium III-M (Tualatin)
-	  on systems which have an Intel 440BX/ZX/MX southbridge.
-
-	  For details, take a look at <file:Documentation/cpu-freq/>.
-
-	  If in doubt, say N.
-
-config X86_P4_CLOCKMOD
-	tristate "Intel Pentium 4 clock modulation"
-	select CPU_FREQ_TABLE
-	help
-	  This adds the CPUFreq driver for Intel Pentium 4 / XEON
-	  processors.  When enabled it will lower CPU temperature by skipping
-	  clocks.
-
-	  This driver should be only used in exceptional
-	  circumstances when very low power is needed because it causes severe
-	  slowdowns and noticeable latencies.  Normally Speedstep should be used
-	  instead.
-
-	  To compile this driver as a module, choose M here: the
-	  module will be called p4-clockmod.
-
-	  For details, take a look at <file:Documentation/cpu-freq/>.
-
-	  Unless you are absolutely sure say N.
-
-config X86_CPUFREQ_NFORCE2
-	tristate "nVidia nForce2 FSB changing"
-	depends on X86_32 && EXPERIMENTAL
-	help
-	  This adds the CPUFreq driver for FSB changing on nVidia nForce2
-	  platforms.
-
-	  For details, take a look at <file:Documentation/cpu-freq/>.
-
-	  If in doubt, say N.
-
-config X86_LONGRUN
-	tristate "Transmeta LongRun"
-	depends on X86_32
-	help
-	  This adds the CPUFreq driver for Transmeta Crusoe and Efficeon processors
-	  which support LongRun.
-
-	  For details, take a look at <file:Documentation/cpu-freq/>.
-
-	  If in doubt, say N.
-
-config X86_LONGHAUL
-	tristate "VIA Cyrix III Longhaul"
-	select CPU_FREQ_TABLE
-	depends on X86_32 && ACPI_PROCESSOR
-	help
-	  This adds the CPUFreq driver for VIA Samuel/CyrixIII,
-	  VIA Cyrix Samuel/C3, VIA Cyrix Ezra and VIA Cyrix Ezra-T
-	  processors.
-
-	  For details, take a look at <file:Documentation/cpu-freq/>.
-
-	  If in doubt, say N.
-
-config X86_E_POWERSAVER
-	tristate "VIA C7 Enhanced PowerSaver (DANGEROUS)"
-	select CPU_FREQ_TABLE
-	depends on X86_32 && EXPERIMENTAL
-	help
-	  This adds the CPUFreq driver for VIA C7 processors.  However, this driver
-	  does not have any safeguards to prevent operating the CPU out of spec
-	  and is thus considered dangerous.  Please use the regular ACPI cpufreq
-	  driver, enabled by CONFIG_X86_ACPI_CPUFREQ.
-
-	  If in doubt, say N.
-
-comment "shared options"
-
-config X86_SPEEDSTEP_LIB
-	tristate
-	default (X86_SPEEDSTEP_ICH || X86_SPEEDSTEP_SMI || X86_P4_CLOCKMOD)
-
-config X86_SPEEDSTEP_RELAXED_CAP_CHECK
-	bool "Relaxed speedstep capability checks"
-	depends on X86_32 && (X86_SPEEDSTEP_SMI || X86_SPEEDSTEP_ICH)
-	help
-	  Don't perform all checks for a speedstep capable system which would
-	  normally be done. Some ancient or strange systems, though speedstep
-	  capable, don't always indicate that they are speedstep capable. This
-	  option lets the probing code bypass some of those checks if the
-	  parameter "relaxed_check=1" is passed to the module.
-
-endif	# CPU_FREQ
-
-endmenu
diff -druN linux-2.6.39-libre/arch/x86/kernel/cpu/cpufreq/longhaul.c linux-3.0-rc7-libre/arch/x86/kernel/cpu/cpufreq/longhaul.c
--- linux-2.6.39-libre/arch/x86/kernel/cpu/cpufreq/longhaul.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/kernel/cpu/cpufreq/longhaul.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,1029 +0,0 @@
-/*
- *  (C) 2001-2004  Dave Jones. <davej@redhat.com>
- *  (C) 2002  Padraig Brady. <padraig@antefacto.com>
- *
- *  Licensed under the terms of the GNU GPL License version 2.
- *  Based upon datasheets & sample CPUs kindly provided by VIA.
- *
- *  VIA have currently 3 different versions of Longhaul.
- *  Version 1 (Longhaul) uses the BCR2 MSR at 0x1147.
- *   It is present only in Samuel 1 (C5A), Samuel 2 (C5B) stepping 0.
- *  Version 2 of longhaul is backward compatible with v1, but adds
- *   LONGHAUL MSR for purpose of both frequency and voltage scaling.
- *   Present in Samuel 2 (steppings 1-7 only) (C5B), and Ezra (C5C).
- *  Version 3 of longhaul got renamed to Powersaver and redesigned
- *   to use only the POWERSAVER MSR at 0x110a.
- *   It is present in Ezra-T (C5M), Nehemiah (C5X) and above.
- *   It's pretty much the same feature wise to longhaul v2, though
- *   there is provision for scaling FSB too, but this doesn't work
- *   too well in practice so we don't even try to use this.
- *
- *  BIG FAT DISCLAIMER: Work in progress code. Possibly *dangerous*
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/init.h>
-#include <linux/cpufreq.h>
-#include <linux/pci.h>
-#include <linux/slab.h>
-#include <linux/string.h>
-#include <linux/delay.h>
-#include <linux/timex.h>
-#include <linux/io.h>
-#include <linux/acpi.h>
-
-#include <asm/msr.h>
-#include <acpi/processor.h>
-
-#include "longhaul.h"
-
-#define PFX "longhaul: "
-
-#define TYPE_LONGHAUL_V1	1
-#define TYPE_LONGHAUL_V2	2
-#define TYPE_POWERSAVER		3
-
-#define	CPU_SAMUEL	1
-#define	CPU_SAMUEL2	2
-#define	CPU_EZRA	3
-#define	CPU_EZRA_T	4
-#define	CPU_NEHEMIAH	5
-#define	CPU_NEHEMIAH_C	6
-
-/* Flags */
-#define USE_ACPI_C3		(1 << 1)
-#define USE_NORTHBRIDGE		(1 << 2)
-
-static int cpu_model;
-static unsigned int numscales = 16;
-static unsigned int fsb;
-
-static const struct mV_pos *vrm_mV_table;
-static const unsigned char *mV_vrm_table;
-
-static unsigned int highest_speed, lowest_speed; /* kHz */
-static unsigned int minmult, maxmult;
-static int can_scale_voltage;
-static struct acpi_processor *pr;
-static struct acpi_processor_cx *cx;
-static u32 acpi_regs_addr;
-static u8 longhaul_flags;
-static unsigned int longhaul_index;
-
-/* Module parameters */
-static int scale_voltage;
-static int disable_acpi_c3;
-static int revid_errata;
-
-#define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, \
-		"longhaul", msg)
-
-
-/* Clock ratios multiplied by 10 */
-static int mults[32];
-static int eblcr[32];
-static int longhaul_version;
-static struct cpufreq_frequency_table *longhaul_table;
-
-#ifdef CONFIG_CPU_FREQ_DEBUG
-static char speedbuffer[8];
-
-static char *print_speed(int speed)
-{
-	if (speed < 1000) {
-		snprintf(speedbuffer, sizeof(speedbuffer), "%dMHz", speed);
-		return speedbuffer;
-	}
-
-	if (speed%1000 == 0)
-		snprintf(speedbuffer, sizeof(speedbuffer),
-			"%dGHz", speed/1000);
-	else
-		snprintf(speedbuffer, sizeof(speedbuffer),
-			"%d.%dGHz", speed/1000, (speed%1000)/100);
-
-	return speedbuffer;
-}
-#endif
-
-
-static unsigned int calc_speed(int mult)
-{
-	int khz;
-	khz = (mult/10)*fsb;
-	if (mult%10)
-		khz += fsb/2;
-	khz *= 1000;
-	return khz;
-}
-
-
-static int longhaul_get_cpu_mult(void)
-{
-	unsigned long invalue = 0, lo, hi;
-
-	rdmsr(MSR_IA32_EBL_CR_POWERON, lo, hi);
-	invalue = (lo & (1<<22|1<<23|1<<24|1<<25))>>22;
-	if (longhaul_version == TYPE_LONGHAUL_V2 ||
-	    longhaul_version == TYPE_POWERSAVER) {
-		if (lo & (1<<27))
-			invalue += 16;
-	}
-	return eblcr[invalue];
-}
-
-/* For processor with BCR2 MSR */
-
-static void do_longhaul1(unsigned int mults_index)
-{
-	union msr_bcr2 bcr2;
-
-	rdmsrl(MSR_VIA_BCR2, bcr2.val);
-	/* Enable software clock multiplier */
-	bcr2.bits.ESOFTBF = 1;
-	bcr2.bits.CLOCKMUL = mults_index & 0xff;
-
-	/* Sync to timer tick */
-	safe_halt();
-	/* Change frequency on next halt or sleep */
-	wrmsrl(MSR_VIA_BCR2, bcr2.val);
-	/* Invoke transition */
-	ACPI_FLUSH_CPU_CACHE();
-	halt();
-
-	/* Disable software clock multiplier */
-	local_irq_disable();
-	rdmsrl(MSR_VIA_BCR2, bcr2.val);
-	bcr2.bits.ESOFTBF = 0;
-	wrmsrl(MSR_VIA_BCR2, bcr2.val);
-}
-
-/* For processor with Longhaul MSR */
-
-static void do_powersaver(int cx_address, unsigned int mults_index,
-			  unsigned int dir)
-{
-	union msr_longhaul longhaul;
-	u32 t;
-
-	rdmsrl(MSR_VIA_LONGHAUL, longhaul.val);
-	/* Setup new frequency */
-	if (!revid_errata)
-		longhaul.bits.RevisionKey = longhaul.bits.RevisionID;
-	else
-		longhaul.bits.RevisionKey = 0;
-	longhaul.bits.SoftBusRatio = mults_index & 0xf;
-	longhaul.bits.SoftBusRatio4 = (mults_index & 0x10) >> 4;
-	/* Setup new voltage */
-	if (can_scale_voltage)
-		longhaul.bits.SoftVID = (mults_index >> 8) & 0x1f;
-	/* Sync to timer tick */
-	safe_halt();
-	/* Raise voltage if necessary */
-	if (can_scale_voltage && dir) {
-		longhaul.bits.EnableSoftVID = 1;
-		wrmsrl(MSR_VIA_LONGHAUL, longhaul.val);
-		/* Change voltage */
-		if (!cx_address) {
-			ACPI_FLUSH_CPU_CACHE();
-			halt();
-		} else {
-			ACPI_FLUSH_CPU_CACHE();
-			/* Invoke C3 */
-			inb(cx_address);
-			/* Dummy op - must do something useless after P_LVL3
-			 * read */
-			t = inl(acpi_gbl_FADT.xpm_timer_block.address);
-		}
-		longhaul.bits.EnableSoftVID = 0;
-		wrmsrl(MSR_VIA_LONGHAUL, longhaul.val);
-	}
-
-	/* Change frequency on next halt or sleep */
-	longhaul.bits.EnableSoftBusRatio = 1;
-	wrmsrl(MSR_VIA_LONGHAUL, longhaul.val);
-	if (!cx_address) {
-		ACPI_FLUSH_CPU_CACHE();
-		halt();
-	} else {
-		ACPI_FLUSH_CPU_CACHE();
-		/* Invoke C3 */
-		inb(cx_address);
-		/* Dummy op - must do something useless after P_LVL3 read */
-		t = inl(acpi_gbl_FADT.xpm_timer_block.address);
-	}
-	/* Disable bus ratio bit */
-	longhaul.bits.EnableSoftBusRatio = 0;
-	wrmsrl(MSR_VIA_LONGHAUL, longhaul.val);
-
-	/* Reduce voltage if necessary */
-	if (can_scale_voltage && !dir) {
-		longhaul.bits.EnableSoftVID = 1;
-		wrmsrl(MSR_VIA_LONGHAUL, longhaul.val);
-		/* Change voltage */
-		if (!cx_address) {
-			ACPI_FLUSH_CPU_CACHE();
-			halt();
-		} else {
-			ACPI_FLUSH_CPU_CACHE();
-			/* Invoke C3 */
-			inb(cx_address);
-			/* Dummy op - must do something useless after P_LVL3
-			 * read */
-			t = inl(acpi_gbl_FADT.xpm_timer_block.address);
-		}
-		longhaul.bits.EnableSoftVID = 0;
-		wrmsrl(MSR_VIA_LONGHAUL, longhaul.val);
-	}
-}
-
-/**
- * longhaul_set_cpu_frequency()
- * @mults_index : bitpattern of the new multiplier.
- *
- * Sets a new clock ratio.
- */
-
-static void longhaul_setstate(unsigned int table_index)
-{
-	unsigned int mults_index;
-	int speed, mult;
-	struct cpufreq_freqs freqs;
-	unsigned long flags;
-	unsigned int pic1_mask, pic2_mask;
-	u16 bm_status = 0;
-	u32 bm_timeout = 1000;
-	unsigned int dir = 0;
-
-	mults_index = longhaul_table[table_index].index;
-	/* Safety precautions */
-	mult = mults[mults_index & 0x1f];
-	if (mult == -1)
-		return;
-	speed = calc_speed(mult);
-	if ((speed > highest_speed) || (speed < lowest_speed))
-		return;
-	/* Voltage transition before frequency transition? */
-	if (can_scale_voltage && longhaul_index < table_index)
-		dir = 1;
-
-	freqs.old = calc_speed(longhaul_get_cpu_mult());
-	freqs.new = speed;
-	freqs.cpu = 0; /* longhaul.c is UP only driver */
-
-	cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
-
-	dprintk("Setting to FSB:%dMHz Mult:%d.%dx (%s)\n",
-			fsb, mult/10, mult%10, print_speed(speed/1000));
-retry_loop:
-	preempt_disable();
-	local_irq_save(flags);
-
-	pic2_mask = inb(0xA1);
-	pic1_mask = inb(0x21);	/* works on C3. save mask. */
-	outb(0xFF, 0xA1);	/* Overkill */
-	outb(0xFE, 0x21);	/* TMR0 only */
-
-	/* Wait while PCI bus is busy. */
-	if (acpi_regs_addr && (longhaul_flags & USE_NORTHBRIDGE
-	    || ((pr != NULL) && pr->flags.bm_control))) {
-		bm_status = inw(acpi_regs_addr);
-		bm_status &= 1 << 4;
-		while (bm_status && bm_timeout) {
-			outw(1 << 4, acpi_regs_addr);
-			bm_timeout--;
-			bm_status = inw(acpi_regs_addr);
-			bm_status &= 1 << 4;
-		}
-	}
-
-	if (longhaul_flags & USE_NORTHBRIDGE) {
-		/* Disable AGP and PCI arbiters */
-		outb(3, 0x22);
-	} else if ((pr != NULL) && pr->flags.bm_control) {
-		/* Disable bus master arbitration */
-		acpi_write_bit_register(ACPI_BITREG_ARB_DISABLE, 1);
-	}
-	switch (longhaul_version) {
-
-	/*
-	 * Longhaul v1. (Samuel[C5A] and Samuel2 stepping 0[C5B])
-	 * Software controlled multipliers only.
-	 */
-	case TYPE_LONGHAUL_V1:
-		do_longhaul1(mults_index);
-		break;
-
-	/*
-	 * Longhaul v2 appears in Samuel2 Steppings 1->7 [C5B] and Ezra [C5C]
-	 *
-	 * Longhaul v3 (aka Powersaver). (Ezra-T [C5M] & Nehemiah [C5N])
-	 * Nehemiah can do FSB scaling too, but this has never been proven
-	 * to work in practice.
-	 */
-	case TYPE_LONGHAUL_V2:
-	case TYPE_POWERSAVER:
-		if (longhaul_flags & USE_ACPI_C3) {
-			/* Don't allow wakeup */
-			acpi_write_bit_register(ACPI_BITREG_BUS_MASTER_RLD, 0);
-			do_powersaver(cx->address, mults_index, dir);
-		} else {
-			do_powersaver(0, mults_index, dir);
-		}
-		break;
-	}
-
-	if (longhaul_flags & USE_NORTHBRIDGE) {
-		/* Enable arbiters */
-		outb(0, 0x22);
-	} else if ((pr != NULL) && pr->flags.bm_control) {
-		/* Enable bus master arbitration */
-		acpi_write_bit_register(ACPI_BITREG_ARB_DISABLE, 0);
-	}
-	outb(pic2_mask, 0xA1);	/* restore mask */
-	outb(pic1_mask, 0x21);
-
-	local_irq_restore(flags);
-	preempt_enable();
-
-	freqs.new = calc_speed(longhaul_get_cpu_mult());
-	/* Check if requested frequency is set. */
-	if (unlikely(freqs.new != speed)) {
-		printk(KERN_INFO PFX "Failed to set requested frequency!\n");
-		/* Revision ID = 1 but processor is expecting revision key
-		 * equal to 0. Jumpers at the bottom of processor will change
-		 * multiplier and FSB, but will not change bits in Longhaul
-		 * MSR nor enable voltage scaling. */
-		if (!revid_errata) {
-			printk(KERN_INFO PFX "Enabling \"Ignore Revision ID\" "
-						"option.\n");
-			revid_errata = 1;
-			msleep(200);
-			goto retry_loop;
-		}
-		/* Why ACPI C3 sometimes doesn't work is a mystery for me.
-		 * But it does happen. Processor is entering ACPI C3 state,
-		 * but it doesn't change frequency. I tried poking various
-		 * bits in northbridge registers, but without success. */
-		if (longhaul_flags & USE_ACPI_C3) {
-			printk(KERN_INFO PFX "Disabling ACPI C3 support.\n");
-			longhaul_flags &= ~USE_ACPI_C3;
-			if (revid_errata) {
-				printk(KERN_INFO PFX "Disabling \"Ignore "
-						"Revision ID\" option.\n");
-				revid_errata = 0;
-			}
-			msleep(200);
-			goto retry_loop;
-		}
-		/* This shouldn't happen. Longhaul ver. 2 was reported not
-		 * working on processors without voltage scaling, but with
-		 * RevID = 1. RevID errata will make things right. Just
-		 * to be 100% sure. */
-		if (longhaul_version == TYPE_LONGHAUL_V2) {
-			printk(KERN_INFO PFX "Switching to Longhaul ver. 1\n");
-			longhaul_version = TYPE_LONGHAUL_V1;
-			msleep(200);
-			goto retry_loop;
-		}
-	}
-	/* Report true CPU frequency */
-	cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
-
-	if (!bm_timeout)
-		printk(KERN_INFO PFX "Warning: Timeout while waiting for "
-				"idle PCI bus.\n");
-}
-
-/*
- * Centaur decided to make life a little more tricky.
- * Only longhaul v1 is allowed to read EBLCR BSEL[0:1].
- * Samuel2 and above have to try and guess what the FSB is.
- * We do this by assuming we booted at maximum multiplier, and interpolate
- * between that value multiplied by possible FSBs and cpu_mhz which
- * was calculated at boot time. Really ugly, but no other way to do this.
- */
-
-#define ROUNDING	0xf
-
-static int guess_fsb(int mult)
-{
-	int speed = cpu_khz / 1000;
-	int i;
-	int speeds[] = { 666, 1000, 1333, 2000 };
-	int f_max, f_min;
-
-	for (i = 0; i < 4; i++) {
-		f_max = ((speeds[i] * mult) + 50) / 100;
-		f_max += (ROUNDING / 2);
-		f_min = f_max - ROUNDING;
-		if ((speed <= f_max) && (speed >= f_min))
-			return speeds[i] / 10;
-	}
-	return 0;
-}
-
-
-static int __cpuinit longhaul_get_ranges(void)
-{
-	unsigned int i, j, k = 0;
-	unsigned int ratio;
-	int mult;
-
-	/* Get current frequency */
-	mult = longhaul_get_cpu_mult();
-	if (mult == -1) {
-		printk(KERN_INFO PFX "Invalid (reserved) multiplier!\n");
-		return -EINVAL;
-	}
-	fsb = guess_fsb(mult);
-	if (fsb == 0) {
-		printk(KERN_INFO PFX "Invalid (reserved) FSB!\n");
-		return -EINVAL;
-	}
-	/* Get max multiplier - as we always did.
-	 * Longhaul MSR is useful only when voltage scaling is enabled.
-	 * C3 is booting at max anyway. */
-	maxmult = mult;
-	/* Get min multiplier */
-	switch (cpu_model) {
-	case CPU_NEHEMIAH:
-		minmult = 50;
-		break;
-	case CPU_NEHEMIAH_C:
-		minmult = 40;
-		break;
-	default:
-		minmult = 30;
-		break;
-	}
-
-	dprintk("MinMult:%d.%dx MaxMult:%d.%dx\n",
-		 minmult/10, minmult%10, maxmult/10, maxmult%10);
-
-	highest_speed = calc_speed(maxmult);
-	lowest_speed = calc_speed(minmult);
-	dprintk("FSB:%dMHz  Lowest speed: %s   Highest speed:%s\n", fsb,
-		 print_speed(lowest_speed/1000),
-		 print_speed(highest_speed/1000));
-
-	if (lowest_speed == highest_speed) {
-		printk(KERN_INFO PFX "highestspeed == lowest, aborting.\n");
-		return -EINVAL;
-	}
-	if (lowest_speed > highest_speed) {
-		printk(KERN_INFO PFX "nonsense! lowest (%d > %d) !\n",
-			lowest_speed, highest_speed);
-		return -EINVAL;
-	}
-
-	longhaul_table = kmalloc((numscales + 1) * sizeof(*longhaul_table),
-			GFP_KERNEL);
-	if (!longhaul_table)
-		return -ENOMEM;
-
-	for (j = 0; j < numscales; j++) {
-		ratio = mults[j];
-		if (ratio == -1)
-			continue;
-		if (ratio > maxmult || ratio < minmult)
-			continue;
-		longhaul_table[k].frequency = calc_speed(ratio);
-		longhaul_table[k].index	= j;
-		k++;
-	}
-	if (k <= 1) {
-		kfree(longhaul_table);
-		return -ENODEV;
-	}
-	/* Sort */
-	for (j = 0; j < k - 1; j++) {
-		unsigned int min_f, min_i;
-		min_f = longhaul_table[j].frequency;
-		min_i = j;
-		for (i = j + 1; i < k; i++) {
-			if (longhaul_table[i].frequency < min_f) {
-				min_f = longhaul_table[i].frequency;
-				min_i = i;
-			}
-		}
-		if (min_i != j) {
-			swap(longhaul_table[j].frequency,
-			     longhaul_table[min_i].frequency);
-			swap(longhaul_table[j].index,
-			     longhaul_table[min_i].index);
-		}
-	}
-
-	longhaul_table[k].frequency = CPUFREQ_TABLE_END;
-
-	/* Find index we are running on */
-	for (j = 0; j < k; j++) {
-		if (mults[longhaul_table[j].index & 0x1f] == mult) {
-			longhaul_index = j;
-			break;
-		}
-	}
-	return 0;
-}
-
-
-static void __cpuinit longhaul_setup_voltagescaling(void)
-{
-	union msr_longhaul longhaul;
-	struct mV_pos minvid, maxvid, vid;
-	unsigned int j, speed, pos, kHz_step, numvscales;
-	int min_vid_speed;
-
-	rdmsrl(MSR_VIA_LONGHAUL, longhaul.val);
-	if (!(longhaul.bits.RevisionID & 1)) {
-		printk(KERN_INFO PFX "Voltage scaling not supported by CPU.\n");
-		return;
-	}
-
-	if (!longhaul.bits.VRMRev) {
-		printk(KERN_INFO PFX "VRM 8.5\n");
-		vrm_mV_table = &vrm85_mV[0];
-		mV_vrm_table = &mV_vrm85[0];
-	} else {
-		printk(KERN_INFO PFX "Mobile VRM\n");
-		if (cpu_model < CPU_NEHEMIAH)
-			return;
-		vrm_mV_table = &mobilevrm_mV[0];
-		mV_vrm_table = &mV_mobilevrm[0];
-	}
-
-	minvid = vrm_mV_table[longhaul.bits.MinimumVID];
-	maxvid = vrm_mV_table[longhaul.bits.MaximumVID];
-
-	if (minvid.mV == 0 || maxvid.mV == 0 || minvid.mV > maxvid.mV) {
-		printk(KERN_INFO PFX "Bogus values Min:%d.%03d Max:%d.%03d. "
-					"Voltage scaling disabled.\n",
-					minvid.mV/1000, minvid.mV%1000,
-					maxvid.mV/1000, maxvid.mV%1000);
-		return;
-	}
-
-	if (minvid.mV == maxvid.mV) {
-		printk(KERN_INFO PFX "Claims to support voltage scaling but "
-				"min & max are both %d.%03d. "
-				"Voltage scaling disabled\n",
-				maxvid.mV/1000, maxvid.mV%1000);
-		return;
-	}
-
-	/* How many voltage steps*/
-	numvscales = maxvid.pos - minvid.pos + 1;
-	printk(KERN_INFO PFX
-		"Max VID=%d.%03d  "
-		"Min VID=%d.%03d, "
-		"%d possible voltage scales\n",
-		maxvid.mV/1000, maxvid.mV%1000,
-		minvid.mV/1000, minvid.mV%1000,
-		numvscales);
-
-	/* Calculate max frequency at min voltage */
-	j = longhaul.bits.MinMHzBR;
-	if (longhaul.bits.MinMHzBR4)
-		j += 16;
-	min_vid_speed = eblcr[j];
-	if (min_vid_speed == -1)
-		return;
-	switch (longhaul.bits.MinMHzFSB) {
-	case 0:
-		min_vid_speed *= 13333;
-		break;
-	case 1:
-		min_vid_speed *= 10000;
-		break;
-	case 3:
-		min_vid_speed *= 6666;
-		break;
-	default:
-		return;
-		break;
-	}
-	if (min_vid_speed >= highest_speed)
-		return;
-	/* Calculate kHz for one voltage step */
-	kHz_step = (highest_speed - min_vid_speed) / numvscales;
-
-	j = 0;
-	while (longhaul_table[j].frequency != CPUFREQ_TABLE_END) {
-		speed = longhaul_table[j].frequency;
-		if (speed > min_vid_speed)
-			pos = (speed - min_vid_speed) / kHz_step + minvid.pos;
-		else
-			pos = minvid.pos;
-		longhaul_table[j].index |= mV_vrm_table[pos] << 8;
-		vid = vrm_mV_table[mV_vrm_table[pos]];
-		printk(KERN_INFO PFX "f: %d kHz, index: %d, vid: %d mV\n",
-				speed, j, vid.mV);
-		j++;
-	}
-
-	can_scale_voltage = 1;
-	printk(KERN_INFO PFX "Voltage scaling enabled.\n");
-}
-
-
-static int longhaul_verify(struct cpufreq_policy *policy)
-{
-	return cpufreq_frequency_table_verify(policy, longhaul_table);
-}
-
-
-static int longhaul_target(struct cpufreq_policy *policy,
-			    unsigned int target_freq, unsigned int relation)
-{
-	unsigned int table_index = 0;
-	unsigned int i;
-	unsigned int dir = 0;
-	u8 vid, current_vid;
-
-	if (cpufreq_frequency_table_target(policy, longhaul_table, target_freq,
-				relation, &table_index))
-		return -EINVAL;
-
-	/* Don't set same frequency again */
-	if (longhaul_index == table_index)
-		return 0;
-
-	if (!can_scale_voltage)
-		longhaul_setstate(table_index);
-	else {
-		/* On test system voltage transitions exceeding single
-		 * step up or down were turning motherboard off. Both
-		 * "ondemand" and "userspace" are unsafe. C7 is doing
-		 * this in hardware, C3 is old and we need to do this
-		 * in software. */
-		i = longhaul_index;
-		current_vid = (longhaul_table[longhaul_index].index >> 8);
-		current_vid &= 0x1f;
-		if (table_index > longhaul_index)
-			dir = 1;
-		while (i != table_index) {
-			vid = (longhaul_table[i].index >> 8) & 0x1f;
-			if (vid != current_vid) {
-				longhaul_setstate(i);
-				current_vid = vid;
-				msleep(200);
-			}
-			if (dir)
-				i++;
-			else
-				i--;
-		}
-		longhaul_setstate(table_index);
-	}
-	longhaul_index = table_index;
-	return 0;
-}
-
-
-static unsigned int longhaul_get(unsigned int cpu)
-{
-	if (cpu)
-		return 0;
-	return calc_speed(longhaul_get_cpu_mult());
-}
-
-static acpi_status longhaul_walk_callback(acpi_handle obj_handle,
-					  u32 nesting_level,
-					  void *context, void **return_value)
-{
-	struct acpi_device *d;
-
-	if (acpi_bus_get_device(obj_handle, &d))
-		return 0;
-
-	*return_value = acpi_driver_data(d);
-	return 1;
-}
-
-/* VIA don't support PM2 reg, but have something similar */
-static int enable_arbiter_disable(void)
-{
-	struct pci_dev *dev;
-	int status = 1;
-	int reg;
-	u8 pci_cmd;
-
-	/* Find PLE133 host bridge */
-	reg = 0x78;
-	dev = pci_get_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8601_0,
-			     NULL);
-	/* Find PM133/VT8605 host bridge */
-	if (dev == NULL)
-		dev = pci_get_device(PCI_VENDOR_ID_VIA,
-				     PCI_DEVICE_ID_VIA_8605_0, NULL);
-	/* Find CLE266 host bridge */
-	if (dev == NULL) {
-		reg = 0x76;
-		dev = pci_get_device(PCI_VENDOR_ID_VIA,
-				     PCI_DEVICE_ID_VIA_862X_0, NULL);
-		/* Find CN400 V-Link host bridge */
-		if (dev == NULL)
-			dev = pci_get_device(PCI_VENDOR_ID_VIA, 0x7259, NULL);
-	}
-	if (dev != NULL) {
-		/* Enable access to port 0x22 */
-		pci_read_config_byte(dev, reg, &pci_cmd);
-		if (!(pci_cmd & 1<<7)) {
-			pci_cmd |= 1<<7;
-			pci_write_config_byte(dev, reg, pci_cmd);
-			pci_read_config_byte(dev, reg, &pci_cmd);
-			if (!(pci_cmd & 1<<7)) {
-				printk(KERN_ERR PFX
-					"Can't enable access to port 0x22.\n");
-				status = 0;
-			}
-		}
-		pci_dev_put(dev);
-		return status;
-	}
-	return 0;
-}
-
-static int longhaul_setup_southbridge(void)
-{
-	struct pci_dev *dev;
-	u8 pci_cmd;
-
-	/* Find VT8235 southbridge */
-	dev = pci_get_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8235, NULL);
-	if (dev == NULL)
-		/* Find VT8237 southbridge */
-		dev = pci_get_device(PCI_VENDOR_ID_VIA,
-				     PCI_DEVICE_ID_VIA_8237, NULL);
-	if (dev != NULL) {
-		/* Set transition time to max */
-		pci_read_config_byte(dev, 0xec, &pci_cmd);
-		pci_cmd &= ~(1 << 2);
-		pci_write_config_byte(dev, 0xec, pci_cmd);
-		pci_read_config_byte(dev, 0xe4, &pci_cmd);
-		pci_cmd &= ~(1 << 7);
-		pci_write_config_byte(dev, 0xe4, pci_cmd);
-		pci_read_config_byte(dev, 0xe5, &pci_cmd);
-		pci_cmd |= 1 << 7;
-		pci_write_config_byte(dev, 0xe5, pci_cmd);
-		/* Get address of ACPI registers block*/
-		pci_read_config_byte(dev, 0x81, &pci_cmd);
-		if (pci_cmd & 1 << 7) {
-			pci_read_config_dword(dev, 0x88, &acpi_regs_addr);
-			acpi_regs_addr &= 0xff00;
-			printk(KERN_INFO PFX "ACPI I/O at 0x%x\n",
-					acpi_regs_addr);
-		}
-
-		pci_dev_put(dev);
-		return 1;
-	}
-	return 0;
-}
-
-static int __cpuinit longhaul_cpu_init(struct cpufreq_policy *policy)
-{
-	struct cpuinfo_x86 *c = &cpu_data(0);
-	char *cpuname = NULL;
-	int ret;
-	u32 lo, hi;
-
-	/* Check what we have on this motherboard */
-	switch (c->x86_model) {
-	case 6:
-		cpu_model = CPU_SAMUEL;
-		cpuname = "C3 'Samuel' [C5A]";
-		longhaul_version = TYPE_LONGHAUL_V1;
-		memcpy(mults, samuel1_mults, sizeof(samuel1_mults));
-		memcpy(eblcr, samuel1_eblcr, sizeof(samuel1_eblcr));
-		break;
-
-	case 7:
-		switch (c->x86_mask) {
-		case 0:
-			longhaul_version = TYPE_LONGHAUL_V1;
-			cpu_model = CPU_SAMUEL2;
-			cpuname = "C3 'Samuel 2' [C5B]";
-			/* Note, this is not a typo, early Samuel2's had
-			 * Samuel1 ratios. */
-			memcpy(mults, samuel1_mults, sizeof(samuel1_mults));
-			memcpy(eblcr, samuel2_eblcr, sizeof(samuel2_eblcr));
-			break;
-		case 1 ... 15:
-			longhaul_version = TYPE_LONGHAUL_V2;
-			if (c->x86_mask < 8) {
-				cpu_model = CPU_SAMUEL2;
-				cpuname = "C3 'Samuel 2' [C5B]";
-			} else {
-				cpu_model = CPU_EZRA;
-				cpuname = "C3 'Ezra' [C5C]";
-			}
-			memcpy(mults, ezra_mults, sizeof(ezra_mults));
-			memcpy(eblcr, ezra_eblcr, sizeof(ezra_eblcr));
-			break;
-		}
-		break;
-
-	case 8:
-		cpu_model = CPU_EZRA_T;
-		cpuname = "C3 'Ezra-T' [C5M]";
-		longhaul_version = TYPE_POWERSAVER;
-		numscales = 32;
-		memcpy(mults, ezrat_mults, sizeof(ezrat_mults));
-		memcpy(eblcr, ezrat_eblcr, sizeof(ezrat_eblcr));
-		break;
-
-	case 9:
-		longhaul_version = TYPE_POWERSAVER;
-		numscales = 32;
-		memcpy(mults, nehemiah_mults, sizeof(nehemiah_mults));
-		memcpy(eblcr, nehemiah_eblcr, sizeof(nehemiah_eblcr));
-		switch (c->x86_mask) {
-		case 0 ... 1:
-			cpu_model = CPU_NEHEMIAH;
-			cpuname = "C3 'Nehemiah A' [C5XLOE]";
-			break;
-		case 2 ... 4:
-			cpu_model = CPU_NEHEMIAH;
-			cpuname = "C3 'Nehemiah B' [C5XLOH]";
-			break;
-		case 5 ... 15:
-			cpu_model = CPU_NEHEMIAH_C;
-			cpuname = "C3 'Nehemiah C' [C5P]";
-			break;
-		}
-		break;
-
-	default:
-		cpuname = "Unknown";
-		break;
-	}
-	/* Check Longhaul ver. 2 */
-	if (longhaul_version == TYPE_LONGHAUL_V2) {
-		rdmsr(MSR_VIA_LONGHAUL, lo, hi);
-		if (lo == 0 && hi == 0)
-			/* Looks like MSR isn't present */
-			longhaul_version = TYPE_LONGHAUL_V1;
-	}
-
-	printk(KERN_INFO PFX "VIA %s CPU detected.  ", cpuname);
-	switch (longhaul_version) {
-	case TYPE_LONGHAUL_V1:
-	case TYPE_LONGHAUL_V2:
-		printk(KERN_CONT "Longhaul v%d supported.\n", longhaul_version);
-		break;
-	case TYPE_POWERSAVER:
-		printk(KERN_CONT "Powersaver supported.\n");
-		break;
-	};
-
-	/* Doesn't hurt */
-	longhaul_setup_southbridge();
-
-	/* Find ACPI data for processor */
-	acpi_walk_namespace(ACPI_TYPE_PROCESSOR, ACPI_ROOT_OBJECT,
-				ACPI_UINT32_MAX, &longhaul_walk_callback, NULL,
-				NULL, (void *)&pr);
-
-	/* Check ACPI support for C3 state */
-	if (pr != NULL && longhaul_version == TYPE_POWERSAVER) {
-		cx = &pr->power.states[ACPI_STATE_C3];
-		if (cx->address > 0 && cx->latency <= 1000)
-			longhaul_flags |= USE_ACPI_C3;
-	}
-	/* Disable if it isn't working */
-	if (disable_acpi_c3)
-		longhaul_flags &= ~USE_ACPI_C3;
-	/* Check if northbridge is friendly */
-	if (enable_arbiter_disable())
-		longhaul_flags |= USE_NORTHBRIDGE;
-
-	/* Check ACPI support for bus master arbiter disable */
-	if (!(longhaul_flags & USE_ACPI_C3
-	     || longhaul_flags & USE_NORTHBRIDGE)
-	    && ((pr == NULL) || !(pr->flags.bm_control))) {
-		printk(KERN_ERR PFX
-			"No ACPI support. Unsupported northbridge.\n");
-		return -ENODEV;
-	}
-
-	if (longhaul_flags & USE_NORTHBRIDGE)
-		printk(KERN_INFO PFX "Using northbridge support.\n");
-	if (longhaul_flags & USE_ACPI_C3)
-		printk(KERN_INFO PFX "Using ACPI support.\n");
-
-	ret = longhaul_get_ranges();
-	if (ret != 0)
-		return ret;
-
-	if ((longhaul_version != TYPE_LONGHAUL_V1) && (scale_voltage != 0))
-		longhaul_setup_voltagescaling();
-
-	policy->cpuinfo.transition_latency = 200000;	/* nsec */
-	policy->cur = calc_speed(longhaul_get_cpu_mult());
-
-	ret = cpufreq_frequency_table_cpuinfo(policy, longhaul_table);
-	if (ret)
-		return ret;
-
-	cpufreq_frequency_table_get_attr(longhaul_table, policy->cpu);
-
-	return 0;
-}
-
-static int __devexit longhaul_cpu_exit(struct cpufreq_policy *policy)
-{
-	cpufreq_frequency_table_put_attr(policy->cpu);
-	return 0;
-}
-
-static struct freq_attr *longhaul_attr[] = {
-	&cpufreq_freq_attr_scaling_available_freqs,
-	NULL,
-};
-
-static struct cpufreq_driver longhaul_driver = {
-	.verify	= longhaul_verify,
-	.target	= longhaul_target,
-	.get	= longhaul_get,
-	.init	= longhaul_cpu_init,
-	.exit	= __devexit_p(longhaul_cpu_exit),
-	.name	= "longhaul",
-	.owner	= THIS_MODULE,
-	.attr	= longhaul_attr,
-};
-
-
-static int __init longhaul_init(void)
-{
-	struct cpuinfo_x86 *c = &cpu_data(0);
-
-	if (c->x86_vendor != X86_VENDOR_CENTAUR || c->x86 != 6)
-		return -ENODEV;
-
-#ifdef CONFIG_SMP
-	if (num_online_cpus() > 1) {
-		printk(KERN_ERR PFX "More than 1 CPU detected, "
-				"longhaul disabled.\n");
-		return -ENODEV;
-	}
-#endif
-#ifdef CONFIG_X86_IO_APIC
-	if (cpu_has_apic) {
-		printk(KERN_ERR PFX "APIC detected. Longhaul is currently "
-				"broken in this configuration.\n");
-		return -ENODEV;
-	}
-#endif
-	switch (c->x86_model) {
-	case 6 ... 9:
-		return cpufreq_register_driver(&longhaul_driver);
-	case 10:
-		printk(KERN_ERR PFX "Use acpi-cpufreq driver for VIA C7\n");
-	default:
-		;
-	}
-
-	return -ENODEV;
-}
-
-
-static void __exit longhaul_exit(void)
-{
-	int i;
-
-	for (i = 0; i < numscales; i++) {
-		if (mults[i] == maxmult) {
-			longhaul_setstate(i);
-			break;
-		}
-	}
-
-	cpufreq_unregister_driver(&longhaul_driver);
-	kfree(longhaul_table);
-}
-
-/* Even if BIOS is exporting ACPI C3 state, and it is used
- * with success when CPU is idle, this state doesn't
- * trigger frequency transition in some cases. */
-module_param(disable_acpi_c3, int, 0644);
-MODULE_PARM_DESC(disable_acpi_c3, "Don't use ACPI C3 support");
-/* Change CPU voltage with frequency. Very useful to save
- * power, but most VIA C3 processors aren't supporting it. */
-module_param(scale_voltage, int, 0644);
-MODULE_PARM_DESC(scale_voltage, "Scale voltage of processor");
-/* Force revision key to 0 for processors which doesn't
- * support voltage scaling, but are introducing itself as
- * such. */
-module_param(revid_errata, int, 0644);
-MODULE_PARM_DESC(revid_errata, "Ignore CPU Revision ID");
-
-MODULE_AUTHOR("Dave Jones <davej@redhat.com>");
-MODULE_DESCRIPTION("Longhaul driver for VIA Cyrix processors.");
-MODULE_LICENSE("GPL");
-
-late_initcall(longhaul_init);
-module_exit(longhaul_exit);
diff -druN linux-2.6.39-libre/arch/x86/kernel/cpu/cpufreq/longhaul.h linux-3.0-rc7-libre/arch/x86/kernel/cpu/cpufreq/longhaul.h
--- linux-2.6.39-libre/arch/x86/kernel/cpu/cpufreq/longhaul.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/kernel/cpu/cpufreq/longhaul.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,353 +0,0 @@
-/*
- *  longhaul.h
- *  (C) 2003 Dave Jones.
- *
- *  Licensed under the terms of the GNU GPL License version 2.
- *
- *  VIA-specific information
- */
-
-union msr_bcr2 {
-	struct {
-		unsigned Reseved:19,	// 18:0
-		ESOFTBF:1,		// 19
-		Reserved2:3,		// 22:20
-		CLOCKMUL:4,		// 26:23
-		Reserved3:5;		// 31:27
-	} bits;
-	unsigned long val;
-};
-
-union msr_longhaul {
-	struct {
-		unsigned RevisionID:4,	// 3:0
-		RevisionKey:4,		// 7:4
-		EnableSoftBusRatio:1,	// 8
-		EnableSoftVID:1,	// 9
-		EnableSoftBSEL:1,	// 10
-		Reserved:3,		// 11:13
-		SoftBusRatio4:1,	// 14
-		VRMRev:1,		// 15
-		SoftBusRatio:4,		// 19:16
-		SoftVID:5,		// 24:20
-		Reserved2:3,		// 27:25
-		SoftBSEL:2,		// 29:28
-		Reserved3:2,		// 31:30
-		MaxMHzBR:4,		// 35:32
-		MaximumVID:5,		// 40:36
-		MaxMHzFSB:2,		// 42:41
-		MaxMHzBR4:1,		// 43
-		Reserved4:4,		// 47:44
-		MinMHzBR:4,		// 51:48
-		MinimumVID:5,		// 56:52
-		MinMHzFSB:2,		// 58:57
-		MinMHzBR4:1,		// 59
-		Reserved5:4;		// 63:60
-	} bits;
-	unsigned long long val;
-};
-
-/*
- * Clock ratio tables. Div/Mod by 10 to get ratio.
- * The eblcr values specify the ratio read from the CPU.
- * The mults values specify what to write to the CPU.
- */
-
-/*
- * VIA C3 Samuel 1  & Samuel 2 (stepping 0)
- */
-static const int __cpuinitdata samuel1_mults[16] = {
-	-1, /* 0000 -> RESERVED */
-	30, /* 0001 ->  3.0x */
-	40, /* 0010 ->  4.0x */
-	-1, /* 0011 -> RESERVED */
-	-1, /* 0100 -> RESERVED */
-	35, /* 0101 ->  3.5x */
-	45, /* 0110 ->  4.5x */
-	55, /* 0111 ->  5.5x */
-	60, /* 1000 ->  6.0x */
-	70, /* 1001 ->  7.0x */
-	80, /* 1010 ->  8.0x */
-	50, /* 1011 ->  5.0x */
-	65, /* 1100 ->  6.5x */
-	75, /* 1101 ->  7.5x */
-	-1, /* 1110 -> RESERVED */
-	-1, /* 1111 -> RESERVED */
-};
-
-static const int __cpuinitdata samuel1_eblcr[16] = {
-	50, /* 0000 -> RESERVED */
-	30, /* 0001 ->  3.0x */
-	40, /* 0010 ->  4.0x */
-	-1, /* 0011 -> RESERVED */
-	55, /* 0100 ->  5.5x */
-	35, /* 0101 ->  3.5x */
-	45, /* 0110 ->  4.5x */
-	-1, /* 0111 -> RESERVED */
-	-1, /* 1000 -> RESERVED */
-	70, /* 1001 ->  7.0x */
-	80, /* 1010 ->  8.0x */
-	60, /* 1011 ->  6.0x */
-	-1, /* 1100 -> RESERVED */
-	75, /* 1101 ->  7.5x */
-	-1, /* 1110 -> RESERVED */
-	65, /* 1111 ->  6.5x */
-};
-
-/*
- * VIA C3 Samuel2 Stepping 1->15
- */
-static const int __cpuinitdata samuel2_eblcr[16] = {
-	50,  /* 0000 ->  5.0x */
-	30,  /* 0001 ->  3.0x */
-	40,  /* 0010 ->  4.0x */
-	100, /* 0011 -> 10.0x */
-	55,  /* 0100 ->  5.5x */
-	35,  /* 0101 ->  3.5x */
-	45,  /* 0110 ->  4.5x */
-	110, /* 0111 -> 11.0x */
-	90,  /* 1000 ->  9.0x */
-	70,  /* 1001 ->  7.0x */
-	80,  /* 1010 ->  8.0x */
-	60,  /* 1011 ->  6.0x */
-	120, /* 1100 -> 12.0x */
-	75,  /* 1101 ->  7.5x */
-	130, /* 1110 -> 13.0x */
-	65,  /* 1111 ->  6.5x */
-};
-
-/*
- * VIA C3 Ezra
- */
-static const int __cpuinitdata ezra_mults[16] = {
-	100, /* 0000 -> 10.0x */
-	30,  /* 0001 ->  3.0x */
-	40,  /* 0010 ->  4.0x */
-	90,  /* 0011 ->  9.0x */
-	95,  /* 0100 ->  9.5x */
-	35,  /* 0101 ->  3.5x */
-	45,  /* 0110 ->  4.5x */
-	55,  /* 0111 ->  5.5x */
-	60,  /* 1000 ->  6.0x */
-	70,  /* 1001 ->  7.0x */
-	80,  /* 1010 ->  8.0x */
-	50,  /* 1011 ->  5.0x */
-	65,  /* 1100 ->  6.5x */
-	75,  /* 1101 ->  7.5x */
-	85,  /* 1110 ->  8.5x */
-	120, /* 1111 -> 12.0x */
-};
-
-static const int __cpuinitdata ezra_eblcr[16] = {
-	50,  /* 0000 ->  5.0x */
-	30,  /* 0001 ->  3.0x */
-	40,  /* 0010 ->  4.0x */
-	100, /* 0011 -> 10.0x */
-	55,  /* 0100 ->  5.5x */
-	35,  /* 0101 ->  3.5x */
-	45,  /* 0110 ->  4.5x */
-	95,  /* 0111 ->  9.5x */
-	90,  /* 1000 ->  9.0x */
-	70,  /* 1001 ->  7.0x */
-	80,  /* 1010 ->  8.0x */
-	60,  /* 1011 ->  6.0x */
-	120, /* 1100 -> 12.0x */
-	75,  /* 1101 ->  7.5x */
-	85,  /* 1110 ->  8.5x */
-	65,  /* 1111 ->  6.5x */
-};
-
-/*
- * VIA C3 (Ezra-T) [C5M].
- */
-static const int __cpuinitdata ezrat_mults[32] = {
-	100, /* 0000 -> 10.0x */
-	30,  /* 0001 ->  3.0x */
-	40,  /* 0010 ->  4.0x */
-	90,  /* 0011 ->  9.0x */
-	95,  /* 0100 ->  9.5x */
-	35,  /* 0101 ->  3.5x */
-	45,  /* 0110 ->  4.5x */
-	55,  /* 0111 ->  5.5x */
-	60,  /* 1000 ->  6.0x */
-	70,  /* 1001 ->  7.0x */
-	80,  /* 1010 ->  8.0x */
-	50,  /* 1011 ->  5.0x */
-	65,  /* 1100 ->  6.5x */
-	75,  /* 1101 ->  7.5x */
-	85,  /* 1110 ->  8.5x */
-	120, /* 1111 ->  12.0x */
-
-	-1,  /* 0000 -> RESERVED (10.0x) */
-	110, /* 0001 -> 11.0x */
-	-1, /* 0010 -> 12.0x */
-	-1,  /* 0011 -> RESERVED (9.0x)*/
-	105, /* 0100 -> 10.5x */
-	115, /* 0101 -> 11.5x */
-	125, /* 0110 -> 12.5x */
-	135, /* 0111 -> 13.5x */
-	140, /* 1000 -> 14.0x */
-	150, /* 1001 -> 15.0x */
-	160, /* 1010 -> 16.0x */
-	130, /* 1011 -> 13.0x */
-	145, /* 1100 -> 14.5x */
-	155, /* 1101 -> 15.5x */
-	-1,  /* 1110 -> RESERVED (13.0x) */
-	-1,  /* 1111 -> RESERVED (12.0x) */
-};
-
-static const int __cpuinitdata ezrat_eblcr[32] = {
-	50,  /* 0000 ->  5.0x */
-	30,  /* 0001 ->  3.0x */
-	40,  /* 0010 ->  4.0x */
-	100, /* 0011 -> 10.0x */
-	55,  /* 0100 ->  5.5x */
-	35,  /* 0101 ->  3.5x */
-	45,  /* 0110 ->  4.5x */
-	95,  /* 0111 ->  9.5x */
-	90,  /* 1000 ->  9.0x */
-	70,  /* 1001 ->  7.0x */
-	80,  /* 1010 ->  8.0x */
-	60,  /* 1011 ->  6.0x */
-	120, /* 1100 -> 12.0x */
-	75,  /* 1101 ->  7.5x */
-	85,  /* 1110 ->  8.5x */
-	65,  /* 1111 ->  6.5x */
-
-	-1,  /* 0000 -> RESERVED (9.0x) */
-	110, /* 0001 -> 11.0x */
-	120, /* 0010 -> 12.0x */
-	-1,  /* 0011 -> RESERVED (10.0x)*/
-	135, /* 0100 -> 13.5x */
-	115, /* 0101 -> 11.5x */
-	125, /* 0110 -> 12.5x */
-	105, /* 0111 -> 10.5x */
-	130, /* 1000 -> 13.0x */
-	150, /* 1001 -> 15.0x */
-	160, /* 1010 -> 16.0x */
-	140, /* 1011 -> 14.0x */
-	-1,  /* 1100 -> RESERVED (12.0x) */
-	155, /* 1101 -> 15.5x */
-	-1,  /* 1110 -> RESERVED (13.0x) */
-	145, /* 1111 -> 14.5x */
-};
-
-/*
- * VIA C3 Nehemiah */
-
-static const int __cpuinitdata nehemiah_mults[32] = {
-	100, /* 0000 -> 10.0x */
-	-1, /* 0001 -> 16.0x */
-	40,  /* 0010 ->  4.0x */
-	90,  /* 0011 ->  9.0x */
-	95,  /* 0100 ->  9.5x */
-	-1,  /* 0101 ->  RESERVED */
-	45,  /* 0110 ->  4.5x */
-	55,  /* 0111 ->  5.5x */
-	60,  /* 1000 ->  6.0x */
-	70,  /* 1001 ->  7.0x */
-	80,  /* 1010 ->  8.0x */
-	50,  /* 1011 ->  5.0x */
-	65,  /* 1100 ->  6.5x */
-	75,  /* 1101 ->  7.5x */
-	85,  /* 1110 ->  8.5x */
-	120, /* 1111 -> 12.0x */
-	-1, /* 0000 -> 10.0x */
-	110, /* 0001 -> 11.0x */
-	-1, /* 0010 -> 12.0x */
-	-1,  /* 0011 ->  9.0x */
-	105, /* 0100 -> 10.5x */
-	115, /* 0101 -> 11.5x */
-	125, /* 0110 -> 12.5x */
-	135, /* 0111 -> 13.5x */
-	140, /* 1000 -> 14.0x */
-	150, /* 1001 -> 15.0x */
-	160, /* 1010 -> 16.0x */
-	130, /* 1011 -> 13.0x */
-	145, /* 1100 -> 14.5x */
-	155, /* 1101 -> 15.5x */
-	-1,  /* 1110 -> RESERVED (13.0x) */
-	-1, /* 1111 -> 12.0x */
-};
-
-static const int __cpuinitdata nehemiah_eblcr[32] = {
-	50,  /* 0000 ->  5.0x */
-	160, /* 0001 -> 16.0x */
-	40,  /* 0010 ->  4.0x */
-	100, /* 0011 -> 10.0x */
-	55,  /* 0100 ->  5.5x */
-	-1,  /* 0101 ->  RESERVED */
-	45,  /* 0110 ->  4.5x */
-	95,  /* 0111 ->  9.5x */
-	90,  /* 1000 ->  9.0x */
-	70,  /* 1001 ->  7.0x */
-	80,  /* 1010 ->  8.0x */
-	60,  /* 1011 ->  6.0x */
-	120, /* 1100 -> 12.0x */
-	75,  /* 1101 ->  7.5x */
-	85,  /* 1110 ->  8.5x */
-	65,  /* 1111 ->  6.5x */
-	90,  /* 0000 ->  9.0x */
-	110, /* 0001 -> 11.0x */
-	120, /* 0010 -> 12.0x */
-	100, /* 0011 -> 10.0x */
-	135, /* 0100 -> 13.5x */
-	115, /* 0101 -> 11.5x */
-	125, /* 0110 -> 12.5x */
-	105, /* 0111 -> 10.5x */
-	130, /* 1000 -> 13.0x */
-	150, /* 1001 -> 15.0x */
-	160, /* 1010 -> 16.0x */
-	140, /* 1011 -> 14.0x */
-	120, /* 1100 -> 12.0x */
-	155, /* 1101 -> 15.5x */
-	-1,  /* 1110 -> RESERVED (13.0x) */
-	145 /* 1111 -> 14.5x */
-};
-
-/*
- * Voltage scales. Div/Mod by 1000 to get actual voltage.
- * Which scale to use depends on the VRM type in use.
- */
-
-struct mV_pos {
-	unsigned short mV;
-	unsigned short pos;
-};
-
-static const struct mV_pos __cpuinitdata vrm85_mV[32] = {
-	{1250, 8},	{1200, 6},	{1150, 4},	{1100, 2},
-	{1050, 0},	{1800, 30},	{1750, 28},	{1700, 26},
-	{1650, 24},	{1600, 22},	{1550, 20},	{1500, 18},
-	{1450, 16},	{1400, 14},	{1350, 12},	{1300, 10},
-	{1275, 9},	{1225, 7},	{1175, 5},	{1125, 3},
-	{1075, 1},	{1825, 31},	{1775, 29},	{1725, 27},
-	{1675, 25},	{1625, 23},	{1575, 21},	{1525, 19},
-	{1475, 17},	{1425, 15},	{1375, 13},	{1325, 11}
-};
-
-static const unsigned char __cpuinitdata mV_vrm85[32] = {
-	0x04,	0x14,	0x03,	0x13,	0x02,	0x12,	0x01,	0x11,
-	0x00,	0x10,	0x0f,	0x1f,	0x0e,	0x1e,	0x0d,	0x1d,
-	0x0c,	0x1c,	0x0b,	0x1b,	0x0a,	0x1a,	0x09,	0x19,
-	0x08,	0x18,	0x07,	0x17,	0x06,	0x16,	0x05,	0x15
-};
-
-static const struct mV_pos __cpuinitdata mobilevrm_mV[32] = {
-	{1750, 31},	{1700, 30},	{1650, 29},	{1600, 28},
-	{1550, 27},	{1500, 26},	{1450, 25},	{1400, 24},
-	{1350, 23},	{1300, 22},	{1250, 21},	{1200, 20},
-	{1150, 19},	{1100, 18},	{1050, 17},	{1000, 16},
-	{975, 15},	{950, 14},	{925, 13},	{900, 12},
-	{875, 11},	{850, 10},	{825, 9},	{800, 8},
-	{775, 7},	{750, 6},	{725, 5},	{700, 4},
-	{675, 3},	{650, 2},	{625, 1},	{600, 0}
-};
-
-static const unsigned char __cpuinitdata mV_mobilevrm[32] = {
-	0x1f,	0x1e,	0x1d,	0x1c,	0x1b,	0x1a,	0x19,	0x18,
-	0x17,	0x16,	0x15,	0x14,	0x13,	0x12,	0x11,	0x10,
-	0x0f,	0x0e,	0x0d,	0x0c,	0x0b,	0x0a,	0x09,	0x08,
-	0x07,	0x06,	0x05,	0x04,	0x03,	0x02,	0x01,	0x00
-};
-
diff -druN linux-2.6.39-libre/arch/x86/kernel/cpu/cpufreq/longrun.c linux-3.0-rc7-libre/arch/x86/kernel/cpu/cpufreq/longrun.c
--- linux-2.6.39-libre/arch/x86/kernel/cpu/cpufreq/longrun.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/kernel/cpu/cpufreq/longrun.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,327 +0,0 @@
-/*
- * (C) 2002 - 2003  Dominik Brodowski <linux@brodo.de>
- *
- *  Licensed under the terms of the GNU GPL License version 2.
- *
- *  BIG FAT DISCLAIMER: Work in progress code. Possibly *dangerous*
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/cpufreq.h>
-#include <linux/timex.h>
-
-#include <asm/msr.h>
-#include <asm/processor.h>
-
-#define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, \
-		"longrun", msg)
-
-static struct cpufreq_driver	longrun_driver;
-
-/**
- * longrun_{low,high}_freq is needed for the conversion of cpufreq kHz
- * values into per cent values. In TMTA microcode, the following is valid:
- * performance_pctg = (current_freq - low_freq)/(high_freq - low_freq)
- */
-static unsigned int longrun_low_freq, longrun_high_freq;
-
-
-/**
- * longrun_get_policy - get the current LongRun policy
- * @policy: struct cpufreq_policy where current policy is written into
- *
- * Reads the current LongRun policy by access to MSR_TMTA_LONGRUN_FLAGS
- * and MSR_TMTA_LONGRUN_CTRL
- */
-static void __cpuinit longrun_get_policy(struct cpufreq_policy *policy)
-{
-	u32 msr_lo, msr_hi;
-
-	rdmsr(MSR_TMTA_LONGRUN_FLAGS, msr_lo, msr_hi);
-	dprintk("longrun flags are %x - %x\n", msr_lo, msr_hi);
-	if (msr_lo & 0x01)
-		policy->policy = CPUFREQ_POLICY_PERFORMANCE;
-	else
-		policy->policy = CPUFREQ_POLICY_POWERSAVE;
-
-	rdmsr(MSR_TMTA_LONGRUN_CTRL, msr_lo, msr_hi);
-	dprintk("longrun ctrl is %x - %x\n", msr_lo, msr_hi);
-	msr_lo &= 0x0000007F;
-	msr_hi &= 0x0000007F;
-
-	if (longrun_high_freq <= longrun_low_freq) {
-		/* Assume degenerate Longrun table */
-		policy->min = policy->max = longrun_high_freq;
-	} else {
-		policy->min = longrun_low_freq + msr_lo *
-			((longrun_high_freq - longrun_low_freq) / 100);
-		policy->max = longrun_low_freq + msr_hi *
-			((longrun_high_freq - longrun_low_freq) / 100);
-	}
-	policy->cpu = 0;
-}
-
-
-/**
- * longrun_set_policy - sets a new CPUFreq policy
- * @policy: new policy
- *
- * Sets a new CPUFreq policy on LongRun-capable processors. This function
- * has to be called with cpufreq_driver locked.
- */
-static int longrun_set_policy(struct cpufreq_policy *policy)
-{
-	u32 msr_lo, msr_hi;
-	u32 pctg_lo, pctg_hi;
-
-	if (!policy)
-		return -EINVAL;
-
-	if (longrun_high_freq <= longrun_low_freq) {
-		/* Assume degenerate Longrun table */
-		pctg_lo = pctg_hi = 100;
-	} else {
-		pctg_lo = (policy->min - longrun_low_freq) /
-			((longrun_high_freq - longrun_low_freq) / 100);
-		pctg_hi = (policy->max - longrun_low_freq) /
-			((longrun_high_freq - longrun_low_freq) / 100);
-	}
-
-	if (pctg_hi > 100)
-		pctg_hi = 100;
-	if (pctg_lo > pctg_hi)
-		pctg_lo = pctg_hi;
-
-	/* performance or economy mode */
-	rdmsr(MSR_TMTA_LONGRUN_FLAGS, msr_lo, msr_hi);
-	msr_lo &= 0xFFFFFFFE;
-	switch (policy->policy) {
-	case CPUFREQ_POLICY_PERFORMANCE:
-		msr_lo |= 0x00000001;
-		break;
-	case CPUFREQ_POLICY_POWERSAVE:
-		break;
-	}
-	wrmsr(MSR_TMTA_LONGRUN_FLAGS, msr_lo, msr_hi);
-
-	/* lower and upper boundary */
-	rdmsr(MSR_TMTA_LONGRUN_CTRL, msr_lo, msr_hi);
-	msr_lo &= 0xFFFFFF80;
-	msr_hi &= 0xFFFFFF80;
-	msr_lo |= pctg_lo;
-	msr_hi |= pctg_hi;
-	wrmsr(MSR_TMTA_LONGRUN_CTRL, msr_lo, msr_hi);
-
-	return 0;
-}
-
-
-/**
- * longrun_verify_poliy - verifies a new CPUFreq policy
- * @policy: the policy to verify
- *
- * Validates a new CPUFreq policy. This function has to be called with
- * cpufreq_driver locked.
- */
-static int longrun_verify_policy(struct cpufreq_policy *policy)
-{
-	if (!policy)
-		return -EINVAL;
-
-	policy->cpu = 0;
-	cpufreq_verify_within_limits(policy,
-		policy->cpuinfo.min_freq,
-		policy->cpuinfo.max_freq);
-
-	if ((policy->policy != CPUFREQ_POLICY_POWERSAVE) &&
-	    (policy->policy != CPUFREQ_POLICY_PERFORMANCE))
-		return -EINVAL;
-
-	return 0;
-}
-
-static unsigned int longrun_get(unsigned int cpu)
-{
-	u32 eax, ebx, ecx, edx;
-
-	if (cpu)
-		return 0;
-
-	cpuid(0x80860007, &eax, &ebx, &ecx, &edx);
-	dprintk("cpuid eax is %u\n", eax);
-
-	return eax * 1000;
-}
-
-/**
- * longrun_determine_freqs - determines the lowest and highest possible core frequency
- * @low_freq: an int to put the lowest frequency into
- * @high_freq: an int to put the highest frequency into
- *
- * Determines the lowest and highest possible core frequencies on this CPU.
- * This is necessary to calculate the performance percentage according to
- * TMTA rules:
- * performance_pctg = (target_freq - low_freq)/(high_freq - low_freq)
- */
-static int __cpuinit longrun_determine_freqs(unsigned int *low_freq,
-						      unsigned int *high_freq)
-{
-	u32 msr_lo, msr_hi;
-	u32 save_lo, save_hi;
-	u32 eax, ebx, ecx, edx;
-	u32 try_hi;
-	struct cpuinfo_x86 *c = &cpu_data(0);
-
-	if (!low_freq || !high_freq)
-		return -EINVAL;
-
-	if (cpu_has(c, X86_FEATURE_LRTI)) {
-		/* if the LongRun Table Interface is present, the
-		 * detection is a bit easier:
-		 * For minimum frequency, read out the maximum
-		 * level (msr_hi), write that into "currently
-		 * selected level", and read out the frequency.
-		 * For maximum frequency, read out level zero.
-		 */
-		/* minimum */
-		rdmsr(MSR_TMTA_LRTI_READOUT, msr_lo, msr_hi);
-		wrmsr(MSR_TMTA_LRTI_READOUT, msr_hi, msr_hi);
-		rdmsr(MSR_TMTA_LRTI_VOLT_MHZ, msr_lo, msr_hi);
-		*low_freq = msr_lo * 1000; /* to kHz */
-
-		/* maximum */
-		wrmsr(MSR_TMTA_LRTI_READOUT, 0, msr_hi);
-		rdmsr(MSR_TMTA_LRTI_VOLT_MHZ, msr_lo, msr_hi);
-		*high_freq = msr_lo * 1000; /* to kHz */
-
-		dprintk("longrun table interface told %u - %u kHz\n",
-				*low_freq, *high_freq);
-
-		if (*low_freq > *high_freq)
-			*low_freq = *high_freq;
-		return 0;
-	}
-
-	/* set the upper border to the value determined during TSC init */
-	*high_freq = (cpu_khz / 1000);
-	*high_freq = *high_freq * 1000;
-	dprintk("high frequency is %u kHz\n", *high_freq);
-
-	/* get current borders */
-	rdmsr(MSR_TMTA_LONGRUN_CTRL, msr_lo, msr_hi);
-	save_lo = msr_lo & 0x0000007F;
-	save_hi = msr_hi & 0x0000007F;
-
-	/* if current perf_pctg is larger than 90%, we need to decrease the
-	 * upper limit to make the calculation more accurate.
-	 */
-	cpuid(0x80860007, &eax, &ebx, &ecx, &edx);
-	/* try decreasing in 10% steps, some processors react only
-	 * on some barrier values */
-	for (try_hi = 80; try_hi > 0 && ecx > 90; try_hi -= 10) {
-		/* set to 0 to try_hi perf_pctg */
-		msr_lo &= 0xFFFFFF80;
-		msr_hi &= 0xFFFFFF80;
-		msr_hi |= try_hi;
-		wrmsr(MSR_TMTA_LONGRUN_CTRL, msr_lo, msr_hi);
-
-		/* read out current core MHz and current perf_pctg */
-		cpuid(0x80860007, &eax, &ebx, &ecx, &edx);
-
-		/* restore values */
-		wrmsr(MSR_TMTA_LONGRUN_CTRL, save_lo, save_hi);
-	}
-	dprintk("percentage is %u %%, freq is %u MHz\n", ecx, eax);
-
-	/* performance_pctg = (current_freq - low_freq)/(high_freq - low_freq)
-	 * eqals
-	 * low_freq * (1 - perf_pctg) = (cur_freq - high_freq * perf_pctg)
-	 *
-	 * high_freq * perf_pctg is stored tempoarily into "ebx".
-	 */
-	ebx = (((cpu_khz / 1000) * ecx) / 100); /* to MHz */
-
-	if ((ecx > 95) || (ecx == 0) || (eax < ebx))
-		return -EIO;
-
-	edx = ((eax - ebx) * 100) / (100 - ecx);
-	*low_freq = edx * 1000; /* back to kHz */
-
-	dprintk("low frequency is %u kHz\n", *low_freq);
-
-	if (*low_freq > *high_freq)
-		*low_freq = *high_freq;
-
-	return 0;
-}
-
-
-static int __cpuinit longrun_cpu_init(struct cpufreq_policy *policy)
-{
-	int result = 0;
-
-	/* capability check */
-	if (policy->cpu != 0)
-		return -ENODEV;
-
-	/* detect low and high frequency */
-	result = longrun_determine_freqs(&longrun_low_freq, &longrun_high_freq);
-	if (result)
-		return result;
-
-	/* cpuinfo and default policy values */
-	policy->cpuinfo.min_freq = longrun_low_freq;
-	policy->cpuinfo.max_freq = longrun_high_freq;
-	policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL;
-	longrun_get_policy(policy);
-
-	return 0;
-}
-
-
-static struct cpufreq_driver longrun_driver = {
-	.flags		= CPUFREQ_CONST_LOOPS,
-	.verify		= longrun_verify_policy,
-	.setpolicy	= longrun_set_policy,
-	.get		= longrun_get,
-	.init		= longrun_cpu_init,
-	.name		= "longrun",
-	.owner		= THIS_MODULE,
-};
-
-
-/**
- * longrun_init - initializes the Transmeta Crusoe LongRun CPUFreq driver
- *
- * Initializes the LongRun support.
- */
-static int __init longrun_init(void)
-{
-	struct cpuinfo_x86 *c = &cpu_data(0);
-
-	if (c->x86_vendor != X86_VENDOR_TRANSMETA ||
-	    !cpu_has(c, X86_FEATURE_LONGRUN))
-		return -ENODEV;
-
-	return cpufreq_register_driver(&longrun_driver);
-}
-
-
-/**
- * longrun_exit - unregisters LongRun support
- */
-static void __exit longrun_exit(void)
-{
-	cpufreq_unregister_driver(&longrun_driver);
-}
-
-
-MODULE_AUTHOR("Dominik Brodowski <linux@brodo.de>");
-MODULE_DESCRIPTION("LongRun driver for Transmeta Crusoe and "
-		"Efficeon processors.");
-MODULE_LICENSE("GPL");
-
-module_init(longrun_init);
-module_exit(longrun_exit);
diff -druN linux-2.6.39-libre/arch/x86/kernel/cpu/cpufreq/Makefile linux-3.0-rc7-libre/arch/x86/kernel/cpu/cpufreq/Makefile
--- linux-2.6.39-libre/arch/x86/kernel/cpu/cpufreq/Makefile	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/kernel/cpu/cpufreq/Makefile	1969-12-31 19:00:00.000000000 -0500
@@ -1,21 +0,0 @@
-# Link order matters. K8 is preferred to ACPI because of firmware bugs in early
-# K8 systems. ACPI is preferred to all other hardware-specific drivers.
-# speedstep-* is preferred over p4-clockmod.
-
-obj-$(CONFIG_X86_POWERNOW_K8)		+= powernow-k8.o mperf.o
-obj-$(CONFIG_X86_ACPI_CPUFREQ)		+= acpi-cpufreq.o mperf.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
-obj-$(CONFIG_X86_E_POWERSAVER)		+= e_powersaver.o
-obj-$(CONFIG_ELAN_CPUFREQ)		+= elanfreq.o
-obj-$(CONFIG_SC520_CPUFREQ)		+= sc520_freq.o
-obj-$(CONFIG_X86_LONGRUN)		+= longrun.o  
-obj-$(CONFIG_X86_GX_SUSPMOD)		+= gx-suspmod.o
-obj-$(CONFIG_X86_SPEEDSTEP_ICH)		+= speedstep-ich.o
-obj-$(CONFIG_X86_SPEEDSTEP_LIB)		+= speedstep-lib.o
-obj-$(CONFIG_X86_SPEEDSTEP_SMI)		+= speedstep-smi.o
-obj-$(CONFIG_X86_SPEEDSTEP_CENTRINO)	+= speedstep-centrino.o
-obj-$(CONFIG_X86_P4_CLOCKMOD)		+= p4-clockmod.o
-obj-$(CONFIG_X86_CPUFREQ_NFORCE2)	+= cpufreq-nforce2.o
diff -druN linux-2.6.39-libre/arch/x86/kernel/cpu/cpufreq/mperf.c linux-3.0-rc7-libre/arch/x86/kernel/cpu/cpufreq/mperf.c
--- linux-2.6.39-libre/arch/x86/kernel/cpu/cpufreq/mperf.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/kernel/cpu/cpufreq/mperf.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,51 +0,0 @@
-#include <linux/kernel.h>
-#include <linux/smp.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/cpufreq.h>
-#include <linux/slab.h>
-
-#include "mperf.h"
-
-static DEFINE_PER_CPU(struct aperfmperf, acfreq_old_perf);
-
-/* Called via smp_call_function_single(), on the target CPU */
-static void read_measured_perf_ctrs(void *_cur)
-{
-	struct aperfmperf *am = _cur;
-
-	get_aperfmperf(am);
-}
-
-/*
- * Return the measured active (C0) frequency on this CPU since last call
- * to this function.
- * Input: cpu number
- * Return: Average CPU frequency in terms of max frequency (zero on error)
- *
- * We use IA32_MPERF and IA32_APERF MSRs to get the measured performance
- * over a period of time, while CPU is in C0 state.
- * IA32_MPERF counts at the rate of max advertised frequency
- * IA32_APERF counts at the rate of actual CPU frequency
- * Only IA32_APERF/IA32_MPERF ratio is architecturally defined and
- * no meaning should be associated with absolute values of these MSRs.
- */
-unsigned int cpufreq_get_measured_perf(struct cpufreq_policy *policy,
-					unsigned int cpu)
-{
-	struct aperfmperf perf;
-	unsigned long ratio;
-	unsigned int retval;
-
-	if (smp_call_function_single(cpu, read_measured_perf_ctrs, &perf, 1))
-		return 0;
-
-	ratio = calc_aperfmperf_ratio(&per_cpu(acfreq_old_perf, cpu), &perf);
-	per_cpu(acfreq_old_perf, cpu) = perf;
-
-	retval = (policy->cpuinfo.max_freq * ratio) >> APERFMPERF_SHIFT;
-
-	return retval;
-}
-EXPORT_SYMBOL_GPL(cpufreq_get_measured_perf);
-MODULE_LICENSE("GPL");
diff -druN linux-2.6.39-libre/arch/x86/kernel/cpu/cpufreq/mperf.h linux-3.0-rc7-libre/arch/x86/kernel/cpu/cpufreq/mperf.h
--- linux-2.6.39-libre/arch/x86/kernel/cpu/cpufreq/mperf.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/kernel/cpu/cpufreq/mperf.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,9 +0,0 @@
-/*
- *  (c) 2010 Advanced Micro Devices, Inc.
- *  Your use of this code is subject to the terms and conditions of the
- *  GNU general public license version 2. See "COPYING" or
- *  http://www.gnu.org/licenses/gpl.html
- */
-
-unsigned int cpufreq_get_measured_perf(struct cpufreq_policy *policy,
-					unsigned int cpu);
diff -druN linux-2.6.39-libre/arch/x86/kernel/cpu/cpufreq/p4-clockmod.c linux-3.0-rc7-libre/arch/x86/kernel/cpu/cpufreq/p4-clockmod.c
--- linux-2.6.39-libre/arch/x86/kernel/cpu/cpufreq/p4-clockmod.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/kernel/cpu/cpufreq/p4-clockmod.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,331 +0,0 @@
-/*
- *	Pentium 4/Xeon CPU on demand clock modulation/speed scaling
- *	(C) 2002 - 2003 Dominik Brodowski <linux@brodo.de>
- *	(C) 2002 Zwane Mwaikambo <zwane@commfireservices.com>
- *	(C) 2002 Arjan van de Ven <arjanv@redhat.com>
- *	(C) 2002 Tora T. Engstad
- *	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.
- *
- *      The author(s) of this software shall not be held liable for damages
- *      of any nature resulting due to the use of this software. This
- *      software is provided AS-IS with no warranties.
- *
- *	Date		Errata			Description
- *	20020525	N44, O17	12.5% or 25% DC causes lockup
- *
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/smp.h>
-#include <linux/cpufreq.h>
-#include <linux/cpumask.h>
-#include <linux/timex.h>
-
-#include <asm/processor.h>
-#include <asm/msr.h>
-#include <asm/timer.h>
-
-#include "speedstep-lib.h"
-
-#define PFX	"p4-clockmod: "
-#define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, \
-		"p4-clockmod", msg)
-
-/*
- * Duty Cycle (3bits), note DC_DISABLE is not specified in
- * intel docs i just use it to mean disable
- */
-enum {
-	DC_RESV, DC_DFLT, DC_25PT, DC_38PT, DC_50PT,
-	DC_64PT, DC_75PT, DC_88PT, DC_DISABLE
-};
-
-#define DC_ENTRIES	8
-
-
-static int has_N44_O17_errata[NR_CPUS];
-static unsigned int stock_freq;
-static struct cpufreq_driver p4clockmod_driver;
-static unsigned int cpufreq_p4_get(unsigned int cpu);
-
-static int cpufreq_p4_setdc(unsigned int cpu, unsigned int newstate)
-{
-	u32 l, h;
-
-	if (!cpu_online(cpu) ||
-	    (newstate > DC_DISABLE) || (newstate == DC_RESV))
-		return -EINVAL;
-
-	rdmsr_on_cpu(cpu, MSR_IA32_THERM_STATUS, &l, &h);
-
-	if (l & 0x01)
-		dprintk("CPU#%d currently thermal throttled\n", cpu);
-
-	if (has_N44_O17_errata[cpu] &&
-	    (newstate == DC_25PT || newstate == DC_DFLT))
-		newstate = DC_38PT;
-
-	rdmsr_on_cpu(cpu, MSR_IA32_THERM_CONTROL, &l, &h);
-	if (newstate == DC_DISABLE) {
-		dprintk("CPU#%d disabling modulation\n", cpu);
-		wrmsr_on_cpu(cpu, MSR_IA32_THERM_CONTROL, l & ~(1<<4), h);
-	} else {
-		dprintk("CPU#%d setting duty cycle to %d%%\n",
-			cpu, ((125 * newstate) / 10));
-		/* bits 63 - 5	: reserved
-		 * bit  4	: enable/disable
-		 * bits 3-1	: duty cycle
-		 * bit  0	: reserved
-		 */
-		l = (l & ~14);
-		l = l | (1<<4) | ((newstate & 0x7)<<1);
-		wrmsr_on_cpu(cpu, MSR_IA32_THERM_CONTROL, l, h);
-	}
-
-	return 0;
-}
-
-
-static struct cpufreq_frequency_table p4clockmod_table[] = {
-	{DC_RESV, CPUFREQ_ENTRY_INVALID},
-	{DC_DFLT, 0},
-	{DC_25PT, 0},
-	{DC_38PT, 0},
-	{DC_50PT, 0},
-	{DC_64PT, 0},
-	{DC_75PT, 0},
-	{DC_88PT, 0},
-	{DC_DISABLE, 0},
-	{DC_RESV, CPUFREQ_TABLE_END},
-};
-
-
-static int cpufreq_p4_target(struct cpufreq_policy *policy,
-			     unsigned int target_freq,
-			     unsigned int relation)
-{
-	unsigned int    newstate = DC_RESV;
-	struct cpufreq_freqs freqs;
-	int i;
-
-	if (cpufreq_frequency_table_target(policy, &p4clockmod_table[0],
-				target_freq, relation, &newstate))
-		return -EINVAL;
-
-	freqs.old = cpufreq_p4_get(policy->cpu);
-	freqs.new = stock_freq * p4clockmod_table[newstate].index / 8;
-
-	if (freqs.new == freqs.old)
-		return 0;
-
-	/* notifiers */
-	for_each_cpu(i, policy->cpus) {
-		freqs.cpu = i;
-		cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
-	}
-
-	/* run on each logical CPU,
-	 * see section 13.15.3 of IA32 Intel Architecture Software
-	 * Developer's Manual, Volume 3
-	 */
-	for_each_cpu(i, policy->cpus)
-		cpufreq_p4_setdc(i, p4clockmod_table[newstate].index);
-
-	/* notifiers */
-	for_each_cpu(i, policy->cpus) {
-		freqs.cpu = i;
-		cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
-	}
-
-	return 0;
-}
-
-
-static int cpufreq_p4_verify(struct cpufreq_policy *policy)
-{
-	return cpufreq_frequency_table_verify(policy, &p4clockmod_table[0]);
-}
-
-
-static unsigned int cpufreq_p4_get_frequency(struct cpuinfo_x86 *c)
-{
-	if (c->x86 == 0x06) {
-		if (cpu_has(c, X86_FEATURE_EST))
-			printk_once(KERN_WARNING PFX "Warning: EST-capable "
-			       "CPU detected. The acpi-cpufreq module offers "
-			       "voltage scaling in addition to frequency "
-			       "scaling. You should use that instead of "
-			       "p4-clockmod, if possible.\n");
-		switch (c->x86_model) {
-		case 0x0E: /* Core */
-		case 0x0F: /* Core Duo */
-		case 0x16: /* Celeron Core */
-		case 0x1C: /* Atom */
-			p4clockmod_driver.flags |= CPUFREQ_CONST_LOOPS;
-			return speedstep_get_frequency(SPEEDSTEP_CPU_PCORE);
-		case 0x0D: /* Pentium M (Dothan) */
-			p4clockmod_driver.flags |= CPUFREQ_CONST_LOOPS;
-			/* fall through */
-		case 0x09: /* Pentium M (Banias) */
-			return speedstep_get_frequency(SPEEDSTEP_CPU_PM);
-		}
-	}
-
-	if (c->x86 != 0xF)
-		return 0;
-
-	/* on P-4s, the TSC runs with constant frequency independent whether
-	 * throttling is active or not. */
-	p4clockmod_driver.flags |= CPUFREQ_CONST_LOOPS;
-
-	if (speedstep_detect_processor() == SPEEDSTEP_CPU_P4M) {
-		printk(KERN_WARNING PFX "Warning: Pentium 4-M detected. "
-		       "The speedstep-ich or acpi cpufreq modules offer "
-		       "voltage scaling in addition of frequency scaling. "
-		       "You should use either one instead of p4-clockmod, "
-		       "if possible.\n");
-		return speedstep_get_frequency(SPEEDSTEP_CPU_P4M);
-	}
-
-	return speedstep_get_frequency(SPEEDSTEP_CPU_P4D);
-}
-
-
-
-static int cpufreq_p4_cpu_init(struct cpufreq_policy *policy)
-{
-	struct cpuinfo_x86 *c = &cpu_data(policy->cpu);
-	int cpuid = 0;
-	unsigned int i;
-
-#ifdef CONFIG_SMP
-	cpumask_copy(policy->cpus, cpu_sibling_mask(policy->cpu));
-#endif
-
-	/* Errata workaround */
-	cpuid = (c->x86 << 8) | (c->x86_model << 4) | c->x86_mask;
-	switch (cpuid) {
-	case 0x0f07:
-	case 0x0f0a:
-	case 0x0f11:
-	case 0x0f12:
-		has_N44_O17_errata[policy->cpu] = 1;
-		dprintk("has errata -- disabling low frequencies\n");
-	}
-
-	if (speedstep_detect_processor() == SPEEDSTEP_CPU_P4D &&
-	    c->x86_model < 2) {
-		/* switch to maximum frequency and measure result */
-		cpufreq_p4_setdc(policy->cpu, DC_DISABLE);
-		recalibrate_cpu_khz();
-	}
-	/* get max frequency */
-	stock_freq = cpufreq_p4_get_frequency(c);
-	if (!stock_freq)
-		return -EINVAL;
-
-	/* table init */
-	for (i = 1; (p4clockmod_table[i].frequency != CPUFREQ_TABLE_END); i++) {
-		if ((i < 2) && (has_N44_O17_errata[policy->cpu]))
-			p4clockmod_table[i].frequency = CPUFREQ_ENTRY_INVALID;
-		else
-			p4clockmod_table[i].frequency = (stock_freq * i)/8;
-	}
-	cpufreq_frequency_table_get_attr(p4clockmod_table, policy->cpu);
-
-	/* cpuinfo and default policy values */
-
-	/* the transition latency is set to be 1 higher than the maximum
-	 * transition latency of the ondemand governor */
-	policy->cpuinfo.transition_latency = 10000001;
-	policy->cur = stock_freq;
-
-	return cpufreq_frequency_table_cpuinfo(policy, &p4clockmod_table[0]);
-}
-
-
-static int cpufreq_p4_cpu_exit(struct cpufreq_policy *policy)
-{
-	cpufreq_frequency_table_put_attr(policy->cpu);
-	return 0;
-}
-
-static unsigned int cpufreq_p4_get(unsigned int cpu)
-{
-	u32 l, h;
-
-	rdmsr_on_cpu(cpu, MSR_IA32_THERM_CONTROL, &l, &h);
-
-	if (l & 0x10) {
-		l = l >> 1;
-		l &= 0x7;
-	} else
-		l = DC_DISABLE;
-
-	if (l != DC_DISABLE)
-		return stock_freq * l / 8;
-
-	return stock_freq;
-}
-
-static struct freq_attr *p4clockmod_attr[] = {
-	&cpufreq_freq_attr_scaling_available_freqs,
-	NULL,
-};
-
-static struct cpufreq_driver p4clockmod_driver = {
-	.verify		= cpufreq_p4_verify,
-	.target		= cpufreq_p4_target,
-	.init		= cpufreq_p4_cpu_init,
-	.exit		= cpufreq_p4_cpu_exit,
-	.get		= cpufreq_p4_get,
-	.name		= "p4-clockmod",
-	.owner		= THIS_MODULE,
-	.attr		= p4clockmod_attr,
-};
-
-
-static int __init cpufreq_p4_init(void)
-{
-	struct cpuinfo_x86 *c = &cpu_data(0);
-	int ret;
-
-	/*
-	 * THERM_CONTROL is architectural for IA32 now, so
-	 * we can rely on the capability checks
-	 */
-	if (c->x86_vendor != X86_VENDOR_INTEL)
-		return -ENODEV;
-
-	if (!test_cpu_cap(c, X86_FEATURE_ACPI) ||
-				!test_cpu_cap(c, X86_FEATURE_ACC))
-		return -ENODEV;
-
-	ret = cpufreq_register_driver(&p4clockmod_driver);
-	if (!ret)
-		printk(KERN_INFO PFX "P4/Xeon(TM) CPU On-Demand Clock "
-				"Modulation available\n");
-
-	return ret;
-}
-
-
-static void __exit cpufreq_p4_exit(void)
-{
-	cpufreq_unregister_driver(&p4clockmod_driver);
-}
-
-
-MODULE_AUTHOR("Zwane Mwaikambo <zwane@commfireservices.com>");
-MODULE_DESCRIPTION("cpufreq driver for Pentium(TM) 4/Xeon(TM)");
-MODULE_LICENSE("GPL");
-
-late_initcall(cpufreq_p4_init);
-module_exit(cpufreq_p4_exit);
diff -druN linux-2.6.39-libre/arch/x86/kernel/cpu/cpufreq/pcc-cpufreq.c linux-3.0-rc7-libre/arch/x86/kernel/cpu/cpufreq/pcc-cpufreq.c
--- linux-2.6.39-libre/arch/x86/kernel/cpu/cpufreq/pcc-cpufreq.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/kernel/cpu/cpufreq/pcc-cpufreq.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,624 +0,0 @@
-/*
- *  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 __percpu *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 0;
-}
-
-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;
-	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, pcch_handle;
-	int ret = 0;
-
-	status = acpi_get_handle(NULL, "\\_SB", &handle);
-	if (ACPI_FAILURE(status))
-		return -ENODEV;
-
-	status = acpi_get_handle(handle, "PCCH", &pcch_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 out;
-	}
-
-	result = pcc_get_offset(cpu);
-	if (result) {
-		dprintk("init: PCCP evaluation failed\n");
-		goto out;
-	}
-
-	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);
-
-	if (!policy->cur) {
-		dprintk("init: Unable to get current CPU frequency\n");
-		result = -EINVAL;
-		goto out;
-	}
-
-	dprintk("init: policy->max is %d, policy->min is %d\n",
-		policy->max, policy->min);
-out:
-	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 -druN linux-2.6.39-libre/arch/x86/kernel/cpu/cpufreq/powernow-k6.c linux-3.0-rc7-libre/arch/x86/kernel/cpu/cpufreq/powernow-k6.c
--- linux-2.6.39-libre/arch/x86/kernel/cpu/cpufreq/powernow-k6.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/kernel/cpu/cpufreq/powernow-k6.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,261 +0,0 @@
-/*
- *  This file was based upon code in Powertweak Linux (http://powertweak.sf.net)
- *  (C) 2000-2003  Dave Jones, Arjan van de Ven, Janne Pänkälä,
- *                 Dominik Brodowski.
- *
- *  Licensed under the terms of the GNU GPL License version 2.
- *
- *  BIG FAT DISCLAIMER: Work in progress code. Possibly *dangerous*
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/cpufreq.h>
-#include <linux/ioport.h>
-#include <linux/timex.h>
-#include <linux/io.h>
-
-#include <asm/msr.h>
-
-#define POWERNOW_IOPORT 0xfff0          /* it doesn't matter where, as long
-					   as it is unused */
-
-#define PFX "powernow-k6: "
-static unsigned int                     busfreq;   /* FSB, in 10 kHz */
-static unsigned int                     max_multiplier;
-
-
-/* Clock ratio multiplied by 10 - see table 27 in AMD#23446 */
-static struct cpufreq_frequency_table clock_ratio[] = {
-	{45,  /* 000 -> 4.5x */ 0},
-	{50,  /* 001 -> 5.0x */ 0},
-	{40,  /* 010 -> 4.0x */ 0},
-	{55,  /* 011 -> 5.5x */ 0},
-	{20,  /* 100 -> 2.0x */ 0},
-	{30,  /* 101 -> 3.0x */ 0},
-	{60,  /* 110 -> 6.0x */ 0},
-	{35,  /* 111 -> 3.5x */ 0},
-	{0, CPUFREQ_TABLE_END}
-};
-
-
-/**
- * powernow_k6_get_cpu_multiplier - returns the current FSB multiplier
- *
- *   Returns the current setting of the frequency multiplier. Core clock
- * speed is frequency of the Front-Side Bus multiplied with this value.
- */
-static int powernow_k6_get_cpu_multiplier(void)
-{
-	u64 invalue = 0;
-	u32 msrval;
-
-	msrval = POWERNOW_IOPORT + 0x1;
-	wrmsr(MSR_K6_EPMR, msrval, 0); /* enable the PowerNow port */
-	invalue = inl(POWERNOW_IOPORT + 0x8);
-	msrval = POWERNOW_IOPORT + 0x0;
-	wrmsr(MSR_K6_EPMR, msrval, 0); /* disable it again */
-
-	return clock_ratio[(invalue >> 5)&7].index;
-}
-
-
-/**
- * powernow_k6_set_state - set the PowerNow! multiplier
- * @best_i: clock_ratio[best_i] is the target multiplier
- *
- *   Tries to change the PowerNow! multiplier
- */
-static void powernow_k6_set_state(unsigned int best_i)
-{
-	unsigned long outvalue = 0, invalue = 0;
-	unsigned long msrval;
-	struct cpufreq_freqs freqs;
-
-	if (clock_ratio[best_i].index > max_multiplier) {
-		printk(KERN_ERR PFX "invalid target frequency\n");
-		return;
-	}
-
-	freqs.old = busfreq * powernow_k6_get_cpu_multiplier();
-	freqs.new = busfreq * clock_ratio[best_i].index;
-	freqs.cpu = 0; /* powernow-k6.c is UP only driver */
-
-	cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
-
-	/* we now need to transform best_i to the BVC format, see AMD#23446 */
-
-	outvalue = (1<<12) | (1<<10) | (1<<9) | (best_i<<5);
-
-	msrval = POWERNOW_IOPORT + 0x1;
-	wrmsr(MSR_K6_EPMR, msrval, 0); /* enable the PowerNow port */
-	invalue = inl(POWERNOW_IOPORT + 0x8);
-	invalue = invalue & 0xf;
-	outvalue = outvalue | invalue;
-	outl(outvalue , (POWERNOW_IOPORT + 0x8));
-	msrval = POWERNOW_IOPORT + 0x0;
-	wrmsr(MSR_K6_EPMR, msrval, 0); /* disable it again */
-
-	cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
-
-	return;
-}
-
-
-/**
- * powernow_k6_verify - verifies a new CPUfreq policy
- * @policy: new policy
- *
- * Policy must be within lowest and highest possible CPU Frequency,
- * and at least one possible state must be within min and max.
- */
-static int powernow_k6_verify(struct cpufreq_policy *policy)
-{
-	return cpufreq_frequency_table_verify(policy, &clock_ratio[0]);
-}
-
-
-/**
- * powernow_k6_setpolicy - sets a new CPUFreq policy
- * @policy: new policy
- * @target_freq: the target frequency
- * @relation: how that frequency relates to achieved frequency
- *  (CPUFREQ_RELATION_L or CPUFREQ_RELATION_H)
- *
- * sets a new CPUFreq policy
- */
-static int powernow_k6_target(struct cpufreq_policy *policy,
-			       unsigned int target_freq,
-			       unsigned int relation)
-{
-	unsigned int newstate = 0;
-
-	if (cpufreq_frequency_table_target(policy, &clock_ratio[0],
-				target_freq, relation, &newstate))
-		return -EINVAL;
-
-	powernow_k6_set_state(newstate);
-
-	return 0;
-}
-
-
-static int powernow_k6_cpu_init(struct cpufreq_policy *policy)
-{
-	unsigned int i, f;
-	int result;
-
-	if (policy->cpu != 0)
-		return -ENODEV;
-
-	/* get frequencies */
-	max_multiplier = powernow_k6_get_cpu_multiplier();
-	busfreq = cpu_khz / max_multiplier;
-
-	/* table init */
-	for (i = 0; (clock_ratio[i].frequency != CPUFREQ_TABLE_END); i++) {
-		f = clock_ratio[i].index;
-		if (f > max_multiplier)
-			clock_ratio[i].frequency = CPUFREQ_ENTRY_INVALID;
-		else
-			clock_ratio[i].frequency = busfreq * f;
-	}
-
-	/* cpuinfo and default policy values */
-	policy->cpuinfo.transition_latency = 200000;
-	policy->cur = busfreq * max_multiplier;
-
-	result = cpufreq_frequency_table_cpuinfo(policy, clock_ratio);
-	if (result)
-		return result;
-
-	cpufreq_frequency_table_get_attr(clock_ratio, policy->cpu);
-
-	return 0;
-}
-
-
-static int powernow_k6_cpu_exit(struct cpufreq_policy *policy)
-{
-	unsigned int i;
-	for (i = 0; i < 8; i++) {
-		if (i == max_multiplier)
-			powernow_k6_set_state(i);
-	}
-	cpufreq_frequency_table_put_attr(policy->cpu);
-	return 0;
-}
-
-static unsigned int powernow_k6_get(unsigned int cpu)
-{
-	unsigned int ret;
-	ret = (busfreq * powernow_k6_get_cpu_multiplier());
-	return ret;
-}
-
-static struct freq_attr *powernow_k6_attr[] = {
-	&cpufreq_freq_attr_scaling_available_freqs,
-	NULL,
-};
-
-static struct cpufreq_driver powernow_k6_driver = {
-	.verify		= powernow_k6_verify,
-	.target		= powernow_k6_target,
-	.init		= powernow_k6_cpu_init,
-	.exit		= powernow_k6_cpu_exit,
-	.get		= powernow_k6_get,
-	.name		= "powernow-k6",
-	.owner		= THIS_MODULE,
-	.attr		= powernow_k6_attr,
-};
-
-
-/**
- * powernow_k6_init - initializes the k6 PowerNow! CPUFreq driver
- *
- *   Initializes the K6 PowerNow! support. Returns -ENODEV on unsupported
- * devices, -EINVAL or -ENOMEM on problems during initiatization, and zero
- * on success.
- */
-static int __init powernow_k6_init(void)
-{
-	struct cpuinfo_x86 *c = &cpu_data(0);
-
-	if ((c->x86_vendor != X86_VENDOR_AMD) || (c->x86 != 5) ||
-		((c->x86_model != 12) && (c->x86_model != 13)))
-		return -ENODEV;
-
-	if (!request_region(POWERNOW_IOPORT, 16, "PowerNow!")) {
-		printk(KERN_INFO PFX "PowerNow IOPORT region already used.\n");
-		return -EIO;
-	}
-
-	if (cpufreq_register_driver(&powernow_k6_driver)) {
-		release_region(POWERNOW_IOPORT, 16);
-		return -EINVAL;
-	}
-
-	return 0;
-}
-
-
-/**
- * powernow_k6_exit - unregisters AMD K6-2+/3+ PowerNow! support
- *
- *   Unregisters AMD K6-2+ / K6-3+ PowerNow! support.
- */
-static void __exit powernow_k6_exit(void)
-{
-	cpufreq_unregister_driver(&powernow_k6_driver);
-	release_region(POWERNOW_IOPORT, 16);
-}
-
-
-MODULE_AUTHOR("Arjan van de Ven, Dave Jones <davej@redhat.com>, "
-		"Dominik Brodowski <linux@brodo.de>");
-MODULE_DESCRIPTION("PowerNow! driver for AMD K6-2+ / K6-3+ processors.");
-MODULE_LICENSE("GPL");
-
-module_init(powernow_k6_init);
-module_exit(powernow_k6_exit);
diff -druN linux-2.6.39-libre/arch/x86/kernel/cpu/cpufreq/powernow-k7.c linux-3.0-rc7-libre/arch/x86/kernel/cpu/cpufreq/powernow-k7.c
--- linux-2.6.39-libre/arch/x86/kernel/cpu/cpufreq/powernow-k7.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/kernel/cpu/cpufreq/powernow-k7.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,752 +0,0 @@
-/*
- *  AMD K7 Powernow driver.
- *  (C) 2003 Dave Jones on behalf of SuSE Labs.
- *  (C) 2003-2004 Dave Jones <davej@redhat.com>
- *
- *  Licensed under the terms of the GNU GPL License version 2.
- *  Based upon datasheets & sample CPUs kindly provided by AMD.
- *
- * Errata 5:
- *  CPU may fail to execute a FID/VID change in presence of interrupt.
- *  - We cli/sti on stepping A0 CPUs around the FID/VID transition.
- * Errata 15:
- *  CPU with half frequency multipliers may hang upon wakeup from disconnect.
- *  - We disable half multipliers if ACPI is used on A0 stepping CPUs.
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/init.h>
-#include <linux/cpufreq.h>
-#include <linux/slab.h>
-#include <linux/string.h>
-#include <linux/dmi.h>
-#include <linux/timex.h>
-#include <linux/io.h>
-
-#include <asm/timer.h>		/* Needed for recalibrate_cpu_khz() */
-#include <asm/msr.h>
-#include <asm/system.h>
-
-#ifdef CONFIG_X86_POWERNOW_K7_ACPI
-#include <linux/acpi.h>
-#include <acpi/processor.h>
-#endif
-
-#include "powernow-k7.h"
-
-#define PFX "powernow: "
-
-
-struct psb_s {
-	u8 signature[10];
-	u8 tableversion;
-	u8 flags;
-	u16 settlingtime;
-	u8 reserved1;
-	u8 numpst;
-};
-
-struct pst_s {
-	u32 cpuid;
-	u8 fsbspeed;
-	u8 maxfid;
-	u8 startvid;
-	u8 numpstates;
-};
-
-#ifdef CONFIG_X86_POWERNOW_K7_ACPI
-union powernow_acpi_control_t {
-	struct {
-		unsigned long fid:5,
-			vid:5,
-			sgtc:20,
-			res1:2;
-	} bits;
-	unsigned long val;
-};
-#endif
-
-#ifdef CONFIG_CPU_FREQ_DEBUG
-/* divide by 1000 to get VCore voltage in V. */
-static const int mobile_vid_table[32] = {
-    2000, 1950, 1900, 1850, 1800, 1750, 1700, 1650,
-    1600, 1550, 1500, 1450, 1400, 1350, 1300, 0,
-    1275, 1250, 1225, 1200, 1175, 1150, 1125, 1100,
-    1075, 1050, 1025, 1000, 975, 950, 925, 0,
-};
-#endif
-
-/* divide by 10 to get FID. */
-static const int fid_codes[32] = {
-    110, 115, 120, 125, 50, 55, 60, 65,
-    70, 75, 80, 85, 90, 95, 100, 105,
-    30, 190, 40, 200, 130, 135, 140, 210,
-    150, 225, 160, 165, 170, 180, -1, -1,
-};
-
-/* This parameter is used in order to force ACPI instead of legacy method for
- * configuration purpose.
- */
-
-static int acpi_force;
-
-static struct cpufreq_frequency_table *powernow_table;
-
-static unsigned int can_scale_bus;
-static unsigned int can_scale_vid;
-static unsigned int minimum_speed = -1;
-static unsigned int maximum_speed;
-static unsigned int number_scales;
-static unsigned int fsb;
-static unsigned int latency;
-static char have_a0;
-
-#define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, \
-		"powernow-k7", msg)
-
-static int check_fsb(unsigned int fsbspeed)
-{
-	int delta;
-	unsigned int f = fsb / 1000;
-
-	delta = (fsbspeed > f) ? fsbspeed - f : f - fsbspeed;
-	return delta < 5;
-}
-
-static int check_powernow(void)
-{
-	struct cpuinfo_x86 *c = &cpu_data(0);
-	unsigned int maxei, eax, ebx, ecx, edx;
-
-	if ((c->x86_vendor != X86_VENDOR_AMD) || (c->x86 != 6)) {
-#ifdef MODULE
-		printk(KERN_INFO PFX "This module only works with "
-				"AMD K7 CPUs\n");
-#endif
-		return 0;
-	}
-
-	/* Get maximum capabilities */
-	maxei = cpuid_eax(0x80000000);
-	if (maxei < 0x80000007) {	/* Any powernow info ? */
-#ifdef MODULE
-		printk(KERN_INFO PFX "No powernow capabilities detected\n");
-#endif
-		return 0;
-	}
-
-	if ((c->x86_model == 6) && (c->x86_mask == 0)) {
-		printk(KERN_INFO PFX "K7 660[A0] core detected, "
-				"enabling errata workarounds\n");
-		have_a0 = 1;
-	}
-
-	cpuid(0x80000007, &eax, &ebx, &ecx, &edx);
-
-	/* Check we can actually do something before we say anything.*/
-	if (!(edx & (1 << 1 | 1 << 2)))
-		return 0;
-
-	printk(KERN_INFO PFX "PowerNOW! Technology present. Can scale: ");
-
-	if (edx & 1 << 1) {
-		printk("frequency");
-		can_scale_bus = 1;
-	}
-
-	if ((edx & (1 << 1 | 1 << 2)) == 0x6)
-		printk(" and ");
-
-	if (edx & 1 << 2) {
-		printk("voltage");
-		can_scale_vid = 1;
-	}
-
-	printk(".\n");
-	return 1;
-}
-
-#ifdef CONFIG_X86_POWERNOW_K7_ACPI
-static void invalidate_entry(unsigned int entry)
-{
-	powernow_table[entry].frequency = CPUFREQ_ENTRY_INVALID;
-}
-#endif
-
-static int get_ranges(unsigned char *pst)
-{
-	unsigned int j;
-	unsigned int speed;
-	u8 fid, vid;
-
-	powernow_table = kzalloc((sizeof(struct cpufreq_frequency_table) *
-				(number_scales + 1)), GFP_KERNEL);
-	if (!powernow_table)
-		return -ENOMEM;
-
-	for (j = 0 ; j < number_scales; j++) {
-		fid = *pst++;
-
-		powernow_table[j].frequency = (fsb * fid_codes[fid]) / 10;
-		powernow_table[j].index = fid; /* lower 8 bits */
-
-		speed = powernow_table[j].frequency;
-
-		if ((fid_codes[fid] % 10) == 5) {
-#ifdef CONFIG_X86_POWERNOW_K7_ACPI
-			if (have_a0 == 1)
-				invalidate_entry(j);
-#endif
-		}
-
-		if (speed < minimum_speed)
-			minimum_speed = speed;
-		if (speed > maximum_speed)
-			maximum_speed = speed;
-
-		vid = *pst++;
-		powernow_table[j].index |= (vid << 8); /* upper 8 bits */
-
-		dprintk("   FID: 0x%x (%d.%dx [%dMHz])  "
-			 "VID: 0x%x (%d.%03dV)\n", fid, fid_codes[fid] / 10,
-			 fid_codes[fid] % 10, speed/1000, vid,
-			 mobile_vid_table[vid]/1000,
-			 mobile_vid_table[vid]%1000);
-	}
-	powernow_table[number_scales].frequency = CPUFREQ_TABLE_END;
-	powernow_table[number_scales].index = 0;
-
-	return 0;
-}
-
-
-static void change_FID(int fid)
-{
-	union msr_fidvidctl fidvidctl;
-
-	rdmsrl(MSR_K7_FID_VID_CTL, fidvidctl.val);
-	if (fidvidctl.bits.FID != fid) {
-		fidvidctl.bits.SGTC = latency;
-		fidvidctl.bits.FID = fid;
-		fidvidctl.bits.VIDC = 0;
-		fidvidctl.bits.FIDC = 1;
-		wrmsrl(MSR_K7_FID_VID_CTL, fidvidctl.val);
-	}
-}
-
-
-static void change_VID(int vid)
-{
-	union msr_fidvidctl fidvidctl;
-
-	rdmsrl(MSR_K7_FID_VID_CTL, fidvidctl.val);
-	if (fidvidctl.bits.VID != vid) {
-		fidvidctl.bits.SGTC = latency;
-		fidvidctl.bits.VID = vid;
-		fidvidctl.bits.FIDC = 0;
-		fidvidctl.bits.VIDC = 1;
-		wrmsrl(MSR_K7_FID_VID_CTL, fidvidctl.val);
-	}
-}
-
-
-static void change_speed(unsigned int index)
-{
-	u8 fid, vid;
-	struct cpufreq_freqs freqs;
-	union msr_fidvidstatus fidvidstatus;
-	int cfid;
-
-	/* fid are the lower 8 bits of the index we stored into
-	 * the cpufreq frequency table in powernow_decode_bios,
-	 * vid are the upper 8 bits.
-	 */
-
-	fid = powernow_table[index].index & 0xFF;
-	vid = (powernow_table[index].index & 0xFF00) >> 8;
-
-	freqs.cpu = 0;
-
-	rdmsrl(MSR_K7_FID_VID_STATUS, fidvidstatus.val);
-	cfid = fidvidstatus.bits.CFID;
-	freqs.old = fsb * fid_codes[cfid] / 10;
-
-	freqs.new = powernow_table[index].frequency;
-
-	cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
-
-	/* Now do the magic poking into the MSRs.  */
-
-	if (have_a0 == 1)	/* A0 errata 5 */
-		local_irq_disable();
-
-	if (freqs.old > freqs.new) {
-		/* Going down, so change FID first */
-		change_FID(fid);
-		change_VID(vid);
-	} else {
-		/* Going up, so change VID first */
-		change_VID(vid);
-		change_FID(fid);
-	}
-
-
-	if (have_a0 == 1)
-		local_irq_enable();
-
-	cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
-}
-
-
-#ifdef CONFIG_X86_POWERNOW_K7_ACPI
-
-static struct acpi_processor_performance *acpi_processor_perf;
-
-static int powernow_acpi_init(void)
-{
-	int i;
-	int retval = 0;
-	union powernow_acpi_control_t pc;
-
-	if (acpi_processor_perf != NULL && powernow_table != NULL) {
-		retval = -EINVAL;
-		goto err0;
-	}
-
-	acpi_processor_perf = kzalloc(sizeof(struct acpi_processor_performance),
-				      GFP_KERNEL);
-	if (!acpi_processor_perf) {
-		retval = -ENOMEM;
-		goto err0;
-	}
-
-	if (!zalloc_cpumask_var(&acpi_processor_perf->shared_cpu_map,
-								GFP_KERNEL)) {
-		retval = -ENOMEM;
-		goto err05;
-	}
-
-	if (acpi_processor_register_performance(acpi_processor_perf, 0)) {
-		retval = -EIO;
-		goto err1;
-	}
-
-	if (acpi_processor_perf->control_register.space_id !=
-			ACPI_ADR_SPACE_FIXED_HARDWARE) {
-		retval = -ENODEV;
-		goto err2;
-	}
-
-	if (acpi_processor_perf->status_register.space_id !=
-			ACPI_ADR_SPACE_FIXED_HARDWARE) {
-		retval = -ENODEV;
-		goto err2;
-	}
-
-	number_scales = acpi_processor_perf->state_count;
-
-	if (number_scales < 2) {
-		retval = -ENODEV;
-		goto err2;
-	}
-
-	powernow_table = kzalloc((sizeof(struct cpufreq_frequency_table) *
-				(number_scales + 1)), GFP_KERNEL);
-	if (!powernow_table) {
-		retval = -ENOMEM;
-		goto err2;
-	}
-
-	pc.val = (unsigned long) acpi_processor_perf->states[0].control;
-	for (i = 0; i < number_scales; i++) {
-		u8 fid, vid;
-		struct acpi_processor_px *state =
-			&acpi_processor_perf->states[i];
-		unsigned int speed, speed_mhz;
-
-		pc.val = (unsigned long) state->control;
-		dprintk("acpi:  P%d: %d MHz %d mW %d uS control %08x SGTC %d\n",
-			 i,
-			 (u32) state->core_frequency,
-			 (u32) state->power,
-			 (u32) state->transition_latency,
-			 (u32) state->control,
-			 pc.bits.sgtc);
-
-		vid = pc.bits.vid;
-		fid = pc.bits.fid;
-
-		powernow_table[i].frequency = fsb * fid_codes[fid] / 10;
-		powernow_table[i].index = fid; /* lower 8 bits */
-		powernow_table[i].index |= (vid << 8); /* upper 8 bits */
-
-		speed = powernow_table[i].frequency;
-		speed_mhz = speed / 1000;
-
-		/* processor_perflib will multiply the MHz value by 1000 to
-		 * get a KHz value (e.g. 1266000). However, powernow-k7 works
-		 * with true KHz values (e.g. 1266768). To ensure that all
-		 * powernow frequencies are available, we must ensure that
-		 * ACPI doesn't restrict them, so we round up the MHz value
-		 * to ensure that perflib's computed KHz value is greater than
-		 * or equal to powernow's KHz value.
-		 */
-		if (speed % 1000 > 0)
-			speed_mhz++;
-
-		if ((fid_codes[fid] % 10) == 5) {
-			if (have_a0 == 1)
-				invalidate_entry(i);
-		}
-
-		dprintk("   FID: 0x%x (%d.%dx [%dMHz])  "
-			 "VID: 0x%x (%d.%03dV)\n", fid, fid_codes[fid] / 10,
-			 fid_codes[fid] % 10, speed_mhz, vid,
-			 mobile_vid_table[vid]/1000,
-			 mobile_vid_table[vid]%1000);
-
-		if (state->core_frequency != speed_mhz) {
-			state->core_frequency = speed_mhz;
-			dprintk("   Corrected ACPI frequency to %d\n",
-				speed_mhz);
-		}
-
-		if (latency < pc.bits.sgtc)
-			latency = pc.bits.sgtc;
-
-		if (speed < minimum_speed)
-			minimum_speed = speed;
-		if (speed > maximum_speed)
-			maximum_speed = speed;
-	}
-
-	powernow_table[i].frequency = CPUFREQ_TABLE_END;
-	powernow_table[i].index = 0;
-
-	/* notify BIOS that we exist */
-	acpi_processor_notify_smm(THIS_MODULE);
-
-	return 0;
-
-err2:
-	acpi_processor_unregister_performance(acpi_processor_perf, 0);
-err1:
-	free_cpumask_var(acpi_processor_perf->shared_cpu_map);
-err05:
-	kfree(acpi_processor_perf);
-err0:
-	printk(KERN_WARNING PFX "ACPI perflib can not be used on "
-			"this platform\n");
-	acpi_processor_perf = NULL;
-	return retval;
-}
-#else
-static int powernow_acpi_init(void)
-{
-	printk(KERN_INFO PFX "no support for ACPI processor found."
-	       "  Please recompile your kernel with ACPI processor\n");
-	return -EINVAL;
-}
-#endif
-
-static void print_pst_entry(struct pst_s *pst, unsigned int j)
-{
-	dprintk("PST:%d (@%p)\n", j, pst);
-	dprintk(" cpuid: 0x%x  fsb: %d  maxFID: 0x%x  startvid: 0x%x\n",
-		pst->cpuid, pst->fsbspeed, pst->maxfid, pst->startvid);
-}
-
-static int powernow_decode_bios(int maxfid, int startvid)
-{
-	struct psb_s *psb;
-	struct pst_s *pst;
-	unsigned int i, j;
-	unsigned char *p;
-	unsigned int etuple;
-	unsigned int ret;
-
-	etuple = cpuid_eax(0x80000001);
-
-	for (i = 0xC0000; i < 0xffff0 ; i += 16) {
-
-		p = phys_to_virt(i);
-
-		if (memcmp(p, "AMDK7PNOW!",  10) == 0) {
-			dprintk("Found PSB header at %p\n", p);
-			psb = (struct psb_s *) p;
-			dprintk("Table version: 0x%x\n", psb->tableversion);
-			if (psb->tableversion != 0x12) {
-				printk(KERN_INFO PFX "Sorry, only v1.2 tables"
-						" supported right now\n");
-				return -ENODEV;
-			}
-
-			dprintk("Flags: 0x%x\n", psb->flags);
-			if ((psb->flags & 1) == 0)
-				dprintk("Mobile voltage regulator\n");
-			else
-				dprintk("Desktop voltage regulator\n");
-
-			latency = psb->settlingtime;
-			if (latency < 100) {
-				printk(KERN_INFO PFX "BIOS set settling time "
-						"to %d microseconds. "
-						"Should be at least 100. "
-						"Correcting.\n", latency);
-				latency = 100;
-			}
-			dprintk("Settling Time: %d microseconds.\n",
-					psb->settlingtime);
-			dprintk("Has %d PST tables. (Only dumping ones "
-					"relevant to this CPU).\n",
-					psb->numpst);
-
-			p += sizeof(struct psb_s);
-
-			pst = (struct pst_s *) p;
-
-			for (j = 0; j < psb->numpst; j++) {
-				pst = (struct pst_s *) p;
-				number_scales = pst->numpstates;
-
-				if ((etuple == pst->cpuid) &&
-				    check_fsb(pst->fsbspeed) &&
-				    (maxfid == pst->maxfid) &&
-				    (startvid == pst->startvid)) {
-					print_pst_entry(pst, j);
-					p = (char *)pst + sizeof(struct pst_s);
-					ret = get_ranges(p);
-					return ret;
-				} else {
-					unsigned int k;
-					p = (char *)pst + sizeof(struct pst_s);
-					for (k = 0; k < number_scales; k++)
-						p += 2;
-				}
-			}
-			printk(KERN_INFO PFX "No PST tables match this cpuid "
-					"(0x%x)\n", etuple);
-			printk(KERN_INFO PFX "This is indicative of a broken "
-					"BIOS.\n");
-
-			return -EINVAL;
-		}
-		p++;
-	}
-
-	return -ENODEV;
-}
-
-
-static int powernow_target(struct cpufreq_policy *policy,
-			    unsigned int target_freq,
-			    unsigned int relation)
-{
-	unsigned int newstate;
-
-	if (cpufreq_frequency_table_target(policy, powernow_table, target_freq,
-				relation, &newstate))
-		return -EINVAL;
-
-	change_speed(newstate);
-
-	return 0;
-}
-
-
-static int powernow_verify(struct cpufreq_policy *policy)
-{
-	return cpufreq_frequency_table_verify(policy, powernow_table);
-}
-
-/*
- * We use the fact that the bus frequency is somehow
- * a multiple of 100000/3 khz, then we compute sgtc according
- * to this multiple.
- * That way, we match more how AMD thinks all of that work.
- * We will then get the same kind of behaviour already tested under
- * the "well-known" other OS.
- */
-static int __cpuinit fixup_sgtc(void)
-{
-	unsigned int sgtc;
-	unsigned int m;
-
-	m = fsb / 3333;
-	if ((m % 10) >= 5)
-		m += 5;
-
-	m /= 10;
-
-	sgtc = 100 * m * latency;
-	sgtc = sgtc / 3;
-	if (sgtc > 0xfffff) {
-		printk(KERN_WARNING PFX "SGTC too large %d\n", sgtc);
-		sgtc = 0xfffff;
-	}
-	return sgtc;
-}
-
-static unsigned int powernow_get(unsigned int cpu)
-{
-	union msr_fidvidstatus fidvidstatus;
-	unsigned int cfid;
-
-	if (cpu)
-		return 0;
-	rdmsrl(MSR_K7_FID_VID_STATUS, fidvidstatus.val);
-	cfid = fidvidstatus.bits.CFID;
-
-	return fsb * fid_codes[cfid] / 10;
-}
-
-
-static int __cpuinit acer_cpufreq_pst(const struct dmi_system_id *d)
-{
-	printk(KERN_WARNING PFX
-		"%s laptop with broken PST tables in BIOS detected.\n",
-		d->ident);
-	printk(KERN_WARNING PFX
-		"You need to downgrade to 3A21 (09/09/2002), or try a newer "
-		"BIOS than 3A71 (01/20/2003)\n");
-	printk(KERN_WARNING PFX
-		"cpufreq scaling has been disabled as a result of this.\n");
-	return 0;
-}
-
-/*
- * Some Athlon laptops have really fucked PST tables.
- * A BIOS update is all that can save them.
- * Mention this, and disable cpufreq.
- */
-static struct dmi_system_id __cpuinitdata powernow_dmi_table[] = {
-	{
-		.callback = acer_cpufreq_pst,
-		.ident = "Acer Aspire",
-		.matches = {
-			DMI_MATCH(DMI_SYS_VENDOR, "Insyde Software"),
-			DMI_MATCH(DMI_BIOS_VERSION, "3A71"),
-		},
-	},
-	{ }
-};
-
-static int __cpuinit powernow_cpu_init(struct cpufreq_policy *policy)
-{
-	union msr_fidvidstatus fidvidstatus;
-	int result;
-
-	if (policy->cpu != 0)
-		return -ENODEV;
-
-	rdmsrl(MSR_K7_FID_VID_STATUS, fidvidstatus.val);
-
-	recalibrate_cpu_khz();
-
-	fsb = (10 * cpu_khz) / fid_codes[fidvidstatus.bits.CFID];
-	if (!fsb) {
-		printk(KERN_WARNING PFX "can not determine bus frequency\n");
-		return -EINVAL;
-	}
-	dprintk("FSB: %3dMHz\n", fsb/1000);
-
-	if (dmi_check_system(powernow_dmi_table) || acpi_force) {
-		printk(KERN_INFO PFX "PSB/PST known to be broken.  "
-				"Trying ACPI instead\n");
-		result = powernow_acpi_init();
-	} else {
-		result = powernow_decode_bios(fidvidstatus.bits.MFID,
-				fidvidstatus.bits.SVID);
-		if (result) {
-			printk(KERN_INFO PFX "Trying ACPI perflib\n");
-			maximum_speed = 0;
-			minimum_speed = -1;
-			latency = 0;
-			result = powernow_acpi_init();
-			if (result) {
-				printk(KERN_INFO PFX
-					"ACPI and legacy methods failed\n");
-			}
-		} else {
-			/* SGTC use the bus clock as timer */
-			latency = fixup_sgtc();
-			printk(KERN_INFO PFX "SGTC: %d\n", latency);
-		}
-	}
-
-	if (result)
-		return result;
-
-	printk(KERN_INFO PFX "Minimum speed %d MHz. Maximum speed %d MHz.\n",
-				minimum_speed/1000, maximum_speed/1000);
-
-	policy->cpuinfo.transition_latency =
-		cpufreq_scale(2000000UL, fsb, latency);
-
-	policy->cur = powernow_get(0);
-
-	cpufreq_frequency_table_get_attr(powernow_table, policy->cpu);
-
-	return cpufreq_frequency_table_cpuinfo(policy, powernow_table);
-}
-
-static int powernow_cpu_exit(struct cpufreq_policy *policy)
-{
-	cpufreq_frequency_table_put_attr(policy->cpu);
-
-#ifdef CONFIG_X86_POWERNOW_K7_ACPI
-	if (acpi_processor_perf) {
-		acpi_processor_unregister_performance(acpi_processor_perf, 0);
-		free_cpumask_var(acpi_processor_perf->shared_cpu_map);
-		kfree(acpi_processor_perf);
-	}
-#endif
-
-	kfree(powernow_table);
-	return 0;
-}
-
-static struct freq_attr *powernow_table_attr[] = {
-	&cpufreq_freq_attr_scaling_available_freqs,
-	NULL,
-};
-
-static struct cpufreq_driver powernow_driver = {
-	.verify		= powernow_verify,
-	.target		= powernow_target,
-	.get		= powernow_get,
-#ifdef CONFIG_X86_POWERNOW_K7_ACPI
-	.bios_limit	= acpi_processor_get_bios_limit,
-#endif
-	.init		= powernow_cpu_init,
-	.exit		= powernow_cpu_exit,
-	.name		= "powernow-k7",
-	.owner		= THIS_MODULE,
-	.attr		= powernow_table_attr,
-};
-
-static int __init powernow_init(void)
-{
-	if (check_powernow() == 0)
-		return -ENODEV;
-	return cpufreq_register_driver(&powernow_driver);
-}
-
-
-static void __exit powernow_exit(void)
-{
-	cpufreq_unregister_driver(&powernow_driver);
-}
-
-module_param(acpi_force,  int, 0444);
-MODULE_PARM_DESC(acpi_force, "Force ACPI to be used.");
-
-MODULE_AUTHOR("Dave Jones <davej@redhat.com>");
-MODULE_DESCRIPTION("Powernow driver for AMD K7 processors.");
-MODULE_LICENSE("GPL");
-
-late_initcall(powernow_init);
-module_exit(powernow_exit);
-
diff -druN linux-2.6.39-libre/arch/x86/kernel/cpu/cpufreq/powernow-k7.h linux-3.0-rc7-libre/arch/x86/kernel/cpu/cpufreq/powernow-k7.h
--- linux-2.6.39-libre/arch/x86/kernel/cpu/cpufreq/powernow-k7.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/kernel/cpu/cpufreq/powernow-k7.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,43 +0,0 @@
-/*
- *  (C) 2003 Dave Jones.
- *
- *  Licensed under the terms of the GNU GPL License version 2.
- *
- *  AMD-specific information
- *
- */
-
-union msr_fidvidctl {
-	struct {
-		unsigned FID:5,			// 4:0
-		reserved1:3,	// 7:5
-		VID:5,			// 12:8
-		reserved2:3,	// 15:13
-		FIDC:1,			// 16
-		VIDC:1,			// 17
-		reserved3:2,	// 19:18
-		FIDCHGRATIO:1,	// 20
-		reserved4:11,	// 31-21
-		SGTC:20,		// 32:51
-		reserved5:12;	// 63:52
-	} bits;
-	unsigned long long val;
-};
-
-union msr_fidvidstatus {
-	struct {
-		unsigned CFID:5,			// 4:0
-		reserved1:3,	// 7:5
-		SFID:5,			// 12:8
-		reserved2:3,	// 15:13
-		MFID:5,			// 20:16
-		reserved3:11,	// 31:21
-		CVID:5,			// 36:32
-		reserved4:3,	// 39:37
-		SVID:5,			// 44:40
-		reserved5:3,	// 47:45
-		MVID:5,			// 52:48
-		reserved6:11;	// 63:53
-	} bits;
-	unsigned long long val;
-};
diff -druN linux-2.6.39-libre/arch/x86/kernel/cpu/cpufreq/powernow-k8.c linux-3.0-rc7-libre/arch/x86/kernel/cpu/cpufreq/powernow-k8.c
--- linux-2.6.39-libre/arch/x86/kernel/cpu/cpufreq/powernow-k8.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/kernel/cpu/cpufreq/powernow-k8.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,1607 +0,0 @@
-/*
- *   (c) 2003-2010 Advanced Micro Devices, Inc.
- *  Your use of this code is subject to the terms and conditions of the
- *  GNU general public license version 2. See "COPYING" or
- *  http://www.gnu.org/licenses/gpl.html
- *
- *  Support : mark.langsdorf@amd.com
- *
- *  Based on the powernow-k7.c module written by Dave Jones.
- *  (C) 2003 Dave Jones on behalf of SuSE Labs
- *  (C) 2004 Dominik Brodowski <linux@brodo.de>
- *  (C) 2004 Pavel Machek <pavel@ucw.cz>
- *  Licensed under the terms of the GNU GPL License version 2.
- *  Based upon datasheets & sample CPUs kindly provided by AMD.
- *
- *  Valuable input gratefully received from Dave Jones, Pavel Machek,
- *  Dominik Brodowski, Jacob Shin, and others.
- *  Originally developed by Paul Devriendt.
- *  Processor information obtained from Chapter 9 (Power and Thermal Management)
- *  of the "BIOS and Kernel Developer's Guide for the AMD Athlon 64 and AMD
- *  Opteron Processors" available for download from www.amd.com
- *
- *  Tables for specific CPUs can be inferred from
- *     http://www.amd.com/us-en/assets/content_type/white_papers_and_tech_docs/30430.pdf
- */
-
-#include <linux/kernel.h>
-#include <linux/smp.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/cpufreq.h>
-#include <linux/slab.h>
-#include <linux/string.h>
-#include <linux/cpumask.h>
-#include <linux/sched.h>	/* for current / set_cpus_allowed() */
-#include <linux/io.h>
-#include <linux/delay.h>
-
-#include <asm/msr.h>
-
-#include <linux/acpi.h>
-#include <linux/mutex.h>
-#include <acpi/processor.h>
-
-#define PFX "powernow-k8: "
-#define VERSION "version 2.20.00"
-#include "powernow-k8.h"
-#include "mperf.h"
-
-/* serialize freq changes  */
-static DEFINE_MUTEX(fidvid_mutex);
-
-static DEFINE_PER_CPU(struct powernow_k8_data *, powernow_data);
-
-static int cpu_family = CPU_OPTERON;
-
-/* core performance boost */
-static bool cpb_capable, cpb_enabled;
-static struct msr __percpu *msrs;
-
-static struct cpufreq_driver cpufreq_amd64_driver;
-
-#ifndef CONFIG_SMP
-static inline const struct cpumask *cpu_core_mask(int cpu)
-{
-	return cpumask_of(0);
-}
-#endif
-
-/* Return a frequency in MHz, given an input fid */
-static u32 find_freq_from_fid(u32 fid)
-{
-	return 800 + (fid * 100);
-}
-
-/* Return a frequency in KHz, given an input fid */
-static u32 find_khz_freq_from_fid(u32 fid)
-{
-	return 1000 * find_freq_from_fid(fid);
-}
-
-static u32 find_khz_freq_from_pstate(struct cpufreq_frequency_table *data,
-		u32 pstate)
-{
-	return data[pstate].frequency;
-}
-
-/* Return the vco fid for an input fid
- *
- * Each "low" fid has corresponding "high" fid, and you can get to "low" fids
- * only from corresponding high fids. This returns "high" fid corresponding to
- * "low" one.
- */
-static u32 convert_fid_to_vco_fid(u32 fid)
-{
-	if (fid < HI_FID_TABLE_BOTTOM)
-		return 8 + (2 * fid);
-	else
-		return fid;
-}
-
-/*
- * Return 1 if the pending bit is set. Unless we just instructed the processor
- * to transition to a new state, seeing this bit set is really bad news.
- */
-static int pending_bit_stuck(void)
-{
-	u32 lo, hi;
-
-	if (cpu_family == CPU_HW_PSTATE)
-		return 0;
-
-	rdmsr(MSR_FIDVID_STATUS, lo, hi);
-	return lo & MSR_S_LO_CHANGE_PENDING ? 1 : 0;
-}
-
-/*
- * Update the global current fid / vid values from the status msr.
- * Returns 1 on error.
- */
-static int query_current_values_with_pending_wait(struct powernow_k8_data *data)
-{
-	u32 lo, hi;
-	u32 i = 0;
-
-	if (cpu_family == CPU_HW_PSTATE) {
-		rdmsr(MSR_PSTATE_STATUS, lo, hi);
-		i = lo & HW_PSTATE_MASK;
-		data->currpstate = i;
-
-		/*
-		 * a workaround for family 11h erratum 311 might cause
-		 * an "out-of-range Pstate if the core is in Pstate-0
-		 */
-		if ((boot_cpu_data.x86 == 0x11) && (i >= data->numps))
-			data->currpstate = HW_PSTATE_0;
-
-		return 0;
-	}
-	do {
-		if (i++ > 10000) {
-			dprintk("detected change pending stuck\n");
-			return 1;
-		}
-		rdmsr(MSR_FIDVID_STATUS, lo, hi);
-	} while (lo & MSR_S_LO_CHANGE_PENDING);
-
-	data->currvid = hi & MSR_S_HI_CURRENT_VID;
-	data->currfid = lo & MSR_S_LO_CURRENT_FID;
-
-	return 0;
-}
-
-/* the isochronous relief time */
-static void count_off_irt(struct powernow_k8_data *data)
-{
-	udelay((1 << data->irt) * 10);
-	return;
-}
-
-/* the voltage stabilization time */
-static void count_off_vst(struct powernow_k8_data *data)
-{
-	udelay(data->vstable * VST_UNITS_20US);
-	return;
-}
-
-/* need to init the control msr to a safe value (for each cpu) */
-static void fidvid_msr_init(void)
-{
-	u32 lo, hi;
-	u8 fid, vid;
-
-	rdmsr(MSR_FIDVID_STATUS, lo, hi);
-	vid = hi & MSR_S_HI_CURRENT_VID;
-	fid = lo & MSR_S_LO_CURRENT_FID;
-	lo = fid | (vid << MSR_C_LO_VID_SHIFT);
-	hi = MSR_C_HI_STP_GNT_BENIGN;
-	dprintk("cpu%d, init lo 0x%x, hi 0x%x\n", smp_processor_id(), lo, hi);
-	wrmsr(MSR_FIDVID_CTL, lo, hi);
-}
-
-/* write the new fid value along with the other control fields to the msr */
-static int write_new_fid(struct powernow_k8_data *data, u32 fid)
-{
-	u32 lo;
-	u32 savevid = data->currvid;
-	u32 i = 0;
-
-	if ((fid & INVALID_FID_MASK) || (data->currvid & INVALID_VID_MASK)) {
-		printk(KERN_ERR PFX "internal error - overflow on fid write\n");
-		return 1;
-	}
-
-	lo = fid;
-	lo |= (data->currvid << MSR_C_LO_VID_SHIFT);
-	lo |= MSR_C_LO_INIT_FID_VID;
-
-	dprintk("writing fid 0x%x, lo 0x%x, hi 0x%x\n",
-		fid, lo, data->plllock * PLL_LOCK_CONVERSION);
-
-	do {
-		wrmsr(MSR_FIDVID_CTL, lo, data->plllock * PLL_LOCK_CONVERSION);
-		if (i++ > 100) {
-			printk(KERN_ERR PFX
-				"Hardware error - pending bit very stuck - "
-				"no further pstate changes possible\n");
-			return 1;
-		}
-	} while (query_current_values_with_pending_wait(data));
-
-	count_off_irt(data);
-
-	if (savevid != data->currvid) {
-		printk(KERN_ERR PFX
-			"vid change on fid trans, old 0x%x, new 0x%x\n",
-			savevid, data->currvid);
-		return 1;
-	}
-
-	if (fid != data->currfid) {
-		printk(KERN_ERR PFX
-			"fid trans failed, fid 0x%x, curr 0x%x\n", fid,
-			data->currfid);
-		return 1;
-	}
-
-	return 0;
-}
-
-/* Write a new vid to the hardware */
-static int write_new_vid(struct powernow_k8_data *data, u32 vid)
-{
-	u32 lo;
-	u32 savefid = data->currfid;
-	int i = 0;
-
-	if ((data->currfid & INVALID_FID_MASK) || (vid & INVALID_VID_MASK)) {
-		printk(KERN_ERR PFX "internal error - overflow on vid write\n");
-		return 1;
-	}
-
-	lo = data->currfid;
-	lo |= (vid << MSR_C_LO_VID_SHIFT);
-	lo |= MSR_C_LO_INIT_FID_VID;
-
-	dprintk("writing vid 0x%x, lo 0x%x, hi 0x%x\n",
-		vid, lo, STOP_GRANT_5NS);
-
-	do {
-		wrmsr(MSR_FIDVID_CTL, lo, STOP_GRANT_5NS);
-		if (i++ > 100) {
-			printk(KERN_ERR PFX "internal error - pending bit "
-					"very stuck - no further pstate "
-					"changes possible\n");
-			return 1;
-		}
-	} while (query_current_values_with_pending_wait(data));
-
-	if (savefid != data->currfid) {
-		printk(KERN_ERR PFX "fid changed on vid trans, old "
-			"0x%x new 0x%x\n",
-		       savefid, data->currfid);
-		return 1;
-	}
-
-	if (vid != data->currvid) {
-		printk(KERN_ERR PFX "vid trans failed, vid 0x%x, "
-				"curr 0x%x\n",
-				vid, data->currvid);
-		return 1;
-	}
-
-	return 0;
-}
-
-/*
- * Reduce the vid by the max of step or reqvid.
- * Decreasing vid codes represent increasing voltages:
- * vid of 0 is 1.550V, vid of 0x1e is 0.800V, vid of VID_OFF is off.
- */
-static int decrease_vid_code_by_step(struct powernow_k8_data *data,
-		u32 reqvid, u32 step)
-{
-	if ((data->currvid - reqvid) > step)
-		reqvid = data->currvid - step;
-
-	if (write_new_vid(data, reqvid))
-		return 1;
-
-	count_off_vst(data);
-
-	return 0;
-}
-
-/* Change hardware pstate by single MSR write */
-static int transition_pstate(struct powernow_k8_data *data, u32 pstate)
-{
-	wrmsr(MSR_PSTATE_CTRL, pstate, 0);
-	data->currpstate = pstate;
-	return 0;
-}
-
-/* Change Opteron/Athlon64 fid and vid, by the 3 phases. */
-static int transition_fid_vid(struct powernow_k8_data *data,
-		u32 reqfid, u32 reqvid)
-{
-	if (core_voltage_pre_transition(data, reqvid, reqfid))
-		return 1;
-
-	if (core_frequency_transition(data, reqfid))
-		return 1;
-
-	if (core_voltage_post_transition(data, reqvid))
-		return 1;
-
-	if (query_current_values_with_pending_wait(data))
-		return 1;
-
-	if ((reqfid != data->currfid) || (reqvid != data->currvid)) {
-		printk(KERN_ERR PFX "failed (cpu%d): req 0x%x 0x%x, "
-				"curr 0x%x 0x%x\n",
-				smp_processor_id(),
-				reqfid, reqvid, data->currfid, data->currvid);
-		return 1;
-	}
-
-	dprintk("transitioned (cpu%d): new fid 0x%x, vid 0x%x\n",
-		smp_processor_id(), data->currfid, data->currvid);
-
-	return 0;
-}
-
-/* Phase 1 - core voltage transition ... setup voltage */
-static int core_voltage_pre_transition(struct powernow_k8_data *data,
-		u32 reqvid, u32 reqfid)
-{
-	u32 rvosteps = data->rvo;
-	u32 savefid = data->currfid;
-	u32 maxvid, lo, rvomult = 1;
-
-	dprintk("ph1 (cpu%d): start, currfid 0x%x, currvid 0x%x, "
-		"reqvid 0x%x, rvo 0x%x\n",
-		smp_processor_id(),
-		data->currfid, data->currvid, reqvid, data->rvo);
-
-	if ((savefid < LO_FID_TABLE_TOP) && (reqfid < LO_FID_TABLE_TOP))
-		rvomult = 2;
-	rvosteps *= rvomult;
-	rdmsr(MSR_FIDVID_STATUS, lo, maxvid);
-	maxvid = 0x1f & (maxvid >> 16);
-	dprintk("ph1 maxvid=0x%x\n", maxvid);
-	if (reqvid < maxvid) /* lower numbers are higher voltages */
-		reqvid = maxvid;
-
-	while (data->currvid > reqvid) {
-		dprintk("ph1: curr 0x%x, req vid 0x%x\n",
-			data->currvid, reqvid);
-		if (decrease_vid_code_by_step(data, reqvid, data->vidmvs))
-			return 1;
-	}
-
-	while ((rvosteps > 0) &&
-			((rvomult * data->rvo + data->currvid) > reqvid)) {
-		if (data->currvid == maxvid) {
-			rvosteps = 0;
-		} else {
-			dprintk("ph1: changing vid for rvo, req 0x%x\n",
-				data->currvid - 1);
-			if (decrease_vid_code_by_step(data, data->currvid-1, 1))
-				return 1;
-			rvosteps--;
-		}
-	}
-
-	if (query_current_values_with_pending_wait(data))
-		return 1;
-
-	if (savefid != data->currfid) {
-		printk(KERN_ERR PFX "ph1 err, currfid changed 0x%x\n",
-				data->currfid);
-		return 1;
-	}
-
-	dprintk("ph1 complete, currfid 0x%x, currvid 0x%x\n",
-		data->currfid, data->currvid);
-
-	return 0;
-}
-
-/* Phase 2 - core frequency transition */
-static int core_frequency_transition(struct powernow_k8_data *data, u32 reqfid)
-{
-	u32 vcoreqfid, vcocurrfid, vcofiddiff;
-	u32 fid_interval, savevid = data->currvid;
-
-	if (data->currfid == reqfid) {
-		printk(KERN_ERR PFX "ph2 null fid transition 0x%x\n",
-				data->currfid);
-		return 0;
-	}
-
-	dprintk("ph2 (cpu%d): starting, currfid 0x%x, currvid 0x%x, "
-		"reqfid 0x%x\n",
-		smp_processor_id(),
-		data->currfid, data->currvid, reqfid);
-
-	vcoreqfid = convert_fid_to_vco_fid(reqfid);
-	vcocurrfid = convert_fid_to_vco_fid(data->currfid);
-	vcofiddiff = vcocurrfid > vcoreqfid ? vcocurrfid - vcoreqfid
-	    : vcoreqfid - vcocurrfid;
-
-	if ((reqfid <= LO_FID_TABLE_TOP) && (data->currfid <= LO_FID_TABLE_TOP))
-		vcofiddiff = 0;
-
-	while (vcofiddiff > 2) {
-		(data->currfid & 1) ? (fid_interval = 1) : (fid_interval = 2);
-
-		if (reqfid > data->currfid) {
-			if (data->currfid > LO_FID_TABLE_TOP) {
-				if (write_new_fid(data,
-						data->currfid + fid_interval))
-					return 1;
-			} else {
-				if (write_new_fid
-				    (data,
-				     2 + convert_fid_to_vco_fid(data->currfid)))
-					return 1;
-			}
-		} else {
-			if (write_new_fid(data, data->currfid - fid_interval))
-				return 1;
-		}
-
-		vcocurrfid = convert_fid_to_vco_fid(data->currfid);
-		vcofiddiff = vcocurrfid > vcoreqfid ? vcocurrfid - vcoreqfid
-		    : vcoreqfid - vcocurrfid;
-	}
-
-	if (write_new_fid(data, reqfid))
-		return 1;
-
-	if (query_current_values_with_pending_wait(data))
-		return 1;
-
-	if (data->currfid != reqfid) {
-		printk(KERN_ERR PFX
-			"ph2: mismatch, failed fid transition, "
-			"curr 0x%x, req 0x%x\n",
-			data->currfid, reqfid);
-		return 1;
-	}
-
-	if (savevid != data->currvid) {
-		printk(KERN_ERR PFX "ph2: vid changed, save 0x%x, curr 0x%x\n",
-			savevid, data->currvid);
-		return 1;
-	}
-
-	dprintk("ph2 complete, currfid 0x%x, currvid 0x%x\n",
-		data->currfid, data->currvid);
-
-	return 0;
-}
-
-/* Phase 3 - core voltage transition flow ... jump to the final vid. */
-static int core_voltage_post_transition(struct powernow_k8_data *data,
-		u32 reqvid)
-{
-	u32 savefid = data->currfid;
-	u32 savereqvid = reqvid;
-
-	dprintk("ph3 (cpu%d): starting, currfid 0x%x, currvid 0x%x\n",
-		smp_processor_id(),
-		data->currfid, data->currvid);
-
-	if (reqvid != data->currvid) {
-		if (write_new_vid(data, reqvid))
-			return 1;
-
-		if (savefid != data->currfid) {
-			printk(KERN_ERR PFX
-			       "ph3: bad fid change, save 0x%x, curr 0x%x\n",
-			       savefid, data->currfid);
-			return 1;
-		}
-
-		if (data->currvid != reqvid) {
-			printk(KERN_ERR PFX
-			       "ph3: failed vid transition\n, "
-			       "req 0x%x, curr 0x%x",
-			       reqvid, data->currvid);
-			return 1;
-		}
-	}
-
-	if (query_current_values_with_pending_wait(data))
-		return 1;
-
-	if (savereqvid != data->currvid) {
-		dprintk("ph3 failed, currvid 0x%x\n", data->currvid);
-		return 1;
-	}
-
-	if (savefid != data->currfid) {
-		dprintk("ph3 failed, currfid changed 0x%x\n",
-			data->currfid);
-		return 1;
-	}
-
-	dprintk("ph3 complete, currfid 0x%x, currvid 0x%x\n",
-		data->currfid, data->currvid);
-
-	return 0;
-}
-
-static void check_supported_cpu(void *_rc)
-{
-	u32 eax, ebx, ecx, edx;
-	int *rc = _rc;
-
-	*rc = -ENODEV;
-
-	if (__this_cpu_read(cpu_info.x86_vendor) != X86_VENDOR_AMD)
-		return;
-
-	eax = cpuid_eax(CPUID_PROCESSOR_SIGNATURE);
-	if (((eax & CPUID_XFAM) != CPUID_XFAM_K8) &&
-	    ((eax & CPUID_XFAM) < CPUID_XFAM_10H))
-		return;
-
-	if ((eax & CPUID_XFAM) == CPUID_XFAM_K8) {
-		if (((eax & CPUID_USE_XFAM_XMOD) != CPUID_USE_XFAM_XMOD) ||
-		    ((eax & CPUID_XMOD) > CPUID_XMOD_REV_MASK)) {
-			printk(KERN_INFO PFX
-				"Processor cpuid %x not supported\n", eax);
-			return;
-		}
-
-		eax = cpuid_eax(CPUID_GET_MAX_CAPABILITIES);
-		if (eax < CPUID_FREQ_VOLT_CAPABILITIES) {
-			printk(KERN_INFO PFX
-			       "No frequency change capabilities detected\n");
-			return;
-		}
-
-		cpuid(CPUID_FREQ_VOLT_CAPABILITIES, &eax, &ebx, &ecx, &edx);
-		if ((edx & P_STATE_TRANSITION_CAPABLE)
-			!= P_STATE_TRANSITION_CAPABLE) {
-			printk(KERN_INFO PFX
-				"Power state transitions not supported\n");
-			return;
-		}
-	} else { /* must be a HW Pstate capable processor */
-		cpuid(CPUID_FREQ_VOLT_CAPABILITIES, &eax, &ebx, &ecx, &edx);
-		if ((edx & USE_HW_PSTATE) == USE_HW_PSTATE)
-			cpu_family = CPU_HW_PSTATE;
-		else
-			return;
-	}
-
-	*rc = 0;
-}
-
-static int check_pst_table(struct powernow_k8_data *data, struct pst_s *pst,
-		u8 maxvid)
-{
-	unsigned int j;
-	u8 lastfid = 0xff;
-
-	for (j = 0; j < data->numps; j++) {
-		if (pst[j].vid > LEAST_VID) {
-			printk(KERN_ERR FW_BUG PFX "vid %d invalid : 0x%x\n",
-			       j, pst[j].vid);
-			return -EINVAL;
-		}
-		if (pst[j].vid < data->rvo) {
-			/* vid + rvo >= 0 */
-			printk(KERN_ERR FW_BUG PFX "0 vid exceeded with pstate"
-			       " %d\n", j);
-			return -ENODEV;
-		}
-		if (pst[j].vid < maxvid + data->rvo) {
-			/* vid + rvo >= maxvid */
-			printk(KERN_ERR FW_BUG PFX "maxvid exceeded with pstate"
-			       " %d\n", j);
-			return -ENODEV;
-		}
-		if (pst[j].fid > MAX_FID) {
-			printk(KERN_ERR FW_BUG PFX "maxfid exceeded with pstate"
-			       " %d\n", j);
-			return -ENODEV;
-		}
-		if (j && (pst[j].fid < HI_FID_TABLE_BOTTOM)) {
-			/* Only first fid is allowed to be in "low" range */
-			printk(KERN_ERR FW_BUG PFX "two low fids - %d : "
-			       "0x%x\n", j, pst[j].fid);
-			return -EINVAL;
-		}
-		if (pst[j].fid < lastfid)
-			lastfid = pst[j].fid;
-	}
-	if (lastfid & 1) {
-		printk(KERN_ERR FW_BUG PFX "lastfid invalid\n");
-		return -EINVAL;
-	}
-	if (lastfid > LO_FID_TABLE_TOP)
-		printk(KERN_INFO FW_BUG PFX
-			"first fid not from lo freq table\n");
-
-	return 0;
-}
-
-static void invalidate_entry(struct cpufreq_frequency_table *powernow_table,
-		unsigned int entry)
-{
-	powernow_table[entry].frequency = CPUFREQ_ENTRY_INVALID;
-}
-
-static void print_basics(struct powernow_k8_data *data)
-{
-	int j;
-	for (j = 0; j < data->numps; j++) {
-		if (data->powernow_table[j].frequency !=
-				CPUFREQ_ENTRY_INVALID) {
-			if (cpu_family == CPU_HW_PSTATE) {
-				printk(KERN_INFO PFX
-					"   %d : pstate %d (%d MHz)\n", j,
-					data->powernow_table[j].index,
-					data->powernow_table[j].frequency/1000);
-			} else {
-				printk(KERN_INFO PFX
-					"fid 0x%x (%d MHz), vid 0x%x\n",
-					data->powernow_table[j].index & 0xff,
-					data->powernow_table[j].frequency/1000,
-					data->powernow_table[j].index >> 8);
-			}
-		}
-	}
-	if (data->batps)
-		printk(KERN_INFO PFX "Only %d pstates on battery\n",
-				data->batps);
-}
-
-static u32 freq_from_fid_did(u32 fid, u32 did)
-{
-	u32 mhz = 0;
-
-	if (boot_cpu_data.x86 == 0x10)
-		mhz = (100 * (fid + 0x10)) >> did;
-	else if (boot_cpu_data.x86 == 0x11)
-		mhz = (100 * (fid + 8)) >> did;
-	else
-		BUG();
-
-	return mhz * 1000;
-}
-
-static int fill_powernow_table(struct powernow_k8_data *data,
-		struct pst_s *pst, u8 maxvid)
-{
-	struct cpufreq_frequency_table *powernow_table;
-	unsigned int j;
-
-	if (data->batps) {
-		/* use ACPI support to get full speed on mains power */
-		printk(KERN_WARNING PFX
-			"Only %d pstates usable (use ACPI driver for full "
-			"range\n", data->batps);
-		data->numps = data->batps;
-	}
-
-	for (j = 1; j < data->numps; j++) {
-		if (pst[j-1].fid >= pst[j].fid) {
-			printk(KERN_ERR PFX "PST out of sequence\n");
-			return -EINVAL;
-		}
-	}
-
-	if (data->numps < 2) {
-		printk(KERN_ERR PFX "no p states to transition\n");
-		return -ENODEV;
-	}
-
-	if (check_pst_table(data, pst, maxvid))
-		return -EINVAL;
-
-	powernow_table = kmalloc((sizeof(struct cpufreq_frequency_table)
-		* (data->numps + 1)), GFP_KERNEL);
-	if (!powernow_table) {
-		printk(KERN_ERR PFX "powernow_table memory alloc failure\n");
-		return -ENOMEM;
-	}
-
-	for (j = 0; j < data->numps; j++) {
-		int freq;
-		powernow_table[j].index = pst[j].fid; /* lower 8 bits */
-		powernow_table[j].index |= (pst[j].vid << 8); /* upper 8 bits */
-		freq = find_khz_freq_from_fid(pst[j].fid);
-		powernow_table[j].frequency = freq;
-	}
-	powernow_table[data->numps].frequency = CPUFREQ_TABLE_END;
-	powernow_table[data->numps].index = 0;
-
-	if (query_current_values_with_pending_wait(data)) {
-		kfree(powernow_table);
-		return -EIO;
-	}
-
-	dprintk("cfid 0x%x, cvid 0x%x\n", data->currfid, data->currvid);
-	data->powernow_table = powernow_table;
-	if (cpumask_first(cpu_core_mask(data->cpu)) == data->cpu)
-		print_basics(data);
-
-	for (j = 0; j < data->numps; j++)
-		if ((pst[j].fid == data->currfid) &&
-		    (pst[j].vid == data->currvid))
-			return 0;
-
-	dprintk("currfid/vid do not match PST, ignoring\n");
-	return 0;
-}
-
-/* Find and validate the PSB/PST table in BIOS. */
-static int find_psb_table(struct powernow_k8_data *data)
-{
-	struct psb_s *psb;
-	unsigned int i;
-	u32 mvs;
-	u8 maxvid;
-	u32 cpst = 0;
-	u32 thiscpuid;
-
-	for (i = 0xc0000; i < 0xffff0; i += 0x10) {
-		/* Scan BIOS looking for the signature. */
-		/* It can not be at ffff0 - it is too big. */
-
-		psb = phys_to_virt(i);
-		if (memcmp(psb, PSB_ID_STRING, PSB_ID_STRING_LEN) != 0)
-			continue;
-
-		dprintk("found PSB header at 0x%p\n", psb);
-
-		dprintk("table vers: 0x%x\n", psb->tableversion);
-		if (psb->tableversion != PSB_VERSION_1_4) {
-			printk(KERN_ERR FW_BUG PFX "PSB table is not v1.4\n");
-			return -ENODEV;
-		}
-
-		dprintk("flags: 0x%x\n", psb->flags1);
-		if (psb->flags1) {
-			printk(KERN_ERR FW_BUG PFX "unknown flags\n");
-			return -ENODEV;
-		}
-
-		data->vstable = psb->vstable;
-		dprintk("voltage stabilization time: %d(*20us)\n",
-				data->vstable);
-
-		dprintk("flags2: 0x%x\n", psb->flags2);
-		data->rvo = psb->flags2 & 3;
-		data->irt = ((psb->flags2) >> 2) & 3;
-		mvs = ((psb->flags2) >> 4) & 3;
-		data->vidmvs = 1 << mvs;
-		data->batps = ((psb->flags2) >> 6) & 3;
-
-		dprintk("ramp voltage offset: %d\n", data->rvo);
-		dprintk("isochronous relief time: %d\n", data->irt);
-		dprintk("maximum voltage step: %d - 0x%x\n", mvs, data->vidmvs);
-
-		dprintk("numpst: 0x%x\n", psb->num_tables);
-		cpst = psb->num_tables;
-		if ((psb->cpuid == 0x00000fc0) ||
-		    (psb->cpuid == 0x00000fe0)) {
-			thiscpuid = cpuid_eax(CPUID_PROCESSOR_SIGNATURE);
-			if ((thiscpuid == 0x00000fc0) ||
-			    (thiscpuid == 0x00000fe0))
-				cpst = 1;
-		}
-		if (cpst != 1) {
-			printk(KERN_ERR FW_BUG PFX "numpst must be 1\n");
-			return -ENODEV;
-		}
-
-		data->plllock = psb->plllocktime;
-		dprintk("plllocktime: 0x%x (units 1us)\n", psb->plllocktime);
-		dprintk("maxfid: 0x%x\n", psb->maxfid);
-		dprintk("maxvid: 0x%x\n", psb->maxvid);
-		maxvid = psb->maxvid;
-
-		data->numps = psb->numps;
-		dprintk("numpstates: 0x%x\n", data->numps);
-		return fill_powernow_table(data,
-				(struct pst_s *)(psb+1), maxvid);
-	}
-	/*
-	 * If you see this message, complain to BIOS manufacturer. If
-	 * he tells you "we do not support Linux" or some similar
-	 * nonsense, remember that Windows 2000 uses the same legacy
-	 * mechanism that the old Linux PSB driver uses. Tell them it
-	 * is broken with Windows 2000.
-	 *
-	 * The reference to the AMD documentation is chapter 9 in the
-	 * BIOS and Kernel Developer's Guide, which is available on
-	 * www.amd.com
-	 */
-	printk(KERN_ERR FW_BUG PFX "No PSB or ACPI _PSS objects\n");
-	printk(KERN_ERR PFX "Make sure that your BIOS is up to date"
-		" and Cool'N'Quiet support is enabled in BIOS setup\n");
-	return -ENODEV;
-}
-
-static void powernow_k8_acpi_pst_values(struct powernow_k8_data *data,
-		unsigned int index)
-{
-	u64 control;
-
-	if (!data->acpi_data.state_count || (cpu_family == CPU_HW_PSTATE))
-		return;
-
-	control = data->acpi_data.states[index].control;
-	data->irt = (control >> IRT_SHIFT) & IRT_MASK;
-	data->rvo = (control >> RVO_SHIFT) & RVO_MASK;
-	data->exttype = (control >> EXT_TYPE_SHIFT) & EXT_TYPE_MASK;
-	data->plllock = (control >> PLL_L_SHIFT) & PLL_L_MASK;
-	data->vidmvs = 1 << ((control >> MVS_SHIFT) & MVS_MASK);
-	data->vstable = (control >> VST_SHIFT) & VST_MASK;
-}
-
-static int powernow_k8_cpu_init_acpi(struct powernow_k8_data *data)
-{
-	struct cpufreq_frequency_table *powernow_table;
-	int ret_val = -ENODEV;
-	u64 control, status;
-
-	if (acpi_processor_register_performance(&data->acpi_data, data->cpu)) {
-		dprintk("register performance failed: bad ACPI data\n");
-		return -EIO;
-	}
-
-	/* verify the data contained in the ACPI structures */
-	if (data->acpi_data.state_count <= 1) {
-		dprintk("No ACPI P-States\n");
-		goto err_out;
-	}
-
-	control = data->acpi_data.control_register.space_id;
-	status = data->acpi_data.status_register.space_id;
-
-	if ((control != ACPI_ADR_SPACE_FIXED_HARDWARE) ||
-	    (status != ACPI_ADR_SPACE_FIXED_HARDWARE)) {
-		dprintk("Invalid control/status registers (%x - %x)\n",
-			control, status);
-		goto err_out;
-	}
-
-	/* fill in data->powernow_table */
-	powernow_table = kmalloc((sizeof(struct cpufreq_frequency_table)
-		* (data->acpi_data.state_count + 1)), GFP_KERNEL);
-	if (!powernow_table) {
-		dprintk("powernow_table memory alloc failure\n");
-		goto err_out;
-	}
-
-	/* fill in data */
-	data->numps = data->acpi_data.state_count;
-	powernow_k8_acpi_pst_values(data, 0);
-
-	if (cpu_family == CPU_HW_PSTATE)
-		ret_val = fill_powernow_table_pstate(data, powernow_table);
-	else
-		ret_val = fill_powernow_table_fidvid(data, powernow_table);
-	if (ret_val)
-		goto err_out_mem;
-
-	powernow_table[data->acpi_data.state_count].frequency =
-		CPUFREQ_TABLE_END;
-	powernow_table[data->acpi_data.state_count].index = 0;
-	data->powernow_table = powernow_table;
-
-	if (cpumask_first(cpu_core_mask(data->cpu)) == data->cpu)
-		print_basics(data);
-
-	/* notify BIOS that we exist */
-	acpi_processor_notify_smm(THIS_MODULE);
-
-	if (!zalloc_cpumask_var(&data->acpi_data.shared_cpu_map, GFP_KERNEL)) {
-		printk(KERN_ERR PFX
-				"unable to alloc powernow_k8_data cpumask\n");
-		ret_val = -ENOMEM;
-		goto err_out_mem;
-	}
-
-	return 0;
-
-err_out_mem:
-	kfree(powernow_table);
-
-err_out:
-	acpi_processor_unregister_performance(&data->acpi_data, data->cpu);
-
-	/* data->acpi_data.state_count informs us at ->exit()
-	 * whether ACPI was used */
-	data->acpi_data.state_count = 0;
-
-	return ret_val;
-}
-
-static int fill_powernow_table_pstate(struct powernow_k8_data *data,
-		struct cpufreq_frequency_table *powernow_table)
-{
-	int i;
-	u32 hi = 0, lo = 0;
-	rdmsr(MSR_PSTATE_CUR_LIMIT, lo, hi);
-	data->max_hw_pstate = (lo & HW_PSTATE_MAX_MASK) >> HW_PSTATE_MAX_SHIFT;
-
-	for (i = 0; i < data->acpi_data.state_count; i++) {
-		u32 index;
-
-		index = data->acpi_data.states[i].control & HW_PSTATE_MASK;
-		if (index > data->max_hw_pstate) {
-			printk(KERN_ERR PFX "invalid pstate %d - "
-					"bad value %d.\n", i, index);
-			printk(KERN_ERR PFX "Please report to BIOS "
-					"manufacturer\n");
-			invalidate_entry(powernow_table, i);
-			continue;
-		}
-		rdmsr(MSR_PSTATE_DEF_BASE + index, lo, hi);
-		if (!(hi & HW_PSTATE_VALID_MASK)) {
-			dprintk("invalid pstate %d, ignoring\n", index);
-			invalidate_entry(powernow_table, i);
-			continue;
-		}
-
-		powernow_table[i].index = index;
-
-		/* Frequency may be rounded for these */
-		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
-			powernow_table[i].frequency =
-				data->acpi_data.states[i].core_frequency * 1000;
-	}
-	return 0;
-}
-
-static int fill_powernow_table_fidvid(struct powernow_k8_data *data,
-		struct cpufreq_frequency_table *powernow_table)
-{
-	int i;
-
-	for (i = 0; i < data->acpi_data.state_count; i++) {
-		u32 fid;
-		u32 vid;
-		u32 freq, index;
-		u64 status, control;
-
-		if (data->exttype) {
-			status =  data->acpi_data.states[i].status;
-			fid = status & EXT_FID_MASK;
-			vid = (status >> VID_SHIFT) & EXT_VID_MASK;
-		} else {
-			control =  data->acpi_data.states[i].control;
-			fid = control & FID_MASK;
-			vid = (control >> VID_SHIFT) & VID_MASK;
-		}
-
-		dprintk("   %d : fid 0x%x, vid 0x%x\n", i, fid, vid);
-
-		index = fid | (vid<<8);
-		powernow_table[i].index = index;
-
-		freq = find_khz_freq_from_fid(fid);
-		powernow_table[i].frequency = freq;
-
-		/* verify frequency is OK */
-		if ((freq > (MAX_FREQ * 1000)) || (freq < (MIN_FREQ * 1000))) {
-			dprintk("invalid freq %u kHz, ignoring\n", freq);
-			invalidate_entry(powernow_table, i);
-			continue;
-		}
-
-		/* verify voltage is OK -
-		 * BIOSs are using "off" to indicate invalid */
-		if (vid == VID_OFF) {
-			dprintk("invalid vid %u, ignoring\n", vid);
-			invalidate_entry(powernow_table, i);
-			continue;
-		}
-
-		if (freq != (data->acpi_data.states[i].core_frequency * 1000)) {
-			printk(KERN_INFO PFX "invalid freq entries "
-				"%u kHz vs. %u kHz\n", freq,
-				(unsigned int)
-				(data->acpi_data.states[i].core_frequency
-				 * 1000));
-			invalidate_entry(powernow_table, i);
-			continue;
-		}
-	}
-	return 0;
-}
-
-static void powernow_k8_cpu_exit_acpi(struct powernow_k8_data *data)
-{
-	if (data->acpi_data.state_count)
-		acpi_processor_unregister_performance(&data->acpi_data,
-				data->cpu);
-	free_cpumask_var(data->acpi_data.shared_cpu_map);
-}
-
-static int get_transition_latency(struct powernow_k8_data *data)
-{
-	int max_latency = 0;
-	int i;
-	for (i = 0; i < data->acpi_data.state_count; i++) {
-		int cur_latency = data->acpi_data.states[i].transition_latency
-			+ data->acpi_data.states[i].bus_master_latency;
-		if (cur_latency > max_latency)
-			max_latency = cur_latency;
-	}
-	if (max_latency == 0) {
-		/*
-		 * Fam 11h and later may return 0 as transition latency. This
-		 * is intended and means "very fast". While cpufreq core and
-		 * governors currently can handle that gracefully, better set it
-		 * to 1 to avoid problems in the future.
-		 */
-		if (boot_cpu_data.x86 < 0x11)
-			printk(KERN_ERR FW_WARN PFX "Invalid zero transition "
-				"latency\n");
-		max_latency = 1;
-	}
-	/* value in usecs, needs to be in nanoseconds */
-	return 1000 * max_latency;
-}
-
-/* Take a frequency, and issue the fid/vid transition command */
-static int transition_frequency_fidvid(struct powernow_k8_data *data,
-		unsigned int index)
-{
-	u32 fid = 0;
-	u32 vid = 0;
-	int res, i;
-	struct cpufreq_freqs freqs;
-
-	dprintk("cpu %d transition to index %u\n", smp_processor_id(), index);
-
-	/* fid/vid correctness check for k8 */
-	/* fid are the lower 8 bits of the index we stored into
-	 * the cpufreq frequency table in find_psb_table, vid
-	 * are the upper 8 bits.
-	 */
-	fid = data->powernow_table[index].index & 0xFF;
-	vid = (data->powernow_table[index].index & 0xFF00) >> 8;
-
-	dprintk("table matched fid 0x%x, giving vid 0x%x\n", fid, vid);
-
-	if (query_current_values_with_pending_wait(data))
-		return 1;
-
-	if ((data->currvid == vid) && (data->currfid == fid)) {
-		dprintk("target matches current values (fid 0x%x, vid 0x%x)\n",
-			fid, vid);
-		return 0;
-	}
-
-	dprintk("cpu %d, changing to fid 0x%x, vid 0x%x\n",
-		smp_processor_id(), fid, vid);
-	freqs.old = find_khz_freq_from_fid(data->currfid);
-	freqs.new = find_khz_freq_from_fid(fid);
-
-	for_each_cpu(i, data->available_cores) {
-		freqs.cpu = i;
-		cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
-	}
-
-	res = transition_fid_vid(data, fid, vid);
-	freqs.new = find_khz_freq_from_fid(data->currfid);
-
-	for_each_cpu(i, data->available_cores) {
-		freqs.cpu = i;
-		cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
-	}
-	return res;
-}
-
-/* Take a frequency, and issue the hardware pstate transition command */
-static int transition_frequency_pstate(struct powernow_k8_data *data,
-		unsigned int index)
-{
-	u32 pstate = 0;
-	int res, i;
-	struct cpufreq_freqs freqs;
-
-	dprintk("cpu %d transition to index %u\n", smp_processor_id(), index);
-
-	/* get MSR index for hardware pstate transition */
-	pstate = index & HW_PSTATE_MASK;
-	if (pstate > data->max_hw_pstate)
-		return 0;
-	freqs.old = find_khz_freq_from_pstate(data->powernow_table,
-			data->currpstate);
-	freqs.new = find_khz_freq_from_pstate(data->powernow_table, pstate);
-
-	for_each_cpu(i, data->available_cores) {
-		freqs.cpu = i;
-		cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
-	}
-
-	res = transition_pstate(data, pstate);
-	freqs.new = find_khz_freq_from_pstate(data->powernow_table, pstate);
-
-	for_each_cpu(i, data->available_cores) {
-		freqs.cpu = i;
-		cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
-	}
-	return res;
-}
-
-/* Driver entry point to switch to the target frequency */
-static int powernowk8_target(struct cpufreq_policy *pol,
-		unsigned targfreq, unsigned relation)
-{
-	cpumask_var_t oldmask;
-	struct powernow_k8_data *data = per_cpu(powernow_data, pol->cpu);
-	u32 checkfid;
-	u32 checkvid;
-	unsigned int newstate;
-	int ret = -EIO;
-
-	if (!data)
-		return -EINVAL;
-
-	checkfid = data->currfid;
-	checkvid = data->currvid;
-
-	/* only run on specific CPU from here on. */
-	/* This is poor form: use a workqueue or smp_call_function_single */
-	if (!alloc_cpumask_var(&oldmask, GFP_KERNEL))
-		return -ENOMEM;
-
-	cpumask_copy(oldmask, tsk_cpus_allowed(current));
-	set_cpus_allowed_ptr(current, cpumask_of(pol->cpu));
-
-	if (smp_processor_id() != pol->cpu) {
-		printk(KERN_ERR PFX "limiting to cpu %u failed\n", pol->cpu);
-		goto err_out;
-	}
-
-	if (pending_bit_stuck()) {
-		printk(KERN_ERR PFX "failing targ, change pending bit set\n");
-		goto err_out;
-	}
-
-	dprintk("targ: cpu %d, %d kHz, min %d, max %d, relation %d\n",
-		pol->cpu, targfreq, pol->min, pol->max, relation);
-
-	if (query_current_values_with_pending_wait(data))
-		goto err_out;
-
-	if (cpu_family != CPU_HW_PSTATE) {
-		dprintk("targ: curr fid 0x%x, vid 0x%x\n",
-		data->currfid, data->currvid);
-
-		if ((checkvid != data->currvid) ||
-		    (checkfid != data->currfid)) {
-			printk(KERN_INFO PFX
-				"error - out of sync, fix 0x%x 0x%x, "
-				"vid 0x%x 0x%x\n",
-				checkfid, data->currfid,
-				checkvid, data->currvid);
-		}
-	}
-
-	if (cpufreq_frequency_table_target(pol, data->powernow_table,
-				targfreq, relation, &newstate))
-		goto err_out;
-
-	mutex_lock(&fidvid_mutex);
-
-	powernow_k8_acpi_pst_values(data, newstate);
-
-	if (cpu_family == CPU_HW_PSTATE)
-		ret = transition_frequency_pstate(data, newstate);
-	else
-		ret = transition_frequency_fidvid(data, newstate);
-	if (ret) {
-		printk(KERN_ERR PFX "transition frequency failed\n");
-		ret = 1;
-		mutex_unlock(&fidvid_mutex);
-		goto err_out;
-	}
-	mutex_unlock(&fidvid_mutex);
-
-	if (cpu_family == CPU_HW_PSTATE)
-		pol->cur = find_khz_freq_from_pstate(data->powernow_table,
-				newstate);
-	else
-		pol->cur = find_khz_freq_from_fid(data->currfid);
-	ret = 0;
-
-err_out:
-	set_cpus_allowed_ptr(current, oldmask);
-	free_cpumask_var(oldmask);
-	return ret;
-}
-
-/* Driver entry point to verify the policy and range of frequencies */
-static int powernowk8_verify(struct cpufreq_policy *pol)
-{
-	struct powernow_k8_data *data = per_cpu(powernow_data, pol->cpu);
-
-	if (!data)
-		return -EINVAL;
-
-	return cpufreq_frequency_table_verify(pol, data->powernow_table);
-}
-
-struct init_on_cpu {
-	struct powernow_k8_data *data;
-	int rc;
-};
-
-static void __cpuinit powernowk8_cpu_init_on_cpu(void *_init_on_cpu)
-{
-	struct init_on_cpu *init_on_cpu = _init_on_cpu;
-
-	if (pending_bit_stuck()) {
-		printk(KERN_ERR PFX "failing init, change pending bit set\n");
-		init_on_cpu->rc = -ENODEV;
-		return;
-	}
-
-	if (query_current_values_with_pending_wait(init_on_cpu->data)) {
-		init_on_cpu->rc = -ENODEV;
-		return;
-	}
-
-	if (cpu_family == CPU_OPTERON)
-		fidvid_msr_init();
-
-	init_on_cpu->rc = 0;
-}
-
-/* per CPU init entry point to the driver */
-static int __cpuinit powernowk8_cpu_init(struct cpufreq_policy *pol)
-{
-	static const char ACPI_PSS_BIOS_BUG_MSG[] =
-		KERN_ERR FW_BUG PFX "No compatible ACPI _PSS objects found.\n"
-		FW_BUG PFX "Try again with latest BIOS.\n";
-	struct powernow_k8_data *data;
-	struct init_on_cpu init_on_cpu;
-	int rc;
-	struct cpuinfo_x86 *c = &cpu_data(pol->cpu);
-
-	if (!cpu_online(pol->cpu))
-		return -ENODEV;
-
-	smp_call_function_single(pol->cpu, check_supported_cpu, &rc, 1);
-	if (rc)
-		return -ENODEV;
-
-	data = kzalloc(sizeof(struct powernow_k8_data), GFP_KERNEL);
-	if (!data) {
-		printk(KERN_ERR PFX "unable to alloc powernow_k8_data");
-		return -ENOMEM;
-	}
-
-	data->cpu = pol->cpu;
-	data->currpstate = HW_PSTATE_INVALID;
-
-	if (powernow_k8_cpu_init_acpi(data)) {
-		/*
-		 * Use the PSB BIOS structure. This is only available on
-		 * an UP version, and is deprecated by AMD.
-		 */
-		if (num_online_cpus() != 1) {
-			printk_once(ACPI_PSS_BIOS_BUG_MSG);
-			goto err_out;
-		}
-		if (pol->cpu != 0) {
-			printk(KERN_ERR FW_BUG PFX "No ACPI _PSS objects for "
-			       "CPU other than CPU0. Complain to your BIOS "
-			       "vendor.\n");
-			goto err_out;
-		}
-		rc = find_psb_table(data);
-		if (rc)
-			goto err_out;
-
-		/* Take a crude guess here.
-		 * That guess was in microseconds, so multiply with 1000 */
-		pol->cpuinfo.transition_latency = (
-			 ((data->rvo + 8) * data->vstable * VST_UNITS_20US) +
-			 ((1 << data->irt) * 30)) * 1000;
-	} else /* ACPI _PSS objects available */
-		pol->cpuinfo.transition_latency = get_transition_latency(data);
-
-	/* only run on specific CPU from here on */
-	init_on_cpu.data = data;
-	smp_call_function_single(data->cpu, powernowk8_cpu_init_on_cpu,
-				 &init_on_cpu, 1);
-	rc = init_on_cpu.rc;
-	if (rc != 0)
-		goto err_out_exit_acpi;
-
-	if (cpu_family == CPU_HW_PSTATE)
-		cpumask_copy(pol->cpus, cpumask_of(pol->cpu));
-	else
-		cpumask_copy(pol->cpus, cpu_core_mask(pol->cpu));
-	data->available_cores = pol->cpus;
-
-	if (cpu_family == CPU_HW_PSTATE)
-		pol->cur = find_khz_freq_from_pstate(data->powernow_table,
-				data->currpstate);
-	else
-		pol->cur = find_khz_freq_from_fid(data->currfid);
-	dprintk("policy current frequency %d kHz\n", pol->cur);
-
-	/* min/max the cpu is capable of */
-	if (cpufreq_frequency_table_cpuinfo(pol, data->powernow_table)) {
-		printk(KERN_ERR FW_BUG PFX "invalid powernow_table\n");
-		powernow_k8_cpu_exit_acpi(data);
-		kfree(data->powernow_table);
-		kfree(data);
-		return -EINVAL;
-	}
-
-	/* Check for APERF/MPERF support in hardware */
-	if (cpu_has(c, X86_FEATURE_APERFMPERF))
-		cpufreq_amd64_driver.getavg = cpufreq_get_measured_perf;
-
-	cpufreq_frequency_table_get_attr(data->powernow_table, pol->cpu);
-
-	if (cpu_family == CPU_HW_PSTATE)
-		dprintk("cpu_init done, current pstate 0x%x\n",
-				data->currpstate);
-	else
-		dprintk("cpu_init done, current fid 0x%x, vid 0x%x\n",
-			data->currfid, data->currvid);
-
-	per_cpu(powernow_data, pol->cpu) = data;
-
-	return 0;
-
-err_out_exit_acpi:
-	powernow_k8_cpu_exit_acpi(data);
-
-err_out:
-	kfree(data);
-	return -ENODEV;
-}
-
-static int __devexit powernowk8_cpu_exit(struct cpufreq_policy *pol)
-{
-	struct powernow_k8_data *data = per_cpu(powernow_data, pol->cpu);
-
-	if (!data)
-		return -EINVAL;
-
-	powernow_k8_cpu_exit_acpi(data);
-
-	cpufreq_frequency_table_put_attr(pol->cpu);
-
-	kfree(data->powernow_table);
-	kfree(data);
-	per_cpu(powernow_data, pol->cpu) = NULL;
-
-	return 0;
-}
-
-static void query_values_on_cpu(void *_err)
-{
-	int *err = _err;
-	struct powernow_k8_data *data = __this_cpu_read(powernow_data);
-
-	*err = query_current_values_with_pending_wait(data);
-}
-
-static unsigned int powernowk8_get(unsigned int cpu)
-{
-	struct powernow_k8_data *data = per_cpu(powernow_data, cpu);
-	unsigned int khz = 0;
-	int err;
-
-	if (!data)
-		return 0;
-
-	smp_call_function_single(cpu, query_values_on_cpu, &err, true);
-	if (err)
-		goto out;
-
-	if (cpu_family == CPU_HW_PSTATE)
-		khz = find_khz_freq_from_pstate(data->powernow_table,
-						data->currpstate);
-	else
-		khz = find_khz_freq_from_fid(data->currfid);
-
-
-out:
-	return khz;
-}
-
-static void _cpb_toggle_msrs(bool t)
-{
-	int cpu;
-
-	get_online_cpus();
-
-	rdmsr_on_cpus(cpu_online_mask, MSR_K7_HWCR, msrs);
-
-	for_each_cpu(cpu, cpu_online_mask) {
-		struct msr *reg = per_cpu_ptr(msrs, cpu);
-		if (t)
-			reg->l &= ~BIT(25);
-		else
-			reg->l |= BIT(25);
-	}
-	wrmsr_on_cpus(cpu_online_mask, MSR_K7_HWCR, msrs);
-
-	put_online_cpus();
-}
-
-/*
- * Switch on/off core performance boosting.
- *
- * 0=disable
- * 1=enable.
- */
-static void cpb_toggle(bool t)
-{
-	if (!cpb_capable)
-		return;
-
-	if (t && !cpb_enabled) {
-		cpb_enabled = true;
-		_cpb_toggle_msrs(t);
-		printk(KERN_INFO PFX "Core Boosting enabled.\n");
-	} else if (!t && cpb_enabled) {
-		cpb_enabled = false;
-		_cpb_toggle_msrs(t);
-		printk(KERN_INFO PFX "Core Boosting disabled.\n");
-	}
-}
-
-static ssize_t store_cpb(struct cpufreq_policy *policy, const char *buf,
-				 size_t count)
-{
-	int ret = -EINVAL;
-	unsigned long val = 0;
-
-	ret = strict_strtoul(buf, 10, &val);
-	if (!ret && (val == 0 || val == 1) && cpb_capable)
-		cpb_toggle(val);
-	else
-		return -EINVAL;
-
-	return count;
-}
-
-static ssize_t show_cpb(struct cpufreq_policy *policy, char *buf)
-{
-	return sprintf(buf, "%u\n", cpb_enabled);
-}
-
-#define define_one_rw(_name) \
-static struct freq_attr _name = \
-__ATTR(_name, 0644, show_##_name, store_##_name)
-
-define_one_rw(cpb);
-
-static struct freq_attr *powernow_k8_attr[] = {
-	&cpufreq_freq_attr_scaling_available_freqs,
-	&cpb,
-	NULL,
-};
-
-static struct cpufreq_driver cpufreq_amd64_driver = {
-	.verify		= powernowk8_verify,
-	.target		= powernowk8_target,
-	.bios_limit	= acpi_processor_get_bios_limit,
-	.init		= powernowk8_cpu_init,
-	.exit		= __devexit_p(powernowk8_cpu_exit),
-	.get		= powernowk8_get,
-	.name		= "powernow-k8",
-	.owner		= THIS_MODULE,
-	.attr		= powernow_k8_attr,
-};
-
-/*
- * Clear the boost-disable flag on the CPU_DOWN path so that this cpu
- * cannot block the remaining ones from boosting. On the CPU_UP path we
- * simply keep the boost-disable flag in sync with the current global
- * state.
- */
-static int cpb_notify(struct notifier_block *nb, unsigned long action,
-		      void *hcpu)
-{
-	unsigned cpu = (long)hcpu;
-	u32 lo, hi;
-
-	switch (action) {
-	case CPU_UP_PREPARE:
-	case CPU_UP_PREPARE_FROZEN:
-
-		if (!cpb_enabled) {
-			rdmsr_on_cpu(cpu, MSR_K7_HWCR, &lo, &hi);
-			lo |= BIT(25);
-			wrmsr_on_cpu(cpu, MSR_K7_HWCR, lo, hi);
-		}
-		break;
-
-	case CPU_DOWN_PREPARE:
-	case CPU_DOWN_PREPARE_FROZEN:
-		rdmsr_on_cpu(cpu, MSR_K7_HWCR, &lo, &hi);
-		lo &= ~BIT(25);
-		wrmsr_on_cpu(cpu, MSR_K7_HWCR, lo, hi);
-		break;
-
-	default:
-		break;
-	}
-
-	return NOTIFY_OK;
-}
-
-static struct notifier_block cpb_nb = {
-	.notifier_call		= cpb_notify,
-};
-
-/* driver entry point for init */
-static int __cpuinit powernowk8_init(void)
-{
-	unsigned int i, supported_cpus = 0, cpu;
-	int rv;
-
-	for_each_online_cpu(i) {
-		int rc;
-		smp_call_function_single(i, check_supported_cpu, &rc, 1);
-		if (rc == 0)
-			supported_cpus++;
-	}
-
-	if (supported_cpus != num_online_cpus())
-		return -ENODEV;
-
-	printk(KERN_INFO PFX "Found %d %s (%d cpu cores) (" VERSION ")\n",
-		num_online_nodes(), boot_cpu_data.x86_model_id, supported_cpus);
-
-	if (boot_cpu_has(X86_FEATURE_CPB)) {
-
-		cpb_capable = true;
-
-		msrs = msrs_alloc();
-		if (!msrs) {
-			printk(KERN_ERR "%s: Error allocating msrs!\n", __func__);
-			return -ENOMEM;
-		}
-
-		register_cpu_notifier(&cpb_nb);
-
-		rdmsr_on_cpus(cpu_online_mask, MSR_K7_HWCR, msrs);
-
-		for_each_cpu(cpu, cpu_online_mask) {
-			struct msr *reg = per_cpu_ptr(msrs, cpu);
-			cpb_enabled |= !(!!(reg->l & BIT(25)));
-		}
-
-		printk(KERN_INFO PFX "Core Performance Boosting: %s.\n",
-			(cpb_enabled ? "on" : "off"));
-	}
-
-	rv = cpufreq_register_driver(&cpufreq_amd64_driver);
-	if (rv < 0 && boot_cpu_has(X86_FEATURE_CPB)) {
-		unregister_cpu_notifier(&cpb_nb);
-		msrs_free(msrs);
-		msrs = NULL;
-	}
-	return rv;
-}
-
-/* driver entry point for term */
-static void __exit powernowk8_exit(void)
-{
-	dprintk("exit\n");
-
-	if (boot_cpu_has(X86_FEATURE_CPB)) {
-		msrs_free(msrs);
-		msrs = NULL;
-
-		unregister_cpu_notifier(&cpb_nb);
-	}
-
-	cpufreq_unregister_driver(&cpufreq_amd64_driver);
-}
-
-MODULE_AUTHOR("Paul Devriendt <paul.devriendt@amd.com> and "
-		"Mark Langsdorf <mark.langsdorf@amd.com>");
-MODULE_DESCRIPTION("AMD Athlon 64 and Opteron processor frequency driver.");
-MODULE_LICENSE("GPL");
-
-late_initcall(powernowk8_init);
-module_exit(powernowk8_exit);
diff -druN linux-2.6.39-libre/arch/x86/kernel/cpu/cpufreq/powernow-k8.h linux-3.0-rc7-libre/arch/x86/kernel/cpu/cpufreq/powernow-k8.h
--- linux-2.6.39-libre/arch/x86/kernel/cpu/cpufreq/powernow-k8.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/kernel/cpu/cpufreq/powernow-k8.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,224 +0,0 @@
-/*
- *  (c) 2003-2006 Advanced Micro Devices, Inc.
- *  Your use of this code is subject to the terms and conditions of the
- *  GNU general public license version 2. See "COPYING" or
- *  http://www.gnu.org/licenses/gpl.html
- */
-
-enum pstate {
-	HW_PSTATE_INVALID = 0xff,
-	HW_PSTATE_0 = 0,
-	HW_PSTATE_1 = 1,
-	HW_PSTATE_2 = 2,
-	HW_PSTATE_3 = 3,
-	HW_PSTATE_4 = 4,
-	HW_PSTATE_5 = 5,
-	HW_PSTATE_6 = 6,
-	HW_PSTATE_7 = 7,
-};
-
-struct powernow_k8_data {
-	unsigned int cpu;
-
-	u32 numps;  /* number of p-states */
-	u32 batps;  /* number of p-states supported on battery */
-	u32 max_hw_pstate; /* maximum legal hardware pstate */
-
-	/* these values are constant when the PSB is used to determine
-	 * vid/fid pairings, but are modified during the ->target() call
-	 * when ACPI is used */
-	u32 rvo;     /* ramp voltage offset */
-	u32 irt;     /* isochronous relief time */
-	u32 vidmvs;  /* usable value calculated from mvs */
-	u32 vstable; /* voltage stabilization time, units 20 us */
-	u32 plllock; /* pll lock time, units 1 us */
-        u32 exttype; /* extended interface = 1 */
-
-	/* keep track of the current fid / vid or pstate */
-	u32 currvid;
-	u32 currfid;
-	enum pstate currpstate;
-
-	/* the powernow_table includes all frequency and vid/fid pairings:
-	 * fid are the lower 8 bits of the index, vid are the upper 8 bits.
-	 * frequency is in kHz */
-	struct cpufreq_frequency_table  *powernow_table;
-
-	/* the acpi table needs to be kept. it's only available if ACPI was
-	 * used to determine valid frequency/vid/fid states */
-	struct acpi_processor_performance acpi_data;
-
-	/* we need to keep track of associated cores, but let cpufreq
-	 * handle hotplug events - so just point at cpufreq pol->cpus
-	 * structure */
-	struct cpumask *available_cores;
-};
-
-/* processor's cpuid instruction support */
-#define CPUID_PROCESSOR_SIGNATURE	1	/* function 1 */
-#define CPUID_XFAM			0x0ff00000	/* extended family */
-#define CPUID_XFAM_K8			0
-#define CPUID_XMOD			0x000f0000	/* extended model */
-#define CPUID_XMOD_REV_MASK		0x000c0000
-#define CPUID_XFAM_10H			0x00100000	/* family 0x10 */
-#define CPUID_USE_XFAM_XMOD		0x00000f00
-#define CPUID_GET_MAX_CAPABILITIES	0x80000000
-#define CPUID_FREQ_VOLT_CAPABILITIES	0x80000007
-#define P_STATE_TRANSITION_CAPABLE	6
-
-/* Model Specific Registers for p-state transitions. MSRs are 64-bit. For     */
-/* writes (wrmsr - opcode 0f 30), the register number is placed in ecx, and   */
-/* the value to write is placed in edx:eax. For reads (rdmsr - opcode 0f 32), */
-/* the register number is placed in ecx, and the data is returned in edx:eax. */
-
-#define MSR_FIDVID_CTL      0xc0010041
-#define MSR_FIDVID_STATUS   0xc0010042
-
-/* Field definitions within the FID VID Low Control MSR : */
-#define MSR_C_LO_INIT_FID_VID     0x00010000
-#define MSR_C_LO_NEW_VID          0x00003f00
-#define MSR_C_LO_NEW_FID          0x0000003f
-#define MSR_C_LO_VID_SHIFT        8
-
-/* Field definitions within the FID VID High Control MSR : */
-#define MSR_C_HI_STP_GNT_TO	  0x000fffff
-
-/* Field definitions within the FID VID Low Status MSR : */
-#define MSR_S_LO_CHANGE_PENDING   0x80000000   /* cleared when completed */
-#define MSR_S_LO_MAX_RAMP_VID     0x3f000000
-#define MSR_S_LO_MAX_FID          0x003f0000
-#define MSR_S_LO_START_FID        0x00003f00
-#define MSR_S_LO_CURRENT_FID      0x0000003f
-
-/* Field definitions within the FID VID High Status MSR : */
-#define MSR_S_HI_MIN_WORKING_VID  0x3f000000
-#define MSR_S_HI_MAX_WORKING_VID  0x003f0000
-#define MSR_S_HI_START_VID        0x00003f00
-#define MSR_S_HI_CURRENT_VID      0x0000003f
-#define MSR_C_HI_STP_GNT_BENIGN	  0x00000001
-
-
-/* Hardware Pstate _PSS and MSR definitions */
-#define USE_HW_PSTATE		0x00000080
-#define HW_PSTATE_MASK 		0x00000007
-#define HW_PSTATE_VALID_MASK 	0x80000000
-#define HW_PSTATE_MAX_MASK	0x000000f0
-#define HW_PSTATE_MAX_SHIFT	4
-#define MSR_PSTATE_DEF_BASE 	0xc0010064 /* base of Pstate MSRs */
-#define MSR_PSTATE_STATUS 	0xc0010063 /* Pstate Status MSR */
-#define MSR_PSTATE_CTRL 	0xc0010062 /* Pstate control MSR */
-#define MSR_PSTATE_CUR_LIMIT	0xc0010061 /* pstate current limit MSR */
-
-/* define the two driver architectures */
-#define CPU_OPTERON 0
-#define CPU_HW_PSTATE 1
-
-
-/*
- * There are restrictions frequencies have to follow:
- * - only 1 entry in the low fid table ( <=1.4GHz )
- * - lowest entry in the high fid table must be >= 2 * the entry in the
- *   low fid table
- * - lowest entry in the high fid table must be a <= 200MHz + 2 * the entry
- *   in the low fid table
- * - the parts can only step at <= 200 MHz intervals, odd fid values are
- *   supported in revision G and later revisions.
- * - lowest frequency must be >= interprocessor hypertransport link speed
- *   (only applies to MP systems obviously)
- */
-
-/* fids (frequency identifiers) are arranged in 2 tables - lo and hi */
-#define LO_FID_TABLE_TOP     7	/* fid values marking the boundary    */
-#define HI_FID_TABLE_BOTTOM  8	/* between the low and high tables    */
-
-#define LO_VCOFREQ_TABLE_TOP    1400	/* corresponding vco frequency values */
-#define HI_VCOFREQ_TABLE_BOTTOM 1600
-
-#define MIN_FREQ_RESOLUTION  200 /* fids jump by 2 matching freq jumps by 200 */
-
-#define MAX_FID 0x2a	/* Spec only gives FID values as far as 5 GHz */
-#define LEAST_VID 0x3e	/* Lowest (numerically highest) useful vid value */
-
-#define MIN_FREQ 800	/* Min and max freqs, per spec */
-#define MAX_FREQ 5000
-
-#define INVALID_FID_MASK 0xffffffc0  /* not a valid fid if these bits are set */
-#define INVALID_VID_MASK 0xffffffc0  /* not a valid vid if these bits are set */
-
-#define VID_OFF 0x3f
-
-#define STOP_GRANT_5NS 1 /* min poss memory access latency for voltage change */
-
-#define PLL_LOCK_CONVERSION (1000/5) /* ms to ns, then divide by clock period */
-
-#define MAXIMUM_VID_STEPS 1  /* Current cpus only allow a single step of 25mV */
-#define VST_UNITS_20US 20   /* Voltage Stabilization Time is in units of 20us */
-
-/*
- * Most values of interest are encoded in a single field of the _PSS
- * entries: the "control" value.
- */
-
-#define IRT_SHIFT      30
-#define RVO_SHIFT      28
-#define EXT_TYPE_SHIFT 27
-#define PLL_L_SHIFT    20
-#define MVS_SHIFT      18
-#define VST_SHIFT      11
-#define VID_SHIFT       6
-#define IRT_MASK        3
-#define RVO_MASK        3
-#define EXT_TYPE_MASK   1
-#define PLL_L_MASK   0x7f
-#define MVS_MASK        3
-#define VST_MASK     0x7f
-#define VID_MASK     0x1f
-#define FID_MASK     0x1f
-#define EXT_VID_MASK 0x3f
-#define EXT_FID_MASK 0x3f
-
-
-/*
- * Version 1.4 of the PSB table. This table is constructed by BIOS and is
- * to tell the OS's power management driver which VIDs and FIDs are
- * supported by this particular processor.
- * If the data in the PSB / PST is wrong, then this driver will program the
- * wrong values into hardware, which is very likely to lead to a crash.
- */
-
-#define PSB_ID_STRING      "AMDK7PNOW!"
-#define PSB_ID_STRING_LEN  10
-
-#define PSB_VERSION_1_4  0x14
-
-struct psb_s {
-	u8 signature[10];
-	u8 tableversion;
-	u8 flags1;
-	u16 vstable;
-	u8 flags2;
-	u8 num_tables;
-	u32 cpuid;
-	u8 plllocktime;
-	u8 maxfid;
-	u8 maxvid;
-	u8 numps;
-};
-
-/* Pairs of fid/vid values are appended to the version 1.4 PSB table. */
-struct pst_s {
-	u8 fid;
-	u8 vid;
-};
-
-#define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, "powernow-k8", msg)
-
-static int core_voltage_pre_transition(struct powernow_k8_data *data,
-	u32 reqvid, u32 regfid);
-static int core_voltage_post_transition(struct powernow_k8_data *data, u32 reqvid);
-static int core_frequency_transition(struct powernow_k8_data *data, u32 reqfid);
-
-static void powernow_k8_acpi_pst_values(struct powernow_k8_data *data, unsigned int index);
-
-static int fill_powernow_table_pstate(struct powernow_k8_data *data, struct cpufreq_frequency_table *powernow_table);
-static int fill_powernow_table_fidvid(struct powernow_k8_data *data, struct cpufreq_frequency_table *powernow_table);
diff -druN linux-2.6.39-libre/arch/x86/kernel/cpu/cpufreq/sc520_freq.c linux-3.0-rc7-libre/arch/x86/kernel/cpu/cpufreq/sc520_freq.c
--- linux-2.6.39-libre/arch/x86/kernel/cpu/cpufreq/sc520_freq.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/kernel/cpu/cpufreq/sc520_freq.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,194 +0,0 @@
-/*
- *	sc520_freq.c: cpufreq driver for the AMD Elan sc520
- *
- *	Copyright (C) 2005 Sean Young <sean@mess.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.
- *
- *	Based on elanfreq.c
- *
- *	2005-03-30: - initial revision
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/init.h>
-
-#include <linux/delay.h>
-#include <linux/cpufreq.h>
-#include <linux/timex.h>
-#include <linux/io.h>
-
-#include <asm/msr.h>
-
-#define MMCR_BASE	0xfffef000	/* The default base address */
-#define OFFS_CPUCTL	0x2   /* CPU Control Register */
-
-static __u8 __iomem *cpuctl;
-
-#define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, \
-		"sc520_freq", msg)
-#define PFX "sc520_freq: "
-
-static struct cpufreq_frequency_table sc520_freq_table[] = {
-	{0x01,	100000},
-	{0x02,	133000},
-	{0,	CPUFREQ_TABLE_END},
-};
-
-static unsigned int sc520_freq_get_cpu_frequency(unsigned int cpu)
-{
-	u8 clockspeed_reg = *cpuctl;
-
-	switch (clockspeed_reg & 0x03) {
-	default:
-		printk(KERN_ERR PFX "error: cpuctl register has unexpected "
-				"value %02x\n", clockspeed_reg);
-	case 0x01:
-		return 100000;
-	case 0x02:
-		return 133000;
-	}
-}
-
-static void sc520_freq_set_cpu_state(unsigned int state)
-{
-
-	struct cpufreq_freqs	freqs;
-	u8 clockspeed_reg;
-
-	freqs.old = sc520_freq_get_cpu_frequency(0);
-	freqs.new = sc520_freq_table[state].frequency;
-	freqs.cpu = 0; /* AMD Elan is UP */
-
-	cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
-
-	dprintk("attempting to set frequency to %i kHz\n",
-			sc520_freq_table[state].frequency);
-
-	local_irq_disable();
-
-	clockspeed_reg = *cpuctl & ~0x03;
-	*cpuctl = clockspeed_reg | sc520_freq_table[state].index;
-
-	local_irq_enable();
-
-	cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
-};
-
-static int sc520_freq_verify(struct cpufreq_policy *policy)
-{
-	return cpufreq_frequency_table_verify(policy, &sc520_freq_table[0]);
-}
-
-static int sc520_freq_target(struct cpufreq_policy *policy,
-			    unsigned int target_freq,
-			    unsigned int relation)
-{
-	unsigned int newstate = 0;
-
-	if (cpufreq_frequency_table_target(policy, sc520_freq_table,
-				target_freq, relation, &newstate))
-		return -EINVAL;
-
-	sc520_freq_set_cpu_state(newstate);
-
-	return 0;
-}
-
-
-/*
- *	Module init and exit code
- */
-
-static int sc520_freq_cpu_init(struct cpufreq_policy *policy)
-{
-	struct cpuinfo_x86 *c = &cpu_data(0);
-	int result;
-
-	/* capability check */
-	if (c->x86_vendor != X86_VENDOR_AMD ||
-	    c->x86 != 4 || c->x86_model != 9)
-		return -ENODEV;
-
-	/* cpuinfo and default policy values */
-	policy->cpuinfo.transition_latency = 1000000; /* 1ms */
-	policy->cur = sc520_freq_get_cpu_frequency(0);
-
-	result = cpufreq_frequency_table_cpuinfo(policy, sc520_freq_table);
-	if (result)
-		return result;
-
-	cpufreq_frequency_table_get_attr(sc520_freq_table, policy->cpu);
-
-	return 0;
-}
-
-
-static int sc520_freq_cpu_exit(struct cpufreq_policy *policy)
-{
-	cpufreq_frequency_table_put_attr(policy->cpu);
-	return 0;
-}
-
-
-static struct freq_attr *sc520_freq_attr[] = {
-	&cpufreq_freq_attr_scaling_available_freqs,
-	NULL,
-};
-
-
-static struct cpufreq_driver sc520_freq_driver = {
-	.get	= sc520_freq_get_cpu_frequency,
-	.verify	= sc520_freq_verify,
-	.target	= sc520_freq_target,
-	.init	= sc520_freq_cpu_init,
-	.exit	= sc520_freq_cpu_exit,
-	.name	= "sc520_freq",
-	.owner	= THIS_MODULE,
-	.attr	= sc520_freq_attr,
-};
-
-
-static int __init sc520_freq_init(void)
-{
-	struct cpuinfo_x86 *c = &cpu_data(0);
-	int err;
-
-	/* Test if we have the right hardware */
-	if (c->x86_vendor != X86_VENDOR_AMD ||
-	    c->x86 != 4 || c->x86_model != 9) {
-		dprintk("no Elan SC520 processor found!\n");
-		return -ENODEV;
-	}
-	cpuctl = ioremap((unsigned long)(MMCR_BASE + OFFS_CPUCTL), 1);
-	if (!cpuctl) {
-		printk(KERN_ERR "sc520_freq: error: failed to remap memory\n");
-		return -ENOMEM;
-	}
-
-	err = cpufreq_register_driver(&sc520_freq_driver);
-	if (err)
-		iounmap(cpuctl);
-
-	return err;
-}
-
-
-static void __exit sc520_freq_exit(void)
-{
-	cpufreq_unregister_driver(&sc520_freq_driver);
-	iounmap(cpuctl);
-}
-
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Sean Young <sean@mess.org>");
-MODULE_DESCRIPTION("cpufreq driver for AMD's Elan sc520 CPU");
-
-module_init(sc520_freq_init);
-module_exit(sc520_freq_exit);
-
diff -druN linux-2.6.39-libre/arch/x86/kernel/cpu/cpufreq/speedstep-centrino.c linux-3.0-rc7-libre/arch/x86/kernel/cpu/cpufreq/speedstep-centrino.c
--- linux-2.6.39-libre/arch/x86/kernel/cpu/cpufreq/speedstep-centrino.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/kernel/cpu/cpufreq/speedstep-centrino.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,636 +0,0 @@
-/*
- * cpufreq driver for Enhanced SpeedStep, as found in Intel's Pentium
- * M (part of the Centrino chipset).
- *
- * Since the original Pentium M, most new Intel CPUs support Enhanced
- * SpeedStep.
- *
- * Despite the "SpeedStep" in the name, this is almost entirely unlike
- * traditional SpeedStep.
- *
- * Modelled on speedstep.c
- *
- * Copyright (C) 2003 Jeremy Fitzhardinge <jeremy@goop.org>
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/cpufreq.h>
-#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>
-#include <asm/cpufeature.h>
-
-#define PFX		"speedstep-centrino: "
-#define MAINTAINER	"cpufreq@vger.kernel.org"
-
-#define dprintk(msg...) \
-	cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, "speedstep-centrino", msg)
-
-#define INTEL_MSR_RANGE	(0xffff)
-
-struct cpu_id
-{
-	__u8	x86;            /* CPU family */
-	__u8	x86_model;	/* model */
-	__u8	x86_mask;	/* stepping */
-};
-
-enum {
-	CPU_BANIAS,
-	CPU_DOTHAN_A1,
-	CPU_DOTHAN_A2,
-	CPU_DOTHAN_B0,
-	CPU_MP4HT_D0,
-	CPU_MP4HT_E0,
-};
-
-static const struct cpu_id cpu_ids[] = {
-	[CPU_BANIAS]	= { 6,  9, 5 },
-	[CPU_DOTHAN_A1]	= { 6, 13, 1 },
-	[CPU_DOTHAN_A2]	= { 6, 13, 2 },
-	[CPU_DOTHAN_B0]	= { 6, 13, 6 },
-	[CPU_MP4HT_D0]	= {15,  3, 4 },
-	[CPU_MP4HT_E0]	= {15,  4, 1 },
-};
-#define N_IDS	ARRAY_SIZE(cpu_ids)
-
-struct cpu_model
-{
-	const struct cpu_id *cpu_id;
-	const char	*model_name;
-	unsigned	max_freq; /* max clock in kHz */
-
-	struct cpufreq_frequency_table *op_points; /* clock/voltage pairs */
-};
-static int centrino_verify_cpu_id(const struct cpuinfo_x86 *c,
-				  const struct cpu_id *x);
-
-/* Operating points for current CPU */
-static DEFINE_PER_CPU(struct cpu_model *, centrino_model);
-static DEFINE_PER_CPU(const struct cpu_id *, centrino_cpu);
-
-static struct cpufreq_driver centrino_driver;
-
-#ifdef CONFIG_X86_SPEEDSTEP_CENTRINO_TABLE
-
-/* Computes the correct form for IA32_PERF_CTL MSR for a particular
-   frequency/voltage operating point; frequency in MHz, volts in mV.
-   This is stored as "index" in the structure. */
-#define OP(mhz, mv)							\
-	{								\
-		.frequency = (mhz) * 1000,				\
-		.index = (((mhz)/100) << 8) | ((mv - 700) / 16)		\
-	}
-
-/*
- * These voltage tables were derived from the Intel Pentium M
- * datasheet, document 25261202.pdf, Table 5.  I have verified they
- * are consistent with my IBM ThinkPad X31, which has a 1.3GHz Pentium
- * M.
- */
-
-/* Ultra Low Voltage Intel Pentium M processor 900MHz (Banias) */
-static struct cpufreq_frequency_table banias_900[] =
-{
-	OP(600,  844),
-	OP(800,  988),
-	OP(900, 1004),
-	{ .frequency = CPUFREQ_TABLE_END }
-};
-
-/* Ultra Low Voltage Intel Pentium M processor 1000MHz (Banias) */
-static struct cpufreq_frequency_table banias_1000[] =
-{
-	OP(600,   844),
-	OP(800,   972),
-	OP(900,   988),
-	OP(1000, 1004),
-	{ .frequency = CPUFREQ_TABLE_END }
-};
-
-/* Low Voltage Intel Pentium M processor 1.10GHz (Banias) */
-static struct cpufreq_frequency_table banias_1100[] =
-{
-	OP( 600,  956),
-	OP( 800, 1020),
-	OP( 900, 1100),
-	OP(1000, 1164),
-	OP(1100, 1180),
-	{ .frequency = CPUFREQ_TABLE_END }
-};
-
-
-/* Low Voltage Intel Pentium M processor 1.20GHz (Banias) */
-static struct cpufreq_frequency_table banias_1200[] =
-{
-	OP( 600,  956),
-	OP( 800, 1004),
-	OP( 900, 1020),
-	OP(1000, 1100),
-	OP(1100, 1164),
-	OP(1200, 1180),
-	{ .frequency = CPUFREQ_TABLE_END }
-};
-
-/* Intel Pentium M processor 1.30GHz (Banias) */
-static struct cpufreq_frequency_table banias_1300[] =
-{
-	OP( 600,  956),
-	OP( 800, 1260),
-	OP(1000, 1292),
-	OP(1200, 1356),
-	OP(1300, 1388),
-	{ .frequency = CPUFREQ_TABLE_END }
-};
-
-/* Intel Pentium M processor 1.40GHz (Banias) */
-static struct cpufreq_frequency_table banias_1400[] =
-{
-	OP( 600,  956),
-	OP( 800, 1180),
-	OP(1000, 1308),
-	OP(1200, 1436),
-	OP(1400, 1484),
-	{ .frequency = CPUFREQ_TABLE_END }
-};
-
-/* Intel Pentium M processor 1.50GHz (Banias) */
-static struct cpufreq_frequency_table banias_1500[] =
-{
-	OP( 600,  956),
-	OP( 800, 1116),
-	OP(1000, 1228),
-	OP(1200, 1356),
-	OP(1400, 1452),
-	OP(1500, 1484),
-	{ .frequency = CPUFREQ_TABLE_END }
-};
-
-/* Intel Pentium M processor 1.60GHz (Banias) */
-static struct cpufreq_frequency_table banias_1600[] =
-{
-	OP( 600,  956),
-	OP( 800, 1036),
-	OP(1000, 1164),
-	OP(1200, 1276),
-	OP(1400, 1420),
-	OP(1600, 1484),
-	{ .frequency = CPUFREQ_TABLE_END }
-};
-
-/* Intel Pentium M processor 1.70GHz (Banias) */
-static struct cpufreq_frequency_table banias_1700[] =
-{
-	OP( 600,  956),
-	OP( 800, 1004),
-	OP(1000, 1116),
-	OP(1200, 1228),
-	OP(1400, 1308),
-	OP(1700, 1484),
-	{ .frequency = CPUFREQ_TABLE_END }
-};
-#undef OP
-
-#define _BANIAS(cpuid, max, name)	\
-{	.cpu_id		= cpuid,	\
-	.model_name	= "Intel(R) Pentium(R) M processor " name "MHz", \
-	.max_freq	= (max)*1000,	\
-	.op_points	= banias_##max,	\
-}
-#define BANIAS(max)	_BANIAS(&cpu_ids[CPU_BANIAS], max, #max)
-
-/* CPU models, their operating frequency range, and freq/voltage
-   operating points */
-static struct cpu_model models[] =
-{
-	_BANIAS(&cpu_ids[CPU_BANIAS], 900, " 900"),
-	BANIAS(1000),
-	BANIAS(1100),
-	BANIAS(1200),
-	BANIAS(1300),
-	BANIAS(1400),
-	BANIAS(1500),
-	BANIAS(1600),
-	BANIAS(1700),
-
-	/* NULL model_name is a wildcard */
-	{ &cpu_ids[CPU_DOTHAN_A1], NULL, 0, NULL },
-	{ &cpu_ids[CPU_DOTHAN_A2], NULL, 0, NULL },
-	{ &cpu_ids[CPU_DOTHAN_B0], NULL, 0, NULL },
-	{ &cpu_ids[CPU_MP4HT_D0], NULL, 0, NULL },
-	{ &cpu_ids[CPU_MP4HT_E0], NULL, 0, NULL },
-
-	{ NULL, }
-};
-#undef _BANIAS
-#undef BANIAS
-
-static int centrino_cpu_init_table(struct cpufreq_policy *policy)
-{
-	struct cpuinfo_x86 *cpu = &cpu_data(policy->cpu);
-	struct cpu_model *model;
-
-	for(model = models; model->cpu_id != NULL; model++)
-		if (centrino_verify_cpu_id(cpu, model->cpu_id) &&
-		    (model->model_name == NULL ||
-		     strcmp(cpu->x86_model_id, model->model_name) == 0))
-			break;
-
-	if (model->cpu_id == NULL) {
-		/* No match at all */
-		dprintk("no support for CPU model \"%s\": "
-		       "send /proc/cpuinfo to " MAINTAINER "\n",
-		       cpu->x86_model_id);
-		return -ENOENT;
-	}
-
-	if (model->op_points == NULL) {
-		/* Matched a non-match */
-		dprintk("no table support for CPU model \"%s\"\n",
-		       cpu->x86_model_id);
-		dprintk("try using the acpi-cpufreq driver\n");
-		return -ENOENT;
-	}
-
-	per_cpu(centrino_model, policy->cpu) = model;
-
-	dprintk("found \"%s\": max frequency: %dkHz\n",
-	       model->model_name, model->max_freq);
-
-	return 0;
-}
-
-#else
-static inline int centrino_cpu_init_table(struct cpufreq_policy *policy)
-{
-	return -ENODEV;
-}
-#endif /* CONFIG_X86_SPEEDSTEP_CENTRINO_TABLE */
-
-static int centrino_verify_cpu_id(const struct cpuinfo_x86 *c,
-				  const struct cpu_id *x)
-{
-	if ((c->x86 == x->x86) &&
-	    (c->x86_model == x->x86_model) &&
-	    (c->x86_mask == x->x86_mask))
-		return 1;
-	return 0;
-}
-
-/* To be called only after centrino_model is initialized */
-static unsigned extract_clock(unsigned msr, unsigned int cpu, int failsafe)
-{
-	int i;
-
-	/*
-	 * Extract clock in kHz from PERF_CTL value
-	 * for centrino, as some DSDTs are buggy.
-	 * Ideally, this can be done using the acpi_data structure.
-	 */
-	if ((per_cpu(centrino_cpu, cpu) == &cpu_ids[CPU_BANIAS]) ||
-	    (per_cpu(centrino_cpu, cpu) == &cpu_ids[CPU_DOTHAN_A1]) ||
-	    (per_cpu(centrino_cpu, cpu) == &cpu_ids[CPU_DOTHAN_B0])) {
-		msr = (msr >> 8) & 0xff;
-		return msr * 100000;
-	}
-
-	if ((!per_cpu(centrino_model, cpu)) ||
-	    (!per_cpu(centrino_model, cpu)->op_points))
-		return 0;
-
-	msr &= 0xffff;
-	for (i = 0;
-		per_cpu(centrino_model, cpu)->op_points[i].frequency
-							!= CPUFREQ_TABLE_END;
-	     i++) {
-		if (msr == per_cpu(centrino_model, cpu)->op_points[i].index)
-			return per_cpu(centrino_model, cpu)->
-							op_points[i].frequency;
-	}
-	if (failsafe)
-		return per_cpu(centrino_model, cpu)->op_points[i-1].frequency;
-	else
-		return 0;
-}
-
-/* Return the current CPU frequency in kHz */
-static unsigned int get_cur_freq(unsigned int cpu)
-{
-	unsigned l, h;
-	unsigned clock_freq;
-
-	rdmsr_on_cpu(cpu, MSR_IA32_PERF_STATUS, &l, &h);
-	clock_freq = extract_clock(l, cpu, 0);
-
-	if (unlikely(clock_freq == 0)) {
-		/*
-		 * On some CPUs, we can see transient MSR values (which are
-		 * not present in _PSS), while CPU is doing some automatic
-		 * P-state transition (like TM2). Get the last freq set 
-		 * in PERF_CTL.
-		 */
-		rdmsr_on_cpu(cpu, MSR_IA32_PERF_CTL, &l, &h);
-		clock_freq = extract_clock(l, cpu, 1);
-	}
-	return clock_freq;
-}
-
-
-static int centrino_cpu_init(struct cpufreq_policy *policy)
-{
-	struct cpuinfo_x86 *cpu = &cpu_data(policy->cpu);
-	unsigned freq;
-	unsigned l, h;
-	int ret;
-	int i;
-
-	/* Only Intel makes Enhanced Speedstep-capable CPUs */
-	if (cpu->x86_vendor != X86_VENDOR_INTEL ||
-	    !cpu_has(cpu, X86_FEATURE_EST))
-		return -ENODEV;
-
-	if (cpu_has(cpu, X86_FEATURE_CONSTANT_TSC))
-		centrino_driver.flags |= CPUFREQ_CONST_LOOPS;
-
-	if (policy->cpu != 0)
-		return -ENODEV;
-
-	for (i = 0; i < N_IDS; i++)
-		if (centrino_verify_cpu_id(cpu, &cpu_ids[i]))
-			break;
-
-	if (i != N_IDS)
-		per_cpu(centrino_cpu, policy->cpu) = &cpu_ids[i];
-
-	if (!per_cpu(centrino_cpu, policy->cpu)) {
-		dprintk("found unsupported CPU with "
-		"Enhanced SpeedStep: send /proc/cpuinfo to "
-		MAINTAINER "\n");
-		return -ENODEV;
-	}
-
-	if (centrino_cpu_init_table(policy)) {
-		return -ENODEV;
-	}
-
-	/* Check to see if Enhanced SpeedStep is enabled, and try to
-	   enable it if not. */
-	rdmsr(MSR_IA32_MISC_ENABLE, l, h);
-
-	if (!(l & MSR_IA32_MISC_ENABLE_ENHANCED_SPEEDSTEP)) {
-		l |= MSR_IA32_MISC_ENABLE_ENHANCED_SPEEDSTEP;
-		dprintk("trying to enable Enhanced SpeedStep (%x)\n", l);
-		wrmsr(MSR_IA32_MISC_ENABLE, l, h);
-
-		/* check to see if it stuck */
-		rdmsr(MSR_IA32_MISC_ENABLE, l, h);
-		if (!(l & MSR_IA32_MISC_ENABLE_ENHANCED_SPEEDSTEP)) {
-			printk(KERN_INFO PFX
-				"couldn't enable Enhanced SpeedStep\n");
-			return -ENODEV;
-		}
-	}
-
-	freq = get_cur_freq(policy->cpu);
-	policy->cpuinfo.transition_latency = 10000;
-						/* 10uS transition latency */
-	policy->cur = freq;
-
-	dprintk("centrino_cpu_init: cur=%dkHz\n", policy->cur);
-
-	ret = cpufreq_frequency_table_cpuinfo(policy,
-		per_cpu(centrino_model, policy->cpu)->op_points);
-	if (ret)
-		return (ret);
-
-	cpufreq_frequency_table_get_attr(
-		per_cpu(centrino_model, policy->cpu)->op_points, policy->cpu);
-
-	return 0;
-}
-
-static int centrino_cpu_exit(struct cpufreq_policy *policy)
-{
-	unsigned int cpu = policy->cpu;
-
-	if (!per_cpu(centrino_model, cpu))
-		return -ENODEV;
-
-	cpufreq_frequency_table_put_attr(cpu);
-
-	per_cpu(centrino_model, cpu) = NULL;
-
-	return 0;
-}
-
-/**
- * centrino_verify - verifies a new CPUFreq policy
- * @policy: new policy
- *
- * Limit must be within this model's frequency range at least one
- * border included.
- */
-static int centrino_verify (struct cpufreq_policy *policy)
-{
-	return cpufreq_frequency_table_verify(policy,
-			per_cpu(centrino_model, policy->cpu)->op_points);
-}
-
-/**
- * centrino_setpolicy - set a new CPUFreq policy
- * @policy: new policy
- * @target_freq: the target frequency
- * @relation: how that frequency relates to achieved frequency
- *	(CPUFREQ_RELATION_L or CPUFREQ_RELATION_H)
- *
- * Sets a new CPUFreq policy.
- */
-static int centrino_target (struct cpufreq_policy *policy,
-			    unsigned int target_freq,
-			    unsigned int relation)
-{
-	unsigned int    newstate = 0;
-	unsigned int	msr, oldmsr = 0, h = 0, cpu = policy->cpu;
-	struct cpufreq_freqs	freqs;
-	int			retval = 0;
-	unsigned int		j, k, first_cpu, tmp;
-	cpumask_var_t covered_cpus;
-
-	if (unlikely(!zalloc_cpumask_var(&covered_cpus, GFP_KERNEL)))
-		return -ENOMEM;
-
-	if (unlikely(per_cpu(centrino_model, cpu) == NULL)) {
-		retval = -ENODEV;
-		goto out;
-	}
-
-	if (unlikely(cpufreq_frequency_table_target(policy,
-			per_cpu(centrino_model, cpu)->op_points,
-			target_freq,
-			relation,
-			&newstate))) {
-		retval = -EINVAL;
-		goto out;
-	}
-
-	first_cpu = 1;
-	for_each_cpu(j, policy->cpus) {
-		int good_cpu;
-
-		/* cpufreq holds the hotplug lock, so we are safe here */
-		if (!cpu_online(j))
-			continue;
-
-		/*
-		 * Support for SMP systems.
-		 * Make sure we are running on CPU that wants to change freq
-		 */
-		if (policy->shared_type == CPUFREQ_SHARED_TYPE_ANY)
-			good_cpu = cpumask_any_and(policy->cpus,
-						   cpu_online_mask);
-		else
-			good_cpu = j;
-
-		if (good_cpu >= nr_cpu_ids) {
-			dprintk("couldn't limit to CPUs in this domain\n");
-			retval = -EAGAIN;
-			if (first_cpu) {
-				/* We haven't started the transition yet. */
-				goto out;
-			}
-			break;
-		}
-
-		msr = per_cpu(centrino_model, cpu)->op_points[newstate].index;
-
-		if (first_cpu) {
-			rdmsr_on_cpu(good_cpu, MSR_IA32_PERF_CTL, &oldmsr, &h);
-			if (msr == (oldmsr & 0xffff)) {
-				dprintk("no change needed - msr was and needs "
-					"to be %x\n", oldmsr);
-				retval = 0;
-				goto out;
-			}
-
-			freqs.old = extract_clock(oldmsr, cpu, 0);
-			freqs.new = extract_clock(msr, cpu, 0);
-
-			dprintk("target=%dkHz old=%d new=%d msr=%04x\n",
-				target_freq, freqs.old, freqs.new, msr);
-
-			for_each_cpu(k, policy->cpus) {
-				if (!cpu_online(k))
-					continue;
-				freqs.cpu = k;
-				cpufreq_notify_transition(&freqs,
-					CPUFREQ_PRECHANGE);
-			}
-
-			first_cpu = 0;
-			/* all but 16 LSB are reserved, treat them with care */
-			oldmsr &= ~0xffff;
-			msr &= 0xffff;
-			oldmsr |= msr;
-		}
-
-		wrmsr_on_cpu(good_cpu, MSR_IA32_PERF_CTL, oldmsr, h);
-		if (policy->shared_type == CPUFREQ_SHARED_TYPE_ANY)
-			break;
-
-		cpumask_set_cpu(j, covered_cpus);
-	}
-
-	for_each_cpu(k, policy->cpus) {
-		if (!cpu_online(k))
-			continue;
-		freqs.cpu = k;
-		cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
-	}
-
-	if (unlikely(retval)) {
-		/*
-		 * We have failed halfway through the frequency change.
-		 * We have sent callbacks to policy->cpus and
-		 * MSRs have already been written on coverd_cpus.
-		 * Best effort undo..
-		 */
-
-		for_each_cpu(j, covered_cpus)
-			wrmsr_on_cpu(j, MSR_IA32_PERF_CTL, oldmsr, h);
-
-		tmp = freqs.new;
-		freqs.new = freqs.old;
-		freqs.old = tmp;
-		for_each_cpu(j, policy->cpus) {
-			if (!cpu_online(j))
-				continue;
-			cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
-			cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
-		}
-	}
-	retval = 0;
-
-out:
-	free_cpumask_var(covered_cpus);
-	return retval;
-}
-
-static struct freq_attr* centrino_attr[] = {
-	&cpufreq_freq_attr_scaling_available_freqs,
-	NULL,
-};
-
-static struct cpufreq_driver centrino_driver = {
-	.name		= "centrino", /* should be speedstep-centrino,
-					 but there's a 16 char limit */
-	.init		= centrino_cpu_init,
-	.exit		= centrino_cpu_exit,
-	.verify		= centrino_verify,
-	.target		= centrino_target,
-	.get		= get_cur_freq,
-	.attr           = centrino_attr,
-	.owner		= THIS_MODULE,
-};
-
-
-/**
- * centrino_init - initializes the Enhanced SpeedStep CPUFreq driver
- *
- * Initializes the Enhanced SpeedStep support. Returns -ENODEV on
- * unsupported devices, -ENOENT if there's no voltage table for this
- * particular CPU model, -EINVAL on problems during initiatization,
- * and zero on success.
- *
- * This is quite picky.  Not only does the CPU have to advertise the
- * "est" flag in the cpuid capability flags, we look for a specific
- * CPU model and stepping, and we need to have the exact model name in
- * our voltage tables.  That is, be paranoid about not releasing
- * someone's valuable magic smoke.
- */
-static int __init centrino_init(void)
-{
-	struct cpuinfo_x86 *cpu = &cpu_data(0);
-
-	if (!cpu_has(cpu, X86_FEATURE_EST))
-		return -ENODEV;
-
-	return cpufreq_register_driver(&centrino_driver);
-}
-
-static void __exit centrino_exit(void)
-{
-	cpufreq_unregister_driver(&centrino_driver);
-}
-
-MODULE_AUTHOR ("Jeremy Fitzhardinge <jeremy@goop.org>");
-MODULE_DESCRIPTION ("Enhanced SpeedStep driver for Intel Pentium M processors.");
-MODULE_LICENSE ("GPL");
-
-late_initcall(centrino_init);
-module_exit(centrino_exit);
diff -druN linux-2.6.39-libre/arch/x86/kernel/cpu/cpufreq/speedstep-ich.c linux-3.0-rc7-libre/arch/x86/kernel/cpu/cpufreq/speedstep-ich.c
--- linux-2.6.39-libre/arch/x86/kernel/cpu/cpufreq/speedstep-ich.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/kernel/cpu/cpufreq/speedstep-ich.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,452 +0,0 @@
-/*
- * (C) 2001  Dave Jones, Arjan van de ven.
- * (C) 2002 - 2003  Dominik Brodowski <linux@brodo.de>
- *
- *  Licensed under the terms of the GNU GPL License version 2.
- *  Based upon reverse engineered information, and on Intel documentation
- *  for chipsets ICH2-M and ICH3-M.
- *
- *  Many thanks to Ducrot Bruno for finding and fixing the last
- *  "missing link" for ICH2-M/ICH3-M support, and to Thomas Winkler
- *  for extensive testing.
- *
- *  BIG FAT DISCLAIMER: Work in progress code. Possibly *dangerous*
- */
-
-
-/*********************************************************************
- *                        SPEEDSTEP - DEFINITIONS                    *
- *********************************************************************/
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/cpufreq.h>
-#include <linux/pci.h>
-#include <linux/sched.h>
-
-#include "speedstep-lib.h"
-
-
-/* speedstep_chipset:
- *   It is necessary to know which chipset is used. As accesses to
- * this device occur at various places in this module, we need a
- * static struct pci_dev * pointing to that device.
- */
-static struct pci_dev *speedstep_chipset_dev;
-
-
-/* speedstep_processor
- */
-static enum speedstep_processor speedstep_processor;
-
-static u32 pmbase;
-
-/*
- *   There are only two frequency states for each processor. Values
- * are in kHz for the time being.
- */
-static struct cpufreq_frequency_table speedstep_freqs[] = {
-	{SPEEDSTEP_HIGH,	0},
-	{SPEEDSTEP_LOW,		0},
-	{0,			CPUFREQ_TABLE_END},
-};
-
-
-#define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, \
-		"speedstep-ich", msg)
-
-
-/**
- * speedstep_find_register - read the PMBASE address
- *
- * Returns: -ENODEV if no register could be found
- */
-static int speedstep_find_register(void)
-{
-	if (!speedstep_chipset_dev)
-		return -ENODEV;
-
-	/* get PMBASE */
-	pci_read_config_dword(speedstep_chipset_dev, 0x40, &pmbase);
-	if (!(pmbase & 0x01)) {
-		printk(KERN_ERR "speedstep-ich: could not find speedstep register\n");
-		return -ENODEV;
-	}
-
-	pmbase &= 0xFFFFFFFE;
-	if (!pmbase) {
-		printk(KERN_ERR "speedstep-ich: could not find speedstep register\n");
-		return -ENODEV;
-	}
-
-	dprintk("pmbase is 0x%x\n", pmbase);
-	return 0;
-}
-
-/**
- * speedstep_set_state - set the SpeedStep state
- * @state: new processor frequency state (SPEEDSTEP_LOW or SPEEDSTEP_HIGH)
- *
- *   Tries to change the SpeedStep state.  Can be called from
- *   smp_call_function_single.
- */
-static void speedstep_set_state(unsigned int state)
-{
-	u8 pm2_blk;
-	u8 value;
-	unsigned long flags;
-
-	if (state > 0x1)
-		return;
-
-	/* Disable IRQs */
-	local_irq_save(flags);
-
-	/* read state */
-	value = inb(pmbase + 0x50);
-
-	dprintk("read at pmbase 0x%x + 0x50 returned 0x%x\n", pmbase, value);
-
-	/* write new state */
-	value &= 0xFE;
-	value |= state;
-
-	dprintk("writing 0x%x to pmbase 0x%x + 0x50\n", value, pmbase);
-
-	/* Disable bus master arbitration */
-	pm2_blk = inb(pmbase + 0x20);
-	pm2_blk |= 0x01;
-	outb(pm2_blk, (pmbase + 0x20));
-
-	/* Actual transition */
-	outb(value, (pmbase + 0x50));
-
-	/* Restore bus master arbitration */
-	pm2_blk &= 0xfe;
-	outb(pm2_blk, (pmbase + 0x20));
-
-	/* check if transition was successful */
-	value = inb(pmbase + 0x50);
-
-	/* Enable IRQs */
-	local_irq_restore(flags);
-
-	dprintk("read at pmbase 0x%x + 0x50 returned 0x%x\n", pmbase, value);
-
-	if (state == (value & 0x1))
-		dprintk("change to %u MHz succeeded\n",
-			speedstep_get_frequency(speedstep_processor) / 1000);
-	else
-		printk(KERN_ERR "cpufreq: change failed - I/O error\n");
-
-	return;
-}
-
-/* Wrapper for smp_call_function_single. */
-static void _speedstep_set_state(void *_state)
-{
-	speedstep_set_state(*(unsigned int *)_state);
-}
-
-/**
- * speedstep_activate - activate SpeedStep control in the chipset
- *
- *   Tries to activate the SpeedStep status and control registers.
- * Returns -EINVAL on an unsupported chipset, and zero on success.
- */
-static int speedstep_activate(void)
-{
-	u16 value = 0;
-
-	if (!speedstep_chipset_dev)
-		return -EINVAL;
-
-	pci_read_config_word(speedstep_chipset_dev, 0x00A0, &value);
-	if (!(value & 0x08)) {
-		value |= 0x08;
-		dprintk("activating SpeedStep (TM) registers\n");
-		pci_write_config_word(speedstep_chipset_dev, 0x00A0, value);
-	}
-
-	return 0;
-}
-
-
-/**
- * speedstep_detect_chipset - detect the Southbridge which contains SpeedStep logic
- *
- *   Detects ICH2-M, ICH3-M and ICH4-M so far. The pci_dev points to
- * the LPC bridge / PM module which contains all power-management
- * functions. Returns the SPEEDSTEP_CHIPSET_-number for the detected
- * chipset, or zero on failure.
- */
-static unsigned int speedstep_detect_chipset(void)
-{
-	speedstep_chipset_dev = pci_get_subsys(PCI_VENDOR_ID_INTEL,
-			      PCI_DEVICE_ID_INTEL_82801DB_12,
-			      PCI_ANY_ID, PCI_ANY_ID,
-			      NULL);
-	if (speedstep_chipset_dev)
-		return 4; /* 4-M */
-
-	speedstep_chipset_dev = pci_get_subsys(PCI_VENDOR_ID_INTEL,
-			      PCI_DEVICE_ID_INTEL_82801CA_12,
-			      PCI_ANY_ID, PCI_ANY_ID,
-			      NULL);
-	if (speedstep_chipset_dev)
-		return 3; /* 3-M */
-
-
-	speedstep_chipset_dev = pci_get_subsys(PCI_VENDOR_ID_INTEL,
-			      PCI_DEVICE_ID_INTEL_82801BA_10,
-			      PCI_ANY_ID, PCI_ANY_ID,
-			      NULL);
-	if (speedstep_chipset_dev) {
-		/* speedstep.c causes lockups on Dell Inspirons 8000 and
-		 * 8100 which use a pretty old revision of the 82815
-		 * host brige. Abort on these systems.
-		 */
-		static struct pci_dev *hostbridge;
-
-		hostbridge  = pci_get_subsys(PCI_VENDOR_ID_INTEL,
-			      PCI_DEVICE_ID_INTEL_82815_MC,
-			      PCI_ANY_ID, PCI_ANY_ID,
-			      NULL);
-
-		if (!hostbridge)
-			return 2; /* 2-M */
-
-		if (hostbridge->revision < 5) {
-			dprintk("hostbridge does not support speedstep\n");
-			speedstep_chipset_dev = NULL;
-			pci_dev_put(hostbridge);
-			return 0;
-		}
-
-		pci_dev_put(hostbridge);
-		return 2; /* 2-M */
-	}
-
-	return 0;
-}
-
-static void get_freq_data(void *_speed)
-{
-	unsigned int *speed = _speed;
-
-	*speed = speedstep_get_frequency(speedstep_processor);
-}
-
-static unsigned int speedstep_get(unsigned int cpu)
-{
-	unsigned int speed;
-
-	/* You're supposed to ensure CPU is online. */
-	if (smp_call_function_single(cpu, get_freq_data, &speed, 1) != 0)
-		BUG();
-
-	dprintk("detected %u kHz as current frequency\n", speed);
-	return speed;
-}
-
-/**
- * speedstep_target - set a new CPUFreq policy
- * @policy: new policy
- * @target_freq: the target frequency
- * @relation: how that frequency relates to achieved frequency
- *	(CPUFREQ_RELATION_L or CPUFREQ_RELATION_H)
- *
- * Sets a new CPUFreq policy.
- */
-static int speedstep_target(struct cpufreq_policy *policy,
-			     unsigned int target_freq,
-			     unsigned int relation)
-{
-	unsigned int newstate = 0, policy_cpu;
-	struct cpufreq_freqs freqs;
-	int i;
-
-	if (cpufreq_frequency_table_target(policy, &speedstep_freqs[0],
-				target_freq, relation, &newstate))
-		return -EINVAL;
-
-	policy_cpu = cpumask_any_and(policy->cpus, cpu_online_mask);
-	freqs.old = speedstep_get(policy_cpu);
-	freqs.new = speedstep_freqs[newstate].frequency;
-	freqs.cpu = policy->cpu;
-
-	dprintk("transiting from %u to %u kHz\n", freqs.old, freqs.new);
-
-	/* no transition necessary */
-	if (freqs.old == freqs.new)
-		return 0;
-
-	for_each_cpu(i, policy->cpus) {
-		freqs.cpu = i;
-		cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
-	}
-
-	smp_call_function_single(policy_cpu, _speedstep_set_state, &newstate,
-				 true);
-
-	for_each_cpu(i, policy->cpus) {
-		freqs.cpu = i;
-		cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
-	}
-
-	return 0;
-}
-
-
-/**
- * speedstep_verify - verifies a new CPUFreq policy
- * @policy: new policy
- *
- * Limit must be within speedstep_low_freq and speedstep_high_freq, with
- * at least one border included.
- */
-static int speedstep_verify(struct cpufreq_policy *policy)
-{
-	return cpufreq_frequency_table_verify(policy, &speedstep_freqs[0]);
-}
-
-struct get_freqs {
-	struct cpufreq_policy *policy;
-	int ret;
-};
-
-static void get_freqs_on_cpu(void *_get_freqs)
-{
-	struct get_freqs *get_freqs = _get_freqs;
-
-	get_freqs->ret =
-		speedstep_get_freqs(speedstep_processor,
-			    &speedstep_freqs[SPEEDSTEP_LOW].frequency,
-			    &speedstep_freqs[SPEEDSTEP_HIGH].frequency,
-			    &get_freqs->policy->cpuinfo.transition_latency,
-			    &speedstep_set_state);
-}
-
-static int speedstep_cpu_init(struct cpufreq_policy *policy)
-{
-	int result;
-	unsigned int policy_cpu, speed;
-	struct get_freqs gf;
-
-	/* only run on CPU to be set, or on its sibling */
-#ifdef CONFIG_SMP
-	cpumask_copy(policy->cpus, cpu_sibling_mask(policy->cpu));
-#endif
-	policy_cpu = cpumask_any_and(policy->cpus, cpu_online_mask);
-
-	/* detect low and high frequency and transition latency */
-	gf.policy = policy;
-	smp_call_function_single(policy_cpu, get_freqs_on_cpu, &gf, 1);
-	if (gf.ret)
-		return gf.ret;
-
-	/* get current speed setting */
-	speed = speedstep_get(policy_cpu);
-	if (!speed)
-		return -EIO;
-
-	dprintk("currently at %s speed setting - %i MHz\n",
-		(speed == speedstep_freqs[SPEEDSTEP_LOW].frequency)
-		? "low" : "high",
-		(speed / 1000));
-
-	/* cpuinfo and default policy values */
-	policy->cur = speed;
-
-	result = cpufreq_frequency_table_cpuinfo(policy, speedstep_freqs);
-	if (result)
-		return result;
-
-	cpufreq_frequency_table_get_attr(speedstep_freqs, policy->cpu);
-
-	return 0;
-}
-
-
-static int speedstep_cpu_exit(struct cpufreq_policy *policy)
-{
-	cpufreq_frequency_table_put_attr(policy->cpu);
-	return 0;
-}
-
-static struct freq_attr *speedstep_attr[] = {
-	&cpufreq_freq_attr_scaling_available_freqs,
-	NULL,
-};
-
-
-static struct cpufreq_driver speedstep_driver = {
-	.name	= "speedstep-ich",
-	.verify	= speedstep_verify,
-	.target	= speedstep_target,
-	.init	= speedstep_cpu_init,
-	.exit	= speedstep_cpu_exit,
-	.get	= speedstep_get,
-	.owner	= THIS_MODULE,
-	.attr	= speedstep_attr,
-};
-
-
-/**
- * speedstep_init - initializes the SpeedStep CPUFreq driver
- *
- *   Initializes the SpeedStep support. Returns -ENODEV on unsupported
- * devices, -EINVAL on problems during initiatization, and zero on
- * success.
- */
-static int __init speedstep_init(void)
-{
-	/* detect processor */
-	speedstep_processor = speedstep_detect_processor();
-	if (!speedstep_processor) {
-		dprintk("Intel(R) SpeedStep(TM) capable processor "
-				"not found\n");
-		return -ENODEV;
-	}
-
-	/* detect chipset */
-	if (!speedstep_detect_chipset()) {
-		dprintk("Intel(R) SpeedStep(TM) for this chipset not "
-				"(yet) available.\n");
-		return -ENODEV;
-	}
-
-	/* activate speedstep support */
-	if (speedstep_activate()) {
-		pci_dev_put(speedstep_chipset_dev);
-		return -EINVAL;
-	}
-
-	if (speedstep_find_register())
-		return -ENODEV;
-
-	return cpufreq_register_driver(&speedstep_driver);
-}
-
-
-/**
- * speedstep_exit - unregisters SpeedStep support
- *
- *   Unregisters SpeedStep support.
- */
-static void __exit speedstep_exit(void)
-{
-	pci_dev_put(speedstep_chipset_dev);
-	cpufreq_unregister_driver(&speedstep_driver);
-}
-
-
-MODULE_AUTHOR("Dave Jones <davej@redhat.com>, "
-		"Dominik Brodowski <linux@brodo.de>");
-MODULE_DESCRIPTION("Speedstep driver for Intel mobile processors on chipsets "
-		"with ICH-M southbridges.");
-MODULE_LICENSE("GPL");
-
-module_init(speedstep_init);
-module_exit(speedstep_exit);
diff -druN linux-2.6.39-libre/arch/x86/kernel/cpu/cpufreq/speedstep-lib.c linux-3.0-rc7-libre/arch/x86/kernel/cpu/cpufreq/speedstep-lib.c
--- linux-2.6.39-libre/arch/x86/kernel/cpu/cpufreq/speedstep-lib.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/kernel/cpu/cpufreq/speedstep-lib.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,481 +0,0 @@
-/*
- * (C) 2002 - 2003 Dominik Brodowski <linux@brodo.de>
- *
- *  Licensed under the terms of the GNU GPL License version 2.
- *
- *  Library for common functions for Intel SpeedStep v.1 and v.2 support
- *
- *  BIG FAT DISCLAIMER: Work in progress code. Possibly *dangerous*
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/init.h>
-#include <linux/cpufreq.h>
-
-#include <asm/msr.h>
-#include <asm/tsc.h>
-#include "speedstep-lib.h"
-
-#define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, \
-		"speedstep-lib", msg)
-
-#define PFX "speedstep-lib: "
-
-#ifdef CONFIG_X86_SPEEDSTEP_RELAXED_CAP_CHECK
-static int relaxed_check;
-#else
-#define relaxed_check 0
-#endif
-
-/*********************************************************************
- *                   GET PROCESSOR CORE SPEED IN KHZ                 *
- *********************************************************************/
-
-static unsigned int pentium3_get_frequency(enum speedstep_processor processor)
-{
-	/* See table 14 of p3_ds.pdf and table 22 of 29834003.pdf */
-	struct {
-		unsigned int ratio;	/* Frequency Multiplier (x10) */
-		u8 bitmap;		/* power on configuration bits
-					[27, 25:22] (in MSR 0x2a) */
-	} msr_decode_mult[] = {
-		{ 30, 0x01 },
-		{ 35, 0x05 },
-		{ 40, 0x02 },
-		{ 45, 0x06 },
-		{ 50, 0x00 },
-		{ 55, 0x04 },
-		{ 60, 0x0b },
-		{ 65, 0x0f },
-		{ 70, 0x09 },
-		{ 75, 0x0d },
-		{ 80, 0x0a },
-		{ 85, 0x26 },
-		{ 90, 0x20 },
-		{ 100, 0x2b },
-		{ 0, 0xff }	/* error or unknown value */
-	};
-
-	/* PIII(-M) FSB settings: see table b1-b of 24547206.pdf */
-	struct {
-		unsigned int value;	/* Front Side Bus speed in MHz */
-		u8 bitmap;		/* power on configuration bits [18: 19]
-					(in MSR 0x2a) */
-	} msr_decode_fsb[] = {
-		{  66, 0x0 },
-		{ 100, 0x2 },
-		{ 133, 0x1 },
-		{   0, 0xff}
-	};
-
-	u32 msr_lo, msr_tmp;
-	int i = 0, j = 0;
-
-	/* read MSR 0x2a - we only need the low 32 bits */
-	rdmsr(MSR_IA32_EBL_CR_POWERON, msr_lo, msr_tmp);
-	dprintk("P3 - MSR_IA32_EBL_CR_POWERON: 0x%x 0x%x\n", msr_lo, msr_tmp);
-	msr_tmp = msr_lo;
-
-	/* decode the FSB */
-	msr_tmp &= 0x00c0000;
-	msr_tmp >>= 18;
-	while (msr_tmp != msr_decode_fsb[i].bitmap) {
-		if (msr_decode_fsb[i].bitmap == 0xff)
-			return 0;
-		i++;
-	}
-
-	/* decode the multiplier */
-	if (processor == SPEEDSTEP_CPU_PIII_C_EARLY) {
-		dprintk("workaround for early PIIIs\n");
-		msr_lo &= 0x03c00000;
-	} else
-		msr_lo &= 0x0bc00000;
-	msr_lo >>= 22;
-	while (msr_lo != msr_decode_mult[j].bitmap) {
-		if (msr_decode_mult[j].bitmap == 0xff)
-			return 0;
-		j++;
-	}
-
-	dprintk("speed is %u\n",
-		(msr_decode_mult[j].ratio * msr_decode_fsb[i].value * 100));
-
-	return msr_decode_mult[j].ratio * msr_decode_fsb[i].value * 100;
-}
-
-
-static unsigned int pentiumM_get_frequency(void)
-{
-	u32 msr_lo, msr_tmp;
-
-	rdmsr(MSR_IA32_EBL_CR_POWERON, msr_lo, msr_tmp);
-	dprintk("PM - MSR_IA32_EBL_CR_POWERON: 0x%x 0x%x\n", msr_lo, msr_tmp);
-
-	/* see table B-2 of 24547212.pdf */
-	if (msr_lo & 0x00040000) {
-		printk(KERN_DEBUG PFX "PM - invalid FSB: 0x%x 0x%x\n",
-				msr_lo, msr_tmp);
-		return 0;
-	}
-
-	msr_tmp = (msr_lo >> 22) & 0x1f;
-	dprintk("bits 22-26 are 0x%x, speed is %u\n",
-			msr_tmp, (msr_tmp * 100 * 1000));
-
-	return msr_tmp * 100 * 1000;
-}
-
-static unsigned int pentium_core_get_frequency(void)
-{
-	u32 fsb = 0;
-	u32 msr_lo, msr_tmp;
-	int ret;
-
-	rdmsr(MSR_FSB_FREQ, msr_lo, msr_tmp);
-	/* see table B-2 of 25366920.pdf */
-	switch (msr_lo & 0x07) {
-	case 5:
-		fsb = 100000;
-		break;
-	case 1:
-		fsb = 133333;
-		break;
-	case 3:
-		fsb = 166667;
-		break;
-	case 2:
-		fsb = 200000;
-		break;
-	case 0:
-		fsb = 266667;
-		break;
-	case 4:
-		fsb = 333333;
-		break;
-	default:
-		printk(KERN_ERR "PCORE - MSR_FSB_FREQ undefined value");
-	}
-
-	rdmsr(MSR_IA32_EBL_CR_POWERON, msr_lo, msr_tmp);
-	dprintk("PCORE - MSR_IA32_EBL_CR_POWERON: 0x%x 0x%x\n",
-			msr_lo, msr_tmp);
-
-	msr_tmp = (msr_lo >> 22) & 0x1f;
-	dprintk("bits 22-26 are 0x%x, speed is %u\n",
-			msr_tmp, (msr_tmp * fsb));
-
-	ret = (msr_tmp * fsb);
-	return ret;
-}
-
-
-static unsigned int pentium4_get_frequency(void)
-{
-	struct cpuinfo_x86 *c = &boot_cpu_data;
-	u32 msr_lo, msr_hi, mult;
-	unsigned int fsb = 0;
-	unsigned int ret;
-	u8 fsb_code;
-
-	/* Pentium 4 Model 0 and 1 do not have the Core Clock Frequency
-	 * to System Bus Frequency Ratio Field in the Processor Frequency
-	 * Configuration Register of the MSR. Therefore the current
-	 * frequency cannot be calculated and has to be measured.
-	 */
-	if (c->x86_model < 2)
-		return cpu_khz;
-
-	rdmsr(0x2c, msr_lo, msr_hi);
-
-	dprintk("P4 - MSR_EBC_FREQUENCY_ID: 0x%x 0x%x\n", msr_lo, msr_hi);
-
-	/* decode the FSB: see IA-32 Intel (C) Architecture Software
-	 * Developer's Manual, Volume 3: System Prgramming Guide,
-	 * revision #12 in Table B-1: MSRs in the Pentium 4 and
-	 * Intel Xeon Processors, on page B-4 and B-5.
-	 */
-	fsb_code = (msr_lo >> 16) & 0x7;
-	switch (fsb_code) {
-	case 0:
-		fsb = 100 * 1000;
-		break;
-	case 1:
-		fsb = 13333 * 10;
-		break;
-	case 2:
-		fsb = 200 * 1000;
-		break;
-	}
-
-	if (!fsb)
-		printk(KERN_DEBUG PFX "couldn't detect FSB speed. "
-				"Please send an e-mail to <linux@brodo.de>\n");
-
-	/* Multiplier. */
-	mult = msr_lo >> 24;
-
-	dprintk("P4 - FSB %u kHz; Multiplier %u; Speed %u kHz\n",
-			fsb, mult, (fsb * mult));
-
-	ret = (fsb * mult);
-	return ret;
-}
-
-
-/* Warning: may get called from smp_call_function_single. */
-unsigned int speedstep_get_frequency(enum speedstep_processor processor)
-{
-	switch (processor) {
-	case SPEEDSTEP_CPU_PCORE:
-		return pentium_core_get_frequency();
-	case SPEEDSTEP_CPU_PM:
-		return pentiumM_get_frequency();
-	case SPEEDSTEP_CPU_P4D:
-	case SPEEDSTEP_CPU_P4M:
-		return pentium4_get_frequency();
-	case SPEEDSTEP_CPU_PIII_T:
-	case SPEEDSTEP_CPU_PIII_C:
-	case SPEEDSTEP_CPU_PIII_C_EARLY:
-		return pentium3_get_frequency(processor);
-	default:
-		return 0;
-	};
-	return 0;
-}
-EXPORT_SYMBOL_GPL(speedstep_get_frequency);
-
-
-/*********************************************************************
- *                 DETECT SPEEDSTEP-CAPABLE PROCESSOR                *
- *********************************************************************/
-
-unsigned int speedstep_detect_processor(void)
-{
-	struct cpuinfo_x86 *c = &cpu_data(0);
-	u32 ebx, msr_lo, msr_hi;
-
-	dprintk("x86: %x, model: %x\n", c->x86, c->x86_model);
-
-	if ((c->x86_vendor != X86_VENDOR_INTEL) ||
-	    ((c->x86 != 6) && (c->x86 != 0xF)))
-		return 0;
-
-	if (c->x86 == 0xF) {
-		/* Intel Mobile Pentium 4-M
-		 * or Intel Mobile Pentium 4 with 533 MHz FSB */
-		if (c->x86_model != 2)
-			return 0;
-
-		ebx = cpuid_ebx(0x00000001);
-		ebx &= 0x000000FF;
-
-		dprintk("ebx value is %x, x86_mask is %x\n", ebx, c->x86_mask);
-
-		switch (c->x86_mask) {
-		case 4:
-			/*
-			 * B-stepping [M-P4-M]
-			 * sample has ebx = 0x0f, production has 0x0e.
-			 */
-			if ((ebx == 0x0e) || (ebx == 0x0f))
-				return SPEEDSTEP_CPU_P4M;
-			break;
-		case 7:
-			/*
-			 * C-stepping [M-P4-M]
-			 * needs to have ebx=0x0e, else it's a celeron:
-			 * cf. 25130917.pdf / page 7, footnote 5 even
-			 * though 25072120.pdf / page 7 doesn't say
-			 * samples are only of B-stepping...
-			 */
-			if (ebx == 0x0e)
-				return SPEEDSTEP_CPU_P4M;
-			break;
-		case 9:
-			/*
-			 * D-stepping [M-P4-M or M-P4/533]
-			 *
-			 * this is totally strange: CPUID 0x0F29 is
-			 * used by M-P4-M, M-P4/533 and(!) Celeron CPUs.
-			 * The latter need to be sorted out as they don't
-			 * support speedstep.
-			 * Celerons with CPUID 0x0F29 may have either
-			 * ebx=0x8 or 0xf -- 25130917.pdf doesn't say anything
-			 * specific.
-			 * M-P4-Ms may have either ebx=0xe or 0xf [see above]
-			 * M-P4/533 have either ebx=0xe or 0xf. [25317607.pdf]
-			 * also, M-P4M HTs have ebx=0x8, too
-			 * For now, they are distinguished by the model_id
-			 * string
-			 */
-			if ((ebx == 0x0e) ||
-				(strstr(c->x86_model_id,
-				    "Mobile Intel(R) Pentium(R) 4") != NULL))
-				return SPEEDSTEP_CPU_P4M;
-			break;
-		default:
-			break;
-		}
-		return 0;
-	}
-
-	switch (c->x86_model) {
-	case 0x0B: /* Intel PIII [Tualatin] */
-		/* cpuid_ebx(1) is 0x04 for desktop PIII,
-		 * 0x06 for mobile PIII-M */
-		ebx = cpuid_ebx(0x00000001);
-		dprintk("ebx is %x\n", ebx);
-
-		ebx &= 0x000000FF;
-
-		if (ebx != 0x06)
-			return 0;
-
-		/* So far all PIII-M processors support SpeedStep. See
-		 * Intel's 24540640.pdf of June 2003
-		 */
-		return SPEEDSTEP_CPU_PIII_T;
-
-	case 0x08: /* Intel PIII [Coppermine] */
-
-		/* all mobile PIII Coppermines have FSB 100 MHz
-		 * ==> sort out a few desktop PIIIs. */
-		rdmsr(MSR_IA32_EBL_CR_POWERON, msr_lo, msr_hi);
-		dprintk("Coppermine: MSR_IA32_EBL_CR_POWERON is 0x%x, 0x%x\n",
-				msr_lo, msr_hi);
-		msr_lo &= 0x00c0000;
-		if (msr_lo != 0x0080000)
-			return 0;
-
-		/*
-		 * If the processor is a mobile version,
-		 * platform ID has bit 50 set
-		 * it has SpeedStep technology if either
-		 * bit 56 or 57 is set
-		 */
-		rdmsr(MSR_IA32_PLATFORM_ID, msr_lo, msr_hi);
-		dprintk("Coppermine: MSR_IA32_PLATFORM ID is 0x%x, 0x%x\n",
-				msr_lo, msr_hi);
-		if ((msr_hi & (1<<18)) &&
-		    (relaxed_check ? 1 : (msr_hi & (3<<24)))) {
-			if (c->x86_mask == 0x01) {
-				dprintk("early PIII version\n");
-				return SPEEDSTEP_CPU_PIII_C_EARLY;
-			} else
-				return SPEEDSTEP_CPU_PIII_C;
-		}
-
-	default:
-		return 0;
-	}
-}
-EXPORT_SYMBOL_GPL(speedstep_detect_processor);
-
-
-/*********************************************************************
- *                     DETECT SPEEDSTEP SPEEDS                       *
- *********************************************************************/
-
-unsigned int speedstep_get_freqs(enum speedstep_processor processor,
-				  unsigned int *low_speed,
-				  unsigned int *high_speed,
-				  unsigned int *transition_latency,
-				  void (*set_state) (unsigned int state))
-{
-	unsigned int prev_speed;
-	unsigned int ret = 0;
-	unsigned long flags;
-	struct timeval tv1, tv2;
-
-	if ((!processor) || (!low_speed) || (!high_speed) || (!set_state))
-		return -EINVAL;
-
-	dprintk("trying to determine both speeds\n");
-
-	/* get current speed */
-	prev_speed = speedstep_get_frequency(processor);
-	if (!prev_speed)
-		return -EIO;
-
-	dprintk("previous speed is %u\n", prev_speed);
-
-	local_irq_save(flags);
-
-	/* switch to low state */
-	set_state(SPEEDSTEP_LOW);
-	*low_speed = speedstep_get_frequency(processor);
-	if (!*low_speed) {
-		ret = -EIO;
-		goto out;
-	}
-
-	dprintk("low speed is %u\n", *low_speed);
-
-	/* start latency measurement */
-	if (transition_latency)
-		do_gettimeofday(&tv1);
-
-	/* switch to high state */
-	set_state(SPEEDSTEP_HIGH);
-
-	/* end latency measurement */
-	if (transition_latency)
-		do_gettimeofday(&tv2);
-
-	*high_speed = speedstep_get_frequency(processor);
-	if (!*high_speed) {
-		ret = -EIO;
-		goto out;
-	}
-
-	dprintk("high speed is %u\n", *high_speed);
-
-	if (*low_speed == *high_speed) {
-		ret = -ENODEV;
-		goto out;
-	}
-
-	/* switch to previous state, if necessary */
-	if (*high_speed != prev_speed)
-		set_state(SPEEDSTEP_LOW);
-
-	if (transition_latency) {
-		*transition_latency = (tv2.tv_sec - tv1.tv_sec) * USEC_PER_SEC +
-			tv2.tv_usec - tv1.tv_usec;
-		dprintk("transition latency is %u uSec\n", *transition_latency);
-
-		/* convert uSec to nSec and add 20% for safety reasons */
-		*transition_latency *= 1200;
-
-		/* check if the latency measurement is too high or too low
-		 * and set it to a safe value (500uSec) in that case
-		 */
-		if (*transition_latency > 10000000 ||
-		    *transition_latency < 50000) {
-			printk(KERN_WARNING PFX "frequency transition "
-					"measured seems out of range (%u "
-					"nSec), falling back to a safe one of"
-					"%u nSec.\n",
-					*transition_latency, 500000);
-			*transition_latency = 500000;
-		}
-	}
-
-out:
-	local_irq_restore(flags);
-	return ret;
-}
-EXPORT_SYMBOL_GPL(speedstep_get_freqs);
-
-#ifdef CONFIG_X86_SPEEDSTEP_RELAXED_CAP_CHECK
-module_param(relaxed_check, int, 0444);
-MODULE_PARM_DESC(relaxed_check,
-		"Don't do all checks for speedstep capability.");
-#endif
-
-MODULE_AUTHOR("Dominik Brodowski <linux@brodo.de>");
-MODULE_DESCRIPTION("Library for Intel SpeedStep 1 or 2 cpufreq drivers.");
-MODULE_LICENSE("GPL");
diff -druN linux-2.6.39-libre/arch/x86/kernel/cpu/cpufreq/speedstep-lib.h linux-3.0-rc7-libre/arch/x86/kernel/cpu/cpufreq/speedstep-lib.h
--- linux-2.6.39-libre/arch/x86/kernel/cpu/cpufreq/speedstep-lib.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/kernel/cpu/cpufreq/speedstep-lib.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,49 +0,0 @@
-/*
- * (C) 2002 - 2003 Dominik Brodowski <linux@brodo.de>
- *
- *  Licensed under the terms of the GNU GPL License version 2.
- *
- *  Library for common functions for Intel SpeedStep v.1 and v.2 support
- *
- *  BIG FAT DISCLAIMER: Work in progress code. Possibly *dangerous*
- */
-
-
-
-/* processors */
-enum speedstep_processor {
-	SPEEDSTEP_CPU_PIII_C_EARLY = 0x00000001,  /* Coppermine core */
-	SPEEDSTEP_CPU_PIII_C	   = 0x00000002,  /* Coppermine core */
-	SPEEDSTEP_CPU_PIII_T	   = 0x00000003,  /* Tualatin core */
-	SPEEDSTEP_CPU_P4M	   = 0x00000004,  /* P4-M  */
-/* the following processors are not speedstep-capable and are not auto-detected
- * in speedstep_detect_processor(). However, their speed can be detected using
- * the speedstep_get_frequency() call. */
-	SPEEDSTEP_CPU_PM	   = 0xFFFFFF03,  /* Pentium M  */
-	SPEEDSTEP_CPU_P4D	   = 0xFFFFFF04,  /* desktop P4  */
-	SPEEDSTEP_CPU_PCORE	   = 0xFFFFFF05,  /* Core */
-};
-
-/* speedstep states -- only two of them */
-
-#define SPEEDSTEP_HIGH	0x00000000
-#define SPEEDSTEP_LOW	0x00000001
-
-
-/* detect a speedstep-capable processor */
-extern enum speedstep_processor speedstep_detect_processor(void);
-
-/* detect the current speed (in khz) of the processor */
-extern unsigned int speedstep_get_frequency(enum speedstep_processor processor);
-
-
-/* detect the low and high speeds of the processor. The callback
- * set_state"'s first argument is either SPEEDSTEP_HIGH or
- * SPEEDSTEP_LOW; the second argument is zero so that no
- * cpufreq_notify_transition calls are initiated.
- */
-extern unsigned int speedstep_get_freqs(enum speedstep_processor processor,
-	unsigned int *low_speed,
-	unsigned int *high_speed,
-	unsigned int *transition_latency,
-	void (*set_state) (unsigned int state));
diff -druN linux-2.6.39-libre/arch/x86/kernel/cpu/cpufreq/speedstep-smi.c linux-3.0-rc7-libre/arch/x86/kernel/cpu/cpufreq/speedstep-smi.c
--- linux-2.6.39-libre/arch/x86/kernel/cpu/cpufreq/speedstep-smi.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/kernel/cpu/cpufreq/speedstep-smi.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,467 +0,0 @@
-/*
- * Intel SpeedStep SMI driver.
- *
- * (C) 2003  Hiroshi Miura <miura@da-cha.org>
- *
- *  Licensed under the terms of the GNU GPL License version 2.
- *
- */
-
-
-/*********************************************************************
- *                        SPEEDSTEP - DEFINITIONS                    *
- *********************************************************************/
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/init.h>
-#include <linux/cpufreq.h>
-#include <linux/delay.h>
-#include <linux/io.h>
-#include <asm/ist.h>
-
-#include "speedstep-lib.h"
-
-/* speedstep system management interface port/command.
- *
- * These parameters are got from IST-SMI BIOS call.
- * If user gives it, these are used.
- *
- */
-static int smi_port;
-static int smi_cmd;
-static unsigned int smi_sig;
-
-/* info about the processor */
-static enum speedstep_processor speedstep_processor;
-
-/*
- * There are only two frequency states for each processor. Values
- * are in kHz for the time being.
- */
-static struct cpufreq_frequency_table speedstep_freqs[] = {
-	{SPEEDSTEP_HIGH,	0},
-	{SPEEDSTEP_LOW,		0},
-	{0,			CPUFREQ_TABLE_END},
-};
-
-#define GET_SPEEDSTEP_OWNER 0
-#define GET_SPEEDSTEP_STATE 1
-#define SET_SPEEDSTEP_STATE 2
-#define GET_SPEEDSTEP_FREQS 4
-
-/* how often shall the SMI call be tried if it failed, e.g. because
- * of DMA activity going on? */
-#define SMI_TRIES 5
-
-#define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, \
-		"speedstep-smi", msg)
-
-/**
- * speedstep_smi_ownership
- */
-static int speedstep_smi_ownership(void)
-{
-	u32 command, result, magic, dummy;
-	u32 function = GET_SPEEDSTEP_OWNER;
-	unsigned char magic_data[] = "Copyright (c) 1999 Intel Corporation";
-
-	command = (smi_sig & 0xffffff00) | (smi_cmd & 0xff);
-	magic = virt_to_phys(magic_data);
-
-	dprintk("trying to obtain ownership with command %x at port %x\n",
-			command, smi_port);
-
-	__asm__ __volatile__(
-		"push %%ebp\n"
-		"out %%al, (%%dx)\n"
-		"pop %%ebp\n"
-		: "=D" (result),
-		  "=a" (dummy), "=b" (dummy), "=c" (dummy), "=d" (dummy),
-		  "=S" (dummy)
-		: "a" (command), "b" (function), "c" (0), "d" (smi_port),
-		  "D" (0), "S" (magic)
-		: "memory"
-	);
-
-	dprintk("result is %x\n", result);
-
-	return result;
-}
-
-/**
- * speedstep_smi_get_freqs - get SpeedStep preferred & current freq.
- * @low: the low frequency value is placed here
- * @high: the high frequency value is placed here
- *
- * Only available on later SpeedStep-enabled systems, returns false results or
- * even hangs [cf. bugme.osdl.org # 1422] on earlier systems. Empirical testing
- * shows that the latter occurs if !(ist_info.event & 0xFFFF).
- */
-static int speedstep_smi_get_freqs(unsigned int *low, unsigned int *high)
-{
-	u32 command, result = 0, edi, high_mhz, low_mhz, dummy;
-	u32 state = 0;
-	u32 function = GET_SPEEDSTEP_FREQS;
-
-	if (!(ist_info.event & 0xFFFF)) {
-		dprintk("bug #1422 -- can't read freqs from BIOS\n");
-		return -ENODEV;
-	}
-
-	command = (smi_sig & 0xffffff00) | (smi_cmd & 0xff);
-
-	dprintk("trying to determine frequencies with command %x at port %x\n",
-			command, smi_port);
-
-	__asm__ __volatile__(
-		"push %%ebp\n"
-		"out %%al, (%%dx)\n"
-		"pop %%ebp"
-		: "=a" (result),
-		  "=b" (high_mhz),
-		  "=c" (low_mhz),
-		  "=d" (state), "=D" (edi), "=S" (dummy)
-		: "a" (command),
-		  "b" (function),
-		  "c" (state),
-		  "d" (smi_port), "S" (0), "D" (0)
-	);
-
-	dprintk("result %x, low_freq %u, high_freq %u\n",
-			result, low_mhz, high_mhz);
-
-	/* abort if results are obviously incorrect... */
-	if ((high_mhz + low_mhz) < 600)
-		return -EINVAL;
-
-	*high = high_mhz * 1000;
-	*low  = low_mhz  * 1000;
-
-	return result;
-}
-
-/**
- * speedstep_get_state - set the SpeedStep state
- * @state: processor frequency state (SPEEDSTEP_LOW or SPEEDSTEP_HIGH)
- *
- */
-static int speedstep_get_state(void)
-{
-	u32 function = GET_SPEEDSTEP_STATE;
-	u32 result, state, edi, command, dummy;
-
-	command = (smi_sig & 0xffffff00) | (smi_cmd & 0xff);
-
-	dprintk("trying to determine current setting with command %x "
-		"at port %x\n", command, smi_port);
-
-	__asm__ __volatile__(
-		"push %%ebp\n"
-		"out %%al, (%%dx)\n"
-		"pop %%ebp\n"
-		: "=a" (result),
-		  "=b" (state), "=D" (edi),
-		  "=c" (dummy), "=d" (dummy), "=S" (dummy)
-		: "a" (command), "b" (function), "c" (0),
-		  "d" (smi_port), "S" (0), "D" (0)
-	);
-
-	dprintk("state is %x, result is %x\n", state, result);
-
-	return state & 1;
-}
-
-
-/**
- * speedstep_set_state - set the SpeedStep state
- * @state: new processor frequency state (SPEEDSTEP_LOW or SPEEDSTEP_HIGH)
- *
- */
-static void speedstep_set_state(unsigned int state)
-{
-	unsigned int result = 0, command, new_state, dummy;
-	unsigned long flags;
-	unsigned int function = SET_SPEEDSTEP_STATE;
-	unsigned int retry = 0;
-
-	if (state > 0x1)
-		return;
-
-	/* Disable IRQs */
-	local_irq_save(flags);
-
-	command = (smi_sig & 0xffffff00) | (smi_cmd & 0xff);
-
-	dprintk("trying to set frequency to state %u "
-		"with command %x at port %x\n",
-		state, command, smi_port);
-
-	do {
-		if (retry) {
-			dprintk("retry %u, previous result %u, waiting...\n",
-					retry, result);
-			mdelay(retry * 50);
-		}
-		retry++;
-		__asm__ __volatile__(
-			"push %%ebp\n"
-			"out %%al, (%%dx)\n"
-			"pop %%ebp"
-			: "=b" (new_state), "=D" (result),
-			  "=c" (dummy), "=a" (dummy),
-			  "=d" (dummy), "=S" (dummy)
-			: "a" (command), "b" (function), "c" (state),
-			  "d" (smi_port), "S" (0), "D" (0)
-			);
-	} while ((new_state != state) && (retry <= SMI_TRIES));
-
-	/* enable IRQs */
-	local_irq_restore(flags);
-
-	if (new_state == state)
-		dprintk("change to %u MHz succeeded after %u tries "
-			"with result %u\n",
-			(speedstep_freqs[new_state].frequency / 1000),
-			retry, result);
-	else
-		printk(KERN_ERR "cpufreq: change to state %u "
-			"failed with new_state %u and result %u\n",
-			state, new_state, result);
-
-	return;
-}
-
-
-/**
- * speedstep_target - set a new CPUFreq policy
- * @policy: new policy
- * @target_freq: new freq
- * @relation:
- *
- * Sets a new CPUFreq policy/freq.
- */
-static int speedstep_target(struct cpufreq_policy *policy,
-			unsigned int target_freq, unsigned int relation)
-{
-	unsigned int newstate = 0;
-	struct cpufreq_freqs freqs;
-
-	if (cpufreq_frequency_table_target(policy, &speedstep_freqs[0],
-				target_freq, relation, &newstate))
-		return -EINVAL;
-
-	freqs.old = speedstep_freqs[speedstep_get_state()].frequency;
-	freqs.new = speedstep_freqs[newstate].frequency;
-	freqs.cpu = 0; /* speedstep.c is UP only driver */
-
-	if (freqs.old == freqs.new)
-		return 0;
-
-	cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
-	speedstep_set_state(newstate);
-	cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
-
-	return 0;
-}
-
-
-/**
- * speedstep_verify - verifies a new CPUFreq policy
- * @policy: new policy
- *
- * Limit must be within speedstep_low_freq and speedstep_high_freq, with
- * at least one border included.
- */
-static int speedstep_verify(struct cpufreq_policy *policy)
-{
-	return cpufreq_frequency_table_verify(policy, &speedstep_freqs[0]);
-}
-
-
-static int speedstep_cpu_init(struct cpufreq_policy *policy)
-{
-	int result;
-	unsigned int speed, state;
-	unsigned int *low, *high;
-
-	/* capability check */
-	if (policy->cpu != 0)
-		return -ENODEV;
-
-	result = speedstep_smi_ownership();
-	if (result) {
-		dprintk("fails in acquiring ownership of a SMI interface.\n");
-		return -EINVAL;
-	}
-
-	/* detect low and high frequency */
-	low = &speedstep_freqs[SPEEDSTEP_LOW].frequency;
-	high = &speedstep_freqs[SPEEDSTEP_HIGH].frequency;
-
-	result = speedstep_smi_get_freqs(low, high);
-	if (result) {
-		/* fall back to speedstep_lib.c dection mechanism:
-		 * try both states out */
-		dprintk("could not detect low and high frequencies "
-				"by SMI call.\n");
-		result = speedstep_get_freqs(speedstep_processor,
-				low, high,
-				NULL,
-				&speedstep_set_state);
-
-		if (result) {
-			dprintk("could not detect two different speeds"
-					" -- aborting.\n");
-			return result;
-		} else
-			dprintk("workaround worked.\n");
-	}
-
-	/* get current speed setting */
-	state = speedstep_get_state();
-	speed = speedstep_freqs[state].frequency;
-
-	dprintk("currently at %s speed setting - %i MHz\n",
-		(speed == speedstep_freqs[SPEEDSTEP_LOW].frequency)
-		? "low" : "high",
-		(speed / 1000));
-
-	/* cpuinfo and default policy values */
-	policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL;
-	policy->cur = speed;
-
-	result = cpufreq_frequency_table_cpuinfo(policy, speedstep_freqs);
-	if (result)
-		return result;
-
-	cpufreq_frequency_table_get_attr(speedstep_freqs, policy->cpu);
-
-	return 0;
-}
-
-static int speedstep_cpu_exit(struct cpufreq_policy *policy)
-{
-	cpufreq_frequency_table_put_attr(policy->cpu);
-	return 0;
-}
-
-static unsigned int speedstep_get(unsigned int cpu)
-{
-	if (cpu)
-		return -ENODEV;
-	return speedstep_get_frequency(speedstep_processor);
-}
-
-
-static int speedstep_resume(struct cpufreq_policy *policy)
-{
-	int result = speedstep_smi_ownership();
-
-	if (result)
-		dprintk("fails in re-acquiring ownership of a SMI interface.\n");
-
-	return result;
-}
-
-static struct freq_attr *speedstep_attr[] = {
-	&cpufreq_freq_attr_scaling_available_freqs,
-	NULL,
-};
-
-static struct cpufreq_driver speedstep_driver = {
-	.name		= "speedstep-smi",
-	.verify		= speedstep_verify,
-	.target		= speedstep_target,
-	.init		= speedstep_cpu_init,
-	.exit		= speedstep_cpu_exit,
-	.get		= speedstep_get,
-	.resume		= speedstep_resume,
-	.owner		= THIS_MODULE,
-	.attr		= speedstep_attr,
-};
-
-/**
- * speedstep_init - initializes the SpeedStep CPUFreq driver
- *
- *   Initializes the SpeedStep support. Returns -ENODEV on unsupported
- * BIOS, -EINVAL on problems during initiatization, and zero on
- * success.
- */
-static int __init speedstep_init(void)
-{
-	speedstep_processor = speedstep_detect_processor();
-
-	switch (speedstep_processor) {
-	case SPEEDSTEP_CPU_PIII_T:
-	case SPEEDSTEP_CPU_PIII_C:
-	case SPEEDSTEP_CPU_PIII_C_EARLY:
-		break;
-	default:
-		speedstep_processor = 0;
-	}
-
-	if (!speedstep_processor) {
-		dprintk("No supported Intel CPU detected.\n");
-		return -ENODEV;
-	}
-
-	dprintk("signature:0x%.8lx, command:0x%.8lx, "
-		"event:0x%.8lx, perf_level:0x%.8lx.\n",
-		ist_info.signature, ist_info.command,
-		ist_info.event, ist_info.perf_level);
-
-	/* Error if no IST-SMI BIOS or no PARM
-		 sig= 'ISGE' aka 'Intel Speedstep Gate E' */
-	if ((ist_info.signature !=  0x47534943) && (
-	    (smi_port == 0) || (smi_cmd == 0)))
-		return -ENODEV;
-
-	if (smi_sig == 1)
-		smi_sig = 0x47534943;
-	else
-		smi_sig = ist_info.signature;
-
-	/* setup smi_port from MODLULE_PARM or BIOS */
-	if ((smi_port > 0xff) || (smi_port < 0))
-		return -EINVAL;
-	else if (smi_port == 0)
-		smi_port = ist_info.command & 0xff;
-
-	if ((smi_cmd > 0xff) || (smi_cmd < 0))
-		return -EINVAL;
-	else if (smi_cmd == 0)
-		smi_cmd = (ist_info.command >> 16) & 0xff;
-
-	return cpufreq_register_driver(&speedstep_driver);
-}
-
-
-/**
- * speedstep_exit - unregisters SpeedStep support
- *
- *   Unregisters SpeedStep support.
- */
-static void __exit speedstep_exit(void)
-{
-	cpufreq_unregister_driver(&speedstep_driver);
-}
-
-module_param(smi_port, int, 0444);
-module_param(smi_cmd,  int, 0444);
-module_param(smi_sig, uint, 0444);
-
-MODULE_PARM_DESC(smi_port, "Override the BIOS-given IST port with this value "
-		"-- Intel's default setting is 0xb2");
-MODULE_PARM_DESC(smi_cmd, "Override the BIOS-given IST command with this value "
-		"-- Intel's default setting is 0x82");
-MODULE_PARM_DESC(smi_sig, "Set to 1 to fake the IST signature when using the "
-		"SMI interface.");
-
-MODULE_AUTHOR("Hiroshi Miura");
-MODULE_DESCRIPTION("Speedstep driver for IST applet SMI interface.");
-MODULE_LICENSE("GPL");
-
-module_init(speedstep_init);
-module_exit(speedstep_exit);
diff -druN linux-2.6.39-libre/arch/x86/kernel/cpu/intel.c linux-3.0-rc7-libre/arch/x86/kernel/cpu/intel.c
--- linux-2.6.39-libre/arch/x86/kernel/cpu/intel.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/kernel/cpu/intel.c	2011-07-11 19:51:52.000000000 -0400
@@ -29,10 +29,10 @@
 
 static void __cpuinit early_init_intel(struct cpuinfo_x86 *c)
 {
+	u64 misc_enable;
+
 	/* Unmask CPUID levels if masked: */
 	if (c->x86 > 6 || (c->x86 == 6 && c->x86_model >= 0xd)) {
-		u64 misc_enable;
-
 		rdmsrl(MSR_IA32_MISC_ENABLE, misc_enable);
 
 		if (misc_enable & MSR_IA32_MISC_ENABLE_LIMIT_CPUID) {
@@ -118,8 +118,6 @@
 	 * (model 2) with the same problem.
 	 */
 	if (c->x86 == 15) {
-		u64 misc_enable;
-
 		rdmsrl(MSR_IA32_MISC_ENABLE, misc_enable);
 
 		if (misc_enable & MSR_IA32_MISC_ENABLE_FAST_STRING) {
@@ -130,6 +128,19 @@
 		}
 	}
 #endif
+
+	/*
+	 * If fast string is not enabled in IA32_MISC_ENABLE for any reason,
+	 * clear the fast string and enhanced fast string CPU capabilities.
+	 */
+	if (c->x86 > 6 || (c->x86 == 6 && c->x86_model >= 0xd)) {
+		rdmsrl(MSR_IA32_MISC_ENABLE, misc_enable);
+		if (!(misc_enable & MSR_IA32_MISC_ENABLE_FAST_STRING)) {
+			printk(KERN_INFO "Disabled fast string operations\n");
+			setup_clear_cpu_cap(X86_FEATURE_REP_GOOD);
+			setup_clear_cpu_cap(X86_FEATURE_ERMS);
+		}
+	}
 }
 
 #ifdef CONFIG_X86_32
@@ -400,12 +411,10 @@
 
 		switch (c->x86_model) {
 		case 5:
-			if (c->x86_mask == 0) {
-				if (l2 == 0)
-					p = "Celeron (Covington)";
-				else if (l2 == 256)
-					p = "Mobile Pentium II (Dixon)";
-			}
+			if (l2 == 0)
+				p = "Celeron (Covington)";
+			else if (l2 == 256)
+				p = "Mobile Pentium II (Dixon)";
 			break;
 
 		case 6:
diff -druN linux-2.6.39-libre/arch/x86/kernel/cpu/intel_cacheinfo.c linux-3.0-rc7-libre/arch/x86/kernel/cpu/intel_cacheinfo.c
--- linux-2.6.39-libre/arch/x86/kernel/cpu/intel_cacheinfo.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/kernel/cpu/intel_cacheinfo.c	2011-07-11 19:51:52.000000000 -0400
@@ -327,7 +327,6 @@
 	l3->subcaches[2] = sc2 = !(val & BIT(8))  + !(val & BIT(9));
 	l3->subcaches[3] = sc3 = !(val & BIT(12)) + !(val & BIT(13));
 
-	l3->indices = (max(max(max(sc0, sc1), sc2), sc3) << 10) - 1;
 	l3->indices = (max(max3(sc0, sc1, sc2), sc3) << 10) - 1;
 }
 
@@ -454,27 +453,16 @@
 {
 	int ret = 0;
 
-#define SUBCACHE_MASK	(3UL << 20)
-#define SUBCACHE_INDEX	0xfff
-
-	/*
-	 * check whether this slot is already used or
-	 * the index is already disabled
-	 */
+	/*  check if @slot is already used or the index is already disabled */
 	ret = amd_get_l3_disable_slot(l3, slot);
 	if (ret >= 0)
 		return -EINVAL;
 
-	/*
-	 * check whether the other slot has disabled the
-	 * same index already
-	 */
-	if (index == amd_get_l3_disable_slot(l3, !slot))
+	if (index > l3->indices)
 		return -EINVAL;
 
-	/* do not allow writes outside of allowed bits */
-	if ((index & ~(SUBCACHE_MASK | SUBCACHE_INDEX)) ||
-	    ((index & SUBCACHE_INDEX) > l3->indices))
+	/* check whether the other slot has disabled the same index already */
+	if (index == amd_get_l3_disable_slot(l3, !slot))
 		return -EINVAL;
 
 	amd_l3_disable_index(l3, cpu, slot, index);
diff -druN linux-2.6.39-libre/arch/x86/kernel/cpu/Makefile linux-3.0-rc7-libre/arch/x86/kernel/cpu/Makefile
--- linux-2.6.39-libre/arch/x86/kernel/cpu/Makefile	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/kernel/cpu/Makefile	2011-07-11 19:51:52.000000000 -0400
@@ -30,7 +30,6 @@
 
 obj-$(CONFIG_X86_MCE)			+= mcheck/
 obj-$(CONFIG_MTRR)			+= mtrr/
-obj-$(CONFIG_CPU_FREQ)			+= cpufreq/
 
 obj-$(CONFIG_X86_LOCAL_APIC)		+= perfctr-watchdog.o
 
diff -druN linux-2.6.39-libre/arch/x86/kernel/cpu/mcheck/mce.c linux-3.0-rc7-libre/arch/x86/kernel/cpu/mcheck/mce.c
--- linux-2.6.39-libre/arch/x86/kernel/cpu/mcheck/mce.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/kernel/cpu/mcheck/mce.c	2011-07-11 19:51:52.000000000 -0400
@@ -105,20 +105,6 @@
 ATOMIC_NOTIFIER_HEAD(x86_mce_decoder_chain);
 EXPORT_SYMBOL_GPL(x86_mce_decoder_chain);
 
-static int default_decode_mce(struct notifier_block *nb, unsigned long val,
-			       void *data)
-{
-	pr_emerg(HW_ERR "No human readable MCE decoding support on this CPU type.\n");
-	pr_emerg(HW_ERR "Run the message through 'mcelog --ascii' to decode.\n");
-
-	return NOTIFY_STOP;
-}
-
-static struct notifier_block mce_dec_nb = {
-	.notifier_call = default_decode_mce,
-	.priority      = -1,
-};
-
 /* MCA banks polled by the period polling timer for corrected events */
 DEFINE_PER_CPU(mce_banks_t, mce_poll_banks) = {
 	[0 ... BITS_TO_LONGS(MAX_NR_BANKS)-1] = ~0UL
@@ -212,6 +198,8 @@
 
 static void print_mce(struct mce *m)
 {
+	int ret = 0;
+
 	pr_emerg(HW_ERR "CPU %d: Machine Check Exception: %Lx Bank %d: %016Lx\n",
 	       m->extcpu, m->mcgstatus, m->bank, m->status);
 
@@ -239,7 +227,11 @@
 	 * Print out human-readable details about the MCE error,
 	 * (if the CPU has an implementation for that)
 	 */
-	atomic_notifier_call_chain(&x86_mce_decoder_chain, 0, m);
+	ret = atomic_notifier_call_chain(&x86_mce_decoder_chain, 0, m);
+	if (ret == NOTIFY_STOP)
+		return;
+
+	pr_emerg_ratelimited(HW_ERR "Run the above through 'mcelog --ascii'\n");
 }
 
 #define PANIC_TIMEOUT 5 /* 5 seconds */
@@ -590,7 +582,6 @@
 		if (!(flags & MCP_DONTLOG) && !mce_dont_log_ce) {
 			mce_log(&m);
 			atomic_notifier_call_chain(&x86_mce_decoder_chain, 0, &m);
-			add_taint(TAINT_MACHINE_CHECK);
 		}
 
 		/*
@@ -1722,8 +1713,6 @@
 
 int __init mcheck_init(void)
 {
-	atomic_notifier_chain_register(&x86_mce_decoder_chain, &mce_dec_nb);
-
 	mcheck_intel_therm_init();
 
 	return 0;
diff -druN linux-2.6.39-libre/arch/x86/kernel/cpu/mcheck/therm_throt.c linux-3.0-rc7-libre/arch/x86/kernel/cpu/mcheck/therm_throt.c
--- linux-2.6.39-libre/arch/x86/kernel/cpu/mcheck/therm_throt.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/kernel/cpu/mcheck/therm_throt.c	2011-07-11 19:51:52.000000000 -0400
@@ -187,8 +187,6 @@
 				this_cpu,
 				level == CORE_LEVEL ? "Core" : "Package",
 				state->count);
-
-		add_taint(TAINT_MACHINE_CHECK);
 		return 1;
 	}
 	if (old_event) {
@@ -355,7 +353,6 @@
 static void intel_thermal_interrupt(void)
 {
 	__u64 msr_val;
-	struct cpuinfo_x86 *c = &cpu_data(smp_processor_id());
 
 	rdmsrl(MSR_IA32_THERM_STATUS, msr_val);
 
@@ -367,19 +364,19 @@
 				CORE_LEVEL) != 0)
 		mce_log_therm_throt_event(CORE_THROTTLED | msr_val);
 
-	if (cpu_has(c, X86_FEATURE_PLN))
+	if (this_cpu_has(X86_FEATURE_PLN))
 		if (therm_throt_process(msr_val & THERM_STATUS_POWER_LIMIT,
 					POWER_LIMIT_EVENT,
 					CORE_LEVEL) != 0)
 			mce_log_therm_throt_event(CORE_POWER_LIMIT | msr_val);
 
-	if (cpu_has(c, X86_FEATURE_PTS)) {
+	if (this_cpu_has(X86_FEATURE_PTS)) {
 		rdmsrl(MSR_IA32_PACKAGE_THERM_STATUS, msr_val);
 		if (therm_throt_process(msr_val & PACKAGE_THERM_STATUS_PROCHOT,
 					THERMAL_THROTTLING_EVENT,
 					PACKAGE_LEVEL) != 0)
 			mce_log_therm_throt_event(PACKAGE_THROTTLED | msr_val);
-		if (cpu_has(c, X86_FEATURE_PLN))
+		if (this_cpu_has(X86_FEATURE_PLN))
 			if (therm_throt_process(msr_val &
 					PACKAGE_THERM_STATUS_POWER_LIMIT,
 					POWER_LIMIT_EVENT,
@@ -393,7 +390,6 @@
 {
 	printk(KERN_ERR "CPU%d: Unexpected LVT thermal interrupt!\n",
 			smp_processor_id());
-	add_taint(TAINT_MACHINE_CHECK);
 }
 
 static void (*smp_thermal_vector)(void) = unexpected_thermal_interrupt;
diff -druN linux-2.6.39-libre/arch/x86/kernel/cpu/perf_event_amd.c linux-3.0-rc7-libre/arch/x86/kernel/cpu/perf_event_amd.c
--- linux-2.6.39-libre/arch/x86/kernel/cpu/perf_event_amd.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/kernel/cpu/perf_event_amd.c	2011-07-11 19:51:52.000000000 -0400
@@ -96,12 +96,14 @@
  */
 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]	= 0x00c2,
-  [PERF_COUNT_HW_BRANCH_MISSES]		= 0x00c3,
+  [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]		= 0x00c2,
+  [PERF_COUNT_HW_BRANCH_MISSES]			= 0x00c3,
+  [PERF_COUNT_HW_STALLED_CYCLES_FRONTEND]	= 0x00d0, /* "Decoder empty" event */
+  [PERF_COUNT_HW_STALLED_CYCLES_BACKEND]	= 0x00d1, /* "Dispatch stalls" event */
 };
 
 static u64 amd_pmu_event_map(int hw_event)
diff -druN linux-2.6.39-libre/arch/x86/kernel/cpu/perf_event.c linux-3.0-rc7-libre/arch/x86/kernel/cpu/perf_event.c
--- linux-2.6.39-libre/arch/x86/kernel/cpu/perf_event.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/kernel/cpu/perf_event.c	2011-07-11 19:51:52.000000000 -0400
@@ -31,6 +31,7 @@
 #include <asm/nmi.h>
 #include <asm/compat.h>
 #include <asm/smp.h>
+#include <asm/alternative.h>
 
 #if 0
 #undef wrmsrl
@@ -363,12 +364,18 @@
 	return new_raw_count;
 }
 
-/* using X86_FEATURE_PERFCTR_CORE to later implement ALTERNATIVE() here */
 static inline int x86_pmu_addr_offset(int index)
 {
-	if (boot_cpu_has(X86_FEATURE_PERFCTR_CORE))
-		return index << 1;
-	return index;
+	int offset;
+
+	/* offset = X86_FEATURE_PERFCTR_CORE ? index << 1 : index */
+	alternative_io(ASM_NOP2,
+		       "shll $1, %%eax",
+		       X86_FEATURE_PERFCTR_CORE,
+		       "=a" (offset),
+		       "a"  (index));
+
+	return offset;
 }
 
 static inline unsigned int x86_pmu_config_addr(int index)
@@ -1766,17 +1773,6 @@
  * callchain support
  */
 
-static void
-backtrace_warning_symbol(void *data, char *msg, unsigned long symbol)
-{
-	/* Ignore warnings */
-}
-
-static void backtrace_warning(void *data, char *msg)
-{
-	/* Ignore warnings */
-}
-
 static int backtrace_stack(void *data, char *name)
 {
 	return 0;
@@ -1790,8 +1786,6 @@
 }
 
 static const struct stacktrace_ops backtrace_ops = {
-	.warning		= backtrace_warning,
-	.warning_symbol		= backtrace_warning_symbol,
 	.stack			= backtrace_stack,
 	.address		= backtrace_address,
 	.walk_stack		= print_context_stack_bp,
diff -druN linux-2.6.39-libre/arch/x86/kernel/cpu/perf_event_intel.c linux-3.0-rc7-libre/arch/x86/kernel/cpu/perf_event_intel.c
--- linux-2.6.39-libre/arch/x86/kernel/cpu/perf_event_intel.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/kernel/cpu/perf_event_intel.c	2011-07-11 19:51:52.000000000 -0400
@@ -36,7 +36,7 @@
   [PERF_COUNT_HW_BUS_CYCLES]		= 0x013c,
 };
 
-static struct event_constraint intel_core_event_constraints[] =
+static struct event_constraint intel_core_event_constraints[] __read_mostly =
 {
 	INTEL_EVENT_CONSTRAINT(0x11, 0x2), /* FP_ASSIST */
 	INTEL_EVENT_CONSTRAINT(0x12, 0x2), /* MUL */
@@ -47,7 +47,7 @@
 	EVENT_CONSTRAINT_END
 };
 
-static struct event_constraint intel_core2_event_constraints[] =
+static struct event_constraint intel_core2_event_constraints[] __read_mostly =
 {
 	FIXED_EVENT_CONSTRAINT(0x00c0, 0), /* INST_RETIRED.ANY */
 	FIXED_EVENT_CONSTRAINT(0x003c, 1), /* CPU_CLK_UNHALTED.CORE */
@@ -70,7 +70,7 @@
 	EVENT_CONSTRAINT_END
 };
 
-static struct event_constraint intel_nehalem_event_constraints[] =
+static struct event_constraint intel_nehalem_event_constraints[] __read_mostly =
 {
 	FIXED_EVENT_CONSTRAINT(0x00c0, 0), /* INST_RETIRED.ANY */
 	FIXED_EVENT_CONSTRAINT(0x003c, 1), /* CPU_CLK_UNHALTED.CORE */
@@ -86,19 +86,19 @@
 	EVENT_CONSTRAINT_END
 };
 
-static struct extra_reg intel_nehalem_extra_regs[] =
+static struct extra_reg intel_nehalem_extra_regs[] __read_mostly =
 {
 	INTEL_EVENT_EXTRA_REG(0xb7, MSR_OFFCORE_RSP_0, 0xffff),
 	EVENT_EXTRA_END
 };
 
-static struct event_constraint intel_nehalem_percore_constraints[] =
+static struct event_constraint intel_nehalem_percore_constraints[] __read_mostly =
 {
 	INTEL_EVENT_CONSTRAINT(0xb7, 0),
 	EVENT_CONSTRAINT_END
 };
 
-static struct event_constraint intel_westmere_event_constraints[] =
+static struct event_constraint intel_westmere_event_constraints[] __read_mostly =
 {
 	FIXED_EVENT_CONSTRAINT(0x00c0, 0), /* INST_RETIRED.ANY */
 	FIXED_EVENT_CONSTRAINT(0x003c, 1), /* CPU_CLK_UNHALTED.CORE */
@@ -110,7 +110,7 @@
 	EVENT_CONSTRAINT_END
 };
 
-static struct event_constraint intel_snb_event_constraints[] =
+static struct event_constraint intel_snb_event_constraints[] __read_mostly =
 {
 	FIXED_EVENT_CONSTRAINT(0x00c0, 0), /* INST_RETIRED.ANY */
 	FIXED_EVENT_CONSTRAINT(0x003c, 1), /* CPU_CLK_UNHALTED.CORE */
@@ -123,21 +123,21 @@
 	EVENT_CONSTRAINT_END
 };
 
-static struct extra_reg intel_westmere_extra_regs[] =
+static struct extra_reg intel_westmere_extra_regs[] __read_mostly =
 {
 	INTEL_EVENT_EXTRA_REG(0xb7, MSR_OFFCORE_RSP_0, 0xffff),
 	INTEL_EVENT_EXTRA_REG(0xbb, MSR_OFFCORE_RSP_1, 0xffff),
 	EVENT_EXTRA_END
 };
 
-static struct event_constraint intel_westmere_percore_constraints[] =
+static struct event_constraint intel_westmere_percore_constraints[] __read_mostly =
 {
 	INTEL_EVENT_CONSTRAINT(0xb7, 0),
 	INTEL_EVENT_CONSTRAINT(0xbb, 0),
 	EVENT_CONSTRAINT_END
 };
 
-static struct event_constraint intel_gen_event_constraints[] =
+static struct event_constraint intel_gen_event_constraints[] __read_mostly =
 {
 	FIXED_EVENT_CONSTRAINT(0x00c0, 0), /* INST_RETIRED.ANY */
 	FIXED_EVENT_CONSTRAINT(0x003c, 1), /* CPU_CLK_UNHALTED.CORE */
@@ -1440,6 +1440,11 @@
 		x86_pmu.enable_all = intel_pmu_nhm_enable_all;
 		x86_pmu.extra_regs = intel_nehalem_extra_regs;
 
+		/* UOPS_ISSUED.STALLED_CYCLES */
+		intel_perfmon_event_map[PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] = 0x180010e;
+		/* UOPS_EXECUTED.CORE_ACTIVE_CYCLES,c=1,i=1 */
+		intel_perfmon_event_map[PERF_COUNT_HW_STALLED_CYCLES_BACKEND] = 0x1803fb1;
+
 		if (ebx & 0x40) {
 			/*
 			 * Erratum AAJ80 detected, we work it around by using
@@ -1480,6 +1485,12 @@
 		x86_pmu.enable_all = intel_pmu_nhm_enable_all;
 		x86_pmu.pebs_constraints = intel_westmere_pebs_event_constraints;
 		x86_pmu.extra_regs = intel_westmere_extra_regs;
+
+		/* UOPS_ISSUED.STALLED_CYCLES */
+		intel_perfmon_event_map[PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] = 0x180010e;
+		/* UOPS_EXECUTED.CORE_ACTIVE_CYCLES,c=1,i=1 */
+		intel_perfmon_event_map[PERF_COUNT_HW_STALLED_CYCLES_BACKEND] = 0x1803fb1;
+
 		pr_cont("Westmere events, ");
 		break;
 
@@ -1491,6 +1502,12 @@
 
 		x86_pmu.event_constraints = intel_snb_event_constraints;
 		x86_pmu.pebs_constraints = intel_snb_pebs_events;
+
+		/* UOPS_ISSUED.ANY,c=1,i=1 to count stall cycles */
+		intel_perfmon_event_map[PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] = 0x180010e;
+		/* UOPS_DISPATCHED.THREAD,c=1,i=1 to count stall cycles*/
+		intel_perfmon_event_map[PERF_COUNT_HW_STALLED_CYCLES_BACKEND] = 0x18001b1;
+
 		pr_cont("SandyBridge events, ");
 		break;
 
diff -druN linux-2.6.39-libre/arch/x86/kernel/cpu/perf_event_p4.c linux-3.0-rc7-libre/arch/x86/kernel/cpu/perf_event_p4.c
--- linux-2.6.39-libre/arch/x86/kernel/cpu/perf_event_p4.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/kernel/cpu/perf_event_p4.c	2011-07-11 19:51:52.000000000 -0400
@@ -468,7 +468,7 @@
 		.opcode		= P4_OPCODE(P4_EVENT_MISPRED_BRANCH_RETIRED),
 		.escr_msr	= { MSR_P4_CRU_ESCR0, MSR_P4_CRU_ESCR1 },
 		.escr_emask	=
-		P4_ESCR_EMASK_BIT(P4_EVENT_MISPRED_BRANCH_RETIRED, NBOGUS),
+			P4_ESCR_EMASK_BIT(P4_EVENT_MISPRED_BRANCH_RETIRED, NBOGUS),
 		.cntr		= { {12, 13, 16}, {14, 15, 17} },
 	},
 	[P4_EVENT_X87_ASSIST] = {
@@ -912,8 +912,7 @@
 	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);
 
@@ -1197,7 +1196,7 @@
 {
 	unsigned int low, high;
 
-	/* If we get stripped -- indexig fails */
+	/* If we get stripped -- indexing fails */
 	BUILD_BUG_ON(ARCH_P4_MAX_CCCR > X86_PMC_MAX_GENERIC);
 
 	rdmsr(MSR_IA32_MISC_ENABLE, low, high);
diff -druN linux-2.6.39-libre/arch/x86/kernel/devicetree.c linux-3.0-rc7-libre/arch/x86/kernel/devicetree.c
--- linux-2.6.39-libre/arch/x86/kernel/devicetree.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/kernel/devicetree.c	2011-07-11 19:51:52.000000000 -0400
@@ -13,6 +13,7 @@
 #include <linux/slab.h>
 #include <linux/pci.h>
 #include <linux/of_pci.h>
+#include <linux/initrd.h>
 
 #include <asm/hpet.h>
 #include <asm/irq_controller.h>
@@ -98,6 +99,16 @@
 	return __alloc_bootmem(size, align, __pa(MAX_DMA_ADDRESS));
 }
 
+#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
+
 void __init add_dtb(u64 data)
 {
 	initial_dtb = data + offsetof(struct setup_data, data);
@@ -369,6 +380,7 @@
 static int ioapic_xlate(struct irq_domain *id, const u32 *intspec, u32 intsize,
 			u32 *out_hwirq, u32 *out_type)
 {
+	struct mp_ioapic_gsi *gsi_cfg;
 	struct io_apic_irq_attr attr;
 	struct of_ioapic_type *it;
 	u32 line, idx, type;
@@ -378,7 +390,8 @@
 
 	line = *intspec;
 	idx = (u32) id->priv;
-	*out_hwirq = line + mp_gsi_routing[idx].gsi_base;
+	gsi_cfg = mp_ioapic_gsi_routing(idx);
+	*out_hwirq = line + gsi_cfg->gsi_base;
 
 	intspec++;
 	type = *intspec;
@@ -407,7 +420,7 @@
 	}
 
 	for (i = 0; i < nr_ioapics; i++) {
-		if (r.start == mp_ioapics[i].apicaddr) {
+		if (r.start == mpc_ioapic_addr(i)) {
 			struct irq_domain *id;
 
 			id = kzalloc(sizeof(*id), GFP_KERNEL);
diff -druN linux-2.6.39-libre/arch/x86/kernel/dumpstack.c linux-3.0-rc7-libre/arch/x86/kernel/dumpstack.c
--- linux-2.6.39-libre/arch/x86/kernel/dumpstack.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/kernel/dumpstack.c	2011-07-11 19:51:52.000000000 -0400
@@ -135,20 +135,6 @@
 }
 EXPORT_SYMBOL_GPL(print_context_stack_bp);
 
-
-static void
-print_trace_warning_symbol(void *data, char *msg, unsigned long symbol)
-{
-	printk(data);
-	print_symbol(msg, symbol);
-	printk("\n");
-}
-
-static void print_trace_warning(void *data, char *msg)
-{
-	printk("%s%s\n", (char *)data, msg);
-}
-
 static int print_trace_stack(void *data, char *name)
 {
 	printk("%s <%s> ", (char *)data, name);
@@ -166,8 +152,6 @@
 }
 
 static const struct stacktrace_ops print_trace_ops = {
-	.warning		= print_trace_warning,
-	.warning_symbol		= print_trace_warning_symbol,
 	.stack			= print_trace_stack,
 	.address		= print_trace_address,
 	.walk_stack		= print_context_stack,
@@ -279,7 +263,6 @@
 	printk("DEBUG_PAGEALLOC");
 #endif
 	printk("\n");
-	sysfs_printk_last_file();
 	if (notify_die(DIE_OOPS, str, regs, err,
 			current->thread.trap_no, SIGSEGV) == NOTIFY_STOP)
 		return 1;
diff -druN linux-2.6.39-libre/arch/x86/kernel/ftrace.c linux-3.0-rc7-libre/arch/x86/kernel/ftrace.c
--- linux-2.6.39-libre/arch/x86/kernel/ftrace.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/kernel/ftrace.c	2011-07-11 19:51:52.000000000 -0400
@@ -123,7 +123,7 @@
 static atomic_t nmi_running = ATOMIC_INIT(0);
 static int mod_code_status;		/* holds return value of text write */
 static void *mod_code_ip;		/* holds the IP to write to */
-static void *mod_code_newcode;		/* holds the text to write to the IP */
+static const void *mod_code_newcode;	/* holds the text to write to the IP */
 
 static unsigned nmi_wait_count;
 static atomic_t nmi_update_count = ATOMIC_INIT(0);
@@ -225,7 +225,7 @@
 }
 
 static int
-do_ftrace_mod_code(unsigned long ip, void *new_code)
+do_ftrace_mod_code(unsigned long ip, const void *new_code)
 {
 	/*
 	 * On x86_64, kernel text mappings are mapped read-only with
@@ -260,14 +260,14 @@
 	return mod_code_status;
 }
 
-static unsigned char *ftrace_nop_replace(void)
+static const unsigned char *ftrace_nop_replace(void)
 {
-	return ideal_nop5;
+	return ideal_nops[NOP_ATOMIC5];
 }
 
 static int
-ftrace_modify_code(unsigned long ip, unsigned char *old_code,
-		   unsigned char *new_code)
+ftrace_modify_code(unsigned long ip, unsigned const char *old_code,
+		   unsigned const char *new_code)
 {
 	unsigned char replaced[MCOUNT_INSN_SIZE];
 
@@ -301,7 +301,7 @@
 int ftrace_make_nop(struct module *mod,
 		    struct dyn_ftrace *rec, unsigned long addr)
 {
-	unsigned char *new, *old;
+	unsigned const char *new, *old;
 	unsigned long ip = rec->ip;
 
 	old = ftrace_call_replace(ip, addr);
@@ -312,7 +312,7 @@
 
 int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
 {
-	unsigned char *new, *old;
+	unsigned const char *new, *old;
 	unsigned long ip = rec->ip;
 
 	old = ftrace_nop_replace();
diff -druN linux-2.6.39-libre/arch/x86/kernel/head32.c linux-3.0-rc7-libre/arch/x86/kernel/head32.c
--- linux-2.6.39-libre/arch/x86/kernel/head32.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/kernel/head32.c	2011-07-11 19:51:52.000000000 -0400
@@ -23,7 +23,6 @@
 static void __init i386_default_early_setup(void)
 {
 	/* Initialize 32bit specific setup functions */
-	x86_init.resources.probe_roms = probe_roms;
 	x86_init.resources.reserve_resources = i386_reserve_resources;
 	x86_init.mpparse.setup_ioapic_ids = setup_ioapic_ids_from_mpc;
 
diff -druN linux-2.6.39-libre/arch/x86/kernel/hpet.c linux-3.0-rc7-libre/arch/x86/kernel/hpet.c
--- linux-2.6.39-libre/arch/x86/kernel/hpet.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/kernel/hpet.c	2011-07-11 19:51:52.000000000 -0400
@@ -217,7 +217,7 @@
 /*
  * Common hpet info
  */
-static unsigned long hpet_period;
+static unsigned long hpet_freq;
 
 static void hpet_legacy_set_mode(enum clock_event_mode mode,
 			  struct clock_event_device *evt);
@@ -232,7 +232,6 @@
 	.features	= CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
 	.set_mode	= hpet_legacy_set_mode,
 	.set_next_event = hpet_legacy_next_event,
-	.shift		= 32,
 	.irq		= 0,
 	.rating		= 50,
 };
@@ -290,28 +289,12 @@
 	hpet_enable_legacy_int();
 
 	/*
-	 * The mult factor is defined as (include/linux/clockchips.h)
-	 *  mult/2^shift = cyc/ns (in contrast to ns/cyc in clocksource.h)
-	 * hpet_period is in units of femtoseconds (per cycle), so
-	 *  mult/2^shift = cyc/ns = 10^6/hpet_period
-	 *  mult = (10^6 * 2^shift)/hpet_period
-	 *  mult = (FSEC_PER_NSEC << hpet_clockevent.shift)/hpet_period
-	 */
-	hpet_clockevent.mult = div_sc((unsigned long) FSEC_PER_NSEC,
-				      hpet_period, hpet_clockevent.shift);
-	/* Calculate the min / max delta */
-	hpet_clockevent.max_delta_ns = clockevent_delta2ns(0x7FFFFFFF,
-							   &hpet_clockevent);
-	/* Setup minimum reprogramming delta. */
-	hpet_clockevent.min_delta_ns = clockevent_delta2ns(HPET_MIN_PROG_DELTA,
-							   &hpet_clockevent);
-
-	/*
 	 * Start hpet with the boot cpu mask and make it
 	 * global after the IO_APIC has been initialized.
 	 */
 	hpet_clockevent.cpumask = cpumask_of(smp_processor_id());
-	clockevents_register_device(&hpet_clockevent);
+	clockevents_config_and_register(&hpet_clockevent, hpet_freq,
+					HPET_MIN_PROG_DELTA, 0x7FFFFFFF);
 	global_clock_event = &hpet_clockevent;
 	printk(KERN_DEBUG "hpet clockevent registered\n");
 }
@@ -549,7 +532,6 @@
 static void init_one_hpet_msi_clockevent(struct hpet_dev *hdev, int cpu)
 {
 	struct clock_event_device *evt = &hdev->evt;
-	uint64_t hpet_freq;
 
 	WARN_ON(cpu != smp_processor_id());
 	if (!(hdev->flags & HPET_DEV_VALID))
@@ -571,24 +553,10 @@
 
 	evt->set_mode = hpet_msi_set_mode;
 	evt->set_next_event = hpet_msi_next_event;
-	evt->shift = 32;
-
-	/*
-	 * The period is a femto seconds value. We need to calculate the
-	 * scaled math multiplication factor for nanosecond to hpet tick
-	 * conversion.
-	 */
-	hpet_freq = FSEC_PER_SEC;
-	do_div(hpet_freq, hpet_period);
-	evt->mult = div_sc((unsigned long) hpet_freq,
-				      NSEC_PER_SEC, evt->shift);
-	/* Calculate the max delta */
-	evt->max_delta_ns = clockevent_delta2ns(0x7FFFFFFF, evt);
-	/* 5 usec minimum reprogramming delta. */
-	evt->min_delta_ns = 5000;
-
 	evt->cpumask = cpumask_of(hdev->cpu);
-	clockevents_register_device(evt);
+
+	clockevents_config_and_register(evt, hpet_freq, HPET_MIN_PROG_DELTA,
+					0x7FFFFFFF);
 }
 
 #ifdef CONFIG_HPET
@@ -792,7 +760,6 @@
 static int hpet_clocksource_register(void)
 {
 	u64 start, now;
-	u64 hpet_freq;
 	cycle_t t1;
 
 	/* Start the counter */
@@ -819,24 +786,7 @@
 		return -ENODEV;
 	}
 
-	/*
-	 * The definition of mult is (include/linux/clocksource.h)
-	 * mult/2^shift = ns/cyc and hpet_period is in units of fsec/cyc
-	 * so we first need to convert hpet_period to ns/cyc units:
-	 *  mult/2^shift = ns/cyc = hpet_period/10^6
-	 *  mult = (hpet_period * 2^shift)/10^6
-	 *  mult = (hpet_period << shift)/FSEC_PER_NSEC
-	 */
-
-	/* Need to convert hpet_period (fsec/cyc) to cyc/sec:
-	 *
-	 * cyc/sec = FSEC_PER_SEC/hpet_period(fsec/cyc)
-	 * cyc/sec = (FSEC_PER_NSEC * NSEC_PER_SEC)/hpet_period
-	 */
-	hpet_freq = FSEC_PER_SEC;
-	do_div(hpet_freq, hpet_period);
 	clocksource_register_hz(&clocksource_hpet, (u32)hpet_freq);
-
 	return 0;
 }
 
@@ -845,7 +795,9 @@
  */
 int __init hpet_enable(void)
 {
+	unsigned long hpet_period;
 	unsigned int id;
+	u64 freq;
 	int i;
 
 	if (!is_hpet_capable())
@@ -884,6 +836,14 @@
 		goto out_nohpet;
 
 	/*
+	 * The period is a femto seconds value. Convert it to a
+	 * frequency.
+	 */
+	freq = FSEC_PER_SEC;
+	do_div(freq, hpet_period);
+	hpet_freq = freq;
+
+	/*
 	 * Read the HPET ID register to retrieve the IRQ routing
 	 * information and the number of channels
 	 */
diff -druN linux-2.6.39-libre/arch/x86/kernel/i8253.c linux-3.0-rc7-libre/arch/x86/kernel/i8253.c
--- linux-2.6.39-libre/arch/x86/kernel/i8253.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/kernel/i8253.c	2011-07-11 19:51:52.000000000 -0400
@@ -93,7 +93,6 @@
 	.features	= CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
 	.set_mode	= init_pit_timer,
 	.set_next_event = pit_next_event,
-	.shift		= 32,
 	.irq		= 0,
 };
 
@@ -108,90 +107,12 @@
 	 * IO_APIC has been initialized.
 	 */
 	pit_ce.cpumask = cpumask_of(smp_processor_id());
-	pit_ce.mult = div_sc(CLOCK_TICK_RATE, NSEC_PER_SEC, pit_ce.shift);
-	pit_ce.max_delta_ns = clockevent_delta2ns(0x7FFF, &pit_ce);
-	pit_ce.min_delta_ns = clockevent_delta2ns(0xF, &pit_ce);
 
-	clockevents_register_device(&pit_ce);
+	clockevents_config_and_register(&pit_ce, CLOCK_TICK_RATE, 0xF, 0x7FFF);
 	global_clock_event = &pit_ce;
 }
 
 #ifndef CONFIG_X86_64
-/*
- * Since the PIT overflows every tick, its not very useful
- * to just read by itself. So use jiffies to emulate a free
- * running counter:
- */
-static cycle_t pit_read(struct clocksource *cs)
-{
-	static int old_count;
-	static u32 old_jifs;
-	unsigned long flags;
-	int count;
-	u32 jifs;
-
-	raw_spin_lock_irqsave(&i8253_lock, flags);
-	/*
-	 * Although our caller may have the read side of xtime_lock,
-	 * this is now a seqlock, and we are cheating in this routine
-	 * by having side effects on state that we cannot undo if
-	 * there is a collision on the seqlock and our caller has to
-	 * retry.  (Namely, old_jifs and old_count.)  So we must treat
-	 * jiffies as volatile despite the lock.  We read jiffies
-	 * before latching the timer count to guarantee that although
-	 * the jiffies value might be older than the count (that is,
-	 * the counter may underflow between the last point where
-	 * jiffies was incremented and the point where we latch the
-	 * count), it cannot be newer.
-	 */
-	jifs = jiffies;
-	outb_pit(0x00, PIT_MODE);	/* latch the count ASAP */
-	count = inb_pit(PIT_CH0);	/* read the latched count */
-	count |= inb_pit(PIT_CH0) << 8;
-
-	/* VIA686a test code... reset the latch if count > max + 1 */
-	if (count > LATCH) {
-		outb_pit(0x34, PIT_MODE);
-		outb_pit(LATCH & 0xff, PIT_CH0);
-		outb_pit(LATCH >> 8, PIT_CH0);
-		count = LATCH - 1;
-	}
-
-	/*
-	 * It's possible for count to appear to go the wrong way for a
-	 * couple of reasons:
-	 *
-	 *  1. The timer counter underflows, but we haven't handled the
-	 *     resulting interrupt and incremented jiffies yet.
-	 *  2. Hardware problem with the timer, not giving us continuous time,
-	 *     the counter does small "jumps" upwards on some Pentium systems,
-	 *     (see c't 95/10 page 335 for Neptun bug.)
-	 *
-	 * Previous attempts to handle these cases intelligently were
-	 * buggy, so we just do the simple thing now.
-	 */
-	if (count > old_count && jifs == old_jifs)
-		count = old_count;
-
-	old_count = count;
-	old_jifs = jifs;
-
-	raw_spin_unlock_irqrestore(&i8253_lock, flags);
-
-	count = (LATCH - 1) - count;
-
-	return (cycle_t)(jifs * LATCH) + count;
-}
-
-static struct clocksource pit_cs = {
-	.name		= "pit",
-	.rating		= 110,
-	.read		= pit_read,
-	.mask		= CLOCKSOURCE_MASK(32),
-	.mult		= 0,
-	.shift		= 20,
-};
-
 static int __init init_pit_clocksource(void)
 {
 	 /*
@@ -205,10 +126,7 @@
 	    pit_ce.mode != CLOCK_EVT_MODE_PERIODIC)
 		return 0;
 
-	pit_cs.mult = clocksource_hz2mult(CLOCK_TICK_RATE, pit_cs.shift);
-
-	return clocksource_register(&pit_cs);
+	return clocksource_i8253_init();
 }
 arch_initcall(init_pit_clocksource);
-
 #endif /* !CONFIG_X86_64 */
diff -druN linux-2.6.39-libre/arch/x86/kernel/irq.c linux-3.0-rc7-libre/arch/x86/kernel/irq.c
--- linux-2.6.39-libre/arch/x86/kernel/irq.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/kernel/irq.c	2011-07-11 19:51:52.000000000 -0400
@@ -249,7 +249,7 @@
 
 		data = irq_desc_get_irq_data(desc);
 		affinity = data->affinity;
-		if (!irq_has_action(irq) ||
+		if (!irq_has_action(irq) || irqd_is_per_cpu(data) ||
 		    cpumask_subset(affinity, cpu_online_mask)) {
 			raw_spin_unlock(&desc->lock);
 			continue;
@@ -276,7 +276,8 @@
 		else if (!(warned++))
 			set_affinity = 0;
 
-		if (!irqd_can_move_in_process_context(data) && chip->irq_unmask)
+		if (!irqd_can_move_in_process_context(data) &&
+		    !irqd_irq_disabled(data) && chip->irq_unmask)
 			chip->irq_unmask(data);
 
 		raw_spin_unlock(&desc->lock);
diff -druN linux-2.6.39-libre/arch/x86/kernel/jump_label.c linux-3.0-rc7-libre/arch/x86/kernel/jump_label.c
--- linux-2.6.39-libre/arch/x86/kernel/jump_label.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/kernel/jump_label.c	2011-07-11 19:51:52.000000000 -0400
@@ -34,7 +34,7 @@
 		code.offset = entry->target -
 				(entry->code + JUMP_LABEL_NOP_SIZE);
 	} else
-		memcpy(&code, ideal_nop5, JUMP_LABEL_NOP_SIZE);
+		memcpy(&code, ideal_nops[NOP_ATOMIC5], JUMP_LABEL_NOP_SIZE);
 	get_online_cpus();
 	mutex_lock(&text_mutex);
 	text_poke_smp((void *)entry->code, &code, JUMP_LABEL_NOP_SIZE);
@@ -44,7 +44,8 @@
 
 void arch_jump_label_text_poke_early(jump_label_t addr)
 {
-	text_poke_early((void *)addr, ideal_nop5, JUMP_LABEL_NOP_SIZE);
+	text_poke_early((void *)addr, ideal_nops[NOP_ATOMIC5],
+			JUMP_LABEL_NOP_SIZE);
 }
 
 #endif
diff -druN linux-2.6.39-libre/arch/x86/kernel/kvmclock.c linux-3.0-rc7-libre/arch/x86/kernel/kvmclock.c
--- linux-2.6.39-libre/arch/x86/kernel/kvmclock.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/kernel/kvmclock.c	2011-07-11 19:51:52.000000000 -0400
@@ -26,8 +26,6 @@
 #include <asm/x86_init.h>
 #include <asm/reboot.h>
 
-#define KVM_SCALE 22
-
 static int kvmclock = 1;
 static int msr_kvm_system_time = MSR_KVM_SYSTEM_TIME;
 static int msr_kvm_wall_clock = MSR_KVM_WALL_CLOCK;
@@ -120,8 +118,6 @@
 	.read = kvm_clock_get_cycles,
 	.rating = 400,
 	.mask = CLOCKSOURCE_MASK(64),
-	.mult = 1 << KVM_SCALE,
-	.shift = KVM_SCALE,
 	.flags = CLOCK_SOURCE_IS_CONTINUOUS,
 };
 
@@ -203,7 +199,7 @@
 	machine_ops.crash_shutdown  = kvm_crash_shutdown;
 #endif
 	kvm_get_preset_lpj();
-	clocksource_register(&kvm_clock);
+	clocksource_register_hz(&kvm_clock, NSEC_PER_SEC);
 	pv_info.paravirt_enabled = 1;
 	pv_info.name = "KVM";
 
diff -druN linux-2.6.39-libre/arch/x86/kernel/Makefile linux-3.0-rc7-libre/arch/x86/kernel/Makefile
--- linux-2.6.39-libre/arch/x86/kernel/Makefile	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/kernel/Makefile	2011-07-11 19:51:52.000000000 -0400
@@ -24,22 +24,26 @@
 nostackp := $(call cc-option, -fno-stack-protector)
 CFLAGS_vsyscall_64.o	:= $(PROFILING) -g0 $(nostackp)
 CFLAGS_hpet.o		:= $(nostackp)
-CFLAGS_tsc.o		:= $(nostackp)
+CFLAGS_vread_tsc_64.o	:= $(nostackp)
 CFLAGS_paravirt.o	:= $(nostackp)
 GCOV_PROFILE_vsyscall_64.o	:= n
 GCOV_PROFILE_hpet.o		:= n
 GCOV_PROFILE_tsc.o		:= n
+GCOV_PROFILE_vread_tsc_64.o	:= n
 GCOV_PROFILE_paravirt.o		:= n
 
+# vread_tsc_64 is hot and should be fully optimized:
+CFLAGS_REMOVE_vread_tsc_64.o = -pg -fno-optimize-sibling-calls
+
 obj-y			:= process_$(BITS).o signal.o entry_$(BITS).o
 obj-y			+= traps.o irq.o irq_$(BITS).o dumpstack_$(BITS).o
 obj-y			+= time.o ioport.o ldt.o dumpstack.o
 obj-y			+= setup.o x86_init.o i8259.o irqinit.o jump_label.o
 obj-$(CONFIG_IRQ_WORK)  += irq_work.o
-obj-$(CONFIG_X86_32)	+= probe_roms_32.o
+obj-y			+= probe_roms.o
 obj-$(CONFIG_X86_32)	+= sys_i386_32.o i386_ksyms_32.o
 obj-$(CONFIG_X86_64)	+= sys_x86_64.o x8664_ksyms_64.o
-obj-$(CONFIG_X86_64)	+= syscall_64.o vsyscall_64.o
+obj-$(CONFIG_X86_64)	+= syscall_64.o vsyscall_64.o vread_tsc_64.o
 obj-y			+= bootflag.o e820.o
 obj-y			+= pci-dma.o quirks.o topology.o kdebugfs.o
 obj-y			+= alternative.o i8253.o pci-nommu.o hw_breakpoint.o
@@ -117,7 +121,7 @@
 ifeq ($(CONFIG_X86_64),y)
 	obj-$(CONFIG_AUDIT)		+= audit_64.o
 
-	obj-$(CONFIG_GART_IOMMU)	+= pci-gart_64.o aperture_64.o
+	obj-$(CONFIG_GART_IOMMU)	+= amd_gart_64.o aperture_64.o
 	obj-$(CONFIG_CALGARY_IOMMU)	+= pci-calgary_64.o tce_64.o
 	obj-$(CONFIG_AMD_IOMMU)		+= amd_iommu_init.o amd_iommu.o
 
diff -druN linux-2.6.39-libre/arch/x86/kernel/module.c linux-3.0-rc7-libre/arch/x86/kernel/module.c
--- linux-2.6.39-libre/arch/x86/kernel/module.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/kernel/module.c	2011-07-11 19:51:52.000000000 -0400
@@ -24,6 +24,7 @@
 #include <linux/bug.h>
 #include <linux/mm.h>
 #include <linux/gfp.h>
+#include <linux/jump_label.h>
 
 #include <asm/system.h>
 #include <asm/page.h>
diff -druN linux-2.6.39-libre/arch/x86/kernel/mpparse.c linux-3.0-rc7-libre/arch/x86/kernel/mpparse.c
--- linux-2.6.39-libre/arch/x86/kernel/mpparse.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/kernel/mpparse.c	2011-07-11 19:51:52.000000000 -0400
@@ -285,7 +285,7 @@
 	intsrc.type = MP_INTSRC;
 	intsrc.irqflag = 0;	/* conforming */
 	intsrc.srcbus = 0;
-	intsrc.dstapic = mp_ioapics[0].apicid;
+	intsrc.dstapic = mpc_ioapic_id(0);
 
 	intsrc.irqtype = mp_INT;
 
@@ -715,17 +715,15 @@
 	}
 }
 
-static int
+static int __init
 check_slot(unsigned long mpc_new_phys, unsigned long mpc_new_length, int count)
 {
-	int ret = 0;
-
 	if (!mpc_new_phys || count <= mpc_new_length) {
 		WARN(1, "update_mptable: No spare slots (length: %x)\n", count);
 		return -1;
 	}
 
-	return ret;
+	return 0;
 }
 #else /* CONFIG_X86_IO_APIC */
 static
diff -druN linux-2.6.39-libre/arch/x86/kernel/pci-dma.c linux-3.0-rc7-libre/arch/x86/kernel/pci-dma.c
--- linux-2.6.39-libre/arch/x86/kernel/pci-dma.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/kernel/pci-dma.c	2011-07-11 19:51:52.000000000 -0400
@@ -68,74 +68,10 @@
 }
 EXPORT_SYMBOL(dma_set_mask);
 
-#if defined(CONFIG_X86_64) && !defined(CONFIG_NUMA)
-static __initdata void *dma32_bootmem_ptr;
-static unsigned long dma32_bootmem_size __initdata = (128ULL<<20);
-
-static int __init parse_dma32_size_opt(char *p)
-{
-	if (!p)
-		return -EINVAL;
-	dma32_bootmem_size = memparse(p, &p);
-	return 0;
-}
-early_param("dma32_size", parse_dma32_size_opt);
-
-void __init dma32_reserve_bootmem(void)
-{
-	unsigned long size, align;
-	if (max_pfn <= MAX_DMA32_PFN)
-		return;
-
-	/*
-	 * check aperture_64.c allocate_aperture() for reason about
-	 * using 512M as goal
-	 */
-	align = 64ULL<<20;
-	size = roundup(dma32_bootmem_size, align);
-	dma32_bootmem_ptr = __alloc_bootmem_nopanic(size, align,
-				 512ULL<<20);
-	/*
-	 * Kmemleak should not scan this block as it may not be mapped via the
-	 * kernel direct mapping.
-	 */
-	kmemleak_ignore(dma32_bootmem_ptr);
-	if (dma32_bootmem_ptr)
-		dma32_bootmem_size = size;
-	else
-		dma32_bootmem_size = 0;
-}
-static void __init dma32_free_bootmem(void)
-{
-
-	if (max_pfn <= MAX_DMA32_PFN)
-		return;
-
-	if (!dma32_bootmem_ptr)
-		return;
-
-	free_bootmem(__pa(dma32_bootmem_ptr), dma32_bootmem_size);
-
-	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)
 {
 	struct iommu_table_entry *p;
 
-	/* free the range so iommu could get some range less than 4G */
-	dma32_free_bootmem();
-
 	sort_iommu_table(__iommu_table, __iommu_table_end);
 	check_iommu_entries(__iommu_table, __iommu_table_end);
 
diff -druN linux-2.6.39-libre/arch/x86/kernel/pci-gart_64.c linux-3.0-rc7-libre/arch/x86/kernel/pci-gart_64.c
--- linux-2.6.39-libre/arch/x86/kernel/pci-gart_64.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/kernel/pci-gart_64.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,898 +0,0 @@
-/*
- * Dynamic DMA mapping support for AMD Hammer.
- *
- * Use the integrated AGP GART in the Hammer northbridge as an IOMMU for PCI.
- * This allows to use PCI devices that only support 32bit addresses on systems
- * with more than 4GB.
- *
- * See Documentation/PCI/PCI-DMA-mapping.txt for the interface specification.
- *
- * Copyright 2002 Andi Kleen, SuSE Labs.
- * Subject to the GNU General Public License v2 only.
- */
-
-#include <linux/types.h>
-#include <linux/ctype.h>
-#include <linux/agp_backend.h>
-#include <linux/init.h>
-#include <linux/mm.h>
-#include <linux/sched.h>
-#include <linux/string.h>
-#include <linux/spinlock.h>
-#include <linux/pci.h>
-#include <linux/module.h>
-#include <linux/topology.h>
-#include <linux/interrupt.h>
-#include <linux/bitmap.h>
-#include <linux/kdebug.h>
-#include <linux/scatterlist.h>
-#include <linux/iommu-helper.h>
-#include <linux/syscore_ops.h>
-#include <linux/io.h>
-#include <linux/gfp.h>
-#include <asm/atomic.h>
-#include <asm/mtrr.h>
-#include <asm/pgtable.h>
-#include <asm/proto.h>
-#include <asm/iommu.h>
-#include <asm/gart.h>
-#include <asm/cacheflush.h>
-#include <asm/swiotlb.h>
-#include <asm/dma.h>
-#include <asm/amd_nb.h>
-#include <asm/x86_init.h>
-#include <asm/iommu_table.h>
-
-static unsigned long iommu_bus_base;	/* GART remapping area (physical) */
-static unsigned long iommu_size;	/* size of remapping area bytes */
-static unsigned long iommu_pages;	/* .. and in pages */
-
-static u32 *iommu_gatt_base;		/* Remapping table */
-
-static dma_addr_t bad_dma_addr;
-
-/*
- * If this is disabled the IOMMU will use an optimized flushing strategy
- * of only flushing when an mapping is reused. With it true the GART is
- * flushed for every mapping. Problem is that doing the lazy flush seems
- * to trigger bugs with some popular PCI cards, in particular 3ware (but
- * has been also also seen with Qlogic at least).
- */
-static int iommu_fullflush = 1;
-
-/* Allocation bitmap for the remapping area: */
-static DEFINE_SPINLOCK(iommu_bitmap_lock);
-/* Guarded by iommu_bitmap_lock: */
-static unsigned long *iommu_gart_bitmap;
-
-static u32 gart_unmapped_entry;
-
-#define GPTE_VALID    1
-#define GPTE_COHERENT 2
-#define GPTE_ENCODE(x) \
-	(((x) & 0xfffff000) | (((x) >> 32) << 4) | GPTE_VALID | GPTE_COHERENT)
-#define GPTE_DECODE(x) (((x) & 0xfffff000) | (((u64)(x) & 0xff0) << 28))
-
-#define EMERGENCY_PAGES 32 /* = 128KB */
-
-#ifdef CONFIG_AGP
-#define AGPEXTERN extern
-#else
-#define AGPEXTERN
-#endif
-
-/* GART can only remap to physical addresses < 1TB */
-#define GART_MAX_PHYS_ADDR	(1ULL << 40)
-
-/* backdoor interface to AGP driver */
-AGPEXTERN int agp_memory_reserved;
-AGPEXTERN __u32 *agp_gatt_table;
-
-static unsigned long next_bit;  /* protected by iommu_bitmap_lock */
-static bool need_flush;		/* global flush state. set for each gart wrap */
-
-static unsigned long alloc_iommu(struct device *dev, int size,
-				 unsigned long align_mask)
-{
-	unsigned long offset, flags;
-	unsigned long boundary_size;
-	unsigned long base_index;
-
-	base_index = ALIGN(iommu_bus_base & dma_get_seg_boundary(dev),
-			   PAGE_SIZE) >> PAGE_SHIFT;
-	boundary_size = ALIGN((u64)dma_get_seg_boundary(dev) + 1,
-			      PAGE_SIZE) >> PAGE_SHIFT;
-
-	spin_lock_irqsave(&iommu_bitmap_lock, flags);
-	offset = iommu_area_alloc(iommu_gart_bitmap, iommu_pages, next_bit,
-				  size, base_index, boundary_size, align_mask);
-	if (offset == -1) {
-		need_flush = true;
-		offset = iommu_area_alloc(iommu_gart_bitmap, iommu_pages, 0,
-					  size, base_index, boundary_size,
-					  align_mask);
-	}
-	if (offset != -1) {
-		next_bit = offset+size;
-		if (next_bit >= iommu_pages) {
-			next_bit = 0;
-			need_flush = true;
-		}
-	}
-	if (iommu_fullflush)
-		need_flush = true;
-	spin_unlock_irqrestore(&iommu_bitmap_lock, flags);
-
-	return offset;
-}
-
-static void free_iommu(unsigned long offset, int size)
-{
-	unsigned long flags;
-
-	spin_lock_irqsave(&iommu_bitmap_lock, flags);
-	bitmap_clear(iommu_gart_bitmap, offset, size);
-	if (offset >= next_bit)
-		next_bit = offset + size;
-	spin_unlock_irqrestore(&iommu_bitmap_lock, flags);
-}
-
-/*
- * Use global flush state to avoid races with multiple flushers.
- */
-static void flush_gart(void)
-{
-	unsigned long flags;
-
-	spin_lock_irqsave(&iommu_bitmap_lock, flags);
-	if (need_flush) {
-		amd_flush_garts();
-		need_flush = false;
-	}
-	spin_unlock_irqrestore(&iommu_bitmap_lock, flags);
-}
-
-#ifdef CONFIG_IOMMU_LEAK
-/* Debugging aid for drivers that don't free their IOMMU tables */
-static int leak_trace;
-static int iommu_leak_pages = 20;
-
-static void dump_leak(void)
-{
-	static int dump;
-
-	if (dump)
-		return;
-	dump = 1;
-
-	show_stack(NULL, NULL);
-	debug_dma_dump_mappings(NULL);
-}
-#endif
-
-static void iommu_full(struct device *dev, size_t size, int dir)
-{
-	/*
-	 * Ran out of IOMMU space for this operation. This is very bad.
-	 * Unfortunately the drivers cannot handle this operation properly.
-	 * Return some non mapped prereserved space in the aperture and
-	 * let the Northbridge deal with it. This will result in garbage
-	 * in the IO operation. When the size exceeds the prereserved space
-	 * memory corruption will occur or random memory will be DMAed
-	 * out. Hopefully no network devices use single mappings that big.
-	 */
-
-	dev_err(dev, "PCI-DMA: Out of IOMMU space for %lu bytes\n", size);
-
-	if (size > PAGE_SIZE*EMERGENCY_PAGES) {
-		if (dir == PCI_DMA_FROMDEVICE || dir == PCI_DMA_BIDIRECTIONAL)
-			panic("PCI-DMA: Memory would be corrupted\n");
-		if (dir == PCI_DMA_TODEVICE || dir == PCI_DMA_BIDIRECTIONAL)
-			panic(KERN_ERR
-				"PCI-DMA: Random memory would be DMAed\n");
-	}
-#ifdef CONFIG_IOMMU_LEAK
-	dump_leak();
-#endif
-}
-
-static inline int
-need_iommu(struct device *dev, unsigned long addr, size_t size)
-{
-	return force_iommu || !dma_capable(dev, addr, size);
-}
-
-static inline int
-nonforced_iommu(struct device *dev, unsigned long addr, size_t size)
-{
-	return !dma_capable(dev, addr, size);
-}
-
-/* Map a single continuous physical area into the IOMMU.
- * Caller needs to check if the iommu is needed and flush.
- */
-static dma_addr_t dma_map_area(struct device *dev, dma_addr_t phys_mem,
-				size_t size, int dir, unsigned long align_mask)
-{
-	unsigned long npages = iommu_num_pages(phys_mem, size, PAGE_SIZE);
-	unsigned long iommu_page;
-	int i;
-
-	if (unlikely(phys_mem + size > GART_MAX_PHYS_ADDR))
-		return bad_dma_addr;
-
-	iommu_page = alloc_iommu(dev, npages, align_mask);
-	if (iommu_page == -1) {
-		if (!nonforced_iommu(dev, phys_mem, size))
-			return phys_mem;
-		if (panic_on_overflow)
-			panic("dma_map_area overflow %lu bytes\n", size);
-		iommu_full(dev, size, dir);
-		return bad_dma_addr;
-	}
-
-	for (i = 0; i < npages; i++) {
-		iommu_gatt_base[iommu_page + i] = GPTE_ENCODE(phys_mem);
-		phys_mem += PAGE_SIZE;
-	}
-	return iommu_bus_base + iommu_page*PAGE_SIZE + (phys_mem & ~PAGE_MASK);
-}
-
-/* Map a single area into the IOMMU */
-static dma_addr_t gart_map_page(struct device *dev, struct page *page,
-				unsigned long offset, size_t size,
-				enum dma_data_direction dir,
-				struct dma_attrs *attrs)
-{
-	unsigned long bus;
-	phys_addr_t paddr = page_to_phys(page) + offset;
-
-	if (!dev)
-		dev = &x86_dma_fallback_dev;
-
-	if (!need_iommu(dev, paddr, size))
-		return paddr;
-
-	bus = dma_map_area(dev, paddr, size, dir, 0);
-	flush_gart();
-
-	return bus;
-}
-
-/*
- * Free a DMA mapping.
- */
-static void gart_unmap_page(struct device *dev, dma_addr_t dma_addr,
-			    size_t size, enum dma_data_direction dir,
-			    struct dma_attrs *attrs)
-{
-	unsigned long iommu_page;
-	int npages;
-	int i;
-
-	if (dma_addr < iommu_bus_base + EMERGENCY_PAGES*PAGE_SIZE ||
-	    dma_addr >= iommu_bus_base + iommu_size)
-		return;
-
-	iommu_page = (dma_addr - iommu_bus_base)>>PAGE_SHIFT;
-	npages = iommu_num_pages(dma_addr, size, PAGE_SIZE);
-	for (i = 0; i < npages; i++) {
-		iommu_gatt_base[iommu_page + i] = gart_unmapped_entry;
-	}
-	free_iommu(iommu_page, npages);
-}
-
-/*
- * Wrapper for pci_unmap_single working with scatterlists.
- */
-static void gart_unmap_sg(struct device *dev, struct scatterlist *sg, int nents,
-			  enum dma_data_direction dir, struct dma_attrs *attrs)
-{
-	struct scatterlist *s;
-	int i;
-
-	for_each_sg(sg, s, nents, i) {
-		if (!s->dma_length || !s->length)
-			break;
-		gart_unmap_page(dev, s->dma_address, s->dma_length, dir, NULL);
-	}
-}
-
-/* Fallback for dma_map_sg in case of overflow */
-static int dma_map_sg_nonforce(struct device *dev, struct scatterlist *sg,
-			       int nents, int dir)
-{
-	struct scatterlist *s;
-	int i;
-
-#ifdef CONFIG_IOMMU_DEBUG
-	pr_debug("dma_map_sg overflow\n");
-#endif
-
-	for_each_sg(sg, s, nents, i) {
-		unsigned long addr = sg_phys(s);
-
-		if (nonforced_iommu(dev, addr, s->length)) {
-			addr = dma_map_area(dev, addr, s->length, dir, 0);
-			if (addr == bad_dma_addr) {
-				if (i > 0)
-					gart_unmap_sg(dev, sg, i, dir, NULL);
-				nents = 0;
-				sg[0].dma_length = 0;
-				break;
-			}
-		}
-		s->dma_address = addr;
-		s->dma_length = s->length;
-	}
-	flush_gart();
-
-	return nents;
-}
-
-/* Map multiple scatterlist entries continuous into the first. */
-static int __dma_map_cont(struct device *dev, struct scatterlist *start,
-			  int nelems, struct scatterlist *sout,
-			  unsigned long pages)
-{
-	unsigned long iommu_start = alloc_iommu(dev, pages, 0);
-	unsigned long iommu_page = iommu_start;
-	struct scatterlist *s;
-	int i;
-
-	if (iommu_start == -1)
-		return -1;
-
-	for_each_sg(start, s, nelems, i) {
-		unsigned long pages, addr;
-		unsigned long phys_addr = s->dma_address;
-
-		BUG_ON(s != start && s->offset);
-		if (s == start) {
-			sout->dma_address = iommu_bus_base;
-			sout->dma_address += iommu_page*PAGE_SIZE + s->offset;
-			sout->dma_length = s->length;
-		} else {
-			sout->dma_length += s->length;
-		}
-
-		addr = phys_addr;
-		pages = iommu_num_pages(s->offset, s->length, PAGE_SIZE);
-		while (pages--) {
-			iommu_gatt_base[iommu_page] = GPTE_ENCODE(addr);
-			addr += PAGE_SIZE;
-			iommu_page++;
-		}
-	}
-	BUG_ON(iommu_page - iommu_start != pages);
-
-	return 0;
-}
-
-static inline int
-dma_map_cont(struct device *dev, struct scatterlist *start, int nelems,
-	     struct scatterlist *sout, unsigned long pages, int need)
-{
-	if (!need) {
-		BUG_ON(nelems != 1);
-		sout->dma_address = start->dma_address;
-		sout->dma_length = start->length;
-		return 0;
-	}
-	return __dma_map_cont(dev, start, nelems, sout, pages);
-}
-
-/*
- * DMA map all entries in a scatterlist.
- * Merge chunks that have page aligned sizes into a continuous mapping.
- */
-static int gart_map_sg(struct device *dev, struct scatterlist *sg, int nents,
-		       enum dma_data_direction dir, struct dma_attrs *attrs)
-{
-	struct scatterlist *s, *ps, *start_sg, *sgmap;
-	int need = 0, nextneed, i, out, start;
-	unsigned long pages = 0;
-	unsigned int seg_size;
-	unsigned int max_seg_size;
-
-	if (nents == 0)
-		return 0;
-
-	if (!dev)
-		dev = &x86_dma_fallback_dev;
-
-	out		= 0;
-	start		= 0;
-	start_sg	= sg;
-	sgmap		= sg;
-	seg_size	= 0;
-	max_seg_size	= dma_get_max_seg_size(dev);
-	ps		= NULL; /* shut up gcc */
-
-	for_each_sg(sg, s, nents, i) {
-		dma_addr_t addr = sg_phys(s);
-
-		s->dma_address = addr;
-		BUG_ON(s->length == 0);
-
-		nextneed = need_iommu(dev, addr, s->length);
-
-		/* Handle the previous not yet processed entries */
-		if (i > start) {
-			/*
-			 * Can only merge when the last chunk ends on a
-			 * page boundary and the new one doesn't have an
-			 * offset.
-			 */
-			if (!iommu_merge || !nextneed || !need || s->offset ||
-			    (s->length + seg_size > max_seg_size) ||
-			    (ps->offset + ps->length) % PAGE_SIZE) {
-				if (dma_map_cont(dev, start_sg, i - start,
-						 sgmap, pages, need) < 0)
-					goto error;
-				out++;
-
-				seg_size	= 0;
-				sgmap		= sg_next(sgmap);
-				pages		= 0;
-				start		= i;
-				start_sg	= s;
-			}
-		}
-
-		seg_size += s->length;
-		need = nextneed;
-		pages += iommu_num_pages(s->offset, s->length, PAGE_SIZE);
-		ps = s;
-	}
-	if (dma_map_cont(dev, start_sg, i - start, sgmap, pages, need) < 0)
-		goto error;
-	out++;
-	flush_gart();
-	if (out < nents) {
-		sgmap = sg_next(sgmap);
-		sgmap->dma_length = 0;
-	}
-	return out;
-
-error:
-	flush_gart();
-	gart_unmap_sg(dev, sg, out, dir, NULL);
-
-	/* When it was forced or merged try again in a dumb way */
-	if (force_iommu || iommu_merge) {
-		out = dma_map_sg_nonforce(dev, sg, nents, dir);
-		if (out > 0)
-			return out;
-	}
-	if (panic_on_overflow)
-		panic("dma_map_sg: overflow on %lu pages\n", pages);
-
-	iommu_full(dev, pages << PAGE_SHIFT, dir);
-	for_each_sg(sg, s, nents, i)
-		s->dma_address = bad_dma_addr;
-	return 0;
-}
-
-/* allocate and map a coherent mapping */
-static void *
-gart_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_addr,
-		    gfp_t flag)
-{
-	dma_addr_t paddr;
-	unsigned long align_mask;
-	struct page *page;
-
-	if (force_iommu && !(flag & GFP_DMA)) {
-		flag &= ~(__GFP_DMA | __GFP_HIGHMEM | __GFP_DMA32);
-		page = alloc_pages(flag | __GFP_ZERO, get_order(size));
-		if (!page)
-			return NULL;
-
-		align_mask = (1UL << get_order(size)) - 1;
-		paddr = dma_map_area(dev, page_to_phys(page), size,
-				     DMA_BIDIRECTIONAL, align_mask);
-
-		flush_gart();
-		if (paddr != bad_dma_addr) {
-			*dma_addr = paddr;
-			return page_address(page);
-		}
-		__free_pages(page, get_order(size));
-	} else
-		return dma_generic_alloc_coherent(dev, size, dma_addr, flag);
-
-	return NULL;
-}
-
-/* free a coherent mapping */
-static void
-gart_free_coherent(struct device *dev, size_t size, void *vaddr,
-		   dma_addr_t dma_addr)
-{
-	gart_unmap_page(dev, dma_addr, size, DMA_BIDIRECTIONAL, NULL);
-	free_pages((unsigned long)vaddr, get_order(size));
-}
-
-static int gart_mapping_error(struct device *dev, dma_addr_t dma_addr)
-{
-	return (dma_addr == bad_dma_addr);
-}
-
-static int no_agp;
-
-static __init unsigned long check_iommu_size(unsigned long aper, u64 aper_size)
-{
-	unsigned long a;
-
-	if (!iommu_size) {
-		iommu_size = aper_size;
-		if (!no_agp)
-			iommu_size /= 2;
-	}
-
-	a = aper + iommu_size;
-	iommu_size -= round_up(a, PMD_PAGE_SIZE) - a;
-
-	if (iommu_size < 64*1024*1024) {
-		pr_warning(
-			"PCI-DMA: Warning: Small IOMMU %luMB."
-			" Consider increasing the AGP aperture in BIOS\n",
-				iommu_size >> 20);
-	}
-
-	return iommu_size;
-}
-
-static __init unsigned read_aperture(struct pci_dev *dev, u32 *size)
-{
-	unsigned aper_size = 0, aper_base_32, aper_order;
-	u64 aper_base;
-
-	pci_read_config_dword(dev, AMD64_GARTAPERTUREBASE, &aper_base_32);
-	pci_read_config_dword(dev, AMD64_GARTAPERTURECTL, &aper_order);
-	aper_order = (aper_order >> 1) & 7;
-
-	aper_base = aper_base_32 & 0x7fff;
-	aper_base <<= 25;
-
-	aper_size = (32 * 1024 * 1024) << aper_order;
-	if (aper_base + aper_size > 0x100000000UL || !aper_size)
-		aper_base = 0;
-
-	*size = aper_size;
-	return aper_base;
-}
-
-static void enable_gart_translations(void)
-{
-	int i;
-
-	if (!amd_nb_has_feature(AMD_NB_GART))
-		return;
-
-	for (i = 0; i < amd_nb_num(); i++) {
-		struct pci_dev *dev = node_to_amd_nb(i)->misc;
-
-		enable_gart_translation(dev, __pa(agp_gatt_table));
-	}
-
-	/* Flush the GART-TLB to remove stale entries */
-	amd_flush_garts();
-}
-
-/*
- * If fix_up_north_bridges is set, the north bridges have to be fixed up on
- * resume in the same way as they are handled in gart_iommu_hole_init().
- */
-static bool fix_up_north_bridges;
-static u32 aperture_order;
-static u32 aperture_alloc;
-
-void set_up_gart_resume(u32 aper_order, u32 aper_alloc)
-{
-	fix_up_north_bridges = true;
-	aperture_order = aper_order;
-	aperture_alloc = aper_alloc;
-}
-
-static void gart_fixup_northbridges(void)
-{
-	int i;
-
-	if (!fix_up_north_bridges)
-		return;
-
-	if (!amd_nb_has_feature(AMD_NB_GART))
-		return;
-
-	pr_info("PCI-DMA: Restoring GART aperture settings\n");
-
-	for (i = 0; i < amd_nb_num(); i++) {
-		struct pci_dev *dev = node_to_amd_nb(i)->misc;
-
-		/*
-		 * Don't enable translations just yet.  That is the next
-		 * step.  Restore the pre-suspend aperture settings.
-		 */
-		gart_set_size_and_enable(dev, aperture_order);
-		pci_write_config_dword(dev, AMD64_GARTAPERTUREBASE, aperture_alloc >> 25);
-	}
-}
-
-static void gart_resume(void)
-{
-	pr_info("PCI-DMA: Resuming GART IOMMU\n");
-
-	gart_fixup_northbridges();
-
-	enable_gart_translations();
-}
-
-static struct syscore_ops gart_syscore_ops = {
-	.resume		= gart_resume,
-
-};
-
-/*
- * Private Northbridge GATT initialization in case we cannot use the
- * AGP driver for some reason.
- */
-static __init int init_amd_gatt(struct agp_kern_info *info)
-{
-	unsigned aper_size, gatt_size, new_aper_size;
-	unsigned aper_base, new_aper_base;
-	struct pci_dev *dev;
-	void *gatt;
-	int i;
-
-	pr_info("PCI-DMA: Disabling AGP.\n");
-
-	aper_size = aper_base = info->aper_size = 0;
-	dev = NULL;
-	for (i = 0; i < amd_nb_num(); i++) {
-		dev = node_to_amd_nb(i)->misc;
-		new_aper_base = read_aperture(dev, &new_aper_size);
-		if (!new_aper_base)
-			goto nommu;
-
-		if (!aper_base) {
-			aper_size = new_aper_size;
-			aper_base = new_aper_base;
-		}
-		if (aper_size != new_aper_size || aper_base != new_aper_base)
-			goto nommu;
-	}
-	if (!aper_base)
-		goto nommu;
-
-	info->aper_base = aper_base;
-	info->aper_size = aper_size >> 20;
-
-	gatt_size = (aper_size >> PAGE_SHIFT) * sizeof(u32);
-	gatt = (void *)__get_free_pages(GFP_KERNEL | __GFP_ZERO,
-					get_order(gatt_size));
-	if (!gatt)
-		panic("Cannot allocate GATT table");
-	if (set_memory_uc((unsigned long)gatt, gatt_size >> PAGE_SHIFT))
-		panic("Could not set GART PTEs to uncacheable pages");
-
-	agp_gatt_table = gatt;
-
-	register_syscore_ops(&gart_syscore_ops);
-
-	flush_gart();
-
-	pr_info("PCI-DMA: aperture base @ %x size %u KB\n",
-	       aper_base, aper_size>>10);
-
-	return 0;
-
- nommu:
-	/* Should not happen anymore */
-	pr_warning("PCI-DMA: More than 4GB of RAM and no IOMMU\n"
-	       "falling back to iommu=soft.\n");
-	return -1;
-}
-
-static struct dma_map_ops gart_dma_ops = {
-	.map_sg				= gart_map_sg,
-	.unmap_sg			= gart_unmap_sg,
-	.map_page			= gart_map_page,
-	.unmap_page			= gart_unmap_page,
-	.alloc_coherent			= gart_alloc_coherent,
-	.free_coherent			= gart_free_coherent,
-	.mapping_error			= gart_mapping_error,
-};
-
-static void gart_iommu_shutdown(void)
-{
-	struct pci_dev *dev;
-	int i;
-
-	/* don't shutdown it if there is AGP installed */
-	if (!no_agp)
-		return;
-
-	if (!amd_nb_has_feature(AMD_NB_GART))
-		return;
-
-	for (i = 0; i < amd_nb_num(); i++) {
-		u32 ctl;
-
-		dev = node_to_amd_nb(i)->misc;
-		pci_read_config_dword(dev, AMD64_GARTAPERTURECTL, &ctl);
-
-		ctl &= ~GARTEN;
-
-		pci_write_config_dword(dev, AMD64_GARTAPERTURECTL, ctl);
-	}
-}
-
-int __init gart_iommu_init(void)
-{
-	struct agp_kern_info info;
-	unsigned long iommu_start;
-	unsigned long aper_base, aper_size;
-	unsigned long start_pfn, end_pfn;
-	unsigned long scratch;
-	long i;
-
-	if (!amd_nb_has_feature(AMD_NB_GART))
-		return 0;
-
-#ifndef CONFIG_AGP_AMD64
-	no_agp = 1;
-#else
-	/* Makefile puts PCI initialization via subsys_initcall first. */
-	/* Add other AMD AGP bridge drivers here */
-	no_agp = no_agp ||
-		(agp_amd64_init() < 0) ||
-		(agp_copy_info(agp_bridge, &info) < 0);
-#endif
-
-	if (no_iommu ||
-	    (!force_iommu && max_pfn <= MAX_DMA32_PFN) ||
-	    !gart_iommu_aperture ||
-	    (no_agp && init_amd_gatt(&info) < 0)) {
-		if (max_pfn > MAX_DMA32_PFN) {
-			pr_warning("More than 4GB of memory but GART IOMMU not available.\n");
-			pr_warning("falling back to iommu=soft.\n");
-		}
-		return 0;
-	}
-
-	/* need to map that range */
-	aper_size	= info.aper_size << 20;
-	aper_base	= info.aper_base;
-	end_pfn		= (aper_base>>PAGE_SHIFT) + (aper_size>>PAGE_SHIFT);
-
-	if (end_pfn > max_low_pfn_mapped) {
-		start_pfn = (aper_base>>PAGE_SHIFT);
-		init_memory_mapping(start_pfn<<PAGE_SHIFT, end_pfn<<PAGE_SHIFT);
-	}
-
-	pr_info("PCI-DMA: using GART IOMMU.\n");
-	iommu_size = check_iommu_size(info.aper_base, aper_size);
-	iommu_pages = iommu_size >> PAGE_SHIFT;
-
-	iommu_gart_bitmap = (void *) __get_free_pages(GFP_KERNEL | __GFP_ZERO,
-						      get_order(iommu_pages/8));
-	if (!iommu_gart_bitmap)
-		panic("Cannot allocate iommu bitmap\n");
-
-#ifdef CONFIG_IOMMU_LEAK
-	if (leak_trace) {
-		int ret;
-
-		ret = dma_debug_resize_entries(iommu_pages);
-		if (ret)
-			pr_debug("PCI-DMA: Cannot trace all the entries\n");
-	}
-#endif
-
-	/*
-	 * Out of IOMMU space handling.
-	 * Reserve some invalid pages at the beginning of the GART.
-	 */
-	bitmap_set(iommu_gart_bitmap, 0, EMERGENCY_PAGES);
-
-	pr_info("PCI-DMA: Reserving %luMB of IOMMU area in the AGP aperture\n",
-	       iommu_size >> 20);
-
-	agp_memory_reserved	= iommu_size;
-	iommu_start		= aper_size - iommu_size;
-	iommu_bus_base		= info.aper_base + iommu_start;
-	bad_dma_addr		= iommu_bus_base;
-	iommu_gatt_base		= agp_gatt_table + (iommu_start>>PAGE_SHIFT);
-
-	/*
-	 * Unmap the IOMMU part of the GART. The alias of the page is
-	 * always mapped with cache enabled and there is no full cache
-	 * coherency across the GART remapping. The unmapping avoids
-	 * automatic prefetches from the CPU allocating cache lines in
-	 * there. All CPU accesses are done via the direct mapping to
-	 * the backing memory. The GART address is only used by PCI
-	 * devices.
-	 */
-	set_memory_np((unsigned long)__va(iommu_bus_base),
-				iommu_size >> PAGE_SHIFT);
-	/*
-	 * Tricky. The GART table remaps the physical memory range,
-	 * so the CPU wont notice potential aliases and if the memory
-	 * is remapped to UC later on, we might surprise the PCI devices
-	 * with a stray writeout of a cacheline. So play it sure and
-	 * do an explicit, full-scale wbinvd() _after_ having marked all
-	 * the pages as Not-Present:
-	 */
-	wbinvd();
-
-	/*
-	 * Now all caches are flushed and we can safely enable
-	 * GART hardware.  Doing it early leaves the possibility
-	 * of stale cache entries that can lead to GART PTE
-	 * errors.
-	 */
-	enable_gart_translations();
-
-	/*
-	 * Try to workaround a bug (thanks to BenH):
-	 * Set unmapped entries to a scratch page instead of 0.
-	 * Any prefetches that hit unmapped entries won't get an bus abort
-	 * then. (P2P bridge may be prefetching on DMA reads).
-	 */
-	scratch = get_zeroed_page(GFP_KERNEL);
-	if (!scratch)
-		panic("Cannot allocate iommu scratch page");
-	gart_unmapped_entry = GPTE_ENCODE(__pa(scratch));
-	for (i = EMERGENCY_PAGES; i < iommu_pages; i++)
-		iommu_gatt_base[i] = gart_unmapped_entry;
-
-	flush_gart();
-	dma_ops = &gart_dma_ops;
-	x86_platform.iommu_shutdown = gart_iommu_shutdown;
-	swiotlb = 0;
-
-	return 0;
-}
-
-void __init gart_parse_options(char *p)
-{
-	int arg;
-
-#ifdef CONFIG_IOMMU_LEAK
-	if (!strncmp(p, "leak", 4)) {
-		leak_trace = 1;
-		p += 4;
-		if (*p == '=')
-			++p;
-		if (isdigit(*p) && get_option(&p, &arg))
-			iommu_leak_pages = arg;
-	}
-#endif
-	if (isdigit(*p) && get_option(&p, &arg))
-		iommu_size = arg;
-	if (!strncmp(p, "fullflush", 9))
-		iommu_fullflush = 1;
-	if (!strncmp(p, "nofullflush", 11))
-		iommu_fullflush = 0;
-	if (!strncmp(p, "noagp", 5))
-		no_agp = 1;
-	if (!strncmp(p, "noaperture", 10))
-		fix_aperture = 0;
-	/* duplicated from pci-dma.c */
-	if (!strncmp(p, "force", 5))
-		gart_iommu_aperture_allowed = 1;
-	if (!strncmp(p, "allowed", 7))
-		gart_iommu_aperture_allowed = 1;
-	if (!strncmp(p, "memaper", 7)) {
-		fallback_aper_force = 1;
-		p += 7;
-		if (*p == '=') {
-			++p;
-			if (get_option(&p, &arg))
-				fallback_aper_order = arg;
-		}
-	}
-}
-IOMMU_INIT_POST(gart_iommu_hole_init);
diff -druN linux-2.6.39-libre/arch/x86/kernel/pci-iommu_table.c linux-3.0-rc7-libre/arch/x86/kernel/pci-iommu_table.c
--- linux-2.6.39-libre/arch/x86/kernel/pci-iommu_table.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/kernel/pci-iommu_table.c	2011-07-11 19:51:52.000000000 -0400
@@ -50,20 +50,14 @@
 				struct iommu_table_entry *finish)
 {
 	struct iommu_table_entry *p, *q, *x;
-	char sym_p[KSYM_SYMBOL_LEN];
-	char sym_q[KSYM_SYMBOL_LEN];
 
 	/* Simple cyclic dependency checker. */
 	for (p = start; p < finish; p++) {
 		q = find_dependents_of(start, finish, p);
 		x = find_dependents_of(start, finish, q);
 		if (p == x) {
-			sprint_symbol(sym_p, (unsigned long)p->detect);
-			sprint_symbol(sym_q, (unsigned long)q->detect);
-
-			printk(KERN_ERR "CYCLIC DEPENDENCY FOUND! %s depends" \
-					" on %s and vice-versa. BREAKING IT.\n",
-					sym_p, sym_q);
+			printk(KERN_ERR "CYCLIC DEPENDENCY FOUND! %pS depends on %pS and vice-versa. BREAKING IT.\n",
+			       p->detect, q->detect);
 			/* Heavy handed way..*/
 			x->depend = 0;
 		}
@@ -72,12 +66,8 @@
 	for (p = start; p < finish; p++) {
 		q = find_dependents_of(p, finish, p);
 		if (q && q > p) {
-			sprint_symbol(sym_p, (unsigned long)p->detect);
-			sprint_symbol(sym_q, (unsigned long)q->detect);
-
-			printk(KERN_ERR "EXECUTION ORDER INVALID! %s "\
-					"should be called before %s!\n",
-					sym_p, sym_q);
+			printk(KERN_ERR "EXECUTION ORDER INVALID! %pS should be called before %pS!\n",
+			       p->detect, q->detect);
 		}
 	}
 }
diff -druN linux-2.6.39-libre/arch/x86/kernel/probe_roms_32.c linux-3.0-rc7-libre/arch/x86/kernel/probe_roms_32.c
--- linux-2.6.39-libre/arch/x86/kernel/probe_roms_32.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/kernel/probe_roms_32.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,166 +0,0 @@
-#include <linux/sched.h>
-#include <linux/mm.h>
-#include <linux/uaccess.h>
-#include <linux/mmzone.h>
-#include <linux/ioport.h>
-#include <linux/seq_file.h>
-#include <linux/console.h>
-#include <linux/init.h>
-#include <linux/edd.h>
-#include <linux/dmi.h>
-#include <linux/pfn.h>
-#include <linux/pci.h>
-#include <asm/pci-direct.h>
-
-
-#include <asm/e820.h>
-#include <asm/mmzone.h>
-#include <asm/setup.h>
-#include <asm/sections.h>
-#include <asm/io.h>
-#include <asm/setup_arch.h>
-
-static struct resource system_rom_resource = {
-	.name	= "System ROM",
-	.start	= 0xf0000,
-	.end	= 0xfffff,
-	.flags	= IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM
-};
-
-static struct resource extension_rom_resource = {
-	.name	= "Extension ROM",
-	.start	= 0xe0000,
-	.end	= 0xeffff,
-	.flags	= IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM
-};
-
-static struct resource adapter_rom_resources[] = { {
-	.name 	= "Adapter ROM",
-	.start	= 0xc8000,
-	.end	= 0,
-	.flags	= IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM
-}, {
-	.name 	= "Adapter ROM",
-	.start	= 0,
-	.end	= 0,
-	.flags	= IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM
-}, {
-	.name 	= "Adapter ROM",
-	.start	= 0,
-	.end	= 0,
-	.flags	= IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM
-}, {
-	.name 	= "Adapter ROM",
-	.start	= 0,
-	.end	= 0,
-	.flags	= IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM
-}, {
-	.name 	= "Adapter ROM",
-	.start	= 0,
-	.end	= 0,
-	.flags	= IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM
-}, {
-	.name 	= "Adapter ROM",
-	.start	= 0,
-	.end	= 0,
-	.flags	= IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM
-} };
-
-static struct resource video_rom_resource = {
-	.name 	= "Video ROM",
-	.start	= 0xc0000,
-	.end	= 0xc7fff,
-	.flags	= IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM
-};
-
-#define ROMSIGNATURE 0xaa55
-
-static int __init romsignature(const unsigned char *rom)
-{
-	const unsigned short * const ptr = (const unsigned short *)rom;
-	unsigned short sig;
-
-	return probe_kernel_address(ptr, sig) == 0 && sig == ROMSIGNATURE;
-}
-
-static int __init romchecksum(const unsigned char *rom, unsigned long length)
-{
-	unsigned char sum, c;
-
-	for (sum = 0; length && probe_kernel_address(rom++, c) == 0; length--)
-		sum += c;
-	return !length && !sum;
-}
-
-void __init probe_roms(void)
-{
-	const unsigned char *rom;
-	unsigned long start, length, upper;
-	unsigned char c;
-	int i;
-
-	/* video rom */
-	upper = adapter_rom_resources[0].start;
-	for (start = video_rom_resource.start; start < upper; start += 2048) {
-		rom = isa_bus_to_virt(start);
-		if (!romsignature(rom))
-			continue;
-
-		video_rom_resource.start = start;
-
-		if (probe_kernel_address(rom + 2, c) != 0)
-			continue;
-
-		/* 0 < length <= 0x7f * 512, historically */
-		length = c * 512;
-
-		/* if checksum okay, trust length byte */
-		if (length && romchecksum(rom, length))
-			video_rom_resource.end = start + length - 1;
-
-		request_resource(&iomem_resource, &video_rom_resource);
-		break;
-	}
-
-	start = (video_rom_resource.end + 1 + 2047) & ~2047UL;
-	if (start < upper)
-		start = upper;
-
-	/* system rom */
-	request_resource(&iomem_resource, &system_rom_resource);
-	upper = system_rom_resource.start;
-
-	/* check for extension rom (ignore length byte!) */
-	rom = isa_bus_to_virt(extension_rom_resource.start);
-	if (romsignature(rom)) {
-		length = extension_rom_resource.end - extension_rom_resource.start + 1;
-		if (romchecksum(rom, length)) {
-			request_resource(&iomem_resource, &extension_rom_resource);
-			upper = extension_rom_resource.start;
-		}
-	}
-
-	/* check for adapter roms on 2k boundaries */
-	for (i = 0; i < ARRAY_SIZE(adapter_rom_resources) && start < upper; start += 2048) {
-		rom = isa_bus_to_virt(start);
-		if (!romsignature(rom))
-			continue;
-
-		if (probe_kernel_address(rom + 2, c) != 0)
-			continue;
-
-		/* 0 < length <= 0x7f * 512, historically */
-		length = c * 512;
-
-		/* but accept any length that fits if checksum okay */
-		if (!length || start + length > upper || !romchecksum(rom, length))
-			continue;
-
-		adapter_rom_resources[i].start = start;
-		adapter_rom_resources[i].end = start + length - 1;
-		request_resource(&iomem_resource, &adapter_rom_resources[i]);
-
-		start = adapter_rom_resources[i++].end & ~2047UL;
-	}
-}
-
diff -druN linux-2.6.39-libre/arch/x86/kernel/probe_roms.c linux-3.0-rc7-libre/arch/x86/kernel/probe_roms.c
--- linux-2.6.39-libre/arch/x86/kernel/probe_roms.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/x86/kernel/probe_roms.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,267 @@
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/uaccess.h>
+#include <linux/mmzone.h>
+#include <linux/ioport.h>
+#include <linux/seq_file.h>
+#include <linux/console.h>
+#include <linux/init.h>
+#include <linux/edd.h>
+#include <linux/dmi.h>
+#include <linux/pfn.h>
+#include <linux/pci.h>
+#include <asm/pci-direct.h>
+
+
+#include <asm/e820.h>
+#include <asm/mmzone.h>
+#include <asm/setup.h>
+#include <asm/sections.h>
+#include <asm/io.h>
+#include <asm/setup_arch.h>
+
+static struct resource system_rom_resource = {
+	.name	= "System ROM",
+	.start	= 0xf0000,
+	.end	= 0xfffff,
+	.flags	= IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM
+};
+
+static struct resource extension_rom_resource = {
+	.name	= "Extension ROM",
+	.start	= 0xe0000,
+	.end	= 0xeffff,
+	.flags	= IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM
+};
+
+static struct resource adapter_rom_resources[] = { {
+	.name 	= "Adapter ROM",
+	.start	= 0xc8000,
+	.end	= 0,
+	.flags	= IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM
+}, {
+	.name 	= "Adapter ROM",
+	.start	= 0,
+	.end	= 0,
+	.flags	= IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM
+}, {
+	.name 	= "Adapter ROM",
+	.start	= 0,
+	.end	= 0,
+	.flags	= IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM
+}, {
+	.name 	= "Adapter ROM",
+	.start	= 0,
+	.end	= 0,
+	.flags	= IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM
+}, {
+	.name 	= "Adapter ROM",
+	.start	= 0,
+	.end	= 0,
+	.flags	= IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM
+}, {
+	.name 	= "Adapter ROM",
+	.start	= 0,
+	.end	= 0,
+	.flags	= IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM
+} };
+
+static struct resource video_rom_resource = {
+	.name 	= "Video ROM",
+	.start	= 0xc0000,
+	.end	= 0xc7fff,
+	.flags	= IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM
+};
+
+/* does this oprom support the given pci device, or any of the devices
+ * that the driver supports?
+ */
+static bool match_id(struct pci_dev *pdev, unsigned short vendor, unsigned short device)
+{
+	struct pci_driver *drv = pdev->driver;
+	const struct pci_device_id *id;
+
+	if (pdev->vendor == vendor && pdev->device == device)
+		return true;
+
+	for (id = drv ? drv->id_table : NULL; id && id->vendor; id++)
+		if (id->vendor == vendor && id->device == device)
+			break;
+
+	return id && id->vendor;
+}
+
+static bool probe_list(struct pci_dev *pdev, unsigned short vendor,
+		       const unsigned char *rom_list)
+{
+	unsigned short device;
+
+	do {
+		if (probe_kernel_address(rom_list, device) != 0)
+			device = 0;
+
+		if (device && match_id(pdev, vendor, device))
+			break;
+
+		rom_list += 2;
+	} while (device);
+
+	return !!device;
+}
+
+static struct resource *find_oprom(struct pci_dev *pdev)
+{
+	struct resource *oprom = NULL;
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(adapter_rom_resources); i++) {
+		struct resource *res = &adapter_rom_resources[i];
+		unsigned short offset, vendor, device, list, rev;
+		const unsigned char *rom;
+
+		if (res->end == 0)
+			break;
+
+		rom = isa_bus_to_virt(res->start);
+		if (probe_kernel_address(rom + 0x18, offset) != 0)
+			continue;
+
+		if (probe_kernel_address(rom + offset + 0x4, vendor) != 0)
+			continue;
+
+		if (probe_kernel_address(rom + offset + 0x6, device) != 0)
+			continue;
+
+		if (match_id(pdev, vendor, device)) {
+			oprom = res;
+			break;
+		}
+
+		if (probe_kernel_address(rom + offset + 0x8, list) == 0 &&
+		    probe_kernel_address(rom + offset + 0xc, rev) == 0 &&
+		    rev >= 3 && list &&
+		    probe_list(pdev, vendor, rom + offset + list)) {
+			oprom = res;
+			break;
+		}
+	}
+
+	return oprom;
+}
+
+void *pci_map_biosrom(struct pci_dev *pdev)
+{
+	struct resource *oprom = find_oprom(pdev);
+
+	if (!oprom)
+		return NULL;
+
+	return ioremap(oprom->start, resource_size(oprom));
+}
+EXPORT_SYMBOL(pci_map_biosrom);
+
+void pci_unmap_biosrom(void __iomem *image)
+{
+	iounmap(image);
+}
+EXPORT_SYMBOL(pci_unmap_biosrom);
+
+size_t pci_biosrom_size(struct pci_dev *pdev)
+{
+	struct resource *oprom = find_oprom(pdev);
+
+	return oprom ? resource_size(oprom) : 0;
+}
+EXPORT_SYMBOL(pci_biosrom_size);
+
+#define ROMSIGNATURE 0xaa55
+
+static int __init romsignature(const unsigned char *rom)
+{
+	const unsigned short * const ptr = (const unsigned short *)rom;
+	unsigned short sig;
+
+	return probe_kernel_address(ptr, sig) == 0 && sig == ROMSIGNATURE;
+}
+
+static int __init romchecksum(const unsigned char *rom, unsigned long length)
+{
+	unsigned char sum, c;
+
+	for (sum = 0; length && probe_kernel_address(rom++, c) == 0; length--)
+		sum += c;
+	return !length && !sum;
+}
+
+void __init probe_roms(void)
+{
+	const unsigned char *rom;
+	unsigned long start, length, upper;
+	unsigned char c;
+	int i;
+
+	/* video rom */
+	upper = adapter_rom_resources[0].start;
+	for (start = video_rom_resource.start; start < upper; start += 2048) {
+		rom = isa_bus_to_virt(start);
+		if (!romsignature(rom))
+			continue;
+
+		video_rom_resource.start = start;
+
+		if (probe_kernel_address(rom + 2, c) != 0)
+			continue;
+
+		/* 0 < length <= 0x7f * 512, historically */
+		length = c * 512;
+
+		/* if checksum okay, trust length byte */
+		if (length && romchecksum(rom, length))
+			video_rom_resource.end = start + length - 1;
+
+		request_resource(&iomem_resource, &video_rom_resource);
+		break;
+	}
+
+	start = (video_rom_resource.end + 1 + 2047) & ~2047UL;
+	if (start < upper)
+		start = upper;
+
+	/* system rom */
+	request_resource(&iomem_resource, &system_rom_resource);
+	upper = system_rom_resource.start;
+
+	/* check for extension rom (ignore length byte!) */
+	rom = isa_bus_to_virt(extension_rom_resource.start);
+	if (romsignature(rom)) {
+		length = extension_rom_resource.end - extension_rom_resource.start + 1;
+		if (romchecksum(rom, length)) {
+			request_resource(&iomem_resource, &extension_rom_resource);
+			upper = extension_rom_resource.start;
+		}
+	}
+
+	/* check for adapter roms on 2k boundaries */
+	for (i = 0; i < ARRAY_SIZE(adapter_rom_resources) && start < upper; start += 2048) {
+		rom = isa_bus_to_virt(start);
+		if (!romsignature(rom))
+			continue;
+
+		if (probe_kernel_address(rom + 2, c) != 0)
+			continue;
+
+		/* 0 < length <= 0x7f * 512, historically */
+		length = c * 512;
+
+		/* but accept any length that fits if checksum okay */
+		if (!length || start + length > upper || !romchecksum(rom, length))
+			continue;
+
+		adapter_rom_resources[i].start = start;
+		adapter_rom_resources[i].end = start + length - 1;
+		request_resource(&iomem_resource, &adapter_rom_resources[i]);
+
+		start = adapter_rom_resources[i++].end & ~2047UL;
+	}
+}
+
diff -druN linux-2.6.39-libre/arch/x86/kernel/process_32.c linux-3.0-rc7-libre/arch/x86/kernel/process_32.c
--- linux-2.6.39-libre/arch/x86/kernel/process_32.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/kernel/process_32.c	2011-07-11 19:51:52.000000000 -0400
@@ -245,7 +245,6 @@
 {
 	set_user_gs(regs, 0);
 	regs->fs		= 0;
-	set_fs(USER_DS);
 	regs->ds		= __USER_DS;
 	regs->es		= __USER_DS;
 	regs->ss		= __USER_DS;
diff -druN linux-2.6.39-libre/arch/x86/kernel/process_64.c linux-3.0-rc7-libre/arch/x86/kernel/process_64.c
--- linux-2.6.39-libre/arch/x86/kernel/process_64.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/kernel/process_64.c	2011-07-11 19:51:52.000000000 -0400
@@ -338,7 +338,6 @@
 	regs->cs		= _cs;
 	regs->ss		= _ss;
 	regs->flags		= X86_EFLAGS_IF;
-	set_fs(USER_DS);
 	/*
 	 * Free the old FP and other extended state
 	 */
diff -druN linux-2.6.39-libre/arch/x86/kernel/process.c linux-3.0-rc7-libre/arch/x86/kernel/process.c
--- linux-2.6.39-libre/arch/x86/kernel/process.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/kernel/process.c	2011-07-11 19:51:52.000000000 -0400
@@ -337,7 +337,9 @@
  * Powermanagement idle function, if any..
  */
 void (*pm_idle)(void);
+#ifdef CONFIG_APM_MODULE
 EXPORT_SYMBOL(pm_idle);
+#endif
 
 #ifdef CONFIG_X86_32
 /*
@@ -449,7 +451,7 @@
 void mwait_idle_with_hints(unsigned long ax, unsigned long cx)
 {
 	if (!need_resched()) {
-		if (cpu_has(__this_cpu_ptr(&cpu_info), X86_FEATURE_CLFLUSH_MONITOR))
+		if (this_cpu_has(X86_FEATURE_CLFLUSH_MONITOR))
 			clflush((void *)&current_thread_info()->flags);
 
 		__monitor((void *)&current_thread_info()->flags, 0, 0);
@@ -465,7 +467,7 @@
 	if (!need_resched()) {
 		trace_power_start(POWER_CSTATE, 1, smp_processor_id());
 		trace_cpu_idle(1, smp_processor_id());
-		if (cpu_has(__this_cpu_ptr(&cpu_info), X86_FEATURE_CLFLUSH_MONITOR))
+		if (this_cpu_has(X86_FEATURE_CLFLUSH_MONITOR))
 			clflush((void *)&current_thread_info()->flags);
 
 		__monitor((void *)&current_thread_info()->flags, 0, 0);
@@ -535,45 +537,45 @@
 	return (edx & MWAIT_EDX_C1);
 }
 
-bool c1e_detected;
-EXPORT_SYMBOL(c1e_detected);
+bool amd_e400_c1e_detected;
+EXPORT_SYMBOL(amd_e400_c1e_detected);
 
-static cpumask_var_t c1e_mask;
+static cpumask_var_t amd_e400_c1e_mask;
 
-void c1e_remove_cpu(int cpu)
+void amd_e400_remove_cpu(int cpu)
 {
-	if (c1e_mask != NULL)
-		cpumask_clear_cpu(cpu, c1e_mask);
+	if (amd_e400_c1e_mask != NULL)
+		cpumask_clear_cpu(cpu, amd_e400_c1e_mask);
 }
 
 /*
- * C1E aware idle routine. We check for C1E active in the interrupt
+ * AMD Erratum 400 aware idle routine. We check for C1E active in the interrupt
  * pending message MSR. If we detect C1E, then we handle it the same
  * way as C3 power states (local apic timer and TSC stop)
  */
-static void c1e_idle(void)
+static void amd_e400_idle(void)
 {
 	if (need_resched())
 		return;
 
-	if (!c1e_detected) {
+	if (!amd_e400_c1e_detected) {
 		u32 lo, hi;
 
 		rdmsr(MSR_K8_INT_PENDING_MSG, lo, hi);
 
 		if (lo & K8_INTP_C1E_ACTIVE_MASK) {
-			c1e_detected = true;
+			amd_e400_c1e_detected = true;
 			if (!boot_cpu_has(X86_FEATURE_NONSTOP_TSC))
 				mark_tsc_unstable("TSC halt in AMD C1E");
 			printk(KERN_INFO "System has AMD C1E enabled\n");
 		}
 	}
 
-	if (c1e_detected) {
+	if (amd_e400_c1e_detected) {
 		int cpu = smp_processor_id();
 
-		if (!cpumask_test_cpu(cpu, c1e_mask)) {
-			cpumask_set_cpu(cpu, c1e_mask);
+		if (!cpumask_test_cpu(cpu, amd_e400_c1e_mask)) {
+			cpumask_set_cpu(cpu, amd_e400_c1e_mask);
 			/*
 			 * Force broadcast so ACPI can not interfere.
 			 */
@@ -616,17 +618,17 @@
 		pm_idle = mwait_idle;
 	} else if (cpu_has_amd_erratum(amd_erratum_400)) {
 		/* E400: APIC timer interrupt does not wake up CPU from C1e */
-		printk(KERN_INFO "using C1E aware idle routine\n");
-		pm_idle = c1e_idle;
+		printk(KERN_INFO "using AMD E400 aware idle routine\n");
+		pm_idle = amd_e400_idle;
 	} else
 		pm_idle = default_idle;
 }
 
-void __init init_c1e_mask(void)
+void __init init_amd_e400_c1e_mask(void)
 {
-	/* If we're using c1e_idle, we need to allocate c1e_mask. */
-	if (pm_idle == c1e_idle)
-		zalloc_cpumask_var(&c1e_mask, GFP_KERNEL);
+	/* If we're using amd_e400_idle, we need to allocate amd_e400_c1e_mask. */
+	if (pm_idle == amd_e400_idle)
+		zalloc_cpumask_var(&amd_e400_c1e_mask, GFP_KERNEL);
 }
 
 static int __init idle_setup(char *str)
@@ -640,6 +642,7 @@
 		boot_option_idle_override = IDLE_POLL;
 	} else if (!strcmp(str, "mwait")) {
 		boot_option_idle_override = IDLE_FORCE_MWAIT;
+		WARN_ONCE(1, "\"idle=mwait\" will be removed in 2012\n");
 	} else if (!strcmp(str, "halt")) {
 		/*
 		 * When the boot option of idle=halt is added, halt is
diff -druN linux-2.6.39-libre/arch/x86/kernel/ptrace.c linux-3.0-rc7-libre/arch/x86/kernel/ptrace.c
--- linux-2.6.39-libre/arch/x86/kernel/ptrace.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/kernel/ptrace.c	2011-07-11 19:51:52.000000000 -0400
@@ -1363,7 +1363,7 @@
  * We must return the syscall number to actually look up in the table.
  * This can be -1L to skip running any syscall at all.
  */
-asmregparm long syscall_trace_enter(struct pt_regs *regs)
+long syscall_trace_enter(struct pt_regs *regs)
 {
 	long ret = 0;
 
@@ -1408,7 +1408,7 @@
 	return ret ?: regs->orig_ax;
 }
 
-asmregparm void syscall_trace_leave(struct pt_regs *regs)
+void syscall_trace_leave(struct pt_regs *regs)
 {
 	bool step;
 
diff -druN linux-2.6.39-libre/arch/x86/kernel/reboot.c linux-3.0-rc7-libre/arch/x86/kernel/reboot.c
--- linux-2.6.39-libre/arch/x86/kernel/reboot.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/kernel/reboot.c	2011-07-11 19:51:52.000000000 -0400
@@ -36,7 +36,7 @@
 
 static const struct desc_ptr no_idt = {};
 static int reboot_mode;
-enum reboot_type reboot_type = BOOT_KBD;
+enum reboot_type reboot_type = BOOT_ACPI;
 int reboot_force;
 
 #if defined(CONFIG_X86_32) && defined(CONFIG_SMP)
@@ -294,6 +294,14 @@
 			DMI_MATCH(DMI_BOARD_NAME, "VersaLogic Menlow board"),
 		},
 	},
+	{ /* Handle reboot issue on Acer Aspire one */
+		.callback = set_bios_reboot,
+		.ident = "Acer Aspire One A110",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "AOA110"),
+		},
+	},
 	{ }
 };
 
@@ -478,9 +486,24 @@
 {
 }
 
+/*
+ * Windows compatible x86 hardware expects the following on reboot:
+ *
+ * 1) If the FADT has the ACPI reboot register flag set, try it
+ * 2) If still alive, write to the keyboard controller
+ * 3) If still alive, write to the ACPI reboot register again
+ * 4) If still alive, write to the keyboard controller again
+ *
+ * If the machine is still alive at this stage, it gives up. We default to
+ * following the same pattern, except that if we're still alive after (4) we'll
+ * try to force a triple fault and then cycle between hitting the keyboard
+ * controller and doing that
+ */
 static void native_machine_emergency_restart(void)
 {
 	int i;
+	int attempt = 0;
+	int orig_reboot_type = reboot_type;
 
 	if (reboot_emergency)
 		emergency_vmx_disable_all();
@@ -502,6 +525,13 @@
 				outb(0xfe, 0x64); /* pulse reset low */
 				udelay(50);
 			}
+			if (attempt == 0 && orig_reboot_type == BOOT_ACPI) {
+				attempt = 1;
+				reboot_type = BOOT_ACPI;
+			} else {
+				reboot_type = BOOT_TRIPLE;
+			}
+			break;
 
 		case BOOT_TRIPLE:
 			load_idt(&no_idt);
diff -druN linux-2.6.39-libre/arch/x86/kernel/setup.c linux-3.0-rc7-libre/arch/x86/kernel/setup.c
--- linux-2.6.39-libre/arch/x86/kernel/setup.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/kernel/setup.c	2011-07-11 19:51:52.000000000 -0400
@@ -691,8 +691,6 @@
 
 void __init setup_arch(char **cmdline_p)
 {
-	unsigned long flags;
-
 #ifdef CONFIG_X86_32
 	memcpy(&boot_cpu_data, &new_cpu_data, sizeof(new_cpu_data));
 	visws_early_detect();
@@ -912,6 +910,13 @@
 	memblock.current_limit = get_max_mapped();
 	memblock_x86_fill();
 
+	/*
+	 * The EFI specification says that boot service code won't be called
+	 * after ExitBootServices(). This is, in fact, a lie.
+	 */
+	if (efi_enabled)
+		efi_reserve_boot_services();
+
 	/* preallocate 4k for mptable mpc */
 	early_reserve_e820_mpc_new();
 
@@ -948,6 +953,8 @@
 	if (init_ohci1394_dma_early)
 		init_ohci1394_dma_on_all_controllers();
 #endif
+	/* Allocate bigger log buffer */
+	setup_log_buf(1);
 
 	reserve_initrd();
 
@@ -966,7 +973,6 @@
 
 	initmem_init();
 	memblock_find_dma_reserve();
-	dma32_reserve_bootmem();
 
 #ifdef CONFIG_KVM_CLOCK
 	kvmclock_init();
@@ -1041,9 +1047,7 @@
 
 	mcheck_init();
 
-	local_irq_save(flags);
-	arch_init_ideal_nop5();
-	local_irq_restore(flags);
+	arch_init_ideal_nops();
 }
 
 #ifdef CONFIG_X86_32
diff -druN linux-2.6.39-libre/arch/x86/kernel/signal.c linux-3.0-rc7-libre/arch/x86/kernel/signal.c
--- linux-2.6.39-libre/arch/x86/kernel/signal.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/kernel/signal.c	2011-07-11 19:51:52.000000000 -0400
@@ -601,10 +601,7 @@
 		goto badframe;
 
 	sigdelsetmask(&set, ~_BLOCKABLE);
-	spin_lock_irq(&current->sighand->siglock);
-	current->blocked = set;
-	recalc_sigpending();
-	spin_unlock_irq(&current->sighand->siglock);
+	set_current_blocked(&set);
 
 	if (restore_sigcontext(regs, &frame->uc.uc_mcontext, &ax))
 		goto badframe;
@@ -682,6 +679,7 @@
 handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka,
 	      sigset_t *oldset, struct pt_regs *regs)
 {
+	sigset_t blocked;
 	int ret;
 
 	/* Are we from a system call? */
@@ -741,12 +739,10 @@
 	 */
 	regs->flags &= ~X86_EFLAGS_TF;
 
-	spin_lock_irq(&current->sighand->siglock);
-	sigorsets(&current->blocked, &current->blocked, &ka->sa.sa_mask);
+	sigorsets(&blocked, &current->blocked, &ka->sa.sa_mask);
 	if (!(ka->sa.sa_flags & SA_NODEFER))
-		sigaddset(&current->blocked, sig);
-	recalc_sigpending();
-	spin_unlock_irq(&current->sighand->siglock);
+		sigaddset(&blocked, sig);
+	set_current_blocked(&blocked);
 
 	tracehook_signal_handler(sig, info, ka, regs,
 				 test_thread_flag(TIF_SINGLESTEP));
diff -druN linux-2.6.39-libre/arch/x86/kernel/smpboot.c linux-3.0-rc7-libre/arch/x86/kernel/smpboot.c
--- linux-2.6.39-libre/arch/x86/kernel/smpboot.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/kernel/smpboot.c	2011-07-11 19:51:52.000000000 -0400
@@ -285,6 +285,19 @@
 	per_cpu(cpu_state, smp_processor_id()) = CPU_ONLINE;
 	x86_platform.nmi_init();
 
+	/*
+	 * Wait until the cpu which brought this one up marked it
+	 * online before enabling interrupts. If we don't do that then
+	 * we can end up waking up the softirq thread before this cpu
+	 * reached the active state, which makes the scheduler unhappy
+	 * and schedule the softirq thread on the wrong cpu. This is
+	 * only observable with forced threaded interrupts, but in
+	 * theory it could also happen w/o them. It's just way harder
+	 * to achieve.
+	 */
+	while (!cpumask_test_cpu(smp_processor_id(), cpu_active_mask))
+		cpu_relax();
+
 	/* enable local interrupts */
 	local_irq_enable();
 
@@ -1307,7 +1320,7 @@
 {
 	idle_task_exit();
 	reset_lazy_tlbstate();
-	c1e_remove_cpu(raw_smp_processor_id());
+	amd_e400_remove_cpu(raw_smp_processor_id());
 
 	mb();
 	/* Ack it */
@@ -1332,9 +1345,9 @@
 	void *mwait_ptr;
 	struct cpuinfo_x86 *c = __this_cpu_ptr(&cpu_info);
 
-	if (!(cpu_has(c, X86_FEATURE_MWAIT) && mwait_usable(c)))
+	if (!(this_cpu_has(X86_FEATURE_MWAIT) && mwait_usable(c)))
 		return;
-	if (!cpu_has(__this_cpu_ptr(&cpu_info), X86_FEATURE_CLFLSH))
+	if (!this_cpu_has(X86_FEATURE_CLFLSH))
 		return;
 	if (__this_cpu_read(cpu_info.cpuid_level) < CPUID_MWAIT_LEAF)
 		return;
diff -druN linux-2.6.39-libre/arch/x86/kernel/smp.c linux-3.0-rc7-libre/arch/x86/kernel/smp.c
--- linux-2.6.39-libre/arch/x86/kernel/smp.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/kernel/smp.c	2011-07-11 19:51:52.000000000 -0400
@@ -194,14 +194,13 @@
 }
 
 /*
- * Reschedule call back. Nothing to do,
- * all the work is done automatically when
- * we return from the interrupt.
+ * Reschedule call back.
  */
 void smp_reschedule_interrupt(struct pt_regs *regs)
 {
 	ack_APIC_irq();
 	inc_irq_stat(irq_resched_count);
+	scheduler_ipi();
 	/*
 	 * KVM uses this interrupt to force a cpu out of guest mode
 	 */
diff -druN linux-2.6.39-libre/arch/x86/kernel/stacktrace.c linux-3.0-rc7-libre/arch/x86/kernel/stacktrace.c
--- linux-2.6.39-libre/arch/x86/kernel/stacktrace.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/kernel/stacktrace.c	2011-07-11 19:51:52.000000000 -0400
@@ -9,15 +9,6 @@
 #include <linux/uaccess.h>
 #include <asm/stacktrace.h>
 
-static void save_stack_warning(void *data, char *msg)
-{
-}
-
-static void
-save_stack_warning_symbol(void *data, char *msg, unsigned long symbol)
-{
-}
-
 static int save_stack_stack(void *data, char *name)
 {
 	return 0;
@@ -53,16 +44,12 @@
 }
 
 static const struct stacktrace_ops save_stack_ops = {
-	.warning	= save_stack_warning,
-	.warning_symbol	= save_stack_warning_symbol,
 	.stack		= save_stack_stack,
 	.address	= save_stack_address,
 	.walk_stack	= print_context_stack,
 };
 
 static const struct stacktrace_ops save_stack_ops_nosched = {
-	.warning	= save_stack_warning,
-	.warning_symbol	= save_stack_warning_symbol,
 	.stack		= save_stack_stack,
 	.address	= save_stack_address_nosched,
 	.walk_stack	= print_context_stack,
diff -druN linux-2.6.39-libre/arch/x86/kernel/syscall_table_32.S linux-3.0-rc7-libre/arch/x86/kernel/syscall_table_32.S
--- linux-2.6.39-libre/arch/x86/kernel/syscall_table_32.S	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/kernel/syscall_table_32.S	2011-07-11 19:51:52.000000000 -0400
@@ -344,3 +344,5 @@
 	.long sys_open_by_handle_at
 	.long sys_clock_adjtime
 	.long sys_syncfs
+	.long sys_sendmmsg		/* 345 */
+	.long sys_setns
diff -druN linux-2.6.39-libre/arch/x86/kernel/tboot.c linux-3.0-rc7-libre/arch/x86/kernel/tboot.c
--- linux-2.6.39-libre/arch/x86/kernel/tboot.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/kernel/tboot.c	2011-07-11 19:51:52.000000000 -0400
@@ -110,7 +110,6 @@
 	.mmap_sem       = __RWSEM_INITIALIZER(init_mm.mmap_sem),
 	.page_table_lock =  __SPIN_LOCK_UNLOCKED(init_mm.page_table_lock),
 	.mmlist         = LIST_HEAD_INIT(init_mm.mmlist),
-	.cpu_vm_mask    = CPU_MASK_ALL,
 };
 
 static inline void switch_to_tboot_pt(void)
diff -druN linux-2.6.39-libre/arch/x86/kernel/test_nx.c linux-3.0-rc7-libre/arch/x86/kernel/test_nx.c
--- linux-2.6.39-libre/arch/x86/kernel/test_nx.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/kernel/test_nx.c	2011-07-11 19:51:52.000000000 -0400
@@ -161,7 +161,7 @@
 	}
 
 #endif
-	return 0;
+	return ret;
 }
 
 static void test_exit(void)
diff -druN linux-2.6.39-libre/arch/x86/kernel/time.c linux-3.0-rc7-libre/arch/x86/kernel/time.c
--- linux-2.6.39-libre/arch/x86/kernel/time.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/kernel/time.c	2011-07-11 19:51:52.000000000 -0400
@@ -23,7 +23,7 @@
 #include <asm/time.h>
 
 #ifdef CONFIG_X86_64
-volatile unsigned long __jiffies __section_jiffies = INITIAL_JIFFIES;
+DEFINE_VVAR(volatile unsigned long, jiffies) = INITIAL_JIFFIES;
 #endif
 
 unsigned long profile_pc(struct pt_regs *regs)
diff -druN linux-2.6.39-libre/arch/x86/kernel/tsc.c linux-3.0-rc7-libre/arch/x86/kernel/tsc.c
--- linux-2.6.39-libre/arch/x86/kernel/tsc.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/kernel/tsc.c	2011-07-11 19:51:52.000000000 -0400
@@ -763,25 +763,6 @@
 		ret : clocksource_tsc.cycle_last;
 }
 
-#ifdef CONFIG_X86_64
-static cycle_t __vsyscall_fn vread_tsc(void)
-{
-	cycle_t ret;
-
-	/*
-	 * Surround the RDTSC by barriers, to make sure it's not
-	 * speculated to outside the seqlock critical section and
-	 * does not cause time warps:
-	 */
-	rdtsc_barrier();
-	ret = (cycle_t)vget_cycles();
-	rdtsc_barrier();
-
-	return ret >= __vsyscall_gtod_data.clock.cycle_last ?
-		ret : __vsyscall_gtod_data.clock.cycle_last;
-}
-#endif
-
 static void resume_tsc(struct clocksource *cs)
 {
 	clocksource_tsc.cycle_last = 0;
diff -druN linux-2.6.39-libre/arch/x86/kernel/vmlinux.lds.S linux-3.0-rc7-libre/arch/x86/kernel/vmlinux.lds.S
--- linux-2.6.39-libre/arch/x86/kernel/vmlinux.lds.S	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/kernel/vmlinux.lds.S	2011-07-11 19:51:52.000000000 -0400
@@ -161,6 +161,12 @@
 
 #define VVIRT_OFFSET (VSYSCALL_ADDR - __vsyscall_0)
 #define VVIRT(x) (ADDR(x) - VVIRT_OFFSET)
+#define EMIT_VVAR(x, offset) .vsyscall_var_ ## x	\
+	ADDR(.vsyscall_0) + offset		 	\
+	: AT(VLOAD(.vsyscall_var_ ## x)) {     		\
+		*(.vsyscall_var_ ## x)			\
+	}						\
+	x = VVIRT(.vsyscall_var_ ## x);
 
 	. = ALIGN(4096);
 	__vsyscall_0 = .;
@@ -175,18 +181,6 @@
 		*(.vsyscall_fn)
 	}
 
-	. = ALIGN(L1_CACHE_BYTES);
-	.vsyscall_gtod_data : AT(VLOAD(.vsyscall_gtod_data)) {
-		*(.vsyscall_gtod_data)
-	}
-
-	vsyscall_gtod_data = VVIRT(.vsyscall_gtod_data);
-	.vsyscall_clock : AT(VLOAD(.vsyscall_clock)) {
-		*(.vsyscall_clock)
-	}
-	vsyscall_clock = VVIRT(.vsyscall_clock);
-
-
 	.vsyscall_1 ADDR(.vsyscall_0) + 1024: AT(VLOAD(.vsyscall_1)) {
 		*(.vsyscall_1)
 	}
@@ -194,21 +188,14 @@
 		*(.vsyscall_2)
 	}
 
-	.vgetcpu_mode : AT(VLOAD(.vgetcpu_mode)) {
-		*(.vgetcpu_mode)
-	}
-	vgetcpu_mode = VVIRT(.vgetcpu_mode);
-
-	. = ALIGN(L1_CACHE_BYTES);
-	.jiffies : AT(VLOAD(.jiffies)) {
-		*(.jiffies)
-	}
-	jiffies = VVIRT(.jiffies);
-
 	.vsyscall_3 ADDR(.vsyscall_0) + 3072: AT(VLOAD(.vsyscall_3)) {
 		*(.vsyscall_3)
 	}
 
+#define __VVAR_KERNEL_LDS
+#include <asm/vvar.h>
+#undef __VVAR_KERNEL_LDS
+
 	. = __vsyscall_0 + PAGE_SIZE;
 
 #undef VSYSCALL_ADDR
@@ -216,6 +203,7 @@
 #undef VLOAD
 #undef VVIRT_OFFSET
 #undef VVIRT
+#undef EMIT_VVAR
 
 #endif /* CONFIG_X86_64 */
 
@@ -306,6 +294,13 @@
 	}
 
 	. = ALIGN(8);
+	.apicdrivers : AT(ADDR(.apicdrivers) - LOAD_OFFSET) {
+		__apicdrivers = .;
+		*(.apicdrivers);
+		__apicdrivers_end = .;
+	}
+
+	. = ALIGN(8);
 	/*
 	 * .exit.text is discard at runtime, not link time, to deal with
 	 *  references from .altinstructions and .eh_frame
@@ -319,7 +314,7 @@
 	}
 
 #if !defined(CONFIG_X86_64) || !defined(CONFIG_SMP)
-	PERCPU(INTERNODE_CACHE_BYTES, PAGE_SIZE)
+	PERCPU_SECTION(INTERNODE_CACHE_BYTES)
 #endif
 
 	. = ALIGN(PAGE_SIZE);
diff -druN linux-2.6.39-libre/arch/x86/kernel/vread_tsc_64.c linux-3.0-rc7-libre/arch/x86/kernel/vread_tsc_64.c
--- linux-2.6.39-libre/arch/x86/kernel/vread_tsc_64.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/x86/kernel/vread_tsc_64.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,36 @@
+/* This code runs in userspace. */
+
+#define DISABLE_BRANCH_PROFILING
+#include <asm/vgtod.h>
+
+notrace cycle_t __vsyscall_fn vread_tsc(void)
+{
+	cycle_t ret;
+	u64 last;
+
+	/*
+	 * Empirically, a fence (of type that depends on the CPU)
+	 * before rdtsc is enough to ensure that rdtsc is ordered
+	 * with respect to loads.  The various CPU manuals are unclear
+	 * as to whether rdtsc can be reordered with later loads,
+	 * but no one has ever seen it happen.
+	 */
+	rdtsc_barrier();
+	ret = (cycle_t)vget_cycles();
+
+	last = VVAR(vsyscall_gtod_data).clock.cycle_last;
+
+	if (likely(ret >= last))
+		return ret;
+
+	/*
+	 * GCC likes to generate cmov here, but this branch is extremely
+	 * predictable (it's just a funciton of time and the likely is
+	 * very likely) and there's a data dependence, so force GCC
+	 * to generate a branch instead.  I don't barrier() because
+	 * we don't actually need a barrier, and if this function
+	 * ever gets inlined it will generate worse code.
+	 */
+	asm volatile ("");
+	return last;
+}
diff -druN linux-2.6.39-libre/arch/x86/kernel/vsyscall_64.c linux-3.0-rc7-libre/arch/x86/kernel/vsyscall_64.c
--- linux-2.6.39-libre/arch/x86/kernel/vsyscall_64.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/kernel/vsyscall_64.c	2011-07-11 19:51:52.000000000 -0400
@@ -49,17 +49,10 @@
 		__attribute__ ((unused, __section__(".vsyscall_" #nr))) notrace
 #define __syscall_clobber "r11","cx","memory"
 
-/*
- * vsyscall_gtod_data contains data that is :
- * - readonly from vsyscalls
- * - written by timer interrupt or systcl (/proc/sys/kernel/vsyscall64)
- * Try to keep this structure as small as possible to avoid cache line ping pongs
- */
-int __vgetcpu_mode __section_vgetcpu_mode;
-
-struct vsyscall_gtod_data __vsyscall_gtod_data __section_vsyscall_gtod_data =
+DEFINE_VVAR(int, vgetcpu_mode);
+DEFINE_VVAR(struct vsyscall_gtod_data, vsyscall_gtod_data) =
 {
-	.lock = SEQLOCK_UNLOCKED,
+	.lock = __SEQLOCK_UNLOCKED(__vsyscall_gtod_data.lock),
 	.sysctl_enabled = 1,
 };
 
@@ -97,7 +90,7 @@
  */
 static __always_inline void do_get_tz(struct timezone * tz)
 {
-	*tz = __vsyscall_gtod_data.sys_tz;
+	*tz = VVAR(vsyscall_gtod_data).sys_tz;
 }
 
 static __always_inline int gettimeofday(struct timeval *tv, struct timezone *tz)
@@ -126,23 +119,24 @@
 	unsigned long mult, shift, nsec;
 	cycle_t (*vread)(void);
 	do {
-		seq = read_seqbegin(&__vsyscall_gtod_data.lock);
+		seq = read_seqbegin(&VVAR(vsyscall_gtod_data).lock);
 
-		vread = __vsyscall_gtod_data.clock.vread;
-		if (unlikely(!__vsyscall_gtod_data.sysctl_enabled || !vread)) {
+		vread = VVAR(vsyscall_gtod_data).clock.vread;
+		if (unlikely(!VVAR(vsyscall_gtod_data).sysctl_enabled ||
+			     !vread)) {
 			gettimeofday(tv,NULL);
 			return;
 		}
 
 		now = vread();
-		base = __vsyscall_gtod_data.clock.cycle_last;
-		mask = __vsyscall_gtod_data.clock.mask;
-		mult = __vsyscall_gtod_data.clock.mult;
-		shift = __vsyscall_gtod_data.clock.shift;
+		base = VVAR(vsyscall_gtod_data).clock.cycle_last;
+		mask = VVAR(vsyscall_gtod_data).clock.mask;
+		mult = VVAR(vsyscall_gtod_data).clock.mult;
+		shift = VVAR(vsyscall_gtod_data).clock.shift;
 
-		tv->tv_sec = __vsyscall_gtod_data.wall_time_sec;
-		nsec = __vsyscall_gtod_data.wall_time_nsec;
-	} while (read_seqretry(&__vsyscall_gtod_data.lock, seq));
+		tv->tv_sec = VVAR(vsyscall_gtod_data).wall_time_sec;
+		nsec = VVAR(vsyscall_gtod_data).wall_time_nsec;
+	} while (read_seqretry(&VVAR(vsyscall_gtod_data).lock, seq));
 
 	/* calculate interval: */
 	cycle_delta = (now - base) & mask;
@@ -171,15 +165,15 @@
 {
 	unsigned seq;
 	time_t result;
-	if (unlikely(!__vsyscall_gtod_data.sysctl_enabled))
+	if (unlikely(!VVAR(vsyscall_gtod_data).sysctl_enabled))
 		return time_syscall(t);
 
 	do {
-		seq = read_seqbegin(&__vsyscall_gtod_data.lock);
+		seq = read_seqbegin(&VVAR(vsyscall_gtod_data).lock);
 
-		result = __vsyscall_gtod_data.wall_time_sec;
+		result = VVAR(vsyscall_gtod_data).wall_time_sec;
 
-	} while (read_seqretry(&__vsyscall_gtod_data.lock, seq));
+	} while (read_seqretry(&VVAR(vsyscall_gtod_data).lock, seq));
 
 	if (t)
 		*t = result;
@@ -208,9 +202,9 @@
 	   We do this here because otherwise user space would do it on
 	   its own in a likely inferior way (no access to jiffies).
 	   If you don't like it pass NULL. */
-	if (tcache && tcache->blob[0] == (j = __jiffies)) {
+	if (tcache && tcache->blob[0] == (j = VVAR(jiffies))) {
 		p = tcache->blob[1];
-	} else if (__vgetcpu_mode == VGETCPU_RDTSCP) {
+	} else if (VVAR(vgetcpu_mode) == VGETCPU_RDTSCP) {
 		/* Load per CPU data from RDTSCP */
 		native_read_tscp(&p);
 	} else {
diff -druN linux-2.6.39-libre/arch/x86/kernel/x86_init.c linux-3.0-rc7-libre/arch/x86/kernel/x86_init.c
--- linux-2.6.39-libre/arch/x86/kernel/x86_init.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/kernel/x86_init.c	2011-07-11 19:51:52.000000000 -0400
@@ -35,7 +35,7 @@
 struct x86_init_ops x86_init __initdata = {
 
 	.resources = {
-		.probe_roms		= x86_init_noop,
+		.probe_roms		= probe_roms,
 		.reserve_resources	= reserve_standard_io_resources,
 		.memory_setup		= default_machine_specific_memory_setup,
 	},
diff -druN linux-2.6.39-libre/arch/x86/kvm/emulate.c linux-3.0-rc7-libre/arch/x86/kvm/emulate.c
--- linux-2.6.39-libre/arch/x86/kvm/emulate.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/kvm/emulate.c	2011-07-11 19:51:52.000000000 -0400
@@ -47,35 +47,42 @@
 #define DstDI       (5<<1)	/* Destination is in ES:(E)DI */
 #define DstMem64    (6<<1)	/* 64bit memory operand */
 #define DstImmUByte (7<<1)	/* 8-bit unsigned immediate operand */
-#define DstMask     (7<<1)
+#define DstDX       (8<<1)	/* Destination is in DX register */
+#define DstMask     (0xf<<1)
 /* Source operand type. */
-#define SrcNone     (0<<4)	/* No source operand. */
-#define SrcReg      (1<<4)	/* Register operand. */
-#define SrcMem      (2<<4)	/* Memory operand. */
-#define SrcMem16    (3<<4)	/* Memory operand (16-bit). */
-#define SrcMem32    (4<<4)	/* Memory operand (32-bit). */
-#define SrcImm      (5<<4)	/* Immediate operand. */
-#define SrcImmByte  (6<<4)	/* 8-bit sign-extended immediate operand. */
-#define SrcOne      (7<<4)	/* Implied '1' */
-#define SrcImmUByte (8<<4)      /* 8-bit unsigned immediate operand. */
-#define SrcImmU     (9<<4)      /* Immediate operand, unsigned */
-#define SrcSI       (0xa<<4)	/* Source is in the DS:RSI */
-#define SrcImmFAddr (0xb<<4)	/* Source is immediate far address */
-#define SrcMemFAddr (0xc<<4)	/* Source is far address in memory */
-#define SrcAcc      (0xd<<4)	/* Source Accumulator */
-#define SrcImmU16   (0xe<<4)    /* Immediate operand, unsigned, 16 bits */
-#define SrcMask     (0xf<<4)
+#define SrcNone     (0<<5)	/* No source operand. */
+#define SrcReg      (1<<5)	/* Register operand. */
+#define SrcMem      (2<<5)	/* Memory operand. */
+#define SrcMem16    (3<<5)	/* Memory operand (16-bit). */
+#define SrcMem32    (4<<5)	/* Memory operand (32-bit). */
+#define SrcImm      (5<<5)	/* Immediate operand. */
+#define SrcImmByte  (6<<5)	/* 8-bit sign-extended immediate operand. */
+#define SrcOne      (7<<5)	/* Implied '1' */
+#define SrcImmUByte (8<<5)      /* 8-bit unsigned immediate operand. */
+#define SrcImmU     (9<<5)      /* Immediate operand, unsigned */
+#define SrcSI       (0xa<<5)	/* Source is in the DS:RSI */
+#define SrcImmFAddr (0xb<<5)	/* Source is immediate far address */
+#define SrcMemFAddr (0xc<<5)	/* Source is far address in memory */
+#define SrcAcc      (0xd<<5)	/* Source Accumulator */
+#define SrcImmU16   (0xe<<5)    /* Immediate operand, unsigned, 16 bits */
+#define SrcDX       (0xf<<5)	/* Source is in DX register */
+#define SrcMask     (0xf<<5)
 /* Generic ModRM decode. */
-#define ModRM       (1<<8)
+#define ModRM       (1<<9)
 /* Destination is only written; never read. */
-#define Mov         (1<<9)
-#define BitOp       (1<<10)
-#define MemAbs      (1<<11)      /* Memory operand is absolute displacement */
-#define String      (1<<12)     /* String instruction (rep capable) */
-#define Stack       (1<<13)     /* Stack instruction (push/pop) */
-#define Group       (1<<14)     /* Bits 3:5 of modrm byte extend opcode */
-#define GroupDual   (1<<15)     /* Alternate decoding of mod == 3 */
+#define Mov         (1<<10)
+#define BitOp       (1<<11)
+#define MemAbs      (1<<12)      /* Memory operand is absolute displacement */
+#define String      (1<<13)     /* String instruction (rep capable) */
+#define Stack       (1<<14)     /* Stack instruction (push/pop) */
+#define GroupMask   (7<<15)     /* Opcode uses one of the group mechanisms */
+#define Group       (1<<15)     /* Bits 3:5 of modrm byte extend opcode */
+#define GroupDual   (2<<15)     /* Alternate decoding of mod == 3 */
+#define Prefix      (3<<15)     /* Instruction varies with 66/f2/f3 prefix */
+#define RMExt       (4<<15)     /* Opcode extension in ModRM r/m if mod == 3 */
+#define Sse         (1<<18)     /* SSE Vector instruction */
 /* Misc flags */
+#define Prot        (1<<21) /* instruction generates #UD if not in prot-mode */
 #define VendorSpecific (1<<22) /* Vendor specific instruction */
 #define NoAccess    (1<<23) /* Don't access memory (lea/invlpg/verr etc) */
 #define Op3264      (1<<24) /* Operand is 64b in long mode, 32b otherwise */
@@ -102,11 +109,14 @@
 
 struct opcode {
 	u32 flags;
+	u8 intercept;
 	union {
 		int (*execute)(struct x86_emulate_ctxt *ctxt);
 		struct opcode *group;
 		struct group_dual *gdual;
+		struct gprefix *gprefix;
 	} u;
+	int (*check_perm)(struct x86_emulate_ctxt *ctxt);
 };
 
 struct group_dual {
@@ -114,6 +124,13 @@
 	struct opcode mod3[8];
 };
 
+struct gprefix {
+	struct opcode pfx_no;
+	struct opcode pfx_66;
+	struct opcode pfx_f2;
+	struct opcode pfx_f3;
+};
+
 /* EFLAGS bit definitions. */
 #define EFLG_ID (1<<21)
 #define EFLG_VIP (1<<20)
@@ -248,42 +265,42 @@
 			     "w", "r", _LO32, "r", "", "r")
 
 /* Instruction has three operands and one operand is stored in ECX register */
-#define __emulate_2op_cl(_op, _cl, _src, _dst, _eflags, _suffix, _type) 	\
-	do {									\
-		unsigned long _tmp;						\
-		_type _clv  = (_cl).val;  					\
-		_type _srcv = (_src).val;    					\
-		_type _dstv = (_dst).val;					\
-										\
-		__asm__ __volatile__ (						\
-			_PRE_EFLAGS("0", "5", "2")				\
-			_op _suffix " %4,%1 \n"					\
-			_POST_EFLAGS("0", "5", "2")				\
-			: "=m" (_eflags), "+r" (_dstv), "=&r" (_tmp)		\
-			: "c" (_clv) , "r" (_srcv), "i" (EFLAGS_MASK)		\
-			); 							\
-										\
-		(_cl).val  = (unsigned long) _clv;				\
-		(_src).val = (unsigned long) _srcv;				\
-		(_dst).val = (unsigned long) _dstv;				\
+#define __emulate_2op_cl(_op, _cl, _src, _dst, _eflags, _suffix, _type)	\
+	do {								\
+		unsigned long _tmp;					\
+		_type _clv  = (_cl).val;				\
+		_type _srcv = (_src).val;				\
+		_type _dstv = (_dst).val;				\
+									\
+		__asm__ __volatile__ (					\
+			_PRE_EFLAGS("0", "5", "2")			\
+			_op _suffix " %4,%1 \n"				\
+			_POST_EFLAGS("0", "5", "2")			\
+			: "=m" (_eflags), "+r" (_dstv), "=&r" (_tmp)	\
+			: "c" (_clv) , "r" (_srcv), "i" (EFLAGS_MASK)	\
+			);						\
+									\
+		(_cl).val  = (unsigned long) _clv;			\
+		(_src).val = (unsigned long) _srcv;			\
+		(_dst).val = (unsigned long) _dstv;			\
 	} while (0)
 
-#define emulate_2op_cl(_op, _cl, _src, _dst, _eflags)				\
-	do {									\
-		switch ((_dst).bytes) {						\
-		case 2:								\
-			__emulate_2op_cl(_op, _cl, _src, _dst, _eflags,  	\
-						"w", unsigned short);         	\
-			break;							\
-		case 4: 							\
-			__emulate_2op_cl(_op, _cl, _src, _dst, _eflags,  	\
-						"l", unsigned int);           	\
-			break;							\
-		case 8:								\
-			ON64(__emulate_2op_cl(_op, _cl, _src, _dst, _eflags,	\
-						"q", unsigned long));  		\
-			break;							\
-		}								\
+#define emulate_2op_cl(_op, _cl, _src, _dst, _eflags)			\
+	do {								\
+		switch ((_dst).bytes) {					\
+		case 2:							\
+			__emulate_2op_cl(_op, _cl, _src, _dst, _eflags,	\
+					 "w", unsigned short);         	\
+			break;						\
+		case 4:							\
+			__emulate_2op_cl(_op, _cl, _src, _dst, _eflags,	\
+					 "l", unsigned int);           	\
+			break;						\
+		case 8:							\
+			ON64(__emulate_2op_cl(_op, _cl, _src, _dst, _eflags, \
+					      "q", unsigned long));	\
+			break;						\
+		}							\
 	} while (0)
 
 #define __emulate_1op(_op, _dst, _eflags, _suffix)			\
@@ -346,13 +363,25 @@
 	} while (0)
 
 /* instruction has only one source operand, destination is implicit (e.g. mul, div, imul, idiv) */
-#define emulate_1op_rax_rdx(_op, _src, _rax, _rdx, _eflags)			\
-	do {									\
-		switch((_src).bytes) {						\
-		case 1: __emulate_1op_rax_rdx(_op, _src, _rax, _rdx, _eflags, "b"); break; \
-		case 2: __emulate_1op_rax_rdx(_op, _src, _rax, _rdx,  _eflags, "w"); break; \
-		case 4: __emulate_1op_rax_rdx(_op, _src, _rax, _rdx, _eflags, "l"); break; \
-		case 8: ON64(__emulate_1op_rax_rdx(_op, _src, _rax, _rdx, _eflags, "q")); break; \
+#define emulate_1op_rax_rdx(_op, _src, _rax, _rdx, _eflags)		\
+	do {								\
+		switch((_src).bytes) {					\
+		case 1:							\
+			__emulate_1op_rax_rdx(_op, _src, _rax, _rdx,	\
+					      _eflags, "b");		\
+			break;						\
+		case 2:							\
+			__emulate_1op_rax_rdx(_op, _src, _rax, _rdx,	\
+					      _eflags, "w");		\
+			break;						\
+		case 4:							\
+			__emulate_1op_rax_rdx(_op, _src, _rax, _rdx,	\
+					      _eflags, "l");		\
+			break;						\
+		case 8:							\
+			ON64(__emulate_1op_rax_rdx(_op, _src, _rax, _rdx, \
+						   _eflags, "q"));	\
+			break;						\
 		}							\
 	} while (0)
 
@@ -388,13 +417,33 @@
 	(_type)_x;							\
 })
 
-#define insn_fetch_arr(_arr, _size, _eip)                                \
+#define insn_fetch_arr(_arr, _size, _eip)				\
 ({	rc = do_insn_fetch(ctxt, ops, (_eip), _arr, (_size));		\
 	if (rc != X86EMUL_CONTINUE)					\
 		goto done;						\
 	(_eip) += (_size);						\
 })
 
+static int emulator_check_intercept(struct x86_emulate_ctxt *ctxt,
+				    enum x86_intercept intercept,
+				    enum x86_intercept_stage stage)
+{
+	struct x86_instruction_info info = {
+		.intercept  = intercept,
+		.rep_prefix = ctxt->decode.rep_prefix,
+		.modrm_mod  = ctxt->decode.modrm_mod,
+		.modrm_reg  = ctxt->decode.modrm_reg,
+		.modrm_rm   = ctxt->decode.modrm_rm,
+		.src_val    = ctxt->decode.src.val64,
+		.src_bytes  = ctxt->decode.src.bytes,
+		.dst_bytes  = ctxt->decode.dst.bytes,
+		.ad_bytes   = ctxt->decode.ad_bytes,
+		.next_rip   = ctxt->eip,
+	};
+
+	return ctxt->ops->intercept(ctxt, &info, stage);
+}
+
 static inline unsigned long ad_mask(struct decode_cache *c)
 {
 	return (1UL << (c->ad_bytes << 3)) - 1;
@@ -430,6 +479,13 @@
 	register_address_increment(c, &c->eip, rel);
 }
 
+static u32 desc_limit_scaled(struct desc_struct *desc)
+{
+	u32 limit = get_desc_limit(desc);
+
+	return desc->g ? (limit << 12) | 0xfff : limit;
+}
+
 static void set_seg_override(struct decode_cache *c, int seg)
 {
 	c->has_seg_override = true;
@@ -442,11 +498,10 @@
 	if (ctxt->mode == X86EMUL_MODE_PROT64 && seg < VCPU_SREG_FS)
 		return 0;
 
-	return ops->get_cached_segment_base(seg, ctxt->vcpu);
+	return ops->get_cached_segment_base(ctxt, seg);
 }
 
 static unsigned seg_override(struct x86_emulate_ctxt *ctxt,
-			     struct x86_emulate_ops *ops,
 			     struct decode_cache *c)
 {
 	if (!c->has_seg_override)
@@ -455,18 +510,6 @@
 	return c->seg_override;
 }
 
-static ulong linear(struct x86_emulate_ctxt *ctxt,
-		    struct segmented_address addr)
-{
-	struct decode_cache *c = &ctxt->decode;
-	ulong la;
-
-	la = seg_base(ctxt, ctxt->ops, addr.seg) + addr.ea;
-	if (c->ad_bytes != 8)
-		la &= (u32)-1;
-	return la;
-}
-
 static int emulate_exception(struct x86_emulate_ctxt *ctxt, int vec,
 			     u32 error, bool valid)
 {
@@ -476,11 +519,21 @@
 	return X86EMUL_PROPAGATE_FAULT;
 }
 
+static int emulate_db(struct x86_emulate_ctxt *ctxt)
+{
+	return emulate_exception(ctxt, DB_VECTOR, 0, false);
+}
+
 static int emulate_gp(struct x86_emulate_ctxt *ctxt, int err)
 {
 	return emulate_exception(ctxt, GP_VECTOR, err, true);
 }
 
+static int emulate_ss(struct x86_emulate_ctxt *ctxt, int err)
+{
+	return emulate_exception(ctxt, SS_VECTOR, err, true);
+}
+
 static int emulate_ud(struct x86_emulate_ctxt *ctxt)
 {
 	return emulate_exception(ctxt, UD_VECTOR, 0, false);
@@ -496,6 +549,128 @@
 	return emulate_exception(ctxt, DE_VECTOR, 0, false);
 }
 
+static int emulate_nm(struct x86_emulate_ctxt *ctxt)
+{
+	return emulate_exception(ctxt, NM_VECTOR, 0, false);
+}
+
+static u16 get_segment_selector(struct x86_emulate_ctxt *ctxt, unsigned seg)
+{
+	u16 selector;
+	struct desc_struct desc;
+
+	ctxt->ops->get_segment(ctxt, &selector, &desc, NULL, seg);
+	return selector;
+}
+
+static void set_segment_selector(struct x86_emulate_ctxt *ctxt, u16 selector,
+				 unsigned seg)
+{
+	u16 dummy;
+	u32 base3;
+	struct desc_struct desc;
+
+	ctxt->ops->get_segment(ctxt, &dummy, &desc, &base3, seg);
+	ctxt->ops->set_segment(ctxt, selector, &desc, base3, seg);
+}
+
+static int __linearize(struct x86_emulate_ctxt *ctxt,
+		     struct segmented_address addr,
+		     unsigned size, bool write, bool fetch,
+		     ulong *linear)
+{
+	struct decode_cache *c = &ctxt->decode;
+	struct desc_struct desc;
+	bool usable;
+	ulong la;
+	u32 lim;
+	u16 sel;
+	unsigned cpl, rpl;
+
+	la = seg_base(ctxt, ctxt->ops, addr.seg) + addr.ea;
+	switch (ctxt->mode) {
+	case X86EMUL_MODE_REAL:
+		break;
+	case X86EMUL_MODE_PROT64:
+		if (((signed long)la << 16) >> 16 != la)
+			return emulate_gp(ctxt, 0);
+		break;
+	default:
+		usable = ctxt->ops->get_segment(ctxt, &sel, &desc, NULL,
+						addr.seg);
+		if (!usable)
+			goto bad;
+		/* code segment or read-only data segment */
+		if (((desc.type & 8) || !(desc.type & 2)) && write)
+			goto bad;
+		/* unreadable code segment */
+		if (!fetch && (desc.type & 8) && !(desc.type & 2))
+			goto bad;
+		lim = desc_limit_scaled(&desc);
+		if ((desc.type & 8) || !(desc.type & 4)) {
+			/* expand-up segment */
+			if (addr.ea > lim || (u32)(addr.ea + size - 1) > lim)
+				goto bad;
+		} else {
+			/* exapand-down segment */
+			if (addr.ea <= lim || (u32)(addr.ea + size - 1) <= lim)
+				goto bad;
+			lim = desc.d ? 0xffffffff : 0xffff;
+			if (addr.ea > lim || (u32)(addr.ea + size - 1) > lim)
+				goto bad;
+		}
+		cpl = ctxt->ops->cpl(ctxt);
+		rpl = sel & 3;
+		cpl = max(cpl, rpl);
+		if (!(desc.type & 8)) {
+			/* data segment */
+			if (cpl > desc.dpl)
+				goto bad;
+		} else if ((desc.type & 8) && !(desc.type & 4)) {
+			/* nonconforming code segment */
+			if (cpl != desc.dpl)
+				goto bad;
+		} else if ((desc.type & 8) && (desc.type & 4)) {
+			/* conforming code segment */
+			if (cpl < desc.dpl)
+				goto bad;
+		}
+		break;
+	}
+	if (fetch ? ctxt->mode != X86EMUL_MODE_PROT64 : c->ad_bytes != 8)
+		la &= (u32)-1;
+	*linear = la;
+	return X86EMUL_CONTINUE;
+bad:
+	if (addr.seg == VCPU_SREG_SS)
+		return emulate_ss(ctxt, addr.seg);
+	else
+		return emulate_gp(ctxt, addr.seg);
+}
+
+static int linearize(struct x86_emulate_ctxt *ctxt,
+		     struct segmented_address addr,
+		     unsigned size, bool write,
+		     ulong *linear)
+{
+	return __linearize(ctxt, addr, size, write, false, linear);
+}
+
+
+static int segmented_read_std(struct x86_emulate_ctxt *ctxt,
+			      struct segmented_address addr,
+			      void *data,
+			      unsigned size)
+{
+	int rc;
+	ulong linear;
+
+	rc = linearize(ctxt, addr, size, false, &linear);
+	if (rc != X86EMUL_CONTINUE)
+		return rc;
+	return ctxt->ops->read_std(ctxt, linear, data, size, &ctxt->exception);
+}
+
 static int do_fetch_insn_byte(struct x86_emulate_ctxt *ctxt,
 			      struct x86_emulate_ops *ops,
 			      unsigned long eip, u8 *dest)
@@ -505,10 +680,15 @@
 	int size, cur_size;
 
 	if (eip == fc->end) {
+		unsigned long linear;
+		struct segmented_address addr = { .seg=VCPU_SREG_CS, .ea=eip};
 		cur_size = fc->end - fc->start;
 		size = min(15UL - cur_size, PAGE_SIZE - offset_in_page(eip));
-		rc = ops->fetch(ctxt->cs_base + eip, fc->data + cur_size,
-				size, ctxt->vcpu, &ctxt->exception);
+		rc = __linearize(ctxt, addr, size, false, true, &linear);
+		if (rc != X86EMUL_CONTINUE)
+			return rc;
+		rc = ops->fetch(ctxt, linear, fc->data + cur_size,
+				size, &ctxt->exception);
 		if (rc != X86EMUL_CONTINUE)
 			return rc;
 		fc->end += size;
@@ -551,7 +731,6 @@
 }
 
 static int read_descriptor(struct x86_emulate_ctxt *ctxt,
-			   struct x86_emulate_ops *ops,
 			   struct segmented_address addr,
 			   u16 *size, unsigned long *address, int op_bytes)
 {
@@ -560,13 +739,11 @@
 	if (op_bytes == 2)
 		op_bytes = 3;
 	*address = 0;
-	rc = ops->read_std(linear(ctxt, addr), (unsigned long *)size, 2,
-			   ctxt->vcpu, &ctxt->exception);
+	rc = segmented_read_std(ctxt, addr, size, 2);
 	if (rc != X86EMUL_CONTINUE)
 		return rc;
 	addr.ea += 2;
-	rc = ops->read_std(linear(ctxt, addr), address, op_bytes,
-			   ctxt->vcpu, &ctxt->exception);
+	rc = segmented_read_std(ctxt, addr, address, op_bytes);
 	return rc;
 }
 
@@ -623,7 +800,63 @@
 	}
 }
 
-static void decode_register_operand(struct operand *op,
+static void read_sse_reg(struct x86_emulate_ctxt *ctxt, sse128_t *data, int reg)
+{
+	ctxt->ops->get_fpu(ctxt);
+	switch (reg) {
+	case 0: asm("movdqu %%xmm0, %0" : "=m"(*data)); break;
+	case 1: asm("movdqu %%xmm1, %0" : "=m"(*data)); break;
+	case 2: asm("movdqu %%xmm2, %0" : "=m"(*data)); break;
+	case 3: asm("movdqu %%xmm3, %0" : "=m"(*data)); break;
+	case 4: asm("movdqu %%xmm4, %0" : "=m"(*data)); break;
+	case 5: asm("movdqu %%xmm5, %0" : "=m"(*data)); break;
+	case 6: asm("movdqu %%xmm6, %0" : "=m"(*data)); break;
+	case 7: asm("movdqu %%xmm7, %0" : "=m"(*data)); break;
+#ifdef CONFIG_X86_64
+	case 8: asm("movdqu %%xmm8, %0" : "=m"(*data)); break;
+	case 9: asm("movdqu %%xmm9, %0" : "=m"(*data)); break;
+	case 10: asm("movdqu %%xmm10, %0" : "=m"(*data)); break;
+	case 11: asm("movdqu %%xmm11, %0" : "=m"(*data)); break;
+	case 12: asm("movdqu %%xmm12, %0" : "=m"(*data)); break;
+	case 13: asm("movdqu %%xmm13, %0" : "=m"(*data)); break;
+	case 14: asm("movdqu %%xmm14, %0" : "=m"(*data)); break;
+	case 15: asm("movdqu %%xmm15, %0" : "=m"(*data)); break;
+#endif
+	default: BUG();
+	}
+	ctxt->ops->put_fpu(ctxt);
+}
+
+static void write_sse_reg(struct x86_emulate_ctxt *ctxt, sse128_t *data,
+			  int reg)
+{
+	ctxt->ops->get_fpu(ctxt);
+	switch (reg) {
+	case 0: asm("movdqu %0, %%xmm0" : : "m"(*data)); break;
+	case 1: asm("movdqu %0, %%xmm1" : : "m"(*data)); break;
+	case 2: asm("movdqu %0, %%xmm2" : : "m"(*data)); break;
+	case 3: asm("movdqu %0, %%xmm3" : : "m"(*data)); break;
+	case 4: asm("movdqu %0, %%xmm4" : : "m"(*data)); break;
+	case 5: asm("movdqu %0, %%xmm5" : : "m"(*data)); break;
+	case 6: asm("movdqu %0, %%xmm6" : : "m"(*data)); break;
+	case 7: asm("movdqu %0, %%xmm7" : : "m"(*data)); break;
+#ifdef CONFIG_X86_64
+	case 8: asm("movdqu %0, %%xmm8" : : "m"(*data)); break;
+	case 9: asm("movdqu %0, %%xmm9" : : "m"(*data)); break;
+	case 10: asm("movdqu %0, %%xmm10" : : "m"(*data)); break;
+	case 11: asm("movdqu %0, %%xmm11" : : "m"(*data)); break;
+	case 12: asm("movdqu %0, %%xmm12" : : "m"(*data)); break;
+	case 13: asm("movdqu %0, %%xmm13" : : "m"(*data)); break;
+	case 14: asm("movdqu %0, %%xmm14" : : "m"(*data)); break;
+	case 15: asm("movdqu %0, %%xmm15" : : "m"(*data)); break;
+#endif
+	default: BUG();
+	}
+	ctxt->ops->put_fpu(ctxt);
+}
+
+static void decode_register_operand(struct x86_emulate_ctxt *ctxt,
+				    struct operand *op,
 				    struct decode_cache *c,
 				    int inhibit_bytereg)
 {
@@ -632,6 +865,15 @@
 
 	if (!(c->d & ModRM))
 		reg = (c->b & 7) | ((c->rex_prefix & 1) << 3);
+
+	if (c->d & Sse) {
+		op->type = OP_XMM;
+		op->bytes = 16;
+		op->addr.xmm = reg;
+		read_sse_reg(ctxt, &op->vec_val, reg);
+		return;
+	}
+
 	op->type = OP_REG;
 	if ((c->d & ByteOp) && !inhibit_bytereg) {
 		op->addr.reg = decode_register(reg, c->regs, highbyte_regs);
@@ -671,6 +913,13 @@
 		op->bytes = (c->d & ByteOp) ? 1 : c->op_bytes;
 		op->addr.reg = decode_register(c->modrm_rm,
 					       c->regs, c->d & ByteOp);
+		if (c->d & Sse) {
+			op->type = OP_XMM;
+			op->bytes = 16;
+			op->addr.xmm = c->modrm_rm;
+			read_sse_reg(ctxt, &op->vec_val, c->modrm_rm);
+			return rc;
+		}
 		fetch_register_operand(op);
 		return rc;
 	}
@@ -819,8 +1068,8 @@
 		if (mc->pos < mc->end)
 			goto read_cached;
 
-		rc = ops->read_emulated(addr, mc->data + mc->end, n,
-					&ctxt->exception, ctxt->vcpu);
+		rc = ops->read_emulated(ctxt, addr, mc->data + mc->end, n,
+					&ctxt->exception);
 		if (rc != X86EMUL_CONTINUE)
 			return rc;
 		mc->end += n;
@@ -834,6 +1083,50 @@
 	return X86EMUL_CONTINUE;
 }
 
+static int segmented_read(struct x86_emulate_ctxt *ctxt,
+			  struct segmented_address addr,
+			  void *data,
+			  unsigned size)
+{
+	int rc;
+	ulong linear;
+
+	rc = linearize(ctxt, addr, size, false, &linear);
+	if (rc != X86EMUL_CONTINUE)
+		return rc;
+	return read_emulated(ctxt, ctxt->ops, linear, data, size);
+}
+
+static int segmented_write(struct x86_emulate_ctxt *ctxt,
+			   struct segmented_address addr,
+			   const void *data,
+			   unsigned size)
+{
+	int rc;
+	ulong linear;
+
+	rc = linearize(ctxt, addr, size, true, &linear);
+	if (rc != X86EMUL_CONTINUE)
+		return rc;
+	return ctxt->ops->write_emulated(ctxt, linear, data, size,
+					 &ctxt->exception);
+}
+
+static int segmented_cmpxchg(struct x86_emulate_ctxt *ctxt,
+			     struct segmented_address addr,
+			     const void *orig_data, const void *data,
+			     unsigned size)
+{
+	int rc;
+	ulong linear;
+
+	rc = linearize(ctxt, addr, size, true, &linear);
+	if (rc != X86EMUL_CONTINUE)
+		return rc;
+	return ctxt->ops->cmpxchg_emulated(ctxt, linear, orig_data, data,
+					   size, &ctxt->exception);
+}
+
 static int pio_in_emulated(struct x86_emulate_ctxt *ctxt,
 			   struct x86_emulate_ops *ops,
 			   unsigned int size, unsigned short port,
@@ -854,7 +1147,7 @@
 		if (n == 0)
 			n = 1;
 		rc->pos = rc->end = 0;
-		if (!ops->pio_in_emulated(size, port, rc->data, n, ctxt->vcpu))
+		if (!ops->pio_in_emulated(ctxt, size, port, rc->data, n))
 			return 0;
 		rc->end = n * size;
 	}
@@ -864,28 +1157,22 @@
 	return 1;
 }
 
-static u32 desc_limit_scaled(struct desc_struct *desc)
-{
-	u32 limit = get_desc_limit(desc);
-
-	return desc->g ? (limit << 12) | 0xfff : limit;
-}
-
 static void get_descriptor_table_ptr(struct x86_emulate_ctxt *ctxt,
 				     struct x86_emulate_ops *ops,
 				     u16 selector, struct desc_ptr *dt)
 {
 	if (selector & 1 << 2) {
 		struct desc_struct desc;
+		u16 sel;
+
 		memset (dt, 0, sizeof *dt);
-		if (!ops->get_cached_descriptor(&desc, NULL, VCPU_SREG_LDTR,
-						ctxt->vcpu))
+		if (!ops->get_segment(ctxt, &sel, &desc, NULL, VCPU_SREG_LDTR))
 			return;
 
 		dt->size = desc_limit_scaled(&desc); /* what if limit > 65535? */
 		dt->address = get_desc_base(&desc);
 	} else
-		ops->get_gdt(dt, ctxt->vcpu);
+		ops->get_gdt(ctxt, dt);
 }
 
 /* allowed just for 8 bytes segments */
@@ -903,8 +1190,7 @@
 	if (dt.size < index * 8 + 7)
 		return emulate_gp(ctxt, selector & 0xfffc);
 	addr = dt.address + index * 8;
-	ret = ops->read_std(addr, desc, sizeof *desc, ctxt->vcpu,
-			    &ctxt->exception);
+	ret = ops->read_std(ctxt, addr, desc, sizeof *desc, &ctxt->exception);
 
        return ret;
 }
@@ -925,8 +1211,7 @@
 		return emulate_gp(ctxt, selector & 0xfffc);
 
 	addr = dt.address + index * 8;
-	ret = ops->write_std(addr, desc, sizeof *desc, ctxt->vcpu,
-			     &ctxt->exception);
+	ret = ops->write_std(ctxt, addr, desc, sizeof *desc, &ctxt->exception);
 
 	return ret;
 }
@@ -986,7 +1271,7 @@
 
 	rpl = selector & 3;
 	dpl = seg_desc.dpl;
-	cpl = ops->cpl(ctxt->vcpu);
+	cpl = ops->cpl(ctxt);
 
 	switch (seg) {
 	case VCPU_SREG_SS:
@@ -1042,8 +1327,7 @@
 			return ret;
 	}
 load:
-	ops->set_segment_selector(selector, seg, ctxt->vcpu);
-	ops->set_cached_descriptor(&seg_desc, 0, seg, ctxt->vcpu);
+	ops->set_segment(ctxt, selector, &seg_desc, 0, seg);
 	return X86EMUL_CONTINUE;
 exception:
 	emulate_exception(ctxt, err_vec, err_code, true);
@@ -1069,8 +1353,7 @@
 	}
 }
 
-static inline int writeback(struct x86_emulate_ctxt *ctxt,
-			    struct x86_emulate_ops *ops)
+static int writeback(struct x86_emulate_ctxt *ctxt)
 {
 	int rc;
 	struct decode_cache *c = &ctxt->decode;
@@ -1081,23 +1364,22 @@
 		break;
 	case OP_MEM:
 		if (c->lock_prefix)
-			rc = ops->cmpxchg_emulated(
-					linear(ctxt, c->dst.addr.mem),
-					&c->dst.orig_val,
-					&c->dst.val,
-					c->dst.bytes,
-					&ctxt->exception,
-					ctxt->vcpu);
+			rc = segmented_cmpxchg(ctxt,
+					       c->dst.addr.mem,
+					       &c->dst.orig_val,
+					       &c->dst.val,
+					       c->dst.bytes);
 		else
-			rc = ops->write_emulated(
-					linear(ctxt, c->dst.addr.mem),
-					&c->dst.val,
-					c->dst.bytes,
-					&ctxt->exception,
-					ctxt->vcpu);
+			rc = segmented_write(ctxt,
+					     c->dst.addr.mem,
+					     &c->dst.val,
+					     c->dst.bytes);
 		if (rc != X86EMUL_CONTINUE)
 			return rc;
 		break;
+	case OP_XMM:
+		write_sse_reg(ctxt, &c->dst.vec_val, c->dst.addr.xmm);
+		break;
 	case OP_NONE:
 		/* no writeback */
 		break;
@@ -1107,21 +1389,21 @@
 	return X86EMUL_CONTINUE;
 }
 
-static inline void emulate_push(struct x86_emulate_ctxt *ctxt,
-				struct x86_emulate_ops *ops)
+static int em_push(struct x86_emulate_ctxt *ctxt)
 {
 	struct decode_cache *c = &ctxt->decode;
+	struct segmented_address addr;
 
-	c->dst.type  = OP_MEM;
-	c->dst.bytes = c->op_bytes;
-	c->dst.val = c->src.val;
 	register_address_increment(c, &c->regs[VCPU_REGS_RSP], -c->op_bytes);
-	c->dst.addr.mem.ea = register_address(c, c->regs[VCPU_REGS_RSP]);
-	c->dst.addr.mem.seg = VCPU_SREG_SS;
+	addr.ea = register_address(c, c->regs[VCPU_REGS_RSP]);
+	addr.seg = VCPU_SREG_SS;
+
+	/* Disable writeback. */
+	c->dst.type = OP_NONE;
+	return segmented_write(ctxt, addr, &c->src.val, c->op_bytes);
 }
 
 static int emulate_pop(struct x86_emulate_ctxt *ctxt,
-		       struct x86_emulate_ops *ops,
 		       void *dest, int len)
 {
 	struct decode_cache *c = &ctxt->decode;
@@ -1130,7 +1412,7 @@
 
 	addr.ea = register_address(c, c->regs[VCPU_REGS_RSP]);
 	addr.seg = VCPU_SREG_SS;
-	rc = read_emulated(ctxt, ops, linear(ctxt, addr), dest, len);
+	rc = segmented_read(ctxt, addr, dest, len);
 	if (rc != X86EMUL_CONTINUE)
 		return rc;
 
@@ -1138,6 +1420,13 @@
 	return rc;
 }
 
+static int em_pop(struct x86_emulate_ctxt *ctxt)
+{
+	struct decode_cache *c = &ctxt->decode;
+
+	return emulate_pop(ctxt, &c->dst.val, c->op_bytes);
+}
+
 static int emulate_popf(struct x86_emulate_ctxt *ctxt,
 		       struct x86_emulate_ops *ops,
 		       void *dest, int len)
@@ -1145,9 +1434,9 @@
 	int rc;
 	unsigned long val, change_mask;
 	int iopl = (ctxt->eflags & X86_EFLAGS_IOPL) >> IOPL_SHIFT;
-	int cpl = ops->cpl(ctxt->vcpu);
+	int cpl = ops->cpl(ctxt);
 
-	rc = emulate_pop(ctxt, ops, &val, len);
+	rc = emulate_pop(ctxt, &val, len);
 	if (rc != X86EMUL_CONTINUE)
 		return rc;
 
@@ -1179,14 +1468,24 @@
 	return rc;
 }
 
-static void emulate_push_sreg(struct x86_emulate_ctxt *ctxt,
-			      struct x86_emulate_ops *ops, int seg)
+static int em_popf(struct x86_emulate_ctxt *ctxt)
 {
 	struct decode_cache *c = &ctxt->decode;
 
-	c->src.val = ops->get_segment_selector(seg, ctxt->vcpu);
+	c->dst.type = OP_REG;
+	c->dst.addr.reg = &ctxt->eflags;
+	c->dst.bytes = c->op_bytes;
+	return emulate_popf(ctxt, ctxt->ops, &c->dst.val, c->op_bytes);
+}
 
-	emulate_push(ctxt, ops);
+static int emulate_push_sreg(struct x86_emulate_ctxt *ctxt,
+			     struct x86_emulate_ops *ops, int seg)
+{
+	struct decode_cache *c = &ctxt->decode;
+
+	c->src.val = get_segment_selector(ctxt, seg);
+
+	return em_push(ctxt);
 }
 
 static int emulate_pop_sreg(struct x86_emulate_ctxt *ctxt,
@@ -1196,7 +1495,7 @@
 	unsigned long selector;
 	int rc;
 
-	rc = emulate_pop(ctxt, ops, &selector, c->op_bytes);
+	rc = emulate_pop(ctxt, &selector, c->op_bytes);
 	if (rc != X86EMUL_CONTINUE)
 		return rc;
 
@@ -1204,8 +1503,7 @@
 	return rc;
 }
 
-static int emulate_pusha(struct x86_emulate_ctxt *ctxt,
-			  struct x86_emulate_ops *ops)
+static int em_pusha(struct x86_emulate_ctxt *ctxt)
 {
 	struct decode_cache *c = &ctxt->decode;
 	unsigned long old_esp = c->regs[VCPU_REGS_RSP];
@@ -1216,23 +1514,25 @@
 		(reg == VCPU_REGS_RSP) ?
 		(c->src.val = old_esp) : (c->src.val = c->regs[reg]);
 
-		emulate_push(ctxt, ops);
-
-		rc = writeback(ctxt, ops);
+		rc = em_push(ctxt);
 		if (rc != X86EMUL_CONTINUE)
 			return rc;
 
 		++reg;
 	}
 
-	/* Disable writeback. */
-	c->dst.type = OP_NONE;
-
 	return rc;
 }
 
-static int emulate_popa(struct x86_emulate_ctxt *ctxt,
-			struct x86_emulate_ops *ops)
+static int em_pushf(struct x86_emulate_ctxt *ctxt)
+{
+	struct decode_cache *c = &ctxt->decode;
+
+	c->src.val =  (unsigned long)ctxt->eflags;
+	return em_push(ctxt);
+}
+
+static int em_popa(struct x86_emulate_ctxt *ctxt)
 {
 	struct decode_cache *c = &ctxt->decode;
 	int rc = X86EMUL_CONTINUE;
@@ -1245,7 +1545,7 @@
 			--reg;
 		}
 
-		rc = emulate_pop(ctxt, ops, &c->regs[reg], c->op_bytes);
+		rc = emulate_pop(ctxt, &c->regs[reg], c->op_bytes);
 		if (rc != X86EMUL_CONTINUE)
 			break;
 		--reg;
@@ -1265,37 +1565,32 @@
 
 	/* TODO: Add limit checks */
 	c->src.val = ctxt->eflags;
-	emulate_push(ctxt, ops);
-	rc = writeback(ctxt, ops);
+	rc = em_push(ctxt);
 	if (rc != X86EMUL_CONTINUE)
 		return rc;
 
 	ctxt->eflags &= ~(EFLG_IF | EFLG_TF | EFLG_AC);
 
-	c->src.val = ops->get_segment_selector(VCPU_SREG_CS, ctxt->vcpu);
-	emulate_push(ctxt, ops);
-	rc = writeback(ctxt, ops);
+	c->src.val = get_segment_selector(ctxt, VCPU_SREG_CS);
+	rc = em_push(ctxt);
 	if (rc != X86EMUL_CONTINUE)
 		return rc;
 
 	c->src.val = c->eip;
-	emulate_push(ctxt, ops);
-	rc = writeback(ctxt, ops);
+	rc = em_push(ctxt);
 	if (rc != X86EMUL_CONTINUE)
 		return rc;
 
-	c->dst.type = OP_NONE;
-
-	ops->get_idt(&dt, ctxt->vcpu);
+	ops->get_idt(ctxt, &dt);
 
 	eip_addr = dt.address + (irq << 2);
 	cs_addr = dt.address + (irq << 2) + 2;
 
-	rc = ops->read_std(cs_addr, &cs, 2, ctxt->vcpu, &ctxt->exception);
+	rc = ops->read_std(ctxt, cs_addr, &cs, 2, &ctxt->exception);
 	if (rc != X86EMUL_CONTINUE)
 		return rc;
 
-	rc = ops->read_std(eip_addr, &eip, 2, ctxt->vcpu, &ctxt->exception);
+	rc = ops->read_std(ctxt, eip_addr, &eip, 2, &ctxt->exception);
 	if (rc != X86EMUL_CONTINUE)
 		return rc;
 
@@ -1339,7 +1634,7 @@
 
 	/* TODO: Add stack limit check */
 
-	rc = emulate_pop(ctxt, ops, &temp_eip, c->op_bytes);
+	rc = emulate_pop(ctxt, &temp_eip, c->op_bytes);
 
 	if (rc != X86EMUL_CONTINUE)
 		return rc;
@@ -1347,12 +1642,12 @@
 	if (temp_eip & ~0xffff)
 		return emulate_gp(ctxt, 0);
 
-	rc = emulate_pop(ctxt, ops, &cs, c->op_bytes);
+	rc = emulate_pop(ctxt, &cs, c->op_bytes);
 
 	if (rc != X86EMUL_CONTINUE)
 		return rc;
 
-	rc = emulate_pop(ctxt, ops, &temp_eflags, c->op_bytes);
+	rc = emulate_pop(ctxt, &temp_eflags, c->op_bytes);
 
 	if (rc != X86EMUL_CONTINUE)
 		return rc;
@@ -1394,15 +1689,31 @@
 	}
 }
 
-static inline int emulate_grp1a(struct x86_emulate_ctxt *ctxt,
-				struct x86_emulate_ops *ops)
+static int em_jmp_far(struct x86_emulate_ctxt *ctxt)
 {
 	struct decode_cache *c = &ctxt->decode;
+	int rc;
+	unsigned short sel;
 
-	return emulate_pop(ctxt, ops, &c->dst.val, c->dst.bytes);
+	memcpy(&sel, c->src.valptr + c->op_bytes, 2);
+
+	rc = load_segment_descriptor(ctxt, ctxt->ops, sel, VCPU_SREG_CS);
+	if (rc != X86EMUL_CONTINUE)
+		return rc;
+
+	c->eip = 0;
+	memcpy(&c->eip, c->src.valptr, c->op_bytes);
+	return X86EMUL_CONTINUE;
 }
 
-static inline void emulate_grp2(struct x86_emulate_ctxt *ctxt)
+static int em_grp1a(struct x86_emulate_ctxt *ctxt)
+{
+	struct decode_cache *c = &ctxt->decode;
+
+	return emulate_pop(ctxt, &c->dst.val, c->dst.bytes);
+}
+
+static int em_grp2(struct x86_emulate_ctxt *ctxt)
 {
 	struct decode_cache *c = &ctxt->decode;
 	switch (c->modrm_reg) {
@@ -1429,10 +1740,10 @@
 		emulate_2op_SrcB("sar", c->src, c->dst, ctxt->eflags);
 		break;
 	}
+	return X86EMUL_CONTINUE;
 }
 
-static inline int emulate_grp3(struct x86_emulate_ctxt *ctxt,
-			       struct x86_emulate_ops *ops)
+static int em_grp3(struct x86_emulate_ctxt *ctxt)
 {
 	struct decode_cache *c = &ctxt->decode;
 	unsigned long *rax = &c->regs[VCPU_REGS_RAX];
@@ -1471,10 +1782,10 @@
 	return X86EMUL_CONTINUE;
 }
 
-static inline int emulate_grp45(struct x86_emulate_ctxt *ctxt,
-			       struct x86_emulate_ops *ops)
+static int em_grp45(struct x86_emulate_ctxt *ctxt)
 {
 	struct decode_cache *c = &ctxt->decode;
+	int rc = X86EMUL_CONTINUE;
 
 	switch (c->modrm_reg) {
 	case 0:	/* inc */
@@ -1488,21 +1799,23 @@
 		old_eip = c->eip;
 		c->eip = c->src.val;
 		c->src.val = old_eip;
-		emulate_push(ctxt, ops);
+		rc = em_push(ctxt);
 		break;
 	}
 	case 4: /* jmp abs */
 		c->eip = c->src.val;
 		break;
+	case 5: /* jmp far */
+		rc = em_jmp_far(ctxt);
+		break;
 	case 6:	/* push */
-		emulate_push(ctxt, ops);
+		rc = em_push(ctxt);
 		break;
 	}
-	return X86EMUL_CONTINUE;
+	return rc;
 }
 
-static inline int emulate_grp9(struct x86_emulate_ctxt *ctxt,
-			       struct x86_emulate_ops *ops)
+static int em_grp9(struct x86_emulate_ctxt *ctxt)
 {
 	struct decode_cache *c = &ctxt->decode;
 	u64 old = c->dst.orig_val64;
@@ -1528,12 +1841,12 @@
 	int rc;
 	unsigned long cs;
 
-	rc = emulate_pop(ctxt, ops, &c->eip, c->op_bytes);
+	rc = emulate_pop(ctxt, &c->eip, c->op_bytes);
 	if (rc != X86EMUL_CONTINUE)
 		return rc;
 	if (c->op_bytes == 4)
 		c->eip = (u32)c->eip;
-	rc = emulate_pop(ctxt, ops, &cs, c->op_bytes);
+	rc = emulate_pop(ctxt, &cs, c->op_bytes);
 	if (rc != X86EMUL_CONTINUE)
 		return rc;
 	rc = load_segment_descriptor(ctxt, ops, (u16)cs, VCPU_SREG_CS);
@@ -1562,8 +1875,10 @@
 			struct x86_emulate_ops *ops, struct desc_struct *cs,
 			struct desc_struct *ss)
 {
+	u16 selector;
+
 	memset(cs, 0, sizeof(struct desc_struct));
-	ops->get_cached_descriptor(cs, NULL, VCPU_SREG_CS, ctxt->vcpu);
+	ops->get_segment(ctxt, &selector, cs, NULL, VCPU_SREG_CS);
 	memset(ss, 0, sizeof(struct desc_struct));
 
 	cs->l = 0;		/* will be adjusted later */
@@ -1593,44 +1908,44 @@
 	struct desc_struct cs, ss;
 	u64 msr_data;
 	u16 cs_sel, ss_sel;
+	u64 efer = 0;
 
 	/* syscall is not available in real mode */
 	if (ctxt->mode == X86EMUL_MODE_REAL ||
 	    ctxt->mode == X86EMUL_MODE_VM86)
 		return emulate_ud(ctxt);
 
+	ops->get_msr(ctxt, MSR_EFER, &efer);
 	setup_syscalls_segments(ctxt, ops, &cs, &ss);
 
-	ops->get_msr(ctxt->vcpu, MSR_STAR, &msr_data);
+	ops->get_msr(ctxt, MSR_STAR, &msr_data);
 	msr_data >>= 32;
 	cs_sel = (u16)(msr_data & 0xfffc);
 	ss_sel = (u16)(msr_data + 8);
 
-	if (is_long_mode(ctxt->vcpu)) {
+	if (efer & EFER_LMA) {
 		cs.d = 0;
 		cs.l = 1;
 	}
-	ops->set_cached_descriptor(&cs, 0, VCPU_SREG_CS, ctxt->vcpu);
-	ops->set_segment_selector(cs_sel, VCPU_SREG_CS, ctxt->vcpu);
-	ops->set_cached_descriptor(&ss, 0, VCPU_SREG_SS, ctxt->vcpu);
-	ops->set_segment_selector(ss_sel, VCPU_SREG_SS, ctxt->vcpu);
+	ops->set_segment(ctxt, cs_sel, &cs, 0, VCPU_SREG_CS);
+	ops->set_segment(ctxt, ss_sel, &ss, 0, VCPU_SREG_SS);
 
 	c->regs[VCPU_REGS_RCX] = c->eip;
-	if (is_long_mode(ctxt->vcpu)) {
+	if (efer & EFER_LMA) {
 #ifdef CONFIG_X86_64
 		c->regs[VCPU_REGS_R11] = ctxt->eflags & ~EFLG_RF;
 
-		ops->get_msr(ctxt->vcpu,
+		ops->get_msr(ctxt,
 			     ctxt->mode == X86EMUL_MODE_PROT64 ?
 			     MSR_LSTAR : MSR_CSTAR, &msr_data);
 		c->eip = msr_data;
 
-		ops->get_msr(ctxt->vcpu, MSR_SYSCALL_MASK, &msr_data);
+		ops->get_msr(ctxt, MSR_SYSCALL_MASK, &msr_data);
 		ctxt->eflags &= ~(msr_data | EFLG_RF);
 #endif
 	} else {
 		/* legacy mode */
-		ops->get_msr(ctxt->vcpu, MSR_STAR, &msr_data);
+		ops->get_msr(ctxt, MSR_STAR, &msr_data);
 		c->eip = (u32)msr_data;
 
 		ctxt->eflags &= ~(EFLG_VM | EFLG_IF | EFLG_RF);
@@ -1646,7 +1961,9 @@
 	struct desc_struct cs, ss;
 	u64 msr_data;
 	u16 cs_sel, ss_sel;
+	u64 efer = 0;
 
+	ctxt->ops->get_msr(ctxt, MSR_EFER, &efer);
 	/* inject #GP if in real mode */
 	if (ctxt->mode == X86EMUL_MODE_REAL)
 		return emulate_gp(ctxt, 0);
@@ -1659,7 +1976,7 @@
 
 	setup_syscalls_segments(ctxt, ops, &cs, &ss);
 
-	ops->get_msr(ctxt->vcpu, MSR_IA32_SYSENTER_CS, &msr_data);
+	ops->get_msr(ctxt, MSR_IA32_SYSENTER_CS, &msr_data);
 	switch (ctxt->mode) {
 	case X86EMUL_MODE_PROT32:
 		if ((msr_data & 0xfffc) == 0x0)
@@ -1676,21 +1993,18 @@
 	cs_sel &= ~SELECTOR_RPL_MASK;
 	ss_sel = cs_sel + 8;
 	ss_sel &= ~SELECTOR_RPL_MASK;
-	if (ctxt->mode == X86EMUL_MODE_PROT64
-		|| is_long_mode(ctxt->vcpu)) {
+	if (ctxt->mode == X86EMUL_MODE_PROT64 || (efer & EFER_LMA)) {
 		cs.d = 0;
 		cs.l = 1;
 	}
 
-	ops->set_cached_descriptor(&cs, 0, VCPU_SREG_CS, ctxt->vcpu);
-	ops->set_segment_selector(cs_sel, VCPU_SREG_CS, ctxt->vcpu);
-	ops->set_cached_descriptor(&ss, 0, VCPU_SREG_SS, ctxt->vcpu);
-	ops->set_segment_selector(ss_sel, VCPU_SREG_SS, ctxt->vcpu);
+	ops->set_segment(ctxt, cs_sel, &cs, 0, VCPU_SREG_CS);
+	ops->set_segment(ctxt, ss_sel, &ss, 0, VCPU_SREG_SS);
 
-	ops->get_msr(ctxt->vcpu, MSR_IA32_SYSENTER_EIP, &msr_data);
+	ops->get_msr(ctxt, MSR_IA32_SYSENTER_EIP, &msr_data);
 	c->eip = msr_data;
 
-	ops->get_msr(ctxt->vcpu, MSR_IA32_SYSENTER_ESP, &msr_data);
+	ops->get_msr(ctxt, MSR_IA32_SYSENTER_ESP, &msr_data);
 	c->regs[VCPU_REGS_RSP] = msr_data;
 
 	return X86EMUL_CONTINUE;
@@ -1719,7 +2033,7 @@
 
 	cs.dpl = 3;
 	ss.dpl = 3;
-	ops->get_msr(ctxt->vcpu, MSR_IA32_SYSENTER_CS, &msr_data);
+	ops->get_msr(ctxt, MSR_IA32_SYSENTER_CS, &msr_data);
 	switch (usermode) {
 	case X86EMUL_MODE_PROT32:
 		cs_sel = (u16)(msr_data + 16);
@@ -1739,10 +2053,8 @@
 	cs_sel |= SELECTOR_RPL_MASK;
 	ss_sel |= SELECTOR_RPL_MASK;
 
-	ops->set_cached_descriptor(&cs, 0, VCPU_SREG_CS, ctxt->vcpu);
-	ops->set_segment_selector(cs_sel, VCPU_SREG_CS, ctxt->vcpu);
-	ops->set_cached_descriptor(&ss, 0, VCPU_SREG_SS, ctxt->vcpu);
-	ops->set_segment_selector(ss_sel, VCPU_SREG_SS, ctxt->vcpu);
+	ops->set_segment(ctxt, cs_sel, &cs, 0, VCPU_SREG_CS);
+	ops->set_segment(ctxt, ss_sel, &ss, 0, VCPU_SREG_SS);
 
 	c->eip = c->regs[VCPU_REGS_RDX];
 	c->regs[VCPU_REGS_RSP] = c->regs[VCPU_REGS_RCX];
@@ -1759,7 +2071,7 @@
 	if (ctxt->mode == X86EMUL_MODE_VM86)
 		return true;
 	iopl = (ctxt->eflags & X86_EFLAGS_IOPL) >> IOPL_SHIFT;
-	return ops->cpl(ctxt->vcpu) > iopl;
+	return ops->cpl(ctxt) > iopl;
 }
 
 static bool emulator_io_port_access_allowed(struct x86_emulate_ctxt *ctxt,
@@ -1769,11 +2081,11 @@
 	struct desc_struct tr_seg;
 	u32 base3;
 	int r;
-	u16 io_bitmap_ptr, perm, bit_idx = port & 0x7;
+	u16 tr, io_bitmap_ptr, perm, bit_idx = port & 0x7;
 	unsigned mask = (1 << len) - 1;
 	unsigned long base;
 
-	ops->get_cached_descriptor(&tr_seg, &base3, VCPU_SREG_TR, ctxt->vcpu);
+	ops->get_segment(ctxt, &tr, &tr_seg, &base3, VCPU_SREG_TR);
 	if (!tr_seg.p)
 		return false;
 	if (desc_limit_scaled(&tr_seg) < 103)
@@ -1782,13 +2094,12 @@
 #ifdef CONFIG_X86_64
 	base |= ((u64)base3) << 32;
 #endif
-	r = ops->read_std(base + 102, &io_bitmap_ptr, 2, ctxt->vcpu, NULL);
+	r = ops->read_std(ctxt, base + 102, &io_bitmap_ptr, 2, NULL);
 	if (r != X86EMUL_CONTINUE)
 		return false;
 	if (io_bitmap_ptr + port/8 > desc_limit_scaled(&tr_seg))
 		return false;
-	r = ops->read_std(base + io_bitmap_ptr + port/8, &perm, 2, ctxt->vcpu,
-			  NULL);
+	r = ops->read_std(ctxt, base + io_bitmap_ptr + port/8, &perm, 2, NULL);
 	if (r != X86EMUL_CONTINUE)
 		return false;
 	if ((perm >> bit_idx) & mask)
@@ -1829,11 +2140,11 @@
 	tss->si = c->regs[VCPU_REGS_RSI];
 	tss->di = c->regs[VCPU_REGS_RDI];
 
-	tss->es = ops->get_segment_selector(VCPU_SREG_ES, ctxt->vcpu);
-	tss->cs = ops->get_segment_selector(VCPU_SREG_CS, ctxt->vcpu);
-	tss->ss = ops->get_segment_selector(VCPU_SREG_SS, ctxt->vcpu);
-	tss->ds = ops->get_segment_selector(VCPU_SREG_DS, ctxt->vcpu);
-	tss->ldt = ops->get_segment_selector(VCPU_SREG_LDTR, ctxt->vcpu);
+	tss->es = get_segment_selector(ctxt, VCPU_SREG_ES);
+	tss->cs = get_segment_selector(ctxt, VCPU_SREG_CS);
+	tss->ss = get_segment_selector(ctxt, VCPU_SREG_SS);
+	tss->ds = get_segment_selector(ctxt, VCPU_SREG_DS);
+	tss->ldt = get_segment_selector(ctxt, VCPU_SREG_LDTR);
 }
 
 static int load_state_from_tss16(struct x86_emulate_ctxt *ctxt,
@@ -1858,11 +2169,11 @@
 	 * SDM says that segment selectors are loaded before segment
 	 * descriptors
 	 */
-	ops->set_segment_selector(tss->ldt, VCPU_SREG_LDTR, ctxt->vcpu);
-	ops->set_segment_selector(tss->es, VCPU_SREG_ES, ctxt->vcpu);
-	ops->set_segment_selector(tss->cs, VCPU_SREG_CS, ctxt->vcpu);
-	ops->set_segment_selector(tss->ss, VCPU_SREG_SS, ctxt->vcpu);
-	ops->set_segment_selector(tss->ds, VCPU_SREG_DS, ctxt->vcpu);
+	set_segment_selector(ctxt, tss->ldt, VCPU_SREG_LDTR);
+	set_segment_selector(ctxt, tss->es, VCPU_SREG_ES);
+	set_segment_selector(ctxt, tss->cs, VCPU_SREG_CS);
+	set_segment_selector(ctxt, tss->ss, VCPU_SREG_SS);
+	set_segment_selector(ctxt, tss->ds, VCPU_SREG_DS);
 
 	/*
 	 * Now load segment descriptors. If fault happenes at this stage
@@ -1896,7 +2207,7 @@
 	int ret;
 	u32 new_tss_base = get_desc_base(new_desc);
 
-	ret = ops->read_std(old_tss_base, &tss_seg, sizeof tss_seg, ctxt->vcpu,
+	ret = ops->read_std(ctxt, old_tss_base, &tss_seg, sizeof tss_seg,
 			    &ctxt->exception);
 	if (ret != X86EMUL_CONTINUE)
 		/* FIXME: need to provide precise fault address */
@@ -1904,13 +2215,13 @@
 
 	save_state_to_tss16(ctxt, ops, &tss_seg);
 
-	ret = ops->write_std(old_tss_base, &tss_seg, sizeof tss_seg, ctxt->vcpu,
+	ret = ops->write_std(ctxt, old_tss_base, &tss_seg, sizeof tss_seg,
 			     &ctxt->exception);
 	if (ret != X86EMUL_CONTINUE)
 		/* FIXME: need to provide precise fault address */
 		return ret;
 
-	ret = ops->read_std(new_tss_base, &tss_seg, sizeof tss_seg, ctxt->vcpu,
+	ret = ops->read_std(ctxt, new_tss_base, &tss_seg, sizeof tss_seg,
 			    &ctxt->exception);
 	if (ret != X86EMUL_CONTINUE)
 		/* FIXME: need to provide precise fault address */
@@ -1919,10 +2230,10 @@
 	if (old_tss_sel != 0xffff) {
 		tss_seg.prev_task_link = old_tss_sel;
 
-		ret = ops->write_std(new_tss_base,
+		ret = ops->write_std(ctxt, new_tss_base,
 				     &tss_seg.prev_task_link,
 				     sizeof tss_seg.prev_task_link,
-				     ctxt->vcpu, &ctxt->exception);
+				     &ctxt->exception);
 		if (ret != X86EMUL_CONTINUE)
 			/* FIXME: need to provide precise fault address */
 			return ret;
@@ -1937,7 +2248,7 @@
 {
 	struct decode_cache *c = &ctxt->decode;
 
-	tss->cr3 = ops->get_cr(3, ctxt->vcpu);
+	tss->cr3 = ops->get_cr(ctxt, 3);
 	tss->eip = c->eip;
 	tss->eflags = ctxt->eflags;
 	tss->eax = c->regs[VCPU_REGS_RAX];
@@ -1949,13 +2260,13 @@
 	tss->esi = c->regs[VCPU_REGS_RSI];
 	tss->edi = c->regs[VCPU_REGS_RDI];
 
-	tss->es = ops->get_segment_selector(VCPU_SREG_ES, ctxt->vcpu);
-	tss->cs = ops->get_segment_selector(VCPU_SREG_CS, ctxt->vcpu);
-	tss->ss = ops->get_segment_selector(VCPU_SREG_SS, ctxt->vcpu);
-	tss->ds = ops->get_segment_selector(VCPU_SREG_DS, ctxt->vcpu);
-	tss->fs = ops->get_segment_selector(VCPU_SREG_FS, ctxt->vcpu);
-	tss->gs = ops->get_segment_selector(VCPU_SREG_GS, ctxt->vcpu);
-	tss->ldt_selector = ops->get_segment_selector(VCPU_SREG_LDTR, ctxt->vcpu);
+	tss->es = get_segment_selector(ctxt, VCPU_SREG_ES);
+	tss->cs = get_segment_selector(ctxt, VCPU_SREG_CS);
+	tss->ss = get_segment_selector(ctxt, VCPU_SREG_SS);
+	tss->ds = get_segment_selector(ctxt, VCPU_SREG_DS);
+	tss->fs = get_segment_selector(ctxt, VCPU_SREG_FS);
+	tss->gs = get_segment_selector(ctxt, VCPU_SREG_GS);
+	tss->ldt_selector = get_segment_selector(ctxt, VCPU_SREG_LDTR);
 }
 
 static int load_state_from_tss32(struct x86_emulate_ctxt *ctxt,
@@ -1965,7 +2276,7 @@
 	struct decode_cache *c = &ctxt->decode;
 	int ret;
 
-	if (ops->set_cr(3, tss->cr3, ctxt->vcpu))
+	if (ops->set_cr(ctxt, 3, tss->cr3))
 		return emulate_gp(ctxt, 0);
 	c->eip = tss->eip;
 	ctxt->eflags = tss->eflags | 2;
@@ -1982,13 +2293,13 @@
 	 * SDM says that segment selectors are loaded before segment
 	 * descriptors
 	 */
-	ops->set_segment_selector(tss->ldt_selector, VCPU_SREG_LDTR, ctxt->vcpu);
-	ops->set_segment_selector(tss->es, VCPU_SREG_ES, ctxt->vcpu);
-	ops->set_segment_selector(tss->cs, VCPU_SREG_CS, ctxt->vcpu);
-	ops->set_segment_selector(tss->ss, VCPU_SREG_SS, ctxt->vcpu);
-	ops->set_segment_selector(tss->ds, VCPU_SREG_DS, ctxt->vcpu);
-	ops->set_segment_selector(tss->fs, VCPU_SREG_FS, ctxt->vcpu);
-	ops->set_segment_selector(tss->gs, VCPU_SREG_GS, ctxt->vcpu);
+	set_segment_selector(ctxt, tss->ldt_selector, VCPU_SREG_LDTR);
+	set_segment_selector(ctxt, tss->es, VCPU_SREG_ES);
+	set_segment_selector(ctxt, tss->cs, VCPU_SREG_CS);
+	set_segment_selector(ctxt, tss->ss, VCPU_SREG_SS);
+	set_segment_selector(ctxt, tss->ds, VCPU_SREG_DS);
+	set_segment_selector(ctxt, tss->fs, VCPU_SREG_FS);
+	set_segment_selector(ctxt, tss->gs, VCPU_SREG_GS);
 
 	/*
 	 * Now load segment descriptors. If fault happenes at this stage
@@ -2028,7 +2339,7 @@
 	int ret;
 	u32 new_tss_base = get_desc_base(new_desc);
 
-	ret = ops->read_std(old_tss_base, &tss_seg, sizeof tss_seg, ctxt->vcpu,
+	ret = ops->read_std(ctxt, old_tss_base, &tss_seg, sizeof tss_seg,
 			    &ctxt->exception);
 	if (ret != X86EMUL_CONTINUE)
 		/* FIXME: need to provide precise fault address */
@@ -2036,13 +2347,13 @@
 
 	save_state_to_tss32(ctxt, ops, &tss_seg);
 
-	ret = ops->write_std(old_tss_base, &tss_seg, sizeof tss_seg, ctxt->vcpu,
+	ret = ops->write_std(ctxt, old_tss_base, &tss_seg, sizeof tss_seg,
 			     &ctxt->exception);
 	if (ret != X86EMUL_CONTINUE)
 		/* FIXME: need to provide precise fault address */
 		return ret;
 
-	ret = ops->read_std(new_tss_base, &tss_seg, sizeof tss_seg, ctxt->vcpu,
+	ret = ops->read_std(ctxt, new_tss_base, &tss_seg, sizeof tss_seg,
 			    &ctxt->exception);
 	if (ret != X86EMUL_CONTINUE)
 		/* FIXME: need to provide precise fault address */
@@ -2051,10 +2362,10 @@
 	if (old_tss_sel != 0xffff) {
 		tss_seg.prev_task_link = old_tss_sel;
 
-		ret = ops->write_std(new_tss_base,
+		ret = ops->write_std(ctxt, new_tss_base,
 				     &tss_seg.prev_task_link,
 				     sizeof tss_seg.prev_task_link,
-				     ctxt->vcpu, &ctxt->exception);
+				     &ctxt->exception);
 		if (ret != X86EMUL_CONTINUE)
 			/* FIXME: need to provide precise fault address */
 			return ret;
@@ -2070,9 +2381,9 @@
 {
 	struct desc_struct curr_tss_desc, next_tss_desc;
 	int ret;
-	u16 old_tss_sel = ops->get_segment_selector(VCPU_SREG_TR, ctxt->vcpu);
+	u16 old_tss_sel = get_segment_selector(ctxt, VCPU_SREG_TR);
 	ulong old_tss_base =
-		ops->get_cached_segment_base(VCPU_SREG_TR, ctxt->vcpu);
+		ops->get_cached_segment_base(ctxt, VCPU_SREG_TR);
 	u32 desc_limit;
 
 	/* FIXME: old_tss_base == ~0 ? */
@@ -2088,7 +2399,7 @@
 
 	if (reason != TASK_SWITCH_IRET) {
 		if ((tss_selector & 3) > next_tss_desc.dpl ||
-		    ops->cpl(ctxt->vcpu) > next_tss_desc.dpl)
+		    ops->cpl(ctxt) > next_tss_desc.dpl)
 			return emulate_gp(ctxt, 0);
 	}
 
@@ -2132,9 +2443,8 @@
 					 &next_tss_desc);
 	}
 
-	ops->set_cr(0,  ops->get_cr(0, ctxt->vcpu) | X86_CR0_TS, ctxt->vcpu);
-	ops->set_cached_descriptor(&next_tss_desc, 0, VCPU_SREG_TR, ctxt->vcpu);
-	ops->set_segment_selector(tss_selector, VCPU_SREG_TR, ctxt->vcpu);
+	ops->set_cr(ctxt, 0,  ops->get_cr(ctxt, 0) | X86_CR0_TS);
+	ops->set_segment(ctxt, tss_selector, &next_tss_desc, 0, VCPU_SREG_TR);
 
 	if (has_error_code) {
 		struct decode_cache *c = &ctxt->decode;
@@ -2142,7 +2452,7 @@
 		c->op_bytes = c->ad_bytes = (next_tss_desc.type & 8) ? 4 : 2;
 		c->lock_prefix = 0;
 		c->src.val = (unsigned long) error_code;
-		emulate_push(ctxt, ops);
+		ret = em_push(ctxt);
 	}
 
 	return ret;
@@ -2162,13 +2472,10 @@
 	rc = emulator_do_task_switch(ctxt, ops, tss_selector, reason,
 				     has_error_code, error_code);
 
-	if (rc == X86EMUL_CONTINUE) {
-		rc = writeback(ctxt, ops);
-		if (rc == X86EMUL_CONTINUE)
-			ctxt->eip = c->eip;
-	}
+	if (rc == X86EMUL_CONTINUE)
+		ctxt->eip = c->eip;
 
-	return (rc == X86EMUL_UNHANDLEABLE) ? -1 : 0;
+	return (rc == X86EMUL_UNHANDLEABLE) ? EMULATION_FAILED : EMULATION_OK;
 }
 
 static void string_addr_inc(struct x86_emulate_ctxt *ctxt, unsigned seg,
@@ -2182,12 +2489,6 @@
 	op->addr.mem.seg = seg;
 }
 
-static int em_push(struct x86_emulate_ctxt *ctxt)
-{
-	emulate_push(ctxt, ctxt->ops);
-	return X86EMUL_CONTINUE;
-}
-
 static int em_das(struct x86_emulate_ctxt *ctxt)
 {
 	struct decode_cache *c = &ctxt->decode;
@@ -2234,7 +2535,7 @@
 	ulong old_eip;
 	int rc;
 
-	old_cs = ctxt->ops->get_segment_selector(VCPU_SREG_CS, ctxt->vcpu);
+	old_cs = get_segment_selector(ctxt, VCPU_SREG_CS);
 	old_eip = c->eip;
 
 	memcpy(&sel, c->src.valptr + c->op_bytes, 2);
@@ -2245,20 +2546,12 @@
 	memcpy(&c->eip, c->src.valptr, c->op_bytes);
 
 	c->src.val = old_cs;
-	emulate_push(ctxt, ctxt->ops);
-	rc = writeback(ctxt, ctxt->ops);
+	rc = em_push(ctxt);
 	if (rc != X86EMUL_CONTINUE)
 		return rc;
 
 	c->src.val = old_eip;
-	emulate_push(ctxt, ctxt->ops);
-	rc = writeback(ctxt, ctxt->ops);
-	if (rc != X86EMUL_CONTINUE)
-		return rc;
-
-	c->dst.type = OP_NONE;
-
-	return X86EMUL_CONTINUE;
+	return em_push(ctxt);
 }
 
 static int em_ret_near_imm(struct x86_emulate_ctxt *ctxt)
@@ -2269,13 +2562,79 @@
 	c->dst.type = OP_REG;
 	c->dst.addr.reg = &c->eip;
 	c->dst.bytes = c->op_bytes;
-	rc = emulate_pop(ctxt, ctxt->ops, &c->dst.val, c->op_bytes);
+	rc = emulate_pop(ctxt, &c->dst.val, c->op_bytes);
 	if (rc != X86EMUL_CONTINUE)
 		return rc;
 	register_address_increment(c, &c->regs[VCPU_REGS_RSP], c->src.val);
 	return X86EMUL_CONTINUE;
 }
 
+static int em_add(struct x86_emulate_ctxt *ctxt)
+{
+	struct decode_cache *c = &ctxt->decode;
+
+	emulate_2op_SrcV("add", c->src, c->dst, ctxt->eflags);
+	return X86EMUL_CONTINUE;
+}
+
+static int em_or(struct x86_emulate_ctxt *ctxt)
+{
+	struct decode_cache *c = &ctxt->decode;
+
+	emulate_2op_SrcV("or", c->src, c->dst, ctxt->eflags);
+	return X86EMUL_CONTINUE;
+}
+
+static int em_adc(struct x86_emulate_ctxt *ctxt)
+{
+	struct decode_cache *c = &ctxt->decode;
+
+	emulate_2op_SrcV("adc", c->src, c->dst, ctxt->eflags);
+	return X86EMUL_CONTINUE;
+}
+
+static int em_sbb(struct x86_emulate_ctxt *ctxt)
+{
+	struct decode_cache *c = &ctxt->decode;
+
+	emulate_2op_SrcV("sbb", c->src, c->dst, ctxt->eflags);
+	return X86EMUL_CONTINUE;
+}
+
+static int em_and(struct x86_emulate_ctxt *ctxt)
+{
+	struct decode_cache *c = &ctxt->decode;
+
+	emulate_2op_SrcV("and", c->src, c->dst, ctxt->eflags);
+	return X86EMUL_CONTINUE;
+}
+
+static int em_sub(struct x86_emulate_ctxt *ctxt)
+{
+	struct decode_cache *c = &ctxt->decode;
+
+	emulate_2op_SrcV("sub", c->src, c->dst, ctxt->eflags);
+	return X86EMUL_CONTINUE;
+}
+
+static int em_xor(struct x86_emulate_ctxt *ctxt)
+{
+	struct decode_cache *c = &ctxt->decode;
+
+	emulate_2op_SrcV("xor", c->src, c->dst, ctxt->eflags);
+	return X86EMUL_CONTINUE;
+}
+
+static int em_cmp(struct x86_emulate_ctxt *ctxt)
+{
+	struct decode_cache *c = &ctxt->decode;
+
+	emulate_2op_SrcV("cmp", c->src, c->dst, ctxt->eflags);
+	/* Disable writeback. */
+	c->dst.type = OP_NONE;
+	return X86EMUL_CONTINUE;
+}
+
 static int em_imul(struct x86_emulate_ctxt *ctxt)
 {
 	struct decode_cache *c = &ctxt->decode;
@@ -2306,13 +2665,10 @@
 
 static int em_rdtsc(struct x86_emulate_ctxt *ctxt)
 {
-	unsigned cpl = ctxt->ops->cpl(ctxt->vcpu);
 	struct decode_cache *c = &ctxt->decode;
 	u64 tsc = 0;
 
-	if (cpl > 0 && (ctxt->ops->get_cr(4, ctxt->vcpu) & X86_CR4_TSD))
-		return emulate_gp(ctxt, 0);
-	ctxt->ops->get_msr(ctxt->vcpu, MSR_IA32_TSC, &tsc);
+	ctxt->ops->get_msr(ctxt, MSR_IA32_TSC, &tsc);
 	c->regs[VCPU_REGS_RAX] = (u32)tsc;
 	c->regs[VCPU_REGS_RDX] = tsc >> 32;
 	return X86EMUL_CONTINUE;
@@ -2325,22 +2681,375 @@
 	return X86EMUL_CONTINUE;
 }
 
+static int em_movdqu(struct x86_emulate_ctxt *ctxt)
+{
+	struct decode_cache *c = &ctxt->decode;
+	memcpy(&c->dst.vec_val, &c->src.vec_val, c->op_bytes);
+	return X86EMUL_CONTINUE;
+}
+
+static int em_invlpg(struct x86_emulate_ctxt *ctxt)
+{
+	struct decode_cache *c = &ctxt->decode;
+	int rc;
+	ulong linear;
+
+	rc = linearize(ctxt, c->src.addr.mem, 1, false, &linear);
+	if (rc == X86EMUL_CONTINUE)
+		ctxt->ops->invlpg(ctxt, linear);
+	/* Disable writeback. */
+	c->dst.type = OP_NONE;
+	return X86EMUL_CONTINUE;
+}
+
+static int em_clts(struct x86_emulate_ctxt *ctxt)
+{
+	ulong cr0;
+
+	cr0 = ctxt->ops->get_cr(ctxt, 0);
+	cr0 &= ~X86_CR0_TS;
+	ctxt->ops->set_cr(ctxt, 0, cr0);
+	return X86EMUL_CONTINUE;
+}
+
+static int em_vmcall(struct x86_emulate_ctxt *ctxt)
+{
+	struct decode_cache *c = &ctxt->decode;
+	int rc;
+
+	if (c->modrm_mod != 3 || c->modrm_rm != 1)
+		return X86EMUL_UNHANDLEABLE;
+
+	rc = ctxt->ops->fix_hypercall(ctxt);
+	if (rc != X86EMUL_CONTINUE)
+		return rc;
+
+	/* Let the processor re-execute the fixed hypercall */
+	c->eip = ctxt->eip;
+	/* Disable writeback. */
+	c->dst.type = OP_NONE;
+	return X86EMUL_CONTINUE;
+}
+
+static int em_lgdt(struct x86_emulate_ctxt *ctxt)
+{
+	struct decode_cache *c = &ctxt->decode;
+	struct desc_ptr desc_ptr;
+	int rc;
+
+	rc = read_descriptor(ctxt, c->src.addr.mem,
+			     &desc_ptr.size, &desc_ptr.address,
+			     c->op_bytes);
+	if (rc != X86EMUL_CONTINUE)
+		return rc;
+	ctxt->ops->set_gdt(ctxt, &desc_ptr);
+	/* Disable writeback. */
+	c->dst.type = OP_NONE;
+	return X86EMUL_CONTINUE;
+}
+
+static int em_vmmcall(struct x86_emulate_ctxt *ctxt)
+{
+	struct decode_cache *c = &ctxt->decode;
+	int rc;
+
+	rc = ctxt->ops->fix_hypercall(ctxt);
+
+	/* Disable writeback. */
+	c->dst.type = OP_NONE;
+	return rc;
+}
+
+static int em_lidt(struct x86_emulate_ctxt *ctxt)
+{
+	struct decode_cache *c = &ctxt->decode;
+	struct desc_ptr desc_ptr;
+	int rc;
+
+	rc = read_descriptor(ctxt, c->src.addr.mem,
+			     &desc_ptr.size, &desc_ptr.address,
+			     c->op_bytes);
+	if (rc != X86EMUL_CONTINUE)
+		return rc;
+	ctxt->ops->set_idt(ctxt, &desc_ptr);
+	/* Disable writeback. */
+	c->dst.type = OP_NONE;
+	return X86EMUL_CONTINUE;
+}
+
+static int em_smsw(struct x86_emulate_ctxt *ctxt)
+{
+	struct decode_cache *c = &ctxt->decode;
+
+	c->dst.bytes = 2;
+	c->dst.val = ctxt->ops->get_cr(ctxt, 0);
+	return X86EMUL_CONTINUE;
+}
+
+static int em_lmsw(struct x86_emulate_ctxt *ctxt)
+{
+	struct decode_cache *c = &ctxt->decode;
+	ctxt->ops->set_cr(ctxt, 0, (ctxt->ops->get_cr(ctxt, 0) & ~0x0eul)
+			  | (c->src.val & 0x0f));
+	c->dst.type = OP_NONE;
+	return X86EMUL_CONTINUE;
+}
+
+static bool valid_cr(int nr)
+{
+	switch (nr) {
+	case 0:
+	case 2 ... 4:
+	case 8:
+		return true;
+	default:
+		return false;
+	}
+}
+
+static int check_cr_read(struct x86_emulate_ctxt *ctxt)
+{
+	struct decode_cache *c = &ctxt->decode;
+
+	if (!valid_cr(c->modrm_reg))
+		return emulate_ud(ctxt);
+
+	return X86EMUL_CONTINUE;
+}
+
+static int check_cr_write(struct x86_emulate_ctxt *ctxt)
+{
+	struct decode_cache *c = &ctxt->decode;
+	u64 new_val = c->src.val64;
+	int cr = c->modrm_reg;
+	u64 efer = 0;
+
+	static u64 cr_reserved_bits[] = {
+		0xffffffff00000000ULL,
+		0, 0, 0, /* CR3 checked later */
+		CR4_RESERVED_BITS,
+		0, 0, 0,
+		CR8_RESERVED_BITS,
+	};
+
+	if (!valid_cr(cr))
+		return emulate_ud(ctxt);
+
+	if (new_val & cr_reserved_bits[cr])
+		return emulate_gp(ctxt, 0);
+
+	switch (cr) {
+	case 0: {
+		u64 cr4;
+		if (((new_val & X86_CR0_PG) && !(new_val & X86_CR0_PE)) ||
+		    ((new_val & X86_CR0_NW) && !(new_val & X86_CR0_CD)))
+			return emulate_gp(ctxt, 0);
+
+		cr4 = ctxt->ops->get_cr(ctxt, 4);
+		ctxt->ops->get_msr(ctxt, MSR_EFER, &efer);
+
+		if ((new_val & X86_CR0_PG) && (efer & EFER_LME) &&
+		    !(cr4 & X86_CR4_PAE))
+			return emulate_gp(ctxt, 0);
+
+		break;
+		}
+	case 3: {
+		u64 rsvd = 0;
+
+		ctxt->ops->get_msr(ctxt, MSR_EFER, &efer);
+		if (efer & EFER_LMA)
+			rsvd = CR3_L_MODE_RESERVED_BITS;
+		else if (ctxt->ops->get_cr(ctxt, 4) & X86_CR4_PAE)
+			rsvd = CR3_PAE_RESERVED_BITS;
+		else if (ctxt->ops->get_cr(ctxt, 0) & X86_CR0_PG)
+			rsvd = CR3_NONPAE_RESERVED_BITS;
+
+		if (new_val & rsvd)
+			return emulate_gp(ctxt, 0);
+
+		break;
+		}
+	case 4: {
+		u64 cr4;
+
+		cr4 = ctxt->ops->get_cr(ctxt, 4);
+		ctxt->ops->get_msr(ctxt, MSR_EFER, &efer);
+
+		if ((efer & EFER_LMA) && !(new_val & X86_CR4_PAE))
+			return emulate_gp(ctxt, 0);
+
+		break;
+		}
+	}
+
+	return X86EMUL_CONTINUE;
+}
+
+static int check_dr7_gd(struct x86_emulate_ctxt *ctxt)
+{
+	unsigned long dr7;
+
+	ctxt->ops->get_dr(ctxt, 7, &dr7);
+
+	/* Check if DR7.Global_Enable is set */
+	return dr7 & (1 << 13);
+}
+
+static int check_dr_read(struct x86_emulate_ctxt *ctxt)
+{
+	struct decode_cache *c = &ctxt->decode;
+	int dr = c->modrm_reg;
+	u64 cr4;
+
+	if (dr > 7)
+		return emulate_ud(ctxt);
+
+	cr4 = ctxt->ops->get_cr(ctxt, 4);
+	if ((cr4 & X86_CR4_DE) && (dr == 4 || dr == 5))
+		return emulate_ud(ctxt);
+
+	if (check_dr7_gd(ctxt))
+		return emulate_db(ctxt);
+
+	return X86EMUL_CONTINUE;
+}
+
+static int check_dr_write(struct x86_emulate_ctxt *ctxt)
+{
+	struct decode_cache *c = &ctxt->decode;
+	u64 new_val = c->src.val64;
+	int dr = c->modrm_reg;
+
+	if ((dr == 6 || dr == 7) && (new_val & 0xffffffff00000000ULL))
+		return emulate_gp(ctxt, 0);
+
+	return check_dr_read(ctxt);
+}
+
+static int check_svme(struct x86_emulate_ctxt *ctxt)
+{
+	u64 efer;
+
+	ctxt->ops->get_msr(ctxt, MSR_EFER, &efer);
+
+	if (!(efer & EFER_SVME))
+		return emulate_ud(ctxt);
+
+	return X86EMUL_CONTINUE;
+}
+
+static int check_svme_pa(struct x86_emulate_ctxt *ctxt)
+{
+	u64 rax = ctxt->decode.regs[VCPU_REGS_RAX];
+
+	/* Valid physical address? */
+	if (rax & 0xffff000000000000ULL)
+		return emulate_gp(ctxt, 0);
+
+	return check_svme(ctxt);
+}
+
+static int check_rdtsc(struct x86_emulate_ctxt *ctxt)
+{
+	u64 cr4 = ctxt->ops->get_cr(ctxt, 4);
+
+	if (cr4 & X86_CR4_TSD && ctxt->ops->cpl(ctxt))
+		return emulate_ud(ctxt);
+
+	return X86EMUL_CONTINUE;
+}
+
+static int check_rdpmc(struct x86_emulate_ctxt *ctxt)
+{
+	u64 cr4 = ctxt->ops->get_cr(ctxt, 4);
+	u64 rcx = ctxt->decode.regs[VCPU_REGS_RCX];
+
+	if ((!(cr4 & X86_CR4_PCE) && ctxt->ops->cpl(ctxt)) ||
+	    (rcx > 3))
+		return emulate_gp(ctxt, 0);
+
+	return X86EMUL_CONTINUE;
+}
+
+static int check_perm_in(struct x86_emulate_ctxt *ctxt)
+{
+	struct decode_cache *c = &ctxt->decode;
+
+	c->dst.bytes = min(c->dst.bytes, 4u);
+	if (!emulator_io_permited(ctxt, ctxt->ops, c->src.val, c->dst.bytes))
+		return emulate_gp(ctxt, 0);
+
+	return X86EMUL_CONTINUE;
+}
+
+static int check_perm_out(struct x86_emulate_ctxt *ctxt)
+{
+	struct decode_cache *c = &ctxt->decode;
+
+	c->src.bytes = min(c->src.bytes, 4u);
+	if (!emulator_io_permited(ctxt, ctxt->ops, c->dst.val, c->src.bytes))
+		return emulate_gp(ctxt, 0);
+
+	return X86EMUL_CONTINUE;
+}
+
 #define D(_y) { .flags = (_y) }
+#define DI(_y, _i) { .flags = (_y), .intercept = x86_intercept_##_i }
+#define DIP(_y, _i, _p) { .flags = (_y), .intercept = x86_intercept_##_i, \
+		      .check_perm = (_p) }
 #define N    D(0)
+#define EXT(_f, _e) { .flags = ((_f) | RMExt), .u.group = (_e) }
 #define G(_f, _g) { .flags = ((_f) | Group), .u.group = (_g) }
-#define GD(_f, _g) { .flags = ((_f) | Group | GroupDual), .u.gdual = (_g) }
+#define GD(_f, _g) { .flags = ((_f) | GroupDual), .u.gdual = (_g) }
 #define I(_f, _e) { .flags = (_f), .u.execute = (_e) }
+#define II(_f, _e, _i) \
+	{ .flags = (_f), .u.execute = (_e), .intercept = x86_intercept_##_i }
+#define IIP(_f, _e, _i, _p) \
+	{ .flags = (_f), .u.execute = (_e), .intercept = x86_intercept_##_i, \
+	  .check_perm = (_p) }
+#define GP(_f, _g) { .flags = ((_f) | Prefix), .u.gprefix = (_g) }
 
 #define D2bv(_f)      D((_f) | ByteOp), D(_f)
+#define D2bvIP(_f, _i, _p) DIP((_f) | ByteOp, _i, _p), DIP(_f, _i, _p)
 #define I2bv(_f, _e)  I((_f) | ByteOp, _e), I(_f, _e)
 
-#define D6ALU(_f) D2bv((_f) | DstMem | SrcReg | ModRM),			\
-		D2bv(((_f) | DstReg | SrcMem | ModRM) & ~Lock),		\
-		D2bv(((_f) & ~Lock) | DstAcc | SrcImm)
+#define I6ALU(_f, _e) I2bv((_f) | DstMem | SrcReg | ModRM, _e),		\
+		I2bv(((_f) | DstReg | SrcMem | ModRM) & ~Lock, _e),	\
+		I2bv(((_f) & ~Lock) | DstAcc | SrcImm, _e)
 
+static struct opcode group7_rm1[] = {
+	DI(SrcNone | ModRM | Priv, monitor),
+	DI(SrcNone | ModRM | Priv, mwait),
+	N, N, N, N, N, N,
+};
+
+static struct opcode group7_rm3[] = {
+	DIP(SrcNone | ModRM | Prot | Priv, vmrun,   check_svme_pa),
+	II(SrcNone | ModRM | Prot | VendorSpecific, em_vmmcall, vmmcall),
+	DIP(SrcNone | ModRM | Prot | Priv, vmload,  check_svme_pa),
+	DIP(SrcNone | ModRM | Prot | Priv, vmsave,  check_svme_pa),
+	DIP(SrcNone | ModRM | Prot | Priv, stgi,    check_svme),
+	DIP(SrcNone | ModRM | Prot | Priv, clgi,    check_svme),
+	DIP(SrcNone | ModRM | Prot | Priv, skinit,  check_svme),
+	DIP(SrcNone | ModRM | Prot | Priv, invlpga, check_svme),
+};
+
+static struct opcode group7_rm7[] = {
+	N,
+	DIP(SrcNone | ModRM, rdtscp, check_rdtsc),
+	N, N, N, N, N, N,
+};
 
 static struct opcode group1[] = {
-	X7(D(Lock)), N
+	I(Lock, em_add),
+	I(Lock, em_or),
+	I(Lock, em_adc),
+	I(Lock, em_sbb),
+	I(Lock, em_and),
+	I(Lock, em_sub),
+	I(Lock, em_xor),
+	I(0, em_cmp),
 };
 
 static struct opcode group1A[] = {
@@ -2366,16 +3075,28 @@
 	D(SrcMem | ModRM | Stack), N,
 };
 
+static struct opcode group6[] = {
+	DI(ModRM | Prot,        sldt),
+	DI(ModRM | Prot,        str),
+	DI(ModRM | Prot | Priv, lldt),
+	DI(ModRM | Prot | Priv, ltr),
+	N, N, N, N,
+};
+
 static struct group_dual group7 = { {
-	N, N, D(ModRM | SrcMem | Priv), D(ModRM | SrcMem | Priv),
-	D(SrcNone | ModRM | DstMem | Mov), N,
-	D(SrcMem16 | ModRM | Mov | Priv),
-	D(SrcMem | ModRM | ByteOp | Priv | NoAccess),
+	DI(ModRM | Mov | DstMem | Priv, sgdt),
+	DI(ModRM | Mov | DstMem | Priv, sidt),
+	II(ModRM | SrcMem | Priv, em_lgdt, lgdt),
+	II(ModRM | SrcMem | Priv, em_lidt, lidt),
+	II(SrcNone | ModRM | DstMem | Mov, em_smsw, smsw), N,
+	II(SrcMem16 | ModRM | Mov | Priv, em_lmsw, lmsw),
+	II(SrcMem | ModRM | ByteOp | Priv | NoAccess, em_invlpg, invlpg),
 }, {
-	D(SrcNone | ModRM | Priv | VendorSpecific), N,
-	N, D(SrcNone | ModRM | Priv | VendorSpecific),
-	D(SrcNone | ModRM | DstMem | Mov), N,
-	D(SrcMem16 | ModRM | Mov | Priv), N,
+	I(SrcNone | ModRM | Priv | VendorSpecific, em_vmcall),
+	EXT(0, group7_rm1),
+	N, EXT(0, group7_rm3),
+	II(SrcNone | ModRM | DstMem | Mov, em_smsw, smsw), N,
+	II(SrcMem16 | ModRM | Mov | Priv, em_lmsw, lmsw), EXT(0, group7_rm7),
 } };
 
 static struct opcode group8[] = {
@@ -2394,35 +3115,40 @@
 	I(DstMem | SrcImm | ModRM | Mov, em_mov), X7(D(Undefined)),
 };
 
+static struct gprefix pfx_0f_6f_0f_7f = {
+	N, N, N, I(Sse, em_movdqu),
+};
+
 static struct opcode opcode_table[256] = {
 	/* 0x00 - 0x07 */
-	D6ALU(Lock),
+	I6ALU(Lock, em_add),
 	D(ImplicitOps | Stack | No64), D(ImplicitOps | Stack | No64),
 	/* 0x08 - 0x0F */
-	D6ALU(Lock),
+	I6ALU(Lock, em_or),
 	D(ImplicitOps | Stack | No64), N,
 	/* 0x10 - 0x17 */
-	D6ALU(Lock),
+	I6ALU(Lock, em_adc),
 	D(ImplicitOps | Stack | No64), D(ImplicitOps | Stack | No64),
 	/* 0x18 - 0x1F */
-	D6ALU(Lock),
+	I6ALU(Lock, em_sbb),
 	D(ImplicitOps | Stack | No64), D(ImplicitOps | Stack | No64),
 	/* 0x20 - 0x27 */
-	D6ALU(Lock), N, N,
+	I6ALU(Lock, em_and), N, N,
 	/* 0x28 - 0x2F */
-	D6ALU(Lock), N, I(ByteOp | DstAcc | No64, em_das),
+	I6ALU(Lock, em_sub), N, I(ByteOp | DstAcc | No64, em_das),
 	/* 0x30 - 0x37 */
-	D6ALU(Lock), N, N,
+	I6ALU(Lock, em_xor), N, N,
 	/* 0x38 - 0x3F */
-	D6ALU(0), N, N,
+	I6ALU(0, em_cmp), N, N,
 	/* 0x40 - 0x4F */
 	X16(D(DstReg)),
 	/* 0x50 - 0x57 */
 	X8(I(SrcReg | Stack, em_push)),
 	/* 0x58 - 0x5F */
-	X8(D(DstReg | Stack)),
+	X8(I(DstReg | Stack, em_pop)),
 	/* 0x60 - 0x67 */
-	D(ImplicitOps | Stack | No64), D(ImplicitOps | Stack | No64),
+	I(ImplicitOps | Stack | No64, em_pusha),
+	I(ImplicitOps | Stack | No64, em_popa),
 	N, D(DstReg | SrcMem32 | ModRM | Mov) /* movsxd (x86/64) */ ,
 	N, N, N, N,
 	/* 0x68 - 0x6F */
@@ -2430,8 +3156,8 @@
 	I(DstReg | SrcMem | ModRM | Src2Imm, em_imul_3op),
 	I(SrcImmByte | Mov | Stack, em_push),
 	I(DstReg | SrcMem | ModRM | Src2ImmByte, em_imul_3op),
-	D2bv(DstDI | Mov | String), /* insb, insw/insd */
-	D2bv(SrcSI | ImplicitOps | String), /* outsb, outsw/outsd */
+	D2bvIP(DstDI | SrcDX | Mov | String, ins, check_perm_in), /* insb, insw/insd */
+	D2bvIP(SrcSI | DstDX | String, outs, check_perm_out), /* outsb, outsw/outsd */
 	/* 0x70 - 0x7F */
 	X16(D(SrcImmByte)),
 	/* 0x80 - 0x87 */
@@ -2446,21 +3172,22 @@
 	D(DstMem | SrcNone | ModRM | Mov), D(ModRM | SrcMem | NoAccess | DstReg),
 	D(ImplicitOps | SrcMem16 | ModRM), G(0, group1A),
 	/* 0x90 - 0x97 */
-	X8(D(SrcAcc | DstReg)),
+	DI(SrcAcc | DstReg, pause), X7(D(SrcAcc | DstReg)),
 	/* 0x98 - 0x9F */
 	D(DstAcc | SrcNone), I(ImplicitOps | SrcAcc, em_cwd),
 	I(SrcImmFAddr | No64, em_call_far), N,
-	D(ImplicitOps | Stack), D(ImplicitOps | Stack), N, N,
+	II(ImplicitOps | Stack, em_pushf, pushf),
+	II(ImplicitOps | Stack, em_popf, popf), N, N,
 	/* 0xA0 - 0xA7 */
 	I2bv(DstAcc | SrcMem | Mov | MemAbs, em_mov),
 	I2bv(DstMem | SrcAcc | Mov | MemAbs, em_mov),
 	I2bv(SrcSI | DstDI | Mov | String, em_mov),
-	D2bv(SrcSI | DstDI | String),
+	I2bv(SrcSI | DstDI | String, em_cmp),
 	/* 0xA8 - 0xAF */
 	D2bv(DstAcc | SrcImm),
 	I2bv(SrcAcc | DstDI | Mov | String, em_mov),
 	I2bv(SrcSI | DstAcc | Mov | String, em_mov),
-	D2bv(SrcAcc | DstDI | String),
+	I2bv(SrcAcc | DstDI | String, em_cmp),
 	/* 0xB0 - 0xB7 */
 	X8(I(ByteOp | DstReg | SrcImm | Mov, em_mov)),
 	/* 0xB8 - 0xBF */
@@ -2473,7 +3200,8 @@
 	G(ByteOp, group11), G(0, group11),
 	/* 0xC8 - 0xCF */
 	N, N, N, D(ImplicitOps | Stack),
-	D(ImplicitOps), D(SrcImmByte), D(ImplicitOps | No64), D(ImplicitOps),
+	D(ImplicitOps), DI(SrcImmByte, intn),
+	D(ImplicitOps | No64), DI(ImplicitOps, iret),
 	/* 0xD0 - 0xD7 */
 	D2bv(DstMem | SrcOne | ModRM), D2bv(DstMem | ModRM),
 	N, N, N, N,
@@ -2481,14 +3209,17 @@
 	N, N, N, N, N, N, N, N,
 	/* 0xE0 - 0xE7 */
 	X4(D(SrcImmByte)),
-	D2bv(SrcImmUByte | DstAcc), D2bv(SrcAcc | DstImmUByte),
+	D2bvIP(SrcImmUByte | DstAcc, in,  check_perm_in),
+	D2bvIP(SrcAcc | DstImmUByte, out, check_perm_out),
 	/* 0xE8 - 0xEF */
 	D(SrcImm | Stack), D(SrcImm | ImplicitOps),
 	D(SrcImmFAddr | No64), D(SrcImmByte | ImplicitOps),
-	D2bv(SrcNone | DstAcc),	D2bv(SrcAcc | ImplicitOps),
+	D2bvIP(SrcDX | DstAcc, in,  check_perm_in),
+	D2bvIP(SrcAcc | DstDX, out, check_perm_out),
 	/* 0xF0 - 0xF7 */
-	N, N, N, N,
-	D(ImplicitOps | Priv), D(ImplicitOps), G(ByteOp, group3), G(0, group3),
+	N, DI(ImplicitOps, icebp), N, N,
+	DI(ImplicitOps | Priv, hlt), D(ImplicitOps),
+	G(ByteOp, group3), G(0, group3),
 	/* 0xF8 - 0xFF */
 	D(ImplicitOps), D(ImplicitOps), D(ImplicitOps), D(ImplicitOps),
 	D(ImplicitOps), D(ImplicitOps), G(0, group4), G(0, group5),
@@ -2496,20 +3227,24 @@
 
 static struct opcode twobyte_table[256] = {
 	/* 0x00 - 0x0F */
-	N, GD(0, &group7), N, N,
-	N, D(ImplicitOps | VendorSpecific), D(ImplicitOps | Priv), N,
-	D(ImplicitOps | Priv), D(ImplicitOps | Priv), N, N,
+	G(0, group6), GD(0, &group7), N, N,
+	N, D(ImplicitOps | VendorSpecific), DI(ImplicitOps | Priv, clts), N,
+	DI(ImplicitOps | Priv, invd), DI(ImplicitOps | Priv, wbinvd), N, N,
 	N, D(ImplicitOps | ModRM), N, N,
 	/* 0x10 - 0x1F */
 	N, N, N, N, N, N, N, N, D(ImplicitOps | ModRM), N, N, N, N, N, N, N,
 	/* 0x20 - 0x2F */
-	D(ModRM | DstMem | Priv | Op3264), D(ModRM | DstMem | Priv | Op3264),
-	D(ModRM | SrcMem | Priv | Op3264), D(ModRM | SrcMem | Priv | Op3264),
+	DIP(ModRM | DstMem | Priv | Op3264, cr_read, check_cr_read),
+	DIP(ModRM | DstMem | Priv | Op3264, dr_read, check_dr_read),
+	DIP(ModRM | SrcMem | Priv | Op3264, cr_write, check_cr_write),
+	DIP(ModRM | SrcMem | Priv | Op3264, dr_write, check_dr_write),
 	N, N, N, N,
 	N, N, N, N, N, N, N, N,
 	/* 0x30 - 0x3F */
-	D(ImplicitOps | Priv), I(ImplicitOps, em_rdtsc),
-	D(ImplicitOps | Priv), N,
+	DI(ImplicitOps | Priv, wrmsr),
+	IIP(ImplicitOps, em_rdtsc, rdtsc, check_rdtsc),
+	DI(ImplicitOps | Priv, rdmsr),
+	DIP(ImplicitOps | Priv, rdpmc, check_rdpmc),
 	D(ImplicitOps | VendorSpecific), D(ImplicitOps | Priv | VendorSpecific),
 	N, N,
 	N, N, N, N, N, N, N, N,
@@ -2518,21 +3253,27 @@
 	/* 0x50 - 0x5F */
 	N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N,
 	/* 0x60 - 0x6F */
-	N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N,
+	N, N, N, N,
+	N, N, N, N,
+	N, N, N, N,
+	N, N, N, GP(SrcMem | DstReg | ModRM | Mov, &pfx_0f_6f_0f_7f),
 	/* 0x70 - 0x7F */
-	N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N,
+	N, N, N, N,
+	N, N, N, N,
+	N, N, N, N,
+	N, N, N, GP(SrcReg | DstMem | ModRM | Mov, &pfx_0f_6f_0f_7f),
 	/* 0x80 - 0x8F */
 	X16(D(SrcImm)),
 	/* 0x90 - 0x9F */
 	X16(D(ByteOp | DstMem | SrcNone | ModRM| Mov)),
 	/* 0xA0 - 0xA7 */
 	D(ImplicitOps | Stack), D(ImplicitOps | Stack),
-	N, D(DstMem | SrcReg | ModRM | BitOp),
+	DI(ImplicitOps, cpuid), D(DstMem | SrcReg | ModRM | BitOp),
 	D(DstMem | SrcReg | Src2ImmByte | ModRM),
 	D(DstMem | SrcReg | Src2CL | ModRM), N, N,
 	/* 0xA8 - 0xAF */
 	D(ImplicitOps | Stack), D(ImplicitOps | Stack),
-	N, D(DstMem | SrcReg | ModRM | BitOp | Lock),
+	DI(ImplicitOps, rsm), D(DstMem | SrcReg | ModRM | BitOp | Lock),
 	D(DstMem | SrcReg | Src2ImmByte | ModRM),
 	D(DstMem | SrcReg | Src2CL | ModRM),
 	D(ModRM), I(DstReg | SrcMem | ModRM, em_imul),
@@ -2564,10 +3305,13 @@
 #undef G
 #undef GD
 #undef I
+#undef GP
+#undef EXT
 
 #undef D2bv
+#undef D2bvIP
 #undef I2bv
-#undef D6ALU
+#undef I6ALU
 
 static unsigned imm_size(struct decode_cache *c)
 {
@@ -2625,16 +3369,16 @@
 	struct decode_cache *c = &ctxt->decode;
 	int rc = X86EMUL_CONTINUE;
 	int mode = ctxt->mode;
-	int def_op_bytes, def_ad_bytes, dual, goffset;
-	struct opcode opcode, *g_mod012, *g_mod3;
-	struct operand memop = { .type = OP_NONE };
+	int def_op_bytes, def_ad_bytes, goffset, simd_prefix;
+	bool op_prefix = false;
+	struct opcode opcode;
+	struct operand memop = { .type = OP_NONE }, *memopp = NULL;
 
 	c->eip = ctxt->eip;
 	c->fetch.start = c->eip;
 	c->fetch.end = c->fetch.start + insn_len;
 	if (insn_len > 0)
 		memcpy(c->fetch.data, insn, insn_len);
-	ctxt->cs_base = seg_base(ctxt, ops, VCPU_SREG_CS);
 
 	switch (mode) {
 	case X86EMUL_MODE_REAL:
@@ -2662,6 +3406,7 @@
 	for (;;) {
 		switch (c->b = insn_fetch(u8, 1, c->eip)) {
 		case 0x66:	/* operand-size override */
+			op_prefix = true;
 			/* switch between 2/4 bytes */
 			c->op_bytes = def_op_bytes ^ 6;
 			break;
@@ -2692,10 +3437,8 @@
 			c->lock_prefix = 1;
 			break;
 		case 0xf2:	/* REPNE/REPNZ */
-			c->rep_prefix = REPNE_PREFIX;
-			break;
 		case 0xf3:	/* REP/REPE/REPZ */
-			c->rep_prefix = REPE_PREFIX;
+			c->rep_prefix = c->b;
 			break;
 		default:
 			goto done_prefixes;
@@ -2722,29 +3465,49 @@
 	}
 	c->d = opcode.flags;
 
-	if (c->d & Group) {
-		dual = c->d & GroupDual;
-		c->modrm = insn_fetch(u8, 1, c->eip);
-		--c->eip;
-
-		if (c->d & GroupDual) {
-			g_mod012 = opcode.u.gdual->mod012;
-			g_mod3 = opcode.u.gdual->mod3;
-		} else
-			g_mod012 = g_mod3 = opcode.u.group;
-
-		c->d &= ~(Group | GroupDual);
-
-		goffset = (c->modrm >> 3) & 7;
+	while (c->d & GroupMask) {
+		switch (c->d & GroupMask) {
+		case Group:
+			c->modrm = insn_fetch(u8, 1, c->eip);
+			--c->eip;
+			goffset = (c->modrm >> 3) & 7;
+			opcode = opcode.u.group[goffset];
+			break;
+		case GroupDual:
+			c->modrm = insn_fetch(u8, 1, c->eip);
+			--c->eip;
+			goffset = (c->modrm >> 3) & 7;
+			if ((c->modrm >> 6) == 3)
+				opcode = opcode.u.gdual->mod3[goffset];
+			else
+				opcode = opcode.u.gdual->mod012[goffset];
+			break;
+		case RMExt:
+			goffset = c->modrm & 7;
+			opcode = opcode.u.group[goffset];
+			break;
+		case Prefix:
+			if (c->rep_prefix && op_prefix)
+				return X86EMUL_UNHANDLEABLE;
+			simd_prefix = op_prefix ? 0x66 : c->rep_prefix;
+			switch (simd_prefix) {
+			case 0x00: opcode = opcode.u.gprefix->pfx_no; break;
+			case 0x66: opcode = opcode.u.gprefix->pfx_66; break;
+			case 0xf2: opcode = opcode.u.gprefix->pfx_f2; break;
+			case 0xf3: opcode = opcode.u.gprefix->pfx_f3; break;
+			}
+			break;
+		default:
+			return X86EMUL_UNHANDLEABLE;
+		}
 
-		if ((c->modrm >> 6) == 3)
-			opcode = g_mod3[goffset];
-		else
-			opcode = g_mod012[goffset];
+		c->d &= ~GroupMask;
 		c->d |= opcode.flags;
 	}
 
 	c->execute = opcode.u.execute;
+	c->check_perm = opcode.check_perm;
+	c->intercept = opcode.intercept;
 
 	/* Unrecognised? */
 	if (c->d == 0 || (c->d & Undefined))
@@ -2763,6 +3526,9 @@
 			c->op_bytes = 4;
 	}
 
+	if (c->d & Sse)
+		c->op_bytes = 16;
+
 	/* ModRM and SIB bytes. */
 	if (c->d & ModRM) {
 		rc = decode_modrm(ctxt, ops, &memop);
@@ -2776,14 +3542,11 @@
 	if (!c->has_seg_override)
 		set_seg_override(c, VCPU_SREG_DS);
 
-	memop.addr.mem.seg = seg_override(ctxt, ops, c);
+	memop.addr.mem.seg = seg_override(ctxt, c);
 
 	if (memop.type == OP_MEM && c->ad_bytes != 8)
 		memop.addr.mem.ea = (u32)memop.addr.mem.ea;
 
-	if (memop.type == OP_MEM && c->rip_relative)
-		memop.addr.mem.ea += c->eip;
-
 	/*
 	 * Decode and fetch the source operand: register, memory
 	 * or immediate.
@@ -2792,7 +3555,7 @@
 	case SrcNone:
 		break;
 	case SrcReg:
-		decode_register_operand(&c->src, c, 0);
+		decode_register_operand(ctxt, &c->src, c, 0);
 		break;
 	case SrcMem16:
 		memop.bytes = 2;
@@ -2805,6 +3568,7 @@
 							   c->op_bytes;
 	srcmem_common:
 		c->src = memop;
+		memopp = &c->src;
 		break;
 	case SrcImmU16:
 		rc = decode_imm(ctxt, &c->src, 2, false);
@@ -2836,7 +3600,7 @@
 		c->src.bytes = (c->d & ByteOp) ? 1 : c->op_bytes;
 		c->src.addr.mem.ea =
 			register_address(c, c->regs[VCPU_REGS_RSI]);
-		c->src.addr.mem.seg = seg_override(ctxt, ops, c),
+		c->src.addr.mem.seg = seg_override(ctxt, c);
 		c->src.val = 0;
 		break;
 	case SrcImmFAddr:
@@ -2849,6 +3613,12 @@
 		memop.bytes = c->op_bytes + 2;
 		goto srcmem_common;
 		break;
+	case SrcDX:
+		c->src.type = OP_REG;
+		c->src.bytes = 2;
+		c->src.addr.reg = &c->regs[VCPU_REGS_RDX];
+		fetch_register_operand(&c->src);
+		break;
 	}
 
 	if (rc != X86EMUL_CONTINUE)
@@ -2883,7 +3653,7 @@
 	/* Decode and fetch the destination operand: register or memory. */
 	switch (c->d & DstMask) {
 	case DstReg:
-		decode_register_operand(&c->dst, c,
+		decode_register_operand(ctxt, &c->dst, c,
 			 c->twobyte && (c->b == 0xb6 || c->b == 0xb7));
 		break;
 	case DstImmUByte:
@@ -2895,6 +3665,7 @@
 	case DstMem:
 	case DstMem64:
 		c->dst = memop;
+		memopp = &c->dst;
 		if ((c->d & DstMask) == DstMem64)
 			c->dst.bytes = 8;
 		else
@@ -2918,15 +3689,24 @@
 		c->dst.addr.mem.seg = VCPU_SREG_ES;
 		c->dst.val = 0;
 		break;
+	case DstDX:
+		c->dst.type = OP_REG;
+		c->dst.bytes = 2;
+		c->dst.addr.reg = &c->regs[VCPU_REGS_RDX];
+		fetch_register_operand(&c->dst);
+		break;
 	case ImplicitOps:
 		/* Special instructions do their own operand decoding. */
 	default:
 		c->dst.type = OP_NONE; /* Disable writeback. */
-		return 0;
+		break;
 	}
 
 done:
-	return (rc == X86EMUL_UNHANDLEABLE) ? -1 : 0;
+	if (memopp && memopp->type == OP_MEM && c->rip_relative)
+		memopp->addr.mem.ea += c->eip;
+
+	return (rc == X86EMUL_UNHANDLEABLE) ? EMULATION_FAILED : EMULATION_OK;
 }
 
 static bool string_insn_completed(struct x86_emulate_ctxt *ctxt)
@@ -2979,12 +3759,51 @@
 		goto done;
 	}
 
+	if ((c->d & Sse)
+	    && ((ops->get_cr(ctxt, 0) & X86_CR0_EM)
+		|| !(ops->get_cr(ctxt, 4) & X86_CR4_OSFXSR))) {
+		rc = emulate_ud(ctxt);
+		goto done;
+	}
+
+	if ((c->d & Sse) && (ops->get_cr(ctxt, 0) & X86_CR0_TS)) {
+		rc = emulate_nm(ctxt);
+		goto done;
+	}
+
+	if (unlikely(ctxt->guest_mode) && c->intercept) {
+		rc = emulator_check_intercept(ctxt, c->intercept,
+					      X86_ICPT_PRE_EXCEPT);
+		if (rc != X86EMUL_CONTINUE)
+			goto done;
+	}
+
 	/* Privileged instruction can be executed only in CPL=0 */
-	if ((c->d & Priv) && ops->cpl(ctxt->vcpu)) {
+	if ((c->d & Priv) && ops->cpl(ctxt)) {
 		rc = emulate_gp(ctxt, 0);
 		goto done;
 	}
 
+	/* Instruction can only be executed in protected mode */
+	if ((c->d & Prot) && !(ctxt->mode & X86EMUL_MODE_PROT)) {
+		rc = emulate_ud(ctxt);
+		goto done;
+	}
+
+	/* Do instruction specific permission checks */
+	if (c->check_perm) {
+		rc = c->check_perm(ctxt);
+		if (rc != X86EMUL_CONTINUE)
+			goto done;
+	}
+
+	if (unlikely(ctxt->guest_mode) && c->intercept) {
+		rc = emulator_check_intercept(ctxt, c->intercept,
+					      X86_ICPT_POST_EXCEPT);
+		if (rc != X86EMUL_CONTINUE)
+			goto done;
+	}
+
 	if (c->rep_prefix && (c->d & String)) {
 		/* All REP prefixes have the same first termination condition */
 		if (address_mask(c, c->regs[VCPU_REGS_RCX]) == 0) {
@@ -2994,16 +3813,16 @@
 	}
 
 	if ((c->src.type == OP_MEM) && !(c->d & NoAccess)) {
-		rc = read_emulated(ctxt, ops, linear(ctxt, c->src.addr.mem),
-					c->src.valptr, c->src.bytes);
+		rc = segmented_read(ctxt, c->src.addr.mem,
+				    c->src.valptr, c->src.bytes);
 		if (rc != X86EMUL_CONTINUE)
 			goto done;
 		c->src.orig_val64 = c->src.val64;
 	}
 
 	if (c->src2.type == OP_MEM) {
-		rc = read_emulated(ctxt, ops, linear(ctxt, c->src2.addr.mem),
-					&c->src2.val, c->src2.bytes);
+		rc = segmented_read(ctxt, c->src2.addr.mem,
+				    &c->src2.val, c->src2.bytes);
 		if (rc != X86EMUL_CONTINUE)
 			goto done;
 	}
@@ -3014,7 +3833,7 @@
 
 	if ((c->dst.type == OP_MEM) && !(c->d & Mov)) {
 		/* optimisation - avoid slow emulated read if Mov */
-		rc = read_emulated(ctxt, ops, linear(ctxt, c->dst.addr.mem),
+		rc = segmented_read(ctxt, c->dst.addr.mem,
 				   &c->dst.val, c->dst.bytes);
 		if (rc != X86EMUL_CONTINUE)
 			goto done;
@@ -3023,6 +3842,13 @@
 
 special_insn:
 
+	if (unlikely(ctxt->guest_mode) && c->intercept) {
+		rc = emulator_check_intercept(ctxt, c->intercept,
+					      X86_ICPT_POST_MEMACCESS);
+		if (rc != X86EMUL_CONTINUE)
+			goto done;
+	}
+
 	if (c->execute) {
 		rc = c->execute(ctxt);
 		if (rc != X86EMUL_CONTINUE)
@@ -3034,75 +3860,33 @@
 		goto twobyte_insn;
 
 	switch (c->b) {
-	case 0x00 ... 0x05:
-	      add:		/* add */
-		emulate_2op_SrcV("add", c->src, c->dst, ctxt->eflags);
-		break;
 	case 0x06:		/* push es */
-		emulate_push_sreg(ctxt, ops, VCPU_SREG_ES);
+		rc = emulate_push_sreg(ctxt, ops, VCPU_SREG_ES);
 		break;
 	case 0x07:		/* pop es */
 		rc = emulate_pop_sreg(ctxt, ops, VCPU_SREG_ES);
 		break;
-	case 0x08 ... 0x0d:
-	      or:		/* or */
-		emulate_2op_SrcV("or", c->src, c->dst, ctxt->eflags);
-		break;
 	case 0x0e:		/* push cs */
-		emulate_push_sreg(ctxt, ops, VCPU_SREG_CS);
-		break;
-	case 0x10 ... 0x15:
-	      adc:		/* adc */
-		emulate_2op_SrcV("adc", c->src, c->dst, ctxt->eflags);
+		rc = emulate_push_sreg(ctxt, ops, VCPU_SREG_CS);
 		break;
 	case 0x16:		/* push ss */
-		emulate_push_sreg(ctxt, ops, VCPU_SREG_SS);
+		rc = emulate_push_sreg(ctxt, ops, VCPU_SREG_SS);
 		break;
 	case 0x17:		/* pop ss */
 		rc = emulate_pop_sreg(ctxt, ops, VCPU_SREG_SS);
 		break;
-	case 0x18 ... 0x1d:
-	      sbb:		/* sbb */
-		emulate_2op_SrcV("sbb", c->src, c->dst, ctxt->eflags);
-		break;
 	case 0x1e:		/* push ds */
-		emulate_push_sreg(ctxt, ops, VCPU_SREG_DS);
+		rc = emulate_push_sreg(ctxt, ops, VCPU_SREG_DS);
 		break;
 	case 0x1f:		/* pop ds */
 		rc = emulate_pop_sreg(ctxt, ops, VCPU_SREG_DS);
 		break;
-	case 0x20 ... 0x25:
-	      and:		/* and */
-		emulate_2op_SrcV("and", c->src, c->dst, ctxt->eflags);
-		break;
-	case 0x28 ... 0x2d:
-	      sub:		/* sub */
-		emulate_2op_SrcV("sub", c->src, c->dst, ctxt->eflags);
-		break;
-	case 0x30 ... 0x35:
-	      xor:		/* xor */
-		emulate_2op_SrcV("xor", c->src, c->dst, ctxt->eflags);
-		break;
-	case 0x38 ... 0x3d:
-	      cmp:		/* cmp */
-		emulate_2op_SrcV("cmp", c->src, c->dst, ctxt->eflags);
-		break;
 	case 0x40 ... 0x47: /* inc r16/r32 */
 		emulate_1op("inc", c->dst, ctxt->eflags);
 		break;
 	case 0x48 ... 0x4f: /* dec r16/r32 */
 		emulate_1op("dec", c->dst, ctxt->eflags);
 		break;
-	case 0x58 ... 0x5f: /* pop reg */
-	pop_instruction:
-		rc = emulate_pop(ctxt, ops, &c->dst.val, c->op_bytes);
-		break;
-	case 0x60:	/* pusha */
-		rc = emulate_pusha(ctxt, ops);
-		break;
-	case 0x61:	/* popa */
-		rc = emulate_popa(ctxt, ops);
-		break;
 	case 0x63:		/* movsxd */
 		if (ctxt->mode != X86EMUL_MODE_PROT64)
 			goto cannot_emulate;
@@ -3121,26 +3905,6 @@
 		if (test_cc(c->b, ctxt->eflags))
 			jmp_rel(c, c->src.val);
 		break;
-	case 0x80 ... 0x83:	/* Grp1 */
-		switch (c->modrm_reg) {
-		case 0:
-			goto add;
-		case 1:
-			goto or;
-		case 2:
-			goto adc;
-		case 3:
-			goto sbb;
-		case 4:
-			goto and;
-		case 5:
-			goto sub;
-		case 6:
-			goto xor;
-		case 7:
-			goto cmp;
-		}
-		break;
 	case 0x84 ... 0x85:
 	test:
 		emulate_2op_SrcV("test", c->src, c->dst, ctxt->eflags);
@@ -3162,7 +3926,7 @@
 			rc = emulate_ud(ctxt);
 			goto done;
 		}
-		c->dst.val = ops->get_segment_selector(c->modrm_reg, ctxt->vcpu);
+		c->dst.val = get_segment_selector(ctxt, c->modrm_reg);
 		break;
 	case 0x8d: /* lea r16/r32, m */
 		c->dst.val = c->src.addr.mem.ea;
@@ -3187,7 +3951,7 @@
 		break;
 	}
 	case 0x8f:		/* pop (sole member of Grp1a) */
-		rc = emulate_grp1a(ctxt, ops);
+		rc = em_grp1a(ctxt);
 		break;
 	case 0x90 ... 0x97: /* nop / xchg reg, rax */
 		if (c->dst.addr.reg == &c->regs[VCPU_REGS_RAX])
@@ -3200,31 +3964,17 @@
 		case 8: c->dst.val = (s32)c->dst.val; break;
 		}
 		break;
-	case 0x9c: /* pushf */
-		c->src.val =  (unsigned long) ctxt->eflags;
-		emulate_push(ctxt, ops);
-		break;
-	case 0x9d: /* popf */
-		c->dst.type = OP_REG;
-		c->dst.addr.reg = &ctxt->eflags;
-		c->dst.bytes = c->op_bytes;
-		rc = emulate_popf(ctxt, ops, &c->dst.val, c->op_bytes);
-		break;
-	case 0xa6 ... 0xa7:	/* cmps */
-		c->dst.type = OP_NONE; /* Disable writeback. */
-		goto cmp;
 	case 0xa8 ... 0xa9:	/* test ax, imm */
 		goto test;
-	case 0xae ... 0xaf:	/* scas */
-		goto cmp;
 	case 0xc0 ... 0xc1:
-		emulate_grp2(ctxt);
+		rc = em_grp2(ctxt);
 		break;
 	case 0xc3: /* ret */
 		c->dst.type = OP_REG;
 		c->dst.addr.reg = &c->eip;
 		c->dst.bytes = c->op_bytes;
-		goto pop_instruction;
+		rc = em_pop(ctxt);
+		break;
 	case 0xc4:		/* les */
 		rc = emulate_load_segment(ctxt, ops, VCPU_SREG_ES);
 		break;
@@ -3252,11 +4002,11 @@
 		rc = emulate_iret(ctxt, ops);
 		break;
 	case 0xd0 ... 0xd1:	/* Grp2 */
-		emulate_grp2(ctxt);
+		rc = em_grp2(ctxt);
 		break;
 	case 0xd2 ... 0xd3:	/* Grp2 */
 		c->src.val = c->regs[VCPU_REGS_RCX];
-		emulate_grp2(ctxt);
+		rc = em_grp2(ctxt);
 		break;
 	case 0xe0 ... 0xe2:	/* loop/loopz/loopnz */
 		register_address_increment(c, &c->regs[VCPU_REGS_RCX], -1);
@@ -3278,23 +4028,14 @@
 		long int rel = c->src.val;
 		c->src.val = (unsigned long) c->eip;
 		jmp_rel(c, rel);
-		emulate_push(ctxt, ops);
+		rc = em_push(ctxt);
 		break;
 	}
 	case 0xe9: /* jmp rel */
 		goto jmp;
-	case 0xea: { /* jmp far */
-		unsigned short sel;
-	jump_far:
-		memcpy(&sel, c->src.valptr + c->op_bytes, 2);
-
-		if (load_segment_descriptor(ctxt, ops, sel, VCPU_SREG_CS))
-			goto done;
-
-		c->eip = 0;
-		memcpy(&c->eip, c->src.valptr, c->op_bytes);
+	case 0xea: /* jmp far */
+		rc = em_jmp_far(ctxt);
 		break;
-	}
 	case 0xeb:
 	      jmp:		/* jmp rel short */
 		jmp_rel(c, c->src.val);
@@ -3302,40 +4043,27 @@
 		break;
 	case 0xec: /* in al,dx */
 	case 0xed: /* in (e/r)ax,dx */
-		c->src.val = c->regs[VCPU_REGS_RDX];
 	do_io_in:
-		c->dst.bytes = min(c->dst.bytes, 4u);
-		if (!emulator_io_permited(ctxt, ops, c->src.val, c->dst.bytes)) {
-			rc = emulate_gp(ctxt, 0);
-			goto done;
-		}
 		if (!pio_in_emulated(ctxt, ops, c->dst.bytes, c->src.val,
 				     &c->dst.val))
 			goto done; /* IO is needed */
 		break;
 	case 0xee: /* out dx,al */
 	case 0xef: /* out dx,(e/r)ax */
-		c->dst.val = c->regs[VCPU_REGS_RDX];
 	do_io_out:
-		c->src.bytes = min(c->src.bytes, 4u);
-		if (!emulator_io_permited(ctxt, ops, c->dst.val,
-					  c->src.bytes)) {
-			rc = emulate_gp(ctxt, 0);
-			goto done;
-		}
-		ops->pio_out_emulated(c->src.bytes, c->dst.val,
-				      &c->src.val, 1, ctxt->vcpu);
+		ops->pio_out_emulated(ctxt, c->src.bytes, c->dst.val,
+				      &c->src.val, 1);
 		c->dst.type = OP_NONE;	/* Disable writeback. */
 		break;
 	case 0xf4:              /* hlt */
-		ctxt->vcpu->arch.halt_request = 1;
+		ctxt->ops->halt(ctxt);
 		break;
 	case 0xf5:	/* cmc */
 		/* complement carry flag from eflags reg */
 		ctxt->eflags ^= EFLG_CF;
 		break;
 	case 0xf6 ... 0xf7:	/* Grp3 */
-		rc = emulate_grp3(ctxt, ops);
+		rc = em_grp3(ctxt);
 		break;
 	case 0xf8: /* clc */
 		ctxt->eflags &= ~EFLG_CF;
@@ -3366,13 +4094,11 @@
 		ctxt->eflags |= EFLG_DF;
 		break;
 	case 0xfe: /* Grp4 */
-	grp45:
-		rc = emulate_grp45(ctxt, ops);
+		rc = em_grp45(ctxt);
 		break;
 	case 0xff: /* Grp5 */
-		if (c->modrm_reg == 5)
-			goto jump_far;
-		goto grp45;
+		rc = em_grp45(ctxt);
+		break;
 	default:
 		goto cannot_emulate;
 	}
@@ -3381,7 +4107,7 @@
 		goto done;
 
 writeback:
-	rc = writeback(ctxt, ops);
+	rc = writeback(ctxt);
 	if (rc != X86EMUL_CONTINUE)
 		goto done;
 
@@ -3392,7 +4118,7 @@
 	c->dst.type = saved_dst_type;
 
 	if ((c->d & SrcMask) == SrcSI)
-		string_addr_inc(ctxt, seg_override(ctxt, ops, c),
+		string_addr_inc(ctxt, seg_override(ctxt, c),
 				VCPU_REGS_RSI, &c->src);
 
 	if ((c->d & DstMask) == DstDI)
@@ -3427,115 +4153,34 @@
 done:
 	if (rc == X86EMUL_PROPAGATE_FAULT)
 		ctxt->have_exception = true;
+	if (rc == X86EMUL_INTERCEPTED)
+		return EMULATION_INTERCEPTED;
+
 	return (rc == X86EMUL_UNHANDLEABLE) ? EMULATION_FAILED : EMULATION_OK;
 
 twobyte_insn:
 	switch (c->b) {
-	case 0x01: /* lgdt, lidt, lmsw */
-		switch (c->modrm_reg) {
-			u16 size;
-			unsigned long address;
-
-		case 0: /* vmcall */
-			if (c->modrm_mod != 3 || c->modrm_rm != 1)
-				goto cannot_emulate;
-
-			rc = kvm_fix_hypercall(ctxt->vcpu);
-			if (rc != X86EMUL_CONTINUE)
-				goto done;
-
-			/* Let the processor re-execute the fixed hypercall */
-			c->eip = ctxt->eip;
-			/* Disable writeback. */
-			c->dst.type = OP_NONE;
-			break;
-		case 2: /* lgdt */
-			rc = read_descriptor(ctxt, ops, c->src.addr.mem,
-					     &size, &address, c->op_bytes);
-			if (rc != X86EMUL_CONTINUE)
-				goto done;
-			realmode_lgdt(ctxt->vcpu, size, address);
-			/* Disable writeback. */
-			c->dst.type = OP_NONE;
-			break;
-		case 3: /* lidt/vmmcall */
-			if (c->modrm_mod == 3) {
-				switch (c->modrm_rm) {
-				case 1:
-					rc = kvm_fix_hypercall(ctxt->vcpu);
-					break;
-				default:
-					goto cannot_emulate;
-				}
-			} else {
-				rc = read_descriptor(ctxt, ops, c->src.addr.mem,
-						     &size, &address,
-						     c->op_bytes);
-				if (rc != X86EMUL_CONTINUE)
-					goto done;
-				realmode_lidt(ctxt->vcpu, size, address);
-			}
-			/* Disable writeback. */
-			c->dst.type = OP_NONE;
-			break;
-		case 4: /* smsw */
-			c->dst.bytes = 2;
-			c->dst.val = ops->get_cr(0, ctxt->vcpu);
-			break;
-		case 6: /* lmsw */
-			ops->set_cr(0, (ops->get_cr(0, ctxt->vcpu) & ~0x0eul) |
-				    (c->src.val & 0x0f), ctxt->vcpu);
-			c->dst.type = OP_NONE;
-			break;
-		case 5: /* not defined */
-			emulate_ud(ctxt);
-			rc = X86EMUL_PROPAGATE_FAULT;
-			goto done;
-		case 7: /* invlpg*/
-			emulate_invlpg(ctxt->vcpu,
-				       linear(ctxt, c->src.addr.mem));
-			/* Disable writeback. */
-			c->dst.type = OP_NONE;
-			break;
-		default:
-			goto cannot_emulate;
-		}
-		break;
 	case 0x05: 		/* syscall */
 		rc = emulate_syscall(ctxt, ops);
 		break;
 	case 0x06:
-		emulate_clts(ctxt->vcpu);
+		rc = em_clts(ctxt);
 		break;
 	case 0x09:		/* wbinvd */
-		kvm_emulate_wbinvd(ctxt->vcpu);
+		(ctxt->ops->wbinvd)(ctxt);
 		break;
 	case 0x08:		/* invd */
 	case 0x0d:		/* GrpP (prefetch) */
 	case 0x18:		/* Grp16 (prefetch/nop) */
 		break;
 	case 0x20: /* mov cr, reg */
-		switch (c->modrm_reg) {
-		case 1:
-		case 5 ... 7:
-		case 9 ... 15:
-			emulate_ud(ctxt);
-			rc = X86EMUL_PROPAGATE_FAULT;
-			goto done;
-		}
-		c->dst.val = ops->get_cr(c->modrm_reg, ctxt->vcpu);
+		c->dst.val = ops->get_cr(ctxt, c->modrm_reg);
 		break;
 	case 0x21: /* mov from dr to reg */
-		if ((ops->get_cr(4, ctxt->vcpu) & X86_CR4_DE) &&
-		    (c->modrm_reg == 4 || c->modrm_reg == 5)) {
-			emulate_ud(ctxt);
-			rc = X86EMUL_PROPAGATE_FAULT;
-			goto done;
-		}
-		ops->get_dr(c->modrm_reg, &c->dst.val, ctxt->vcpu);
+		ops->get_dr(ctxt, c->modrm_reg, &c->dst.val);
 		break;
 	case 0x22: /* mov reg, cr */
-		if (ops->set_cr(c->modrm_reg, c->src.val, ctxt->vcpu)) {
+		if (ops->set_cr(ctxt, c->modrm_reg, c->src.val)) {
 			emulate_gp(ctxt, 0);
 			rc = X86EMUL_PROPAGATE_FAULT;
 			goto done;
@@ -3543,16 +4188,9 @@
 		c->dst.type = OP_NONE;
 		break;
 	case 0x23: /* mov from reg to dr */
-		if ((ops->get_cr(4, ctxt->vcpu) & X86_CR4_DE) &&
-		    (c->modrm_reg == 4 || c->modrm_reg == 5)) {
-			emulate_ud(ctxt);
-			rc = X86EMUL_PROPAGATE_FAULT;
-			goto done;
-		}
-
-		if (ops->set_dr(c->modrm_reg, c->src.val &
+		if (ops->set_dr(ctxt, c->modrm_reg, c->src.val &
 				((ctxt->mode == X86EMUL_MODE_PROT64) ?
-				 ~0ULL : ~0U), ctxt->vcpu) < 0) {
+				 ~0ULL : ~0U)) < 0) {
 			/* #UD condition is already handled by the code above */
 			emulate_gp(ctxt, 0);
 			rc = X86EMUL_PROPAGATE_FAULT;
@@ -3565,7 +4203,7 @@
 		/* wrmsr */
 		msr_data = (u32)c->regs[VCPU_REGS_RAX]
 			| ((u64)c->regs[VCPU_REGS_RDX] << 32);
-		if (ops->set_msr(ctxt->vcpu, c->regs[VCPU_REGS_RCX], msr_data)) {
+		if (ops->set_msr(ctxt, c->regs[VCPU_REGS_RCX], msr_data)) {
 			emulate_gp(ctxt, 0);
 			rc = X86EMUL_PROPAGATE_FAULT;
 			goto done;
@@ -3574,7 +4212,7 @@
 		break;
 	case 0x32:
 		/* rdmsr */
-		if (ops->get_msr(ctxt->vcpu, c->regs[VCPU_REGS_RCX], &msr_data)) {
+		if (ops->get_msr(ctxt, c->regs[VCPU_REGS_RCX], &msr_data)) {
 			emulate_gp(ctxt, 0);
 			rc = X86EMUL_PROPAGATE_FAULT;
 			goto done;
@@ -3603,7 +4241,7 @@
 		c->dst.val = test_cc(c->b, ctxt->eflags);
 		break;
 	case 0xa0:	  /* push fs */
-		emulate_push_sreg(ctxt, ops, VCPU_SREG_FS);
+		rc = emulate_push_sreg(ctxt, ops, VCPU_SREG_FS);
 		break;
 	case 0xa1:	 /* pop fs */
 		rc = emulate_pop_sreg(ctxt, ops, VCPU_SREG_FS);
@@ -3620,7 +4258,7 @@
 		emulate_2op_cl("shld", c->src2, c->src, c->dst, ctxt->eflags);
 		break;
 	case 0xa8:	/* push gs */
-		emulate_push_sreg(ctxt, ops, VCPU_SREG_GS);
+		rc = emulate_push_sreg(ctxt, ops, VCPU_SREG_GS);
 		break;
 	case 0xa9:	/* pop gs */
 		rc = emulate_pop_sreg(ctxt, ops, VCPU_SREG_GS);
@@ -3727,7 +4365,7 @@
 							(u64) c->src.val;
 		break;
 	case 0xc7:		/* Grp9 (cmpxchg8b) */
-		rc = emulate_grp9(ctxt, ops);
+		rc = em_grp9(ctxt);
 		break;
 	default:
 		goto cannot_emulate;
@@ -3739,5 +4377,5 @@
 	goto writeback;
 
 cannot_emulate:
-	return -1;
+	return EMULATION_FAILED;
 }
diff -druN linux-2.6.39-libre/arch/x86/kvm/i8254.h linux-3.0-rc7-libre/arch/x86/kvm/i8254.h
--- linux-2.6.39-libre/arch/x86/kvm/i8254.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/kvm/i8254.h	2011-07-11 19:51:52.000000000 -0400
@@ -33,7 +33,6 @@
 };
 
 struct kvm_pit {
-	unsigned long base_addresss;
 	struct kvm_io_device dev;
 	struct kvm_io_device speaker_dev;
 	struct kvm *kvm;
@@ -51,7 +50,6 @@
 #define KVM_MAX_PIT_INTR_INTERVAL   HZ / 100
 #define KVM_PIT_CHANNEL_MASK	    0x3
 
-void kvm_inject_pit_timer_irqs(struct kvm_vcpu *vcpu);
 void kvm_pit_load_count(struct kvm *kvm, int channel, u32 val, int hpet_legacy_start);
 struct kvm_pit *kvm_create_pit(struct kvm *kvm, u32 flags);
 void kvm_free_pit(struct kvm *kvm);
diff -druN linux-2.6.39-libre/arch/x86/kvm/irq.h linux-3.0-rc7-libre/arch/x86/kvm/irq.h
--- linux-2.6.39-libre/arch/x86/kvm/irq.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/kvm/irq.h	2011-07-11 19:51:52.000000000 -0400
@@ -75,7 +75,6 @@
 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);
 
 static inline struct kvm_pic *pic_irqchip(struct kvm *kvm)
 {
@@ -100,7 +99,6 @@
 void __kvm_migrate_pit_timer(struct kvm_vcpu *vcpu);
 void __kvm_migrate_timers(struct kvm_vcpu *vcpu);
 
-int pit_has_pending_timer(struct kvm_vcpu *vcpu);
 int apic_has_pending_timer(struct kvm_vcpu *vcpu);
 
 #endif
diff -druN linux-2.6.39-libre/arch/x86/kvm/mmu.c linux-3.0-rc7-libre/arch/x86/kvm/mmu.c
--- linux-2.6.39-libre/arch/x86/kvm/mmu.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/kvm/mmu.c	2011-07-11 19:51:52.000000000 -0400
@@ -565,7 +565,7 @@
 
 static bool mapping_level_dirty_bitmap(struct kvm_vcpu *vcpu, gfn_t large_gfn)
 {
-	return gfn_to_memslot_dirty_bitmap(vcpu, large_gfn, true);
+	return !gfn_to_memslot_dirty_bitmap(vcpu, large_gfn, true);
 }
 
 static int mapping_level(struct kvm_vcpu *vcpu, gfn_t large_gfn)
@@ -1206,7 +1206,7 @@
 
 static void nonpaging_update_pte(struct kvm_vcpu *vcpu,
 				 struct kvm_mmu_page *sp, u64 *spte,
-				 const void *pte, unsigned long mmu_seq)
+				 const void *pte)
 {
 	WARN_ON(1);
 }
@@ -3163,9 +3163,8 @@
 }
 
 static void mmu_pte_write_new_pte(struct kvm_vcpu *vcpu,
-				  struct kvm_mmu_page *sp,
-				  u64 *spte,
-				  const void *new, unsigned long mmu_seq)
+				  struct kvm_mmu_page *sp, u64 *spte,
+				  const void *new)
 {
 	if (sp->role.level != PT_PAGE_TABLE_LEVEL) {
 		++vcpu->kvm->stat.mmu_pde_zapped;
@@ -3173,7 +3172,7 @@
         }
 
 	++vcpu->kvm->stat.mmu_pte_updated;
-	vcpu->arch.mmu.update_pte(vcpu, sp, spte, new, mmu_seq);
+	vcpu->arch.mmu.update_pte(vcpu, sp, spte, new);
 }
 
 static bool need_remote_flush(u64 old, u64 new)
@@ -3229,7 +3228,6 @@
 	struct kvm_mmu_page *sp;
 	struct hlist_node *node;
 	LIST_HEAD(invalid_list);
-	unsigned long mmu_seq;
 	u64 entry, gentry, *spte;
 	unsigned pte_size, page_offset, misaligned, quadrant, offset;
 	int level, npte, invlpg_counter, r, flooded = 0;
@@ -3271,9 +3269,6 @@
 		break;
 	}
 
-	mmu_seq = vcpu->kvm->mmu_notifier_seq;
-	smp_rmb();
-
 	spin_lock(&vcpu->kvm->mmu_lock);
 	if (atomic_read(&vcpu->kvm->arch.invlpg_counter) != invlpg_counter)
 		gentry = 0;
@@ -3345,8 +3340,7 @@
 			if (gentry &&
 			      !((sp->role.word ^ vcpu->arch.mmu.base_role.word)
 			      & mask.word))
-				mmu_pte_write_new_pte(vcpu, sp, spte, &gentry,
-						      mmu_seq);
+				mmu_pte_write_new_pte(vcpu, sp, spte, &gentry);
 			if (!remote_flush && need_remote_flush(entry, *spte))
 				remote_flush = true;
 			++spte;
@@ -3551,10 +3545,11 @@
 	return kvm_mmu_prepare_zap_page(kvm, page, invalid_list);
 }
 
-static int mmu_shrink(struct shrinker *shrink, int nr_to_scan, gfp_t gfp_mask)
+static int mmu_shrink(struct shrinker *shrink, struct shrink_control *sc)
 {
 	struct kvm *kvm;
 	struct kvm *kvm_freed = NULL;
+	int nr_to_scan = sc->nr_to_scan;
 
 	if (nr_to_scan == 0)
 		goto out;
diff -druN linux-2.6.39-libre/arch/x86/kvm/paging_tmpl.h linux-3.0-rc7-libre/arch/x86/kvm/paging_tmpl.h
--- linux-2.6.39-libre/arch/x86/kvm/paging_tmpl.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/kvm/paging_tmpl.h	2011-07-11 19:51:52.000000000 -0400
@@ -78,15 +78,19 @@
 	return (gpte & PT_LVL_ADDR_MASK(lvl)) >> PAGE_SHIFT;
 }
 
-static bool FNAME(cmpxchg_gpte)(struct kvm *kvm,
-			 gfn_t table_gfn, unsigned index,
-			 pt_element_t orig_pte, pt_element_t new_pte)
+static int FNAME(cmpxchg_gpte)(struct kvm_vcpu *vcpu, struct kvm_mmu *mmu,
+			       pt_element_t __user *ptep_user, unsigned index,
+			       pt_element_t orig_pte, pt_element_t new_pte)
 {
+	int npages;
 	pt_element_t ret;
 	pt_element_t *table;
 	struct page *page;
 
-	page = gfn_to_page(kvm, table_gfn);
+	npages = get_user_pages_fast((unsigned long)ptep_user, 1, 1, &page);
+	/* Check if the user is doing something meaningless. */
+	if (unlikely(npages != 1))
+		return -EFAULT;
 
 	table = kmap_atomic(page, KM_USER0);
 	ret = CMPXCHG(&table[index], orig_pte, new_pte);
@@ -117,6 +121,7 @@
 				    gva_t addr, u32 access)
 {
 	pt_element_t pte;
+	pt_element_t __user *uninitialized_var(ptep_user);
 	gfn_t table_gfn;
 	unsigned index, pt_access, uninitialized_var(pte_access);
 	gpa_t pte_gpa;
@@ -152,6 +157,9 @@
 	pt_access = ACC_ALL;
 
 	for (;;) {
+		gfn_t real_gfn;
+		unsigned long host_addr;
+
 		index = PT_INDEX(addr, walker->level);
 
 		table_gfn = gpte_to_gfn(pte);
@@ -160,43 +168,64 @@
 		walker->table_gfn[walker->level - 1] = table_gfn;
 		walker->pte_gpa[walker->level - 1] = pte_gpa;
 
-		if (kvm_read_guest_page_mmu(vcpu, mmu, table_gfn, &pte,
-					    offset, sizeof(pte),
-					    PFERR_USER_MASK|PFERR_WRITE_MASK)) {
+		real_gfn = mmu->translate_gpa(vcpu, gfn_to_gpa(table_gfn),
+					      PFERR_USER_MASK|PFERR_WRITE_MASK);
+		if (unlikely(real_gfn == UNMAPPED_GVA)) {
+			present = false;
+			break;
+		}
+		real_gfn = gpa_to_gfn(real_gfn);
+
+		host_addr = gfn_to_hva(vcpu->kvm, real_gfn);
+		if (unlikely(kvm_is_error_hva(host_addr))) {
+			present = false;
+			break;
+		}
+
+		ptep_user = (pt_element_t __user *)((void *)host_addr + offset);
+		if (unlikely(__copy_from_user(&pte, ptep_user, sizeof(pte)))) {
 			present = false;
 			break;
 		}
 
 		trace_kvm_mmu_paging_element(pte, walker->level);
 
-		if (!is_present_gpte(pte)) {
+		if (unlikely(!is_present_gpte(pte))) {
 			present = false;
 			break;
 		}
 
-		if (is_rsvd_bits_set(&vcpu->arch.mmu, pte, walker->level)) {
+		if (unlikely(is_rsvd_bits_set(&vcpu->arch.mmu, pte,
+					      walker->level))) {
 			rsvd_fault = true;
 			break;
 		}
 
-		if (write_fault && !is_writable_pte(pte))
-			if (user_fault || is_write_protection(vcpu))
-				eperm = true;
+		if (unlikely(write_fault && !is_writable_pte(pte)
+			     && (user_fault || is_write_protection(vcpu))))
+			eperm = true;
 
-		if (user_fault && !(pte & PT_USER_MASK))
+		if (unlikely(user_fault && !(pte & PT_USER_MASK)))
 			eperm = true;
 
 #if PTTYPE == 64
-		if (fetch_fault && (pte & PT64_NX_MASK))
+		if (unlikely(fetch_fault && (pte & PT64_NX_MASK)))
 			eperm = true;
 #endif
 
-		if (!eperm && !rsvd_fault && !(pte & PT_ACCESSED_MASK)) {
+		if (!eperm && !rsvd_fault
+		    && unlikely(!(pte & PT_ACCESSED_MASK))) {
+			int ret;
 			trace_kvm_mmu_set_accessed_bit(table_gfn, index,
 						       sizeof(pte));
-			if (FNAME(cmpxchg_gpte)(vcpu->kvm, table_gfn,
-			    index, pte, pte|PT_ACCESSED_MASK))
+			ret = FNAME(cmpxchg_gpte)(vcpu, mmu, ptep_user, index,
+						  pte, pte|PT_ACCESSED_MASK);
+			if (unlikely(ret < 0)) {
+				present = false;
+				break;
+			} else if (ret)
 				goto walk;
+
 			mark_page_dirty(vcpu->kvm, table_gfn);
 			pte |= PT_ACCESSED_MASK;
 		}
@@ -241,17 +270,21 @@
 		--walker->level;
 	}
 
-	if (!present || eperm || rsvd_fault)
+	if (unlikely(!present || eperm || rsvd_fault))
 		goto error;
 
-	if (write_fault && !is_dirty_gpte(pte)) {
-		bool ret;
+	if (write_fault && unlikely(!is_dirty_gpte(pte))) {
+		int ret;
 
 		trace_kvm_mmu_set_dirty_bit(table_gfn, index, sizeof(pte));
-		ret = FNAME(cmpxchg_gpte)(vcpu->kvm, table_gfn, index, pte,
-			    pte|PT_DIRTY_MASK);
-		if (ret)
+		ret = FNAME(cmpxchg_gpte)(vcpu, mmu, ptep_user, index,
+					  pte, pte|PT_DIRTY_MASK);
+		if (unlikely(ret < 0)) {
+			present = false;
+			goto error;
+		} else if (ret)
 			goto walk;
+
 		mark_page_dirty(vcpu->kvm, table_gfn);
 		pte |= PT_DIRTY_MASK;
 		walker->ptes[walker->level - 1] = pte;
@@ -325,7 +358,7 @@
 }
 
 static void FNAME(update_pte)(struct kvm_vcpu *vcpu, struct kvm_mmu_page *sp,
-			      u64 *spte, const void *pte, unsigned long mmu_seq)
+			      u64 *spte, const void *pte)
 {
 	pt_element_t gpte;
 	unsigned pte_access;
@@ -342,8 +375,6 @@
 		kvm_release_pfn_clean(pfn);
 		return;
 	}
-	if (mmu_notifier_retry(vcpu, mmu_seq))
-		return;
 
 	/*
 	 * we call mmu_set_spte() with host_writable = true because that
diff -druN linux-2.6.39-libre/arch/x86/kvm/svm.c linux-3.0-rc7-libre/arch/x86/kvm/svm.c
--- linux-2.6.39-libre/arch/x86/kvm/svm.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/kvm/svm.c	2011-07-11 19:51:52.000000000 -0400
@@ -63,6 +63,10 @@
 
 #define DEBUGCTL_RESERVED_BITS (~(0x3fULL))
 
+#define TSC_RATIO_RSVD          0xffffff0000000000ULL
+#define TSC_RATIO_MIN		0x0000000000000001ULL
+#define TSC_RATIO_MAX		0x000000ffffffffffULL
+
 static bool erratum_383_found __read_mostly;
 
 static const u32 host_save_user_msrs[] = {
@@ -93,14 +97,6 @@
 	/* A VMEXIT is required but not yet emulated */
 	bool exit_required;
 
-	/*
-	 * If we vmexit during an instruction emulation we need this to restore
-	 * the l1 guest rip after the emulation
-	 */
-	unsigned long vmexit_rip;
-	unsigned long vmexit_rsp;
-	unsigned long vmexit_rax;
-
 	/* cache for intercepts of the guest */
 	u32 intercept_cr;
 	u32 intercept_dr;
@@ -144,8 +140,13 @@
 	unsigned int3_injected;
 	unsigned long int3_rip;
 	u32 apf_reason;
+
+	u64  tsc_ratio;
 };
 
+static DEFINE_PER_CPU(u64, current_tsc_ratio);
+#define TSC_RATIO_DEFAULT	0x0100000000ULL
+
 #define MSR_INVALID			0xffffffffU
 
 static struct svm_direct_access_msrs {
@@ -190,6 +191,7 @@
 static int nested_svm_vmexit(struct vcpu_svm *svm);
 static int nested_svm_check_exception(struct vcpu_svm *svm, unsigned nr,
 				      bool has_error_code, u32 error_code);
+static u64 __scale_tsc(u64 ratio, u64 tsc);
 
 enum {
 	VMCB_INTERCEPTS, /* Intercept vectors, TSC offset,
@@ -376,7 +378,6 @@
 };
 
 static DEFINE_PER_CPU(struct svm_cpu_data *, svm_data);
-static uint32_t svm_features;
 
 struct svm_init_data {
 	int cpu;
@@ -569,6 +570,10 @@
 
 static void svm_hardware_disable(void *garbage)
 {
+	/* Make sure we clean up behind us */
+	if (static_cpu_has(X86_FEATURE_TSCRATEMSR))
+		wrmsrl(MSR_AMD64_TSC_RATIO, TSC_RATIO_DEFAULT);
+
 	cpu_svm_disable();
 }
 
@@ -610,6 +615,11 @@
 
 	wrmsrl(MSR_VM_HSAVE_PA, page_to_pfn(sd->save_area) << PAGE_SHIFT);
 
+	if (static_cpu_has(X86_FEATURE_TSCRATEMSR)) {
+		wrmsrl(MSR_AMD64_TSC_RATIO, TSC_RATIO_DEFAULT);
+		__get_cpu_var(current_tsc_ratio) = TSC_RATIO_DEFAULT;
+	}
+
 	svm_init_erratum_383();
 
 	return 0;
@@ -791,6 +801,23 @@
 	if (boot_cpu_has(X86_FEATURE_FXSR_OPT))
 		kvm_enable_efer_bits(EFER_FFXSR);
 
+	if (boot_cpu_has(X86_FEATURE_TSCRATEMSR)) {
+		u64 max;
+
+		kvm_has_tsc_control = true;
+
+		/*
+		 * Make sure the user can only configure tsc_khz values that
+		 * fit into a signed integer.
+		 * A min value is not calculated needed because it will always
+		 * be 1 on all machines and a value of 0 is used to disable
+		 * tsc-scaling for the vcpu.
+		 */
+		max = min(0x7fffffffULL, __scale_tsc(tsc_khz, TSC_RATIO_MAX));
+
+		kvm_max_guest_tsc_khz = max;
+	}
+
 	if (nested) {
 		printk(KERN_INFO "kvm: Nested Virtualization enabled\n");
 		kvm_enable_efer_bits(EFER_SVME | EFER_LMSLE);
@@ -802,8 +829,6 @@
 			goto err;
 	}
 
-	svm_features = cpuid_edx(SVM_CPUID_FUNC);
-
 	if (!boot_cpu_has(X86_FEATURE_NPT))
 		npt_enabled = false;
 
@@ -854,6 +879,64 @@
 	seg->base = 0;
 }
 
+static u64 __scale_tsc(u64 ratio, u64 tsc)
+{
+	u64 mult, frac, _tsc;
+
+	mult  = ratio >> 32;
+	frac  = ratio & ((1ULL << 32) - 1);
+
+	_tsc  = tsc;
+	_tsc *= mult;
+	_tsc += (tsc >> 32) * frac;
+	_tsc += ((tsc & ((1ULL << 32) - 1)) * frac) >> 32;
+
+	return _tsc;
+}
+
+static u64 svm_scale_tsc(struct kvm_vcpu *vcpu, u64 tsc)
+{
+	struct vcpu_svm *svm = to_svm(vcpu);
+	u64 _tsc = tsc;
+
+	if (svm->tsc_ratio != TSC_RATIO_DEFAULT)
+		_tsc = __scale_tsc(svm->tsc_ratio, tsc);
+
+	return _tsc;
+}
+
+static void svm_set_tsc_khz(struct kvm_vcpu *vcpu, u32 user_tsc_khz)
+{
+	struct vcpu_svm *svm = to_svm(vcpu);
+	u64 ratio;
+	u64 khz;
+
+	/* TSC scaling supported? */
+	if (!boot_cpu_has(X86_FEATURE_TSCRATEMSR))
+		return;
+
+	/* TSC-Scaling disabled or guest TSC same frequency as host TSC? */
+	if (user_tsc_khz == 0) {
+		vcpu->arch.virtual_tsc_khz = 0;
+		svm->tsc_ratio = TSC_RATIO_DEFAULT;
+		return;
+	}
+
+	khz = user_tsc_khz;
+
+	/* TSC scaling required  - calculate ratio */
+	ratio = khz << 32;
+	do_div(ratio, tsc_khz);
+
+	if (ratio == 0 || ratio & TSC_RATIO_RSVD) {
+		WARN_ONCE(1, "Invalid TSC ratio - virtual-tsc-khz=%u\n",
+				user_tsc_khz);
+		return;
+	}
+	vcpu->arch.virtual_tsc_khz = user_tsc_khz;
+	svm->tsc_ratio             = ratio;
+}
+
 static void svm_write_tsc_offset(struct kvm_vcpu *vcpu, u64 offset)
 {
 	struct vcpu_svm *svm = to_svm(vcpu);
@@ -880,6 +963,15 @@
 	mark_dirty(svm->vmcb, VMCB_INTERCEPTS);
 }
 
+static u64 svm_compute_tsc_offset(struct kvm_vcpu *vcpu, u64 target_tsc)
+{
+	u64 tsc;
+
+	tsc = svm_scale_tsc(vcpu, native_read_tsc());
+
+	return target_tsc - tsc;
+}
+
 static void init_vmcb(struct vcpu_svm *svm)
 {
 	struct vmcb_control_area *control = &svm->vmcb->control;
@@ -975,7 +1067,7 @@
 	svm_set_efer(&svm->vcpu, 0);
 	save->dr6 = 0xffff0ff0;
 	save->dr7 = 0x400;
-	save->rflags = 2;
+	kvm_set_rflags(&svm->vcpu, 2);
 	save->rip = 0x0000fff0;
 	svm->vcpu.arch.regs[VCPU_REGS_RIP] = save->rip;
 
@@ -1048,6 +1140,8 @@
 		goto out;
 	}
 
+	svm->tsc_ratio = TSC_RATIO_DEFAULT;
+
 	err = kvm_vcpu_init(&svm->vcpu, kvm, id);
 	if (err)
 		goto free_svm;
@@ -1141,6 +1235,12 @@
 
 	for (i = 0; i < NR_HOST_SAVE_USER_MSRS; i++)
 		rdmsrl(host_save_user_msrs[i], svm->host_user_msrs[i]);
+
+	if (static_cpu_has(X86_FEATURE_TSCRATEMSR) &&
+	    svm->tsc_ratio != __get_cpu_var(current_tsc_ratio)) {
+		__get_cpu_var(current_tsc_ratio) = svm->tsc_ratio;
+		wrmsrl(MSR_AMD64_TSC_RATIO, svm->tsc_ratio);
+	}
 }
 
 static void svm_vcpu_put(struct kvm_vcpu *vcpu)
@@ -1365,31 +1465,6 @@
 {
 	struct vcpu_svm *svm = to_svm(vcpu);
 
-	if (is_guest_mode(vcpu)) {
-		/*
-		 * We are here because we run in nested mode, the host kvm
-		 * intercepts cr0 writes but the l1 hypervisor does not.
-		 * But the L1 hypervisor may intercept selective cr0 writes.
-		 * This needs to be checked here.
-		 */
-		unsigned long old, new;
-
-		/* Remove bits that would trigger a real cr0 write intercept */
-		old = vcpu->arch.cr0 & SVM_CR0_SELECTIVE_MASK;
-		new = cr0 & SVM_CR0_SELECTIVE_MASK;
-
-		if (old == new) {
-			/* cr0 write with ts and mp unchanged */
-			svm->vmcb->control.exit_code = SVM_EXIT_CR0_SEL_WRITE;
-			if (nested_svm_exit_handled(svm) == NESTED_EXIT_DONE) {
-				svm->nested.vmexit_rip = kvm_rip_read(vcpu);
-				svm->nested.vmexit_rsp = kvm_register_read(vcpu, VCPU_REGS_RSP);
-				svm->nested.vmexit_rax = kvm_register_read(vcpu, VCPU_REGS_RAX);
-				return;
-			}
-		}
-	}
-
 #ifdef CONFIG_X86_64
 	if (vcpu->arch.efer & EFER_LME) {
 		if (!is_paging(vcpu) && (cr0 & X86_CR0_PG)) {
@@ -2127,7 +2202,7 @@
 	nested_vmcb->save.cr3    = kvm_read_cr3(&svm->vcpu);
 	nested_vmcb->save.cr2    = vmcb->save.cr2;
 	nested_vmcb->save.cr4    = svm->vcpu.arch.cr4;
-	nested_vmcb->save.rflags = vmcb->save.rflags;
+	nested_vmcb->save.rflags = kvm_get_rflags(&svm->vcpu);
 	nested_vmcb->save.rip    = vmcb->save.rip;
 	nested_vmcb->save.rsp    = vmcb->save.rsp;
 	nested_vmcb->save.rax    = vmcb->save.rax;
@@ -2184,7 +2259,7 @@
 	svm->vmcb->save.ds = hsave->save.ds;
 	svm->vmcb->save.gdtr = hsave->save.gdtr;
 	svm->vmcb->save.idtr = hsave->save.idtr;
-	svm->vmcb->save.rflags = hsave->save.rflags;
+	kvm_set_rflags(&svm->vcpu, hsave->save.rflags);
 	svm_set_efer(&svm->vcpu, hsave->save.efer);
 	svm_set_cr0(&svm->vcpu, hsave->save.cr0 | X86_CR0_PE);
 	svm_set_cr4(&svm->vcpu, hsave->save.cr4);
@@ -2312,7 +2387,7 @@
 	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.rflags = kvm_get_rflags(&svm->vcpu);
 	hsave->save.rip    = kvm_rip_read(&svm->vcpu);
 	hsave->save.rsp    = vmcb->save.rsp;
 	hsave->save.rax    = vmcb->save.rax;
@@ -2323,7 +2398,7 @@
 
 	copy_vmcb_control_area(hsave, vmcb);
 
-	if (svm->vmcb->save.rflags & X86_EFLAGS_IF)
+	if (kvm_get_rflags(&svm->vcpu) & X86_EFLAGS_IF)
 		svm->vcpu.arch.hflags |= HF_HIF_MASK;
 	else
 		svm->vcpu.arch.hflags &= ~HF_HIF_MASK;
@@ -2341,7 +2416,7 @@
 	svm->vmcb->save.ds = nested_vmcb->save.ds;
 	svm->vmcb->save.gdtr = nested_vmcb->save.gdtr;
 	svm->vmcb->save.idtr = nested_vmcb->save.idtr;
-	svm->vmcb->save.rflags = nested_vmcb->save.rflags;
+	kvm_set_rflags(&svm->vcpu, nested_vmcb->save.rflags);
 	svm_set_efer(&svm->vcpu, nested_vmcb->save.efer);
 	svm_set_cr0(&svm->vcpu, nested_vmcb->save.cr0);
 	svm_set_cr4(&svm->vcpu, nested_vmcb->save.cr4);
@@ -2443,13 +2518,13 @@
 	if (nested_svm_check_permissions(svm))
 		return 1;
 
-	svm->next_rip = kvm_rip_read(&svm->vcpu) + 3;
-	skip_emulated_instruction(&svm->vcpu);
-
 	nested_vmcb = nested_svm_map(svm, svm->vmcb->save.rax, &page);
 	if (!nested_vmcb)
 		return 1;
 
+	svm->next_rip = kvm_rip_read(&svm->vcpu) + 3;
+	skip_emulated_instruction(&svm->vcpu);
+
 	nested_svm_vmloadsave(nested_vmcb, svm->vmcb);
 	nested_svm_unmap(page);
 
@@ -2464,13 +2539,13 @@
 	if (nested_svm_check_permissions(svm))
 		return 1;
 
-	svm->next_rip = kvm_rip_read(&svm->vcpu) + 3;
-	skip_emulated_instruction(&svm->vcpu);
-
 	nested_vmcb = nested_svm_map(svm, svm->vmcb->save.rax, &page);
 	if (!nested_vmcb)
 		return 1;
 
+	svm->next_rip = kvm_rip_read(&svm->vcpu) + 3;
+	skip_emulated_instruction(&svm->vcpu);
+
 	nested_svm_vmloadsave(svm->vmcb, nested_vmcb);
 	nested_svm_unmap(page);
 
@@ -2676,6 +2751,29 @@
 	return emulate_instruction(&svm->vcpu, 0) == EMULATE_DONE;
 }
 
+bool check_selective_cr0_intercepted(struct vcpu_svm *svm, unsigned long val)
+{
+	unsigned long cr0 = svm->vcpu.arch.cr0;
+	bool ret = false;
+	u64 intercept;
+
+	intercept = svm->nested.intercept;
+
+	if (!is_guest_mode(&svm->vcpu) ||
+	    (!(intercept & (1ULL << INTERCEPT_SELECTIVE_CR0))))
+		return false;
+
+	cr0 &= ~SVM_CR0_SELECTIVE_MASK;
+	val &= ~SVM_CR0_SELECTIVE_MASK;
+
+	if (cr0 ^ val) {
+		svm->vmcb->control.exit_code = SVM_EXIT_CR0_SEL_WRITE;
+		ret = (nested_svm_exit_handled(svm) == NESTED_EXIT_DONE);
+	}
+
+	return ret;
+}
+
 #define CR_VALID (1ULL << 63)
 
 static int cr_interception(struct vcpu_svm *svm)
@@ -2699,7 +2797,11 @@
 		val = kvm_register_read(&svm->vcpu, reg);
 		switch (cr) {
 		case 0:
-			err = kvm_set_cr0(&svm->vcpu, val);
+			if (!check_selective_cr0_intercepted(svm, val))
+				err = kvm_set_cr0(&svm->vcpu, val);
+			else
+				return 1;
+
 			break;
 		case 3:
 			err = kvm_set_cr3(&svm->vcpu, val);
@@ -2744,23 +2846,6 @@
 	return 1;
 }
 
-static int cr0_write_interception(struct vcpu_svm *svm)
-{
-	struct kvm_vcpu *vcpu = &svm->vcpu;
-	int r;
-
-	r = cr_interception(svm);
-
-	if (svm->nested.vmexit_rip) {
-		kvm_register_write(vcpu, VCPU_REGS_RIP, svm->nested.vmexit_rip);
-		kvm_register_write(vcpu, VCPU_REGS_RSP, svm->nested.vmexit_rsp);
-		kvm_register_write(vcpu, VCPU_REGS_RAX, svm->nested.vmexit_rax);
-		svm->nested.vmexit_rip = 0;
-	}
-
-	return r;
-}
-
 static int dr_interception(struct vcpu_svm *svm)
 {
 	int reg, dr;
@@ -2813,7 +2898,9 @@
 	case MSR_IA32_TSC: {
 		struct vmcb *vmcb = get_host_vmcb(svm);
 
-		*data = vmcb->control.tsc_offset + native_read_tsc();
+		*data = vmcb->control.tsc_offset +
+			svm_scale_tsc(vcpu, native_read_tsc());
+
 		break;
 	}
 	case MSR_STAR:
@@ -3048,7 +3135,7 @@
 	[SVM_EXIT_READ_CR4]			= cr_interception,
 	[SVM_EXIT_READ_CR8]			= cr_interception,
 	[SVM_EXIT_CR0_SEL_WRITE]		= emulate_on_interception,
-	[SVM_EXIT_WRITE_CR0]			= cr0_write_interception,
+	[SVM_EXIT_WRITE_CR0]			= cr_interception,
 	[SVM_EXIT_WRITE_CR3]			= cr_interception,
 	[SVM_EXIT_WRITE_CR4]			= cr_interception,
 	[SVM_EXIT_WRITE_CR8]			= cr8_write_interception,
@@ -3104,97 +3191,109 @@
 	[SVM_EXIT_NPF]				= pf_interception,
 };
 
-void dump_vmcb(struct kvm_vcpu *vcpu)
+static void dump_vmcb(struct kvm_vcpu *vcpu)
 {
 	struct vcpu_svm *svm = to_svm(vcpu);
 	struct vmcb_control_area *control = &svm->vmcb->control;
 	struct vmcb_save_area *save = &svm->vmcb->save;
 
 	pr_err("VMCB Control Area:\n");
-	pr_err("cr_read:            %04x\n", control->intercept_cr & 0xffff);
-	pr_err("cr_write:           %04x\n", control->intercept_cr >> 16);
-	pr_err("dr_read:            %04x\n", control->intercept_dr & 0xffff);
-	pr_err("dr_write:           %04x\n", control->intercept_dr >> 16);
-	pr_err("exceptions:         %08x\n", control->intercept_exceptions);
-	pr_err("intercepts:         %016llx\n", control->intercept);
-	pr_err("pause filter count: %d\n", control->pause_filter_count);
-	pr_err("iopm_base_pa:       %016llx\n", control->iopm_base_pa);
-	pr_err("msrpm_base_pa:      %016llx\n", control->msrpm_base_pa);
-	pr_err("tsc_offset:         %016llx\n", control->tsc_offset);
-	pr_err("asid:               %d\n", control->asid);
-	pr_err("tlb_ctl:            %d\n", control->tlb_ctl);
-	pr_err("int_ctl:            %08x\n", control->int_ctl);
-	pr_err("int_vector:         %08x\n", control->int_vector);
-	pr_err("int_state:          %08x\n", control->int_state);
-	pr_err("exit_code:          %08x\n", control->exit_code);
-	pr_err("exit_info1:         %016llx\n", control->exit_info_1);
-	pr_err("exit_info2:         %016llx\n", control->exit_info_2);
-	pr_err("exit_int_info:      %08x\n", control->exit_int_info);
-	pr_err("exit_int_info_err:  %08x\n", control->exit_int_info_err);
-	pr_err("nested_ctl:         %lld\n", control->nested_ctl);
-	pr_err("nested_cr3:         %016llx\n", control->nested_cr3);
-	pr_err("event_inj:          %08x\n", control->event_inj);
-	pr_err("event_inj_err:      %08x\n", control->event_inj_err);
-	pr_err("lbr_ctl:            %lld\n", control->lbr_ctl);
-	pr_err("next_rip:           %016llx\n", control->next_rip);
+	pr_err("%-20s%04x\n", "cr_read:", control->intercept_cr & 0xffff);
+	pr_err("%-20s%04x\n", "cr_write:", control->intercept_cr >> 16);
+	pr_err("%-20s%04x\n", "dr_read:", control->intercept_dr & 0xffff);
+	pr_err("%-20s%04x\n", "dr_write:", control->intercept_dr >> 16);
+	pr_err("%-20s%08x\n", "exceptions:", control->intercept_exceptions);
+	pr_err("%-20s%016llx\n", "intercepts:", control->intercept);
+	pr_err("%-20s%d\n", "pause filter count:", control->pause_filter_count);
+	pr_err("%-20s%016llx\n", "iopm_base_pa:", control->iopm_base_pa);
+	pr_err("%-20s%016llx\n", "msrpm_base_pa:", control->msrpm_base_pa);
+	pr_err("%-20s%016llx\n", "tsc_offset:", control->tsc_offset);
+	pr_err("%-20s%d\n", "asid:", control->asid);
+	pr_err("%-20s%d\n", "tlb_ctl:", control->tlb_ctl);
+	pr_err("%-20s%08x\n", "int_ctl:", control->int_ctl);
+	pr_err("%-20s%08x\n", "int_vector:", control->int_vector);
+	pr_err("%-20s%08x\n", "int_state:", control->int_state);
+	pr_err("%-20s%08x\n", "exit_code:", control->exit_code);
+	pr_err("%-20s%016llx\n", "exit_info1:", control->exit_info_1);
+	pr_err("%-20s%016llx\n", "exit_info2:", control->exit_info_2);
+	pr_err("%-20s%08x\n", "exit_int_info:", control->exit_int_info);
+	pr_err("%-20s%08x\n", "exit_int_info_err:", control->exit_int_info_err);
+	pr_err("%-20s%lld\n", "nested_ctl:", control->nested_ctl);
+	pr_err("%-20s%016llx\n", "nested_cr3:", control->nested_cr3);
+	pr_err("%-20s%08x\n", "event_inj:", control->event_inj);
+	pr_err("%-20s%08x\n", "event_inj_err:", control->event_inj_err);
+	pr_err("%-20s%lld\n", "lbr_ctl:", control->lbr_ctl);
+	pr_err("%-20s%016llx\n", "next_rip:", control->next_rip);
 	pr_err("VMCB State Save Area:\n");
-	pr_err("es:   s: %04x a: %04x l: %08x b: %016llx\n",
-		save->es.selector, save->es.attrib,
-		save->es.limit, save->es.base);
-	pr_err("cs:   s: %04x a: %04x l: %08x b: %016llx\n",
-		save->cs.selector, save->cs.attrib,
-		save->cs.limit, save->cs.base);
-	pr_err("ss:   s: %04x a: %04x l: %08x b: %016llx\n",
-		save->ss.selector, save->ss.attrib,
-		save->ss.limit, save->ss.base);
-	pr_err("ds:   s: %04x a: %04x l: %08x b: %016llx\n",
-		save->ds.selector, save->ds.attrib,
-		save->ds.limit, save->ds.base);
-	pr_err("fs:   s: %04x a: %04x l: %08x b: %016llx\n",
-		save->fs.selector, save->fs.attrib,
-		save->fs.limit, save->fs.base);
-	pr_err("gs:   s: %04x a: %04x l: %08x b: %016llx\n",
-		save->gs.selector, save->gs.attrib,
-		save->gs.limit, save->gs.base);
-	pr_err("gdtr: s: %04x a: %04x l: %08x b: %016llx\n",
-		save->gdtr.selector, save->gdtr.attrib,
-		save->gdtr.limit, save->gdtr.base);
-	pr_err("ldtr: s: %04x a: %04x l: %08x b: %016llx\n",
-		save->ldtr.selector, save->ldtr.attrib,
-		save->ldtr.limit, save->ldtr.base);
-	pr_err("idtr: s: %04x a: %04x l: %08x b: %016llx\n",
-		save->idtr.selector, save->idtr.attrib,
-		save->idtr.limit, save->idtr.base);
-	pr_err("tr:   s: %04x a: %04x l: %08x b: %016llx\n",
-		save->tr.selector, save->tr.attrib,
-		save->tr.limit, save->tr.base);
+	pr_err("%-5s s: %04x a: %04x l: %08x b: %016llx\n",
+	       "es:",
+	       save->es.selector, save->es.attrib,
+	       save->es.limit, save->es.base);
+	pr_err("%-5s s: %04x a: %04x l: %08x b: %016llx\n",
+	       "cs:",
+	       save->cs.selector, save->cs.attrib,
+	       save->cs.limit, save->cs.base);
+	pr_err("%-5s s: %04x a: %04x l: %08x b: %016llx\n",
+	       "ss:",
+	       save->ss.selector, save->ss.attrib,
+	       save->ss.limit, save->ss.base);
+	pr_err("%-5s s: %04x a: %04x l: %08x b: %016llx\n",
+	       "ds:",
+	       save->ds.selector, save->ds.attrib,
+	       save->ds.limit, save->ds.base);
+	pr_err("%-5s s: %04x a: %04x l: %08x b: %016llx\n",
+	       "fs:",
+	       save->fs.selector, save->fs.attrib,
+	       save->fs.limit, save->fs.base);
+	pr_err("%-5s s: %04x a: %04x l: %08x b: %016llx\n",
+	       "gs:",
+	       save->gs.selector, save->gs.attrib,
+	       save->gs.limit, save->gs.base);
+	pr_err("%-5s s: %04x a: %04x l: %08x b: %016llx\n",
+	       "gdtr:",
+	       save->gdtr.selector, save->gdtr.attrib,
+	       save->gdtr.limit, save->gdtr.base);
+	pr_err("%-5s s: %04x a: %04x l: %08x b: %016llx\n",
+	       "ldtr:",
+	       save->ldtr.selector, save->ldtr.attrib,
+	       save->ldtr.limit, save->ldtr.base);
+	pr_err("%-5s s: %04x a: %04x l: %08x b: %016llx\n",
+	       "idtr:",
+	       save->idtr.selector, save->idtr.attrib,
+	       save->idtr.limit, save->idtr.base);
+	pr_err("%-5s s: %04x a: %04x l: %08x b: %016llx\n",
+	       "tr:",
+	       save->tr.selector, save->tr.attrib,
+	       save->tr.limit, save->tr.base);
 	pr_err("cpl:            %d                efer:         %016llx\n",
 		save->cpl, save->efer);
-	pr_err("cr0:            %016llx cr2:          %016llx\n",
-		save->cr0, save->cr2);
-	pr_err("cr3:            %016llx cr4:          %016llx\n",
-		save->cr3, save->cr4);
-	pr_err("dr6:            %016llx dr7:          %016llx\n",
-		save->dr6, save->dr7);
-	pr_err("rip:            %016llx rflags:       %016llx\n",
-		save->rip, save->rflags);
-	pr_err("rsp:            %016llx rax:          %016llx\n",
-		save->rsp, save->rax);
-	pr_err("star:           %016llx lstar:        %016llx\n",
-		save->star, save->lstar);
-	pr_err("cstar:          %016llx sfmask:       %016llx\n",
-		save->cstar, save->sfmask);
-	pr_err("kernel_gs_base: %016llx sysenter_cs:  %016llx\n",
-		save->kernel_gs_base, save->sysenter_cs);
-	pr_err("sysenter_esp:   %016llx sysenter_eip: %016llx\n",
-		save->sysenter_esp, save->sysenter_eip);
-	pr_err("gpat:           %016llx dbgctl:       %016llx\n",
-		save->g_pat, save->dbgctl);
-	pr_err("br_from:        %016llx br_to:        %016llx\n",
-		save->br_from, save->br_to);
-	pr_err("excp_from:      %016llx excp_to:      %016llx\n",
-		save->last_excp_from, save->last_excp_to);
-
+	pr_err("%-15s %016llx %-13s %016llx\n",
+	       "cr0:", save->cr0, "cr2:", save->cr2);
+	pr_err("%-15s %016llx %-13s %016llx\n",
+	       "cr3:", save->cr3, "cr4:", save->cr4);
+	pr_err("%-15s %016llx %-13s %016llx\n",
+	       "dr6:", save->dr6, "dr7:", save->dr7);
+	pr_err("%-15s %016llx %-13s %016llx\n",
+	       "rip:", save->rip, "rflags:", save->rflags);
+	pr_err("%-15s %016llx %-13s %016llx\n",
+	       "rsp:", save->rsp, "rax:", save->rax);
+	pr_err("%-15s %016llx %-13s %016llx\n",
+	       "star:", save->star, "lstar:", save->lstar);
+	pr_err("%-15s %016llx %-13s %016llx\n",
+	       "cstar:", save->cstar, "sfmask:", save->sfmask);
+	pr_err("%-15s %016llx %-13s %016llx\n",
+	       "kernel_gs_base:", save->kernel_gs_base,
+	       "sysenter_cs:", save->sysenter_cs);
+	pr_err("%-15s %016llx %-13s %016llx\n",
+	       "sysenter_esp:", save->sysenter_esp,
+	       "sysenter_eip:", save->sysenter_eip);
+	pr_err("%-15s %016llx %-13s %016llx\n",
+	       "gpat:", save->g_pat, "dbgctl:", save->dbgctl);
+	pr_err("%-15s %016llx %-13s %016llx\n",
+	       "br_from:", save->br_from, "br_to:", save->br_to);
+	pr_err("%-15s %016llx %-13s %016llx\n",
+	       "excp_from:", save->last_excp_from,
+	       "excp_to:", save->last_excp_to);
 }
 
 static void svm_get_exit_info(struct kvm_vcpu *vcpu, u64 *info1, u64 *info2)
@@ -3384,7 +3483,7 @@
 	     (vmcb->control.int_state & SVM_INTERRUPT_SHADOW_MASK))
 		return 0;
 
-	ret = !!(vmcb->save.rflags & X86_EFLAGS_IF);
+	ret = !!(kvm_get_rflags(vcpu) & X86_EFLAGS_IF);
 
 	if (is_guest_mode(vcpu))
 		return ret && !(svm->vcpu.arch.hflags & HF_VINTR_MASK);
@@ -3871,6 +3970,186 @@
 	update_cr0_intercept(svm);
 }
 
+#define PRE_EX(exit)  { .exit_code = (exit), \
+			.stage = X86_ICPT_PRE_EXCEPT, }
+#define POST_EX(exit) { .exit_code = (exit), \
+			.stage = X86_ICPT_POST_EXCEPT, }
+#define POST_MEM(exit) { .exit_code = (exit), \
+			.stage = X86_ICPT_POST_MEMACCESS, }
+
+static struct __x86_intercept {
+	u32 exit_code;
+	enum x86_intercept_stage stage;
+} x86_intercept_map[] = {
+	[x86_intercept_cr_read]		= POST_EX(SVM_EXIT_READ_CR0),
+	[x86_intercept_cr_write]	= POST_EX(SVM_EXIT_WRITE_CR0),
+	[x86_intercept_clts]		= POST_EX(SVM_EXIT_WRITE_CR0),
+	[x86_intercept_lmsw]		= POST_EX(SVM_EXIT_WRITE_CR0),
+	[x86_intercept_smsw]		= POST_EX(SVM_EXIT_READ_CR0),
+	[x86_intercept_dr_read]		= POST_EX(SVM_EXIT_READ_DR0),
+	[x86_intercept_dr_write]	= POST_EX(SVM_EXIT_WRITE_DR0),
+	[x86_intercept_sldt]		= POST_EX(SVM_EXIT_LDTR_READ),
+	[x86_intercept_str]		= POST_EX(SVM_EXIT_TR_READ),
+	[x86_intercept_lldt]		= POST_EX(SVM_EXIT_LDTR_WRITE),
+	[x86_intercept_ltr]		= POST_EX(SVM_EXIT_TR_WRITE),
+	[x86_intercept_sgdt]		= POST_EX(SVM_EXIT_GDTR_READ),
+	[x86_intercept_sidt]		= POST_EX(SVM_EXIT_IDTR_READ),
+	[x86_intercept_lgdt]		= POST_EX(SVM_EXIT_GDTR_WRITE),
+	[x86_intercept_lidt]		= POST_EX(SVM_EXIT_IDTR_WRITE),
+	[x86_intercept_vmrun]		= POST_EX(SVM_EXIT_VMRUN),
+	[x86_intercept_vmmcall]		= POST_EX(SVM_EXIT_VMMCALL),
+	[x86_intercept_vmload]		= POST_EX(SVM_EXIT_VMLOAD),
+	[x86_intercept_vmsave]		= POST_EX(SVM_EXIT_VMSAVE),
+	[x86_intercept_stgi]		= POST_EX(SVM_EXIT_STGI),
+	[x86_intercept_clgi]		= POST_EX(SVM_EXIT_CLGI),
+	[x86_intercept_skinit]		= POST_EX(SVM_EXIT_SKINIT),
+	[x86_intercept_invlpga]		= POST_EX(SVM_EXIT_INVLPGA),
+	[x86_intercept_rdtscp]		= POST_EX(SVM_EXIT_RDTSCP),
+	[x86_intercept_monitor]		= POST_MEM(SVM_EXIT_MONITOR),
+	[x86_intercept_mwait]		= POST_EX(SVM_EXIT_MWAIT),
+	[x86_intercept_invlpg]		= POST_EX(SVM_EXIT_INVLPG),
+	[x86_intercept_invd]		= POST_EX(SVM_EXIT_INVD),
+	[x86_intercept_wbinvd]		= POST_EX(SVM_EXIT_WBINVD),
+	[x86_intercept_wrmsr]		= POST_EX(SVM_EXIT_MSR),
+	[x86_intercept_rdtsc]		= POST_EX(SVM_EXIT_RDTSC),
+	[x86_intercept_rdmsr]		= POST_EX(SVM_EXIT_MSR),
+	[x86_intercept_rdpmc]		= POST_EX(SVM_EXIT_RDPMC),
+	[x86_intercept_cpuid]		= PRE_EX(SVM_EXIT_CPUID),
+	[x86_intercept_rsm]		= PRE_EX(SVM_EXIT_RSM),
+	[x86_intercept_pause]		= PRE_EX(SVM_EXIT_PAUSE),
+	[x86_intercept_pushf]		= PRE_EX(SVM_EXIT_PUSHF),
+	[x86_intercept_popf]		= PRE_EX(SVM_EXIT_POPF),
+	[x86_intercept_intn]		= PRE_EX(SVM_EXIT_SWINT),
+	[x86_intercept_iret]		= PRE_EX(SVM_EXIT_IRET),
+	[x86_intercept_icebp]		= PRE_EX(SVM_EXIT_ICEBP),
+	[x86_intercept_hlt]		= POST_EX(SVM_EXIT_HLT),
+	[x86_intercept_in]		= POST_EX(SVM_EXIT_IOIO),
+	[x86_intercept_ins]		= POST_EX(SVM_EXIT_IOIO),
+	[x86_intercept_out]		= POST_EX(SVM_EXIT_IOIO),
+	[x86_intercept_outs]		= POST_EX(SVM_EXIT_IOIO),
+};
+
+#undef PRE_EX
+#undef POST_EX
+#undef POST_MEM
+
+static int svm_check_intercept(struct kvm_vcpu *vcpu,
+			       struct x86_instruction_info *info,
+			       enum x86_intercept_stage stage)
+{
+	struct vcpu_svm *svm = to_svm(vcpu);
+	int vmexit, ret = X86EMUL_CONTINUE;
+	struct __x86_intercept icpt_info;
+	struct vmcb *vmcb = svm->vmcb;
+
+	if (info->intercept >= ARRAY_SIZE(x86_intercept_map))
+		goto out;
+
+	icpt_info = x86_intercept_map[info->intercept];
+
+	if (stage != icpt_info.stage)
+		goto out;
+
+	switch (icpt_info.exit_code) {
+	case SVM_EXIT_READ_CR0:
+		if (info->intercept == x86_intercept_cr_read)
+			icpt_info.exit_code += info->modrm_reg;
+		break;
+	case SVM_EXIT_WRITE_CR0: {
+		unsigned long cr0, val;
+		u64 intercept;
+
+		if (info->intercept == x86_intercept_cr_write)
+			icpt_info.exit_code += info->modrm_reg;
+
+		if (icpt_info.exit_code != SVM_EXIT_WRITE_CR0)
+			break;
+
+		intercept = svm->nested.intercept;
+
+		if (!(intercept & (1ULL << INTERCEPT_SELECTIVE_CR0)))
+			break;
+
+		cr0 = vcpu->arch.cr0 & ~SVM_CR0_SELECTIVE_MASK;
+		val = info->src_val  & ~SVM_CR0_SELECTIVE_MASK;
+
+		if (info->intercept == x86_intercept_lmsw) {
+			cr0 &= 0xfUL;
+			val &= 0xfUL;
+			/* lmsw can't clear PE - catch this here */
+			if (cr0 & X86_CR0_PE)
+				val |= X86_CR0_PE;
+		}
+
+		if (cr0 ^ val)
+			icpt_info.exit_code = SVM_EXIT_CR0_SEL_WRITE;
+
+		break;
+	}
+	case SVM_EXIT_READ_DR0:
+	case SVM_EXIT_WRITE_DR0:
+		icpt_info.exit_code += info->modrm_reg;
+		break;
+	case SVM_EXIT_MSR:
+		if (info->intercept == x86_intercept_wrmsr)
+			vmcb->control.exit_info_1 = 1;
+		else
+			vmcb->control.exit_info_1 = 0;
+		break;
+	case SVM_EXIT_PAUSE:
+		/*
+		 * We get this for NOP only, but pause
+		 * is rep not, check this here
+		 */
+		if (info->rep_prefix != REPE_PREFIX)
+			goto out;
+	case SVM_EXIT_IOIO: {
+		u64 exit_info;
+		u32 bytes;
+
+		exit_info = (vcpu->arch.regs[VCPU_REGS_RDX] & 0xffff) << 16;
+
+		if (info->intercept == x86_intercept_in ||
+		    info->intercept == x86_intercept_ins) {
+			exit_info |= SVM_IOIO_TYPE_MASK;
+			bytes = info->src_bytes;
+		} else {
+			bytes = info->dst_bytes;
+		}
+
+		if (info->intercept == x86_intercept_outs ||
+		    info->intercept == x86_intercept_ins)
+			exit_info |= SVM_IOIO_STR_MASK;
+
+		if (info->rep_prefix)
+			exit_info |= SVM_IOIO_REP_MASK;
+
+		bytes = min(bytes, 4u);
+
+		exit_info |= bytes << SVM_IOIO_SIZE_SHIFT;
+
+		exit_info |= (u32)info->ad_bytes << (SVM_IOIO_ASIZE_SHIFT - 1);
+
+		vmcb->control.exit_info_1 = exit_info;
+		vmcb->control.exit_info_2 = info->next_rip;
+
+		break;
+	}
+	default:
+		break;
+	}
+
+	vmcb->control.next_rip  = info->next_rip;
+	vmcb->control.exit_code = icpt_info.exit_code;
+	vmexit = nested_svm_exit_handled(svm);
+
+	ret = (vmexit == NESTED_EXIT_DONE) ? X86EMUL_INTERCEPTED
+					   : X86EMUL_CONTINUE;
+
+out:
+	return ret;
+}
+
 static struct kvm_x86_ops svm_x86_ops = {
 	.cpu_has_kvm_support = has_svm,
 	.disabled_by_bios = is_disabled,
@@ -3952,10 +4231,14 @@
 
 	.has_wbinvd_exit = svm_has_wbinvd_exit,
 
+	.set_tsc_khz = svm_set_tsc_khz,
 	.write_tsc_offset = svm_write_tsc_offset,
 	.adjust_tsc_offset = svm_adjust_tsc_offset,
+	.compute_tsc_offset = svm_compute_tsc_offset,
 
 	.set_tdp_cr3 = set_tdp_cr3,
+
+	.check_intercept = svm_check_intercept,
 };
 
 static int __init svm_init(void)
diff -druN linux-2.6.39-libre/arch/x86/kvm/vmx.c linux-3.0-rc7-libre/arch/x86/kvm/vmx.c
--- linux-2.6.39-libre/arch/x86/kvm/vmx.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/kvm/vmx.c	2011-07-11 19:51:52.000000000 -0400
@@ -128,8 +128,11 @@
 	unsigned long         host_rsp;
 	int                   launched;
 	u8                    fail;
+	u8                    cpl;
+	bool                  nmi_known_unmasked;
 	u32                   exit_intr_info;
 	u32                   idt_vectoring_info;
+	ulong                 rflags;
 	struct shared_msr_entry *guest_msrs;
 	int                   nmsrs;
 	int                   save_nmsrs;
@@ -159,6 +162,10 @@
 			u32 ar;
 		} tr, es, ds, fs, gs;
 	} rmode;
+	struct {
+		u32 bitmask; /* 4 bits per segment (1 bit per field) */
+		struct kvm_save_segment seg[8];
+	} segment_cache;
 	int vpid;
 	bool emulation_required;
 
@@ -171,6 +178,15 @@
 	bool rdtscp_enabled;
 };
 
+enum segment_cache_field {
+	SEG_FIELD_SEL = 0,
+	SEG_FIELD_BASE = 1,
+	SEG_FIELD_LIMIT = 2,
+	SEG_FIELD_AR = 3,
+
+	SEG_FIELD_NR = 4
+};
+
 static inline struct vcpu_vmx *to_vmx(struct kvm_vcpu *vcpu)
 {
 	return container_of(vcpu, struct vcpu_vmx, vcpu);
@@ -643,6 +659,62 @@
 	vmcs_writel(field, vmcs_readl(field) | mask);
 }
 
+static void vmx_segment_cache_clear(struct vcpu_vmx *vmx)
+{
+	vmx->segment_cache.bitmask = 0;
+}
+
+static bool vmx_segment_cache_test_set(struct vcpu_vmx *vmx, unsigned seg,
+				       unsigned field)
+{
+	bool ret;
+	u32 mask = 1 << (seg * SEG_FIELD_NR + field);
+
+	if (!(vmx->vcpu.arch.regs_avail & (1 << VCPU_EXREG_SEGMENTS))) {
+		vmx->vcpu.arch.regs_avail |= (1 << VCPU_EXREG_SEGMENTS);
+		vmx->segment_cache.bitmask = 0;
+	}
+	ret = vmx->segment_cache.bitmask & mask;
+	vmx->segment_cache.bitmask |= mask;
+	return ret;
+}
+
+static u16 vmx_read_guest_seg_selector(struct vcpu_vmx *vmx, unsigned seg)
+{
+	u16 *p = &vmx->segment_cache.seg[seg].selector;
+
+	if (!vmx_segment_cache_test_set(vmx, seg, SEG_FIELD_SEL))
+		*p = vmcs_read16(kvm_vmx_segment_fields[seg].selector);
+	return *p;
+}
+
+static ulong vmx_read_guest_seg_base(struct vcpu_vmx *vmx, unsigned seg)
+{
+	ulong *p = &vmx->segment_cache.seg[seg].base;
+
+	if (!vmx_segment_cache_test_set(vmx, seg, SEG_FIELD_BASE))
+		*p = vmcs_readl(kvm_vmx_segment_fields[seg].base);
+	return *p;
+}
+
+static u32 vmx_read_guest_seg_limit(struct vcpu_vmx *vmx, unsigned seg)
+{
+	u32 *p = &vmx->segment_cache.seg[seg].limit;
+
+	if (!vmx_segment_cache_test_set(vmx, seg, SEG_FIELD_LIMIT))
+		*p = vmcs_read32(kvm_vmx_segment_fields[seg].limit);
+	return *p;
+}
+
+static u32 vmx_read_guest_seg_ar(struct vcpu_vmx *vmx, unsigned seg)
+{
+	u32 *p = &vmx->segment_cache.seg[seg].ar;
+
+	if (!vmx_segment_cache_test_set(vmx, seg, SEG_FIELD_AR))
+		*p = vmcs_read32(kvm_vmx_segment_fields[seg].ar_bytes);
+	return *p;
+}
+
 static void update_exception_bitmap(struct kvm_vcpu *vcpu)
 {
 	u32 eb;
@@ -970,17 +1042,24 @@
 {
 	unsigned long rflags, save_rflags;
 
-	rflags = vmcs_readl(GUEST_RFLAGS);
-	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;
+	if (!test_bit(VCPU_EXREG_RFLAGS, (ulong *)&vcpu->arch.regs_avail)) {
+		__set_bit(VCPU_EXREG_RFLAGS, (ulong *)&vcpu->arch.regs_avail);
+		rflags = vmcs_readl(GUEST_RFLAGS);
+		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;
+		}
+		to_vmx(vcpu)->rflags = rflags;
 	}
-	return rflags;
+	return to_vmx(vcpu)->rflags;
 }
 
 static void vmx_set_rflags(struct kvm_vcpu *vcpu, unsigned long rflags)
 {
+	__set_bit(VCPU_EXREG_RFLAGS, (ulong *)&vcpu->arch.regs_avail);
+	__clear_bit(VCPU_EXREG_CPL, (ulong *)&vcpu->arch.regs_avail);
+	to_vmx(vcpu)->rflags = rflags;
 	if (to_vmx(vcpu)->rmode.vm86_active) {
 		to_vmx(vcpu)->rmode.save_rflags = rflags;
 		rflags |= X86_EFLAGS_IOPL | X86_EFLAGS_VM;
@@ -1053,7 +1132,10 @@
 	}
 
 	if (vmx->rmode.vm86_active) {
-		if (kvm_inject_realmode_interrupt(vcpu, nr) != EMULATE_DONE)
+		int inc_eip = 0;
+		if (kvm_exception_is_soft(nr))
+			inc_eip = vcpu->arch.event_exit_inst_len;
+		if (kvm_inject_realmode_interrupt(vcpu, nr, inc_eip) != EMULATE_DONE)
 			kvm_make_request(KVM_REQ_TRIPLE_FAULT, vcpu);
 		return;
 	}
@@ -1151,6 +1233,16 @@
 }
 
 /*
+ * Empty call-back. Needs to be implemented when VMX enables the SET_TSC_KHZ
+ * ioctl. In this case the call-back should update internal vmx state to make
+ * the changes effective.
+ */
+static void vmx_set_tsc_khz(struct kvm_vcpu *vcpu, u32 user_tsc_khz)
+{
+	/* Nothing to do here */
+}
+
+/*
  * writes 'offset' into guest's timestamp counter offset register
  */
 static void vmx_write_tsc_offset(struct kvm_vcpu *vcpu, u64 offset)
@@ -1164,6 +1256,11 @@
 	vmcs_write64(TSC_OFFSET, offset + adjustment);
 }
 
+static u64 vmx_compute_tsc_offset(struct kvm_vcpu *vcpu, u64 target_tsc)
+{
+	return target_tsc - native_read_tsc();
+}
+
 /*
  * Reads an msr value (of 'msr_index') into 'pdata'.
  * Returns 0 on success, non-0 otherwise.
@@ -1243,9 +1340,11 @@
 		break;
 #ifdef CONFIG_X86_64
 	case MSR_FS_BASE:
+		vmx_segment_cache_clear(vmx);
 		vmcs_writel(GUEST_FS_BASE, data);
 		break;
 	case MSR_GS_BASE:
+		vmx_segment_cache_clear(vmx);
 		vmcs_writel(GUEST_GS_BASE, data);
 		break;
 	case MSR_KERNEL_GS_BASE:
@@ -1689,6 +1788,8 @@
 	vmx->emulation_required = 1;
 	vmx->rmode.vm86_active = 0;
 
+	vmx_segment_cache_clear(vmx);
+
 	vmcs_write16(GUEST_TR_SELECTOR, vmx->rmode.tr.selector);
 	vmcs_writel(GUEST_TR_BASE, vmx->rmode.tr.base);
 	vmcs_write32(GUEST_TR_LIMIT, vmx->rmode.tr.limit);
@@ -1712,6 +1813,8 @@
 	fix_pmode_dataseg(VCPU_SREG_GS, &vmx->rmode.gs);
 	fix_pmode_dataseg(VCPU_SREG_FS, &vmx->rmode.fs);
 
+	vmx_segment_cache_clear(vmx);
+
 	vmcs_write16(GUEST_SS_SELECTOR, 0);
 	vmcs_write32(GUEST_SS_AR_BYTES, 0x93);
 
@@ -1775,6 +1878,8 @@
 		vcpu->srcu_idx = srcu_read_lock(&vcpu->kvm->srcu);
 	}
 
+	vmx_segment_cache_clear(vmx);
+
 	vmx->rmode.tr.selector = vmcs_read16(GUEST_TR_SELECTOR);
 	vmx->rmode.tr.base = vmcs_readl(GUEST_TR_BASE);
 	vmcs_writel(GUEST_TR_BASE, rmode_tss_base(vcpu->kvm));
@@ -1851,6 +1956,8 @@
 {
 	u32 guest_tr_ar;
 
+	vmx_segment_cache_clear(to_vmx(vcpu));
+
 	guest_tr_ar = vmcs_read32(GUEST_TR_AR_BYTES);
 	if ((guest_tr_ar & AR_TYPE_MASK) != AR_TYPE_BUSY_64_TSS) {
 		printk(KERN_DEBUG "%s: tss fixup for long mode. \n",
@@ -1940,7 +2047,8 @@
 					unsigned long cr0,
 					struct kvm_vcpu *vcpu)
 {
-	vmx_decache_cr3(vcpu);
+	if (!test_bit(VCPU_EXREG_CR3, (ulong *)&vcpu->arch.regs_avail))
+		vmx_decache_cr3(vcpu);
 	if (!(cr0 & X86_CR0_PG)) {
 		/* From paging/starting to nonpaging */
 		vmcs_write32(CPU_BASED_VM_EXEC_CONTROL,
@@ -1998,6 +2106,7 @@
 	vmcs_writel(CR0_READ_SHADOW, cr0);
 	vmcs_writel(GUEST_CR0, hw_cr0);
 	vcpu->arch.cr0 = cr0;
+	__clear_bit(VCPU_EXREG_CPL, (ulong *)&vcpu->arch.regs_avail);
 }
 
 static u64 construct_eptp(unsigned long root_hpa)
@@ -2053,7 +2162,6 @@
 			    struct kvm_segment *var, int seg)
 {
 	struct vcpu_vmx *vmx = to_vmx(vcpu);
-	struct kvm_vmx_segment_field *sf = &kvm_vmx_segment_fields[seg];
 	struct kvm_save_segment *save;
 	u32 ar;
 
@@ -2075,13 +2183,13 @@
 		var->limit = save->limit;
 		ar = save->ar;
 		if (seg == VCPU_SREG_TR
-		    || var->selector == vmcs_read16(sf->selector))
+		    || var->selector == vmx_read_guest_seg_selector(vmx, seg))
 			goto use_saved_rmode_seg;
 	}
-	var->base = vmcs_readl(sf->base);
-	var->limit = vmcs_read32(sf->limit);
-	var->selector = vmcs_read16(sf->selector);
-	ar = vmcs_read32(sf->ar_bytes);
+	var->base = vmx_read_guest_seg_base(vmx, seg);
+	var->limit = vmx_read_guest_seg_limit(vmx, seg);
+	var->selector = vmx_read_guest_seg_selector(vmx, seg);
+	ar = vmx_read_guest_seg_ar(vmx, seg);
 use_saved_rmode_seg:
 	if ((ar & AR_UNUSABLE_MASK) && !emulate_invalid_guest_state)
 		ar = 0;
@@ -2098,27 +2206,37 @@
 
 static u64 vmx_get_segment_base(struct kvm_vcpu *vcpu, int seg)
 {
-	struct kvm_vmx_segment_field *sf = &kvm_vmx_segment_fields[seg];
 	struct kvm_segment s;
 
 	if (to_vmx(vcpu)->rmode.vm86_active) {
 		vmx_get_segment(vcpu, &s, seg);
 		return s.base;
 	}
-	return vmcs_readl(sf->base);
+	return vmx_read_guest_seg_base(to_vmx(vcpu), seg);
 }
 
-static int vmx_get_cpl(struct kvm_vcpu *vcpu)
+static int __vmx_get_cpl(struct kvm_vcpu *vcpu)
 {
 	if (!is_protmode(vcpu))
 		return 0;
 
-	if (vmx_get_rflags(vcpu) & X86_EFLAGS_VM) /* if virtual 8086 */
+	if (!is_long_mode(vcpu)
+	    && (kvm_get_rflags(vcpu) & X86_EFLAGS_VM)) /* if virtual 8086 */
 		return 3;
 
-	return vmcs_read16(GUEST_CS_SELECTOR) & 3;
+	return vmx_read_guest_seg_selector(to_vmx(vcpu), VCPU_SREG_CS) & 3;
 }
 
+static int vmx_get_cpl(struct kvm_vcpu *vcpu)
+{
+	if (!test_bit(VCPU_EXREG_CPL, (ulong *)&vcpu->arch.regs_avail)) {
+		__set_bit(VCPU_EXREG_CPL, (ulong *)&vcpu->arch.regs_avail);
+		to_vmx(vcpu)->cpl = __vmx_get_cpl(vcpu);
+	}
+	return to_vmx(vcpu)->cpl;
+}
+
+
 static u32 vmx_segment_access_rights(struct kvm_segment *var)
 {
 	u32 ar;
@@ -2148,6 +2266,8 @@
 	struct kvm_vmx_segment_field *sf = &kvm_vmx_segment_fields[seg];
 	u32 ar;
 
+	vmx_segment_cache_clear(vmx);
+
 	if (vmx->rmode.vm86_active && seg == VCPU_SREG_TR) {
 		vmcs_write16(sf->selector, var->selector);
 		vmx->rmode.tr.selector = var->selector;
@@ -2184,11 +2304,12 @@
 		ar |= 0x1; /* Accessed */
 
 	vmcs_write32(sf->ar_bytes, ar);
+	__clear_bit(VCPU_EXREG_CPL, (ulong *)&vcpu->arch.regs_avail);
 }
 
 static void vmx_get_cs_db_l_bits(struct kvm_vcpu *vcpu, int *db, int *l)
 {
-	u32 ar = vmcs_read32(GUEST_CS_AR_BYTES);
+	u32 ar = vmx_read_guest_seg_ar(to_vmx(vcpu), VCPU_SREG_CS);
 
 	*db = (ar >> 14) & 1;
 	*l = (ar >> 13) & 1;
@@ -2775,6 +2896,8 @@
 	if (ret != 0)
 		goto out;
 
+	vmx_segment_cache_clear(vmx);
+
 	seg_setup(VCPU_SREG_CS);
 	/*
 	 * GUEST_CS_BASE should really be 0xffff0000, but VT vm86 mode
@@ -2904,7 +3027,10 @@
 
 	++vcpu->stat.irq_injections;
 	if (vmx->rmode.vm86_active) {
-		if (kvm_inject_realmode_interrupt(vcpu, irq) != EMULATE_DONE)
+		int inc_eip = 0;
+		if (vcpu->arch.interrupt.soft)
+			inc_eip = vcpu->arch.event_exit_inst_len;
+		if (kvm_inject_realmode_interrupt(vcpu, irq, inc_eip) != EMULATE_DONE)
 			kvm_make_request(KVM_REQ_TRIPLE_FAULT, vcpu);
 		return;
 	}
@@ -2937,8 +3063,9 @@
 	}
 
 	++vcpu->stat.nmi_injections;
+	vmx->nmi_known_unmasked = false;
 	if (vmx->rmode.vm86_active) {
-		if (kvm_inject_realmode_interrupt(vcpu, NMI_VECTOR) != EMULATE_DONE)
+		if (kvm_inject_realmode_interrupt(vcpu, NMI_VECTOR, 0) != EMULATE_DONE)
 			kvm_make_request(KVM_REQ_TRIPLE_FAULT, vcpu);
 		return;
 	}
@@ -2961,6 +3088,8 @@
 {
 	if (!cpu_has_virtual_nmis())
 		return to_vmx(vcpu)->soft_vnmi_blocked;
+	if (to_vmx(vcpu)->nmi_known_unmasked)
+		return false;
 	return vmcs_read32(GUEST_INTERRUPTIBILITY_INFO)	& GUEST_INTR_STATE_NMI;
 }
 
@@ -2974,6 +3103,7 @@
 			vmx->vnmi_blocked_time = 0;
 		}
 	} else {
+		vmx->nmi_known_unmasked = !masked;
 		if (masked)
 			vmcs_set_bits(GUEST_INTERRUPTIBILITY_INFO,
 				      GUEST_INTR_STATE_NMI);
@@ -3091,7 +3221,7 @@
 	enum emulation_result er;
 
 	vect_info = vmx->idt_vectoring_info;
-	intr_info = vmcs_read32(VM_EXIT_INTR_INFO);
+	intr_info = vmx->exit_intr_info;
 
 	if (is_machine_check(intr_info))
 		return handle_machine_check(vcpu);
@@ -3122,7 +3252,6 @@
 	}
 
 	error_code = 0;
-	rip = kvm_rip_read(vcpu);
 	if (intr_info & INTR_INFO_DELIVER_CODE_MASK)
 		error_code = vmcs_read32(VM_EXIT_INTR_ERROR_CODE);
 	if (is_page_fault(intr_info)) {
@@ -3169,6 +3298,7 @@
 		vmx->vcpu.arch.event_exit_inst_len =
 			vmcs_read32(VM_EXIT_INSTRUCTION_LEN);
 		kvm_run->exit_reason = KVM_EXIT_DEBUG;
+		rip = kvm_rip_read(vcpu);
 		kvm_run->debug.arch.pc = vmcs_readl(GUEST_CS_BASE) + rip;
 		kvm_run->debug.arch.exception = ex_no;
 		break;
@@ -3505,9 +3635,7 @@
 		switch (type) {
 		case INTR_TYPE_NMI_INTR:
 			vcpu->arch.nmi_injected = false;
-			if (cpu_has_virtual_nmis())
-				vmcs_set_bits(GUEST_INTERRUPTIBILITY_INFO,
-					      GUEST_INTR_STATE_NMI);
+			vmx_set_nmi_mask(vcpu, true);
 			break;
 		case INTR_TYPE_EXT_INTR:
 		case INTR_TYPE_SOFT_INTR:
@@ -3867,12 +3995,17 @@
 
 static void vmx_complete_atomic_exit(struct vcpu_vmx *vmx)
 {
-	u32 exit_intr_info = vmx->exit_intr_info;
+	u32 exit_intr_info;
+
+	if (!(vmx->exit_reason == EXIT_REASON_MCE_DURING_VMENTRY
+	      || vmx->exit_reason == EXIT_REASON_EXCEPTION_NMI))
+		return;
+
+	vmx->exit_intr_info = vmcs_read32(VM_EXIT_INTR_INFO);
+	exit_intr_info = vmx->exit_intr_info;
 
 	/* Handle machine checks before interrupts are enabled */
-	if ((vmx->exit_reason == EXIT_REASON_MCE_DURING_VMENTRY)
-	    || (vmx->exit_reason == EXIT_REASON_EXCEPTION_NMI
-		&& is_machine_check(exit_intr_info)))
+	if (is_machine_check(exit_intr_info))
 		kvm_machine_check();
 
 	/* We need to handle NMIs before interrupts are enabled */
@@ -3886,7 +4019,7 @@
 
 static void vmx_recover_nmi_blocking(struct vcpu_vmx *vmx)
 {
-	u32 exit_intr_info = vmx->exit_intr_info;
+	u32 exit_intr_info;
 	bool unblock_nmi;
 	u8 vector;
 	bool idtv_info_valid;
@@ -3894,6 +4027,13 @@
 	idtv_info_valid = vmx->idt_vectoring_info & VECTORING_INFO_VALID_MASK;
 
 	if (cpu_has_virtual_nmis()) {
+		if (vmx->nmi_known_unmasked)
+			return;
+		/*
+		 * Can't use vmx->exit_intr_info since we're not sure what
+		 * the exit reason is.
+		 */
+		exit_intr_info = vmcs_read32(VM_EXIT_INTR_INFO);
 		unblock_nmi = (exit_intr_info & INTR_INFO_UNBLOCK_NMI) != 0;
 		vector = exit_intr_info & INTR_INFO_VECTOR_MASK;
 		/*
@@ -3910,6 +4050,10 @@
 		    vector != DF_VECTOR && !idtv_info_valid)
 			vmcs_set_bits(GUEST_INTERRUPTIBILITY_INFO,
 				      GUEST_INTR_STATE_NMI);
+		else
+			vmx->nmi_known_unmasked =
+				!(vmcs_read32(GUEST_INTERRUPTIBILITY_INFO)
+				  & GUEST_INTR_STATE_NMI);
 	} else if (unlikely(vmx->soft_vnmi_blocked))
 		vmx->vnmi_blocked_time +=
 			ktime_to_ns(ktime_sub(ktime_get(), vmx->entry_time));
@@ -3946,8 +4090,7 @@
 		 * Clear bit "block by NMI" before VM entry if a NMI
 		 * delivery faulted.
 		 */
-		vmcs_clear_bits(GUEST_INTERRUPTIBILITY_INFO,
-				GUEST_INTR_STATE_NMI);
+		vmx_set_nmi_mask(&vmx->vcpu, false);
 		break;
 	case INTR_TYPE_SOFT_EXCEPTION:
 		vmx->vcpu.arch.event_exit_inst_len =
@@ -4124,7 +4267,10 @@
 	      );
 
 	vcpu->arch.regs_avail = ~((1 << VCPU_REGS_RIP) | (1 << VCPU_REGS_RSP)
+				  | (1 << VCPU_EXREG_RFLAGS)
+				  | (1 << VCPU_EXREG_CPL)
 				  | (1 << VCPU_EXREG_PDPTR)
+				  | (1 << VCPU_EXREG_SEGMENTS)
 				  | (1 << VCPU_EXREG_CR3));
 	vcpu->arch.regs_dirty = 0;
 
@@ -4134,7 +4280,6 @@
 	vmx->launched = 1;
 
 	vmx->exit_reason = vmcs_read32(VM_EXIT_REASON);
-	vmx->exit_intr_info = vmcs_read32(VM_EXIT_INTR_INFO);
 
 	vmx_complete_atomic_exit(vmx);
 	vmx_recover_nmi_blocking(vmx);
@@ -4195,8 +4340,8 @@
 		goto free_vcpu;
 
 	vmx->guest_msrs = kmalloc(PAGE_SIZE, GFP_KERNEL);
+	err = -ENOMEM;
 	if (!vmx->guest_msrs) {
-		err = -ENOMEM;
 		goto uninit_vcpu;
 	}
 
@@ -4215,7 +4360,8 @@
 	if (err)
 		goto free_vmcs;
 	if (vm_need_virtualize_apic_accesses(kvm))
-		if (alloc_apic_access_page(kvm) != 0)
+		err = alloc_apic_access_page(kvm);
+		if (err)
 			goto free_vmcs;
 
 	if (enable_ept) {
@@ -4368,6 +4514,13 @@
 {
 }
 
+static int vmx_check_intercept(struct kvm_vcpu *vcpu,
+			       struct x86_instruction_info *info,
+			       enum x86_intercept_stage stage)
+{
+	return X86EMUL_CONTINUE;
+}
+
 static struct kvm_x86_ops vmx_x86_ops = {
 	.cpu_has_kvm_support = cpu_has_kvm_support,
 	.disabled_by_bios = vmx_disabled_by_bios,
@@ -4449,10 +4602,14 @@
 
 	.has_wbinvd_exit = cpu_has_vmx_wbinvd_exit,
 
+	.set_tsc_khz = vmx_set_tsc_khz,
 	.write_tsc_offset = vmx_write_tsc_offset,
 	.adjust_tsc_offset = vmx_adjust_tsc_offset,
+	.compute_tsc_offset = vmx_compute_tsc_offset,
 
 	.set_tdp_cr3 = vmx_set_cr3,
+
+	.check_intercept = vmx_check_intercept,
 };
 
 static int __init vmx_init(void)
diff -druN linux-2.6.39-libre/arch/x86/kvm/x86.c linux-3.0-rc7-libre/arch/x86/kvm/x86.c
--- linux-2.6.39-libre/arch/x86/kvm/x86.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/kvm/x86.c	2011-07-11 19:51:52.000000000 -0400
@@ -60,22 +60,12 @@
 #include <asm/div64.h>
 
 #define MAX_IO_MSRS 256
-#define CR0_RESERVED_BITS						\
-	(~(unsigned long)(X86_CR0_PE | X86_CR0_MP | X86_CR0_EM | X86_CR0_TS \
-			  | X86_CR0_ET | X86_CR0_NE | X86_CR0_WP | X86_CR0_AM \
-			  | X86_CR0_NW | X86_CR0_CD | X86_CR0_PG))
-#define CR4_RESERVED_BITS						\
-	(~(unsigned long)(X86_CR4_VME | X86_CR4_PVI | X86_CR4_TSD | X86_CR4_DE\
-			  | X86_CR4_PSE | X86_CR4_PAE | X86_CR4_MCE	\
-			  | X86_CR4_PGE | X86_CR4_PCE | X86_CR4_OSFXSR	\
-			  | X86_CR4_OSXSAVE \
-			  | X86_CR4_OSXMMEXCPT | X86_CR4_VMXE))
-
-#define CR8_RESERVED_BITS (~(unsigned long)X86_CR8_TPR)
-
 #define KVM_MAX_MCE_BANKS 32
 #define KVM_MCE_CAP_SUPPORTED (MCG_CTL_P | MCG_SER_P)
 
+#define emul_to_vcpu(ctxt) \
+	container_of(ctxt, struct kvm_vcpu, arch.emulate_ctxt)
+
 /* EFER defaults:
  * - enable syscall per default because its emulated by KVM
  * - enable LME and LMA per default on 64 bit KVM
@@ -100,6 +90,11 @@
 int ignore_msrs = 0;
 module_param_named(ignore_msrs, ignore_msrs, bool, S_IRUGO | S_IWUSR);
 
+bool kvm_has_tsc_control;
+EXPORT_SYMBOL_GPL(kvm_has_tsc_control);
+u32  kvm_max_guest_tsc_khz;
+EXPORT_SYMBOL_GPL(kvm_max_guest_tsc_khz);
+
 #define KVM_NR_SHARED_MSRS 16
 
 struct kvm_shared_msrs_global {
@@ -157,6 +152,8 @@
 
 u64 __read_mostly host_xcr0;
 
+int emulator_fix_hypercall(struct x86_emulate_ctxt *ctxt);
+
 static inline void kvm_async_pf_hash_reset(struct kvm_vcpu *vcpu)
 {
 	int i;
@@ -361,8 +358,8 @@
 
 void kvm_inject_nmi(struct kvm_vcpu *vcpu)
 {
-	kvm_make_request(KVM_REQ_NMI, vcpu);
 	kvm_make_request(KVM_REQ_EVENT, vcpu);
+	vcpu->arch.nmi_pending = 1;
 }
 EXPORT_SYMBOL_GPL(kvm_inject_nmi);
 
@@ -982,7 +979,15 @@
 	return ret;
 }
 
-static inline u64 nsec_to_cycles(u64 nsec)
+static u64 vcpu_tsc_khz(struct kvm_vcpu *vcpu)
+{
+	if (vcpu->arch.virtual_tsc_khz)
+		return vcpu->arch.virtual_tsc_khz;
+	else
+		return __this_cpu_read(cpu_tsc_khz);
+}
+
+static inline u64 nsec_to_cycles(struct kvm_vcpu *vcpu, u64 nsec)
 {
 	u64 ret;
 
@@ -990,25 +995,24 @@
 	if (kvm_tsc_changes_freq())
 		printk_once(KERN_WARNING
 		 "kvm: unreliable cycle conversion on adjustable rate TSC\n");
-	ret = nsec * __this_cpu_read(cpu_tsc_khz);
+	ret = nsec * vcpu_tsc_khz(vcpu);
 	do_div(ret, USEC_PER_SEC);
 	return ret;
 }
 
-static void kvm_arch_set_tsc_khz(struct kvm *kvm, u32 this_tsc_khz)
+static void kvm_init_tsc_catchup(struct kvm_vcpu *vcpu, u32 this_tsc_khz)
 {
 	/* Compute a scale to convert nanoseconds in TSC cycles */
 	kvm_get_time_scale(this_tsc_khz, NSEC_PER_SEC / 1000,
-			   &kvm->arch.virtual_tsc_shift,
-			   &kvm->arch.virtual_tsc_mult);
-	kvm->arch.virtual_tsc_khz = this_tsc_khz;
+			   &vcpu->arch.tsc_catchup_shift,
+			   &vcpu->arch.tsc_catchup_mult);
 }
 
 static u64 compute_guest_tsc(struct kvm_vcpu *vcpu, s64 kernel_ns)
 {
 	u64 tsc = pvclock_scale_delta(kernel_ns-vcpu->arch.last_tsc_nsec,
-				      vcpu->kvm->arch.virtual_tsc_mult,
-				      vcpu->kvm->arch.virtual_tsc_shift);
+				      vcpu->arch.tsc_catchup_mult,
+				      vcpu->arch.tsc_catchup_shift);
 	tsc += vcpu->arch.last_tsc_write;
 	return tsc;
 }
@@ -1021,7 +1025,7 @@
 	s64 sdiff;
 
 	raw_spin_lock_irqsave(&kvm->arch.tsc_write_lock, flags);
-	offset = data - native_read_tsc();
+	offset = kvm_x86_ops->compute_tsc_offset(vcpu, data);
 	ns = get_kernel_ns();
 	elapsed = ns - kvm->arch.last_tsc_nsec;
 	sdiff = data - kvm->arch.last_tsc_write;
@@ -1037,13 +1041,13 @@
 	 * In that case, for a reliable TSC, we can match TSC offsets,
 	 * or make a best guest using elapsed value.
 	 */
-	if (sdiff < nsec_to_cycles(5ULL * NSEC_PER_SEC) &&
+	if (sdiff < nsec_to_cycles(vcpu, 5ULL * NSEC_PER_SEC) &&
 	    elapsed < 5ULL * NSEC_PER_SEC) {
 		if (!check_tsc_unstable()) {
 			offset = kvm->arch.last_tsc_offset;
 			pr_debug("kvm: matched tsc offset for %llu\n", data);
 		} else {
-			u64 delta = nsec_to_cycles(elapsed);
+			u64 delta = nsec_to_cycles(vcpu, elapsed);
 			offset += delta;
 			pr_debug("kvm: adjusted tsc offset by %llu\n", delta);
 		}
@@ -1075,8 +1079,7 @@
 	local_irq_save(flags);
 	kvm_get_msr(v, MSR_IA32_TSC, &tsc_timestamp);
 	kernel_ns = get_kernel_ns();
-	this_tsc_khz = __this_cpu_read(cpu_tsc_khz);
-
+	this_tsc_khz = vcpu_tsc_khz(v);
 	if (unlikely(this_tsc_khz == 0)) {
 		local_irq_restore(flags);
 		kvm_make_request(KVM_REQ_CLOCK_UPDATE, v);
@@ -1993,6 +1996,7 @@
 	case KVM_CAP_X86_ROBUST_SINGLESTEP:
 	case KVM_CAP_XSAVE:
 	case KVM_CAP_ASYNC_PF:
+	case KVM_CAP_GET_TSC_KHZ:
 		r = 1;
 		break;
 	case KVM_CAP_COALESCED_MMIO:
@@ -2019,6 +2023,9 @@
 	case KVM_CAP_XCRS:
 		r = cpu_has_xsave;
 		break;
+	case KVM_CAP_TSC_CONTROL:
+		r = kvm_has_tsc_control;
+		break;
 	default:
 		r = 0;
 		break;
@@ -2120,8 +2127,13 @@
 	kvm_x86_ops->vcpu_load(vcpu, cpu);
 	if (unlikely(vcpu->cpu != cpu) || check_tsc_unstable()) {
 		/* Make sure TSC doesn't go backwards */
-		s64 tsc_delta = !vcpu->arch.last_host_tsc ? 0 :
-				native_read_tsc() - vcpu->arch.last_host_tsc;
+		s64 tsc_delta;
+		u64 tsc;
+
+		kvm_get_msr(vcpu, MSR_IA32_TSC, &tsc);
+		tsc_delta = !vcpu->arch.last_guest_tsc ? 0 :
+			     tsc - vcpu->arch.last_guest_tsc;
+
 		if (tsc_delta < 0)
 			mark_tsc_unstable("KVM discovered backwards TSC");
 		if (check_tsc_unstable()) {
@@ -2139,7 +2151,7 @@
 {
 	kvm_x86_ops->vcpu_put(vcpu);
 	kvm_put_guest_fpu(vcpu);
-	vcpu->arch.last_host_tsc = native_read_tsc();
+	kvm_get_msr(vcpu, MSR_IA32_TSC, &vcpu->arch.last_guest_tsc);
 }
 
 static int is_efer_nx(void)
@@ -2324,6 +2336,12 @@
 		F(3DNOWPREFETCH) | 0 /* OSVW */ | 0 /* IBS */ | F(XOP) |
 		0 /* SKINIT, WDT, LWP */ | F(FMA4) | F(TBM);
 
+	/* cpuid 0xC0000001.edx */
+	const u32 kvm_supported_word5_x86_features =
+		F(XSTORE) | F(XSTORE_EN) | F(XCRYPT) | F(XCRYPT_EN) |
+		F(ACE2) | F(ACE2_EN) | F(PHE) | F(PHE_EN) |
+		F(PMM) | F(PMM_EN);
+
 	/* all calls to cpuid_count() should be made on the same cpu */
 	get_cpu();
 	do_cpuid_1_ent(entry, function, index);
@@ -2418,6 +2436,7 @@
 		entry->eax = (1 << KVM_FEATURE_CLOCKSOURCE) |
 			     (1 << KVM_FEATURE_NOP_IO_DELAY) |
 			     (1 << KVM_FEATURE_CLOCKSOURCE2) |
+			     (1 << KVM_FEATURE_ASYNC_PF) |
 			     (1 << KVM_FEATURE_CLOCKSOURCE_STABLE_BIT);
 		entry->ebx = 0;
 		entry->ecx = 0;
@@ -2432,6 +2451,20 @@
 		entry->ecx &= kvm_supported_word6_x86_features;
 		cpuid_mask(&entry->ecx, 6);
 		break;
+	/*Add support for Centaur's CPUID instruction*/
+	case 0xC0000000:
+		/*Just support up to 0xC0000004 now*/
+		entry->eax = min(entry->eax, 0xC0000004);
+		break;
+	case 0xC0000001:
+		entry->edx &= kvm_supported_word5_x86_features;
+		cpuid_mask(&entry->edx, 5);
+		break;
+	case 0xC0000002:
+	case 0xC0000003:
+	case 0xC0000004:
+		/*Now nothing to do, reserved for the future*/
+		break;
 	}
 
 	kvm_x86_ops->set_supported_cpuid(function, entry);
@@ -2478,6 +2511,26 @@
 	if (nent >= cpuid->nent)
 		goto out_free;
 
+	/* Add support for Centaur's CPUID instruction. */
+	if (boot_cpu_data.x86_vendor == X86_VENDOR_CENTAUR) {
+		do_cpuid_ent(&cpuid_entries[nent], 0xC0000000, 0,
+				&nent, cpuid->nent);
+
+		r = -E2BIG;
+		if (nent >= cpuid->nent)
+			goto out_free;
+
+		limit = cpuid_entries[nent - 1].eax;
+		for (func = 0xC0000001;
+			func <= limit && nent < cpuid->nent; ++func)
+			do_cpuid_ent(&cpuid_entries[nent], func, 0,
+					&nent, cpuid->nent);
+
+		r = -E2BIG;
+		if (nent >= cpuid->nent)
+			goto out_free;
+	}
+
 	do_cpuid_ent(&cpuid_entries[nent], KVM_CPUID_SIGNATURE, 0, &nent,
 		     cpuid->nent);
 
@@ -3046,6 +3099,32 @@
 		r = kvm_vcpu_ioctl_x86_set_xcrs(vcpu, u.xcrs);
 		break;
 	}
+	case KVM_SET_TSC_KHZ: {
+		u32 user_tsc_khz;
+
+		r = -EINVAL;
+		if (!kvm_has_tsc_control)
+			break;
+
+		user_tsc_khz = (u32)arg;
+
+		if (user_tsc_khz >= kvm_max_guest_tsc_khz)
+			goto out;
+
+		kvm_x86_ops->set_tsc_khz(vcpu, user_tsc_khz);
+
+		r = 0;
+		goto out;
+	}
+	case KVM_GET_TSC_KHZ: {
+		r = -EIO;
+		if (check_tsc_unstable())
+			goto out;
+
+		r = vcpu_tsc_khz(vcpu);
+
+		goto out;
+	}
 	default:
 		r = -EINVAL;
 	}
@@ -3595,20 +3674,43 @@
 static int vcpu_mmio_write(struct kvm_vcpu *vcpu, gpa_t addr, int len,
 			   const void *v)
 {
-	if (vcpu->arch.apic &&
-	    !kvm_iodevice_write(&vcpu->arch.apic->dev, addr, len, v))
-		return 0;
+	int handled = 0;
+	int n;
 
-	return kvm_io_bus_write(vcpu->kvm, KVM_MMIO_BUS, addr, len, v);
+	do {
+		n = min(len, 8);
+		if (!(vcpu->arch.apic &&
+		      !kvm_iodevice_write(&vcpu->arch.apic->dev, addr, n, v))
+		    && kvm_io_bus_write(vcpu->kvm, KVM_MMIO_BUS, addr, n, v))
+			break;
+		handled += n;
+		addr += n;
+		len -= n;
+		v += n;
+	} while (len);
+
+	return handled;
 }
 
 static int vcpu_mmio_read(struct kvm_vcpu *vcpu, gpa_t addr, int len, void *v)
 {
-	if (vcpu->arch.apic &&
-	    !kvm_iodevice_read(&vcpu->arch.apic->dev, addr, len, v))
-		return 0;
+	int handled = 0;
+	int n;
 
-	return kvm_io_bus_read(vcpu->kvm, KVM_MMIO_BUS, addr, len, v);
+	do {
+		n = min(len, 8);
+		if (!(vcpu->arch.apic &&
+		      !kvm_iodevice_read(&vcpu->arch.apic->dev, addr, n, v))
+		    && kvm_io_bus_read(vcpu->kvm, KVM_MMIO_BUS, addr, n, v))
+			break;
+		trace_kvm_mmio(KVM_TRACE_MMIO_READ, n, addr, *(u64 *)v);
+		handled += n;
+		addr += n;
+		len -= n;
+		v += n;
+	} while (len);
+
+	return handled;
 }
 
 static void kvm_set_segment(struct kvm_vcpu *vcpu,
@@ -3703,37 +3805,43 @@
 }
 
 /* used for instruction fetching */
-static int kvm_fetch_guest_virt(gva_t addr, void *val, unsigned int bytes,
-				struct kvm_vcpu *vcpu,
+static int kvm_fetch_guest_virt(struct x86_emulate_ctxt *ctxt,
+				gva_t addr, void *val, unsigned int bytes,
 				struct x86_exception *exception)
 {
+	struct kvm_vcpu *vcpu = emul_to_vcpu(ctxt);
 	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,
 					  exception);
 }
 
-static int kvm_read_guest_virt(gva_t addr, void *val, unsigned int bytes,
-			       struct kvm_vcpu *vcpu,
+static int kvm_read_guest_virt(struct x86_emulate_ctxt *ctxt,
+			       gva_t addr, void *val, unsigned int bytes,
 			       struct x86_exception *exception)
 {
+	struct kvm_vcpu *vcpu = emul_to_vcpu(ctxt);
 	u32 access = (kvm_x86_ops->get_cpl(vcpu) == 3) ? PFERR_USER_MASK : 0;
+
 	return kvm_read_guest_virt_helper(addr, val, bytes, vcpu, access,
 					  exception);
 }
 
-static int kvm_read_guest_virt_system(gva_t addr, void *val, unsigned int bytes,
-				      struct kvm_vcpu *vcpu,
+static int kvm_read_guest_virt_system(struct x86_emulate_ctxt *ctxt,
+				      gva_t addr, void *val, unsigned int bytes,
 				      struct x86_exception *exception)
 {
+	struct kvm_vcpu *vcpu = emul_to_vcpu(ctxt);
 	return kvm_read_guest_virt_helper(addr, val, bytes, vcpu, 0, exception);
 }
 
-static int kvm_write_guest_virt_system(gva_t addr, void *val,
+static int kvm_write_guest_virt_system(struct x86_emulate_ctxt *ctxt,
+				       gva_t addr, void *val,
 				       unsigned int bytes,
-				       struct kvm_vcpu *vcpu,
 				       struct x86_exception *exception)
 {
+	struct kvm_vcpu *vcpu = emul_to_vcpu(ctxt);
 	void *data = val;
 	int r = X86EMUL_CONTINUE;
 
@@ -3761,13 +3869,15 @@
 	return r;
 }
 
-static int emulator_read_emulated(unsigned long addr,
+static int emulator_read_emulated(struct x86_emulate_ctxt *ctxt,
+				  unsigned long addr,
 				  void *val,
 				  unsigned int bytes,
-				  struct x86_exception *exception,
-				  struct kvm_vcpu *vcpu)
+				  struct x86_exception *exception)
 {
+	struct kvm_vcpu *vcpu = emul_to_vcpu(ctxt);
 	gpa_t                 gpa;
+	int handled;
 
 	if (vcpu->mmio_read_completed) {
 		memcpy(val, vcpu->mmio_data, bytes);
@@ -3786,7 +3896,7 @@
 	if ((gpa & PAGE_MASK) == APIC_DEFAULT_PHYS_BASE)
 		goto mmio;
 
-	if (kvm_read_guest_virt(addr, val, bytes, vcpu, exception)
+	if (kvm_read_guest_virt(ctxt, addr, val, bytes, exception)
 	    == X86EMUL_CONTINUE)
 		return X86EMUL_CONTINUE;
 
@@ -3794,18 +3904,24 @@
 	/*
 	 * Is this MMIO handled locally?
 	 */
-	if (!vcpu_mmio_read(vcpu, gpa, bytes, val)) {
-		trace_kvm_mmio(KVM_TRACE_MMIO_READ, bytes, gpa, *(u64 *)val);
+	handled = vcpu_mmio_read(vcpu, gpa, bytes, val);
+
+	if (handled == bytes)
 		return X86EMUL_CONTINUE;
-	}
+
+	gpa += handled;
+	bytes -= handled;
+	val += handled;
 
 	trace_kvm_mmio(KVM_TRACE_MMIO_READ_UNSATISFIED, bytes, gpa, 0);
 
 	vcpu->mmio_needed = 1;
 	vcpu->run->exit_reason = KVM_EXIT_MMIO;
 	vcpu->run->mmio.phys_addr = vcpu->mmio_phys_addr = gpa;
-	vcpu->run->mmio.len = vcpu->mmio_size = bytes;
+	vcpu->mmio_size = bytes;
+	vcpu->run->mmio.len = min(vcpu->mmio_size, 8);
 	vcpu->run->mmio.is_write = vcpu->mmio_is_write = 0;
+	vcpu->mmio_index = 0;
 
 	return X86EMUL_IO_NEEDED;
 }
@@ -3829,6 +3945,7 @@
 					   struct kvm_vcpu *vcpu)
 {
 	gpa_t                 gpa;
+	int handled;
 
 	gpa = kvm_mmu_gva_to_gpa_write(vcpu, addr, exception);
 
@@ -3847,25 +3964,35 @@
 	/*
 	 * Is this MMIO handled locally?
 	 */
-	if (!vcpu_mmio_write(vcpu, gpa, bytes, val))
+	handled = vcpu_mmio_write(vcpu, gpa, bytes, val);
+	if (handled == bytes)
 		return X86EMUL_CONTINUE;
 
+	gpa += handled;
+	bytes -= handled;
+	val += handled;
+
 	vcpu->mmio_needed = 1;
+	memcpy(vcpu->mmio_data, val, bytes);
 	vcpu->run->exit_reason = KVM_EXIT_MMIO;
 	vcpu->run->mmio.phys_addr = vcpu->mmio_phys_addr = gpa;
-	vcpu->run->mmio.len = vcpu->mmio_size = bytes;
+	vcpu->mmio_size = bytes;
+	vcpu->run->mmio.len = min(vcpu->mmio_size, 8);
 	vcpu->run->mmio.is_write = vcpu->mmio_is_write = 1;
-	memcpy(vcpu->run->mmio.data, val, bytes);
+	memcpy(vcpu->run->mmio.data, vcpu->mmio_data, 8);
+	vcpu->mmio_index = 0;
 
 	return X86EMUL_CONTINUE;
 }
 
-int emulator_write_emulated(unsigned long addr,
+int emulator_write_emulated(struct x86_emulate_ctxt *ctxt,
+			    unsigned long addr,
 			    const void *val,
 			    unsigned int bytes,
-			    struct x86_exception *exception,
-			    struct kvm_vcpu *vcpu)
+			    struct x86_exception *exception)
 {
+	struct kvm_vcpu *vcpu = emul_to_vcpu(ctxt);
+
 	/* Crossing a page boundary? */
 	if (((addr + bytes - 1) ^ addr) & PAGE_MASK) {
 		int rc, now;
@@ -3893,13 +4020,14 @@
 	(cmpxchg64((u64 *)(ptr), *(u64 *)(old), *(u64 *)(new)) == *(u64 *)(old))
 #endif
 
-static int emulator_cmpxchg_emulated(unsigned long addr,
+static int emulator_cmpxchg_emulated(struct x86_emulate_ctxt *ctxt,
+				     unsigned long addr,
 				     const void *old,
 				     const void *new,
 				     unsigned int bytes,
-				     struct x86_exception *exception,
-				     struct kvm_vcpu *vcpu)
+				     struct x86_exception *exception)
 {
+	struct kvm_vcpu *vcpu = emul_to_vcpu(ctxt);
 	gpa_t gpa;
 	struct page *page;
 	char *kaddr;
@@ -3955,7 +4083,7 @@
 emul_write:
 	printk_once(KERN_WARNING "kvm: emulating exchange as write\n");
 
-	return emulator_write_emulated(addr, new, bytes, exception, vcpu);
+	return emulator_write_emulated(ctxt, addr, new, bytes, exception);
 }
 
 static int kernel_pio(struct kvm_vcpu *vcpu, void *pd)
@@ -3974,9 +4102,12 @@
 }
 
 
-static int emulator_pio_in_emulated(int size, unsigned short port, void *val,
-			     unsigned int count, struct kvm_vcpu *vcpu)
+static int emulator_pio_in_emulated(struct x86_emulate_ctxt *ctxt,
+				    int size, unsigned short port, void *val,
+				    unsigned int count)
 {
+	struct kvm_vcpu *vcpu = emul_to_vcpu(ctxt);
+
 	if (vcpu->arch.pio.count)
 		goto data_avail;
 
@@ -4004,10 +4135,12 @@
 	return 0;
 }
 
-static int emulator_pio_out_emulated(int size, unsigned short port,
-			      const void *val, unsigned int count,
-			      struct kvm_vcpu *vcpu)
+static int emulator_pio_out_emulated(struct x86_emulate_ctxt *ctxt,
+				     int size, unsigned short port,
+				     const void *val, unsigned int count)
 {
+	struct kvm_vcpu *vcpu = emul_to_vcpu(ctxt);
+
 	trace_kvm_pio(1, port, size, count);
 
 	vcpu->arch.pio.port = port;
@@ -4037,10 +4170,9 @@
 	return kvm_x86_ops->get_segment_base(vcpu, seg);
 }
 
-int emulate_invlpg(struct kvm_vcpu *vcpu, gva_t address)
+static void emulator_invlpg(struct x86_emulate_ctxt *ctxt, ulong address)
 {
-	kvm_mmu_invlpg(vcpu, address);
-	return X86EMUL_CONTINUE;
+	kvm_mmu_invlpg(emul_to_vcpu(ctxt), address);
 }
 
 int kvm_emulate_wbinvd(struct kvm_vcpu *vcpu)
@@ -4062,22 +4194,20 @@
 }
 EXPORT_SYMBOL_GPL(kvm_emulate_wbinvd);
 
-int emulate_clts(struct kvm_vcpu *vcpu)
+static void emulator_wbinvd(struct x86_emulate_ctxt *ctxt)
 {
-	kvm_x86_ops->set_cr0(vcpu, kvm_read_cr0_bits(vcpu, ~X86_CR0_TS));
-	kvm_x86_ops->fpu_activate(vcpu);
-	return X86EMUL_CONTINUE;
+	kvm_emulate_wbinvd(emul_to_vcpu(ctxt));
 }
 
-int emulator_get_dr(int dr, unsigned long *dest, struct kvm_vcpu *vcpu)
+int emulator_get_dr(struct x86_emulate_ctxt *ctxt, int dr, unsigned long *dest)
 {
-	return _kvm_get_dr(vcpu, dr, dest);
+	return _kvm_get_dr(emul_to_vcpu(ctxt), dr, dest);
 }
 
-int emulator_set_dr(int dr, unsigned long value, struct kvm_vcpu *vcpu)
+int emulator_set_dr(struct x86_emulate_ctxt *ctxt, int dr, unsigned long value)
 {
 
-	return __kvm_set_dr(vcpu, dr, value);
+	return __kvm_set_dr(emul_to_vcpu(ctxt), dr, value);
 }
 
 static u64 mk_cr_64(u64 curr_cr, u32 new_val)
@@ -4085,8 +4215,9 @@
 	return (curr_cr & ~((1ULL << 32) - 1)) | new_val;
 }
 
-static unsigned long emulator_get_cr(int cr, struct kvm_vcpu *vcpu)
+static unsigned long emulator_get_cr(struct x86_emulate_ctxt *ctxt, int cr)
 {
+	struct kvm_vcpu *vcpu = emul_to_vcpu(ctxt);
 	unsigned long value;
 
 	switch (cr) {
@@ -4113,8 +4244,9 @@
 	return value;
 }
 
-static int emulator_set_cr(int cr, unsigned long val, struct kvm_vcpu *vcpu)
+static int emulator_set_cr(struct x86_emulate_ctxt *ctxt, int cr, ulong val)
 {
+	struct kvm_vcpu *vcpu = emul_to_vcpu(ctxt);
 	int res = 0;
 
 	switch (cr) {
@@ -4141,33 +4273,45 @@
 	return res;
 }
 
-static int emulator_get_cpl(struct kvm_vcpu *vcpu)
+static int emulator_get_cpl(struct x86_emulate_ctxt *ctxt)
 {
-	return kvm_x86_ops->get_cpl(vcpu);
+	return kvm_x86_ops->get_cpl(emul_to_vcpu(ctxt));
 }
 
-static void emulator_get_gdt(struct desc_ptr *dt, struct kvm_vcpu *vcpu)
+static void emulator_get_gdt(struct x86_emulate_ctxt *ctxt, struct desc_ptr *dt)
 {
-	kvm_x86_ops->get_gdt(vcpu, dt);
+	kvm_x86_ops->get_gdt(emul_to_vcpu(ctxt), dt);
 }
 
-static void emulator_get_idt(struct desc_ptr *dt, struct kvm_vcpu *vcpu)
+static void emulator_get_idt(struct x86_emulate_ctxt *ctxt, struct desc_ptr *dt)
 {
-	kvm_x86_ops->get_idt(vcpu, dt);
+	kvm_x86_ops->get_idt(emul_to_vcpu(ctxt), dt);
 }
 
-static unsigned long emulator_get_cached_segment_base(int seg,
-						      struct kvm_vcpu *vcpu)
+static void emulator_set_gdt(struct x86_emulate_ctxt *ctxt, struct desc_ptr *dt)
 {
-	return get_segment_base(vcpu, seg);
+	kvm_x86_ops->set_gdt(emul_to_vcpu(ctxt), dt);
 }
 
-static bool emulator_get_cached_descriptor(struct desc_struct *desc, u32 *base3,
-					   int seg, struct kvm_vcpu *vcpu)
+static void emulator_set_idt(struct x86_emulate_ctxt *ctxt, struct desc_ptr *dt)
+{
+	kvm_x86_ops->set_idt(emul_to_vcpu(ctxt), dt);
+}
+
+static unsigned long emulator_get_cached_segment_base(
+	struct x86_emulate_ctxt *ctxt, int seg)
+{
+	return get_segment_base(emul_to_vcpu(ctxt), seg);
+}
+
+static bool emulator_get_segment(struct x86_emulate_ctxt *ctxt, u16 *selector,
+				 struct desc_struct *desc, u32 *base3,
+				 int seg)
 {
 	struct kvm_segment var;
 
-	kvm_get_segment(vcpu, &var, seg);
+	kvm_get_segment(emul_to_vcpu(ctxt), &var, seg);
+	*selector = var.selector;
 
 	if (var.unusable)
 		return false;
@@ -4192,14 +4336,14 @@
 	return true;
 }
 
-static void emulator_set_cached_descriptor(struct desc_struct *desc, u32 base3,
-					   int seg, struct kvm_vcpu *vcpu)
+static void emulator_set_segment(struct x86_emulate_ctxt *ctxt, u16 selector,
+				 struct desc_struct *desc, u32 base3,
+				 int seg)
 {
+	struct kvm_vcpu *vcpu = emul_to_vcpu(ctxt);
 	struct kvm_segment var;
 
-	/* needed to preserve selector */
-	kvm_get_segment(vcpu, &var, seg);
-
+	var.selector = selector;
 	var.base = get_desc_base(desc);
 #ifdef CONFIG_X86_64
 	var.base |= ((u64)base3) << 32;
@@ -4223,22 +4367,44 @@
 	return;
 }
 
-static u16 emulator_get_segment_selector(int seg, struct kvm_vcpu *vcpu)
+static int emulator_get_msr(struct x86_emulate_ctxt *ctxt,
+			    u32 msr_index, u64 *pdata)
 {
-	struct kvm_segment kvm_seg;
+	return kvm_get_msr(emul_to_vcpu(ctxt), msr_index, pdata);
+}
 
-	kvm_get_segment(vcpu, &kvm_seg, seg);
-	return kvm_seg.selector;
+static int emulator_set_msr(struct x86_emulate_ctxt *ctxt,
+			    u32 msr_index, u64 data)
+{
+	return kvm_set_msr(emul_to_vcpu(ctxt), msr_index, data);
 }
 
-static void emulator_set_segment_selector(u16 sel, int seg,
-					  struct kvm_vcpu *vcpu)
+static void emulator_halt(struct x86_emulate_ctxt *ctxt)
 {
-	struct kvm_segment kvm_seg;
+	emul_to_vcpu(ctxt)->arch.halt_request = 1;
+}
 
-	kvm_get_segment(vcpu, &kvm_seg, seg);
-	kvm_seg.selector = sel;
-	kvm_set_segment(vcpu, &kvm_seg, seg);
+static void emulator_get_fpu(struct x86_emulate_ctxt *ctxt)
+{
+	preempt_disable();
+	kvm_load_guest_fpu(emul_to_vcpu(ctxt));
+	/*
+	 * CR0.TS may reference the host fpu state, not the guest fpu state,
+	 * so it may be clear at this point.
+	 */
+	clts();
+}
+
+static void emulator_put_fpu(struct x86_emulate_ctxt *ctxt)
+{
+	preempt_enable();
+}
+
+static int emulator_intercept(struct x86_emulate_ctxt *ctxt,
+			      struct x86_instruction_info *info,
+			      enum x86_intercept_stage stage)
+{
+	return kvm_x86_ops->check_intercept(emul_to_vcpu(ctxt), info, stage);
 }
 
 static struct x86_emulate_ops emulate_ops = {
@@ -4248,22 +4414,29 @@
 	.read_emulated       = emulator_read_emulated,
 	.write_emulated      = emulator_write_emulated,
 	.cmpxchg_emulated    = emulator_cmpxchg_emulated,
+	.invlpg              = emulator_invlpg,
 	.pio_in_emulated     = emulator_pio_in_emulated,
 	.pio_out_emulated    = emulator_pio_out_emulated,
-	.get_cached_descriptor = emulator_get_cached_descriptor,
-	.set_cached_descriptor = emulator_set_cached_descriptor,
-	.get_segment_selector = emulator_get_segment_selector,
-	.set_segment_selector = emulator_set_segment_selector,
+	.get_segment         = emulator_get_segment,
+	.set_segment         = emulator_set_segment,
 	.get_cached_segment_base = emulator_get_cached_segment_base,
 	.get_gdt             = emulator_get_gdt,
 	.get_idt	     = emulator_get_idt,
+	.set_gdt             = emulator_set_gdt,
+	.set_idt	     = emulator_set_idt,
 	.get_cr              = emulator_get_cr,
 	.set_cr              = emulator_set_cr,
 	.cpl                 = emulator_get_cpl,
 	.get_dr              = emulator_get_dr,
 	.set_dr              = emulator_set_dr,
-	.set_msr             = kvm_set_msr,
-	.get_msr             = kvm_get_msr,
+	.set_msr             = emulator_set_msr,
+	.get_msr             = emulator_get_msr,
+	.halt                = emulator_halt,
+	.wbinvd              = emulator_wbinvd,
+	.fix_hypercall       = emulator_fix_hypercall,
+	.get_fpu             = emulator_get_fpu,
+	.put_fpu             = emulator_put_fpu,
+	.intercept           = emulator_intercept,
 };
 
 static void cache_all_regs(struct kvm_vcpu *vcpu)
@@ -4305,12 +4478,17 @@
 	struct decode_cache *c = &vcpu->arch.emulate_ctxt.decode;
 	int cs_db, cs_l;
 
+	/*
+	 * TODO: fix emulate.c to use guest_read/write_register
+	 * instead of direct ->regs accesses, can save hundred cycles
+	 * on Intel for instructions that don't read/change RSP, for
+	 * for example.
+	 */
 	cache_all_regs(vcpu);
 
 	kvm_x86_ops->get_cs_db_l_bits(vcpu, &cs_db, &cs_l);
 
-	vcpu->arch.emulate_ctxt.vcpu = vcpu;
-	vcpu->arch.emulate_ctxt.eflags = kvm_x86_ops->get_rflags(vcpu);
+	vcpu->arch.emulate_ctxt.eflags = kvm_get_rflags(vcpu);
 	vcpu->arch.emulate_ctxt.eip = kvm_rip_read(vcpu);
 	vcpu->arch.emulate_ctxt.mode =
 		(!is_protmode(vcpu)) ? X86EMUL_MODE_REAL :
@@ -4318,11 +4496,13 @@
 		? X86EMUL_MODE_VM86 : cs_l
 		? X86EMUL_MODE_PROT64 :	cs_db
 		? X86EMUL_MODE_PROT32 : X86EMUL_MODE_PROT16;
+	vcpu->arch.emulate_ctxt.guest_mode = is_guest_mode(vcpu);
 	memset(c, 0, sizeof(struct decode_cache));
 	memcpy(c->regs, vcpu->arch.regs, sizeof c->regs);
+	vcpu->arch.emulate_regs_need_sync_from_vcpu = false;
 }
 
-int kvm_inject_realmode_interrupt(struct kvm_vcpu *vcpu, int irq)
+int kvm_inject_realmode_interrupt(struct kvm_vcpu *vcpu, int irq, int inc_eip)
 {
 	struct decode_cache *c = &vcpu->arch.emulate_ctxt.decode;
 	int ret;
@@ -4331,7 +4511,8 @@
 
 	vcpu->arch.emulate_ctxt.decode.op_bytes = 2;
 	vcpu->arch.emulate_ctxt.decode.ad_bytes = 2;
-	vcpu->arch.emulate_ctxt.decode.eip = vcpu->arch.emulate_ctxt.eip;
+	vcpu->arch.emulate_ctxt.decode.eip = vcpu->arch.emulate_ctxt.eip +
+								 inc_eip;
 	ret = emulate_int_real(&vcpu->arch.emulate_ctxt, &emulate_ops, irq);
 
 	if (ret != X86EMUL_CONTINUE)
@@ -4340,7 +4521,7 @@
 	vcpu->arch.emulate_ctxt.eip = c->eip;
 	memcpy(vcpu->arch.regs, c->regs, sizeof c->regs);
 	kvm_rip_write(vcpu, vcpu->arch.emulate_ctxt.eip);
-	kvm_x86_ops->set_rflags(vcpu, vcpu->arch.emulate_ctxt.eflags);
+	kvm_set_rflags(vcpu, vcpu->arch.emulate_ctxt.eflags);
 
 	if (irq == NMI_VECTOR)
 		vcpu->arch.nmi_pending = false;
@@ -4402,16 +4583,9 @@
 {
 	int r;
 	struct decode_cache *c = &vcpu->arch.emulate_ctxt.decode;
+	bool writeback = true;
 
 	kvm_clear_exception_queue(vcpu);
-	vcpu->arch.mmio_fault_cr2 = cr2;
-	/*
-	 * TODO: fix emulate.c to use guest_read/write_register
-	 * instead of direct ->regs accesses, can save hundred cycles
-	 * on Intel for instructions that don't read/change RSP, for
-	 * for example.
-	 */
-	cache_all_regs(vcpu);
 
 	if (!(emulation_type & EMULTYPE_NO_DECODE)) {
 		init_emulate_ctxt(vcpu);
@@ -4442,13 +4616,19 @@
 		return EMULATE_DONE;
 	}
 
-	/* this is needed for vmware backdor interface to work since it
+	/* this is needed for vmware backdoor interface to work since it
 	   changes registers values  during IO operation */
-	memcpy(c->regs, vcpu->arch.regs, sizeof c->regs);
+	if (vcpu->arch.emulate_regs_need_sync_from_vcpu) {
+		vcpu->arch.emulate_regs_need_sync_from_vcpu = false;
+		memcpy(c->regs, vcpu->arch.regs, sizeof c->regs);
+	}
 
 restart:
 	r = x86_emulate_insn(&vcpu->arch.emulate_ctxt);
 
+	if (r == EMULATION_INTERCEPTED)
+		return EMULATE_DONE;
+
 	if (r == EMULATION_FAILED) {
 		if (reexecute_instruction(vcpu, cr2))
 			return EMULATE_DONE;
@@ -4462,21 +4642,28 @@
 	} else if (vcpu->arch.pio.count) {
 		if (!vcpu->arch.pio.in)
 			vcpu->arch.pio.count = 0;
+		else
+			writeback = false;
 		r = EMULATE_DO_MMIO;
 	} else if (vcpu->mmio_needed) {
-		if (vcpu->mmio_is_write)
-			vcpu->mmio_needed = 0;
+		if (!vcpu->mmio_is_write)
+			writeback = false;
 		r = EMULATE_DO_MMIO;
 	} else if (r == EMULATION_RESTART)
 		goto restart;
 	else
 		r = EMULATE_DONE;
 
-	toggle_interruptibility(vcpu, vcpu->arch.emulate_ctxt.interruptibility);
-	kvm_x86_ops->set_rflags(vcpu, vcpu->arch.emulate_ctxt.eflags);
-	kvm_make_request(KVM_REQ_EVENT, vcpu);
-	memcpy(vcpu->arch.regs, c->regs, sizeof c->regs);
-	kvm_rip_write(vcpu, vcpu->arch.emulate_ctxt.eip);
+	if (writeback) {
+		toggle_interruptibility(vcpu,
+				vcpu->arch.emulate_ctxt.interruptibility);
+		kvm_set_rflags(vcpu, vcpu->arch.emulate_ctxt.eflags);
+		kvm_make_request(KVM_REQ_EVENT, vcpu);
+		memcpy(vcpu->arch.regs, c->regs, sizeof c->regs);
+		vcpu->arch.emulate_regs_need_sync_to_vcpu = false;
+		kvm_rip_write(vcpu, vcpu->arch.emulate_ctxt.eip);
+	} else
+		vcpu->arch.emulate_regs_need_sync_to_vcpu = true;
 
 	return r;
 }
@@ -4485,7 +4672,8 @@
 int kvm_fast_pio_out(struct kvm_vcpu *vcpu, int size, unsigned short port)
 {
 	unsigned long val = kvm_register_read(vcpu, VCPU_REGS_RAX);
-	int ret = emulator_pio_out_emulated(size, port, &val, 1, vcpu);
+	int ret = emulator_pio_out_emulated(&vcpu->arch.emulate_ctxt,
+					    size, port, &val, 1);
 	/* do not return to emulator after return from userspace */
 	vcpu->arch.pio.count = 0;
 	return ret;
@@ -4879,8 +5067,9 @@
 }
 EXPORT_SYMBOL_GPL(kvm_emulate_hypercall);
 
-int kvm_fix_hypercall(struct kvm_vcpu *vcpu)
+int emulator_fix_hypercall(struct x86_emulate_ctxt *ctxt)
 {
+	struct kvm_vcpu *vcpu = emul_to_vcpu(ctxt);
 	char instruction[3];
 	unsigned long rip = kvm_rip_read(vcpu);
 
@@ -4893,21 +5082,8 @@
 
 	kvm_x86_ops->patch_hypercall(vcpu, instruction);
 
-	return emulator_write_emulated(rip, instruction, 3, NULL, vcpu);
-}
-
-void realmode_lgdt(struct kvm_vcpu *vcpu, u16 limit, unsigned long base)
-{
-	struct desc_ptr dt = { limit, base };
-
-	kvm_x86_ops->set_gdt(vcpu, &dt);
-}
-
-void realmode_lidt(struct kvm_vcpu *vcpu, u16 limit, unsigned long base)
-{
-	struct desc_ptr dt = { limit, base };
-
-	kvm_x86_ops->set_idt(vcpu, &dt);
+	return emulator_write_emulated(&vcpu->arch.emulate_ctxt,
+				       rip, instruction, 3, NULL);
 }
 
 static int move_to_next_stateful_cpuid_entry(struct kvm_vcpu *vcpu, int i)
@@ -5170,6 +5346,7 @@
 static int vcpu_enter_guest(struct kvm_vcpu *vcpu)
 {
 	int r;
+	bool nmi_pending;
 	bool req_int_win = !irqchip_in_kernel(vcpu->kvm) &&
 		vcpu->run->request_interrupt_window;
 
@@ -5207,19 +5384,25 @@
 			r = 1;
 			goto out;
 		}
-		if (kvm_check_request(KVM_REQ_NMI, vcpu))
-			vcpu->arch.nmi_pending = true;
 	}
 
 	r = kvm_mmu_reload(vcpu);
 	if (unlikely(r))
 		goto out;
 
+	/*
+	 * An NMI can be injected between local nmi_pending read and
+	 * vcpu->arch.nmi_pending read inside inject_pending_event().
+	 * But in that case, KVM_REQ_EVENT will be set, which makes
+	 * the race described above benign.
+	 */
+	nmi_pending = ACCESS_ONCE(vcpu->arch.nmi_pending);
+
 	if (kvm_check_request(KVM_REQ_EVENT, vcpu) || req_int_win) {
 		inject_pending_event(vcpu);
 
 		/* enable NMI/IRQ window open exits if needed */
-		if (vcpu->arch.nmi_pending)
+		if (nmi_pending)
 			kvm_x86_ops->enable_nmi_window(vcpu);
 		else if (kvm_cpu_has_interrupt(vcpu) || req_int_win)
 			kvm_x86_ops->enable_irq_window(vcpu);
@@ -5399,6 +5582,41 @@
 	return r;
 }
 
+static int complete_mmio(struct kvm_vcpu *vcpu)
+{
+	struct kvm_run *run = vcpu->run;
+	int r;
+
+	if (!(vcpu->arch.pio.count || vcpu->mmio_needed))
+		return 1;
+
+	if (vcpu->mmio_needed) {
+		vcpu->mmio_needed = 0;
+		if (!vcpu->mmio_is_write)
+			memcpy(vcpu->mmio_data + vcpu->mmio_index,
+			       run->mmio.data, 8);
+		vcpu->mmio_index += 8;
+		if (vcpu->mmio_index < vcpu->mmio_size) {
+			run->exit_reason = KVM_EXIT_MMIO;
+			run->mmio.phys_addr = vcpu->mmio_phys_addr + vcpu->mmio_index;
+			memcpy(run->mmio.data, vcpu->mmio_data + vcpu->mmio_index, 8);
+			run->mmio.len = min(vcpu->mmio_size - vcpu->mmio_index, 8);
+			run->mmio.is_write = vcpu->mmio_is_write;
+			vcpu->mmio_needed = 1;
+			return 0;
+		}
+		if (vcpu->mmio_is_write)
+			return 1;
+		vcpu->mmio_read_completed = 1;
+	}
+	vcpu->srcu_idx = srcu_read_lock(&vcpu->kvm->srcu);
+	r = emulate_instruction(vcpu, EMULTYPE_NO_DECODE);
+	srcu_read_unlock(&vcpu->kvm->srcu, vcpu->srcu_idx);
+	if (r != EMULATE_DONE)
+		return 0;
+	return 1;
+}
+
 int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
 {
 	int r;
@@ -5425,20 +5643,10 @@
 		}
 	}
 
-	if (vcpu->arch.pio.count || vcpu->mmio_needed) {
-		if (vcpu->mmio_needed) {
-			memcpy(vcpu->mmio_data, kvm_run->mmio.data, 8);
-			vcpu->mmio_read_completed = 1;
-			vcpu->mmio_needed = 0;
-		}
-		vcpu->srcu_idx = srcu_read_lock(&vcpu->kvm->srcu);
-		r = emulate_instruction(vcpu, EMULTYPE_NO_DECODE);
-		srcu_read_unlock(&vcpu->kvm->srcu, vcpu->srcu_idx);
-		if (r != EMULATE_DONE) {
-			r = 0;
-			goto out;
-		}
-	}
+	r = complete_mmio(vcpu);
+	if (r <= 0)
+		goto out;
+
 	if (kvm_run->exit_reason == KVM_EXIT_HYPERCALL)
 		kvm_register_write(vcpu, VCPU_REGS_RAX,
 				     kvm_run->hypercall.ret);
@@ -5455,6 +5663,18 @@
 
 int kvm_arch_vcpu_ioctl_get_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs)
 {
+	if (vcpu->arch.emulate_regs_need_sync_to_vcpu) {
+		/*
+		 * We are here if userspace calls get_regs() in the middle of
+		 * instruction emulation. Registers state needs to be copied
+		 * back from emulation context to vcpu. Usrapace shouldn't do
+		 * that usually, but some bad designed PV devices (vmware
+		 * backdoor interface) need this to work
+		 */
+		struct decode_cache *c = &vcpu->arch.emulate_ctxt.decode;
+		memcpy(vcpu->arch.regs, c->regs, sizeof c->regs);
+		vcpu->arch.emulate_regs_need_sync_to_vcpu = false;
+	}
 	regs->rax = kvm_register_read(vcpu, VCPU_REGS_RAX);
 	regs->rbx = kvm_register_read(vcpu, VCPU_REGS_RBX);
 	regs->rcx = kvm_register_read(vcpu, VCPU_REGS_RCX);
@@ -5482,6 +5702,9 @@
 
 int kvm_arch_vcpu_ioctl_set_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs)
 {
+	vcpu->arch.emulate_regs_need_sync_from_vcpu = true;
+	vcpu->arch.emulate_regs_need_sync_to_vcpu = false;
+
 	kvm_register_write(vcpu, VCPU_REGS_RAX, regs->rax);
 	kvm_register_write(vcpu, VCPU_REGS_RBX, regs->rbx);
 	kvm_register_write(vcpu, VCPU_REGS_RCX, regs->rcx);
@@ -5592,7 +5815,7 @@
 
 	memcpy(vcpu->arch.regs, c->regs, sizeof c->regs);
 	kvm_rip_write(vcpu, vcpu->arch.emulate_ctxt.eip);
-	kvm_x86_ops->set_rflags(vcpu, vcpu->arch.emulate_ctxt.eflags);
+	kvm_set_rflags(vcpu, vcpu->arch.emulate_ctxt.eflags);
 	kvm_make_request(KVM_REQ_EVENT, vcpu);
 	return EMULATE_DONE;
 }
@@ -5974,8 +6197,7 @@
 	}
 	vcpu->arch.pio_data = page_address(page);
 
-	if (!kvm->arch.virtual_tsc_khz)
-		kvm_arch_set_tsc_khz(kvm, max_tsc_khz);
+	kvm_init_tsc_catchup(vcpu, max_tsc_khz);
 
 	r = kvm_mmu_create(vcpu);
 	if (r < 0)
diff -druN linux-2.6.39-libre/arch/x86/kvm/x86.h linux-3.0-rc7-libre/arch/x86/kvm/x86.h
--- linux-2.6.39-libre/arch/x86/kvm/x86.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/kvm/x86.h	2011-07-11 19:51:52.000000000 -0400
@@ -77,7 +77,7 @@
 
 void kvm_before_handle_nmi(struct kvm_vcpu *vcpu);
 void kvm_after_handle_nmi(struct kvm_vcpu *vcpu);
-int kvm_inject_realmode_interrupt(struct kvm_vcpu *vcpu, int irq);
+int kvm_inject_realmode_interrupt(struct kvm_vcpu *vcpu, int irq, int inc_eip);
 
 void kvm_write_tsc(struct kvm_vcpu *vcpu, u64 data);
 
diff -druN linux-2.6.39-libre/arch/x86/lguest/boot.c linux-3.0-rc7-libre/arch/x86/lguest/boot.c
--- linux-2.6.39-libre/arch/x86/lguest/boot.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/lguest/boot.c	2011-07-11 19:51:52.000000000 -0400
@@ -7,7 +7,7 @@
  * kernel and insert a module (lg.ko) which allows us to run other Linux
  * kernels the same way we'd run processes.  We call the first kernel the Host,
  * and the others the Guests.  The program which sets up and configures Guests
- * (such as the example in Documentation/lguest/lguest.c) is called the
+ * (such as the example in Documentation/virtual/lguest/lguest.c) is called the
  * Launcher.
  *
  * Secondly, we only run specially modified Guests, not normal kernels: setting
@@ -913,8 +913,6 @@
 	.rating		= 200,
 	.read		= lguest_clock_read,
 	.mask		= CLOCKSOURCE_MASK(64),
-	.mult		= 1 << 22,
-	.shift		= 22,
 	.flags		= CLOCK_SOURCE_IS_CONTINUOUS,
 };
 
@@ -995,9 +993,10 @@
 static void lguest_time_init(void)
 {
 	/* Set up the timer interrupt (0) to go to our simple timer routine */
+	lguest_setup_irq(0);
 	irq_set_handler(0, lguest_time_irq);
 
-	clocksource_register(&lguest_clock);
+	clocksource_register_hz(&lguest_clock, NSEC_PER_SEC);
 
 	/* We can't set cpumask in the initializer: damn C limitations!  Set it
 	 * here and register our timer device. */
diff -druN linux-2.6.39-libre/arch/x86/lib/clear_page_64.S linux-3.0-rc7-libre/arch/x86/lib/clear_page_64.S
--- linux-2.6.39-libre/arch/x86/lib/clear_page_64.S	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/lib/clear_page_64.S	2011-07-11 19:51:52.000000000 -0400
@@ -1,5 +1,6 @@
 #include <linux/linkage.h>
 #include <asm/dwarf2.h>
+#include <asm/alternative-asm.h>
 
 /*
  * Zero a page. 	
@@ -14,6 +15,15 @@
 	CFI_ENDPROC
 ENDPROC(clear_page_c)
 
+ENTRY(clear_page_c_e)
+	CFI_STARTPROC
+	movl $4096,%ecx
+	xorl %eax,%eax
+	rep stosb
+	ret
+	CFI_ENDPROC
+ENDPROC(clear_page_c_e)
+
 ENTRY(clear_page)
 	CFI_STARTPROC
 	xorl   %eax,%eax
@@ -38,21 +48,26 @@
 .Lclear_page_end:
 ENDPROC(clear_page)
 
-	/* Some CPUs run faster using the string instructions.
-	   It is also a lot simpler. Use this when possible */
+	/*
+	 * Some CPUs support enhanced REP MOVSB/STOSB instructions.
+	 * It is recommended to use this when possible.
+	 * If enhanced REP MOVSB/STOSB is not available, try to use fast string.
+	 * Otherwise, use original function.
+	 *
+	 */
 
 #include <asm/cpufeature.h>
 
 	.section .altinstr_replacement,"ax"
 1:	.byte 0xeb					/* jmp <disp8> */
 	.byte (clear_page_c - clear_page) - (2f - 1b)	/* offset */
-2:
+2:	.byte 0xeb					/* jmp <disp8> */
+	.byte (clear_page_c_e - clear_page) - (3f - 2b)	/* offset */
+3:
 	.previous
 	.section .altinstructions,"a"
-	.align 8
-	.quad clear_page
-	.quad 1b
-	.word X86_FEATURE_REP_GOOD
-	.byte .Lclear_page_end - clear_page
-	.byte 2b - 1b
+	altinstruction_entry clear_page,1b,X86_FEATURE_REP_GOOD,\
+			     .Lclear_page_end-clear_page, 2b-1b
+	altinstruction_entry clear_page,2b,X86_FEATURE_ERMS,   \
+			     .Lclear_page_end-clear_page,3b-2b
 	.previous
diff -druN linux-2.6.39-libre/arch/x86/lib/copy_user_64.S linux-3.0-rc7-libre/arch/x86/lib/copy_user_64.S
--- linux-2.6.39-libre/arch/x86/lib/copy_user_64.S	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/lib/copy_user_64.S	2011-07-11 19:51:52.000000000 -0400
@@ -15,23 +15,30 @@
 #include <asm/asm-offsets.h>
 #include <asm/thread_info.h>
 #include <asm/cpufeature.h>
+#include <asm/alternative-asm.h>
 
-	.macro ALTERNATIVE_JUMP feature,orig,alt
+/*
+ * By placing feature2 after feature1 in altinstructions section, we logically
+ * implement:
+ * If CPU has feature2, jmp to alt2 is used
+ * else if CPU has feature1, jmp to alt1 is used
+ * else jmp to orig is used.
+ */
+	.macro ALTERNATIVE_JUMP feature1,feature2,orig,alt1,alt2
 0:
 	.byte 0xe9	/* 32bit jump */
 	.long \orig-1f	/* by default jump to orig */
 1:
 	.section .altinstr_replacement,"ax"
 2:	.byte 0xe9			/* near jump with 32bit immediate */
-	.long \alt-1b /* offset */   /* or alternatively to alt */
+	.long \alt1-1b /* offset */   /* or alternatively to alt1 */
+3:	.byte 0xe9			/* near jump with 32bit immediate */
+	.long \alt2-1b /* offset */   /* or alternatively to alt2 */
 	.previous
+
 	.section .altinstructions,"a"
-	.align 8
-	.quad  0b
-	.quad  2b
-	.word  \feature			/* when feature is set */
-	.byte  5
-	.byte  5
+	altinstruction_entry 0b,2b,\feature1,5,5
+	altinstruction_entry 0b,3b,\feature2,5,5
 	.previous
 	.endm
 
@@ -72,8 +79,10 @@
 	addq %rdx,%rcx
 	jc bad_to_user
 	cmpq TI_addr_limit(%rax),%rcx
-	jae bad_to_user
-	ALTERNATIVE_JUMP X86_FEATURE_REP_GOOD,copy_user_generic_unrolled,copy_user_generic_string
+	ja bad_to_user
+	ALTERNATIVE_JUMP X86_FEATURE_REP_GOOD,X86_FEATURE_ERMS,	\
+		copy_user_generic_unrolled,copy_user_generic_string,	\
+		copy_user_enhanced_fast_string
 	CFI_ENDPROC
 ENDPROC(_copy_to_user)
 
@@ -85,8 +94,10 @@
 	addq %rdx,%rcx
 	jc bad_from_user
 	cmpq TI_addr_limit(%rax),%rcx
-	jae bad_from_user
-	ALTERNATIVE_JUMP X86_FEATURE_REP_GOOD,copy_user_generic_unrolled,copy_user_generic_string
+	ja bad_from_user
+	ALTERNATIVE_JUMP X86_FEATURE_REP_GOOD,X86_FEATURE_ERMS,	\
+		copy_user_generic_unrolled,copy_user_generic_string,	\
+		copy_user_enhanced_fast_string
 	CFI_ENDPROC
 ENDPROC(_copy_from_user)
 
@@ -255,3 +266,37 @@
 	.previous
 	CFI_ENDPROC
 ENDPROC(copy_user_generic_string)
+
+/*
+ * Some CPUs are adding enhanced REP MOVSB/STOSB instructions.
+ * It's recommended to use enhanced REP MOVSB/STOSB if it's enabled.
+ *
+ * Input:
+ * rdi destination
+ * rsi source
+ * rdx count
+ *
+ * Output:
+ * eax uncopied bytes or 0 if successful.
+ */
+ENTRY(copy_user_enhanced_fast_string)
+	CFI_STARTPROC
+	andl %edx,%edx
+	jz 2f
+	movl %edx,%ecx
+1:	rep
+	movsb
+2:	xorl %eax,%eax
+	ret
+
+	.section .fixup,"ax"
+12:	movl %ecx,%edx		/* ecx is zerorest also */
+	jmp copy_user_handle_tail
+	.previous
+
+	.section __ex_table,"a"
+	.align 8
+	.quad 1b,12b
+	.previous
+	CFI_ENDPROC
+ENDPROC(copy_user_enhanced_fast_string)
diff -druN linux-2.6.39-libre/arch/x86/lib/memcpy_64.S linux-3.0-rc7-libre/arch/x86/lib/memcpy_64.S
--- linux-2.6.39-libre/arch/x86/lib/memcpy_64.S	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/lib/memcpy_64.S	2011-07-11 19:51:52.000000000 -0400
@@ -4,6 +4,7 @@
 
 #include <asm/cpufeature.h>
 #include <asm/dwarf2.h>
+#include <asm/alternative-asm.h>
 
 /*
  * memcpy - Copy a memory block.
@@ -37,6 +38,23 @@
 .Lmemcpy_e:
 	.previous
 
+/*
+ * memcpy_c_e() - enhanced fast string memcpy. This is faster and simpler than
+ * memcpy_c. Use memcpy_c_e when possible.
+ *
+ * This gets patched over the unrolled variant (below) via the
+ * alternative instructions framework:
+ */
+	.section .altinstr_replacement, "ax", @progbits
+.Lmemcpy_c_e:
+	movq %rdi, %rax
+
+	movl %edx, %ecx
+	rep movsb
+	ret
+.Lmemcpy_e_e:
+	.previous
+
 ENTRY(__memcpy)
 ENTRY(memcpy)
 	CFI_STARTPROC
@@ -49,7 +67,7 @@
 	jb .Lhandle_tail
 
 	/*
-	 * We check whether memory false dependece could occur,
+	 * We check whether memory false dependence could occur,
 	 * then jump to corresponding copy mode.
 	 */
 	cmp  %dil, %sil
@@ -171,21 +189,22 @@
 ENDPROC(__memcpy)
 
 	/*
-	 * Some CPUs run faster using the string copy instructions.
-	 * It is also a lot simpler. Use this when possible:
-	 */
-
-	.section .altinstructions, "a"
-	.align 8
-	.quad memcpy
-	.quad .Lmemcpy_c
-	.word X86_FEATURE_REP_GOOD
-
-	/*
+	 * Some CPUs are adding enhanced REP MOVSB/STOSB feature
+	 * If the feature is supported, memcpy_c_e() is the first choice.
+	 * If enhanced rep movsb copy is not available, use fast string copy
+	 * memcpy_c() when possible. This is faster and code is simpler than
+	 * original memcpy().
+	 * Otherwise, original memcpy() is used.
+	 * In .altinstructions section, ERMS feature is placed after REG_GOOD
+         * feature to implement the right patch order.
+	 *
 	 * Replace only beginning, memcpy is used to apply alternatives,
 	 * so it is silly to overwrite itself with nops - reboot is the
 	 * only outcome...
 	 */
-	.byte .Lmemcpy_e - .Lmemcpy_c
-	.byte .Lmemcpy_e - .Lmemcpy_c
+	.section .altinstructions, "a"
+	altinstruction_entry memcpy,.Lmemcpy_c,X86_FEATURE_REP_GOOD,\
+			     .Lmemcpy_e-.Lmemcpy_c,.Lmemcpy_e-.Lmemcpy_c
+	altinstruction_entry memcpy,.Lmemcpy_c_e,X86_FEATURE_ERMS, \
+			     .Lmemcpy_e_e-.Lmemcpy_c_e,.Lmemcpy_e_e-.Lmemcpy_c_e
 	.previous
diff -druN linux-2.6.39-libre/arch/x86/lib/memmove_64.S linux-3.0-rc7-libre/arch/x86/lib/memmove_64.S
--- linux-2.6.39-libre/arch/x86/lib/memmove_64.S	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/lib/memmove_64.S	2011-07-11 19:51:52.000000000 -0400
@@ -8,6 +8,7 @@
 #define _STRING_C
 #include <linux/linkage.h>
 #include <asm/dwarf2.h>
+#include <asm/cpufeature.h>
 
 #undef memmove
 
@@ -24,6 +25,7 @@
  */
 ENTRY(memmove)
 	CFI_STARTPROC
+
 	/* Handle more 32bytes in loop */
 	mov %rdi, %rax
 	cmp $0x20, %rdx
@@ -31,8 +33,13 @@
 
 	/* Decide forward/backward copy mode */
 	cmp %rdi, %rsi
-	jb	2f
+	jge .Lmemmove_begin_forward
+	mov %rsi, %r8
+	add %rdx, %r8
+	cmp %rdi, %r8
+	jg 2f
 
+.Lmemmove_begin_forward:
 	/*
 	 * movsq instruction have many startup latency
 	 * so we handle small size by general register.
@@ -78,6 +85,8 @@
 	rep movsq
 	movq %r11, (%r10)
 	jmp 13f
+.Lmemmove_end_forward:
+
 	/*
 	 * Handle data backward by movsq.
 	 */
@@ -194,4 +203,22 @@
 13:
 	retq
 	CFI_ENDPROC
+
+	.section .altinstr_replacement,"ax"
+.Lmemmove_begin_forward_efs:
+	/* Forward moving data. */
+	movq %rdx, %rcx
+	rep movsb
+	retq
+.Lmemmove_end_forward_efs:
+	.previous
+
+	.section .altinstructions,"a"
+	.align 8
+	.quad .Lmemmove_begin_forward
+	.quad .Lmemmove_begin_forward_efs
+	.word X86_FEATURE_ERMS
+	.byte .Lmemmove_end_forward-.Lmemmove_begin_forward
+	.byte .Lmemmove_end_forward_efs-.Lmemmove_begin_forward_efs
+	.previous
 ENDPROC(memmove)
diff -druN linux-2.6.39-libre/arch/x86/lib/memset_64.S linux-3.0-rc7-libre/arch/x86/lib/memset_64.S
--- linux-2.6.39-libre/arch/x86/lib/memset_64.S	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/lib/memset_64.S	2011-07-11 19:51:52.000000000 -0400
@@ -2,9 +2,13 @@
 
 #include <linux/linkage.h>
 #include <asm/dwarf2.h>
+#include <asm/cpufeature.h>
+#include <asm/alternative-asm.h>
 
 /*
- * ISO C memset - set a memory block to a byte value.
+ * ISO C memset - set a memory block to a byte value. This function uses fast
+ * string to get better performance than the original function. The code is
+ * simpler and shorter than the orignal function as well.
  *	
  * rdi   destination
  * rsi   value (char) 
@@ -31,6 +35,28 @@
 .Lmemset_e:
 	.previous
 
+/*
+ * ISO C memset - set a memory block to a byte value. This function uses
+ * enhanced rep stosb to override the fast string function.
+ * The code is simpler and shorter than the fast string function as well.
+ *
+ * rdi   destination
+ * rsi   value (char)
+ * rdx   count (bytes)
+ *
+ * rax   original destination
+ */
+	.section .altinstr_replacement, "ax", @progbits
+.Lmemset_c_e:
+	movq %rdi,%r9
+	movb %sil,%al
+	movl %edx,%ecx
+	rep stosb
+	movq %r9,%rax
+	ret
+.Lmemset_e_e:
+	.previous
+
 ENTRY(memset)
 ENTRY(__memset)
 	CFI_STARTPROC
@@ -112,16 +138,20 @@
 ENDPROC(memset)
 ENDPROC(__memset)
 
-	/* Some CPUs run faster using the string instructions.
-	   It is also a lot simpler. Use this when possible */
-
-#include <asm/cpufeature.h>
-
+	/* Some CPUs support enhanced REP MOVSB/STOSB feature.
+	 * It is recommended to use this when possible.
+	 *
+	 * If enhanced REP MOVSB/STOSB feature is not available, use fast string
+	 * instructions.
+	 *
+	 * Otherwise, use original memset function.
+	 *
+	 * In .altinstructions section, ERMS feature is placed after REG_GOOD
+         * feature to implement the right patch order.
+	 */
 	.section .altinstructions,"a"
-	.align 8
-	.quad memset
-	.quad .Lmemset_c
-	.word X86_FEATURE_REP_GOOD
-	.byte .Lfinal - memset
-	.byte .Lmemset_e - .Lmemset_c
+	altinstruction_entry memset,.Lmemset_c,X86_FEATURE_REP_GOOD,\
+			     .Lfinal-memset,.Lmemset_e-.Lmemset_c
+	altinstruction_entry memset,.Lmemset_c_e,X86_FEATURE_ERMS, \
+			     .Lfinal-memset,.Lmemset_e_e-.Lmemset_c_e
 	.previous
diff -druN linux-2.6.39-libre/arch/x86/Makefile_32.cpu linux-3.0-rc7-libre/arch/x86/Makefile_32.cpu
--- linux-2.6.39-libre/arch/x86/Makefile_32.cpu	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/Makefile_32.cpu	2011-07-11 19:51:52.000000000 -0400
@@ -37,7 +37,7 @@
 	$(call cc-option,-mtune=atom,$(call cc-option,-mtune=generic))
 
 # AMD Elan support
-cflags-$(CONFIG_X86_ELAN)	+= -march=i486
+cflags-$(CONFIG_MELAN)		+= -march=i486
 
 # Geode GX1 support
 cflags-$(CONFIG_MGEODEGX1)	+= -march=pentium-mmx
diff -druN linux-2.6.39-libre/arch/x86/mm/amdtopology_64.c linux-3.0-rc7-libre/arch/x86/mm/amdtopology_64.c
--- linux-2.6.39-libre/arch/x86/mm/amdtopology_64.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/mm/amdtopology_64.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,196 +0,0 @@
-/*
- * AMD NUMA support.
- * Discover the memory map and associated nodes.
- *
- * This version reads it directly from the AMD northbridge.
- *
- * Copyright 2002,2003 Andi Kleen, SuSE Labs.
- */
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/string.h>
-#include <linux/module.h>
-#include <linux/nodemask.h>
-#include <linux/memblock.h>
-
-#include <asm/io.h>
-#include <linux/pci_ids.h>
-#include <linux/acpi.h>
-#include <asm/types.h>
-#include <asm/mmzone.h>
-#include <asm/proto.h>
-#include <asm/e820.h>
-#include <asm/pci-direct.h>
-#include <asm/numa.h>
-#include <asm/mpspec.h>
-#include <asm/apic.h>
-#include <asm/amd_nb.h>
-
-static unsigned char __initdata nodeids[8];
-
-static __init int find_northbridge(void)
-{
-	int num;
-
-	for (num = 0; num < 32; num++) {
-		u32 header;
-
-		header = read_pci_config(0, num, 0, 0x00);
-		if (header != (PCI_VENDOR_ID_AMD | (0x1100<<16)) &&
-			header != (PCI_VENDOR_ID_AMD | (0x1200<<16)) &&
-			header != (PCI_VENDOR_ID_AMD | (0x1300<<16)))
-			continue;
-
-		header = read_pci_config(0, num, 1, 0x00);
-		if (header != (PCI_VENDOR_ID_AMD | (0x1101<<16)) &&
-			header != (PCI_VENDOR_ID_AMD | (0x1201<<16)) &&
-			header != (PCI_VENDOR_ID_AMD | (0x1301<<16)))
-			continue;
-		return num;
-	}
-
-	return -ENOENT;
-}
-
-static __init void early_get_boot_cpu_id(void)
-{
-	/*
-	 * need to get the APIC ID of the BSP so can use that to
-	 * create apicid_to_node in amd_scan_nodes()
-	 */
-#ifdef CONFIG_X86_MPPARSE
-	/*
-	 * get boot-time SMP configuration:
-	 */
-	if (smp_found_config)
-		early_get_smp_config();
-#endif
-}
-
-int __init amd_numa_init(void)
-{
-	unsigned long start = PFN_PHYS(0);
-	unsigned long end = PFN_PHYS(max_pfn);
-	unsigned numnodes;
-	unsigned long prevbase;
-	int i, j, nb;
-	u32 nodeid, reg;
-	unsigned int bits, cores, apicid_base;
-
-	if (!early_pci_allowed())
-		return -EINVAL;
-
-	nb = find_northbridge();
-	if (nb < 0)
-		return nb;
-
-	pr_info("Scanning NUMA topology in Northbridge %d\n", nb);
-
-	reg = read_pci_config(0, nb, 0, 0x60);
-	numnodes = ((reg >> 4) & 0xF) + 1;
-	if (numnodes <= 1)
-		return -ENOENT;
-
-	pr_info("Number of physical nodes %d\n", numnodes);
-
-	prevbase = 0;
-	for (i = 0; i < 8; i++) {
-		unsigned long base, limit;
-
-		base = read_pci_config(0, nb, 1, 0x40 + i*8);
-		limit = read_pci_config(0, nb, 1, 0x44 + i*8);
-
-		nodeids[i] = nodeid = limit & 7;
-		if ((base & 3) == 0) {
-			if (i < numnodes)
-				pr_info("Skipping disabled node %d\n", i);
-			continue;
-		}
-		if (nodeid >= numnodes) {
-			pr_info("Ignoring excess node %d (%lx:%lx)\n", nodeid,
-				base, limit);
-			continue;
-		}
-
-		if (!limit) {
-			pr_info("Skipping node entry %d (base %lx)\n",
-				i, base);
-			continue;
-		}
-		if ((base >> 8) & 3 || (limit >> 8) & 3) {
-			pr_err("Node %d using interleaving mode %lx/%lx\n",
-			       nodeid, (base >> 8) & 3, (limit >> 8) & 3);
-			return -EINVAL;
-		}
-		if (node_isset(nodeid, numa_nodes_parsed)) {
-			pr_info("Node %d already present, skipping\n",
-				nodeid);
-			continue;
-		}
-
-		limit >>= 16;
-		limit <<= 24;
-		limit |= (1<<24)-1;
-		limit++;
-
-		if (limit > end)
-			limit = end;
-		if (limit <= base)
-			continue;
-
-		base >>= 16;
-		base <<= 24;
-
-		if (base < start)
-			base = start;
-		if (limit > end)
-			limit = end;
-		if (limit == base) {
-			pr_err("Empty node %d\n", nodeid);
-			continue;
-		}
-		if (limit < base) {
-			pr_err("Node %d bogus settings %lx-%lx.\n",
-			       nodeid, base, limit);
-			continue;
-		}
-
-		/* Could sort here, but pun for now. Should not happen anyroads. */
-		if (prevbase > base) {
-			pr_err("Node map not sorted %lx,%lx\n",
-			       prevbase, base);
-			return -EINVAL;
-		}
-
-		pr_info("Node %d MemBase %016lx Limit %016lx\n",
-			nodeid, base, limit);
-
-		prevbase = base;
-		numa_add_memblk(nodeid, base, limit);
-		node_set(nodeid, numa_nodes_parsed);
-	}
-
-	if (!nodes_weight(numa_nodes_parsed))
-		return -ENOENT;
-
-	/*
-	 * We seem to have valid NUMA configuration.  Map apicids to nodes
-	 * using the coreid bits from early_identify_cpu.
-	 */
-	bits = boot_cpu_data.x86_coreid_bits;
-	cores = 1 << bits;
-	apicid_base = 0;
-
-	/* get the APIC ID of the BSP early for systems with apicid lifting */
-	early_get_boot_cpu_id();
-	if (boot_cpu_physical_apicid > 0) {
-		pr_info("BSP APIC ID: %02x\n", boot_cpu_physical_apicid);
-		apicid_base = boot_cpu_physical_apicid;
-	}
-
-	for_each_node_mask(i, numa_nodes_parsed)
-		for (j = apicid_base; j < cores + apicid_base; j++)
-			set_apicid_to_node((i << bits) + j, i);
-
-	return 0;
-}
diff -druN linux-2.6.39-libre/arch/x86/mm/amdtopology.c linux-3.0-rc7-libre/arch/x86/mm/amdtopology.c
--- linux-2.6.39-libre/arch/x86/mm/amdtopology.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/x86/mm/amdtopology.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,197 @@
+/*
+ * AMD NUMA support.
+ * Discover the memory map and associated nodes.
+ *
+ * This version reads it directly from the AMD northbridge.
+ *
+ * Copyright 2002,2003 Andi Kleen, SuSE Labs.
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/string.h>
+#include <linux/module.h>
+#include <linux/nodemask.h>
+#include <linux/memblock.h>
+#include <linux/bootmem.h>
+
+#include <asm/io.h>
+#include <linux/pci_ids.h>
+#include <linux/acpi.h>
+#include <asm/types.h>
+#include <asm/mmzone.h>
+#include <asm/proto.h>
+#include <asm/e820.h>
+#include <asm/pci-direct.h>
+#include <asm/numa.h>
+#include <asm/mpspec.h>
+#include <asm/apic.h>
+#include <asm/amd_nb.h>
+
+static unsigned char __initdata nodeids[8];
+
+static __init int find_northbridge(void)
+{
+	int num;
+
+	for (num = 0; num < 32; num++) {
+		u32 header;
+
+		header = read_pci_config(0, num, 0, 0x00);
+		if (header != (PCI_VENDOR_ID_AMD | (0x1100<<16)) &&
+			header != (PCI_VENDOR_ID_AMD | (0x1200<<16)) &&
+			header != (PCI_VENDOR_ID_AMD | (0x1300<<16)))
+			continue;
+
+		header = read_pci_config(0, num, 1, 0x00);
+		if (header != (PCI_VENDOR_ID_AMD | (0x1101<<16)) &&
+			header != (PCI_VENDOR_ID_AMD | (0x1201<<16)) &&
+			header != (PCI_VENDOR_ID_AMD | (0x1301<<16)))
+			continue;
+		return num;
+	}
+
+	return -ENOENT;
+}
+
+static __init void early_get_boot_cpu_id(void)
+{
+	/*
+	 * need to get the APIC ID of the BSP so can use that to
+	 * create apicid_to_node in amd_scan_nodes()
+	 */
+#ifdef CONFIG_X86_MPPARSE
+	/*
+	 * get boot-time SMP configuration:
+	 */
+	if (smp_found_config)
+		early_get_smp_config();
+#endif
+}
+
+int __init amd_numa_init(void)
+{
+	u64 start = PFN_PHYS(0);
+	u64 end = PFN_PHYS(max_pfn);
+	unsigned numnodes;
+	u64 prevbase;
+	int i, j, nb;
+	u32 nodeid, reg;
+	unsigned int bits, cores, apicid_base;
+
+	if (!early_pci_allowed())
+		return -EINVAL;
+
+	nb = find_northbridge();
+	if (nb < 0)
+		return nb;
+
+	pr_info("Scanning NUMA topology in Northbridge %d\n", nb);
+
+	reg = read_pci_config(0, nb, 0, 0x60);
+	numnodes = ((reg >> 4) & 0xF) + 1;
+	if (numnodes <= 1)
+		return -ENOENT;
+
+	pr_info("Number of physical nodes %d\n", numnodes);
+
+	prevbase = 0;
+	for (i = 0; i < 8; i++) {
+		u64 base, limit;
+
+		base = read_pci_config(0, nb, 1, 0x40 + i*8);
+		limit = read_pci_config(0, nb, 1, 0x44 + i*8);
+
+		nodeids[i] = nodeid = limit & 7;
+		if ((base & 3) == 0) {
+			if (i < numnodes)
+				pr_info("Skipping disabled node %d\n", i);
+			continue;
+		}
+		if (nodeid >= numnodes) {
+			pr_info("Ignoring excess node %d (%Lx:%Lx)\n", nodeid,
+				base, limit);
+			continue;
+		}
+
+		if (!limit) {
+			pr_info("Skipping node entry %d (base %Lx)\n",
+				i, base);
+			continue;
+		}
+		if ((base >> 8) & 3 || (limit >> 8) & 3) {
+			pr_err("Node %d using interleaving mode %Lx/%Lx\n",
+			       nodeid, (base >> 8) & 3, (limit >> 8) & 3);
+			return -EINVAL;
+		}
+		if (node_isset(nodeid, numa_nodes_parsed)) {
+			pr_info("Node %d already present, skipping\n",
+				nodeid);
+			continue;
+		}
+
+		limit >>= 16;
+		limit <<= 24;
+		limit |= (1<<24)-1;
+		limit++;
+
+		if (limit > end)
+			limit = end;
+		if (limit <= base)
+			continue;
+
+		base >>= 16;
+		base <<= 24;
+
+		if (base < start)
+			base = start;
+		if (limit > end)
+			limit = end;
+		if (limit == base) {
+			pr_err("Empty node %d\n", nodeid);
+			continue;
+		}
+		if (limit < base) {
+			pr_err("Node %d bogus settings %Lx-%Lx.\n",
+			       nodeid, base, limit);
+			continue;
+		}
+
+		/* Could sort here, but pun for now. Should not happen anyroads. */
+		if (prevbase > base) {
+			pr_err("Node map not sorted %Lx,%Lx\n",
+			       prevbase, base);
+			return -EINVAL;
+		}
+
+		pr_info("Node %d MemBase %016Lx Limit %016Lx\n",
+			nodeid, base, limit);
+
+		prevbase = base;
+		numa_add_memblk(nodeid, base, limit);
+		node_set(nodeid, numa_nodes_parsed);
+	}
+
+	if (!nodes_weight(numa_nodes_parsed))
+		return -ENOENT;
+
+	/*
+	 * We seem to have valid NUMA configuration.  Map apicids to nodes
+	 * using the coreid bits from early_identify_cpu.
+	 */
+	bits = boot_cpu_data.x86_coreid_bits;
+	cores = 1 << bits;
+	apicid_base = 0;
+
+	/* get the APIC ID of the BSP early for systems with apicid lifting */
+	early_get_boot_cpu_id();
+	if (boot_cpu_physical_apicid > 0) {
+		pr_info("BSP APIC ID: %02x\n", boot_cpu_physical_apicid);
+		apicid_base = boot_cpu_physical_apicid;
+	}
+
+	for_each_node_mask(i, numa_nodes_parsed)
+		for (j = apicid_base; j < cores + apicid_base; j++)
+			set_apicid_to_node((i << bits) + j, i);
+
+	return 0;
+}
diff -druN linux-2.6.39-libre/arch/x86/mm/fault.c linux-3.0-rc7-libre/arch/x86/mm/fault.c
--- linux-2.6.39-libre/arch/x86/mm/fault.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/mm/fault.c	2011-07-11 19:51:52.000000000 -0400
@@ -12,6 +12,7 @@
 #include <linux/mmiotrace.h>		/* kmmio_handler, ...		*/
 #include <linux/perf_event.h>		/* perf_sw_event		*/
 #include <linux/hugetlb.h>		/* hstate_index_to_shift	*/
+#include <linux/prefetch.h>		/* prefetchw			*/
 
 #include <asm/traps.h>			/* dotraplinkage, ...		*/
 #include <asm/pgalloc.h>		/* pgd_*(), ...			*/
@@ -822,16 +823,30 @@
 	force_sig_info_fault(SIGBUS, code, address, tsk, fault);
 }
 
-static noinline void
+static noinline int
 mm_fault_error(struct pt_regs *regs, unsigned long error_code,
 	       unsigned long address, unsigned int fault)
 {
+	/*
+	 * Pagefault was interrupted by SIGKILL. We have no reason to
+	 * continue pagefault.
+	 */
+	if (fatal_signal_pending(current)) {
+		if (!(fault & VM_FAULT_RETRY))
+			up_read(&current->mm->mmap_sem);
+		if (!(error_code & PF_USER))
+			no_context(regs, error_code, address);
+		return 1;
+	}
+	if (!(fault & VM_FAULT_ERROR))
+		return 0;
+
 	if (fault & VM_FAULT_OOM) {
 		/* Kernel mode? Handle exceptions or die: */
 		if (!(error_code & PF_USER)) {
 			up_read(&current->mm->mmap_sem);
 			no_context(regs, error_code, address);
-			return;
+			return 1;
 		}
 
 		out_of_memory(regs, error_code, address);
@@ -842,6 +857,7 @@
 		else
 			BUG();
 	}
+	return 1;
 }
 
 static int spurious_fault_check(unsigned long error_code, pte_t *pte)
@@ -964,7 +980,7 @@
 	struct mm_struct *mm;
 	int fault;
 	int write = error_code & PF_WRITE;
-	unsigned int flags = FAULT_FLAG_ALLOW_RETRY |
+	unsigned int flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE |
 					(write ? FAULT_FLAG_WRITE : 0);
 
 	tsk = current;
@@ -1132,9 +1148,9 @@
 	 */
 	fault = handle_mm_fault(mm, vma, address, flags);
 
-	if (unlikely(fault & VM_FAULT_ERROR)) {
-		mm_fault_error(regs, error_code, address, fault);
-		return;
+	if (unlikely(fault & (VM_FAULT_RETRY|VM_FAULT_ERROR))) {
+		if (mm_fault_error(regs, error_code, address, fault))
+			return;
 	}
 
 	/*
diff -druN linux-2.6.39-libre/arch/x86/mm/hugetlbpage.c linux-3.0-rc7-libre/arch/x86/mm/hugetlbpage.c
--- linux-2.6.39-libre/arch/x86/mm/hugetlbpage.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/mm/hugetlbpage.c	2011-07-11 19:51:52.000000000 -0400
@@ -72,7 +72,7 @@
 	if (!vma_shareable(vma, addr))
 		return;
 
-	spin_lock(&mapping->i_mmap_lock);
+	mutex_lock(&mapping->i_mmap_mutex);
 	vma_prio_tree_foreach(svma, &iter, &mapping->i_mmap, idx, idx) {
 		if (svma == vma)
 			continue;
@@ -97,7 +97,7 @@
 		put_page(virt_to_page(spte));
 	spin_unlock(&mm->page_table_lock);
 out:
-	spin_unlock(&mapping->i_mmap_lock);
+	mutex_unlock(&mapping->i_mmap_mutex);
 }
 
 /*
diff -druN linux-2.6.39-libre/arch/x86/mm/init_32.c linux-3.0-rc7-libre/arch/x86/mm/init_32.c
--- linux-2.6.39-libre/arch/x86/mm/init_32.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/mm/init_32.c	2011-07-11 19:51:52.000000000 -0400
@@ -678,8 +678,10 @@
 {
 	unsigned long max_zone_pfns[MAX_NR_ZONES];
 	memset(max_zone_pfns, 0, sizeof(max_zone_pfns));
+#ifdef CONFIG_ZONE_DMA
 	max_zone_pfns[ZONE_DMA] =
 		virt_to_phys((char *)MAX_DMA_ADDRESS) >> PAGE_SHIFT;
+#endif
 	max_zone_pfns[ZONE_NORMAL] = max_low_pfn;
 #ifdef CONFIG_HIGHMEM
 	max_zone_pfns[ZONE_HIGHMEM] = highend_pfn;
@@ -716,6 +718,7 @@
 	 * NOTE: at this point the bootmem allocator is fully available.
 	 */
 	olpc_dt_build_devicetree();
+	sparse_memory_present_with_active_regions(MAX_NUMNODES);
 	sparse_init();
 	zone_sizes_init();
 }
diff -druN linux-2.6.39-libre/arch/x86/mm/init_64.c linux-3.0-rc7-libre/arch/x86/mm/init_64.c
--- linux-2.6.39-libre/arch/x86/mm/init_64.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/mm/init_64.c	2011-07-11 19:51:52.000000000 -0400
@@ -616,7 +616,9 @@
 	unsigned long max_zone_pfns[MAX_NR_ZONES];
 
 	memset(max_zone_pfns, 0, sizeof(max_zone_pfns));
+#ifdef CONFIG_ZONE_DMA
 	max_zone_pfns[ZONE_DMA] = MAX_DMA_PFN;
+#endif
 	max_zone_pfns[ZONE_DMA32] = MAX_DMA32_PFN;
 	max_zone_pfns[ZONE_NORMAL] = max_pfn;
 
@@ -679,14 +681,6 @@
 }
 EXPORT_SYMBOL_GPL(arch_add_memory);
 
-#if !defined(CONFIG_ACPI_NUMA) && defined(CONFIG_NUMA)
-int memory_add_physaddr_to_nid(u64 start)
-{
-	return 0;
-}
-EXPORT_SYMBOL_GPL(memory_add_physaddr_to_nid);
-#endif
-
 #endif /* CONFIG_MEMORY_HOTPLUG */
 
 static struct kcore_list kcore_vsyscall;
diff -druN linux-2.6.39-libre/arch/x86/mm/init.c linux-3.0-rc7-libre/arch/x86/mm/init.c
--- linux-2.6.39-libre/arch/x86/mm/init.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/mm/init.c	2011-07-11 19:51:52.000000000 -0400
@@ -16,8 +16,6 @@
 #include <asm/tlb.h>
 #include <asm/proto.h>
 
-DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
-
 unsigned long __initdata pgt_buf_start;
 unsigned long __meminitdata pgt_buf_end;
 unsigned long __meminitdata pgt_buf_top;
diff -druN linux-2.6.39-libre/arch/x86/mm/ioremap.c linux-3.0-rc7-libre/arch/x86/mm/ioremap.c
--- linux-2.6.39-libre/arch/x86/mm/ioremap.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/mm/ioremap.c	2011-07-11 19:51:52.000000000 -0400
@@ -91,13 +91,6 @@
 		return (__force void __iomem *)phys_to_virt(phys_addr);
 
 	/*
-	 * Check if the request spans more than any BAR in the iomem resource
-	 * tree.
-	 */
-	WARN_ONCE(iomem_map_sanity_check(phys_addr, size),
-		  KERN_INFO "Info: mapping multiple BARs. Your kernel is fine.");
-
-	/*
 	 * Don't allow anybody to remap normal RAM that we're using..
 	 */
 	last_pfn = last_addr >> PAGE_SHIFT;
@@ -170,6 +163,13 @@
 	ret_addr = (void __iomem *) (vaddr + offset);
 	mmiotrace_ioremap(unaligned_phys_addr, unaligned_size, ret_addr);
 
+	/*
+	 * Check if the request spans more than any BAR in the iomem resource
+	 * tree.
+	 */
+	WARN_ONCE(iomem_map_sanity_check(unaligned_phys_addr, unaligned_size),
+		  KERN_INFO "Info: mapping multiple BARs. Your kernel is fine.");
+
 	return ret_addr;
 err_free_area:
 	free_vm_area(area);
diff -druN linux-2.6.39-libre/arch/x86/mm/Makefile linux-3.0-rc7-libre/arch/x86/mm/Makefile
--- linux-2.6.39-libre/arch/x86/mm/Makefile	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/mm/Makefile	2011-07-11 19:51:52.000000000 -0400
@@ -23,8 +23,8 @@
 obj-$(CONFIG_MMIOTRACE_TEST)	+= testmmiotrace.o
 
 obj-$(CONFIG_NUMA)		+= numa.o numa_$(BITS).o
-obj-$(CONFIG_AMD_NUMA)		+= amdtopology_64.o
-obj-$(CONFIG_ACPI_NUMA)		+= srat_$(BITS).o
+obj-$(CONFIG_AMD_NUMA)		+= amdtopology.o
+obj-$(CONFIG_ACPI_NUMA)		+= srat.o
 obj-$(CONFIG_NUMA_EMU)		+= numa_emulation.o
 
 obj-$(CONFIG_HAVE_MEMBLOCK)		+= memblock.o
diff -druN linux-2.6.39-libre/arch/x86/mm/memblock.c linux-3.0-rc7-libre/arch/x86/mm/memblock.c
--- linux-2.6.39-libre/arch/x86/mm/memblock.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/mm/memblock.c	2011-07-11 19:51:52.000000000 -0400
@@ -8,7 +8,7 @@
 #include <linux/range.h>
 
 /* Check for already reserved areas */
-static bool __init check_with_memblock_reserved_size(u64 *addrp, u64 *sizep, u64 align)
+bool __init memblock_x86_check_reserved_size(u64 *addrp, u64 *sizep, u64 align)
 {
 	struct memblock_region *r;
 	u64 addr = *addrp, last;
@@ -59,7 +59,7 @@
 		if (addr >= ei_last)
 			continue;
 		*sizep = ei_last - addr;
-		while (check_with_memblock_reserved_size(&addr, sizep, align))
+		while (memblock_x86_check_reserved_size(&addr, sizep, align))
 			;
 
 		if (*sizep)
diff -druN linux-2.6.39-libre/arch/x86/mm/numa_32.c linux-3.0-rc7-libre/arch/x86/mm/numa_32.c
--- linux-2.6.39-libre/arch/x86/mm/numa_32.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/mm/numa_32.c	2011-07-11 19:51:52.000000000 -0400
@@ -22,39 +22,11 @@
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
-#include <linux/mm.h>
 #include <linux/bootmem.h>
 #include <linux/memblock.h>
-#include <linux/mmzone.h>
-#include <linux/highmem.h>
-#include <linux/initrd.h>
-#include <linux/nodemask.h>
 #include <linux/module.h>
-#include <linux/kexec.h>
-#include <linux/pfn.h>
-#include <linux/swap.h>
-#include <linux/acpi.h>
-
-#include <asm/e820.h>
-#include <asm/setup.h>
-#include <asm/mmzone.h>
-#include <asm/bios_ebda.h>
-#include <asm/proto.h>
-
-struct pglist_data *node_data[MAX_NUMNODES] __read_mostly;
-EXPORT_SYMBOL(node_data);
-
-/*
- * numa interface - we expect the numa architecture specific code to have
- *                  populated the following initialisation.
- *
- * 1) node_online_map  - the map of all nodes configured (online) in the system
- * 2) node_start_pfn   - the starting page frame number for a node
- * 3) node_end_pfn     - the ending page fram number for a node
- */
-unsigned long node_start_pfn[MAX_NUMNODES] __read_mostly;
-unsigned long node_end_pfn[MAX_NUMNODES] __read_mostly;
 
+#include "numa_internal.h"
 
 #ifdef CONFIG_DISCONTIGMEM
 /*
@@ -99,108 +71,46 @@
 }
 #endif
 
-extern unsigned long find_max_low_pfn(void);
 extern unsigned long highend_pfn, highstart_pfn;
 
 #define LARGE_PAGE_BYTES (PTRS_PER_PTE * PAGE_SIZE)
 
-unsigned long node_remap_size[MAX_NUMNODES];
 static void *node_remap_start_vaddr[MAX_NUMNODES];
 void set_pmd_pfn(unsigned long vaddr, unsigned long pfn, pgprot_t flags);
 
-static unsigned long kva_start_pfn;
-static unsigned long kva_pages;
-
-int __cpuinit numa_cpu_node(int cpu)
-{
-	return apic->x86_32_numa_cpu_node(cpu);
-}
-
 /*
- * FLAT - support for basic PC memory model with discontig enabled, essentially
- *        a single node with all available processors in it with a flat
- *        memory map.
- */
-int __init get_memcfg_numa_flat(void)
-{
-	printk(KERN_DEBUG "NUMA - single node, flat memory mode\n");
-
-	node_start_pfn[0] = 0;
-	node_end_pfn[0] = max_pfn;
-	memblock_x86_register_active_regions(0, 0, max_pfn);
-	memory_present(0, 0, max_pfn);
-	node_remap_size[0] = node_memmap_size_bytes(0, 0, max_pfn);
-
-        /* Indicate there is one node available. */
-	nodes_clear(node_online_map);
-	node_set_online(0);
-	return 1;
-}
-
-/*
- * Find the highest page frame number we have available for the node
- */
-static void __init propagate_e820_map_node(int nid)
-{
-	if (node_end_pfn[nid] > max_pfn)
-		node_end_pfn[nid] = max_pfn;
-	/*
-	 * if a user has given mem=XXXX, then we need to make sure 
-	 * that the node _starts_ before that, too, not just ends
-	 */
-	if (node_start_pfn[nid] > max_pfn)
-		node_start_pfn[nid] = max_pfn;
-	BUG_ON(node_start_pfn[nid] > node_end_pfn[nid]);
-}
-
-/* 
- * Allocate memory for the pg_data_t for this node via a crude pre-bootmem
- * method.  For node zero take this from the bottom of memory, for
- * subsequent nodes place them at node_remap_start_vaddr which contains
- * node local data in physically node local memory.  See setup_memory()
- * for details.
- */
-static void __init allocate_pgdat(int nid)
-{
-	char buf[16];
-
-	if (node_has_online_mem(nid) && node_remap_start_vaddr[nid])
-		NODE_DATA(nid) = (pg_data_t *)node_remap_start_vaddr[nid];
-	else {
-		unsigned long pgdat_phys;
-		pgdat_phys = memblock_find_in_range(min_low_pfn<<PAGE_SHIFT,
-				 max_pfn_mapped<<PAGE_SHIFT,
-				 sizeof(pg_data_t),
-				 PAGE_SIZE);
-		NODE_DATA(nid) = (pg_data_t *)(pfn_to_kaddr(pgdat_phys>>PAGE_SHIFT));
-		memset(buf, 0, sizeof(buf));
-		sprintf(buf, "NODE_DATA %d",  nid);
-		memblock_x86_reserve_range(pgdat_phys, pgdat_phys + sizeof(pg_data_t), buf);
-	}
-	printk(KERN_DEBUG "allocate_pgdat: node %d NODE_DATA %08lx\n",
-		nid, (unsigned long)NODE_DATA(nid));
-}
-
-/*
- * In the DISCONTIGMEM and SPARSEMEM memory model, a portion of the kernel
- * virtual address space (KVA) is reserved and portions of nodes are mapped
- * using it. This is to allow node-local memory to be allocated for
- * structures that would normally require ZONE_NORMAL. The memory is
- * allocated with alloc_remap() and callers should be prepared to allocate
- * from the bootmem allocator instead.
+ * Remap memory allocator
  */
 static unsigned long node_remap_start_pfn[MAX_NUMNODES];
 static void *node_remap_end_vaddr[MAX_NUMNODES];
 static void *node_remap_alloc_vaddr[MAX_NUMNODES];
-static unsigned long node_remap_offset[MAX_NUMNODES];
 
+/**
+ * alloc_remap - Allocate remapped memory
+ * @nid: NUMA node to allocate memory from
+ * @size: The size of allocation
+ *
+ * Allocate @size bytes from the remap area of NUMA node @nid.  The
+ * size of the remap area is predetermined by init_alloc_remap() and
+ * only the callers considered there should call this function.  For
+ * more info, please read the comment on top of init_alloc_remap().
+ *
+ * The caller must be ready to handle allocation failure from this
+ * function and fall back to regular memory allocator in such cases.
+ *
+ * CONTEXT:
+ * Single CPU early boot context.
+ *
+ * RETURNS:
+ * Pointer to the allocated memory on success, %NULL on failure.
+ */
 void *alloc_remap(int nid, unsigned long size)
 {
 	void *allocation = node_remap_alloc_vaddr[nid];
 
 	size = ALIGN(size, L1_CACHE_BYTES);
 
-	if (!allocation || (allocation + size) >= node_remap_end_vaddr[nid])
+	if (!allocation || (allocation + size) > node_remap_end_vaddr[nid])
 		return NULL;
 
 	node_remap_alloc_vaddr[nid] += size;
@@ -209,26 +119,6 @@
 	return allocation;
 }
 
-static void __init remap_numa_kva(void)
-{
-	void *vaddr;
-	unsigned long pfn;
-	int node;
-
-	for_each_online_node(node) {
-		printk(KERN_DEBUG "remap_numa_kva: node %d\n", node);
-		for (pfn=0; pfn < node_remap_size[node]; pfn += PTRS_PER_PTE) {
-			vaddr = node_remap_start_vaddr[node]+(pfn<<PAGE_SHIFT);
-			printk(KERN_DEBUG "remap_numa_kva: %08lx to pfn %08lx\n",
-				(unsigned long)vaddr,
-				node_remap_start_pfn[node] + pfn);
-			set_pmd_pfn((ulong) vaddr, 
-				node_remap_start_pfn[node] + pfn, 
-				PAGE_KERNEL_LARGE);
-		}
-	}
-}
-
 #ifdef CONFIG_HIBERNATION
 /**
  * resume_map_numa_kva - add KVA mapping to the temporary page tables created
@@ -240,15 +130,16 @@
 	int node;
 
 	for_each_online_node(node) {
-		unsigned long start_va, start_pfn, size, pfn;
+		unsigned long start_va, start_pfn, nr_pages, pfn;
 
 		start_va = (unsigned long)node_remap_start_vaddr[node];
 		start_pfn = node_remap_start_pfn[node];
-		size = node_remap_size[node];
+		nr_pages = (node_remap_end_vaddr[node] -
+			    node_remap_start_vaddr[node]) >> PAGE_SHIFT;
 
 		printk(KERN_DEBUG "%s: node %d\n", __func__, node);
 
-		for (pfn = 0; pfn < size; pfn += PTRS_PER_PTE) {
+		for (pfn = 0; pfn < nr_pages; pfn += PTRS_PER_PTE) {
 			unsigned long vaddr = start_va + (pfn << PAGE_SHIFT);
 			pgd_t *pgd = pgd_base + pgd_index(vaddr);
 			pud_t *pud = pud_offset(pgd, vaddr);
@@ -264,132 +155,89 @@
 }
 #endif
 
-static __init unsigned long calculate_numa_remap_pages(void)
+/**
+ * init_alloc_remap - Initialize remap allocator for a NUMA node
+ * @nid: NUMA node to initizlie remap allocator for
+ *
+ * NUMA nodes may end up without any lowmem.  As allocating pgdat and
+ * memmap on a different node with lowmem is inefficient, a special
+ * remap allocator is implemented which can be used by alloc_remap().
+ *
+ * For each node, the amount of memory which will be necessary for
+ * pgdat and memmap is calculated and two memory areas of the size are
+ * allocated - one in the node and the other in lowmem; then, the area
+ * in the node is remapped to the lowmem area.
+ *
+ * As pgdat and memmap must be allocated in lowmem anyway, this
+ * doesn't waste lowmem address space; however, the actual lowmem
+ * which gets remapped over is wasted.  The amount shouldn't be
+ * problematic on machines this feature will be used.
+ *
+ * Initialization failure isn't fatal.  alloc_remap() is used
+ * opportunistically and the callers will fall back to other memory
+ * allocation mechanisms on failure.
+ */
+void __init init_alloc_remap(int nid, u64 start, u64 end)
 {
-	int nid;
-	unsigned long size, reserve_pages = 0;
-
-	for_each_online_node(nid) {
-		u64 node_kva_target;
-		u64 node_kva_final;
-
-		/*
-		 * The acpi/srat node info can show hot-add memroy zones
-		 * where memory could be added but not currently present.
-		 */
-		printk(KERN_DEBUG "node %d pfn: [%lx - %lx]\n",
-			nid, node_start_pfn[nid], node_end_pfn[nid]);
-		if (node_start_pfn[nid] > max_pfn)
-			continue;
-		if (!node_end_pfn[nid])
-			continue;
-		if (node_end_pfn[nid] > max_pfn)
-			node_end_pfn[nid] = max_pfn;
-
-		/* ensure the remap includes space for the pgdat. */
-		size = node_remap_size[nid] + sizeof(pg_data_t);
-
-		/* convert size to large (pmd size) pages, rounding up */
-		size = (size + LARGE_PAGE_BYTES - 1) / LARGE_PAGE_BYTES;
-		/* now the roundup is correct, convert to PAGE_SIZE pages */
-		size = size * PTRS_PER_PTE;
-
-		node_kva_target = round_down(node_end_pfn[nid] - size,
-						 PTRS_PER_PTE);
-		node_kva_target <<= PAGE_SHIFT;
-		do {
-			node_kva_final = memblock_find_in_range(node_kva_target,
-					((u64)node_end_pfn[nid])<<PAGE_SHIFT,
-						((u64)size)<<PAGE_SHIFT,
-						LARGE_PAGE_BYTES);
-			node_kva_target -= LARGE_PAGE_BYTES;
-		} while (node_kva_final == MEMBLOCK_ERROR &&
-			 (node_kva_target>>PAGE_SHIFT) > (node_start_pfn[nid]));
+	unsigned long start_pfn = start >> PAGE_SHIFT;
+	unsigned long end_pfn = end >> PAGE_SHIFT;
+	unsigned long size, pfn;
+	u64 node_pa, remap_pa;
+	void *remap_va;
 
-		if (node_kva_final == MEMBLOCK_ERROR)
-			panic("Can not get kva ram\n");
+	/*
+	 * The acpi/srat node info can show hot-add memroy zones where
+	 * memory could be added but not currently present.
+	 */
+	printk(KERN_DEBUG "node %d pfn: [%lx - %lx]\n",
+	       nid, start_pfn, end_pfn);
 
-		node_remap_size[nid] = size;
-		node_remap_offset[nid] = reserve_pages;
-		reserve_pages += size;
-		printk(KERN_DEBUG "Reserving %ld pages of KVA for lmem_map of"
-				  " node %d at %llx\n",
-				size, nid, node_kva_final>>PAGE_SHIFT);
+	/* calculate the necessary space aligned to large page size */
+	size = node_memmap_size_bytes(nid, start_pfn, end_pfn);
+	size += ALIGN(sizeof(pg_data_t), PAGE_SIZE);
+	size = ALIGN(size, LARGE_PAGE_BYTES);
 
-		/*
-		 *  prevent kva address below max_low_pfn want it on system
-		 *  with less memory later.
-		 *  layout will be: KVA address , KVA RAM
-		 *
-		 *  we are supposed to only record the one less then max_low_pfn
-		 *  but we could have some hole in high memory, and it will only
-		 *  check page_is_ram(pfn) && !page_is_reserved_early(pfn) to decide
-		 *  to use it as free.
-		 *  So memblock_x86_reserve_range here, hope we don't run out of that array
-		 */
-		memblock_x86_reserve_range(node_kva_final,
-			      node_kva_final+(((u64)size)<<PAGE_SHIFT),
-			      "KVA RAM");
+	/* allocate node memory and the lowmem remap area */
+	node_pa = memblock_find_in_range(start, end, size, LARGE_PAGE_BYTES);
+	if (node_pa == MEMBLOCK_ERROR) {
+		pr_warning("remap_alloc: failed to allocate %lu bytes for node %d\n",
+			   size, nid);
+		return;
+	}
+	memblock_x86_reserve_range(node_pa, node_pa + size, "KVA RAM");
 
-		node_remap_start_pfn[nid] = node_kva_final>>PAGE_SHIFT;
+	remap_pa = memblock_find_in_range(min_low_pfn << PAGE_SHIFT,
+					  max_low_pfn << PAGE_SHIFT,
+					  size, LARGE_PAGE_BYTES);
+	if (remap_pa == MEMBLOCK_ERROR) {
+		pr_warning("remap_alloc: failed to allocate %lu bytes remap area for node %d\n",
+			   size, nid);
+		memblock_x86_free_range(node_pa, node_pa + size);
+		return;
 	}
-	printk(KERN_INFO "Reserving total of %lx pages for numa KVA remap\n",
-			reserve_pages);
-	return reserve_pages;
-}
+	memblock_x86_reserve_range(remap_pa, remap_pa + size, "KVA PG");
+	remap_va = phys_to_virt(remap_pa);
 
-static void init_remap_allocator(int nid)
-{
-	node_remap_start_vaddr[nid] = pfn_to_kaddr(
-			kva_start_pfn + node_remap_offset[nid]);
-	node_remap_end_vaddr[nid] = node_remap_start_vaddr[nid] +
-		(node_remap_size[nid] * PAGE_SIZE);
-	node_remap_alloc_vaddr[nid] = node_remap_start_vaddr[nid] +
-		ALIGN(sizeof(pg_data_t), PAGE_SIZE);
+	/* perform actual remap */
+	for (pfn = 0; pfn < size >> PAGE_SHIFT; pfn += PTRS_PER_PTE)
+		set_pmd_pfn((unsigned long)remap_va + (pfn << PAGE_SHIFT),
+			    (node_pa >> PAGE_SHIFT) + pfn,
+			    PAGE_KERNEL_LARGE);
 
-	printk(KERN_DEBUG "node %d will remap to vaddr %08lx - %08lx\n", nid,
-		(ulong) node_remap_start_vaddr[nid],
-		(ulong) node_remap_end_vaddr[nid]);
+	/* initialize remap allocator parameters */
+	node_remap_start_pfn[nid] = node_pa >> PAGE_SHIFT;
+	node_remap_start_vaddr[nid] = remap_va;
+	node_remap_end_vaddr[nid] = remap_va + size;
+	node_remap_alloc_vaddr[nid] = remap_va;
+
+	printk(KERN_DEBUG "remap_alloc: node %d [%08llx-%08llx) -> [%p-%p)\n",
+	       nid, node_pa, node_pa + size, remap_va, remap_va + size);
 }
 
 void __init initmem_init(void)
 {
-	int nid;
-	long kva_target_pfn;
-
-	/*
-	 * When mapping a NUMA machine we allocate the node_mem_map arrays
-	 * from node local memory.  They are then mapped directly into KVA
-	 * between zone normal and vmalloc space.  Calculate the size of
-	 * this space and use it to adjust the boundary between ZONE_NORMAL
-	 * and ZONE_HIGHMEM.
-	 */
-
-	get_memcfg_numa();
-	numa_init_array();
-
-	kva_pages = roundup(calculate_numa_remap_pages(), PTRS_PER_PTE);
-
-	kva_target_pfn = round_down(max_low_pfn - kva_pages, PTRS_PER_PTE);
-	do {
-		kva_start_pfn = memblock_find_in_range(kva_target_pfn<<PAGE_SHIFT,
-					max_low_pfn<<PAGE_SHIFT,
-					kva_pages<<PAGE_SHIFT,
-					PTRS_PER_PTE<<PAGE_SHIFT) >> PAGE_SHIFT;
-		kva_target_pfn -= PTRS_PER_PTE;
-	} while (kva_start_pfn == MEMBLOCK_ERROR && kva_target_pfn > min_low_pfn);
-
-	if (kva_start_pfn == MEMBLOCK_ERROR)
-		panic("Can not get kva space\n");
-
-	printk(KERN_INFO "kva_start_pfn ~ %lx max_low_pfn ~ %lx\n",
-		kva_start_pfn, max_low_pfn);
-	printk(KERN_INFO "max_pfn = %lx\n", max_pfn);
+	x86_numa_init();
 
-	/* avoid clash with initrd */
-	memblock_x86_reserve_range(kva_start_pfn<<PAGE_SHIFT,
-		      (kva_start_pfn + kva_pages)<<PAGE_SHIFT,
-		     "KVA PG");
 #ifdef CONFIG_HIGHMEM
 	highstart_pfn = highend_pfn = max_pfn;
 	if (max_pfn > max_low_pfn)
@@ -409,51 +257,9 @@
 
 	printk(KERN_DEBUG "Low memory ends at vaddr %08lx\n",
 			(ulong) pfn_to_kaddr(max_low_pfn));
-	for_each_online_node(nid) {
-		init_remap_allocator(nid);
-
-		allocate_pgdat(nid);
-	}
-	remap_numa_kva();
 
 	printk(KERN_DEBUG "High memory starts at vaddr %08lx\n",
 			(ulong) pfn_to_kaddr(highstart_pfn));
-	for_each_online_node(nid)
-		propagate_e820_map_node(nid);
-
-	for_each_online_node(nid) {
-		memset(NODE_DATA(nid), 0, sizeof(struct pglist_data));
-		NODE_DATA(nid)->node_id = nid;
-	}
 
 	setup_bootmem_allocator();
 }
-
-#ifdef CONFIG_MEMORY_HOTPLUG
-static int paddr_to_nid(u64 addr)
-{
-	int nid;
-	unsigned long pfn = PFN_DOWN(addr);
-
-	for_each_node(nid)
-		if (node_start_pfn[nid] <= pfn &&
-		    pfn < node_end_pfn[nid])
-			return nid;
-
-	return -1;
-}
-
-/*
- * This function is used to ask node id BEFORE memmap and mem_section's
- * initialization (pfn_to_nid() can't be used yet).
- * If _PXM is not defined on ACPI's DSDT, node id must be found by this.
- */
-int memory_add_physaddr_to_nid(u64 addr)
-{
-	int nid = paddr_to_nid(addr);
-	return (nid >= 0) ? nid : 0;
-}
-
-EXPORT_SYMBOL_GPL(memory_add_physaddr_to_nid);
-#endif
-
diff -druN linux-2.6.39-libre/arch/x86/mm/numa_64.c linux-3.0-rc7-libre/arch/x86/mm/numa_64.c
--- linux-2.6.39-libre/arch/x86/mm/numa_64.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/mm/numa_64.c	2011-07-11 19:51:52.000000000 -0400
@@ -2,646 +2,13 @@
  * Generic VM initialization for x86-64 NUMA setups.
  * Copyright 2002,2003 Andi Kleen, SuSE Labs.
  */
-#include <linux/kernel.h>
-#include <linux/mm.h>
-#include <linux/string.h>
-#include <linux/init.h>
 #include <linux/bootmem.h>
-#include <linux/memblock.h>
-#include <linux/mmzone.h>
-#include <linux/ctype.h>
-#include <linux/module.h>
-#include <linux/nodemask.h>
-#include <linux/sched.h>
-#include <linux/acpi.h>
-
-#include <asm/e820.h>
-#include <asm/proto.h>
-#include <asm/dma.h>
-#include <asm/acpi.h>
-#include <asm/amd_nb.h>
 
 #include "numa_internal.h"
 
-struct pglist_data *node_data[MAX_NUMNODES] __read_mostly;
-EXPORT_SYMBOL(node_data);
-
-nodemask_t numa_nodes_parsed __initdata;
-
-struct memnode memnode;
-
-static unsigned long __initdata nodemap_addr;
-static unsigned long __initdata nodemap_size;
-
-static struct numa_meminfo numa_meminfo __initdata;
-
-static int numa_distance_cnt;
-static u8 *numa_distance;
-
-/*
- * Given a shift value, try to populate memnodemap[]
- * Returns :
- * 1 if OK
- * 0 if memnodmap[] too small (of shift too small)
- * -1 if node overlap or lost ram (shift too big)
- */
-static int __init populate_memnodemap(const struct numa_meminfo *mi, int shift)
-{
-	unsigned long addr, end;
-	int i, res = -1;
-
-	memset(memnodemap, 0xff, sizeof(s16)*memnodemapsize);
-	for (i = 0; i < mi->nr_blks; i++) {
-		addr = mi->blk[i].start;
-		end = mi->blk[i].end;
-		if (addr >= end)
-			continue;
-		if ((end >> shift) >= memnodemapsize)
-			return 0;
-		do {
-			if (memnodemap[addr >> shift] != NUMA_NO_NODE)
-				return -1;
-			memnodemap[addr >> shift] = mi->blk[i].nid;
-			addr += (1UL << shift);
-		} while (addr < end);
-		res = 1;
-	}
-	return res;
-}
-
-static int __init allocate_cachealigned_memnodemap(void)
-{
-	unsigned long addr;
-
-	memnodemap = memnode.embedded_map;
-	if (memnodemapsize <= ARRAY_SIZE(memnode.embedded_map))
-		return 0;
-
-	addr = 0x8000;
-	nodemap_size = roundup(sizeof(s16) * memnodemapsize, L1_CACHE_BYTES);
-	nodemap_addr = memblock_find_in_range(addr, get_max_mapped(),
-				      nodemap_size, L1_CACHE_BYTES);
-	if (nodemap_addr == MEMBLOCK_ERROR) {
-		printk(KERN_ERR
-		       "NUMA: Unable to allocate Memory to Node hash map\n");
-		nodemap_addr = nodemap_size = 0;
-		return -1;
-	}
-	memnodemap = phys_to_virt(nodemap_addr);
-	memblock_x86_reserve_range(nodemap_addr, nodemap_addr + nodemap_size, "MEMNODEMAP");
-
-	printk(KERN_DEBUG "NUMA: Allocated memnodemap from %lx - %lx\n",
-	       nodemap_addr, nodemap_addr + nodemap_size);
-	return 0;
-}
-
-/*
- * The LSB of all start and end addresses in the node map is the value of the
- * maximum possible shift.
- */
-static int __init extract_lsb_from_nodes(const struct numa_meminfo *mi)
-{
-	int i, nodes_used = 0;
-	unsigned long start, end;
-	unsigned long bitfield = 0, memtop = 0;
-
-	for (i = 0; i < mi->nr_blks; i++) {
-		start = mi->blk[i].start;
-		end = mi->blk[i].end;
-		if (start >= end)
-			continue;
-		bitfield |= start;
-		nodes_used++;
-		if (end > memtop)
-			memtop = end;
-	}
-	if (nodes_used <= 1)
-		i = 63;
-	else
-		i = find_first_bit(&bitfield, sizeof(unsigned long)*8);
-	memnodemapsize = (memtop >> i)+1;
-	return i;
-}
-
-static int __init compute_hash_shift(const struct numa_meminfo *mi)
-{
-	int shift;
-
-	shift = extract_lsb_from_nodes(mi);
-	if (allocate_cachealigned_memnodemap())
-		return -1;
-	printk(KERN_DEBUG "NUMA: Using %d for the hash shift.\n",
-		shift);
-
-	if (populate_memnodemap(mi, shift) != 1) {
-		printk(KERN_INFO "Your memory is not aligned you need to "
-		       "rebuild your kernel with a bigger NODEMAPSIZE "
-		       "shift=%d\n", shift);
-		return -1;
-	}
-	return shift;
-}
-
-int __meminit  __early_pfn_to_nid(unsigned long pfn)
-{
-	return phys_to_nid(pfn << PAGE_SHIFT);
-}
-
-static void * __init early_node_mem(int nodeid, unsigned long start,
-				    unsigned long end, unsigned long size,
-				    unsigned long align)
-{
-	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 = memblock_x86_find_in_range_node(nodeid, start, end, size, align);
-	if (mem != MEMBLOCK_ERROR)
-		return __va(mem);
-
-	/* extend the search scope */
-	end = max_pfn_mapped << PAGE_SHIFT;
-	start = MAX_DMA_PFN << PAGE_SHIFT;
-	mem = memblock_find_in_range(start, end, size, align);
-	if (mem != MEMBLOCK_ERROR)
-		return __va(mem);
-
-	printk(KERN_ERR "Cannot find %lu bytes in node %d\n",
-		       size, nodeid);
-
-	return NULL;
-}
-
-static int __init numa_add_memblk_to(int nid, u64 start, u64 end,
-				     struct numa_meminfo *mi)
-{
-	/* ignore zero length blks */
-	if (start == end)
-		return 0;
-
-	/* whine about and ignore invalid blks */
-	if (start > end || nid < 0 || nid >= MAX_NUMNODES) {
-		pr_warning("NUMA: Warning: invalid memblk node %d (%Lx-%Lx)\n",
-			   nid, start, end);
-		return 0;
-	}
-
-	if (mi->nr_blks >= NR_NODE_MEMBLKS) {
-		pr_err("NUMA: too many memblk ranges\n");
-		return -EINVAL;
-	}
-
-	mi->blk[mi->nr_blks].start = start;
-	mi->blk[mi->nr_blks].end = end;
-	mi->blk[mi->nr_blks].nid = nid;
-	mi->nr_blks++;
-	return 0;
-}
-
-/**
- * numa_remove_memblk_from - Remove one numa_memblk from a numa_meminfo
- * @idx: Index of memblk to remove
- * @mi: numa_meminfo to remove memblk from
- *
- * Remove @idx'th numa_memblk from @mi by shifting @mi->blk[] and
- * decrementing @mi->nr_blks.
- */
-void __init numa_remove_memblk_from(int idx, struct numa_meminfo *mi)
-{
-	mi->nr_blks--;
-	memmove(&mi->blk[idx], &mi->blk[idx + 1],
-		(mi->nr_blks - idx) * sizeof(mi->blk[0]));
-}
-
-/**
- * numa_add_memblk - Add one numa_memblk to numa_meminfo
- * @nid: NUMA node ID of the new memblk
- * @start: Start address of the new memblk
- * @end: End address of the new memblk
- *
- * Add a new memblk to the default numa_meminfo.
- *
- * RETURNS:
- * 0 on success, -errno on failure.
- */
-int __init numa_add_memblk(int nid, u64 start, u64 end)
-{
-	return numa_add_memblk_to(nid, start, end, &numa_meminfo);
-}
-
-/* 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, nodedata_phys;
-	const int pgdat_size = roundup(sizeof(pg_data_t), PAGE_SIZE);
-	int nid;
-
-	if (!end)
-		return;
-
-	/*
-	 * Don't confuse VM with a node that doesn't have the
-	 * minimum amount of memory:
-	 */
-	if (end && (end - start) < NODE_MIN_SIZE)
-		return;
-
-	start = roundup(start, ZONE_ALIGN);
-
-	printk(KERN_INFO "Initmem setup node %d %016lx-%016lx\n", nodeid,
-	       start, end);
-
-	start_pfn = start >> PAGE_SHIFT;
-	last_pfn = end >> PAGE_SHIFT;
-
-	node_data[nodeid] = early_node_mem(nodeid, start, end, pgdat_size,
-					   SMP_CACHE_BYTES);
-	if (node_data[nodeid] == NULL)
-		return;
-	nodedata_phys = __pa(node_data[nodeid]);
-	memblock_x86_reserve_range(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)->node_id = nodeid;
-	NODE_DATA(nodeid)->node_start_pfn = start_pfn;
-	NODE_DATA(nodeid)->node_spanned_pages = last_pfn - start_pfn;
-
-	node_set_online(nodeid);
-}
-
-/**
- * numa_cleanup_meminfo - Cleanup a numa_meminfo
- * @mi: numa_meminfo to clean up
- *
- * Sanitize @mi by merging and removing unncessary memblks.  Also check for
- * conflicts and clear unused memblks.
- *
- * RETURNS:
- * 0 on success, -errno on failure.
- */
-int __init numa_cleanup_meminfo(struct numa_meminfo *mi)
-{
-	const u64 low = 0;
-	const u64 high = (u64)max_pfn << PAGE_SHIFT;
-	int i, j, k;
-
-	for (i = 0; i < mi->nr_blks; i++) {
-		struct numa_memblk *bi = &mi->blk[i];
-
-		/* make sure all blocks are inside the limits */
-		bi->start = max(bi->start, low);
-		bi->end = min(bi->end, high);
-
-		/* and there's no empty block */
-		if (bi->start >= bi->end) {
-			numa_remove_memblk_from(i--, mi);
-			continue;
-		}
-
-		for (j = i + 1; j < mi->nr_blks; j++) {
-			struct numa_memblk *bj = &mi->blk[j];
-			unsigned long start, end;
-
-			/*
-			 * See whether there are overlapping blocks.  Whine
-			 * about but allow overlaps of the same nid.  They
-			 * will be merged below.
-			 */
-			if (bi->end > bj->start && bi->start < bj->end) {
-				if (bi->nid != bj->nid) {
-					pr_err("NUMA: node %d (%Lx-%Lx) overlaps with node %d (%Lx-%Lx)\n",
-					       bi->nid, bi->start, bi->end,
-					       bj->nid, bj->start, bj->end);
-					return -EINVAL;
-				}
-				pr_warning("NUMA: Warning: node %d (%Lx-%Lx) overlaps with itself (%Lx-%Lx)\n",
-					   bi->nid, bi->start, bi->end,
-					   bj->start, bj->end);
-			}
-
-			/*
-			 * Join together blocks on the same node, holes
-			 * between which don't overlap with memory on other
-			 * nodes.
-			 */
-			if (bi->nid != bj->nid)
-				continue;
-			start = max(min(bi->start, bj->start), low);
-			end = min(max(bi->end, bj->end), high);
-			for (k = 0; k < mi->nr_blks; k++) {
-				struct numa_memblk *bk = &mi->blk[k];
-
-				if (bi->nid == bk->nid)
-					continue;
-				if (start < bk->end && end > bk->start)
-					break;
-			}
-			if (k < mi->nr_blks)
-				continue;
-			printk(KERN_INFO "NUMA: Node %d [%Lx,%Lx) + [%Lx,%Lx) -> [%lx,%lx)\n",
-			       bi->nid, bi->start, bi->end, bj->start, bj->end,
-			       start, end);
-			bi->start = start;
-			bi->end = end;
-			numa_remove_memblk_from(j--, mi);
-		}
-	}
-
-	for (i = mi->nr_blks; i < ARRAY_SIZE(mi->blk); i++) {
-		mi->blk[i].start = mi->blk[i].end = 0;
-		mi->blk[i].nid = NUMA_NO_NODE;
-	}
-
-	return 0;
-}
-
-/*
- * Set nodes, which have memory in @mi, in *@nodemask.
- */
-static void __init numa_nodemask_from_meminfo(nodemask_t *nodemask,
-					      const struct numa_meminfo *mi)
-{
-	int i;
-
-	for (i = 0; i < ARRAY_SIZE(mi->blk); i++)
-		if (mi->blk[i].start != mi->blk[i].end &&
-		    mi->blk[i].nid != NUMA_NO_NODE)
-			node_set(mi->blk[i].nid, *nodemask);
-}
-
-/**
- * numa_reset_distance - Reset NUMA distance table
- *
- * The current table is freed.  The next numa_set_distance() call will
- * create a new one.
- */
-void __init numa_reset_distance(void)
-{
-	size_t size = numa_distance_cnt * numa_distance_cnt * sizeof(numa_distance[0]);
-
-	/* numa_distance could be 1LU marking allocation failure, test cnt */
-	if (numa_distance_cnt)
-		memblock_x86_free_range(__pa(numa_distance),
-					__pa(numa_distance) + size);
-	numa_distance_cnt = 0;
-	numa_distance = NULL;	/* enable table creation */
-}
-
-static int __init numa_alloc_distance(void)
-{
-	nodemask_t nodes_parsed;
-	size_t size;
-	int i, j, cnt = 0;
-	u64 phys;
-
-	/* size the new table and allocate it */
-	nodes_parsed = numa_nodes_parsed;
-	numa_nodemask_from_meminfo(&nodes_parsed, &numa_meminfo);
-
-	for_each_node_mask(i, nodes_parsed)
-		cnt = i;
-	cnt++;
-	size = cnt * cnt * sizeof(numa_distance[0]);
-
-	phys = memblock_find_in_range(0, (u64)max_pfn_mapped << PAGE_SHIFT,
-				      size, PAGE_SIZE);
-	if (phys == MEMBLOCK_ERROR) {
-		pr_warning("NUMA: Warning: can't allocate distance table!\n");
-		/* don't retry until explicitly reset */
-		numa_distance = (void *)1LU;
-		return -ENOMEM;
-	}
-	memblock_x86_reserve_range(phys, phys + size, "NUMA DIST");
-
-	numa_distance = __va(phys);
-	numa_distance_cnt = cnt;
-
-	/* fill with the default distances */
-	for (i = 0; i < cnt; i++)
-		for (j = 0; j < cnt; j++)
-			numa_distance[i * cnt + j] = i == j ?
-				LOCAL_DISTANCE : REMOTE_DISTANCE;
-	printk(KERN_DEBUG "NUMA: Initialized distance table, cnt=%d\n", cnt);
-
-	return 0;
-}
-
-/**
- * numa_set_distance - Set NUMA distance from one NUMA to another
- * @from: the 'from' node to set distance
- * @to: the 'to'  node to set distance
- * @distance: NUMA distance
- *
- * Set the distance from node @from to @to to @distance.  If distance table
- * doesn't exist, one which is large enough to accommodate all the currently
- * known nodes will be created.
- *
- * If such table cannot be allocated, a warning is printed and further
- * calls are ignored until the distance table is reset with
- * numa_reset_distance().
- *
- * If @from or @to is higher than the highest known node at the time of
- * table creation or @distance doesn't make sense, the call is ignored.
- * This is to allow simplification of specific NUMA config implementations.
- */
-void __init numa_set_distance(int from, int to, int distance)
-{
-	if (!numa_distance && numa_alloc_distance() < 0)
-		return;
-
-	if (from >= numa_distance_cnt || to >= numa_distance_cnt) {
-		printk_once(KERN_DEBUG "NUMA: Debug: distance out of bound, from=%d to=%d distance=%d\n",
-			    from, to, distance);
-		return;
-	}
-
-	if ((u8)distance != distance ||
-	    (from == to && distance != LOCAL_DISTANCE)) {
-		pr_warn_once("NUMA: Warning: invalid distance parameter, from=%d to=%d distance=%d\n",
-			     from, to, distance);
-		return;
-	}
-
-	numa_distance[from * numa_distance_cnt + to] = distance;
-}
-
-int __node_distance(int from, int to)
-{
-	if (from >= numa_distance_cnt || to >= numa_distance_cnt)
-		return from == to ? LOCAL_DISTANCE : REMOTE_DISTANCE;
-	return numa_distance[from * numa_distance_cnt + to];
-}
-EXPORT_SYMBOL(__node_distance);
-
-/*
- * Sanity check to catch more bad NUMA configurations (they are amazingly
- * common).  Make sure the nodes cover all memory.
- */
-static bool __init numa_meminfo_cover_memory(const struct numa_meminfo *mi)
-{
-	unsigned long numaram, e820ram;
-	int i;
-
-	numaram = 0;
-	for (i = 0; i < mi->nr_blks; i++) {
-		unsigned long s = mi->blk[i].start >> PAGE_SHIFT;
-		unsigned long e = mi->blk[i].end >> PAGE_SHIFT;
-		numaram += e - s;
-		numaram -= __absent_pages_in_range(mi->blk[i].nid, s, e);
-		if ((long)numaram < 0)
-			numaram = 0;
-	}
-
-	e820ram = max_pfn - (memblock_x86_hole_size(0,
-					max_pfn << PAGE_SHIFT) >> PAGE_SHIFT);
-	/* We seem to lose 3 pages somewhere. Allow 1M of slack. */
-	if ((long)(e820ram - numaram) >= (1 << (20 - PAGE_SHIFT))) {
-		printk(KERN_ERR "NUMA: nodes only cover %luMB of your %luMB e820 RAM. Not used.\n",
-		       (numaram << PAGE_SHIFT) >> 20,
-		       (e820ram << PAGE_SHIFT) >> 20);
-		return false;
-	}
-	return true;
-}
-
-static int __init numa_register_memblks(struct numa_meminfo *mi)
-{
-	int i, nid;
-
-	/* Account for nodes with cpus and no memory */
-	node_possible_map = numa_nodes_parsed;
-	numa_nodemask_from_meminfo(&node_possible_map, mi);
-	if (WARN_ON(nodes_empty(node_possible_map)))
-		return -EINVAL;
-
-	memnode_shift = compute_hash_shift(mi);
-	if (memnode_shift < 0) {
-		printk(KERN_ERR "NUMA: No NUMA node hash function found. Contact maintainer\n");
-		return -EINVAL;
-	}
-
-	for (i = 0; i < mi->nr_blks; i++)
-		memblock_x86_register_active_regions(mi->blk[i].nid,
-					mi->blk[i].start >> PAGE_SHIFT,
-					mi->blk[i].end >> PAGE_SHIFT);
-
-	/* for out of order entries */
-	sort_node_map();
-	if (!numa_meminfo_cover_memory(mi))
-		return -EINVAL;
-
-	/* Finally register nodes. */
-	for_each_node_mask(nid, node_possible_map) {
-		u64 start = (u64)max_pfn << PAGE_SHIFT;
-		u64 end = 0;
-
-		for (i = 0; i < mi->nr_blks; i++) {
-			if (nid != mi->blk[i].nid)
-				continue;
-			start = min(mi->blk[i].start, start);
-			end = max(mi->blk[i].end, end);
-		}
-
-		if (start < end)
-			setup_node_bootmem(nid, start, end);
-	}
-
-	return 0;
-}
-
-/**
- * dummy_numma_init - Fallback dummy NUMA init
- *
- * Used if there's no underlying NUMA architecture, NUMA initialization
- * fails, or NUMA is disabled on the command line.
- *
- * Must online at least one node and add memory blocks that cover all
- * allowed memory.  This function must not fail.
- */
-static int __init dummy_numa_init(void)
-{
-	printk(KERN_INFO "%s\n",
-	       numa_off ? "NUMA turned off" : "No NUMA configuration found");
-	printk(KERN_INFO "Faking a node at %016lx-%016lx\n",
-	       0LU, max_pfn << PAGE_SHIFT);
-
-	node_set(0, numa_nodes_parsed);
-	numa_add_memblk(0, 0, (u64)max_pfn << PAGE_SHIFT);
-
-	return 0;
-}
-
-static int __init numa_init(int (*init_func)(void))
-{
-	int i;
-	int ret;
-
-	for (i = 0; i < MAX_LOCAL_APIC; i++)
-		set_apicid_to_node(i, NUMA_NO_NODE);
-
-	nodes_clear(numa_nodes_parsed);
-	nodes_clear(node_possible_map);
-	nodes_clear(node_online_map);
-	memset(&numa_meminfo, 0, sizeof(numa_meminfo));
-	remove_all_active_ranges();
-	numa_reset_distance();
-
-	ret = init_func();
-	if (ret < 0)
-		return ret;
-	ret = numa_cleanup_meminfo(&numa_meminfo);
-	if (ret < 0)
-		return ret;
-
-	numa_emulation(&numa_meminfo, numa_distance_cnt);
-
-	ret = numa_register_memblks(&numa_meminfo);
-	if (ret < 0)
-		return ret;
-
-	for (i = 0; i < nr_cpu_ids; i++) {
-		int nid = early_cpu_to_node(i);
-
-		if (nid == NUMA_NO_NODE)
-			continue;
-		if (!node_online(nid))
-			numa_clear_node(i);
-	}
-	numa_init_array();
-	return 0;
-}
-
 void __init initmem_init(void)
 {
-	int ret;
-
-	if (!numa_off) {
-#ifdef CONFIG_ACPI_NUMA
-		ret = numa_init(x86_acpi_numa_init);
-		if (!ret)
-			return;
-#endif
-#ifdef CONFIG_AMD_NUMA
-		ret = numa_init(amd_numa_init);
-		if (!ret)
-			return;
-#endif
-	}
-
-	numa_init(dummy_numa_init);
+	x86_numa_init();
 }
 
 unsigned long __init numa_free_all_bootmem(void)
@@ -656,12 +23,3 @@
 
 	return pages;
 }
-
-int __cpuinit numa_cpu_node(int cpu)
-{
-	int apicid = early_per_cpu(x86_cpu_to_apicid, cpu);
-
-	if (apicid != BAD_APICID)
-		return __apicid_to_node[apicid];
-	return NUMA_NO_NODE;
-}
diff -druN linux-2.6.39-libre/arch/x86/mm/numa.c linux-3.0-rc7-libre/arch/x86/mm/numa.c
--- linux-2.6.39-libre/arch/x86/mm/numa.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/mm/numa.c	2011-07-11 19:51:52.000000000 -0400
@@ -1,11 +1,39 @@
 /* Common code for 32 and 64-bit NUMA */
-#include <linux/topology.h>
-#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/string.h>
+#include <linux/init.h>
 #include <linux/bootmem.h>
-#include <asm/numa.h>
+#include <linux/memblock.h>
+#include <linux/mmzone.h>
+#include <linux/ctype.h>
+#include <linux/module.h>
+#include <linux/nodemask.h>
+#include <linux/sched.h>
+#include <linux/topology.h>
+
+#include <asm/e820.h>
+#include <asm/proto.h>
+#include <asm/dma.h>
 #include <asm/acpi.h>
+#include <asm/amd_nb.h>
+
+#include "numa_internal.h"
 
 int __initdata numa_off;
+nodemask_t numa_nodes_parsed __initdata;
+
+struct pglist_data *node_data[MAX_NUMNODES] __read_mostly;
+EXPORT_SYMBOL(node_data);
+
+static struct numa_meminfo numa_meminfo
+#ifndef CONFIG_MEMORY_HOTPLUG
+__initdata
+#endif
+;
+
+static int numa_distance_cnt;
+static u8 *numa_distance;
 
 static __init int numa_setup(char *opt)
 {
@@ -32,6 +60,15 @@
 	[0 ... MAX_LOCAL_APIC-1] = NUMA_NO_NODE
 };
 
+int __cpuinit numa_cpu_node(int cpu)
+{
+	int apicid = early_per_cpu(x86_cpu_to_apicid, cpu);
+
+	if (apicid != BAD_APICID)
+		return __apicid_to_node[apicid];
+	return NUMA_NO_NODE;
+}
+
 cpumask_var_t node_to_cpumask_map[MAX_NUMNODES];
 EXPORT_SYMBOL(node_to_cpumask_map);
 
@@ -95,6 +132,407 @@
 	pr_debug("Node to cpumask map for %d nodes\n", nr_node_ids);
 }
 
+static int __init numa_add_memblk_to(int nid, u64 start, u64 end,
+				     struct numa_meminfo *mi)
+{
+	/* ignore zero length blks */
+	if (start == end)
+		return 0;
+
+	/* whine about and ignore invalid blks */
+	if (start > end || nid < 0 || nid >= MAX_NUMNODES) {
+		pr_warning("NUMA: Warning: invalid memblk node %d (%Lx-%Lx)\n",
+			   nid, start, end);
+		return 0;
+	}
+
+	if (mi->nr_blks >= NR_NODE_MEMBLKS) {
+		pr_err("NUMA: too many memblk ranges\n");
+		return -EINVAL;
+	}
+
+	mi->blk[mi->nr_blks].start = start;
+	mi->blk[mi->nr_blks].end = end;
+	mi->blk[mi->nr_blks].nid = nid;
+	mi->nr_blks++;
+	return 0;
+}
+
+/**
+ * numa_remove_memblk_from - Remove one numa_memblk from a numa_meminfo
+ * @idx: Index of memblk to remove
+ * @mi: numa_meminfo to remove memblk from
+ *
+ * Remove @idx'th numa_memblk from @mi by shifting @mi->blk[] and
+ * decrementing @mi->nr_blks.
+ */
+void __init numa_remove_memblk_from(int idx, struct numa_meminfo *mi)
+{
+	mi->nr_blks--;
+	memmove(&mi->blk[idx], &mi->blk[idx + 1],
+		(mi->nr_blks - idx) * sizeof(mi->blk[0]));
+}
+
+/**
+ * numa_add_memblk - Add one numa_memblk to numa_meminfo
+ * @nid: NUMA node ID of the new memblk
+ * @start: Start address of the new memblk
+ * @end: End address of the new memblk
+ *
+ * Add a new memblk to the default numa_meminfo.
+ *
+ * RETURNS:
+ * 0 on success, -errno on failure.
+ */
+int __init numa_add_memblk(int nid, u64 start, u64 end)
+{
+	return numa_add_memblk_to(nid, start, end, &numa_meminfo);
+}
+
+/* Initialize NODE_DATA for a node on the local memory */
+static void __init setup_node_data(int nid, u64 start, u64 end)
+{
+	const u64 nd_low = PFN_PHYS(MAX_DMA_PFN);
+	const u64 nd_high = PFN_PHYS(max_pfn_mapped);
+	const size_t nd_size = roundup(sizeof(pg_data_t), PAGE_SIZE);
+	bool remapped = false;
+	u64 nd_pa;
+	void *nd;
+	int tnid;
+
+	/*
+	 * Don't confuse VM with a node that doesn't have the
+	 * minimum amount of memory:
+	 */
+	if (end && (end - start) < NODE_MIN_SIZE)
+		return;
+
+	/* initialize remap allocator before aligning to ZONE_ALIGN */
+	init_alloc_remap(nid, start, end);
+
+	start = roundup(start, ZONE_ALIGN);
+
+	printk(KERN_INFO "Initmem setup node %d %016Lx-%016Lx\n",
+	       nid, start, end);
+
+	/*
+	 * Allocate node data.  Try remap allocator first, node-local
+	 * memory and then any node.  Never allocate in DMA zone.
+	 */
+	nd = alloc_remap(nid, nd_size);
+	if (nd) {
+		nd_pa = __pa(nd);
+		remapped = true;
+	} else {
+		nd_pa = memblock_x86_find_in_range_node(nid, nd_low, nd_high,
+						nd_size, SMP_CACHE_BYTES);
+		if (nd_pa == MEMBLOCK_ERROR)
+			nd_pa = memblock_find_in_range(nd_low, nd_high,
+						nd_size, SMP_CACHE_BYTES);
+		if (nd_pa == MEMBLOCK_ERROR) {
+			pr_err("Cannot find %zu bytes in node %d\n",
+			       nd_size, nid);
+			return;
+		}
+		memblock_x86_reserve_range(nd_pa, nd_pa + nd_size, "NODE_DATA");
+		nd = __va(nd_pa);
+	}
+
+	/* report and initialize */
+	printk(KERN_INFO "  NODE_DATA [%016Lx - %016Lx]%s\n",
+	       nd_pa, nd_pa + nd_size - 1, remapped ? " (remapped)" : "");
+	tnid = early_pfn_to_nid(nd_pa >> PAGE_SHIFT);
+	if (!remapped && tnid != nid)
+		printk(KERN_INFO "    NODE_DATA(%d) on node %d\n", nid, tnid);
+
+	node_data[nid] = nd;
+	memset(NODE_DATA(nid), 0, sizeof(pg_data_t));
+	NODE_DATA(nid)->node_id = nid;
+	NODE_DATA(nid)->node_start_pfn = start >> PAGE_SHIFT;
+	NODE_DATA(nid)->node_spanned_pages = (end - start) >> PAGE_SHIFT;
+
+	node_set_online(nid);
+}
+
+/**
+ * numa_cleanup_meminfo - Cleanup a numa_meminfo
+ * @mi: numa_meminfo to clean up
+ *
+ * Sanitize @mi by merging and removing unncessary memblks.  Also check for
+ * conflicts and clear unused memblks.
+ *
+ * RETURNS:
+ * 0 on success, -errno on failure.
+ */
+int __init numa_cleanup_meminfo(struct numa_meminfo *mi)
+{
+	const u64 low = 0;
+	const u64 high = PFN_PHYS(max_pfn);
+	int i, j, k;
+
+	/* first, trim all entries */
+	for (i = 0; i < mi->nr_blks; i++) {
+		struct numa_memblk *bi = &mi->blk[i];
+
+		/* make sure all blocks are inside the limits */
+		bi->start = max(bi->start, low);
+		bi->end = min(bi->end, high);
+
+		/* and there's no empty block */
+		if (bi->start >= bi->end)
+			numa_remove_memblk_from(i--, mi);
+	}
+
+	/* merge neighboring / overlapping entries */
+	for (i = 0; i < mi->nr_blks; i++) {
+		struct numa_memblk *bi = &mi->blk[i];
+
+		for (j = i + 1; j < mi->nr_blks; j++) {
+			struct numa_memblk *bj = &mi->blk[j];
+			u64 start, end;
+
+			/*
+			 * See whether there are overlapping blocks.  Whine
+			 * about but allow overlaps of the same nid.  They
+			 * will be merged below.
+			 */
+			if (bi->end > bj->start && bi->start < bj->end) {
+				if (bi->nid != bj->nid) {
+					pr_err("NUMA: node %d (%Lx-%Lx) overlaps with node %d (%Lx-%Lx)\n",
+					       bi->nid, bi->start, bi->end,
+					       bj->nid, bj->start, bj->end);
+					return -EINVAL;
+				}
+				pr_warning("NUMA: Warning: node %d (%Lx-%Lx) overlaps with itself (%Lx-%Lx)\n",
+					   bi->nid, bi->start, bi->end,
+					   bj->start, bj->end);
+			}
+
+			/*
+			 * Join together blocks on the same node, holes
+			 * between which don't overlap with memory on other
+			 * nodes.
+			 */
+			if (bi->nid != bj->nid)
+				continue;
+			start = min(bi->start, bj->start);
+			end = max(bi->end, bj->end);
+			for (k = 0; k < mi->nr_blks; k++) {
+				struct numa_memblk *bk = &mi->blk[k];
+
+				if (bi->nid == bk->nid)
+					continue;
+				if (start < bk->end && end > bk->start)
+					break;
+			}
+			if (k < mi->nr_blks)
+				continue;
+			printk(KERN_INFO "NUMA: Node %d [%Lx,%Lx) + [%Lx,%Lx) -> [%Lx,%Lx)\n",
+			       bi->nid, bi->start, bi->end, bj->start, bj->end,
+			       start, end);
+			bi->start = start;
+			bi->end = end;
+			numa_remove_memblk_from(j--, mi);
+		}
+	}
+
+	/* clear unused ones */
+	for (i = mi->nr_blks; i < ARRAY_SIZE(mi->blk); i++) {
+		mi->blk[i].start = mi->blk[i].end = 0;
+		mi->blk[i].nid = NUMA_NO_NODE;
+	}
+
+	return 0;
+}
+
+/*
+ * Set nodes, which have memory in @mi, in *@nodemask.
+ */
+static void __init numa_nodemask_from_meminfo(nodemask_t *nodemask,
+					      const struct numa_meminfo *mi)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(mi->blk); i++)
+		if (mi->blk[i].start != mi->blk[i].end &&
+		    mi->blk[i].nid != NUMA_NO_NODE)
+			node_set(mi->blk[i].nid, *nodemask);
+}
+
+/**
+ * numa_reset_distance - Reset NUMA distance table
+ *
+ * The current table is freed.  The next numa_set_distance() call will
+ * create a new one.
+ */
+void __init numa_reset_distance(void)
+{
+	size_t size = numa_distance_cnt * numa_distance_cnt * sizeof(numa_distance[0]);
+
+	/* numa_distance could be 1LU marking allocation failure, test cnt */
+	if (numa_distance_cnt)
+		memblock_x86_free_range(__pa(numa_distance),
+					__pa(numa_distance) + size);
+	numa_distance_cnt = 0;
+	numa_distance = NULL;	/* enable table creation */
+}
+
+static int __init numa_alloc_distance(void)
+{
+	nodemask_t nodes_parsed;
+	size_t size;
+	int i, j, cnt = 0;
+	u64 phys;
+
+	/* size the new table and allocate it */
+	nodes_parsed = numa_nodes_parsed;
+	numa_nodemask_from_meminfo(&nodes_parsed, &numa_meminfo);
+
+	for_each_node_mask(i, nodes_parsed)
+		cnt = i;
+	cnt++;
+	size = cnt * cnt * sizeof(numa_distance[0]);
+
+	phys = memblock_find_in_range(0, PFN_PHYS(max_pfn_mapped),
+				      size, PAGE_SIZE);
+	if (phys == MEMBLOCK_ERROR) {
+		pr_warning("NUMA: Warning: can't allocate distance table!\n");
+		/* don't retry until explicitly reset */
+		numa_distance = (void *)1LU;
+		return -ENOMEM;
+	}
+	memblock_x86_reserve_range(phys, phys + size, "NUMA DIST");
+
+	numa_distance = __va(phys);
+	numa_distance_cnt = cnt;
+
+	/* fill with the default distances */
+	for (i = 0; i < cnt; i++)
+		for (j = 0; j < cnt; j++)
+			numa_distance[i * cnt + j] = i == j ?
+				LOCAL_DISTANCE : REMOTE_DISTANCE;
+	printk(KERN_DEBUG "NUMA: Initialized distance table, cnt=%d\n", cnt);
+
+	return 0;
+}
+
+/**
+ * numa_set_distance - Set NUMA distance from one NUMA to another
+ * @from: the 'from' node to set distance
+ * @to: the 'to'  node to set distance
+ * @distance: NUMA distance
+ *
+ * Set the distance from node @from to @to to @distance.  If distance table
+ * doesn't exist, one which is large enough to accommodate all the currently
+ * known nodes will be created.
+ *
+ * If such table cannot be allocated, a warning is printed and further
+ * calls are ignored until the distance table is reset with
+ * numa_reset_distance().
+ *
+ * If @from or @to is higher than the highest known node at the time of
+ * table creation or @distance doesn't make sense, the call is ignored.
+ * This is to allow simplification of specific NUMA config implementations.
+ */
+void __init numa_set_distance(int from, int to, int distance)
+{
+	if (!numa_distance && numa_alloc_distance() < 0)
+		return;
+
+	if (from >= numa_distance_cnt || to >= numa_distance_cnt) {
+		printk_once(KERN_DEBUG "NUMA: Debug: distance out of bound, from=%d to=%d distance=%d\n",
+			    from, to, distance);
+		return;
+	}
+
+	if ((u8)distance != distance ||
+	    (from == to && distance != LOCAL_DISTANCE)) {
+		pr_warn_once("NUMA: Warning: invalid distance parameter, from=%d to=%d distance=%d\n",
+			     from, to, distance);
+		return;
+	}
+
+	numa_distance[from * numa_distance_cnt + to] = distance;
+}
+
+int __node_distance(int from, int to)
+{
+	if (from >= numa_distance_cnt || to >= numa_distance_cnt)
+		return from == to ? LOCAL_DISTANCE : REMOTE_DISTANCE;
+	return numa_distance[from * numa_distance_cnt + to];
+}
+EXPORT_SYMBOL(__node_distance);
+
+/*
+ * Sanity check to catch more bad NUMA configurations (they are amazingly
+ * common).  Make sure the nodes cover all memory.
+ */
+static bool __init numa_meminfo_cover_memory(const struct numa_meminfo *mi)
+{
+	u64 numaram, e820ram;
+	int i;
+
+	numaram = 0;
+	for (i = 0; i < mi->nr_blks; i++) {
+		u64 s = mi->blk[i].start >> PAGE_SHIFT;
+		u64 e = mi->blk[i].end >> PAGE_SHIFT;
+		numaram += e - s;
+		numaram -= __absent_pages_in_range(mi->blk[i].nid, s, e);
+		if ((s64)numaram < 0)
+			numaram = 0;
+	}
+
+	e820ram = max_pfn - (memblock_x86_hole_size(0,
+					PFN_PHYS(max_pfn)) >> PAGE_SHIFT);
+	/* We seem to lose 3 pages somewhere. Allow 1M of slack. */
+	if ((s64)(e820ram - numaram) >= (1 << (20 - PAGE_SHIFT))) {
+		printk(KERN_ERR "NUMA: nodes only cover %LuMB of your %LuMB e820 RAM. Not used.\n",
+		       (numaram << PAGE_SHIFT) >> 20,
+		       (e820ram << PAGE_SHIFT) >> 20);
+		return false;
+	}
+	return true;
+}
+
+static int __init numa_register_memblks(struct numa_meminfo *mi)
+{
+	int i, nid;
+
+	/* Account for nodes with cpus and no memory */
+	node_possible_map = numa_nodes_parsed;
+	numa_nodemask_from_meminfo(&node_possible_map, mi);
+	if (WARN_ON(nodes_empty(node_possible_map)))
+		return -EINVAL;
+
+	for (i = 0; i < mi->nr_blks; i++)
+		memblock_x86_register_active_regions(mi->blk[i].nid,
+					mi->blk[i].start >> PAGE_SHIFT,
+					mi->blk[i].end >> PAGE_SHIFT);
+
+	/* for out of order entries */
+	sort_node_map();
+	if (!numa_meminfo_cover_memory(mi))
+		return -EINVAL;
+
+	/* Finally register nodes. */
+	for_each_node_mask(nid, node_possible_map) {
+		u64 start = PFN_PHYS(max_pfn);
+		u64 end = 0;
+
+		for (i = 0; i < mi->nr_blks; i++) {
+			if (nid != mi->blk[i].nid)
+				continue;
+			start = min(mi->blk[i].start, start);
+			end = max(mi->blk[i].end, end);
+		}
+
+		if (start < end)
+			setup_node_data(nid, start, end);
+	}
+
+	return 0;
+}
+
 /*
  * There are unfortunately some poorly designed mainboards around that
  * only connect memory to a single CPU. This breaks the 1:1 cpu->node
@@ -102,7 +540,7 @@
  * as the number of CPUs is not known yet. We round robin the existing
  * nodes.
  */
-void __init numa_init_array(void)
+static void __init numa_init_array(void)
 {
 	int rr, i;
 
@@ -117,6 +555,95 @@
 	}
 }
 
+static int __init numa_init(int (*init_func)(void))
+{
+	int i;
+	int ret;
+
+	for (i = 0; i < MAX_LOCAL_APIC; i++)
+		set_apicid_to_node(i, NUMA_NO_NODE);
+
+	nodes_clear(numa_nodes_parsed);
+	nodes_clear(node_possible_map);
+	nodes_clear(node_online_map);
+	memset(&numa_meminfo, 0, sizeof(numa_meminfo));
+	remove_all_active_ranges();
+	numa_reset_distance();
+
+	ret = init_func();
+	if (ret < 0)
+		return ret;
+	ret = numa_cleanup_meminfo(&numa_meminfo);
+	if (ret < 0)
+		return ret;
+
+	numa_emulation(&numa_meminfo, numa_distance_cnt);
+
+	ret = numa_register_memblks(&numa_meminfo);
+	if (ret < 0)
+		return ret;
+
+	for (i = 0; i < nr_cpu_ids; i++) {
+		int nid = early_cpu_to_node(i);
+
+		if (nid == NUMA_NO_NODE)
+			continue;
+		if (!node_online(nid))
+			numa_clear_node(i);
+	}
+	numa_init_array();
+	return 0;
+}
+
+/**
+ * dummy_numa_init - Fallback dummy NUMA init
+ *
+ * Used if there's no underlying NUMA architecture, NUMA initialization
+ * fails, or NUMA is disabled on the command line.
+ *
+ * Must online at least one node and add memory blocks that cover all
+ * allowed memory.  This function must not fail.
+ */
+static int __init dummy_numa_init(void)
+{
+	printk(KERN_INFO "%s\n",
+	       numa_off ? "NUMA turned off" : "No NUMA configuration found");
+	printk(KERN_INFO "Faking a node at %016Lx-%016Lx\n",
+	       0LLU, PFN_PHYS(max_pfn));
+
+	node_set(0, numa_nodes_parsed);
+	numa_add_memblk(0, 0, PFN_PHYS(max_pfn));
+
+	return 0;
+}
+
+/**
+ * x86_numa_init - Initialize NUMA
+ *
+ * Try each configured NUMA initialization method until one succeeds.  The
+ * last fallback is dummy single node config encomapssing whole memory and
+ * never fails.
+ */
+void __init x86_numa_init(void)
+{
+	if (!numa_off) {
+#ifdef CONFIG_X86_NUMAQ
+		if (!numa_init(numaq_numa_init))
+			return;
+#endif
+#ifdef CONFIG_ACPI_NUMA
+		if (!numa_init(x86_acpi_numa_init))
+			return;
+#endif
+#ifdef CONFIG_AMD_NUMA
+		if (!numa_init(amd_numa_init))
+			return;
+#endif
+	}
+
+	numa_init(dummy_numa_init);
+}
+
 static __init int find_near_online_node(int node)
 {
 	int n, val;
@@ -282,3 +809,18 @@
 EXPORT_SYMBOL(cpumask_of_node);
 
 #endif	/* !CONFIG_DEBUG_PER_CPU_MAPS */
+
+#ifdef CONFIG_MEMORY_HOTPLUG
+int memory_add_physaddr_to_nid(u64 start)
+{
+	struct numa_meminfo *mi = &numa_meminfo;
+	int nid = mi->blk[0].nid;
+	int i;
+
+	for (i = 0; i < mi->nr_blks; i++)
+		if (mi->blk[i].start <= start && mi->blk[i].end > start)
+			nid = mi->blk[i].nid;
+	return nid;
+}
+EXPORT_SYMBOL_GPL(memory_add_physaddr_to_nid);
+#endif
diff -druN linux-2.6.39-libre/arch/x86/mm/numa_emulation.c linux-3.0-rc7-libre/arch/x86/mm/numa_emulation.c
--- linux-2.6.39-libre/arch/x86/mm/numa_emulation.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/mm/numa_emulation.c	2011-07-11 19:51:52.000000000 -0400
@@ -5,6 +5,7 @@
 #include <linux/errno.h>
 #include <linux/topology.h>
 #include <linux/memblock.h>
+#include <linux/bootmem.h>
 #include <asm/dma.h>
 
 #include "numa_internal.h"
@@ -84,7 +85,13 @@
 		nr_nodes = MAX_NUMNODES;
 	}
 
-	size = (max_addr - addr - memblock_x86_hole_size(addr, max_addr)) / nr_nodes;
+	/*
+	 * Calculate target node size.  x86_32 freaks on __udivdi3() so do
+	 * the division in ulong number of pages and convert back.
+	 */
+	size = max_addr - addr - memblock_x86_hole_size(addr, max_addr);
+	size = PFN_PHYS((unsigned long)(size >> PAGE_SHIFT) / nr_nodes);
+
 	/*
 	 * Calculate the number of big nodes that can be allocated as a result
 	 * of consolidating the remainder.
@@ -226,7 +233,7 @@
 	 */
 	while (nodes_weight(physnode_mask)) {
 		for_each_node_mask(i, physnode_mask) {
-			u64 dma32_end = MAX_DMA32_PFN << PAGE_SHIFT;
+			u64 dma32_end = PFN_PHYS(MAX_DMA32_PFN);
 			u64 start, limit, end;
 			int phys_blk;
 
@@ -298,7 +305,7 @@
 {
 	static struct numa_meminfo ei __initdata;
 	static struct numa_meminfo pi __initdata;
-	const u64 max_addr = max_pfn << PAGE_SHIFT;
+	const u64 max_addr = PFN_PHYS(max_pfn);
 	u8 *phys_dist = NULL;
 	size_t phys_size = numa_dist_cnt * numa_dist_cnt * sizeof(phys_dist[0]);
 	int max_emu_nid, dfl_phys_nid;
@@ -342,8 +349,7 @@
 	if (numa_dist_cnt) {
 		u64 phys;
 
-		phys = memblock_find_in_range(0,
-					      (u64)max_pfn_mapped << PAGE_SHIFT,
+		phys = memblock_find_in_range(0, PFN_PHYS(max_pfn_mapped),
 					      phys_size, PAGE_SIZE);
 		if (phys == MEMBLOCK_ERROR) {
 			pr_warning("NUMA: Warning: can't allocate copy of distance table, disabling emulation\n");
diff -druN linux-2.6.39-libre/arch/x86/mm/numa_internal.h linux-3.0-rc7-libre/arch/x86/mm/numa_internal.h
--- linux-2.6.39-libre/arch/x86/mm/numa_internal.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/mm/numa_internal.h	2011-07-11 19:51:52.000000000 -0400
@@ -19,6 +19,14 @@
 int __init numa_cleanup_meminfo(struct numa_meminfo *mi);
 void __init numa_reset_distance(void);
 
+void __init x86_numa_init(void);
+
+#ifdef CONFIG_X86_64
+static inline void init_alloc_remap(int nid, u64 start, u64 end)	{ }
+#else
+void __init init_alloc_remap(int nid, u64 start, u64 end);
+#endif
+
 #ifdef CONFIG_NUMA_EMU
 void __init numa_emulation(struct numa_meminfo *numa_meminfo,
 			   int numa_dist_cnt);
diff -druN linux-2.6.39-libre/arch/x86/mm/pf_in.c linux-3.0-rc7-libre/arch/x86/mm/pf_in.c
--- linux-2.6.39-libre/arch/x86/mm/pf_in.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/mm/pf_in.c	2011-07-11 19:51:52.000000000 -0400
@@ -414,22 +414,17 @@
 	unsigned char *p;
 	struct prefix_bits prf;
 	int i;
-	unsigned long rv;
 
 	p = (unsigned char *)ins_addr;
 	p += skip_prefix(p, &prf);
 	p += get_opcode(p, &opcode);
 	for (i = 0; i < ARRAY_SIZE(reg_rop); i++)
-		if (reg_rop[i] == opcode) {
-			rv = REG_READ;
+		if (reg_rop[i] == opcode)
 			goto do_work;
-		}
 
 	for (i = 0; i < ARRAY_SIZE(reg_wop); i++)
-		if (reg_wop[i] == opcode) {
-			rv = REG_WRITE;
+		if (reg_wop[i] == opcode)
 			goto do_work;
-		}
 
 	printk(KERN_ERR "mmiotrace: Not a register instruction, opcode "
 							"0x%02x\n", opcode);
@@ -474,16 +469,13 @@
 	unsigned char *p;
 	struct prefix_bits prf;
 	int i;
-	unsigned long rv;
 
 	p = (unsigned char *)ins_addr;
 	p += skip_prefix(p, &prf);
 	p += get_opcode(p, &opcode);
 	for (i = 0; i < ARRAY_SIZE(imm_wop); i++)
-		if (imm_wop[i] == opcode) {
-			rv = IMM_WRITE;
+		if (imm_wop[i] == opcode)
 			goto do_work;
-		}
 
 	printk(KERN_ERR "mmiotrace: Not an immediate instruction, opcode "
 							"0x%02x\n", opcode);
diff -druN linux-2.6.39-libre/arch/x86/mm/srat_32.c linux-3.0-rc7-libre/arch/x86/mm/srat_32.c
--- linux-2.6.39-libre/arch/x86/mm/srat_32.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/mm/srat_32.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,288 +0,0 @@
-/*
- * Some of the code in this file has been gleaned from the 64 bit 
- * discontigmem support code base.
- *
- * Copyright (C) 2002, IBM Corp.
- *
- * All rights reserved.          
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
- * NON INFRINGEMENT.  See the GNU General Public License for more
- * details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * Send feedback to Pat Gaughen <gone@us.ibm.com>
- */
-#include <linux/mm.h>
-#include <linux/bootmem.h>
-#include <linux/memblock.h>
-#include <linux/mmzone.h>
-#include <linux/acpi.h>
-#include <linux/nodemask.h>
-#include <asm/srat.h>
-#include <asm/topology.h>
-#include <asm/smp.h>
-#include <asm/e820.h>
-
-/*
- * proximity macros and definitions
- */
-#define NODE_ARRAY_INDEX(x)	((x) / 8)	/* 8 bits/char */
-#define NODE_ARRAY_OFFSET(x)	((x) % 8)	/* 8 bits/char */
-#define BMAP_SET(bmap, bit)	((bmap)[NODE_ARRAY_INDEX(bit)] |= 1 << NODE_ARRAY_OFFSET(bit))
-#define BMAP_TEST(bmap, bit)	((bmap)[NODE_ARRAY_INDEX(bit)] & (1 << NODE_ARRAY_OFFSET(bit)))
-/* bitmap length; _PXM is at most 255 */
-#define PXM_BITMAP_LEN (MAX_PXM_DOMAINS / 8) 
-static u8 __initdata pxm_bitmap[PXM_BITMAP_LEN];	/* bitmap of proximity domains */
-
-#define MAX_CHUNKS_PER_NODE	3
-#define MAXCHUNKS		(MAX_CHUNKS_PER_NODE * MAX_NUMNODES)
-struct node_memory_chunk_s {
-	unsigned long	start_pfn;
-	unsigned long	end_pfn;
-	u8	pxm;		// proximity domain of node
-	u8	nid;		// which cnode contains this chunk?
-	u8	bank;		// which mem bank on this node
-};
-static struct node_memory_chunk_s __initdata node_memory_chunk[MAXCHUNKS];
-
-static int __initdata num_memory_chunks; /* total number of memory chunks */
-static u8 __initdata apicid_to_pxm[MAX_LOCAL_APIC];
-
-int acpi_numa __initdata;
-
-static __init void bad_srat(void)
-{
-        printk(KERN_ERR "SRAT: SRAT not used.\n");
-        acpi_numa = -1;
-	num_memory_chunks = 0;
-}
-
-static __init inline int srat_disabled(void)
-{
-	return numa_off || acpi_numa < 0;
-}
-
-/* Identify CPU proximity domains */
-void __init
-acpi_numa_processor_affinity_init(struct acpi_srat_cpu_affinity *cpu_affinity)
-{
-	if (srat_disabled())
-		return;
-	if (cpu_affinity->header.length !=
-	     sizeof(struct acpi_srat_cpu_affinity)) {
-		bad_srat();
-		return;
-	}
-
-	if ((cpu_affinity->flags & ACPI_SRAT_CPU_ENABLED) == 0)
-		return;		/* empty entry */
-
-	/* mark this node as "seen" in node bitmap */
-	BMAP_SET(pxm_bitmap, cpu_affinity->proximity_domain_lo);
-
-	/* don't need to check apic_id here, because it is always 8 bits */
-	apicid_to_pxm[cpu_affinity->apic_id] = cpu_affinity->proximity_domain_lo;
-
-	printk(KERN_DEBUG "CPU %02x in proximity domain %02x\n",
-		cpu_affinity->apic_id, cpu_affinity->proximity_domain_lo);
-}
-
-/*
- * Identify memory proximity domains and hot-remove capabilities.
- * Fill node memory chunk list structure.
- */
-void __init
-acpi_numa_memory_affinity_init(struct acpi_srat_mem_affinity *memory_affinity)
-{
-	unsigned long long paddr, size;
-	unsigned long start_pfn, end_pfn;
-	u8 pxm;
-	struct node_memory_chunk_s *p, *q, *pend;
-
-	if (srat_disabled())
-		return;
-	if (memory_affinity->header.length !=
-	     sizeof(struct acpi_srat_mem_affinity)) {
-		bad_srat();
-		return;
-	}
-
-	if ((memory_affinity->flags & ACPI_SRAT_MEM_ENABLED) == 0)
-		return;		/* empty entry */
-
-	pxm = memory_affinity->proximity_domain & 0xff;
-
-	/* mark this node as "seen" in node bitmap */
-	BMAP_SET(pxm_bitmap, pxm);
-
-	/* calculate info for memory chunk structure */
-	paddr = memory_affinity->base_address;
-	size = memory_affinity->length;
-
-	start_pfn = paddr >> PAGE_SHIFT;
-	end_pfn = (paddr + size) >> PAGE_SHIFT;
-
-
-	if (num_memory_chunks >= MAXCHUNKS) {
-		printk(KERN_WARNING "Too many mem chunks in SRAT."
-			" Ignoring %lld MBytes at %llx\n",
-			size/(1024*1024), paddr);
-		return;
-	}
-
-	/* Insertion sort based on base address */
-	pend = &node_memory_chunk[num_memory_chunks];
-	for (p = &node_memory_chunk[0]; p < pend; p++) {
-		if (start_pfn < p->start_pfn)
-			break;
-	}
-	if (p < pend) {
-		for (q = pend; q >= p; q--)
-			*(q + 1) = *q;
-	}
-	p->start_pfn = start_pfn;
-	p->end_pfn = end_pfn;
-	p->pxm = pxm;
-
-	num_memory_chunks++;
-
-	printk(KERN_DEBUG "Memory range %08lx to %08lx"
-			  " in proximity domain %02x %s\n",
-		start_pfn, end_pfn,
-		pxm,
-		((memory_affinity->flags & ACPI_SRAT_MEM_HOT_PLUGGABLE) ?
-		 "enabled and removable" : "enabled" ) );
-}
-
-/* Callback for SLIT parsing */
-void __init acpi_numa_slit_init(struct acpi_table_slit *slit)
-{
-}
-
-void acpi_numa_arch_fixup(void)
-{
-}
-/*
- * The SRAT table always lists ascending addresses, so can always
- * assume that the first "start" address that you see is the real
- * start of the node, and that the current "end" address is after
- * the previous one.
- */
-static __init int node_read_chunk(int nid, struct node_memory_chunk_s *memory_chunk)
-{
-	/*
-	 * Only add present memory as told by the e820.
-	 * There is no guarantee from the SRAT that the memory it
-	 * enumerates is present at boot time because it represents
-	 * *possible* memory hotplug areas the same as normal RAM.
-	 */
-	if (memory_chunk->start_pfn >= max_pfn) {
-		printk(KERN_INFO "Ignoring SRAT pfns: %08lx - %08lx\n",
-			memory_chunk->start_pfn, memory_chunk->end_pfn);
-		return -1;
-	}
-	if (memory_chunk->nid != nid)
-		return -1;
-
-	if (!node_has_online_mem(nid))
-		node_start_pfn[nid] = memory_chunk->start_pfn;
-
-	if (node_start_pfn[nid] > memory_chunk->start_pfn)
-		node_start_pfn[nid] = memory_chunk->start_pfn;
-
-	if (node_end_pfn[nid] < memory_chunk->end_pfn)
-		node_end_pfn[nid] = memory_chunk->end_pfn;
-
-	return 0;
-}
-
-int __init get_memcfg_from_srat(void)
-{
-	int i, j, nid;
-
-	if (srat_disabled())
-		goto out_fail;
-
-	if (acpi_numa_init() < 0)
-		goto out_fail;
-
-	if (num_memory_chunks == 0) {
-		printk(KERN_DEBUG
-			 "could not find any ACPI SRAT memory areas.\n");
-		goto out_fail;
-	}
-
-	/* Calculate total number of nodes in system from PXM bitmap and create
-	 * a set of sequential node IDs starting at zero.  (ACPI doesn't seem
-	 * to specify the range of _PXM values.)
-	 */
-	/*
-	 * MCD - we no longer HAVE to number nodes sequentially.  PXM domain
-	 * numbers could go as high as 256, and MAX_NUMNODES for i386 is typically
-	 * 32, so we will continue numbering them in this manner until MAX_NUMNODES
-	 * approaches MAX_PXM_DOMAINS for i386.
-	 */
-	nodes_clear(node_online_map);
-	for (i = 0; i < MAX_PXM_DOMAINS; i++) {
-		if (BMAP_TEST(pxm_bitmap, i)) {
-			int nid = acpi_map_pxm_to_node(i);
-			node_set_online(nid);
-		}
-	}
-	BUG_ON(num_online_nodes() == 0);
-
-	/* set cnode id in memory chunk structure */
-	for (i = 0; i < num_memory_chunks; i++)
-		node_memory_chunk[i].nid = pxm_to_node(node_memory_chunk[i].pxm);
-
-	printk(KERN_DEBUG "pxm bitmap: ");
-	for (i = 0; i < sizeof(pxm_bitmap); i++) {
-		printk(KERN_CONT "%02x ", pxm_bitmap[i]);
-	}
-	printk(KERN_CONT "\n");
-	printk(KERN_DEBUG "Number of logical nodes in system = %d\n",
-			 num_online_nodes());
-	printk(KERN_DEBUG "Number of memory chunks in system = %d\n",
-			 num_memory_chunks);
-
-	for (i = 0; i < MAX_LOCAL_APIC; i++)
-		set_apicid_to_node(i, pxm_to_node(apicid_to_pxm[i]));
-
-	for (j = 0; j < num_memory_chunks; j++){
-		struct node_memory_chunk_s * chunk = &node_memory_chunk[j];
-		printk(KERN_DEBUG
-			"chunk %d nid %d start_pfn %08lx end_pfn %08lx\n",
-		       j, chunk->nid, chunk->start_pfn, chunk->end_pfn);
-		if (node_read_chunk(chunk->nid, chunk))
-			continue;
-
-		memblock_x86_register_active_regions(chunk->nid, chunk->start_pfn,
-					     min(chunk->end_pfn, max_pfn));
-	}
-	/* for out of order entries in SRAT */
-	sort_node_map();
-
-	for_each_online_node(nid) {
-		unsigned long start = node_start_pfn[nid];
-		unsigned long end = min(node_end_pfn[nid], max_pfn);
-
-		memory_present(nid, start, end);
-		node_remap_size[nid] = node_memmap_size_bytes(nid, start, end);
-	}
-	return 1;
-out_fail:
-	printk(KERN_DEBUG "failed to get NUMA memory information from SRAT"
-			" table\n");
-	return 0;
-}
diff -druN linux-2.6.39-libre/arch/x86/mm/srat_64.c linux-3.0-rc7-libre/arch/x86/mm/srat_64.c
--- linux-2.6.39-libre/arch/x86/mm/srat_64.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/mm/srat_64.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,260 +0,0 @@
-/*
- * ACPI 3.0 based NUMA setup
- * Copyright 2004 Andi Kleen, SuSE Labs.
- *
- * Reads the ACPI SRAT table to figure out what memory belongs to which CPUs.
- *
- * Called from acpi_numa_init while reading the SRAT and SLIT tables.
- * Assumes all memory regions belonging to a single proximity domain
- * are in one chunk. Holes between them will be included in the node.
- */
-
-#include <linux/kernel.h>
-#include <linux/acpi.h>
-#include <linux/mmzone.h>
-#include <linux/bitmap.h>
-#include <linux/module.h>
-#include <linux/topology.h>
-#include <linux/bootmem.h>
-#include <linux/memblock.h>
-#include <linux/mm.h>
-#include <asm/proto.h>
-#include <asm/numa.h>
-#include <asm/e820.h>
-#include <asm/apic.h>
-#include <asm/uv/uv.h>
-
-int acpi_numa __initdata;
-
-static struct bootnode nodes_add[MAX_NUMNODES];
-
-static __init int setup_node(int pxm)
-{
-	return acpi_map_pxm_to_node(pxm);
-}
-
-static __init void bad_srat(void)
-{
-	printk(KERN_ERR "SRAT: SRAT not used.\n");
-	acpi_numa = -1;
-	memset(nodes_add, 0, sizeof(nodes_add));
-}
-
-static __init inline int srat_disabled(void)
-{
-	return acpi_numa < 0;
-}
-
-/* Callback for SLIT parsing */
-void __init acpi_numa_slit_init(struct acpi_table_slit *slit)
-{
-	int i, j;
-
-	for (i = 0; i < slit->locality_count; i++)
-		for (j = 0; j < slit->locality_count; j++)
-			numa_set_distance(pxm_to_node(i), pxm_to_node(j),
-				slit->entry[slit->locality_count * i + j]);
-}
-
-/* Callback for Proximity Domain -> x2APIC mapping */
-void __init
-acpi_numa_x2apic_affinity_init(struct acpi_srat_x2apic_cpu_affinity *pa)
-{
-	int pxm, node;
-	int apic_id;
-
-	if (srat_disabled())
-		return;
-	if (pa->header.length < sizeof(struct acpi_srat_x2apic_cpu_affinity)) {
-		bad_srat();
-		return;
-	}
-	if ((pa->flags & ACPI_SRAT_CPU_ENABLED) == 0)
-		return;
-	pxm = pa->proximity_domain;
-	node = setup_node(pxm);
-	if (node < 0) {
-		printk(KERN_ERR "SRAT: Too many proximity domains %x\n", pxm);
-		bad_srat();
-		return;
-	}
-
-	apic_id = pa->apic_id;
-	if (apic_id >= MAX_LOCAL_APIC) {
-		printk(KERN_INFO "SRAT: PXM %u -> APIC 0x%04x -> Node %u skipped apicid that is too big\n", pxm, apic_id, node);
-		return;
-	}
-	set_apicid_to_node(apic_id, node);
-	node_set(node, numa_nodes_parsed);
-	acpi_numa = 1;
-	printk(KERN_INFO "SRAT: PXM %u -> APIC 0x%04x -> Node %u\n",
-	       pxm, apic_id, node);
-}
-
-/* Callback for Proximity Domain -> LAPIC mapping */
-void __init
-acpi_numa_processor_affinity_init(struct acpi_srat_cpu_affinity *pa)
-{
-	int pxm, node;
-	int apic_id;
-
-	if (srat_disabled())
-		return;
-	if (pa->header.length != sizeof(struct acpi_srat_cpu_affinity)) {
-		bad_srat();
-		return;
-	}
-	if ((pa->flags & ACPI_SRAT_CPU_ENABLED) == 0)
-		return;
-	pxm = pa->proximity_domain_lo;
-	node = setup_node(pxm);
-	if (node < 0) {
-		printk(KERN_ERR "SRAT: Too many proximity domains %x\n", pxm);
-		bad_srat();
-		return;
-	}
-
-	if (get_uv_system_type() >= UV_X2APIC)
-		apic_id = (pa->apic_id << 8) | pa->local_sapic_eid;
-	else
-		apic_id = pa->apic_id;
-
-	if (apic_id >= MAX_LOCAL_APIC) {
-		printk(KERN_INFO "SRAT: PXM %u -> APIC 0x%02x -> Node %u skipped apicid that is too big\n", pxm, apic_id, node);
-		return;
-	}
-
-	set_apicid_to_node(apic_id, node);
-	node_set(node, numa_nodes_parsed);
-	acpi_numa = 1;
-	printk(KERN_INFO "SRAT: PXM %u -> APIC 0x%02x -> Node %u\n",
-	       pxm, apic_id, node);
-}
-
-#ifdef CONFIG_MEMORY_HOTPLUG_SPARSE
-static inline int save_add_info(void) {return 1;}
-#else
-static inline int save_add_info(void) {return 0;}
-#endif
-/*
- * Update nodes_add[]
- * This code supports one contiguous hot add area per node
- */
-static void __init
-update_nodes_add(int node, unsigned long start, unsigned long end)
-{
-	unsigned long s_pfn = start >> PAGE_SHIFT;
-	unsigned long e_pfn = end >> PAGE_SHIFT;
-	int changed = 0;
-	struct bootnode *nd = &nodes_add[node];
-
-	/* I had some trouble with strange memory hotadd regions breaking
-	   the boot. Be very strict here and reject anything unexpected.
-	   If you want working memory hotadd write correct SRATs.
-
-	   The node size check is a basic sanity check to guard against
-	   mistakes */
-	if ((signed long)(end - start) < NODE_MIN_SIZE) {
-		printk(KERN_ERR "SRAT: Hotplug area too small\n");
-		return;
-	}
-
-	/* This check might be a bit too strict, but I'm keeping it for now. */
-	if (absent_pages_in_range(s_pfn, e_pfn) != e_pfn - s_pfn) {
-		printk(KERN_ERR
-			"SRAT: Hotplug area %lu -> %lu has existing memory\n",
-			s_pfn, e_pfn);
-		return;
-	}
-
-	/* Looks good */
-
-	if (nd->start == nd->end) {
-		nd->start = start;
-		nd->end = end;
-		changed = 1;
-	} else {
-		if (nd->start == end) {
-			nd->start = start;
-			changed = 1;
-		}
-		if (nd->end == start) {
-			nd->end = end;
-			changed = 1;
-		}
-		if (!changed)
-			printk(KERN_ERR "SRAT: Hotplug zone not continuous. Partly ignored\n");
-	}
-
-	if (changed) {
-		node_set(node, numa_nodes_parsed);
-		printk(KERN_INFO "SRAT: hot plug zone found %Lx - %Lx\n",
-				 nd->start, nd->end);
-	}
-}
-
-/* Callback for parsing of the Proximity Domain <-> Memory Area mappings */
-void __init
-acpi_numa_memory_affinity_init(struct acpi_srat_mem_affinity *ma)
-{
-	unsigned long start, end;
-	int node, pxm;
-
-	if (srat_disabled())
-		return;
-	if (ma->header.length != sizeof(struct acpi_srat_mem_affinity)) {
-		bad_srat();
-		return;
-	}
-	if ((ma->flags & ACPI_SRAT_MEM_ENABLED) == 0)
-		return;
-
-	if ((ma->flags & ACPI_SRAT_MEM_HOT_PLUGGABLE) && !save_add_info())
-		return;
-	start = ma->base_address;
-	end = start + ma->length;
-	pxm = ma->proximity_domain;
-	node = setup_node(pxm);
-	if (node < 0) {
-		printk(KERN_ERR "SRAT: Too many proximity domains.\n");
-		bad_srat();
-		return;
-	}
-
-	if (numa_add_memblk(node, start, end) < 0) {
-		bad_srat();
-		return;
-	}
-
-	printk(KERN_INFO "SRAT: Node %u PXM %u %lx-%lx\n", node, pxm,
-	       start, end);
-
-	if (ma->flags & ACPI_SRAT_MEM_HOT_PLUGGABLE)
-		update_nodes_add(node, start, end);
-}
-
-void __init acpi_numa_arch_fixup(void) {}
-
-int __init x86_acpi_numa_init(void)
-{
-	int ret;
-
-	ret = acpi_numa_init();
-	if (ret < 0)
-		return ret;
-	return srat_disabled() ? -EINVAL : 0;
-}
-
-#if defined(CONFIG_MEMORY_HOTPLUG_SPARSE) || defined(CONFIG_ACPI_HOTPLUG_MEMORY)
-int memory_add_physaddr_to_nid(u64 start)
-{
-	int i, ret = 0;
-
-	for_each_node(i)
-		if (nodes_add[i].start <= start && nodes_add[i].end > start)
-			ret = i;
-
-	return ret;
-}
-EXPORT_SYMBOL_GPL(memory_add_physaddr_to_nid);
-#endif
diff -druN linux-2.6.39-libre/arch/x86/mm/srat.c linux-3.0-rc7-libre/arch/x86/mm/srat.c
--- linux-2.6.39-libre/arch/x86/mm/srat.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/x86/mm/srat.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,184 @@
+/*
+ * ACPI 3.0 based NUMA setup
+ * Copyright 2004 Andi Kleen, SuSE Labs.
+ *
+ * Reads the ACPI SRAT table to figure out what memory belongs to which CPUs.
+ *
+ * Called from acpi_numa_init while reading the SRAT and SLIT tables.
+ * Assumes all memory regions belonging to a single proximity domain
+ * are in one chunk. Holes between them will be included in the node.
+ */
+
+#include <linux/kernel.h>
+#include <linux/acpi.h>
+#include <linux/mmzone.h>
+#include <linux/bitmap.h>
+#include <linux/module.h>
+#include <linux/topology.h>
+#include <linux/bootmem.h>
+#include <linux/memblock.h>
+#include <linux/mm.h>
+#include <asm/proto.h>
+#include <asm/numa.h>
+#include <asm/e820.h>
+#include <asm/apic.h>
+#include <asm/uv/uv.h>
+
+int acpi_numa __initdata;
+
+static __init int setup_node(int pxm)
+{
+	return acpi_map_pxm_to_node(pxm);
+}
+
+static __init void bad_srat(void)
+{
+	printk(KERN_ERR "SRAT: SRAT not used.\n");
+	acpi_numa = -1;
+}
+
+static __init inline int srat_disabled(void)
+{
+	return acpi_numa < 0;
+}
+
+/* Callback for SLIT parsing */
+void __init acpi_numa_slit_init(struct acpi_table_slit *slit)
+{
+	int i, j;
+
+	for (i = 0; i < slit->locality_count; i++)
+		for (j = 0; j < slit->locality_count; j++)
+			numa_set_distance(pxm_to_node(i), pxm_to_node(j),
+				slit->entry[slit->locality_count * i + j]);
+}
+
+/* Callback for Proximity Domain -> x2APIC mapping */
+void __init
+acpi_numa_x2apic_affinity_init(struct acpi_srat_x2apic_cpu_affinity *pa)
+{
+	int pxm, node;
+	int apic_id;
+
+	if (srat_disabled())
+		return;
+	if (pa->header.length < sizeof(struct acpi_srat_x2apic_cpu_affinity)) {
+		bad_srat();
+		return;
+	}
+	if ((pa->flags & ACPI_SRAT_CPU_ENABLED) == 0)
+		return;
+	pxm = pa->proximity_domain;
+	node = setup_node(pxm);
+	if (node < 0) {
+		printk(KERN_ERR "SRAT: Too many proximity domains %x\n", pxm);
+		bad_srat();
+		return;
+	}
+
+	apic_id = pa->apic_id;
+	if (apic_id >= MAX_LOCAL_APIC) {
+		printk(KERN_INFO "SRAT: PXM %u -> APIC 0x%04x -> Node %u skipped apicid that is too big\n", pxm, apic_id, node);
+		return;
+	}
+	set_apicid_to_node(apic_id, node);
+	node_set(node, numa_nodes_parsed);
+	acpi_numa = 1;
+	printk(KERN_INFO "SRAT: PXM %u -> APIC 0x%04x -> Node %u\n",
+	       pxm, apic_id, node);
+}
+
+/* Callback for Proximity Domain -> LAPIC mapping */
+void __init
+acpi_numa_processor_affinity_init(struct acpi_srat_cpu_affinity *pa)
+{
+	int pxm, node;
+	int apic_id;
+
+	if (srat_disabled())
+		return;
+	if (pa->header.length != sizeof(struct acpi_srat_cpu_affinity)) {
+		bad_srat();
+		return;
+	}
+	if ((pa->flags & ACPI_SRAT_CPU_ENABLED) == 0)
+		return;
+	pxm = pa->proximity_domain_lo;
+	node = setup_node(pxm);
+	if (node < 0) {
+		printk(KERN_ERR "SRAT: Too many proximity domains %x\n", pxm);
+		bad_srat();
+		return;
+	}
+
+	if (get_uv_system_type() >= UV_X2APIC)
+		apic_id = (pa->apic_id << 8) | pa->local_sapic_eid;
+	else
+		apic_id = pa->apic_id;
+
+	if (apic_id >= MAX_LOCAL_APIC) {
+		printk(KERN_INFO "SRAT: PXM %u -> APIC 0x%02x -> Node %u skipped apicid that is too big\n", pxm, apic_id, node);
+		return;
+	}
+
+	set_apicid_to_node(apic_id, node);
+	node_set(node, numa_nodes_parsed);
+	acpi_numa = 1;
+	printk(KERN_INFO "SRAT: PXM %u -> APIC 0x%02x -> Node %u\n",
+	       pxm, apic_id, node);
+}
+
+#ifdef CONFIG_MEMORY_HOTPLUG
+static inline int save_add_info(void) {return 1;}
+#else
+static inline int save_add_info(void) {return 0;}
+#endif
+
+/* Callback for parsing of the Proximity Domain <-> Memory Area mappings */
+void __init
+acpi_numa_memory_affinity_init(struct acpi_srat_mem_affinity *ma)
+{
+	u64 start, end;
+	int node, pxm;
+
+	if (srat_disabled())
+		return;
+	if (ma->header.length != sizeof(struct acpi_srat_mem_affinity)) {
+		bad_srat();
+		return;
+	}
+	if ((ma->flags & ACPI_SRAT_MEM_ENABLED) == 0)
+		return;
+
+	if ((ma->flags & ACPI_SRAT_MEM_HOT_PLUGGABLE) && !save_add_info())
+		return;
+	start = ma->base_address;
+	end = start + ma->length;
+	pxm = ma->proximity_domain;
+	node = setup_node(pxm);
+	if (node < 0) {
+		printk(KERN_ERR "SRAT: Too many proximity domains.\n");
+		bad_srat();
+		return;
+	}
+
+	if (numa_add_memblk(node, start, end) < 0) {
+		bad_srat();
+		return;
+	}
+
+	printk(KERN_INFO "SRAT: Node %u PXM %u %Lx-%Lx\n", node, pxm,
+	       start, end);
+}
+
+void __init acpi_numa_arch_fixup(void) {}
+
+int __init x86_acpi_numa_init(void)
+{
+	int ret;
+
+	ret = acpi_numa_init();
+	if (ret < 0)
+		return ret;
+	return srat_disabled() ? -EINVAL : 0;
+}
diff -druN linux-2.6.39-libre/arch/x86/net/bpf_jit_comp.c linux-3.0-rc7-libre/arch/x86/net/bpf_jit_comp.c
--- linux-2.6.39-libre/arch/x86/net/bpf_jit_comp.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/x86/net/bpf_jit_comp.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,654 @@
+/* bpf_jit_comp.c : BPF JIT compiler
+ *
+ * Copyright (C) 2011 Eric Dumazet (eric.dumazet@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/moduleloader.h>
+#include <asm/cacheflush.h>
+#include <linux/netdevice.h>
+#include <linux/filter.h>
+
+/*
+ * Conventions :
+ *  EAX : BPF A accumulator
+ *  EBX : BPF X accumulator
+ *  RDI : pointer to skb   (first argument given to JIT function)
+ *  RBP : frame pointer (even if CONFIG_FRAME_POINTER=n)
+ *  ECX,EDX,ESI : scratch registers
+ *  r9d : skb->len - skb->data_len (headlen)
+ *  r8  : skb->data
+ * -8(RBP) : saved RBX value
+ * -16(RBP)..-80(RBP) : BPF_MEMWORDS values
+ */
+int bpf_jit_enable __read_mostly;
+
+/*
+ * assembly code in arch/x86/net/bpf_jit.S
+ */
+extern u8 sk_load_word[], sk_load_half[], sk_load_byte[], sk_load_byte_msh[];
+extern u8 sk_load_word_ind[], sk_load_half_ind[], sk_load_byte_ind[];
+
+static inline u8 *emit_code(u8 *ptr, u32 bytes, unsigned int len)
+{
+	if (len == 1)
+		*ptr = bytes;
+	else if (len == 2)
+		*(u16 *)ptr = bytes;
+	else {
+		*(u32 *)ptr = bytes;
+		barrier();
+	}
+	return ptr + len;
+}
+
+#define EMIT(bytes, len)	do { prog = emit_code(prog, bytes, len); } while (0)
+
+#define EMIT1(b1)		EMIT(b1, 1)
+#define EMIT2(b1, b2)		EMIT((b1) + ((b2) << 8), 2)
+#define EMIT3(b1, b2, b3)	EMIT((b1) + ((b2) << 8) + ((b3) << 16), 3)
+#define EMIT4(b1, b2, b3, b4)   EMIT((b1) + ((b2) << 8) + ((b3) << 16) + ((b4) << 24), 4)
+#define EMIT1_off32(b1, off)	do { EMIT1(b1); EMIT(off, 4);} while (0)
+
+#define CLEAR_A() EMIT2(0x31, 0xc0) /* xor %eax,%eax */
+#define CLEAR_X() EMIT2(0x31, 0xdb) /* xor %ebx,%ebx */
+
+static inline bool is_imm8(int value)
+{
+	return value <= 127 && value >= -128;
+}
+
+static inline bool is_near(int offset)
+{
+	return offset <= 127 && offset >= -128;
+}
+
+#define EMIT_JMP(offset)						\
+do {									\
+	if (offset) {							\
+		if (is_near(offset))					\
+			EMIT2(0xeb, offset); /* jmp .+off8 */		\
+		else							\
+			EMIT1_off32(0xe9, offset); /* jmp .+off32 */	\
+	}								\
+} while (0)
+
+/* list of x86 cond jumps opcodes (. + s8)
+ * Add 0x10 (and an extra 0x0f) to generate far jumps (. + s32)
+ */
+#define X86_JB  0x72
+#define X86_JAE 0x73
+#define X86_JE  0x74
+#define X86_JNE 0x75
+#define X86_JBE 0x76
+#define X86_JA  0x77
+
+#define EMIT_COND_JMP(op, offset)				\
+do {								\
+	if (is_near(offset))					\
+		EMIT2(op, offset); /* jxx .+off8 */		\
+	else {							\
+		EMIT2(0x0f, op + 0x10);				\
+		EMIT(offset, 4); /* jxx .+off32 */		\
+	}							\
+} while (0)
+
+#define COND_SEL(CODE, TOP, FOP)	\
+	case CODE:			\
+		t_op = TOP;		\
+		f_op = FOP;		\
+		goto cond_branch
+
+
+#define SEEN_DATAREF 1 /* might call external helpers */
+#define SEEN_XREG    2 /* ebx is used */
+#define SEEN_MEM     4 /* use mem[] for temporary storage */
+
+static inline void bpf_flush_icache(void *start, void *end)
+{
+	mm_segment_t old_fs = get_fs();
+
+	set_fs(KERNEL_DS);
+	smp_wmb();
+	flush_icache_range((unsigned long)start, (unsigned long)end);
+	set_fs(old_fs);
+}
+
+
+void bpf_jit_compile(struct sk_filter *fp)
+{
+	u8 temp[64];
+	u8 *prog;
+	unsigned int proglen, oldproglen = 0;
+	int ilen, i;
+	int t_offset, f_offset;
+	u8 t_op, f_op, seen = 0, pass;
+	u8 *image = NULL;
+	u8 *func;
+	int pc_ret0 = -1; /* bpf index of first RET #0 instruction (if any) */
+	unsigned int cleanup_addr; /* epilogue code offset */
+	unsigned int *addrs;
+	const struct sock_filter *filter = fp->insns;
+	int flen = fp->len;
+
+	if (!bpf_jit_enable)
+		return;
+
+	addrs = kmalloc(flen * sizeof(*addrs), GFP_KERNEL);
+	if (addrs == NULL)
+		return;
+
+	/* Before first pass, make a rough estimation of addrs[]
+	 * each bpf instruction is translated to less than 64 bytes
+	 */
+	for (proglen = 0, i = 0; i < flen; i++) {
+		proglen += 64;
+		addrs[i] = proglen;
+	}
+	cleanup_addr = proglen; /* epilogue address */
+
+	for (pass = 0; pass < 10; pass++) {
+		/* no prologue/epilogue for trivial filters (RET something) */
+		proglen = 0;
+		prog = temp;
+
+		if (seen) {
+			EMIT4(0x55, 0x48, 0x89, 0xe5); /* push %rbp; mov %rsp,%rbp */
+			EMIT4(0x48, 0x83, 0xec, 96);	/* subq  $96,%rsp	*/
+			/* note : must save %rbx in case bpf_error is hit */
+			if (seen & (SEEN_XREG | SEEN_DATAREF))
+				EMIT4(0x48, 0x89, 0x5d, 0xf8); /* mov %rbx, -8(%rbp) */
+			if (seen & SEEN_XREG)
+				CLEAR_X(); /* make sure we dont leek kernel memory */
+
+			/*
+			 * If this filter needs to access skb data,
+			 * loads r9 and r8 with :
+			 *  r9 = skb->len - skb->data_len
+			 *  r8 = skb->data
+			 */
+			if (seen & SEEN_DATAREF) {
+				if (offsetof(struct sk_buff, len) <= 127)
+					/* mov    off8(%rdi),%r9d */
+					EMIT4(0x44, 0x8b, 0x4f, offsetof(struct sk_buff, len));
+				else {
+					/* mov    off32(%rdi),%r9d */
+					EMIT3(0x44, 0x8b, 0x8f);
+					EMIT(offsetof(struct sk_buff, len), 4);
+				}
+				if (is_imm8(offsetof(struct sk_buff, data_len)))
+					/* sub    off8(%rdi),%r9d */
+					EMIT4(0x44, 0x2b, 0x4f, offsetof(struct sk_buff, data_len));
+				else {
+					EMIT3(0x44, 0x2b, 0x8f);
+					EMIT(offsetof(struct sk_buff, data_len), 4);
+				}
+
+				if (is_imm8(offsetof(struct sk_buff, data)))
+					/* mov off8(%rdi),%r8 */
+					EMIT4(0x4c, 0x8b, 0x47, offsetof(struct sk_buff, data));
+				else {
+					/* mov off32(%rdi),%r8 */
+					EMIT3(0x4c, 0x8b, 0x87);
+					EMIT(offsetof(struct sk_buff, data), 4);
+				}
+			}
+		}
+
+		switch (filter[0].code) {
+		case BPF_S_RET_K:
+		case BPF_S_LD_W_LEN:
+		case BPF_S_ANC_PROTOCOL:
+		case BPF_S_ANC_IFINDEX:
+		case BPF_S_ANC_MARK:
+		case BPF_S_ANC_RXHASH:
+		case BPF_S_ANC_CPU:
+		case BPF_S_ANC_QUEUE:
+		case BPF_S_LD_W_ABS:
+		case BPF_S_LD_H_ABS:
+		case BPF_S_LD_B_ABS:
+			/* first instruction sets A register (or is RET 'constant') */
+			break;
+		default:
+			/* make sure we dont leak kernel information to user */
+			CLEAR_A(); /* A = 0 */
+		}
+
+		for (i = 0; i < flen; i++) {
+			unsigned int K = filter[i].k;
+
+			switch (filter[i].code) {
+			case BPF_S_ALU_ADD_X: /* A += X; */
+				seen |= SEEN_XREG;
+				EMIT2(0x01, 0xd8);		/* add %ebx,%eax */
+				break;
+			case BPF_S_ALU_ADD_K: /* A += K; */
+				if (!K)
+					break;
+				if (is_imm8(K))
+					EMIT3(0x83, 0xc0, K);	/* add imm8,%eax */
+				else
+					EMIT1_off32(0x05, K);	/* add imm32,%eax */
+				break;
+			case BPF_S_ALU_SUB_X: /* A -= X; */
+				seen |= SEEN_XREG;
+				EMIT2(0x29, 0xd8);		/* sub    %ebx,%eax */
+				break;
+			case BPF_S_ALU_SUB_K: /* A -= K */
+				if (!K)
+					break;
+				if (is_imm8(K))
+					EMIT3(0x83, 0xe8, K); /* sub imm8,%eax */
+				else
+					EMIT1_off32(0x2d, K); /* sub imm32,%eax */
+				break;
+			case BPF_S_ALU_MUL_X: /* A *= X; */
+				seen |= SEEN_XREG;
+				EMIT3(0x0f, 0xaf, 0xc3);	/* imul %ebx,%eax */
+				break;
+			case BPF_S_ALU_MUL_K: /* A *= K */
+				if (is_imm8(K))
+					EMIT3(0x6b, 0xc0, K); /* imul imm8,%eax,%eax */
+				else {
+					EMIT2(0x69, 0xc0);		/* imul imm32,%eax */
+					EMIT(K, 4);
+				}
+				break;
+			case BPF_S_ALU_DIV_X: /* A /= X; */
+				seen |= SEEN_XREG;
+				EMIT2(0x85, 0xdb);	/* test %ebx,%ebx */
+				if (pc_ret0 != -1)
+					EMIT_COND_JMP(X86_JE, addrs[pc_ret0] - (addrs[i] - 4));
+				else {
+					EMIT_COND_JMP(X86_JNE, 2 + 5);
+					CLEAR_A();
+					EMIT1_off32(0xe9, cleanup_addr - (addrs[i] - 4)); /* jmp .+off32 */
+				}
+				EMIT4(0x31, 0xd2, 0xf7, 0xf3); /* xor %edx,%edx; div %ebx */
+				break;
+			case BPF_S_ALU_DIV_K: /* A = reciprocal_divide(A, K); */
+				EMIT3(0x48, 0x69, 0xc0); /* imul imm32,%rax,%rax */
+				EMIT(K, 4);
+				EMIT4(0x48, 0xc1, 0xe8, 0x20); /* shr $0x20,%rax */
+				break;
+			case BPF_S_ALU_AND_X:
+				seen |= SEEN_XREG;
+				EMIT2(0x21, 0xd8);		/* and %ebx,%eax */
+				break;
+			case BPF_S_ALU_AND_K:
+				if (K >= 0xFFFFFF00) {
+					EMIT2(0x24, K & 0xFF); /* and imm8,%al */
+				} else if (K >= 0xFFFF0000) {
+					EMIT2(0x66, 0x25);	/* and imm16,%ax */
+					EMIT2(K, 2);
+				} else {
+					EMIT1_off32(0x25, K);	/* and imm32,%eax */
+				}
+				break;
+			case BPF_S_ALU_OR_X:
+				seen |= SEEN_XREG;
+				EMIT2(0x09, 0xd8);		/* or %ebx,%eax */
+				break;
+			case BPF_S_ALU_OR_K:
+				if (is_imm8(K))
+					EMIT3(0x83, 0xc8, K); /* or imm8,%eax */
+				else
+					EMIT1_off32(0x0d, K);	/* or imm32,%eax */
+				break;
+			case BPF_S_ALU_LSH_X: /* A <<= X; */
+				seen |= SEEN_XREG;
+				EMIT4(0x89, 0xd9, 0xd3, 0xe0);	/* mov %ebx,%ecx; shl %cl,%eax */
+				break;
+			case BPF_S_ALU_LSH_K:
+				if (K == 0)
+					break;
+				else if (K == 1)
+					EMIT2(0xd1, 0xe0); /* shl %eax */
+				else
+					EMIT3(0xc1, 0xe0, K);
+				break;
+			case BPF_S_ALU_RSH_X: /* A >>= X; */
+				seen |= SEEN_XREG;
+				EMIT4(0x89, 0xd9, 0xd3, 0xe8);	/* mov %ebx,%ecx; shr %cl,%eax */
+				break;
+			case BPF_S_ALU_RSH_K: /* A >>= K; */
+				if (K == 0)
+					break;
+				else if (K == 1)
+					EMIT2(0xd1, 0xe8); /* shr %eax */
+				else
+					EMIT3(0xc1, 0xe8, K);
+				break;
+			case BPF_S_ALU_NEG:
+				EMIT2(0xf7, 0xd8);		/* neg %eax */
+				break;
+			case BPF_S_RET_K:
+				if (!K) {
+					if (pc_ret0 == -1)
+						pc_ret0 = i;
+					CLEAR_A();
+				} else {
+					EMIT1_off32(0xb8, K);	/* mov $imm32,%eax */
+				}
+				/* fallinto */
+			case BPF_S_RET_A:
+				if (seen) {
+					if (i != flen - 1) {
+						EMIT_JMP(cleanup_addr - addrs[i]);
+						break;
+					}
+					if (seen & SEEN_XREG)
+						EMIT4(0x48, 0x8b, 0x5d, 0xf8);  /* mov  -8(%rbp),%rbx */
+					EMIT1(0xc9);		/* leaveq */
+				}
+				EMIT1(0xc3);		/* ret */
+				break;
+			case BPF_S_MISC_TAX: /* X = A */
+				seen |= SEEN_XREG;
+				EMIT2(0x89, 0xc3);	/* mov    %eax,%ebx */
+				break;
+			case BPF_S_MISC_TXA: /* A = X */
+				seen |= SEEN_XREG;
+				EMIT2(0x89, 0xd8);	/* mov    %ebx,%eax */
+				break;
+			case BPF_S_LD_IMM: /* A = K */
+				if (!K)
+					CLEAR_A();
+				else
+					EMIT1_off32(0xb8, K); /* mov $imm32,%eax */
+				break;
+			case BPF_S_LDX_IMM: /* X = K */
+				seen |= SEEN_XREG;
+				if (!K)
+					CLEAR_X();
+				else
+					EMIT1_off32(0xbb, K); /* mov $imm32,%ebx */
+				break;
+			case BPF_S_LD_MEM: /* A = mem[K] : mov off8(%rbp),%eax */
+				seen |= SEEN_MEM;
+				EMIT3(0x8b, 0x45, 0xf0 - K*4);
+				break;
+			case BPF_S_LDX_MEM: /* X = mem[K] : mov off8(%rbp),%ebx */
+				seen |= SEEN_XREG | SEEN_MEM;
+				EMIT3(0x8b, 0x5d, 0xf0 - K*4);
+				break;
+			case BPF_S_ST: /* mem[K] = A : mov %eax,off8(%rbp) */
+				seen |= SEEN_MEM;
+				EMIT3(0x89, 0x45, 0xf0 - K*4);
+				break;
+			case BPF_S_STX: /* mem[K] = X : mov %ebx,off8(%rbp) */
+				seen |= SEEN_XREG | SEEN_MEM;
+				EMIT3(0x89, 0x5d, 0xf0 - K*4);
+				break;
+			case BPF_S_LD_W_LEN: /*	A = skb->len; */
+				BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, len) != 4);
+				if (is_imm8(offsetof(struct sk_buff, len)))
+					/* mov    off8(%rdi),%eax */
+					EMIT3(0x8b, 0x47, offsetof(struct sk_buff, len));
+				else {
+					EMIT2(0x8b, 0x87);
+					EMIT(offsetof(struct sk_buff, len), 4);
+				}
+				break;
+			case BPF_S_LDX_W_LEN: /* X = skb->len; */
+				seen |= SEEN_XREG;
+				if (is_imm8(offsetof(struct sk_buff, len)))
+					/* mov off8(%rdi),%ebx */
+					EMIT3(0x8b, 0x5f, offsetof(struct sk_buff, len));
+				else {
+					EMIT2(0x8b, 0x9f);
+					EMIT(offsetof(struct sk_buff, len), 4);
+				}
+				break;
+			case BPF_S_ANC_PROTOCOL: /* A = ntohs(skb->protocol); */
+				BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, protocol) != 2);
+				if (is_imm8(offsetof(struct sk_buff, protocol))) {
+					/* movzwl off8(%rdi),%eax */
+					EMIT4(0x0f, 0xb7, 0x47, offsetof(struct sk_buff, protocol));
+				} else {
+					EMIT3(0x0f, 0xb7, 0x87); /* movzwl off32(%rdi),%eax */
+					EMIT(offsetof(struct sk_buff, protocol), 4);
+				}
+				EMIT2(0x86, 0xc4); /* ntohs() : xchg   %al,%ah */
+				break;
+			case BPF_S_ANC_IFINDEX:
+				if (is_imm8(offsetof(struct sk_buff, dev))) {
+					/* movq off8(%rdi),%rax */
+					EMIT4(0x48, 0x8b, 0x47, offsetof(struct sk_buff, dev));
+				} else {
+					EMIT3(0x48, 0x8b, 0x87); /* movq off32(%rdi),%rax */
+					EMIT(offsetof(struct sk_buff, dev), 4);
+				}
+				EMIT3(0x48, 0x85, 0xc0);	/* test %rax,%rax */
+				EMIT_COND_JMP(X86_JE, cleanup_addr - (addrs[i] - 6));
+				BUILD_BUG_ON(FIELD_SIZEOF(struct net_device, ifindex) != 4);
+				EMIT2(0x8b, 0x80);	/* mov off32(%rax),%eax */
+				EMIT(offsetof(struct net_device, ifindex), 4);
+				break;
+			case BPF_S_ANC_MARK:
+				BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, mark) != 4);
+				if (is_imm8(offsetof(struct sk_buff, mark))) {
+					/* mov off8(%rdi),%eax */
+					EMIT3(0x8b, 0x47, offsetof(struct sk_buff, mark));
+				} else {
+					EMIT2(0x8b, 0x87);
+					EMIT(offsetof(struct sk_buff, mark), 4);
+				}
+				break;
+			case BPF_S_ANC_RXHASH:
+				BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, rxhash) != 4);
+				if (is_imm8(offsetof(struct sk_buff, rxhash))) {
+					/* mov off8(%rdi),%eax */
+					EMIT3(0x8b, 0x47, offsetof(struct sk_buff, rxhash));
+				} else {
+					EMIT2(0x8b, 0x87);
+					EMIT(offsetof(struct sk_buff, rxhash), 4);
+				}
+				break;
+			case BPF_S_ANC_QUEUE:
+				BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, queue_mapping) != 2);
+				if (is_imm8(offsetof(struct sk_buff, queue_mapping))) {
+					/* movzwl off8(%rdi),%eax */
+					EMIT4(0x0f, 0xb7, 0x47, offsetof(struct sk_buff, queue_mapping));
+				} else {
+					EMIT3(0x0f, 0xb7, 0x87); /* movzwl off32(%rdi),%eax */
+					EMIT(offsetof(struct sk_buff, queue_mapping), 4);
+				}
+				break;
+			case BPF_S_ANC_CPU:
+#ifdef CONFIG_SMP
+				EMIT4(0x65, 0x8b, 0x04, 0x25); /* mov %gs:off32,%eax */
+				EMIT((u32)(unsigned long)&cpu_number, 4); /* A = smp_processor_id(); */
+#else
+				CLEAR_A();
+#endif
+				break;
+			case BPF_S_LD_W_ABS:
+				func = sk_load_word;
+common_load:			seen |= SEEN_DATAREF;
+				if ((int)K < 0)
+					goto out;
+				t_offset = func - (image + addrs[i]);
+				EMIT1_off32(0xbe, K); /* mov imm32,%esi */
+				EMIT1_off32(0xe8, t_offset); /* call */
+				break;
+			case BPF_S_LD_H_ABS:
+				func = sk_load_half;
+				goto common_load;
+			case BPF_S_LD_B_ABS:
+				func = sk_load_byte;
+				goto common_load;
+			case BPF_S_LDX_B_MSH:
+				if ((int)K < 0) {
+					if (pc_ret0 != -1) {
+						EMIT_JMP(addrs[pc_ret0] - addrs[i]);
+						break;
+					}
+					CLEAR_A();
+					EMIT_JMP(cleanup_addr - addrs[i]);
+					break;
+				}
+				seen |= SEEN_DATAREF | SEEN_XREG;
+				t_offset = sk_load_byte_msh - (image + addrs[i]);
+				EMIT1_off32(0xbe, K);	/* mov imm32,%esi */
+				EMIT1_off32(0xe8, t_offset); /* call sk_load_byte_msh */
+				break;
+			case BPF_S_LD_W_IND:
+				func = sk_load_word_ind;
+common_load_ind:		seen |= SEEN_DATAREF | SEEN_XREG;
+				t_offset = func - (image + addrs[i]);
+				EMIT1_off32(0xbe, K);	/* mov imm32,%esi   */
+				EMIT1_off32(0xe8, t_offset);	/* call sk_load_xxx_ind */
+				break;
+			case BPF_S_LD_H_IND:
+				func = sk_load_half_ind;
+				goto common_load_ind;
+			case BPF_S_LD_B_IND:
+				func = sk_load_byte_ind;
+				goto common_load_ind;
+			case BPF_S_JMP_JA:
+				t_offset = addrs[i + K] - addrs[i];
+				EMIT_JMP(t_offset);
+				break;
+			COND_SEL(BPF_S_JMP_JGT_K, X86_JA, X86_JBE);
+			COND_SEL(BPF_S_JMP_JGE_K, X86_JAE, X86_JB);
+			COND_SEL(BPF_S_JMP_JEQ_K, X86_JE, X86_JNE);
+			COND_SEL(BPF_S_JMP_JSET_K,X86_JNE, X86_JE);
+			COND_SEL(BPF_S_JMP_JGT_X, X86_JA, X86_JBE);
+			COND_SEL(BPF_S_JMP_JGE_X, X86_JAE, X86_JB);
+			COND_SEL(BPF_S_JMP_JEQ_X, X86_JE, X86_JNE);
+			COND_SEL(BPF_S_JMP_JSET_X,X86_JNE, X86_JE);
+
+cond_branch:			f_offset = addrs[i + filter[i].jf] - addrs[i];
+				t_offset = addrs[i + filter[i].jt] - addrs[i];
+
+				/* same targets, can avoid doing the test :) */
+				if (filter[i].jt == filter[i].jf) {
+					EMIT_JMP(t_offset);
+					break;
+				}
+
+				switch (filter[i].code) {
+				case BPF_S_JMP_JGT_X:
+				case BPF_S_JMP_JGE_X:
+				case BPF_S_JMP_JEQ_X:
+					seen |= SEEN_XREG;
+					EMIT2(0x39, 0xd8); /* cmp %ebx,%eax */
+					break;
+				case BPF_S_JMP_JSET_X:
+					seen |= SEEN_XREG;
+					EMIT2(0x85, 0xd8); /* test %ebx,%eax */
+					break;
+				case BPF_S_JMP_JEQ_K:
+					if (K == 0) {
+						EMIT2(0x85, 0xc0); /* test   %eax,%eax */
+						break;
+					}
+				case BPF_S_JMP_JGT_K:
+				case BPF_S_JMP_JGE_K:
+					if (K <= 127)
+						EMIT3(0x83, 0xf8, K); /* cmp imm8,%eax */
+					else
+						EMIT1_off32(0x3d, K); /* cmp imm32,%eax */
+					break;
+				case BPF_S_JMP_JSET_K:
+					if (K <= 0xFF)
+						EMIT2(0xa8, K); /* test imm8,%al */
+					else if (!(K & 0xFFFF00FF))
+						EMIT3(0xf6, 0xc4, K >> 8); /* test imm8,%ah */
+					else if (K <= 0xFFFF) {
+						EMIT2(0x66, 0xa9); /* test imm16,%ax */
+						EMIT(K, 2);
+					} else {
+						EMIT1_off32(0xa9, K); /* test imm32,%eax */
+					}
+					break;
+				}
+				if (filter[i].jt != 0) {
+					if (filter[i].jf)
+						t_offset += is_near(f_offset) ? 2 : 6;
+					EMIT_COND_JMP(t_op, t_offset);
+					if (filter[i].jf)
+						EMIT_JMP(f_offset);
+					break;
+				}
+				EMIT_COND_JMP(f_op, f_offset);
+				break;
+			default:
+				/* hmm, too complex filter, give up with jit compiler */
+				goto out;
+			}
+			ilen = prog - temp;
+			if (image) {
+				if (unlikely(proglen + ilen > oldproglen)) {
+					pr_err("bpb_jit_compile fatal error\n");
+					kfree(addrs);
+					module_free(NULL, image);
+					return;
+				}
+				memcpy(image + proglen, temp, ilen);
+			}
+			proglen += ilen;
+			addrs[i] = proglen;
+			prog = temp;
+		}
+		/* last bpf instruction is always a RET :
+		 * use it to give the cleanup instruction(s) addr
+		 */
+		cleanup_addr = proglen - 1; /* ret */
+		if (seen)
+			cleanup_addr -= 1; /* leaveq */
+		if (seen & SEEN_XREG)
+			cleanup_addr -= 4; /* mov  -8(%rbp),%rbx */
+
+		if (image) {
+			WARN_ON(proglen != oldproglen);
+			break;
+		}
+		if (proglen == oldproglen) {
+			image = module_alloc(max_t(unsigned int,
+						   proglen,
+						   sizeof(struct work_struct)));
+			if (!image)
+				goto out;
+		}
+		oldproglen = proglen;
+	}
+	if (bpf_jit_enable > 1)
+		pr_err("flen=%d proglen=%u pass=%d image=%p\n",
+		       flen, proglen, pass, image);
+
+	if (image) {
+		if (bpf_jit_enable > 1)
+			print_hex_dump(KERN_ERR, "JIT code: ", DUMP_PREFIX_ADDRESS,
+				       16, 1, image, proglen, false);
+
+		bpf_flush_icache(image, image + proglen);
+
+		fp->bpf_func = (void *)image;
+	}
+out:
+	kfree(addrs);
+	return;
+}
+
+static void jit_free_defer(struct work_struct *arg)
+{
+	module_free(NULL, arg);
+}
+
+/* run from softirq, we must use a work_struct to call
+ * module_free() from process context
+ */
+void bpf_jit_free(struct sk_filter *fp)
+{
+	if (fp->bpf_func != sk_run_filter) {
+		struct work_struct *work = (struct work_struct *)fp->bpf_func;
+
+		INIT_WORK(work, jit_free_defer);
+		schedule_work(work);
+	}
+}
diff -druN linux-2.6.39-libre/arch/x86/net/bpf_jit.S linux-3.0-rc7-libre/arch/x86/net/bpf_jit.S
--- linux-2.6.39-libre/arch/x86/net/bpf_jit.S	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/x86/net/bpf_jit.S	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,140 @@
+/* bpf_jit.S : BPF JIT helper functions
+ *
+ * Copyright (C) 2011 Eric Dumazet (eric.dumazet@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/linkage.h>
+#include <asm/dwarf2.h>
+
+/*
+ * Calling convention :
+ * rdi : skb pointer
+ * esi : offset of byte(s) to fetch in skb (can be scratched)
+ * r8  : copy of skb->data
+ * r9d : hlen = skb->len - skb->data_len
+ */
+#define SKBDATA	%r8
+
+sk_load_word_ind:
+	.globl	sk_load_word_ind
+
+	add	%ebx,%esi	/* offset += X */
+#	test    %esi,%esi	/* if (offset < 0) goto bpf_error; */
+	js	bpf_error
+
+sk_load_word:
+	.globl	sk_load_word
+
+	mov	%r9d,%eax		# hlen
+	sub	%esi,%eax		# hlen - offset
+	cmp	$3,%eax
+	jle	bpf_slow_path_word
+	mov     (SKBDATA,%rsi),%eax
+	bswap   %eax  			/* ntohl() */
+	ret
+
+
+sk_load_half_ind:
+	.globl sk_load_half_ind
+
+	add	%ebx,%esi	/* offset += X */
+	js	bpf_error
+
+sk_load_half:
+	.globl	sk_load_half
+
+	mov	%r9d,%eax
+	sub	%esi,%eax		#	hlen - offset
+	cmp	$1,%eax
+	jle	bpf_slow_path_half
+	movzwl	(SKBDATA,%rsi),%eax
+	rol	$8,%ax			# ntohs()
+	ret
+
+sk_load_byte_ind:
+	.globl sk_load_byte_ind
+	add	%ebx,%esi	/* offset += X */
+	js	bpf_error
+
+sk_load_byte:
+	.globl	sk_load_byte
+
+	cmp	%esi,%r9d   /* if (offset >= hlen) goto bpf_slow_path_byte */
+	jle	bpf_slow_path_byte
+	movzbl	(SKBDATA,%rsi),%eax
+	ret
+
+/**
+ * sk_load_byte_msh - BPF_S_LDX_B_MSH helper
+ *
+ * Implements BPF_S_LDX_B_MSH : ldxb  4*([offset]&0xf)
+ * Must preserve A accumulator (%eax)
+ * Inputs : %esi is the offset value, already known positive
+ */
+ENTRY(sk_load_byte_msh)
+	CFI_STARTPROC
+	cmp	%esi,%r9d      /* if (offset >= hlen) goto bpf_slow_path_byte_msh */
+	jle	bpf_slow_path_byte_msh
+	movzbl	(SKBDATA,%rsi),%ebx
+	and	$15,%bl
+	shl	$2,%bl
+	ret
+	CFI_ENDPROC
+ENDPROC(sk_load_byte_msh)
+
+bpf_error:
+# force a return 0 from jit handler
+	xor		%eax,%eax
+	mov		-8(%rbp),%rbx
+	leaveq
+	ret
+
+/* rsi contains offset and can be scratched */
+#define bpf_slow_path_common(LEN)		\
+	push	%rdi;    /* save skb */		\
+	push	%r9;				\
+	push	SKBDATA;			\
+/* rsi already has offset */			\
+	mov	$LEN,%ecx;	/* len */	\
+	lea	-12(%rbp),%rdx;			\
+	call	skb_copy_bits;			\
+	test    %eax,%eax;			\
+	pop	SKBDATA;			\
+	pop	%r9;				\
+	pop	%rdi
+
+
+bpf_slow_path_word:
+	bpf_slow_path_common(4)
+	js	bpf_error
+	mov	-12(%rbp),%eax
+	bswap	%eax
+	ret
+
+bpf_slow_path_half:
+	bpf_slow_path_common(2)
+	js	bpf_error
+	mov	-12(%rbp),%ax
+	rol	$8,%ax
+	movzwl	%ax,%eax
+	ret
+
+bpf_slow_path_byte:
+	bpf_slow_path_common(1)
+	js	bpf_error
+	movzbl	-12(%rbp),%eax
+	ret
+
+bpf_slow_path_byte_msh:
+	xchg	%eax,%ebx /* dont lose A , X is about to be scratched */
+	bpf_slow_path_common(1)
+	js	bpf_error
+	movzbl	-12(%rbp),%eax
+	and	$15,%al
+	shl	$2,%al
+	xchg	%eax,%ebx
+	ret
diff -druN linux-2.6.39-libre/arch/x86/net/Makefile linux-3.0-rc7-libre/arch/x86/net/Makefile
--- linux-2.6.39-libre/arch/x86/net/Makefile	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/arch/x86/net/Makefile	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,4 @@
+#
+# Arch-specific network modules
+#
+obj-$(CONFIG_BPF_JIT) += bpf_jit.o bpf_jit_comp.o
diff -druN linux-2.6.39-libre/arch/x86/oprofile/backtrace.c linux-3.0-rc7-libre/arch/x86/oprofile/backtrace.c
--- linux-2.6.39-libre/arch/x86/oprofile/backtrace.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/oprofile/backtrace.c	2011-07-11 19:51:52.000000000 -0400
@@ -16,17 +16,6 @@
 #include <asm/stacktrace.h>
 #include <linux/compat.h>
 
-static void backtrace_warning_symbol(void *data, char *msg,
-				     unsigned long symbol)
-{
-	/* Ignore warnings */
-}
-
-static void backtrace_warning(void *data, char *msg)
-{
-	/* Ignore warnings */
-}
-
 static int backtrace_stack(void *data, char *name)
 {
 	/* Yes, we want all stacks */
@@ -42,8 +31,6 @@
 }
 
 static struct stacktrace_ops backtrace_ops = {
-	.warning	= backtrace_warning,
-	.warning_symbol	= backtrace_warning_symbol,
 	.stack		= backtrace_stack,
 	.address	= backtrace_address,
 	.walk_stack	= print_context_stack,
diff -druN linux-2.6.39-libre/arch/x86/oprofile/nmi_int.c linux-3.0-rc7-libre/arch/x86/oprofile/nmi_int.c
--- linux-2.6.39-libre/arch/x86/oprofile/nmi_int.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/oprofile/nmi_int.c	2011-07-11 19:51:52.000000000 -0400
@@ -112,8 +112,10 @@
 static int nmi_start(void)
 {
 	get_online_cpus();
-	on_each_cpu(nmi_cpu_start, NULL, 1);
 	ctr_running = 1;
+	/* make ctr_running visible to the nmi handler: */
+	smp_mb();
+	on_each_cpu(nmi_cpu_start, NULL, 1);
 	put_online_cpus();
 	return 0;
 }
@@ -504,15 +506,18 @@
 
 	nmi_enabled = 0;
 	ctr_running = 0;
-	barrier();
+	/* make variables visible to the nmi handler: */
+	smp_mb();
 	err = register_die_notifier(&profile_exceptions_nb);
 	if (err)
 		goto fail;
 
 	get_online_cpus();
 	register_cpu_notifier(&oprofile_cpu_nb);
-	on_each_cpu(nmi_cpu_setup, NULL, 1);
 	nmi_enabled = 1;
+	/* make nmi_enabled visible to the nmi handler: */
+	smp_mb();
+	on_each_cpu(nmi_cpu_setup, NULL, 1);
 	put_online_cpus();
 
 	return 0;
@@ -531,7 +536,8 @@
 	nmi_enabled = 0;
 	ctr_running = 0;
 	put_online_cpus();
-	barrier();
+	/* make variables visible to the nmi handler: */
+	smp_mb();
 	unregister_die_notifier(&profile_exceptions_nb);
 	msrs = &get_cpu_var(cpu_msrs);
 	model->shutdown(msrs);
diff -druN linux-2.6.39-libre/arch/x86/oprofile/op_model_amd.c linux-3.0-rc7-libre/arch/x86/oprofile/op_model_amd.c
--- linux-2.6.39-libre/arch/x86/oprofile/op_model_amd.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/oprofile/op_model_amd.c	2011-07-11 19:51:52.000000000 -0400
@@ -316,16 +316,23 @@
 		wrmsrl(MSR_AMD64_IBSOPCTL, 0);
 }
 
-static inline int eilvt_is_available(int offset)
+static inline int get_eilvt(int offset)
 {
-	/* check if we may assign a vector */
 	return !setup_APIC_eilvt(offset, 0, APIC_EILVT_MSG_NMI, 1);
 }
 
+static inline int put_eilvt(int offset)
+{
+	return !setup_APIC_eilvt(offset, 0, 0, 1);
+}
+
 static inline int ibs_eilvt_valid(void)
 {
 	int offset;
 	u64 val;
+	int valid = 0;
+
+	preempt_disable();
 
 	rdmsrl(MSR_AMD64_IBSCTL, val);
 	offset = val & IBSCTL_LVT_OFFSET_MASK;
@@ -333,16 +340,20 @@
 	if (!(val & IBSCTL_LVT_OFFSET_VALID)) {
 		pr_err(FW_BUG "cpu %d, invalid IBS interrupt offset %d (MSR%08X=0x%016llx)\n",
 		       smp_processor_id(), offset, MSR_AMD64_IBSCTL, val);
-		return 0;
+		goto out;
 	}
 
-	if (!eilvt_is_available(offset)) {
+	if (!get_eilvt(offset)) {
 		pr_err(FW_BUG "cpu %d, IBS interrupt offset %d not available (MSR%08X=0x%016llx)\n",
 		       smp_processor_id(), offset, MSR_AMD64_IBSCTL, val);
-		return 0;
+		goto out;
 	}
 
-	return 1;
+	valid = 1;
+out:
+	preempt_enable();
+
+	return valid;
 }
 
 static inline int get_ibs_offset(void)
@@ -598,69 +609,76 @@
 	return 0;
 }
 
+/*
+ * This runs only on the current cpu. We try to find an LVT offset and
+ * setup the local APIC. For this we must disable preemption. On
+ * success we initialize all nodes with this offset. This updates then
+ * the offset in the IBS_CTL per-node msr. The per-core APIC setup of
+ * the IBS interrupt vector is called from op_amd_setup_ctrs()/op_-
+ * amd_cpu_shutdown() using the new offset.
+ */
 static int force_ibs_eilvt_setup(void)
 {
-	int i;
+	int offset;
 	int ret;
 
-	/* find the next free available EILVT entry */
-	for (i = 1; i < 4; i++) {
-		if (!eilvt_is_available(i))
-			continue;
-		ret = setup_ibs_ctl(i);
-		if (ret)
-			return ret;
-		pr_err(FW_BUG "using offset %d for IBS interrupts\n", i);
-		return 0;
+	preempt_disable();
+	/* find the next free available EILVT entry, skip offset 0 */
+	for (offset = 1; offset < APIC_EILVT_NR_MAX; offset++) {
+		if (get_eilvt(offset))
+			break;
 	}
+	preempt_enable();
 
-	printk(KERN_DEBUG "No EILVT entry available\n");
-
-	return -EBUSY;
-}
-
-static int __init_ibs_nmi(void)
-{
-	int ret;
-
-	if (ibs_eilvt_valid())
-		return 0;
+	if (offset == APIC_EILVT_NR_MAX) {
+		printk(KERN_DEBUG "No EILVT entry available\n");
+		return -EBUSY;
+	}
 
-	ret = force_ibs_eilvt_setup();
+	ret = setup_ibs_ctl(offset);
 	if (ret)
-		return ret;
+		goto out;
 
-	if (!ibs_eilvt_valid())
-		return -EFAULT;
+	if (!ibs_eilvt_valid()) {
+		ret = -EFAULT;
+		goto out;
+	}
 
+	pr_err(FW_BUG "using offset %d for IBS interrupts\n", offset);
 	pr_err(FW_BUG "workaround enabled for IBS LVT offset\n");
 
 	return 0;
+out:
+	preempt_disable();
+	put_eilvt(offset);
+	preempt_enable();
+	return ret;
 }
 
 /*
  * check and reserve APIC extended interrupt LVT offset for IBS if
  * available
- *
- * init_ibs() preforms implicitly cpu-local operations, so pin this
- * thread to its current CPU
  */
 
 static void init_ibs(void)
 {
-	preempt_disable();
-
 	ibs_caps = get_ibs_caps();
+
 	if (!ibs_caps)
+		return;
+
+	if (ibs_eilvt_valid())
 		goto out;
 
-	if (__init_ibs_nmi() < 0)
-		ibs_caps = 0;
-	else
-		printk(KERN_INFO "oprofile: AMD IBS detected (0x%08x)\n", ibs_caps);
+	if (!force_ibs_eilvt_setup())
+		goto out;
+
+	/* Failed to setup ibs */
+	ibs_caps = 0;
+	return;
 
 out:
-	preempt_enable();
+	printk(KERN_INFO "oprofile: AMD IBS detected (0x%08x)\n", ibs_caps);
 }
 
 static int (*create_arch_files)(struct super_block *sb, struct dentry *root);
diff -druN linux-2.6.39-libre/arch/x86/pci/acpi.c linux-3.0-rc7-libre/arch/x86/pci/acpi.c
--- linux-2.6.39-libre/arch/x86/pci/acpi.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/pci/acpi.c	2011-07-11 19:51:52.000000000 -0400
@@ -188,7 +188,7 @@
 	return false;
 }
 
-static void coalesce_windows(struct pci_root_info *info, int type)
+static void coalesce_windows(struct pci_root_info *info, unsigned long type)
 {
 	int i, j;
 	struct resource *res1, *res2;
diff -druN linux-2.6.39-libre/arch/x86/pci/direct.c linux-3.0-rc7-libre/arch/x86/pci/direct.c
--- linux-2.6.39-libre/arch/x86/pci/direct.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/pci/direct.c	2011-07-11 19:51:52.000000000 -0400
@@ -280,12 +280,9 @@
 
 int __init pci_direct_probe(void)
 {
-	struct resource *region, *region2;
-
 	if ((pci_probe & PCI_PROBE_CONF1) == 0)
 		goto type2;
-	region = request_region(0xCF8, 8, "PCI conf1");
-	if (!region)
+	if (!request_region(0xCF8, 8, "PCI conf1"))
 		goto type2;
 
 	if (pci_check_type1()) {
@@ -293,16 +290,14 @@
 		port_cf9_safe = true;
 		return 1;
 	}
-	release_resource(region);
+	release_region(0xCF8, 8);
 
  type2:
 	if ((pci_probe & PCI_PROBE_CONF2) == 0)
 		return 0;
-	region = request_region(0xCF8, 4, "PCI conf2");
-	if (!region)
+	if (!request_region(0xCF8, 4, "PCI conf2"))
 		return 0;
-	region2 = request_region(0xC000, 0x1000, "PCI conf2");
-	if (!region2)
+	if (!request_region(0xC000, 0x1000, "PCI conf2"))
 		goto fail2;
 
 	if (pci_check_type2()) {
@@ -311,8 +306,8 @@
 		return 2;
 	}
 
-	release_resource(region2);
+	release_region(0xC000, 0x1000);
  fail2:
-	release_resource(region);
+	release_region(0xCF8, 4);
 	return 0;
 }
diff -druN linux-2.6.39-libre/arch/x86/pci/irq.c linux-3.0-rc7-libre/arch/x86/pci/irq.c
--- linux-2.6.39-libre/arch/x86/pci/irq.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/pci/irq.c	2011-07-11 19:51:52.000000000 -0400
@@ -602,7 +602,9 @@
 	||  (device >= PCI_DEVICE_ID_INTEL_COUGARPOINT_LPC_MIN && 
 	     device <= PCI_DEVICE_ID_INTEL_COUGARPOINT_LPC_MAX)
 	||  (device >= PCI_DEVICE_ID_INTEL_DH89XXCC_LPC_MIN &&
-	     device <= PCI_DEVICE_ID_INTEL_DH89XXCC_LPC_MAX)) {
+	     device <= PCI_DEVICE_ID_INTEL_DH89XXCC_LPC_MAX)
+	||  (device >= PCI_DEVICE_ID_INTEL_PANTHERPOINT_LPC_MIN &&
+	     device <= PCI_DEVICE_ID_INTEL_PANTHERPOINT_LPC_MAX)) {
 		r->name = "PIIX/ICH";
 		r->get = pirq_piix_get;
 		r->set = pirq_piix_set;
diff -druN linux-2.6.39-libre/arch/x86/pci/mmconfig-shared.c linux-3.0-rc7-libre/arch/x86/pci/mmconfig-shared.c
--- linux-2.6.39-libre/arch/x86/pci/mmconfig-shared.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/pci/mmconfig-shared.c	2011-07-11 19:51:52.000000000 -0400
@@ -606,6 +606,16 @@
 	if (list_empty(&pci_mmcfg_list))
 		return;
 
+	if (pcibios_last_bus < 0) {
+		const struct pci_mmcfg_region *cfg;
+
+		list_for_each_entry(cfg, &pci_mmcfg_list, list) {
+			if (cfg->segment)
+				break;
+			pcibios_last_bus = cfg->end_bus;
+		}
+	}
+
 	if (pci_mmcfg_arch_init())
 		pci_probe = (pci_probe & ~PCI_PROBE_MASK) | PCI_PROBE_MMCONF;
 	else {
diff -druN linux-2.6.39-libre/arch/x86/pci/xen.c linux-3.0-rc7-libre/arch/x86/pci/xen.c
--- linux-2.6.39-libre/arch/x86/pci/xen.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/pci/xen.c	2011-07-11 19:51:52.000000000 -0400
@@ -108,7 +108,8 @@
 		}
 		irq = xen_bind_pirq_msi_to_irq(dev, msidesc, pirq, 0,
 					       (type == PCI_CAP_ID_MSIX) ?
-					       "msi-x" : "msi");
+					       "msi-x" : "msi",
+					       DOMID_SELF);
 		if (irq < 0)
 			goto error;
 		dev_dbg(&dev->dev,
@@ -148,7 +149,8 @@
 		irq = xen_bind_pirq_msi_to_irq(dev, msidesc, v[i], 0,
 					       (type == PCI_CAP_ID_MSIX) ?
 					       "pcifront-msi-x" :
-					       "pcifront-msi");
+					       "pcifront-msi",
+						DOMID_SELF);
 		if (irq < 0)
 			goto free;
 		i++;
@@ -190,9 +192,16 @@
 
 	list_for_each_entry(msidesc, &dev->msi_list, list) {
 		struct physdev_map_pirq map_irq;
+		domid_t domid;
+
+		domid = ret = xen_find_device_domain_owner(dev);
+		/* N.B. Casting int's -ENODEV to uint16_t results in 0xFFED,
+		 * hence check ret value for < 0. */
+		if (ret < 0)
+			domid = DOMID_SELF;
 
 		memset(&map_irq, 0, sizeof(map_irq));
-		map_irq.domid = DOMID_SELF;
+		map_irq.domid = domid;
 		map_irq.type = MAP_PIRQ_TYPE_MSI;
 		map_irq.index = -1;
 		map_irq.pirq = -1;
@@ -215,14 +224,16 @@
 
 		ret = HYPERVISOR_physdev_op(PHYSDEVOP_map_pirq, &map_irq);
 		if (ret) {
-			dev_warn(&dev->dev, "xen map irq failed %d\n", ret);
+			dev_warn(&dev->dev, "xen map irq failed %d for %d domain\n",
+				 ret, domid);
 			goto out;
 		}
 
 		ret = xen_bind_pirq_msi_to_irq(dev, msidesc,
 					       map_irq.pirq, map_irq.index,
 					       (type == PCI_CAP_ID_MSIX) ?
-					       "msi-x" : "msi");
+					       "msi-x" : "msi",
+						domid);
 		if (ret < 0)
 			goto out;
 	}
@@ -316,7 +327,7 @@
 }
 
 #ifdef CONFIG_XEN_DOM0
-static int xen_register_pirq(u32 gsi, int triggering)
+static int xen_register_pirq(u32 gsi, int gsi_override, int triggering)
 {
 	int rc, pirq, irq = -1;
 	struct physdev_map_pirq map_irq;
@@ -333,16 +344,18 @@
 		shareable = 1;
 		name = "ioapic-level";
 	}
-
 	pirq = xen_allocate_pirq_gsi(gsi);
 	if (pirq < 0)
 		goto out;
 
-	irq = xen_bind_pirq_gsi_to_irq(gsi, pirq, shareable, name);
+	if (gsi_override >= 0)
+		irq = xen_bind_pirq_gsi_to_irq(gsi_override, pirq, shareable, name);
+	else
+		irq = xen_bind_pirq_gsi_to_irq(gsi, pirq, shareable, name);
 	if (irq < 0)
 		goto out;
 
-	printk(KERN_DEBUG "xen: --> pirq=%d -> irq=%d\n", pirq, irq);
+	printk(KERN_DEBUG "xen: --> pirq=%d -> irq=%d (gsi=%d)\n", pirq, irq, gsi);
 
 	map_irq.domid = DOMID_SELF;
 	map_irq.type = MAP_PIRQ_TYPE_GSI;
@@ -359,7 +372,7 @@
 	return irq;
 }
 
-static int xen_register_gsi(u32 gsi, int triggering, int polarity)
+static int xen_register_gsi(u32 gsi, int gsi_override, int triggering, int polarity)
 {
 	int rc, irq;
 	struct physdev_setup_gsi setup_gsi;
@@ -370,7 +383,7 @@
 	printk(KERN_DEBUG "xen: registering gsi %u triggering %d polarity %d\n",
 			gsi, triggering, polarity);
 
-	irq = xen_register_pirq(gsi, triggering);
+	irq = xen_register_pirq(gsi, gsi_override, triggering);
 
 	setup_gsi.gsi = gsi;
 	setup_gsi.triggering = (triggering == ACPI_EDGE_SENSITIVE ? 0 : 1);
@@ -392,6 +405,8 @@
 	int rc;
 	int trigger, polarity;
 	int gsi = acpi_sci_override_gsi;
+	int irq = -1;
+	int gsi_override = -1;
 
 	if (!gsi)
 		return;
@@ -408,7 +423,25 @@
 	printk(KERN_INFO "xen: sci override: global_irq=%d trigger=%d "
 			"polarity=%d\n", gsi, trigger, polarity);
 
-	gsi = xen_register_gsi(gsi, trigger, polarity);
+	/* Before we bind the GSI to a Linux IRQ, check whether
+	 * we need to override it with bus_irq (IRQ) value. Usually for
+	 * IRQs below IRQ_LEGACY_IRQ this holds IRQ == GSI, as so:
+	 *  ACPI: INT_SRC_OVR (bus 0 bus_irq 9 global_irq 9 low level)
+	 * but there are oddballs where the IRQ != GSI:
+	 *  ACPI: INT_SRC_OVR (bus 0 bus_irq 9 global_irq 20 low level)
+	 * which ends up being: gsi_to_irq[9] == 20
+	 * (which is what acpi_gsi_to_irq ends up calling when starting the
+	 * the ACPI interpreter and keels over since IRQ 9 has not been
+	 * setup as we had setup IRQ 20 for it).
+	 */
+	/* Check whether the GSI != IRQ */
+	if (acpi_gsi_to_irq(gsi, &irq) == 0) {
+		if (irq >= 0 && irq != gsi)
+			/* Bugger, we MUST have that IRQ. */
+			gsi_override = irq;
+	}
+
+	gsi = xen_register_gsi(gsi, gsi_override, trigger, polarity);
 	printk(KERN_INFO "xen: acpi sci %d\n", gsi);
 
 	return;
@@ -417,7 +450,7 @@
 static int acpi_register_gsi_xen(struct device *dev, u32 gsi,
 				 int trigger, int polarity)
 {
-	return xen_register_gsi(gsi, trigger, polarity);
+	return xen_register_gsi(gsi, -1 /* no GSI override */, trigger, polarity);
 }
 
 static int __init pci_xen_initial_domain(void)
@@ -456,8 +489,83 @@
 		if (acpi_get_override_irq(irq, &trigger, &polarity) == -1)
 			continue;
 
-		xen_register_pirq(irq,
+		xen_register_pirq(irq, -1 /* no GSI override */,
 			trigger ? ACPI_LEVEL_SENSITIVE : ACPI_EDGE_SENSITIVE);
 	}
 }
 #endif
+
+#ifdef CONFIG_XEN_DOM0
+struct xen_device_domain_owner {
+	domid_t domain;
+	struct pci_dev *dev;
+	struct list_head list;
+};
+
+static DEFINE_SPINLOCK(dev_domain_list_spinlock);
+static struct list_head dev_domain_list = LIST_HEAD_INIT(dev_domain_list);
+
+static struct xen_device_domain_owner *find_device(struct pci_dev *dev)
+{
+	struct xen_device_domain_owner *owner;
+
+	list_for_each_entry(owner, &dev_domain_list, list) {
+		if (owner->dev == dev)
+			return owner;
+	}
+	return NULL;
+}
+
+int xen_find_device_domain_owner(struct pci_dev *dev)
+{
+	struct xen_device_domain_owner *owner;
+	int domain = -ENODEV;
+
+	spin_lock(&dev_domain_list_spinlock);
+	owner = find_device(dev);
+	if (owner)
+		domain = owner->domain;
+	spin_unlock(&dev_domain_list_spinlock);
+	return domain;
+}
+EXPORT_SYMBOL_GPL(xen_find_device_domain_owner);
+
+int xen_register_device_domain_owner(struct pci_dev *dev, uint16_t domain)
+{
+	struct xen_device_domain_owner *owner;
+
+	owner = kzalloc(sizeof(struct xen_device_domain_owner), GFP_KERNEL);
+	if (!owner)
+		return -ENODEV;
+
+	spin_lock(&dev_domain_list_spinlock);
+	if (find_device(dev)) {
+		spin_unlock(&dev_domain_list_spinlock);
+		kfree(owner);
+		return -EEXIST;
+	}
+	owner->domain = domain;
+	owner->dev = dev;
+	list_add_tail(&owner->list, &dev_domain_list);
+	spin_unlock(&dev_domain_list_spinlock);
+	return 0;
+}
+EXPORT_SYMBOL_GPL(xen_register_device_domain_owner);
+
+int xen_unregister_device_domain_owner(struct pci_dev *dev)
+{
+	struct xen_device_domain_owner *owner;
+
+	spin_lock(&dev_domain_list_spinlock);
+	owner = find_device(dev);
+	if (!owner) {
+		spin_unlock(&dev_domain_list_spinlock);
+		return -ENODEV;
+	}
+	list_del(&owner->list);
+	spin_unlock(&dev_domain_list_spinlock);
+	kfree(owner);
+	return 0;
+}
+EXPORT_SYMBOL_GPL(xen_unregister_device_domain_owner);
+#endif
diff -druN linux-2.6.39-libre/arch/x86/platform/efi/efi_64.c linux-3.0-rc7-libre/arch/x86/platform/efi/efi_64.c
--- linux-2.6.39-libre/arch/x86/platform/efi/efi_64.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/platform/efi/efi_64.c	2011-07-11 19:51:52.000000000 -0400
@@ -41,22 +41,7 @@
 static pgd_t save_pgd __initdata;
 static unsigned long efi_flags __initdata;
 
-static void __init early_mapping_set_exec(unsigned long start,
-					  unsigned long end,
-					  int executable)
-{
-	unsigned long num_pages;
-
-	start &= PMD_MASK;
-	end = (end + PMD_SIZE - 1) & PMD_MASK;
-	num_pages = (end - start) >> PAGE_SHIFT;
-	if (executable)
-		set_memory_x((unsigned long)__va(start), num_pages);
-	else
-		set_memory_nx((unsigned long)__va(start), num_pages);
-}
-
-static void __init early_runtime_code_mapping_set_exec(int executable)
+static void __init early_code_mapping_set_exec(int executable)
 {
 	efi_memory_desc_t *md;
 	void *p;
@@ -64,14 +49,12 @@
 	if (!(__supported_pte_mask & _PAGE_NX))
 		return;
 
-	/* Make EFI runtime service code area executable */
+	/* Make EFI service code area executable */
 	for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) {
 		md = p;
-		if (md->type == EFI_RUNTIME_SERVICES_CODE) {
-			unsigned long end;
-			end = md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT);
-			early_mapping_set_exec(md->phys_addr, end, executable);
-		}
+		if (md->type == EFI_RUNTIME_SERVICES_CODE ||
+		    md->type == EFI_BOOT_SERVICES_CODE)
+			efi_set_executable(md, executable);
 	}
 }
 
@@ -79,7 +62,7 @@
 {
 	unsigned long vaddress;
 
-	early_runtime_code_mapping_set_exec(1);
+	early_code_mapping_set_exec(1);
 	local_irq_save(efi_flags);
 	vaddress = (unsigned long)__va(0x0UL);
 	save_pgd = *pgd_offset_k(0x0UL);
@@ -95,7 +78,7 @@
 	set_pgd(pgd_offset_k(0x0UL), save_pgd);
 	__flush_tlb_all();
 	local_irq_restore(efi_flags);
-	early_runtime_code_mapping_set_exec(0);
+	early_code_mapping_set_exec(0);
 }
 
 void __iomem *__init efi_ioremap(unsigned long phys_addr, unsigned long size,
@@ -107,8 +90,10 @@
 		return ioremap(phys_addr, size);
 
 	last_map_pfn = init_memory_mapping(phys_addr, phys_addr + size);
-	if ((last_map_pfn << PAGE_SHIFT) < phys_addr + size)
-		return NULL;
+	if ((last_map_pfn << PAGE_SHIFT) < phys_addr + size) {
+		unsigned long top = last_map_pfn << PAGE_SHIFT;
+		efi_ioremap(top, size - (top - phys_addr), type);
+	}
 
 	return (void __iomem *)__va(phys_addr);
 }
diff -druN linux-2.6.39-libre/arch/x86/platform/efi/efi.c linux-3.0-rc7-libre/arch/x86/platform/efi/efi.c
--- linux-2.6.39-libre/arch/x86/platform/efi/efi.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/platform/efi/efi.c	2011-07-11 19:51:52.000000000 -0400
@@ -145,17 +145,6 @@
 		       data_size, data);
 }
 
-static efi_status_t virt_efi_set_virtual_address_map(
-	unsigned long memory_map_size,
-	unsigned long descriptor_size,
-	u32 descriptor_version,
-	efi_memory_desc_t *virtual_map)
-{
-	return efi_call_virt4(set_virtual_address_map,
-			      memory_map_size, descriptor_size,
-			      descriptor_version, virtual_map);
-}
-
 static efi_status_t __init phys_efi_set_virtual_address_map(
 	unsigned long memory_map_size,
 	unsigned long descriptor_size,
@@ -315,6 +304,61 @@
 }
 #endif  /*  EFI_DEBUG  */
 
+void __init efi_reserve_boot_services(void)
+{
+	void *p;
+
+	for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) {
+		efi_memory_desc_t *md = p;
+		u64 start = md->phys_addr;
+		u64 size = md->num_pages << EFI_PAGE_SHIFT;
+
+		if (md->type != EFI_BOOT_SERVICES_CODE &&
+		    md->type != EFI_BOOT_SERVICES_DATA)
+			continue;
+		/* Only reserve where possible:
+		 * - Not within any already allocated areas
+		 * - Not over any memory area (really needed, if above?)
+		 * - Not within any part of the kernel
+		 * - Not the bios reserved area
+		*/
+		if ((start+size >= virt_to_phys(_text)
+				&& start <= virt_to_phys(_end)) ||
+			!e820_all_mapped(start, start+size, E820_RAM) ||
+			memblock_x86_check_reserved_size(&start, &size,
+							1<<EFI_PAGE_SHIFT)) {
+			/* Could not reserve, skip it */
+			md->num_pages = 0;
+			memblock_dbg(PFX "Could not reserve boot range "
+					"[0x%010llx-0x%010llx]\n",
+						start, start+size-1);
+		} else
+			memblock_x86_reserve_range(start, start+size,
+							"EFI Boot");
+	}
+}
+
+static void __init efi_free_boot_services(void)
+{
+	void *p;
+
+	for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) {
+		efi_memory_desc_t *md = p;
+		unsigned long long start = md->phys_addr;
+		unsigned long long size = md->num_pages << EFI_PAGE_SHIFT;
+
+		if (md->type != EFI_BOOT_SERVICES_CODE &&
+		    md->type != EFI_BOOT_SERVICES_DATA)
+			continue;
+
+		/* Could not reserve boot area */
+		if (!size)
+			continue;
+
+		free_bootmem_late(start, size);
+	}
+}
+
 void __init efi_init(void)
 {
 	efi_config_table_t *config_tables;
@@ -460,19 +504,30 @@
 	x86_platform.set_wallclock = efi_set_rtc_mmss;
 #endif
 
-	/* Setup for EFI runtime service */
-	reboot_type = BOOT_EFI;
-
 #if EFI_DEBUG
 	print_efi_memmap();
 #endif
 }
 
+void __init efi_set_executable(efi_memory_desc_t *md, bool executable)
+{
+	u64 addr, npages;
+
+	addr = md->virt_addr;
+	npages = md->num_pages;
+
+	memrange_efi_to_native(&addr, &npages);
+
+	if (executable)
+		set_memory_x(addr, npages);
+	else
+		set_memory_nx(addr, npages);
+}
+
 static void __init runtime_code_page_mkexec(void)
 {
 	efi_memory_desc_t *md;
 	void *p;
-	u64 addr, npages;
 
 	/* Make EFI runtime service code area executable */
 	for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) {
@@ -481,10 +536,7 @@
 		if (md->type != EFI_RUNTIME_SERVICES_CODE)
 			continue;
 
-		addr = md->virt_addr;
-		npages = md->num_pages;
-		memrange_efi_to_native(&addr, &npages);
-		set_memory_x(addr, npages);
+		efi_set_executable(md, true);
 	}
 }
 
@@ -498,16 +550,47 @@
  */
 void __init efi_enter_virtual_mode(void)
 {
-	efi_memory_desc_t *md;
+	efi_memory_desc_t *md, *prev_md = NULL;
 	efi_status_t status;
 	unsigned long size;
 	u64 end, systab, addr, npages, end_pfn;
-	void *p, *va;
+	void *p, *va, *new_memmap = NULL;
+	int count = 0;
 
 	efi.systab = NULL;
+
+	/* Merge contiguous regions of the same type and attribute */
 	for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) {
+		u64 prev_size;
 		md = p;
-		if (!(md->attribute & EFI_MEMORY_RUNTIME))
+
+		if (!prev_md) {
+			prev_md = md;
+			continue;
+		}
+
+		if (prev_md->type != md->type ||
+		    prev_md->attribute != md->attribute) {
+			prev_md = md;
+			continue;
+		}
+
+		prev_size = prev_md->num_pages << EFI_PAGE_SHIFT;
+
+		if (md->phys_addr == (prev_md->phys_addr + prev_size)) {
+			prev_md->num_pages += md->num_pages;
+			md->type = EFI_RESERVED_TYPE;
+			md->attribute = 0;
+			continue;
+		}
+		prev_md = md;
+	}
+
+	for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) {
+		md = p;
+		if (!(md->attribute & EFI_MEMORY_RUNTIME) &&
+		    md->type != EFI_BOOT_SERVICES_CODE &&
+		    md->type != EFI_BOOT_SERVICES_DATA)
 			continue;
 
 		size = md->num_pages << EFI_PAGE_SHIFT;
@@ -541,15 +624,21 @@
 			systab += md->virt_addr - md->phys_addr;
 			efi.systab = (efi_system_table_t *) (unsigned long) systab;
 		}
+		new_memmap = krealloc(new_memmap,
+				      (count + 1) * memmap.desc_size,
+				      GFP_KERNEL);
+		memcpy(new_memmap + (count * memmap.desc_size), md,
+		       memmap.desc_size);
+		count++;
 	}
 
 	BUG_ON(!efi.systab);
 
 	status = phys_efi_set_virtual_address_map(
-		memmap.desc_size * memmap.nr_map,
+		memmap.desc_size * count,
 		memmap.desc_size,
 		memmap.desc_version,
-		memmap.phys_map);
+		(efi_memory_desc_t *)__pa(new_memmap));
 
 	if (status != EFI_SUCCESS) {
 		printk(KERN_ALERT "Unable to switch EFI into virtual mode "
@@ -558,6 +647,13 @@
 	}
 
 	/*
+	 * Thankfully, it does seem that no runtime services other than
+	 * SetVirtualAddressMap() will touch boot services code, so we can
+	 * get rid of it all at this point
+	 */
+	efi_free_boot_services();
+
+	/*
 	 * Now that EFI is in virtual mode, update the function
 	 * pointers in the runtime service table to the new virtual addresses.
 	 *
@@ -572,11 +668,12 @@
 	efi.set_variable = virt_efi_set_variable;
 	efi.get_next_high_mono_count = virt_efi_get_next_high_mono_count;
 	efi.reset_system = virt_efi_reset_system;
-	efi.set_virtual_address_map = virt_efi_set_virtual_address_map;
+	efi.set_virtual_address_map = NULL;
 	if (__supported_pte_mask & _PAGE_NX)
 		runtime_code_page_mkexec();
 	early_iounmap(memmap.map, memmap.nr_map * memmap.desc_size);
 	memmap.map = NULL;
+	kfree(new_memmap);
 }
 
 /*
diff -druN linux-2.6.39-libre/arch/x86/platform/mrst/mrst.c linux-3.0-rc7-libre/arch/x86/platform/mrst/mrst.c
--- linux-2.6.39-libre/arch/x86/platform/mrst/mrst.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/platform/mrst/mrst.c	2011-07-11 19:51:52.000000000 -0400
@@ -194,7 +194,7 @@
 	return 0;
 }
 
-void __init mrst_time_init(void)
+static void __init mrst_time_init(void)
 {
 	sfi_table_parse(SFI_SIG_MTMR, NULL, NULL, sfi_parse_mtmr);
 	switch (mrst_timer_options) {
@@ -216,7 +216,7 @@
 	apbt_time_init();
 }
 
-void __cpuinit mrst_arch_setup(void)
+static void __cpuinit mrst_arch_setup(void)
 {
 	if (boot_cpu_data.x86 == 6 && boot_cpu_data.x86_model == 0x27)
 		__mrst_cpu_chip = MRST_CPU_CHIP_PENWELL;
diff -druN linux-2.6.39-libre/arch/x86/platform/olpc/Makefile linux-3.0-rc7-libre/arch/x86/platform/olpc/Makefile
--- linux-2.6.39-libre/arch/x86/platform/olpc/Makefile	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/platform/olpc/Makefile	2011-07-11 19:51:52.000000000 -0400
@@ -1,4 +1,2 @@
-obj-$(CONFIG_OLPC)		+= olpc.o
+obj-$(CONFIG_OLPC)		+= olpc.o olpc_ofw.o olpc_dt.o
 obj-$(CONFIG_OLPC_XO1)		+= olpc-xo1.o
-obj-$(CONFIG_OLPC)		+= olpc_ofw.o
-obj-$(CONFIG_OF_PROMTREE)	+= olpc_dt.o
diff -druN linux-2.6.39-libre/arch/x86/platform/olpc/olpc.c linux-3.0-rc7-libre/arch/x86/platform/olpc/olpc.c
--- linux-2.6.39-libre/arch/x86/platform/olpc/olpc.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/platform/olpc/olpc.c	2011-07-11 19:51:52.000000000 -0400
@@ -18,6 +18,7 @@
 #include <linux/io.h>
 #include <linux/string.h>
 #include <linux/platform_device.h>
+#include <linux/of.h>
 
 #include <asm/geode.h>
 #include <asm/setup.h>
@@ -187,41 +188,43 @@
 }
 EXPORT_SYMBOL_GPL(olpc_ec_cmd);
 
-static bool __init check_ofw_architecture(void)
+static bool __init check_ofw_architecture(struct device_node *root)
 {
-	size_t propsize;
-	char olpc_arch[5];
-	const void *args[] = { NULL, "architecture", olpc_arch, (void *)5 };
-	void *res[] = { &propsize };
+	const char *olpc_arch;
+	int propsize;
 
-	if (olpc_ofw("getprop", args, res)) {
-		printk(KERN_ERR "ofw: getprop call failed!\n");
-		return false;
-	}
+	olpc_arch = of_get_property(root, "architecture", &propsize);
 	return propsize == 5 && strncmp("OLPC", olpc_arch, 5) == 0;
 }
 
-static u32 __init get_board_revision(void)
+static u32 __init get_board_revision(struct device_node *root)
 {
-	size_t propsize;
-	__be32 rev;
-	const void *args[] = { NULL, "board-revision-int", &rev, (void *)4 };
-	void *res[] = { &propsize };
+	int propsize;
+	const __be32 *rev;
 
-	if (olpc_ofw("getprop", args, res) || propsize != 4) {
-		printk(KERN_ERR "ofw: getprop call failed!\n");
-		return cpu_to_be32(0);
-	}
-	return be32_to_cpu(rev);
+	rev = of_get_property(root, "board-revision-int", &propsize);
+	if (propsize != 4)
+		return 0;
+
+	return be32_to_cpu(*rev);
 }
 
 static bool __init platform_detect(void)
 {
-	if (!check_ofw_architecture())
+	struct device_node *root = of_find_node_by_path("/");
+	bool success;
+
+	if (!root)
 		return false;
-	olpc_platform_info.flags |= OLPC_F_PRESENT;
-	olpc_platform_info.boardrev = get_board_revision();
-	return true;
+
+	success = check_ofw_architecture(root);
+	if (success) {
+		olpc_platform_info.boardrev = get_board_revision(root);
+		olpc_platform_info.flags |= OLPC_F_PRESENT;
+	}
+
+	of_node_put(root);
+	return success;
 }
 
 static int __init add_xo1_platform_devices(void)
diff -druN linux-2.6.39-libre/arch/x86/platform/olpc/olpc_dt.c linux-3.0-rc7-libre/arch/x86/platform/olpc/olpc_dt.c
--- linux-2.6.39-libre/arch/x86/platform/olpc/olpc_dt.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/platform/olpc/olpc_dt.c	2011-07-11 19:51:52.000000000 -0400
@@ -19,7 +19,9 @@
 #include <linux/kernel.h>
 #include <linux/bootmem.h>
 #include <linux/of.h>
+#include <linux/of_platform.h>
 #include <linux/of_pdt.h>
+#include <asm/olpc.h>
 #include <asm/olpc_ofw.h>
 
 static phandle __init olpc_dt_getsibling(phandle node)
@@ -180,3 +182,20 @@
 	pr_info("PROM DT: Built device tree with %u bytes of memory.\n",
 			prom_early_allocated);
 }
+
+/* A list of DT node/bus matches that we want to expose as platform devices */
+static struct of_device_id __initdata of_ids[] = {
+	{ .compatible = "olpc,xo1-battery" },
+	{ .compatible = "olpc,xo1-dcon" },
+	{ .compatible = "olpc,xo1-rtc" },
+	{},
+};
+
+static int __init olpc_create_platform_devices(void)
+{
+	if (machine_is_olpc())
+		return of_platform_bus_probe(NULL, of_ids, NULL);
+	else
+		return 0;
+}
+device_initcall(olpc_create_platform_devices);
diff -druN linux-2.6.39-libre/arch/x86/platform/uv/tlb_uv.c linux-3.0-rc7-libre/arch/x86/platform/uv/tlb_uv.c
--- linux-2.6.39-libre/arch/x86/platform/uv/tlb_uv.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/platform/uv/tlb_uv.c	2011-07-11 19:51:52.000000000 -0400
@@ -1,7 +1,7 @@
 /*
  *	SGI UltraViolet TLB flush routines.
  *
- *	(c) 2008-2010 Cliff Wickman <cpw@sgi.com>, SGI.
+ *	(c) 2008-2011 Cliff Wickman <cpw@sgi.com>, SGI.
  *
  *	This code is released under the GNU General Public License version 2 or
  *	later.
@@ -35,6 +35,7 @@
 		5242880,
 		167772160
 };
+
 static int timeout_us;
 static int nobau;
 static int baudisabled;
@@ -42,20 +43,70 @@
 static cycles_t congested_cycles;
 
 /* tunables: */
-static int max_bau_concurrent = MAX_BAU_CONCURRENT;
-static int max_bau_concurrent_constant = MAX_BAU_CONCURRENT;
-static int plugged_delay = PLUGGED_DELAY;
-static int plugsb4reset = PLUGSB4RESET;
-static int timeoutsb4reset = TIMEOUTSB4RESET;
-static int ipi_reset_limit = IPI_RESET_LIMIT;
-static int complete_threshold = COMPLETE_THRESHOLD;
-static int congested_response_us = CONGESTED_RESPONSE_US;
-static int congested_reps = CONGESTED_REPS;
-static int congested_period = CONGESTED_PERIOD;
+static int max_concurr		= MAX_BAU_CONCURRENT;
+static int max_concurr_const	= MAX_BAU_CONCURRENT;
+static int plugged_delay	= PLUGGED_DELAY;
+static int plugsb4reset		= PLUGSB4RESET;
+static int timeoutsb4reset	= TIMEOUTSB4RESET;
+static int ipi_reset_limit	= IPI_RESET_LIMIT;
+static int complete_threshold	= COMPLETE_THRESHOLD;
+static int congested_respns_us	= CONGESTED_RESPONSE_US;
+static int congested_reps	= CONGESTED_REPS;
+static int congested_period	= CONGESTED_PERIOD;
+
+static struct tunables tunables[] = {
+	{&max_concurr, MAX_BAU_CONCURRENT}, /* must be [0] */
+	{&plugged_delay, PLUGGED_DELAY},
+	{&plugsb4reset, PLUGSB4RESET},
+	{&timeoutsb4reset, TIMEOUTSB4RESET},
+	{&ipi_reset_limit, IPI_RESET_LIMIT},
+	{&complete_threshold, COMPLETE_THRESHOLD},
+	{&congested_respns_us, CONGESTED_RESPONSE_US},
+	{&congested_reps, CONGESTED_REPS},
+	{&congested_period, CONGESTED_PERIOD}
+};
+
 static struct dentry *tunables_dir;
 static struct dentry *tunables_file;
 
-static int __init setup_nobau(char *arg)
+/* these correspond to the statistics printed by ptc_seq_show() */
+static char *stat_description[] = {
+	"sent:     number of shootdown messages sent",
+	"stime:    time spent sending messages",
+	"numuvhubs: number of hubs targeted with shootdown",
+	"numuvhubs16: number times 16 or more hubs targeted",
+	"numuvhubs8: number times 8 or more hubs targeted",
+	"numuvhubs4: number times 4 or more hubs targeted",
+	"numuvhubs2: number times 2 or more hubs targeted",
+	"numuvhubs1: number times 1 hub targeted",
+	"numcpus:  number of cpus targeted with shootdown",
+	"dto:      number of destination timeouts",
+	"retries:  destination timeout retries sent",
+	"rok:   :  destination timeouts successfully retried",
+	"resetp:   ipi-style resource resets for plugs",
+	"resett:   ipi-style resource resets for timeouts",
+	"giveup:   fall-backs to ipi-style shootdowns",
+	"sto:      number of source timeouts",
+	"bz:       number of stay-busy's",
+	"throt:    number times spun in throttle",
+	"swack:   image of UVH_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE",
+	"recv:     shootdown messages received",
+	"rtime:    time spent processing messages",
+	"all:      shootdown all-tlb messages",
+	"one:      shootdown one-tlb messages",
+	"mult:     interrupts that found multiple messages",
+	"none:     interrupts that found no messages",
+	"retry:    number of retry messages processed",
+	"canc:     number messages canceled by retries",
+	"nocan:    number retries that found nothing to cancel",
+	"reset:    number of ipi-style reset requests processed",
+	"rcan:     number messages canceled by reset requests",
+	"disable:  number times use of the BAU was disabled",
+	"enable:   number times use of the BAU was re-enabled"
+};
+
+static int __init
+setup_nobau(char *arg)
 {
 	nobau = 1;
 	return 0;
@@ -63,7 +114,7 @@
 early_param("nobau", setup_nobau);
 
 /* base pnode in this partition */
-static int uv_partition_base_pnode __read_mostly;
+static int uv_base_pnode __read_mostly;
 /* position of pnode (which is nasid>>1): */
 static int uv_nshift __read_mostly;
 static unsigned long uv_mmask __read_mostly;
@@ -109,60 +160,52 @@
  * clear of the Timeout bit (as well) will free the resource. No reply will
  * be sent (the hardware will only do one reply per message).
  */
-static inline void uv_reply_to_message(struct msg_desc *mdp,
-				       struct bau_control *bcp)
+static void reply_to_message(struct msg_desc *mdp, struct bau_control *bcp)
 {
 	unsigned long dw;
-	struct bau_payload_queue_entry *msg;
+	struct bau_pq_entry *msg;
 
 	msg = mdp->msg;
 	if (!msg->canceled) {
-		dw = (msg->sw_ack_vector << UV_SW_ACK_NPENDING) |
-						msg->sw_ack_vector;
-		uv_write_local_mmr(
-				UVH_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE_ALIAS, dw);
+		dw = (msg->swack_vec << UV_SW_ACK_NPENDING) | msg->swack_vec;
+		write_mmr_sw_ack(dw);
 	}
 	msg->replied_to = 1;
-	msg->sw_ack_vector = 0;
+	msg->swack_vec = 0;
 }
 
 /*
  * Process the receipt of a RETRY message
  */
-static inline void uv_bau_process_retry_msg(struct msg_desc *mdp,
-					    struct bau_control *bcp)
+static void bau_process_retry_msg(struct msg_desc *mdp,
+					struct bau_control *bcp)
 {
 	int i;
 	int cancel_count = 0;
-	int slot2;
 	unsigned long msg_res;
 	unsigned long mmr = 0;
-	struct bau_payload_queue_entry *msg;
-	struct bau_payload_queue_entry *msg2;
-	struct ptc_stats *stat;
+	struct bau_pq_entry *msg = mdp->msg;
+	struct bau_pq_entry *msg2;
+	struct ptc_stats *stat = bcp->statp;
 
-	msg = mdp->msg;
-	stat = bcp->statp;
 	stat->d_retries++;
 	/*
 	 * cancel any message from msg+1 to the retry itself
 	 */
 	for (msg2 = msg+1, i = 0; i < DEST_Q_SIZE; msg2++, i++) {
-		if (msg2 > mdp->va_queue_last)
-			msg2 = mdp->va_queue_first;
+		if (msg2 > mdp->queue_last)
+			msg2 = mdp->queue_first;
 		if (msg2 == msg)
 			break;
 
-		/* same conditions for cancellation as uv_do_reset */
+		/* same conditions for cancellation as do_reset */
 		if ((msg2->replied_to == 0) && (msg2->canceled == 0) &&
-		    (msg2->sw_ack_vector) && ((msg2->sw_ack_vector &
-			msg->sw_ack_vector) == 0) &&
+		    (msg2->swack_vec) && ((msg2->swack_vec &
+			msg->swack_vec) == 0) &&
 		    (msg2->sending_cpu == msg->sending_cpu) &&
 		    (msg2->msg_type != MSG_NOOP)) {
-			slot2 = msg2 - mdp->va_queue_first;
-			mmr = uv_read_local_mmr
-				(UVH_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE);
-			msg_res = msg2->sw_ack_vector;
+			mmr = read_mmr_sw_ack();
+			msg_res = msg2->swack_vec;
 			/*
 			 * This is a message retry; clear the resources held
 			 * by the previous message only if they timed out.
@@ -170,6 +213,7 @@
 			 * situation to report.
 			 */
 			if (mmr & (msg_res << UV_SW_ACK_NPENDING)) {
+				unsigned long mr;
 				/*
 				 * is the resource timed out?
 				 * make everyone ignore the cancelled message.
@@ -177,10 +221,8 @@
 				msg2->canceled = 1;
 				stat->d_canceled++;
 				cancel_count++;
-				uv_write_local_mmr(
-				    UVH_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE_ALIAS,
-					(msg_res << UV_SW_ACK_NPENDING) |
-					 msg_res);
+				mr = (msg_res << UV_SW_ACK_NPENDING) | msg_res;
+				write_mmr_sw_ack(mr);
 			}
 		}
 	}
@@ -192,20 +234,19 @@
  * Do all the things a cpu should do for a TLB shootdown message.
  * Other cpu's may come here at the same time for this message.
  */
-static void uv_bau_process_message(struct msg_desc *mdp,
-				   struct bau_control *bcp)
+static void bau_process_message(struct msg_desc *mdp,
+					struct bau_control *bcp)
 {
-	int msg_ack_count;
 	short socket_ack_count = 0;
-	struct ptc_stats *stat;
-	struct bau_payload_queue_entry *msg;
+	short *sp;
+	struct atomic_short *asp;
+	struct ptc_stats *stat = bcp->statp;
+	struct bau_pq_entry *msg = mdp->msg;
 	struct bau_control *smaster = bcp->socket_master;
 
 	/*
 	 * This must be a normal message, or retry of a normal message
 	 */
-	msg = mdp->msg;
-	stat = bcp->statp;
 	if (msg->address == TLB_FLUSH_ALL) {
 		local_flush_tlb();
 		stat->d_alltlb++;
@@ -222,30 +263,32 @@
 	 * cpu number.
 	 */
 	if (msg->msg_type == MSG_RETRY && bcp == bcp->uvhub_master)
-		uv_bau_process_retry_msg(mdp, bcp);
+		bau_process_retry_msg(mdp, bcp);
 
 	/*
-	 * This is a sw_ack message, so we have to reply to it.
+	 * This is a swack message, so we have to reply to it.
 	 * Count each responding cpu on the socket. This avoids
 	 * pinging the count's cache line back and forth between
 	 * the sockets.
 	 */
-	socket_ack_count = atomic_add_short_return(1, (struct atomic_short *)
-			&smaster->socket_acknowledge_count[mdp->msg_slot]);
+	sp = &smaster->socket_acknowledge_count[mdp->msg_slot];
+	asp = (struct atomic_short *)sp;
+	socket_ack_count = atom_asr(1, asp);
 	if (socket_ack_count == bcp->cpus_in_socket) {
+		int msg_ack_count;
 		/*
 		 * Both sockets dump their completed count total into
 		 * the message's count.
 		 */
 		smaster->socket_acknowledge_count[mdp->msg_slot] = 0;
-		msg_ack_count = atomic_add_short_return(socket_ack_count,
-				(struct atomic_short *)&msg->acknowledge_count);
+		asp = (struct atomic_short *)&msg->acknowledge_count;
+		msg_ack_count = atom_asr(socket_ack_count, asp);
 
 		if (msg_ack_count == bcp->cpus_in_uvhub) {
 			/*
 			 * All cpus in uvhub saw it; reply
 			 */
-			uv_reply_to_message(mdp, bcp);
+			reply_to_message(mdp, bcp);
 		}
 	}
 
@@ -268,62 +311,51 @@
  * Last resort when we get a large number of destination timeouts is
  * to clear resources held by a given cpu.
  * Do this with IPI so that all messages in the BAU message queue
- * can be identified by their nonzero sw_ack_vector field.
+ * can be identified by their nonzero swack_vec field.
  *
  * This is entered for a single cpu on the uvhub.
  * The sender want's this uvhub to free a specific message's
- * sw_ack resources.
+ * swack resources.
  */
-static void
-uv_do_reset(void *ptr)
+static void do_reset(void *ptr)
 {
 	int i;
-	int slot;
-	int count = 0;
-	unsigned long mmr;
-	unsigned long msg_res;
-	struct bau_control *bcp;
-	struct reset_args *rap;
-	struct bau_payload_queue_entry *msg;
-	struct ptc_stats *stat;
+	struct bau_control *bcp = &per_cpu(bau_control, smp_processor_id());
+	struct reset_args *rap = (struct reset_args *)ptr;
+	struct bau_pq_entry *msg;
+	struct ptc_stats *stat = bcp->statp;
 
-	bcp = &per_cpu(bau_control, smp_processor_id());
-	rap = (struct reset_args *)ptr;
-	stat = bcp->statp;
 	stat->d_resets++;
-
 	/*
 	 * We're looking for the given sender, and
-	 * will free its sw_ack resource.
+	 * will free its swack resource.
 	 * If all cpu's finally responded after the timeout, its
 	 * message 'replied_to' was set.
 	 */
-	for (msg = bcp->va_queue_first, i = 0; i < DEST_Q_SIZE; msg++, i++) {
-		/* uv_do_reset: same conditions for cancellation as
-		   uv_bau_process_retry_msg() */
+	for (msg = bcp->queue_first, i = 0; i < DEST_Q_SIZE; msg++, i++) {
+		unsigned long msg_res;
+		/* do_reset: same conditions for cancellation as
+		   bau_process_retry_msg() */
 		if ((msg->replied_to == 0) &&
 		    (msg->canceled == 0) &&
 		    (msg->sending_cpu == rap->sender) &&
-		    (msg->sw_ack_vector) &&
+		    (msg->swack_vec) &&
 		    (msg->msg_type != MSG_NOOP)) {
+			unsigned long mmr;
+			unsigned long mr;
 			/*
 			 * make everyone else ignore this message
 			 */
 			msg->canceled = 1;
-			slot = msg - bcp->va_queue_first;
-			count++;
 			/*
 			 * only reset the resource if it is still pending
 			 */
-			mmr = uv_read_local_mmr
-					(UVH_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE);
-			msg_res = msg->sw_ack_vector;
+			mmr = read_mmr_sw_ack();
+			msg_res = msg->swack_vec;
+			mr = (msg_res << UV_SW_ACK_NPENDING) | msg_res;
 			if (mmr & msg_res) {
 				stat->d_rcanceled++;
-				uv_write_local_mmr(
-				    UVH_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE_ALIAS,
-					(msg_res << UV_SW_ACK_NPENDING) |
-					 msg_res);
+				write_mmr_sw_ack(mr);
 			}
 		}
 	}
@@ -334,39 +366,38 @@
  * Use IPI to get all target uvhubs to release resources held by
  * a given sending cpu number.
  */
-static void uv_reset_with_ipi(struct bau_target_uvhubmask *distribution,
-			      int sender)
+static void reset_with_ipi(struct bau_targ_hubmask *distribution, int sender)
 {
 	int uvhub;
-	int cpu;
+	int maskbits;
 	cpumask_t mask;
 	struct reset_args reset_args;
 
 	reset_args.sender = sender;
-
 	cpus_clear(mask);
 	/* find a single cpu for each uvhub in this distribution mask */
-	for (uvhub = 0;
-		    uvhub < sizeof(struct bau_target_uvhubmask) * BITSPERBYTE;
-		    uvhub++) {
+	maskbits = sizeof(struct bau_targ_hubmask) * BITSPERBYTE;
+	for (uvhub = 0; uvhub < maskbits; uvhub++) {
+		int cpu;
 		if (!bau_uvhub_isset(uvhub, distribution))
 			continue;
 		/* find a cpu for this uvhub */
 		cpu = uvhub_to_first_cpu(uvhub);
 		cpu_set(cpu, mask);
 	}
-	/* IPI all cpus; Preemption is already disabled */
-	smp_call_function_many(&mask, uv_do_reset, (void *)&reset_args, 1);
+
+	/* IPI all cpus; preemption is already disabled */
+	smp_call_function_many(&mask, do_reset, (void *)&reset_args, 1);
 	return;
 }
 
-static inline unsigned long
-cycles_2_us(unsigned long long cyc)
+static inline unsigned long cycles_2_us(unsigned long long cyc)
 {
 	unsigned long long ns;
 	unsigned long us;
-	ns =  (cyc * per_cpu(cyc2ns, smp_processor_id()))
-						>> CYC2NS_SCALE_FACTOR;
+	int cpu = smp_processor_id();
+
+	ns =  (cyc * per_cpu(cyc2ns, cpu)) >> CYC2NS_SCALE_FACTOR;
 	us = ns / 1000;
 	return us;
 }
@@ -376,56 +407,56 @@
  * leaves uvhub_quiesce set so that no new broadcasts are started by
  * bau_flush_send_and_wait()
  */
-static inline void
-quiesce_local_uvhub(struct bau_control *hmaster)
+static inline void quiesce_local_uvhub(struct bau_control *hmaster)
 {
-	atomic_add_short_return(1, (struct atomic_short *)
-		 &hmaster->uvhub_quiesce);
+	atom_asr(1, (struct atomic_short *)&hmaster->uvhub_quiesce);
 }
 
 /*
  * mark this quiet-requestor as done
  */
-static inline void
-end_uvhub_quiesce(struct bau_control *hmaster)
+static inline void end_uvhub_quiesce(struct bau_control *hmaster)
 {
-	atomic_add_short_return(-1, (struct atomic_short *)
-		&hmaster->uvhub_quiesce);
+	atom_asr(-1, (struct atomic_short *)&hmaster->uvhub_quiesce);
+}
+
+static unsigned long uv1_read_status(unsigned long mmr_offset, int right_shift)
+{
+	unsigned long descriptor_status;
+
+	descriptor_status = uv_read_local_mmr(mmr_offset);
+	descriptor_status >>= right_shift;
+	descriptor_status &= UV_ACT_STATUS_MASK;
+	return descriptor_status;
 }
 
 /*
  * Wait for completion of a broadcast software ack message
  * return COMPLETE, RETRY(PLUGGED or TIMEOUT) or GIVEUP
  */
-static int uv_wait_completion(struct bau_desc *bau_desc,
-	unsigned long mmr_offset, int right_shift, int this_cpu,
-	struct bau_control *bcp, struct bau_control *smaster, long try)
+static int uv1_wait_completion(struct bau_desc *bau_desc,
+				unsigned long mmr_offset, int right_shift,
+				struct bau_control *bcp, long try)
 {
 	unsigned long descriptor_status;
-	cycles_t ttime;
+	cycles_t ttm;
 	struct ptc_stats *stat = bcp->statp;
-	struct bau_control *hmaster;
-
-	hmaster = bcp->uvhub_master;
 
+	descriptor_status = uv1_read_status(mmr_offset, right_shift);
 	/* spin on the status MMR, waiting for it to go idle */
-	while ((descriptor_status = (((unsigned long)
-		uv_read_local_mmr(mmr_offset) >>
-			right_shift) & UV_ACT_STATUS_MASK)) !=
-			DESC_STATUS_IDLE) {
+	while ((descriptor_status != DS_IDLE)) {
 		/*
-		 * Our software ack messages may be blocked because there are
-		 * no swack resources available.  As long as none of them
-		 * has timed out hardware will NACK our message and its
-		 * state will stay IDLE.
+		 * Our software ack messages may be blocked because
+		 * there are no swack resources available.  As long
+		 * as none of them has timed out hardware will NACK
+		 * our message and its state will stay IDLE.
 		 */
-		if (descriptor_status == DESC_STATUS_SOURCE_TIMEOUT) {
+		if (descriptor_status == DS_SOURCE_TIMEOUT) {
 			stat->s_stimeout++;
 			return FLUSH_GIVEUP;
-		} else if (descriptor_status ==
-					DESC_STATUS_DESTINATION_TIMEOUT) {
+		} else if (descriptor_status == DS_DESTINATION_TIMEOUT) {
 			stat->s_dtimeout++;
-			ttime = get_cycles();
+			ttm = get_cycles();
 
 			/*
 			 * Our retries may be blocked by all destination
@@ -433,8 +464,7 @@
 			 * pending.  In that case hardware returns the
 			 * ERROR that looks like a destination timeout.
 			 */
-			if (cycles_2_us(ttime - bcp->send_message) <
-							timeout_us) {
+			if (cycles_2_us(ttm - bcp->send_message) < timeout_us) {
 				bcp->conseccompletes = 0;
 				return FLUSH_RETRY_PLUGGED;
 			}
@@ -447,80 +477,160 @@
 			 */
 			cpu_relax();
 		}
+		descriptor_status = uv1_read_status(mmr_offset, right_shift);
 	}
 	bcp->conseccompletes++;
 	return FLUSH_COMPLETE;
 }
 
-static inline cycles_t
-sec_2_cycles(unsigned long sec)
+/*
+ * UV2 has an extra bit of status in the ACTIVATION_STATUS_2 register.
+ */
+static unsigned long uv2_read_status(unsigned long offset, int rshft, int cpu)
 {
-	unsigned long ns;
-	cycles_t cyc;
+	unsigned long descriptor_status;
+	unsigned long descriptor_status2;
 
-	ns = sec * 1000000000;
-	cyc = (ns << CYC2NS_SCALE_FACTOR)/(per_cpu(cyc2ns, smp_processor_id()));
-	return cyc;
+	descriptor_status = ((read_lmmr(offset) >> rshft) & UV_ACT_STATUS_MASK);
+	descriptor_status2 = (read_mmr_uv2_status() >> cpu) & 0x1UL;
+	descriptor_status = (descriptor_status << 1) | descriptor_status2;
+	return descriptor_status;
+}
+
+static int uv2_wait_completion(struct bau_desc *bau_desc,
+				unsigned long mmr_offset, int right_shift,
+				struct bau_control *bcp, long try)
+{
+	unsigned long descriptor_stat;
+	cycles_t ttm;
+	int cpu = bcp->uvhub_cpu;
+	struct ptc_stats *stat = bcp->statp;
+
+	descriptor_stat = uv2_read_status(mmr_offset, right_shift, cpu);
+
+	/* spin on the status MMR, waiting for it to go idle */
+	while (descriptor_stat != UV2H_DESC_IDLE) {
+		/*
+		 * Our software ack messages may be blocked because
+		 * there are no swack resources available.  As long
+		 * as none of them has timed out hardware will NACK
+		 * our message and its state will stay IDLE.
+		 */
+		if ((descriptor_stat == UV2H_DESC_SOURCE_TIMEOUT) ||
+		    (descriptor_stat == UV2H_DESC_DEST_STRONG_NACK) ||
+		    (descriptor_stat == UV2H_DESC_DEST_PUT_ERR)) {
+			stat->s_stimeout++;
+			return FLUSH_GIVEUP;
+		} else if (descriptor_stat == UV2H_DESC_DEST_TIMEOUT) {
+			stat->s_dtimeout++;
+			ttm = get_cycles();
+			/*
+			 * Our retries may be blocked by all destination
+			 * swack resources being consumed, and a timeout
+			 * pending.  In that case hardware returns the
+			 * ERROR that looks like a destination timeout.
+			 */
+			if (cycles_2_us(ttm - bcp->send_message) < timeout_us) {
+				bcp->conseccompletes = 0;
+				return FLUSH_RETRY_PLUGGED;
+			}
+			bcp->conseccompletes = 0;
+			return FLUSH_RETRY_TIMEOUT;
+		} else {
+			/*
+			 * descriptor_stat is still BUSY
+			 */
+			cpu_relax();
+		}
+		descriptor_stat = uv2_read_status(mmr_offset, right_shift, cpu);
+	}
+	bcp->conseccompletes++;
+	return FLUSH_COMPLETE;
 }
 
 /*
- * conditionally add 1 to *v, unless *v is >= u
- * return 0 if we cannot add 1 to *v because it is >= u
- * return 1 if we can add 1 to *v because it is < u
- * the add is atomic
- *
- * This is close to atomic_add_unless(), but this allows the 'u' value
- * to be lowered below the current 'v'.  atomic_add_unless can only stop
- * on equal.
+ * There are 2 status registers; each and array[32] of 2 bits. Set up for
+ * which register to read and position in that register based on cpu in
+ * current hub.
  */
-static inline int atomic_inc_unless_ge(spinlock_t *lock, atomic_t *v, int u)
+static int wait_completion(struct bau_desc *bau_desc,
+				struct bau_control *bcp, long try)
 {
-	spin_lock(lock);
-	if (atomic_read(v) >= u) {
-		spin_unlock(lock);
-		return 0;
+	int right_shift;
+	unsigned long mmr_offset;
+	int cpu = bcp->uvhub_cpu;
+
+	if (cpu < UV_CPUS_PER_AS) {
+		mmr_offset = UVH_LB_BAU_SB_ACTIVATION_STATUS_0;
+		right_shift = cpu * UV_ACT_STATUS_SIZE;
+	} else {
+		mmr_offset = UVH_LB_BAU_SB_ACTIVATION_STATUS_1;
+		right_shift = ((cpu - UV_CPUS_PER_AS) * UV_ACT_STATUS_SIZE);
 	}
-	atomic_inc(v);
-	spin_unlock(lock);
-	return 1;
+
+	if (is_uv1_hub())
+		return uv1_wait_completion(bau_desc, mmr_offset, right_shift,
+								bcp, try);
+	else
+		return uv2_wait_completion(bau_desc, mmr_offset, right_shift,
+								bcp, try);
+}
+
+static inline cycles_t sec_2_cycles(unsigned long sec)
+{
+	unsigned long ns;
+	cycles_t cyc;
+
+	ns = sec * 1000000000;
+	cyc = (ns << CYC2NS_SCALE_FACTOR)/(per_cpu(cyc2ns, smp_processor_id()));
+	return cyc;
 }
 
 /*
- * Our retries are blocked by all destination swack resources being
+ * Our retries are blocked by all destination sw ack resources being
  * in use, and a timeout is pending. In that case hardware immediately
  * returns the ERROR that looks like a destination timeout.
  */
-static void
-destination_plugged(struct bau_desc *bau_desc, struct bau_control *bcp,
+static void destination_plugged(struct bau_desc *bau_desc,
+			struct bau_control *bcp,
 			struct bau_control *hmaster, struct ptc_stats *stat)
 {
 	udelay(bcp->plugged_delay);
 	bcp->plugged_tries++;
+
 	if (bcp->plugged_tries >= bcp->plugsb4reset) {
 		bcp->plugged_tries = 0;
+
 		quiesce_local_uvhub(hmaster);
+
 		spin_lock(&hmaster->queue_lock);
-		uv_reset_with_ipi(&bau_desc->distribution, bcp->cpu);
+		reset_with_ipi(&bau_desc->distribution, bcp->cpu);
 		spin_unlock(&hmaster->queue_lock);
+
 		end_uvhub_quiesce(hmaster);
+
 		bcp->ipi_attempts++;
 		stat->s_resets_plug++;
 	}
 }
 
-static void
-destination_timeout(struct bau_desc *bau_desc, struct bau_control *bcp,
-			struct bau_control *hmaster, struct ptc_stats *stat)
+static void destination_timeout(struct bau_desc *bau_desc,
+			struct bau_control *bcp, struct bau_control *hmaster,
+			struct ptc_stats *stat)
 {
-	hmaster->max_bau_concurrent = 1;
+	hmaster->max_concurr = 1;
 	bcp->timeout_tries++;
 	if (bcp->timeout_tries >= bcp->timeoutsb4reset) {
 		bcp->timeout_tries = 0;
+
 		quiesce_local_uvhub(hmaster);
+
 		spin_lock(&hmaster->queue_lock);
-		uv_reset_with_ipi(&bau_desc->distribution, bcp->cpu);
+		reset_with_ipi(&bau_desc->distribution, bcp->cpu);
 		spin_unlock(&hmaster->queue_lock);
+
 		end_uvhub_quiesce(hmaster);
+
 		bcp->ipi_attempts++;
 		stat->s_resets_timeout++;
 	}
@@ -530,34 +640,104 @@
  * Completions are taking a very long time due to a congested numalink
  * network.
  */
-static void
-disable_for_congestion(struct bau_control *bcp, struct ptc_stats *stat)
+static void disable_for_congestion(struct bau_control *bcp,
+					struct ptc_stats *stat)
 {
-	int tcpu;
-	struct bau_control *tbcp;
-
 	/* let only one cpu do this disabling */
 	spin_lock(&disable_lock);
+
 	if (!baudisabled && bcp->period_requests &&
 	    ((bcp->period_time / bcp->period_requests) > congested_cycles)) {
+		int tcpu;
+		struct bau_control *tbcp;
 		/* it becomes this cpu's job to turn on the use of the
 		   BAU again */
 		baudisabled = 1;
 		bcp->set_bau_off = 1;
-		bcp->set_bau_on_time = get_cycles() +
-			sec_2_cycles(bcp->congested_period);
+		bcp->set_bau_on_time = get_cycles();
+		bcp->set_bau_on_time += sec_2_cycles(bcp->cong_period);
 		stat->s_bau_disabled++;
 		for_each_present_cpu(tcpu) {
 			tbcp = &per_cpu(bau_control, tcpu);
-				tbcp->baudisabled = 1;
+			tbcp->baudisabled = 1;
 		}
 	}
+
 	spin_unlock(&disable_lock);
 }
 
-/**
- * uv_flush_send_and_wait
- *
+static void count_max_concurr(int stat, struct bau_control *bcp,
+				struct bau_control *hmaster)
+{
+	bcp->plugged_tries = 0;
+	bcp->timeout_tries = 0;
+	if (stat != FLUSH_COMPLETE)
+		return;
+	if (bcp->conseccompletes <= bcp->complete_threshold)
+		return;
+	if (hmaster->max_concurr >= hmaster->max_concurr_const)
+		return;
+	hmaster->max_concurr++;
+}
+
+static void record_send_stats(cycles_t time1, cycles_t time2,
+		struct bau_control *bcp, struct ptc_stats *stat,
+		int completion_status, int try)
+{
+	cycles_t elapsed;
+
+	if (time2 > time1) {
+		elapsed = time2 - time1;
+		stat->s_time += elapsed;
+
+		if ((completion_status == FLUSH_COMPLETE) && (try == 1)) {
+			bcp->period_requests++;
+			bcp->period_time += elapsed;
+			if ((elapsed > congested_cycles) &&
+			    (bcp->period_requests > bcp->cong_reps))
+				disable_for_congestion(bcp, stat);
+		}
+	} else
+		stat->s_requestor--;
+
+	if (completion_status == FLUSH_COMPLETE && try > 1)
+		stat->s_retriesok++;
+	else if (completion_status == FLUSH_GIVEUP)
+		stat->s_giveup++;
+}
+
+/*
+ * Because of a uv1 hardware bug only a limited number of concurrent
+ * requests can be made.
+ */
+static void uv1_throttle(struct bau_control *hmaster, struct ptc_stats *stat)
+{
+	spinlock_t *lock = &hmaster->uvhub_lock;
+	atomic_t *v;
+
+	v = &hmaster->active_descriptor_count;
+	if (!atomic_inc_unless_ge(lock, v, hmaster->max_concurr)) {
+		stat->s_throttles++;
+		do {
+			cpu_relax();
+		} while (!atomic_inc_unless_ge(lock, v, hmaster->max_concurr));
+	}
+}
+
+/*
+ * Handle the completion status of a message send.
+ */
+static void handle_cmplt(int completion_status, struct bau_desc *bau_desc,
+			struct bau_control *bcp, struct bau_control *hmaster,
+			struct ptc_stats *stat)
+{
+	if (completion_status == FLUSH_RETRY_PLUGGED)
+		destination_plugged(bau_desc, bcp, hmaster, stat);
+	else if (completion_status == FLUSH_RETRY_TIMEOUT)
+		destination_timeout(bau_desc, bcp, hmaster, stat);
+}
+
+/*
  * Send a broadcast and wait for it to complete.
  *
  * The flush_mask contains the cpus the broadcast is to be sent to including
@@ -568,44 +748,23 @@
  * returned to the kernel.
  */
 int uv_flush_send_and_wait(struct bau_desc *bau_desc,
-			   struct cpumask *flush_mask, struct bau_control *bcp)
+			struct cpumask *flush_mask, struct bau_control *bcp)
 {
-	int right_shift;
-	int completion_status = 0;
 	int seq_number = 0;
+	int completion_stat = 0;
 	long try = 0;
-	int cpu = bcp->uvhub_cpu;
-	int this_cpu = bcp->cpu;
-	unsigned long mmr_offset;
 	unsigned long index;
 	cycles_t time1;
 	cycles_t time2;
-	cycles_t elapsed;
 	struct ptc_stats *stat = bcp->statp;
-	struct bau_control *smaster = bcp->socket_master;
 	struct bau_control *hmaster = bcp->uvhub_master;
 
-	if (!atomic_inc_unless_ge(&hmaster->uvhub_lock,
-			&hmaster->active_descriptor_count,
-			hmaster->max_bau_concurrent)) {
-		stat->s_throttles++;
-		do {
-			cpu_relax();
-		} while (!atomic_inc_unless_ge(&hmaster->uvhub_lock,
-			&hmaster->active_descriptor_count,
-			hmaster->max_bau_concurrent));
-	}
+	if (is_uv1_hub())
+		uv1_throttle(hmaster, stat);
+
 	while (hmaster->uvhub_quiesce)
 		cpu_relax();
 
-	if (cpu < UV_CPUS_PER_ACT_STATUS) {
-		mmr_offset = UVH_LB_BAU_SB_ACTIVATION_STATUS_0;
-		right_shift = cpu * UV_ACT_STATUS_SIZE;
-	} else {
-		mmr_offset = UVH_LB_BAU_SB_ACTIVATION_STATUS_1;
-		right_shift =
-		    ((cpu - UV_CPUS_PER_ACT_STATUS) * UV_ACT_STATUS_SIZE);
-	}
 	time1 = get_cycles();
 	do {
 		if (try == 0) {
@@ -615,64 +774,134 @@
 			bau_desc->header.msg_type = MSG_RETRY;
 			stat->s_retry_messages++;
 		}
+
 		bau_desc->header.sequence = seq_number;
-		index = (1UL << UVH_LB_BAU_SB_ACTIVATION_CONTROL_PUSH_SHFT) |
-			bcp->uvhub_cpu;
+		index = (1UL << AS_PUSH_SHIFT) | bcp->uvhub_cpu;
 		bcp->send_message = get_cycles();
-		uv_write_local_mmr(UVH_LB_BAU_SB_ACTIVATION_CONTROL, index);
+
+		write_mmr_activation(index);
+
 		try++;
-		completion_status = uv_wait_completion(bau_desc, mmr_offset,
-			right_shift, this_cpu, bcp, smaster, try);
+		completion_stat = wait_completion(bau_desc, bcp, try);
+
+		handle_cmplt(completion_stat, bau_desc, bcp, hmaster, stat);
 
-		if (completion_status == FLUSH_RETRY_PLUGGED) {
-			destination_plugged(bau_desc, bcp, hmaster, stat);
-		} else if (completion_status == FLUSH_RETRY_TIMEOUT) {
-			destination_timeout(bau_desc, bcp, hmaster, stat);
-		}
 		if (bcp->ipi_attempts >= bcp->ipi_reset_limit) {
 			bcp->ipi_attempts = 0;
-			completion_status = FLUSH_GIVEUP;
+			completion_stat = FLUSH_GIVEUP;
 			break;
 		}
 		cpu_relax();
-	} while ((completion_status == FLUSH_RETRY_PLUGGED) ||
-		 (completion_status == FLUSH_RETRY_TIMEOUT));
+	} while ((completion_stat == FLUSH_RETRY_PLUGGED) ||
+		 (completion_stat == FLUSH_RETRY_TIMEOUT));
+
 	time2 = get_cycles();
-	bcp->plugged_tries = 0;
-	bcp->timeout_tries = 0;
-	if ((completion_status == FLUSH_COMPLETE) &&
-	    (bcp->conseccompletes > bcp->complete_threshold) &&
-	    (hmaster->max_bau_concurrent <
-					hmaster->max_bau_concurrent_constant))
-			hmaster->max_bau_concurrent++;
+
+	count_max_concurr(completion_stat, bcp, hmaster);
+
 	while (hmaster->uvhub_quiesce)
 		cpu_relax();
+
 	atomic_dec(&hmaster->active_descriptor_count);
-	if (time2 > time1) {
-		elapsed = time2 - time1;
-		stat->s_time += elapsed;
-		if ((completion_status == FLUSH_COMPLETE) && (try == 1)) {
-			bcp->period_requests++;
-			bcp->period_time += elapsed;
-			if ((elapsed > congested_cycles) &&
-			    (bcp->period_requests > bcp->congested_reps)) {
-				disable_for_congestion(bcp, stat);
+
+	record_send_stats(time1, time2, bcp, stat, completion_stat, try);
+
+	if (completion_stat == FLUSH_GIVEUP)
+		return 1;
+	return 0;
+}
+
+/*
+ * The BAU is disabled. When the disabled time period has expired, the cpu
+ * that disabled it must re-enable it.
+ * Return 0 if it is re-enabled for all cpus.
+ */
+static int check_enable(struct bau_control *bcp, struct ptc_stats *stat)
+{
+	int tcpu;
+	struct bau_control *tbcp;
+
+	if (bcp->set_bau_off) {
+		if (get_cycles() >= bcp->set_bau_on_time) {
+			stat->s_bau_reenabled++;
+			baudisabled = 0;
+			for_each_present_cpu(tcpu) {
+				tbcp = &per_cpu(bau_control, tcpu);
+				tbcp->baudisabled = 0;
+				tbcp->period_requests = 0;
+				tbcp->period_time = 0;
 			}
+			return 0;
 		}
+	}
+	return -1;
+}
+
+static void record_send_statistics(struct ptc_stats *stat, int locals, int hubs,
+				int remotes, struct bau_desc *bau_desc)
+{
+	stat->s_requestor++;
+	stat->s_ntargcpu += remotes + locals;
+	stat->s_ntargremotes += remotes;
+	stat->s_ntarglocals += locals;
+
+	/* uvhub statistics */
+	hubs = bau_uvhub_weight(&bau_desc->distribution);
+	if (locals) {
+		stat->s_ntarglocaluvhub++;
+		stat->s_ntargremoteuvhub += (hubs - 1);
 	} else
-		stat->s_requestor--;
-	if (completion_status == FLUSH_COMPLETE && try > 1)
-		stat->s_retriesok++;
-	else if (completion_status == FLUSH_GIVEUP) {
-		stat->s_giveup++;
-		return 1;
+		stat->s_ntargremoteuvhub += hubs;
+
+	stat->s_ntarguvhub += hubs;
+
+	if (hubs >= 16)
+		stat->s_ntarguvhub16++;
+	else if (hubs >= 8)
+		stat->s_ntarguvhub8++;
+	else if (hubs >= 4)
+		stat->s_ntarguvhub4++;
+	else if (hubs >= 2)
+		stat->s_ntarguvhub2++;
+	else
+		stat->s_ntarguvhub1++;
+}
+
+/*
+ * Translate a cpu mask to the uvhub distribution mask in the BAU
+ * activation descriptor.
+ */
+static int set_distrib_bits(struct cpumask *flush_mask, struct bau_control *bcp,
+			struct bau_desc *bau_desc, int *localsp, int *remotesp)
+{
+	int cpu;
+	int pnode;
+	int cnt = 0;
+	struct hub_and_pnode *hpp;
+
+	for_each_cpu(cpu, flush_mask) {
+		/*
+		 * The distribution vector is a bit map of pnodes, relative
+		 * to the partition base pnode (and the partition base nasid
+		 * in the header).
+		 * Translate cpu to pnode and hub using a local memory array.
+		 */
+		hpp = &bcp->socket_master->thp[cpu];
+		pnode = hpp->pnode - bcp->partition_base_pnode;
+		bau_uvhub_set(pnode, &bau_desc->distribution);
+		cnt++;
+		if (hpp->uvhub == bcp->uvhub)
+			(*localsp)++;
+		else
+			(*remotesp)++;
 	}
+	if (!cnt)
+		return 1;
 	return 0;
 }
 
-/**
- * uv_flush_tlb_others - globally purge translation cache of a virtual
- * address or all TLB's
+/*
+ * globally purge translation cache of a virtual address or all TLB's
  * @cpumask: mask of all cpu's in which the address is to be removed
  * @mm: mm_struct containing virtual address range
  * @va: virtual address to be removed (or TLB_FLUSH_ALL for all TLB's on cpu)
@@ -696,20 +925,16 @@
  * done.  The returned pointer is valid till preemption is re-enabled.
  */
 const struct cpumask *uv_flush_tlb_others(const struct cpumask *cpumask,
-					  struct mm_struct *mm,
-					  unsigned long va, unsigned int cpu)
+				struct mm_struct *mm, unsigned long va,
+				unsigned int cpu)
 {
 	int locals = 0;
 	int remotes = 0;
 	int hubs = 0;
-	int tcpu;
-	int tpnode;
 	struct bau_desc *bau_desc;
 	struct cpumask *flush_mask;
 	struct ptc_stats *stat;
 	struct bau_control *bcp;
-	struct bau_control *tbcp;
-	struct hub_and_pnode *hpp;
 
 	/* kernel was booted 'nobau' */
 	if (nobau)
@@ -720,20 +945,8 @@
 
 	/* bau was disabled due to slow response */
 	if (bcp->baudisabled) {
-		/* the cpu that disabled it must re-enable it */
-		if (bcp->set_bau_off) {
-			if (get_cycles() >= bcp->set_bau_on_time) {
-				stat->s_bau_reenabled++;
-				baudisabled = 0;
-				for_each_present_cpu(tcpu) {
-					tbcp = &per_cpu(bau_control, tcpu);
-					tbcp->baudisabled = 0;
-					tbcp->period_requests = 0;
-					tbcp->period_time = 0;
-				}
-			}
-		}
-		return cpumask;
+		if (check_enable(bcp, stat))
+			return cpumask;
 	}
 
 	/*
@@ -744,59 +957,20 @@
 	flush_mask = (struct cpumask *)per_cpu(uv_flush_tlb_mask, cpu);
 	/* don't actually do a shootdown of the local cpu */
 	cpumask_andnot(flush_mask, cpumask, cpumask_of(cpu));
+
 	if (cpu_isset(cpu, *cpumask))
 		stat->s_ntargself++;
 
 	bau_desc = bcp->descriptor_base;
-	bau_desc += UV_ITEMS_PER_DESCRIPTOR * bcp->uvhub_cpu;
+	bau_desc += ITEMS_PER_DESC * bcp->uvhub_cpu;
 	bau_uvhubs_clear(&bau_desc->distribution, UV_DISTRIBUTION_SIZE);
-
-	for_each_cpu(tcpu, flush_mask) {
-		/*
-		 * The distribution vector is a bit map of pnodes, relative
-		 * to the partition base pnode (and the partition base nasid
-		 * in the header).
-		 * Translate cpu to pnode and hub using an array stored
-		 * in local memory.
-		 */
-		hpp = &bcp->socket_master->target_hub_and_pnode[tcpu];
-		tpnode = hpp->pnode - bcp->partition_base_pnode;
-		bau_uvhub_set(tpnode, &bau_desc->distribution);
-		if (hpp->uvhub == bcp->uvhub)
-			locals++;
-		else
-			remotes++;
-	}
-	if ((locals + remotes) == 0)
+	if (set_distrib_bits(flush_mask, bcp, bau_desc, &locals, &remotes))
 		return NULL;
-	stat->s_requestor++;
-	stat->s_ntargcpu += remotes + locals;
-	stat->s_ntargremotes += remotes;
-	stat->s_ntarglocals += locals;
-	remotes = bau_uvhub_weight(&bau_desc->distribution);
 
-	/* uvhub statistics */
-	hubs = bau_uvhub_weight(&bau_desc->distribution);
-	if (locals) {
-		stat->s_ntarglocaluvhub++;
-		stat->s_ntargremoteuvhub += (hubs - 1);
-	} else
-		stat->s_ntargremoteuvhub += hubs;
-	stat->s_ntarguvhub += hubs;
-	if (hubs >= 16)
-		stat->s_ntarguvhub16++;
-	else if (hubs >= 8)
-		stat->s_ntarguvhub8++;
-	else if (hubs >= 4)
-		stat->s_ntarguvhub4++;
-	else if (hubs >= 2)
-		stat->s_ntarguvhub2++;
-	else
-		stat->s_ntarguvhub1++;
+	record_send_statistics(stat, locals, hubs, remotes, bau_desc);
 
 	bau_desc->payload.address = va;
 	bau_desc->payload.sending_cpu = cpu;
-
 	/*
 	 * uv_flush_send_and_wait returns 0 if all cpu's were messaged,
 	 * or 1 if it gave up and the original cpumask should be returned.
@@ -825,26 +999,31 @@
 {
 	int count = 0;
 	cycles_t time_start;
-	struct bau_payload_queue_entry *msg;
+	struct bau_pq_entry *msg;
 	struct bau_control *bcp;
 	struct ptc_stats *stat;
 	struct msg_desc msgdesc;
 
 	time_start = get_cycles();
+
 	bcp = &per_cpu(bau_control, smp_processor_id());
 	stat = bcp->statp;
-	msgdesc.va_queue_first = bcp->va_queue_first;
-	msgdesc.va_queue_last = bcp->va_queue_last;
+
+	msgdesc.queue_first = bcp->queue_first;
+	msgdesc.queue_last = bcp->queue_last;
+
 	msg = bcp->bau_msg_head;
-	while (msg->sw_ack_vector) {
+	while (msg->swack_vec) {
 		count++;
-		msgdesc.msg_slot = msg - msgdesc.va_queue_first;
-		msgdesc.sw_ack_slot = ffs(msg->sw_ack_vector) - 1;
+
+		msgdesc.msg_slot = msg - msgdesc.queue_first;
+		msgdesc.swack_slot = ffs(msg->swack_vec) - 1;
 		msgdesc.msg = msg;
-		uv_bau_process_message(&msgdesc, bcp);
+		bau_process_message(&msgdesc, bcp);
+
 		msg++;
-		if (msg > msgdesc.va_queue_last)
-			msg = msgdesc.va_queue_first;
+		if (msg > msgdesc.queue_last)
+			msg = msgdesc.queue_first;
 		bcp->bau_msg_head = msg;
 	}
 	stat->d_time += (get_cycles() - time_start);
@@ -852,18 +1031,17 @@
 		stat->d_nomsg++;
 	else if (count > 1)
 		stat->d_multmsg++;
+
 	ack_APIC_irq();
 }
 
 /*
- * uv_enable_timeouts
- *
- * Each target uvhub (i.e. a uvhub that has no cpu's) needs to have
+ * Each target uvhub (i.e. a uvhub that has cpu's) needs to have
  * shootdown message timeouts enabled.  The timeout does not cause
  * an interrupt, but causes an error message to be returned to
  * the sender.
  */
-static void __init uv_enable_timeouts(void)
+static void __init enable_timeouts(void)
 {
 	int uvhub;
 	int nuvhubs;
@@ -877,47 +1055,44 @@
 			continue;
 
 		pnode = uv_blade_to_pnode(uvhub);
-		mmr_image =
-		    uv_read_global_mmr64(pnode, UVH_LB_BAU_MISC_CONTROL);
+		mmr_image = read_mmr_misc_control(pnode);
 		/*
 		 * Set the timeout period and then lock it in, in three
 		 * steps; captures and locks in the period.
 		 *
 		 * To program the period, the SOFT_ACK_MODE must be off.
 		 */
-		mmr_image &= ~((unsigned long)1 <<
-		    UVH_LB_BAU_MISC_CONTROL_ENABLE_INTD_SOFT_ACK_MODE_SHFT);
-		uv_write_global_mmr64
-		    (pnode, UVH_LB_BAU_MISC_CONTROL, mmr_image);
+		mmr_image &= ~(1L << SOFTACK_MSHIFT);
+		write_mmr_misc_control(pnode, mmr_image);
 		/*
 		 * Set the 4-bit period.
 		 */
-		mmr_image &= ~((unsigned long)0xf <<
-		     UVH_LB_BAU_MISC_CONTROL_INTD_SOFT_ACK_TIMEOUT_PERIOD_SHFT);
-		mmr_image |= (UV_INTD_SOFT_ACK_TIMEOUT_PERIOD <<
-		     UVH_LB_BAU_MISC_CONTROL_INTD_SOFT_ACK_TIMEOUT_PERIOD_SHFT);
-		uv_write_global_mmr64
-		    (pnode, UVH_LB_BAU_MISC_CONTROL, mmr_image);
+		mmr_image &= ~((unsigned long)0xf << SOFTACK_PSHIFT);
+		mmr_image |= (SOFTACK_TIMEOUT_PERIOD << SOFTACK_PSHIFT);
+		write_mmr_misc_control(pnode, mmr_image);
 		/*
+		 * UV1:
 		 * Subsequent reversals of the timebase bit (3) cause an
 		 * immediate timeout of one or all INTD resources as
 		 * indicated in bits 2:0 (7 causes all of them to timeout).
 		 */
-		mmr_image |= ((unsigned long)1 <<
-		    UVH_LB_BAU_MISC_CONTROL_ENABLE_INTD_SOFT_ACK_MODE_SHFT);
-		uv_write_global_mmr64
-		    (pnode, UVH_LB_BAU_MISC_CONTROL, mmr_image);
+		mmr_image |= (1L << SOFTACK_MSHIFT);
+		if (is_uv2_hub()) {
+			mmr_image |= (1L << UV2_LEG_SHFT);
+			mmr_image |= (1L << UV2_EXT_SHFT);
+		}
+		write_mmr_misc_control(pnode, mmr_image);
 	}
 }
 
-static void *uv_ptc_seq_start(struct seq_file *file, loff_t *offset)
+static void *ptc_seq_start(struct seq_file *file, loff_t *offset)
 {
 	if (*offset < num_possible_cpus())
 		return offset;
 	return NULL;
 }
 
-static void *uv_ptc_seq_next(struct seq_file *file, void *data, loff_t *offset)
+static void *ptc_seq_next(struct seq_file *file, void *data, loff_t *offset)
 {
 	(*offset)++;
 	if (*offset < num_possible_cpus())
@@ -925,12 +1100,11 @@
 	return NULL;
 }
 
-static void uv_ptc_seq_stop(struct seq_file *file, void *data)
+static void ptc_seq_stop(struct seq_file *file, void *data)
 {
 }
 
-static inline unsigned long long
-microsec_2_cycles(unsigned long microsec)
+static inline unsigned long long usec_2_cycles(unsigned long microsec)
 {
 	unsigned long ns;
 	unsigned long long cyc;
@@ -941,29 +1115,27 @@
 }
 
 /*
- * Display the statistics thru /proc.
+ * Display the statistics thru /proc/sgi_uv/ptc_statistics
  * 'data' points to the cpu number
+ * Note: see the descriptions in stat_description[].
  */
-static int uv_ptc_seq_show(struct seq_file *file, void *data)
+static int ptc_seq_show(struct seq_file *file, void *data)
 {
 	struct ptc_stats *stat;
 	int cpu;
 
 	cpu = *(loff_t *)data;
-
 	if (!cpu) {
 		seq_printf(file,
 			"# cpu sent stime self locals remotes ncpus localhub ");
 		seq_printf(file,
 			"remotehub numuvhubs numuvhubs16 numuvhubs8 ");
 		seq_printf(file,
-			"numuvhubs4 numuvhubs2 numuvhubs1 dto ");
-		seq_printf(file,
-			"retries rok resetp resett giveup sto bz throt ");
+			"numuvhubs4 numuvhubs2 numuvhubs1 dto retries rok ");
 		seq_printf(file,
-			"sw_ack recv rtime all ");
+			"resetp resett giveup sto bz throt swack recv rtime ");
 		seq_printf(file,
-			"one mult none retry canc nocan reset rcan ");
+			"all one mult none retry canc nocan reset rcan ");
 		seq_printf(file,
 			"disable enable\n");
 	}
@@ -990,8 +1162,7 @@
 		/* destination side statistics */
 		seq_printf(file,
 			   "%lx %ld %ld %ld %ld %ld %ld %ld %ld %ld %ld %ld ",
-			   uv_read_global_mmr64(uv_cpu_to_pnode(cpu),
-					UVH_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE),
+			   read_gmmr_sw_ack(uv_cpu_to_pnode(cpu)),
 			   stat->d_requestee, cycles_2_us(stat->d_time),
 			   stat->d_alltlb, stat->d_onetlb, stat->d_multmsg,
 			   stat->d_nomsg, stat->d_retries, stat->d_canceled,
@@ -1000,7 +1171,6 @@
 		seq_printf(file, "%ld %ld\n",
 			stat->s_bau_disabled, stat->s_bau_reenabled);
 	}
-
 	return 0;
 }
 
@@ -1008,18 +1178,18 @@
  * Display the tunables thru debugfs
  */
 static ssize_t tunables_read(struct file *file, char __user *userbuf,
-						size_t count, loff_t *ppos)
+				size_t count, loff_t *ppos)
 {
 	char *buf;
 	int ret;
 
 	buf = kasprintf(GFP_KERNEL, "%s %s %s\n%d %d %d %d %d %d %d %d %d\n",
-		"max_bau_concurrent plugged_delay plugsb4reset",
+		"max_concur plugged_delay plugsb4reset",
 		"timeoutsb4reset ipi_reset_limit complete_threshold",
 		"congested_response_us congested_reps congested_period",
-		max_bau_concurrent, plugged_delay, plugsb4reset,
+		max_concurr, plugged_delay, plugsb4reset,
 		timeoutsb4reset, ipi_reset_limit, complete_threshold,
-		congested_response_us, congested_reps, congested_period);
+		congested_respns_us, congested_reps, congested_period);
 
 	if (!buf)
 		return -ENOMEM;
@@ -1030,13 +1200,16 @@
 }
 
 /*
- * -1: resetf the statistics
+ * handle a write to /proc/sgi_uv/ptc_statistics
+ * -1: reset the statistics
  *  0: display meaning of the statistics
  */
-static ssize_t uv_ptc_proc_write(struct file *file, const char __user *user,
-				 size_t count, loff_t *data)
+static ssize_t ptc_proc_write(struct file *file, const char __user *user,
+				size_t count, loff_t *data)
 {
 	int cpu;
+	int i;
+	int elements;
 	long input_arg;
 	char optstr[64];
 	struct ptc_stats *stat;
@@ -1046,79 +1219,18 @@
 	if (copy_from_user(optstr, user, count))
 		return -EFAULT;
 	optstr[count - 1] = '\0';
+
 	if (strict_strtol(optstr, 10, &input_arg) < 0) {
 		printk(KERN_DEBUG "%s is invalid\n", optstr);
 		return -EINVAL;
 	}
 
 	if (input_arg == 0) {
+		elements = sizeof(stat_description)/sizeof(*stat_description);
 		printk(KERN_DEBUG "# cpu:      cpu number\n");
 		printk(KERN_DEBUG "Sender statistics:\n");
-		printk(KERN_DEBUG
-		"sent:     number of shootdown messages sent\n");
-		printk(KERN_DEBUG
-		"stime:    time spent sending messages\n");
-		printk(KERN_DEBUG
-		"numuvhubs: number of hubs targeted with shootdown\n");
-		printk(KERN_DEBUG
-		"numuvhubs16: number times 16 or more hubs targeted\n");
-		printk(KERN_DEBUG
-		"numuvhubs8: number times 8 or more hubs targeted\n");
-		printk(KERN_DEBUG
-		"numuvhubs4: number times 4 or more hubs targeted\n");
-		printk(KERN_DEBUG
-		"numuvhubs2: number times 2 or more hubs targeted\n");
-		printk(KERN_DEBUG
-		"numuvhubs1: number times 1 hub targeted\n");
-		printk(KERN_DEBUG
-		"numcpus:  number of cpus targeted with shootdown\n");
-		printk(KERN_DEBUG
-		"dto:      number of destination timeouts\n");
-		printk(KERN_DEBUG
-		"retries:  destination timeout retries sent\n");
-		printk(KERN_DEBUG
-		"rok:   :  destination timeouts successfully retried\n");
-		printk(KERN_DEBUG
-		"resetp:   ipi-style resource resets for plugs\n");
-		printk(KERN_DEBUG
-		"resett:   ipi-style resource resets for timeouts\n");
-		printk(KERN_DEBUG
-		"giveup:   fall-backs to ipi-style shootdowns\n");
-		printk(KERN_DEBUG
-		"sto:      number of source timeouts\n");
-		printk(KERN_DEBUG
-		"bz:       number of stay-busy's\n");
-		printk(KERN_DEBUG
-		"throt:    number times spun in throttle\n");
-		printk(KERN_DEBUG "Destination side statistics:\n");
-		printk(KERN_DEBUG
-		"sw_ack:   image of UVH_LB_BAU_INTD_SOFTWARE_ACKNOWLEDGE\n");
-		printk(KERN_DEBUG
-		"recv:     shootdown messages received\n");
-		printk(KERN_DEBUG
-		"rtime:    time spent processing messages\n");
-		printk(KERN_DEBUG
-		"all:      shootdown all-tlb messages\n");
-		printk(KERN_DEBUG
-		"one:      shootdown one-tlb messages\n");
-		printk(KERN_DEBUG
-		"mult:     interrupts that found multiple messages\n");
-		printk(KERN_DEBUG
-		"none:     interrupts that found no messages\n");
-		printk(KERN_DEBUG
-		"retry:    number of retry messages processed\n");
-		printk(KERN_DEBUG
-		"canc:     number messages canceled by retries\n");
-		printk(KERN_DEBUG
-		"nocan:    number retries that found nothing to cancel\n");
-		printk(KERN_DEBUG
-		"reset:    number of ipi-style reset requests processed\n");
-		printk(KERN_DEBUG
-		"rcan:     number messages canceled by reset requests\n");
-		printk(KERN_DEBUG
-		"disable:  number times use of the BAU was disabled\n");
-		printk(KERN_DEBUG
-		"enable:   number times use of the BAU was re-enabled\n");
+		for (i = 0; i < elements; i++)
+			printk(KERN_DEBUG "%s\n", stat_description[i]);
 	} else if (input_arg == -1) {
 		for_each_present_cpu(cpu) {
 			stat = &per_cpu(ptcstats, cpu);
@@ -1145,27 +1257,18 @@
 }
 
 /*
- * set the tunables
- * 0 values reset them to defaults
+ * Parse the values written to /sys/kernel/debug/sgi_uv/bau_tunables.
+ * Zero values reset them to defaults.
  */
-static ssize_t tunables_write(struct file *file, const char __user *user,
-				 size_t count, loff_t *data)
+static int parse_tunables_write(struct bau_control *bcp, char *instr,
+				int count)
 {
-	int cpu;
-	int cnt = 0;
-	int val;
 	char *p;
 	char *q;
-	char instr[64];
-	struct bau_control *bcp;
-
-	if (count == 0 || count > sizeof(instr)-1)
-		return -EINVAL;
-	if (copy_from_user(instr, user, count))
-		return -EFAULT;
+	int cnt = 0;
+	int val;
+	int e = sizeof(tunables) / sizeof(*tunables);
 
-	instr[count] = '\0';
-	/* count the fields */
 	p = instr + strspn(instr, WHITESPACE);
 	q = p;
 	for (; *p; p = q + strspn(q, WHITESPACE)) {
@@ -1174,8 +1277,8 @@
 		if (q == p)
 			break;
 	}
-	if (cnt != 9) {
-		printk(KERN_INFO "bau tunable error: should be 9 numbers\n");
+	if (cnt != e) {
+		printk(KERN_INFO "bau tunable error: should be %d values\n", e);
 		return -EINVAL;
 	}
 
@@ -1187,97 +1290,80 @@
 		switch (cnt) {
 		case 0:
 			if (val == 0) {
-				max_bau_concurrent = MAX_BAU_CONCURRENT;
-				max_bau_concurrent_constant =
-							MAX_BAU_CONCURRENT;
+				max_concurr = MAX_BAU_CONCURRENT;
+				max_concurr_const = MAX_BAU_CONCURRENT;
 				continue;
 			}
-			bcp = &per_cpu(bau_control, smp_processor_id());
 			if (val < 1 || val > bcp->cpus_in_uvhub) {
 				printk(KERN_DEBUG
 				"Error: BAU max concurrent %d is invalid\n",
 				val);
 				return -EINVAL;
 			}
-			max_bau_concurrent = val;
-			max_bau_concurrent_constant = val;
-			continue;
-		case 1:
-			if (val == 0)
-				plugged_delay = PLUGGED_DELAY;
-			else
-				plugged_delay = val;
-			continue;
-		case 2:
-			if (val == 0)
-				plugsb4reset = PLUGSB4RESET;
-			else
-				plugsb4reset = val;
-			continue;
-		case 3:
-			if (val == 0)
-				timeoutsb4reset = TIMEOUTSB4RESET;
-			else
-				timeoutsb4reset = val;
-			continue;
-		case 4:
-			if (val == 0)
-				ipi_reset_limit = IPI_RESET_LIMIT;
-			else
-				ipi_reset_limit = val;
-			continue;
-		case 5:
-			if (val == 0)
-				complete_threshold = COMPLETE_THRESHOLD;
-			else
-				complete_threshold = val;
-			continue;
-		case 6:
-			if (val == 0)
-				congested_response_us = CONGESTED_RESPONSE_US;
-			else
-				congested_response_us = val;
-			continue;
-		case 7:
-			if (val == 0)
-				congested_reps = CONGESTED_REPS;
-			else
-				congested_reps = val;
+			max_concurr = val;
+			max_concurr_const = val;
 			continue;
-		case 8:
+		default:
 			if (val == 0)
-				congested_period = CONGESTED_PERIOD;
+				*tunables[cnt].tunp = tunables[cnt].deflt;
 			else
-				congested_period = val;
+				*tunables[cnt].tunp = val;
 			continue;
 		}
 		if (q == p)
 			break;
 	}
+	return 0;
+}
+
+/*
+ * Handle a write to debugfs. (/sys/kernel/debug/sgi_uv/bau_tunables)
+ */
+static ssize_t tunables_write(struct file *file, const char __user *user,
+				size_t count, loff_t *data)
+{
+	int cpu;
+	int ret;
+	char instr[100];
+	struct bau_control *bcp;
+
+	if (count == 0 || count > sizeof(instr)-1)
+		return -EINVAL;
+	if (copy_from_user(instr, user, count))
+		return -EFAULT;
+
+	instr[count] = '\0';
+
+	bcp = &per_cpu(bau_control, smp_processor_id());
+
+	ret = parse_tunables_write(bcp, instr, count);
+	if (ret)
+		return ret;
+
 	for_each_present_cpu(cpu) {
 		bcp = &per_cpu(bau_control, cpu);
-		bcp->max_bau_concurrent = max_bau_concurrent;
-		bcp->max_bau_concurrent_constant = max_bau_concurrent;
-		bcp->plugged_delay = plugged_delay;
-		bcp->plugsb4reset = plugsb4reset;
-		bcp->timeoutsb4reset = timeoutsb4reset;
-		bcp->ipi_reset_limit = ipi_reset_limit;
-		bcp->complete_threshold = complete_threshold;
-		bcp->congested_response_us = congested_response_us;
-		bcp->congested_reps = congested_reps;
-		bcp->congested_period = congested_period;
+		bcp->max_concurr =		max_concurr;
+		bcp->max_concurr_const =	max_concurr;
+		bcp->plugged_delay =		plugged_delay;
+		bcp->plugsb4reset =		plugsb4reset;
+		bcp->timeoutsb4reset =		timeoutsb4reset;
+		bcp->ipi_reset_limit =		ipi_reset_limit;
+		bcp->complete_threshold =	complete_threshold;
+		bcp->cong_response_us =		congested_respns_us;
+		bcp->cong_reps =		congested_reps;
+		bcp->cong_period =		congested_period;
 	}
 	return count;
 }
 
 static const struct seq_operations uv_ptc_seq_ops = {
-	.start		= uv_ptc_seq_start,
-	.next		= uv_ptc_seq_next,
-	.stop		= uv_ptc_seq_stop,
-	.show		= uv_ptc_seq_show
+	.start		= ptc_seq_start,
+	.next		= ptc_seq_next,
+	.stop		= ptc_seq_stop,
+	.show		= ptc_seq_show
 };
 
-static int uv_ptc_proc_open(struct inode *inode, struct file *file)
+static int ptc_proc_open(struct inode *inode, struct file *file)
 {
 	return seq_open(file, &uv_ptc_seq_ops);
 }
@@ -1288,9 +1374,9 @@
 }
 
 static const struct file_operations proc_uv_ptc_operations = {
-	.open		= uv_ptc_proc_open,
+	.open		= ptc_proc_open,
 	.read		= seq_read,
-	.write		= uv_ptc_proc_write,
+	.write		= ptc_proc_write,
 	.llseek		= seq_lseek,
 	.release	= seq_release,
 };
@@ -1324,7 +1410,7 @@
 		return -EINVAL;
 	}
 	tunables_file = debugfs_create_file(UV_BAU_TUNABLES_FILE, 0600,
-			tunables_dir, NULL, &tunables_fops);
+					tunables_dir, NULL, &tunables_fops);
 	if (!tunables_file) {
 		printk(KERN_ERR "unable to create debugfs file %s\n",
 		       UV_BAU_TUNABLES_FILE);
@@ -1336,24 +1422,24 @@
 /*
  * Initialize the sending side's sending buffers.
  */
-static void
-uv_activation_descriptor_init(int node, int pnode, int base_pnode)
+static void activation_descriptor_init(int node, int pnode, int base_pnode)
 {
 	int i;
 	int cpu;
 	unsigned long pa;
 	unsigned long m;
 	unsigned long n;
+	size_t dsize;
 	struct bau_desc *bau_desc;
 	struct bau_desc *bd2;
 	struct bau_control *bcp;
 
 	/*
-	 * each bau_desc is 64 bytes; there are 8 (UV_ITEMS_PER_DESCRIPTOR)
-	 * per cpu; and one per cpu on the uvhub (UV_ADP_SIZE)
+	 * each bau_desc is 64 bytes; there are 8 (ITEMS_PER_DESC)
+	 * per cpu; and one per cpu on the uvhub (ADP_SZ)
 	 */
-	bau_desc = kmalloc_node(sizeof(struct bau_desc) * UV_ADP_SIZE
-				* UV_ITEMS_PER_DESCRIPTOR, GFP_KERNEL, node);
+	dsize = sizeof(struct bau_desc) * ADP_SZ * ITEMS_PER_DESC;
+	bau_desc = kmalloc_node(dsize, GFP_KERNEL, node);
 	BUG_ON(!bau_desc);
 
 	pa = uv_gpa(bau_desc); /* need the real nasid*/
@@ -1361,27 +1447,25 @@
 	m = pa & uv_mmask;
 
 	/* the 14-bit pnode */
-	uv_write_global_mmr64(pnode, UVH_LB_BAU_SB_DESCRIPTOR_BASE,
-			      (n << UV_DESC_BASE_PNODE_SHIFT | m));
+	write_mmr_descriptor_base(pnode, (n << UV_DESC_PSHIFT | m));
 	/*
-	 * Initializing all 8 (UV_ITEMS_PER_DESCRIPTOR) descriptors for each
+	 * Initializing all 8 (ITEMS_PER_DESC) descriptors for each
 	 * cpu even though we only use the first one; one descriptor can
 	 * describe a broadcast to 256 uv hubs.
 	 */
-	for (i = 0, bd2 = bau_desc; i < (UV_ADP_SIZE*UV_ITEMS_PER_DESCRIPTOR);
-		i++, bd2++) {
+	for (i = 0, bd2 = bau_desc; i < (ADP_SZ * ITEMS_PER_DESC); i++, bd2++) {
 		memset(bd2, 0, sizeof(struct bau_desc));
-		bd2->header.sw_ack_flag = 1;
+		bd2->header.swack_flag =	1;
 		/*
 		 * The base_dest_nasid set in the message header is the nasid
 		 * of the first uvhub in the partition. The bit map will
 		 * indicate destination pnode numbers relative to that base.
 		 * They may not be consecutive if nasid striding is being used.
 		 */
-		bd2->header.base_dest_nasid = UV_PNODE_TO_NASID(base_pnode);
-		bd2->header.dest_subnodeid = UV_LB_SUBNODEID;
-		bd2->header.command = UV_NET_ENDPOINT_INTD;
-		bd2->header.int_both = 1;
+		bd2->header.base_dest_nasid =	UV_PNODE_TO_NASID(base_pnode);
+		bd2->header.dest_subnodeid =	UV_LB_SUBNODEID;
+		bd2->header.command =		UV_NET_ENDPOINT_INTD;
+		bd2->header.int_both =		1;
 		/*
 		 * all others need to be set to zero:
 		 *   fairness chaining multilevel count replied_to
@@ -1401,57 +1485,55 @@
  * - node is first node (kernel memory notion) on the uvhub
  * - pnode is the uvhub's physical identifier
  */
-static void
-uv_payload_queue_init(int node, int pnode)
+static void pq_init(int node, int pnode)
 {
-	int pn;
 	int cpu;
+	size_t plsize;
 	char *cp;
-	unsigned long pa;
-	struct bau_payload_queue_entry *pqp;
-	struct bau_payload_queue_entry *pqp_malloc;
+	void *vp;
+	unsigned long pn;
+	unsigned long first;
+	unsigned long pn_first;
+	unsigned long last;
+	struct bau_pq_entry *pqp;
 	struct bau_control *bcp;
 
-	pqp = kmalloc_node((DEST_Q_SIZE + 1)
-			   * sizeof(struct bau_payload_queue_entry),
-			   GFP_KERNEL, node);
+	plsize = (DEST_Q_SIZE + 1) * sizeof(struct bau_pq_entry);
+	vp = kmalloc_node(plsize, GFP_KERNEL, node);
+	pqp = (struct bau_pq_entry *)vp;
 	BUG_ON(!pqp);
-	pqp_malloc = pqp;
 
 	cp = (char *)pqp + 31;
-	pqp = (struct bau_payload_queue_entry *)(((unsigned long)cp >> 5) << 5);
+	pqp = (struct bau_pq_entry *)(((unsigned long)cp >> 5) << 5);
 
 	for_each_present_cpu(cpu) {
 		if (pnode != uv_cpu_to_pnode(cpu))
 			continue;
 		/* for every cpu on this pnode: */
 		bcp = &per_cpu(bau_control, cpu);
-		bcp->va_queue_first = pqp;
-		bcp->bau_msg_head = pqp;
-		bcp->va_queue_last = pqp + (DEST_Q_SIZE - 1);
+		bcp->queue_first	= pqp;
+		bcp->bau_msg_head	= pqp;
+		bcp->queue_last		= pqp + (DEST_Q_SIZE - 1);
 	}
 	/*
 	 * need the pnode of where the memory was really allocated
 	 */
-	pa = uv_gpa(pqp);
-	pn = pa >> uv_nshift;
-	uv_write_global_mmr64(pnode,
-			      UVH_LB_BAU_INTD_PAYLOAD_QUEUE_FIRST,
-			      ((unsigned long)pn << UV_PAYLOADQ_PNODE_SHIFT) |
-			      uv_physnodeaddr(pqp));
-	uv_write_global_mmr64(pnode, UVH_LB_BAU_INTD_PAYLOAD_QUEUE_TAIL,
-			      uv_physnodeaddr(pqp));
-	uv_write_global_mmr64(pnode, UVH_LB_BAU_INTD_PAYLOAD_QUEUE_LAST,
-			      (unsigned long)
-			      uv_physnodeaddr(pqp + (DEST_Q_SIZE - 1)));
+	pn = uv_gpa(pqp) >> uv_nshift;
+	first = uv_physnodeaddr(pqp);
+	pn_first = ((unsigned long)pn << UV_PAYLOADQ_PNODE_SHIFT) | first;
+	last = uv_physnodeaddr(pqp + (DEST_Q_SIZE - 1));
+	write_mmr_payload_first(pnode, pn_first);
+	write_mmr_payload_tail(pnode, first);
+	write_mmr_payload_last(pnode, last);
+
 	/* in effect, all msg_type's are set to MSG_NOOP */
-	memset(pqp, 0, sizeof(struct bau_payload_queue_entry) * DEST_Q_SIZE);
+	memset(pqp, 0, sizeof(struct bau_pq_entry) * DEST_Q_SIZE);
 }
 
 /*
  * Initialization of each UV hub's structures
  */
-static void __init uv_init_uvhub(int uvhub, int vector, int base_pnode)
+static void __init init_uvhub(int uvhub, int vector, int base_pnode)
 {
 	int node;
 	int pnode;
@@ -1459,24 +1541,24 @@
 
 	node = uvhub_to_first_node(uvhub);
 	pnode = uv_blade_to_pnode(uvhub);
-	uv_activation_descriptor_init(node, pnode, base_pnode);
-	uv_payload_queue_init(node, pnode);
+
+	activation_descriptor_init(node, pnode, base_pnode);
+
+	pq_init(node, pnode);
 	/*
 	 * The below initialization can't be in firmware because the
 	 * messaging IRQ will be determined by the OS.
 	 */
 	apicid = uvhub_to_first_apicid(uvhub) | uv_apicid_hibits;
-	uv_write_global_mmr64(pnode, UVH_BAU_DATA_CONFIG,
-				      ((apicid << 32) | vector));
+	write_mmr_data_config(pnode, ((apicid << 32) | vector));
 }
 
 /*
  * We will set BAU_MISC_CONTROL with a timeout period.
  * But the BIOS has set UVH_AGING_PRESCALE_SEL and UVH_TRANSACTION_TIMEOUT.
- * So the destination timeout period has be be calculated from them.
+ * So the destination timeout period has to be calculated from them.
  */
-static int
-calculate_destination_timeout(void)
+static int calculate_destination_timeout(void)
 {
 	unsigned long mmr_image;
 	int mult1;
@@ -1486,73 +1568,92 @@
 	int ret;
 	unsigned long ts_ns;
 
-	mult1 = UV_INTD_SOFT_ACK_TIMEOUT_PERIOD & BAU_MISC_CONTROL_MULT_MASK;
-	mmr_image = uv_read_local_mmr(UVH_AGING_PRESCALE_SEL);
-	index = (mmr_image >> BAU_URGENCY_7_SHIFT) & BAU_URGENCY_7_MASK;
-	mmr_image = uv_read_local_mmr(UVH_TRANSACTION_TIMEOUT);
-	mult2 = (mmr_image >> BAU_TRANS_SHIFT) & BAU_TRANS_MASK;
-	base = timeout_base_ns[index];
-	ts_ns = base * mult1 * mult2;
-	ret = ts_ns / 1000;
+	if (is_uv1_hub()) {
+		mult1 = SOFTACK_TIMEOUT_PERIOD & BAU_MISC_CONTROL_MULT_MASK;
+		mmr_image = uv_read_local_mmr(UVH_AGING_PRESCALE_SEL);
+		index = (mmr_image >> BAU_URGENCY_7_SHIFT) & BAU_URGENCY_7_MASK;
+		mmr_image = uv_read_local_mmr(UVH_TRANSACTION_TIMEOUT);
+		mult2 = (mmr_image >> BAU_TRANS_SHIFT) & BAU_TRANS_MASK;
+		base = timeout_base_ns[index];
+		ts_ns = base * mult1 * mult2;
+		ret = ts_ns / 1000;
+	} else {
+		/* 4 bits  0/1 for 10/80us, 3 bits of multiplier */
+		mmr_image = uv_read_local_mmr(UVH_AGING_PRESCALE_SEL);
+		mmr_image = (mmr_image & UV_SA_MASK) >> UV_SA_SHFT;
+		if (mmr_image & (1L << UV2_ACK_UNITS_SHFT))
+			mult1 = 80;
+		else
+			mult1 = 10;
+		base = mmr_image & UV2_ACK_MASK;
+		ret = mult1 * base;
+	}
 	return ret;
 }
 
+static void __init init_per_cpu_tunables(void)
+{
+	int cpu;
+	struct bau_control *bcp;
+
+	for_each_present_cpu(cpu) {
+		bcp = &per_cpu(bau_control, cpu);
+		bcp->baudisabled		= 0;
+		bcp->statp			= &per_cpu(ptcstats, cpu);
+		/* time interval to catch a hardware stay-busy bug */
+		bcp->timeout_interval		= usec_2_cycles(2*timeout_us);
+		bcp->max_concurr		= max_concurr;
+		bcp->max_concurr_const		= max_concurr;
+		bcp->plugged_delay		= plugged_delay;
+		bcp->plugsb4reset		= plugsb4reset;
+		bcp->timeoutsb4reset		= timeoutsb4reset;
+		bcp->ipi_reset_limit		= ipi_reset_limit;
+		bcp->complete_threshold		= complete_threshold;
+		bcp->cong_response_us		= congested_respns_us;
+		bcp->cong_reps			= congested_reps;
+		bcp->cong_period		= congested_period;
+	}
+}
+
 /*
- * initialize the bau_control structure for each cpu
+ * Scan all cpus to collect blade and socket summaries.
  */
-static int __init uv_init_per_cpu(int nuvhubs, int base_part_pnode)
+static int __init get_cpu_topology(int base_pnode,
+					struct uvhub_desc *uvhub_descs,
+					unsigned char *uvhub_mask)
 {
-	int i;
 	int cpu;
-	int tcpu;
 	int pnode;
 	int uvhub;
-	int have_hmaster;
-	short socket = 0;
-	unsigned short socket_mask;
-	unsigned char *uvhub_mask;
+	int socket;
 	struct bau_control *bcp;
 	struct uvhub_desc *bdp;
 	struct socket_desc *sdp;
-	struct bau_control *hmaster = NULL;
-	struct bau_control *smaster = NULL;
-	struct socket_desc {
-		short num_cpus;
-		short cpu_number[MAX_CPUS_PER_SOCKET];
-	};
-	struct uvhub_desc {
-		unsigned short socket_mask;
-		short num_cpus;
-		short uvhub;
-		short pnode;
-		struct socket_desc socket[2];
-	};
-	struct uvhub_desc *uvhub_descs;
 
-	timeout_us = calculate_destination_timeout();
-
-	uvhub_descs = kmalloc(nuvhubs * sizeof(struct uvhub_desc), GFP_KERNEL);
-	memset(uvhub_descs, 0, nuvhubs * sizeof(struct uvhub_desc));
-	uvhub_mask = kzalloc((nuvhubs+7)/8, GFP_KERNEL);
 	for_each_present_cpu(cpu) {
 		bcp = &per_cpu(bau_control, cpu);
+
 		memset(bcp, 0, sizeof(struct bau_control));
+
 		pnode = uv_cpu_hub_info(cpu)->pnode;
-		if ((pnode - base_part_pnode) >= UV_DISTRIBUTION_SIZE) {
+		if ((pnode - base_pnode) >= UV_DISTRIBUTION_SIZE) {
 			printk(KERN_EMERG
 				"cpu %d pnode %d-%d beyond %d; BAU disabled\n",
-				cpu, pnode, base_part_pnode,
-				UV_DISTRIBUTION_SIZE);
+				cpu, pnode, base_pnode, UV_DISTRIBUTION_SIZE);
 			return 1;
 		}
+
 		bcp->osnode = cpu_to_node(cpu);
-		bcp->partition_base_pnode = uv_partition_base_pnode;
+		bcp->partition_base_pnode = base_pnode;
+
 		uvhub = uv_cpu_hub_info(cpu)->numa_blade_id;
 		*(uvhub_mask + (uvhub/8)) |= (1 << (uvhub%8));
 		bdp = &uvhub_descs[uvhub];
+
 		bdp->num_cpus++;
 		bdp->uvhub = uvhub;
 		bdp->pnode = pnode;
+
 		/* kludge: 'assuming' one node per socket, and assuming that
 		   disabling a socket just leaves a gap in node numbers */
 		socket = bcp->osnode & 1;
@@ -1561,84 +1662,129 @@
 		sdp->cpu_number[sdp->num_cpus] = cpu;
 		sdp->num_cpus++;
 		if (sdp->num_cpus > MAX_CPUS_PER_SOCKET) {
-			printk(KERN_EMERG "%d cpus per socket invalid\n", sdp->num_cpus);
+			printk(KERN_EMERG "%d cpus per socket invalid\n",
+				sdp->num_cpus);
 			return 1;
 		}
 	}
+	return 0;
+}
+
+/*
+ * Each socket is to get a local array of pnodes/hubs.
+ */
+static void make_per_cpu_thp(struct bau_control *smaster)
+{
+	int cpu;
+	size_t hpsz = sizeof(struct hub_and_pnode) * num_possible_cpus();
+
+	smaster->thp = kmalloc_node(hpsz, GFP_KERNEL, smaster->osnode);
+	memset(smaster->thp, 0, hpsz);
+	for_each_present_cpu(cpu) {
+		smaster->thp[cpu].pnode = uv_cpu_hub_info(cpu)->pnode;
+		smaster->thp[cpu].uvhub = uv_cpu_hub_info(cpu)->numa_blade_id;
+	}
+}
+
+/*
+ * Initialize all the per_cpu information for the cpu's on a given socket,
+ * given what has been gathered into the socket_desc struct.
+ * And reports the chosen hub and socket masters back to the caller.
+ */
+static int scan_sock(struct socket_desc *sdp, struct uvhub_desc *bdp,
+			struct bau_control **smasterp,
+			struct bau_control **hmasterp)
+{
+	int i;
+	int cpu;
+	struct bau_control *bcp;
+
+	for (i = 0; i < sdp->num_cpus; i++) {
+		cpu = sdp->cpu_number[i];
+		bcp = &per_cpu(bau_control, cpu);
+		bcp->cpu = cpu;
+		if (i == 0) {
+			*smasterp = bcp;
+			if (!(*hmasterp))
+				*hmasterp = bcp;
+		}
+		bcp->cpus_in_uvhub = bdp->num_cpus;
+		bcp->cpus_in_socket = sdp->num_cpus;
+		bcp->socket_master = *smasterp;
+		bcp->uvhub = bdp->uvhub;
+		bcp->uvhub_master = *hmasterp;
+		bcp->uvhub_cpu = uv_cpu_hub_info(cpu)->blade_processor_id;
+		if (bcp->uvhub_cpu >= MAX_CPUS_PER_UVHUB) {
+			printk(KERN_EMERG "%d cpus per uvhub invalid\n",
+				bcp->uvhub_cpu);
+			return 1;
+		}
+	}
+	return 0;
+}
+
+/*
+ * Summarize the blade and socket topology into the per_cpu structures.
+ */
+static int __init summarize_uvhub_sockets(int nuvhubs,
+			struct uvhub_desc *uvhub_descs,
+			unsigned char *uvhub_mask)
+{
+	int socket;
+	int uvhub;
+	unsigned short socket_mask;
+
 	for (uvhub = 0; uvhub < nuvhubs; uvhub++) {
+		struct uvhub_desc *bdp;
+		struct bau_control *smaster = NULL;
+		struct bau_control *hmaster = NULL;
+
 		if (!(*(uvhub_mask + (uvhub/8)) & (1 << (uvhub%8))))
 			continue;
-		have_hmaster = 0;
+
 		bdp = &uvhub_descs[uvhub];
 		socket_mask = bdp->socket_mask;
 		socket = 0;
 		while (socket_mask) {
-			if (!(socket_mask & 1))
-				goto nextsocket;
-			sdp = &bdp->socket[socket];
-			for (i = 0; i < sdp->num_cpus; i++) {
-				cpu = sdp->cpu_number[i];
-				bcp = &per_cpu(bau_control, cpu);
-				bcp->cpu = cpu;
-				if (i == 0) {
-					smaster = bcp;
-					if (!have_hmaster) {
-						have_hmaster++;
-						hmaster = bcp;
-					}
-				}
-				bcp->cpus_in_uvhub = bdp->num_cpus;
-				bcp->cpus_in_socket = sdp->num_cpus;
-				bcp->socket_master = smaster;
-				bcp->uvhub = bdp->uvhub;
-				bcp->uvhub_master = hmaster;
-				bcp->uvhub_cpu = uv_cpu_hub_info(cpu)->
-						blade_processor_id;
-				if (bcp->uvhub_cpu >= MAX_CPUS_PER_UVHUB) {
-					printk(KERN_EMERG
-						"%d cpus per uvhub invalid\n",
-						bcp->uvhub_cpu);
+			struct socket_desc *sdp;
+			if ((socket_mask & 1)) {
+				sdp = &bdp->socket[socket];
+				if (scan_sock(sdp, bdp, &smaster, &hmaster))
 					return 1;
-				}
 			}
-nextsocket:
 			socket++;
 			socket_mask = (socket_mask >> 1);
-			/* each socket gets a local array of pnodes/hubs */
-			bcp = smaster;
-			bcp->target_hub_and_pnode = kmalloc_node(
-				sizeof(struct hub_and_pnode) *
-				num_possible_cpus(), GFP_KERNEL, bcp->osnode);
-			memset(bcp->target_hub_and_pnode, 0,
-				sizeof(struct hub_and_pnode) *
-				num_possible_cpus());
-			for_each_present_cpu(tcpu) {
-				bcp->target_hub_and_pnode[tcpu].pnode =
-					uv_cpu_hub_info(tcpu)->pnode;
-				bcp->target_hub_and_pnode[tcpu].uvhub =
-					uv_cpu_hub_info(tcpu)->numa_blade_id;
-			}
+			make_per_cpu_thp(smaster);
 		}
 	}
+	return 0;
+}
+
+/*
+ * initialize the bau_control structure for each cpu
+ */
+static int __init init_per_cpu(int nuvhubs, int base_part_pnode)
+{
+	unsigned char *uvhub_mask;
+	void *vp;
+	struct uvhub_desc *uvhub_descs;
+
+	timeout_us = calculate_destination_timeout();
+
+	vp = kmalloc(nuvhubs * sizeof(struct uvhub_desc), GFP_KERNEL);
+	uvhub_descs = (struct uvhub_desc *)vp;
+	memset(uvhub_descs, 0, nuvhubs * sizeof(struct uvhub_desc));
+	uvhub_mask = kzalloc((nuvhubs+7)/8, GFP_KERNEL);
+
+	if (get_cpu_topology(base_part_pnode, uvhub_descs, uvhub_mask))
+		return 1;
+
+	if (summarize_uvhub_sockets(nuvhubs, uvhub_descs, uvhub_mask))
+		return 1;
+
 	kfree(uvhub_descs);
 	kfree(uvhub_mask);
-	for_each_present_cpu(cpu) {
-		bcp = &per_cpu(bau_control, cpu);
-		bcp->baudisabled = 0;
-		bcp->statp = &per_cpu(ptcstats, cpu);
-		/* time interval to catch a hardware stay-busy bug */
-		bcp->timeout_interval = microsec_2_cycles(2*timeout_us);
-		bcp->max_bau_concurrent = max_bau_concurrent;
-		bcp->max_bau_concurrent_constant = max_bau_concurrent;
-		bcp->plugged_delay = plugged_delay;
-		bcp->plugsb4reset = plugsb4reset;
-		bcp->timeoutsb4reset = timeoutsb4reset;
-		bcp->ipi_reset_limit = ipi_reset_limit;
-		bcp->complete_threshold = complete_threshold;
-		bcp->congested_response_us = congested_response_us;
-		bcp->congested_reps = congested_reps;
-		bcp->congested_period = congested_period;
-	}
+	init_per_cpu_tunables();
 	return 0;
 }
 
@@ -1651,8 +1797,9 @@
 	int pnode;
 	int nuvhubs;
 	int cur_cpu;
+	int cpus;
 	int vector;
-	unsigned long mmr;
+	cpumask_var_t *mask;
 
 	if (!is_uv_system())
 		return 0;
@@ -1660,24 +1807,25 @@
 	if (nobau)
 		return 0;
 
-	for_each_possible_cpu(cur_cpu)
-		zalloc_cpumask_var_node(&per_cpu(uv_flush_tlb_mask, cur_cpu),
-				       GFP_KERNEL, cpu_to_node(cur_cpu));
+	for_each_possible_cpu(cur_cpu) {
+		mask = &per_cpu(uv_flush_tlb_mask, cur_cpu);
+		zalloc_cpumask_var_node(mask, GFP_KERNEL, cpu_to_node(cur_cpu));
+	}
 
 	uv_nshift = uv_hub_info->m_val;
 	uv_mmask = (1UL << uv_hub_info->m_val) - 1;
 	nuvhubs = uv_num_possible_blades();
 	spin_lock_init(&disable_lock);
-	congested_cycles = microsec_2_cycles(congested_response_us);
+	congested_cycles = usec_2_cycles(congested_respns_us);
 
-	uv_partition_base_pnode = 0x7fffffff;
+	uv_base_pnode = 0x7fffffff;
 	for (uvhub = 0; uvhub < nuvhubs; uvhub++) {
-		if (uv_blade_nr_possible_cpus(uvhub) &&
-			(uv_blade_to_pnode(uvhub) < uv_partition_base_pnode))
-			uv_partition_base_pnode = uv_blade_to_pnode(uvhub);
+		cpus = uv_blade_nr_possible_cpus(uvhub);
+		if (cpus && (uv_blade_to_pnode(uvhub) < uv_base_pnode))
+			uv_base_pnode = uv_blade_to_pnode(uvhub);
 	}
 
-	if (uv_init_per_cpu(nuvhubs, uv_partition_base_pnode)) {
+	if (init_per_cpu(nuvhubs, uv_base_pnode)) {
 		nobau = 1;
 		return 0;
 	}
@@ -1685,21 +1833,21 @@
 	vector = UV_BAU_MESSAGE;
 	for_each_possible_blade(uvhub)
 		if (uv_blade_nr_possible_cpus(uvhub))
-			uv_init_uvhub(uvhub, vector, uv_partition_base_pnode);
+			init_uvhub(uvhub, vector, uv_base_pnode);
 
-	uv_enable_timeouts();
+	enable_timeouts();
 	alloc_intr_gate(vector, uv_bau_message_intr1);
 
 	for_each_possible_blade(uvhub) {
 		if (uv_blade_nr_possible_cpus(uvhub)) {
+			unsigned long val;
+			unsigned long mmr;
 			pnode = uv_blade_to_pnode(uvhub);
 			/* INIT the bau */
-			uv_write_global_mmr64(pnode,
-					UVH_LB_BAU_SB_ACTIVATION_CONTROL,
-					((unsigned long)1 << 63));
+			val = 1L << 63;
+			write_gmmr_activation(pnode, val);
 			mmr = 1; /* should be 1 to broadcast to both sockets */
-			uv_write_global_mmr64(pnode, UVH_BAU_DATA_BROADCAST,
-						mmr);
+			write_mmr_data_broadcast(pnode, mmr);
 		}
 	}
 
diff -druN linux-2.6.39-libre/arch/x86/platform/uv/uv_time.c linux-3.0-rc7-libre/arch/x86/platform/uv/uv_time.c
--- linux-2.6.39-libre/arch/x86/platform/uv/uv_time.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/platform/uv/uv_time.c	2011-07-11 19:51:52.000000000 -0400
@@ -40,7 +40,6 @@
 	.rating		= 400,
 	.read		= uv_read_rtc,
 	.mask		= (cycle_t)UVH_RTC_REAL_TIME_CLOCK_MASK,
-	.shift		= 10,
 	.flags		= CLOCK_SOURCE_IS_CONTINUOUS,
 };
 
@@ -100,8 +99,12 @@
 /* Check for an RTC interrupt pending */
 static int uv_intr_pending(int pnode)
 {
-	return uv_read_global_mmr64(pnode, UVH_EVENT_OCCURRED0) &
-		UVH_EVENT_OCCURRED0_RTC1_MASK;
+	if (is_uv1_hub())
+		return uv_read_global_mmr64(pnode, UVH_EVENT_OCCURRED0) &
+			UV1H_EVENT_OCCURRED0_RTC1_MASK;
+	else
+		return uv_read_global_mmr64(pnode, UV2H_EVENT_OCCURRED2) &
+			UV2H_EVENT_OCCURRED2_RTC_1_MASK;
 }
 
 /* Setup interrupt and return non-zero if early expiration occurred. */
@@ -115,8 +118,12 @@
 		UVH_RTC1_INT_CONFIG_M_MASK);
 	uv_write_global_mmr64(pnode, UVH_INT_CMPB, -1L);
 
-	uv_write_global_mmr64(pnode, UVH_EVENT_OCCURRED0_ALIAS,
-		UVH_EVENT_OCCURRED0_RTC1_MASK);
+	if (is_uv1_hub())
+		uv_write_global_mmr64(pnode, UVH_EVENT_OCCURRED0_ALIAS,
+				UV1H_EVENT_OCCURRED0_RTC1_MASK);
+	else
+		uv_write_global_mmr64(pnode, UV2H_EVENT_OCCURRED2_ALIAS,
+				UV2H_EVENT_OCCURRED2_RTC_1_MASK);
 
 	val = (X86_PLATFORM_IPI_VECTOR << UVH_RTC1_INT_CONFIG_VECTOR_SHFT) |
 		((u64)apicid << UVH_RTC1_INT_CONFIG_APIC_ID_SHFT);
@@ -372,14 +379,11 @@
 	if (!is_uv_system())
 		return -ENODEV;
 
-	clocksource_uv.mult = clocksource_hz2mult(sn_rtc_cycles_per_second,
-				clocksource_uv.shift);
-
 	/* If single blade, prefer tsc */
 	if (uv_num_possible_blades() == 1)
 		clocksource_uv.rating = 250;
 
-	rc = clocksource_register(&clocksource_uv);
+	rc = clocksource_register_hz(&clocksource_uv, sn_rtc_cycles_per_second);
 	if (rc)
 		printk(KERN_INFO "UV RTC clocksource failed rc %d\n", rc);
 	else
diff -druN linux-2.6.39-libre/arch/x86/vdso/Makefile linux-3.0-rc7-libre/arch/x86/vdso/Makefile
--- linux-2.6.39-libre/arch/x86/vdso/Makefile	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/vdso/Makefile	2011-07-11 19:51:52.000000000 -0400
@@ -11,7 +11,7 @@
 
 
 # files to link into the vdso
-vobjs-y := vdso-note.o vclock_gettime.o vgetcpu.o vvar.o
+vobjs-y := vdso-note.o vclock_gettime.o vgetcpu.o
 
 # files to link into kernel
 obj-$(VDSO64-y)			+= vma.o vdso.o
@@ -37,11 +37,24 @@
 $(obj)/%.so: $(obj)/%.so.dbg FORCE
 	$(call if_changed,objcopy)
 
+#
+# Don't omit frame pointers for ease of userspace debugging, but do
+# optimize sibling calls.
+#
 CFL := $(PROFILING) -mcmodel=small -fPIC -O2 -fasynchronous-unwind-tables -m64 \
-       $(filter -g%,$(KBUILD_CFLAGS)) $(call cc-option, -fno-stack-protector)
+       $(filter -g%,$(KBUILD_CFLAGS)) $(call cc-option, -fno-stack-protector) \
+       -fno-omit-frame-pointer -foptimize-sibling-calls
 
 $(vobjs): KBUILD_CFLAGS += $(CFL)
 
+#
+# vDSO code runs in userspace and -pg doesn't help with profiling anyway.
+#
+CFLAGS_REMOVE_vdso-note.o = -pg
+CFLAGS_REMOVE_vclock_gettime.o = -pg
+CFLAGS_REMOVE_vgetcpu.o = -pg
+CFLAGS_REMOVE_vvar.o = -pg
+
 targets += vdso-syms.lds
 obj-$(VDSO64-y)			+= vdso-syms.lds
 
diff -druN linux-2.6.39-libre/arch/x86/vdso/vclock_gettime.c linux-3.0-rc7-libre/arch/x86/vdso/vclock_gettime.c
--- linux-2.6.39-libre/arch/x86/vdso/vclock_gettime.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/vdso/vclock_gettime.c	2011-07-11 19:51:52.000000000 -0400
@@ -2,7 +2,7 @@
  * Copyright 2006 Andi Kleen, SUSE Labs.
  * Subject to the GNU Public License, v.2
  *
- * Fast user context implementation of clock_gettime and gettimeofday.
+ * Fast user context implementation of clock_gettime, gettimeofday, and time.
  *
  * The code should have no internal unresolved relocations.
  * Check with readelf after changing.
@@ -22,9 +22,8 @@
 #include <asm/hpet.h>
 #include <asm/unistd.h>
 #include <asm/io.h>
-#include "vextern.h"
 
-#define gtod vdso_vsyscall_gtod_data
+#define gtod (&VVAR(vsyscall_gtod_data))
 
 notrace static long vdso_fallback_gettime(long clock, struct timespec *ts)
 {
@@ -56,22 +55,6 @@
 	return 0;
 }
 
-/* Copy of the version in kernel/time.c which we cannot directly access */
-notrace static void
-vset_normalized_timespec(struct timespec *ts, long sec, long nsec)
-{
-	while (nsec >= NSEC_PER_SEC) {
-		nsec -= NSEC_PER_SEC;
-		++sec;
-	}
-	while (nsec < 0) {
-		nsec += NSEC_PER_SEC;
-		--sec;
-	}
-	ts->tv_sec = sec;
-	ts->tv_nsec = nsec;
-}
-
 notrace static noinline int do_monotonic(struct timespec *ts)
 {
 	unsigned long seq, ns, secs;
@@ -82,7 +65,17 @@
 		secs += gtod->wall_to_monotonic.tv_sec;
 		ns += gtod->wall_to_monotonic.tv_nsec;
 	} while (unlikely(read_seqretry(&gtod->lock, seq)));
-	vset_normalized_timespec(ts, secs, ns);
+
+	/* wall_time_nsec, vgetns(), and wall_to_monotonic.tv_nsec
+	 * are all guaranteed to be nonnegative.
+	 */
+	while (ns >= NSEC_PER_SEC) {
+		ns -= NSEC_PER_SEC;
+		++secs;
+	}
+	ts->tv_sec = secs;
+	ts->tv_nsec = ns;
+
 	return 0;
 }
 
@@ -107,7 +100,17 @@
 		secs += gtod->wall_to_monotonic.tv_sec;
 		ns += gtod->wall_to_monotonic.tv_nsec;
 	} while (unlikely(read_seqretry(&gtod->lock, seq)));
-	vset_normalized_timespec(ts, secs, ns);
+
+	/* wall_time_nsec and wall_to_monotonic.tv_nsec are
+	 * guaranteed to be between 0 and NSEC_PER_SEC.
+	 */
+	if (ns >= NSEC_PER_SEC) {
+		ns -= NSEC_PER_SEC;
+		++secs;
+	}
+	ts->tv_sec = secs;
+	ts->tv_nsec = ns;
+
 	return 0;
 }
 
@@ -157,3 +160,32 @@
 }
 int gettimeofday(struct timeval *, struct timezone *)
 	__attribute__((weak, alias("__vdso_gettimeofday")));
+
+/* This will break when the xtime seconds get inaccurate, but that is
+ * unlikely */
+
+static __always_inline long time_syscall(long *t)
+{
+	long secs;
+	asm volatile("syscall"
+		     : "=a" (secs)
+		     : "0" (__NR_time), "D" (t) : "cc", "r11", "cx", "memory");
+	return secs;
+}
+
+notrace time_t __vdso_time(time_t *t)
+{
+	time_t result;
+
+	if (unlikely(!VVAR(vsyscall_gtod_data).sysctl_enabled))
+		return time_syscall(t);
+
+	/* This is atomic on x86_64 so we don't need any locks. */
+	result = ACCESS_ONCE(VVAR(vsyscall_gtod_data).wall_time_sec);
+
+	if (t)
+		*t = result;
+	return result;
+}
+int time(time_t *t)
+	__attribute__((weak, alias("__vdso_time")));
diff -druN linux-2.6.39-libre/arch/x86/vdso/vdso.lds.S linux-3.0-rc7-libre/arch/x86/vdso/vdso.lds.S
--- linux-2.6.39-libre/arch/x86/vdso/vdso.lds.S	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/vdso/vdso.lds.S	2011-07-11 19:51:52.000000000 -0400
@@ -23,15 +23,10 @@
 		__vdso_gettimeofday;
 		getcpu;
 		__vdso_getcpu;
+		time;
+		__vdso_time;
 	local: *;
 	};
 }
 
 VDSO64_PRELINK = VDSO_PRELINK;
-
-/*
- * Define VDSO64_x for each VEXTERN(x), for use via VDSO64_SYMBOL.
- */
-#define VEXTERN(x)	VDSO64_ ## x = vdso_ ## x;
-#include "vextern.h"
-#undef	VEXTERN
diff -druN linux-2.6.39-libre/arch/x86/vdso/vextern.h linux-3.0-rc7-libre/arch/x86/vdso/vextern.h
--- linux-2.6.39-libre/arch/x86/vdso/vextern.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/vdso/vextern.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,16 +0,0 @@
-#ifndef VEXTERN
-#include <asm/vsyscall.h>
-#define VEXTERN(x) \
-	extern typeof(x) *vdso_ ## x __attribute__((visibility("hidden")));
-#endif
-
-#define VMAGIC 0xfeedbabeabcdefabUL
-
-/* Any kernel variables used in the vDSO must be exported in the main
-   kernel's vmlinux.lds.S/vsyscall.h/proper __section and
-   put into vextern.h and be referenced as a pointer with vdso prefix.
-   The main kernel later fills in the values.   */
-
-VEXTERN(jiffies)
-VEXTERN(vgetcpu_mode)
-VEXTERN(vsyscall_gtod_data)
diff -druN linux-2.6.39-libre/arch/x86/vdso/vgetcpu.c linux-3.0-rc7-libre/arch/x86/vdso/vgetcpu.c
--- linux-2.6.39-libre/arch/x86/vdso/vgetcpu.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/vdso/vgetcpu.c	2011-07-11 19:51:52.000000000 -0400
@@ -11,14 +11,13 @@
 #include <linux/time.h>
 #include <asm/vsyscall.h>
 #include <asm/vgtod.h>
-#include "vextern.h"
 
 notrace long
 __vdso_getcpu(unsigned *cpu, unsigned *node, struct getcpu_cache *unused)
 {
 	unsigned int p;
 
-	if (*vdso_vgetcpu_mode == VGETCPU_RDTSCP) {
+	if (VVAR(vgetcpu_mode) == VGETCPU_RDTSCP) {
 		/* Load per CPU data from RDTSCP */
 		native_read_tscp(&p);
 	} else {
diff -druN linux-2.6.39-libre/arch/x86/vdso/vma.c linux-3.0-rc7-libre/arch/x86/vdso/vma.c
--- linux-2.6.39-libre/arch/x86/vdso/vma.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/vdso/vma.c	2011-07-11 19:51:52.000000000 -0400
@@ -15,9 +15,6 @@
 #include <asm/proto.h>
 #include <asm/vdso.h>
 
-#include "vextern.h"		/* Just for VMAGIC.  */
-#undef VEXTERN
-
 unsigned int __read_mostly vdso_enabled = 1;
 
 extern char vdso_start[], vdso_end[];
@@ -26,20 +23,10 @@
 static struct page **vdso_pages;
 static unsigned vdso_size;
 
-static inline void *var_ref(void *p, char *name)
-{
-	if (*(void **)p != (void *)VMAGIC) {
-		printk("VDSO: variable %s broken\n", name);
-		vdso_enabled = 0;
-	}
-	return p;
-}
-
 static int __init init_vdso_vars(void)
 {
 	int npages = (vdso_end - vdso_start + PAGE_SIZE - 1) / PAGE_SIZE;
 	int i;
-	char *vbase;
 
 	vdso_size = npages << PAGE_SHIFT;
 	vdso_pages = kmalloc(sizeof(struct page *) * npages, GFP_KERNEL);
@@ -54,20 +41,6 @@
 		copy_page(page_address(p), vdso_start + i*PAGE_SIZE);
 	}
 
-	vbase = vmap(vdso_pages, npages, 0, PAGE_KERNEL);
-	if (!vbase)
-		goto oom;
-
-	if (memcmp(vbase, "\177ELF", 4)) {
-		printk("VDSO: I'm broken; not ELF\n");
-		vdso_enabled = 0;
-	}
-
-#define VEXTERN(x) \
-	*(typeof(__ ## x) **) var_ref(VDSO64_SYMBOL(vbase, x), #x) = &__ ## x;
-#include "vextern.h"
-#undef VEXTERN
-	vunmap(vbase);
 	return 0;
 
  oom:
diff -druN linux-2.6.39-libre/arch/x86/vdso/vvar.c linux-3.0-rc7-libre/arch/x86/vdso/vvar.c
--- linux-2.6.39-libre/arch/x86/vdso/vvar.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/vdso/vvar.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,12 +0,0 @@
-/* Define pointer to external vDSO variables.
-   These are part of the vDSO. The kernel fills in the real addresses
-   at boot time. This is done because when the vdso is linked the
-   kernel isn't yet and we don't know the final addresses. */
-#include <linux/kernel.h>
-#include <linux/time.h>
-#include <asm/vsyscall.h>
-#include <asm/timex.h>
-#include <asm/vgtod.h>
-
-#define VEXTERN(x) typeof (__ ## x) *const vdso_ ## x = (void *)VMAGIC;
-#include "vextern.h"
diff -druN linux-2.6.39-libre/arch/x86/xen/enlighten.c linux-3.0-rc7-libre/arch/x86/xen/enlighten.c
--- linux-2.6.39-libre/arch/x86/xen/enlighten.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/xen/enlighten.c	2011-07-11 19:51:52.000000000 -0400
@@ -235,7 +235,7 @@
 	*dx &= maskedx;
 }
 
-static __init void xen_init_cpuid_mask(void)
+static void __init xen_init_cpuid_mask(void)
 {
 	unsigned int ax, bx, cx, dx;
 	unsigned int xsave_mask;
@@ -400,7 +400,7 @@
 /*
  * load_gdt for early boot, when the gdt is only mapped once
  */
-static __init void xen_load_gdt_boot(const struct desc_ptr *dtr)
+static void __init xen_load_gdt_boot(const struct desc_ptr *dtr)
 {
 	unsigned long va = dtr->address;
 	unsigned int size = dtr->size + 1;
@@ -662,7 +662,7 @@
  * Version of write_gdt_entry for use at early boot-time needed to
  * update an entry as simply as possible.
  */
-static __init void xen_write_gdt_entry_boot(struct desc_struct *dt, int entry,
+static void __init xen_write_gdt_entry_boot(struct desc_struct *dt, int entry,
 					    const void *desc, int type)
 {
 	switch (type) {
@@ -933,18 +933,18 @@
 	return ret;
 }
 
-static const struct pv_info xen_info __initdata = {
+static const struct pv_info xen_info __initconst = {
 	.paravirt_enabled = 1,
 	.shared_kernel_pmd = 0,
 
 	.name = "Xen",
 };
 
-static const struct pv_init_ops xen_init_ops __initdata = {
+static const struct pv_init_ops xen_init_ops __initconst = {
 	.patch = xen_patch,
 };
 
-static const struct pv_cpu_ops xen_cpu_ops __initdata = {
+static const struct pv_cpu_ops xen_cpu_ops __initconst = {
 	.cpuid = xen_cpuid,
 
 	.set_debugreg = xen_set_debugreg,
@@ -1004,7 +1004,7 @@
 	.end_context_switch = xen_end_context_switch,
 };
 
-static const struct pv_apic_ops xen_apic_ops __initdata = {
+static const struct pv_apic_ops xen_apic_ops __initconst = {
 #ifdef CONFIG_X86_LOCAL_APIC
 	.startup_ipi_hook = paravirt_nop,
 #endif
@@ -1033,6 +1033,13 @@
 	xen_reboot(SHUTDOWN_poweroff);
 }
 
+static void xen_machine_power_off(void)
+{
+	if (pm_power_off)
+		pm_power_off();
+	xen_reboot(SHUTDOWN_poweroff);
+}
+
 static void xen_crash_shutdown(struct pt_regs *regs)
 {
 	xen_reboot(SHUTDOWN_crash);
@@ -1055,10 +1062,10 @@
 	return 0;
 }
 
-static const struct machine_ops __initdata xen_machine_ops = {
+static const struct machine_ops xen_machine_ops __initconst = {
 	.restart = xen_restart,
 	.halt = xen_machine_halt,
-	.power_off = xen_machine_halt,
+	.power_off = xen_machine_power_off,
 	.shutdown = xen_machine_halt,
 	.crash_shutdown = xen_crash_shutdown,
 	.emergency_restart = xen_emergency_restart,
@@ -1332,7 +1339,7 @@
 	return NOTIFY_OK;
 }
 
-static struct notifier_block __cpuinitdata xen_hvm_cpu_notifier = {
+static struct notifier_block xen_hvm_cpu_notifier __cpuinitdata = {
 	.notifier_call	= xen_hvm_cpu_notify,
 };
 
@@ -1381,7 +1388,7 @@
 }
 EXPORT_SYMBOL_GPL(xen_hvm_need_lapic);
 
-const __refconst struct hypervisor_x86 x86_hyper_xen_hvm = {
+const struct hypervisor_x86 x86_hyper_xen_hvm __refconst = {
 	.name			= "Xen HVM",
 	.detect			= xen_hvm_platform,
 	.init_platform		= xen_hvm_guest_init,
diff -druN linux-2.6.39-libre/arch/x86/xen/irq.c linux-3.0-rc7-libre/arch/x86/xen/irq.c
--- linux-2.6.39-libre/arch/x86/xen/irq.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/xen/irq.c	2011-07-11 19:51:52.000000000 -0400
@@ -113,7 +113,7 @@
 		xen_safe_halt();
 }
 
-static const struct pv_irq_ops xen_irq_ops __initdata = {
+static const struct pv_irq_ops xen_irq_ops __initconst = {
 	.save_fl = PV_CALLEE_SAVE(xen_save_fl),
 	.restore_fl = PV_CALLEE_SAVE(xen_restore_fl),
 	.irq_disable = PV_CALLEE_SAVE(xen_irq_disable),
diff -druN linux-2.6.39-libre/arch/x86/xen/mmu.c linux-3.0-rc7-libre/arch/x86/xen/mmu.c
--- linux-2.6.39-libre/arch/x86/xen/mmu.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/xen/mmu.c	2011-07-11 19:51:52.000000000 -0400
@@ -59,6 +59,7 @@
 #include <asm/page.h>
 #include <asm/init.h>
 #include <asm/pat.h>
+#include <asm/smp.h>
 
 #include <asm/xen/hypercall.h>
 #include <asm/xen/hypervisor.h>
@@ -75,67 +76,12 @@
 #include "mmu.h"
 #include "debugfs.h"
 
-#define MMU_UPDATE_HISTO	30
-
 /*
  * Protects atomic reservation decrease/increase against concurrent increases.
  * Also protects non-atomic updates of current_pages and balloon lists.
  */
 DEFINE_SPINLOCK(xen_reservation_lock);
 
-#ifdef CONFIG_XEN_DEBUG_FS
-
-static struct {
-	u32 pgd_update;
-	u32 pgd_update_pinned;
-	u32 pgd_update_batched;
-
-	u32 pud_update;
-	u32 pud_update_pinned;
-	u32 pud_update_batched;
-
-	u32 pmd_update;
-	u32 pmd_update_pinned;
-	u32 pmd_update_batched;
-
-	u32 pte_update;
-	u32 pte_update_pinned;
-	u32 pte_update_batched;
-
-	u32 mmu_update;
-	u32 mmu_update_extended;
-	u32 mmu_update_histo[MMU_UPDATE_HISTO];
-
-	u32 prot_commit;
-	u32 prot_commit_batched;
-
-	u32 set_pte_at;
-	u32 set_pte_at_batched;
-	u32 set_pte_at_pinned;
-	u32 set_pte_at_current;
-	u32 set_pte_at_kernel;
-} mmu_stats;
-
-static u8 zero_stats;
-
-static inline void check_zero(void)
-{
-	if (unlikely(zero_stats)) {
-		memset(&mmu_stats, 0, sizeof(mmu_stats));
-		zero_stats = 0;
-	}
-}
-
-#define ADD_STATS(elem, val)			\
-	do { check_zero(); mmu_stats.elem += (val); } while(0)
-
-#else  /* !CONFIG_XEN_DEBUG_FS */
-
-#define ADD_STATS(elem, val)	do { (void)(val); } while(0)
-
-#endif /* CONFIG_XEN_DEBUG_FS */
-
-
 /*
  * Identity map, in addition to plain kernel map.  This needs to be
  * large enough to allocate page table pages to allocate the rest.
@@ -243,11 +189,6 @@
 	return PagePinned(page);
 }
 
-static bool xen_iomap_pte(pte_t pte)
-{
-	return pte_flags(pte) & _PAGE_IOMAP;
-}
-
 void xen_set_domain_pte(pte_t *ptep, pte_t pteval, unsigned domid)
 {
 	struct multicall_space mcs;
@@ -257,7 +198,7 @@
 	u = mcs.args;
 
 	/* ptep might be kmapped when using 32-bit HIGHPTE */
-	u->ptr = arbitrary_virt_to_machine(ptep).maddr;
+	u->ptr = virt_to_machine(ptep).maddr;
 	u->val = pte_val_ma(pteval);
 
 	MULTI_mmu_update(mcs.mc, mcs.args, 1, NULL, domid);
@@ -266,11 +207,6 @@
 }
 EXPORT_SYMBOL_GPL(xen_set_domain_pte);
 
-static void xen_set_iomap_pte(pte_t *ptep, pte_t pteval)
-{
-	xen_set_domain_pte(ptep, pteval, DOMID_IO);
-}
-
 static void xen_extend_mmu_update(const struct mmu_update *update)
 {
 	struct multicall_space mcs;
@@ -279,27 +215,17 @@
 	mcs = xen_mc_extend_args(__HYPERVISOR_mmu_update, sizeof(*u));
 
 	if (mcs.mc != NULL) {
-		ADD_STATS(mmu_update_extended, 1);
-		ADD_STATS(mmu_update_histo[mcs.mc->args[1]], -1);
-
 		mcs.mc->args[1]++;
-
-		if (mcs.mc->args[1] < MMU_UPDATE_HISTO)
-			ADD_STATS(mmu_update_histo[mcs.mc->args[1]], 1);
-		else
-			ADD_STATS(mmu_update_histo[0], 1);
 	} else {
-		ADD_STATS(mmu_update, 1);
 		mcs = __xen_mc_entry(sizeof(*u));
 		MULTI_mmu_update(mcs.mc, mcs.args, 1, NULL, DOMID_SELF);
-		ADD_STATS(mmu_update_histo[1], 1);
 	}
 
 	u = mcs.args;
 	*u = *update;
 }
 
-void xen_set_pmd_hyper(pmd_t *ptr, pmd_t val)
+static void xen_set_pmd_hyper(pmd_t *ptr, pmd_t val)
 {
 	struct mmu_update u;
 
@@ -312,17 +238,13 @@
 	u.val = pmd_val_ma(val);
 	xen_extend_mmu_update(&u);
 
-	ADD_STATS(pmd_update_batched, paravirt_get_lazy_mode() == PARAVIRT_LAZY_MMU);
-
 	xen_mc_issue(PARAVIRT_LAZY_MMU);
 
 	preempt_enable();
 }
 
-void xen_set_pmd(pmd_t *ptr, pmd_t val)
+static void xen_set_pmd(pmd_t *ptr, pmd_t val)
 {
-	ADD_STATS(pmd_update, 1);
-
 	/* If page is not pinned, we can just update the entry
 	   directly */
 	if (!xen_page_pinned(ptr)) {
@@ -330,8 +252,6 @@
 		return;
 	}
 
-	ADD_STATS(pmd_update_pinned, 1);
-
 	xen_set_pmd_hyper(ptr, val);
 }
 
@@ -344,35 +264,34 @@
 	set_pte_vaddr(vaddr, mfn_pte(mfn, flags));
 }
 
-void xen_set_pte_at(struct mm_struct *mm, unsigned long addr,
-		    pte_t *ptep, pte_t pteval)
+static bool xen_batched_set_pte(pte_t *ptep, pte_t pteval)
 {
-	if (xen_iomap_pte(pteval)) {
-		xen_set_iomap_pte(ptep, pteval);
-		goto out;
-	}
+	struct mmu_update u;
 
-	ADD_STATS(set_pte_at, 1);
-//	ADD_STATS(set_pte_at_pinned, xen_page_pinned(ptep));
-	ADD_STATS(set_pte_at_current, mm == current->mm);
-	ADD_STATS(set_pte_at_kernel, mm == &init_mm);
+	if (paravirt_get_lazy_mode() != PARAVIRT_LAZY_MMU)
+		return false;
 
-	if (mm == current->mm || mm == &init_mm) {
-		if (paravirt_get_lazy_mode() == PARAVIRT_LAZY_MMU) {
-			struct multicall_space mcs;
-			mcs = xen_mc_entry(0);
+	xen_mc_batch();
 
-			MULTI_update_va_mapping(mcs.mc, addr, pteval, 0);
-			ADD_STATS(set_pte_at_batched, 1);
-			xen_mc_issue(PARAVIRT_LAZY_MMU);
-			goto out;
-		} else
-			if (HYPERVISOR_update_va_mapping(addr, pteval, 0) == 0)
-				goto out;
-	}
-	xen_set_pte(ptep, pteval);
+	u.ptr = virt_to_machine(ptep).maddr | MMU_NORMAL_PT_UPDATE;
+	u.val = pte_val_ma(pteval);
+	xen_extend_mmu_update(&u);
 
-out:	return;
+	xen_mc_issue(PARAVIRT_LAZY_MMU);
+
+	return true;
+}
+
+static void xen_set_pte(pte_t *ptep, pte_t pteval)
+{
+	if (!xen_batched_set_pte(ptep, pteval))
+		native_set_pte(ptep, pteval);
+}
+
+static void xen_set_pte_at(struct mm_struct *mm, unsigned long addr,
+		    pte_t *ptep, pte_t pteval)
+{
+	xen_set_pte(ptep, pteval);
 }
 
 pte_t xen_ptep_modify_prot_start(struct mm_struct *mm,
@@ -389,13 +308,10 @@
 
 	xen_mc_batch();
 
-	u.ptr = arbitrary_virt_to_machine(ptep).maddr | MMU_PT_UPDATE_PRESERVE_AD;
+	u.ptr = virt_to_machine(ptep).maddr | MMU_PT_UPDATE_PRESERVE_AD;
 	u.val = pte_val_ma(pte);
 	xen_extend_mmu_update(&u);
 
-	ADD_STATS(prot_commit, 1);
-	ADD_STATS(prot_commit_batched, paravirt_get_lazy_mode() == PARAVIRT_LAZY_MMU);
-
 	xen_mc_issue(PARAVIRT_LAZY_MMU);
 }
 
@@ -463,7 +379,7 @@
 	return val;
 }
 
-pteval_t xen_pte_val(pte_t pte)
+static pteval_t xen_pte_val(pte_t pte)
 {
 	pteval_t pteval = pte.pte;
 
@@ -480,7 +396,7 @@
 }
 PV_CALLEE_SAVE_REGS_THUNK(xen_pte_val);
 
-pgdval_t xen_pgd_val(pgd_t pgd)
+static pgdval_t xen_pgd_val(pgd_t pgd)
 {
 	return pte_mfn_to_pfn(pgd.pgd);
 }
@@ -511,7 +427,7 @@
 	WARN_ON(pat != 0x0007010600070106ull);
 }
 
-pte_t xen_make_pte(pteval_t pte)
+static pte_t xen_make_pte(pteval_t pte)
 {
 	phys_addr_t addr = (pte & PTE_PFN_MASK);
 
@@ -581,20 +497,20 @@
 PV_CALLEE_SAVE_REGS_THUNK(xen_make_pte_debug);
 #endif
 
-pgd_t xen_make_pgd(pgdval_t pgd)
+static pgd_t xen_make_pgd(pgdval_t pgd)
 {
 	pgd = pte_pfn_to_mfn(pgd);
 	return native_make_pgd(pgd);
 }
 PV_CALLEE_SAVE_REGS_THUNK(xen_make_pgd);
 
-pmdval_t xen_pmd_val(pmd_t pmd)
+static pmdval_t xen_pmd_val(pmd_t pmd)
 {
 	return pte_mfn_to_pfn(pmd.pmd);
 }
 PV_CALLEE_SAVE_REGS_THUNK(xen_pmd_val);
 
-void xen_set_pud_hyper(pud_t *ptr, pud_t val)
+static void xen_set_pud_hyper(pud_t *ptr, pud_t val)
 {
 	struct mmu_update u;
 
@@ -607,17 +523,13 @@
 	u.val = pud_val_ma(val);
 	xen_extend_mmu_update(&u);
 
-	ADD_STATS(pud_update_batched, paravirt_get_lazy_mode() == PARAVIRT_LAZY_MMU);
-
 	xen_mc_issue(PARAVIRT_LAZY_MMU);
 
 	preempt_enable();
 }
 
-void xen_set_pud(pud_t *ptr, pud_t val)
+static void xen_set_pud(pud_t *ptr, pud_t val)
 {
-	ADD_STATS(pud_update, 1);
-
 	/* If page is not pinned, we can just update the entry
 	   directly */
 	if (!xen_page_pinned(ptr)) {
@@ -625,56 +537,28 @@
 		return;
 	}
 
-	ADD_STATS(pud_update_pinned, 1);
-
 	xen_set_pud_hyper(ptr, val);
 }
 
-void xen_set_pte(pte_t *ptep, pte_t pte)
-{
-	if (xen_iomap_pte(pte)) {
-		xen_set_iomap_pte(ptep, pte);
-		return;
-	}
-
-	ADD_STATS(pte_update, 1);
-//	ADD_STATS(pte_update_pinned, xen_page_pinned(ptep));
-	ADD_STATS(pte_update_batched, paravirt_get_lazy_mode() == PARAVIRT_LAZY_MMU);
-
-#ifdef CONFIG_X86_PAE
-	ptep->pte_high = pte.pte_high;
-	smp_wmb();
-	ptep->pte_low = pte.pte_low;
-#else
-	*ptep = pte;
-#endif
-}
-
 #ifdef CONFIG_X86_PAE
-void xen_set_pte_atomic(pte_t *ptep, pte_t pte)
+static void xen_set_pte_atomic(pte_t *ptep, pte_t pte)
 {
-	if (xen_iomap_pte(pte)) {
-		xen_set_iomap_pte(ptep, pte);
-		return;
-	}
-
 	set_64bit((u64 *)ptep, native_pte_val(pte));
 }
 
-void xen_pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
+static void xen_pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
 {
-	ptep->pte_low = 0;
-	smp_wmb();		/* make sure low gets written first */
-	ptep->pte_high = 0;
+	if (!xen_batched_set_pte(ptep, native_make_pte(0)))
+		native_pte_clear(mm, addr, ptep);
 }
 
-void xen_pmd_clear(pmd_t *pmdp)
+static void xen_pmd_clear(pmd_t *pmdp)
 {
 	set_pmd(pmdp, __pmd(0));
 }
 #endif	/* CONFIG_X86_PAE */
 
-pmd_t xen_make_pmd(pmdval_t pmd)
+static pmd_t xen_make_pmd(pmdval_t pmd)
 {
 	pmd = pte_pfn_to_mfn(pmd);
 	return native_make_pmd(pmd);
@@ -682,13 +566,13 @@
 PV_CALLEE_SAVE_REGS_THUNK(xen_make_pmd);
 
 #if PAGETABLE_LEVELS == 4
-pudval_t xen_pud_val(pud_t pud)
+static pudval_t xen_pud_val(pud_t pud)
 {
 	return pte_mfn_to_pfn(pud.pud);
 }
 PV_CALLEE_SAVE_REGS_THUNK(xen_pud_val);
 
-pud_t xen_make_pud(pudval_t pud)
+static pud_t xen_make_pud(pudval_t pud)
 {
 	pud = pte_pfn_to_mfn(pud);
 
@@ -696,7 +580,7 @@
 }
 PV_CALLEE_SAVE_REGS_THUNK(xen_make_pud);
 
-pgd_t *xen_get_user_pgd(pgd_t *pgd)
+static pgd_t *xen_get_user_pgd(pgd_t *pgd)
 {
 	pgd_t *pgd_page = (pgd_t *)(((unsigned long)pgd) & PAGE_MASK);
 	unsigned offset = pgd - pgd_page;
@@ -728,7 +612,7 @@
  *  2. It is always pinned
  *  3. It has no user pagetable attached to it
  */
-void __init xen_set_pgd_hyper(pgd_t *ptr, pgd_t val)
+static void __init xen_set_pgd_hyper(pgd_t *ptr, pgd_t val)
 {
 	preempt_disable();
 
@@ -741,12 +625,10 @@
 	preempt_enable();
 }
 
-void xen_set_pgd(pgd_t *ptr, pgd_t val)
+static void xen_set_pgd(pgd_t *ptr, pgd_t val)
 {
 	pgd_t *user_ptr = xen_get_user_pgd(ptr);
 
-	ADD_STATS(pgd_update, 1);
-
 	/* If page is not pinned, we can just update the entry
 	   directly */
 	if (!xen_page_pinned(ptr)) {
@@ -758,9 +640,6 @@
 		return;
 	}
 
-	ADD_STATS(pgd_update_pinned, 1);
-	ADD_STATS(pgd_update_batched, paravirt_get_lazy_mode() == PARAVIRT_LAZY_MMU);
-
 	/* If it's pinned, then we can at least batch the kernel and
 	   user updates together. */
 	xen_mc_batch();
@@ -1054,7 +933,7 @@
  * that's before we have page structures to store the bits.  So do all
  * the book-keeping now.
  */
-static __init int xen_mark_pinned(struct mm_struct *mm, struct page *page,
+static int __init xen_mark_pinned(struct mm_struct *mm, struct page *page,
 				  enum pt_level level)
 {
 	SetPagePinned(page);
@@ -1162,14 +1041,14 @@
 	spin_unlock(&pgd_lock);
 }
 
-void xen_activate_mm(struct mm_struct *prev, struct mm_struct *next)
+static void xen_activate_mm(struct mm_struct *prev, struct mm_struct *next)
 {
 	spin_lock(&next->page_table_lock);
 	xen_pgd_pin(next);
 	spin_unlock(&next->page_table_lock);
 }
 
-void xen_dup_mmap(struct mm_struct *oldmm, struct mm_struct *mm)
+static void xen_dup_mmap(struct mm_struct *oldmm, struct mm_struct *mm)
 {
 	spin_lock(&mm->page_table_lock);
 	xen_pgd_pin(mm);
@@ -1187,7 +1066,7 @@
 
 	active_mm = percpu_read(cpu_tlbstate.active_mm);
 
-	if (active_mm == mm)
+	if (active_mm == mm && percpu_read(cpu_tlbstate.state) != TLBSTATE_OK)
 		leave_mm(smp_processor_id());
 
 	/* If this cpu still has a stale cr3 reference, then make sure
@@ -1256,7 +1135,7 @@
  * pagetable because of lazy tlb flushing.  This means we need need to
  * switch all CPUs off this pagetable before we can unpin it.
  */
-void xen_exit_mmap(struct mm_struct *mm)
+static void xen_exit_mmap(struct mm_struct *mm)
 {
 	get_cpu();		/* make sure we don't move around */
 	xen_drop_mm_ref(mm);
@@ -1271,7 +1150,7 @@
 	spin_unlock(&mm->page_table_lock);
 }
 
-static __init void xen_pagetable_setup_start(pgd_t *base)
+static void __init xen_pagetable_setup_start(pgd_t *base)
 {
 }
 
@@ -1291,7 +1170,7 @@
 
 static void xen_post_allocator_init(void);
 
-static __init void xen_pagetable_setup_done(pgd_t *base)
+static void __init xen_pagetable_setup_done(pgd_t *base)
 {
 	xen_setup_shared_info();
 	xen_post_allocator_init();
@@ -1353,7 +1232,11 @@
 {
 	struct {
 		struct mmuext_op op;
+#ifdef CONFIG_SMP
+		DECLARE_BITMAP(mask, num_processors);
+#else
 		DECLARE_BITMAP(mask, NR_CPUS);
+#endif
 	} *args;
 	struct multicall_space mcs;
 
@@ -1488,7 +1371,7 @@
 }
 
 #ifdef CONFIG_X86_32
-static __init pte_t mask_rw_pte(pte_t *ptep, pte_t pte)
+static pte_t __init mask_rw_pte(pte_t *ptep, pte_t pte)
 {
 	/* If there's an existing pte, then don't allow _PAGE_RW to be set */
 	if (pte_val_ma(*ptep) & _PAGE_PRESENT)
@@ -1498,7 +1381,7 @@
 	return pte;
 }
 #else /* CONFIG_X86_64 */
-static __init pte_t mask_rw_pte(pte_t *ptep, pte_t pte)
+static pte_t __init mask_rw_pte(pte_t *ptep, pte_t pte)
 {
 	unsigned long pfn = pte_pfn(pte);
 
@@ -1519,7 +1402,7 @@
 
 /* Init-time set_pte while constructing initial pagetables, which
    doesn't allow RO pagetable pages to be remapped RW */
-static __init void xen_set_pte_init(pte_t *ptep, pte_t pte)
+static void __init xen_set_pte_init(pte_t *ptep, pte_t pte)
 {
 	pte = mask_rw_pte(ptep, pte);
 
@@ -1537,7 +1420,7 @@
 
 /* Early in boot, while setting up the initial pagetable, assume
    everything is pinned. */
-static __init void xen_alloc_pte_init(struct mm_struct *mm, unsigned long pfn)
+static void __init xen_alloc_pte_init(struct mm_struct *mm, unsigned long pfn)
 {
 #ifdef CONFIG_FLATMEM
 	BUG_ON(mem_map);	/* should only be used early */
@@ -1547,7 +1430,7 @@
 }
 
 /* Used for pmd and pud */
-static __init void xen_alloc_pmd_init(struct mm_struct *mm, unsigned long pfn)
+static void __init xen_alloc_pmd_init(struct mm_struct *mm, unsigned long pfn)
 {
 #ifdef CONFIG_FLATMEM
 	BUG_ON(mem_map);	/* should only be used early */
@@ -1557,13 +1440,13 @@
 
 /* Early release_pte assumes that all pts are pinned, since there's
    only init_mm and anything attached to that is pinned. */
-static __init void xen_release_pte_init(unsigned long pfn)
+static void __init xen_release_pte_init(unsigned long pfn)
 {
 	pin_pagetable_pfn(MMUEXT_UNPIN_TABLE, pfn);
 	make_lowmem_page_readwrite(__va(PFN_PHYS(pfn)));
 }
 
-static __init void xen_release_pmd_init(unsigned long pfn)
+static void __init xen_release_pmd_init(unsigned long pfn)
 {
 	make_lowmem_page_readwrite(__va(PFN_PHYS(pfn)));
 }
@@ -1689,7 +1572,7 @@
 		BUG();
 }
 
-static __init void xen_map_identity_early(pmd_t *pmd, unsigned long max_pfn)
+static void __init xen_map_identity_early(pmd_t *pmd, unsigned long max_pfn)
 {
 	unsigned pmdidx, pteidx;
 	unsigned ident_pte;
@@ -1721,6 +1604,11 @@
 		for (pteidx = 0; pteidx < PTRS_PER_PTE; pteidx++, pfn++) {
 			pte_t pte;
 
+#ifdef CONFIG_X86_32
+			if (pfn > max_pfn_mapped)
+				max_pfn_mapped = pfn;
+#endif
+
 			if (!pte_none(pte_page[pteidx]))
 				continue;
 
@@ -1772,7 +1660,7 @@
  * of the physical mapping once some sort of allocator has been set
  * up.
  */
-__init pgd_t *xen_setup_kernel_pagetable(pgd_t *pgd,
+pgd_t * __init xen_setup_kernel_pagetable(pgd_t *pgd,
 					 unsigned long max_pfn)
 {
 	pud_t *l3;
@@ -1843,7 +1731,7 @@
 static RESERVE_BRK_ARRAY(pmd_t, initial_kernel_pmd, PTRS_PER_PMD);
 static RESERVE_BRK_ARRAY(pmd_t, swapper_kernel_pmd, PTRS_PER_PMD);
 
-static __init void xen_write_cr3_init(unsigned long cr3)
+static void __init xen_write_cr3_init(unsigned long cr3)
 {
 	unsigned long pfn = PFN_DOWN(__pa(swapper_pg_dir));
 
@@ -1880,7 +1768,7 @@
 	pv_mmu_ops.write_cr3 = &xen_write_cr3;
 }
 
-__init pgd_t *xen_setup_kernel_pagetable(pgd_t *pgd,
+pgd_t * __init xen_setup_kernel_pagetable(pgd_t *pgd,
 					 unsigned long max_pfn)
 {
 	pmd_t *kernel_pmd;
@@ -1888,7 +1776,9 @@
 	initial_kernel_pmd =
 		extend_brk(sizeof(pmd_t) * PTRS_PER_PMD, PAGE_SIZE);
 
-	max_pfn_mapped = PFN_DOWN(__pa(xen_start_info->mfn_list));
+	max_pfn_mapped = PFN_DOWN(__pa(xen_start_info->pt_base) +
+				  xen_start_info->nr_pt_frames * PAGE_SIZE +
+				  512*1024);
 
 	kernel_pmd = m2v(pgd[KERNEL_PGD_BOUNDARY].pgd);
 	memcpy(initial_kernel_pmd, kernel_pmd, sizeof(pmd_t) * PTRS_PER_PMD);
@@ -1986,7 +1876,7 @@
 #endif
 }
 
-__init void xen_ident_map_ISA(void)
+void __init xen_ident_map_ISA(void)
 {
 	unsigned long pa;
 
@@ -2009,7 +1899,7 @@
 	xen_flush_tlb();
 }
 
-static __init void xen_post_allocator_init(void)
+static void __init xen_post_allocator_init(void)
 {
 #ifdef CONFIG_XEN_DEBUG
 	pv_mmu_ops.make_pte = PV_CALLEE_SAVE(xen_make_pte_debug);
@@ -2046,7 +1936,7 @@
 	preempt_enable();
 }
 
-static const struct pv_mmu_ops xen_mmu_ops __initdata = {
+static const struct pv_mmu_ops xen_mmu_ops __initconst = {
 	.read_cr2 = xen_read_cr2,
 	.write_cr2 = xen_write_cr2,
 
@@ -2371,7 +2261,7 @@
 	struct remap_data *rmd = data;
 	pte_t pte = pte_mkspecial(pfn_pte(rmd->mfn++, rmd->prot));
 
-	rmd->mmu_update->ptr = arbitrary_virt_to_machine(ptep).maddr;
+	rmd->mmu_update->ptr = virt_to_machine(ptep).maddr;
 	rmd->mmu_update->val = pte_val_ma(pte);
 	rmd->mmu_update++;
 
@@ -2425,7 +2315,6 @@
 EXPORT_SYMBOL_GPL(xen_remap_domain_mfn_range);
 
 #ifdef CONFIG_XEN_DEBUG_FS
-
 static int p2m_dump_open(struct inode *inode, struct file *filp)
 {
 	return single_open(filp, p2m_dump_show, NULL);
@@ -2437,65 +2326,4 @@
 	.llseek		= seq_lseek,
 	.release	= single_release,
 };
-
-static struct dentry *d_mmu_debug;
-
-static int __init xen_mmu_debugfs(void)
-{
-	struct dentry *d_xen = xen_init_debugfs();
-
-	if (d_xen == NULL)
-		return -ENOMEM;
-
-	d_mmu_debug = debugfs_create_dir("mmu", d_xen);
-
-	debugfs_create_u8("zero_stats", 0644, d_mmu_debug, &zero_stats);
-
-	debugfs_create_u32("pgd_update", 0444, d_mmu_debug, &mmu_stats.pgd_update);
-	debugfs_create_u32("pgd_update_pinned", 0444, d_mmu_debug,
-			   &mmu_stats.pgd_update_pinned);
-	debugfs_create_u32("pgd_update_batched", 0444, d_mmu_debug,
-			   &mmu_stats.pgd_update_pinned);
-
-	debugfs_create_u32("pud_update", 0444, d_mmu_debug, &mmu_stats.pud_update);
-	debugfs_create_u32("pud_update_pinned", 0444, d_mmu_debug,
-			   &mmu_stats.pud_update_pinned);
-	debugfs_create_u32("pud_update_batched", 0444, d_mmu_debug,
-			   &mmu_stats.pud_update_pinned);
-
-	debugfs_create_u32("pmd_update", 0444, d_mmu_debug, &mmu_stats.pmd_update);
-	debugfs_create_u32("pmd_update_pinned", 0444, d_mmu_debug,
-			   &mmu_stats.pmd_update_pinned);
-	debugfs_create_u32("pmd_update_batched", 0444, d_mmu_debug,
-			   &mmu_stats.pmd_update_pinned);
-
-	debugfs_create_u32("pte_update", 0444, d_mmu_debug, &mmu_stats.pte_update);
-//	debugfs_create_u32("pte_update_pinned", 0444, d_mmu_debug,
-//			   &mmu_stats.pte_update_pinned);
-	debugfs_create_u32("pte_update_batched", 0444, d_mmu_debug,
-			   &mmu_stats.pte_update_pinned);
-
-	debugfs_create_u32("mmu_update", 0444, d_mmu_debug, &mmu_stats.mmu_update);
-	debugfs_create_u32("mmu_update_extended", 0444, d_mmu_debug,
-			   &mmu_stats.mmu_update_extended);
-	xen_debugfs_create_u32_array("mmu_update_histo", 0444, d_mmu_debug,
-				     mmu_stats.mmu_update_histo, 20);
-
-	debugfs_create_u32("set_pte_at", 0444, d_mmu_debug, &mmu_stats.set_pte_at);
-	debugfs_create_u32("set_pte_at_batched", 0444, d_mmu_debug,
-			   &mmu_stats.set_pte_at_batched);
-	debugfs_create_u32("set_pte_at_current", 0444, d_mmu_debug,
-			   &mmu_stats.set_pte_at_current);
-	debugfs_create_u32("set_pte_at_kernel", 0444, d_mmu_debug,
-			   &mmu_stats.set_pte_at_kernel);
-
-	debugfs_create_u32("prot_commit", 0444, d_mmu_debug, &mmu_stats.prot_commit);
-	debugfs_create_u32("prot_commit_batched", 0444, d_mmu_debug,
-			   &mmu_stats.prot_commit_batched);
-
-	debugfs_create_file("p2m", 0600, d_mmu_debug, NULL, &p2m_dump_fops);
-	return 0;
-}
-fs_initcall(xen_mmu_debugfs);
-
-#endif	/* CONFIG_XEN_DEBUG_FS */
+#endif /* CONFIG_XEN_DEBUG_FS */
diff -druN linux-2.6.39-libre/arch/x86/xen/mmu.h linux-3.0-rc7-libre/arch/x86/xen/mmu.h
--- linux-2.6.39-libre/arch/x86/xen/mmu.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/xen/mmu.h	2011-07-11 19:51:52.000000000 -0400
@@ -15,43 +15,6 @@
 
 void set_pte_mfn(unsigned long vaddr, unsigned long pfn, pgprot_t flags);
 
-
-void xen_activate_mm(struct mm_struct *prev, struct mm_struct *next);
-void xen_dup_mmap(struct mm_struct *oldmm, struct mm_struct *mm);
-void xen_exit_mmap(struct mm_struct *mm);
-
-pteval_t xen_pte_val(pte_t);
-pmdval_t xen_pmd_val(pmd_t);
-pgdval_t xen_pgd_val(pgd_t);
-
-pte_t xen_make_pte(pteval_t);
-pmd_t xen_make_pmd(pmdval_t);
-pgd_t xen_make_pgd(pgdval_t);
-
-void xen_set_pte(pte_t *ptep, pte_t pteval);
-void xen_set_pte_at(struct mm_struct *mm, unsigned long addr,
-		    pte_t *ptep, pte_t pteval);
-
-#ifdef CONFIG_X86_PAE
-void xen_set_pte_atomic(pte_t *ptep, pte_t pte);
-void xen_pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep);
-void xen_pmd_clear(pmd_t *pmdp);
-#endif	/* CONFIG_X86_PAE */
-
-void xen_set_pmd(pmd_t *pmdp, pmd_t pmdval);
-void xen_set_pud(pud_t *ptr, pud_t val);
-void xen_set_pmd_hyper(pmd_t *pmdp, pmd_t pmdval);
-void xen_set_pud_hyper(pud_t *ptr, pud_t val);
-
-#if PAGETABLE_LEVELS == 4
-pudval_t xen_pud_val(pud_t pud);
-pud_t xen_make_pud(pudval_t pudval);
-void xen_set_pgd(pgd_t *pgdp, pgd_t pgd);
-void xen_set_pgd_hyper(pgd_t *pgdp, pgd_t pgd);
-#endif
-
-pgd_t *xen_get_user_pgd(pgd_t *pgd);
-
 pte_t xen_ptep_modify_prot_start(struct mm_struct *mm, unsigned long addr, pte_t *ptep);
 void  xen_ptep_modify_prot_commit(struct mm_struct *mm, unsigned long addr,
 				  pte_t *ptep, pte_t pte);
diff -druN linux-2.6.39-libre/arch/x86/xen/multicalls.c linux-3.0-rc7-libre/arch/x86/xen/multicalls.c
--- linux-2.6.39-libre/arch/x86/xen/multicalls.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/xen/multicalls.c	2011-07-11 19:51:52.000000000 -0400
@@ -189,10 +189,10 @@
 	unsigned argidx = roundup(b->argidx, sizeof(u64));
 
 	BUG_ON(preemptible());
-	BUG_ON(b->argidx > MC_ARGS);
+	BUG_ON(b->argidx >= MC_ARGS);
 
 	if (b->mcidx == MC_BATCH ||
-	    (argidx + args) > MC_ARGS) {
+	    (argidx + args) >= MC_ARGS) {
 		mc_stats_flush(b->mcidx == MC_BATCH ? FL_SLOTS : FL_ARGS);
 		xen_mc_flush();
 		argidx = roundup(b->argidx, sizeof(u64));
@@ -206,7 +206,7 @@
 	ret.args = &b->args[argidx];
 	b->argidx = argidx + args;
 
-	BUG_ON(b->argidx > MC_ARGS);
+	BUG_ON(b->argidx >= MC_ARGS);
 	return ret;
 }
 
@@ -216,7 +216,7 @@
 	struct multicall_space ret = { NULL, NULL };
 
 	BUG_ON(preemptible());
-	BUG_ON(b->argidx > MC_ARGS);
+	BUG_ON(b->argidx >= MC_ARGS);
 
 	if (b->mcidx == 0)
 		return ret;
@@ -224,14 +224,14 @@
 	if (b->entries[b->mcidx - 1].op != op)
 		return ret;
 
-	if ((b->argidx + size) > MC_ARGS)
+	if ((b->argidx + size) >= MC_ARGS)
 		return ret;
 
 	ret.mc = &b->entries[b->mcidx - 1];
 	ret.args = &b->args[b->argidx];
 	b->argidx += size;
 
-	BUG_ON(b->argidx > MC_ARGS);
+	BUG_ON(b->argidx >= MC_ARGS);
 	return ret;
 }
 
diff -druN linux-2.6.39-libre/arch/x86/xen/p2m.c linux-3.0-rc7-libre/arch/x86/xen/p2m.c
--- linux-2.6.39-libre/arch/x86/xen/p2m.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/xen/p2m.c	2011-07-11 19:51:52.000000000 -0400
@@ -522,11 +522,20 @@
 	/* Boundary cross-over for the edges: */
 	if (idx) {
 		unsigned long *p2m = extend_brk(PAGE_SIZE, PAGE_SIZE);
+		unsigned long *mid_mfn_p;
 
 		p2m_init(p2m);
 
 		p2m_top[topidx][mididx] = p2m;
 
+		/* For save/restore we need to MFN of the P2M saved */
+		
+		mid_mfn_p = p2m_top_mfn_p[topidx];
+		WARN(mid_mfn_p[mididx] != virt_to_mfn(p2m_missing),
+			"P2M_TOP_P[%d][%d] != MFN of p2m_missing!\n",
+			topidx, mididx);
+		mid_mfn_p[mididx] = virt_to_mfn(p2m);
+
 	}
 	return idx != 0;
 }
@@ -549,12 +558,29 @@
 		pfn += P2M_MID_PER_PAGE * P2M_PER_PAGE)
 	{
 		unsigned topidx = p2m_top_index(pfn);
-		if (p2m_top[topidx] == p2m_mid_missing) {
-			unsigned long **mid = extend_brk(PAGE_SIZE, PAGE_SIZE);
+		unsigned long *mid_mfn_p;
+		unsigned long **mid;
+
+		mid = p2m_top[topidx];
+		mid_mfn_p = p2m_top_mfn_p[topidx];
+		if (mid == p2m_mid_missing) {
+			mid = extend_brk(PAGE_SIZE, PAGE_SIZE);
 
 			p2m_mid_init(mid);
 
 			p2m_top[topidx] = mid;
+
+			BUG_ON(mid_mfn_p != p2m_mid_missing_mfn);
+		}
+		/* And the save/restore P2M tables.. */
+		if (mid_mfn_p == p2m_mid_missing_mfn) {
+			mid_mfn_p = extend_brk(PAGE_SIZE, PAGE_SIZE);
+			p2m_mid_mfn_init(mid_mfn_p);
+
+			p2m_top_mfn_p[topidx] = mid_mfn_p;
+			p2m_top_mfn[topidx] = virt_to_mfn(mid_mfn_p);
+			/* Note: we don't set mid_mfn_p[midix] here,
+		 	 * look in __early_alloc_p2m */
 		}
 	}
 
@@ -650,7 +676,7 @@
 }
 
 /* Add an MFN override for a particular page */
-int m2p_add_override(unsigned long mfn, struct page *page)
+int m2p_add_override(unsigned long mfn, struct page *page, bool clear_pte)
 {
 	unsigned long flags;
 	unsigned long pfn;
@@ -662,7 +688,6 @@
 	if (!PageHighMem(page)) {
 		address = (unsigned long)__va(pfn << PAGE_SHIFT);
 		ptep = lookup_address(address, &level);
-
 		if (WARN(ptep == NULL || level != PG_LEVEL_4K,
 					"m2p_add_override: pfn %lx not mapped", pfn))
 			return -EINVAL;
@@ -674,18 +699,17 @@
 	if (unlikely(!set_phys_to_machine(pfn, FOREIGN_FRAME(mfn))))
 		return -ENOMEM;
 
-	if (!PageHighMem(page))
+	if (clear_pte && !PageHighMem(page))
 		/* Just zap old mapping for now */
 		pte_clear(&init_mm, address, ptep);
-
 	spin_lock_irqsave(&m2p_override_lock, flags);
 	list_add(&page->lru,  &m2p_overrides[mfn_hash(mfn)]);
 	spin_unlock_irqrestore(&m2p_override_lock, flags);
 
 	return 0;
 }
-
-int m2p_remove_override(struct page *page)
+EXPORT_SYMBOL_GPL(m2p_add_override);
+int m2p_remove_override(struct page *page, bool clear_pte)
 {
 	unsigned long flags;
 	unsigned long mfn;
@@ -713,7 +737,7 @@
 	spin_unlock_irqrestore(&m2p_override_lock, flags);
 	set_phys_to_machine(pfn, page->index);
 
-	if (!PageHighMem(page))
+	if (clear_pte && !PageHighMem(page))
 		set_pte_at(&init_mm, address, ptep,
 				pfn_pte(pfn, PAGE_KERNEL));
 		/* No tlb flush necessary because the caller already
@@ -721,6 +745,7 @@
 
 	return 0;
 }
+EXPORT_SYMBOL_GPL(m2p_remove_override);
 
 struct page *m2p_find_override(unsigned long mfn)
 {
diff -druN linux-2.6.39-libre/arch/x86/xen/pci-swiotlb-xen.c linux-3.0-rc7-libre/arch/x86/xen/pci-swiotlb-xen.c
--- linux-2.6.39-libre/arch/x86/xen/pci-swiotlb-xen.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/xen/pci-swiotlb-xen.c	2011-07-11 19:51:52.000000000 -0400
@@ -36,7 +36,7 @@
 
 	/* If running as PV guest, either iommu=soft, or swiotlb=force will
 	 * activate this IOMMU. If running as PV privileged, activate it
-	 * irregardlesss.
+	 * irregardless.
 	 */
 	if ((xen_initial_domain() || swiotlb || swiotlb_force) &&
 	    (xen_pv_domain()))
diff -druN linux-2.6.39-libre/arch/x86/xen/setup.c linux-3.0-rc7-libre/arch/x86/xen/setup.c
--- linux-2.6.39-libre/arch/x86/xen/setup.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/xen/setup.c	2011-07-11 19:51:52.000000000 -0400
@@ -50,7 +50,7 @@
  */
 #define EXTRA_MEM_RATIO		(10)
 
-static __init void xen_add_extra_mem(unsigned long pages)
+static void __init xen_add_extra_mem(unsigned long pages)
 {
 	unsigned long pfn;
 
@@ -166,7 +166,7 @@
 		if (last > end)
 			continue;
 
-		if (entry->type == E820_RAM) {
+		if ((entry->type == E820_RAM) || (entry->type == E820_UNUSABLE)) {
 			if (start > start_pci)
 				identity += set_phys_range_identity(
 						PFN_UP(start_pci), PFN_DOWN(start));
@@ -227,7 +227,7 @@
 
 	memcpy(map_raw, map, sizeof(map));
 	e820.nr_map = 0;
-	xen_extra_mem_start = max((1ULL << 32), mem_end);
+	xen_extra_mem_start = mem_end;
 	for (i = 0; i < memmap.nr_entries; i++) {
 		unsigned long long end;
 
@@ -262,6 +262,12 @@
 		if (map[i].size > 0)
 			e820_add_region(map[i].addr, map[i].size, map[i].type);
 	}
+	/* Align the balloon area so that max_low_pfn does not get set
+	 * to be at the _end_ of the PCI gap at the far end (fee01000).
+	 * Note that xen_extra_mem_start gets set in the loop above to be
+	 * past the last E820 region. */
+	if (xen_initial_domain() && (xen_extra_mem_start < (1ULL<<32)))
+		xen_extra_mem_start = (1ULL<<32);
 
 	/*
 	 * In domU, the ISA region is normal, usable memory, but we
@@ -336,7 +342,7 @@
 #endif
 }
 
-static __cpuinit int register_callback(unsigned type, const void *func)
+static int __cpuinit register_callback(unsigned type, const void *func)
 {
 	struct callback_register callback = {
 		.type = type,
diff -druN linux-2.6.39-libre/arch/x86/xen/smp.c linux-3.0-rc7-libre/arch/x86/xen/smp.c
--- linux-2.6.39-libre/arch/x86/xen/smp.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/xen/smp.c	2011-07-11 19:51:52.000000000 -0400
@@ -46,18 +46,17 @@
 static irqreturn_t xen_call_function_single_interrupt(int irq, void *dev_id);
 
 /*
- * Reschedule call back. Nothing to do,
- * all the work is done automatically when
- * we return from the interrupt.
+ * Reschedule call back.
  */
 static irqreturn_t xen_reschedule_interrupt(int irq, void *dev_id)
 {
 	inc_irq_stat(irq_resched_count);
+	scheduler_ipi();
 
 	return IRQ_HANDLED;
 }
 
-static __cpuinit void cpu_bringup(void)
+static void __cpuinit cpu_bringup(void)
 {
 	int cpu = smp_processor_id();
 
@@ -85,7 +84,7 @@
 	wmb();			/* make sure everything is out */
 }
 
-static __cpuinit void cpu_bringup_and_idle(void)
+static void __cpuinit cpu_bringup_and_idle(void)
 {
 	cpu_bringup();
 	cpu_idle();
@@ -206,11 +205,18 @@
 static void __init xen_smp_prepare_cpus(unsigned int max_cpus)
 {
 	unsigned cpu;
+	unsigned int i;
 
 	xen_init_lock_cpu(0);
 
 	smp_store_cpu_info(0);
 	cpu_data(0).x86_max_cores = 1;
+
+	for_each_possible_cpu(i) {
+		zalloc_cpumask_var(&per_cpu(cpu_sibling_map, i), GFP_KERNEL);
+		zalloc_cpumask_var(&per_cpu(cpu_core_map, i), GFP_KERNEL);
+		zalloc_cpumask_var(&per_cpu(cpu_llc_shared_map, i), GFP_KERNEL);
+	}
 	set_cpu_sibling_map(0);
 
 	if (xen_smp_intr_init(0))
@@ -242,7 +248,7 @@
 	}
 }
 
-static __cpuinit int
+static int __cpuinit
 cpu_initialize_context(unsigned int cpu, struct task_struct *idle)
 {
 	struct vcpu_guest_context *ctxt;
@@ -486,7 +492,7 @@
 	return IRQ_HANDLED;
 }
 
-static const struct smp_ops xen_smp_ops __initdata = {
+static const struct smp_ops xen_smp_ops __initconst = {
 	.smp_prepare_boot_cpu = xen_smp_prepare_boot_cpu,
 	.smp_prepare_cpus = xen_smp_prepare_cpus,
 	.smp_cpus_done = xen_smp_cpus_done,
diff -druN linux-2.6.39-libre/arch/x86/xen/time.c linux-3.0-rc7-libre/arch/x86/xen/time.c
--- linux-2.6.39-libre/arch/x86/xen/time.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/xen/time.c	2011-07-11 19:51:52.000000000 -0400
@@ -26,8 +26,6 @@
 
 #include "xen-ops.h"
 
-#define XEN_SHIFT 22
-
 /* Xen may fire a timer up to this many ns early */
 #define TIMER_SLOP	100000
 #define NS_PER_TICK	(1000000000LL / HZ)
@@ -211,8 +209,6 @@
 	.rating = 400,
 	.read = xen_clocksource_get_cycles,
 	.mask = ~0,
-	.mult = 1<<XEN_SHIFT,		/* time directly in nanoseconds */
-	.shift = XEN_SHIFT,
 	.flags = CLOCK_SOURCE_IS_CONTINUOUS,
 };
 
@@ -439,16 +435,16 @@
 	}
 }
 
-static const struct pv_time_ops xen_time_ops __initdata = {
+static const struct pv_time_ops xen_time_ops __initconst = {
 	.sched_clock = xen_clocksource_read,
 };
 
-static __init void xen_time_init(void)
+static void __init xen_time_init(void)
 {
 	int cpu = smp_processor_id();
 	struct timespec tp;
 
-	clocksource_register(&xen_clocksource);
+	clocksource_register_hz(&xen_clocksource, NSEC_PER_SEC);
 
 	if (HYPERVISOR_vcpu_op(VCPUOP_stop_periodic_timer, cpu, NULL) == 0) {
 		/* Successfully turned off 100Hz tick, so we have the
@@ -468,7 +464,7 @@
 	xen_setup_cpu_clockevents();
 }
 
-__init void xen_init_time_ops(void)
+void __init xen_init_time_ops(void)
 {
 	pv_time_ops = xen_time_ops;
 
@@ -490,7 +486,7 @@
 	xen_setup_cpu_clockevents();
 }
 
-__init void xen_hvm_init_time_ops(void)
+void __init xen_hvm_init_time_ops(void)
 {
 	/* vector callback is needed otherwise we cannot receive interrupts
 	 * on cpu > 0 and at this point we don't know how many cpus are
diff -druN linux-2.6.39-libre/arch/x86/xen/xen-ops.h linux-3.0-rc7-libre/arch/x86/xen/xen-ops.h
--- linux-2.6.39-libre/arch/x86/xen/xen-ops.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/x86/xen/xen-ops.h	2011-07-11 19:51:52.000000000 -0400
@@ -74,7 +74,7 @@
 
 #ifdef CONFIG_PARAVIRT_SPINLOCKS
 void __init xen_init_spinlocks(void);
-__cpuinit void xen_init_lock_cpu(int cpu);
+void __cpuinit xen_init_lock_cpu(int cpu);
 void xen_uninit_lock_cpu(int cpu);
 #else
 static inline void xen_init_spinlocks(void)
diff -druN linux-2.6.39-libre/arch/xtensa/configs/s6105_defconfig linux-3.0-rc7-libre/arch/xtensa/configs/s6105_defconfig
--- linux-2.6.39-libre/arch/xtensa/configs/s6105_defconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/xtensa/configs/s6105_defconfig	2011-07-11 19:51:52.000000000 -0400
@@ -23,7 +23,6 @@
 #
 CONFIG_EXPERIMENTAL=y
 CONFIG_BROKEN_ON_SMP=y
-CONFIG_LOCK_KERNEL=y
 CONFIG_INIT_ENV_ARG_LIMIT=32
 CONFIG_LOCALVERSION=""
 CONFIG_LOCALVERSION_AUTO=y
diff -druN linux-2.6.39-libre/arch/xtensa/include/asm/page.h linux-3.0-rc7-libre/arch/xtensa/include/asm/page.h
--- linux-2.6.39-libre/arch/xtensa/include/asm/page.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/xtensa/include/asm/page.h	2011-07-11 19:51:52.000000000 -0400
@@ -171,10 +171,6 @@
 #define virt_addr_valid(kaddr)	pfn_valid(__pa(kaddr) >> PAGE_SHIFT)
 #define page_to_phys(page)	(page_to_pfn(page) << PAGE_SHIFT)
 
-#ifdef CONFIG_MMU
-#define WANT_PAGE_VIRTUAL
-#endif
-
 #endif /* __ASSEMBLY__ */
 
 #define VM_DATA_DEFAULT_FLAGS	(VM_READ | VM_WRITE | VM_EXEC | \
diff -druN linux-2.6.39-libre/arch/xtensa/include/asm/unistd.h linux-3.0-rc7-libre/arch/xtensa/include/asm/unistd.h
--- linux-2.6.39-libre/arch/xtensa/include/asm/unistd.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/xtensa/include/asm/unistd.h	2011-07-11 19:51:52.000000000 -0400
@@ -683,8 +683,10 @@
 __SYSCALL(306, sys_eventfd, 1)
 #define __NR_recvmmsg				307
 __SYSCALL(307, sys_recvmmsg, 5)
+#define __NR_setns				308
+__SYSCALL(308, sys_setns, 2)
 
-#define __NR_syscall_count			308
+#define __NR_syscall_count			309
 
 /*
  * sysxtensa syscall handler
diff -druN linux-2.6.39-libre/arch/xtensa/Kconfig linux-3.0-rc7-libre/arch/xtensa/Kconfig
--- linux-2.6.39-libre/arch/xtensa/Kconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/xtensa/Kconfig	2011-07-11 19:51:52.000000000 -0400
@@ -20,12 +20,6 @@
 config RWSEM_XCHGADD_ALGORITHM
 	def_bool y
 
-config GENERIC_FIND_NEXT_BIT
-	def_bool y
-
-config GENERIC_FIND_BIT_LE
-	def_bool y
-
 config GENERIC_HWEIGHT
 	def_bool y
 
diff -druN linux-2.6.39-libre/arch/xtensa/kernel/vmlinux.lds.S linux-3.0-rc7-libre/arch/xtensa/kernel/vmlinux.lds.S
--- linux-2.6.39-libre/arch/xtensa/kernel/vmlinux.lds.S	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/xtensa/kernel/vmlinux.lds.S	2011-07-11 19:51:52.000000000 -0400
@@ -155,7 +155,7 @@
     INIT_RAM_FS
   }
 
-  PERCPU(XCHAL_ICACHE_LINESIZE, PAGE_SIZE)
+  PERCPU_SECTION(XCHAL_ICACHE_LINESIZE)
 
   /* We need this dummy segment here */
 
diff -druN linux-2.6.39-libre/arch/xtensa/mm/mmu.c linux-3.0-rc7-libre/arch/xtensa/mm/mmu.c
--- linux-2.6.39-libre/arch/xtensa/mm/mmu.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/xtensa/mm/mmu.c	2011-07-11 19:51:52.000000000 -0400
@@ -14,8 +14,6 @@
 #include <asm/mmu_context.h>
 #include <asm/page.h>
 
-DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
-
 void __init paging_init(void)
 {
 	memset(swapper_pg_dir, 0, PAGE_SIZE);
diff -druN linux-2.6.39-libre/arch/xtensa/mm/pgtable.c linux-3.0-rc7-libre/arch/xtensa/mm/pgtable.c
--- linux-2.6.39-libre/arch/xtensa/mm/pgtable.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/arch/xtensa/mm/pgtable.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,72 +0,0 @@
-/*
- * arch/xtensa/mm/pgtable.c
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 2001 - 2005 Tensilica Inc.
- *
- * Chris Zankel <chris@zankel.net>
- */
-
-#if (DCACHE_SIZE > PAGE_SIZE)
-
-pte_t* pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address)
-{
-	pte_t *pte = NULL, *p;
-	int color = ADDR_COLOR(address);
-	int i;
-
-	p = (pte_t*) __get_free_pages(GFP_KERNEL|__GFP_REPEAT, COLOR_ORDER);
-
-	if (likely(p)) {
-		split_page(virt_to_page(p), COLOR_ORDER);
-
-		for (i = 0; i < COLOR_SIZE; i++) {
-			if (ADDR_COLOR(p) == color)
-				pte = p;
-			else
-				free_page(p);
-			p += PTRS_PER_PTE;
-		}
-		clear_page(pte);
-	}
-	return pte;
-}
-
-#ifdef PROFILING
-
-int mask;
-int hit;
-int flush;
-
-#endif
-
-struct page* pte_alloc_one(struct mm_struct *mm, unsigned long address)
-{
-	struct page *page = NULL, *p;
-	int color = ADDR_COLOR(address);
-
-	p = alloc_pages(GFP_KERNEL | __GFP_REPEAT, PTE_ORDER);
-
-	if (likely(p)) {
-		split_page(p, COLOR_ORDER);
-
-		for (i = 0; i < PAGE_ORDER; i++) {
-			if (PADDR_COLOR(page_address(p)) == color)
-				page = p;
-			else
-				__free_page(p);
-			p++;
-		}
-		clear_highpage(page);
-	}
-
-	return page;
-}
-
-#endif
-
-
-
diff -druN linux-2.6.39-libre/block/blk-cgroup.c linux-3.0-rc7-libre/block/blk-cgroup.c
--- linux-2.6.39-libre/block/blk-cgroup.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/block/blk-cgroup.c	2011-07-11 19:51:52.000000000 -0400
@@ -30,10 +30,8 @@
 
 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 int blkiocg_can_attach_task(struct cgroup *, struct task_struct *);
+static void blkiocg_attach_task(struct cgroup *, struct task_struct *);
 static void blkiocg_destroy(struct cgroup_subsys *, struct cgroup *);
 static int blkiocg_populate(struct cgroup_subsys *, struct cgroup *);
 
@@ -46,8 +44,8 @@
 struct cgroup_subsys blkio_subsys = {
 	.name = "blkio",
 	.create = blkiocg_create,
-	.can_attach = blkiocg_can_attach,
-	.attach = blkiocg_attach,
+	.can_attach_task = blkiocg_can_attach_task,
+	.attach_task = blkiocg_attach_task,
 	.destroy = blkiocg_destroy,
 	.populate = blkiocg_populate,
 #ifdef CONFIG_BLK_CGROUP
@@ -385,25 +383,40 @@
 
 	spin_lock_irqsave(&blkg->stats_lock, flags);
 	blkg->stats.time += time;
+#ifdef CONFIG_DEBUG_BLK_CGROUP
 	blkg->stats.unaccounted_time += unaccounted_time;
+#endif
 	spin_unlock_irqrestore(&blkg->stats_lock, flags);
 }
 EXPORT_SYMBOL_GPL(blkiocg_update_timeslice_used);
 
+/*
+ * should be called under rcu read lock or queue lock to make sure blkg pointer
+ * is valid.
+ */
 void blkiocg_update_dispatch_stats(struct blkio_group *blkg,
 				uint64_t bytes, bool direction, bool sync)
 {
-	struct blkio_group_stats *stats;
+	struct blkio_group_stats_cpu *stats_cpu;
 	unsigned long flags;
 
-	spin_lock_irqsave(&blkg->stats_lock, flags);
-	stats = &blkg->stats;
-	stats->sectors += bytes >> 9;
-	blkio_add_stat(stats->stat_arr[BLKIO_STAT_SERVICED], 1, direction,
-			sync);
-	blkio_add_stat(stats->stat_arr[BLKIO_STAT_SERVICE_BYTES], bytes,
-			direction, sync);
-	spin_unlock_irqrestore(&blkg->stats_lock, flags);
+	/*
+	 * Disabling interrupts to provide mutual exclusion between two
+	 * writes on same cpu. It probably is not needed for 64bit. Not
+	 * optimizing that case yet.
+	 */
+	local_irq_save(flags);
+
+	stats_cpu = this_cpu_ptr(blkg->stats_cpu);
+
+	u64_stats_update_begin(&stats_cpu->syncp);
+	stats_cpu->sectors += bytes >> 9;
+	blkio_add_stat(stats_cpu->stat_arr_cpu[BLKIO_STAT_CPU_SERVICED],
+			1, direction, sync);
+	blkio_add_stat(stats_cpu->stat_arr_cpu[BLKIO_STAT_CPU_SERVICE_BYTES],
+			bytes, direction, sync);
+	u64_stats_update_end(&stats_cpu->syncp);
+	local_irq_restore(flags);
 }
 EXPORT_SYMBOL_GPL(blkiocg_update_dispatch_stats);
 
@@ -426,18 +439,44 @@
 }
 EXPORT_SYMBOL_GPL(blkiocg_update_completion_stats);
 
+/*  Merged stats are per cpu.  */
 void blkiocg_update_io_merged_stats(struct blkio_group *blkg, bool direction,
 					bool sync)
 {
+	struct blkio_group_stats_cpu *stats_cpu;
 	unsigned long flags;
 
-	spin_lock_irqsave(&blkg->stats_lock, flags);
-	blkio_add_stat(blkg->stats.stat_arr[BLKIO_STAT_MERGED], 1, direction,
-			sync);
-	spin_unlock_irqrestore(&blkg->stats_lock, flags);
+	/*
+	 * Disabling interrupts to provide mutual exclusion between two
+	 * writes on same cpu. It probably is not needed for 64bit. Not
+	 * optimizing that case yet.
+	 */
+	local_irq_save(flags);
+
+	stats_cpu = this_cpu_ptr(blkg->stats_cpu);
+
+	u64_stats_update_begin(&stats_cpu->syncp);
+	blkio_add_stat(stats_cpu->stat_arr_cpu[BLKIO_STAT_CPU_MERGED], 1,
+				direction, sync);
+	u64_stats_update_end(&stats_cpu->syncp);
+	local_irq_restore(flags);
 }
 EXPORT_SYMBOL_GPL(blkiocg_update_io_merged_stats);
 
+/*
+ * This function allocates the per cpu stats for blkio_group. Should be called
+ * from sleepable context as alloc_per_cpu() requires that.
+ */
+int blkio_alloc_blkg_stats(struct blkio_group *blkg)
+{
+	/* Allocate memory for per cpu stats */
+	blkg->stats_cpu = alloc_percpu(struct blkio_group_stats_cpu);
+	if (!blkg->stats_cpu)
+		return -ENOMEM;
+	return 0;
+}
+EXPORT_SYMBOL_GPL(blkio_alloc_blkg_stats);
+
 void blkiocg_add_blkio_group(struct blkio_cgroup *blkcg,
 		struct blkio_group *blkg, void *key, dev_t dev,
 		enum blkio_policy_id plid)
@@ -508,6 +547,30 @@
 }
 EXPORT_SYMBOL_GPL(blkiocg_lookup_group);
 
+static void blkio_reset_stats_cpu(struct blkio_group *blkg)
+{
+	struct blkio_group_stats_cpu *stats_cpu;
+	int i, j, k;
+	/*
+	 * Note: On 64 bit arch this should not be an issue. This has the
+	 * possibility of returning some inconsistent value on 32bit arch
+	 * as 64bit update on 32bit is non atomic. Taking care of this
+	 * corner case makes code very complicated, like sending IPIs to
+	 * cpus, taking care of stats of offline cpus etc.
+	 *
+	 * reset stats is anyway more of a debug feature and this sounds a
+	 * corner case. So I am not complicating the code yet until and
+	 * unless this becomes a real issue.
+	 */
+	for_each_possible_cpu(i) {
+		stats_cpu = per_cpu_ptr(blkg->stats_cpu, i);
+		stats_cpu->sectors = 0;
+		for(j = 0; j < BLKIO_STAT_CPU_NR; j++)
+			for (k = 0; k < BLKIO_STAT_TOTAL; k++)
+				stats_cpu->stat_arr_cpu[j][k] = 0;
+	}
+}
+
 static int
 blkiocg_reset_stats(struct cgroup *cgroup, struct cftype *cftype, u64 val)
 {
@@ -552,7 +615,11 @@
 		}
 #endif
 		spin_unlock(&blkg->stats_lock);
+
+		/* Reset Per cpu stats which don't take blkg->stats_lock */
+		blkio_reset_stats_cpu(blkg);
 	}
+
 	spin_unlock_irq(&blkcg->lock);
 	return 0;
 }
@@ -598,6 +665,59 @@
 	return val;
 }
 
+
+static uint64_t blkio_read_stat_cpu(struct blkio_group *blkg,
+			enum stat_type_cpu type, enum stat_sub_type sub_type)
+{
+	int cpu;
+	struct blkio_group_stats_cpu *stats_cpu;
+	u64 val = 0, tval;
+
+	for_each_possible_cpu(cpu) {
+		unsigned int start;
+		stats_cpu  = per_cpu_ptr(blkg->stats_cpu, cpu);
+
+		do {
+			start = u64_stats_fetch_begin(&stats_cpu->syncp);
+			if (type == BLKIO_STAT_CPU_SECTORS)
+				tval = stats_cpu->sectors;
+			else
+				tval = stats_cpu->stat_arr_cpu[type][sub_type];
+		} while(u64_stats_fetch_retry(&stats_cpu->syncp, start));
+
+		val += tval;
+	}
+
+	return val;
+}
+
+static uint64_t blkio_get_stat_cpu(struct blkio_group *blkg,
+		struct cgroup_map_cb *cb, dev_t dev, enum stat_type_cpu type)
+{
+	uint64_t disk_total, val;
+	char key_str[MAX_KEY_LEN];
+	enum stat_sub_type sub_type;
+
+	if (type == BLKIO_STAT_CPU_SECTORS) {
+		val = blkio_read_stat_cpu(blkg, type, 0);
+		return blkio_fill_stat(key_str, MAX_KEY_LEN - 1, val, cb, dev);
+	}
+
+	for (sub_type = BLKIO_STAT_READ; sub_type < BLKIO_STAT_TOTAL;
+			sub_type++) {
+		blkio_get_key_name(sub_type, dev, key_str, MAX_KEY_LEN, false);
+		val = blkio_read_stat_cpu(blkg, type, sub_type);
+		cb->fill(cb, key_str, val);
+	}
+
+	disk_total = blkio_read_stat_cpu(blkg, type, BLKIO_STAT_READ) +
+			blkio_read_stat_cpu(blkg, type, BLKIO_STAT_WRITE);
+
+	blkio_get_key_name(BLKIO_STAT_TOTAL, dev, key_str, MAX_KEY_LEN, false);
+	cb->fill(cb, key_str, disk_total);
+	return disk_total;
+}
+
 /* This should be called with blkg->stats_lock held */
 static uint64_t blkio_get_stat(struct blkio_group *blkg,
 		struct cgroup_map_cb *cb, dev_t dev, enum stat_type type)
@@ -609,9 +729,6 @@
 	if (type == BLKIO_STAT_TIME)
 		return blkio_fill_stat(key_str, MAX_KEY_LEN - 1,
 					blkg->stats.time, cb, dev);
-	if (type == BLKIO_STAT_SECTORS)
-		return blkio_fill_stat(key_str, MAX_KEY_LEN - 1,
-					blkg->stats.sectors, cb, dev);
 #ifdef CONFIG_DEBUG_BLK_CGROUP
 	if (type == BLKIO_STAT_UNACCOUNTED_TIME)
 		return blkio_fill_stat(key_str, MAX_KEY_LEN - 1,
@@ -1075,8 +1192,8 @@
 }
 
 static int blkio_read_blkg_stats(struct blkio_cgroup *blkcg,
-		struct cftype *cft, struct cgroup_map_cb *cb, enum stat_type type,
-		bool show_total)
+		struct cftype *cft, struct cgroup_map_cb *cb,
+		enum stat_type type, bool show_total, bool pcpu)
 {
 	struct blkio_group *blkg;
 	struct hlist_node *n;
@@ -1087,10 +1204,15 @@
 		if (blkg->dev) {
 			if (!cftype_blkg_same_policy(cft, blkg))
 				continue;
-			spin_lock_irq(&blkg->stats_lock);
-			cgroup_total += blkio_get_stat(blkg, cb, blkg->dev,
-						type);
-			spin_unlock_irq(&blkg->stats_lock);
+			if (pcpu)
+				cgroup_total += blkio_get_stat_cpu(blkg, cb,
+						blkg->dev, type);
+			else {
+				spin_lock_irq(&blkg->stats_lock);
+				cgroup_total += blkio_get_stat(blkg, cb,
+						blkg->dev, type);
+				spin_unlock_irq(&blkg->stats_lock);
+			}
 		}
 	}
 	if (show_total)
@@ -1114,47 +1236,47 @@
 		switch(name) {
 		case BLKIO_PROP_time:
 			return blkio_read_blkg_stats(blkcg, cft, cb,
-						BLKIO_STAT_TIME, 0);
+						BLKIO_STAT_TIME, 0, 0);
 		case BLKIO_PROP_sectors:
 			return blkio_read_blkg_stats(blkcg, cft, cb,
-						BLKIO_STAT_SECTORS, 0);
+						BLKIO_STAT_CPU_SECTORS, 0, 1);
 		case BLKIO_PROP_io_service_bytes:
 			return blkio_read_blkg_stats(blkcg, cft, cb,
-						BLKIO_STAT_SERVICE_BYTES, 1);
+					BLKIO_STAT_CPU_SERVICE_BYTES, 1, 1);
 		case BLKIO_PROP_io_serviced:
 			return blkio_read_blkg_stats(blkcg, cft, cb,
-						BLKIO_STAT_SERVICED, 1);
+						BLKIO_STAT_CPU_SERVICED, 1, 1);
 		case BLKIO_PROP_io_service_time:
 			return blkio_read_blkg_stats(blkcg, cft, cb,
-						BLKIO_STAT_SERVICE_TIME, 1);
+						BLKIO_STAT_SERVICE_TIME, 1, 0);
 		case BLKIO_PROP_io_wait_time:
 			return blkio_read_blkg_stats(blkcg, cft, cb,
-						BLKIO_STAT_WAIT_TIME, 1);
+						BLKIO_STAT_WAIT_TIME, 1, 0);
 		case BLKIO_PROP_io_merged:
 			return blkio_read_blkg_stats(blkcg, cft, cb,
-						BLKIO_STAT_MERGED, 1);
+						BLKIO_STAT_CPU_MERGED, 1, 1);
 		case BLKIO_PROP_io_queued:
 			return blkio_read_blkg_stats(blkcg, cft, cb,
-						BLKIO_STAT_QUEUED, 1);
+						BLKIO_STAT_QUEUED, 1, 0);
 #ifdef CONFIG_DEBUG_BLK_CGROUP
 		case BLKIO_PROP_unaccounted_time:
 			return blkio_read_blkg_stats(blkcg, cft, cb,
-						BLKIO_STAT_UNACCOUNTED_TIME, 0);
+					BLKIO_STAT_UNACCOUNTED_TIME, 0, 0);
 		case BLKIO_PROP_dequeue:
 			return blkio_read_blkg_stats(blkcg, cft, cb,
-						BLKIO_STAT_DEQUEUE, 0);
+						BLKIO_STAT_DEQUEUE, 0, 0);
 		case BLKIO_PROP_avg_queue_size:
 			return blkio_read_blkg_stats(blkcg, cft, cb,
-						BLKIO_STAT_AVG_QUEUE_SIZE, 0);
+					BLKIO_STAT_AVG_QUEUE_SIZE, 0, 0);
 		case BLKIO_PROP_group_wait_time:
 			return blkio_read_blkg_stats(blkcg, cft, cb,
-						BLKIO_STAT_GROUP_WAIT_TIME, 0);
+					BLKIO_STAT_GROUP_WAIT_TIME, 0, 0);
 		case BLKIO_PROP_idle_time:
 			return blkio_read_blkg_stats(blkcg, cft, cb,
-						BLKIO_STAT_IDLE_TIME, 0);
+						BLKIO_STAT_IDLE_TIME, 0, 0);
 		case BLKIO_PROP_empty_time:
 			return blkio_read_blkg_stats(blkcg, cft, cb,
-						BLKIO_STAT_EMPTY_TIME, 0);
+						BLKIO_STAT_EMPTY_TIME, 0, 0);
 #endif
 		default:
 			BUG();
@@ -1164,10 +1286,10 @@
 		switch(name){
 		case BLKIO_THROTL_io_service_bytes:
 			return blkio_read_blkg_stats(blkcg, cft, cb,
-						BLKIO_STAT_SERVICE_BYTES, 1);
+						BLKIO_STAT_CPU_SERVICE_BYTES, 1, 1);
 		case BLKIO_THROTL_io_serviced:
 			return blkio_read_blkg_stats(blkcg, cft, cb,
-						BLKIO_STAT_SERVICED, 1);
+						BLKIO_STAT_CPU_SERVICED, 1, 1);
 		default:
 			BUG();
 		}
@@ -1492,9 +1614,7 @@
  * of the main cic data structures.  For now we allow a task to change
  * its cgroup only if it's the only owner of its ioc.
  */
-static int blkiocg_can_attach(struct cgroup_subsys *subsys,
-				struct cgroup *cgroup, struct task_struct *tsk,
-				bool threadgroup)
+static int blkiocg_can_attach_task(struct cgroup *cgrp, struct task_struct *tsk)
 {
 	struct io_context *ioc;
 	int ret = 0;
@@ -1509,9 +1629,7 @@
 	return ret;
 }
 
-static void blkiocg_attach(struct cgroup_subsys *subsys, struct cgroup *cgroup,
-				struct cgroup *prev, struct task_struct *tsk,
-				bool threadgroup)
+static void blkiocg_attach_task(struct cgroup *cgrp, struct task_struct *tsk)
 {
 	struct io_context *ioc;
 
diff -druN linux-2.6.39-libre/block/blk-cgroup.h linux-3.0-rc7-libre/block/blk-cgroup.h
--- linux-2.6.39-libre/block/blk-cgroup.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/block/blk-cgroup.h	2011-07-11 19:51:52.000000000 -0400
@@ -14,6 +14,7 @@
  */
 
 #include <linux/cgroup.h>
+#include <linux/u64_stats_sync.h>
 
 enum blkio_policy_id {
 	BLKIO_POLICY_PROP = 0,		/* Proportional Bandwidth division */
@@ -36,22 +37,15 @@
 	 * request completion for IOs doen by this cgroup. This may not be
 	 * accurate when NCQ is turned on. */
 	BLKIO_STAT_SERVICE_TIME = 0,
-	/* Total bytes transferred */
-	BLKIO_STAT_SERVICE_BYTES,
-	/* Total IOs serviced, post merge */
-	BLKIO_STAT_SERVICED,
 	/* Total time spent waiting in scheduler queue in ns */
 	BLKIO_STAT_WAIT_TIME,
-	/* Number of IOs merged */
-	BLKIO_STAT_MERGED,
 	/* Number of IOs queued up */
 	BLKIO_STAT_QUEUED,
 	/* All the single valued stats go below this */
 	BLKIO_STAT_TIME,
-	BLKIO_STAT_SECTORS,
+#ifdef CONFIG_DEBUG_BLK_CGROUP
 	/* Time not charged to this cgroup */
 	BLKIO_STAT_UNACCOUNTED_TIME,
-#ifdef CONFIG_DEBUG_BLK_CGROUP
 	BLKIO_STAT_AVG_QUEUE_SIZE,
 	BLKIO_STAT_IDLE_TIME,
 	BLKIO_STAT_EMPTY_TIME,
@@ -60,6 +54,18 @@
 #endif
 };
 
+/* Per cpu stats */
+enum stat_type_cpu {
+	BLKIO_STAT_CPU_SECTORS,
+	/* Total bytes transferred */
+	BLKIO_STAT_CPU_SERVICE_BYTES,
+	/* Total IOs serviced, post merge */
+	BLKIO_STAT_CPU_SERVICED,
+	/* Number of IOs merged */
+	BLKIO_STAT_CPU_MERGED,
+	BLKIO_STAT_CPU_NR
+};
+
 enum stat_sub_type {
 	BLKIO_STAT_READ = 0,
 	BLKIO_STAT_WRITE,
@@ -116,11 +122,11 @@
 struct blkio_group_stats {
 	/* total disk time and nr sectors dispatched by this group */
 	uint64_t time;
-	uint64_t sectors;
-	/* Time not charged to this cgroup */
-	uint64_t unaccounted_time;
 	uint64_t stat_arr[BLKIO_STAT_QUEUED + 1][BLKIO_STAT_TOTAL];
 #ifdef CONFIG_DEBUG_BLK_CGROUP
+	/* Time not charged to this cgroup */
+	uint64_t unaccounted_time;
+
 	/* Sum of number of IOs queued across all samples */
 	uint64_t avg_queue_size_sum;
 	/* Count of samples taken for average */
@@ -145,6 +151,13 @@
 #endif
 };
 
+/* Per cpu blkio group stats */
+struct blkio_group_stats_cpu {
+	uint64_t sectors;
+	uint64_t stat_arr_cpu[BLKIO_STAT_CPU_NR][BLKIO_STAT_TOTAL];
+	struct u64_stats_sync syncp;
+};
+
 struct blkio_group {
 	/* An rcu protected unique identifier for the group */
 	void *key;
@@ -160,6 +173,8 @@
 	/* Need to serialize the stats in the case of reset/update */
 	spinlock_t stats_lock;
 	struct blkio_group_stats stats;
+	/* Per cpu stats pointer */
+	struct blkio_group_stats_cpu __percpu *stats_cpu;
 };
 
 struct blkio_policy_node {
@@ -295,6 +310,7 @@
 extern void blkiocg_add_blkio_group(struct blkio_cgroup *blkcg,
 	struct blkio_group *blkg, void *key, dev_t dev,
 	enum blkio_policy_id plid);
+extern int blkio_alloc_blkg_stats(struct blkio_group *blkg);
 extern int blkiocg_del_blkio_group(struct blkio_group *blkg);
 extern struct blkio_group *blkiocg_lookup_group(struct blkio_cgroup *blkcg,
 						void *key);
@@ -322,6 +338,8 @@
 		struct blkio_group *blkg, void *key, dev_t dev,
 		enum blkio_policy_id plid) {}
 
+static inline int blkio_alloc_blkg_stats(struct blkio_group *blkg) { return 0; }
+
 static inline int
 blkiocg_del_blkio_group(struct blkio_group *blkg) { return 0; }
 
diff -druN linux-2.6.39-libre/block/blk-core.c linux-3.0-rc7-libre/block/blk-core.c
--- linux-2.6.39-libre/block/blk-core.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/block/blk-core.c	2011-07-11 19:51:52.000000000 -0400
@@ -345,6 +345,7 @@
 {
 	kobject_put(&q->kobj);
 }
+EXPORT_SYMBOL(blk_put_queue);
 
 /*
  * Note: If a driver supplied the queue lock, it should not zap that lock
@@ -566,11 +567,10 @@
 
 	return 1;
 }
+EXPORT_SYMBOL(blk_get_queue);
 
 static inline void blk_free_request(struct request_queue *q, struct request *rq)
 {
-	BUG_ON(rq->cmd_flags & REQ_ON_PLUG);
-
 	if (rq->cmd_flags & REQ_ELVPRIV)
 		elv_put_request(q, rq);
 	mempool_free(rq, q->rq.rq_pool);
@@ -1110,14 +1110,6 @@
 {
 	const int ff = bio->bi_rw & REQ_FAILFAST_MASK;
 
-	/*
-	 * Debug stuff, kill later
-	 */
-	if (!rq_mergeable(req)) {
-		blk_dump_rq_flags(req, "back");
-		return false;
-	}
-
 	if (!ll_back_merge_fn(q, req, bio))
 		return false;
 
@@ -1132,6 +1124,7 @@
 	req->ioprio = ioprio_best(req->ioprio, bio_prio(bio));
 
 	drive_stat_acct(req, 0);
+	elv_bio_merged(q, req, bio);
 	return true;
 }
 
@@ -1139,15 +1132,6 @@
 				    struct request *req, struct bio *bio)
 {
 	const int ff = bio->bi_rw & REQ_FAILFAST_MASK;
-	sector_t sector;
-
-	/*
-	 * Debug stuff, kill later
-	 */
-	if (!rq_mergeable(req)) {
-		blk_dump_rq_flags(req, "front");
-		return false;
-	}
 
 	if (!ll_front_merge_fn(q, req, bio))
 		return false;
@@ -1157,8 +1141,6 @@
 	if ((req->cmd_flags & REQ_FAILFAST_MASK) != ff)
 		blk_rq_set_mixed_merge(req);
 
-	sector = bio->bi_sector;
-
 	bio->bi_next = req->bio;
 	req->bio = bio;
 
@@ -1173,6 +1155,7 @@
 	req->ioprio = ioprio_best(req->ioprio, bio_prio(bio));
 
 	drive_stat_acct(req, 0);
+	elv_bio_merged(q, req, bio);
 	return true;
 }
 
@@ -1258,14 +1241,12 @@
 
 	el_ret = elv_merge(q, &req, bio);
 	if (el_ret == ELEVATOR_BACK_MERGE) {
-		BUG_ON(req->cmd_flags & REQ_ON_PLUG);
 		if (bio_attempt_back_merge(q, req, bio)) {
 			if (!attempt_back_merge(q, req))
 				elv_merged_request(q, req, el_ret);
 			goto out_unlock;
 		}
 	} else if (el_ret == ELEVATOR_FRONT_MERGE) {
-		BUG_ON(req->cmd_flags & REQ_ON_PLUG);
 		if (bio_attempt_front_merge(q, req, bio)) {
 			if (!attempt_front_merge(q, req))
 				elv_merged_request(q, req, el_ret);
@@ -1320,10 +1301,6 @@
 			if (__rq->q != q)
 				plug->should_sort = 1;
 		}
-		/*
-		 * Debug flag, kill later
-		 */
-		req->cmd_flags |= REQ_ON_PLUG;
 		list_add_tail(&req->queuelist, &plug->list);
 		drive_stat_acct(req, 1);
 	} else {
@@ -1550,7 +1527,8 @@
 			goto end_io;
 		}
 
-		blk_throtl_bio(q, &bio);
+		if (blk_throtl_bio(q, &bio))
+			goto end_io;
 
 		/*
 		 * If bio = NULL, bio has been throttled and will be submitted
@@ -2748,7 +2726,6 @@
 	while (!list_empty(&list)) {
 		rq = list_entry_rq(list.next);
 		list_del_init(&rq->queuelist);
-		BUG_ON(!(rq->cmd_flags & REQ_ON_PLUG));
 		BUG_ON(!rq->q);
 		if (rq->q != q) {
 			/*
@@ -2760,8 +2737,6 @@
 			depth = 0;
 			spin_lock(q->queue_lock);
 		}
-		rq->cmd_flags &= ~REQ_ON_PLUG;
-
 		/*
 		 * rq is already accounted, so use raw insert
 		 */
diff -druN linux-2.6.39-libre/block/blk-exec.c linux-3.0-rc7-libre/block/blk-exec.c
--- linux-2.6.39-libre/block/blk-exec.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/block/blk-exec.c	2011-07-11 19:51:52.000000000 -0400
@@ -56,7 +56,7 @@
 	spin_lock_irq(q->queue_lock);
 	__elv_add_request(q, rq, where);
 	__blk_run_queue(q);
-	/* the queue is stopped so it won't be plugged+unplugged */
+	/* the queue is stopped so it won't be run */
 	if (rq->cmd_type == REQ_TYPE_PM_RESUME)
 		q->request_fn(q);
 	spin_unlock_irq(q->queue_lock);
diff -druN linux-2.6.39-libre/block/blk-flush.c linux-3.0-rc7-libre/block/blk-flush.c
--- linux-2.6.39-libre/block/blk-flush.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/block/blk-flush.c	2011-07-11 19:51:52.000000000 -0400
@@ -212,13 +212,19 @@
 	}
 
 	/*
-	 * Moving a request silently to empty queue_head may stall the
-	 * queue.  Kick the queue in those cases.  This function is called
-	 * from request completion path and calling directly into
-	 * request_fn may confuse the driver.  Always use kblockd.
+	 * Kick the queue to avoid stall for two cases:
+	 * 1. Moving a request silently to empty queue_head may stall the
+	 * queue.
+	 * 2. When flush request is running in non-queueable queue, the
+	 * queue is hold. Restart the queue after flush request is finished
+	 * to avoid stall.
+	 * This function is called from request completion path and calling
+	 * directly into request_fn may confuse the driver.  Always use
+	 * kblockd.
 	 */
-	if (queued)
+	if (queued || q->flush_queue_delayed)
 		blk_run_queue_async(q);
+	q->flush_queue_delayed = 0;
 }
 
 /**
diff -druN linux-2.6.39-libre/block/blk.h linux-3.0-rc7-libre/block/blk.h
--- linux-2.6.39-libre/block/blk.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/block/blk.h	2011-07-11 19:51:52.000000000 -0400
@@ -62,7 +62,28 @@
 			return rq;
 		}
 
-		if (!q->elevator->ops->elevator_dispatch_fn(q, 0))
+		/*
+		 * Flush request is running and flush request isn't queueable
+		 * in the drive, we can hold the queue till flush request is
+		 * finished. Even we don't do this, driver can't dispatch next
+		 * requests and will requeue them. And this can improve
+		 * throughput too. For example, we have request flush1, write1,
+		 * flush 2. flush1 is dispatched, then queue is hold, write1
+		 * isn't inserted to queue. After flush1 is finished, flush2
+		 * will be dispatched. Since disk cache is already clean,
+		 * flush2 will be finished very soon, so looks like flush2 is
+		 * folded to flush1.
+		 * Since the queue is hold, a flag is set to indicate the queue
+		 * should be restarted later. Please see flush_end_io() for
+		 * details.
+		 */
+		if (q->flush_pending_idx != q->flush_running_idx &&
+				!queue_flush_queueable(q)) {
+			q->flush_queue_delayed = 1;
+			return NULL;
+		}
+		if (test_bit(QUEUE_FLAG_DEAD, &q->queue_flags) ||
+		    !q->elevator->ops->elevator_dispatch_fn(q, 0))
 			return NULL;
 	}
 }
diff -druN linux-2.6.39-libre/block/blk-ioc.c linux-3.0-rc7-libre/block/blk-ioc.c
--- linux-2.6.39-libre/block/blk-ioc.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/block/blk-ioc.c	2011-07-11 19:51:52.000000000 -0400
@@ -21,7 +21,7 @@
 	if (!hlist_empty(&ioc->cic_list)) {
 		struct cfq_io_context *cic;
 
-		cic = list_entry(ioc->cic_list.first, struct cfq_io_context,
+		cic = hlist_entry(ioc->cic_list.first, struct cfq_io_context,
 								cic_list);
 		cic->dtor(ioc);
 	}
@@ -57,7 +57,7 @@
 	if (!hlist_empty(&ioc->cic_list)) {
 		struct cfq_io_context *cic;
 
-		cic = list_entry(ioc->cic_list.first, struct cfq_io_context,
+		cic = hlist_entry(ioc->cic_list.first, struct cfq_io_context,
 								cic_list);
 		cic->exit(ioc);
 	}
@@ -96,6 +96,9 @@
 		INIT_RADIX_TREE(&ret->radix_root, GFP_ATOMIC | __GFP_HIGH);
 		INIT_HLIST_HEAD(&ret->cic_list);
 		ret->ioc_data = NULL;
+#if defined(CONFIG_BLK_CGROUP) || defined(CONFIG_BLK_CGROUP_MODULE)
+		ret->cgroup_changed = 0;
+#endif
 	}
 
 	return ret;
diff -druN linux-2.6.39-libre/block/blk-lib.c linux-3.0-rc7-libre/block/blk-lib.c
--- linux-2.6.39-libre/block/blk-lib.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/block/blk-lib.c	2011-07-11 19:51:52.000000000 -0400
@@ -9,17 +9,20 @@
 
 #include "blk.h"
 
-static void blkdev_discard_end_io(struct bio *bio, int err)
-{
-	if (err) {
-		if (err == -EOPNOTSUPP)
-			set_bit(BIO_EOPNOTSUPP, &bio->bi_flags);
-		clear_bit(BIO_UPTODATE, &bio->bi_flags);
-	}
+struct bio_batch {
+	atomic_t		done;
+	unsigned long		flags;
+	struct completion	*wait;
+};
 
-	if (bio->bi_private)
-		complete(bio->bi_private);
+static void bio_batch_end_io(struct bio *bio, int err)
+{
+	struct bio_batch *bb = bio->bi_private;
 
+	if (err && (err != -EOPNOTSUPP))
+		clear_bit(BIO_UPTODATE, &bb->flags);
+	if (atomic_dec_and_test(&bb->done))
+		complete(bb->wait);
 	bio_put(bio);
 }
 
@@ -41,6 +44,7 @@
 	struct request_queue *q = bdev_get_queue(bdev);
 	int type = REQ_WRITE | REQ_DISCARD;
 	unsigned int max_discard_sectors;
+	struct bio_batch bb;
 	struct bio *bio;
 	int ret = 0;
 
@@ -67,7 +71,11 @@
 		type |= REQ_SECURE;
 	}
 
-	while (nr_sects && !ret) {
+	atomic_set(&bb.done, 1);
+	bb.flags = 1 << BIO_UPTODATE;
+	bb.wait = &wait;
+
+	while (nr_sects) {
 		bio = bio_alloc(gfp_mask, 1);
 		if (!bio) {
 			ret = -ENOMEM;
@@ -75,9 +83,9 @@
 		}
 
 		bio->bi_sector = sector;
-		bio->bi_end_io = blkdev_discard_end_io;
+		bio->bi_end_io = bio_batch_end_io;
 		bio->bi_bdev = bdev;
-		bio->bi_private = &wait;
+		bio->bi_private = &bb;
 
 		if (nr_sects > max_discard_sectors) {
 			bio->bi_size = max_discard_sectors << 9;
@@ -88,45 +96,21 @@
 			nr_sects = 0;
 		}
 
-		bio_get(bio);
+		atomic_inc(&bb.done);
 		submit_bio(type, bio);
+	}
 
+	/* Wait for bios in-flight */
+	if (!atomic_dec_and_test(&bb.done))
 		wait_for_completion(&wait);
 
-		if (bio_flagged(bio, BIO_EOPNOTSUPP))
-			ret = -EOPNOTSUPP;
-		else if (!bio_flagged(bio, BIO_UPTODATE))
-			ret = -EIO;
-		bio_put(bio);
-	}
+	if (!test_bit(BIO_UPTODATE, &bb.flags))
+		ret = -EIO;
 
 	return ret;
 }
 EXPORT_SYMBOL(blkdev_issue_discard);
 
-struct bio_batch
-{
-	atomic_t 		done;
-	unsigned long 		flags;
-	struct completion 	*wait;
-};
-
-static void bio_batch_end_io(struct bio *bio, int err)
-{
-	struct bio_batch *bb = bio->bi_private;
-
-	if (err) {
-		if (err == -EOPNOTSUPP)
-			set_bit(BIO_EOPNOTSUPP, &bb->flags);
-		else
-			clear_bit(BIO_UPTODATE, &bb->flags);
-	}
-	if (bb)
-		if (atomic_dec_and_test(&bb->done))
-			complete(bb->wait);
-	bio_put(bio);
-}
-
 /**
  * blkdev_issue_zeroout - generate number of zero filed write bios
  * @bdev:	blockdev to issue
@@ -151,7 +135,6 @@
 	bb.flags = 1 << BIO_UPTODATE;
 	bb.wait = &wait;
 
-submit:
 	ret = 0;
 	while (nr_sects != 0) {
 		bio = bio_alloc(gfp_mask,
@@ -168,9 +151,6 @@
 
 		while (nr_sects != 0) {
 			sz = min((sector_t) PAGE_SIZE >> 9 , nr_sects);
-			if (sz == 0)
-				/* bio has maximum size possible */
-				break;
 			ret = bio_add_page(bio, ZERO_PAGE(0), sz << 9, 0);
 			nr_sects -= ret >> 9;
 			sector += ret >> 9;
@@ -190,16 +170,6 @@
 		/* One of bios in the batch was completed with error.*/
 		ret = -EIO;
 
-	if (ret)
-		goto out;
-
-	if (test_bit(BIO_EOPNOTSUPP, &bb.flags)) {
-		ret = -EOPNOTSUPP;
-		goto out;
-	}
-	if (nr_sects != 0)
-		goto submit;
-out:
 	return ret;
 }
 EXPORT_SYMBOL(blkdev_issue_zeroout);
diff -druN linux-2.6.39-libre/block/blk-settings.c linux-3.0-rc7-libre/block/blk-settings.c
--- linux-2.6.39-libre/block/blk-settings.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/block/blk-settings.c	2011-07-11 19:51:52.000000000 -0400
@@ -120,7 +120,7 @@
 	lim->discard_granularity = 0;
 	lim->discard_alignment = 0;
 	lim->discard_misaligned = 0;
-	lim->discard_zeroes_data = -1;
+	lim->discard_zeroes_data = 1;
 	lim->logical_block_size = lim->physical_block_size = lim->io_min = 512;
 	lim->bounce_pfn = (unsigned long)(BLK_BOUNCE_ANY >> PAGE_SHIFT);
 	lim->alignment_offset = 0;
@@ -166,6 +166,7 @@
 
 	blk_set_default_limits(&q->limits);
 	blk_queue_max_hw_sectors(q, BLK_SAFE_MAX_SECTORS);
+	q->limits.discard_zeroes_data = 0;
 
 	/*
 	 * by default assume old behaviour and bounce for any highmem page
@@ -790,6 +791,12 @@
 }
 EXPORT_SYMBOL_GPL(blk_queue_flush);
 
+void blk_queue_flush_queueable(struct request_queue *q, bool queueable)
+{
+	q->flush_not_queueable = !queueable;
+}
+EXPORT_SYMBOL_GPL(blk_queue_flush_queueable);
+
 static int __init blk_settings_init(void)
 {
 	blk_max_low_pfn = max_low_pfn - 1;
diff -druN linux-2.6.39-libre/block/blk-sysfs.c linux-3.0-rc7-libre/block/blk-sysfs.c
--- linux-2.6.39-libre/block/blk-sysfs.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/block/blk-sysfs.c	2011-07-11 19:51:52.000000000 -0400
@@ -152,7 +152,8 @@
 
 static ssize_t queue_discard_max_show(struct request_queue *q, char *page)
 {
-	return queue_var_show(q->limits.max_discard_sectors << 9, page);
+	return sprintf(page, "%llu\n",
+		       (unsigned long long)q->limits.max_discard_sectors << 9);
 }
 
 static ssize_t queue_discard_zeroes_data_show(struct request_queue *q, char *page)
diff -druN linux-2.6.39-libre/block/blk-throttle.c linux-3.0-rc7-libre/block/blk-throttle.c
--- linux-2.6.39-libre/block/blk-throttle.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/block/blk-throttle.c	2011-07-11 19:51:52.000000000 -0400
@@ -78,6 +78,8 @@
 
 	/* Some throttle limits got updated for the group */
 	int limits_changed;
+
+	struct rcu_head rcu_head;
 };
 
 struct throtl_data
@@ -88,7 +90,7 @@
 	/* service tree for active throtl groups */
 	struct throtl_rb_root tg_service_tree;
 
-	struct throtl_grp root_tg;
+	struct throtl_grp *root_tg;
 	struct request_queue *queue;
 
 	/* Total Number of queued bios on READ and WRITE lists */
@@ -151,56 +153,44 @@
 	return tg;
 }
 
-static void throtl_put_tg(struct throtl_grp *tg)
+static void throtl_free_tg(struct rcu_head *head)
 {
-	BUG_ON(atomic_read(&tg->ref) <= 0);
-	if (!atomic_dec_and_test(&tg->ref))
-		return;
+	struct throtl_grp *tg;
+
+	tg = container_of(head, struct throtl_grp, rcu_head);
+	free_percpu(tg->blkg.stats_cpu);
 	kfree(tg);
 }
 
-static struct throtl_grp * throtl_find_alloc_tg(struct throtl_data *td,
-			struct blkio_cgroup *blkcg)
+static void throtl_put_tg(struct throtl_grp *tg)
 {
-	struct throtl_grp *tg = NULL;
-	void *key = td;
-	struct backing_dev_info *bdi = &td->queue->backing_dev_info;
-	unsigned int major, minor;
+	BUG_ON(atomic_read(&tg->ref) <= 0);
+	if (!atomic_dec_and_test(&tg->ref))
+		return;
 
 	/*
-	 * TODO: Speed up blkiocg_lookup_group() by maintaining a radix
-	 * tree of blkg (instead of traversing through hash list all
-	 * the time.
+	 * A group is freed in rcu manner. But having an rcu lock does not
+	 * mean that one can access all the fields of blkg and assume these
+	 * are valid. For example, don't try to follow throtl_data and
+	 * request queue links.
+	 *
+	 * Having a reference to blkg under an rcu allows acess to only
+	 * values local to groups like group stats and group rate limits
 	 */
+	call_rcu(&tg->rcu_head, throtl_free_tg);
+}
 
-	/*
-	 * This is the common case when there are no blkio cgroups.
- 	 * Avoid lookup in this case
- 	 */
-	if (blkcg == &blkio_root_cgroup)
-		tg = &td->root_tg;
-	else
-		tg = tg_of_blkg(blkiocg_lookup_group(blkcg, key));
-
-	/* Fill in device details for root group */
-	if (tg && !tg->blkg.dev && bdi->dev && dev_name(bdi->dev)) {
-		sscanf(dev_name(bdi->dev), "%u:%u", &major, &minor);
-		tg->blkg.dev = MKDEV(major, minor);
-		goto done;
-	}
-
-	if (tg)
-		goto done;
-
-	tg = kzalloc_node(sizeof(*tg), GFP_ATOMIC, td->queue->node);
-	if (!tg)
-		goto done;
-
+static void throtl_init_group(struct throtl_grp *tg)
+{
 	INIT_HLIST_NODE(&tg->tg_node);
 	RB_CLEAR_NODE(&tg->rb_node);
 	bio_list_init(&tg->bio_lists[0]);
 	bio_list_init(&tg->bio_lists[1]);
-	td->limits_changed = false;
+	tg->limits_changed = false;
+
+	/* Practically unlimited BW */
+	tg->bps[0] = tg->bps[1] = -1;
+	tg->iops[0] = tg->iops[1] = -1;
 
 	/*
 	 * Take the initial reference that will be released on destroy
@@ -209,33 +199,181 @@
 	 * exit or cgroup deletion path depending on who is exiting first.
 	 */
 	atomic_set(&tg->ref, 1);
+}
+
+/* Should be called with rcu read lock held (needed for blkcg) */
+static void
+throtl_add_group_to_td_list(struct throtl_data *td, struct throtl_grp *tg)
+{
+	hlist_add_head(&tg->tg_node, &td->tg_list);
+	td->nr_undestroyed_grps++;
+}
+
+static void
+__throtl_tg_fill_dev_details(struct throtl_data *td, struct throtl_grp *tg)
+{
+	struct backing_dev_info *bdi = &td->queue->backing_dev_info;
+	unsigned int major, minor;
+
+	if (!tg || tg->blkg.dev)
+		return;
+
+	/*
+	 * Fill in device details for a group which might not have been
+	 * filled at group creation time as queue was being instantiated
+	 * and driver had not attached a device yet
+	 */
+	if (bdi->dev && dev_name(bdi->dev)) {
+		sscanf(dev_name(bdi->dev), "%u:%u", &major, &minor);
+		tg->blkg.dev = MKDEV(major, minor);
+	}
+}
+
+/*
+ * Should be called with without queue lock held. Here queue lock will be
+ * taken rarely. It will be taken only once during life time of a group
+ * if need be
+ */
+static void
+throtl_tg_fill_dev_details(struct throtl_data *td, struct throtl_grp *tg)
+{
+	if (!tg || tg->blkg.dev)
+		return;
+
+	spin_lock_irq(td->queue->queue_lock);
+	__throtl_tg_fill_dev_details(td, tg);
+	spin_unlock_irq(td->queue->queue_lock);
+}
+
+static void throtl_init_add_tg_lists(struct throtl_data *td,
+			struct throtl_grp *tg, struct blkio_cgroup *blkcg)
+{
+	__throtl_tg_fill_dev_details(td, tg);
 
 	/* Add group onto cgroup list */
-	sscanf(dev_name(bdi->dev), "%u:%u", &major, &minor);
 	blkiocg_add_blkio_group(blkcg, &tg->blkg, (void *)td,
-				MKDEV(major, minor), BLKIO_POLICY_THROTL);
+				tg->blkg.dev, BLKIO_POLICY_THROTL);
 
 	tg->bps[READ] = blkcg_get_read_bps(blkcg, tg->blkg.dev);
 	tg->bps[WRITE] = blkcg_get_write_bps(blkcg, tg->blkg.dev);
 	tg->iops[READ] = blkcg_get_read_iops(blkcg, tg->blkg.dev);
 	tg->iops[WRITE] = blkcg_get_write_iops(blkcg, tg->blkg.dev);
 
-	hlist_add_head(&tg->tg_node, &td->tg_list);
-	td->nr_undestroyed_grps++;
-done:
+	throtl_add_group_to_td_list(td, tg);
+}
+
+/* Should be called without queue lock and outside of rcu period */
+static struct throtl_grp *throtl_alloc_tg(struct throtl_data *td)
+{
+	struct throtl_grp *tg = NULL;
+	int ret;
+
+	tg = kzalloc_node(sizeof(*tg), GFP_ATOMIC, td->queue->node);
+	if (!tg)
+		return NULL;
+
+	ret = blkio_alloc_blkg_stats(&tg->blkg);
+
+	if (ret) {
+		kfree(tg);
+		return NULL;
+	}
+
+	throtl_init_group(tg);
 	return tg;
 }
 
-static struct throtl_grp * throtl_get_tg(struct throtl_data *td)
+static struct
+throtl_grp *throtl_find_tg(struct throtl_data *td, struct blkio_cgroup *blkcg)
 {
 	struct throtl_grp *tg = NULL;
+	void *key = td;
+
+	/*
+	 * This is the common case when there are no blkio cgroups.
+ 	 * Avoid lookup in this case
+ 	 */
+	if (blkcg == &blkio_root_cgroup)
+		tg = td->root_tg;
+	else
+		tg = tg_of_blkg(blkiocg_lookup_group(blkcg, key));
+
+	__throtl_tg_fill_dev_details(td, tg);
+	return tg;
+}
+
+/*
+ * This function returns with queue lock unlocked in case of error, like
+ * request queue is no more
+ */
+static struct throtl_grp * throtl_get_tg(struct throtl_data *td)
+{
+	struct throtl_grp *tg = NULL, *__tg = NULL;
 	struct blkio_cgroup *blkcg;
+	struct request_queue *q = td->queue;
 
 	rcu_read_lock();
 	blkcg = task_blkio_cgroup(current);
-	tg = throtl_find_alloc_tg(td, blkcg);
-	if (!tg)
-		tg = &td->root_tg;
+	tg = throtl_find_tg(td, blkcg);
+	if (tg) {
+		rcu_read_unlock();
+		return tg;
+	}
+
+	/*
+	 * Need to allocate a group. Allocation of group also needs allocation
+	 * of per cpu stats which in-turn takes a mutex() and can block. Hence
+	 * we need to drop rcu lock and queue_lock before we call alloc
+	 *
+	 * Take the request queue reference to make sure queue does not
+	 * go away once we return from allocation.
+	 */
+	blk_get_queue(q);
+	rcu_read_unlock();
+	spin_unlock_irq(q->queue_lock);
+
+	tg = throtl_alloc_tg(td);
+	/*
+	 * We might have slept in group allocation. Make sure queue is not
+	 * dead
+	 */
+	if (unlikely(test_bit(QUEUE_FLAG_DEAD, &q->queue_flags))) {
+		blk_put_queue(q);
+		if (tg)
+			kfree(tg);
+
+		return ERR_PTR(-ENODEV);
+	}
+	blk_put_queue(q);
+
+	/* Group allocated and queue is still alive. take the lock */
+	spin_lock_irq(q->queue_lock);
+
+	/*
+	 * Initialize the new group. After sleeping, read the blkcg again.
+	 */
+	rcu_read_lock();
+	blkcg = task_blkio_cgroup(current);
+
+	/*
+	 * If some other thread already allocated the group while we were
+	 * not holding queue lock, free up the group
+	 */
+	__tg = throtl_find_tg(td, blkcg);
+
+	if (__tg) {
+		kfree(tg);
+		rcu_read_unlock();
+		return __tg;
+	}
+
+	/* Group allocation failed. Account the IO to root group */
+	if (!tg) {
+		tg = td->root_tg;
+		return tg;
+	}
+
+	throtl_init_add_tg_lists(td, tg, blkcg);
 	rcu_read_unlock();
 	return tg;
 }
@@ -544,6 +682,12 @@
 	return 0;
 }
 
+static bool tg_no_rule_group(struct throtl_grp *tg, bool rw) {
+	if (tg->bps[rw] == -1 && tg->iops[rw] == -1)
+		return 1;
+	return 0;
+}
+
 /*
  * Returns whether one can dispatch a bio or not. Also returns approx number
  * of jiffies to wait before this bio is with-in IO rate and can be dispatched
@@ -608,10 +752,6 @@
 	tg->bytes_disp[rw] += bio->bi_size;
 	tg->io_disp[rw]++;
 
-	/*
-	 * TODO: This will take blkg->stats_lock. Figure out a way
-	 * to avoid this cost.
-	 */
 	blkiocg_update_dispatch_stats(&tg->blkg, bio->bi_size, rw, sync);
 }
 
@@ -787,7 +927,7 @@
 
 	bio_list_init(&bio_list_on_stack);
 
-	throtl_log(td, "dispatch nr_queued=%lu read=%u write=%u",
+	throtl_log(td, "dispatch nr_queued=%d read=%u write=%u",
 			total_nr_queued(td), td->nr_queued[READ],
 			td->nr_queued[WRITE]);
 
@@ -989,15 +1129,51 @@
 	struct throtl_grp *tg;
 	struct bio *bio = *biop;
 	bool rw = bio_data_dir(bio), update_disptime = true;
+	struct blkio_cgroup *blkcg;
 
 	if (bio->bi_rw & REQ_THROTTLED) {
 		bio->bi_rw &= ~REQ_THROTTLED;
 		return 0;
 	}
 
+	/*
+	 * A throtl_grp pointer retrieved under rcu can be used to access
+	 * basic fields like stats and io rates. If a group has no rules,
+	 * just update the dispatch stats in lockless manner and return.
+	 */
+
+	rcu_read_lock();
+	blkcg = task_blkio_cgroup(current);
+	tg = throtl_find_tg(td, blkcg);
+	if (tg) {
+		throtl_tg_fill_dev_details(td, tg);
+
+		if (tg_no_rule_group(tg, rw)) {
+			blkiocg_update_dispatch_stats(&tg->blkg, bio->bi_size,
+					rw, bio->bi_rw & REQ_SYNC);
+			rcu_read_unlock();
+			return 0;
+		}
+	}
+	rcu_read_unlock();
+
+	/*
+	 * Either group has not been allocated yet or it is not an unlimited
+	 * IO group
+	 */
+
 	spin_lock_irq(q->queue_lock);
 	tg = throtl_get_tg(td);
 
+	if (IS_ERR(tg)) {
+		if (PTR_ERR(tg)	== -ENODEV) {
+			/*
+			 * Queue is gone. No queue lock held here.
+			 */
+			return -ENODEV;
+		}
+	}
+
 	if (tg->nr_queued[rw]) {
 		/*
 		 * There is already another bio queued in same dir. No
@@ -1028,7 +1204,7 @@
 	}
 
 queue_bio:
-	throtl_log_tg(td, tg, "[%c] bio. bdisp=%u sz=%u bps=%llu"
+	throtl_log_tg(td, tg, "[%c] bio. bdisp=%llu sz=%u bps=%llu"
 			" iodisp=%u iops=%u queued=%d/%d",
 			rw == READ ? 'R' : 'W',
 			tg->bytes_disp[rw], bio->bi_size, tg->bps[rw],
@@ -1060,39 +1236,24 @@
 	INIT_HLIST_HEAD(&td->tg_list);
 	td->tg_service_tree = THROTL_RB_ROOT;
 	td->limits_changed = false;
+	INIT_DELAYED_WORK(&td->throtl_work, blk_throtl_work);
 
-	/* Init root group */
-	tg = &td->root_tg;
-	INIT_HLIST_NODE(&tg->tg_node);
-	RB_CLEAR_NODE(&tg->rb_node);
-	bio_list_init(&tg->bio_lists[0]);
-	bio_list_init(&tg->bio_lists[1]);
-
-	/* Practically unlimited BW */
-	tg->bps[0] = tg->bps[1] = -1;
-	tg->iops[0] = tg->iops[1] = -1;
-	td->limits_changed = false;
+	/* alloc and Init root group. */
+	td->queue = q;
+	tg = throtl_alloc_tg(td);
 
-	/*
-	 * Set root group reference to 2. One reference will be dropped when
-	 * all groups on tg_list are being deleted during queue exit. Other
-	 * reference will remain there as we don't want to delete this group
-	 * as it is statically allocated and gets destroyed when throtl_data
-	 * goes away.
-	 */
-	atomic_set(&tg->ref, 2);
-	hlist_add_head(&tg->tg_node, &td->tg_list);
-	td->nr_undestroyed_grps++;
+	if (!tg) {
+		kfree(td);
+		return -ENOMEM;
+	}
 
-	INIT_DELAYED_WORK(&td->throtl_work, blk_throtl_work);
+	td->root_tg = tg;
 
 	rcu_read_lock();
-	blkiocg_add_blkio_group(&blkio_root_cgroup, &tg->blkg, (void *)td,
-					0, BLKIO_POLICY_THROTL);
+	throtl_init_add_tg_lists(td, tg, &blkio_root_cgroup);
 	rcu_read_unlock();
 
 	/* Attach throtl data to request queue */
-	td->queue = q;
 	q->td = td;
 	return 0;
 }
diff -druN linux-2.6.39-libre/block/cfq-iosched.c linux-3.0-rc7-libre/block/cfq-iosched.c
--- linux-2.6.39-libre/block/cfq-iosched.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/block/cfq-iosched.c	2011-07-11 19:51:52.000000000 -0400
@@ -185,7 +185,7 @@
 	int nr_cfqq;
 
 	/*
-	 * Per group busy queus average. Useful for workload slice calc. We
+	 * Per group busy queues average. Useful for workload slice calc. We
 	 * create the array for each prio class but at run time it is used
 	 * only for RT and BE class and slot for IDLE class remains unused.
 	 * This is primarily done to avoid confusion and a gcc warning.
@@ -300,7 +300,9 @@
 
 	/* List of cfq groups being managed on this device*/
 	struct hlist_head cfqg_list;
-	struct rcu_head rcu;
+
+	/* Number of groups which are on blkcg->blkg_list */
+	unsigned int nr_blkcg_linked_grps;
 };
 
 static struct cfq_group *cfq_get_next_cfqg(struct cfq_data *cfqd);
@@ -367,16 +369,16 @@
 #define cfq_log_cfqq(cfqd, cfqq, fmt, args...)	\
 	blk_add_trace_msg((cfqd)->queue, "cfq%d%c %s " fmt, (cfqq)->pid, \
 			cfq_cfqq_sync((cfqq)) ? 'S' : 'A', \
-			blkg_path(&(cfqq)->cfqg->blkg), ##args);
+			blkg_path(&(cfqq)->cfqg->blkg), ##args)
 
 #define cfq_log_cfqg(cfqd, cfqg, fmt, args...)				\
 	blk_add_trace_msg((cfqd)->queue, "%s " fmt,			\
-				blkg_path(&(cfqg)->blkg), ##args);      \
+				blkg_path(&(cfqg)->blkg), ##args)       \
 
 #else
 #define cfq_log_cfqq(cfqd, cfqq, fmt, args...)	\
 	blk_add_trace_msg((cfqd)->queue, "cfq%d " fmt, (cfqq)->pid, ##args)
-#define cfq_log_cfqg(cfqd, cfqg, fmt, args...)		do {} while (0);
+#define cfq_log_cfqg(cfqd, cfqg, fmt, args...)		do {} while (0)
 #endif
 #define cfq_log(cfqd, fmt, args...)	\
 	blk_add_trace_msg((cfqd)->queue, "cfq " fmt, ##args)
@@ -665,15 +667,11 @@
 	if (rq2 == NULL)
 		return rq1;
 
-	if (rq_is_sync(rq1) && !rq_is_sync(rq2))
-		return rq1;
-	else if (rq_is_sync(rq2) && !rq_is_sync(rq1))
-		return rq2;
-	if ((rq1->cmd_flags & REQ_META) && !(rq2->cmd_flags & REQ_META))
-		return rq1;
-	else if ((rq2->cmd_flags & REQ_META) &&
-		 !(rq1->cmd_flags & REQ_META))
-		return rq2;
+	if (rq_is_sync(rq1) != rq_is_sync(rq2))
+		return rq_is_sync(rq1) ? rq1 : rq2;
+
+	if ((rq1->cmd_flags ^ rq2->cmd_flags) & REQ_META)
+		return rq1->cmd_flags & REQ_META ? rq1 : rq2;
 
 	s1 = blk_rq_pos(rq1);
 	s2 = blk_rq_pos(rq2);
@@ -990,9 +988,10 @@
 
 	cfq_log_cfqg(cfqd, cfqg, "served: vt=%llu min_vt=%llu", cfqg->vdisktime,
 					st->min_vdisktime);
-	cfq_log_cfqq(cfqq->cfqd, cfqq, "sl_used=%u disp=%u charge=%u iops=%u"
-			" sect=%u", used_sl, cfqq->slice_dispatch, charge,
-			iops_mode(cfqd), cfqq->nr_sectors);
+	cfq_log_cfqq(cfqq->cfqd, cfqq,
+		     "sl_used=%u disp=%u charge=%u iops=%u sect=%lu",
+		     used_sl, cfqq->slice_dispatch, charge,
+		     iops_mode(cfqd), cfqq->nr_sectors);
 	cfq_blkiocg_update_timeslice_used(&cfqg->blkg, used_sl,
 					  unaccounted_sl);
 	cfq_blkiocg_set_start_empty_time(&cfqg->blkg);
@@ -1014,28 +1013,47 @@
 	cfqg->needs_update = true;
 }
 
-static struct cfq_group * cfq_find_alloc_cfqg(struct cfq_data *cfqd,
-		struct blkio_cgroup *blkcg, int create)
+static void cfq_init_add_cfqg_lists(struct cfq_data *cfqd,
+			struct cfq_group *cfqg, struct blkio_cgroup *blkcg)
 {
-	struct cfq_group *cfqg = NULL;
-	void *key = cfqd;
-	int i, j;
-	struct cfq_rb_root *st;
 	struct backing_dev_info *bdi = &cfqd->queue->backing_dev_info;
 	unsigned int major, minor;
 
-	cfqg = cfqg_of_blkg(blkiocg_lookup_group(blkcg, key));
-	if (cfqg && !cfqg->blkg.dev && bdi->dev && dev_name(bdi->dev)) {
+	/*
+	 * Add group onto cgroup list. It might happen that bdi->dev is
+	 * not initialized yet. Initialize this new group without major
+	 * and minor info and this info will be filled in once a new thread
+	 * comes for IO.
+	 */
+	if (bdi->dev) {
 		sscanf(dev_name(bdi->dev), "%u:%u", &major, &minor);
-		cfqg->blkg.dev = MKDEV(major, minor);
-		goto done;
-	}
-	if (cfqg || !create)
-		goto done;
+		cfq_blkiocg_add_blkio_group(blkcg, &cfqg->blkg,
+					(void *)cfqd, MKDEV(major, minor));
+	} else
+		cfq_blkiocg_add_blkio_group(blkcg, &cfqg->blkg,
+					(void *)cfqd, 0);
+
+	cfqd->nr_blkcg_linked_grps++;
+	cfqg->weight = blkcg_get_weight(blkcg, cfqg->blkg.dev);
+
+	/* Add group on cfqd list */
+	hlist_add_head(&cfqg->cfqd_node, &cfqd->cfqg_list);
+}
+
+/*
+ * Should be called from sleepable context. No request queue lock as per
+ * cpu stats are allocated dynamically and alloc_percpu needs to be called
+ * from sleepable context.
+ */
+static struct cfq_group * cfq_alloc_cfqg(struct cfq_data *cfqd)
+{
+	struct cfq_group *cfqg = NULL;
+	int i, j, ret;
+	struct cfq_rb_root *st;
 
 	cfqg = kzalloc_node(sizeof(*cfqg), GFP_ATOMIC, cfqd->queue->node);
 	if (!cfqg)
-		goto done;
+		return NULL;
 
 	for_each_cfqg_st(cfqg, i, j, st)
 		*st = CFQ_RB_ROOT;
@@ -1049,43 +1067,94 @@
 	 */
 	cfqg->ref = 1;
 
+	ret = blkio_alloc_blkg_stats(&cfqg->blkg);
+	if (ret) {
+		kfree(cfqg);
+		return NULL;
+	}
+
+	return cfqg;
+}
+
+static struct cfq_group *
+cfq_find_cfqg(struct cfq_data *cfqd, struct blkio_cgroup *blkcg)
+{
+	struct cfq_group *cfqg = NULL;
+	void *key = cfqd;
+	struct backing_dev_info *bdi = &cfqd->queue->backing_dev_info;
+	unsigned int major, minor;
+
 	/*
-	 * Add group onto cgroup list. It might happen that bdi->dev is
-	 * not initialized yet. Initialize this new group without major
-	 * and minor info and this info will be filled in once a new thread
-	 * comes for IO. See code above.
+	 * This is the common case when there are no blkio cgroups.
+	 * Avoid lookup in this case
 	 */
-	if (bdi->dev) {
-		sscanf(dev_name(bdi->dev), "%u:%u", &major, &minor);
-		cfq_blkiocg_add_blkio_group(blkcg, &cfqg->blkg, (void *)cfqd,
-					MKDEV(major, minor));
-	} else
-		cfq_blkiocg_add_blkio_group(blkcg, &cfqg->blkg, (void *)cfqd,
-					0);
-
-	cfqg->weight = blkcg_get_weight(blkcg, cfqg->blkg.dev);
+	if (blkcg == &blkio_root_cgroup)
+		cfqg = &cfqd->root_group;
+	else
+		cfqg = cfqg_of_blkg(blkiocg_lookup_group(blkcg, key));
 
-	/* Add group on cfqd list */
-	hlist_add_head(&cfqg->cfqd_node, &cfqd->cfqg_list);
+	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);
+	}
 
-done:
 	return cfqg;
 }
 
 /*
- * Search for the cfq group current task belongs to. If create = 1, then also
- * create the cfq group if it does not exist. request_queue lock must be held.
+ * Search for the cfq group current task belongs to. request_queue lock must
+ * be held.
  */
-static struct cfq_group *cfq_get_cfqg(struct cfq_data *cfqd, int create)
+static struct cfq_group *cfq_get_cfqg(struct cfq_data *cfqd)
 {
 	struct blkio_cgroup *blkcg;
-	struct cfq_group *cfqg = NULL;
+	struct cfq_group *cfqg = NULL, *__cfqg = NULL;
+	struct request_queue *q = cfqd->queue;
 
 	rcu_read_lock();
 	blkcg = task_blkio_cgroup(current);
-	cfqg = cfq_find_alloc_cfqg(cfqd, blkcg, create);
-	if (!cfqg && create)
+	cfqg = cfq_find_cfqg(cfqd, blkcg);
+	if (cfqg) {
+		rcu_read_unlock();
+		return cfqg;
+	}
+
+	/*
+	 * Need to allocate a group. Allocation of group also needs allocation
+	 * of per cpu stats which in-turn takes a mutex() and can block. Hence
+	 * we need to drop rcu lock and queue_lock before we call alloc.
+	 *
+	 * Not taking any queue reference here and assuming that queue is
+	 * around by the time we return. CFQ queue allocation code does
+	 * the same. It might be racy though.
+	 */
+
+	rcu_read_unlock();
+	spin_unlock_irq(q->queue_lock);
+
+	cfqg = cfq_alloc_cfqg(cfqd);
+
+	spin_lock_irq(q->queue_lock);
+
+	rcu_read_lock();
+	blkcg = task_blkio_cgroup(current);
+
+	/*
+	 * If some other thread already allocated the group while we were
+	 * not holding queue lock, free up the group
+	 */
+	__cfqg = cfq_find_cfqg(cfqd, blkcg);
+
+	if (__cfqg) {
+		kfree(cfqg);
+		rcu_read_unlock();
+		return __cfqg;
+	}
+
+	if (!cfqg)
 		cfqg = &cfqd->root_group;
+
+	cfq_init_add_cfqg_lists(cfqd, cfqg, blkcg);
 	rcu_read_unlock();
 	return cfqg;
 }
@@ -1118,6 +1187,7 @@
 		return;
 	for_each_cfqg_st(cfqg, i, j, st)
 		BUG_ON(!RB_EMPTY_ROOT(&st->rb));
+	free_percpu(cfqg->blkg.stats_cpu);
 	kfree(cfqg);
 }
 
@@ -1176,7 +1246,7 @@
 }
 
 #else /* GROUP_IOSCHED */
-static struct cfq_group *cfq_get_cfqg(struct cfq_data *cfqd, int create)
+static struct cfq_group *cfq_get_cfqg(struct cfq_data *cfqd)
 {
 	return &cfqd->root_group;
 }
@@ -1210,7 +1280,6 @@
 	struct cfq_rb_root *service_tree;
 	int left;
 	int new_cfqq = 1;
-	int group_changed = 0;
 
 	service_tree = service_tree_for(cfqq->cfqg, cfqq_prio(cfqq),
 						cfqq_type(cfqq));
@@ -1281,7 +1350,7 @@
 	rb_link_node(&cfqq->rb_node, parent, p);
 	rb_insert_color(&cfqq->rb_node, &service_tree->rb);
 	service_tree->count++;
-	if ((add_front || !new_cfqq) && !group_changed)
+	if (add_front || !new_cfqq)
 		return;
 	cfq_group_notify_queue_add(cfqd, cfqq->cfqg);
 }
@@ -1955,8 +2024,8 @@
 	 */
 	if (sample_valid(cic->ttime_samples) &&
 	    (cfqq->slice_end - jiffies < cic->ttime_mean)) {
-		cfq_log_cfqq(cfqd, cfqq, "Not idling. think_time:%d",
-				cic->ttime_mean);
+		cfq_log_cfqq(cfqd, cfqq, "Not idling. think_time:%lu",
+			     cic->ttime_mean);
 		return;
 	}
 
@@ -2029,7 +2098,7 @@
 
 	WARN_ON(cfqq->ioprio >= IOPRIO_BE_NR);
 
-	return 2 * (base_rq + base_rq * (CFQ_PRIO_LISTS - 1 - cfqq->ioprio));
+	return 2 * base_rq * (IOPRIO_BE_NR - cfqq->ioprio);
 }
 
 /*
@@ -2704,8 +2773,14 @@
 	smp_wmb();
 	cic->key = cfqd_dead_key(cfqd);
 
-	if (ioc->ioc_data == cic)
+	rcu_read_lock();
+	if (rcu_dereference(ioc->ioc_data) == cic) {
+		rcu_read_unlock();
+		spin_lock(&ioc->lock);
 		rcu_assign_pointer(ioc->ioc_data, NULL);
+		spin_unlock(&ioc->lock);
+	} else
+		rcu_read_unlock();
 
 	if (cic->cfqq[BLK_RW_ASYNC]) {
 		cfq_exit_cfqq(cfqd, cic->cfqq[BLK_RW_ASYNC]);
@@ -2911,7 +2986,7 @@
 	struct cfq_group *cfqg;
 
 retry:
-	cfqg = cfq_get_cfqg(cfqd, 1);
+	cfqg = cfq_get_cfqg(cfqd);
 	cic = cfq_cic_lookup(cfqd, ioc);
 	/* cic always exists here */
 	cfqq = cic_to_cfqq(cic, is_sync);
@@ -3012,7 +3087,8 @@
 
 	spin_lock_irqsave(&ioc->lock, flags);
 
-	BUG_ON(ioc->ioc_data == cic);
+	BUG_ON(rcu_dereference_check(ioc->ioc_data,
+		lockdep_is_held(&ioc->lock)) == cic);
 
 	radix_tree_delete(&ioc->radix_root, cfqd->cic_index);
 	hlist_del_rcu(&cic->cic_list);
@@ -3718,9 +3794,6 @@
 	return 0;
 
 queue_fail:
-	if (cic)
-		put_io_context(cic->ioc);
-
 	cfq_schedule_dispatch(cfqd);
 	spin_unlock_irqrestore(q->queue_lock, flags);
 	cfq_log(cfqd, "set_request fail");
@@ -3815,15 +3888,11 @@
 		cfq_put_queue(cfqd->async_idle_cfqq);
 }
 
-static void cfq_cfqd_free(struct rcu_head *head)
-{
-	kfree(container_of(head, struct cfq_data, rcu));
-}
-
 static void cfq_exit_queue(struct elevator_queue *e)
 {
 	struct cfq_data *cfqd = e->elevator_data;
 	struct request_queue *q = cfqd->queue;
+	bool wait = false;
 
 	cfq_shutdown_timer_wq(cfqd);
 
@@ -3842,7 +3911,13 @@
 
 	cfq_put_async_queues(cfqd);
 	cfq_release_cfq_groups(cfqd);
-	cfq_blkiocg_del_blkio_group(&cfqd->root_group.blkg);
+
+	/*
+	 * If there are groups which we could not unlink from blkcg list,
+	 * wait for a rcu period for them to be freed.
+	 */
+	if (cfqd->nr_blkcg_linked_grps)
+		wait = true;
 
 	spin_unlock_irq(q->queue_lock);
 
@@ -3852,8 +3927,25 @@
 	ida_remove(&cic_index_ida, cfqd->cic_index);
 	spin_unlock(&cic_index_lock);
 
-	/* Wait for cfqg->blkg->key accessors to exit their grace periods. */
-	call_rcu(&cfqd->rcu, cfq_cfqd_free);
+	/*
+	 * Wait for cfqg->blkg->key accessors to exit their grace periods.
+	 * Do this wait only if there are other unlinked groups out
+	 * there. This can happen if cgroup deletion path claimed the
+	 * responsibility of cleaning up a group before queue cleanup code
+	 * get to the group.
+	 *
+	 * Do not call synchronize_rcu() unconditionally as there are drivers
+	 * which create/delete request queue hundreds of times during scan/boot
+	 * and synchronize_rcu() can take significant time and slow down boot.
+	 */
+	if (wait)
+		synchronize_rcu();
+
+#ifdef CONFIG_CFQ_GROUP_IOSCHED
+	/* Free up per cpu stats for root group */
+	free_percpu(cfqd->root_group.blkg.stats_cpu);
+#endif
+	kfree(cfqd);
 }
 
 static int cfq_alloc_cic_index(void)
@@ -3886,8 +3978,12 @@
 		return NULL;
 
 	cfqd = kmalloc_node(sizeof(*cfqd), GFP_KERNEL | __GFP_ZERO, q->node);
-	if (!cfqd)
+	if (!cfqd) {
+		spin_lock(&cic_index_lock);
+		ida_remove(&cic_index_ida, i);
+		spin_unlock(&cic_index_lock);
 		return NULL;
+	}
 
 	/*
 	 * Don't need take queue_lock in the routine, since we are
@@ -3909,14 +4005,29 @@
 
 #ifdef CONFIG_CFQ_GROUP_IOSCHED
 	/*
-	 * Take a reference to root group which we never drop. This is just
-	 * to make sure that cfq_put_cfqg() does not try to kfree root group
+	 * Set root group reference to 2. One reference will be dropped when
+	 * all groups on cfqd->cfqg_list are being deleted during queue exit.
+	 * Other reference will remain there as we don't want to delete this
+	 * group as it is statically allocated and gets destroyed when
+	 * throtl_data goes away.
 	 */
-	cfqg->ref = 1;
+	cfqg->ref = 2;
+
+	if (blkio_alloc_blkg_stats(&cfqg->blkg)) {
+		kfree(cfqg);
+		kfree(cfqd);
+		return NULL;
+	}
+
 	rcu_read_lock();
+
 	cfq_blkiocg_add_blkio_group(&blkio_root_cgroup, &cfqg->blkg,
 					(void *)cfqd, 0);
 	rcu_read_unlock();
+	cfqd->nr_blkcg_linked_grps++;
+
+	/* Add group on cfqd->cfqg_list */
+	hlist_add_head(&cfqg->cfqd_node, &cfqd->cfqg_list);
 #endif
 	/*
 	 * Not strictly needed (since RB_ROOT just clears the node and we
diff -druN linux-2.6.39-libre/block/elevator.c linux-3.0-rc7-libre/block/elevator.c
--- linux-2.6.39-libre/block/elevator.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/block/elevator.c	2011-07-11 19:51:52.000000000 -0400
@@ -155,13 +155,8 @@
 
 	e = elevator_find(name);
 	if (!e) {
-		char elv[ELV_NAME_MAX + strlen("-iosched")];
-
 		spin_unlock(&elv_list_lock);
-
-		snprintf(elv, sizeof(elv), "%s-iosched", name);
-
-		request_module("%s", elv);
+		request_module("%s-iosched", name);
 		spin_lock(&elv_list_lock);
 		e = elevator_find(name);
 	}
@@ -421,8 +416,6 @@
 	struct list_head *entry;
 	int stop_flags;
 
-	BUG_ON(rq->cmd_flags & REQ_ON_PLUG);
-
 	if (q->last_merge == rq)
 		q->last_merge = NULL;
 
@@ -661,8 +654,6 @@
 
 	rq->q = q;
 
-	BUG_ON(rq->cmd_flags & REQ_ON_PLUG);
-
 	if (rq->cmd_flags & REQ_SOFTBARRIER) {
 		/* barriers are scheduling boundary, update end_sector */
 		if (rq->cmd_type == REQ_TYPE_FS ||
diff -druN linux-2.6.39-libre/block/genhd.c linux-3.0-rc7-libre/block/genhd.c
--- linux-2.6.39-libre/block/genhd.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/block/genhd.c	2011-07-11 19:51:52.000000000 -0400
@@ -1371,6 +1371,7 @@
 	struct gendisk		*disk;		/* the associated disk */
 	spinlock_t		lock;
 
+	struct mutex		block_mutex;	/* protects blocking */
 	int			block;		/* event blocking depth */
 	unsigned int		pending;	/* events already sent out */
 	unsigned int		clearing;	/* events being cleared */
@@ -1414,22 +1415,44 @@
 	return msecs_to_jiffies(intv_msecs);
 }
 
-static void __disk_block_events(struct gendisk *disk, bool sync)
+/**
+ * disk_block_events - block and flush disk event checking
+ * @disk: disk to block events for
+ *
+ * On return from this function, it is guaranteed that event checking
+ * isn't in progress and won't happen until unblocked by
+ * disk_unblock_events().  Events blocking is counted and the actual
+ * unblocking happens after the matching number of unblocks are done.
+ *
+ * Note that this intentionally does not block event checking from
+ * disk_clear_events().
+ *
+ * CONTEXT:
+ * Might sleep.
+ */
+void disk_block_events(struct gendisk *disk)
 {
 	struct disk_events *ev = disk->ev;
 	unsigned long flags;
 	bool cancel;
 
+	if (!ev)
+		return;
+
+	/*
+	 * Outer mutex ensures that the first blocker completes canceling
+	 * the event work before further blockers are allowed to finish.
+	 */
+	mutex_lock(&ev->block_mutex);
+
 	spin_lock_irqsave(&ev->lock, flags);
 	cancel = !ev->block++;
 	spin_unlock_irqrestore(&ev->lock, flags);
 
-	if (cancel) {
-		if (sync)
-			cancel_delayed_work_sync(&disk->ev->dwork);
-		else
-			cancel_delayed_work(&disk->ev->dwork);
-	}
+	if (cancel)
+		cancel_delayed_work_sync(&disk->ev->dwork);
+
+	mutex_unlock(&ev->block_mutex);
 }
 
 static void __disk_unblock_events(struct gendisk *disk, bool check_now)
@@ -1461,27 +1484,6 @@
 }
 
 /**
- * disk_block_events - block and flush disk event checking
- * @disk: disk to block events for
- *
- * On return from this function, it is guaranteed that event checking
- * isn't in progress and won't happen until unblocked by
- * disk_unblock_events().  Events blocking is counted and the actual
- * unblocking happens after the matching number of unblocks are done.
- *
- * Note that this intentionally does not block event checking from
- * disk_clear_events().
- *
- * CONTEXT:
- * Might sleep.
- */
-void disk_block_events(struct gendisk *disk)
-{
-	if (disk->ev)
-		__disk_block_events(disk, true);
-}
-
-/**
  * disk_unblock_events - unblock disk event checking
  * @disk: disk to unblock events for
  *
@@ -1508,10 +1510,18 @@
  */
 void disk_check_events(struct gendisk *disk)
 {
-	if (disk->ev) {
-		__disk_block_events(disk, false);
-		__disk_unblock_events(disk, true);
+	struct disk_events *ev = disk->ev;
+	unsigned long flags;
+
+	if (!ev)
+		return;
+
+	spin_lock_irqsave(&ev->lock, flags);
+	if (!ev->block) {
+		cancel_delayed_work(&ev->dwork);
+		queue_delayed_work(system_nrt_wq, &ev->dwork, 0);
 	}
+	spin_unlock_irqrestore(&ev->lock, flags);
 }
 EXPORT_SYMBOL_GPL(disk_check_events);
 
@@ -1546,7 +1556,7 @@
 	spin_unlock_irq(&ev->lock);
 
 	/* uncondtionally schedule event check and wait for it to finish */
-	__disk_block_events(disk, true);
+	disk_block_events(disk);
 	queue_delayed_work(system_nrt_wq, &ev->dwork, 0);
 	flush_delayed_work(&ev->dwork);
 	__disk_unblock_events(disk, false);
@@ -1664,7 +1674,7 @@
 	if (intv < 0 && intv != -1)
 		return -EINVAL;
 
-	__disk_block_events(disk, true);
+	disk_block_events(disk);
 	disk->ev->poll_msecs = intv;
 	__disk_unblock_events(disk, true);
 
@@ -1728,7 +1738,7 @@
 {
 	struct disk_events *ev;
 
-	if (!disk->fops->check_events || !(disk->events | disk->async_events))
+	if (!disk->fops->check_events)
 		return;
 
 	ev = kzalloc(sizeof(*ev), GFP_KERNEL);
@@ -1750,6 +1760,7 @@
 	INIT_LIST_HEAD(&ev->node);
 	ev->disk = disk;
 	spin_lock_init(&ev->lock);
+	mutex_init(&ev->block_mutex);
 	ev->block = 1;
 	ev->poll_msecs = -1;
 	INIT_DELAYED_WORK(&ev->dwork, disk_events_workfn);
@@ -1770,7 +1781,7 @@
 	if (!disk->ev)
 		return;
 
-	__disk_block_events(disk, true);
+	disk_block_events(disk);
 
 	mutex_lock(&disk_events_mutex);
 	list_del_init(&disk->ev->node);
diff -druN linux-2.6.39-libre/CREDITS linux-3.0-rc7-libre/CREDITS
--- linux-2.6.39-libre/CREDITS	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/CREDITS	2011-07-11 19:51:52.000000000 -0400
@@ -328,7 +328,7 @@
 N: Johannes Berg
 E: johannes@sipsolutions.net
 W: http://johannes.sipsolutions.net/
-P: 1024D/9AB78CA5 AD02 0176 4E29 C137 1DF6 08D2 FC44 CF86 9AB7 8CA5
+P: 4096R/7BF9099A C0EB C440 F6DA 091C 884D  8532 E0F3 73F3 7BF9 099A
 D: powerpc & 802.11 hacker
 
 N: Stephen R. van den Berg (AKA BuGless)
@@ -518,6 +518,14 @@
 E: zab@zabbo.net
 D: maestro pci sound
 
+N: David Brownell
+D: Kernel engineer, mentor, and friend.  Maintained USB EHCI and
+D: gadget layers, SPI subsystem, GPIO subsystem, and more than a few
+D: device drivers.  His encouragement also helped many engineers get
+D: started working on the Linux kernel.  David passed away in early
+D: 2011, and will be greatly missed.
+W: https://lkml.org/lkml/2011/4/5/36
+
 N: Gary Brubaker
 E: xavyer@ix.netcom.com
 D: USB Serial Empeg Empeg-car Mark I/II Driver
@@ -2943,6 +2951,10 @@
 S: 70110 Kuopio
 S: Finland
 
+N: Tobias Ringström
+E: tori@unhappy.mine.nu
+D: Davicom DM9102(A)/DM9132/DM9801 fast ethernet driver
+
 N: Luca Risolia
 E: luca.risolia@studio.unibo.it
 P: 1024D/FCE635A4 88E8 F32F 7244 68BA 3958  5D40 99DA 5D2A FCE6 35A4
@@ -3913,6 +3925,10 @@
 S: D-73732 Esslingen
 S: Germany
 
+N: Roman Zippel
+E: zippel@linux-m68k.org
+D: AFFS and HFS filesystems, m68k maintainer, new kernel configuration in 2.5
+
 N: Leonard N. Zubkoff
 W: http://www.dandelion.com/Linux/
 D: BusLogic SCSI driver
diff -druN linux-2.6.39-libre/crypto/deflate.c linux-3.0-rc7-libre/crypto/deflate.c
--- linux-2.6.39-libre/crypto/deflate.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/crypto/deflate.c	2011-07-11 19:51:52.000000000 -0400
@@ -32,7 +32,6 @@
 #include <linux/interrupt.h>
 #include <linux/mm.h>
 #include <linux/net.h>
-#include <linux/slab.h>
 
 #define DEFLATE_DEF_LEVEL		Z_DEFAULT_COMPRESSION
 #define DEFLATE_DEF_WINBITS		11
@@ -73,7 +72,7 @@
 	int ret = 0;
 	struct z_stream_s *stream = &ctx->decomp_stream;
 
-	stream->workspace = kzalloc(zlib_inflate_workspacesize(), GFP_KERNEL);
+	stream->workspace = vzalloc(zlib_inflate_workspacesize());
 	if (!stream->workspace) {
 		ret = -ENOMEM;
 		goto out;
@@ -86,7 +85,7 @@
 out:
 	return ret;
 out_free:
-	kfree(stream->workspace);
+	vfree(stream->workspace);
 	goto out;
 }
 
@@ -99,7 +98,7 @@
 static void deflate_decomp_exit(struct deflate_ctx *ctx)
 {
 	zlib_inflateEnd(&ctx->decomp_stream);
-	kfree(ctx->decomp_stream.workspace);
+	vfree(ctx->decomp_stream.workspace);
 }
 
 static int deflate_init(struct crypto_tfm *tfm)
diff -druN linux-2.6.39-libre/crypto/Kconfig linux-3.0-rc7-libre/crypto/Kconfig
--- linux-2.6.39-libre/crypto/Kconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/crypto/Kconfig	2011-07-11 19:51:52.000000000 -0400
@@ -264,11 +264,6 @@
 	  key size 256, 384 or 512 bits. This implementation currently
 	  can't handle a sectorsize which is not a multiple of 16 bytes.
 
-config CRYPTO_FPU
-	tristate
-	select CRYPTO_BLKCIPHER
-	select CRYPTO_MANAGER
-
 comment "Hash modes"
 
 config CRYPTO_HMAC
@@ -543,7 +538,6 @@
 	select CRYPTO_AES_586 if !64BIT
 	select CRYPTO_CRYPTD
 	select CRYPTO_ALGAPI
-	select CRYPTO_FPU
 	help
 	  Use Intel AES-NI instructions for AES algorithm.
 
diff -druN linux-2.6.39-libre/crypto/tcrypt.c linux-3.0-rc7-libre/crypto/tcrypt.c
--- linux-2.6.39-libre/crypto/tcrypt.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/crypto/tcrypt.c	2011-07-11 19:51:52.000000000 -0400
@@ -1009,6 +1009,10 @@
 				speed_template_32_48_64);
 		test_cipher_speed("xts(aes)", DECRYPT, sec, NULL, 0,
 				speed_template_32_48_64);
+		test_cipher_speed("ctr(aes)", ENCRYPT, sec, NULL, 0,
+				speed_template_16_24_32);
+		test_cipher_speed("ctr(aes)", DECRYPT, sec, NULL, 0,
+				speed_template_16_24_32);
 		break;
 
 	case 201:
diff -druN linux-2.6.39-libre/crypto/testmgr.c linux-3.0-rc7-libre/crypto/testmgr.c
--- linux-2.6.39-libre/crypto/testmgr.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/crypto/testmgr.c	2011-07-11 19:51:52.000000000 -0400
@@ -2219,6 +2219,22 @@
 			}
 		}
 	}, {
+		.alg = "ofb(aes)",
+		.test = alg_test_skcipher,
+		.fips_allowed = 1,
+		.suite = {
+			.cipher = {
+				.enc = {
+					.vecs = aes_ofb_enc_tv_template,
+					.count = AES_OFB_ENC_TEST_VECTORS
+				},
+				.dec = {
+					.vecs = aes_ofb_dec_tv_template,
+					.count = AES_OFB_DEC_TEST_VECTORS
+				}
+			}
+		}
+	}, {
 		.alg = "pcbc(fcrypt)",
 		.test = alg_test_skcipher,
 		.suite = {
diff -druN linux-2.6.39-libre/crypto/testmgr.h linux-3.0-rc7-libre/crypto/testmgr.h
--- linux-2.6.39-libre/crypto/testmgr.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/crypto/testmgr.h	2011-07-11 19:51:52.000000000 -0400
@@ -2980,6 +2980,8 @@
 #define AES_XTS_DEC_TEST_VECTORS 4
 #define AES_CTR_ENC_TEST_VECTORS 3
 #define AES_CTR_DEC_TEST_VECTORS 3
+#define AES_OFB_ENC_TEST_VECTORS 1
+#define AES_OFB_DEC_TEST_VECTORS 1
 #define AES_CTR_3686_ENC_TEST_VECTORS 7
 #define AES_CTR_3686_DEC_TEST_VECTORS 6
 #define AES_GCM_ENC_TEST_VECTORS 9
@@ -5506,6 +5508,64 @@
 	},
 };
 
+static struct cipher_testvec aes_ofb_enc_tv_template[] = {
+	 /* From NIST Special Publication 800-38A, Appendix F.5 */
+	{
+		.key	= "\x2b\x7e\x15\x16\x28\xae\xd2\xa6"
+			  "\xab\xf7\x15\x88\x09\xcf\x4f\x3c",
+		.klen	= 16,
+		.iv	= "\x00\x01\x02\x03\x04\x05\x06\x07\x08"
+			  "\x09\x0a\x0b\x0c\x0d\x0e\x0f",
+		.input = "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96"
+			  "\xe9\x3d\x7e\x11\x73\x93\x17\x2a"
+			  "\xae\x2d\x8a\x57\x1e\x03\xac\x9c"
+			  "\x9e\xb7\x6f\xac\x45\xaf\x8e\x51"
+			  "\x30\xc8\x1c\x46\xa3\x5c\xe4\x11"
+			  "\xe5\xfb\xc1\x19\x1a\x0a\x52\xef"
+			  "\xf6\x9f\x24\x45\xdf\x4f\x9b\x17"
+			  "\xad\x2b\x41\x7b\xe6\x6c\x37\x10",
+		.ilen	= 64,
+		.result = "\x3b\x3f\xd9\x2e\xb7\x2d\xad\x20"
+			  "\x33\x34\x49\xf8\xe8\x3c\xfb\x4a"
+			  "\x77\x89\x50\x8d\x16\x91\x8f\x03\xf5"
+			  "\x3c\x52\xda\xc5\x4e\xd8\x25"
+			  "\x97\x40\x05\x1e\x9c\x5f\xec\xf6\x43"
+			  "\x44\xf7\xa8\x22\x60\xed\xcc"
+			  "\x30\x4c\x65\x28\xf6\x59\xc7\x78"
+			  "\x66\xa5\x10\xd9\xc1\xd6\xae\x5e",
+		.rlen	= 64,
+	}
+};
+
+static struct cipher_testvec aes_ofb_dec_tv_template[] = {
+	 /* From NIST Special Publication 800-38A, Appendix F.5 */
+	{
+		.key	= "\x2b\x7e\x15\x16\x28\xae\xd2\xa6"
+			  "\xab\xf7\x15\x88\x09\xcf\x4f\x3c",
+		.klen	= 16,
+		.iv	= "\x00\x01\x02\x03\x04\x05\x06\x07\x08"
+			  "\x09\x0a\x0b\x0c\x0d\x0e\x0f",
+		.input = "\x3b\x3f\xd9\x2e\xb7\x2d\xad\x20"
+			  "\x33\x34\x49\xf8\xe8\x3c\xfb\x4a"
+			  "\x77\x89\x50\x8d\x16\x91\x8f\x03\xf5"
+			  "\x3c\x52\xda\xc5\x4e\xd8\x25"
+			  "\x97\x40\x05\x1e\x9c\x5f\xec\xf6\x43"
+			  "\x44\xf7\xa8\x22\x60\xed\xcc"
+			  "\x30\x4c\x65\x28\xf6\x59\xc7\x78"
+			  "\x66\xa5\x10\xd9\xc1\xd6\xae\x5e",
+		.ilen	= 64,
+		.result = "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96"
+			  "\xe9\x3d\x7e\x11\x73\x93\x17\x2a"
+			  "\xae\x2d\x8a\x57\x1e\x03\xac\x9c"
+			  "\x9e\xb7\x6f\xac\x45\xaf\x8e\x51"
+			  "\x30\xc8\x1c\x46\xa3\x5c\xe4\x11"
+			  "\xe5\xfb\xc1\x19\x1a\x0a\x52\xef"
+			  "\xf6\x9f\x24\x45\xdf\x4f\x9b\x17"
+			  "\xad\x2b\x41\x7b\xe6\x6c\x37\x10",
+		.rlen	= 64,
+	}
+};
+
 static struct aead_testvec aes_gcm_enc_tv_template[] = {
 	{ /* From McGrew & Viega - http://citeseer.ist.psu.edu/656989.html */
 		.key    = zeroed_string,
diff -druN linux-2.6.39-libre/crypto/zlib.c linux-3.0-rc7-libre/crypto/zlib.c
--- linux-2.6.39-libre/crypto/zlib.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/crypto/zlib.c	2011-07-11 19:51:52.000000000 -0400
@@ -29,7 +29,6 @@
 #include <linux/interrupt.h>
 #include <linux/mm.h>
 #include <linux/net.h>
-#include <linux/slab.h>
 
 #include <crypto/internal/compress.h>
 
@@ -60,7 +59,7 @@
 
 	if (stream->workspace) {
 		zlib_inflateEnd(stream);
-		kfree(stream->workspace);
+		vfree(stream->workspace);
 		stream->workspace = NULL;
 	}
 }
@@ -228,13 +227,13 @@
 				 ? nla_get_u32(tb[ZLIB_DECOMP_WINDOWBITS])
 				 : DEF_WBITS;
 
-	stream->workspace = kzalloc(zlib_inflate_workspacesize(), GFP_KERNEL);
+	stream->workspace = vzalloc(zlib_inflate_workspacesize());
 	if (!stream->workspace)
 		return -ENOMEM;
 
 	ret = zlib_inflateInit2(stream, ctx->decomp_windowBits);
 	if (ret != Z_OK) {
-		kfree(stream->workspace);
+		vfree(stream->workspace);
 		stream->workspace = NULL;
 		return -EINVAL;
 	}
diff -druN linux-2.6.39-libre/Documentation/00-INDEX linux-3.0-rc7-libre/Documentation/00-INDEX
--- linux-2.6.39-libre/Documentation/00-INDEX	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/Documentation/00-INDEX	2011-07-11 19:51:52.000000000 -0400
@@ -192,10 +192,6 @@
 	- listing of various WWW + books that document kernel internals.
 kernel-parameters.txt
 	- summary listing of command line / boot prompt args for the kernel.
-keys-request-key.txt
-	- description of the kernel key request service.
-keys.txt
-	- description of the kernel key retention service.
 kobject.txt
 	- info of the kobject infrastructure of the Linux kernel.
 kprobes.txt
@@ -294,6 +290,8 @@
 	- directory with info on the scheduler.
 scsi/
 	- directory with info on Linux scsi support.
+security/
+	- directory that contains security-related info
 serial/
 	- directory with info on the low level serial API.
 serial-console.txt
@@ -328,8 +326,6 @@
 	- info on the magic SysRq key.
 telephony/
 	- directory with info on telephony (e.g. voice over IP) support.
-uml/
-	- directory with information about User Mode Linux.
 unicode.txt
 	- info on the Unicode character/font mapping used in Linux.
 unshare.txt
diff -druN linux-2.6.39-libre/Documentation/ABI/obsolete/o2cb linux-3.0-rc7-libre/Documentation/ABI/obsolete/o2cb
--- linux-2.6.39-libre/Documentation/ABI/obsolete/o2cb	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/Documentation/ABI/obsolete/o2cb	1969-12-31 19:00:00.000000000 -0500
@@ -1,11 +0,0 @@
-What:		/sys/o2cb symlink
-Date:		Dec 2005
-KernelVersion:	2.6.16
-Contact:	ocfs2-devel@oss.oracle.com
-Description:	This is a symlink: /sys/o2cb to /sys/fs/o2cb. The symlink will
-		be removed when new versions of ocfs2-tools which know to look
-		in /sys/fs/o2cb are sufficiently prevalent. Don't code new
-		software to look here, it should try /sys/fs/o2cb instead.
-		See Documentation/ABI/stable/o2cb for more information on usage.
-Users:		ocfs2-tools. It's sufficient to mail proposed changes to
-		ocfs2-devel@oss.oracle.com.
diff -druN linux-2.6.39-libre/Documentation/ABI/obsolete/sysfs-driver-hid-roccat-koneplus linux-3.0-rc7-libre/Documentation/ABI/obsolete/sysfs-driver-hid-roccat-koneplus
--- linux-2.6.39-libre/Documentation/ABI/obsolete/sysfs-driver-hid-roccat-koneplus	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/Documentation/ABI/obsolete/sysfs-driver-hid-roccat-koneplus	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,10 @@
+What:		/sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/koneplus/roccatkoneplus<minor>/startup_profile
+Date:		October 2010
+Contact:	Stefan Achatz <erazor_de@users.sourceforge.net>
+Description:	The integer value of this attribute ranges from 0-4.
+                When read, this attribute returns the number of the actual
+                profile. This value is persistent, so its equivalent to the
+                profile that's active when the mouse is powered on next time.
+		When written, this file sets the number of the startup profile
+		and the mouse activates this profile immediately.
+		Please use actual_profile, it does the same thing.
diff -druN linux-2.6.39-libre/Documentation/ABI/removed/o2cb linux-3.0-rc7-libre/Documentation/ABI/removed/o2cb
--- linux-2.6.39-libre/Documentation/ABI/removed/o2cb	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/Documentation/ABI/removed/o2cb	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,10 @@
+What:		/sys/o2cb symlink
+Date:		May 2011
+KernelVersion:	2.6.40
+Contact:	ocfs2-devel@oss.oracle.com
+Description:	This is a symlink: /sys/o2cb to /sys/fs/o2cb. The symlink is
+		removed when new versions of ocfs2-tools which know to look
+		in /sys/fs/o2cb are sufficiently prevalent. Don't code new
+		software to look here, it should try /sys/fs/o2cb instead.
+Users:		ocfs2-tools. It's sufficient to mail proposed changes to
+		ocfs2-devel@oss.oracle.com.
diff -druN linux-2.6.39-libre/Documentation/ABI/testing/sysfs-block linux-3.0-rc7-libre/Documentation/ABI/testing/sysfs-block
--- linux-2.6.39-libre/Documentation/ABI/testing/sysfs-block	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/Documentation/ABI/testing/sysfs-block	2011-07-11 19:51:52.000000000 -0400
@@ -142,3 +142,67 @@
 		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.
+
+What:		/sys/block/<disk>/discard_alignment
+Date:		May 2011
+Contact:	Martin K. Petersen <martin.petersen@oracle.com>
+Description:
+		Devices that support discard functionality may
+		internally allocate space in units that are bigger than
+		the exported logical block size. The discard_alignment
+		parameter indicates how many bytes the beginning of the
+		device is offset from the internal allocation unit's
+		natural alignment.
+
+What:		/sys/block/<disk>/<partition>/discard_alignment
+Date:		May 2011
+Contact:	Martin K. Petersen <martin.petersen@oracle.com>
+Description:
+		Devices that support discard functionality may
+		internally allocate space in units that are bigger than
+		the exported logical block size. The discard_alignment
+		parameter indicates how many bytes the beginning of the
+		partition is offset from the internal allocation unit's
+		natural alignment.
+
+What:		/sys/block/<disk>/queue/discard_granularity
+Date:		May 2011
+Contact:	Martin K. Petersen <martin.petersen@oracle.com>
+Description:
+		Devices that support discard functionality may
+		internally allocate space using units that are bigger
+		than the logical block size. The discard_granularity
+		parameter indicates the size of the internal allocation
+		unit in bytes if reported by the device. Otherwise the
+		discard_granularity will be set to match the device's
+		physical block size. A discard_granularity of 0 means
+		that the device does not support discard functionality.
+
+What:		/sys/block/<disk>/queue/discard_max_bytes
+Date:		May 2011
+Contact:	Martin K. Petersen <martin.petersen@oracle.com>
+Description:
+		Devices that support discard functionality may have
+		internal limits on the number of bytes that can be
+		trimmed or unmapped in a single operation. Some storage
+		protocols also have inherent limits on the number of
+		blocks that can be described in a single command. The
+		discard_max_bytes parameter is set by the device driver
+		to the maximum number of bytes that can be discarded in
+		a single operation. Discard requests issued to the
+		device must not exceed this limit. A discard_max_bytes
+		value of 0 means that the device does not support
+		discard functionality.
+
+What:		/sys/block/<disk>/queue/discard_zeroes_data
+Date:		May 2011
+Contact:	Martin K. Petersen <martin.petersen@oracle.com>
+Description:
+		Devices that support discard functionality may return
+		stale or random data when a previously discarded block
+		is read back. This can cause problems if the filesystem
+		expects discarded blocks to be explicitly cleared. If a
+		device reports that it deterministically returns zeroes
+		when a discarded area is read the discard_zeroes_data
+		parameter will be set to one. Otherwise it will be 0 and
+		the result of reading a discarded area is undefined.
diff -druN linux-2.6.39-libre/Documentation/ABI/testing/sysfs-bus-bcma linux-3.0-rc7-libre/Documentation/ABI/testing/sysfs-bus-bcma
--- linux-2.6.39-libre/Documentation/ABI/testing/sysfs-bus-bcma	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/Documentation/ABI/testing/sysfs-bus-bcma	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,31 @@
+What:		/sys/bus/bcma/devices/.../manuf
+Date:		May 2011
+KernelVersion:	2.6.40
+Contact:	Rafał Miłecki <zajec5@gmail.com>
+Description:
+		Each BCMA core has it's manufacturer id. See
+		include/linux/bcma/bcma.h for possible values.
+
+What:		/sys/bus/bcma/devices/.../id
+Date:		May 2011
+KernelVersion:	2.6.40
+Contact:	Rafał Miłecki <zajec5@gmail.com>
+Description:
+		There are a few types of BCMA cores, they can be identified by
+		id field.
+
+What:		/sys/bus/bcma/devices/.../rev
+Date:		May 2011
+KernelVersion:	2.6.40
+Contact:	Rafał Miłecki <zajec5@gmail.com>
+Description:
+		BCMA cores of the same type can still slightly differ depending
+		on their revision. Use it for detailed programming.
+
+What:		/sys/bus/bcma/devices/.../class
+Date:		May 2011
+KernelVersion:	2.6.40
+Contact:	Rafał Miłecki <zajec5@gmail.com>
+Description:
+		Each BCMA core is identified by few fields, including class it
+		belongs to. See include/linux/bcma/bcma.h for possible values.
diff -druN linux-2.6.39-libre/Documentation/ABI/testing/sysfs-bus-pci linux-3.0-rc7-libre/Documentation/ABI/testing/sysfs-bus-pci
--- linux-2.6.39-libre/Documentation/ABI/testing/sysfs-bus-pci	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/Documentation/ABI/testing/sysfs-bus-pci	2011-07-11 19:51:52.000000000 -0400
@@ -74,6 +74,15 @@
 		hot-remove the PCI device and any of its children.
 		Depends on CONFIG_HOTPLUG.
 
+What:		/sys/bus/pci/devices/.../pci_bus/.../rescan
+Date:		May 2011
+Contact:	Linux PCI developers <linux-pci@vger.kernel.org>
+Description:
+		Writing a non-zero value to this attribute will
+		force a rescan of the bus and all child buses,
+		and re-discover devices removed earlier from this
+		part of the device tree.  Depends on CONFIG_HOTPLUG.
+
 What:		/sys/bus/pci/devices/.../rescan
 Date:		January 2009
 Contact:	Linux PCI developers <linux-pci@vger.kernel.org>
diff -druN linux-2.6.39-libre/Documentation/ABI/testing/sysfs-class-backlight-driver-adp8870 linux-3.0-rc7-libre/Documentation/ABI/testing/sysfs-class-backlight-driver-adp8870
--- linux-2.6.39-libre/Documentation/ABI/testing/sysfs-class-backlight-driver-adp8870	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/Documentation/ABI/testing/sysfs-class-backlight-driver-adp8870	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,56 @@
+What:		/sys/class/backlight/<backlight>/<ambient light zone>_max
+What:		/sys/class/backlight/<backlight>/l1_daylight_max
+What:		/sys/class/backlight/<backlight>/l2_bright_max
+What:		/sys/class/backlight/<backlight>/l3_office_max
+What:		/sys/class/backlight/<backlight>/l4_indoor_max
+What:		/sys/class/backlight/<backlight>/l5_dark_max
+Date:		Mai 2011
+KernelVersion:	2.6.40
+Contact:	device-drivers-devel@blackfin.uclinux.org
+Description:
+		Control the maximum brightness for <ambient light zone>
+		on this <backlight>. Values are between 0 and 127. This file
+		will also show the brightness level stored for this
+		<ambient light zone>.
+
+What:		/sys/class/backlight/<backlight>/<ambient light zone>_dim
+What:		/sys/class/backlight/<backlight>/l2_bright_dim
+What:		/sys/class/backlight/<backlight>/l3_office_dim
+What:		/sys/class/backlight/<backlight>/l4_indoor_dim
+What:		/sys/class/backlight/<backlight>/l5_dark_dim
+Date:		Mai 2011
+KernelVersion:	2.6.40
+Contact:	device-drivers-devel@blackfin.uclinux.org
+Description:
+		Control the dim brightness for <ambient light zone>
+		on this <backlight>. Values are between 0 and 127, typically
+		set to 0. Full off when the backlight is disabled.
+		This file will also show the dim brightness level stored for
+		this <ambient light zone>.
+
+What:		/sys/class/backlight/<backlight>/ambient_light_level
+Date:		Mai 2011
+KernelVersion:	2.6.40
+Contact:	device-drivers-devel@blackfin.uclinux.org
+Description:
+		Get conversion value of the light sensor.
+		This value is updated every 80 ms (when the light sensor
+		is enabled). Returns integer between 0 (dark) and
+		8000 (max ambient brightness)
+
+What:		/sys/class/backlight/<backlight>/ambient_light_zone
+Date:		Mai 2011
+KernelVersion:	2.6.40
+Contact:	device-drivers-devel@blackfin.uclinux.org
+Description:
+		Get/Set current ambient light zone. Reading returns
+		integer between 1..5 (1 = daylight, 2 = bright, ..., 5 = dark).
+		Writing a value between 1..5 forces the backlight controller
+		to enter the corresponding ambient light zone.
+		Writing 0 returns to normal/automatic ambient light level
+		operation. The ambient light sensing feature on these devices
+		is an extension to the API documented in
+		Documentation/ABI/stable/sysfs-class-backlight.
+		It can be enabled by writing the value stored in
+		/sys/class/backlight/<backlight>/max_brightness to
+		/sys/class/backlight/<backlight>/brightness.
\ No newline at end of file
diff -druN linux-2.6.39-libre/Documentation/ABI/testing/sysfs-devices-system-cpu linux-3.0-rc7-libre/Documentation/ABI/testing/sysfs-devices-system-cpu
--- linux-2.6.39-libre/Documentation/ABI/testing/sysfs-devices-system-cpu	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/Documentation/ABI/testing/sysfs-devices-system-cpu	2011-07-11 19:51:52.000000000 -0400
@@ -183,21 +183,21 @@
 		to learn how to control the knobs.
 
 
-What:      /sys/devices/system/cpu/cpu*/cache/index*/cache_disable_X
-Date:      August 2008
+What:		/sys/devices/system/cpu/cpu*/cache/index3/cache_disable_{0,1}
+Date:		August 2008
 KernelVersion:	2.6.27
-Contact:	mark.langsdorf@amd.com
-Description:	These files exist in every cpu's cache index directories.
-		There are currently 2 cache_disable_# files in each
-		directory.  Reading from these files on a supported
-		processor will return that cache disable index value
-		for that processor and node.  Writing to one of these
-		files will cause the specificed cache index to be disabled.
+Contact:	discuss@x86-64.org
+Description:	Disable L3 cache indices
 
-		Currently, only AMD Family 10h Processors support cache index
-		disable, and only for their L3 caches.  See the BIOS and
-		Kernel Developer's Guide at
-		http://support.amd.com/us/Embedded_TechDocs/31116-Public-GH-BKDG_3-28_5-28-09.pdf	
-		for formatting information and other details on the
-		cache index disable.
-Users:    joachim.deguara@amd.com
+		These files exist in every CPU's cache/index3 directory. Each
+		cache_disable_{0,1} file corresponds to one disable slot which
+		can be used to disable a cache index. Reading from these files
+		on a processor with this functionality will return the currently
+		disabled index for that node. There is one L3 structure per
+		node, or per internal node on MCM machines. Writing a valid
+		index to one of these files will cause the specificed cache
+		index to be disabled.
+
+		All AMD processors with L3 caches provide this functionality.
+		For details, see BKDGs at
+		http://developer.amd.com/documentation/guides/Pages/default.aspx
diff -druN linux-2.6.39-libre/Documentation/ABI/testing/sysfs-driver-hid-roccat-koneplus linux-3.0-rc7-libre/Documentation/ABI/testing/sysfs-driver-hid-roccat-koneplus
--- linux-2.6.39-libre/Documentation/ABI/testing/sysfs-driver-hid-roccat-koneplus	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/Documentation/ABI/testing/sysfs-driver-hid-roccat-koneplus	2011-07-11 19:51:52.000000000 -0400
@@ -1,9 +1,12 @@
 What:		/sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/koneplus/roccatkoneplus<minor>/actual_profile
 Date:		October 2010
 Contact:	Stefan Achatz <erazor_de@users.sourceforge.net>
-Description:	When read, this file returns the number of the actual profile in
-		range 0-4.
-		This file is readonly.
+Description:	The integer value of this attribute ranges from 0-4.
+                When read, this attribute returns the number of the actual
+                profile. This value is persistent, so its equivalent to the
+                profile that's active when the mouse is powered on next time.
+		When written, this file sets the number of the startup profile
+		and the mouse activates this profile immediately.
 Users:		http://roccat.sourceforge.net
 
 What:		/sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/koneplus/roccatkoneplus<minor>/firmware_version
@@ -89,16 +92,6 @@
 		This file is writeonly.
 Users:		http://roccat.sourceforge.net
 
-What:		/sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/koneplus/roccatkoneplus<minor>/startup_profile
-Date:		October 2010
-Contact:	Stefan Achatz <erazor_de@users.sourceforge.net>
-Description:	The integer value of this attribute ranges from 0-4.
-                When read, this attribute returns the number of the profile
-                that's active when the mouse is powered on.
-		When written, this file sets the number of the startup profile
-		and the mouse activates this profile immediately.
-Users:		http://roccat.sourceforge.net
-
 What:		/sys/bus/usb/devices/<busnum>-<devnum>:<config num>.<interface num>/<hid-bus>:<vendor-id>:<product-id>.<num>/koneplus/roccatkoneplus<minor>/tcu
 Date:		October 2010
 Contact:	Stefan Achatz <erazor_de@users.sourceforge.net>
diff -druN linux-2.6.39-libre/Documentation/ABI/testing/sysfs-firmware-dmi linux-3.0-rc7-libre/Documentation/ABI/testing/sysfs-firmware-dmi
--- linux-2.6.39-libre/Documentation/ABI/testing/sysfs-firmware-dmi	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/Documentation/ABI/testing/sysfs-firmware-dmi	2011-07-11 19:51:52.000000000 -0400
@@ -14,14 +14,15 @@
 
 		DMI is structured as a large table of entries, where
 		each entry has a common header indicating the type and
-		length of the entry, as well as 'handle' that is
-		supposed to be unique amongst all entries.
+		length of the entry, as well as a firmware-provided
+		'handle' that is supposed to be unique amongst all
+		entries.
 
 		Some entries are required by the specification, but many
 		others are optional.  In general though, users should
 		never expect to find a specific entry type on their
 		system unless they know for certain what their firmware
-		is doing.  Machine to machine will vary.
+		is doing.  Machine to machine experiences will vary.
 
 		Multiple entries of the same type are allowed.  In order
 		to handle these duplicate entry types, each entry is
@@ -67,25 +68,24 @@
 			  and the two terminating nul characters.
 		type	: The type of the entry.  This value is the same
 			  as found in the directory name.  It indicates
-			  how the rest of the entry should be
-			  interpreted.
+			  how the rest of the entry should be interpreted.
 		instance: The instance ordinal of the entry for the
 			  given type.  This value is the same as found
 			  in the parent directory name.
-		position: The position of the entry within the entirety
-			  of the entirety.
+		position: The ordinal position (zero-based) of the entry
+			  within the entirety of the DMI entry table.
 
 		=== Entry Specialization ===
 
 		Some entry types may have other information available in
-		sysfs.
+		sysfs.  Not all types are specialized.
 
 		--- Type 15 - System Event Log ---
 
 		This entry allows the firmware to export a log of
 		events the system has taken.  This information is
 		typically backed by nvram, but the implementation
-		details are abstracted by this table.  This entries data
+		details are abstracted by this table.  This entry's data
 		is exported in the directory:
 
 		/sys/firmware/dmi/entries/15-0/system_event_log
diff -druN linux-2.6.39-libre/Documentation/ABI/testing/sysfs-firmware-gsmi linux-3.0-rc7-libre/Documentation/ABI/testing/sysfs-firmware-gsmi
--- linux-2.6.39-libre/Documentation/ABI/testing/sysfs-firmware-gsmi	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/Documentation/ABI/testing/sysfs-firmware-gsmi	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,58 @@
+What:		/sys/firmware/gsmi
+Date:		March 2011
+Contact:	Mike Waychison <mikew@google.com>
+Description:
+		Some servers used internally at Google have firmware
+		that provides callback functionality via explicit SMI
+		triggers.  Some of the callbacks are similar to those
+		provided by the EFI runtime services page, but due to
+		historical reasons this different entry-point has been
+		used.
+
+		The gsmi driver implements the kernel's abstraction for
+		these firmware callbacks.  Currently, this functionality
+		is limited to handling the system event log and getting
+		access to EFI-style variables stored in nvram.
+
+		Layout:
+
+		/sys/firmware/gsmi/vars:
+
+			This directory has the same layout (and
+			underlying implementation as /sys/firmware/efi/vars.
+			See Documentation/ABI/*/sysfs-firmware-efi-vars
+			for more information on how to interact with
+			this structure.
+
+		/sys/firmware/gsmi/append_to_eventlog - write-only:
+
+			This file takes a binary blob and passes it onto
+			the firmware to be timestamped and appended to
+			the system eventlog.  The binary format is
+			interpreted by the firmware and may change from
+			platform to platform.  The only kernel-enforced
+			requirement is that the blob be prefixed with a
+			32bit host-endian type used as part of the
+			firmware call.
+
+		/sys/firmware/gsmi/clear_config - write-only:
+
+			Writing any value to this file will cause the
+			entire firmware configuration to be reset to
+			"factory defaults".  Callers should assume that
+			a reboot is required for the configuration to be
+			cleared.
+
+		/sys/firmware/gsmi/clear_eventlog - write-only:
+
+			This file is used to clear out a portion/the
+			whole of the system event log.  Values written
+			should be values between 1 and 100 inclusive (in
+			ASCII) representing the fraction of the log to
+			clear.  Not all platforms support fractional
+			clearing though, and this writes to this file
+			will error out if the firmware doesn't like your
+			submitted fraction.
+
+			Callers should assume that a reboot is needed
+			for this operation to complete.
diff -druN linux-2.6.39-libre/Documentation/ABI/testing/sysfs-firmware-log linux-3.0-rc7-libre/Documentation/ABI/testing/sysfs-firmware-log
--- linux-2.6.39-libre/Documentation/ABI/testing/sysfs-firmware-log	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/Documentation/ABI/testing/sysfs-firmware-log	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,7 @@
+What:		/sys/firmware/log
+Date:		February 2011
+Contact:	Mike Waychison <mikew@google.com>
+Description:
+		The /sys/firmware/log is a binary file that represents a
+		read-only copy of the firmware's log if one is
+		available.
diff -druN linux-2.6.39-libre/Documentation/ABI/testing/sysfs-kernel-fscaps linux-3.0-rc7-libre/Documentation/ABI/testing/sysfs-kernel-fscaps
--- linux-2.6.39-libre/Documentation/ABI/testing/sysfs-kernel-fscaps	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/Documentation/ABI/testing/sysfs-kernel-fscaps	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,8 @@
+What:		/sys/kernel/fscaps
+Date:		February 2011
+KernelVersion:	2.6.38
+Contact:	Ludwig Nussel <ludwig.nussel@suse.de>
+Description
+		Shows whether file system capabilities are honored
+		when executing a binary
+
diff -druN linux-2.6.39-libre/Documentation/ABI/testing/sysfs-kernel-mm-cleancache linux-3.0-rc7-libre/Documentation/ABI/testing/sysfs-kernel-mm-cleancache
--- linux-2.6.39-libre/Documentation/ABI/testing/sysfs-kernel-mm-cleancache	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/Documentation/ABI/testing/sysfs-kernel-mm-cleancache	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,11 @@
+What:		/sys/kernel/mm/cleancache/
+Date:		April 2011
+Contact:	Dan Magenheimer <dan.magenheimer@oracle.com>
+Description:
+		/sys/kernel/mm/cleancache/ contains a number of files which
+		record a count of various cleancache operations
+		(sum across all filesystems):
+			succ_gets
+			failed_gets
+			puts
+			flushes
diff -druN linux-2.6.39-libre/Documentation/ABI/testing/sysfs-power linux-3.0-rc7-libre/Documentation/ABI/testing/sysfs-power
--- linux-2.6.39-libre/Documentation/ABI/testing/sysfs-power	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/Documentation/ABI/testing/sysfs-power	2011-07-11 19:51:52.000000000 -0400
@@ -158,3 +158,17 @@
 		successful, will make the kernel abort a subsequent transition
 		to a sleep state if any wakeup events are reported after the
 		write has returned.
+
+What:		/sys/power/reserved_size
+Date:		May 2011
+Contact:	Rafael J. Wysocki <rjw@sisk.pl>
+Description:
+		The /sys/power/reserved_size file allows user space to control
+		the amount of memory reserved for allocations made by device
+		drivers during the "device freeze" stage of hibernation.  It can
+		be written a string representing a non-negative integer that
+		will be used as the amount of memory to reserve for allocations
+		made by device drivers' "freeze" callbacks, in bytes.
+
+		Reading from this file will display the current value, which is
+		set to 1 MB by default.
diff -druN linux-2.6.39-libre/Documentation/ABI/testing/sysfs-ptp linux-3.0-rc7-libre/Documentation/ABI/testing/sysfs-ptp
--- linux-2.6.39-libre/Documentation/ABI/testing/sysfs-ptp	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/Documentation/ABI/testing/sysfs-ptp	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,98 @@
+What:		/sys/class/ptp/
+Date:		September 2010
+Contact:	Richard Cochran <richardcochran@gmail.com>
+Description:
+		This directory contains files and directories
+		providing a standardized interface to the ancillary
+		features of PTP hardware clocks.
+
+What:		/sys/class/ptp/ptpN/
+Date:		September 2010
+Contact:	Richard Cochran <richardcochran@gmail.com>
+Description:
+		This directory contains the attributes of the Nth PTP
+		hardware clock registered into the PTP class driver
+		subsystem.
+
+What:		/sys/class/ptp/ptpN/clock_name
+Date:		September 2010
+Contact:	Richard Cochran <richardcochran@gmail.com>
+Description:
+		This file contains the name of the PTP hardware clock
+		as a human readable string.
+
+What:		/sys/class/ptp/ptpN/max_adjustment
+Date:		September 2010
+Contact:	Richard Cochran <richardcochran@gmail.com>
+Description:
+		This file contains the PTP hardware clock's maximum
+		frequency adjustment value (a positive integer) in
+		parts per billion.
+
+What:		/sys/class/ptp/ptpN/n_alarms
+Date:		September 2010
+Contact:	Richard Cochran <richardcochran@gmail.com>
+Description:
+		This file contains the number of periodic or one shot
+		alarms offer by the PTP hardware clock.
+
+What:		/sys/class/ptp/ptpN/n_external_timestamps
+Date:		September 2010
+Contact:	Richard Cochran <richardcochran@gmail.com>
+Description:
+		This file contains the number of external timestamp
+		channels offered by the PTP hardware clock.
+
+What:		/sys/class/ptp/ptpN/n_periodic_outputs
+Date:		September 2010
+Contact:	Richard Cochran <richardcochran@gmail.com>
+Description:
+		This file contains the number of programmable periodic
+		output channels offered by the PTP hardware clock.
+
+What:		/sys/class/ptp/ptpN/pps_avaiable
+Date:		September 2010
+Contact:	Richard Cochran <richardcochran@gmail.com>
+Description:
+		This file indicates whether the PTP hardware clock
+		supports a Pulse Per Second to the host CPU. Reading
+		"1" means that the PPS is supported, while "0" means
+		not supported.
+
+What:		/sys/class/ptp/ptpN/extts_enable
+Date:		September 2010
+Contact:	Richard Cochran <richardcochran@gmail.com>
+Description:
+		This write-only file enables or disables external
+		timestamps. To enable external timestamps, write the
+		channel index followed by a "1" into the file.
+		To disable external timestamps, write the channel
+		index followed by a "0" into the file.
+
+What:		/sys/class/ptp/ptpN/fifo
+Date:		September 2010
+Contact:	Richard Cochran <richardcochran@gmail.com>
+Description:
+		This file provides timestamps on external events, in
+		the form of three integers: channel index, seconds,
+		and nanoseconds.
+
+What:		/sys/class/ptp/ptpN/period
+Date:		September 2010
+Contact:	Richard Cochran <richardcochran@gmail.com>
+Description:
+		This write-only file enables or disables periodic
+		outputs. To enable a periodic output, write five
+		integers into the file: channel index, start time
+		seconds, start time nanoseconds, period seconds, and
+		period nanoseconds. To disable a periodic output, set
+		all the seconds and nanoseconds values to zero.
+
+What:		/sys/class/ptp/ptpN/pps_enable
+Date:		September 2010
+Contact:	Richard Cochran <richardcochran@gmail.com>
+Description:
+		This write-only file enables or disables delivery of
+		PPS events to the Linux PPS subsystem. To enable PPS
+		events, write a "1" into the file. To disable events,
+		write a "0" into the file.
diff -druN linux-2.6.39-libre/Documentation/accounting/cgroupstats.txt linux-3.0-rc7-libre/Documentation/accounting/cgroupstats.txt
--- linux-2.6.39-libre/Documentation/accounting/cgroupstats.txt	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/Documentation/accounting/cgroupstats.txt	2011-07-11 19:51:52.000000000 -0400
@@ -21,7 +21,7 @@
 To extract cgroup statistics a utility very similar to getdelays.c
 has been developed, the sample output of the utility is shown below
 
-~/balbir/cgroupstats # ./getdelays  -C "/cgroup/a"
+~/balbir/cgroupstats # ./getdelays  -C "/sys/fs/cgroup/a"
 sleeping 1, blocked 0, running 1, stopped 0, uninterruptible 0
-~/balbir/cgroupstats # ./getdelays  -C "/cgroup"
+~/balbir/cgroupstats # ./getdelays  -C "/sys/fs/cgroup"
 sleeping 155, blocked 0, running 1, stopped 0, uninterruptible 2
diff -druN linux-2.6.39-libre/Documentation/accounting/getdelays.c linux-3.0-rc7-libre/Documentation/accounting/getdelays.c
--- linux-2.6.39-libre/Documentation/accounting/getdelays.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/Documentation/accounting/getdelays.c	2011-07-11 19:51:52.000000000 -0400
@@ -177,6 +177,8 @@
 	rc = send_cmd(sd, GENL_ID_CTRL, getpid(), CTRL_CMD_GETFAMILY,
 			CTRL_ATTR_FAMILY_NAME, (void *)name,
 			strlen(TASKSTATS_GENL_NAME)+1);
+	if (rc < 0)
+		return 0;	/* sendto() failure? */
 
 	rep_len = recv(sd, &ans, sizeof(ans), 0);
 	if (ans.n.nlmsg_type == NLMSG_ERROR ||
@@ -191,30 +193,37 @@
 	return id;
 }
 
+#define average_ms(t, c) (t / 1000000ULL / (c ? c : 1))
+
 static void print_delayacct(struct taskstats *t)
 {
-	printf("\n\nCPU   %15s%15s%15s%15s\n"
-	       "      %15llu%15llu%15llu%15llu\n"
-	       "IO    %15s%15s\n"
-	       "      %15llu%15llu\n"
-	       "SWAP  %15s%15s\n"
-	       "      %15llu%15llu\n"
-	       "RECLAIM  %12s%15s\n"
-	       "      %15llu%15llu\n",
-	       "count", "real total", "virtual total", "delay total",
+	printf("\n\nCPU   %15s%15s%15s%15s%15s\n"
+	       "      %15llu%15llu%15llu%15llu%15.3fms\n"
+	       "IO    %15s%15s%15s\n"
+	       "      %15llu%15llu%15llums\n"
+	       "SWAP  %15s%15s%15s\n"
+	       "      %15llu%15llu%15llums\n"
+	       "RECLAIM  %12s%15s%15s\n"
+	       "      %15llu%15llu%15llums\n",
+	       "count", "real total", "virtual total",
+	       "delay total", "delay average",
 	       (unsigned long long)t->cpu_count,
 	       (unsigned long long)t->cpu_run_real_total,
 	       (unsigned long long)t->cpu_run_virtual_total,
 	       (unsigned long long)t->cpu_delay_total,
-	       "count", "delay total",
+	       average_ms((double)t->cpu_delay_total, t->cpu_count),
+	       "count", "delay total", "delay average",
 	       (unsigned long long)t->blkio_count,
 	       (unsigned long long)t->blkio_delay_total,
-	       "count", "delay total",
+	       average_ms(t->blkio_delay_total, t->blkio_count),
+	       "count", "delay total", "delay average",
 	       (unsigned long long)t->swapin_count,
 	       (unsigned long long)t->swapin_delay_total,
-	       "count", "delay total",
+	       average_ms(t->swapin_delay_total, t->swapin_count),
+	       "count", "delay total", "delay average",
 	       (unsigned long long)t->freepages_count,
-	       (unsigned long long)t->freepages_delay_total);
+	       (unsigned long long)t->freepages_delay_total,
+	       average_ms(t->freepages_delay_total, t->freepages_count));
 }
 
 static void task_context_switch_counts(struct taskstats *t)
@@ -433,8 +442,6 @@
 	}
 
 	do {
-		int i;
-
 		rep_len = recv(nl_sd, &msg, sizeof(msg), 0);
 		PRINTF("received %d bytes\n", rep_len);
 
@@ -459,7 +466,6 @@
 
 		na = (struct nlattr *) GENLMSG_DATA(&msg);
 		len = 0;
-		i = 0;
 		while (len < rep_len) {
 			len += NLA_ALIGN(na->nla_len);
 			switch (na->nla_type) {
diff -druN linux-2.6.39-libre/Documentation/acpi/method-customizing.txt linux-3.0-rc7-libre/Documentation/acpi/method-customizing.txt
--- linux-2.6.39-libre/Documentation/acpi/method-customizing.txt	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/Documentation/acpi/method-customizing.txt	2011-07-11 19:51:52.000000000 -0400
@@ -66,3 +66,8 @@
       But each individual write to debugfs can implement a SINGLE
       method override. i.e. if we want to insert/override multiple
       ACPI methods, we need to redo step c) ~ g) for multiple times.
+
+Note: Be aware that root can mis-use this driver to modify arbitrary
+      memory and gain additional rights, if root's privileges got
+      restricted (for example if root is not allowed to load additional
+      modules after boot).
diff -druN linux-2.6.39-libre/Documentation/apparmor.txt linux-3.0-rc7-libre/Documentation/apparmor.txt
--- linux-2.6.39-libre/Documentation/apparmor.txt	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/Documentation/apparmor.txt	1969-12-31 19:00:00.000000000 -0500
@@ -1,39 +0,0 @@
---- What is AppArmor? ---
-
-AppArmor is MAC style security extension for the Linux kernel.  It implements
-a task centered policy, with task "profiles" being created and loaded
-from user space.  Tasks on the system that do not have a profile defined for
-them run in an unconfined state which is equivalent to standard Linux DAC
-permissions.
-
---- How to enable/disable ---
-
-set CONFIG_SECURITY_APPARMOR=y
-
-If AppArmor should be selected as the default security module then
-   set CONFIG_DEFAULT_SECURITY="apparmor"
-   and CONFIG_SECURITY_APPARMOR_BOOTPARAM_VALUE=1
-
-Build the kernel
-
-If AppArmor is not the default security module it can be enabled by passing
-security=apparmor on the kernel's command line.
-
-If AppArmor is the default security module it can be disabled by passing
-apparmor=0, security=XXXX (where XXX is valid security module), on the
-kernel's command line
-
-For AppArmor to enforce any restrictions beyond standard Linux DAC permissions
-policy must be loaded into the kernel from user space (see the Documentation
-and tools links).
-
---- Documentation ---
-
-Documentation can be found on the wiki.
-
---- Links ---
-
-Mailing List - apparmor@lists.ubuntu.com
-Wiki - http://apparmor.wiki.kernel.org/
-User space tools - https://launchpad.net/apparmor
-Kernel module - git://git.kernel.org/pub/scm/linux/kernel/git/jj/apparmor-dev.git
diff -druN linux-2.6.39-libre/Documentation/arm/Booting linux-3.0-rc7-libre/Documentation/arm/Booting
--- linux-2.6.39-libre/Documentation/arm/Booting	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/Documentation/arm/Booting	2011-07-11 19:51:52.000000000 -0400
@@ -65,13 +65,19 @@
 The boot loader must ultimately be able to provide a MACH_TYPE_xxx
 value to the kernel. (see linux/arch/arm/tools/mach-types).
 
-
-4. Setup the kernel tagged list
--------------------------------
+4. Setup boot data
+------------------
 
 Existing boot loaders:		OPTIONAL, HIGHLY RECOMMENDED
 New boot loaders:		MANDATORY
 
+The boot loader must provide either a tagged list or a dtb image for
+passing configuration data to the kernel.  The physical address of the
+boot data is passed to the kernel in register r2.
+
+4a. Setup the kernel tagged list
+--------------------------------
+
 The boot loader must create and initialise the kernel tagged list.
 A valid tagged list starts with ATAG_CORE and ends with ATAG_NONE.
 The ATAG_CORE tag may or may not be empty.  An empty ATAG_CORE tag
@@ -101,6 +107,24 @@
 the kernel decompressor nor initrd 'bootp' program will overwrite
 it.  The recommended placement is in the first 16KiB of RAM.
 
+4b. Setup the device tree
+-------------------------
+
+The boot loader must load a device tree image (dtb) into system ram
+at a 64bit aligned address and initialize it with the boot data.  The
+dtb format is documented in Documentation/devicetree/booting-without-of.txt.
+The kernel will look for the dtb magic value of 0xd00dfeed at the dtb
+physical address to determine if a dtb has been passed instead of a
+tagged list.
+
+The boot loader must pass at a minimum the size and location of the
+system memory, and the root filesystem location.  The dtb must be
+placed in a region of memory where the kernel decompressor will not
+overwrite it.  The recommended placement is in the first 16KiB of RAM
+with the caveat that it may not be located at physical address 0 since
+the kernel interprets a value of 0 in r2 to mean neither a tagged list
+nor a dtb were passed.
+
 5. Calling the kernel image
 ---------------------------
 
@@ -125,7 +149,8 @@
 - CPU register settings
   r0 = 0,
   r1 = machine type number discovered in (3) above.
-  r2 = physical address of tagged list in system RAM.
+  r2 = physical address of tagged list in system RAM, or
+       physical address of device tree block (dtb) in system RAM
 
 - CPU mode
   All forms of interrupts must be disabled (IRQs and FIQs)
diff -druN linux-2.6.39-libre/Documentation/arm/Samsung/Overview.txt linux-3.0-rc7-libre/Documentation/arm/Samsung/Overview.txt
--- linux-2.6.39-libre/Documentation/arm/Samsung/Overview.txt	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/Documentation/arm/Samsung/Overview.txt	2011-07-11 19:51:52.000000000 -0400
@@ -14,7 +14,6 @@
   - S3C24XX: See Documentation/arm/Samsung-S3C24XX/Overview.txt for full list
   - S3C64XX: S3C6400 and S3C6410
   - S5P6440
-  - S5P6442
   - S5PC100
   - S5PC110 / S5PV210
 
@@ -36,7 +35,6 @@
   unifying all the SoCs into one kernel.
 
   s5p6440_defconfig - S5P6440 specific default configuration
-  s5p6442_defconfig - S5P6442 specific default configuration
   s5pc100_defconfig - S5PC100 specific default configuration
   s5pc110_defconfig - S5PC110 specific default configuration
   s5pv210_defconfig - S5PV210 specific default configuration
diff -druN linux-2.6.39-libre/Documentation/atomic_ops.txt linux-3.0-rc7-libre/Documentation/atomic_ops.txt
--- linux-2.6.39-libre/Documentation/atomic_ops.txt	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/Documentation/atomic_ops.txt	2011-07-11 19:51:52.000000000 -0400
@@ -12,7 +12,7 @@
 C integer type will fail.  Something like the following should
 suffice:
 
-	typedef struct { volatile int counter; } atomic_t;
+	typedef struct { int counter; } atomic_t;
 
 Historically, counter has been declared volatile.  This is now discouraged.
 See Documentation/volatile-considered-harmful.txt for the complete rationale.
diff -druN linux-2.6.39-libre/Documentation/blockdev/cciss.txt linux-3.0-rc7-libre/Documentation/blockdev/cciss.txt
--- linux-2.6.39-libre/Documentation/blockdev/cciss.txt	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/Documentation/blockdev/cciss.txt	2011-07-11 19:51:52.000000000 -0400
@@ -169,3 +169,18 @@
 must rewind the tape (by issuing "mt -f /dev/st0 rewind" for example)
 before i/o can proceed again to a tape drive which was reset.
 
+There is a cciss_tape_cmds module parameter which can be used to make cciss
+allocate more commands for use by tape drives.  Ordinarily only a few commands
+(6) are allocated for tape drives because tape drives are slow and
+infrequently used and the primary purpose of Smart Array controllers is to
+act as a RAID controller for disk drives, so the vast majority of commands
+are allocated for disk devices.  However, if you have more than a few tape
+drives attached to a smart array, the default number of commands may not be
+enought (for example, if you have 8 tape drives, you could only rewind 6
+at one time with the default number of commands.)  The cciss_tape_cmds module
+parameter allows more commands (up to 16 more) to be allocated for use by
+tape drives.  For example:
+
+        insmod cciss.ko cciss_tape_cmds=16
+
+Or, as a kernel boot parameter passed in via grub:  cciss.cciss_tape_cmds=8
diff -druN linux-2.6.39-libre/Documentation/cachetlb.txt linux-3.0-rc7-libre/Documentation/cachetlb.txt
--- linux-2.6.39-libre/Documentation/cachetlb.txt	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/Documentation/cachetlb.txt	2011-07-11 19:51:52.000000000 -0400
@@ -16,7 +16,7 @@
 thinking SMP cache/tlb flushing must be so inefficient, this is in
 fact an area where many optimizations are possible.  For example,
 if it can be proven that a user address space has never executed
-on a cpu (see vma->cpu_vm_mask), one need not perform a flush
+on a cpu (see mm_cpumask()), one need not perform a flush
 for this address space on that cpu.
 
 First, the TLB flushing interfaces, since they are the simplest.  The
diff -druN linux-2.6.39-libre/Documentation/cgroups/blkio-controller.txt linux-3.0-rc7-libre/Documentation/cgroups/blkio-controller.txt
--- linux-2.6.39-libre/Documentation/cgroups/blkio-controller.txt	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/Documentation/cgroups/blkio-controller.txt	2011-07-11 19:51:52.000000000 -0400
@@ -28,16 +28,19 @@
 - Enable group scheduling in CFQ
 	CONFIG_CFQ_GROUP_IOSCHED=y
 
-- Compile and boot into kernel and mount IO controller (blkio).
+- Compile and boot into kernel and mount IO controller (blkio); see
+  cgroups.txt, Why are cgroups needed?.
 
-	mount -t cgroup -o blkio none /cgroup
+	mount -t tmpfs cgroup_root /sys/fs/cgroup
+	mkdir /sys/fs/cgroup/blkio
+	mount -t cgroup -o blkio none /sys/fs/cgroup/blkio
 
 - Create two cgroups
-	mkdir -p /cgroup/test1/ /cgroup/test2
+	mkdir -p /sys/fs/cgroup/blkio/test1/ /sys/fs/cgroup/blkio/test2
 
 - Set weights of group test1 and test2
-	echo 1000 > /cgroup/test1/blkio.weight
-	echo 500 > /cgroup/test2/blkio.weight
+	echo 1000 > /sys/fs/cgroup/blkio/test1/blkio.weight
+	echo 500 > /sys/fs/cgroup/blkio/test2/blkio.weight
 
 - Create two same size files (say 512MB each) on same disk (file1, file2) and
   launch two dd threads in different cgroup to read those files.
@@ -46,12 +49,12 @@
 	echo 3 > /proc/sys/vm/drop_caches
 
 	dd if=/mnt/sdb/zerofile1 of=/dev/null &
-	echo $! > /cgroup/test1/tasks
-	cat /cgroup/test1/tasks
+	echo $! > /sys/fs/cgroup/blkio/test1/tasks
+	cat /sys/fs/cgroup/blkio/test1/tasks
 
 	dd if=/mnt/sdb/zerofile2 of=/dev/null &
-	echo $! > /cgroup/test2/tasks
-	cat /cgroup/test2/tasks
+	echo $! > /sys/fs/cgroup/blkio/test2/tasks
+	cat /sys/fs/cgroup/blkio/test2/tasks
 
 - At macro level, first dd should finish first. To get more precise data, keep
   on looking at (with the help of script), at blkio.disk_time and
@@ -68,13 +71,13 @@
 - Enable throttling in block layer
 	CONFIG_BLK_DEV_THROTTLING=y
 
-- Mount blkio controller
-        mount -t cgroup -o blkio none /cgroup/blkio
+- Mount blkio controller (see cgroups.txt, Why are cgroups needed?)
+        mount -t cgroup -o blkio none /sys/fs/cgroup/blkio
 
 - Specify a bandwidth rate on particular device for root group. The format
   for policy is "<major>:<minor>  <byes_per_second>".
 
-        echo "8:16  1048576" > /cgroup/blkio/blkio.read_bps_device
+        echo "8:16  1048576" > /sys/fs/cgroup/blkio/blkio.throttle.read_bps_device
 
   Above will put a limit of 1MB/second on reads happening for root group
   on device having major/minor number 8:16.
@@ -87,7 +90,7 @@
         1024+0 records out
         4194304 bytes (4.2 MB) copied, 4.0001 s, 1.0 MB/s
 
- Limits for writes can be put using blkio.write_bps_device file.
+ Limits for writes can be put using blkio.throttle.write_bps_device file.
 
 Hierarchical Cgroups
 ====================
@@ -108,7 +111,7 @@
   CFQ and throttling will practically treat all groups at same level.
 
 				pivot
-			     /  |   \  \
+			     /  /   \  \
 			root  test1 test2  test3
 
   Down the line we can implement hierarchical accounting/control support
@@ -149,7 +152,7 @@
 
 	  Following is the format.
 
-	  #echo dev_maj:dev_minor weight > /path/to/cgroup/blkio.weight_device
+	  # echo dev_maj:dev_minor weight > blkio.weight_device
 	  Configure weight=300 on /dev/sdb (8:16) in this cgroup
 	  # echo 8:16 300 > blkio.weight_device
 	  # cat blkio.weight_device
@@ -283,28 +286,28 @@
 	  specified in bytes per second. Rules are per deivce. Following is
 	  the format.
 
-  echo "<major>:<minor>  <rate_bytes_per_second>" > /cgrp/blkio.read_bps_device
+  echo "<major>:<minor>  <rate_bytes_per_second>" > /cgrp/blkio.throttle.read_bps_device
 
 - blkio.throttle.write_bps_device
 	- Specifies upper limit on WRITE rate to the device. IO rate is
 	  specified in bytes per second. Rules are per deivce. Following is
 	  the format.
 
-  echo "<major>:<minor>  <rate_bytes_per_second>" > /cgrp/blkio.write_bps_device
+  echo "<major>:<minor>  <rate_bytes_per_second>" > /cgrp/blkio.throttle.write_bps_device
 
 - blkio.throttle.read_iops_device
 	- Specifies upper limit on READ rate from the device. IO rate is
 	  specified in IO per second. Rules are per deivce. Following is
 	  the format.
 
-  echo "<major>:<minor>  <rate_io_per_second>" > /cgrp/blkio.read_iops_device
+  echo "<major>:<minor>  <rate_io_per_second>" > /cgrp/blkio.throttle.read_iops_device
 
 - blkio.throttle.write_iops_device
 	- Specifies upper limit on WRITE rate to the device. IO rate is
 	  specified in io per second. Rules are per deivce. Following is
 	  the format.
 
-  echo "<major>:<minor>  <rate_io_per_second>" > /cgrp/blkio.write_iops_device
+  echo "<major>:<minor>  <rate_io_per_second>" > /cgrp/blkio.throttle.write_iops_device
 
 Note: If both BW and IOPS rules are specified for a device, then IO is
       subjectd to both the constraints.
diff -druN linux-2.6.39-libre/Documentation/cgroups/cgroups.txt linux-3.0-rc7-libre/Documentation/cgroups/cgroups.txt
--- linux-2.6.39-libre/Documentation/cgroups/cgroups.txt	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/Documentation/cgroups/cgroups.txt	2011-07-11 19:51:52.000000000 -0400
@@ -138,11 +138,11 @@
 the admin can easily set up a script which receives exec notifications
 and depending on who is launching the browser he can
 
-       # echo browser_pid > /mnt/<restype>/<userclass>/tasks
+    # echo browser_pid > /sys/fs/cgroup/<restype>/<userclass>/tasks
 
 With only a single hierarchy, he now would potentially have to create
 a separate cgroup for every browser launched and associate it with
-approp network and other resource class.  This may lead to
+appropriate network and other resource class.  This may lead to
 proliferation of such cgroups.
 
 Also lets say that the administrator would like to give enhanced network
@@ -153,9 +153,9 @@
 With ability to write pids directly to resource classes, it's just a
 matter of :
 
-       # echo pid > /mnt/network/<new_class>/tasks
+       # echo pid > /sys/fs/cgroup/network/<new_class>/tasks
        (after some time)
-       # echo pid > /mnt/network/<orig_class>/tasks
+       # echo pid > /sys/fs/cgroup/network/<orig_class>/tasks
 
 Without this ability, he would have to split the cgroup into
 multiple separate ones and then associate the new cgroups with the
@@ -236,7 +236,8 @@
  - 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.
-   This is a read-only file, for now.
+   Writing a thread group id into this file moves all threads in that
+   group into this cgroup.
  - 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)
@@ -309,21 +310,24 @@
 To start a new job that is to be contained within a cgroup, using
 the "cpuset" cgroup subsystem, the steps are something like:
 
- 1) mkdir /dev/cgroup
- 2) mount -t cgroup -ocpuset cpuset /dev/cgroup
- 3) Create the new cgroup by doing mkdir's and write's (or echo's) in
-    the /dev/cgroup virtual file system.
- 4) Start a task that will be the "founding father" of the new job.
- 5) Attach that task to the new cgroup by writing its pid to the
-    /dev/cgroup tasks file for that cgroup.
- 6) fork, exec or clone the job tasks from this founding father task.
+ 1) mount -t tmpfs cgroup_root /sys/fs/cgroup
+ 2) mkdir /sys/fs/cgroup/cpuset
+ 3) mount -t cgroup -ocpuset cpuset /sys/fs/cgroup/cpuset
+ 4) Create the new cgroup by doing mkdir's and write's (or echo's) in
+    the /sys/fs/cgroup virtual file system.
+ 5) Start a task that will be the "founding father" of the new job.
+ 6) Attach that task to the new cgroup by writing its pid to the
+    /sys/fs/cgroup/cpuset/tasks file for that cgroup.
+ 7) fork, exec or clone the job tasks from this founding father task.
 
 For example, the following sequence of commands will setup a cgroup
 named "Charlie", containing just CPUs 2 and 3, and Memory Node 1,
 and then start a subshell 'sh' in that cgroup:
 
-  mount -t cgroup cpuset -ocpuset /dev/cgroup
-  cd /dev/cgroup
+  mount -t tmpfs cgroup_root /sys/fs/cgroup
+  mkdir /sys/fs/cgroup/cpuset
+  mount -t cgroup cpuset -ocpuset /sys/fs/cgroup/cpuset
+  cd /sys/fs/cgroup/cpuset
   mkdir Charlie
   cd Charlie
   /bin/echo 2-3 > cpuset.cpus
@@ -344,7 +348,7 @@
 virtual filesystem.
 
 To mount a cgroup hierarchy with all available subsystems, type:
-# mount -t cgroup xxx /dev/cgroup
+# mount -t cgroup xxx /sys/fs/cgroup
 
 The "xxx" is not interpreted by the cgroup code, but will appear in
 /proc/mounts so may be any useful identifying string that you like.
@@ -353,23 +357,32 @@
 if cpusets are enabled the user will have to populate the cpus and mems files
 for each new cgroup created before that group can be used.
 
+As explained in section `1.2 Why are cgroups needed?' you should create
+different hierarchies of cgroups for each single resource or group of
+resources you want to control. Therefore, you should mount a tmpfs on
+/sys/fs/cgroup and create directories for each cgroup resource or resource
+group.
+
+# mount -t tmpfs cgroup_root /sys/fs/cgroup
+# mkdir /sys/fs/cgroup/rg1
+
 To mount a cgroup hierarchy with just the cpuset and memory
 subsystems, type:
-# mount -t cgroup -o cpuset,memory hier1 /dev/cgroup
+# mount -t cgroup -o cpuset,memory hier1 /sys/fs/cgroup/rg1
 
 To change the set of subsystems bound to a mounted hierarchy, just
 remount with different options:
-# mount -o remount,cpuset,blkio hier1 /dev/cgroup
+# mount -o remount,cpuset,blkio hier1 /sys/fs/cgroup/rg1
 
 Now memory is removed from the hierarchy and blkio is added.
 
 Note this will add blkio to the hierarchy but won't remove memory or
 cpuset, because the new options are appended to the old ones:
-# mount -o remount,blkio /dev/cgroup
+# mount -o remount,blkio /sys/fs/cgroup/rg1
 
 To Specify a hierarchy's release_agent:
 # mount -t cgroup -o cpuset,release_agent="/sbin/cpuset_release_agent" \
-  xxx /dev/cgroup
+  xxx /sys/fs/cgroup/rg1
 
 Note that specifying 'release_agent' more than once will return failure.
 
@@ -378,17 +391,17 @@
 the ability to arbitrarily bind/unbind subsystems from an existing
 cgroup hierarchy is intended to be implemented in the future.
 
-Then under /dev/cgroup you can find a tree that corresponds to the
-tree of the cgroups in the system. For instance, /dev/cgroup
+Then under /sys/fs/cgroup/rg1 you can find a tree that corresponds to the
+tree of the cgroups in the system. For instance, /sys/fs/cgroup/rg1
 is the cgroup that holds the whole system.
 
 If you want to change the value of release_agent:
-# echo "/sbin/new_release_agent" > /dev/cgroup/release_agent
+# echo "/sbin/new_release_agent" > /sys/fs/cgroup/rg1/release_agent
 
 It can also be changed via remount.
 
-If you want to create a new cgroup under /dev/cgroup:
-# cd /dev/cgroup
+If you want to create a new cgroup under /sys/fs/cgroup/rg1:
+# cd /sys/fs/cgroup/rg1
 # mkdir my_cgroup
 
 Now you want to do something with this cgroup.
@@ -430,6 +443,12 @@
 
 # echo 0 > tasks
 
+You can use the cgroup.procs file instead of the tasks file to move all
+threads in a threadgroup at once. Echoing the pid of any task in a
+threadgroup to cgroup.procs causes all tasks in that threadgroup to be
+be attached to the cgroup. Writing 0 to cgroup.procs moves all tasks
+in the writing task's threadgroup.
+
 Note: Since every task is always a member of exactly one cgroup in each
 mounted hierarchy, to remove a task from its current cgroup you must
 move it into a new cgroup (possibly the root cgroup) by writing to the
@@ -575,7 +594,7 @@
 called multiple times against a cgroup.
 
 int can_attach(struct cgroup_subsys *ss, struct cgroup *cgrp,
-	       struct task_struct *task, bool threadgroup)
+	       struct task_struct *task)
 (cgroup_mutex held by caller)
 
 Called prior to moving a task into a cgroup; if the subsystem
@@ -584,9 +603,14 @@
 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 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.
+attach() or cancel_attach() will be called in future.
+
+int can_attach_task(struct cgroup *cgrp, struct task_struct *tsk);
+(cgroup_mutex held by caller)
+
+As can_attach, but for operations that must be run once per task to be
+attached (possibly many when using cgroup_attach_proc). Called after
+can_attach.
 
 void cancel_attach(struct cgroup_subsys *ss, struct cgroup *cgrp,
 	       struct task_struct *task, bool threadgroup)
@@ -598,15 +622,24 @@
 This will be called only about subsystems whose can_attach() operation have
 succeeded.
 
+void pre_attach(struct cgroup *cgrp);
+(cgroup_mutex held by caller)
+
+For any non-per-thread attachment work that needs to happen before
+attach_task. Needed by cpuset.
+
 void attach(struct cgroup_subsys *ss, struct cgroup *cgrp,
-	    struct cgroup *old_cgrp, struct task_struct *task,
-	    bool threadgroup)
+	    struct cgroup *old_cgrp, struct task_struct *task)
 (cgroup_mutex held by caller)
 
 Called after the task has been attached to the cgroup, to allow any
 post-attachment activity that requires memory allocations or blocking.
-If threadgroup is true, the subsystem should take care of all threads
-in the specified thread's threadgroup. Currently does not support any
+
+void attach_task(struct cgroup *cgrp, struct task_struct *tsk);
+(cgroup_mutex held by caller)
+
+As attach, but for operations that must be run once per task to be attached,
+like can_attach_task. Called before attach. Currently does not support any
 subsystem that might need the old_cgrp for every thread in the group.
 
 void fork(struct cgroup_subsy *ss, struct task_struct *task)
@@ -630,7 +663,7 @@
 void post_clone(struct cgroup_subsys *ss, struct cgroup *cgrp)
 (cgroup_mutex held by caller)
 
-Called at the end of cgroup_clone() to do any parameter
+Called during cgroup_create() to do any parameter
 initialization which might be required before a task could attach.  For
 example in cpusets, no task may attach before 'cpus' and 'mems' are set
 up.
diff -druN linux-2.6.39-libre/Documentation/cgroups/cpuacct.txt linux-3.0-rc7-libre/Documentation/cgroups/cpuacct.txt
--- linux-2.6.39-libre/Documentation/cgroups/cpuacct.txt	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/Documentation/cgroups/cpuacct.txt	2011-07-11 19:51:52.000000000 -0400
@@ -10,26 +10,25 @@
 
 Accounting groups can be created by first mounting the cgroup filesystem.
 
-# mkdir /cgroups
-# mount -t cgroup -ocpuacct none /cgroups
+# mount -t cgroup -ocpuacct none /sys/fs/cgroup
 
-With the above step, the initial or the parent accounting group
-becomes visible at /cgroups. At bootup, this group includes all the
-tasks in the system. /cgroups/tasks lists the tasks in this cgroup.
-/cgroups/cpuacct.usage gives the CPU time (in nanoseconds) obtained by
-this group which is essentially the CPU time obtained by all the tasks
+With the above step, the initial or the parent accounting group becomes
+visible at /sys/fs/cgroup. At bootup, this group includes all the tasks in
+the system. /sys/fs/cgroup/tasks lists the tasks in this cgroup.
+/sys/fs/cgroup/cpuacct.usage gives the CPU time (in nanoseconds) obtained
+by this group which is essentially the CPU time obtained by all the tasks
 in the system.
 
-New accounting groups can be created under the parent group /cgroups.
+New accounting groups can be created under the parent group /sys/fs/cgroup.
 
-# cd /cgroups
+# cd /sys/fs/cgroup
 # mkdir g1
 # echo $$ > g1
 
 The above steps create a new group g1 and move the current shell
 process (bash) into it. CPU time consumed by this bash and its children
 can be obtained from g1/cpuacct.usage and the same is accumulated in
-/cgroups/cpuacct.usage also.
+/sys/fs/cgroup/cpuacct.usage also.
 
 cpuacct.stat file lists a few statistics which further divide the
 CPU time obtained by the cgroup into user and system times. Currently
diff -druN linux-2.6.39-libre/Documentation/cgroups/cpusets.txt linux-3.0-rc7-libre/Documentation/cgroups/cpusets.txt
--- linux-2.6.39-libre/Documentation/cgroups/cpusets.txt	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/Documentation/cgroups/cpusets.txt	2011-07-11 19:51:52.000000000 -0400
@@ -661,21 +661,21 @@
 
 To start a new job that is to be contained within a cpuset, the steps are:
 
- 1) mkdir /dev/cpuset
- 2) mount -t cgroup -ocpuset cpuset /dev/cpuset
+ 1) mkdir /sys/fs/cgroup/cpuset
+ 2) mount -t cgroup -ocpuset cpuset /sys/fs/cgroup/cpuset
  3) Create the new cpuset by doing mkdir's and write's (or echo's) in
-    the /dev/cpuset virtual file system.
+    the /sys/fs/cgroup/cpuset virtual file system.
  4) Start a task that will be the "founding father" of the new job.
  5) Attach that task to the new cpuset by writing its pid to the
-    /dev/cpuset tasks file for that cpuset.
+    /sys/fs/cgroup/cpuset tasks file for that cpuset.
  6) fork, exec or clone the job tasks from this founding father task.
 
 For example, the following sequence of commands will setup a cpuset
 named "Charlie", containing just CPUs 2 and 3, and Memory Node 1,
 and then start a subshell 'sh' in that cpuset:
 
-  mount -t cgroup -ocpuset cpuset /dev/cpuset
-  cd /dev/cpuset
+  mount -t cgroup -ocpuset cpuset /sys/fs/cgroup/cpuset
+  cd /sys/fs/cgroup/cpuset
   mkdir Charlie
   cd Charlie
   /bin/echo 2-3 > cpuset.cpus
@@ -710,14 +710,14 @@
 virtual filesystem.
 
 To mount it, type:
-# mount -t cgroup -o cpuset cpuset /dev/cpuset
+# mount -t cgroup -o cpuset cpuset /sys/fs/cgroup/cpuset
 
-Then under /dev/cpuset you can find a tree that corresponds to the
-tree of the cpusets in the system. For instance, /dev/cpuset
+Then under /sys/fs/cgroup/cpuset you can find a tree that corresponds to the
+tree of the cpusets in the system. For instance, /sys/fs/cgroup/cpuset
 is the cpuset that holds the whole system.
 
-If you want to create a new cpuset under /dev/cpuset:
-# cd /dev/cpuset
+If you want to create a new cpuset under /sys/fs/cgroup/cpuset:
+# cd /sys/fs/cgroup/cpuset
 # mkdir my_cpuset
 
 Now you want to do something with this cpuset.
@@ -765,12 +765,12 @@
 
 The command
 
-mount -t cpuset X /dev/cpuset
+mount -t cpuset X /sys/fs/cgroup/cpuset
 
 is equivalent to
 
-mount -t cgroup -ocpuset,noprefix X /dev/cpuset
-echo "/sbin/cpuset_release_agent" > /dev/cpuset/release_agent
+mount -t cgroup -ocpuset,noprefix X /sys/fs/cgroup/cpuset
+echo "/sbin/cpuset_release_agent" > /sys/fs/cgroup/cpuset/release_agent
 
 2.2 Adding/removing cpus
 ------------------------
diff -druN linux-2.6.39-libre/Documentation/cgroups/devices.txt linux-3.0-rc7-libre/Documentation/cgroups/devices.txt
--- linux-2.6.39-libre/Documentation/cgroups/devices.txt	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/Documentation/cgroups/devices.txt	2011-07-11 19:51:52.000000000 -0400
@@ -22,16 +22,16 @@
 An entry is added using devices.allow, and removed using
 devices.deny.  For instance
 
-	echo 'c 1:3 mr' > /cgroups/1/devices.allow
+	echo 'c 1:3 mr' > /sys/fs/cgroup/1/devices.allow
 
 allows cgroup 1 to read and mknod the device usually known as
 /dev/null.  Doing
 
-	echo a > /cgroups/1/devices.deny
+	echo a > /sys/fs/cgroup/1/devices.deny
 
 will remove the default 'a *:* rwm' entry. Doing
 
-	echo a > /cgroups/1/devices.allow
+	echo a > /sys/fs/cgroup/1/devices.allow
 
 will add the 'a *:* rwm' entry to the whitelist.
 
diff -druN linux-2.6.39-libre/Documentation/cgroups/freezer-subsystem.txt linux-3.0-rc7-libre/Documentation/cgroups/freezer-subsystem.txt
--- linux-2.6.39-libre/Documentation/cgroups/freezer-subsystem.txt	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/Documentation/cgroups/freezer-subsystem.txt	2011-07-11 19:51:52.000000000 -0400
@@ -59,28 +59,28 @@
 
 * Examples of usage :
 
-   # mkdir /containers
-   # mount -t cgroup -ofreezer freezer  /containers
-   # mkdir /containers/0
-   # echo $some_pid > /containers/0/tasks
+   # mkdir /sys/fs/cgroup/freezer
+   # mount -t cgroup -ofreezer freezer /sys/fs/cgroup/freezer
+   # mkdir /sys/fs/cgroup/freezer/0
+   # echo $some_pid > /sys/fs/cgroup/freezer/0/tasks
 
 to get status of the freezer subsystem :
 
-   # cat /containers/0/freezer.state
+   # cat /sys/fs/cgroup/freezer/0/freezer.state
    THAWED
 
 to freeze all tasks in the container :
 
-   # echo FROZEN > /containers/0/freezer.state
-   # cat /containers/0/freezer.state
+   # echo FROZEN > /sys/fs/cgroup/freezer/0/freezer.state
+   # cat /sys/fs/cgroup/freezer/0/freezer.state
    FREEZING
-   # cat /containers/0/freezer.state
+   # cat /sys/fs/cgroup/freezer/0/freezer.state
    FROZEN
 
 to unfreeze all tasks in the container :
 
-   # echo THAWED > /containers/0/freezer.state
-   # cat /containers/0/freezer.state
+   # echo THAWED > /sys/fs/cgroup/freezer/0/freezer.state
+   # cat /sys/fs/cgroup/freezer/0/freezer.state
    THAWED
 
 This is the basic mechanism which should do the right thing for user space task
diff -druN linux-2.6.39-libre/Documentation/cgroups/memory.txt linux-3.0-rc7-libre/Documentation/cgroups/memory.txt
--- linux-2.6.39-libre/Documentation/cgroups/memory.txt	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/Documentation/cgroups/memory.txt	2011-07-11 19:51:52.000000000 -0400
@@ -1,8 +1,8 @@
 Memory Resource Controller
 
-NOTE: The Memory Resource Controller has been generically been referred
-      to as the memory controller in this document. Do not confuse memory
-      controller used here with the memory controller that is used in hardware.
+NOTE: The Memory Resource Controller has generically been referred to as the
+      memory controller in this document. Do not confuse memory controller
+      used here with the memory controller that is used in hardware.
 
 (For editors)
 In this document:
@@ -70,6 +70,7 @@
 				 (See sysctl's vm.swappiness)
  memory.move_charge_at_immigrate # set/show controls of moving charges
  memory.oom_control		 # set/show oom controls.
+ memory.numa_stat		 # show the number of memory usage per numa node
 
 1. History
 
@@ -181,7 +182,7 @@
 page will eventually get charged for it (once it is uncharged from
 the cgroup that brought it in -- this will happen on memory pressure).
 
-Exception: If CONFIG_CGROUP_CGROUP_MEM_RES_CTLR_SWAP is not used..
+Exception: If CONFIG_CGROUP_CGROUP_MEM_RES_CTLR_SWAP is not used.
 When you do swapoff and make swapped-out pages of shmem(tmpfs) to
 be backed into memory in force, charges for pages are accounted against the
 caller of swapoff rather than the users of shmem.
@@ -213,7 +214,7 @@
 OS point of view.
 
 * What happens when a cgroup hits memory.memsw.limit_in_bytes
-When a cgroup his memory.memsw.limit_in_bytes, it's useless to do swap-out
+When a cgroup hits memory.memsw.limit_in_bytes, it's useless to do swap-out
 in this cgroup. Then, swap-out will not be done by cgroup routine and file
 caches are dropped. But as mentioned above, global LRU can do swapout memory
 from it for sanity of the system's memory management state. You can't forbid
@@ -263,16 +264,17 @@
 c. Enable CONFIG_CGROUP_MEM_RES_CTLR
 d. Enable CONFIG_CGROUP_MEM_RES_CTLR_SWAP (to use swap extension)
 
-1. Prepare the cgroups
-# mkdir -p /cgroups
-# mount -t cgroup none /cgroups -o memory
+1. Prepare the cgroups (see cgroups.txt, Why are cgroups needed?)
+# mount -t tmpfs none /sys/fs/cgroup
+# mkdir /sys/fs/cgroup/memory
+# mount -t cgroup none /sys/fs/cgroup/memory -o memory
 
 2. Make the new group and move bash into it
-# mkdir /cgroups/0
-# echo $$ > /cgroups/0/tasks
+# mkdir /sys/fs/cgroup/memory/0
+# echo $$ > /sys/fs/cgroup/memory/0/tasks
 
 Since now we're in the 0 cgroup, we can alter the memory limit:
-# echo 4M > /cgroups/0/memory.limit_in_bytes
+# echo 4M > /sys/fs/cgroup/memory/0/memory.limit_in_bytes
 
 NOTE: We can use a suffix (k, K, m, M, g or G) to indicate values in kilo,
 mega or gigabytes. (Here, Kilo, Mega, Giga are Kibibytes, Mebibytes, Gibibytes.)
@@ -280,11 +282,11 @@
 NOTE: We can write "-1" to reset the *.limit_in_bytes(unlimited).
 NOTE: We cannot set limits on the root cgroup any more.
 
-# cat /cgroups/0/memory.limit_in_bytes
+# cat /sys/fs/cgroup/memory/0/memory.limit_in_bytes
 4194304
 
 We can check the usage:
-# cat /cgroups/0/memory.usage_in_bytes
+# cat /sys/fs/cgroup/memory/0/memory.usage_in_bytes
 1216512
 
 A successful write to this file does not guarantee a successful set of
@@ -464,6 +466,24 @@
 If you want to know more exact memory usage, you should use RSS+CACHE(+SWAP)
 value in memory.stat(see 5.2).
 
+5.6 numa_stat
+
+This is similar to numa_maps but operates on a per-memcg basis.  This is
+useful for providing visibility into the numa locality information within
+an memcg since the pages are allowed to be allocated from any physical
+node.  One of the usecases is evaluating application performance by
+combining this information with the application's cpu allocation.
+
+We export "total", "file", "anon" and "unevictable" pages per-node for
+each memcg.  The ouput format of memory.numa_stat is:
+
+total=<total pages> N0=<node 0 pages> N1=<node 1 pages> ...
+file=<total file pages> N0=<node 0 pages> N1=<node 1 pages> ...
+anon=<total anon pages> N0=<node 0 pages> N1=<node 1 pages> ...
+unevictable=<total anon pages> N0=<node 0 pages> N1=<node 1 pages> ...
+
+And we have total = file + anon + unevictable.
+
 6. Hierarchy support
 
 The memory controller supports a deep hierarchy and hierarchical accounting.
@@ -471,13 +491,13 @@
 cgroup filesystem. Consider for example, the following cgroup filesystem
 hierarchy
 
-		root
+	       root
 	     /  |   \
-           /	|    \
-	  a	b	c
-			| \
-			|  \
-			d   e
+            /	|    \
+	   a	b     c
+		      | \
+		      |  \
+		      d   e
 
 In the diagram above, with hierarchical accounting enabled, all memory
 usage of e, is accounted to its ancestors up until the root (i.e, c and root),
diff -druN linux-2.6.39-libre/Documentation/Changes linux-3.0-rc7-libre/Documentation/Changes
--- linux-2.6.39-libre/Documentation/Changes	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/Documentation/Changes	2011-07-11 19:51:52.000000000 -0400
@@ -2,13 +2,7 @@
 =====
 
 This document is designed to provide a list of the minimum levels of
-software necessary to run the 2.6 kernels, as well as provide brief
-instructions regarding any other "Gotchas" users may encounter when
-trying life on the Bleeding Edge.  If upgrading from a pre-2.4.x
-kernel, please consult the Changes file included with 2.4.x kernels for
-additional information; most of that information will not be repeated
-here.  Basically, this document assumes that your system is already
-functional and running at least 2.4.x kernels.
+software necessary to run the 3.0 kernels.
 
 This document is originally based on my "Changes" file for 2.0.x kernels
 and therefore owes credit to the same people as that file (Jared Mauch,
@@ -22,11 +16,10 @@
 encountered a bug!  If you're unsure what version you're currently
 running, the suggested command should tell you.
 
-Again, keep in mind that this list assumes you are already
-functionally running a Linux 2.4 kernel.  Also, not all tools are
-necessary on all systems; obviously, if you don't have any ISDN
-hardware, for example, you probably needn't concern yourself with
-isdn4k-utils.
+Again, keep in mind that this list assumes you are already functionally
+running a Linux kernel.  Also, not all tools are necessary on all
+systems; obviously, if you don't have any ISDN hardware, for example,
+you probably needn't concern yourself with isdn4k-utils.
 
 o  Gnu C                  3.2                     # gcc --version
 o  Gnu make               3.80                    # make --version
@@ -114,12 +107,12 @@
 
 If the unthinkable happens and your kernel oopses, you may need the
 ksymoops tool to decode it, but in most cases you don't.
-In the 2.6 kernel it is generally preferred to build the kernel with
-CONFIG_KALLSYMS so that it produces readable dumps that can be used as-is
-(this also produces better output than ksymoops).
-If for some reason your kernel is not build with CONFIG_KALLSYMS and
-you have no way to rebuild and reproduce the Oops with that option, then
-you can still decode that Oops with ksymoops.
+It is generally preferred to build the kernel with CONFIG_KALLSYMS so
+that it produces readable dumps that can be used as-is (this also
+produces better output than ksymoops).  If for some reason your kernel
+is not build with CONFIG_KALLSYMS and you have no way to rebuild and
+reproduce the Oops with that option, then you can still decode that Oops
+with ksymoops.
 
 Module-Init-Tools
 -----------------
@@ -261,8 +254,8 @@
 NFS-utils
 ---------
 
-In 2.4 and earlier kernels, the nfs server needed to know about any
-client that expected to be able to access files via NFS.  This
+In ancient (2.4 and earlier) kernels, the nfs server needed to know
+about any client that expected to be able to access files via NFS.  This
 information would be given to the kernel by "mountd" when the client
 mounted the filesystem, or by "exportfs" at system startup.  exportfs
 would take information about active clients from /var/lib/nfs/rmtab.
@@ -272,11 +265,11 @@
 fail-over.  Even when the system is working well, rmtab suffers from
 getting lots of old entries that never get removed.
 
-With 2.6 we have the option of having the kernel tell mountd when it
-gets a request from an unknown host, and mountd can give appropriate
-export information to the kernel.  This removes the dependency on
-rmtab and means that the kernel only needs to know about currently
-active clients.
+With modern kernels we have the option of having the kernel tell mountd
+when it gets a request from an unknown host, and mountd can give
+appropriate export information to the kernel.  This removes the
+dependency on rmtab and means that the kernel only needs to know about
+currently active clients.
 
 To enable this new functionality, you need to:
 
diff -druN linux-2.6.39-libre/Documentation/CodingStyle linux-3.0-rc7-libre/Documentation/CodingStyle
--- linux-2.6.39-libre/Documentation/CodingStyle	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/Documentation/CodingStyle	2011-07-11 19:51:52.000000000 -0400
@@ -680,8 +680,8 @@
 		Chapter 14: Allocating memory
 
 The kernel provides the following general purpose memory allocators:
-kmalloc(), kzalloc(), kcalloc(), and vmalloc().  Please refer to the API
-documentation for further information about them.
+kmalloc(), kzalloc(), kcalloc(), vmalloc(), and vzalloc().  Please refer to
+the API documentation for further information about them.
 
 The preferred form for passing a size of a struct is the following:
 
diff -druN linux-2.6.39-libre/Documentation/credentials.txt linux-3.0-rc7-libre/Documentation/credentials.txt
--- linux-2.6.39-libre/Documentation/credentials.txt	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/Documentation/credentials.txt	1969-12-31 19:00:00.000000000 -0500
@@ -1,581 +0,0 @@
-			     ====================
-			     CREDENTIALS IN LINUX
-			     ====================
-
-By: David Howells <dhowells@redhat.com>
-
-Contents:
-
- (*) Overview.
-
- (*) Types of credentials.
-
- (*) File markings.
-
- (*) Task credentials.
-
-     - Immutable credentials.
-     - Accessing task credentials.
-     - Accessing another task's credentials.
-     - Altering credentials.
-     - Managing credentials.
-
- (*) Open file credentials.
-
- (*) Overriding the VFS's use of credentials.
-
-
-========
-OVERVIEW
-========
-
-There are several parts to the security check performed by Linux when one
-object acts upon another:
-
- (1) Objects.
-
-     Objects are things in the system that may be acted upon directly by
-     userspace programs.  Linux has a variety of actionable objects, including:
-
-	- Tasks
-	- Files/inodes
-	- Sockets
-	- Message queues
-	- Shared memory segments
-	- Semaphores
-	- Keys
-
-     As a part of the description of all these objects there is a set of
-     credentials.  What's in the set depends on the type of object.
-
- (2) Object ownership.
-
-     Amongst the credentials of most objects, there will be a subset that
-     indicates the ownership of that object.  This is used for resource
-     accounting and limitation (disk quotas and task rlimits for example).
-
-     In a standard UNIX filesystem, for instance, this will be defined by the
-     UID marked on the inode.
-
- (3) The objective context.
-
-     Also amongst the credentials of those objects, there will be a subset that
-     indicates the 'objective context' of that object.  This may or may not be
-     the same set as in (2) - in standard UNIX files, for instance, this is the
-     defined by the UID and the GID marked on the inode.
-
-     The objective context is used as part of the security calculation that is
-     carried out when an object is acted upon.
-
- (4) Subjects.
-
-     A subject is an object that is acting upon another object.
-
-     Most of the objects in the system are inactive: they don't act on other
-     objects within the system.  Processes/tasks are the obvious exception:
-     they do stuff; they access and manipulate things.
-
-     Objects other than tasks may under some circumstances also be subjects.
-     For instance an open file may send SIGIO to a task using the UID and EUID
-     given to it by a task that called fcntl(F_SETOWN) upon it.  In this case,
-     the file struct will have a subjective context too.
-
- (5) The subjective context.
-
-     A subject has an additional interpretation of its credentials.  A subset
-     of its credentials forms the 'subjective context'.  The subjective context
-     is used as part of the security calculation that is carried out when a
-     subject acts.
-
-     A Linux task, for example, has the FSUID, FSGID and the supplementary
-     group list for when it is acting upon a file - which are quite separate
-     from the real UID and GID that normally form the objective context of the
-     task.
-
- (6) Actions.
-
-     Linux has a number of actions available that a subject may perform upon an
-     object.  The set of actions available depends on the nature of the subject
-     and the object.
-
-     Actions include reading, writing, creating and deleting files; forking or
-     signalling and tracing tasks.
-
- (7) Rules, access control lists and security calculations.
-
-     When a subject acts upon an object, a security calculation is made.  This
-     involves taking the subjective context, the objective context and the
-     action, and searching one or more sets of rules to see whether the subject
-     is granted or denied permission to act in the desired manner on the
-     object, given those contexts.
-
-     There are two main sources of rules:
-
-     (a) Discretionary access control (DAC):
-
-	 Sometimes the object will include sets of rules as part of its
-	 description.  This is an 'Access Control List' or 'ACL'.  A Linux
-	 file may supply more than one ACL.
-
-	 A traditional UNIX file, for example, includes a permissions mask that
-	 is an abbreviated ACL with three fixed classes of subject ('user',
-	 'group' and 'other'), each of which may be granted certain privileges
-	 ('read', 'write' and 'execute' - whatever those map to for the object
-	 in question).  UNIX file permissions do not allow the arbitrary
-	 specification of subjects, however, and so are of limited use.
-
-	 A Linux file might also sport a POSIX ACL.  This is a list of rules
-	 that grants various permissions to arbitrary subjects.
-
-     (b) Mandatory access control (MAC):
-
-	 The system as a whole may have one or more sets of rules that get
-	 applied to all subjects and objects, regardless of their source.
-	 SELinux and Smack are examples of this.
-
-	 In the case of SELinux and Smack, each object is given a label as part
-	 of its credentials.  When an action is requested, they take the
-	 subject label, the object label and the action and look for a rule
-	 that says that this action is either granted or denied.
-
-
-====================
-TYPES OF CREDENTIALS
-====================
-
-The Linux kernel supports the following types of credentials:
-
- (1) Traditional UNIX credentials.
-
-	Real User ID
-	Real Group ID
-
-     The UID and GID are carried by most, if not all, Linux objects, even if in
-     some cases it has to be invented (FAT or CIFS files for example, which are
-     derived from Windows).  These (mostly) define the objective context of
-     that object, with tasks being slightly different in some cases.
-
-	Effective, Saved and FS User ID
-	Effective, Saved and FS Group ID
-	Supplementary groups
-
-     These are additional credentials used by tasks only.  Usually, an
-     EUID/EGID/GROUPS will be used as the subjective context, and real UID/GID
-     will be used as the objective.  For tasks, it should be noted that this is
-     not always true.
-
- (2) Capabilities.
-
-	Set of permitted capabilities
-	Set of inheritable capabilities
-	Set of effective capabilities
-	Capability bounding set
-
-     These are only carried by tasks.  They indicate superior capabilities
-     granted piecemeal to a task that an ordinary task wouldn't otherwise have.
-     These are manipulated implicitly by changes to the traditional UNIX
-     credentials, but can also be manipulated directly by the capset() system
-     call.
-
-     The permitted capabilities are those caps that the process might grant
-     itself to its effective or permitted sets through capset().  This
-     inheritable set might also be so constrained.
-
-     The effective capabilities are the ones that a task is actually allowed to
-     make use of itself.
-
-     The inheritable capabilities are the ones that may get passed across
-     execve().
-
-     The bounding set limits the capabilities that may be inherited across
-     execve(), especially when a binary is executed that will execute as UID 0.
-
- (3) Secure management flags (securebits).
-
-     These are only carried by tasks.  These govern the way the above
-     credentials are manipulated and inherited over certain operations such as
-     execve().  They aren't used directly as objective or subjective
-     credentials.
-
- (4) Keys and keyrings.
-
-     These are only carried by tasks.  They carry and cache security tokens
-     that don't fit into the other standard UNIX credentials.  They are for
-     making such things as network filesystem keys available to the file
-     accesses performed by processes, without the necessity of ordinary
-     programs having to know about security details involved.
-
-     Keyrings are a special type of key.  They carry sets of other keys and can
-     be searched for the desired key.  Each process may subscribe to a number
-     of keyrings:
-
-	Per-thread keying
-	Per-process keyring
-	Per-session keyring
-
-     When a process accesses a key, if not already present, it will normally be
-     cached on one of these keyrings for future accesses to find.
-
-     For more information on using keys, see Documentation/keys.txt.
-
- (5) LSM
-
-     The Linux Security Module allows extra controls to be placed over the
-     operations that a task may do.  Currently Linux supports two main
-     alternate LSM options: SELinux and Smack.
-
-     Both work by labelling the objects in a system and then applying sets of
-     rules (policies) that say what operations a task with one label may do to
-     an object with another label.
-
- (6) AF_KEY
-
-     This is a socket-based approach to credential management for networking
-     stacks [RFC 2367].  It isn't discussed by this document as it doesn't
-     interact directly with task and file credentials; rather it keeps system
-     level credentials.
-
-
-When a file is opened, part of the opening task's subjective context is
-recorded in the file struct created.  This allows operations using that file
-struct to use those credentials instead of the subjective context of the task
-that issued the operation.  An example of this would be a file opened on a
-network filesystem where the credentials of the opened file should be presented
-to the server, regardless of who is actually doing a read or a write upon it.
-
-
-=============
-FILE MARKINGS
-=============
-
-Files on disk or obtained over the network may have annotations that form the
-objective security context of that file.  Depending on the type of filesystem,
-this may include one or more of the following:
-
- (*) UNIX UID, GID, mode;
-
- (*) Windows user ID;
-
- (*) Access control list;
-
- (*) LSM security label;
-
- (*) UNIX exec privilege escalation bits (SUID/SGID);
-
- (*) File capabilities exec privilege escalation bits.
-
-These are compared to the task's subjective security context, and certain
-operations allowed or disallowed as a result.  In the case of execve(), the
-privilege escalation bits come into play, and may allow the resulting process
-extra privileges, based on the annotations on the executable file.
-
-
-================
-TASK CREDENTIALS
-================
-
-In Linux, all of a task's credentials are held in (uid, gid) or through
-(groups, keys, LSM security) a refcounted structure of type 'struct cred'.
-Each task points to its credentials by a pointer called 'cred' in its
-task_struct.
-
-Once a set of credentials has been prepared and committed, it may not be
-changed, barring the following exceptions:
-
- (1) its reference count may be changed;
-
- (2) the reference count on the group_info struct it points to may be changed;
-
- (3) the reference count on the security data it points to may be changed;
-
- (4) the reference count on any keyrings it points to may be changed;
-
- (5) any keyrings it points to may be revoked, expired or have their security
-     attributes changed; and
-
- (6) the contents of any keyrings to which it points may be changed (the whole
-     point of keyrings being a shared set of credentials, modifiable by anyone
-     with appropriate access).
-
-To alter anything in the cred struct, the copy-and-replace principle must be
-adhered to.  First take a copy, then alter the copy and then use RCU to change
-the task pointer to make it point to the new copy.  There are wrappers to aid
-with this (see below).
-
-A task may only alter its _own_ credentials; it is no longer permitted for a
-task to alter another's credentials.  This means the capset() system call is no
-longer permitted to take any PID other than the one of the current process.
-Also keyctl_instantiate() and keyctl_negate() functions no longer permit
-attachment to process-specific keyrings in the requesting process as the
-instantiating process may need to create them.
-
-
-IMMUTABLE CREDENTIALS
----------------------
-
-Once a set of credentials has been made public (by calling commit_creds() for
-example), it must be considered immutable, barring two exceptions:
-
- (1) The reference count may be altered.
-
- (2) Whilst the keyring subscriptions of a set of credentials may not be
-     changed, the keyrings subscribed to may have their contents altered.
-
-To catch accidental credential alteration at compile time, struct task_struct
-has _const_ pointers to its credential sets, as does struct file.  Furthermore,
-certain functions such as get_cred() and put_cred() operate on const pointers,
-thus rendering casts unnecessary, but require to temporarily ditch the const
-qualification to be able to alter the reference count.
-
-
-ACCESSING TASK CREDENTIALS
---------------------------
-
-A task being able to alter only its own credentials permits the current process
-to read or replace its own credentials without the need for any form of locking
-- which simplifies things greatly.  It can just call:
-
-	const struct cred *current_cred()
-
-to get a pointer to its credentials structure, and it doesn't have to release
-it afterwards.
-
-There are convenience wrappers for retrieving specific aspects of a task's
-credentials (the value is simply returned in each case):
-
-	uid_t current_uid(void)		Current's real UID
-	gid_t current_gid(void)		Current's real GID
-	uid_t current_euid(void)	Current's effective UID
-	gid_t current_egid(void)	Current's effective GID
-	uid_t current_fsuid(void)	Current's file access UID
-	gid_t current_fsgid(void)	Current's file access GID
-	kernel_cap_t current_cap(void)	Current's effective capabilities
-	void *current_security(void)	Current's LSM security pointer
-	struct user_struct *current_user(void)  Current's user account
-
-There are also convenience wrappers for retrieving specific associated pairs of
-a task's credentials:
-
-	void current_uid_gid(uid_t *, gid_t *);
-	void current_euid_egid(uid_t *, gid_t *);
-	void current_fsuid_fsgid(uid_t *, gid_t *);
-
-which return these pairs of values through their arguments after retrieving
-them from the current task's credentials.
-
-
-In addition, there is a function for obtaining a reference on the current
-process's current set of credentials:
-
-	const struct cred *get_current_cred(void);
-
-and functions for getting references to one of the credentials that don't
-actually live in struct cred:
-
-	struct user_struct *get_current_user(void);
-	struct group_info *get_current_groups(void);
-
-which get references to the current process's user accounting structure and
-supplementary groups list respectively.
-
-Once a reference has been obtained, it must be released with put_cred(),
-free_uid() or put_group_info() as appropriate.
-
-
-ACCESSING ANOTHER TASK'S CREDENTIALS
-------------------------------------
-
-Whilst a task may access its own credentials without the need for locking, the
-same is not true of a task wanting to access another task's credentials.  It
-must use the RCU read lock and rcu_dereference().
-
-The rcu_dereference() is wrapped by:
-
-	const struct cred *__task_cred(struct task_struct *task);
-
-This should be used inside the RCU read lock, as in the following example:
-
-	void foo(struct task_struct *t, struct foo_data *f)
-	{
-		const struct cred *tcred;
-		...
-		rcu_read_lock();
-		tcred = __task_cred(t);
-		f->uid = tcred->uid;
-		f->gid = tcred->gid;
-		f->groups = get_group_info(tcred->groups);
-		rcu_read_unlock();
-		...
-	}
-
-Should it be necessary to hold another task's credentials for a long period of
-time, and possibly to sleep whilst doing so, then the caller should get a
-reference on them using:
-
-	const struct cred *get_task_cred(struct task_struct *task);
-
-This does all the RCU magic inside of it.  The caller must call put_cred() on
-the credentials so obtained when they're finished with.
-
- [*] Note: The result of __task_cred() should not be passed directly to
-     get_cred() as this may race with commit_cred().
-
-There are a couple of convenience functions to access bits of another task's
-credentials, hiding the RCU magic from the caller:
-
-	uid_t task_uid(task)		Task's real UID
-	uid_t task_euid(task)		Task's effective UID
-
-If the caller is holding the RCU read lock at the time anyway, then:
-
-	__task_cred(task)->uid
-	__task_cred(task)->euid
-
-should be used instead.  Similarly, if multiple aspects of a task's credentials
-need to be accessed, RCU read lock should be used, __task_cred() called, the
-result stored in a temporary pointer and then the credential aspects called
-from that before dropping the lock.  This prevents the potentially expensive
-RCU magic from being invoked multiple times.
-
-Should some other single aspect of another task's credentials need to be
-accessed, then this can be used:
-
-	task_cred_xxx(task, member)
-
-where 'member' is a non-pointer member of the cred struct.  For instance:
-
-	uid_t task_cred_xxx(task, suid);
-
-will retrieve 'struct cred::suid' from the task, doing the appropriate RCU
-magic.  This may not be used for pointer members as what they point to may
-disappear the moment the RCU read lock is dropped.
-
-
-ALTERING CREDENTIALS
---------------------
-
-As previously mentioned, a task may only alter its own credentials, and may not
-alter those of another task.  This means that it doesn't need to use any
-locking to alter its own credentials.
-
-To alter the current process's credentials, a function should first prepare a
-new set of credentials by calling:
-
-	struct cred *prepare_creds(void);
-
-this locks current->cred_replace_mutex and then allocates and constructs a
-duplicate of the current process's credentials, returning with the mutex still
-held if successful.  It returns NULL if not successful (out of memory).
-
-The mutex prevents ptrace() from altering the ptrace state of a process whilst
-security checks on credentials construction and changing is taking place as
-the ptrace state may alter the outcome, particularly in the case of execve().
-
-The new credentials set should be altered appropriately, and any security
-checks and hooks done.  Both the current and the proposed sets of credentials
-are available for this purpose as current_cred() will return the current set
-still at this point.
-
-
-When the credential set is ready, it should be committed to the current process
-by calling:
-
-	int commit_creds(struct cred *new);
-
-This will alter various aspects of the credentials and the process, giving the
-LSM a chance to do likewise, then it will use rcu_assign_pointer() to actually
-commit the new credentials to current->cred, it will release
-current->cred_replace_mutex to allow ptrace() to take place, and it will notify
-the scheduler and others of the changes.
-
-This function is guaranteed to return 0, so that it can be tail-called at the
-end of such functions as sys_setresuid().
-
-Note that this function consumes the caller's reference to the new credentials.
-The caller should _not_ call put_cred() on the new credentials afterwards.
-
-Furthermore, once this function has been called on a new set of credentials,
-those credentials may _not_ be changed further.
-
-
-Should the security checks fail or some other error occur after prepare_creds()
-has been called, then the following function should be invoked:
-
-	void abort_creds(struct cred *new);
-
-This releases the lock on current->cred_replace_mutex that prepare_creds() got
-and then releases the new credentials.
-
-
-A typical credentials alteration function would look something like this:
-
-	int alter_suid(uid_t suid)
-	{
-		struct cred *new;
-		int ret;
-
-		new = prepare_creds();
-		if (!new)
-			return -ENOMEM;
-
-		new->suid = suid;
-		ret = security_alter_suid(new);
-		if (ret < 0) {
-			abort_creds(new);
-			return ret;
-		}
-
-		return commit_creds(new);
-	}
-
-
-MANAGING CREDENTIALS
---------------------
-
-There are some functions to help manage credentials:
-
- (*) void put_cred(const struct cred *cred);
-
-     This releases a reference to the given set of credentials.  If the
-     reference count reaches zero, the credentials will be scheduled for
-     destruction by the RCU system.
-
- (*) const struct cred *get_cred(const struct cred *cred);
-
-     This gets a reference on a live set of credentials, returning a pointer to
-     that set of credentials.
-
- (*) struct cred *get_new_cred(struct cred *cred);
-
-     This gets a reference on a set of credentials that is under construction
-     and is thus still mutable, returning a pointer to that set of credentials.
-
-
-=====================
-OPEN FILE CREDENTIALS
-=====================
-
-When a new file is opened, a reference is obtained on the opening task's
-credentials and this is attached to the file struct as 'f_cred' in place of
-'f_uid' and 'f_gid'.  Code that used to access file->f_uid and file->f_gid
-should now access file->f_cred->fsuid and file->f_cred->fsgid.
-
-It is safe to access f_cred without the use of RCU or locking because the
-pointer will not change over the lifetime of the file struct, and nor will the
-contents of the cred struct pointed to, barring the exceptions listed above
-(see the Task Credentials section).
-
-
-=======================================
-OVERRIDING THE VFS'S USE OF CREDENTIALS
-=======================================
-
-Under some circumstances it is desirable to override the credentials used by
-the VFS, and that can be done by calling into such as vfs_mkdir() with a
-different set of credentials.  This is done in the following places:
-
- (*) sys_faccessat().
-
- (*) do_coredump().
-
- (*) nfs4recover.c.
diff -druN linux-2.6.39-libre/Documentation/devicetree/bindings/crypto/fsl-sec4.txt linux-3.0-rc7-libre/Documentation/devicetree/bindings/crypto/fsl-sec4.txt
--- linux-2.6.39-libre/Documentation/devicetree/bindings/crypto/fsl-sec4.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/Documentation/devicetree/bindings/crypto/fsl-sec4.txt	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,397 @@
+=====================================================================
+SEC 4 Device Tree Binding
+Copyright (C) 2008-2011 Freescale Semiconductor Inc.
+
+ CONTENTS
+   -Overview
+   -SEC 4 Node
+   -Job Ring Node
+   -Run Time Integrity Check (RTIC) Node
+   -Run Time Integrity Check (RTIC) Memory Node
+   -Secure Non-Volatile Storage (SNVS) Node
+   -Full Example
+
+NOTE: the SEC 4 is also known as Freescale's Cryptographic Accelerator
+Accelerator and Assurance Module (CAAM).
+
+=====================================================================
+Overview
+
+DESCRIPTION
+
+SEC 4 h/w can process requests from 2 types of sources.
+1. DPAA Queue Interface (HW interface between Queue Manager & SEC 4).
+2. Job Rings (HW interface between cores & SEC 4 registers).
+
+High Speed Data Path Configuration:
+
+HW interface between QM & SEC 4 and also BM & SEC 4, on DPAA-enabled parts
+such as the P4080.  The number of simultaneous dequeues the QI can make is
+equal to the number of Descriptor Controller (DECO) engines in a particular
+SEC version.  E.g., the SEC 4.0 in the P4080 has 5 DECOs and can thus
+dequeue from 5 subportals simultaneously.
+
+Job Ring Data Path Configuration:
+
+Each JR is located on a separate 4k page, they may (or may not) be made visible
+in the memory partition devoted to a particular core.  The P4080 has 4 JRs, so
+up to 4 JRs can be configured; and all 4 JRs process requests in parallel.
+
+=====================================================================
+SEC 4 Node
+
+Description
+
+    Node defines the base address of the SEC 4 block.
+    This block specifies the address range of all global
+    configuration registers for the SEC 4 block.  It
+    also receives interrupts from the Run Time Integrity Check
+    (RTIC) function within the SEC 4 block.
+
+PROPERTIES
+
+   - compatible
+      Usage: required
+      Value type: <string>
+      Definition: Must include "fsl,sec-v4.0"
+
+   - #address-cells
+       Usage: required
+       Value type: <u32>
+       Definition: A standard property.  Defines the number of cells
+           for representing physical addresses in child nodes.
+
+   - #size-cells
+       Usage: required
+       Value type: <u32>
+       Definition: A standard property.  Defines the number of cells
+           for representing the size of physical addresses in
+           child nodes.
+
+   - reg
+      Usage: required
+      Value type: <prop-encoded-array>
+      Definition: A standard property.  Specifies the physical
+          address and length of the SEC4 configuration registers.
+          registers
+
+   - ranges
+       Usage: required
+       Value type: <prop-encoded-array>
+       Definition: A standard property.  Specifies the physical address
+           range of the SEC 4.0 register space (-SNVS not included).  A
+           triplet that includes the child address, parent address, &
+           length.
+
+   - interrupts
+      Usage: required
+      Value type: <prop_encoded-array>
+      Definition:  Specifies the interrupts generated by this
+           device.  The value of the interrupts property
+           consists of one interrupt specifier. The format
+           of the specifier is defined by the binding document
+           describing the node's interrupt parent.
+
+   - interrupt-parent
+      Usage: (required if interrupt property is defined)
+      Value type: <phandle>
+      Definition: A single <phandle> value that points
+          to the interrupt parent to which the child domain
+          is being mapped.
+
+   Note: All other standard properties (see the ePAPR) are allowed
+   but are optional.
+
+
+EXAMPLE
+	crypto@300000 {
+		compatible = "fsl,sec-v4.0";
+		#address-cells = <1>;
+		#size-cells = <1>;
+		reg = <0x300000 0x10000>;
+		ranges = <0 0x300000 0x10000>;
+		interrupt-parent = <&mpic>;
+		interrupts = <92 2>;
+	};
+
+=====================================================================
+Job Ring (JR) Node
+
+    Child of the crypto node defines data processing interface to SEC 4
+    across the peripheral bus for purposes of processing
+    cryptographic descriptors. The specified address
+    range can be made visible to one (or more) cores.
+    The interrupt defined for this node is controlled within
+    the address range of this node.
+
+  - compatible
+      Usage: required
+      Value type: <string>
+      Definition: Must include "fsl,sec-v4.0-job-ring"
+
+  - reg
+      Usage: required
+      Value type: <prop-encoded-array>
+      Definition: Specifies a two JR parameters:  an offset from
+          the parent physical address and the length the JR registers.
+
+   - fsl,liodn
+       Usage: optional-but-recommended
+       Value type: <prop-encoded-array>
+       Definition:
+           Specifies the LIODN to be used in conjunction with
+           the ppid-to-liodn table that specifies the PPID to LIODN mapping.
+           Needed if the PAMU is used.  Value is a 12 bit value
+           where value is a LIODN ID for this JR. This property is
+           normally set by boot firmware.
+
+   - interrupts
+      Usage: required
+      Value type: <prop_encoded-array>
+      Definition:  Specifies the interrupts generated by this
+           device.  The value of the interrupts property
+           consists of one interrupt specifier. The format
+           of the specifier is defined by the binding document
+           describing the node's interrupt parent.
+
+   - interrupt-parent
+      Usage: (required if interrupt property is defined)
+      Value type: <phandle>
+      Definition: A single <phandle> value that points
+          to the interrupt parent to which the child domain
+          is being mapped.
+
+EXAMPLE
+	jr@1000 {
+		compatible = "fsl,sec-v4.0-job-ring";
+		reg = <0x1000 0x1000>;
+		fsl,liodn = <0x081>;
+		interrupt-parent = <&mpic>;
+		interrupts = <88 2>;
+	};
+
+
+=====================================================================
+Run Time Integrity Check (RTIC) Node
+
+  Child node of the crypto node.  Defines a register space that
+  contains up to 5 sets of addresses and their lengths (sizes) that
+  will be checked at run time.  After an initial hash result is
+  calculated, these addresses are checked by HW to monitor any
+  change.  If any memory is modified, a Security Violation is
+  triggered (see SNVS definition).
+
+
+  - compatible
+      Usage: required
+      Value type: <string>
+      Definition: Must include "fsl,sec-v4.0-rtic".
+
+   - #address-cells
+       Usage: required
+       Value type: <u32>
+       Definition: A standard property.  Defines the number of cells
+           for representing physical addresses in child nodes.  Must
+           have a value of 1.
+
+   - #size-cells
+       Usage: required
+       Value type: <u32>
+       Definition: A standard property.  Defines the number of cells
+           for representing the size of physical addresses in
+           child nodes.  Must have a value of 1.
+
+  - reg
+      Usage: required
+      Value type: <prop-encoded-array>
+      Definition: A standard property.  Specifies a two parameters:
+          an offset from the parent physical address and the length
+          the SEC4 registers.
+
+   - ranges
+       Usage: required
+       Value type: <prop-encoded-array>
+       Definition: A standard property.  Specifies the physical address
+           range of the SEC 4 register space (-SNVS not included).  A
+           triplet that includes the child address, parent address, &
+           length.
+
+EXAMPLE
+	rtic@6000 {
+		compatible = "fsl,sec-v4.0-rtic";
+		#address-cells = <1>;
+		#size-cells = <1>;
+		reg = <0x6000 0x100>;
+		ranges = <0x0 0x6100 0xe00>;
+	};
+
+=====================================================================
+Run Time Integrity Check (RTIC) Memory Node
+  A child node that defines individual RTIC memory regions that are used to
+  perform run-time integrity check of memory areas that should not modified.
+  The node defines a register that contains the memory address &
+  length (combined) and a second register that contains the hash result
+  in big endian format.
+
+  - compatible
+      Usage: required
+      Value type: <string>
+      Definition: Must include "fsl,sec-v4.0-rtic-memory".
+
+  - reg
+      Usage: required
+      Value type: <prop-encoded-array>
+      Definition: A standard property.  Specifies two parameters:
+          an offset from the parent physical address and the length:
+
+          1. The location of the RTIC memory address & length registers.
+          2. The location RTIC hash result.
+
+  - fsl,rtic-region
+       Usage: optional-but-recommended
+       Value type: <prop-encoded-array>
+       Definition:
+           Specifies the HW address (36 bit address) for this region
+           followed by the length of the HW partition to be checked;
+           the address is represented as a 64 bit quantity followed
+           by a 32 bit length.
+
+   - fsl,liodn
+       Usage: optional-but-recommended
+       Value type: <prop-encoded-array>
+       Definition:
+           Specifies the LIODN to be used in conjunction with
+           the ppid-to-liodn table that specifies the PPID to LIODN
+           mapping.  Needed if the PAMU is used.  Value is a 12 bit value
+           where value is a LIODN ID for this RTIC memory region. This
+           property is normally set by boot firmware.
+
+EXAMPLE
+	rtic-a@0 {
+		compatible = "fsl,sec-v4.0-rtic-memory";
+		reg = <0x00 0x20 0x100 0x80>;
+		fsl,liodn   = <0x03c>;
+		fsl,rtic-region  = <0x12345678 0x12345678 0x12345678>;
+	};
+
+=====================================================================
+Secure Non-Volatile Storage (SNVS) Node
+
+    Node defines address range and the associated
+    interrupt for the SNVS function.  This function
+    monitors security state information & reports
+    security violations.
+
+  - compatible
+      Usage: required
+      Value type: <string>
+      Definition: Must include "fsl,sec-v4.0-mon".
+
+  - reg
+      Usage: required
+      Value type: <prop-encoded-array>
+      Definition: A standard property.  Specifies the physical
+          address and length of the SEC4 configuration
+          registers.
+
+   - interrupts
+      Usage: required
+      Value type: <prop_encoded-array>
+      Definition:  Specifies the interrupts generated by this
+           device.  The value of the interrupts property
+           consists of one interrupt specifier. The format
+           of the specifier is defined by the binding document
+           describing the node's interrupt parent.
+
+   - interrupt-parent
+      Usage: (required if interrupt property is defined)
+      Value type: <phandle>
+      Definition: A single <phandle> value that points
+          to the interrupt parent to which the child domain
+          is being mapped.
+
+EXAMPLE
+	sec_mon@314000 {
+		compatible = "fsl,sec-v4.0-mon";
+		reg = <0x314000 0x1000>;
+		interrupt-parent = <&mpic>;
+		interrupts = <93 2>;
+	};
+
+=====================================================================
+FULL EXAMPLE
+
+	crypto: crypto@300000 {
+		compatible = "fsl,sec-v4.0";
+		#address-cells = <1>;
+		#size-cells = <1>;
+		reg = <0x300000 0x10000>;
+		ranges = <0 0x300000 0x10000>;
+		interrupt-parent = <&mpic>;
+		interrupts = <92 2>;
+
+		sec_jr0: jr@1000 {
+			compatible = "fsl,sec-v4.0-job-ring";
+			reg = <0x1000 0x1000>;
+			interrupt-parent = <&mpic>;
+			interrupts = <88 2>;
+		};
+
+		sec_jr1: jr@2000 {
+			compatible = "fsl,sec-v4.0-job-ring";
+			reg = <0x2000 0x1000>;
+			interrupt-parent = <&mpic>;
+			interrupts = <89 2>;
+		};
+
+		sec_jr2: jr@3000 {
+			compatible = "fsl,sec-v4.0-job-ring";
+			reg = <0x3000 0x1000>;
+			interrupt-parent = <&mpic>;
+			interrupts = <90 2>;
+		};
+
+		sec_jr3: jr@4000 {
+			compatible = "fsl,sec-v4.0-job-ring";
+			reg = <0x4000 0x1000>;
+			interrupt-parent = <&mpic>;
+			interrupts = <91 2>;
+		};
+
+		rtic@6000 {
+			compatible = "fsl,sec-v4.0-rtic";
+			#address-cells = <1>;
+			#size-cells = <1>;
+			reg = <0x6000 0x100>;
+			ranges = <0x0 0x6100 0xe00>;
+
+			rtic_a: rtic-a@0 {
+				compatible = "fsl,sec-v4.0-rtic-memory";
+				reg = <0x00 0x20 0x100 0x80>;
+			};
+
+			rtic_b: rtic-b@20 {
+				compatible = "fsl,sec-v4.0-rtic-memory";
+				reg = <0x20 0x20 0x200 0x80>;
+			};
+
+			rtic_c: rtic-c@40 {
+				compatible = "fsl,sec-v4.0-rtic-memory";
+				reg = <0x40 0x20 0x300 0x80>;
+			};
+
+			rtic_d: rtic-d@60 {
+				compatible = "fsl,sec-v4.0-rtic-memory";
+				reg = <0x60 0x20 0x500 0x80>;
+			};
+		};
+	};
+
+	sec_mon: sec_mon@314000 {
+		compatible = "fsl,sec-v4.0-mon";
+		reg = <0x314000 0x1000>;
+		interrupt-parent = <&mpic>;
+		interrupts = <93 2>;
+	};
+
+=====================================================================
diff -druN linux-2.6.39-libre/Documentation/devicetree/bindings/net/can/fsl-flexcan.txt linux-3.0-rc7-libre/Documentation/devicetree/bindings/net/can/fsl-flexcan.txt
--- linux-2.6.39-libre/Documentation/devicetree/bindings/net/can/fsl-flexcan.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/Documentation/devicetree/bindings/net/can/fsl-flexcan.txt	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,61 @@
+CAN Device Tree Bindings
+------------------------
+2011 Freescale Semiconductor, Inc.
+
+fsl,flexcan-v1.0 nodes
+-----------------------
+In addition to the required compatible-, reg- and interrupt-properties, you can
+also specify which clock source shall be used for the controller.
+
+CPI Clock- Can Protocol Interface Clock
+	This CLK_SRC bit of CTRL(control register) selects the clock source to
+	the CAN Protocol Interface(CPI) to be either the peripheral clock
+	(driven by the PLL) or the crystal oscillator clock. The selected clock
+	is the one fed to the prescaler to generate the Serial Clock (Sclock).
+	The PRESDIV field of CTRL(control register) controls a prescaler that
+	generates the Serial Clock (Sclock), whose period defines the
+	time quantum used to compose the CAN waveform.
+
+Can Engine Clock Source
+	There are two sources for CAN clock
+	- Platform Clock  It represents the bus clock
+	- Oscillator Clock
+
+	Peripheral Clock (PLL)
+	--------------
+		     |
+		    ---------		      -------------
+		    |       |CPI Clock	      | Prescaler |       Sclock
+		    |       |---------------->| (1.. 256) |------------>
+		    ---------		      -------------
+                     |  |
+	--------------  ---------------------CLK_SRC
+	Oscillator Clock
+
+- fsl,flexcan-clock-source : CAN Engine Clock Source.This property selects
+			     the peripheral clock. PLL clock is fed to the
+			     prescaler to generate the Serial Clock (Sclock).
+			     Valid values are "oscillator" and "platform"
+			     "oscillator": CAN engine clock source is oscillator clock.
+			     "platform" The CAN engine clock source is the bus clock
+		             (platform clock).
+
+- fsl,flexcan-clock-divider : for the reference and system clock, an additional
+			      clock divider can be specified.
+- clock-frequency: frequency required to calculate the bitrate for FlexCAN.
+
+Note:
+	- v1.0 of flexcan-v1.0 represent the IP block version for P1010 SOC.
+	- P1010 does not have oscillator as the Clock Source.So the default
+	  Clock Source is platform clock.
+Examples:
+
+	can0@1c000 {
+		compatible = "fsl,flexcan-v1.0";
+		reg = <0x1c000 0x1000>;
+		interrupts = <48 0x2>;
+		interrupt-parent = <&mpic>;
+		fsl,flexcan-clock-source = "platform";
+		fsl,flexcan-clock-divider = <2>;
+		clock-frequency = <fixed by u-boot>;
+	};
diff -druN linux-2.6.39-libre/Documentation/devicetree/bindings/net/fsl-tsec-phy.txt linux-3.0-rc7-libre/Documentation/devicetree/bindings/net/fsl-tsec-phy.txt
--- linux-2.6.39-libre/Documentation/devicetree/bindings/net/fsl-tsec-phy.txt	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/Documentation/devicetree/bindings/net/fsl-tsec-phy.txt	2011-07-11 19:51:52.000000000 -0400
@@ -74,3 +74,57 @@
 		interrupt-parent = <&mpic>;
 		phy-handle = <&phy0>
 	};
+
+* Gianfar PTP clock nodes
+
+General Properties:
+
+  - compatible   Should be "fsl,etsec-ptp"
+  - reg          Offset and length of the register set for the device
+  - interrupts   There should be at least two interrupts. Some devices
+                 have as many as four PTP related interrupts.
+
+Clock Properties:
+
+  - fsl,tclk-period  Timer reference clock period in nanoseconds.
+  - fsl,tmr-prsc     Prescaler, divides the output clock.
+  - fsl,tmr-add      Frequency compensation value.
+  - fsl,tmr-fiper1   Fixed interval period pulse generator.
+  - fsl,tmr-fiper2   Fixed interval period pulse generator.
+  - fsl,max-adj      Maximum frequency adjustment in parts per billion.
+
+  These properties set the operational parameters for the PTP
+  clock. You must choose these carefully for the clock to work right.
+  Here is how to figure good values:
+
+  TimerOsc     = system clock               MHz
+  tclk_period  = desired clock period       nanoseconds
+  NominalFreq  = 1000 / tclk_period         MHz
+  FreqDivRatio = TimerOsc / NominalFreq     (must be greater that 1.0)
+  tmr_add      = ceil(2^32 / FreqDivRatio)
+  OutputClock  = NominalFreq / tmr_prsc     MHz
+  PulseWidth   = 1 / OutputClock            microseconds
+  FiperFreq1   = desired frequency in Hz
+  FiperDiv1    = 1000000 * OutputClock / FiperFreq1
+  tmr_fiper1   = tmr_prsc * tclk_period * FiperDiv1 - tclk_period
+  max_adj      = 1000000000 * (FreqDivRatio - 1.0) - 1
+
+  The calculation for tmr_fiper2 is the same as for tmr_fiper1. The
+  driver expects that tmr_fiper1 will be correctly set to produce a 1
+  Pulse Per Second (PPS) signal, since this will be offered to the PPS
+  subsystem to synchronize the Linux clock.
+
+Example:
+
+	ptp_clock@24E00 {
+		compatible = "fsl,etsec-ptp";
+		reg = <0x24E00 0xB0>;
+		interrupts = <12 0x8 13 0x8>;
+		interrupt-parent = < &ipic >;
+		fsl,tclk-period = <10>;
+		fsl,tmr-prsc    = <100>;
+		fsl,tmr-add     = <0x999999A4>;
+		fsl,tmr-fiper1  = <0x3B9AC9F6>;
+		fsl,tmr-fiper2  = <0x00018696>;
+		fsl,max-adj     = <659999998>;
+	};
diff -druN linux-2.6.39-libre/Documentation/devicetree/bindings/powerpc/fsl/ifc.txt linux-3.0-rc7-libre/Documentation/devicetree/bindings/powerpc/fsl/ifc.txt
--- linux-2.6.39-libre/Documentation/devicetree/bindings/powerpc/fsl/ifc.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/Documentation/devicetree/bindings/powerpc/fsl/ifc.txt	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,76 @@
+Integrated Flash Controller
+
+Properties:
+- name : Should be ifc
+- compatible : should contain "fsl,ifc". The version of the integrated
+               flash controller can be found in the IFC_REV register at
+               offset zero.
+
+- #address-cells : Should be either two or three.  The first cell is the
+                   chipselect number, and the remaining cells are the
+                   offset into the chipselect.
+- #size-cells : Either one or two, depending on how large each chipselect
+                can be.
+- reg : Offset and length of the register set for the device
+- interrupts : IFC has two interrupts. The first one is the "common"
+               interrupt(CM_EVTER_STAT), and second is the NAND interrupt
+               (NAND_EVTER_STAT).
+
+- ranges : Each range corresponds to a single chipselect, and covers
+           the entire access window as configured.
+
+Child device nodes describe the devices connected to IFC such as NOR (e.g.
+cfi-flash) and NAND (fsl,ifc-nand). There might be board specific devices
+like FPGAs, CPLDs, etc.
+
+Example:
+
+	ifc@ffe1e000 {
+		compatible = "fsl,ifc", "simple-bus";
+		#address-cells = <2>;
+		#size-cells = <1>;
+		reg = <0x0 0xffe1e000 0 0x2000>;
+		interrupts = <16 2 19 2>;
+
+		/* NOR, NAND Flashes and CPLD on board */
+		ranges = <0x0 0x0 0x0 0xee000000 0x02000000
+			  0x1 0x0 0x0 0xffa00000 0x00010000
+			  0x3 0x0 0x0 0xffb00000 0x00020000>;
+
+		flash@0,0 {
+			#address-cells = <1>;
+			#size-cells = <1>;
+			compatible = "cfi-flash";
+			reg = <0x0 0x0 0x2000000>;
+			bank-width = <2>;
+			device-width = <1>;
+
+			partition@0 {
+				/* 32MB for user data */
+				reg = <0x0 0x02000000>;
+				label = "NOR Data";
+			};
+		};
+
+		flash@1,0 {
+			#address-cells = <1>;
+			#size-cells = <1>;
+			compatible = "fsl,ifc-nand";
+			reg = <0x1 0x0 0x10000>;
+
+			partition@0 {
+				/* This location must not be altered  */
+				/* 1MB for u-boot Bootloader Image */
+				reg = <0x0 0x00100000>;
+				label = "NAND U-Boot Image";
+				read-only;
+			};
+		};
+
+		cpld@3,0 {
+			#address-cells = <1>;
+			#size-cells = <1>;
+			compatible = "fsl,p1010rdb-cpld";
+			reg = <0x3 0x0 0x000001f>;
+		};
+	};
diff -druN linux-2.6.39-libre/Documentation/devicetree/bindings/powerpc/fsl/mpic-timer.txt linux-3.0-rc7-libre/Documentation/devicetree/bindings/powerpc/fsl/mpic-timer.txt
--- linux-2.6.39-libre/Documentation/devicetree/bindings/powerpc/fsl/mpic-timer.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/Documentation/devicetree/bindings/powerpc/fsl/mpic-timer.txt	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,38 @@
+* Freescale MPIC timers
+
+Required properties:
+- compatible: "fsl,mpic-global-timer"
+
+- reg : Contains two regions.  The first is the main timer register bank
+  (GTCCRxx, GTBCRxx, GTVPRxx, GTDRxx).  The second is the timer control
+  register (TCRx) for the group.
+
+- fsl,available-ranges: use <start count> style section to define which
+  timer interrupts can be used.  This property is optional; without this,
+  all timers within the group can be used.
+
+- interrupts: one interrupt per timer in the group, in order, starting
+  with timer zero.  If timer-available-ranges is present, only the
+  interrupts that correspond to available timers shall be present.
+
+Example:
+	/* Note that this requires #interrupt-cells to be 4 */
+	timer0: timer@41100 {
+		compatible = "fsl,mpic-global-timer";
+		reg = <0x41100 0x100 0x41300 4>;
+
+		/* Another AMP partition is using timers 0 and 1 */
+		fsl,available-ranges = <2 2>;
+
+		interrupts = <2 0 3 0
+		              3 0 3 0>;
+	};
+
+	timer1: timer@42100 {
+		compatible = "fsl,mpic-global-timer";
+		reg = <0x42100 0x100 0x42300 4>;
+		interrupts = <4 0 3 0
+		              5 0 3 0
+		              6 0 3 0
+		              7 0 3 0>;
+	};
diff -druN linux-2.6.39-libre/Documentation/devicetree/bindings/powerpc/fsl/mpic.txt linux-3.0-rc7-libre/Documentation/devicetree/bindings/powerpc/fsl/mpic.txt
--- linux-2.6.39-libre/Documentation/devicetree/bindings/powerpc/fsl/mpic.txt	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/Documentation/devicetree/bindings/powerpc/fsl/mpic.txt	2011-07-11 19:51:52.000000000 -0400
@@ -190,7 +190,7 @@
 	 */
 	timer0: timer@41100 {
 		compatible = "fsl,mpic-global-timer";
-		reg = <0x41100 0x100>;
+		reg = <0x41100 0x100 0x41300 4>;
 		interrupts = <0 0 3 0
 		              1 0 3 0
 		              2 0 3 0
diff -druN linux-2.6.39-libre/Documentation/devicetree/bindings/powerpc/nintendo/wii.txt linux-3.0-rc7-libre/Documentation/devicetree/bindings/powerpc/nintendo/wii.txt
--- linux-2.6.39-libre/Documentation/devicetree/bindings/powerpc/nintendo/wii.txt	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/Documentation/devicetree/bindings/powerpc/nintendo/wii.txt	2011-07-11 19:51:52.000000000 -0400
@@ -127,7 +127,7 @@
    - reg : should contain the SDHCI registers location and length
    - interrupts : should contain the SDHCI interrupt
 
-1.j) The Inter-Processsor Communication (IPC) node
+1.j) The Inter-Processor Communication (IPC) node
 
   Represent the Inter-Processor Communication interface. This interface
   enables communications between the Broadway and the Starlet processors.
diff -druN linux-2.6.39-libre/Documentation/devicetree/booting-without-of.txt linux-3.0-rc7-libre/Documentation/devicetree/booting-without-of.txt
--- linux-2.6.39-libre/Documentation/devicetree/booting-without-of.txt	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/Documentation/devicetree/booting-without-of.txt	2011-07-11 19:51:52.000000000 -0400
@@ -12,8 +12,9 @@
 =================
 
   I - Introduction
-    1) Entry point for arch/powerpc
-    2) Entry point for arch/x86
+    1) Entry point for arch/arm
+    2) Entry point for arch/powerpc
+    3) Entry point for arch/x86
 
   II - The DT block format
     1) Header
@@ -148,7 +149,46 @@
 it with special cases.
 
 
-1) Entry point for arch/powerpc
+1) Entry point for arch/arm
+---------------------------
+
+   There is one single entry point to the kernel, at the start
+   of the kernel image. That entry point supports two calling
+   conventions.  A summary of the interface is described here.  A full
+   description of the boot requirements is documented in
+   Documentation/arm/Booting
+
+        a) ATAGS interface.  Minimal information is passed from firmware
+        to the kernel with a tagged list of predefined parameters.
+
+                r0 : 0
+
+                r1 : Machine type number
+
+                r2 : Physical address of tagged list in system RAM
+
+        b) Entry with a flattened device-tree block.  Firmware loads the
+        physical address of the flattened device tree block (dtb) into r2,
+        r1 is not used, but it is considered good practise to use a valid
+        machine number as described in Documentation/arm/Booting.
+
+                r0 : 0
+
+                r1 : Valid machine type number.  When using a device tree,
+                a single machine type number will often be assigned to
+                represent a class or family of SoCs.
+
+                r2 : physical pointer to the device-tree block
+                (defined in chapter II) in RAM.  Device tree can be located
+                anywhere in system RAM, but it should be aligned on a 64 bit
+                boundary.
+
+   The kernel will differentiate between ATAGS and device tree booting by
+   reading the memory pointed to by r2 and looking for either the flattened
+   device tree block magic value (0xd00dfeed) or the ATAG_CORE value at
+   offset 0x4 from r2 (0x54410001).
+
+2) Entry point for arch/powerpc
 -------------------------------
 
    There is one single entry point to the kernel, at the start
@@ -226,7 +266,7 @@
   cannot support both configurations with Book E and configurations
   with classic Powerpc architectures.
 
-2) Entry point for arch/x86
+3) Entry point for arch/x86
 -------------------------------
 
   There is one single 32bit entry point to the kernel at code32_start,
diff -druN linux-2.6.39-libre/Documentation/dmaengine.txt linux-3.0-rc7-libre/Documentation/dmaengine.txt
--- linux-2.6.39-libre/Documentation/dmaengine.txt	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/Documentation/dmaengine.txt	2011-07-11 19:51:52.000000000 -0400
@@ -1 +1,96 @@
-See Documentation/crypto/async-tx-api.txt
+			DMA Engine API Guide
+			====================
+
+		 Vinod Koul <vinod dot koul at intel.com>
+
+NOTE: For DMA Engine usage in async_tx please see:
+	Documentation/crypto/async-tx-api.txt
+
+
+Below is a guide to device driver writers on how to use the Slave-DMA API of the
+DMA Engine. This is applicable only for slave DMA usage only.
+
+The slave DMA usage consists of following steps
+1. Allocate a DMA slave channel
+2. Set slave and controller specific parameters
+3. Get a descriptor for transaction
+4. Submit the transaction and wait for callback notification
+
+1. Allocate a DMA slave channel
+Channel allocation is slightly different in the slave DMA context, client
+drivers typically need a channel from a particular DMA controller only and even
+in some cases a specific channel is desired. To request a channel
+dma_request_channel() API is used.
+
+Interface:
+struct dma_chan *dma_request_channel(dma_cap_mask_t mask,
+		dma_filter_fn filter_fn,
+		void *filter_param);
+where dma_filter_fn is defined as:
+typedef bool (*dma_filter_fn)(struct dma_chan *chan, void *filter_param);
+
+When the optional 'filter_fn' parameter is set to NULL dma_request_channel
+simply returns the first channel that satisfies the capability mask.  Otherwise,
+when the mask parameter is insufficient for specifying the necessary channel,
+the filter_fn routine can be used to disposition the available channels in the
+system. The filter_fn routine is called once for each free channel in the
+system.  Upon seeing a suitable channel filter_fn returns DMA_ACK which flags
+that channel to be the return value from dma_request_channel.  A channel
+allocated via this interface is exclusive to the caller, until
+dma_release_channel() is called.
+
+2. Set slave and controller specific parameters
+Next step is always to pass some specific information to the DMA driver. Most of
+the generic information which a slave DMA can use is in struct dma_slave_config.
+It allows the clients to specify DMA direction, DMA addresses, bus widths, DMA
+burst lengths etc. If some DMA controllers have more parameters to be sent then
+they should try to embed struct dma_slave_config in their controller specific
+structure. That gives flexibility to client to pass more parameters, if
+required.
+
+Interface:
+int dmaengine_slave_config(struct dma_chan *chan,
+					  struct dma_slave_config *config)
+
+3. Get a descriptor for transaction
+For slave usage the various modes of slave transfers supported by the
+DMA-engine are:
+slave_sg	- DMA a list of scatter gather buffers from/to a peripheral
+dma_cyclic	- Perform a cyclic DMA operation from/to a peripheral till the
+		  operation is explicitly stopped.
+The non NULL return of this transfer API represents a "descriptor" for the given
+transaction.
+
+Interface:
+struct dma_async_tx_descriptor *(*chan->device->device_prep_dma_sg)(
+		struct dma_chan *chan,
+		struct scatterlist *dst_sg, unsigned int dst_nents,
+		struct scatterlist *src_sg, unsigned int src_nents,
+		unsigned long flags);
+struct dma_async_tx_descriptor *(*chan->device->device_prep_dma_cyclic)(
+		struct dma_chan *chan, dma_addr_t buf_addr, size_t buf_len,
+		size_t period_len, enum dma_data_direction direction);
+
+4. Submit the transaction and wait for callback notification
+To schedule the transaction to be scheduled by dma device, the "descriptor"
+returned in above (3) needs to be submitted.
+To tell the dma driver that a transaction is ready to be serviced, the
+descriptor->submit() callback needs to be invoked. This chains the descriptor to
+the pending queue.
+The transactions in the pending queue can be activated by calling the
+issue_pending API. If channel is idle then the first transaction in queue is
+started and subsequent ones queued up.
+On completion of the DMA operation the next in queue is submitted and a tasklet
+triggered. The tasklet would then call the client driver completion callback
+routine for notification, if set.
+Interface:
+void dma_async_issue_pending(struct dma_chan *chan);
+
+==============================================================================
+
+Additional usage notes for dma driver writers
+1/ Although DMA engine specifies that completion callback routines cannot submit
+any new operations, but typically for slave DMA subsequent transaction may not
+be available for submit prior to callback routine being called. This requirement
+is not a requirement for DMA-slave devices. But they should take care to drop
+the spin-lock they might be holding before calling the callback routine
diff -druN linux-2.6.39-libre/Documentation/DocBook/device-drivers.tmpl linux-3.0-rc7-libre/Documentation/DocBook/device-drivers.tmpl
--- linux-2.6.39-libre/Documentation/DocBook/device-drivers.tmpl	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/Documentation/DocBook/device-drivers.tmpl	2011-07-11 19:51:52.000000000 -0400
@@ -96,10 +96,10 @@
 
   <chapter id="devdrivers">
      <title>Device drivers infrastructure</title>
+     <sect1><title>The Basic Device Driver-Model Structures </title>
+!Iinclude/linux/device.h
+     </sect1>
      <sect1><title>Device Drivers Base</title>
-<!--
-X!Iinclude/linux/device.h
--->
 !Edrivers/base/driver.c
 !Edrivers/base/core.c
 !Edrivers/base/class.c
diff -druN linux-2.6.39-libre/Documentation/DocBook/dvb/dvbapi.xml linux-3.0-rc7-libre/Documentation/DocBook/dvb/dvbapi.xml
--- linux-2.6.39-libre/Documentation/DocBook/dvb/dvbapi.xml	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/Documentation/DocBook/dvb/dvbapi.xml	2011-07-11 19:51:52.000000000 -0400
@@ -35,6 +35,14 @@
 <revhistory>
 <!-- Put document revisions here, newest first. -->
 <revision>
+	<revnumber>2.0.4</revnumber>
+	<date>2011-05-06</date>
+	<authorinitials>mcc</authorinitials>
+	<revremark>
+		Add more information about DVB APIv5, better describing the frontend GET/SET props ioctl's.
+	</revremark>
+</revision>
+<revision>
 	<revnumber>2.0.3</revnumber>
 	<date>2010-07-03</date>
 	<authorinitials>mcc</authorinitials>
diff -druN linux-2.6.39-libre/Documentation/DocBook/dvb/dvbproperty.xml linux-3.0-rc7-libre/Documentation/DocBook/dvb/dvbproperty.xml
--- linux-2.6.39-libre/Documentation/DocBook/dvb/dvbproperty.xml	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/Documentation/DocBook/dvb/dvbproperty.xml	2011-07-11 19:51:52.000000000 -0400
@@ -1,6 +1,330 @@
-<section id="FE_GET_PROPERTY">
+<section id="FE_GET_SET_PROPERTY">
 <title>FE_GET_PROPERTY/FE_SET_PROPERTY</title>
 
+<programlisting>
+/* Reserved fields should be set to 0 */
+struct dtv_property {
+	__u32 cmd;
+	union {
+		__u32 data;
+		struct {
+			__u8 data[32];
+			__u32 len;
+			__u32 reserved1[3];
+			void *reserved2;
+		} buffer;
+	} u;
+	int result;
+} __attribute__ ((packed));
+
+/* num of properties cannot exceed DTV_IOCTL_MAX_MSGS per ioctl */
+#define DTV_IOCTL_MAX_MSGS 64
+
+struct dtv_properties {
+	__u32 num;
+	struct dtv_property *props;
+};
+</programlisting>
+
+<section id="FE_GET_PROPERTY">
+<title>FE_GET_PROPERTY</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This ioctl call returns one or more frontend properties. This call only
+ requires read-only access to the device.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int ioctl(int fd, int request = <link linkend="FE_GET_PROPERTY">FE_GET_PROPERTY</link>,
+ dtv_properties &#x22C6;props);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry align="char">
+<para>int fd</para>
+</entry><entry
+ align="char">
+<para>File descriptor returned by a previous call to open().</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>int num</para>
+</entry><entry
+ align="char">
+<para>Equals <link linkend="FE_GET_PROPERTY">FE_GET_PROPERTY</link> for this command.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>struct dtv_property *props</para>
+</entry><entry
+ align="char">
+<para>Points to the location where the front-end property commands are stored.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>ERRORS</para>
+<informaltable><tgroup cols="2"><tbody><row>
+  <entry align="char"><para>EINVAL</para></entry>
+  <entry align="char"><para>Invalid parameter(s) received or number of parameters out of the range.</para></entry>
+ </row><row>
+  <entry align="char"><para>ENOMEM</para></entry>
+  <entry align="char"><para>Out of memory.</para></entry>
+ </row><row>
+  <entry align="char"><para>EFAULT</para></entry>
+  <entry align="char"><para>Failure while copying data from/to userspace.</para></entry>
+ </row><row>
+  <entry align="char"><para>EOPNOTSUPP</para></entry>
+  <entry align="char"><para>Property type not supported.</para></entry>
+ </row></tbody></tgroup></informaltable>
+</section>
+
+<section id="FE_SET_PROPERTY">
+<title>FE_SET_PROPERTY</title>
+<para>DESCRIPTION
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>This ioctl call sets one or more frontend properties. This call only
+ requires read-only access to the device.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>SYNOPSIS
+</para>
+<informaltable><tgroup cols="1"><tbody><row><entry
+ align="char">
+<para>int ioctl(int fd, int request = <link linkend="FE_SET_PROPERTY">FE_SET_PROPERTY</link>,
+ dtv_properties &#x22C6;props);</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>PARAMETERS
+</para>
+<informaltable><tgroup cols="2"><tbody><row><entry align="char">
+<para>int fd</para>
+</entry><entry
+ align="char">
+<para>File descriptor returned by a previous call to open().</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>int num</para>
+</entry><entry
+ align="char">
+<para>Equals <link linkend="FE_SET_PROPERTY">FE_SET_PROPERTY</link> for this command.</para>
+</entry>
+ </row><row><entry
+ align="char">
+<para>struct dtv_property *props</para>
+</entry><entry
+ align="char">
+<para>Points to the location where the front-end property commands are stored.</para>
+</entry>
+ </row></tbody></tgroup></informaltable>
+<para>ERRORS
+</para>
+<informaltable><tgroup cols="2"><tbody><row>
+  <entry align="char"><para>EINVAL</para></entry>
+  <entry align="char"><para>Invalid parameter(s) received or number of parameters out of the range.</para></entry>
+ </row><row>
+  <entry align="char"><para>ENOMEM</para></entry>
+  <entry align="char"><para>Out of memory.</para></entry>
+ </row><row>
+  <entry align="char"><para>EFAULT</para></entry>
+  <entry align="char"><para>Failure while copying data from/to userspace.</para></entry>
+ </row><row>
+  <entry align="char"><para>EOPNOTSUPP</para></entry>
+  <entry align="char"><para>Property type not supported.</para></entry>
+ </row></tbody></tgroup></informaltable>
+</section>
+
+<section>
+	<title>Property types</title>
+<para>
+On <link linkend="FE_GET_PROPERTY">FE_GET_PROPERTY</link>/<link linkend="FE_SET_PROPERTY">FE_SET_PROPERTY</link>,
+the actual action is determined by the dtv_property cmd/data pairs. With one single ioctl, is possible to
+get/set up to 64 properties. The actual meaning of each property is described on the next sections.
+</para>
+
+<para>The available frontend property types are:</para>
+<programlisting>
+#define DTV_UNDEFINED		0
+#define DTV_TUNE		1
+#define DTV_CLEAR		2
+#define DTV_FREQUENCY		3
+#define DTV_MODULATION		4
+#define DTV_BANDWIDTH_HZ	5
+#define DTV_INVERSION		6
+#define DTV_DISEQC_MASTER	7
+#define DTV_SYMBOL_RATE		8
+#define DTV_INNER_FEC		9
+#define DTV_VOLTAGE		10
+#define DTV_TONE		11
+#define DTV_PILOT		12
+#define DTV_ROLLOFF		13
+#define DTV_DISEQC_SLAVE_REPLY	14
+#define DTV_FE_CAPABILITY_COUNT	15
+#define DTV_FE_CAPABILITY	16
+#define DTV_DELIVERY_SYSTEM	17
+#define DTV_ISDBT_PARTIAL_RECEPTION	18
+#define DTV_ISDBT_SOUND_BROADCASTING	19
+#define DTV_ISDBT_SB_SUBCHANNEL_ID	20
+#define DTV_ISDBT_SB_SEGMENT_IDX	21
+#define DTV_ISDBT_SB_SEGMENT_COUNT	22
+#define DTV_ISDBT_LAYERA_FEC			23
+#define DTV_ISDBT_LAYERA_MODULATION		24
+#define DTV_ISDBT_LAYERA_SEGMENT_COUNT		25
+#define DTV_ISDBT_LAYERA_TIME_INTERLEAVING	26
+#define DTV_ISDBT_LAYERB_FEC			27
+#define DTV_ISDBT_LAYERB_MODULATION		28
+#define DTV_ISDBT_LAYERB_SEGMENT_COUNT		29
+#define DTV_ISDBT_LAYERB_TIME_INTERLEAVING	30
+#define DTV_ISDBT_LAYERC_FEC			31
+#define DTV_ISDBT_LAYERC_MODULATION		32
+#define DTV_ISDBT_LAYERC_SEGMENT_COUNT		33
+#define DTV_ISDBT_LAYERC_TIME_INTERLEAVING	34
+#define DTV_API_VERSION		35
+#define DTV_CODE_RATE_HP	36
+#define DTV_CODE_RATE_LP	37
+#define DTV_GUARD_INTERVAL	38
+#define DTV_TRANSMISSION_MODE	39
+#define DTV_HIERARCHY		40
+#define DTV_ISDBT_LAYER_ENABLED	41
+#define DTV_ISDBS_TS_ID		42
+</programlisting>
+</section>
+
+<section id="fe_property_common">
+	<title>Parameters that are common to all Digital TV standards</title>
+	<section id="DTV_FREQUENCY">
+		<title><constant>DTV_FREQUENCY</constant></title>
+
+		<para>Central frequency of the channel, in HZ.</para>
+
+		<para>Notes:</para>
+		<para>1)For ISDB-T, the channels are usually transmitted with an offset of 143kHz.
+			E.g. a valid frequncy could be 474143 kHz. The stepping is bound to the bandwidth of
+			the channel which is 6MHz.</para>
+
+		<para>2)As in ISDB-Tsb the channel consists of only one or three segments the
+			frequency step is 429kHz, 3*429 respectively. As for ISDB-T the
+			central frequency of the channel is expected.</para>
+	</section>
+
+	<section id="DTV_BANDWIDTH_HZ">
+		<title><constant>DTV_BANDWIDTH_HZ</constant></title>
+
+		<para>Bandwidth for the channel, in HZ.</para>
+
+		<para>Possible values:
+			<constant>1712000</constant>,
+			<constant>5000000</constant>,
+			<constant>6000000</constant>,
+			<constant>7000000</constant>,
+			<constant>8000000</constant>,
+			<constant>10000000</constant>.
+		</para>
+
+		<para>Notes:</para>
+
+		<para>1) For ISDB-T it should be always 6000000Hz (6MHz)</para>
+		<para>2) For ISDB-Tsb it can vary depending on the number of connected segments</para>
+		<para>3) Bandwidth doesn't apply for DVB-C transmissions, as the bandwidth
+			 for DVB-C depends on the symbol rate</para>
+		<para>4) Bandwidth in ISDB-T is fixed (6MHz) or can be easily derived from
+			other parameters (DTV_ISDBT_SB_SEGMENT_IDX,
+			DTV_ISDBT_SB_SEGMENT_COUNT).</para>
+		<para>5) DVB-T supports 6, 7 and 8MHz.</para>
+		<para>6) In addition, DVB-T2 supports 1.172, 5 and 10MHz.</para>
+	</section>
+
+	<section id="DTV_DELIVERY_SYSTEM">
+		<title><constant>DTV_DELIVERY_SYSTEM</constant></title>
+
+		<para>Specifies the type of Delivery system</para>
+
+		<para>Possible values: </para>
+<programlisting>
+typedef enum fe_delivery_system {
+	SYS_UNDEFINED,
+	SYS_DVBC_ANNEX_AC,
+	SYS_DVBC_ANNEX_B,
+	SYS_DVBT,
+	SYS_DSS,
+	SYS_DVBS,
+	SYS_DVBS2,
+	SYS_DVBH,
+	SYS_ISDBT,
+	SYS_ISDBS,
+	SYS_ISDBC,
+	SYS_ATSC,
+	SYS_ATSCMH,
+	SYS_DMBTH,
+	SYS_CMMB,
+	SYS_DAB,
+	SYS_DVBT2,
+} fe_delivery_system_t;
+</programlisting>
+
+	</section>
+
+	<section id="DTV_TRANSMISSION_MODE">
+		<title><constant>DTV_TRANSMISSION_MODE</constant></title>
+
+		<para>Specifies the number of carriers used by the standard</para>
+
+		<para>Possible values are:</para>
+<programlisting>
+typedef enum fe_transmit_mode {
+	TRANSMISSION_MODE_2K,
+	TRANSMISSION_MODE_8K,
+	TRANSMISSION_MODE_AUTO,
+	TRANSMISSION_MODE_4K,
+	TRANSMISSION_MODE_1K,
+	TRANSMISSION_MODE_16K,
+	TRANSMISSION_MODE_32K,
+} fe_transmit_mode_t;
+</programlisting>
+
+		<para>Notes:</para>
+		<para>1) ISDB-T supports three carrier/symbol-size: 8K, 4K, 2K. It is called
+			'mode' in the standard: Mode 1 is 2K, mode 2 is 4K, mode 3 is 8K</para>
+
+		<para>2) If <constant>DTV_TRANSMISSION_MODE</constant> is set the <constant>TRANSMISSION_MODE_AUTO</constant> the
+			hardware will try to find the correct FFT-size (if capable) and will
+			use TMCC to fill in the missing parameters.</para>
+		<para>3) DVB-T specifies 2K and 8K as valid sizes.</para>
+		<para>4) DVB-T2 specifies 1K, 2K, 4K, 8K, 16K and 32K.</para>
+	</section>
+
+	<section id="DTV_GUARD_INTERVAL">
+		<title><constant>DTV_GUARD_INTERVAL</constant></title>
+
+		<para>Possible values are:</para>
+<programlisting>
+typedef enum fe_guard_interval {
+	GUARD_INTERVAL_1_32,
+	GUARD_INTERVAL_1_16,
+	GUARD_INTERVAL_1_8,
+	GUARD_INTERVAL_1_4,
+	GUARD_INTERVAL_AUTO,
+	GUARD_INTERVAL_1_128,
+	GUARD_INTERVAL_19_128,
+	GUARD_INTERVAL_19_256,
+} fe_guard_interval_t;
+</programlisting>
+
+		<para>Notes:</para>
+		<para>1) If <constant>DTV_GUARD_INTERVAL</constant> is set the <constant>GUARD_INTERVAL_AUTO</constant> the hardware will
+			try to find the correct guard interval (if capable) and will use TMCC to fill
+			in the missing parameters.</para>
+		<para>2) Intervals 1/128, 19/128 and 19/256 are used only for DVB-T2 at present</para>
+	</section>
+</section>
+
 <section id="isdbt">
 	<title>ISDB-T frontend</title>
 	<para>This section describes shortly what are the possible parameters in the Linux
@@ -32,73 +356,6 @@
 
 	<para>Parameters used by ISDB-T and ISDB-Tsb.</para>
 
-	<section id="isdbt-parms">
-		<title>Parameters that are common with DVB-T and ATSC</title>
-
-		<section id="isdbt-freq">
-			<title><constant>DTV_FREQUENCY</constant></title>
-
-			<para>Central frequency of the channel.</para>
-
-			<para>For ISDB-T the channels are usually transmitted with an offset of 143kHz. E.g. a
-				valid frequncy could be 474143 kHz. The stepping is bound to the bandwidth of
-				the channel which is 6MHz.</para>
-
-			<para>As in ISDB-Tsb the channel consists of only one or three segments the
-				frequency step is 429kHz, 3*429 respectively. As for ISDB-T the
-				central frequency of the channel is expected.</para>
-		</section>
-
-		<section id="isdbt-bw">
-			<title><constant>DTV_BANDWIDTH_HZ</constant> (optional)</title>
-
-			<para>Possible values:</para>
-
-			<para>For ISDB-T it should be always 6000000Hz (6MHz)</para>
-			<para>For ISDB-Tsb it can vary depending on the number of connected segments</para>
-
-			<para>Note: Hardware specific values might be given here, but standard
-				applications should not bother to set a value to this field as
-				standard demods are ignoring it anyway.</para>
-
-			<para>Bandwidth in ISDB-T is fixed (6MHz) or can be easily derived from
-				other parameters (DTV_ISDBT_SB_SEGMENT_IDX,
-				DTV_ISDBT_SB_SEGMENT_COUNT).</para>
-		</section>
-
-		<section id="isdbt-delivery-sys">
-			<title><constant>DTV_DELIVERY_SYSTEM</constant></title>
-
-			<para>Possible values: <constant>SYS_ISDBT</constant></para>
-		</section>
-
-		<section id="isdbt-tx-mode">
-			<title><constant>DTV_TRANSMISSION_MODE</constant></title>
-
-			<para>ISDB-T supports three carrier/symbol-size: 8K, 4K, 2K. It is called
-				'mode' in the standard: Mode 1 is 2K, mode 2 is 4K, mode 3 is 8K</para>
-
-			<para>Possible values: <constant>TRANSMISSION_MODE_2K</constant>, <constant>TRANSMISSION_MODE_8K</constant>,
-				<constant>TRANSMISSION_MODE_AUTO</constant>, <constant>TRANSMISSION_MODE_4K</constant></para>
-
-			<para>If <constant>DTV_TRANSMISSION_MODE</constant> is set the <constant>TRANSMISSION_MODE_AUTO</constant> the
-				hardware will try to find the correct FFT-size (if capable) and will
-				use TMCC to fill in the missing parameters.</para>
-
-			<para><constant>TRANSMISSION_MODE_4K</constant> is added at the same time as the other new parameters.</para>
-		</section>
-
-		<section id="isdbt-guard-interval">
-			<title><constant>DTV_GUARD_INTERVAL</constant></title>
-
-			<para>Possible values: <constant>GUARD_INTERVAL_1_32</constant>, <constant>GUARD_INTERVAL_1_16</constant>, <constant>GUARD_INTERVAL_1_8</constant>,
-				<constant>GUARD_INTERVAL_1_4</constant>, <constant>GUARD_INTERVAL_AUTO</constant></para>
-
-			<para>If <constant>DTV_GUARD_INTERVAL</constant> is set the <constant>GUARD_INTERVAL_AUTO</constant> the hardware will
-				try to find the correct guard interval (if capable) and will use TMCC to fill
-				in the missing parameters.</para>
-		</section>
-	</section>
 	<section id="isdbt-new-parms">
 		<title>ISDB-T only parameters</title>
 
@@ -314,5 +571,20 @@
 			</section>
 		</section>
 	</section>
+	<section id="dvbt2-params">
+		<title>DVB-T2 parameters</title>
+		
+		<para>This section covers parameters that apply only to the DVB-T2 delivery method. DVB-T2
+			support is currently in the early stages development so expect this section to grow
+			and become more detailed with time.</para>
+
+		<section id="dvbt2-plp-id">
+			<title><constant>DTV_DVBT2_PLP_ID</constant></title>
+
+			<para>DVB-T2 supports Physical Layer Pipes (PLP) to allow transmission of
+				many data types via a single multiplex. The API will soon support this
+				at which point this section will be expanded.</para>
+		</section>
+	</section>
 </section>
 </section>
diff -druN linux-2.6.39-libre/Documentation/DocBook/dvb/frontend.h.xml linux-3.0-rc7-libre/Documentation/DocBook/dvb/frontend.h.xml
--- linux-2.6.39-libre/Documentation/DocBook/dvb/frontend.h.xml	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/Documentation/DocBook/dvb/frontend.h.xml	2011-07-11 19:51:52.000000000 -0400
@@ -176,14 +176,20 @@
         TRANSMISSION_MODE_2K,
         TRANSMISSION_MODE_8K,
         TRANSMISSION_MODE_AUTO,
-        TRANSMISSION_MODE_4K
+        TRANSMISSION_MODE_4K,
+        TRANSMISSION_MODE_1K,
+        TRANSMISSION_MODE_16K,
+        TRANSMISSION_MODE_32K,
 } fe_transmit_mode_t;
 
 typedef enum fe_bandwidth {
         BANDWIDTH_8_MHZ,
         BANDWIDTH_7_MHZ,
         BANDWIDTH_6_MHZ,
-        BANDWIDTH_AUTO
+        BANDWIDTH_AUTO,
+        BANDWIDTH_5_MHZ,
+        BANDWIDTH_10_MHZ,
+        BANDWIDTH_1_712_MHZ,
 } fe_bandwidth_t;
 
 
@@ -192,7 +198,10 @@
         GUARD_INTERVAL_1_16,
         GUARD_INTERVAL_1_8,
         GUARD_INTERVAL_1_4,
-        GUARD_INTERVAL_AUTO
+        GUARD_INTERVAL_AUTO,
+        GUARD_INTERVAL_1_128,
+        GUARD_INTERVAL_19_128,
+        GUARD_INTERVAL_19_256,
 } fe_guard_interval_t;
 
 
@@ -306,7 +315,9 @@
 
 #define DTV_ISDBS_TS_ID         42
 
-#define DTV_MAX_COMMAND                         DTV_ISDBS_TS_ID
+#define DTV_DVBT2_PLP_ID	43
+
+#define DTV_MAX_COMMAND                         DTV_DVBT2_PLP_ID
 
 typedef enum fe_pilot {
         PILOT_ON,
@@ -338,6 +349,7 @@
         SYS_DMBTH,
         SYS_CMMB,
         SYS_DAB,
+        SYS_DVBT2,
 } fe_delivery_system_t;
 
 struct dtv_cmds_h {
diff -druN linux-2.6.39-libre/Documentation/DocBook/genericirq.tmpl linux-3.0-rc7-libre/Documentation/DocBook/genericirq.tmpl
--- linux-2.6.39-libre/Documentation/DocBook/genericirq.tmpl	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/Documentation/DocBook/genericirq.tmpl	2011-07-11 19:51:52.000000000 -0400
@@ -191,8 +191,8 @@
 	<para>
 	Whenever an interrupt triggers, the lowlevel arch code calls into
 	the generic interrupt code by calling desc->handle_irq().
-	This highlevel IRQ handling function only uses desc->chip primitives
-	referenced by the assigned chip descriptor structure.
+	This highlevel IRQ handling function only uses desc->irq_data.chip
+	primitives referenced by the assigned chip descriptor structure.
 	</para>
     </sect1>
     <sect1 id="Highlevel_Driver_API">
@@ -206,11 +206,11 @@
 	  <listitem><para>enable_irq()</para></listitem>
 	  <listitem><para>disable_irq_nosync() (SMP only)</para></listitem>
 	  <listitem><para>synchronize_irq() (SMP only)</para></listitem>
-	  <listitem><para>set_irq_type()</para></listitem>
-	  <listitem><para>set_irq_wake()</para></listitem>
-	  <listitem><para>set_irq_data()</para></listitem>
-	  <listitem><para>set_irq_chip()</para></listitem>
-	  <listitem><para>set_irq_chip_data()</para></listitem>
+	  <listitem><para>irq_set_irq_type()</para></listitem>
+	  <listitem><para>irq_set_irq_wake()</para></listitem>
+	  <listitem><para>irq_set_handler_data()</para></listitem>
+	  <listitem><para>irq_set_chip()</para></listitem>
+	  <listitem><para>irq_set_chip_data()</para></listitem>
           </itemizedlist>
 	  See the autogenerated function documentation for details.
 	</para>
@@ -225,6 +225,8 @@
 	  <listitem><para>handle_fasteoi_irq</para></listitem>
 	  <listitem><para>handle_simple_irq</para></listitem>
 	  <listitem><para>handle_percpu_irq</para></listitem>
+	  <listitem><para>handle_edge_eoi_irq</para></listitem>
+	  <listitem><para>handle_bad_irq</para></listitem>
 	  </itemizedlist>
 	  The interrupt flow handlers (either predefined or architecture
 	  specific) are assigned to specific interrupts by the architecture
@@ -241,13 +243,13 @@
 		<programlisting>
 default_enable(struct irq_data *data)
 {
-	desc->chip->irq_unmask(data);
+	desc->irq_data.chip->irq_unmask(data);
 }
 
 default_disable(struct irq_data *data)
 {
 	if (!delay_disable(data))
-		desc->chip->irq_mask(data);
+		desc->irq_data.chip->irq_mask(data);
 }
 
 default_ack(struct irq_data *data)
@@ -284,9 +286,9 @@
 		<para>
 		The following control flow is implemented (simplified excerpt):
 		<programlisting>
-desc->chip->irq_mask();
-handle_IRQ_event(desc->action);
-desc->chip->irq_unmask();
+desc->irq_data.chip->irq_mask_ack();
+handle_irq_event(desc->action);
+desc->irq_data.chip->irq_unmask();
 		</programlisting>
 		</para>
 	    </sect3>
@@ -300,8 +302,8 @@
 		<para>
 		The following control flow is implemented (simplified excerpt):
 		<programlisting>
-handle_IRQ_event(desc->action);
-desc->chip->irq_eoi();
+handle_irq_event(desc->action);
+desc->irq_data.chip->irq_eoi();
 		</programlisting>
 		</para>
 	    </sect3>
@@ -315,17 +317,17 @@
 		The following control flow is implemented (simplified excerpt):
 		<programlisting>
 if (desc->status &amp; running) {
-	desc->chip->irq_mask();
+	desc->irq_data.chip->irq_mask_ack();
 	desc->status |= pending | masked;
 	return;
 }
-desc->chip->irq_ack();
+desc->irq_data.chip->irq_ack();
 desc->status |= running;
 do {
 	if (desc->status &amp; masked)
-		desc->chip->irq_unmask();
+		desc->irq_data.chip->irq_unmask();
 	desc->status &amp;= ~pending;
-	handle_IRQ_event(desc->action);
+	handle_irq_event(desc->action);
 } while (status &amp; pending);
 desc->status &amp;= ~running;
 		</programlisting>
@@ -344,7 +346,7 @@
 		<para>
 		The following control flow is implemented (simplified excerpt):
 		<programlisting>
-handle_IRQ_event(desc->action);
+handle_irq_event(desc->action);
 		</programlisting>
 		</para>
    	    </sect3>
@@ -362,12 +364,29 @@
 		<para>
 		The following control flow is implemented (simplified excerpt):
 		<programlisting>
-handle_IRQ_event(desc->action);
-if (desc->chip->irq_eoi)
-        desc->chip->irq_eoi();
+if (desc->irq_data.chip->irq_ack)
+	desc->irq_data.chip->irq_ack();
+handle_irq_event(desc->action);
+if (desc->irq_data.chip->irq_eoi)
+        desc->irq_data.chip->irq_eoi();
 		</programlisting>
 		</para>
    	    </sect3>
+	    <sect3 id="EOI_Edge_IRQ_flow_handler">
+	 	<title>EOI Edge IRQ flow handler</title>
+		<para>
+		handle_edge_eoi_irq provides an abnomination of the edge
+		handler which is solely used to tame a badly wreckaged
+		irq controller on powerpc/cell.
+		</para>
+   	    </sect3>
+	    <sect3 id="BAD_IRQ_flow_handler">
+	 	<title>Bad IRQ flow handler</title>
+		<para>
+		handle_bad_irq is used for spurious interrupts which
+		have no real handler assigned..
+		</para>
+   	    </sect3>
 	</sect2>
 	<sect2 id="Quirks_and_optimizations">
 	<title>Quirks and optimizations</title>
@@ -410,6 +429,7 @@
 	  <listitem><para>irq_mask_ack() - Optional, recommended for performance</para></listitem>
 	  <listitem><para>irq_mask()</para></listitem>
 	  <listitem><para>irq_unmask()</para></listitem>
+	  <listitem><para>irq_eoi() - Optional, required for eoi flow handlers</para></listitem>
 	  <listitem><para>irq_retrigger() - Optional</para></listitem>
 	  <listitem><para>irq_set_type() - Optional</para></listitem>
 	  <listitem><para>irq_set_wake() - Optional</para></listitem>
@@ -424,32 +444,24 @@
   <chapter id="doirq">
      <title>__do_IRQ entry point</title>
      <para>
- 	The original implementation __do_IRQ() is an alternative entry
-	point for all types of interrupts.
+	The original implementation __do_IRQ() was an alternative entry
+	point for all types of interrupts. It not longer exists.
      </para>
      <para>
 	This handler turned out to be not suitable for all
 	interrupt hardware and was therefore reimplemented with split
-	functionality for egde/level/simple/percpu interrupts. This is not
+	functionality for edge/level/simple/percpu interrupts. This is not
 	only a functional optimization. It also shortens code paths for
 	interrupts.
       </para>
-      <para>
-	To make use of the split implementation, replace the call to
-	__do_IRQ by a call to desc->handle_irq() and associate
-        the appropriate handler function to desc->handle_irq().
-	In most cases the generic handler implementations should
-	be sufficient.
-     </para>
   </chapter>
 
   <chapter id="locking">
      <title>Locking on SMP</title>
      <para>
 	The locking of chip registers is up to the architecture that
-	defines the chip primitives. There is a chip->lock field that can be used
-	for serialization, but the generic layer does not touch it. The per-irq
-	structure is protected via desc->lock, by the generic layer.
+	defines the chip primitives. The per-irq structure is
+	protected via desc->lock, by the generic layer.
      </para>
   </chapter>
   <chapter id="structs">
diff -druN linux-2.6.39-libre/Documentation/DocBook/.gitignore linux-3.0-rc7-libre/Documentation/DocBook/.gitignore
--- linux-2.6.39-libre/Documentation/DocBook/.gitignore	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/Documentation/DocBook/.gitignore	2011-07-11 19:51:52.000000000 -0400
@@ -8,3 +8,4 @@
 *.dvi
 *.log
 *.out
+media/
diff -druN linux-2.6.39-libre/Documentation/DocBook/Makefile linux-3.0-rc7-libre/Documentation/DocBook/Makefile
--- linux-2.6.39-libre/Documentation/DocBook/Makefile	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/Documentation/DocBook/Makefile	2011-07-11 19:51:52.000000000 -0400
@@ -73,7 +73,7 @@
 ###
 #External programs used
 KERNELDOC = $(srctree)/scripts/kernel-doc
-DOCPROC   = $(objtree)/scripts/basic/docproc
+DOCPROC   = $(objtree)/scripts/docproc
 
 XMLTOFLAGS = -m $(srctree)/Documentation/DocBook/stylesheet.xsl
 XMLTOFLAGS += --skip-validation
diff -druN linux-2.6.39-libre/Documentation/DocBook/media-entities.tmpl linux-3.0-rc7-libre/Documentation/DocBook/media-entities.tmpl
--- linux-2.6.39-libre/Documentation/DocBook/media-entities.tmpl	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/Documentation/DocBook/media-entities.tmpl	2011-07-11 19:51:52.000000000 -0400
@@ -270,6 +270,7 @@
 <!ENTITY sub-write SYSTEM "v4l/func-write.xml">
 <!ENTITY sub-io SYSTEM "v4l/io.xml">
 <!ENTITY sub-grey SYSTEM "v4l/pixfmt-grey.xml">
+<!ENTITY sub-m420 SYSTEM "v4l/pixfmt-m420.xml">
 <!ENTITY sub-nv12 SYSTEM "v4l/pixfmt-nv12.xml">
 <!ENTITY sub-nv12m SYSTEM "v4l/pixfmt-nv12m.xml">
 <!ENTITY sub-nv12mt SYSTEM "v4l/pixfmt-nv12mt.xml">
@@ -292,9 +293,11 @@
 <!ENTITY sub-yuyv SYSTEM "v4l/pixfmt-yuyv.xml">
 <!ENTITY sub-yvyu SYSTEM "v4l/pixfmt-yvyu.xml">
 <!ENTITY sub-srggb10 SYSTEM "v4l/pixfmt-srggb10.xml">
+<!ENTITY sub-srggb12 SYSTEM "v4l/pixfmt-srggb12.xml">
 <!ENTITY sub-srggb8 SYSTEM "v4l/pixfmt-srggb8.xml">
 <!ENTITY sub-y10 SYSTEM "v4l/pixfmt-y10.xml">
 <!ENTITY sub-y12 SYSTEM "v4l/pixfmt-y12.xml">
+<!ENTITY sub-y10b SYSTEM "v4l/pixfmt-y10b.xml">
 <!ENTITY sub-pixfmt SYSTEM "v4l/pixfmt.xml">
 <!ENTITY sub-cropcap SYSTEM "v4l/vidioc-cropcap.xml">
 <!ENTITY sub-dbg-g-register SYSTEM "v4l/vidioc-dbg-g-register.xml">
@@ -371,9 +374,9 @@
 <!ENTITY sub-media-indices SYSTEM "media-indices.tmpl">
 
 <!ENTITY sub-media-controller SYSTEM "v4l/media-controller.xml">
-<!ENTITY sub-media-open SYSTEM "v4l/media-func-open.xml">
-<!ENTITY sub-media-close SYSTEM "v4l/media-func-close.xml">
-<!ENTITY sub-media-ioctl SYSTEM "v4l/media-func-ioctl.xml">
+<!ENTITY sub-media-func-open SYSTEM "v4l/media-func-open.xml">
+<!ENTITY sub-media-func-close SYSTEM "v4l/media-func-close.xml">
+<!ENTITY sub-media-func-ioctl SYSTEM "v4l/media-func-ioctl.xml">
 <!ENTITY sub-media-ioc-device-info SYSTEM "v4l/media-ioc-device-info.xml">
 <!ENTITY sub-media-ioc-enum-entities SYSTEM "v4l/media-ioc-enum-entities.xml">
 <!ENTITY sub-media-ioc-enum-links SYSTEM "v4l/media-ioc-enum-links.xml">
diff -druN linux-2.6.39-libre/Documentation/DocBook/mtdnand.tmpl linux-3.0-rc7-libre/Documentation/DocBook/mtdnand.tmpl
--- linux-2.6.39-libre/Documentation/DocBook/mtdnand.tmpl	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/Documentation/DocBook/mtdnand.tmpl	2011-07-11 19:51:52.000000000 -0400
@@ -189,8 +189,7 @@
 		<title>Partition defines</title>
 		<para>
 			If you want to divide your device into partitions, then
-			enable the configuration switch CONFIG_MTD_PARTITIONS and define
-			a partitioning scheme suitable to your board.
+			define a partitioning scheme suitable to your board.
 		</para>
 		<programlisting>
 #define NUM_PARTITIONS 2
diff -druN linux-2.6.39-libre/Documentation/DocBook/v4l/media-controller.xml linux-3.0-rc7-libre/Documentation/DocBook/v4l/media-controller.xml
--- linux-2.6.39-libre/Documentation/DocBook/v4l/media-controller.xml	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/Documentation/DocBook/v4l/media-controller.xml	2011-07-11 19:51:52.000000000 -0400
@@ -78,9 +78,9 @@
 <appendix id="media-user-func">
   <title>Function Reference</title>
   <!-- Keep this alphabetically sorted. -->
-  &sub-media-open;
-  &sub-media-close;
-  &sub-media-ioctl;
+  &sub-media-func-open;
+  &sub-media-func-close;
+  &sub-media-func-ioctl;
   <!-- All ioctls go here. -->
   &sub-media-ioc-device-info;
   &sub-media-ioc-enum-entities;
diff -druN linux-2.6.39-libre/Documentation/DocBook/v4l/pixfmt-m420.xml linux-3.0-rc7-libre/Documentation/DocBook/v4l/pixfmt-m420.xml
--- linux-2.6.39-libre/Documentation/DocBook/v4l/pixfmt-m420.xml	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/Documentation/DocBook/v4l/pixfmt-m420.xml	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,147 @@
+    <refentry id="V4L2-PIX-FMT-M420">
+      <refmeta>
+	<refentrytitle>V4L2_PIX_FMT_M420 ('M420')</refentrytitle>
+	&manvol;
+      </refmeta>
+      <refnamediv>
+	<refname><constant>V4L2_PIX_FMT_M420</constant></refname>
+	<refpurpose>Format with &frac12; horizontal and vertical chroma
+	resolution, also known as YUV 4:2:0. Hybrid plane line-interleaved
+	layout.</refpurpose>
+      </refnamediv>
+      <refsect1>
+	<title>Description</title>
+
+	<para>M420 is a YUV format with &frac12; horizontal and vertical chroma
+	subsampling (YUV 4:2:0). Pixels are organized as interleaved luma and
+	chroma planes. Two lines of luma data are followed by one line of chroma
+	data.</para>
+	<para>The luma plane has one byte per pixel. The chroma plane contains
+	interleaved CbCr pixels subsampled by &frac12; in the horizontal and
+	vertical directions. Each CbCr pair belongs to four pixels. For example,
+Cb<subscript>0</subscript>/Cr<subscript>0</subscript> belongs to
+Y'<subscript>00</subscript>, Y'<subscript>01</subscript>,
+Y'<subscript>10</subscript>, Y'<subscript>11</subscript>.</para>
+
+	<para>All line lengths are identical: if the Y lines include pad bytes
+	so do the CbCr lines.</para>
+
+	<example>
+	  <title><constant>V4L2_PIX_FMT_M420</constant> 4 &times; 4
+pixel image</title>
+
+	  <formalpara>
+	    <title>Byte Order.</title>
+	    <para>Each cell is one byte.
+		<informaltable frame="none">
+		<tgroup cols="5" align="center">
+		  <colspec align="left" colwidth="2*" />
+		  <tbody valign="top">
+		    <row>
+		      <entry>start&nbsp;+&nbsp;0:</entry>
+		      <entry>Y'<subscript>00</subscript></entry>
+		      <entry>Y'<subscript>01</subscript></entry>
+		      <entry>Y'<subscript>02</subscript></entry>
+		      <entry>Y'<subscript>03</subscript></entry>
+		    </row>
+		    <row>
+		      <entry>start&nbsp;+&nbsp;4:</entry>
+		      <entry>Y'<subscript>10</subscript></entry>
+		      <entry>Y'<subscript>11</subscript></entry>
+		      <entry>Y'<subscript>12</subscript></entry>
+		      <entry>Y'<subscript>13</subscript></entry>
+		    </row>
+		    <row>
+		      <entry>start&nbsp;+&nbsp;8:</entry>
+		      <entry>Cb<subscript>00</subscript></entry>
+		      <entry>Cr<subscript>00</subscript></entry>
+		      <entry>Cb<subscript>01</subscript></entry>
+		      <entry>Cr<subscript>01</subscript></entry>
+		    </row>
+		    <row>
+		      <entry>start&nbsp;+&nbsp;16:</entry>
+		      <entry>Y'<subscript>20</subscript></entry>
+		      <entry>Y'<subscript>21</subscript></entry>
+		      <entry>Y'<subscript>22</subscript></entry>
+		      <entry>Y'<subscript>23</subscript></entry>
+		    </row>
+		    <row>
+		      <entry>start&nbsp;+&nbsp;20:</entry>
+		      <entry>Y'<subscript>30</subscript></entry>
+		      <entry>Y'<subscript>31</subscript></entry>
+		      <entry>Y'<subscript>32</subscript></entry>
+		      <entry>Y'<subscript>33</subscript></entry>
+		    </row>
+		    <row>
+		      <entry>start&nbsp;+&nbsp;24:</entry>
+		      <entry>Cb<subscript>10</subscript></entry>
+		      <entry>Cr<subscript>10</subscript></entry>
+		      <entry>Cb<subscript>11</subscript></entry>
+		      <entry>Cr<subscript>11</subscript></entry>
+		    </row>
+		  </tbody>
+		</tgroup>
+		</informaltable>
+	      </para>
+	  </formalpara>
+
+	  <formalpara>
+	    <title>Color Sample Location.</title>
+	    <para>
+		<informaltable frame="none">
+		<tgroup cols="7" align="center">
+		  <tbody valign="top">
+		    <row>
+		      <entry></entry>
+		      <entry>0</entry><entry></entry><entry>1</entry><entry></entry>
+		      <entry>2</entry><entry></entry><entry>3</entry>
+		    </row>
+		    <row>
+		      <entry>0</entry>
+		      <entry>Y</entry><entry></entry><entry>Y</entry><entry></entry>
+		      <entry>Y</entry><entry></entry><entry>Y</entry>
+		    </row>
+		    <row>
+		      <entry></entry>
+		      <entry></entry><entry>C</entry><entry></entry><entry></entry>
+		      <entry></entry><entry>C</entry><entry></entry>
+		    </row>
+		    <row>
+		      <entry>1</entry>
+		      <entry>Y</entry><entry></entry><entry>Y</entry><entry></entry>
+		      <entry>Y</entry><entry></entry><entry>Y</entry>
+		    </row>
+		    <row>
+		      <entry></entry>
+		    </row>
+		    <row>
+		      <entry>2</entry>
+		      <entry>Y</entry><entry></entry><entry>Y</entry><entry></entry>
+		      <entry>Y</entry><entry></entry><entry>Y</entry>
+		    </row>
+		    <row>
+		      <entry></entry>
+		      <entry></entry><entry>C</entry><entry></entry><entry></entry>
+		      <entry></entry><entry>C</entry><entry></entry>
+		    </row>
+		    <row>
+		      <entry>3</entry>
+		      <entry>Y</entry><entry></entry><entry>Y</entry><entry></entry>
+		      <entry>Y</entry><entry></entry><entry>Y</entry>
+		    </row>
+		  </tbody>
+		</tgroup>
+		</informaltable>
+	      </para>
+	  </formalpara>
+	</example>
+      </refsect1>
+    </refentry>
+
+  <!--
+Local Variables:
+mode: sgml
+sgml-parent-document: "pixfmt.sgml"
+indent-tabs-mode: nil
+End:
+  -->
diff -druN linux-2.6.39-libre/Documentation/DocBook/v4l/pixfmt.xml linux-3.0-rc7-libre/Documentation/DocBook/v4l/pixfmt.xml
--- linux-2.6.39-libre/Documentation/DocBook/v4l/pixfmt.xml	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/Documentation/DocBook/v4l/pixfmt.xml	2011-07-11 19:51:52.000000000 -0400
@@ -673,6 +673,7 @@
     &sub-srggb8;
     &sub-sbggr16;
     &sub-srggb10;
+    &sub-srggb12;
   </section>
 
   <section id="yuv-formats">
@@ -697,6 +698,7 @@
     &sub-grey;
     &sub-y10;
     &sub-y12;
+    &sub-y10b;
     &sub-y16;
     &sub-yuyv;
     &sub-uyvy;
@@ -712,6 +714,7 @@
     &sub-nv12m;
     &sub-nv12mt;
     &sub-nv16;
+    &sub-m420;
   </section>
 
   <section>
diff -druN linux-2.6.39-libre/Documentation/DocBook/v4l/pixfmt-y10b.xml linux-3.0-rc7-libre/Documentation/DocBook/v4l/pixfmt-y10b.xml
--- linux-2.6.39-libre/Documentation/DocBook/v4l/pixfmt-y10b.xml	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/Documentation/DocBook/v4l/pixfmt-y10b.xml	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,43 @@
+<refentry id="V4L2-PIX-FMT-Y10BPACK">
+  <refmeta>
+    <refentrytitle>V4L2_PIX_FMT_Y10BPACK ('Y10B')</refentrytitle>
+    &manvol;
+  </refmeta>
+  <refnamediv>
+    <refname><constant>V4L2_PIX_FMT_Y10BPACK</constant></refname>
+    <refpurpose>Grey-scale image as a bit-packed array</refpurpose>
+  </refnamediv>
+  <refsect1>
+    <title>Description</title>
+
+    <para>This is a packed grey-scale image format with a depth of 10 bits per
+      pixel. Pixels are stored in a bit-packed array of 10bit bits per pixel,
+      with no padding between them and with the most significant bits coming
+      first from the left.</para>
+
+    <example>
+      <title><constant>V4L2_PIX_FMT_Y10BPACK</constant> 4 pixel data stream taking 5 bytes</title>
+
+      <formalpara>
+	<title>Bit-packed representation</title>
+	<para>pixels cross the byte boundary and have a ratio of 5 bytes for each 4
+          pixels.
+	  <informaltable frame="all">
+	    <tgroup cols="5" align="center">
+	      <colspec align="left" colwidth="2*" />
+	      <tbody valign="top">
+		<row>
+		  <entry>Y'<subscript>00[9:2]</subscript></entry>
+		  <entry>Y'<subscript>00[1:0]</subscript>Y'<subscript>01[9:4]</subscript></entry>
+		  <entry>Y'<subscript>01[3:0]</subscript>Y'<subscript>02[9:6]</subscript></entry>
+		  <entry>Y'<subscript>02[5:0]</subscript>Y'<subscript>03[9:8]</subscript></entry>
+		  <entry>Y'<subscript>03[7:0]</subscript></entry>
+		</row>
+	      </tbody>
+	    </tgroup>
+	  </informaltable>
+	</para>
+      </formalpara>
+    </example>
+  </refsect1>
+</refentry>
diff -druN linux-2.6.39-libre/Documentation/DocBook/v4l/subdev-formats.xml linux-3.0-rc7-libre/Documentation/DocBook/v4l/subdev-formats.xml
--- linux-2.6.39-libre/Documentation/DocBook/v4l/subdev-formats.xml	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/Documentation/DocBook/v4l/subdev-formats.xml	2011-07-11 19:51:52.000000000 -0400
@@ -2522,5 +2522,51 @@
 	</tgroup>
       </table>
     </section>
+
+    <section>
+      <title>JPEG Compressed Formats</title>
+
+      <para>Those data formats consist of an ordered sequence of 8-bit bytes
+	obtained from JPEG compression process. Additionally to the
+	<constant>_JPEG</constant> prefix the format code is made of
+	the following information.
+	<itemizedlist>
+	  <listitem><para>The number of bus samples per entropy encoded byte.</para></listitem>
+	  <listitem><para>The bus width.</para></listitem>
+	</itemizedlist>
+      </para>
+
+      <para>For instance, for a JPEG baseline process and an 8-bit bus width
+        the format will be named <constant>V4L2_MBUS_FMT_JPEG_1X8</constant>.
+      </para>
+
+      <para>The following table lists existing JPEG compressed formats.</para>
+
+      <table pgwide="0" frame="none" id="v4l2-mbus-pixelcode-jpeg">
+	<title>JPEG Formats</title>
+	<tgroup cols="3">
+	  <colspec colname="id" align="left" />
+	  <colspec colname="code" align="left"/>
+	  <colspec colname="remarks" align="left"/>
+	  <thead>
+	    <row>
+	      <entry>Identifier</entry>
+	      <entry>Code</entry>
+	      <entry>Remarks</entry>
+	    </row>
+	  </thead>
+	  <tbody valign="top">
+	    <row id="V4L2-MBUS-FMT-JPEG-1X8">
+	      <entry>V4L2_MBUS_FMT_JPEG_1X8</entry>
+	      <entry>0x4001</entry>
+	      <entry>Besides of its usage for the parallel bus this format is
+		recommended for transmission of JPEG data over MIPI CSI bus
+		using the User Defined 8-bit Data types.
+	      </entry>
+	    </row>
+	  </tbody>
+	</tgroup>
+      </table>
+    </section>
   </section>
 </section>
diff -druN linux-2.6.39-libre/Documentation/DocBook/v4l/videodev2.h.xml linux-3.0-rc7-libre/Documentation/DocBook/v4l/videodev2.h.xml
--- linux-2.6.39-libre/Documentation/DocBook/v4l/videodev2.h.xml	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/Documentation/DocBook/v4l/videodev2.h.xml	2011-07-11 19:51:52.000000000 -0400
@@ -311,6 +311,9 @@
 #define <link linkend="V4L2-PIX-FMT-Y10">V4L2_PIX_FMT_Y10</link>     v4l2_fourcc('Y', '1', '0', ' ') /* 10  Greyscale     */
 #define <link linkend="V4L2-PIX-FMT-Y16">V4L2_PIX_FMT_Y16</link>     v4l2_fourcc('Y', '1', '6', ' ') /* 16  Greyscale     */
 
+/* Grey bit-packed formats */
+#define <link linkend="V4L2-PIX-FMT-Y10BPACK">V4L2_PIX_FMT_Y10BPACK</link>    v4l2_fourcc('Y', '1', '0', 'B') /* 10  Greyscale bit-packed */
+
 /* Palette formats */
 #define <link linkend="V4L2-PIX-FMT-PAL8">V4L2_PIX_FMT_PAL8</link>    v4l2_fourcc('P', 'A', 'L', '8') /*  8  8-bit palette */
 
@@ -333,6 +336,7 @@
 #define <link linkend="V4L2-PIX-FMT-YUV420">V4L2_PIX_FMT_YUV420</link>  v4l2_fourcc('Y', 'U', '1', '2') /* 12  YUV 4:2:0     */
 #define <link linkend="V4L2-PIX-FMT-HI240">V4L2_PIX_FMT_HI240</link>   v4l2_fourcc('H', 'I', '2', '4') /*  8  8-bit color   */
 #define <link linkend="V4L2-PIX-FMT-HM12">V4L2_PIX_FMT_HM12</link>    v4l2_fourcc('H', 'M', '1', '2') /*  8  YUV 4:2:0 16x16 macroblocks */
+#define <link linkend="V4L2-PIX-FMT-M420">V4L2_PIX_FMT_M420</link>    v4l2_fourcc('M', '4', '2', '0') /* 12  YUV 4:2:0 2 lines y, 1 line uv interleaved */
 
 /* two planes -- one Y, one Cr + Cb interleaved  */
 #define <link linkend="V4L2-PIX-FMT-NV12">V4L2_PIX_FMT_NV12</link>    v4l2_fourcc('N', 'V', '1', '2') /* 12  Y/CbCr 4:2:0  */
diff -druN linux-2.6.39-libre/Documentation/dontdiff linux-3.0-rc7-libre/Documentation/dontdiff
--- linux-2.6.39-libre/Documentation/dontdiff	2011-05-19 02:07:25.000000000 -0400
+++ linux-3.0-rc7-libre/Documentation/dontdiff	2011-07-21 06:49:31.000000000 -0400
@@ -1,6 +1,8 @@
 *.a
 *.aux
 *.bin
+*.bz2
+*.cis
 *.cpio
 *.csp
 *.dsp
@@ -8,6 +10,8 @@
 *.elf
 *.eps
 *.fw
+*.gcno
+*.gcov
 *.gen.S
 *.gif
 *.grep
@@ -19,14 +23,20 @@
 *.ko
 *.log
 *.lst
+*.lzma
+*.lzo
+*.mo
 *.moc
 *.mod.c
 *.o
 *.o.*
+*.order
 *.orig
 *.out
+*.patch
 *.pdf
 *.png
+*.pot
 *.ps
 *.rej
 *.s
@@ -39,16 +49,22 @@
 *.tex
 *.ver
 *.xml
+*.xz
 *_MODULES
 *_vga16.c
 *~
+\#*#
 *.9
-*.9.gz
 .*
+.*.d
 .mm
 53c700_d.h
 CVS
 ChangeSet
+GPATH
+GRTAGS
+GSYMS
+GTAGS
 Image
 Kerntypes
 Module.markers
@@ -57,15 +73,14 @@
 SCCS
 System.map*
 TAGS
+aconf
+af_names.h
 aic7*reg.h*
 aic7*reg_print.c*
 aic7*seq.h*
 aicasm
 aicdb.h*
-altivec1.c
-altivec2.c
-altivec4.c
-altivec8.c
+altivec*.c
 asm-offsets.h
 asm_offsets.h
 autoconf.h*
@@ -80,6 +95,7 @@
 build
 bvmlinux
 bzImage*
+capability_names.h
 capflags.c
 classlist.h*
 comp*.log
@@ -88,7 +104,8 @@
 config
 config-*
 config_data.h*
-config_data.gz*
+config.mak
+config.mak.autogen
 conmakehash
 consolemap_deftbl.c*
 cpustr.h
@@ -96,7 +113,9 @@
 cscope.*
 defkeymap.c
 devlist.h*
+dnotify_test
 docproc
+dslm
 elf2ecoff
 elfconfig.h*
 evergreen_reg_safe.h
@@ -105,6 +124,7 @@
 fore200e_mkfirm
 fore200e_pca_fw.c*
 gconf
+gconf.glade.h
 gen-devlist
 gen_crc32table
 gen_init_cpio
@@ -112,11 +132,12 @@
 genheaders
 genksyms
 *_gray256.c
+hpet_example
+hugepage-mmap
+hugepage-shm
 ihex2fw
 ikconfig.h*
 inat-tables.c
-initramfs_data.cpio
-initramfs_data.cpio.gz
 initramfs_list
 int16.c
 int1.c
@@ -133,15 +154,19 @@
 lkc_defs.h
 lex.c
 lex.*.c
+linux
 logo_*.c
 logo_*_clut224.c
 logo_*_mono.c
 lxdialog
+mach
 mach-types
 mach-types.h
 machtypes.h
 map
+map_hugetlb
 maui_boot.h
+media
 mconf
 miboot*
 mk_elfconfig
@@ -150,23 +175,29 @@
 mkcpustr
 mkdep
 mkprep
+mkregtable
 mktables
 mktree
 modpost
 modules.builtin
 modules.order
 modversions.h*
+nconf
 ncscope.*
 offset.h
 offsets.h
 oui.c*
+page-types
 parse.c
 parse.h
 patches*
 /*(DEBLOBBED)*/
 /*(DEBLOBBED)*/
-piggy.gz
+perf.data
+perf.data.old
+perf-archive
 piggyback
+piggy.gzip
 piggy.S
 pnmtologo
 ppc_defs.h*
@@ -177,10 +208,9 @@
 r300_reg_safe.h
 r420_reg_safe.h
 r600_reg_safe.h
-raid6altivec*.c
-raid6int*.c
-raid6tables.c
+recordmcount
 relocs
+rlim_names.h
 rn50_reg_safe.h
 rs600_reg_safe.h
 rv515_reg_safe.h
@@ -194,6 +224,7 @@
 syscalltab.h
 tables.c
 tags
+test_get_len
 tftpboot.img
 timeconst.h
 times.h*
@@ -210,10 +241,13 @@
 vdso64.lds
 vdso64.so.dbg
 version.h*
+vmImage
 vmlinux
 vmlinux-*
 vmlinux.aout
+vmlinux.bin.all
 vmlinux.lds
+vmlinuz
 voffset.h
 vsyscall.lds
 vsyscall_32.lds
diff -druN linux-2.6.39-libre/Documentation/driver-model/bus.txt linux-3.0-rc7-libre/Documentation/driver-model/bus.txt
--- linux-2.6.39-libre/Documentation/driver-model/bus.txt	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/Documentation/driver-model/bus.txt	2011-07-11 19:51:52.000000000 -0400
@@ -3,24 +3,7 @@
 
 Definition
 ~~~~~~~~~~
-
-struct bus_type {
-	char			* name;
-
-	struct subsystem	subsys;
-	struct kset		drivers;
-	struct kset		devices;
-
-	struct bus_attribute	* bus_attrs;
-	struct device_attribute	* dev_attrs;
-	struct driver_attribute	* drv_attrs;
-
-	int		(*match)(struct device * dev, struct device_driver * drv);
-	int		(*hotplug) (struct device *dev, char **envp, 
-				    int num_envp, char *buffer, int buffer_size);
-	int		(*suspend)(struct device * dev, pm_message_t state);
-	int		(*resume)(struct device * dev);
-};
+See the kerneldoc for the struct bus_type.
 
 int bus_register(struct bus_type * bus);
 
diff -druN linux-2.6.39-libre/Documentation/driver-model/class.txt linux-3.0-rc7-libre/Documentation/driver-model/class.txt
--- linux-2.6.39-libre/Documentation/driver-model/class.txt	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/Documentation/driver-model/class.txt	2011-07-11 19:51:52.000000000 -0400
@@ -27,22 +27,7 @@
 typedef int (*devclass_add)(struct device *);
 typedef void (*devclass_remove)(struct device *);
 
-struct device_class {
-	char			* name;
-	rwlock_t		lock;
-	u32			devnum;
-	struct list_head	node;
-
-	struct list_head	drivers;
-	struct list_head	intf_list;
-
-	struct driver_dir_entry	dir;
-	struct driver_dir_entry	device_dir;
-	struct driver_dir_entry	driver_dir;
-
-	devclass_add		add_device;
-	devclass_remove		remove_device;
-};
+See the kerneldoc for the struct class.
 
 A typical device class definition would look like: 
 
diff -druN linux-2.6.39-libre/Documentation/driver-model/device.txt linux-3.0-rc7-libre/Documentation/driver-model/device.txt
--- linux-2.6.39-libre/Documentation/driver-model/device.txt	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/Documentation/driver-model/device.txt	2011-07-11 19:51:52.000000000 -0400
@@ -2,96 +2,7 @@
 The Basic Device Structure
 ~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-struct device {
-        struct list_head g_list;
-        struct list_head node;
-        struct list_head bus_list;
-        struct list_head driver_list;
-        struct list_head intf_list;
-        struct list_head children;
-        struct device   * parent;
-
-        char    name[DEVICE_NAME_SIZE];
-        char    bus_id[BUS_ID_SIZE];
-
-        spinlock_t      lock;
-        atomic_t        refcount;
-
-        struct bus_type * bus;
-        struct driver_dir_entry dir;
-
-	u32		class_num;
-
-        struct device_driver *driver;
-        void            *driver_data;
-        void            *platform_data;
-
-        u32             current_state;
-        unsigned char *saved_state;
-
-        void    (*release)(struct device * dev);
-};
-
-Fields 
-~~~~~~
-g_list:	Node in the global device list.
-
-node:	Node in device's parent's children list.
-
-bus_list: Node in device's bus's devices list.
-
-driver_list:   Node in device's driver's devices list.
-
-intf_list:     List of intf_data. There is one structure allocated for
-	       each interface that the device supports.
-
-children:      List of child devices.
-
-parent:        *** FIXME ***
-
-name:	       ASCII description of device. 
-	       Example: " 3Com Corporation 3c905 100BaseTX [Boomerang]"
-
-bus_id:	       ASCII representation of device's bus position. This 
-	       field should be a name unique across all devices on the
-	       bus type the device belongs to. 
-
-	       Example: PCI bus_ids are in the form of
-	       <bus number>:<slot number>.<function number> 
-	       This name is unique across all PCI devices in the system.
-
-lock:	       Spinlock for the device. 
-
-refcount:      Reference count on the device.
-
-bus:	       Pointer to struct bus_type that device belongs to.
-
-dir:	       Device's sysfs directory.
-
-class_num:     Class-enumerated value of the device.
-
-driver:	       Pointer to struct device_driver that controls the device.
-
-driver_data:   Driver-specific data.
-
-platform_data: Platform data specific to the device.
-
-	       Example:  for devices on custom boards, as typical of embedded
-	       and SOC based hardware, Linux often uses platform_data to point
-	       to board-specific structures describing devices and how they
-	       are wired.  That can include what ports are available, chip
-	       variants, which GPIO pins act in what additional roles, and so
-	       on.  This shrinks the "Board Support Packages" (BSPs) and
-	       minimizes board-specific #ifdefs in drivers.
-
-current_state: Current power state of the device.
-
-saved_state:   Pointer to saved state of the device. This is usable by
-	       the device driver controlling the device.
-
-release:       Callback to free the device after all references have 
-	       gone away. This should be set by the allocator of the 
-	       device (i.e. the bus driver that discovered the device).
+See the kerneldoc for the struct device.
 
 
 Programming Interface
diff -druN linux-2.6.39-libre/Documentation/driver-model/driver.txt linux-3.0-rc7-libre/Documentation/driver-model/driver.txt
--- linux-2.6.39-libre/Documentation/driver-model/driver.txt	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/Documentation/driver-model/driver.txt	2011-07-11 19:51:52.000000000 -0400
@@ -1,23 +1,7 @@
 
 Device Drivers
 
-struct device_driver {
-        char                    * name;
-        struct bus_type         * bus;
-
-        struct completion	unloaded;
-        struct kobject		kobj;
-        list_t                  devices;
-
-        struct module		*owner;
-
-        int     (*probe)        (struct device * dev);
-        int     (*remove)       (struct device * dev);
-
-        int     (*suspend)      (struct device * dev, pm_message_t state);
-        int     (*resume)       (struct device * dev);
-};
-
+See the kerneldoc for the struct device_driver.
 
 
 Allocation
diff -druN linux-2.6.39-libre/Documentation/feature-removal-schedule.txt linux-3.0-rc7-libre/Documentation/feature-removal-schedule.txt
--- linux-2.6.39-libre/Documentation/feature-removal-schedule.txt	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/Documentation/feature-removal-schedule.txt	2011-07-11 19:51:52.000000000 -0400
@@ -6,6 +6,42 @@
 
 ---------------------------
 
+What:	x86 floppy disable_hlt
+When:	2012
+Why:	ancient workaround of dubious utility clutters the
+	code used by everybody else.
+Who:	Len Brown <len.brown@intel.com>
+
+---------------------------
+
+What:	CONFIG_APM_CPU_IDLE, and its ability to call APM BIOS in idle
+When:	2012
+Why:	This optional sub-feature of APM is of dubious reliability,
+	and ancient APM laptops are likely better served by calling HLT.
+	Deleting CONFIG_APM_CPU_IDLE allows x86 to stop exporting
+	the pm_idle function pointer to modules.
+Who:	Len Brown <len.brown@intel.com>
+
+----------------------------
+
+What:	x86_32 "no-hlt" cmdline param
+When:	2012
+Why:	remove a branch from idle path, simplify code used by everybody.
+	This option disabled the use of HLT in idle and machine_halt()
+	for hardware that was flakey 15-years ago.  Today we have
+	"idle=poll" that removed HLT from idle, and so if such a machine
+	is still running the upstream kernel, "idle=poll" is likely sufficient.
+Who:	Len Brown <len.brown@intel.com>
+
+----------------------------
+
+What:	x86 "idle=mwait" cmdline param
+When:	2012
+Why:	simplify x86 idle code
+Who:	Len Brown <len.brown@intel.com>
+
+----------------------------
+
 What:	PRISM54
 When:	2.6.34
 
@@ -35,17 +71,6 @@
 
 ---------------------------
 
-What:	AR9170USB
-When:	2.6.40
-
-Why:	This driver is deprecated and the firmware is no longer
-	maintained. The replacement driver "carl9170" has been
-	around for a while, so the devices are still supported.
-
-Who:	Christian Lamparter <chunkeey@googlemail.com>
-
----------------------------
-
 What:	IRQF_SAMPLE_RANDOM
 Check:	IRQF_SAMPLE_RANDOM
 When:	July 2009
@@ -226,7 +251,7 @@
 What:	CONFIG_ACPI_PROCFS_POWER
 When:	2.6.39
 Why:	sysfs I/F for ACPI power devices, including AC and Battery,
-        has been working in upstream kenrel since 2.6.24, Sep 2007.
+        has been working in upstream kernel since 2.6.24, Sep 2007.
 	In 2.6.37, we make the sysfs I/F always built in and this option
 	disabled by default.
 	Remove this option and the ACPI power procfs interface in 2.6.39.
@@ -273,16 +298,6 @@
 
 ---------------------------
 
-What:	/sys/o2cb symlink
-When:	January 2010
-Why:	/sys/fs/o2cb is the proper location for this information - /sys/o2cb
-	exists as a symlink for backwards compatibility for old versions of
-	ocfs2-tools. 2 years should be sufficient time to phase in new versions
-	which know to look in /sys/fs/o2cb.
-Who:	ocfs2-devel@oss.oracle.com
-
----------------------------
-
 What:	Ability for non root users to shm_get hugetlb pages based on mlock
 	resource limits
 When:	2.6.31
@@ -405,16 +420,6 @@
 
 ----------------------------
 
-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 paravirt mmu host support
 When:	January 2011
 Why:	The paravirt mmu host support is slower than non-paravirt mmu, both
@@ -460,14 +465,6 @@
 
 ----------------------------
 
-What:	The acpi_sleep=s4_nonvs command line option
-When:	2.6.37
-Files:	arch/x86/kernel/acpi/sleep.c
-Why:	superseded by acpi_sleep=nonvs
-Who:	Rafael J. Wysocki <rjw@sisk.pl>
-
-----------------------------
-
 What: 	PCI DMA unmap state API
 When:	August 2012
 Why:	PCI DMA unmap state API (include/linux/pci-dma.h) was replaced
@@ -484,23 +481,6 @@
 
 ----------------------------
 
-What:   namespace cgroup (ns_cgroup)
-When:   2.6.38
-Why:    The ns_cgroup leads to some problems:
-	* cgroup creation is out-of-control
-	* cgroup name can conflict when pids are looping
-	* it is not possible to have a single process handling
-	a lot of namespaces without falling in a exponential creation time
-	* we may want to create a namespace without creating a cgroup
-
-	The ns_cgroup is replaced by a compatibility flag 'clone_children',
-	where a newly created cgroup will copy the parent cgroup values.
-	The userspace has to manually create a cgroup and add a task to
-	the 'tasks' file.
-Who:    Daniel Lezcano <daniel.lezcano@free.fr>
-
-----------------------------
-
 What:	iwlwifi disable_hw_scan module parameters
 When:	2.6.40
 Why:	Hareware scan is the prefer method for iwlwifi devices for
@@ -580,3 +560,48 @@
 Who:	Jean Delvare <khali@linux-fr.org>
 
 ----------------------------
+
+What:	Support for UVCIOC_CTRL_ADD in the uvcvideo driver
+When:	2.6.42
+Why:	The information passed to the driver by this ioctl is now queried
+	dynamically from the device.
+Who:	Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+
+----------------------------
+
+What:	Support for UVCIOC_CTRL_MAP_OLD in the uvcvideo driver
+When:	2.6.42
+Why:	Used only by applications compiled against older driver versions.
+	Superseded by UVCIOC_CTRL_MAP which supports V4L2 menu controls.
+Who:	Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+
+----------------------------
+
+What:	Support for UVCIOC_CTRL_GET and UVCIOC_CTRL_SET in the uvcvideo driver
+When:	2.6.42
+Why:	Superseded by the UVCIOC_CTRL_QUERY ioctl.
+Who:	Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+
+----------------------------
+
+What:	For VIDIOC_S_FREQUENCY the type field must match the device node's type.
+	If not, return -EINVAL.
+When:	3.2
+Why:	It makes no sense to switch the tuner to radio mode by calling
+	VIDIOC_S_FREQUENCY on a video node, or to switch the tuner to tv mode by
+	calling VIDIOC_S_FREQUENCY on a radio node. This is the first step of a
+	move to more consistent handling of tv and radio tuners.
+Who:	Hans Verkuil <hans.verkuil@cisco.com>
+
+----------------------------
+
+What:	Opening a radio device node will no longer automatically switch the
+	tuner mode from tv to radio.
+When:	3.3
+Why:	Just opening a V4L device should not change the state of the hardware
+	like that. It's very unexpected and against the V4L spec. Instead, you
+	switch to radio mode by calling VIDIOC_S_FREQUENCY. This is the second
+	and last step of the move to consistent handling of tv and radio tuners.
+Who:	Hans Verkuil <hans.verkuil@cisco.com>
+
+----------------------------
diff -druN linux-2.6.39-libre/Documentation/filesystems/9p.txt linux-3.0-rc7-libre/Documentation/filesystems/9p.txt
--- linux-2.6.39-libre/Documentation/filesystems/9p.txt	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/Documentation/filesystems/9p.txt	2011-07-11 19:51:52.000000000 -0400
@@ -25,6 +25,8 @@
 		http://xcpu.org/papers/cellfs-talk.pdf
 	* PROSE I/O: Using 9p to enable Application Partitions
 		http://plan9.escet.urjc.es/iwp9/cready/PROSE_iwp9_2006.pdf
+	* VirtFS: A Virtualization Aware File System pass-through
+		http://goo.gl/3WPDg
 
 USAGE
 =====
@@ -130,31 +132,20 @@
 RESOURCES
 =========
 
-Our current recommendation is to use Inferno (http://www.vitanuova.com/nferno/index.html)
-as the 9p server.  You can start a 9p server under Inferno by issuing the
-following command:
-   ; styxlisten -A tcp!*!564 export '#U*'
+Protocol specifications are maintained on github:
+http://ericvh.github.com/9p-rfc/
 
-The -A specifies an unauthenticated export.  The 564 is the port # (you may
-have to choose a higher port number if running as a normal user).  The '#U*'
-specifies exporting the root of the Linux name space.  You may specify a
-subset of the namespace by extending the path: '#U*'/tmp would just export
-/tmp.  For more information, see the Inferno manual pages covering styxlisten
-and export.
+9p client and server implementations are listed on
+http://9p.cat-v.org/implementations
 
-A Linux version of the 9p server is now maintained under the npfs project
-on sourceforge (http://sourceforge.net/projects/npfs).  The currently
-maintained version is the single-threaded version of the server (named spfs)
-available from the same SVN repository.
+A 9p2000.L server is being developed by LLNL and can be found
+at http://code.google.com/p/diod/
 
 There are user and developer mailing lists available through the v9fs project
 on sourceforge (http://sourceforge.net/projects/v9fs).
 
-A stand-alone version of the module (which should build for any 2.6 kernel)
-is available via (http://github.com/ericvh/9p-sac/tree/master)
-
-News and other information is maintained on SWiK (http://swik.net/v9fs)
-and the Wiki (http://sf.net/apps/mediawiki/v9fs/index.php).
+News and other information is maintained on a Wiki.
+(http://sf.net/apps/mediawiki/v9fs/index.php).
 
 Bug reports may be issued through the kernel.org bugzilla 
 (http://bugzilla.kernel.org)
diff -druN linux-2.6.39-libre/Documentation/filesystems/caching/netfs-api.txt linux-3.0-rc7-libre/Documentation/filesystems/caching/netfs-api.txt
--- linux-2.6.39-libre/Documentation/filesystems/caching/netfs-api.txt	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/Documentation/filesystems/caching/netfs-api.txt	2011-07-11 19:51:52.000000000 -0400
@@ -673,6 +673,22 @@
 in which case the page will not be stored in the cache this time.
 
 
+BULK INODE PAGE UNCACHE
+-----------------------
+
+A convenience routine is provided to perform an uncache on all the pages
+attached to an inode.  This assumes that the pages on the inode correspond on a
+1:1 basis with the pages in the cache.
+
+	void fscache_uncache_all_inode_pages(struct fscache_cookie *cookie,
+					     struct inode *inode);
+
+This takes the netfs cookie that the pages were cached with and the inode that
+the pages are attached to.  This function will wait for pages to finish being
+written to the cache and for the cache to finish with the page generally.  No
+error is returned.
+
+
 ==========================
 INDEX AND DATA FILE UPDATE
 ==========================
diff -druN linux-2.6.39-libre/Documentation/filesystems/configfs/configfs_example_explicit.c linux-3.0-rc7-libre/Documentation/filesystems/configfs/configfs_example_explicit.c
--- linux-2.6.39-libre/Documentation/filesystems/configfs/configfs_example_explicit.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/Documentation/filesystems/configfs/configfs_example_explicit.c	2011-07-11 19:51:52.000000000 -0400
@@ -464,9 +464,8 @@
 	return 0;
 
 out_unregister:
-	for (; i >= 0; i--) {
+	for (i--; i >= 0; i--)
 		configfs_unregister_subsystem(example_subsys[i]);
-	}
 
 	return ret;
 }
@@ -475,9 +474,8 @@
 {
 	int i;
 
-	for (i = 0; example_subsys[i]; i++) {
+	for (i = 0; example_subsys[i]; i++)
 		configfs_unregister_subsystem(example_subsys[i]);
-	}
 }
 
 module_init(configfs_example_init);
diff -druN linux-2.6.39-libre/Documentation/filesystems/configfs/configfs_example_macros.c linux-3.0-rc7-libre/Documentation/filesystems/configfs/configfs_example_macros.c
--- linux-2.6.39-libre/Documentation/filesystems/configfs/configfs_example_macros.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/Documentation/filesystems/configfs/configfs_example_macros.c	2011-07-11 19:51:52.000000000 -0400
@@ -427,9 +427,8 @@
 	return 0;
 
 out_unregister:
-	for (; i >= 0; i--) {
+	for (i--; i >= 0; i--)
 		configfs_unregister_subsystem(example_subsys[i]);
-	}
 
 	return ret;
 }
@@ -438,9 +437,8 @@
 {
 	int i;
 
-	for (i = 0; example_subsys[i]; i++) {
+	for (i = 0; example_subsys[i]; i++)
 		configfs_unregister_subsystem(example_subsys[i]);
-	}
 }
 
 module_init(configfs_example_init);
diff -druN linux-2.6.39-libre/Documentation/filesystems/ext4.txt linux-3.0-rc7-libre/Documentation/filesystems/ext4.txt
--- linux-2.6.39-libre/Documentation/filesystems/ext4.txt	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/Documentation/filesystems/ext4.txt	2011-07-11 19:51:52.000000000 -0400
@@ -226,10 +226,6 @@
 noacl			This option disables POSIX Access Control List
 			support.
 
-reservation
-
-noreservation
-
 bsddf		(*)	Make 'df' act like BSD.
 minixdf			Make 'df' act like Minix.
 
diff -druN linux-2.6.39-libre/Documentation/filesystems/Locking linux-3.0-rc7-libre/Documentation/filesystems/Locking
--- linux-2.6.39-libre/Documentation/filesystems/Locking	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/Documentation/filesystems/Locking	2011-07-11 19:51:52.000000000 -0400
@@ -104,7 +104,7 @@
 prototypes:
 	struct inode *(*alloc_inode)(struct super_block *sb);
 	void (*destroy_inode)(struct inode *);
-	void (*dirty_inode) (struct inode *);
+	void (*dirty_inode) (struct inode *, int flags);
 	int (*write_inode) (struct inode *, struct writeback_control *wbc);
 	int (*drop_inode) (struct inode *);
 	void (*evict_inode) (struct inode *);
@@ -126,7 +126,7 @@
 			s_umount
 alloc_inode:
 destroy_inode:
-dirty_inode:				(must not sleep)
+dirty_inode:
 write_inode:
 drop_inode:				!!!inode->i_lock!!!
 evict_inode:
diff -druN linux-2.6.39-libre/Documentation/filesystems/nfs/idmapper.txt linux-3.0-rc7-libre/Documentation/filesystems/nfs/idmapper.txt
--- linux-2.6.39-libre/Documentation/filesystems/nfs/idmapper.txt	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/Documentation/filesystems/nfs/idmapper.txt	2011-07-11 19:51:52.000000000 -0400
@@ -47,8 +47,8 @@
 this case, /some/other/program will handle all uid lookups and
 /usr/sbin/nfs.idmap will handle gid, user, and group lookups.
 
-See <file:Documentation/keys-request-keys.txt> for more information about the
-request-key function.
+See <file:Documentation/security/keys-request-keys.txt> for more information
+about the request-key function.
 
 
 =========
diff -druN linux-2.6.39-libre/Documentation/filesystems/ocfs2.txt linux-3.0-rc7-libre/Documentation/filesystems/ocfs2.txt
--- linux-2.6.39-libre/Documentation/filesystems/ocfs2.txt	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/Documentation/filesystems/ocfs2.txt	2011-07-11 19:51:52.000000000 -0400
@@ -46,9 +46,15 @@
 intr		(*)	Allow signals to interrupt cluster operations.
 nointr			Do not allow signals to interrupt cluster
 			operations.
+noatime			Do not update access time.
+relatime(*)		Update atime if the previous atime is older than
+			mtime or ctime
+strictatime		Always update atime, but the minimum update interval
+			is specified by atime_quantum.
 atime_quantum=60(*)	OCFS2 will not update atime unless this number
 			of seconds has passed since the last update.
-			Set to zero to always update atime.
+			Set to zero to always update atime. This option need
+			work with strictatime.
 data=ordered	(*)	All data are forced directly out to the main file
 			system prior to its metadata being committed to the
 			journal.
diff -druN linux-2.6.39-libre/Documentation/filesystems/proc.txt linux-3.0-rc7-libre/Documentation/filesystems/proc.txt
--- linux-2.6.39-libre/Documentation/filesystems/proc.txt	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/Documentation/filesystems/proc.txt	2011-07-11 19:51:52.000000000 -0400
@@ -574,6 +574,12 @@
   > cat /proc/irq/0/smp_affinity
   ffffffff
 
+There is an alternate interface, smp_affinity_list which allows specifying
+a cpu range instead of a bitmask:
+
+  > cat /proc/irq/0/smp_affinity_list
+  1024-1031
+
 The default_smp_affinity mask applies to all non-active IRQs, which are the
 IRQs which have not yet been allocated/activated, and hence which lack a
 /proc/irq/[0-9]* directory.
@@ -583,12 +589,13 @@
 include information about any possible driver locality preference.
 
 prof_cpu_mask specifies which CPUs are to be profiled by the system wide
-profiler. Default value is ffffffff (all cpus).
+profiler. Default value is ffffffff (all cpus if there are only 32 of them).
 
 The way IRQs are routed is handled by the IO-APIC, and it's Round Robin
 between all the CPUs which are allowed to handle it. As usual the kernel has
 more info than you and does a better job than you, so the defaults are the
-best choice for almost everyone.
+best choice for almost everyone.  [Note this applies only to those IO-APIC's
+that support "Round Robin" interrupt distribution.]
 
 There are  three  more  important subdirectories in /proc: net, scsi, and sys.
 The general  rule  is  that  the  contents,  or  even  the  existence of these
diff -druN linux-2.6.39-libre/Documentation/filesystems/ubifs.txt linux-3.0-rc7-libre/Documentation/filesystems/ubifs.txt
--- linux-2.6.39-libre/Documentation/filesystems/ubifs.txt	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/Documentation/filesystems/ubifs.txt	2011-07-11 19:51:52.000000000 -0400
@@ -115,28 +115,8 @@
 Module Parameters for Debugging
 ===============================
 
-When UBIFS has been compiled with debugging enabled, there are 3 module
+When UBIFS has been compiled with debugging enabled, there are 2 module
 parameters that are available to control aspects of testing and debugging.
-The parameters are unsigned integers where each bit controls an option.
-The parameters are:
-
-debug_msgs	Selects which debug messages to display, as follows:
-
-		Message Type				Flag value
-
-		General messages			1
-		Journal messages			2
-		Mount messages				4
-		Commit messages				8
-		LEB search messages			16
-		Budgeting messages			32
-		Garbage collection messages		64
-		Tree Node Cache (TNC) messages		128
-		LEB properties (lprops) messages	256
-		Input/output messages			512
-		Log messages				1024
-		Scan messages				2048
-		Recovery messages			4096
 
 debug_chks	Selects extra checks that UBIFS can do while running:
 
@@ -154,11 +134,9 @@
 
 		Test mode				Flag value
 
-		Force in-the-gaps method		2
 		Failure mode for recovery testing	4
 
-For example, set debug_msgs to 5 to display General messages and Mount
-messages.
+For example, set debug_chks to 3 to enable general and TNC checks.
 
 
 References
diff -druN linux-2.6.39-libre/Documentation/filesystems/vfs.txt linux-3.0-rc7-libre/Documentation/filesystems/vfs.txt
--- linux-2.6.39-libre/Documentation/filesystems/vfs.txt	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/Documentation/filesystems/vfs.txt	2011-07-11 19:51:52.000000000 -0400
@@ -211,7 +211,7 @@
         struct inode *(*alloc_inode)(struct super_block *sb);
         void (*destroy_inode)(struct inode *);
 
-        void (*dirty_inode) (struct inode *);
+        void (*dirty_inode) (struct inode *, int flags);
         int (*write_inode) (struct inode *, int);
         void (*drop_inode) (struct inode *);
         void (*delete_inode) (struct inode *);
diff -druN linux-2.6.39-libre/Documentation/filesystems/xfs.txt linux-3.0-rc7-libre/Documentation/filesystems/xfs.txt
--- linux-2.6.39-libre/Documentation/filesystems/xfs.txt	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/Documentation/filesystems/xfs.txt	2011-07-11 19:51:52.000000000 -0400
@@ -39,6 +39,12 @@
 	drive level write caching to be enabled, for devices that
 	support write barriers.
 
+  discard
+	Issue command to let the block device reclaim space freed by the
+	filesystem.  This is useful for SSD devices, thinly provisioned
+	LUNs and virtual machine images, but may have a performance
+	impact.  This option is incompatible with the nodelaylog option.
+
   dmapi
 	Enable the DMAPI (Data Management API) event callouts.
 	Use with the "mtpt" option.
diff -druN linux-2.6.39-libre/Documentation/hid/hiddev.txt linux-3.0-rc7-libre/Documentation/hid/hiddev.txt
--- linux-2.6.39-libre/Documentation/hid/hiddev.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/Documentation/hid/hiddev.txt	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,205 @@
+Care and feeding of your Human Interface Devices
+
+INTRODUCTION
+
+In addition to the normal input type HID devices, USB also uses the
+human interface device protocols for things that are not really human
+interfaces, but have similar sorts of communication needs. The two big
+examples for this are power devices (especially uninterruptable power
+supplies) and monitor control on higher end monitors.
+
+To support these disparate requirements, the Linux USB system provides
+HID events to two separate interfaces:
+* the input subsystem, which converts HID events into normal input
+device interfaces (such as keyboard, mouse and joystick) and a
+normalised event interface - see Documentation/input/input.txt
+* the hiddev interface, which provides fairly raw HID events
+
+The data flow for a HID event produced by a device is something like
+the following :
+
+ usb.c ---> hid-core.c  ----> hid-input.c ----> [keyboard/mouse/joystick/event]
+                         |
+                         |
+                          --> hiddev.c ----> POWER / MONITOR CONTROL 
+
+In addition, other subsystems (apart from USB) can potentially feed
+events into the input subsystem, but these have no effect on the hid
+device interface.
+
+USING THE HID DEVICE INTERFACE
+
+The hiddev interface is a char interface using the normal USB major,
+with the minor numbers starting at 96 and finishing at 111. Therefore,
+you need the following commands:
+mknod /dev/usb/hiddev0 c 180 96
+mknod /dev/usb/hiddev1 c 180 97
+mknod /dev/usb/hiddev2 c 180 98
+mknod /dev/usb/hiddev3 c 180 99
+mknod /dev/usb/hiddev4 c 180 100
+mknod /dev/usb/hiddev5 c 180 101
+mknod /dev/usb/hiddev6 c 180 102
+mknod /dev/usb/hiddev7 c 180 103
+mknod /dev/usb/hiddev8 c 180 104
+mknod /dev/usb/hiddev9 c 180 105
+mknod /dev/usb/hiddev10 c 180 106
+mknod /dev/usb/hiddev11 c 180 107
+mknod /dev/usb/hiddev12 c 180 108
+mknod /dev/usb/hiddev13 c 180 109
+mknod /dev/usb/hiddev14 c 180 110
+mknod /dev/usb/hiddev15 c 180 111
+
+So you point your hiddev compliant user-space program at the correct
+interface for your device, and it all just works.
+
+Assuming that you have a hiddev compliant user-space program, of
+course. If you need to write one, read on.
+
+
+THE HIDDEV API
+This description should be read in conjunction with the HID
+specification, freely available from http://www.usb.org, and
+conveniently linked of http://www.linux-usb.org.
+
+The hiddev API uses a read() interface, and a set of ioctl() calls.
+
+HID devices exchange data with the host computer using data
+bundles called "reports".  Each report is divided into "fields",
+each of which can have one or more "usages".  In the hid-core,
+each one of these usages has a single signed 32 bit value.
+
+read():
+This is the event interface.  When the HID device's state changes,
+it performs an interrupt transfer containing a report which contains
+the changed value.  The hid-core.c module parses the report, and
+returns to hiddev.c the individual usages that have changed within
+the report.  In its basic mode, the hiddev will make these individual
+usage changes available to the reader using a struct hiddev_event:
+
+       struct hiddev_event {
+           unsigned hid;
+           signed int value;
+       };
+
+containing the HID usage identifier for the status that changed, and
+the value that it was changed to. Note that the structure is defined
+within <linux/hiddev.h>, along with some other useful #defines and
+structures.  The HID usage identifier is a composite of the HID usage
+page shifted to the 16 high order bits ORed with the usage code.  The
+behavior of the read() function can be modified using the HIDIOCSFLAG
+ioctl() described below.
+
+
+ioctl(): 
+This is the control interface. There are a number of controls: 
+
+HIDIOCGVERSION - int (read)
+Gets the version code out of the hiddev driver.
+
+HIDIOCAPPLICATION - (none)
+This ioctl call returns the HID application usage associated with the
+hid device. The third argument to ioctl() specifies which application
+index to get. This is useful when the device has more than one
+application collection. If the index is invalid (greater or equal to
+the number of application collections this device has) the ioctl
+returns -1. You can find out beforehand how many application
+collections the device has from the num_applications field from the
+hiddev_devinfo structure. 
+
+HIDIOCGCOLLECTIONINFO - struct hiddev_collection_info (read/write)
+This returns a superset of the information above, providing not only
+application collections, but all the collections the device has.  It
+also returns the level the collection lives in the hierarchy.
+The user passes in a hiddev_collection_info struct with the index 
+field set to the index that should be returned.  The ioctl fills in 
+the other fields.  If the index is larger than the last collection 
+index, the ioctl returns -1 and sets errno to -EINVAL.
+
+HIDIOCGDEVINFO - struct hiddev_devinfo (read)
+Gets a hiddev_devinfo structure which describes the device.
+
+HIDIOCGSTRING - struct hiddev_string_descriptor (read/write)
+Gets a string descriptor from the device. The caller must fill in the
+"index" field to indicate which descriptor should be returned.
+
+HIDIOCINITREPORT - (none)
+Instructs the kernel to retrieve all input and feature report values
+from the device. At this point, all the usage structures will contain
+current values for the device, and will maintain it as the device
+changes.  Note that the use of this ioctl is unnecessary in general,
+since later kernels automatically initialize the reports from the
+device at attach time.
+
+HIDIOCGNAME - string (variable length)
+Gets the device name
+
+HIDIOCGREPORT - struct hiddev_report_info (write)
+Instructs the kernel to get a feature or input report from the device,
+in order to selectively update the usage structures (in contrast to
+INITREPORT).
+
+HIDIOCSREPORT - struct hiddev_report_info (write)
+Instructs the kernel to send a report to the device. This report can
+be filled in by the user through HIDIOCSUSAGE calls (below) to fill in
+individual usage values in the report before sending the report in full
+to the device. 
+
+HIDIOCGREPORTINFO - struct hiddev_report_info (read/write)
+Fills in a hiddev_report_info structure for the user. The report is
+looked up by type (input, output or feature) and id, so these fields
+must be filled in by the user. The ID can be absolute -- the actual
+report id as reported by the device -- or relative --
+HID_REPORT_ID_FIRST for the first report, and (HID_REPORT_ID_NEXT |
+report_id) for the next report after report_id. Without a-priori
+information about report ids, the right way to use this ioctl is to
+use the relative IDs above to enumerate the valid IDs. The ioctl
+returns non-zero when there is no more next ID. The real report ID is
+filled into the returned hiddev_report_info structure. 
+
+HIDIOCGFIELDINFO - struct hiddev_field_info (read/write)
+Returns the field information associated with a report in a
+hiddev_field_info structure. The user must fill in report_id and
+report_type in this structure, as above. The field_index should also
+be filled in, which should be a number from 0 and maxfield-1, as
+returned from a previous HIDIOCGREPORTINFO call. 
+
+HIDIOCGUCODE - struct hiddev_usage_ref (read/write)
+Returns the usage_code in a hiddev_usage_ref structure, given that
+given its report type, report id, field index, and index within the
+field have already been filled into the structure.
+
+HIDIOCGUSAGE - struct hiddev_usage_ref (read/write)
+Returns the value of a usage in a hiddev_usage_ref structure. The
+usage to be retrieved can be specified as above, or the user can
+choose to fill in the report_type field and specify the report_id as
+HID_REPORT_ID_UNKNOWN. In this case, the hiddev_usage_ref will be
+filled in with the report and field information associated with this
+usage if it is found. 
+
+HIDIOCSUSAGE - struct hiddev_usage_ref (write)
+Sets the value of a usage in an output report.  The user fills in
+the hiddev_usage_ref structure as above, but additionally fills in
+the value field.
+
+HIDIOGCOLLECTIONINDEX - struct hiddev_usage_ref (write)
+Returns the collection index associated with this usage.  This
+indicates where in the collection hierarchy this usage sits.
+
+HIDIOCGFLAG - int (read)
+HIDIOCSFLAG - int (write)
+These operations respectively inspect and replace the mode flags
+that influence the read() call above.  The flags are as follows:
+
+    HIDDEV_FLAG_UREF - read() calls will now return 
+        struct hiddev_usage_ref instead of struct hiddev_event.
+        This is a larger structure, but in situations where the
+        device has more than one usage in its reports with the
+        same usage code, this mode serves to resolve such
+        ambiguity.
+
+    HIDDEV_FLAG_REPORT - This flag can only be used in conjunction
+        with HIDDEV_FLAG_UREF.  With this flag set, when the device
+        sends a report, a struct hiddev_usage_ref will be returned
+        to read() filled in with the report_type and report_id, but 
+        with field_index set to FIELD_INDEX_NONE.  This serves as
+        additional notification when the device has sent a report.
diff -druN linux-2.6.39-libre/Documentation/hid/hidraw.txt linux-3.0-rc7-libre/Documentation/hid/hidraw.txt
--- linux-2.6.39-libre/Documentation/hid/hidraw.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/Documentation/hid/hidraw.txt	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,119 @@
+      HIDRAW - Raw Access to USB and Bluetooth Human Interface Devices
+     ==================================================================
+
+The hidraw driver provides a raw interface to USB and Bluetooth Human
+Interface Devices (HIDs).  It differs from hiddev in that reports sent and
+received are not parsed by the HID parser, but are sent to and received from
+the device unmodified.
+
+Hidraw should be used if the userspace application knows exactly how to
+communicate with the hardware device, and is able to construct the HID
+reports manually.  This is often the case when making userspace drivers for
+custom HID devices.
+
+Hidraw is also useful for communicating with non-conformant HID devices
+which send and receive data in a way that is inconsistent with their report
+descriptors.  Because hiddev parses reports which are sent and received
+through it, checking them against the device's report descriptor, such
+communication with these non-conformant devices is impossible using hiddev.
+Hidraw is the only alternative, short of writing a custom kernel driver, for
+these non-conformant devices.
+
+A benefit of hidraw is that its use by userspace applications is independent
+of the underlying hardware type.  Currently, Hidraw is implemented for USB
+and Bluetooth.  In the future, as new hardware bus types are developed which
+use the HID specification, hidraw will be expanded to add support for these
+new bus types.
+
+Hidraw uses a dynamic major number, meaning that udev should be relied on to
+create hidraw device nodes.  Udev will typically create the device nodes
+directly under /dev (eg: /dev/hidraw0).  As this location is distribution-
+and udev rule-dependent, applications should use libudev to locate hidraw
+devices attached to the system.  There is a tutorial on libudev with a
+working example at:
+	http://www.signal11.us/oss/udev/
+
+The HIDRAW API
+---------------
+
+read()
+-------
+read() will read a queued report received from the HID device. On USB
+devices, the reports read using read() are the reports sent from the device
+on the INTERRUPT IN endpoint.  By default, read() will block until there is
+a report available to be read.  read() can be made non-blocking, by passing
+the O_NONBLOCK flag to open(), or by setting the O_NONBLOCK flag using
+fcntl().
+
+On a device which uses numbered reports, the first byte of the returned data
+will be the report number; the report data follows, beginning in the second
+byte.  For devices which do not use numbered reports, the report data
+will begin at the first byte.
+
+write()
+--------
+The write() function will write a report to the device. For USB devices, if
+the device has an INTERRUPT OUT endpoint, the report will be sent on that
+endpoint. If it does not, the report will be sent over the control endpoint,
+using a SET_REPORT transfer.
+
+The first byte of the buffer passed to write() should be set to the report
+number.  If the device does not use numbered reports, the first byte should
+be set to 0. The report data itself should begin at the second byte.
+
+ioctl()
+--------
+Hidraw supports the following ioctls:
+
+HIDIOCGRDESCSIZE: Get Report Descriptor Size
+This ioctl will get the size of the device's report descriptor.
+
+HIDIOCGRDESC: Get Report Descriptor
+This ioctl returns the device's report descriptor using a
+hidraw_report_descriptor struct.  Make sure to set the size field of the
+hidraw_report_descriptor struct to the size returned from HIDIOCGRDESCSIZE.
+
+HIDIOCGRAWINFO: Get Raw Info
+This ioctl will return a hidraw_devinfo struct containing the bus type, the
+vendor ID (VID), and product ID (PID) of the device. The bus type can be one
+of:
+	BUS_USB
+	BUS_HIL
+	BUS_BLUETOOTH
+	BUS_VIRTUAL
+which are defined in linux/input.h.
+
+HIDIOCGRAWNAME(len): Get Raw Name
+This ioctl returns a string containing the vendor and product strings of
+the device.  The returned string is Unicode, UTF-8 encoded.
+
+HIDIOCGRAWPHYS(len): Get Physical Address
+This ioctl returns a string representing the physical address of the device.
+For USB devices, the string contains the physical path to the device (the
+USB controller, hubs, ports, etc).  For Bluetooth devices, the string
+contains the hardware (MAC) address of the device.
+
+HIDIOCSFEATURE(len): Send a Feature Report
+This ioctl will send a feature report to the device.  Per the HID
+specification, feature reports are always sent using the control endpoint.
+Set the first byte of the supplied buffer to the report number.  For devices
+which do not use numbered reports, set the first byte to 0. The report data
+begins in the second byte. Make sure to set len accordingly, to one more
+than the length of the report (to account for the report number).
+
+HIDIOCGFEATURE(len): Get a Feature Report
+This ioctl will request a feature report from the device using the control
+endpoint.  The first byte of the supplied buffer should be set to the report
+number of the requested report.  For devices which do not use numbered
+reports, set the first byte to 0.  The report will be returned starting at
+the first byte of the buffer (ie: the report number is not returned).
+
+Example
+---------
+In samples/, find hid-example.c, which shows examples of read(), write(),
+and all the ioctls for hidraw.  The code may be used by anyone for any
+purpose, and can serve as a starting point for developing applications using
+hidraw.
+
+Document by:
+	Alan Ott <alan@signal11.us>, Signal 11 Software
diff -druN linux-2.6.39-libre/Documentation/HOWTO linux-3.0-rc7-libre/Documentation/HOWTO
--- linux-2.6.39-libre/Documentation/HOWTO	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/Documentation/HOWTO	2011-07-11 19:51:52.000000000 -0400
@@ -209,7 +209,7 @@
 Cross-Reference project, which is able to present source code in a
 self-referential, indexed webpage format. An excellent up-to-date
 repository of the kernel code may be found at:
-	http://users.sosdg.org/~qiyong/lxr/
+	http://lxr.linux.no/+trees
 
 
 The development process
diff -druN linux-2.6.39-libre/Documentation/hwmon/adm1275 linux-3.0-rc7-libre/Documentation/hwmon/adm1275
--- linux-2.6.39-libre/Documentation/hwmon/adm1275	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/Documentation/hwmon/adm1275	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,60 @@
+Kernel driver adm1275
+=====================
+
+Supported chips:
+  * Analog Devices ADM1275
+    Prefix: 'adm1275'
+    Addresses scanned: -
+    Datasheet: www.analog.com/static/imported-files/data_sheets/ADM1275.pdf
+
+Author: Guenter Roeck <guenter.roeck@ericsson.com>
+
+
+Description
+-----------
+
+This driver supports hardware montoring for Analog Devices ADM1275 Hot-Swap
+Controller and Digital Power Monitor.
+
+The ADM1275 is a hot-swap controller that allows a circuit board to be removed
+from or inserted into a live backplane. It also features current and voltage
+readback via an integrated 12-bit analog-to-digital converter (ADC), accessed
+using a PMBus. interface.
+
+The driver is a client driver to the core PMBus driver. Please see
+Documentation/hwmon/pmbus for details on PMBus client drivers.
+
+
+Usage Notes
+-----------
+
+This driver does not auto-detect devices. You will have to instantiate the
+devices explicitly. Please see Documentation/i2c/instantiating-devices for
+details.
+
+
+Platform data support
+---------------------
+
+The driver supports standard PMBus driver platform data. Please see
+Documentation/hwmon/pmbus for details.
+
+
+Sysfs entries
+-------------
+
+The following attributes are supported. Limits are read-write; all other
+attributes are read-only.
+
+in1_label		"vin1" or "vout1" depending on chip variant and
+			configuration.
+in1_input		Measured voltage. From READ_VOUT register.
+in1_min			Minumum Voltage. From VOUT_UV_WARN_LIMIT register.
+in1_max			Maximum voltage. From VOUT_OV_WARN_LIMIT register.
+in1_min_alarm		Voltage low alarm. From VOLTAGE_UV_WARNING status.
+in1_max_alarm		Voltage high alarm. From VOLTAGE_OV_WARNING status.
+
+curr1_label		"iout1"
+curr1_input		Measured current. From READ_IOUT register.
+curr1_max		Maximum current. From IOUT_OC_WARN_LIMIT register.
+curr1_max_alarm		Current high alarm. From IOUT_OC_WARN_LIMIT register.
diff -druN linux-2.6.39-libre/Documentation/hwmon/coretemp linux-3.0-rc7-libre/Documentation/hwmon/coretemp
--- linux-2.6.39-libre/Documentation/hwmon/coretemp	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/Documentation/hwmon/coretemp	2011-07-11 19:51:52.000000000 -0400
@@ -15,8 +15,13 @@
 
 Description
 -----------
+This driver permits reading the DTS (Digital Temperature Sensor) embedded
+inside Intel CPUs. This driver can read both the per-core and per-package
+temperature using the appropriate sensors. The per-package sensor is new;
+as of now, it is present only in the SandyBridge platform. The driver will
+show the temperature of all cores inside a package under a single device
+directory inside hwmon.
 
-This driver permits reading temperature sensor embedded inside Intel Core CPU.
 Temperature is measured in degrees Celsius and measurement resolution is
 1 degree C. Valid temperatures are from 0 to TjMax degrees C, because
 the actual value of temperature register is in fact a delta from TjMax.
@@ -27,13 +32,15 @@
 may be raised, if the temperature grows enough (more than TjMax) to trigger
 the Out-Of-Spec bit. Following table summarizes the exported sysfs files:
 
-temp1_input	 - Core temperature (in millidegrees Celsius).
-temp1_max	 - All cooling devices should be turned on (on Core2).
-temp1_crit	 - Maximum junction temperature (in millidegrees Celsius).
-temp1_crit_alarm - Set when Out-of-spec bit is set, never clears.
+All Sysfs entries are named with their core_id (represented here by 'X').
+tempX_input	 - Core temperature (in millidegrees Celsius).
+tempX_max	 - All cooling devices should be turned on (on Core2).
+tempX_crit	 - Maximum junction temperature (in millidegrees Celsius).
+tempX_crit_alarm - Set when Out-of-spec bit is set, never clears.
 		   Correct CPU operation is no longer guaranteed.
-temp1_label	 - Contains string "Core X", where X is processor
-		   number.
+tempX_label	 - Contains string "Core X", where X is processor
+		   number. For Package temp, this will be "Physical id Y",
+		   where Y is the package number.
 
 The TjMax temperature is set to 85 degrees C if undocumented model specific
 register (UMSR) 0xee has bit 30 set. If not the TjMax is 100 degrees C as
diff -druN linux-2.6.39-libre/Documentation/hwmon/emc6w201 linux-3.0-rc7-libre/Documentation/hwmon/emc6w201
--- linux-2.6.39-libre/Documentation/hwmon/emc6w201	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/Documentation/hwmon/emc6w201	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,42 @@
+Kernel driver emc6w201
+======================
+
+Supported chips:
+  * SMSC EMC6W201
+    Prefix: 'emc6w201'
+    Addresses scanned: I2C 0x2c, 0x2d, 0x2e
+    Datasheet: Not public
+
+Author: Jean Delvare <khali@linux-fr.org>
+
+
+Description
+-----------
+
+From the datasheet:
+
+"The EMC6W201 is an environmental monitoring device with automatic fan
+control capability and enhanced system acoustics for noise suppression.
+This ACPI compliant device provides hardware monitoring for up to six
+voltages (including its own VCC) and five external thermal sensors,
+measures the speed of up to five fans, and controls the speed of
+multiple DC fans using three Pulse Width Modulator (PWM) outputs. Note
+that it is possible to control more than three fans by connecting two
+fans to one PWM output. The EMC6W201 will be available in a 36-pin
+QFN package."
+
+The device is functionally close to the EMC6D100 series, but is
+register-incompatible.
+
+The driver currently only supports the monitoring of the voltages,
+temperatures and fan speeds. Limits can be changed. Alarms are not
+supported, and neither is fan speed control.
+
+
+Known Systems With EMC6W201
+---------------------------
+
+The EMC6W201 is a rare device, only found on a few systems, made in
+2005 and 2006. Known systems with this device:
+* Dell Precision 670 workstation
+* Gigabyte 2CEWH mainboard
diff -druN linux-2.6.39-libre/Documentation/hwmon/f71882fg linux-3.0-rc7-libre/Documentation/hwmon/f71882fg
--- linux-2.6.39-libre/Documentation/hwmon/f71882fg	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/Documentation/hwmon/f71882fg	2011-07-11 19:51:52.000000000 -0400
@@ -6,6 +6,10 @@
     Prefix: 'f71808e'
     Addresses scanned: none, address read from Super I/O config space
     Datasheet: Not public
+  * Fintek F71808A
+    Prefix: 'f71808a'
+    Addresses scanned: none, address read from Super I/O config space
+    Datasheet: Not public
   * Fintek F71858FG
     Prefix: 'f71858fg'
     Addresses scanned: none, address read from Super I/O config space
@@ -18,6 +22,10 @@
     Prefix: 'f71869'
     Addresses scanned: none, address read from Super I/O config space
     Datasheet: Available from the Fintek website
+  * Fintek F71869A
+    Prefix: 'f71869a'
+    Addresses scanned: none, address read from Super I/O config space
+    Datasheet: Not public
   * Fintek F71882FG and F71883FG
     Prefix: 'f71882fg'
     Addresses scanned: none, address read from Super I/O config space
diff -druN linux-2.6.39-libre/Documentation/hwmon/fam15h_power linux-3.0-rc7-libre/Documentation/hwmon/fam15h_power
--- linux-2.6.39-libre/Documentation/hwmon/fam15h_power	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/Documentation/hwmon/fam15h_power	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,37 @@
+Kernel driver fam15h_power
+==========================
+
+Supported chips:
+* AMD Family 15h Processors
+
+  Prefix: 'fam15h_power'
+  Addresses scanned: PCI space
+  Datasheets:
+  BIOS and Kernel Developer's Guide (BKDG) For AMD Family 15h Processors
+    (not yet published)
+
+Author: Andreas Herrmann <andreas.herrmann3@amd.com>
+
+Description
+-----------
+
+This driver permits reading of registers providing power information
+of AMD Family 15h processors.
+
+For AMD Family 15h processors the following power values can be
+calculated using different processor northbridge function registers:
+
+* BasePwrWatts: Specifies in watts the maximum amount of power
+  consumed by the processor for NB and logic external to the core.
+* ProcessorPwrWatts: Specifies in watts the maximum amount of power
+  the processor can support.
+* CurrPwrWatts: Specifies in watts the current amount of power being
+  consumed by the processor.
+
+This driver provides ProcessorPwrWatts and CurrPwrWatts:
+* power1_crit (ProcessorPwrWatts)
+* power1_input (CurrPwrWatts)
+
+On multi-node processors the calculated value is for the entire
+package and not for a single node. Thus the driver creates sysfs
+attributes only for internal node0 of a multi-node processor.
diff -druN linux-2.6.39-libre/Documentation/hwmon/k10temp linux-3.0-rc7-libre/Documentation/hwmon/k10temp
--- linux-2.6.39-libre/Documentation/hwmon/k10temp	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/Documentation/hwmon/k10temp	2011-07-11 19:51:52.000000000 -0400
@@ -9,8 +9,9 @@
   Socket S1G3: Athlon II, Sempron, Turion II
 * AMD Family 11h processors:
   Socket S1G2: Athlon (X2), Sempron (X2), Turion X2 (Ultra)
-* AMD Family 12h processors: "Llano"
-* AMD Family 14h processors: "Brazos" (C/E/G-Series)
+* AMD Family 12h processors: "Llano" (E2/A4/A6/A8-Series)
+* AMD Family 14h processors: "Brazos" (C/E/G/Z-Series)
+* AMD Family 15h processors: "Bulldozer"
 
   Prefix: 'k10temp'
   Addresses scanned: PCI space
@@ -19,12 +20,16 @@
     http://support.amd.com/us/Processor_TechDocs/31116.pdf
   BIOS and Kernel Developer's Guide (BKDG) for AMD Family 11h Processors:
     http://support.amd.com/us/Processor_TechDocs/41256.pdf
+  BIOS and Kernel Developer's Guide (BKDG) for AMD Family 12h Processors:
+    http://support.amd.com/us/Processor_TechDocs/41131.pdf
   BIOS and Kernel Developer's Guide (BKDG) for AMD Family 14h Models 00h-0Fh Processors:
     http://support.amd.com/us/Processor_TechDocs/43170.pdf
   Revision Guide for AMD Family 10h Processors:
     http://support.amd.com/us/Processor_TechDocs/41322.pdf
   Revision Guide for AMD Family 11h Processors:
     http://support.amd.com/us/Processor_TechDocs/41788.pdf
+  Revision Guide for AMD Family 12h Processors:
+    http://support.amd.com/us/Processor_TechDocs/44739.pdf
   Revision Guide for AMD Family 14h Models 00h-0Fh Processors:
     http://support.amd.com/us/Processor_TechDocs/47534.pdf
   AMD Family 11h Processor Power and Thermal Data Sheet for Notebooks:
@@ -40,7 +45,7 @@
 -----------
 
 This driver permits reading of the internal temperature sensor of AMD
-Family 10h/11h/12h/14h processors.
+Family 10h/11h/12h/14h/15h processors.
 
 All these processors have a sensor, but on those for Socket F or AM2+,
 the sensor may return inconsistent values (erratum 319).  The driver
diff -druN linux-2.6.39-libre/Documentation/hwmon/max16065 linux-3.0-rc7-libre/Documentation/hwmon/max16065
--- linux-2.6.39-libre/Documentation/hwmon/max16065	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/Documentation/hwmon/max16065	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,98 @@
+Kernel driver max16065
+======================
+
+Supported chips:
+  * Maxim MAX16065, MAX16066
+    Prefixes: 'max16065', 'max16066'
+    Addresses scanned: -
+    Datasheet:
+	http://datasheets.maxim-ic.com/en/ds/MAX16065-MAX16066.pdf
+ *  Maxim MAX16067
+    Prefix: 'max16067'
+    Addresses scanned: -
+    Datasheet:
+	http://datasheets.maxim-ic.com/en/ds/MAX16067.pdf
+ *  Maxim MAX16068
+    Prefix: 'max16068'
+    Addresses scanned: -
+    Datasheet:
+	http://datasheets.maxim-ic.com/en/ds/MAX16068.pdf
+ *  Maxim MAX16070/MAX16071
+    Prefixes: 'max16070', 'max16071'
+    Addresses scanned: -
+    Datasheet:
+	http://datasheets.maxim-ic.com/en/ds/MAX16070-MAX16071.pdf
+
+
+Author: Guenter Roeck <guenter.roeck@ericsson.com>
+
+
+Description
+-----------
+
+[From datasheets] The MAX16065/MAX16066 flash-configurable system managers
+monitor and sequence multiple system voltages. The MAX16065/MAX16066 can also
+accurately monitor (+/-2.5%) one current channel using a dedicated high-side
+current-sense amplifier. The MAX16065 manages up to twelve system voltages
+simultaneously, and the MAX16066 manages up to eight supply voltages.
+
+The MAX16067 flash-configurable system manager monitors and sequences multiple
+system voltages. The MAX16067 manages up to six system voltages simultaneously.
+
+The MAX16068 flash-configurable system manager monitors and manages up to six
+system voltages simultaneously.
+
+The MAX16070/MAX16071 flash-configurable system monitors supervise multiple
+system voltages. The MAX16070/MAX16071 can also accurately monitor (+/-2.5%)
+one current channel using a dedicated high-side current-sense amplifier. The
+MAX16070 monitors up to twelve system voltages simultaneously, and the MAX16071
+monitors up to eight supply voltages.
+
+Each monitored channel has its own low and high critical limits. MAX16065,
+MAX16066, MAX16070, and MAX16071 support an additional limit which is
+configurable as either low or high secondary limit. MAX16065, MAX16066,
+MAX16070, and MAX16071 also support supply current monitoring.
+
+
+Usage Notes
+-----------
+
+This driver does not probe for devices, since there is no register which
+can be safely used to identify the chip. You will have to instantiate
+the devices explicitly. Please see Documentation/i2c/instantiating-devices for
+details.
+
+
+Sysfs entries
+-------------
+
+in[0-11]_input		Input voltage measurements.
+
+in12_input		Voltage on CSP (Current Sense Positive) pin.
+			Only if the chip supports current sensing and if
+			current sensing is enabled.
+
+in[0-11]_min		Low warning limit.
+			Supported on MAX16065, MAX16066, MAX16070, and MAX16071
+			only.
+
+in[0-11]_max		High warning limit.
+			Supported on MAX16065, MAX16066, MAX16070, and MAX16071
+			only.
+
+			Either low or high warning limits are supported
+			(depending on chip configuration), but not both.
+
+in[0-11]_lcrit		Low critical limit.
+
+in[0-11]_crit		High critical limit.
+
+in[0-11]_alarm		Input voltage alarm.
+
+curr1_input		Current sense input; only if the chip supports current
+			sensing and if current sensing is enabled.
+			Displayed current assumes 0.001 Ohm current sense
+			resistor.
+
+curr1_alarm		Overcurrent alarm; only if the chip supports current
+			sensing and if current sensing is enabled.
diff -druN linux-2.6.39-libre/Documentation/hwmon/max6642 linux-3.0-rc7-libre/Documentation/hwmon/max6642
--- linux-2.6.39-libre/Documentation/hwmon/max6642	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/Documentation/hwmon/max6642	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,21 @@
+Kernel driver max6642
+=====================
+
+Supported chips:
+  * Maxim MAX6642
+    Prefix: 'max6642'
+    Addresses scanned: I2C 0x48-0x4f
+    Datasheet: Publicly available at the Maxim website
+               http://datasheets.maxim-ic.com/en/ds/MAX6642.pdf
+
+Authors:
+        Per Dalen <per.dalen@appeartv.com>
+
+Description
+-----------
+
+The MAX6642 is a digital temperature sensor. It senses its own temperature as
+well as the temperature on one external diode.
+
+All temperature values are given in degrees Celsius. Resolution
+is 0.25 degree for the local temperature and for the remote temperature.
diff -druN linux-2.6.39-libre/Documentation/hwmon/max6650 linux-3.0-rc7-libre/Documentation/hwmon/max6650
--- linux-2.6.39-libre/Documentation/hwmon/max6650	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/Documentation/hwmon/max6650	2011-07-11 19:51:52.000000000 -0400
@@ -2,9 +2,13 @@
 =====================
 
 Supported chips:
-  * Maxim 6650 / 6651
+  * Maxim MAX6650
     Prefix: 'max6650'
-    Addresses scanned: I2C 0x1b, 0x1f, 0x48, 0x4b
+    Addresses scanned: none
+    Datasheet: http://pdfserv.maxim-ic.com/en/ds/MAX6650-MAX6651.pdf
+  * Maxim MAX6651
+    Prefix: 'max6651'
+    Addresses scanned: none
     Datasheet: http://pdfserv.maxim-ic.com/en/ds/MAX6650-MAX6651.pdf
 
 Authors:
@@ -15,10 +19,10 @@
 Description
 -----------
 
-This driver implements support for the Maxim 6650/6651
+This driver implements support for the Maxim MAX6650 and MAX6651.
 
-The 2 devices are very similar, but the Maxim 6550 has a reduced feature
-set, e.g. only one fan-input, instead of 4 for the 6651.
+The 2 devices are very similar, but the MAX6550 has a reduced feature
+set, e.g. only one fan-input, instead of 4 for the MAX6651.
 
 The driver is not able to distinguish between the 2 devices.
 
@@ -36,6 +40,13 @@
 			values are 1, 2, 4, and 8. Use lower values for
 			faster fans.
 
+Usage notes
+-----------
+
+This driver does not auto-detect devices. You will have to instantiate the
+devices explicitly. Please see Documentation/i2c/instantiating-devices for
+details.
+
 Module parameters
 -----------------
 
diff -druN linux-2.6.39-libre/Documentation/hwmon/pkgtemp linux-3.0-rc7-libre/Documentation/hwmon/pkgtemp
--- linux-2.6.39-libre/Documentation/hwmon/pkgtemp	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/Documentation/hwmon/pkgtemp	1969-12-31 19:00:00.000000000 -0500
@@ -1,36 +0,0 @@
-Kernel driver pkgtemp
-======================
-
-Supported chips:
-  * Intel family
-    Prefix: 'pkgtemp'
-    CPUID:
-    Datasheet: Intel 64 and IA-32 Architectures Software Developer's Manual
-               Volume 3A: System Programming Guide
-
-Author: Fenghua Yu
-
-Description
------------
-
-This driver permits reading package level temperature sensor embedded inside
-Intel CPU package. The sensors can be in core, uncore, memory controller, or
-other components in a package. The feature is first implemented in Intel Sandy
-Bridge platform.
-
-Temperature is measured in degrees Celsius and measurement resolution is
-1 degree C. Valid temperatures are from 0 to TjMax degrees C, because the actual
-value of temperature register is in fact a delta from TjMax.
-
-Temperature known as TjMax is the maximum junction temperature of package.
-We get this from MSR_IA32_TEMPERATURE_TARGET. If the MSR is not accessible,
-we define TjMax as 100 degrees Celsius. At this temperature, protection
-mechanism will perform actions to forcibly cool down the package. Alarm
-may be raised, if the temperature grows enough (more than TjMax) to trigger
-the Out-Of-Spec bit. Following table summarizes the exported sysfs files:
-
-temp1_input	  - Package temperature (in millidegrees Celsius).
-temp1_max        - All cooling devices should be turned on.
-temp1_crit	  - Maximum junction temperature (in millidegrees Celsius).
-temp1_crit_alarm - Set when Out-of-spec bit is set, never clears.
-		    Correct CPU operation is no longer guaranteed.
diff -druN linux-2.6.39-libre/Documentation/hwmon/sht15 linux-3.0-rc7-libre/Documentation/hwmon/sht15
--- linux-2.6.39-libre/Documentation/hwmon/sht15	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/Documentation/hwmon/sht15	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,74 @@
+Kernel driver sht15
+===================
+
+Authors:
+  * Wouter Horre
+  * Jonathan Cameron
+  * Vivien Didelot <vivien.didelot@savoirfairelinux.com>
+  * Jerome Oufella <jerome.oufella@savoirfairelinux.com>
+
+Supported chips:
+  * Sensirion SHT10
+    Prefix: 'sht10'
+
+  * Sensirion SHT11
+    Prefix: 'sht11'
+
+  * Sensirion SHT15
+    Prefix: 'sht15'
+
+  * Sensirion SHT71
+    Prefix: 'sht71'
+
+  * Sensirion SHT75
+    Prefix: 'sht75'
+
+Datasheet: Publicly available at the Sensirion website
+http://www.sensirion.ch/en/pdf/product_information/Datasheet-humidity-sensor-SHT1x.pdf
+
+Description
+-----------
+
+The SHT10, SHT11, SHT15, SHT71, and SHT75 are humidity and temperature
+sensors.
+
+The devices communicate using two GPIO lines.
+
+Supported resolutions for the measurements are 14 bits for temperature and 12
+bits for humidity, or 12 bits for temperature and 8 bits for humidity.
+
+The humidity calibration coefficients are programmed into an OTP memory on the
+chip. These coefficients are used to internally calibrate the signals from the
+sensors. Disabling the reload of those coefficients allows saving 10ms for each
+measurement and decrease power consumption, while loosing on precision.
+
+Some options may be set directly in the sht15_platform_data structure
+or via sysfs attributes.
+
+Notes:
+  * The regulator supply name is set to "vcc".
+  * If a CRC validation fails, a soft reset command is sent, which resets
+    status register to its hardware default value, but the driver will try to
+    restore the previous device configuration.
+
+Platform data
+-------------
+
+* checksum:
+  set it to true to enable CRC validation of the readings (default to false).
+* no_otp_reload:
+  flag to indicate not to reload from OTP (default to false).
+* low_resolution:
+  flag to indicate the temp/humidity resolution to use (default to false).
+
+Sysfs interface
+---------------
+
+* temp1_input:     temperature input
+* humidity1_input: humidity input
+* heater_enable:   write 1 in this attribute to enable the on-chip heater,
+                   0 to disable it. Be careful not to enable the heater
+                   for too long.
+* temp1_fault:     if 1, this means that the voltage is low (below 2.47V) and
+                   measurement may be invalid.
+* humidity1_fault: same as temp1_fault.
diff -druN linux-2.6.39-libre/Documentation/hwmon/ucd9000 linux-3.0-rc7-libre/Documentation/hwmon/ucd9000
--- linux-2.6.39-libre/Documentation/hwmon/ucd9000	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/Documentation/hwmon/ucd9000	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,110 @@
+Kernel driver ucd9000
+=====================
+
+Supported chips:
+  * TI UCD90120, UCD90124, UCD9090, and UCD90910
+    Prefixes: 'ucd90120', 'ucd90124', 'ucd9090', 'ucd90910'
+    Addresses scanned: -
+    Datasheets:
+	http://focus.ti.com/lit/ds/symlink/ucd90120.pdf
+	http://focus.ti.com/lit/ds/symlink/ucd90124.pdf
+	http://focus.ti.com/lit/ds/symlink/ucd9090.pdf
+	http://focus.ti.com/lit/ds/symlink/ucd90910.pdf
+
+Author: Guenter Roeck <guenter.roeck@ericsson.com>
+
+
+Description
+-----------
+
+From datasheets:
+
+The UCD90120 Power Supply Sequencer and System Health Monitor monitors and
+sequences up to 12 independent voltage rails. The device integrates a 12-bit
+ADC with a 2.5V internal reference for monitoring up to 13 power supply voltage,
+current, or temperature inputs.
+
+The UCD90124 is a 12-rail PMBus/I2C addressable power-supply sequencer and
+system-health monitor. The device integrates a 12-bit ADC for monitoring up to
+13 power-supply voltage, current, or temperature inputs. Twenty-six GPIO pins
+can be used for power supply enables, power-on reset signals, external
+interrupts, cascading, or other system functions. Twelve of these pins offer PWM
+functionality. Using these pins, the UCD90124 offers support for fan control,
+margining, and general-purpose PWM functions.
+
+The UCD9090 is a 10-rail PMBus/I2C addressable power-supply sequencer and
+monitor. The device integrates a 12-bit ADC for monitoring up to 10 power-supply
+voltage inputs. Twenty-three GPIO pins can be used for power supply enables,
+power-on reset signals, external interrupts, cascading, or other system
+functions. Ten of these pins offer PWM functionality. Using these pins, the
+UCD9090 offers support for margining, and general-purpose PWM functions.
+
+The UCD90910 is a ten-rail I2C / PMBus addressable power-supply sequencer and
+system-health monitor. The device integrates a 12-bit ADC for monitoring up to
+13 power-supply voltage, current, or temperature inputs.
+
+This driver is a client driver to the core PMBus driver. Please see
+Documentation/hwmon/pmbus for details on PMBus client drivers.
+
+
+Usage Notes
+-----------
+
+This driver does not auto-detect devices. You will have to instantiate the
+devices explicitly. Please see Documentation/i2c/instantiating-devices for
+details.
+
+
+Platform data support
+---------------------
+
+The driver supports standard PMBus driver platform data. Please see
+Documentation/hwmon/pmbus for details.
+
+
+Sysfs entries
+-------------
+
+The following attributes are supported. Limits are read-write; all other
+attributes are read-only.
+
+in[1-12]_label		"vout[1-12]".
+in[1-12]_input		Measured voltage. From READ_VOUT register.
+in[1-12]_min		Minumum Voltage. From VOUT_UV_WARN_LIMIT register.
+in[1-12]_max		Maximum voltage. From VOUT_OV_WARN_LIMIT register.
+in[1-12]_lcrit		Critical minumum Voltage. VOUT_UV_FAULT_LIMIT register.
+in[1-12]_crit		Critical maximum voltage. From VOUT_OV_FAULT_LIMIT register.
+in[1-12]_min_alarm	Voltage low alarm. From VOLTAGE_UV_WARNING status.
+in[1-12]_max_alarm	Voltage high alarm. From VOLTAGE_OV_WARNING status.
+in[1-12]_lcrit_alarm	Voltage critical low alarm. From VOLTAGE_UV_FAULT status.
+in[1-12]_crit_alarm	Voltage critical high alarm. From VOLTAGE_OV_FAULT status.
+
+curr[1-12]_label	"iout[1-12]".
+curr[1-12]_input	Measured current. From READ_IOUT register.
+curr[1-12]_max		Maximum current. From IOUT_OC_WARN_LIMIT register.
+curr[1-12]_lcrit	Critical minumum output current. From IOUT_UC_FAULT_LIMIT
+			register.
+curr[1-12]_crit		Critical maximum current. From IOUT_OC_FAULT_LIMIT register.
+curr[1-12]_max_alarm	Current high alarm. From IOUT_OC_WARNING status.
+curr[1-12]_crit_alarm	Current critical high alarm. From IOUT_OC_FAULT status.
+
+			For each attribute index, either voltage or current is
+			reported, but not both. If voltage or current is
+			reported depends on the chip configuration.
+
+temp[1-2]_input		Measured temperatures. From READ_TEMPERATURE_1 and
+			READ_TEMPERATURE_2 registers.
+temp[1-2]_max		Maximum temperature. From OT_WARN_LIMIT register.
+temp[1-2]_crit		Critical high temperature. From OT_FAULT_LIMIT register.
+temp[1-2]_max_alarm	Temperature high alarm.
+temp[1-2]_crit_alarm	Temperature critical high alarm.
+
+fan[1-4]_input		Fan RPM.
+fan[1-4]_alarm		Fan alarm.
+fan[1-4]_fault		Fan fault.
+
+			Fan attributes are only available on chips supporting
+			fan control (UCD90124, UCD90910). Attribute files are
+			created only for enabled fans.
+			Note that even though UCD90910 supports up to 10 fans,
+			only up to four fans are currently supported.
diff -druN linux-2.6.39-libre/Documentation/hwmon/ucd9200 linux-3.0-rc7-libre/Documentation/hwmon/ucd9200
--- linux-2.6.39-libre/Documentation/hwmon/ucd9200	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/Documentation/hwmon/ucd9200	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,112 @@
+Kernel driver ucd9200
+=====================
+
+Supported chips:
+  * TI UCD9220, UCD9222, UCD9224, UCD9240, UCD9244, UCD9246, and UCD9248
+    Prefixes: 'ucd9220', 'ucd9222', 'ucd9224', 'ucd9240', 'ucd9244', 'ucd9246',
+	'ucd9248'
+    Addresses scanned: -
+    Datasheets:
+	http://focus.ti.com/lit/ds/symlink/ucd9220.pdf
+	http://focus.ti.com/lit/ds/symlink/ucd9222.pdf
+	http://focus.ti.com/lit/ds/symlink/ucd9224.pdf
+	http://focus.ti.com/lit/ds/symlink/ucd9240.pdf
+	http://focus.ti.com/lit/ds/symlink/ucd9244.pdf
+	http://focus.ti.com/lit/ds/symlink/ucd9246.pdf
+	http://focus.ti.com/lit/ds/symlink/ucd9248.pdf
+
+Author: Guenter Roeck <guenter.roeck@ericsson.com>
+
+
+Description
+-----------
+
+[From datasheets] UCD9220, UCD9222, UCD9224, UCD9240, UCD9244, UCD9246, and
+UCD9248 are multi-rail, multi-phase synchronous buck digital PWM controllers
+designed for non-isolated DC/DC power applications. The devices integrate
+dedicated circuitry for DC/DC loop management with flash memory and a serial
+interface to support configuration, monitoring and management.
+
+This driver is a client driver to the core PMBus driver. Please see
+Documentation/hwmon/pmbus for details on PMBus client drivers.
+
+
+Usage Notes
+-----------
+
+This driver does not auto-detect devices. You will have to instantiate the
+devices explicitly. Please see Documentation/i2c/instantiating-devices for
+details.
+
+
+Platform data support
+---------------------
+
+The driver supports standard PMBus driver platform data. Please see
+Documentation/hwmon/pmbus for details.
+
+
+Sysfs entries
+-------------
+
+The following attributes are supported. Limits are read-write; all other
+attributes are read-only.
+
+in1_label		"vin".
+in1_input		Measured voltage. From READ_VIN register.
+in1_min			Minumum Voltage. From VIN_UV_WARN_LIMIT register.
+in1_max			Maximum voltage. From VIN_OV_WARN_LIMIT register.
+in1_lcrit		Critical minumum Voltage. VIN_UV_FAULT_LIMIT register.
+in1_crit		Critical maximum voltage. From VIN_OV_FAULT_LIMIT register.
+in1_min_alarm		Voltage low alarm. From VIN_UV_WARNING status.
+in1_max_alarm		Voltage high alarm. From VIN_OV_WARNING status.
+in1_lcrit_alarm		Voltage critical low alarm. From VIN_UV_FAULT status.
+in1_crit_alarm		Voltage critical high alarm. From VIN_OV_FAULT status.
+
+in[2-5]_label		"vout[1-4]".
+in[2-5]_input		Measured voltage. From READ_VOUT register.
+in[2-5]_min		Minumum Voltage. From VOUT_UV_WARN_LIMIT register.
+in[2-5]_max		Maximum voltage. From VOUT_OV_WARN_LIMIT register.
+in[2-5]_lcrit		Critical minumum Voltage. VOUT_UV_FAULT_LIMIT register.
+in[2-5]_crit		Critical maximum voltage. From VOUT_OV_FAULT_LIMIT register.
+in[2-5]_min_alarm	Voltage low alarm. From VOLTAGE_UV_WARNING status.
+in[2-5]_max_alarm	Voltage high alarm. From VOLTAGE_OV_WARNING status.
+in[2-5]_lcrit_alarm	Voltage critical low alarm. From VOLTAGE_UV_FAULT status.
+in[2-5]_crit_alarm	Voltage critical high alarm. From VOLTAGE_OV_FAULT status.
+
+curr1_label		"iin".
+curr1_input		Measured current. From READ_IIN register.
+
+curr[2-5]_label		"iout[1-4]".
+curr[2-5]_input		Measured current. From READ_IOUT register.
+curr[2-5]_max		Maximum current. From IOUT_OC_WARN_LIMIT register.
+curr[2-5]_lcrit		Critical minumum output current. From IOUT_UC_FAULT_LIMIT
+			register.
+curr[2-5]_crit		Critical maximum current. From IOUT_OC_FAULT_LIMIT register.
+curr[2-5]_max_alarm	Current high alarm. From IOUT_OC_WARNING status.
+curr[2-5]_crit_alarm	Current critical high alarm. From IOUT_OC_FAULT status.
+
+power1_input		Measured input power. From READ_PIN register.
+power1_label		"pin"
+
+power[2-5]_input	Measured output power. From READ_POUT register.
+power[2-5]_label	"pout[1-4]"
+
+			The number of output voltage, current, and power
+			attribute sets is determined by the number of enabled
+			rails. See chip datasheets for details.
+
+temp[1-5]_input		Measured temperatures. From READ_TEMPERATURE_1 and
+		        READ_TEMPERATURE_2 registers.
+			temp1 is the chip internal temperature. temp[2-5] are
+			rail temperatures.  temp[2-5] attributes are only
+			created for enabled rails. See chip datasheets for
+			details.
+temp[1-5]_max		Maximum temperature. From OT_WARN_LIMIT register.
+temp[1-5]_crit		Critical high temperature. From OT_FAULT_LIMIT register.
+temp[1-5]_max_alarm	Temperature high alarm.
+temp[1-5]_crit_alarm	Temperature critical high alarm.
+
+fan1_input		Fan RPM. ucd9240 only.
+fan1_alarm		Fan alarm. ucd9240 only.
+fan1_fault		Fan fault. ucd9240 only.
diff -druN linux-2.6.39-libre/Documentation/i2c/busses/i2c-i801 linux-3.0-rc7-libre/Documentation/i2c/busses/i2c-i801
--- linux-2.6.39-libre/Documentation/i2c/busses/i2c-i801	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/Documentation/i2c/busses/i2c-i801	2011-07-11 19:51:52.000000000 -0400
@@ -19,6 +19,7 @@
   * Intel 6 Series (PCH)
   * Intel Patsburg (PCH)
   * Intel DH89xxCC (PCH)
+  * Intel Panther Point (PCH)
    Datasheets: Publicly available at the Intel website
 
 On Intel Patsburg and later chipsets, both the normal host SMBus controller
diff -druN linux-2.6.39-libre/Documentation/i2c/writing-clients linux-3.0-rc7-libre/Documentation/i2c/writing-clients
--- linux-2.6.39-libre/Documentation/i2c/writing-clients	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/Documentation/i2c/writing-clients	2011-07-11 19:51:52.000000000 -0400
@@ -38,7 +38,7 @@
 		.name	= "foo",
 	},
 
-	.id_table	= foo_ids,
+	.id_table	= foo_idtable,
 	.probe		= foo_probe,
 	.remove		= foo_remove,
 	/* if device autodetection is needed: */
diff -druN linux-2.6.39-libre/Documentation/input/elantech.txt linux-3.0-rc7-libre/Documentation/input/elantech.txt
--- linux-2.6.39-libre/Documentation/input/elantech.txt	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/Documentation/input/elantech.txt	2011-07-11 19:51:52.000000000 -0400
@@ -34,7 +34,8 @@
 Currently the Linux Elantech touchpad driver is aware of two different
 hardware versions unimaginatively called version 1 and version 2. Version 1
 is found in "older" laptops and uses 4 bytes per packet. Version 2 seems to
-be introduced with the EeePC and uses 6 bytes per packet.
+be introduced with the EeePC and uses 6 bytes per packet, and provides
+additional features such as position of two fingers, and width of the touch.
 
 The driver tries to support both hardware versions and should be compatible
 with the Xorg Synaptics touchpad driver and its graphical configuration
@@ -94,18 +95,44 @@
    can check these bits and reject any packet that appears corrupted. Using
    this knob you can bypass that check.
 
-   It is not known yet whether hardware version 2 provides the same parity
-   bits. Hence checking is disabled by default. Currently even turning it on
-   will do nothing.
-
+   Hardware version 2 does not provide the same parity bits. Only some basic
+   data consistency checking can be done. For now checking is disabled by
+   default. Currently even turning it on will do nothing.
 
 /////////////////////////////////////////////////////////////////////////////
 
+3. Differentiating hardware versions
+   =================================
+
+To detect the hardware version, read the version number as param[0].param[1].param[2]
 
-3. Hardware version 1
+ 4 bytes version: (after the arrow is the name given in the Dell-provided driver)
+ 02.00.22 => EF013
+ 02.06.00 => EF019
+In the wild, there appear to be more versions, such as 00.01.64, 01.00.21,
+02.00.00, 02.00.04, 02.00.06.
+
+ 6 bytes:
+ 02.00.30 => EF113
+ 02.08.00 => EF023
+ 02.08.XX => EF123
+ 02.0B.00 => EF215
+ 04.01.XX => Scroll_EF051
+ 04.02.XX => EF051
+In the wild, there appear to be more versions, such as 04.03.01, 04.04.11. There
+appears to be almost no difference, except for EF113, which does not report
+pressure/width and has different data consistency checks.
+
+Probably all the versions with param[0] <= 01 can be considered as
+4 bytes/firmware 1. The versions < 02.08.00, with the exception of 02.00.30, as
+4 bytes/firmware 2. Everything >= 02.08.00 can be considered as 6 bytes.
+
+/////////////////////////////////////////////////////////////////////////////
+
+4. Hardware version 1
    ==================
 
-3.1 Registers
+4.1 Registers
     ~~~~~~~~~
 
 By echoing a hexadecimal value to a register it contents can be altered.
@@ -168,7 +195,7 @@
          smart edge activation area width?
 
 
-3.2 Native relative mode 4 byte packet format
+4.2 Native relative mode 4 byte packet format
     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 byte 0:
@@ -226,9 +253,13 @@
                        positive = down
 
 
-3.3 Native absolute mode 4 byte packet format
+4.3 Native absolute mode 4 byte packet format
     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
+EF013 and EF019 have a special behaviour (due to a bug in the firmware?), and
+when 1 finger is touching, the first 2 position reports must be discarded.
+This counting is reset whenever a different number of fingers is reported.
+
 byte 0:
    firmware version 1.x:
 
@@ -279,11 +310,11 @@
 /////////////////////////////////////////////////////////////////////////////
 
 
-4. Hardware version 2
+5. Hardware version 2
    ==================
 
 
-4.1 Registers
+5.1 Registers
     ~~~~~~~~~
 
 By echoing a hexadecimal value to a register it contents can be altered.
@@ -316,16 +347,41 @@
                                    0x7f = never i.e. tap again to release)
 
 
-4.2 Native absolute mode 6 byte packet format
+5.2 Native absolute mode 6 byte packet format
     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+5.2.1 Parity checking and packet re-synchronization
+There is no parity checking, however some consistency checks can be performed.
 
-4.2.1 One finger touch
+For instance for EF113:
+        SA1= packet[0];
+        A1 = packet[1];
+        B1 = packet[2];
+        SB1= packet[3];
+        C1 = packet[4];
+        D1 = packet[5];
+        if( (((SA1 & 0x3C) != 0x3C) && ((SA1 & 0xC0) != 0x80)) || // check Byte 1
+            (((SA1 & 0x0C) != 0x0C) && ((SA1 & 0xC0) == 0x80)) || // check Byte 1 (one finger pressed)
+            (((SA1 & 0xC0) != 0x80) && (( A1 & 0xF0) != 0x00)) || // check Byte 2
+            (((SB1 & 0x3E) != 0x38) && ((SA1 & 0xC0) != 0x80)) || // check Byte 4
+            (((SB1 & 0x0E) != 0x08) && ((SA1 & 0xC0) == 0x80)) || // check Byte 4 (one finger pressed)
+            (((SA1 & 0xC0) != 0x80) && (( C1 & 0xF0) != 0x00))  ) // check Byte 5
+		// error detected
+
+For all the other ones, there are just a few constant bits:
+        if( ((packet[0] & 0x0C) != 0x04) ||
+            ((packet[3] & 0x0f) != 0x02) )
+		// error detected
+
+
+In case an error is detected, all the packets are shifted by one (and packet[0] is discarded).
+
+5.2.1 One/Three finger touch
       ~~~~~~~~~~~~~~~~
 
 byte 0:
 
    bit   7   6   5   4   3   2   1   0
-        n1  n0   .   .   .   .   R   L
+	 n1  n0  w3  w2   .   .   R   L
 
          L, R = 1 when Left, Right mouse button pressed
          n1..n0 = numbers of fingers on touchpad
@@ -333,24 +389,40 @@
 byte 1:
 
    bit   7   6   5   4   3   2   1   0
-         .   .   .   .   .  x10 x9  x8
+	 p7  p6  p5  p4  .  x10 x9  x8
 
 byte 2:
 
    bit   7   6   5   4   3   2   1   0
-        x7  x6  x5  x4  x4  x2  x1  x0
+	 x7  x6  x5  x4  x3  x2  x1  x0
 
          x10..x0 = absolute x value (horizontal)
 
 byte 3:
 
    bit   7   6   5   4   3   2   1   0
-         .   .   .   .   .   .   .   .
+	 n4  vf  w1  w0   .   .   .  b2
+
+	 n4 = set if more than 3 fingers (only in 3 fingers mode)
+	 vf = a kind of flag ? (only on EF123, 0 when finger is over one
+	      of the buttons, 1 otherwise)
+	 w3..w0 = width of the finger touch (not EF113)
+	 b2 (on EF113 only, 0 otherwise), b2.R.L indicates one button pressed:
+		0 = none
+		1 = Left
+		2 = Right
+		3 = Middle (Left and Right)
+		4 = Forward
+		5 = Back
+		6 = Another one
+		7 = Another one
 
 byte 4:
 
    bit   7   6   5   4   3   2   1   0
-         .   .   .   .   .   .  y9  y8
+        p3  p1  p2  p0   .   .  y9  y8
+
+	 p7..p0 = pressure (not EF113)
 
 byte 5:
 
@@ -363,6 +435,11 @@
 4.2.2 Two finger touch
       ~~~~~~~~~~~~~~~~
 
+Note that the two pairs of coordinates are not exactly the coordinates of the
+two fingers, but only the pair of the lower-left and upper-right coordinates.
+So the actual fingers might be situated on the other diagonal of the square
+defined by these two points.
+
 byte 0:
 
    bit   7   6   5   4   3   2   1   0
@@ -376,14 +453,14 @@
    bit   7   6   5   4   3   2   1   0
         ax7 ax6 ax5 ax4 ax3 ax2 ax1 ax0
 
-         ax8..ax0 = first finger absolute x value
+	 ax8..ax0 = lower-left finger absolute x value
 
 byte 2:
 
    bit   7   6   5   4   3   2   1   0
         ay7 ay6 ay5 ay4 ay3 ay2 ay1 ay0
 
-         ay8..ay0 = first finger absolute y value
+	 ay8..ay0 = lower-left finger absolute y value
 
 byte 3:
 
@@ -395,11 +472,11 @@
    bit   7   6   5   4   3   2   1   0
         bx7 bx6 bx5 bx4 bx3 bx2 bx1 bx0
 
-         bx8..bx0 = second finger absolute x value
+         bx8..bx0 = upper-right finger absolute x value
 
 byte 5:
 
    bit   7   6   5   4   3   2   1   0
         by7 by8 by5 by4 by3 by2 by1 by0
 
-         by8..by0 = second finger absolute y value
+         by8..by0 = upper-right finger absolute y value
diff -druN linux-2.6.39-libre/Documentation/input/rotary-encoder.txt linux-3.0-rc7-libre/Documentation/input/rotary-encoder.txt
--- linux-2.6.39-libre/Documentation/input/rotary-encoder.txt	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/Documentation/input/rotary-encoder.txt	2011-07-11 19:51:52.000000000 -0400
@@ -9,6 +9,9 @@
 and by triggering on falling and rising edges, the turn direction can
 be determined.
 
+Some encoders have both outputs low in stable states, whereas others also have
+a stable state with both outputs high (half-period mode).
+
 The phase diagram of these two outputs look like this:
 
                   _____       _____       _____
@@ -26,6 +29,8 @@
                 |<-------->|
 	          one step
 
+                |<-->|
+	          one step (half-period mode)
 
 For more information, please see
 	http://en.wikipedia.org/wiki/Rotary_encoder
@@ -34,6 +39,13 @@
 1. Events / state machine
 -------------------------
 
+In half-period mode, state a) and c) above are used to determine the
+rotational direction based on the last stable state. Events are reported in
+states b) and d) given that the new stable state is different from the last
+(i.e. the rotation was not reversed half-way).
+
+Otherwise, the following apply:
+
 a) Rising edge on channel A, channel B in low state
 	This state is used to recognize a clockwise turn
 
@@ -96,6 +108,7 @@
 	.gpio_b		= GPIO_ROTARY_B,
 	.inverted_a	= 0,
 	.inverted_b	= 0,
+	.half_period	= false,
 };
 
 static struct platform_device rotary_encoder_device = {
diff -druN linux-2.6.39-libre/Documentation/ioctl/ioctl-number.txt linux-3.0-rc7-libre/Documentation/ioctl/ioctl-number.txt
--- linux-2.6.39-libre/Documentation/ioctl/ioctl-number.txt	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/Documentation/ioctl/ioctl-number.txt	2011-07-11 19:51:52.000000000 -0400
@@ -166,7 +166,6 @@
 'T'	all	arch/x86/include/asm/ioctls.h	conflict!
 'T'	C0-DF	linux/if_tun.h		conflict!
 'U'	all	sound/asound.h		conflict!
-'U'	00-0F	drivers/media/video/uvc/uvcvideo.h	conflict!
 'U'	00-CF	linux/uinput.h		conflict!
 'U'	00-EF	linux/usbdevice_fs.h
 'U'	C0-CF	drivers/bluetooth/hci_uart.h
@@ -259,6 +258,7 @@
 't'	80-8F	linux/isdn_ppp.h
 't'	90	linux/toshiba.h
 'u'	00-1F	linux/smb_fs.h		gone
+'u'	20-3F	linux/uvcvideo.h	USB video class host driver
 'v'	00-1F	linux/ext2_fs.h		conflict!
 'v'	00-1F	linux/fs.h		conflict!
 'v'	00-0F	linux/sonypi.h		conflict!
@@ -304,6 +304,7 @@
 0xB0	all	RATIO devices		in development:
 					<mailto:vgo@ratio.de>
 0xB1	00-1F	PPPoX			<mailto:mostrows@styx.uwaterloo.ca>
+0xB3	00	linux/mmc/ioctl.h
 0xC0	00-0F	linux/usb/iowarrior.h
 0xCB	00-1F	CBM serial IEC bus	in development:
 					<mailto:michael.klein@puffin.lb.shuttle.de>
diff -druN linux-2.6.39-libre/Documentation/IRQ-affinity.txt linux-3.0-rc7-libre/Documentation/IRQ-affinity.txt
--- linux-2.6.39-libre/Documentation/IRQ-affinity.txt	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/Documentation/IRQ-affinity.txt	2011-07-11 19:51:52.000000000 -0400
@@ -4,10 +4,11 @@
 
 SMP IRQ affinity
 
-/proc/irq/IRQ#/smp_affinity specifies which target CPUs are permitted
-for a given IRQ source. It's a bitmask of allowed CPUs. It's not allowed
-to turn off all CPUs, and if an IRQ controller does not support IRQ
-affinity then the value will not change from the default 0xffffffff.
+/proc/irq/IRQ#/smp_affinity and /proc/irq/IRQ#/smp_affinity_list specify
+which target CPUs are permitted for a given IRQ source.  It's a bitmask
+(smp_affinity) or cpu list (smp_affinity_list) of allowed CPUs.  It's not
+allowed to turn off all CPUs, and if an IRQ controller does not support
+IRQ affinity then the value will not change from the default of all cpus.
 
 /proc/irq/default_smp_affinity specifies default affinity mask that applies
 to all non-active IRQs. Once IRQ is allocated/activated its affinity bitmask
@@ -54,3 +55,11 @@
 This time around IRQ44 was delivered only to the last four processors.
 i.e counters for the CPU0-3 did not change.
 
+Here is an example of limiting that same irq (44) to cpus 1024 to 1031:
+
+[root@moon 44]# echo 1024-1031 > smp_affinity
+[root@moon 44]# cat smp_affinity
+1024-1031
+
+Note that to do this with a bitmask would require 32 bitmasks of zero
+to follow the pertinent one.
diff -druN linux-2.6.39-libre/Documentation/ja_JP/HOWTO linux-3.0-rc7-libre/Documentation/ja_JP/HOWTO
--- linux-2.6.39-libre/Documentation/ja_JP/HOWTO	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/Documentation/ja_JP/HOWTO	2011-07-11 19:51:52.000000000 -0400
@@ -11,14 +11,14 @@
 fork. So if you have any comments or updates for this file, please try
 to update the original English file first.
 
-Last Updated: 2008/10/24
+Last Updated: 2011/03/31
 ==================================
 これは、
-linux-2.6.28/Documentation/HOWTO
+linux-2.6.38/Documentation/HOWTO
 の和訳です。
 
 翻訳団体： JF プロジェクト < http://www.linux.or.jp/JF/ >
-翻訳日： 2008/10/24
+翻訳日： 2011/3/28
 翻訳者： Tsugikazu Shibata <tshibata at ab dot jp dot nec dot com>
 校正者： 松倉さん <nbh--mats at nifty dot com>
          小林 雅典さん (Masanori Kobayasi) <zap03216 at nifty dot ne dot jp>
@@ -256,8 +256,8 @@
   - メインの 2.6.x カーネルツリー
   - 2.6.x.y -stable カーネルツリー
   - 2.6.x -git カーネルパッチ
-  - 2.6.x -mm カーネルパッチ
   - サブシステム毎のカーネルツリーとパッチ
+  - 統合テストのための 2.6.x -next カーネルツリー
 
 2.6.x カーネルツリー
 -----------------
@@ -268,9 +268,9 @@
 
   - 新しいカーネルがリリースされた直後に、2週間の特別期間が設けられ、
     この期間中に、メンテナ達は Linus に大きな差分を送ることができます。
-    このような差分は通常 -mm カーネルに数週間含まれてきたパッチです。
+    このような差分は通常 -next カーネルに数週間含まれてきたパッチです。
     大きな変更は git(カーネルのソース管理ツール、詳細は
-    http://git.or.cz/  参照) を使って送るのが好ましいやり方ですが、パッ
+    http://git-scm.com/  参照) を使って送るのが好ましいやり方ですが、パッ
     チファイルの形式のまま送るのでも十分です。
 
   - 2週間後、-rc1 カーネルがリリースされ、この後にはカーネル全体の安定
@@ -333,86 +333,44 @@
 れは -rc カーネルと比べて、パッチが大丈夫かどうかも確認しないで自動的
 に生成されるので、より実験的です。
 
-2.6.x -mm カーネルパッチ
-------------------------
-
-Andrew Morton によってリリースされる実験的なカーネルパッチ群です。
-Andrew は個別のサブシステムカーネルツリーとパッチを全て集めてきて
-linux-kernel メーリングリストで収集された多数のパッチと同時に一つにま
-とめます。
-このツリーは新機能とパッチが検証される場となります。ある期間の間パッチ
-が -mm に入って価値を証明されたら、Andrew やサブシステムメンテナが、
-メインラインへ入れるように Linus にプッシュします。
-
-メインカーネルツリーに含めるために Linus に送る前に、すべての新しいパッ
-チが -mm ツリーでテストされることが強く推奨されています。マージウィン
-ドウが開く前に -mm ツリーに現れなかったパッチはメインラインにマージさ
-れることは困難になります。
-
-これらのカーネルは安定して動作すべきシステムとして使うのには適切ではあ
-りませんし、カーネルブランチの中でももっとも動作にリスクが高いものです。
-
-もしあなたが、カーネル開発プロセスの支援をしたいと思っているのであれば、
-どうぞこれらのカーネルリリースをテストに使ってみて、そしてもし問題があ
-れば、またもし全てが正しく動作したとしても、linux-kernel メーリングリ
-ストにフィードバックを提供してください。
-
-すべての他の実験的パッチに加えて、これらのカーネルは通常リリース時点で
-メインラインの -git カーネルに含まれる全ての変更も含んでいます。
-
--mm カーネルは決まったスケジュールではリリースされません、しかし通常幾
-つかの -mm カーネル (1 から 3 が普通）が各-rc カーネルの間にリリースさ
-れます。
-
 サブシステム毎のカーネルツリーとパッチ
 -------------------------------------------
 
-カーネルの様々な領域で何が起きているかを見られるようにするため、多くの
-カーネルサブシステム開発者は彼らの開発ツリーを公開しています。これらの
-ツリーは説明したように -mm カーネルリリースに入れ込まれます。
-
-以下はさまざまなカーネルツリーの中のいくつかのリスト-
-
-  git ツリー-
-    - Kbuild の開発ツリー、Sam Ravnborg <sam@ravnborg.org>
-	git.kernel.org:/pub/scm/linux/kernel/git/sam/kbuild.git
-
-    - ACPI の開発ツリー、 Len Brown <len.brown@intel.com>
-	git.kernel.org:/pub/scm/linux/kernel/git/lenb/linux-acpi-2.6.git
-
-    - Block の開発ツリー、Jens Axboe <axboe@suse.de>
-	git.kernel.org:/pub/scm/linux/kernel/git/axboe/linux-2.6-block.git
-
-    - DRM の開発ツリー、Dave Airlie <airlied@linux.ie>
-	git.kernel.org:/pub/scm/linux/kernel/git/airlied/drm-2.6.git
-
-    - ia64 の開発ツリー、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
-
-    - ネットワークドライバ, Jeff Garzik <jgarzik@pobox.com>
-	git.kernel.org:/pub/scm/linux/kernel/git/jgarzik/netdev-2.6.git
+それぞれのカーネルサブシステムのメンテナ達は --- そして多くのカーネル
+サブシステムの開発者達も --- 各自の最新の開発状況をソースリポジトリに
+公開しています。そのため、自分とは異なる領域のカーネルで何が起きている
+かを他の人が見られるようになっています。開発が早く進んでいる領域では、
+開発者は自身の投稿がどのサブシステムカーネルツリーを元にしているか質問
+されるので、その投稿とすでに進行中の他の作業との衝突が避けられます。
 
-    - pcmcia, Dominik Brodowski <linux@dominikbrodowski.net>
-	git.kernel.org:/pub/scm/linux/kernel/git/brodo/pcmcia-2.6.git
+大部分のこれらのリポジトリは git ツリーです。しかしその他の SCM や
+quilt シリーズとして公開されているパッチキューも使われています。これら
+のサブシステムリポジトリのアドレスは MAINTAINERS ファイルにリストされ
+ています。これらの多くは 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
+提案されたパッチがこのようなサブシステムツリーにコミットされる前に、メー
+リングリストで事前にレビューにかけられます（以下の対応するセクションを
+参照）。いくつかのカーネルサブシステムでは、このレビューは patchwork
+というツールによって追跡されます。Patchwork は web インターフェイスに
+よってパッチ投稿の表示、パッチへのコメント付けや改訂などができ、そして
+メンテナはパッチに対して、レビュー中、受付済み、拒否というようなマーク
+をつけることができます。大部分のこれらの patchwork のサイトは
+http://patchwork.kernel.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 カーネルツリー
+---------------------------------------------
 
-  quilt ツリー-
-    - USB, ドライバコアと I2C, Greg Kroah-Hartman <gregkh@suse.de>
-	kernel.org/pub/linux/kernel/people/gregkh/gregkh-2.6/
+サブシステムツリーの更新内容がメインラインの 2.6.x ツリーにマージされ
+る前に、それらは統合テストされる必要があります。この目的のため、実質的
+に全サブシステムツリーからほぼ毎日プルされてできる特別なテスト用のリ
+ポジトリが存在します-
+       http://git.kernel.org/?p=linux/kernel/git/sfr/linux-next.git
+       http://linux.f-seidel.de/linux-next/pmwiki/
 
-  その他のカーネルツリーは http://git.kernel.org/ と MAINTAINERS ファ
-  イルに一覧表があります。
+このやり方によって、-next カーネルは次のマージ機会でどんなものがメイン
+ラインカーネルにマージされるか、おおまかなの展望を提供します。-next 
+カーネルの実行テストを行う冒険好きなテスターは大いに歓迎されます
 
 バグレポート
 -------------
@@ -673,10 +631,9 @@
 じところからスタートしたのですから。
 
 Paolo Ciarrocchi に感謝、彼は彼の書いた "Development Process"
-(http://linux.tar.bz/articles/2.6-development_process)セクショ
-ンをこのテキストの原型にすることを許可してくれました。
-Rundy Dunlap と Gerrit Huizenga はメーリングリストでやるべきこととやっ
-てはいけないことのリストを提供してくれました。
+(http://lwn.net/Articles/94386/) セクションをこのテキストの原型にする
+ことを許可してくれました。Rundy Dunlap と Gerrit Huizenga はメーリング
+リストでやるべきこととやってはいけないことのリストを提供してくれました。
 以下の人々のレビュー、コメント、貢献に感謝。
 Pat Mochel, Hanna Linder, Randy Dunlap, Kay Sievers,
 Vojtech Pavlik, Jan Kara, Josh Boyer, Kees Cook, Andrew Morton, Andi
diff -druN linux-2.6.39-libre/Documentation/kbuild/kbuild.txt linux-3.0-rc7-libre/Documentation/kbuild/kbuild.txt
--- linux-2.6.39-libre/Documentation/kbuild/kbuild.txt	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/Documentation/kbuild/kbuild.txt	2011-07-11 19:51:52.000000000 -0400
@@ -201,3 +201,16 @@
 --------------------------------------------------
 If enabled over the make command line with "W=1", it turns on additional
 gcc -W... options for more extensive build-time checking.
+
+KBUILD_BUILD_TIMESTAMP
+--------------------------------------------------
+Setting this to a date string overrides the timestamp used in the
+UTS_VERSION definition (uname -v in the running kernel). The value has to
+be a string that can be passed to date -d. The default value
+is the output of the date command at one point during build.
+
+KBUILD_BUILD_USER, KBUILD_BUILD_HOST
+--------------------------------------------------
+These two variables allow to override the user@host string displayed during
+boot and in /proc/version. The default value is the output of the commands
+whoami and host, respectively.
diff -druN linux-2.6.39-libre/Documentation/kbuild/kconfig-language.txt linux-3.0-rc7-libre/Documentation/kbuild/kconfig-language.txt
--- linux-2.6.39-libre/Documentation/kbuild/kconfig-language.txt	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/Documentation/kbuild/kconfig-language.txt	2011-07-11 19:51:52.000000000 -0400
@@ -113,6 +113,13 @@
 	That will limit the usefulness but on the other hand avoid
 	the illegal configurations all over.
 
+- limiting menu display: "visible if" <expr>
+  This attribute is only applicable to menu blocks, if the condition is
+  false, the menu block is not displayed to the user (the symbols
+  contained there can still be selected by other symbols, though). It is
+  similar to a conditional "prompt" attribude for individual menu
+  entries. Default value of "visible" is true.
+
 - numerical ranges: "range" <symbol> <symbol> ["if" <expr>]
   This allows to limit the range of possible input values for int
   and hex symbols. The user can only input a value which is larger than
@@ -303,7 +310,8 @@
 	"endmenu"
 
 This defines a menu block, see "Menu structure" above for more
-information. The only possible options are dependencies.
+information. The only possible options are dependencies and "visible"
+attributes.
 
 if:
 
@@ -381,3 +389,25 @@
 
 limits FOO to module (=m) or disabled (=n).
 
+Kconfig symbol existence
+~~~~~~~~~~~~~~~~~~~~~~~~
+The following two methods produce the same kconfig symbol dependencies
+but differ greatly in kconfig symbol existence (production) in the
+generated config file.
+
+case 1:
+
+config FOO
+	tristate "about foo"
+	depends on BAR
+
+vs. case 2:
+
+if BAR
+config FOO
+	tristate "about foo"
+endif
+
+In case 1, the symbol FOO will always exist in the config file (given
+no other dependencies).  In case 2, the symbol FOO will only exist in
+the config file if BAR is enabled.
diff -druN linux-2.6.39-libre/Documentation/kbuild/kconfig.txt linux-3.0-rc7-libre/Documentation/kbuild/kconfig.txt
--- linux-2.6.39-libre/Documentation/kbuild/kconfig.txt	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/Documentation/kbuild/kconfig.txt	2011-07-11 19:51:52.000000000 -0400
@@ -48,11 +48,6 @@
 If you set KCONFIG_OVERWRITECONFIG in the environment, Kconfig will not
 break symlinks when .config is a symlink to somewhere else.
 
-KCONFIG_NOTIMESTAMP
---------------------------------------------------
-If this environment variable exists and is non-null, the timestamp line
-in generated .config files is omitted.
-
 ______________________________________________________________________
 Environment variables for '{allyes/allmod/allno/rand}config'
 
diff -druN linux-2.6.39-libre/Documentation/kbuild/makefiles.txt linux-3.0-rc7-libre/Documentation/kbuild/makefiles.txt
--- linux-2.6.39-libre/Documentation/kbuild/makefiles.txt	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/Documentation/kbuild/makefiles.txt	2011-07-11 19:51:52.000000000 -0400
@@ -40,11 +40,13 @@
 	   --- 6.6 Commands useful for building a boot image
 	   --- 6.7 Custom kbuild commands
 	   --- 6.8 Preprocessing linker scripts
+	   --- 6.9 Generic header files
 
 	=== 7 Kbuild syntax for exported headers
 		--- 7.1 header-y
 		--- 7.2 objhdr-y
 		--- 7.3 destination-y
+		--- 7.4 generic-y
 
 	=== 8 Kbuild Variables
 	=== 9 Makefile language
@@ -499,6 +501,18 @@
 	gcc >= 3.00. For gcc < 3.00, -malign-functions=4 is used.
 	Note: cc-option-align uses KBUILD_CFLAGS for $(CC) options
 
+    cc-disable-warning
+	cc-disable-warning checks if gcc supports a given warning and returns
+	the commandline switch to disable it. This special function is needed,
+	because gcc 4.4 and later accept any unknown -Wno-* option and only
+	warn about it if there is another warning in the source file.
+
+	Example:
+		KBUILD_CFLAGS += $(call cc-disable-warning, unused-but-set-variable)
+
+	In the above example, -Wno-unused-but-set-variable will be added to
+	KBUILD_CFLAGS only if gcc really accepts it.
+
     cc-version
 	cc-version returns a numerical version of the $(CC) compiler version.
 	The format is <major><minor> where both are two digits. So for example
@@ -955,6 +969,11 @@
 	used when linking modules. This is often a linker script.
 	From commandline LDFLAGS_MODULE shall be used (see kbuild.txt).
 
+    KBUILD_ARFLAGS   Options for $(AR) when creating archives
+
+	$(KBUILD_ARFLAGS) set by the top level Makefile to "D" (deterministic
+	mode) if this option is supported by $(AR).
+
 --- 6.2 Add prerequisites to archprepare:
 
 	The archprepare: rule is used to list prerequisites that need to be
@@ -1209,6 +1228,14 @@
 	The kbuild infrastructure for *lds file are used in several
 	architecture-specific files.
 
+--- 6.9 Generic header files
+
+	The directory include/asm-generic contains the header files
+	that may be shared between individual architectures.
+	The recommended approach how to use a generic header file is
+	to list the file in the Kbuild file.
+	See "7.4 generic-y" for further info on syntax etc.
+
 === 7 Kbuild syntax for exported headers
 
 The kernel include a set of headers that is exported to userspace.
@@ -1265,6 +1292,32 @@
 	In the example above all exported headers in the Kbuild file
 	will be located in the directory "include/linux" when exported.
 
+	--- 7.4 generic-y
+
+	If an architecture uses a verbatim copy of a header from
+	include/asm-generic then this is listed in the file
+	arch/$(ARCH)/include/asm/Kbuild like this:
+
+		Example:
+			#arch/x86/include/asm/Kbuild
+			generic-y += termios.h
+			generic-y += rtc.h
+
+	During the prepare phase of the build a wrapper include
+	file is generated in the directory:
+
+		arch/$(ARCH)/include/generated/asm
+
+	When a header is exported where the architecture uses
+	the generic header a similar wrapper is generated as part
+	of the set of exported headers in the directory:
+
+		usr/include/asm
+
+	The generated wrapper will in both cases look like the following:
+
+		Example: termios.h
+			#include <asm-generic/termios.h>
 
 === 8 Kbuild Variables
 
diff -druN linux-2.6.39-libre/Documentation/kernel-parameters.txt linux-3.0-rc7-libre/Documentation/kernel-parameters.txt
--- linux-2.6.39-libre/Documentation/kernel-parameters.txt	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/Documentation/kernel-parameters.txt	2011-07-11 19:51:52.000000000 -0400
@@ -245,7 +245,7 @@
 
 	acpi_sleep=	[HW,ACPI] Sleep options
 			Format: { s3_bios, s3_mode, s3_beep, s4_nohwsig,
-				  old_ordering, s4_nonvs, sci_force_enable }
+				  old_ordering, nonvs, sci_force_enable }
 			See Documentation/power/video.txt for information on
 			s3_bios and s3_mode.
 			s3_beep is for debugging; it makes the PC's speaker beep
@@ -999,7 +999,10 @@
 			With this option on every unmap_single operation will
 			result in a hardware IOTLB flush operation as opposed
 			to batching them for performance.
-
+		sp_off [Default Off]
+			By default, super page will be supported if Intel IOMMU
+			has the capability. With this option, super page will
+			not be supported.
 	intremap=	[X86-64, Intel-IOMMU]
 			Format: { on (default) | off | nosid }
 			on	enable Interrupt Remapping (default)
@@ -1664,6 +1667,10 @@
 			noexec=on: enable non-executable mappings (default)
 			noexec=off: disable non-executable mappings
 
+	nosmep		[X86]
+			Disable SMEP (Supervisor Mode Execution Protection)
+			even if it is supported by processor.
+
 	noexec32	[X86-64]
 			This affects only 32-bit executables.
 			noexec32=on: enable non-executable mappings (default)
@@ -1773,9 +1780,6 @@
 
 	nosoftlockup	[KNL] Disable the soft-lockup detector.
 
-	noswapaccount	[KNL] Disable accounting of swap in memory resource
-			controller. (See Documentation/cgroups/memory.txt)
-
 	nosync		[HW,M68K] Disables sync negotiation for all devices.
 
 	notsc		[BUGS=X86-32] Disable Time Stamp Counter
@@ -2011,6 +2015,8 @@
 				the default.
 				off: Turn ECRC off
 				on: Turn ECRC on.
+		realloc		reallocate PCI resources if allocations done by BIOS
+				are erroneous.
 
 	pcie_aspm=	[PCIE] Forcibly enable or disable PCIe Active State Power
 			Management.
@@ -2581,6 +2587,10 @@
 					bytes of sense data);
 				c = FIX_CAPACITY (decrease the reported
 					device capacity by one sector);
+				d = NO_READ_DISC_INFO (don't use
+					READ_DISC_INFO command);
+				e = NO_READ_CAPACITY_16 (don't use
+					READ_CAPACITY_16 command);
 				h = CAPACITY_HEURISTICS (decrease the
 					reported device capacity by one
 					sector if the number is odd);
@@ -2590,6 +2600,8 @@
 					unlock ejectable media);
 				m = MAX_SECTORS_64 (don't transfer more
 					than 64 sectors = 32 KB at a time);
+				n = INITIAL_READ10 (force a retry of the
+					initial READ(10) command);
 				o = CAPACITY_OK (accept the capacity
 					reported by the device);
 				r = IGNORE_RESIDUE (the device reports
diff -druN linux-2.6.39-libre/Documentation/keys-request-key.txt linux-3.0-rc7-libre/Documentation/keys-request-key.txt
--- linux-2.6.39-libre/Documentation/keys-request-key.txt	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/Documentation/keys-request-key.txt	1969-12-31 19:00:00.000000000 -0500
@@ -1,202 +0,0 @@
-			      ===================
-			      KEY REQUEST SERVICE
-			      ===================
-
-The key request service is part of the key retention service (refer to
-Documentation/keys.txt).  This document explains more fully how the requesting
-algorithm works.
-
-The process starts by either the kernel requesting a service by calling
-request_key*():
-
-	struct key *request_key(const struct key_type *type,
-				const char *description,
-				const char *callout_info);
-
-or:
-
-	struct key *request_key_with_auxdata(const struct key_type *type,
-					     const char *description,
-					     const char *callout_info,
-					     size_t callout_len,
-					     void *aux);
-
-or:
-
-	struct key *request_key_async(const struct key_type *type,
-				      const char *description,
-				      const char *callout_info,
-				      size_t callout_len);
-
-or:
-
-	struct key *request_key_async_with_auxdata(const struct key_type *type,
-						   const char *description,
-						   const char *callout_info,
-					     	   size_t callout_len,
-						   void *aux);
-
-Or by userspace invoking the request_key system call:
-
-	key_serial_t request_key(const char *type,
-				 const char *description,
-				 const char *callout_info,
-				 key_serial_t dest_keyring);
-
-The main difference between the access points is that the in-kernel interface
-does not need to link the key to a keyring to prevent it from being immediately
-destroyed.  The kernel interface returns a pointer directly to the key, and
-it's up to the caller to destroy the key.
-
-The request_key*_with_auxdata() calls are like the in-kernel request_key*()
-calls, except that they permit auxiliary data to be passed to the upcaller (the
-default is NULL).  This is only useful for those key types that define their
-own upcall mechanism rather than using /sbin/request-key.
-
-The two async in-kernel calls may return keys that are still in the process of
-being constructed.  The two non-async ones will wait for construction to
-complete first.
-
-The userspace interface links the key to a keyring associated with the process
-to prevent the key from going away, and returns the serial number of the key to
-the caller.
-
-
-The following example assumes that the key types involved don't define their
-own upcall mechanisms.  If they do, then those should be substituted for the
-forking and execution of /sbin/request-key.
-
-
-===========
-THE PROCESS
-===========
-
-A request proceeds in the following manner:
-
- (1) Process A calls request_key() [the userspace syscall calls the kernel
-     interface].
-
- (2) request_key() searches the process's subscribed keyrings to see if there's
-     a suitable key there.  If there is, it returns the key.  If there isn't,
-     and callout_info is not set, an error is returned.  Otherwise the process
-     proceeds to the next step.
-
- (3) request_key() sees that A doesn't have the desired key yet, so it creates
-     two things:
-
-     (a) An uninstantiated key U of requested type and description.
-
-     (b) An authorisation key V that refers to key U and notes that process A
-     	 is the context in which key U should be instantiated and secured, and
-     	 from which associated key requests may be satisfied.
-
- (4) request_key() then forks and executes /sbin/request-key with a new session
-     keyring that contains a link to auth key V.
-
- (5) /sbin/request-key assumes the authority associated with key U.
-
- (6) /sbin/request-key execs an appropriate program to perform the actual
-     instantiation.
-
- (7) The program may want to access another key from A's context (say a
-     Kerberos TGT key).  It just requests the appropriate key, and the keyring
-     search notes that the session keyring has auth key V in its bottom level.
-
-     This will permit it to then search the keyrings of process A with the
-     UID, GID, groups and security info of process A as if it was process A,
-     and come up with key W.
-
- (8) The program then does what it must to get the data with which to
-     instantiate key U, using key W as a reference (perhaps it contacts a
-     Kerberos server using the TGT) and then instantiates key U.
-
- (9) Upon instantiating key U, auth key V is automatically revoked so that it
-     may not be used again.
-
-(10) The program then exits 0 and request_key() deletes key V and returns key
-     U to the caller.
-
-This also extends further.  If key W (step 7 above) didn't exist, key W would
-be created uninstantiated, another auth key (X) would be created (as per step
-3) and another copy of /sbin/request-key spawned (as per step 4); but the
-context specified by auth key X will still be process A, as it was in auth key
-V.
-
-This is because process A's keyrings can't simply be attached to
-/sbin/request-key at the appropriate places because (a) execve will discard two
-of them, and (b) it requires the same UID/GID/Groups all the way through.
-
-
-====================================
-NEGATIVE INSTANTIATION AND REJECTION
-====================================
-
-Rather than instantiating a key, it is possible for the possessor of an
-authorisation key to negatively instantiate a key that's under construction.
-This is a short duration placeholder that causes any attempt at re-requesting
-the key whilst it exists to fail with error ENOKEY if negated or the specified
-error if rejected.
-
-This is provided to prevent excessive repeated spawning of /sbin/request-key
-processes for a key that will never be obtainable.
-
-Should the /sbin/request-key process exit anything other than 0 or die on a
-signal, the key under construction will be automatically negatively
-instantiated for a short amount of time.
-
-
-====================
-THE SEARCH ALGORITHM
-====================
-
-A search of any particular keyring proceeds in the following fashion:
-
- (1) When the key management code searches for a key (keyring_search_aux) it
-     firstly calls key_permission(SEARCH) on the keyring it's starting with,
-     if this denies permission, it doesn't search further.
-
- (2) It considers all the non-keyring keys within that keyring and, if any key
-     matches the criteria specified, calls key_permission(SEARCH) on it to see
-     if the key is allowed to be found.  If it is, that key is returned; if
-     not, the search continues, and the error code is retained if of higher
-     priority than the one currently set.
-
- (3) It then considers all the keyring-type keys in the keyring it's currently
-     searching.  It calls key_permission(SEARCH) on each keyring, and if this
-     grants permission, it recurses, executing steps (2) and (3) on that
-     keyring.
-
-The process stops immediately a valid key is found with permission granted to
-use it.  Any error from a previous match attempt is discarded and the key is
-returned.
-
-When search_process_keyrings() is invoked, it performs the following searches
-until one succeeds:
-
- (1) If extant, the process's thread keyring is searched.
-
- (2) If extant, the process's process keyring is searched.
-
- (3) The process's session keyring is searched.
-
- (4) If the process has assumed the authority associated with a request_key()
-     authorisation key then:
-
-     (a) If extant, the calling process's thread keyring is searched.
-
-     (b) If extant, the calling process's process keyring is searched.
-
-     (c) The calling process's session keyring is searched.
-
-The moment one succeeds, all pending errors are discarded and the found key is
-returned.
-
-Only if all these fail does the whole thing fail with the highest priority
-error.  Note that several errors may have come from LSM.
-
-The error priority is:
-
-	EKEYREVOKED > EKEYEXPIRED > ENOKEY
-
-EACCES/EPERM are only returned on a direct search of a specific keyring where
-the basal keyring does not grant Search permission.
diff -druN linux-2.6.39-libre/Documentation/keys-trusted-encrypted.txt linux-3.0-rc7-libre/Documentation/keys-trusted-encrypted.txt
--- linux-2.6.39-libre/Documentation/keys-trusted-encrypted.txt	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/Documentation/keys-trusted-encrypted.txt	1969-12-31 19:00:00.000000000 -0500
@@ -1,145 +0,0 @@
-			Trusted and Encrypted Keys
-
-Trusted and Encrypted Keys are two new key types added to the existing kernel
-key ring service.  Both of these new types are variable length symmetic keys,
-and in both cases all keys are created in the kernel, and user space sees,
-stores, and loads only encrypted blobs.  Trusted Keys require the availability
-of a Trusted Platform Module (TPM) chip for greater security, while Encrypted
-Keys can be used on any system.  All user level blobs, are displayed and loaded
-in hex ascii for convenience, and are integrity verified.
-
-Trusted Keys use a TPM both to generate and to seal the keys.  Keys are sealed
-under a 2048 bit RSA key in the TPM, and optionally sealed to specified PCR
-(integrity measurement) values, and only unsealed by the TPM, if PCRs and blob
-integrity verifications match.  A loaded Trusted Key can be updated with new
-(future) PCR values, so keys are easily migrated to new pcr values, such as
-when the kernel and initramfs are updated.  The same key can have many saved
-blobs under different PCR values, so multiple boots are easily supported.
-
-By default, trusted keys are sealed under the SRK, which has the default
-authorization value (20 zeros).  This can be set at takeownership time with the
-trouser's utility: "tpm_takeownership -u -z".
-
-Usage:
-    keyctl add trusted name "new keylen [options]" ring
-    keyctl add trusted name "load hex_blob [pcrlock=pcrnum]" ring
-    keyctl update key "update [options]"
-    keyctl print keyid
-
-    options:
-       keyhandle= ascii hex value of sealing key default 0x40000000 (SRK)
-       keyauth=	  ascii hex auth for sealing key default 0x00...i
-		  (40 ascii zeros)
-       blobauth=  ascii hex auth for sealed data default 0x00...
-		  (40 ascii zeros)
-       blobauth=  ascii hex auth for sealed data default 0x00...
-		  (40 ascii zeros)
-       pcrinfo=	  ascii hex of PCR_INFO or PCR_INFO_LONG (no default)
-       pcrlock=	  pcr number to be extended to "lock" blob
-       migratable= 0|1 indicating permission to reseal to new PCR values,
-                   default 1 (resealing allowed)
-
-"keyctl print" returns an ascii hex copy of the sealed key, which is in standard
-TPM_STORED_DATA format.  The key length for new keys are always in bytes.
-Trusted Keys can be 32 - 128 bytes (256 - 1024 bits), the upper limit is to fit
-within the 2048 bit SRK (RSA) keylength, with all necessary structure/padding.
-
-Encrypted keys do not depend on a TPM, and are faster, as they use AES for
-encryption/decryption.  New keys are created from kernel generated random
-numbers, and are encrypted/decrypted using a specified 'master' key.  The
-'master' key can either be a trusted-key or user-key type.  The main
-disadvantage of encrypted keys is that if they are not rooted in a trusted key,
-they are only as secure as the user key encrypting them.  The master user key
-should therefore be loaded in as secure a way as possible, preferably early in
-boot.
-
-Usage:
-  keyctl add encrypted name "new key-type:master-key-name keylen" ring
-  keyctl add encrypted name "load hex_blob" ring
-  keyctl update keyid "update key-type:master-key-name"
-
-where 'key-type' is either 'trusted' or 'user'.
-
-Examples of trusted and encrypted key usage:
-
-Create and save a trusted key named "kmk" of length 32 bytes:
-
-    $ keyctl add trusted kmk "new 32" @u
-    440502848
-
-    $ keyctl show
-    Session Keyring
-           -3 --alswrv    500   500  keyring: _ses
-     97833714 --alswrv    500    -1   \_ keyring: _uid.500
-    440502848 --alswrv    500   500       \_ trusted: kmk
-
-    $ keyctl print 440502848
-    0101000000000000000001005d01b7e3f4a6be5709930f3b70a743cbb42e0cc95e18e915
-    3f60da455bbf1144ad12e4f92b452f966929f6105fd29ca28e4d4d5a031d068478bacb0b
-    27351119f822911b0a11ba3d3498ba6a32e50dac7f32894dd890eb9ad578e4e292c83722
-    a52e56a097e6a68b3f56f7a52ece0cdccba1eb62cad7d817f6dc58898b3ac15f36026fec
-    d568bd4a706cb60bb37be6d8f1240661199d640b66fb0fe3b079f97f450b9ef9c22c6d5d
-    dd379f0facd1cd020281dfa3c70ba21a3fa6fc2471dc6d13ecf8298b946f65345faa5ef0
-    f1f8fff03ad0acb083725535636addb08d73dedb9832da198081e5deae84bfaf0409c22b
-    e4a8aea2b607ec96931e6f4d4fe563ba
-
-    $ keyctl pipe 440502848 > kmk.blob
-
-Load a trusted key from the saved blob:
-
-    $ keyctl add trusted kmk "load `cat kmk.blob`" @u
-    268728824
-
-    $ keyctl print 268728824
-    0101000000000000000001005d01b7e3f4a6be5709930f3b70a743cbb42e0cc95e18e915
-    3f60da455bbf1144ad12e4f92b452f966929f6105fd29ca28e4d4d5a031d068478bacb0b
-    27351119f822911b0a11ba3d3498ba6a32e50dac7f32894dd890eb9ad578e4e292c83722
-    a52e56a097e6a68b3f56f7a52ece0cdccba1eb62cad7d817f6dc58898b3ac15f36026fec
-    d568bd4a706cb60bb37be6d8f1240661199d640b66fb0fe3b079f97f450b9ef9c22c6d5d
-    dd379f0facd1cd020281dfa3c70ba21a3fa6fc2471dc6d13ecf8298b946f65345faa5ef0
-    f1f8fff03ad0acb083725535636addb08d73dedb9832da198081e5deae84bfaf0409c22b
-    e4a8aea2b607ec96931e6f4d4fe563ba
-
-Reseal a trusted key under new pcr values:
-
-    $ keyctl update 268728824 "update pcrinfo=`cat pcr.blob`"
-    $ keyctl print 268728824
-    010100000000002c0002800093c35a09b70fff26e7a98ae786c641e678ec6ffb6b46d805
-    77c8a6377aed9d3219c6dfec4b23ffe3000001005d37d472ac8a44023fbb3d18583a4f73
-    d3a076c0858f6f1dcaa39ea0f119911ff03f5406df4f7f27f41da8d7194f45c9f4e00f2e
-    df449f266253aa3f52e55c53de147773e00f0f9aca86c64d94c95382265968c354c5eab4
-    9638c5ae99c89de1e0997242edfb0b501744e11ff9762dfd951cffd93227cc513384e7e6
-    e782c29435c7ec2edafaa2f4c1fe6e7a781b59549ff5296371b42133777dcc5b8b971610
-    94bc67ede19e43ddb9dc2baacad374a36feaf0314d700af0a65c164b7082401740e489c9
-    7ef6a24defe4846104209bf0c3eced7fa1a672ed5b125fc9d8cd88b476a658a4434644ef
-    df8ae9a178e9f83ba9f08d10fa47e4226b98b0702f06b3b8
-
-Create and save an encrypted key "evm" using the above trusted key "kmk":
-
-    $ keyctl add encrypted evm "new trusted:kmk 32" @u
-    159771175
-
-    $ keyctl print 159771175
-    trusted:kmk 32 2375725ad57798846a9bbd240de8906f006e66c03af53b1b382dbbc55
-    be2a44616e4959430436dc4f2a7a9659aa60bb4652aeb2120f149ed197c564e024717c64
-    5972dcb82ab2dde83376d82b2e3c09ffc
-
-    $ keyctl pipe 159771175 > evm.blob
-
-Load an encrypted key "evm" from saved blob:
-
-    $ keyctl add encrypted evm "load `cat evm.blob`" @u
-    831684262
-
-    $ keyctl print 831684262
-    trusted:kmk 32 2375725ad57798846a9bbd240de8906f006e66c03af53b1b382dbbc55
-    be2a44616e4959430436dc4f2a7a9659aa60bb4652aeb2120f149ed197c564e024717c64
-    5972dcb82ab2dde83376d82b2e3c09ffc
-
-
-The initial consumer of trusted keys is EVM, which at boot time needs a high
-quality symmetric key for HMAC protection of file metadata.  The use of a
-trusted key provides strong guarantees that the EVM key has not been
-compromised by a user level problem, and when sealed to specific boot PCR
-values, protects against boot and offline attacks.  Other uses for trusted and
-encrypted keys, such as for disk and file encryption are anticipated.
diff -druN linux-2.6.39-libre/Documentation/keys.txt linux-3.0-rc7-libre/Documentation/keys.txt
--- linux-2.6.39-libre/Documentation/keys.txt	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/Documentation/keys.txt	1969-12-31 19:00:00.000000000 -0500
@@ -1,1290 +0,0 @@
-			 ============================
-			 KERNEL KEY RETENTION SERVICE
-			 ============================
-
-This service allows cryptographic keys, authentication tokens, cross-domain
-user mappings, and similar to be cached in the kernel for the use of
-filesystems and other kernel services.
-
-Keyrings are permitted; these are a special type of key that can hold links to
-other keys. Processes each have three standard keyring subscriptions that a
-kernel service can search for relevant keys.
-
-The key service can be configured on by enabling:
-
-	"Security options"/"Enable access key retention support" (CONFIG_KEYS)
-
-This document has the following sections:
-
-	- Key overview
-	- Key service overview
-	- Key access permissions
-	- SELinux support
-	- New procfs files
-	- Userspace system call interface
-	- Kernel services
-	- Notes on accessing payload contents
-	- Defining a key type
-	- Request-key callback service
-	- Garbage collection
-
-
-============
-KEY OVERVIEW
-============
-
-In this context, keys represent units of cryptographic data, authentication
-tokens, keyrings, etc.. These are represented in the kernel by struct key.
-
-Each key has a number of attributes:
-
-	- A serial number.
-	- A type.
-	- A description (for matching a key in a search).
-	- Access control information.
-	- An expiry time.
-	- A payload.
-	- State.
-
-
- (*) Each key is issued a serial number of type key_serial_t that is unique for
-     the lifetime of that key. All serial numbers are positive non-zero 32-bit
-     integers.
-
-     Userspace programs can use a key's serial numbers as a way to gain access
-     to it, subject to permission checking.
-
- (*) Each key is of a defined "type". Types must be registered inside the
-     kernel by a kernel service (such as a filesystem) before keys of that type
-     can be added or used. Userspace programs cannot define new types directly.
-
-     Key types are represented in the kernel by struct key_type. This defines a
-     number of operations that can be performed on a key of that type.
-
-     Should a type be removed from the system, all the keys of that type will
-     be invalidated.
-
- (*) Each key has a description. This should be a printable string. The key
-     type provides an operation to perform a match between the description on a
-     key and a criterion string.
-
- (*) Each key has an owner user ID, a group ID and a permissions mask. These
-     are used to control what a process may do to a key from userspace, and
-     whether a kernel service will be able to find the key.
-
- (*) Each key can be set to expire at a specific time by the key type's
-     instantiation function. Keys can also be immortal.
-
- (*) Each key can have a payload. This is a quantity of data that represent the
-     actual "key". In the case of a keyring, this is a list of keys to which
-     the keyring links; in the case of a user-defined key, it's an arbitrary
-     blob of data.
-
-     Having a payload is not required; and the payload can, in fact, just be a
-     value stored in the struct key itself.
-
-     When a key is instantiated, the key type's instantiation function is
-     called with a blob of data, and that then creates the key's payload in
-     some way.
-
-     Similarly, when userspace wants to read back the contents of the key, if
-     permitted, another key type operation will be called to convert the key's
-     attached payload back into a blob of data.
-
- (*) Each key can be in one of a number of basic states:
-
-     (*) Uninstantiated. The key exists, but does not have any data attached.
-     	 Keys being requested from userspace will be in this state.
-
-     (*) Instantiated. This is the normal state. The key is fully formed, and
-	 has data attached.
-
-     (*) Negative. This is a relatively short-lived state. The key acts as a
-	 note saying that a previous call out to userspace failed, and acts as
-	 a throttle on key lookups. A negative key can be updated to a normal
-	 state.
-
-     (*) Expired. Keys can have lifetimes set. If their lifetime is exceeded,
-	 they traverse to this state. An expired key can be updated back to a
-	 normal state.
-
-     (*) Revoked. A key is put in this state by userspace action. It can't be
-	 found or operated upon (apart from by unlinking it).
-
-     (*) Dead. The key's type was unregistered, and so the key is now useless.
-
-Keys in the last three states are subject to garbage collection.  See the
-section on "Garbage collection".
-
-
-====================
-KEY SERVICE OVERVIEW
-====================
-
-The key service provides a number of features besides keys:
-
- (*) The key service defines two special key types:
-
-     (+) "keyring"
-
-	 Keyrings are special keys that contain a list of other keys. Keyring
-	 lists can be modified using various system calls. Keyrings should not
-	 be given a payload when created.
-
-     (+) "user"
-
-	 A key of this type has a description and a payload that are arbitrary
-	 blobs of data. These can be created, updated and read by userspace,
-	 and aren't intended for use by kernel services.
-
- (*) Each process subscribes to three keyrings: a thread-specific keyring, a
-     process-specific keyring, and a session-specific keyring.
-
-     The thread-specific keyring is discarded from the child when any sort of
-     clone, fork, vfork or execve occurs. A new keyring is created only when
-     required.
-
-     The process-specific keyring is replaced with an empty one in the child on
-     clone, fork, vfork unless CLONE_THREAD is supplied, in which case it is
-     shared. execve also discards the process's process keyring and creates a
-     new one.
-
-     The session-specific keyring is persistent across clone, fork, vfork and
-     execve, even when the latter executes a set-UID or set-GID binary. A
-     process can, however, replace its current session keyring with a new one
-     by using PR_JOIN_SESSION_KEYRING. It is permitted to request an anonymous
-     new one, or to attempt to create or join one of a specific name.
-
-     The ownership of the thread keyring changes when the real UID and GID of
-     the thread changes.
-
- (*) Each user ID resident in the system holds two special keyrings: a user
-     specific keyring and a default user session keyring. The default session
-     keyring is initialised with a link to the user-specific keyring.
-
-     When a process changes its real UID, if it used to have no session key, it
-     will be subscribed to the default session key for the new UID.
-
-     If a process attempts to access its session key when it doesn't have one,
-     it will be subscribed to the default for its current UID.
-
- (*) Each user has two quotas against which the keys they own are tracked. One
-     limits the total number of keys and keyrings, the other limits the total
-     amount of description and payload space that can be consumed.
-
-     The user can view information on this and other statistics through procfs
-     files.  The root user may also alter the quota limits through sysctl files
-     (see the section "New procfs files").
-
-     Process-specific and thread-specific keyrings are not counted towards a
-     user's quota.
-
-     If a system call that modifies a key or keyring in some way would put the
-     user over quota, the operation is refused and error EDQUOT is returned.
-
- (*) There's a system call interface by which userspace programs can create and
-     manipulate keys and keyrings.
-
- (*) There's a kernel interface by which services can register types and search
-     for keys.
-
- (*) There's a way for the a search done from the kernel to call back to
-     userspace to request a key that can't be found in a process's keyrings.
-
- (*) An optional filesystem is available through which the key database can be
-     viewed and manipulated.
-
-
-======================
-KEY ACCESS PERMISSIONS
-======================
-
-Keys have an owner user ID, a group access ID, and a permissions mask. The mask
-has up to eight bits each for possessor, user, group and other access. Only
-six of each set of eight bits are defined. These permissions granted are:
-
- (*) View
-
-     This permits a key or keyring's attributes to be viewed - including key
-     type and description.
-
- (*) Read
-
-     This permits a key's payload to be viewed or a keyring's list of linked
-     keys.
-
- (*) Write
-
-     This permits a key's payload to be instantiated or updated, or it allows a
-     link to be added to or removed from a keyring.
-
- (*) Search
-
-     This permits keyrings to be searched and keys to be found. Searches can
-     only recurse into nested keyrings that have search permission set.
-
- (*) Link
-
-     This permits a key or keyring to be linked to. To create a link from a
-     keyring to a key, a process must have Write permission on the keyring and
-     Link permission on the key.
-
- (*) Set Attribute
-
-     This permits a key's UID, GID and permissions mask to be changed.
-
-For changing the ownership, group ID or permissions mask, being the owner of
-the key or having the sysadmin capability is sufficient.
-
-
-===============
-SELINUX SUPPORT
-===============
-
-The security class "key" has been added to SELinux so that mandatory access
-controls can be applied to keys created within various contexts.  This support
-is preliminary, and is likely to change quite significantly in the near future.
-Currently, all of the basic permissions explained above are provided in SELinux
-as well; SELinux is simply invoked after all basic permission checks have been
-performed.
-
-The value of the file /proc/self/attr/keycreate influences the labeling of
-newly-created keys.  If the contents of that file correspond to an SELinux
-security context, then the key will be assigned that context.  Otherwise, the
-key will be assigned the current context of the task that invoked the key
-creation request.  Tasks must be granted explicit permission to assign a
-particular context to newly-created keys, using the "create" permission in the
-key security class.
-
-The default keyrings associated with users will be labeled with the default
-context of the user if and only if the login programs have been instrumented to
-properly initialize keycreate during the login process.  Otherwise, they will
-be labeled with the context of the login program itself.
-
-Note, however, that the default keyrings associated with the root user are
-labeled with the default kernel context, since they are created early in the
-boot process, before root has a chance to log in.
-
-The keyrings associated with new threads are each labeled with the context of
-their associated thread, and both session and process keyrings are handled
-similarly.
-
-
-================
-NEW PROCFS FILES
-================
-
-Two files have been added to procfs by which an administrator can find out
-about the status of the key service:
-
- (*) /proc/keys
-
-     This lists the keys that are currently viewable by the task reading the
-     file, giving information about their type, description and permissions.
-     It is not possible to view the payload of the key this way, though some
-     information about it may be given.
-
-     The only keys included in the list are those that grant View permission to
-     the reading process whether or not it possesses them.  Note that LSM
-     security checks are still performed, and may further filter out keys that
-     the current process is not authorised to view.
-
-     The contents of the file look like this:
-
-	SERIAL   FLAGS  USAGE EXPY PERM     UID   GID   TYPE      DESCRIPTION: SUMMARY
-	00000001 I-----    39 perm 1f3f0000     0     0 keyring   _uid_ses.0: 1/4
-	00000002 I-----     2 perm 1f3f0000     0     0 keyring   _uid.0: empty
-	00000007 I-----     1 perm 1f3f0000     0     0 keyring   _pid.1: empty
-	0000018d I-----     1 perm 1f3f0000     0     0 keyring   _pid.412: empty
-	000004d2 I--Q--     1 perm 1f3f0000    32    -1 keyring   _uid.32: 1/4
-	000004d3 I--Q--     3 perm 1f3f0000    32    -1 keyring   _uid_ses.32: empty
-	00000892 I--QU-     1 perm 1f000000     0     0 user      metal:copper: 0
-	00000893 I--Q-N     1  35s 1f3f0000     0     0 user      metal:silver: 0
-	00000894 I--Q--     1  10h 003f0000     0     0 user      metal:gold: 0
-
-     The flags are:
-
-	I	Instantiated
-	R	Revoked
-	D	Dead
-	Q	Contributes to user's quota
-	U	Under construction by callback to userspace
-	N	Negative key
-
-     This file must be enabled at kernel configuration time as it allows anyone
-     to list the keys database.
-
- (*) /proc/key-users
-
-     This file lists the tracking data for each user that has at least one key
-     on the system.  Such data includes quota information and statistics:
-
-	[root@andromeda root]# cat /proc/key-users
-	0:     46 45/45 1/100 13/10000
-	29:     2 2/2 2/100 40/10000
-	32:     2 2/2 2/100 40/10000
-	38:     2 2/2 2/100 40/10000
-
-     The format of each line is
-	<UID>:			User ID to which this applies
-	<usage>			Structure refcount
-	<inst>/<keys>		Total number of keys and number instantiated
-	<keys>/<max>		Key count quota
-	<bytes>/<max>		Key size quota
-
-
-Four new sysctl files have been added also for the purpose of controlling the
-quota limits on keys:
-
- (*) /proc/sys/kernel/keys/root_maxkeys
-     /proc/sys/kernel/keys/root_maxbytes
-
-     These files hold the maximum number of keys that root may have and the
-     maximum total number of bytes of data that root may have stored in those
-     keys.
-
- (*) /proc/sys/kernel/keys/maxkeys
-     /proc/sys/kernel/keys/maxbytes
-
-     These files hold the maximum number of keys that each non-root user may
-     have and the maximum total number of bytes of data that each of those
-     users may have stored in their keys.
-
-Root may alter these by writing each new limit as a decimal number string to
-the appropriate file.
-
-
-===============================
-USERSPACE SYSTEM CALL INTERFACE
-===============================
-
-Userspace can manipulate keys directly through three new syscalls: add_key,
-request_key and keyctl. The latter provides a number of functions for
-manipulating keys.
-
-When referring to a key directly, userspace programs should use the key's
-serial number (a positive 32-bit integer). However, there are some special
-values available for referring to special keys and keyrings that relate to the
-process making the call:
-
-	CONSTANT			VALUE	KEY REFERENCED
-	==============================	======	===========================
-	KEY_SPEC_THREAD_KEYRING		-1	thread-specific keyring
-	KEY_SPEC_PROCESS_KEYRING	-2	process-specific keyring
-	KEY_SPEC_SESSION_KEYRING	-3	session-specific keyring
-	KEY_SPEC_USER_KEYRING		-4	UID-specific keyring
-	KEY_SPEC_USER_SESSION_KEYRING	-5	UID-session keyring
-	KEY_SPEC_GROUP_KEYRING		-6	GID-specific keyring
-	KEY_SPEC_REQKEY_AUTH_KEY	-7	assumed request_key()
-						  authorisation key
-
-
-The main syscalls are:
-
- (*) Create a new key of given type, description and payload and add it to the
-     nominated keyring:
-
-	key_serial_t add_key(const char *type, const char *desc,
-			     const void *payload, size_t plen,
-			     key_serial_t keyring);
-
-     If a key of the same type and description as that proposed already exists
-     in the keyring, this will try to update it with the given payload, or it
-     will return error EEXIST if that function is not supported by the key
-     type. The process must also have permission to write to the key to be able
-     to update it. The new key will have all user permissions granted and no
-     group or third party permissions.
-
-     Otherwise, this will attempt to create a new key of the specified type and
-     description, and to instantiate it with the supplied payload and attach it
-     to the keyring. In this case, an error will be generated if the process
-     does not have permission to write to the keyring.
-
-     The payload is optional, and the pointer can be NULL if not required by
-     the type. The payload is plen in size, and plen can be zero for an empty
-     payload.
-
-     A new keyring can be generated by setting type "keyring", the keyring name
-     as the description (or NULL) and setting the payload to NULL.
-
-     User defined keys can be created by specifying type "user". It is
-     recommended that a user defined key's description by prefixed with a type
-     ID and a colon, such as "krb5tgt:" for a Kerberos 5 ticket granting
-     ticket.
-
-     Any other type must have been registered with the kernel in advance by a
-     kernel service such as a filesystem.
-
-     The ID of the new or updated key is returned if successful.
-
-
- (*) Search the process's keyrings for a key, potentially calling out to
-     userspace to create it.
-
-	key_serial_t request_key(const char *type, const char *description,
-				 const char *callout_info,
-				 key_serial_t dest_keyring);
-
-     This function searches all the process's keyrings in the order thread,
-     process, session for a matching key. This works very much like
-     KEYCTL_SEARCH, including the optional attachment of the discovered key to
-     a keyring.
-
-     If a key cannot be found, and if callout_info is not NULL, then
-     /sbin/request-key will be invoked in an attempt to obtain a key. The
-     callout_info string will be passed as an argument to the program.
-
-     See also Documentation/keys-request-key.txt.
-
-
-The keyctl syscall functions are:
-
- (*) Map a special key ID to a real key ID for this process:
-
-	key_serial_t keyctl(KEYCTL_GET_KEYRING_ID, key_serial_t id,
-			    int create);
-
-     The special key specified by "id" is looked up (with the key being created
-     if necessary) and the ID of the key or keyring thus found is returned if
-     it exists.
-
-     If the key does not yet exist, the key will be created if "create" is
-     non-zero; and the error ENOKEY will be returned if "create" is zero.
-
-
- (*) Replace the session keyring this process subscribes to with a new one:
-
-	key_serial_t keyctl(KEYCTL_JOIN_SESSION_KEYRING, const char *name);
-
-     If name is NULL, an anonymous keyring is created attached to the process
-     as its session keyring, displacing the old session keyring.
-
-     If name is not NULL, if a keyring of that name exists, the process
-     attempts to attach it as the session keyring, returning an error if that
-     is not permitted; otherwise a new keyring of that name is created and
-     attached as the session keyring.
-
-     To attach to a named keyring, the keyring must have search permission for
-     the process's ownership.
-
-     The ID of the new session keyring is returned if successful.
-
-
- (*) Update the specified key:
-
-	long keyctl(KEYCTL_UPDATE, key_serial_t key, const void *payload,
-		    size_t plen);
-
-     This will try to update the specified key with the given payload, or it
-     will return error EOPNOTSUPP if that function is not supported by the key
-     type. The process must also have permission to write to the key to be able
-     to update it.
-
-     The payload is of length plen, and may be absent or empty as for
-     add_key().
-
-
- (*) Revoke a key:
-
-	long keyctl(KEYCTL_REVOKE, key_serial_t key);
-
-     This makes a key unavailable for further operations. Further attempts to
-     use the key will be met with error EKEYREVOKED, and the key will no longer
-     be findable.
-
-
- (*) Change the ownership of a key:
-
-	long keyctl(KEYCTL_CHOWN, key_serial_t key, uid_t uid, gid_t gid);
-
-     This function permits a key's owner and group ID to be changed. Either one
-     of uid or gid can be set to -1 to suppress that change.
-
-     Only the superuser can change a key's owner to something other than the
-     key's current owner. Similarly, only the superuser can change a key's
-     group ID to something other than the calling process's group ID or one of
-     its group list members.
-
-
- (*) Change the permissions mask on a key:
-
-	long keyctl(KEYCTL_SETPERM, key_serial_t key, key_perm_t perm);
-
-     This function permits the owner of a key or the superuser to change the
-     permissions mask on a key.
-
-     Only bits the available bits are permitted; if any other bits are set,
-     error EINVAL will be returned.
-
-
- (*) Describe a key:
-
-	long keyctl(KEYCTL_DESCRIBE, key_serial_t key, char *buffer,
-		    size_t buflen);
-
-     This function returns a summary of the key's attributes (but not its
-     payload data) as a string in the buffer provided.
-
-     Unless there's an error, it always returns the amount of data it could
-     produce, even if that's too big for the buffer, but it won't copy more
-     than requested to userspace. If the buffer pointer is NULL then no copy
-     will take place.
-
-     A process must have view permission on the key for this function to be
-     successful.
-
-     If successful, a string is placed in the buffer in the following format:
-
-	<type>;<uid>;<gid>;<perm>;<description>
-
-     Where type and description are strings, uid and gid are decimal, and perm
-     is hexadecimal. A NUL character is included at the end of the string if
-     the buffer is sufficiently big.
-
-     This can be parsed with
-
-	sscanf(buffer, "%[^;];%d;%d;%o;%s", type, &uid, &gid, &mode, desc);
-
-
- (*) Clear out a keyring:
-
-	long keyctl(KEYCTL_CLEAR, key_serial_t keyring);
-
-     This function clears the list of keys attached to a keyring. The calling
-     process must have write permission on the keyring, and it must be a
-     keyring (or else error ENOTDIR will result).
-
-
- (*) Link a key into a keyring:
-
-	long keyctl(KEYCTL_LINK, key_serial_t keyring, key_serial_t key);
-
-     This function creates a link from the keyring to the key. The process must
-     have write permission on the keyring and must have link permission on the
-     key.
-
-     Should the keyring not be a keyring, error ENOTDIR will result; and if the
-     keyring is full, error ENFILE will result.
-
-     The link procedure checks the nesting of the keyrings, returning ELOOP if
-     it appears too deep or EDEADLK if the link would introduce a cycle.
-
-     Any links within the keyring to keys that match the new key in terms of
-     type and description will be discarded from the keyring as the new one is
-     added.
-
-
- (*) Unlink a key or keyring from another keyring:
-
-	long keyctl(KEYCTL_UNLINK, key_serial_t keyring, key_serial_t key);
-
-     This function looks through the keyring for the first link to the
-     specified key, and removes it if found. Subsequent links to that key are
-     ignored. The process must have write permission on the keyring.
-
-     If the keyring is not a keyring, error ENOTDIR will result; and if the key
-     is not present, error ENOENT will be the result.
-
-
- (*) Search a keyring tree for a key:
-
-	key_serial_t keyctl(KEYCTL_SEARCH, key_serial_t keyring,
-			    const char *type, const char *description,
-			    key_serial_t dest_keyring);
-
-     This searches the keyring tree headed by the specified keyring until a key
-     is found that matches the type and description criteria. Each keyring is
-     checked for keys before recursion into its children occurs.
-
-     The process must have search permission on the top level keyring, or else
-     error EACCES will result. Only keyrings that the process has search
-     permission on will be recursed into, and only keys and keyrings for which
-     a process has search permission can be matched. If the specified keyring
-     is not a keyring, ENOTDIR will result.
-
-     If the search succeeds, the function will attempt to link the found key
-     into the destination keyring if one is supplied (non-zero ID). All the
-     constraints applicable to KEYCTL_LINK apply in this case too.
-
-     Error ENOKEY, EKEYREVOKED or EKEYEXPIRED will be returned if the search
-     fails. On success, the resulting key ID will be returned.
-
-
- (*) Read the payload data from a key:
-
-	long keyctl(KEYCTL_READ, key_serial_t keyring, char *buffer,
-		    size_t buflen);
-
-     This function attempts to read the payload data from the specified key
-     into the buffer. The process must have read permission on the key to
-     succeed.
-
-     The returned data will be processed for presentation by the key type. For
-     instance, a keyring will return an array of key_serial_t entries
-     representing the IDs of all the keys to which it is subscribed. The user
-     defined key type will return its data as is. If a key type does not
-     implement this function, error EOPNOTSUPP will result.
-
-     As much of the data as can be fitted into the buffer will be copied to
-     userspace if the buffer pointer is not NULL.
-
-     On a successful return, the function will always return the amount of data
-     available rather than the amount copied.
-
-
- (*) Instantiate a partially constructed key.
-
-	long keyctl(KEYCTL_INSTANTIATE, key_serial_t key,
-		    const void *payload, size_t plen,
-		    key_serial_t keyring);
-	long keyctl(KEYCTL_INSTANTIATE_IOV, key_serial_t key,
-		    const struct iovec *payload_iov, unsigned ioc,
-		    key_serial_t keyring);
-
-     If the kernel calls back to userspace to complete the instantiation of a
-     key, userspace should use this call to supply data for the key before the
-     invoked process returns, or else the key will be marked negative
-     automatically.
-
-     The process must have write access on the key to be able to instantiate
-     it, and the key must be uninstantiated.
-
-     If a keyring is specified (non-zero), the key will also be linked into
-     that keyring, however all the constraints applying in KEYCTL_LINK apply in
-     this case too.
-
-     The payload and plen arguments describe the payload data as for add_key().
-
-     The payload_iov and ioc arguments describe the payload data in an iovec
-     array instead of a single buffer.
-
-
- (*) Negatively instantiate a partially constructed key.
-
-	long keyctl(KEYCTL_NEGATE, key_serial_t key,
-		    unsigned timeout, key_serial_t keyring);
-	long keyctl(KEYCTL_REJECT, key_serial_t key,
-		    unsigned timeout, unsigned error, key_serial_t keyring);
-
-     If the kernel calls back to userspace to complete the instantiation of a
-     key, userspace should use this call mark the key as negative before the
-     invoked process returns if it is unable to fulfil the request.
-
-     The process must have write access on the key to be able to instantiate
-     it, and the key must be uninstantiated.
-
-     If a keyring is specified (non-zero), the key will also be linked into
-     that keyring, however all the constraints applying in KEYCTL_LINK apply in
-     this case too.
-
-     If the key is rejected, future searches for it will return the specified
-     error code until the rejected key expires.  Negating the key is the same
-     as rejecting the key with ENOKEY as the error code.
-
-
- (*) Set the default request-key destination keyring.
-
-	long keyctl(KEYCTL_SET_REQKEY_KEYRING, int reqkey_defl);
-
-     This sets the default keyring to which implicitly requested keys will be
-     attached for this thread. reqkey_defl should be one of these constants:
-
-	CONSTANT				VALUE	NEW DEFAULT KEYRING
-	======================================	======	=======================
-	KEY_REQKEY_DEFL_NO_CHANGE		-1	No change
-	KEY_REQKEY_DEFL_DEFAULT			0	Default[1]
-	KEY_REQKEY_DEFL_THREAD_KEYRING		1	Thread keyring
-	KEY_REQKEY_DEFL_PROCESS_KEYRING		2	Process keyring
-	KEY_REQKEY_DEFL_SESSION_KEYRING		3	Session keyring
-	KEY_REQKEY_DEFL_USER_KEYRING		4	User keyring
-	KEY_REQKEY_DEFL_USER_SESSION_KEYRING	5	User session keyring
-	KEY_REQKEY_DEFL_GROUP_KEYRING		6	Group keyring
-
-     The old default will be returned if successful and error EINVAL will be
-     returned if reqkey_defl is not one of the above values.
-
-     The default keyring can be overridden by the keyring indicated to the
-     request_key() system call.
-
-     Note that this setting is inherited across fork/exec.
-
-     [1] The default is: the thread keyring if there is one, otherwise
-     the process keyring if there is one, otherwise the session keyring if
-     there is one, otherwise the user default session keyring.
-
-
- (*) Set the timeout on a key.
-
-	long keyctl(KEYCTL_SET_TIMEOUT, key_serial_t key, unsigned timeout);
-
-     This sets or clears the timeout on a key. The timeout can be 0 to clear
-     the timeout or a number of seconds to set the expiry time that far into
-     the future.
-
-     The process must have attribute modification access on a key to set its
-     timeout. Timeouts may not be set with this function on negative, revoked
-     or expired keys.
-
-
- (*) Assume the authority granted to instantiate a key
-
-	long keyctl(KEYCTL_ASSUME_AUTHORITY, key_serial_t key);
-
-     This assumes or divests the authority required to instantiate the
-     specified key. Authority can only be assumed if the thread has the
-     authorisation key associated with the specified key in its keyrings
-     somewhere.
-
-     Once authority is assumed, searches for keys will also search the
-     requester's keyrings using the requester's security label, UID, GID and
-     groups.
-
-     If the requested authority is unavailable, error EPERM will be returned,
-     likewise if the authority has been revoked because the target key is
-     already instantiated.
-
-     If the specified key is 0, then any assumed authority will be divested.
-
-     The assumed authoritative key is inherited across fork and exec.
-
-
- (*) Get the LSM security context attached to a key.
-
-	long keyctl(KEYCTL_GET_SECURITY, key_serial_t key, char *buffer,
-		    size_t buflen)
-
-     This function returns a string that represents the LSM security context
-     attached to a key in the buffer provided.
-
-     Unless there's an error, it always returns the amount of data it could
-     produce, even if that's too big for the buffer, but it won't copy more
-     than requested to userspace. If the buffer pointer is NULL then no copy
-     will take place.
-
-     A NUL character is included at the end of the string if the buffer is
-     sufficiently big.  This is included in the returned count.  If no LSM is
-     in force then an empty string will be returned.
-
-     A process must have view permission on the key for this function to be
-     successful.
-
-
- (*) Install the calling process's session keyring on its parent.
-
-	long keyctl(KEYCTL_SESSION_TO_PARENT);
-
-     This functions attempts to install the calling process's session keyring
-     on to the calling process's parent, replacing the parent's current session
-     keyring.
-
-     The calling process must have the same ownership as its parent, the
-     keyring must have the same ownership as the calling process, the calling
-     process must have LINK permission on the keyring and the active LSM module
-     mustn't deny permission, otherwise error EPERM will be returned.
-
-     Error ENOMEM will be returned if there was insufficient memory to complete
-     the operation, otherwise 0 will be returned to indicate success.
-
-     The keyring will be replaced next time the parent process leaves the
-     kernel and resumes executing userspace.
-
-
-===============
-KERNEL SERVICES
-===============
-
-The kernel services for key management are fairly simple to deal with. They can
-be broken down into two areas: keys and key types.
-
-Dealing with keys is fairly straightforward. Firstly, the kernel service
-registers its type, then it searches for a key of that type. It should retain
-the key as long as it has need of it, and then it should release it. For a
-filesystem or device file, a search would probably be performed during the open
-call, and the key released upon close. How to deal with conflicting keys due to
-two different users opening the same file is left to the filesystem author to
-solve.
-
-To access the key manager, the following header must be #included:
-
-	<linux/key.h>
-
-Specific key types should have a header file under include/keys/ that should be
-used to access that type.  For keys of type "user", for example, that would be:
-
-	<keys/user-type.h>
-
-Note that there are two different types of pointers to keys that may be
-encountered:
-
- (*) struct key *
-
-     This simply points to the key structure itself. Key structures will be at
-     least four-byte aligned.
-
- (*) key_ref_t
-
-     This is equivalent to a struct key *, but the least significant bit is set
-     if the caller "possesses" the key. By "possession" it is meant that the
-     calling processes has a searchable link to the key from one of its
-     keyrings. There are three functions for dealing with these:
-
-	key_ref_t make_key_ref(const struct key *key,
-			       unsigned long possession);
-
-	struct key *key_ref_to_ptr(const key_ref_t key_ref);
-
-	unsigned long is_key_possessed(const key_ref_t key_ref);
-
-     The first function constructs a key reference from a key pointer and
-     possession information (which must be 0 or 1 and not any other value).
-
-     The second function retrieves the key pointer from a reference and the
-     third retrieves the possession flag.
-
-When accessing a key's payload contents, certain precautions must be taken to
-prevent access vs modification races. See the section "Notes on accessing
-payload contents" for more information.
-
-(*) To search for a key, call:
-
-	struct key *request_key(const struct key_type *type,
-				const char *description,
-				const char *callout_info);
-
-    This is used to request a key or keyring with a description that matches
-    the description specified according to the key type's match function. This
-    permits approximate matching to occur. If callout_string is not NULL, then
-    /sbin/request-key will be invoked in an attempt to obtain the key from
-    userspace. In that case, callout_string will be passed as an argument to
-    the program.
-
-    Should the function fail error ENOKEY, EKEYEXPIRED or EKEYREVOKED will be
-    returned.
-
-    If successful, the key will have been attached to the default keyring for
-    implicitly obtained request-key keys, as set by KEYCTL_SET_REQKEY_KEYRING.
-
-    See also Documentation/keys-request-key.txt.
-
-
-(*) To search for a key, passing auxiliary data to the upcaller, call:
-
-	struct key *request_key_with_auxdata(const struct key_type *type,
-					     const char *description,
-					     const void *callout_info,
-					     size_t callout_len,
-					     void *aux);
-
-    This is identical to request_key(), except that the auxiliary data is
-    passed to the key_type->request_key() op if it exists, and the callout_info
-    is a blob of length callout_len, if given (the length may be 0).
-
-
-(*) A key can be requested asynchronously by calling one of:
-
-	struct key *request_key_async(const struct key_type *type,
-				      const char *description,
-				      const void *callout_info,
-				      size_t callout_len);
-
-    or:
-
-	struct key *request_key_async_with_auxdata(const struct key_type *type,
-						   const char *description,
-						   const char *callout_info,
-					     	   size_t callout_len,
-					     	   void *aux);
-
-    which are asynchronous equivalents of request_key() and
-    request_key_with_auxdata() respectively.
-
-    These two functions return with the key potentially still under
-    construction.  To wait for construction completion, the following should be
-    called:
-
-	int wait_for_key_construction(struct key *key, bool intr);
-
-    The function will wait for the key to finish being constructed and then
-    invokes key_validate() to return an appropriate value to indicate the state
-    of the key (0 indicates the key is usable).
-
-    If intr is true, then the wait can be interrupted by a signal, in which
-    case error ERESTARTSYS will be returned.
-
-
-(*) When it is no longer required, the key should be released using:
-
-	void key_put(struct key *key);
-
-    Or:
-
-	void key_ref_put(key_ref_t key_ref);
-
-    These can be called from interrupt context. If CONFIG_KEYS is not set then
-    the argument will not be parsed.
-
-
-(*) Extra references can be made to a key by calling the following function:
-
-	struct key *key_get(struct key *key);
-
-    These need to be disposed of by calling key_put() when they've been
-    finished with. The key pointer passed in will be returned. If the pointer
-    is NULL or CONFIG_KEYS is not set then the key will not be dereferenced and
-    no increment will take place.
-
-
-(*) A key's serial number can be obtained by calling:
-
-	key_serial_t key_serial(struct key *key);
-
-    If key is NULL or if CONFIG_KEYS is not set then 0 will be returned (in the
-    latter case without parsing the argument).
-
-
-(*) If a keyring was found in the search, this can be further searched by:
-
-	key_ref_t keyring_search(key_ref_t keyring_ref,
-				 const struct key_type *type,
-				 const char *description)
-
-    This searches the keyring tree specified for a matching key. Error ENOKEY
-    is returned upon failure (use IS_ERR/PTR_ERR to determine). If successful,
-    the returned key will need to be released.
-
-    The possession attribute from the keyring reference is used to control
-    access through the permissions mask and is propagated to the returned key
-    reference pointer if successful.
-
-
-(*) To check the validity of a key, this function can be called:
-
-	int validate_key(struct key *key);
-
-    This checks that the key in question hasn't expired or and hasn't been
-    revoked. Should the key be invalid, error EKEYEXPIRED or EKEYREVOKED will
-    be returned. If the key is NULL or if CONFIG_KEYS is not set then 0 will be
-    returned (in the latter case without parsing the argument).
-
-
-(*) To register a key type, the following function should be called:
-
-	int register_key_type(struct key_type *type);
-
-    This will return error EEXIST if a type of the same name is already
-    present.
-
-
-(*) To unregister a key type, call:
-
-	void unregister_key_type(struct key_type *type);
-
-
-Under some circumstances, it may be desirable to deal with a bundle of keys.
-The facility provides access to the keyring type for managing such a bundle:
-
-	struct key_type key_type_keyring;
-
-This can be used with a function such as request_key() to find a specific
-keyring in a process's keyrings.  A keyring thus found can then be searched
-with keyring_search().  Note that it is not possible to use request_key() to
-search a specific keyring, so using keyrings in this way is of limited utility.
-
-
-===================================
-NOTES ON ACCESSING PAYLOAD CONTENTS
-===================================
-
-The simplest payload is just a number in key->payload.value. In this case,
-there's no need to indulge in RCU or locking when accessing the payload.
-
-More complex payload contents must be allocated and a pointer to them set in
-key->payload.data. One of the following ways must be selected to access the
-data:
-
- (1) Unmodifiable key type.
-
-     If the key type does not have a modify method, then the key's payload can
-     be accessed without any form of locking, provided that it's known to be
-     instantiated (uninstantiated keys cannot be "found").
-
- (2) The key's semaphore.
-
-     The semaphore could be used to govern access to the payload and to control
-     the payload pointer. It must be write-locked for modifications and would
-     have to be read-locked for general access. The disadvantage of doing this
-     is that the accessor may be required to sleep.
-
- (3) RCU.
-
-     RCU must be used when the semaphore isn't already held; if the semaphore
-     is held then the contents can't change under you unexpectedly as the
-     semaphore must still be used to serialise modifications to the key. The
-     key management code takes care of this for the key type.
-
-     However, this means using:
-
-	rcu_read_lock() ... rcu_dereference() ... rcu_read_unlock()
-
-     to read the pointer, and:
-
-	rcu_dereference() ... rcu_assign_pointer() ... call_rcu()
-
-     to set the pointer and dispose of the old contents after a grace period.
-     Note that only the key type should ever modify a key's payload.
-
-     Furthermore, an RCU controlled payload must hold a struct rcu_head for the
-     use of call_rcu() and, if the payload is of variable size, the length of
-     the payload. key->datalen cannot be relied upon to be consistent with the
-     payload just dereferenced if the key's semaphore is not held.
-
-
-===================
-DEFINING A KEY TYPE
-===================
-
-A kernel service may want to define its own key type. For instance, an AFS
-filesystem might want to define a Kerberos 5 ticket key type. To do this, it
-author fills in a key_type struct and registers it with the system.
-
-Source files that implement key types should include the following header file:
-
-	<linux/key-type.h>
-
-The structure has a number of fields, some of which are mandatory:
-
- (*) const char *name
-
-     The name of the key type. This is used to translate a key type name
-     supplied by userspace into a pointer to the structure.
-
-
- (*) size_t def_datalen
-
-     This is optional - it supplies the default payload data length as
-     contributed to the quota. If the key type's payload is always or almost
-     always the same size, then this is a more efficient way to do things.
-
-     The data length (and quota) on a particular key can always be changed
-     during instantiation or update by calling:
-
-	int key_payload_reserve(struct key *key, size_t datalen);
-
-     With the revised data length. Error EDQUOT will be returned if this is not
-     viable.
-
-
- (*) int (*vet_description)(const char *description);
-
-     This optional method is called to vet a key description.  If the key type
-     doesn't approve of the key description, it may return an error, otherwise
-     it should return 0.
-
-
- (*) int (*instantiate)(struct key *key, const void *data, size_t datalen);
-
-     This method is called to attach a payload to a key during construction.
-     The payload attached need not bear any relation to the data passed to this
-     function.
-
-     If the amount of data attached to the key differs from the size in
-     keytype->def_datalen, then key_payload_reserve() should be called.
-
-     This method does not have to lock the key in order to attach a payload.
-     The fact that KEY_FLAG_INSTANTIATED is not set in key->flags prevents
-     anything else from gaining access to the key.
-
-     It is safe to sleep in this method.
-
-
- (*) int (*update)(struct key *key, const void *data, size_t datalen);
-
-     If this type of key can be updated, then this method should be provided.
-     It is called to update a key's payload from the blob of data provided.
-
-     key_payload_reserve() should be called if the data length might change
-     before any changes are actually made. Note that if this succeeds, the type
-     is committed to changing the key because it's already been altered, so all
-     memory allocation must be done first.
-
-     The key will have its semaphore write-locked before this method is called,
-     but this only deters other writers; any changes to the key's payload must
-     be made under RCU conditions, and call_rcu() must be used to dispose of
-     the old payload.
-
-     key_payload_reserve() should be called before the changes are made, but
-     after all allocations and other potentially failing function calls are
-     made.
-
-     It is safe to sleep in this method.
-
-
- (*) int (*match)(const struct key *key, const void *desc);
-
-     This method is called to match a key against a description. It should
-     return non-zero if the two match, zero if they don't.
-
-     This method should not need to lock the key in any way. The type and
-     description can be considered invariant, and the payload should not be
-     accessed (the key may not yet be instantiated).
-
-     It is not safe to sleep in this method; the caller may hold spinlocks.
-
-
- (*) void (*revoke)(struct key *key);
-
-     This method is optional.  It is called to discard part of the payload
-     data upon a key being revoked.  The caller will have the key semaphore
-     write-locked.
-
-     It is safe to sleep in this method, though care should be taken to avoid
-     a deadlock against the key semaphore.
-
-
- (*) void (*destroy)(struct key *key);
-
-     This method is optional. It is called to discard the payload data on a key
-     when it is being destroyed.
-
-     This method does not need to lock the key to access the payload; it can
-     consider the key as being inaccessible at this time. Note that the key's
-     type may have been changed before this function is called.
-
-     It is not safe to sleep in this method; the caller may hold spinlocks.
-
-
- (*) void (*describe)(const struct key *key, struct seq_file *p);
-
-     This method is optional. It is called during /proc/keys reading to
-     summarise a key's description and payload in text form.
-
-     This method will be called with the RCU read lock held. rcu_dereference()
-     should be used to read the payload pointer if the payload is to be
-     accessed. key->datalen cannot be trusted to stay consistent with the
-     contents of the payload.
-
-     The description will not change, though the key's state may.
-
-     It is not safe to sleep in this method; the RCU read lock is held by the
-     caller.
-
-
- (*) long (*read)(const struct key *key, char __user *buffer, size_t buflen);
-
-     This method is optional. It is called by KEYCTL_READ to translate the
-     key's payload into something a blob of data for userspace to deal with.
-     Ideally, the blob should be in the same format as that passed in to the
-     instantiate and update methods.
-
-     If successful, the blob size that could be produced should be returned
-     rather than the size copied.
-
-     This method will be called with the key's semaphore read-locked. This will
-     prevent the key's payload changing. It is not necessary to use RCU locking
-     when accessing the key's payload. It is safe to sleep in this method, such
-     as might happen when the userspace buffer is accessed.
-
-
- (*) int (*request_key)(struct key_construction *cons, const char *op,
-			void *aux);
-
-     This method is optional.  If provided, request_key() and friends will
-     invoke this function rather than upcalling to /sbin/request-key to operate
-     upon a key of this type.
-
-     The aux parameter is as passed to request_key_async_with_auxdata() and
-     similar or is NULL otherwise.  Also passed are the construction record for
-     the key to be operated upon and the operation type (currently only
-     "create").
-
-     This method is permitted to return before the upcall is complete, but the
-     following function must be called under all circumstances to complete the
-     instantiation process, whether or not it succeeds, whether or not there's
-     an error:
-
-	void complete_request_key(struct key_construction *cons, int error);
-
-     The error parameter should be 0 on success, -ve on error.  The
-     construction record is destroyed by this action and the authorisation key
-     will be revoked.  If an error is indicated, the key under construction
-     will be negatively instantiated if it wasn't already instantiated.
-
-     If this method returns an error, that error will be returned to the
-     caller of request_key*().  complete_request_key() must be called prior to
-     returning.
-
-     The key under construction and the authorisation key can be found in the
-     key_construction struct pointed to by cons:
-
-     (*) struct key *key;
-
-     	 The key under construction.
-
-     (*) struct key *authkey;
-
-     	 The authorisation key.
-
-
-============================
-REQUEST-KEY CALLBACK SERVICE
-============================
-
-To create a new key, the kernel will attempt to execute the following command
-line:
-
-	/sbin/request-key create <key> <uid> <gid> \
-		<threadring> <processring> <sessionring> <callout_info>
-
-<key> is the key being constructed, and the three keyrings are the process
-keyrings from the process that caused the search to be issued. These are
-included for two reasons:
-
-  (1) There may be an authentication token in one of the keyrings that is
-      required to obtain the key, eg: a Kerberos Ticket-Granting Ticket.
-
-  (2) The new key should probably be cached in one of these rings.
-
-This program should set it UID and GID to those specified before attempting to
-access any more keys. It may then look around for a user specific process to
-hand the request off to (perhaps a path held in placed in another key by, for
-example, the KDE desktop manager).
-
-The program (or whatever it calls) should finish construction of the key by
-calling KEYCTL_INSTANTIATE or KEYCTL_INSTANTIATE_IOV, which also permits it to
-cache the key in one of the keyrings (probably the session ring) before
-returning.  Alternatively, the key can be marked as negative with KEYCTL_NEGATE
-or KEYCTL_REJECT; this also permits the key to be cached in one of the
-keyrings.
-
-If it returns with the key remaining in the unconstructed state, the key will
-be marked as being negative, it will be added to the session keyring, and an
-error will be returned to the key requestor.
-
-Supplementary information may be provided from whoever or whatever invoked this
-service. This will be passed as the <callout_info> parameter. If no such
-information was made available, then "-" will be passed as this parameter
-instead.
-
-
-Similarly, the kernel may attempt to update an expired or a soon to expire key
-by executing:
-
-	/sbin/request-key update <key> <uid> <gid> \
-		<threadring> <processring> <sessionring>
-
-In this case, the program isn't required to actually attach the key to a ring;
-the rings are provided for reference.
-
-
-==================
-GARBAGE COLLECTION
-==================
-
-Dead keys (for which the type has been removed) will be automatically unlinked
-from those keyrings that point to them and deleted as soon as possible by a
-background garbage collector.
-
-Similarly, revoked and expired keys will be garbage collected, but only after a
-certain amount of time has passed.  This time is set as a number of seconds in:
-
-	/proc/sys/kernel/keys/gc_delay
diff -druN linux-2.6.39-libre/Documentation/kmemleak.txt linux-3.0-rc7-libre/Documentation/kmemleak.txt
--- linux-2.6.39-libre/Documentation/kmemleak.txt	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/Documentation/kmemleak.txt	2011-07-11 19:51:52.000000000 -0400
@@ -11,7 +11,9 @@
 reported via /sys/kernel/debug/kmemleak. A similar method is used by the
 Valgrind tool (memcheck --leak-check) to detect the memory leaks in
 user-space applications.
-Kmemleak is supported on x86, arm, powerpc, sparc, sh, microblaze and tile.
+
+Please check DEBUG_KMEMLEAK dependencies in lib/Kconfig.debug for supported
+architectures.
 
 Usage
 -----
diff -druN linux-2.6.39-libre/Documentation/kvm/api.txt linux-3.0-rc7-libre/Documentation/kvm/api.txt
--- linux-2.6.39-libre/Documentation/kvm/api.txt	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/Documentation/kvm/api.txt	1969-12-31 19:00:00.000000000 -0500
@@ -1,1451 +0,0 @@
-The Definitive KVM (Kernel-based Virtual Machine) API Documentation
-===================================================================
-
-1. General description
-
-The kvm API is a set of ioctls that are issued to control various aspects
-of a virtual machine.  The ioctls belong to three classes
-
- - System ioctls: These query and set global attributes which affect the
-   whole kvm subsystem.  In addition a system ioctl is used to create
-   virtual machines
-
- - VM ioctls: These query and set attributes that affect an entire virtual
-   machine, for example memory layout.  In addition a VM ioctl is used to
-   create virtual cpus (vcpus).
-
-   Only run VM ioctls from the same process (address space) that was used
-   to create the VM.
-
- - vcpu ioctls: These query and set attributes that control the operation
-   of a single virtual cpu.
-
-   Only run vcpu ioctls from the same thread that was used to create the
-   vcpu.
-
-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 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
-actually running guest code.
-
-In general file descriptors can be migrated among processes by means
-of fork() and the SCM_RIGHTS facility of unix domain socket.  These
-kinds of tricks are explicitly not supported by kvm.  While they will
-not cause harm to the host, their actual behavior is not guaranteed by
-the API.  The only supported use is one virtual machine per process,
-and one vcpu per thread.
-
-3. Extensions
-
-As of Linux 2.6.22, the KVM ABI has been stabilized: no backward
-incompatible change are allowed.  However, there is an extension
-facility that allows backward-compatible extensions to the API to be
-queried and used.
-
-The extension mechanism is not based on on the Linux version number.
-Instead, kvm defines extension identifiers and a facility to query
-whether a particular extension identifier is available.  If it is, a
-set of ioctls is available for application use.
-
-4. API description
-
-This section describes ioctls that can be used to control kvm guests.
-For each ioctl, the following information is provided along with a
-description:
-
-  Capability: which KVM extension provides this ioctl.  Can be 'basic',
-      which means that is will be provided by any kernel that supports
-      API version 12 (see section 4.1), or a KVM_CAP_xyz constant, which
-      means availability needs to be checked with KVM_CHECK_EXTENSION
-      (see section 4.4).
-
-  Architectures: which instruction set architectures provide this ioctl.
-      x86 includes both i386 and x86_64.
-
-  Type: system, vm, or vcpu.
-
-  Parameters: what parameters are accepted by the ioctl.
-
-  Returns: the return value.  General error numbers (EBADF, ENOMEM, EINVAL)
-      are not detailed, but errors with specific meanings are.
-
-4.1 KVM_GET_API_VERSION
-
-Capability: basic
-Architectures: all
-Type: system ioctl
-Parameters: none
-Returns: the constant KVM_API_VERSION (=12)
-
-This identifies the API version as the stable kvm API. It is not
-expected that this number will change.  However, Linux 2.6.20 and
-2.6.21 report earlier versions; these are not documented and not
-supported.  Applications should refuse to run if KVM_GET_API_VERSION
-returns a value other than 12.  If this check passes, all ioctls
-described as 'basic' will be available.
-
-4.2 KVM_CREATE_VM
-
-Capability: basic
-Architectures: all
-Type: system ioctl
-Parameters: none
-Returns: a VM fd that can be used to control the new virtual machine.
-
-The new VM has no virtual cpus and no memory.  An mmap() of a VM fd
-will access the virtual machine's physical address space; offset zero
-corresponds to guest physical address zero.  Use of mmap() on a VM fd
-is discouraged if userspace memory allocation (KVM_CAP_USER_MEMORY) is
-available.
-
-4.3 KVM_GET_MSR_INDEX_LIST
-
-Capability: basic
-Architectures: x86
-Type: system
-Parameters: struct kvm_msr_list (in/out)
-Returns: 0 on success; -1 on error
-Errors:
-  E2BIG:     the msr index list is to be to fit in the array specified by
-             the user.
-
-struct kvm_msr_list {
-	__u32 nmsrs; /* number of msrs in entries */
-	__u32 indices[0];
-};
-
-This ioctl returns the guest msrs that are supported.  The list varies
-by kvm version and host processor, but does not change otherwise.  The
-user fills in the size of the indices array in nmsrs, and in return
-kvm adjusts nmsrs to reflect the actual number of msrs and fills in
-the indices array with their numbers.
-
-Note: if kvm indicates supports MCE (KVM_CAP_MCE), then the MCE bank MSRs are
-not returned in the MSR list, as different vcpus can have a different number
-of banks, as set via the KVM_X86_SETUP_MCE ioctl.
-
-4.4 KVM_CHECK_EXTENSION
-
-Capability: basic
-Architectures: all
-Type: system ioctl
-Parameters: extension identifier (KVM_CAP_*)
-Returns: 0 if unsupported; 1 (or some other positive integer) if supported
-
-The API allows the application to query about extensions to the core
-kvm API.  Userspace passes an extension identifier (an integer) and
-receives an integer that describes the extension availability.
-Generally 0 means no and 1 means yes, but some extensions may report
-additional information in the integer return value.
-
-4.5 KVM_GET_VCPU_MMAP_SIZE
-
-Capability: basic
-Architectures: all
-Type: system ioctl
-Parameters: none
-Returns: size of vcpu mmap area, in bytes
-
-The KVM_RUN ioctl (cf.) communicates with userspace via a shared
-memory region.  This ioctl returns the size of that region.  See the
-KVM_RUN documentation for details.
-
-4.6 KVM_SET_MEMORY_REGION
-
-Capability: basic
-Architectures: all
-Type: vm ioctl
-Parameters: struct kvm_memory_region (in)
-Returns: 0 on success, -1 on error
-
-This ioctl is obsolete and has been removed.
-
-4.7 KVM_CREATE_VCPU
-
-Capability: basic
-Architectures: all
-Type: vm ioctl
-Parameters: vcpu id (apic id on x86)
-Returns: vcpu fd on success, -1 on error
-
-This API adds a vcpu to a virtual machine.  The vcpu id is a small integer
-in the range [0, max_vcpus).
-
-4.8 KVM_GET_DIRTY_LOG (vm ioctl)
-
-Capability: basic
-Architectures: x86
-Type: vm ioctl
-Parameters: struct kvm_dirty_log (in/out)
-Returns: 0 on success, -1 on error
-
-/* for KVM_GET_DIRTY_LOG */
-struct kvm_dirty_log {
-	__u32 slot;
-	__u32 padding;
-	union {
-		void __user *dirty_bitmap; /* one bit per page */
-		__u64 padding;
-	};
-};
-
-Given a memory slot, return a bitmap containing any pages dirtied
-since the last call to this ioctl.  Bit 0 is the first page in the
-memory slot.  Ensure the entire structure is cleared to avoid padding
-issues.
-
-4.9 KVM_SET_MEMORY_ALIAS
-
-Capability: basic
-Architectures: x86
-Type: vm ioctl
-Parameters: struct kvm_memory_alias (in)
-Returns: 0 (success), -1 (error)
-
-This ioctl is obsolete and has been removed.
-
-4.10 KVM_RUN
-
-Capability: basic
-Architectures: all
-Type: vcpu ioctl
-Parameters: none
-Returns: 0 on success, -1 on error
-Errors:
-  EINTR:     an unmasked signal is pending
-
-This ioctl is used to run a guest virtual cpu.  While there are no
-explicit parameters, there is an implicit parameter block that can be
-obtained by mmap()ing the vcpu fd at offset 0, with the size given by
-KVM_GET_VCPU_MMAP_SIZE.  The parameter block is formatted as a 'struct
-kvm_run' (see below).
-
-4.11 KVM_GET_REGS
-
-Capability: basic
-Architectures: all
-Type: vcpu ioctl
-Parameters: struct kvm_regs (out)
-Returns: 0 on success, -1 on error
-
-Reads the general purpose registers from the vcpu.
-
-/* x86 */
-struct kvm_regs {
-	/* out (KVM_GET_REGS) / in (KVM_SET_REGS) */
-	__u64 rax, rbx, rcx, rdx;
-	__u64 rsi, rdi, rsp, rbp;
-	__u64 r8,  r9,  r10, r11;
-	__u64 r12, r13, r14, r15;
-	__u64 rip, rflags;
-};
-
-4.12 KVM_SET_REGS
-
-Capability: basic
-Architectures: all
-Type: vcpu ioctl
-Parameters: struct kvm_regs (in)
-Returns: 0 on success, -1 on error
-
-Writes the general purpose registers into the vcpu.
-
-See KVM_GET_REGS for the data structure.
-
-4.13 KVM_GET_SREGS
-
-Capability: basic
-Architectures: x86
-Type: vcpu ioctl
-Parameters: struct kvm_sregs (out)
-Returns: 0 on success, -1 on error
-
-Reads special registers from the vcpu.
-
-/* x86 */
-struct kvm_sregs {
-	struct kvm_segment cs, ds, es, fs, gs, ss;
-	struct kvm_segment tr, ldt;
-	struct kvm_dtable gdt, idt;
-	__u64 cr0, cr2, cr3, cr4, cr8;
-	__u64 efer;
-	__u64 apic_base;
-	__u64 interrupt_bitmap[(KVM_NR_INTERRUPTS + 63) / 64];
-};
-
-interrupt_bitmap is a bitmap of pending external interrupts.  At most
-one bit may be set.  This interrupt has been acknowledged by the APIC
-but not yet injected into the cpu core.
-
-4.14 KVM_SET_SREGS
-
-Capability: basic
-Architectures: x86
-Type: vcpu ioctl
-Parameters: struct kvm_sregs (in)
-Returns: 0 on success, -1 on error
-
-Writes special registers into the vcpu.  See KVM_GET_SREGS for the
-data structures.
-
-4.15 KVM_TRANSLATE
-
-Capability: basic
-Architectures: x86
-Type: vcpu ioctl
-Parameters: struct kvm_translation (in/out)
-Returns: 0 on success, -1 on error
-
-Translates a virtual address according to the vcpu's current address
-translation mode.
-
-struct kvm_translation {
-	/* in */
-	__u64 linear_address;
-
-	/* out */
-	__u64 physical_address;
-	__u8  valid;
-	__u8  writeable;
-	__u8  usermode;
-	__u8  pad[5];
-};
-
-4.16 KVM_INTERRUPT
-
-Capability: basic
-Architectures: x86, ppc
-Type: vcpu ioctl
-Parameters: struct kvm_interrupt (in)
-Returns: 0 on success, -1 on error
-
-Queues a hardware interrupt vector to be injected.  This is only
-useful if in-kernel local APIC or equivalent is not used.
-
-/* for KVM_INTERRUPT */
-struct kvm_interrupt {
-	/* in */
-	__u32 irq;
-};
-
-X86:
-
-Note 'irq' is an interrupt vector, not an interrupt pin or line.
-
-PPC:
-
-Queues an external interrupt to be injected. This ioctl is overleaded
-with 3 different irq values:
-
-a) KVM_INTERRUPT_SET
-
-  This injects an edge type external interrupt into the guest once it's ready
-  to receive interrupts. When injected, the interrupt is done.
-
-b) KVM_INTERRUPT_UNSET
-
-  This unsets any pending interrupt.
-
-  Only available with KVM_CAP_PPC_UNSET_IRQ.
-
-c) KVM_INTERRUPT_SET_LEVEL
-
-  This injects a level type external interrupt into the guest context. The
-  interrupt stays pending until a specific ioctl with KVM_INTERRUPT_UNSET
-  is triggered.
-
-  Only available with KVM_CAP_PPC_IRQ_LEVEL.
-
-Note that any value for 'irq' other than the ones stated above is invalid
-and incurs unexpected behavior.
-
-4.17 KVM_DEBUG_GUEST
-
-Capability: basic
-Architectures: none
-Type: vcpu ioctl
-Parameters: none)
-Returns: -1 on error
-
-Support for this has been removed.  Use KVM_SET_GUEST_DEBUG instead.
-
-4.18 KVM_GET_MSRS
-
-Capability: basic
-Architectures: x86
-Type: vcpu ioctl
-Parameters: struct kvm_msrs (in/out)
-Returns: 0 on success, -1 on error
-
-Reads model-specific registers from the vcpu.  Supported msr indices can
-be obtained using KVM_GET_MSR_INDEX_LIST.
-
-struct kvm_msrs {
-	__u32 nmsrs; /* number of msrs in entries */
-	__u32 pad;
-
-	struct kvm_msr_entry entries[0];
-};
-
-struct kvm_msr_entry {
-	__u32 index;
-	__u32 reserved;
-	__u64 data;
-};
-
-Application code should set the 'nmsrs' member (which indicates the
-size of the entries array) and the 'index' member of each array entry.
-kvm will fill in the 'data' member.
-
-4.19 KVM_SET_MSRS
-
-Capability: basic
-Architectures: x86
-Type: vcpu ioctl
-Parameters: struct kvm_msrs (in)
-Returns: 0 on success, -1 on error
-
-Writes model-specific registers to the vcpu.  See KVM_GET_MSRS for the
-data structures.
-
-Application code should set the 'nmsrs' member (which indicates the
-size of the entries array), and the 'index' and 'data' members of each
-array entry.
-
-4.20 KVM_SET_CPUID
-
-Capability: basic
-Architectures: x86
-Type: vcpu ioctl
-Parameters: struct kvm_cpuid (in)
-Returns: 0 on success, -1 on error
-
-Defines the vcpu responses to the cpuid instruction.  Applications
-should use the KVM_SET_CPUID2 ioctl if available.
-
-
-struct kvm_cpuid_entry {
-	__u32 function;
-	__u32 eax;
-	__u32 ebx;
-	__u32 ecx;
-	__u32 edx;
-	__u32 padding;
-};
-
-/* for KVM_SET_CPUID */
-struct kvm_cpuid {
-	__u32 nent;
-	__u32 padding;
-	struct kvm_cpuid_entry entries[0];
-};
-
-4.21 KVM_SET_SIGNAL_MASK
-
-Capability: basic
-Architectures: x86
-Type: vcpu ioctl
-Parameters: struct kvm_signal_mask (in)
-Returns: 0 on success, -1 on error
-
-Defines which signals are blocked during execution of KVM_RUN.  This
-signal mask temporarily overrides the threads signal mask.  Any
-unblocked signal received (except SIGKILL and SIGSTOP, which retain
-their traditional behaviour) will cause KVM_RUN to return with -EINTR.
-
-Note the signal will only be delivered if not blocked by the original
-signal mask.
-
-/* for KVM_SET_SIGNAL_MASK */
-struct kvm_signal_mask {
-	__u32 len;
-	__u8  sigset[0];
-};
-
-4.22 KVM_GET_FPU
-
-Capability: basic
-Architectures: x86
-Type: vcpu ioctl
-Parameters: struct kvm_fpu (out)
-Returns: 0 on success, -1 on error
-
-Reads the floating point state from the vcpu.
-
-/* for KVM_GET_FPU and KVM_SET_FPU */
-struct kvm_fpu {
-	__u8  fpr[8][16];
-	__u16 fcw;
-	__u16 fsw;
-	__u8  ftwx;  /* in fxsave format */
-	__u8  pad1;
-	__u16 last_opcode;
-	__u64 last_ip;
-	__u64 last_dp;
-	__u8  xmm[16][16];
-	__u32 mxcsr;
-	__u32 pad2;
-};
-
-4.23 KVM_SET_FPU
-
-Capability: basic
-Architectures: x86
-Type: vcpu ioctl
-Parameters: struct kvm_fpu (in)
-Returns: 0 on success, -1 on error
-
-Writes the floating point state to the vcpu.
-
-/* for KVM_GET_FPU and KVM_SET_FPU */
-struct kvm_fpu {
-	__u8  fpr[8][16];
-	__u16 fcw;
-	__u16 fsw;
-	__u8  ftwx;  /* in fxsave format */
-	__u8  pad1;
-	__u16 last_opcode;
-	__u64 last_ip;
-	__u64 last_dp;
-	__u8  xmm[16][16];
-	__u32 mxcsr;
-	__u32 pad2;
-};
-
-4.24 KVM_CREATE_IRQCHIP
-
-Capability: KVM_CAP_IRQCHIP
-Architectures: x86, ia64
-Type: vm ioctl
-Parameters: none
-Returns: 0 on success, -1 on error
-
-Creates an interrupt controller model in the kernel.  On x86, creates a virtual
-ioapic, a virtual PIC (two PICs, nested), and sets up future vcpus to have a
-local APIC.  IRQ routing for GSIs 0-15 is set to both PIC and IOAPIC; GSI 16-23
-only go to the IOAPIC.  On ia64, a IOSAPIC is created.
-
-4.25 KVM_IRQ_LINE
-
-Capability: KVM_CAP_IRQCHIP
-Architectures: x86, ia64
-Type: vm ioctl
-Parameters: struct kvm_irq_level
-Returns: 0 on success, -1 on error
-
-Sets the level of a GSI input to the interrupt controller model in the kernel.
-Requires that an interrupt controller model has been previously created with
-KVM_CREATE_IRQCHIP.  Note that edge-triggered interrupts require the level
-to be set to 1 and then back to 0.
-
-struct kvm_irq_level {
-	union {
-		__u32 irq;     /* GSI */
-		__s32 status;  /* not used for KVM_IRQ_LEVEL */
-	};
-	__u32 level;           /* 0 or 1 */
-};
-
-4.26 KVM_GET_IRQCHIP
-
-Capability: KVM_CAP_IRQCHIP
-Architectures: x86, ia64
-Type: vm ioctl
-Parameters: struct kvm_irqchip (in/out)
-Returns: 0 on success, -1 on error
-
-Reads the state of a kernel interrupt controller created with
-KVM_CREATE_IRQCHIP into a buffer provided by the caller.
-
-struct kvm_irqchip {
-	__u32 chip_id;  /* 0 = PIC1, 1 = PIC2, 2 = IOAPIC */
-	__u32 pad;
-        union {
-		char dummy[512];  /* reserving space */
-		struct kvm_pic_state pic;
-		struct kvm_ioapic_state ioapic;
-	} chip;
-};
-
-4.27 KVM_SET_IRQCHIP
-
-Capability: KVM_CAP_IRQCHIP
-Architectures: x86, ia64
-Type: vm ioctl
-Parameters: struct kvm_irqchip (in)
-Returns: 0 on success, -1 on error
-
-Sets the state of a kernel interrupt controller created with
-KVM_CREATE_IRQCHIP from a buffer provided by the caller.
-
-struct kvm_irqchip {
-	__u32 chip_id;  /* 0 = PIC1, 1 = PIC2, 2 = IOAPIC */
-	__u32 pad;
-        union {
-		char dummy[512];  /* reserving space */
-		struct kvm_pic_state pic;
-		struct kvm_ioapic_state ioapic;
-	} chip;
-};
-
-4.28 KVM_XEN_HVM_CONFIG
-
-Capability: KVM_CAP_XEN_HVM
-Architectures: x86
-Type: vm ioctl
-Parameters: struct kvm_xen_hvm_config (in)
-Returns: 0 on success, -1 on error
-
-Sets the MSR that the Xen HVM guest uses to initialize its hypercall
-page, and provides the starting address and size of the hypercall
-blobs in userspace.  When the guest writes the MSR, kvm copies one
-page of a blob (32- or 64-bit, depending on the vcpu mode) to guest
-memory.
-
-struct kvm_xen_hvm_config {
-	__u32 flags;
-	__u32 msr;
-	__u64 blob_addr_32;
-	__u64 blob_addr_64;
-	__u8 blob_size_32;
-	__u8 blob_size_64;
-	__u8 pad2[30];
-};
-
-4.29 KVM_GET_CLOCK
-
-Capability: KVM_CAP_ADJUST_CLOCK
-Architectures: x86
-Type: vm ioctl
-Parameters: struct kvm_clock_data (out)
-Returns: 0 on success, -1 on error
-
-Gets the current timestamp of kvmclock as seen by the current guest. In
-conjunction with KVM_SET_CLOCK, it is used to ensure monotonicity on scenarios
-such as migration.
-
-struct kvm_clock_data {
-	__u64 clock;  /* kvmclock current value */
-	__u32 flags;
-	__u32 pad[9];
-};
-
-4.30 KVM_SET_CLOCK
-
-Capability: KVM_CAP_ADJUST_CLOCK
-Architectures: x86
-Type: vm ioctl
-Parameters: struct kvm_clock_data (in)
-Returns: 0 on success, -1 on error
-
-Sets the current timestamp of kvmclock to the value specified in its parameter.
-In conjunction with KVM_GET_CLOCK, it is used to ensure monotonicity on scenarios
-such as migration.
-
-struct kvm_clock_data {
-	__u64 clock;  /* kvmclock current value */
-	__u32 flags;
-	__u32 pad[9];
-};
-
-4.31 KVM_GET_VCPU_EVENTS
-
-Capability: KVM_CAP_VCPU_EVENTS
-Extended by: KVM_CAP_INTR_SHADOW
-Architectures: x86
-Type: vm ioctl
-Parameters: struct kvm_vcpu_event (out)
-Returns: 0 on success, -1 on error
-
-Gets currently pending exceptions, interrupts, and NMIs as well as related
-states of the vcpu.
-
-struct kvm_vcpu_events {
-	struct {
-		__u8 injected;
-		__u8 nr;
-		__u8 has_error_code;
-		__u8 pad;
-		__u32 error_code;
-	} exception;
-	struct {
-		__u8 injected;
-		__u8 nr;
-		__u8 soft;
-		__u8 shadow;
-	} interrupt;
-	struct {
-		__u8 injected;
-		__u8 pending;
-		__u8 masked;
-		__u8 pad;
-	} nmi;
-	__u32 sipi_vector;
-	__u32 flags;
-};
-
-KVM_VCPUEVENT_VALID_SHADOW may be set in the flags field to signal that
-interrupt.shadow contains a valid state. Otherwise, this field is undefined.
-
-4.32 KVM_SET_VCPU_EVENTS
-
-Capability: KVM_CAP_VCPU_EVENTS
-Extended by: KVM_CAP_INTR_SHADOW
-Architectures: x86
-Type: vm ioctl
-Parameters: struct kvm_vcpu_event (in)
-Returns: 0 on success, -1 on error
-
-Set pending exceptions, interrupts, and NMIs as well as related states of the
-vcpu.
-
-See KVM_GET_VCPU_EVENTS for the data structure.
-
-Fields that may be modified asynchronously by running VCPUs can be excluded
-from the update. These fields are nmi.pending and sipi_vector. Keep the
-corresponding bits in the flags field cleared to suppress overwriting the
-current in-kernel state. The bits are:
-
-KVM_VCPUEVENT_VALID_NMI_PENDING - transfer nmi.pending to the kernel
-KVM_VCPUEVENT_VALID_SIPI_VECTOR - transfer sipi_vector
-
-If KVM_CAP_INTR_SHADOW is available, KVM_VCPUEVENT_VALID_SHADOW can be set in
-the flags field to signal that interrupt.shadow contains a valid state and
-shall be written into the VCPU.
-
-4.33 KVM_GET_DEBUGREGS
-
-Capability: KVM_CAP_DEBUGREGS
-Architectures: x86
-Type: vm ioctl
-Parameters: struct kvm_debugregs (out)
-Returns: 0 on success, -1 on error
-
-Reads debug registers from the vcpu.
-
-struct kvm_debugregs {
-	__u64 db[4];
-	__u64 dr6;
-	__u64 dr7;
-	__u64 flags;
-	__u64 reserved[9];
-};
-
-4.34 KVM_SET_DEBUGREGS
-
-Capability: KVM_CAP_DEBUGREGS
-Architectures: x86
-Type: vm ioctl
-Parameters: struct kvm_debugregs (in)
-Returns: 0 on success, -1 on error
-
-Writes debug registers into the vcpu.
-
-See KVM_GET_DEBUGREGS for the data structure. The flags field is unused
-yet and must be cleared on entry.
-
-4.35 KVM_SET_USER_MEMORY_REGION
-
-Capability: KVM_CAP_USER_MEM
-Architectures: all
-Type: vm ioctl
-Parameters: struct kvm_userspace_memory_region (in)
-Returns: 0 on success, -1 on error
-
-struct kvm_userspace_memory_region {
-	__u32 slot;
-	__u32 flags;
-	__u64 guest_phys_addr;
-	__u64 memory_size; /* bytes */
-	__u64 userspace_addr; /* start of the userspace allocated memory */
-};
-
-/* for kvm_memory_region::flags */
-#define KVM_MEM_LOG_DIRTY_PAGES  1UL
-
-This ioctl allows the user to create or modify a guest physical memory
-slot.  When changing an existing slot, it may be moved in the guest
-physical memory space, or its flags may be modified.  It may not be
-resized.  Slots may not overlap in guest physical address space.
-
-Memory for the region is taken starting at the address denoted by the
-field userspace_addr, which must point at user addressable memory for
-the entire memory slot size.  Any object may back this memory, including
-anonymous memory, ordinary files, and hugetlbfs.
-
-It is recommended that the lower 21 bits of guest_phys_addr and userspace_addr
-be identical.  This allows large pages in the guest to be backed by large
-pages in the host.
-
-The flags field supports just one flag, KVM_MEM_LOG_DIRTY_PAGES, which
-instructs kvm to keep track of writes to memory within the slot.  See
-the KVM_GET_DIRTY_LOG ioctl.
-
-When the KVM_CAP_SYNC_MMU capability, changes in the backing of the memory
-region are automatically reflected into the guest.  For example, an mmap()
-that affects the region will be made visible immediately.  Another example
-is madvise(MADV_DROP).
-
-It is recommended to use this API instead of the KVM_SET_MEMORY_REGION ioctl.
-The KVM_SET_MEMORY_REGION does not allow fine grained control over memory
-allocation and is deprecated.
-
-4.36 KVM_SET_TSS_ADDR
-
-Capability: KVM_CAP_SET_TSS_ADDR
-Architectures: x86
-Type: vm ioctl
-Parameters: unsigned long tss_address (in)
-Returns: 0 on success, -1 on error
-
-This ioctl defines the physical address of a three-page region in the guest
-physical address space.  The region must be within the first 4GB of the
-guest physical address space and must not conflict with any memory slot
-or any mmio address.  The guest may malfunction if it accesses this memory
-region.
-
-This ioctl is required on Intel-based hosts.  This is needed on Intel hardware
-because of a quirk in the virtualization implementation (see the internals
-documentation when it pops into existence).
-
-4.37 KVM_ENABLE_CAP
-
-Capability: KVM_CAP_ENABLE_CAP
-Architectures: ppc
-Type: vcpu ioctl
-Parameters: struct kvm_enable_cap (in)
-Returns: 0 on success; -1 on error
-
-+Not all extensions are enabled by default. Using this ioctl the application
-can enable an extension, making it available to the guest.
-
-On systems that do not support this ioctl, it always fails. On systems that
-do support it, it only works for extensions that are supported for enablement.
-
-To check if a capability can be enabled, the KVM_CHECK_EXTENSION ioctl should
-be used.
-
-struct kvm_enable_cap {
-       /* in */
-       __u32 cap;
-
-The capability that is supposed to get enabled.
-
-       __u32 flags;
-
-A bitfield indicating future enhancements. Has to be 0 for now.
-
-       __u64 args[4];
-
-Arguments for enabling a feature. If a feature needs initial values to
-function properly, this is the place to put them.
-
-       __u8  pad[64];
-};
-
-4.38 KVM_GET_MP_STATE
-
-Capability: KVM_CAP_MP_STATE
-Architectures: x86, ia64
-Type: vcpu ioctl
-Parameters: struct kvm_mp_state (out)
-Returns: 0 on success; -1 on error
-
-struct kvm_mp_state {
-	__u32 mp_state;
-};
-
-Returns the vcpu's current "multiprocessing state" (though also valid on
-uniprocessor guests).
-
-Possible values are:
-
- - KVM_MP_STATE_RUNNABLE:        the vcpu is currently running
- - KVM_MP_STATE_UNINITIALIZED:   the vcpu is an application processor (AP)
-                                 which has not yet received an INIT signal
- - KVM_MP_STATE_INIT_RECEIVED:   the vcpu has received an INIT signal, and is
-                                 now ready for a SIPI
- - KVM_MP_STATE_HALTED:          the vcpu has executed a HLT instruction and
-                                 is waiting for an interrupt
- - KVM_MP_STATE_SIPI_RECEIVED:   the vcpu has just received a SIPI (vector
-                                 accessible via KVM_GET_VCPU_EVENTS)
-
-This ioctl is only useful after KVM_CREATE_IRQCHIP.  Without an in-kernel
-irqchip, the multiprocessing state must be maintained by userspace.
-
-4.39 KVM_SET_MP_STATE
-
-Capability: KVM_CAP_MP_STATE
-Architectures: x86, ia64
-Type: vcpu ioctl
-Parameters: struct kvm_mp_state (in)
-Returns: 0 on success; -1 on error
-
-Sets the vcpu's current "multiprocessing state"; see KVM_GET_MP_STATE for
-arguments.
-
-This ioctl is only useful after KVM_CREATE_IRQCHIP.  Without an in-kernel
-irqchip, the multiprocessing state must be maintained by userspace.
-
-4.40 KVM_SET_IDENTITY_MAP_ADDR
-
-Capability: KVM_CAP_SET_IDENTITY_MAP_ADDR
-Architectures: x86
-Type: vm ioctl
-Parameters: unsigned long identity (in)
-Returns: 0 on success, -1 on error
-
-This ioctl defines the physical address of a one-page region in the guest
-physical address space.  The region must be within the first 4GB of the
-guest physical address space and must not conflict with any memory slot
-or any mmio address.  The guest may malfunction if it accesses this memory
-region.
-
-This ioctl is required on Intel-based hosts.  This is needed on Intel hardware
-because of a quirk in the virtualization implementation (see the internals
-documentation when it pops into existence).
-
-4.41 KVM_SET_BOOT_CPU_ID
-
-Capability: KVM_CAP_SET_BOOT_CPU_ID
-Architectures: x86, ia64
-Type: vm ioctl
-Parameters: unsigned long vcpu_id
-Returns: 0 on success, -1 on error
-
-Define which vcpu is the Bootstrap Processor (BSP).  Values are the same
-as the vcpu id in KVM_CREATE_VCPU.  If this ioctl is not called, the default
-is vcpu 0.
-
-4.42 KVM_GET_XSAVE
-
-Capability: KVM_CAP_XSAVE
-Architectures: x86
-Type: vcpu ioctl
-Parameters: struct kvm_xsave (out)
-Returns: 0 on success, -1 on error
-
-struct kvm_xsave {
-	__u32 region[1024];
-};
-
-This ioctl would copy current vcpu's xsave struct to the userspace.
-
-4.43 KVM_SET_XSAVE
-
-Capability: KVM_CAP_XSAVE
-Architectures: x86
-Type: vcpu ioctl
-Parameters: struct kvm_xsave (in)
-Returns: 0 on success, -1 on error
-
-struct kvm_xsave {
-	__u32 region[1024];
-};
-
-This ioctl would copy userspace's xsave struct to the kernel.
-
-4.44 KVM_GET_XCRS
-
-Capability: KVM_CAP_XCRS
-Architectures: x86
-Type: vcpu ioctl
-Parameters: struct kvm_xcrs (out)
-Returns: 0 on success, -1 on error
-
-struct kvm_xcr {
-	__u32 xcr;
-	__u32 reserved;
-	__u64 value;
-};
-
-struct kvm_xcrs {
-	__u32 nr_xcrs;
-	__u32 flags;
-	struct kvm_xcr xcrs[KVM_MAX_XCRS];
-	__u64 padding[16];
-};
-
-This ioctl would copy current vcpu's xcrs to the userspace.
-
-4.45 KVM_SET_XCRS
-
-Capability: KVM_CAP_XCRS
-Architectures: x86
-Type: vcpu ioctl
-Parameters: struct kvm_xcrs (in)
-Returns: 0 on success, -1 on error
-
-struct kvm_xcr {
-	__u32 xcr;
-	__u32 reserved;
-	__u64 value;
-};
-
-struct kvm_xcrs {
-	__u32 nr_xcrs;
-	__u32 flags;
-	struct kvm_xcr xcrs[KVM_MAX_XCRS];
-	__u64 padding[16];
-};
-
-This ioctl would set vcpu's xcr to the value userspace specified.
-
-4.46 KVM_GET_SUPPORTED_CPUID
-
-Capability: KVM_CAP_EXT_CPUID
-Architectures: x86
-Type: system ioctl
-Parameters: struct kvm_cpuid2 (in/out)
-Returns: 0 on success, -1 on error
-
-struct kvm_cpuid2 {
-	__u32 nent;
-	__u32 padding;
-	struct kvm_cpuid_entry2 entries[0];
-};
-
-#define KVM_CPUID_FLAG_SIGNIFCANT_INDEX 1
-#define KVM_CPUID_FLAG_STATEFUL_FUNC    2
-#define KVM_CPUID_FLAG_STATE_READ_NEXT  4
-
-struct kvm_cpuid_entry2 {
-	__u32 function;
-	__u32 index;
-	__u32 flags;
-	__u32 eax;
-	__u32 ebx;
-	__u32 ecx;
-	__u32 edx;
-	__u32 padding[3];
-};
-
-This ioctl returns x86 cpuid features which are supported by both the hardware
-and kvm.  Userspace can use the information returned by this ioctl to
-construct cpuid information (for KVM_SET_CPUID2) that is consistent with
-hardware, kernel, and userspace capabilities, and with user requirements (for
-example, the user may wish to constrain cpuid to emulate older hardware,
-or for feature consistency across a cluster).
-
-Userspace invokes KVM_GET_SUPPORTED_CPUID by passing a kvm_cpuid2 structure
-with the 'nent' field indicating the number of entries in the variable-size
-array 'entries'.  If the number of entries is too low to describe the cpu
-capabilities, an error (E2BIG) is returned.  If the number is too high,
-the 'nent' field is adjusted and an error (ENOMEM) is returned.  If the
-number is just right, the 'nent' field is adjusted to the number of valid
-entries in the 'entries' array, which is then filled.
-
-The entries returned are the host cpuid as returned by the cpuid instruction,
-with unknown or unsupported features masked out.  Some features (for example,
-x2apic), may not be present in the host cpu, but are exposed by kvm if it can
-emulate them efficiently. The fields in each entry are defined as follows:
-
-  function: the eax value used to obtain the entry
-  index: the ecx value used to obtain the entry (for entries that are
-         affected by ecx)
-  flags: an OR of zero or more of the following:
-        KVM_CPUID_FLAG_SIGNIFCANT_INDEX:
-           if the index field is valid
-        KVM_CPUID_FLAG_STATEFUL_FUNC:
-           if cpuid for this function returns different values for successive
-           invocations; there will be several entries with the same function,
-           all with this flag set
-        KVM_CPUID_FLAG_STATE_READ_NEXT:
-           for KVM_CPUID_FLAG_STATEFUL_FUNC entries, set if this entry is
-           the first entry to be read by a cpu
-   eax, ebx, ecx, edx: the values returned by the cpuid instruction for
-         this function/index combination
-
-4.47 KVM_PPC_GET_PVINFO
-
-Capability: KVM_CAP_PPC_GET_PVINFO
-Architectures: ppc
-Type: vm ioctl
-Parameters: struct kvm_ppc_pvinfo (out)
-Returns: 0 on success, !0 on error
-
-struct kvm_ppc_pvinfo {
-	__u32 flags;
-	__u32 hcall[4];
-	__u8  pad[108];
-};
-
-This ioctl fetches PV specific information that need to be passed to the guest
-using the device tree or other means from vm context.
-
-For now the only implemented piece of information distributed here is an array
-of 4 instructions that make up a hypercall.
-
-If any additional field gets added to this structure later on, a bit for that
-additional piece of information will be set in the flags bitmap.
-
-4.48 KVM_ASSIGN_PCI_DEVICE
-
-Capability: KVM_CAP_DEVICE_ASSIGNMENT
-Architectures: x86 ia64
-Type: vm ioctl
-Parameters: struct kvm_assigned_pci_dev (in)
-Returns: 0 on success, -1 on error
-
-Assigns a host PCI device to the VM.
-
-struct kvm_assigned_pci_dev {
-	__u32 assigned_dev_id;
-	__u32 busnr;
-	__u32 devfn;
-	__u32 flags;
-	__u32 segnr;
-	union {
-		__u32 reserved[11];
-	};
-};
-
-The PCI device is specified by the triple segnr, busnr, and devfn.
-Identification in succeeding service requests is done via assigned_dev_id. The
-following flags are specified:
-
-/* Depends on KVM_CAP_IOMMU */
-#define KVM_DEV_ASSIGN_ENABLE_IOMMU	(1 << 0)
-
-4.49 KVM_DEASSIGN_PCI_DEVICE
-
-Capability: KVM_CAP_DEVICE_DEASSIGNMENT
-Architectures: x86 ia64
-Type: vm ioctl
-Parameters: struct kvm_assigned_pci_dev (in)
-Returns: 0 on success, -1 on error
-
-Ends PCI device assignment, releasing all associated resources.
-
-See KVM_CAP_DEVICE_ASSIGNMENT for the data structure. Only assigned_dev_id is
-used in kvm_assigned_pci_dev to identify the device.
-
-4.50 KVM_ASSIGN_DEV_IRQ
-
-Capability: KVM_CAP_ASSIGN_DEV_IRQ
-Architectures: x86 ia64
-Type: vm ioctl
-Parameters: struct kvm_assigned_irq (in)
-Returns: 0 on success, -1 on error
-
-Assigns an IRQ to a passed-through device.
-
-struct kvm_assigned_irq {
-	__u32 assigned_dev_id;
-	__u32 host_irq;
-	__u32 guest_irq;
-	__u32 flags;
-	union {
-		struct {
-			__u32 addr_lo;
-			__u32 addr_hi;
-			__u32 data;
-		} guest_msi;
-		__u32 reserved[12];
-	};
-};
-
-The following flags are defined:
-
-#define KVM_DEV_IRQ_HOST_INTX    (1 << 0)
-#define KVM_DEV_IRQ_HOST_MSI     (1 << 1)
-#define KVM_DEV_IRQ_HOST_MSIX    (1 << 2)
-
-#define KVM_DEV_IRQ_GUEST_INTX   (1 << 8)
-#define KVM_DEV_IRQ_GUEST_MSI    (1 << 9)
-#define KVM_DEV_IRQ_GUEST_MSIX   (1 << 10)
-
-It is not valid to specify multiple types per host or guest IRQ. However, the
-IRQ type of host and guest can differ or can even be null.
-
-4.51 KVM_DEASSIGN_DEV_IRQ
-
-Capability: KVM_CAP_ASSIGN_DEV_IRQ
-Architectures: x86 ia64
-Type: vm ioctl
-Parameters: struct kvm_assigned_irq (in)
-Returns: 0 on success, -1 on error
-
-Ends an IRQ assignment to a passed-through device.
-
-See KVM_ASSIGN_DEV_IRQ for the data structure. The target device is specified
-by assigned_dev_id, flags must correspond to the IRQ type specified on
-KVM_ASSIGN_DEV_IRQ. Partial deassignment of host or guest IRQ is allowed.
-
-4.52 KVM_SET_GSI_ROUTING
-
-Capability: KVM_CAP_IRQ_ROUTING
-Architectures: x86 ia64
-Type: vm ioctl
-Parameters: struct kvm_irq_routing (in)
-Returns: 0 on success, -1 on error
-
-Sets the GSI routing table entries, overwriting any previously set entries.
-
-struct kvm_irq_routing {
-	__u32 nr;
-	__u32 flags;
-	struct kvm_irq_routing_entry entries[0];
-};
-
-No flags are specified so far, the corresponding field must be set to zero.
-
-struct kvm_irq_routing_entry {
-	__u32 gsi;
-	__u32 type;
-	__u32 flags;
-	__u32 pad;
-	union {
-		struct kvm_irq_routing_irqchip irqchip;
-		struct kvm_irq_routing_msi msi;
-		__u32 pad[8];
-	} u;
-};
-
-/* gsi routing entry types */
-#define KVM_IRQ_ROUTING_IRQCHIP 1
-#define KVM_IRQ_ROUTING_MSI 2
-
-No flags are specified so far, the corresponding field must be set to zero.
-
-struct kvm_irq_routing_irqchip {
-	__u32 irqchip;
-	__u32 pin;
-};
-
-struct kvm_irq_routing_msi {
-	__u32 address_lo;
-	__u32 address_hi;
-	__u32 data;
-	__u32 pad;
-};
-
-4.53 KVM_ASSIGN_SET_MSIX_NR
-
-Capability: KVM_CAP_DEVICE_MSIX
-Architectures: x86 ia64
-Type: vm ioctl
-Parameters: struct kvm_assigned_msix_nr (in)
-Returns: 0 on success, -1 on error
-
-Set the number of MSI-X interrupts for an assigned device. This service can
-only be called once in the lifetime of an assigned device.
-
-struct kvm_assigned_msix_nr {
-	__u32 assigned_dev_id;
-	__u16 entry_nr;
-	__u16 padding;
-};
-
-#define KVM_MAX_MSIX_PER_DEV		256
-
-4.54 KVM_ASSIGN_SET_MSIX_ENTRY
-
-Capability: KVM_CAP_DEVICE_MSIX
-Architectures: x86 ia64
-Type: vm ioctl
-Parameters: struct kvm_assigned_msix_entry (in)
-Returns: 0 on success, -1 on error
-
-Specifies the routing of an MSI-X assigned device interrupt to a GSI. Setting
-the GSI vector to zero means disabling the interrupt.
-
-struct kvm_assigned_msix_entry {
-	__u32 assigned_dev_id;
-	__u32 gsi;
-	__u16 entry; /* The index of entry in the MSI-X table */
-	__u16 padding[3];
-};
-
-5. The kvm_run structure
-
-Application code obtains a pointer to the kvm_run structure by
-mmap()ing a vcpu fd.  From that point, application code can control
-execution by changing fields in kvm_run prior to calling the KVM_RUN
-ioctl, and obtain information about the reason KVM_RUN returned by
-looking up structure members.
-
-struct kvm_run {
-	/* in */
-	__u8 request_interrupt_window;
-
-Request that KVM_RUN return when it becomes possible to inject external
-interrupts into the guest.  Useful in conjunction with KVM_INTERRUPT.
-
-	__u8 padding1[7];
-
-	/* out */
-	__u32 exit_reason;
-
-When KVM_RUN has returned successfully (return value 0), this informs
-application code why KVM_RUN has returned.  Allowable values for this
-field are detailed below.
-
-	__u8 ready_for_interrupt_injection;
-
-If request_interrupt_window has been specified, this field indicates
-an interrupt can be injected now with KVM_INTERRUPT.
-
-	__u8 if_flag;
-
-The value of the current interrupt flag.  Only valid if in-kernel
-local APIC is not used.
-
-	__u8 padding2[2];
-
-	/* in (pre_kvm_run), out (post_kvm_run) */
-	__u64 cr8;
-
-The value of the cr8 register.  Only valid if in-kernel local APIC is
-not used.  Both input and output.
-
-	__u64 apic_base;
-
-The value of the APIC BASE msr.  Only valid if in-kernel local
-APIC is not used.  Both input and output.
-
-	union {
-		/* KVM_EXIT_UNKNOWN */
-		struct {
-			__u64 hardware_exit_reason;
-		} hw;
-
-If exit_reason is KVM_EXIT_UNKNOWN, the vcpu has exited due to unknown
-reasons.  Further architecture-specific information is available in
-hardware_exit_reason.
-
-		/* KVM_EXIT_FAIL_ENTRY */
-		struct {
-			__u64 hardware_entry_failure_reason;
-		} fail_entry;
-
-If exit_reason is KVM_EXIT_FAIL_ENTRY, the vcpu could not be run due
-to unknown reasons.  Further architecture-specific information is
-available in hardware_entry_failure_reason.
-
-		/* KVM_EXIT_EXCEPTION */
-		struct {
-			__u32 exception;
-			__u32 error_code;
-		} ex;
-
-Unused.
-
-		/* KVM_EXIT_IO */
-		struct {
-#define KVM_EXIT_IO_IN  0
-#define KVM_EXIT_IO_OUT 1
-			__u8 direction;
-			__u8 size; /* bytes */
-			__u16 port;
-			__u32 count;
-			__u64 data_offset; /* relative to kvm_run start */
-		} io;
-
-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 packed array.
-
-		struct {
-			struct kvm_debug_exit_arch arch;
-		} debug;
-
-Unused.
-
-		/* KVM_EXIT_MMIO */
-		struct {
-			__u64 phys_addr;
-			__u8  data[8];
-			__u32 len;
-			__u8  is_write;
-		} mmio;
-
-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.
-
-NOTE: For KVM_EXIT_IO, KVM_EXIT_MMIO and KVM_EXIT_OSI, the corresponding
-operations are complete (and guest state is consistent) only after userspace
-has re-entered the kernel with KVM_RUN.  The kernel side will first finish
-incomplete operations and then check for pending signals.  Userspace
-can re-enter the guest with an unmasked signal pending to complete
-pending operations.
-
-		/* KVM_EXIT_HYPERCALL */
-		struct {
-			__u64 nr;
-			__u64 args[6];
-			__u64 ret;
-			__u32 longmode;
-			__u32 pad;
-		} hypercall;
-
-Unused.  This was once used for 'hypercall to userspace'.  To implement
-such functionality, use KVM_EXIT_IO (x86) or KVM_EXIT_MMIO (all except s390).
-Note KVM_EXIT_IO is significantly faster than KVM_EXIT_MMIO.
-
-		/* KVM_EXIT_TPR_ACCESS */
-		struct {
-			__u64 rip;
-			__u32 is_write;
-			__u32 pad;
-		} tpr_access;
-
-To be documented (KVM_TPR_ACCESS_REPORTING).
-
-		/* KVM_EXIT_S390_SIEIC */
-		struct {
-			__u8 icptcode;
-			__u64 mask; /* psw upper half */
-			__u64 addr; /* psw lower half */
-			__u16 ipa;
-			__u32 ipb;
-		} s390_sieic;
-
-s390 specific.
-
-		/* KVM_EXIT_S390_RESET */
-#define KVM_S390_RESET_POR       1
-#define KVM_S390_RESET_CLEAR     2
-#define KVM_S390_RESET_SUBSYSTEM 4
-#define KVM_S390_RESET_CPU_INIT  8
-#define KVM_S390_RESET_IPL       16
-		__u64 s390_reset_flags;
-
-s390 specific.
-
-		/* KVM_EXIT_DCR */
-		struct {
-			__u32 dcrn;
-			__u32 data;
-			__u8  is_write;
-		} dcr;
-
-powerpc specific.
-
-		/* KVM_EXIT_OSI */
-		struct {
-			__u64 gprs[32];
-		} osi;
-
-MOL uses a special hypercall interface it calls 'OSI'. To enable it, we catch
-hypercalls and exit with this exit struct that contains all the guest gprs.
-
-If exit_reason is KVM_EXIT_OSI, then the vcpu has triggered such a hypercall.
-Userspace can now handle the hypercall and when it's done modify the gprs as
-necessary. Upon guest entry all guest GPRs will then be replaced by the values
-in this struct.
-
-		/* Fix the size of the union. */
-		char padding[256];
-	};
-};
diff -druN linux-2.6.39-libre/Documentation/kvm/cpuid.txt linux-3.0-rc7-libre/Documentation/kvm/cpuid.txt
--- linux-2.6.39-libre/Documentation/kvm/cpuid.txt	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/Documentation/kvm/cpuid.txt	1969-12-31 19:00:00.000000000 -0500
@@ -1,45 +0,0 @@
-KVM CPUID bits
-Glauber Costa <glommer@redhat.com>, Red Hat Inc, 2010
-=====================================================
-
-A guest running on a kvm host, can check some of its features using
-cpuid. This is not always guaranteed to work, since userspace can
-mask-out some, or even all KVM-related cpuid features before launching
-a guest.
-
-KVM cpuid functions are:
-
-function: KVM_CPUID_SIGNATURE (0x40000000)
-returns : eax = 0,
-          ebx = 0x4b4d564b,
-          ecx = 0x564b4d56,
-          edx = 0x4d.
-Note that this value in ebx, ecx and edx corresponds to the string "KVMKVMKVM".
-This function queries the presence of KVM cpuid leafs.
-
-
-function: define KVM_CPUID_FEATURES (0x40000001)
-returns : ebx, ecx, edx = 0
-          eax = and OR'ed group of (1 << flag), where each flags is:
-
-
-flag                               || value || meaning
-=============================================================================
-KVM_FEATURE_CLOCKSOURCE            ||     0 || kvmclock available at msrs
-                                   ||       || 0x11 and 0x12.
-------------------------------------------------------------------------------
-KVM_FEATURE_NOP_IO_DELAY           ||     1 || not necessary to perform delays
-                                   ||       || on PIO operations.
-------------------------------------------------------------------------------
-KVM_FEATURE_MMU_OP                 ||     2 || deprecated.
-------------------------------------------------------------------------------
-KVM_FEATURE_CLOCKSOURCE2           ||     3 || kvmclock available at msrs
-                                   ||       || 0x4b564d00 and 0x4b564d01
-------------------------------------------------------------------------------
-KVM_FEATURE_ASYNC_PF               ||     4 || async pf can be enabled by
-                                   ||       || writing to msr 0x4b564d02
-------------------------------------------------------------------------------
-KVM_FEATURE_CLOCKSOURCE_STABLE_BIT ||    24 || host will warn if no guest-side
-                                   ||       || per-cpu warps are expected in
-                                   ||       || kvmclock.
-------------------------------------------------------------------------------
diff -druN linux-2.6.39-libre/Documentation/kvm/locking.txt linux-3.0-rc7-libre/Documentation/kvm/locking.txt
--- linux-2.6.39-libre/Documentation/kvm/locking.txt	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/Documentation/kvm/locking.txt	1969-12-31 19:00:00.000000000 -0500
@@ -1,25 +0,0 @@
-KVM Lock Overview
-=================
-
-1. Acquisition Orders
----------------------
-
-(to be written)
-
-2. Reference
-------------
-
-Name:		kvm_lock
-Type:		raw_spinlock
-Arch:		any
-Protects:	- vm_list
-		- hardware virtualization enable/disable
-Comment:	'raw' because hardware enabling/disabling must be atomic /wrt
-		migration.
-
-Name:		kvm_arch::tsc_write_lock
-Type:		raw_spinlock
-Arch:		x86
-Protects:	- kvm_arch::{last_tsc_write,last_tsc_nsec,last_tsc_offset}
-		- tsc offset in vmcb
-Comment:	'raw' because updating the tsc offsets must not be preempted.
diff -druN linux-2.6.39-libre/Documentation/kvm/mmu.txt linux-3.0-rc7-libre/Documentation/kvm/mmu.txt
--- linux-2.6.39-libre/Documentation/kvm/mmu.txt	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/Documentation/kvm/mmu.txt	1969-12-31 19:00:00.000000000 -0500
@@ -1,348 +0,0 @@
-The x86 kvm shadow mmu
-======================
-
-The mmu (in arch/x86/kvm, files mmu.[ch] and paging_tmpl.h) is responsible
-for presenting a standard x86 mmu to the guest, while translating guest
-physical addresses to host physical addresses.
-
-The mmu code attempts to satisfy the following requirements:
-
-- correctness: the guest should not be able to determine that it is running
-               on an emulated mmu except for timing (we attempt to comply
-               with the specification, not emulate the characteristics of
-               a particular implementation such as tlb size)
-- security:    the guest must not be able to touch host memory not assigned
-               to it
-- performance: minimize the performance penalty imposed by the mmu
-- scaling:     need to scale to large memory and large vcpu guests
-- hardware:    support the full range of x86 virtualization hardware
-- integration: Linux memory management code must be in control of guest memory
-               so that swapping, page migration, page merging, transparent
-               hugepages, and similar features work without change
-- dirty tracking: report writes to guest memory to enable live migration
-               and framebuffer-based displays
-- footprint:   keep the amount of pinned kernel memory low (most memory
-               should be shrinkable)
-- reliability:  avoid multipage or GFP_ATOMIC allocations
-
-Acronyms
-========
-
-pfn   host page frame number
-hpa   host physical address
-hva   host virtual address
-gfn   guest frame number
-gpa   guest physical address
-gva   guest virtual address
-ngpa  nested guest physical address
-ngva  nested guest virtual address
-pte   page table entry (used also to refer generically to paging structure
-      entries)
-gpte  guest pte (referring to gfns)
-spte  shadow pte (referring to pfns)
-tdp   two dimensional paging (vendor neutral term for NPT and EPT)
-
-Virtual and real hardware supported
-===================================
-
-The mmu supports first-generation mmu hardware, which allows an atomic switch
-of the current paging mode and cr3 during guest entry, as well as
-two-dimensional paging (AMD's NPT and Intel's EPT).  The emulated hardware
-it exposes is the traditional 2/3/4 level x86 mmu, with support for global
-pages, pae, pse, pse36, cr0.wp, and 1GB pages.  Work is in progress to support
-exposing NPT capable hardware on NPT capable hosts.
-
-Translation
-===========
-
-The primary job of the mmu is to program the processor's mmu to translate
-addresses for the guest.  Different translations are required at different
-times:
-
-- when guest paging is disabled, we translate guest physical addresses to
-  host physical addresses (gpa->hpa)
-- when guest paging is enabled, we translate guest virtual addresses, to
-  guest physical addresses, to host physical addresses (gva->gpa->hpa)
-- when the guest launches a guest of its own, we translate nested guest
-  virtual addresses, to nested guest physical addresses, to guest physical
-  addresses, to host physical addresses (ngva->ngpa->gpa->hpa)
-
-The primary challenge is to encode between 1 and 3 translations into hardware
-that support only 1 (traditional) and 2 (tdp) translations.  When the
-number of required translations matches the hardware, the mmu operates in
-direct mode; otherwise it operates in shadow mode (see below).
-
-Memory
-======
-
-Guest memory (gpa) is part of the user address space of the process that is
-using kvm.  Userspace defines the translation between guest addresses and user
-addresses (gpa->hva); note that two gpas may alias to the same hva, but not
-vice versa.
-
-These hvas may be backed using any method available to the host: anonymous
-memory, file backed memory, and device memory.  Memory might be paged by the
-host at any time.
-
-Events
-======
-
-The mmu is driven by events, some from the guest, some from the host.
-
-Guest generated events:
-- writes to control registers (especially cr3)
-- invlpg/invlpga instruction execution
-- access to missing or protected translations
-
-Host generated events:
-- changes in the gpa->hpa translation (either through gpa->hva changes or
-  through hva->hpa changes)
-- memory pressure (the shrinker)
-
-Shadow pages
-============
-
-The principal data structure is the shadow page, 'struct kvm_mmu_page'.  A
-shadow page contains 512 sptes, which can be either leaf or nonleaf sptes.  A
-shadow page may contain a mix of leaf and nonleaf sptes.
-
-A nonleaf spte allows the hardware mmu to reach the leaf pages and
-is not related to a translation directly.  It points to other shadow pages.
-
-A leaf spte corresponds to either one or two translations encoded into
-one paging structure entry.  These are always the lowest level of the
-translation stack, with optional higher level translations left to NPT/EPT.
-Leaf ptes point at guest pages.
-
-The following table shows translations encoded by leaf ptes, with higher-level
-translations in parentheses:
-
- Non-nested guests:
-  nonpaging:     gpa->hpa
-  paging:        gva->gpa->hpa
-  paging, tdp:   (gva->)gpa->hpa
- Nested guests:
-  non-tdp:       ngva->gpa->hpa  (*)
-  tdp:           (ngva->)ngpa->gpa->hpa
-
-(*) the guest hypervisor will encode the ngva->gpa translation into its page
-    tables if npt is not present
-
-Shadow pages contain the following information:
-  role.level:
-    The level in the shadow paging hierarchy that this shadow page belongs to.
-    1=4k sptes, 2=2M sptes, 3=1G sptes, etc.
-  role.direct:
-    If set, leaf sptes reachable from this page are for a linear range.
-    Examples include real mode translation, large guest pages backed by small
-    host pages, and gpa->hpa translations when NPT or EPT is active.
-    The linear range starts at (gfn << PAGE_SHIFT) and its size is determined
-    by role.level (2MB for first level, 1GB for second level, 0.5TB for third
-    level, 256TB for fourth level)
-    If clear, this page corresponds to a guest page table denoted by the gfn
-    field.
-  role.quadrant:
-    When role.cr4_pae=0, the guest uses 32-bit gptes while the host uses 64-bit
-    sptes.  That means a guest page table contains more ptes than the host,
-    so multiple shadow pages are needed to shadow one guest page.
-    For first-level shadow pages, role.quadrant can be 0 or 1 and denotes the
-    first or second 512-gpte block in the guest page table.  For second-level
-    page tables, each 32-bit gpte is converted to two 64-bit sptes
-    (since each first-level guest page is shadowed by two first-level
-    shadow pages) so role.quadrant takes values in the range 0..3.  Each
-    quadrant maps 1GB virtual address space.
-  role.access:
-    Inherited guest access permissions in the form uwx.  Note execute
-    permission is positive, not negative.
-  role.invalid:
-    The page is invalid and should not be used.  It is a root page that is
-    currently pinned (by a cpu hardware register pointing to it); once it is
-    unpinned it will be destroyed.
-  role.cr4_pae:
-    Contains the value of cr4.pae for which the page is valid (e.g. whether
-    32-bit or 64-bit gptes are in use).
-  role.nxe:
-    Contains the value of efer.nxe for which the page is valid.
-  role.cr0_wp:
-    Contains the value of cr0.wp for which the page is valid.
-  gfn:
-    Either the guest page table containing the translations shadowed by this
-    page, or the base page frame for linear translations.  See role.direct.
-  spt:
-    A pageful of 64-bit sptes containing the translations for this page.
-    Accessed by both kvm and hardware.
-    The page pointed to by spt will have its page->private pointing back
-    at the shadow page structure.
-    sptes in spt point either at guest pages, or at lower-level shadow pages.
-    Specifically, if sp1 and sp2 are shadow pages, then sp1->spt[n] may point
-    at __pa(sp2->spt).  sp2 will point back at sp1 through parent_pte.
-    The spt array forms a DAG structure with the shadow page as a node, and
-    guest pages as leaves.
-  gfns:
-    An array of 512 guest frame numbers, one for each present pte.  Used to
-    perform a reverse map from a pte to a gfn. When role.direct is set, any
-    element of this array can be calculated from the gfn field when used, in
-    this case, the array of gfns is not allocated. See role.direct and gfn.
-  slot_bitmap:
-    A bitmap containing one bit per memory slot.  If the page contains a pte
-    mapping a page from memory slot n, then bit n of slot_bitmap will be set
-    (if a page is aliased among several slots, then it is not guaranteed that
-    all slots will be marked).
-    Used during dirty logging to avoid scanning a shadow page if none if its
-    pages need tracking.
-  root_count:
-    A counter keeping track of how many hardware registers (guest cr3 or
-    pdptrs) are now pointing at the page.  While this counter is nonzero, the
-    page cannot be destroyed.  See role.invalid.
-  multimapped:
-    Whether there exist multiple sptes pointing at this page.
-  parent_pte/parent_ptes:
-    If multimapped is zero, parent_pte points at the single spte that points at
-    this page's spt.  Otherwise, parent_ptes points at a data structure
-    with a list of parent_ptes.
-  unsync:
-    If true, then the translations in this page may not match the guest's
-    translation.  This is equivalent to the state of the tlb when a pte is
-    changed but before the tlb entry is flushed.  Accordingly, unsync ptes
-    are synchronized when the guest executes invlpg or flushes its tlb by
-    other means.  Valid for leaf pages.
-  unsync_children:
-    How many sptes in the page point at pages that are unsync (or have
-    unsynchronized children).
-  unsync_child_bitmap:
-    A bitmap indicating which sptes in spt point (directly or indirectly) at
-    pages that may be unsynchronized.  Used to quickly locate all unsychronized
-    pages reachable from a given page.
-
-Reverse map
-===========
-
-The mmu maintains a reverse mapping whereby all ptes mapping a page can be
-reached given its gfn.  This is used, for example, when swapping out a page.
-
-Synchronized and unsynchronized pages
-=====================================
-
-The guest uses two events to synchronize its tlb and page tables: tlb flushes
-and page invalidations (invlpg).
-
-A tlb flush means that we need to synchronize all sptes reachable from the
-guest's cr3.  This is expensive, so we keep all guest page tables write
-protected, and synchronize sptes to gptes when a gpte is written.
-
-A special case is when a guest page table is reachable from the current
-guest cr3.  In this case, the guest is obliged to issue an invlpg instruction
-before using the translation.  We take advantage of that by removing write
-protection from the guest page, and allowing the guest to modify it freely.
-We synchronize modified gptes when the guest invokes invlpg.  This reduces
-the amount of emulation we have to do when the guest modifies multiple gptes,
-or when the a guest page is no longer used as a page table and is used for
-random guest data.
-
-As a side effect we have to resynchronize all reachable unsynchronized shadow
-pages on a tlb flush.
-
-
-Reaction to events
-==================
-
-- guest page fault (or npt page fault, or ept violation)
-
-This is the most complicated event.  The cause of a page fault can be:
-
-  - a true guest fault (the guest translation won't allow the access) (*)
-  - access to a missing translation
-  - access to a protected translation
-    - when logging dirty pages, memory is write protected
-    - synchronized shadow pages are write protected (*)
-  - access to untranslatable memory (mmio)
-
-  (*) not applicable in direct mode
-
-Handling a page fault is performed as follows:
-
- - if needed, walk the guest page tables to determine the guest translation
-   (gva->gpa or ngpa->gpa)
-   - if permissions are insufficient, reflect the fault back to the guest
- - determine the host page
-   - if this is an mmio request, there is no host page; call the emulator
-     to emulate the instruction instead
- - walk the shadow page table to find the spte for the translation,
-   instantiating missing intermediate page tables as necessary
- - try to unsynchronize the page
-   - if successful, we can let the guest continue and modify the gpte
- - emulate the instruction
-   - if failed, unshadow the page and let the guest continue
- - update any translations that were modified by the instruction
-
-invlpg handling:
-
-  - walk the shadow page hierarchy and drop affected translations
-  - try to reinstantiate the indicated translation in the hope that the
-    guest will use it in the near future
-
-Guest control register updates:
-
-- mov to cr3
-  - look up new shadow roots
-  - synchronize newly reachable shadow pages
-
-- mov to cr0/cr4/efer
-  - set up mmu context for new paging mode
-  - look up new shadow roots
-  - synchronize newly reachable shadow pages
-
-Host translation updates:
-
-  - mmu notifier called with updated hva
-  - look up affected sptes through reverse map
-  - drop (or update) translations
-
-Emulating cr0.wp
-================
-
-If tdp is not enabled, the host must keep cr0.wp=1 so page write protection
-works for the guest kernel, not guest guest userspace.  When the guest
-cr0.wp=1, this does not present a problem.  However when the guest cr0.wp=0,
-we cannot map the permissions for gpte.u=1, gpte.w=0 to any spte (the
-semantics require allowing any guest kernel access plus user read access).
-
-We handle this by mapping the permissions to two possible sptes, depending
-on fault type:
-
-- kernel write fault: spte.u=0, spte.w=1 (allows full kernel access,
-  disallows user access)
-- read fault: spte.u=1, spte.w=0 (allows full read access, disallows kernel
-  write access)
-
-(user write faults generate a #PF)
-
-Large pages
-===========
-
-The mmu supports all combinations of large and small guest and host pages.
-Supported page sizes include 4k, 2M, 4M, and 1G.  4M pages are treated as
-two separate 2M pages, on both guest and host, since the mmu always uses PAE
-paging.
-
-To instantiate a large spte, four constraints must be satisfied:
-
-- the spte must point to a large host page
-- the guest pte must be a large pte of at least equivalent size (if tdp is
-  enabled, there is no guest pte and this condition is satisified)
-- if the spte will be writeable, the large page frame may not overlap any
-  write-protected pages
-- the guest page must be wholly contained by a single memory slot
-
-To check the last two conditions, the mmu maintains a ->write_count set of
-arrays for each memory slot and large page size.  Every write protected page
-causes its write_count to be incremented, thus preventing instantiation of
-a large spte.  The frames at the end of an unaligned memory slot have
-artificically inflated ->write_counts so they can never be instantiated.
-
-Further reading
-===============
-
-- NPT presentation from KVM Forum 2008
-  http://www.linux-kvm.org/wiki/images/c/c8/KvmForum2008%24kdf2008_21.pdf
-
diff -druN linux-2.6.39-libre/Documentation/kvm/msr.txt linux-3.0-rc7-libre/Documentation/kvm/msr.txt
--- linux-2.6.39-libre/Documentation/kvm/msr.txt	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/Documentation/kvm/msr.txt	1969-12-31 19:00:00.000000000 -0500
@@ -1,187 +0,0 @@
-KVM-specific MSRs.
-Glauber Costa <glommer@redhat.com>, Red Hat Inc, 2010
-=====================================================
-
-KVM makes use of some custom MSRs to service some requests.
-
-Custom MSRs have a range reserved for them, that goes from
-0x4b564d00 to 0x4b564dff. There are MSRs outside this area,
-but they are deprecated and their use is discouraged.
-
-Custom MSR list
---------
-
-The current supported Custom MSR list is:
-
-MSR_KVM_WALL_CLOCK_NEW:   0x4b564d00
-
-	data: 4-byte alignment physical address of a memory area which must be
-	in guest RAM. This memory is expected to hold a copy of the following
-	structure:
-
-	struct pvclock_wall_clock {
-		u32   version;
-		u32   sec;
-		u32   nsec;
-	} __attribute__((__packed__));
-
-	whose data will be filled in by the hypervisor. The hypervisor is only
-	guaranteed to update this data at the moment of MSR write.
-	Users that want to reliably query this information more than once have
-	to write more than once to this MSR. Fields have the following meanings:
-
-		version: guest has to check version before and after grabbing
-		time information and check that they are both equal and even.
-		An odd version indicates an in-progress update.
-
-		sec: number of seconds for wallclock.
-
-		nsec: number of nanoseconds for wallclock.
-
-	Note that although MSRs are per-CPU entities, the effect of this
-	particular MSR is global.
-
-	Availability of this MSR must be checked via bit 3 in 0x4000001 cpuid
-	leaf prior to usage.
-
-MSR_KVM_SYSTEM_TIME_NEW:  0x4b564d01
-
-	data: 4-byte aligned physical address of a memory area which must be in
-	guest RAM, plus an enable bit in bit 0. This memory is expected to hold
-	a copy of the following structure:
-
-	struct pvclock_vcpu_time_info {
-		u32   version;
-		u32   pad0;
-		u64   tsc_timestamp;
-		u64   system_time;
-		u32   tsc_to_system_mul;
-		s8    tsc_shift;
-		u8    flags;
-		u8    pad[2];
-	} __attribute__((__packed__)); /* 32 bytes */
-
-	whose data will be filled in by the hypervisor periodically. Only one
-	write, or registration, is needed for each VCPU. The interval between
-	updates of this structure is arbitrary and implementation-dependent.
-	The hypervisor may update this structure at any time it sees fit until
-	anything with bit0 == 0 is written to it.
-
-	Fields have the following meanings:
-
-		version: guest has to check version before and after grabbing
-		time information and check that they are both equal and even.
-		An odd version indicates an in-progress update.
-
-		tsc_timestamp: the tsc value at the current VCPU at the time
-		of the update of this structure. Guests can subtract this value
-		from current tsc to derive a notion of elapsed time since the
-		structure update.
-
-		system_time: a host notion of monotonic time, including sleep
-		time at the time this structure was last updated. Unit is
-		nanoseconds.
-
-		tsc_to_system_mul: a function of the tsc frequency. One has
-		to multiply any tsc-related quantity by this value to get
-		a value in nanoseconds, besides dividing by 2^tsc_shift
-
-		tsc_shift: cycle to nanosecond divider, as a power of two, to
-		allow for shift rights. One has to shift right any tsc-related
-		quantity by this value to get a value in nanoseconds, besides
-		multiplying by tsc_to_system_mul.
-
-		With this information, guests can derive per-CPU time by
-		doing:
-
-			time = (current_tsc - tsc_timestamp)
-			time = (time * tsc_to_system_mul) >> tsc_shift
-			time = time + system_time
-
-		flags: bits in this field indicate extended capabilities
-		coordinated between the guest and the hypervisor. Availability
-		of specific flags has to be checked in 0x40000001 cpuid leaf.
-		Current flags are:
-
-		 flag bit   | cpuid bit    | meaning
-		-------------------------------------------------------------
-			    |	           | time measures taken across
-		     0      |	   24      | multiple cpus are guaranteed to
-			    |		   | be monotonic
-		-------------------------------------------------------------
-
-	Availability of this MSR must be checked via bit 3 in 0x4000001 cpuid
-	leaf prior to usage.
-
-
-MSR_KVM_WALL_CLOCK:  0x11
-
-	data and functioning: same as MSR_KVM_WALL_CLOCK_NEW. Use that instead.
-
-	This MSR falls outside the reserved KVM range and may be removed in the
-	future. Its usage is deprecated.
-
-	Availability of this MSR must be checked via bit 0 in 0x4000001 cpuid
-	leaf prior to usage.
-
-MSR_KVM_SYSTEM_TIME: 0x12
-
-	data and functioning: same as MSR_KVM_SYSTEM_TIME_NEW. Use that instead.
-
-	This MSR falls outside the reserved KVM range and may be removed in the
-	future. Its usage is deprecated.
-
-	Availability of this MSR must be checked via bit 0 in 0x4000001 cpuid
-	leaf prior to usage.
-
-	The suggested algorithm for detecting kvmclock presence is then:
-
-		if (!kvm_para_available())    /* refer to cpuid.txt */
-			return NON_PRESENT;
-
-		flags = cpuid_eax(0x40000001);
-		if (flags & 3) {
-			msr_kvm_system_time = MSR_KVM_SYSTEM_TIME_NEW;
-			msr_kvm_wall_clock = MSR_KVM_WALL_CLOCK_NEW;
-			return PRESENT;
-		} else if (flags & 0) {
-			msr_kvm_system_time = MSR_KVM_SYSTEM_TIME;
-			msr_kvm_wall_clock = MSR_KVM_WALL_CLOCK;
-			return PRESENT;
-		} else
-			return NON_PRESENT;
-
-MSR_KVM_ASYNC_PF_EN: 0x4b564d02
-	data: Bits 63-6 hold 64-byte aligned physical address of a
-	64 byte memory area which must be in guest RAM and must be
-	zeroed. Bits 5-2 are reserved and should be zero. Bit 0 is 1
-	when asynchronous page faults are enabled on the vcpu 0 when
-	disabled. Bit 2 is 1 if asynchronous page faults can be injected
-	when vcpu is in cpl == 0.
-
-	First 4 byte of 64 byte memory location will be written to by
-	the hypervisor at the time of asynchronous page fault (APF)
-	injection to indicate type of asynchronous page fault. Value
-	of 1 means that the page referred to by the page fault is not
-	present. Value 2 means that the page is now available. Disabling
-	interrupt inhibits APFs. Guest must not enable interrupt
-	before the reason is read, or it may be overwritten by another
-	APF. Since APF uses the same exception vector as regular page
-	fault guest must reset the reason to 0 before it does
-	something that can generate normal page fault.  If during page
-	fault APF reason is 0 it means that this is regular page
-	fault.
-
-	During delivery of type 1 APF cr2 contains a token that will
-	be used to notify a guest when missing page becomes
-	available. When page becomes available type 2 APF is sent with
-	cr2 set to the token associated with the page. There is special
-	kind of token 0xffffffff which tells vcpu that it should wake
-	up all processes waiting for APFs and no individual type 2 APFs
-	will be sent.
-
-	If APF is disabled while there are outstanding APFs, they will
-	not be delivered.
-
-	Currently type 2 APF will be always delivered on the same vcpu as
-	type 1 was, but guest should not rely on that.
diff -druN linux-2.6.39-libre/Documentation/kvm/ppc-pv.txt linux-3.0-rc7-libre/Documentation/kvm/ppc-pv.txt
--- linux-2.6.39-libre/Documentation/kvm/ppc-pv.txt	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/Documentation/kvm/ppc-pv.txt	1969-12-31 19:00:00.000000000 -0500
@@ -1,196 +0,0 @@
-The PPC KVM paravirtual interface
-=================================
-
-The basic execution principle by which KVM on PowerPC works is to run all kernel
-space code in PR=1 which is user space. This way we trap all privileged
-instructions and can emulate them accordingly.
-
-Unfortunately that is also the downfall. There are quite some privileged
-instructions that needlessly return us to the hypervisor even though they
-could be handled differently.
-
-This is what the PPC PV interface helps with. It takes privileged instructions
-and transforms them into unprivileged ones with some help from the hypervisor.
-This cuts down virtualization costs by about 50% on some of my benchmarks.
-
-The code for that interface can be found in arch/powerpc/kernel/kvm*
-
-Querying for existence
-======================
-
-To find out if we're running on KVM or not, we leverage the device tree. When
-Linux is running on KVM, a node /hypervisor exists. That node contains a
-compatible property with the value "linux,kvm".
-
-Once you determined you're running under a PV capable KVM, you can now use
-hypercalls as described below.
-
-KVM hypercalls
-==============
-
-Inside the device tree's /hypervisor node there's a property called
-'hypercall-instructions'. This property contains at most 4 opcodes that make
-up the hypercall. To call a hypercall, just call these instructions.
-
-The parameters are as follows:
-
-	Register	IN			OUT
-
-	r0		-			volatile
-	r3		1st parameter		Return code
-	r4		2nd parameter		1st output value
-	r5		3rd parameter		2nd output value
-	r6		4th parameter		3rd output value
-	r7		5th parameter		4th output value
-	r8		6th parameter		5th output value
-	r9		7th parameter		6th output value
-	r10		8th parameter		7th output value
-	r11		hypercall number	8th output value
-	r12		-			volatile
-
-Hypercall definitions are shared in generic code, so the same hypercall numbers
-apply for x86 and powerpc alike with the exception that each KVM hypercall
-also needs to be ORed with the KVM vendor code which is (42 << 16).
-
-Return codes can be as follows:
-
-	Code		Meaning
-
-	0		Success
-	12		Hypercall not implemented
-	<0		Error
-
-The magic page
-==============
-
-To enable communication between the hypervisor and guest there is a new shared
-page that contains parts of supervisor visible register state. The guest can
-map this shared page using the KVM hypercall KVM_HC_PPC_MAP_MAGIC_PAGE.
-
-With this hypercall issued the guest always gets the magic page mapped at the
-desired location in effective and physical address space. For now, we always
-map the page to -4096. This way we can access it using absolute load and store
-functions. The following instruction reads the first field of the magic page:
-
-	ld	rX, -4096(0)
-
-The interface is designed to be extensible should there be need later to add
-additional registers to the magic page. If you add fields to the magic page,
-also define a new hypercall feature to indicate that the host can give you more
-registers. Only if the host supports the additional features, make use of them.
-
-The magic page has the following layout as described in
-arch/powerpc/include/asm/kvm_para.h:
-
-struct kvm_vcpu_arch_shared {
-	__u64 scratch1;
-	__u64 scratch2;
-	__u64 scratch3;
-	__u64 critical;		/* Guest may not get interrupts if == r1 */
-	__u64 sprg0;
-	__u64 sprg1;
-	__u64 sprg2;
-	__u64 sprg3;
-	__u64 srr0;
-	__u64 srr1;
-	__u64 dar;
-	__u64 msr;
-	__u32 dsisr;
-	__u32 int_pending;	/* Tells the guest if we have an interrupt */
-};
-
-Additions to the page must only occur at the end. Struct fields are always 32
-or 64 bit aligned, depending on them being 32 or 64 bit wide respectively.
-
-Magic page features
-===================
-
-When mapping the magic page using the KVM hypercall KVM_HC_PPC_MAP_MAGIC_PAGE,
-a second return value is passed to the guest. This second return value contains
-a bitmap of available features inside the magic page.
-
-The following enhancements to the magic page are currently available:
-
-  KVM_MAGIC_FEAT_SR		Maps SR registers r/w in the magic page
-
-For enhanced features in the magic page, please check for the existence of the
-feature before using them!
-
-MSR bits
-========
-
-The MSR contains bits that require hypervisor intervention and bits that do
-not require direct hypervisor intervention because they only get interpreted
-when entering the guest or don't have any impact on the hypervisor's behavior.
-
-The following bits are safe to be set inside the guest:
-
-  MSR_EE
-  MSR_RI
-  MSR_CR
-  MSR_ME
-
-If any other bit changes in the MSR, please still use mtmsr(d).
-
-Patched instructions
-====================
-
-The "ld" and "std" instructions are transormed to "lwz" and "stw" instructions
-respectively on 32 bit systems with an added offset of 4 to accommodate for big
-endianness.
-
-The following is a list of mapping the Linux kernel performs when running as
-guest. Implementing any of those mappings is optional, as the instruction traps
-also act on the shared page. So calling privileged instructions still works as
-before.
-
-From			To
-====			==
-
-mfmsr	rX		ld	rX, magic_page->msr
-mfsprg	rX, 0		ld	rX, magic_page->sprg0
-mfsprg	rX, 1		ld	rX, magic_page->sprg1
-mfsprg	rX, 2		ld	rX, magic_page->sprg2
-mfsprg	rX, 3		ld	rX, magic_page->sprg3
-mfsrr0	rX		ld	rX, magic_page->srr0
-mfsrr1	rX		ld	rX, magic_page->srr1
-mfdar	rX		ld	rX, magic_page->dar
-mfdsisr	rX		lwz	rX, magic_page->dsisr
-
-mtmsr	rX		std	rX, magic_page->msr
-mtsprg	0, rX		std	rX, magic_page->sprg0
-mtsprg	1, rX		std	rX, magic_page->sprg1
-mtsprg	2, rX		std	rX, magic_page->sprg2
-mtsprg	3, rX		std	rX, magic_page->sprg3
-mtsrr0	rX		std	rX, magic_page->srr0
-mtsrr1	rX		std	rX, magic_page->srr1
-mtdar	rX		std	rX, magic_page->dar
-mtdsisr	rX		stw	rX, magic_page->dsisr
-
-tlbsync			nop
-
-mtmsrd	rX, 0		b	<special mtmsr section>
-mtmsr	rX		b	<special mtmsr section>
-
-mtmsrd	rX, 1		b	<special mtmsrd section>
-
-[Book3S only]
-mtsrin	rX, rY		b	<special mtsrin section>
-
-[BookE only]
-wrteei	[0|1]		b	<special wrteei section>
-
-
-Some instructions require more logic to determine what's going on than a load
-or store instruction can deliver. To enable patching of those, we keep some
-RAM around where we can live translate instructions to. What happens is the
-following:
-
-	1) copy emulation code to memory
-	2) patch that code to fit the emulated instruction
-	3) patch that code to return to the original pc + 4
-	4) patch the original instruction to branch to the new code
-
-That way we can inject an arbitrary amount of code as replacement for a single
-instruction. This allows us to check for pending interrupts when setting EE=1
-for example.
diff -druN linux-2.6.39-libre/Documentation/kvm/review-checklist.txt linux-3.0-rc7-libre/Documentation/kvm/review-checklist.txt
--- linux-2.6.39-libre/Documentation/kvm/review-checklist.txt	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/Documentation/kvm/review-checklist.txt	1969-12-31 19:00:00.000000000 -0500
@@ -1,38 +0,0 @@
-Review checklist for kvm patches
-================================
-
-1.  The patch must follow Documentation/CodingStyle and
-    Documentation/SubmittingPatches.
-
-2.  Patches should be against kvm.git master branch.
-
-3.  If the patch introduces or modifies a new userspace API:
-    - the API must be documented in Documentation/kvm/api.txt
-    - the API must be discoverable using KVM_CHECK_EXTENSION
-
-4.  New state must include support for save/restore.
-
-5.  New features must default to off (userspace should explicitly request them).
-    Performance improvements can and should default to on.
-
-6.  New cpu features should be exposed via KVM_GET_SUPPORTED_CPUID2
-
-7.  Emulator changes should be accompanied by unit tests for qemu-kvm.git
-    kvm/test directory.
-
-8.  Changes should be vendor neutral when possible.  Changes to common code
-    are better than duplicating changes to vendor code.
-
-9.  Similarly, prefer changes to arch independent code than to arch dependent
-    code.
-
-10. User/kernel interfaces and guest/host interfaces must be 64-bit clean
-    (all variables and sizes naturally aligned on 64-bit; use specific types
-    only - u64 rather than ulong).
-
-11. New guest visible features must either be documented in a hardware manual
-    or be accompanied by documentation.
-
-12. Features must be robust against reset and kexec - for example, shared
-    host/guest memory must be unshared to prevent the host from writing to
-    guest memory that the guest has not reserved for this purpose.
diff -druN linux-2.6.39-libre/Documentation/kvm/timekeeping.txt linux-3.0-rc7-libre/Documentation/kvm/timekeeping.txt
--- linux-2.6.39-libre/Documentation/kvm/timekeeping.txt	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/Documentation/kvm/timekeeping.txt	1969-12-31 19:00:00.000000000 -0500
@@ -1,612 +0,0 @@
-
-	Timekeeping Virtualization for X86-Based Architectures
-
-	Zachary Amsden <zamsden@redhat.com>
-	Copyright (c) 2010, Red Hat.  All rights reserved.
-
-1) Overview
-2) Timing Devices
-3) TSC Hardware
-4) Virtualization Problems
-
-=========================================================================
-
-1) Overview
-
-One of the most complicated parts of the X86 platform, and specifically,
-the virtualization of this platform is the plethora of timing devices available
-and the complexity of emulating those devices.  In addition, virtualization of
-time introduces a new set of challenges because it introduces a multiplexed
-division of time beyond the control of the guest CPU.
-
-First, we will describe the various timekeeping hardware available, then
-present some of the problems which arise and solutions available, giving
-specific recommendations for certain classes of KVM guests.
-
-The purpose of this document is to collect data and information relevant to
-timekeeping which may be difficult to find elsewhere, specifically,
-information relevant to KVM and hardware-based virtualization.
-
-=========================================================================
-
-2) Timing Devices
-
-First we discuss the basic hardware devices available.  TSC and the related
-KVM clock are special enough to warrant a full exposition and are described in
-the following section.
-
-2.1) i8254 - PIT
-
-One of the first timer devices available is the programmable interrupt timer,
-or PIT.  The PIT has a fixed frequency 1.193182 MHz base clock and three
-channels which can be programmed to deliver periodic or one-shot interrupts.
-These three channels can be configured in different modes and have individual
-counters.  Channel 1 and 2 were not available for general use in the original
-IBM PC, and historically were connected to control RAM refresh and the PC
-speaker.  Now the PIT is typically integrated as part of an emulated chipset
-and a separate physical PIT is not used.
-
-The PIT uses I/O ports 0x40 - 0x43.  Access to the 16-bit counters is done
-using single or multiple byte access to the I/O ports.  There are 6 modes
-available, but not all modes are available to all timers, as only timer 2
-has a connected gate input, required for modes 1 and 5.  The gate line is
-controlled by port 61h, bit 0, as illustrated in the following diagram.
-
- --------------             ----------------
-|              |           |                |
-|  1.1932 MHz  |---------->| CLOCK      OUT | ---------> IRQ 0
-|    Clock     |   |       |                |
- --------------    |    +->| GATE  TIMER 0  |
-                   |        ----------------
-                   |
-                   |        ----------------
-                   |       |                |
-                   |------>| CLOCK      OUT | ---------> 66.3 KHZ DRAM
-                   |       |                |            (aka /dev/null)
-                   |    +->| GATE  TIMER 1  |
-                   |        ----------------
-                   |
-                   |        ----------------
-                   |       |                |
-                   |------>| CLOCK      OUT | ---------> Port 61h, bit 5
-                           |                |      |
-Port 61h, bit 0 ---------->| GATE  TIMER 2  |       \_.----   ____
-                            ----------------         _|    )--|LPF|---Speaker
-                                                    / *----   \___/
-Port 61h, bit 1 -----------------------------------/
-
-The timer modes are now described.
-
-Mode 0: Single Timeout.   This is a one-shot software timeout that counts down
- when the gate is high (always true for timers 0 and 1).  When the count
- reaches zero, the output goes high.
-
-Mode 1: Triggered One-shot.  The output is initially set high.  When the gate
- line is set high, a countdown is initiated (which does not stop if the gate is
- lowered), during which the output is set low.  When the count reaches zero,
- the output goes high.
-
-Mode 2: Rate Generator.  The output is initially set high.  When the countdown
- reaches 1, the output goes low for one count and then returns high.  The value
- is reloaded and the countdown automatically resumes.  If the gate line goes
- low, the count is halted.  If the output is low when the gate is lowered, the
- output automatically goes high (this only affects timer 2).
-
-Mode 3: Square Wave.   This generates a high / low square wave.  The count
- determines the length of the pulse, which alternates between high and low
- when zero is reached.  The count only proceeds when gate is high and is
- automatically reloaded on reaching zero.  The count is decremented twice at
- each clock to generate a full high / low cycle at the full periodic rate.
- If the count is even, the clock remains high for N/2 counts and low for N/2
- counts; if the clock is odd, the clock is high for (N+1)/2 counts and low
- for (N-1)/2 counts.  Only even values are latched by the counter, so odd
- values are not observed when reading.  This is the intended mode for timer 2,
- which generates sine-like tones by low-pass filtering the square wave output.
-
-Mode 4: Software Strobe.  After programming this mode and loading the counter,
- the output remains high until the counter reaches zero.  Then the output
- goes low for 1 clock cycle and returns high.  The counter is not reloaded.
- Counting only occurs when gate is high.
-
-Mode 5: Hardware Strobe.  After programming and loading the counter, the
- output remains high.  When the gate is raised, a countdown is initiated
- (which does not stop if the gate is lowered).  When the counter reaches zero,
- the output goes low for 1 clock cycle and then returns high.  The counter is
- not reloaded.
-
-In addition to normal binary counting, the PIT supports BCD counting.  The
-command port, 0x43 is used to set the counter and mode for each of the three
-timers.
-
-PIT commands, issued to port 0x43, using the following bit encoding:
-
-Bit 7-4: Command (See table below)
-Bit 3-1: Mode (000 = Mode 0, 101 = Mode 5, 11X = undefined)
-Bit 0  : Binary (0) / BCD (1)
-
-Command table:
-
-0000 - Latch Timer 0 count for port 0x40
-	sample and hold the count to be read in port 0x40;
-	additional commands ignored until counter is read;
-	mode bits ignored.
-
-0001 - Set Timer 0 LSB mode for port 0x40
-	set timer to read LSB only and force MSB to zero;
-	mode bits set timer mode
-
-0010 - Set Timer 0 MSB mode for port 0x40
-	set timer to read MSB only and force LSB to zero;
-	mode bits set timer mode
-
-0011 - Set Timer 0 16-bit mode for port 0x40
-	set timer to read / write LSB first, then MSB;
-	mode bits set timer mode
-
-0100 - Latch Timer 1 count for port 0x41 - as described above
-0101 - Set Timer 1 LSB mode for port 0x41 - as described above
-0110 - Set Timer 1 MSB mode for port 0x41 - as described above
-0111 - Set Timer 1 16-bit mode for port 0x41 - as described above
-
-1000 - Latch Timer 2 count for port 0x42 - as described above
-1001 - Set Timer 2 LSB mode for port 0x42 - as described above
-1010 - Set Timer 2 MSB mode for port 0x42 - as described above
-1011 - Set Timer 2 16-bit mode for port 0x42 as described above
-
-1101 - General counter latch
-	Latch combination of counters into corresponding ports
-	Bit 3 = Counter 2
-	Bit 2 = Counter 1
-	Bit 1 = Counter 0
-	Bit 0 = Unused
-
-1110 - Latch timer status
-	Latch combination of counter mode into corresponding ports
-	Bit 3 = Counter 2
-	Bit 2 = Counter 1
-	Bit 1 = Counter 0
-
-	The output of ports 0x40-0x42 following this command will be:
-
-	Bit 7 = Output pin
-	Bit 6 = Count loaded (0 if timer has expired)
-	Bit 5-4 = Read / Write mode
-	    01 = MSB only
-	    10 = LSB only
-	    11 = LSB / MSB (16-bit)
-	Bit 3-1 = Mode
-	Bit 0 = Binary (0) / BCD mode (1)
-
-2.2) RTC
-
-The second device which was available in the original PC was the MC146818 real
-time clock.  The original device is now obsolete, and usually emulated by the
-system chipset, sometimes by an HPET and some frankenstein IRQ routing.
-
-The RTC is accessed through CMOS variables, which uses an index register to
-control which bytes are read.  Since there is only one index register, read
-of the CMOS and read of the RTC require lock protection (in addition, it is
-dangerous to allow userspace utilities such as hwclock to have direct RTC
-access, as they could corrupt kernel reads and writes of CMOS memory).
-
-The RTC generates an interrupt which is usually routed to IRQ 8.  The interrupt
-can function as a periodic timer, an additional once a day alarm, and can issue
-interrupts after an update of the CMOS registers by the MC146818 is complete.
-The type of interrupt is signalled in the RTC status registers.
-
-The RTC will update the current time fields by battery power even while the
-system is off.  The current time fields should not be read while an update is
-in progress, as indicated in the status register.
-
-The clock uses a 32.768kHz crystal, so bits 6-4 of register A should be
-programmed to a 32kHz divider if the RTC is to count seconds.
-
-This is the RAM map originally used for the RTC/CMOS:
-
-Location    Size    Description
-------------------------------------------
-00h         byte    Current second (BCD)
-01h         byte    Seconds alarm (BCD)
-02h         byte    Current minute (BCD)
-03h         byte    Minutes alarm (BCD)
-04h         byte    Current hour (BCD)
-05h         byte    Hours alarm (BCD)
-06h         byte    Current day of week (BCD)
-07h         byte    Current day of month (BCD)
-08h         byte    Current month (BCD)
-09h         byte    Current year (BCD)
-0Ah         byte    Register A
-                       bit 7   = Update in progress
-                       bit 6-4 = Divider for clock
-                                  000 = 4.194 MHz
-                                  001 = 1.049 MHz
-                                  010 = 32 kHz
-                                  10X = test modes
-                                  110 = reset / disable
-                                  111 = reset / disable
-                       bit 3-0 = Rate selection for periodic interrupt
-                                  000 = periodic timer disabled
-                                  001 = 3.90625 uS
-                                  010 = 7.8125 uS
-                                  011 = .122070 mS
-                                  100 = .244141 mS
-                                     ...
-                                 1101 = 125 mS
-                                 1110 = 250 mS
-                                 1111 = 500 mS
-0Bh         byte    Register B
-                       bit 7   = Run (0) / Halt (1)
-                       bit 6   = Periodic interrupt enable
-                       bit 5   = Alarm interrupt enable
-                       bit 4   = Update-ended interrupt enable
-                       bit 3   = Square wave interrupt enable
-                       bit 2   = BCD calendar (0) / Binary (1)
-                       bit 1   = 12-hour mode (0) / 24-hour mode (1)
-                       bit 0   = 0 (DST off) / 1 (DST enabled)
-OCh         byte    Register C (read only)
-                       bit 7   = interrupt request flag (IRQF)
-                       bit 6   = periodic interrupt flag (PF)
-                       bit 5   = alarm interrupt flag (AF)
-                       bit 4   = update interrupt flag (UF)
-                       bit 3-0 = reserved
-ODh         byte    Register D (read only)
-                       bit 7   = RTC has power
-                       bit 6-0 = reserved
-32h         byte    Current century BCD (*)
-  (*) location vendor specific and now determined from ACPI global tables
-
-2.3) APIC
-
-On Pentium and later processors, an on-board timer is available to each CPU
-as part of the Advanced Programmable Interrupt Controller.  The APIC is
-accessed through memory-mapped registers and provides interrupt service to each
-CPU, used for IPIs and local timer interrupts.
-
-Although in theory the APIC is a safe and stable source for local interrupts,
-in practice, many bugs and glitches have occurred due to the special nature of
-the APIC CPU-local memory-mapped hardware.  Beware that CPU errata may affect
-the use of the APIC and that workarounds may be required.  In addition, some of
-these workarounds pose unique constraints for virtualization - requiring either
-extra overhead incurred from extra reads of memory-mapped I/O or additional
-functionality that may be more computationally expensive to implement.
-
-Since the APIC is documented quite well in the Intel and AMD manuals, we will
-avoid repetition of the detail here.  It should be pointed out that the APIC
-timer is programmed through the LVT (local vector timer) register, is capable
-of one-shot or periodic operation, and is based on the bus clock divided down
-by the programmable divider register.
-
-2.4) HPET
-
-HPET is quite complex, and was originally intended to replace the PIT / RTC
-support of the X86 PC.  It remains to be seen whether that will be the case, as
-the de facto standard of PC hardware is to emulate these older devices.  Some
-systems designated as legacy free may support only the HPET as a hardware timer
-device.
-
-The HPET spec is rather loose and vague, requiring at least 3 hardware timers,
-but allowing implementation freedom to support many more.  It also imposes no
-fixed rate on the timer frequency, but does impose some extremal values on
-frequency, error and slew.
-
-In general, the HPET is recommended as a high precision (compared to PIT /RTC)
-time source which is independent of local variation (as there is only one HPET
-in any given system).  The HPET is also memory-mapped, and its presence is
-indicated through ACPI tables by the BIOS.
-
-Detailed specification of the HPET is beyond the current scope of this
-document, as it is also very well documented elsewhere.
-
-2.5) Offboard Timers
-
-Several cards, both proprietary (watchdog boards) and commonplace (e1000) have
-timing chips built into the cards which may have registers which are accessible
-to kernel or user drivers.  To the author's knowledge, using these to generate
-a clocksource for a Linux or other kernel has not yet been attempted and is in
-general frowned upon as not playing by the agreed rules of the game.  Such a
-timer device would require additional support to be virtualized properly and is
-not considered important at this time as no known operating system does this.
-
-=========================================================================
-
-3) TSC Hardware
-
-The TSC or time stamp counter is relatively simple in theory; it counts
-instruction cycles issued by the processor, which can be used as a measure of
-time.  In practice, due to a number of problems, it is the most complicated
-timekeeping device to use.
-
-The TSC is represented internally as a 64-bit MSR which can be read with the
-RDMSR, RDTSC, or RDTSCP (when available) instructions.  In the past, hardware
-limitations made it possible to write the TSC, but generally on old hardware it
-was only possible to write the low 32-bits of the 64-bit counter, and the upper
-32-bits of the counter were cleared.  Now, however, on Intel processors family
-0Fh, for models 3, 4 and 6, and family 06h, models e and f, this restriction
-has been lifted and all 64-bits are writable.  On AMD systems, the ability to
-write the TSC MSR is not an architectural guarantee.
-
-The TSC is accessible from CPL-0 and conditionally, for CPL > 0 software by
-means of the CR4.TSD bit, which when enabled, disables CPL > 0 TSC access.
-
-Some vendors have implemented an additional instruction, RDTSCP, which returns
-atomically not just the TSC, but an indicator which corresponds to the
-processor number.  This can be used to index into an array of TSC variables to
-determine offset information in SMP systems where TSCs are not synchronized.
-The presence of this instruction must be determined by consulting CPUID feature
-bits.
-
-Both VMX and SVM provide extension fields in the virtualization hardware which
-allows the guest visible TSC to be offset by a constant.  Newer implementations
-promise to allow the TSC to additionally be scaled, but this hardware is not
-yet widely available.
-
-3.1) TSC synchronization
-
-The TSC is a CPU-local clock in most implementations.  This means, on SMP
-platforms, the TSCs of different CPUs may start at different times depending
-on when the CPUs are powered on.  Generally, CPUs on the same die will share
-the same clock, however, this is not always the case.
-
-The BIOS may attempt to resynchronize the TSCs during the poweron process and
-the operating system or other system software may attempt to do this as well.
-Several hardware limitations make the problem worse - if it is not possible to
-write the full 64-bits of the TSC, it may be impossible to match the TSC in
-newly arriving CPUs to that of the rest of the system, resulting in
-unsynchronized TSCs.  This may be done by BIOS or system software, but in
-practice, getting a perfectly synchronized TSC will not be possible unless all
-values are read from the same clock, which generally only is possible on single
-socket systems or those with special hardware support.
-
-3.2) TSC and CPU hotplug
-
-As touched on already, CPUs which arrive later than the boot time of the system
-may not have a TSC value that is synchronized with the rest of the system.
-Either system software, BIOS, or SMM code may actually try to establish the TSC
-to a value matching the rest of the system, but a perfect match is usually not
-a guarantee.  This can have the effect of bringing a system from a state where
-TSC is synchronized back to a state where TSC synchronization flaws, however
-small, may be exposed to the OS and any virtualization environment.
-
-3.3) TSC and multi-socket / NUMA
-
-Multi-socket systems, especially large multi-socket systems are likely to have
-individual clocksources rather than a single, universally distributed clock.
-Since these clocks are driven by different crystals, they will not have
-perfectly matched frequency, and temperature and electrical variations will
-cause the CPU clocks, and thus the TSCs to drift over time.  Depending on the
-exact clock and bus design, the drift may or may not be fixed in absolute
-error, and may accumulate over time.
-
-In addition, very large systems may deliberately slew the clocks of individual
-cores.  This technique, known as spread-spectrum clocking, reduces EMI at the
-clock frequency and harmonics of it, which may be required to pass FCC
-standards for telecommunications and computer equipment.
-
-It is recommended not to trust the TSCs to remain synchronized on NUMA or
-multiple socket systems for these reasons.
-
-3.4) TSC and C-states
-
-C-states, or idling states of the processor, especially C1E and deeper sleep
-states may be problematic for TSC as well.  The TSC may stop advancing in such
-a state, resulting in a TSC which is behind that of other CPUs when execution
-is resumed.  Such CPUs must be detected and flagged by the operating system
-based on CPU and chipset identifications.
-
-The TSC in such a case may be corrected by catching it up to a known external
-clocksource.
-
-3.5) TSC frequency change / P-states
-
-To make things slightly more interesting, some CPUs may change frequency.  They
-may or may not run the TSC at the same rate, and because the frequency change
-may be staggered or slewed, at some points in time, the TSC rate may not be
-known other than falling within a range of values.  In this case, the TSC will
-not be a stable time source, and must be calibrated against a known, stable,
-external clock to be a usable source of time.
-
-Whether the TSC runs at a constant rate or scales with the P-state is model
-dependent and must be determined by inspecting CPUID, chipset or vendor
-specific MSR fields.
-
-In addition, some vendors have known bugs where the P-state is actually
-compensated for properly during normal operation, but when the processor is
-inactive, the P-state may be raised temporarily to service cache misses from
-other processors.  In such cases, the TSC on halted CPUs could advance faster
-than that of non-halted processors.  AMD Turion processors are known to have
-this problem.
-
-3.6) TSC and STPCLK / T-states
-
-External signals given to the processor may also have the effect of stopping
-the TSC.  This is typically done for thermal emergency power control to prevent
-an overheating condition, and typically, there is no way to detect that this
-condition has happened.
-
-3.7) TSC virtualization - VMX
-
-VMX provides conditional trapping of RDTSC, RDMSR, WRMSR and RDTSCP
-instructions, which is enough for full virtualization of TSC in any manner.  In
-addition, VMX allows passing through the host TSC plus an additional TSC_OFFSET
-field specified in the VMCS.  Special instructions must be used to read and
-write the VMCS field.
-
-3.8) TSC virtualization - SVM
-
-SVM provides conditional trapping of RDTSC, RDMSR, WRMSR and RDTSCP
-instructions, which is enough for full virtualization of TSC in any manner.  In
-addition, SVM allows passing through the host TSC plus an additional offset
-field specified in the SVM control block.
-
-3.9) TSC feature bits in Linux
-
-In summary, there is no way to guarantee the TSC remains in perfect
-synchronization unless it is explicitly guaranteed by the architecture.  Even
-if so, the TSCs in multi-sockets or NUMA systems may still run independently
-despite being locally consistent.
-
-The following feature bits are used by Linux to signal various TSC attributes,
-but they can only be taken to be meaningful for UP or single node systems.
-
-X86_FEATURE_TSC 		: The TSC is available in hardware
-X86_FEATURE_RDTSCP		: The RDTSCP instruction is available
-X86_FEATURE_CONSTANT_TSC 	: The TSC rate is unchanged with P-states
-X86_FEATURE_NONSTOP_TSC		: The TSC does not stop in C-states
-X86_FEATURE_TSC_RELIABLE	: TSC sync checks are skipped (VMware)
-
-4) Virtualization Problems
-
-Timekeeping is especially problematic for virtualization because a number of
-challenges arise.  The most obvious problem is that time is now shared between
-the host and, potentially, a number of virtual machines.  Thus the virtual
-operating system does not run with 100% usage of the CPU, despite the fact that
-it may very well make that assumption.  It may expect it to remain true to very
-exacting bounds when interrupt sources are disabled, but in reality only its
-virtual interrupt sources are disabled, and the machine may still be preempted
-at any time.  This causes problems as the passage of real time, the injection
-of machine interrupts and the associated clock sources are no longer completely
-synchronized with real time.
-
-This same problem can occur on native harware to a degree, as SMM mode may
-steal cycles from the naturally on X86 systems when SMM mode is used by the
-BIOS, but not in such an extreme fashion.  However, the fact that SMM mode may
-cause similar problems to virtualization makes it a good justification for
-solving many of these problems on bare metal.
-
-4.1) Interrupt clocking
-
-One of the most immediate problems that occurs with legacy operating systems
-is that the system timekeeping routines are often designed to keep track of
-time by counting periodic interrupts.  These interrupts may come from the PIT
-or the RTC, but the problem is the same: the host virtualization engine may not
-be able to deliver the proper number of interrupts per second, and so guest
-time may fall behind.  This is especially problematic if a high interrupt rate
-is selected, such as 1000 HZ, which is unfortunately the default for many Linux
-guests.
-
-There are three approaches to solving this problem; first, it may be possible
-to simply ignore it.  Guests which have a separate time source for tracking
-'wall clock' or 'real time' may not need any adjustment of their interrupts to
-maintain proper time.  If this is not sufficient, it may be necessary to inject
-additional interrupts into the guest in order to increase the effective
-interrupt rate.  This approach leads to complications in extreme conditions,
-where host load or guest lag is too much to compensate for, and thus another
-solution to the problem has risen: the guest may need to become aware of lost
-ticks and compensate for them internally.  Although promising in theory, the
-implementation of this policy in Linux has been extremely error prone, and a
-number of buggy variants of lost tick compensation are distributed across
-commonly used Linux systems.
-
-Windows uses periodic RTC clocking as a means of keeping time internally, and
-thus requires interrupt slewing to keep proper time.  It does use a low enough
-rate (ed: is it 18.2 Hz?) however that it has not yet been a problem in
-practice.
-
-4.2) TSC sampling and serialization
-
-As the highest precision time source available, the cycle counter of the CPU
-has aroused much interest from developers.  As explained above, this timer has
-many problems unique to its nature as a local, potentially unstable and
-potentially unsynchronized source.  One issue which is not unique to the TSC,
-but is highlighted because of its very precise nature is sampling delay.  By
-definition, the counter, once read is already old.  However, it is also
-possible for the counter to be read ahead of the actual use of the result.
-This is a consequence of the superscalar execution of the instruction stream,
-which may execute instructions out of order.  Such execution is called
-non-serialized.  Forcing serialized execution is necessary for precise
-measurement with the TSC, and requires a serializing instruction, such as CPUID
-or an MSR read.
-
-Since CPUID may actually be virtualized by a trap and emulate mechanism, this
-serialization can pose a performance issue for hardware virtualization.  An
-accurate time stamp counter reading may therefore not always be available, and
-it may be necessary for an implementation to guard against "backwards" reads of
-the TSC as seen from other CPUs, even in an otherwise perfectly synchronized
-system.
-
-4.3) Timespec aliasing
-
-Additionally, this lack of serialization from the TSC poses another challenge
-when using results of the TSC when measured against another time source.  As
-the TSC is much higher precision, many possible values of the TSC may be read
-while another clock is still expressing the same value.
-
-That is, you may read (T,T+10) while external clock C maintains the same value.
-Due to non-serialized reads, you may actually end up with a range which
-fluctuates - from (T-1.. T+10).  Thus, any time calculated from a TSC, but
-calibrated against an external value may have a range of valid values.
-Re-calibrating this computation may actually cause time, as computed after the
-calibration, to go backwards, compared with time computed before the
-calibration.
-
-This problem is particularly pronounced with an internal time source in Linux,
-the kernel time, which is expressed in the theoretically high resolution
-timespec - but which advances in much larger granularity intervals, sometimes
-at the rate of jiffies, and possibly in catchup modes, at a much larger step.
-
-This aliasing requires care in the computation and recalibration of kvmclock
-and any other values derived from TSC computation (such as TSC virtualization
-itself).
-
-4.4) Migration
-
-Migration of a virtual machine raises problems for timekeeping in two ways.
-First, the migration itself may take time, during which interrupts cannot be
-delivered, and after which, the guest time may need to be caught up.  NTP may
-be able to help to some degree here, as the clock correction required is
-typically small enough to fall in the NTP-correctable window.
-
-An additional concern is that timers based off the TSC (or HPET, if the raw bus
-clock is exposed) may now be running at different rates, requiring compensation
-in some way in the hypervisor by virtualizing these timers.  In addition,
-migrating to a faster machine may preclude the use of a passthrough TSC, as a
-faster clock cannot be made visible to a guest without the potential of time
-advancing faster than usual.  A slower clock is less of a problem, as it can
-always be caught up to the original rate.  KVM clock avoids these problems by
-simply storing multipliers and offsets against the TSC for the guest to convert
-back into nanosecond resolution values.
-
-4.5) Scheduling
-
-Since scheduling may be based on precise timing and firing of interrupts, the
-scheduling algorithms of an operating system may be adversely affected by
-virtualization.  In theory, the effect is random and should be universally
-distributed, but in contrived as well as real scenarios (guest device access,
-causes of virtualization exits, possible context switch), this may not always
-be the case.  The effect of this has not been well studied.
-
-In an attempt to work around this, several implementations have provided a
-paravirtualized scheduler clock, which reveals the true amount of CPU time for
-which a virtual machine has been running.
-
-4.6) Watchdogs
-
-Watchdog timers, such as the lock detector in Linux may fire accidentally when
-running under hardware virtualization due to timer interrupts being delayed or
-misinterpretation of the passage of real time.  Usually, these warnings are
-spurious and can be ignored, but in some circumstances it may be necessary to
-disable such detection.
-
-4.7) Delays and precision timing
-
-Precise timing and delays may not be possible in a virtualized system.  This
-can happen if the system is controlling physical hardware, or issues delays to
-compensate for slower I/O to and from devices.  The first issue is not solvable
-in general for a virtualized system; hardware control software can't be
-adequately virtualized without a full real-time operating system, which would
-require an RT aware virtualization platform.
-
-The second issue may cause performance problems, but this is unlikely to be a
-significant issue.  In many cases these delays may be eliminated through
-configuration or paravirtualization.
-
-4.8) Covert channels and leaks
-
-In addition to the above problems, time information will inevitably leak to the
-guest about the host in anything but a perfect implementation of virtualized
-time.  This may allow the guest to infer the presence of a hypervisor (as in a
-red-pill type detection), and it may allow information to leak between guests
-by using CPU utilization itself as a signalling channel.  Preventing such
-problems would require completely isolated virtual time which may not track
-real time any longer.  This may be useful in certain security or QA contexts,
-but in general isn't recommended for real-world deployment scenarios.
diff -druN linux-2.6.39-libre/Documentation/laptops/acer-wmi.txt linux-3.0-rc7-libre/Documentation/laptops/acer-wmi.txt
--- linux-2.6.39-libre/Documentation/laptops/acer-wmi.txt	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/Documentation/laptops/acer-wmi.txt	1969-12-31 19:00:00.000000000 -0500
@@ -1,184 +0,0 @@
-Acer Laptop WMI Extras Driver
-http://code.google.com/p/aceracpi
-Version 0.3
-4th April 2009
-
-Copyright 2007-2009 Carlos Corbacho <carlos@strangeworlds.co.uk>
-
-acer-wmi is a driver to allow you to control various parts of your Acer laptop
-hardware under Linux which are exposed via ACPI-WMI.
-
-This driver completely replaces the old out-of-tree acer_acpi, which I am
-currently maintaining for bug fixes only on pre-2.6.25 kernels. All development
-work is now focused solely on acer-wmi.
-
-Disclaimer
-**********
-
-Acer and Wistron have provided nothing towards the development acer_acpi or
-acer-wmi. All information we have has been through the efforts of the developers
-and the users to discover as much as possible about the hardware.
-
-As such, I do warn that this could break your hardware - this is extremely
-unlikely of course, but please bear this in mind.
-
-Background
-**********
-
-acer-wmi is derived from acer_acpi, originally developed by Mark
-Smith in 2005, then taken over by Carlos Corbacho in 2007, in order to activate
-the wireless LAN card under a 64-bit version of Linux, as acerhk[1] (the
-previous solution to the problem) relied on making 32 bit BIOS calls which are
-not possible in kernel space from a 64 bit OS.
-
-[1] acerhk: http://www.cakey.de/acerhk/
-
-Supported Hardware
-******************
-
-NOTE: The Acer Aspire One is not supported hardware. It cannot work with
-acer-wmi until Acer fix their ACPI-WMI implementation on them, so has been
-blacklisted until that happens.
-
-Please see the website for the current list of known working hardware:
-
-http://code.google.com/p/aceracpi/wiki/SupportedHardware
-
-If your laptop is not listed, or listed as unknown, and works with acer-wmi,
-please contact me with a copy of the DSDT.
-
-If your Acer laptop doesn't work with acer-wmi, I would also like to see the
-DSDT.
-
-To send me the DSDT, as root/sudo:
-
-cat /sys/firmware/acpi/tables/DSDT > dsdt
-
-And send me the resulting 'dsdt' file.
-
-Usage
-*****
-
-On Acer laptops, acer-wmi should already be autoloaded based on DMI matching.
-For non-Acer laptops, until WMI based autoloading support is added, you will
-need to manually load acer-wmi.
-
-acer-wmi creates /sys/devices/platform/acer-wmi, and fills it with various
-files whose usage is detailed below, which enables you to control some of the
-following (varies between models):
-
-* the wireless LAN card radio
-* inbuilt Bluetooth adapter
-* inbuilt 3G card
-* mail LED of your laptop
-* brightness of the LCD panel
-
-Wireless
-********
-
-With regards to wireless, all acer-wmi does is enable the radio on the card. It
-is not responsible for the wireless LED - once the radio is enabled, this is
-down to the wireless driver for your card. So the behaviour of the wireless LED,
-once you enable the radio, will depend on your hardware and driver combination.
-
-e.g. With the BCM4318 on the Acer Aspire 5020 series:
-
-ndiswrapper: Light blinks on when transmitting
-b43: Solid light, blinks off when transmitting
-
-Wireless radio control is unconditionally enabled - all Acer laptops that support
-acer-wmi come with built-in wireless. However, should you feel so inclined to
-ever wish to remove the card, or swap it out at some point, please get in touch
-with me, as we may well be able to gain some data on wireless card detection.
-
-The wireless radio is exposed through rfkill.
-
-Bluetooth
-*********
-
-For bluetooth, this is an internal USB dongle, so once enabled, you will get
-a USB device connection event, and a new USB device appears. When you disable
-bluetooth, you get the reverse - a USB device disconnect event, followed by the
-device disappearing again.
-
-Bluetooth is autodetected by acer-wmi, so if you do not have a bluetooth module
-installed in your laptop, this file won't exist (please be aware that it is
-quite common for Acer not to fit bluetooth to their laptops - so just because
-you have a bluetooth button on the laptop, doesn't mean that bluetooth is
-installed).
-
-For the adventurously minded - if you want to buy an internal bluetooth
-module off the internet that is compatible with your laptop and fit it, then
-it will work just fine with acer-wmi.
-
-Bluetooth is exposed through rfkill.
-
-3G
-**
-
-3G is currently not autodetected, so the 'threeg' file is always created under
-sysfs. So far, no-one in possession of an Acer laptop with 3G built-in appears to
-have tried Linux, or reported back, so we don't have any information on this.
-
-If you have an Acer laptop that does have a 3G card in, please contact me so we
-can properly detect these, and find out a bit more about them.
-
-To read the status of the 3G card (0=off, 1=on):
-cat /sys/devices/platform/acer-wmi/threeg
-
-To enable the 3G card:
-echo 1 > /sys/devices/platform/acer-wmi/threeg
-
-To disable the 3G card:
-echo 0 > /sys/devices/platform/acer-wmi/threeg
-
-To set the state of the 3G card when loading acer-wmi, pass:
-threeg=X (where X is 0 or 1)
-
-Mail LED
-********
-
-This can be found in most older Acer laptops supported by acer-wmi, and many
-newer ones - it is built into the 'mail' button, and blinks when active.
-
-On newer (WMID) laptops though, we have no way of detecting the mail LED. If
-your laptop identifies itself in dmesg as a WMID model, then please try loading
-acer_acpi with:
-
-force_series=2490
-
-This will use a known alternative method of reading/ writing the mail LED. If
-it works, please report back to me with the DMI data from your laptop so this
-can be added to acer-wmi.
-
-The LED is exposed through the LED subsystem, and can be found in:
-
-/sys/devices/platform/acer-wmi/leds/acer-wmi::mail/
-
-The mail LED is autodetected, so if you don't have one, the LED device won't
-be registered.
-
-Backlight
-*********
-
-The backlight brightness control is available on all acer-wmi supported
-hardware. The maximum brightness level is usually 15, but on some newer laptops
-it's 10 (this is again autodetected).
-
-The backlight is exposed through the backlight subsystem, and can be found in:
-
-/sys/devices/platform/acer-wmi/backlight/acer-wmi/
-
-Credits
-*******
-
-Olaf Tauber, who did the real hard work when he developed acerhk
-http://www.cakey.de/acerhk/
-All the authors of laptop ACPI modules in the kernel, whose work
-was an inspiration in the early days of acer_acpi
-Mathieu Segaud, who solved the problem with having to modprobe the driver
-twice in acer_acpi 0.2.
-Jim Ramsay, who added support for the WMID interface
-Mark Smith, who started the original acer_acpi
-
-And the many people who have used both acer_acpi and acer-wmi.
diff -druN linux-2.6.39-libre/Documentation/laptops/thinkpad-acpi.txt linux-3.0-rc7-libre/Documentation/laptops/thinkpad-acpi.txt
--- linux-2.6.39-libre/Documentation/laptops/thinkpad-acpi.txt	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/Documentation/laptops/thinkpad-acpi.txt	2011-07-11 19:51:52.000000000 -0400
@@ -534,6 +534,8 @@
 0x2404		System is waking up from hibernation to undock
 0x2405		System is waking up from hibernation to eject bay
 0x5010		Brightness level changed/control event
+0x6000		KEYBOARD: Numlock key pressed
+0x6005		KEYBOARD: Fn key pressed (TO BE VERIFIED)
 
 Events that are propagated by the driver to userspace:
 
@@ -545,6 +547,8 @@
 0x3006		Bay hotplug request (hint to power up SATA link when
 		the optical drive tray is ejected)
 0x4003		Undocked (see 0x2x04), can sleep again
+0x4010		Docked into hotplug port replicator (non-ACPI dock)
+0x4011		Undocked from hotplug port replicator (non-ACPI dock)
 0x500B		Tablet pen inserted into its storage bay
 0x500C		Tablet pen removed from its storage bay
 0x6011		ALARM: battery is too hot
@@ -552,6 +556,7 @@
 0x6021		ALARM: a sensor is too hot
 0x6022		ALARM: a sensor is extremely hot
 0x6030		System thermal table changed
+0x6040		Nvidia Optimus/AC adapter related (TO BE VERIFIED)
 
 Battery nearly empty alarms are a last resort attempt to get the
 operating system to hibernate or shutdown cleanly (0x2313), or shutdown
diff -druN linux-2.6.39-libre/Documentation/lguest/extract linux-3.0-rc7-libre/Documentation/lguest/extract
--- linux-2.6.39-libre/Documentation/lguest/extract	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/Documentation/lguest/extract	1969-12-31 19:00:00.000000000 -0500
@@ -1,58 +0,0 @@
-#! /bin/sh
-
-set -e
-
-PREFIX=$1
-shift
-
-trap 'rm -r $TMPDIR' 0
-TMPDIR=`mktemp -d`
-
-exec 3>/dev/null
-for f; do
-    while IFS="
-" read -r LINE; do
-	case "$LINE" in
-	    *$PREFIX:[0-9]*:\**)
-		NUM=`echo "$LINE" | sed "s/.*$PREFIX:\([0-9]*\).*/\1/"`
-		if [ -f $TMPDIR/$NUM ]; then
-		    echo "$TMPDIR/$NUM already exits prior to $f"
-		    exit 1
-		fi
-		exec 3>>$TMPDIR/$NUM
-		echo $f | sed 's,\.\./,,g' > $TMPDIR/.$NUM
-		/bin/echo "$LINE" | sed -e "s/$PREFIX:[0-9]*//" -e "s/:\*/*/" >&3
-		;;
-	    *$PREFIX:[0-9]*)
-		NUM=`echo "$LINE" | sed "s/.*$PREFIX:\([0-9]*\).*/\1/"`
-		if [ -f $TMPDIR/$NUM ]; then
-		    echo "$TMPDIR/$NUM already exits prior to $f"
-		    exit 1
-		fi
-		exec 3>>$TMPDIR/$NUM
-		echo $f | sed 's,\.\./,,g' > $TMPDIR/.$NUM
-		/bin/echo "$LINE" | sed "s/$PREFIX:[0-9]*//" >&3
-		;;
-	    *:\**)
-		/bin/echo "$LINE" | sed -e "s/:\*/*/" -e "s,/\*\*/,," >&3
-		echo >&3
-		exec 3>/dev/null
-		;;
-	    *)
-		/bin/echo "$LINE" >&3
-		;;
-	esac
-    done < $f
-    echo >&3
-    exec 3>/dev/null
-done
-
-LASTFILE=""
-for f in $TMPDIR/*; do
-    if [ "$LASTFILE" != $(cat $TMPDIR/.$(basename $f) ) ]; then
-	LASTFILE=$(cat $TMPDIR/.$(basename $f) )
-	echo "[ $LASTFILE ]"
-    fi
-    cat $f
-done
-
diff -druN linux-2.6.39-libre/Documentation/lguest/.gitignore linux-3.0-rc7-libre/Documentation/lguest/.gitignore
--- linux-2.6.39-libre/Documentation/lguest/.gitignore	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/Documentation/lguest/.gitignore	1969-12-31 19:00:00.000000000 -0500
@@ -1 +0,0 @@
-lguest
diff -druN linux-2.6.39-libre/Documentation/lguest/lguest.c linux-3.0-rc7-libre/Documentation/lguest/lguest.c
--- linux-2.6.39-libre/Documentation/lguest/lguest.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/Documentation/lguest/lguest.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,2095 +0,0 @@
-/*P:100
- * This is the Launcher code, a simple program which lays out the "physical"
- * memory for the new Guest by mapping the kernel image and the virtual
- * devices, then opens /dev/lguest to tell the kernel about the Guest and
- * control it.
-:*/
-#define _LARGEFILE64_SOURCE
-#define _GNU_SOURCE
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
-#include <err.h>
-#include <stdint.h>
-#include <stdlib.h>
-#include <elf.h>
-#include <sys/mman.h>
-#include <sys/param.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/wait.h>
-#include <sys/eventfd.h>
-#include <fcntl.h>
-#include <stdbool.h>
-#include <errno.h>
-#include <ctype.h>
-#include <sys/socket.h>
-#include <sys/ioctl.h>
-#include <sys/time.h>
-#include <time.h>
-#include <netinet/in.h>
-#include <net/if.h>
-#include <linux/sockios.h>
-#include <linux/if_tun.h>
-#include <sys/uio.h>
-#include <termios.h>
-#include <getopt.h>
-#include <assert.h>
-#include <sched.h>
-#include <limits.h>
-#include <stddef.h>
-#include <signal.h>
-#include <pwd.h>
-#include <grp.h>
-
-#include <linux/virtio_config.h>
-#include <linux/virtio_net.h>
-#include <linux/virtio_blk.h>
-#include <linux/virtio_console.h>
-#include <linux/virtio_rng.h>
-#include <linux/virtio_ring.h>
-#include <asm/bootparam.h>
-#include "../../include/linux/lguest_launcher.h"
-/*L:110
- * We can ignore the 42 include files we need for this program, but I do want
- * to draw attention to the use of kernel-style types.
- *
- * As Linus said, "C is a Spartan language, and so should your naming be."  I
- * like these abbreviations, so we define them here.  Note that u64 is always
- * unsigned long long, which works on all Linux systems: this means that we can
- * use %llu in printf for any u64.
- */
-typedef unsigned long long u64;
-typedef uint32_t u32;
-typedef uint16_t u16;
-typedef uint8_t u8;
-/*:*/
-
-#define PAGE_PRESENT 0x7 	/* Present, RW, Execute */
-#define BRIDGE_PFX "bridge:"
-#ifndef SIOCBRADDIF
-#define SIOCBRADDIF	0x89a2		/* add interface to bridge      */
-#endif
-/* We can have up to 256 pages for devices. */
-#define DEVICE_PAGES 256
-/* This will occupy 3 pages: it must be a power of 2. */
-#define VIRTQUEUE_NUM 256
-
-/*L:120
- * verbose is both a global flag and a macro.  The C preprocessor allows
- * this, and although I wouldn't recommend it, it works quite nicely here.
- */
-static bool verbose;
-#define verbose(args...) \
-	do { if (verbose) printf(args); } while(0)
-/*:*/
-
-/* The pointer to the start of guest memory. */
-static void *guest_base;
-/* The maximum guest physical address allowed, and maximum possible. */
-static unsigned long guest_limit, guest_max;
-/* The /dev/lguest file descriptor. */
-static int lguest_fd;
-
-/* a per-cpu variable indicating whose vcpu is currently running */
-static unsigned int __thread cpu_id;
-
-/* This is our list of devices. */
-struct device_list {
-	/* Counter to assign interrupt numbers. */
-	unsigned int next_irq;
-
-	/* Counter to print out convenient device numbers. */
-	unsigned int device_num;
-
-	/* The descriptor page for the devices. */
-	u8 *descpage;
-
-	/* A single linked list of devices. */
-	struct device *dev;
-	/* And a pointer to the last device for easy append. */
-	struct device *lastdev;
-};
-
-/* The list of Guest devices, based on command line arguments. */
-static struct device_list devices;
-
-/* The device structure describes a single device. */
-struct device {
-	/* The linked-list pointer. */
-	struct device *next;
-
-	/* The device's descriptor, as mapped into the Guest. */
-	struct lguest_device_desc *desc;
-
-	/* We can't trust desc values once Guest has booted: we use these. */
-	unsigned int feature_len;
-	unsigned int num_vq;
-
-	/* The name of this device, for --verbose. */
-	const char *name;
-
-	/* Any queues attached to this device */
-	struct virtqueue *vq;
-
-	/* Is it operational */
-	bool running;
-
-	/* Does Guest want an intrrupt on empty? */
-	bool irq_on_empty;
-
-	/* Device-specific data. */
-	void *priv;
-};
-
-/* The virtqueue structure describes a queue attached to a device. */
-struct virtqueue {
-	struct virtqueue *next;
-
-	/* Which device owns me. */
-	struct device *dev;
-
-	/* The configuration for this queue. */
-	struct lguest_vqconfig config;
-
-	/* The actual ring of buffers. */
-	struct vring vring;
-
-	/* Last available index we saw. */
-	u16 last_avail_idx;
-
-	/* How many are used since we sent last irq? */
-	unsigned int pending_used;
-
-	/* Eventfd where Guest notifications arrive. */
-	int eventfd;
-
-	/* Function for the thread which is servicing this virtqueue. */
-	void (*service)(struct virtqueue *vq);
-	pid_t thread;
-};
-
-/* Remember the arguments to the program so we can "reboot" */
-static char **main_args;
-
-/* The original tty settings to restore on exit. */
-static struct termios orig_term;
-
-/*
- * We have to be careful with barriers: our devices are all run in separate
- * threads and so we need to make sure that changes visible to the Guest happen
- * in precise order.
- */
-#define wmb() __asm__ __volatile__("" : : : "memory")
-#define mb() __asm__ __volatile__("" : : : "memory")
-
-/*
- * Convert an iovec element to the given type.
- *
- * This is a fairly ugly trick: we need to know the size of the type and
- * alignment requirement to check the pointer is kosher.  It's also nice to
- * have the name of the type in case we report failure.
- *
- * Typing those three things all the time is cumbersome and error prone, so we
- * have a macro which sets them all up and passes to the real function.
- */
-#define convert(iov, type) \
-	((type *)_convert((iov), sizeof(type), __alignof__(type), #type))
-
-static void *_convert(struct iovec *iov, size_t size, size_t align,
-		      const char *name)
-{
-	if (iov->iov_len != size)
-		errx(1, "Bad iovec size %zu for %s", iov->iov_len, name);
-	if ((unsigned long)iov->iov_base % align != 0)
-		errx(1, "Bad alignment %p for %s", iov->iov_base, name);
-	return iov->iov_base;
-}
-
-/* Wrapper for the last available index.  Makes it easier to change. */
-#define lg_last_avail(vq)	((vq)->last_avail_idx)
-
-/*
- * The virtio configuration space is defined to be little-endian.  x86 is
- * little-endian too, but it's nice to be explicit so we have these helpers.
- */
-#define cpu_to_le16(v16) (v16)
-#define cpu_to_le32(v32) (v32)
-#define cpu_to_le64(v64) (v64)
-#define le16_to_cpu(v16) (v16)
-#define le32_to_cpu(v32) (v32)
-#define le64_to_cpu(v64) (v64)
-
-/* Is this iovec empty? */
-static bool iov_empty(const struct iovec iov[], unsigned int num_iov)
-{
-	unsigned int i;
-
-	for (i = 0; i < num_iov; i++)
-		if (iov[i].iov_len)
-			return false;
-	return true;
-}
-
-/* Take len bytes from the front of this iovec. */
-static void iov_consume(struct iovec iov[], unsigned num_iov, unsigned len)
-{
-	unsigned int i;
-
-	for (i = 0; i < num_iov; i++) {
-		unsigned int used;
-
-		used = iov[i].iov_len < len ? iov[i].iov_len : len;
-		iov[i].iov_base += used;
-		iov[i].iov_len -= used;
-		len -= used;
-	}
-	assert(len == 0);
-}
-
-/* The device virtqueue descriptors are followed by feature bitmasks. */
-static u8 *get_feature_bits(struct device *dev)
-{
-	return (u8 *)(dev->desc + 1)
-		+ dev->num_vq * sizeof(struct lguest_vqconfig);
-}
-
-/*L:100
- * The Launcher code itself takes us out into userspace, that scary place where
- * pointers run wild and free!  Unfortunately, like most userspace programs,
- * it's quite boring (which is why everyone likes to hack on the kernel!).
- * Perhaps if you make up an Lguest Drinking Game at this point, it will get
- * you through this section.  Or, maybe not.
- *
- * The Launcher sets up a big chunk of memory to be the Guest's "physical"
- * memory and stores it in "guest_base".  In other words, Guest physical ==
- * Launcher virtual with an offset.
- *
- * This can be tough to get your head around, but usually it just means that we
- * use these trivial conversion functions when the Guest gives us its
- * "physical" addresses:
- */
-static void *from_guest_phys(unsigned long addr)
-{
-	return guest_base + addr;
-}
-
-static unsigned long to_guest_phys(const void *addr)
-{
-	return (addr - guest_base);
-}
-
-/*L:130
- * Loading the Kernel.
- *
- * We start with couple of simple helper routines.  open_or_die() avoids
- * error-checking code cluttering the callers:
- */
-static int open_or_die(const char *name, int flags)
-{
-	int fd = open(name, flags);
-	if (fd < 0)
-		err(1, "Failed to open %s", name);
-	return fd;
-}
-
-/* map_zeroed_pages() takes a number of pages. */
-static void *map_zeroed_pages(unsigned int num)
-{
-	int fd = open_or_die("/dev/zero", O_RDONLY);
-	void *addr;
-
-	/*
-	 * We use a private mapping (ie. if we write to the page, it will be
-	 * copied). We allocate an extra two pages PROT_NONE to act as guard
-	 * pages against read/write attempts that exceed allocated space.
-	 */
-	addr = mmap(NULL, getpagesize() * (num+2),
-		    PROT_NONE, MAP_PRIVATE, fd, 0);
-
-	if (addr == MAP_FAILED)
-		err(1, "Mmapping %u pages of /dev/zero", num);
-
-	if (mprotect(addr + getpagesize(), getpagesize() * num,
-		     PROT_READ|PROT_WRITE) == -1)
-		err(1, "mprotect rw %u pages failed", num);
-
-	/*
-	 * One neat mmap feature is that you can close the fd, and it
-	 * stays mapped.
-	 */
-	close(fd);
-
-	/* Return address after PROT_NONE page */
-	return addr + getpagesize();
-}
-
-/* Get some more pages for a device. */
-static void *get_pages(unsigned int num)
-{
-	void *addr = from_guest_phys(guest_limit);
-
-	guest_limit += num * getpagesize();
-	if (guest_limit > guest_max)
-		errx(1, "Not enough memory for devices");
-	return addr;
-}
-
-/*
- * This routine is used to load the kernel or initrd.  It tries mmap, but if
- * that fails (Plan 9's kernel file isn't nicely aligned on page boundaries),
- * it falls back to reading the memory in.
- */
-static void map_at(int fd, void *addr, unsigned long offset, unsigned long len)
-{
-	ssize_t r;
-
-	/*
-	 * We map writable even though for some segments are marked read-only.
-	 * The kernel really wants to be writable: it patches its own
-	 * instructions.
-	 *
-	 * MAP_PRIVATE means that the page won't be copied until a write is
-	 * done to it.  This allows us to share untouched memory between
-	 * Guests.
-	 */
-	if (mmap(addr, len, PROT_READ|PROT_WRITE,
-		 MAP_FIXED|MAP_PRIVATE, fd, offset) != MAP_FAILED)
-		return;
-
-	/* pread does a seek and a read in one shot: saves a few lines. */
-	r = pread(fd, addr, len, offset);
-	if (r != len)
-		err(1, "Reading offset %lu len %lu gave %zi", offset, len, r);
-}
-
-/*
- * This routine takes an open vmlinux image, which is in ELF, and maps it into
- * the Guest memory.  ELF = Embedded Linking Format, which is the format used
- * by all modern binaries on Linux including the kernel.
- *
- * The ELF headers give *two* addresses: a physical address, and a virtual
- * address.  We use the physical address; the Guest will map itself to the
- * virtual address.
- *
- * We return the starting address.
- */
-static unsigned long map_elf(int elf_fd, const Elf32_Ehdr *ehdr)
-{
-	Elf32_Phdr phdr[ehdr->e_phnum];
-	unsigned int i;
-
-	/*
-	 * Sanity checks on the main ELF header: an x86 executable with a
-	 * reasonable number of correctly-sized program headers.
-	 */
-	if (ehdr->e_type != ET_EXEC
-	    || ehdr->e_machine != EM_386
-	    || ehdr->e_phentsize != sizeof(Elf32_Phdr)
-	    || ehdr->e_phnum < 1 || ehdr->e_phnum > 65536U/sizeof(Elf32_Phdr))
-		errx(1, "Malformed elf header");
-
-	/*
-	 * An ELF executable contains an ELF header and a number of "program"
-	 * headers which indicate which parts ("segments") of the program to
-	 * load where.
-	 */
-
-	/* We read in all the program headers at once: */
-	if (lseek(elf_fd, ehdr->e_phoff, SEEK_SET) < 0)
-		err(1, "Seeking to program headers");
-	if (read(elf_fd, phdr, sizeof(phdr)) != sizeof(phdr))
-		err(1, "Reading program headers");
-
-	/*
-	 * Try all the headers: there are usually only three.  A read-only one,
-	 * a read-write one, and a "note" section which we don't load.
-	 */
-	for (i = 0; i < ehdr->e_phnum; i++) {
-		/* If this isn't a loadable segment, we ignore it */
-		if (phdr[i].p_type != PT_LOAD)
-			continue;
-
-		verbose("Section %i: size %i addr %p\n",
-			i, phdr[i].p_memsz, (void *)phdr[i].p_paddr);
-
-		/* We map this section of the file at its physical address. */
-		map_at(elf_fd, from_guest_phys(phdr[i].p_paddr),
-		       phdr[i].p_offset, phdr[i].p_filesz);
-	}
-
-	/* The entry point is given in the ELF header. */
-	return ehdr->e_entry;
-}
-
-/*L:150
- * A bzImage, unlike an ELF file, is not meant to be loaded.  You're supposed
- * to jump into it and it will unpack itself.  We used to have to perform some
- * hairy magic because the unpacking code scared me.
- *
- * Fortunately, Jeremy Fitzhardinge convinced me it wasn't that hard and wrote
- * a small patch to jump over the tricky bits in the Guest, so now we just read
- * the funky header so we know where in the file to load, and away we go!
- */
-static unsigned long load_bzimage(int fd)
-{
-	struct boot_params boot;
-	int r;
-	/* Modern bzImages get loaded at 1M. */
-	void *p = from_guest_phys(0x100000);
-
-	/*
-	 * Go back to the start of the file and read the header.  It should be
-	 * a Linux boot header (see Documentation/x86/i386/boot.txt)
-	 */
-	lseek(fd, 0, SEEK_SET);
-	read(fd, &boot, sizeof(boot));
-
-	/* Inside the setup_hdr, we expect the magic "HdrS" */
-	if (memcmp(&boot.hdr.header, "HdrS", 4) != 0)
-		errx(1, "This doesn't look like a bzImage to me");
-
-	/* Skip over the extra sectors of the header. */
-	lseek(fd, (boot.hdr.setup_sects+1) * 512, SEEK_SET);
-
-	/* Now read everything into memory. in nice big chunks. */
-	while ((r = read(fd, p, 65536)) > 0)
-		p += r;
-
-	/* Finally, code32_start tells us where to enter the kernel. */
-	return boot.hdr.code32_start;
-}
-
-/*L:140
- * Loading the kernel is easy when it's a "vmlinux", but most kernels
- * come wrapped up in the self-decompressing "bzImage" format.  With a little
- * work, we can load those, too.
- */
-static unsigned long load_kernel(int fd)
-{
-	Elf32_Ehdr hdr;
-
-	/* Read in the first few bytes. */
-	if (read(fd, &hdr, sizeof(hdr)) != sizeof(hdr))
-		err(1, "Reading kernel");
-
-	/* If it's an ELF file, it starts with "\177ELF" */
-	if (memcmp(hdr.e_ident, ELFMAG, SELFMAG) == 0)
-		return map_elf(fd, &hdr);
-
-	/* Otherwise we assume it's a bzImage, and try to load it. */
-	return load_bzimage(fd);
-}
-
-/*
- * This is a trivial little helper to align pages.  Andi Kleen hated it because
- * it calls getpagesize() twice: "it's dumb code."
- *
- * Kernel guys get really het up about optimization, even when it's not
- * necessary.  I leave this code as a reaction against that.
- */
-static inline unsigned long page_align(unsigned long addr)
-{
-	/* Add upwards and truncate downwards. */
-	return ((addr + getpagesize()-1) & ~(getpagesize()-1));
-}
-
-/*L:180
- * An "initial ram disk" is a disk image loaded into memory along with the
- * kernel which the kernel can use to boot from without needing any drivers.
- * Most distributions now use this as standard: the initrd contains the code to
- * load the appropriate driver modules for the current machine.
- *
- * Importantly, James Morris works for RedHat, and Fedora uses initrds for its
- * kernels.  He sent me this (and tells me when I break it).
- */
-static unsigned long load_initrd(const char *name, unsigned long mem)
-{
-	int ifd;
-	struct stat st;
-	unsigned long len;
-
-	ifd = open_or_die(name, O_RDONLY);
-	/* fstat() is needed to get the file size. */
-	if (fstat(ifd, &st) < 0)
-		err(1, "fstat() on initrd '%s'", name);
-
-	/*
-	 * We map the initrd at the top of memory, but mmap wants it to be
-	 * page-aligned, so we round the size up for that.
-	 */
-	len = page_align(st.st_size);
-	map_at(ifd, from_guest_phys(mem - len), 0, st.st_size);
-	/*
-	 * Once a file is mapped, you can close the file descriptor.  It's a
-	 * little odd, but quite useful.
-	 */
-	close(ifd);
-	verbose("mapped initrd %s size=%lu @ %p\n", name, len, (void*)mem-len);
-
-	/* We return the initrd size. */
-	return len;
-}
-/*:*/
-
-/*
- * Simple routine to roll all the commandline arguments together with spaces
- * between them.
- */
-static void concat(char *dst, char *args[])
-{
-	unsigned int i, len = 0;
-
-	for (i = 0; args[i]; i++) {
-		if (i) {
-			strcat(dst+len, " ");
-			len++;
-		}
-		strcpy(dst+len, args[i]);
-		len += strlen(args[i]);
-	}
-	/* In case it's empty. */
-	dst[len] = '\0';
-}
-
-/*L:185
- * This is where we actually tell the kernel to initialize the Guest.  We
- * saw the arguments it expects when we looked at initialize() in lguest_user.c:
- * the base of Guest "physical" memory, the top physical page to allow and the
- * entry point for the Guest.
- */
-static void tell_kernel(unsigned long start)
-{
-	unsigned long args[] = { LHREQ_INITIALIZE,
-				 (unsigned long)guest_base,
-				 guest_limit / getpagesize(), start };
-	verbose("Guest: %p - %p (%#lx)\n",
-		guest_base, guest_base + guest_limit, guest_limit);
-	lguest_fd = open_or_die("/dev/lguest", O_RDWR);
-	if (write(lguest_fd, args, sizeof(args)) < 0)
-		err(1, "Writing to /dev/lguest");
-}
-/*:*/
-
-/*L:200
- * Device Handling.
- *
- * When the Guest gives us a buffer, it sends an array of addresses and sizes.
- * We need to make sure it's not trying to reach into the Launcher itself, so
- * we have a convenient routine which checks it and exits with an error message
- * if something funny is going on:
- */
-static void *_check_pointer(unsigned long addr, unsigned int size,
-			    unsigned int line)
-{
-	/*
-	 * Check if the requested address and size exceeds the allocated memory,
-	 * or addr + size wraps around.
-	 */
-	if ((addr + size) > guest_limit || (addr + size) < addr)
-		errx(1, "%s:%i: Invalid address %#lx", __FILE__, line, addr);
-	/*
-	 * We return a pointer for the caller's convenience, now we know it's
-	 * safe to use.
-	 */
-	return from_guest_phys(addr);
-}
-/* A macro which transparently hands the line number to the real function. */
-#define check_pointer(addr,size) _check_pointer(addr, size, __LINE__)
-
-/*
- * Each buffer in the virtqueues is actually a chain of descriptors.  This
- * function returns the next descriptor in the chain, or vq->vring.num if we're
- * at the end.
- */
-static unsigned next_desc(struct vring_desc *desc,
-			  unsigned int i, unsigned int max)
-{
-	unsigned int next;
-
-	/* If this descriptor says it doesn't chain, we're done. */
-	if (!(desc[i].flags & VRING_DESC_F_NEXT))
-		return max;
-
-	/* Check they're not leading us off end of descriptors. */
-	next = desc[i].next;
-	/* Make sure compiler knows to grab that: we don't want it changing! */
-	wmb();
-
-	if (next >= max)
-		errx(1, "Desc next is %u", next);
-
-	return next;
-}
-
-/*
- * This actually sends the interrupt for this virtqueue, if we've used a
- * buffer.
- */
-static void trigger_irq(struct virtqueue *vq)
-{
-	unsigned long buf[] = { LHREQ_IRQ, vq->config.irq };
-
-	/* Don't inform them if nothing used. */
-	if (!vq->pending_used)
-		return;
-	vq->pending_used = 0;
-
-	/* If they don't want an interrupt, don't send one... */
-	if (vq->vring.avail->flags & VRING_AVAIL_F_NO_INTERRUPT) {
-		/* ... unless they've asked us to force one on empty. */
-		if (!vq->dev->irq_on_empty
-		    || lg_last_avail(vq) != vq->vring.avail->idx)
-			return;
-	}
-
-	/* Send the Guest an interrupt tell them we used something up. */
-	if (write(lguest_fd, buf, sizeof(buf)) != 0)
-		err(1, "Triggering irq %i", vq->config.irq);
-}
-
-/*
- * This looks in the virtqueue 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 waits if necessary, and returns the descriptor number found.
- */
-static unsigned wait_for_vq_desc(struct virtqueue *vq,
-				 struct iovec iov[],
-				 unsigned int *out_num, unsigned int *in_num)
-{
-	unsigned int i, head, max;
-	struct vring_desc *desc;
-	u16 last_avail = lg_last_avail(vq);
-
-	/* There's nothing available? */
-	while (last_avail == vq->vring.avail->idx) {
-		u64 event;
-
-		/*
-		 * Since we're about to sleep, now is a good time to tell the
-		 * Guest about what we've used up to now.
-		 */
-		trigger_irq(vq);
-
-		/* OK, now we need to know about added descriptors. */
-		vq->vring.used->flags &= ~VRING_USED_F_NO_NOTIFY;
-
-		/*
-		 * They could have slipped one in as we were doing that: make
-		 * sure it's written, then check again.
-		 */
-		mb();
-		if (last_avail != vq->vring.avail->idx) {
-			vq->vring.used->flags |= VRING_USED_F_NO_NOTIFY;
-			break;
-		}
-
-		/* Nothing new?  Wait for eventfd to tell us they refilled. */
-		if (read(vq->eventfd, &event, sizeof(event)) != sizeof(event))
-			errx(1, "Event read failed?");
-
-		/* We don't need to be notified again. */
-		vq->vring.used->flags |= VRING_USED_F_NO_NOTIFY;
-	}
-
-	/* Check it isn't doing very strange things with descriptor numbers. */
-	if ((u16)(vq->vring.avail->idx - last_avail) > vq->vring.num)
-		errx(1, "Guest moved used index from %u to %u",
-		     last_avail, vq->vring.avail->idx);
-
-	/*
-	 * Grab the next descriptor number they're advertising, and increment
-	 * the index we've seen.
-	 */
-	head = vq->vring.avail->ring[last_avail % vq->vring.num];
-	lg_last_avail(vq)++;
-
-	/* If their number is silly, that's a fatal mistake. */
-	if (head >= vq->vring.num)
-		errx(1, "Guest says index %u is available", head);
-
-	/* When we start there are none of either input nor output. */
-	*out_num = *in_num = 0;
-
-	max = vq->vring.num;
-	desc = vq->vring.desc;
-	i = head;
-
-	/*
-	 * If this is an indirect entry, then this buffer contains a descriptor
-	 * table which we handle as if it's any normal descriptor chain.
-	 */
-	if (desc[i].flags & VRING_DESC_F_INDIRECT) {
-		if (desc[i].len % sizeof(struct vring_desc))
-			errx(1, "Invalid size for indirect buffer table");
-
-		max = desc[i].len / sizeof(struct vring_desc);
-		desc = check_pointer(desc[i].addr, desc[i].len);
-		i = 0;
-	}
-
-	do {
-		/* Grab the first descriptor, and check it's OK. */
-		iov[*out_num + *in_num].iov_len = desc[i].len;
-		iov[*out_num + *in_num].iov_base
-			= check_pointer(desc[i].addr, desc[i].len);
-		/* If this is an input descriptor, increment that count. */
-		if (desc[i].flags & VRING_DESC_F_WRITE)
-			(*in_num)++;
-		else {
-			/*
-			 * If it's an output descriptor, they're all supposed
-			 * to come before any input descriptors.
-			 */
-			if (*in_num)
-				errx(1, "Descriptor has out after in");
-			(*out_num)++;
-		}
-
-		/* If we've got too many, that implies a descriptor loop. */
-		if (*out_num + *in_num > max)
-			errx(1, "Looped descriptor");
-	} while ((i = next_desc(desc, i, max)) != max);
-
-	return head;
-}
-
-/*
- * After we've used one of their buffers, we tell the Guest about it.  Sometime
- * later we'll want to send them an interrupt using trigger_irq(); note that
- * wait_for_vq_desc() does that for us if it has to wait.
- */
-static void add_used(struct 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->vring.used->ring[vq->vring.used->idx % vq->vring.num];
-	used->id = head;
-	used->len = len;
-	/* Make sure buffer is written before we update index. */
-	wmb();
-	vq->vring.used->idx++;
-	vq->pending_used++;
-}
-
-/* And here's the combo meal deal.  Supersize me! */
-static void add_used_and_trigger(struct virtqueue *vq, unsigned head, int len)
-{
-	add_used(vq, head, len);
-	trigger_irq(vq);
-}
-
-/*
- * The Console
- *
- * We associate some data with the console for our exit hack.
- */
-struct console_abort {
-	/* How many times have they hit ^C? */
-	int count;
-	/* When did they start? */
-	struct timeval start;
-};
-
-/* This is the routine which handles console input (ie. stdin). */
-static void console_input(struct virtqueue *vq)
-{
-	int len;
-	unsigned int head, in_num, out_num;
-	struct console_abort *abort = vq->dev->priv;
-	struct iovec iov[vq->vring.num];
-
-	/* Make sure there's a descriptor available. */
-	head = wait_for_vq_desc(vq, iov, &out_num, &in_num);
-	if (out_num)
-		errx(1, "Output buffers in console in queue?");
-
-	/* Read into it.  This is where we usually wait. */
-	len = readv(STDIN_FILENO, iov, in_num);
-	if (len <= 0) {
-		/* Ran out of input? */
-		warnx("Failed to get console input, ignoring console.");
-		/*
-		 * For simplicity, dying threads kill the whole Launcher.  So
-		 * just nap here.
-		 */
-		for (;;)
-			pause();
-	}
-
-	/* Tell the Guest we used a buffer. */
-	add_used_and_trigger(vq, head, len);
-
-	/*
-	 * Three ^C within one second?  Exit.
-	 *
-	 * This is such a hack, but works surprisingly well.  Each ^C has to
-	 * be in a buffer by itself, so they can't be too fast.  But we check
-	 * that we get three within about a second, so they can't be too
-	 * slow.
-	 */
-	if (len != 1 || ((char *)iov[0].iov_base)[0] != 3) {
-		abort->count = 0;
-		return;
-	}
-
-	abort->count++;
-	if (abort->count == 1)
-		gettimeofday(&abort->start, NULL);
-	else if (abort->count == 3) {
-		struct timeval now;
-		gettimeofday(&now, NULL);
-		/* Kill all Launcher processes with SIGINT, like normal ^C */
-		if (now.tv_sec <= abort->start.tv_sec+1)
-			kill(0, SIGINT);
-		abort->count = 0;
-	}
-}
-
-/* This is the routine which handles console output (ie. stdout). */
-static void console_output(struct virtqueue *vq)
-{
-	unsigned int head, out, in;
-	struct iovec iov[vq->vring.num];
-
-	/* We usually wait in here, for the Guest to give us something. */
-	head = wait_for_vq_desc(vq, iov, &out, &in);
-	if (in)
-		errx(1, "Input buffers in console output queue?");
-
-	/* writev can return a partial write, so we loop here. */
-	while (!iov_empty(iov, out)) {
-		int len = writev(STDOUT_FILENO, iov, out);
-		if (len <= 0)
-			err(1, "Write to stdout gave %i", len);
-		iov_consume(iov, out, len);
-	}
-
-	/*
-	 * We're finished with that buffer: if we're going to sleep,
-	 * wait_for_vq_desc() will prod the Guest with an interrupt.
-	 */
-	add_used(vq, head, 0);
-}
-
-/*
- * The Network
- *
- * Handling output for network is also simple: we get all the output buffers
- * and write them to /dev/net/tun.
- */
-struct net_info {
-	int tunfd;
-};
-
-static void net_output(struct virtqueue *vq)
-{
-	struct net_info *net_info = vq->dev->priv;
-	unsigned int head, out, in;
-	struct iovec iov[vq->vring.num];
-
-	/* We usually wait in here for the Guest to give us a packet. */
-	head = wait_for_vq_desc(vq, iov, &out, &in);
-	if (in)
-		errx(1, "Input buffers in net output queue?");
-	/*
-	 * Send the whole thing through to /dev/net/tun.  It expects the exact
-	 * same format: what a coincidence!
-	 */
-	if (writev(net_info->tunfd, iov, out) < 0)
-		errx(1, "Write to tun failed?");
-
-	/*
-	 * Done with that one; wait_for_vq_desc() will send the interrupt if
-	 * all packets are processed.
-	 */
-	add_used(vq, head, 0);
-}
-
-/*
- * Handling network input is a bit trickier, because I've tried to optimize it.
- *
- * First we have a helper routine which tells is if from this file descriptor
- * (ie. the /dev/net/tun device) will block:
- */
-static bool will_block(int fd)
-{
-	fd_set fdset;
-	struct timeval zero = { 0, 0 };
-	FD_ZERO(&fdset);
-	FD_SET(fd, &fdset);
-	return select(fd+1, &fdset, NULL, NULL, &zero) != 1;
-}
-
-/*
- * This handles packets coming in from the tun device to our Guest.  Like all
- * service routines, it gets called again as soon as it returns, so you don't
- * see a while(1) loop here.
- */
-static void net_input(struct virtqueue *vq)
-{
-	int len;
-	unsigned int head, out, in;
-	struct iovec iov[vq->vring.num];
-	struct net_info *net_info = vq->dev->priv;
-
-	/*
-	 * Get a descriptor to write an incoming packet into.  This will also
-	 * send an interrupt if they're out of descriptors.
-	 */
-	head = wait_for_vq_desc(vq, iov, &out, &in);
-	if (out)
-		errx(1, "Output buffers in net input queue?");
-
-	/*
-	 * If it looks like we'll block reading from the tun device, send them
-	 * an interrupt.
-	 */
-	if (vq->pending_used && will_block(net_info->tunfd))
-		trigger_irq(vq);
-
-	/*
-	 * Read in the packet.  This is where we normally wait (when there's no
-	 * incoming network traffic).
-	 */
-	len = readv(net_info->tunfd, iov, in);
-	if (len <= 0)
-		err(1, "Failed to read from tun.");
-
-	/*
-	 * Mark that packet buffer as used, but don't interrupt here.  We want
-	 * to wait until we've done as much work as we can.
-	 */
-	add_used(vq, head, len);
-}
-/*:*/
-
-/* This is the helper to create threads: run the service routine in a loop. */
-static int do_thread(void *_vq)
-{
-	struct virtqueue *vq = _vq;
-
-	for (;;)
-		vq->service(vq);
-	return 0;
-}
-
-/*
- * When a child dies, we kill our entire process group with SIGTERM.  This
- * also has the side effect that the shell restores the console for us!
- */
-static void kill_launcher(int signal)
-{
-	kill(0, SIGTERM);
-}
-
-static void reset_device(struct device *dev)
-{
-	struct virtqueue *vq;
-
-	verbose("Resetting device %s\n", dev->name);
-
-	/* Clear any features they've acked. */
-	memset(get_feature_bits(dev) + dev->feature_len, 0, dev->feature_len);
-
-	/* We're going to be explicitly killing threads, so ignore them. */
-	signal(SIGCHLD, SIG_IGN);
-
-	/* Zero out the virtqueues, get rid of their threads */
-	for (vq = dev->vq; vq; vq = vq->next) {
-		if (vq->thread != (pid_t)-1) {
-			kill(vq->thread, SIGTERM);
-			waitpid(vq->thread, NULL, 0);
-			vq->thread = (pid_t)-1;
-		}
-		memset(vq->vring.desc, 0,
-		       vring_size(vq->config.num, LGUEST_VRING_ALIGN));
-		lg_last_avail(vq) = 0;
-	}
-	dev->running = false;
-
-	/* Now we care if threads die. */
-	signal(SIGCHLD, (void *)kill_launcher);
-}
-
-/*L:216
- * This actually creates the thread which services the virtqueue for a device.
- */
-static void create_thread(struct virtqueue *vq)
-{
-	/*
-	 * Create stack for thread.  Since the stack grows upwards, we point
-	 * the stack pointer to the end of this region.
-	 */
-	char *stack = malloc(32768);
-	unsigned long args[] = { LHREQ_EVENTFD,
-				 vq->config.pfn*getpagesize(), 0 };
-
-	/* Create a zero-initialized eventfd. */
-	vq->eventfd = eventfd(0, 0);
-	if (vq->eventfd < 0)
-		err(1, "Creating eventfd");
-	args[2] = vq->eventfd;
-
-	/*
-	 * Attach an eventfd to this virtqueue: it will go off when the Guest
-	 * does an LHCALL_NOTIFY for this vq.
-	 */
-	if (write(lguest_fd, &args, sizeof(args)) != 0)
-		err(1, "Attaching eventfd");
-
-	/*
-	 * CLONE_VM: because it has to access the Guest memory, and SIGCHLD so
-	 * we get a signal if it dies.
-	 */
-	vq->thread = clone(do_thread, stack + 32768, CLONE_VM | SIGCHLD, vq);
-	if (vq->thread == (pid_t)-1)
-		err(1, "Creating clone");
-
-	/* We close our local copy now the child has it. */
-	close(vq->eventfd);
-}
-
-static bool accepted_feature(struct device *dev, unsigned int bit)
-{
-	const u8 *features = get_feature_bits(dev) + dev->feature_len;
-
-	if (dev->feature_len < bit / CHAR_BIT)
-		return false;
-	return features[bit / CHAR_BIT] & (1 << (bit % CHAR_BIT));
-}
-
-static void start_device(struct device *dev)
-{
-	unsigned int i;
-	struct virtqueue *vq;
-
-	verbose("Device %s OK: offered", dev->name);
-	for (i = 0; i < dev->feature_len; i++)
-		verbose(" %02x", get_feature_bits(dev)[i]);
-	verbose(", accepted");
-	for (i = 0; i < dev->feature_len; i++)
-		verbose(" %02x", get_feature_bits(dev)
-			[dev->feature_len+i]);
-
-	dev->irq_on_empty = accepted_feature(dev, VIRTIO_F_NOTIFY_ON_EMPTY);
-
-	for (vq = dev->vq; vq; vq = vq->next) {
-		if (vq->service)
-			create_thread(vq);
-	}
-	dev->running = true;
-}
-
-static void cleanup_devices(void)
-{
-	struct device *dev;
-
-	for (dev = devices.dev; dev; dev = dev->next)
-		reset_device(dev);
-
-	/* If we saved off the original terminal settings, restore them now. */
-	if (orig_term.c_lflag & (ISIG|ICANON|ECHO))
-		tcsetattr(STDIN_FILENO, TCSANOW, &orig_term);
-}
-
-/* When the Guest tells us they updated the status field, we handle it. */
-static void update_device_status(struct device *dev)
-{
-	/* A zero status is a reset, otherwise it's a set of flags. */
-	if (dev->desc->status == 0)
-		reset_device(dev);
-	else if (dev->desc->status & VIRTIO_CONFIG_S_FAILED) {
-		warnx("Device %s configuration FAILED", dev->name);
-		if (dev->running)
-			reset_device(dev);
-	} else if (dev->desc->status & VIRTIO_CONFIG_S_DRIVER_OK) {
-		if (!dev->running)
-			start_device(dev);
-	}
-}
-
-/*L:215
- * This is the generic routine we call when the Guest uses LHCALL_NOTIFY.  In
- * particular, it's used to notify us of device status changes during boot.
- */
-static void handle_output(unsigned long addr)
-{
-	struct device *i;
-
-	/* Check each device. */
-	for (i = devices.dev; i; i = i->next) {
-		struct virtqueue *vq;
-
-		/*
-		 * Notifications to device descriptors mean they updated the
-		 * device status.
-		 */
-		if (from_guest_phys(addr) == i->desc) {
-			update_device_status(i);
-			return;
-		}
-
-		/*
-		 * Devices *can* be used before status is set to DRIVER_OK.
-		 * The original plan was that they would never do this: they
-		 * would always finish setting up their status bits before
-		 * actually touching the virtqueues.  In practice, we allowed
-		 * them to, and they do (eg. the disk probes for partition
-		 * tables as part of initialization).
-		 *
-		 * If we see this, we start the device: once it's running, we
-		 * expect the device to catch all the notifications.
-		 */
-		for (vq = i->vq; vq; vq = vq->next) {
-			if (addr != vq->config.pfn*getpagesize())
-				continue;
-			if (i->running)
-				errx(1, "Notification on running %s", i->name);
-			/* This just calls create_thread() for each virtqueue */
-			start_device(i);
-			return;
-		}
-	}
-
-	/*
-	 * Early console write is done using notify on a nul-terminated string
-	 * in Guest memory.  It's also great for hacking debugging messages
-	 * into a Guest.
-	 */
-	if (addr >= guest_limit)
-		errx(1, "Bad NOTIFY %#lx", addr);
-
-	write(STDOUT_FILENO, from_guest_phys(addr),
-	      strnlen(from_guest_phys(addr), guest_limit - addr));
-}
-
-/*L:190
- * Device Setup
- *
- * All devices need a descriptor so the Guest knows it exists, and a "struct
- * device" so the Launcher can keep track of it.  We have common helper
- * routines to allocate and manage them.
- */
-
-/*
- * The layout of the device page is a "struct lguest_device_desc" followed by a
- * number of virtqueue descriptors, then two sets of feature bits, then an
- * array of configuration bytes.  This routine returns the configuration
- * pointer.
- */
-static u8 *device_config(const struct device *dev)
-{
-	return (void *)(dev->desc + 1)
-		+ dev->num_vq * sizeof(struct lguest_vqconfig)
-		+ dev->feature_len * 2;
-}
-
-/*
- * This routine allocates a new "struct lguest_device_desc" from descriptor
- * table page just above the Guest's normal memory.  It returns a pointer to
- * that descriptor.
- */
-static struct lguest_device_desc *new_dev_desc(u16 type)
-{
-	struct lguest_device_desc d = { .type = type };
-	void *p;
-
-	/* Figure out where the next device config is, based on the last one. */
-	if (devices.lastdev)
-		p = device_config(devices.lastdev)
-			+ devices.lastdev->desc->config_len;
-	else
-		p = devices.descpage;
-
-	/* We only have one page for all the descriptors. */
-	if (p + sizeof(d) > (void *)devices.descpage + getpagesize())
-		errx(1, "Too many devices");
-
-	/* p might not be aligned, so we memcpy in. */
-	return memcpy(p, &d, sizeof(d));
-}
-
-/*
- * Each device descriptor is followed by the description of its virtqueues.  We
- * specify how many descriptors the virtqueue is to have.
- */
-static void add_virtqueue(struct device *dev, unsigned int num_descs,
-			  void (*service)(struct virtqueue *))
-{
-	unsigned int pages;
-	struct virtqueue **i, *vq = malloc(sizeof(*vq));
-	void *p;
-
-	/* First we need some memory for this virtqueue. */
-	pages = (vring_size(num_descs, LGUEST_VRING_ALIGN) + getpagesize() - 1)
-		/ getpagesize();
-	p = get_pages(pages);
-
-	/* Initialize the virtqueue */
-	vq->next = NULL;
-	vq->last_avail_idx = 0;
-	vq->dev = dev;
-
-	/*
-	 * This is the routine the service thread will run, and its Process ID
-	 * once it's running.
-	 */
-	vq->service = service;
-	vq->thread = (pid_t)-1;
-
-	/* Initialize the configuration. */
-	vq->config.num = num_descs;
-	vq->config.irq = devices.next_irq++;
-	vq->config.pfn = to_guest_phys(p) / getpagesize();
-
-	/* Initialize the vring. */
-	vring_init(&vq->vring, num_descs, p, LGUEST_VRING_ALIGN);
-
-	/*
-	 * Append virtqueue to this device's descriptor.  We use
-	 * device_config() to get the end of the device's current virtqueues;
-	 * we check that we haven't added any config or feature information
-	 * yet, otherwise we'd be overwriting them.
-	 */
-	assert(dev->desc->config_len == 0 && dev->desc->feature_len == 0);
-	memcpy(device_config(dev), &vq->config, sizeof(vq->config));
-	dev->num_vq++;
-	dev->desc->num_vq++;
-
-	verbose("Virtqueue page %#lx\n", to_guest_phys(p));
-
-	/*
-	 * Add to tail of list, so dev->vq is first vq, dev->vq->next is
-	 * second.
-	 */
-	for (i = &dev->vq; *i; i = &(*i)->next);
-	*i = vq;
-}
-
-/*
- * The first half of the feature bitmask is for us to advertise features.  The
- * second half is for the Guest to accept features.
- */
-static void add_feature(struct device *dev, unsigned bit)
-{
-	u8 *features = get_feature_bits(dev);
-
-	/* We can't extend the feature bits once we've added config bytes */
-	if (dev->desc->feature_len <= bit / CHAR_BIT) {
-		assert(dev->desc->config_len == 0);
-		dev->feature_len = dev->desc->feature_len = (bit/CHAR_BIT) + 1;
-	}
-
-	features[bit / CHAR_BIT] |= (1 << (bit % CHAR_BIT));
-}
-
-/*
- * This routine sets the configuration fields for an existing device's
- * descriptor.  It only works for the last device, but that's OK because that's
- * how we use it.
- */
-static void set_config(struct device *dev, unsigned len, const void *conf)
-{
-	/* Check we haven't overflowed our single page. */
-	if (device_config(dev) + len > devices.descpage + getpagesize())
-		errx(1, "Too many devices");
-
-	/* Copy in the config information, and store the length. */
-	memcpy(device_config(dev), conf, len);
-	dev->desc->config_len = len;
-
-	/* Size must fit in config_len field (8 bits)! */
-	assert(dev->desc->config_len == len);
-}
-
-/*
- * This routine does all the creation and setup of a new device, including
- * calling new_dev_desc() to allocate the descriptor and device memory.  We
- * don't actually start the service threads until later.
- *
- * See what I mean about userspace being boring?
- */
-static struct device *new_device(const char *name, u16 type)
-{
-	struct device *dev = malloc(sizeof(*dev));
-
-	/* Now we populate the fields one at a time. */
-	dev->desc = new_dev_desc(type);
-	dev->name = name;
-	dev->vq = NULL;
-	dev->feature_len = 0;
-	dev->num_vq = 0;
-	dev->running = false;
-
-	/*
-	 * Append to device list.  Prepending to a single-linked list is
-	 * easier, but the user expects the devices to be arranged on the bus
-	 * in command-line order.  The first network device on the command line
-	 * is eth0, the first block device /dev/vda, etc.
-	 */
-	if (devices.lastdev)
-		devices.lastdev->next = dev;
-	else
-		devices.dev = dev;
-	devices.lastdev = dev;
-
-	return dev;
-}
-
-/*
- * Our first setup routine is the console.  It's a fairly simple device, but
- * UNIX tty handling makes it uglier than it could be.
- */
-static void setup_console(void)
-{
-	struct device *dev;
-
-	/* If we can save the initial standard input settings... */
-	if (tcgetattr(STDIN_FILENO, &orig_term) == 0) {
-		struct termios term = orig_term;
-		/*
-		 * Then we turn off echo, line buffering and ^C etc: We want a
-		 * raw input stream to the Guest.
-		 */
-		term.c_lflag &= ~(ISIG|ICANON|ECHO);
-		tcsetattr(STDIN_FILENO, TCSANOW, &term);
-	}
-
-	dev = new_device("console", VIRTIO_ID_CONSOLE);
-
-	/* We store the console state in dev->priv, and initialize it. */
-	dev->priv = malloc(sizeof(struct console_abort));
-	((struct console_abort *)dev->priv)->count = 0;
-
-	/*
-	 * The console needs two virtqueues: the input then the output.  When
-	 * they put something the input queue, we make sure we're listening to
-	 * stdin.  When they put something in the output queue, we write it to
-	 * stdout.
-	 */
-	add_virtqueue(dev, VIRTQUEUE_NUM, console_input);
-	add_virtqueue(dev, VIRTQUEUE_NUM, console_output);
-
-	verbose("device %u: console\n", ++devices.device_num);
-}
-/*:*/
-
-/*M:010
- * Inter-guest networking is an interesting area.  Simplest is to have a
- * --sharenet=<name> option which opens or creates a named pipe.  This can be
- * used to send packets to another guest in a 1:1 manner.
- *
- * More sopisticated is to use one of the tools developed for project like UML
- * to do networking.
- *
- * Faster is to do virtio bonding in kernel.  Doing this 1:1 would be
- * completely generic ("here's my vring, attach to your vring") and would work
- * for any traffic.  Of course, namespace and permissions issues need to be
- * dealt with.  A more sophisticated "multi-channel" virtio_net.c could hide
- * multiple inter-guest channels behind one interface, although it would
- * require some manner of hotplugging new virtio channels.
- *
- * Finally, we could implement a virtio network switch in the kernel.
-:*/
-
-static u32 str2ip(const char *ipaddr)
-{
-	unsigned int b[4];
-
-	if (sscanf(ipaddr, "%u.%u.%u.%u", &b[0], &b[1], &b[2], &b[3]) != 4)
-		errx(1, "Failed to parse IP address '%s'", ipaddr);
-	return (b[0] << 24) | (b[1] << 16) | (b[2] << 8) | b[3];
-}
-
-static void str2mac(const char *macaddr, unsigned char mac[6])
-{
-	unsigned int m[6];
-	if (sscanf(macaddr, "%02x:%02x:%02x:%02x:%02x:%02x",
-		   &m[0], &m[1], &m[2], &m[3], &m[4], &m[5]) != 6)
-		errx(1, "Failed to parse mac address '%s'", macaddr);
-	mac[0] = m[0];
-	mac[1] = m[1];
-	mac[2] = m[2];
-	mac[3] = m[3];
-	mac[4] = m[4];
-	mac[5] = m[5];
-}
-
-/*
- * This code is "adapted" from libbridge: it attaches the Host end of the
- * network device to the bridge device specified by the command line.
- *
- * This is yet another James Morris contribution (I'm an IP-level guy, so I
- * dislike bridging), and I just try not to break it.
- */
-static void add_to_bridge(int fd, const char *if_name, const char *br_name)
-{
-	int ifidx;
-	struct ifreq ifr;
-
-	if (!*br_name)
-		errx(1, "must specify bridge name");
-
-	ifidx = if_nametoindex(if_name);
-	if (!ifidx)
-		errx(1, "interface %s does not exist!", if_name);
-
-	strncpy(ifr.ifr_name, br_name, IFNAMSIZ);
-	ifr.ifr_name[IFNAMSIZ-1] = '\0';
-	ifr.ifr_ifindex = ifidx;
-	if (ioctl(fd, SIOCBRADDIF, &ifr) < 0)
-		err(1, "can't add %s to bridge %s", if_name, br_name);
-}
-
-/*
- * This sets up the Host end of the network device with an IP address, brings
- * it up so packets will flow, the copies the MAC address into the hwaddr
- * pointer.
- */
-static void configure_device(int fd, const char *tapif, u32 ipaddr)
-{
-	struct ifreq ifr;
-	struct sockaddr_in sin;
-
-	memset(&ifr, 0, sizeof(ifr));
-	strcpy(ifr.ifr_name, tapif);
-
-	/* Don't read these incantations.  Just cut & paste them like I did! */
-	sin.sin_family = AF_INET;
-	sin.sin_addr.s_addr = htonl(ipaddr);
-	memcpy(&ifr.ifr_addr, &sin, sizeof(sin));
-	if (ioctl(fd, SIOCSIFADDR, &ifr) != 0)
-		err(1, "Setting %s interface address", tapif);
-	ifr.ifr_flags = IFF_UP;
-	if (ioctl(fd, SIOCSIFFLAGS, &ifr) != 0)
-		err(1, "Bringing interface %s up", tapif);
-}
-
-static int get_tun_device(char tapif[IFNAMSIZ])
-{
-	struct ifreq ifr;
-	int netfd;
-
-	/* Start with this zeroed.  Messy but sure. */
-	memset(&ifr, 0, sizeof(ifr));
-
-	/*
-	 * We open the /dev/net/tun device and tell it we want a tap device.  A
-	 * tap device is like a tun device, only somehow different.  To tell
-	 * the truth, I completely blundered my way through this code, but it
-	 * works now!
-	 */
-	netfd = open_or_die("/dev/net/tun", O_RDWR);
-	ifr.ifr_flags = IFF_TAP | IFF_NO_PI | IFF_VNET_HDR;
-	strcpy(ifr.ifr_name, "tap%d");
-	if (ioctl(netfd, TUNSETIFF, &ifr) != 0)
-		err(1, "configuring /dev/net/tun");
-
-	if (ioctl(netfd, TUNSETOFFLOAD,
-		  TUN_F_CSUM|TUN_F_TSO4|TUN_F_TSO6|TUN_F_TSO_ECN) != 0)
-		err(1, "Could not set features for tun device");
-
-	/*
-	 * We don't need checksums calculated for packets coming in this
-	 * device: trust us!
-	 */
-	ioctl(netfd, TUNSETNOCSUM, 1);
-
-	memcpy(tapif, ifr.ifr_name, IFNAMSIZ);
-	return netfd;
-}
-
-/*L:195
- * Our network is a Host<->Guest network.  This can either use bridging or
- * routing, but the principle is the same: it uses the "tun" device to inject
- * packets into the Host as if they came in from a normal network card.  We
- * just shunt packets between the Guest and the tun device.
- */
-static void setup_tun_net(char *arg)
-{
-	struct device *dev;
-	struct net_info *net_info = malloc(sizeof(*net_info));
-	int ipfd;
-	u32 ip = INADDR_ANY;
-	bool bridging = false;
-	char tapif[IFNAMSIZ], *p;
-	struct virtio_net_config conf;
-
-	net_info->tunfd = get_tun_device(tapif);
-
-	/* First we create a new network device. */
-	dev = new_device("net", VIRTIO_ID_NET);
-	dev->priv = net_info;
-
-	/* Network devices need a recv and a send queue, just like console. */
-	add_virtqueue(dev, VIRTQUEUE_NUM, net_input);
-	add_virtqueue(dev, VIRTQUEUE_NUM, net_output);
-
-	/*
-	 * We need a socket to perform the magic network ioctls to bring up the
-	 * tap interface, connect to the bridge etc.  Any socket will do!
-	 */
-	ipfd = socket(PF_INET, SOCK_DGRAM, IPPROTO_IP);
-	if (ipfd < 0)
-		err(1, "opening IP socket");
-
-	/* If the command line was --tunnet=bridge:<name> do bridging. */
-	if (!strncmp(BRIDGE_PFX, arg, strlen(BRIDGE_PFX))) {
-		arg += strlen(BRIDGE_PFX);
-		bridging = true;
-	}
-
-	/* A mac address may follow the bridge name or IP address */
-	p = strchr(arg, ':');
-	if (p) {
-		str2mac(p+1, conf.mac);
-		add_feature(dev, VIRTIO_NET_F_MAC);
-		*p = '\0';
-	}
-
-	/* arg is now either an IP address or a bridge name */
-	if (bridging)
-		add_to_bridge(ipfd, tapif, arg);
-	else
-		ip = str2ip(arg);
-
-	/* Set up the tun device. */
-	configure_device(ipfd, tapif, ip);
-
-	add_feature(dev, VIRTIO_F_NOTIFY_ON_EMPTY);
-	/* Expect Guest to handle everything except UFO */
-	add_feature(dev, VIRTIO_NET_F_CSUM);
-	add_feature(dev, VIRTIO_NET_F_GUEST_CSUM);
-	add_feature(dev, VIRTIO_NET_F_GUEST_TSO4);
-	add_feature(dev, VIRTIO_NET_F_GUEST_TSO6);
-	add_feature(dev, VIRTIO_NET_F_GUEST_ECN);
-	add_feature(dev, VIRTIO_NET_F_HOST_TSO4);
-	add_feature(dev, VIRTIO_NET_F_HOST_TSO6);
-	add_feature(dev, VIRTIO_NET_F_HOST_ECN);
-	/* We handle indirect ring entries */
-	add_feature(dev, VIRTIO_RING_F_INDIRECT_DESC);
-	set_config(dev, sizeof(conf), &conf);
-
-	/* We don't need the socket any more; setup is done. */
-	close(ipfd);
-
-	devices.device_num++;
-
-	if (bridging)
-		verbose("device %u: tun %s attached to bridge: %s\n",
-			devices.device_num, tapif, arg);
-	else
-		verbose("device %u: tun %s: %s\n",
-			devices.device_num, tapif, arg);
-}
-/*:*/
-
-/* This hangs off device->priv. */
-struct vblk_info {
-	/* The size of the file. */
-	off64_t len;
-
-	/* The file descriptor for the file. */
-	int fd;
-
-};
-
-/*L:210
- * The Disk
- *
- * The disk only has one virtqueue, so it only has one thread.  It is really
- * simple: the Guest asks for a block number and we read or write that position
- * in the file.
- *
- * Before we serviced each virtqueue in a separate thread, that was unacceptably
- * slow: the Guest waits until the read is finished before running anything
- * else, even if it could have been doing useful work.
- *
- * We could have used async I/O, except it's reputed to suck so hard that
- * characters actually go missing from your code when you try to use it.
- */
-static void blk_request(struct virtqueue *vq)
-{
-	struct vblk_info *vblk = vq->dev->priv;
-	unsigned int head, out_num, in_num, wlen;
-	int ret;
-	u8 *in;
-	struct virtio_blk_outhdr *out;
-	struct iovec iov[vq->vring.num];
-	off64_t off;
-
-	/*
-	 * Get the next request, where we normally wait.  It triggers the
-	 * interrupt to acknowledge previously serviced requests (if any).
-	 */
-	head = wait_for_vq_desc(vq, iov, &out_num, &in_num);
-
-	/*
-	 * Every block request should contain at least one output buffer
-	 * (detailing the location on disk and the type of request) and one
-	 * input buffer (to hold the result).
-	 */
-	if (out_num == 0 || in_num == 0)
-		errx(1, "Bad virtblk cmd %u out=%u in=%u",
-		     head, out_num, in_num);
-
-	out = convert(&iov[0], struct virtio_blk_outhdr);
-	in = convert(&iov[out_num+in_num-1], u8);
-	/*
-	 * For historical reasons, block operations are expressed in 512 byte
-	 * "sectors".
-	 */
-	off = out->sector * 512;
-
-	/*
-	 * In general the virtio block driver is allowed to try SCSI commands.
-	 * It'd be nice if we supported eject, for example, but we don't.
-	 */
-	if (out->type & VIRTIO_BLK_T_SCSI_CMD) {
-		fprintf(stderr, "Scsi commands unsupported\n");
-		*in = VIRTIO_BLK_S_UNSUPP;
-		wlen = sizeof(*in);
-	} else if (out->type & VIRTIO_BLK_T_OUT) {
-		/*
-		 * Write
-		 *
-		 * Move to the right location in the block file.  This can fail
-		 * if they try to write past end.
-		 */
-		if (lseek64(vblk->fd, off, SEEK_SET) != off)
-			err(1, "Bad seek to sector %llu", out->sector);
-
-		ret = writev(vblk->fd, iov+1, out_num-1);
-		verbose("WRITE to sector %llu: %i\n", out->sector, ret);
-
-		/*
-		 * Grr... Now we know how long the descriptor they sent was, we
-		 * make sure they didn't try to write over the end of the block
-		 * file (possibly extending it).
-		 */
-		if (ret > 0 && off + ret > vblk->len) {
-			/* Trim it back to the correct length */
-			ftruncate64(vblk->fd, vblk->len);
-			/* Die, bad Guest, die. */
-			errx(1, "Write past end %llu+%u", off, ret);
-		}
-
-		wlen = sizeof(*in);
-		*in = (ret >= 0 ? VIRTIO_BLK_S_OK : VIRTIO_BLK_S_IOERR);
-	} else if (out->type & VIRTIO_BLK_T_FLUSH) {
-		/* Flush */
-		ret = fdatasync(vblk->fd);
-		verbose("FLUSH fdatasync: %i\n", ret);
-		wlen = sizeof(*in);
-		*in = (ret >= 0 ? VIRTIO_BLK_S_OK : VIRTIO_BLK_S_IOERR);
-	} else {
-		/*
-		 * Read
-		 *
-		 * Move to the right location in the block file.  This can fail
-		 * if they try to read past end.
-		 */
-		if (lseek64(vblk->fd, off, SEEK_SET) != off)
-			err(1, "Bad seek to sector %llu", out->sector);
-
-		ret = readv(vblk->fd, iov+1, in_num-1);
-		verbose("READ from sector %llu: %i\n", out->sector, ret);
-		if (ret >= 0) {
-			wlen = sizeof(*in) + ret;
-			*in = VIRTIO_BLK_S_OK;
-		} else {
-			wlen = sizeof(*in);
-			*in = VIRTIO_BLK_S_IOERR;
-		}
-	}
-
-	/* Finished that request. */
-	add_used(vq, head, wlen);
-}
-
-/*L:198 This actually sets up a virtual block device. */
-static void setup_block_file(const char *filename)
-{
-	struct device *dev;
-	struct vblk_info *vblk;
-	struct virtio_blk_config conf;
-
-	/* Creat the device. */
-	dev = new_device("block", VIRTIO_ID_BLOCK);
-
-	/* The device has one virtqueue, where the Guest places requests. */
-	add_virtqueue(dev, VIRTQUEUE_NUM, blk_request);
-
-	/* Allocate the room for our own bookkeeping */
-	vblk = dev->priv = malloc(sizeof(*vblk));
-
-	/* First we open the file and store the length. */
-	vblk->fd = open_or_die(filename, O_RDWR|O_LARGEFILE);
-	vblk->len = lseek64(vblk->fd, 0, SEEK_END);
-
-	/* We support FLUSH. */
-	add_feature(dev, VIRTIO_BLK_F_FLUSH);
-
-	/* Tell Guest how many sectors this device has. */
-	conf.capacity = cpu_to_le64(vblk->len / 512);
-
-	/*
-	 * Tell Guest not to put in too many descriptors at once: two are used
-	 * for the in and out elements.
-	 */
-	add_feature(dev, VIRTIO_BLK_F_SEG_MAX);
-	conf.seg_max = cpu_to_le32(VIRTQUEUE_NUM - 2);
-
-	/* Don't try to put whole struct: we have 8 bit limit. */
-	set_config(dev, offsetof(struct virtio_blk_config, geometry), &conf);
-
-	verbose("device %u: virtblock %llu sectors\n",
-		++devices.device_num, le64_to_cpu(conf.capacity));
-}
-
-/*L:211
- * Our random number generator device reads from /dev/random into the Guest's
- * input buffers.  The usual case is that the Guest doesn't want random numbers
- * and so has no buffers although /dev/random is still readable, whereas
- * console is the reverse.
- *
- * The same logic applies, however.
- */
-struct rng_info {
-	int rfd;
-};
-
-static void rng_input(struct virtqueue *vq)
-{
-	int len;
-	unsigned int head, in_num, out_num, totlen = 0;
-	struct rng_info *rng_info = vq->dev->priv;
-	struct iovec iov[vq->vring.num];
-
-	/* First we need a buffer from the Guests's virtqueue. */
-	head = wait_for_vq_desc(vq, iov, &out_num, &in_num);
-	if (out_num)
-		errx(1, "Output buffers in rng?");
-
-	/*
-	 * Just like the console write, we loop to cover the whole iovec.
-	 * In this case, short reads actually happen quite a bit.
-	 */
-	while (!iov_empty(iov, in_num)) {
-		len = readv(rng_info->rfd, iov, in_num);
-		if (len <= 0)
-			err(1, "Read from /dev/random gave %i", len);
-		iov_consume(iov, in_num, len);
-		totlen += len;
-	}
-
-	/* Tell the Guest about the new input. */
-	add_used(vq, head, totlen);
-}
-
-/*L:199
- * This creates a "hardware" random number device for the Guest.
- */
-static void setup_rng(void)
-{
-	struct device *dev;
-	struct rng_info *rng_info = malloc(sizeof(*rng_info));
-
-	/* Our device's privat info simply contains the /dev/random fd. */
-	rng_info->rfd = open_or_die("/dev/random", O_RDONLY);
-
-	/* Create the new device. */
-	dev = new_device("rng", VIRTIO_ID_RNG);
-	dev->priv = rng_info;
-
-	/* The device has one virtqueue, where the Guest places inbufs. */
-	add_virtqueue(dev, VIRTQUEUE_NUM, rng_input);
-
-	verbose("device %u: rng\n", devices.device_num++);
-}
-/* That's the end of device setup. */
-
-/*L:230 Reboot is pretty easy: clean up and exec() the Launcher afresh. */
-static void __attribute__((noreturn)) restart_guest(void)
-{
-	unsigned int i;
-
-	/*
-	 * Since we don't track all open fds, we simply close everything beyond
-	 * stderr.
-	 */
-	for (i = 3; i < FD_SETSIZE; i++)
-		close(i);
-
-	/* Reset all the devices (kills all threads). */
-	cleanup_devices();
-
-	execv(main_args[0], main_args);
-	err(1, "Could not exec %s", main_args[0]);
-}
-
-/*L:220
- * Finally we reach the core of the Launcher which runs the Guest, serves
- * its input and output, and finally, lays it to rest.
- */
-static void __attribute__((noreturn)) run_guest(void)
-{
-	for (;;) {
-		unsigned long notify_addr;
-		int readval;
-
-		/* We read from the /dev/lguest device to run the Guest. */
-		readval = pread(lguest_fd, &notify_addr,
-				sizeof(notify_addr), cpu_id);
-
-		/* One unsigned long means the Guest did HCALL_NOTIFY */
-		if (readval == sizeof(notify_addr)) {
-			verbose("Notify on address %#lx\n", notify_addr);
-			handle_output(notify_addr);
-		/* ENOENT means the Guest died.  Reading tells us why. */
-		} else if (errno == ENOENT) {
-			char reason[1024] = { 0 };
-			pread(lguest_fd, reason, sizeof(reason)-1, cpu_id);
-			errx(1, "%s", reason);
-		/* ERESTART means that we need to reboot the guest */
-		} else if (errno == ERESTART) {
-			restart_guest();
-		/* Anything else means a bug or incompatible change. */
-		} else
-			err(1, "Running guest failed");
-	}
-}
-/*L:240
- * This is the end of the Launcher.  The good news: we are over halfway
- * through!  The bad news: the most fiendish part of the code still lies ahead
- * of us.
- *
- * Are you ready?  Take a deep breath and join me in the core of the Host, in
- * "make Host".
-:*/
-
-static struct option opts[] = {
-	{ "verbose", 0, NULL, 'v' },
-	{ "tunnet", 1, NULL, 't' },
-	{ "block", 1, NULL, 'b' },
-	{ "rng", 0, NULL, 'r' },
-	{ "initrd", 1, NULL, 'i' },
-	{ "username", 1, NULL, 'u' },
-	{ "chroot", 1, NULL, 'c' },
-	{ NULL },
-};
-static void usage(void)
-{
-	errx(1, "Usage: lguest [--verbose] "
-	     "[--tunnet=(<ipaddr>:<macaddr>|bridge:<bridgename>:<macaddr>)\n"
-	     "|--block=<filename>|--initrd=<filename>]...\n"
-	     "<mem-in-mb> vmlinux [args...]");
-}
-
-/*L:105 The main routine is where the real work begins: */
-int main(int argc, char *argv[])
-{
-	/* Memory, code startpoint and size of the (optional) initrd. */
-	unsigned long mem = 0, start, initrd_size = 0;
-	/* Two temporaries. */
-	int i, c;
-	/* The boot information for the Guest. */
-	struct boot_params *boot;
-	/* If they specify an initrd file to load. */
-	const char *initrd_name = NULL;
-
-	/* Password structure for initgroups/setres[gu]id */
-	struct passwd *user_details = NULL;
-
-	/* Directory to chroot to */
-	char *chroot_path = NULL;
-
-	/* Save the args: we "reboot" by execing ourselves again. */
-	main_args = argv;
-
-	/*
-	 * First we initialize the device list.  We keep a pointer to the last
-	 * device, and the next interrupt number to use for devices (1:
-	 * remember that 0 is used by the timer).
-	 */
-	devices.lastdev = NULL;
-	devices.next_irq = 1;
-
-	/* We're CPU 0.  In fact, that's the only CPU possible right now. */
-	cpu_id = 0;
-
-	/*
-	 * We need to know how much memory so we can set up the device
-	 * descriptor and memory pages for the devices as we parse the command
-	 * line.  So we quickly look through the arguments to find the amount
-	 * of memory now.
-	 */
-	for (i = 1; i < argc; i++) {
-		if (argv[i][0] != '-') {
-			mem = atoi(argv[i]) * 1024 * 1024;
-			/*
-			 * We start by mapping anonymous pages over all of
-			 * guest-physical memory range.  This fills it with 0,
-			 * and ensures that the Guest won't be killed when it
-			 * tries to access it.
-			 */
-			guest_base = map_zeroed_pages(mem / getpagesize()
-						      + DEVICE_PAGES);
-			guest_limit = mem;
-			guest_max = mem + DEVICE_PAGES*getpagesize();
-			devices.descpage = get_pages(1);
-			break;
-		}
-	}
-
-	/* The options are fairly straight-forward */
-	while ((c = getopt_long(argc, argv, "v", opts, NULL)) != EOF) {
-		switch (c) {
-		case 'v':
-			verbose = true;
-			break;
-		case 't':
-			setup_tun_net(optarg);
-			break;
-		case 'b':
-			setup_block_file(optarg);
-			break;
-		case 'r':
-			setup_rng();
-			break;
-		case 'i':
-			initrd_name = optarg;
-			break;
-		case 'u':
-			user_details = getpwnam(optarg);
-			if (!user_details)
-				err(1, "getpwnam failed, incorrect username?");
-			break;
-		case 'c':
-			chroot_path = optarg;
-			break;
-		default:
-			warnx("Unknown argument %s", argv[optind]);
-			usage();
-		}
-	}
-	/*
-	 * After the other arguments we expect memory and kernel image name,
-	 * followed by command line arguments for the kernel.
-	 */
-	if (optind + 2 > argc)
-		usage();
-
-	verbose("Guest base is at %p\n", guest_base);
-
-	/* We always have a console device */
-	setup_console();
-
-	/* Now we load the kernel */
-	start = load_kernel(open_or_die(argv[optind+1], O_RDONLY));
-
-	/* Boot information is stashed at physical address 0 */
-	boot = from_guest_phys(0);
-
-	/* Map the initrd image if requested (at top of physical memory) */
-	if (initrd_name) {
-		initrd_size = load_initrd(initrd_name, mem);
-		/*
-		 * These are the location in the Linux boot header where the
-		 * start and size of the initrd are expected to be found.
-		 */
-		boot->hdr.ramdisk_image = mem - initrd_size;
-		boot->hdr.ramdisk_size = initrd_size;
-		/* The bootloader type 0xFF means "unknown"; that's OK. */
-		boot->hdr.type_of_loader = 0xFF;
-	}
-
-	/*
-	 * The Linux boot header contains an "E820" memory map: ours is a
-	 * simple, single region.
-	 */
-	boot->e820_entries = 1;
-	boot->e820_map[0] = ((struct e820entry) { 0, mem, E820_RAM });
-	/*
-	 * The boot header contains a command line pointer: we put the command
-	 * line after the boot header.
-	 */
-	boot->hdr.cmd_line_ptr = to_guest_phys(boot + 1);
-	/* We use a simple helper to copy the arguments separated by spaces. */
-	concat((char *)(boot + 1), argv+optind+2);
-
-	/* Boot protocol version: 2.07 supports the fields for lguest. */
-	boot->hdr.version = 0x207;
-
-	/* The hardware_subarch value of "1" tells the Guest it's an lguest. */
-	boot->hdr.hardware_subarch = 1;
-
-	/* Tell the entry path not to try to reload segment registers. */
-	boot->hdr.loadflags |= KEEP_SEGMENTS;
-
-	/*
-	 * We tell the kernel to initialize the Guest: this returns the open
-	 * /dev/lguest file descriptor.
-	 */
-	tell_kernel(start);
-
-	/* Ensure that we terminate if a device-servicing child dies. */
-	signal(SIGCHLD, kill_launcher);
-
-	/* If we exit via err(), this kills all the threads, restores tty. */
-	atexit(cleanup_devices);
-
-	/* If requested, chroot to a directory */
-	if (chroot_path) {
-		if (chroot(chroot_path) != 0)
-			err(1, "chroot(\"%s\") failed", chroot_path);
-
-		if (chdir("/") != 0)
-			err(1, "chdir(\"/\") failed");
-
-		verbose("chroot done\n");
-	}
-
-	/* If requested, drop privileges */
-	if (user_details) {
-		uid_t u;
-		gid_t g;
-
-		u = user_details->pw_uid;
-		g = user_details->pw_gid;
-
-		if (initgroups(user_details->pw_name, g) != 0)
-			err(1, "initgroups failed");
-
-		if (setresgid(g, g, g) != 0)
-			err(1, "setresgid failed");
-
-		if (setresuid(u, u, u) != 0)
-			err(1, "setresuid failed");
-
-		verbose("Dropping privileges completed\n");
-	}
-
-	/* Finally, run the Guest.  This doesn't return. */
-	run_guest();
-}
-/*:*/
-
-/*M:999
- * Mastery is done: you now know everything I do.
- *
- * But surely you have seen code, features and bugs in your wanderings which
- * you now yearn to attack?  That is the real game, and I look forward to you
- * patching and forking lguest into the Your-Name-Here-visor.
- *
- * Farewell, and good coding!
- * Rusty Russell.
- */
diff -druN linux-2.6.39-libre/Documentation/lguest/lguest.txt linux-3.0-rc7-libre/Documentation/lguest/lguest.txt
--- linux-2.6.39-libre/Documentation/lguest/lguest.txt	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/Documentation/lguest/lguest.txt	1969-12-31 19:00:00.000000000 -0500
@@ -1,128 +0,0 @@
-      __
- (___()'`;  Rusty's Remarkably Unreliable Guide to Lguest
- /,    /`      - or, A Young Coder's Illustrated Hypervisor
- \\"--\\    http://lguest.ozlabs.org
-
-Lguest is designed to be a minimal 32-bit x86 hypervisor for the Linux kernel,
-for Linux developers and users to experiment with virtualization with the
-minimum of complexity.  Nonetheless, it should have sufficient features to
-make it useful for specific tasks, and, of course, you are encouraged to fork
-and enhance it (see drivers/lguest/README).
-
-Features:
-
-- Kernel module which runs in a normal kernel.
-- Simple I/O model for communication.
-- Simple program to create new guests.
-- Logo contains cute puppies: http://lguest.ozlabs.org
-
-Developer features:
-
-- Fun to hack on.
-- No ABI: being tied to a specific kernel anyway, you can change anything.
-- Many opportunities for improvement or feature implementation.
-
-Running Lguest:
-
-- The easiest way to run lguest is to use same kernel as guest and host.
-  You can configure them differently, but usually it's easiest not to.
-
-  You will need to configure your kernel with the following options:
-
-  "General setup":
-     "Prompt for development and/or incomplete code/drivers" = Y
-        (CONFIG_EXPERIMENTAL=y)
-
-  "Processor type and features":
-     "Paravirtualized guest support" = Y
-        "Lguest guest support" = Y
-     "High Memory Support" = off/4GB
-     "Alignment value to which kernel should be aligned" = 0x100000
-        (CONFIG_PARAVIRT=y, CONFIG_LGUEST_GUEST=y, CONFIG_HIGHMEM64G=n and
-         CONFIG_PHYSICAL_ALIGN=0x100000)
-
-  "Device Drivers":
-     "Block devices"
-        "Virtio block driver (EXPERIMENTAL)" = M/Y
-     "Network device support"
-        "Universal TUN/TAP device driver support" = M/Y
-        "Virtio network driver (EXPERIMENTAL)" = M/Y
-           (CONFIG_VIRTIO_BLK=m, CONFIG_VIRTIO_NET=m and CONFIG_TUN=m)
-
-  "Virtualization"
-     "Linux hypervisor example code" = M/Y
-        (CONFIG_LGUEST=m)
-
-- A tool called "lguest" is available in this directory: type "make"
-  to build it.  If you didn't build your kernel in-tree, use "make
-  O=<builddir>".
-
-- Create or find a root disk image.  There are several useful ones
-  around, such as the xm-test tiny root image at
-	  http://xm-test.xensource.com/ramdisks/initrd-1.1-i386.img
-
-  For more serious work, I usually use a distribution ISO image and
-  install it under qemu, then make multiple copies:
-
-	  dd if=/dev/zero of=rootfile bs=1M count=2048
-	  qemu -cdrom image.iso -hda rootfile -net user -net nic -boot d
-
-  Make sure that you install a getty on /dev/hvc0 if you want to log in on the
-  console!
-
-- "modprobe lg" if you built it as a module.
-
-- Run an lguest as root:
-
-      Documentation/lguest/lguest 64 vmlinux --tunnet=192.168.19.1 --block=rootfile root=/dev/vda
-
-   Explanation:
-    64: the amount of memory to use, in MB.
-
-    vmlinux: the kernel image found in the top of your build directory.  You
-       can also use a standard bzImage.
-
-    --tunnet=192.168.19.1: configures a "tap" device for networking with this
-       IP address.
-
-    --block=rootfile: a file or block device which becomes /dev/vda
-       inside the guest.
-
-    root=/dev/vda: this (and anything else on the command line) are
-       kernel boot parameters.
-
-- Configuring networking.  I usually have the host masquerade, using
-  "iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE" and "echo 1 >
-  /proc/sys/net/ipv4/ip_forward".  In this example, I would configure
-  eth0 inside the guest at 192.168.19.2.
-
-  Another method is to bridge the tap device to an external interface
-  using --tunnet=bridge:<bridgename>, and perhaps run dhcp on the guest
-  to obtain an IP address.  The bridge needs to be configured first:
-  this option simply adds the tap interface to it.
-
-  A simple example on my system:
-
-    ifconfig eth0 0.0.0.0
-    brctl addbr lg0
-    ifconfig lg0 up
-    brctl addif lg0 eth0
-    dhclient lg0
-
-  Then use --tunnet=bridge:lg0 when launching the guest.
-
-  See:
-  
-    http://www.linuxfoundation.org/collaborate/workgroups/networking/bridge
-    
-  for general information on how to get bridging to work.
-
-- Random number generation. Using the --rng option will provide a
-  /dev/hwrng in the guest that will read from the host's /dev/random.
-  Use this option in conjunction with rng-tools (see ../hw_random.txt)
-  to provide entropy to the guest kernel's /dev/random.
-
-There is a helpful mailing list at http://ozlabs.org/mailman/listinfo/lguest
-
-Good luck!
-Rusty Russell rusty@rustcorp.com.au.
diff -druN linux-2.6.39-libre/Documentation/lguest/Makefile linux-3.0-rc7-libre/Documentation/lguest/Makefile
--- linux-2.6.39-libre/Documentation/lguest/Makefile	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/Documentation/lguest/Makefile	1969-12-31 19:00:00.000000000 -0500
@@ -1,8 +0,0 @@
-# This creates the demonstration utility "lguest" which runs a Linux guest.
-# Missing headers?  Add "-I../../include -I../../arch/x86/include"
-CFLAGS:=-m32 -Wall -Wmissing-declarations -Wmissing-prototypes -O3 -U_FORTIFY_SOURCE
-
-all: lguest
-
-clean:
-	rm -f lguest
diff -druN linux-2.6.39-libre/Documentation/lockstat.txt linux-3.0-rc7-libre/Documentation/lockstat.txt
--- linux-2.6.39-libre/Documentation/lockstat.txt	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/Documentation/lockstat.txt	2011-07-11 19:51:52.000000000 -0400
@@ -12,8 +12,9 @@
 - HOW
 
 Lockdep already has hooks in the lock functions and maps lock instances to
-lock classes. We build on that. The graph below shows the relation between
-the lock functions and the various hooks therein.
+lock classes. We build on that (see Documentation/lockdep-design.txt).
+The graph below shows the relation between the lock functions and the various
+hooks therein.
 
         __acquire
             |
@@ -128,6 +129,37 @@
 
 The integer part of the time values is in us.
 
+Dealing with nested locks, subclasses may appear:
+
+32...............................................................................................................................................................................................
+33
+34                               &rq->lock:         13128          13128           0.43         190.53      103881.26          97454        3453404           0.00         401.11    13224683.11
+35                               ---------
+36                               &rq->lock            645          [<ffffffff8103bfc4>] task_rq_lock+0x43/0x75
+37                               &rq->lock            297          [<ffffffff8104ba65>] try_to_wake_up+0x127/0x25a
+38                               &rq->lock            360          [<ffffffff8103c4c5>] select_task_rq_fair+0x1f0/0x74a
+39                               &rq->lock            428          [<ffffffff81045f98>] scheduler_tick+0x46/0x1fb
+40                               ---------
+41                               &rq->lock             77          [<ffffffff8103bfc4>] task_rq_lock+0x43/0x75
+42                               &rq->lock            174          [<ffffffff8104ba65>] try_to_wake_up+0x127/0x25a
+43                               &rq->lock           4715          [<ffffffff8103ed4b>] double_rq_lock+0x42/0x54
+44                               &rq->lock            893          [<ffffffff81340524>] schedule+0x157/0x7b8
+45
+46...............................................................................................................................................................................................
+47
+48                             &rq->lock/1:         11526          11488           0.33         388.73      136294.31          21461          38404           0.00          37.93      109388.53
+49                             -----------
+50                             &rq->lock/1          11526          [<ffffffff8103ed58>] double_rq_lock+0x4f/0x54
+51                             -----------
+52                             &rq->lock/1           5645          [<ffffffff8103ed4b>] double_rq_lock+0x42/0x54
+53                             &rq->lock/1           1224          [<ffffffff81340524>] schedule+0x157/0x7b8
+54                             &rq->lock/1           4336          [<ffffffff8103ed58>] double_rq_lock+0x4f/0x54
+55                             &rq->lock/1            181          [<ffffffff8104ba65>] try_to_wake_up+0x127/0x25a
+
+Line 48 shows statistics for the second subclass (/1) of &rq->lock class
+(subclass starts from 0), since in this case, as line 50 suggests,
+double_rq_lock actually acquires a nested lock of two spinlocks.
+
 View the top contending locks:
 
 # grep : /proc/lock_stat | head
@@ -136,7 +168,7 @@
                              dcache_lock:          1037           1161           0.38          45.32         774.51           6611         243371           0.15         306.48       77387.24
                          &inode->i_mutex:           161            286 18446744073709       62882.54     1244614.55           3653          20598 18446744073709       62318.60     1693822.74
                          &zone->lru_lock:            94             94           0.53           7.33          92.10           4366          32690           0.29          59.81       16350.06
-              &inode->i_data.i_mmap_lock:            79             79           0.40           3.77          53.03          11779          87755           0.28         116.93       29898.44
+              &inode->i_data.i_mmap_mutex:            79             79           0.40           3.77          53.03          11779          87755           0.28         116.93       29898.44
                         &q->__queue_lock:            48             50           0.52          31.62          86.31            774          13131           0.17         113.08       12277.52
                         &rq->rq_lock_key:            43             47           0.74          68.50         170.63           3706          33929           0.22         107.99       17460.62
                       &rq->rq_lock_key#2:            39             46           0.75           6.68          49.03           2979          32292           0.17         125.17       17137.63
diff -druN linux-2.6.39-libre/Documentation/md.txt linux-3.0-rc7-libre/Documentation/md.txt
--- linux-2.6.39-libre/Documentation/md.txt	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/Documentation/md.txt	2011-07-11 19:51:52.000000000 -0400
@@ -555,7 +555,7 @@
    sync_min
    sync_max
      The two values, given as numbers of sectors, indicate a range
-     withing the array where 'check'/'repair' will operate. Must be
+     within the array where 'check'/'repair' will operate. Must be
      a multiple of chunk_size. When it reaches "sync_max" it will
      pause, rather than complete.
      You can use 'select' or 'poll' on "sync_completed" to wait for
diff -druN linux-2.6.39-libre/Documentation/mmc/00-INDEX linux-3.0-rc7-libre/Documentation/mmc/00-INDEX
--- linux-2.6.39-libre/Documentation/mmc/00-INDEX	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/Documentation/mmc/00-INDEX	2011-07-11 19:51:52.000000000 -0400
@@ -2,3 +2,5 @@
         - this file
 mmc-dev-attrs.txt
         - info on SD and MMC device attributes
+mmc-dev-parts.txt
+        - info on SD and MMC device partitions
diff -druN linux-2.6.39-libre/Documentation/mmc/mmc-dev-attrs.txt linux-3.0-rc7-libre/Documentation/mmc/mmc-dev-attrs.txt
--- linux-2.6.39-libre/Documentation/mmc/mmc-dev-attrs.txt	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/Documentation/mmc/mmc-dev-attrs.txt	2011-07-11 19:51:52.000000000 -0400
@@ -1,3 +1,13 @@
+SD and MMC Block Device Attributes
+==================================
+
+These attributes are defined for the block devices associated with the
+SD or MMC device.
+
+The following attributes are read/write.
+
+	force_ro		Enforce read-only access even if write protect switch is off.
+
 SD and MMC Device Attributes
 ============================
 
diff -druN linux-2.6.39-libre/Documentation/mmc/mmc-dev-parts.txt linux-3.0-rc7-libre/Documentation/mmc/mmc-dev-parts.txt
--- linux-2.6.39-libre/Documentation/mmc/mmc-dev-parts.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/Documentation/mmc/mmc-dev-parts.txt	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,27 @@
+SD and MMC Device Partitions
+============================
+
+Device partitions are additional logical block devices present on the
+SD/MMC device.
+
+As of this writing, MMC boot partitions as supported and exposed as
+/dev/mmcblkXboot0 and /dev/mmcblkXboot1, where X is the index of the
+parent /dev/mmcblkX.
+
+MMC Boot Partitions
+===================
+
+Read and write access is provided to the two MMC boot partitions. Due to
+the sensitive nature of the boot partition contents, which often store
+a bootloader or bootloader configuration tables crucial to booting the
+platform, write access is disabled by default to reduce the chance of
+accidental bricking.
+
+To enable write access to /dev/mmcblkXbootY, disable the forced read-only
+access with:
+
+echo 0 > /sys/block/mmcblkXbootY/force_ro
+
+To re-enable read-only access:
+
+echo 1 > /sys/block/mmcblkXbootY/force_ro
diff -druN linux-2.6.39-libre/Documentation/networking/batman-adv.txt linux-3.0-rc7-libre/Documentation/networking/batman-adv.txt
--- linux-2.6.39-libre/Documentation/networking/batman-adv.txt	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/Documentation/networking/batman-adv.txt	2011-07-11 19:51:52.000000000 -0400
@@ -1,4 +1,4 @@
-[state: 27-01-2011]
+[state: 17-04-2011]
 
 BATMAN-ADV
 ----------
@@ -19,6 +19,7 @@
 network driver, and can be used on wifi as well as ethernet  lan,
 vpn,  etc ... (anything with ethernet-style layer 2).
 
+
 CONFIGURATION
 -------------
 
@@ -160,13 +161,13 @@
 -> "TQ mac  value"  -  src mac's link quality towards mac address
                        of a neighbor originator's interface which
                        is being used for routing
--> "HNA mac" - HNA announced by source mac
+-> "TT mac" - TT announced by source mac
 -> "PRIMARY" - this  is a primary interface
 -> "SEC mac" - secondary mac address of source
                (requires preceding PRIMARY)
 
 The TQ value has a range from 4 to 255 with 255 being  the  best.
-The HNA entries are showing which hosts are connected to the mesh
+The TT entries are showing which hosts are connected to the mesh
 via bat0 or being bridged into the mesh network.  The PRIMARY/SEC
 values are only applied on primary interfaces
 
@@ -199,7 +200,7 @@
 
 0 - All  debug  output  disabled
 1 - Enable messages related to routing / flooding / broadcasting
-2 - Enable route or hna added / changed / deleted
+2 - Enable route or tt entry added / changed / deleted
 3 - Enable all messages
 
 The debug output can be changed at runtime  using  the  file
@@ -207,7 +208,7 @@
 
 # echo 2 > /sys/class/net/bat0/mesh/log_level
 
-will enable debug messages for when routes or HNAs change.
+will enable debug messages for when routes or TTs change.
 
 
 BATCTL
diff -druN linux-2.6.39-libre/Documentation/networking/bonding.txt linux-3.0-rc7-libre/Documentation/networking/bonding.txt
--- linux-2.6.39-libre/Documentation/networking/bonding.txt	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/Documentation/networking/bonding.txt	2011-07-11 19:51:52.000000000 -0400
@@ -1,7 +1,7 @@
 
 		Linux Ethernet Bonding Driver HOWTO
 
-		Latest update: 23 September 2009
+		Latest update: 27 April 2011
 
 Initial release : Thomas Davis <tadavis at lbl.gov>
 Corrections, HA extensions : 2000/10/03-15 :
@@ -585,25 +585,23 @@
 		chosen.
 
 num_grat_arp
-
-	Specifies the number of gratuitous ARPs to be issued after a
-	failover event.  One gratuitous ARP is issued immediately after
-	the failover, subsequent ARPs are sent at a rate of one per link
-	monitor interval (arp_interval or miimon, whichever is active).
-
-	The valid range is 0 - 255; the default value is 1.  This option
-	affects only the active-backup mode.  This option was added for
-	bonding version 3.3.0.
-
 num_unsol_na
 
-	Specifies the number of unsolicited IPv6 Neighbor Advertisements
-	to be issued after a failover event.  One unsolicited NA is issued
-	immediately after the failover.
+	Specify the number of peer notifications (gratuitous ARPs and
+	unsolicited IPv6 Neighbor Advertisements) to be issued after a
+	failover event.  As soon as the link is up on the new slave
+	(possibly immediately) a peer notification is sent on the
+	bonding device and each VLAN sub-device.  This is repeated at
+	each link monitor interval (arp_interval or miimon, whichever
+	is active) if the number is greater than 1.
 
-	The valid range is 0 - 255; the default value is 1.  This option
-	affects only the active-backup mode.  This option was added for
-	bonding version 3.4.0.
+	The valid range is 0 - 255; the default value is 1.  These options
+	affect only the active-backup mode.  These options were added for
+	bonding versions 3.3.0 and 3.4.0 respectively.
+
+	From Linux 2.6.40 and bonding version 3.7.1, these notifications
+	are generated by the ipv4 and ipv6 code and the numbers of
+	repetitions cannot be set independently.
 
 primary
 
@@ -772,8 +770,17 @@
 	a failover event. One membership report is issued immediately after
 	the failover, subsequent packets are sent in each 200ms interval.
 
-	The valid range is 0 - 255; the default value is 1. This option
-	was added for bonding version 3.7.0.
+	The valid range is 0 - 255; the default value is 1. A value of 0
+	prevents the IGMP membership report from being issued in response
+	to the failover event.
+
+	This option is useful for bonding modes balance-rr (0), active-backup
+	(1), balance-tlb (5) and balance-alb (6), in which a failover can
+	switch the IGMP traffic from one slave to another.  Therefore a fresh
+	IGMP report must be issued to cause the switch to forward the incoming
+	IGMP traffic over the newly selected slave.
+
+	This option was added for bonding version 3.7.0.
 
 3. Configuring Bonding Devices
 ==============================
diff -druN linux-2.6.39-libre/Documentation/networking/dns_resolver.txt linux-3.0-rc7-libre/Documentation/networking/dns_resolver.txt
--- linux-2.6.39-libre/Documentation/networking/dns_resolver.txt	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/Documentation/networking/dns_resolver.txt	2011-07-11 19:51:52.000000000 -0400
@@ -139,8 +139,8 @@
 dns_query() returns a copy of the value attached to the key, or an error if
 that is indicated instead.
 
-See <file:Documentation/keys-request-key.txt> for further information about
-request-key function.
+See <file:Documentation/security/keys-request-key.txt> for further
+information about request-key function.
 
 
 =========
diff -druN linux-2.6.39-libre/Documentation/networking/igb.txt linux-3.0-rc7-libre/Documentation/networking/igb.txt
--- linux-2.6.39-libre/Documentation/networking/igb.txt	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/Documentation/networking/igb.txt	2011-07-11 19:51:52.000000000 -0400
@@ -93,6 +93,19 @@
   REQUIREMENTS: MSI-X support is required for Multiqueue. If MSI-X is not
   found, the system will fallback to MSI or to Legacy interrupts.
 
+  MAC and VLAN anti-spoofing feature
+  ----------------------------------
+  When a malicious driver attempts to send a spoofed packet, it is dropped by
+  the hardware and not transmitted.  An interrupt is sent to the PF driver
+  notifying it of the spoof attempt.
+
+  When a spoofed packet is detected the PF driver will send the following
+  message to the system log (displayed by  the "dmesg" command):
+
+  Spoof event(s) detected on VF(n)
+
+  Where n=the VF that attempted to do the spoofing.
+
 Support
 =======
 
diff -druN linux-2.6.39-libre/Documentation/power/devices.txt linux-3.0-rc7-libre/Documentation/power/devices.txt
--- linux-2.6.39-libre/Documentation/power/devices.txt	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/Documentation/power/devices.txt	2011-07-11 19:51:52.000000000 -0400
@@ -279,11 +279,15 @@
 	time.)  Unlike the other suspend-related phases, during the prepare
 	phase the device tree is traversed top-down.
 
-	The prepare phase uses only a bus callback.  After the callback method
-	returns, no new children may be registered below the device.  The method
-	may also prepare the device or driver in some way for the upcoming
-	system power transition, but it should not put the device into a
-	low-power state.
+	In addition to that, if device drivers need to allocate additional
+	memory to be able to hadle device suspend correctly, that should be
+	done in the prepare phase.
+
+	After the prepare callback method returns, no new children may be
+	registered below the device.  The method may also prepare the device or
+	driver in some way for the upcoming system power transition (for
+	example, by allocating additional memory required for this purpose), but
+	it should not put the device into a low-power state.
 
     2.	The suspend methods should quiesce the device to stop it from performing
 	I/O.  They also may save the device registers and put it into the
@@ -516,59 +520,20 @@
 device.  This field is a pointer to an object of type struct dev_power_domain,
 defined in include/linux/pm.h, providing a set of power management callbacks
 analogous to the subsystem-level and device driver callbacks that are executed
-for the given device during all power transitions, in addition to the respective
-subsystem-level callbacks.  Specifically, the power domain "suspend" callbacks
-(i.e. ->runtime_suspend(), ->suspend(), ->freeze(), ->poweroff(), etc.) are
-executed after the analogous subsystem-level callbacks, while the power domain
-"resume" callbacks (i.e. ->runtime_resume(), ->resume(), ->thaw(), ->restore,
-etc.) are executed before the analogous subsystem-level callbacks.  Error codes
-returned by the "suspend" and "resume" power domain callbacks are ignored.
-
-Power domain ->runtime_idle() callback is executed before the subsystem-level
-->runtime_idle() callback and the result returned by it is not ignored.  Namely,
-if it returns error code, the subsystem-level ->runtime_idle() callback will not
-be called and the helper function rpm_idle() executing it will return error
-code.  This mechanism is intended to help platforms where saving device state
-is a time consuming operation and should only be carried out if all devices
-in the power domain are idle, before turning off the shared power resource(s).
-Namely, the power domain ->runtime_idle() callback may return error code until
-the pm_runtime_idle() helper (or its asychronous version) has been called for
-all devices in the power domain (it is recommended that the returned error code
-be -EBUSY in those cases), preventing the subsystem-level ->runtime_idle()
-callback from being run prematurely.
-
-The support for device power domains is only relevant to platforms needing to
-use the same subsystem-level (e.g. platform bus type) and device driver power
-management callbacks in many different power domain configurations and wanting
-to avoid incorporating the support for power domains into the subsystem-level
-callbacks.  The other platforms need not implement it or take it into account
-in any way.
-
-
-System Devices
---------------
-System devices (sysdevs) follow a slightly different API, which can be found in
-
-	include/linux/sysdev.h
-	drivers/base/sys.c
-
-System devices will be suspended with interrupts disabled, and after all other
-devices have been suspended.  On resume, they will be resumed before any other
-devices, and also with interrupts disabled.  These things occur in special
-"sysdev_driver" phases, which affect only system devices.
-
-Thus, after the suspend_noirq (or freeze_noirq or poweroff_noirq) phase, when
-the non-boot CPUs are all offline and IRQs are disabled on the remaining online
-CPU, then a sysdev_driver.suspend phase is carried out, and the system enters a
-sleep state (or a system image is created).  During resume (or after the image
-has been created or loaded) a sysdev_driver.resume phase is carried out, IRQs
-are enabled on the only online CPU, the non-boot CPUs are enabled, and the
-resume_noirq (or thaw_noirq or restore_noirq) phase begins.
+for the given device during all power transitions, instead of the respective
+subsystem-level callbacks.  Specifically, if a device's pm_domain pointer is
+not NULL, the ->suspend() callback from the object pointed to by it will be
+executed instead of its subsystem's (e.g. bus type's) ->suspend() callback and
+anlogously for all of the remaining callbacks.  In other words, power management
+domain callbacks, if defined for the given device, always take precedence over
+the callbacks provided by the device's subsystem (e.g. bus type).
 
-Code to actually enter and exit the system-wide low power state sometimes
-involves hardware details that are only known to the boot firmware, and
-may leave a CPU running software (from SRAM or flash memory) that monitors
-the system and manages its wakeup sequence.
+The support for device power management domains is only relevant to platforms
+needing to use the same device driver power management callbacks in many
+different power domain configurations and wanting to avoid incorporating the
+support for power domains into subsystem-level callbacks, for example by
+modifying the platform bus type.  Other platforms need not implement it or take
+it into account in any way.
 
 
 Device Low Power (suspend) States
diff -druN linux-2.6.39-libre/Documentation/power/notifiers.txt linux-3.0-rc7-libre/Documentation/power/notifiers.txt
--- linux-2.6.39-libre/Documentation/power/notifiers.txt	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/Documentation/power/notifiers.txt	2011-07-11 19:51:52.000000000 -0400
@@ -1,46 +1,41 @@
 Suspend notifiers
-	(C) 2007 Rafael J. Wysocki <rjw@sisk.pl>, GPL
-
-There are some operations that device drivers may want to carry out in their
-.suspend() routines, but shouldn't, because they can cause the hibernation or
-suspend to fail. For example, a driver may want to allocate a substantial amount
-of memory (like 50 MB) in .suspend(), but that shouldn't be done after the
-swsusp's memory shrinker has run.
+	(C) 2007-2011 Rafael J. Wysocki <rjw@sisk.pl>, GPL
 
-Also, there may be some operations, that subsystems want to carry out before a
-hibernation/suspend or after a restore/resume, requiring the system to be fully
-functional, so the drivers' .suspend() and .resume() routines are not suitable
-for this purpose.  For example, device drivers may want to upload firmware to
-their devices after a restore from a hibernation image, but they cannot do it by
-calling request_firmware() from their .resume() routines (user land processes
-are frozen at this point).  The solution may be to load the firmware into
-memory before processes are frozen and upload it from there in the .resume()
-routine.  Of course, a hibernation notifier may be used for this purpose.
+There are some operations that subsystems or drivers may want to carry out
+before hibernation/suspend or after restore/resume, but they require the system
+to be fully functional, so the drivers' and subsystems' .suspend() and .resume()
+or even .prepare() and .complete() callbacks are not suitable for this purpose.
+For example, device drivers may want to upload firmware to their devices after
+resume/restore, but they cannot do it by calling request_firmware() from their
+.resume() or .complete() routines (user land processes are frozen at these
+points).  The solution may be to load the firmware into memory before processes
+are frozen and upload it from there in the .resume() routine.
+A suspend/hibernation notifier may be used for this purpose.
 
-The subsystems that have such needs can register suspend notifiers that will be
-called upon the following events by the suspend core:
+The subsystems or drivers having such needs can register suspend notifiers that
+will be called upon the following events by the PM core:
 
 PM_HIBERNATION_PREPARE	The system is going to hibernate or suspend, tasks will
 			be frozen immediately.
 
 PM_POST_HIBERNATION	The system memory state has been restored from a
-			hibernation image or an error occurred during the
-			hibernation.  Device drivers' .resume() callbacks have
+			hibernation image or an error occurred during
+			hibernation.  Device drivers' restore callbacks have
 			been executed and tasks have been thawed.
 
 PM_RESTORE_PREPARE	The system is going to restore a hibernation image.
-			If all goes well the restored kernel will issue a
+			If all goes well, the restored kernel will issue a
 			PM_POST_HIBERNATION notification.
 
-PM_POST_RESTORE		An error occurred during the hibernation restore.
-			Device drivers' .resume() callbacks have been executed
+PM_POST_RESTORE		An error occurred during restore from hibernation.
+			Device drivers' restore callbacks have been executed
 			and tasks have been thawed.
 
-PM_SUSPEND_PREPARE	The system is preparing for a suspend.
+PM_SUSPEND_PREPARE	The system is preparing for suspend.
 
 PM_POST_SUSPEND		The system has just resumed or an error occurred during
-			the suspend.	Device drivers' .resume() callbacks have
-			been executed and tasks have been thawed.
+			suspend.  Device drivers' resume callbacks have been
+			executed and tasks have been thawed.
 
 It is generally assumed that whatever the notifiers do for
 PM_HIBERNATION_PREPARE, should be undone for PM_POST_HIBERNATION.  Analogously,
diff -druN linux-2.6.39-libre/Documentation/power/regulator/machine.txt linux-3.0-rc7-libre/Documentation/power/regulator/machine.txt
--- linux-2.6.39-libre/Documentation/power/regulator/machine.txt	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/Documentation/power/regulator/machine.txt	2011-07-11 19:51:52.000000000 -0400
@@ -53,11 +53,11 @@
 
 Regulator-1 supplies power to Regulator-2. This relationship must be registered
 with the core so that Regulator-1 is also enabled when Consumer A enables its
-supply (Regulator-2). The supply regulator is set by the supply_regulator_dev
+supply (Regulator-2). The supply regulator is set by the supply_regulator
 field below:-
 
 static struct regulator_init_data regulator2_data = {
-	.supply_regulator_dev = &platform_regulator1_device.dev,
+	.supply_regulator = "regulator_name",
 	.constraints = {
 		.min_uV = 1800000,
 		.max_uV = 2000000,
diff -druN linux-2.6.39-libre/Documentation/power/runtime_pm.txt linux-3.0-rc7-libre/Documentation/power/runtime_pm.txt
--- linux-2.6.39-libre/Documentation/power/runtime_pm.txt	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/Documentation/power/runtime_pm.txt	2011-07-11 19:51:52.000000000 -0400
@@ -501,13 +501,29 @@
 should be used.  Of course, for this purpose the device's run-time PM has to be
 enabled earlier by calling pm_runtime_enable().
 
-If the device bus type's or driver's ->probe() or ->remove() callback runs
+If the device bus type's or driver's ->probe() callback runs
 pm_runtime_suspend() or pm_runtime_idle() or their asynchronous counterparts,
 they will fail returning -EAGAIN, because the device's usage counter is
-incremented by the core before executing ->probe() and ->remove().  Still, it
-may be desirable to suspend the device as soon as ->probe() or ->remove() has
-finished, so the PM core uses pm_runtime_idle_sync() to invoke the
-subsystem-level idle callback for the device at that time.
+incremented by the driver core before executing ->probe().  Still, it may be
+desirable to suspend the device as soon as ->probe() has finished, so the driver
+core uses pm_runtime_put_sync() to invoke the subsystem-level idle callback for
+the device at that time.
+
+Moreover, the driver core prevents runtime PM callbacks from racing with the bus
+notifier callback in __device_release_driver(), which is necessary, because the
+notifier is used by some subsystems to carry out operations affecting the
+runtime PM functionality.  It does so by calling pm_runtime_get_sync() before
+driver_sysfs_remove() and the BUS_NOTIFY_UNBIND_DRIVER notifications.  This
+resumes the device if it's in the suspended state and prevents it from
+being suspended again while those routines are being executed.
+
+To allow bus types and drivers to put devices into the suspended state by
+calling pm_runtime_suspend() from their ->remove() routines, the driver core
+executes pm_runtime_put_sync() after running the BUS_NOTIFY_UNBIND_DRIVER
+notifications in __device_release_driver().  This requires bus types and
+drivers to make their ->remove() callbacks avoid races with runtime PM directly,
+but also it allows of more flexibility in the handling of devices during the
+removal of their drivers.
 
 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
@@ -566,11 +582,6 @@
 	pm_runtime_set_active(dev);
 	pm_runtime_enable(dev);
 
-The PM core always increments the run-time usage counter before calling the
-->prepare() callback and decrements it after calling the ->complete() callback.
-Hence disabling run-time PM temporarily like this will not cause any run-time
-suspend callbacks to be lost.
-
 7. Generic subsystem callbacks
 
 Subsystems may wish to conserve code space by using the set of generic power
diff -druN linux-2.6.39-libre/Documentation/printk-formats.txt linux-3.0-rc7-libre/Documentation/printk-formats.txt
--- linux-2.6.39-libre/Documentation/printk-formats.txt	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/Documentation/printk-formats.txt	2011-07-11 19:51:52.000000000 -0400
@@ -9,7 +9,121 @@
 		size_t			%zu or %zx
 		ssize_t			%zd or %zx
 
-Raw pointer value SHOULD be printed with %p.
+Raw pointer value SHOULD be printed with %p. The kernel supports
+the following extended format specifiers for pointer types:
+
+Symbols/Function Pointers:
+
+	%pF	versatile_init+0x0/0x110
+	%pf	versatile_init
+	%pS	versatile_init+0x0/0x110
+	%ps	versatile_init
+	%pB	prev_fn_of_versatile_init+0x88/0x88
+
+	For printing symbols and function pointers. The 'S' and 's' specifiers
+	result in the symbol name with ('S') or without ('s') offsets. Where
+	this is used on a kernel without KALLSYMS - the symbol address is
+	printed instead.
+
+	The 'B' specifier results in the symbol name with offsets and should be
+	used when printing stack backtraces. The specifier takes into
+	consideration the effect of compiler optimisations which may occur
+	when tail-call's are used and marked with the noreturn GCC attribute.
+
+	On ia64, ppc64 and parisc64 architectures function pointers are
+	actually function descriptors which must first be resolved. The 'F' and
+	'f' specifiers perform this resolution and then provide the same
+	functionality as the 'S' and 's' specifiers.
+
+Kernel Pointers:
+
+	%pK	0x01234567 or 0x0123456789abcdef
+
+	For printing kernel pointers which should be hidden from unprivileged
+	users. The behaviour of %pK depends on the kptr_restrict sysctl - see
+	Documentation/sysctl/kernel.txt for more details.
+
+Struct Resources:
+
+	%pr	[mem 0x60000000-0x6fffffff flags 0x2200] or
+		[mem 0x0000000060000000-0x000000006fffffff flags 0x2200]
+	%pR	[mem 0x60000000-0x6fffffff pref] or
+		[mem 0x0000000060000000-0x000000006fffffff pref]
+
+	For printing struct resources. The 'R' and 'r' specifiers result in a
+	printed resource with ('R') or without ('r') a decoded flags member.
+
+MAC/FDDI addresses:
+
+	%pM	00:01:02:03:04:05
+	%pMF	00-01-02-03-04-05
+	%pm	000102030405
+
+	For printing 6-byte MAC/FDDI addresses in hex notation. The 'M' and 'm'
+	specifiers result in a printed address with ('M') or without ('m') byte
+	separators. The default byte separator is the colon (':').
+
+	Where FDDI addresses are concerned the 'F' specifier can be used after
+	the 'M' specifier to use dash ('-') separators instead of the default
+	separator.
+
+IPv4 addresses:
+
+	%pI4	1.2.3.4
+	%pi4	001.002.003.004
+	%p[Ii][hnbl]
+
+	For printing IPv4 dot-separated decimal addresses. The 'I4' and 'i4'
+	specifiers result in a printed address with ('i4') or without ('I4')
+	leading zeros.
+
+	The additional 'h', 'n', 'b', and 'l' specifiers are used to specify
+	host, network, big or little endian order addresses respectively. Where
+	no specifier is provided the default network/big endian order is used.
+
+IPv6 addresses:
+
+	%pI6	0001:0002:0003:0004:0005:0006:0007:0008
+	%pi6	00010002000300040005000600070008
+	%pI6c	1:2:3:4:5:6:7:8
+
+	For printing IPv6 network-order 16-bit hex addresses. The 'I6' and 'i6'
+	specifiers result in a printed address with ('I6') or without ('i6')
+	colon-separators. Leading zeros are always used.
+
+	The additional 'c' specifier can be used with the 'I' specifier to
+	print a compressed IPv6 address as described by
+	http://tools.ietf.org/html/rfc5952
+
+UUID/GUID addresses:
+
+	%pUb	00010203-0405-0607-0809-0a0b0c0d0e0f
+	%pUB	00010203-0405-0607-0809-0A0B0C0D0E0F
+	%pUl	03020100-0504-0706-0809-0a0b0c0e0e0f
+	%pUL	03020100-0504-0706-0809-0A0B0C0E0E0F
+
+	For printing 16-byte UUID/GUIDs addresses. The additional 'l', 'L',
+	'b' and 'B' specifiers are used to specify a little endian order in
+	lower ('l') or upper case ('L') hex characters - and big endian order
+	in lower ('b') or upper case ('B') hex characters.
+
+	Where no additional specifiers are used the default little endian
+	order with lower case hex characters will be printed.
+
+struct va_format:
+
+	%pV
+
+	For printing struct va_format structures. These contain a format string
+	and va_list as follows:
+
+	struct va_format {
+		const char *fmt;
+		va_list *va;
+	};
+
+	Do not use this feature without some mechanism to verify the
+	correctness of the format string and va_list arguments.
 
 u64 SHOULD be printed with %llu/%llx, (unsigned long long):
 
@@ -32,4 +146,5 @@
 Thank you for your cooperation and attention.
 
 
-By Randy Dunlap <rdunlap@xenotime.net>
+By Randy Dunlap <rdunlap@xenotime.net> and
+Andrew Murray <amurray@mpc-data.co.uk>
diff -druN linux-2.6.39-libre/Documentation/pti/pti_intel_mid.txt linux-3.0-rc7-libre/Documentation/pti/pti_intel_mid.txt
--- linux-2.6.39-libre/Documentation/pti/pti_intel_mid.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/Documentation/pti/pti_intel_mid.txt	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,99 @@
+The Intel MID PTI project is HW implemented in Intel Atom
+system-on-a-chip designs based on the Parallel Trace
+Interface for MIPI P1149.7 cJTAG standard.  The kernel solution
+for this platform involves the following files:
+
+./include/linux/pti.h
+./drivers/.../n_tracesink.h
+./drivers/.../n_tracerouter.c
+./drivers/.../n_tracesink.c
+./drivers/.../pti.c
+
+pti.c is the driver that enables various debugging features
+popular on platforms from certain mobile manufacturers.
+n_tracerouter.c and n_tracesink.c allow extra system information to
+be collected and routed to the pti driver, such as trace
+debugging data from a modem.  Although n_tracerouter
+and n_tracesink are a part of the complete PTI solution,
+these two line disciplines can work separately from
+pti.c and route any data stream from one /dev/tty node
+to another /dev/tty node via kernel-space.  This provides
+a stable, reliable connection that will not break unless
+the user-space application shuts down (plus avoids
+kernel->user->kernel context switch overheads of routing
+data).
+
+An example debugging usage for this driver system:
+   *Hook /dev/ttyPTI0 to syslogd.  Opening this port will also start
+    a console device to further capture debugging messages to PTI.
+   *Hook /dev/ttyPTI1 to modem debugging data to write to PTI HW.
+    This is where n_tracerouter and n_tracesink are used.
+   *Hook /dev/pti to a user-level debugging application for writing
+    to PTI HW.
+   *Use mipi_* Kernel Driver API in other device drivers for
+    debugging to PTI by first requesting a PTI write address via
+    mipi_request_masterchannel(1).
+
+Below is example pseudo-code on how a 'privileged' application
+can hook up n_tracerouter and n_tracesink to any tty on
+a system.  'Privileged' means the application has enough
+privileges to successfully manipulate the ldisc drivers
+but is not just blindly executing as 'root'. Keep in mind
+the use of ioctl(,TIOCSETD,) is not specific to the n_tracerouter
+and n_tracesink line discpline drivers but is a generic
+operation for a program to use a line discpline driver
+on a tty port other than the default n_tty.
+
+/////////// To hook up n_tracerouter and n_tracesink /////////
+
+// Note that n_tracerouter depends on n_tracesink.
+#include <errno.h>
+#define ONE_TTY "/dev/ttyOne"
+#define TWO_TTY "/dev/ttyTwo"
+
+// needed global to hand onto ldisc connection
+static int g_fd_source = -1;
+static int g_fd_sink  = -1;
+
+// these two vars used to grab LDISC values from loaded ldisc drivers
+// in OS.  Look at /proc/tty/ldiscs to get the right numbers from
+// the ldiscs loaded in the system.
+int source_ldisc_num, sink_ldisc_num = -1;
+int retval;
+
+g_fd_source = open(ONE_TTY, O_RDWR); // must be R/W
+g_fd_sink   = open(TWO_TTY, O_RDWR); // must be R/W
+
+if (g_fd_source <= 0) || (g_fd_sink <= 0) {
+   // doubt you'll want to use these exact error lines of code
+   printf("Error on open(). errno: %d\n",errno);
+   return errno;
+}
+
+retval = ioctl(g_fd_sink, TIOCSETD, &sink_ldisc_num);
+if (retval < 0) {
+   printf("Error on ioctl().  errno: %d\n", errno);
+   return errno;
+}
+
+retval = ioctl(g_fd_source, TIOCSETD, &source_ldisc_num);
+if (retval < 0) {
+   printf("Error on ioctl().  errno: %d\n", errno);
+   return errno;
+}
+
+/////////// To disconnect n_tracerouter and n_tracesink ////////
+
+// First make sure data through the ldiscs has stopped.
+
+// Second, disconnect ldiscs.  This provides a
+// little cleaner shutdown on tty stack.
+sink_ldisc_num = 0;
+source_ldisc_num = 0;
+ioctl(g_fd_uart, TIOCSETD, &sink_ldisc_num);
+ioctl(g_fd_gadget, TIOCSETD, &source_ldisc_num);
+
+// Three, program closes connection, and cleanup:
+close(g_fd_uart);
+close(g_fd_gadget);
+g_fd_uart = g_fd_gadget = NULL;
diff -druN linux-2.6.39-libre/Documentation/ptp/ptp.txt linux-3.0-rc7-libre/Documentation/ptp/ptp.txt
--- linux-2.6.39-libre/Documentation/ptp/ptp.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/Documentation/ptp/ptp.txt	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,89 @@
+
+* PTP hardware clock infrastructure for Linux
+
+  This patch set introduces support for IEEE 1588 PTP clocks in
+  Linux. Together with the SO_TIMESTAMPING socket options, this
+  presents a standardized method for developing PTP user space
+  programs, synchronizing Linux with external clocks, and using the
+  ancillary features of PTP hardware clocks.
+
+  A new class driver exports a kernel interface for specific clock
+  drivers and a user space interface. The infrastructure supports a
+  complete set of PTP hardware clock functionality.
+
+  + Basic clock operations
+    - Set time
+    - Get time
+    - Shift the clock by a given offset atomically
+    - Adjust clock frequency
+
+  + Ancillary clock features
+    - One short or periodic alarms, with signal delivery to user program
+    - Time stamp external events
+    - Period output signals configurable from user space
+    - Synchronization of the Linux system time via the PPS subsystem
+
+** PTP hardware clock kernel API
+
+   A PTP clock driver registers itself with the class driver. The
+   class driver handles all of the dealings with user space. The
+   author of a clock driver need only implement the details of
+   programming the clock hardware. The clock driver notifies the class
+   driver of asynchronous events (alarms and external time stamps) via
+   a simple message passing interface.
+
+   The class driver supports multiple PTP clock drivers. In normal use
+   cases, only one PTP clock is needed. However, for testing and
+   development, it can be useful to have more than one clock in a
+   single system, in order to allow performance comparisons.
+
+** PTP hardware clock user space API
+
+   The class driver also creates a character device for each
+   registered clock. User space can use an open file descriptor from
+   the character device as a POSIX clock id and may call
+   clock_gettime, clock_settime, and clock_adjtime.  These calls
+   implement the basic clock operations.
+
+   User space programs may control the clock using standardized
+   ioctls. A program may query, enable, configure, and disable the
+   ancillary clock features. User space can receive time stamped
+   events via blocking read() and poll(). One shot and periodic
+   signals may be configured via the POSIX timer_settime() system
+   call.
+
+** Writing clock drivers
+
+   Clock drivers include include/linux/ptp_clock_kernel.h and register
+   themselves by presenting a 'struct ptp_clock_info' to the
+   registration method. Clock drivers must implement all of the
+   functions in the interface. If a clock does not offer a particular
+   ancillary feature, then the driver should just return -EOPNOTSUPP
+   from those functions.
+
+   Drivers must ensure that all of the methods in interface are
+   reentrant. Since most hardware implementations treat the time value
+   as a 64 bit integer accessed as two 32 bit registers, drivers
+   should use spin_lock_irqsave/spin_unlock_irqrestore to protect
+   against concurrent access. This locking cannot be accomplished in
+   class driver, since the lock may also be needed by the clock
+   driver's interrupt service routine.
+
+** Supported hardware
+
+   + Freescale eTSEC gianfar
+     - 2 Time stamp external triggers, programmable polarity (opt. interrupt)
+     - 2 Alarm registers (optional interrupt)
+     - 3 Periodic signals (optional interrupt)
+
+   + National DP83640
+     - 6 GPIOs programmable as inputs or outputs
+     - 6 GPIOs with dedicated functions (LED/JTAG/clock) can also be
+       used as general inputs or outputs
+     - GPIO inputs can time stamp external triggers
+     - GPIO outputs can produce periodic signals
+     - 1 interrupt pin
+
+   + Intel IXP465
+     - Auxiliary Slave/Master Mode Snapshot (optional interrupt)
+     - Target Time (optional interrupt)
diff -druN linux-2.6.39-libre/Documentation/ptp/testptp.c linux-3.0-rc7-libre/Documentation/ptp/testptp.c
--- linux-2.6.39-libre/Documentation/ptp/testptp.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/Documentation/ptp/testptp.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,381 @@
+/*
+ * PTP 1588 clock support - User space test program
+ *
+ * Copyright (C) 2010 OMICRON electronics GmbH
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the 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 <errno.h>
+#include <fcntl.h>
+#include <math.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/ioctl.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <sys/time.h>
+#include <sys/timex.h>
+#include <sys/types.h>
+#include <time.h>
+#include <unistd.h>
+
+#include <linux/ptp_clock.h>
+
+#define DEVICE "/dev/ptp0"
+
+#ifndef ADJ_SETOFFSET
+#define ADJ_SETOFFSET 0x0100
+#endif
+
+#ifndef CLOCK_INVALID
+#define CLOCK_INVALID -1
+#endif
+
+/* When glibc offers the syscall, this will go away. */
+#include <sys/syscall.h>
+static int clock_adjtime(clockid_t id, struct timex *tx)
+{
+	return syscall(__NR_clock_adjtime, id, tx);
+}
+
+static clockid_t get_clockid(int fd)
+{
+#define CLOCKFD 3
+#define FD_TO_CLOCKID(fd)	((~(clockid_t) (fd) << 3) | CLOCKFD)
+
+	return FD_TO_CLOCKID(fd);
+}
+
+static void handle_alarm(int s)
+{
+	printf("received signal %d\n", s);
+}
+
+static int install_handler(int signum, void (*handler)(int))
+{
+	struct sigaction action;
+	sigset_t mask;
+
+	/* Unblock the signal. */
+	sigemptyset(&mask);
+	sigaddset(&mask, signum);
+	sigprocmask(SIG_UNBLOCK, &mask, NULL);
+
+	/* Install the signal handler. */
+	action.sa_handler = handler;
+	action.sa_flags = 0;
+	sigemptyset(&action.sa_mask);
+	sigaction(signum, &action, NULL);
+
+	return 0;
+}
+
+static long ppb_to_scaled_ppm(int ppb)
+{
+	/*
+	 * The 'freq' field in the 'struct timex' is in parts per
+	 * million, but with a 16 bit binary fractional field.
+	 * Instead of calculating either one of
+	 *
+	 *    scaled_ppm = (ppb / 1000) << 16  [1]
+	 *    scaled_ppm = (ppb << 16) / 1000  [2]
+	 *
+	 * we simply use double precision math, in order to avoid the
+	 * truncation in [1] and the possible overflow in [2].
+	 */
+	return (long) (ppb * 65.536);
+}
+
+static void usage(char *progname)
+{
+	fprintf(stderr,
+		"usage: %s [options]\n"
+		" -a val     request a one-shot alarm after 'val' seconds\n"
+		" -A val     request a periodic alarm every 'val' seconds\n"
+		" -c         query the ptp clock's capabilities\n"
+		" -d name    device to open\n"
+		" -e val     read 'val' external time stamp events\n"
+		" -f val     adjust the ptp clock frequency by 'val' ppb\n"
+		" -g         get the ptp clock time\n"
+		" -h         prints this message\n"
+		" -p val     enable output with a period of 'val' nanoseconds\n"
+		" -P val     enable or disable (val=1|0) the system clock PPS\n"
+		" -s         set the ptp clock time from the system time\n"
+		" -S         set the system time from the ptp clock time\n"
+		" -t val     shift the ptp clock time by 'val' seconds\n",
+		progname);
+}
+
+int main(int argc, char *argv[])
+{
+	struct ptp_clock_caps caps;
+	struct ptp_extts_event event;
+	struct ptp_extts_request extts_request;
+	struct ptp_perout_request perout_request;
+	struct timespec ts;
+	struct timex tx;
+
+	static timer_t timerid;
+	struct itimerspec timeout;
+	struct sigevent sigevent;
+
+	char *progname;
+	int c, cnt, fd;
+
+	char *device = DEVICE;
+	clockid_t clkid;
+	int adjfreq = 0x7fffffff;
+	int adjtime = 0;
+	int capabilities = 0;
+	int extts = 0;
+	int gettime = 0;
+	int oneshot = 0;
+	int periodic = 0;
+	int perout = -1;
+	int pps = -1;
+	int settime = 0;
+
+	progname = strrchr(argv[0], '/');
+	progname = progname ? 1+progname : argv[0];
+	while (EOF != (c = getopt(argc, argv, "a:A:cd:e:f:ghp:P:sSt:v"))) {
+		switch (c) {
+		case 'a':
+			oneshot = atoi(optarg);
+			break;
+		case 'A':
+			periodic = atoi(optarg);
+			break;
+		case 'c':
+			capabilities = 1;
+			break;
+		case 'd':
+			device = optarg;
+			break;
+		case 'e':
+			extts = atoi(optarg);
+			break;
+		case 'f':
+			adjfreq = atoi(optarg);
+			break;
+		case 'g':
+			gettime = 1;
+			break;
+		case 'p':
+			perout = atoi(optarg);
+			break;
+		case 'P':
+			pps = atoi(optarg);
+			break;
+		case 's':
+			settime = 1;
+			break;
+		case 'S':
+			settime = 2;
+			break;
+		case 't':
+			adjtime = atoi(optarg);
+			break;
+		case 'h':
+			usage(progname);
+			return 0;
+		case '?':
+		default:
+			usage(progname);
+			return -1;
+		}
+	}
+
+	fd = open(device, O_RDWR);
+	if (fd < 0) {
+		fprintf(stderr, "opening %s: %s\n", device, strerror(errno));
+		return -1;
+	}
+
+	clkid = get_clockid(fd);
+	if (CLOCK_INVALID == clkid) {
+		fprintf(stderr, "failed to read clock id\n");
+		return -1;
+	}
+
+	if (capabilities) {
+		if (ioctl(fd, PTP_CLOCK_GETCAPS, &caps)) {
+			perror("PTP_CLOCK_GETCAPS");
+		} else {
+			printf("capabilities:\n"
+			       "  %d maximum frequency adjustment (ppb)\n"
+			       "  %d programmable alarms\n"
+			       "  %d external time stamp channels\n"
+			       "  %d programmable periodic signals\n"
+			       "  %d pulse per second\n",
+			       caps.max_adj,
+			       caps.n_alarm,
+			       caps.n_ext_ts,
+			       caps.n_per_out,
+			       caps.pps);
+		}
+	}
+
+	if (0x7fffffff != adjfreq) {
+		memset(&tx, 0, sizeof(tx));
+		tx.modes = ADJ_FREQUENCY;
+		tx.freq = ppb_to_scaled_ppm(adjfreq);
+		if (clock_adjtime(clkid, &tx)) {
+			perror("clock_adjtime");
+		} else {
+			puts("frequency adjustment okay");
+		}
+	}
+
+	if (adjtime) {
+		memset(&tx, 0, sizeof(tx));
+		tx.modes = ADJ_SETOFFSET;
+		tx.time.tv_sec = adjtime;
+		tx.time.tv_usec = 0;
+		if (clock_adjtime(clkid, &tx) < 0) {
+			perror("clock_adjtime");
+		} else {
+			puts("time shift okay");
+		}
+	}
+
+	if (gettime) {
+		if (clock_gettime(clkid, &ts)) {
+			perror("clock_gettime");
+		} else {
+			printf("clock time: %ld.%09ld or %s",
+			       ts.tv_sec, ts.tv_nsec, ctime(&ts.tv_sec));
+		}
+	}
+
+	if (settime == 1) {
+		clock_gettime(CLOCK_REALTIME, &ts);
+		if (clock_settime(clkid, &ts)) {
+			perror("clock_settime");
+		} else {
+			puts("set time okay");
+		}
+	}
+
+	if (settime == 2) {
+		clock_gettime(clkid, &ts);
+		if (clock_settime(CLOCK_REALTIME, &ts)) {
+			perror("clock_settime");
+		} else {
+			puts("set time okay");
+		}
+	}
+
+	if (extts) {
+		memset(&extts_request, 0, sizeof(extts_request));
+		extts_request.index = 0;
+		extts_request.flags = PTP_ENABLE_FEATURE;
+		if (ioctl(fd, PTP_EXTTS_REQUEST, &extts_request)) {
+			perror("PTP_EXTTS_REQUEST");
+			extts = 0;
+		} else {
+			puts("external time stamp request okay");
+		}
+		for (; extts; extts--) {
+			cnt = read(fd, &event, sizeof(event));
+			if (cnt != sizeof(event)) {
+				perror("read");
+				break;
+			}
+			printf("event index %u at %lld.%09u\n", event.index,
+			       event.t.sec, event.t.nsec);
+			fflush(stdout);
+		}
+		/* Disable the feature again. */
+		extts_request.flags = 0;
+		if (ioctl(fd, PTP_EXTTS_REQUEST, &extts_request)) {
+			perror("PTP_EXTTS_REQUEST");
+		}
+	}
+
+	if (oneshot) {
+		install_handler(SIGALRM, handle_alarm);
+		/* Create a timer. */
+		sigevent.sigev_notify = SIGEV_SIGNAL;
+		sigevent.sigev_signo = SIGALRM;
+		if (timer_create(clkid, &sigevent, &timerid)) {
+			perror("timer_create");
+			return -1;
+		}
+		/* Start the timer. */
+		memset(&timeout, 0, sizeof(timeout));
+		timeout.it_value.tv_sec = oneshot;
+		if (timer_settime(timerid, 0, &timeout, NULL)) {
+			perror("timer_settime");
+			return -1;
+		}
+		pause();
+		timer_delete(timerid);
+	}
+
+	if (periodic) {
+		install_handler(SIGALRM, handle_alarm);
+		/* Create a timer. */
+		sigevent.sigev_notify = SIGEV_SIGNAL;
+		sigevent.sigev_signo = SIGALRM;
+		if (timer_create(clkid, &sigevent, &timerid)) {
+			perror("timer_create");
+			return -1;
+		}
+		/* Start the timer. */
+		memset(&timeout, 0, sizeof(timeout));
+		timeout.it_interval.tv_sec = periodic;
+		timeout.it_value.tv_sec = periodic;
+		if (timer_settime(timerid, 0, &timeout, NULL)) {
+			perror("timer_settime");
+			return -1;
+		}
+		while (1) {
+			pause();
+		}
+		timer_delete(timerid);
+	}
+
+	if (perout >= 0) {
+		if (clock_gettime(clkid, &ts)) {
+			perror("clock_gettime");
+			return -1;
+		}
+		memset(&perout_request, 0, sizeof(perout_request));
+		perout_request.index = 0;
+		perout_request.start.sec = ts.tv_sec + 2;
+		perout_request.start.nsec = 0;
+		perout_request.period.sec = 0;
+		perout_request.period.nsec = perout;
+		if (ioctl(fd, PTP_PEROUT_REQUEST, &perout_request)) {
+			perror("PTP_PEROUT_REQUEST");
+		} else {
+			puts("periodic output request okay");
+		}
+	}
+
+	if (pps != -1) {
+		int enable = pps ? 1 : 0;
+		if (ioctl(fd, PTP_ENABLE_PPS, enable)) {
+			perror("PTP_ENABLE_PPS");
+		} else {
+			puts("pps for system time request okay");
+		}
+	}
+
+	close(fd);
+	return 0;
+}
diff -druN linux-2.6.39-libre/Documentation/ptp/testptp.mk linux-3.0-rc7-libre/Documentation/ptp/testptp.mk
--- linux-2.6.39-libre/Documentation/ptp/testptp.mk	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/Documentation/ptp/testptp.mk	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,33 @@
+# PTP 1588 clock support - User space test program
+#
+# Copyright (C) 2010 OMICRON electronics GmbH
+#
+#  This program is free software; you can redistribute it and/or modify
+#  it under the terms of the GNU General Public License as published by
+#  the Free Software Foundation; either version 2 of the License, or
+#  (at your option) any later version.
+#
+#  This program is distributed in the hope that it will be useful,
+#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#  GNU General Public License for more details.
+#
+#  You should have received a copy of the GNU General Public License
+#  along with this program; if not, write to the Free Software
+#  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+CC        = $(CROSS_COMPILE)gcc
+INC       = -I$(KBUILD_OUTPUT)/usr/include
+CFLAGS    = -Wall $(INC)
+LDLIBS    = -lrt
+PROGS     = testptp
+
+all: $(PROGS)
+
+testptp: testptp.o
+
+clean:
+	rm -f testptp.o
+
+distclean: clean
+	rm -f $(PROGS)
diff -druN linux-2.6.39-libre/Documentation/RCU/00-INDEX linux-3.0-rc7-libre/Documentation/RCU/00-INDEX
--- linux-2.6.39-libre/Documentation/RCU/00-INDEX	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/Documentation/RCU/00-INDEX	2011-07-11 19:51:52.000000000 -0400
@@ -21,7 +21,7 @@
 RTFP.txt
 	- List of RCU papers (bibliography) going back to 1980.
 stallwarn.txt
-	- RCU CPU stall warnings (CONFIG_RCU_CPU_STALL_DETECTOR)
+	- RCU CPU stall warnings (module parameter rcu_cpu_stall_suppress)
 torture.txt
 	- RCU Torture Test Operation (CONFIG_RCU_TORTURE_TEST)
 trace.txt
diff -druN linux-2.6.39-libre/Documentation/RCU/stallwarn.txt linux-3.0-rc7-libre/Documentation/RCU/stallwarn.txt
--- linux-2.6.39-libre/Documentation/RCU/stallwarn.txt	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/Documentation/RCU/stallwarn.txt	2011-07-11 19:51:52.000000000 -0400
@@ -1,22 +1,25 @@
 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 set of C preprocessor macros:
+The rcu_cpu_stall_suppress module parameter enables RCU's CPU stall
+detector, which detects conditions that unduly delay RCU grace periods.
+This module parameter enables CPU stall detection by default, but
+may be overridden via boot-time parameter or at runtime via sysfs.
+The stall detector's idea of what constitutes "unduly delayed" is
+controlled by a set of kernel configuration variables and cpp macros:
 
-RCU_SECONDS_TILL_STALL_CHECK
+CONFIG_RCU_CPU_STALL_TIMEOUT
 
-	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.	This time period is normally ten seconds.
+	This kernel configuration parameter defines the period of time
+	that RCU will wait from the beginning of a grace period until it
+	issues an RCU CPU stall warning.  This time period 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
-	for the same stall.  This time period is normally set to thirty
-	seconds.
+	for the same stall.  This time period is normally set to three
+	times the check interval plus thirty seconds.
 
 RCU_STALL_RAT_DELAY
 
diff -druN linux-2.6.39-libre/Documentation/RCU/trace.txt linux-3.0-rc7-libre/Documentation/RCU/trace.txt
--- linux-2.6.39-libre/Documentation/RCU/trace.txt	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/Documentation/RCU/trace.txt	2011-07-11 19:51:52.000000000 -0400
@@ -10,34 +10,46 @@
 
 CONFIG_TREE_RCU and CONFIG_TREE_PREEMPT_RCU debugfs Files and Formats
 
-These implementations of RCU provides five debugfs files under the
-top-level directory RCU: rcu/rcudata (which displays fields in struct
-rcu_data), rcu/rcudata.csv (which is a .csv spreadsheet version of
-rcu/rcudata), rcu/rcugp (which displays grace-period counters),
-rcu/rcuhier (which displays the struct rcu_node hierarchy), and
-rcu/rcu_pending (which displays counts of the reasons that the
-rcu_pending() function decided that there was core RCU work to do).
+These implementations of RCU provides several debugfs files under the
+top-level directory "rcu":
+
+rcu/rcudata:
+	Displays fields in struct rcu_data.
+rcu/rcudata.csv:
+	Comma-separated values spreadsheet version of rcudata.
+rcu/rcugp:
+	Displays grace-period counters.
+rcu/rcuhier:
+	Displays the struct rcu_node hierarchy.
+rcu/rcu_pending:
+	Displays counts of the reasons rcu_pending() decided that RCU had
+	work to do.
+rcu/rcutorture:
+	Displays rcutorture test progress.
+rcu/rcuboost:
+	Displays RCU boosting statistics.  Only present if
+	CONFIG_RCU_BOOST=y.
 
 The output of "cat rcu/rcudata" looks as follows:
 
 rcu_sched:
-  0 c=17829 g=17829 pq=1 pqc=17829 qp=0 dt=10951/1 dn=0 df=1101 of=0 ri=36 ql=0 b=10
-  1 c=17829 g=17829 pq=1 pqc=17829 qp=0 dt=16117/1 dn=0 df=1015 of=0 ri=0 ql=0 b=10
-  2 c=17829 g=17829 pq=1 pqc=17829 qp=0 dt=1445/1 dn=0 df=1839 of=0 ri=0 ql=0 b=10
-  3 c=17829 g=17829 pq=1 pqc=17829 qp=0 dt=6681/1 dn=0 df=1545 of=0 ri=0 ql=0 b=10
-  4 c=17829 g=17829 pq=1 pqc=17829 qp=0 dt=1003/1 dn=0 df=1992 of=0 ri=0 ql=0 b=10
-  5 c=17829 g=17830 pq=1 pqc=17829 qp=1 dt=3887/1 dn=0 df=3331 of=0 ri=4 ql=2 b=10
-  6 c=17829 g=17829 pq=1 pqc=17829 qp=0 dt=859/1 dn=0 df=3224 of=0 ri=0 ql=0 b=10
-  7 c=17829 g=17830 pq=0 pqc=17829 qp=1 dt=3761/1 dn=0 df=1818 of=0 ri=0 ql=2 b=10
+  0 c=20972 g=20973 pq=1 pqc=20972 qp=0 dt=545/1/0 df=50 of=0 ri=0 ql=163 qs=NRW. kt=0/W/0 ktl=ebc3 b=10 ci=153737 co=0 ca=0
+  1 c=20972 g=20973 pq=1 pqc=20972 qp=0 dt=967/1/0 df=58 of=0 ri=0 ql=634 qs=NRW. kt=0/W/1 ktl=58c b=10 ci=191037 co=0 ca=0
+  2 c=20972 g=20973 pq=1 pqc=20972 qp=0 dt=1081/1/0 df=175 of=0 ri=0 ql=74 qs=N.W. kt=0/W/2 ktl=da94 b=10 ci=75991 co=0 ca=0
+  3 c=20942 g=20943 pq=1 pqc=20942 qp=1 dt=1846/0/0 df=404 of=0 ri=0 ql=0 qs=.... kt=0/W/3 ktl=d1cd b=10 ci=72261 co=0 ca=0
+  4 c=20972 g=20973 pq=1 pqc=20972 qp=0 dt=369/1/0 df=83 of=0 ri=0 ql=48 qs=N.W. kt=0/W/4 ktl=e0e7 b=10 ci=128365 co=0 ca=0
+  5 c=20972 g=20973 pq=1 pqc=20972 qp=0 dt=381/1/0 df=64 of=0 ri=0 ql=169 qs=NRW. kt=0/W/5 ktl=fb2f b=10 ci=164360 co=0 ca=0
+  6 c=20972 g=20973 pq=1 pqc=20972 qp=0 dt=1037/1/0 df=183 of=0 ri=0 ql=62 qs=N.W. kt=0/W/6 ktl=d2ad b=10 ci=65663 co=0 ca=0
+  7 c=20897 g=20897 pq=1 pqc=20896 qp=0 dt=1572/0/0 df=382 of=0 ri=0 ql=0 qs=.... kt=0/W/7 ktl=cf15 b=10 ci=75006 co=0 ca=0
 rcu_bh:
-  0 c=-275 g=-275 pq=1 pqc=-275 qp=0 dt=10951/1 dn=0 df=0 of=0 ri=0 ql=0 b=10
-  1 c=-275 g=-275 pq=1 pqc=-275 qp=0 dt=16117/1 dn=0 df=13 of=0 ri=0 ql=0 b=10
-  2 c=-275 g=-275 pq=1 pqc=-275 qp=0 dt=1445/1 dn=0 df=15 of=0 ri=0 ql=0 b=10
-  3 c=-275 g=-275 pq=1 pqc=-275 qp=0 dt=6681/1 dn=0 df=9 of=0 ri=0 ql=0 b=10
-  4 c=-275 g=-275 pq=1 pqc=-275 qp=0 dt=1003/1 dn=0 df=15 of=0 ri=0 ql=0 b=10
-  5 c=-275 g=-275 pq=1 pqc=-275 qp=0 dt=3887/1 dn=0 df=15 of=0 ri=0 ql=0 b=10
-  6 c=-275 g=-275 pq=1 pqc=-275 qp=0 dt=859/1 dn=0 df=15 of=0 ri=0 ql=0 b=10
-  7 c=-275 g=-275 pq=1 pqc=-275 qp=0 dt=3761/1 dn=0 df=15 of=0 ri=0 ql=0 b=10
+  0 c=1480 g=1480 pq=1 pqc=1479 qp=0 dt=545/1/0 df=6 of=0 ri=1 ql=0 qs=.... kt=0/W/0 ktl=ebc3 b=10 ci=0 co=0 ca=0
+  1 c=1480 g=1480 pq=1 pqc=1479 qp=0 dt=967/1/0 df=3 of=0 ri=1 ql=0 qs=.... kt=0/W/1 ktl=58c b=10 ci=151 co=0 ca=0
+  2 c=1480 g=1480 pq=1 pqc=1479 qp=0 dt=1081/1/0 df=6 of=0 ri=1 ql=0 qs=.... kt=0/W/2 ktl=da94 b=10 ci=0 co=0 ca=0
+  3 c=1480 g=1480 pq=1 pqc=1479 qp=0 dt=1846/0/0 df=8 of=0 ri=1 ql=0 qs=.... kt=0/W/3 ktl=d1cd b=10 ci=0 co=0 ca=0
+  4 c=1480 g=1480 pq=1 pqc=1479 qp=0 dt=369/1/0 df=6 of=0 ri=1 ql=0 qs=.... kt=0/W/4 ktl=e0e7 b=10 ci=0 co=0 ca=0
+  5 c=1480 g=1480 pq=1 pqc=1479 qp=0 dt=381/1/0 df=4 of=0 ri=1 ql=0 qs=.... kt=0/W/5 ktl=fb2f b=10 ci=0 co=0 ca=0
+  6 c=1480 g=1480 pq=1 pqc=1479 qp=0 dt=1037/1/0 df=6 of=0 ri=1 ql=0 qs=.... kt=0/W/6 ktl=d2ad b=10 ci=0 co=0 ca=0
+  7 c=1474 g=1474 pq=1 pqc=1473 qp=0 dt=1572/0/0 df=8 of=0 ri=1 ql=0 qs=.... kt=0/W/7 ktl=cf15 b=10 ci=0 co=0 ca=0
 
 The first section lists the rcu_data structures for rcu_sched, the second
 for rcu_bh.  Note that CONFIG_TREE_PREEMPT_RCU kernels will have an
@@ -52,17 +64,18 @@
 	substantially larger than the number of actual CPUs.
 
 o	"c" is the count of grace periods that this CPU believes have
-	completed.  CPUs in dynticks idle mode may lag quite a ways
-	behind, for example, CPU 4 under "rcu_sched" above, which has
-	slept through the past 25 RCU grace periods.  It is not unusual
-	to see CPUs lagging by thousands of grace periods.
+	completed.  Offlined CPUs and CPUs in dynticks idle mode may
+	lag quite a ways behind, for example, CPU 6 under "rcu_sched"
+	above, which has been offline through not quite 40,000 RCU grace
+	periods.  It is not unusual to see CPUs lagging by thousands of
+	grace periods.
 
 o	"g" is the count of grace periods that this CPU believes have
-	started.  Again, CPUs in dynticks idle mode may lag behind.
-	If the "c" and "g" values are equal, this CPU has already
-	reported a quiescent state for the last RCU grace period that
-	it is aware of, otherwise, the CPU believes that it owes RCU a
-	quiescent state.
+	started.  Again, offlined CPUs and CPUs in dynticks idle mode
+	may lag behind.  If the "c" and "g" values are equal, this CPU
+	has already reported a quiescent state for the last RCU grace
+	period that it is aware of, otherwise, the CPU believes that it
+	owes RCU a quiescent state.
 
 o	"pq" indicates that this CPU has passed through a quiescent state
 	for the current grace period.  It is possible for "pq" to be
@@ -81,22 +94,16 @@
 	the next grace period!
 
 o	"qp" indicates that RCU still expects a quiescent state from
-	this CPU.
+	this CPU.  Offlined CPUs and CPUs in dyntick idle mode might
+	well have qp=1, which is OK: RCU is still ignoring them.
 
 o	"dt" is the current value of the dyntick counter that is incremented
 	when entering or leaving dynticks idle state, either by the
-	scheduler or by irq.  The number after the "/" is the interrupt
-	nesting depth when in dyntick-idle state, or one greater than
-	the interrupt-nesting depth otherwise.
-
-	This field is displayed only for CONFIG_NO_HZ kernels.
-
-o	"dn" is the current value of the dyntick counter that is incremented
-	when entering or leaving dynticks idle state via NMI.  If both
-	the "dt" and "dn" values are even, then this CPU is in dynticks
-	idle mode and may be ignored by RCU.  If either of these two
-	counters is odd, then RCU must be alert to the possibility of
-	an RCU read-side critical section running on this CPU.
+	scheduler or by irq.  This number is even if the CPU is in
+	dyntick idle mode and odd otherwise.  The number after the first
+	"/" is the interrupt nesting depth when in dyntick-idle state,
+	or one greater than the interrupt-nesting depth otherwise.
+	The number after the second "/" is the NMI nesting depth.
 
 	This field is displayed only for CONFIG_NO_HZ kernels.
 
@@ -108,7 +115,7 @@
 
 o	"of" is the number of times that some other CPU has forced a
 	quiescent state on behalf of this CPU due to this CPU being
-	offline.  In a perfect world, this might neve happen, but it
+	offline.  In a perfect world, this might never happen, but it
 	turns out that offlining and onlining a CPU can take several grace
 	periods, and so there is likely to be an extended period of time
 	when RCU believes that the CPU is online when it really is not.
@@ -125,6 +132,62 @@
 	of what state they are in (new, waiting for grace period to
 	start, waiting for grace period to end, ready to invoke).
 
+o	"qs" gives an indication of the state of the callback queue
+	with four characters:
+
+	"N"	Indicates that there are callbacks queued that are not
+		ready to be handled by the next grace period, and thus
+		will be handled by the grace period following the next
+		one.
+
+	"R"	Indicates that there are callbacks queued that are
+		ready to be handled by the next grace period.
+
+	"W"	Indicates that there are callbacks queued that are
+		waiting on the current grace period.
+
+	"D"	Indicates that there are callbacks queued that have
+		already been handled by a prior grace period, and are
+		thus waiting to be invoked.  Note that callbacks in
+		the process of being invoked are not counted here.
+		Callbacks in the process of being invoked are those
+		that have been removed from the rcu_data structures
+		queues by rcu_do_batch(), but which have not yet been
+		invoked.
+
+	If there are no callbacks in a given one of the above states,
+	the corresponding character is replaced by ".".
+
+o	"kt" is the per-CPU kernel-thread state.  The digit preceding
+	the first slash is zero if there is no work pending and 1
+	otherwise.  The character between the first pair of slashes is
+	as follows:
+
+	"S"	The kernel thread is stopped, in other words, all
+		CPUs corresponding to this rcu_node structure are
+		offline.
+
+	"R"	The kernel thread is running.
+
+	"W"	The kernel thread is waiting because there is no work
+		for it to do.
+
+	"O"	The kernel thread is waiting because it has been
+		forced off of its designated CPU or because its
+		->cpus_allowed mask permits it to run on other than
+		its designated CPU.
+
+	"Y"	The kernel thread is yielding to avoid hogging CPU.
+
+	"?"	Unknown value, indicates a bug.
+
+	The number after the final slash is the CPU that the kthread
+	is actually running on.
+
+o	"ktl" is the low-order 16 bits (in hexadecimal) of the count of
+	the number of times that this CPU's per-CPU kthread has gone
+	through its loop servicing invoke_rcu_cpu_kthread() requests.
+
 o	"b" is the batch limit for this CPU.  If more than this number
 	of RCU callbacks is ready to invoke, then the remainder will
 	be deferred.
@@ -174,14 +237,14 @@
 The output of "cat rcu/rcuhier" looks as follows, with very long lines:
 
 c=6902 g=6903 s=2 jfq=3 j=72c7 nfqs=13142/nfqsng=0(13142) fqlh=6
-1/1 .>. 0:127 ^0    
-3/3 .>. 0:35 ^0    0/0 .>. 36:71 ^1    0/0 .>. 72:107 ^2    0/0 .>. 108:127 ^3    
-3/3f .>. 0:5 ^0    2/3 .>. 6:11 ^1    0/0 .>. 12:17 ^2    0/0 .>. 18:23 ^3    0/0 .>. 24:29 ^4    0/0 .>. 30:35 ^5    0/0 .>. 36:41 ^0    0/0 .>. 42:47 ^1    0/0 .>. 48:53 ^2    0/0 .>. 54:59 ^3    0/0 .>. 60:65 ^4    0/0 .>. 66:71 ^5    0/0 .>. 72:77 ^0    0/0 .>. 78:83 ^1    0/0 .>. 84:89 ^2    0/0 .>. 90:95 ^3    0/0 .>. 96:101 ^4    0/0 .>. 102:107 ^5    0/0 .>. 108:113 ^0    0/0 .>. 114:119 ^1    0/0 .>. 120:125 ^2    0/0 .>. 126:127 ^3    
+1/1 ..>. 0:127 ^0
+3/3 ..>. 0:35 ^0    0/0 ..>. 36:71 ^1    0/0 ..>. 72:107 ^2    0/0 ..>. 108:127 ^3
+3/3f ..>. 0:5 ^0    2/3 ..>. 6:11 ^1    0/0 ..>. 12:17 ^2    0/0 ..>. 18:23 ^3    0/0 ..>. 24:29 ^4    0/0 ..>. 30:35 ^5    0/0 ..>. 36:41 ^0    0/0 ..>. 42:47 ^1    0/0 ..>. 48:53 ^2    0/0 ..>. 54:59 ^3    0/0 ..>. 60:65 ^4    0/0 ..>. 66:71 ^5    0/0 ..>. 72:77 ^0    0/0 ..>. 78:83 ^1    0/0 ..>. 84:89 ^2    0/0 ..>. 90:95 ^3    0/0 ..>. 96:101 ^4    0/0 ..>. 102:107 ^5    0/0 ..>. 108:113 ^0    0/0 ..>. 114:119 ^1    0/0 ..>. 120:125 ^2    0/0 ..>. 126:127 ^3
 rcu_bh:
 c=-226 g=-226 s=1 jfq=-5701 j=72c7 nfqs=88/nfqsng=0(88) fqlh=0
-0/1 .>. 0:127 ^0    
-0/3 .>. 0:35 ^0    0/0 .>. 36:71 ^1    0/0 .>. 72:107 ^2    0/0 .>. 108:127 ^3    
-0/3f .>. 0:5 ^0    0/3 .>. 6:11 ^1    0/0 .>. 12:17 ^2    0/0 .>. 18:23 ^3    0/0 .>. 24:29 ^4    0/0 .>. 30:35 ^5    0/0 .>. 36:41 ^0    0/0 .>. 42:47 ^1    0/0 .>. 48:53 ^2    0/0 .>. 54:59 ^3    0/0 .>. 60:65 ^4    0/0 .>. 66:71 ^5    0/0 .>. 72:77 ^0    0/0 .>. 78:83 ^1    0/0 .>. 84:89 ^2    0/0 .>. 90:95 ^3    0/0 .>. 96:101 ^4    0/0 .>. 102:107 ^5    0/0 .>. 108:113 ^0    0/0 .>. 114:119 ^1    0/0 .>. 120:125 ^2    0/0 .>. 126:127 ^3
+0/1 ..>. 0:127 ^0
+0/3 ..>. 0:35 ^0    0/0 ..>. 36:71 ^1    0/0 ..>. 72:107 ^2    0/0 ..>. 108:127 ^3
+0/3f ..>. 0:5 ^0    0/3 ..>. 6:11 ^1    0/0 ..>. 12:17 ^2    0/0 ..>. 18:23 ^3    0/0 ..>. 24:29 ^4    0/0 ..>. 30:35 ^5    0/0 ..>. 36:41 ^0    0/0 ..>. 42:47 ^1    0/0 ..>. 48:53 ^2    0/0 ..>. 54:59 ^3    0/0 ..>. 60:65 ^4    0/0 ..>. 66:71 ^5    0/0 ..>. 72:77 ^0    0/0 ..>. 78:83 ^1    0/0 ..>. 84:89 ^2    0/0 ..>. 90:95 ^3    0/0 ..>. 96:101 ^4    0/0 ..>. 102:107 ^5    0/0 ..>. 108:113 ^0    0/0 ..>. 114:119 ^1    0/0 ..>. 120:125 ^2    0/0 ..>. 126:127 ^3
 
 This is once again split into "rcu_sched" and "rcu_bh" portions,
 and CONFIG_TREE_PREEMPT_RCU kernels will again have an additional
@@ -240,13 +303,20 @@
 		current grace period.
 
 	o	The characters separated by the ">" indicate the state
-		of the blocked-tasks lists.  A "T" preceding the ">"
+		of the blocked-tasks lists.  A "G" preceding the ">"
 		indicates that at least one task blocked in an RCU
 		read-side critical section blocks the current grace
-		period, while a "." preceding the ">" indicates otherwise.
-		The character following the ">" indicates similarly for
-		the next grace period.  A "T" should appear in this
-		field only for rcu-preempt.
+		period, while a "E" preceding the ">" indicates that
+		at least one task blocked in an RCU read-side critical
+		section blocks the current expedited grace period.
+		A "T" character following the ">" indicates that at
+		least one task is blocked within an RCU read-side
+		critical section, regardless of whether any current
+		grace period (expedited or normal) is inconvenienced.
+		A "." character appears if the corresponding condition
+		does not hold, so that "..>." indicates that no tasks
+		are blocked.  In contrast, "GE>T" indicates maximal
+		inconvenience from blocked tasks.
 
 	o	The numbers separated by the ":" are the range of CPUs
 		served by this struct rcu_node.  This can be helpful
@@ -328,6 +398,113 @@
 	is due to short-circuit evaluation in rcu_pending().
 
 
+The output of "cat rcu/rcutorture" looks as follows:
+
+rcutorture test sequence: 0 (test in progress)
+rcutorture update version number: 615
+
+The first line shows the number of rcutorture tests that have completed
+since boot.  If a test is currently running, the "(test in progress)"
+string will appear as shown above.  The second line shows the number of
+update cycles that the current test has started, or zero if there is
+no test in progress.
+
+
+The output of "cat rcu/rcuboost" looks as follows:
+
+0:5 tasks=.... kt=W ntb=0 neb=0 nnb=0 j=2f95 bt=300f
+     balk: nt=0 egt=989 bt=0 nb=0 ny=0 nos=16
+6:7 tasks=.... kt=W ntb=0 neb=0 nnb=0 j=2f95 bt=300f
+     balk: nt=0 egt=225 bt=0 nb=0 ny=0 nos=6
+
+This information is output only for rcu_preempt.  Each two-line entry
+corresponds to a leaf rcu_node strcuture.  The fields are as follows:
+
+o	"n:m" is the CPU-number range for the corresponding two-line
+	entry.  In the sample output above, the first entry covers
+	CPUs zero through five and the second entry covers CPUs 6
+	and 7.
+
+o	"tasks=TNEB" gives the state of the various segments of the
+	rnp->blocked_tasks list:
+
+	"T"	This indicates that there are some tasks that blocked
+		while running on one of the corresponding CPUs while
+		in an RCU read-side critical section.
+
+	"N"	This indicates that some of the blocked tasks are preventing
+		the current normal (non-expedited) grace period from
+		completing.
+
+	"E"	This indicates that some of the blocked tasks are preventing
+		the current expedited grace period from completing.
+
+	"B"	This indicates that some of the blocked tasks are in
+		need of RCU priority boosting.
+
+	Each character is replaced with "." if the corresponding
+	condition does not hold.
+
+o	"kt" is the state of the RCU priority-boosting kernel
+	thread associated with the corresponding rcu_node structure.
+	The state can be one of the following:
+
+	"S"	The kernel thread is stopped, in other words, all
+		CPUs corresponding to this rcu_node structure are
+		offline.
+
+	"R"	The kernel thread is running.
+
+	"W"	The kernel thread is waiting because there is no work
+		for it to do.
+
+	"Y"	The kernel thread is yielding to avoid hogging CPU.
+
+	"?"	Unknown value, indicates a bug.
+
+o	"ntb" is the number of tasks boosted.
+
+o	"neb" is the number of tasks boosted in order to complete an
+	expedited grace period.
+
+o	"nnb" is the number of tasks boosted in order to complete a
+	normal (non-expedited) grace period.  When boosting a task
+	that was blocking both an expedited and a normal grace period,
+	it is counted against the expedited total above.
+
+o	"j" is the low-order 16 bits of the jiffies counter in
+	hexadecimal.
+
+o	"bt" is the low-order 16 bits of the value that the jiffies
+	counter will have when we next start boosting, assuming that
+	the current grace period does not end beforehand.  This is
+	also in hexadecimal.
+
+o	"balk: nt" counts the number of times we didn't boost (in
+	other words, we balked) even though it was time to boost because
+	there were no blocked tasks to boost.  This situation occurs
+	when there is one blocked task on one rcu_node structure and
+	none on some other rcu_node structure.
+
+o	"egt" counts the number of times we balked because although
+	there were blocked tasks, none of them were blocking the
+	current grace period, whether expedited or otherwise.
+
+o	"bt" counts the number of times we balked because boosting
+	had already been initiated for the current grace period.
+
+o	"nb" counts the number of times we balked because there
+	was at least one task blocking the current non-expedited grace
+	period that never had blocked.  If it is already running, it
+	just won't help to boost its priority!
+
+o	"ny" counts the number of times we balked because it was
+	not yet time to start boosting.
+
+o	"nos" counts the number of times we balked for other
+	reasons, e.g., the grace period ended first.
+
+
 CONFIG_TINY_RCU and CONFIG_TINY_PREEMPT_RCU debugfs Files and Formats
 
 These implementations of RCU provides a single debugfs file under the
@@ -394,9 +571,9 @@
 o	"nnb" is the number of normal grace periods that have had
 	to resort to RCU priority boosting since boot.
 
-o	"j" is the low-order 12 bits of the jiffies counter in hexadecimal.
+o	"j" is the low-order 16 bits of the jiffies counter in hexadecimal.
 
-o	"bt" is the low-order 12 bits of the value that the jiffies counter
+o	"bt" is the low-order 16 bits of the value that the jiffies counter
 	will have at the next time that boosting is scheduled to begin.
 
 o	In the line beginning with "normal balk", the fields are as follows:
diff -druN linux-2.6.39-libre/Documentation/scheduler/sched-design-CFS.txt linux-3.0-rc7-libre/Documentation/scheduler/sched-design-CFS.txt
--- linux-2.6.39-libre/Documentation/scheduler/sched-design-CFS.txt	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/Documentation/scheduler/sched-design-CFS.txt	2011-07-11 19:51:52.000000000 -0400
@@ -223,9 +223,10 @@
 group created using the pseudo filesystem.  See example steps below to create
 task groups and modify their CPU share using the "cgroups" pseudo filesystem.
 
-	# mkdir /dev/cpuctl
-	# mount -t cgroup -ocpu none /dev/cpuctl
-	# cd /dev/cpuctl
+	# mount -t tmpfs cgroup_root /sys/fs/cgroup
+	# mkdir /sys/fs/cgroup/cpu
+	# mount -t cgroup -ocpu none /sys/fs/cgroup/cpu
+	# cd /sys/fs/cgroup/cpu
 
 	# mkdir multimedia	# create "multimedia" group of tasks
 	# mkdir browser		# create "browser" group of tasks
diff -druN linux-2.6.39-libre/Documentation/scheduler/sched-rt-group.txt linux-3.0-rc7-libre/Documentation/scheduler/sched-rt-group.txt
--- linux-2.6.39-libre/Documentation/scheduler/sched-rt-group.txt	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/Documentation/scheduler/sched-rt-group.txt	2011-07-11 19:51:52.000000000 -0400
@@ -129,9 +129,8 @@
 Enabling CONFIG_RT_GROUP_SCHED lets you explicitly allocate real
 CPU bandwidth to task groups.
 
-This uses the /cgroup virtual file system and
-"/cgroup/<cgroup>/cpu.rt_runtime_us" to control the CPU time reserved for each
-control group.
+This uses the cgroup virtual file system and "<cgroup>/cpu.rt_runtime_us"
+to control the CPU time reserved for each control group.
 
 For more information on working with control groups, you should read
 Documentation/cgroups/cgroups.txt as well.
@@ -150,7 +149,7 @@
 ===============
 
 There is work in progress to make the scheduling period for each group
-("/cgroup/<cgroup>/cpu.rt_period_us") configurable as well.
+("<cgroup>/cpu.rt_period_us") configurable as well.
 
 The constraint on the period is that a subgroup must have a smaller or
 equal period to its parent. But realistically its not very useful _yet_
diff -druN linux-2.6.39-libre/Documentation/scsi/ChangeLog.megaraid_sas linux-3.0-rc7-libre/Documentation/scsi/ChangeLog.megaraid_sas
--- linux-2.6.39-libre/Documentation/scsi/ChangeLog.megaraid_sas	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/Documentation/scsi/ChangeLog.megaraid_sas	2011-07-11 19:51:52.000000000 -0400
@@ -1,3 +1,17 @@
+Release Date    : Wed. May 11, 2011 17:00:00 PST 2010 -
+			(emaild-id:megaraidlinux@lsi.com)
+			Adam Radford
+Current Version : 00.00.05.38-rc1
+Old Version     : 00.00.05.34-rc1
+    1. Remove MSI-X black list, use MFI_REG_STATE.ready.msiEnable.
+    2. Remove un-used function megasas_return_cmd_for_smid().
+    3. Check MFI_REG_STATE.fault.resetAdapter in megasas_reset_fusion().
+    4. Disable interrupts/free_irq() in megasas_shutdown().
+    5. Fix bug where AENs could be lost in probe() and resume().
+    6. Convert 6,10,12 byte CDB's to 16 byte CDB for large LBA's for FastPath
+       IO.
+    7. Add 1078 OCR support.
+-------------------------------------------------------------------------------
 Release Date    : Thu. Feb 24, 2011 17:00:00 PST 2010 -
 			(emaild-id:megaraidlinux@lsi.com)
 			Adam Radford
diff -druN linux-2.6.39-libre/Documentation/scsi/LICENSE.qla2xxx linux-3.0-rc7-libre/Documentation/scsi/LICENSE.qla2xxx
--- linux-2.6.39-libre/Documentation/scsi/LICENSE.qla2xxx	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/Documentation/scsi/LICENSE.qla2xxx	2011-07-11 19:51:52.000000000 -0400
@@ -1,11 +1,11 @@
-Copyright (c)  2003-2005 QLogic Corporation
-QLogic Linux Fibre Channel HBA Driver
+Copyright (c) 2003-2011 QLogic Corporation
+QLogic Linux/ESX Fibre Channel HBA Driver
 
-This program includes a device driver for Linux 2.6 that may be
+This program includes a device driver for Linux 2.6/ESX that may be
 distributed with QLogic hardware specific firmware binary file.
 You may modify and redistribute the device driver code under the
-GNU General Public License as published by the Free Software
-Foundation (version 2 or a later version).
+GNU General Public License (a copy of which is attached hereto as
+Exhibit A) published by the Free Software Foundation (version 2).
 
 You may redistribute the hardware specific firmware binary file
 under the following terms:
@@ -43,3 +43,285 @@
 TRADE SECRET, MASK WORK, OR OTHER PROPRIETARY RIGHT) EMBODIED IN
 ANY OTHER QLOGIC HARDWARE OR SOFTWARE EITHER SOLELY OR IN
 COMBINATION WITH THIS PROGRAM.
+
+
+EXHIBIT A
+
+		    GNU GENERAL PUBLIC LICENSE
+		       Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+ 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+			    Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users.  This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it.  (Some other Free Software Foundation software is covered by
+the GNU Lesser General Public License instead.)  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+  To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have.  You must make sure that they, too, receive or can get the
+source code.  And you must show them these terms so they know their
+rights.
+
+  We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+  Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software.  If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+  Finally, any free program is threatened constantly by software
+patents.  We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary.  To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+		    GNU GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License.  The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language.  (Hereinafter, translation is included without limitation in
+the term "modification".)  Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+  1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+  2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) You must cause the modified files to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    b) You must cause any work that you distribute or publish, that in
+    whole or in part contains or is derived from the Program or any
+    part thereof, to be licensed as a whole at no charge to all third
+    parties under the terms of this License.
+
+    c) If the modified program normally reads commands interactively
+    when run, you must cause it, when started running for such
+    interactive use in the most ordinary way, to print or display an
+    announcement including an appropriate copyright notice and a
+    notice that there is no warranty (or else, saying that you provide
+    a warranty) and that users may redistribute the program under
+    these conditions, and telling the user how to view a copy of this
+    License.  (Exception: if the Program itself is interactive but
+    does not normally print such an announcement, your work based on
+    the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+    a) Accompany it with the complete corresponding machine-readable
+    source code, which must be distributed under the terms of Sections
+    1 and 2 above on a medium customarily used for software interchange; or,
+
+    b) Accompany it with a written offer, valid for at least three
+    years, to give any third party, for a charge no more than your
+    cost of physically performing source distribution, a complete
+    machine-readable copy of the corresponding source code, to be
+    distributed under the terms of Sections 1 and 2 above on a medium
+    customarily used for software interchange; or,
+
+    c) Accompany it with the information you received as to the offer
+    to distribute corresponding source code.  (This alternative is
+    allowed only for noncommercial distribution and only if you
+    received the program in object code or executable form with such
+    an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it.  For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable.  However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License.  Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+  5. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Program or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+  6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+  7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded.  In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+  9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation.  If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+  10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission.  For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this.  Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+			    NO WARRANTY
+
+  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
diff -druN linux-2.6.39-libre/Documentation/security/00-INDEX linux-3.0-rc7-libre/Documentation/security/00-INDEX
--- linux-2.6.39-libre/Documentation/security/00-INDEX	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/Documentation/security/00-INDEX	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,18 @@
+00-INDEX
+	- this file.
+SELinux.txt
+	- how to get started with the SELinux security enhancement.
+Smack.txt
+	- documentation on the Smack Linux Security Module.
+apparmor.txt
+	- documentation on the AppArmor security extension.
+credentials.txt
+	- documentation about credentials in Linux.
+keys-request-key.txt
+	- description of the kernel key request service.
+keys-trusted-encrypted.txt
+	- info on the Trusted and Encrypted keys in the kernel key ring service.
+keys.txt
+	- description of the kernel key retention service.
+tomoyo.txt
+	- documentation on the TOMOYO Linux Security Module.
diff -druN linux-2.6.39-libre/Documentation/security/apparmor.txt linux-3.0-rc7-libre/Documentation/security/apparmor.txt
--- linux-2.6.39-libre/Documentation/security/apparmor.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/Documentation/security/apparmor.txt	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,39 @@
+--- What is AppArmor? ---
+
+AppArmor is MAC style security extension for the Linux kernel.  It implements
+a task centered policy, with task "profiles" being created and loaded
+from user space.  Tasks on the system that do not have a profile defined for
+them run in an unconfined state which is equivalent to standard Linux DAC
+permissions.
+
+--- How to enable/disable ---
+
+set CONFIG_SECURITY_APPARMOR=y
+
+If AppArmor should be selected as the default security module then
+   set CONFIG_DEFAULT_SECURITY="apparmor"
+   and CONFIG_SECURITY_APPARMOR_BOOTPARAM_VALUE=1
+
+Build the kernel
+
+If AppArmor is not the default security module it can be enabled by passing
+security=apparmor on the kernel's command line.
+
+If AppArmor is the default security module it can be disabled by passing
+apparmor=0, security=XXXX (where XXX is valid security module), on the
+kernel's command line
+
+For AppArmor to enforce any restrictions beyond standard Linux DAC permissions
+policy must be loaded into the kernel from user space (see the Documentation
+and tools links).
+
+--- Documentation ---
+
+Documentation can be found on the wiki.
+
+--- Links ---
+
+Mailing List - apparmor@lists.ubuntu.com
+Wiki - http://apparmor.wiki.kernel.org/
+User space tools - https://launchpad.net/apparmor
+Kernel module - git://git.kernel.org/pub/scm/linux/kernel/git/jj/apparmor-dev.git
diff -druN linux-2.6.39-libre/Documentation/security/credentials.txt linux-3.0-rc7-libre/Documentation/security/credentials.txt
--- linux-2.6.39-libre/Documentation/security/credentials.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/Documentation/security/credentials.txt	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,581 @@
+			     ====================
+			     CREDENTIALS IN LINUX
+			     ====================
+
+By: David Howells <dhowells@redhat.com>
+
+Contents:
+
+ (*) Overview.
+
+ (*) Types of credentials.
+
+ (*) File markings.
+
+ (*) Task credentials.
+
+     - Immutable credentials.
+     - Accessing task credentials.
+     - Accessing another task's credentials.
+     - Altering credentials.
+     - Managing credentials.
+
+ (*) Open file credentials.
+
+ (*) Overriding the VFS's use of credentials.
+
+
+========
+OVERVIEW
+========
+
+There are several parts to the security check performed by Linux when one
+object acts upon another:
+
+ (1) Objects.
+
+     Objects are things in the system that may be acted upon directly by
+     userspace programs.  Linux has a variety of actionable objects, including:
+
+	- Tasks
+	- Files/inodes
+	- Sockets
+	- Message queues
+	- Shared memory segments
+	- Semaphores
+	- Keys
+
+     As a part of the description of all these objects there is a set of
+     credentials.  What's in the set depends on the type of object.
+
+ (2) Object ownership.
+
+     Amongst the credentials of most objects, there will be a subset that
+     indicates the ownership of that object.  This is used for resource
+     accounting and limitation (disk quotas and task rlimits for example).
+
+     In a standard UNIX filesystem, for instance, this will be defined by the
+     UID marked on the inode.
+
+ (3) The objective context.
+
+     Also amongst the credentials of those objects, there will be a subset that
+     indicates the 'objective context' of that object.  This may or may not be
+     the same set as in (2) - in standard UNIX files, for instance, this is the
+     defined by the UID and the GID marked on the inode.
+
+     The objective context is used as part of the security calculation that is
+     carried out when an object is acted upon.
+
+ (4) Subjects.
+
+     A subject is an object that is acting upon another object.
+
+     Most of the objects in the system are inactive: they don't act on other
+     objects within the system.  Processes/tasks are the obvious exception:
+     they do stuff; they access and manipulate things.
+
+     Objects other than tasks may under some circumstances also be subjects.
+     For instance an open file may send SIGIO to a task using the UID and EUID
+     given to it by a task that called fcntl(F_SETOWN) upon it.  In this case,
+     the file struct will have a subjective context too.
+
+ (5) The subjective context.
+
+     A subject has an additional interpretation of its credentials.  A subset
+     of its credentials forms the 'subjective context'.  The subjective context
+     is used as part of the security calculation that is carried out when a
+     subject acts.
+
+     A Linux task, for example, has the FSUID, FSGID and the supplementary
+     group list for when it is acting upon a file - which are quite separate
+     from the real UID and GID that normally form the objective context of the
+     task.
+
+ (6) Actions.
+
+     Linux has a number of actions available that a subject may perform upon an
+     object.  The set of actions available depends on the nature of the subject
+     and the object.
+
+     Actions include reading, writing, creating and deleting files; forking or
+     signalling and tracing tasks.
+
+ (7) Rules, access control lists and security calculations.
+
+     When a subject acts upon an object, a security calculation is made.  This
+     involves taking the subjective context, the objective context and the
+     action, and searching one or more sets of rules to see whether the subject
+     is granted or denied permission to act in the desired manner on the
+     object, given those contexts.
+
+     There are two main sources of rules:
+
+     (a) Discretionary access control (DAC):
+
+	 Sometimes the object will include sets of rules as part of its
+	 description.  This is an 'Access Control List' or 'ACL'.  A Linux
+	 file may supply more than one ACL.
+
+	 A traditional UNIX file, for example, includes a permissions mask that
+	 is an abbreviated ACL with three fixed classes of subject ('user',
+	 'group' and 'other'), each of which may be granted certain privileges
+	 ('read', 'write' and 'execute' - whatever those map to for the object
+	 in question).  UNIX file permissions do not allow the arbitrary
+	 specification of subjects, however, and so are of limited use.
+
+	 A Linux file might also sport a POSIX ACL.  This is a list of rules
+	 that grants various permissions to arbitrary subjects.
+
+     (b) Mandatory access control (MAC):
+
+	 The system as a whole may have one or more sets of rules that get
+	 applied to all subjects and objects, regardless of their source.
+	 SELinux and Smack are examples of this.
+
+	 In the case of SELinux and Smack, each object is given a label as part
+	 of its credentials.  When an action is requested, they take the
+	 subject label, the object label and the action and look for a rule
+	 that says that this action is either granted or denied.
+
+
+====================
+TYPES OF CREDENTIALS
+====================
+
+The Linux kernel supports the following types of credentials:
+
+ (1) Traditional UNIX credentials.
+
+	Real User ID
+	Real Group ID
+
+     The UID and GID are carried by most, if not all, Linux objects, even if in
+     some cases it has to be invented (FAT or CIFS files for example, which are
+     derived from Windows).  These (mostly) define the objective context of
+     that object, with tasks being slightly different in some cases.
+
+	Effective, Saved and FS User ID
+	Effective, Saved and FS Group ID
+	Supplementary groups
+
+     These are additional credentials used by tasks only.  Usually, an
+     EUID/EGID/GROUPS will be used as the subjective context, and real UID/GID
+     will be used as the objective.  For tasks, it should be noted that this is
+     not always true.
+
+ (2) Capabilities.
+
+	Set of permitted capabilities
+	Set of inheritable capabilities
+	Set of effective capabilities
+	Capability bounding set
+
+     These are only carried by tasks.  They indicate superior capabilities
+     granted piecemeal to a task that an ordinary task wouldn't otherwise have.
+     These are manipulated implicitly by changes to the traditional UNIX
+     credentials, but can also be manipulated directly by the capset() system
+     call.
+
+     The permitted capabilities are those caps that the process might grant
+     itself to its effective or permitted sets through capset().  This
+     inheritable set might also be so constrained.
+
+     The effective capabilities are the ones that a task is actually allowed to
+     make use of itself.
+
+     The inheritable capabilities are the ones that may get passed across
+     execve().
+
+     The bounding set limits the capabilities that may be inherited across
+     execve(), especially when a binary is executed that will execute as UID 0.
+
+ (3) Secure management flags (securebits).
+
+     These are only carried by tasks.  These govern the way the above
+     credentials are manipulated and inherited over certain operations such as
+     execve().  They aren't used directly as objective or subjective
+     credentials.
+
+ (4) Keys and keyrings.
+
+     These are only carried by tasks.  They carry and cache security tokens
+     that don't fit into the other standard UNIX credentials.  They are for
+     making such things as network filesystem keys available to the file
+     accesses performed by processes, without the necessity of ordinary
+     programs having to know about security details involved.
+
+     Keyrings are a special type of key.  They carry sets of other keys and can
+     be searched for the desired key.  Each process may subscribe to a number
+     of keyrings:
+
+	Per-thread keying
+	Per-process keyring
+	Per-session keyring
+
+     When a process accesses a key, if not already present, it will normally be
+     cached on one of these keyrings for future accesses to find.
+
+     For more information on using keys, see Documentation/security/keys.txt.
+
+ (5) LSM
+
+     The Linux Security Module allows extra controls to be placed over the
+     operations that a task may do.  Currently Linux supports two main
+     alternate LSM options: SELinux and Smack.
+
+     Both work by labelling the objects in a system and then applying sets of
+     rules (policies) that say what operations a task with one label may do to
+     an object with another label.
+
+ (6) AF_KEY
+
+     This is a socket-based approach to credential management for networking
+     stacks [RFC 2367].  It isn't discussed by this document as it doesn't
+     interact directly with task and file credentials; rather it keeps system
+     level credentials.
+
+
+When a file is opened, part of the opening task's subjective context is
+recorded in the file struct created.  This allows operations using that file
+struct to use those credentials instead of the subjective context of the task
+that issued the operation.  An example of this would be a file opened on a
+network filesystem where the credentials of the opened file should be presented
+to the server, regardless of who is actually doing a read or a write upon it.
+
+
+=============
+FILE MARKINGS
+=============
+
+Files on disk or obtained over the network may have annotations that form the
+objective security context of that file.  Depending on the type of filesystem,
+this may include one or more of the following:
+
+ (*) UNIX UID, GID, mode;
+
+ (*) Windows user ID;
+
+ (*) Access control list;
+
+ (*) LSM security label;
+
+ (*) UNIX exec privilege escalation bits (SUID/SGID);
+
+ (*) File capabilities exec privilege escalation bits.
+
+These are compared to the task's subjective security context, and certain
+operations allowed or disallowed as a result.  In the case of execve(), the
+privilege escalation bits come into play, and may allow the resulting process
+extra privileges, based on the annotations on the executable file.
+
+
+================
+TASK CREDENTIALS
+================
+
+In Linux, all of a task's credentials are held in (uid, gid) or through
+(groups, keys, LSM security) a refcounted structure of type 'struct cred'.
+Each task points to its credentials by a pointer called 'cred' in its
+task_struct.
+
+Once a set of credentials has been prepared and committed, it may not be
+changed, barring the following exceptions:
+
+ (1) its reference count may be changed;
+
+ (2) the reference count on the group_info struct it points to may be changed;
+
+ (3) the reference count on the security data it points to may be changed;
+
+ (4) the reference count on any keyrings it points to may be changed;
+
+ (5) any keyrings it points to may be revoked, expired or have their security
+     attributes changed; and
+
+ (6) the contents of any keyrings to which it points may be changed (the whole
+     point of keyrings being a shared set of credentials, modifiable by anyone
+     with appropriate access).
+
+To alter anything in the cred struct, the copy-and-replace principle must be
+adhered to.  First take a copy, then alter the copy and then use RCU to change
+the task pointer to make it point to the new copy.  There are wrappers to aid
+with this (see below).
+
+A task may only alter its _own_ credentials; it is no longer permitted for a
+task to alter another's credentials.  This means the capset() system call is no
+longer permitted to take any PID other than the one of the current process.
+Also keyctl_instantiate() and keyctl_negate() functions no longer permit
+attachment to process-specific keyrings in the requesting process as the
+instantiating process may need to create them.
+
+
+IMMUTABLE CREDENTIALS
+---------------------
+
+Once a set of credentials has been made public (by calling commit_creds() for
+example), it must be considered immutable, barring two exceptions:
+
+ (1) The reference count may be altered.
+
+ (2) Whilst the keyring subscriptions of a set of credentials may not be
+     changed, the keyrings subscribed to may have their contents altered.
+
+To catch accidental credential alteration at compile time, struct task_struct
+has _const_ pointers to its credential sets, as does struct file.  Furthermore,
+certain functions such as get_cred() and put_cred() operate on const pointers,
+thus rendering casts unnecessary, but require to temporarily ditch the const
+qualification to be able to alter the reference count.
+
+
+ACCESSING TASK CREDENTIALS
+--------------------------
+
+A task being able to alter only its own credentials permits the current process
+to read or replace its own credentials without the need for any form of locking
+- which simplifies things greatly.  It can just call:
+
+	const struct cred *current_cred()
+
+to get a pointer to its credentials structure, and it doesn't have to release
+it afterwards.
+
+There are convenience wrappers for retrieving specific aspects of a task's
+credentials (the value is simply returned in each case):
+
+	uid_t current_uid(void)		Current's real UID
+	gid_t current_gid(void)		Current's real GID
+	uid_t current_euid(void)	Current's effective UID
+	gid_t current_egid(void)	Current's effective GID
+	uid_t current_fsuid(void)	Current's file access UID
+	gid_t current_fsgid(void)	Current's file access GID
+	kernel_cap_t current_cap(void)	Current's effective capabilities
+	void *current_security(void)	Current's LSM security pointer
+	struct user_struct *current_user(void)  Current's user account
+
+There are also convenience wrappers for retrieving specific associated pairs of
+a task's credentials:
+
+	void current_uid_gid(uid_t *, gid_t *);
+	void current_euid_egid(uid_t *, gid_t *);
+	void current_fsuid_fsgid(uid_t *, gid_t *);
+
+which return these pairs of values through their arguments after retrieving
+them from the current task's credentials.
+
+
+In addition, there is a function for obtaining a reference on the current
+process's current set of credentials:
+
+	const struct cred *get_current_cred(void);
+
+and functions for getting references to one of the credentials that don't
+actually live in struct cred:
+
+	struct user_struct *get_current_user(void);
+	struct group_info *get_current_groups(void);
+
+which get references to the current process's user accounting structure and
+supplementary groups list respectively.
+
+Once a reference has been obtained, it must be released with put_cred(),
+free_uid() or put_group_info() as appropriate.
+
+
+ACCESSING ANOTHER TASK'S CREDENTIALS
+------------------------------------
+
+Whilst a task may access its own credentials without the need for locking, the
+same is not true of a task wanting to access another task's credentials.  It
+must use the RCU read lock and rcu_dereference().
+
+The rcu_dereference() is wrapped by:
+
+	const struct cred *__task_cred(struct task_struct *task);
+
+This should be used inside the RCU read lock, as in the following example:
+
+	void foo(struct task_struct *t, struct foo_data *f)
+	{
+		const struct cred *tcred;
+		...
+		rcu_read_lock();
+		tcred = __task_cred(t);
+		f->uid = tcred->uid;
+		f->gid = tcred->gid;
+		f->groups = get_group_info(tcred->groups);
+		rcu_read_unlock();
+		...
+	}
+
+Should it be necessary to hold another task's credentials for a long period of
+time, and possibly to sleep whilst doing so, then the caller should get a
+reference on them using:
+
+	const struct cred *get_task_cred(struct task_struct *task);
+
+This does all the RCU magic inside of it.  The caller must call put_cred() on
+the credentials so obtained when they're finished with.
+
+ [*] Note: The result of __task_cred() should not be passed directly to
+     get_cred() as this may race with commit_cred().
+
+There are a couple of convenience functions to access bits of another task's
+credentials, hiding the RCU magic from the caller:
+
+	uid_t task_uid(task)		Task's real UID
+	uid_t task_euid(task)		Task's effective UID
+
+If the caller is holding the RCU read lock at the time anyway, then:
+
+	__task_cred(task)->uid
+	__task_cred(task)->euid
+
+should be used instead.  Similarly, if multiple aspects of a task's credentials
+need to be accessed, RCU read lock should be used, __task_cred() called, the
+result stored in a temporary pointer and then the credential aspects called
+from that before dropping the lock.  This prevents the potentially expensive
+RCU magic from being invoked multiple times.
+
+Should some other single aspect of another task's credentials need to be
+accessed, then this can be used:
+
+	task_cred_xxx(task, member)
+
+where 'member' is a non-pointer member of the cred struct.  For instance:
+
+	uid_t task_cred_xxx(task, suid);
+
+will retrieve 'struct cred::suid' from the task, doing the appropriate RCU
+magic.  This may not be used for pointer members as what they point to may
+disappear the moment the RCU read lock is dropped.
+
+
+ALTERING CREDENTIALS
+--------------------
+
+As previously mentioned, a task may only alter its own credentials, and may not
+alter those of another task.  This means that it doesn't need to use any
+locking to alter its own credentials.
+
+To alter the current process's credentials, a function should first prepare a
+new set of credentials by calling:
+
+	struct cred *prepare_creds(void);
+
+this locks current->cred_replace_mutex and then allocates and constructs a
+duplicate of the current process's credentials, returning with the mutex still
+held if successful.  It returns NULL if not successful (out of memory).
+
+The mutex prevents ptrace() from altering the ptrace state of a process whilst
+security checks on credentials construction and changing is taking place as
+the ptrace state may alter the outcome, particularly in the case of execve().
+
+The new credentials set should be altered appropriately, and any security
+checks and hooks done.  Both the current and the proposed sets of credentials
+are available for this purpose as current_cred() will return the current set
+still at this point.
+
+
+When the credential set is ready, it should be committed to the current process
+by calling:
+
+	int commit_creds(struct cred *new);
+
+This will alter various aspects of the credentials and the process, giving the
+LSM a chance to do likewise, then it will use rcu_assign_pointer() to actually
+commit the new credentials to current->cred, it will release
+current->cred_replace_mutex to allow ptrace() to take place, and it will notify
+the scheduler and others of the changes.
+
+This function is guaranteed to return 0, so that it can be tail-called at the
+end of such functions as sys_setresuid().
+
+Note that this function consumes the caller's reference to the new credentials.
+The caller should _not_ call put_cred() on the new credentials afterwards.
+
+Furthermore, once this function has been called on a new set of credentials,
+those credentials may _not_ be changed further.
+
+
+Should the security checks fail or some other error occur after prepare_creds()
+has been called, then the following function should be invoked:
+
+	void abort_creds(struct cred *new);
+
+This releases the lock on current->cred_replace_mutex that prepare_creds() got
+and then releases the new credentials.
+
+
+A typical credentials alteration function would look something like this:
+
+	int alter_suid(uid_t suid)
+	{
+		struct cred *new;
+		int ret;
+
+		new = prepare_creds();
+		if (!new)
+			return -ENOMEM;
+
+		new->suid = suid;
+		ret = security_alter_suid(new);
+		if (ret < 0) {
+			abort_creds(new);
+			return ret;
+		}
+
+		return commit_creds(new);
+	}
+
+
+MANAGING CREDENTIALS
+--------------------
+
+There are some functions to help manage credentials:
+
+ (*) void put_cred(const struct cred *cred);
+
+     This releases a reference to the given set of credentials.  If the
+     reference count reaches zero, the credentials will be scheduled for
+     destruction by the RCU system.
+
+ (*) const struct cred *get_cred(const struct cred *cred);
+
+     This gets a reference on a live set of credentials, returning a pointer to
+     that set of credentials.
+
+ (*) struct cred *get_new_cred(struct cred *cred);
+
+     This gets a reference on a set of credentials that is under construction
+     and is thus still mutable, returning a pointer to that set of credentials.
+
+
+=====================
+OPEN FILE CREDENTIALS
+=====================
+
+When a new file is opened, a reference is obtained on the opening task's
+credentials and this is attached to the file struct as 'f_cred' in place of
+'f_uid' and 'f_gid'.  Code that used to access file->f_uid and file->f_gid
+should now access file->f_cred->fsuid and file->f_cred->fsgid.
+
+It is safe to access f_cred without the use of RCU or locking because the
+pointer will not change over the lifetime of the file struct, and nor will the
+contents of the cred struct pointed to, barring the exceptions listed above
+(see the Task Credentials section).
+
+
+=======================================
+OVERRIDING THE VFS'S USE OF CREDENTIALS
+=======================================
+
+Under some circumstances it is desirable to override the credentials used by
+the VFS, and that can be done by calling into such as vfs_mkdir() with a
+different set of credentials.  This is done in the following places:
+
+ (*) sys_faccessat().
+
+ (*) do_coredump().
+
+ (*) nfs4recover.c.
diff -druN linux-2.6.39-libre/Documentation/security/keys-request-key.txt linux-3.0-rc7-libre/Documentation/security/keys-request-key.txt
--- linux-2.6.39-libre/Documentation/security/keys-request-key.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/Documentation/security/keys-request-key.txt	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,202 @@
+			      ===================
+			      KEY REQUEST SERVICE
+			      ===================
+
+The key request service is part of the key retention service (refer to
+Documentation/security/keys.txt).  This document explains more fully how
+the requesting algorithm works.
+
+The process starts by either the kernel requesting a service by calling
+request_key*():
+
+	struct key *request_key(const struct key_type *type,
+				const char *description,
+				const char *callout_info);
+
+or:
+
+	struct key *request_key_with_auxdata(const struct key_type *type,
+					     const char *description,
+					     const char *callout_info,
+					     size_t callout_len,
+					     void *aux);
+
+or:
+
+	struct key *request_key_async(const struct key_type *type,
+				      const char *description,
+				      const char *callout_info,
+				      size_t callout_len);
+
+or:
+
+	struct key *request_key_async_with_auxdata(const struct key_type *type,
+						   const char *description,
+						   const char *callout_info,
+					     	   size_t callout_len,
+						   void *aux);
+
+Or by userspace invoking the request_key system call:
+
+	key_serial_t request_key(const char *type,
+				 const char *description,
+				 const char *callout_info,
+				 key_serial_t dest_keyring);
+
+The main difference between the access points is that the in-kernel interface
+does not need to link the key to a keyring to prevent it from being immediately
+destroyed.  The kernel interface returns a pointer directly to the key, and
+it's up to the caller to destroy the key.
+
+The request_key*_with_auxdata() calls are like the in-kernel request_key*()
+calls, except that they permit auxiliary data to be passed to the upcaller (the
+default is NULL).  This is only useful for those key types that define their
+own upcall mechanism rather than using /sbin/request-key.
+
+The two async in-kernel calls may return keys that are still in the process of
+being constructed.  The two non-async ones will wait for construction to
+complete first.
+
+The userspace interface links the key to a keyring associated with the process
+to prevent the key from going away, and returns the serial number of the key to
+the caller.
+
+
+The following example assumes that the key types involved don't define their
+own upcall mechanisms.  If they do, then those should be substituted for the
+forking and execution of /sbin/request-key.
+
+
+===========
+THE PROCESS
+===========
+
+A request proceeds in the following manner:
+
+ (1) Process A calls request_key() [the userspace syscall calls the kernel
+     interface].
+
+ (2) request_key() searches the process's subscribed keyrings to see if there's
+     a suitable key there.  If there is, it returns the key.  If there isn't,
+     and callout_info is not set, an error is returned.  Otherwise the process
+     proceeds to the next step.
+
+ (3) request_key() sees that A doesn't have the desired key yet, so it creates
+     two things:
+
+     (a) An uninstantiated key U of requested type and description.
+
+     (b) An authorisation key V that refers to key U and notes that process A
+     	 is the context in which key U should be instantiated and secured, and
+     	 from which associated key requests may be satisfied.
+
+ (4) request_key() then forks and executes /sbin/request-key with a new session
+     keyring that contains a link to auth key V.
+
+ (5) /sbin/request-key assumes the authority associated with key U.
+
+ (6) /sbin/request-key execs an appropriate program to perform the actual
+     instantiation.
+
+ (7) The program may want to access another key from A's context (say a
+     Kerberos TGT key).  It just requests the appropriate key, and the keyring
+     search notes that the session keyring has auth key V in its bottom level.
+
+     This will permit it to then search the keyrings of process A with the
+     UID, GID, groups and security info of process A as if it was process A,
+     and come up with key W.
+
+ (8) The program then does what it must to get the data with which to
+     instantiate key U, using key W as a reference (perhaps it contacts a
+     Kerberos server using the TGT) and then instantiates key U.
+
+ (9) Upon instantiating key U, auth key V is automatically revoked so that it
+     may not be used again.
+
+(10) The program then exits 0 and request_key() deletes key V and returns key
+     U to the caller.
+
+This also extends further.  If key W (step 7 above) didn't exist, key W would
+be created uninstantiated, another auth key (X) would be created (as per step
+3) and another copy of /sbin/request-key spawned (as per step 4); but the
+context specified by auth key X will still be process A, as it was in auth key
+V.
+
+This is because process A's keyrings can't simply be attached to
+/sbin/request-key at the appropriate places because (a) execve will discard two
+of them, and (b) it requires the same UID/GID/Groups all the way through.
+
+
+====================================
+NEGATIVE INSTANTIATION AND REJECTION
+====================================
+
+Rather than instantiating a key, it is possible for the possessor of an
+authorisation key to negatively instantiate a key that's under construction.
+This is a short duration placeholder that causes any attempt at re-requesting
+the key whilst it exists to fail with error ENOKEY if negated or the specified
+error if rejected.
+
+This is provided to prevent excessive repeated spawning of /sbin/request-key
+processes for a key that will never be obtainable.
+
+Should the /sbin/request-key process exit anything other than 0 or die on a
+signal, the key under construction will be automatically negatively
+instantiated for a short amount of time.
+
+
+====================
+THE SEARCH ALGORITHM
+====================
+
+A search of any particular keyring proceeds in the following fashion:
+
+ (1) When the key management code searches for a key (keyring_search_aux) it
+     firstly calls key_permission(SEARCH) on the keyring it's starting with,
+     if this denies permission, it doesn't search further.
+
+ (2) It considers all the non-keyring keys within that keyring and, if any key
+     matches the criteria specified, calls key_permission(SEARCH) on it to see
+     if the key is allowed to be found.  If it is, that key is returned; if
+     not, the search continues, and the error code is retained if of higher
+     priority than the one currently set.
+
+ (3) It then considers all the keyring-type keys in the keyring it's currently
+     searching.  It calls key_permission(SEARCH) on each keyring, and if this
+     grants permission, it recurses, executing steps (2) and (3) on that
+     keyring.
+
+The process stops immediately a valid key is found with permission granted to
+use it.  Any error from a previous match attempt is discarded and the key is
+returned.
+
+When search_process_keyrings() is invoked, it performs the following searches
+until one succeeds:
+
+ (1) If extant, the process's thread keyring is searched.
+
+ (2) If extant, the process's process keyring is searched.
+
+ (3) The process's session keyring is searched.
+
+ (4) If the process has assumed the authority associated with a request_key()
+     authorisation key then:
+
+     (a) If extant, the calling process's thread keyring is searched.
+
+     (b) If extant, the calling process's process keyring is searched.
+
+     (c) The calling process's session keyring is searched.
+
+The moment one succeeds, all pending errors are discarded and the found key is
+returned.
+
+Only if all these fail does the whole thing fail with the highest priority
+error.  Note that several errors may have come from LSM.
+
+The error priority is:
+
+	EKEYREVOKED > EKEYEXPIRED > ENOKEY
+
+EACCES/EPERM are only returned on a direct search of a specific keyring where
+the basal keyring does not grant Search permission.
diff -druN linux-2.6.39-libre/Documentation/security/keys-trusted-encrypted.txt linux-3.0-rc7-libre/Documentation/security/keys-trusted-encrypted.txt
--- linux-2.6.39-libre/Documentation/security/keys-trusted-encrypted.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/Documentation/security/keys-trusted-encrypted.txt	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,145 @@
+			Trusted and Encrypted Keys
+
+Trusted and Encrypted Keys are two new key types added to the existing kernel
+key ring service.  Both of these new types are variable length symmetic keys,
+and in both cases all keys are created in the kernel, and user space sees,
+stores, and loads only encrypted blobs.  Trusted Keys require the availability
+of a Trusted Platform Module (TPM) chip for greater security, while Encrypted
+Keys can be used on any system.  All user level blobs, are displayed and loaded
+in hex ascii for convenience, and are integrity verified.
+
+Trusted Keys use a TPM both to generate and to seal the keys.  Keys are sealed
+under a 2048 bit RSA key in the TPM, and optionally sealed to specified PCR
+(integrity measurement) values, and only unsealed by the TPM, if PCRs and blob
+integrity verifications match.  A loaded Trusted Key can be updated with new
+(future) PCR values, so keys are easily migrated to new pcr values, such as
+when the kernel and initramfs are updated.  The same key can have many saved
+blobs under different PCR values, so multiple boots are easily supported.
+
+By default, trusted keys are sealed under the SRK, which has the default
+authorization value (20 zeros).  This can be set at takeownership time with the
+trouser's utility: "tpm_takeownership -u -z".
+
+Usage:
+    keyctl add trusted name "new keylen [options]" ring
+    keyctl add trusted name "load hex_blob [pcrlock=pcrnum]" ring
+    keyctl update key "update [options]"
+    keyctl print keyid
+
+    options:
+       keyhandle= ascii hex value of sealing key default 0x40000000 (SRK)
+       keyauth=	  ascii hex auth for sealing key default 0x00...i
+		  (40 ascii zeros)
+       blobauth=  ascii hex auth for sealed data default 0x00...
+		  (40 ascii zeros)
+       blobauth=  ascii hex auth for sealed data default 0x00...
+		  (40 ascii zeros)
+       pcrinfo=	  ascii hex of PCR_INFO or PCR_INFO_LONG (no default)
+       pcrlock=	  pcr number to be extended to "lock" blob
+       migratable= 0|1 indicating permission to reseal to new PCR values,
+                   default 1 (resealing allowed)
+
+"keyctl print" returns an ascii hex copy of the sealed key, which is in standard
+TPM_STORED_DATA format.  The key length for new keys are always in bytes.
+Trusted Keys can be 32 - 128 bytes (256 - 1024 bits), the upper limit is to fit
+within the 2048 bit SRK (RSA) keylength, with all necessary structure/padding.
+
+Encrypted keys do not depend on a TPM, and are faster, as they use AES for
+encryption/decryption.  New keys are created from kernel generated random
+numbers, and are encrypted/decrypted using a specified 'master' key.  The
+'master' key can either be a trusted-key or user-key type.  The main
+disadvantage of encrypted keys is that if they are not rooted in a trusted key,
+they are only as secure as the user key encrypting them.  The master user key
+should therefore be loaded in as secure a way as possible, preferably early in
+boot.
+
+Usage:
+  keyctl add encrypted name "new key-type:master-key-name keylen" ring
+  keyctl add encrypted name "load hex_blob" ring
+  keyctl update keyid "update key-type:master-key-name"
+
+where 'key-type' is either 'trusted' or 'user'.
+
+Examples of trusted and encrypted key usage:
+
+Create and save a trusted key named "kmk" of length 32 bytes:
+
+    $ keyctl add trusted kmk "new 32" @u
+    440502848
+
+    $ keyctl show
+    Session Keyring
+           -3 --alswrv    500   500  keyring: _ses
+     97833714 --alswrv    500    -1   \_ keyring: _uid.500
+    440502848 --alswrv    500   500       \_ trusted: kmk
+
+    $ keyctl print 440502848
+    0101000000000000000001005d01b7e3f4a6be5709930f3b70a743cbb42e0cc95e18e915
+    3f60da455bbf1144ad12e4f92b452f966929f6105fd29ca28e4d4d5a031d068478bacb0b
+    27351119f822911b0a11ba3d3498ba6a32e50dac7f32894dd890eb9ad578e4e292c83722
+    a52e56a097e6a68b3f56f7a52ece0cdccba1eb62cad7d817f6dc58898b3ac15f36026fec
+    d568bd4a706cb60bb37be6d8f1240661199d640b66fb0fe3b079f97f450b9ef9c22c6d5d
+    dd379f0facd1cd020281dfa3c70ba21a3fa6fc2471dc6d13ecf8298b946f65345faa5ef0
+    f1f8fff03ad0acb083725535636addb08d73dedb9832da198081e5deae84bfaf0409c22b
+    e4a8aea2b607ec96931e6f4d4fe563ba
+
+    $ keyctl pipe 440502848 > kmk.blob
+
+Load a trusted key from the saved blob:
+
+    $ keyctl add trusted kmk "load `cat kmk.blob`" @u
+    268728824
+
+    $ keyctl print 268728824
+    0101000000000000000001005d01b7e3f4a6be5709930f3b70a743cbb42e0cc95e18e915
+    3f60da455bbf1144ad12e4f92b452f966929f6105fd29ca28e4d4d5a031d068478bacb0b
+    27351119f822911b0a11ba3d3498ba6a32e50dac7f32894dd890eb9ad578e4e292c83722
+    a52e56a097e6a68b3f56f7a52ece0cdccba1eb62cad7d817f6dc58898b3ac15f36026fec
+    d568bd4a706cb60bb37be6d8f1240661199d640b66fb0fe3b079f97f450b9ef9c22c6d5d
+    dd379f0facd1cd020281dfa3c70ba21a3fa6fc2471dc6d13ecf8298b946f65345faa5ef0
+    f1f8fff03ad0acb083725535636addb08d73dedb9832da198081e5deae84bfaf0409c22b
+    e4a8aea2b607ec96931e6f4d4fe563ba
+
+Reseal a trusted key under new pcr values:
+
+    $ keyctl update 268728824 "update pcrinfo=`cat pcr.blob`"
+    $ keyctl print 268728824
+    010100000000002c0002800093c35a09b70fff26e7a98ae786c641e678ec6ffb6b46d805
+    77c8a6377aed9d3219c6dfec4b23ffe3000001005d37d472ac8a44023fbb3d18583a4f73
+    d3a076c0858f6f1dcaa39ea0f119911ff03f5406df4f7f27f41da8d7194f45c9f4e00f2e
+    df449f266253aa3f52e55c53de147773e00f0f9aca86c64d94c95382265968c354c5eab4
+    9638c5ae99c89de1e0997242edfb0b501744e11ff9762dfd951cffd93227cc513384e7e6
+    e782c29435c7ec2edafaa2f4c1fe6e7a781b59549ff5296371b42133777dcc5b8b971610
+    94bc67ede19e43ddb9dc2baacad374a36feaf0314d700af0a65c164b7082401740e489c9
+    7ef6a24defe4846104209bf0c3eced7fa1a672ed5b125fc9d8cd88b476a658a4434644ef
+    df8ae9a178e9f83ba9f08d10fa47e4226b98b0702f06b3b8
+
+Create and save an encrypted key "evm" using the above trusted key "kmk":
+
+    $ keyctl add encrypted evm "new trusted:kmk 32" @u
+    159771175
+
+    $ keyctl print 159771175
+    trusted:kmk 32 2375725ad57798846a9bbd240de8906f006e66c03af53b1b382dbbc55
+    be2a44616e4959430436dc4f2a7a9659aa60bb4652aeb2120f149ed197c564e024717c64
+    5972dcb82ab2dde83376d82b2e3c09ffc
+
+    $ keyctl pipe 159771175 > evm.blob
+
+Load an encrypted key "evm" from saved blob:
+
+    $ keyctl add encrypted evm "load `cat evm.blob`" @u
+    831684262
+
+    $ keyctl print 831684262
+    trusted:kmk 32 2375725ad57798846a9bbd240de8906f006e66c03af53b1b382dbbc55
+    be2a44616e4959430436dc4f2a7a9659aa60bb4652aeb2120f149ed197c564e024717c64
+    5972dcb82ab2dde83376d82b2e3c09ffc
+
+
+The initial consumer of trusted keys is EVM, which at boot time needs a high
+quality symmetric key for HMAC protection of file metadata.  The use of a
+trusted key provides strong guarantees that the EVM key has not been
+compromised by a user level problem, and when sealed to specific boot PCR
+values, protects against boot and offline attacks.  Other uses for trusted and
+encrypted keys, such as for disk and file encryption are anticipated.
diff -druN linux-2.6.39-libre/Documentation/security/keys.txt linux-3.0-rc7-libre/Documentation/security/keys.txt
--- linux-2.6.39-libre/Documentation/security/keys.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/Documentation/security/keys.txt	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,1290 @@
+			 ============================
+			 KERNEL KEY RETENTION SERVICE
+			 ============================
+
+This service allows cryptographic keys, authentication tokens, cross-domain
+user mappings, and similar to be cached in the kernel for the use of
+filesystems and other kernel services.
+
+Keyrings are permitted; these are a special type of key that can hold links to
+other keys. Processes each have three standard keyring subscriptions that a
+kernel service can search for relevant keys.
+
+The key service can be configured on by enabling:
+
+	"Security options"/"Enable access key retention support" (CONFIG_KEYS)
+
+This document has the following sections:
+
+	- Key overview
+	- Key service overview
+	- Key access permissions
+	- SELinux support
+	- New procfs files
+	- Userspace system call interface
+	- Kernel services
+	- Notes on accessing payload contents
+	- Defining a key type
+	- Request-key callback service
+	- Garbage collection
+
+
+============
+KEY OVERVIEW
+============
+
+In this context, keys represent units of cryptographic data, authentication
+tokens, keyrings, etc.. These are represented in the kernel by struct key.
+
+Each key has a number of attributes:
+
+	- A serial number.
+	- A type.
+	- A description (for matching a key in a search).
+	- Access control information.
+	- An expiry time.
+	- A payload.
+	- State.
+
+
+ (*) Each key is issued a serial number of type key_serial_t that is unique for
+     the lifetime of that key. All serial numbers are positive non-zero 32-bit
+     integers.
+
+     Userspace programs can use a key's serial numbers as a way to gain access
+     to it, subject to permission checking.
+
+ (*) Each key is of a defined "type". Types must be registered inside the
+     kernel by a kernel service (such as a filesystem) before keys of that type
+     can be added or used. Userspace programs cannot define new types directly.
+
+     Key types are represented in the kernel by struct key_type. This defines a
+     number of operations that can be performed on a key of that type.
+
+     Should a type be removed from the system, all the keys of that type will
+     be invalidated.
+
+ (*) Each key has a description. This should be a printable string. The key
+     type provides an operation to perform a match between the description on a
+     key and a criterion string.
+
+ (*) Each key has an owner user ID, a group ID and a permissions mask. These
+     are used to control what a process may do to a key from userspace, and
+     whether a kernel service will be able to find the key.
+
+ (*) Each key can be set to expire at a specific time by the key type's
+     instantiation function. Keys can also be immortal.
+
+ (*) Each key can have a payload. This is a quantity of data that represent the
+     actual "key". In the case of a keyring, this is a list of keys to which
+     the keyring links; in the case of a user-defined key, it's an arbitrary
+     blob of data.
+
+     Having a payload is not required; and the payload can, in fact, just be a
+     value stored in the struct key itself.
+
+     When a key is instantiated, the key type's instantiation function is
+     called with a blob of data, and that then creates the key's payload in
+     some way.
+
+     Similarly, when userspace wants to read back the contents of the key, if
+     permitted, another key type operation will be called to convert the key's
+     attached payload back into a blob of data.
+
+ (*) Each key can be in one of a number of basic states:
+
+     (*) Uninstantiated. The key exists, but does not have any data attached.
+     	 Keys being requested from userspace will be in this state.
+
+     (*) Instantiated. This is the normal state. The key is fully formed, and
+	 has data attached.
+
+     (*) Negative. This is a relatively short-lived state. The key acts as a
+	 note saying that a previous call out to userspace failed, and acts as
+	 a throttle on key lookups. A negative key can be updated to a normal
+	 state.
+
+     (*) Expired. Keys can have lifetimes set. If their lifetime is exceeded,
+	 they traverse to this state. An expired key can be updated back to a
+	 normal state.
+
+     (*) Revoked. A key is put in this state by userspace action. It can't be
+	 found or operated upon (apart from by unlinking it).
+
+     (*) Dead. The key's type was unregistered, and so the key is now useless.
+
+Keys in the last three states are subject to garbage collection.  See the
+section on "Garbage collection".
+
+
+====================
+KEY SERVICE OVERVIEW
+====================
+
+The key service provides a number of features besides keys:
+
+ (*) The key service defines two special key types:
+
+     (+) "keyring"
+
+	 Keyrings are special keys that contain a list of other keys. Keyring
+	 lists can be modified using various system calls. Keyrings should not
+	 be given a payload when created.
+
+     (+) "user"
+
+	 A key of this type has a description and a payload that are arbitrary
+	 blobs of data. These can be created, updated and read by userspace,
+	 and aren't intended for use by kernel services.
+
+ (*) Each process subscribes to three keyrings: a thread-specific keyring, a
+     process-specific keyring, and a session-specific keyring.
+
+     The thread-specific keyring is discarded from the child when any sort of
+     clone, fork, vfork or execve occurs. A new keyring is created only when
+     required.
+
+     The process-specific keyring is replaced with an empty one in the child on
+     clone, fork, vfork unless CLONE_THREAD is supplied, in which case it is
+     shared. execve also discards the process's process keyring and creates a
+     new one.
+
+     The session-specific keyring is persistent across clone, fork, vfork and
+     execve, even when the latter executes a set-UID or set-GID binary. A
+     process can, however, replace its current session keyring with a new one
+     by using PR_JOIN_SESSION_KEYRING. It is permitted to request an anonymous
+     new one, or to attempt to create or join one of a specific name.
+
+     The ownership of the thread keyring changes when the real UID and GID of
+     the thread changes.
+
+ (*) Each user ID resident in the system holds two special keyrings: a user
+     specific keyring and a default user session keyring. The default session
+     keyring is initialised with a link to the user-specific keyring.
+
+     When a process changes its real UID, if it used to have no session key, it
+     will be subscribed to the default session key for the new UID.
+
+     If a process attempts to access its session key when it doesn't have one,
+     it will be subscribed to the default for its current UID.
+
+ (*) Each user has two quotas against which the keys they own are tracked. One
+     limits the total number of keys and keyrings, the other limits the total
+     amount of description and payload space that can be consumed.
+
+     The user can view information on this and other statistics through procfs
+     files.  The root user may also alter the quota limits through sysctl files
+     (see the section "New procfs files").
+
+     Process-specific and thread-specific keyrings are not counted towards a
+     user's quota.
+
+     If a system call that modifies a key or keyring in some way would put the
+     user over quota, the operation is refused and error EDQUOT is returned.
+
+ (*) There's a system call interface by which userspace programs can create and
+     manipulate keys and keyrings.
+
+ (*) There's a kernel interface by which services can register types and search
+     for keys.
+
+ (*) There's a way for the a search done from the kernel to call back to
+     userspace to request a key that can't be found in a process's keyrings.
+
+ (*) An optional filesystem is available through which the key database can be
+     viewed and manipulated.
+
+
+======================
+KEY ACCESS PERMISSIONS
+======================
+
+Keys have an owner user ID, a group access ID, and a permissions mask. The mask
+has up to eight bits each for possessor, user, group and other access. Only
+six of each set of eight bits are defined. These permissions granted are:
+
+ (*) View
+
+     This permits a key or keyring's attributes to be viewed - including key
+     type and description.
+
+ (*) Read
+
+     This permits a key's payload to be viewed or a keyring's list of linked
+     keys.
+
+ (*) Write
+
+     This permits a key's payload to be instantiated or updated, or it allows a
+     link to be added to or removed from a keyring.
+
+ (*) Search
+
+     This permits keyrings to be searched and keys to be found. Searches can
+     only recurse into nested keyrings that have search permission set.
+
+ (*) Link
+
+     This permits a key or keyring to be linked to. To create a link from a
+     keyring to a key, a process must have Write permission on the keyring and
+     Link permission on the key.
+
+ (*) Set Attribute
+
+     This permits a key's UID, GID and permissions mask to be changed.
+
+For changing the ownership, group ID or permissions mask, being the owner of
+the key or having the sysadmin capability is sufficient.
+
+
+===============
+SELINUX SUPPORT
+===============
+
+The security class "key" has been added to SELinux so that mandatory access
+controls can be applied to keys created within various contexts.  This support
+is preliminary, and is likely to change quite significantly in the near future.
+Currently, all of the basic permissions explained above are provided in SELinux
+as well; SELinux is simply invoked after all basic permission checks have been
+performed.
+
+The value of the file /proc/self/attr/keycreate influences the labeling of
+newly-created keys.  If the contents of that file correspond to an SELinux
+security context, then the key will be assigned that context.  Otherwise, the
+key will be assigned the current context of the task that invoked the key
+creation request.  Tasks must be granted explicit permission to assign a
+particular context to newly-created keys, using the "create" permission in the
+key security class.
+
+The default keyrings associated with users will be labeled with the default
+context of the user if and only if the login programs have been instrumented to
+properly initialize keycreate during the login process.  Otherwise, they will
+be labeled with the context of the login program itself.
+
+Note, however, that the default keyrings associated with the root user are
+labeled with the default kernel context, since they are created early in the
+boot process, before root has a chance to log in.
+
+The keyrings associated with new threads are each labeled with the context of
+their associated thread, and both session and process keyrings are handled
+similarly.
+
+
+================
+NEW PROCFS FILES
+================
+
+Two files have been added to procfs by which an administrator can find out
+about the status of the key service:
+
+ (*) /proc/keys
+
+     This lists the keys that are currently viewable by the task reading the
+     file, giving information about their type, description and permissions.
+     It is not possible to view the payload of the key this way, though some
+     information about it may be given.
+
+     The only keys included in the list are those that grant View permission to
+     the reading process whether or not it possesses them.  Note that LSM
+     security checks are still performed, and may further filter out keys that
+     the current process is not authorised to view.
+
+     The contents of the file look like this:
+
+	SERIAL   FLAGS  USAGE EXPY PERM     UID   GID   TYPE      DESCRIPTION: SUMMARY
+	00000001 I-----    39 perm 1f3f0000     0     0 keyring   _uid_ses.0: 1/4
+	00000002 I-----     2 perm 1f3f0000     0     0 keyring   _uid.0: empty
+	00000007 I-----     1 perm 1f3f0000     0     0 keyring   _pid.1: empty
+	0000018d I-----     1 perm 1f3f0000     0     0 keyring   _pid.412: empty
+	000004d2 I--Q--     1 perm 1f3f0000    32    -1 keyring   _uid.32: 1/4
+	000004d3 I--Q--     3 perm 1f3f0000    32    -1 keyring   _uid_ses.32: empty
+	00000892 I--QU-     1 perm 1f000000     0     0 user      metal:copper: 0
+	00000893 I--Q-N     1  35s 1f3f0000     0     0 user      metal:silver: 0
+	00000894 I--Q--     1  10h 003f0000     0     0 user      metal:gold: 0
+
+     The flags are:
+
+	I	Instantiated
+	R	Revoked
+	D	Dead
+	Q	Contributes to user's quota
+	U	Under construction by callback to userspace
+	N	Negative key
+
+     This file must be enabled at kernel configuration time as it allows anyone
+     to list the keys database.
+
+ (*) /proc/key-users
+
+     This file lists the tracking data for each user that has at least one key
+     on the system.  Such data includes quota information and statistics:
+
+	[root@andromeda root]# cat /proc/key-users
+	0:     46 45/45 1/100 13/10000
+	29:     2 2/2 2/100 40/10000
+	32:     2 2/2 2/100 40/10000
+	38:     2 2/2 2/100 40/10000
+
+     The format of each line is
+	<UID>:			User ID to which this applies
+	<usage>			Structure refcount
+	<inst>/<keys>		Total number of keys and number instantiated
+	<keys>/<max>		Key count quota
+	<bytes>/<max>		Key size quota
+
+
+Four new sysctl files have been added also for the purpose of controlling the
+quota limits on keys:
+
+ (*) /proc/sys/kernel/keys/root_maxkeys
+     /proc/sys/kernel/keys/root_maxbytes
+
+     These files hold the maximum number of keys that root may have and the
+     maximum total number of bytes of data that root may have stored in those
+     keys.
+
+ (*) /proc/sys/kernel/keys/maxkeys
+     /proc/sys/kernel/keys/maxbytes
+
+     These files hold the maximum number of keys that each non-root user may
+     have and the maximum total number of bytes of data that each of those
+     users may have stored in their keys.
+
+Root may alter these by writing each new limit as a decimal number string to
+the appropriate file.
+
+
+===============================
+USERSPACE SYSTEM CALL INTERFACE
+===============================
+
+Userspace can manipulate keys directly through three new syscalls: add_key,
+request_key and keyctl. The latter provides a number of functions for
+manipulating keys.
+
+When referring to a key directly, userspace programs should use the key's
+serial number (a positive 32-bit integer). However, there are some special
+values available for referring to special keys and keyrings that relate to the
+process making the call:
+
+	CONSTANT			VALUE	KEY REFERENCED
+	==============================	======	===========================
+	KEY_SPEC_THREAD_KEYRING		-1	thread-specific keyring
+	KEY_SPEC_PROCESS_KEYRING	-2	process-specific keyring
+	KEY_SPEC_SESSION_KEYRING	-3	session-specific keyring
+	KEY_SPEC_USER_KEYRING		-4	UID-specific keyring
+	KEY_SPEC_USER_SESSION_KEYRING	-5	UID-session keyring
+	KEY_SPEC_GROUP_KEYRING		-6	GID-specific keyring
+	KEY_SPEC_REQKEY_AUTH_KEY	-7	assumed request_key()
+						  authorisation key
+
+
+The main syscalls are:
+
+ (*) Create a new key of given type, description and payload and add it to the
+     nominated keyring:
+
+	key_serial_t add_key(const char *type, const char *desc,
+			     const void *payload, size_t plen,
+			     key_serial_t keyring);
+
+     If a key of the same type and description as that proposed already exists
+     in the keyring, this will try to update it with the given payload, or it
+     will return error EEXIST if that function is not supported by the key
+     type. The process must also have permission to write to the key to be able
+     to update it. The new key will have all user permissions granted and no
+     group or third party permissions.
+
+     Otherwise, this will attempt to create a new key of the specified type and
+     description, and to instantiate it with the supplied payload and attach it
+     to the keyring. In this case, an error will be generated if the process
+     does not have permission to write to the keyring.
+
+     The payload is optional, and the pointer can be NULL if not required by
+     the type. The payload is plen in size, and plen can be zero for an empty
+     payload.
+
+     A new keyring can be generated by setting type "keyring", the keyring name
+     as the description (or NULL) and setting the payload to NULL.
+
+     User defined keys can be created by specifying type "user". It is
+     recommended that a user defined key's description by prefixed with a type
+     ID and a colon, such as "krb5tgt:" for a Kerberos 5 ticket granting
+     ticket.
+
+     Any other type must have been registered with the kernel in advance by a
+     kernel service such as a filesystem.
+
+     The ID of the new or updated key is returned if successful.
+
+
+ (*) Search the process's keyrings for a key, potentially calling out to
+     userspace to create it.
+
+	key_serial_t request_key(const char *type, const char *description,
+				 const char *callout_info,
+				 key_serial_t dest_keyring);
+
+     This function searches all the process's keyrings in the order thread,
+     process, session for a matching key. This works very much like
+     KEYCTL_SEARCH, including the optional attachment of the discovered key to
+     a keyring.
+
+     If a key cannot be found, and if callout_info is not NULL, then
+     /sbin/request-key will be invoked in an attempt to obtain a key. The
+     callout_info string will be passed as an argument to the program.
+
+     See also Documentation/security/keys-request-key.txt.
+
+
+The keyctl syscall functions are:
+
+ (*) Map a special key ID to a real key ID for this process:
+
+	key_serial_t keyctl(KEYCTL_GET_KEYRING_ID, key_serial_t id,
+			    int create);
+
+     The special key specified by "id" is looked up (with the key being created
+     if necessary) and the ID of the key or keyring thus found is returned if
+     it exists.
+
+     If the key does not yet exist, the key will be created if "create" is
+     non-zero; and the error ENOKEY will be returned if "create" is zero.
+
+
+ (*) Replace the session keyring this process subscribes to with a new one:
+
+	key_serial_t keyctl(KEYCTL_JOIN_SESSION_KEYRING, const char *name);
+
+     If name is NULL, an anonymous keyring is created attached to the process
+     as its session keyring, displacing the old session keyring.
+
+     If name is not NULL, if a keyring of that name exists, the process
+     attempts to attach it as the session keyring, returning an error if that
+     is not permitted; otherwise a new keyring of that name is created and
+     attached as the session keyring.
+
+     To attach to a named keyring, the keyring must have search permission for
+     the process's ownership.
+
+     The ID of the new session keyring is returned if successful.
+
+
+ (*) Update the specified key:
+
+	long keyctl(KEYCTL_UPDATE, key_serial_t key, const void *payload,
+		    size_t plen);
+
+     This will try to update the specified key with the given payload, or it
+     will return error EOPNOTSUPP if that function is not supported by the key
+     type. The process must also have permission to write to the key to be able
+     to update it.
+
+     The payload is of length plen, and may be absent or empty as for
+     add_key().
+
+
+ (*) Revoke a key:
+
+	long keyctl(KEYCTL_REVOKE, key_serial_t key);
+
+     This makes a key unavailable for further operations. Further attempts to
+     use the key will be met with error EKEYREVOKED, and the key will no longer
+     be findable.
+
+
+ (*) Change the ownership of a key:
+
+	long keyctl(KEYCTL_CHOWN, key_serial_t key, uid_t uid, gid_t gid);
+
+     This function permits a key's owner and group ID to be changed. Either one
+     of uid or gid can be set to -1 to suppress that change.
+
+     Only the superuser can change a key's owner to something other than the
+     key's current owner. Similarly, only the superuser can change a key's
+     group ID to something other than the calling process's group ID or one of
+     its group list members.
+
+
+ (*) Change the permissions mask on a key:
+
+	long keyctl(KEYCTL_SETPERM, key_serial_t key, key_perm_t perm);
+
+     This function permits the owner of a key or the superuser to change the
+     permissions mask on a key.
+
+     Only bits the available bits are permitted; if any other bits are set,
+     error EINVAL will be returned.
+
+
+ (*) Describe a key:
+
+	long keyctl(KEYCTL_DESCRIBE, key_serial_t key, char *buffer,
+		    size_t buflen);
+
+     This function returns a summary of the key's attributes (but not its
+     payload data) as a string in the buffer provided.
+
+     Unless there's an error, it always returns the amount of data it could
+     produce, even if that's too big for the buffer, but it won't copy more
+     than requested to userspace. If the buffer pointer is NULL then no copy
+     will take place.
+
+     A process must have view permission on the key for this function to be
+     successful.
+
+     If successful, a string is placed in the buffer in the following format:
+
+	<type>;<uid>;<gid>;<perm>;<description>
+
+     Where type and description are strings, uid and gid are decimal, and perm
+     is hexadecimal. A NUL character is included at the end of the string if
+     the buffer is sufficiently big.
+
+     This can be parsed with
+
+	sscanf(buffer, "%[^;];%d;%d;%o;%s", type, &uid, &gid, &mode, desc);
+
+
+ (*) Clear out a keyring:
+
+	long keyctl(KEYCTL_CLEAR, key_serial_t keyring);
+
+     This function clears the list of keys attached to a keyring. The calling
+     process must have write permission on the keyring, and it must be a
+     keyring (or else error ENOTDIR will result).
+
+
+ (*) Link a key into a keyring:
+
+	long keyctl(KEYCTL_LINK, key_serial_t keyring, key_serial_t key);
+
+     This function creates a link from the keyring to the key. The process must
+     have write permission on the keyring and must have link permission on the
+     key.
+
+     Should the keyring not be a keyring, error ENOTDIR will result; and if the
+     keyring is full, error ENFILE will result.
+
+     The link procedure checks the nesting of the keyrings, returning ELOOP if
+     it appears too deep or EDEADLK if the link would introduce a cycle.
+
+     Any links within the keyring to keys that match the new key in terms of
+     type and description will be discarded from the keyring as the new one is
+     added.
+
+
+ (*) Unlink a key or keyring from another keyring:
+
+	long keyctl(KEYCTL_UNLINK, key_serial_t keyring, key_serial_t key);
+
+     This function looks through the keyring for the first link to the
+     specified key, and removes it if found. Subsequent links to that key are
+     ignored. The process must have write permission on the keyring.
+
+     If the keyring is not a keyring, error ENOTDIR will result; and if the key
+     is not present, error ENOENT will be the result.
+
+
+ (*) Search a keyring tree for a key:
+
+	key_serial_t keyctl(KEYCTL_SEARCH, key_serial_t keyring,
+			    const char *type, const char *description,
+			    key_serial_t dest_keyring);
+
+     This searches the keyring tree headed by the specified keyring until a key
+     is found that matches the type and description criteria. Each keyring is
+     checked for keys before recursion into its children occurs.
+
+     The process must have search permission on the top level keyring, or else
+     error EACCES will result. Only keyrings that the process has search
+     permission on will be recursed into, and only keys and keyrings for which
+     a process has search permission can be matched. If the specified keyring
+     is not a keyring, ENOTDIR will result.
+
+     If the search succeeds, the function will attempt to link the found key
+     into the destination keyring if one is supplied (non-zero ID). All the
+     constraints applicable to KEYCTL_LINK apply in this case too.
+
+     Error ENOKEY, EKEYREVOKED or EKEYEXPIRED will be returned if the search
+     fails. On success, the resulting key ID will be returned.
+
+
+ (*) Read the payload data from a key:
+
+	long keyctl(KEYCTL_READ, key_serial_t keyring, char *buffer,
+		    size_t buflen);
+
+     This function attempts to read the payload data from the specified key
+     into the buffer. The process must have read permission on the key to
+     succeed.
+
+     The returned data will be processed for presentation by the key type. For
+     instance, a keyring will return an array of key_serial_t entries
+     representing the IDs of all the keys to which it is subscribed. The user
+     defined key type will return its data as is. If a key type does not
+     implement this function, error EOPNOTSUPP will result.
+
+     As much of the data as can be fitted into the buffer will be copied to
+     userspace if the buffer pointer is not NULL.
+
+     On a successful return, the function will always return the amount of data
+     available rather than the amount copied.
+
+
+ (*) Instantiate a partially constructed key.
+
+	long keyctl(KEYCTL_INSTANTIATE, key_serial_t key,
+		    const void *payload, size_t plen,
+		    key_serial_t keyring);
+	long keyctl(KEYCTL_INSTANTIATE_IOV, key_serial_t key,
+		    const struct iovec *payload_iov, unsigned ioc,
+		    key_serial_t keyring);
+
+     If the kernel calls back to userspace to complete the instantiation of a
+     key, userspace should use this call to supply data for the key before the
+     invoked process returns, or else the key will be marked negative
+     automatically.
+
+     The process must have write access on the key to be able to instantiate
+     it, and the key must be uninstantiated.
+
+     If a keyring is specified (non-zero), the key will also be linked into
+     that keyring, however all the constraints applying in KEYCTL_LINK apply in
+     this case too.
+
+     The payload and plen arguments describe the payload data as for add_key().
+
+     The payload_iov and ioc arguments describe the payload data in an iovec
+     array instead of a single buffer.
+
+
+ (*) Negatively instantiate a partially constructed key.
+
+	long keyctl(KEYCTL_NEGATE, key_serial_t key,
+		    unsigned timeout, key_serial_t keyring);
+	long keyctl(KEYCTL_REJECT, key_serial_t key,
+		    unsigned timeout, unsigned error, key_serial_t keyring);
+
+     If the kernel calls back to userspace to complete the instantiation of a
+     key, userspace should use this call mark the key as negative before the
+     invoked process returns if it is unable to fulfil the request.
+
+     The process must have write access on the key to be able to instantiate
+     it, and the key must be uninstantiated.
+
+     If a keyring is specified (non-zero), the key will also be linked into
+     that keyring, however all the constraints applying in KEYCTL_LINK apply in
+     this case too.
+
+     If the key is rejected, future searches for it will return the specified
+     error code until the rejected key expires.  Negating the key is the same
+     as rejecting the key with ENOKEY as the error code.
+
+
+ (*) Set the default request-key destination keyring.
+
+	long keyctl(KEYCTL_SET_REQKEY_KEYRING, int reqkey_defl);
+
+     This sets the default keyring to which implicitly requested keys will be
+     attached for this thread. reqkey_defl should be one of these constants:
+
+	CONSTANT				VALUE	NEW DEFAULT KEYRING
+	======================================	======	=======================
+	KEY_REQKEY_DEFL_NO_CHANGE		-1	No change
+	KEY_REQKEY_DEFL_DEFAULT			0	Default[1]
+	KEY_REQKEY_DEFL_THREAD_KEYRING		1	Thread keyring
+	KEY_REQKEY_DEFL_PROCESS_KEYRING		2	Process keyring
+	KEY_REQKEY_DEFL_SESSION_KEYRING		3	Session keyring
+	KEY_REQKEY_DEFL_USER_KEYRING		4	User keyring
+	KEY_REQKEY_DEFL_USER_SESSION_KEYRING	5	User session keyring
+	KEY_REQKEY_DEFL_GROUP_KEYRING		6	Group keyring
+
+     The old default will be returned if successful and error EINVAL will be
+     returned if reqkey_defl is not one of the above values.
+
+     The default keyring can be overridden by the keyring indicated to the
+     request_key() system call.
+
+     Note that this setting is inherited across fork/exec.
+
+     [1] The default is: the thread keyring if there is one, otherwise
+     the process keyring if there is one, otherwise the session keyring if
+     there is one, otherwise the user default session keyring.
+
+
+ (*) Set the timeout on a key.
+
+	long keyctl(KEYCTL_SET_TIMEOUT, key_serial_t key, unsigned timeout);
+
+     This sets or clears the timeout on a key. The timeout can be 0 to clear
+     the timeout or a number of seconds to set the expiry time that far into
+     the future.
+
+     The process must have attribute modification access on a key to set its
+     timeout. Timeouts may not be set with this function on negative, revoked
+     or expired keys.
+
+
+ (*) Assume the authority granted to instantiate a key
+
+	long keyctl(KEYCTL_ASSUME_AUTHORITY, key_serial_t key);
+
+     This assumes or divests the authority required to instantiate the
+     specified key. Authority can only be assumed if the thread has the
+     authorisation key associated with the specified key in its keyrings
+     somewhere.
+
+     Once authority is assumed, searches for keys will also search the
+     requester's keyrings using the requester's security label, UID, GID and
+     groups.
+
+     If the requested authority is unavailable, error EPERM will be returned,
+     likewise if the authority has been revoked because the target key is
+     already instantiated.
+
+     If the specified key is 0, then any assumed authority will be divested.
+
+     The assumed authoritative key is inherited across fork and exec.
+
+
+ (*) Get the LSM security context attached to a key.
+
+	long keyctl(KEYCTL_GET_SECURITY, key_serial_t key, char *buffer,
+		    size_t buflen)
+
+     This function returns a string that represents the LSM security context
+     attached to a key in the buffer provided.
+
+     Unless there's an error, it always returns the amount of data it could
+     produce, even if that's too big for the buffer, but it won't copy more
+     than requested to userspace. If the buffer pointer is NULL then no copy
+     will take place.
+
+     A NUL character is included at the end of the string if the buffer is
+     sufficiently big.  This is included in the returned count.  If no LSM is
+     in force then an empty string will be returned.
+
+     A process must have view permission on the key for this function to be
+     successful.
+
+
+ (*) Install the calling process's session keyring on its parent.
+
+	long keyctl(KEYCTL_SESSION_TO_PARENT);
+
+     This functions attempts to install the calling process's session keyring
+     on to the calling process's parent, replacing the parent's current session
+     keyring.
+
+     The calling process must have the same ownership as its parent, the
+     keyring must have the same ownership as the calling process, the calling
+     process must have LINK permission on the keyring and the active LSM module
+     mustn't deny permission, otherwise error EPERM will be returned.
+
+     Error ENOMEM will be returned if there was insufficient memory to complete
+     the operation, otherwise 0 will be returned to indicate success.
+
+     The keyring will be replaced next time the parent process leaves the
+     kernel and resumes executing userspace.
+
+
+===============
+KERNEL SERVICES
+===============
+
+The kernel services for key management are fairly simple to deal with. They can
+be broken down into two areas: keys and key types.
+
+Dealing with keys is fairly straightforward. Firstly, the kernel service
+registers its type, then it searches for a key of that type. It should retain
+the key as long as it has need of it, and then it should release it. For a
+filesystem or device file, a search would probably be performed during the open
+call, and the key released upon close. How to deal with conflicting keys due to
+two different users opening the same file is left to the filesystem author to
+solve.
+
+To access the key manager, the following header must be #included:
+
+	<linux/key.h>
+
+Specific key types should have a header file under include/keys/ that should be
+used to access that type.  For keys of type "user", for example, that would be:
+
+	<keys/user-type.h>
+
+Note that there are two different types of pointers to keys that may be
+encountered:
+
+ (*) struct key *
+
+     This simply points to the key structure itself. Key structures will be at
+     least four-byte aligned.
+
+ (*) key_ref_t
+
+     This is equivalent to a struct key *, but the least significant bit is set
+     if the caller "possesses" the key. By "possession" it is meant that the
+     calling processes has a searchable link to the key from one of its
+     keyrings. There are three functions for dealing with these:
+
+	key_ref_t make_key_ref(const struct key *key,
+			       unsigned long possession);
+
+	struct key *key_ref_to_ptr(const key_ref_t key_ref);
+
+	unsigned long is_key_possessed(const key_ref_t key_ref);
+
+     The first function constructs a key reference from a key pointer and
+     possession information (which must be 0 or 1 and not any other value).
+
+     The second function retrieves the key pointer from a reference and the
+     third retrieves the possession flag.
+
+When accessing a key's payload contents, certain precautions must be taken to
+prevent access vs modification races. See the section "Notes on accessing
+payload contents" for more information.
+
+(*) To search for a key, call:
+
+	struct key *request_key(const struct key_type *type,
+				const char *description,
+				const char *callout_info);
+
+    This is used to request a key or keyring with a description that matches
+    the description specified according to the key type's match function. This
+    permits approximate matching to occur. If callout_string is not NULL, then
+    /sbin/request-key will be invoked in an attempt to obtain the key from
+    userspace. In that case, callout_string will be passed as an argument to
+    the program.
+
+    Should the function fail error ENOKEY, EKEYEXPIRED or EKEYREVOKED will be
+    returned.
+
+    If successful, the key will have been attached to the default keyring for
+    implicitly obtained request-key keys, as set by KEYCTL_SET_REQKEY_KEYRING.
+
+    See also Documentation/security/keys-request-key.txt.
+
+
+(*) To search for a key, passing auxiliary data to the upcaller, call:
+
+	struct key *request_key_with_auxdata(const struct key_type *type,
+					     const char *description,
+					     const void *callout_info,
+					     size_t callout_len,
+					     void *aux);
+
+    This is identical to request_key(), except that the auxiliary data is
+    passed to the key_type->request_key() op if it exists, and the callout_info
+    is a blob of length callout_len, if given (the length may be 0).
+
+
+(*) A key can be requested asynchronously by calling one of:
+
+	struct key *request_key_async(const struct key_type *type,
+				      const char *description,
+				      const void *callout_info,
+				      size_t callout_len);
+
+    or:
+
+	struct key *request_key_async_with_auxdata(const struct key_type *type,
+						   const char *description,
+						   const char *callout_info,
+					     	   size_t callout_len,
+					     	   void *aux);
+
+    which are asynchronous equivalents of request_key() and
+    request_key_with_auxdata() respectively.
+
+    These two functions return with the key potentially still under
+    construction.  To wait for construction completion, the following should be
+    called:
+
+	int wait_for_key_construction(struct key *key, bool intr);
+
+    The function will wait for the key to finish being constructed and then
+    invokes key_validate() to return an appropriate value to indicate the state
+    of the key (0 indicates the key is usable).
+
+    If intr is true, then the wait can be interrupted by a signal, in which
+    case error ERESTARTSYS will be returned.
+
+
+(*) When it is no longer required, the key should be released using:
+
+	void key_put(struct key *key);
+
+    Or:
+
+	void key_ref_put(key_ref_t key_ref);
+
+    These can be called from interrupt context. If CONFIG_KEYS is not set then
+    the argument will not be parsed.
+
+
+(*) Extra references can be made to a key by calling the following function:
+
+	struct key *key_get(struct key *key);
+
+    These need to be disposed of by calling key_put() when they've been
+    finished with. The key pointer passed in will be returned. If the pointer
+    is NULL or CONFIG_KEYS is not set then the key will not be dereferenced and
+    no increment will take place.
+
+
+(*) A key's serial number can be obtained by calling:
+
+	key_serial_t key_serial(struct key *key);
+
+    If key is NULL or if CONFIG_KEYS is not set then 0 will be returned (in the
+    latter case without parsing the argument).
+
+
+(*) If a keyring was found in the search, this can be further searched by:
+
+	key_ref_t keyring_search(key_ref_t keyring_ref,
+				 const struct key_type *type,
+				 const char *description)
+
+    This searches the keyring tree specified for a matching key. Error ENOKEY
+    is returned upon failure (use IS_ERR/PTR_ERR to determine). If successful,
+    the returned key will need to be released.
+
+    The possession attribute from the keyring reference is used to control
+    access through the permissions mask and is propagated to the returned key
+    reference pointer if successful.
+
+
+(*) To check the validity of a key, this function can be called:
+
+	int validate_key(struct key *key);
+
+    This checks that the key in question hasn't expired or and hasn't been
+    revoked. Should the key be invalid, error EKEYEXPIRED or EKEYREVOKED will
+    be returned. If the key is NULL or if CONFIG_KEYS is not set then 0 will be
+    returned (in the latter case without parsing the argument).
+
+
+(*) To register a key type, the following function should be called:
+
+	int register_key_type(struct key_type *type);
+
+    This will return error EEXIST if a type of the same name is already
+    present.
+
+
+(*) To unregister a key type, call:
+
+	void unregister_key_type(struct key_type *type);
+
+
+Under some circumstances, it may be desirable to deal with a bundle of keys.
+The facility provides access to the keyring type for managing such a bundle:
+
+	struct key_type key_type_keyring;
+
+This can be used with a function such as request_key() to find a specific
+keyring in a process's keyrings.  A keyring thus found can then be searched
+with keyring_search().  Note that it is not possible to use request_key() to
+search a specific keyring, so using keyrings in this way is of limited utility.
+
+
+===================================
+NOTES ON ACCESSING PAYLOAD CONTENTS
+===================================
+
+The simplest payload is just a number in key->payload.value. In this case,
+there's no need to indulge in RCU or locking when accessing the payload.
+
+More complex payload contents must be allocated and a pointer to them set in
+key->payload.data. One of the following ways must be selected to access the
+data:
+
+ (1) Unmodifiable key type.
+
+     If the key type does not have a modify method, then the key's payload can
+     be accessed without any form of locking, provided that it's known to be
+     instantiated (uninstantiated keys cannot be "found").
+
+ (2) The key's semaphore.
+
+     The semaphore could be used to govern access to the payload and to control
+     the payload pointer. It must be write-locked for modifications and would
+     have to be read-locked for general access. The disadvantage of doing this
+     is that the accessor may be required to sleep.
+
+ (3) RCU.
+
+     RCU must be used when the semaphore isn't already held; if the semaphore
+     is held then the contents can't change under you unexpectedly as the
+     semaphore must still be used to serialise modifications to the key. The
+     key management code takes care of this for the key type.
+
+     However, this means using:
+
+	rcu_read_lock() ... rcu_dereference() ... rcu_read_unlock()
+
+     to read the pointer, and:
+
+	rcu_dereference() ... rcu_assign_pointer() ... call_rcu()
+
+     to set the pointer and dispose of the old contents after a grace period.
+     Note that only the key type should ever modify a key's payload.
+
+     Furthermore, an RCU controlled payload must hold a struct rcu_head for the
+     use of call_rcu() and, if the payload is of variable size, the length of
+     the payload. key->datalen cannot be relied upon to be consistent with the
+     payload just dereferenced if the key's semaphore is not held.
+
+
+===================
+DEFINING A KEY TYPE
+===================
+
+A kernel service may want to define its own key type. For instance, an AFS
+filesystem might want to define a Kerberos 5 ticket key type. To do this, it
+author fills in a key_type struct and registers it with the system.
+
+Source files that implement key types should include the following header file:
+
+	<linux/key-type.h>
+
+The structure has a number of fields, some of which are mandatory:
+
+ (*) const char *name
+
+     The name of the key type. This is used to translate a key type name
+     supplied by userspace into a pointer to the structure.
+
+
+ (*) size_t def_datalen
+
+     This is optional - it supplies the default payload data length as
+     contributed to the quota. If the key type's payload is always or almost
+     always the same size, then this is a more efficient way to do things.
+
+     The data length (and quota) on a particular key can always be changed
+     during instantiation or update by calling:
+
+	int key_payload_reserve(struct key *key, size_t datalen);
+
+     With the revised data length. Error EDQUOT will be returned if this is not
+     viable.
+
+
+ (*) int (*vet_description)(const char *description);
+
+     This optional method is called to vet a key description.  If the key type
+     doesn't approve of the key description, it may return an error, otherwise
+     it should return 0.
+
+
+ (*) int (*instantiate)(struct key *key, const void *data, size_t datalen);
+
+     This method is called to attach a payload to a key during construction.
+     The payload attached need not bear any relation to the data passed to this
+     function.
+
+     If the amount of data attached to the key differs from the size in
+     keytype->def_datalen, then key_payload_reserve() should be called.
+
+     This method does not have to lock the key in order to attach a payload.
+     The fact that KEY_FLAG_INSTANTIATED is not set in key->flags prevents
+     anything else from gaining access to the key.
+
+     It is safe to sleep in this method.
+
+
+ (*) int (*update)(struct key *key, const void *data, size_t datalen);
+
+     If this type of key can be updated, then this method should be provided.
+     It is called to update a key's payload from the blob of data provided.
+
+     key_payload_reserve() should be called if the data length might change
+     before any changes are actually made. Note that if this succeeds, the type
+     is committed to changing the key because it's already been altered, so all
+     memory allocation must be done first.
+
+     The key will have its semaphore write-locked before this method is called,
+     but this only deters other writers; any changes to the key's payload must
+     be made under RCU conditions, and call_rcu() must be used to dispose of
+     the old payload.
+
+     key_payload_reserve() should be called before the changes are made, but
+     after all allocations and other potentially failing function calls are
+     made.
+
+     It is safe to sleep in this method.
+
+
+ (*) int (*match)(const struct key *key, const void *desc);
+
+     This method is called to match a key against a description. It should
+     return non-zero if the two match, zero if they don't.
+
+     This method should not need to lock the key in any way. The type and
+     description can be considered invariant, and the payload should not be
+     accessed (the key may not yet be instantiated).
+
+     It is not safe to sleep in this method; the caller may hold spinlocks.
+
+
+ (*) void (*revoke)(struct key *key);
+
+     This method is optional.  It is called to discard part of the payload
+     data upon a key being revoked.  The caller will have the key semaphore
+     write-locked.
+
+     It is safe to sleep in this method, though care should be taken to avoid
+     a deadlock against the key semaphore.
+
+
+ (*) void (*destroy)(struct key *key);
+
+     This method is optional. It is called to discard the payload data on a key
+     when it is being destroyed.
+
+     This method does not need to lock the key to access the payload; it can
+     consider the key as being inaccessible at this time. Note that the key's
+     type may have been changed before this function is called.
+
+     It is not safe to sleep in this method; the caller may hold spinlocks.
+
+
+ (*) void (*describe)(const struct key *key, struct seq_file *p);
+
+     This method is optional. It is called during /proc/keys reading to
+     summarise a key's description and payload in text form.
+
+     This method will be called with the RCU read lock held. rcu_dereference()
+     should be used to read the payload pointer if the payload is to be
+     accessed. key->datalen cannot be trusted to stay consistent with the
+     contents of the payload.
+
+     The description will not change, though the key's state may.
+
+     It is not safe to sleep in this method; the RCU read lock is held by the
+     caller.
+
+
+ (*) long (*read)(const struct key *key, char __user *buffer, size_t buflen);
+
+     This method is optional. It is called by KEYCTL_READ to translate the
+     key's payload into something a blob of data for userspace to deal with.
+     Ideally, the blob should be in the same format as that passed in to the
+     instantiate and update methods.
+
+     If successful, the blob size that could be produced should be returned
+     rather than the size copied.
+
+     This method will be called with the key's semaphore read-locked. This will
+     prevent the key's payload changing. It is not necessary to use RCU locking
+     when accessing the key's payload. It is safe to sleep in this method, such
+     as might happen when the userspace buffer is accessed.
+
+
+ (*) int (*request_key)(struct key_construction *cons, const char *op,
+			void *aux);
+
+     This method is optional.  If provided, request_key() and friends will
+     invoke this function rather than upcalling to /sbin/request-key to operate
+     upon a key of this type.
+
+     The aux parameter is as passed to request_key_async_with_auxdata() and
+     similar or is NULL otherwise.  Also passed are the construction record for
+     the key to be operated upon and the operation type (currently only
+     "create").
+
+     This method is permitted to return before the upcall is complete, but the
+     following function must be called under all circumstances to complete the
+     instantiation process, whether or not it succeeds, whether or not there's
+     an error:
+
+	void complete_request_key(struct key_construction *cons, int error);
+
+     The error parameter should be 0 on success, -ve on error.  The
+     construction record is destroyed by this action and the authorisation key
+     will be revoked.  If an error is indicated, the key under construction
+     will be negatively instantiated if it wasn't already instantiated.
+
+     If this method returns an error, that error will be returned to the
+     caller of request_key*().  complete_request_key() must be called prior to
+     returning.
+
+     The key under construction and the authorisation key can be found in the
+     key_construction struct pointed to by cons:
+
+     (*) struct key *key;
+
+     	 The key under construction.
+
+     (*) struct key *authkey;
+
+     	 The authorisation key.
+
+
+============================
+REQUEST-KEY CALLBACK SERVICE
+============================
+
+To create a new key, the kernel will attempt to execute the following command
+line:
+
+	/sbin/request-key create <key> <uid> <gid> \
+		<threadring> <processring> <sessionring> <callout_info>
+
+<key> is the key being constructed, and the three keyrings are the process
+keyrings from the process that caused the search to be issued. These are
+included for two reasons:
+
+  (1) There may be an authentication token in one of the keyrings that is
+      required to obtain the key, eg: a Kerberos Ticket-Granting Ticket.
+
+  (2) The new key should probably be cached in one of these rings.
+
+This program should set it UID and GID to those specified before attempting to
+access any more keys. It may then look around for a user specific process to
+hand the request off to (perhaps a path held in placed in another key by, for
+example, the KDE desktop manager).
+
+The program (or whatever it calls) should finish construction of the key by
+calling KEYCTL_INSTANTIATE or KEYCTL_INSTANTIATE_IOV, which also permits it to
+cache the key in one of the keyrings (probably the session ring) before
+returning.  Alternatively, the key can be marked as negative with KEYCTL_NEGATE
+or KEYCTL_REJECT; this also permits the key to be cached in one of the
+keyrings.
+
+If it returns with the key remaining in the unconstructed state, the key will
+be marked as being negative, it will be added to the session keyring, and an
+error will be returned to the key requestor.
+
+Supplementary information may be provided from whoever or whatever invoked this
+service. This will be passed as the <callout_info> parameter. If no such
+information was made available, then "-" will be passed as this parameter
+instead.
+
+
+Similarly, the kernel may attempt to update an expired or a soon to expire key
+by executing:
+
+	/sbin/request-key update <key> <uid> <gid> \
+		<threadring> <processring> <sessionring>
+
+In this case, the program isn't required to actually attach the key to a ring;
+the rings are provided for reference.
+
+
+==================
+GARBAGE COLLECTION
+==================
+
+Dead keys (for which the type has been removed) will be automatically unlinked
+from those keyrings that point to them and deleted as soon as possible by a
+background garbage collector.
+
+Similarly, revoked and expired keys will be garbage collected, but only after a
+certain amount of time has passed.  This time is set as a number of seconds in:
+
+	/proc/sys/kernel/keys/gc_delay
diff -druN linux-2.6.39-libre/Documentation/security/SELinux.txt linux-3.0-rc7-libre/Documentation/security/SELinux.txt
--- linux-2.6.39-libre/Documentation/security/SELinux.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/Documentation/security/SELinux.txt	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,27 @@
+If you want to use SELinux, chances are you will want
+to use the distro-provided policies, or install the
+latest reference policy release from
+	http://oss.tresys.com/projects/refpolicy
+
+However, if you want to install a dummy policy for
+testing, you can do using 'mdp' provided under
+scripts/selinux.  Note that this requires the selinux
+userspace to be installed - in particular you will
+need checkpolicy to compile a kernel, and setfiles and
+fixfiles to label the filesystem.
+
+	1. Compile the kernel with selinux enabled.
+	2. Type 'make' to compile mdp.
+	3. Make sure that you are not running with
+	   SELinux enabled and a real policy.  If
+	   you are, reboot with selinux disabled
+	   before continuing.
+	4. Run install_policy.sh:
+		cd scripts/selinux
+		sh install_policy.sh
+
+Step 4 will create a new dummy policy valid for your
+kernel, with a single selinux user, role, and type.
+It will compile the policy, will set your SELINUXTYPE to
+dummy in /etc/selinux/config, install the compiled policy
+as 'dummy', and relabel your filesystem.
diff -druN linux-2.6.39-libre/Documentation/security/Smack.txt linux-3.0-rc7-libre/Documentation/security/Smack.txt
--- linux-2.6.39-libre/Documentation/security/Smack.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/Documentation/security/Smack.txt	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,541 @@
+
+
+    "Good for you, you've decided to clean the elevator!"
+    - The Elevator, from Dark Star
+
+Smack is the the Simplified Mandatory Access Control Kernel.
+Smack is a kernel based implementation of mandatory access
+control that includes simplicity in its primary design goals.
+
+Smack is not the only Mandatory Access Control scheme
+available for Linux. Those new to Mandatory Access Control
+are encouraged to compare Smack with the other mechanisms
+available to determine which is best suited to the problem
+at hand.
+
+Smack consists of three major components:
+    - The kernel
+    - A start-up script and a few modified applications
+    - Configuration data
+
+The kernel component of Smack is implemented as a Linux
+Security Modules (LSM) module. It requires netlabel and
+works best with file systems that support extended attributes,
+although xattr support is not strictly required.
+It is safe to run a Smack kernel under a "vanilla" distribution.
+Smack kernels use the CIPSO IP option. Some network
+configurations are intolerant of IP options and can impede
+access to systems that use them as Smack does.
+
+The startup script etc-init.d-smack should be installed
+in /etc/init.d/smack and should be invoked early in the
+start-up process. On Fedora rc5.d/S02smack is recommended.
+This script ensures that certain devices have the correct
+Smack attributes and loads the Smack configuration if
+any is defined. This script invokes two programs that
+ensure configuration data is properly formatted. These
+programs are /usr/sbin/smackload and /usr/sin/smackcipso.
+The system will run just fine without these programs,
+but it will be difficult to set access rules properly.
+
+A version of "ls" that provides a "-M" option to display
+Smack labels on long listing is available.
+
+A hacked version of sshd that allows network logins by users
+with specific Smack labels is available. This version does
+not work for scp. You must set the /etc/ssh/sshd_config
+line:
+   UsePrivilegeSeparation no
+
+The format of /etc/smack/usr is:
+
+   username smack
+
+In keeping with the intent of Smack, configuration data is
+minimal and not strictly required. The most important
+configuration step is mounting the smackfs pseudo filesystem.
+
+Add this line to /etc/fstab:
+
+    smackfs /smack smackfs smackfsdef=* 0 0
+
+and create the /smack directory for mounting.
+
+Smack uses extended attributes (xattrs) to store file labels.
+The command to set a Smack label on a file is:
+
+    # attr -S -s SMACK64 -V "value" path
+
+NOTE: Smack labels are limited to 23 characters. The attr command
+      does not enforce this restriction and can be used to set
+      invalid Smack labels on files.
+
+If you don't do anything special all users will get the floor ("_")
+label when they log in. If you do want to log in via the hacked ssh
+at other labels use the attr command to set the smack value on the
+home directory and its contents.
+
+You can add access rules in /etc/smack/accesses. They take the form:
+
+    subjectlabel objectlabel access
+
+access is a combination of the letters rwxa which specify the
+kind of access permitted a subject with subjectlabel on an
+object with objectlabel. If there is no rule no access is allowed.
+
+A process can see the smack label it is running with by
+reading /proc/self/attr/current. A privileged process can
+set the process smack by writing there.
+
+Look for additional programs on http://schaufler-ca.com
+
+From the Smack Whitepaper:
+
+The Simplified Mandatory Access Control Kernel
+
+Casey Schaufler
+casey@schaufler-ca.com
+
+Mandatory Access Control
+
+Computer systems employ a variety of schemes to constrain how information is
+shared among the people and services using the machine. Some of these schemes
+allow the program or user to decide what other programs or users are allowed
+access to pieces of data. These schemes are called discretionary access
+control mechanisms because the access control is specified at the discretion
+of the user. Other schemes do not leave the decision regarding what a user or
+program can access up to users or programs. These schemes are called mandatory
+access control mechanisms because you don't have a choice regarding the users
+or programs that have access to pieces of data.
+
+Bell & LaPadula
+
+From the middle of the 1980's until the turn of the century Mandatory Access
+Control (MAC) was very closely associated with the Bell & LaPadula security
+model, a mathematical description of the United States Department of Defense
+policy for marking paper documents. MAC in this form enjoyed a following
+within the Capital Beltway and Scandinavian supercomputer centers but was
+often sited as failing to address general needs.
+
+Domain Type Enforcement
+
+Around the turn of the century Domain Type Enforcement (DTE) became popular.
+This scheme organizes users, programs, and data into domains that are
+protected from each other. This scheme has been widely deployed as a component
+of popular Linux distributions. The administrative overhead required to
+maintain this scheme and the detailed understanding of the whole system
+necessary to provide a secure domain mapping leads to the scheme being
+disabled or used in limited ways in the majority of cases.
+
+Smack
+
+Smack is a Mandatory Access Control mechanism designed to provide useful MAC
+while avoiding the pitfalls of its predecessors. The limitations of Bell &
+LaPadula are addressed by providing a scheme whereby access can be controlled
+according to the requirements of the system and its purpose rather than those
+imposed by an arcane government policy. The complexity of Domain Type
+Enforcement and avoided by defining access controls in terms of the access
+modes already in use.
+
+Smack Terminology
+
+The jargon used to talk about Smack will be familiar to those who have dealt
+with other MAC systems and shouldn't be too difficult for the uninitiated to
+pick up. There are four terms that are used in a specific way and that are
+especially important:
+
+	Subject: A subject is an active entity on the computer system.
+	On Smack a subject is a task, which is in turn the basic unit
+	of execution.
+
+	Object: An object is a passive entity on the computer system.
+	On Smack files of all types, IPC, and tasks can be objects.
+
+	Access: Any attempt by a subject to put information into or get
+	information from an object is an access.
+
+	Label: Data that identifies the Mandatory Access Control
+	characteristics of a subject or an object.
+
+These definitions are consistent with the traditional use in the security
+community. There are also some terms from Linux that are likely to crop up:
+
+	Capability: A task that possesses a capability has permission to
+	violate an aspect of the system security policy, as identified by
+	the specific capability. A task that possesses one or more
+	capabilities is a privileged task, whereas a task with no
+	capabilities is an unprivileged task.
+
+	Privilege: A task that is allowed to violate the system security
+	policy is said to have privilege. As of this writing a task can
+	have privilege either by possessing capabilities or by having an
+	effective user of root.
+
+Smack Basics
+
+Smack is an extension to a Linux system. It enforces additional restrictions
+on what subjects can access which objects, based on the labels attached to
+each of the subject and the object.
+
+Labels
+
+Smack labels are ASCII character strings, one to twenty-three characters in
+length. Single character labels using special characters, that being anything
+other than a letter or digit, are reserved for use by the Smack development
+team. Smack labels are unstructured, case sensitive, and the only operation
+ever performed on them is comparison for equality. Smack labels cannot
+contain unprintable characters, the "/" (slash), the "\" (backslash), the "'"
+(quote) and '"' (double-quote) characters.
+Smack labels cannot begin with a '-', which is reserved for special options.
+
+There are some predefined labels:
+
+	_ 	Pronounced "floor", a single underscore character.
+	^ 	Pronounced "hat", a single circumflex character.
+	* 	Pronounced "star", a single asterisk character.
+	? 	Pronounced "huh", a single question mark character.
+	@ 	Pronounced "Internet", a single at sign character.
+
+Every task on a Smack system is assigned a label. System tasks, such as
+init(8) and systems daemons, are run with the floor ("_") label. User tasks
+are assigned labels according to the specification found in the
+/etc/smack/user configuration file.
+
+Access Rules
+
+Smack uses the traditional access modes of Linux. These modes are read,
+execute, write, and occasionally append. There are a few cases where the
+access mode may not be obvious. These include:
+
+	Signals: A signal is a write operation from the subject task to
+	the object task.
+	Internet Domain IPC: Transmission of a packet is considered a
+	write operation from the source task to the destination task.
+
+Smack restricts access based on the label attached to a subject and the label
+attached to the object it is trying to access. The rules enforced are, in
+order:
+
+	1. Any access requested by a task labeled "*" is denied.
+	2. A read or execute access requested by a task labeled "^"
+	   is permitted.
+	3. A read or execute access requested on an object labeled "_"
+	   is permitted.
+	4. Any access requested on an object labeled "*" is permitted.
+	5. Any access requested by a task on an object with the same
+	   label is permitted.
+	6. Any access requested that is explicitly defined in the loaded
+	   rule set is permitted.
+	7. Any other access is denied.
+
+Smack Access Rules
+
+With the isolation provided by Smack access separation is simple. There are
+many interesting cases where limited access by subjects to objects with
+different labels is desired. One example is the familiar spy model of
+sensitivity, where a scientist working on a highly classified project would be
+able to read documents of lower classifications and anything she writes will
+be "born" highly classified. To accommodate such schemes Smack includes a
+mechanism for specifying rules allowing access between labels.
+
+Access Rule Format
+
+The format of an access rule is:
+
+	subject-label object-label access
+
+Where subject-label is the Smack label of the task, object-label is the Smack
+label of the thing being accessed, and access is a string specifying the sort
+of access allowed. The Smack labels are limited to 23 characters. The access
+specification is searched for letters that describe access modes:
+
+	a: indicates that append access should be granted.
+	r: indicates that read access should be granted.
+	w: indicates that write access should be granted.
+	x: indicates that execute access should be granted.
+
+Uppercase values for the specification letters are allowed as well.
+Access mode specifications can be in any order. Examples of acceptable rules
+are:
+
+	TopSecret Secret  rx
+	Secret    Unclass R
+	Manager   Game    x
+	User      HR      w
+	New       Old     rRrRr
+	Closed    Off     -
+
+Examples of unacceptable rules are:
+
+	Top Secret Secret     rx
+	Ace        Ace        r
+	Odd        spells     waxbeans
+
+Spaces are not allowed in labels. Since a subject always has access to files
+with the same label specifying a rule for that case is pointless. Only
+valid letters (rwxaRWXA) and the dash ('-') character are allowed in
+access specifications. The dash is a placeholder, so "a-r" is the same
+as "ar". A lone dash is used to specify that no access should be allowed.
+
+Applying Access Rules
+
+The developers of Linux rarely define new sorts of things, usually importing
+schemes and concepts from other systems. Most often, the other systems are
+variants of Unix. Unix has many endearing properties, but consistency of
+access control models is not one of them. Smack strives to treat accesses as
+uniformly as is sensible while keeping with the spirit of the underlying
+mechanism.
+
+File system objects including files, directories, named pipes, symbolic links,
+and devices require access permissions that closely match those used by mode
+bit access. To open a file for reading read access is required on the file. To
+search a directory requires execute access. Creating a file with write access
+requires both read and write access on the containing directory. Deleting a
+file requires read and write access to the file and to the containing
+directory. It is possible that a user may be able to see that a file exists
+but not any of its attributes by the circumstance of having read access to the
+containing directory but not to the differently labeled file. This is an
+artifact of the file name being data in the directory, not a part of the file.
+
+IPC objects, message queues, semaphore sets, and memory segments exist in flat
+namespaces and access requests are only required to match the object in
+question.
+
+Process objects reflect tasks on the system and the Smack label used to access
+them is the same Smack label that the task would use for its own access
+attempts. Sending a signal via the kill() system call is a write operation
+from the signaler to the recipient. Debugging a process requires both reading
+and writing. Creating a new task is an internal operation that results in two
+tasks with identical Smack labels and requires no access checks.
+
+Sockets are data structures attached to processes and sending a packet from
+one process to another requires that the sender have write access to the
+receiver. The receiver is not required to have read access to the sender.
+
+Setting Access Rules
+
+The configuration file /etc/smack/accesses contains the rules to be set at
+system startup. The contents are written to the special file /smack/load.
+Rules can be written to /smack/load at any time and take effect immediately.
+For any pair of subject and object labels there can be only one rule, with the
+most recently specified overriding any earlier specification.
+
+The program smackload is provided to ensure data is formatted
+properly when written to /smack/load. This program reads lines
+of the form
+
+    subjectlabel objectlabel mode.
+
+Task Attribute
+
+The Smack label of a process can be read from /proc/<pid>/attr/current. A
+process can read its own Smack label from /proc/self/attr/current. A
+privileged process can change its own Smack label by writing to
+/proc/self/attr/current but not the label of another process.
+
+File Attribute
+
+The Smack label of a filesystem object is stored as an extended attribute
+named SMACK64 on the file. This attribute is in the security namespace. It can
+only be changed by a process with privilege.
+
+Privilege
+
+A process with CAP_MAC_OVERRIDE is privileged.
+
+Smack Networking
+
+As mentioned before, Smack enforces access control on network protocol
+transmissions. Every packet sent by a Smack process is tagged with its Smack
+label. This is done by adding a CIPSO tag to the header of the IP packet. Each
+packet received is expected to have a CIPSO tag that identifies the label and
+if it lacks such a tag the network ambient label is assumed. Before the packet
+is delivered a check is made to determine that a subject with the label on the
+packet has write access to the receiving process and if that is not the case
+the packet is dropped.
+
+CIPSO Configuration
+
+It is normally unnecessary to specify the CIPSO configuration. The default
+values used by the system handle all internal cases. Smack will compose CIPSO
+label values to match the Smack labels being used without administrative
+intervention. Unlabeled packets that come into the system will be given the
+ambient label.
+
+Smack requires configuration in the case where packets from a system that is
+not smack that speaks CIPSO may be encountered. Usually this will be a Trusted
+Solaris system, but there are other, less widely deployed systems out there.
+CIPSO provides 3 important values, a Domain Of Interpretation (DOI), a level,
+and a category set with each packet. The DOI is intended to identify a group
+of systems that use compatible labeling schemes, and the DOI specified on the
+smack system must match that of the remote system or packets will be
+discarded. The DOI is 3 by default. The value can be read from /smack/doi and
+can be changed by writing to /smack/doi.
+
+The label and category set are mapped to a Smack label as defined in
+/etc/smack/cipso.
+
+A Smack/CIPSO mapping has the form:
+
+	smack level [category [category]*]
+
+Smack does not expect the level or category sets to be related in any
+particular way and does not assume or assign accesses based on them. Some
+examples of mappings:
+
+	TopSecret 7
+	TS:A,B    7 1 2
+	SecBDE    5 2 4 6
+	RAFTERS   7 12 26
+
+The ":" and "," characters are permitted in a Smack label but have no special
+meaning.
+
+The mapping of Smack labels to CIPSO values is defined by writing to
+/smack/cipso. Again, the format of data written to this special file
+is highly restrictive, so the program smackcipso is provided to
+ensure the writes are done properly. This program takes mappings
+on the standard input and sends them to /smack/cipso properly.
+
+In addition to explicit mappings Smack supports direct CIPSO mappings. One
+CIPSO level is used to indicate that the category set passed in the packet is
+in fact an encoding of the Smack label. The level used is 250 by default. The
+value can be read from /smack/direct and changed by writing to /smack/direct.
+
+Socket Attributes
+
+There are two attributes that are associated with sockets. These attributes
+can only be set by privileged tasks, but any task can read them for their own
+sockets.
+
+	SMACK64IPIN: The Smack label of the task object. A privileged
+	program that will enforce policy may set this to the star label.
+
+	SMACK64IPOUT: The Smack label transmitted with outgoing packets.
+	A privileged program may set this to match the label of another
+	task with which it hopes to communicate.
+
+Smack Netlabel Exceptions
+
+You will often find that your labeled application has to talk to the outside,
+unlabeled world. To do this there's a special file /smack/netlabel where you can
+add some exceptions in the form of :
+@IP1	   LABEL1 or
+@IP2/MASK  LABEL2
+
+It means that your application will have unlabeled access to @IP1 if it has
+write access on LABEL1, and access to the subnet @IP2/MASK if it has write
+access on LABEL2.
+
+Entries in the /smack/netlabel file are matched by longest mask first, like in
+classless IPv4 routing.
+
+A special label '@' and an option '-CIPSO' can be used there :
+@      means Internet, any application with any label has access to it
+-CIPSO means standard CIPSO networking
+
+If you don't know what CIPSO is and don't plan to use it, you can just do :
+echo 127.0.0.1 -CIPSO > /smack/netlabel
+echo 0.0.0.0/0 @      > /smack/netlabel
+
+If you use CIPSO on your 192.168.0.0/16 local network and need also unlabeled
+Internet access, you can have :
+echo 127.0.0.1      -CIPSO > /smack/netlabel
+echo 192.168.0.0/16 -CIPSO > /smack/netlabel
+echo 0.0.0.0/0      @      > /smack/netlabel
+
+
+Writing Applications for Smack
+
+There are three sorts of applications that will run on a Smack system. How an
+application interacts with Smack will determine what it will have to do to
+work properly under Smack.
+
+Smack Ignorant Applications
+
+By far the majority of applications have no reason whatever to care about the
+unique properties of Smack. Since invoking a program has no impact on the
+Smack label associated with the process the only concern likely to arise is
+whether the process has execute access to the program.
+
+Smack Relevant Applications
+
+Some programs can be improved by teaching them about Smack, but do not make
+any security decisions themselves. The utility ls(1) is one example of such a
+program.
+
+Smack Enforcing Applications
+
+These are special programs that not only know about Smack, but participate in
+the enforcement of system policy. In most cases these are the programs that
+set up user sessions. There are also network services that provide information
+to processes running with various labels.
+
+File System Interfaces
+
+Smack maintains labels on file system objects using extended attributes. The
+Smack label of a file, directory, or other file system object can be obtained
+using getxattr(2).
+
+	len = getxattr("/", "security.SMACK64", value, sizeof (value));
+
+will put the Smack label of the root directory into value. A privileged
+process can set the Smack label of a file system object with setxattr(2).
+
+	len = strlen("Rubble");
+	rc = setxattr("/foo", "security.SMACK64", "Rubble", len, 0);
+
+will set the Smack label of /foo to "Rubble" if the program has appropriate
+privilege.
+
+Socket Interfaces
+
+The socket attributes can be read using fgetxattr(2).
+
+A privileged process can set the Smack label of outgoing packets with
+fsetxattr(2).
+
+	len = strlen("Rubble");
+	rc = fsetxattr(fd, "security.SMACK64IPOUT", "Rubble", len, 0);
+
+will set the Smack label "Rubble" on packets going out from the socket if the
+program has appropriate privilege.
+
+	rc = fsetxattr(fd, "security.SMACK64IPIN, "*", strlen("*"), 0);
+
+will set the Smack label "*" as the object label against which incoming
+packets will be checked if the program has appropriate privilege.
+
+Administration
+
+Smack supports some mount options:
+
+	smackfsdef=label: specifies the label to give files that lack
+	the Smack label extended attribute.
+
+	smackfsroot=label: specifies the label to assign the root of the
+	file system if it lacks the Smack extended attribute.
+
+	smackfshat=label: specifies a label that must have read access to
+	all labels set on the filesystem. Not yet enforced.
+
+	smackfsfloor=label: specifies a label to which all labels set on the
+	filesystem must have read access. Not yet enforced.
+
+These mount options apply to all file system types.
+
+Smack auditing
+
+If you want Smack auditing of security events, you need to set CONFIG_AUDIT
+in your kernel configuration.
+By default, all denied events will be audited. You can change this behavior by
+writing a single character to the /smack/logging file :
+0 : no logging
+1 : log denied (default)
+2 : log accepted
+3 : log denied & accepted
+
+Events are logged as 'key=value' pairs, for each event you at least will get
+the subjet, the object, the rights requested, the action, the kernel function
+that triggered the event, plus other pairs depending on the type of event
+audited.
diff -druN linux-2.6.39-libre/Documentation/security/tomoyo.txt linux-3.0-rc7-libre/Documentation/security/tomoyo.txt
--- linux-2.6.39-libre/Documentation/security/tomoyo.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/Documentation/security/tomoyo.txt	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,55 @@
+--- What is TOMOYO? ---
+
+TOMOYO is a name-based MAC extension (LSM module) for the Linux kernel.
+
+LiveCD-based tutorials are available at
+http://tomoyo.sourceforge.jp/1.7/1st-step/ubuntu10.04-live/
+http://tomoyo.sourceforge.jp/1.7/1st-step/centos5-live/ .
+Though these tutorials use non-LSM version of TOMOYO, they are useful for you
+to know what TOMOYO is.
+
+--- How to enable TOMOYO? ---
+
+Build the kernel with CONFIG_SECURITY_TOMOYO=y and pass "security=tomoyo" on
+kernel's command line.
+
+Please see http://tomoyo.sourceforge.jp/2.3/ for details.
+
+--- Where is documentation? ---
+
+User <-> Kernel interface documentation is available at
+http://tomoyo.sourceforge.jp/2.3/policy-reference.html .
+
+Materials we prepared for seminars and symposiums are available at
+http://sourceforge.jp/projects/tomoyo/docs/?category_id=532&language_id=1 .
+Below lists are chosen from three aspects.
+
+What is TOMOYO?
+  TOMOYO Linux Overview
+    http://sourceforge.jp/projects/tomoyo/docs/lca2009-takeda.pdf
+  TOMOYO Linux: pragmatic and manageable security for Linux
+    http://sourceforge.jp/projects/tomoyo/docs/freedomhectaipei-tomoyo.pdf
+  TOMOYO Linux: A Practical Method to Understand and Protect Your Own Linux Box
+    http://sourceforge.jp/projects/tomoyo/docs/PacSec2007-en-no-demo.pdf
+
+What can TOMOYO do?
+  Deep inside TOMOYO Linux
+    http://sourceforge.jp/projects/tomoyo/docs/lca2009-kumaneko.pdf
+  The role of "pathname based access control" in security.
+    http://sourceforge.jp/projects/tomoyo/docs/lfj2008-bof.pdf
+
+History of TOMOYO?
+  Realities of Mainlining
+    http://sourceforge.jp/projects/tomoyo/docs/lfj2008.pdf
+
+--- What is future plan? ---
+
+We believe that inode based security and name based security are complementary
+and both should be used together. But unfortunately, so far, we cannot enable
+multiple LSM modules at the same time. We feel sorry that you have to give up
+SELinux/SMACK/AppArmor etc. when you want to use TOMOYO.
+
+We hope that LSM becomes stackable in future. Meanwhile, you can use non-LSM
+version of TOMOYO, available at http://tomoyo.sourceforge.jp/1.7/ .
+LSM version of TOMOYO is a subset of non-LSM version of TOMOYO. We are planning
+to port non-LSM version's functionalities to LSM versions.
diff -druN linux-2.6.39-libre/Documentation/SELinux.txt linux-3.0-rc7-libre/Documentation/SELinux.txt
--- linux-2.6.39-libre/Documentation/SELinux.txt	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/Documentation/SELinux.txt	1969-12-31 19:00:00.000000000 -0500
@@ -1,27 +0,0 @@
-If you want to use SELinux, chances are you will want
-to use the distro-provided policies, or install the
-latest reference policy release from
-	http://oss.tresys.com/projects/refpolicy
-
-However, if you want to install a dummy policy for
-testing, you can do using 'mdp' provided under
-scripts/selinux.  Note that this requires the selinux
-userspace to be installed - in particular you will
-need checkpolicy to compile a kernel, and setfiles and
-fixfiles to label the filesystem.
-
-	1. Compile the kernel with selinux enabled.
-	2. Type 'make' to compile mdp.
-	3. Make sure that you are not running with
-	   SELinux enabled and a real policy.  If
-	   you are, reboot with selinux disabled
-	   before continuing.
-	4. Run install_policy.sh:
-		cd scripts/selinux
-		sh install_policy.sh
-
-Step 4 will create a new dummy policy valid for your
-kernel, with a single selinux user, role, and type.
-It will compile the policy, will set your SELINUXTYPE to
-dummy in /etc/selinux/config, install the compiled policy
-as 'dummy', and relabel your filesystem.
diff -druN linux-2.6.39-libre/Documentation/Smack.txt linux-3.0-rc7-libre/Documentation/Smack.txt
--- linux-2.6.39-libre/Documentation/Smack.txt	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/Documentation/Smack.txt	1969-12-31 19:00:00.000000000 -0500
@@ -1,541 +0,0 @@
-
-
-    "Good for you, you've decided to clean the elevator!"
-    - The Elevator, from Dark Star
-
-Smack is the the Simplified Mandatory Access Control Kernel.
-Smack is a kernel based implementation of mandatory access
-control that includes simplicity in its primary design goals.
-
-Smack is not the only Mandatory Access Control scheme
-available for Linux. Those new to Mandatory Access Control
-are encouraged to compare Smack with the other mechanisms
-available to determine which is best suited to the problem
-at hand.
-
-Smack consists of three major components:
-    - The kernel
-    - A start-up script and a few modified applications
-    - Configuration data
-
-The kernel component of Smack is implemented as a Linux
-Security Modules (LSM) module. It requires netlabel and
-works best with file systems that support extended attributes,
-although xattr support is not strictly required.
-It is safe to run a Smack kernel under a "vanilla" distribution.
-Smack kernels use the CIPSO IP option. Some network
-configurations are intolerant of IP options and can impede
-access to systems that use them as Smack does.
-
-The startup script etc-init.d-smack should be installed
-in /etc/init.d/smack and should be invoked early in the
-start-up process. On Fedora rc5.d/S02smack is recommended.
-This script ensures that certain devices have the correct
-Smack attributes and loads the Smack configuration if
-any is defined. This script invokes two programs that
-ensure configuration data is properly formatted. These
-programs are /usr/sbin/smackload and /usr/sin/smackcipso.
-The system will run just fine without these programs,
-but it will be difficult to set access rules properly.
-
-A version of "ls" that provides a "-M" option to display
-Smack labels on long listing is available.
-
-A hacked version of sshd that allows network logins by users
-with specific Smack labels is available. This version does
-not work for scp. You must set the /etc/ssh/sshd_config
-line:
-   UsePrivilegeSeparation no
-
-The format of /etc/smack/usr is:
-
-   username smack
-
-In keeping with the intent of Smack, configuration data is
-minimal and not strictly required. The most important
-configuration step is mounting the smackfs pseudo filesystem.
-
-Add this line to /etc/fstab:
-
-    smackfs /smack smackfs smackfsdef=* 0 0
-
-and create the /smack directory for mounting.
-
-Smack uses extended attributes (xattrs) to store file labels.
-The command to set a Smack label on a file is:
-
-    # attr -S -s SMACK64 -V "value" path
-
-NOTE: Smack labels are limited to 23 characters. The attr command
-      does not enforce this restriction and can be used to set
-      invalid Smack labels on files.
-
-If you don't do anything special all users will get the floor ("_")
-label when they log in. If you do want to log in via the hacked ssh
-at other labels use the attr command to set the smack value on the
-home directory and its contents.
-
-You can add access rules in /etc/smack/accesses. They take the form:
-
-    subjectlabel objectlabel access
-
-access is a combination of the letters rwxa which specify the
-kind of access permitted a subject with subjectlabel on an
-object with objectlabel. If there is no rule no access is allowed.
-
-A process can see the smack label it is running with by
-reading /proc/self/attr/current. A privileged process can
-set the process smack by writing there.
-
-Look for additional programs on http://schaufler-ca.com
-
-From the Smack Whitepaper:
-
-The Simplified Mandatory Access Control Kernel
-
-Casey Schaufler
-casey@schaufler-ca.com
-
-Mandatory Access Control
-
-Computer systems employ a variety of schemes to constrain how information is
-shared among the people and services using the machine. Some of these schemes
-allow the program or user to decide what other programs or users are allowed
-access to pieces of data. These schemes are called discretionary access
-control mechanisms because the access control is specified at the discretion
-of the user. Other schemes do not leave the decision regarding what a user or
-program can access up to users or programs. These schemes are called mandatory
-access control mechanisms because you don't have a choice regarding the users
-or programs that have access to pieces of data.
-
-Bell & LaPadula
-
-From the middle of the 1980's until the turn of the century Mandatory Access
-Control (MAC) was very closely associated with the Bell & LaPadula security
-model, a mathematical description of the United States Department of Defense
-policy for marking paper documents. MAC in this form enjoyed a following
-within the Capital Beltway and Scandinavian supercomputer centers but was
-often sited as failing to address general needs.
-
-Domain Type Enforcement
-
-Around the turn of the century Domain Type Enforcement (DTE) became popular.
-This scheme organizes users, programs, and data into domains that are
-protected from each other. This scheme has been widely deployed as a component
-of popular Linux distributions. The administrative overhead required to
-maintain this scheme and the detailed understanding of the whole system
-necessary to provide a secure domain mapping leads to the scheme being
-disabled or used in limited ways in the majority of cases.
-
-Smack
-
-Smack is a Mandatory Access Control mechanism designed to provide useful MAC
-while avoiding the pitfalls of its predecessors. The limitations of Bell &
-LaPadula are addressed by providing a scheme whereby access can be controlled
-according to the requirements of the system and its purpose rather than those
-imposed by an arcane government policy. The complexity of Domain Type
-Enforcement and avoided by defining access controls in terms of the access
-modes already in use.
-
-Smack Terminology
-
-The jargon used to talk about Smack will be familiar to those who have dealt
-with other MAC systems and shouldn't be too difficult for the uninitiated to
-pick up. There are four terms that are used in a specific way and that are
-especially important:
-
-	Subject: A subject is an active entity on the computer system.
-	On Smack a subject is a task, which is in turn the basic unit
-	of execution.
-
-	Object: An object is a passive entity on the computer system.
-	On Smack files of all types, IPC, and tasks can be objects.
-
-	Access: Any attempt by a subject to put information into or get
-	information from an object is an access.
-
-	Label: Data that identifies the Mandatory Access Control
-	characteristics of a subject or an object.
-
-These definitions are consistent with the traditional use in the security
-community. There are also some terms from Linux that are likely to crop up:
-
-	Capability: A task that possesses a capability has permission to
-	violate an aspect of the system security policy, as identified by
-	the specific capability. A task that possesses one or more
-	capabilities is a privileged task, whereas a task with no
-	capabilities is an unprivileged task.
-
-	Privilege: A task that is allowed to violate the system security
-	policy is said to have privilege. As of this writing a task can
-	have privilege either by possessing capabilities or by having an
-	effective user of root.
-
-Smack Basics
-
-Smack is an extension to a Linux system. It enforces additional restrictions
-on what subjects can access which objects, based on the labels attached to
-each of the subject and the object.
-
-Labels
-
-Smack labels are ASCII character strings, one to twenty-three characters in
-length. Single character labels using special characters, that being anything
-other than a letter or digit, are reserved for use by the Smack development
-team. Smack labels are unstructured, case sensitive, and the only operation
-ever performed on them is comparison for equality. Smack labels cannot
-contain unprintable characters, the "/" (slash), the "\" (backslash), the "'"
-(quote) and '"' (double-quote) characters.
-Smack labels cannot begin with a '-', which is reserved for special options.
-
-There are some predefined labels:
-
-	_ 	Pronounced "floor", a single underscore character.
-	^ 	Pronounced "hat", a single circumflex character.
-	* 	Pronounced "star", a single asterisk character.
-	? 	Pronounced "huh", a single question mark character.
-	@ 	Pronounced "Internet", a single at sign character.
-
-Every task on a Smack system is assigned a label. System tasks, such as
-init(8) and systems daemons, are run with the floor ("_") label. User tasks
-are assigned labels according to the specification found in the
-/etc/smack/user configuration file.
-
-Access Rules
-
-Smack uses the traditional access modes of Linux. These modes are read,
-execute, write, and occasionally append. There are a few cases where the
-access mode may not be obvious. These include:
-
-	Signals: A signal is a write operation from the subject task to
-	the object task.
-	Internet Domain IPC: Transmission of a packet is considered a
-	write operation from the source task to the destination task.
-
-Smack restricts access based on the label attached to a subject and the label
-attached to the object it is trying to access. The rules enforced are, in
-order:
-
-	1. Any access requested by a task labeled "*" is denied.
-	2. A read or execute access requested by a task labeled "^"
-	   is permitted.
-	3. A read or execute access requested on an object labeled "_"
-	   is permitted.
-	4. Any access requested on an object labeled "*" is permitted.
-	5. Any access requested by a task on an object with the same
-	   label is permitted.
-	6. Any access requested that is explicitly defined in the loaded
-	   rule set is permitted.
-	7. Any other access is denied.
-
-Smack Access Rules
-
-With the isolation provided by Smack access separation is simple. There are
-many interesting cases where limited access by subjects to objects with
-different labels is desired. One example is the familiar spy model of
-sensitivity, where a scientist working on a highly classified project would be
-able to read documents of lower classifications and anything she writes will
-be "born" highly classified. To accommodate such schemes Smack includes a
-mechanism for specifying rules allowing access between labels.
-
-Access Rule Format
-
-The format of an access rule is:
-
-	subject-label object-label access
-
-Where subject-label is the Smack label of the task, object-label is the Smack
-label of the thing being accessed, and access is a string specifying the sort
-of access allowed. The Smack labels are limited to 23 characters. The access
-specification is searched for letters that describe access modes:
-
-	a: indicates that append access should be granted.
-	r: indicates that read access should be granted.
-	w: indicates that write access should be granted.
-	x: indicates that execute access should be granted.
-
-Uppercase values for the specification letters are allowed as well.
-Access mode specifications can be in any order. Examples of acceptable rules
-are:
-
-	TopSecret Secret  rx
-	Secret    Unclass R
-	Manager   Game    x
-	User      HR      w
-	New       Old     rRrRr
-	Closed    Off     -
-
-Examples of unacceptable rules are:
-
-	Top Secret Secret     rx
-	Ace        Ace        r
-	Odd        spells     waxbeans
-
-Spaces are not allowed in labels. Since a subject always has access to files
-with the same label specifying a rule for that case is pointless. Only
-valid letters (rwxaRWXA) and the dash ('-') character are allowed in
-access specifications. The dash is a placeholder, so "a-r" is the same
-as "ar". A lone dash is used to specify that no access should be allowed.
-
-Applying Access Rules
-
-The developers of Linux rarely define new sorts of things, usually importing
-schemes and concepts from other systems. Most often, the other systems are
-variants of Unix. Unix has many endearing properties, but consistency of
-access control models is not one of them. Smack strives to treat accesses as
-uniformly as is sensible while keeping with the spirit of the underlying
-mechanism.
-
-File system objects including files, directories, named pipes, symbolic links,
-and devices require access permissions that closely match those used by mode
-bit access. To open a file for reading read access is required on the file. To
-search a directory requires execute access. Creating a file with write access
-requires both read and write access on the containing directory. Deleting a
-file requires read and write access to the file and to the containing
-directory. It is possible that a user may be able to see that a file exists
-but not any of its attributes by the circumstance of having read access to the
-containing directory but not to the differently labeled file. This is an
-artifact of the file name being data in the directory, not a part of the file.
-
-IPC objects, message queues, semaphore sets, and memory segments exist in flat
-namespaces and access requests are only required to match the object in
-question.
-
-Process objects reflect tasks on the system and the Smack label used to access
-them is the same Smack label that the task would use for its own access
-attempts. Sending a signal via the kill() system call is a write operation
-from the signaler to the recipient. Debugging a process requires both reading
-and writing. Creating a new task is an internal operation that results in two
-tasks with identical Smack labels and requires no access checks.
-
-Sockets are data structures attached to processes and sending a packet from
-one process to another requires that the sender have write access to the
-receiver. The receiver is not required to have read access to the sender.
-
-Setting Access Rules
-
-The configuration file /etc/smack/accesses contains the rules to be set at
-system startup. The contents are written to the special file /smack/load.
-Rules can be written to /smack/load at any time and take effect immediately.
-For any pair of subject and object labels there can be only one rule, with the
-most recently specified overriding any earlier specification.
-
-The program smackload is provided to ensure data is formatted
-properly when written to /smack/load. This program reads lines
-of the form
-
-    subjectlabel objectlabel mode.
-
-Task Attribute
-
-The Smack label of a process can be read from /proc/<pid>/attr/current. A
-process can read its own Smack label from /proc/self/attr/current. A
-privileged process can change its own Smack label by writing to
-/proc/self/attr/current but not the label of another process.
-
-File Attribute
-
-The Smack label of a filesystem object is stored as an extended attribute
-named SMACK64 on the file. This attribute is in the security namespace. It can
-only be changed by a process with privilege.
-
-Privilege
-
-A process with CAP_MAC_OVERRIDE is privileged.
-
-Smack Networking
-
-As mentioned before, Smack enforces access control on network protocol
-transmissions. Every packet sent by a Smack process is tagged with its Smack
-label. This is done by adding a CIPSO tag to the header of the IP packet. Each
-packet received is expected to have a CIPSO tag that identifies the label and
-if it lacks such a tag the network ambient label is assumed. Before the packet
-is delivered a check is made to determine that a subject with the label on the
-packet has write access to the receiving process and if that is not the case
-the packet is dropped.
-
-CIPSO Configuration
-
-It is normally unnecessary to specify the CIPSO configuration. The default
-values used by the system handle all internal cases. Smack will compose CIPSO
-label values to match the Smack labels being used without administrative
-intervention. Unlabeled packets that come into the system will be given the
-ambient label.
-
-Smack requires configuration in the case where packets from a system that is
-not smack that speaks CIPSO may be encountered. Usually this will be a Trusted
-Solaris system, but there are other, less widely deployed systems out there.
-CIPSO provides 3 important values, a Domain Of Interpretation (DOI), a level,
-and a category set with each packet. The DOI is intended to identify a group
-of systems that use compatible labeling schemes, and the DOI specified on the
-smack system must match that of the remote system or packets will be
-discarded. The DOI is 3 by default. The value can be read from /smack/doi and
-can be changed by writing to /smack/doi.
-
-The label and category set are mapped to a Smack label as defined in
-/etc/smack/cipso.
-
-A Smack/CIPSO mapping has the form:
-
-	smack level [category [category]*]
-
-Smack does not expect the level or category sets to be related in any
-particular way and does not assume or assign accesses based on them. Some
-examples of mappings:
-
-	TopSecret 7
-	TS:A,B    7 1 2
-	SecBDE    5 2 4 6
-	RAFTERS   7 12 26
-
-The ":" and "," characters are permitted in a Smack label but have no special
-meaning.
-
-The mapping of Smack labels to CIPSO values is defined by writing to
-/smack/cipso. Again, the format of data written to this special file
-is highly restrictive, so the program smackcipso is provided to
-ensure the writes are done properly. This program takes mappings
-on the standard input and sends them to /smack/cipso properly.
-
-In addition to explicit mappings Smack supports direct CIPSO mappings. One
-CIPSO level is used to indicate that the category set passed in the packet is
-in fact an encoding of the Smack label. The level used is 250 by default. The
-value can be read from /smack/direct and changed by writing to /smack/direct.
-
-Socket Attributes
-
-There are two attributes that are associated with sockets. These attributes
-can only be set by privileged tasks, but any task can read them for their own
-sockets.
-
-	SMACK64IPIN: The Smack label of the task object. A privileged
-	program that will enforce policy may set this to the star label.
-
-	SMACK64IPOUT: The Smack label transmitted with outgoing packets.
-	A privileged program may set this to match the label of another
-	task with which it hopes to communicate.
-
-Smack Netlabel Exceptions
-
-You will often find that your labeled application has to talk to the outside,
-unlabeled world. To do this there's a special file /smack/netlabel where you can
-add some exceptions in the form of :
-@IP1	   LABEL1 or
-@IP2/MASK  LABEL2
-
-It means that your application will have unlabeled access to @IP1 if it has
-write access on LABEL1, and access to the subnet @IP2/MASK if it has write
-access on LABEL2.
-
-Entries in the /smack/netlabel file are matched by longest mask first, like in
-classless IPv4 routing.
-
-A special label '@' and an option '-CIPSO' can be used there :
-@      means Internet, any application with any label has access to it
--CIPSO means standard CIPSO networking
-
-If you don't know what CIPSO is and don't plan to use it, you can just do :
-echo 127.0.0.1 -CIPSO > /smack/netlabel
-echo 0.0.0.0/0 @      > /smack/netlabel
-
-If you use CIPSO on your 192.168.0.0/16 local network and need also unlabeled
-Internet access, you can have :
-echo 127.0.0.1      -CIPSO > /smack/netlabel
-echo 192.168.0.0/16 -CIPSO > /smack/netlabel
-echo 0.0.0.0/0      @      > /smack/netlabel
-
-
-Writing Applications for Smack
-
-There are three sorts of applications that will run on a Smack system. How an
-application interacts with Smack will determine what it will have to do to
-work properly under Smack.
-
-Smack Ignorant Applications
-
-By far the majority of applications have no reason whatever to care about the
-unique properties of Smack. Since invoking a program has no impact on the
-Smack label associated with the process the only concern likely to arise is
-whether the process has execute access to the program.
-
-Smack Relevant Applications
-
-Some programs can be improved by teaching them about Smack, but do not make
-any security decisions themselves. The utility ls(1) is one example of such a
-program.
-
-Smack Enforcing Applications
-
-These are special programs that not only know about Smack, but participate in
-the enforcement of system policy. In most cases these are the programs that
-set up user sessions. There are also network services that provide information
-to processes running with various labels.
-
-File System Interfaces
-
-Smack maintains labels on file system objects using extended attributes. The
-Smack label of a file, directory, or other file system object can be obtained
-using getxattr(2).
-
-	len = getxattr("/", "security.SMACK64", value, sizeof (value));
-
-will put the Smack label of the root directory into value. A privileged
-process can set the Smack label of a file system object with setxattr(2).
-
-	len = strlen("Rubble");
-	rc = setxattr("/foo", "security.SMACK64", "Rubble", len, 0);
-
-will set the Smack label of /foo to "Rubble" if the program has appropriate
-privilege.
-
-Socket Interfaces
-
-The socket attributes can be read using fgetxattr(2).
-
-A privileged process can set the Smack label of outgoing packets with
-fsetxattr(2).
-
-	len = strlen("Rubble");
-	rc = fsetxattr(fd, "security.SMACK64IPOUT", "Rubble", len, 0);
-
-will set the Smack label "Rubble" on packets going out from the socket if the
-program has appropriate privilege.
-
-	rc = fsetxattr(fd, "security.SMACK64IPIN, "*", strlen("*"), 0);
-
-will set the Smack label "*" as the object label against which incoming
-packets will be checked if the program has appropriate privilege.
-
-Administration
-
-Smack supports some mount options:
-
-	smackfsdef=label: specifies the label to give files that lack
-	the Smack label extended attribute.
-
-	smackfsroot=label: specifies the label to assign the root of the
-	file system if it lacks the Smack extended attribute.
-
-	smackfshat=label: specifies a label that must have read access to
-	all labels set on the filesystem. Not yet enforced.
-
-	smackfsfloor=label: specifies a label to which all labels set on the
-	filesystem must have read access. Not yet enforced.
-
-These mount options apply to all file system types.
-
-Smack auditing
-
-If you want Smack auditing of security events, you need to set CONFIG_AUDIT
-in your kernel configuration.
-By default, all denied events will be audited. You can change this behavior by
-writing a single character to the /smack/logging file :
-0 : no logging
-1 : log denied (default)
-2 : log accepted
-3 : log denied & accepted
-
-Events are logged as 'key=value' pairs, for each event you at least will get
-the subjet, the object, the rights requested, the action, the kernel function
-that triggered the event, plus other pairs depending on the type of event
-audited.
diff -druN linux-2.6.39-libre/Documentation/sound/alsa/ALSA-Configuration.txt linux-3.0-rc7-libre/Documentation/sound/alsa/ALSA-Configuration.txt
--- linux-2.6.39-libre/Documentation/sound/alsa/ALSA-Configuration.txt	2011-05-19 02:20:53.000000000 -0400
+++ linux-3.0-rc7-libre/Documentation/sound/alsa/ALSA-Configuration.txt	2011-07-21 07:03:23.000000000 -0400
@@ -1230,6 +1230,13 @@
     This module supports multiple cards.
     The driver requires the firmware loader support on kernel.
 
+  Module snd-lola
+  ---------------
+
+    Module for Digigram Lola PCI-e boards
+
+    This module supports multiple cards.
+
   Module snd-lx6464es
   -------------------
 
diff -druN linux-2.6.39-libre/Documentation/sound/alsa/HD-Audio-Models.txt linux-3.0-rc7-libre/Documentation/sound/alsa/HD-Audio-Models.txt
--- linux-2.6.39-libre/Documentation/sound/alsa/HD-Audio-Models.txt	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/Documentation/sound/alsa/HD-Audio-Models.txt	2011-07-11 19:51:52.000000000 -0400
@@ -94,7 +94,7 @@
   3stack-dig	3-stack (2-channel) with SPDIF
   3stack-6ch	 3-stack (6-channel)
   3stack-6ch-dig 3-stack (6-channel) with SPDIF
-  6stack-dig	 6-stack with SPDIF
+  5stack-dig	 5-stack with SPDIF
   lenovo-101e	 Lenovo laptop
   eeepc-p701	ASUS Eeepc P701
   eeepc-ep20	ASUS Eeepc EP20
diff -druN linux-2.6.39-libre/Documentation/spinlocks.txt linux-3.0-rc7-libre/Documentation/spinlocks.txt
--- linux-2.6.39-libre/Documentation/spinlocks.txt	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/Documentation/spinlocks.txt	2011-07-11 19:51:52.000000000 -0400
@@ -13,18 +13,8 @@
 The above is always safe. It will disable interrupts _locally_, but the
 spinlock itself will guarantee the global lock, so it will guarantee that
 there is only one thread-of-control within the region(s) protected by that
-lock. This works well even under UP. The above sequence under UP
-essentially is just the same as doing
-
-	unsigned long flags;
-
-	save_flags(flags); cli();
-	 ... critical section ...
-	restore_flags(flags);
-
-so the code does _not_ need to worry about UP vs SMP issues: the spinlocks
-work correctly under both (and spinlocks are actually more efficient on
-architectures that allow doing the "save_flags + cli" in one operation).
+lock. This works well even under UP also, so the code does _not_ need to
+worry about UP vs SMP issues: the spinlocks work correctly under both.
 
    NOTE! Implications of spin_locks for memory are further described in:
 
@@ -36,27 +26,7 @@
 spinlock for most things - using more than one spinlock can make things a
 lot more complex and even slower and is usually worth it only for
 sequences that you _know_ need to be split up: avoid it at all cost if you
-aren't sure). HOWEVER, it _does_ mean that if you have some code that does
-
-	cli();
-	.. critical section ..
-	sti();
-
-and another sequence that does
-
-	spin_lock_irqsave(flags);
-	.. critical section ..
-	spin_unlock_irqrestore(flags);
-
-then they are NOT mutually exclusive, and the critical regions can happen
-at the same time on two different CPU's. That's fine per se, but the
-critical regions had better be critical for different things (ie they
-can't stomp on each other).
-
-The above is a problem mainly if you end up mixing code - for example the
-routines in ll_rw_block() tend to use cli/sti to protect the atomicity of
-their actions, and if a driver uses spinlocks instead then you should
-think about issues like the above.
+aren't sure).
 
 This is really the only really hard part about spinlocks: once you start
 using spinlocks they tend to expand to areas you might not have noticed
@@ -120,11 +90,10 @@
 
 The single spin-lock primitives above are by no means the only ones. They
 are the most safe ones, and the ones that work under all circumstances,
-but partly _because_ they are safe they are also fairly slow. They are
-much faster than a generic global cli/sti pair, but slower than they'd
-need to be, because they do have to disable interrupts (which is just a
-single instruction on a x86, but it's an expensive one - and on other
-architectures it can be worse).
+but partly _because_ they are safe they are also fairly slow. They are slower
+than they'd need to be, because they do have to disable interrupts
+(which is just a single instruction on a x86, but it's an expensive one -
+and on other architectures it can be worse).
 
 If you have a case where you have to protect a data structure across
 several CPU's and you want to use spinlocks you can potentially use
diff -druN linux-2.6.39-libre/Documentation/stable_api_nonsense.txt linux-3.0-rc7-libre/Documentation/stable_api_nonsense.txt
--- linux-2.6.39-libre/Documentation/stable_api_nonsense.txt	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/Documentation/stable_api_nonsense.txt	2011-07-11 19:51:52.000000000 -0400
@@ -122,7 +122,7 @@
 
 In both of these instances, all developers agreed that these were
 important changes that needed to be made, and they were made, with
-relatively little pain.  If Linux had to ensure that it preserve a
+relatively little pain.  If Linux had to ensure that it will preserve a
 stable source interface, a new interface would have been created, and
 the older, broken one would have had to be maintained over time, leading
 to extra work for the USB developers.  Since all Linux USB developers do
diff -druN linux-2.6.39-libre/Documentation/SubmittingPatches linux-3.0-rc7-libre/Documentation/SubmittingPatches
--- linux-2.6.39-libre/Documentation/SubmittingPatches	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/Documentation/SubmittingPatches	2011-07-11 19:51:52.000000000 -0400
@@ -714,10 +714,11 @@
   <http://linux.yyz.us/patch-format.html>
 
 Greg Kroah-Hartman, "How to piss off a kernel subsystem maintainer".
-  <http://www.kroah.com/log/2005/03/31/>
-  <http://www.kroah.com/log/2005/07/08/>
-  <http://www.kroah.com/log/2005/10/19/>
-  <http://www.kroah.com/log/2006/01/11/>
+  <http://www.kroah.com/log/linux/maintainer.html>
+  <http://www.kroah.com/log/linux/maintainer-02.html>
+  <http://www.kroah.com/log/linux/maintainer-03.html>
+  <http://www.kroah.com/log/linux/maintainer-04.html>
+  <http://www.kroah.com/log/linux/maintainer-05.html>
 
 NO!!!! No more huge patch bombs to linux-kernel@vger.kernel.org people!
   <http://marc.theaimsgroup.com/?l=linux-kernel&m=112112749912944&w=2>
diff -druN linux-2.6.39-libre/Documentation/sysctl/fs.txt linux-3.0-rc7-libre/Documentation/sysctl/fs.txt
--- linux-2.6.39-libre/Documentation/sysctl/fs.txt	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/Documentation/sysctl/fs.txt	2011-07-11 19:51:52.000000000 -0400
@@ -231,13 +231,6 @@
 
 This directory contains configuration options for the epoll(7) interface.
 
-max_user_instances
-------------------
-
-This is the maximum number of epoll file descriptors that a single user can
-have open at a given time. The default value is 128, and should be enough
-for normal users.
-
 max_user_watches
 ----------------
 
diff -druN linux-2.6.39-libre/Documentation/sysctl/kernel.txt linux-3.0-rc7-libre/Documentation/sysctl/kernel.txt
--- linux-2.6.39-libre/Documentation/sysctl/kernel.txt	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/Documentation/sysctl/kernel.txt	2011-07-11 19:51:52.000000000 -0400
@@ -161,7 +161,8 @@
 	%s	signal number
 	%t	UNIX time of dump
 	%h	hostname
-	%e	executable filename
+	%e	executable filename (may be shortened)
+	%E	executable path
 	%<OTHER> both are dropped
 . If the first character of the pattern is a '|', the kernel will treat
   the rest of the pattern as a command to run.  The core dump will be
diff -druN linux-2.6.39-libre/Documentation/sysctl/net.txt linux-3.0-rc7-libre/Documentation/sysctl/net.txt
--- linux-2.6.39-libre/Documentation/sysctl/net.txt	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/Documentation/sysctl/net.txt	2011-07-11 19:51:52.000000000 -0400
@@ -32,6 +32,17 @@
 1. /proc/sys/net/core - Network core options
 -------------------------------------------------------
 
+bpf_jit_enable
+--------------
+
+This enables Berkeley Packet Filter Just in Time compiler.
+Currently supported on x86_64 architecture, bpf_jit provides a framework
+to speed packet filtering, the one used by tcpdump/libpcap for example.
+Values :
+	0 - disable the JIT (default value)
+	1 - enable the JIT
+	2 - enable the JIT and ask the compiler to emit traces on kernel log.
+
 rmem_default
 ------------
 
diff -druN linux-2.6.39-libre/Documentation/sysctl/vm.txt linux-3.0-rc7-libre/Documentation/sysctl/vm.txt
--- linux-2.6.39-libre/Documentation/sysctl/vm.txt	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/Documentation/sysctl/vm.txt	2011-07-11 19:51:52.000000000 -0400
@@ -481,10 +481,10 @@
 Type(A) is called as "Node" order. Type (B) is "Zone" order.
 
 "Node order" orders the zonelists by node, then by zone within each node.
-Specify "[Nn]ode" for zone order
+Specify "[Nn]ode" for node order
 
 "Zone Order" orders the zonelists by zone type, then by node within each
-zone.  Specify "[Zz]one"for zode order.
+zone.  Specify "[Zz]one" for zone order.
 
 Specify "[Dd]efault" to request automatic configuration.  Autoconfiguration
 will select "node" order in following case.
diff -druN linux-2.6.39-libre/Documentation/timers/timers-howto.txt linux-3.0-rc7-libre/Documentation/timers/timers-howto.txt
--- linux-2.6.39-libre/Documentation/timers/timers-howto.txt	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/Documentation/timers/timers-howto.txt	2011-07-11 19:51:52.000000000 -0400
@@ -24,7 +24,7 @@
 
 	ndelay(unsigned long nsecs)
 	udelay(unsigned long usecs)
-	mdelay(unsgined long msecs)
+	mdelay(unsigned long msecs)
 
 	udelay is the generally preferred API; ndelay-level
 	precision may not actually exist on many non-PC devices.
diff -druN linux-2.6.39-libre/Documentation/tomoyo.txt linux-3.0-rc7-libre/Documentation/tomoyo.txt
--- linux-2.6.39-libre/Documentation/tomoyo.txt	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/Documentation/tomoyo.txt	1969-12-31 19:00:00.000000000 -0500
@@ -1,55 +0,0 @@
---- What is TOMOYO? ---
-
-TOMOYO is a name-based MAC extension (LSM module) for the Linux kernel.
-
-LiveCD-based tutorials are available at
-http://tomoyo.sourceforge.jp/1.7/1st-step/ubuntu10.04-live/
-http://tomoyo.sourceforge.jp/1.7/1st-step/centos5-live/ .
-Though these tutorials use non-LSM version of TOMOYO, they are useful for you
-to know what TOMOYO is.
-
---- How to enable TOMOYO? ---
-
-Build the kernel with CONFIG_SECURITY_TOMOYO=y and pass "security=tomoyo" on
-kernel's command line.
-
-Please see http://tomoyo.sourceforge.jp/2.3/ for details.
-
---- Where is documentation? ---
-
-User <-> Kernel interface documentation is available at
-http://tomoyo.sourceforge.jp/2.3/policy-reference.html .
-
-Materials we prepared for seminars and symposiums are available at
-http://sourceforge.jp/projects/tomoyo/docs/?category_id=532&language_id=1 .
-Below lists are chosen from three aspects.
-
-What is TOMOYO?
-  TOMOYO Linux Overview
-    http://sourceforge.jp/projects/tomoyo/docs/lca2009-takeda.pdf
-  TOMOYO Linux: pragmatic and manageable security for Linux
-    http://sourceforge.jp/projects/tomoyo/docs/freedomhectaipei-tomoyo.pdf
-  TOMOYO Linux: A Practical Method to Understand and Protect Your Own Linux Box
-    http://sourceforge.jp/projects/tomoyo/docs/PacSec2007-en-no-demo.pdf
-
-What can TOMOYO do?
-  Deep inside TOMOYO Linux
-    http://sourceforge.jp/projects/tomoyo/docs/lca2009-kumaneko.pdf
-  The role of "pathname based access control" in security.
-    http://sourceforge.jp/projects/tomoyo/docs/lfj2008-bof.pdf
-
-History of TOMOYO?
-  Realities of Mainlining
-    http://sourceforge.jp/projects/tomoyo/docs/lfj2008.pdf
-
---- What is future plan? ---
-
-We believe that inode based security and name based security are complementary
-and both should be used together. But unfortunately, so far, we cannot enable
-multiple LSM modules at the same time. We feel sorry that you have to give up
-SELinux/SMACK/AppArmor etc. when you want to use TOMOYO.
-
-We hope that LSM becomes stackable in future. Meanwhile, you can use non-LSM
-version of TOMOYO, available at http://tomoyo.sourceforge.jp/1.7/ .
-LSM version of TOMOYO is a subset of non-LSM version of TOMOYO. We are planning
-to port non-LSM version's functionalities to LSM versions.
diff -druN linux-2.6.39-libre/Documentation/trace/kprobetrace.txt linux-3.0-rc7-libre/Documentation/trace/kprobetrace.txt
--- linux-2.6.39-libre/Documentation/trace/kprobetrace.txt	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/Documentation/trace/kprobetrace.txt	2011-07-11 19:51:52.000000000 -0400
@@ -120,7 +120,6 @@
         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 __probe_ip; offset:12;      size:4; signed:0;
         field:int __probe_nargs;        offset:16;      size:4; signed:1;
diff -druN linux-2.6.39-libre/Documentation/uml/UserModeLinux-HOWTO.txt linux-3.0-rc7-libre/Documentation/uml/UserModeLinux-HOWTO.txt
--- linux-2.6.39-libre/Documentation/uml/UserModeLinux-HOWTO.txt	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/Documentation/uml/UserModeLinux-HOWTO.txt	1969-12-31 19:00:00.000000000 -0500
@@ -1,4579 +0,0 @@
-  User Mode Linux HOWTO
-  User Mode Linux Core Team
-  Mon Nov 18 14:16:16 EST 2002
-
-  This document describes the use and abuse of Jeff Dike's User Mode
-  Linux: a port of the Linux kernel as a normal Intel Linux process.
-  ______________________________________________________________________
-
-  Table of Contents
-
-  1. Introduction
-
-     1.1 How is User Mode Linux Different?
-     1.2 Why Would I Want User Mode Linux?
-
-  2. Compiling the kernel and modules
-
-     2.1 Compiling the kernel
-     2.2 Compiling and installing kernel modules
-     2.3 Compiling and installing uml_utilities
-
-  3. Running UML and logging in
-
-     3.1 Running UML
-     3.2 Logging in
-     3.3 Examples
-
-  4. UML on 2G/2G hosts
-
-     4.1 Introduction
-     4.2 The problem
-     4.3 The solution
-
-  5. Setting up serial lines and consoles
-
-     5.1 Specifying the device
-     5.2 Specifying the channel
-     5.3 Examples
-
-  6. Setting up the network
-
-     6.1 General setup
-     6.2 Userspace daemons
-     6.3 Specifying ethernet addresses
-     6.4 UML interface setup
-     6.5 Multicast
-     6.6 TUN/TAP with the uml_net helper
-     6.7 TUN/TAP with a preconfigured tap device
-     6.8 Ethertap
-     6.9 The switch daemon
-     6.10 Slip
-     6.11 Slirp
-     6.12 pcap
-     6.13 Setting up the host yourself
-
-  7. Sharing Filesystems between Virtual Machines
-
-     7.1 A warning
-     7.2 Using layered block devices
-     7.3 Note!
-     7.4 Another warning
-     7.5 uml_moo : Merging a COW file with its backing file
-
-  8. Creating filesystems
-
-     8.1 Create the filesystem file
-     8.2 Assign the file to a UML device
-     8.3 Creating and mounting the filesystem
-
-  9. Host file access
-
-     9.1 Using hostfs
-     9.2 hostfs as the root filesystem
-     9.3 Building hostfs
-
-  10. The Management Console
-     10.1 version
-     10.2 halt and reboot
-     10.3 config
-     10.4 remove
-     10.5 sysrq
-     10.6 help
-     10.7 cad
-     10.8 stop
-     10.9 go
-
-  11. Kernel debugging
-
-     11.1 Starting the kernel under gdb
-     11.2 Examining sleeping processes
-     11.3 Running ddd on UML
-     11.4 Debugging modules
-     11.5 Attaching gdb to the kernel
-     11.6 Using alternate debuggers
-
-  12. Kernel debugging examples
-
-     12.1 The case of the hung fsck
-     12.2 Episode 2: The case of the hung fsck
-
-  13. What to do when UML doesn't work
-
-     13.1 Strange compilation errors when you build from source
-     13.2 (obsolete)
-     13.3 A variety of panics and hangs with /tmp on a reiserfs  filesystem
-     13.4 The compile fails with errors about conflicting types for 'open', 'dup', and 'waitpid'
-     13.5 UML doesn't work when /tmp is an NFS filesystem
-     13.6 UML hangs on boot when compiled with gprof support
-     13.7 syslogd dies with a SIGTERM on startup
-     13.8 TUN/TAP networking doesn't work on a 2.4 host
-     13.9 You can network to the host but not to other machines on the net
-     13.10 I have no root and I want to scream
-     13.11 UML build conflict between ptrace.h and ucontext.h
-     13.12 The UML BogoMips is exactly half the host's BogoMips
-     13.13 When you run UML, it immediately segfaults
-     13.14 xterms appear, then immediately disappear
-     13.15 Any other panic, hang, or strange behavior
-
-  14. Diagnosing Problems
-
-     14.1 Case 1 : Normal kernel panics
-     14.2 Case 2 : Tracing thread panics
-     14.3 Case 3 : Tracing thread panics caused by other threads
-     14.4 Case 4 : Hangs
-
-  15. Thanks
-
-     15.1 Code and Documentation
-     15.2 Flushing out bugs
-     15.3 Buglets and clean-ups
-     15.4 Case Studies
-     15.5 Other contributions
-
-
-  ______________________________________________________________________
-
-  11..  IInnttrroodduuccttiioonn
-
-  Welcome to User Mode Linux.  It's going to be fun.
-
-
-
-  11..11..  HHooww iiss UUsseerr MMooddee LLiinnuuxx DDiiffffeerreenntt??
-
-  Normally, the Linux Kernel talks straight to your hardware (video
-  card, keyboard, hard drives, etc), and any programs which run ask the
-  kernel to operate the hardware, like so:
-
-
-
-         +-----------+-----------+----+
-         | Process 1 | Process 2 | ...|
-         +-----------+-----------+----+
-         |       Linux Kernel         |
-         +----------------------------+
-         |         Hardware           |
-         +----------------------------+
-
-
-
-
-  The User Mode Linux Kernel is different; instead of talking to the
-  hardware, it talks to a `real' Linux kernel (called the `host kernel'
-  from now on), like any other program.  Programs can then run inside
-  User-Mode Linux as if they were running under a normal kernel, like
-  so:
-
-
-
-                     +----------------+
-                     | Process 2 | ...|
-         +-----------+----------------+
-         | Process 1 | User-Mode Linux|
-         +----------------------------+
-         |       Linux Kernel         |
-         +----------------------------+
-         |         Hardware           |
-         +----------------------------+
-
-
-
-
-
-  11..22..  WWhhyy WWoouulldd II WWaanntt UUsseerr MMooddee LLiinnuuxx??
-
-
-  1. If User Mode Linux crashes, your host kernel is still fine.
-
-  2. You can run a usermode kernel as a non-root user.
-
-  3. You can debug the User Mode Linux like any normal process.
-
-  4. You can run gprof (profiling) and gcov (coverage testing).
-
-  5. You can play with your kernel without breaking things.
-
-  6. You can use it as a sandbox for testing new apps.
-
-  7. You can try new development kernels safely.
-
-  8. You can run different distributions simultaneously.
-
-  9. It's extremely fun.
-
-
-
-
-
-  22..  CCoommppiilliinngg tthhee kkeerrnneell aanndd mmoodduulleess
-
-
-
-
-  22..11..  CCoommppiilliinngg tthhee kkeerrnneell
-
-
-  Compiling the user mode kernel is just like compiling any other
-  kernel.  Let's go through the steps, using 2.4.0-prerelease (current
-  as of this writing) as an example:
-
-
-  1. Download the latest UML patch from
-
-     the download page <http://user-mode-linux.sourceforge.net/
-
-     In this example, the file is uml-patch-2.4.0-prerelease.bz2.
-
-
-  2. Download the matching kernel from your favourite kernel mirror,
-     such as:
-
-     ftp://ftp.ca.kernel.org/pub/kernel/v2.4/linux-2.4.0-prerelease.tar.bz2
-     <ftp://ftp.ca.kernel.org/pub/kernel/v2.4/linux-2.4.0-prerelease.tar.bz2>
-     .
-
-
-  3. Make a directory and unpack the kernel into it.
-
-
-
-       host%
-       mkdir ~/uml
-
-
-
-
-
-
-       host%
-       cd ~/uml
-
-
-
-
-
-
-       host%
-       tar -xzvf linux-2.4.0-prerelease.tar.bz2
-
-
-
-
-
-
-  4. Apply the patch using
-
-
-
-       host%
-       cd ~/uml/linux
-
-
-
-       host%
-       bzcat uml-patch-2.4.0-prerelease.bz2 | patch -p1
-
-
-
-
-
-
-  5. Run your favorite config; `make xconfig ARCH=um' is the most
-     convenient.  `make config ARCH=um' and 'make menuconfig ARCH=um'
-     will work as well.  The defaults will give you a useful kernel.  If
-     you want to change something, go ahead, it probably won't hurt
-     anything.
-
-
-     Note:  If the host is configured with a 2G/2G address space split
-     rather than the usual 3G/1G split, then the packaged UML binaries
-     will not run.  They will immediately segfault.  See ``UML on 2G/2G
-     hosts''  for the scoop on running UML on your system.
-
-
-
-  6. Finish with `make linux ARCH=um': the result is a file called
-     `linux' in the top directory of your source tree.
-
-  Make sure that you don't build this kernel in /usr/src/linux.  On some
-  distributions, /usr/include/asm is a link into this pool.  The user-
-  mode build changes the other end of that link, and things that include
-  <asm/anything.h> stop compiling.
-
-  The sources are also available from cvs at the project's cvs page,
-  which has directions on getting the sources. You can also browse the
-  CVS pool from there.
-
-  If you get the CVS sources, you will have to check them out into an
-  empty directory. You will then have to copy each file into the
-  corresponding directory in the appropriate kernel pool.
-
-  If you don't have the latest kernel pool, you can get the
-  corresponding user-mode sources with
-
-
-       host% cvs co -r v_2_3_x linux
-
-
-
-
-  where 'x' is the version in your pool. Note that you will not get the
-  bug fixes and enhancements that have gone into subsequent releases.
-
-
-  22..22..  CCoommppiilliinngg aanndd iinnssttaalllliinngg kkeerrnneell mmoodduulleess
-
-  UML modules are built in the same way as the native kernel (with the
-  exception of the 'ARCH=um' that you always need for UML):
-
-
-       host% make modules ARCH=um
-
-
-
-
-  Any modules that you want to load into this kernel need to be built in
-  the user-mode pool.  Modules from the native kernel won't work.
-
-  You can install them by using ftp or something to copy them into the
-  virtual machine and dropping them into /lib/modules/`uname -r`.
-
-  You can also get the kernel build process to install them as follows:
-
-  1. with the kernel not booted, mount the root filesystem in the top
-     level of the kernel pool:
-
-
-       host% mount root_fs mnt -o loop
-
-
-
-
-
-
-  2. run
-
-
-       host%
-       make modules_install INSTALL_MOD_PATH=`pwd`/mnt ARCH=um
-
-
-
-
-
-
-  3. unmount the filesystem
-
-
-       host% umount mnt
-
-
-
-
-
-
-  4. boot the kernel on it
-
-
-  When the system is booted, you can use insmod as usual to get the
-  modules into the kernel.  A number of things have been loaded into UML
-  as modules, especially filesystems and network protocols and filters,
-  so most symbols which need to be exported probably already are.
-  However, if you do find symbols that need exporting, let  us
-  <http://user-mode-linux.sourceforge.net/>  know, and
-  they'll be "taken care of".
-
-
-
-  22..33..  CCoommppiilliinngg aanndd iinnssttaalllliinngg uummll__uuttiilliittiieess
-
-  Many features of the UML kernel require a user-space helper program,
-  so a uml_utilities package is distributed separately from the kernel
-  patch which provides these helpers. Included within this is:
-
-  +o  port-helper - Used by consoles which connect to xterms or ports
-
-  +o  tunctl - Configuration tool to create and delete tap devices
-
-  +o  uml_net - Setuid binary for automatic tap device configuration
-
-  +o  uml_switch - User-space virtual switch required for daemon
-     transport
-
-     The uml_utilities tree is compiled with:
-
-
-       host#
-       make && make install
-
-
-
-
-  Note that UML kernel patches may require a specific version of the
-  uml_utilities distribution. If you don't keep up with the mailing
-  lists, ensure that you have the latest release of uml_utilities if you
-  are experiencing problems with your UML kernel, particularly when
-  dealing with consoles or command-line switches to the helper programs
-
-
-
-
-
-
-
-
-  33..  RRuunnnniinngg UUMMLL aanndd llooggggiinngg iinn
-
-
-
-  33..11..  RRuunnnniinngg UUMMLL
-
-  It runs on 2.2.15 or later, and all 2.4 kernels.
-
-
-  Booting UML is straightforward.  Simply run 'linux': it will try to
-  mount the file `root_fs' in the current directory.  You do not need to
-  run it as root.  If your root filesystem is not named `root_fs', then
-  you need to put a `ubd0=root_fs_whatever' switch on the linux command
-  line.
-
-
-  You will need a filesystem to boot UML from.  There are a number
-  available for download from  here  <http://user-mode-
-  linux.sourceforge.net/> .  There are also  several tools
-  <http://user-mode-linux.sourceforge.net/>  which can be
-  used to generate UML-compatible filesystem images from media.
-  The kernel will boot up and present you with a login prompt.
-
-
-  Note:  If the host is configured with a 2G/2G address space split
-  rather than the usual 3G/1G split, then the packaged UML binaries will
-  not run.  They will immediately segfault.  See ``UML on 2G/2G hosts''
-  for the scoop on running UML on your system.
-
-
-
-  33..22..  LLooggggiinngg iinn
-
-
-
-  The prepackaged filesystems have a root account with password 'root'
-  and a user account with password 'user'.  The login banner will
-  generally tell you how to log in.  So, you log in and you will find
-  yourself inside a little virtual machine. Our filesystems have a
-  variety of commands and utilities installed (and it is fairly easy to
-  add more), so you will have a lot of tools with which to poke around
-  the system.
-
-  There are a couple of other ways to log in:
-
-  +o  On a virtual console
-
-
-
-     Each virtual console that is configured (i.e. the device exists in
-     /dev and /etc/inittab runs a getty on it) will come up in its own
-     xterm.  If you get tired of the xterms, read ``Setting up serial
-     lines and consoles''  to see how to attach the consoles to
-     something else, like host ptys.
-
-
-
-  +o  Over the serial line
-
-
-     In the boot output, find a line that looks like:
-
-
-
-       serial line 0 assigned pty /dev/ptyp1
-
-
-
-
-  Attach your favorite terminal program to the corresponding tty.  I.e.
-  for minicom, the command would be
-
-
-       host% minicom -o -p /dev/ttyp1
-
-
-
-
-
-
-  +o  Over the net
-
-
-     If the network is running, then you can telnet to the virtual
-     machine and log in to it.  See ``Setting up the network''  to learn
-     about setting up a virtual network.
-
-  When you're done using it, run halt, and the kernel will bring itself
-  down and the process will exit.
-
-
-  33..33..  EExxaammpplleess
-
-  Here are some examples of UML in action:
-
-  +o  A login session <http://user-mode-linux.sourceforge.net/login.html>
-
-  +o  A virtual network <http://user-mode-linux.sourceforge.net/net.html>
-
-
-
-
-
-
-
-  44..  UUMMLL oonn 22GG//22GG hhoossttss
-
-
-
-
-  44..11..  IInnttrroodduuccttiioonn
-
-
-  Most Linux machines are configured so that the kernel occupies the
-  upper 1G (0xc0000000 - 0xffffffff) of the 4G address space and
-  processes use the lower 3G (0x00000000 - 0xbfffffff).  However, some
-  machine are configured with a 2G/2G split, with the kernel occupying
-  the upper 2G (0x80000000 - 0xffffffff) and processes using the lower
-  2G (0x00000000 - 0x7fffffff).
-
-
-
-
-  44..22..  TThhee pprroobblleemm
-
-
-  The prebuilt UML binaries on this site will not run on 2G/2G hosts
-  because UML occupies the upper .5G of the 3G process address space
-  (0xa0000000 - 0xbfffffff).  Obviously, on 2G/2G hosts, this is right
-  in the middle of the kernel address space, so UML won't even load - it
-  will immediately segfault.
-
-
-
-
-  44..33..  TThhee ssoolluuttiioonn
-
-
-  The fix for this is to rebuild UML from source after enabling
-  CONFIG_HOST_2G_2G (under 'General Setup').  This will cause UML to
-  load itself in the top .5G of that smaller process address space,
-  where it will run fine.  See ``Compiling the kernel and modules''  if
-  you need help building UML from source.
-
-
-
-
-
-
-
-
-
-
-  55..  SSeettttiinngg uupp sseerriiaall lliinneess aanndd ccoonnssoolleess
-
-
-  It is possible to attach UML serial lines and consoles to many types
-  of host I/O channels by specifying them on the command line.
-
-
-  You can attach them to host ptys, ttys, file descriptors, and ports.
-  This allows you to do things like
-
-  +o  have a UML console appear on an unused host console,
-
-  +o  hook two virtual machines together by having one attach to a pty
-     and having the other attach to the corresponding tty
-
-  +o  make a virtual machine accessible from the net by attaching a
-     console to a port on the host.
-
-
-  The general format of the command line option is device=channel.
-
-
-
-  55..11..  SSppeecciiffyyiinngg tthhee ddeevviiccee
-
-  Devices are specified with "con" or "ssl" (console or serial line,
-  respectively), optionally with a device number if you are talking
-  about a specific device.
-
-
-  Using just "con" or "ssl" describes all of the consoles or serial
-  lines.  If you want to talk about console #3 or serial line #10, they
-  would be "con3" and "ssl10", respectively.
-
-
-  A specific device name will override a less general "con=" or "ssl=".
-  So, for example, you can assign a pty to each of the serial lines
-  except for the first two like this:
-
-
-        ssl=pty ssl0=tty:/dev/tty0 ssl1=tty:/dev/tty1
-
-
-
-
-  The specificity of the device name is all that matters; order on the
-  command line is irrelevant.
-
-
-
-  55..22..  SSppeecciiffyyiinngg tthhee cchhaannnneell
-
-  There are a number of different types of channels to attach a UML
-  device to, each with a different way of specifying exactly what to
-  attach to.
-
-  +o  pseudo-terminals - device=pty pts terminals - device=pts
-
-
-     This will cause UML to allocate a free host pseudo-terminal for the
-     device.  The terminal that it got will be announced in the boot
-     log.  You access it by attaching a terminal program to the
-     corresponding tty:
-
-  +o  screen /dev/pts/n
-
-  +o  screen /dev/ttyxx
-
-  +o  minicom -o -p /dev/ttyxx - minicom seems not able to handle pts
-     devices
-
-  +o  kermit - start it up, 'open' the device, then 'connect'
-
-
-
-
-
-  +o  terminals - device=tty:tty device file
-
-
-     This will make UML attach the device to the specified tty (i.e
-
-
-        con1=tty:/dev/tty3
-
-
-
-
-  will attach UML's console 1 to the host's /dev/tty3).  If the tty that
-  you specify is the slave end of a tty/pty pair, something else must
-  have already opened the corresponding pty in order for this to work.
-
-
-
-
-
-  +o  xterms - device=xterm
-
-
-     UML will run an xterm and the device will be attached to it.
-
-
-
-
-
-  +o  Port - device=port:port number
-
-
-     This will attach the UML devices to the specified host port.
-     Attaching console 1 to the host's port 9000 would be done like
-     this:
-
-
-        con1=port:9000
-
-
-
-
-  Attaching all the serial lines to that port would be done similarly:
-
-
-        ssl=port:9000
-
-
-
-
-  You access these devices by telnetting to that port.  Each active tel-
-  net session gets a different device.  If there are more telnets to a
-  port than UML devices attached to it, then the extra telnet sessions
-  will block until an existing telnet detaches, or until another device
-  becomes active (i.e. by being activated in /etc/inittab).
-
-  This channel has the advantage that you can both attach multiple UML
-  devices to it and know how to access them without reading the UML boot
-  log.  It is also unique in allowing access to a UML from remote
-  machines without requiring that the UML be networked.  This could be
-  useful in allowing public access to UMLs because they would be
-  accessible from the net, but wouldn't need any kind of network
-  filtering or access control because they would have no network access.
-
-
-  If you attach the main console to a portal, then the UML boot will
-  appear to hang.  In reality, it's waiting for a telnet to connect, at
-  which point the boot will proceed.
-
-
-
-
-
-  +o  already-existing file descriptors - device=file descriptor
-
-
-     If you set up a file descriptor on the UML command line, you can
-     attach a UML device to it.  This is most commonly used to put the
-     main console back on stdin and stdout after assigning all the other
-     consoles to something else:
-
-
-        con0=fd:0,fd:1 con=pts
-
-
-
-
-
-
-
-
-  +o  Nothing - device=null
-
-
-     This allows the device to be opened, in contrast to 'none', but
-     reads will block, and writes will succeed and the data will be
-     thrown out.
-
-
-
-
-
-  +o  None - device=none
-
-
-     This causes the device to disappear.
-
-
-
-  You can also specify different input and output channels for a device
-  by putting a comma between them:
-
-
-        ssl3=tty:/dev/tty2,xterm
-
-
-
-
-  will cause serial line 3 to accept input on the host's /dev/tty3 and
-  display output on an xterm.  That's a silly example - the most common
-  use of this syntax is to reattach the main console to stdin and stdout
-  as shown above.
-
-
-  If you decide to move the main console away from stdin/stdout, the
-  initial boot output will appear in the terminal that you're running
-  UML in.  However, once the console driver has been officially
-  initialized, then the boot output will start appearing wherever you
-  specified that console 0 should be.  That device will receive all
-  subsequent output.
-
-
-
-  55..33..  EExxaammpplleess
-
-  There are a number of interesting things you can do with this
-  capability.
-
-
-  First, this is how you get rid of those bleeding console xterms by
-  attaching them to host ptys:
-
-
-        con=pty con0=fd:0,fd:1
-
-
-
-
-  This will make a UML console take over an unused host virtual console,
-  so that when you switch to it, you will see the UML login prompt
-  rather than the host login prompt:
-
-
-        con1=tty:/dev/tty6
-
-
-
-
-  You can attach two virtual machines together with what amounts to a
-  serial line as follows:
-
-  Run one UML with a serial line attached to a pty -
-
-
-        ssl1=pty
-
-
-
-
-  Look at the boot log to see what pty it got (this example will assume
-  that it got /dev/ptyp1).
-
-  Boot the other UML with a serial line attached to the corresponding
-  tty -
-
-
-        ssl1=tty:/dev/ttyp1
-
-
-
-
-  Log in, make sure that it has no getty on that serial line, attach a
-  terminal program like minicom to it, and you should see the login
-  prompt of the other virtual machine.
-
-
-  66..  SSeettttiinngg uupp tthhee nneettwwoorrkk
-
-
-
-  This page describes how to set up the various transports and to
-  provide a UML instance with network access to the host, other machines
-  on the local net, and the rest of the net.
-
-
-  As of 2.4.5, UML networking has been completely redone to make it much
-  easier to set up, fix bugs, and add new features.
-
-
-  There is a new helper, uml_net, which does the host setup that
-  requires root privileges.
-
-
-  There are currently five transport types available for a UML virtual
-  machine to exchange packets with other hosts:
-
-  +o  ethertap
-
-  +o  TUN/TAP
-
-  +o  Multicast
-
-  +o  a switch daemon
-
-  +o  slip
-
-  +o  slirp
-
-  +o  pcap
-
-     The TUN/TAP, ethertap, slip, and slirp transports allow a UML
-     instance to exchange packets with the host.  They may be directed
-     to the host or the host may just act as a router to provide access
-     to other physical or virtual machines.
-
-
-  The pcap transport is a synthetic read-only interface, using the
-  libpcap binary to collect packets from interfaces on the host and
-  filter them.  This is useful for building preconfigured traffic
-  monitors or sniffers.
-
-
-  The daemon and multicast transports provide a completely virtual
-  network to other virtual machines.  This network is completely
-  disconnected from the physical network unless one of the virtual
-  machines on it is acting as a gateway.
-
-
-  With so many host transports, which one should you use?  Here's when
-  you should use each one:
-
-  +o  ethertap - if you want access to the host networking and it is
-     running 2.2
-
-  +o  TUN/TAP - if you want access to the host networking and it is
-     running 2.4.  Also, the TUN/TAP transport is able to use a
-     preconfigured device, allowing it to avoid using the setuid uml_net
-     helper, which is a security advantage.
-
-  +o  Multicast - if you want a purely virtual network and you don't want
-     to set up anything but the UML
-
-  +o  a switch daemon - if you want a purely virtual network and you
-     don't mind running the daemon in order to get somewhat better
-     performance
-
-  +o  slip - there is no particular reason to run the slip backend unless
-     ethertap and TUN/TAP are just not available for some reason
-
-  +o  slirp - if you don't have root access on the host to setup
-     networking, or if you don't want to allocate an IP to your UML
-
-  +o  pcap - not much use for actual network connectivity, but great for
-     monitoring traffic on the host
-
-     Ethertap is available on 2.4 and works fine.  TUN/TAP is preferred
-     to it because it has better performance and ethertap is officially
-     considered obsolete in 2.4.  Also, the root helper only needs to
-     run occasionally for TUN/TAP, rather than handling every packet, as
-     it does with ethertap.  This is a slight security advantage since
-     it provides fewer opportunities for a nasty UML user to somehow
-     exploit the helper's root privileges.
-
-
-  66..11..  GGeenneerraall sseettuupp
-
-  First, you must have the virtual network enabled in your UML.  If are
-  running a prebuilt kernel from this site, everything is already
-  enabled.  If you build the kernel yourself, under the "Network device
-  support" menu, enable "Network device support", and then the three
-  transports.
-
-
-  The next step is to provide a network device to the virtual machine.
-  This is done by describing it on the kernel command line.
-
-  The general format is
-
-
-       eth <n> = <transport> , <transport args>
-
-
-
-
-  For example, a virtual ethernet device may be attached to a host
-  ethertap device as follows:
-
-
-       eth0=ethertap,tap0,fe:fd:0:0:0:1,192.168.0.254
-
-
-
-
-  This sets up eth0 inside the virtual machine to attach itself to the
-  host /dev/tap0, assigns it an ethernet address, and assigns the host
-  tap0 interface an IP address.
-
-
-
-  Note that the IP address you assign to the host end of the tap device
-  must be different than the IP you assign to the eth device inside UML.
-  If you are short on IPs and don't want to consume two per UML, then
-  you can reuse the host's eth IP address for the host ends of the tap
-  devices.  Internally, the UMLs must still get unique IPs for their eth
-  devices.  You can also give the UMLs non-routable IPs (192.168.x.x or
-  10.x.x.x) and have the host masquerade them.  This will let outgoing
-  connections work, but incoming connections won't without more work,
-  such as port forwarding from the host.
-  Also note that when you configure the host side of an interface, it is
-  only acting as a gateway.  It will respond to pings sent to it
-  locally, but is not useful to do that since it's a host interface.
-  You are not talking to the UML when you ping that interface and get a
-  response.
-
-
-  You can also add devices to a UML and remove them at runtime.  See the
-  ``The Management Console''  page for details.
-
-
-  The sections below describe this in more detail.
-
-
-  Once you've decided how you're going to set up the devices, you boot
-  UML, log in, configure the UML side of the devices, and set up routes
-  to the outside world.  At that point, you will be able to talk to any
-  other machines, physical or virtual, on the net.
-
-
-  If ifconfig inside UML fails and the network refuses to come up, run
-  tell you what went wrong.
-
-
-
-  66..22..  UUsseerrssppaaccee ddaaeemmoonnss
-
-  You will likely need the setuid helper, or the switch daemon, or both.
-  They are both installed with the RPM and deb, so if you've installed
-  either, you can skip the rest of this section.
-
-
-  If not, then you need to check them out of CVS, build them, and
-  install them.  The helper is uml_net, in CVS /tools/uml_net, and the
-  daemon is uml_switch, in CVS /tools/uml_router.  They are both built
-  with a plain 'make'.  Both need to be installed in a directory that's
-  in your path - /usr/bin is recommend.  On top of that, uml_net needs
-  to be setuid root.
-
-
-
-  66..33..  SSppeecciiffyyiinngg eetthheerrnneett aaddddrreesssseess
-
-  Below, you will see that the TUN/TAP, ethertap, and daemon interfaces
-  allow you to specify hardware addresses for the virtual ethernet
-  devices.  This is generally not necessary.  If you don't have a
-  specific reason to do it, you probably shouldn't.  If one is not
-  specified on the command line, the driver will assign one based on the
-  device IP address.  It will provide the address fe:fd:nn:nn:nn:nn
-  where nn.nn.nn.nn is the device IP address.  This is nearly always
-  sufficient to guarantee a unique hardware address for the device.  A
-  couple of exceptions are:
-
-  +o  Another set of virtual ethernet devices are on the same network and
-     they are assigned hardware addresses using a different scheme which
-     may conflict with the UML IP address-based scheme
-
-  +o  You aren't going to use the device for IP networking, so you don't
-     assign the device an IP address
-
-     If you let the driver provide the hardware address, you should make
-     sure that the device IP address is known before the interface is
-     brought up.  So, inside UML, this will guarantee that:
-
-
-
-  UML#
-  ifconfig eth0 192.168.0.250 up
-
-
-
-
-  If you decide to assign the hardware address yourself, make sure that
-  the first byte of the address is even.  Addresses with an odd first
-  byte are broadcast addresses, which you don't want assigned to a
-  device.
-
-
-
-  66..44..  UUMMLL iinntteerrffaaccee sseettuupp
-
-  Once the network devices have been described on the command line, you
-  should boot UML and log in.
-
-
-  The first thing to do is bring the interface up:
-
-
-       UML# ifconfig ethn ip-address up
-
-
-
-
-  You should be able to ping the host at this point.
-
-
-  To reach the rest of the world, you should set a default route to the
-  host:
-
-
-       UML# route add default gw host ip
-
-
-
-
-  Again, with host ip of 192.168.0.4:
-
-
-       UML# route add default gw 192.168.0.4
-
-
-
-
-  This page used to recommend setting a network route to your local net.
-  This is wrong, because it will cause UML to try to figure out hardware
-  addresses of the local machines by arping on the interface to the
-  host.  Since that interface is basically a single strand of ethernet
-  with two nodes on it (UML and the host) and arp requests don't cross
-  networks, they will fail to elicit any responses.  So, what you want
-  is for UML to just blindly throw all packets at the host and let it
-  figure out what to do with them, which is what leaving out the network
-  route and adding the default route does.
-
-
-  Note: If you can't communicate with other hosts on your physical
-  ethernet, it's probably because of a network route that's
-  automatically set up.  If you run 'route -n' and see a route that
-  looks like this:
-
-
-
-
-  Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
-  192.168.0.0     0.0.0.0         255.255.255.0   U     0      0      0   eth0
-
-
-
-
-  with a mask that's not 255.255.255.255, then replace it with a route
-  to your host:
-
-
-       UML#
-       route del -net 192.168.0.0 dev eth0 netmask 255.255.255.0
-
-
-
-
-
-
-       UML#
-       route add -host 192.168.0.4 dev eth0
-
-
-
-
-  This, plus the default route to the host, will allow UML to exchange
-  packets with any machine on your ethernet.
-
-
-
-  66..55..  MMuullttiiccaasstt
-
-  The simplest way to set up a virtual network between multiple UMLs is
-  to use the mcast transport.  This was written by Harald Welte and is
-  present in UML version 2.4.5-5um and later.  Your system must have
-  multicast enabled in the kernel and there must be a multicast-capable
-  network device on the host.  Normally, this is eth0, but if there is
-  no ethernet card on the host, then you will likely get strange error
-  messages when you bring the device up inside UML.
-
-
-  To use it, run two UMLs with
-
-
-        eth0=mcast
-
-
-
-
-  on their command lines.  Log in, configure the ethernet device in each
-  machine with different IP addresses:
-
-
-       UML1# ifconfig eth0 192.168.0.254
-
-
-
-
-
-
-       UML2# ifconfig eth0 192.168.0.253
-
-
-
-
-  and they should be able to talk to each other.
-
-  The full set of command line options for this transport are
-
-
-
-       ethn=mcast,ethernet address,multicast
-       address,multicast port,ttl
-
-
-
-
-  Harald's original README is here <http://user-mode-linux.source-
-  forge.net/>  and explains these in detail, as well as
-  some other issues.
-
-
-
-  66..66..  TTUUNN//TTAAPP wwiitthh tthhee uummll__nneett hheellppeerr
-
-  TUN/TAP is the preferred mechanism on 2.4 to exchange packets with the
-  host.  The TUN/TAP backend has been in UML since 2.4.9-3um.
-
-
-  The easiest way to get up and running is to let the setuid uml_net
-  helper do the host setup for you.  This involves insmod-ing the tun.o
-  module if necessary, configuring the device, and setting up IP
-  forwarding, routing, and proxy arp.  If you are new to UML networking,
-  do this first.  If you're concerned about the security implications of
-  the setuid helper, use it to get up and running, then read the next
-  section to see how to have UML use a preconfigured tap device, which
-  avoids the use of uml_net.
-
-
-  If you specify an IP address for the host side of the device, the
-  uml_net helper will do all necessary setup on the host - the only
-  requirement is that TUN/TAP be available, either built in to the host
-  kernel or as the tun.o module.
-
-  The format of the command line switch to attach a device to a TUN/TAP
-  device is
-
-
-       eth <n> =tuntap,,, <IP address>
-
-
-
-
-  For example, this argument will attach the UML's eth0 to the next
-  available tap device and assign an ethernet address to it based on its
-  IP address
-
-
-       eth0=tuntap,,,192.168.0.254
-
-
-
-
-
-
-  Note that the IP address that must be used for the eth device inside
-  UML is fixed by the routing and proxy arp that is set up on the
-  TUN/TAP device on the host.  You can use a different one, but it won't
-  work because reply packets won't reach the UML.  This is a feature.
-  It prevents a nasty UML user from doing things like setting the UML IP
-  to the same as the network's nameserver or mail server.
-
-
-  There are a couple potential problems with running the TUN/TAP
-  transport on a 2.4 host kernel
-
-  +o  TUN/TAP seems not to work on 2.4.3 and earlier.  Upgrade the host
-     kernel or use the ethertap transport.
-
-  +o  With an upgraded kernel, TUN/TAP may fail with
-
-
-       File descriptor in bad state
-
-
-
-
-  This is due to a header mismatch between the upgraded kernel and the
-  kernel that was originally installed on the machine.  The fix is to
-  make sure that /usr/src/linux points to the headers for the running
-  kernel.
-
-  These were pointed out by Tim Robinson <timro at trkr dot net> in
-  <http://www.geocrawler.com/> name="this uml-
-  user post"> .
-
-
-
-  66..77..  TTUUNN//TTAAPP wwiitthh aa pprreeccoonnffiigguurreedd ttaapp ddeevviiccee
-
-  If you prefer not to have UML use uml_net (which is somewhat
-  insecure), with UML 2.4.17-11, you can set up a TUN/TAP device
-  beforehand.  The setup needs to be done as root, but once that's done,
-  there is no need for root assistance.  Setting up the device is done
-  as follows:
-
-  +o  Create the device with tunctl (available from the UML utilities
-     tarball)
-
-
-
-
-       host#  tunctl -u uid
-
-
-
-
-  where uid is the user id or username that UML will be run as.  This
-  will tell you what device was created.
-
-  +o  Configure the device IP (change IP addresses and device name to
-     suit)
-
-
-
-
-       host#  ifconfig tap0 192.168.0.254 up
-
-
-
-
-
-  +o  Set up routing and arping if desired - this is my recipe, there are
-     other ways of doing the same thing
-
-
-       host#
-       bash -c 'echo 1 > /proc/sys/net/ipv4/ip_forward'
-
-       host#
-       route add -host 192.168.0.253 dev tap0
-
-
-
-
-
-
-       host#
-       bash -c 'echo 1 > /proc/sys/net/ipv4/conf/tap0/proxy_arp'
-
-
-
-
-
-
-       host#
-       arp -Ds 192.168.0.253 eth0 pub
-
-
-
-
-  Note that this must be done every time the host boots - this configu-
-  ration is not stored across host reboots.  So, it's probably a good
-  idea to stick it in an rc file.  An even better idea would be a little
-  utility which reads the information from a config file and sets up
-  devices at boot time.
-
-  +o  Rather than using up two IPs and ARPing for one of them, you can
-     also provide direct access to your LAN by the UML by using a
-     bridge.
-
-
-       host#
-       brctl addbr br0
-
-
-
-
-
-
-       host#
-       ifconfig eth0 0.0.0.0 promisc up
-
-
-
-
-
-
-       host#
-       ifconfig tap0 0.0.0.0 promisc up
-
-
-
-
-
-
-       host#
-       ifconfig br0 192.168.0.1 netmask 255.255.255.0 up
-
-
-
-
-
-
-
-  host#
-  brctl stp br0 off
-
-
-
-
-
-
-       host#
-       brctl setfd br0 1
-
-
-
-
-
-
-       host#
-       brctl sethello br0 1
-
-
-
-
-
-
-       host#
-       brctl addif br0 eth0
-
-
-
-
-
-
-       host#
-       brctl addif br0 tap0
-
-
-
-
-  Note that 'br0' should be setup using ifconfig with the existing IP
-  address of eth0, as eth0 no longer has its own IP.
-
-  +o
-
-
-     Also, the /dev/net/tun device must be writable by the user running
-     UML in order for the UML to use the device that's been configured
-     for it.  The simplest thing to do is
-
-
-       host#  chmod 666 /dev/net/tun
-
-
-
-
-  Making it world-writable looks bad, but it seems not to be
-  exploitable as a security hole.  However, it does allow anyone to cre-
-  ate useless tap devices (useless because they can't configure them),
-  which is a DOS attack.  A somewhat more secure alternative would to be
-  to create a group containing all the users who have preconfigured tap
-  devices and chgrp /dev/net/tun to that group with mode 664 or 660.
-
-
-  +o  Once the device is set up, run UML with 'eth0=tuntap,device name'
-     (i.e. 'eth0=tuntap,tap0') on the command line (or do it with the
-     mconsole config command).
-
-  +o  Bring the eth device up in UML and you're in business.
-
-     If you don't want that tap device any more, you can make it non-
-     persistent with
-
-
-       host#  tunctl -d tap device
-
-
-
-
-  Finally, tunctl has a -b (for brief mode) switch which causes it to
-  output only the name of the tap device it created.  This makes it
-  suitable for capture by a script:
-
-
-       host#  TAP=`tunctl -u 1000 -b`
-
-
-
-
-
-
-  66..88..  EEtthheerrttaapp
-
-  Ethertap is the general mechanism on 2.2 for userspace processes to
-  exchange packets with the kernel.
-
-
-
-  To use this transport, you need to describe the virtual network device
-  on the UML command line.  The general format for this is
-
-
-       eth <n> =ethertap, <device> , <ethernet address> , <tap IP address>
-
-
-
-
-  So, the previous example
-
-
-       eth0=ethertap,tap0,fe:fd:0:0:0:1,192.168.0.254
-
-
-
-
-  attaches the UML eth0 device to the host /dev/tap0, assigns it the
-  ethernet address fe:fd:0:0:0:1, and assigns the IP address
-  192.168.0.254 to the tap device.
-
-
-
-  The tap device is mandatory, but the others are optional.  If the
-  ethernet address is omitted, one will be assigned to it.
-
-
-  The presence of the tap IP address will cause the helper to run and do
-  whatever host setup is needed to allow the virtual machine to
-  communicate with the outside world.  If you're not sure you know what
-  you're doing, this is the way to go.
-
-
-  If it is absent, then you must configure the tap device and whatever
-  arping and routing you will need on the host.  However, even in this
-  case, the uml_net helper still needs to be in your path and it must be
-  setuid root if you're not running UML as root.  This is because the
-  tap device doesn't support SIGIO, which UML needs in order to use
-  something as a source of input.  So, the helper is used as a
-  convenient asynchronous IO thread.
-
-  If you're using the uml_net helper, you can ignore the following host
-  setup - uml_net will do it for you.  You just need to make sure you
-  have ethertap available, either built in to the host kernel or
-  available as a module.
-
-
-  If you want to set things up yourself, you need to make sure that the
-  appropriate /dev entry exists.  If it doesn't, become root and create
-  it as follows:
-
-
-       mknod /dev/tap <minor>  c 36  <minor>  + 16
-
-
-
-
-  For example, this is how to create /dev/tap0:
-
-
-       mknod /dev/tap0 c 36 0 + 16
-
-
-
-
-  You also need to make sure that the host kernel has ethertap support.
-  If ethertap is enabled as a module, you apparently need to insmod
-  ethertap once for each ethertap device you want to enable.  So,
-
-
-       host#
-       insmod ethertap
-
-
-
-
-  will give you the tap0 interface.  To get the tap1 interface, you need
-  to run
-
-
-       host#
-       insmod ethertap unit=1 -o ethertap1
-
-
-
-
-
-
-
-  66..99..  TThhee sswwiittcchh ddaaeemmoonn
-
-  NNoottee: This is the daemon formerly known as uml_router, but which was
-  renamed so the network weenies of the world would stop growling at me.
-
-
-  The switch daemon, uml_switch, provides a mechanism for creating a
-  totally virtual network.  By default, it provides no connection to the
-  host network (but see -tap, below).
-
-
-  The first thing you need to do is run the daemon.  Running it with no
-  arguments will make it listen on a default pair of unix domain
-  sockets.
-
-
-  If you want it to listen on a different pair of sockets, use
-
-
-        -unix control socket data socket
-
-
-
-
-
-  If you want it to act as a hub rather than a switch, use
-
-
-        -hub
-
-
-
-
-
-  If you want the switch to be connected to host networking (allowing
-  the umls to get access to the outside world through the host), use
-
-
-        -tap tap0
-
-
-
-
-
-  Note that the tap device must be preconfigured (see "TUN/TAP with a
-  preconfigured tap device", above).  If you're using a different tap
-  device than tap0, specify that instead of tap0.
-
-
-  uml_switch can be backgrounded as follows
-
-
-       host%
-       uml_switch [ options ] < /dev/null > /dev/null
-
-
-
-
-  The reason it doesn't background by default is that it listens to
-  stdin for EOF.  When it sees that, it exits.
-
-
-  The general format of the kernel command line switch is
-
-
-
-       ethn=daemon,ethernet address,socket
-       type,control socket,data socket
-
-
-
-
-  You can leave off everything except the 'daemon'.  You only need to
-  specify the ethernet address if the one that will be assigned to it
-  isn't acceptable for some reason.  The rest of the arguments describe
-  how to communicate with the daemon.  You should only specify them if
-  you told the daemon to use different sockets than the default.  So, if
-  you ran the daemon with no arguments, running the UML on the same
-  machine with
-       eth0=daemon
-
-
-
-
-  will cause the eth0 driver to attach itself to the daemon correctly.
-
-
-
-  66..1100..  SSlliipp
-
-  Slip is another, less general, mechanism for a process to communicate
-  with the host networking.  In contrast to the ethertap interface,
-  which exchanges ethernet frames with the host and can be used to
-  transport any higher-level protocol, it can only be used to transport
-  IP.
-
-
-  The general format of the command line switch is
-
-
-
-       ethn=slip,slip IP
-
-
-
-
-  The slip IP argument is the IP address that will be assigned to the
-  host end of the slip device.  If it is specified, the helper will run
-  and will set up the host so that the virtual machine can reach it and
-  the rest of the network.
-
-
-  There are some oddities with this interface that you should be aware
-  of.  You should only specify one slip device on a given virtual
-  machine, and its name inside UML will be 'umn', not 'eth0' or whatever
-  you specified on the command line.  These problems will be fixed at
-  some point.
-
-
-
-  66..1111..  SSlliirrpp
-
-  slirp uses an external program, usually /usr/bin/slirp, to provide IP
-  only networking connectivity through the host. This is similar to IP
-  masquerading with a firewall, although the translation is performed in
-  user-space, rather than by the kernel.  As slirp does not set up any
-  interfaces on the host, or changes routing, slirp does not require
-  root access or setuid binaries on the host.
-
-
-  The general format of the command line switch for slirp is:
-
-
-
-       ethn=slirp,ethernet address,slirp path
-
-
-
-
-  The ethernet address is optional, as UML will set up the interface
-  with an ethernet address based upon the initial IP address of the
-  interface.  The slirp path is generally /usr/bin/slirp, although it
-  will depend on distribution.
-
-
-  The slirp program can have a number of options passed to the command
-  line and we can't add them to the UML command line, as they will be
-  parsed incorrectly.  Instead, a wrapper shell script can be written or
-  the options inserted into the  /.slirprc file.  More information on
-  all of the slirp options can be found in its man pages.
-
-
-  The eth0 interface on UML should be set up with the IP 10.2.0.15,
-  although you can use anything as long as it is not used by a network
-  you will be connecting to. The default route on UML should be set to
-  use
-
-
-       UML#
-       route add default dev eth0
-
-
-
-
-  slirp provides a number of useful IP addresses which can be used by
-  UML, such as 10.0.2.3 which is an alias for the DNS server specified
-  in /etc/resolv.conf on the host or the IP given in the 'dns' option
-  for slirp.
-
-
-  Even with a baudrate setting higher than 115200, the slirp connection
-  is limited to 115200. If you need it to go faster, the slirp binary
-  needs to be compiled with FULL_BOLT defined in config.h.
-
-
-
-  66..1122..  ppccaapp
-
-  The pcap transport is attached to a UML ethernet device on the command
-  line or with uml_mconsole with the following syntax:
-
-
-
-       ethn=pcap,host interface,filter
-       expression,option1,option2
-
-
-
-
-  The expression and options are optional.
-
-
-  The interface is whatever network device on the host you want to
-  sniff.  The expression is a pcap filter expression, which is also what
-  tcpdump uses, so if you know how to specify tcpdump filters, you will
-  use the same expressions here.  The options are up to two of
-  'promisc', control whether pcap puts the host interface into
-  promiscuous mode. 'optimize' and 'nooptimize' control whether the pcap
-  expression optimizer is used.
-
-
-  Example:
-
-
-
-       eth0=pcap,eth0,tcp
-
-       eth1=pcap,eth0,!tcp
-
-
-
-  will cause the UML eth0 to emit all tcp packets on the host eth0 and
-  the UML eth1 to emit all non-tcp packets on the host eth0.
-
-
-
-  66..1133..  SSeettttiinngg uupp tthhee hhoosstt yyoouurrsseellff
-
-  If you don't specify an address for the host side of the ethertap or
-  slip device, UML won't do any setup on the host.  So this is what is
-  needed to get things working (the examples use a host-side IP of
-  192.168.0.251 and a UML-side IP of 192.168.0.250 - adjust to suit your
-  own network):
-
-  +o  The device needs to be configured with its IP address.  Tap devices
-     are also configured with an mtu of 1484.  Slip devices are
-     configured with a point-to-point address pointing at the UML ip
-     address.
-
-
-       host#  ifconfig tap0 arp mtu 1484 192.168.0.251 up
-
-
-
-
-
-
-       host#
-       ifconfig sl0 192.168.0.251 pointopoint 192.168.0.250 up
-
-
-
-
-
-  +o  If a tap device is being set up, a route is set to the UML IP.
-
-
-       UML# route add -host 192.168.0.250 gw 192.168.0.251
-
-
-
-
-
-  +o  To allow other hosts on your network to see the virtual machine,
-     proxy arp is set up for it.
-
-
-       host#  arp -Ds 192.168.0.250 eth0 pub
-
-
-
-
-
-  +o  Finally, the host is set up to route packets.
-
-
-       host#  echo 1 > /proc/sys/net/ipv4/ip_forward
-
-
-
-
-
-
-
-
-
-
-  77..  SShhaarriinngg FFiilleessyysstteemmss bbeettwweeeenn VViirrttuuaall MMaacchhiinneess
-
-
-
-
-  77..11..  AA wwaarrnniinngg
-
-  Don't attempt to share filesystems simply by booting two UMLs from the
-  same file.  That's the same thing as booting two physical machines
-  from a shared disk.  It will result in filesystem corruption.
-
-
-
-  77..22..  UUssiinngg llaayyeerreedd bblloocckk ddeevviicceess
-
-  The way to share a filesystem between two virtual machines is to use
-  the copy-on-write (COW) layering capability of the ubd block driver.
-  As of 2.4.6-2um, the driver supports layering a read-write private
-  device over a read-only shared device.  A machine's writes are stored
-  in the private device, while reads come from either device - the
-  private one if the requested block is valid in it, the shared one if
-  not.  Using this scheme, the majority of data which is unchanged is
-  shared between an arbitrary number of virtual machines, each of which
-  has a much smaller file containing the changes that it has made.  With
-  a large number of UMLs booting from a large root filesystem, this
-  leads to a huge disk space saving.  It will also help performance,
-  since the host will be able to cache the shared data using a much
-  smaller amount of memory, so UML disk requests will be served from the
-  host's memory rather than its disks.
-
-
-
-
-  To add a copy-on-write layer to an existing block device file, simply
-  add the name of the COW file to the appropriate ubd switch:
-
-
-        ubd0=root_fs_cow,root_fs_debian_22
-
-
-
-
-  where 'root_fs_cow' is the private COW file and 'root_fs_debian_22' is
-  the existing shared filesystem.  The COW file need not exist.  If it
-  doesn't, the driver will create and initialize it.  Once the COW file
-  has been initialized, it can be used on its own on the command line:
-
-
-        ubd0=root_fs_cow
-
-
-
-
-  The name of the backing file is stored in the COW file header, so it
-  would be redundant to continue specifying it on the command line.
-
-
-
-  77..33..  NNoottee!!
-
-  When checking the size of the COW file in order to see the gobs of
-  space that you're saving, make sure you use 'ls -ls' to see the actual
-  disk consumption rather than the length of the file.  The COW file is
-  sparse, so the length will be very different from the disk usage.
-  Here is a 'ls -l' of a COW file and backing file from one boot and
-  shutdown:
-       host% ls -l cow.debian debian2.2
-       -rw-r--r--    1 jdike    jdike    492504064 Aug  6 21:16 cow.debian
-       -rwxrw-rw-    1 jdike    jdike    537919488 Aug  6 20:42 debian2.2
-
-
-
-
-  Doesn't look like much saved space, does it?  Well, here's 'ls -ls':
-
-
-       host% ls -ls cow.debian debian2.2
-          880 -rw-r--r--    1 jdike    jdike    492504064 Aug  6 21:16 cow.debian
-       525832 -rwxrw-rw-    1 jdike    jdike    537919488 Aug  6 20:42 debian2.2
-
-
-
-
-  Now, you can see that the COW file has less than a meg of disk, rather
-  than 492 meg.
-
-
-
-  77..44..  AAnnootthheerr wwaarrnniinngg
-
-  Once a filesystem is being used as a readonly backing file for a COW
-  file, do not boot directly from it or modify it in any way.  Doing so
-  will invalidate any COW files that are using it.  The mtime and size
-  of the backing file are stored in the COW file header at its creation,
-  and they must continue to match.  If they don't, the driver will
-  refuse to use the COW file.
-
-
-
-
-  If you attempt to evade this restriction by changing either the
-  backing file or the COW header by hand, you will get a corrupted
-  filesystem.
-
-
-
-
-  Among other things, this means that upgrading the distribution in a
-  backing file and expecting that all of the COW files using it will see
-  the upgrade will not work.
-
-
-
-
-  77..55..  uummll__mmoooo :: MMeerrggiinngg aa CCOOWW ffiillee wwiitthh iittss bbaacckkiinngg ffiillee
-
-  Depending on how you use UML and COW devices, it may be advisable to
-  merge the changes in the COW file into the backing file every once in
-  a while.
-
-
-
-
-  The utility that does this is uml_moo.  Its usage is
-
-
-       host% uml_moo COW file new backing file
-
-
-
-
-  There's no need to specify the backing file since that information is
-  already in the COW file header.  If you're paranoid, boot the new
-  merged file, and if you're happy with it, move it over the old backing
-  file.
-
-
-
-
-  uml_moo creates a new backing file by default as a safety measure.  It
-  also has a destructive merge option which will merge the COW file
-  directly into its current backing file.  This is really only usable
-  when the backing file only has one COW file associated with it.  If
-  there are multiple COWs associated with a backing file, a -d merge of
-  one of them will invalidate all of the others.  However, it is
-  convenient if you're short of disk space, and it should also be
-  noticeably faster than a non-destructive merge.
-
-
-
-
-  uml_moo is installed with the UML deb and RPM.  If you didn't install
-  UML from one of those packages, you can also get it from the UML
-  utilities <http://user-mode-linux.sourceforge.net/
-  utilities>  tar file in tools/moo.
-
-
-
-
-
-
-
-
-  88..  CCrreeaattiinngg ffiilleessyysstteemmss
-
-
-  You may want to create and mount new UML filesystems, either because
-  your root filesystem isn't large enough or because you want to use a
-  filesystem other than ext2.
-
-
-  This was written on the occasion of reiserfs being included in the
-  2.4.1 kernel pool, and therefore the 2.4.1 UML, so the examples will
-  talk about reiserfs.  This information is generic, and the examples
-  should be easy to translate to the filesystem of your choice.
-
-
-  88..11..  CCrreeaattee tthhee ffiilleessyysstteemm ffiillee
-
-  dd is your friend.  All you need to do is tell dd to create an empty
-  file of the appropriate size.  I usually make it sparse to save time
-  and to avoid allocating disk space until it's actually used.  For
-  example, the following command will create a sparse 100 meg file full
-  of zeroes.
-
-
-       host%
-       dd if=/dev/zero of=new_filesystem seek=100 count=1 bs=1M
-
-
-
-
-
-
-  88..22..  AAssssiiggnn tthhee ffiillee ttoo aa UUMMLL ddeevviiccee
-
-  Add an argument like the following to the UML command line:
-
-  ubd4=new_filesystem
-
-
-
-
-  making sure that you use an unassigned ubd device number.
-
-
-
-  88..33..  CCrreeaattiinngg aanndd mmoouunnttiinngg tthhee ffiilleessyysstteemm
-
-  Make sure that the filesystem is available, either by being built into
-  the kernel, or available as a module, then boot up UML and log in.  If
-  the root filesystem doesn't have the filesystem utilities (mkfs, fsck,
-  etc), then get them into UML by way of the net or hostfs.
-
-
-  Make the new filesystem on the device assigned to the new file:
-
-
-       host#  mkreiserfs /dev/ubd/4
-
-
-       <----------- MKREISERFSv2 ----------->
-
-       ReiserFS version 3.6.25
-       Block size 4096 bytes
-       Block count 25856
-       Used blocks 8212
-               Journal - 8192 blocks (18-8209), journal header is in block 8210
-               Bitmaps: 17
-               Root block 8211
-       Hash function "r5"
-       ATTENTION: ALL DATA WILL BE LOST ON '/dev/ubd/4'! (y/n)y
-       journal size 8192 (from 18)
-       Initializing journal - 0%....20%....40%....60%....80%....100%
-       Syncing..done.
-
-
-
-
-  Now, mount it:
-
-
-       UML#
-       mount /dev/ubd/4 /mnt
-
-
-
-
-  and you're in business.
-
-
-
-
-
-
-
-
-
-  99..  HHoosstt ffiillee aacccceessss
-
-
-  If you want to access files on the host machine from inside UML, you
-  can treat it as a separate machine and either nfs mount directories
-  from the host or copy files into the virtual machine with scp or rcp.
-  However, since UML is running on the host, it can access those
-  files just like any other process and make them available inside the
-  virtual machine without needing to use the network.
-
-
-  This is now possible with the hostfs virtual filesystem.  With it, you
-  can mount a host directory into the UML filesystem and access the
-  files contained in it just as you would on the host.
-
-
-  99..11..  UUssiinngg hhoossttffss
-
-  To begin with, make sure that hostfs is available inside the virtual
-  machine with
-
-
-       UML# cat /proc/filesystems
-
-
-
-  .  hostfs should be listed.  If it's not, either rebuild the kernel
-  with hostfs configured into it or make sure that hostfs is built as a
-  module and available inside the virtual machine, and insmod it.
-
-
-  Now all you need to do is run mount:
-
-
-       UML# mount none /mnt/host -t hostfs
-
-
-
-
-  will mount the host's / on the virtual machine's /mnt/host.
-
-
-  If you don't want to mount the host root directory, then you can
-  specify a subdirectory to mount with the -o switch to mount:
-
-
-       UML# mount none /mnt/home -t hostfs -o /home
-
-
-
-
-  will mount the hosts's /home on the virtual machine's /mnt/home.
-
-
-
-  99..22..  hhoossttffss aass tthhee rroooott ffiilleessyysstteemm
-
-  It's possible to boot from a directory hierarchy on the host using
-  hostfs rather than using the standard filesystem in a file.
-
-  To start, you need that hierarchy.  The easiest way is to loop mount
-  an existing root_fs file:
-
-
-       host#  mount root_fs uml_root_dir -o loop
-
-
-
-
-  You need to change the filesystem type of / in etc/fstab to be
-  'hostfs', so that line looks like this:
-
-  /dev/ubd/0       /        hostfs      defaults          1   1
-
-
-
-
-  Then you need to chown to yourself all the files in that directory
-  that are owned by root.  This worked for me:
-
-
-       host#  find . -uid 0 -exec chown jdike {} \;
-
-
-
-
-  Next, make sure that your UML kernel has hostfs compiled in, not as a
-  module.  Then run UML with the boot device pointing at that directory:
-
-
-        ubd0=/path/to/uml/root/directory
-
-
-
-
-  UML should then boot as it does normally.
-
-
-  99..33..  BBuuiillddiinngg hhoossttffss
-
-  If you need to build hostfs because it's not in your kernel, you have
-  two choices:
-
-
-
-  +o  Compiling hostfs into the kernel:
-
-
-     Reconfigure the kernel and set the 'Host filesystem' option under
-
-
-  +o  Compiling hostfs as a module:
-
-
-     Reconfigure the kernel and set the 'Host filesystem' option under
-     be in arch/um/fs/hostfs/hostfs.o.  Install that in
-     /lib/modules/`uname -r`/fs in the virtual machine, boot it up, and
-
-
-       UML# insmod hostfs
-
-
-
-
-
-
-
-
-
-
-
-
-  1100..  TThhee MMaannaaggeemmeenntt CCoonnssoollee
-
-
-
-  The UML management console is a low-level interface to the kernel,
-  somewhat like the i386 SysRq interface.  Since there is a full-blown
-  operating system under UML, there is much greater flexibility possible
-  than with the SysRq mechanism.
-
-
-  There are a number of things you can do with the mconsole interface:
-
-  +o  get the kernel version
-
-  +o  add and remove devices
-
-  +o  halt or reboot the machine
-
-  +o  Send SysRq commands
-
-  +o  Pause and resume the UML
-
-
-  You need the mconsole client (uml_mconsole) which is present in CVS
-  (/tools/mconsole) in 2.4.5-9um and later, and will be in the RPM in
-  2.4.6.
-
-
-  You also need CONFIG_MCONSOLE (under 'General Setup') enabled in UML.
-  When you boot UML, you'll see a line like:
-
-
-       mconsole initialized on /home/jdike/.uml/umlNJ32yL/mconsole
-
-
-
-
-  If you specify a unique machine id one the UML command line, i.e.
-
-
-        umid=debian
-
-
-
-
-  you'll see this
-
-
-       mconsole initialized on /home/jdike/.uml/debian/mconsole
-
-
-
-
-  That file is the socket that uml_mconsole will use to communicate with
-  UML.  Run it with either the umid or the full path as its argument:
-
-
-       host% uml_mconsole debian
-
-
-
-
-  or
-
-
-       host% uml_mconsole /home/jdike/.uml/debian/mconsole
-
-
-
-
-  You'll get a prompt, at which you can run one of these commands:
-
-  +o  version
-
-  +o  halt
-
-  +o  reboot
-
-  +o  config
-
-  +o  remove
-
-  +o  sysrq
-
-  +o  help
-
-  +o  cad
-
-  +o  stop
-
-  +o  go
-
-
-  1100..11..  vveerrssiioonn
-
-  This takes no arguments.  It prints the UML version.
-
-
-       (mconsole)  version
-       OK Linux usermode 2.4.5-9um #1 Wed Jun 20 22:47:08 EDT 2001 i686
-
-
-
-
-  There are a couple actual uses for this.  It's a simple no-op which
-  can be used to check that a UML is running.  It's also a way of
-  sending an interrupt to the UML.  This is sometimes useful on SMP
-  hosts, where there's a bug which causes signals to UML to be lost,
-  often causing it to appear to hang.  Sending such a UML the mconsole
-  version command is a good way to 'wake it up' before networking has
-  been enabled, as it does not do anything to the function of the UML.
-
-
-
-  1100..22..  hhaalltt aanndd rreebboooott
-
-  These take no arguments.  They shut the machine down immediately, with
-  no syncing of disks and no clean shutdown of userspace.  So, they are
-  pretty close to crashing the machine.
-
-
-       (mconsole)  halt
-       OK
-
-
-
-
-
-
-  1100..33..  ccoonnffiigg
-
-  "config" adds a new device to the virtual machine.  Currently the ubd
-  and network drivers support this.  It takes one argument, which is the
-  device to add, with the same syntax as the kernel command line.
-
-
-
-
-  (mconsole)
-  config ubd3=/home/jdike/incoming/roots/root_fs_debian22
-
-  OK
-  (mconsole)  config eth1=mcast
-  OK
-
-
-
-
-
-
-  1100..44..  rreemmoovvee
-
-  "remove" deletes a device from the system.  Its argument is just the
-  name of the device to be removed. The device must be idle in whatever
-  sense the driver considers necessary.  In the case of the ubd driver,
-  the removed block device must not be mounted, swapped on, or otherwise
-  open, and in the case of the network driver, the device must be down.
-
-
-       (mconsole)  remove ubd3
-       OK
-       (mconsole)  remove eth1
-       OK
-
-
-
-
-
-
-  1100..55..  ssyyssrrqq
-
-  This takes one argument, which is a single letter.  It calls the
-  generic kernel's SysRq driver, which does whatever is called for by
-  that argument.  See the SysRq documentation in Documentation/sysrq.txt
-  in your favorite kernel tree to see what letters are valid and what
-  they do.
-
-
-
-  1100..66..  hheellpp
-
-  "help" returns a string listing the valid commands and what each one
-  does.
-
-
-
-  1100..77..  ccaadd
-
-  This invokes the Ctl-Alt-Del action on init.  What exactly this ends
-  up doing is up to /etc/inittab.  Normally, it reboots the machine.
-  With UML, this is usually not desired, so if a halt would be better,
-  then find the section of inittab that looks like this
-
-
-       # What to do when CTRL-ALT-DEL is pressed.
-       ca:12345:ctrlaltdel:/sbin/shutdown -t1 -a -r now
-
-
-
-
-  and change the command to halt.
-
-
-
-  1100..88..  ssttoopp
-
-  This puts the UML in a loop reading mconsole requests until a 'go'
-  mconsole command is received. This is very useful for making backups
-  of UML filesystems, as the UML can be stopped, then synced via 'sysrq
-  s', so that everything is written to the filesystem. You can then copy
-  the filesystem and then send the UML 'go' via mconsole.
-
-
-  Note that a UML running with more than one CPU will have problems
-  after you send the 'stop' command, as only one CPU will be held in a
-  mconsole loop and all others will continue as normal.  This is a bug,
-  and will be fixed.
-
-
-
-  1100..99..  ggoo
-
-  This resumes a UML after being paused by a 'stop' command. Note that
-  when the UML has resumed, TCP connections may have timed out and if
-  the UML is paused for a long period of time, crond might go a little
-  crazy, running all the jobs it didn't do earlier.
-
-
-
-
-
-
-
-
-  1111..  KKeerrnneell ddeebbuuggggiinngg
-
-
-  NNoottee:: The interface that makes debugging, as described here, possible
-  is present in 2.4.0-test6 kernels and later.
-
-
-  Since the user-mode kernel runs as a normal Linux process, it is
-  possible to debug it with gdb almost like any other process.  It is
-  slightly different because the kernel's threads are already being
-  ptraced for system call interception, so gdb can't ptrace them.
-  However, a mechanism has been added to work around that problem.
-
-
-  In order to debug the kernel, you need build it from source.  See
-  ``Compiling the kernel and modules''  for information on doing that.
-  Make sure that you enable CONFIG_DEBUGSYM and CONFIG_PT_PROXY during
-  the config.  These will compile the kernel with -g, and enable the
-  ptrace proxy so that gdb works with UML, respectively.
-
-
-
-
-  1111..11..  SSttaarrttiinngg tthhee kkeerrnneell uunnddeerr ggddbb
-
-  You can have the kernel running under the control of gdb from the
-  beginning by putting 'debug' on the command line.  You will get an
-  xterm with gdb running inside it.  The kernel will send some commands
-  to gdb which will leave it stopped at the beginning of start_kernel.
-  At this point, you can get things going with 'next', 'step', or
-  'cont'.
-
-
-  There is a transcript of a debugging session  here <debug-
-  session.html> , with breakpoints being set in the scheduler and in an
-  interrupt handler.
-  1111..22..  EExxaammiinniinngg sslleeeeppiinngg pprroocceesssseess
-
-  Not every bug is evident in the currently running process.  Sometimes,
-  processes hang in the kernel when they shouldn't because they've
-  deadlocked on a semaphore or something similar.  In this case, when
-  you ^C gdb and get a backtrace, you will see the idle thread, which
-  isn't very relevant.
-
-
-  What you want is the stack of whatever process is sleeping when it
-  shouldn't be.  You need to figure out which process that is, which is
-  generally fairly easy.  Then you need to get its host process id,
-  which you can do either by looking at ps on the host or at
-  task.thread.extern_pid in gdb.
-
-
-  Now what you do is this:
-
-  +o  detach from the current thread
-
-
-       (UML gdb)  det
-
-
-
-
-
-  +o  attach to the thread you are interested in
-
-
-       (UML gdb)  att <host pid>
-
-
-
-
-
-  +o  look at its stack and anything else of interest
-
-
-       (UML gdb)  bt
-
-
-
-
-  Note that you can't do anything at this point that requires that a
-  process execute, e.g. calling a function
-
-  +o  when you're done looking at that process, reattach to the current
-     thread and continue it
-
-
-       (UML gdb)
-       att 1
-
-
-
-
-
-
-       (UML gdb)
-       c
-
-
-
-
-  Here, specifying any pid which is not the process id of a UML thread
-  will cause gdb to reattach to the current thread.  I commonly use 1,
-  but any other invalid pid would work.
-
-
-
-  1111..33..  RRuunnnniinngg dddddd oonn UUMMLL
-
-  ddd works on UML, but requires a special kludge.  The process goes
-  like this:
-
-  +o  Start ddd
-
-
-       host% ddd linux
-
-
-
-
-
-  +o  With ps, get the pid of the gdb that ddd started.  You can ask the
-     gdb to tell you, but for some reason that confuses things and
-     causes a hang.
-
-  +o  run UML with 'debug=parent gdb-pid=<pid>' added to the command line
-     - it will just sit there after you hit return
-
-  +o  type 'att 1' to the ddd gdb and you will see something like
-
-
-       0xa013dc51 in __kill ()
-
-
-       (gdb)
-
-
-
-
-
-  +o  At this point, type 'c', UML will boot up, and you can use ddd just
-     as you do on any other process.
-
-
-
-  1111..44..  DDeebbuuggggiinngg mmoodduulleess
-
-  gdb has support for debugging code which is dynamically loaded into
-  the process.  This support is what is needed to debug kernel modules
-  under UML.
-
-
-  Using that support is somewhat complicated.  You have to tell gdb what
-  object file you just loaded into UML and where in memory it is.  Then,
-  it can read the symbol table, and figure out where all the symbols are
-  from the load address that you provided.  It gets more interesting
-  when you load the module again (i.e. after an rmmod).  You have to
-  tell gdb to forget about all its symbols, including the main UML ones
-  for some reason, then load then all back in again.
-
-
-  There's an easy way and a hard way to do this.  The easy way is to use
-  the umlgdb expect script written by Chandan Kudige.  It basically
-  automates the process for you.
-
-
-  First, you must tell it where your modules are.  There is a list in
-  the script that looks like this:
-       set MODULE_PATHS {
-       "fat" "/usr/src/uml/linux-2.4.18/fs/fat/fat.o"
-       "isofs" "/usr/src/uml/linux-2.4.18/fs/isofs/isofs.o"
-       "minix" "/usr/src/uml/linux-2.4.18/fs/minix/minix.o"
-       }
-
-
-
-
-  You change that to list the names and paths of the modules that you
-  are going to debug.  Then you run it from the toplevel directory of
-  your UML pool and it basically tells you what to do:
-
-
-
-
-                   ******** GDB pid is 21903 ********
-       Start UML as: ./linux <kernel switches> debug gdb-pid=21903
-
-
-
-       GNU gdb 5.0rh-5 Red Hat Linux 7.1
-       Copyright 2001 Free Software Foundation, Inc.
-       GDB is free software, covered by the GNU General Public License, and you are
-       welcome to change it and/or distribute copies of it under certain conditions.
-       Type "show copying" to see the conditions.
-       There is absolutely no warranty for GDB.  Type "show warranty" for details.
-       This GDB was configured as "i386-redhat-linux"...
-       (gdb) b sys_init_module
-       Breakpoint 1 at 0xa0011923: file module.c, line 349.
-       (gdb) att 1
-
-
-
-
-  After you run UML and it sits there doing nothing, you hit return at
-  the 'att 1' and continue it:
-
-
-       Attaching to program: /home/jdike/linux/2.4/um/./linux, process 1
-       0xa00f4221 in __kill ()
-       (UML gdb)  c
-       Continuing.
-
-
-
-
-  At this point, you debug normally.  When you insmod something, the
-  expect magic will kick in and you'll see something like:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-   *** Module hostfs loaded ***
-  Breakpoint 1, sys_init_module (name_user=0x805abb0 "hostfs",
-      mod_user=0x8070e00) at module.c:349
-  349             char *name, *n_name, *name_tmp = NULL;
-  (UML gdb)  finish
-  Run till exit from #0  sys_init_module (name_user=0x805abb0 "hostfs",
-      mod_user=0x8070e00) at module.c:349
-  0xa00e2e23 in execute_syscall (r=0xa8140284) at syscall_kern.c:411
-  411             else res = EXECUTE_SYSCALL(syscall, regs);
-  Value returned is $1 = 0
-  (UML gdb)
-  p/x (int)module_list + module_list->size_of_struct
-
-  $2 = 0xa9021054
-  (UML gdb)  symbol-file ./linux
-  Load new symbol table from "./linux"? (y or n) y
-  Reading symbols from ./linux...
-  done.
-  (UML gdb)
-  add-symbol-file /home/jdike/linux/2.4/um/arch/um/fs/hostfs/hostfs.o 0xa9021054
-
-  add symbol table from file "/home/jdike/linux/2.4/um/arch/um/fs/hostfs/hostfs.o" at
-          .text_addr = 0xa9021054
-   (y or n) y
-
-  Reading symbols from /home/jdike/linux/2.4/um/arch/um/fs/hostfs/hostfs.o...
-  done.
-  (UML gdb)  p *module_list
-  $1 = {size_of_struct = 84, next = 0xa0178720, name = 0xa9022de0 "hostfs",
-    size = 9016, uc = {usecount = {counter = 0}, pad = 0}, flags = 1,
-    nsyms = 57, ndeps = 0, syms = 0xa9023170, deps = 0x0, refs = 0x0,
-    init = 0xa90221f0 <init_hostfs>, cleanup = 0xa902222c <exit_hostfs>,
-    ex_table_start = 0x0, ex_table_end = 0x0, persist_start = 0x0,
-    persist_end = 0x0, can_unload = 0, runsize = 0, kallsyms_start = 0x0,
-    kallsyms_end = 0x0,
-    archdata_start = 0x1b855 <Address 0x1b855 out of bounds>,
-    archdata_end = 0xe5890000 <Address 0xe5890000 out of bounds>,
-    kernel_data = 0xf689c35d <Address 0xf689c35d out of bounds>}
-  >> Finished loading symbols for hostfs ...
-
-
-
-
-  That's the easy way.  It's highly recommended.  The hard way is
-  described below in case you're interested in what's going on.
-
-
-  Boot the kernel under the debugger and load the module with insmod or
-  modprobe.  With gdb, do:
-
-
-       (UML gdb)  p module_list
-
-
-
-
-  This is a list of modules that have been loaded into the kernel, with
-  the most recently loaded module first.  Normally, the module you want
-  is at module_list.  If it's not, walk down the next links, looking at
-  the name fields until find the module you want to debug.  Take the
-  address of that structure, and add module.size_of_struct (which in
-  2.4.10 kernels is 96 (0x60)) to it.  Gdb can make this hard addition
-  for you :-):
-
-
-
-  (UML gdb)
-  printf "%#x\n", (int)module_list module_list->size_of_struct
-
-
-
-
-  The offset from the module start occasionally changes (before 2.4.0,
-  it was module.size_of_struct + 4), so it's a good idea to check the
-  init and cleanup addresses once in a while, as describe below.  Now
-  do:
-
-
-       (UML gdb)
-       add-symbol-file /path/to/module/on/host that_address
-
-
-
-
-  Tell gdb you really want to do it, and you're in business.
-
-
-  If there's any doubt that you got the offset right, like breakpoints
-  appear not to work, or they're appearing in the wrong place, you can
-  check it by looking at the module structure.  The init and cleanup
-  fields should look like:
-
-
-       init = 0x588066b0 <init_hostfs>, cleanup = 0x588066c0 <exit_hostfs>
-
-
-
-
-  with no offsets on the symbol names.  If the names are right, but they
-  are offset, then the offset tells you how much you need to add to the
-  address you gave to add-symbol-file.
-
-
-  When you want to load in a new version of the module, you need to get
-  gdb to forget about the old one.  The only way I've found to do that
-  is to tell gdb to forget about all symbols that it knows about:
-
-
-       (UML gdb)  symbol-file
-
-
-
-
-  Then reload the symbols from the kernel binary:
-
-
-       (UML gdb)  symbol-file /path/to/kernel
-
-
-
-
-  and repeat the process above.  You'll also need to re-enable break-
-  points.  They were disabled when you dumped all the symbols because
-  gdb couldn't figure out where they should go.
-
-
-
-  1111..55..  AAttttaacchhiinngg ggddbb ttoo tthhee kkeerrnneell
-
-  If you don't have the kernel running under gdb, you can attach gdb to
-  it later by sending the tracing thread a SIGUSR1.  The first line of
-  the console output identifies its pid:
-       tracing thread pid = 20093
-
-
-
-
-  When you send it the signal:
-
-
-       host% kill -USR1 20093
-
-
-
-
-  you will get an xterm with gdb running in it.
-
-
-  If you have the mconsole compiled into UML, then the mconsole client
-  can be used to start gdb:
-
-
-       (mconsole)  (mconsole) config gdb=xterm
-
-
-
-
-  will fire up an xterm with gdb running in it.
-
-
-
-  1111..66..  UUssiinngg aalltteerrnnaattee ddeebbuuggggeerrss
-
-  UML has support for attaching to an already running debugger rather
-  than starting gdb itself.  This is present in CVS as of 17 Apr 2001.
-  I sent it to Alan for inclusion in the ac tree, and it will be in my
-  2.4.4 release.
-
-
-  This is useful when gdb is a subprocess of some UI, such as emacs or
-  ddd.  It can also be used to run debuggers other than gdb on UML.
-  Below is an example of using strace as an alternate debugger.
-
-
-  To do this, you need to get the pid of the debugger and pass it in
-  with the
-
-
-  If you are using gdb under some UI, then tell it to 'att 1', and
-  you'll find yourself attached to UML.
-
-
-  If you are using something other than gdb as your debugger, then
-  you'll need to get it to do the equivalent of 'att 1' if it doesn't do
-  it automatically.
-
-
-  An example of an alternate debugger is strace.  You can strace the
-  actual kernel as follows:
-
-  +o  Run the following in a shell
-
-
-       host%
-       sh -c 'echo pid=$$; echo -n hit return; read x; exec strace -p 1 -o strace.out'
-
-
-
-  +o  Run UML with 'debug' and 'gdb-pid=<pid>' with the pid printed out
-     by the previous command
-
-  +o  Hit return in the shell, and UML will start running, and strace
-     output will start accumulating in the output file.
-
-     Note that this is different from running
-
-
-       host% strace ./linux
-
-
-
-
-  That will strace only the main UML thread, the tracing thread, which
-  doesn't do any of the actual kernel work.  It just oversees the vir-
-  tual machine.  In contrast, using strace as described above will show
-  you the low-level activity of the virtual machine.
-
-
-
-
-
-  1122..  KKeerrnneell ddeebbuuggggiinngg eexxaammpplleess
-
-  1122..11..  TThhee ccaassee ooff tthhee hhuunngg ffsscckk
-
-  When booting up the kernel, fsck failed, and dropped me into a shell
-  to fix things up.  I ran fsck -y, which hung:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-  Setting hostname uml                    [ OK ]
-  Checking root filesystem
-  /dev/fhd0 was not cleanly unmounted, check forced.
-  Error reading block 86894 (Attempt to read block from filesystem resulted in short read) while reading indirect blocks of inode 19780.
-
-  /dev/fhd0: UNEXPECTED INCONSISTENCY; RUN fsck MANUALLY.
-          (i.e., without -a or -p options)
-  [ FAILED ]
-
-  *** An error occurred during the file system check.
-  *** Dropping you to a shell; the system will reboot
-  *** when you leave the shell.
-  Give root password for maintenance
-  (or type Control-D for normal startup):
-
-  [root@uml /root]# fsck -y /dev/fhd0
-  fsck -y /dev/fhd0
-  Parallelizing fsck version 1.14 (9-Jan-1999)
-  e2fsck 1.14, 9-Jan-1999 for EXT2 FS 0.5b, 95/08/09
-  /dev/fhd0 contains a file system with errors, check forced.
-  Pass 1: Checking inodes, blocks, and sizes
-  Error reading block 86894 (Attempt to read block from filesystem resulted in short read) while reading indirect blocks of inode 19780.  Ignore error? yes
-
-  Inode 19780, i_blocks is 1548, should be 540.  Fix? yes
-
-  Pass 2: Checking directory structure
-  Error reading block 49405 (Attempt to read block from filesystem resulted in short read).  Ignore error? yes
-
-  Directory inode 11858, block 0, offset 0: directory corrupted
-  Salvage? yes
-
-  Missing '.' in directory inode 11858.
-  Fix? yes
-
-  Missing '..' in directory inode 11858.
-  Fix? yes
-
-
-
-
-
-  The standard drill in this sort of situation is to fire up gdb on the
-  signal thread, which, in this case, was pid 1935.  In another window,
-  I run gdb and attach pid 1935.
-
-
-
-
-       ~/linux/2.3.26/um 1016: gdb linux
-       GNU gdb 4.17.0.11 with Linux support
-       Copyright 1998 Free Software Foundation, Inc.
-       GDB is free software, covered by the GNU General Public License, and you are
-       welcome to change it and/or distribute copies of it under certain conditions.
-       Type "show copying" to see the conditions.
-       There is absolutely no warranty for GDB.  Type "show warranty" for details.
-       This GDB was configured as "i386-redhat-linux"...
-
-       (gdb) att 1935
-       Attaching to program `/home/dike/linux/2.3.26/um/linux', Pid 1935
-       0x100756d9 in __wait4 ()
-
-
-
-
-
-
-  Let's see what's currently running:
-
-
-
-       (gdb) p current_task.pid
-       $1 = 0
-
-
-
-
-
-  It's the idle thread, which means that fsck went to sleep for some
-  reason and never woke up.
-
-
-  Let's guess that the last process in the process list is fsck:
-
-
-
-       (gdb) p current_task.prev_task.comm
-       $13 = "fsck.ext2\000\000\000\000\000\000"
-
-
-
-
-
-  It is, so let's see what it thinks it's up to:
-
-
-
-       (gdb) p current_task.prev_task.thread
-       $14 = {extern_pid = 1980, tracing = 0, want_tracing = 0, forking = 0,
-         kernel_stack_page = 0, signal_stack = 1342627840, syscall = {id = 4, args = {
-             3, 134973440, 1024, 0, 1024}, have_result = 0, result = 50590720},
-         request = {op = 2, u = {exec = {ip = 1350467584, sp = 2952789424}, fork = {
-               regs = {1350467584, 2952789424, 0 <repeats 15 times>}, sigstack = 0,
-               pid = 0}, switch_to = 0x507e8000, thread = {proc = 0x507e8000,
-               arg = 0xaffffdb0, flags = 0, new_pid = 0}, input_request = {
-               op = 1350467584, fd = -1342177872, proc = 0, pid = 0}}}}
-
-
-
-
-
-  The interesting things here are the fact that its .thread.syscall.id
-  is __NR_write (see the big switch in arch/um/kernel/syscall_kern.c or
-  the defines in include/asm-um/arch/unistd.h), and that it never
-  returned.  Also, its .request.op is OP_SWITCH (see
-  arch/um/include/user_util.h).  These mean that it went into a write,
-  and, for some reason, called schedule().
-
-
-  The fact that it never returned from write means that its stack should
-  be fairly interesting.  Its pid is 1980 (.thread.extern_pid).  That
-  process is being ptraced by the signal thread, so it must be detached
-  before gdb can attach it:
-
-
-
-
-
-
-
-
-
-
-  (gdb) call detach(1980)
-
-  Program received signal SIGSEGV, Segmentation fault.
-  <function called from gdb>
-  The program being debugged stopped while in a function called from GDB.
-  When the function (detach) is done executing, GDB will silently
-  stop (instead of continuing to evaluate the expression containing
-  the function call).
-  (gdb) call detach(1980)
-  $15 = 0
-
-
-
-
-
-  The first detach segfaults for some reason, and the second one
-  succeeds.
-
-
-  Now I detach from the signal thread, attach to the fsck thread, and
-  look at its stack:
-
-
-       (gdb) det
-       Detaching from program: /home/dike/linux/2.3.26/um/linux Pid 1935
-       (gdb) att 1980
-       Attaching to program `/home/dike/linux/2.3.26/um/linux', Pid 1980
-       0x10070451 in __kill ()
-       (gdb) bt
-       #0  0x10070451 in __kill ()
-       #1  0x10068ccd in usr1_pid (pid=1980) at process.c:30
-       #2  0x1006a03f in _switch_to (prev=0x50072000, next=0x507e8000)
-           at process_kern.c:156
-       #3  0x1006a052 in switch_to (prev=0x50072000, next=0x507e8000, last=0x50072000)
-           at process_kern.c:161
-       #4  0x10001d12 in schedule () at sched.c:777
-       #5  0x1006a744 in __down (sem=0x507d241c) at semaphore.c:71
-       #6  0x1006aa10 in __down_failed () at semaphore.c:157
-       #7  0x1006c5d8 in segv_handler (sc=0x5006e940) at trap_user.c:174
-       #8  0x1006c5ec in kern_segv_handler (sig=11) at trap_user.c:182
-       #9  <signal handler called>
-       #10 0x10155404 in errno ()
-       #11 0x1006c0aa in segv (address=1342179328, is_write=2) at trap_kern.c:50
-       #12 0x1006c5d8 in segv_handler (sc=0x5006eaf8) at trap_user.c:174
-       #13 0x1006c5ec in kern_segv_handler (sig=11) at trap_user.c:182
-       #14 <signal handler called>
-       #15 0xc0fd in ?? ()
-       #16 0x10016647 in sys_write (fd=3,
-           buf=0x80b8800 <Address 0x80b8800 out of bounds>, count=1024)
-           at read_write.c:159
-       #17 0x1006d5b3 in execute_syscall (syscall=4, args=0x5006ef08)
-           at syscall_kern.c:254
-       #18 0x1006af87 in really_do_syscall (sig=12) at syscall_user.c:35
-       #19 <signal handler called>
-       #20 0x400dc8b0 in ?? ()
-
-
-
-
-
-  The interesting things here are :
-
-  +o  There are two segfaults on this stack (frames 9 and 14)
-
-  +o  The first faulting address (frame 11) is 0x50000800
-
-  (gdb) p (void *)1342179328
-  $16 = (void *) 0x50000800
-
-
-
-
-
-  The initial faulting address is interesting because it is on the idle
-  thread's stack.  I had been seeing the idle thread segfault for no
-  apparent reason, and the cause looked like stack corruption.  In hopes
-  of catching the culprit in the act, I had turned off all protections
-  to that stack while the idle thread wasn't running.  This apparently
-  tripped that trap.
-
-
-  However, the more immediate problem is that second segfault and I'm
-  going to concentrate on that.  First, I want to see where the fault
-  happened, so I have to go look at the sigcontent struct in frame 8:
-
-
-
-       (gdb) up
-       #1  0x10068ccd in usr1_pid (pid=1980) at process.c:30
-       30        kill(pid, SIGUSR1);
-       (gdb)
-       #2  0x1006a03f in _switch_to (prev=0x50072000, next=0x507e8000)
-           at process_kern.c:156
-       156       usr1_pid(getpid());
-       (gdb)
-       #3  0x1006a052 in switch_to (prev=0x50072000, next=0x507e8000, last=0x50072000)
-           at process_kern.c:161
-       161       _switch_to(prev, next);
-       (gdb)
-       #4  0x10001d12 in schedule () at sched.c:777
-       777             switch_to(prev, next, prev);
-       (gdb)
-       #5  0x1006a744 in __down (sem=0x507d241c) at semaphore.c:71
-       71                      schedule();
-       (gdb)
-       #6  0x1006aa10 in __down_failed () at semaphore.c:157
-       157     }
-       (gdb)
-       #7  0x1006c5d8 in segv_handler (sc=0x5006e940) at trap_user.c:174
-       174       segv(sc->cr2, sc->err & 2);
-       (gdb)
-       #8  0x1006c5ec in kern_segv_handler (sig=11) at trap_user.c:182
-       182       segv_handler(sc);
-       (gdb) p *sc
-       Cannot access memory at address 0x0.
-
-
-
-
-  That's not very useful, so I'll try a more manual method:
-
-
-       (gdb) p *((struct sigcontext *) (&sig + 1))
-       $19 = {gs = 0, __gsh = 0, fs = 0, __fsh = 0, es = 43, __esh = 0, ds = 43,
-         __dsh = 0, edi = 1342179328, esi = 1350378548, ebp = 1342630440,
-         esp = 1342630420, ebx = 1348150624, edx = 1280, ecx = 0, eax = 0,
-         trapno = 14, err = 4, eip = 268480945, cs = 35, __csh = 0, eflags = 66118,
-         esp_at_signal = 1342630420, ss = 43, __ssh = 0, fpstate = 0x0, oldmask = 0,
-         cr2 = 1280}
-
-
-
-  The ip is in handle_mm_fault:
-
-
-       (gdb) p (void *)268480945
-       $20 = (void *) 0x1000b1b1
-       (gdb) i sym $20
-       handle_mm_fault + 57 in section .text
-
-
-
-
-
-  Specifically, it's in pte_alloc:
-
-
-       (gdb) i line *$20
-       Line 124 of "/home/dike/linux/2.3.26/um/include/asm/pgalloc.h"
-          starts at address 0x1000b1b1 <handle_mm_fault+57>
-          and ends at 0x1000b1b7 <handle_mm_fault+63>.
-
-
-
-
-
-  To find where in handle_mm_fault this is, I'll jump forward in the
-  code until I see an address in that procedure:
-
-
-
-       (gdb) i line *0x1000b1c0
-       Line 126 of "/home/dike/linux/2.3.26/um/include/asm/pgalloc.h"
-          starts at address 0x1000b1b7 <handle_mm_fault+63>
-          and ends at 0x1000b1c3 <handle_mm_fault+75>.
-       (gdb) i line *0x1000b1d0
-       Line 131 of "/home/dike/linux/2.3.26/um/include/asm/pgalloc.h"
-          starts at address 0x1000b1d0 <handle_mm_fault+88>
-          and ends at 0x1000b1da <handle_mm_fault+98>.
-       (gdb) i line *0x1000b1e0
-       Line 61 of "/home/dike/linux/2.3.26/um/include/asm/pgalloc.h"
-          starts at address 0x1000b1da <handle_mm_fault+98>
-          and ends at 0x1000b1e1 <handle_mm_fault+105>.
-       (gdb) i line *0x1000b1f0
-       Line 134 of "/home/dike/linux/2.3.26/um/include/asm/pgalloc.h"
-          starts at address 0x1000b1f0 <handle_mm_fault+120>
-          and ends at 0x1000b200 <handle_mm_fault+136>.
-       (gdb) i line *0x1000b200
-       Line 135 of "/home/dike/linux/2.3.26/um/include/asm/pgalloc.h"
-          starts at address 0x1000b200 <handle_mm_fault+136>
-          and ends at 0x1000b208 <handle_mm_fault+144>.
-       (gdb) i line *0x1000b210
-       Line 139 of "/home/dike/linux/2.3.26/um/include/asm/pgalloc.h"
-          starts at address 0x1000b210 <handle_mm_fault+152>
-          and ends at 0x1000b219 <handle_mm_fault+161>.
-       (gdb) i line *0x1000b220
-       Line 1168 of "memory.c" starts at address 0x1000b21e <handle_mm_fault+166>
-          and ends at 0x1000b222 <handle_mm_fault+170>.
-
-
-
-
-
-  Something is apparently wrong with the page tables or vma_structs, so
-  lets go back to frame 11 and have a look at them:
-
-
-
-  #11 0x1006c0aa in segv (address=1342179328, is_write=2) at trap_kern.c:50
-  50        handle_mm_fault(current, vma, address, is_write);
-  (gdb) call pgd_offset_proc(vma->vm_mm, address)
-  $22 = (pgd_t *) 0x80a548c
-
-
-
-
-
-  That's pretty bogus.  Page tables aren't supposed to be in process
-  text or data areas.  Let's see what's in the vma:
-
-
-       (gdb) p *vma
-       $23 = {vm_mm = 0x507d2434, vm_start = 0, vm_end = 134512640,
-         vm_next = 0x80a4f8c, vm_page_prot = {pgprot = 0}, vm_flags = 31200,
-         vm_avl_height = 2058, vm_avl_left = 0x80a8c94, vm_avl_right = 0x80d1000,
-         vm_next_share = 0xaffffdb0, vm_pprev_share = 0xaffffe63,
-         vm_ops = 0xaffffe7a, vm_pgoff = 2952789626, vm_file = 0xafffffec,
-         vm_private_data = 0x62}
-       (gdb) p *vma.vm_mm
-       $24 = {mmap = 0x507d2434, mmap_avl = 0x0, mmap_cache = 0x8048000,
-         pgd = 0x80a4f8c, mm_users = {counter = 0}, mm_count = {counter = 134904288},
-         map_count = 134909076, mmap_sem = {count = {counter = 135073792},
-           sleepers = -1342177872, wait = {lock = <optimized out or zero length>,
-             task_list = {next = 0xaffffe63, prev = 0xaffffe7a},
-             __magic = -1342177670, __creator = -1342177300}, __magic = 98},
-         page_table_lock = {}, context = 138, start_code = 0, end_code = 0,
-         start_data = 0, end_data = 0, start_brk = 0, brk = 0, start_stack = 0,
-         arg_start = 0, arg_end = 0, env_start = 0, env_end = 0, rss = 1350381536,
-         total_vm = 0, locked_vm = 0, def_flags = 0, cpu_vm_mask = 0, swap_cnt = 0,
-         swap_address = 0, segments = 0x0}
-
-
-
-
-
-  This also pretty bogus.  With all of the 0x80xxxxx and 0xaffffxxx
-  addresses, this is looking like a stack was plonked down on top of
-  these structures.  Maybe it's a stack overflow from the next page:
-
-
-
-       (gdb) p vma
-       $25 = (struct vm_area_struct *) 0x507d2434
-
-
-
-
-
-  That's towards the lower quarter of the page, so that would have to
-  have been pretty heavy stack overflow:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-  (gdb) x/100x $25
-  0x507d2434:     0x507d2434      0x00000000      0x08048000      0x080a4f8c
-  0x507d2444:     0x00000000      0x080a79e0      0x080a8c94      0x080d1000
-  0x507d2454:     0xaffffdb0      0xaffffe63      0xaffffe7a      0xaffffe7a
-  0x507d2464:     0xafffffec      0x00000062      0x0000008a      0x00000000
-  0x507d2474:     0x00000000      0x00000000      0x00000000      0x00000000
-  0x507d2484:     0x00000000      0x00000000      0x00000000      0x00000000
-  0x507d2494:     0x00000000      0x00000000      0x507d2fe0      0x00000000
-  0x507d24a4:     0x00000000      0x00000000      0x00000000      0x00000000
-  0x507d24b4:     0x00000000      0x00000000      0x00000000      0x00000000
-  0x507d24c4:     0x00000000      0x00000000      0x00000000      0x00000000
-  0x507d24d4:     0x00000000      0x00000000      0x00000000      0x00000000
-  0x507d24e4:     0x00000000      0x00000000      0x00000000      0x00000000
-  0x507d24f4:     0x00000000      0x00000000      0x00000000      0x00000000
-  0x507d2504:     0x00000000      0x00000000      0x00000000      0x00000000
-  0x507d2514:     0x00000000      0x00000000      0x00000000      0x00000000
-  0x507d2524:     0x00000000      0x00000000      0x00000000      0x00000000
-  0x507d2534:     0x00000000      0x00000000      0x507d25dc      0x00000000
-  0x507d2544:     0x00000000      0x00000000      0x00000000      0x00000000
-  0x507d2554:     0x00000000      0x00000000      0x00000000      0x00000000
-  0x507d2564:     0x00000000      0x00000000      0x00000000      0x00000000
-  0x507d2574:     0x00000000      0x00000000      0x00000000      0x00000000
-  0x507d2584:     0x00000000      0x00000000      0x00000000      0x00000000
-  0x507d2594:     0x00000000      0x00000000      0x00000000      0x00000000
-  0x507d25a4:     0x00000000      0x00000000      0x00000000      0x00000000
-  0x507d25b4:     0x00000000      0x00000000      0x00000000      0x00000000
-
-
-
-
-
-  It's not stack overflow.  The only "stack-like" piece of this data is
-  the vma_struct itself.
-
-
-  At this point, I don't see any avenues to pursue, so I just have to
-  admit that I have no idea what's going on.  What I will do, though, is
-  stick a trap on the segfault handler which will stop if it sees any
-  writes to the idle thread's stack.  That was the thing that happened
-  first, and it may be that if I can catch it immediately, what's going
-  on will be somewhat clearer.
-
-
-  1122..22..  EEppiissooddee 22:: TThhee ccaassee ooff tthhee hhuunngg ffsscckk
-
-  After setting a trap in the SEGV handler for accesses to the signal
-  thread's stack, I reran the kernel.
-
-
-  fsck hung again, this time by hitting the trap:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-  Setting hostname uml                            [ OK ]
-  Checking root filesystem
-  /dev/fhd0 contains a file system with errors, check forced.
-  Error reading block 86894 (Attempt to read block from filesystem resulted in short read) while reading indirect blocks of inode 19780.
-
-  /dev/fhd0: UNEXPECTED INCONSISTENCY; RUN fsck MANUALLY.
-          (i.e., without -a or -p options)
-  [ FAILED ]
-
-  *** An error occurred during the file system check.
-  *** Dropping you to a shell; the system will reboot
-  *** when you leave the shell.
-  Give root password for maintenance
-  (or type Control-D for normal startup):
-
-  [root@uml /root]# fsck -y /dev/fhd0
-  fsck -y /dev/fhd0
-  Parallelizing fsck version 1.14 (9-Jan-1999)
-  e2fsck 1.14, 9-Jan-1999 for EXT2 FS 0.5b, 95/08/09
-  /dev/fhd0 contains a file system with errors, check forced.
-  Pass 1: Checking inodes, blocks, and sizes
-  Error reading block 86894 (Attempt to read block from filesystem resulted in short read) while reading indirect blocks of inode 19780.  Ignore error? yes
-
-  Pass 2: Checking directory structure
-  Error reading block 49405 (Attempt to read block from filesystem resulted in short read).  Ignore error? yes
-
-  Directory inode 11858, block 0, offset 0: directory corrupted
-  Salvage? yes
-
-  Missing '.' in directory inode 11858.
-  Fix? yes
-
-  Missing '..' in directory inode 11858.
-  Fix? yes
-
-  Untested (4127) [100fe44c]: trap_kern.c line 31
-
-
-
-
-
-  I need to get the signal thread to detach from pid 4127 so that I can
-  attach to it with gdb.  This is done by sending it a SIGUSR1, which is
-  caught by the signal thread, which detaches the process:
-
-
-       kill -USR1 4127
-
-
-
-
-
-  Now I can run gdb on it:
-
-
-
-
-
-
-
-
-
-
-
-
-
-  ~/linux/2.3.26/um 1034: gdb linux
-  GNU gdb 4.17.0.11 with Linux support
-  Copyright 1998 Free Software Foundation, Inc.
-  GDB is free software, covered by the GNU General Public License, and you are
-  welcome to change it and/or distribute copies of it under certain conditions.
-  Type "show copying" to see the conditions.
-  There is absolutely no warranty for GDB.  Type "show warranty" for details.
-  This GDB was configured as "i386-redhat-linux"...
-  (gdb) att 4127
-  Attaching to program `/home/dike/linux/2.3.26/um/linux', Pid 4127
-  0x10075891 in __libc_nanosleep ()
-
-
-
-
-
-  The backtrace shows that it was in a write and that the fault address
-  (address in frame 3) is 0x50000800, which is right in the middle of
-  the signal thread's stack page:
-
-
-       (gdb) bt
-       #0  0x10075891 in __libc_nanosleep ()
-       #1  0x1007584d in __sleep (seconds=1000000)
-           at ../sysdeps/unix/sysv/linux/sleep.c:78
-       #2  0x1006ce9a in stop () at user_util.c:191
-       #3  0x1006bf88 in segv (address=1342179328, is_write=2) at trap_kern.c:31
-       #4  0x1006c628 in segv_handler (sc=0x5006eaf8) at trap_user.c:174
-       #5  0x1006c63c in kern_segv_handler (sig=11) at trap_user.c:182
-       #6  <signal handler called>
-       #7  0xc0fd in ?? ()
-       #8  0x10016647 in sys_write (fd=3, buf=0x80b8800 "R.", count=1024)
-           at read_write.c:159
-       #9  0x1006d603 in execute_syscall (syscall=4, args=0x5006ef08)
-           at syscall_kern.c:254
-       #10 0x1006af87 in really_do_syscall (sig=12) at syscall_user.c:35
-       #11 <signal handler called>
-       #12 0x400dc8b0 in ?? ()
-       #13 <signal handler called>
-       #14 0x400dc8b0 in ?? ()
-       #15 0x80545fd in ?? ()
-       #16 0x804daae in ?? ()
-       #17 0x8054334 in ?? ()
-       #18 0x804d23e in ?? ()
-       #19 0x8049632 in ?? ()
-       #20 0x80491d2 in ?? ()
-       #21 0x80596b5 in ?? ()
-       (gdb) p (void *)1342179328
-       $3 = (void *) 0x50000800
-
-
-
-
-
-  Going up the stack to the segv_handler frame and looking at where in
-  the code the access happened shows that it happened near line 110 of
-  block_dev.c:
-
-
-
-
-
-
-
-
-
-  (gdb) up
-  #1  0x1007584d in __sleep (seconds=1000000)
-      at ../sysdeps/unix/sysv/linux/sleep.c:78
-  ../sysdeps/unix/sysv/linux/sleep.c:78: No such file or directory.
-  (gdb)
-  #2  0x1006ce9a in stop () at user_util.c:191
-  191       while(1) sleep(1000000);
-  (gdb)
-  #3  0x1006bf88 in segv (address=1342179328, is_write=2) at trap_kern.c:31
-  31          KERN_UNTESTED();
-  (gdb)
-  #4  0x1006c628 in segv_handler (sc=0x5006eaf8) at trap_user.c:174
-  174       segv(sc->cr2, sc->err & 2);
-  (gdb) p *sc
-  $1 = {gs = 0, __gsh = 0, fs = 0, __fsh = 0, es = 43, __esh = 0, ds = 43,
-    __dsh = 0, edi = 1342179328, esi = 134973440, ebp = 1342631484,
-    esp = 1342630864, ebx = 256, edx = 0, ecx = 256, eax = 1024, trapno = 14,
-    err = 6, eip = 268550834, cs = 35, __csh = 0, eflags = 66070,
-    esp_at_signal = 1342630864, ss = 43, __ssh = 0, fpstate = 0x0, oldmask = 0,
-    cr2 = 1342179328}
-  (gdb) p (void *)268550834
-  $2 = (void *) 0x1001c2b2
-  (gdb) i sym $2
-  block_write + 1090 in section .text
-  (gdb) i line *$2
-  Line 209 of "/home/dike/linux/2.3.26/um/include/asm/arch/string.h"
-     starts at address 0x1001c2a1 <block_write+1073>
-     and ends at 0x1001c2bf <block_write+1103>.
-  (gdb) i line *0x1001c2c0
-  Line 110 of "block_dev.c" starts at address 0x1001c2bf <block_write+1103>
-     and ends at 0x1001c2e3 <block_write+1139>.
-
-
-
-
-
-  Looking at the source shows that the fault happened during a call to
-  copy_to_user to copy the data into the kernel:
-
-
-       107             count -= chars;
-       108             copy_from_user(p,buf,chars);
-       109             p += chars;
-       110             buf += chars;
-
-
-
-
-
-  p is the pointer which must contain 0x50000800, since buf contains
-  0x80b8800 (frame 8 above).  It is defined as:
-
-
-                       p = offset + bh->b_data;
-
-
-
-
-
-  I need to figure out what bh is, and it just so happens that bh is
-  passed as an argument to mark_buffer_uptodate and mark_buffer_dirty a
-  few lines later, so I do a little disassembly:
-
-
-
-
-  (gdb) disas 0x1001c2bf 0x1001c2e0
-  Dump of assembler code from 0x1001c2bf to 0x1001c2d0:
-  0x1001c2bf <block_write+1103>:  addl   %eax,0xc(%ebp)
-  0x1001c2c2 <block_write+1106>:  movl   0xfffffdd4(%ebp),%edx
-  0x1001c2c8 <block_write+1112>:  btsl   $0x0,0x18(%edx)
-  0x1001c2cd <block_write+1117>:  btsl   $0x1,0x18(%edx)
-  0x1001c2d2 <block_write+1122>:  sbbl   %ecx,%ecx
-  0x1001c2d4 <block_write+1124>:  testl  %ecx,%ecx
-  0x1001c2d6 <block_write+1126>:  jne    0x1001c2e3 <block_write+1139>
-  0x1001c2d8 <block_write+1128>:  pushl  $0x0
-  0x1001c2da <block_write+1130>:  pushl  %edx
-  0x1001c2db <block_write+1131>:  call   0x1001819c <__mark_buffer_dirty>
-  End of assembler dump.
-
-
-
-
-
-  At that point, bh is in %edx (address 0x1001c2da), which is calculated
-  at 0x1001c2c2 as %ebp + 0xfffffdd4, so I figure exactly what that is,
-  taking %ebp from the sigcontext_struct above:
-
-
-       (gdb) p (void *)1342631484
-       $5 = (void *) 0x5006ee3c
-       (gdb) p 0x5006ee3c+0xfffffdd4
-       $6 = 1342630928
-       (gdb) p (void *)$6
-       $7 = (void *) 0x5006ec10
-       (gdb) p *((void **)$7)
-       $8 = (void *) 0x50100200
-
-
-
-
-
-  Now, I look at the structure to see what's in it, and particularly,
-  what its b_data field contains:
-
-
-       (gdb) p *((struct buffer_head *)0x50100200)
-       $13 = {b_next = 0x50289380, b_blocknr = 49405, b_size = 1024, b_list = 0,
-         b_dev = 15872, b_count = {counter = 1}, b_rdev = 15872, b_state = 24,
-         b_flushtime = 0, b_next_free = 0x501001a0, b_prev_free = 0x50100260,
-         b_this_page = 0x501001a0, b_reqnext = 0x0, b_pprev = 0x507fcf58,
-         b_data = 0x50000800 "", b_page = 0x50004000,
-         b_end_io = 0x10017f60 <end_buffer_io_sync>, b_dev_id = 0x0,
-         b_rsector = 98810, b_wait = {lock = <optimized out or zero length>,
-           task_list = {next = 0x50100248, prev = 0x50100248}, __magic = 1343226448,
-           __creator = 0}, b_kiobuf = 0x0}
-
-
-
-
-
-  The b_data field is indeed 0x50000800, so the question becomes how
-  that happened.  The rest of the structure looks fine, so this probably
-  is not a case of data corruption.  It happened on purpose somehow.
-
-
-  The b_page field is a pointer to the page_struct representing the
-  0x50000000 page.  Looking at it shows the kernel's idea of the state
-  of that page:
-
-
-
-  (gdb) p *$13.b_page
-  $17 = {list = {next = 0x50004a5c, prev = 0x100c5174}, mapping = 0x0,
-    index = 0, next_hash = 0x0, count = {counter = 1}, flags = 132, lru = {
-      next = 0x50008460, prev = 0x50019350}, wait = {
-      lock = <optimized out or zero length>, task_list = {next = 0x50004024,
-        prev = 0x50004024}, __magic = 1342193708, __creator = 0},
-    pprev_hash = 0x0, buffers = 0x501002c0, virtual = 1342177280,
-    zone = 0x100c5160}
-
-
-
-
-
-  Some sanity-checking: the virtual field shows the "virtual" address of
-  this page, which in this kernel is the same as its "physical" address,
-  and the page_struct itself should be mem_map[0], since it represents
-  the first page of memory:
-
-
-
-       (gdb) p (void *)1342177280
-       $18 = (void *) 0x50000000
-       (gdb) p mem_map
-       $19 = (mem_map_t *) 0x50004000
-
-
-
-
-
-  These check out fine.
-
-
-  Now to check out the page_struct itself.  In particular, the flags
-  field shows whether the page is considered free or not:
-
-
-       (gdb) p (void *)132
-       $21 = (void *) 0x84
-
-
-
-
-
-  The "reserved" bit is the high bit, which is definitely not set, so
-  the kernel considers the signal stack page to be free and available to
-  be used.
-
-
-  At this point, I jump to conclusions and start looking at my early
-  boot code, because that's where that page is supposed to be reserved.
-
-
-  In my setup_arch procedure, I have the following code which looks just
-  fine:
-
-
-
-       bootmap_size = init_bootmem(start_pfn, end_pfn - start_pfn);
-       free_bootmem(__pa(low_physmem) + bootmap_size, high_physmem - low_physmem);
-
-
-
-
-
-  Two stack pages have already been allocated, and low_physmem points to
-  the third page, which is the beginning of free memory.
-  The init_bootmem call declares the entire memory to the boot memory
-  manager, which marks it all reserved.  The free_bootmem call frees up
-  all of it, except for the first two pages.  This looks correct to me.
-
-
-  So, I decide to see init_bootmem run and make sure that it is marking
-  those first two pages as reserved.  I never get that far.
-
-
-  Stepping into init_bootmem, and looking at bootmem_map before looking
-  at what it contains shows the following:
-
-
-
-       (gdb) p bootmem_map
-       $3 = (void *) 0x50000000
-
-
-
-
-
-  Aha!  The light dawns.  That first page is doing double duty as a
-  stack and as the boot memory map.  The last thing that the boot memory
-  manager does is to free the pages used by its memory map, so this page
-  is getting freed even its marked as reserved.
-
-
-  The fix was to initialize the boot memory manager before allocating
-  those two stack pages, and then allocate them through the boot memory
-  manager.  After doing this, and fixing a couple of subsequent buglets,
-  the stack corruption problem disappeared.
-
-
-
-
-
-  1133..  WWhhaatt ttoo ddoo wwhheenn UUMMLL ddooeessnn''tt wwoorrkk
-
-
-
-
-  1133..11..  SSttrraannggee ccoommppiillaattiioonn eerrrroorrss wwhheenn yyoouu bbuuiilldd ffrroomm ssoouurrccee
-
-  As of test11, it is necessary to have "ARCH=um" in the environment or
-  on the make command line for all steps in building UML, including
-  clean, distclean, or mrproper, config, menuconfig, or xconfig, dep,
-  and linux.  If you forget for any of them, the i386 build seems to
-  contaminate the UML build.  If this happens, start from scratch with
-
-
-       host%
-       make mrproper ARCH=um
-
-
-
-
-  and repeat the build process with ARCH=um on all the steps.
-
-
-  See ``Compiling the kernel and modules''  for more details.
-
-
-  Another cause of strange compilation errors is building UML in
-  /usr/src/linux.  If you do this, the first thing you need to do is
-  clean up the mess you made.  The /usr/src/linux/asm link will now
-  point to /usr/src/linux/asm-um.  Make it point back to
-  /usr/src/linux/asm-i386.  Then, move your UML pool someplace else and
-  build it there.  Also see below, where a more specific set of symptoms
-  is described.
-
-
-
-  1133..33..  AA vvaarriieettyy ooff ppaanniiccss aanndd hhaannggss wwiitthh //ttmmpp oonn aa rreeiisseerrffss  ffiilleessyyss--
-  tteemm
-
-  I saw this on reiserfs 3.5.21 and it seems to be fixed in 3.5.27.
-  Panics preceded by
-
-
-       Detaching pid nnnn
-
-
-
-  are diagnostic of this problem.  This is a reiserfs bug which causes a
-  thread to occasionally read stale data from a mmapped page shared with
-  another thread.  The fix is to upgrade the filesystem or to have /tmp
-  be an ext2 filesystem.
-
-
-
-  1133..44..  TThhee ccoommppiillee ffaaiillss wwiitthh eerrrroorrss aabboouutt ccoonnfflliiccttiinngg ttyyppeess ffoorr
-  ''ooppeenn'',, ''dduupp'',, aanndd ''wwaaiittppiidd''
-
-  This happens when you build in /usr/src/linux.  The UML build makes
-  the include/asm link point to include/asm-um.  /usr/include/asm points
-  to /usr/src/linux/include/asm, so when that link gets moved, files
-  which need to include the asm-i386 versions of headers get the
-  incompatible asm-um versions.  The fix is to move the include/asm link
-  back to include/asm-i386 and to do UML builds someplace else.
-
-
-
-  1133..55..  UUMMLL ddooeessnn''tt wwoorrkk wwhheenn //ttmmpp iiss aann NNFFSS ffiilleessyysstteemm
-
-  This seems to be a similar situation with the ReiserFS problem above.
-  Some versions of NFS seems not to handle mmap correctly, which UML
-  depends on.  The workaround is have /tmp be a non-NFS directory.
-
-
-  1133..66..  UUMMLL hhaannggss oonn bboooott wwhheenn ccoommppiilleedd wwiitthh ggpprrooff ssuuppppoorrtt
-
-  If you build UML with gprof support and, early in the boot, it does
-  this
-
-
-       kernel BUG at page_alloc.c:100!
-
-
-
-
-  you have a buggy gcc.  You can work around the problem by removing
-  UM_FASTCALL from CFLAGS in arch/um/Makefile-i386.  This will open up
-  another bug, but that one is fairly hard to reproduce.
-
-
-
-  1133..77..  ssyyssllooggdd ddiieess wwiitthh aa SSIIGGTTEERRMM oonn ssttaarrttuupp
-
-  The exact boot error depends on the distribution that you're booting,
-  but Debian produces this:
-
-
-       /etc/rc2.d/S10sysklogd: line 49:    93 Terminated
-       start-stop-daemon --start --quiet --exec /sbin/syslogd -- $SYSLOGD
-
-
-
-
-  This is a syslogd bug.  There's a race between a parent process
-  installing a signal handler and its child sending the signal.  See
-  this uml-devel post <http://www.geocrawler.com/lists/3/Source-
-  Forge/709/0/6612801>  for the details.
-
-
-
-  1133..88..  TTUUNN//TTAAPP nneettwwoorrkkiinngg ddooeessnn''tt wwoorrkk oonn aa 22..44 hhoosstt
-
-  There are a couple of problems which were
-  <http://www.geocrawler.com/lists/3/SourceForge/597/0/> name="pointed
-  out">  by Tim Robinson <timro at trkr dot net>
-
-  +o  It doesn't work on hosts running 2.4.7 (or thereabouts) or earlier.
-     The fix is to upgrade to something more recent and then read the
-     next item.
-
-  +o  If you see
-
-
-       File descriptor in bad state
-
-
-
-  when you bring up the device inside UML, you have a header mismatch
-  between the original kernel and the upgraded one.  Make /usr/src/linux
-  point at the new headers.  This will only be a problem if you build
-  uml_net yourself.
-
-
-
-  1133..99..  YYoouu ccaann nneettwwoorrkk ttoo tthhee hhoosstt bbuutt nnoott ttoo ootthheerr mmaacchhiinneess oonn tthhee
-  nneett
-
-  If you can connect to the host, and the host can connect to UML, but
-  you cannot connect to any other machines, then you may need to enable
-  IP Masquerading on the host.  Usually this is only experienced when
-  using private IP addresses (192.168.x.x or 10.x.x.x) for host/UML
-  networking, rather than the public address space that your host is
-  connected to.  UML does not enable IP Masquerading, so you will need
-  to create a static rule to enable it:
-
-
-       host%
-       iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
-
-
-
-
-  Replace eth0 with the interface that you use to talk to the rest of
-  the world.
-
-
-  Documentation on IP Masquerading, and SNAT, can be found at
-  www.netfilter.org  <http://www.netfilter.org> .
-
-
-  If you can reach the local net, but not the outside Internet, then
-  that is usually a routing problem.  The UML needs a default route:
-
-
-       UML#
-       route add default gw gateway IP
-
-
-
-
-  The gateway IP can be any machine on the local net that knows how to
-  reach the outside world.  Usually, this is the host or the local net-
-  work's gateway.
-
-
-  Occasionally, we hear from someone who can reach some machines, but
-  not others on the same net, or who can reach some ports on other
-  machines, but not others.  These are usually caused by strange
-  firewalling somewhere between the UML and the other box.  You track
-  this down by running tcpdump on every interface the packets travel
-  over and see where they disappear.  When you find a machine that takes
-  the packets in, but does not send them onward, that's the culprit.
-
-
-
-  1133..1100..  II hhaavvee nnoo rroooott aanndd II wwaanntt ttoo ssccrreeaamm
-
-  Thanks to Birgit Wahlich for telling me about this strange one.  It
-  turns out that there's a limit of six environment variables on the
-  kernel command line.  When that limit is reached or exceeded, argument
-  processing stops, which means that the 'root=' argument that UML
-  usually adds is not seen.  So, the filesystem has no idea what the
-  root device is, so it panics.
-
-
-  The fix is to put less stuff on the command line.  Glomming all your
-  setup variables into one is probably the best way to go.
-
-
-
-  1133..1111..  UUMMLL bbuuiilldd ccoonnfflliicctt bbeettwweeeenn ppttrraaccee..hh aanndd uuccoonntteexxtt..hh
-
-  On some older systems, /usr/include/asm/ptrace.h and
-  /usr/include/sys/ucontext.h define the same names.  So, when they're
-  included together, the defines from one completely mess up the parsing
-  of the other, producing errors like:
-       /usr/include/sys/ucontext.h:47: parse error before
-       `10'
-
-
-
-
-  plus a pile of warnings.
-
-
-  This is a libc botch, which has since been fixed, and I don't see any
-  way around it besides upgrading.
-
-
-
-  1133..1122..  TThhee UUMMLL BBooggooMMiippss iiss eexxaaccttllyy hhaallff tthhee hhoosstt''ss BBooggooMMiippss
-
-  On i386 kernels, there are two ways of running the loop that is used
-  to calculate the BogoMips rating, using the TSC if it's there or using
-  a one-instruction loop.  The TSC produces twice the BogoMips as the
-  loop.  UML uses the loop, since it has nothing resembling a TSC, and
-  will get almost exactly the same BogoMips as a host using the loop.
-  However, on a host with a TSC, its BogoMips will be double the loop
-  BogoMips, and therefore double the UML BogoMips.
-
-
-
-  1133..1133..  WWhheenn yyoouu rruunn UUMMLL,, iitt iimmmmeeddiiaatteellyy sseeggffaauullttss
-
-  If the host is configured with the 2G/2G address space split, that's
-  why.  See ``UML on 2G/2G hosts''  for the details on getting UML to
-  run on your host.
-
-
-
-  1133..1144..  xxtteerrmmss aappppeeaarr,, tthheenn iimmmmeeddiiaatteellyy ddiissaappppeeaarr
-
-  If you're running an up to date kernel with an old release of
-  uml_utilities, the port-helper program will not work properly, so
-  xterms will exit straight after they appear. The solution is to
-  upgrade to the latest release of uml_utilities.  Usually this problem
-  occurs when you have installed a packaged release of UML then compiled
-  your own development kernel without upgrading the uml_utilities from
-  the source distribution.
-
-
-
-  1133..1155..  AAnnyy ootthheerr ppaanniicc,, hhaanngg,, oorr ssttrraannggee bbeehhaavviioorr
-
-  If you're seeing truly strange behavior, such as hangs or panics that
-  happen in random places, or you try running the debugger to see what's
-  happening and it acts strangely, then it could be a problem in the
-  host kernel.  If you're not running a stock Linus or -ac kernel, then
-  try that.  An early version of the preemption patch and a 2.4.10 SuSE
-  kernel have caused very strange problems in UML.
-
-
-  Otherwise, let me know about it.  Send a message to one of the UML
-  mailing lists - either the developer list - user-mode-linux-devel at
-  lists dot sourceforge dot net (subscription info) or the user list -
-  user-mode-linux-user at lists dot sourceforge do net (subscription
-  info), whichever you prefer.  Don't assume that everyone knows about
-  it and that a fix is imminent.
-
-
-  If you want to be super-helpful, read ``Diagnosing Problems'' and
-  follow the instructions contained therein.
-  1144..  DDiiaaggnnoossiinngg PPrroobblleemmss
-
-
-  If you get UML to crash, hang, or otherwise misbehave, you should
-  report this on one of the project mailing lists, either the developer
-  list - user-mode-linux-devel at lists dot sourceforge dot net
-  (subscription info) or the user list - user-mode-linux-user at lists
-  dot sourceforge dot net (subscription info).  When you do, it is
-  likely that I will want more information.  So, it would be helpful to
-  read the stuff below, do whatever is applicable in your case, and
-  report the results to the list.
-
-
-  For any diagnosis, you're going to need to build a debugging kernel.
-  The binaries from this site aren't debuggable.  If you haven't done
-  this before, read about ``Compiling the kernel and modules''  and
-  ``Kernel debugging''  UML first.
-
-
-  1144..11..  CCaassee 11 :: NNoorrmmaall kkeerrnneell ppaanniiccss
-
-  The most common case is for a normal thread to panic.  To debug this,
-  you will need to run it under the debugger (add 'debug' to the command
-  line).  An xterm will start up with gdb running inside it.  Continue
-  it when it stops in start_kernel and make it crash.  Now ^C gdb and
-
-
-  If the panic was a "Kernel mode fault", then there will be a segv
-  frame on the stack and I'm going to want some more information.  The
-  stack might look something like this:
-
-
-       (UML gdb)  backtrace
-       #0  0x1009bf76 in __sigprocmask (how=1, set=0x5f347940, oset=0x0)
-           at ../sysdeps/unix/sysv/linux/sigprocmask.c:49
-       #1  0x10091411 in change_sig (signal=10, on=1) at process.c:218
-       #2  0x10094785 in timer_handler (sig=26) at time_kern.c:32
-       #3  0x1009bf38 in __restore ()
-           at ../sysdeps/unix/sysv/linux/i386/sigaction.c:125
-       #4  0x1009534c in segv (address=8, ip=268849158, is_write=2, is_user=0)
-           at trap_kern.c:66
-       #5  0x10095c04 in segv_handler (sig=11) at trap_user.c:285
-       #6  0x1009bf38 in __restore ()
-
-
-
-
-  I'm going to want to see the symbol and line information for the value
-  of ip in the segv frame.  In this case, you would do the following:
-
-
-       (UML gdb)  i sym 268849158
-
-
-
-
-  and
-
-
-       (UML gdb)  i line *268849158
-
-
-
-
-  The reason for this is the __restore frame right above the segv_han-
-  dler frame is hiding the frame that actually segfaulted.  So, I have
-  to get that information from the faulting ip.
-
-
-  1144..22..  CCaassee 22 :: TTrraacciinngg tthhrreeaadd ppaanniiccss
-
-  The less common and more painful case is when the tracing thread
-  panics.  In this case, the kernel debugger will be useless because it
-  needs a healthy tracing thread in order to work.  The first thing to
-  do is get a backtrace from the tracing thread.  This is done by
-  figuring out what its pid is, firing up gdb, and attaching it to that
-  pid.  You can figure out the tracing thread pid by looking at the
-  first line of the console output, which will look like this:
-
-
-       tracing thread pid = 15851
-
-
-
-
-  or by running ps on the host and finding the line that looks like
-  this:
-
-
-       jdike 15851 4.5 0.4 132568 1104 pts/0 S 21:34 0:05 ./linux [(tracing thread)]
-
-
-
-
-  If the panic was 'segfault in signals', then follow the instructions
-  above for collecting information about the location of the seg fault.
-
-
-  If the tracing thread flaked out all by itself, then send that
-  backtrace in and wait for our crack debugging team to fix the problem.
-
-
-  1144..33..  CCaassee 33 :: TTrraacciinngg tthhrreeaadd ppaanniiccss ccaauusseedd bbyy ootthheerr tthhrreeaaddss
-
-  However, there are cases where the misbehavior of another thread
-  caused the problem.  The most common panic of this type is:
-
-
-       wait_for_stop failed to wait for  <pid>  to stop with  <signal number>
-
-
-
-
-  In this case, you'll need to get a backtrace from the process men-
-  tioned in the panic, which is complicated by the fact that the kernel
-  debugger is defunct and without some fancy footwork, another gdb can't
-  attach to it.  So, this is how the fancy footwork goes:
-
-  In a shell:
-
-
-       host% kill -STOP pid
-
-
-
-
-  Run gdb on the tracing thread as described in case 2 and do:
-
-
-       (host gdb)  call detach(pid)
-
-
-  If you get a segfault, do it again.  It always works the second time.
-
-  Detach from the tracing thread and attach to that other thread:
-
-
-       (host gdb)  detach
-
-
-
-
-
-
-       (host gdb)  attach pid
-
-
-
-
-  If gdb hangs when attaching to that process, go back to a shell and
-  do:
-
-
-       host%
-       kill -CONT pid
-
-
-
-
-  And then get the backtrace:
-
-
-       (host gdb)  backtrace
-
-
-
-
-
-  1144..44..  CCaassee 44 :: HHaannggss
-
-  Hangs seem to be fairly rare, but they sometimes happen.  When a hang
-  happens, we need a backtrace from the offending process.  Run the
-  kernel debugger as described in case 1 and get a backtrace.  If the
-  current process is not the idle thread, then send in the backtrace.
-  You can tell that it's the idle thread if the stack looks like this:
-
-
-       #0  0x100b1401 in __libc_nanosleep ()
-       #1  0x100a2885 in idle_sleep (secs=10) at time.c:122
-       #2  0x100a546f in do_idle () at process_kern.c:445
-       #3  0x100a5508 in cpu_idle () at process_kern.c:471
-       #4  0x100ec18f in start_kernel () at init/main.c:592
-       #5  0x100a3e10 in start_kernel_proc (unused=0x0) at um_arch.c:71
-       #6  0x100a383f in signal_tramp (arg=0x100a3dd8) at trap_user.c:50
-
-
-
-
-  If this is the case, then some other process is at fault, and went to
-  sleep when it shouldn't have.  Run ps on the host and figure out which
-  process should not have gone to sleep and stayed asleep.  Then attach
-  to it with gdb and get a backtrace as described in case 3.
-
-
-
-
-
-
-  1155..  TThhaannkkss
-
-
-  A number of people have helped this project in various ways, and this
-  page gives recognition where recognition is due.
-
-
-  If you're listed here and you would prefer a real link on your name,
-  or no link at all, instead of the despammed email address pseudo-link,
-  let me know.
-
-
-  If you're not listed here and you think maybe you should be, please
-  let me know that as well.  I try to get everyone, but sometimes my
-  bookkeeping lapses and I forget about contributions.
-
-
-  1155..11..  CCooddee aanndd DDooccuummeennttaattiioonn
-
-  Rusty Russell <rusty at linuxcare.com.au>  -
-
-  +o  wrote the  HOWTO <http://user-mode-
-     linux.sourceforge.net/UserModeLinux-HOWTO.html>
-
-  +o  prodded me into making this project official and putting it on
-     SourceForge
-
-  +o  came up with the way cool UML logo <http://user-mode-
-     linux.sourceforge.net/uml-small.png>
-
-  +o  redid the config process
-
-
-  Peter Moulder <reiter at netspace.net.au>  - Fixed my config and build
-  processes, and added some useful code to the block driver
-
-
-  Bill Stearns <wstearns at pobox.com>  -
-
-  +o  HOWTO updates
-
-  +o  lots of bug reports
-
-  +o  lots of testing
-
-  +o  dedicated a box (uml.ists.dartmouth.edu) to support UML development
-
-  +o  wrote the mkrootfs script, which allows bootable filesystems of
-     RPM-based distributions to be cranked out
-
-  +o  cranked out a large number of filesystems with said script
-
-
-  Jim Leu <jleu at mindspring.com>  - Wrote the virtual ethernet driver
-  and associated usermode tools
-
-  Lars Brinkhoff <http://lars.nocrew.org/>  - Contributed the ptrace
-  proxy from his own  project <http://a386.nocrew.org/> to allow easier
-  kernel debugging
-
-
-  Andrea Arcangeli <andrea at suse.de>  - Redid some of the early boot
-  code so that it would work on machines with Large File Support
-
-
-  Chris Emerson <http://www.chiark.greenend.org.uk/~cemerson/>  - Did
-  the first UML port to Linux/ppc
-
-
-  Harald Welte <laforge at gnumonks.org>  - Wrote the multicast
-  transport for the network driver
-
-
-  Jorgen Cederlof - Added special file support to hostfs
-
-
-  Greg Lonnon  <glonnon at ridgerun dot com>  - Changed the ubd driver
-  to allow it to layer a COW file on a shared read-only filesystem and
-  wrote the iomem emulation support
-
-
-  Henrik Nordstrom <http://hem.passagen.se/hno/>  - Provided a variety
-  of patches, fixes, and clues
-
-
-  Lennert Buytenhek - Contributed various patches, a rewrite of the
-  network driver, the first implementation of the mconsole driver, and
-  did the bulk of the work needed to get SMP working again.
-
-
-  Yon Uriarte - Fixed the TUN/TAP network backend while I slept.
-
-
-  Adam Heath - Made a bunch of nice cleanups to the initialization code,
-  plus various other small patches.
-
-
-  Matt Zimmerman - Matt volunteered to be the UML Debian maintainer and
-  is doing a real nice job of it.  He also noticed and fixed a number of
-  actually and potentially exploitable security holes in uml_net.  Plus
-  the occasional patch.  I like patches.
-
-
-  James McMechan - James seems to have taken over maintenance of the ubd
-  driver and is doing a nice job of it.
-
-
-  Chandan Kudige - wrote the umlgdb script which automates the reloading
-  of module symbols.
-
-
-  Steve Schmidtke - wrote the UML slirp transport and hostaudio drivers,
-  enabling UML processes to access audio devices on the host. He also
-  submitted patches for the slip transport and lots of other things.
-
-
-  David Coulson <http://davidcoulson.net>  -
-
-  +o  Set up the usermodelinux.org <http://usermodelinux.org>  site,
-     which is a great way of keeping the UML user community on top of
-     UML goings-on.
-
-  +o  Site documentation and updates
-
-  +o  Nifty little UML management daemon  UMLd
-     <http://uml.openconsultancy.com/umld/>
-
-  +o  Lots of testing and bug reports
-
-
-
-
-  1155..22..  FFlluusshhiinngg oouutt bbuuggss
-
-
-
-  +o  Yuri Pudgorodsky
-
-  +o  Gerald Britton
-
-  +o  Ian Wehrman
-
-  +o  Gord Lamb
-
-  +o  Eugene Koontz
-
-  +o  John H. Hartman
-
-  +o  Anders Karlsson
-
-  +o  Daniel Phillips
-
-  +o  John Fremlin
-
-  +o  Rainer Burgstaller
-
-  +o  James Stevenson
-
-  +o  Matt Clay
-
-  +o  Cliff Jefferies
-
-  +o  Geoff Hoff
-
-  +o  Lennert Buytenhek
-
-  +o  Al Viro
-
-  +o  Frank Klingenhoefer
-
-  +o  Livio Baldini Soares
-
-  +o  Jon Burgess
-
-  +o  Petru Paler
-
-  +o  Paul
-
-  +o  Chris Reahard
-
-  +o  Sverker Nilsson
-
-  +o  Gong Su
-
-  +o  johan verrept
-
-  +o  Bjorn Eriksson
-
-  +o  Lorenzo Allegrucci
-
-  +o  Muli Ben-Yehuda
-
-  +o  David Mansfield
-
-  +o  Howard Goff
-
-  +o  Mike Anderson
-
-  +o  John Byrne
-
-  +o  Sapan J. Batia
-
-  +o  Iris Huang
-
-  +o  Jan Hudec
-
-  +o  Voluspa
-
-
-
-
-  1155..33..  BBuugglleettss aanndd cclleeaann--uuppss
-
-
-
-  +o  Dave Zarzycki
-
-  +o  Adam Lazur
-
-  +o  Boria Feigin
-
-  +o  Brian J. Murrell
-
-  +o  JS
-
-  +o  Roman Zippel
-
-  +o  Wil Cooley
-
-  +o  Ayelet Shemesh
-
-  +o  Will Dyson
-
-  +o  Sverker Nilsson
-
-  +o  dvorak
-
-  +o  v.naga srinivas
-
-  +o  Shlomi Fish
-
-  +o  Roger Binns
-
-  +o  johan verrept
-
-  +o  MrChuoi
-
-  +o  Peter Cleve
-
-  +o  Vincent Guffens
-
-  +o  Nathan Scott
-
-  +o  Patrick Caulfield
-
-  +o  jbearce
-
-  +o  Catalin Marinas
-
-  +o  Shane Spencer
-
-  +o  Zou Min
-
-
-  +o  Ryan Boder
-
-  +o  Lorenzo Colitti
-
-  +o  Gwendal Grignou
-
-  +o  Andre' Breiler
-
-  +o  Tsutomu Yasuda
-
-
-
-  1155..44..  CCaassee SSttuuddiieess
-
-
-  +o  Jon Wright
-
-  +o  William McEwan
-
-  +o  Michael Richardson
-
-
-
-  1155..55..  OOtthheerr ccoonnttrriibbuuttiioonnss
-
-
-  Bill Carr <Bill.Carr at compaq.com>  made the Red Hat mkrootfs script
-  work with RH 6.2.
-
-  Michael Jennings <mikejen at hevanet.com>  sent in some material which
-  is now gracing the top of the  index  page <http://user-mode-
-  linux.sourceforge.net/>  of this site.
-
-  SGI <http://www.sgi.com>  (and more specifically Ralf Baechle <ralf at
-  uni-koblenz.de> ) gave me an account on oss.sgi.com
-  <http://www.oss.sgi.com> .  The bandwidth there made it possible to
-  produce most of the filesystems available on the project download
-  page.
-
-  Laurent Bonnaud <Laurent.Bonnaud at inpg.fr>  took the old grotty
-  Debian filesystem that I've been distributing and updated it to 2.2.
-  It is now available by itself here.
-
-  Rik van Riel gave me some ftp space on ftp.nl.linux.org so I can make
-  releases even when Sourceforge is broken.
-
-  Rodrigo de Castro looked at my broken pte code and told me what was
-  wrong with it, letting me fix a long-standing (several weeks) and
-  serious set of bugs.
-
-  Chris Reahard built a specialized root filesystem for running a DNS
-  server jailed inside UML.  It's available from the download
-  <http://user-mode-linux.sourceforge.net/dl-sf.html>  page in the Jail
-  Filesystems section.
-
-
-
-
-
-
-
-
-
-
-
-
diff -druN linux-2.6.39-libre/Documentation/usb/callbacks.txt linux-3.0-rc7-libre/Documentation/usb/callbacks.txt
--- linux-2.6.39-libre/Documentation/usb/callbacks.txt	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/Documentation/usb/callbacks.txt	2011-07-11 19:51:52.000000000 -0400
@@ -95,9 +95,11 @@
 
 int (*pre_reset)(struct usb_interface *intf);
 
-Another driver or user space is triggering a reset on the device which
-contains the interface passed as an argument. Cease IO and save any
-device state you need to restore.
+A driver or user space is triggering a reset on the device which
+contains the interface passed as an argument. Cease IO, wait for all
+outstanding URBs to complete, and save any device state you need to
+restore.  No more URBs may be submitted until the post_reset method
+is called.
 
 If you need to allocate memory here, use GFP_NOIO or GFP_ATOMIC, if you
 are in atomic context.
diff -druN linux-2.6.39-libre/Documentation/usb/error-codes.txt linux-3.0-rc7-libre/Documentation/usb/error-codes.txt
--- linux-2.6.39-libre/Documentation/usb/error-codes.txt	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/Documentation/usb/error-codes.txt	2011-07-11 19:51:52.000000000 -0400
@@ -76,6 +76,13 @@
 reported.  That's because transfers often involve several packets, so that
 one or more packets could finish before an error stops further endpoint I/O.
 
+For isochronous URBs, the urb status value is non-zero only if the URB is
+unlinked, the device is removed, the host controller is disabled, or the total
+transferred length is less than the requested length and the URB_SHORT_NOT_OK
+flag is set.  Completion handlers for isochronous URBs should only see
+urb->status set to zero, -ENOENT, -ECONNRESET, -ESHUTDOWN, or -EREMOTEIO.
+Individual frame descriptor status fields may report more status codes.
+
 
 0			Transfer completed successfully
 
@@ -132,7 +139,7 @@
 			device removal events immediately.
 
 -EXDEV			ISO transfer only partially completed
-			look at individual frame status for details
+			(only set in iso_frame_desc[n].status, not urb->status)
 
 -EINVAL			ISO madness, if this happens: Log off and go home
 
diff -druN linux-2.6.39-libre/Documentation/usb/hiddev.txt linux-3.0-rc7-libre/Documentation/usb/hiddev.txt
--- linux-2.6.39-libre/Documentation/usb/hiddev.txt	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/Documentation/usb/hiddev.txt	1969-12-31 19:00:00.000000000 -0500
@@ -1,205 +0,0 @@
-Care and feeding of your Human Interface Devices
-
-INTRODUCTION
-
-In addition to the normal input type HID devices, USB also uses the
-human interface device protocols for things that are not really human
-interfaces, but have similar sorts of communication needs. The two big
-examples for this are power devices (especially uninterruptable power
-supplies) and monitor control on higher end monitors.
-
-To support these disparate requirements, the Linux USB system provides
-HID events to two separate interfaces:
-* the input subsystem, which converts HID events into normal input
-device interfaces (such as keyboard, mouse and joystick) and a
-normalised event interface - see Documentation/input/input.txt
-* the hiddev interface, which provides fairly raw HID events
-
-The data flow for a HID event produced by a device is something like
-the following :
-
- usb.c ---> hid-core.c  ----> hid-input.c ----> [keyboard/mouse/joystick/event]
-                         |
-                         |
-                          --> hiddev.c ----> POWER / MONITOR CONTROL 
-
-In addition, other subsystems (apart from USB) can potentially feed
-events into the input subsystem, but these have no effect on the hid
-device interface.
-
-USING THE HID DEVICE INTERFACE
-
-The hiddev interface is a char interface using the normal USB major,
-with the minor numbers starting at 96 and finishing at 111. Therefore,
-you need the following commands:
-mknod /dev/usb/hiddev0 c 180 96
-mknod /dev/usb/hiddev1 c 180 97
-mknod /dev/usb/hiddev2 c 180 98
-mknod /dev/usb/hiddev3 c 180 99
-mknod /dev/usb/hiddev4 c 180 100
-mknod /dev/usb/hiddev5 c 180 101
-mknod /dev/usb/hiddev6 c 180 102
-mknod /dev/usb/hiddev7 c 180 103
-mknod /dev/usb/hiddev8 c 180 104
-mknod /dev/usb/hiddev9 c 180 105
-mknod /dev/usb/hiddev10 c 180 106
-mknod /dev/usb/hiddev11 c 180 107
-mknod /dev/usb/hiddev12 c 180 108
-mknod /dev/usb/hiddev13 c 180 109
-mknod /dev/usb/hiddev14 c 180 110
-mknod /dev/usb/hiddev15 c 180 111
-
-So you point your hiddev compliant user-space program at the correct
-interface for your device, and it all just works.
-
-Assuming that you have a hiddev compliant user-space program, of
-course. If you need to write one, read on.
-
-
-THE HIDDEV API
-This description should be read in conjunction with the HID
-specification, freely available from http://www.usb.org, and
-conveniently linked of http://www.linux-usb.org.
-
-The hiddev API uses a read() interface, and a set of ioctl() calls.
-
-HID devices exchange data with the host computer using data
-bundles called "reports".  Each report is divided into "fields",
-each of which can have one or more "usages".  In the hid-core,
-each one of these usages has a single signed 32 bit value.
-
-read():
-This is the event interface.  When the HID device's state changes,
-it performs an interrupt transfer containing a report which contains
-the changed value.  The hid-core.c module parses the report, and
-returns to hiddev.c the individual usages that have changed within
-the report.  In its basic mode, the hiddev will make these individual
-usage changes available to the reader using a struct hiddev_event:
-
-       struct hiddev_event {
-           unsigned hid;
-           signed int value;
-       };
-
-containing the HID usage identifier for the status that changed, and
-the value that it was changed to. Note that the structure is defined
-within <linux/hiddev.h>, along with some other useful #defines and
-structures.  The HID usage identifier is a composite of the HID usage
-page shifted to the 16 high order bits ORed with the usage code.  The
-behavior of the read() function can be modified using the HIDIOCSFLAG
-ioctl() described below.
-
-
-ioctl(): 
-This is the control interface. There are a number of controls: 
-
-HIDIOCGVERSION - int (read)
-Gets the version code out of the hiddev driver.
-
-HIDIOCAPPLICATION - (none)
-This ioctl call returns the HID application usage associated with the
-hid device. The third argument to ioctl() specifies which application
-index to get. This is useful when the device has more than one
-application collection. If the index is invalid (greater or equal to
-the number of application collections this device has) the ioctl
-returns -1. You can find out beforehand how many application
-collections the device has from the num_applications field from the
-hiddev_devinfo structure. 
-
-HIDIOCGCOLLECTIONINFO - struct hiddev_collection_info (read/write)
-This returns a superset of the information above, providing not only
-application collections, but all the collections the device has.  It
-also returns the level the collection lives in the hierarchy.
-The user passes in a hiddev_collection_info struct with the index 
-field set to the index that should be returned.  The ioctl fills in 
-the other fields.  If the index is larger than the last collection 
-index, the ioctl returns -1 and sets errno to -EINVAL.
-
-HIDIOCGDEVINFO - struct hiddev_devinfo (read)
-Gets a hiddev_devinfo structure which describes the device.
-
-HIDIOCGSTRING - struct hiddev_string_descriptor (read/write)
-Gets a string descriptor from the device. The caller must fill in the
-"index" field to indicate which descriptor should be returned.
-
-HIDIOCINITREPORT - (none)
-Instructs the kernel to retrieve all input and feature report values
-from the device. At this point, all the usage structures will contain
-current values for the device, and will maintain it as the device
-changes.  Note that the use of this ioctl is unnecessary in general,
-since later kernels automatically initialize the reports from the
-device at attach time.
-
-HIDIOCGNAME - string (variable length)
-Gets the device name
-
-HIDIOCGREPORT - struct hiddev_report_info (write)
-Instructs the kernel to get a feature or input report from the device,
-in order to selectively update the usage structures (in contrast to
-INITREPORT).
-
-HIDIOCSREPORT - struct hiddev_report_info (write)
-Instructs the kernel to send a report to the device. This report can
-be filled in by the user through HIDIOCSUSAGE calls (below) to fill in
-individual usage values in the report before sending the report in full
-to the device. 
-
-HIDIOCGREPORTINFO - struct hiddev_report_info (read/write)
-Fills in a hiddev_report_info structure for the user. The report is
-looked up by type (input, output or feature) and id, so these fields
-must be filled in by the user. The ID can be absolute -- the actual
-report id as reported by the device -- or relative --
-HID_REPORT_ID_FIRST for the first report, and (HID_REPORT_ID_NEXT |
-report_id) for the next report after report_id. Without a-priori
-information about report ids, the right way to use this ioctl is to
-use the relative IDs above to enumerate the valid IDs. The ioctl
-returns non-zero when there is no more next ID. The real report ID is
-filled into the returned hiddev_report_info structure. 
-
-HIDIOCGFIELDINFO - struct hiddev_field_info (read/write)
-Returns the field information associated with a report in a
-hiddev_field_info structure. The user must fill in report_id and
-report_type in this structure, as above. The field_index should also
-be filled in, which should be a number from 0 and maxfield-1, as
-returned from a previous HIDIOCGREPORTINFO call. 
-
-HIDIOCGUCODE - struct hiddev_usage_ref (read/write)
-Returns the usage_code in a hiddev_usage_ref structure, given that
-given its report type, report id, field index, and index within the
-field have already been filled into the structure.
-
-HIDIOCGUSAGE - struct hiddev_usage_ref (read/write)
-Returns the value of a usage in a hiddev_usage_ref structure. The
-usage to be retrieved can be specified as above, or the user can
-choose to fill in the report_type field and specify the report_id as
-HID_REPORT_ID_UNKNOWN. In this case, the hiddev_usage_ref will be
-filled in with the report and field information associated with this
-usage if it is found. 
-
-HIDIOCSUSAGE - struct hiddev_usage_ref (write)
-Sets the value of a usage in an output report.  The user fills in
-the hiddev_usage_ref structure as above, but additionally fills in
-the value field.
-
-HIDIOGCOLLECTIONINDEX - struct hiddev_usage_ref (write)
-Returns the collection index associated with this usage.  This
-indicates where in the collection hierarchy this usage sits.
-
-HIDIOCGFLAG - int (read)
-HIDIOCSFLAG - int (write)
-These operations respectively inspect and replace the mode flags
-that influence the read() call above.  The flags are as follows:
-
-    HIDDEV_FLAG_UREF - read() calls will now return 
-        struct hiddev_usage_ref instead of struct hiddev_event.
-        This is a larger structure, but in situations where the
-        device has more than one usage in its reports with the
-        same usage code, this mode serves to resolve such
-        ambiguity.
-
-    HIDDEV_FLAG_REPORT - This flag can only be used in conjunction
-        with HIDDEV_FLAG_UREF.  With this flag set, when the device
-        sends a report, a struct hiddev_usage_ref will be returned
-        to read() filled in with the report_type and report_id, but 
-        with field_index set to FIELD_INDEX_NONE.  This serves as
-        additional notification when the device has sent a report.
diff -druN linux-2.6.39-libre/Documentation/usb/linux-cdc-acm.inf linux-3.0-rc7-libre/Documentation/usb/linux-cdc-acm.inf
--- linux-2.6.39-libre/Documentation/usb/linux-cdc-acm.inf	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/Documentation/usb/linux-cdc-acm.inf	2011-07-11 19:51:52.000000000 -0400
@@ -90,10 +90,10 @@
 [SourceDisksFiles]
 [SourceDisksNames]
 [DeviceList]
-%DESCRIPTION%=DriverInstall, USB\VID_0525&PID_A4A7, USB\VID_0525&PID_A4AB&MI_02
+%DESCRIPTION%=DriverInstall, USB\VID_0525&PID_A4A7, USB\VID_1D6B&PID_0104&MI_02
 
 [DeviceList.NTamd64]
-%DESCRIPTION%=DriverInstall, USB\VID_0525&PID_A4A7, USB\VID_0525&PID_A4AB&MI_02
+%DESCRIPTION%=DriverInstall, USB\VID_0525&PID_A4A7, USB\VID_1D6B&PID_0104&MI_02
 
 
 ;------------------------------------------------------------------------------
diff -druN linux-2.6.39-libre/Documentation/usb/linux.inf linux-3.0-rc7-libre/Documentation/usb/linux.inf
--- linux-2.6.39-libre/Documentation/usb/linux.inf	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/Documentation/usb/linux.inf	2011-07-11 19:51:52.000000000 -0400
@@ -18,15 +18,15 @@
 
 ; Decoration for x86 architecture
 [LinuxDevices.NTx86]
-%LinuxDevice%       = RNDIS.NT.5.1, USB\VID_0525&PID_a4a2, USB\VID_0525&PID_a4ab&MI_00
+%LinuxDevice%       = RNDIS.NT.5.1, USB\VID_0525&PID_a4a2, USB\VID_1d6b&PID_0104&MI_00
 
 ; Decoration for x64 architecture
 [LinuxDevices.NTamd64]
-%LinuxDevice%       = RNDIS.NT.5.1, USB\VID_0525&PID_a4a2, USB\VID_0525&PID_a4ab&MI_00
+%LinuxDevice%       = RNDIS.NT.5.1, USB\VID_0525&PID_a4a2, USB\VID_1d6b&PID_0104&MI_00
 
 ; Decoration for ia64 architecture
 [LinuxDevices.NTia64]
-%LinuxDevice%       = RNDIS.NT.5.1, USB\VID_0525&PID_a4a2, USB\VID_0525&PID_a4ab&MI_00
+%LinuxDevice%       = RNDIS.NT.5.1, USB\VID_0525&PID_a4a2, USB\VID_1d6b&PID_0104&MI_00
 
 ;@@@ This is the common setting for setup
 [ControlFlags]
diff -druN linux-2.6.39-libre/Documentation/vgaarbiter.txt linux-3.0-rc7-libre/Documentation/vgaarbiter.txt
--- linux-2.6.39-libre/Documentation/vgaarbiter.txt	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/Documentation/vgaarbiter.txt	2011-07-11 19:51:52.000000000 -0400
@@ -14,11 +14,10 @@
 than one legacy device co-exists on the same machine. But the problem happens
 when these devices are trying to be accessed by different userspace clients
 (e.g. two server in parallel). Their address assignments conflict. Moreover,
-ideally, being an userspace application, it is not the role of the the X
-server to control bus resources. Therefore an arbitration scheme outside of
-the X server is needed to control the sharing of these resources. This
-document introduces the operation of the VGA arbiter implemented for Linux
-kernel.
+ideally, being a userspace application, it is not the role of the X server to
+control bus resources. Therefore an arbitration scheme outside of the X server
+is needed to control the sharing of these resources. This document introduces
+the operation of the VGA arbiter implemented for the Linux kernel.
 
 ----------------------------------------------------------------------------
 
@@ -39,7 +38,7 @@
 The vgaarb is a module of the Linux Kernel. When it is initially loaded, it
 scans all PCI devices and adds the VGA ones inside the arbitration. The
 arbiter then enables/disables the decoding on different devices of the VGA
-legacy instructions. Device which do not want/need to use the arbiter may
+legacy instructions. Devices which do not want/need to use the arbiter may
 explicitly tell it by calling vga_set_legacy_decoding().
 
 The kernel exports a char device interface (/dev/vga_arbiter) to the clients,
@@ -95,8 +94,8 @@
 notify them being added/removed in the system and automatically added/removed
 in the arbiter.
 
-There's also a in-kernel API of the arbiter in the case of DRM, vgacon and
-others which may use the arbiter.
+There is also an in-kernel API of the arbiter in case DRM, vgacon, or other
+drivers want to use it.
 
 
 I.2 libpciaccess
@@ -117,9 +116,8 @@
     struct pci_device *vga_default_dev;
 
 
-The vga_count is usually need to keep informed how many cards are being
-arbitrated, so for instance if there's only one then it can totally escape the
-scheme.
+The vga_count is used to track how many cards are being arbitrated, so for
+instance, if there is only one card, then it can completely escape arbitration.
 
 
 These functions below acquire VGA resources for the given card and mark those
diff -druN linux-2.6.39-libre/Documentation/video4linux/CARDLIST.em28xx linux-3.0-rc7-libre/Documentation/video4linux/CARDLIST.em28xx
--- linux-2.6.39-libre/Documentation/video4linux/CARDLIST.em28xx	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/Documentation/video4linux/CARDLIST.em28xx	2011-07-11 19:51:52.000000000 -0400
@@ -54,7 +54,7 @@
  53 -> Pinnacle Hybrid Pro                      (em2881)
  54 -> Kworld VS-DVB-T 323UR                    (em2882)        [eb1a:e323]
  55 -> Terratec Cinnergy Hybrid T USB XS (em2882) (em2882)        [0ccd:005e,0ccd:0042]
- 56 -> Pinnacle Hybrid Pro (2)                  (em2882)        [2304:0226]
+ 56 -> Pinnacle Hybrid Pro (330e)               (em2882)        [2304:0226]
  57 -> Kworld PlusTV HD Hybrid 330              (em2883)        [eb1a:a316]
  58 -> Compro VideoMate ForYou/Stereo           (em2820/em2840) [185b:2041]
  60 -> Hauppauge WinTV HVR 850                  (em2883)        [2040:651f]
diff -druN linux-2.6.39-libre/Documentation/video4linux/gspca.txt linux-3.0-rc7-libre/Documentation/video4linux/gspca.txt
--- linux-2.6.39-libre/Documentation/video4linux/gspca.txt	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/Documentation/video4linux/gspca.txt	2011-07-11 19:51:52.000000000 -0400
@@ -275,6 +275,7 @@
 pac7302		093a:262a	Webcam 300k
 pac7302		093a:262c	Philips SPC 230 NC
 jeilinj		0979:0280	Sakar 57379
+jeilinj		0979:0280	Sportscam DV15
 zc3xx		0ac8:0302	Z-star Vimicro zc0302
 vc032x		0ac8:0321	Vimicro generic vc0321
 vc032x		0ac8:0323	Vimicro Vc0323
diff -druN linux-2.6.39-libre/Documentation/video4linux/uvcvideo.txt linux-3.0-rc7-libre/Documentation/video4linux/uvcvideo.txt
--- linux-2.6.39-libre/Documentation/video4linux/uvcvideo.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/Documentation/video4linux/uvcvideo.txt	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,239 @@
+Linux USB Video Class (UVC) driver
+==================================
+
+This file documents some driver-specific aspects of the UVC driver, such as
+driver-specific ioctls and implementation notes.
+
+Questions and remarks can be sent to the Linux UVC development mailing list at
+linux-uvc-devel@lists.berlios.de.
+
+
+Extension Unit (XU) support
+---------------------------
+
+1. Introduction
+
+The UVC specification allows for vendor-specific extensions through extension
+units (XUs). The Linux UVC driver supports extension unit controls (XU controls)
+through two separate mechanisms:
+
+  - through mappings of XU controls to V4L2 controls
+  - through a driver-specific ioctl interface
+
+The first one allows generic V4L2 applications to use XU controls by mapping
+certain XU controls onto V4L2 controls, which then show up during ordinary
+control enumeration.
+
+The second mechanism requires uvcvideo-specific knowledge for the application to
+access XU controls but exposes the entire UVC XU concept to user space for
+maximum flexibility.
+
+Both mechanisms complement each other and are described in more detail below.
+
+
+2. Control mappings
+
+The UVC driver provides an API for user space applications to define so-called
+control mappings at runtime. These allow for individual XU controls or byte
+ranges thereof to be mapped to new V4L2 controls. Such controls appear and
+function exactly like normal V4L2 controls (i.e. the stock controls, such as
+brightness, contrast, etc.). However, reading or writing of such a V4L2 controls
+triggers a read or write of the associated XU control.
+
+The ioctl used to create these control mappings is called UVCIOC_CTRL_MAP.
+Previous driver versions (before 0.2.0) required another ioctl to be used
+beforehand (UVCIOC_CTRL_ADD) to pass XU control information to the UVC driver.
+This is no longer necessary as newer uvcvideo versions query the information
+directly from the device.
+
+For details on the UVCIOC_CTRL_MAP ioctl please refer to the section titled
+"IOCTL reference" below.
+
+
+3. Driver specific XU control interface
+
+For applications that need to access XU controls directly, e.g. for testing
+purposes, firmware upload, or accessing binary controls, a second mechanism to
+access XU controls is provided in the form of a driver-specific ioctl, namely
+UVCIOC_CTRL_QUERY.
+
+A call to this ioctl allows applications to send queries to the UVC driver that
+directly map to the low-level UVC control requests.
+
+In order to make such a request the UVC unit ID of the control's extension unit
+and the control selector need to be known. This information either needs to be
+hardcoded in the application or queried using other ways such as by parsing the
+UVC descriptor or, if available, using the media controller API to enumerate a
+device's entities.
+
+Unless the control size is already known it is necessary to first make a
+UVC_GET_LEN requests in order to be able to allocate a sufficiently large buffer
+and set the buffer size to the correct value. Similarly, to find out whether
+UVC_GET_CUR or UVC_SET_CUR are valid requests for a given control, a
+UVC_GET_INFO request should be made. The bits 0 (GET supported) and 1 (SET
+supported) of the resulting byte indicate which requests are valid.
+
+With the addition of the UVCIOC_CTRL_QUERY ioctl the UVCIOC_CTRL_GET and
+UVCIOC_CTRL_SET ioctls have become obsolete since their functionality is a
+subset of the former ioctl. For the time being they are still supported but
+application developers are encouraged to use UVCIOC_CTRL_QUERY instead.
+
+For details on the UVCIOC_CTRL_QUERY ioctl please refer to the section titled
+"IOCTL reference" below.
+
+
+4. Security
+
+The API doesn't currently provide a fine-grained access control facility. The
+UVCIOC_CTRL_ADD and UVCIOC_CTRL_MAP ioctls require super user permissions.
+
+Suggestions on how to improve this are welcome.
+
+
+5. Debugging
+
+In order to debug problems related to XU controls or controls in general it is
+recommended to enable the UVC_TRACE_CONTROL bit in the module parameter 'trace'.
+This causes extra output to be written into the system log.
+
+
+6. IOCTL reference
+
+---- UVCIOC_CTRL_MAP - Map a UVC control to a V4L2 control ----
+
+Argument: struct uvc_xu_control_mapping
+
+Description:
+	This ioctl creates a mapping between a UVC control or part of a UVC
+	control and a V4L2 control. Once mappings are defined, userspace
+	applications can access vendor-defined UVC control through the V4L2
+	control API.
+
+	To create a mapping, applications fill the uvc_xu_control_mapping
+	structure with information about an existing UVC control defined with
+	UVCIOC_CTRL_ADD and a new V4L2 control.
+
+	A UVC control can be mapped to several V4L2 controls. For instance,
+	a UVC pan/tilt control could be mapped to separate pan and tilt V4L2
+	controls. The UVC control is divided into non overlapping fields using
+	the 'size' and 'offset' fields and are then independantly mapped to
+	V4L2 control.
+
+	For signed integer V4L2 controls the data_type field should be set to
+	UVC_CTRL_DATA_TYPE_SIGNED. Other values are currently ignored.
+
+Return value:
+	On success 0 is returned. On error -1 is returned and errno is set
+	appropriately.
+
+	ENOMEM
+		Not enough memory to perform the operation.
+	EPERM
+		Insufficient privileges (super user privileges are required).
+	EINVAL
+		No such UVC control.
+	EOVERFLOW
+		The requested offset and size would overflow the UVC control.
+	EEXIST
+		Mapping already exists.
+
+Data types:
+	* struct uvc_xu_control_mapping
+
+	__u32	id		V4L2 control identifier
+	__u8	name[32]	V4L2 control name
+	__u8	entity[16]	UVC extension unit GUID
+	__u8	selector	UVC control selector
+	__u8	size		V4L2 control size (in bits)
+	__u8	offset		V4L2 control offset (in bits)
+	enum v4l2_ctrl_type
+		v4l2_type	V4L2 control type
+	enum uvc_control_data_type
+		data_type	UVC control data type
+	struct uvc_menu_info
+		*menu_info	Array of menu entries (for menu controls only)
+	__u32	menu_count	Number of menu entries (for menu controls only)
+
+	* struct uvc_menu_info
+
+	__u32	value		Menu entry value used by the device
+	__u8	name[32]	Menu entry name
+
+
+	* enum uvc_control_data_type
+
+	UVC_CTRL_DATA_TYPE_RAW		Raw control (byte array)
+	UVC_CTRL_DATA_TYPE_SIGNED	Signed integer
+	UVC_CTRL_DATA_TYPE_UNSIGNED	Unsigned integer
+	UVC_CTRL_DATA_TYPE_BOOLEAN	Boolean
+	UVC_CTRL_DATA_TYPE_ENUM		Enumeration
+	UVC_CTRL_DATA_TYPE_BITMASK	Bitmask
+
+
+---- UVCIOC_CTRL_QUERY - Query a UVC XU control ----
+
+Argument: struct uvc_xu_control_query
+
+Description:
+	This ioctl queries a UVC XU control identified by its extension unit ID
+	and control selector.
+
+	There are a number of different queries available that closely
+	correspond to the low-level control requests described in the UVC
+	specification. These requests are:
+
+	UVC_GET_CUR
+		Obtain the current value of the control.
+	UVC_GET_MIN
+		Obtain the minimum value of the control.
+	UVC_GET_MAX
+		Obtain the maximum value of the control.
+	UVC_GET_DEF
+		Obtain the default value of the control.
+	UVC_GET_RES
+		Query the resolution of the control, i.e. the step size of the
+		allowed control values.
+	UVC_GET_LEN
+		Query the size of the control in bytes.
+	UVC_GET_INFO
+		Query the control information bitmap, which indicates whether
+		get/set requests are supported.
+	UVC_SET_CUR
+		Update the value of the control.
+
+	Applications must set the 'size' field to the correct length for the
+	control. Exceptions are the UVC_GET_LEN and UVC_GET_INFO queries, for
+	which the size must be set to 2 and 1, respectively. The 'data' field
+	must point to a valid writable buffer big enough to hold the indicated
+	number of data bytes.
+
+	Data is copied directly from the device without any driver-side
+	processing. Applications are responsible for data buffer formatting,
+	including little-endian/big-endian conversion. This is particularly
+	important for the result of the UVC_GET_LEN requests, which is always
+	returned as a little-endian 16-bit integer by the device.
+
+Return value:
+	On success 0 is returned. On error -1 is returned and errno is set
+	appropriately.
+
+	ENOENT
+		The device does not support the given control or the specified
+		extension unit could not be found.
+	ENOBUFS
+		The specified buffer size is incorrect (too big or too small).
+	EINVAL
+		An invalid request code was passed.
+	EBADRQC
+		The given request is not supported by the given control.
+	EFAULT
+		The data pointer references an inaccessible memory area.
+
+Data types:
+	* struct uvc_xu_control_query
+
+	__u8	unit		Extension unit ID
+	__u8	selector	Control selector
+	__u8	query		Request code to send to the device
+	__u16	size		Control data size (in bytes)
+	__u8	*data		Control value
diff -druN linux-2.6.39-libre/Documentation/video4linux/Zoran linux-3.0-rc7-libre/Documentation/video4linux/Zoran
--- linux-2.6.39-libre/Documentation/video4linux/Zoran	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/Documentation/video4linux/Zoran	2011-07-11 19:51:52.000000000 -0400
@@ -130,7 +130,6 @@
 
 Note: No module for the mse3000 is available yet
 Note: No module for the vpx3224 is available yet
-Note: use encoder=X or decoder=X for non-default i2c chips
 
 ===========================
 
diff -druN linux-2.6.39-libre/Documentation/virtual/00-INDEX linux-3.0-rc7-libre/Documentation/virtual/00-INDEX
--- linux-2.6.39-libre/Documentation/virtual/00-INDEX	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/Documentation/virtual/00-INDEX	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,10 @@
+Virtualization support in the Linux kernel.
+
+00-INDEX
+	- this file.
+kvm/
+	- Kernel Virtual Machine.  See also http://linux-kvm.org
+lguest/
+	- Extremely simple hypervisor for experimental/educational use.
+uml/
+	- User Mode Linux, builds/runs Linux kernel as a userspace program.
diff -druN linux-2.6.39-libre/Documentation/virtual/kvm/api.txt linux-3.0-rc7-libre/Documentation/virtual/kvm/api.txt
--- linux-2.6.39-libre/Documentation/virtual/kvm/api.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/Documentation/virtual/kvm/api.txt	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,1479 @@
+The Definitive KVM (Kernel-based Virtual Machine) API Documentation
+===================================================================
+
+1. General description
+
+The kvm API is a set of ioctls that are issued to control various aspects
+of a virtual machine.  The ioctls belong to three classes
+
+ - System ioctls: These query and set global attributes which affect the
+   whole kvm subsystem.  In addition a system ioctl is used to create
+   virtual machines
+
+ - VM ioctls: These query and set attributes that affect an entire virtual
+   machine, for example memory layout.  In addition a VM ioctl is used to
+   create virtual cpus (vcpus).
+
+   Only run VM ioctls from the same process (address space) that was used
+   to create the VM.
+
+ - vcpu ioctls: These query and set attributes that control the operation
+   of a single virtual cpu.
+
+   Only run vcpu ioctls from the same thread that was used to create the
+   vcpu.
+
+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 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
+actually running guest code.
+
+In general file descriptors can be migrated among processes by means
+of fork() and the SCM_RIGHTS facility of unix domain socket.  These
+kinds of tricks are explicitly not supported by kvm.  While they will
+not cause harm to the host, their actual behavior is not guaranteed by
+the API.  The only supported use is one virtual machine per process,
+and one vcpu per thread.
+
+3. Extensions
+
+As of Linux 2.6.22, the KVM ABI has been stabilized: no backward
+incompatible change are allowed.  However, there is an extension
+facility that allows backward-compatible extensions to the API to be
+queried and used.
+
+The extension mechanism is not based on on the Linux version number.
+Instead, kvm defines extension identifiers and a facility to query
+whether a particular extension identifier is available.  If it is, a
+set of ioctls is available for application use.
+
+4. API description
+
+This section describes ioctls that can be used to control kvm guests.
+For each ioctl, the following information is provided along with a
+description:
+
+  Capability: which KVM extension provides this ioctl.  Can be 'basic',
+      which means that is will be provided by any kernel that supports
+      API version 12 (see section 4.1), or a KVM_CAP_xyz constant, which
+      means availability needs to be checked with KVM_CHECK_EXTENSION
+      (see section 4.4).
+
+  Architectures: which instruction set architectures provide this ioctl.
+      x86 includes both i386 and x86_64.
+
+  Type: system, vm, or vcpu.
+
+  Parameters: what parameters are accepted by the ioctl.
+
+  Returns: the return value.  General error numbers (EBADF, ENOMEM, EINVAL)
+      are not detailed, but errors with specific meanings are.
+
+4.1 KVM_GET_API_VERSION
+
+Capability: basic
+Architectures: all
+Type: system ioctl
+Parameters: none
+Returns: the constant KVM_API_VERSION (=12)
+
+This identifies the API version as the stable kvm API. It is not
+expected that this number will change.  However, Linux 2.6.20 and
+2.6.21 report earlier versions; these are not documented and not
+supported.  Applications should refuse to run if KVM_GET_API_VERSION
+returns a value other than 12.  If this check passes, all ioctls
+described as 'basic' will be available.
+
+4.2 KVM_CREATE_VM
+
+Capability: basic
+Architectures: all
+Type: system ioctl
+Parameters: none
+Returns: a VM fd that can be used to control the new virtual machine.
+
+The new VM has no virtual cpus and no memory.  An mmap() of a VM fd
+will access the virtual machine's physical address space; offset zero
+corresponds to guest physical address zero.  Use of mmap() on a VM fd
+is discouraged if userspace memory allocation (KVM_CAP_USER_MEMORY) is
+available.
+
+4.3 KVM_GET_MSR_INDEX_LIST
+
+Capability: basic
+Architectures: x86
+Type: system
+Parameters: struct kvm_msr_list (in/out)
+Returns: 0 on success; -1 on error
+Errors:
+  E2BIG:     the msr index list is to be to fit in the array specified by
+             the user.
+
+struct kvm_msr_list {
+	__u32 nmsrs; /* number of msrs in entries */
+	__u32 indices[0];
+};
+
+This ioctl returns the guest msrs that are supported.  The list varies
+by kvm version and host processor, but does not change otherwise.  The
+user fills in the size of the indices array in nmsrs, and in return
+kvm adjusts nmsrs to reflect the actual number of msrs and fills in
+the indices array with their numbers.
+
+Note: if kvm indicates supports MCE (KVM_CAP_MCE), then the MCE bank MSRs are
+not returned in the MSR list, as different vcpus can have a different number
+of banks, as set via the KVM_X86_SETUP_MCE ioctl.
+
+4.4 KVM_CHECK_EXTENSION
+
+Capability: basic
+Architectures: all
+Type: system ioctl
+Parameters: extension identifier (KVM_CAP_*)
+Returns: 0 if unsupported; 1 (or some other positive integer) if supported
+
+The API allows the application to query about extensions to the core
+kvm API.  Userspace passes an extension identifier (an integer) and
+receives an integer that describes the extension availability.
+Generally 0 means no and 1 means yes, but some extensions may report
+additional information in the integer return value.
+
+4.5 KVM_GET_VCPU_MMAP_SIZE
+
+Capability: basic
+Architectures: all
+Type: system ioctl
+Parameters: none
+Returns: size of vcpu mmap area, in bytes
+
+The KVM_RUN ioctl (cf.) communicates with userspace via a shared
+memory region.  This ioctl returns the size of that region.  See the
+KVM_RUN documentation for details.
+
+4.6 KVM_SET_MEMORY_REGION
+
+Capability: basic
+Architectures: all
+Type: vm ioctl
+Parameters: struct kvm_memory_region (in)
+Returns: 0 on success, -1 on error
+
+This ioctl is obsolete and has been removed.
+
+4.7 KVM_CREATE_VCPU
+
+Capability: basic
+Architectures: all
+Type: vm ioctl
+Parameters: vcpu id (apic id on x86)
+Returns: vcpu fd on success, -1 on error
+
+This API adds a vcpu to a virtual machine.  The vcpu id is a small integer
+in the range [0, max_vcpus).  You can use KVM_CAP_NR_VCPUS of the
+KVM_CHECK_EXTENSION ioctl() to determine the value for max_vcpus at run-time.
+If the KVM_CAP_NR_VCPUS does not exist, you should assume that max_vcpus is 4
+cpus max.
+
+4.8 KVM_GET_DIRTY_LOG (vm ioctl)
+
+Capability: basic
+Architectures: x86
+Type: vm ioctl
+Parameters: struct kvm_dirty_log (in/out)
+Returns: 0 on success, -1 on error
+
+/* for KVM_GET_DIRTY_LOG */
+struct kvm_dirty_log {
+	__u32 slot;
+	__u32 padding;
+	union {
+		void __user *dirty_bitmap; /* one bit per page */
+		__u64 padding;
+	};
+};
+
+Given a memory slot, return a bitmap containing any pages dirtied
+since the last call to this ioctl.  Bit 0 is the first page in the
+memory slot.  Ensure the entire structure is cleared to avoid padding
+issues.
+
+4.9 KVM_SET_MEMORY_ALIAS
+
+Capability: basic
+Architectures: x86
+Type: vm ioctl
+Parameters: struct kvm_memory_alias (in)
+Returns: 0 (success), -1 (error)
+
+This ioctl is obsolete and has been removed.
+
+4.10 KVM_RUN
+
+Capability: basic
+Architectures: all
+Type: vcpu ioctl
+Parameters: none
+Returns: 0 on success, -1 on error
+Errors:
+  EINTR:     an unmasked signal is pending
+
+This ioctl is used to run a guest virtual cpu.  While there are no
+explicit parameters, there is an implicit parameter block that can be
+obtained by mmap()ing the vcpu fd at offset 0, with the size given by
+KVM_GET_VCPU_MMAP_SIZE.  The parameter block is formatted as a 'struct
+kvm_run' (see below).
+
+4.11 KVM_GET_REGS
+
+Capability: basic
+Architectures: all
+Type: vcpu ioctl
+Parameters: struct kvm_regs (out)
+Returns: 0 on success, -1 on error
+
+Reads the general purpose registers from the vcpu.
+
+/* x86 */
+struct kvm_regs {
+	/* out (KVM_GET_REGS) / in (KVM_SET_REGS) */
+	__u64 rax, rbx, rcx, rdx;
+	__u64 rsi, rdi, rsp, rbp;
+	__u64 r8,  r9,  r10, r11;
+	__u64 r12, r13, r14, r15;
+	__u64 rip, rflags;
+};
+
+4.12 KVM_SET_REGS
+
+Capability: basic
+Architectures: all
+Type: vcpu ioctl
+Parameters: struct kvm_regs (in)
+Returns: 0 on success, -1 on error
+
+Writes the general purpose registers into the vcpu.
+
+See KVM_GET_REGS for the data structure.
+
+4.13 KVM_GET_SREGS
+
+Capability: basic
+Architectures: x86, ppc
+Type: vcpu ioctl
+Parameters: struct kvm_sregs (out)
+Returns: 0 on success, -1 on error
+
+Reads special registers from the vcpu.
+
+/* x86 */
+struct kvm_sregs {
+	struct kvm_segment cs, ds, es, fs, gs, ss;
+	struct kvm_segment tr, ldt;
+	struct kvm_dtable gdt, idt;
+	__u64 cr0, cr2, cr3, cr4, cr8;
+	__u64 efer;
+	__u64 apic_base;
+	__u64 interrupt_bitmap[(KVM_NR_INTERRUPTS + 63) / 64];
+};
+
+/* ppc -- see arch/powerpc/include/asm/kvm.h */
+
+interrupt_bitmap is a bitmap of pending external interrupts.  At most
+one bit may be set.  This interrupt has been acknowledged by the APIC
+but not yet injected into the cpu core.
+
+4.14 KVM_SET_SREGS
+
+Capability: basic
+Architectures: x86, ppc
+Type: vcpu ioctl
+Parameters: struct kvm_sregs (in)
+Returns: 0 on success, -1 on error
+
+Writes special registers into the vcpu.  See KVM_GET_SREGS for the
+data structures.
+
+4.15 KVM_TRANSLATE
+
+Capability: basic
+Architectures: x86
+Type: vcpu ioctl
+Parameters: struct kvm_translation (in/out)
+Returns: 0 on success, -1 on error
+
+Translates a virtual address according to the vcpu's current address
+translation mode.
+
+struct kvm_translation {
+	/* in */
+	__u64 linear_address;
+
+	/* out */
+	__u64 physical_address;
+	__u8  valid;
+	__u8  writeable;
+	__u8  usermode;
+	__u8  pad[5];
+};
+
+4.16 KVM_INTERRUPT
+
+Capability: basic
+Architectures: x86, ppc
+Type: vcpu ioctl
+Parameters: struct kvm_interrupt (in)
+Returns: 0 on success, -1 on error
+
+Queues a hardware interrupt vector to be injected.  This is only
+useful if in-kernel local APIC or equivalent is not used.
+
+/* for KVM_INTERRUPT */
+struct kvm_interrupt {
+	/* in */
+	__u32 irq;
+};
+
+X86:
+
+Note 'irq' is an interrupt vector, not an interrupt pin or line.
+
+PPC:
+
+Queues an external interrupt to be injected. This ioctl is overleaded
+with 3 different irq values:
+
+a) KVM_INTERRUPT_SET
+
+  This injects an edge type external interrupt into the guest once it's ready
+  to receive interrupts. When injected, the interrupt is done.
+
+b) KVM_INTERRUPT_UNSET
+
+  This unsets any pending interrupt.
+
+  Only available with KVM_CAP_PPC_UNSET_IRQ.
+
+c) KVM_INTERRUPT_SET_LEVEL
+
+  This injects a level type external interrupt into the guest context. The
+  interrupt stays pending until a specific ioctl with KVM_INTERRUPT_UNSET
+  is triggered.
+
+  Only available with KVM_CAP_PPC_IRQ_LEVEL.
+
+Note that any value for 'irq' other than the ones stated above is invalid
+and incurs unexpected behavior.
+
+4.17 KVM_DEBUG_GUEST
+
+Capability: basic
+Architectures: none
+Type: vcpu ioctl
+Parameters: none)
+Returns: -1 on error
+
+Support for this has been removed.  Use KVM_SET_GUEST_DEBUG instead.
+
+4.18 KVM_GET_MSRS
+
+Capability: basic
+Architectures: x86
+Type: vcpu ioctl
+Parameters: struct kvm_msrs (in/out)
+Returns: 0 on success, -1 on error
+
+Reads model-specific registers from the vcpu.  Supported msr indices can
+be obtained using KVM_GET_MSR_INDEX_LIST.
+
+struct kvm_msrs {
+	__u32 nmsrs; /* number of msrs in entries */
+	__u32 pad;
+
+	struct kvm_msr_entry entries[0];
+};
+
+struct kvm_msr_entry {
+	__u32 index;
+	__u32 reserved;
+	__u64 data;
+};
+
+Application code should set the 'nmsrs' member (which indicates the
+size of the entries array) and the 'index' member of each array entry.
+kvm will fill in the 'data' member.
+
+4.19 KVM_SET_MSRS
+
+Capability: basic
+Architectures: x86
+Type: vcpu ioctl
+Parameters: struct kvm_msrs (in)
+Returns: 0 on success, -1 on error
+
+Writes model-specific registers to the vcpu.  See KVM_GET_MSRS for the
+data structures.
+
+Application code should set the 'nmsrs' member (which indicates the
+size of the entries array), and the 'index' and 'data' members of each
+array entry.
+
+4.20 KVM_SET_CPUID
+
+Capability: basic
+Architectures: x86
+Type: vcpu ioctl
+Parameters: struct kvm_cpuid (in)
+Returns: 0 on success, -1 on error
+
+Defines the vcpu responses to the cpuid instruction.  Applications
+should use the KVM_SET_CPUID2 ioctl if available.
+
+
+struct kvm_cpuid_entry {
+	__u32 function;
+	__u32 eax;
+	__u32 ebx;
+	__u32 ecx;
+	__u32 edx;
+	__u32 padding;
+};
+
+/* for KVM_SET_CPUID */
+struct kvm_cpuid {
+	__u32 nent;
+	__u32 padding;
+	struct kvm_cpuid_entry entries[0];
+};
+
+4.21 KVM_SET_SIGNAL_MASK
+
+Capability: basic
+Architectures: x86
+Type: vcpu ioctl
+Parameters: struct kvm_signal_mask (in)
+Returns: 0 on success, -1 on error
+
+Defines which signals are blocked during execution of KVM_RUN.  This
+signal mask temporarily overrides the threads signal mask.  Any
+unblocked signal received (except SIGKILL and SIGSTOP, which retain
+their traditional behaviour) will cause KVM_RUN to return with -EINTR.
+
+Note the signal will only be delivered if not blocked by the original
+signal mask.
+
+/* for KVM_SET_SIGNAL_MASK */
+struct kvm_signal_mask {
+	__u32 len;
+	__u8  sigset[0];
+};
+
+4.22 KVM_GET_FPU
+
+Capability: basic
+Architectures: x86
+Type: vcpu ioctl
+Parameters: struct kvm_fpu (out)
+Returns: 0 on success, -1 on error
+
+Reads the floating point state from the vcpu.
+
+/* for KVM_GET_FPU and KVM_SET_FPU */
+struct kvm_fpu {
+	__u8  fpr[8][16];
+	__u16 fcw;
+	__u16 fsw;
+	__u8  ftwx;  /* in fxsave format */
+	__u8  pad1;
+	__u16 last_opcode;
+	__u64 last_ip;
+	__u64 last_dp;
+	__u8  xmm[16][16];
+	__u32 mxcsr;
+	__u32 pad2;
+};
+
+4.23 KVM_SET_FPU
+
+Capability: basic
+Architectures: x86
+Type: vcpu ioctl
+Parameters: struct kvm_fpu (in)
+Returns: 0 on success, -1 on error
+
+Writes the floating point state to the vcpu.
+
+/* for KVM_GET_FPU and KVM_SET_FPU */
+struct kvm_fpu {
+	__u8  fpr[8][16];
+	__u16 fcw;
+	__u16 fsw;
+	__u8  ftwx;  /* in fxsave format */
+	__u8  pad1;
+	__u16 last_opcode;
+	__u64 last_ip;
+	__u64 last_dp;
+	__u8  xmm[16][16];
+	__u32 mxcsr;
+	__u32 pad2;
+};
+
+4.24 KVM_CREATE_IRQCHIP
+
+Capability: KVM_CAP_IRQCHIP
+Architectures: x86, ia64
+Type: vm ioctl
+Parameters: none
+Returns: 0 on success, -1 on error
+
+Creates an interrupt controller model in the kernel.  On x86, creates a virtual
+ioapic, a virtual PIC (two PICs, nested), and sets up future vcpus to have a
+local APIC.  IRQ routing for GSIs 0-15 is set to both PIC and IOAPIC; GSI 16-23
+only go to the IOAPIC.  On ia64, a IOSAPIC is created.
+
+4.25 KVM_IRQ_LINE
+
+Capability: KVM_CAP_IRQCHIP
+Architectures: x86, ia64
+Type: vm ioctl
+Parameters: struct kvm_irq_level
+Returns: 0 on success, -1 on error
+
+Sets the level of a GSI input to the interrupt controller model in the kernel.
+Requires that an interrupt controller model has been previously created with
+KVM_CREATE_IRQCHIP.  Note that edge-triggered interrupts require the level
+to be set to 1 and then back to 0.
+
+struct kvm_irq_level {
+	union {
+		__u32 irq;     /* GSI */
+		__s32 status;  /* not used for KVM_IRQ_LEVEL */
+	};
+	__u32 level;           /* 0 or 1 */
+};
+
+4.26 KVM_GET_IRQCHIP
+
+Capability: KVM_CAP_IRQCHIP
+Architectures: x86, ia64
+Type: vm ioctl
+Parameters: struct kvm_irqchip (in/out)
+Returns: 0 on success, -1 on error
+
+Reads the state of a kernel interrupt controller created with
+KVM_CREATE_IRQCHIP into a buffer provided by the caller.
+
+struct kvm_irqchip {
+	__u32 chip_id;  /* 0 = PIC1, 1 = PIC2, 2 = IOAPIC */
+	__u32 pad;
+        union {
+		char dummy[512];  /* reserving space */
+		struct kvm_pic_state pic;
+		struct kvm_ioapic_state ioapic;
+	} chip;
+};
+
+4.27 KVM_SET_IRQCHIP
+
+Capability: KVM_CAP_IRQCHIP
+Architectures: x86, ia64
+Type: vm ioctl
+Parameters: struct kvm_irqchip (in)
+Returns: 0 on success, -1 on error
+
+Sets the state of a kernel interrupt controller created with
+KVM_CREATE_IRQCHIP from a buffer provided by the caller.
+
+struct kvm_irqchip {
+	__u32 chip_id;  /* 0 = PIC1, 1 = PIC2, 2 = IOAPIC */
+	__u32 pad;
+        union {
+		char dummy[512];  /* reserving space */
+		struct kvm_pic_state pic;
+		struct kvm_ioapic_state ioapic;
+	} chip;
+};
+
+4.28 KVM_XEN_HVM_CONFIG
+
+Capability: KVM_CAP_XEN_HVM
+Architectures: x86
+Type: vm ioctl
+Parameters: struct kvm_xen_hvm_config (in)
+Returns: 0 on success, -1 on error
+
+Sets the MSR that the Xen HVM guest uses to initialize its hypercall
+page, and provides the starting address and size of the hypercall
+blobs in userspace.  When the guest writes the MSR, kvm copies one
+page of a blob (32- or 64-bit, depending on the vcpu mode) to guest
+memory.
+
+struct kvm_xen_hvm_config {
+	__u32 flags;
+	__u32 msr;
+	__u64 blob_addr_32;
+	__u64 blob_addr_64;
+	__u8 blob_size_32;
+	__u8 blob_size_64;
+	__u8 pad2[30];
+};
+
+4.29 KVM_GET_CLOCK
+
+Capability: KVM_CAP_ADJUST_CLOCK
+Architectures: x86
+Type: vm ioctl
+Parameters: struct kvm_clock_data (out)
+Returns: 0 on success, -1 on error
+
+Gets the current timestamp of kvmclock as seen by the current guest. In
+conjunction with KVM_SET_CLOCK, it is used to ensure monotonicity on scenarios
+such as migration.
+
+struct kvm_clock_data {
+	__u64 clock;  /* kvmclock current value */
+	__u32 flags;
+	__u32 pad[9];
+};
+
+4.30 KVM_SET_CLOCK
+
+Capability: KVM_CAP_ADJUST_CLOCK
+Architectures: x86
+Type: vm ioctl
+Parameters: struct kvm_clock_data (in)
+Returns: 0 on success, -1 on error
+
+Sets the current timestamp of kvmclock to the value specified in its parameter.
+In conjunction with KVM_GET_CLOCK, it is used to ensure monotonicity on scenarios
+such as migration.
+
+struct kvm_clock_data {
+	__u64 clock;  /* kvmclock current value */
+	__u32 flags;
+	__u32 pad[9];
+};
+
+4.31 KVM_GET_VCPU_EVENTS
+
+Capability: KVM_CAP_VCPU_EVENTS
+Extended by: KVM_CAP_INTR_SHADOW
+Architectures: x86
+Type: vm ioctl
+Parameters: struct kvm_vcpu_event (out)
+Returns: 0 on success, -1 on error
+
+Gets currently pending exceptions, interrupts, and NMIs as well as related
+states of the vcpu.
+
+struct kvm_vcpu_events {
+	struct {
+		__u8 injected;
+		__u8 nr;
+		__u8 has_error_code;
+		__u8 pad;
+		__u32 error_code;
+	} exception;
+	struct {
+		__u8 injected;
+		__u8 nr;
+		__u8 soft;
+		__u8 shadow;
+	} interrupt;
+	struct {
+		__u8 injected;
+		__u8 pending;
+		__u8 masked;
+		__u8 pad;
+	} nmi;
+	__u32 sipi_vector;
+	__u32 flags;
+};
+
+KVM_VCPUEVENT_VALID_SHADOW may be set in the flags field to signal that
+interrupt.shadow contains a valid state. Otherwise, this field is undefined.
+
+4.32 KVM_SET_VCPU_EVENTS
+
+Capability: KVM_CAP_VCPU_EVENTS
+Extended by: KVM_CAP_INTR_SHADOW
+Architectures: x86
+Type: vm ioctl
+Parameters: struct kvm_vcpu_event (in)
+Returns: 0 on success, -1 on error
+
+Set pending exceptions, interrupts, and NMIs as well as related states of the
+vcpu.
+
+See KVM_GET_VCPU_EVENTS for the data structure.
+
+Fields that may be modified asynchronously by running VCPUs can be excluded
+from the update. These fields are nmi.pending and sipi_vector. Keep the
+corresponding bits in the flags field cleared to suppress overwriting the
+current in-kernel state. The bits are:
+
+KVM_VCPUEVENT_VALID_NMI_PENDING - transfer nmi.pending to the kernel
+KVM_VCPUEVENT_VALID_SIPI_VECTOR - transfer sipi_vector
+
+If KVM_CAP_INTR_SHADOW is available, KVM_VCPUEVENT_VALID_SHADOW can be set in
+the flags field to signal that interrupt.shadow contains a valid state and
+shall be written into the VCPU.
+
+4.33 KVM_GET_DEBUGREGS
+
+Capability: KVM_CAP_DEBUGREGS
+Architectures: x86
+Type: vm ioctl
+Parameters: struct kvm_debugregs (out)
+Returns: 0 on success, -1 on error
+
+Reads debug registers from the vcpu.
+
+struct kvm_debugregs {
+	__u64 db[4];
+	__u64 dr6;
+	__u64 dr7;
+	__u64 flags;
+	__u64 reserved[9];
+};
+
+4.34 KVM_SET_DEBUGREGS
+
+Capability: KVM_CAP_DEBUGREGS
+Architectures: x86
+Type: vm ioctl
+Parameters: struct kvm_debugregs (in)
+Returns: 0 on success, -1 on error
+
+Writes debug registers into the vcpu.
+
+See KVM_GET_DEBUGREGS for the data structure. The flags field is unused
+yet and must be cleared on entry.
+
+4.35 KVM_SET_USER_MEMORY_REGION
+
+Capability: KVM_CAP_USER_MEM
+Architectures: all
+Type: vm ioctl
+Parameters: struct kvm_userspace_memory_region (in)
+Returns: 0 on success, -1 on error
+
+struct kvm_userspace_memory_region {
+	__u32 slot;
+	__u32 flags;
+	__u64 guest_phys_addr;
+	__u64 memory_size; /* bytes */
+	__u64 userspace_addr; /* start of the userspace allocated memory */
+};
+
+/* for kvm_memory_region::flags */
+#define KVM_MEM_LOG_DIRTY_PAGES  1UL
+
+This ioctl allows the user to create or modify a guest physical memory
+slot.  When changing an existing slot, it may be moved in the guest
+physical memory space, or its flags may be modified.  It may not be
+resized.  Slots may not overlap in guest physical address space.
+
+Memory for the region is taken starting at the address denoted by the
+field userspace_addr, which must point at user addressable memory for
+the entire memory slot size.  Any object may back this memory, including
+anonymous memory, ordinary files, and hugetlbfs.
+
+It is recommended that the lower 21 bits of guest_phys_addr and userspace_addr
+be identical.  This allows large pages in the guest to be backed by large
+pages in the host.
+
+The flags field supports just one flag, KVM_MEM_LOG_DIRTY_PAGES, which
+instructs kvm to keep track of writes to memory within the slot.  See
+the KVM_GET_DIRTY_LOG ioctl.
+
+When the KVM_CAP_SYNC_MMU capability, changes in the backing of the memory
+region are automatically reflected into the guest.  For example, an mmap()
+that affects the region will be made visible immediately.  Another example
+is madvise(MADV_DROP).
+
+It is recommended to use this API instead of the KVM_SET_MEMORY_REGION ioctl.
+The KVM_SET_MEMORY_REGION does not allow fine grained control over memory
+allocation and is deprecated.
+
+4.36 KVM_SET_TSS_ADDR
+
+Capability: KVM_CAP_SET_TSS_ADDR
+Architectures: x86
+Type: vm ioctl
+Parameters: unsigned long tss_address (in)
+Returns: 0 on success, -1 on error
+
+This ioctl defines the physical address of a three-page region in the guest
+physical address space.  The region must be within the first 4GB of the
+guest physical address space and must not conflict with any memory slot
+or any mmio address.  The guest may malfunction if it accesses this memory
+region.
+
+This ioctl is required on Intel-based hosts.  This is needed on Intel hardware
+because of a quirk in the virtualization implementation (see the internals
+documentation when it pops into existence).
+
+4.37 KVM_ENABLE_CAP
+
+Capability: KVM_CAP_ENABLE_CAP
+Architectures: ppc
+Type: vcpu ioctl
+Parameters: struct kvm_enable_cap (in)
+Returns: 0 on success; -1 on error
+
++Not all extensions are enabled by default. Using this ioctl the application
+can enable an extension, making it available to the guest.
+
+On systems that do not support this ioctl, it always fails. On systems that
+do support it, it only works for extensions that are supported for enablement.
+
+To check if a capability can be enabled, the KVM_CHECK_EXTENSION ioctl should
+be used.
+
+struct kvm_enable_cap {
+       /* in */
+       __u32 cap;
+
+The capability that is supposed to get enabled.
+
+       __u32 flags;
+
+A bitfield indicating future enhancements. Has to be 0 for now.
+
+       __u64 args[4];
+
+Arguments for enabling a feature. If a feature needs initial values to
+function properly, this is the place to put them.
+
+       __u8  pad[64];
+};
+
+4.38 KVM_GET_MP_STATE
+
+Capability: KVM_CAP_MP_STATE
+Architectures: x86, ia64
+Type: vcpu ioctl
+Parameters: struct kvm_mp_state (out)
+Returns: 0 on success; -1 on error
+
+struct kvm_mp_state {
+	__u32 mp_state;
+};
+
+Returns the vcpu's current "multiprocessing state" (though also valid on
+uniprocessor guests).
+
+Possible values are:
+
+ - KVM_MP_STATE_RUNNABLE:        the vcpu is currently running
+ - KVM_MP_STATE_UNINITIALIZED:   the vcpu is an application processor (AP)
+                                 which has not yet received an INIT signal
+ - KVM_MP_STATE_INIT_RECEIVED:   the vcpu has received an INIT signal, and is
+                                 now ready for a SIPI
+ - KVM_MP_STATE_HALTED:          the vcpu has executed a HLT instruction and
+                                 is waiting for an interrupt
+ - KVM_MP_STATE_SIPI_RECEIVED:   the vcpu has just received a SIPI (vector
+                                 accessible via KVM_GET_VCPU_EVENTS)
+
+This ioctl is only useful after KVM_CREATE_IRQCHIP.  Without an in-kernel
+irqchip, the multiprocessing state must be maintained by userspace.
+
+4.39 KVM_SET_MP_STATE
+
+Capability: KVM_CAP_MP_STATE
+Architectures: x86, ia64
+Type: vcpu ioctl
+Parameters: struct kvm_mp_state (in)
+Returns: 0 on success; -1 on error
+
+Sets the vcpu's current "multiprocessing state"; see KVM_GET_MP_STATE for
+arguments.
+
+This ioctl is only useful after KVM_CREATE_IRQCHIP.  Without an in-kernel
+irqchip, the multiprocessing state must be maintained by userspace.
+
+4.40 KVM_SET_IDENTITY_MAP_ADDR
+
+Capability: KVM_CAP_SET_IDENTITY_MAP_ADDR
+Architectures: x86
+Type: vm ioctl
+Parameters: unsigned long identity (in)
+Returns: 0 on success, -1 on error
+
+This ioctl defines the physical address of a one-page region in the guest
+physical address space.  The region must be within the first 4GB of the
+guest physical address space and must not conflict with any memory slot
+or any mmio address.  The guest may malfunction if it accesses this memory
+region.
+
+This ioctl is required on Intel-based hosts.  This is needed on Intel hardware
+because of a quirk in the virtualization implementation (see the internals
+documentation when it pops into existence).
+
+4.41 KVM_SET_BOOT_CPU_ID
+
+Capability: KVM_CAP_SET_BOOT_CPU_ID
+Architectures: x86, ia64
+Type: vm ioctl
+Parameters: unsigned long vcpu_id
+Returns: 0 on success, -1 on error
+
+Define which vcpu is the Bootstrap Processor (BSP).  Values are the same
+as the vcpu id in KVM_CREATE_VCPU.  If this ioctl is not called, the default
+is vcpu 0.
+
+4.42 KVM_GET_XSAVE
+
+Capability: KVM_CAP_XSAVE
+Architectures: x86
+Type: vcpu ioctl
+Parameters: struct kvm_xsave (out)
+Returns: 0 on success, -1 on error
+
+struct kvm_xsave {
+	__u32 region[1024];
+};
+
+This ioctl would copy current vcpu's xsave struct to the userspace.
+
+4.43 KVM_SET_XSAVE
+
+Capability: KVM_CAP_XSAVE
+Architectures: x86
+Type: vcpu ioctl
+Parameters: struct kvm_xsave (in)
+Returns: 0 on success, -1 on error
+
+struct kvm_xsave {
+	__u32 region[1024];
+};
+
+This ioctl would copy userspace's xsave struct to the kernel.
+
+4.44 KVM_GET_XCRS
+
+Capability: KVM_CAP_XCRS
+Architectures: x86
+Type: vcpu ioctl
+Parameters: struct kvm_xcrs (out)
+Returns: 0 on success, -1 on error
+
+struct kvm_xcr {
+	__u32 xcr;
+	__u32 reserved;
+	__u64 value;
+};
+
+struct kvm_xcrs {
+	__u32 nr_xcrs;
+	__u32 flags;
+	struct kvm_xcr xcrs[KVM_MAX_XCRS];
+	__u64 padding[16];
+};
+
+This ioctl would copy current vcpu's xcrs to the userspace.
+
+4.45 KVM_SET_XCRS
+
+Capability: KVM_CAP_XCRS
+Architectures: x86
+Type: vcpu ioctl
+Parameters: struct kvm_xcrs (in)
+Returns: 0 on success, -1 on error
+
+struct kvm_xcr {
+	__u32 xcr;
+	__u32 reserved;
+	__u64 value;
+};
+
+struct kvm_xcrs {
+	__u32 nr_xcrs;
+	__u32 flags;
+	struct kvm_xcr xcrs[KVM_MAX_XCRS];
+	__u64 padding[16];
+};
+
+This ioctl would set vcpu's xcr to the value userspace specified.
+
+4.46 KVM_GET_SUPPORTED_CPUID
+
+Capability: KVM_CAP_EXT_CPUID
+Architectures: x86
+Type: system ioctl
+Parameters: struct kvm_cpuid2 (in/out)
+Returns: 0 on success, -1 on error
+
+struct kvm_cpuid2 {
+	__u32 nent;
+	__u32 padding;
+	struct kvm_cpuid_entry2 entries[0];
+};
+
+#define KVM_CPUID_FLAG_SIGNIFCANT_INDEX 1
+#define KVM_CPUID_FLAG_STATEFUL_FUNC    2
+#define KVM_CPUID_FLAG_STATE_READ_NEXT  4
+
+struct kvm_cpuid_entry2 {
+	__u32 function;
+	__u32 index;
+	__u32 flags;
+	__u32 eax;
+	__u32 ebx;
+	__u32 ecx;
+	__u32 edx;
+	__u32 padding[3];
+};
+
+This ioctl returns x86 cpuid features which are supported by both the hardware
+and kvm.  Userspace can use the information returned by this ioctl to
+construct cpuid information (for KVM_SET_CPUID2) that is consistent with
+hardware, kernel, and userspace capabilities, and with user requirements (for
+example, the user may wish to constrain cpuid to emulate older hardware,
+or for feature consistency across a cluster).
+
+Userspace invokes KVM_GET_SUPPORTED_CPUID by passing a kvm_cpuid2 structure
+with the 'nent' field indicating the number of entries in the variable-size
+array 'entries'.  If the number of entries is too low to describe the cpu
+capabilities, an error (E2BIG) is returned.  If the number is too high,
+the 'nent' field is adjusted and an error (ENOMEM) is returned.  If the
+number is just right, the 'nent' field is adjusted to the number of valid
+entries in the 'entries' array, which is then filled.
+
+The entries returned are the host cpuid as returned by the cpuid instruction,
+with unknown or unsupported features masked out.  Some features (for example,
+x2apic), may not be present in the host cpu, but are exposed by kvm if it can
+emulate them efficiently. The fields in each entry are defined as follows:
+
+  function: the eax value used to obtain the entry
+  index: the ecx value used to obtain the entry (for entries that are
+         affected by ecx)
+  flags: an OR of zero or more of the following:
+        KVM_CPUID_FLAG_SIGNIFCANT_INDEX:
+           if the index field is valid
+        KVM_CPUID_FLAG_STATEFUL_FUNC:
+           if cpuid for this function returns different values for successive
+           invocations; there will be several entries with the same function,
+           all with this flag set
+        KVM_CPUID_FLAG_STATE_READ_NEXT:
+           for KVM_CPUID_FLAG_STATEFUL_FUNC entries, set if this entry is
+           the first entry to be read by a cpu
+   eax, ebx, ecx, edx: the values returned by the cpuid instruction for
+         this function/index combination
+
+4.47 KVM_PPC_GET_PVINFO
+
+Capability: KVM_CAP_PPC_GET_PVINFO
+Architectures: ppc
+Type: vm ioctl
+Parameters: struct kvm_ppc_pvinfo (out)
+Returns: 0 on success, !0 on error
+
+struct kvm_ppc_pvinfo {
+	__u32 flags;
+	__u32 hcall[4];
+	__u8  pad[108];
+};
+
+This ioctl fetches PV specific information that need to be passed to the guest
+using the device tree or other means from vm context.
+
+For now the only implemented piece of information distributed here is an array
+of 4 instructions that make up a hypercall.
+
+If any additional field gets added to this structure later on, a bit for that
+additional piece of information will be set in the flags bitmap.
+
+4.48 KVM_ASSIGN_PCI_DEVICE
+
+Capability: KVM_CAP_DEVICE_ASSIGNMENT
+Architectures: x86 ia64
+Type: vm ioctl
+Parameters: struct kvm_assigned_pci_dev (in)
+Returns: 0 on success, -1 on error
+
+Assigns a host PCI device to the VM.
+
+struct kvm_assigned_pci_dev {
+	__u32 assigned_dev_id;
+	__u32 busnr;
+	__u32 devfn;
+	__u32 flags;
+	__u32 segnr;
+	union {
+		__u32 reserved[11];
+	};
+};
+
+The PCI device is specified by the triple segnr, busnr, and devfn.
+Identification in succeeding service requests is done via assigned_dev_id. The
+following flags are specified:
+
+/* Depends on KVM_CAP_IOMMU */
+#define KVM_DEV_ASSIGN_ENABLE_IOMMU	(1 << 0)
+
+4.49 KVM_DEASSIGN_PCI_DEVICE
+
+Capability: KVM_CAP_DEVICE_DEASSIGNMENT
+Architectures: x86 ia64
+Type: vm ioctl
+Parameters: struct kvm_assigned_pci_dev (in)
+Returns: 0 on success, -1 on error
+
+Ends PCI device assignment, releasing all associated resources.
+
+See KVM_CAP_DEVICE_ASSIGNMENT for the data structure. Only assigned_dev_id is
+used in kvm_assigned_pci_dev to identify the device.
+
+4.50 KVM_ASSIGN_DEV_IRQ
+
+Capability: KVM_CAP_ASSIGN_DEV_IRQ
+Architectures: x86 ia64
+Type: vm ioctl
+Parameters: struct kvm_assigned_irq (in)
+Returns: 0 on success, -1 on error
+
+Assigns an IRQ to a passed-through device.
+
+struct kvm_assigned_irq {
+	__u32 assigned_dev_id;
+	__u32 host_irq;
+	__u32 guest_irq;
+	__u32 flags;
+	union {
+		struct {
+			__u32 addr_lo;
+			__u32 addr_hi;
+			__u32 data;
+		} guest_msi;
+		__u32 reserved[12];
+	};
+};
+
+The following flags are defined:
+
+#define KVM_DEV_IRQ_HOST_INTX    (1 << 0)
+#define KVM_DEV_IRQ_HOST_MSI     (1 << 1)
+#define KVM_DEV_IRQ_HOST_MSIX    (1 << 2)
+
+#define KVM_DEV_IRQ_GUEST_INTX   (1 << 8)
+#define KVM_DEV_IRQ_GUEST_MSI    (1 << 9)
+#define KVM_DEV_IRQ_GUEST_MSIX   (1 << 10)
+
+It is not valid to specify multiple types per host or guest IRQ. However, the
+IRQ type of host and guest can differ or can even be null.
+
+4.51 KVM_DEASSIGN_DEV_IRQ
+
+Capability: KVM_CAP_ASSIGN_DEV_IRQ
+Architectures: x86 ia64
+Type: vm ioctl
+Parameters: struct kvm_assigned_irq (in)
+Returns: 0 on success, -1 on error
+
+Ends an IRQ assignment to a passed-through device.
+
+See KVM_ASSIGN_DEV_IRQ for the data structure. The target device is specified
+by assigned_dev_id, flags must correspond to the IRQ type specified on
+KVM_ASSIGN_DEV_IRQ. Partial deassignment of host or guest IRQ is allowed.
+
+4.52 KVM_SET_GSI_ROUTING
+
+Capability: KVM_CAP_IRQ_ROUTING
+Architectures: x86 ia64
+Type: vm ioctl
+Parameters: struct kvm_irq_routing (in)
+Returns: 0 on success, -1 on error
+
+Sets the GSI routing table entries, overwriting any previously set entries.
+
+struct kvm_irq_routing {
+	__u32 nr;
+	__u32 flags;
+	struct kvm_irq_routing_entry entries[0];
+};
+
+No flags are specified so far, the corresponding field must be set to zero.
+
+struct kvm_irq_routing_entry {
+	__u32 gsi;
+	__u32 type;
+	__u32 flags;
+	__u32 pad;
+	union {
+		struct kvm_irq_routing_irqchip irqchip;
+		struct kvm_irq_routing_msi msi;
+		__u32 pad[8];
+	} u;
+};
+
+/* gsi routing entry types */
+#define KVM_IRQ_ROUTING_IRQCHIP 1
+#define KVM_IRQ_ROUTING_MSI 2
+
+No flags are specified so far, the corresponding field must be set to zero.
+
+struct kvm_irq_routing_irqchip {
+	__u32 irqchip;
+	__u32 pin;
+};
+
+struct kvm_irq_routing_msi {
+	__u32 address_lo;
+	__u32 address_hi;
+	__u32 data;
+	__u32 pad;
+};
+
+4.53 KVM_ASSIGN_SET_MSIX_NR
+
+Capability: KVM_CAP_DEVICE_MSIX
+Architectures: x86 ia64
+Type: vm ioctl
+Parameters: struct kvm_assigned_msix_nr (in)
+Returns: 0 on success, -1 on error
+
+Set the number of MSI-X interrupts for an assigned device. This service can
+only be called once in the lifetime of an assigned device.
+
+struct kvm_assigned_msix_nr {
+	__u32 assigned_dev_id;
+	__u16 entry_nr;
+	__u16 padding;
+};
+
+#define KVM_MAX_MSIX_PER_DEV		256
+
+4.54 KVM_ASSIGN_SET_MSIX_ENTRY
+
+Capability: KVM_CAP_DEVICE_MSIX
+Architectures: x86 ia64
+Type: vm ioctl
+Parameters: struct kvm_assigned_msix_entry (in)
+Returns: 0 on success, -1 on error
+
+Specifies the routing of an MSI-X assigned device interrupt to a GSI. Setting
+the GSI vector to zero means disabling the interrupt.
+
+struct kvm_assigned_msix_entry {
+	__u32 assigned_dev_id;
+	__u32 gsi;
+	__u16 entry; /* The index of entry in the MSI-X table */
+	__u16 padding[3];
+};
+
+4.54 KVM_SET_TSC_KHZ
+
+Capability: KVM_CAP_TSC_CONTROL
+Architectures: x86
+Type: vcpu ioctl
+Parameters: virtual tsc_khz
+Returns: 0 on success, -1 on error
+
+Specifies the tsc frequency for the virtual machine. The unit of the
+frequency is KHz.
+
+4.55 KVM_GET_TSC_KHZ
+
+Capability: KVM_CAP_GET_TSC_KHZ
+Architectures: x86
+Type: vcpu ioctl
+Parameters: none
+Returns: virtual tsc-khz on success, negative value on error
+
+Returns the tsc frequency of the guest. The unit of the return value is
+KHz. If the host has unstable tsc this ioctl returns -EIO instead as an
+error.
+
+5. The kvm_run structure
+
+Application code obtains a pointer to the kvm_run structure by
+mmap()ing a vcpu fd.  From that point, application code can control
+execution by changing fields in kvm_run prior to calling the KVM_RUN
+ioctl, and obtain information about the reason KVM_RUN returned by
+looking up structure members.
+
+struct kvm_run {
+	/* in */
+	__u8 request_interrupt_window;
+
+Request that KVM_RUN return when it becomes possible to inject external
+interrupts into the guest.  Useful in conjunction with KVM_INTERRUPT.
+
+	__u8 padding1[7];
+
+	/* out */
+	__u32 exit_reason;
+
+When KVM_RUN has returned successfully (return value 0), this informs
+application code why KVM_RUN has returned.  Allowable values for this
+field are detailed below.
+
+	__u8 ready_for_interrupt_injection;
+
+If request_interrupt_window has been specified, this field indicates
+an interrupt can be injected now with KVM_INTERRUPT.
+
+	__u8 if_flag;
+
+The value of the current interrupt flag.  Only valid if in-kernel
+local APIC is not used.
+
+	__u8 padding2[2];
+
+	/* in (pre_kvm_run), out (post_kvm_run) */
+	__u64 cr8;
+
+The value of the cr8 register.  Only valid if in-kernel local APIC is
+not used.  Both input and output.
+
+	__u64 apic_base;
+
+The value of the APIC BASE msr.  Only valid if in-kernel local
+APIC is not used.  Both input and output.
+
+	union {
+		/* KVM_EXIT_UNKNOWN */
+		struct {
+			__u64 hardware_exit_reason;
+		} hw;
+
+If exit_reason is KVM_EXIT_UNKNOWN, the vcpu has exited due to unknown
+reasons.  Further architecture-specific information is available in
+hardware_exit_reason.
+
+		/* KVM_EXIT_FAIL_ENTRY */
+		struct {
+			__u64 hardware_entry_failure_reason;
+		} fail_entry;
+
+If exit_reason is KVM_EXIT_FAIL_ENTRY, the vcpu could not be run due
+to unknown reasons.  Further architecture-specific information is
+available in hardware_entry_failure_reason.
+
+		/* KVM_EXIT_EXCEPTION */
+		struct {
+			__u32 exception;
+			__u32 error_code;
+		} ex;
+
+Unused.
+
+		/* KVM_EXIT_IO */
+		struct {
+#define KVM_EXIT_IO_IN  0
+#define KVM_EXIT_IO_OUT 1
+			__u8 direction;
+			__u8 size; /* bytes */
+			__u16 port;
+			__u32 count;
+			__u64 data_offset; /* relative to kvm_run start */
+		} io;
+
+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 packed array.
+
+		struct {
+			struct kvm_debug_exit_arch arch;
+		} debug;
+
+Unused.
+
+		/* KVM_EXIT_MMIO */
+		struct {
+			__u64 phys_addr;
+			__u8  data[8];
+			__u32 len;
+			__u8  is_write;
+		} mmio;
+
+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.
+
+NOTE: For KVM_EXIT_IO, KVM_EXIT_MMIO and KVM_EXIT_OSI, the corresponding
+operations are complete (and guest state is consistent) only after userspace
+has re-entered the kernel with KVM_RUN.  The kernel side will first finish
+incomplete operations and then check for pending signals.  Userspace
+can re-enter the guest with an unmasked signal pending to complete
+pending operations.
+
+		/* KVM_EXIT_HYPERCALL */
+		struct {
+			__u64 nr;
+			__u64 args[6];
+			__u64 ret;
+			__u32 longmode;
+			__u32 pad;
+		} hypercall;
+
+Unused.  This was once used for 'hypercall to userspace'.  To implement
+such functionality, use KVM_EXIT_IO (x86) or KVM_EXIT_MMIO (all except s390).
+Note KVM_EXIT_IO is significantly faster than KVM_EXIT_MMIO.
+
+		/* KVM_EXIT_TPR_ACCESS */
+		struct {
+			__u64 rip;
+			__u32 is_write;
+			__u32 pad;
+		} tpr_access;
+
+To be documented (KVM_TPR_ACCESS_REPORTING).
+
+		/* KVM_EXIT_S390_SIEIC */
+		struct {
+			__u8 icptcode;
+			__u64 mask; /* psw upper half */
+			__u64 addr; /* psw lower half */
+			__u16 ipa;
+			__u32 ipb;
+		} s390_sieic;
+
+s390 specific.
+
+		/* KVM_EXIT_S390_RESET */
+#define KVM_S390_RESET_POR       1
+#define KVM_S390_RESET_CLEAR     2
+#define KVM_S390_RESET_SUBSYSTEM 4
+#define KVM_S390_RESET_CPU_INIT  8
+#define KVM_S390_RESET_IPL       16
+		__u64 s390_reset_flags;
+
+s390 specific.
+
+		/* KVM_EXIT_DCR */
+		struct {
+			__u32 dcrn;
+			__u32 data;
+			__u8  is_write;
+		} dcr;
+
+powerpc specific.
+
+		/* KVM_EXIT_OSI */
+		struct {
+			__u64 gprs[32];
+		} osi;
+
+MOL uses a special hypercall interface it calls 'OSI'. To enable it, we catch
+hypercalls and exit with this exit struct that contains all the guest gprs.
+
+If exit_reason is KVM_EXIT_OSI, then the vcpu has triggered such a hypercall.
+Userspace can now handle the hypercall and when it's done modify the gprs as
+necessary. Upon guest entry all guest GPRs will then be replaced by the values
+in this struct.
+
+		/* Fix the size of the union. */
+		char padding[256];
+	};
+};
diff -druN linux-2.6.39-libre/Documentation/virtual/kvm/cpuid.txt linux-3.0-rc7-libre/Documentation/virtual/kvm/cpuid.txt
--- linux-2.6.39-libre/Documentation/virtual/kvm/cpuid.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/Documentation/virtual/kvm/cpuid.txt	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,45 @@
+KVM CPUID bits
+Glauber Costa <glommer@redhat.com>, Red Hat Inc, 2010
+=====================================================
+
+A guest running on a kvm host, can check some of its features using
+cpuid. This is not always guaranteed to work, since userspace can
+mask-out some, or even all KVM-related cpuid features before launching
+a guest.
+
+KVM cpuid functions are:
+
+function: KVM_CPUID_SIGNATURE (0x40000000)
+returns : eax = 0,
+          ebx = 0x4b4d564b,
+          ecx = 0x564b4d56,
+          edx = 0x4d.
+Note that this value in ebx, ecx and edx corresponds to the string "KVMKVMKVM".
+This function queries the presence of KVM cpuid leafs.
+
+
+function: define KVM_CPUID_FEATURES (0x40000001)
+returns : ebx, ecx, edx = 0
+          eax = and OR'ed group of (1 << flag), where each flags is:
+
+
+flag                               || value || meaning
+=============================================================================
+KVM_FEATURE_CLOCKSOURCE            ||     0 || kvmclock available at msrs
+                                   ||       || 0x11 and 0x12.
+------------------------------------------------------------------------------
+KVM_FEATURE_NOP_IO_DELAY           ||     1 || not necessary to perform delays
+                                   ||       || on PIO operations.
+------------------------------------------------------------------------------
+KVM_FEATURE_MMU_OP                 ||     2 || deprecated.
+------------------------------------------------------------------------------
+KVM_FEATURE_CLOCKSOURCE2           ||     3 || kvmclock available at msrs
+                                   ||       || 0x4b564d00 and 0x4b564d01
+------------------------------------------------------------------------------
+KVM_FEATURE_ASYNC_PF               ||     4 || async pf can be enabled by
+                                   ||       || writing to msr 0x4b564d02
+------------------------------------------------------------------------------
+KVM_FEATURE_CLOCKSOURCE_STABLE_BIT ||    24 || host will warn if no guest-side
+                                   ||       || per-cpu warps are expected in
+                                   ||       || kvmclock.
+------------------------------------------------------------------------------
diff -druN linux-2.6.39-libre/Documentation/virtual/kvm/locking.txt linux-3.0-rc7-libre/Documentation/virtual/kvm/locking.txt
--- linux-2.6.39-libre/Documentation/virtual/kvm/locking.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/Documentation/virtual/kvm/locking.txt	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,25 @@
+KVM Lock Overview
+=================
+
+1. Acquisition Orders
+---------------------
+
+(to be written)
+
+2. Reference
+------------
+
+Name:		kvm_lock
+Type:		raw_spinlock
+Arch:		any
+Protects:	- vm_list
+		- hardware virtualization enable/disable
+Comment:	'raw' because hardware enabling/disabling must be atomic /wrt
+		migration.
+
+Name:		kvm_arch::tsc_write_lock
+Type:		raw_spinlock
+Arch:		x86
+Protects:	- kvm_arch::{last_tsc_write,last_tsc_nsec,last_tsc_offset}
+		- tsc offset in vmcb
+Comment:	'raw' because updating the tsc offsets must not be preempted.
diff -druN linux-2.6.39-libre/Documentation/virtual/kvm/mmu.txt linux-3.0-rc7-libre/Documentation/virtual/kvm/mmu.txt
--- linux-2.6.39-libre/Documentation/virtual/kvm/mmu.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/Documentation/virtual/kvm/mmu.txt	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,348 @@
+The x86 kvm shadow mmu
+======================
+
+The mmu (in arch/x86/kvm, files mmu.[ch] and paging_tmpl.h) is responsible
+for presenting a standard x86 mmu to the guest, while translating guest
+physical addresses to host physical addresses.
+
+The mmu code attempts to satisfy the following requirements:
+
+- correctness: the guest should not be able to determine that it is running
+               on an emulated mmu except for timing (we attempt to comply
+               with the specification, not emulate the characteristics of
+               a particular implementation such as tlb size)
+- security:    the guest must not be able to touch host memory not assigned
+               to it
+- performance: minimize the performance penalty imposed by the mmu
+- scaling:     need to scale to large memory and large vcpu guests
+- hardware:    support the full range of x86 virtualization hardware
+- integration: Linux memory management code must be in control of guest memory
+               so that swapping, page migration, page merging, transparent
+               hugepages, and similar features work without change
+- dirty tracking: report writes to guest memory to enable live migration
+               and framebuffer-based displays
+- footprint:   keep the amount of pinned kernel memory low (most memory
+               should be shrinkable)
+- reliability:  avoid multipage or GFP_ATOMIC allocations
+
+Acronyms
+========
+
+pfn   host page frame number
+hpa   host physical address
+hva   host virtual address
+gfn   guest frame number
+gpa   guest physical address
+gva   guest virtual address
+ngpa  nested guest physical address
+ngva  nested guest virtual address
+pte   page table entry (used also to refer generically to paging structure
+      entries)
+gpte  guest pte (referring to gfns)
+spte  shadow pte (referring to pfns)
+tdp   two dimensional paging (vendor neutral term for NPT and EPT)
+
+Virtual and real hardware supported
+===================================
+
+The mmu supports first-generation mmu hardware, which allows an atomic switch
+of the current paging mode and cr3 during guest entry, as well as
+two-dimensional paging (AMD's NPT and Intel's EPT).  The emulated hardware
+it exposes is the traditional 2/3/4 level x86 mmu, with support for global
+pages, pae, pse, pse36, cr0.wp, and 1GB pages.  Work is in progress to support
+exposing NPT capable hardware on NPT capable hosts.
+
+Translation
+===========
+
+The primary job of the mmu is to program the processor's mmu to translate
+addresses for the guest.  Different translations are required at different
+times:
+
+- when guest paging is disabled, we translate guest physical addresses to
+  host physical addresses (gpa->hpa)
+- when guest paging is enabled, we translate guest virtual addresses, to
+  guest physical addresses, to host physical addresses (gva->gpa->hpa)
+- when the guest launches a guest of its own, we translate nested guest
+  virtual addresses, to nested guest physical addresses, to guest physical
+  addresses, to host physical addresses (ngva->ngpa->gpa->hpa)
+
+The primary challenge is to encode between 1 and 3 translations into hardware
+that support only 1 (traditional) and 2 (tdp) translations.  When the
+number of required translations matches the hardware, the mmu operates in
+direct mode; otherwise it operates in shadow mode (see below).
+
+Memory
+======
+
+Guest memory (gpa) is part of the user address space of the process that is
+using kvm.  Userspace defines the translation between guest addresses and user
+addresses (gpa->hva); note that two gpas may alias to the same hva, but not
+vice versa.
+
+These hvas may be backed using any method available to the host: anonymous
+memory, file backed memory, and device memory.  Memory might be paged by the
+host at any time.
+
+Events
+======
+
+The mmu is driven by events, some from the guest, some from the host.
+
+Guest generated events:
+- writes to control registers (especially cr3)
+- invlpg/invlpga instruction execution
+- access to missing or protected translations
+
+Host generated events:
+- changes in the gpa->hpa translation (either through gpa->hva changes or
+  through hva->hpa changes)
+- memory pressure (the shrinker)
+
+Shadow pages
+============
+
+The principal data structure is the shadow page, 'struct kvm_mmu_page'.  A
+shadow page contains 512 sptes, which can be either leaf or nonleaf sptes.  A
+shadow page may contain a mix of leaf and nonleaf sptes.
+
+A nonleaf spte allows the hardware mmu to reach the leaf pages and
+is not related to a translation directly.  It points to other shadow pages.
+
+A leaf spte corresponds to either one or two translations encoded into
+one paging structure entry.  These are always the lowest level of the
+translation stack, with optional higher level translations left to NPT/EPT.
+Leaf ptes point at guest pages.
+
+The following table shows translations encoded by leaf ptes, with higher-level
+translations in parentheses:
+
+ Non-nested guests:
+  nonpaging:     gpa->hpa
+  paging:        gva->gpa->hpa
+  paging, tdp:   (gva->)gpa->hpa
+ Nested guests:
+  non-tdp:       ngva->gpa->hpa  (*)
+  tdp:           (ngva->)ngpa->gpa->hpa
+
+(*) the guest hypervisor will encode the ngva->gpa translation into its page
+    tables if npt is not present
+
+Shadow pages contain the following information:
+  role.level:
+    The level in the shadow paging hierarchy that this shadow page belongs to.
+    1=4k sptes, 2=2M sptes, 3=1G sptes, etc.
+  role.direct:
+    If set, leaf sptes reachable from this page are for a linear range.
+    Examples include real mode translation, large guest pages backed by small
+    host pages, and gpa->hpa translations when NPT or EPT is active.
+    The linear range starts at (gfn << PAGE_SHIFT) and its size is determined
+    by role.level (2MB for first level, 1GB for second level, 0.5TB for third
+    level, 256TB for fourth level)
+    If clear, this page corresponds to a guest page table denoted by the gfn
+    field.
+  role.quadrant:
+    When role.cr4_pae=0, the guest uses 32-bit gptes while the host uses 64-bit
+    sptes.  That means a guest page table contains more ptes than the host,
+    so multiple shadow pages are needed to shadow one guest page.
+    For first-level shadow pages, role.quadrant can be 0 or 1 and denotes the
+    first or second 512-gpte block in the guest page table.  For second-level
+    page tables, each 32-bit gpte is converted to two 64-bit sptes
+    (since each first-level guest page is shadowed by two first-level
+    shadow pages) so role.quadrant takes values in the range 0..3.  Each
+    quadrant maps 1GB virtual address space.
+  role.access:
+    Inherited guest access permissions in the form uwx.  Note execute
+    permission is positive, not negative.
+  role.invalid:
+    The page is invalid and should not be used.  It is a root page that is
+    currently pinned (by a cpu hardware register pointing to it); once it is
+    unpinned it will be destroyed.
+  role.cr4_pae:
+    Contains the value of cr4.pae for which the page is valid (e.g. whether
+    32-bit or 64-bit gptes are in use).
+  role.nxe:
+    Contains the value of efer.nxe for which the page is valid.
+  role.cr0_wp:
+    Contains the value of cr0.wp for which the page is valid.
+  gfn:
+    Either the guest page table containing the translations shadowed by this
+    page, or the base page frame for linear translations.  See role.direct.
+  spt:
+    A pageful of 64-bit sptes containing the translations for this page.
+    Accessed by both kvm and hardware.
+    The page pointed to by spt will have its page->private pointing back
+    at the shadow page structure.
+    sptes in spt point either at guest pages, or at lower-level shadow pages.
+    Specifically, if sp1 and sp2 are shadow pages, then sp1->spt[n] may point
+    at __pa(sp2->spt).  sp2 will point back at sp1 through parent_pte.
+    The spt array forms a DAG structure with the shadow page as a node, and
+    guest pages as leaves.
+  gfns:
+    An array of 512 guest frame numbers, one for each present pte.  Used to
+    perform a reverse map from a pte to a gfn. When role.direct is set, any
+    element of this array can be calculated from the gfn field when used, in
+    this case, the array of gfns is not allocated. See role.direct and gfn.
+  slot_bitmap:
+    A bitmap containing one bit per memory slot.  If the page contains a pte
+    mapping a page from memory slot n, then bit n of slot_bitmap will be set
+    (if a page is aliased among several slots, then it is not guaranteed that
+    all slots will be marked).
+    Used during dirty logging to avoid scanning a shadow page if none if its
+    pages need tracking.
+  root_count:
+    A counter keeping track of how many hardware registers (guest cr3 or
+    pdptrs) are now pointing at the page.  While this counter is nonzero, the
+    page cannot be destroyed.  See role.invalid.
+  multimapped:
+    Whether there exist multiple sptes pointing at this page.
+  parent_pte/parent_ptes:
+    If multimapped is zero, parent_pte points at the single spte that points at
+    this page's spt.  Otherwise, parent_ptes points at a data structure
+    with a list of parent_ptes.
+  unsync:
+    If true, then the translations in this page may not match the guest's
+    translation.  This is equivalent to the state of the tlb when a pte is
+    changed but before the tlb entry is flushed.  Accordingly, unsync ptes
+    are synchronized when the guest executes invlpg or flushes its tlb by
+    other means.  Valid for leaf pages.
+  unsync_children:
+    How many sptes in the page point at pages that are unsync (or have
+    unsynchronized children).
+  unsync_child_bitmap:
+    A bitmap indicating which sptes in spt point (directly or indirectly) at
+    pages that may be unsynchronized.  Used to quickly locate all unsychronized
+    pages reachable from a given page.
+
+Reverse map
+===========
+
+The mmu maintains a reverse mapping whereby all ptes mapping a page can be
+reached given its gfn.  This is used, for example, when swapping out a page.
+
+Synchronized and unsynchronized pages
+=====================================
+
+The guest uses two events to synchronize its tlb and page tables: tlb flushes
+and page invalidations (invlpg).
+
+A tlb flush means that we need to synchronize all sptes reachable from the
+guest's cr3.  This is expensive, so we keep all guest page tables write
+protected, and synchronize sptes to gptes when a gpte is written.
+
+A special case is when a guest page table is reachable from the current
+guest cr3.  In this case, the guest is obliged to issue an invlpg instruction
+before using the translation.  We take advantage of that by removing write
+protection from the guest page, and allowing the guest to modify it freely.
+We synchronize modified gptes when the guest invokes invlpg.  This reduces
+the amount of emulation we have to do when the guest modifies multiple gptes,
+or when the a guest page is no longer used as a page table and is used for
+random guest data.
+
+As a side effect we have to resynchronize all reachable unsynchronized shadow
+pages on a tlb flush.
+
+
+Reaction to events
+==================
+
+- guest page fault (or npt page fault, or ept violation)
+
+This is the most complicated event.  The cause of a page fault can be:
+
+  - a true guest fault (the guest translation won't allow the access) (*)
+  - access to a missing translation
+  - access to a protected translation
+    - when logging dirty pages, memory is write protected
+    - synchronized shadow pages are write protected (*)
+  - access to untranslatable memory (mmio)
+
+  (*) not applicable in direct mode
+
+Handling a page fault is performed as follows:
+
+ - if needed, walk the guest page tables to determine the guest translation
+   (gva->gpa or ngpa->gpa)
+   - if permissions are insufficient, reflect the fault back to the guest
+ - determine the host page
+   - if this is an mmio request, there is no host page; call the emulator
+     to emulate the instruction instead
+ - walk the shadow page table to find the spte for the translation,
+   instantiating missing intermediate page tables as necessary
+ - try to unsynchronize the page
+   - if successful, we can let the guest continue and modify the gpte
+ - emulate the instruction
+   - if failed, unshadow the page and let the guest continue
+ - update any translations that were modified by the instruction
+
+invlpg handling:
+
+  - walk the shadow page hierarchy and drop affected translations
+  - try to reinstantiate the indicated translation in the hope that the
+    guest will use it in the near future
+
+Guest control register updates:
+
+- mov to cr3
+  - look up new shadow roots
+  - synchronize newly reachable shadow pages
+
+- mov to cr0/cr4/efer
+  - set up mmu context for new paging mode
+  - look up new shadow roots
+  - synchronize newly reachable shadow pages
+
+Host translation updates:
+
+  - mmu notifier called with updated hva
+  - look up affected sptes through reverse map
+  - drop (or update) translations
+
+Emulating cr0.wp
+================
+
+If tdp is not enabled, the host must keep cr0.wp=1 so page write protection
+works for the guest kernel, not guest guest userspace.  When the guest
+cr0.wp=1, this does not present a problem.  However when the guest cr0.wp=0,
+we cannot map the permissions for gpte.u=1, gpte.w=0 to any spte (the
+semantics require allowing any guest kernel access plus user read access).
+
+We handle this by mapping the permissions to two possible sptes, depending
+on fault type:
+
+- kernel write fault: spte.u=0, spte.w=1 (allows full kernel access,
+  disallows user access)
+- read fault: spte.u=1, spte.w=0 (allows full read access, disallows kernel
+  write access)
+
+(user write faults generate a #PF)
+
+Large pages
+===========
+
+The mmu supports all combinations of large and small guest and host pages.
+Supported page sizes include 4k, 2M, 4M, and 1G.  4M pages are treated as
+two separate 2M pages, on both guest and host, since the mmu always uses PAE
+paging.
+
+To instantiate a large spte, four constraints must be satisfied:
+
+- the spte must point to a large host page
+- the guest pte must be a large pte of at least equivalent size (if tdp is
+  enabled, there is no guest pte and this condition is satisified)
+- if the spte will be writeable, the large page frame may not overlap any
+  write-protected pages
+- the guest page must be wholly contained by a single memory slot
+
+To check the last two conditions, the mmu maintains a ->write_count set of
+arrays for each memory slot and large page size.  Every write protected page
+causes its write_count to be incremented, thus preventing instantiation of
+a large spte.  The frames at the end of an unaligned memory slot have
+artificically inflated ->write_counts so they can never be instantiated.
+
+Further reading
+===============
+
+- NPT presentation from KVM Forum 2008
+  http://www.linux-kvm.org/wiki/images/c/c8/KvmForum2008%24kdf2008_21.pdf
+
diff -druN linux-2.6.39-libre/Documentation/virtual/kvm/msr.txt linux-3.0-rc7-libre/Documentation/virtual/kvm/msr.txt
--- linux-2.6.39-libre/Documentation/virtual/kvm/msr.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/Documentation/virtual/kvm/msr.txt	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,187 @@
+KVM-specific MSRs.
+Glauber Costa <glommer@redhat.com>, Red Hat Inc, 2010
+=====================================================
+
+KVM makes use of some custom MSRs to service some requests.
+
+Custom MSRs have a range reserved for them, that goes from
+0x4b564d00 to 0x4b564dff. There are MSRs outside this area,
+but they are deprecated and their use is discouraged.
+
+Custom MSR list
+--------
+
+The current supported Custom MSR list is:
+
+MSR_KVM_WALL_CLOCK_NEW:   0x4b564d00
+
+	data: 4-byte alignment physical address of a memory area which must be
+	in guest RAM. This memory is expected to hold a copy of the following
+	structure:
+
+	struct pvclock_wall_clock {
+		u32   version;
+		u32   sec;
+		u32   nsec;
+	} __attribute__((__packed__));
+
+	whose data will be filled in by the hypervisor. The hypervisor is only
+	guaranteed to update this data at the moment of MSR write.
+	Users that want to reliably query this information more than once have
+	to write more than once to this MSR. Fields have the following meanings:
+
+		version: guest has to check version before and after grabbing
+		time information and check that they are both equal and even.
+		An odd version indicates an in-progress update.
+
+		sec: number of seconds for wallclock.
+
+		nsec: number of nanoseconds for wallclock.
+
+	Note that although MSRs are per-CPU entities, the effect of this
+	particular MSR is global.
+
+	Availability of this MSR must be checked via bit 3 in 0x4000001 cpuid
+	leaf prior to usage.
+
+MSR_KVM_SYSTEM_TIME_NEW:  0x4b564d01
+
+	data: 4-byte aligned physical address of a memory area which must be in
+	guest RAM, plus an enable bit in bit 0. This memory is expected to hold
+	a copy of the following structure:
+
+	struct pvclock_vcpu_time_info {
+		u32   version;
+		u32   pad0;
+		u64   tsc_timestamp;
+		u64   system_time;
+		u32   tsc_to_system_mul;
+		s8    tsc_shift;
+		u8    flags;
+		u8    pad[2];
+	} __attribute__((__packed__)); /* 32 bytes */
+
+	whose data will be filled in by the hypervisor periodically. Only one
+	write, or registration, is needed for each VCPU. The interval between
+	updates of this structure is arbitrary and implementation-dependent.
+	The hypervisor may update this structure at any time it sees fit until
+	anything with bit0 == 0 is written to it.
+
+	Fields have the following meanings:
+
+		version: guest has to check version before and after grabbing
+		time information and check that they are both equal and even.
+		An odd version indicates an in-progress update.
+
+		tsc_timestamp: the tsc value at the current VCPU at the time
+		of the update of this structure. Guests can subtract this value
+		from current tsc to derive a notion of elapsed time since the
+		structure update.
+
+		system_time: a host notion of monotonic time, including sleep
+		time at the time this structure was last updated. Unit is
+		nanoseconds.
+
+		tsc_to_system_mul: a function of the tsc frequency. One has
+		to multiply any tsc-related quantity by this value to get
+		a value in nanoseconds, besides dividing by 2^tsc_shift
+
+		tsc_shift: cycle to nanosecond divider, as a power of two, to
+		allow for shift rights. One has to shift right any tsc-related
+		quantity by this value to get a value in nanoseconds, besides
+		multiplying by tsc_to_system_mul.
+
+		With this information, guests can derive per-CPU time by
+		doing:
+
+			time = (current_tsc - tsc_timestamp)
+			time = (time * tsc_to_system_mul) >> tsc_shift
+			time = time + system_time
+
+		flags: bits in this field indicate extended capabilities
+		coordinated between the guest and the hypervisor. Availability
+		of specific flags has to be checked in 0x40000001 cpuid leaf.
+		Current flags are:
+
+		 flag bit   | cpuid bit    | meaning
+		-------------------------------------------------------------
+			    |	           | time measures taken across
+		     0      |	   24      | multiple cpus are guaranteed to
+			    |		   | be monotonic
+		-------------------------------------------------------------
+
+	Availability of this MSR must be checked via bit 3 in 0x4000001 cpuid
+	leaf prior to usage.
+
+
+MSR_KVM_WALL_CLOCK:  0x11
+
+	data and functioning: same as MSR_KVM_WALL_CLOCK_NEW. Use that instead.
+
+	This MSR falls outside the reserved KVM range and may be removed in the
+	future. Its usage is deprecated.
+
+	Availability of this MSR must be checked via bit 0 in 0x4000001 cpuid
+	leaf prior to usage.
+
+MSR_KVM_SYSTEM_TIME: 0x12
+
+	data and functioning: same as MSR_KVM_SYSTEM_TIME_NEW. Use that instead.
+
+	This MSR falls outside the reserved KVM range and may be removed in the
+	future. Its usage is deprecated.
+
+	Availability of this MSR must be checked via bit 0 in 0x4000001 cpuid
+	leaf prior to usage.
+
+	The suggested algorithm for detecting kvmclock presence is then:
+
+		if (!kvm_para_available())    /* refer to cpuid.txt */
+			return NON_PRESENT;
+
+		flags = cpuid_eax(0x40000001);
+		if (flags & 3) {
+			msr_kvm_system_time = MSR_KVM_SYSTEM_TIME_NEW;
+			msr_kvm_wall_clock = MSR_KVM_WALL_CLOCK_NEW;
+			return PRESENT;
+		} else if (flags & 0) {
+			msr_kvm_system_time = MSR_KVM_SYSTEM_TIME;
+			msr_kvm_wall_clock = MSR_KVM_WALL_CLOCK;
+			return PRESENT;
+		} else
+			return NON_PRESENT;
+
+MSR_KVM_ASYNC_PF_EN: 0x4b564d02
+	data: Bits 63-6 hold 64-byte aligned physical address of a
+	64 byte memory area which must be in guest RAM and must be
+	zeroed. Bits 5-2 are reserved and should be zero. Bit 0 is 1
+	when asynchronous page faults are enabled on the vcpu 0 when
+	disabled. Bit 2 is 1 if asynchronous page faults can be injected
+	when vcpu is in cpl == 0.
+
+	First 4 byte of 64 byte memory location will be written to by
+	the hypervisor at the time of asynchronous page fault (APF)
+	injection to indicate type of asynchronous page fault. Value
+	of 1 means that the page referred to by the page fault is not
+	present. Value 2 means that the page is now available. Disabling
+	interrupt inhibits APFs. Guest must not enable interrupt
+	before the reason is read, or it may be overwritten by another
+	APF. Since APF uses the same exception vector as regular page
+	fault guest must reset the reason to 0 before it does
+	something that can generate normal page fault.  If during page
+	fault APF reason is 0 it means that this is regular page
+	fault.
+
+	During delivery of type 1 APF cr2 contains a token that will
+	be used to notify a guest when missing page becomes
+	available. When page becomes available type 2 APF is sent with
+	cr2 set to the token associated with the page. There is special
+	kind of token 0xffffffff which tells vcpu that it should wake
+	up all processes waiting for APFs and no individual type 2 APFs
+	will be sent.
+
+	If APF is disabled while there are outstanding APFs, they will
+	not be delivered.
+
+	Currently type 2 APF will be always delivered on the same vcpu as
+	type 1 was, but guest should not rely on that.
diff -druN linux-2.6.39-libre/Documentation/virtual/kvm/ppc-pv.txt linux-3.0-rc7-libre/Documentation/virtual/kvm/ppc-pv.txt
--- linux-2.6.39-libre/Documentation/virtual/kvm/ppc-pv.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/Documentation/virtual/kvm/ppc-pv.txt	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,196 @@
+The PPC KVM paravirtual interface
+=================================
+
+The basic execution principle by which KVM on PowerPC works is to run all kernel
+space code in PR=1 which is user space. This way we trap all privileged
+instructions and can emulate them accordingly.
+
+Unfortunately that is also the downfall. There are quite some privileged
+instructions that needlessly return us to the hypervisor even though they
+could be handled differently.
+
+This is what the PPC PV interface helps with. It takes privileged instructions
+and transforms them into unprivileged ones with some help from the hypervisor.
+This cuts down virtualization costs by about 50% on some of my benchmarks.
+
+The code for that interface can be found in arch/powerpc/kernel/kvm*
+
+Querying for existence
+======================
+
+To find out if we're running on KVM or not, we leverage the device tree. When
+Linux is running on KVM, a node /hypervisor exists. That node contains a
+compatible property with the value "linux,kvm".
+
+Once you determined you're running under a PV capable KVM, you can now use
+hypercalls as described below.
+
+KVM hypercalls
+==============
+
+Inside the device tree's /hypervisor node there's a property called
+'hypercall-instructions'. This property contains at most 4 opcodes that make
+up the hypercall. To call a hypercall, just call these instructions.
+
+The parameters are as follows:
+
+	Register	IN			OUT
+
+	r0		-			volatile
+	r3		1st parameter		Return code
+	r4		2nd parameter		1st output value
+	r5		3rd parameter		2nd output value
+	r6		4th parameter		3rd output value
+	r7		5th parameter		4th output value
+	r8		6th parameter		5th output value
+	r9		7th parameter		6th output value
+	r10		8th parameter		7th output value
+	r11		hypercall number	8th output value
+	r12		-			volatile
+
+Hypercall definitions are shared in generic code, so the same hypercall numbers
+apply for x86 and powerpc alike with the exception that each KVM hypercall
+also needs to be ORed with the KVM vendor code which is (42 << 16).
+
+Return codes can be as follows:
+
+	Code		Meaning
+
+	0		Success
+	12		Hypercall not implemented
+	<0		Error
+
+The magic page
+==============
+
+To enable communication between the hypervisor and guest there is a new shared
+page that contains parts of supervisor visible register state. The guest can
+map this shared page using the KVM hypercall KVM_HC_PPC_MAP_MAGIC_PAGE.
+
+With this hypercall issued the guest always gets the magic page mapped at the
+desired location in effective and physical address space. For now, we always
+map the page to -4096. This way we can access it using absolute load and store
+functions. The following instruction reads the first field of the magic page:
+
+	ld	rX, -4096(0)
+
+The interface is designed to be extensible should there be need later to add
+additional registers to the magic page. If you add fields to the magic page,
+also define a new hypercall feature to indicate that the host can give you more
+registers. Only if the host supports the additional features, make use of them.
+
+The magic page has the following layout as described in
+arch/powerpc/include/asm/kvm_para.h:
+
+struct kvm_vcpu_arch_shared {
+	__u64 scratch1;
+	__u64 scratch2;
+	__u64 scratch3;
+	__u64 critical;		/* Guest may not get interrupts if == r1 */
+	__u64 sprg0;
+	__u64 sprg1;
+	__u64 sprg2;
+	__u64 sprg3;
+	__u64 srr0;
+	__u64 srr1;
+	__u64 dar;
+	__u64 msr;
+	__u32 dsisr;
+	__u32 int_pending;	/* Tells the guest if we have an interrupt */
+};
+
+Additions to the page must only occur at the end. Struct fields are always 32
+or 64 bit aligned, depending on them being 32 or 64 bit wide respectively.
+
+Magic page features
+===================
+
+When mapping the magic page using the KVM hypercall KVM_HC_PPC_MAP_MAGIC_PAGE,
+a second return value is passed to the guest. This second return value contains
+a bitmap of available features inside the magic page.
+
+The following enhancements to the magic page are currently available:
+
+  KVM_MAGIC_FEAT_SR		Maps SR registers r/w in the magic page
+
+For enhanced features in the magic page, please check for the existence of the
+feature before using them!
+
+MSR bits
+========
+
+The MSR contains bits that require hypervisor intervention and bits that do
+not require direct hypervisor intervention because they only get interpreted
+when entering the guest or don't have any impact on the hypervisor's behavior.
+
+The following bits are safe to be set inside the guest:
+
+  MSR_EE
+  MSR_RI
+  MSR_CR
+  MSR_ME
+
+If any other bit changes in the MSR, please still use mtmsr(d).
+
+Patched instructions
+====================
+
+The "ld" and "std" instructions are transormed to "lwz" and "stw" instructions
+respectively on 32 bit systems with an added offset of 4 to accommodate for big
+endianness.
+
+The following is a list of mapping the Linux kernel performs when running as
+guest. Implementing any of those mappings is optional, as the instruction traps
+also act on the shared page. So calling privileged instructions still works as
+before.
+
+From			To
+====			==
+
+mfmsr	rX		ld	rX, magic_page->msr
+mfsprg	rX, 0		ld	rX, magic_page->sprg0
+mfsprg	rX, 1		ld	rX, magic_page->sprg1
+mfsprg	rX, 2		ld	rX, magic_page->sprg2
+mfsprg	rX, 3		ld	rX, magic_page->sprg3
+mfsrr0	rX		ld	rX, magic_page->srr0
+mfsrr1	rX		ld	rX, magic_page->srr1
+mfdar	rX		ld	rX, magic_page->dar
+mfdsisr	rX		lwz	rX, magic_page->dsisr
+
+mtmsr	rX		std	rX, magic_page->msr
+mtsprg	0, rX		std	rX, magic_page->sprg0
+mtsprg	1, rX		std	rX, magic_page->sprg1
+mtsprg	2, rX		std	rX, magic_page->sprg2
+mtsprg	3, rX		std	rX, magic_page->sprg3
+mtsrr0	rX		std	rX, magic_page->srr0
+mtsrr1	rX		std	rX, magic_page->srr1
+mtdar	rX		std	rX, magic_page->dar
+mtdsisr	rX		stw	rX, magic_page->dsisr
+
+tlbsync			nop
+
+mtmsrd	rX, 0		b	<special mtmsr section>
+mtmsr	rX		b	<special mtmsr section>
+
+mtmsrd	rX, 1		b	<special mtmsrd section>
+
+[Book3S only]
+mtsrin	rX, rY		b	<special mtsrin section>
+
+[BookE only]
+wrteei	[0|1]		b	<special wrteei section>
+
+
+Some instructions require more logic to determine what's going on than a load
+or store instruction can deliver. To enable patching of those, we keep some
+RAM around where we can live translate instructions to. What happens is the
+following:
+
+	1) copy emulation code to memory
+	2) patch that code to fit the emulated instruction
+	3) patch that code to return to the original pc + 4
+	4) patch the original instruction to branch to the new code
+
+That way we can inject an arbitrary amount of code as replacement for a single
+instruction. This allows us to check for pending interrupts when setting EE=1
+for example.
diff -druN linux-2.6.39-libre/Documentation/virtual/kvm/review-checklist.txt linux-3.0-rc7-libre/Documentation/virtual/kvm/review-checklist.txt
--- linux-2.6.39-libre/Documentation/virtual/kvm/review-checklist.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/Documentation/virtual/kvm/review-checklist.txt	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,38 @@
+Review checklist for kvm patches
+================================
+
+1.  The patch must follow Documentation/CodingStyle and
+    Documentation/SubmittingPatches.
+
+2.  Patches should be against kvm.git master branch.
+
+3.  If the patch introduces or modifies a new userspace API:
+    - the API must be documented in Documentation/virtual/kvm/api.txt
+    - the API must be discoverable using KVM_CHECK_EXTENSION
+
+4.  New state must include support for save/restore.
+
+5.  New features must default to off (userspace should explicitly request them).
+    Performance improvements can and should default to on.
+
+6.  New cpu features should be exposed via KVM_GET_SUPPORTED_CPUID2
+
+7.  Emulator changes should be accompanied by unit tests for qemu-kvm.git
+    kvm/test directory.
+
+8.  Changes should be vendor neutral when possible.  Changes to common code
+    are better than duplicating changes to vendor code.
+
+9.  Similarly, prefer changes to arch independent code than to arch dependent
+    code.
+
+10. User/kernel interfaces and guest/host interfaces must be 64-bit clean
+    (all variables and sizes naturally aligned on 64-bit; use specific types
+    only - u64 rather than ulong).
+
+11. New guest visible features must either be documented in a hardware manual
+    or be accompanied by documentation.
+
+12. Features must be robust against reset and kexec - for example, shared
+    host/guest memory must be unshared to prevent the host from writing to
+    guest memory that the guest has not reserved for this purpose.
diff -druN linux-2.6.39-libre/Documentation/virtual/kvm/timekeeping.txt linux-3.0-rc7-libre/Documentation/virtual/kvm/timekeeping.txt
--- linux-2.6.39-libre/Documentation/virtual/kvm/timekeeping.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/Documentation/virtual/kvm/timekeeping.txt	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,612 @@
+
+	Timekeeping Virtualization for X86-Based Architectures
+
+	Zachary Amsden <zamsden@redhat.com>
+	Copyright (c) 2010, Red Hat.  All rights reserved.
+
+1) Overview
+2) Timing Devices
+3) TSC Hardware
+4) Virtualization Problems
+
+=========================================================================
+
+1) Overview
+
+One of the most complicated parts of the X86 platform, and specifically,
+the virtualization of this platform is the plethora of timing devices available
+and the complexity of emulating those devices.  In addition, virtualization of
+time introduces a new set of challenges because it introduces a multiplexed
+division of time beyond the control of the guest CPU.
+
+First, we will describe the various timekeeping hardware available, then
+present some of the problems which arise and solutions available, giving
+specific recommendations for certain classes of KVM guests.
+
+The purpose of this document is to collect data and information relevant to
+timekeeping which may be difficult to find elsewhere, specifically,
+information relevant to KVM and hardware-based virtualization.
+
+=========================================================================
+
+2) Timing Devices
+
+First we discuss the basic hardware devices available.  TSC and the related
+KVM clock are special enough to warrant a full exposition and are described in
+the following section.
+
+2.1) i8254 - PIT
+
+One of the first timer devices available is the programmable interrupt timer,
+or PIT.  The PIT has a fixed frequency 1.193182 MHz base clock and three
+channels which can be programmed to deliver periodic or one-shot interrupts.
+These three channels can be configured in different modes and have individual
+counters.  Channel 1 and 2 were not available for general use in the original
+IBM PC, and historically were connected to control RAM refresh and the PC
+speaker.  Now the PIT is typically integrated as part of an emulated chipset
+and a separate physical PIT is not used.
+
+The PIT uses I/O ports 0x40 - 0x43.  Access to the 16-bit counters is done
+using single or multiple byte access to the I/O ports.  There are 6 modes
+available, but not all modes are available to all timers, as only timer 2
+has a connected gate input, required for modes 1 and 5.  The gate line is
+controlled by port 61h, bit 0, as illustrated in the following diagram.
+
+ --------------             ----------------
+|              |           |                |
+|  1.1932 MHz  |---------->| CLOCK      OUT | ---------> IRQ 0
+|    Clock     |   |       |                |
+ --------------    |    +->| GATE  TIMER 0  |
+                   |        ----------------
+                   |
+                   |        ----------------
+                   |       |                |
+                   |------>| CLOCK      OUT | ---------> 66.3 KHZ DRAM
+                   |       |                |            (aka /dev/null)
+                   |    +->| GATE  TIMER 1  |
+                   |        ----------------
+                   |
+                   |        ----------------
+                   |       |                |
+                   |------>| CLOCK      OUT | ---------> Port 61h, bit 5
+                           |                |      |
+Port 61h, bit 0 ---------->| GATE  TIMER 2  |       \_.----   ____
+                            ----------------         _|    )--|LPF|---Speaker
+                                                    / *----   \___/
+Port 61h, bit 1 -----------------------------------/
+
+The timer modes are now described.
+
+Mode 0: Single Timeout.   This is a one-shot software timeout that counts down
+ when the gate is high (always true for timers 0 and 1).  When the count
+ reaches zero, the output goes high.
+
+Mode 1: Triggered One-shot.  The output is initially set high.  When the gate
+ line is set high, a countdown is initiated (which does not stop if the gate is
+ lowered), during which the output is set low.  When the count reaches zero,
+ the output goes high.
+
+Mode 2: Rate Generator.  The output is initially set high.  When the countdown
+ reaches 1, the output goes low for one count and then returns high.  The value
+ is reloaded and the countdown automatically resumes.  If the gate line goes
+ low, the count is halted.  If the output is low when the gate is lowered, the
+ output automatically goes high (this only affects timer 2).
+
+Mode 3: Square Wave.   This generates a high / low square wave.  The count
+ determines the length of the pulse, which alternates between high and low
+ when zero is reached.  The count only proceeds when gate is high and is
+ automatically reloaded on reaching zero.  The count is decremented twice at
+ each clock to generate a full high / low cycle at the full periodic rate.
+ If the count is even, the clock remains high for N/2 counts and low for N/2
+ counts; if the clock is odd, the clock is high for (N+1)/2 counts and low
+ for (N-1)/2 counts.  Only even values are latched by the counter, so odd
+ values are not observed when reading.  This is the intended mode for timer 2,
+ which generates sine-like tones by low-pass filtering the square wave output.
+
+Mode 4: Software Strobe.  After programming this mode and loading the counter,
+ the output remains high until the counter reaches zero.  Then the output
+ goes low for 1 clock cycle and returns high.  The counter is not reloaded.
+ Counting only occurs when gate is high.
+
+Mode 5: Hardware Strobe.  After programming and loading the counter, the
+ output remains high.  When the gate is raised, a countdown is initiated
+ (which does not stop if the gate is lowered).  When the counter reaches zero,
+ the output goes low for 1 clock cycle and then returns high.  The counter is
+ not reloaded.
+
+In addition to normal binary counting, the PIT supports BCD counting.  The
+command port, 0x43 is used to set the counter and mode for each of the three
+timers.
+
+PIT commands, issued to port 0x43, using the following bit encoding:
+
+Bit 7-4: Command (See table below)
+Bit 3-1: Mode (000 = Mode 0, 101 = Mode 5, 11X = undefined)
+Bit 0  : Binary (0) / BCD (1)
+
+Command table:
+
+0000 - Latch Timer 0 count for port 0x40
+	sample and hold the count to be read in port 0x40;
+	additional commands ignored until counter is read;
+	mode bits ignored.
+
+0001 - Set Timer 0 LSB mode for port 0x40
+	set timer to read LSB only and force MSB to zero;
+	mode bits set timer mode
+
+0010 - Set Timer 0 MSB mode for port 0x40
+	set timer to read MSB only and force LSB to zero;
+	mode bits set timer mode
+
+0011 - Set Timer 0 16-bit mode for port 0x40
+	set timer to read / write LSB first, then MSB;
+	mode bits set timer mode
+
+0100 - Latch Timer 1 count for port 0x41 - as described above
+0101 - Set Timer 1 LSB mode for port 0x41 - as described above
+0110 - Set Timer 1 MSB mode for port 0x41 - as described above
+0111 - Set Timer 1 16-bit mode for port 0x41 - as described above
+
+1000 - Latch Timer 2 count for port 0x42 - as described above
+1001 - Set Timer 2 LSB mode for port 0x42 - as described above
+1010 - Set Timer 2 MSB mode for port 0x42 - as described above
+1011 - Set Timer 2 16-bit mode for port 0x42 as described above
+
+1101 - General counter latch
+	Latch combination of counters into corresponding ports
+	Bit 3 = Counter 2
+	Bit 2 = Counter 1
+	Bit 1 = Counter 0
+	Bit 0 = Unused
+
+1110 - Latch timer status
+	Latch combination of counter mode into corresponding ports
+	Bit 3 = Counter 2
+	Bit 2 = Counter 1
+	Bit 1 = Counter 0
+
+	The output of ports 0x40-0x42 following this command will be:
+
+	Bit 7 = Output pin
+	Bit 6 = Count loaded (0 if timer has expired)
+	Bit 5-4 = Read / Write mode
+	    01 = MSB only
+	    10 = LSB only
+	    11 = LSB / MSB (16-bit)
+	Bit 3-1 = Mode
+	Bit 0 = Binary (0) / BCD mode (1)
+
+2.2) RTC
+
+The second device which was available in the original PC was the MC146818 real
+time clock.  The original device is now obsolete, and usually emulated by the
+system chipset, sometimes by an HPET and some frankenstein IRQ routing.
+
+The RTC is accessed through CMOS variables, which uses an index register to
+control which bytes are read.  Since there is only one index register, read
+of the CMOS and read of the RTC require lock protection (in addition, it is
+dangerous to allow userspace utilities such as hwclock to have direct RTC
+access, as they could corrupt kernel reads and writes of CMOS memory).
+
+The RTC generates an interrupt which is usually routed to IRQ 8.  The interrupt
+can function as a periodic timer, an additional once a day alarm, and can issue
+interrupts after an update of the CMOS registers by the MC146818 is complete.
+The type of interrupt is signalled in the RTC status registers.
+
+The RTC will update the current time fields by battery power even while the
+system is off.  The current time fields should not be read while an update is
+in progress, as indicated in the status register.
+
+The clock uses a 32.768kHz crystal, so bits 6-4 of register A should be
+programmed to a 32kHz divider if the RTC is to count seconds.
+
+This is the RAM map originally used for the RTC/CMOS:
+
+Location    Size    Description
+------------------------------------------
+00h         byte    Current second (BCD)
+01h         byte    Seconds alarm (BCD)
+02h         byte    Current minute (BCD)
+03h         byte    Minutes alarm (BCD)
+04h         byte    Current hour (BCD)
+05h         byte    Hours alarm (BCD)
+06h         byte    Current day of week (BCD)
+07h         byte    Current day of month (BCD)
+08h         byte    Current month (BCD)
+09h         byte    Current year (BCD)
+0Ah         byte    Register A
+                       bit 7   = Update in progress
+                       bit 6-4 = Divider for clock
+                                  000 = 4.194 MHz
+                                  001 = 1.049 MHz
+                                  010 = 32 kHz
+                                  10X = test modes
+                                  110 = reset / disable
+                                  111 = reset / disable
+                       bit 3-0 = Rate selection for periodic interrupt
+                                  000 = periodic timer disabled
+                                  001 = 3.90625 uS
+                                  010 = 7.8125 uS
+                                  011 = .122070 mS
+                                  100 = .244141 mS
+                                     ...
+                                 1101 = 125 mS
+                                 1110 = 250 mS
+                                 1111 = 500 mS
+0Bh         byte    Register B
+                       bit 7   = Run (0) / Halt (1)
+                       bit 6   = Periodic interrupt enable
+                       bit 5   = Alarm interrupt enable
+                       bit 4   = Update-ended interrupt enable
+                       bit 3   = Square wave interrupt enable
+                       bit 2   = BCD calendar (0) / Binary (1)
+                       bit 1   = 12-hour mode (0) / 24-hour mode (1)
+                       bit 0   = 0 (DST off) / 1 (DST enabled)
+OCh         byte    Register C (read only)
+                       bit 7   = interrupt request flag (IRQF)
+                       bit 6   = periodic interrupt flag (PF)
+                       bit 5   = alarm interrupt flag (AF)
+                       bit 4   = update interrupt flag (UF)
+                       bit 3-0 = reserved
+ODh         byte    Register D (read only)
+                       bit 7   = RTC has power
+                       bit 6-0 = reserved
+32h         byte    Current century BCD (*)
+  (*) location vendor specific and now determined from ACPI global tables
+
+2.3) APIC
+
+On Pentium and later processors, an on-board timer is available to each CPU
+as part of the Advanced Programmable Interrupt Controller.  The APIC is
+accessed through memory-mapped registers and provides interrupt service to each
+CPU, used for IPIs and local timer interrupts.
+
+Although in theory the APIC is a safe and stable source for local interrupts,
+in practice, many bugs and glitches have occurred due to the special nature of
+the APIC CPU-local memory-mapped hardware.  Beware that CPU errata may affect
+the use of the APIC and that workarounds may be required.  In addition, some of
+these workarounds pose unique constraints for virtualization - requiring either
+extra overhead incurred from extra reads of memory-mapped I/O or additional
+functionality that may be more computationally expensive to implement.
+
+Since the APIC is documented quite well in the Intel and AMD manuals, we will
+avoid repetition of the detail here.  It should be pointed out that the APIC
+timer is programmed through the LVT (local vector timer) register, is capable
+of one-shot or periodic operation, and is based on the bus clock divided down
+by the programmable divider register.
+
+2.4) HPET
+
+HPET is quite complex, and was originally intended to replace the PIT / RTC
+support of the X86 PC.  It remains to be seen whether that will be the case, as
+the de facto standard of PC hardware is to emulate these older devices.  Some
+systems designated as legacy free may support only the HPET as a hardware timer
+device.
+
+The HPET spec is rather loose and vague, requiring at least 3 hardware timers,
+but allowing implementation freedom to support many more.  It also imposes no
+fixed rate on the timer frequency, but does impose some extremal values on
+frequency, error and slew.
+
+In general, the HPET is recommended as a high precision (compared to PIT /RTC)
+time source which is independent of local variation (as there is only one HPET
+in any given system).  The HPET is also memory-mapped, and its presence is
+indicated through ACPI tables by the BIOS.
+
+Detailed specification of the HPET is beyond the current scope of this
+document, as it is also very well documented elsewhere.
+
+2.5) Offboard Timers
+
+Several cards, both proprietary (watchdog boards) and commonplace (e1000) have
+timing chips built into the cards which may have registers which are accessible
+to kernel or user drivers.  To the author's knowledge, using these to generate
+a clocksource for a Linux or other kernel has not yet been attempted and is in
+general frowned upon as not playing by the agreed rules of the game.  Such a
+timer device would require additional support to be virtualized properly and is
+not considered important at this time as no known operating system does this.
+
+=========================================================================
+
+3) TSC Hardware
+
+The TSC or time stamp counter is relatively simple in theory; it counts
+instruction cycles issued by the processor, which can be used as a measure of
+time.  In practice, due to a number of problems, it is the most complicated
+timekeeping device to use.
+
+The TSC is represented internally as a 64-bit MSR which can be read with the
+RDMSR, RDTSC, or RDTSCP (when available) instructions.  In the past, hardware
+limitations made it possible to write the TSC, but generally on old hardware it
+was only possible to write the low 32-bits of the 64-bit counter, and the upper
+32-bits of the counter were cleared.  Now, however, on Intel processors family
+0Fh, for models 3, 4 and 6, and family 06h, models e and f, this restriction
+has been lifted and all 64-bits are writable.  On AMD systems, the ability to
+write the TSC MSR is not an architectural guarantee.
+
+The TSC is accessible from CPL-0 and conditionally, for CPL > 0 software by
+means of the CR4.TSD bit, which when enabled, disables CPL > 0 TSC access.
+
+Some vendors have implemented an additional instruction, RDTSCP, which returns
+atomically not just the TSC, but an indicator which corresponds to the
+processor number.  This can be used to index into an array of TSC variables to
+determine offset information in SMP systems where TSCs are not synchronized.
+The presence of this instruction must be determined by consulting CPUID feature
+bits.
+
+Both VMX and SVM provide extension fields in the virtualization hardware which
+allows the guest visible TSC to be offset by a constant.  Newer implementations
+promise to allow the TSC to additionally be scaled, but this hardware is not
+yet widely available.
+
+3.1) TSC synchronization
+
+The TSC is a CPU-local clock in most implementations.  This means, on SMP
+platforms, the TSCs of different CPUs may start at different times depending
+on when the CPUs are powered on.  Generally, CPUs on the same die will share
+the same clock, however, this is not always the case.
+
+The BIOS may attempt to resynchronize the TSCs during the poweron process and
+the operating system or other system software may attempt to do this as well.
+Several hardware limitations make the problem worse - if it is not possible to
+write the full 64-bits of the TSC, it may be impossible to match the TSC in
+newly arriving CPUs to that of the rest of the system, resulting in
+unsynchronized TSCs.  This may be done by BIOS or system software, but in
+practice, getting a perfectly synchronized TSC will not be possible unless all
+values are read from the same clock, which generally only is possible on single
+socket systems or those with special hardware support.
+
+3.2) TSC and CPU hotplug
+
+As touched on already, CPUs which arrive later than the boot time of the system
+may not have a TSC value that is synchronized with the rest of the system.
+Either system software, BIOS, or SMM code may actually try to establish the TSC
+to a value matching the rest of the system, but a perfect match is usually not
+a guarantee.  This can have the effect of bringing a system from a state where
+TSC is synchronized back to a state where TSC synchronization flaws, however
+small, may be exposed to the OS and any virtualization environment.
+
+3.3) TSC and multi-socket / NUMA
+
+Multi-socket systems, especially large multi-socket systems are likely to have
+individual clocksources rather than a single, universally distributed clock.
+Since these clocks are driven by different crystals, they will not have
+perfectly matched frequency, and temperature and electrical variations will
+cause the CPU clocks, and thus the TSCs to drift over time.  Depending on the
+exact clock and bus design, the drift may or may not be fixed in absolute
+error, and may accumulate over time.
+
+In addition, very large systems may deliberately slew the clocks of individual
+cores.  This technique, known as spread-spectrum clocking, reduces EMI at the
+clock frequency and harmonics of it, which may be required to pass FCC
+standards for telecommunications and computer equipment.
+
+It is recommended not to trust the TSCs to remain synchronized on NUMA or
+multiple socket systems for these reasons.
+
+3.4) TSC and C-states
+
+C-states, or idling states of the processor, especially C1E and deeper sleep
+states may be problematic for TSC as well.  The TSC may stop advancing in such
+a state, resulting in a TSC which is behind that of other CPUs when execution
+is resumed.  Such CPUs must be detected and flagged by the operating system
+based on CPU and chipset identifications.
+
+The TSC in such a case may be corrected by catching it up to a known external
+clocksource.
+
+3.5) TSC frequency change / P-states
+
+To make things slightly more interesting, some CPUs may change frequency.  They
+may or may not run the TSC at the same rate, and because the frequency change
+may be staggered or slewed, at some points in time, the TSC rate may not be
+known other than falling within a range of values.  In this case, the TSC will
+not be a stable time source, and must be calibrated against a known, stable,
+external clock to be a usable source of time.
+
+Whether the TSC runs at a constant rate or scales with the P-state is model
+dependent and must be determined by inspecting CPUID, chipset or vendor
+specific MSR fields.
+
+In addition, some vendors have known bugs where the P-state is actually
+compensated for properly during normal operation, but when the processor is
+inactive, the P-state may be raised temporarily to service cache misses from
+other processors.  In such cases, the TSC on halted CPUs could advance faster
+than that of non-halted processors.  AMD Turion processors are known to have
+this problem.
+
+3.6) TSC and STPCLK / T-states
+
+External signals given to the processor may also have the effect of stopping
+the TSC.  This is typically done for thermal emergency power control to prevent
+an overheating condition, and typically, there is no way to detect that this
+condition has happened.
+
+3.7) TSC virtualization - VMX
+
+VMX provides conditional trapping of RDTSC, RDMSR, WRMSR and RDTSCP
+instructions, which is enough for full virtualization of TSC in any manner.  In
+addition, VMX allows passing through the host TSC plus an additional TSC_OFFSET
+field specified in the VMCS.  Special instructions must be used to read and
+write the VMCS field.
+
+3.8) TSC virtualization - SVM
+
+SVM provides conditional trapping of RDTSC, RDMSR, WRMSR and RDTSCP
+instructions, which is enough for full virtualization of TSC in any manner.  In
+addition, SVM allows passing through the host TSC plus an additional offset
+field specified in the SVM control block.
+
+3.9) TSC feature bits in Linux
+
+In summary, there is no way to guarantee the TSC remains in perfect
+synchronization unless it is explicitly guaranteed by the architecture.  Even
+if so, the TSCs in multi-sockets or NUMA systems may still run independently
+despite being locally consistent.
+
+The following feature bits are used by Linux to signal various TSC attributes,
+but they can only be taken to be meaningful for UP or single node systems.
+
+X86_FEATURE_TSC 		: The TSC is available in hardware
+X86_FEATURE_RDTSCP		: The RDTSCP instruction is available
+X86_FEATURE_CONSTANT_TSC 	: The TSC rate is unchanged with P-states
+X86_FEATURE_NONSTOP_TSC		: The TSC does not stop in C-states
+X86_FEATURE_TSC_RELIABLE	: TSC sync checks are skipped (VMware)
+
+4) Virtualization Problems
+
+Timekeeping is especially problematic for virtualization because a number of
+challenges arise.  The most obvious problem is that time is now shared between
+the host and, potentially, a number of virtual machines.  Thus the virtual
+operating system does not run with 100% usage of the CPU, despite the fact that
+it may very well make that assumption.  It may expect it to remain true to very
+exacting bounds when interrupt sources are disabled, but in reality only its
+virtual interrupt sources are disabled, and the machine may still be preempted
+at any time.  This causes problems as the passage of real time, the injection
+of machine interrupts and the associated clock sources are no longer completely
+synchronized with real time.
+
+This same problem can occur on native harware to a degree, as SMM mode may
+steal cycles from the naturally on X86 systems when SMM mode is used by the
+BIOS, but not in such an extreme fashion.  However, the fact that SMM mode may
+cause similar problems to virtualization makes it a good justification for
+solving many of these problems on bare metal.
+
+4.1) Interrupt clocking
+
+One of the most immediate problems that occurs with legacy operating systems
+is that the system timekeeping routines are often designed to keep track of
+time by counting periodic interrupts.  These interrupts may come from the PIT
+or the RTC, but the problem is the same: the host virtualization engine may not
+be able to deliver the proper number of interrupts per second, and so guest
+time may fall behind.  This is especially problematic if a high interrupt rate
+is selected, such as 1000 HZ, which is unfortunately the default for many Linux
+guests.
+
+There are three approaches to solving this problem; first, it may be possible
+to simply ignore it.  Guests which have a separate time source for tracking
+'wall clock' or 'real time' may not need any adjustment of their interrupts to
+maintain proper time.  If this is not sufficient, it may be necessary to inject
+additional interrupts into the guest in order to increase the effective
+interrupt rate.  This approach leads to complications in extreme conditions,
+where host load or guest lag is too much to compensate for, and thus another
+solution to the problem has risen: the guest may need to become aware of lost
+ticks and compensate for them internally.  Although promising in theory, the
+implementation of this policy in Linux has been extremely error prone, and a
+number of buggy variants of lost tick compensation are distributed across
+commonly used Linux systems.
+
+Windows uses periodic RTC clocking as a means of keeping time internally, and
+thus requires interrupt slewing to keep proper time.  It does use a low enough
+rate (ed: is it 18.2 Hz?) however that it has not yet been a problem in
+practice.
+
+4.2) TSC sampling and serialization
+
+As the highest precision time source available, the cycle counter of the CPU
+has aroused much interest from developers.  As explained above, this timer has
+many problems unique to its nature as a local, potentially unstable and
+potentially unsynchronized source.  One issue which is not unique to the TSC,
+but is highlighted because of its very precise nature is sampling delay.  By
+definition, the counter, once read is already old.  However, it is also
+possible for the counter to be read ahead of the actual use of the result.
+This is a consequence of the superscalar execution of the instruction stream,
+which may execute instructions out of order.  Such execution is called
+non-serialized.  Forcing serialized execution is necessary for precise
+measurement with the TSC, and requires a serializing instruction, such as CPUID
+or an MSR read.
+
+Since CPUID may actually be virtualized by a trap and emulate mechanism, this
+serialization can pose a performance issue for hardware virtualization.  An
+accurate time stamp counter reading may therefore not always be available, and
+it may be necessary for an implementation to guard against "backwards" reads of
+the TSC as seen from other CPUs, even in an otherwise perfectly synchronized
+system.
+
+4.3) Timespec aliasing
+
+Additionally, this lack of serialization from the TSC poses another challenge
+when using results of the TSC when measured against another time source.  As
+the TSC is much higher precision, many possible values of the TSC may be read
+while another clock is still expressing the same value.
+
+That is, you may read (T,T+10) while external clock C maintains the same value.
+Due to non-serialized reads, you may actually end up with a range which
+fluctuates - from (T-1.. T+10).  Thus, any time calculated from a TSC, but
+calibrated against an external value may have a range of valid values.
+Re-calibrating this computation may actually cause time, as computed after the
+calibration, to go backwards, compared with time computed before the
+calibration.
+
+This problem is particularly pronounced with an internal time source in Linux,
+the kernel time, which is expressed in the theoretically high resolution
+timespec - but which advances in much larger granularity intervals, sometimes
+at the rate of jiffies, and possibly in catchup modes, at a much larger step.
+
+This aliasing requires care in the computation and recalibration of kvmclock
+and any other values derived from TSC computation (such as TSC virtualization
+itself).
+
+4.4) Migration
+
+Migration of a virtual machine raises problems for timekeeping in two ways.
+First, the migration itself may take time, during which interrupts cannot be
+delivered, and after which, the guest time may need to be caught up.  NTP may
+be able to help to some degree here, as the clock correction required is
+typically small enough to fall in the NTP-correctable window.
+
+An additional concern is that timers based off the TSC (or HPET, if the raw bus
+clock is exposed) may now be running at different rates, requiring compensation
+in some way in the hypervisor by virtualizing these timers.  In addition,
+migrating to a faster machine may preclude the use of a passthrough TSC, as a
+faster clock cannot be made visible to a guest without the potential of time
+advancing faster than usual.  A slower clock is less of a problem, as it can
+always be caught up to the original rate.  KVM clock avoids these problems by
+simply storing multipliers and offsets against the TSC for the guest to convert
+back into nanosecond resolution values.
+
+4.5) Scheduling
+
+Since scheduling may be based on precise timing and firing of interrupts, the
+scheduling algorithms of an operating system may be adversely affected by
+virtualization.  In theory, the effect is random and should be universally
+distributed, but in contrived as well as real scenarios (guest device access,
+causes of virtualization exits, possible context switch), this may not always
+be the case.  The effect of this has not been well studied.
+
+In an attempt to work around this, several implementations have provided a
+paravirtualized scheduler clock, which reveals the true amount of CPU time for
+which a virtual machine has been running.
+
+4.6) Watchdogs
+
+Watchdog timers, such as the lock detector in Linux may fire accidentally when
+running under hardware virtualization due to timer interrupts being delayed or
+misinterpretation of the passage of real time.  Usually, these warnings are
+spurious and can be ignored, but in some circumstances it may be necessary to
+disable such detection.
+
+4.7) Delays and precision timing
+
+Precise timing and delays may not be possible in a virtualized system.  This
+can happen if the system is controlling physical hardware, or issues delays to
+compensate for slower I/O to and from devices.  The first issue is not solvable
+in general for a virtualized system; hardware control software can't be
+adequately virtualized without a full real-time operating system, which would
+require an RT aware virtualization platform.
+
+The second issue may cause performance problems, but this is unlikely to be a
+significant issue.  In many cases these delays may be eliminated through
+configuration or paravirtualization.
+
+4.8) Covert channels and leaks
+
+In addition to the above problems, time information will inevitably leak to the
+guest about the host in anything but a perfect implementation of virtualized
+time.  This may allow the guest to infer the presence of a hypervisor (as in a
+red-pill type detection), and it may allow information to leak between guests
+by using CPU utilization itself as a signalling channel.  Preventing such
+problems would require completely isolated virtual time which may not track
+real time any longer.  This may be useful in certain security or QA contexts,
+but in general isn't recommended for real-world deployment scenarios.
diff -druN linux-2.6.39-libre/Documentation/virtual/lguest/extract linux-3.0-rc7-libre/Documentation/virtual/lguest/extract
--- linux-2.6.39-libre/Documentation/virtual/lguest/extract	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/Documentation/virtual/lguest/extract	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,58 @@
+#! /bin/sh
+
+set -e
+
+PREFIX=$1
+shift
+
+trap 'rm -r $TMPDIR' 0
+TMPDIR=`mktemp -d`
+
+exec 3>/dev/null
+for f; do
+    while IFS="
+" read -r LINE; do
+	case "$LINE" in
+	    *$PREFIX:[0-9]*:\**)
+		NUM=`echo "$LINE" | sed "s/.*$PREFIX:\([0-9]*\).*/\1/"`
+		if [ -f $TMPDIR/$NUM ]; then
+		    echo "$TMPDIR/$NUM already exits prior to $f"
+		    exit 1
+		fi
+		exec 3>>$TMPDIR/$NUM
+		echo $f | sed 's,\.\./,,g' > $TMPDIR/.$NUM
+		/bin/echo "$LINE" | sed -e "s/$PREFIX:[0-9]*//" -e "s/:\*/*/" >&3
+		;;
+	    *$PREFIX:[0-9]*)
+		NUM=`echo "$LINE" | sed "s/.*$PREFIX:\([0-9]*\).*/\1/"`
+		if [ -f $TMPDIR/$NUM ]; then
+		    echo "$TMPDIR/$NUM already exits prior to $f"
+		    exit 1
+		fi
+		exec 3>>$TMPDIR/$NUM
+		echo $f | sed 's,\.\./,,g' > $TMPDIR/.$NUM
+		/bin/echo "$LINE" | sed "s/$PREFIX:[0-9]*//" >&3
+		;;
+	    *:\**)
+		/bin/echo "$LINE" | sed -e "s/:\*/*/" -e "s,/\*\*/,," >&3
+		echo >&3
+		exec 3>/dev/null
+		;;
+	    *)
+		/bin/echo "$LINE" >&3
+		;;
+	esac
+    done < $f
+    echo >&3
+    exec 3>/dev/null
+done
+
+LASTFILE=""
+for f in $TMPDIR/*; do
+    if [ "$LASTFILE" != $(cat $TMPDIR/.$(basename $f) ) ]; then
+	LASTFILE=$(cat $TMPDIR/.$(basename $f) )
+	echo "[ $LASTFILE ]"
+    fi
+    cat $f
+done
+
diff -druN linux-2.6.39-libre/Documentation/virtual/lguest/.gitignore linux-3.0-rc7-libre/Documentation/virtual/lguest/.gitignore
--- linux-2.6.39-libre/Documentation/virtual/lguest/.gitignore	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/Documentation/virtual/lguest/.gitignore	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1 @@
+lguest
diff -druN linux-2.6.39-libre/Documentation/virtual/lguest/lguest.c linux-3.0-rc7-libre/Documentation/virtual/lguest/lguest.c
--- linux-2.6.39-libre/Documentation/virtual/lguest/lguest.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/Documentation/virtual/lguest/lguest.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,2077 @@
+/*P:100
+ * This is the Launcher code, a simple program which lays out the "physical"
+ * memory for the new Guest by mapping the kernel image and the virtual
+ * devices, then opens /dev/lguest to tell the kernel about the Guest and
+ * control it.
+:*/
+#define _LARGEFILE64_SOURCE
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <err.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <elf.h>
+#include <sys/mman.h>
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/wait.h>
+#include <sys/eventfd.h>
+#include <fcntl.h>
+#include <stdbool.h>
+#include <errno.h>
+#include <ctype.h>
+#include <sys/socket.h>
+#include <sys/ioctl.h>
+#include <sys/time.h>
+#include <time.h>
+#include <netinet/in.h>
+#include <net/if.h>
+#include <linux/sockios.h>
+#include <linux/if_tun.h>
+#include <sys/uio.h>
+#include <termios.h>
+#include <getopt.h>
+#include <assert.h>
+#include <sched.h>
+#include <limits.h>
+#include <stddef.h>
+#include <signal.h>
+#include <pwd.h>
+#include <grp.h>
+
+#include <linux/virtio_config.h>
+#include <linux/virtio_net.h>
+#include <linux/virtio_blk.h>
+#include <linux/virtio_console.h>
+#include <linux/virtio_rng.h>
+#include <linux/virtio_ring.h>
+#include <asm/bootparam.h>
+#include "../../../include/linux/lguest_launcher.h"
+/*L:110
+ * We can ignore the 42 include files we need for this program, but I do want
+ * to draw attention to the use of kernel-style types.
+ *
+ * As Linus said, "C is a Spartan language, and so should your naming be."  I
+ * like these abbreviations, so we define them here.  Note that u64 is always
+ * unsigned long long, which works on all Linux systems: this means that we can
+ * use %llu in printf for any u64.
+ */
+typedef unsigned long long u64;
+typedef uint32_t u32;
+typedef uint16_t u16;
+typedef uint8_t u8;
+/*:*/
+
+#define PAGE_PRESENT 0x7 	/* Present, RW, Execute */
+#define BRIDGE_PFX "bridge:"
+#ifndef SIOCBRADDIF
+#define SIOCBRADDIF	0x89a2		/* add interface to bridge      */
+#endif
+/* We can have up to 256 pages for devices. */
+#define DEVICE_PAGES 256
+/* This will occupy 3 pages: it must be a power of 2. */
+#define VIRTQUEUE_NUM 256
+
+/*L:120
+ * verbose is both a global flag and a macro.  The C preprocessor allows
+ * this, and although I wouldn't recommend it, it works quite nicely here.
+ */
+static bool verbose;
+#define verbose(args...) \
+	do { if (verbose) printf(args); } while(0)
+/*:*/
+
+/* The pointer to the start of guest memory. */
+static void *guest_base;
+/* The maximum guest physical address allowed, and maximum possible. */
+static unsigned long guest_limit, guest_max;
+/* The /dev/lguest file descriptor. */
+static int lguest_fd;
+
+/* a per-cpu variable indicating whose vcpu is currently running */
+static unsigned int __thread cpu_id;
+
+/* This is our list of devices. */
+struct device_list {
+	/* Counter to assign interrupt numbers. */
+	unsigned int next_irq;
+
+	/* Counter to print out convenient device numbers. */
+	unsigned int device_num;
+
+	/* The descriptor page for the devices. */
+	u8 *descpage;
+
+	/* A single linked list of devices. */
+	struct device *dev;
+	/* And a pointer to the last device for easy append. */
+	struct device *lastdev;
+};
+
+/* The list of Guest devices, based on command line arguments. */
+static struct device_list devices;
+
+/* The device structure describes a single device. */
+struct device {
+	/* The linked-list pointer. */
+	struct device *next;
+
+	/* The device's descriptor, as mapped into the Guest. */
+	struct lguest_device_desc *desc;
+
+	/* We can't trust desc values once Guest has booted: we use these. */
+	unsigned int feature_len;
+	unsigned int num_vq;
+
+	/* The name of this device, for --verbose. */
+	const char *name;
+
+	/* Any queues attached to this device */
+	struct virtqueue *vq;
+
+	/* Is it operational */
+	bool running;
+
+	/* Device-specific data. */
+	void *priv;
+};
+
+/* The virtqueue structure describes a queue attached to a device. */
+struct virtqueue {
+	struct virtqueue *next;
+
+	/* Which device owns me. */
+	struct device *dev;
+
+	/* The configuration for this queue. */
+	struct lguest_vqconfig config;
+
+	/* The actual ring of buffers. */
+	struct vring vring;
+
+	/* Last available index we saw. */
+	u16 last_avail_idx;
+
+	/* How many are used since we sent last irq? */
+	unsigned int pending_used;
+
+	/* Eventfd where Guest notifications arrive. */
+	int eventfd;
+
+	/* Function for the thread which is servicing this virtqueue. */
+	void (*service)(struct virtqueue *vq);
+	pid_t thread;
+};
+
+/* Remember the arguments to the program so we can "reboot" */
+static char **main_args;
+
+/* The original tty settings to restore on exit. */
+static struct termios orig_term;
+
+/*
+ * We have to be careful with barriers: our devices are all run in separate
+ * threads and so we need to make sure that changes visible to the Guest happen
+ * in precise order.
+ */
+#define wmb() __asm__ __volatile__("" : : : "memory")
+#define mb() __asm__ __volatile__("" : : : "memory")
+
+/*
+ * Convert an iovec element to the given type.
+ *
+ * This is a fairly ugly trick: we need to know the size of the type and
+ * alignment requirement to check the pointer is kosher.  It's also nice to
+ * have the name of the type in case we report failure.
+ *
+ * Typing those three things all the time is cumbersome and error prone, so we
+ * have a macro which sets them all up and passes to the real function.
+ */
+#define convert(iov, type) \
+	((type *)_convert((iov), sizeof(type), __alignof__(type), #type))
+
+static void *_convert(struct iovec *iov, size_t size, size_t align,
+		      const char *name)
+{
+	if (iov->iov_len != size)
+		errx(1, "Bad iovec size %zu for %s", iov->iov_len, name);
+	if ((unsigned long)iov->iov_base % align != 0)
+		errx(1, "Bad alignment %p for %s", iov->iov_base, name);
+	return iov->iov_base;
+}
+
+/* Wrapper for the last available index.  Makes it easier to change. */
+#define lg_last_avail(vq)	((vq)->last_avail_idx)
+
+/*
+ * The virtio configuration space is defined to be little-endian.  x86 is
+ * little-endian too, but it's nice to be explicit so we have these helpers.
+ */
+#define cpu_to_le16(v16) (v16)
+#define cpu_to_le32(v32) (v32)
+#define cpu_to_le64(v64) (v64)
+#define le16_to_cpu(v16) (v16)
+#define le32_to_cpu(v32) (v32)
+#define le64_to_cpu(v64) (v64)
+
+/* Is this iovec empty? */
+static bool iov_empty(const struct iovec iov[], unsigned int num_iov)
+{
+	unsigned int i;
+
+	for (i = 0; i < num_iov; i++)
+		if (iov[i].iov_len)
+			return false;
+	return true;
+}
+
+/* Take len bytes from the front of this iovec. */
+static void iov_consume(struct iovec iov[], unsigned num_iov, unsigned len)
+{
+	unsigned int i;
+
+	for (i = 0; i < num_iov; i++) {
+		unsigned int used;
+
+		used = iov[i].iov_len < len ? iov[i].iov_len : len;
+		iov[i].iov_base += used;
+		iov[i].iov_len -= used;
+		len -= used;
+	}
+	assert(len == 0);
+}
+
+/* The device virtqueue descriptors are followed by feature bitmasks. */
+static u8 *get_feature_bits(struct device *dev)
+{
+	return (u8 *)(dev->desc + 1)
+		+ dev->num_vq * sizeof(struct lguest_vqconfig);
+}
+
+/*L:100
+ * The Launcher code itself takes us out into userspace, that scary place where
+ * pointers run wild and free!  Unfortunately, like most userspace programs,
+ * it's quite boring (which is why everyone likes to hack on the kernel!).
+ * Perhaps if you make up an Lguest Drinking Game at this point, it will get
+ * you through this section.  Or, maybe not.
+ *
+ * The Launcher sets up a big chunk of memory to be the Guest's "physical"
+ * memory and stores it in "guest_base".  In other words, Guest physical ==
+ * Launcher virtual with an offset.
+ *
+ * This can be tough to get your head around, but usually it just means that we
+ * use these trivial conversion functions when the Guest gives us its
+ * "physical" addresses:
+ */
+static void *from_guest_phys(unsigned long addr)
+{
+	return guest_base + addr;
+}
+
+static unsigned long to_guest_phys(const void *addr)
+{
+	return (addr - guest_base);
+}
+
+/*L:130
+ * Loading the Kernel.
+ *
+ * We start with couple of simple helper routines.  open_or_die() avoids
+ * error-checking code cluttering the callers:
+ */
+static int open_or_die(const char *name, int flags)
+{
+	int fd = open(name, flags);
+	if (fd < 0)
+		err(1, "Failed to open %s", name);
+	return fd;
+}
+
+/* map_zeroed_pages() takes a number of pages. */
+static void *map_zeroed_pages(unsigned int num)
+{
+	int fd = open_or_die("/dev/zero", O_RDONLY);
+	void *addr;
+
+	/*
+	 * We use a private mapping (ie. if we write to the page, it will be
+	 * copied). We allocate an extra two pages PROT_NONE to act as guard
+	 * pages against read/write attempts that exceed allocated space.
+	 */
+	addr = mmap(NULL, getpagesize() * (num+2),
+		    PROT_NONE, MAP_PRIVATE, fd, 0);
+
+	if (addr == MAP_FAILED)
+		err(1, "Mmapping %u pages of /dev/zero", num);
+
+	if (mprotect(addr + getpagesize(), getpagesize() * num,
+		     PROT_READ|PROT_WRITE) == -1)
+		err(1, "mprotect rw %u pages failed", num);
+
+	/*
+	 * One neat mmap feature is that you can close the fd, and it
+	 * stays mapped.
+	 */
+	close(fd);
+
+	/* Return address after PROT_NONE page */
+	return addr + getpagesize();
+}
+
+/* Get some more pages for a device. */
+static void *get_pages(unsigned int num)
+{
+	void *addr = from_guest_phys(guest_limit);
+
+	guest_limit += num * getpagesize();
+	if (guest_limit > guest_max)
+		errx(1, "Not enough memory for devices");
+	return addr;
+}
+
+/*
+ * This routine is used to load the kernel or initrd.  It tries mmap, but if
+ * that fails (Plan 9's kernel file isn't nicely aligned on page boundaries),
+ * it falls back to reading the memory in.
+ */
+static void map_at(int fd, void *addr, unsigned long offset, unsigned long len)
+{
+	ssize_t r;
+
+	/*
+	 * We map writable even though for some segments are marked read-only.
+	 * The kernel really wants to be writable: it patches its own
+	 * instructions.
+	 *
+	 * MAP_PRIVATE means that the page won't be copied until a write is
+	 * done to it.  This allows us to share untouched memory between
+	 * Guests.
+	 */
+	if (mmap(addr, len, PROT_READ|PROT_WRITE,
+		 MAP_FIXED|MAP_PRIVATE, fd, offset) != MAP_FAILED)
+		return;
+
+	/* pread does a seek and a read in one shot: saves a few lines. */
+	r = pread(fd, addr, len, offset);
+	if (r != len)
+		err(1, "Reading offset %lu len %lu gave %zi", offset, len, r);
+}
+
+/*
+ * This routine takes an open vmlinux image, which is in ELF, and maps it into
+ * the Guest memory.  ELF = Embedded Linking Format, which is the format used
+ * by all modern binaries on Linux including the kernel.
+ *
+ * The ELF headers give *two* addresses: a physical address, and a virtual
+ * address.  We use the physical address; the Guest will map itself to the
+ * virtual address.
+ *
+ * We return the starting address.
+ */
+static unsigned long map_elf(int elf_fd, const Elf32_Ehdr *ehdr)
+{
+	Elf32_Phdr phdr[ehdr->e_phnum];
+	unsigned int i;
+
+	/*
+	 * Sanity checks on the main ELF header: an x86 executable with a
+	 * reasonable number of correctly-sized program headers.
+	 */
+	if (ehdr->e_type != ET_EXEC
+	    || ehdr->e_machine != EM_386
+	    || ehdr->e_phentsize != sizeof(Elf32_Phdr)
+	    || ehdr->e_phnum < 1 || ehdr->e_phnum > 65536U/sizeof(Elf32_Phdr))
+		errx(1, "Malformed elf header");
+
+	/*
+	 * An ELF executable contains an ELF header and a number of "program"
+	 * headers which indicate which parts ("segments") of the program to
+	 * load where.
+	 */
+
+	/* We read in all the program headers at once: */
+	if (lseek(elf_fd, ehdr->e_phoff, SEEK_SET) < 0)
+		err(1, "Seeking to program headers");
+	if (read(elf_fd, phdr, sizeof(phdr)) != sizeof(phdr))
+		err(1, "Reading program headers");
+
+	/*
+	 * Try all the headers: there are usually only three.  A read-only one,
+	 * a read-write one, and a "note" section which we don't load.
+	 */
+	for (i = 0; i < ehdr->e_phnum; i++) {
+		/* If this isn't a loadable segment, we ignore it */
+		if (phdr[i].p_type != PT_LOAD)
+			continue;
+
+		verbose("Section %i: size %i addr %p\n",
+			i, phdr[i].p_memsz, (void *)phdr[i].p_paddr);
+
+		/* We map this section of the file at its physical address. */
+		map_at(elf_fd, from_guest_phys(phdr[i].p_paddr),
+		       phdr[i].p_offset, phdr[i].p_filesz);
+	}
+
+	/* The entry point is given in the ELF header. */
+	return ehdr->e_entry;
+}
+
+/*L:150
+ * A bzImage, unlike an ELF file, is not meant to be loaded.  You're supposed
+ * to jump into it and it will unpack itself.  We used to have to perform some
+ * hairy magic because the unpacking code scared me.
+ *
+ * Fortunately, Jeremy Fitzhardinge convinced me it wasn't that hard and wrote
+ * a small patch to jump over the tricky bits in the Guest, so now we just read
+ * the funky header so we know where in the file to load, and away we go!
+ */
+static unsigned long load_bzimage(int fd)
+{
+	struct boot_params boot;
+	int r;
+	/* Modern bzImages get loaded at 1M. */
+	void *p = from_guest_phys(0x100000);
+
+	/*
+	 * Go back to the start of the file and read the header.  It should be
+	 * a Linux boot header (see Documentation/x86/i386/boot.txt)
+	 */
+	lseek(fd, 0, SEEK_SET);
+	read(fd, &boot, sizeof(boot));
+
+	/* Inside the setup_hdr, we expect the magic "HdrS" */
+	if (memcmp(&boot.hdr.header, "HdrS", 4) != 0)
+		errx(1, "This doesn't look like a bzImage to me");
+
+	/* Skip over the extra sectors of the header. */
+	lseek(fd, (boot.hdr.setup_sects+1) * 512, SEEK_SET);
+
+	/* Now read everything into memory. in nice big chunks. */
+	while ((r = read(fd, p, 65536)) > 0)
+		p += r;
+
+	/* Finally, code32_start tells us where to enter the kernel. */
+	return boot.hdr.code32_start;
+}
+
+/*L:140
+ * Loading the kernel is easy when it's a "vmlinux", but most kernels
+ * come wrapped up in the self-decompressing "bzImage" format.  With a little
+ * work, we can load those, too.
+ */
+static unsigned long load_kernel(int fd)
+{
+	Elf32_Ehdr hdr;
+
+	/* Read in the first few bytes. */
+	if (read(fd, &hdr, sizeof(hdr)) != sizeof(hdr))
+		err(1, "Reading kernel");
+
+	/* If it's an ELF file, it starts with "\177ELF" */
+	if (memcmp(hdr.e_ident, ELFMAG, SELFMAG) == 0)
+		return map_elf(fd, &hdr);
+
+	/* Otherwise we assume it's a bzImage, and try to load it. */
+	return load_bzimage(fd);
+}
+
+/*
+ * This is a trivial little helper to align pages.  Andi Kleen hated it because
+ * it calls getpagesize() twice: "it's dumb code."
+ *
+ * Kernel guys get really het up about optimization, even when it's not
+ * necessary.  I leave this code as a reaction against that.
+ */
+static inline unsigned long page_align(unsigned long addr)
+{
+	/* Add upwards and truncate downwards. */
+	return ((addr + getpagesize()-1) & ~(getpagesize()-1));
+}
+
+/*L:180
+ * An "initial ram disk" is a disk image loaded into memory along with the
+ * kernel which the kernel can use to boot from without needing any drivers.
+ * Most distributions now use this as standard: the initrd contains the code to
+ * load the appropriate driver modules for the current machine.
+ *
+ * Importantly, James Morris works for RedHat, and Fedora uses initrds for its
+ * kernels.  He sent me this (and tells me when I break it).
+ */
+static unsigned long load_initrd(const char *name, unsigned long mem)
+{
+	int ifd;
+	struct stat st;
+	unsigned long len;
+
+	ifd = open_or_die(name, O_RDONLY);
+	/* fstat() is needed to get the file size. */
+	if (fstat(ifd, &st) < 0)
+		err(1, "fstat() on initrd '%s'", name);
+
+	/*
+	 * We map the initrd at the top of memory, but mmap wants it to be
+	 * page-aligned, so we round the size up for that.
+	 */
+	len = page_align(st.st_size);
+	map_at(ifd, from_guest_phys(mem - len), 0, st.st_size);
+	/*
+	 * Once a file is mapped, you can close the file descriptor.  It's a
+	 * little odd, but quite useful.
+	 */
+	close(ifd);
+	verbose("mapped initrd %s size=%lu @ %p\n", name, len, (void*)mem-len);
+
+	/* We return the initrd size. */
+	return len;
+}
+/*:*/
+
+/*
+ * Simple routine to roll all the commandline arguments together with spaces
+ * between them.
+ */
+static void concat(char *dst, char *args[])
+{
+	unsigned int i, len = 0;
+
+	for (i = 0; args[i]; i++) {
+		if (i) {
+			strcat(dst+len, " ");
+			len++;
+		}
+		strcpy(dst+len, args[i]);
+		len += strlen(args[i]);
+	}
+	/* In case it's empty. */
+	dst[len] = '\0';
+}
+
+/*L:185
+ * This is where we actually tell the kernel to initialize the Guest.  We
+ * saw the arguments it expects when we looked at initialize() in lguest_user.c:
+ * the base of Guest "physical" memory, the top physical page to allow and the
+ * entry point for the Guest.
+ */
+static void tell_kernel(unsigned long start)
+{
+	unsigned long args[] = { LHREQ_INITIALIZE,
+				 (unsigned long)guest_base,
+				 guest_limit / getpagesize(), start };
+	verbose("Guest: %p - %p (%#lx)\n",
+		guest_base, guest_base + guest_limit, guest_limit);
+	lguest_fd = open_or_die("/dev/lguest", O_RDWR);
+	if (write(lguest_fd, args, sizeof(args)) < 0)
+		err(1, "Writing to /dev/lguest");
+}
+/*:*/
+
+/*L:200
+ * Device Handling.
+ *
+ * When the Guest gives us a buffer, it sends an array of addresses and sizes.
+ * We need to make sure it's not trying to reach into the Launcher itself, so
+ * we have a convenient routine which checks it and exits with an error message
+ * if something funny is going on:
+ */
+static void *_check_pointer(unsigned long addr, unsigned int size,
+			    unsigned int line)
+{
+	/*
+	 * Check if the requested address and size exceeds the allocated memory,
+	 * or addr + size wraps around.
+	 */
+	if ((addr + size) > guest_limit || (addr + size) < addr)
+		errx(1, "%s:%i: Invalid address %#lx", __FILE__, line, addr);
+	/*
+	 * We return a pointer for the caller's convenience, now we know it's
+	 * safe to use.
+	 */
+	return from_guest_phys(addr);
+}
+/* A macro which transparently hands the line number to the real function. */
+#define check_pointer(addr,size) _check_pointer(addr, size, __LINE__)
+
+/*
+ * Each buffer in the virtqueues is actually a chain of descriptors.  This
+ * function returns the next descriptor in the chain, or vq->vring.num if we're
+ * at the end.
+ */
+static unsigned next_desc(struct vring_desc *desc,
+			  unsigned int i, unsigned int max)
+{
+	unsigned int next;
+
+	/* If this descriptor says it doesn't chain, we're done. */
+	if (!(desc[i].flags & VRING_DESC_F_NEXT))
+		return max;
+
+	/* Check they're not leading us off end of descriptors. */
+	next = desc[i].next;
+	/* Make sure compiler knows to grab that: we don't want it changing! */
+	wmb();
+
+	if (next >= max)
+		errx(1, "Desc next is %u", next);
+
+	return next;
+}
+
+/*
+ * This actually sends the interrupt for this virtqueue, if we've used a
+ * buffer.
+ */
+static void trigger_irq(struct virtqueue *vq)
+{
+	unsigned long buf[] = { LHREQ_IRQ, vq->config.irq };
+
+	/* Don't inform them if nothing used. */
+	if (!vq->pending_used)
+		return;
+	vq->pending_used = 0;
+
+	/* If they don't want an interrupt, don't send one... */
+	if (vq->vring.avail->flags & VRING_AVAIL_F_NO_INTERRUPT) {
+		return;
+	}
+
+	/* Send the Guest an interrupt tell them we used something up. */
+	if (write(lguest_fd, buf, sizeof(buf)) != 0)
+		err(1, "Triggering irq %i", vq->config.irq);
+}
+
+/*
+ * This looks in the virtqueue 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 waits if necessary, and returns the descriptor number found.
+ */
+static unsigned wait_for_vq_desc(struct virtqueue *vq,
+				 struct iovec iov[],
+				 unsigned int *out_num, unsigned int *in_num)
+{
+	unsigned int i, head, max;
+	struct vring_desc *desc;
+	u16 last_avail = lg_last_avail(vq);
+
+	/* There's nothing available? */
+	while (last_avail == vq->vring.avail->idx) {
+		u64 event;
+
+		/*
+		 * Since we're about to sleep, now is a good time to tell the
+		 * Guest about what we've used up to now.
+		 */
+		trigger_irq(vq);
+
+		/* OK, now we need to know about added descriptors. */
+		vq->vring.used->flags &= ~VRING_USED_F_NO_NOTIFY;
+
+		/*
+		 * They could have slipped one in as we were doing that: make
+		 * sure it's written, then check again.
+		 */
+		mb();
+		if (last_avail != vq->vring.avail->idx) {
+			vq->vring.used->flags |= VRING_USED_F_NO_NOTIFY;
+			break;
+		}
+
+		/* Nothing new?  Wait for eventfd to tell us they refilled. */
+		if (read(vq->eventfd, &event, sizeof(event)) != sizeof(event))
+			errx(1, "Event read failed?");
+
+		/* We don't need to be notified again. */
+		vq->vring.used->flags |= VRING_USED_F_NO_NOTIFY;
+	}
+
+	/* Check it isn't doing very strange things with descriptor numbers. */
+	if ((u16)(vq->vring.avail->idx - last_avail) > vq->vring.num)
+		errx(1, "Guest moved used index from %u to %u",
+		     last_avail, vq->vring.avail->idx);
+
+	/*
+	 * Grab the next descriptor number they're advertising, and increment
+	 * the index we've seen.
+	 */
+	head = vq->vring.avail->ring[last_avail % vq->vring.num];
+	lg_last_avail(vq)++;
+
+	/* If their number is silly, that's a fatal mistake. */
+	if (head >= vq->vring.num)
+		errx(1, "Guest says index %u is available", head);
+
+	/* When we start there are none of either input nor output. */
+	*out_num = *in_num = 0;
+
+	max = vq->vring.num;
+	desc = vq->vring.desc;
+	i = head;
+
+	/*
+	 * If this is an indirect entry, then this buffer contains a descriptor
+	 * table which we handle as if it's any normal descriptor chain.
+	 */
+	if (desc[i].flags & VRING_DESC_F_INDIRECT) {
+		if (desc[i].len % sizeof(struct vring_desc))
+			errx(1, "Invalid size for indirect buffer table");
+
+		max = desc[i].len / sizeof(struct vring_desc);
+		desc = check_pointer(desc[i].addr, desc[i].len);
+		i = 0;
+	}
+
+	do {
+		/* Grab the first descriptor, and check it's OK. */
+		iov[*out_num + *in_num].iov_len = desc[i].len;
+		iov[*out_num + *in_num].iov_base
+			= check_pointer(desc[i].addr, desc[i].len);
+		/* If this is an input descriptor, increment that count. */
+		if (desc[i].flags & VRING_DESC_F_WRITE)
+			(*in_num)++;
+		else {
+			/*
+			 * If it's an output descriptor, they're all supposed
+			 * to come before any input descriptors.
+			 */
+			if (*in_num)
+				errx(1, "Descriptor has out after in");
+			(*out_num)++;
+		}
+
+		/* If we've got too many, that implies a descriptor loop. */
+		if (*out_num + *in_num > max)
+			errx(1, "Looped descriptor");
+	} while ((i = next_desc(desc, i, max)) != max);
+
+	return head;
+}
+
+/*
+ * After we've used one of their buffers, we tell the Guest about it.  Sometime
+ * later we'll want to send them an interrupt using trigger_irq(); note that
+ * wait_for_vq_desc() does that for us if it has to wait.
+ */
+static void add_used(struct 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->vring.used->ring[vq->vring.used->idx % vq->vring.num];
+	used->id = head;
+	used->len = len;
+	/* Make sure buffer is written before we update index. */
+	wmb();
+	vq->vring.used->idx++;
+	vq->pending_used++;
+}
+
+/* And here's the combo meal deal.  Supersize me! */
+static void add_used_and_trigger(struct virtqueue *vq, unsigned head, int len)
+{
+	add_used(vq, head, len);
+	trigger_irq(vq);
+}
+
+/*
+ * The Console
+ *
+ * We associate some data with the console for our exit hack.
+ */
+struct console_abort {
+	/* How many times have they hit ^C? */
+	int count;
+	/* When did they start? */
+	struct timeval start;
+};
+
+/* This is the routine which handles console input (ie. stdin). */
+static void console_input(struct virtqueue *vq)
+{
+	int len;
+	unsigned int head, in_num, out_num;
+	struct console_abort *abort = vq->dev->priv;
+	struct iovec iov[vq->vring.num];
+
+	/* Make sure there's a descriptor available. */
+	head = wait_for_vq_desc(vq, iov, &out_num, &in_num);
+	if (out_num)
+		errx(1, "Output buffers in console in queue?");
+
+	/* Read into it.  This is where we usually wait. */
+	len = readv(STDIN_FILENO, iov, in_num);
+	if (len <= 0) {
+		/* Ran out of input? */
+		warnx("Failed to get console input, ignoring console.");
+		/*
+		 * For simplicity, dying threads kill the whole Launcher.  So
+		 * just nap here.
+		 */
+		for (;;)
+			pause();
+	}
+
+	/* Tell the Guest we used a buffer. */
+	add_used_and_trigger(vq, head, len);
+
+	/*
+	 * Three ^C within one second?  Exit.
+	 *
+	 * This is such a hack, but works surprisingly well.  Each ^C has to
+	 * be in a buffer by itself, so they can't be too fast.  But we check
+	 * that we get three within about a second, so they can't be too
+	 * slow.
+	 */
+	if (len != 1 || ((char *)iov[0].iov_base)[0] != 3) {
+		abort->count = 0;
+		return;
+	}
+
+	abort->count++;
+	if (abort->count == 1)
+		gettimeofday(&abort->start, NULL);
+	else if (abort->count == 3) {
+		struct timeval now;
+		gettimeofday(&now, NULL);
+		/* Kill all Launcher processes with SIGINT, like normal ^C */
+		if (now.tv_sec <= abort->start.tv_sec+1)
+			kill(0, SIGINT);
+		abort->count = 0;
+	}
+}
+
+/* This is the routine which handles console output (ie. stdout). */
+static void console_output(struct virtqueue *vq)
+{
+	unsigned int head, out, in;
+	struct iovec iov[vq->vring.num];
+
+	/* We usually wait in here, for the Guest to give us something. */
+	head = wait_for_vq_desc(vq, iov, &out, &in);
+	if (in)
+		errx(1, "Input buffers in console output queue?");
+
+	/* writev can return a partial write, so we loop here. */
+	while (!iov_empty(iov, out)) {
+		int len = writev(STDOUT_FILENO, iov, out);
+		if (len <= 0)
+			err(1, "Write to stdout gave %i", len);
+		iov_consume(iov, out, len);
+	}
+
+	/*
+	 * We're finished with that buffer: if we're going to sleep,
+	 * wait_for_vq_desc() will prod the Guest with an interrupt.
+	 */
+	add_used(vq, head, 0);
+}
+
+/*
+ * The Network
+ *
+ * Handling output for network is also simple: we get all the output buffers
+ * and write them to /dev/net/tun.
+ */
+struct net_info {
+	int tunfd;
+};
+
+static void net_output(struct virtqueue *vq)
+{
+	struct net_info *net_info = vq->dev->priv;
+	unsigned int head, out, in;
+	struct iovec iov[vq->vring.num];
+
+	/* We usually wait in here for the Guest to give us a packet. */
+	head = wait_for_vq_desc(vq, iov, &out, &in);
+	if (in)
+		errx(1, "Input buffers in net output queue?");
+	/*
+	 * Send the whole thing through to /dev/net/tun.  It expects the exact
+	 * same format: what a coincidence!
+	 */
+	if (writev(net_info->tunfd, iov, out) < 0)
+		errx(1, "Write to tun failed?");
+
+	/*
+	 * Done with that one; wait_for_vq_desc() will send the interrupt if
+	 * all packets are processed.
+	 */
+	add_used(vq, head, 0);
+}
+
+/*
+ * Handling network input is a bit trickier, because I've tried to optimize it.
+ *
+ * First we have a helper routine which tells is if from this file descriptor
+ * (ie. the /dev/net/tun device) will block:
+ */
+static bool will_block(int fd)
+{
+	fd_set fdset;
+	struct timeval zero = { 0, 0 };
+	FD_ZERO(&fdset);
+	FD_SET(fd, &fdset);
+	return select(fd+1, &fdset, NULL, NULL, &zero) != 1;
+}
+
+/*
+ * This handles packets coming in from the tun device to our Guest.  Like all
+ * service routines, it gets called again as soon as it returns, so you don't
+ * see a while(1) loop here.
+ */
+static void net_input(struct virtqueue *vq)
+{
+	int len;
+	unsigned int head, out, in;
+	struct iovec iov[vq->vring.num];
+	struct net_info *net_info = vq->dev->priv;
+
+	/*
+	 * Get a descriptor to write an incoming packet into.  This will also
+	 * send an interrupt if they're out of descriptors.
+	 */
+	head = wait_for_vq_desc(vq, iov, &out, &in);
+	if (out)
+		errx(1, "Output buffers in net input queue?");
+
+	/*
+	 * If it looks like we'll block reading from the tun device, send them
+	 * an interrupt.
+	 */
+	if (vq->pending_used && will_block(net_info->tunfd))
+		trigger_irq(vq);
+
+	/*
+	 * Read in the packet.  This is where we normally wait (when there's no
+	 * incoming network traffic).
+	 */
+	len = readv(net_info->tunfd, iov, in);
+	if (len <= 0)
+		err(1, "Failed to read from tun.");
+
+	/*
+	 * Mark that packet buffer as used, but don't interrupt here.  We want
+	 * to wait until we've done as much work as we can.
+	 */
+	add_used(vq, head, len);
+}
+/*:*/
+
+/* This is the helper to create threads: run the service routine in a loop. */
+static int do_thread(void *_vq)
+{
+	struct virtqueue *vq = _vq;
+
+	for (;;)
+		vq->service(vq);
+	return 0;
+}
+
+/*
+ * When a child dies, we kill our entire process group with SIGTERM.  This
+ * also has the side effect that the shell restores the console for us!
+ */
+static void kill_launcher(int signal)
+{
+	kill(0, SIGTERM);
+}
+
+static void reset_device(struct device *dev)
+{
+	struct virtqueue *vq;
+
+	verbose("Resetting device %s\n", dev->name);
+
+	/* Clear any features they've acked. */
+	memset(get_feature_bits(dev) + dev->feature_len, 0, dev->feature_len);
+
+	/* We're going to be explicitly killing threads, so ignore them. */
+	signal(SIGCHLD, SIG_IGN);
+
+	/* Zero out the virtqueues, get rid of their threads */
+	for (vq = dev->vq; vq; vq = vq->next) {
+		if (vq->thread != (pid_t)-1) {
+			kill(vq->thread, SIGTERM);
+			waitpid(vq->thread, NULL, 0);
+			vq->thread = (pid_t)-1;
+		}
+		memset(vq->vring.desc, 0,
+		       vring_size(vq->config.num, LGUEST_VRING_ALIGN));
+		lg_last_avail(vq) = 0;
+	}
+	dev->running = false;
+
+	/* Now we care if threads die. */
+	signal(SIGCHLD, (void *)kill_launcher);
+}
+
+/*L:216
+ * This actually creates the thread which services the virtqueue for a device.
+ */
+static void create_thread(struct virtqueue *vq)
+{
+	/*
+	 * Create stack for thread.  Since the stack grows upwards, we point
+	 * the stack pointer to the end of this region.
+	 */
+	char *stack = malloc(32768);
+	unsigned long args[] = { LHREQ_EVENTFD,
+				 vq->config.pfn*getpagesize(), 0 };
+
+	/* Create a zero-initialized eventfd. */
+	vq->eventfd = eventfd(0, 0);
+	if (vq->eventfd < 0)
+		err(1, "Creating eventfd");
+	args[2] = vq->eventfd;
+
+	/*
+	 * Attach an eventfd to this virtqueue: it will go off when the Guest
+	 * does an LHCALL_NOTIFY for this vq.
+	 */
+	if (write(lguest_fd, &args, sizeof(args)) != 0)
+		err(1, "Attaching eventfd");
+
+	/*
+	 * CLONE_VM: because it has to access the Guest memory, and SIGCHLD so
+	 * we get a signal if it dies.
+	 */
+	vq->thread = clone(do_thread, stack + 32768, CLONE_VM | SIGCHLD, vq);
+	if (vq->thread == (pid_t)-1)
+		err(1, "Creating clone");
+
+	/* We close our local copy now the child has it. */
+	close(vq->eventfd);
+}
+
+static void start_device(struct device *dev)
+{
+	unsigned int i;
+	struct virtqueue *vq;
+
+	verbose("Device %s OK: offered", dev->name);
+	for (i = 0; i < dev->feature_len; i++)
+		verbose(" %02x", get_feature_bits(dev)[i]);
+	verbose(", accepted");
+	for (i = 0; i < dev->feature_len; i++)
+		verbose(" %02x", get_feature_bits(dev)
+			[dev->feature_len+i]);
+
+	for (vq = dev->vq; vq; vq = vq->next) {
+		if (vq->service)
+			create_thread(vq);
+	}
+	dev->running = true;
+}
+
+static void cleanup_devices(void)
+{
+	struct device *dev;
+
+	for (dev = devices.dev; dev; dev = dev->next)
+		reset_device(dev);
+
+	/* If we saved off the original terminal settings, restore them now. */
+	if (orig_term.c_lflag & (ISIG|ICANON|ECHO))
+		tcsetattr(STDIN_FILENO, TCSANOW, &orig_term);
+}
+
+/* When the Guest tells us they updated the status field, we handle it. */
+static void update_device_status(struct device *dev)
+{
+	/* A zero status is a reset, otherwise it's a set of flags. */
+	if (dev->desc->status == 0)
+		reset_device(dev);
+	else if (dev->desc->status & VIRTIO_CONFIG_S_FAILED) {
+		warnx("Device %s configuration FAILED", dev->name);
+		if (dev->running)
+			reset_device(dev);
+	} else if (dev->desc->status & VIRTIO_CONFIG_S_DRIVER_OK) {
+		if (!dev->running)
+			start_device(dev);
+	}
+}
+
+/*L:215
+ * This is the generic routine we call when the Guest uses LHCALL_NOTIFY.  In
+ * particular, it's used to notify us of device status changes during boot.
+ */
+static void handle_output(unsigned long addr)
+{
+	struct device *i;
+
+	/* Check each device. */
+	for (i = devices.dev; i; i = i->next) {
+		struct virtqueue *vq;
+
+		/*
+		 * Notifications to device descriptors mean they updated the
+		 * device status.
+		 */
+		if (from_guest_phys(addr) == i->desc) {
+			update_device_status(i);
+			return;
+		}
+
+		/*
+		 * Devices *can* be used before status is set to DRIVER_OK.
+		 * The original plan was that they would never do this: they
+		 * would always finish setting up their status bits before
+		 * actually touching the virtqueues.  In practice, we allowed
+		 * them to, and they do (eg. the disk probes for partition
+		 * tables as part of initialization).
+		 *
+		 * If we see this, we start the device: once it's running, we
+		 * expect the device to catch all the notifications.
+		 */
+		for (vq = i->vq; vq; vq = vq->next) {
+			if (addr != vq->config.pfn*getpagesize())
+				continue;
+			if (i->running)
+				errx(1, "Notification on running %s", i->name);
+			/* This just calls create_thread() for each virtqueue */
+			start_device(i);
+			return;
+		}
+	}
+
+	/*
+	 * Early console write is done using notify on a nul-terminated string
+	 * in Guest memory.  It's also great for hacking debugging messages
+	 * into a Guest.
+	 */
+	if (addr >= guest_limit)
+		errx(1, "Bad NOTIFY %#lx", addr);
+
+	write(STDOUT_FILENO, from_guest_phys(addr),
+	      strnlen(from_guest_phys(addr), guest_limit - addr));
+}
+
+/*L:190
+ * Device Setup
+ *
+ * All devices need a descriptor so the Guest knows it exists, and a "struct
+ * device" so the Launcher can keep track of it.  We have common helper
+ * routines to allocate and manage them.
+ */
+
+/*
+ * The layout of the device page is a "struct lguest_device_desc" followed by a
+ * number of virtqueue descriptors, then two sets of feature bits, then an
+ * array of configuration bytes.  This routine returns the configuration
+ * pointer.
+ */
+static u8 *device_config(const struct device *dev)
+{
+	return (void *)(dev->desc + 1)
+		+ dev->num_vq * sizeof(struct lguest_vqconfig)
+		+ dev->feature_len * 2;
+}
+
+/*
+ * This routine allocates a new "struct lguest_device_desc" from descriptor
+ * table page just above the Guest's normal memory.  It returns a pointer to
+ * that descriptor.
+ */
+static struct lguest_device_desc *new_dev_desc(u16 type)
+{
+	struct lguest_device_desc d = { .type = type };
+	void *p;
+
+	/* Figure out where the next device config is, based on the last one. */
+	if (devices.lastdev)
+		p = device_config(devices.lastdev)
+			+ devices.lastdev->desc->config_len;
+	else
+		p = devices.descpage;
+
+	/* We only have one page for all the descriptors. */
+	if (p + sizeof(d) > (void *)devices.descpage + getpagesize())
+		errx(1, "Too many devices");
+
+	/* p might not be aligned, so we memcpy in. */
+	return memcpy(p, &d, sizeof(d));
+}
+
+/*
+ * Each device descriptor is followed by the description of its virtqueues.  We
+ * specify how many descriptors the virtqueue is to have.
+ */
+static void add_virtqueue(struct device *dev, unsigned int num_descs,
+			  void (*service)(struct virtqueue *))
+{
+	unsigned int pages;
+	struct virtqueue **i, *vq = malloc(sizeof(*vq));
+	void *p;
+
+	/* First we need some memory for this virtqueue. */
+	pages = (vring_size(num_descs, LGUEST_VRING_ALIGN) + getpagesize() - 1)
+		/ getpagesize();
+	p = get_pages(pages);
+
+	/* Initialize the virtqueue */
+	vq->next = NULL;
+	vq->last_avail_idx = 0;
+	vq->dev = dev;
+
+	/*
+	 * This is the routine the service thread will run, and its Process ID
+	 * once it's running.
+	 */
+	vq->service = service;
+	vq->thread = (pid_t)-1;
+
+	/* Initialize the configuration. */
+	vq->config.num = num_descs;
+	vq->config.irq = devices.next_irq++;
+	vq->config.pfn = to_guest_phys(p) / getpagesize();
+
+	/* Initialize the vring. */
+	vring_init(&vq->vring, num_descs, p, LGUEST_VRING_ALIGN);
+
+	/*
+	 * Append virtqueue to this device's descriptor.  We use
+	 * device_config() to get the end of the device's current virtqueues;
+	 * we check that we haven't added any config or feature information
+	 * yet, otherwise we'd be overwriting them.
+	 */
+	assert(dev->desc->config_len == 0 && dev->desc->feature_len == 0);
+	memcpy(device_config(dev), &vq->config, sizeof(vq->config));
+	dev->num_vq++;
+	dev->desc->num_vq++;
+
+	verbose("Virtqueue page %#lx\n", to_guest_phys(p));
+
+	/*
+	 * Add to tail of list, so dev->vq is first vq, dev->vq->next is
+	 * second.
+	 */
+	for (i = &dev->vq; *i; i = &(*i)->next);
+	*i = vq;
+}
+
+/*
+ * The first half of the feature bitmask is for us to advertise features.  The
+ * second half is for the Guest to accept features.
+ */
+static void add_feature(struct device *dev, unsigned bit)
+{
+	u8 *features = get_feature_bits(dev);
+
+	/* We can't extend the feature bits once we've added config bytes */
+	if (dev->desc->feature_len <= bit / CHAR_BIT) {
+		assert(dev->desc->config_len == 0);
+		dev->feature_len = dev->desc->feature_len = (bit/CHAR_BIT) + 1;
+	}
+
+	features[bit / CHAR_BIT] |= (1 << (bit % CHAR_BIT));
+}
+
+/*
+ * This routine sets the configuration fields for an existing device's
+ * descriptor.  It only works for the last device, but that's OK because that's
+ * how we use it.
+ */
+static void set_config(struct device *dev, unsigned len, const void *conf)
+{
+	/* Check we haven't overflowed our single page. */
+	if (device_config(dev) + len > devices.descpage + getpagesize())
+		errx(1, "Too many devices");
+
+	/* Copy in the config information, and store the length. */
+	memcpy(device_config(dev), conf, len);
+	dev->desc->config_len = len;
+
+	/* Size must fit in config_len field (8 bits)! */
+	assert(dev->desc->config_len == len);
+}
+
+/*
+ * This routine does all the creation and setup of a new device, including
+ * calling new_dev_desc() to allocate the descriptor and device memory.  We
+ * don't actually start the service threads until later.
+ *
+ * See what I mean about userspace being boring?
+ */
+static struct device *new_device(const char *name, u16 type)
+{
+	struct device *dev = malloc(sizeof(*dev));
+
+	/* Now we populate the fields one at a time. */
+	dev->desc = new_dev_desc(type);
+	dev->name = name;
+	dev->vq = NULL;
+	dev->feature_len = 0;
+	dev->num_vq = 0;
+	dev->running = false;
+
+	/*
+	 * Append to device list.  Prepending to a single-linked list is
+	 * easier, but the user expects the devices to be arranged on the bus
+	 * in command-line order.  The first network device on the command line
+	 * is eth0, the first block device /dev/vda, etc.
+	 */
+	if (devices.lastdev)
+		devices.lastdev->next = dev;
+	else
+		devices.dev = dev;
+	devices.lastdev = dev;
+
+	return dev;
+}
+
+/*
+ * Our first setup routine is the console.  It's a fairly simple device, but
+ * UNIX tty handling makes it uglier than it could be.
+ */
+static void setup_console(void)
+{
+	struct device *dev;
+
+	/* If we can save the initial standard input settings... */
+	if (tcgetattr(STDIN_FILENO, &orig_term) == 0) {
+		struct termios term = orig_term;
+		/*
+		 * Then we turn off echo, line buffering and ^C etc: We want a
+		 * raw input stream to the Guest.
+		 */
+		term.c_lflag &= ~(ISIG|ICANON|ECHO);
+		tcsetattr(STDIN_FILENO, TCSANOW, &term);
+	}
+
+	dev = new_device("console", VIRTIO_ID_CONSOLE);
+
+	/* We store the console state in dev->priv, and initialize it. */
+	dev->priv = malloc(sizeof(struct console_abort));
+	((struct console_abort *)dev->priv)->count = 0;
+
+	/*
+	 * The console needs two virtqueues: the input then the output.  When
+	 * they put something the input queue, we make sure we're listening to
+	 * stdin.  When they put something in the output queue, we write it to
+	 * stdout.
+	 */
+	add_virtqueue(dev, VIRTQUEUE_NUM, console_input);
+	add_virtqueue(dev, VIRTQUEUE_NUM, console_output);
+
+	verbose("device %u: console\n", ++devices.device_num);
+}
+/*:*/
+
+/*M:010
+ * Inter-guest networking is an interesting area.  Simplest is to have a
+ * --sharenet=<name> option which opens or creates a named pipe.  This can be
+ * used to send packets to another guest in a 1:1 manner.
+ *
+ * More sopisticated is to use one of the tools developed for project like UML
+ * to do networking.
+ *
+ * Faster is to do virtio bonding in kernel.  Doing this 1:1 would be
+ * completely generic ("here's my vring, attach to your vring") and would work
+ * for any traffic.  Of course, namespace and permissions issues need to be
+ * dealt with.  A more sophisticated "multi-channel" virtio_net.c could hide
+ * multiple inter-guest channels behind one interface, although it would
+ * require some manner of hotplugging new virtio channels.
+ *
+ * Finally, we could implement a virtio network switch in the kernel.
+:*/
+
+static u32 str2ip(const char *ipaddr)
+{
+	unsigned int b[4];
+
+	if (sscanf(ipaddr, "%u.%u.%u.%u", &b[0], &b[1], &b[2], &b[3]) != 4)
+		errx(1, "Failed to parse IP address '%s'", ipaddr);
+	return (b[0] << 24) | (b[1] << 16) | (b[2] << 8) | b[3];
+}
+
+static void str2mac(const char *macaddr, unsigned char mac[6])
+{
+	unsigned int m[6];
+	if (sscanf(macaddr, "%02x:%02x:%02x:%02x:%02x:%02x",
+		   &m[0], &m[1], &m[2], &m[3], &m[4], &m[5]) != 6)
+		errx(1, "Failed to parse mac address '%s'", macaddr);
+	mac[0] = m[0];
+	mac[1] = m[1];
+	mac[2] = m[2];
+	mac[3] = m[3];
+	mac[4] = m[4];
+	mac[5] = m[5];
+}
+
+/*
+ * This code is "adapted" from libbridge: it attaches the Host end of the
+ * network device to the bridge device specified by the command line.
+ *
+ * This is yet another James Morris contribution (I'm an IP-level guy, so I
+ * dislike bridging), and I just try not to break it.
+ */
+static void add_to_bridge(int fd, const char *if_name, const char *br_name)
+{
+	int ifidx;
+	struct ifreq ifr;
+
+	if (!*br_name)
+		errx(1, "must specify bridge name");
+
+	ifidx = if_nametoindex(if_name);
+	if (!ifidx)
+		errx(1, "interface %s does not exist!", if_name);
+
+	strncpy(ifr.ifr_name, br_name, IFNAMSIZ);
+	ifr.ifr_name[IFNAMSIZ-1] = '\0';
+	ifr.ifr_ifindex = ifidx;
+	if (ioctl(fd, SIOCBRADDIF, &ifr) < 0)
+		err(1, "can't add %s to bridge %s", if_name, br_name);
+}
+
+/*
+ * This sets up the Host end of the network device with an IP address, brings
+ * it up so packets will flow, the copies the MAC address into the hwaddr
+ * pointer.
+ */
+static void configure_device(int fd, const char *tapif, u32 ipaddr)
+{
+	struct ifreq ifr;
+	struct sockaddr_in sin;
+
+	memset(&ifr, 0, sizeof(ifr));
+	strcpy(ifr.ifr_name, tapif);
+
+	/* Don't read these incantations.  Just cut & paste them like I did! */
+	sin.sin_family = AF_INET;
+	sin.sin_addr.s_addr = htonl(ipaddr);
+	memcpy(&ifr.ifr_addr, &sin, sizeof(sin));
+	if (ioctl(fd, SIOCSIFADDR, &ifr) != 0)
+		err(1, "Setting %s interface address", tapif);
+	ifr.ifr_flags = IFF_UP;
+	if (ioctl(fd, SIOCSIFFLAGS, &ifr) != 0)
+		err(1, "Bringing interface %s up", tapif);
+}
+
+static int get_tun_device(char tapif[IFNAMSIZ])
+{
+	struct ifreq ifr;
+	int netfd;
+
+	/* Start with this zeroed.  Messy but sure. */
+	memset(&ifr, 0, sizeof(ifr));
+
+	/*
+	 * We open the /dev/net/tun device and tell it we want a tap device.  A
+	 * tap device is like a tun device, only somehow different.  To tell
+	 * the truth, I completely blundered my way through this code, but it
+	 * works now!
+	 */
+	netfd = open_or_die("/dev/net/tun", O_RDWR);
+	ifr.ifr_flags = IFF_TAP | IFF_NO_PI | IFF_VNET_HDR;
+	strcpy(ifr.ifr_name, "tap%d");
+	if (ioctl(netfd, TUNSETIFF, &ifr) != 0)
+		err(1, "configuring /dev/net/tun");
+
+	if (ioctl(netfd, TUNSETOFFLOAD,
+		  TUN_F_CSUM|TUN_F_TSO4|TUN_F_TSO6|TUN_F_TSO_ECN) != 0)
+		err(1, "Could not set features for tun device");
+
+	/*
+	 * We don't need checksums calculated for packets coming in this
+	 * device: trust us!
+	 */
+	ioctl(netfd, TUNSETNOCSUM, 1);
+
+	memcpy(tapif, ifr.ifr_name, IFNAMSIZ);
+	return netfd;
+}
+
+/*L:195
+ * Our network is a Host<->Guest network.  This can either use bridging or
+ * routing, but the principle is the same: it uses the "tun" device to inject
+ * packets into the Host as if they came in from a normal network card.  We
+ * just shunt packets between the Guest and the tun device.
+ */
+static void setup_tun_net(char *arg)
+{
+	struct device *dev;
+	struct net_info *net_info = malloc(sizeof(*net_info));
+	int ipfd;
+	u32 ip = INADDR_ANY;
+	bool bridging = false;
+	char tapif[IFNAMSIZ], *p;
+	struct virtio_net_config conf;
+
+	net_info->tunfd = get_tun_device(tapif);
+
+	/* First we create a new network device. */
+	dev = new_device("net", VIRTIO_ID_NET);
+	dev->priv = net_info;
+
+	/* Network devices need a recv and a send queue, just like console. */
+	add_virtqueue(dev, VIRTQUEUE_NUM, net_input);
+	add_virtqueue(dev, VIRTQUEUE_NUM, net_output);
+
+	/*
+	 * We need a socket to perform the magic network ioctls to bring up the
+	 * tap interface, connect to the bridge etc.  Any socket will do!
+	 */
+	ipfd = socket(PF_INET, SOCK_DGRAM, IPPROTO_IP);
+	if (ipfd < 0)
+		err(1, "opening IP socket");
+
+	/* If the command line was --tunnet=bridge:<name> do bridging. */
+	if (!strncmp(BRIDGE_PFX, arg, strlen(BRIDGE_PFX))) {
+		arg += strlen(BRIDGE_PFX);
+		bridging = true;
+	}
+
+	/* A mac address may follow the bridge name or IP address */
+	p = strchr(arg, ':');
+	if (p) {
+		str2mac(p+1, conf.mac);
+		add_feature(dev, VIRTIO_NET_F_MAC);
+		*p = '\0';
+	}
+
+	/* arg is now either an IP address or a bridge name */
+	if (bridging)
+		add_to_bridge(ipfd, tapif, arg);
+	else
+		ip = str2ip(arg);
+
+	/* Set up the tun device. */
+	configure_device(ipfd, tapif, ip);
+
+	/* Expect Guest to handle everything except UFO */
+	add_feature(dev, VIRTIO_NET_F_CSUM);
+	add_feature(dev, VIRTIO_NET_F_GUEST_CSUM);
+	add_feature(dev, VIRTIO_NET_F_GUEST_TSO4);
+	add_feature(dev, VIRTIO_NET_F_GUEST_TSO6);
+	add_feature(dev, VIRTIO_NET_F_GUEST_ECN);
+	add_feature(dev, VIRTIO_NET_F_HOST_TSO4);
+	add_feature(dev, VIRTIO_NET_F_HOST_TSO6);
+	add_feature(dev, VIRTIO_NET_F_HOST_ECN);
+	/* We handle indirect ring entries */
+	add_feature(dev, VIRTIO_RING_F_INDIRECT_DESC);
+	set_config(dev, sizeof(conf), &conf);
+
+	/* We don't need the socket any more; setup is done. */
+	close(ipfd);
+
+	devices.device_num++;
+
+	if (bridging)
+		verbose("device %u: tun %s attached to bridge: %s\n",
+			devices.device_num, tapif, arg);
+	else
+		verbose("device %u: tun %s: %s\n",
+			devices.device_num, tapif, arg);
+}
+/*:*/
+
+/* This hangs off device->priv. */
+struct vblk_info {
+	/* The size of the file. */
+	off64_t len;
+
+	/* The file descriptor for the file. */
+	int fd;
+
+};
+
+/*L:210
+ * The Disk
+ *
+ * The disk only has one virtqueue, so it only has one thread.  It is really
+ * simple: the Guest asks for a block number and we read or write that position
+ * in the file.
+ *
+ * Before we serviced each virtqueue in a separate thread, that was unacceptably
+ * slow: the Guest waits until the read is finished before running anything
+ * else, even if it could have been doing useful work.
+ *
+ * We could have used async I/O, except it's reputed to suck so hard that
+ * characters actually go missing from your code when you try to use it.
+ */
+static void blk_request(struct virtqueue *vq)
+{
+	struct vblk_info *vblk = vq->dev->priv;
+	unsigned int head, out_num, in_num, wlen;
+	int ret;
+	u8 *in;
+	struct virtio_blk_outhdr *out;
+	struct iovec iov[vq->vring.num];
+	off64_t off;
+
+	/*
+	 * Get the next request, where we normally wait.  It triggers the
+	 * interrupt to acknowledge previously serviced requests (if any).
+	 */
+	head = wait_for_vq_desc(vq, iov, &out_num, &in_num);
+
+	/*
+	 * Every block request should contain at least one output buffer
+	 * (detailing the location on disk and the type of request) and one
+	 * input buffer (to hold the result).
+	 */
+	if (out_num == 0 || in_num == 0)
+		errx(1, "Bad virtblk cmd %u out=%u in=%u",
+		     head, out_num, in_num);
+
+	out = convert(&iov[0], struct virtio_blk_outhdr);
+	in = convert(&iov[out_num+in_num-1], u8);
+	/*
+	 * For historical reasons, block operations are expressed in 512 byte
+	 * "sectors".
+	 */
+	off = out->sector * 512;
+
+	/*
+	 * In general the virtio block driver is allowed to try SCSI commands.
+	 * It'd be nice if we supported eject, for example, but we don't.
+	 */
+	if (out->type & VIRTIO_BLK_T_SCSI_CMD) {
+		fprintf(stderr, "Scsi commands unsupported\n");
+		*in = VIRTIO_BLK_S_UNSUPP;
+		wlen = sizeof(*in);
+	} else if (out->type & VIRTIO_BLK_T_OUT) {
+		/*
+		 * Write
+		 *
+		 * Move to the right location in the block file.  This can fail
+		 * if they try to write past end.
+		 */
+		if (lseek64(vblk->fd, off, SEEK_SET) != off)
+			err(1, "Bad seek to sector %llu", out->sector);
+
+		ret = writev(vblk->fd, iov+1, out_num-1);
+		verbose("WRITE to sector %llu: %i\n", out->sector, ret);
+
+		/*
+		 * Grr... Now we know how long the descriptor they sent was, we
+		 * make sure they didn't try to write over the end of the block
+		 * file (possibly extending it).
+		 */
+		if (ret > 0 && off + ret > vblk->len) {
+			/* Trim it back to the correct length */
+			ftruncate64(vblk->fd, vblk->len);
+			/* Die, bad Guest, die. */
+			errx(1, "Write past end %llu+%u", off, ret);
+		}
+
+		wlen = sizeof(*in);
+		*in = (ret >= 0 ? VIRTIO_BLK_S_OK : VIRTIO_BLK_S_IOERR);
+	} else if (out->type & VIRTIO_BLK_T_FLUSH) {
+		/* Flush */
+		ret = fdatasync(vblk->fd);
+		verbose("FLUSH fdatasync: %i\n", ret);
+		wlen = sizeof(*in);
+		*in = (ret >= 0 ? VIRTIO_BLK_S_OK : VIRTIO_BLK_S_IOERR);
+	} else {
+		/*
+		 * Read
+		 *
+		 * Move to the right location in the block file.  This can fail
+		 * if they try to read past end.
+		 */
+		if (lseek64(vblk->fd, off, SEEK_SET) != off)
+			err(1, "Bad seek to sector %llu", out->sector);
+
+		ret = readv(vblk->fd, iov+1, in_num-1);
+		verbose("READ from sector %llu: %i\n", out->sector, ret);
+		if (ret >= 0) {
+			wlen = sizeof(*in) + ret;
+			*in = VIRTIO_BLK_S_OK;
+		} else {
+			wlen = sizeof(*in);
+			*in = VIRTIO_BLK_S_IOERR;
+		}
+	}
+
+	/* Finished that request. */
+	add_used(vq, head, wlen);
+}
+
+/*L:198 This actually sets up a virtual block device. */
+static void setup_block_file(const char *filename)
+{
+	struct device *dev;
+	struct vblk_info *vblk;
+	struct virtio_blk_config conf;
+
+	/* Creat the device. */
+	dev = new_device("block", VIRTIO_ID_BLOCK);
+
+	/* The device has one virtqueue, where the Guest places requests. */
+	add_virtqueue(dev, VIRTQUEUE_NUM, blk_request);
+
+	/* Allocate the room for our own bookkeeping */
+	vblk = dev->priv = malloc(sizeof(*vblk));
+
+	/* First we open the file and store the length. */
+	vblk->fd = open_or_die(filename, O_RDWR|O_LARGEFILE);
+	vblk->len = lseek64(vblk->fd, 0, SEEK_END);
+
+	/* We support FLUSH. */
+	add_feature(dev, VIRTIO_BLK_F_FLUSH);
+
+	/* Tell Guest how many sectors this device has. */
+	conf.capacity = cpu_to_le64(vblk->len / 512);
+
+	/*
+	 * Tell Guest not to put in too many descriptors at once: two are used
+	 * for the in and out elements.
+	 */
+	add_feature(dev, VIRTIO_BLK_F_SEG_MAX);
+	conf.seg_max = cpu_to_le32(VIRTQUEUE_NUM - 2);
+
+	/* Don't try to put whole struct: we have 8 bit limit. */
+	set_config(dev, offsetof(struct virtio_blk_config, geometry), &conf);
+
+	verbose("device %u: virtblock %llu sectors\n",
+		++devices.device_num, le64_to_cpu(conf.capacity));
+}
+
+/*L:211
+ * Our random number generator device reads from /dev/random into the Guest's
+ * input buffers.  The usual case is that the Guest doesn't want random numbers
+ * and so has no buffers although /dev/random is still readable, whereas
+ * console is the reverse.
+ *
+ * The same logic applies, however.
+ */
+struct rng_info {
+	int rfd;
+};
+
+static void rng_input(struct virtqueue *vq)
+{
+	int len;
+	unsigned int head, in_num, out_num, totlen = 0;
+	struct rng_info *rng_info = vq->dev->priv;
+	struct iovec iov[vq->vring.num];
+
+	/* First we need a buffer from the Guests's virtqueue. */
+	head = wait_for_vq_desc(vq, iov, &out_num, &in_num);
+	if (out_num)
+		errx(1, "Output buffers in rng?");
+
+	/*
+	 * Just like the console write, we loop to cover the whole iovec.
+	 * In this case, short reads actually happen quite a bit.
+	 */
+	while (!iov_empty(iov, in_num)) {
+		len = readv(rng_info->rfd, iov, in_num);
+		if (len <= 0)
+			err(1, "Read from /dev/random gave %i", len);
+		iov_consume(iov, in_num, len);
+		totlen += len;
+	}
+
+	/* Tell the Guest about the new input. */
+	add_used(vq, head, totlen);
+}
+
+/*L:199
+ * This creates a "hardware" random number device for the Guest.
+ */
+static void setup_rng(void)
+{
+	struct device *dev;
+	struct rng_info *rng_info = malloc(sizeof(*rng_info));
+
+	/* Our device's privat info simply contains the /dev/random fd. */
+	rng_info->rfd = open_or_die("/dev/random", O_RDONLY);
+
+	/* Create the new device. */
+	dev = new_device("rng", VIRTIO_ID_RNG);
+	dev->priv = rng_info;
+
+	/* The device has one virtqueue, where the Guest places inbufs. */
+	add_virtqueue(dev, VIRTQUEUE_NUM, rng_input);
+
+	verbose("device %u: rng\n", devices.device_num++);
+}
+/* That's the end of device setup. */
+
+/*L:230 Reboot is pretty easy: clean up and exec() the Launcher afresh. */
+static void __attribute__((noreturn)) restart_guest(void)
+{
+	unsigned int i;
+
+	/*
+	 * Since we don't track all open fds, we simply close everything beyond
+	 * stderr.
+	 */
+	for (i = 3; i < FD_SETSIZE; i++)
+		close(i);
+
+	/* Reset all the devices (kills all threads). */
+	cleanup_devices();
+
+	execv(main_args[0], main_args);
+	err(1, "Could not exec %s", main_args[0]);
+}
+
+/*L:220
+ * Finally we reach the core of the Launcher which runs the Guest, serves
+ * its input and output, and finally, lays it to rest.
+ */
+static void __attribute__((noreturn)) run_guest(void)
+{
+	for (;;) {
+		unsigned long notify_addr;
+		int readval;
+
+		/* We read from the /dev/lguest device to run the Guest. */
+		readval = pread(lguest_fd, &notify_addr,
+				sizeof(notify_addr), cpu_id);
+
+		/* One unsigned long means the Guest did HCALL_NOTIFY */
+		if (readval == sizeof(notify_addr)) {
+			verbose("Notify on address %#lx\n", notify_addr);
+			handle_output(notify_addr);
+		/* ENOENT means the Guest died.  Reading tells us why. */
+		} else if (errno == ENOENT) {
+			char reason[1024] = { 0 };
+			pread(lguest_fd, reason, sizeof(reason)-1, cpu_id);
+			errx(1, "%s", reason);
+		/* ERESTART means that we need to reboot the guest */
+		} else if (errno == ERESTART) {
+			restart_guest();
+		/* Anything else means a bug or incompatible change. */
+		} else
+			err(1, "Running guest failed");
+	}
+}
+/*L:240
+ * This is the end of the Launcher.  The good news: we are over halfway
+ * through!  The bad news: the most fiendish part of the code still lies ahead
+ * of us.
+ *
+ * Are you ready?  Take a deep breath and join me in the core of the Host, in
+ * "make Host".
+:*/
+
+static struct option opts[] = {
+	{ "verbose", 0, NULL, 'v' },
+	{ "tunnet", 1, NULL, 't' },
+	{ "block", 1, NULL, 'b' },
+	{ "rng", 0, NULL, 'r' },
+	{ "initrd", 1, NULL, 'i' },
+	{ "username", 1, NULL, 'u' },
+	{ "chroot", 1, NULL, 'c' },
+	{ NULL },
+};
+static void usage(void)
+{
+	errx(1, "Usage: lguest [--verbose] "
+	     "[--tunnet=(<ipaddr>:<macaddr>|bridge:<bridgename>:<macaddr>)\n"
+	     "|--block=<filename>|--initrd=<filename>]...\n"
+	     "<mem-in-mb> vmlinux [args...]");
+}
+
+/*L:105 The main routine is where the real work begins: */
+int main(int argc, char *argv[])
+{
+	/* Memory, code startpoint and size of the (optional) initrd. */
+	unsigned long mem = 0, start, initrd_size = 0;
+	/* Two temporaries. */
+	int i, c;
+	/* The boot information for the Guest. */
+	struct boot_params *boot;
+	/* If they specify an initrd file to load. */
+	const char *initrd_name = NULL;
+
+	/* Password structure for initgroups/setres[gu]id */
+	struct passwd *user_details = NULL;
+
+	/* Directory to chroot to */
+	char *chroot_path = NULL;
+
+	/* Save the args: we "reboot" by execing ourselves again. */
+	main_args = argv;
+
+	/*
+	 * First we initialize the device list.  We keep a pointer to the last
+	 * device, and the next interrupt number to use for devices (1:
+	 * remember that 0 is used by the timer).
+	 */
+	devices.lastdev = NULL;
+	devices.next_irq = 1;
+
+	/* We're CPU 0.  In fact, that's the only CPU possible right now. */
+	cpu_id = 0;
+
+	/*
+	 * We need to know how much memory so we can set up the device
+	 * descriptor and memory pages for the devices as we parse the command
+	 * line.  So we quickly look through the arguments to find the amount
+	 * of memory now.
+	 */
+	for (i = 1; i < argc; i++) {
+		if (argv[i][0] != '-') {
+			mem = atoi(argv[i]) * 1024 * 1024;
+			/*
+			 * We start by mapping anonymous pages over all of
+			 * guest-physical memory range.  This fills it with 0,
+			 * and ensures that the Guest won't be killed when it
+			 * tries to access it.
+			 */
+			guest_base = map_zeroed_pages(mem / getpagesize()
+						      + DEVICE_PAGES);
+			guest_limit = mem;
+			guest_max = mem + DEVICE_PAGES*getpagesize();
+			devices.descpage = get_pages(1);
+			break;
+		}
+	}
+
+	/* The options are fairly straight-forward */
+	while ((c = getopt_long(argc, argv, "v", opts, NULL)) != EOF) {
+		switch (c) {
+		case 'v':
+			verbose = true;
+			break;
+		case 't':
+			setup_tun_net(optarg);
+			break;
+		case 'b':
+			setup_block_file(optarg);
+			break;
+		case 'r':
+			setup_rng();
+			break;
+		case 'i':
+			initrd_name = optarg;
+			break;
+		case 'u':
+			user_details = getpwnam(optarg);
+			if (!user_details)
+				err(1, "getpwnam failed, incorrect username?");
+			break;
+		case 'c':
+			chroot_path = optarg;
+			break;
+		default:
+			warnx("Unknown argument %s", argv[optind]);
+			usage();
+		}
+	}
+	/*
+	 * After the other arguments we expect memory and kernel image name,
+	 * followed by command line arguments for the kernel.
+	 */
+	if (optind + 2 > argc)
+		usage();
+
+	verbose("Guest base is at %p\n", guest_base);
+
+	/* We always have a console device */
+	setup_console();
+
+	/* Now we load the kernel */
+	start = load_kernel(open_or_die(argv[optind+1], O_RDONLY));
+
+	/* Boot information is stashed at physical address 0 */
+	boot = from_guest_phys(0);
+
+	/* Map the initrd image if requested (at top of physical memory) */
+	if (initrd_name) {
+		initrd_size = load_initrd(initrd_name, mem);
+		/*
+		 * These are the location in the Linux boot header where the
+		 * start and size of the initrd are expected to be found.
+		 */
+		boot->hdr.ramdisk_image = mem - initrd_size;
+		boot->hdr.ramdisk_size = initrd_size;
+		/* The bootloader type 0xFF means "unknown"; that's OK. */
+		boot->hdr.type_of_loader = 0xFF;
+	}
+
+	/*
+	 * The Linux boot header contains an "E820" memory map: ours is a
+	 * simple, single region.
+	 */
+	boot->e820_entries = 1;
+	boot->e820_map[0] = ((struct e820entry) { 0, mem, E820_RAM });
+	/*
+	 * The boot header contains a command line pointer: we put the command
+	 * line after the boot header.
+	 */
+	boot->hdr.cmd_line_ptr = to_guest_phys(boot + 1);
+	/* We use a simple helper to copy the arguments separated by spaces. */
+	concat((char *)(boot + 1), argv+optind+2);
+
+	/* Boot protocol version: 2.07 supports the fields for lguest. */
+	boot->hdr.version = 0x207;
+
+	/* The hardware_subarch value of "1" tells the Guest it's an lguest. */
+	boot->hdr.hardware_subarch = 1;
+
+	/* Tell the entry path not to try to reload segment registers. */
+	boot->hdr.loadflags |= KEEP_SEGMENTS;
+
+	/*
+	 * We tell the kernel to initialize the Guest: this returns the open
+	 * /dev/lguest file descriptor.
+	 */
+	tell_kernel(start);
+
+	/* Ensure that we terminate if a device-servicing child dies. */
+	signal(SIGCHLD, kill_launcher);
+
+	/* If we exit via err(), this kills all the threads, restores tty. */
+	atexit(cleanup_devices);
+
+	/* If requested, chroot to a directory */
+	if (chroot_path) {
+		if (chroot(chroot_path) != 0)
+			err(1, "chroot(\"%s\") failed", chroot_path);
+
+		if (chdir("/") != 0)
+			err(1, "chdir(\"/\") failed");
+
+		verbose("chroot done\n");
+	}
+
+	/* If requested, drop privileges */
+	if (user_details) {
+		uid_t u;
+		gid_t g;
+
+		u = user_details->pw_uid;
+		g = user_details->pw_gid;
+
+		if (initgroups(user_details->pw_name, g) != 0)
+			err(1, "initgroups failed");
+
+		if (setresgid(g, g, g) != 0)
+			err(1, "setresgid failed");
+
+		if (setresuid(u, u, u) != 0)
+			err(1, "setresuid failed");
+
+		verbose("Dropping privileges completed\n");
+	}
+
+	/* Finally, run the Guest.  This doesn't return. */
+	run_guest();
+}
+/*:*/
+
+/*M:999
+ * Mastery is done: you now know everything I do.
+ *
+ * But surely you have seen code, features and bugs in your wanderings which
+ * you now yearn to attack?  That is the real game, and I look forward to you
+ * patching and forking lguest into the Your-Name-Here-visor.
+ *
+ * Farewell, and good coding!
+ * Rusty Russell.
+ */
diff -druN linux-2.6.39-libre/Documentation/virtual/lguest/lguest.txt linux-3.0-rc7-libre/Documentation/virtual/lguest/lguest.txt
--- linux-2.6.39-libre/Documentation/virtual/lguest/lguest.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/Documentation/virtual/lguest/lguest.txt	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,129 @@
+      __
+ (___()'`;  Rusty's Remarkably Unreliable Guide to Lguest
+ /,    /`      - or, A Young Coder's Illustrated Hypervisor
+ \\"--\\    http://lguest.ozlabs.org
+
+Lguest is designed to be a minimal 32-bit x86 hypervisor for the Linux kernel,
+for Linux developers and users to experiment with virtualization with the
+minimum of complexity.  Nonetheless, it should have sufficient features to
+make it useful for specific tasks, and, of course, you are encouraged to fork
+and enhance it (see drivers/lguest/README).
+
+Features:
+
+- Kernel module which runs in a normal kernel.
+- Simple I/O model for communication.
+- Simple program to create new guests.
+- Logo contains cute puppies: http://lguest.ozlabs.org
+
+Developer features:
+
+- Fun to hack on.
+- No ABI: being tied to a specific kernel anyway, you can change anything.
+- Many opportunities for improvement or feature implementation.
+
+Running Lguest:
+
+- The easiest way to run lguest is to use same kernel as guest and host.
+  You can configure them differently, but usually it's easiest not to.
+
+  You will need to configure your kernel with the following options:
+
+  "General setup":
+     "Prompt for development and/or incomplete code/drivers" = Y
+        (CONFIG_EXPERIMENTAL=y)
+
+  "Processor type and features":
+     "Paravirtualized guest support" = Y
+        "Lguest guest support" = Y
+     "High Memory Support" = off/4GB
+     "Alignment value to which kernel should be aligned" = 0x100000
+        (CONFIG_PARAVIRT=y, CONFIG_LGUEST_GUEST=y, CONFIG_HIGHMEM64G=n and
+         CONFIG_PHYSICAL_ALIGN=0x100000)
+
+  "Device Drivers":
+     "Block devices"
+        "Virtio block driver (EXPERIMENTAL)" = M/Y
+     "Network device support"
+        "Universal TUN/TAP device driver support" = M/Y
+        "Virtio network driver (EXPERIMENTAL)" = M/Y
+           (CONFIG_VIRTIO_BLK=m, CONFIG_VIRTIO_NET=m and CONFIG_TUN=m)
+
+  "Virtualization"
+     "Linux hypervisor example code" = M/Y
+        (CONFIG_LGUEST=m)
+
+- A tool called "lguest" is available in this directory: type "make"
+  to build it.  If you didn't build your kernel in-tree, use "make
+  O=<builddir>".
+
+- Create or find a root disk image.  There are several useful ones
+  around, such as the xm-test tiny root image at
+	  http://xm-test.xensource.com/ramdisks/initrd-1.1-i386.img
+
+  For more serious work, I usually use a distribution ISO image and
+  install it under qemu, then make multiple copies:
+
+	  dd if=/dev/zero of=rootfile bs=1M count=2048
+	  qemu -cdrom image.iso -hda rootfile -net user -net nic -boot d
+
+  Make sure that you install a getty on /dev/hvc0 if you want to log in on the
+  console!
+
+- "modprobe lg" if you built it as a module.
+
+- Run an lguest as root:
+
+      Documentation/virtual/lguest/lguest 64 vmlinux --tunnet=192.168.19.1 \
+        --block=rootfile root=/dev/vda
+
+   Explanation:
+    64: the amount of memory to use, in MB.
+
+    vmlinux: the kernel image found in the top of your build directory.  You
+       can also use a standard bzImage.
+
+    --tunnet=192.168.19.1: configures a "tap" device for networking with this
+       IP address.
+
+    --block=rootfile: a file or block device which becomes /dev/vda
+       inside the guest.
+
+    root=/dev/vda: this (and anything else on the command line) are
+       kernel boot parameters.
+
+- Configuring networking.  I usually have the host masquerade, using
+  "iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE" and "echo 1 >
+  /proc/sys/net/ipv4/ip_forward".  In this example, I would configure
+  eth0 inside the guest at 192.168.19.2.
+
+  Another method is to bridge the tap device to an external interface
+  using --tunnet=bridge:<bridgename>, and perhaps run dhcp on the guest
+  to obtain an IP address.  The bridge needs to be configured first:
+  this option simply adds the tap interface to it.
+
+  A simple example on my system:
+
+    ifconfig eth0 0.0.0.0
+    brctl addbr lg0
+    ifconfig lg0 up
+    brctl addif lg0 eth0
+    dhclient lg0
+
+  Then use --tunnet=bridge:lg0 when launching the guest.
+
+  See:
+  
+    http://www.linuxfoundation.org/collaborate/workgroups/networking/bridge
+    
+  for general information on how to get bridging to work.
+
+- Random number generation. Using the --rng option will provide a
+  /dev/hwrng in the guest that will read from the host's /dev/random.
+  Use this option in conjunction with rng-tools (see ../hw_random.txt)
+  to provide entropy to the guest kernel's /dev/random.
+
+There is a helpful mailing list at http://ozlabs.org/mailman/listinfo/lguest
+
+Good luck!
+Rusty Russell rusty@rustcorp.com.au.
diff -druN linux-2.6.39-libre/Documentation/virtual/lguest/Makefile linux-3.0-rc7-libre/Documentation/virtual/lguest/Makefile
--- linux-2.6.39-libre/Documentation/virtual/lguest/Makefile	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/Documentation/virtual/lguest/Makefile	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,8 @@
+# This creates the demonstration utility "lguest" which runs a Linux guest.
+# Missing headers?  Add "-I../../../include -I../../../arch/x86/include"
+CFLAGS:=-m32 -Wall -Wmissing-declarations -Wmissing-prototypes -O3 -U_FORTIFY_SOURCE
+
+all: lguest
+
+clean:
+	rm -f lguest
diff -druN linux-2.6.39-libre/Documentation/virtual/uml/UserModeLinux-HOWTO.txt linux-3.0-rc7-libre/Documentation/virtual/uml/UserModeLinux-HOWTO.txt
--- linux-2.6.39-libre/Documentation/virtual/uml/UserModeLinux-HOWTO.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/Documentation/virtual/uml/UserModeLinux-HOWTO.txt	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,4589 @@
+  User Mode Linux HOWTO
+  User Mode Linux Core Team
+  Mon Nov 18 14:16:16 EST 2002
+
+  This document describes the use and abuse of Jeff Dike's User Mode
+  Linux: a port of the Linux kernel as a normal Intel Linux process.
+  ______________________________________________________________________
+
+  Table of Contents
+
+  1. Introduction
+
+     1.1 How is User Mode Linux Different?
+     1.2 Why Would I Want User Mode Linux?
+
+  2. Compiling the kernel and modules
+
+     2.1 Compiling the kernel
+     2.2 Compiling and installing kernel modules
+     2.3 Compiling and installing uml_utilities
+
+  3. Running UML and logging in
+
+     3.1 Running UML
+     3.2 Logging in
+     3.3 Examples
+
+  4. UML on 2G/2G hosts
+
+     4.1 Introduction
+     4.2 The problem
+     4.3 The solution
+
+  5. Setting up serial lines and consoles
+
+     5.1 Specifying the device
+     5.2 Specifying the channel
+     5.3 Examples
+
+  6. Setting up the network
+
+     6.1 General setup
+     6.2 Userspace daemons
+     6.3 Specifying ethernet addresses
+     6.4 UML interface setup
+     6.5 Multicast
+     6.6 TUN/TAP with the uml_net helper
+     6.7 TUN/TAP with a preconfigured tap device
+     6.8 Ethertap
+     6.9 The switch daemon
+     6.10 Slip
+     6.11 Slirp
+     6.12 pcap
+     6.13 Setting up the host yourself
+
+  7. Sharing Filesystems between Virtual Machines
+
+     7.1 A warning
+     7.2 Using layered block devices
+     7.3 Note!
+     7.4 Another warning
+     7.5 uml_moo : Merging a COW file with its backing file
+
+  8. Creating filesystems
+
+     8.1 Create the filesystem file
+     8.2 Assign the file to a UML device
+     8.3 Creating and mounting the filesystem
+
+  9. Host file access
+
+     9.1 Using hostfs
+     9.2 hostfs as the root filesystem
+     9.3 Building hostfs
+
+  10. The Management Console
+     10.1 version
+     10.2 halt and reboot
+     10.3 config
+     10.4 remove
+     10.5 sysrq
+     10.6 help
+     10.7 cad
+     10.8 stop
+     10.9 go
+
+  11. Kernel debugging
+
+     11.1 Starting the kernel under gdb
+     11.2 Examining sleeping processes
+     11.3 Running ddd on UML
+     11.4 Debugging modules
+     11.5 Attaching gdb to the kernel
+     11.6 Using alternate debuggers
+
+  12. Kernel debugging examples
+
+     12.1 The case of the hung fsck
+     12.2 Episode 2: The case of the hung fsck
+
+  13. What to do when UML doesn't work
+
+     13.1 Strange compilation errors when you build from source
+     13.2 (obsolete)
+     13.3 A variety of panics and hangs with /tmp on a reiserfs  filesystem
+     13.4 The compile fails with errors about conflicting types for 'open', 'dup', and 'waitpid'
+     13.5 UML doesn't work when /tmp is an NFS filesystem
+     13.6 UML hangs on boot when compiled with gprof support
+     13.7 syslogd dies with a SIGTERM on startup
+     13.8 TUN/TAP networking doesn't work on a 2.4 host
+     13.9 You can network to the host but not to other machines on the net
+     13.10 I have no root and I want to scream
+     13.11 UML build conflict between ptrace.h and ucontext.h
+     13.12 The UML BogoMips is exactly half the host's BogoMips
+     13.13 When you run UML, it immediately segfaults
+     13.14 xterms appear, then immediately disappear
+     13.15 Any other panic, hang, or strange behavior
+
+  14. Diagnosing Problems
+
+     14.1 Case 1 : Normal kernel panics
+     14.2 Case 2 : Tracing thread panics
+     14.3 Case 3 : Tracing thread panics caused by other threads
+     14.4 Case 4 : Hangs
+
+  15. Thanks
+
+     15.1 Code and Documentation
+     15.2 Flushing out bugs
+     15.3 Buglets and clean-ups
+     15.4 Case Studies
+     15.5 Other contributions
+
+
+  ______________________________________________________________________
+
+  11..  IInnttrroodduuccttiioonn
+
+  Welcome to User Mode Linux.  It's going to be fun.
+
+
+
+  11..11..  HHooww iiss UUsseerr MMooddee LLiinnuuxx DDiiffffeerreenntt??
+
+  Normally, the Linux Kernel talks straight to your hardware (video
+  card, keyboard, hard drives, etc), and any programs which run ask the
+  kernel to operate the hardware, like so:
+
+
+
+         +-----------+-----------+----+
+         | Process 1 | Process 2 | ...|
+         +-----------+-----------+----+
+         |       Linux Kernel         |
+         +----------------------------+
+         |         Hardware           |
+         +----------------------------+
+
+
+
+
+  The User Mode Linux Kernel is different; instead of talking to the
+  hardware, it talks to a `real' Linux kernel (called the `host kernel'
+  from now on), like any other program.  Programs can then run inside
+  User-Mode Linux as if they were running under a normal kernel, like
+  so:
+
+
+
+                     +----------------+
+                     | Process 2 | ...|
+         +-----------+----------------+
+         | Process 1 | User-Mode Linux|
+         +----------------------------+
+         |       Linux Kernel         |
+         +----------------------------+
+         |         Hardware           |
+         +----------------------------+
+
+
+
+
+
+  11..22..  WWhhyy WWoouulldd II WWaanntt UUsseerr MMooddee LLiinnuuxx??
+
+
+  1. If User Mode Linux crashes, your host kernel is still fine.
+
+  2. You can run a usermode kernel as a non-root user.
+
+  3. You can debug the User Mode Linux like any normal process.
+
+  4. You can run gprof (profiling) and gcov (coverage testing).
+
+  5. You can play with your kernel without breaking things.
+
+  6. You can use it as a sandbox for testing new apps.
+
+  7. You can try new development kernels safely.
+
+  8. You can run different distributions simultaneously.
+
+  9. It's extremely fun.
+
+
+
+
+
+  22..  CCoommppiilliinngg tthhee kkeerrnneell aanndd mmoodduulleess
+
+
+
+
+  22..11..  CCoommppiilliinngg tthhee kkeerrnneell
+
+
+  Compiling the user mode kernel is just like compiling any other
+  kernel.  Let's go through the steps, using 2.4.0-prerelease (current
+  as of this writing) as an example:
+
+
+  1. Download the latest UML patch from
+
+     the download page <http://user-mode-linux.sourceforge.net/
+
+     In this example, the file is uml-patch-2.4.0-prerelease.bz2.
+
+
+  2. Download the matching kernel from your favourite kernel mirror,
+     such as:
+
+     ftp://ftp.ca.kernel.org/pub/kernel/v2.4/linux-2.4.0-prerelease.tar.bz2
+     <ftp://ftp.ca.kernel.org/pub/kernel/v2.4/linux-2.4.0-prerelease.tar.bz2>
+     .
+
+
+  3. Make a directory and unpack the kernel into it.
+
+
+
+       host%
+       mkdir ~/uml
+
+
+
+
+
+
+       host%
+       cd ~/uml
+
+
+
+
+
+
+       host%
+       tar -xzvf linux-2.4.0-prerelease.tar.bz2
+
+
+
+
+
+
+  4. Apply the patch using
+
+
+
+       host%
+       cd ~/uml/linux
+
+
+
+       host%
+       bzcat uml-patch-2.4.0-prerelease.bz2 | patch -p1
+
+
+
+
+
+
+  5. Run your favorite config; `make xconfig ARCH=um' is the most
+     convenient.  `make config ARCH=um' and 'make menuconfig ARCH=um'
+     will work as well.  The defaults will give you a useful kernel.  If
+     you want to change something, go ahead, it probably won't hurt
+     anything.
+
+
+     Note:  If the host is configured with a 2G/2G address space split
+     rather than the usual 3G/1G split, then the packaged UML binaries
+     will not run.  They will immediately segfault.  See ``UML on 2G/2G
+     hosts''  for the scoop on running UML on your system.
+
+
+
+  6. Finish with `make linux ARCH=um': the result is a file called
+     `linux' in the top directory of your source tree.
+
+  Make sure that you don't build this kernel in /usr/src/linux.  On some
+  distributions, /usr/include/asm is a link into this pool.  The user-
+  mode build changes the other end of that link, and things that include
+  <asm/anything.h> stop compiling.
+
+  The sources are also available from cvs at the project's cvs page,
+  which has directions on getting the sources. You can also browse the
+  CVS pool from there.
+
+  If you get the CVS sources, you will have to check them out into an
+  empty directory. You will then have to copy each file into the
+  corresponding directory in the appropriate kernel pool.
+
+  If you don't have the latest kernel pool, you can get the
+  corresponding user-mode sources with
+
+
+       host% cvs co -r v_2_3_x linux
+
+
+
+
+  where 'x' is the version in your pool. Note that you will not get the
+  bug fixes and enhancements that have gone into subsequent releases.
+
+
+  22..22..  CCoommppiilliinngg aanndd iinnssttaalllliinngg kkeerrnneell mmoodduulleess
+
+  UML modules are built in the same way as the native kernel (with the
+  exception of the 'ARCH=um' that you always need for UML):
+
+
+       host% make modules ARCH=um
+
+
+
+
+  Any modules that you want to load into this kernel need to be built in
+  the user-mode pool.  Modules from the native kernel won't work.
+
+  You can install them by using ftp or something to copy them into the
+  virtual machine and dropping them into /lib/modules/`uname -r`.
+
+  You can also get the kernel build process to install them as follows:
+
+  1. with the kernel not booted, mount the root filesystem in the top
+     level of the kernel pool:
+
+
+       host% mount root_fs mnt -o loop
+
+
+
+
+
+
+  2. run
+
+
+       host%
+       make modules_install INSTALL_MOD_PATH=`pwd`/mnt ARCH=um
+
+
+
+
+
+
+  3. unmount the filesystem
+
+
+       host% umount mnt
+
+
+
+
+
+
+  4. boot the kernel on it
+
+
+  When the system is booted, you can use insmod as usual to get the
+  modules into the kernel.  A number of things have been loaded into UML
+  as modules, especially filesystems and network protocols and filters,
+  so most symbols which need to be exported probably already are.
+  However, if you do find symbols that need exporting, let  us
+  <http://user-mode-linux.sourceforge.net/>  know, and
+  they'll be "taken care of".
+
+
+
+  22..33..  CCoommppiilliinngg aanndd iinnssttaalllliinngg uummll__uuttiilliittiieess
+
+  Many features of the UML kernel require a user-space helper program,
+  so a uml_utilities package is distributed separately from the kernel
+  patch which provides these helpers. Included within this is:
+
+  +o  port-helper - Used by consoles which connect to xterms or ports
+
+  +o  tunctl - Configuration tool to create and delete tap devices
+
+  +o  uml_net - Setuid binary for automatic tap device configuration
+
+  +o  uml_switch - User-space virtual switch required for daemon
+     transport
+
+     The uml_utilities tree is compiled with:
+
+
+       host#
+       make && make install
+
+
+
+
+  Note that UML kernel patches may require a specific version of the
+  uml_utilities distribution. If you don't keep up with the mailing
+  lists, ensure that you have the latest release of uml_utilities if you
+  are experiencing problems with your UML kernel, particularly when
+  dealing with consoles or command-line switches to the helper programs
+
+
+
+
+
+
+
+
+  33..  RRuunnnniinngg UUMMLL aanndd llooggggiinngg iinn
+
+
+
+  33..11..  RRuunnnniinngg UUMMLL
+
+  It runs on 2.2.15 or later, and all 2.4 kernels.
+
+
+  Booting UML is straightforward.  Simply run 'linux': it will try to
+  mount the file `root_fs' in the current directory.  You do not need to
+  run it as root.  If your root filesystem is not named `root_fs', then
+  you need to put a `ubd0=root_fs_whatever' switch on the linux command
+  line.
+
+
+  You will need a filesystem to boot UML from.  There are a number
+  available for download from  here  <http://user-mode-
+  linux.sourceforge.net/> .  There are also  several tools
+  <http://user-mode-linux.sourceforge.net/>  which can be
+  used to generate UML-compatible filesystem images from media.
+  The kernel will boot up and present you with a login prompt.
+
+
+  Note:  If the host is configured with a 2G/2G address space split
+  rather than the usual 3G/1G split, then the packaged UML binaries will
+  not run.  They will immediately segfault.  See ``UML on 2G/2G hosts''
+  for the scoop on running UML on your system.
+
+
+
+  33..22..  LLooggggiinngg iinn
+
+
+
+  The prepackaged filesystems have a root account with password 'root'
+  and a user account with password 'user'.  The login banner will
+  generally tell you how to log in.  So, you log in and you will find
+  yourself inside a little virtual machine. Our filesystems have a
+  variety of commands and utilities installed (and it is fairly easy to
+  add more), so you will have a lot of tools with which to poke around
+  the system.
+
+  There are a couple of other ways to log in:
+
+  +o  On a virtual console
+
+
+
+     Each virtual console that is configured (i.e. the device exists in
+     /dev and /etc/inittab runs a getty on it) will come up in its own
+     xterm.  If you get tired of the xterms, read ``Setting up serial
+     lines and consoles''  to see how to attach the consoles to
+     something else, like host ptys.
+
+
+
+  +o  Over the serial line
+
+
+     In the boot output, find a line that looks like:
+
+
+
+       serial line 0 assigned pty /dev/ptyp1
+
+
+
+
+  Attach your favorite terminal program to the corresponding tty.  I.e.
+  for minicom, the command would be
+
+
+       host% minicom -o -p /dev/ttyp1
+
+
+
+
+
+
+  +o  Over the net
+
+
+     If the network is running, then you can telnet to the virtual
+     machine and log in to it.  See ``Setting up the network''  to learn
+     about setting up a virtual network.
+
+  When you're done using it, run halt, and the kernel will bring itself
+  down and the process will exit.
+
+
+  33..33..  EExxaammpplleess
+
+  Here are some examples of UML in action:
+
+  +o  A login session <http://user-mode-linux.sourceforge.net/login.html>
+
+  +o  A virtual network <http://user-mode-linux.sourceforge.net/net.html>
+
+
+
+
+
+
+
+  44..  UUMMLL oonn 22GG//22GG hhoossttss
+
+
+
+
+  44..11..  IInnttrroodduuccttiioonn
+
+
+  Most Linux machines are configured so that the kernel occupies the
+  upper 1G (0xc0000000 - 0xffffffff) of the 4G address space and
+  processes use the lower 3G (0x00000000 - 0xbfffffff).  However, some
+  machine are configured with a 2G/2G split, with the kernel occupying
+  the upper 2G (0x80000000 - 0xffffffff) and processes using the lower
+  2G (0x00000000 - 0x7fffffff).
+
+
+
+
+  44..22..  TThhee pprroobblleemm
+
+
+  The prebuilt UML binaries on this site will not run on 2G/2G hosts
+  because UML occupies the upper .5G of the 3G process address space
+  (0xa0000000 - 0xbfffffff).  Obviously, on 2G/2G hosts, this is right
+  in the middle of the kernel address space, so UML won't even load - it
+  will immediately segfault.
+
+
+
+
+  44..33..  TThhee ssoolluuttiioonn
+
+
+  The fix for this is to rebuild UML from source after enabling
+  CONFIG_HOST_2G_2G (under 'General Setup').  This will cause UML to
+  load itself in the top .5G of that smaller process address space,
+  where it will run fine.  See ``Compiling the kernel and modules''  if
+  you need help building UML from source.
+
+
+
+
+
+
+
+
+
+
+  55..  SSeettttiinngg uupp sseerriiaall lliinneess aanndd ccoonnssoolleess
+
+
+  It is possible to attach UML serial lines and consoles to many types
+  of host I/O channels by specifying them on the command line.
+
+
+  You can attach them to host ptys, ttys, file descriptors, and ports.
+  This allows you to do things like
+
+  +o  have a UML console appear on an unused host console,
+
+  +o  hook two virtual machines together by having one attach to a pty
+     and having the other attach to the corresponding tty
+
+  +o  make a virtual machine accessible from the net by attaching a
+     console to a port on the host.
+
+
+  The general format of the command line option is device=channel.
+
+
+
+  55..11..  SSppeecciiffyyiinngg tthhee ddeevviiccee
+
+  Devices are specified with "con" or "ssl" (console or serial line,
+  respectively), optionally with a device number if you are talking
+  about a specific device.
+
+
+  Using just "con" or "ssl" describes all of the consoles or serial
+  lines.  If you want to talk about console #3 or serial line #10, they
+  would be "con3" and "ssl10", respectively.
+
+
+  A specific device name will override a less general "con=" or "ssl=".
+  So, for example, you can assign a pty to each of the serial lines
+  except for the first two like this:
+
+
+        ssl=pty ssl0=tty:/dev/tty0 ssl1=tty:/dev/tty1
+
+
+
+
+  The specificity of the device name is all that matters; order on the
+  command line is irrelevant.
+
+
+
+  55..22..  SSppeecciiffyyiinngg tthhee cchhaannnneell
+
+  There are a number of different types of channels to attach a UML
+  device to, each with a different way of specifying exactly what to
+  attach to.
+
+  +o  pseudo-terminals - device=pty pts terminals - device=pts
+
+
+     This will cause UML to allocate a free host pseudo-terminal for the
+     device.  The terminal that it got will be announced in the boot
+     log.  You access it by attaching a terminal program to the
+     corresponding tty:
+
+  +o  screen /dev/pts/n
+
+  +o  screen /dev/ttyxx
+
+  +o  minicom -o -p /dev/ttyxx - minicom seems not able to handle pts
+     devices
+
+  +o  kermit - start it up, 'open' the device, then 'connect'
+
+
+
+
+
+  +o  terminals - device=tty:tty device file
+
+
+     This will make UML attach the device to the specified tty (i.e
+
+
+        con1=tty:/dev/tty3
+
+
+
+
+  will attach UML's console 1 to the host's /dev/tty3).  If the tty that
+  you specify is the slave end of a tty/pty pair, something else must
+  have already opened the corresponding pty in order for this to work.
+
+
+
+
+
+  +o  xterms - device=xterm
+
+
+     UML will run an xterm and the device will be attached to it.
+
+
+
+
+
+  +o  Port - device=port:port number
+
+
+     This will attach the UML devices to the specified host port.
+     Attaching console 1 to the host's port 9000 would be done like
+     this:
+
+
+        con1=port:9000
+
+
+
+
+  Attaching all the serial lines to that port would be done similarly:
+
+
+        ssl=port:9000
+
+
+
+
+  You access these devices by telnetting to that port.  Each active tel-
+  net session gets a different device.  If there are more telnets to a
+  port than UML devices attached to it, then the extra telnet sessions
+  will block until an existing telnet detaches, or until another device
+  becomes active (i.e. by being activated in /etc/inittab).
+
+  This channel has the advantage that you can both attach multiple UML
+  devices to it and know how to access them without reading the UML boot
+  log.  It is also unique in allowing access to a UML from remote
+  machines without requiring that the UML be networked.  This could be
+  useful in allowing public access to UMLs because they would be
+  accessible from the net, but wouldn't need any kind of network
+  filtering or access control because they would have no network access.
+
+
+  If you attach the main console to a portal, then the UML boot will
+  appear to hang.  In reality, it's waiting for a telnet to connect, at
+  which point the boot will proceed.
+
+
+
+
+
+  +o  already-existing file descriptors - device=file descriptor
+
+
+     If you set up a file descriptor on the UML command line, you can
+     attach a UML device to it.  This is most commonly used to put the
+     main console back on stdin and stdout after assigning all the other
+     consoles to something else:
+
+
+        con0=fd:0,fd:1 con=pts
+
+
+
+
+
+
+
+
+  +o  Nothing - device=null
+
+
+     This allows the device to be opened, in contrast to 'none', but
+     reads will block, and writes will succeed and the data will be
+     thrown out.
+
+
+
+
+
+  +o  None - device=none
+
+
+     This causes the device to disappear.
+
+
+
+  You can also specify different input and output channels for a device
+  by putting a comma between them:
+
+
+        ssl3=tty:/dev/tty2,xterm
+
+
+
+
+  will cause serial line 3 to accept input on the host's /dev/tty3 and
+  display output on an xterm.  That's a silly example - the most common
+  use of this syntax is to reattach the main console to stdin and stdout
+  as shown above.
+
+
+  If you decide to move the main console away from stdin/stdout, the
+  initial boot output will appear in the terminal that you're running
+  UML in.  However, once the console driver has been officially
+  initialized, then the boot output will start appearing wherever you
+  specified that console 0 should be.  That device will receive all
+  subsequent output.
+
+
+
+  55..33..  EExxaammpplleess
+
+  There are a number of interesting things you can do with this
+  capability.
+
+
+  First, this is how you get rid of those bleeding console xterms by
+  attaching them to host ptys:
+
+
+        con=pty con0=fd:0,fd:1
+
+
+
+
+  This will make a UML console take over an unused host virtual console,
+  so that when you switch to it, you will see the UML login prompt
+  rather than the host login prompt:
+
+
+        con1=tty:/dev/tty6
+
+
+
+
+  You can attach two virtual machines together with what amounts to a
+  serial line as follows:
+
+  Run one UML with a serial line attached to a pty -
+
+
+        ssl1=pty
+
+
+
+
+  Look at the boot log to see what pty it got (this example will assume
+  that it got /dev/ptyp1).
+
+  Boot the other UML with a serial line attached to the corresponding
+  tty -
+
+
+        ssl1=tty:/dev/ttyp1
+
+
+
+
+  Log in, make sure that it has no getty on that serial line, attach a
+  terminal program like minicom to it, and you should see the login
+  prompt of the other virtual machine.
+
+
+  66..  SSeettttiinngg uupp tthhee nneettwwoorrkk
+
+
+
+  This page describes how to set up the various transports and to
+  provide a UML instance with network access to the host, other machines
+  on the local net, and the rest of the net.
+
+
+  As of 2.4.5, UML networking has been completely redone to make it much
+  easier to set up, fix bugs, and add new features.
+
+
+  There is a new helper, uml_net, which does the host setup that
+  requires root privileges.
+
+
+  There are currently five transport types available for a UML virtual
+  machine to exchange packets with other hosts:
+
+  +o  ethertap
+
+  +o  TUN/TAP
+
+  +o  Multicast
+
+  +o  a switch daemon
+
+  +o  slip
+
+  +o  slirp
+
+  +o  pcap
+
+     The TUN/TAP, ethertap, slip, and slirp transports allow a UML
+     instance to exchange packets with the host.  They may be directed
+     to the host or the host may just act as a router to provide access
+     to other physical or virtual machines.
+
+
+  The pcap transport is a synthetic read-only interface, using the
+  libpcap binary to collect packets from interfaces on the host and
+  filter them.  This is useful for building preconfigured traffic
+  monitors or sniffers.
+
+
+  The daemon and multicast transports provide a completely virtual
+  network to other virtual machines.  This network is completely
+  disconnected from the physical network unless one of the virtual
+  machines on it is acting as a gateway.
+
+
+  With so many host transports, which one should you use?  Here's when
+  you should use each one:
+
+  +o  ethertap - if you want access to the host networking and it is
+     running 2.2
+
+  +o  TUN/TAP - if you want access to the host networking and it is
+     running 2.4.  Also, the TUN/TAP transport is able to use a
+     preconfigured device, allowing it to avoid using the setuid uml_net
+     helper, which is a security advantage.
+
+  +o  Multicast - if you want a purely virtual network and you don't want
+     to set up anything but the UML
+
+  +o  a switch daemon - if you want a purely virtual network and you
+     don't mind running the daemon in order to get somewhat better
+     performance
+
+  +o  slip - there is no particular reason to run the slip backend unless
+     ethertap and TUN/TAP are just not available for some reason
+
+  +o  slirp - if you don't have root access on the host to setup
+     networking, or if you don't want to allocate an IP to your UML
+
+  +o  pcap - not much use for actual network connectivity, but great for
+     monitoring traffic on the host
+
+     Ethertap is available on 2.4 and works fine.  TUN/TAP is preferred
+     to it because it has better performance and ethertap is officially
+     considered obsolete in 2.4.  Also, the root helper only needs to
+     run occasionally for TUN/TAP, rather than handling every packet, as
+     it does with ethertap.  This is a slight security advantage since
+     it provides fewer opportunities for a nasty UML user to somehow
+     exploit the helper's root privileges.
+
+
+  66..11..  GGeenneerraall sseettuupp
+
+  First, you must have the virtual network enabled in your UML.  If are
+  running a prebuilt kernel from this site, everything is already
+  enabled.  If you build the kernel yourself, under the "Network device
+  support" menu, enable "Network device support", and then the three
+  transports.
+
+
+  The next step is to provide a network device to the virtual machine.
+  This is done by describing it on the kernel command line.
+
+  The general format is
+
+
+       eth <n> = <transport> , <transport args>
+
+
+
+
+  For example, a virtual ethernet device may be attached to a host
+  ethertap device as follows:
+
+
+       eth0=ethertap,tap0,fe:fd:0:0:0:1,192.168.0.254
+
+
+
+
+  This sets up eth0 inside the virtual machine to attach itself to the
+  host /dev/tap0, assigns it an ethernet address, and assigns the host
+  tap0 interface an IP address.
+
+
+
+  Note that the IP address you assign to the host end of the tap device
+  must be different than the IP you assign to the eth device inside UML.
+  If you are short on IPs and don't want to consume two per UML, then
+  you can reuse the host's eth IP address for the host ends of the tap
+  devices.  Internally, the UMLs must still get unique IPs for their eth
+  devices.  You can also give the UMLs non-routable IPs (192.168.x.x or
+  10.x.x.x) and have the host masquerade them.  This will let outgoing
+  connections work, but incoming connections won't without more work,
+  such as port forwarding from the host.
+  Also note that when you configure the host side of an interface, it is
+  only acting as a gateway.  It will respond to pings sent to it
+  locally, but is not useful to do that since it's a host interface.
+  You are not talking to the UML when you ping that interface and get a
+  response.
+
+
+  You can also add devices to a UML and remove them at runtime.  See the
+  ``The Management Console''  page for details.
+
+
+  The sections below describe this in more detail.
+
+
+  Once you've decided how you're going to set up the devices, you boot
+  UML, log in, configure the UML side of the devices, and set up routes
+  to the outside world.  At that point, you will be able to talk to any
+  other machines, physical or virtual, on the net.
+
+
+  If ifconfig inside UML fails and the network refuses to come up, run
+  tell you what went wrong.
+
+
+
+  66..22..  UUsseerrssppaaccee ddaaeemmoonnss
+
+  You will likely need the setuid helper, or the switch daemon, or both.
+  They are both installed with the RPM and deb, so if you've installed
+  either, you can skip the rest of this section.
+
+
+  If not, then you need to check them out of CVS, build them, and
+  install them.  The helper is uml_net, in CVS /tools/uml_net, and the
+  daemon is uml_switch, in CVS /tools/uml_router.  They are both built
+  with a plain 'make'.  Both need to be installed in a directory that's
+  in your path - /usr/bin is recommend.  On top of that, uml_net needs
+  to be setuid root.
+
+
+
+  66..33..  SSppeecciiffyyiinngg eetthheerrnneett aaddddrreesssseess
+
+  Below, you will see that the TUN/TAP, ethertap, and daemon interfaces
+  allow you to specify hardware addresses for the virtual ethernet
+  devices.  This is generally not necessary.  If you don't have a
+  specific reason to do it, you probably shouldn't.  If one is not
+  specified on the command line, the driver will assign one based on the
+  device IP address.  It will provide the address fe:fd:nn:nn:nn:nn
+  where nn.nn.nn.nn is the device IP address.  This is nearly always
+  sufficient to guarantee a unique hardware address for the device.  A
+  couple of exceptions are:
+
+  +o  Another set of virtual ethernet devices are on the same network and
+     they are assigned hardware addresses using a different scheme which
+     may conflict with the UML IP address-based scheme
+
+  +o  You aren't going to use the device for IP networking, so you don't
+     assign the device an IP address
+
+     If you let the driver provide the hardware address, you should make
+     sure that the device IP address is known before the interface is
+     brought up.  So, inside UML, this will guarantee that:
+
+
+
+  UML#
+  ifconfig eth0 192.168.0.250 up
+
+
+
+
+  If you decide to assign the hardware address yourself, make sure that
+  the first byte of the address is even.  Addresses with an odd first
+  byte are broadcast addresses, which you don't want assigned to a
+  device.
+
+
+
+  66..44..  UUMMLL iinntteerrffaaccee sseettuupp
+
+  Once the network devices have been described on the command line, you
+  should boot UML and log in.
+
+
+  The first thing to do is bring the interface up:
+
+
+       UML# ifconfig ethn ip-address up
+
+
+
+
+  You should be able to ping the host at this point.
+
+
+  To reach the rest of the world, you should set a default route to the
+  host:
+
+
+       UML# route add default gw host ip
+
+
+
+
+  Again, with host ip of 192.168.0.4:
+
+
+       UML# route add default gw 192.168.0.4
+
+
+
+
+  This page used to recommend setting a network route to your local net.
+  This is wrong, because it will cause UML to try to figure out hardware
+  addresses of the local machines by arping on the interface to the
+  host.  Since that interface is basically a single strand of ethernet
+  with two nodes on it (UML and the host) and arp requests don't cross
+  networks, they will fail to elicit any responses.  So, what you want
+  is for UML to just blindly throw all packets at the host and let it
+  figure out what to do with them, which is what leaving out the network
+  route and adding the default route does.
+
+
+  Note: If you can't communicate with other hosts on your physical
+  ethernet, it's probably because of a network route that's
+  automatically set up.  If you run 'route -n' and see a route that
+  looks like this:
+
+
+
+
+  Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
+  192.168.0.0     0.0.0.0         255.255.255.0   U     0      0      0   eth0
+
+
+
+
+  with a mask that's not 255.255.255.255, then replace it with a route
+  to your host:
+
+
+       UML#
+       route del -net 192.168.0.0 dev eth0 netmask 255.255.255.0
+
+
+
+
+
+
+       UML#
+       route add -host 192.168.0.4 dev eth0
+
+
+
+
+  This, plus the default route to the host, will allow UML to exchange
+  packets with any machine on your ethernet.
+
+
+
+  66..55..  MMuullttiiccaasstt
+
+  The simplest way to set up a virtual network between multiple UMLs is
+  to use the mcast transport.  This was written by Harald Welte and is
+  present in UML version 2.4.5-5um and later.  Your system must have
+  multicast enabled in the kernel and there must be a multicast-capable
+  network device on the host.  Normally, this is eth0, but if there is
+  no ethernet card on the host, then you will likely get strange error
+  messages when you bring the device up inside UML.
+
+
+  To use it, run two UMLs with
+
+
+        eth0=mcast
+
+
+
+
+  on their command lines.  Log in, configure the ethernet device in each
+  machine with different IP addresses:
+
+
+       UML1# ifconfig eth0 192.168.0.254
+
+
+
+
+
+
+       UML2# ifconfig eth0 192.168.0.253
+
+
+
+
+  and they should be able to talk to each other.
+
+  The full set of command line options for this transport are
+
+
+
+       ethn=mcast,ethernet address,multicast
+       address,multicast port,ttl
+
+
+
+
+  Harald's original README is here <http://user-mode-linux.source-
+  forge.net/>  and explains these in detail, as well as
+  some other issues.
+
+  There is also a related point-to-point only "ucast" transport.
+  This is useful when your network does not support multicast, and
+  all network connections are simple point to point links.
+
+  The full set of command line options for this transport are
+
+
+       ethn=ucast,ethernet address,remote address,listen port,remote port
+
+
+
+
+  66..66..  TTUUNN//TTAAPP wwiitthh tthhee uummll__nneett hheellppeerr
+
+  TUN/TAP is the preferred mechanism on 2.4 to exchange packets with the
+  host.  The TUN/TAP backend has been in UML since 2.4.9-3um.
+
+
+  The easiest way to get up and running is to let the setuid uml_net
+  helper do the host setup for you.  This involves insmod-ing the tun.o
+  module if necessary, configuring the device, and setting up IP
+  forwarding, routing, and proxy arp.  If you are new to UML networking,
+  do this first.  If you're concerned about the security implications of
+  the setuid helper, use it to get up and running, then read the next
+  section to see how to have UML use a preconfigured tap device, which
+  avoids the use of uml_net.
+
+
+  If you specify an IP address for the host side of the device, the
+  uml_net helper will do all necessary setup on the host - the only
+  requirement is that TUN/TAP be available, either built in to the host
+  kernel or as the tun.o module.
+
+  The format of the command line switch to attach a device to a TUN/TAP
+  device is
+
+
+       eth <n> =tuntap,,, <IP address>
+
+
+
+
+  For example, this argument will attach the UML's eth0 to the next
+  available tap device and assign an ethernet address to it based on its
+  IP address
+
+
+       eth0=tuntap,,,192.168.0.254
+
+
+
+
+
+
+  Note that the IP address that must be used for the eth device inside
+  UML is fixed by the routing and proxy arp that is set up on the
+  TUN/TAP device on the host.  You can use a different one, but it won't
+  work because reply packets won't reach the UML.  This is a feature.
+  It prevents a nasty UML user from doing things like setting the UML IP
+  to the same as the network's nameserver or mail server.
+
+
+  There are a couple potential problems with running the TUN/TAP
+  transport on a 2.4 host kernel
+
+  +o  TUN/TAP seems not to work on 2.4.3 and earlier.  Upgrade the host
+     kernel or use the ethertap transport.
+
+  +o  With an upgraded kernel, TUN/TAP may fail with
+
+
+       File descriptor in bad state
+
+
+
+
+  This is due to a header mismatch between the upgraded kernel and the
+  kernel that was originally installed on the machine.  The fix is to
+  make sure that /usr/src/linux points to the headers for the running
+  kernel.
+
+  These were pointed out by Tim Robinson <timro at trkr dot net> in
+  <http://www.geocrawler.com/> name="this uml-
+  user post"> .
+
+
+
+  66..77..  TTUUNN//TTAAPP wwiitthh aa pprreeccoonnffiigguurreedd ttaapp ddeevviiccee
+
+  If you prefer not to have UML use uml_net (which is somewhat
+  insecure), with UML 2.4.17-11, you can set up a TUN/TAP device
+  beforehand.  The setup needs to be done as root, but once that's done,
+  there is no need for root assistance.  Setting up the device is done
+  as follows:
+
+  +o  Create the device with tunctl (available from the UML utilities
+     tarball)
+
+
+
+
+       host#  tunctl -u uid
+
+
+
+
+  where uid is the user id or username that UML will be run as.  This
+  will tell you what device was created.
+
+  +o  Configure the device IP (change IP addresses and device name to
+     suit)
+
+
+
+
+       host#  ifconfig tap0 192.168.0.254 up
+
+
+
+
+
+  +o  Set up routing and arping if desired - this is my recipe, there are
+     other ways of doing the same thing
+
+
+       host#
+       bash -c 'echo 1 > /proc/sys/net/ipv4/ip_forward'
+
+       host#
+       route add -host 192.168.0.253 dev tap0
+
+
+
+
+
+
+       host#
+       bash -c 'echo 1 > /proc/sys/net/ipv4/conf/tap0/proxy_arp'
+
+
+
+
+
+
+       host#
+       arp -Ds 192.168.0.253 eth0 pub
+
+
+
+
+  Note that this must be done every time the host boots - this configu-
+  ration is not stored across host reboots.  So, it's probably a good
+  idea to stick it in an rc file.  An even better idea would be a little
+  utility which reads the information from a config file and sets up
+  devices at boot time.
+
+  +o  Rather than using up two IPs and ARPing for one of them, you can
+     also provide direct access to your LAN by the UML by using a
+     bridge.
+
+
+       host#
+       brctl addbr br0
+
+
+
+
+
+
+       host#
+       ifconfig eth0 0.0.0.0 promisc up
+
+
+
+
+
+
+       host#
+       ifconfig tap0 0.0.0.0 promisc up
+
+
+
+
+
+
+       host#
+       ifconfig br0 192.168.0.1 netmask 255.255.255.0 up
+
+
+
+
+
+
+
+  host#
+  brctl stp br0 off
+
+
+
+
+
+
+       host#
+       brctl setfd br0 1
+
+
+
+
+
+
+       host#
+       brctl sethello br0 1
+
+
+
+
+
+
+       host#
+       brctl addif br0 eth0
+
+
+
+
+
+
+       host#
+       brctl addif br0 tap0
+
+
+
+
+  Note that 'br0' should be setup using ifconfig with the existing IP
+  address of eth0, as eth0 no longer has its own IP.
+
+  +o
+
+
+     Also, the /dev/net/tun device must be writable by the user running
+     UML in order for the UML to use the device that's been configured
+     for it.  The simplest thing to do is
+
+
+       host#  chmod 666 /dev/net/tun
+
+
+
+
+  Making it world-writable looks bad, but it seems not to be
+  exploitable as a security hole.  However, it does allow anyone to cre-
+  ate useless tap devices (useless because they can't configure them),
+  which is a DOS attack.  A somewhat more secure alternative would to be
+  to create a group containing all the users who have preconfigured tap
+  devices and chgrp /dev/net/tun to that group with mode 664 or 660.
+
+
+  +o  Once the device is set up, run UML with 'eth0=tuntap,device name'
+     (i.e. 'eth0=tuntap,tap0') on the command line (or do it with the
+     mconsole config command).
+
+  +o  Bring the eth device up in UML and you're in business.
+
+     If you don't want that tap device any more, you can make it non-
+     persistent with
+
+
+       host#  tunctl -d tap device
+
+
+
+
+  Finally, tunctl has a -b (for brief mode) switch which causes it to
+  output only the name of the tap device it created.  This makes it
+  suitable for capture by a script:
+
+
+       host#  TAP=`tunctl -u 1000 -b`
+
+
+
+
+
+
+  66..88..  EEtthheerrttaapp
+
+  Ethertap is the general mechanism on 2.2 for userspace processes to
+  exchange packets with the kernel.
+
+
+
+  To use this transport, you need to describe the virtual network device
+  on the UML command line.  The general format for this is
+
+
+       eth <n> =ethertap, <device> , <ethernet address> , <tap IP address>
+
+
+
+
+  So, the previous example
+
+
+       eth0=ethertap,tap0,fe:fd:0:0:0:1,192.168.0.254
+
+
+
+
+  attaches the UML eth0 device to the host /dev/tap0, assigns it the
+  ethernet address fe:fd:0:0:0:1, and assigns the IP address
+  192.168.0.254 to the tap device.
+
+
+
+  The tap device is mandatory, but the others are optional.  If the
+  ethernet address is omitted, one will be assigned to it.
+
+
+  The presence of the tap IP address will cause the helper to run and do
+  whatever host setup is needed to allow the virtual machine to
+  communicate with the outside world.  If you're not sure you know what
+  you're doing, this is the way to go.
+
+
+  If it is absent, then you must configure the tap device and whatever
+  arping and routing you will need on the host.  However, even in this
+  case, the uml_net helper still needs to be in your path and it must be
+  setuid root if you're not running UML as root.  This is because the
+  tap device doesn't support SIGIO, which UML needs in order to use
+  something as a source of input.  So, the helper is used as a
+  convenient asynchronous IO thread.
+
+  If you're using the uml_net helper, you can ignore the following host
+  setup - uml_net will do it for you.  You just need to make sure you
+  have ethertap available, either built in to the host kernel or
+  available as a module.
+
+
+  If you want to set things up yourself, you need to make sure that the
+  appropriate /dev entry exists.  If it doesn't, become root and create
+  it as follows:
+
+
+       mknod /dev/tap <minor>  c 36  <minor>  + 16
+
+
+
+
+  For example, this is how to create /dev/tap0:
+
+
+       mknod /dev/tap0 c 36 0 + 16
+
+
+
+
+  You also need to make sure that the host kernel has ethertap support.
+  If ethertap is enabled as a module, you apparently need to insmod
+  ethertap once for each ethertap device you want to enable.  So,
+
+
+       host#
+       insmod ethertap
+
+
+
+
+  will give you the tap0 interface.  To get the tap1 interface, you need
+  to run
+
+
+       host#
+       insmod ethertap unit=1 -o ethertap1
+
+
+
+
+
+
+
+  66..99..  TThhee sswwiittcchh ddaaeemmoonn
+
+  NNoottee: This is the daemon formerly known as uml_router, but which was
+  renamed so the network weenies of the world would stop growling at me.
+
+
+  The switch daemon, uml_switch, provides a mechanism for creating a
+  totally virtual network.  By default, it provides no connection to the
+  host network (but see -tap, below).
+
+
+  The first thing you need to do is run the daemon.  Running it with no
+  arguments will make it listen on a default pair of unix domain
+  sockets.
+
+
+  If you want it to listen on a different pair of sockets, use
+
+
+        -unix control socket data socket
+
+
+
+
+
+  If you want it to act as a hub rather than a switch, use
+
+
+        -hub
+
+
+
+
+
+  If you want the switch to be connected to host networking (allowing
+  the umls to get access to the outside world through the host), use
+
+
+        -tap tap0
+
+
+
+
+
+  Note that the tap device must be preconfigured (see "TUN/TAP with a
+  preconfigured tap device", above).  If you're using a different tap
+  device than tap0, specify that instead of tap0.
+
+
+  uml_switch can be backgrounded as follows
+
+
+       host%
+       uml_switch [ options ] < /dev/null > /dev/null
+
+
+
+
+  The reason it doesn't background by default is that it listens to
+  stdin for EOF.  When it sees that, it exits.
+
+
+  The general format of the kernel command line switch is
+
+
+
+       ethn=daemon,ethernet address,socket
+       type,control socket,data socket
+
+
+
+
+  You can leave off everything except the 'daemon'.  You only need to
+  specify the ethernet address if the one that will be assigned to it
+  isn't acceptable for some reason.  The rest of the arguments describe
+  how to communicate with the daemon.  You should only specify them if
+  you told the daemon to use different sockets than the default.  So, if
+  you ran the daemon with no arguments, running the UML on the same
+  machine with
+       eth0=daemon
+
+
+
+
+  will cause the eth0 driver to attach itself to the daemon correctly.
+
+
+
+  66..1100..  SSlliipp
+
+  Slip is another, less general, mechanism for a process to communicate
+  with the host networking.  In contrast to the ethertap interface,
+  which exchanges ethernet frames with the host and can be used to
+  transport any higher-level protocol, it can only be used to transport
+  IP.
+
+
+  The general format of the command line switch is
+
+
+
+       ethn=slip,slip IP
+
+
+
+
+  The slip IP argument is the IP address that will be assigned to the
+  host end of the slip device.  If it is specified, the helper will run
+  and will set up the host so that the virtual machine can reach it and
+  the rest of the network.
+
+
+  There are some oddities with this interface that you should be aware
+  of.  You should only specify one slip device on a given virtual
+  machine, and its name inside UML will be 'umn', not 'eth0' or whatever
+  you specified on the command line.  These problems will be fixed at
+  some point.
+
+
+
+  66..1111..  SSlliirrpp
+
+  slirp uses an external program, usually /usr/bin/slirp, to provide IP
+  only networking connectivity through the host. This is similar to IP
+  masquerading with a firewall, although the translation is performed in
+  user-space, rather than by the kernel.  As slirp does not set up any
+  interfaces on the host, or changes routing, slirp does not require
+  root access or setuid binaries on the host.
+
+
+  The general format of the command line switch for slirp is:
+
+
+
+       ethn=slirp,ethernet address,slirp path
+
+
+
+
+  The ethernet address is optional, as UML will set up the interface
+  with an ethernet address based upon the initial IP address of the
+  interface.  The slirp path is generally /usr/bin/slirp, although it
+  will depend on distribution.
+
+
+  The slirp program can have a number of options passed to the command
+  line and we can't add them to the UML command line, as they will be
+  parsed incorrectly.  Instead, a wrapper shell script can be written or
+  the options inserted into the  /.slirprc file.  More information on
+  all of the slirp options can be found in its man pages.
+
+
+  The eth0 interface on UML should be set up with the IP 10.2.0.15,
+  although you can use anything as long as it is not used by a network
+  you will be connecting to. The default route on UML should be set to
+  use
+
+
+       UML#
+       route add default dev eth0
+
+
+
+
+  slirp provides a number of useful IP addresses which can be used by
+  UML, such as 10.0.2.3 which is an alias for the DNS server specified
+  in /etc/resolv.conf on the host or the IP given in the 'dns' option
+  for slirp.
+
+
+  Even with a baudrate setting higher than 115200, the slirp connection
+  is limited to 115200. If you need it to go faster, the slirp binary
+  needs to be compiled with FULL_BOLT defined in config.h.
+
+
+
+  66..1122..  ppccaapp
+
+  The pcap transport is attached to a UML ethernet device on the command
+  line or with uml_mconsole with the following syntax:
+
+
+
+       ethn=pcap,host interface,filter
+       expression,option1,option2
+
+
+
+
+  The expression and options are optional.
+
+
+  The interface is whatever network device on the host you want to
+  sniff.  The expression is a pcap filter expression, which is also what
+  tcpdump uses, so if you know how to specify tcpdump filters, you will
+  use the same expressions here.  The options are up to two of
+  'promisc', control whether pcap puts the host interface into
+  promiscuous mode. 'optimize' and 'nooptimize' control whether the pcap
+  expression optimizer is used.
+
+
+  Example:
+
+
+
+       eth0=pcap,eth0,tcp
+
+       eth1=pcap,eth0,!tcp
+
+
+
+  will cause the UML eth0 to emit all tcp packets on the host eth0 and
+  the UML eth1 to emit all non-tcp packets on the host eth0.
+
+
+
+  66..1133..  SSeettttiinngg uupp tthhee hhoosstt yyoouurrsseellff
+
+  If you don't specify an address for the host side of the ethertap or
+  slip device, UML won't do any setup on the host.  So this is what is
+  needed to get things working (the examples use a host-side IP of
+  192.168.0.251 and a UML-side IP of 192.168.0.250 - adjust to suit your
+  own network):
+
+  +o  The device needs to be configured with its IP address.  Tap devices
+     are also configured with an mtu of 1484.  Slip devices are
+     configured with a point-to-point address pointing at the UML ip
+     address.
+
+
+       host#  ifconfig tap0 arp mtu 1484 192.168.0.251 up
+
+
+
+
+
+
+       host#
+       ifconfig sl0 192.168.0.251 pointopoint 192.168.0.250 up
+
+
+
+
+
+  +o  If a tap device is being set up, a route is set to the UML IP.
+
+
+       UML# route add -host 192.168.0.250 gw 192.168.0.251
+
+
+
+
+
+  +o  To allow other hosts on your network to see the virtual machine,
+     proxy arp is set up for it.
+
+
+       host#  arp -Ds 192.168.0.250 eth0 pub
+
+
+
+
+
+  +o  Finally, the host is set up to route packets.
+
+
+       host#  echo 1 > /proc/sys/net/ipv4/ip_forward
+
+
+
+
+
+
+
+
+
+
+  77..  SShhaarriinngg FFiilleessyysstteemmss bbeettwweeeenn VViirrttuuaall MMaacchhiinneess
+
+
+
+
+  77..11..  AA wwaarrnniinngg
+
+  Don't attempt to share filesystems simply by booting two UMLs from the
+  same file.  That's the same thing as booting two physical machines
+  from a shared disk.  It will result in filesystem corruption.
+
+
+
+  77..22..  UUssiinngg llaayyeerreedd bblloocckk ddeevviicceess
+
+  The way to share a filesystem between two virtual machines is to use
+  the copy-on-write (COW) layering capability of the ubd block driver.
+  As of 2.4.6-2um, the driver supports layering a read-write private
+  device over a read-only shared device.  A machine's writes are stored
+  in the private device, while reads come from either device - the
+  private one if the requested block is valid in it, the shared one if
+  not.  Using this scheme, the majority of data which is unchanged is
+  shared between an arbitrary number of virtual machines, each of which
+  has a much smaller file containing the changes that it has made.  With
+  a large number of UMLs booting from a large root filesystem, this
+  leads to a huge disk space saving.  It will also help performance,
+  since the host will be able to cache the shared data using a much
+  smaller amount of memory, so UML disk requests will be served from the
+  host's memory rather than its disks.
+
+
+
+
+  To add a copy-on-write layer to an existing block device file, simply
+  add the name of the COW file to the appropriate ubd switch:
+
+
+        ubd0=root_fs_cow,root_fs_debian_22
+
+
+
+
+  where 'root_fs_cow' is the private COW file and 'root_fs_debian_22' is
+  the existing shared filesystem.  The COW file need not exist.  If it
+  doesn't, the driver will create and initialize it.  Once the COW file
+  has been initialized, it can be used on its own on the command line:
+
+
+        ubd0=root_fs_cow
+
+
+
+
+  The name of the backing file is stored in the COW file header, so it
+  would be redundant to continue specifying it on the command line.
+
+
+
+  77..33..  NNoottee!!
+
+  When checking the size of the COW file in order to see the gobs of
+  space that you're saving, make sure you use 'ls -ls' to see the actual
+  disk consumption rather than the length of the file.  The COW file is
+  sparse, so the length will be very different from the disk usage.
+  Here is a 'ls -l' of a COW file and backing file from one boot and
+  shutdown:
+       host% ls -l cow.debian debian2.2
+       -rw-r--r--    1 jdike    jdike    492504064 Aug  6 21:16 cow.debian
+       -rwxrw-rw-    1 jdike    jdike    537919488 Aug  6 20:42 debian2.2
+
+
+
+
+  Doesn't look like much saved space, does it?  Well, here's 'ls -ls':
+
+
+       host% ls -ls cow.debian debian2.2
+          880 -rw-r--r--    1 jdike    jdike    492504064 Aug  6 21:16 cow.debian
+       525832 -rwxrw-rw-    1 jdike    jdike    537919488 Aug  6 20:42 debian2.2
+
+
+
+
+  Now, you can see that the COW file has less than a meg of disk, rather
+  than 492 meg.
+
+
+
+  77..44..  AAnnootthheerr wwaarrnniinngg
+
+  Once a filesystem is being used as a readonly backing file for a COW
+  file, do not boot directly from it or modify it in any way.  Doing so
+  will invalidate any COW files that are using it.  The mtime and size
+  of the backing file are stored in the COW file header at its creation,
+  and they must continue to match.  If they don't, the driver will
+  refuse to use the COW file.
+
+
+
+
+  If you attempt to evade this restriction by changing either the
+  backing file or the COW header by hand, you will get a corrupted
+  filesystem.
+
+
+
+
+  Among other things, this means that upgrading the distribution in a
+  backing file and expecting that all of the COW files using it will see
+  the upgrade will not work.
+
+
+
+
+  77..55..  uummll__mmoooo :: MMeerrggiinngg aa CCOOWW ffiillee wwiitthh iittss bbaacckkiinngg ffiillee
+
+  Depending on how you use UML and COW devices, it may be advisable to
+  merge the changes in the COW file into the backing file every once in
+  a while.
+
+
+
+
+  The utility that does this is uml_moo.  Its usage is
+
+
+       host% uml_moo COW file new backing file
+
+
+
+
+  There's no need to specify the backing file since that information is
+  already in the COW file header.  If you're paranoid, boot the new
+  merged file, and if you're happy with it, move it over the old backing
+  file.
+
+
+
+
+  uml_moo creates a new backing file by default as a safety measure.  It
+  also has a destructive merge option which will merge the COW file
+  directly into its current backing file.  This is really only usable
+  when the backing file only has one COW file associated with it.  If
+  there are multiple COWs associated with a backing file, a -d merge of
+  one of them will invalidate all of the others.  However, it is
+  convenient if you're short of disk space, and it should also be
+  noticeably faster than a non-destructive merge.
+
+
+
+
+  uml_moo is installed with the UML deb and RPM.  If you didn't install
+  UML from one of those packages, you can also get it from the UML
+  utilities <http://user-mode-linux.sourceforge.net/
+  utilities>  tar file in tools/moo.
+
+
+
+
+
+
+
+
+  88..  CCrreeaattiinngg ffiilleessyysstteemmss
+
+
+  You may want to create and mount new UML filesystems, either because
+  your root filesystem isn't large enough or because you want to use a
+  filesystem other than ext2.
+
+
+  This was written on the occasion of reiserfs being included in the
+  2.4.1 kernel pool, and therefore the 2.4.1 UML, so the examples will
+  talk about reiserfs.  This information is generic, and the examples
+  should be easy to translate to the filesystem of your choice.
+
+
+  88..11..  CCrreeaattee tthhee ffiilleessyysstteemm ffiillee
+
+  dd is your friend.  All you need to do is tell dd to create an empty
+  file of the appropriate size.  I usually make it sparse to save time
+  and to avoid allocating disk space until it's actually used.  For
+  example, the following command will create a sparse 100 meg file full
+  of zeroes.
+
+
+       host%
+       dd if=/dev/zero of=new_filesystem seek=100 count=1 bs=1M
+
+
+
+
+
+
+  88..22..  AAssssiiggnn tthhee ffiillee ttoo aa UUMMLL ddeevviiccee
+
+  Add an argument like the following to the UML command line:
+
+  ubd4=new_filesystem
+
+
+
+
+  making sure that you use an unassigned ubd device number.
+
+
+
+  88..33..  CCrreeaattiinngg aanndd mmoouunnttiinngg tthhee ffiilleessyysstteemm
+
+  Make sure that the filesystem is available, either by being built into
+  the kernel, or available as a module, then boot up UML and log in.  If
+  the root filesystem doesn't have the filesystem utilities (mkfs, fsck,
+  etc), then get them into UML by way of the net or hostfs.
+
+
+  Make the new filesystem on the device assigned to the new file:
+
+
+       host#  mkreiserfs /dev/ubd/4
+
+
+       <----------- MKREISERFSv2 ----------->
+
+       ReiserFS version 3.6.25
+       Block size 4096 bytes
+       Block count 25856
+       Used blocks 8212
+               Journal - 8192 blocks (18-8209), journal header is in block 8210
+               Bitmaps: 17
+               Root block 8211
+       Hash function "r5"
+       ATTENTION: ALL DATA WILL BE LOST ON '/dev/ubd/4'! (y/n)y
+       journal size 8192 (from 18)
+       Initializing journal - 0%....20%....40%....60%....80%....100%
+       Syncing..done.
+
+
+
+
+  Now, mount it:
+
+
+       UML#
+       mount /dev/ubd/4 /mnt
+
+
+
+
+  and you're in business.
+
+
+
+
+
+
+
+
+
+  99..  HHoosstt ffiillee aacccceessss
+
+
+  If you want to access files on the host machine from inside UML, you
+  can treat it as a separate machine and either nfs mount directories
+  from the host or copy files into the virtual machine with scp or rcp.
+  However, since UML is running on the host, it can access those
+  files just like any other process and make them available inside the
+  virtual machine without needing to use the network.
+
+
+  This is now possible with the hostfs virtual filesystem.  With it, you
+  can mount a host directory into the UML filesystem and access the
+  files contained in it just as you would on the host.
+
+
+  99..11..  UUssiinngg hhoossttffss
+
+  To begin with, make sure that hostfs is available inside the virtual
+  machine with
+
+
+       UML# cat /proc/filesystems
+
+
+
+  .  hostfs should be listed.  If it's not, either rebuild the kernel
+  with hostfs configured into it or make sure that hostfs is built as a
+  module and available inside the virtual machine, and insmod it.
+
+
+  Now all you need to do is run mount:
+
+
+       UML# mount none /mnt/host -t hostfs
+
+
+
+
+  will mount the host's / on the virtual machine's /mnt/host.
+
+
+  If you don't want to mount the host root directory, then you can
+  specify a subdirectory to mount with the -o switch to mount:
+
+
+       UML# mount none /mnt/home -t hostfs -o /home
+
+
+
+
+  will mount the hosts's /home on the virtual machine's /mnt/home.
+
+
+
+  99..22..  hhoossttffss aass tthhee rroooott ffiilleessyysstteemm
+
+  It's possible to boot from a directory hierarchy on the host using
+  hostfs rather than using the standard filesystem in a file.
+
+  To start, you need that hierarchy.  The easiest way is to loop mount
+  an existing root_fs file:
+
+
+       host#  mount root_fs uml_root_dir -o loop
+
+
+
+
+  You need to change the filesystem type of / in etc/fstab to be
+  'hostfs', so that line looks like this:
+
+  /dev/ubd/0       /        hostfs      defaults          1   1
+
+
+
+
+  Then you need to chown to yourself all the files in that directory
+  that are owned by root.  This worked for me:
+
+
+       host#  find . -uid 0 -exec chown jdike {} \;
+
+
+
+
+  Next, make sure that your UML kernel has hostfs compiled in, not as a
+  module.  Then run UML with the boot device pointing at that directory:
+
+
+        ubd0=/path/to/uml/root/directory
+
+
+
+
+  UML should then boot as it does normally.
+
+
+  99..33..  BBuuiillddiinngg hhoossttffss
+
+  If you need to build hostfs because it's not in your kernel, you have
+  two choices:
+
+
+
+  +o  Compiling hostfs into the kernel:
+
+
+     Reconfigure the kernel and set the 'Host filesystem' option under
+
+
+  +o  Compiling hostfs as a module:
+
+
+     Reconfigure the kernel and set the 'Host filesystem' option under
+     be in arch/um/fs/hostfs/hostfs.o.  Install that in
+     /lib/modules/`uname -r`/fs in the virtual machine, boot it up, and
+
+
+       UML# insmod hostfs
+
+
+
+
+
+
+
+
+
+
+
+
+  1100..  TThhee MMaannaaggeemmeenntt CCoonnssoollee
+
+
+
+  The UML management console is a low-level interface to the kernel,
+  somewhat like the i386 SysRq interface.  Since there is a full-blown
+  operating system under UML, there is much greater flexibility possible
+  than with the SysRq mechanism.
+
+
+  There are a number of things you can do with the mconsole interface:
+
+  +o  get the kernel version
+
+  +o  add and remove devices
+
+  +o  halt or reboot the machine
+
+  +o  Send SysRq commands
+
+  +o  Pause and resume the UML
+
+
+  You need the mconsole client (uml_mconsole) which is present in CVS
+  (/tools/mconsole) in 2.4.5-9um and later, and will be in the RPM in
+  2.4.6.
+
+
+  You also need CONFIG_MCONSOLE (under 'General Setup') enabled in UML.
+  When you boot UML, you'll see a line like:
+
+
+       mconsole initialized on /home/jdike/.uml/umlNJ32yL/mconsole
+
+
+
+
+  If you specify a unique machine id one the UML command line, i.e.
+
+
+        umid=debian
+
+
+
+
+  you'll see this
+
+
+       mconsole initialized on /home/jdike/.uml/debian/mconsole
+
+
+
+
+  That file is the socket that uml_mconsole will use to communicate with
+  UML.  Run it with either the umid or the full path as its argument:
+
+
+       host% uml_mconsole debian
+
+
+
+
+  or
+
+
+       host% uml_mconsole /home/jdike/.uml/debian/mconsole
+
+
+
+
+  You'll get a prompt, at which you can run one of these commands:
+
+  +o  version
+
+  +o  halt
+
+  +o  reboot
+
+  +o  config
+
+  +o  remove
+
+  +o  sysrq
+
+  +o  help
+
+  +o  cad
+
+  +o  stop
+
+  +o  go
+
+
+  1100..11..  vveerrssiioonn
+
+  This takes no arguments.  It prints the UML version.
+
+
+       (mconsole)  version
+       OK Linux usermode 2.4.5-9um #1 Wed Jun 20 22:47:08 EDT 2001 i686
+
+
+
+
+  There are a couple actual uses for this.  It's a simple no-op which
+  can be used to check that a UML is running.  It's also a way of
+  sending an interrupt to the UML.  This is sometimes useful on SMP
+  hosts, where there's a bug which causes signals to UML to be lost,
+  often causing it to appear to hang.  Sending such a UML the mconsole
+  version command is a good way to 'wake it up' before networking has
+  been enabled, as it does not do anything to the function of the UML.
+
+
+
+  1100..22..  hhaalltt aanndd rreebboooott
+
+  These take no arguments.  They shut the machine down immediately, with
+  no syncing of disks and no clean shutdown of userspace.  So, they are
+  pretty close to crashing the machine.
+
+
+       (mconsole)  halt
+       OK
+
+
+
+
+
+
+  1100..33..  ccoonnffiigg
+
+  "config" adds a new device to the virtual machine.  Currently the ubd
+  and network drivers support this.  It takes one argument, which is the
+  device to add, with the same syntax as the kernel command line.
+
+
+
+
+  (mconsole)
+  config ubd3=/home/jdike/incoming/roots/root_fs_debian22
+
+  OK
+  (mconsole)  config eth1=mcast
+  OK
+
+
+
+
+
+
+  1100..44..  rreemmoovvee
+
+  "remove" deletes a device from the system.  Its argument is just the
+  name of the device to be removed. The device must be idle in whatever
+  sense the driver considers necessary.  In the case of the ubd driver,
+  the removed block device must not be mounted, swapped on, or otherwise
+  open, and in the case of the network driver, the device must be down.
+
+
+       (mconsole)  remove ubd3
+       OK
+       (mconsole)  remove eth1
+       OK
+
+
+
+
+
+
+  1100..55..  ssyyssrrqq
+
+  This takes one argument, which is a single letter.  It calls the
+  generic kernel's SysRq driver, which does whatever is called for by
+  that argument.  See the SysRq documentation in Documentation/sysrq.txt
+  in your favorite kernel tree to see what letters are valid and what
+  they do.
+
+
+
+  1100..66..  hheellpp
+
+  "help" returns a string listing the valid commands and what each one
+  does.
+
+
+
+  1100..77..  ccaadd
+
+  This invokes the Ctl-Alt-Del action on init.  What exactly this ends
+  up doing is up to /etc/inittab.  Normally, it reboots the machine.
+  With UML, this is usually not desired, so if a halt would be better,
+  then find the section of inittab that looks like this
+
+
+       # What to do when CTRL-ALT-DEL is pressed.
+       ca:12345:ctrlaltdel:/sbin/shutdown -t1 -a -r now
+
+
+
+
+  and change the command to halt.
+
+
+
+  1100..88..  ssttoopp
+
+  This puts the UML in a loop reading mconsole requests until a 'go'
+  mconsole command is received. This is very useful for making backups
+  of UML filesystems, as the UML can be stopped, then synced via 'sysrq
+  s', so that everything is written to the filesystem. You can then copy
+  the filesystem and then send the UML 'go' via mconsole.
+
+
+  Note that a UML running with more than one CPU will have problems
+  after you send the 'stop' command, as only one CPU will be held in a
+  mconsole loop and all others will continue as normal.  This is a bug,
+  and will be fixed.
+
+
+
+  1100..99..  ggoo
+
+  This resumes a UML after being paused by a 'stop' command. Note that
+  when the UML has resumed, TCP connections may have timed out and if
+  the UML is paused for a long period of time, crond might go a little
+  crazy, running all the jobs it didn't do earlier.
+
+
+
+
+
+
+
+
+  1111..  KKeerrnneell ddeebbuuggggiinngg
+
+
+  NNoottee:: The interface that makes debugging, as described here, possible
+  is present in 2.4.0-test6 kernels and later.
+
+
+  Since the user-mode kernel runs as a normal Linux process, it is
+  possible to debug it with gdb almost like any other process.  It is
+  slightly different because the kernel's threads are already being
+  ptraced for system call interception, so gdb can't ptrace them.
+  However, a mechanism has been added to work around that problem.
+
+
+  In order to debug the kernel, you need build it from source.  See
+  ``Compiling the kernel and modules''  for information on doing that.
+  Make sure that you enable CONFIG_DEBUGSYM and CONFIG_PT_PROXY during
+  the config.  These will compile the kernel with -g, and enable the
+  ptrace proxy so that gdb works with UML, respectively.
+
+
+
+
+  1111..11..  SSttaarrttiinngg tthhee kkeerrnneell uunnddeerr ggddbb
+
+  You can have the kernel running under the control of gdb from the
+  beginning by putting 'debug' on the command line.  You will get an
+  xterm with gdb running inside it.  The kernel will send some commands
+  to gdb which will leave it stopped at the beginning of start_kernel.
+  At this point, you can get things going with 'next', 'step', or
+  'cont'.
+
+
+  There is a transcript of a debugging session  here <debug-
+  session.html> , with breakpoints being set in the scheduler and in an
+  interrupt handler.
+  1111..22..  EExxaammiinniinngg sslleeeeppiinngg pprroocceesssseess
+
+  Not every bug is evident in the currently running process.  Sometimes,
+  processes hang in the kernel when they shouldn't because they've
+  deadlocked on a semaphore or something similar.  In this case, when
+  you ^C gdb and get a backtrace, you will see the idle thread, which
+  isn't very relevant.
+
+
+  What you want is the stack of whatever process is sleeping when it
+  shouldn't be.  You need to figure out which process that is, which is
+  generally fairly easy.  Then you need to get its host process id,
+  which you can do either by looking at ps on the host or at
+  task.thread.extern_pid in gdb.
+
+
+  Now what you do is this:
+
+  +o  detach from the current thread
+
+
+       (UML gdb)  det
+
+
+
+
+
+  +o  attach to the thread you are interested in
+
+
+       (UML gdb)  att <host pid>
+
+
+
+
+
+  +o  look at its stack and anything else of interest
+
+
+       (UML gdb)  bt
+
+
+
+
+  Note that you can't do anything at this point that requires that a
+  process execute, e.g. calling a function
+
+  +o  when you're done looking at that process, reattach to the current
+     thread and continue it
+
+
+       (UML gdb)
+       att 1
+
+
+
+
+
+
+       (UML gdb)
+       c
+
+
+
+
+  Here, specifying any pid which is not the process id of a UML thread
+  will cause gdb to reattach to the current thread.  I commonly use 1,
+  but any other invalid pid would work.
+
+
+
+  1111..33..  RRuunnnniinngg dddddd oonn UUMMLL
+
+  ddd works on UML, but requires a special kludge.  The process goes
+  like this:
+
+  +o  Start ddd
+
+
+       host% ddd linux
+
+
+
+
+
+  +o  With ps, get the pid of the gdb that ddd started.  You can ask the
+     gdb to tell you, but for some reason that confuses things and
+     causes a hang.
+
+  +o  run UML with 'debug=parent gdb-pid=<pid>' added to the command line
+     - it will just sit there after you hit return
+
+  +o  type 'att 1' to the ddd gdb and you will see something like
+
+
+       0xa013dc51 in __kill ()
+
+
+       (gdb)
+
+
+
+
+
+  +o  At this point, type 'c', UML will boot up, and you can use ddd just
+     as you do on any other process.
+
+
+
+  1111..44..  DDeebbuuggggiinngg mmoodduulleess
+
+  gdb has support for debugging code which is dynamically loaded into
+  the process.  This support is what is needed to debug kernel modules
+  under UML.
+
+
+  Using that support is somewhat complicated.  You have to tell gdb what
+  object file you just loaded into UML and where in memory it is.  Then,
+  it can read the symbol table, and figure out where all the symbols are
+  from the load address that you provided.  It gets more interesting
+  when you load the module again (i.e. after an rmmod).  You have to
+  tell gdb to forget about all its symbols, including the main UML ones
+  for some reason, then load then all back in again.
+
+
+  There's an easy way and a hard way to do this.  The easy way is to use
+  the umlgdb expect script written by Chandan Kudige.  It basically
+  automates the process for you.
+
+
+  First, you must tell it where your modules are.  There is a list in
+  the script that looks like this:
+       set MODULE_PATHS {
+       "fat" "/usr/src/uml/linux-2.4.18/fs/fat/fat.o"
+       "isofs" "/usr/src/uml/linux-2.4.18/fs/isofs/isofs.o"
+       "minix" "/usr/src/uml/linux-2.4.18/fs/minix/minix.o"
+       }
+
+
+
+
+  You change that to list the names and paths of the modules that you
+  are going to debug.  Then you run it from the toplevel directory of
+  your UML pool and it basically tells you what to do:
+
+
+
+
+                   ******** GDB pid is 21903 ********
+       Start UML as: ./linux <kernel switches> debug gdb-pid=21903
+
+
+
+       GNU gdb 5.0rh-5 Red Hat Linux 7.1
+       Copyright 2001 Free Software Foundation, Inc.
+       GDB is free software, covered by the GNU General Public License, and you are
+       welcome to change it and/or distribute copies of it under certain conditions.
+       Type "show copying" to see the conditions.
+       There is absolutely no warranty for GDB.  Type "show warranty" for details.
+       This GDB was configured as "i386-redhat-linux"...
+       (gdb) b sys_init_module
+       Breakpoint 1 at 0xa0011923: file module.c, line 349.
+       (gdb) att 1
+
+
+
+
+  After you run UML and it sits there doing nothing, you hit return at
+  the 'att 1' and continue it:
+
+
+       Attaching to program: /home/jdike/linux/2.4/um/./linux, process 1
+       0xa00f4221 in __kill ()
+       (UML gdb)  c
+       Continuing.
+
+
+
+
+  At this point, you debug normally.  When you insmod something, the
+  expect magic will kick in and you'll see something like:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+   *** Module hostfs loaded ***
+  Breakpoint 1, sys_init_module (name_user=0x805abb0 "hostfs",
+      mod_user=0x8070e00) at module.c:349
+  349             char *name, *n_name, *name_tmp = NULL;
+  (UML gdb)  finish
+  Run till exit from #0  sys_init_module (name_user=0x805abb0 "hostfs",
+      mod_user=0x8070e00) at module.c:349
+  0xa00e2e23 in execute_syscall (r=0xa8140284) at syscall_kern.c:411
+  411             else res = EXECUTE_SYSCALL(syscall, regs);
+  Value returned is $1 = 0
+  (UML gdb)
+  p/x (int)module_list + module_list->size_of_struct
+
+  $2 = 0xa9021054
+  (UML gdb)  symbol-file ./linux
+  Load new symbol table from "./linux"? (y or n) y
+  Reading symbols from ./linux...
+  done.
+  (UML gdb)
+  add-symbol-file /home/jdike/linux/2.4/um/arch/um/fs/hostfs/hostfs.o 0xa9021054
+
+  add symbol table from file "/home/jdike/linux/2.4/um/arch/um/fs/hostfs/hostfs.o" at
+          .text_addr = 0xa9021054
+   (y or n) y
+
+  Reading symbols from /home/jdike/linux/2.4/um/arch/um/fs/hostfs/hostfs.o...
+  done.
+  (UML gdb)  p *module_list
+  $1 = {size_of_struct = 84, next = 0xa0178720, name = 0xa9022de0 "hostfs",
+    size = 9016, uc = {usecount = {counter = 0}, pad = 0}, flags = 1,
+    nsyms = 57, ndeps = 0, syms = 0xa9023170, deps = 0x0, refs = 0x0,
+    init = 0xa90221f0 <init_hostfs>, cleanup = 0xa902222c <exit_hostfs>,
+    ex_table_start = 0x0, ex_table_end = 0x0, persist_start = 0x0,
+    persist_end = 0x0, can_unload = 0, runsize = 0, kallsyms_start = 0x0,
+    kallsyms_end = 0x0,
+    archdata_start = 0x1b855 <Address 0x1b855 out of bounds>,
+    archdata_end = 0xe5890000 <Address 0xe5890000 out of bounds>,
+    kernel_data = 0xf689c35d <Address 0xf689c35d out of bounds>}
+  >> Finished loading symbols for hostfs ...
+
+
+
+
+  That's the easy way.  It's highly recommended.  The hard way is
+  described below in case you're interested in what's going on.
+
+
+  Boot the kernel under the debugger and load the module with insmod or
+  modprobe.  With gdb, do:
+
+
+       (UML gdb)  p module_list
+
+
+
+
+  This is a list of modules that have been loaded into the kernel, with
+  the most recently loaded module first.  Normally, the module you want
+  is at module_list.  If it's not, walk down the next links, looking at
+  the name fields until find the module you want to debug.  Take the
+  address of that structure, and add module.size_of_struct (which in
+  2.4.10 kernels is 96 (0x60)) to it.  Gdb can make this hard addition
+  for you :-):
+
+
+
+  (UML gdb)
+  printf "%#x\n", (int)module_list module_list->size_of_struct
+
+
+
+
+  The offset from the module start occasionally changes (before 2.4.0,
+  it was module.size_of_struct + 4), so it's a good idea to check the
+  init and cleanup addresses once in a while, as describe below.  Now
+  do:
+
+
+       (UML gdb)
+       add-symbol-file /path/to/module/on/host that_address
+
+
+
+
+  Tell gdb you really want to do it, and you're in business.
+
+
+  If there's any doubt that you got the offset right, like breakpoints
+  appear not to work, or they're appearing in the wrong place, you can
+  check it by looking at the module structure.  The init and cleanup
+  fields should look like:
+
+
+       init = 0x588066b0 <init_hostfs>, cleanup = 0x588066c0 <exit_hostfs>
+
+
+
+
+  with no offsets on the symbol names.  If the names are right, but they
+  are offset, then the offset tells you how much you need to add to the
+  address you gave to add-symbol-file.
+
+
+  When you want to load in a new version of the module, you need to get
+  gdb to forget about the old one.  The only way I've found to do that
+  is to tell gdb to forget about all symbols that it knows about:
+
+
+       (UML gdb)  symbol-file
+
+
+
+
+  Then reload the symbols from the kernel binary:
+
+
+       (UML gdb)  symbol-file /path/to/kernel
+
+
+
+
+  and repeat the process above.  You'll also need to re-enable break-
+  points.  They were disabled when you dumped all the symbols because
+  gdb couldn't figure out where they should go.
+
+
+
+  1111..55..  AAttttaacchhiinngg ggddbb ttoo tthhee kkeerrnneell
+
+  If you don't have the kernel running under gdb, you can attach gdb to
+  it later by sending the tracing thread a SIGUSR1.  The first line of
+  the console output identifies its pid:
+       tracing thread pid = 20093
+
+
+
+
+  When you send it the signal:
+
+
+       host% kill -USR1 20093
+
+
+
+
+  you will get an xterm with gdb running in it.
+
+
+  If you have the mconsole compiled into UML, then the mconsole client
+  can be used to start gdb:
+
+
+       (mconsole)  (mconsole) config gdb=xterm
+
+
+
+
+  will fire up an xterm with gdb running in it.
+
+
+
+  1111..66..  UUssiinngg aalltteerrnnaattee ddeebbuuggggeerrss
+
+  UML has support for attaching to an already running debugger rather
+  than starting gdb itself.  This is present in CVS as of 17 Apr 2001.
+  I sent it to Alan for inclusion in the ac tree, and it will be in my
+  2.4.4 release.
+
+
+  This is useful when gdb is a subprocess of some UI, such as emacs or
+  ddd.  It can also be used to run debuggers other than gdb on UML.
+  Below is an example of using strace as an alternate debugger.
+
+
+  To do this, you need to get the pid of the debugger and pass it in
+  with the
+
+
+  If you are using gdb under some UI, then tell it to 'att 1', and
+  you'll find yourself attached to UML.
+
+
+  If you are using something other than gdb as your debugger, then
+  you'll need to get it to do the equivalent of 'att 1' if it doesn't do
+  it automatically.
+
+
+  An example of an alternate debugger is strace.  You can strace the
+  actual kernel as follows:
+
+  +o  Run the following in a shell
+
+
+       host%
+       sh -c 'echo pid=$$; echo -n hit return; read x; exec strace -p 1 -o strace.out'
+
+
+
+  +o  Run UML with 'debug' and 'gdb-pid=<pid>' with the pid printed out
+     by the previous command
+
+  +o  Hit return in the shell, and UML will start running, and strace
+     output will start accumulating in the output file.
+
+     Note that this is different from running
+
+
+       host% strace ./linux
+
+
+
+
+  That will strace only the main UML thread, the tracing thread, which
+  doesn't do any of the actual kernel work.  It just oversees the vir-
+  tual machine.  In contrast, using strace as described above will show
+  you the low-level activity of the virtual machine.
+
+
+
+
+
+  1122..  KKeerrnneell ddeebbuuggggiinngg eexxaammpplleess
+
+  1122..11..  TThhee ccaassee ooff tthhee hhuunngg ffsscckk
+
+  When booting up the kernel, fsck failed, and dropped me into a shell
+  to fix things up.  I ran fsck -y, which hung:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+  Setting hostname uml                    [ OK ]
+  Checking root filesystem
+  /dev/fhd0 was not cleanly unmounted, check forced.
+  Error reading block 86894 (Attempt to read block from filesystem resulted in short read) while reading indirect blocks of inode 19780.
+
+  /dev/fhd0: UNEXPECTED INCONSISTENCY; RUN fsck MANUALLY.
+          (i.e., without -a or -p options)
+  [ FAILED ]
+
+  *** An error occurred during the file system check.
+  *** Dropping you to a shell; the system will reboot
+  *** when you leave the shell.
+  Give root password for maintenance
+  (or type Control-D for normal startup):
+
+  [root@uml /root]# fsck -y /dev/fhd0
+  fsck -y /dev/fhd0
+  Parallelizing fsck version 1.14 (9-Jan-1999)
+  e2fsck 1.14, 9-Jan-1999 for EXT2 FS 0.5b, 95/08/09
+  /dev/fhd0 contains a file system with errors, check forced.
+  Pass 1: Checking inodes, blocks, and sizes
+  Error reading block 86894 (Attempt to read block from filesystem resulted in short read) while reading indirect blocks of inode 19780.  Ignore error? yes
+
+  Inode 19780, i_blocks is 1548, should be 540.  Fix? yes
+
+  Pass 2: Checking directory structure
+  Error reading block 49405 (Attempt to read block from filesystem resulted in short read).  Ignore error? yes
+
+  Directory inode 11858, block 0, offset 0: directory corrupted
+  Salvage? yes
+
+  Missing '.' in directory inode 11858.
+  Fix? yes
+
+  Missing '..' in directory inode 11858.
+  Fix? yes
+
+
+
+
+
+  The standard drill in this sort of situation is to fire up gdb on the
+  signal thread, which, in this case, was pid 1935.  In another window,
+  I run gdb and attach pid 1935.
+
+
+
+
+       ~/linux/2.3.26/um 1016: gdb linux
+       GNU gdb 4.17.0.11 with Linux support
+       Copyright 1998 Free Software Foundation, Inc.
+       GDB is free software, covered by the GNU General Public License, and you are
+       welcome to change it and/or distribute copies of it under certain conditions.
+       Type "show copying" to see the conditions.
+       There is absolutely no warranty for GDB.  Type "show warranty" for details.
+       This GDB was configured as "i386-redhat-linux"...
+
+       (gdb) att 1935
+       Attaching to program `/home/dike/linux/2.3.26/um/linux', Pid 1935
+       0x100756d9 in __wait4 ()
+
+
+
+
+
+
+  Let's see what's currently running:
+
+
+
+       (gdb) p current_task.pid
+       $1 = 0
+
+
+
+
+
+  It's the idle thread, which means that fsck went to sleep for some
+  reason and never woke up.
+
+
+  Let's guess that the last process in the process list is fsck:
+
+
+
+       (gdb) p current_task.prev_task.comm
+       $13 = "fsck.ext2\000\000\000\000\000\000"
+
+
+
+
+
+  It is, so let's see what it thinks it's up to:
+
+
+
+       (gdb) p current_task.prev_task.thread
+       $14 = {extern_pid = 1980, tracing = 0, want_tracing = 0, forking = 0,
+         kernel_stack_page = 0, signal_stack = 1342627840, syscall = {id = 4, args = {
+             3, 134973440, 1024, 0, 1024}, have_result = 0, result = 50590720},
+         request = {op = 2, u = {exec = {ip = 1350467584, sp = 2952789424}, fork = {
+               regs = {1350467584, 2952789424, 0 <repeats 15 times>}, sigstack = 0,
+               pid = 0}, switch_to = 0x507e8000, thread = {proc = 0x507e8000,
+               arg = 0xaffffdb0, flags = 0, new_pid = 0}, input_request = {
+               op = 1350467584, fd = -1342177872, proc = 0, pid = 0}}}}
+
+
+
+
+
+  The interesting things here are the fact that its .thread.syscall.id
+  is __NR_write (see the big switch in arch/um/kernel/syscall_kern.c or
+  the defines in include/asm-um/arch/unistd.h), and that it never
+  returned.  Also, its .request.op is OP_SWITCH (see
+  arch/um/include/user_util.h).  These mean that it went into a write,
+  and, for some reason, called schedule().
+
+
+  The fact that it never returned from write means that its stack should
+  be fairly interesting.  Its pid is 1980 (.thread.extern_pid).  That
+  process is being ptraced by the signal thread, so it must be detached
+  before gdb can attach it:
+
+
+
+
+
+
+
+
+
+
+  (gdb) call detach(1980)
+
+  Program received signal SIGSEGV, Segmentation fault.
+  <function called from gdb>
+  The program being debugged stopped while in a function called from GDB.
+  When the function (detach) is done executing, GDB will silently
+  stop (instead of continuing to evaluate the expression containing
+  the function call).
+  (gdb) call detach(1980)
+  $15 = 0
+
+
+
+
+
+  The first detach segfaults for some reason, and the second one
+  succeeds.
+
+
+  Now I detach from the signal thread, attach to the fsck thread, and
+  look at its stack:
+
+
+       (gdb) det
+       Detaching from program: /home/dike/linux/2.3.26/um/linux Pid 1935
+       (gdb) att 1980
+       Attaching to program `/home/dike/linux/2.3.26/um/linux', Pid 1980
+       0x10070451 in __kill ()
+       (gdb) bt
+       #0  0x10070451 in __kill ()
+       #1  0x10068ccd in usr1_pid (pid=1980) at process.c:30
+       #2  0x1006a03f in _switch_to (prev=0x50072000, next=0x507e8000)
+           at process_kern.c:156
+       #3  0x1006a052 in switch_to (prev=0x50072000, next=0x507e8000, last=0x50072000)
+           at process_kern.c:161
+       #4  0x10001d12 in schedule () at sched.c:777
+       #5  0x1006a744 in __down (sem=0x507d241c) at semaphore.c:71
+       #6  0x1006aa10 in __down_failed () at semaphore.c:157
+       #7  0x1006c5d8 in segv_handler (sc=0x5006e940) at trap_user.c:174
+       #8  0x1006c5ec in kern_segv_handler (sig=11) at trap_user.c:182
+       #9  <signal handler called>
+       #10 0x10155404 in errno ()
+       #11 0x1006c0aa in segv (address=1342179328, is_write=2) at trap_kern.c:50
+       #12 0x1006c5d8 in segv_handler (sc=0x5006eaf8) at trap_user.c:174
+       #13 0x1006c5ec in kern_segv_handler (sig=11) at trap_user.c:182
+       #14 <signal handler called>
+       #15 0xc0fd in ?? ()
+       #16 0x10016647 in sys_write (fd=3,
+           buf=0x80b8800 <Address 0x80b8800 out of bounds>, count=1024)
+           at read_write.c:159
+       #17 0x1006d5b3 in execute_syscall (syscall=4, args=0x5006ef08)
+           at syscall_kern.c:254
+       #18 0x1006af87 in really_do_syscall (sig=12) at syscall_user.c:35
+       #19 <signal handler called>
+       #20 0x400dc8b0 in ?? ()
+
+
+
+
+
+  The interesting things here are :
+
+  +o  There are two segfaults on this stack (frames 9 and 14)
+
+  +o  The first faulting address (frame 11) is 0x50000800
+
+  (gdb) p (void *)1342179328
+  $16 = (void *) 0x50000800
+
+
+
+
+
+  The initial faulting address is interesting because it is on the idle
+  thread's stack.  I had been seeing the idle thread segfault for no
+  apparent reason, and the cause looked like stack corruption.  In hopes
+  of catching the culprit in the act, I had turned off all protections
+  to that stack while the idle thread wasn't running.  This apparently
+  tripped that trap.
+
+
+  However, the more immediate problem is that second segfault and I'm
+  going to concentrate on that.  First, I want to see where the fault
+  happened, so I have to go look at the sigcontent struct in frame 8:
+
+
+
+       (gdb) up
+       #1  0x10068ccd in usr1_pid (pid=1980) at process.c:30
+       30        kill(pid, SIGUSR1);
+       (gdb)
+       #2  0x1006a03f in _switch_to (prev=0x50072000, next=0x507e8000)
+           at process_kern.c:156
+       156       usr1_pid(getpid());
+       (gdb)
+       #3  0x1006a052 in switch_to (prev=0x50072000, next=0x507e8000, last=0x50072000)
+           at process_kern.c:161
+       161       _switch_to(prev, next);
+       (gdb)
+       #4  0x10001d12 in schedule () at sched.c:777
+       777             switch_to(prev, next, prev);
+       (gdb)
+       #5  0x1006a744 in __down (sem=0x507d241c) at semaphore.c:71
+       71                      schedule();
+       (gdb)
+       #6  0x1006aa10 in __down_failed () at semaphore.c:157
+       157     }
+       (gdb)
+       #7  0x1006c5d8 in segv_handler (sc=0x5006e940) at trap_user.c:174
+       174       segv(sc->cr2, sc->err & 2);
+       (gdb)
+       #8  0x1006c5ec in kern_segv_handler (sig=11) at trap_user.c:182
+       182       segv_handler(sc);
+       (gdb) p *sc
+       Cannot access memory at address 0x0.
+
+
+
+
+  That's not very useful, so I'll try a more manual method:
+
+
+       (gdb) p *((struct sigcontext *) (&sig + 1))
+       $19 = {gs = 0, __gsh = 0, fs = 0, __fsh = 0, es = 43, __esh = 0, ds = 43,
+         __dsh = 0, edi = 1342179328, esi = 1350378548, ebp = 1342630440,
+         esp = 1342630420, ebx = 1348150624, edx = 1280, ecx = 0, eax = 0,
+         trapno = 14, err = 4, eip = 268480945, cs = 35, __csh = 0, eflags = 66118,
+         esp_at_signal = 1342630420, ss = 43, __ssh = 0, fpstate = 0x0, oldmask = 0,
+         cr2 = 1280}
+
+
+
+  The ip is in handle_mm_fault:
+
+
+       (gdb) p (void *)268480945
+       $20 = (void *) 0x1000b1b1
+       (gdb) i sym $20
+       handle_mm_fault + 57 in section .text
+
+
+
+
+
+  Specifically, it's in pte_alloc:
+
+
+       (gdb) i line *$20
+       Line 124 of "/home/dike/linux/2.3.26/um/include/asm/pgalloc.h"
+          starts at address 0x1000b1b1 <handle_mm_fault+57>
+          and ends at 0x1000b1b7 <handle_mm_fault+63>.
+
+
+
+
+
+  To find where in handle_mm_fault this is, I'll jump forward in the
+  code until I see an address in that procedure:
+
+
+
+       (gdb) i line *0x1000b1c0
+       Line 126 of "/home/dike/linux/2.3.26/um/include/asm/pgalloc.h"
+          starts at address 0x1000b1b7 <handle_mm_fault+63>
+          and ends at 0x1000b1c3 <handle_mm_fault+75>.
+       (gdb) i line *0x1000b1d0
+       Line 131 of "/home/dike/linux/2.3.26/um/include/asm/pgalloc.h"
+          starts at address 0x1000b1d0 <handle_mm_fault+88>
+          and ends at 0x1000b1da <handle_mm_fault+98>.
+       (gdb) i line *0x1000b1e0
+       Line 61 of "/home/dike/linux/2.3.26/um/include/asm/pgalloc.h"
+          starts at address 0x1000b1da <handle_mm_fault+98>
+          and ends at 0x1000b1e1 <handle_mm_fault+105>.
+       (gdb) i line *0x1000b1f0
+       Line 134 of "/home/dike/linux/2.3.26/um/include/asm/pgalloc.h"
+          starts at address 0x1000b1f0 <handle_mm_fault+120>
+          and ends at 0x1000b200 <handle_mm_fault+136>.
+       (gdb) i line *0x1000b200
+       Line 135 of "/home/dike/linux/2.3.26/um/include/asm/pgalloc.h"
+          starts at address 0x1000b200 <handle_mm_fault+136>
+          and ends at 0x1000b208 <handle_mm_fault+144>.
+       (gdb) i line *0x1000b210
+       Line 139 of "/home/dike/linux/2.3.26/um/include/asm/pgalloc.h"
+          starts at address 0x1000b210 <handle_mm_fault+152>
+          and ends at 0x1000b219 <handle_mm_fault+161>.
+       (gdb) i line *0x1000b220
+       Line 1168 of "memory.c" starts at address 0x1000b21e <handle_mm_fault+166>
+          and ends at 0x1000b222 <handle_mm_fault+170>.
+
+
+
+
+
+  Something is apparently wrong with the page tables or vma_structs, so
+  lets go back to frame 11 and have a look at them:
+
+
+
+  #11 0x1006c0aa in segv (address=1342179328, is_write=2) at trap_kern.c:50
+  50        handle_mm_fault(current, vma, address, is_write);
+  (gdb) call pgd_offset_proc(vma->vm_mm, address)
+  $22 = (pgd_t *) 0x80a548c
+
+
+
+
+
+  That's pretty bogus.  Page tables aren't supposed to be in process
+  text or data areas.  Let's see what's in the vma:
+
+
+       (gdb) p *vma
+       $23 = {vm_mm = 0x507d2434, vm_start = 0, vm_end = 134512640,
+         vm_next = 0x80a4f8c, vm_page_prot = {pgprot = 0}, vm_flags = 31200,
+         vm_avl_height = 2058, vm_avl_left = 0x80a8c94, vm_avl_right = 0x80d1000,
+         vm_next_share = 0xaffffdb0, vm_pprev_share = 0xaffffe63,
+         vm_ops = 0xaffffe7a, vm_pgoff = 2952789626, vm_file = 0xafffffec,
+         vm_private_data = 0x62}
+       (gdb) p *vma.vm_mm
+       $24 = {mmap = 0x507d2434, mmap_avl = 0x0, mmap_cache = 0x8048000,
+         pgd = 0x80a4f8c, mm_users = {counter = 0}, mm_count = {counter = 134904288},
+         map_count = 134909076, mmap_sem = {count = {counter = 135073792},
+           sleepers = -1342177872, wait = {lock = <optimized out or zero length>,
+             task_list = {next = 0xaffffe63, prev = 0xaffffe7a},
+             __magic = -1342177670, __creator = -1342177300}, __magic = 98},
+         page_table_lock = {}, context = 138, start_code = 0, end_code = 0,
+         start_data = 0, end_data = 0, start_brk = 0, brk = 0, start_stack = 0,
+         arg_start = 0, arg_end = 0, env_start = 0, env_end = 0, rss = 1350381536,
+         total_vm = 0, locked_vm = 0, def_flags = 0, cpu_vm_mask = 0, swap_cnt = 0,
+         swap_address = 0, segments = 0x0}
+
+
+
+
+
+  This also pretty bogus.  With all of the 0x80xxxxx and 0xaffffxxx
+  addresses, this is looking like a stack was plonked down on top of
+  these structures.  Maybe it's a stack overflow from the next page:
+
+
+
+       (gdb) p vma
+       $25 = (struct vm_area_struct *) 0x507d2434
+
+
+
+
+
+  That's towards the lower quarter of the page, so that would have to
+  have been pretty heavy stack overflow:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+  (gdb) x/100x $25
+  0x507d2434:     0x507d2434      0x00000000      0x08048000      0x080a4f8c
+  0x507d2444:     0x00000000      0x080a79e0      0x080a8c94      0x080d1000
+  0x507d2454:     0xaffffdb0      0xaffffe63      0xaffffe7a      0xaffffe7a
+  0x507d2464:     0xafffffec      0x00000062      0x0000008a      0x00000000
+  0x507d2474:     0x00000000      0x00000000      0x00000000      0x00000000
+  0x507d2484:     0x00000000      0x00000000      0x00000000      0x00000000
+  0x507d2494:     0x00000000      0x00000000      0x507d2fe0      0x00000000
+  0x507d24a4:     0x00000000      0x00000000      0x00000000      0x00000000
+  0x507d24b4:     0x00000000      0x00000000      0x00000000      0x00000000
+  0x507d24c4:     0x00000000      0x00000000      0x00000000      0x00000000
+  0x507d24d4:     0x00000000      0x00000000      0x00000000      0x00000000
+  0x507d24e4:     0x00000000      0x00000000      0x00000000      0x00000000
+  0x507d24f4:     0x00000000      0x00000000      0x00000000      0x00000000
+  0x507d2504:     0x00000000      0x00000000      0x00000000      0x00000000
+  0x507d2514:     0x00000000      0x00000000      0x00000000      0x00000000
+  0x507d2524:     0x00000000      0x00000000      0x00000000      0x00000000
+  0x507d2534:     0x00000000      0x00000000      0x507d25dc      0x00000000
+  0x507d2544:     0x00000000      0x00000000      0x00000000      0x00000000
+  0x507d2554:     0x00000000      0x00000000      0x00000000      0x00000000
+  0x507d2564:     0x00000000      0x00000000      0x00000000      0x00000000
+  0x507d2574:     0x00000000      0x00000000      0x00000000      0x00000000
+  0x507d2584:     0x00000000      0x00000000      0x00000000      0x00000000
+  0x507d2594:     0x00000000      0x00000000      0x00000000      0x00000000
+  0x507d25a4:     0x00000000      0x00000000      0x00000000      0x00000000
+  0x507d25b4:     0x00000000      0x00000000      0x00000000      0x00000000
+
+
+
+
+
+  It's not stack overflow.  The only "stack-like" piece of this data is
+  the vma_struct itself.
+
+
+  At this point, I don't see any avenues to pursue, so I just have to
+  admit that I have no idea what's going on.  What I will do, though, is
+  stick a trap on the segfault handler which will stop if it sees any
+  writes to the idle thread's stack.  That was the thing that happened
+  first, and it may be that if I can catch it immediately, what's going
+  on will be somewhat clearer.
+
+
+  1122..22..  EEppiissooddee 22:: TThhee ccaassee ooff tthhee hhuunngg ffsscckk
+
+  After setting a trap in the SEGV handler for accesses to the signal
+  thread's stack, I reran the kernel.
+
+
+  fsck hung again, this time by hitting the trap:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+  Setting hostname uml                            [ OK ]
+  Checking root filesystem
+  /dev/fhd0 contains a file system with errors, check forced.
+  Error reading block 86894 (Attempt to read block from filesystem resulted in short read) while reading indirect blocks of inode 19780.
+
+  /dev/fhd0: UNEXPECTED INCONSISTENCY; RUN fsck MANUALLY.
+          (i.e., without -a or -p options)
+  [ FAILED ]
+
+  *** An error occurred during the file system check.
+  *** Dropping you to a shell; the system will reboot
+  *** when you leave the shell.
+  Give root password for maintenance
+  (or type Control-D for normal startup):
+
+  [root@uml /root]# fsck -y /dev/fhd0
+  fsck -y /dev/fhd0
+  Parallelizing fsck version 1.14 (9-Jan-1999)
+  e2fsck 1.14, 9-Jan-1999 for EXT2 FS 0.5b, 95/08/09
+  /dev/fhd0 contains a file system with errors, check forced.
+  Pass 1: Checking inodes, blocks, and sizes
+  Error reading block 86894 (Attempt to read block from filesystem resulted in short read) while reading indirect blocks of inode 19780.  Ignore error? yes
+
+  Pass 2: Checking directory structure
+  Error reading block 49405 (Attempt to read block from filesystem resulted in short read).  Ignore error? yes
+
+  Directory inode 11858, block 0, offset 0: directory corrupted
+  Salvage? yes
+
+  Missing '.' in directory inode 11858.
+  Fix? yes
+
+  Missing '..' in directory inode 11858.
+  Fix? yes
+
+  Untested (4127) [100fe44c]: trap_kern.c line 31
+
+
+
+
+
+  I need to get the signal thread to detach from pid 4127 so that I can
+  attach to it with gdb.  This is done by sending it a SIGUSR1, which is
+  caught by the signal thread, which detaches the process:
+
+
+       kill -USR1 4127
+
+
+
+
+
+  Now I can run gdb on it:
+
+
+
+
+
+
+
+
+
+
+
+
+
+  ~/linux/2.3.26/um 1034: gdb linux
+  GNU gdb 4.17.0.11 with Linux support
+  Copyright 1998 Free Software Foundation, Inc.
+  GDB is free software, covered by the GNU General Public License, and you are
+  welcome to change it and/or distribute copies of it under certain conditions.
+  Type "show copying" to see the conditions.
+  There is absolutely no warranty for GDB.  Type "show warranty" for details.
+  This GDB was configured as "i386-redhat-linux"...
+  (gdb) att 4127
+  Attaching to program `/home/dike/linux/2.3.26/um/linux', Pid 4127
+  0x10075891 in __libc_nanosleep ()
+
+
+
+
+
+  The backtrace shows that it was in a write and that the fault address
+  (address in frame 3) is 0x50000800, which is right in the middle of
+  the signal thread's stack page:
+
+
+       (gdb) bt
+       #0  0x10075891 in __libc_nanosleep ()
+       #1  0x1007584d in __sleep (seconds=1000000)
+           at ../sysdeps/unix/sysv/linux/sleep.c:78
+       #2  0x1006ce9a in stop () at user_util.c:191
+       #3  0x1006bf88 in segv (address=1342179328, is_write=2) at trap_kern.c:31
+       #4  0x1006c628 in segv_handler (sc=0x5006eaf8) at trap_user.c:174
+       #5  0x1006c63c in kern_segv_handler (sig=11) at trap_user.c:182
+       #6  <signal handler called>
+       #7  0xc0fd in ?? ()
+       #8  0x10016647 in sys_write (fd=3, buf=0x80b8800 "R.", count=1024)
+           at read_write.c:159
+       #9  0x1006d603 in execute_syscall (syscall=4, args=0x5006ef08)
+           at syscall_kern.c:254
+       #10 0x1006af87 in really_do_syscall (sig=12) at syscall_user.c:35
+       #11 <signal handler called>
+       #12 0x400dc8b0 in ?? ()
+       #13 <signal handler called>
+       #14 0x400dc8b0 in ?? ()
+       #15 0x80545fd in ?? ()
+       #16 0x804daae in ?? ()
+       #17 0x8054334 in ?? ()
+       #18 0x804d23e in ?? ()
+       #19 0x8049632 in ?? ()
+       #20 0x80491d2 in ?? ()
+       #21 0x80596b5 in ?? ()
+       (gdb) p (void *)1342179328
+       $3 = (void *) 0x50000800
+
+
+
+
+
+  Going up the stack to the segv_handler frame and looking at where in
+  the code the access happened shows that it happened near line 110 of
+  block_dev.c:
+
+
+
+
+
+
+
+
+
+  (gdb) up
+  #1  0x1007584d in __sleep (seconds=1000000)
+      at ../sysdeps/unix/sysv/linux/sleep.c:78
+  ../sysdeps/unix/sysv/linux/sleep.c:78: No such file or directory.
+  (gdb)
+  #2  0x1006ce9a in stop () at user_util.c:191
+  191       while(1) sleep(1000000);
+  (gdb)
+  #3  0x1006bf88 in segv (address=1342179328, is_write=2) at trap_kern.c:31
+  31          KERN_UNTESTED();
+  (gdb)
+  #4  0x1006c628 in segv_handler (sc=0x5006eaf8) at trap_user.c:174
+  174       segv(sc->cr2, sc->err & 2);
+  (gdb) p *sc
+  $1 = {gs = 0, __gsh = 0, fs = 0, __fsh = 0, es = 43, __esh = 0, ds = 43,
+    __dsh = 0, edi = 1342179328, esi = 134973440, ebp = 1342631484,
+    esp = 1342630864, ebx = 256, edx = 0, ecx = 256, eax = 1024, trapno = 14,
+    err = 6, eip = 268550834, cs = 35, __csh = 0, eflags = 66070,
+    esp_at_signal = 1342630864, ss = 43, __ssh = 0, fpstate = 0x0, oldmask = 0,
+    cr2 = 1342179328}
+  (gdb) p (void *)268550834
+  $2 = (void *) 0x1001c2b2
+  (gdb) i sym $2
+  block_write + 1090 in section .text
+  (gdb) i line *$2
+  Line 209 of "/home/dike/linux/2.3.26/um/include/asm/arch/string.h"
+     starts at address 0x1001c2a1 <block_write+1073>
+     and ends at 0x1001c2bf <block_write+1103>.
+  (gdb) i line *0x1001c2c0
+  Line 110 of "block_dev.c" starts at address 0x1001c2bf <block_write+1103>
+     and ends at 0x1001c2e3 <block_write+1139>.
+
+
+
+
+
+  Looking at the source shows that the fault happened during a call to
+  copy_to_user to copy the data into the kernel:
+
+
+       107             count -= chars;
+       108             copy_from_user(p,buf,chars);
+       109             p += chars;
+       110             buf += chars;
+
+
+
+
+
+  p is the pointer which must contain 0x50000800, since buf contains
+  0x80b8800 (frame 8 above).  It is defined as:
+
+
+                       p = offset + bh->b_data;
+
+
+
+
+
+  I need to figure out what bh is, and it just so happens that bh is
+  passed as an argument to mark_buffer_uptodate and mark_buffer_dirty a
+  few lines later, so I do a little disassembly:
+
+
+
+
+  (gdb) disas 0x1001c2bf 0x1001c2e0
+  Dump of assembler code from 0x1001c2bf to 0x1001c2d0:
+  0x1001c2bf <block_write+1103>:  addl   %eax,0xc(%ebp)
+  0x1001c2c2 <block_write+1106>:  movl   0xfffffdd4(%ebp),%edx
+  0x1001c2c8 <block_write+1112>:  btsl   $0x0,0x18(%edx)
+  0x1001c2cd <block_write+1117>:  btsl   $0x1,0x18(%edx)
+  0x1001c2d2 <block_write+1122>:  sbbl   %ecx,%ecx
+  0x1001c2d4 <block_write+1124>:  testl  %ecx,%ecx
+  0x1001c2d6 <block_write+1126>:  jne    0x1001c2e3 <block_write+1139>
+  0x1001c2d8 <block_write+1128>:  pushl  $0x0
+  0x1001c2da <block_write+1130>:  pushl  %edx
+  0x1001c2db <block_write+1131>:  call   0x1001819c <__mark_buffer_dirty>
+  End of assembler dump.
+
+
+
+
+
+  At that point, bh is in %edx (address 0x1001c2da), which is calculated
+  at 0x1001c2c2 as %ebp + 0xfffffdd4, so I figure exactly what that is,
+  taking %ebp from the sigcontext_struct above:
+
+
+       (gdb) p (void *)1342631484
+       $5 = (void *) 0x5006ee3c
+       (gdb) p 0x5006ee3c+0xfffffdd4
+       $6 = 1342630928
+       (gdb) p (void *)$6
+       $7 = (void *) 0x5006ec10
+       (gdb) p *((void **)$7)
+       $8 = (void *) 0x50100200
+
+
+
+
+
+  Now, I look at the structure to see what's in it, and particularly,
+  what its b_data field contains:
+
+
+       (gdb) p *((struct buffer_head *)0x50100200)
+       $13 = {b_next = 0x50289380, b_blocknr = 49405, b_size = 1024, b_list = 0,
+         b_dev = 15872, b_count = {counter = 1}, b_rdev = 15872, b_state = 24,
+         b_flushtime = 0, b_next_free = 0x501001a0, b_prev_free = 0x50100260,
+         b_this_page = 0x501001a0, b_reqnext = 0x0, b_pprev = 0x507fcf58,
+         b_data = 0x50000800 "", b_page = 0x50004000,
+         b_end_io = 0x10017f60 <end_buffer_io_sync>, b_dev_id = 0x0,
+         b_rsector = 98810, b_wait = {lock = <optimized out or zero length>,
+           task_list = {next = 0x50100248, prev = 0x50100248}, __magic = 1343226448,
+           __creator = 0}, b_kiobuf = 0x0}
+
+
+
+
+
+  The b_data field is indeed 0x50000800, so the question becomes how
+  that happened.  The rest of the structure looks fine, so this probably
+  is not a case of data corruption.  It happened on purpose somehow.
+
+
+  The b_page field is a pointer to the page_struct representing the
+  0x50000000 page.  Looking at it shows the kernel's idea of the state
+  of that page:
+
+
+
+  (gdb) p *$13.b_page
+  $17 = {list = {next = 0x50004a5c, prev = 0x100c5174}, mapping = 0x0,
+    index = 0, next_hash = 0x0, count = {counter = 1}, flags = 132, lru = {
+      next = 0x50008460, prev = 0x50019350}, wait = {
+      lock = <optimized out or zero length>, task_list = {next = 0x50004024,
+        prev = 0x50004024}, __magic = 1342193708, __creator = 0},
+    pprev_hash = 0x0, buffers = 0x501002c0, virtual = 1342177280,
+    zone = 0x100c5160}
+
+
+
+
+
+  Some sanity-checking: the virtual field shows the "virtual" address of
+  this page, which in this kernel is the same as its "physical" address,
+  and the page_struct itself should be mem_map[0], since it represents
+  the first page of memory:
+
+
+
+       (gdb) p (void *)1342177280
+       $18 = (void *) 0x50000000
+       (gdb) p mem_map
+       $19 = (mem_map_t *) 0x50004000
+
+
+
+
+
+  These check out fine.
+
+
+  Now to check out the page_struct itself.  In particular, the flags
+  field shows whether the page is considered free or not:
+
+
+       (gdb) p (void *)132
+       $21 = (void *) 0x84
+
+
+
+
+
+  The "reserved" bit is the high bit, which is definitely not set, so
+  the kernel considers the signal stack page to be free and available to
+  be used.
+
+
+  At this point, I jump to conclusions and start looking at my early
+  boot code, because that's where that page is supposed to be reserved.
+
+
+  In my setup_arch procedure, I have the following code which looks just
+  fine:
+
+
+
+       bootmap_size = init_bootmem(start_pfn, end_pfn - start_pfn);
+       free_bootmem(__pa(low_physmem) + bootmap_size, high_physmem - low_physmem);
+
+
+
+
+
+  Two stack pages have already been allocated, and low_physmem points to
+  the third page, which is the beginning of free memory.
+  The init_bootmem call declares the entire memory to the boot memory
+  manager, which marks it all reserved.  The free_bootmem call frees up
+  all of it, except for the first two pages.  This looks correct to me.
+
+
+  So, I decide to see init_bootmem run and make sure that it is marking
+  those first two pages as reserved.  I never get that far.
+
+
+  Stepping into init_bootmem, and looking at bootmem_map before looking
+  at what it contains shows the following:
+
+
+
+       (gdb) p bootmem_map
+       $3 = (void *) 0x50000000
+
+
+
+
+
+  Aha!  The light dawns.  That first page is doing double duty as a
+  stack and as the boot memory map.  The last thing that the boot memory
+  manager does is to free the pages used by its memory map, so this page
+  is getting freed even its marked as reserved.
+
+
+  The fix was to initialize the boot memory manager before allocating
+  those two stack pages, and then allocate them through the boot memory
+  manager.  After doing this, and fixing a couple of subsequent buglets,
+  the stack corruption problem disappeared.
+
+
+
+
+
+  1133..  WWhhaatt ttoo ddoo wwhheenn UUMMLL ddooeessnn''tt wwoorrkk
+
+
+
+
+  1133..11..  SSttrraannggee ccoommppiillaattiioonn eerrrroorrss wwhheenn yyoouu bbuuiilldd ffrroomm ssoouurrccee
+
+  As of test11, it is necessary to have "ARCH=um" in the environment or
+  on the make command line for all steps in building UML, including
+  clean, distclean, or mrproper, config, menuconfig, or xconfig, dep,
+  and linux.  If you forget for any of them, the i386 build seems to
+  contaminate the UML build.  If this happens, start from scratch with
+
+
+       host%
+       make mrproper ARCH=um
+
+
+
+
+  and repeat the build process with ARCH=um on all the steps.
+
+
+  See ``Compiling the kernel and modules''  for more details.
+
+
+  Another cause of strange compilation errors is building UML in
+  /usr/src/linux.  If you do this, the first thing you need to do is
+  clean up the mess you made.  The /usr/src/linux/asm link will now
+  point to /usr/src/linux/asm-um.  Make it point back to
+  /usr/src/linux/asm-i386.  Then, move your UML pool someplace else and
+  build it there.  Also see below, where a more specific set of symptoms
+  is described.
+
+
+
+  1133..33..  AA vvaarriieettyy ooff ppaanniiccss aanndd hhaannggss wwiitthh //ttmmpp oonn aa rreeiisseerrffss  ffiilleessyyss--
+  tteemm
+
+  I saw this on reiserfs 3.5.21 and it seems to be fixed in 3.5.27.
+  Panics preceded by
+
+
+       Detaching pid nnnn
+
+
+
+  are diagnostic of this problem.  This is a reiserfs bug which causes a
+  thread to occasionally read stale data from a mmapped page shared with
+  another thread.  The fix is to upgrade the filesystem or to have /tmp
+  be an ext2 filesystem.
+
+
+
+  1133..44..  TThhee ccoommppiillee ffaaiillss wwiitthh eerrrroorrss aabboouutt ccoonnfflliiccttiinngg ttyyppeess ffoorr
+  ''ooppeenn'',, ''dduupp'',, aanndd ''wwaaiittppiidd''
+
+  This happens when you build in /usr/src/linux.  The UML build makes
+  the include/asm link point to include/asm-um.  /usr/include/asm points
+  to /usr/src/linux/include/asm, so when that link gets moved, files
+  which need to include the asm-i386 versions of headers get the
+  incompatible asm-um versions.  The fix is to move the include/asm link
+  back to include/asm-i386 and to do UML builds someplace else.
+
+
+
+  1133..55..  UUMMLL ddooeessnn''tt wwoorrkk wwhheenn //ttmmpp iiss aann NNFFSS ffiilleessyysstteemm
+
+  This seems to be a similar situation with the ReiserFS problem above.
+  Some versions of NFS seems not to handle mmap correctly, which UML
+  depends on.  The workaround is have /tmp be a non-NFS directory.
+
+
+  1133..66..  UUMMLL hhaannggss oonn bboooott wwhheenn ccoommppiilleedd wwiitthh ggpprrooff ssuuppppoorrtt
+
+  If you build UML with gprof support and, early in the boot, it does
+  this
+
+
+       kernel BUG at page_alloc.c:100!
+
+
+
+
+  you have a buggy gcc.  You can work around the problem by removing
+  UM_FASTCALL from CFLAGS in arch/um/Makefile-i386.  This will open up
+  another bug, but that one is fairly hard to reproduce.
+
+
+
+  1133..77..  ssyyssllooggdd ddiieess wwiitthh aa SSIIGGTTEERRMM oonn ssttaarrttuupp
+
+  The exact boot error depends on the distribution that you're booting,
+  but Debian produces this:
+
+
+       /etc/rc2.d/S10sysklogd: line 49:    93 Terminated
+       start-stop-daemon --start --quiet --exec /sbin/syslogd -- $SYSLOGD
+
+
+
+
+  This is a syslogd bug.  There's a race between a parent process
+  installing a signal handler and its child sending the signal.  See
+  this uml-devel post <http://www.geocrawler.com/lists/3/Source-
+  Forge/709/0/6612801>  for the details.
+
+
+
+  1133..88..  TTUUNN//TTAAPP nneettwwoorrkkiinngg ddooeessnn''tt wwoorrkk oonn aa 22..44 hhoosstt
+
+  There are a couple of problems which were
+  <http://www.geocrawler.com/lists/3/SourceForge/597/0/> name="pointed
+  out">  by Tim Robinson <timro at trkr dot net>
+
+  +o  It doesn't work on hosts running 2.4.7 (or thereabouts) or earlier.
+     The fix is to upgrade to something more recent and then read the
+     next item.
+
+  +o  If you see
+
+
+       File descriptor in bad state
+
+
+
+  when you bring up the device inside UML, you have a header mismatch
+  between the original kernel and the upgraded one.  Make /usr/src/linux
+  point at the new headers.  This will only be a problem if you build
+  uml_net yourself.
+
+
+
+  1133..99..  YYoouu ccaann nneettwwoorrkk ttoo tthhee hhoosstt bbuutt nnoott ttoo ootthheerr mmaacchhiinneess oonn tthhee
+  nneett
+
+  If you can connect to the host, and the host can connect to UML, but
+  you cannot connect to any other machines, then you may need to enable
+  IP Masquerading on the host.  Usually this is only experienced when
+  using private IP addresses (192.168.x.x or 10.x.x.x) for host/UML
+  networking, rather than the public address space that your host is
+  connected to.  UML does not enable IP Masquerading, so you will need
+  to create a static rule to enable it:
+
+
+       host%
+       iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
+
+
+
+
+  Replace eth0 with the interface that you use to talk to the rest of
+  the world.
+
+
+  Documentation on IP Masquerading, and SNAT, can be found at
+  www.netfilter.org  <http://www.netfilter.org> .
+
+
+  If you can reach the local net, but not the outside Internet, then
+  that is usually a routing problem.  The UML needs a default route:
+
+
+       UML#
+       route add default gw gateway IP
+
+
+
+
+  The gateway IP can be any machine on the local net that knows how to
+  reach the outside world.  Usually, this is the host or the local net-
+  work's gateway.
+
+
+  Occasionally, we hear from someone who can reach some machines, but
+  not others on the same net, or who can reach some ports on other
+  machines, but not others.  These are usually caused by strange
+  firewalling somewhere between the UML and the other box.  You track
+  this down by running tcpdump on every interface the packets travel
+  over and see where they disappear.  When you find a machine that takes
+  the packets in, but does not send them onward, that's the culprit.
+
+
+
+  1133..1100..  II hhaavvee nnoo rroooott aanndd II wwaanntt ttoo ssccrreeaamm
+
+  Thanks to Birgit Wahlich for telling me about this strange one.  It
+  turns out that there's a limit of six environment variables on the
+  kernel command line.  When that limit is reached or exceeded, argument
+  processing stops, which means that the 'root=' argument that UML
+  usually adds is not seen.  So, the filesystem has no idea what the
+  root device is, so it panics.
+
+
+  The fix is to put less stuff on the command line.  Glomming all your
+  setup variables into one is probably the best way to go.
+
+
+
+  1133..1111..  UUMMLL bbuuiilldd ccoonnfflliicctt bbeettwweeeenn ppttrraaccee..hh aanndd uuccoonntteexxtt..hh
+
+  On some older systems, /usr/include/asm/ptrace.h and
+  /usr/include/sys/ucontext.h define the same names.  So, when they're
+  included together, the defines from one completely mess up the parsing
+  of the other, producing errors like:
+       /usr/include/sys/ucontext.h:47: parse error before
+       `10'
+
+
+
+
+  plus a pile of warnings.
+
+
+  This is a libc botch, which has since been fixed, and I don't see any
+  way around it besides upgrading.
+
+
+
+  1133..1122..  TThhee UUMMLL BBooggooMMiippss iiss eexxaaccttllyy hhaallff tthhee hhoosstt''ss BBooggooMMiippss
+
+  On i386 kernels, there are two ways of running the loop that is used
+  to calculate the BogoMips rating, using the TSC if it's there or using
+  a one-instruction loop.  The TSC produces twice the BogoMips as the
+  loop.  UML uses the loop, since it has nothing resembling a TSC, and
+  will get almost exactly the same BogoMips as a host using the loop.
+  However, on a host with a TSC, its BogoMips will be double the loop
+  BogoMips, and therefore double the UML BogoMips.
+
+
+
+  1133..1133..  WWhheenn yyoouu rruunn UUMMLL,, iitt iimmmmeeddiiaatteellyy sseeggffaauullttss
+
+  If the host is configured with the 2G/2G address space split, that's
+  why.  See ``UML on 2G/2G hosts''  for the details on getting UML to
+  run on your host.
+
+
+
+  1133..1144..  xxtteerrmmss aappppeeaarr,, tthheenn iimmmmeeddiiaatteellyy ddiissaappppeeaarr
+
+  If you're running an up to date kernel with an old release of
+  uml_utilities, the port-helper program will not work properly, so
+  xterms will exit straight after they appear. The solution is to
+  upgrade to the latest release of uml_utilities.  Usually this problem
+  occurs when you have installed a packaged release of UML then compiled
+  your own development kernel without upgrading the uml_utilities from
+  the source distribution.
+
+
+
+  1133..1155..  AAnnyy ootthheerr ppaanniicc,, hhaanngg,, oorr ssttrraannggee bbeehhaavviioorr
+
+  If you're seeing truly strange behavior, such as hangs or panics that
+  happen in random places, or you try running the debugger to see what's
+  happening and it acts strangely, then it could be a problem in the
+  host kernel.  If you're not running a stock Linus or -ac kernel, then
+  try that.  An early version of the preemption patch and a 2.4.10 SuSE
+  kernel have caused very strange problems in UML.
+
+
+  Otherwise, let me know about it.  Send a message to one of the UML
+  mailing lists - either the developer list - user-mode-linux-devel at
+  lists dot sourceforge dot net (subscription info) or the user list -
+  user-mode-linux-user at lists dot sourceforge do net (subscription
+  info), whichever you prefer.  Don't assume that everyone knows about
+  it and that a fix is imminent.
+
+
+  If you want to be super-helpful, read ``Diagnosing Problems'' and
+  follow the instructions contained therein.
+  1144..  DDiiaaggnnoossiinngg PPrroobblleemmss
+
+
+  If you get UML to crash, hang, or otherwise misbehave, you should
+  report this on one of the project mailing lists, either the developer
+  list - user-mode-linux-devel at lists dot sourceforge dot net
+  (subscription info) or the user list - user-mode-linux-user at lists
+  dot sourceforge dot net (subscription info).  When you do, it is
+  likely that I will want more information.  So, it would be helpful to
+  read the stuff below, do whatever is applicable in your case, and
+  report the results to the list.
+
+
+  For any diagnosis, you're going to need to build a debugging kernel.
+  The binaries from this site aren't debuggable.  If you haven't done
+  this before, read about ``Compiling the kernel and modules''  and
+  ``Kernel debugging''  UML first.
+
+
+  1144..11..  CCaassee 11 :: NNoorrmmaall kkeerrnneell ppaanniiccss
+
+  The most common case is for a normal thread to panic.  To debug this,
+  you will need to run it under the debugger (add 'debug' to the command
+  line).  An xterm will start up with gdb running inside it.  Continue
+  it when it stops in start_kernel and make it crash.  Now ^C gdb and
+
+
+  If the panic was a "Kernel mode fault", then there will be a segv
+  frame on the stack and I'm going to want some more information.  The
+  stack might look something like this:
+
+
+       (UML gdb)  backtrace
+       #0  0x1009bf76 in __sigprocmask (how=1, set=0x5f347940, oset=0x0)
+           at ../sysdeps/unix/sysv/linux/sigprocmask.c:49
+       #1  0x10091411 in change_sig (signal=10, on=1) at process.c:218
+       #2  0x10094785 in timer_handler (sig=26) at time_kern.c:32
+       #3  0x1009bf38 in __restore ()
+           at ../sysdeps/unix/sysv/linux/i386/sigaction.c:125
+       #4  0x1009534c in segv (address=8, ip=268849158, is_write=2, is_user=0)
+           at trap_kern.c:66
+       #5  0x10095c04 in segv_handler (sig=11) at trap_user.c:285
+       #6  0x1009bf38 in __restore ()
+
+
+
+
+  I'm going to want to see the symbol and line information for the value
+  of ip in the segv frame.  In this case, you would do the following:
+
+
+       (UML gdb)  i sym 268849158
+
+
+
+
+  and
+
+
+       (UML gdb)  i line *268849158
+
+
+
+
+  The reason for this is the __restore frame right above the segv_han-
+  dler frame is hiding the frame that actually segfaulted.  So, I have
+  to get that information from the faulting ip.
+
+
+  1144..22..  CCaassee 22 :: TTrraacciinngg tthhrreeaadd ppaanniiccss
+
+  The less common and more painful case is when the tracing thread
+  panics.  In this case, the kernel debugger will be useless because it
+  needs a healthy tracing thread in order to work.  The first thing to
+  do is get a backtrace from the tracing thread.  This is done by
+  figuring out what its pid is, firing up gdb, and attaching it to that
+  pid.  You can figure out the tracing thread pid by looking at the
+  first line of the console output, which will look like this:
+
+
+       tracing thread pid = 15851
+
+
+
+
+  or by running ps on the host and finding the line that looks like
+  this:
+
+
+       jdike 15851 4.5 0.4 132568 1104 pts/0 S 21:34 0:05 ./linux [(tracing thread)]
+
+
+
+
+  If the panic was 'segfault in signals', then follow the instructions
+  above for collecting information about the location of the seg fault.
+
+
+  If the tracing thread flaked out all by itself, then send that
+  backtrace in and wait for our crack debugging team to fix the problem.
+
+
+  1144..33..  CCaassee 33 :: TTrraacciinngg tthhrreeaadd ppaanniiccss ccaauusseedd bbyy ootthheerr tthhrreeaaddss
+
+  However, there are cases where the misbehavior of another thread
+  caused the problem.  The most common panic of this type is:
+
+
+       wait_for_stop failed to wait for  <pid>  to stop with  <signal number>
+
+
+
+
+  In this case, you'll need to get a backtrace from the process men-
+  tioned in the panic, which is complicated by the fact that the kernel
+  debugger is defunct and without some fancy footwork, another gdb can't
+  attach to it.  So, this is how the fancy footwork goes:
+
+  In a shell:
+
+
+       host% kill -STOP pid
+
+
+
+
+  Run gdb on the tracing thread as described in case 2 and do:
+
+
+       (host gdb)  call detach(pid)
+
+
+  If you get a segfault, do it again.  It always works the second time.
+
+  Detach from the tracing thread and attach to that other thread:
+
+
+       (host gdb)  detach
+
+
+
+
+
+
+       (host gdb)  attach pid
+
+
+
+
+  If gdb hangs when attaching to that process, go back to a shell and
+  do:
+
+
+       host%
+       kill -CONT pid
+
+
+
+
+  And then get the backtrace:
+
+
+       (host gdb)  backtrace
+
+
+
+
+
+  1144..44..  CCaassee 44 :: HHaannggss
+
+  Hangs seem to be fairly rare, but they sometimes happen.  When a hang
+  happens, we need a backtrace from the offending process.  Run the
+  kernel debugger as described in case 1 and get a backtrace.  If the
+  current process is not the idle thread, then send in the backtrace.
+  You can tell that it's the idle thread if the stack looks like this:
+
+
+       #0  0x100b1401 in __libc_nanosleep ()
+       #1  0x100a2885 in idle_sleep (secs=10) at time.c:122
+       #2  0x100a546f in do_idle () at process_kern.c:445
+       #3  0x100a5508 in cpu_idle () at process_kern.c:471
+       #4  0x100ec18f in start_kernel () at init/main.c:592
+       #5  0x100a3e10 in start_kernel_proc (unused=0x0) at um_arch.c:71
+       #6  0x100a383f in signal_tramp (arg=0x100a3dd8) at trap_user.c:50
+
+
+
+
+  If this is the case, then some other process is at fault, and went to
+  sleep when it shouldn't have.  Run ps on the host and figure out which
+  process should not have gone to sleep and stayed asleep.  Then attach
+  to it with gdb and get a backtrace as described in case 3.
+
+
+
+
+
+
+  1155..  TThhaannkkss
+
+
+  A number of people have helped this project in various ways, and this
+  page gives recognition where recognition is due.
+
+
+  If you're listed here and you would prefer a real link on your name,
+  or no link at all, instead of the despammed email address pseudo-link,
+  let me know.
+
+
+  If you're not listed here and you think maybe you should be, please
+  let me know that as well.  I try to get everyone, but sometimes my
+  bookkeeping lapses and I forget about contributions.
+
+
+  1155..11..  CCooddee aanndd DDooccuummeennttaattiioonn
+
+  Rusty Russell <rusty at linuxcare.com.au>  -
+
+  +o  wrote the  HOWTO <http://user-mode-
+     linux.sourceforge.net/UserModeLinux-HOWTO.html>
+
+  +o  prodded me into making this project official and putting it on
+     SourceForge
+
+  +o  came up with the way cool UML logo <http://user-mode-
+     linux.sourceforge.net/uml-small.png>
+
+  +o  redid the config process
+
+
+  Peter Moulder <reiter at netspace.net.au>  - Fixed my config and build
+  processes, and added some useful code to the block driver
+
+
+  Bill Stearns <wstearns at pobox.com>  -
+
+  +o  HOWTO updates
+
+  +o  lots of bug reports
+
+  +o  lots of testing
+
+  +o  dedicated a box (uml.ists.dartmouth.edu) to support UML development
+
+  +o  wrote the mkrootfs script, which allows bootable filesystems of
+     RPM-based distributions to be cranked out
+
+  +o  cranked out a large number of filesystems with said script
+
+
+  Jim Leu <jleu at mindspring.com>  - Wrote the virtual ethernet driver
+  and associated usermode tools
+
+  Lars Brinkhoff <http://lars.nocrew.org/>  - Contributed the ptrace
+  proxy from his own  project <http://a386.nocrew.org/> to allow easier
+  kernel debugging
+
+
+  Andrea Arcangeli <andrea at suse.de>  - Redid some of the early boot
+  code so that it would work on machines with Large File Support
+
+
+  Chris Emerson <http://www.chiark.greenend.org.uk/~cemerson/>  - Did
+  the first UML port to Linux/ppc
+
+
+  Harald Welte <laforge at gnumonks.org>  - Wrote the multicast
+  transport for the network driver
+
+
+  Jorgen Cederlof - Added special file support to hostfs
+
+
+  Greg Lonnon  <glonnon at ridgerun dot com>  - Changed the ubd driver
+  to allow it to layer a COW file on a shared read-only filesystem and
+  wrote the iomem emulation support
+
+
+  Henrik Nordstrom <http://hem.passagen.se/hno/>  - Provided a variety
+  of patches, fixes, and clues
+
+
+  Lennert Buytenhek - Contributed various patches, a rewrite of the
+  network driver, the first implementation of the mconsole driver, and
+  did the bulk of the work needed to get SMP working again.
+
+
+  Yon Uriarte - Fixed the TUN/TAP network backend while I slept.
+
+
+  Adam Heath - Made a bunch of nice cleanups to the initialization code,
+  plus various other small patches.
+
+
+  Matt Zimmerman - Matt volunteered to be the UML Debian maintainer and
+  is doing a real nice job of it.  He also noticed and fixed a number of
+  actually and potentially exploitable security holes in uml_net.  Plus
+  the occasional patch.  I like patches.
+
+
+  James McMechan - James seems to have taken over maintenance of the ubd
+  driver and is doing a nice job of it.
+
+
+  Chandan Kudige - wrote the umlgdb script which automates the reloading
+  of module symbols.
+
+
+  Steve Schmidtke - wrote the UML slirp transport and hostaudio drivers,
+  enabling UML processes to access audio devices on the host. He also
+  submitted patches for the slip transport and lots of other things.
+
+
+  David Coulson <http://davidcoulson.net>  -
+
+  +o  Set up the usermodelinux.org <http://usermodelinux.org>  site,
+     which is a great way of keeping the UML user community on top of
+     UML goings-on.
+
+  +o  Site documentation and updates
+
+  +o  Nifty little UML management daemon  UMLd
+     <http://uml.openconsultancy.com/umld/>
+
+  +o  Lots of testing and bug reports
+
+
+
+
+  1155..22..  FFlluusshhiinngg oouutt bbuuggss
+
+
+
+  +o  Yuri Pudgorodsky
+
+  +o  Gerald Britton
+
+  +o  Ian Wehrman
+
+  +o  Gord Lamb
+
+  +o  Eugene Koontz
+
+  +o  John H. Hartman
+
+  +o  Anders Karlsson
+
+  +o  Daniel Phillips
+
+  +o  John Fremlin
+
+  +o  Rainer Burgstaller
+
+  +o  James Stevenson
+
+  +o  Matt Clay
+
+  +o  Cliff Jefferies
+
+  +o  Geoff Hoff
+
+  +o  Lennert Buytenhek
+
+  +o  Al Viro
+
+  +o  Frank Klingenhoefer
+
+  +o  Livio Baldini Soares
+
+  +o  Jon Burgess
+
+  +o  Petru Paler
+
+  +o  Paul
+
+  +o  Chris Reahard
+
+  +o  Sverker Nilsson
+
+  +o  Gong Su
+
+  +o  johan verrept
+
+  +o  Bjorn Eriksson
+
+  +o  Lorenzo Allegrucci
+
+  +o  Muli Ben-Yehuda
+
+  +o  David Mansfield
+
+  +o  Howard Goff
+
+  +o  Mike Anderson
+
+  +o  John Byrne
+
+  +o  Sapan J. Batia
+
+  +o  Iris Huang
+
+  +o  Jan Hudec
+
+  +o  Voluspa
+
+
+
+
+  1155..33..  BBuugglleettss aanndd cclleeaann--uuppss
+
+
+
+  +o  Dave Zarzycki
+
+  +o  Adam Lazur
+
+  +o  Boria Feigin
+
+  +o  Brian J. Murrell
+
+  +o  JS
+
+  +o  Roman Zippel
+
+  +o  Wil Cooley
+
+  +o  Ayelet Shemesh
+
+  +o  Will Dyson
+
+  +o  Sverker Nilsson
+
+  +o  dvorak
+
+  +o  v.naga srinivas
+
+  +o  Shlomi Fish
+
+  +o  Roger Binns
+
+  +o  johan verrept
+
+  +o  MrChuoi
+
+  +o  Peter Cleve
+
+  +o  Vincent Guffens
+
+  +o  Nathan Scott
+
+  +o  Patrick Caulfield
+
+  +o  jbearce
+
+  +o  Catalin Marinas
+
+  +o  Shane Spencer
+
+  +o  Zou Min
+
+
+  +o  Ryan Boder
+
+  +o  Lorenzo Colitti
+
+  +o  Gwendal Grignou
+
+  +o  Andre' Breiler
+
+  +o  Tsutomu Yasuda
+
+
+
+  1155..44..  CCaassee SSttuuddiieess
+
+
+  +o  Jon Wright
+
+  +o  William McEwan
+
+  +o  Michael Richardson
+
+
+
+  1155..55..  OOtthheerr ccoonnttrriibbuuttiioonnss
+
+
+  Bill Carr <Bill.Carr at compaq.com>  made the Red Hat mkrootfs script
+  work with RH 6.2.
+
+  Michael Jennings <mikejen at hevanet.com>  sent in some material which
+  is now gracing the top of the  index  page <http://user-mode-
+  linux.sourceforge.net/>  of this site.
+
+  SGI <http://www.sgi.com>  (and more specifically Ralf Baechle <ralf at
+  uni-koblenz.de> ) gave me an account on oss.sgi.com
+  <http://www.oss.sgi.com> .  The bandwidth there made it possible to
+  produce most of the filesystems available on the project download
+  page.
+
+  Laurent Bonnaud <Laurent.Bonnaud at inpg.fr>  took the old grotty
+  Debian filesystem that I've been distributing and updated it to 2.2.
+  It is now available by itself here.
+
+  Rik van Riel gave me some ftp space on ftp.nl.linux.org so I can make
+  releases even when Sourceforge is broken.
+
+  Rodrigo de Castro looked at my broken pte code and told me what was
+  wrong with it, letting me fix a long-standing (several weeks) and
+  serious set of bugs.
+
+  Chris Reahard built a specialized root filesystem for running a DNS
+  server jailed inside UML.  It's available from the download
+  <http://user-mode-linux.sourceforge.net/dl-sf.html>  page in the Jail
+  Filesystems section.
+
+
+
+
+
+
+
+
+
+
+
+
diff -druN linux-2.6.39-libre/Documentation/vm/cleancache.txt linux-3.0-rc7-libre/Documentation/vm/cleancache.txt
--- linux-2.6.39-libre/Documentation/vm/cleancache.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/Documentation/vm/cleancache.txt	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,278 @@
+MOTIVATION
+
+Cleancache is a new optional feature provided by the VFS layer that
+potentially dramatically increases page cache effectiveness for
+many workloads in many environments at a negligible cost.
+
+Cleancache can be thought of as a page-granularity victim cache for clean
+pages that the kernel's pageframe replacement algorithm (PFRA) would like
+to keep around, but can't since there isn't enough memory.  So when the
+PFRA "evicts" a page, it first attempts to use cleancache code to
+put the data contained in that page into "transcendent memory", memory
+that is not directly accessible or addressable by the kernel and is
+of unknown and possibly time-varying size.
+
+Later, when a cleancache-enabled filesystem wishes to access a page
+in a file on disk, it first checks cleancache to see if it already
+contains it; if it does, the page of data is copied into the kernel
+and a disk access is avoided.
+
+Transcendent memory "drivers" for cleancache are currently implemented
+in Xen (using hypervisor memory) and zcache (using in-kernel compressed
+memory) and other implementations are in development.
+
+FAQs are included below.
+
+IMPLEMENTATION OVERVIEW
+
+A cleancache "backend" that provides transcendent memory registers itself
+to the kernel's cleancache "frontend" by calling cleancache_register_ops,
+passing a pointer to a cleancache_ops structure with funcs set appropriately.
+Note that cleancache_register_ops returns the previous settings so that
+chaining can be performed if desired. The functions provided must conform to
+certain semantics as follows:
+
+Most important, cleancache is "ephemeral".  Pages which are copied into
+cleancache have an indefinite lifetime which is completely unknowable
+by the kernel and so may or may not still be in cleancache at any later time.
+Thus, as its name implies, cleancache is not suitable for dirty pages.
+Cleancache has complete discretion over what pages to preserve and what
+pages to discard and when.
+
+Mounting a cleancache-enabled filesystem should call "init_fs" to obtain a
+pool id which, if positive, must be saved in the filesystem's superblock;
+a negative return value indicates failure.  A "put_page" will copy a
+(presumably about-to-be-evicted) page into cleancache and associate it with
+the pool id, a file key, and a page index into the file.  (The combination
+of a pool id, a file key, and an index is sometimes called a "handle".)
+A "get_page" will copy the page, if found, from cleancache into kernel memory.
+A "flush_page" will ensure the page no longer is present in cleancache;
+a "flush_inode" will flush all pages associated with the specified file;
+and, when a filesystem is unmounted, a "flush_fs" will flush all pages in
+all files specified by the given pool id and also surrender the pool id.
+
+An "init_shared_fs", like init_fs, obtains a pool id but tells cleancache
+to treat the pool as shared using a 128-bit UUID as a key.  On systems
+that may run multiple kernels (such as hard partitioned or virtualized
+systems) that may share a clustered filesystem, and where cleancache
+may be shared among those kernels, calls to init_shared_fs that specify the
+same UUID will receive the same pool id, thus allowing the pages to
+be shared.  Note that any security requirements must be imposed outside
+of the kernel (e.g. by "tools" that control cleancache).  Or a
+cleancache implementation can simply disable shared_init by always
+returning a negative value.
+
+If a get_page is successful on a non-shared pool, the page is flushed (thus
+making cleancache an "exclusive" cache).  On a shared pool, the page
+is NOT flushed on a successful get_page so that it remains accessible to
+other sharers.  The kernel is responsible for ensuring coherency between
+cleancache (shared or not), the page cache, and the filesystem, using
+cleancache flush operations as required.
+
+Note that cleancache must enforce put-put-get coherency and get-get
+coherency.  For the former, if two puts are made to the same handle but
+with different data, say AAA by the first put and BBB by the second, a
+subsequent get can never return the stale data (AAA).  For get-get coherency,
+if a get for a given handle fails, subsequent gets for that handle will
+never succeed unless preceded by a successful put with that handle.
+
+Last, cleancache provides no SMP serialization guarantees; if two
+different Linux threads are simultaneously putting and flushing a page
+with the same handle, the results are indeterminate.  Callers must
+lock the page to ensure serial behavior.
+
+CLEANCACHE PERFORMANCE METRICS
+
+Cleancache monitoring is done by sysfs files in the
+/sys/kernel/mm/cleancache directory.  The effectiveness of cleancache
+can be measured (across all filesystems) with:
+
+succ_gets	- number of gets that were successful
+failed_gets	- number of gets that failed
+puts		- number of puts attempted (all "succeed")
+flushes		- number of flushes attempted
+
+A backend implementatation may provide additional metrics.
+
+FAQ
+
+1) Where's the value? (Andrew Morton)
+
+Cleancache provides a significant performance benefit to many workloads
+in many environments with negligible overhead by improving the
+effectiveness of the pagecache.  Clean pagecache pages are
+saved in transcendent memory (RAM that is otherwise not directly
+addressable to the kernel); fetching those pages later avoids "refaults"
+and thus disk reads.
+
+Cleancache (and its sister code "frontswap") provide interfaces for
+this transcendent memory (aka "tmem"), which conceptually lies between
+fast kernel-directly-addressable RAM and slower DMA/asynchronous devices.
+Disallowing direct kernel or userland reads/writes to tmem
+is ideal when data is transformed to a different form and size (such
+as with compression) or secretly moved (as might be useful for write-
+balancing for some RAM-like devices).  Evicted page-cache pages (and
+swap pages) are a great use for this kind of slower-than-RAM-but-much-
+faster-than-disk transcendent memory, and the cleancache (and frontswap)
+"page-object-oriented" specification provides a nice way to read and
+write -- and indirectly "name" -- the pages.
+
+In the virtual case, the whole point of virtualization is to statistically
+multiplex physical resources across the varying demands of multiple
+virtual machines.  This is really hard to do with RAM and efforts to
+do it well with no kernel change have essentially failed (except in some
+well-publicized special-case workloads).  Cleancache -- and frontswap --
+with a fairly small impact on the kernel, provide a huge amount
+of flexibility for more dynamic, flexible RAM multiplexing.
+Specifically, the Xen Transcendent Memory backend allows otherwise
+"fallow" hypervisor-owned RAM to not only be "time-shared" between multiple
+virtual machines, but the pages can be compressed and deduplicated to
+optimize RAM utilization.  And when guest OS's are induced to surrender
+underutilized RAM (e.g. with "self-ballooning"), page cache pages
+are the first to go, and cleancache allows those pages to be
+saved and reclaimed if overall host system memory conditions allow.
+
+And the identical interface used for cleancache can be used in
+physical systems as well.  The zcache driver acts as a memory-hungry
+device that stores pages of data in a compressed state.  And
+the proposed "RAMster" driver shares RAM across multiple physical
+systems.
+
+2) Why does cleancache have its sticky fingers so deep inside the
+   filesystems and VFS? (Andrew Morton and Christoph Hellwig)
+
+The core hooks for cleancache in VFS are in most cases a single line
+and the minimum set are placed precisely where needed to maintain
+coherency (via cleancache_flush operations) between cleancache,
+the page cache, and disk.  All hooks compile into nothingness if
+cleancache is config'ed off and turn into a function-pointer-
+compare-to-NULL if config'ed on but no backend claims the ops
+functions, or to a compare-struct-element-to-negative if a
+backend claims the ops functions but a filesystem doesn't enable
+cleancache.
+
+Some filesystems are built entirely on top of VFS and the hooks
+in VFS are sufficient, so don't require an "init_fs" hook; the
+initial implementation of cleancache didn't provide this hook.
+But for some filesystems (such as btrfs), the VFS hooks are
+incomplete and one or more hooks in fs-specific code are required.
+And for some other filesystems, such as tmpfs, cleancache may
+be counterproductive.  So it seemed prudent to require a filesystem
+to "opt in" to use cleancache, which requires adding a hook in
+each filesystem.  Not all filesystems are supported by cleancache
+only because they haven't been tested.  The existing set should
+be sufficient to validate the concept, the opt-in approach means
+that untested filesystems are not affected, and the hooks in the
+existing filesystems should make it very easy to add more
+filesystems in the future.
+
+The total impact of the hooks to existing fs and mm files is only
+about 40 lines added (not counting comments and blank lines).
+
+3) Why not make cleancache asynchronous and batched so it can
+   more easily interface with real devices with DMA instead
+   of copying each individual page? (Minchan Kim)
+
+The one-page-at-a-time copy semantics simplifies the implementation
+on both the frontend and backend and also allows the backend to
+do fancy things on-the-fly like page compression and
+page deduplication.  And since the data is "gone" (copied into/out
+of the pageframe) before the cleancache get/put call returns,
+a great deal of race conditions and potential coherency issues
+are avoided.  While the interface seems odd for a "real device"
+or for real kernel-addressable RAM, it makes perfect sense for
+transcendent memory.
+
+4) Why is non-shared cleancache "exclusive"?  And where is the
+   page "flushed" after a "get"? (Minchan Kim)
+
+The main reason is to free up space in transcendent memory and
+to avoid unnecessary cleancache_flush calls.  If you want inclusive,
+the page can be "put" immediately following the "get".  If
+put-after-get for inclusive becomes common, the interface could
+be easily extended to add a "get_no_flush" call.
+
+The flush is done by the cleancache backend implementation.
+
+5) What's the performance impact?
+
+Performance analysis has been presented at OLS'09 and LCA'10.
+Briefly, performance gains can be significant on most workloads,
+especially when memory pressure is high (e.g. when RAM is
+overcommitted in a virtual workload); and because the hooks are
+invoked primarily in place of or in addition to a disk read/write,
+overhead is negligible even in worst case workloads.  Basically
+cleancache replaces I/O with memory-copy-CPU-overhead; on older
+single-core systems with slow memory-copy speeds, cleancache
+has little value, but in newer multicore machines, especially
+consolidated/virtualized machines, it has great value.
+
+6) How do I add cleancache support for filesystem X? (Boaz Harrash)
+
+Filesystems that are well-behaved and conform to certain
+restrictions can utilize cleancache simply by making a call to
+cleancache_init_fs at mount time.  Unusual, misbehaving, or
+poorly layered filesystems must either add additional hooks
+and/or undergo extensive additional testing... or should just
+not enable the optional cleancache.
+
+Some points for a filesystem to consider:
+
+- The FS should be block-device-based (e.g. a ram-based FS such
+  as tmpfs should not enable cleancache)
+- To ensure coherency/correctness, the FS must ensure that all
+  file removal or truncation operations either go through VFS or
+  add hooks to do the equivalent cleancache "flush" operations
+- To ensure coherency/correctness, either inode numbers must
+  be unique across the lifetime of the on-disk file OR the
+  FS must provide an "encode_fh" function.
+- The FS must call the VFS superblock alloc and deactivate routines
+  or add hooks to do the equivalent cleancache calls done there.
+- To maximize performance, all pages fetched from the FS should
+  go through the do_mpag_readpage routine or the FS should add
+  hooks to do the equivalent (cf. btrfs)
+- Currently, the FS blocksize must be the same as PAGESIZE.  This
+  is not an architectural restriction, but no backends currently
+  support anything different.
+- A clustered FS should invoke the "shared_init_fs" cleancache
+  hook to get best performance for some backends.
+
+7) Why not use the KVA of the inode as the key? (Christoph Hellwig)
+
+If cleancache would use the inode virtual address instead of
+inode/filehandle, the pool id could be eliminated.  But, this
+won't work because cleancache retains pagecache data pages
+persistently even when the inode has been pruned from the
+inode unused list, and only flushes the data page if the file
+gets removed/truncated.  So if cleancache used the inode kva,
+there would be potential coherency issues if/when the inode
+kva is reused for a different file.  Alternately, if cleancache
+flushed the pages when the inode kva was freed, much of the value
+of cleancache would be lost because the cache of pages in cleanache
+is potentially much larger than the kernel pagecache and is most
+useful if the pages survive inode cache removal.
+
+8) Why is a global variable required?
+
+The cleancache_enabled flag is checked in all of the frequently-used
+cleancache hooks.  The alternative is a function call to check a static
+variable. Since cleancache is enabled dynamically at runtime, systems
+that don't enable cleancache would suffer thousands (possibly
+tens-of-thousands) of unnecessary function calls per second.  So the
+global variable allows cleancache to be enabled by default at compile
+time, but have insignificant performance impact when cleancache remains
+disabled at runtime.
+
+9) Does cleanache work with KVM?
+
+The memory model of KVM is sufficiently different that a cleancache
+backend may have less value for KVM.  This remains to be tested,
+especially in an overcommitted system.
+
+10) Does cleancache work in userspace?  It sounds useful for
+   memory hungry caches like web browsers.  (Jamie Lokier)
+
+No plans yet, though we agree it sounds useful, at least for
+apps that bypass the page cache (e.g. O_DIRECT).
+
+Last updated: Dan Magenheimer, April 13 2011
diff -druN linux-2.6.39-libre/Documentation/vm/hwpoison.txt linux-3.0-rc7-libre/Documentation/vm/hwpoison.txt
--- linux-2.6.39-libre/Documentation/vm/hwpoison.txt	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/Documentation/vm/hwpoison.txt	2011-07-11 19:51:52.000000000 -0400
@@ -129,12 +129,12 @@
 of the memcg.
 
 Example:
-        mkdir /cgroup/hwpoison
+        mkdir /sys/fs/cgroup/mem/hwpoison
 
         usemem -m 100 -s 1000 &
-        echo `jobs -p` > /cgroup/hwpoison/tasks
+        echo `jobs -p` > /sys/fs/cgroup/mem/hwpoison/tasks
 
-        memcg_ino=$(ls -id /cgroup/hwpoison | cut -f1 -d' ')
+        memcg_ino=$(ls -id /sys/fs/cgroup/mem/hwpoison | cut -f1 -d' ')
         echo $memcg_ino > /debug/hwpoison/corrupt-filter-memcg
 
         page-types -p `pidof init`   --hwpoison  # shall do nothing
diff -druN linux-2.6.39-libre/Documentation/vm/locking linux-3.0-rc7-libre/Documentation/vm/locking
--- linux-2.6.39-libre/Documentation/vm/locking	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/Documentation/vm/locking	2011-07-11 19:51:52.000000000 -0400
@@ -66,7 +66,7 @@
 expand_stack(), it is hard to come up with a destructive scenario without 
 having the vmlist protection in this case.
 
-The page_table_lock nests with the inode i_mmap_lock and the kmem cache
+The page_table_lock nests with the inode i_mmap_mutex and the kmem cache
 c_spinlock spinlocks.  This is okay, since the kmem code asks for pages after
 dropping c_spinlock.  The page_table_lock also nests with pagecache_lock and
 pagemap_lru_lock spinlocks, and no code asks for memory with these locks
diff -druN linux-2.6.39-libre/Documentation/x86/x86_64/boot-options.txt linux-3.0-rc7-libre/Documentation/x86/x86_64/boot-options.txt
--- linux-2.6.39-libre/Documentation/x86/x86_64/boot-options.txt	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/Documentation/x86/x86_64/boot-options.txt	2011-07-11 19:51:52.000000000 -0400
@@ -206,7 +206,7 @@
       (e.g. because you have < 3 GB memory).
       Kernel boot message: "PCI-DMA: Disabling IOMMU"
 
-   2. <arch/x86_64/kernel/pci-gart.c>: AMD GART based hardware IOMMU.
+   2. <arch/x86/kernel/amd_gart_64.c>: AMD GART based hardware IOMMU.
       Kernel boot message: "PCI-DMA: using GART IOMMU"
 
    3. <arch/x86_64/kernel/pci-swiotlb.c> : Software IOMMU implementation. Used
diff -druN linux-2.6.39-libre/Documentation/zh_CN/email-clients.txt linux-3.0-rc7-libre/Documentation/zh_CN/email-clients.txt
--- linux-2.6.39-libre/Documentation/zh_CN/email-clients.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/Documentation/zh_CN/email-clients.txt	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,210 @@
+锘?Chinese translated version of Documentation/email-clients.txt
+
+If you have any comment or update to the content, please contact the
+original document maintainer directly.  However, if you have a problem
+communicating in English you can also ask the Chinese maintainer for
+help.  Contact the Chinese maintainer if this translation is outdated
+or if there is a problem with the translation.
+
+Chinese maintainer: Harry Wei <harryxiyou@gmail.com>
+---------------------------------------------------------------------
+Documentation/email-clients.txt ???涓????缈昏??
+
+濡??????宠??璁烘????存?版???????????瀹癸??璇风?存?ヨ??绯诲?????妗ｇ??缁存?よ?????濡????浣?浣跨?ㄨ?辨??
+浜ゆ???????伴?剧??璇?锛?涔????浠ュ??涓???????缁存?よ??姹???┿??濡???????缈昏????存?颁???????舵?????缈?
+璇?瀛???ㄩ??棰?锛?璇疯??绯讳腑??????缁存?よ?????
+
+涓???????缁存?よ??锛? 璐惧??濞?  Harry Wei <harryxiyou@gmail.com>
+涓???????缈昏?????锛? 璐惧??濞?  Harry Wei <harryxiyou@gmail.com>
+涓?????????¤?????锛? Yinglin Luan <synmyth@gmail.com>
+		Xiaochen Wang <wangxiaochen0@gmail.com>
+		yaxinsn <yaxinsn@163.com>
+
+浠ヤ??涓烘?ｆ??
+---------------------------------------------------------------------
+
+Linux???浠跺?㈡?风?????缃?淇℃??
+======================================================================
+
+?????????缃?
+----------------------------------------------------------------------
+Linux?????歌ˉ涓???????杩????浠惰?????浜ょ??锛????濂芥??琛ヤ??浣?涓洪??浠朵????????宓?????????????浜?缁存?よ??
+??ユ?堕??浠讹??浣???????浠剁?????瀹规?煎??搴?璇ユ??"text/plain"?????惰??锛????浠朵????????涓?璧???????锛?
+???涓鸿??浼?浣胯ˉ涓????寮???ㄩ?ㄥ????ㄨ??璁鸿??绋?涓???????寰???伴?俱??
+
+??ㄦ?ュ?????Linux?????歌ˉ涓???????浠跺?㈡?风????ㄥ?????琛ヤ????跺??璇ュ??浜?????????????濮???舵?????渚?濡?锛?
+浠?浠?涓???芥?瑰?????????????ゅ?惰〃绗???????绌烘?硷???????虫????ㄦ??涓?琛????寮?澶存?????缁?灏俱??
+
+涓?瑕????杩?"format=flowed"妯″????????琛ヤ?????杩???蜂??寮?璧蜂?????棰????浠ュ?????瀹崇?????琛????
+
+涓?瑕?璁╀????????浠跺?㈡?风??杩?琛??????ㄦ?㈣?????杩???蜂??浼???村??浣????琛ヤ?????
+
+???浠跺?㈡?风??涓???芥?瑰???????????瀛?绗????缂??????瑰?????瑕??????????琛ヤ???????芥??ASCII??????UTF-8缂??????瑰??锛?
+濡????浣?浣跨??UTF-8缂??????瑰???????????浠讹????ｄ??浣?灏?浼???垮??涓?浜??????藉????????瀛?绗???????棰????
+
+???浠跺?㈡?风??搴?璇ュ舰???骞朵??淇???? References: ?????? In-Reply-To: ???棰?锛???ｄ??
+???浠惰??棰?灏变??浼?涓???????
+
+澶???剁??甯?(?????????璐寸??甯?)???甯镐????界?ㄤ??琛ヤ??锛????涓哄?惰〃绗?浼?杞????涓虹┖??笺??浣跨??xclipboard, xclip
+??????xcutsel涔?璁稿??浠ワ??浣???????濂芥??璇?涓?涓?????????垮??浣跨?ㄥ????剁??甯????
+
+涓?瑕???ㄤ娇???PGP/GPG缃插????????浠朵腑??????琛ヤ?????杩???蜂??浣垮??寰?澶???????涓???借?诲??????????ㄤ??浣????琛ヤ?????
+锛?杩?涓????棰?搴?璇ユ?????浠ヤ慨澶????锛?
+
+??ㄧ???????搁??浠跺??琛ㄥ?????琛ヤ??涔????锛?缁????宸卞?????涓?涓?琛ヤ?????涓?涓???????涓绘??锛?淇?瀛???ユ?跺?扮??
+???浠讹??灏?琛ヤ?????'patch'??戒护???涓?锛?濡??????????浜?锛????缁??????搁??浠跺??琛ㄥ????????
+
+
+涓?浜????浠跺?㈡?风?????绀?
+----------------------------------------------------------------------
+杩????缁???轰??浜?璇?缁????MUA???缃????绀猴?????浠ョ?ㄤ??缁?Linux?????稿?????琛ヤ?????杩?浜?骞朵???????虫??
+?????????杞?浠跺?????缃???荤?????
+
+璇存??锛?
+TUI = 浠ユ?????涓哄?虹???????ㄦ?锋?ュ??
+GUI = ??惧舰?????㈢?ㄦ?锋?ュ??
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Alpine (TUI)
+
+???缃????椤癸??
+???"Sending Preferences"??ㄥ??锛?
+
+- "Do Not Send Flowed Text"蹇?椤诲?????
+- "Strip Whitespace Before Sending"蹇?椤诲?抽??
+
+褰???????浠舵?讹????????搴?璇ユ?惧?ㄨˉ涓?浼???虹?扮????版?癸????跺?????涓?CTRL-R缁???????锛?浣挎??瀹????
+琛ヤ?????浠跺????ュ?伴??浠朵腑???
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Evolution (GUI)
+
+涓?浜?寮????????????????浣跨?ㄥ????????琛ヤ??
+
+褰??????╅??浠堕??椤癸??Preformat
+  浠?Format->Heading->Preformatted (Ctrl-7)??????宸ュ?锋??
+
+??跺??浣跨??锛?
+  Insert->Text File... (Alt-n x)?????ヨˉ涓????浠躲??
+
+浣?杩????浠?"diff -Nru old.c new.c | xclip"锛???????Preformat锛???跺??浣跨?ㄤ腑??撮??杩?琛?绮?甯????
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Kmail (GUI)
+
+涓?浜?寮????????????????浣跨?ㄥ????????琛ヤ?????
+
+榛?璁よ?剧疆涓?涓?HTML??煎??????????????锛?涓?瑕??????ㄥ?????
+
+褰?涔????涓?灏????浠剁????跺??锛???ㄩ??椤逛?????涓?瑕??????╄????ㄦ?㈣????????涓????缂虹?瑰氨???浣???ㄩ??浠朵腑杈???ョ??浠讳????????
+??戒??浼?琚??????ㄦ?㈣??锛????姝や??蹇?椤诲?ㄥ?????琛ヤ??涔?????????ㄦ?㈣????????绠?????????规??灏辨???????ㄨ????ㄦ?㈣????ヤ功??????浠讹??
+??跺?????瀹?淇?瀛?涓鸿??绋裤??涓????浣???ㄨ??绋夸腑???娆℃??寮?瀹?锛?瀹?宸茬????ㄩ?ㄨ????ㄦ?㈣??浜?锛???ｄ??浣???????浠惰?界?舵病???
+?????╄????ㄦ?㈣??锛?浣????杩?涓?浼?澶卞?诲凡???????????ㄦ?㈣?????
+
+??ㄩ??浠剁??搴????锛??????ヨˉ涓?涔????锛???句??甯哥?ㄧ??琛ヤ??瀹????绗?锛?涓?涓?杩?瀛????(---)???
+
+??跺?????"Message"????????＄??锛??????╂????ユ??浠讹????ョ????????浣????琛ヤ?????浠躲??杩????涓?涓?棰?澶???????椤癸??浣????浠?
+???杩?瀹????缃?浣???????浠跺缓绔?宸ュ?锋????????锛?杩????浠ュ甫涓?"insert file"??炬?????
+
+浣????浠ュ????ㄥ?伴??杩?GPG???璁伴??浠讹??浣???????宓?琛ヤ?????濂戒??瑕?浣跨??GPG???璁板??浠????浣?涓哄??宓??????????绛惧??琛ヤ??锛?
+褰?浠?GPG涓???????7浣?缂??????朵??浣夸??浠?????????村??澶???????
+
+濡????浣????瑕?浠ラ??浠剁??褰㈠????????琛ヤ??锛???ｄ??灏卞?抽????瑰?婚??浠讹????跺?????涓?灞???э??绐????"Suggest automatic
+display"锛?杩???峰??宓????浠舵?村?规??璁╄?昏???????般??
+
+褰?浣?瑕?淇?瀛?灏?瑕?????????????宓???????琛ヤ??锛?浣????浠ヤ??娑???????琛ㄧ????奸????╁?????琛ヤ????????浠讹????跺????冲?婚?????
+"save as"???浣????浠ヤ娇??ㄤ??涓?娌℃????存?圭????????琛ヤ????????浠讹??濡????瀹????浠ユ?ｇ‘???褰㈠??缁???????褰?浣?姝ｇ????ㄥ??
+???宸辩??绐???ｄ??涓?瀵????锛???ｆ?舵病??????椤瑰??浠ヤ??瀛????浠?--宸茬?????涓?涓?杩???风??bug琚?姹???ュ?颁??kmail???bugzilla
+骞朵??甯????杩?灏?浼?琚?澶??????????浠舵??浠ュ?????瀵规??涓???ㄦ?峰??璇诲???????????琚?淇?瀛????锛????浠ュ?????浣???虫?????浠跺????跺?板?朵????版?癸??
+浣?涓?寰?涓????浠?浠????????????逛负缁?????????翠?????璇汇??
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Lotus Notes (GUI)
+
+涓?瑕?浣跨?ㄥ?????
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Mutt (TUI)
+
+寰?澶?Linux寮????浜哄??浣跨??mutt瀹㈡?风??锛????浠ヨ?????瀹????瀹?宸ヤ????????甯告??浜????
+
+Mutt涓????甯?缂?杈????锛????浠ヤ??绠′??浣跨?ㄤ??涔?缂?杈???ㄩ?戒??搴?璇ュ甫????????ㄦ??琛????澶у????扮??杈???ㄩ?藉甫???
+涓?涓?"insert file"???椤癸??瀹????浠ラ??杩?涓???瑰?????浠跺??瀹圭????瑰???????ユ??浠躲??
+
+'vim'浣?涓?mutt???缂?杈????锛?
+  set editor="vi"
+
+  濡????浣跨??xclip锛???插?ヤ互涓???戒护
+  :set paste
+  ???涓????涔??????????shift-insert??????浣跨??
+  :r filename
+
+濡??????宠?????琛ヤ??浣?涓哄??宓??????????
+(a)ttach宸ヤ?????寰?濂斤??涓?甯????"set paste"???
+
+???缃????椤癸??
+瀹?搴?璇ヤ互榛?璁よ?剧疆???褰㈠??宸ヤ?????
+??惰??锛????"send_charset"璁剧疆涓?"us-ascii::utf-8"涔????涓?涓?涓???????涓绘?????
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Pine (TUI)
+
+Pine杩???绘??涓?浜?绌烘?煎????????棰?锛?浣????杩?浜???板?ㄥ??璇ラ?借??淇?澶?浜????
+
+濡???????浠ワ??璇蜂娇???alpine(pine???缁ф?胯??)
+
+???缃????椤癸??
+- ???杩?????????????瑕?娑???ゆ??绋???????
+- "no-strip-whitespace-before-send"???椤逛????????瑕???????
+
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Sylpheed (GUI)
+
+- ???宓??????????浠ュ??濂界??宸ヤ??锛???????浣跨?ㄩ??浠讹?????
+- ???璁镐娇??ㄥ????ㄧ??缂?杈???ㄣ??
+- 瀵逛?????褰?杈?澶???堕??甯告?????
+- 濡???????杩?non-SSL杩???ワ?????娉?浣跨??TLS SMTP?????????
+- ??ㄧ?????绐???ｄ腑???涓?涓?寰??????ㄧ??ruler bar???
+- 缁???板?????涓?娣诲????板??灏变??浼?姝ｇ‘???浜?瑙ｆ?剧ず??????
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Thunderbird (GUI)
+
+榛?璁ゆ????典??锛?thunderbird寰?瀹规??????????????锛?浣????杩????涓?浜???规?????浠ュ己??跺?????寰???村ソ???
+
+- ??ㄧ?ㄦ?峰????疯?剧疆???锛?缁???????瀵诲??锛?涓?瑕???????"Compose messages in HTML format"???
+
+- 缂?杈?浣????Thunderbird???缃?璁剧疆??ヤ娇瀹?涓?瑕????琛?浣跨??锛?user_pref("mailnews.wraplength", 0);
+
+- 缂?杈?浣????Thunderbird???缃?璁剧疆锛?浣垮??涓?瑕?浣跨??"format=flowed"??煎??锛?user_pref("mailnews.
+  send_plaintext_flowed", false);
+
+- 浣????瑕?浣?Thunderbird???涓洪???????煎????瑰??锛?
+  濡????榛?璁ゆ????典??浣?涔??????????HTML??煎??锛???ｄ?????寰???俱??浠?浠?浠????棰???????涓????妗?涓???????"Preformat"??煎?????
+  濡????榛?璁ゆ????典??浣?涔??????????????????煎??锛?浣?涓?寰????瀹???逛负HTML??煎??锛?浠?浠?浣?涓轰??娆℃?х??锛???ヤ功?????扮??娑????锛?
+  ??跺??寮哄?朵娇瀹??????版???????煎??锛???????瀹?灏变?????琛????瑕?瀹???板??锛???ㄥ??淇＄????炬??涓?浣跨??shift?????ヤ娇瀹????涓?HTML
+  ??煎??锛???跺?????棰???????涓????妗?涓???????"Preformat"??煎?????
+
+- ???璁镐娇??ㄥ????ㄧ??缂?杈????锛?
+  ???瀵?Thunderbird???琛ヤ?????绠?????????规??灏辨??浣跨?ㄤ??涓?"external editor"??╁??锛???跺??浣跨?ㄤ????????娆㈢??
+  $EDITOR??ヨ?诲???????????骞惰ˉ涓???版?????涓????瑕?瀹???板??锛????浠ヤ??杞藉苟涓?瀹?瑁?杩?涓???╁??锛???跺??娣诲??涓?涓?浣跨?ㄥ?????
+  ??????View->Toolbars->Customize...??????褰?浣?涔????淇℃???????跺??浠?浠???瑰?诲??灏卞??浠ヤ?????
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+TkRat (GUI)
+
+???浠ヤ娇??ㄥ?????浣跨??"Insert file..."??????澶???ㄧ??缂?杈???ㄣ??
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Gmail (Web GUI)
+
+涓?瑕?浣跨?ㄥ????????琛ヤ?????
+
+Gmail缃?椤靛?㈡?风???????ㄥ?版????惰〃绗?杞????涓虹┖??笺??
+
+??界?跺?惰〃绗?杞????涓虹┖??奸??棰????浠ヨ??澶???ㄧ??杈???ㄨВ??筹???????跺??杩?浼?浣跨?ㄥ??杞???㈣?????姣?琛???????涓?78涓?瀛?绗????
+
+???涓?涓????棰????Gmail杩?浼????浠讳??涓????ASCII???瀛?绗????淇℃????逛负base64缂???????瀹????涓?瑗垮????????娆ф床浜虹?????瀛????
+
+                                ###
diff -druN linux-2.6.39-libre/drivers/acpi/acpica/acconfig.h linux-3.0-rc7-libre/drivers/acpi/acpica/acconfig.h
--- linux-2.6.39-libre/drivers/acpi/acpica/acconfig.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/acpi/acpica/acconfig.h	2011-07-11 19:51:52.000000000 -0400
@@ -187,7 +187,6 @@
 
 /* Operation regions */
 
-#define ACPI_NUM_PREDEFINED_REGIONS     9
 #define ACPI_USER_REGION_BEGIN          0x80
 
 /* Maximum space_ids for Operation Regions */
diff -druN linux-2.6.39-libre/drivers/acpi/acpica/acevents.h linux-3.0-rc7-libre/drivers/acpi/acpica/acevents.h
--- linux-2.6.39-libre/drivers/acpi/acpica/acevents.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/acpi/acpica/acevents.h	2011-07-11 19:51:52.000000000 -0400
@@ -58,12 +58,6 @@
  */
 u8 acpi_ev_is_notify_object(struct acpi_namespace_node *node);
 
-acpi_status acpi_ev_acquire_global_lock(u16 timeout);
-
-acpi_status acpi_ev_release_global_lock(void);
-
-acpi_status acpi_ev_init_global_lock_handler(void);
-
 u32 acpi_ev_get_gpe_number_index(u32 gpe_number);
 
 acpi_status
@@ -71,6 +65,17 @@
 			     u32 notify_value);
 
 /*
+ * evglock - Global Lock support
+ */
+acpi_status acpi_ev_init_global_lock_handler(void);
+
+acpi_status acpi_ev_acquire_global_lock(u16 timeout);
+
+acpi_status acpi_ev_release_global_lock(void);
+
+acpi_status acpi_ev_remove_global_lock_handler(void);
+
+/*
  * evgpe - Low-level GPE support
  */
 u32 acpi_ev_gpe_detect(struct acpi_gpe_xrupt_info *gpe_xrupt_list);
diff -druN linux-2.6.39-libre/drivers/acpi/acpica/acglobal.h linux-3.0-rc7-libre/drivers/acpi/acpica/acglobal.h
--- linux-2.6.39-libre/drivers/acpi/acpica/acglobal.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/acpi/acpica/acglobal.h	2011-07-11 19:51:52.000000000 -0400
@@ -214,24 +214,23 @@
 
 /*
  * Global lock mutex is an actual AML mutex object
- * Global lock semaphore works in conjunction with the HW global lock
+ * Global lock semaphore works in conjunction with the actual global lock
+ * Global lock spinlock is used for "pending" handshake
  */
 ACPI_EXTERN union acpi_operand_object *acpi_gbl_global_lock_mutex;
 ACPI_EXTERN acpi_semaphore acpi_gbl_global_lock_semaphore;
+ACPI_EXTERN acpi_spinlock acpi_gbl_global_lock_pending_lock;
 ACPI_EXTERN u16 acpi_gbl_global_lock_handle;
 ACPI_EXTERN u8 acpi_gbl_global_lock_acquired;
 ACPI_EXTERN u8 acpi_gbl_global_lock_present;
+ACPI_EXTERN u8 acpi_gbl_global_lock_pending;
 
 /*
  * Spinlocks are used for interfaces that can be possibly called at
  * interrupt level
  */
-ACPI_EXTERN spinlock_t _acpi_gbl_gpe_lock;	/* For GPE data structs and registers */
-ACPI_EXTERN spinlock_t _acpi_gbl_hardware_lock;	/* For ACPI H/W except GPE registers */
-ACPI_EXTERN spinlock_t _acpi_ev_global_lock_pending_lock; /* For global lock */
-#define acpi_gbl_gpe_lock	&_acpi_gbl_gpe_lock
-#define acpi_gbl_hardware_lock	&_acpi_gbl_hardware_lock
-#define acpi_ev_global_lock_pending_lock &_acpi_ev_global_lock_pending_lock
+ACPI_EXTERN acpi_spinlock acpi_gbl_gpe_lock;	/* For GPE data structs and registers */
+ACPI_EXTERN acpi_spinlock acpi_gbl_hardware_lock;	/* For ACPI H/W except GPE registers */
 
 /*****************************************************************************
  *
diff -druN linux-2.6.39-libre/drivers/acpi/acpica/amlcode.h linux-3.0-rc7-libre/drivers/acpi/acpica/amlcode.h
--- linux-2.6.39-libre/drivers/acpi/acpica/amlcode.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/acpi/acpica/amlcode.h	2011-07-11 19:51:52.000000000 -0400
@@ -394,21 +394,6 @@
 #define AML_CLASS_METHOD_CALL       0x09
 #define AML_CLASS_UNKNOWN           0x0A
 
-/* Predefined Operation Region space_iDs */
-
-typedef enum {
-	REGION_MEMORY = 0,
-	REGION_IO,
-	REGION_PCI_CONFIG,
-	REGION_EC,
-	REGION_SMBUS,
-	REGION_CMOS,
-	REGION_PCI_BAR,
-	REGION_IPMI,
-	REGION_DATA_TABLE,	/* Internal use only */
-	REGION_FIXED_HW = 0x7F
-} AML_REGION_TYPES;
-
 /* Comparison operation codes for match_op operator */
 
 typedef enum {
diff -druN linux-2.6.39-libre/drivers/acpi/acpica/dswload2.c linux-3.0-rc7-libre/drivers/acpi/acpica/dswload2.c
--- linux-2.6.39-libre/drivers/acpi/acpica/dswload2.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/acpi/acpica/dswload2.c	2011-07-11 19:51:52.000000000 -0400
@@ -562,7 +562,7 @@
 				    ((op->common.value.arg)->common.value.
 				     integer);
 			} else {
-				region_space = REGION_DATA_TABLE;
+				region_space = ACPI_ADR_SPACE_DATA_TABLE;
 			}
 
 			/*
diff -druN linux-2.6.39-libre/drivers/acpi/acpica/dswload.c linux-3.0-rc7-libre/drivers/acpi/acpica/dswload.c
--- linux-2.6.39-libre/drivers/acpi/acpica/dswload.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/acpi/acpica/dswload.c	2011-07-11 19:51:52.000000000 -0400
@@ -450,7 +450,7 @@
 			status =
 			    acpi_ex_create_region(op->named.data,
 						  op->named.length,
-						  REGION_DATA_TABLE,
+						  ACPI_ADR_SPACE_DATA_TABLE,
 						  walk_state);
 			if (ACPI_FAILURE(status)) {
 				return_ACPI_STATUS(status);
diff -druN linux-2.6.39-libre/drivers/acpi/acpica/evglock.c linux-3.0-rc7-libre/drivers/acpi/acpica/evglock.c
--- linux-2.6.39-libre/drivers/acpi/acpica/evglock.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/acpi/acpica/evglock.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,335 @@
+/******************************************************************************
+ *
+ * Module Name: evglock - Global Lock support
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2011, Intel Corp.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions, and the following disclaimer,
+ *    without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ *    substantially similar to the "NO WARRANTY" disclaimer below
+ *    ("Disclaimer") and any redistribution must be conditioned upon
+ *    including a substantially similar Disclaimer requirement for further
+ *    binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ *    of any contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ */
+
+#include <acpi/acpi.h>
+#include "accommon.h"
+#include "acevents.h"
+#include "acinterp.h"
+
+#define _COMPONENT          ACPI_EVENTS
+ACPI_MODULE_NAME("evglock")
+
+/* Local prototypes */
+static u32 acpi_ev_global_lock_handler(void *context);
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ev_init_global_lock_handler
+ *
+ * PARAMETERS:  None
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Install a handler for the global lock release event
+ *
+ ******************************************************************************/
+
+acpi_status acpi_ev_init_global_lock_handler(void)
+{
+	acpi_status status;
+
+	ACPI_FUNCTION_TRACE(ev_init_global_lock_handler);
+
+	/* Attempt installation of the global lock handler */
+
+	status = acpi_install_fixed_event_handler(ACPI_EVENT_GLOBAL,
+						  acpi_ev_global_lock_handler,
+						  NULL);
+
+	/*
+	 * If the global lock does not exist on this platform, the attempt to
+	 * enable GBL_STATUS will fail (the GBL_ENABLE bit will not stick).
+	 * Map to AE_OK, but mark global lock as not present. Any attempt to
+	 * actually use the global lock will be flagged with an error.
+	 */
+	acpi_gbl_global_lock_present = FALSE;
+	if (status == AE_NO_HARDWARE_RESPONSE) {
+		ACPI_ERROR((AE_INFO,
+			    "No response from Global Lock hardware, disabling lock"));
+
+		return_ACPI_STATUS(AE_OK);
+	}
+
+	status = acpi_os_create_lock(&acpi_gbl_global_lock_pending_lock);
+	if (ACPI_FAILURE(status)) {
+		return_ACPI_STATUS(status);
+	}
+
+	acpi_gbl_global_lock_pending = FALSE;
+	acpi_gbl_global_lock_present = TRUE;
+	return_ACPI_STATUS(status);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ev_remove_global_lock_handler
+ *
+ * PARAMETERS:  None
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Remove the handler for the Global Lock
+ *
+ ******************************************************************************/
+
+acpi_status acpi_ev_remove_global_lock_handler(void)
+{
+	acpi_status status;
+
+	ACPI_FUNCTION_TRACE(ev_remove_global_lock_handler);
+
+	acpi_gbl_global_lock_present = FALSE;
+	status = acpi_remove_fixed_event_handler(ACPI_EVENT_GLOBAL,
+						 acpi_ev_global_lock_handler);
+
+	return_ACPI_STATUS(status);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ev_global_lock_handler
+ *
+ * PARAMETERS:  Context         - From thread interface, not used
+ *
+ * RETURN:      ACPI_INTERRUPT_HANDLED
+ *
+ * DESCRIPTION: Invoked directly from the SCI handler when a global lock
+ *              release interrupt occurs. If there is actually a pending
+ *              request for the lock, signal the waiting thread.
+ *
+ ******************************************************************************/
+
+static u32 acpi_ev_global_lock_handler(void *context)
+{
+	acpi_status status;
+	acpi_cpu_flags flags;
+
+	flags = acpi_os_acquire_lock(acpi_gbl_global_lock_pending_lock);
+
+	/*
+	 * If a request for the global lock is not actually pending,
+	 * we are done. This handles "spurious" global lock interrupts
+	 * which are possible (and have been seen) with bad BIOSs.
+	 */
+	if (!acpi_gbl_global_lock_pending) {
+		goto cleanup_and_exit;
+	}
+
+	/*
+	 * Send a unit to the global lock semaphore. The actual acquisition
+	 * of the global lock will be performed by the waiting thread.
+	 */
+	status = acpi_os_signal_semaphore(acpi_gbl_global_lock_semaphore, 1);
+	if (ACPI_FAILURE(status)) {
+		ACPI_ERROR((AE_INFO, "Could not signal Global Lock semaphore"));
+	}
+
+	acpi_gbl_global_lock_pending = FALSE;
+
+      cleanup_and_exit:
+
+	acpi_os_release_lock(acpi_gbl_global_lock_pending_lock, flags);
+	return (ACPI_INTERRUPT_HANDLED);
+}
+
+/******************************************************************************
+ *
+ * FUNCTION:    acpi_ev_acquire_global_lock
+ *
+ * PARAMETERS:  Timeout         - Max time to wait for the lock, in millisec.
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Attempt to gain ownership of the Global Lock.
+ *
+ * MUTEX:       Interpreter must be locked
+ *
+ * Note: The original implementation allowed multiple threads to "acquire" the
+ * Global Lock, and the OS would hold the lock until the last thread had
+ * released it. However, this could potentially starve the BIOS out of the
+ * lock, especially in the case where there is a tight handshake between the
+ * Embedded Controller driver and the BIOS. Therefore, this implementation
+ * allows only one thread to acquire the HW Global Lock at a time, and makes
+ * the global lock appear as a standard mutex on the OS side.
+ *
+ *****************************************************************************/
+
+acpi_status acpi_ev_acquire_global_lock(u16 timeout)
+{
+	acpi_cpu_flags flags;
+	acpi_status status;
+	u8 acquired = FALSE;
+
+	ACPI_FUNCTION_TRACE(ev_acquire_global_lock);
+
+	/*
+	 * Only one thread can acquire the GL at a time, the global_lock_mutex
+	 * enforces this. This interface releases the interpreter if we must wait.
+	 */
+	status =
+	    acpi_ex_system_wait_mutex(acpi_gbl_global_lock_mutex->mutex.
+				      os_mutex, timeout);
+	if (ACPI_FAILURE(status)) {
+		return_ACPI_STATUS(status);
+	}
+
+	/*
+	 * Update the global lock handle and check for wraparound. The handle is
+	 * only used for the external global lock interfaces, but it is updated
+	 * here to properly handle the case where a single thread may acquire the
+	 * lock via both the AML and the acpi_acquire_global_lock interfaces. The
+	 * handle is therefore updated on the first acquire from a given thread
+	 * regardless of where the acquisition request originated.
+	 */
+	acpi_gbl_global_lock_handle++;
+	if (acpi_gbl_global_lock_handle == 0) {
+		acpi_gbl_global_lock_handle = 1;
+	}
+
+	/*
+	 * Make sure that a global lock actually exists. If not, just
+	 * treat the lock as a standard mutex.
+	 */
+	if (!acpi_gbl_global_lock_present) {
+		acpi_gbl_global_lock_acquired = TRUE;
+		return_ACPI_STATUS(AE_OK);
+	}
+
+	flags = acpi_os_acquire_lock(acpi_gbl_global_lock_pending_lock);
+
+	do {
+
+		/* Attempt to acquire the actual hardware lock */
+
+		ACPI_ACQUIRE_GLOBAL_LOCK(acpi_gbl_FACS, acquired);
+		if (acquired) {
+			acpi_gbl_global_lock_acquired = TRUE;
+			ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
+					  "Acquired hardware Global Lock\n"));
+			break;
+		}
+
+		/*
+		 * Did not get the lock. The pending bit was set above, and
+		 * we must now wait until we receive the global lock
+		 * released interrupt.
+		 */
+		acpi_gbl_global_lock_pending = TRUE;
+		acpi_os_release_lock(acpi_gbl_global_lock_pending_lock, flags);
+
+		ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
+				  "Waiting for hardware Global Lock\n"));
+
+		/*
+		 * Wait for handshake with the global lock interrupt handler.
+		 * This interface releases the interpreter if we must wait.
+		 */
+		status =
+		    acpi_ex_system_wait_semaphore
+		    (acpi_gbl_global_lock_semaphore, ACPI_WAIT_FOREVER);
+
+		flags = acpi_os_acquire_lock(acpi_gbl_global_lock_pending_lock);
+
+	} while (ACPI_SUCCESS(status));
+
+	acpi_gbl_global_lock_pending = FALSE;
+	acpi_os_release_lock(acpi_gbl_global_lock_pending_lock, flags);
+
+	return_ACPI_STATUS(status);
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ev_release_global_lock
+ *
+ * PARAMETERS:  None
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Releases ownership of the Global Lock.
+ *
+ ******************************************************************************/
+
+acpi_status acpi_ev_release_global_lock(void)
+{
+	u8 pending = FALSE;
+	acpi_status status = AE_OK;
+
+	ACPI_FUNCTION_TRACE(ev_release_global_lock);
+
+	/* Lock must be already acquired */
+
+	if (!acpi_gbl_global_lock_acquired) {
+		ACPI_WARNING((AE_INFO,
+			      "Cannot release the ACPI Global Lock, it has not been acquired"));
+		return_ACPI_STATUS(AE_NOT_ACQUIRED);
+	}
+
+	if (acpi_gbl_global_lock_present) {
+
+		/* Allow any thread to release the lock */
+
+		ACPI_RELEASE_GLOBAL_LOCK(acpi_gbl_FACS, pending);
+
+		/*
+		 * If the pending bit was set, we must write GBL_RLS to the control
+		 * register
+		 */
+		if (pending) {
+			status =
+			    acpi_write_bit_register
+			    (ACPI_BITREG_GLOBAL_LOCK_RELEASE,
+			     ACPI_ENABLE_EVENT);
+		}
+
+		ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
+				  "Released hardware Global Lock\n"));
+	}
+
+	acpi_gbl_global_lock_acquired = FALSE;
+
+	/* Release the local GL mutex */
+
+	acpi_os_release_mutex(acpi_gbl_global_lock_mutex->mutex.os_mutex);
+	return_ACPI_STATUS(status);
+}
diff -druN linux-2.6.39-libre/drivers/acpi/acpica/evmisc.c linux-3.0-rc7-libre/drivers/acpi/acpica/evmisc.c
--- linux-2.6.39-libre/drivers/acpi/acpica/evmisc.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/acpi/acpica/evmisc.c	2011-07-11 19:51:52.000000000 -0400
@@ -45,7 +45,6 @@
 #include "accommon.h"
 #include "acevents.h"
 #include "acnamesp.h"
-#include "acinterp.h"
 
 #define _COMPONENT          ACPI_EVENTS
 ACPI_MODULE_NAME("evmisc")
@@ -53,10 +52,6 @@
 /* Local prototypes */
 static void ACPI_SYSTEM_XFACE acpi_ev_notify_dispatch(void *context);
 
-static u32 acpi_ev_global_lock_handler(void *context);
-
-static acpi_status acpi_ev_remove_global_lock_handler(void);
-
 /*******************************************************************************
  *
  * FUNCTION:    acpi_ev_is_notify_object
@@ -275,304 +270,6 @@
 	acpi_ut_delete_generic_state(notify_info);
 }
 
-/*******************************************************************************
- *
- * FUNCTION:    acpi_ev_global_lock_handler
- *
- * PARAMETERS:  Context         - From thread interface, not used
- *
- * RETURN:      ACPI_INTERRUPT_HANDLED
- *
- * DESCRIPTION: Invoked directly from the SCI handler when a global lock
- *              release interrupt occurs.  If there's a thread waiting for
- *              the global lock, signal it.
- *
- * NOTE: Assumes that the semaphore can be signaled from interrupt level. If
- * this is not possible for some reason, a separate thread will have to be
- * scheduled to do this.
- *
- ******************************************************************************/
-static u8 acpi_ev_global_lock_pending;
-
-static u32 acpi_ev_global_lock_handler(void *context)
-{
-	acpi_status status;
-	acpi_cpu_flags flags;
-
-	flags = acpi_os_acquire_lock(acpi_ev_global_lock_pending_lock);
-
-	if (!acpi_ev_global_lock_pending) {
-		goto out;
-	}
-
-	/* Send a unit to the semaphore */
-
-	status = acpi_os_signal_semaphore(acpi_gbl_global_lock_semaphore, 1);
-	if (ACPI_FAILURE(status)) {
-		ACPI_ERROR((AE_INFO, "Could not signal Global Lock semaphore"));
-	}
-
-	acpi_ev_global_lock_pending = FALSE;
-
- out:
-	acpi_os_release_lock(acpi_ev_global_lock_pending_lock, flags);
-
-	return (ACPI_INTERRUPT_HANDLED);
-}
-
-/*******************************************************************************
- *
- * FUNCTION:    acpi_ev_init_global_lock_handler
- *
- * PARAMETERS:  None
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Install a handler for the global lock release event
- *
- ******************************************************************************/
-
-acpi_status acpi_ev_init_global_lock_handler(void)
-{
-	acpi_status status;
-
-	ACPI_FUNCTION_TRACE(ev_init_global_lock_handler);
-
-	/* Attempt installation of the global lock handler */
-
-	status = acpi_install_fixed_event_handler(ACPI_EVENT_GLOBAL,
-						  acpi_ev_global_lock_handler,
-						  NULL);
-
-	/*
-	 * If the global lock does not exist on this platform, the attempt to
-	 * enable GBL_STATUS will fail (the GBL_ENABLE bit will not stick).
-	 * Map to AE_OK, but mark global lock as not present. Any attempt to
-	 * actually use the global lock will be flagged with an error.
-	 */
-	if (status == AE_NO_HARDWARE_RESPONSE) {
-		ACPI_ERROR((AE_INFO,
-			    "No response from Global Lock hardware, disabling lock"));
-
-		acpi_gbl_global_lock_present = FALSE;
-		return_ACPI_STATUS(AE_OK);
-	}
-
-	acpi_gbl_global_lock_present = TRUE;
-	return_ACPI_STATUS(status);
-}
-
-/*******************************************************************************
- *
- * FUNCTION:    acpi_ev_remove_global_lock_handler
- *
- * PARAMETERS:  None
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Remove the handler for the Global Lock
- *
- ******************************************************************************/
-
-static acpi_status acpi_ev_remove_global_lock_handler(void)
-{
-	acpi_status status;
-
-	ACPI_FUNCTION_TRACE(ev_remove_global_lock_handler);
-
-	acpi_gbl_global_lock_present = FALSE;
-	status = acpi_remove_fixed_event_handler(ACPI_EVENT_GLOBAL,
-						 acpi_ev_global_lock_handler);
-
-	return_ACPI_STATUS(status);
-}
-
-/******************************************************************************
- *
- * FUNCTION:    acpi_ev_acquire_global_lock
- *
- * PARAMETERS:  Timeout         - Max time to wait for the lock, in millisec.
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Attempt to gain ownership of the Global Lock.
- *
- * MUTEX:       Interpreter must be locked
- *
- * Note: The original implementation allowed multiple threads to "acquire" the
- * Global Lock, and the OS would hold the lock until the last thread had
- * released it. However, this could potentially starve the BIOS out of the
- * lock, especially in the case where there is a tight handshake between the
- * Embedded Controller driver and the BIOS. Therefore, this implementation
- * allows only one thread to acquire the HW Global Lock at a time, and makes
- * the global lock appear as a standard mutex on the OS side.
- *
- *****************************************************************************/
-static acpi_thread_id acpi_ev_global_lock_thread_id;
-static int acpi_ev_global_lock_acquired;
-
-acpi_status acpi_ev_acquire_global_lock(u16 timeout)
-{
-	acpi_cpu_flags flags;
-	acpi_status status = AE_OK;
-	u8 acquired = FALSE;
-
-	ACPI_FUNCTION_TRACE(ev_acquire_global_lock);
-
-	/*
-	 * Only one thread can acquire the GL at a time, the global_lock_mutex
-	 * enforces this. This interface releases the interpreter if we must wait.
-	 */
-	status = acpi_ex_system_wait_mutex(
-			acpi_gbl_global_lock_mutex->mutex.os_mutex, 0);
-	if (status == AE_TIME) {
-		if (acpi_ev_global_lock_thread_id == acpi_os_get_thread_id()) {
-			acpi_ev_global_lock_acquired++;
-			return AE_OK;
-		}
-	}
-
-	if (ACPI_FAILURE(status)) {
-		status = acpi_ex_system_wait_mutex(
-				acpi_gbl_global_lock_mutex->mutex.os_mutex,
-				timeout);
-	}
-	if (ACPI_FAILURE(status)) {
-		return_ACPI_STATUS(status);
-	}
-
-	acpi_ev_global_lock_thread_id = acpi_os_get_thread_id();
-	acpi_ev_global_lock_acquired++;
-
-	/*
-	 * Update the global lock handle and check for wraparound. The handle is
-	 * only used for the external global lock interfaces, but it is updated
-	 * here to properly handle the case where a single thread may acquire the
-	 * lock via both the AML and the acpi_acquire_global_lock interfaces. The
-	 * handle is therefore updated on the first acquire from a given thread
-	 * regardless of where the acquisition request originated.
-	 */
-	acpi_gbl_global_lock_handle++;
-	if (acpi_gbl_global_lock_handle == 0) {
-		acpi_gbl_global_lock_handle = 1;
-	}
-
-	/*
-	 * Make sure that a global lock actually exists. If not, just treat the
-	 * lock as a standard mutex.
-	 */
-	if (!acpi_gbl_global_lock_present) {
-		acpi_gbl_global_lock_acquired = TRUE;
-		return_ACPI_STATUS(AE_OK);
-	}
-
-	flags = acpi_os_acquire_lock(acpi_ev_global_lock_pending_lock);
-
-	do {
-
-		/* Attempt to acquire the actual hardware lock */
-
-		ACPI_ACQUIRE_GLOBAL_LOCK(acpi_gbl_FACS, acquired);
-		if (acquired) {
-			acpi_gbl_global_lock_acquired = TRUE;
-
-			ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
-					  "Acquired hardware Global Lock\n"));
-			break;
-		}
-
-		acpi_ev_global_lock_pending = TRUE;
-
-		acpi_os_release_lock(acpi_ev_global_lock_pending_lock, flags);
-
-		/*
-		 * Did not get the lock. The pending bit was set above, and we
-		 * must wait until we get the global lock released interrupt.
-		 */
-		ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
-				  "Waiting for hardware Global Lock\n"));
-
-		/*
-		 * Wait for handshake with the global lock interrupt handler.
-		 * This interface releases the interpreter if we must wait.
-		 */
-		status = acpi_ex_system_wait_semaphore(
-						acpi_gbl_global_lock_semaphore,
-						ACPI_WAIT_FOREVER);
-
-		flags = acpi_os_acquire_lock(acpi_ev_global_lock_pending_lock);
-
-	} while (ACPI_SUCCESS(status));
-
-	acpi_ev_global_lock_pending = FALSE;
-
-	acpi_os_release_lock(acpi_ev_global_lock_pending_lock, flags);
-
-	return_ACPI_STATUS(status);
-}
-
-/*******************************************************************************
- *
- * FUNCTION:    acpi_ev_release_global_lock
- *
- * PARAMETERS:  None
- *
- * RETURN:      Status
- *
- * DESCRIPTION: Releases ownership of the Global Lock.
- *
- ******************************************************************************/
-
-acpi_status acpi_ev_release_global_lock(void)
-{
-	u8 pending = FALSE;
-	acpi_status status = AE_OK;
-
-	ACPI_FUNCTION_TRACE(ev_release_global_lock);
-
-	/* Lock must be already acquired */
-
-	if (!acpi_gbl_global_lock_acquired) {
-		ACPI_WARNING((AE_INFO,
-			      "Cannot release the ACPI Global Lock, it has not been acquired"));
-		return_ACPI_STATUS(AE_NOT_ACQUIRED);
-	}
-
-	acpi_ev_global_lock_acquired--;
-	if (acpi_ev_global_lock_acquired > 0) {
-		return AE_OK;
-	}
-
-	if (acpi_gbl_global_lock_present) {
-
-		/* Allow any thread to release the lock */
-
-		ACPI_RELEASE_GLOBAL_LOCK(acpi_gbl_FACS, pending);
-
-		/*
-		 * If the pending bit was set, we must write GBL_RLS to the control
-		 * register
-		 */
-		if (pending) {
-			status =
-			    acpi_write_bit_register
-			    (ACPI_BITREG_GLOBAL_LOCK_RELEASE,
-			     ACPI_ENABLE_EVENT);
-		}
-
-		ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
-				  "Released hardware Global Lock\n"));
-	}
-
-	acpi_gbl_global_lock_acquired = FALSE;
-
-	/* Release the local GL mutex */
-	acpi_ev_global_lock_thread_id = 0;
-	acpi_ev_global_lock_acquired = 0;
-	acpi_os_release_mutex(acpi_gbl_global_lock_mutex->mutex.os_mutex);
-	return_ACPI_STATUS(status);
-}
-
 /******************************************************************************
  *
  * FUNCTION:    acpi_ev_terminate
diff -druN linux-2.6.39-libre/drivers/acpi/acpica/evregion.c linux-3.0-rc7-libre/drivers/acpi/acpica/evregion.c
--- linux-2.6.39-libre/drivers/acpi/acpica/evregion.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/acpi/acpica/evregion.c	2011-07-11 19:51:52.000000000 -0400
@@ -55,6 +55,8 @@
 acpi_ev_has_default_handler(struct acpi_namespace_node *node,
 			    acpi_adr_space_type space_id);
 
+static void acpi_ev_orphan_ec_reg_method(void);
+
 static acpi_status
 acpi_ev_reg_run(acpi_handle obj_handle,
 		u32 level, void *context, void **return_value);
@@ -561,7 +563,9 @@
 
 			/* Now stop region accesses by executing the _REG method */
 
-			status = acpi_ev_execute_reg_method(region_obj, 0);
+			status =
+			    acpi_ev_execute_reg_method(region_obj,
+						       ACPI_REG_DISCONNECT);
 			if (ACPI_FAILURE(status)) {
 				ACPI_EXCEPTION((AE_INFO, status,
 						"from region _REG, [%s]",
@@ -1062,6 +1066,12 @@
 					ACPI_NS_WALK_UNLOCK, acpi_ev_reg_run,
 					NULL, &space_id, NULL);
 
+	/* Special case for EC: handle "orphan" _REG methods with no region */
+
+	if (space_id == ACPI_ADR_SPACE_EC) {
+		acpi_ev_orphan_ec_reg_method();
+	}
+
 	return_ACPI_STATUS(status);
 }
 
@@ -1120,6 +1130,113 @@
 		return (AE_OK);
 	}
 
-	status = acpi_ev_execute_reg_method(obj_desc, 1);
+	status = acpi_ev_execute_reg_method(obj_desc, ACPI_REG_CONNECT);
 	return (status);
 }
+
+/*******************************************************************************
+ *
+ * FUNCTION:    acpi_ev_orphan_ec_reg_method
+ *
+ * PARAMETERS:  None
+ *
+ * RETURN:      None
+ *
+ * DESCRIPTION: Execute an "orphan" _REG method that appears under the EC
+ *              device. This is a _REG method that has no corresponding region
+ *              within the EC device scope. The orphan _REG method appears to
+ *              have been enabled by the description of the ECDT in the ACPI
+ *              specification: "The availability of the region space can be
+ *              detected by providing a _REG method object underneath the
+ *              Embedded Controller device."
+ *
+ *              To quickly access the EC device, we use the EC_ID that appears
+ *              within the ECDT. Otherwise, we would need to perform a time-
+ *              consuming namespace walk, executing _HID methods to find the
+ *              EC device.
+ *
+ ******************************************************************************/
+
+static void acpi_ev_orphan_ec_reg_method(void)
+{
+	struct acpi_table_ecdt *table;
+	acpi_status status;
+	struct acpi_object_list args;
+	union acpi_object objects[2];
+	struct acpi_namespace_node *ec_device_node;
+	struct acpi_namespace_node *reg_method;
+	struct acpi_namespace_node *next_node;
+
+	ACPI_FUNCTION_TRACE(ev_orphan_ec_reg_method);
+
+	/* Get the ECDT (if present in system) */
+
+	status = acpi_get_table(ACPI_SIG_ECDT, 0,
+				ACPI_CAST_INDIRECT_PTR(struct acpi_table_header,
+						       &table));
+	if (ACPI_FAILURE(status)) {
+		return_VOID;
+	}
+
+	/* We need a valid EC_ID string */
+
+	if (!(*table->id)) {
+		return_VOID;
+	}
+
+	/* Namespace is currently locked, must release */
+
+	(void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
+
+	/* Get a handle to the EC device referenced in the ECDT */
+
+	status = acpi_get_handle(NULL,
+				 ACPI_CAST_PTR(char, table->id),
+				 ACPI_CAST_PTR(acpi_handle, &ec_device_node));
+	if (ACPI_FAILURE(status)) {
+		goto exit;
+	}
+
+	/* Get a handle to a _REG method immediately under the EC device */
+
+	status = acpi_get_handle(ec_device_node,
+				 METHOD_NAME__REG, ACPI_CAST_PTR(acpi_handle,
+								 &reg_method));
+	if (ACPI_FAILURE(status)) {
+		goto exit;
+	}
+
+	/*
+	 * Execute the _REG method only if there is no Operation Region in
+	 * this scope with the Embedded Controller space ID. Otherwise, it
+	 * will already have been executed. Note, this allows for Regions
+	 * with other space IDs to be present; but the code below will then
+	 * execute the _REG method with the EC space ID argument.
+	 */
+	next_node = acpi_ns_get_next_node(ec_device_node, NULL);
+	while (next_node) {
+		if ((next_node->type == ACPI_TYPE_REGION) &&
+		    (next_node->object) &&
+		    (next_node->object->region.space_id == ACPI_ADR_SPACE_EC)) {
+			goto exit;	/* Do not execute _REG */
+		}
+		next_node = acpi_ns_get_next_node(ec_device_node, next_node);
+	}
+
+	/* Evaluate the _REG(EC,Connect) method */
+
+	args.count = 2;
+	args.pointer = objects;
+	objects[0].type = ACPI_TYPE_INTEGER;
+	objects[0].integer.value = ACPI_ADR_SPACE_EC;
+	objects[1].type = ACPI_TYPE_INTEGER;
+	objects[1].integer.value = ACPI_REG_CONNECT;
+
+	status = acpi_evaluate_object(reg_method, NULL, &args, NULL);
+
+      exit:
+	/* We ignore all errors from above, don't care */
+
+	status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
+	return_VOID;
+}
diff -druN linux-2.6.39-libre/drivers/acpi/acpica/evrgnini.c linux-3.0-rc7-libre/drivers/acpi/acpica/evrgnini.c
--- linux-2.6.39-libre/drivers/acpi/acpica/evrgnini.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/acpi/acpica/evrgnini.c	2011-07-11 19:51:52.000000000 -0400
@@ -637,7 +637,7 @@
 
 					status =
 					    acpi_ev_execute_reg_method
-					    (region_obj, 1);
+					    (region_obj, ACPI_REG_CONNECT);
 
 					if (acpi_ns_locked) {
 						status =
diff -druN linux-2.6.39-libre/drivers/acpi/acpica/evxfregn.c linux-3.0-rc7-libre/drivers/acpi/acpica/evxfregn.c
--- linux-2.6.39-libre/drivers/acpi/acpica/evxfregn.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/acpi/acpica/evxfregn.c	2011-07-11 19:51:52.000000000 -0400
@@ -130,20 +130,21 @@
 	case ACPI_ADR_SPACE_PCI_CONFIG:
 	case ACPI_ADR_SPACE_DATA_TABLE:
 
-		if (acpi_gbl_reg_methods_executed) {
-
-			/* Run all _REG methods for this address space */
+		if (!acpi_gbl_reg_methods_executed) {
 
-			status = acpi_ev_execute_reg_methods(node, space_id);
+			/* We will defer execution of the _REG methods for this space */
+			goto unlock_and_exit;
 		}
 		break;
 
 	default:
-
-		status = acpi_ev_execute_reg_methods(node, space_id);
 		break;
 	}
 
+	/* Run all _REG methods for this address space */
+
+	status = acpi_ev_execute_reg_methods(node, space_id);
+
       unlock_and_exit:
 	(void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
 	return_ACPI_STATUS(status);
diff -druN linux-2.6.39-libre/drivers/acpi/acpica/excreate.c linux-3.0-rc7-libre/drivers/acpi/acpica/excreate.c
--- linux-2.6.39-libre/drivers/acpi/acpica/excreate.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/acpi/acpica/excreate.c	2011-07-11 19:51:52.000000000 -0400
@@ -305,7 +305,8 @@
 	 * range
 	 */
 	if ((region_space >= ACPI_NUM_PREDEFINED_REGIONS) &&
-	    (region_space < ACPI_USER_REGION_BEGIN)) {
+	    (region_space < ACPI_USER_REGION_BEGIN) &&
+	    (region_space != ACPI_ADR_SPACE_DATA_TABLE)) {
 		ACPI_ERROR((AE_INFO, "Invalid AddressSpace type 0x%X",
 			    region_space));
 		return_ACPI_STATUS(AE_AML_INVALID_SPACE_ID);
diff -druN linux-2.6.39-libre/drivers/acpi/acpica/Makefile linux-3.0-rc7-libre/drivers/acpi/acpica/Makefile
--- linux-2.6.39-libre/drivers/acpi/acpica/Makefile	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/acpi/acpica/Makefile	2011-07-11 19:51:52.000000000 -0400
@@ -14,7 +14,7 @@
 
 acpi-y += evevent.o  evregion.o  evsci.o    evxfevnt.o \
 	 evmisc.o   evrgnini.o  evxface.o  evxfregn.o \
-	 evgpe.o    evgpeblk.o evgpeinit.o  evgpeutil.o evxfgpe.o
+	 evgpe.o    evgpeblk.o evgpeinit.o  evgpeutil.o evxfgpe.o evglock.o
 
 acpi-y += exconfig.o  exfield.o  exnames.o   exoparg6.o  exresolv.o  exstorob.o\
 	 exconvrt.o  exfldio.o  exoparg1.o  exprep.o    exresop.o   exsystem.o\
diff -druN linux-2.6.39-libre/drivers/acpi/acpica/nsrepair.c linux-3.0-rc7-libre/drivers/acpi/acpica/nsrepair.c
--- linux-2.6.39-libre/drivers/acpi/acpica/nsrepair.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/acpi/acpica/nsrepair.c	2011-07-11 19:51:52.000000000 -0400
@@ -74,7 +74,6 @@
  *
  * 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
  *
@@ -623,16 +622,12 @@
 	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.
+	 * We can safely remove all NULL elements from these package types:
+	 * PTYPE1_VAR packages contain a variable number of simple data types.
+	 * PTYPE2 packages contain a variable number of sub-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:
@@ -642,6 +637,8 @@
 		break;
 
 	default:
+	case ACPI_PTYPE1_FIXED:
+	case ACPI_PTYPE1_OPTION:
 		return;
 	}
 
diff -druN linux-2.6.39-libre/drivers/acpi/acpica/utdecode.c linux-3.0-rc7-libre/drivers/acpi/acpica/utdecode.c
--- linux-2.6.39-libre/drivers/acpi/acpica/utdecode.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/acpi/acpica/utdecode.c	2011-07-11 19:51:52.000000000 -0400
@@ -170,8 +170,7 @@
 	"SMBus",
 	"SystemCMOS",
 	"PCIBARTarget",
-	"IPMI",
-	"DataTable"
+	"IPMI"
 };
 
 char *acpi_ut_get_region_name(u8 space_id)
@@ -179,6 +178,8 @@
 
 	if (space_id >= ACPI_USER_REGION_BEGIN) {
 		return ("UserDefinedRegion");
+	} else if (space_id == ACPI_ADR_SPACE_DATA_TABLE) {
+		return ("DataTable");
 	} else if (space_id == ACPI_ADR_SPACE_FIXED_HARDWARE) {
 		return ("FunctionalFixedHW");
 	} else if (space_id >= ACPI_NUM_PREDEFINED_REGIONS) {
diff -druN linux-2.6.39-libre/drivers/acpi/acpica/utmutex.c linux-3.0-rc7-libre/drivers/acpi/acpica/utmutex.c
--- linux-2.6.39-libre/drivers/acpi/acpica/utmutex.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/acpi/acpica/utmutex.c	2011-07-11 19:51:52.000000000 -0400
@@ -83,9 +83,15 @@
 
 	/* Create the spinlocks for use at interrupt level */
 
-	spin_lock_init(acpi_gbl_gpe_lock);
-	spin_lock_init(acpi_gbl_hardware_lock);
-	spin_lock_init(acpi_ev_global_lock_pending_lock);
+	status = acpi_os_create_lock (&acpi_gbl_gpe_lock);
+	if (ACPI_FAILURE (status)) {
+		return_ACPI_STATUS (status);
+	}
+
+	status = acpi_os_create_lock (&acpi_gbl_hardware_lock);
+	if (ACPI_FAILURE (status)) {
+		return_ACPI_STATUS (status);
+	}
 
 	/* Mutex for _OSI support */
 	status = acpi_os_create_mutex(&acpi_gbl_osi_mutex);
diff -druN linux-2.6.39-libre/drivers/acpi/acpica/utresrc.c linux-3.0-rc7-libre/drivers/acpi/acpica/utresrc.c
--- linux-2.6.39-libre/drivers/acpi/acpica/utresrc.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/acpi/acpica/utresrc.c	2011-07-11 19:51:52.000000000 -0400
@@ -50,7 +50,7 @@
 #if defined(ACPI_DISASSEMBLER) || defined (ACPI_DEBUGGER)
 /*
  * Strings used to decode resource descriptors.
- * Used by both the disasssembler and the debugger resource dump routines
+ * Used by both the disassembler and the debugger resource dump routines
  */
 const char *acpi_gbl_bm_decode[] = {
 	"NotBusMaster",
diff -druN linux-2.6.39-libre/drivers/acpi/apei/einj.c linux-3.0-rc7-libre/drivers/acpi/apei/einj.c
--- linux-2.6.39-libre/drivers/acpi/apei/einj.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/acpi/apei/einj.c	2011-07-11 19:51:52.000000000 -0400
@@ -101,6 +101,14 @@
 
 static struct einj_parameter *einj_param;
 
+#ifndef writeq
+static inline void writeq(__u64 val, volatile void __iomem *addr)
+{
+	writel(val, addr);
+	writel(val >> 32, addr+4);
+}
+#endif
+
 static void einj_exec_ctx_init(struct apei_exec_context *ctx)
 {
 	apei_exec_ctx_init(ctx, einj_ins_type, ARRAY_SIZE(einj_ins_type),
diff -druN linux-2.6.39-libre/drivers/acpi/apei/erst.c linux-3.0-rc7-libre/drivers/acpi/apei/erst.c
--- linux-2.6.39-libre/drivers/acpi/apei/erst.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/acpi/apei/erst.c	2011-07-11 19:51:52.000000000 -0400
@@ -929,13 +929,17 @@
 	return 0;
 }
 
-static size_t erst_reader(u64 *id, enum pstore_type_id *type,
+static int erst_open_pstore(struct pstore_info *psi);
+static int erst_close_pstore(struct pstore_info *psi);
+static ssize_t erst_reader(u64 *id, enum pstore_type_id *type,
 		       struct timespec *time);
 static u64 erst_writer(enum pstore_type_id type, size_t size);
 
 static struct pstore_info erst_info = {
 	.owner		= THIS_MODULE,
 	.name		= "erst",
+	.open		= erst_open_pstore,
+	.close		= erst_close_pstore,
 	.read		= erst_reader,
 	.write		= erst_writer,
 	.erase		= erst_clear
@@ -957,12 +961,32 @@
 	char data[];
 } __packed;
 
-static size_t erst_reader(u64 *id, enum pstore_type_id *type,
+static int reader_pos;
+
+static int erst_open_pstore(struct pstore_info *psi)
+{
+	int rc;
+
+	if (erst_disable)
+		return -ENODEV;
+
+	rc = erst_get_record_id_begin(&reader_pos);
+
+	return rc;
+}
+
+static int erst_close_pstore(struct pstore_info *psi)
+{
+	erst_get_record_id_end();
+
+	return 0;
+}
+
+static ssize_t erst_reader(u64 *id, enum pstore_type_id *type,
 		       struct timespec *time)
 {
 	int rc;
-	ssize_t len;
-	unsigned long flags;
+	ssize_t len = 0;
 	u64 record_id;
 	struct cper_pstore_record *rcd = (struct cper_pstore_record *)
 					(erst_info.buf - sizeof(*rcd));
@@ -970,24 +994,28 @@
 	if (erst_disable)
 		return -ENODEV;
 
-	raw_spin_lock_irqsave(&erst_lock, flags);
 skip:
-	rc = __erst_get_next_record_id(&record_id);
-	if (rc) {
-		raw_spin_unlock_irqrestore(&erst_lock, flags);
-		return rc;
-	}
+	rc = erst_get_record_id_next(&reader_pos, &record_id);
+	if (rc)
+		goto out;
+
 	/* no more record */
 	if (record_id == APEI_ERST_INVALID_RECORD_ID) {
-		raw_spin_unlock_irqrestore(&erst_lock, flags);
-		return 0;
+		rc = -1;
+		goto out;
 	}
 
-	len = __erst_read(record_id, &rcd->hdr, sizeof(*rcd) +
-			  erst_erange.size);
+	len = erst_read(record_id, &rcd->hdr, sizeof(*rcd) +
+			erst_info.bufsize);
+	/* The record may be cleared by others, try read next record */
+	if (len == -ENOENT)
+		goto skip;
+	else if (len < 0) {
+		rc = -1;
+		goto out;
+	}
 	if (uuid_le_cmp(rcd->hdr.creator_id, CPER_CREATOR_PSTORE) != 0)
 		goto skip;
-	raw_spin_unlock_irqrestore(&erst_lock, flags);
 
 	*id = record_id;
 	if (uuid_le_cmp(rcd->sec_hdr.section_type,
@@ -1005,7 +1033,8 @@
 		time->tv_sec = 0;
 	time->tv_nsec = 0;
 
-	return len - sizeof(*rcd);
+out:
+	return (rc < 0) ? rc : (len - sizeof(*rcd));
 }
 
 static u64 erst_writer(enum pstore_type_id type, size_t size)
diff -druN linux-2.6.39-libre/drivers/acpi/apei/Kconfig linux-3.0-rc7-libre/drivers/acpi/apei/Kconfig
--- linux-2.6.39-libre/drivers/acpi/apei/Kconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/acpi/apei/Kconfig	2011-07-11 19:51:52.000000000 -0400
@@ -1,5 +1,6 @@
 config ACPI_APEI
 	bool "ACPI Platform Error Interface (APEI)"
+	select MISC_FILESYSTEMS
 	select PSTORE
 	depends on X86
 	help
diff -druN linux-2.6.39-libre/drivers/acpi/atomicio.c linux-3.0-rc7-libre/drivers/acpi/atomicio.c
--- linux-2.6.39-libre/drivers/acpi/atomicio.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/acpi/atomicio.c	2011-07-11 19:51:52.000000000 -0400
@@ -280,9 +280,11 @@
 	case 32:
 		*val = readl(addr);
 		break;
+#ifdef readq
 	case 64:
 		*val = readq(addr);
 		break;
+#endif
 	default:
 		return -EINVAL;
 	}
@@ -307,9 +309,11 @@
 	case 32:
 		writel(val, addr);
 		break;
+#ifdef writeq
 	case 64:
 		writeq(val, addr);
 		break;
+#endif
 	default:
 		return -EINVAL;
 	}
diff -druN linux-2.6.39-libre/drivers/acpi/bus.c linux-3.0-rc7-libre/drivers/acpi/bus.c
--- linux-2.6.39-libre/drivers/acpi/bus.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/acpi/bus.c	2011-07-11 19:51:52.000000000 -0400
@@ -227,7 +227,7 @@
 	acpi_status status = AE_OK;
 	char object_name[5] = { '_', 'P', 'S', '0' + state, '\0' };
 
-	if (!device || (state < ACPI_STATE_D0) || (state > ACPI_STATE_D3))
+	if (!device || (state < ACPI_STATE_D0) || (state > ACPI_STATE_D3_COLD))
 		return -EINVAL;
 
 	/* Make sure this is a valid target state */
diff -druN linux-2.6.39-libre/drivers/acpi/custom_method.c linux-3.0-rc7-libre/drivers/acpi/custom_method.c
--- linux-2.6.39-libre/drivers/acpi/custom_method.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/acpi/custom_method.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,100 @@
+/*
+ * debugfs.c - ACPI debugfs interface to userspace.
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/uaccess.h>
+#include <linux/debugfs.h>
+#include <acpi/acpi_drivers.h>
+
+#include "internal.h"
+
+#define _COMPONENT		ACPI_SYSTEM_COMPONENT
+ACPI_MODULE_NAME("custom_method");
+MODULE_LICENSE("GPL");
+
+static struct dentry *cm_dentry;
+
+/* /sys/kernel/debug/acpi/custom_method */
+
+static ssize_t cm_write(struct file *file, const char __user * user_buf,
+			size_t count, loff_t *ppos)
+{
+	static char *buf;
+	static u32 max_size;
+	static u32 uncopied_bytes;
+
+	struct acpi_table_header table;
+	acpi_status status;
+
+	if (!(*ppos)) {
+		/* parse the table header to get the table length */
+		if (count <= sizeof(struct acpi_table_header))
+			return -EINVAL;
+		if (copy_from_user(&table, user_buf,
+				   sizeof(struct acpi_table_header)))
+			return -EFAULT;
+		uncopied_bytes = max_size = table.length;
+		buf = kzalloc(max_size, GFP_KERNEL);
+		if (!buf)
+			return -ENOMEM;
+	}
+
+	if (buf == NULL)
+		return -EINVAL;
+
+	if ((*ppos > max_size) ||
+	    (*ppos + count > max_size) ||
+	    (*ppos + count < count) ||
+	    (count > uncopied_bytes))
+		return -EINVAL;
+
+	if (copy_from_user(buf + (*ppos), user_buf, count)) {
+		kfree(buf);
+		buf = NULL;
+		return -EFAULT;
+	}
+
+	uncopied_bytes -= count;
+	*ppos += count;
+
+	if (!uncopied_bytes) {
+		status = acpi_install_method(buf);
+		kfree(buf);
+		buf = NULL;
+		if (ACPI_FAILURE(status))
+			return -EINVAL;
+		add_taint(TAINT_OVERRIDDEN_ACPI_TABLE);
+	}
+
+	return count;
+}
+
+static const struct file_operations cm_fops = {
+	.write = cm_write,
+	.llseek = default_llseek,
+};
+
+static int __init acpi_custom_method_init(void)
+{
+	if (acpi_debugfs_dir == NULL)
+		return -ENOENT;
+
+	cm_dentry = debugfs_create_file("custom_method", S_IWUSR,
+					acpi_debugfs_dir, NULL, &cm_fops);
+	if (cm_dentry == NULL)
+		return -ENODEV;
+
+	return 0;
+}
+
+static void __exit acpi_custom_method_exit(void)
+{
+	if (cm_dentry)
+		debugfs_remove(cm_dentry);
+ }
+
+module_init(acpi_custom_method_init);
+module_exit(acpi_custom_method_exit);
diff -druN linux-2.6.39-libre/drivers/acpi/debugfs.c linux-3.0-rc7-libre/drivers/acpi/debugfs.c
--- linux-2.6.39-libre/drivers/acpi/debugfs.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/acpi/debugfs.c	2011-07-11 19:51:52.000000000 -0400
@@ -3,100 +3,16 @@
  */
 
 #include <linux/init.h>
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/uaccess.h>
 #include <linux/debugfs.h>
 #include <acpi/acpi_drivers.h>
 
 #define _COMPONENT		ACPI_SYSTEM_COMPONENT
 ACPI_MODULE_NAME("debugfs");
 
+struct dentry *acpi_debugfs_dir;
+EXPORT_SYMBOL_GPL(acpi_debugfs_dir);
 
-/* /sys/modules/acpi/parameters/aml_debug_output */
-
-module_param_named(aml_debug_output, acpi_gbl_enable_aml_debug_object,
-		   bool, 0644);
-MODULE_PARM_DESC(aml_debug_output,
-		 "To enable/disable the ACPI Debug Object output.");
-
-/* /sys/kernel/debug/acpi/custom_method */
-
-static ssize_t cm_write(struct file *file, const char __user * user_buf,
-			size_t count, loff_t *ppos)
-{
-	static char *buf;
-	static u32 max_size;
-	static u32 uncopied_bytes;
-
-	struct acpi_table_header table;
-	acpi_status status;
-
-	if (!(*ppos)) {
-		/* parse the table header to get the table length */
-		if (count <= sizeof(struct acpi_table_header))
-			return -EINVAL;
-		if (copy_from_user(&table, user_buf,
-				   sizeof(struct acpi_table_header)))
-			return -EFAULT;
-		uncopied_bytes = max_size = table.length;
-		buf = kzalloc(max_size, GFP_KERNEL);
-		if (!buf)
-			return -ENOMEM;
-	}
-
-	if (buf == NULL)
-		return -EINVAL;
-
-	if ((*ppos > max_size) ||
-	    (*ppos + count > max_size) ||
-	    (*ppos + count < count) ||
-	    (count > uncopied_bytes))
-		return -EINVAL;
-
-	if (copy_from_user(buf + (*ppos), user_buf, count)) {
-		kfree(buf);
-		buf = NULL;
-		return -EFAULT;
-	}
-
-	uncopied_bytes -= count;
-	*ppos += count;
-
-	if (!uncopied_bytes) {
-		status = acpi_install_method(buf);
-		kfree(buf);
-		buf = NULL;
-		if (ACPI_FAILURE(status))
-			return -EINVAL;
-		add_taint(TAINT_OVERRIDDEN_ACPI_TABLE);
-	}
-
-	return count;
-}
-
-static const struct file_operations cm_fops = {
-	.write = cm_write,
-	.llseek = default_llseek,
-};
-
-int __init acpi_debugfs_init(void)
+void __init acpi_debugfs_init(void)
 {
-	struct dentry *acpi_dir, *cm_dentry;
-
-	acpi_dir = debugfs_create_dir("acpi", NULL);
-	if (!acpi_dir)
-		goto err;
-
-	cm_dentry = debugfs_create_file("custom_method", S_IWUSR,
-					acpi_dir, NULL, &cm_fops);
-	if (!cm_dentry)
-		goto err;
-
-	return 0;
-
-err:
-	if (acpi_dir)
-		debugfs_remove(acpi_dir);
-	return -EINVAL;
+	acpi_debugfs_dir = debugfs_create_dir("acpi", NULL);
 }
diff -druN linux-2.6.39-libre/drivers/acpi/ec.c linux-3.0-rc7-libre/drivers/acpi/ec.c
--- linux-2.6.39-libre/drivers/acpi/ec.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/acpi/ec.c	2011-07-11 19:51:52.000000000 -0400
@@ -69,7 +69,6 @@
 
 #define ACPI_EC_DELAY		500	/* Wait 500ms max. during EC ops */
 #define ACPI_EC_UDELAY_GLK	1000	/* Wait 1ms max. to get global lock */
-#define ACPI_EC_CDELAY		10	/* Wait 10us before polling EC */
 #define ACPI_EC_MSI_UDELAY	550	/* Wait 550us for MSI EC */
 
 #define ACPI_EC_STORM_THRESHOLD 8	/* number of false interrupts
@@ -433,8 +432,7 @@
 
 int ec_transaction(u8 command,
 		   const u8 * wdata, unsigned wdata_len,
-		   u8 * rdata, unsigned rdata_len,
-		   int force_poll)
+		   u8 * rdata, unsigned rdata_len)
 {
 	struct transaction t = {.command = command,
 				.wdata = wdata, .rdata = rdata,
@@ -592,8 +590,6 @@
 	mutex_unlock(&ec->lock);
 }
 
-static void acpi_ec_gpe_query(void *ec_cxt);
-
 static int ec_check_sci(struct acpi_ec *ec, u8 state)
 {
 	if (state & ACPI_EC_FLAG_SCI) {
@@ -808,8 +804,6 @@
 			return -EINVAL;
 	}
 
-	ec->handle = device->handle;
-
 	/* Find and register all query methods */
 	acpi_walk_namespace(ACPI_TYPE_METHOD, ec->handle, 1,
 			    acpi_ec_register_query_methods, NULL, ec, NULL);
@@ -938,8 +932,19 @@
 	ec_flag_msi, "MSI hardware", {
 	DMI_MATCH(DMI_CHASSIS_VENDOR, "MICRO-STAR")}, NULL},
 	{
+	ec_flag_msi, "Quanta hardware", {
+	DMI_MATCH(DMI_SYS_VENDOR, "Quanta"),
+	DMI_MATCH(DMI_PRODUCT_NAME, "TW8/SW8/DW8"),}, NULL},
+	{
+	ec_flag_msi, "Quanta hardware", {
+	DMI_MATCH(DMI_SYS_VENDOR, "Quanta"),
+	DMI_MATCH(DMI_PRODUCT_NAME, "TW9/SW9"),}, NULL},
+	{
 	ec_validate_ecdt, "ASUS hardware", {
 	DMI_MATCH(DMI_BIOS_VENDOR, "ASUS") }, NULL},
+	{
+	ec_validate_ecdt, "ASUS hardware", {
+	DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer Inc.") }, NULL},
 	{},
 };
 
diff -druN linux-2.6.39-libre/drivers/acpi/internal.h linux-3.0-rc7-libre/drivers/acpi/internal.h
--- linux-2.6.39-libre/drivers/acpi/internal.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/acpi/internal.h	2011-07-11 19:51:52.000000000 -0400
@@ -28,9 +28,10 @@
 int acpi_sysfs_init(void);
 
 #ifdef CONFIG_DEBUG_FS
+extern struct dentry *acpi_debugfs_dir;
 int acpi_debugfs_init(void);
 #else
-static inline int acpi_debugfs_init(void) { return 0; }
+static inline void acpi_debugfs_init(void) { return; }
 #endif
 
 /* --------------------------------------------------------------------------
diff -druN linux-2.6.39-libre/drivers/acpi/Kconfig linux-3.0-rc7-libre/drivers/acpi/Kconfig
--- linux-2.6.39-libre/drivers/acpi/Kconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/acpi/Kconfig	2011-07-11 19:51:52.000000000 -0400
@@ -73,17 +73,6 @@
 
 	  Say N to delete power /proc/acpi/ directories that have moved to /sys/
 
-config ACPI_POWER_METER
-	tristate "ACPI 4.0 power meter"
-	depends on HWMON
-	help
-	  This driver exposes ACPI 4.0 power meters as hardware monitoring
-	  devices.  Say Y (or M) if you have a computer with ACPI 4.0 firmware
-	  and a power meter.
-
-	  To compile this driver as a module, choose M here:
-	  the module will be called power-meter.
-
 config ACPI_EC_DEBUGFS
 	tristate "EC read/write access through /sys/kernel/debug/ec"
 	default n
@@ -380,6 +369,21 @@
 	  which is used to report some hardware errors notified via
 	  SCI, mainly the corrected errors.
 
+config ACPI_CUSTOM_METHOD
+	tristate "Allow ACPI methods to be inserted/replaced at run time"
+	depends on DEBUG_FS
+	default n
+	help
+	  This debug facility allows ACPI AML methods to me inserted and/or
+	  replaced without rebooting the system. For details refer to:
+	  Documentation/acpi/method-customizing.txt.
+
+	  NOTE: This option is security sensitive, because it allows arbitrary
+	  kernel memory to be written to by root (uid=0) users, allowing them
+	  to bypass certain security measures (e.g. if root is not allowed to
+	  load additional kernel modules after boot, this feature may be used
+	  to override that restriction).
+
 source "drivers/acpi/apei/Kconfig"
 
 endif	# ACPI
diff -druN linux-2.6.39-libre/drivers/acpi/Makefile linux-3.0-rc7-libre/drivers/acpi/Makefile
--- linux-2.6.39-libre/drivers/acpi/Makefile	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/acpi/Makefile	2011-07-11 19:51:52.000000000 -0400
@@ -59,9 +59,9 @@
 obj-$(CONFIG_ACPI_BATTERY)	+= battery.o
 obj-$(CONFIG_ACPI_SBS)		+= sbshc.o
 obj-$(CONFIG_ACPI_SBS)		+= sbs.o
-obj-$(CONFIG_ACPI_POWER_METER)	+= power_meter.o
 obj-$(CONFIG_ACPI_HED)		+= hed.o
 obj-$(CONFIG_ACPI_EC_DEBUGFS)	+= ec_sys.o
+obj-$(CONFIG_ACPI_CUSTOM_METHOD)+= custom_method.o
 
 # processor has its own "processor." module_param namespace
 processor-y			:= processor_driver.o processor_throttling.o
diff -druN linux-2.6.39-libre/drivers/acpi/osl.c linux-3.0-rc7-libre/drivers/acpi/osl.c
--- linux-2.6.39-libre/drivers/acpi/osl.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/acpi/osl.c	2011-07-11 19:51:52.000000000 -0400
@@ -902,14 +902,6 @@
 
 EXPORT_SYMBOL(acpi_os_wait_events_complete);
 
-/*
- * Deallocate the memory for a spinlock.
- */
-void acpi_os_delete_lock(acpi_spinlock handle)
-{
-	return;
-}
-
 acpi_status
 acpi_os_create_semaphore(u32 max_units, u32 initial_units, acpi_handle * handle)
 {
@@ -1341,6 +1333,31 @@
 EXPORT_SYMBOL(acpi_resources_are_enforced);
 
 /*
+ * Create and initialize a spinlock.
+ */
+acpi_status
+acpi_os_create_lock(acpi_spinlock *out_handle)
+{
+	spinlock_t *lock;
+
+	lock = ACPI_ALLOCATE(sizeof(spinlock_t));
+	if (!lock)
+		return AE_NO_MEMORY;
+	spin_lock_init(lock);
+	*out_handle = lock;
+
+	return AE_OK;
+}
+
+/*
+ * Deallocate the memory for a spinlock.
+ */
+void acpi_os_delete_lock(acpi_spinlock handle)
+{
+	ACPI_FREE(handle);
+}
+
+/*
  * Acquire a spinlock.
  *
  * handle is a pointer to the spinlock_t.
diff -druN linux-2.6.39-libre/drivers/acpi/pci_root.c linux-3.0-rc7-libre/drivers/acpi/pci_root.c
--- linux-2.6.39-libre/drivers/acpi/pci_root.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/acpi/pci_root.c	2011-07-11 19:51:52.000000000 -0400
@@ -596,12 +596,18 @@
 			dev_info(root->bus->bridge,
 				"ACPI _OSC control (0x%02x) granted\n", flags);
 		} else {
-			dev_dbg(root->bus->bridge,
-				"ACPI _OSC request failed (code %d)\n", status);
-			printk(KERN_INFO "Unable to assume _OSC PCIe control. "
-				"Disabling ASPM\n");
+			dev_info(root->bus->bridge,
+				"ACPI _OSC request failed (%s), "
+				"returned control mask: 0x%02x\n",
+				acpi_format_exception(status), flags);
+			pr_info("ACPI _OSC control for PCIe not granted, "
+				"disabling ASPM\n");
 			pcie_no_aspm();
 		}
+	} else {
+		dev_info(root->bus->bridge,
+			 "Unable to request _OSC control "
+			 "(_OSC support mask: 0x%02x)\n", flags);
 	}
 
 	pci_acpi_add_bus_pm_notifier(device, root->bus);
diff -druN linux-2.6.39-libre/drivers/acpi/power_meter.c linux-3.0-rc7-libre/drivers/acpi/power_meter.c
--- linux-2.6.39-libre/drivers/acpi/power_meter.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/acpi/power_meter.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,1023 +0,0 @@
-/*
- * A hwmon driver for ACPI 4.0 power meters
- * Copyright (C) 2009 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/hwmon.h>
-#include <linux/hwmon-sysfs.h>
-#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>
-#include <acpi/acpi_drivers.h>
-#include <acpi/acpi_bus.h>
-
-#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		"pwr_meter_resource"
-
-#define NUM_SENSORS			17
-
-#define POWER_METER_CAN_MEASURE	(1 << 0)
-#define POWER_METER_CAN_TRIP	(1 << 1)
-#define POWER_METER_CAN_CAP	(1 << 2)
-#define POWER_METER_CAN_NOTIFY	(1 << 3)
-#define POWER_METER_IS_BATTERY	(1 << 8)
-#define UNKNOWN_HYSTERESIS	0xFFFFFFFF
-
-#define METER_NOTIFY_CONFIG	0x80
-#define METER_NOTIFY_TRIP	0x81
-#define METER_NOTIFY_CAP	0x82
-#define METER_NOTIFY_CAPPING	0x83
-#define METER_NOTIFY_INTERVAL	0x84
-
-#define POWER_AVERAGE_NAME	"power1_average"
-#define POWER_CAP_NAME		"power1_cap"
-#define POWER_AVG_INTERVAL_NAME	"power1_average_interval"
-#define POWER_ALARM_NAME	"power1_alarm"
-
-static int cap_in_hardware;
-static int force_cap_on;
-
-static int can_cap_in_hardware(void)
-{
-	return force_cap_on || cap_in_hardware;
-}
-
-static const struct acpi_device_id power_meter_ids[] = {
-	{"ACPI000D", 0},
-	{"", 0},
-};
-MODULE_DEVICE_TABLE(acpi, power_meter_ids);
-
-struct acpi_power_meter_capabilities {
-	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 {
-	struct acpi_device	*acpi_dev;
-	acpi_bus_id		name;
-	struct mutex		lock;
-	struct device		*hwmon_dev;
-	struct acpi_power_meter_capabilities	caps;
-	acpi_string		model_number;
-	acpi_string		serial_number;
-	acpi_string		oem_info;
-	u64		power;
-	u64		cap;
-	u64		avg_interval;
-	int			sensors_valid;
-	unsigned long		sensors_last_updated;
-	struct sensor_device_attribute	sensors[NUM_SENSORS];
-	int			num_sensors;
-	int			trip[2];
-	int			num_domain_devices;
-	struct acpi_device	**domain_devices;
-	struct kobject		*holders_dir;
-};
-
-struct ro_sensor_template {
-	char *label;
-	ssize_t (*show)(struct device *dev,
-			struct device_attribute *devattr,
-			char *buf);
-	int index;
-};
-
-struct rw_sensor_template {
-	char *label;
-	ssize_t (*show)(struct device *dev,
-			struct device_attribute *devattr,
-			char *buf);
-	ssize_t (*set)(struct device *dev,
-		       struct device_attribute *devattr,
-		       const char *buf, size_t count);
-	int index;
-};
-
-/* Averaging interval */
-static int update_avg_interval(struct acpi_power_meter_resource *resource)
-{
-	unsigned long long data;
-	acpi_status status;
-
-	status = acpi_evaluate_integer(resource->acpi_dev->handle, "_GAI",
-				       NULL, &data);
-	if (ACPI_FAILURE(status)) {
-		ACPI_EXCEPTION((AE_INFO, status, "Evaluating _GAI"));
-		return -ENODEV;
-	}
-
-	resource->avg_interval = data;
-	return 0;
-}
-
-static ssize_t show_avg_interval(struct device *dev,
-				 struct device_attribute *devattr,
-				 char *buf)
-{
-	struct acpi_device *acpi_dev = to_acpi_device(dev);
-	struct acpi_power_meter_resource *resource = acpi_dev->driver_data;
-
-	mutex_lock(&resource->lock);
-	update_avg_interval(resource);
-	mutex_unlock(&resource->lock);
-
-	return sprintf(buf, "%llu\n", resource->avg_interval);
-}
-
-static ssize_t set_avg_interval(struct device *dev,
-				struct device_attribute *devattr,
-				const char *buf, size_t count)
-{
-	struct acpi_device *acpi_dev = to_acpi_device(dev);
-	struct acpi_power_meter_resource *resource = acpi_dev->driver_data;
-	union acpi_object arg0 = { ACPI_TYPE_INTEGER };
-	struct acpi_object_list args = { 1, &arg0 };
-	int res;
-	unsigned long temp;
-	unsigned long long data;
-	acpi_status status;
-
-	res = strict_strtoul(buf, 10, &temp);
-	if (res)
-		return res;
-
-	if (temp > resource->caps.max_avg_interval ||
-	    temp < resource->caps.min_avg_interval)
-		return -EINVAL;
-	arg0.integer.value = temp;
-
-	mutex_lock(&resource->lock);
-	status = acpi_evaluate_integer(resource->acpi_dev->handle, "_PAI",
-				       &args, &data);
-	if (!ACPI_FAILURE(status))
-		resource->avg_interval = temp;
-	mutex_unlock(&resource->lock);
-
-	if (ACPI_FAILURE(status)) {
-		ACPI_EXCEPTION((AE_INFO, status, "Evaluating _PAI"));
-		return -EINVAL;
-	}
-
-	/* _PAI returns 0 on success, nonzero otherwise */
-	if (data)
-		return -EINVAL;
-
-	return count;
-}
-
-/* Cap functions */
-static int update_cap(struct acpi_power_meter_resource *resource)
-{
-	unsigned long long data;
-	acpi_status status;
-
-	status = acpi_evaluate_integer(resource->acpi_dev->handle, "_GHL",
-				       NULL, &data);
-	if (ACPI_FAILURE(status)) {
-		ACPI_EXCEPTION((AE_INFO, status, "Evaluating _GHL"));
-		return -ENODEV;
-	}
-
-	resource->cap = data;
-	return 0;
-}
-
-static ssize_t show_cap(struct device *dev,
-			struct device_attribute *devattr,
-			char *buf)
-{
-	struct acpi_device *acpi_dev = to_acpi_device(dev);
-	struct acpi_power_meter_resource *resource = acpi_dev->driver_data;
-
-	mutex_lock(&resource->lock);
-	update_cap(resource);
-	mutex_unlock(&resource->lock);
-
-	return sprintf(buf, "%llu\n", resource->cap * 1000);
-}
-
-static ssize_t set_cap(struct device *dev, struct device_attribute *devattr,
-		       const char *buf, size_t count)
-{
-	struct acpi_device *acpi_dev = to_acpi_device(dev);
-	struct acpi_power_meter_resource *resource = acpi_dev->driver_data;
-	union acpi_object arg0 = { ACPI_TYPE_INTEGER };
-	struct acpi_object_list args = { 1, &arg0 };
-	int res;
-	unsigned long temp;
-	unsigned long long data;
-	acpi_status status;
-
-	res = strict_strtoul(buf, 10, &temp);
-	if (res)
-		return res;
-
-	temp /= 1000;
-	if (temp > resource->caps.max_cap || temp < resource->caps.min_cap)
-		return -EINVAL;
-	arg0.integer.value = temp;
-
-	mutex_lock(&resource->lock);
-	status = acpi_evaluate_integer(resource->acpi_dev->handle, "_SHL",
-				       &args, &data);
-	if (!ACPI_FAILURE(status))
-		resource->cap = temp;
-	mutex_unlock(&resource->lock);
-
-	if (ACPI_FAILURE(status)) {
-		ACPI_EXCEPTION((AE_INFO, status, "Evaluating _SHL"));
-		return -EINVAL;
-	}
-
-	/* _SHL returns 0 on success, nonzero otherwise */
-	if (data)
-		return -EINVAL;
-
-	return count;
-}
-
-/* Power meter trip points */
-static int set_acpi_trip(struct acpi_power_meter_resource *resource)
-{
-	union acpi_object arg_objs[] = {
-		{ACPI_TYPE_INTEGER},
-		{ACPI_TYPE_INTEGER}
-	};
-	struct acpi_object_list args = { 2, arg_objs };
-	unsigned long long data;
-	acpi_status status;
-
-	/* Both trip levels must be set */
-	if (resource->trip[0] < 0 || resource->trip[1] < 0)
-		return 0;
-
-	/* This driver stores min, max; ACPI wants max, min. */
-	arg_objs[0].integer.value = resource->trip[1];
-	arg_objs[1].integer.value = resource->trip[0];
-
-	status = acpi_evaluate_integer(resource->acpi_dev->handle, "_PTP",
-				       &args, &data);
-	if (ACPI_FAILURE(status)) {
-		ACPI_EXCEPTION((AE_INFO, status, "Evaluating _PTP"));
-		return -EINVAL;
-	}
-
-	/* _PTP returns 0 on success, nonzero otherwise */
-	if (data)
-		return -EINVAL;
-
-	return 0;
-}
-
-static ssize_t set_trip(struct device *dev, struct device_attribute *devattr,
-			const char *buf, size_t count)
-{
-	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;
-	int res;
-	unsigned long temp;
-
-	res = strict_strtoul(buf, 10, &temp);
-	if (res)
-		return res;
-
-	temp /= 1000;
-	if (temp < 0)
-		return -EINVAL;
-
-	mutex_lock(&resource->lock);
-	resource->trip[attr->index - 7] = temp;
-	res = set_acpi_trip(resource);
-	mutex_unlock(&resource->lock);
-
-	if (res)
-		return res;
-
-	return count;
-}
-
-/* Power meter */
-static int update_meter(struct acpi_power_meter_resource *resource)
-{
-	unsigned long long data;
-	acpi_status status;
-	unsigned long local_jiffies = jiffies;
-
-	if (time_before(local_jiffies, resource->sensors_last_updated +
-			msecs_to_jiffies(resource->caps.sampling_time)) &&
-			resource->sensors_valid)
-		return 0;
-
-	status = acpi_evaluate_integer(resource->acpi_dev->handle, "_PMM",
-				       NULL, &data);
-	if (ACPI_FAILURE(status)) {
-		ACPI_EXCEPTION((AE_INFO, status, "Evaluating _PMM"));
-		return -ENODEV;
-	}
-
-	resource->power = data;
-	resource->sensors_valid = 1;
-	resource->sensors_last_updated = jiffies;
-	return 0;
-}
-
-static ssize_t show_power(struct device *dev,
-			  struct device_attribute *devattr,
-			  char *buf)
-{
-	struct acpi_device *acpi_dev = to_acpi_device(dev);
-	struct acpi_power_meter_resource *resource = acpi_dev->driver_data;
-
-	mutex_lock(&resource->lock);
-	update_meter(resource);
-	mutex_unlock(&resource->lock);
-
-	return sprintf(buf, "%llu\n", resource->power * 1000);
-}
-
-/* Miscellaneous */
-static ssize_t show_str(struct device *dev,
-			struct device_attribute *devattr,
-			char *buf)
-{
-	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_string val;
-
-	switch (attr->index) {
-	case 0:
-		val = resource->model_number;
-		break;
-	case 1:
-		val = resource->serial_number;
-		break;
-	case 2:
-		val = resource->oem_info;
-		break;
-	default:
-		BUG();
-	}
-
-	return sprintf(buf, "%s\n", val);
-}
-
-static ssize_t show_val(struct device *dev,
-			struct device_attribute *devattr,
-			char *buf)
-{
-	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;
-	u64 val = 0;
-
-	switch (attr->index) {
-	case 0:
-		val = resource->caps.min_avg_interval;
-		break;
-	case 1:
-		val = resource->caps.max_avg_interval;
-		break;
-	case 2:
-		val = resource->caps.min_cap * 1000;
-		break;
-	case 3:
-		val = resource->caps.max_cap * 1000;
-		break;
-	case 4:
-		if (resource->caps.hysteresis == UNKNOWN_HYSTERESIS)
-			return sprintf(buf, "unknown\n");
-
-		val = resource->caps.hysteresis * 1000;
-		break;
-	case 5:
-		if (resource->caps.flags & POWER_METER_IS_BATTERY)
-			val = 1;
-		else
-			val = 0;
-		break;
-	case 6:
-		if (resource->power > resource->cap)
-			val = 1;
-		else
-			val = 0;
-		break;
-	case 7:
-	case 8:
-		if (resource->trip[attr->index - 7] < 0)
-			return sprintf(buf, "unknown\n");
-
-		val = resource->trip[attr->index - 7] * 1000;
-		break;
-	default:
-		BUG();
-	}
-
-	return sprintf(buf, "%llu\n", val);
-}
-
-static ssize_t show_accuracy(struct device *dev,
-			     struct device_attribute *devattr,
-			     char *buf)
-{
-	struct acpi_device *acpi_dev = to_acpi_device(dev);
-	struct acpi_power_meter_resource *resource = acpi_dev->driver_data;
-	unsigned int acc = resource->caps.accuracy;
-
-	return sprintf(buf, "%u.%u%%\n", acc / 1000, acc % 1000);
-}
-
-static ssize_t show_name(struct device *dev,
-			 struct device_attribute *devattr,
-			 char *buf)
-{
-	return sprintf(buf, "%s\n", ACPI_POWER_METER_NAME);
-}
-
-/* Sensor descriptions.  If you add a sensor, update NUM_SENSORS above! */
-static struct ro_sensor_template meter_ro_attrs[] = {
-{POWER_AVERAGE_NAME, show_power, 0},
-{"power1_accuracy", show_accuracy, 0},
-{"power1_average_interval_min", show_val, 0},
-{"power1_average_interval_max", show_val, 1},
-{"power1_is_battery", show_val, 5},
-{NULL, NULL, 0},
-};
-
-static struct rw_sensor_template meter_rw_attrs[] = {
-{POWER_AVG_INTERVAL_NAME, show_avg_interval, set_avg_interval, 0},
-{NULL, NULL, NULL, 0},
-};
-
-static struct ro_sensor_template misc_cap_attrs[] = {
-{"power1_cap_min", show_val, 2},
-{"power1_cap_max", show_val, 3},
-{"power1_cap_hyst", show_val, 4},
-{POWER_ALARM_NAME, show_val, 6},
-{NULL, NULL, 0},
-};
-
-static struct ro_sensor_template ro_cap_attrs[] = {
-{POWER_CAP_NAME, show_cap, 0},
-{NULL, NULL, 0},
-};
-
-static struct rw_sensor_template rw_cap_attrs[] = {
-{POWER_CAP_NAME, show_cap, set_cap, 0},
-{NULL, NULL, NULL, 0},
-};
-
-static struct rw_sensor_template trip_attrs[] = {
-{"power1_average_min", show_val, set_trip, 7},
-{"power1_average_max", show_val, set_trip, 8},
-{NULL, NULL, NULL, 0},
-};
-
-static struct ro_sensor_template misc_attrs[] = {
-{"name", show_name, 0},
-{"power1_model_number", show_str, 0},
-{"power1_oem_info", show_str, 2},
-{"power1_serial_number", show_str, 1},
-{NULL, NULL, 0},
-};
-
-/* Read power domain data */
-static void remove_domain_devices(struct acpi_power_meter_resource *resource)
-{
-	int i;
-
-	if (!resource->num_domain_devices)
-		return;
-
-	for (i = 0; i < resource->num_domain_devices; i++) {
-		struct acpi_device *obj = resource->domain_devices[i];
-		if (!obj)
-			continue;
-
-		sysfs_remove_link(resource->holders_dir,
-				  kobject_name(&obj->dev.kobj));
-		put_device(&obj->dev);
-	}
-
-	kfree(resource->domain_devices);
-	kobject_put(resource->holders_dir);
-	resource->num_domain_devices = 0;
-}
-
-static int read_domain_devices(struct acpi_power_meter_resource *resource)
-{
-	int res = 0;
-	int i;
-	struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
-	union acpi_object *pss;
-	acpi_status status;
-
-	status = acpi_evaluate_object(resource->acpi_dev->handle, "_PMD", NULL,
-				      &buffer);
-	if (ACPI_FAILURE(status)) {
-		ACPI_EXCEPTION((AE_INFO, status, "Evaluating _PMD"));
-		return -ENODEV;
-	}
-
-	pss = buffer.pointer;
-	if (!pss ||
-	    pss->type != ACPI_TYPE_PACKAGE) {
-		dev_err(&resource->acpi_dev->dev, ACPI_POWER_METER_NAME
-			"Invalid _PMD data\n");
-		res = -EFAULT;
-		goto end;
-	}
-
-	if (!pss->package.count)
-		goto end;
-
-	resource->domain_devices = kzalloc(sizeof(struct acpi_device *) *
-					   pss->package.count, GFP_KERNEL);
-	if (!resource->domain_devices) {
-		res = -ENOMEM;
-		goto end;
-	}
-
-	resource->holders_dir = kobject_create_and_add("measures",
-					&resource->acpi_dev->dev.kobj);
-	if (!resource->holders_dir) {
-		res = -ENOMEM;
-		goto exit_free;
-	}
-
-	resource->num_domain_devices = pss->package.count;
-
-	for (i = 0; i < pss->package.count; i++) {
-		struct acpi_device *obj;
-		union acpi_object *element = &(pss->package.elements[i]);
-
-		/* Refuse non-references */
-		if (element->type != ACPI_TYPE_LOCAL_REFERENCE)
-			continue;
-
-		/* Create a symlink to domain objects */
-		resource->domain_devices[i] = NULL;
-		status = acpi_bus_get_device(element->reference.handle,
-					     &resource->domain_devices[i]);
-		if (ACPI_FAILURE(status))
-			continue;
-
-		obj = resource->domain_devices[i];
-		get_device(&obj->dev);
-
-		res = sysfs_create_link(resource->holders_dir, &obj->dev.kobj,
-				      kobject_name(&obj->dev.kobj));
-		if (res) {
-			put_device(&obj->dev);
-			resource->domain_devices[i] = NULL;
-		}
-	}
-
-	res = 0;
-	goto end;
-
-exit_free:
-	kfree(resource->domain_devices);
-end:
-	kfree(buffer.pointer);
-	return res;
-}
-
-/* Registration and deregistration */
-static int register_ro_attrs(struct acpi_power_meter_resource *resource,
-			     struct ro_sensor_template *ro)
-{
-	struct device *dev = &resource->acpi_dev->dev;
-	struct sensor_device_attribute *sensors =
-		&resource->sensors[resource->num_sensors];
-	int res = 0;
-
-	while (ro->label) {
-		sensors->dev_attr.attr.name = ro->label;
-		sensors->dev_attr.attr.mode = S_IRUGO;
-		sensors->dev_attr.show = ro->show;
-		sensors->index = ro->index;
-
-		res = device_create_file(dev, &sensors->dev_attr);
-		if (res) {
-			sensors->dev_attr.attr.name = NULL;
-			goto error;
-		}
-		sensors++;
-		resource->num_sensors++;
-		ro++;
-	}
-
-error:
-	return res;
-}
-
-static int register_rw_attrs(struct acpi_power_meter_resource *resource,
-			     struct rw_sensor_template *rw)
-{
-	struct device *dev = &resource->acpi_dev->dev;
-	struct sensor_device_attribute *sensors =
-		&resource->sensors[resource->num_sensors];
-	int res = 0;
-
-	while (rw->label) {
-		sensors->dev_attr.attr.name = rw->label;
-		sensors->dev_attr.attr.mode = S_IRUGO | S_IWUSR;
-		sensors->dev_attr.show = rw->show;
-		sensors->dev_attr.store = rw->set;
-		sensors->index = rw->index;
-
-		res = device_create_file(dev, &sensors->dev_attr);
-		if (res) {
-			sensors->dev_attr.attr.name = NULL;
-			goto error;
-		}
-		sensors++;
-		resource->num_sensors++;
-		rw++;
-	}
-
-error:
-	return res;
-}
-
-static void remove_attrs(struct acpi_power_meter_resource *resource)
-{
-	int i;
-
-	for (i = 0; i < resource->num_sensors; i++) {
-		if (!resource->sensors[i].dev_attr.attr.name)
-			continue;
-		device_remove_file(&resource->acpi_dev->dev,
-				   &resource->sensors[i].dev_attr);
-	}
-
-	remove_domain_devices(resource);
-
-	resource->num_sensors = 0;
-}
-
-static int setup_attrs(struct acpi_power_meter_resource *resource)
-{
-	int res = 0;
-
-	res = read_domain_devices(resource);
-	if (res)
-		return res;
-
-	if (resource->caps.flags & POWER_METER_CAN_MEASURE) {
-		res = register_ro_attrs(resource, meter_ro_attrs);
-		if (res)
-			goto error;
-		res = register_rw_attrs(resource, meter_rw_attrs);
-		if (res)
-			goto error;
-	}
-
-	if (resource->caps.flags & POWER_METER_CAN_CAP) {
-		if (!can_cap_in_hardware()) {
-			dev_err(&resource->acpi_dev->dev,
-				"Ignoring unsafe software power cap!\n");
-			goto skip_unsafe_cap;
-		}
-
-		if (resource->caps.configurable_cap) {
-			res = register_rw_attrs(resource, rw_cap_attrs);
-			if (res)
-				goto error;
-		} else {
-			res = register_ro_attrs(resource, ro_cap_attrs);
-			if (res)
-				goto error;
-		}
-		res = register_ro_attrs(resource, misc_cap_attrs);
-		if (res)
-			goto error;
-	}
-skip_unsafe_cap:
-
-	if (resource->caps.flags & POWER_METER_CAN_TRIP) {
-		res = register_rw_attrs(resource, trip_attrs);
-		if (res)
-			goto error;
-	}
-
-	res = register_ro_attrs(resource, misc_attrs);
-	if (res)
-		goto error;
-
-	return res;
-error:
-	remove_attrs(resource);
-	return res;
-}
-
-static void free_capabilities(struct acpi_power_meter_resource *resource)
-{
-	acpi_string *str;
-	int i;
-
-	str = &resource->model_number;
-	for (i = 0; i < 3; i++, str++)
-		kfree(*str);
-}
-
-static int read_capabilities(struct acpi_power_meter_resource *resource)
-{
-	int res = 0;
-	int i;
-	struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
-	struct acpi_buffer state = { 0, NULL };
-	struct acpi_buffer format = { sizeof("NNNNNNNNNNN"), "NNNNNNNNNNN" };
-	union acpi_object *pss;
-	acpi_string *str;
-	acpi_status status;
-
-	status = acpi_evaluate_object(resource->acpi_dev->handle, "_PMC", NULL,
-				      &buffer);
-	if (ACPI_FAILURE(status)) {
-		ACPI_EXCEPTION((AE_INFO, status, "Evaluating _PMC"));
-		return -ENODEV;
-	}
-
-	pss = buffer.pointer;
-	if (!pss ||
-	    pss->type != ACPI_TYPE_PACKAGE ||
-	    pss->package.count != 14) {
-		dev_err(&resource->acpi_dev->dev, ACPI_POWER_METER_NAME
-			"Invalid _PMC data\n");
-		res = -EFAULT;
-		goto end;
-	}
-
-	/* Grab all the integer data at once */
-	state.length = sizeof(struct acpi_power_meter_capabilities);
-	state.pointer = &resource->caps;
-
-	status = acpi_extract_package(pss, &format, &state);
-	if (ACPI_FAILURE(status)) {
-		ACPI_EXCEPTION((AE_INFO, status, "Invalid data"));
-		res = -EFAULT;
-		goto end;
-	}
-
-	if (resource->caps.units) {
-		dev_err(&resource->acpi_dev->dev, ACPI_POWER_METER_NAME
-			"Unknown units %llu.\n",
-			resource->caps.units);
-		res = -EINVAL;
-		goto end;
-	}
-
-	/* Grab the string data */
-	str = &resource->model_number;
-
-	for (i = 11; i < 14; i++) {
-		union acpi_object *element = &(pss->package.elements[i]);
-
-		if (element->type != ACPI_TYPE_STRING) {
-			res = -EINVAL;
-			goto error;
-		}
-
-		*str = kzalloc(sizeof(u8) * (element->string.length + 1),
-			       GFP_KERNEL);
-		if (!*str) {
-			res = -ENOMEM;
-			goto error;
-		}
-
-		strncpy(*str, element->string.pointer, element->string.length);
-		str++;
-	}
-
-	dev_info(&resource->acpi_dev->dev, "Found ACPI power meter.\n");
-	goto end;
-error:
-	str = &resource->model_number;
-	for (i = 0; i < 3; i++, str++)
-		kfree(*str);
-end:
-	kfree(buffer.pointer);
-	return res;
-}
-
-/* Handle ACPI event notifications */
-static void acpi_power_meter_notify(struct acpi_device *device, u32 event)
-{
-	struct acpi_power_meter_resource *resource;
-	int res;
-
-	if (!device || !acpi_driver_data(device))
-		return;
-
-	resource = acpi_driver_data(device);
-
-	mutex_lock(&resource->lock);
-	switch (event) {
-	case METER_NOTIFY_CONFIG:
-		free_capabilities(resource);
-		res = read_capabilities(resource);
-		if (res)
-			break;
-
-		remove_attrs(resource);
-		setup_attrs(resource);
-		break;
-	case METER_NOTIFY_TRIP:
-		sysfs_notify(&device->dev.kobj, NULL, POWER_AVERAGE_NAME);
-		update_meter(resource);
-		break;
-	case METER_NOTIFY_CAP:
-		sysfs_notify(&device->dev.kobj, NULL, POWER_CAP_NAME);
-		update_cap(resource);
-		break;
-	case METER_NOTIFY_INTERVAL:
-		sysfs_notify(&device->dev.kobj, NULL, POWER_AVG_INTERVAL_NAME);
-		update_avg_interval(resource);
-		break;
-	case METER_NOTIFY_CAPPING:
-		sysfs_notify(&device->dev.kobj, NULL, POWER_ALARM_NAME);
-		dev_info(&device->dev, "Capping in progress.\n");
-		break;
-	default:
-		BUG();
-	}
-	mutex_unlock(&resource->lock);
-
-	acpi_bus_generate_netlink_event(ACPI_POWER_METER_CLASS,
-					dev_name(&device->dev), event, 0);
-}
-
-static int acpi_power_meter_add(struct acpi_device *device)
-{
-	int res;
-	struct acpi_power_meter_resource *resource;
-
-	if (!device)
-		return -EINVAL;
-
-	resource = kzalloc(sizeof(struct acpi_power_meter_resource),
-			   GFP_KERNEL);
-	if (!resource)
-		return -ENOMEM;
-
-	resource->sensors_valid = 0;
-	resource->acpi_dev = device;
-	mutex_init(&resource->lock);
-	strcpy(acpi_device_name(device), ACPI_POWER_METER_DEVICE_NAME);
-	strcpy(acpi_device_class(device), ACPI_POWER_METER_CLASS);
-	device->driver_data = resource;
-
-	free_capabilities(resource);
-	res = read_capabilities(resource);
-	if (res)
-		goto exit_free;
-
-	resource->trip[0] = resource->trip[1] = -1;
-
-	res = setup_attrs(resource);
-	if (res)
-		goto exit_free;
-
-	resource->hwmon_dev = hwmon_device_register(&device->dev);
-	if (IS_ERR(resource->hwmon_dev)) {
-		res = PTR_ERR(resource->hwmon_dev);
-		goto exit_remove;
-	}
-
-	res = 0;
-	goto exit;
-
-exit_remove:
-	remove_attrs(resource);
-exit_free:
-	kfree(resource);
-exit:
-	return res;
-}
-
-static int acpi_power_meter_remove(struct acpi_device *device, int type)
-{
-	struct acpi_power_meter_resource *resource;
-
-	if (!device || !acpi_driver_data(device))
-		return -EINVAL;
-
-	resource = acpi_driver_data(device);
-	hwmon_device_unregister(resource->hwmon_dev);
-
-	free_capabilities(resource);
-	remove_attrs(resource);
-
-	kfree(resource);
-	return 0;
-}
-
-static int acpi_power_meter_resume(struct acpi_device *device)
-{
-	struct acpi_power_meter_resource *resource;
-
-	if (!device || !acpi_driver_data(device))
-		return -EINVAL;
-
-	resource = acpi_driver_data(device);
-	free_capabilities(resource);
-	read_capabilities(resource);
-
-	return 0;
-}
-
-static struct acpi_driver acpi_power_meter_driver = {
-	.name = "power_meter",
-	.class = ACPI_POWER_METER_CLASS,
-	.ids = power_meter_ids,
-	.ops = {
-		.add = acpi_power_meter_add,
-		.remove = acpi_power_meter_remove,
-		.resume = acpi_power_meter_resume,
-		.notify = acpi_power_meter_notify,
-		},
-};
-
-/* Module init/exit routines */
-static int __init enable_cap_knobs(const struct dmi_system_id *d)
-{
-	cap_in_hardware = 1;
-	return 0;
-}
-
-static struct dmi_system_id __initdata pm_dmi_table[] = {
-	{
-		enable_cap_knobs, "IBM Active Energy Manager",
-		{
-			DMI_MATCH(DMI_SYS_VENDOR, "IBM")
-		},
-	},
-	{}
-};
-
-static int __init acpi_power_meter_init(void)
-{
-	int result;
-
-	if (acpi_disabled)
-		return -ENODEV;
-
-	dmi_check_system(pm_dmi_table);
-
-	result = acpi_bus_register_driver(&acpi_power_meter_driver);
-	if (result < 0)
-		return -ENODEV;
-
-	return 0;
-}
-
-static void __exit acpi_power_meter_exit(void)
-{
-	acpi_bus_unregister_driver(&acpi_power_meter_driver);
-}
-
-MODULE_AUTHOR("Darrick J. Wong <djwong@us.ibm.com>");
-MODULE_DESCRIPTION("ACPI 4.0 power meter driver");
-MODULE_LICENSE("GPL");
-
-module_param(force_cap_on, bool, 0644);
-MODULE_PARM_DESC(force_cap_on, "Enable power cap even it is unsafe to do so.");
-
-module_init(acpi_power_meter_init);
-module_exit(acpi_power_meter_exit);
diff -druN linux-2.6.39-libre/drivers/acpi/processor_core.c linux-3.0-rc7-libre/drivers/acpi/processor_core.c
--- linux-2.6.39-libre/drivers/acpi/processor_core.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/acpi/processor_core.c	2011-07-11 19:51:52.000000000 -0400
@@ -37,7 +37,6 @@
 	{},
 };
 
-#ifdef CONFIG_SMP
 static int map_lapic_id(struct acpi_subtable_header *entry,
 		 u32 acpi_id, int *apic_id)
 {
@@ -165,7 +164,9 @@
 
 int acpi_get_cpuid(acpi_handle handle, int type, u32 acpi_id)
 {
+#ifdef CONFIG_SMP
 	int i;
+#endif
 	int apic_id = -1;
 
 	apic_id = map_mat_entry(handle, type, acpi_id);
@@ -174,14 +175,19 @@
 	if (apic_id == -1)
 		return apic_id;
 
+#ifdef CONFIG_SMP
 	for_each_possible_cpu(i) {
 		if (cpu_physical_id(i) == apic_id)
 			return i;
 	}
+#else
+	/* In UP kernel, only processor 0 is valid */
+	if (apic_id == 0)
+		return apic_id;
+#endif
 	return -1;
 }
 EXPORT_SYMBOL_GPL(acpi_get_cpuid);
-#endif
 
 static bool __init processor_physically_present(acpi_handle handle)
 {
@@ -217,7 +223,7 @@
 	type = (acpi_type == ACPI_TYPE_DEVICE) ? 1 : 0;
 	cpuid = acpi_get_cpuid(handle, type, acpi_id);
 
-	if ((cpuid == -1) && (num_possible_cpus() > 1))
+	if (cpuid == -1)
 		return false;
 
 	return true;
diff -druN linux-2.6.39-libre/drivers/acpi/processor_idle.c linux-3.0-rc7-libre/drivers/acpi/processor_idle.c
--- linux-2.6.39-libre/drivers/acpi/processor_idle.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/acpi/processor_idle.c	2011-07-11 19:51:52.000000000 -0400
@@ -161,7 +161,7 @@
 	if (cpu_has(&cpu_data(pr->id), X86_FEATURE_ARAT))
 		return;
 
-	if (c1e_detected)
+	if (amd_e400_c1e_detected)
 		type = ACPI_STATE_C1;
 
 	/*
diff -druN linux-2.6.39-libre/drivers/acpi/processor_perflib.c linux-3.0-rc7-libre/drivers/acpi/processor_perflib.c
--- linux-2.6.39-libre/drivers/acpi/processor_perflib.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/acpi/processor_perflib.c	2011-07-11 19:51:52.000000000 -0400
@@ -49,10 +49,6 @@
 
 static DEFINE_MUTEX(performance_mutex);
 
-/* Use cpufreq debug layer for _PPC changes. */
-#define cpufreq_printk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_CORE, \
-						"cpufreq-core", msg)
-
 /*
  * _PPC support is implemented as a CPUfreq policy notifier:
  * This means each time a CPUfreq driver registered also with
@@ -145,7 +141,7 @@
 		return -ENODEV;
 	}
 
-	cpufreq_printk("CPU %d: _PPC is %d - frequency %s limited\n", pr->id,
+	pr_debug("CPU %d: _PPC is %d - frequency %s limited\n", pr->id,
 		       (int)ppc, ppc ? "" : "not");
 
 	pr->performance_platform_limit = (int)ppc;
diff -druN linux-2.6.39-libre/drivers/acpi/processor_throttling.c linux-3.0-rc7-libre/drivers/acpi/processor_throttling.c
--- linux-2.6.39-libre/drivers/acpi/processor_throttling.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/acpi/processor_throttling.c	2011-07-11 19:51:52.000000000 -0400
@@ -710,20 +710,14 @@
 }
 
 #ifdef CONFIG_X86
-static int acpi_throttling_rdmsr(struct acpi_processor *pr,
-					u64 *value)
+static int acpi_throttling_rdmsr(u64 *value)
 {
-	struct cpuinfo_x86 *c;
 	u64 msr_high, msr_low;
-	unsigned int cpu;
 	u64 msr = 0;
 	int ret = -1;
 
-	cpu = pr->id;
-	c = &cpu_data(cpu);
-
-	if ((c->x86_vendor != X86_VENDOR_INTEL) ||
-		!cpu_has(c, X86_FEATURE_ACPI)) {
+	if ((this_cpu_read(cpu_info.x86_vendor) != X86_VENDOR_INTEL) ||
+		!this_cpu_has(X86_FEATURE_ACPI)) {
 		printk(KERN_ERR PREFIX
 			"HARDWARE addr space,NOT supported yet\n");
 	} else {
@@ -738,18 +732,13 @@
 	return ret;
 }
 
-static int acpi_throttling_wrmsr(struct acpi_processor *pr, u64 value)
+static int acpi_throttling_wrmsr(u64 value)
 {
-	struct cpuinfo_x86 *c;
-	unsigned int cpu;
 	int ret = -1;
 	u64 msr;
 
-	cpu = pr->id;
-	c = &cpu_data(cpu);
-
-	if ((c->x86_vendor != X86_VENDOR_INTEL) ||
-		!cpu_has(c, X86_FEATURE_ACPI)) {
+	if ((this_cpu_read(cpu_info.x86_vendor) != X86_VENDOR_INTEL) ||
+		!this_cpu_has(X86_FEATURE_ACPI)) {
 		printk(KERN_ERR PREFIX
 			"HARDWARE addr space,NOT supported yet\n");
 	} else {
@@ -761,15 +750,14 @@
 	return ret;
 }
 #else
-static int acpi_throttling_rdmsr(struct acpi_processor *pr,
-				u64 *value)
+static int acpi_throttling_rdmsr(u64 *value)
 {
 	printk(KERN_ERR PREFIX
 		"HARDWARE addr space,NOT supported yet\n");
 	return -1;
 }
 
-static int acpi_throttling_wrmsr(struct acpi_processor *pr, u64 value)
+static int acpi_throttling_wrmsr(u64 value)
 {
 	printk(KERN_ERR PREFIX
 		"HARDWARE addr space,NOT supported yet\n");
@@ -801,7 +789,7 @@
 		ret = 0;
 		break;
 	case ACPI_ADR_SPACE_FIXED_HARDWARE:
-		ret = acpi_throttling_rdmsr(pr, value);
+		ret = acpi_throttling_rdmsr(value);
 		break;
 	default:
 		printk(KERN_ERR PREFIX "Unknown addr space %d\n",
@@ -834,7 +822,7 @@
 		ret = 0;
 		break;
 	case ACPI_ADR_SPACE_FIXED_HARDWARE:
-		ret = acpi_throttling_wrmsr(pr, value);
+		ret = acpi_throttling_wrmsr(value);
 		break;
 	default:
 		printk(KERN_ERR PREFIX "Unknown addr space %d\n",
diff -druN linux-2.6.39-libre/drivers/acpi/sysfs.c linux-3.0-rc7-libre/drivers/acpi/sysfs.c
--- linux-2.6.39-libre/drivers/acpi/sysfs.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/acpi/sysfs.c	2011-07-11 19:51:52.000000000 -0400
@@ -220,6 +220,14 @@
 		  NULL, 0644);
 #endif /* CONFIG_ACPI_DEBUG */
 
+
+/* /sys/modules/acpi/parameters/aml_debug_output */
+
+module_param_named(aml_debug_output, acpi_gbl_enable_aml_debug_object,
+		   bool, 0644);
+MODULE_PARM_DESC(aml_debug_output,
+		 "To enable/disable the ACPI Debug Object output.");
+
 /* /sys/module/acpi/parameters/acpica_version */
 static int param_get_acpica_version(char *buffer, struct kernel_param *kp)
 {
diff -druN linux-2.6.39-libre/drivers/acpi/video.c linux-3.0-rc7-libre/drivers/acpi/video.c
--- linux-2.6.39-libre/drivers/acpi/video.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/acpi/video.c	2011-07-11 19:51:52.000000000 -0400
@@ -1521,7 +1521,7 @@
 		acpi_bus_generate_proc_event(device, event, 0);
 		keycode = KEY_BRIGHTNESSDOWN;
 		break;
-	case ACPI_VIDEO_NOTIFY_ZERO_BRIGHTNESS:	/* zero brightnesss */
+	case ACPI_VIDEO_NOTIFY_ZERO_BRIGHTNESS:	/* zero brightness */
 		if (brightness_switch_enabled)
 			acpi_video_switch_brightness(video_device, event);
 		acpi_bus_generate_proc_event(device, event, 0);
diff -druN linux-2.6.39-libre/drivers/amba/bus.c linux-3.0-rc7-libre/drivers/amba/bus.c
--- linux-2.6.39-libre/drivers/amba/bus.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/amba/bus.c	2011-07-11 19:51:52.000000000 -0400
@@ -603,6 +603,10 @@
 	if (ret)
 		goto err_out;
 
+	/* Hard-coded primecell ID instead of plug-n-play */
+	if (dev->periphid != 0)
+		goto skip_probe;
+
 	/*
 	 * Dynamically calculate the size of the resource
 	 * and use this for iomap
@@ -643,6 +647,7 @@
 	if (ret)
 		goto err_release;
 
+ skip_probe:
 	ret = device_add(&dev->dev);
 	if (ret)
 		goto err_release;
diff -druN linux-2.6.39-libre/drivers/ata/acard-ahci.c linux-3.0-rc7-libre/drivers/ata/acard-ahci.c
--- linux-2.6.39-libre/drivers/ata/acard-ahci.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/ata/acard-ahci.c	2011-07-11 19:51:52.000000000 -0400
@@ -417,7 +417,7 @@
 
 	VPRINTK("ENTER\n");
 
-	WARN_ON(ATA_MAX_QUEUE > AHCI_MAX_CMDS);
+	WARN_ON((int)ATA_MAX_QUEUE > AHCI_MAX_CMDS);
 
 	if (!printed_version++)
 		dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n");
diff -druN linux-2.6.39-libre/drivers/ata/libahci.c linux-3.0-rc7-libre/drivers/ata/libahci.c
--- linux-2.6.39-libre/drivers/ata/libahci.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/ata/libahci.c	2011-07-11 19:51:52.000000000 -0400
@@ -452,7 +452,7 @@
 	}
 
 	if (mask_port_map) {
-		dev_printk(KERN_ERR, dev, "masking port_map 0x%x -> 0x%x\n",
+		dev_printk(KERN_WARNING, dev, "masking port_map 0x%x -> 0x%x\n",
 			   port_map,
 			   port_map & mask_port_map);
 		port_map &= mask_port_map;
diff -druN linux-2.6.39-libre/drivers/ata/libata-core.c linux-3.0-rc7-libre/drivers/ata/libata-core.c
--- linux-2.6.39-libre/drivers/ata/libata-core.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/ata/libata-core.c	2011-07-11 19:51:52.000000000 -0400
@@ -3619,8 +3619,14 @@
 		scontrol |= (0x2 << 8);
 		break;
 	case ATA_LPM_MIN_POWER:
-		/* no restrictions on LPM transitions */
-		scontrol &= ~(0x3 << 8);
+		if (ata_link_nr_enabled(link) > 0)
+			/* no restrictions on LPM transitions */
+			scontrol &= ~(0x3 << 8);
+		else {
+			/* empty port, power off */
+			scontrol &= ~0xf;
+			scontrol |= (0x1 << 2);
+		}
 		break;
 	default:
 		WARN_ON(1);
@@ -4137,9 +4143,9 @@
 	 * Devices which choke on SETXFER.  Applies only if both the
 	 * device and controller are SATA.
 	 */
-	{ "PIONEER DVD-RW  DVRTD08",	"1.00",	ATA_HORKAGE_NOSETXFER },
-	{ "PIONEER DVD-RW  DVR-212D",	"1.28", ATA_HORKAGE_NOSETXFER },
-	{ "PIONEER DVD-RW  DVR-216D",	"1.08", ATA_HORKAGE_NOSETXFER },
+	{ "PIONEER DVD-RW  DVRTD08",	NULL,	ATA_HORKAGE_NOSETXFER },
+	{ "PIONEER DVD-RW  DVR-212D",	NULL,	ATA_HORKAGE_NOSETXFER },
+	{ "PIONEER DVD-RW  DVR-216D",	NULL,	ATA_HORKAGE_NOSETXFER },
 
 	/* End Marker */
 	{ }
diff -druN linux-2.6.39-libre/drivers/ata/libata-eh.c linux-3.0-rc7-libre/drivers/ata/libata-eh.c
--- linux-2.6.39-libre/drivers/ata/libata-eh.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/ata/libata-eh.c	2011-07-11 19:51:52.000000000 -0400
@@ -2802,10 +2802,11 @@
 	}
 
 	/*
-	 * Some controllers can't be frozen very well and may set
-	 * spuruious error conditions during reset.  Clear accumulated
-	 * error information.  As reset is the final recovery action,
-	 * nothing is lost by doing this.
+	 * Some controllers can't be frozen very well and may set spurious
+	 * error conditions during reset.  Clear accumulated error
+	 * information and re-thaw the port if frozen.  As reset is the
+	 * final recovery action and we cross check link onlineness against
+	 * device classification later, no hotplug event is lost by this.
 	 */
 	spin_lock_irqsave(link->ap->lock, flags);
 	memset(&link->eh_info, 0, sizeof(link->eh_info));
@@ -2814,6 +2815,9 @@
 	ap->pflags &= ~ATA_PFLAG_EH_PENDING;
 	spin_unlock_irqrestore(link->ap->lock, flags);
 
+	if (ap->pflags & ATA_PFLAG_FROZEN)
+		ata_eh_thaw_port(ap);
+
 	/*
 	 * Make sure onlineness and classification result correspond.
 	 * Hotplug could have happened during reset and some
@@ -3423,7 +3427,7 @@
 	return rc;
 }
 
-static int ata_link_nr_enabled(struct ata_link *link)
+int ata_link_nr_enabled(struct ata_link *link)
 {
 	struct ata_device *dev;
 	int cnt = 0;
diff -druN linux-2.6.39-libre/drivers/ata/libata-pmp.c linux-3.0-rc7-libre/drivers/ata/libata-pmp.c
--- linux-2.6.39-libre/drivers/ata/libata-pmp.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/ata/libata-pmp.c	2011-07-11 19:51:52.000000000 -0400
@@ -449,6 +449,16 @@
 		 * otherwise.  Don't try hard to recover it.
 		 */
 		ap->pmp_link[ap->nr_pmp_links - 1].flags |= ATA_LFLAG_NO_RETRY;
+	} else if (vendor == 0x197b && devid == 0x2352) {
+		/* chip found in Thermaltake BlackX Duet, jmicron JMB350? */
+		ata_for_each_link(link, ap, EDGE) {
+			/* SRST breaks detection and disks get misclassified
+			 * LPM disabled to avoid potential problems
+			 */
+			link->flags |= ATA_LFLAG_NO_LPM |
+				       ATA_LFLAG_NO_SRST |
+				       ATA_LFLAG_ASSUME_ATA;
+		}
 	}
 }
 
diff -druN linux-2.6.39-libre/drivers/ata/libata-scsi.c linux-3.0-rc7-libre/drivers/ata/libata-scsi.c
--- linux-2.6.39-libre/drivers/ata/libata-scsi.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/ata/libata-scsi.c	2011-07-11 19:51:52.000000000 -0400
@@ -1089,21 +1089,21 @@
 static int ata_scsi_dev_config(struct scsi_device *sdev,
 			       struct ata_device *dev)
 {
+	struct request_queue *q = sdev->request_queue;
+
 	if (!ata_id_has_unload(dev->id))
 		dev->flags |= ATA_DFLAG_NO_UNLOAD;
 
 	/* configure max sectors */
-	blk_queue_max_hw_sectors(sdev->request_queue, dev->max_sectors);
+	blk_queue_max_hw_sectors(q, dev->max_sectors);
 
 	if (dev->class == ATA_DEV_ATAPI) {
-		struct request_queue *q = sdev->request_queue;
 		void *buf;
 
 		sdev->sector_size = ATA_SECT_SIZE;
 
 		/* set DMA padding */
-		blk_queue_update_dma_pad(sdev->request_queue,
-					 ATA_DMA_PAD_SZ - 1);
+		blk_queue_update_dma_pad(q, ATA_DMA_PAD_SZ - 1);
 
 		/* configure draining */
 		buf = kmalloc(ATAPI_MAX_DRAIN, q->bounce_gfp | GFP_KERNEL);
@@ -1131,8 +1131,7 @@
 			"sector_size=%u > PAGE_SIZE, PIO may malfunction\n",
 			sdev->sector_size);
 
-	blk_queue_update_dma_alignment(sdev->request_queue,
-				       sdev->sector_size - 1);
+	blk_queue_update_dma_alignment(q, sdev->sector_size - 1);
 
 	if (dev->flags & ATA_DFLAG_AN)
 		set_bit(SDEV_EVT_MEDIA_CHANGE, sdev->supported_events);
@@ -1145,6 +1144,8 @@
 		scsi_adjust_queue_depth(sdev, MSG_SIMPLE_TAG, depth);
 	}
 
+	blk_queue_flush_queueable(q, false);
+
 	dev->sdev = sdev;
 	return 0;
 }
@@ -2138,7 +2139,7 @@
 	 * with the unmap bit set.
 	 */
 	if (ata_id_has_trim(args->id)) {
-		put_unaligned_be32(65535 * 512 / 8, &rbuf[20]);
+		put_unaligned_be64(65535 * 512 / 8, &rbuf[36]);
 		put_unaligned_be32(1, &rbuf[28]);
 	}
 
@@ -3796,6 +3797,12 @@
  */
 int ata_sas_port_start(struct ata_port *ap)
 {
+	/*
+	 * the port is marked as frozen at allocation time, but if we don't
+	 * have new eh, we won't thaw it
+	 */
+	if (!ap->ops->error_handler)
+		ap->pflags &= ~ATA_PFLAG_FROZEN;
 	return 0;
 }
 EXPORT_SYMBOL_GPL(ata_sas_port_start);
diff -druN linux-2.6.39-libre/drivers/ata/libata-sff.c linux-3.0-rc7-libre/drivers/ata/libata-sff.c
--- linux-2.6.39-libre/drivers/ata/libata-sff.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/ata/libata-sff.c	2011-07-11 19:51:52.000000000 -0400
@@ -2447,13 +2447,18 @@
 		return -ENOMEM;
 
 	if (!legacy_mode && pdev->irq) {
+		int i;
+
 		rc = devm_request_irq(dev, pdev->irq, irq_handler,
 				      IRQF_SHARED, drv_name, host);
 		if (rc)
 			goto out;
 
-		ata_port_desc(host->ports[0], "irq %d", pdev->irq);
-		ata_port_desc(host->ports[1], "irq %d", pdev->irq);
+		for (i = 0; i < 2; i++) {
+			if (ata_port_is_dummy(host->ports[i]))
+				continue;
+			ata_port_desc(host->ports[i], "irq %d", pdev->irq);
+		}
 	} else if (legacy_mode) {
 		if (!ata_port_is_dummy(host->ports[0])) {
 			rc = devm_request_irq(dev, ATA_PRIMARY_IRQ(pdev),
diff -druN linux-2.6.39-libre/drivers/ata/pata_at91.c linux-3.0-rc7-libre/drivers/ata/pata_at91.c
--- linux-2.6.39-libre/drivers/ata/pata_at91.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/ata/pata_at91.c	2011-07-11 19:51:52.000000000 -0400
@@ -3,6 +3,7 @@
  * with CompactFlash interface in True IDE mode
  *
  * Copyright (C) 2009 Matyukevich Sergey
+ *               2011 Igor Plyatov
  *
  * Based on:
  *      * generic platform driver by Paul Mundt: drivers/ata/pata_platform.c
@@ -31,38 +32,150 @@
 #include <mach/board.h>
 #include <mach/gpio.h>
 
+#define DRV_NAME		"pata_at91"
+#define DRV_VERSION		"0.3"
 
-#define DRV_NAME "pata_at91"
-#define DRV_VERSION "0.2"
-
-#define CF_IDE_OFFSET	    0x00c00000
-#define CF_ALT_IDE_OFFSET   0x00e00000
-#define CF_IDE_RES_SIZE     0x08
-#define NCS_RD_PULSE_LIMIT  0x3f /* maximal value for pulse bitfields */
+#define CF_IDE_OFFSET		0x00c00000
+#define CF_ALT_IDE_OFFSET	0x00e00000
+#define CF_IDE_RES_SIZE		0x08
+#define CS_PULSE_MAXIMUM	319
+#define ER_SMC_CALC		1
+#define ER_SMC_RECALC		2
 
 struct at91_ide_info {
 	unsigned long mode;
 	unsigned int cs;
-
 	struct clk *mck;
-
 	void __iomem *ide_addr;
 	void __iomem *alt_addr;
 };
 
-static const struct ata_timing initial_timing = {
-	.mode		= XFER_PIO_0,
-	.setup		= 70,
-	.act8b		= 290,
-	.rec8b		= 240,
-	.cyc8b		= 600,
-	.active		= 165,
-	.recover	= 150,
-	.dmack_hold	= 0,
-	.cycle		= 600,
-	.udma		= 0
+/**
+ * struct smc_range - range of valid values for SMC register.
+ */
+struct smc_range {
+	int min;
+	int max;
 };
 
+/**
+ * adjust_smc_value - adjust value for one of SMC registers.
+ * @value: adjusted value
+ * @range: array of SMC ranges with valid values
+ * @size: SMC ranges array size
+ *
+ * This returns the difference between input and output value or negative
+ * in case of invalid input value.
+ * If negative returned, then output value = maximal possible from ranges.
+ */
+static int adjust_smc_value(int *value, struct smc_range *range, int size)
+{
+	int maximum = (range + size - 1)->max;
+	int remainder;
+
+	do {
+		if (*value < range->min) {
+			remainder = range->min - *value;
+			*value = range->min; /* nearest valid value */
+			return remainder;
+		} else if ((range->min <= *value) && (*value <= range->max))
+			return 0;
+
+		range++;
+	} while (--size);
+	*value = maximum;
+
+	return -1; /* invalid value */
+}
+
+/**
+ * calc_smc_vals - calculate SMC register values
+ * @dev: ATA device
+ * @setup: SMC_SETUP register value
+ * @pulse: SMC_PULSE register value
+ * @cycle: SMC_CYCLE register value
+ *
+ * This returns negative in case of invalid values for SMC registers:
+ * -ER_SMC_RECALC - recalculation required for SMC values,
+ * -ER_SMC_CALC - calculation failed (invalid input values).
+ *
+ * SMC use special coding scheme, see "Coding and Range of Timing
+ * Parameters" table from AT91SAM9 datasheets.
+ *
+ *	SMC_SETUP = 128*setup[5] + setup[4:0]
+ *	SMC_PULSE = 256*pulse[6] + pulse[5:0]
+ *	SMC_CYCLE = 256*cycle[8:7] + cycle[6:0]
+ */
+static int calc_smc_vals(struct device *dev,
+		int *setup, int *pulse, int *cycle, int *cs_pulse)
+{
+	int ret_val;
+	int err = 0;
+	struct smc_range range_setup[] = {	/* SMC_SETUP valid values */
+		{.min = 0,	.max = 31},	/* first  range */
+		{.min = 128,	.max = 159}	/* second range */
+	};
+	struct smc_range range_pulse[] = {	/* SMC_PULSE valid values */
+		{.min = 0,	.max = 63},	/* first  range */
+		{.min = 256,	.max = 319}	/* second range */
+	};
+	struct smc_range range_cycle[] = {	/* SMC_CYCLE valid values */
+		{.min = 0,	.max = 127},	/* first  range */
+		{.min = 256,	.max = 383},	/* second range */
+		{.min = 512,	.max = 639},	/* third  range */
+		{.min = 768,	.max = 895}	/* fourth range */
+	};
+
+	ret_val = adjust_smc_value(setup, range_setup, ARRAY_SIZE(range_setup));
+	if (ret_val < 0)
+		dev_warn(dev, "maximal SMC Setup value\n");
+	else
+		*cycle += ret_val;
+
+	ret_val = adjust_smc_value(pulse, range_pulse, ARRAY_SIZE(range_pulse));
+	if (ret_val < 0)
+		dev_warn(dev, "maximal SMC Pulse value\n");
+	else
+		*cycle += ret_val;
+
+	ret_val = adjust_smc_value(cycle, range_cycle, ARRAY_SIZE(range_cycle));
+	if (ret_val < 0)
+		dev_warn(dev, "maximal SMC Cycle value\n");
+
+	*cs_pulse = *cycle;
+	if (*cs_pulse > CS_PULSE_MAXIMUM) {
+		dev_err(dev, "unable to calculate valid SMC settings\n");
+		return -ER_SMC_CALC;
+	}
+
+	ret_val = adjust_smc_value(cs_pulse, range_pulse,
+					ARRAY_SIZE(range_pulse));
+	if (ret_val < 0) {
+		dev_warn(dev, "maximal SMC CS Pulse value\n");
+	} else if (ret_val != 0) {
+		*cycle = *cs_pulse;
+		dev_warn(dev, "SMC Cycle extended\n");
+		err = -ER_SMC_RECALC;
+	}
+
+	return err;
+}
+
+/**
+ * to_smc_format - convert values into SMC format
+ * @setup: SETUP value of SMC Setup Register
+ * @pulse: PULSE value of SMC Pulse Register
+ * @cycle: CYCLE value of SMC Cycle Register
+ * @cs_pulse: NCS_PULSE value of SMC Pulse Register
+ */
+static void to_smc_format(int *setup, int *pulse, int *cycle, int *cs_pulse)
+{
+	*setup = (*setup & 0x1f) | ((*setup & 0x80) >> 2);
+	*pulse = (*pulse & 0x3f) | ((*pulse & 0x100) >> 2);
+	*cycle = (*cycle & 0x7f) | ((*cycle & 0x300) >> 1);
+	*cs_pulse = (*cs_pulse & 0x3f) | ((*cs_pulse & 0x100) >> 2);
+}
+
 static unsigned long calc_mck_cycles(unsigned long ns, unsigned long mck_hz)
 {
 	unsigned long mul;
@@ -80,85 +193,77 @@
 	return (ns * mul + 65536) >> 16;    /* rounding */
 }
 
-static void set_smc_mode(struct at91_ide_info *info)
-{
-	at91_sys_write(AT91_SMC_MODE(info->cs), info->mode);
-	return;
-}
-
-static void set_smc_timing(struct device *dev,
+/**
+ * set_smc_timing - SMC timings setup.
+ * @dev: device
+ * @info: AT91 IDE info
+ * @ata: ATA timings
+ *
+ * Its assumed that write timings are same as read timings,
+ * cs_setup = 0 and cs_pulse = cycle.
+ */
+static void set_smc_timing(struct device *dev, struct ata_device *adev,
 		struct at91_ide_info *info, const struct ata_timing *ata)
 {
-	unsigned long read_cycle, write_cycle, active, recover;
-	unsigned long nrd_setup, nrd_pulse, nrd_recover;
-	unsigned long nwe_setup, nwe_pulse;
-
-	unsigned long ncs_write_setup, ncs_write_pulse;
-	unsigned long ncs_read_setup, ncs_read_pulse;
-
-	unsigned long mck_hz;
-
-	read_cycle  = ata->cyc8b;
-	nrd_setup   = ata->setup;
-	nrd_pulse   = ata->act8b;
-	nrd_recover = ata->rec8b;
+	int ret = 0;
+	int use_iordy;
+	unsigned int t6z;         /* data tristate time in ns */
+	unsigned int cycle;       /* SMC Cycle width in MCK ticks */
+	unsigned int setup;       /* SMC Setup width in MCK ticks */
+	unsigned int pulse;       /* CFIOR and CFIOW pulse width in MCK ticks */
+	unsigned int cs_setup = 0;/* CS4 or CS5 setup width in MCK ticks */
+	unsigned int cs_pulse;    /* CS4 or CS5 pulse width in MCK ticks*/
+	unsigned int tdf_cycles;  /* SMC TDF MCK ticks */
+	unsigned long mck_hz;     /* MCK frequency in Hz */
 
+	t6z = (ata->mode < XFER_PIO_5) ? 30 : 20;
 	mck_hz = clk_get_rate(info->mck);
+	cycle = calc_mck_cycles(ata->cyc8b, mck_hz);
+	setup = calc_mck_cycles(ata->setup, mck_hz);
+	pulse = calc_mck_cycles(ata->act8b, mck_hz);
+	tdf_cycles = calc_mck_cycles(t6z, mck_hz);
 
-	read_cycle  = calc_mck_cycles(read_cycle, mck_hz);
-	nrd_setup   = calc_mck_cycles(nrd_setup, mck_hz);
-	nrd_pulse   = calc_mck_cycles(nrd_pulse, mck_hz);
-	nrd_recover = calc_mck_cycles(nrd_recover, mck_hz);
+	do {
+		ret = calc_smc_vals(dev, &setup, &pulse, &cycle, &cs_pulse);
+	} while (ret == -ER_SMC_RECALC);
 
-	active  = nrd_setup + nrd_pulse;
-	recover = read_cycle - active;
+	if (ret == -ER_SMC_CALC)
+		dev_err(dev, "Interface may not operate correctly\n");
 
-	/* Need at least two cycles recovery */
-	if (recover < 2)
-		read_cycle = active + 2;
+	dev_dbg(dev, "SMC Setup=%u, Pulse=%u, Cycle=%u, CS Pulse=%u\n",
+		setup, pulse, cycle, cs_pulse);
+	to_smc_format(&setup, &pulse, &cycle, &cs_pulse);
+	/* disable or enable waiting for IORDY signal */
+	use_iordy = ata_pio_need_iordy(adev);
+	if (use_iordy)
+		info->mode |= AT91_SMC_EXNWMODE_READY;
 
-	/* (CS0, CS1, DIR, OE) <= (CFCE1, CFCE2, CFRNW, NCSX) timings */
-	ncs_read_setup = 1;
-	ncs_read_pulse = read_cycle - 2;
-	if (ncs_read_pulse > NCS_RD_PULSE_LIMIT) {
-		ncs_read_pulse = NCS_RD_PULSE_LIMIT;
-		dev_warn(dev, "ncs_read_pulse limited to maximal value %lu\n",
-			ncs_read_pulse);
+	if (tdf_cycles > 15) {
+		tdf_cycles = 15;
+		dev_warn(dev, "maximal SMC TDF Cycles value\n");
 	}
 
-	/* Write timings same as read timings */
-	write_cycle = read_cycle;
-	nwe_setup = nrd_setup;
-	nwe_pulse = nrd_pulse;
-	ncs_write_setup = ncs_read_setup;
-	ncs_write_pulse = ncs_read_pulse;
-
-	dev_dbg(dev, "ATA timings: nrd_setup = %lu nrd_pulse = %lu nrd_cycle = %lu\n",
-			nrd_setup, nrd_pulse, read_cycle);
-	dev_dbg(dev, "ATA timings: nwe_setup = %lu nwe_pulse = %lu nwe_cycle = %lu\n",
-			nwe_setup, nwe_pulse, write_cycle);
-	dev_dbg(dev, "ATA timings: ncs_read_setup = %lu ncs_read_pulse = %lu\n",
-			ncs_read_setup, ncs_read_pulse);
-	dev_dbg(dev, "ATA timings: ncs_write_setup = %lu ncs_write_pulse = %lu\n",
-			ncs_write_setup, ncs_write_pulse);
+	dev_dbg(dev, "Use IORDY=%u, TDF Cycles=%u\n", use_iordy, tdf_cycles);
+	info->mode |= AT91_SMC_TDF_(tdf_cycles);
 
+	/* write SMC Setup Register */
 	at91_sys_write(AT91_SMC_SETUP(info->cs),
-			AT91_SMC_NWESETUP_(nwe_setup) |
-			AT91_SMC_NRDSETUP_(nrd_setup) |
-			AT91_SMC_NCS_WRSETUP_(ncs_write_setup) |
-			AT91_SMC_NCS_RDSETUP_(ncs_read_setup));
-
+			AT91_SMC_NWESETUP_(setup) |
+			AT91_SMC_NRDSETUP_(setup) |
+			AT91_SMC_NCS_WRSETUP_(cs_setup) |
+			AT91_SMC_NCS_RDSETUP_(cs_setup));
+	/* write SMC Pulse Register */
 	at91_sys_write(AT91_SMC_PULSE(info->cs),
-			AT91_SMC_NWEPULSE_(nwe_pulse) |
-			AT91_SMC_NRDPULSE_(nrd_pulse) |
-			AT91_SMC_NCS_WRPULSE_(ncs_write_pulse) |
-			AT91_SMC_NCS_RDPULSE_(ncs_read_pulse));
-
+			AT91_SMC_NWEPULSE_(pulse) |
+			AT91_SMC_NRDPULSE_(pulse) |
+			AT91_SMC_NCS_WRPULSE_(cs_pulse) |
+			AT91_SMC_NCS_RDPULSE_(cs_pulse));
+	/* write SMC Cycle Register */
 	at91_sys_write(AT91_SMC_CYCLE(info->cs),
-			AT91_SMC_NWECYCLE_(write_cycle) |
-			AT91_SMC_NRDCYCLE_(read_cycle));
-
-	return;
+			AT91_SMC_NWECYCLE_(cycle) |
+			AT91_SMC_NRDCYCLE_(cycle));
+	/* write SMC Mode Register*/
+	at91_sys_write(AT91_SMC_MODE(info->cs), info->mode);
 }
 
 static void pata_at91_set_piomode(struct ata_port *ap, struct ata_device *adev)
@@ -172,15 +277,9 @@
 	if (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);
+		timing = *ata_timing_find_mode(XFER_PIO_0);
 	}
-
-	/* Setup SMC mode */
-	set_smc_mode(info);
-
-	return;
+	set_smc_timing(ap->dev, adev, info, &timing);
 }
 
 static unsigned int pata_at91_data_xfer_noirq(struct ata_device *dev,
@@ -346,7 +445,7 @@
 static struct platform_driver pata_at91_driver = {
 	.probe		= pata_at91_probe,
 	.remove		= __devexit_p(pata_at91_remove),
-	.driver 	= {
+	.driver		= {
 		.name		= DRV_NAME,
 		.owner		= THIS_MODULE,
 	},
diff -druN linux-2.6.39-libre/drivers/ata/pata_cmd64x.c linux-3.0-rc7-libre/drivers/ata/pata_cmd64x.c
--- linux-2.6.39-libre/drivers/ata/pata_cmd64x.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/ata/pata_cmd64x.c	2011-07-11 19:51:52.000000000 -0400
@@ -41,6 +41,9 @@
 enum {
 	CFR 		= 0x50,
 		CFR_INTR_CH0  = 0x04,
+	CNTRL		= 0x51,
+		CNTRL_CH0     = 0x04,
+		CNTRL_CH1     = 0x08,
 	CMDTIM 		= 0x52,
 	ARTTIM0 	= 0x53,
 	DRWTIM0 	= 0x54,
@@ -328,9 +331,19 @@
 			.port_ops = &cmd648_port_ops
 		}
 	};
-	const struct ata_port_info *ppi[] = { &cmd_info[id->driver_data], NULL };
-	u8 mrdmode;
+	const struct ata_port_info *ppi[] = { 
+		&cmd_info[id->driver_data],
+		&cmd_info[id->driver_data],
+		NULL
+	};
+	u8 mrdmode, reg;
 	int rc;
+	struct pci_dev *bridge = pdev->bus->self;
+	/* mobility split bridges don't report enabled ports correctly */
+	int port_ok = !(bridge && bridge->vendor ==
+			PCI_VENDOR_ID_MOBILITY_ELECTRONICS);
+	/* all (with exceptions below) apart from 643 have CNTRL_CH0 bit */
+	int cntrl_ch0_ok = (id->driver_data != 0);
 
 	rc = pcim_enable_device(pdev);
 	if (rc)
@@ -341,11 +354,18 @@
 
 	if (pdev->device == PCI_DEVICE_ID_CMD_646) {
 		/* Does UDMA work ? */
-		if (pdev->revision > 4)
+		if (pdev->revision > 4) {
 			ppi[0] = &cmd_info[2];
+			ppi[1] = &cmd_info[2];
+		}
 		/* Early rev with other problems ? */
-		else if (pdev->revision == 1)
+		else if (pdev->revision == 1) {
 			ppi[0] = &cmd_info[3];
+			ppi[1] = &cmd_info[3];
+		}
+		/* revs 1,2 have no CNTRL_CH0 */
+		if (pdev->revision < 3)
+			cntrl_ch0_ok = 0;
 	}
 
 	pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 64);
@@ -354,6 +374,20 @@
 	mrdmode |= 0x02;	/* Memory read line enable */
 	pci_write_config_byte(pdev, MRDMODE, mrdmode);
 
+	/* check for enabled ports */
+	pci_read_config_byte(pdev, CNTRL, &reg);
+	if (!port_ok)
+		dev_printk(KERN_NOTICE, &pdev->dev, "Mobility Bridge detected, ignoring CNTRL port enable/disable\n");
+	if (port_ok && cntrl_ch0_ok && !(reg & CNTRL_CH0)) {
+		dev_printk(KERN_NOTICE, &pdev->dev, "Primary port is disabled\n");
+		ppi[0] = &ata_dummy_port_info;
+		
+	}
+	if (port_ok && !(reg & CNTRL_CH1)) {
+		dev_printk(KERN_NOTICE, &pdev->dev, "Secondary port is disabled\n");
+		ppi[1] = &ata_dummy_port_info;
+	}
+
 	/* Force PIO 0 here.. */
 
 	/* PPC specific fixup copied from old driver */
diff -druN linux-2.6.39-libre/drivers/ata/pata_marvell.c linux-3.0-rc7-libre/drivers/ata/pata_marvell.c
--- linux-2.6.39-libre/drivers/ata/pata_marvell.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/ata/pata_marvell.c	2011-07-11 19:51:52.000000000 -0400
@@ -161,6 +161,9 @@
 	{ PCI_DEVICE(0x11AB, 0x6121), },
 	{ PCI_DEVICE(0x11AB, 0x6123), },
 	{ PCI_DEVICE(0x11AB, 0x6145), },
+	{ PCI_DEVICE(0x1B4B, 0x91A0), },
+	{ PCI_DEVICE(0x1B4B, 0x91A4), },
+
 	{ }	/* terminate list */
 };
 
diff -druN linux-2.6.39-libre/drivers/ata/pata_pcmcia.c linux-3.0-rc7-libre/drivers/ata/pata_pcmcia.c
--- linux-2.6.39-libre/drivers/ata/pata_pcmcia.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/ata/pata_pcmcia.c	2011-07-11 19:51:52.000000000 -0400
@@ -309,7 +309,7 @@
 	pcmcia_disable_device(pdev);
 }
 
-static struct pcmcia_device_id pcmcia_devices[] = {
+static const struct pcmcia_device_id pcmcia_devices[] = {
 	PCMCIA_DEVICE_FUNC_ID(4),
 	PCMCIA_DEVICE_MANF_CARD(0x0000, 0x0000),	/* Corsair */
 	PCMCIA_DEVICE_MANF_CARD(0x0007, 0x0000),	/* Hitachi */
diff -druN linux-2.6.39-libre/drivers/ata/pata_triflex.c linux-3.0-rc7-libre/drivers/ata/pata_triflex.c
--- linux-2.6.39-libre/drivers/ata/pata_triflex.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/ata/pata_triflex.c	2011-07-11 19:51:52.000000000 -0400
@@ -210,13 +210,34 @@
 	{ },
 };
 
+#ifdef CONFIG_PM
+static int triflex_ata_pci_device_suspend(struct pci_dev *pdev, pm_message_t mesg)
+{
+	struct ata_host *host = dev_get_drvdata(&pdev->dev);
+	int rc = 0;
+
+	rc = ata_host_suspend(host, mesg);
+	if (rc)
+		return rc;
+
+	/*
+	 * We must not disable or powerdown the device.
+	 * APM bios refuses to suspend if IDE is not accessible.
+	 */
+	pci_save_state(pdev);
+
+	return 0;
+}
+
+#endif
+
 static struct pci_driver triflex_pci_driver = {
 	.name 		= DRV_NAME,
 	.id_table	= triflex,
 	.probe 		= triflex_init_one,
 	.remove		= ata_pci_remove_one,
 #ifdef CONFIG_PM
-	.suspend	= ata_pci_device_suspend,
+	.suspend	= triflex_ata_pci_device_suspend,
 	.resume		= ata_pci_device_resume,
 #endif
 };
diff -druN linux-2.6.39-libre/drivers/ata/sata_dwc_460ex.c linux-3.0-rc7-libre/drivers/ata/sata_dwc_460ex.c
--- linux-2.6.39-libre/drivers/ata/sata_dwc_460ex.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/ata/sata_dwc_460ex.c	2011-07-11 19:51:52.000000000 -0400
@@ -389,7 +389,7 @@
 /*
  * Function: get_burst_length_encode
  * arguments: datalength: length in bytes of data
- * returns value to be programmed in register corrresponding to data length
+ * returns value to be programmed in register corresponding to data length
  * This value is effectively the log(base 2) of the length
  */
 static  int get_burst_length_encode(int datalength)
diff -druN linux-2.6.39-libre/drivers/atm/eni.c linux-3.0-rc7-libre/drivers/atm/eni.c
--- linux-2.6.39-libre/drivers/atm/eni.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/atm/eni.c	2011-07-11 19:51:52.000000000 -0400
@@ -1469,10 +1469,7 @@
 
 static void bug_int(struct atm_dev *dev,unsigned long reason)
 {
-	struct eni_dev *eni_dev;
-
 	DPRINTK(">bug_int\n");
-	eni_dev = ENI_DEV(dev);
 	if (reason & MID_DMA_ERR_ACK)
 		printk(KERN_CRIT DEV_LABEL "(itf %d): driver error - DMA "
 		    "error\n",dev->number);
@@ -1900,7 +1897,6 @@
 
 static int eni_open(struct atm_vcc *vcc)
 {
-	struct eni_dev *eni_dev;
 	struct eni_vcc *eni_vcc;
 	int error;
 	short vpi = vcc->vpi;
@@ -1910,7 +1906,6 @@
 	EVENT("eni_open\n",0,0);
 	if (!test_bit(ATM_VF_PARTIAL,&vcc->flags))
 		vcc->dev_data = NULL;
-	eni_dev = ENI_DEV(vcc->dev);
 	if (vci != ATM_VPI_UNSPEC && vpi != ATM_VCI_UNSPEC)
 		set_bit(ATM_VF_ADDR,&vcc->flags);
 	if (vcc->qos.aal != ATM_AAL0 && vcc->qos.aal != ATM_AAL5)
diff -druN linux-2.6.39-libre/drivers/atm/he.c linux-3.0-rc7-libre/drivers/atm/he.c
--- linux-2.6.39-libre/drivers/atm/he.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/atm/he.c	2011-07-11 19:51:52.000000000 -0400
@@ -1801,7 +1801,7 @@
 next_rbrq_entry:
 		he_dev->rbrq_head = (struct he_rbrq *)
 				((unsigned long) he_dev->rbrq_base |
-					RBRQ_MASK(++he_dev->rbrq_head));
+					RBRQ_MASK(he_dev->rbrq_head + 1));
 
 	}
 	read_unlock(&vcc_sklist_lock);
@@ -1884,7 +1884,7 @@
 			pci_pool_free(he_dev->tpd_pool, tpd, TPD_ADDR(tpd->status));
 		he_dev->tbrq_head = (struct he_tbrq *)
 				((unsigned long) he_dev->tbrq_base |
-					TBRQ_MASK(++he_dev->tbrq_head));
+					TBRQ_MASK(he_dev->tbrq_head + 1));
 	}
 
 	if (updated) {
diff -druN linux-2.6.39-libre/drivers/atm/idt77252.c linux-3.0-rc7-libre/drivers/atm/idt77252.c
--- linux-2.6.39-libre/drivers/atm/idt77252.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/atm/idt77252.c	2011-07-11 19:51:52.000000000 -0400
@@ -1261,14 +1261,13 @@
 				    PCI_DMA_FROMDEVICE);
 
 	while (head != tail) {
-		unsigned int vpi, vci, pti;
+		unsigned int vpi, vci;
 		u32 header;
 
 		header = le32_to_cpu(*(u32 *) &queue->data[0]);
 
 		vpi = (header & ATM_HDR_VPI_MASK) >> ATM_HDR_VPI_SHIFT;
 		vci = (header & ATM_HDR_VCI_MASK) >> ATM_HDR_VCI_SHIFT;
-		pti = (header & ATM_HDR_PTI_MASK) >> ATM_HDR_PTI_SHIFT;
 
 #ifdef CONFIG_ATM_IDT77252_DEBUG
 		if (debug & DBG_RAW_CELL) {
@@ -2709,53 +2708,10 @@
 static void
 idt77252_collect_stat(struct idt77252_dev *card)
 {
-	u32 cdc, vpec, icc;
-
-	cdc = readl(SAR_REG_CDC);
-	vpec = readl(SAR_REG_VPEC);
-	icc = readl(SAR_REG_ICC);
-
-#ifdef	NOTDEF
-	printk("%s:", card->name);
-
-	if (cdc & 0x7f0000) {
-		char *s = "";
-
-		printk(" [");
-		if (cdc & (1 << 22)) {
-			printk("%sRM ID", s);
-			s = " | ";
-		}
-		if (cdc & (1 << 21)) {
-			printk("%sCON TAB", s);
-			s = " | ";
-		}
-		if (cdc & (1 << 20)) {
-			printk("%sNO FB", s);
-			s = " | ";
-		}
-		if (cdc & (1 << 19)) {
-			printk("%sOAM CRC", s);
-			s = " | ";
-		}
-		if (cdc & (1 << 18)) {
-			printk("%sRM CRC", s);
-			s = " | ";
-		}
-		if (cdc & (1 << 17)) {
-			printk("%sRM FIFO", s);
-			s = " | ";
-		}
-		if (cdc & (1 << 16)) {
-			printk("%sRX FIFO", s);
-			s = " | ";
-		}
-		printk("]");
-	}
+	(void) readl(SAR_REG_CDC);
+	(void) readl(SAR_REG_VPEC);
+	(void) readl(SAR_REG_ICC);
 
-	printk(" CDC %04x, VPEC %04x, ICC: %04x\n",
-	       cdc & 0xffff, vpec & 0xffff, icc & 0xffff);
-#endif
 }
 
 static irqreturn_t
diff -druN linux-2.6.39-libre/drivers/atm/iphase.c linux-3.0-rc7-libre/drivers/atm/iphase.c
--- linux-2.6.39-libre/drivers/atm/iphase.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/atm/iphase.c	2011-07-11 19:51:52.000000000 -0400
@@ -613,7 +613,6 @@
    struct sk_buff *skb;
    int num_desc;
    struct atm_vcc *vcc;
-   struct ia_vcc *iavcc;
    num_desc = ia_avail_descs(iadev);
 
    while (num_desc && (skb = skb_dequeue(&iadev->tx_backlog))) {
@@ -627,7 +626,6 @@
          printk("Free the SKB on closed vci %d \n", vcc->vci);
          break;
       }
-      iavcc = INPH_IA_VCC(vcc);
       if (ia_pkt_tx (vcc, skb)) {
          skb_queue_head(&iadev->tx_backlog, skb);
       }
@@ -823,8 +821,6 @@
   volatile IA_SUNI *suni;
   volatile ia_mb25_t *mb25;
   volatile suni_pm7345_t *suni_pm7345;
-  u32 intr_status;
-  u_int frmr_intr;
 
   if(iadev->phy_type & FE_25MBIT_PHY) {
      mb25 = (ia_mb25_t*)iadev->phy;
@@ -832,18 +828,18 @@
   } else if (iadev->phy_type & FE_DS3_PHY) {
      suni_pm7345 = (suni_pm7345_t *)iadev->phy;
      /* clear FRMR interrupts */
-     frmr_intr   = suni_pm7345->suni_ds3_frm_intr_stat; 
+     (void) suni_pm7345->suni_ds3_frm_intr_stat; 
      iadev->carrier_detect =  
            Boolean(!(suni_pm7345->suni_ds3_frm_stat & SUNI_DS3_LOSV));
   } else if (iadev->phy_type & FE_E3_PHY ) {
      suni_pm7345 = (suni_pm7345_t *)iadev->phy;
-     frmr_intr   = suni_pm7345->suni_e3_frm_maint_intr_ind;
+     (void) suni_pm7345->suni_e3_frm_maint_intr_ind;
      iadev->carrier_detect =
            Boolean(!(suni_pm7345->suni_e3_frm_fram_intr_ind_stat&SUNI_E3_LOS));
   }
   else { 
      suni = (IA_SUNI *)iadev->phy;
-     intr_status = suni->suni_rsop_status & 0xff;
+     (void) suni->suni_rsop_status;
      iadev->carrier_detect = Boolean(!(suni->suni_rsop_status & SUNI_LOSV));
   }
   if (iadev->carrier_detect)
@@ -2660,7 +2656,6 @@
   
 static int ia_open(struct atm_vcc *vcc)
 {  
-	IADEV *iadev;  
 	struct ia_vcc *ia_vcc;  
 	int error;  
 	if (!test_bit(ATM_VF_PARTIAL,&vcc->flags))  
@@ -2668,7 +2663,6 @@
 		IF_EVENT(printk("ia: not partially allocated resources\n");)  
 		vcc->dev_data = NULL;
 	}  
-	iadev = INPH_IA_DEV(vcc->dev);  
 	if (vcc->vci != ATM_VPI_UNSPEC && vcc->vpi != ATM_VCI_UNSPEC)  
 	{  
 		IF_EVENT(printk("iphase open: unspec part\n");)  
@@ -3052,11 +3046,9 @@
 static int ia_send(struct atm_vcc *vcc, struct sk_buff *skb)
 {
         IADEV *iadev; 
-        struct ia_vcc *iavcc;
         unsigned long flags;
 
         iadev = INPH_IA_DEV(vcc->dev);
-        iavcc = INPH_IA_VCC(vcc); 
         if ((!skb)||(skb->len>(iadev->tx_buf_sz-sizeof(struct cpcs_trailer))))
         {
             if (!skb)
diff -druN linux-2.6.39-libre/drivers/atm/solos-pci.c linux-3.0-rc7-libre/drivers/atm/solos-pci.c
--- linux-2.6.39-libre/drivers/atm/solos-pci.c	2011-05-19 02:07:28.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/atm/solos-pci.c	2011-07-21 06:49:39.000000000 -0400
@@ -525,7 +525,6 @@
 {
 	const struct firmware *fw;
 	const char *fw_name;
-	uint32_t data32 = 0;
 	int blocksize = 0;
 	int numblocks = 0;
 	int offset;
@@ -574,7 +573,7 @@
 	
 	dev_info(&card->dev->dev, "Changing FPGA to Update mode\n");
 	iowrite32(1, card->config_regs + FPGA_MODE);
-	data32 = ioread32(card->config_regs + FPGA_MODE); 
+	(void) ioread32(card->config_regs + FPGA_MODE); 
 
 	/* Set mode to Chip Erase */
 	if(chip == 0 || chip == 2)
diff -druN linux-2.6.39-libre/drivers/base/base.h linux-3.0-rc7-libre/drivers/base/base.h
--- linux-2.6.39-libre/drivers/base/base.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/base/base.h	2011-07-11 19:51:52.000000000 -0400
@@ -111,8 +111,6 @@
 	return drv->bus->match ? drv->bus->match(dev, drv) : 1;
 }
 
-extern void sysdev_shutdown(void);
-
 extern char *make_class_name(const char *name, struct kobject *kobj);
 
 extern int devres_release_all(struct device *dev);
diff -druN linux-2.6.39-libre/drivers/base/core.c linux-3.0-rc7-libre/drivers/base/core.c
--- linux-2.6.39-libre/drivers/base/core.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/base/core.c	2011-07-11 19:51:52.000000000 -0400
@@ -400,7 +400,7 @@
 static int device_add_attrs(struct device *dev)
 {
 	struct class *class = dev->class;
-	struct device_type *type = dev->type;
+	const struct device_type *type = dev->type;
 	int error;
 
 	if (class) {
@@ -440,7 +440,7 @@
 static void device_remove_attrs(struct device *dev)
 {
 	struct class *class = dev->class;
-	struct device_type *type = dev->type;
+	const struct device_type *type = dev->type;
 
 	device_remove_groups(dev, dev->groups);
 
@@ -1314,8 +1314,7 @@
 EXPORT_SYMBOL_GPL(device_create_file);
 EXPORT_SYMBOL_GPL(device_remove_file);
 
-struct root_device
-{
+struct root_device {
 	struct device dev;
 	struct module *owner;
 };
diff -druN linux-2.6.39-libre/drivers/base/dd.c linux-3.0-rc7-libre/drivers/base/dd.c
--- linux-2.6.39-libre/drivers/base/dd.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/base/dd.c	2011-07-11 19:51:52.000000000 -0400
@@ -245,6 +245,10 @@
 
 	device_lock(dev);
 	if (dev->driver) {
+		if (klist_node_attached(&dev->p->knode_driver)) {
+			ret = 1;
+			goto out_unlock;
+		}
 		ret = device_bind_driver(dev);
 		if (ret == 0)
 			ret = 1;
@@ -257,6 +261,7 @@
 		ret = bus_for_each_drv(dev->bus, NULL, dev, __device_attach);
 		pm_runtime_put_sync(dev);
 	}
+out_unlock:
 	device_unlock(dev);
 	return ret;
 }
@@ -316,8 +321,7 @@
 
 	drv = dev->driver;
 	if (drv) {
-		pm_runtime_get_noresume(dev);
-		pm_runtime_barrier(dev);
+		pm_runtime_get_sync(dev);
 
 		driver_sysfs_remove(dev);
 
@@ -326,6 +330,8 @@
 						     BUS_NOTIFY_UNBIND_DRIVER,
 						     dev);
 
+		pm_runtime_put_sync(dev);
+
 		if (dev->bus && dev->bus->remove)
 			dev->bus->remove(dev);
 		else if (drv->remove)
@@ -338,7 +344,6 @@
 						     BUS_NOTIFY_UNBOUND_DRIVER,
 						     dev);
 
-		pm_runtime_put_sync(dev);
 	}
 }
 
@@ -408,17 +413,16 @@
 }
 EXPORT_SYMBOL(dev_get_drvdata);
 
-void dev_set_drvdata(struct device *dev, void *data)
+int dev_set_drvdata(struct device *dev, void *data)
 {
 	int error;
 
-	if (!dev)
-		return;
 	if (!dev->p) {
 		error = device_private_init(dev);
 		if (error)
-			return;
+			return error;
 	}
 	dev->p->driver_data = data;
+	return 0;
 }
 EXPORT_SYMBOL(dev_set_drvdata);
diff -druN linux-2.6.39-libre/drivers/base/firmware_class.c linux-3.0-rc7-libre/drivers/base/firmware_class.c
--- linux-2.6.39-libre/drivers/base/firmware_class.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/base/firmware_class.c	2011-07-11 19:51:52.000000000 -0400
@@ -521,6 +521,11 @@
 	if (!firmware_p)
 		return -EINVAL;
 
+	if (WARN_ON(usermodehelper_is_disabled())) {
+		dev_err(device, "firmware: %s will not be loaded\n", name);
+		return -EBUSY;
+	}
+
 	*firmware_p = firmware = kzalloc(sizeof(*firmware), GFP_KERNEL);
 	if (!firmware) {
 		dev_err(device, "%s: kmalloc(struct firmware) failed\n",
diff -druN linux-2.6.39-libre/drivers/base/Kconfig linux-3.0-rc7-libre/drivers/base/Kconfig
--- linux-2.6.39-libre/drivers/base/Kconfig	2011-05-19 02:21:02.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/base/Kconfig	2011-07-21 07:03:33.000000000 -0400
@@ -168,11 +168,4 @@
 	bool
 	default n
 
-config ARCH_NO_SYSDEV_OPS
-	bool
-	---help---
-	  To be selected by architectures that don't use sysdev class or
-	  sysdev driver power management (suspend/resume) and shutdown
-	  operations.
-
 endmenu
diff -druN linux-2.6.39-libre/drivers/base/memory.c linux-3.0-rc7-libre/drivers/base/memory.c
--- linux-2.6.39-libre/drivers/base/memory.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/base/memory.c	2011-07-11 19:51:52.000000000 -0400
@@ -48,7 +48,8 @@
 	return MEMORY_CLASS_NAME;
 }
 
-static int memory_uevent(struct kset *kset, struct kobject *obj, struct kobj_uevent_env *env)
+static int memory_uevent(struct kset *kset, struct kobject *obj,
+			struct kobj_uevent_env *env)
 {
 	int retval = 0;
 
@@ -228,10 +229,11 @@
  * OK to have direct references to sparsemem variables in here.
  */
 static int
-memory_section_action(unsigned long phys_index, unsigned long action)
+memory_block_action(unsigned long phys_index, unsigned long action)
 {
 	int i;
 	unsigned long start_pfn, start_paddr;
+	unsigned long nr_pages = PAGES_PER_SECTION * sections_per_block;
 	struct page *first_page;
 	int ret;
 
@@ -243,7 +245,7 @@
 	 * that way.
 	 */
 	if (action == MEM_ONLINE) {
-		for (i = 0; i < PAGES_PER_SECTION; i++) {
+		for (i = 0; i < nr_pages; i++) {
 			if (PageReserved(first_page+i))
 				continue;
 
@@ -257,12 +259,12 @@
 	switch (action) {
 		case MEM_ONLINE:
 			start_pfn = page_to_pfn(first_page);
-			ret = online_pages(start_pfn, PAGES_PER_SECTION);
+			ret = online_pages(start_pfn, nr_pages);
 			break;
 		case MEM_OFFLINE:
 			start_paddr = page_to_pfn(first_page) << PAGE_SHIFT;
 			ret = remove_memory(start_paddr,
-					    PAGES_PER_SECTION << PAGE_SHIFT);
+					    nr_pages << PAGE_SHIFT);
 			break;
 		default:
 			WARN(1, KERN_WARNING "%s(%ld, %ld) unknown action: "
@@ -276,7 +278,7 @@
 static int memory_block_change_state(struct memory_block *mem,
 		unsigned long to_state, unsigned long from_state_req)
 {
-	int i, ret = 0;
+	int ret = 0;
 
 	mutex_lock(&mem->state_mutex);
 
@@ -288,20 +290,11 @@
 	if (to_state == MEM_OFFLINE)
 		mem->state = MEM_GOING_OFFLINE;
 
-	for (i = 0; i < sections_per_block; i++) {
-		ret = memory_section_action(mem->start_section_nr + i,
-					    to_state);
-		if (ret)
-			break;
-	}
-
-	if (ret) {
-		for (i = 0; i < sections_per_block; i++)
-			memory_section_action(mem->start_section_nr + i,
-					      from_state_req);
+	ret = memory_block_action(mem->start_section_nr, to_state);
 
+	if (ret)
 		mem->state = from_state_req;
-	} else
+	else
 		mem->state = to_state;
 
 out:
@@ -396,15 +389,14 @@
 		ret = add_memory(nid, phys_addr,
 				 PAGES_PER_SECTION << PAGE_SHIFT);
 		if (ret)
-			break;
+			goto out;
 
 		phys_addr += MIN_MEMORY_BLOCK_SIZE;
 	}
 
-	if (ret)
-		count = ret;
-
-	return count;
+	ret = count;
+out:
+	return ret;
 }
 static CLASS_ATTR(probe, S_IWUSR, NULL, memory_probe_store);
 
diff -druN linux-2.6.39-libre/drivers/base/node.c linux-3.0-rc7-libre/drivers/base/node.c
--- linux-2.6.39-libre/drivers/base/node.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/base/node.c	2011-07-11 19:51:52.000000000 -0400
@@ -7,6 +7,7 @@
 #include <linux/init.h>
 #include <linux/mm.h>
 #include <linux/memory.h>
+#include <linux/vmstat.h>
 #include <linux/node.h>
 #include <linux/hugetlb.h>
 #include <linux/compaction.h>
@@ -179,11 +180,14 @@
 				struct sysdev_attribute *attr, char *buf)
 {
 	int nid = dev->id;
-	return sprintf(buf,
-		"nr_written %lu\n"
-		"nr_dirtied %lu\n",
-		node_page_state(nid, NR_WRITTEN),
-		node_page_state(nid, NR_DIRTIED));
+	int i;
+	int n = 0;
+
+	for (i = 0; i < NR_VM_ZONE_STAT_ITEMS; i++)
+		n += sprintf(buf+n, "%s %lu\n", vmstat_text[i],
+			     node_page_state(nid, i));
+
+	return n;
 }
 static SYSDEV_ATTR(vmstat, S_IRUGO, node_read_vmstat, NULL);
 
diff -druN linux-2.6.39-libre/drivers/base/platform.c linux-3.0-rc7-libre/drivers/base/platform.c
--- linux-2.6.39-libre/drivers/base/platform.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/base/platform.c	2011-07-11 19:51:52.000000000 -0400
@@ -192,18 +192,18 @@
 int platform_device_add_resources(struct platform_device *pdev,
 				  const struct resource *res, unsigned int num)
 {
-	struct resource *r;
-
-	if (!res)
-		return 0;
+	struct resource *r = NULL;
 
-	r = kmemdup(res, sizeof(struct resource) * num, GFP_KERNEL);
-	if (r) {
-		pdev->resource = r;
-		pdev->num_resources = num;
-		return 0;
+	if (res) {
+		r = kmemdup(res, sizeof(struct resource) * num, GFP_KERNEL);
+		if (!r)
+			return -ENOMEM;
 	}
-	return -ENOMEM;
+
+	kfree(pdev->resource);
+	pdev->resource = r;
+	pdev->num_resources = num;
+	return 0;
 }
 EXPORT_SYMBOL_GPL(platform_device_add_resources);
 
@@ -220,17 +220,17 @@
 int platform_device_add_data(struct platform_device *pdev, const void *data,
 			     size_t size)
 {
-	void *d;
-
-	if (!data)
-		return 0;
+	void *d = NULL;
 
-	d = kmemdup(data, size, GFP_KERNEL);
-	if (d) {
-		pdev->dev.platform_data = d;
-		return 0;
+	if (data) {
+		d = kmemdup(data, size, GFP_KERNEL);
+		if (!d)
+			return -ENOMEM;
 	}
-	return -ENOMEM;
+
+	kfree(pdev->dev.platform_data);
+	pdev->dev.platform_data = d;
+	return 0;
 }
 EXPORT_SYMBOL_GPL(platform_device_add_data);
 
@@ -367,7 +367,7 @@
  *
  * Returns &struct platform_device pointer on success, or ERR_PTR() on error.
  */
-struct platform_device *__init_or_module platform_device_register_resndata(
+struct platform_device *platform_device_register_resndata(
 		struct device *parent,
 		const char *name, int id,
 		const struct resource *res, unsigned int num,
@@ -667,7 +667,7 @@
 	return ret;
 }
 
-static int platform_pm_prepare(struct device *dev)
+int platform_pm_prepare(struct device *dev)
 {
 	struct device_driver *drv = dev->driver;
 	int ret = 0;
@@ -678,7 +678,7 @@
 	return ret;
 }
 
-static void platform_pm_complete(struct device *dev)
+void platform_pm_complete(struct device *dev)
 {
 	struct device_driver *drv = dev->driver;
 
@@ -686,16 +686,11 @@
 		drv->pm->complete(dev);
 }
 
-#else /* !CONFIG_PM_SLEEP */
-
-#define platform_pm_prepare		NULL
-#define platform_pm_complete		NULL
-
-#endif /* !CONFIG_PM_SLEEP */
+#endif /* CONFIG_PM_SLEEP */
 
 #ifdef CONFIG_SUSPEND
 
-int __weak platform_pm_suspend(struct device *dev)
+int platform_pm_suspend(struct device *dev)
 {
 	struct device_driver *drv = dev->driver;
 	int ret = 0;
@@ -713,7 +708,7 @@
 	return ret;
 }
 
-int __weak platform_pm_suspend_noirq(struct device *dev)
+int platform_pm_suspend_noirq(struct device *dev)
 {
 	struct device_driver *drv = dev->driver;
 	int ret = 0;
@@ -729,7 +724,7 @@
 	return ret;
 }
 
-int __weak platform_pm_resume(struct device *dev)
+int platform_pm_resume(struct device *dev)
 {
 	struct device_driver *drv = dev->driver;
 	int ret = 0;
@@ -747,7 +742,7 @@
 	return ret;
 }
 
-int __weak platform_pm_resume_noirq(struct device *dev)
+int platform_pm_resume_noirq(struct device *dev)
 {
 	struct device_driver *drv = dev->driver;
 	int ret = 0;
@@ -763,18 +758,11 @@
 	return ret;
 }
 
-#else /* !CONFIG_SUSPEND */
-
-#define platform_pm_suspend		NULL
-#define platform_pm_resume		NULL
-#define platform_pm_suspend_noirq	NULL
-#define platform_pm_resume_noirq	NULL
-
-#endif /* !CONFIG_SUSPEND */
+#endif /* CONFIG_SUSPEND */
 
 #ifdef CONFIG_HIBERNATE_CALLBACKS
 
-static int platform_pm_freeze(struct device *dev)
+int platform_pm_freeze(struct device *dev)
 {
 	struct device_driver *drv = dev->driver;
 	int ret = 0;
@@ -792,7 +780,7 @@
 	return ret;
 }
 
-static int platform_pm_freeze_noirq(struct device *dev)
+int platform_pm_freeze_noirq(struct device *dev)
 {
 	struct device_driver *drv = dev->driver;
 	int ret = 0;
@@ -808,7 +796,7 @@
 	return ret;
 }
 
-static int platform_pm_thaw(struct device *dev)
+int platform_pm_thaw(struct device *dev)
 {
 	struct device_driver *drv = dev->driver;
 	int ret = 0;
@@ -826,7 +814,7 @@
 	return ret;
 }
 
-static int platform_pm_thaw_noirq(struct device *dev)
+int platform_pm_thaw_noirq(struct device *dev)
 {
 	struct device_driver *drv = dev->driver;
 	int ret = 0;
@@ -842,7 +830,7 @@
 	return ret;
 }
 
-static int platform_pm_poweroff(struct device *dev)
+int platform_pm_poweroff(struct device *dev)
 {
 	struct device_driver *drv = dev->driver;
 	int ret = 0;
@@ -860,7 +848,7 @@
 	return ret;
 }
 
-static int platform_pm_poweroff_noirq(struct device *dev)
+int platform_pm_poweroff_noirq(struct device *dev)
 {
 	struct device_driver *drv = dev->driver;
 	int ret = 0;
@@ -876,7 +864,7 @@
 	return ret;
 }
 
-static int platform_pm_restore(struct device *dev)
+int platform_pm_restore(struct device *dev)
 {
 	struct device_driver *drv = dev->driver;
 	int ret = 0;
@@ -894,7 +882,7 @@
 	return ret;
 }
 
-static int platform_pm_restore_noirq(struct device *dev)
+int platform_pm_restore_noirq(struct device *dev)
 {
 	struct device_driver *drv = dev->driver;
 	int ret = 0;
@@ -910,62 +898,13 @@
 	return ret;
 }
 
-#else /* !CONFIG_HIBERNATE_CALLBACKS */
-
-#define platform_pm_freeze		NULL
-#define platform_pm_thaw		NULL
-#define platform_pm_poweroff		NULL
-#define platform_pm_restore		NULL
-#define platform_pm_freeze_noirq	NULL
-#define platform_pm_thaw_noirq		NULL
-#define platform_pm_poweroff_noirq	NULL
-#define platform_pm_restore_noirq	NULL
-
-#endif /* !CONFIG_HIBERNATE_CALLBACKS */
-
-#ifdef CONFIG_PM_RUNTIME
-
-int __weak platform_pm_runtime_suspend(struct device *dev)
-{
-	return pm_generic_runtime_suspend(dev);
-};
-
-int __weak platform_pm_runtime_resume(struct device *dev)
-{
-	return pm_generic_runtime_resume(dev);
-};
-
-int __weak platform_pm_runtime_idle(struct device *dev)
-{
-	return pm_generic_runtime_idle(dev);
-};
-
-#else /* !CONFIG_PM_RUNTIME */
-
-#define platform_pm_runtime_suspend NULL
-#define platform_pm_runtime_resume NULL
-#define platform_pm_runtime_idle NULL
-
-#endif /* !CONFIG_PM_RUNTIME */
+#endif /* CONFIG_HIBERNATE_CALLBACKS */
 
 static const struct dev_pm_ops platform_dev_pm_ops = {
-	.prepare = platform_pm_prepare,
-	.complete = platform_pm_complete,
-	.suspend = platform_pm_suspend,
-	.resume = platform_pm_resume,
-	.freeze = platform_pm_freeze,
-	.thaw = platform_pm_thaw,
-	.poweroff = platform_pm_poweroff,
-	.restore = platform_pm_restore,
-	.suspend_noirq = platform_pm_suspend_noirq,
-	.resume_noirq = platform_pm_resume_noirq,
-	.freeze_noirq = platform_pm_freeze_noirq,
-	.thaw_noirq = platform_pm_thaw_noirq,
-	.poweroff_noirq = platform_pm_poweroff_noirq,
-	.restore_noirq = platform_pm_restore_noirq,
-	.runtime_suspend = platform_pm_runtime_suspend,
-	.runtime_resume = platform_pm_runtime_resume,
-	.runtime_idle = platform_pm_runtime_idle,
+	.runtime_suspend = pm_generic_runtime_suspend,
+	.runtime_resume = pm_generic_runtime_resume,
+	.runtime_idle = pm_generic_runtime_idle,
+	USE_PLATFORM_PM_SLEEP_OPS
 };
 
 struct bus_type platform_bus_type = {
@@ -977,41 +916,6 @@
 };
 EXPORT_SYMBOL_GPL(platform_bus_type);
 
-/**
- * platform_bus_get_pm_ops() - return pointer to busses dev_pm_ops
- *
- * This function can be used by platform code to get the current
- * set of dev_pm_ops functions used by the platform_bus_type.
- */
-const struct dev_pm_ops * __init platform_bus_get_pm_ops(void)
-{
-	return platform_bus_type.pm;
-}
-
-/**
- * platform_bus_set_pm_ops() - update dev_pm_ops for the platform_bus_type
- *
- * @pm: pointer to new dev_pm_ops struct to be used for platform_bus_type
- *
- * Platform code can override the dev_pm_ops methods of
- * platform_bus_type by using this function.  It is expected that
- * platform code will first do a platform_bus_get_pm_ops(), then
- * kmemdup it, then customize selected methods and pass a pointer to
- * the new struct dev_pm_ops to this function.
- *
- * Since platform-specific code is customizing methods for *all*
- * devices (not just platform-specific devices) it is expected that
- * any custom overrides of these functions will keep existing behavior
- * and simply extend it.  For example, any customization of the
- * runtime PM methods should continue to call the pm_generic_*
- * functions as the default ones do in addition to the
- * platform-specific behavior.
- */
-void __init platform_bus_set_pm_ops(const struct dev_pm_ops *pm)
-{
-	platform_bus_type.pm = pm;
-}
-
 int __init platform_bus_init(void)
 {
 	int error;
diff -druN linux-2.6.39-libre/drivers/base/power/clock_ops.c linux-3.0-rc7-libre/drivers/base/power/clock_ops.c
--- linux-2.6.39-libre/drivers/base/power/clock_ops.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/base/power/clock_ops.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,431 @@
+/*
+ * drivers/base/power/clock_ops.c - Generic clock manipulation PM callbacks
+ *
+ * Copyright (c) 2011 Rafael J. Wysocki <rjw@sisk.pl>, Renesas Electronics Corp.
+ *
+ * This file is released under the GPLv2.
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/io.h>
+#include <linux/pm.h>
+#include <linux/pm_runtime.h>
+#include <linux/clk.h>
+#include <linux/slab.h>
+#include <linux/err.h>
+
+#ifdef CONFIG_PM_RUNTIME
+
+struct pm_runtime_clk_data {
+	struct list_head clock_list;
+	struct mutex lock;
+};
+
+enum pce_status {
+	PCE_STATUS_NONE = 0,
+	PCE_STATUS_ACQUIRED,
+	PCE_STATUS_ENABLED,
+	PCE_STATUS_ERROR,
+};
+
+struct pm_clock_entry {
+	struct list_head node;
+	char *con_id;
+	struct clk *clk;
+	enum pce_status status;
+};
+
+static struct pm_runtime_clk_data *__to_prd(struct device *dev)
+{
+	return dev ? dev->power.subsys_data : NULL;
+}
+
+/**
+ * pm_runtime_clk_add - Start using a device clock for runtime PM.
+ * @dev: Device whose clock is going to be used for runtime PM.
+ * @con_id: Connection ID of the clock.
+ *
+ * Add the clock represented by @con_id to the list of clocks used for
+ * the runtime PM of @dev.
+ */
+int pm_runtime_clk_add(struct device *dev, const char *con_id)
+{
+	struct pm_runtime_clk_data *prd = __to_prd(dev);
+	struct pm_clock_entry *ce;
+
+	if (!prd)
+		return -EINVAL;
+
+	ce = kzalloc(sizeof(*ce), GFP_KERNEL);
+	if (!ce) {
+		dev_err(dev, "Not enough memory for clock entry.\n");
+		return -ENOMEM;
+	}
+
+	if (con_id) {
+		ce->con_id = kstrdup(con_id, GFP_KERNEL);
+		if (!ce->con_id) {
+			dev_err(dev,
+				"Not enough memory for clock connection ID.\n");
+			kfree(ce);
+			return -ENOMEM;
+		}
+	}
+
+	mutex_lock(&prd->lock);
+	list_add_tail(&ce->node, &prd->clock_list);
+	mutex_unlock(&prd->lock);
+	return 0;
+}
+
+/**
+ * __pm_runtime_clk_remove - Destroy runtime PM clock entry.
+ * @ce: Runtime PM clock entry to destroy.
+ *
+ * This routine must be called under the mutex protecting the runtime PM list
+ * of clocks corresponding the the @ce's device.
+ */
+static void __pm_runtime_clk_remove(struct pm_clock_entry *ce)
+{
+	if (!ce)
+		return;
+
+	list_del(&ce->node);
+
+	if (ce->status < PCE_STATUS_ERROR) {
+		if (ce->status == PCE_STATUS_ENABLED)
+			clk_disable(ce->clk);
+
+		if (ce->status >= PCE_STATUS_ACQUIRED)
+			clk_put(ce->clk);
+	}
+
+	if (ce->con_id)
+		kfree(ce->con_id);
+
+	kfree(ce);
+}
+
+/**
+ * pm_runtime_clk_remove - Stop using a device clock for runtime PM.
+ * @dev: Device whose clock should not be used for runtime PM any more.
+ * @con_id: Connection ID of the clock.
+ *
+ * Remove the clock represented by @con_id from the list of clocks used for
+ * the runtime PM of @dev.
+ */
+void pm_runtime_clk_remove(struct device *dev, const char *con_id)
+{
+	struct pm_runtime_clk_data *prd = __to_prd(dev);
+	struct pm_clock_entry *ce;
+
+	if (!prd)
+		return;
+
+	mutex_lock(&prd->lock);
+
+	list_for_each_entry(ce, &prd->clock_list, node) {
+		if (!con_id && !ce->con_id) {
+			__pm_runtime_clk_remove(ce);
+			break;
+		} else if (!con_id || !ce->con_id) {
+			continue;
+		} else if (!strcmp(con_id, ce->con_id)) {
+			__pm_runtime_clk_remove(ce);
+			break;
+		}
+	}
+
+	mutex_unlock(&prd->lock);
+}
+
+/**
+ * pm_runtime_clk_init - Initialize a device's list of runtime PM clocks.
+ * @dev: Device to initialize the list of runtime PM clocks for.
+ *
+ * Allocate a struct pm_runtime_clk_data object, initialize its lock member and
+ * make the @dev's power.subsys_data field point to it.
+ */
+int pm_runtime_clk_init(struct device *dev)
+{
+	struct pm_runtime_clk_data *prd;
+
+	prd = kzalloc(sizeof(*prd), GFP_KERNEL);
+	if (!prd) {
+		dev_err(dev, "Not enough memory fo runtime PM data.\n");
+		return -ENOMEM;
+	}
+
+	INIT_LIST_HEAD(&prd->clock_list);
+	mutex_init(&prd->lock);
+	dev->power.subsys_data = prd;
+	return 0;
+}
+
+/**
+ * pm_runtime_clk_destroy - Destroy a device's list of runtime PM clocks.
+ * @dev: Device to destroy the list of runtime PM clocks for.
+ *
+ * Clear the @dev's power.subsys_data field, remove the list of clock entries
+ * from the struct pm_runtime_clk_data object pointed to by it before and free
+ * that object.
+ */
+void pm_runtime_clk_destroy(struct device *dev)
+{
+	struct pm_runtime_clk_data *prd = __to_prd(dev);
+	struct pm_clock_entry *ce, *c;
+
+	if (!prd)
+		return;
+
+	dev->power.subsys_data = NULL;
+
+	mutex_lock(&prd->lock);
+
+	list_for_each_entry_safe_reverse(ce, c, &prd->clock_list, node)
+		__pm_runtime_clk_remove(ce);
+
+	mutex_unlock(&prd->lock);
+
+	kfree(prd);
+}
+
+/**
+ * pm_runtime_clk_acquire - Acquire a device clock.
+ * @dev: Device whose clock is to be acquired.
+ * @con_id: Connection ID of the clock.
+ */
+static void pm_runtime_clk_acquire(struct device *dev,
+				    struct pm_clock_entry *ce)
+{
+	ce->clk = clk_get(dev, ce->con_id);
+	if (IS_ERR(ce->clk)) {
+		ce->status = PCE_STATUS_ERROR;
+	} else {
+		ce->status = PCE_STATUS_ACQUIRED;
+		dev_dbg(dev, "Clock %s managed by runtime PM.\n", ce->con_id);
+	}
+}
+
+/**
+ * pm_runtime_clk_suspend - Disable clocks in a device's runtime PM clock list.
+ * @dev: Device to disable the clocks for.
+ */
+int pm_runtime_clk_suspend(struct device *dev)
+{
+	struct pm_runtime_clk_data *prd = __to_prd(dev);
+	struct pm_clock_entry *ce;
+
+	dev_dbg(dev, "%s()\n", __func__);
+
+	if (!prd)
+		return 0;
+
+	mutex_lock(&prd->lock);
+
+	list_for_each_entry_reverse(ce, &prd->clock_list, node) {
+		if (ce->status == PCE_STATUS_NONE)
+			pm_runtime_clk_acquire(dev, ce);
+
+		if (ce->status < PCE_STATUS_ERROR) {
+			clk_disable(ce->clk);
+			ce->status = PCE_STATUS_ACQUIRED;
+		}
+	}
+
+	mutex_unlock(&prd->lock);
+
+	return 0;
+}
+
+/**
+ * pm_runtime_clk_resume - Enable clocks in a device's runtime PM clock list.
+ * @dev: Device to enable the clocks for.
+ */
+int pm_runtime_clk_resume(struct device *dev)
+{
+	struct pm_runtime_clk_data *prd = __to_prd(dev);
+	struct pm_clock_entry *ce;
+
+	dev_dbg(dev, "%s()\n", __func__);
+
+	if (!prd)
+		return 0;
+
+	mutex_lock(&prd->lock);
+
+	list_for_each_entry(ce, &prd->clock_list, node) {
+		if (ce->status == PCE_STATUS_NONE)
+			pm_runtime_clk_acquire(dev, ce);
+
+		if (ce->status < PCE_STATUS_ERROR) {
+			clk_enable(ce->clk);
+			ce->status = PCE_STATUS_ENABLED;
+		}
+	}
+
+	mutex_unlock(&prd->lock);
+
+	return 0;
+}
+
+/**
+ * pm_runtime_clk_notify - Notify routine for device addition and removal.
+ * @nb: Notifier block object this function is a member of.
+ * @action: Operation being carried out by the caller.
+ * @data: Device the routine is being run for.
+ *
+ * For this function to work, @nb must be a member of an object of type
+ * struct pm_clk_notifier_block containing all of the requisite data.
+ * Specifically, the pwr_domain member of that object is copied to the device's
+ * pwr_domain field and its con_ids member is used to populate the device's list
+ * of runtime PM clocks, depending on @action.
+ *
+ * If the device's pwr_domain field is already populated with a value different
+ * from the one stored in the struct pm_clk_notifier_block object, the function
+ * does nothing.
+ */
+static int pm_runtime_clk_notify(struct notifier_block *nb,
+				 unsigned long action, void *data)
+{
+	struct pm_clk_notifier_block *clknb;
+	struct device *dev = data;
+	char **con_id;
+	int error;
+
+	dev_dbg(dev, "%s() %ld\n", __func__, action);
+
+	clknb = container_of(nb, struct pm_clk_notifier_block, nb);
+
+	switch (action) {
+	case BUS_NOTIFY_ADD_DEVICE:
+		if (dev->pwr_domain)
+			break;
+
+		error = pm_runtime_clk_init(dev);
+		if (error)
+			break;
+
+		dev->pwr_domain = clknb->pwr_domain;
+		if (clknb->con_ids[0]) {
+			for (con_id = clknb->con_ids; *con_id; con_id++)
+				pm_runtime_clk_add(dev, *con_id);
+		} else {
+			pm_runtime_clk_add(dev, NULL);
+		}
+
+		break;
+	case BUS_NOTIFY_DEL_DEVICE:
+		if (dev->pwr_domain != clknb->pwr_domain)
+			break;
+
+		dev->pwr_domain = NULL;
+		pm_runtime_clk_destroy(dev);
+		break;
+	}
+
+	return 0;
+}
+
+#else /* !CONFIG_PM_RUNTIME */
+
+/**
+ * enable_clock - Enable a device clock.
+ * @dev: Device whose clock is to be enabled.
+ * @con_id: Connection ID of the clock.
+ */
+static void enable_clock(struct device *dev, const char *con_id)
+{
+	struct clk *clk;
+
+	clk = clk_get(dev, con_id);
+	if (!IS_ERR(clk)) {
+		clk_enable(clk);
+		clk_put(clk);
+		dev_info(dev, "Runtime PM disabled, clock forced on.\n");
+	}
+}
+
+/**
+ * disable_clock - Disable a device clock.
+ * @dev: Device whose clock is to be disabled.
+ * @con_id: Connection ID of the clock.
+ */
+static void disable_clock(struct device *dev, const char *con_id)
+{
+	struct clk *clk;
+
+	clk = clk_get(dev, con_id);
+	if (!IS_ERR(clk)) {
+		clk_disable(clk);
+		clk_put(clk);
+		dev_info(dev, "Runtime PM disabled, clock forced off.\n");
+	}
+}
+
+/**
+ * pm_runtime_clk_notify - Notify routine for device addition and removal.
+ * @nb: Notifier block object this function is a member of.
+ * @action: Operation being carried out by the caller.
+ * @data: Device the routine is being run for.
+ *
+ * For this function to work, @nb must be a member of an object of type
+ * struct pm_clk_notifier_block containing all of the requisite data.
+ * Specifically, the con_ids member of that object is used to enable or disable
+ * the device's clocks, depending on @action.
+ */
+static int pm_runtime_clk_notify(struct notifier_block *nb,
+				 unsigned long action, void *data)
+{
+	struct pm_clk_notifier_block *clknb;
+	struct device *dev = data;
+	char **con_id;
+
+	dev_dbg(dev, "%s() %ld\n", __func__, action);
+
+	clknb = container_of(nb, struct pm_clk_notifier_block, nb);
+
+	switch (action) {
+	case BUS_NOTIFY_BIND_DRIVER:
+		if (clknb->con_ids[0]) {
+			for (con_id = clknb->con_ids; *con_id; con_id++)
+				enable_clock(dev, *con_id);
+		} else {
+			enable_clock(dev, NULL);
+		}
+		break;
+	case BUS_NOTIFY_UNBOUND_DRIVER:
+		if (clknb->con_ids[0]) {
+			for (con_id = clknb->con_ids; *con_id; con_id++)
+				disable_clock(dev, *con_id);
+		} else {
+			disable_clock(dev, NULL);
+		}
+		break;
+	}
+
+	return 0;
+}
+
+#endif /* !CONFIG_PM_RUNTIME */
+
+/**
+ * pm_runtime_clk_add_notifier - Add bus type notifier for runtime PM clocks.
+ * @bus: Bus type to add the notifier to.
+ * @clknb: Notifier to be added to the given bus type.
+ *
+ * The nb member of @clknb is not expected to be initialized and its
+ * notifier_call member will be replaced with pm_runtime_clk_notify().  However,
+ * the remaining members of @clknb should be populated prior to calling this
+ * routine.
+ */
+void pm_runtime_clk_add_notifier(struct bus_type *bus,
+				 struct pm_clk_notifier_block *clknb)
+{
+	if (!bus || !clknb)
+		return;
+
+	clknb->nb.notifier_call = pm_runtime_clk_notify;
+	bus_register_notifier(bus, &clknb->nb);
+}
diff -druN linux-2.6.39-libre/drivers/base/power/generic_ops.c linux-3.0-rc7-libre/drivers/base/power/generic_ops.c
--- linux-2.6.39-libre/drivers/base/power/generic_ops.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/base/power/generic_ops.c	2011-07-11 19:51:52.000000000 -0400
@@ -74,6 +74,23 @@
 
 #ifdef CONFIG_PM_SLEEP
 /**
+ * pm_generic_prepare - Generic routine preparing a device for power transition.
+ * @dev: Device to prepare.
+ *
+ * Prepare a device for a system-wide power transition.
+ */
+int pm_generic_prepare(struct device *dev)
+{
+	struct device_driver *drv = dev->driver;
+	int ret = 0;
+
+	if (drv && drv->pm && drv->pm->prepare)
+		ret = drv->pm->prepare(dev);
+
+	return ret;
+}
+
+/**
  * __pm_generic_call - Generic suspend/freeze/poweroff/thaw subsystem callback.
  * @dev: Device to handle.
  * @event: PM transition of the system under way.
@@ -213,16 +230,38 @@
 	return __pm_generic_resume(dev, PM_EVENT_RESTORE);
 }
 EXPORT_SYMBOL_GPL(pm_generic_restore);
+
+/**
+ * pm_generic_complete - Generic routine competing a device power transition.
+ * @dev: Device to handle.
+ *
+ * Complete a device power transition during a system-wide power transition.
+ */
+void pm_generic_complete(struct device *dev)
+{
+	struct device_driver *drv = dev->driver;
+
+	if (drv && drv->pm && drv->pm->complete)
+		drv->pm->complete(dev);
+
+	/*
+	 * Let runtime PM try to suspend devices that haven't been in use before
+	 * going into the system-wide sleep state we're resuming from.
+	 */
+	pm_runtime_idle(dev);
+}
 #endif /* CONFIG_PM_SLEEP */
 
 struct dev_pm_ops generic_subsys_pm_ops = {
 #ifdef CONFIG_PM_SLEEP
+	.prepare = pm_generic_prepare,
 	.suspend = pm_generic_suspend,
 	.resume = pm_generic_resume,
 	.freeze = pm_generic_freeze,
 	.thaw = pm_generic_thaw,
 	.poweroff = pm_generic_poweroff,
 	.restore = pm_generic_restore,
+	.complete = pm_generic_complete,
 #endif
 #ifdef CONFIG_PM_RUNTIME
 	.runtime_suspend = pm_generic_runtime_suspend,
diff -druN linux-2.6.39-libre/drivers/base/power/main.c linux-3.0-rc7-libre/drivers/base/power/main.c
--- linux-2.6.39-libre/drivers/base/power/main.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/base/power/main.c	2011-07-11 19:51:52.000000000 -0400
@@ -57,7 +57,8 @@
  */
 void device_pm_init(struct device *dev)
 {
-	dev->power.in_suspend = false;
+	dev->power.is_prepared = false;
+	dev->power.is_suspended = false;
 	init_completion(&dev->power.completion);
 	complete_all(&dev->power.completion);
 	dev->power.wakeup = NULL;
@@ -91,7 +92,7 @@
 	pr_debug("PM: Adding info for %s:%s\n",
 		 dev->bus ? dev->bus->name : "No Bus", dev_name(dev));
 	mutex_lock(&dpm_list_mtx);
-	if (dev->parent && dev->parent->power.in_suspend)
+	if (dev->parent && dev->parent->power.is_prepared)
 		dev_warn(dev, "parent %s should not be sleeping\n",
 			dev_name(dev->parent));
 	list_add_tail(&dev->power.entry, &dpm_list);
@@ -426,10 +427,8 @@
 
 	if (dev->pwr_domain) {
 		pm_dev_dbg(dev, state, "EARLY power domain ");
-		pm_noirq_op(dev, &dev->pwr_domain->ops, state);
-	}
-
-	if (dev->type && dev->type->pm) {
+		error = pm_noirq_op(dev, &dev->pwr_domain->ops, state);
+	} else if (dev->type && dev->type->pm) {
 		pm_dev_dbg(dev, state, "EARLY type ");
 		error = pm_noirq_op(dev, dev->type->pm, state);
 	} else if (dev->class && dev->class->pm) {
@@ -513,11 +512,19 @@
 	dpm_wait(dev->parent, async);
 	device_lock(dev);
 
-	dev->power.in_suspend = false;
+	/*
+	 * This is a fib.  But we'll allow new children to be added below
+	 * a resumed device, even if the device hasn't been completed yet.
+	 */
+	dev->power.is_prepared = false;
+
+	if (!dev->power.is_suspended)
+		goto Unlock;
 
 	if (dev->pwr_domain) {
 		pm_dev_dbg(dev, state, "power domain ");
-		pm_op(dev, &dev->pwr_domain->ops, state);
+		error = pm_op(dev, &dev->pwr_domain->ops, state);
+		goto End;
 	}
 
 	if (dev->type && dev->type->pm) {
@@ -549,6 +556,9 @@
 	}
 
  End:
+	dev->power.is_suspended = false;
+
+ Unlock:
 	device_unlock(dev);
 	complete_all(&dev->power.completion);
 
@@ -580,11 +590,13 @@
  * Execute the appropriate "resume" callback for all devices whose status
  * indicates that they are suspended.
  */
-static void dpm_resume(pm_message_t state)
+void dpm_resume(pm_message_t state)
 {
 	struct device *dev;
 	ktime_t starttime = ktime_get();
 
+	might_sleep();
+
 	mutex_lock(&dpm_list_mtx);
 	pm_transition = state;
 	async_error = 0;
@@ -629,12 +641,11 @@
 {
 	device_lock(dev);
 
-	if (dev->pwr_domain && dev->pwr_domain->ops.complete) {
+	if (dev->pwr_domain) {
 		pm_dev_dbg(dev, state, "completing power domain ");
-		dev->pwr_domain->ops.complete(dev);
-	}
-
-	if (dev->type && dev->type->pm) {
+		if (dev->pwr_domain->ops.complete)
+			dev->pwr_domain->ops.complete(dev);
+	} else if (dev->type && dev->type->pm) {
 		pm_dev_dbg(dev, state, "completing type ");
 		if (dev->type->pm->complete)
 			dev->type->pm->complete(dev);
@@ -658,17 +669,19 @@
  * Execute the ->complete() callbacks for all devices whose PM status is not
  * DPM_ON (this allows new devices to be registered).
  */
-static void dpm_complete(pm_message_t state)
+void dpm_complete(pm_message_t state)
 {
 	struct list_head list;
 
+	might_sleep();
+
 	INIT_LIST_HEAD(&list);
 	mutex_lock(&dpm_list_mtx);
 	while (!list_empty(&dpm_prepared_list)) {
 		struct device *dev = to_device(dpm_prepared_list.prev);
 
 		get_device(dev);
-		dev->power.in_suspend = false;
+		dev->power.is_prepared = false;
 		list_move(&dev->power.entry, &list);
 		mutex_unlock(&dpm_list_mtx);
 
@@ -690,7 +703,6 @@
  */
 void dpm_resume_end(pm_message_t state)
 {
-	might_sleep();
 	dpm_resume(state);
 	dpm_complete(state);
 }
@@ -732,7 +744,12 @@
 {
 	int error;
 
-	if (dev->type && dev->type->pm) {
+	if (dev->pwr_domain) {
+		pm_dev_dbg(dev, state, "LATE power domain ");
+		error = pm_noirq_op(dev, &dev->pwr_domain->ops, state);
+		if (error)
+			return error;
+	} else if (dev->type && dev->type->pm) {
 		pm_dev_dbg(dev, state, "LATE type ");
 		error = pm_noirq_op(dev, dev->type->pm, state);
 		if (error)
@@ -749,11 +766,6 @@
 			return error;
 	}
 
-	if (dev->pwr_domain) {
-		pm_dev_dbg(dev, state, "LATE power domain ");
-		pm_noirq_op(dev, &dev->pwr_domain->ops, state);
-	}
-
 	return 0;
 }
 
@@ -834,28 +846,34 @@
 	device_lock(dev);
 
 	if (async_error)
-		goto End;
+		goto Unlock;
 
 	if (pm_wakeup_pending()) {
 		async_error = -EBUSY;
+		goto Unlock;
+	}
+
+	if (dev->pwr_domain) {
+		pm_dev_dbg(dev, state, "power domain ");
+		error = pm_op(dev, &dev->pwr_domain->ops, state);
 		goto End;
 	}
 
 	if (dev->type && dev->type->pm) {
 		pm_dev_dbg(dev, state, "type ");
 		error = pm_op(dev, dev->type->pm, state);
-		goto Domain;
+		goto End;
 	}
 
 	if (dev->class) {
 		if (dev->class->pm) {
 			pm_dev_dbg(dev, state, "class ");
 			error = pm_op(dev, dev->class->pm, state);
-			goto Domain;
+			goto End;
 		} else if (dev->class->suspend) {
 			pm_dev_dbg(dev, state, "legacy class ");
 			error = legacy_suspend(dev, state, dev->class->suspend);
-			goto Domain;
+			goto End;
 		}
 	}
 
@@ -869,13 +887,10 @@
 		}
 	}
 
- Domain:
-	if (!error && dev->pwr_domain) {
-		pm_dev_dbg(dev, state, "power domain ");
-		pm_op(dev, &dev->pwr_domain->ops, state);
-	}
-
  End:
+	dev->power.is_suspended = !error;
+
+ Unlock:
 	device_unlock(dev);
 	complete_all(&dev->power.completion);
 
@@ -914,11 +929,13 @@
  * dpm_suspend - Execute "suspend" callbacks for all non-sysdev devices.
  * @state: PM transition of the system being carried out.
  */
-static int dpm_suspend(pm_message_t state)
+int dpm_suspend(pm_message_t state)
 {
 	ktime_t starttime = ktime_get();
 	int error = 0;
 
+	might_sleep();
+
 	mutex_lock(&dpm_list_mtx);
 	pm_transition = state;
 	async_error = 0;
@@ -965,7 +982,14 @@
 
 	device_lock(dev);
 
-	if (dev->type && dev->type->pm) {
+	if (dev->pwr_domain) {
+		pm_dev_dbg(dev, state, "preparing power domain ");
+		if (dev->pwr_domain->ops.prepare)
+			error = dev->pwr_domain->ops.prepare(dev);
+		suspend_report_result(dev->pwr_domain->ops.prepare, error);
+		if (error)
+			goto End;
+	} else if (dev->type && dev->type->pm) {
 		pm_dev_dbg(dev, state, "preparing type ");
 		if (dev->type->pm->prepare)
 			error = dev->type->pm->prepare(dev);
@@ -984,13 +1008,6 @@
 		if (dev->bus->pm->prepare)
 			error = dev->bus->pm->prepare(dev);
 		suspend_report_result(dev->bus->pm->prepare, error);
-		if (error)
-			goto End;
-	}
-
-	if (dev->pwr_domain && dev->pwr_domain->ops.prepare) {
-		pm_dev_dbg(dev, state, "preparing power domain ");
-		dev->pwr_domain->ops.prepare(dev);
 	}
 
  End:
@@ -1005,10 +1022,12 @@
  *
  * Execute the ->prepare() callback(s) for all devices.
  */
-static int dpm_prepare(pm_message_t state)
+int dpm_prepare(pm_message_t state)
 {
 	int error = 0;
 
+	might_sleep();
+
 	mutex_lock(&dpm_list_mtx);
 	while (!list_empty(&dpm_list)) {
 		struct device *dev = to_device(dpm_list.next);
@@ -1037,7 +1056,7 @@
 			put_device(dev);
 			break;
 		}
-		dev->power.in_suspend = true;
+		dev->power.is_prepared = true;
 		if (!list_empty(&dev->power.entry))
 			list_move_tail(&dev->power.entry, &dpm_prepared_list);
 		put_device(dev);
@@ -1057,7 +1076,6 @@
 {
 	int error;
 
-	might_sleep();
 	error = dpm_prepare(state);
 	if (!error)
 		error = dpm_suspend(state);
diff -druN linux-2.6.39-libre/drivers/base/power/Makefile linux-3.0-rc7-libre/drivers/base/power/Makefile
--- linux-2.6.39-libre/drivers/base/power/Makefile	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/base/power/Makefile	2011-07-11 19:51:52.000000000 -0400
@@ -3,6 +3,6 @@
 obj-$(CONFIG_PM_RUNTIME)	+= runtime.o
 obj-$(CONFIG_PM_TRACE_RTC)	+= trace.o
 obj-$(CONFIG_PM_OPP)	+= opp.o
+obj-$(CONFIG_HAVE_CLK)	+= clock_ops.o
 
-ccflags-$(CONFIG_DEBUG_DRIVER) := -DDEBUG
-ccflags-$(CONFIG_PM_VERBOSE)   += -DDEBUG
+ccflags-$(CONFIG_DEBUG_DRIVER) := -DDEBUG
\ No newline at end of file
diff -druN linux-2.6.39-libre/drivers/base/power/runtime.c linux-3.0-rc7-libre/drivers/base/power/runtime.c
--- linux-2.6.39-libre/drivers/base/power/runtime.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/base/power/runtime.c	2011-07-11 19:51:52.000000000 -0400
@@ -168,7 +168,6 @@
 static int rpm_idle(struct device *dev, int rpmflags)
 {
 	int (*callback)(struct device *);
-	int (*domain_callback)(struct device *);
 	int retval;
 
 	retval = rpm_check_suspend_allowed(dev);
@@ -214,7 +213,9 @@
 
 	dev->power.idle_notification = true;
 
-	if (dev->type && dev->type->pm)
+	if (dev->pwr_domain)
+		callback = dev->pwr_domain->ops.runtime_idle;
+	else if (dev->type && dev->type->pm)
 		callback = dev->type->pm->runtime_idle;
 	else if (dev->class && dev->class->pm)
 		callback = dev->class->pm->runtime_idle;
@@ -223,19 +224,10 @@
 	else
 		callback = NULL;
 
-	if (dev->pwr_domain)
-		domain_callback = dev->pwr_domain->ops.runtime_idle;
-	else
-		domain_callback = NULL;
-
-	if (callback || domain_callback) {
+	if (callback) {
 		spin_unlock_irq(&dev->power.lock);
 
-		if (domain_callback)
-			retval = domain_callback(dev);
-
-		if (!retval && callback)
-			callback(dev);
+		callback(dev);
 
 		spin_lock_irq(&dev->power.lock);
 	}
@@ -382,7 +374,9 @@
 
 	__update_runtime_status(dev, RPM_SUSPENDING);
 
-	if (dev->type && dev->type->pm)
+	if (dev->pwr_domain)
+		callback = dev->pwr_domain->ops.runtime_suspend;
+	else if (dev->type && dev->type->pm)
 		callback = dev->type->pm->runtime_suspend;
 	else if (dev->class && dev->class->pm)
 		callback = dev->class->pm->runtime_suspend;
@@ -400,8 +394,6 @@
 		else
 			pm_runtime_cancel_pending(dev);
 	} else {
-		if (dev->pwr_domain)
-			rpm_callback(dev->pwr_domain->ops.runtime_suspend, dev);
  no_callback:
 		__update_runtime_status(dev, RPM_SUSPENDED);
 		pm_runtime_deactivate_timer(dev);
@@ -582,9 +574,8 @@
 	__update_runtime_status(dev, RPM_RESUMING);
 
 	if (dev->pwr_domain)
-		rpm_callback(dev->pwr_domain->ops.runtime_resume, dev);
-
-	if (dev->type && dev->type->pm)
+		callback = dev->pwr_domain->ops.runtime_resume;
+	else if (dev->type && dev->type->pm)
 		callback = dev->type->pm->runtime_resume;
 	else if (dev->class && dev->class->pm)
 		callback = dev->class->pm->runtime_resume;
diff -druN linux-2.6.39-libre/drivers/base/power/sysfs.c linux-3.0-rc7-libre/drivers/base/power/sysfs.c
--- linux-2.6.39-libre/drivers/base/power/sysfs.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/base/power/sysfs.c	2011-07-11 19:51:52.000000000 -0400
@@ -212,8 +212,9 @@
 static DEVICE_ATTR(autosuspend_delay_ms, 0644, autosuspend_delay_ms_show,
 		autosuspend_delay_ms_store);
 
-#endif
+#endif /* CONFIG_PM_RUNTIME */
 
+#ifdef CONFIG_PM_SLEEP
 static ssize_t
 wake_show(struct device * dev, struct device_attribute *attr, char * buf)
 {
@@ -248,7 +249,6 @@
 
 static DEVICE_ATTR(wakeup, 0644, wake_show, wake_store);
 
-#ifdef CONFIG_PM_SLEEP
 static ssize_t wakeup_count_show(struct device *dev,
 				struct device_attribute *attr, char *buf)
 {
diff -druN linux-2.6.39-libre/drivers/base/power/wakeup.c linux-3.0-rc7-libre/drivers/base/power/wakeup.c
--- linux-2.6.39-libre/drivers/base/power/wakeup.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/base/power/wakeup.c	2011-07-11 19:51:52.000000000 -0400
@@ -110,7 +110,6 @@
 	spin_lock_irq(&events_lock);
 	list_add_rcu(&ws->entry, &wakeup_sources);
 	spin_unlock_irq(&events_lock);
-	synchronize_rcu();
 }
 EXPORT_SYMBOL_GPL(wakeup_source_add);
 
diff -druN linux-2.6.39-libre/drivers/base/sys.c linux-3.0-rc7-libre/drivers/base/sys.c
--- linux-2.6.39-libre/drivers/base/sys.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/base/sys.c	2011-07-11 19:51:52.000000000 -0400
@@ -328,203 +328,8 @@
 	kobject_put(&sysdev->kobj);
 }
 
-
-#ifndef CONFIG_ARCH_NO_SYSDEV_OPS
-/**
- *	sysdev_shutdown - Shut down all system devices.
- *
- *	Loop over each class of system devices, and the devices in each
- *	of those classes. For each device, we call the shutdown method for
- *	each driver registered for the device - the auxiliaries,
- *	and the class driver.
- *
- *	Note: The list is iterated in reverse order, so that we shut down
- *	child devices before we shut down their parents. The list ordering
- *	is guaranteed by virtue of the fact that child devices are registered
- *	after their parents.
- */
-void sysdev_shutdown(void)
-{
-	struct sysdev_class *cls;
-
-	pr_debug("Shutting Down System Devices\n");
-
-	mutex_lock(&sysdev_drivers_lock);
-	list_for_each_entry_reverse(cls, &system_kset->list, kset.kobj.entry) {
-		struct sys_device *sysdev;
-
-		pr_debug("Shutting down type '%s':\n",
-			 kobject_name(&cls->kset.kobj));
-
-		list_for_each_entry(sysdev, &cls->kset.list, kobj.entry) {
-			struct sysdev_driver *drv;
-			pr_debug(" %s\n", kobject_name(&sysdev->kobj));
-
-			/* Call auxiliary drivers first */
-			list_for_each_entry(drv, &cls->drivers, entry) {
-				if (drv->shutdown)
-					drv->shutdown(sysdev);
-			}
-
-			/* Now call the generic one */
-			if (cls->shutdown)
-				cls->shutdown(sysdev);
-		}
-	}
-	mutex_unlock(&sysdev_drivers_lock);
-}
-
-static void __sysdev_resume(struct sys_device *dev)
-{
-	struct sysdev_class *cls = dev->cls;
-	struct sysdev_driver *drv;
-
-	/* First, call the class-specific one */
-	if (cls->resume)
-		cls->resume(dev);
-	WARN_ONCE(!irqs_disabled(),
-		"Interrupts enabled after %pF\n", cls->resume);
-
-	/* Call auxiliary drivers next. */
-	list_for_each_entry(drv, &cls->drivers, entry) {
-		if (drv->resume)
-			drv->resume(dev);
-		WARN_ONCE(!irqs_disabled(),
-			"Interrupts enabled after %pF\n", drv->resume);
-	}
-}
-
-/**
- *	sysdev_suspend - Suspend all system devices.
- *	@state:		Power state to enter.
- *
- *	We perform an almost identical operation as sysdev_shutdown()
- *	above, though calling ->suspend() instead. Interrupts are disabled
- *	when this called. Devices are responsible for both saving state and
- *	quiescing or powering down the device.
- *
- *	This is only called by the device PM core, so we let them handle
- *	all synchronization.
- */
-int sysdev_suspend(pm_message_t state)
-{
-	struct sysdev_class *cls;
-	struct sys_device *sysdev, *err_dev;
-	struct sysdev_driver *drv, *err_drv;
-	int ret;
-
-	pr_debug("Checking wake-up interrupts\n");
-
-	/* Return error code if there are any wake-up interrupts pending */
-	ret = check_wakeup_irqs();
-	if (ret)
-		return ret;
-
-	WARN_ONCE(!irqs_disabled(),
-		"Interrupts enabled while suspending system devices\n");
-
-	pr_debug("Suspending System Devices\n");
-
-	list_for_each_entry_reverse(cls, &system_kset->list, kset.kobj.entry) {
-		pr_debug("Suspending type '%s':\n",
-			 kobject_name(&cls->kset.kobj));
-
-		list_for_each_entry(sysdev, &cls->kset.list, kobj.entry) {
-			pr_debug(" %s\n", kobject_name(&sysdev->kobj));
-
-			/* Call auxiliary drivers first */
-			list_for_each_entry(drv, &cls->drivers, entry) {
-				if (drv->suspend) {
-					ret = drv->suspend(sysdev, state);
-					if (ret)
-						goto aux_driver;
-				}
-				WARN_ONCE(!irqs_disabled(),
-					"Interrupts enabled after %pF\n",
-					drv->suspend);
-			}
-
-			/* Now call the generic one */
-			if (cls->suspend) {
-				ret = cls->suspend(sysdev, state);
-				if (ret)
-					goto cls_driver;
-				WARN_ONCE(!irqs_disabled(),
-					"Interrupts enabled after %pF\n",
-					cls->suspend);
-			}
-		}
-	}
-	return 0;
-	/* resume current sysdev */
-cls_driver:
-	drv = NULL;
-	printk(KERN_ERR "Class suspend failed for %s: %d\n",
-		kobject_name(&sysdev->kobj), ret);
-
-aux_driver:
-	if (drv)
-		printk(KERN_ERR "Class driver suspend failed for %s: %d\n",
-				kobject_name(&sysdev->kobj), ret);
-	list_for_each_entry(err_drv, &cls->drivers, entry) {
-		if (err_drv == drv)
-			break;
-		if (err_drv->resume)
-			err_drv->resume(sysdev);
-	}
-
-	/* resume other sysdevs in current class */
-	list_for_each_entry(err_dev, &cls->kset.list, kobj.entry) {
-		if (err_dev == sysdev)
-			break;
-		pr_debug(" %s\n", kobject_name(&err_dev->kobj));
-		__sysdev_resume(err_dev);
-	}
-
-	/* resume other classes */
-	list_for_each_entry_continue(cls, &system_kset->list, kset.kobj.entry) {
-		list_for_each_entry(err_dev, &cls->kset.list, kobj.entry) {
-			pr_debug(" %s\n", kobject_name(&err_dev->kobj));
-			__sysdev_resume(err_dev);
-		}
-	}
-	return ret;
-}
-EXPORT_SYMBOL_GPL(sysdev_suspend);
-
-/**
- *	sysdev_resume - Bring system devices back to life.
- *
- *	Similar to sysdev_suspend(), but we iterate the list forwards
- *	to guarantee that parent devices are resumed before their children.
- *
- *	Note: Interrupts are disabled when called.
- */
-int sysdev_resume(void)
-{
-	struct sysdev_class *cls;
-
-	WARN_ONCE(!irqs_disabled(),
-		"Interrupts enabled while resuming system devices\n");
-
-	pr_debug("Resuming System Devices\n");
-
-	list_for_each_entry(cls, &system_kset->list, kset.kobj.entry) {
-		struct sys_device *sysdev;
-
-		pr_debug("Resuming type '%s':\n",
-			 kobject_name(&cls->kset.kobj));
-
-		list_for_each_entry(sysdev, &cls->kset.list, kobj.entry) {
-			pr_debug(" %s\n", kobject_name(&sysdev->kobj));
-
-			__sysdev_resume(sysdev);
-		}
-	}
-	return 0;
-}
-EXPORT_SYMBOL_GPL(sysdev_resume);
-#endif /* CONFIG_ARCH_NO_SYSDEV_OPS */
+EXPORT_SYMBOL_GPL(sysdev_register);
+EXPORT_SYMBOL_GPL(sysdev_unregister);
 
 int __init system_bus_init(void)
 {
@@ -534,9 +339,6 @@
 	return 0;
 }
 
-EXPORT_SYMBOL_GPL(sysdev_register);
-EXPORT_SYMBOL_GPL(sysdev_unregister);
-
 #define to_ext_attr(x) container_of(x, struct sysdev_ext_attribute, attr)
 
 ssize_t sysdev_store_ulong(struct sys_device *sysdev,
diff -druN linux-2.6.39-libre/drivers/base/syscore.c linux-3.0-rc7-libre/drivers/base/syscore.c
--- linux-2.6.39-libre/drivers/base/syscore.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/base/syscore.c	2011-07-11 19:51:52.000000000 -0400
@@ -9,6 +9,7 @@
 #include <linux/syscore_ops.h>
 #include <linux/mutex.h>
 #include <linux/module.h>
+#include <linux/interrupt.h>
 
 static LIST_HEAD(syscore_ops_list);
 static DEFINE_MUTEX(syscore_ops_lock);
@@ -48,6 +49,13 @@
 	struct syscore_ops *ops;
 	int ret = 0;
 
+	pr_debug("Checking wakeup interrupts\n");
+
+	/* Return error code if there are any wakeup interrupts pending. */
+	ret = check_wakeup_irqs();
+	if (ret)
+		return ret;
+
 	WARN_ONCE(!irqs_disabled(),
 		"Interrupts enabled before system core suspend.\n");
 
diff -druN linux-2.6.39-libre/drivers/bcma/bcma_private.h linux-3.0-rc7-libre/drivers/bcma/bcma_private.h
--- linux-2.6.39-libre/drivers/bcma/bcma_private.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/bcma/bcma_private.h	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,28 @@
+#ifndef LINUX_BCMA_PRIVATE_H_
+#define LINUX_BCMA_PRIVATE_H_
+
+#ifndef pr_fmt
+#define pr_fmt(fmt)		KBUILD_MODNAME ": " fmt
+#endif
+
+#include <linux/bcma/bcma.h>
+#include <linux/delay.h>
+
+#define BCMA_CORE_SIZE		0x1000
+
+struct bcma_bus;
+
+/* main.c */
+extern int bcma_bus_register(struct bcma_bus *bus);
+extern void bcma_bus_unregister(struct bcma_bus *bus);
+
+/* scan.c */
+int bcma_bus_scan(struct bcma_bus *bus);
+
+#ifdef CONFIG_BCMA_HOST_PCI
+/* host_pci.c */
+extern int __init bcma_host_pci_init(void);
+extern void __exit bcma_host_pci_exit(void);
+#endif /* CONFIG_BCMA_HOST_PCI */
+
+#endif
diff -druN linux-2.6.39-libre/drivers/bcma/core.c linux-3.0-rc7-libre/drivers/bcma/core.c
--- linux-2.6.39-libre/drivers/bcma/core.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/bcma/core.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,51 @@
+/*
+ * Broadcom specific AMBA
+ * Core ops
+ *
+ * Licensed under the GNU/GPL. See COPYING for details.
+ */
+
+#include "bcma_private.h"
+#include <linux/bcma/bcma.h>
+
+bool bcma_core_is_enabled(struct bcma_device *core)
+{
+	if ((bcma_aread32(core, BCMA_IOCTL) & (BCMA_IOCTL_CLK | BCMA_IOCTL_FGC))
+	    != BCMA_IOCTL_CLK)
+		return false;
+	if (bcma_aread32(core, BCMA_RESET_CTL) & BCMA_RESET_CTL_RESET)
+		return false;
+	return true;
+}
+EXPORT_SYMBOL_GPL(bcma_core_is_enabled);
+
+static void bcma_core_disable(struct bcma_device *core, u32 flags)
+{
+	if (bcma_aread32(core, BCMA_RESET_CTL) & BCMA_RESET_CTL_RESET)
+		return;
+
+	bcma_awrite32(core, BCMA_IOCTL, flags);
+	bcma_aread32(core, BCMA_IOCTL);
+	udelay(10);
+
+	bcma_awrite32(core, BCMA_RESET_CTL, BCMA_RESET_CTL_RESET);
+	udelay(1);
+}
+
+int bcma_core_enable(struct bcma_device *core, u32 flags)
+{
+	bcma_core_disable(core, flags);
+
+	bcma_awrite32(core, BCMA_IOCTL, (BCMA_IOCTL_CLK | BCMA_IOCTL_FGC | flags));
+	bcma_aread32(core, BCMA_IOCTL);
+
+	bcma_awrite32(core, BCMA_RESET_CTL, 0);
+	udelay(1);
+
+	bcma_awrite32(core, BCMA_IOCTL, (BCMA_IOCTL_CLK | flags));
+	bcma_aread32(core, BCMA_IOCTL);
+	udelay(1);
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(bcma_core_enable);
diff -druN linux-2.6.39-libre/drivers/bcma/driver_chipcommon.c linux-3.0-rc7-libre/drivers/bcma/driver_chipcommon.c
--- linux-2.6.39-libre/drivers/bcma/driver_chipcommon.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/bcma/driver_chipcommon.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,89 @@
+/*
+ * Broadcom specific AMBA
+ * ChipCommon core driver
+ *
+ * Copyright 2005, Broadcom Corporation
+ * Copyright 2006, 2007, Michael Buesch <mb@bu3sch.de>
+ *
+ * Licensed under the GNU/GPL. See COPYING for details.
+ */
+
+#include "bcma_private.h"
+#include <linux/bcma/bcma.h>
+
+static inline u32 bcma_cc_write32_masked(struct bcma_drv_cc *cc, u16 offset,
+					 u32 mask, u32 value)
+{
+	value &= mask;
+	value |= bcma_cc_read32(cc, offset) & ~mask;
+	bcma_cc_write32(cc, offset, value);
+
+	return value;
+}
+
+void bcma_core_chipcommon_init(struct bcma_drv_cc *cc)
+{
+	if (cc->core->id.rev >= 11)
+		cc->status = bcma_cc_read32(cc, BCMA_CC_CHIPSTAT);
+	cc->capabilities = bcma_cc_read32(cc, BCMA_CC_CAP);
+	if (cc->core->id.rev >= 35)
+		cc->capabilities_ext = bcma_cc_read32(cc, BCMA_CC_CAP_EXT);
+
+	if (cc->core->id.rev >= 20) {
+		bcma_cc_write32(cc, BCMA_CC_GPIOPULLUP, 0);
+		bcma_cc_write32(cc, BCMA_CC_GPIOPULLDOWN, 0);
+	}
+
+	if (cc->capabilities & BCMA_CC_CAP_PMU)
+		bcma_pmu_init(cc);
+	if (cc->capabilities & BCMA_CC_CAP_PCTL)
+		pr_err("Power control not implemented!\n");
+}
+
+/* Set chip watchdog reset timer to fire in 'ticks' backplane cycles */
+void bcma_chipco_watchdog_timer_set(struct bcma_drv_cc *cc, u32 ticks)
+{
+	/* instant NMI */
+	bcma_cc_write32(cc, BCMA_CC_WATCHDOG, ticks);
+}
+
+void bcma_chipco_irq_mask(struct bcma_drv_cc *cc, u32 mask, u32 value)
+{
+	bcma_cc_write32_masked(cc, BCMA_CC_IRQMASK, mask, value);
+}
+
+u32 bcma_chipco_irq_status(struct bcma_drv_cc *cc, u32 mask)
+{
+	return bcma_cc_read32(cc, BCMA_CC_IRQSTAT) & mask;
+}
+
+u32 bcma_chipco_gpio_in(struct bcma_drv_cc *cc, u32 mask)
+{
+	return bcma_cc_read32(cc, BCMA_CC_GPIOIN) & mask;
+}
+
+u32 bcma_chipco_gpio_out(struct bcma_drv_cc *cc, u32 mask, u32 value)
+{
+	return bcma_cc_write32_masked(cc, BCMA_CC_GPIOOUT, mask, value);
+}
+
+u32 bcma_chipco_gpio_outen(struct bcma_drv_cc *cc, u32 mask, u32 value)
+{
+	return bcma_cc_write32_masked(cc, BCMA_CC_GPIOOUTEN, mask, value);
+}
+
+u32 bcma_chipco_gpio_control(struct bcma_drv_cc *cc, u32 mask, u32 value)
+{
+	return bcma_cc_write32_masked(cc, BCMA_CC_GPIOCTL, mask, value);
+}
+EXPORT_SYMBOL_GPL(bcma_chipco_gpio_control);
+
+u32 bcma_chipco_gpio_intmask(struct bcma_drv_cc *cc, u32 mask, u32 value)
+{
+	return bcma_cc_write32_masked(cc, BCMA_CC_GPIOIRQ, mask, value);
+}
+
+u32 bcma_chipco_gpio_polarity(struct bcma_drv_cc *cc, u32 mask, u32 value)
+{
+	return bcma_cc_write32_masked(cc, BCMA_CC_GPIOPOL, mask, value);
+}
diff -druN linux-2.6.39-libre/drivers/bcma/driver_chipcommon_pmu.c linux-3.0-rc7-libre/drivers/bcma/driver_chipcommon_pmu.c
--- linux-2.6.39-libre/drivers/bcma/driver_chipcommon_pmu.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/bcma/driver_chipcommon_pmu.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,134 @@
+/*
+ * Broadcom specific AMBA
+ * ChipCommon Power Management Unit driver
+ *
+ * Copyright 2009, Michael Buesch <mb@bu3sch.de>
+ * Copyright 2007, Broadcom Corporation
+ *
+ * Licensed under the GNU/GPL. See COPYING for details.
+ */
+
+#include "bcma_private.h"
+#include <linux/bcma/bcma.h>
+
+static void bcma_chipco_chipctl_maskset(struct bcma_drv_cc *cc,
+					u32 offset, u32 mask, u32 set)
+{
+	u32 value;
+
+	bcma_cc_read32(cc, BCMA_CC_CHIPCTL_ADDR);
+	bcma_cc_write32(cc, BCMA_CC_CHIPCTL_ADDR, offset);
+	bcma_cc_read32(cc, BCMA_CC_CHIPCTL_ADDR);
+	value = bcma_cc_read32(cc, BCMA_CC_CHIPCTL_DATA);
+	value &= mask;
+	value |= set;
+	bcma_cc_write32(cc, BCMA_CC_CHIPCTL_DATA, value);
+	bcma_cc_read32(cc, BCMA_CC_CHIPCTL_DATA);
+}
+
+static void bcma_pmu_pll_init(struct bcma_drv_cc *cc)
+{
+	struct bcma_bus *bus = cc->core->bus;
+
+	switch (bus->chipinfo.id) {
+	case 0x4313:
+	case 0x4331:
+	case 43224:
+	case 43225:
+		break;
+	default:
+		pr_err("PLL init unknown for device 0x%04X\n",
+			bus->chipinfo.id);
+	}
+}
+
+static void bcma_pmu_resources_init(struct bcma_drv_cc *cc)
+{
+	struct bcma_bus *bus = cc->core->bus;
+	u32 min_msk = 0, max_msk = 0;
+
+	switch (bus->chipinfo.id) {
+	case 0x4313:
+		min_msk = 0x200D;
+		max_msk = 0xFFFF;
+		break;
+	case 43224:
+		break;
+	default:
+		pr_err("PMU resource config unknown for device 0x%04X\n",
+			bus->chipinfo.id);
+	}
+
+	/* Set the resource masks. */
+	if (min_msk)
+		bcma_cc_write32(cc, BCMA_CC_PMU_MINRES_MSK, min_msk);
+	if (max_msk)
+		bcma_cc_write32(cc, BCMA_CC_PMU_MAXRES_MSK, max_msk);
+}
+
+void bcma_pmu_swreg_init(struct bcma_drv_cc *cc)
+{
+	struct bcma_bus *bus = cc->core->bus;
+
+	switch (bus->chipinfo.id) {
+	case 0x4313:
+	case 0x4331:
+	case 43224:
+		break;
+	default:
+		pr_err("PMU switch/regulators init unknown for device "
+			"0x%04X\n", bus->chipinfo.id);
+	}
+}
+
+void bcma_pmu_workarounds(struct bcma_drv_cc *cc)
+{
+	struct bcma_bus *bus = cc->core->bus;
+
+	switch (bus->chipinfo.id) {
+	case 0x4313:
+		bcma_chipco_chipctl_maskset(cc, 0, ~0, 0x7);
+		break;
+	case 0x4331:
+		pr_err("Enabling Ext PA lines not implemented\n");
+		break;
+	case 43224:
+		if (bus->chipinfo.rev == 0) {
+			pr_err("Workarounds for 43224 rev 0 not fully "
+				"implemented\n");
+			bcma_chipco_chipctl_maskset(cc, 0, ~0, 0xF0);
+		} else {
+			bcma_chipco_chipctl_maskset(cc, 0, ~0, 0xF0);
+		}
+		break;
+	default:
+		pr_err("Workarounds unknown for device 0x%04X\n",
+			bus->chipinfo.id);
+	}
+}
+
+void bcma_pmu_init(struct bcma_drv_cc *cc)
+{
+	u32 pmucap;
+
+	pmucap = bcma_cc_read32(cc, BCMA_CC_PMU_CAP);
+	cc->pmu.rev = (pmucap & BCMA_CC_PMU_CAP_REVISION);
+
+	pr_debug("Found rev %u PMU (capabilities 0x%08X)\n", cc->pmu.rev,
+		 pmucap);
+
+	if (cc->pmu.rev == 1)
+		bcma_cc_mask32(cc, BCMA_CC_PMU_CTL,
+			      ~BCMA_CC_PMU_CTL_NOILPONW);
+	else
+		bcma_cc_set32(cc, BCMA_CC_PMU_CTL,
+			     BCMA_CC_PMU_CTL_NOILPONW);
+
+	if (cc->core->id.id == 0x4329 && cc->core->id.rev == 2)
+		pr_err("Fix for 4329b0 bad LPOM state not implemented!\n");
+
+	bcma_pmu_pll_init(cc);
+	bcma_pmu_resources_init(cc);
+	bcma_pmu_swreg_init(cc);
+	bcma_pmu_workarounds(cc);
+}
diff -druN linux-2.6.39-libre/drivers/bcma/driver_pci.c linux-3.0-rc7-libre/drivers/bcma/driver_pci.c
--- linux-2.6.39-libre/drivers/bcma/driver_pci.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/bcma/driver_pci.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,163 @@
+/*
+ * Broadcom specific AMBA
+ * PCI Core
+ *
+ * Copyright 2005, Broadcom Corporation
+ * Copyright 2006, 2007, Michael Buesch <mb@bu3sch.de>
+ *
+ * Licensed under the GNU/GPL. See COPYING for details.
+ */
+
+#include "bcma_private.h"
+#include <linux/bcma/bcma.h>
+
+/**************************************************
+ * R/W ops.
+ **************************************************/
+
+static u32 bcma_pcie_read(struct bcma_drv_pci *pc, u32 address)
+{
+	pcicore_write32(pc, 0x130, address);
+	pcicore_read32(pc, 0x130);
+	return pcicore_read32(pc, 0x134);
+}
+
+#if 0
+static void bcma_pcie_write(struct bcma_drv_pci *pc, u32 address, u32 data)
+{
+	pcicore_write32(pc, 0x130, address);
+	pcicore_read32(pc, 0x130);
+	pcicore_write32(pc, 0x134, data);
+}
+#endif
+
+static void bcma_pcie_mdio_set_phy(struct bcma_drv_pci *pc, u8 phy)
+{
+	const u16 mdio_control = 0x128;
+	const u16 mdio_data = 0x12C;
+	u32 v;
+	int i;
+
+	v = (1 << 30); /* Start of Transaction */
+	v |= (1 << 28); /* Write Transaction */
+	v |= (1 << 17); /* Turnaround */
+	v |= (0x1F << 18);
+	v |= (phy << 4);
+	pcicore_write32(pc, mdio_data, v);
+
+	udelay(10);
+	for (i = 0; i < 200; i++) {
+		v = pcicore_read32(pc, mdio_control);
+		if (v & 0x100 /* Trans complete */)
+			break;
+		msleep(1);
+	}
+}
+
+static u16 bcma_pcie_mdio_read(struct bcma_drv_pci *pc, u8 device, u8 address)
+{
+	const u16 mdio_control = 0x128;
+	const u16 mdio_data = 0x12C;
+	int max_retries = 10;
+	u16 ret = 0;
+	u32 v;
+	int i;
+
+	v = 0x80; /* Enable Preamble Sequence */
+	v |= 0x2; /* MDIO Clock Divisor */
+	pcicore_write32(pc, mdio_control, v);
+
+	if (pc->core->id.rev >= 10) {
+		max_retries = 200;
+		bcma_pcie_mdio_set_phy(pc, device);
+	}
+
+	v = (1 << 30); /* Start of Transaction */
+	v |= (1 << 29); /* Read Transaction */
+	v |= (1 << 17); /* Turnaround */
+	if (pc->core->id.rev < 10)
+		v |= (u32)device << 22;
+	v |= (u32)address << 18;
+	pcicore_write32(pc, mdio_data, v);
+	/* Wait for the device to complete the transaction */
+	udelay(10);
+	for (i = 0; i < max_retries; i++) {
+		v = pcicore_read32(pc, mdio_control);
+		if (v & 0x100 /* Trans complete */) {
+			udelay(10);
+			ret = pcicore_read32(pc, mdio_data);
+			break;
+		}
+		msleep(1);
+	}
+	pcicore_write32(pc, mdio_control, 0);
+	return ret;
+}
+
+static void bcma_pcie_mdio_write(struct bcma_drv_pci *pc, u8 device,
+				u8 address, u16 data)
+{
+	const u16 mdio_control = 0x128;
+	const u16 mdio_data = 0x12C;
+	int max_retries = 10;
+	u32 v;
+	int i;
+
+	v = 0x80; /* Enable Preamble Sequence */
+	v |= 0x2; /* MDIO Clock Divisor */
+	pcicore_write32(pc, mdio_control, v);
+
+	if (pc->core->id.rev >= 10) {
+		max_retries = 200;
+		bcma_pcie_mdio_set_phy(pc, device);
+	}
+
+	v = (1 << 30); /* Start of Transaction */
+	v |= (1 << 28); /* Write Transaction */
+	v |= (1 << 17); /* Turnaround */
+	if (pc->core->id.rev < 10)
+		v |= (u32)device << 22;
+	v |= (u32)address << 18;
+	v |= data;
+	pcicore_write32(pc, mdio_data, v);
+	/* Wait for the device to complete the transaction */
+	udelay(10);
+	for (i = 0; i < max_retries; i++) {
+		v = pcicore_read32(pc, mdio_control);
+		if (v & 0x100 /* Trans complete */)
+			break;
+		msleep(1);
+	}
+	pcicore_write32(pc, mdio_control, 0);
+}
+
+/**************************************************
+ * Workarounds.
+ **************************************************/
+
+static u8 bcma_pcicore_polarity_workaround(struct bcma_drv_pci *pc)
+{
+	return (bcma_pcie_read(pc, 0x204) & 0x10) ? 0xC0 : 0x80;
+}
+
+static void bcma_pcicore_serdes_workaround(struct bcma_drv_pci *pc)
+{
+	const u8 serdes_pll_device = 0x1D;
+	const u8 serdes_rx_device = 0x1F;
+	u16 tmp;
+
+	bcma_pcie_mdio_write(pc, serdes_rx_device, 1 /* Control */,
+			      bcma_pcicore_polarity_workaround(pc));
+	tmp = bcma_pcie_mdio_read(pc, serdes_pll_device, 1 /* Control */);
+	if (tmp & 0x4000)
+		bcma_pcie_mdio_write(pc, serdes_pll_device, 1, tmp & ~0x4000);
+}
+
+/**************************************************
+ * Init.
+ **************************************************/
+
+void bcma_core_pci_init(struct bcma_drv_pci *pc)
+{
+	bcma_pcicore_serdes_workaround(pc);
+}
diff -druN linux-2.6.39-libre/drivers/bcma/host_pci.c linux-3.0-rc7-libre/drivers/bcma/host_pci.c
--- linux-2.6.39-libre/drivers/bcma/host_pci.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/bcma/host_pci.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,198 @@
+/*
+ * Broadcom specific AMBA
+ * PCI Host
+ *
+ * Licensed under the GNU/GPL. See COPYING for details.
+ */
+
+#include "bcma_private.h"
+#include <linux/slab.h>
+#include <linux/bcma/bcma.h>
+#include <linux/pci.h>
+
+static void bcma_host_pci_switch_core(struct bcma_device *core)
+{
+	pci_write_config_dword(core->bus->host_pci, BCMA_PCI_BAR0_WIN,
+			       core->addr);
+	pci_write_config_dword(core->bus->host_pci, BCMA_PCI_BAR0_WIN2,
+			       core->wrap);
+	core->bus->mapped_core = core;
+	pr_debug("Switched to core: 0x%X\n", core->id.id);
+}
+
+static u8 bcma_host_pci_read8(struct bcma_device *core, u16 offset)
+{
+	if (core->bus->mapped_core != core)
+		bcma_host_pci_switch_core(core);
+	return ioread8(core->bus->mmio + offset);
+}
+
+static u16 bcma_host_pci_read16(struct bcma_device *core, u16 offset)
+{
+	if (core->bus->mapped_core != core)
+		bcma_host_pci_switch_core(core);
+	return ioread16(core->bus->mmio + offset);
+}
+
+static u32 bcma_host_pci_read32(struct bcma_device *core, u16 offset)
+{
+	if (core->bus->mapped_core != core)
+		bcma_host_pci_switch_core(core);
+	return ioread32(core->bus->mmio + offset);
+}
+
+static void bcma_host_pci_write8(struct bcma_device *core, u16 offset,
+				 u8 value)
+{
+	if (core->bus->mapped_core != core)
+		bcma_host_pci_switch_core(core);
+	iowrite8(value, core->bus->mmio + offset);
+}
+
+static void bcma_host_pci_write16(struct bcma_device *core, u16 offset,
+				 u16 value)
+{
+	if (core->bus->mapped_core != core)
+		bcma_host_pci_switch_core(core);
+	iowrite16(value, core->bus->mmio + offset);
+}
+
+static void bcma_host_pci_write32(struct bcma_device *core, u16 offset,
+				 u32 value)
+{
+	if (core->bus->mapped_core != core)
+		bcma_host_pci_switch_core(core);
+	iowrite32(value, core->bus->mmio + offset);
+}
+
+static u32 bcma_host_pci_aread32(struct bcma_device *core, u16 offset)
+{
+	if (core->bus->mapped_core != core)
+		bcma_host_pci_switch_core(core);
+	return ioread32(core->bus->mmio + (1 * BCMA_CORE_SIZE) + offset);
+}
+
+static void bcma_host_pci_awrite32(struct bcma_device *core, u16 offset,
+				  u32 value)
+{
+	if (core->bus->mapped_core != core)
+		bcma_host_pci_switch_core(core);
+	iowrite32(value, core->bus->mmio + (1 * BCMA_CORE_SIZE) + offset);
+}
+
+const struct bcma_host_ops bcma_host_pci_ops = {
+	.read8		= bcma_host_pci_read8,
+	.read16		= bcma_host_pci_read16,
+	.read32		= bcma_host_pci_read32,
+	.write8		= bcma_host_pci_write8,
+	.write16	= bcma_host_pci_write16,
+	.write32	= bcma_host_pci_write32,
+	.aread32	= bcma_host_pci_aread32,
+	.awrite32	= bcma_host_pci_awrite32,
+};
+
+static int bcma_host_pci_probe(struct pci_dev *dev,
+			     const struct pci_device_id *id)
+{
+	struct bcma_bus *bus;
+	int err = -ENOMEM;
+	const char *name;
+	u32 val;
+
+	/* Alloc */
+	bus = kzalloc(sizeof(*bus), GFP_KERNEL);
+	if (!bus)
+		goto out;
+
+	/* Basic PCI configuration */
+	err = pci_enable_device(dev);
+	if (err)
+		goto err_kfree_bus;
+
+	name = dev_name(&dev->dev);
+	if (dev->driver && dev->driver->name)
+		name = dev->driver->name;
+	err = pci_request_regions(dev, name);
+	if (err)
+		goto err_pci_disable;
+	pci_set_master(dev);
+
+	/* Disable the RETRY_TIMEOUT register (0x41) to keep
+	 * PCI Tx retries from interfering with C3 CPU state */
+	pci_read_config_dword(dev, 0x40, &val);
+	if ((val & 0x0000ff00) != 0)
+		pci_write_config_dword(dev, 0x40, val & 0xffff00ff);
+
+	/* SSB needed additional powering up, do we have any AMBA PCI cards? */
+	if (!pci_is_pcie(dev))
+		pr_err("PCI card detected, report problems.\n");
+
+	/* Map MMIO */
+	err = -ENOMEM;
+	bus->mmio = pci_iomap(dev, 0, ~0UL);
+	if (!bus->mmio)
+		goto err_pci_release_regions;
+
+	/* Host specific */
+	bus->host_pci = dev;
+	bus->hosttype = BCMA_HOSTTYPE_PCI;
+	bus->ops = &bcma_host_pci_ops;
+
+	/* Register */
+	err = bcma_bus_register(bus);
+	if (err)
+		goto err_pci_unmap_mmio;
+
+	pci_set_drvdata(dev, bus);
+
+out:
+	return err;
+
+err_pci_unmap_mmio:
+	pci_iounmap(dev, bus->mmio);
+err_pci_release_regions:
+	pci_release_regions(dev);
+err_pci_disable:
+	pci_disable_device(dev);
+err_kfree_bus:
+	kfree(bus);
+	return err;
+}
+
+static void bcma_host_pci_remove(struct pci_dev *dev)
+{
+	struct bcma_bus *bus = pci_get_drvdata(dev);
+
+	bcma_bus_unregister(bus);
+	pci_iounmap(dev, bus->mmio);
+	pci_release_regions(dev);
+	pci_disable_device(dev);
+	kfree(bus);
+	pci_set_drvdata(dev, NULL);
+}
+
+static DEFINE_PCI_DEVICE_TABLE(bcma_pci_bridge_tbl) = {
+	{ PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x0576) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4331) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4353) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4727) },
+	{ 0, },
+};
+MODULE_DEVICE_TABLE(pci, bcma_pci_bridge_tbl);
+
+static struct pci_driver bcma_pci_bridge_driver = {
+	.name = "bcma-pci-bridge",
+	.id_table = bcma_pci_bridge_tbl,
+	.probe = bcma_host_pci_probe,
+	.remove = bcma_host_pci_remove,
+};
+
+int __init bcma_host_pci_init(void)
+{
+	return pci_register_driver(&bcma_pci_bridge_driver);
+}
+
+void __exit bcma_host_pci_exit(void)
+{
+	pci_unregister_driver(&bcma_pci_bridge_driver);
+}
diff -druN linux-2.6.39-libre/drivers/bcma/Kconfig linux-3.0-rc7-libre/drivers/bcma/Kconfig
--- linux-2.6.39-libre/drivers/bcma/Kconfig	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/bcma/Kconfig	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,33 @@
+config BCMA_POSSIBLE
+	bool
+	depends on HAS_IOMEM && HAS_DMA
+	default y
+
+menu "Broadcom specific AMBA"
+	depends on BCMA_POSSIBLE
+
+config BCMA
+	tristate "BCMA support"
+	depends on BCMA_POSSIBLE
+	help
+	  Bus driver for Broadcom specific Advanced Microcontroller Bus
+	  Architecture.
+
+config BCMA_HOST_PCI_POSSIBLE
+	bool
+	depends on BCMA && PCI = y
+	default y
+
+config BCMA_HOST_PCI
+	bool "Support for BCMA on PCI-host bus"
+	depends on BCMA_HOST_PCI_POSSIBLE
+
+config BCMA_DEBUG
+	bool "BCMA debugging"
+	depends on BCMA
+	help
+	  This turns on additional debugging messages.
+
+	  If unsure, say N
+
+endmenu
diff -druN linux-2.6.39-libre/drivers/bcma/main.c linux-3.0-rc7-libre/drivers/bcma/main.c
--- linux-2.6.39-libre/drivers/bcma/main.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/bcma/main.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,247 @@
+/*
+ * Broadcom specific AMBA
+ * Bus subsystem
+ *
+ * Licensed under the GNU/GPL. See COPYING for details.
+ */
+
+#include "bcma_private.h"
+#include <linux/bcma/bcma.h>
+
+MODULE_DESCRIPTION("Broadcom's specific AMBA driver");
+MODULE_LICENSE("GPL");
+
+static int bcma_bus_match(struct device *dev, struct device_driver *drv);
+static int bcma_device_probe(struct device *dev);
+static int bcma_device_remove(struct device *dev);
+
+static ssize_t manuf_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	struct bcma_device *core = container_of(dev, struct bcma_device, dev);
+	return sprintf(buf, "0x%03X\n", core->id.manuf);
+}
+static ssize_t id_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	struct bcma_device *core = container_of(dev, struct bcma_device, dev);
+	return sprintf(buf, "0x%03X\n", core->id.id);
+}
+static ssize_t rev_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	struct bcma_device *core = container_of(dev, struct bcma_device, dev);
+	return sprintf(buf, "0x%02X\n", core->id.rev);
+}
+static ssize_t class_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	struct bcma_device *core = container_of(dev, struct bcma_device, dev);
+	return sprintf(buf, "0x%X\n", core->id.class);
+}
+static struct device_attribute bcma_device_attrs[] = {
+	__ATTR_RO(manuf),
+	__ATTR_RO(id),
+	__ATTR_RO(rev),
+	__ATTR_RO(class),
+	__ATTR_NULL,
+};
+
+static struct bus_type bcma_bus_type = {
+	.name		= "bcma",
+	.match		= bcma_bus_match,
+	.probe		= bcma_device_probe,
+	.remove		= bcma_device_remove,
+	.dev_attrs	= bcma_device_attrs,
+};
+
+static struct bcma_device *bcma_find_core(struct bcma_bus *bus, u16 coreid)
+{
+	struct bcma_device *core;
+
+	list_for_each_entry(core, &bus->cores, list) {
+		if (core->id.id == coreid)
+			return core;
+	}
+	return NULL;
+}
+
+static void bcma_release_core_dev(struct device *dev)
+{
+	struct bcma_device *core = container_of(dev, struct bcma_device, dev);
+	kfree(core);
+}
+
+static int bcma_register_cores(struct bcma_bus *bus)
+{
+	struct bcma_device *core;
+	int err, dev_id = 0;
+
+	list_for_each_entry(core, &bus->cores, list) {
+		/* We support that cores ourself */
+		switch (core->id.id) {
+		case BCMA_CORE_CHIPCOMMON:
+		case BCMA_CORE_PCI:
+		case BCMA_CORE_PCIE:
+			continue;
+		}
+
+		core->dev.release = bcma_release_core_dev;
+		core->dev.bus = &bcma_bus_type;
+		dev_set_name(&core->dev, "bcma%d:%d", 0/*bus->num*/, dev_id);
+
+		switch (bus->hosttype) {
+		case BCMA_HOSTTYPE_PCI:
+			core->dev.parent = &bus->host_pci->dev;
+			break;
+		case BCMA_HOSTTYPE_NONE:
+		case BCMA_HOSTTYPE_SDIO:
+			break;
+		}
+
+		err = device_register(&core->dev);
+		if (err) {
+			pr_err("Could not register dev for core 0x%03X\n",
+			       core->id.id);
+			continue;
+		}
+		core->dev_registered = true;
+		dev_id++;
+	}
+
+	return 0;
+}
+
+static void bcma_unregister_cores(struct bcma_bus *bus)
+{
+	struct bcma_device *core;
+
+	list_for_each_entry(core, &bus->cores, list) {
+		if (core->dev_registered)
+			device_unregister(&core->dev);
+	}
+}
+
+int bcma_bus_register(struct bcma_bus *bus)
+{
+	int err;
+	struct bcma_device *core;
+
+	/* Scan for devices (cores) */
+	err = bcma_bus_scan(bus);
+	if (err) {
+		pr_err("Failed to scan: %d\n", err);
+		return -1;
+	}
+
+	/* Init CC core */
+	core = bcma_find_core(bus, BCMA_CORE_CHIPCOMMON);
+	if (core) {
+		bus->drv_cc.core = core;
+		bcma_core_chipcommon_init(&bus->drv_cc);
+	}
+
+	/* Init PCIE core */
+	core = bcma_find_core(bus, BCMA_CORE_PCIE);
+	if (core) {
+		bus->drv_pci.core = core;
+		bcma_core_pci_init(&bus->drv_pci);
+	}
+
+	/* Register found cores */
+	bcma_register_cores(bus);
+
+	pr_info("Bus registered\n");
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(bcma_bus_register);
+
+void bcma_bus_unregister(struct bcma_bus *bus)
+{
+	bcma_unregister_cores(bus);
+}
+EXPORT_SYMBOL_GPL(bcma_bus_unregister);
+
+int __bcma_driver_register(struct bcma_driver *drv, struct module *owner)
+{
+	drv->drv.name = drv->name;
+	drv->drv.bus = &bcma_bus_type;
+	drv->drv.owner = owner;
+
+	return driver_register(&drv->drv);
+}
+EXPORT_SYMBOL_GPL(__bcma_driver_register);
+
+void bcma_driver_unregister(struct bcma_driver *drv)
+{
+	driver_unregister(&drv->drv);
+}
+EXPORT_SYMBOL_GPL(bcma_driver_unregister);
+
+static int bcma_bus_match(struct device *dev, struct device_driver *drv)
+{
+	struct bcma_device *core = container_of(dev, struct bcma_device, dev);
+	struct bcma_driver *adrv = container_of(drv, struct bcma_driver, drv);
+	const struct bcma_device_id *cid = &core->id;
+	const struct bcma_device_id *did;
+
+	for (did = adrv->id_table; did->manuf || did->id || did->rev; did++) {
+	    if ((did->manuf == cid->manuf || did->manuf == BCMA_ANY_MANUF) &&
+		(did->id == cid->id || did->id == BCMA_ANY_ID) &&
+		(did->rev == cid->rev || did->rev == BCMA_ANY_REV) &&
+		(did->class == cid->class || did->class == BCMA_ANY_CLASS))
+			return 1;
+	}
+	return 0;
+}
+
+static int bcma_device_probe(struct device *dev)
+{
+	struct bcma_device *core = container_of(dev, struct bcma_device, dev);
+	struct bcma_driver *adrv = container_of(dev->driver, struct bcma_driver,
+					       drv);
+	int err = 0;
+
+	if (adrv->probe)
+		err = adrv->probe(core);
+
+	return err;
+}
+
+static int bcma_device_remove(struct device *dev)
+{
+	struct bcma_device *core = container_of(dev, struct bcma_device, dev);
+	struct bcma_driver *adrv = container_of(dev->driver, struct bcma_driver,
+					       drv);
+
+	if (adrv->remove)
+		adrv->remove(core);
+
+	return 0;
+}
+
+static int __init bcma_modinit(void)
+{
+	int err;
+
+	err = bus_register(&bcma_bus_type);
+	if (err)
+		return err;
+
+#ifdef CONFIG_BCMA_HOST_PCI
+	err = bcma_host_pci_init();
+	if (err) {
+		pr_err("PCI host initialization failed\n");
+		err = 0;
+	}
+#endif
+
+	return err;
+}
+fs_initcall(bcma_modinit);
+
+static void __exit bcma_modexit(void)
+{
+#ifdef CONFIG_BCMA_HOST_PCI
+	bcma_host_pci_exit();
+#endif
+	bus_unregister(&bcma_bus_type);
+}
+module_exit(bcma_modexit)
diff -druN linux-2.6.39-libre/drivers/bcma/Makefile linux-3.0-rc7-libre/drivers/bcma/Makefile
--- linux-2.6.39-libre/drivers/bcma/Makefile	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/bcma/Makefile	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,7 @@
+bcma-y					+= main.o scan.o core.o
+bcma-y					+= driver_chipcommon.o driver_chipcommon_pmu.o
+bcma-y					+= driver_pci.o
+bcma-$(CONFIG_BCMA_HOST_PCI)		+= host_pci.o
+obj-$(CONFIG_BCMA)			+= bcma.o
+
+ccflags-$(CONFIG_BCMA_DEBUG)		:= -DDEBUG
diff -druN linux-2.6.39-libre/drivers/bcma/README linux-3.0-rc7-libre/drivers/bcma/README
--- linux-2.6.39-libre/drivers/bcma/README	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/bcma/README	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,19 @@
+Broadcom introduced new bus as replacement for older SSB. It is based on AMBA,
+however from programming point of view there is nothing AMBA specific we use.
+
+Standard AMBA drivers are platform specific, have hardcoded addresses and use
+AMBA standard fields like CID and PID.
+
+In case of Broadcom's cards every device consists of:
+1) Broadcom specific AMBA device. It is put on AMBA bus, but can not be treated
+   as standard AMBA device. Reading it's CID or PID can cause machine lockup.
+2) AMBA standard devices called ports or wrappers. They have CIDs (AMBA_CID)
+   and PIDs (0x103BB369), but we do not use that info for anything. One of that
+   devices is used for managing Broadcom specific core.
+
+Addresses of AMBA devices are not hardcoded in driver and have to be read from
+EPROM.
+
+In this situation we decided to introduce separated bus. It can contain up to
+16 devices identified by Broadcom specific fields: manufacturer, id, revision
+and class.
diff -druN linux-2.6.39-libre/drivers/bcma/scan.c linux-3.0-rc7-libre/drivers/bcma/scan.c
--- linux-2.6.39-libre/drivers/bcma/scan.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/bcma/scan.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,360 @@
+/*
+ * Broadcom specific AMBA
+ * Bus scanning
+ *
+ * Licensed under the GNU/GPL. See COPYING for details.
+ */
+
+#include "scan.h"
+#include "bcma_private.h"
+
+#include <linux/bcma/bcma.h>
+#include <linux/bcma/bcma_regs.h>
+#include <linux/pci.h>
+#include <linux/io.h>
+#include <linux/dma-mapping.h>
+#include <linux/slab.h>
+
+struct bcma_device_id_name {
+	u16 id;
+	const char *name;
+};
+struct bcma_device_id_name bcma_device_names[] = {
+	{ BCMA_CORE_OOB_ROUTER, "OOB Router" },
+	{ BCMA_CORE_INVALID, "Invalid" },
+	{ BCMA_CORE_CHIPCOMMON, "ChipCommon" },
+	{ BCMA_CORE_ILINE20, "ILine 20" },
+	{ BCMA_CORE_SRAM, "SRAM" },
+	{ BCMA_CORE_SDRAM, "SDRAM" },
+	{ BCMA_CORE_PCI, "PCI" },
+	{ BCMA_CORE_MIPS, "MIPS" },
+	{ BCMA_CORE_ETHERNET, "Fast Ethernet" },
+	{ BCMA_CORE_V90, "V90" },
+	{ BCMA_CORE_USB11_HOSTDEV, "USB 1.1 Hostdev" },
+	{ BCMA_CORE_ADSL, "ADSL" },
+	{ BCMA_CORE_ILINE100, "ILine 100" },
+	{ BCMA_CORE_IPSEC, "IPSEC" },
+	{ BCMA_CORE_UTOPIA, "UTOPIA" },
+	{ BCMA_CORE_PCMCIA, "PCMCIA" },
+	{ BCMA_CORE_INTERNAL_MEM, "Internal Memory" },
+	{ BCMA_CORE_MEMC_SDRAM, "MEMC SDRAM" },
+	{ BCMA_CORE_OFDM, "OFDM" },
+	{ BCMA_CORE_EXTIF, "EXTIF" },
+	{ BCMA_CORE_80211, "IEEE 802.11" },
+	{ BCMA_CORE_PHY_A, "PHY A" },
+	{ BCMA_CORE_PHY_B, "PHY B" },
+	{ BCMA_CORE_PHY_G, "PHY G" },
+	{ BCMA_CORE_MIPS_3302, "MIPS 3302" },
+	{ BCMA_CORE_USB11_HOST, "USB 1.1 Host" },
+	{ BCMA_CORE_USB11_DEV, "USB 1.1 Device" },
+	{ BCMA_CORE_USB20_HOST, "USB 2.0 Host" },
+	{ BCMA_CORE_USB20_DEV, "USB 2.0 Device" },
+	{ BCMA_CORE_SDIO_HOST, "SDIO Host" },
+	{ BCMA_CORE_ROBOSWITCH, "Roboswitch" },
+	{ BCMA_CORE_PARA_ATA, "PATA" },
+	{ BCMA_CORE_SATA_XORDMA, "SATA XOR-DMA" },
+	{ BCMA_CORE_ETHERNET_GBIT, "GBit Ethernet" },
+	{ BCMA_CORE_PCIE, "PCIe" },
+	{ BCMA_CORE_PHY_N, "PHY N" },
+	{ BCMA_CORE_SRAM_CTL, "SRAM Controller" },
+	{ BCMA_CORE_MINI_MACPHY, "Mini MACPHY" },
+	{ BCMA_CORE_ARM_1176, "ARM 1176" },
+	{ BCMA_CORE_ARM_7TDMI, "ARM 7TDMI" },
+	{ BCMA_CORE_PHY_LP, "PHY LP" },
+	{ BCMA_CORE_PMU, "PMU" },
+	{ BCMA_CORE_PHY_SSN, "PHY SSN" },
+	{ BCMA_CORE_SDIO_DEV, "SDIO Device" },
+	{ BCMA_CORE_ARM_CM3, "ARM CM3" },
+	{ BCMA_CORE_PHY_HT, "PHY HT" },
+	{ BCMA_CORE_MIPS_74K, "MIPS 74K" },
+	{ BCMA_CORE_MAC_GBIT, "GBit MAC" },
+	{ BCMA_CORE_DDR12_MEM_CTL, "DDR1/DDR2 Memory Controller" },
+	{ BCMA_CORE_PCIE_RC, "PCIe Root Complex" },
+	{ BCMA_CORE_OCP_OCP_BRIDGE, "OCP to OCP Bridge" },
+	{ BCMA_CORE_SHARED_COMMON, "Common Shared" },
+	{ BCMA_CORE_OCP_AHB_BRIDGE, "OCP to AHB Bridge" },
+	{ BCMA_CORE_SPI_HOST, "SPI Host" },
+	{ BCMA_CORE_I2S, "I2S" },
+	{ BCMA_CORE_SDR_DDR1_MEM_CTL, "SDR/DDR1 Memory Controller" },
+	{ BCMA_CORE_SHIM, "SHIM" },
+	{ BCMA_CORE_DEFAULT, "Default" },
+};
+const char *bcma_device_name(struct bcma_device_id *id)
+{
+	int i;
+
+	if (id->manuf == BCMA_MANUF_BCM) {
+		for (i = 0; i < ARRAY_SIZE(bcma_device_names); i++) {
+			if (bcma_device_names[i].id == id->id)
+				return bcma_device_names[i].name;
+		}
+	}
+	return "UNKNOWN";
+}
+
+static u32 bcma_scan_read32(struct bcma_bus *bus, u8 current_coreidx,
+		       u16 offset)
+{
+	return readl(bus->mmio + offset);
+}
+
+static void bcma_scan_switch_core(struct bcma_bus *bus, u32 addr)
+{
+	if (bus->hosttype == BCMA_HOSTTYPE_PCI)
+		pci_write_config_dword(bus->host_pci, BCMA_PCI_BAR0_WIN,
+				       addr);
+}
+
+static u32 bcma_erom_get_ent(struct bcma_bus *bus, u32 **eromptr)
+{
+	u32 ent = readl(*eromptr);
+	(*eromptr)++;
+	return ent;
+}
+
+static void bcma_erom_push_ent(u32 **eromptr)
+{
+	(*eromptr)--;
+}
+
+static s32 bcma_erom_get_ci(struct bcma_bus *bus, u32 **eromptr)
+{
+	u32 ent = bcma_erom_get_ent(bus, eromptr);
+	if (!(ent & SCAN_ER_VALID))
+		return -ENOENT;
+	if ((ent & SCAN_ER_TAG) != SCAN_ER_TAG_CI)
+		return -ENOENT;
+	return ent;
+}
+
+static bool bcma_erom_is_end(struct bcma_bus *bus, u32 **eromptr)
+{
+	u32 ent = bcma_erom_get_ent(bus, eromptr);
+	bcma_erom_push_ent(eromptr);
+	return (ent == (SCAN_ER_TAG_END | SCAN_ER_VALID));
+}
+
+static bool bcma_erom_is_bridge(struct bcma_bus *bus, u32 **eromptr)
+{
+	u32 ent = bcma_erom_get_ent(bus, eromptr);
+	bcma_erom_push_ent(eromptr);
+	return (((ent & SCAN_ER_VALID)) &&
+		((ent & SCAN_ER_TAGX) == SCAN_ER_TAG_ADDR) &&
+		((ent & SCAN_ADDR_TYPE) == SCAN_ADDR_TYPE_BRIDGE));
+}
+
+static void bcma_erom_skip_component(struct bcma_bus *bus, u32 **eromptr)
+{
+	u32 ent;
+	while (1) {
+		ent = bcma_erom_get_ent(bus, eromptr);
+		if ((ent & SCAN_ER_VALID) &&
+		    ((ent & SCAN_ER_TAG) == SCAN_ER_TAG_CI))
+			break;
+		if (ent == (SCAN_ER_TAG_END | SCAN_ER_VALID))
+			break;
+	}
+	bcma_erom_push_ent(eromptr);
+}
+
+static s32 bcma_erom_get_mst_port(struct bcma_bus *bus, u32 **eromptr)
+{
+	u32 ent = bcma_erom_get_ent(bus, eromptr);
+	if (!(ent & SCAN_ER_VALID))
+		return -ENOENT;
+	if ((ent & SCAN_ER_TAG) != SCAN_ER_TAG_MP)
+		return -ENOENT;
+	return ent;
+}
+
+static s32 bcma_erom_get_addr_desc(struct bcma_bus *bus, u32 **eromptr,
+				  u32 type, u8 port)
+{
+	u32 addrl, addrh, sizel, sizeh = 0;
+	u32 size;
+
+	u32 ent = bcma_erom_get_ent(bus, eromptr);
+	if ((!(ent & SCAN_ER_VALID)) ||
+	    ((ent & SCAN_ER_TAGX) != SCAN_ER_TAG_ADDR) ||
+	    ((ent & SCAN_ADDR_TYPE) != type) ||
+	    (((ent & SCAN_ADDR_PORT) >> SCAN_ADDR_PORT_SHIFT) != port)) {
+		bcma_erom_push_ent(eromptr);
+		return -EINVAL;
+	}
+
+	addrl = ent & SCAN_ADDR_ADDR;
+	if (ent & SCAN_ADDR_AG32)
+		addrh = bcma_erom_get_ent(bus, eromptr);
+	else
+		addrh = 0;
+
+	if ((ent & SCAN_ADDR_SZ) == SCAN_ADDR_SZ_SZD) {
+		size = bcma_erom_get_ent(bus, eromptr);
+		sizel = size & SCAN_SIZE_SZ;
+		if (size & SCAN_SIZE_SG32)
+			sizeh = bcma_erom_get_ent(bus, eromptr);
+	} else
+		sizel = SCAN_ADDR_SZ_BASE <<
+				((ent & SCAN_ADDR_SZ) >> SCAN_ADDR_SZ_SHIFT);
+
+	return addrl;
+}
+
+int bcma_bus_scan(struct bcma_bus *bus)
+{
+	u32 erombase;
+	u32 __iomem *eromptr, *eromend;
+
+	s32 cia, cib;
+	u8 ports[2], wrappers[2];
+
+	s32 tmp;
+	u8 i, j;
+
+	int err;
+
+	INIT_LIST_HEAD(&bus->cores);
+	bus->nr_cores = 0;
+
+	bcma_scan_switch_core(bus, BCMA_ADDR_BASE);
+
+	tmp = bcma_scan_read32(bus, 0, BCMA_CC_ID);
+	bus->chipinfo.id = (tmp & BCMA_CC_ID_ID) >> BCMA_CC_ID_ID_SHIFT;
+	bus->chipinfo.rev = (tmp & BCMA_CC_ID_REV) >> BCMA_CC_ID_REV_SHIFT;
+	bus->chipinfo.pkg = (tmp & BCMA_CC_ID_PKG) >> BCMA_CC_ID_PKG_SHIFT;
+
+	erombase = bcma_scan_read32(bus, 0, BCMA_CC_EROM);
+	eromptr = bus->mmio;
+	eromend = eromptr + BCMA_CORE_SIZE / sizeof(u32);
+
+	bcma_scan_switch_core(bus, erombase);
+
+	while (eromptr < eromend) {
+		struct bcma_device *core = kzalloc(sizeof(*core), GFP_KERNEL);
+		if (!core)
+			return -ENOMEM;
+		INIT_LIST_HEAD(&core->list);
+		core->bus = bus;
+
+		/* get CIs */
+		cia = bcma_erom_get_ci(bus, &eromptr);
+		if (cia < 0) {
+			bcma_erom_push_ent(&eromptr);
+			if (bcma_erom_is_end(bus, &eromptr))
+				break;
+			err= -EILSEQ;
+			goto out;
+		}
+		cib = bcma_erom_get_ci(bus, &eromptr);
+		if (cib < 0) {
+			err= -EILSEQ;
+			goto out;
+		}
+
+		/* parse CIs */
+		core->id.class = (cia & SCAN_CIA_CLASS) >> SCAN_CIA_CLASS_SHIFT;
+		core->id.id = (cia & SCAN_CIA_ID) >> SCAN_CIA_ID_SHIFT;
+		core->id.manuf = (cia & SCAN_CIA_MANUF) >> SCAN_CIA_MANUF_SHIFT;
+		ports[0] = (cib & SCAN_CIB_NMP) >> SCAN_CIB_NMP_SHIFT;
+		ports[1] = (cib & SCAN_CIB_NSP) >> SCAN_CIB_NSP_SHIFT;
+		wrappers[0] = (cib & SCAN_CIB_NMW) >> SCAN_CIB_NMW_SHIFT;
+		wrappers[1] = (cib & SCAN_CIB_NSW) >> SCAN_CIB_NSW_SHIFT;
+		core->id.rev = (cib & SCAN_CIB_REV) >> SCAN_CIB_REV_SHIFT;
+
+		if (((core->id.manuf == BCMA_MANUF_ARM) &&
+		     (core->id.id == 0xFFF)) ||
+		    (ports[1] == 0)) {
+			bcma_erom_skip_component(bus, &eromptr);
+			continue;
+		}
+
+		/* check if component is a core at all */
+		if (wrappers[0] + wrappers[1] == 0) {
+			/* we could save addrl of the router
+			if (cid == BCMA_CORE_OOB_ROUTER)
+			 */
+			bcma_erom_skip_component(bus, &eromptr);
+			continue;
+		}
+
+		if (bcma_erom_is_bridge(bus, &eromptr)) {
+			bcma_erom_skip_component(bus, &eromptr);
+			continue;
+		}
+
+		/* get & parse master ports */
+		for (i = 0; i < ports[0]; i++) {
+			u32 mst_port_d = bcma_erom_get_mst_port(bus, &eromptr);
+			if (mst_port_d < 0) {
+				err= -EILSEQ;
+				goto out;
+			}
+		}
+
+		/* get & parse slave ports */
+		for (i = 0; i < ports[1]; i++) {
+			for (j = 0; ; j++) {
+				tmp = bcma_erom_get_addr_desc(bus, &eromptr,
+					SCAN_ADDR_TYPE_SLAVE, i);
+				if (tmp < 0) {
+					/* no more entries for port _i_ */
+					/* pr_debug("erom: slave port %d "
+					 * "has %d descriptors\n", i, j); */
+					break;
+				} else {
+					if (i == 0 && j == 0)
+						core->addr = tmp;
+				}
+			}
+		}
+
+		/* get & parse master wrappers */
+		for (i = 0; i < wrappers[0]; i++) {
+			for (j = 0; ; j++) {
+				tmp = bcma_erom_get_addr_desc(bus, &eromptr,
+					SCAN_ADDR_TYPE_MWRAP, i);
+				if (tmp < 0) {
+					/* no more entries for port _i_ */
+					/* pr_debug("erom: master wrapper %d "
+					 * "has %d descriptors\n", i, j); */
+					break;
+				} else {
+					if (i == 0 && j == 0)
+						core->wrap = tmp;
+				}
+			}
+		}
+
+		/* get & parse slave wrappers */
+		for (i = 0; i < wrappers[1]; i++) {
+			u8 hack = (ports[1] == 1) ? 0 : 1;
+			for (j = 0; ; j++) {
+				tmp = bcma_erom_get_addr_desc(bus, &eromptr,
+					SCAN_ADDR_TYPE_SWRAP, i + hack);
+				if (tmp < 0) {
+					/* no more entries for port _i_ */
+					/* pr_debug("erom: master wrapper %d "
+					 * has %d descriptors\n", i, j); */
+					break;
+				} else {
+					if (wrappers[0] == 0 && !i && !j)
+						core->wrap = tmp;
+				}
+			}
+		}
+
+		pr_info("Core %d found: %s "
+			"(manuf 0x%03X, id 0x%03X, rev 0x%02X, class 0x%X)\n",
+			bus->nr_cores, bcma_device_name(&core->id),
+			core->id.manuf, core->id.id, core->id.rev,
+			core->id.class);
+
+		core->core_index = bus->nr_cores++;
+		list_add(&core->list, &bus->cores);
+		continue;
+out:
+		return err;
+	}
+
+	return 0;
+}
diff -druN linux-2.6.39-libre/drivers/bcma/scan.h linux-3.0-rc7-libre/drivers/bcma/scan.h
--- linux-2.6.39-libre/drivers/bcma/scan.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/bcma/scan.h	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,56 @@
+#ifndef BCMA_SCAN_H_
+#define BCMA_SCAN_H_
+
+#define BCMA_ADDR_BASE		0x18000000
+#define BCMA_WRAP_BASE		0x18100000
+
+#define SCAN_ER_VALID		0x00000001
+#define SCAN_ER_TAGX		0x00000006 /* we have to ignore 0x8 bit when checking tag for SCAN_ER_TAG_ADDR */
+#define SCAN_ER_TAG		0x0000000E
+#define  SCAN_ER_TAG_CI		0x00000000
+#define  SCAN_ER_TAG_MP		0x00000002
+#define  SCAN_ER_TAG_ADDR	0x00000004
+#define  SCAN_ER_TAG_END	0x0000000E
+#define SCAN_ER_BAD		0xFFFFFFFF
+
+#define SCAN_CIA_CLASS		0x000000F0
+#define SCAN_CIA_CLASS_SHIFT	4
+#define SCAN_CIA_ID		0x000FFF00
+#define SCAN_CIA_ID_SHIFT	8
+#define SCAN_CIA_MANUF		0xFFF00000
+#define SCAN_CIA_MANUF_SHIFT	20
+
+#define SCAN_CIB_NMP		0x000001F0
+#define SCAN_CIB_NMP_SHIFT	4
+#define SCAN_CIB_NSP		0x00003E00
+#define SCAN_CIB_NSP_SHIFT	9
+#define SCAN_CIB_NMW		0x0007C000
+#define SCAN_CIB_NMW_SHIFT	14
+#define SCAN_CIB_NSW		0x00F80000
+#define SCAN_CIB_NSW_SHIFT	17
+#define SCAN_CIB_REV		0xFF000000
+#define SCAN_CIB_REV_SHIFT	24
+
+#define SCAN_ADDR_AG32		0x00000008
+#define SCAN_ADDR_SZ		0x00000030
+#define SCAN_ADDR_SZ_SHIFT	4
+#define  SCAN_ADDR_SZ_4K	0x00000000
+#define  SCAN_ADDR_SZ_8K	0x00000010
+#define  SCAN_ADDR_SZ_16K	0x00000020
+#define  SCAN_ADDR_SZ_SZD	0x00000030
+#define SCAN_ADDR_TYPE		0x000000C0
+#define  SCAN_ADDR_TYPE_SLAVE	0x00000000
+#define  SCAN_ADDR_TYPE_BRIDGE	0x00000040
+#define  SCAN_ADDR_TYPE_SWRAP	0x00000080
+#define  SCAN_ADDR_TYPE_MWRAP	0x000000C0
+#define SCAN_ADDR_PORT		0x00000F00
+#define SCAN_ADDR_PORT_SHIFT	8
+#define SCAN_ADDR_ADDR		0xFFFFF000
+
+#define SCAN_ADDR_SZ_BASE	0x00001000	/* 4KB */
+
+#define SCAN_SIZE_SZ_ALIGN	0x00000FFF
+#define SCAN_SIZE_SZ		0xFFFFF000
+#define SCAN_SIZE_SG32		0x00000008
+
+#endif /* BCMA_SCAN_H_ */
diff -druN linux-2.6.39-libre/drivers/bcma/TODO linux-3.0-rc7-libre/drivers/bcma/TODO
--- linux-2.6.39-libre/drivers/bcma/TODO	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/bcma/TODO	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,3 @@
+- Interrupts
+- Defines for PCI core driver
+- Create kernel Documentation (use info from README)
diff -druN linux-2.6.39-libre/drivers/block/brd.c linux-3.0-rc7-libre/drivers/block/brd.c
--- linux-2.6.39-libre/drivers/block/brd.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/block/brd.c	2011-07-11 19:51:52.000000000 -0400
@@ -35,10 +35,6 @@
  */
 struct brd_device {
 	int		brd_number;
-	int		brd_refcnt;
-	loff_t		brd_offset;
-	loff_t		brd_sizelimit;
-	unsigned	brd_blocksize;
 
 	struct request_queue	*brd_queue;
 	struct gendisk		*brd_disk;
@@ -440,11 +436,11 @@
 int rd_size = CONFIG_BLK_DEV_RAM_SIZE;
 static int max_part;
 static int part_shift;
-module_param(rd_nr, int, 0);
+module_param(rd_nr, int, S_IRUGO);
 MODULE_PARM_DESC(rd_nr, "Maximum number of brd devices");
-module_param(rd_size, int, 0);
+module_param(rd_size, int, S_IRUGO);
 MODULE_PARM_DESC(rd_size, "Size of each RAM disk in kbytes.");
-module_param(max_part, int, 0);
+module_param(max_part, int, S_IRUGO);
 MODULE_PARM_DESC(max_part, "Maximum number of partitions per RAM disk");
 MODULE_LICENSE("GPL");
 MODULE_ALIAS_BLOCKDEV_MAJOR(RAMDISK_MAJOR);
@@ -552,7 +548,7 @@
 	struct kobject *kobj;
 
 	mutex_lock(&brd_devices_mutex);
-	brd = brd_init_one(dev & MINORMASK);
+	brd = brd_init_one(MINOR(dev) >> part_shift);
 	kobj = brd ? get_disk(brd->brd_disk) : ERR_PTR(-ENOMEM);
 	mutex_unlock(&brd_devices_mutex);
 
@@ -575,25 +571,39 @@
 	 *
 	 * (1) if rd_nr is specified, create that many upfront, and this
 	 *     also becomes a hard limit.
-	 * (2) if rd_nr is not specified, create 1 rd device on module
-	 *     load, user can further extend brd device by create dev node
-	 *     themselves and have kernel automatically instantiate actual
-	 *     device on-demand.
+	 * (2) if rd_nr is not specified, create CONFIG_BLK_DEV_RAM_COUNT
+	 *     (default 16) rd device on module load, user can further
+	 *     extend brd device by create dev node themselves and have
+	 *     kernel automatically instantiate actual device on-demand.
 	 */
 
 	part_shift = 0;
-	if (max_part > 0)
+	if (max_part > 0) {
 		part_shift = fls(max_part);
 
+		/*
+		 * Adjust max_part according to part_shift as it is exported
+		 * to user space so that user can decide correct minor number
+		 * if [s]he want to create more devices.
+		 *
+		 * Note that -1 is required because partition 0 is reserved
+		 * for the whole disk.
+		 */
+		max_part = (1UL << part_shift) - 1;
+	}
+
+	if ((1UL << part_shift) > DISK_MAX_PARTS)
+		return -EINVAL;
+
 	if (rd_nr > 1UL << (MINORBITS - part_shift))
 		return -EINVAL;
 
 	if (rd_nr) {
 		nr = rd_nr;
-		range = rd_nr;
+		range = rd_nr << part_shift;
 	} else {
 		nr = CONFIG_BLK_DEV_RAM_COUNT;
-		range = 1UL << (MINORBITS - part_shift);
+		range = 1UL << MINORBITS;
 	}
 
 	if (register_blkdev(RAMDISK_MAJOR, "ramdisk"))
@@ -632,7 +642,7 @@
 	unsigned long range;
 	struct brd_device *brd, *next;
 
-	range = rd_nr ? rd_nr :  1UL << (MINORBITS - part_shift);
+	range = rd_nr ? rd_nr << part_shift : 1UL << MINORBITS;
 
 	list_for_each_entry_safe(brd, next, &brd_devices, brd_list)
 		brd_del_one(brd);
diff -druN linux-2.6.39-libre/drivers/block/cciss.c linux-3.0-rc7-libre/drivers/block/cciss.c
--- linux-2.6.39-libre/drivers/block/cciss.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/block/cciss.c	2011-07-11 19:51:52.000000000 -0400
@@ -64,6 +64,10 @@
 MODULE_SUPPORTED_DEVICE("HP Smart Array Controllers");
 MODULE_VERSION("3.6.26");
 MODULE_LICENSE("GPL");
+static int cciss_tape_cmds = 6;
+module_param(cciss_tape_cmds, int, 0644);
+MODULE_PARM_DESC(cciss_tape_cmds,
+	"number of commands to allocate for tape devices (default: 6)");
 
 static DEFINE_MUTEX(cciss_mutex);
 static struct proc_dir_entry *proc_cciss;
@@ -194,6 +198,8 @@
 static int __devinit cciss_pci_find_memory_BAR(struct pci_dev *pdev,
 	unsigned long *memory_bar);
 static inline u32 cciss_tag_discard_error_bits(ctlr_info_t *h, u32 tag);
+static __devinit int write_driver_ver_to_cfgtable(
+	CfgTable_struct __iomem *cfgtable);
 
 /* performant mode helper functions */
 static void  calc_bucket_map(int *bucket, int num_buckets, int nsgs,
@@ -556,7 +562,7 @@
 #define to_hba(n) container_of(n, struct ctlr_info, dev)
 #define to_drv(n) container_of(n, drive_info_struct, dev)
 
-/* List of controllers which cannot be reset on kexec with reset_devices */
+/* List of controllers which cannot be hard reset on kexec with reset_devices */
 static u32 unresettable_controller[] = {
 	0x324a103C, /* Smart Array P712m */
 	0x324b103C, /* SmartArray P711m */
@@ -574,23 +580,45 @@
 	0x409D0E11, /* Smart Array 6400 EM */
 };
 
-static int ctlr_is_resettable(struct ctlr_info *h)
+/* List of controllers which cannot even be soft reset */
+static u32 soft_unresettable_controller[] = {
+	0x409C0E11, /* Smart Array 6400 */
+	0x409D0E11, /* Smart Array 6400 EM */
+};
+
+static int ctlr_is_hard_resettable(u32 board_id)
 {
 	int i;
 
 	for (i = 0; i < ARRAY_SIZE(unresettable_controller); i++)
-		if (unresettable_controller[i] == h->board_id)
+		if (unresettable_controller[i] == board_id)
 			return 0;
 	return 1;
 }
 
+static int ctlr_is_soft_resettable(u32 board_id)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(soft_unresettable_controller); i++)
+		if (soft_unresettable_controller[i] == board_id)
+			return 0;
+	return 1;
+}
+
+static int ctlr_is_resettable(u32 board_id)
+{
+	return ctlr_is_hard_resettable(board_id) ||
+		ctlr_is_soft_resettable(board_id);
+}
+
 static ssize_t host_show_resettable(struct device *dev,
 				    struct device_attribute *attr,
 				    char *buf)
 {
 	struct ctlr_info *h = to_hba(dev);
 
-	return snprintf(buf, 20, "%d\n", ctlr_is_resettable(h));
+	return snprintf(buf, 20, "%d\n", ctlr_is_resettable(h->board_id));
 }
 static DEVICE_ATTR(resettable, S_IRUGO, host_show_resettable, NULL);
 
@@ -2567,7 +2595,7 @@
 		}
 	} else if (cmd_type == TYPE_MSG) {
 		switch (cmd) {
-		case 0:	/* ABORT message */
+		case CCISS_ABORT_MSG:
 			c->Request.CDBLen = 12;
 			c->Request.Type.Attribute = ATTR_SIMPLE;
 			c->Request.Type.Direction = XFER_WRITE;
@@ -2577,16 +2605,16 @@
 			/* buff contains the tag of the command to abort */
 			memcpy(&c->Request.CDB[4], buff, 8);
 			break;
-		case 1:	/* RESET message */
+		case CCISS_RESET_MSG:
 			c->Request.CDBLen = 16;
 			c->Request.Type.Attribute = ATTR_SIMPLE;
 			c->Request.Type.Direction = XFER_NONE;
 			c->Request.Timeout = 0;
 			memset(&c->Request.CDB[0], 0, sizeof(c->Request.CDB));
 			c->Request.CDB[0] = cmd;	/* reset */
-			c->Request.CDB[1] = 0x03;	/* reset a target */
+			c->Request.CDB[1] = CCISS_RESET_TYPE_TARGET;
 			break;
-		case 3:	/* No-Op message */
+		case CCISS_NOOP_MSG:
 			c->Request.CDBLen = 1;
 			c->Request.Type.Attribute = ATTR_SIMPLE;
 			c->Request.Type.Direction = XFER_WRITE;
@@ -2615,6 +2643,31 @@
 	return status;
 }
 
+static int __devinit cciss_send_reset(ctlr_info_t *h, unsigned char *scsi3addr,
+	u8 reset_type)
+{
+	CommandList_struct *c;
+	int return_status;
+
+	c = cmd_alloc(h);
+	if (!c)
+		return -ENOMEM;
+	return_status = fill_cmd(h, c, CCISS_RESET_MSG, NULL, 0, 0,
+		CTLR_LUNID, TYPE_MSG);
+	c->Request.CDB[1] = reset_type; /* fill_cmd defaults to target reset */
+	if (return_status != IO_OK) {
+		cmd_special_free(h, c);
+		return return_status;
+	}
+	c->waiting = NULL;
+	enqueue_cmd_and_start_io(h, c);
+	/* Don't wait for completion, the reset won't complete.  Don't free
+	 * the command either.  This is the last command we will send before
+	 * re-initializing everything, so it doesn't matter and won't leak.
+	 */
+	return 0;
+}
+
 static int check_target_status(ctlr_info_t *h, CommandList_struct *c)
 {
 	switch (c->err_info->ScsiStatus) {
@@ -3461,6 +3514,63 @@
 	return next_command(h);
 }
 
+/* Some controllers, like p400, will give us one interrupt
+ * after a soft reset, even if we turned interrupts off.
+ * Only need to check for this in the cciss_xxx_discard_completions
+ * functions.
+ */
+static int ignore_bogus_interrupt(ctlr_info_t *h)
+{
+	if (likely(!reset_devices))
+		return 0;
+
+	if (likely(h->interrupts_enabled))
+		return 0;
+
+	dev_info(&h->pdev->dev, "Received interrupt while interrupts disabled "
+		"(known firmware bug.)  Ignoring.\n");
+
+	return 1;
+}
+
+static irqreturn_t cciss_intx_discard_completions(int irq, void *dev_id)
+{
+	ctlr_info_t *h = dev_id;
+	unsigned long flags;
+	u32 raw_tag;
+
+	if (ignore_bogus_interrupt(h))
+		return IRQ_NONE;
+
+	if (interrupt_not_for_us(h))
+		return IRQ_NONE;
+	spin_lock_irqsave(&h->lock, flags);
+	while (interrupt_pending(h)) {
+		raw_tag = get_next_completion(h);
+		while (raw_tag != FIFO_EMPTY)
+			raw_tag = next_command(h);
+	}
+	spin_unlock_irqrestore(&h->lock, flags);
+	return IRQ_HANDLED;
+}
+
+static irqreturn_t cciss_msix_discard_completions(int irq, void *dev_id)
+{
+	ctlr_info_t *h = dev_id;
+	unsigned long flags;
+	u32 raw_tag;
+
+	if (ignore_bogus_interrupt(h))
+		return IRQ_NONE;
+
+	spin_lock_irqsave(&h->lock, flags);
+	raw_tag = get_next_completion(h);
+	while (raw_tag != FIFO_EMPTY)
+		raw_tag = next_command(h);
+	spin_unlock_irqrestore(&h->lock, flags);
+	return IRQ_HANDLED;
+}
+
 static irqreturn_t do_cciss_intx(int irq, void *dev_id)
 {
 	ctlr_info_t *h = dev_id;
@@ -4078,6 +4188,9 @@
 		cfg_base_addr_index) + cfg_offset, sizeof(h->cfgtable));
 	if (!h->cfgtable)
 		return -ENOMEM;
+	rc = write_driver_ver_to_cfgtable(h->cfgtable);
+	if (rc)
+		return rc;
 	/* Find performant mode table. */
 	trans_offset = readl(&h->cfgtable->TransMethodOffset);
 	h->transtable = remap_pci_mem(pci_resource_start(h->pdev,
@@ -4112,7 +4225,7 @@
 static void __devinit cciss_find_board_params(ctlr_info_t *h)
 {
 	cciss_get_max_perf_mode_cmds(h);
-	h->nr_cmds = h->max_commands - 4; /* Allow room for some ioctls */
+	h->nr_cmds = h->max_commands - 4 - cciss_tape_cmds;
 	h->maxsgentries = readl(&(h->cfgtable->MaxSGElements));
 	/*
 	 * Limit in-command s/g elements to 32 save dma'able memory.
@@ -4348,7 +4461,7 @@
 		tag = readl(vaddr + SA5_REPLY_PORT_OFFSET);
 		if ((tag & ~3) == paddr32)
 			break;
-		schedule_timeout_uninterruptible(HZ);
+		msleep(CCISS_POST_RESET_NOOP_TIMEOUT_MSECS);
 	}
 
 	iounmap(vaddr);
@@ -4375,11 +4488,10 @@
 	return 0;
 }
 
-#define cciss_soft_reset_controller(p) cciss_message(p, 1, 0)
 #define cciss_noop(p) cciss_message(p, 3, 0)
 
 static int cciss_controller_hard_reset(struct pci_dev *pdev,
-	void * __iomem vaddr, bool use_doorbell)
+	void * __iomem vaddr, u32 use_doorbell)
 {
 	u16 pmcsr;
 	int pos;
@@ -4390,8 +4502,7 @@
 		 * other way using the doorbell register.
 		 */
 		dev_info(&pdev->dev, "using doorbell to reset controller\n");
-		writel(DOORBELL_CTLR_RESET, vaddr + SA5_DOORBELL);
-		msleep(1000);
+		writel(use_doorbell, vaddr + SA5_DOORBELL);
 	} else { /* Try to do it the PCI power state way */
 
 		/* Quoting from the Open CISS Specification: "The Power
@@ -4422,12 +4533,64 @@
 		pmcsr &= ~PCI_PM_CTRL_STATE_MASK;
 		pmcsr |= PCI_D0;
 		pci_write_config_word(pdev, pos + PCI_PM_CTRL, pmcsr);
-
-		msleep(500);
 	}
 	return 0;
 }
 
+static __devinit void init_driver_version(char *driver_version, int len)
+{
+	memset(driver_version, 0, len);
+	strncpy(driver_version, "cciss " DRIVER_NAME, len - 1);
+}
+
+static __devinit int write_driver_ver_to_cfgtable(
+	CfgTable_struct __iomem *cfgtable)
+{
+	char *driver_version;
+	int i, size = sizeof(cfgtable->driver_version);
+
+	driver_version = kmalloc(size, GFP_KERNEL);
+	if (!driver_version)
+		return -ENOMEM;
+
+	init_driver_version(driver_version, size);
+	for (i = 0; i < size; i++)
+		writeb(driver_version[i], &cfgtable->driver_version[i]);
+	kfree(driver_version);
+	return 0;
+}
+
+static __devinit void read_driver_ver_from_cfgtable(
+	CfgTable_struct __iomem *cfgtable, unsigned char *driver_ver)
+{
+	int i;
+
+	for (i = 0; i < sizeof(cfgtable->driver_version); i++)
+		driver_ver[i] = readb(&cfgtable->driver_version[i]);
+}
+
+static __devinit int controller_reset_failed(
+	CfgTable_struct __iomem *cfgtable)
+{
+
+	char *driver_ver, *old_driver_ver;
+	int rc, size = sizeof(cfgtable->driver_version);
+
+	old_driver_ver = kmalloc(2 * size, GFP_KERNEL);
+	if (!old_driver_ver)
+		return -ENOMEM;
+	driver_ver = old_driver_ver + size;
+
+	/* After a reset, the 32 bytes of "driver version" in the cfgtable
+	 * should have been changed, otherwise we know the reset failed.
+	 */
+	init_driver_version(old_driver_ver, size);
+	read_driver_ver_from_cfgtable(cfgtable, driver_ver);
+	rc = !memcmp(driver_ver, old_driver_ver, size);
+	kfree(old_driver_ver);
+	return rc;
+}
+
 /* This does a hard reset of the controller using PCI power management
  * states or using the doorbell register. */
 static __devinit int cciss_kdump_hard_reset_controller(struct pci_dev *pdev)
@@ -4437,10 +4600,10 @@
 	u64 cfg_base_addr_index;
 	void __iomem *vaddr;
 	unsigned long paddr;
-	u32 misc_fw_support, active_transport;
+	u32 misc_fw_support;
 	int rc;
 	CfgTable_struct __iomem *cfgtable;
-	bool use_doorbell;
+	u32 use_doorbell;
 	u32 board_id;
 	u16 command_register;
 
@@ -4464,12 +4627,16 @@
 	 * likely not be happy.  Just forbid resetting this conjoined mess.
 	 */
 	cciss_lookup_board_id(pdev, &board_id);
-	if (board_id == 0x409C0E11 || board_id == 0x409D0E11) {
+	if (!ctlr_is_resettable(board_id)) {
 		dev_warn(&pdev->dev, "Cannot reset Smart Array 640x "
 				"due to shared cache module.");
 		return -ENODEV;
 	}
 
+	/* if controller is soft- but not hard resettable... */
+	if (!ctlr_is_hard_resettable(board_id))
+		return -ENOTSUPP; /* try soft reset later. */
+
 	/* Save the PCI command register */
 	pci_read_config_word(pdev, 4, &command_register);
 	/* Turn the board off.  This is so that later pci_restore_state()
@@ -4497,16 +4664,28 @@
 		rc = -ENOMEM;
 		goto unmap_vaddr;
 	}
+	rc = write_driver_ver_to_cfgtable(cfgtable);
+	if (rc)
+		goto unmap_vaddr;
 
-	/* If reset via doorbell register is supported, use that. */
-	misc_fw_support = readl(&cfgtable->misc_fw_support);
-	use_doorbell = misc_fw_support & MISC_FW_DOORBELL_RESET;
-
-	/* The doorbell reset seems to cause lockups on some Smart
-	 * Arrays (e.g. P410, P410i, maybe others).  Until this is
-	 * fixed or at least isolated, avoid the doorbell reset.
+	/* If reset via doorbell register is supported, use that.
+	 * There are two such methods.  Favor the newest method.
 	 */
-	use_doorbell = 0;
+	misc_fw_support = readl(&cfgtable->misc_fw_support);
+	use_doorbell = misc_fw_support & MISC_FW_DOORBELL_RESET2;
+	if (use_doorbell) {
+		use_doorbell = DOORBELL_CTLR_RESET2;
+	} else {
+		use_doorbell = misc_fw_support & MISC_FW_DOORBELL_RESET;
+		if (use_doorbell) {
+			dev_warn(&pdev->dev, "Controller claims that "
+				"'Bit 2 doorbell reset' is "
+				"supported, but not 'bit 5 doorbell reset'.  "
+				"Firmware update is recommended.\n");
+			rc = -ENOTSUPP; /* use the soft reset */
+			goto unmap_cfgtable;
+		}
+	}
 
 	rc = cciss_controller_hard_reset(pdev, vaddr, use_doorbell);
 	if (rc)
@@ -4524,30 +4703,31 @@
 	msleep(CCISS_POST_RESET_PAUSE_MSECS);
 
 	/* Wait for board to become not ready, then ready. */
-	dev_info(&pdev->dev, "Waiting for board to become ready.\n");
+	dev_info(&pdev->dev, "Waiting for board to reset.\n");
 	rc = cciss_wait_for_board_state(pdev, vaddr, BOARD_NOT_READY);
-	if (rc) /* Don't bail, might be E500, etc. which can't be reset */
-		dev_warn(&pdev->dev,
-			"failed waiting for board to become not ready\n");
+	if (rc) {
+		dev_warn(&pdev->dev, "Failed waiting for board to hard reset."
+				"  Will try soft reset.\n");
+		rc = -ENOTSUPP; /* Not expected, but try soft reset later */
+		goto unmap_cfgtable;
+	}
 	rc = cciss_wait_for_board_state(pdev, vaddr, BOARD_READY);
 	if (rc) {
 		dev_warn(&pdev->dev,
-			"failed waiting for board to become ready\n");
+			"failed waiting for board to become ready "
+			"after hard reset\n");
 		goto unmap_cfgtable;
 	}
-	dev_info(&pdev->dev, "board ready.\n");
 
-	/* Controller should be in simple mode at this point.  If it's not,
-	 * It means we're on one of those controllers which doesn't support
-	 * the doorbell reset method and on which the PCI power management reset
-	 * method doesn't work (P800, for example.)
-	 * In those cases, don't try to proceed, as it generally doesn't work.
-	 */
-	active_transport = readl(&cfgtable->TransportActive);
-	if (active_transport & PERFORMANT_MODE) {
-		dev_warn(&pdev->dev, "Unable to successfully reset controller,"
-			" Ignoring controller.\n");
-		rc = -ENODEV;
+	rc = controller_reset_failed(vaddr);
+	if (rc < 0)
+		goto unmap_cfgtable;
+	if (rc) {
+		dev_warn(&pdev->dev, "Unable to successfully hard reset "
+			"controller. Will try soft reset.\n");
+		rc = -ENOTSUPP; /* Not expected, but try soft reset later */
+	} else {
+		dev_info(&pdev->dev, "Board ready after hard reset.\n");
 	}
 
 unmap_cfgtable:
@@ -4574,11 +4754,12 @@
 	 * due to concerns about shared bbwc between 6402/6404 pair.
 	 */
 	if (rc == -ENOTSUPP)
-		return 0; /* just try to do the kdump anyhow. */
+		return rc; /* just try to do the kdump anyhow. */
 	if (rc)
 		return -ENODEV;
 
 	/* Now try to get the controller to respond to a no-op */
+	dev_warn(&pdev->dev, "Waiting for controller to respond to no-op\n");
 	for (i = 0; i < CCISS_POST_RESET_NOOP_RETRIES; i++) {
 		if (cciss_noop(pdev) == 0)
 			break;
@@ -4591,6 +4772,148 @@
 	return 0;
 }
 
+static __devinit int cciss_allocate_cmd_pool(ctlr_info_t *h)
+{
+	h->cmd_pool_bits = kmalloc(
+		DIV_ROUND_UP(h->nr_cmds, BITS_PER_LONG) *
+		sizeof(unsigned long), GFP_KERNEL);
+	h->cmd_pool = pci_alloc_consistent(h->pdev,
+		h->nr_cmds * sizeof(CommandList_struct),
+		&(h->cmd_pool_dhandle));
+	h->errinfo_pool = pci_alloc_consistent(h->pdev,
+		h->nr_cmds * sizeof(ErrorInfo_struct),
+		&(h->errinfo_pool_dhandle));
+	if ((h->cmd_pool_bits == NULL)
+		|| (h->cmd_pool == NULL)
+		|| (h->errinfo_pool == NULL)) {
+		dev_err(&h->pdev->dev, "out of memory");
+		return -ENOMEM;
+	}
+	return 0;
+}
+
+static __devinit int cciss_allocate_scatterlists(ctlr_info_t *h)
+{
+	int i;
+
+	/* zero it, so that on free we need not know how many were alloc'ed */
+	h->scatter_list = kzalloc(h->max_commands *
+				sizeof(struct scatterlist *), GFP_KERNEL);
+	if (!h->scatter_list)
+		return -ENOMEM;
+
+	for (i = 0; i < h->nr_cmds; i++) {
+		h->scatter_list[i] = kmalloc(sizeof(struct scatterlist) *
+						h->maxsgentries, GFP_KERNEL);
+		if (h->scatter_list[i] == NULL) {
+			dev_err(&h->pdev->dev, "could not allocate "
+				"s/g lists\n");
+			return -ENOMEM;
+		}
+	}
+	return 0;
+}
+
+static void cciss_free_scatterlists(ctlr_info_t *h)
+{
+	int i;
+
+	if (h->scatter_list) {
+		for (i = 0; i < h->nr_cmds; i++)
+			kfree(h->scatter_list[i]);
+		kfree(h->scatter_list);
+	}
+}
+
+static void cciss_free_cmd_pool(ctlr_info_t *h)
+{
+	kfree(h->cmd_pool_bits);
+	if (h->cmd_pool)
+		pci_free_consistent(h->pdev,
+			h->nr_cmds * sizeof(CommandList_struct),
+			h->cmd_pool, h->cmd_pool_dhandle);
+	if (h->errinfo_pool)
+		pci_free_consistent(h->pdev,
+			h->nr_cmds * sizeof(ErrorInfo_struct),
+			h->errinfo_pool, h->errinfo_pool_dhandle);
+}
+
+static int cciss_request_irq(ctlr_info_t *h,
+	irqreturn_t (*msixhandler)(int, void *),
+	irqreturn_t (*intxhandler)(int, void *))
+{
+	if (h->msix_vector || h->msi_vector) {
+		if (!request_irq(h->intr[PERF_MODE_INT], msixhandler,
+				IRQF_DISABLED, h->devname, h))
+			return 0;
+		dev_err(&h->pdev->dev, "Unable to get msi irq %d"
+			" for %s\n", h->intr[PERF_MODE_INT],
+			h->devname);
+		return -1;
+	}
+
+	if (!request_irq(h->intr[PERF_MODE_INT], intxhandler,
+			IRQF_DISABLED, h->devname, h))
+		return 0;
+	dev_err(&h->pdev->dev, "Unable to get irq %d for %s\n",
+		h->intr[PERF_MODE_INT], h->devname);
+	return -1;
+}
+
+static int __devinit cciss_kdump_soft_reset(ctlr_info_t *h)
+{
+	if (cciss_send_reset(h, CTLR_LUNID, CCISS_RESET_TYPE_CONTROLLER)) {
+		dev_warn(&h->pdev->dev, "Resetting array controller failed.\n");
+		return -EIO;
+	}
+
+	dev_info(&h->pdev->dev, "Waiting for board to soft reset.\n");
+	if (cciss_wait_for_board_state(h->pdev, h->vaddr, BOARD_NOT_READY)) {
+		dev_warn(&h->pdev->dev, "Soft reset had no effect.\n");
+		return -1;
+	}
+
+	dev_info(&h->pdev->dev, "Board reset, awaiting READY status.\n");
+	if (cciss_wait_for_board_state(h->pdev, h->vaddr, BOARD_READY)) {
+		dev_warn(&h->pdev->dev, "Board failed to become ready "
+			"after soft reset.\n");
+		return -1;
+	}
+
+	return 0;
+}
+
+static void cciss_undo_allocations_after_kdump_soft_reset(ctlr_info_t *h)
+{
+	int ctlr = h->ctlr;
+
+	free_irq(h->intr[PERF_MODE_INT], h);
+#ifdef CONFIG_PCI_MSI
+	if (h->msix_vector)
+		pci_disable_msix(h->pdev);
+	else if (h->msi_vector)
+		pci_disable_msi(h->pdev);
+#endif /* CONFIG_PCI_MSI */
+	cciss_free_sg_chain_blocks(h->cmd_sg_list, h->nr_cmds);
+	cciss_free_scatterlists(h);
+	cciss_free_cmd_pool(h);
+	kfree(h->blockFetchTable);
+	if (h->reply_pool)
+		pci_free_consistent(h->pdev, h->max_commands * sizeof(__u64),
+				h->reply_pool, h->reply_pool_dhandle);
+	if (h->transtable)
+		iounmap(h->transtable);
+	if (h->cfgtable)
+		iounmap(h->cfgtable);
+	if (h->vaddr)
+		iounmap(h->vaddr);
+	unregister_blkdev(h->major, h->devname);
+	cciss_destroy_hba_sysfs_entry(h);
+	pci_release_regions(h->pdev);
+	kfree(h);
+	hba[ctlr] = NULL;
+}
+
 /*
  *  This is it.  Find all the controllers and register them.  I really hate
  *  stealing all these major device numbers.
@@ -4601,15 +4924,28 @@
 {
 	int i;
 	int j = 0;
-	int k = 0;
 	int rc;
+	int try_soft_reset = 0;
 	int dac, return_code;
 	InquiryData_struct *inq_buff;
 	ctlr_info_t *h;
+	unsigned long flags;
 
 	rc = cciss_init_reset_devices(pdev);
-	if (rc)
-		return rc;
+	if (rc) {
+		if (rc != -ENOTSUPP)
+			return rc;
+		/* If the reset fails in a particular way (it has no way to do
+		 * a proper hard reset, so returns -ENOTSUPP) we can try to do
+		 * a soft reset once we get the controller configured up to the
+		 * point that it can accept a command.
+		 */
+		try_soft_reset = 1;
+		rc = 0;
+	}
+
+reinit_after_soft_reset:
+
 	i = alloc_cciss_hba(pdev);
 	if (i < 0)
 		return -1;
@@ -4627,6 +4963,11 @@
 	sprintf(h->devname, "cciss%d", i);
 	h->ctlr = i;
 
+	if (cciss_tape_cmds < 2)
+		cciss_tape_cmds = 2;
+	if (cciss_tape_cmds > 16)
+		cciss_tape_cmds = 16;
+
 	init_completion(&h->scan_wait);
 
 	if (cciss_create_hba_sysfs_entry(h))
@@ -4662,62 +5003,20 @@
 
 	/* make sure the board interrupts are off */
 	h->access.set_intr_mask(h, CCISS_INTR_OFF);
-	if (h->msi_vector || h->msix_vector) {
-		if (request_irq(h->intr[PERF_MODE_INT],
-				do_cciss_msix_intr,
-				IRQF_DISABLED, h->devname, h)) {
-			dev_err(&h->pdev->dev, "Unable to get irq %d for %s\n",
-			       h->intr[PERF_MODE_INT], h->devname);
-			goto clean2;
-		}
-	} else {
-		if (request_irq(h->intr[PERF_MODE_INT], do_cciss_intx,
-				IRQF_DISABLED, h->devname, h)) {
-			dev_err(&h->pdev->dev, "Unable to get irq %d for %s\n",
-			       h->intr[PERF_MODE_INT], h->devname);
-			goto clean2;
-		}
-	}
+	rc = cciss_request_irq(h, do_cciss_msix_intr, do_cciss_intx);
+	if (rc)
+		goto clean2;
 
 	dev_info(&h->pdev->dev, "%s: <0x%x> at PCI %s IRQ %d%s using DAC\n",
 	       h->devname, pdev->device, pci_name(pdev),
 	       h->intr[PERF_MODE_INT], dac ? "" : " not");
 
-	h->cmd_pool_bits =
-	    kmalloc(DIV_ROUND_UP(h->nr_cmds, BITS_PER_LONG)
-			* sizeof(unsigned long), GFP_KERNEL);
-	h->cmd_pool = (CommandList_struct *)
-	    pci_alloc_consistent(h->pdev,
-		    h->nr_cmds * sizeof(CommandList_struct),
-		    &(h->cmd_pool_dhandle));
-	h->errinfo_pool = (ErrorInfo_struct *)
-	    pci_alloc_consistent(h->pdev,
-		    h->nr_cmds * sizeof(ErrorInfo_struct),
-		    &(h->errinfo_pool_dhandle));
-	if ((h->cmd_pool_bits == NULL)
-	    || (h->cmd_pool == NULL)
-	    || (h->errinfo_pool == NULL)) {
-		dev_err(&h->pdev->dev, "out of memory");
+	if (cciss_allocate_cmd_pool(h))
 		goto clean4;
-	}
 
-	/* Need space for temp scatter list */
-	h->scatter_list = kmalloc(h->max_commands *
-						sizeof(struct scatterlist *),
-						GFP_KERNEL);
-	if (!h->scatter_list)
+	if (cciss_allocate_scatterlists(h))
 		goto clean4;
 
-	for (k = 0; k < h->nr_cmds; k++) {
-		h->scatter_list[k] = kmalloc(sizeof(struct scatterlist) *
-							h->maxsgentries,
-							GFP_KERNEL);
-		if (h->scatter_list[k] == NULL) {
-			dev_err(&h->pdev->dev,
-				"could not allocate s/g lists\n");
-			goto clean4;
-		}
-	}
 	h->cmd_sg_list = cciss_allocate_sg_chain_blocks(h,
 		h->chainsize, h->nr_cmds);
 	if (!h->cmd_sg_list && h->chainsize > 0)
@@ -4741,6 +5040,62 @@
 		h->gendisk[j] = NULL;
 	}
 
+	/* At this point, the controller is ready to take commands.
+	 * Now, if reset_devices and the hard reset didn't work, try
+	 * the soft reset and see if that works.
+	 */
+	if (try_soft_reset) {
+
+		/* This is kind of gross.  We may or may not get a completion
+		 * from the soft reset command, and if we do, then the value
+		 * from the fifo may or may not be valid.  So, we wait 10 secs
+		 * after the reset throwing away any completions we get during
+		 * that time.  Unregister the interrupt handler and register
+		 * fake ones to scoop up any residual completions.
+		 */
+		spin_lock_irqsave(&h->lock, flags);
+		h->access.set_intr_mask(h, CCISS_INTR_OFF);
+		spin_unlock_irqrestore(&h->lock, flags);
+		free_irq(h->intr[PERF_MODE_INT], h);
+		rc = cciss_request_irq(h, cciss_msix_discard_completions,
+					cciss_intx_discard_completions);
+		if (rc) {
+			dev_warn(&h->pdev->dev, "Failed to request_irq after "
+				"soft reset.\n");
+			goto clean4;
+		}
+
+		rc = cciss_kdump_soft_reset(h);
+		if (rc) {
+			dev_warn(&h->pdev->dev, "Soft reset failed.\n");
+			goto clean4;
+		}
+
+		dev_info(&h->pdev->dev, "Board READY.\n");
+		dev_info(&h->pdev->dev,
+			"Waiting for stale completions to drain.\n");
+		h->access.set_intr_mask(h, CCISS_INTR_ON);
+		msleep(10000);
+		h->access.set_intr_mask(h, CCISS_INTR_OFF);
+
+		rc = controller_reset_failed(h->cfgtable);
+		if (rc)
+			dev_info(&h->pdev->dev,
+				"Soft reset appears to have failed.\n");
+
+		/* since the controller's reset, we have to go back and re-init
+		 * everything.  Easiest to just forget what we've done and do it
+		 * all over again.
+		 */
+		cciss_undo_allocations_after_kdump_soft_reset(h);
+		try_soft_reset = 0;
+		if (rc)
+			/* don't go to clean4, we already unallocated */
+			return -ENODEV;
+
+		goto reinit_after_soft_reset;
+	}
+
 	cciss_scsi_setup(h);
 
 	/* Turn the interrupts on so we can service requests */
@@ -4775,21 +5130,9 @@
 	return 1;
 
 clean4:
-	kfree(h->cmd_pool_bits);
-	/* Free up sg elements */
-	for (k-- ; k >= 0; k--)
-		kfree(h->scatter_list[k]);
-	kfree(h->scatter_list);
+	cciss_free_cmd_pool(h);
+	cciss_free_scatterlists(h);
 	cciss_free_sg_chain_blocks(h->cmd_sg_list, h->nr_cmds);
-	if (h->cmd_pool)
-		pci_free_consistent(h->pdev,
-				    h->nr_cmds * sizeof(CommandList_struct),
-				    h->cmd_pool, h->cmd_pool_dhandle);
-	if (h->errinfo_pool)
-		pci_free_consistent(h->pdev,
-				    h->nr_cmds * sizeof(ErrorInfo_struct),
-				    h->errinfo_pool,
-				    h->errinfo_pool_dhandle);
 	free_irq(h->intr[PERF_MODE_INT], h);
 clean2:
 	unregister_blkdev(h->major, h->devname);
@@ -4887,16 +5230,16 @@
 	iounmap(h->cfgtable);
 	iounmap(h->vaddr);
 
-	pci_free_consistent(h->pdev, h->nr_cmds * sizeof(CommandList_struct),
-			    h->cmd_pool, h->cmd_pool_dhandle);
-	pci_free_consistent(h->pdev, h->nr_cmds * sizeof(ErrorInfo_struct),
-			    h->errinfo_pool, h->errinfo_pool_dhandle);
-	kfree(h->cmd_pool_bits);
+	cciss_free_cmd_pool(h);
 	/* Free up sg elements */
 	for (j = 0; j < h->nr_cmds; j++)
 		kfree(h->scatter_list[j]);
 	kfree(h->scatter_list);
 	cciss_free_sg_chain_blocks(h->cmd_sg_list, h->nr_cmds);
+	kfree(h->blockFetchTable);
+	if (h->reply_pool)
+		pci_free_consistent(h->pdev, h->max_commands * sizeof(__u64),
+				h->reply_pool, h->reply_pool_dhandle);
 	/*
 	 * Deliberately omit pci_disable_device(): it does something nasty to
 	 * Smart Array controllers that pci_enable_device does not undo
diff -druN linux-2.6.39-libre/drivers/block/cciss_cmd.h linux-3.0-rc7-libre/drivers/block/cciss_cmd.h
--- linux-2.6.39-libre/drivers/block/cciss_cmd.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/block/cciss_cmd.h	2011-07-11 19:51:52.000000000 -0400
@@ -53,6 +53,7 @@
 #define CFGTBL_ChangeReq        0x00000001l
 #define CFGTBL_AccCmds          0x00000001l
 #define DOORBELL_CTLR_RESET     0x00000004l
+#define DOORBELL_CTLR_RESET2    0x00000020l
 
 #define CFGTBL_Trans_Simple     0x00000002l
 #define CFGTBL_Trans_Performant 0x00000004l
@@ -142,6 +143,14 @@
 #define BMIC_CACHE_FLUSH 0xc2
 #define CCISS_CACHE_FLUSH 0x01	/* C2 was already being used by CCISS */
 
+#define CCISS_ABORT_MSG 0x00
+#define CCISS_RESET_MSG 0x01
+#define CCISS_RESET_TYPE_CONTROLLER 0x00
+#define CCISS_RESET_TYPE_BUS 0x01
+#define CCISS_RESET_TYPE_TARGET 0x03
+#define CCISS_RESET_TYPE_LUN 0x04
+#define CCISS_NOOP_MSG 0x03
+
 /* Command List Structure */
 #define CTLR_LUNID "\0\0\0\0\0\0\0\0"
 
@@ -235,6 +244,8 @@
   u8		   reserved[0x78 - 0x58];
   u32		   misc_fw_support; /* offset 0x78 */
 #define MISC_FW_DOORBELL_RESET (0x02)
+#define MISC_FW_DOORBELL_RESET2 (0x10)
+	u8	   driver_version[32];
 } CfgTable_struct;
 
 struct TransTable_struct {
diff -druN linux-2.6.39-libre/drivers/block/cciss.h linux-3.0-rc7-libre/drivers/block/cciss.h
--- linux-2.6.39-libre/drivers/block/cciss.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/block/cciss.h	2011-07-11 19:51:52.000000000 -0400
@@ -200,7 +200,7 @@
  * the above.
  */
 #define CCISS_BOARD_READY_WAIT_SECS (120)
-#define CCISS_BOARD_NOT_READY_WAIT_SECS (10)
+#define CCISS_BOARD_NOT_READY_WAIT_SECS (100)
 #define CCISS_BOARD_READY_POLL_INTERVAL_MSECS (100)
 #define CCISS_BOARD_READY_ITERATIONS \
 	((CCISS_BOARD_READY_WAIT_SECS * 1000) / \
@@ -209,8 +209,9 @@
 	((CCISS_BOARD_NOT_READY_WAIT_SECS * 1000) / \
 		CCISS_BOARD_READY_POLL_INTERVAL_MSECS)
 #define CCISS_POST_RESET_PAUSE_MSECS (3000)
-#define CCISS_POST_RESET_NOOP_INTERVAL_MSECS (1000)
+#define CCISS_POST_RESET_NOOP_INTERVAL_MSECS (4000)
 #define CCISS_POST_RESET_NOOP_RETRIES (12)
+#define CCISS_POST_RESET_NOOP_TIMEOUT_MSECS (10000)
 
 /* 
 	Send the command to the hardware 
@@ -239,11 +240,13 @@
 	{ /* Turn interrupts on */
 		h->interrupts_enabled = 1;
 		writel(0, h->vaddr + SA5_REPLY_INTR_MASK_OFFSET);
+		(void) readl(h->vaddr + SA5_REPLY_INTR_MASK_OFFSET);
 	} else /* Turn them off */
 	{
 		h->interrupts_enabled = 0;
         	writel( SA5_INTR_OFF, 
 			h->vaddr + SA5_REPLY_INTR_MASK_OFFSET);
+		(void) readl(h->vaddr + SA5_REPLY_INTR_MASK_OFFSET);
 	}
 }
 /*
@@ -257,11 +260,13 @@
         { /* Turn interrupts on */
 		h->interrupts_enabled = 1;
                 writel(0, h->vaddr + SA5_REPLY_INTR_MASK_OFFSET);
+		(void) readl(h->vaddr + SA5_REPLY_INTR_MASK_OFFSET);
         } else /* Turn them off */
         {
 		h->interrupts_enabled = 0;
                 writel( SA5B_INTR_OFF,
                         h->vaddr + SA5_REPLY_INTR_MASK_OFFSET);
+		(void) readl(h->vaddr + SA5_REPLY_INTR_MASK_OFFSET);
         }
 }
 
@@ -271,10 +276,12 @@
 	if (val) { /* turn on interrupts */
 		h->interrupts_enabled = 1;
 		writel(0, h->vaddr + SA5_REPLY_INTR_MASK_OFFSET);
+		(void) readl(h->vaddr + SA5_REPLY_INTR_MASK_OFFSET);
 	} else {
 		h->interrupts_enabled = 0;
 		writel(SA5_PERF_INTR_OFF,
 				h->vaddr + SA5_REPLY_INTR_MASK_OFFSET);
+		(void) readl(h->vaddr + SA5_REPLY_INTR_MASK_OFFSET);
 	}
 }
 
diff -druN linux-2.6.39-libre/drivers/block/cciss_scsi.c linux-3.0-rc7-libre/drivers/block/cciss_scsi.c
--- linux-2.6.39-libre/drivers/block/cciss_scsi.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/block/cciss_scsi.c	2011-07-11 19:51:52.000000000 -0400
@@ -84,7 +84,6 @@
 	.proc_name		= "cciss",
 	.proc_info		= cciss_scsi_proc_info,
 	.queuecommand		= cciss_scsi_queue_command,
-	.can_queue		= SCSI_CCISS_CAN_QUEUE,
 	.this_id		= 7,
 	.cmd_per_lun		= 1,
 	.use_clustering		= DISABLE_CLUSTERING,
@@ -108,16 +107,13 @@
 
 #pragma pack()
 
-#define CMD_STACK_SIZE (SCSI_CCISS_CAN_QUEUE * \
-		CCISS_MAX_SCSI_DEVS_PER_HBA + 2)
-			// plus two for init time usage
-
 #pragma pack(1)
 struct cciss_scsi_cmd_stack_t {
 	struct cciss_scsi_cmd_stack_elem_t *pool;
-	struct cciss_scsi_cmd_stack_elem_t *elem[CMD_STACK_SIZE];
+	struct cciss_scsi_cmd_stack_elem_t **elem;
 	dma_addr_t cmd_pool_handle;
 	int top;
+	int nelems;
 };
 #pragma pack()
 
@@ -191,7 +187,7 @@
 	sa = h->scsi_ctlr;
 	stk = &sa->cmd_stack; 
 	stk->top++;
-	if (stk->top >= CMD_STACK_SIZE) {
+	if (stk->top >= stk->nelems) {
 		dev_err(&h->pdev->dev,
 			"scsi_cmd_free called too many times.\n");
 		BUG();
@@ -206,13 +202,14 @@
 	struct cciss_scsi_cmd_stack_t *stk;
 	size_t size;
 
+	stk = &sa->cmd_stack;
+	stk->nelems = cciss_tape_cmds + 2;
 	sa->cmd_sg_list = cciss_allocate_sg_chain_blocks(h,
-		h->chainsize, CMD_STACK_SIZE);
+		h->chainsize, stk->nelems);
 	if (!sa->cmd_sg_list && h->chainsize > 0)
 		return -ENOMEM;
 
-	stk = &sa->cmd_stack; 
-	size = sizeof(struct cciss_scsi_cmd_stack_elem_t) * CMD_STACK_SIZE;
+	size = sizeof(struct cciss_scsi_cmd_stack_elem_t) * stk->nelems;
 
 	/* Check alignment, see cciss_cmd.h near CommandList_struct def. */
 	BUILD_BUG_ON((sizeof(*stk->pool) % COMMANDLIST_ALIGNMENT) != 0);
@@ -221,18 +218,23 @@
 		pci_alloc_consistent(h->pdev, size, &stk->cmd_pool_handle);
 
 	if (stk->pool == NULL) {
-		cciss_free_sg_chain_blocks(sa->cmd_sg_list, CMD_STACK_SIZE);
+		cciss_free_sg_chain_blocks(sa->cmd_sg_list, stk->nelems);
 		sa->cmd_sg_list = NULL;
 		return -ENOMEM;
 	}
-
-	for (i=0; i<CMD_STACK_SIZE; i++) {
+	stk->elem = kmalloc(sizeof(stk->elem[0]) * stk->nelems, GFP_KERNEL);
+	if (!stk->elem) {
+		pci_free_consistent(h->pdev, size, stk->pool,
+		stk->cmd_pool_handle);
+		return -1;
+	}
+	for (i = 0; i < stk->nelems; 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;
+	stk->top = stk->nelems-1;
 	return 0;
 }
 
@@ -245,16 +247,18 @@
 
 	sa = h->scsi_ctlr;
 	stk = &sa->cmd_stack; 
-	if (stk->top != CMD_STACK_SIZE-1) {
+	if (stk->top != stk->nelems-1) {
 		dev_warn(&h->pdev->dev,
 			"bug: %d scsi commands are still outstanding.\n",
-			CMD_STACK_SIZE - stk->top);
+			stk->nelems - stk->top);
 	}
-	size = sizeof(struct cciss_scsi_cmd_stack_elem_t) * CMD_STACK_SIZE;
+	size = sizeof(struct cciss_scsi_cmd_stack_elem_t) * stk->nelems;
 
 	pci_free_consistent(h->pdev, size, stk->pool, stk->cmd_pool_handle);
 	stk->pool = NULL;
-	cciss_free_sg_chain_blocks(sa->cmd_sg_list, CMD_STACK_SIZE);
+	cciss_free_sg_chain_blocks(sa->cmd_sg_list, stk->nelems);
+	kfree(stk->elem);
+	stk->elem = NULL;
 }
 
 #if 0
@@ -859,6 +863,7 @@
 	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->can_queue = cciss_tape_cmds;
 	sh->sg_tablesize = h->maxsgentries;
 	sh->max_cmd_len = MAX_COMMAND_SIZE;
 
diff -druN linux-2.6.39-libre/drivers/block/cciss_scsi.h linux-3.0-rc7-libre/drivers/block/cciss_scsi.h
--- linux-2.6.39-libre/drivers/block/cciss_scsi.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/block/cciss_scsi.h	2011-07-11 19:51:52.000000000 -0400
@@ -36,13 +36,9 @@
 		   addressible natively, and may in fact turn
 		   out to be not scsi at all. */
 
-#define SCSI_CCISS_CAN_QUEUE 2
 
 /* 
 
-Note, cmd_per_lun could give us some trouble, so I'm setting it very low.
-Likewise, SCSI_CCISS_CAN_QUEUE is set very conservatively.
-
 If the upper scsi layer tries to track how many commands we have 
 outstanding, it will be operating under the misapprehension that it is
 the only one sending us requests.  We also have the block interface,
diff -druN linux-2.6.39-libre/drivers/block/drbd/drbd_actlog.c linux-3.0-rc7-libre/drivers/block/drbd/drbd_actlog.c
--- linux-2.6.39-libre/drivers/block/drbd/drbd_actlog.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/block/drbd/drbd_actlog.c	2011-07-11 19:51:52.000000000 -0400
@@ -28,7 +28,7 @@
 #include "drbd_int.h"
 #include "drbd_wrappers.h"
 
-/* We maintain a trivial check sum in our on disk activity log.
+/* We maintain a trivial checksum in our on disk activity log.
  * With that we can ensure correct operation even when the storage
  * device might do a partial (last) sector write while losing power.
  */
@@ -79,7 +79,7 @@
 	md_io.error = 0;
 
 	if ((rw & WRITE) && !test_bit(MD_NO_FUA, &mdev->flags))
-		rw |= REQ_FUA;
+		rw |= REQ_FUA | REQ_FLUSH;
 	rw |= REQ_SYNC;
 
 	bio = bio_alloc(GFP_NOIO, 1);
diff -druN linux-2.6.39-libre/drivers/block/drbd/drbd_bitmap.c linux-3.0-rc7-libre/drivers/block/drbd/drbd_bitmap.c
--- linux-2.6.39-libre/drivers/block/drbd/drbd_bitmap.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/block/drbd/drbd_bitmap.c	2011-07-11 19:51:52.000000000 -0400
@@ -74,7 +74,7 @@
  *	as we are "attached" to a local disk, which at 32 GiB for 1PiB storage
  *	seems excessive.
  *
- *	We plan to reduce the amount of in-core bitmap pages by pageing them in
+ *	We plan to reduce the amount of in-core bitmap pages by paging them in
  *	and out against their on-disk location as necessary, but need to make
  *	sure we don't cause too much meta data IO, and must not deadlock in
  *	tight memory situations. This needs some more work.
@@ -112,9 +112,6 @@
 	struct task_struct *bm_task;
 };
 
-static int __bm_change_bits_to(struct drbd_conf *mdev, const unsigned long s,
-			       unsigned long e, int val, const enum km_type km);
-
 #define bm_print_lock_info(m) __bm_print_lock_info(m, __func__)
 static void __bm_print_lock_info(struct drbd_conf *mdev, const char *func)
 {
@@ -200,7 +197,7 @@
  * we if bits have been cleared since last IO. */
 #define BM_PAGE_LAZY_WRITEOUT	28
 
-/* store_page_idx uses non-atomic assingment. It is only used directly after
+/* store_page_idx uses non-atomic assignment. It is only used directly after
  * allocating the page.  All other bm_set_page_* and bm_clear_page_* need to
  * use atomic bit manipulation, as set_out_of_sync (and therefore bitmap
  * changes) may happen from various contexts, and wait_on_bit/wake_up_bit
@@ -318,7 +315,7 @@
 /* word offset from start of bitmap to word number _in_page_
  * modulo longs per page
 #define MLPP(X) ((X) % (PAGE_SIZE/sizeof(long))
- hm, well, Philipp thinks gcc might not optimze the % into & (... - 1)
+ hm, well, Philipp thinks gcc might not optimize the % into & (... - 1)
  so do it explicitly:
  */
 #define MLPP(X) ((X) & ((PAGE_SIZE/sizeof(long))-1))
@@ -994,6 +991,9 @@
 		bio_endio(bio, -EIO);
 	} else {
 		submit_bio(rw, bio);
+		/* this should not count as user activity and cause the
+		 * resync to throttle -- see drbd_rs_should_slow_down(). */
+		atomic_add(len >> 9, &mdev->rs_sect_ev);
 	}
 }
 
@@ -1256,7 +1256,7 @@
  * expected to be called for only a few bits (e - s about BITS_PER_LONG).
  * Must hold bitmap lock already. */
 static int __bm_change_bits_to(struct drbd_conf *mdev, const unsigned long s,
-	unsigned long e, int val, const enum km_type km)
+	unsigned long e, int val)
 {
 	struct drbd_bitmap *b = mdev->bitmap;
 	unsigned long *p_addr = NULL;
@@ -1274,14 +1274,14 @@
 		unsigned int page_nr = bm_bit_to_page_idx(b, bitnr);
 		if (page_nr != last_page_nr) {
 			if (p_addr)
-				__bm_unmap(p_addr, km);
+				__bm_unmap(p_addr, KM_IRQ1);
 			if (c < 0)
 				bm_set_page_lazy_writeout(b->bm_pages[last_page_nr]);
 			else if (c > 0)
 				bm_set_page_need_writeout(b->bm_pages[last_page_nr]);
 			changed_total += c;
 			c = 0;
-			p_addr = __bm_map_pidx(b, page_nr, km);
+			p_addr = __bm_map_pidx(b, page_nr, KM_IRQ1);
 			last_page_nr = page_nr;
 		}
 		if (val)
@@ -1290,7 +1290,7 @@
 			c -= (0 != __test_and_clear_bit_le(bitnr & BITS_PER_PAGE_MASK, p_addr));
 	}
 	if (p_addr)
-		__bm_unmap(p_addr, km);
+		__bm_unmap(p_addr, KM_IRQ1);
 	if (c < 0)
 		bm_set_page_lazy_writeout(b->bm_pages[last_page_nr]);
 	else if (c > 0)
@@ -1318,7 +1318,7 @@
 	if ((val ? BM_DONT_SET : BM_DONT_CLEAR) & b->bm_flags)
 		bm_print_lock_info(mdev);
 
-	c = __bm_change_bits_to(mdev, s, e, val, KM_IRQ1);
+	c = __bm_change_bits_to(mdev, s, e, val);
 
 	spin_unlock_irqrestore(&b->bm_lock, flags);
 	return c;
@@ -1343,16 +1343,17 @@
 {
 	int i;
 	int bits;
-	unsigned long *paddr = kmap_atomic(b->bm_pages[page_nr], KM_USER0);
+	unsigned long *paddr = kmap_atomic(b->bm_pages[page_nr], KM_IRQ1);
 	for (i = first_word; i < last_word; i++) {
 		bits = hweight_long(paddr[i]);
 		paddr[i] = ~0UL;
 		b->bm_set += BITS_PER_LONG - bits;
 	}
-	kunmap_atomic(paddr, KM_USER0);
+	kunmap_atomic(paddr, KM_IRQ1);
 }
 
-/* Same thing as drbd_bm_set_bits, but without taking the spin_lock_irqsave.
+/* Same thing as drbd_bm_set_bits,
+ * but more efficient for a large bit range.
  * You must first drbd_bm_lock().
  * Can be called to set the whole bitmap in one go.
  * Sets bits from s to e _inclusive_. */
@@ -1366,6 +1367,7 @@
 	 * Do not use memset, because we must account for changes,
 	 * so we need to loop over the words with hweight() anyways.
 	 */
+	struct drbd_bitmap *b = mdev->bitmap;
 	unsigned long sl = ALIGN(s,BITS_PER_LONG);
 	unsigned long el = (e+1) & ~((unsigned long)BITS_PER_LONG-1);
 	int first_page;
@@ -1376,15 +1378,19 @@
 
 	if (e - s <= 3*BITS_PER_LONG) {
 		/* don't bother; el and sl may even be wrong. */
-		__bm_change_bits_to(mdev, s, e, 1, KM_USER0);
+		spin_lock_irq(&b->bm_lock);
+		__bm_change_bits_to(mdev, s, e, 1);
+		spin_unlock_irq(&b->bm_lock);
 		return;
 	}
 
 	/* difference is large enough that we can trust sl and el */
 
+	spin_lock_irq(&b->bm_lock);
+
 	/* bits filling the current long */
 	if (sl)
-		__bm_change_bits_to(mdev, s, sl-1, 1, KM_USER0);
+		__bm_change_bits_to(mdev, s, sl-1, 1);
 
 	first_page = sl >> (3 + PAGE_SHIFT);
 	last_page = el >> (3 + PAGE_SHIFT);
@@ -1397,8 +1403,10 @@
 	/* first and full pages, unless first page == last page */
 	for (page_nr = first_page; page_nr < last_page; page_nr++) {
 		bm_set_full_words_within_one_page(mdev->bitmap, page_nr, first_word, last_word);
+		spin_unlock_irq(&b->bm_lock);
 		cond_resched();
 		first_word = 0;
+		spin_lock_irq(&b->bm_lock);
 	}
 
 	/* last page (respectively only page, for first page == last page) */
@@ -1411,7 +1419,8 @@
 	 * it would trigger an assert in __bm_change_bits_to()
 	 */
 	if (el <= e)
-		__bm_change_bits_to(mdev, el, e, 1, KM_USER0);
+		__bm_change_bits_to(mdev, el, e, 1);
+	spin_unlock_irq(&b->bm_lock);
 }
 
 /* returns bit state
diff -druN linux-2.6.39-libre/drivers/block/drbd/drbd_int.h linux-3.0-rc7-libre/drivers/block/drbd/drbd_int.h
--- linux-2.6.39-libre/drivers/block/drbd/drbd_int.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/block/drbd/drbd_int.h	2011-07-11 19:51:52.000000000 -0400
@@ -42,6 +42,7 @@
 #include <linux/genhd.h>
 #include <net/tcp.h>
 #include <linux/lru_cache.h>
+#include <linux/prefetch.h>
 
 #ifdef __CHECKER__
 # define __protected_by(x)       __attribute__((require_context(x,1,999,"rdwr")))
@@ -699,7 +700,7 @@
 	 * see drbd_endio_pri(). */
 	struct bio *private_bio;
 
-	struct hlist_node colision;
+	struct hlist_node collision;
 	sector_t sector;
 	unsigned int size;
 	unsigned int epoch; /* barrier_nr */
@@ -765,7 +766,7 @@
 
 struct drbd_epoch_entry {
 	struct drbd_work w;
-	struct hlist_node colision;
+	struct hlist_node collision;
 	struct drbd_epoch *epoch; /* for writes */
 	struct drbd_conf *mdev;
 	struct page *pages;
@@ -1128,6 +1129,8 @@
 	int rs_in_flight; /* resync sectors in flight (to proxy, in proxy and from proxy) */
 	int rs_planed;    /* resync sectors already planned */
 	atomic_t ap_in_flight; /* App sectors in flight (waiting for ack) */
+	int peer_max_bio_size;
+	int local_max_bio_size;
 };
 
 static inline struct drbd_conf *minor_to_mdev(unsigned int minor)
@@ -1217,8 +1220,6 @@
 extern void tl_release(struct drbd_conf *mdev, unsigned int barrier_nr,
 		       unsigned int set_size);
 extern void tl_clear(struct drbd_conf *mdev);
-enum drbd_req_event;
-extern void tl_restart(struct drbd_conf *mdev, enum drbd_req_event what);
 extern void _tl_add_barrier(struct drbd_conf *, struct drbd_tl_epoch *);
 extern void drbd_free_sock(struct drbd_conf *mdev);
 extern int drbd_send(struct drbd_conf *mdev, struct socket *sock,
@@ -1433,6 +1434,7 @@
  * hash table. */
 #define HT_SHIFT 8
 #define DRBD_MAX_BIO_SIZE (1U<<(9+HT_SHIFT))
+#define DRBD_MAX_BIO_SIZE_SAFE (1 << 12)       /* Works always = 4k */
 
 #define DRBD_MAX_SIZE_H80_PACKET (1 << 15) /* The old header only allows packets up to 32Kib data */
 
@@ -1517,9 +1519,9 @@
 extern char *ppsize(char *buf, unsigned long long size);
 extern sector_t drbd_new_dev_size(struct drbd_conf *, struct drbd_backing_dev *, int);
 enum determine_dev_size { dev_size_error = -1, unchanged = 0, shrunk = 1, grew = 2 };
-extern enum determine_dev_size drbd_determin_dev_size(struct drbd_conf *, enum dds_flags) __must_hold(local);
+extern enum determine_dev_size drbd_determine_dev_size(struct drbd_conf *, enum dds_flags) __must_hold(local);
 extern void resync_after_online_grow(struct drbd_conf *);
-extern void drbd_setup_queue_param(struct drbd_conf *mdev, unsigned int) __must_hold(local);
+extern void drbd_reconsider_max_bio_size(struct drbd_conf *mdev);
 extern enum drbd_state_rv drbd_set_role(struct drbd_conf *mdev,
 					enum drbd_role new_role,
 					int force);
@@ -1827,6 +1829,8 @@
 		if (!forcedetach) {
 			if (__ratelimit(&drbd_ratelimit_state))
 				dev_err(DEV, "Local IO failed in %s.\n", where);
+			if (mdev->state.disk > D_INCONSISTENT)
+				_drbd_set_state(_NS(mdev, disk, D_INCONSISTENT), CS_HARD, NULL);
 			break;
 		}
 		/* NOTE fall through to detach case if forcedetach set */
@@ -2152,6 +2156,10 @@
 static inline void put_ldev(struct drbd_conf *mdev)
 {
 	int i = atomic_dec_return(&mdev->local_cnt);
+
+	/* This may be called from some endio handler,
+	 * so we must not sleep here. */
+
 	__release(local);
 	D_ASSERT(i >= 0);
 	if (i == 0) {
diff -druN linux-2.6.39-libre/drivers/block/drbd/drbd_main.c linux-3.0-rc7-libre/drivers/block/drbd/drbd_main.c
--- linux-2.6.39-libre/drivers/block/drbd/drbd_main.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/block/drbd/drbd_main.c	2011-07-11 19:51:52.000000000 -0400
@@ -745,6 +745,9 @@
 		  mdev->agreed_pro_version < 88)
 		rv = SS_NOT_SUPPORTED;
 
+	else if (ns.conn >= C_CONNECTED && ns.pdsk == D_UNKNOWN)
+		rv = SS_CONNECTED_OUTDATES;
+
 	return rv;
 }
 
@@ -1565,6 +1568,10 @@
 		put_ldev(mdev);
 	}
 
+	/* Notify peer that I had a local IO error, and did not detached.. */
+	if (os.disk == D_UP_TO_DATE && ns.disk == D_INCONSISTENT)
+		drbd_send_state(mdev);
+
 	/* Disks got bigger while they were detached */
 	if (ns.disk > D_NEGOTIATING && ns.pdsk > D_NEGOTIATING &&
 	    test_and_clear_bit(RESYNC_AFTER_NEG, &mdev->flags)) {
@@ -2064,7 +2071,7 @@
 {
 	struct p_sizes p;
 	sector_t d_size, u_size;
-	int q_order_type;
+	int q_order_type, max_bio_size;
 	int ok;
 
 	if (get_ldev_if_state(mdev, D_NEGOTIATING)) {
@@ -2072,17 +2079,20 @@
 		d_size = drbd_get_max_capacity(mdev->ldev);
 		u_size = mdev->ldev->dc.disk_size;
 		q_order_type = drbd_queue_order_type(mdev);
+		max_bio_size = queue_max_hw_sectors(mdev->ldev->backing_bdev->bd_disk->queue) << 9;
+		max_bio_size = min_t(int, max_bio_size, DRBD_MAX_BIO_SIZE);
 		put_ldev(mdev);
 	} else {
 		d_size = 0;
 		u_size = 0;
 		q_order_type = QUEUE_ORDERED_NONE;
+		max_bio_size = DRBD_MAX_BIO_SIZE; /* ... multiple BIOs per peer_request */
 	}
 
 	p.d_size = cpu_to_be64(d_size);
 	p.u_size = cpu_to_be64(u_size);
 	p.c_size = cpu_to_be64(trigger_reply ? 0 : drbd_get_capacity(mdev->this_bdev));
-	p.max_bio_size = cpu_to_be32(queue_max_hw_sectors(mdev->rq_queue) << 9);
+	p.max_bio_size = cpu_to_be32(max_bio_size);
 	p.queue_order_type = cpu_to_be16(q_order_type);
 	p.dds_flags = cpu_to_be16(flags);
 
@@ -2722,7 +2732,7 @@
 
 		/* double check digest, sometimes buffers have been modified in flight. */
 		if (dgs > 0 && dgs <= 64) {
-			/* 64 byte, 512 bit, is the larges digest size
+			/* 64 byte, 512 bit, is the largest digest size
 			 * currently supported in kernel crypto. */
 			unsigned char digest[64];
 			drbd_csum_bio(mdev, mdev->integrity_w_tfm, req->master_bio, digest);
@@ -3041,6 +3051,8 @@
 	mdev->agreed_pro_version = PRO_VERSION_MAX;
 	mdev->write_ordering = WO_bdev_flush;
 	mdev->resync_wenr = LC_FREE;
+	mdev->peer_max_bio_size = DRBD_MAX_BIO_SIZE_SAFE;
+	mdev->local_max_bio_size = DRBD_MAX_BIO_SIZE_SAFE;
 }
 
 void drbd_mdev_cleanup(struct drbd_conf *mdev)
@@ -3275,7 +3287,7 @@
 
 	drbd_release_ee_lists(mdev);
 
-	/* should be free'd on disconnect? */
+	/* should be freed on disconnect? */
 	kfree(mdev->ee_hash);
 	/*
 	mdev->ee_hash_s = 0;
@@ -3415,7 +3427,9 @@
 	q->backing_dev_info.congested_data = mdev;
 
 	blk_queue_make_request(q, drbd_make_request);
-	blk_queue_max_hw_sectors(q, DRBD_MAX_BIO_SIZE >> 9);
+	/* Setting the max_hw_sectors to an odd value of 8kibyte here
+	   This triggers a max_bio_size message upon first attach or connect */
+	blk_queue_max_hw_sectors(q, DRBD_MAX_BIO_SIZE_SAFE >> 8);
 	blk_queue_bounce_limit(q, BLK_BOUNCE_ANY);
 	blk_queue_merge_bvec(q, drbd_merge_bvec);
 	q->queue_lock = &mdev->req_lock;
@@ -3627,7 +3641,8 @@
 	      /* `-- act_log->nr_elements <-- sync_conf.al_extents */
 	u32 bm_offset;         /* offset to the bitmap, from here */
 	u32 bm_bytes_per_bit;  /* BM_BLOCK_SIZE */
-	u32 reserved_u32[4];
+	u32 la_peer_max_bio_size;   /* last peer max_bio_size */
+	u32 reserved_u32[3];
 
 } __packed;
 
@@ -3668,6 +3683,7 @@
 	buffer->device_uuid = cpu_to_be64(mdev->ldev->md.device_uuid);
 
 	buffer->bm_offset = cpu_to_be32(mdev->ldev->md.bm_offset);
+	buffer->la_peer_max_bio_size = cpu_to_be32(mdev->peer_max_bio_size);
 
 	D_ASSERT(drbd_md_ss__(mdev, mdev->ldev) == mdev->ldev->md.md_offset);
 	sector = mdev->ldev->md.md_offset;
@@ -3751,6 +3767,15 @@
 	mdev->sync_conf.al_extents = be32_to_cpu(buffer->al_nr_extents);
 	bdev->md.device_uuid = be64_to_cpu(buffer->device_uuid);
 
+	spin_lock_irq(&mdev->req_lock);
+	if (mdev->state.conn < C_CONNECTED) {
+		int peer;
+		peer = be32_to_cpu(buffer->la_peer_max_bio_size);
+		peer = max_t(int, peer, DRBD_MAX_BIO_SIZE_SAFE);
+		mdev->peer_max_bio_size = peer;
+	}
+	spin_unlock_irq(&mdev->req_lock);
+
 	if (mdev->sync_conf.al_extents < 7)
 		mdev->sync_conf.al_extents = 127;
 
diff -druN linux-2.6.39-libre/drivers/block/drbd/drbd_nl.c linux-3.0-rc7-libre/drivers/block/drbd/drbd_nl.c
--- linux-2.6.39-libre/drivers/block/drbd/drbd_nl.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/block/drbd/drbd_nl.c	2011-07-11 19:51:52.000000000 -0400
@@ -272,9 +272,28 @@
 {
 	struct drbd_conf *mdev = (struct drbd_conf *)data;
 	enum drbd_disk_state nps;
+	union drbd_state ns;
 
 	nps = drbd_try_outdate_peer(mdev);
-	drbd_request_state(mdev, NS(pdsk, nps));
+
+	/* Not using
+	   drbd_request_state(mdev, NS(pdsk, nps));
+	   here, because we might were able to re-establish the connection
+	   in the meantime. This can only partially be solved in the state's
+	   engine is_valid_state() and is_valid_state_transition()
+	   functions.
+
+	   nps can be D_INCONSISTENT, D_OUTDATED or D_UNKNOWN.
+	   pdsk == D_INCONSISTENT while conn >= C_CONNECTED is valid,
+	   therefore we have to have the pre state change check here.
+	*/
+	spin_lock_irq(&mdev->req_lock);
+	ns = mdev->state;
+	if (ns.conn < C_WF_REPORT_PARAMS) {
+		ns.pdsk = nps;
+		_drbd_set_state(mdev, ns, CS_VERBOSE, NULL);
+	}
+	spin_unlock_irq(&mdev->req_lock);
 
 	return 0;
 }
@@ -577,7 +596,7 @@
  * Returns 0 on success, negative return values indicate errors.
  * You should call drbd_md_sync() after calling this function.
  */
-enum determine_dev_size drbd_determin_dev_size(struct drbd_conf *mdev, enum dds_flags flags) __must_hold(local)
+enum determine_dev_size drbd_determine_dev_size(struct drbd_conf *mdev, enum dds_flags flags) __must_hold(local)
 {
 	sector_t prev_first_sect, prev_size; /* previous meta location */
 	sector_t la_size;
@@ -773,30 +792,78 @@
 	return 0;
 }
 
-void drbd_setup_queue_param(struct drbd_conf *mdev, unsigned int max_bio_size) __must_hold(local)
+static void drbd_setup_queue_param(struct drbd_conf *mdev, unsigned int max_bio_size)
 {
 	struct request_queue * const q = mdev->rq_queue;
-	struct request_queue * const b = mdev->ldev->backing_bdev->bd_disk->queue;
-	int max_segments = mdev->ldev->dc.max_bio_bvecs;
-	int max_hw_sectors = min(queue_max_hw_sectors(b), max_bio_size >> 9);
+	int max_hw_sectors = max_bio_size >> 9;
+	int max_segments = 0;
+
+	if (get_ldev_if_state(mdev, D_ATTACHING)) {
+		struct request_queue * const b = mdev->ldev->backing_bdev->bd_disk->queue;
+
+		max_hw_sectors = min(queue_max_hw_sectors(b), max_bio_size >> 9);
+		max_segments = mdev->ldev->dc.max_bio_bvecs;
+		put_ldev(mdev);
+	}
 
 	blk_queue_logical_block_size(q, 512);
 	blk_queue_max_hw_sectors(q, max_hw_sectors);
 	/* This is the workaround for "bio would need to, but cannot, be split" */
 	blk_queue_max_segments(q, max_segments ? max_segments : BLK_MAX_SEGMENTS);
 	blk_queue_segment_boundary(q, PAGE_CACHE_SIZE-1);
-	blk_queue_stack_limits(q, b);
 
-	dev_info(DEV, "max BIO size = %u\n", queue_max_hw_sectors(q) << 9);
+	if (get_ldev_if_state(mdev, D_ATTACHING)) {
+		struct request_queue * const b = mdev->ldev->backing_bdev->bd_disk->queue;
 
-	if (q->backing_dev_info.ra_pages != b->backing_dev_info.ra_pages) {
-		dev_info(DEV, "Adjusting my ra_pages to backing device's (%lu -> %lu)\n",
-		     q->backing_dev_info.ra_pages,
-		     b->backing_dev_info.ra_pages);
-		q->backing_dev_info.ra_pages = b->backing_dev_info.ra_pages;
+		blk_queue_stack_limits(q, b);
+
+		if (q->backing_dev_info.ra_pages != b->backing_dev_info.ra_pages) {
+			dev_info(DEV, "Adjusting my ra_pages to backing device's (%lu -> %lu)\n",
+				 q->backing_dev_info.ra_pages,
+				 b->backing_dev_info.ra_pages);
+			q->backing_dev_info.ra_pages = b->backing_dev_info.ra_pages;
+		}
+		put_ldev(mdev);
 	}
 }
 
+void drbd_reconsider_max_bio_size(struct drbd_conf *mdev)
+{
+	int now, new, local, peer;
+
+	now = queue_max_hw_sectors(mdev->rq_queue) << 9;
+	local = mdev->local_max_bio_size; /* Eventually last known value, from volatile memory */
+	peer = mdev->peer_max_bio_size; /* Eventually last known value, from meta data */
+
+	if (get_ldev_if_state(mdev, D_ATTACHING)) {
+		local = queue_max_hw_sectors(mdev->ldev->backing_bdev->bd_disk->queue) << 9;
+		mdev->local_max_bio_size = local;
+		put_ldev(mdev);
+	}
+
+	/* We may ignore peer limits if the peer is modern enough.
+	   Because new from 8.3.8 onwards the peer can use multiple
+	   BIOs for a single peer_request */
+	if (mdev->state.conn >= C_CONNECTED) {
+		if (mdev->agreed_pro_version < 94)
+			peer = mdev->peer_max_bio_size;
+		else if (mdev->agreed_pro_version == 94)
+			peer = DRBD_MAX_SIZE_H80_PACKET;
+		else /* drbd 8.3.8 onwards */
+			peer = DRBD_MAX_BIO_SIZE;
+	}
+
+	new = min_t(int, local, peer);
+
+	if (mdev->state.role == R_PRIMARY && new < now)
+		dev_err(DEV, "ASSERT FAILED new < now; (%d < %d)\n", new, now);
+
+	if (new != now)
+		dev_info(DEV, "max BIO size = %u\n", new);
+
+	drbd_setup_queue_param(mdev, new);
+}
+
 /* serialize deconfig (worker exiting, doing cleanup)
  * and reconfig (drbdsetup disk, drbdsetup net)
  *
@@ -865,7 +932,6 @@
 	struct block_device *bdev;
 	struct lru_cache *resync_lru = NULL;
 	union drbd_state ns, os;
-	unsigned int max_bio_size;
 	enum drbd_state_rv rv;
 	int cp_discovered = 0;
 	int logical_block_size;
@@ -1117,20 +1183,7 @@
 	mdev->read_cnt = 0;
 	mdev->writ_cnt = 0;
 
-	max_bio_size = DRBD_MAX_BIO_SIZE;
-	if (mdev->state.conn == C_CONNECTED) {
-		/* We are Primary, Connected, and now attach a new local
-		 * backing store. We must not increase the user visible maximum
-		 * bio size on this device to something the peer may not be
-		 * able to handle. */
-		if (mdev->agreed_pro_version < 94)
-			max_bio_size = queue_max_hw_sectors(mdev->rq_queue) << 9;
-		else if (mdev->agreed_pro_version == 94)
-			max_bio_size = DRBD_MAX_SIZE_H80_PACKET;
-		/* else: drbd 8.3.9 and later, stay with default */
-	}
-
-	drbd_setup_queue_param(mdev, max_bio_size);
+	drbd_reconsider_max_bio_size(mdev);
 
 	/* If I am currently not R_PRIMARY,
 	 * but meta data primary indicator is set,
@@ -1152,7 +1205,7 @@
 	    !drbd_md_test_flag(mdev->ldev, MDF_CONNECTED_IND))
 		set_bit(USE_DEGR_WFC_T, &mdev->flags);
 
-	dd = drbd_determin_dev_size(mdev, 0);
+	dd = drbd_determine_dev_size(mdev, 0);
 	if (dd == dev_size_error) {
 		retcode = ERR_NOMEM_BITMAP;
 		goto force_diskless_dec;
@@ -1281,11 +1334,19 @@
 static int drbd_nl_detach(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp,
 			  struct drbd_nl_cfg_reply *reply)
 {
+	enum drbd_ret_code retcode;
+	int ret;
 	drbd_suspend_io(mdev); /* so no-one is stuck in drbd_al_begin_io */
-	reply->ret_code = drbd_request_state(mdev, NS(disk, D_DISKLESS));
-	if (mdev->state.disk == D_DISKLESS)
-		wait_event(mdev->misc_wait, !atomic_read(&mdev->local_cnt));
+	retcode = drbd_request_state(mdev, NS(disk, D_FAILED));
+	/* D_FAILED will transition to DISKLESS. */
+	ret = wait_event_interruptible(mdev->misc_wait,
+			mdev->state.disk != D_FAILED);
 	drbd_resume_io(mdev);
+	if ((int)retcode == (int)SS_IS_DISKLESS)
+		retcode = SS_NOTHING_TO_DO;
+	if (ret)
+		retcode = ERR_INTR;
+	reply->ret_code = retcode;
 	return 0;
 }
 
@@ -1658,7 +1719,7 @@
 
 	mdev->ldev->dc.disk_size = (sector_t)rs.resize_size;
 	ddsf = (rs.resize_force ? DDSF_FORCED : 0) | (rs.no_resync ? DDSF_NO_RESYNC : 0);
-	dd = drbd_determin_dev_size(mdev, ddsf);
+	dd = drbd_determine_dev_size(mdev, ddsf);
 	drbd_md_sync(mdev);
 	put_ldev(mdev);
 	if (dd == dev_size_error) {
diff -druN linux-2.6.39-libre/drivers/block/drbd/drbd_receiver.c linux-3.0-rc7-libre/drivers/block/drbd/drbd_receiver.c
--- linux-2.6.39-libre/drivers/block/drbd/drbd_receiver.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/block/drbd/drbd_receiver.c	2011-07-11 19:51:52.000000000 -0400
@@ -333,7 +333,7 @@
 	if (!page)
 		goto fail;
 
-	INIT_HLIST_NODE(&e->colision);
+	INIT_HLIST_NODE(&e->collision);
 	e->epoch = NULL;
 	e->mdev = mdev;
 	e->pages = page;
@@ -356,7 +356,7 @@
 		kfree(e->digest);
 	drbd_pp_free(mdev, e->pages, is_net);
 	D_ASSERT(atomic_read(&e->pending_bios) == 0);
-	D_ASSERT(hlist_unhashed(&e->colision));
+	D_ASSERT(hlist_unhashed(&e->collision));
 	mempool_free(e, drbd_ee_mempool);
 }
 
@@ -787,7 +787,7 @@
 		}
 
 		if (sock && msock) {
-			schedule_timeout_interruptible(HZ / 10);
+			schedule_timeout_interruptible(mdev->net_conf->ping_timeo*HZ/10);
 			ok = drbd_socket_okay(mdev, &sock);
 			ok = drbd_socket_okay(mdev, &msock) && ok;
 			if (ok)
@@ -899,11 +899,6 @@
 
 	drbd_thread_start(&mdev->asender);
 
-	if (mdev->agreed_pro_version < 95 && get_ldev(mdev)) {
-		drbd_setup_queue_param(mdev, DRBD_MAX_SIZE_H80_PACKET);
-		put_ldev(mdev);
-	}
-
 	if (drbd_send_protocol(mdev) == -1)
 		return -1;
 	drbd_send_sync_param(mdev, &mdev->sync_conf);
@@ -1418,7 +1413,7 @@
 	sector_t sector = e->sector;
 	int ok;
 
-	D_ASSERT(hlist_unhashed(&e->colision));
+	D_ASSERT(hlist_unhashed(&e->collision));
 
 	if (likely((e->flags & EE_WAS_ERROR) == 0)) {
 		drbd_set_in_sync(mdev, sector, e->size);
@@ -1487,7 +1482,7 @@
 		return false;
 	}
 
-	/* hlist_del(&req->colision) is done in _req_may_be_done, to avoid
+	/* hlist_del(&req->collision) is done in _req_may_be_done, to avoid
 	 * special casing it there for the various failure cases.
 	 * still no race with drbd_fail_pending_reads */
 	ok = recv_dless_read(mdev, req, sector, data_size);
@@ -1558,11 +1553,11 @@
 	 * P_WRITE_ACK / P_NEG_ACK, to get the sequence number right.  */
 	if (mdev->net_conf->two_primaries) {
 		spin_lock_irq(&mdev->req_lock);
-		D_ASSERT(!hlist_unhashed(&e->colision));
-		hlist_del_init(&e->colision);
+		D_ASSERT(!hlist_unhashed(&e->collision));
+		hlist_del_init(&e->collision);
 		spin_unlock_irq(&mdev->req_lock);
 	} else {
-		D_ASSERT(hlist_unhashed(&e->colision));
+		D_ASSERT(hlist_unhashed(&e->collision));
 	}
 
 	drbd_may_finish_epoch(mdev, e->epoch, EV_PUT + (cancel ? EV_CLEANUP : 0));
@@ -1579,8 +1574,8 @@
 	ok = drbd_send_ack(mdev, P_DISCARD_ACK, e);
 
 	spin_lock_irq(&mdev->req_lock);
-	D_ASSERT(!hlist_unhashed(&e->colision));
-	hlist_del_init(&e->colision);
+	D_ASSERT(!hlist_unhashed(&e->collision));
+	hlist_del_init(&e->collision);
 	spin_unlock_irq(&mdev->req_lock);
 
 	dec_unacked(mdev);
@@ -1755,7 +1750,7 @@
 
 		spin_lock_irq(&mdev->req_lock);
 
-		hlist_add_head(&e->colision, ee_hash_slot(mdev, sector));
+		hlist_add_head(&e->collision, ee_hash_slot(mdev, sector));
 
 #define OVERLAPS overlaps(i->sector, i->size, sector, size)
 		slot = tl_hash_slot(mdev, sector);
@@ -1765,7 +1760,7 @@
 			int have_conflict = 0;
 			prepare_to_wait(&mdev->misc_wait, &wait,
 				TASK_INTERRUPTIBLE);
-			hlist_for_each_entry(i, n, slot, colision) {
+			hlist_for_each_entry(i, n, slot, collision) {
 				if (OVERLAPS) {
 					/* only ALERT on first iteration,
 					 * we may be woken up early... */
@@ -1804,7 +1799,7 @@
 			}
 
 			if (signal_pending(current)) {
-				hlist_del_init(&e->colision);
+				hlist_del_init(&e->collision);
 
 				spin_unlock_irq(&mdev->req_lock);
 
@@ -1862,7 +1857,7 @@
 	dev_err(DEV, "submit failed, triggering re-connect\n");
 	spin_lock_irq(&mdev->req_lock);
 	list_del(&e->w.list);
-	hlist_del_init(&e->colision);
+	hlist_del_init(&e->collision);
 	spin_unlock_irq(&mdev->req_lock);
 	if (e->flags & EE_CALL_AL_COMPLETE_IO)
 		drbd_al_complete_io(mdev, e->sector);
@@ -2916,12 +2911,6 @@
 	return false;
 }
 
-static void drbd_setup_order_type(struct drbd_conf *mdev, int peer)
-{
-	/* sorry, we currently have no working implementation
-	 * of distributed TCQ */
-}
-
 /* warn if the arguments differ by more than 12.5% */
 static void warn_if_differ_considerably(struct drbd_conf *mdev,
 	const char *s, sector_t a, sector_t b)
@@ -2939,7 +2928,6 @@
 {
 	struct p_sizes *p = &mdev->data.rbuf.sizes;
 	enum determine_dev_size dd = unchanged;
-	unsigned int max_bio_size;
 	sector_t p_size, p_usize, my_usize;
 	int ldsc = 0; /* local disk size changed */
 	enum dds_flags ddsf;
@@ -2994,7 +2982,7 @@
 
 	ddsf = be16_to_cpu(p->dds_flags);
 	if (get_ldev(mdev)) {
-		dd = drbd_determin_dev_size(mdev, ddsf);
+		dd = drbd_determine_dev_size(mdev, ddsf);
 		put_ldev(mdev);
 		if (dd == dev_size_error)
 			return false;
@@ -3004,23 +2992,15 @@
 		drbd_set_my_capacity(mdev, p_size);
 	}
 
+	mdev->peer_max_bio_size = be32_to_cpu(p->max_bio_size);
+	drbd_reconsider_max_bio_size(mdev);
+
 	if (get_ldev(mdev)) {
 		if (mdev->ldev->known_size != drbd_get_capacity(mdev->ldev->backing_bdev)) {
 			mdev->ldev->known_size = drbd_get_capacity(mdev->ldev->backing_bdev);
 			ldsc = 1;
 		}
 
-		if (mdev->agreed_pro_version < 94)
-			max_bio_size = be32_to_cpu(p->max_bio_size);
-		else if (mdev->agreed_pro_version == 94)
-			max_bio_size = DRBD_MAX_SIZE_H80_PACKET;
-		else /* drbd 8.3.8 onwards */
-			max_bio_size = DRBD_MAX_BIO_SIZE;
-
-		if (max_bio_size != queue_max_hw_sectors(mdev->rq_queue) << 9)
-			drbd_setup_queue_param(mdev, max_bio_size);
-
-		drbd_setup_order_type(mdev, be16_to_cpu(p->queue_order_type));
 		put_ldev(mdev);
 	}
 
@@ -4275,7 +4255,7 @@
 	struct hlist_node *n;
 	struct drbd_request *req;
 
-	hlist_for_each_entry(req, n, slot, colision) {
+	hlist_for_each_entry(req, n, slot, collision) {
 		if ((unsigned long)req == (unsigned long)id) {
 			if (req->sector != sector) {
 				dev_err(DEV, "_ack_id_to_req: found req %p but it has "
@@ -4554,6 +4534,7 @@
 	int received = 0;
 	int expect   = sizeof(struct p_header80);
 	int empty;
+	int ping_timeout_active = 0;
 
 	sprintf(current->comm, "drbd%d_asender", mdev_to_minor(mdev));
 
@@ -4566,6 +4547,7 @@
 			ERR_IF(!drbd_send_ping(mdev)) goto reconnect;
 			mdev->meta.socket->sk->sk_rcvtimeo =
 				mdev->net_conf->ping_timeo*HZ/10;
+			ping_timeout_active = 1;
 		}
 
 		/* conditionally cork;
@@ -4620,8 +4602,12 @@
 			dev_err(DEV, "meta connection shut down by peer.\n");
 			goto reconnect;
 		} else if (rv == -EAGAIN) {
-			if (mdev->meta.socket->sk->sk_rcvtimeo ==
-			    mdev->net_conf->ping_timeo*HZ/10) {
+			/* If the data socket received something meanwhile,
+			 * that is good enough: peer is still alive. */
+			if (time_after(mdev->last_received,
+				jiffies - mdev->meta.socket->sk->sk_rcvtimeo))
+				continue;
+			if (ping_timeout_active) {
 				dev_err(DEV, "PingAck did not arrive in time.\n");
 				goto reconnect;
 			}
@@ -4656,10 +4642,16 @@
 				goto reconnect;
 		}
 		if (received == expect) {
+			mdev->last_received = jiffies;
 			D_ASSERT(cmd != NULL);
 			if (!cmd->process(mdev, h))
 				goto reconnect;
 
+			/* the idle_timeout (ping-int)
+			 * has been restored in got_PingAck() */
+			if (cmd == get_asender_cmd(P_PING_ACK))
+				ping_timeout_active = 0;
+
 			buf	 = h;
 			received = 0;
 			expect	 = sizeof(struct p_header80);
diff -druN linux-2.6.39-libre/drivers/block/drbd/drbd_req.c linux-3.0-rc7-libre/drivers/block/drbd/drbd_req.c
--- linux-2.6.39-libre/drivers/block/drbd/drbd_req.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/block/drbd/drbd_req.c	2011-07-11 19:51:52.000000000 -0400
@@ -163,7 +163,7 @@
 		 * they must have been failed on the spot */
 #define OVERLAPS overlaps(sector, size, i->sector, i->size)
 		slot = tl_hash_slot(mdev, sector);
-		hlist_for_each_entry(i, n, slot, colision) {
+		hlist_for_each_entry(i, n, slot, collision) {
 			if (OVERLAPS) {
 				dev_alert(DEV, "LOGIC BUG: completed: %p %llus +%u; "
 				      "other: %p %llus +%u\n",
@@ -187,7 +187,7 @@
 #undef OVERLAPS
 #define OVERLAPS overlaps(sector, size, e->sector, e->size)
 		slot = ee_hash_slot(mdev, req->sector);
-		hlist_for_each_entry(e, n, slot, colision) {
+		hlist_for_each_entry(e, n, slot, collision) {
 			if (OVERLAPS) {
 				wake_up(&mdev->misc_wait);
 				break;
@@ -260,8 +260,8 @@
 
 		/* remove the request from the conflict detection
 		 * respective block_id verification hash */
-		if (!hlist_unhashed(&req->colision))
-			hlist_del(&req->colision);
+		if (!hlist_unhashed(&req->collision))
+			hlist_del(&req->collision);
 		else
 			D_ASSERT((s & (RQ_NET_MASK & ~RQ_NET_DONE)) == 0);
 
@@ -329,7 +329,7 @@
 	struct hlist_node *n;
 	struct hlist_head *slot;
 
-	D_ASSERT(hlist_unhashed(&req->colision));
+	D_ASSERT(hlist_unhashed(&req->collision));
 
 	if (!get_net_conf(mdev))
 		return 0;
@@ -341,7 +341,7 @@
 
 #define OVERLAPS overlaps(i->sector, i->size, sector, size)
 	slot = tl_hash_slot(mdev, sector);
-	hlist_for_each_entry(i, n, slot, colision) {
+	hlist_for_each_entry(i, n, slot, collision) {
 		if (OVERLAPS) {
 			dev_alert(DEV, "%s[%u] Concurrent local write detected! "
 			      "[DISCARD L] new: %llus +%u; "
@@ -359,7 +359,7 @@
 #undef OVERLAPS
 #define OVERLAPS overlaps(e->sector, e->size, sector, size)
 		slot = ee_hash_slot(mdev, sector);
-		hlist_for_each_entry(e, n, slot, colision) {
+		hlist_for_each_entry(e, n, slot, collision) {
 			if (OVERLAPS) {
 				dev_alert(DEV, "%s[%u] Concurrent remote write detected!"
 				      " [DISCARD L] new: %llus +%u; "
@@ -491,7 +491,7 @@
 
 		/* so we can verify the handle in the answer packet
 		 * corresponding hlist_del is in _req_may_be_done() */
-		hlist_add_head(&req->colision, ar_hash_slot(mdev, req->sector));
+		hlist_add_head(&req->collision, ar_hash_slot(mdev, req->sector));
 
 		set_bit(UNPLUG_REMOTE, &mdev->flags);
 
@@ -507,7 +507,7 @@
 		/* assert something? */
 		/* from drbd_make_request_common only */
 
-		hlist_add_head(&req->colision, tl_hash_slot(mdev, req->sector));
+		hlist_add_head(&req->collision, tl_hash_slot(mdev, req->sector));
 		/* corresponding hlist_del is in _req_may_be_done() */
 
 		/* NOTE
@@ -1033,7 +1033,7 @@
 	err = 0;
 
 fail_free_complete:
-	if (rw == WRITE && local)
+	if (req->rq_state & RQ_IN_ACT_LOG)
 		drbd_al_complete_io(mdev, sector);
 fail_and_free_req:
 	if (local) {
diff -druN linux-2.6.39-libre/drivers/block/drbd/drbd_req.h linux-3.0-rc7-libre/drivers/block/drbd/drbd_req.h
--- linux-2.6.39-libre/drivers/block/drbd/drbd_req.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/block/drbd/drbd_req.h	2011-07-11 19:51:52.000000000 -0400
@@ -256,7 +256,7 @@
 	struct hlist_node *n;
 	struct drbd_request *req;
 
-	hlist_for_each_entry(req, n, slot, colision) {
+	hlist_for_each_entry(req, n, slot, collision) {
 		if ((unsigned long)req == (unsigned long)id) {
 			D_ASSERT(req->sector == sector);
 			return req;
@@ -291,7 +291,7 @@
 		req->epoch       = 0;
 		req->sector      = bio_src->bi_sector;
 		req->size        = bio_src->bi_size;
-		INIT_HLIST_NODE(&req->colision);
+		INIT_HLIST_NODE(&req->collision);
 		INIT_LIST_HEAD(&req->tl_requests);
 		INIT_LIST_HEAD(&req->w.list);
 	}
@@ -323,6 +323,7 @@
 extern void complete_master_bio(struct drbd_conf *mdev,
 		struct bio_and_error *m);
 extern void request_timer_fn(unsigned long data);
+extern void tl_restart(struct drbd_conf *mdev, enum drbd_req_event what);
 
 /* use this if you don't want to deal with calling complete_master_bio()
  * outside the spinlock, e.g. when walking some list on cleanup. */
diff -druN linux-2.6.39-libre/drivers/block/drbd/drbd_worker.c linux-3.0-rc7-libre/drivers/block/drbd/drbd_worker.c
--- linux-2.6.39-libre/drivers/block/drbd/drbd_worker.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/block/drbd/drbd_worker.c	2011-07-11 19:51:52.000000000 -0400
@@ -126,7 +126,7 @@
 	list_del(&e->w.list); /* has been on active_ee or sync_ee */
 	list_add_tail(&e->w.list, &mdev->done_ee);
 
-	/* No hlist_del_init(&e->colision) here, we did not send the Ack yet,
+	/* No hlist_del_init(&e->collision) here, we did not send the Ack yet,
 	 * neither did we wake possibly waiting conflicting requests.
 	 * done from "drbd_process_done_ee" within the appropriate w.cb
 	 * (e_end_block/e_end_resync_block) or from _drbd_clear_done_ee */
@@ -297,42 +297,48 @@
 	crypto_hash_final(&desc, digest);
 }
 
-static int w_e_send_csum(struct drbd_conf *mdev, struct drbd_work *w, int cancel)
+/* TODO merge common code with w_e_end_ov_req */
+int w_e_send_csum(struct drbd_conf *mdev, struct drbd_work *w, int cancel)
 {
 	struct drbd_epoch_entry *e = container_of(w, struct drbd_epoch_entry, w);
 	int digest_size;
 	void *digest;
-	int ok;
+	int ok = 1;
 
 	D_ASSERT(e->block_id == DRBD_MAGIC + 0xbeef);
 
-	if (unlikely(cancel)) {
-		drbd_free_ee(mdev, e);
-		return 1;
-	}
+	if (unlikely(cancel))
+		goto out;
 
-	if (likely((e->flags & EE_WAS_ERROR) == 0)) {
-		digest_size = crypto_hash_digestsize(mdev->csums_tfm);
-		digest = kmalloc(digest_size, GFP_NOIO);
-		if (digest) {
-			drbd_csum_ee(mdev, mdev->csums_tfm, e, digest);
+	if (likely((e->flags & EE_WAS_ERROR) != 0))
+		goto out;
 
-			inc_rs_pending(mdev);
-			ok = drbd_send_drequest_csum(mdev,
-						     e->sector,
-						     e->size,
-						     digest,
-						     digest_size,
-						     P_CSUM_RS_REQUEST);
-			kfree(digest);
-		} else {
-			dev_err(DEV, "kmalloc() of digest failed.\n");
-			ok = 0;
-		}
-	} else
-		ok = 1;
+	digest_size = crypto_hash_digestsize(mdev->csums_tfm);
+	digest = kmalloc(digest_size, GFP_NOIO);
+	if (digest) {
+		sector_t sector = e->sector;
+		unsigned int size = e->size;
+		drbd_csum_ee(mdev, mdev->csums_tfm, e, digest);
+		/* Free e and pages before send.
+		 * In case we block on congestion, we could otherwise run into
+		 * some distributed deadlock, if the other side blocks on
+		 * congestion as well, because our receiver blocks in
+		 * drbd_pp_alloc due to pp_in_use > max_buffers. */
+		drbd_free_ee(mdev, e);
+		e = NULL;
+		inc_rs_pending(mdev);
+		ok = drbd_send_drequest_csum(mdev, sector, size,
+					     digest, digest_size,
+					     P_CSUM_RS_REQUEST);
+		kfree(digest);
+	} else {
+		dev_err(DEV, "kmalloc() of digest failed.\n");
+		ok = 0;
+	}
 
-	drbd_free_ee(mdev, e);
+out:
+	if (e)
+		drbd_free_ee(mdev, e);
 
 	if (unlikely(!ok))
 		dev_err(DEV, "drbd_send_drequest(..., csum) failed\n");
@@ -530,12 +536,7 @@
 		return 1;
 	}
 
-	/* starting with drbd 8.3.8, we can handle multi-bio EEs,
-	 * if it should be necessary */
-	max_bio_size =
-		mdev->agreed_pro_version < 94 ? queue_max_hw_sectors(mdev->rq_queue) << 9 :
-		mdev->agreed_pro_version < 95 ?	DRBD_MAX_SIZE_H80_PACKET : DRBD_MAX_BIO_SIZE;
-
+	max_bio_size = queue_max_hw_sectors(mdev->rq_queue) << 9;
 	number = drbd_rs_number_requests(mdev);
 	if (number == 0)
 		goto requeue;
@@ -834,7 +835,7 @@
 			const int ratio =
 				(t == 0)     ? 0 :
 			(t < 100000) ? ((s*100)/t) : (s/(t/100));
-			dev_info(DEV, "%u %% had equal check sums, eliminated: %luK; "
+			dev_info(DEV, "%u %% had equal checksums, eliminated: %luK; "
 			     "transferred %luK total %luK\n",
 			     ratio,
 			     Bit2KB(mdev->rs_same_csum),
@@ -1071,9 +1072,12 @@
 	return ok;
 }
 
+/* TODO merge common code with w_e_send_csum */
 int w_e_end_ov_req(struct drbd_conf *mdev, struct drbd_work *w, int cancel)
 {
 	struct drbd_epoch_entry *e = container_of(w, struct drbd_epoch_entry, w);
+	sector_t sector = e->sector;
+	unsigned int size = e->size;
 	int digest_size;
 	void *digest;
 	int ok = 1;
@@ -1093,17 +1097,25 @@
 	else
 		memset(digest, 0, digest_size);
 
+	/* Free e and pages before send.
+	 * In case we block on congestion, we could otherwise run into
+	 * some distributed deadlock, if the other side blocks on
+	 * congestion as well, because our receiver blocks in
+	 * drbd_pp_alloc due to pp_in_use > max_buffers. */
+	drbd_free_ee(mdev, e);
+	e = NULL;
 	inc_rs_pending(mdev);
-	ok = drbd_send_drequest_csum(mdev, e->sector, e->size,
-				     digest, digest_size, P_OV_REPLY);
+	ok = drbd_send_drequest_csum(mdev, sector, size,
+				     digest, digest_size,
+				     P_OV_REPLY);
 	if (!ok)
 		dec_rs_pending(mdev);
 	kfree(digest);
 
 out:
-	drbd_free_ee(mdev, e);
+	if (e)
+		drbd_free_ee(mdev, e);
 	dec_unacked(mdev);
-
 	return ok;
 }
 
@@ -1122,8 +1134,10 @@
 {
 	struct drbd_epoch_entry *e = container_of(w, struct drbd_epoch_entry, w);
 	struct digest_info *di;
-	int digest_size;
 	void *digest;
+	sector_t sector = e->sector;
+	unsigned int size = e->size;
+	int digest_size;
 	int ok, eq = 0;
 
 	if (unlikely(cancel)) {
@@ -1153,16 +1167,21 @@
 		}
 	}
 
-	dec_unacked(mdev);
+		/* Free e and pages before send.
+		 * In case we block on congestion, we could otherwise run into
+		 * some distributed deadlock, if the other side blocks on
+		 * congestion as well, because our receiver blocks in
+		 * drbd_pp_alloc due to pp_in_use > max_buffers. */
+	drbd_free_ee(mdev, e);
 	if (!eq)
-		drbd_ov_oos_found(mdev, e->sector, e->size);
+		drbd_ov_oos_found(mdev, sector, size);
 	else
 		ov_oos_print(mdev);
 
-	ok = drbd_send_ack_ex(mdev, P_OV_RESULT, e->sector, e->size,
+	ok = drbd_send_ack_ex(mdev, P_OV_RESULT, sector, size,
 			      eq ? ID_IN_SYNC : ID_OUT_OF_SYNC);
 
-	drbd_free_ee(mdev, e);
+	dec_unacked(mdev);
 
 	--mdev->ov_left;
 
diff -druN linux-2.6.39-libre/drivers/block/floppy.c linux-3.0-rc7-libre/drivers/block/floppy.c
--- linux-2.6.39-libre/drivers/block/floppy.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/block/floppy.c	2011-07-11 19:51:52.000000000 -0400
@@ -1038,6 +1038,7 @@
 {
 	unsigned long flags;
 
+	WARN_ONCE(1, "floppy_disable_hlt() scheduled for removal in 2012");
 	spin_lock_irqsave(&floppy_hlt_lock, flags);
 	if (!hlt_disabled) {
 		hlt_disabled = 1;
diff -druN linux-2.6.39-libre/drivers/block/Kconfig linux-3.0-rc7-libre/drivers/block/Kconfig
--- linux-2.6.39-libre/drivers/block/Kconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/block/Kconfig	2011-07-11 19:51:52.000000000 -0400
@@ -470,6 +470,27 @@
 	  block device driver.  It communicates with a back-end driver
 	  in another domain which drives the actual block device.
 
+config XEN_BLKDEV_BACKEND
+	tristate "Block-device backend driver"
+	depends on XEN_BACKEND
+	help
+	  The block-device backend driver allows the kernel to export its
+	  block devices to other guests via a high-performance shared-memory
+	  interface.
+
+	  The corresponding Linux frontend driver is enabled by the
+	  CONFIG_XEN_BLKDEV_FRONTEND configuration option.
+
+	  The backend driver attaches itself to a any block device specified
+	  in the XenBus configuration. There are no limits to what the block
+	  device as long as it has a major and minor.
+
+	  If you are compiling a kernel to run in a Xen block backend driver
+	  domain (often this is domain 0) you should say Y here. To
+	  compile this driver as a module, chose M here: the module
+	  will be called xen-blkback.
+
+
 config VIRTIO_BLK
 	tristate "Virtio block driver (EXPERIMENTAL)"
 	depends on EXPERIMENTAL && VIRTIO
diff -druN linux-2.6.39-libre/drivers/block/loop.c linux-3.0-rc7-libre/drivers/block/loop.c
--- linux-2.6.39-libre/drivers/block/loop.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/block/loop.c	2011-07-11 19:51:52.000000000 -0400
@@ -1540,9 +1540,9 @@
  * And now the modules code and kernel interface.
  */
 static int max_loop;
-module_param(max_loop, int, 0);
+module_param(max_loop, int, S_IRUGO);
 MODULE_PARM_DESC(max_loop, "Maximum number of loop devices");
-module_param(max_part, int, 0);
+module_param(max_part, int, S_IRUGO);
 MODULE_PARM_DESC(max_part, "Maximum number of partitions per loop device");
 MODULE_LICENSE("GPL");
 MODULE_ALIAS_BLOCKDEV_MAJOR(LOOP_MAJOR);
@@ -1658,7 +1658,7 @@
 	struct kobject *kobj;
 
 	mutex_lock(&loop_devices_mutex);
-	lo = loop_init_one(dev & MINORMASK);
+	lo = loop_init_one(MINOR(dev) >> part_shift);
 	kobj = lo ? get_disk(lo->lo_disk) : ERR_PTR(-ENOMEM);
 	mutex_unlock(&loop_devices_mutex);
 
@@ -1688,18 +1688,32 @@
 	 */
 
 	part_shift = 0;
-	if (max_part > 0)
+	if (max_part > 0) {
 		part_shift = fls(max_part);
 
+		/*
+		 * Adjust max_part according to part_shift as it is exported
+		 * to user space so that user can decide correct minor number
+		 * if [s]he want to create more devices.
+		 *
+		 * Note that -1 is required because partition 0 is reserved
+		 * for the whole disk.
+		 */
+		max_part = (1UL << part_shift) - 1;
+	}
+
+	if ((1UL << part_shift) > DISK_MAX_PARTS)
+		return -EINVAL;
+
 	if (max_loop > 1UL << (MINORBITS - part_shift))
 		return -EINVAL;
 
 	if (max_loop) {
 		nr = max_loop;
-		range = max_loop;
+		range = max_loop << part_shift;
 	} else {
 		nr = 8;
-		range = 1UL << (MINORBITS - part_shift);
+		range = 1UL << MINORBITS;
 	}
 
 	if (register_blkdev(LOOP_MAJOR, "loop"))
@@ -1738,7 +1752,7 @@
 	unsigned long range;
 	struct loop_device *lo, *next;
 
-	range = max_loop ? max_loop :  1UL << (MINORBITS - part_shift);
+	range = max_loop ? max_loop << part_shift : 1UL << MINORBITS;
 
 	list_for_each_entry_safe(lo, next, &loop_devices, lo_list)
 		loop_del_one(lo);
diff -druN linux-2.6.39-libre/drivers/block/Makefile linux-3.0-rc7-libre/drivers/block/Makefile
--- linux-2.6.39-libre/drivers/block/Makefile	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/block/Makefile	2011-07-11 19:51:52.000000000 -0400
@@ -36,6 +36,7 @@
 obj-$(CONFIG_BLK_DEV_HD)	+= hd.o
 
 obj-$(CONFIG_XEN_BLKDEV_FRONTEND)	+= xen-blkfront.o
+obj-$(CONFIG_XEN_BLKDEV_BACKEND)	+= xen-blkback/
 obj-$(CONFIG_BLK_DEV_DRBD)     += drbd/
 obj-$(CONFIG_BLK_DEV_RBD)     += rbd.o
 
diff -druN linux-2.6.39-libre/drivers/block/nbd.c linux-3.0-rc7-libre/drivers/block/nbd.c
--- linux-2.6.39-libre/drivers/block/nbd.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/block/nbd.c	2011-07-11 19:51:52.000000000 -0400
@@ -192,7 +192,8 @@
 			if (lo->xmit_timeout)
 				del_timer_sync(&ti);
 		} else
-			result = kernel_recvmsg(sock, &msg, &iov, 1, size, 0);
+			result = kernel_recvmsg(sock, &msg, &iov, 1, size,
+						msg.msg_flags);
 
 		if (signal_pending(current)) {
 			siginfo_t info;
@@ -753,9 +754,26 @@
 		return -ENOMEM;
 
 	part_shift = 0;
-	if (max_part > 0)
+	if (max_part > 0) {
 		part_shift = fls(max_part);
 
+		/*
+		 * Adjust max_part according to part_shift as it is exported
+		 * to user space so that user can know the max number of
+		 * partition kernel should be able to manage.
+		 *
+		 * Note that -1 is required because partition 0 is reserved
+		 * for the whole disk.
+		 */
+		max_part = (1UL << part_shift) - 1;
+	}
+
+	if ((1UL << part_shift) > DISK_MAX_PARTS)
+		return -EINVAL;
+
+	if (nbds_max > 1UL << (MINORBITS - part_shift))
+		return -EINVAL;
+
 	for (i = 0; i < nbds_max; i++) {
 		struct gendisk *disk = alloc_disk(1 << part_shift);
 		if (!disk)
diff -druN linux-2.6.39-libre/drivers/block/paride/pcd.c linux-3.0-rc7-libre/drivers/block/paride/pcd.c
--- linux-2.6.39-libre/drivers/block/paride/pcd.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/block/paride/pcd.c	2011-07-11 19:51:52.000000000 -0400
@@ -320,6 +320,7 @@
 		disk->first_minor = unit;
 		strcpy(disk->disk_name, cd->name);	/* umm... */
 		disk->fops = &pcd_bdops;
+		disk->flags = GENHD_FL_BLOCK_EVENTS_ON_EXCL_WRITE;
 	}
 }
 
diff -druN linux-2.6.39-libre/drivers/block/rbd.c linux-3.0-rc7-libre/drivers/block/rbd.c
--- linux-2.6.39-libre/drivers/block/rbd.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/block/rbd.c	2011-07-11 19:51:52.000000000 -0400
@@ -1191,14 +1191,19 @@
 static void rbd_watch_cb(u64 ver, u64 notify_id, u8 opcode, void *data)
 {
 	struct rbd_device *dev = (struct rbd_device *)data;
+	int rc;
+
 	if (!dev)
 		return;
 
 	dout("rbd_watch_cb %s notify_id=%lld opcode=%d\n", dev->obj_md_name,
 		notify_id, (int)opcode);
 	mutex_lock_nested(&ctl_mutex, SINGLE_DEPTH_NESTING);
-	__rbd_update_snaps(dev);
+	rc = __rbd_update_snaps(dev);
 	mutex_unlock(&ctl_mutex);
+	if (rc)
+		pr_warning(DRV_NAME "%d got notification but failed to update"
+			   " snaps: %d\n", dev->major, rc);
 
 	rbd_req_sync_notify_ack(dev, ver, notify_id, dev->obj_md_name);
 }
@@ -1597,7 +1602,7 @@
 	int name_len = strlen(snap_name);
 	u64 new_snapid;
 	int ret;
-	void *data, *data_start, *data_end;
+	void *data, *p, *e;
 	u64 ver;
 
 	/* we should create a snapshot only if we're pointing at the head */
@@ -1614,16 +1619,16 @@
 	if (!data)
 		return -ENOMEM;
 
-	data_start = data;
-	data_end = data + name_len + 16;
+	p = data;
+	e = data + name_len + 16;
 
-	ceph_encode_string_safe(&data, data_end, snap_name, name_len, bad);
-	ceph_encode_64_safe(&data, data_end, new_snapid, bad);
+	ceph_encode_string_safe(&p, e, snap_name, name_len, bad);
+	ceph_encode_64_safe(&p, e, new_snapid, bad);
 
 	ret = rbd_req_sync_exec(dev, dev->obj_md_name, "rbd", "snap_add",
-				data_start, data - data_start, &ver);
+				data, p - data, &ver);
 
-	kfree(data_start);
+	kfree(data);
 
 	if (ret < 0)
 		return ret;
@@ -1659,6 +1664,9 @@
 	if (ret < 0)
 		return ret;
 
+	/* resized? */
+	set_capacity(rbd_dev->disk, h.image_size / 512ULL);
+
 	down_write(&rbd_dev->header.snap_rwsem);
 
 	snap_seq = rbd_dev->header.snapc->seq;
@@ -1716,7 +1724,8 @@
 	if (!disk)
 		goto out;
 
-	sprintf(disk->disk_name, DRV_NAME "%d", rbd_dev->id);
+	snprintf(disk->disk_name, sizeof(disk->disk_name), DRV_NAME "%d",
+		 rbd_dev->id);
 	disk->major = rbd_dev->major;
 	disk->first_minor = 0;
 	disk->fops = &rbd_bd_ops;
diff -druN linux-2.6.39-libre/drivers/block/virtio_blk.c linux-3.0-rc7-libre/drivers/block/virtio_blk.c
--- linux-2.6.39-libre/drivers/block/virtio_blk.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/block/virtio_blk.c	2011-07-11 19:51:52.000000000 -0400
@@ -6,10 +6,13 @@
 #include <linux/virtio.h>
 #include <linux/virtio_blk.h>
 #include <linux/scatterlist.h>
+#include <linux/string_helpers.h>
+#include <scsi/scsi_cmnd.h>
 
 #define PART_BITS 4
 
 static int major, index;
+struct workqueue_struct *virtblk_wq;
 
 struct virtio_blk
 {
@@ -26,6 +29,9 @@
 
 	mempool_t *pool;
 
+	/* Process context for config space updates */
+	struct work_struct config_work;
+
 	/* What host tells us, plus 2 for header & tailer. */
 	unsigned int sg_elems;
 
@@ -141,7 +147,7 @@
 	num = blk_rq_map_sg(q, vbr->req, vblk->sg + out);
 
 	if (vbr->req->cmd_type == REQ_TYPE_BLOCK_PC) {
-		sg_set_buf(&vblk->sg[num + out + in++], vbr->req->sense, 96);
+		sg_set_buf(&vblk->sg[num + out + in++], vbr->req->sense, SCSI_SENSE_BUFFERSIZE);
 		sg_set_buf(&vblk->sg[num + out + in++], &vbr->in_hdr,
 			   sizeof(vbr->in_hdr));
 	}
@@ -291,6 +297,46 @@
 }
 DEVICE_ATTR(serial, S_IRUGO, virtblk_serial_show, NULL);
 
+static void virtblk_config_changed_work(struct work_struct *work)
+{
+	struct virtio_blk *vblk =
+		container_of(work, struct virtio_blk, config_work);
+	struct virtio_device *vdev = vblk->vdev;
+	struct request_queue *q = vblk->disk->queue;
+	char cap_str_2[10], cap_str_10[10];
+	u64 capacity, size;
+
+	/* Host must always specify the capacity. */
+	vdev->config->get(vdev, offsetof(struct virtio_blk_config, capacity),
+			  &capacity, sizeof(capacity));
+
+	/* If capacity is too big, truncate with warning. */
+	if ((sector_t)capacity != capacity) {
+		dev_warn(&vdev->dev, "Capacity %llu too large: truncating\n",
+			 (unsigned long long)capacity);
+		capacity = (sector_t)-1;
+	}
+
+	size = capacity * queue_logical_block_size(q);
+	string_get_size(size, STRING_UNITS_2, cap_str_2, sizeof(cap_str_2));
+	string_get_size(size, STRING_UNITS_10, cap_str_10, sizeof(cap_str_10));
+
+	dev_notice(&vdev->dev,
+		  "new size: %llu %d-byte logical blocks (%s/%s)\n",
+		  (unsigned long long)capacity,
+		  queue_logical_block_size(q),
+		  cap_str_10, cap_str_2);
+
+	set_capacity(vblk->disk, capacity);
+}
+
+static void virtblk_config_changed(struct virtio_device *vdev)
+{
+	struct virtio_blk *vblk = vdev->priv;
+
+	queue_work(virtblk_wq, &vblk->config_work);
+}
+
 static int __devinit virtblk_probe(struct virtio_device *vdev)
 {
 	struct virtio_blk *vblk;
@@ -327,6 +373,7 @@
 	vblk->vdev = vdev;
 	vblk->sg_elems = sg_elems;
 	sg_init_table(vblk->sg, vblk->sg_elems);
+	INIT_WORK(&vblk->config_work, virtblk_config_changed_work);
 
 	/* We expect one virtqueue, for output. */
 	vblk->vq = virtio_find_single_vq(vdev, blk_done, "requests");
@@ -477,6 +524,8 @@
 {
 	struct virtio_blk *vblk = vdev->priv;
 
+	flush_work(&vblk->config_work);
+
 	/* Nothing should be pending. */
 	BUG_ON(!list_empty(&vblk->reqs));
 
@@ -508,27 +557,47 @@
  * Use __refdata to avoid this warning.
  */
 static struct virtio_driver __refdata virtio_blk = {
-	.feature_table = features,
-	.feature_table_size = ARRAY_SIZE(features),
-	.driver.name =	KBUILD_MODNAME,
-	.driver.owner =	THIS_MODULE,
-	.id_table =	id_table,
-	.probe =	virtblk_probe,
-	.remove =	__devexit_p(virtblk_remove),
+	.feature_table		= features,
+	.feature_table_size	= ARRAY_SIZE(features),
+	.driver.name		= KBUILD_MODNAME,
+	.driver.owner		= THIS_MODULE,
+	.id_table		= id_table,
+	.probe			= virtblk_probe,
+	.remove			= __devexit_p(virtblk_remove),
+	.config_changed		= virtblk_config_changed,
 };
 
 static int __init init(void)
 {
+	int error;
+
+	virtblk_wq = alloc_workqueue("virtio-blk", 0, 0);
+	if (!virtblk_wq)
+		return -ENOMEM;
+
 	major = register_blkdev(0, "virtblk");
-	if (major < 0)
-		return major;
-	return register_virtio_driver(&virtio_blk);
+	if (major < 0) {
+		error = major;
+		goto out_destroy_workqueue;
+	}
+
+	error = register_virtio_driver(&virtio_blk);
+	if (error)
+		goto out_unregister_blkdev;
+	return 0;
+
+out_unregister_blkdev:
+	unregister_blkdev(major, "virtblk");
+out_destroy_workqueue:
+	destroy_workqueue(virtblk_wq);
+	return error;
 }
 
 static void __exit fini(void)
 {
 	unregister_blkdev(major, "virtblk");
 	unregister_virtio_driver(&virtio_blk);
+	destroy_workqueue(virtblk_wq);
 }
 module_init(init);
 module_exit(fini);
diff -druN linux-2.6.39-libre/drivers/block/xen-blkback/blkback.c linux-3.0-rc7-libre/drivers/block/xen-blkback/blkback.c
--- linux-2.6.39-libre/drivers/block/xen-blkback/blkback.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/block/xen-blkback/blkback.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,826 @@
+/******************************************************************************
+ *
+ * Back-end of the driver for virtual block devices. This portion of the
+ * driver exports a 'unified' block-device interface that can be accessed
+ * by any operating system that implements a compatible front end. A
+ * reference front-end implementation can be found in:
+ *  drivers/block/xen-blkfront.c
+ *
+ * Copyright (c) 2003-2004, Keir Fraser & Steve Hand
+ * Copyright (c) 2005, Christopher Clark
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation; or, when distributed
+ * separately from the Linux kernel or incorporated into other
+ * software packages, subject to the following license:
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this source file (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy, modify,
+ * merge, publish, distribute, sublicense, and/or sell copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#include <linux/spinlock.h>
+#include <linux/kthread.h>
+#include <linux/list.h>
+#include <linux/delay.h>
+#include <linux/freezer.h>
+
+#include <xen/events.h>
+#include <xen/page.h>
+#include <asm/xen/hypervisor.h>
+#include <asm/xen/hypercall.h>
+#include "common.h"
+
+/*
+ * These are rather arbitrary. They are fairly large because adjacent requests
+ * pulled from a communication ring are quite likely to end up being part of
+ * the same scatter/gather request at the disc.
+ *
+ * ** TRY INCREASING 'xen_blkif_reqs' IF WRITE SPEEDS SEEM TOO LOW **
+ *
+ * This will increase the chances of being able to write whole tracks.
+ * 64 should be enough to keep us competitive with Linux.
+ */
+static int xen_blkif_reqs = 64;
+module_param_named(reqs, xen_blkif_reqs, int, 0);
+MODULE_PARM_DESC(reqs, "Number of blkback requests to allocate");
+
+/* Run-time switchable: /sys/module/blkback/parameters/ */
+static unsigned int log_stats;
+module_param(log_stats, int, 0644);
+
+/*
+ * Each outstanding request that we've passed to the lower device layers has a
+ * 'pending_req' allocated to it. Each buffer_head that completes decrements
+ * the pendcnt towards zero. When it hits zero, the specified domain has a
+ * response queued for it, with the saved 'id' passed back.
+ */
+struct pending_req {
+	struct xen_blkif	*blkif;
+	u64			id;
+	int			nr_pages;
+	atomic_t		pendcnt;
+	unsigned short		operation;
+	int			status;
+	struct list_head	free_list;
+};
+
+#define BLKBACK_INVALID_HANDLE (~0)
+
+struct xen_blkbk {
+	struct pending_req	*pending_reqs;
+	/* List of all 'pending_req' available */
+	struct list_head	pending_free;
+	/* And its spinlock. */
+	spinlock_t		pending_free_lock;
+	wait_queue_head_t	pending_free_wq;
+	/* The list of all pages that are available. */
+	struct page		**pending_pages;
+	/* And the grant handles that are available. */
+	grant_handle_t		*pending_grant_handles;
+};
+
+static struct xen_blkbk *blkbk;
+
+/*
+ * Little helpful macro to figure out the index and virtual address of the
+ * pending_pages[..]. For each 'pending_req' we have have up to
+ * BLKIF_MAX_SEGMENTS_PER_REQUEST (11) pages. The seg would be from 0 through
+ * 10 and would index in the pending_pages[..].
+ */
+static inline int vaddr_pagenr(struct pending_req *req, int seg)
+{
+	return (req - blkbk->pending_reqs) *
+		BLKIF_MAX_SEGMENTS_PER_REQUEST + seg;
+}
+
+#define pending_page(req, seg) pending_pages[vaddr_pagenr(req, seg)]
+
+static inline unsigned long vaddr(struct pending_req *req, int seg)
+{
+	unsigned long pfn = page_to_pfn(blkbk->pending_page(req, seg));
+	return (unsigned long)pfn_to_kaddr(pfn);
+}
+
+#define pending_handle(_req, _seg) \
+	(blkbk->pending_grant_handles[vaddr_pagenr(_req, _seg)])
+
+
+static int do_block_io_op(struct xen_blkif *blkif);
+static int dispatch_rw_block_io(struct xen_blkif *blkif,
+				struct blkif_request *req,
+				struct pending_req *pending_req);
+static void make_response(struct xen_blkif *blkif, u64 id,
+			  unsigned short op, int st);
+
+/*
+ * Retrieve from the 'pending_reqs' a free pending_req structure to be used.
+ */
+static struct pending_req *alloc_req(void)
+{
+	struct pending_req *req = NULL;
+	unsigned long flags;
+
+	spin_lock_irqsave(&blkbk->pending_free_lock, flags);
+	if (!list_empty(&blkbk->pending_free)) {
+		req = list_entry(blkbk->pending_free.next, struct pending_req,
+				 free_list);
+		list_del(&req->free_list);
+	}
+	spin_unlock_irqrestore(&blkbk->pending_free_lock, flags);
+	return req;
+}
+
+/*
+ * Return the 'pending_req' structure back to the freepool. We also
+ * wake up the thread if it was waiting for a free page.
+ */
+static void free_req(struct pending_req *req)
+{
+	unsigned long flags;
+	int was_empty;
+
+	spin_lock_irqsave(&blkbk->pending_free_lock, flags);
+	was_empty = list_empty(&blkbk->pending_free);
+	list_add(&req->free_list, &blkbk->pending_free);
+	spin_unlock_irqrestore(&blkbk->pending_free_lock, flags);
+	if (was_empty)
+		wake_up(&blkbk->pending_free_wq);
+}
+
+/*
+ * Routines for managing virtual block devices (vbds).
+ */
+static int xen_vbd_translate(struct phys_req *req, struct xen_blkif *blkif,
+			     int operation)
+{
+	struct xen_vbd *vbd = &blkif->vbd;
+	int rc = -EACCES;
+
+	if ((operation != READ) && vbd->readonly)
+		goto out;
+
+	if (likely(req->nr_sects)) {
+		blkif_sector_t end = req->sector_number + req->nr_sects;
+
+		if (unlikely(end < req->sector_number))
+			goto out;
+		if (unlikely(end > vbd_sz(vbd)))
+			goto out;
+	}
+
+	req->dev  = vbd->pdevice;
+	req->bdev = vbd->bdev;
+	rc = 0;
+
+ out:
+	return rc;
+}
+
+static void xen_vbd_resize(struct xen_blkif *blkif)
+{
+	struct xen_vbd *vbd = &blkif->vbd;
+	struct xenbus_transaction xbt;
+	int err;
+	struct xenbus_device *dev = xen_blkbk_xenbus(blkif->be);
+	unsigned long long new_size = vbd_sz(vbd);
+
+	pr_info(DRV_PFX "VBD Resize: Domid: %d, Device: (%d, %d)\n",
+		blkif->domid, MAJOR(vbd->pdevice), MINOR(vbd->pdevice));
+	pr_info(DRV_PFX "VBD Resize: new size %llu\n", new_size);
+	vbd->size = new_size;
+again:
+	err = xenbus_transaction_start(&xbt);
+	if (err) {
+		pr_warn(DRV_PFX "Error starting transaction");
+		return;
+	}
+	err = xenbus_printf(xbt, dev->nodename, "sectors", "%llu",
+			    (unsigned long long)vbd_sz(vbd));
+	if (err) {
+		pr_warn(DRV_PFX "Error writing new size");
+		goto abort;
+	}
+	/*
+	 * Write the current state; we will use this to synchronize
+	 * the front-end. If the current state is "connected" the
+	 * front-end will get the new size information online.
+	 */
+	err = xenbus_printf(xbt, dev->nodename, "state", "%d", dev->state);
+	if (err) {
+		pr_warn(DRV_PFX "Error writing the state");
+		goto abort;
+	}
+
+	err = xenbus_transaction_end(xbt, 0);
+	if (err == -EAGAIN)
+		goto again;
+	if (err)
+		pr_warn(DRV_PFX "Error ending transaction");
+	return;
+abort:
+	xenbus_transaction_end(xbt, 1);
+}
+
+/*
+ * Notification from the guest OS.
+ */
+static void blkif_notify_work(struct xen_blkif *blkif)
+{
+	blkif->waiting_reqs = 1;
+	wake_up(&blkif->wq);
+}
+
+irqreturn_t xen_blkif_be_int(int irq, void *dev_id)
+{
+	blkif_notify_work(dev_id);
+	return IRQ_HANDLED;
+}
+
+/*
+ * SCHEDULER FUNCTIONS
+ */
+
+static void print_stats(struct xen_blkif *blkif)
+{
+	pr_info("xen-blkback (%s): oo %3d  |  rd %4d  |  wr %4d  |  f %4d\n",
+		 current->comm, blkif->st_oo_req,
+		 blkif->st_rd_req, blkif->st_wr_req, blkif->st_f_req);
+	blkif->st_print = jiffies + msecs_to_jiffies(10 * 1000);
+	blkif->st_rd_req = 0;
+	blkif->st_wr_req = 0;
+	blkif->st_oo_req = 0;
+}
+
+int xen_blkif_schedule(void *arg)
+{
+	struct xen_blkif *blkif = arg;
+	struct xen_vbd *vbd = &blkif->vbd;
+
+	xen_blkif_get(blkif);
+
+	while (!kthread_should_stop()) {
+		if (try_to_freeze())
+			continue;
+		if (unlikely(vbd->size != vbd_sz(vbd)))
+			xen_vbd_resize(blkif);
+
+		wait_event_interruptible(
+			blkif->wq,
+			blkif->waiting_reqs || kthread_should_stop());
+		wait_event_interruptible(
+			blkbk->pending_free_wq,
+			!list_empty(&blkbk->pending_free) ||
+			kthread_should_stop());
+
+		blkif->waiting_reqs = 0;
+		smp_mb(); /* clear flag *before* checking for work */
+
+		if (do_block_io_op(blkif))
+			blkif->waiting_reqs = 1;
+
+		if (log_stats && time_after(jiffies, blkif->st_print))
+			print_stats(blkif);
+	}
+
+	if (log_stats)
+		print_stats(blkif);
+
+	blkif->xenblkd = NULL;
+	xen_blkif_put(blkif);
+
+	return 0;
+}
+
+struct seg_buf {
+	unsigned long buf;
+	unsigned int nsec;
+};
+/*
+ * Unmap the grant references, and also remove the M2P over-rides
+ * used in the 'pending_req'.
+ */
+static void xen_blkbk_unmap(struct pending_req *req)
+{
+	struct gnttab_unmap_grant_ref unmap[BLKIF_MAX_SEGMENTS_PER_REQUEST];
+	unsigned int i, invcount = 0;
+	grant_handle_t handle;
+	int ret;
+
+	for (i = 0; i < req->nr_pages; i++) {
+		handle = pending_handle(req, i);
+		if (handle == BLKBACK_INVALID_HANDLE)
+			continue;
+		gnttab_set_unmap_op(&unmap[invcount], vaddr(req, i),
+				    GNTMAP_host_map, handle);
+		pending_handle(req, i) = BLKBACK_INVALID_HANDLE;
+		invcount++;
+	}
+
+	ret = HYPERVISOR_grant_table_op(
+		GNTTABOP_unmap_grant_ref, unmap, invcount);
+	BUG_ON(ret);
+	/*
+	 * Note, we use invcount, so nr->pages, so we can't index
+	 * using vaddr(req, i).
+	 */
+	for (i = 0; i < invcount; i++) {
+		ret = m2p_remove_override(
+			virt_to_page(unmap[i].host_addr), false);
+		if (ret) {
+			pr_alert(DRV_PFX "Failed to remove M2P override for %lx\n",
+				 (unsigned long)unmap[i].host_addr);
+			continue;
+		}
+	}
+}
+
+static int xen_blkbk_map(struct blkif_request *req,
+			 struct pending_req *pending_req,
+			 struct seg_buf seg[])
+{
+	struct gnttab_map_grant_ref map[BLKIF_MAX_SEGMENTS_PER_REQUEST];
+	int i;
+	int nseg = req->nr_segments;
+	int ret = 0;
+
+	/*
+	 * Fill out preq.nr_sects with proper amount of sectors, and setup
+	 * assign map[..] with the PFN of the page in our domain with the
+	 * corresponding grant reference for each page.
+	 */
+	for (i = 0; i < nseg; i++) {
+		uint32_t flags;
+
+		flags = GNTMAP_host_map;
+		if (pending_req->operation != BLKIF_OP_READ)
+			flags |= GNTMAP_readonly;
+		gnttab_set_map_op(&map[i], vaddr(pending_req, i), flags,
+				  req->u.rw.seg[i].gref,
+				  pending_req->blkif->domid);
+	}
+
+	ret = HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, map, nseg);
+	BUG_ON(ret);
+
+	/*
+	 * Now swizzle the MFN in our domain with the MFN from the other domain
+	 * so that when we access vaddr(pending_req,i) it has the contents of
+	 * the page from the other domain.
+	 */
+	for (i = 0; i < nseg; i++) {
+		if (unlikely(map[i].status != 0)) {
+			pr_debug(DRV_PFX "invalid buffer -- could not remap it\n");
+			map[i].handle = BLKBACK_INVALID_HANDLE;
+			ret |= 1;
+		}
+
+		pending_handle(pending_req, i) = map[i].handle;
+
+		if (ret)
+			continue;
+
+		ret = m2p_add_override(PFN_DOWN(map[i].dev_bus_addr),
+			blkbk->pending_page(pending_req, i), false);
+		if (ret) {
+			pr_alert(DRV_PFX "Failed to install M2P override for %lx (ret: %d)\n",
+				 (unsigned long)map[i].dev_bus_addr, ret);
+			/* We could switch over to GNTTABOP_copy */
+			continue;
+		}
+
+		seg[i].buf  = map[i].dev_bus_addr |
+			(req->u.rw.seg[i].first_sect << 9);
+	}
+	return ret;
+}
+
+/*
+ * Completion callback on the bio's. Called as bh->b_end_io()
+ */
+
+static void __end_block_io_op(struct pending_req *pending_req, int error)
+{
+	/* An error fails the entire request. */
+	if ((pending_req->operation == BLKIF_OP_FLUSH_DISKCACHE) &&
+	    (error == -EOPNOTSUPP)) {
+		pr_debug(DRV_PFX "flush diskcache op failed, not supported\n");
+		xen_blkbk_flush_diskcache(XBT_NIL, pending_req->blkif->be, 0);
+		pending_req->status = BLKIF_RSP_EOPNOTSUPP;
+	} else if (error) {
+		pr_debug(DRV_PFX "Buffer not up-to-date at end of operation,"
+			 " error=%d\n", error);
+		pending_req->status = BLKIF_RSP_ERROR;
+	}
+
+	/*
+	 * If all of the bio's have completed it is time to unmap
+	 * the grant references associated with 'request' and provide
+	 * the proper response on the ring.
+	 */
+	if (atomic_dec_and_test(&pending_req->pendcnt)) {
+		xen_blkbk_unmap(pending_req);
+		make_response(pending_req->blkif, pending_req->id,
+			      pending_req->operation, pending_req->status);
+		xen_blkif_put(pending_req->blkif);
+		free_req(pending_req);
+	}
+}
+
+/*
+ * bio callback.
+ */
+static void end_block_io_op(struct bio *bio, int error)
+{
+	__end_block_io_op(bio->bi_private, error);
+	bio_put(bio);
+}
+
+
+
+/*
+ * Function to copy the from the ring buffer the 'struct blkif_request'
+ * (which has the sectors we want, number of them, grant references, etc),
+ * and transmute  it to the block API to hand it over to the proper block disk.
+ */
+static int do_block_io_op(struct xen_blkif *blkif)
+{
+	union blkif_back_rings *blk_rings = &blkif->blk_rings;
+	struct blkif_request req;
+	struct pending_req *pending_req;
+	RING_IDX rc, rp;
+	int more_to_do = 0;
+
+	rc = blk_rings->common.req_cons;
+	rp = blk_rings->common.sring->req_prod;
+	rmb(); /* Ensure we see queued requests up to 'rp'. */
+
+	while (rc != rp) {
+
+		if (RING_REQUEST_CONS_OVERFLOW(&blk_rings->common, rc))
+			break;
+
+		if (kthread_should_stop()) {
+			more_to_do = 1;
+			break;
+		}
+
+		pending_req = alloc_req();
+		if (NULL == pending_req) {
+			blkif->st_oo_req++;
+			more_to_do = 1;
+			break;
+		}
+
+		switch (blkif->blk_protocol) {
+		case BLKIF_PROTOCOL_NATIVE:
+			memcpy(&req, RING_GET_REQUEST(&blk_rings->native, rc), sizeof(req));
+			break;
+		case BLKIF_PROTOCOL_X86_32:
+			blkif_get_x86_32_req(&req, RING_GET_REQUEST(&blk_rings->x86_32, rc));
+			break;
+		case BLKIF_PROTOCOL_X86_64:
+			blkif_get_x86_64_req(&req, RING_GET_REQUEST(&blk_rings->x86_64, rc));
+			break;
+		default:
+			BUG();
+		}
+		blk_rings->common.req_cons = ++rc; /* before make_response() */
+
+		/* Apply all sanity checks to /private copy/ of request. */
+		barrier();
+
+		if (dispatch_rw_block_io(blkif, &req, pending_req))
+			break;
+
+		/* Yield point for this unbounded loop. */
+		cond_resched();
+	}
+
+	return more_to_do;
+}
+
+/*
+ * Transmutation of the 'struct blkif_request' to a proper 'struct bio'
+ * and call the 'submit_bio' to pass it to the underlying storage.
+ */
+static int dispatch_rw_block_io(struct xen_blkif *blkif,
+				struct blkif_request *req,
+				struct pending_req *pending_req)
+{
+	struct phys_req preq;
+	struct seg_buf seg[BLKIF_MAX_SEGMENTS_PER_REQUEST];
+	unsigned int nseg;
+	struct bio *bio = NULL;
+	struct bio *biolist[BLKIF_MAX_SEGMENTS_PER_REQUEST];
+	int i, nbio = 0;
+	int operation;
+	struct blk_plug plug;
+
+	switch (req->operation) {
+	case BLKIF_OP_READ:
+		blkif->st_rd_req++;
+		operation = READ;
+		break;
+	case BLKIF_OP_WRITE:
+		blkif->st_wr_req++;
+		operation = WRITE_ODIRECT;
+		break;
+	case BLKIF_OP_FLUSH_DISKCACHE:
+		blkif->st_f_req++;
+		operation = WRITE_FLUSH;
+		break;
+	case BLKIF_OP_WRITE_BARRIER:
+	default:
+		operation = 0; /* make gcc happy */
+		goto fail_response;
+		break;
+	}
+
+	/* Check that the number of segments is sane. */
+	nseg = req->nr_segments;
+	if (unlikely(nseg == 0 && operation != WRITE_FLUSH) ||
+	    unlikely(nseg > BLKIF_MAX_SEGMENTS_PER_REQUEST)) {
+		pr_debug(DRV_PFX "Bad number of segments in request (%d)\n",
+			 nseg);
+		/* Haven't submitted any bio's yet. */
+		goto fail_response;
+	}
+
+	preq.dev           = req->handle;
+	preq.sector_number = req->u.rw.sector_number;
+	preq.nr_sects      = 0;
+
+	pending_req->blkif     = blkif;
+	pending_req->id        = req->id;
+	pending_req->operation = req->operation;
+	pending_req->status    = BLKIF_RSP_OKAY;
+	pending_req->nr_pages  = nseg;
+
+	for (i = 0; i < nseg; i++) {
+		seg[i].nsec = req->u.rw.seg[i].last_sect -
+			req->u.rw.seg[i].first_sect + 1;
+		if ((req->u.rw.seg[i].last_sect >= (PAGE_SIZE >> 9)) ||
+		    (req->u.rw.seg[i].last_sect < req->u.rw.seg[i].first_sect))
+			goto fail_response;
+		preq.nr_sects += seg[i].nsec;
+
+	}
+
+	if (xen_vbd_translate(&preq, blkif, operation) != 0) {
+		pr_debug(DRV_PFX "access denied: %s of [%llu,%llu] on dev=%04x\n",
+			 operation == READ ? "read" : "write",
+			 preq.sector_number,
+			 preq.sector_number + preq.nr_sects, preq.dev);
+		goto fail_response;
+	}
+
+	/*
+	 * This check _MUST_ be done after xen_vbd_translate as the preq.bdev
+	 * is set there.
+	 */
+	for (i = 0; i < nseg; i++) {
+		if (((int)preq.sector_number|(int)seg[i].nsec) &
+		    ((bdev_logical_block_size(preq.bdev) >> 9) - 1)) {
+			pr_debug(DRV_PFX "Misaligned I/O request from domain %d",
+				 blkif->domid);
+			goto fail_response;
+		}
+	}
+
+	/*
+	 * If we have failed at this point, we need to undo the M2P override,
+	 * set gnttab_set_unmap_op on all of the grant references and perform
+	 * the hypercall to unmap the grants - that is all done in
+	 * xen_blkbk_unmap.
+	 */
+	if (xen_blkbk_map(req, pending_req, seg))
+		goto fail_flush;
+
+	/* This corresponding xen_blkif_put is done in __end_block_io_op */
+	xen_blkif_get(blkif);
+
+	for (i = 0; i < nseg; i++) {
+		while ((bio == NULL) ||
+		       (bio_add_page(bio,
+				     blkbk->pending_page(pending_req, i),
+				     seg[i].nsec << 9,
+				     seg[i].buf & ~PAGE_MASK) == 0)) {
+
+			bio = bio_alloc(GFP_KERNEL, nseg-i);
+			if (unlikely(bio == NULL))
+				goto fail_put_bio;
+
+			biolist[nbio++] = bio;
+			bio->bi_bdev    = preq.bdev;
+			bio->bi_private = pending_req;
+			bio->bi_end_io  = end_block_io_op;
+			bio->bi_sector  = preq.sector_number;
+		}
+
+		preq.sector_number += seg[i].nsec;
+	}
+
+	/* This will be hit if the operation was a flush. */
+	if (!bio) {
+		BUG_ON(operation != WRITE_FLUSH);
+
+		bio = bio_alloc(GFP_KERNEL, 0);
+		if (unlikely(bio == NULL))
+			goto fail_put_bio;
+
+		biolist[nbio++] = bio;
+		bio->bi_bdev    = preq.bdev;
+		bio->bi_private = pending_req;
+		bio->bi_end_io  = end_block_io_op;
+	}
+
+	/*
+	 * We set it one so that the last submit_bio does not have to call
+	 * atomic_inc.
+	 */
+	atomic_set(&pending_req->pendcnt, nbio);
+
+	/* Get a reference count for the disk queue and start sending I/O */
+	blk_start_plug(&plug);
+
+	for (i = 0; i < nbio; i++)
+		submit_bio(operation, biolist[i]);
+
+	/* Let the I/Os go.. */
+	blk_finish_plug(&plug);
+
+	if (operation == READ)
+		blkif->st_rd_sect += preq.nr_sects;
+	else if (operation == WRITE || operation == WRITE_FLUSH)
+		blkif->st_wr_sect += preq.nr_sects;
+
+	return 0;
+
+ fail_flush:
+	xen_blkbk_unmap(pending_req);
+ fail_response:
+	/* Haven't submitted any bio's yet. */
+	make_response(blkif, req->id, req->operation, BLKIF_RSP_ERROR);
+	free_req(pending_req);
+	msleep(1); /* back off a bit */
+	return -EIO;
+
+ fail_put_bio:
+	for (i = 0; i < nbio; i++)
+		bio_put(biolist[i]);
+	__end_block_io_op(pending_req, -EINVAL);
+	msleep(1); /* back off a bit */
+	return -EIO;
+}
+
+
+
+/*
+ * Put a response on the ring on how the operation fared.
+ */
+static void make_response(struct xen_blkif *blkif, u64 id,
+			  unsigned short op, int st)
+{
+	struct blkif_response  resp;
+	unsigned long     flags;
+	union blkif_back_rings *blk_rings = &blkif->blk_rings;
+	int more_to_do = 0;
+	int notify;
+
+	resp.id        = id;
+	resp.operation = op;
+	resp.status    = st;
+
+	spin_lock_irqsave(&blkif->blk_ring_lock, flags);
+	/* Place on the response ring for the relevant domain. */
+	switch (blkif->blk_protocol) {
+	case BLKIF_PROTOCOL_NATIVE:
+		memcpy(RING_GET_RESPONSE(&blk_rings->native, blk_rings->native.rsp_prod_pvt),
+		       &resp, sizeof(resp));
+		break;
+	case BLKIF_PROTOCOL_X86_32:
+		memcpy(RING_GET_RESPONSE(&blk_rings->x86_32, blk_rings->x86_32.rsp_prod_pvt),
+		       &resp, sizeof(resp));
+		break;
+	case BLKIF_PROTOCOL_X86_64:
+		memcpy(RING_GET_RESPONSE(&blk_rings->x86_64, blk_rings->x86_64.rsp_prod_pvt),
+		       &resp, sizeof(resp));
+		break;
+	default:
+		BUG();
+	}
+	blk_rings->common.rsp_prod_pvt++;
+	RING_PUSH_RESPONSES_AND_CHECK_NOTIFY(&blk_rings->common, notify);
+	if (blk_rings->common.rsp_prod_pvt == blk_rings->common.req_cons) {
+		/*
+		 * Tail check for pending requests. Allows frontend to avoid
+		 * notifications if requests are already in flight (lower
+		 * overheads and promotes batching).
+		 */
+		RING_FINAL_CHECK_FOR_REQUESTS(&blk_rings->common, more_to_do);
+
+	} else if (RING_HAS_UNCONSUMED_REQUESTS(&blk_rings->common)) {
+		more_to_do = 1;
+	}
+
+	spin_unlock_irqrestore(&blkif->blk_ring_lock, flags);
+
+	if (more_to_do)
+		blkif_notify_work(blkif);
+	if (notify)
+		notify_remote_via_irq(blkif->irq);
+}
+
+static int __init xen_blkif_init(void)
+{
+	int i, mmap_pages;
+	int rc = 0;
+
+	if (!xen_pv_domain())
+		return -ENODEV;
+
+	blkbk = kzalloc(sizeof(struct xen_blkbk), GFP_KERNEL);
+	if (!blkbk) {
+		pr_alert(DRV_PFX "%s: out of memory!\n", __func__);
+		return -ENOMEM;
+	}
+
+	mmap_pages = xen_blkif_reqs * BLKIF_MAX_SEGMENTS_PER_REQUEST;
+
+	blkbk->pending_reqs          = kmalloc(sizeof(blkbk->pending_reqs[0]) *
+					xen_blkif_reqs, GFP_KERNEL);
+	blkbk->pending_grant_handles = kzalloc(sizeof(blkbk->pending_grant_handles[0]) *
+					mmap_pages, GFP_KERNEL);
+	blkbk->pending_pages         = kzalloc(sizeof(blkbk->pending_pages[0]) *
+					mmap_pages, GFP_KERNEL);
+
+	if (!blkbk->pending_reqs || !blkbk->pending_grant_handles ||
+	    !blkbk->pending_pages) {
+		rc = -ENOMEM;
+		goto out_of_memory;
+	}
+
+	for (i = 0; i < mmap_pages; i++) {
+		blkbk->pending_grant_handles[i] = BLKBACK_INVALID_HANDLE;
+		blkbk->pending_pages[i] = alloc_page(GFP_KERNEL);
+		if (blkbk->pending_pages[i] == NULL) {
+			rc = -ENOMEM;
+			goto out_of_memory;
+		}
+	}
+	rc = xen_blkif_interface_init();
+	if (rc)
+		goto failed_init;
+
+	memset(blkbk->pending_reqs, 0, sizeof(blkbk->pending_reqs));
+
+	INIT_LIST_HEAD(&blkbk->pending_free);
+	spin_lock_init(&blkbk->pending_free_lock);
+	init_waitqueue_head(&blkbk->pending_free_wq);
+
+	for (i = 0; i < xen_blkif_reqs; i++)
+		list_add_tail(&blkbk->pending_reqs[i].free_list,
+			      &blkbk->pending_free);
+
+	rc = xen_blkif_xenbus_init();
+	if (rc)
+		goto failed_init;
+
+	return 0;
+
+ out_of_memory:
+	pr_alert(DRV_PFX "%s: out of memory\n", __func__);
+ failed_init:
+	kfree(blkbk->pending_reqs);
+	kfree(blkbk->pending_grant_handles);
+	if (blkbk->pending_pages) {
+		for (i = 0; i < mmap_pages; i++) {
+			if (blkbk->pending_pages[i])
+				__free_page(blkbk->pending_pages[i]);
+		}
+		kfree(blkbk->pending_pages);
+	}
+	kfree(blkbk);
+	blkbk = NULL;
+	return rc;
+}
+
+module_init(xen_blkif_init);
+
+MODULE_LICENSE("Dual BSD/GPL");
diff -druN linux-2.6.39-libre/drivers/block/xen-blkback/common.h linux-3.0-rc7-libre/drivers/block/xen-blkback/common.h
--- linux-2.6.39-libre/drivers/block/xen-blkback/common.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/block/xen-blkback/common.h	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,233 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation; or, when distributed
+ * separately from the Linux kernel or incorporated into other
+ * software packages, subject to the following license:
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this source file (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy, modify,
+ * merge, publish, distribute, sublicense, and/or sell copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#ifndef __XEN_BLKIF__BACKEND__COMMON_H__
+#define __XEN_BLKIF__BACKEND__COMMON_H__
+
+#include <linux/version.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/slab.h>
+#include <linux/blkdev.h>
+#include <linux/vmalloc.h>
+#include <linux/wait.h>
+#include <linux/io.h>
+#include <asm/setup.h>
+#include <asm/pgalloc.h>
+#include <asm/hypervisor.h>
+#include <xen/grant_table.h>
+#include <xen/xenbus.h>
+#include <xen/interface/io/ring.h>
+#include <xen/interface/io/blkif.h>
+#include <xen/interface/io/protocols.h>
+
+#define DRV_PFX "xen-blkback:"
+#define DPRINTK(fmt, args...)				\
+	pr_debug(DRV_PFX "(%s:%d) " fmt ".\n",	\
+		 __func__, __LINE__, ##args)
+
+
+/* Not a real protocol.  Used to generate ring structs which contain
+ * the elements common to all protocols only.  This way we get a
+ * compiler-checkable way to use common struct elements, so we can
+ * avoid using switch(protocol) in a number of places.  */
+struct blkif_common_request {
+	char dummy;
+};
+struct blkif_common_response {
+	char dummy;
+};
+
+/* i386 protocol version */
+#pragma pack(push, 4)
+struct blkif_x86_32_request {
+	uint8_t        operation;    /* BLKIF_OP_???                         */
+	uint8_t        nr_segments;  /* number of segments                   */
+	blkif_vdev_t   handle;       /* only for read/write requests         */
+	uint64_t       id;           /* private guest value, echoed in resp  */
+	blkif_sector_t sector_number;/* start sector idx on disk (r/w only)  */
+	struct blkif_request_segment seg[BLKIF_MAX_SEGMENTS_PER_REQUEST];
+};
+struct blkif_x86_32_response {
+	uint64_t        id;              /* copied from request */
+	uint8_t         operation;       /* copied from request */
+	int16_t         status;          /* BLKIF_RSP_???       */
+};
+#pragma pack(pop)
+
+/* x86_64 protocol version */
+struct blkif_x86_64_request {
+	uint8_t        operation;    /* BLKIF_OP_???                         */
+	uint8_t        nr_segments;  /* number of segments                   */
+	blkif_vdev_t   handle;       /* only for read/write requests         */
+	uint64_t       __attribute__((__aligned__(8))) id;
+	blkif_sector_t sector_number;/* start sector idx on disk (r/w only)  */
+	struct blkif_request_segment seg[BLKIF_MAX_SEGMENTS_PER_REQUEST];
+};
+struct blkif_x86_64_response {
+	uint64_t       __attribute__((__aligned__(8))) id;
+	uint8_t         operation;       /* copied from request */
+	int16_t         status;          /* BLKIF_RSP_???       */
+};
+
+DEFINE_RING_TYPES(blkif_common, struct blkif_common_request,
+		  struct blkif_common_response);
+DEFINE_RING_TYPES(blkif_x86_32, struct blkif_x86_32_request,
+		  struct blkif_x86_32_response);
+DEFINE_RING_TYPES(blkif_x86_64, struct blkif_x86_64_request,
+		  struct blkif_x86_64_response);
+
+union blkif_back_rings {
+	struct blkif_back_ring        native;
+	struct blkif_common_back_ring common;
+	struct blkif_x86_32_back_ring x86_32;
+	struct blkif_x86_64_back_ring x86_64;
+};
+
+enum blkif_protocol {
+	BLKIF_PROTOCOL_NATIVE = 1,
+	BLKIF_PROTOCOL_X86_32 = 2,
+	BLKIF_PROTOCOL_X86_64 = 3,
+};
+
+struct xen_vbd {
+	/* What the domain refers to this vbd as. */
+	blkif_vdev_t		handle;
+	/* Non-zero -> read-only */
+	unsigned char		readonly;
+	/* VDISK_xxx */
+	unsigned char		type;
+	/* phys device that this vbd maps to. */
+	u32			pdevice;
+	struct block_device	*bdev;
+	/* Cached size parameter. */
+	sector_t		size;
+	bool			flush_support;
+};
+
+struct backend_info;
+
+struct xen_blkif {
+	/* Unique identifier for this interface. */
+	domid_t			domid;
+	unsigned int		handle;
+	/* Physical parameters of the comms window. */
+	unsigned int		irq;
+	/* Comms information. */
+	enum blkif_protocol	blk_protocol;
+	union blkif_back_rings	blk_rings;
+	struct vm_struct	*blk_ring_area;
+	/* The VBD attached to this interface. */
+	struct xen_vbd		vbd;
+	/* Back pointer to the backend_info. */
+	struct backend_info	*be;
+	/* Private fields. */
+	spinlock_t		blk_ring_lock;
+	atomic_t		refcnt;
+
+	wait_queue_head_t	wq;
+	/* One thread per one blkif. */
+	struct task_struct	*xenblkd;
+	unsigned int		waiting_reqs;
+
+	/* statistics */
+	unsigned long		st_print;
+	int			st_rd_req;
+	int			st_wr_req;
+	int			st_oo_req;
+	int			st_f_req;
+	int			st_rd_sect;
+	int			st_wr_sect;
+
+	wait_queue_head_t	waiting_to_free;
+
+	grant_handle_t		shmem_handle;
+	grant_ref_t		shmem_ref;
+};
+
+
+#define vbd_sz(_v)	((_v)->bdev->bd_part ? \
+			 (_v)->bdev->bd_part->nr_sects : \
+			  get_capacity((_v)->bdev->bd_disk))
+
+#define xen_blkif_get(_b) (atomic_inc(&(_b)->refcnt))
+#define xen_blkif_put(_b)				\
+	do {						\
+		if (atomic_dec_and_test(&(_b)->refcnt))	\
+			wake_up(&(_b)->waiting_to_free);\
+	} while (0)
+
+struct phys_req {
+	unsigned short		dev;
+	unsigned short		nr_sects;
+	struct block_device	*bdev;
+	blkif_sector_t		sector_number;
+};
+int xen_blkif_interface_init(void);
+
+int xen_blkif_xenbus_init(void);
+
+irqreturn_t xen_blkif_be_int(int irq, void *dev_id);
+int xen_blkif_schedule(void *arg);
+
+int xen_blkbk_flush_diskcache(struct xenbus_transaction xbt,
+			      struct backend_info *be, int state);
+
+struct xenbus_device *xen_blkbk_xenbus(struct backend_info *be);
+
+static inline void blkif_get_x86_32_req(struct blkif_request *dst,
+					struct blkif_x86_32_request *src)
+{
+	int i, n = BLKIF_MAX_SEGMENTS_PER_REQUEST;
+	dst->operation = src->operation;
+	dst->nr_segments = src->nr_segments;
+	dst->handle = src->handle;
+	dst->id = src->id;
+	dst->u.rw.sector_number = src->sector_number;
+	barrier();
+	if (n > dst->nr_segments)
+		n = dst->nr_segments;
+	for (i = 0; i < n; i++)
+		dst->u.rw.seg[i] = src->seg[i];
+}
+
+static inline void blkif_get_x86_64_req(struct blkif_request *dst,
+					struct blkif_x86_64_request *src)
+{
+	int i, n = BLKIF_MAX_SEGMENTS_PER_REQUEST;
+	dst->operation = src->operation;
+	dst->nr_segments = src->nr_segments;
+	dst->handle = src->handle;
+	dst->id = src->id;
+	dst->u.rw.sector_number = src->sector_number;
+	barrier();
+	if (n > dst->nr_segments)
+		n = dst->nr_segments;
+	for (i = 0; i < n; i++)
+		dst->u.rw.seg[i] = src->seg[i];
+}
+
+#endif /* __XEN_BLKIF__BACKEND__COMMON_H__ */
diff -druN linux-2.6.39-libre/drivers/block/xen-blkback/Makefile linux-3.0-rc7-libre/drivers/block/xen-blkback/Makefile
--- linux-2.6.39-libre/drivers/block/xen-blkback/Makefile	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/block/xen-blkback/Makefile	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,3 @@
+obj-$(CONFIG_XEN_BLKDEV_BACKEND) := xen-blkback.o
+
+xen-blkback-y	:= blkback.o xenbus.o
diff -druN linux-2.6.39-libre/drivers/block/xen-blkback/xenbus.c linux-3.0-rc7-libre/drivers/block/xen-blkback/xenbus.c
--- linux-2.6.39-libre/drivers/block/xen-blkback/xenbus.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/block/xen-blkback/xenbus.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,767 @@
+/*  Xenbus code for blkif backend
+    Copyright (C) 2005 Rusty Russell <rusty@rustcorp.com.au>
+    Copyright (C) 2005 XenSource Ltd
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+*/
+
+#include <stdarg.h>
+#include <linux/module.h>
+#include <linux/kthread.h>
+#include <xen/events.h>
+#include <xen/grant_table.h>
+#include "common.h"
+
+struct backend_info {
+	struct xenbus_device	*dev;
+	struct xen_blkif	*blkif;
+	struct xenbus_watch	backend_watch;
+	unsigned		major;
+	unsigned		minor;
+	char			*mode;
+};
+
+static struct kmem_cache *xen_blkif_cachep;
+static void connect(struct backend_info *);
+static int connect_ring(struct backend_info *);
+static void backend_changed(struct xenbus_watch *, const char **,
+			    unsigned int);
+
+struct xenbus_device *xen_blkbk_xenbus(struct backend_info *be)
+{
+	return be->dev;
+}
+
+static int blkback_name(struct xen_blkif *blkif, char *buf)
+{
+	char *devpath, *devname;
+	struct xenbus_device *dev = blkif->be->dev;
+
+	devpath = xenbus_read(XBT_NIL, dev->nodename, "dev", NULL);
+	if (IS_ERR(devpath))
+		return PTR_ERR(devpath);
+
+	devname = strstr(devpath, "/dev/");
+	if (devname != NULL)
+		devname += strlen("/dev/");
+	else
+		devname  = devpath;
+
+	snprintf(buf, TASK_COMM_LEN, "blkback.%d.%s", blkif->domid, devname);
+	kfree(devpath);
+
+	return 0;
+}
+
+static void xen_update_blkif_status(struct xen_blkif *blkif)
+{
+	int err;
+	char name[TASK_COMM_LEN];
+
+	/* Not ready to connect? */
+	if (!blkif->irq || !blkif->vbd.bdev)
+		return;
+
+	/* Already connected? */
+	if (blkif->be->dev->state == XenbusStateConnected)
+		return;
+
+	/* Attempt to connect: exit if we fail to. */
+	connect(blkif->be);
+	if (blkif->be->dev->state != XenbusStateConnected)
+		return;
+
+	err = blkback_name(blkif, name);
+	if (err) {
+		xenbus_dev_error(blkif->be->dev, err, "get blkback dev name");
+		return;
+	}
+
+	err = filemap_write_and_wait(blkif->vbd.bdev->bd_inode->i_mapping);
+	if (err) {
+		xenbus_dev_error(blkif->be->dev, err, "block flush");
+		return;
+	}
+	invalidate_inode_pages2(blkif->vbd.bdev->bd_inode->i_mapping);
+
+	blkif->xenblkd = kthread_run(xen_blkif_schedule, blkif, name);
+	if (IS_ERR(blkif->xenblkd)) {
+		err = PTR_ERR(blkif->xenblkd);
+		blkif->xenblkd = NULL;
+		xenbus_dev_error(blkif->be->dev, err, "start xenblkd");
+	}
+}
+
+static struct xen_blkif *xen_blkif_alloc(domid_t domid)
+{
+	struct xen_blkif *blkif;
+
+	blkif = kmem_cache_alloc(xen_blkif_cachep, GFP_KERNEL);
+	if (!blkif)
+		return ERR_PTR(-ENOMEM);
+
+	memset(blkif, 0, sizeof(*blkif));
+	blkif->domid = domid;
+	spin_lock_init(&blkif->blk_ring_lock);
+	atomic_set(&blkif->refcnt, 1);
+	init_waitqueue_head(&blkif->wq);
+	blkif->st_print = jiffies;
+	init_waitqueue_head(&blkif->waiting_to_free);
+
+	return blkif;
+}
+
+static int map_frontend_page(struct xen_blkif *blkif, unsigned long shared_page)
+{
+	struct gnttab_map_grant_ref op;
+
+	gnttab_set_map_op(&op, (unsigned long)blkif->blk_ring_area->addr,
+			  GNTMAP_host_map, shared_page, blkif->domid);
+
+	if (HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1))
+		BUG();
+
+	if (op.status) {
+		DPRINTK("Grant table operation failure !\n");
+		return op.status;
+	}
+
+	blkif->shmem_ref = shared_page;
+	blkif->shmem_handle = op.handle;
+
+	return 0;
+}
+
+static void unmap_frontend_page(struct xen_blkif *blkif)
+{
+	struct gnttab_unmap_grant_ref op;
+
+	gnttab_set_unmap_op(&op, (unsigned long)blkif->blk_ring_area->addr,
+			    GNTMAP_host_map, blkif->shmem_handle);
+
+	if (HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, &op, 1))
+		BUG();
+}
+
+static int xen_blkif_map(struct xen_blkif *blkif, unsigned long shared_page,
+			 unsigned int evtchn)
+{
+	int err;
+
+	/* Already connected through? */
+	if (blkif->irq)
+		return 0;
+
+	blkif->blk_ring_area = alloc_vm_area(PAGE_SIZE);
+	if (!blkif->blk_ring_area)
+		return -ENOMEM;
+
+	err = map_frontend_page(blkif, shared_page);
+	if (err) {
+		free_vm_area(blkif->blk_ring_area);
+		return err;
+	}
+
+	switch (blkif->blk_protocol) {
+	case BLKIF_PROTOCOL_NATIVE:
+	{
+		struct blkif_sring *sring;
+		sring = (struct blkif_sring *)blkif->blk_ring_area->addr;
+		BACK_RING_INIT(&blkif->blk_rings.native, sring, PAGE_SIZE);
+		break;
+	}
+	case BLKIF_PROTOCOL_X86_32:
+	{
+		struct blkif_x86_32_sring *sring_x86_32;
+		sring_x86_32 = (struct blkif_x86_32_sring *)blkif->blk_ring_area->addr;
+		BACK_RING_INIT(&blkif->blk_rings.x86_32, sring_x86_32, PAGE_SIZE);
+		break;
+	}
+	case BLKIF_PROTOCOL_X86_64:
+	{
+		struct blkif_x86_64_sring *sring_x86_64;
+		sring_x86_64 = (struct blkif_x86_64_sring *)blkif->blk_ring_area->addr;
+		BACK_RING_INIT(&blkif->blk_rings.x86_64, sring_x86_64, PAGE_SIZE);
+		break;
+	}
+	default:
+		BUG();
+	}
+
+	err = bind_interdomain_evtchn_to_irqhandler(blkif->domid, evtchn,
+						    xen_blkif_be_int, 0,
+						    "blkif-backend", blkif);
+	if (err < 0) {
+		unmap_frontend_page(blkif);
+		free_vm_area(blkif->blk_ring_area);
+		blkif->blk_rings.common.sring = NULL;
+		return err;
+	}
+	blkif->irq = err;
+
+	return 0;
+}
+
+static void xen_blkif_disconnect(struct xen_blkif *blkif)
+{
+	if (blkif->xenblkd) {
+		kthread_stop(blkif->xenblkd);
+		blkif->xenblkd = NULL;
+	}
+
+	atomic_dec(&blkif->refcnt);
+	wait_event(blkif->waiting_to_free, atomic_read(&blkif->refcnt) == 0);
+	atomic_inc(&blkif->refcnt);
+
+	if (blkif->irq) {
+		unbind_from_irqhandler(blkif->irq, blkif);
+		blkif->irq = 0;
+	}
+
+	if (blkif->blk_rings.common.sring) {
+		unmap_frontend_page(blkif);
+		free_vm_area(blkif->blk_ring_area);
+		blkif->blk_rings.common.sring = NULL;
+	}
+}
+
+void xen_blkif_free(struct xen_blkif *blkif)
+{
+	if (!atomic_dec_and_test(&blkif->refcnt))
+		BUG();
+	kmem_cache_free(xen_blkif_cachep, blkif);
+}
+
+int __init xen_blkif_interface_init(void)
+{
+	xen_blkif_cachep = kmem_cache_create("blkif_cache",
+					     sizeof(struct xen_blkif),
+					     0, 0, NULL);
+	if (!xen_blkif_cachep)
+		return -ENOMEM;
+
+	return 0;
+}
+
+/*
+ *  sysfs interface for VBD I/O requests
+ */
+
+#define VBD_SHOW(name, format, args...)					\
+	static ssize_t show_##name(struct device *_dev,			\
+				   struct device_attribute *attr,	\
+				   char *buf)				\
+	{								\
+		struct xenbus_device *dev = to_xenbus_device(_dev);	\
+		struct backend_info *be = dev_get_drvdata(&dev->dev);	\
+									\
+		return sprintf(buf, format, ##args);			\
+	}								\
+	static DEVICE_ATTR(name, S_IRUGO, show_##name, NULL)
+
+VBD_SHOW(oo_req,  "%d\n", be->blkif->st_oo_req);
+VBD_SHOW(rd_req,  "%d\n", be->blkif->st_rd_req);
+VBD_SHOW(wr_req,  "%d\n", be->blkif->st_wr_req);
+VBD_SHOW(f_req,  "%d\n", be->blkif->st_f_req);
+VBD_SHOW(rd_sect, "%d\n", be->blkif->st_rd_sect);
+VBD_SHOW(wr_sect, "%d\n", be->blkif->st_wr_sect);
+
+static struct attribute *xen_vbdstat_attrs[] = {
+	&dev_attr_oo_req.attr,
+	&dev_attr_rd_req.attr,
+	&dev_attr_wr_req.attr,
+	&dev_attr_f_req.attr,
+	&dev_attr_rd_sect.attr,
+	&dev_attr_wr_sect.attr,
+	NULL
+};
+
+static struct attribute_group xen_vbdstat_group = {
+	.name = "statistics",
+	.attrs = xen_vbdstat_attrs,
+};
+
+VBD_SHOW(physical_device, "%x:%x\n", be->major, be->minor);
+VBD_SHOW(mode, "%s\n", be->mode);
+
+int xenvbd_sysfs_addif(struct xenbus_device *dev)
+{
+	int error;
+
+	error = device_create_file(&dev->dev, &dev_attr_physical_device);
+	if (error)
+		goto fail1;
+
+	error = device_create_file(&dev->dev, &dev_attr_mode);
+	if (error)
+		goto fail2;
+
+	error = sysfs_create_group(&dev->dev.kobj, &xen_vbdstat_group);
+	if (error)
+		goto fail3;
+
+	return 0;
+
+fail3:	sysfs_remove_group(&dev->dev.kobj, &xen_vbdstat_group);
+fail2:	device_remove_file(&dev->dev, &dev_attr_mode);
+fail1:	device_remove_file(&dev->dev, &dev_attr_physical_device);
+	return error;
+}
+
+void xenvbd_sysfs_delif(struct xenbus_device *dev)
+{
+	sysfs_remove_group(&dev->dev.kobj, &xen_vbdstat_group);
+	device_remove_file(&dev->dev, &dev_attr_mode);
+	device_remove_file(&dev->dev, &dev_attr_physical_device);
+}
+
+
+static void xen_vbd_free(struct xen_vbd *vbd)
+{
+	if (vbd->bdev)
+		blkdev_put(vbd->bdev, vbd->readonly ? FMODE_READ : FMODE_WRITE);
+	vbd->bdev = NULL;
+}
+
+static int xen_vbd_create(struct xen_blkif *blkif, blkif_vdev_t handle,
+			  unsigned major, unsigned minor, int readonly,
+			  int cdrom)
+{
+	struct xen_vbd *vbd;
+	struct block_device *bdev;
+	struct request_queue *q;
+
+	vbd = &blkif->vbd;
+	vbd->handle   = handle;
+	vbd->readonly = readonly;
+	vbd->type     = 0;
+
+	vbd->pdevice  = MKDEV(major, minor);
+
+	bdev = blkdev_get_by_dev(vbd->pdevice, vbd->readonly ?
+				 FMODE_READ : FMODE_WRITE, NULL);
+
+	if (IS_ERR(bdev)) {
+		DPRINTK("xen_vbd_create: device %08x could not be opened.\n",
+			vbd->pdevice);
+		return -ENOENT;
+	}
+
+	vbd->bdev = bdev;
+	if (vbd->bdev->bd_disk == NULL) {
+		DPRINTK("xen_vbd_create: device %08x doesn't exist.\n",
+			vbd->pdevice);
+		xen_vbd_free(vbd);
+		return -ENOENT;
+	}
+	vbd->size = vbd_sz(vbd);
+
+	if (vbd->bdev->bd_disk->flags & GENHD_FL_CD || cdrom)
+		vbd->type |= VDISK_CDROM;
+	if (vbd->bdev->bd_disk->flags & GENHD_FL_REMOVABLE)
+		vbd->type |= VDISK_REMOVABLE;
+
+	q = bdev_get_queue(bdev);
+	if (q && q->flush_flags)
+		vbd->flush_support = true;
+
+	DPRINTK("Successful creation of handle=%04x (dom=%u)\n",
+		handle, blkif->domid);
+	return 0;
+}
+static int xen_blkbk_remove(struct xenbus_device *dev)
+{
+	struct backend_info *be = dev_get_drvdata(&dev->dev);
+
+	DPRINTK("");
+
+	if (be->major || be->minor)
+		xenvbd_sysfs_delif(dev);
+
+	if (be->backend_watch.node) {
+		unregister_xenbus_watch(&be->backend_watch);
+		kfree(be->backend_watch.node);
+		be->backend_watch.node = NULL;
+	}
+
+	if (be->blkif) {
+		xen_blkif_disconnect(be->blkif);
+		xen_vbd_free(&be->blkif->vbd);
+		xen_blkif_free(be->blkif);
+		be->blkif = NULL;
+	}
+
+	kfree(be);
+	dev_set_drvdata(&dev->dev, NULL);
+	return 0;
+}
+
+int xen_blkbk_flush_diskcache(struct xenbus_transaction xbt,
+			      struct backend_info *be, int state)
+{
+	struct xenbus_device *dev = be->dev;
+	int err;
+
+	err = xenbus_printf(xbt, dev->nodename, "feature-flush-cache",
+			    "%d", state);
+	if (err)
+		xenbus_dev_fatal(dev, err, "writing feature-flush-cache");
+
+	return err;
+}
+
+/*
+ * Entry point to this code when a new device is created.  Allocate the basic
+ * structures, and watch the store waiting for the hotplug scripts to tell us
+ * the device's physical major and minor numbers.  Switch to InitWait.
+ */
+static int xen_blkbk_probe(struct xenbus_device *dev,
+			   const struct xenbus_device_id *id)
+{
+	int err;
+	struct backend_info *be = kzalloc(sizeof(struct backend_info),
+					  GFP_KERNEL);
+	if (!be) {
+		xenbus_dev_fatal(dev, -ENOMEM,
+				 "allocating backend structure");
+		return -ENOMEM;
+	}
+	be->dev = dev;
+	dev_set_drvdata(&dev->dev, be);
+
+	be->blkif = xen_blkif_alloc(dev->otherend_id);
+	if (IS_ERR(be->blkif)) {
+		err = PTR_ERR(be->blkif);
+		be->blkif = NULL;
+		xenbus_dev_fatal(dev, err, "creating block interface");
+		goto fail;
+	}
+
+	/* setup back pointer */
+	be->blkif->be = be;
+
+	err = xenbus_watch_pathfmt(dev, &be->backend_watch, backend_changed,
+				   "%s/%s", dev->nodename, "physical-device");
+	if (err)
+		goto fail;
+
+	err = xenbus_switch_state(dev, XenbusStateInitWait);
+	if (err)
+		goto fail;
+
+	return 0;
+
+fail:
+	DPRINTK("failed");
+	xen_blkbk_remove(dev);
+	return err;
+}
+
+
+/*
+ * Callback received when the hotplug scripts have placed the physical-device
+ * node.  Read it and the mode node, and create a vbd.  If the frontend is
+ * ready, connect.
+ */
+static void backend_changed(struct xenbus_watch *watch,
+			    const char **vec, unsigned int len)
+{
+	int err;
+	unsigned major;
+	unsigned minor;
+	struct backend_info *be
+		= container_of(watch, struct backend_info, backend_watch);
+	struct xenbus_device *dev = be->dev;
+	int cdrom = 0;
+	char *device_type;
+
+	DPRINTK("");
+
+	err = xenbus_scanf(XBT_NIL, dev->nodename, "physical-device", "%x:%x",
+			   &major, &minor);
+	if (XENBUS_EXIST_ERR(err)) {
+		/*
+		 * Since this watch will fire once immediately after it is
+		 * registered, we expect this.  Ignore it, and wait for the
+		 * hotplug scripts.
+		 */
+		return;
+	}
+	if (err != 2) {
+		xenbus_dev_fatal(dev, err, "reading physical-device");
+		return;
+	}
+
+	if ((be->major || be->minor) &&
+	    ((be->major != major) || (be->minor != minor))) {
+		pr_warn(DRV_PFX "changing physical device (from %x:%x to %x:%x) not supported.\n",
+			be->major, be->minor, major, minor);
+		return;
+	}
+
+	be->mode = xenbus_read(XBT_NIL, dev->nodename, "mode", NULL);
+	if (IS_ERR(be->mode)) {
+		err = PTR_ERR(be->mode);
+		be->mode = NULL;
+		xenbus_dev_fatal(dev, err, "reading mode");
+		return;
+	}
+
+	device_type = xenbus_read(XBT_NIL, dev->otherend, "device-type", NULL);
+	if (!IS_ERR(device_type)) {
+		cdrom = strcmp(device_type, "cdrom") == 0;
+		kfree(device_type);
+	}
+
+	if (be->major == 0 && be->minor == 0) {
+		/* Front end dir is a number, which is used as the handle. */
+
+		char *p = strrchr(dev->otherend, '/') + 1;
+		long handle;
+		err = strict_strtoul(p, 0, &handle);
+		if (err)
+			return;
+
+		be->major = major;
+		be->minor = minor;
+
+		err = xen_vbd_create(be->blkif, handle, major, minor,
+				 (NULL == strchr(be->mode, 'w')), cdrom);
+		if (err) {
+			be->major = 0;
+			be->minor = 0;
+			xenbus_dev_fatal(dev, err, "creating vbd structure");
+			return;
+		}
+
+		err = xenvbd_sysfs_addif(dev);
+		if (err) {
+			xen_vbd_free(&be->blkif->vbd);
+			be->major = 0;
+			be->minor = 0;
+			xenbus_dev_fatal(dev, err, "creating sysfs entries");
+			return;
+		}
+
+		/* We're potentially connected now */
+		xen_update_blkif_status(be->blkif);
+	}
+}
+
+
+/*
+ * Callback received when the frontend's state changes.
+ */
+static void frontend_changed(struct xenbus_device *dev,
+			     enum xenbus_state frontend_state)
+{
+	struct backend_info *be = dev_get_drvdata(&dev->dev);
+	int err;
+
+	DPRINTK("%s", xenbus_strstate(frontend_state));
+
+	switch (frontend_state) {
+	case XenbusStateInitialising:
+		if (dev->state == XenbusStateClosed) {
+			pr_info(DRV_PFX "%s: prepare for reconnect\n",
+				dev->nodename);
+			xenbus_switch_state(dev, XenbusStateInitWait);
+		}
+		break;
+
+	case XenbusStateInitialised:
+	case XenbusStateConnected:
+		/*
+		 * Ensure we connect even when two watches fire in
+		 * close successsion and we miss the intermediate value
+		 * of frontend_state.
+		 */
+		if (dev->state == XenbusStateConnected)
+			break;
+
+		/*
+		 * Enforce precondition before potential leak point.
+		 * blkif_disconnect() is idempotent.
+		 */
+		xen_blkif_disconnect(be->blkif);
+
+		err = connect_ring(be);
+		if (err)
+			break;
+		xen_update_blkif_status(be->blkif);
+		break;
+
+	case XenbusStateClosing:
+		xen_blkif_disconnect(be->blkif);
+		xenbus_switch_state(dev, XenbusStateClosing);
+		break;
+
+	case XenbusStateClosed:
+		xenbus_switch_state(dev, XenbusStateClosed);
+		if (xenbus_dev_is_online(dev))
+			break;
+		/* fall through if not online */
+	case XenbusStateUnknown:
+		/* implies blkif_disconnect() via blkback_remove() */
+		device_unregister(&dev->dev);
+		break;
+
+	default:
+		xenbus_dev_fatal(dev, -EINVAL, "saw state %d at frontend",
+				 frontend_state);
+		break;
+	}
+}
+
+
+/* ** Connection ** */
+
+
+/*
+ * Write the physical details regarding the block device to the store, and
+ * switch to Connected state.
+ */
+static void connect(struct backend_info *be)
+{
+	struct xenbus_transaction xbt;
+	int err;
+	struct xenbus_device *dev = be->dev;
+
+	DPRINTK("%s", dev->otherend);
+
+	/* Supply the information about the device the frontend needs */
+again:
+	err = xenbus_transaction_start(&xbt);
+	if (err) {
+		xenbus_dev_fatal(dev, err, "starting transaction");
+		return;
+	}
+
+	err = xen_blkbk_flush_diskcache(xbt, be, be->blkif->vbd.flush_support);
+	if (err)
+		goto abort;
+
+	err = xenbus_printf(xbt, dev->nodename, "sectors", "%llu",
+			    (unsigned long long)vbd_sz(&be->blkif->vbd));
+	if (err) {
+		xenbus_dev_fatal(dev, err, "writing %s/sectors",
+				 dev->nodename);
+		goto abort;
+	}
+
+	/* FIXME: use a typename instead */
+	err = xenbus_printf(xbt, dev->nodename, "info", "%u",
+			    be->blkif->vbd.type |
+			    (be->blkif->vbd.readonly ? VDISK_READONLY : 0));
+	if (err) {
+		xenbus_dev_fatal(dev, err, "writing %s/info",
+				 dev->nodename);
+		goto abort;
+	}
+	err = xenbus_printf(xbt, dev->nodename, "sector-size", "%lu",
+			    (unsigned long)
+			    bdev_logical_block_size(be->blkif->vbd.bdev));
+	if (err) {
+		xenbus_dev_fatal(dev, err, "writing %s/sector-size",
+				 dev->nodename);
+		goto abort;
+	}
+
+	err = xenbus_transaction_end(xbt, 0);
+	if (err == -EAGAIN)
+		goto again;
+	if (err)
+		xenbus_dev_fatal(dev, err, "ending transaction");
+
+	err = xenbus_switch_state(dev, XenbusStateConnected);
+	if (err)
+		xenbus_dev_fatal(dev, err, "switching to Connected state",
+				 dev->nodename);
+
+	return;
+ abort:
+	xenbus_transaction_end(xbt, 1);
+}
+
+
+static int connect_ring(struct backend_info *be)
+{
+	struct xenbus_device *dev = be->dev;
+	unsigned long ring_ref;
+	unsigned int evtchn;
+	char protocol[64] = "";
+	int err;
+
+	DPRINTK("%s", dev->otherend);
+
+	err = xenbus_gather(XBT_NIL, dev->otherend, "ring-ref", "%lu",
+			    &ring_ref, "event-channel", "%u", &evtchn, NULL);
+	if (err) {
+		xenbus_dev_fatal(dev, err,
+				 "reading %s/ring-ref and event-channel",
+				 dev->otherend);
+		return err;
+	}
+
+	be->blkif->blk_protocol = BLKIF_PROTOCOL_NATIVE;
+	err = xenbus_gather(XBT_NIL, dev->otherend, "protocol",
+			    "%63s", protocol, NULL);
+	if (err)
+		strcpy(protocol, "unspecified, assuming native");
+	else if (0 == strcmp(protocol, XEN_IO_PROTO_ABI_NATIVE))
+		be->blkif->blk_protocol = BLKIF_PROTOCOL_NATIVE;
+	else if (0 == strcmp(protocol, XEN_IO_PROTO_ABI_X86_32))
+		be->blkif->blk_protocol = BLKIF_PROTOCOL_X86_32;
+	else if (0 == strcmp(protocol, XEN_IO_PROTO_ABI_X86_64))
+		be->blkif->blk_protocol = BLKIF_PROTOCOL_X86_64;
+	else {
+		xenbus_dev_fatal(dev, err, "unknown fe protocol %s", protocol);
+		return -1;
+	}
+	pr_info(DRV_PFX "ring-ref %ld, event-channel %d, protocol %d (%s)\n",
+		ring_ref, evtchn, be->blkif->blk_protocol, protocol);
+
+	/* Map the shared frame, irq etc. */
+	err = xen_blkif_map(be->blkif, ring_ref, evtchn);
+	if (err) {
+		xenbus_dev_fatal(dev, err, "mapping ring-ref %lu port %u",
+				 ring_ref, evtchn);
+		return err;
+	}
+
+	return 0;
+}
+
+
+/* ** Driver Registration ** */
+
+
+static const struct xenbus_device_id xen_blkbk_ids[] = {
+	{ "vbd" },
+	{ "" }
+};
+
+
+static struct xenbus_driver xen_blkbk = {
+	.name = "vbd",
+	.owner = THIS_MODULE,
+	.ids = xen_blkbk_ids,
+	.probe = xen_blkbk_probe,
+	.remove = xen_blkbk_remove,
+	.otherend_changed = frontend_changed
+};
+
+
+int xen_blkif_xenbus_init(void)
+{
+	return xenbus_register_backend(&xen_blkbk);
+}
diff -druN linux-2.6.39-libre/drivers/block/xen-blkfront.c linux-3.0-rc7-libre/drivers/block/xen-blkfront.c
--- linux-2.6.39-libre/drivers/block/xen-blkfront.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/block/xen-blkfront.c	2011-07-11 19:51:52.000000000 -0400
@@ -97,6 +97,7 @@
 	struct blk_shadow shadow[BLK_RING_SIZE];
 	unsigned long shadow_free;
 	unsigned int feature_flush;
+	unsigned int flush_op;
 	int is_ready;
 };
 
@@ -250,8 +251,7 @@
 
 /*
  * Generate a Xen blkfront IO request from a blk layer request.  Reads
- * and writes are handled as expected.  Since we lack a loose flush
- * request, we map flushes into a full ordered barrier.
+ * and writes are handled as expected.
  *
  * @req: a request struct
  */
@@ -293,14 +293,13 @@
 
 	if (req->cmd_flags & (REQ_FLUSH | REQ_FUA)) {
 		/*
-		 * Ideally we could just do an unordered
-		 * flush-to-disk, but all we have is a full write
-		 * barrier at the moment.  However, a barrier write is
+		 * Ideally we can do an unordered flush-to-disk. In case the
+		 * backend onlysupports barriers, use that. A barrier request
 		 * a superset of FUA, so we can implement it the same
 		 * way.  (It's also a FLUSH+FUA, since it is
 		 * guaranteed ordered WRT previous writes.)
 		 */
-		ring_req->operation = BLKIF_OP_WRITE_BARRIER;
+		ring_req->operation = info->flush_op;
 	}
 
 	ring_req->nr_segments = blk_rq_map_sg(req->q, req, info->sg);
@@ -433,8 +432,11 @@
 static void xlvbd_flush(struct blkfront_info *info)
 {
 	blk_queue_flush(info->rq, info->feature_flush);
-	printk(KERN_INFO "blkfront: %s: barriers %s\n",
+	printk(KERN_INFO "blkfront: %s: %s: %s\n",
 	       info->gd->disk_name,
+	       info->flush_op == BLKIF_OP_WRITE_BARRIER ?
+		"barrier" : (info->flush_op == BLKIF_OP_FLUSH_DISKCACHE ?
+		"flush diskcache" : "barrier or flush"),
 	       info->feature_flush ? "enabled" : "disabled");
 }
 
@@ -720,15 +722,20 @@
 
 		error = (bret->status == BLKIF_RSP_OKAY) ? 0 : -EIO;
 		switch (bret->operation) {
+		case BLKIF_OP_FLUSH_DISKCACHE:
 		case BLKIF_OP_WRITE_BARRIER:
 			if (unlikely(bret->status == BLKIF_RSP_EOPNOTSUPP)) {
-				printk(KERN_WARNING "blkfront: %s: write barrier op failed\n",
+				printk(KERN_WARNING "blkfront: %s: write %s op failed\n",
+				       info->flush_op == BLKIF_OP_WRITE_BARRIER ?
+				       "barrier" :  "flush disk cache",
 				       info->gd->disk_name);
 				error = -EOPNOTSUPP;
 			}
 			if (unlikely(bret->status == BLKIF_RSP_ERROR &&
 				     info->shadow[id].req.nr_segments == 0)) {
-				printk(KERN_WARNING "blkfront: %s: empty write barrier op failed\n",
+				printk(KERN_WARNING "blkfront: %s: empty write %s op failed\n",
+				       info->flush_op == BLKIF_OP_WRITE_BARRIER ?
+				       "barrier" :  "flush disk cache",
 				       info->gd->disk_name);
 				error = -EOPNOTSUPP;
 			}
@@ -736,6 +743,7 @@
 				if (error == -EOPNOTSUPP)
 					error = 0;
 				info->feature_flush = 0;
+				info->flush_op = 0;
 				xlvbd_flush(info);
 			}
 			/* fall through */
@@ -1100,7 +1108,7 @@
 	unsigned long sector_size;
 	unsigned int binfo;
 	int err;
-	int barrier;
+	int barrier, flush;
 
 	switch (info->connected) {
 	case BLKIF_STATE_CONNECTED:
@@ -1140,8 +1148,11 @@
 		return;
 	}
 
+	info->feature_flush = 0;
+	info->flush_op = 0;
+
 	err = xenbus_gather(XBT_NIL, info->xbdev->otherend,
-			    "feature-barrier", "%lu", &barrier,
+			    "feature-barrier", "%d", &barrier,
 			    NULL);
 
 	/*
@@ -1151,11 +1162,23 @@
 	 *
 	 * If there are barriers, then we use flush.
 	 */
-	info->feature_flush = 0;
-
-	if (!err && barrier)
+	if (!err && barrier) {
 		info->feature_flush = REQ_FLUSH | REQ_FUA;
+		info->flush_op = BLKIF_OP_WRITE_BARRIER;
+	}
+	/*
+	 * And if there is "feature-flush-cache" use that above
+	 * barriers.
+	 */
+	err = xenbus_gather(XBT_NIL, info->xbdev->otherend,
+			    "feature-flush-cache", "%d", &flush,
+			    NULL);
 
+	if (!err && flush) {
+		info->feature_flush = REQ_FLUSH;
+		info->flush_op = BLKIF_OP_FLUSH_DISKCACHE;
+	}
+		
 	err = xlvbd_alloc_gendisk(sectors, info, binfo, sector_size);
 	if (err) {
 		xenbus_dev_fatal(info->xbdev, err, "xlvbd_add at %s",
diff -druN linux-2.6.39-libre/drivers/bluetooth/ath3k.c linux-3.0-rc7-libre/drivers/bluetooth/ath3k.c
--- linux-2.6.39-libre/drivers/bluetooth/ath3k.c	2011-05-19 02:16:29.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/bluetooth/ath3k.c	2011-07-21 06:58:33.000000000 -0400
@@ -62,6 +62,7 @@
 
 	/* Atheros AR3011 with sflash firmware*/
 	{ USB_DEVICE(0x0CF3, 0x3002) },
+	{ USB_DEVICE(0x13d3, 0x3304) },
 
 	/* Atheros AR9285 Malbec with sflash firmware */
 	{ USB_DEVICE(0x03F0, 0x311D) },
@@ -138,9 +139,6 @@
 		count -= size;
 	}
 
-	kfree(send_buf);
-	return 0;
-
 error:
 	kfree(send_buf);
 	return err;
diff -druN linux-2.6.39-libre/drivers/bluetooth/bluecard_cs.c linux-3.0-rc7-libre/drivers/bluetooth/bluecard_cs.c
--- linux-2.6.39-libre/drivers/bluetooth/bluecard_cs.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/bluetooth/bluecard_cs.c	2011-07-11 19:51:52.000000000 -0400
@@ -930,7 +930,7 @@
 	pcmcia_disable_device(link);
 }
 
-static struct pcmcia_device_id bluecard_ids[] = {
+static const struct pcmcia_device_id bluecard_ids[] = {
 	PCMCIA_DEVICE_PROD_ID12("BlueCard", "LSE041", 0xbaf16fbf, 0x657cc15e),
 	PCMCIA_DEVICE_PROD_ID12("BTCFCARD", "LSE139", 0xe3987764, 0x2524b59c),
 	PCMCIA_DEVICE_PROD_ID12("WSS", "LSE039", 0x0a0736ec, 0x24e6dfab),
diff -druN linux-2.6.39-libre/drivers/bluetooth/bt3c_cs.c linux-3.0-rc7-libre/drivers/bluetooth/bt3c_cs.c
--- linux-2.6.39-libre/drivers/bluetooth/bt3c_cs.c	2011-05-19 02:16:36.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/bluetooth/bt3c_cs.c	2011-07-21 06:58:39.000000000 -0400
@@ -761,7 +761,7 @@
 }
 
 
-static struct pcmcia_device_id bt3c_ids[] = {
+static const struct pcmcia_device_id bt3c_ids[] = {
 	PCMCIA_DEVICE_PROD_ID13("3COM", "Bluetooth PC Card", 0xefce0a31, 0xd4ce9b02),
 	PCMCIA_DEVICE_NULL
 };
diff -druN linux-2.6.39-libre/drivers/bluetooth/btmrvl_debugfs.c linux-3.0-rc7-libre/drivers/bluetooth/btmrvl_debugfs.c
--- linux-2.6.39-libre/drivers/bluetooth/btmrvl_debugfs.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/bluetooth/btmrvl_debugfs.c	2011-07-11 19:51:52.000000000 -0400
@@ -64,6 +64,8 @@
 		return -EFAULT;
 
 	ret = strict_strtol(buf, 10, &result);
+	if (ret)
+		return ret;
 
 	priv->btmrvl_dev.hscfgcmd = result;
 
@@ -108,6 +110,8 @@
 		return -EFAULT;
 
 	ret = strict_strtol(buf, 10, &result);
+	if (ret)
+		return ret;
 
 	priv->btmrvl_dev.psmode = result;
 
@@ -147,6 +151,8 @@
 		return -EFAULT;
 
 	ret = strict_strtol(buf, 10, &result);
+	if (ret)
+		return ret;
 
 	priv->btmrvl_dev.pscmd = result;
 
@@ -191,6 +197,8 @@
 		return -EFAULT;
 
 	ret = strict_strtol(buf, 16, &result);
+	if (ret)
+		return ret;
 
 	priv->btmrvl_dev.gpio_gap = result;
 
@@ -230,6 +238,8 @@
 		return -EFAULT;
 
 	ret = strict_strtol(buf, 10, &result);
+	if (ret)
+		return ret;
 
 	priv->btmrvl_dev.hscmd = result;
 	if (priv->btmrvl_dev.hscmd) {
@@ -272,6 +282,8 @@
 		return -EFAULT;
 
 	ret = strict_strtol(buf, 10, &result);
+	if (ret)
+		return ret;
 
 	priv->btmrvl_dev.hsmode = result;
 
diff -druN linux-2.6.39-libre/drivers/bluetooth/btmrvl_sdio.c linux-3.0-rc7-libre/drivers/bluetooth/btmrvl_sdio.c
--- linux-2.6.39-libre/drivers/bluetooth/btmrvl_sdio.c	2011-05-19 02:16:39.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/bluetooth/btmrvl_sdio.c	2011-07-21 06:58:41.000000000 -0400
@@ -49,14 +49,58 @@
 static u8 user_rmmod;
 static u8 sdio_ireg;
 
+static const struct btmrvl_sdio_card_reg btmrvl_reg_8688 = {
+	.cfg = 0x03,
+	.host_int_mask = 0x04,
+	.host_intstatus = 0x05,
+	.card_status = 0x20,
+	.sq_read_base_addr_a0 = 0x10,
+	.sq_read_base_addr_a1 = 0x11,
+	.card_fw_status0 = 0x40,
+	.card_fw_status1 = 0x41,
+	.card_rx_len = 0x42,
+	.card_rx_unit = 0x43,
+	.io_port_0 = 0x00,
+	.io_port_1 = 0x01,
+	.io_port_2 = 0x02,
+};
+static const struct btmrvl_sdio_card_reg btmrvl_reg_8787 = {
+	.cfg = 0x00,
+	.host_int_mask = 0x02,
+	.host_intstatus = 0x03,
+	.card_status = 0x30,
+	.sq_read_base_addr_a0 = 0x40,
+	.sq_read_base_addr_a1 = 0x41,
+	.card_revision = 0x5c,
+	.card_fw_status0 = 0x60,
+	.card_fw_status1 = 0x61,
+	.card_rx_len = 0x62,
+	.card_rx_unit = 0x63,
+	.io_port_0 = 0x78,
+	.io_port_1 = 0x79,
+	.io_port_2 = 0x7a,
+};
+
 static const struct btmrvl_sdio_device btmrvl_sdio_sd6888 = {
 	.helper		= "/*(DEBLOBBED)*/",
+	.reg		= &btmrvl_reg_8688,
+	.sd_blksz_fw_dl	= 64,
+};
+
+static const struct btmrvl_sdio_device btmrvl_sdio_sd8787 = {
+	.helper		= NULL,
+	.firmware	= "/*(DEBLOBBED)*/",
+	.reg		= &btmrvl_reg_8787,
+	.sd_blksz_fw_dl	= 256,
 };
 
 static const struct sdio_device_id btmrvl_sdio_ids[] = {
 	/* Marvell SD8688 Bluetooth device */
 	{ SDIO_DEVICE(SDIO_VENDOR_ID_MARVELL, 0x9105),
 			.driver_data = (unsigned long) &btmrvl_sdio_sd6888 },
+	/* Marvell SD8787 Bluetooth device */
+	{ SDIO_DEVICE(SDIO_VENDOR_ID_MARVELL, 0x911A),
+			.driver_data = (unsigned long) &btmrvl_sdio_sd8787 },
 
 	{ }	/* Terminating entry */
 };
@@ -68,7 +112,7 @@
 	u8 reg;
 	int ret;
 
-	reg = sdio_readb(card->func, CARD_RX_UNIT_REG, &ret);
+	reg = sdio_readb(card->func, card->reg->card_rx_unit, &ret);
 	if (!ret)
 		card->rx_unit = reg;
 
@@ -82,11 +126,11 @@
 
 	*dat = 0;
 
-	fws0 = sdio_readb(card->func, CARD_FW_STATUS0_REG, &ret);
+	fws0 = sdio_readb(card->func, card->reg->card_fw_status0, &ret);
 	if (ret)
 		return -EIO;
 
-	fws1 = sdio_readb(card->func, CARD_FW_STATUS1_REG, &ret);
+	fws1 = sdio_readb(card->func, card->reg->card_fw_status1, &ret);
 	if (ret)
 		return -EIO;
 
@@ -100,7 +144,7 @@
 	u8 reg;
 	int ret;
 
-	reg = sdio_readb(card->func, CARD_RX_LEN_REG, &ret);
+	reg = sdio_readb(card->func, card->reg->card_rx_len, &ret);
 	if (!ret)
 		*dat = (u16) reg << card->rx_unit;
 
@@ -112,7 +156,7 @@
 {
 	int ret;
 
-	sdio_writeb(card->func, mask, HOST_INT_MASK_REG, &ret);
+	sdio_writeb(card->func, mask, card->reg->host_int_mask, &ret);
 	if (ret) {
 		BT_ERR("Unable to enable the host interrupt!");
 		ret = -EIO;
@@ -127,13 +171,13 @@
 	u8 host_int_mask;
 	int ret;
 
-	host_int_mask = sdio_readb(card->func, HOST_INT_MASK_REG, &ret);
+	host_int_mask = sdio_readb(card->func, card->reg->host_int_mask, &ret);
 	if (ret)
 		return -EIO;
 
 	host_int_mask &= ~mask;
 
-	sdio_writeb(card->func, host_int_mask, HOST_INT_MASK_REG, &ret);
+	sdio_writeb(card->func, host_int_mask, card->reg->host_int_mask, &ret);
 	if (ret < 0) {
 		BT_ERR("Unable to disable the host interrupt!");
 		return -EIO;
@@ -149,7 +193,7 @@
 	int ret;
 
 	for (tries = 0; tries < MAX_POLL_TRIES * 1000; tries++) {
-		status = sdio_readb(card->func, CARD_STATUS_REG, &ret);
+		status = sdio_readb(card->func, card->reg->card_status,	&ret);
 		if (ret)
 			goto failed;
 		if ((status & bits) == bits)
@@ -298,7 +342,7 @@
 	u8 base0, base1;
 	void *tmpfwbuf = NULL;
 	u8 *fwbuf;
-	u16 len;
+	u16 len, blksz_dl = card->sd_blksz_fw_dl;
 	int txlen = 0, tx_blocks = 0, count = 0;
 
 	ret = reject_firmware(&fw_firmware, card->firmware,
@@ -344,7 +388,7 @@
 
 		for (tries = 0; tries < MAX_POLL_TRIES; tries++) {
 			base0 = sdio_readb(card->func,
-					SQ_READ_BASE_ADDRESS_A0_REG, &ret);
+					card->reg->sq_read_base_addr_a0, &ret);
 			if (ret) {
 				BT_ERR("BASE0 register read failed:"
 					" base0 = 0x%04X(%d)."
@@ -354,7 +398,7 @@
 				goto done;
 			}
 			base1 = sdio_readb(card->func,
-					SQ_READ_BASE_ADDRESS_A1_REG, &ret);
+					card->reg->sq_read_base_addr_a1, &ret);
 			if (ret) {
 				BT_ERR("BASE1 register read failed:"
 					" base1 = 0x%04X(%d)."
@@ -402,20 +446,19 @@
 			if (firmwarelen - offset < txlen)
 				txlen = firmwarelen - offset;
 
-			tx_blocks =
-			    (txlen + SDIO_BLOCK_SIZE - 1) / SDIO_BLOCK_SIZE;
+			tx_blocks = (txlen + blksz_dl - 1) / blksz_dl;
 
 			memcpy(fwbuf, &firmware[offset], txlen);
 		}
 
 		ret = sdio_writesb(card->func, card->ioport, fwbuf,
-					tx_blocks * SDIO_BLOCK_SIZE);
+						tx_blocks * blksz_dl);
 
 		if (ret < 0) {
 			BT_ERR("FW download, writesb(%d) failed @%d",
 							count, offset);
-			sdio_writeb(card->func, HOST_CMD53_FIN, CONFIG_REG,
-									&ret);
+			sdio_writeb(card->func, HOST_CMD53_FIN,
+						card->reg->cfg, &ret);
 			if (ret)
 				BT_ERR("writeb failed (CFG)");
 		}
@@ -596,7 +639,7 @@
 
 	priv = card->priv;
 
-	ireg = sdio_readb(card->func, HOST_INTSTATUS_REG, &ret);
+	ireg = sdio_readb(card->func, card->reg->host_intstatus, &ret);
 	if (ret) {
 		BT_ERR("sdio_readb: read int status register failed");
 		return;
@@ -612,7 +655,7 @@
 
 		sdio_writeb(card->func, ~(ireg) & (DN_LD_HOST_INT_STATUS |
 					UP_LD_HOST_INT_STATUS),
-				HOST_INTSTATUS_REG, &ret);
+				card->reg->host_intstatus, &ret);
 		if (ret) {
 			BT_ERR("sdio_writeb: clear int status register failed");
 			return;
@@ -663,7 +706,7 @@
 		goto release_irq;
 	}
 
-	reg = sdio_readb(func, IO_PORT_0_REG, &ret);
+	reg = sdio_readb(func, card->reg->io_port_0, &ret);
 	if (ret < 0) {
 		ret = -EIO;
 		goto release_irq;
@@ -671,7 +714,7 @@
 
 	card->ioport = reg;
 
-	reg = sdio_readb(func, IO_PORT_1_REG, &ret);
+	reg = sdio_readb(func, card->reg->io_port_1, &ret);
 	if (ret < 0) {
 		ret = -EIO;
 		goto release_irq;
@@ -679,7 +722,7 @@
 
 	card->ioport |= (reg << 8);
 
-	reg = sdio_readb(func, IO_PORT_2_REG, &ret);
+	reg = sdio_readb(func, card->reg->io_port_2, &ret);
 	if (ret < 0) {
 		ret = -EIO;
 		goto release_irq;
@@ -814,6 +857,8 @@
 static int btmrvl_sdio_download_fw(struct btmrvl_sdio_card *card)
 {
 	int ret = 0;
+	u8 fws0;
+	int pollnum = MAX_POLL_TRIES;
 
 	if (!card || !card->func) {
 		BT_ERR("card or function is NULL!");
@@ -826,20 +871,36 @@
 		goto done;
 	}
 
-	ret = btmrvl_sdio_download_helper(card);
+	/* Check if other function driver is downloading the firmware */
+	fws0 = sdio_readb(card->func, card->reg->card_fw_status0, &ret);
 	if (ret) {
-		BT_ERR("Failed to download helper!");
+		BT_ERR("Failed to read FW downloading status!");
 		ret = -EIO;
 		goto done;
 	}
+	if (fws0) {
+		BT_DBG("BT not the winner (%#x). Skip FW downloading", fws0);
 
-	if (btmrvl_sdio_download_fw_w_helper(card)) {
-		BT_ERR("Failed to download firmware!");
-		ret = -EIO;
-		goto done;
+		/* Give other function more time to download the firmware */
+		pollnum *= 10;
+	} else {
+		if (card->helper) {
+			ret = btmrvl_sdio_download_helper(card);
+			if (ret) {
+				BT_ERR("Failed to download helper!");
+				ret = -EIO;
+				goto done;
+			}
+		}
+
+		if (btmrvl_sdio_download_fw_w_helper(card)) {
+			BT_ERR("Failed to download firmware!");
+			ret = -EIO;
+			goto done;
+		}
 	}
 
-	if (btmrvl_sdio_verify_fw_download(card, MAX_POLL_TRIES)) {
+	if (btmrvl_sdio_verify_fw_download(card, pollnum)) {
 		BT_ERR("FW failed to be active in time!");
 		ret = -ETIMEDOUT;
 		goto done;
@@ -863,7 +924,7 @@
 
 	sdio_claim_host(card->func);
 
-	sdio_writeb(card->func, HOST_POWER_UP, CONFIG_REG, &ret);
+	sdio_writeb(card->func, HOST_POWER_UP, card->reg->cfg, &ret);
 
 	sdio_release_host(card->func);
 
@@ -892,8 +953,10 @@
 
 	if (id->driver_data) {
 		struct btmrvl_sdio_device *data = (void *) id->driver_data;
-		card->helper   = data->helper;
+		card->helper = data->helper;
 		card->firmware = data->firmware;
+		card->reg = data->reg;
+		card->sd_blksz_fw_dl = data->sd_blksz_fw_dl;
 	}
 
 	if (btmrvl_sdio_register_dev(card) < 0) {
diff -druN linux-2.6.39-libre/drivers/bluetooth/btmrvl_sdio.h linux-3.0-rc7-libre/drivers/bluetooth/btmrvl_sdio.h
--- linux-2.6.39-libre/drivers/bluetooth/btmrvl_sdio.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/bluetooth/btmrvl_sdio.h	2011-07-11 19:51:52.000000000 -0400
@@ -47,44 +47,46 @@
 /* Max retry number of CMD53 write */
 #define MAX_WRITE_IOMEM_RETRY		2
 
-/* Host Control Registers */
-#define IO_PORT_0_REG			0x00
-#define IO_PORT_1_REG			0x01
-#define IO_PORT_2_REG			0x02
-
-#define CONFIG_REG			0x03
-#define HOST_POWER_UP			BIT(1)
-#define HOST_CMD53_FIN			BIT(2)
-
-#define HOST_INT_MASK_REG		0x04
-#define HIM_DISABLE			0xff
-#define HIM_ENABLE			(BIT(0) | BIT(1))
+/* register bitmasks */
+#define HOST_POWER_UP				BIT(1)
+#define HOST_CMD53_FIN				BIT(2)
 
-#define HOST_INTSTATUS_REG		0x05
-#define UP_LD_HOST_INT_STATUS		BIT(0)
-#define DN_LD_HOST_INT_STATUS		BIT(1)
+#define HIM_DISABLE				0xff
+#define HIM_ENABLE				(BIT(0) | BIT(1))
 
-/* Card Control Registers */
-#define SQ_READ_BASE_ADDRESS_A0_REG  	0x10
-#define SQ_READ_BASE_ADDRESS_A1_REG  	0x11
+#define UP_LD_HOST_INT_STATUS			BIT(0)
+#define DN_LD_HOST_INT_STATUS			BIT(1)
 
-#define CARD_STATUS_REG              	0x20
-#define DN_LD_CARD_RDY               	BIT(0)
-#define CARD_IO_READY              	BIT(3)
+#define DN_LD_CARD_RDY				BIT(0)
+#define CARD_IO_READY				BIT(3)
 
-#define CARD_FW_STATUS0_REG		0x40
-#define CARD_FW_STATUS1_REG		0x41
-#define FIRMWARE_READY			0xfedc
+#define FIRMWARE_READY				0xfedc
 
-#define CARD_RX_LEN_REG			0x42
-#define CARD_RX_UNIT_REG		0x43
 
+struct btmrvl_sdio_card_reg {
+	u8 cfg;
+	u8 host_int_mask;
+	u8 host_intstatus;
+	u8 card_status;
+	u8 sq_read_base_addr_a0;
+	u8 sq_read_base_addr_a1;
+	u8 card_revision;
+	u8 card_fw_status0;
+	u8 card_fw_status1;
+	u8 card_rx_len;
+	u8 card_rx_unit;
+	u8 io_port_0;
+	u8 io_port_1;
+	u8 io_port_2;
+};
 
 struct btmrvl_sdio_card {
 	struct sdio_func *func;
 	u32 ioport;
 	const char *helper;
 	const char *firmware;
+	const struct btmrvl_sdio_card_reg *reg;
+	u16 sd_blksz_fw_dl;
 	u8 rx_unit;
 	struct btmrvl_private *priv;
 };
@@ -92,6 +94,8 @@
 struct btmrvl_sdio_device {
 	const char *helper;
 	const char *firmware;
+	const struct btmrvl_sdio_card_reg *reg;
+	u16 sd_blksz_fw_dl;
 };
 
 
diff -druN linux-2.6.39-libre/drivers/bluetooth/btuart_cs.c linux-3.0-rc7-libre/drivers/bluetooth/btuart_cs.c
--- linux-2.6.39-libre/drivers/bluetooth/btuart_cs.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/bluetooth/btuart_cs.c	2011-07-11 19:51:52.000000000 -0400
@@ -689,7 +689,7 @@
 	pcmcia_disable_device(link);
 }
 
-static struct pcmcia_device_id btuart_ids[] = {
+static const struct pcmcia_device_id btuart_ids[] = {
 	/* don't use this driver. Use serial_cs + hci_uart instead */
 	PCMCIA_DEVICE_NULL
 };
diff -druN linux-2.6.39-libre/drivers/bluetooth/btusb.c linux-3.0-rc7-libre/drivers/bluetooth/btusb.c
--- linux-2.6.39-libre/drivers/bluetooth/btusb.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/bluetooth/btusb.c	2011-07-11 19:51:52.000000000 -0400
@@ -104,6 +104,7 @@
 
 	/* Atheros 3011 with sflash firmware */
 	{ USB_DEVICE(0x0cf3, 0x3002), .driver_info = BTUSB_IGNORE },
+	{ USB_DEVICE(0x13d3, 0x3304), .driver_info = BTUSB_IGNORE },
 
 	/* Atheros AR9285 Malbec with sflash firmware */
 	{ USB_DEVICE(0x03f0, 0x311d), .driver_info = BTUSB_IGNORE },
diff -druN linux-2.6.39-libre/drivers/bluetooth/dtl1_cs.c linux-3.0-rc7-libre/drivers/bluetooth/dtl1_cs.c
--- linux-2.6.39-libre/drivers/bluetooth/dtl1_cs.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/bluetooth/dtl1_cs.c	2011-07-11 19:51:52.000000000 -0400
@@ -636,7 +636,7 @@
 }
 
 
-static struct pcmcia_device_id dtl1_ids[] = {
+static const struct pcmcia_device_id dtl1_ids[] = {
 	PCMCIA_DEVICE_PROD_ID12("Nokia Mobile Phones", "DTL-1", 0xe1bfdd64, 0xe168480d),
 	PCMCIA_DEVICE_PROD_ID12("Nokia Mobile Phones", "DTL-4", 0xe1bfdd64, 0x9102bc82),
 	PCMCIA_DEVICE_PROD_ID12("Socket", "CF", 0xb38bcc2e, 0x44ebf863),
diff -druN linux-2.6.39-libre/drivers/bluetooth/hci_ath.c linux-3.0-rc7-libre/drivers/bluetooth/hci_ath.c
--- linux-2.6.39-libre/drivers/bluetooth/hci_ath.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/bluetooth/hci_ath.c	2011-07-11 19:51:52.000000000 -0400
@@ -201,8 +201,13 @@
 /* Recv data */
 static int ath_recv(struct hci_uart *hu, void *data, int count)
 {
-	if (hci_recv_stream_fragment(hu->hdev, data, count) < 0)
+	int ret;
+
+	ret = hci_recv_stream_fragment(hu->hdev, data, count);
+	if (ret < 0) {
 		BT_ERR("Frame Reassembly Failed");
+		return ret;
+	}
 
 	return count;
 }
diff -druN linux-2.6.39-libre/drivers/bluetooth/hci_h4.c linux-3.0-rc7-libre/drivers/bluetooth/hci_h4.c
--- linux-2.6.39-libre/drivers/bluetooth/hci_h4.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/bluetooth/hci_h4.c	2011-07-11 19:51:52.000000000 -0400
@@ -151,8 +151,13 @@
 /* Recv data */
 static int h4_recv(struct hci_uart *hu, void *data, int count)
 {
-	if (hci_recv_stream_fragment(hu->hdev, data, count) < 0)
+	int ret;
+
+	ret = hci_recv_stream_fragment(hu->hdev, data, count);
+	if (ret < 0) {
 		BT_ERR("Frame Reassembly Failed");
+		return ret;
+	}
 
 	return count;
 }
diff -druN linux-2.6.39-libre/drivers/bluetooth/Kconfig linux-3.0-rc7-libre/drivers/bluetooth/Kconfig
--- linux-2.6.39-libre/drivers/bluetooth/Kconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/bluetooth/Kconfig	2011-07-11 19:51:52.000000000 -0400
@@ -188,7 +188,7 @@
 	  The core driver to support Marvell Bluetooth devices.
 
 	  This driver is required if you want to support
-	  Marvell Bluetooth devices, such as 8688.
+	  Marvell Bluetooth devices, such as 8688/8787.
 
 	  Say Y here to compile Marvell Bluetooth driver
 	  into the kernel or say M to compile it as module.
@@ -201,7 +201,7 @@
 	  The driver for Marvell Bluetooth chipsets with SDIO interface.
 
 	  This driver is required if you want to use Marvell Bluetooth
-	  devices with SDIO interface. Currently only SD8688 chipset is
+	  devices with SDIO interface. Currently SD8688/SD8787 chipsets are
 	  supported.
 
 	  Say Y here to compile support for Marvell BT-over-SDIO driver
diff -druN linux-2.6.39-libre/drivers/cdrom/viocd.c linux-3.0-rc7-libre/drivers/cdrom/viocd.c
--- linux-2.6.39-libre/drivers/cdrom/viocd.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/cdrom/viocd.c	2011-07-11 19:51:52.000000000 -0400
@@ -625,7 +625,8 @@
 	blk_queue_max_hw_sectors(q, 4096 / 512);
 	gendisk->queue = q;
 	gendisk->fops = &viocd_fops;
-	gendisk->flags = GENHD_FL_CD|GENHD_FL_REMOVABLE;
+	gendisk->flags = GENHD_FL_CD | GENHD_FL_REMOVABLE |
+			 GENHD_FL_BLOCK_EVENTS_ON_EXCL_WRITE;
 	set_capacity(gendisk, 0);
 	gendisk->private_data = d;
 	d->viocd_disk = gendisk;
diff -druN linux-2.6.39-libre/drivers/char/agp/intel-agp.c linux-3.0-rc7-libre/drivers/char/agp/intel-agp.c
--- linux-2.6.39-libre/drivers/char/agp/intel-agp.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/char/agp/intel-agp.c	2011-07-11 19:51:52.000000000 -0400
@@ -903,6 +903,9 @@
 	ID(PCI_DEVICE_ID_INTEL_SANDYBRIDGE_HB),
 	ID(PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_HB),
 	ID(PCI_DEVICE_ID_INTEL_SANDYBRIDGE_S_HB),
+	ID(PCI_DEVICE_ID_INTEL_IVYBRIDGE_HB),
+	ID(PCI_DEVICE_ID_INTEL_IVYBRIDGE_M_HB),
+	ID(PCI_DEVICE_ID_INTEL_IVYBRIDGE_S_HB),
 	{ }
 };
 
diff -druN linux-2.6.39-libre/drivers/char/agp/intel-agp.h linux-3.0-rc7-libre/drivers/char/agp/intel-agp.h
--- linux-2.6.39-libre/drivers/char/agp/intel-agp.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/char/agp/intel-agp.h	2011-07-11 19:51:52.000000000 -0400
@@ -225,6 +225,14 @@
 #define PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_GT2_PLUS_IG	0x0126
 #define PCI_DEVICE_ID_INTEL_SANDYBRIDGE_S_HB		0x0108  /* Server */
 #define PCI_DEVICE_ID_INTEL_SANDYBRIDGE_S_IG		0x010A
+#define PCI_DEVICE_ID_INTEL_IVYBRIDGE_HB		0x0150  /* Desktop */
+#define PCI_DEVICE_ID_INTEL_IVYBRIDGE_GT1_IG		0x0152
+#define PCI_DEVICE_ID_INTEL_IVYBRIDGE_GT2_IG		0x0162
+#define PCI_DEVICE_ID_INTEL_IVYBRIDGE_M_HB		0x0154  /* Mobile */
+#define PCI_DEVICE_ID_INTEL_IVYBRIDGE_M_GT1_IG		0x0156
+#define PCI_DEVICE_ID_INTEL_IVYBRIDGE_M_GT2_IG		0x0166
+#define PCI_DEVICE_ID_INTEL_IVYBRIDGE_S_HB		0x0158  /* Server */
+#define PCI_DEVICE_ID_INTEL_IVYBRIDGE_S_GT1_IG		0x015A
 
 int intel_gmch_probe(struct pci_dev *pdev,
 			       struct agp_bridge_data *bridge);
diff -druN linux-2.6.39-libre/drivers/char/agp/intel-gtt.c linux-3.0-rc7-libre/drivers/char/agp/intel-gtt.c
--- linux-2.6.39-libre/drivers/char/agp/intel-gtt.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/char/agp/intel-gtt.c	2011-07-11 19:51:52.000000000 -0400
@@ -1420,6 +1420,16 @@
 	    "Sandybridge", &sandybridge_gtt_driver },
 	{ PCI_DEVICE_ID_INTEL_SANDYBRIDGE_S_IG,
 	    "Sandybridge", &sandybridge_gtt_driver },
+	{ PCI_DEVICE_ID_INTEL_IVYBRIDGE_GT1_IG,
+	    "Ivybridge", &sandybridge_gtt_driver },
+	{ PCI_DEVICE_ID_INTEL_IVYBRIDGE_GT2_IG,
+	    "Ivybridge", &sandybridge_gtt_driver },
+	{ PCI_DEVICE_ID_INTEL_IVYBRIDGE_M_GT1_IG,
+	    "Ivybridge", &sandybridge_gtt_driver },
+	{ PCI_DEVICE_ID_INTEL_IVYBRIDGE_M_GT2_IG,
+	    "Ivybridge", &sandybridge_gtt_driver },
+	{ PCI_DEVICE_ID_INTEL_IVYBRIDGE_S_GT1_IG,
+	    "Ivybridge", &sandybridge_gtt_driver },
 	{ 0, NULL, NULL }
 };
 
diff -druN linux-2.6.39-libre/drivers/char/agp/uninorth-agp.c linux-3.0-rc7-libre/drivers/char/agp/uninorth-agp.c
--- linux-2.6.39-libre/drivers/char/agp/uninorth-agp.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/char/agp/uninorth-agp.c	2011-07-11 19:51:52.000000000 -0400
@@ -80,7 +80,7 @@
 			       ctrl | UNI_N_CFG_GART_INVAL);
 	pci_write_config_dword(agp_bridge->dev, UNI_N_CFG_GART_CTRL, ctrl);
 
-	if (uninorth_rev <= 0x30) {
+	if (!mem && uninorth_rev <= 0x30) {
 		pci_write_config_dword(agp_bridge->dev, UNI_N_CFG_GART_CTRL,
 				       ctrl | UNI_N_CFG_GART_2xRESET);
 		pci_write_config_dword(agp_bridge->dev, UNI_N_CFG_GART_CTRL,
diff -druN linux-2.6.39-libre/drivers/char/apm-emulation.c linux-3.0-rc7-libre/drivers/char/apm-emulation.c
--- linux-2.6.39-libre/drivers/char/apm-emulation.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/char/apm-emulation.c	2011-07-11 19:51:52.000000000 -0400
@@ -126,7 +126,6 @@
 /*
  * Local variables
  */
-static DEFINE_MUTEX(apm_mutex);
 static atomic_t suspend_acks_pending = ATOMIC_INIT(0);
 static atomic_t userspace_notification_inhibit = ATOMIC_INIT(0);
 static int apm_disabled;
@@ -275,7 +274,6 @@
 	if (!as->suser || !as->writer)
 		return -EPERM;
 
-	mutex_lock(&apm_mutex);
 	switch (cmd) {
 	case APM_IOC_SUSPEND:
 		mutex_lock(&state_lock);
@@ -336,7 +334,6 @@
 		mutex_unlock(&state_lock);
 		break;
 	}
-	mutex_unlock(&apm_mutex);
 
 	return err;
 }
@@ -371,7 +368,6 @@
 {
 	struct apm_user *as;
 
-	mutex_lock(&apm_mutex);
 	as = kzalloc(sizeof(*as), GFP_KERNEL);
 	if (as) {
 		/*
@@ -391,7 +387,6 @@
 
 		filp->private_data = as;
 	}
-	mutex_unlock(&apm_mutex);
 
 	return as ? 0 : -ENOMEM;
 }
diff -druN linux-2.6.39-libre/drivers/char/bsr.c linux-3.0-rc7-libre/drivers/char/bsr.c
--- linux-2.6.39-libre/drivers/char/bsr.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/char/bsr.c	2011-07-11 19:51:52.000000000 -0400
@@ -295,7 +295,7 @@
 static int __init bsr_init(void)
 {
 	struct device_node *np;
-	dev_t bsr_dev = MKDEV(bsr_major, 0);
+	dev_t bsr_dev;
 	int ret = -ENODEV;
 	int result;
 
diff -druN linux-2.6.39-libre/drivers/char/hpet.c linux-3.0-rc7-libre/drivers/char/hpet.c
--- linux-2.6.39-libre/drivers/char/hpet.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/char/hpet.c	2011-07-11 19:51:52.000000000 -0400
@@ -84,8 +84,6 @@
 	.rating		= 250,
 	.read		= read_hpet,
 	.mask		= CLOCKSOURCE_MASK(64),
-	.mult		= 0,		/* to be calculated */
-	.shift		= 10,
 	.flags		= CLOCK_SOURCE_IS_CONTINUOUS,
 };
 static struct clocksource *hpet_clocksource;
@@ -165,11 +163,32 @@
 	 * This has the effect of treating non-periodic like periodic.
 	 */
 	if ((devp->hd_flags & (HPET_IE | HPET_PERIODIC)) == HPET_IE) {
-		unsigned long m, t;
+		unsigned long m, t, mc, base, k;
+		struct hpet __iomem *hpet = devp->hd_hpet;
+		struct hpets *hpetp = devp->hd_hpets;
 
 		t = devp->hd_ireqfreq;
 		m = read_counter(&devp->hd_timer->hpet_compare);
-		write_counter(t + m, &devp->hd_timer->hpet_compare);
+		mc = read_counter(&hpet->hpet_mc);
+		/* The time for the next interrupt would logically be t + m,
+		 * however, if we are very unlucky and the interrupt is delayed
+		 * for longer than t then we will completely miss the next
+		 * interrupt if we set t + m and an application will hang.
+		 * Therefore we need to make a more complex computation assuming
+		 * that there exists a k for which the following is true:
+		 * k * t + base < mc + delta
+		 * (k + 1) * t + base > mc + delta
+		 * where t is the interval in hpet ticks for the given freq,
+		 * base is the theoretical start value 0 < base < t,
+		 * mc is the main counter value at the time of the interrupt,
+		 * delta is the time it takes to write the a value to the
+		 * comparator.
+		 * k may then be computed as (mc - base + delta) / t .
+		 */
+		base = mc % t;
+		k = (mc - base + hpetp->hp_delta) / t;
+		write_counter(t * (k + 1) + base,
+			      &devp->hd_timer->hpet_compare);
 	}
 
 	if (devp->hd_flags & HPET_SHARED_IRQ)
@@ -934,9 +953,7 @@
 	if (!hpet_clocksource) {
 		hpet_mctr = (void __iomem *)&hpetp->hp_hpet->hpet_mc;
 		CLKSRC_FSYS_MMIO_SET(clocksource_hpet.fsys_mmio, hpet_mctr);
-		clocksource_hpet.mult = clocksource_hz2mult(hpetp->hp_tick_freq,
-						clocksource_hpet.shift);
-		clocksource_register(&clocksource_hpet);
+		clocksource_register_hz(&clocksource_hpet, hpetp->hp_tick_freq);
 		hpetp->hp_clocksource = &clocksource_hpet;
 		hpet_clocksource = &clocksource_hpet;
 	}
diff -druN linux-2.6.39-libre/drivers/char/hw_random/amd-rng.c linux-3.0-rc7-libre/drivers/char/hw_random/amd-rng.c
--- linux-2.6.39-libre/drivers/char/hw_random/amd-rng.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/char/hw_random/amd-rng.c	2011-07-11 19:51:52.000000000 -0400
@@ -133,6 +133,12 @@
 	pmbase &= 0x0000FF00;
 	if (pmbase == 0)
 		goto out;
+	if (!request_region(pmbase + 0xF0, 8, "AMD HWRNG")) {
+		dev_err(&pdev->dev, "AMD HWRNG region 0x%x already in use!\n",
+			pmbase + 0xF0);
+		err = -EBUSY;
+		goto out;
+	}
 	amd_rng.priv = (unsigned long)pmbase;
 	amd_pdev = pdev;
 
@@ -141,6 +147,7 @@
 	if (err) {
 		printk(KERN_ERR PFX "RNG registering failed (%d)\n",
 		       err);
+		release_region(pmbase + 0xF0, 8);
 		goto out;
 	}
 out:
@@ -149,6 +156,8 @@
 
 static void __exit mod_exit(void)
 {
+	u32 pmbase = (unsigned long)amd_rng.priv;
+	release_region(pmbase + 0xF0, 8);
 	hwrng_unregister(&amd_rng);
 }
 
diff -druN linux-2.6.39-libre/drivers/char/hw_random/Kconfig linux-3.0-rc7-libre/drivers/char/hw_random/Kconfig
--- linux-2.6.39-libre/drivers/char/hw_random/Kconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/char/hw_random/Kconfig	2011-07-11 19:51:52.000000000 -0400
@@ -49,7 +49,7 @@
 
 config HW_RANDOM_AMD
 	tristate "AMD HW Random Number Generator support"
-	depends on HW_RANDOM && X86 && PCI
+	depends on HW_RANDOM && (X86 || PPC_MAPLE) && PCI
 	default HW_RANDOM
 	---help---
 	  This driver provides kernel-side support for the Random Number
diff -druN linux-2.6.39-libre/drivers/char/i8k.c linux-3.0-rc7-libre/drivers/char/i8k.c
--- linux-2.6.39-libre/drivers/char/i8k.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/char/i8k.c	2011-07-11 19:51:52.000000000 -0400
@@ -5,6 +5,9 @@
  *
  * Copyright (C) 2001  Massimo Dal Zotto <dz@debian.org>
  *
+ * Hwmon integration:
+ * Copyright (C) 2011  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, or (at your option) any
@@ -24,6 +27,8 @@
 #include <linux/dmi.h>
 #include <linux/capability.h>
 #include <linux/mutex.h>
+#include <linux/hwmon.h>
+#include <linux/hwmon-sysfs.h>
 #include <asm/uaccess.h>
 #include <asm/io.h>
 
@@ -58,6 +63,7 @@
 
 static DEFINE_MUTEX(i8k_mutex);
 static char bios_version[4];
+static struct device *i8k_hwmon_dev;
 
 MODULE_AUTHOR("Massimo Dal Zotto (dz@debian.org)");
 MODULE_DESCRIPTION("Driver for accessing SMM BIOS on Dell laptops");
@@ -139,8 +145,8 @@
 		"movl %%edi,20(%%rax)\n\t"
 		"popq %%rdx\n\t"
 		"movl %%edx,0(%%rax)\n\t"
-		"lahf\n\t"
-		"shrl $8,%%eax\n\t"
+		"pushfq\n\t"
+		"popq %%rax\n\t"
 		"andl $1,%%eax\n"
 		:"=a"(rc)
 		:    "a"(regs)
@@ -455,6 +461,152 @@
 	return single_open(file, i8k_proc_show, NULL);
 }
 
+
+/*
+ * Hwmon interface
+ */
+
+static ssize_t i8k_hwmon_show_temp(struct device *dev,
+				   struct device_attribute *devattr,
+				   char *buf)
+{
+	int cpu_temp;
+
+	cpu_temp = i8k_get_temp(0);
+	if (cpu_temp < 0)
+		return cpu_temp;
+	return sprintf(buf, "%d\n", cpu_temp * 1000);
+}
+
+static ssize_t i8k_hwmon_show_fan(struct device *dev,
+				  struct device_attribute *devattr,
+				  char *buf)
+{
+	int index = to_sensor_dev_attr(devattr)->index;
+	int fan_speed;
+
+	fan_speed = i8k_get_fan_speed(index);
+	if (fan_speed < 0)
+		return fan_speed;
+	return sprintf(buf, "%d\n", fan_speed);
+}
+
+static ssize_t i8k_hwmon_show_label(struct device *dev,
+				    struct device_attribute *devattr,
+				    char *buf)
+{
+	static const char *labels[4] = {
+		"i8k",
+		"CPU",
+		"Left Fan",
+		"Right Fan",
+	};
+	int index = to_sensor_dev_attr(devattr)->index;
+
+	return sprintf(buf, "%s\n", labels[index]);
+}
+
+static DEVICE_ATTR(temp1_input, S_IRUGO, i8k_hwmon_show_temp, NULL);
+static SENSOR_DEVICE_ATTR(fan1_input, S_IRUGO, i8k_hwmon_show_fan, NULL,
+			  I8K_FAN_LEFT);
+static SENSOR_DEVICE_ATTR(fan2_input, S_IRUGO, i8k_hwmon_show_fan, NULL,
+			  I8K_FAN_RIGHT);
+static SENSOR_DEVICE_ATTR(name, S_IRUGO, i8k_hwmon_show_label, NULL, 0);
+static SENSOR_DEVICE_ATTR(temp1_label, S_IRUGO, i8k_hwmon_show_label, NULL, 1);
+static SENSOR_DEVICE_ATTR(fan1_label, S_IRUGO, i8k_hwmon_show_label, NULL, 2);
+static SENSOR_DEVICE_ATTR(fan2_label, S_IRUGO, i8k_hwmon_show_label, NULL, 3);
+
+static void i8k_hwmon_remove_files(struct device *dev)
+{
+	device_remove_file(dev, &dev_attr_temp1_input);
+	device_remove_file(dev, &sensor_dev_attr_fan1_input.dev_attr);
+	device_remove_file(dev, &sensor_dev_attr_fan2_input.dev_attr);
+	device_remove_file(dev, &sensor_dev_attr_temp1_label.dev_attr);
+	device_remove_file(dev, &sensor_dev_attr_fan1_label.dev_attr);
+	device_remove_file(dev, &sensor_dev_attr_fan2_label.dev_attr);
+	device_remove_file(dev, &sensor_dev_attr_name.dev_attr);
+}
+
+static int __init i8k_init_hwmon(void)
+{
+	int err;
+
+	i8k_hwmon_dev = hwmon_device_register(NULL);
+	if (IS_ERR(i8k_hwmon_dev)) {
+		err = PTR_ERR(i8k_hwmon_dev);
+		i8k_hwmon_dev = NULL;
+		printk(KERN_ERR "i8k: hwmon registration failed (%d)\n", err);
+		return err;
+	}
+
+	/* Required name attribute */
+	err = device_create_file(i8k_hwmon_dev,
+				 &sensor_dev_attr_name.dev_attr);
+	if (err)
+		goto exit_unregister;
+
+	/* CPU temperature attributes, if temperature reading is OK */
+	err = i8k_get_temp(0);
+	if (err < 0) {
+		dev_dbg(i8k_hwmon_dev,
+			"Not creating temperature attributes (%d)\n", err);
+	} else {
+		err = device_create_file(i8k_hwmon_dev, &dev_attr_temp1_input);
+		if (err)
+			goto exit_remove_files;
+		err = device_create_file(i8k_hwmon_dev,
+					 &sensor_dev_attr_temp1_label.dev_attr);
+		if (err)
+			goto exit_remove_files;
+	}
+
+	/* Left fan attributes, if left fan is present */
+	err = i8k_get_fan_status(I8K_FAN_LEFT);
+	if (err < 0) {
+		dev_dbg(i8k_hwmon_dev,
+			"Not creating %s fan attributes (%d)\n", "left", err);
+	} else {
+		err = device_create_file(i8k_hwmon_dev,
+					 &sensor_dev_attr_fan1_input.dev_attr);
+		if (err)
+			goto exit_remove_files;
+		err = device_create_file(i8k_hwmon_dev,
+					 &sensor_dev_attr_fan1_label.dev_attr);
+		if (err)
+			goto exit_remove_files;
+	}
+
+	/* Right fan attributes, if right fan is present */
+	err = i8k_get_fan_status(I8K_FAN_RIGHT);
+	if (err < 0) {
+		dev_dbg(i8k_hwmon_dev,
+			"Not creating %s fan attributes (%d)\n", "right", err);
+	} else {
+		err = device_create_file(i8k_hwmon_dev,
+					 &sensor_dev_attr_fan2_input.dev_attr);
+		if (err)
+			goto exit_remove_files;
+		err = device_create_file(i8k_hwmon_dev,
+					 &sensor_dev_attr_fan2_label.dev_attr);
+		if (err)
+			goto exit_remove_files;
+	}
+
+	return 0;
+
+ exit_remove_files:
+	i8k_hwmon_remove_files(i8k_hwmon_dev);
+ exit_unregister:
+	hwmon_device_unregister(i8k_hwmon_dev);
+	return err;
+}
+
+static void __exit i8k_exit_hwmon(void)
+{
+	i8k_hwmon_remove_files(i8k_hwmon_dev);
+	hwmon_device_unregister(i8k_hwmon_dev);
+}
+
 static struct dmi_system_id __initdata i8k_dmi_table[] = {
 	{
 		.ident = "Dell Inspiron",
@@ -580,6 +732,7 @@
 static int __init i8k_init(void)
 {
 	struct proc_dir_entry *proc_i8k;
+	int err;
 
 	/* Are we running on an supported laptop? */
 	if (i8k_probe())
@@ -590,15 +743,24 @@
 	if (!proc_i8k)
 		return -ENOENT;
 
+	err = i8k_init_hwmon();
+	if (err)
+		goto exit_remove_proc;
+
 	printk(KERN_INFO
 	       "Dell laptop SMM driver v%s Massimo Dal Zotto (dz@debian.org)\n",
 	       I8K_VERSION);
 
 	return 0;
+
+ exit_remove_proc:
+	remove_proc_entry("i8k", NULL);
+	return err;
 }
 
 static void __exit i8k_exit(void)
 {
+	i8k_exit_hwmon();
 	remove_proc_entry("i8k", NULL);
 }
 
diff -druN linux-2.6.39-libre/drivers/char/ipmi/ipmi_msghandler.c linux-3.0-rc7-libre/drivers/char/ipmi/ipmi_msghandler.c
--- linux-2.6.39-libre/drivers/char/ipmi/ipmi_msghandler.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/char/ipmi/ipmi_msghandler.c	2011-07-11 19:51:52.000000000 -0400
@@ -36,6 +36,7 @@
 #include <asm/system.h>
 #include <linux/poll.h>
 #include <linux/sched.h>
+#include <linux/seq_file.h>
 #include <linux/spinlock.h>
 #include <linux/mutex.h>
 #include <linux/slab.h>
@@ -1896,102 +1897,128 @@
 EXPORT_SYMBOL(ipmi_request_supply_msgs);
 
 #ifdef CONFIG_PROC_FS
-static int ipmb_file_read_proc(char *page, char **start, off_t off,
-			       int count, int *eof, void *data)
+static int smi_ipmb_proc_show(struct seq_file *m, void *v)
 {
-	char       *out = (char *) page;
-	ipmi_smi_t intf = data;
+	ipmi_smi_t intf = m->private;
 	int        i;
-	int        rv = 0;
 
-	for (i = 0; i < IPMI_MAX_CHANNELS; i++)
-		rv += sprintf(out+rv, "%x ", intf->channels[i].address);
-	out[rv-1] = '\n'; /* Replace the final space with a newline */
-	out[rv] = '\0';
-	rv++;
-	return rv;
+	seq_printf(m, "%x", intf->channels[0].address);
+	for (i = 1; i < IPMI_MAX_CHANNELS; i++)
+		seq_printf(m, " %x", intf->channels[i].address);
+	return seq_putc(m, '\n');
 }
 
-static int version_file_read_proc(char *page, char **start, off_t off,
-				  int count, int *eof, void *data)
+static int smi_ipmb_proc_open(struct inode *inode, struct file *file)
 {
-	char       *out = (char *) page;
-	ipmi_smi_t intf = data;
+	return single_open(file, smi_ipmb_proc_show, PDE(inode)->data);
+}
 
-	return sprintf(out, "%u.%u\n",
+static const struct file_operations smi_ipmb_proc_ops = {
+	.open		= smi_ipmb_proc_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
+static int smi_version_proc_show(struct seq_file *m, void *v)
+{
+	ipmi_smi_t intf = m->private;
+
+	return seq_printf(m, "%u.%u\n",
 		       ipmi_version_major(&intf->bmc->id),
 		       ipmi_version_minor(&intf->bmc->id));
 }
 
-static int stat_file_read_proc(char *page, char **start, off_t off,
-			       int count, int *eof, void *data)
+static int smi_version_proc_open(struct inode *inode, struct file *file)
 {
-	char       *out = (char *) page;
-	ipmi_smi_t intf = data;
+	return single_open(file, smi_version_proc_show, PDE(inode)->data);
+}
 
-	out += sprintf(out, "sent_invalid_commands:       %u\n",
+static const struct file_operations smi_version_proc_ops = {
+	.open		= smi_version_proc_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
+static int smi_stats_proc_show(struct seq_file *m, void *v)
+{
+	ipmi_smi_t intf = m->private;
+
+	seq_printf(m, "sent_invalid_commands:       %u\n",
 		       ipmi_get_stat(intf, sent_invalid_commands));
-	out += sprintf(out, "sent_local_commands:         %u\n",
+	seq_printf(m, "sent_local_commands:         %u\n",
 		       ipmi_get_stat(intf, sent_local_commands));
-	out += sprintf(out, "handled_local_responses:     %u\n",
+	seq_printf(m, "handled_local_responses:     %u\n",
 		       ipmi_get_stat(intf, handled_local_responses));
-	out += sprintf(out, "unhandled_local_responses:   %u\n",
+	seq_printf(m, "unhandled_local_responses:   %u\n",
 		       ipmi_get_stat(intf, unhandled_local_responses));
-	out += sprintf(out, "sent_ipmb_commands:          %u\n",
+	seq_printf(m, "sent_ipmb_commands:          %u\n",
 		       ipmi_get_stat(intf, sent_ipmb_commands));
-	out += sprintf(out, "sent_ipmb_command_errs:      %u\n",
+	seq_printf(m, "sent_ipmb_command_errs:      %u\n",
 		       ipmi_get_stat(intf, sent_ipmb_command_errs));
-	out += sprintf(out, "retransmitted_ipmb_commands: %u\n",
+	seq_printf(m, "retransmitted_ipmb_commands: %u\n",
 		       ipmi_get_stat(intf, retransmitted_ipmb_commands));
-	out += sprintf(out, "timed_out_ipmb_commands:     %u\n",
+	seq_printf(m, "timed_out_ipmb_commands:     %u\n",
 		       ipmi_get_stat(intf, timed_out_ipmb_commands));
-	out += sprintf(out, "timed_out_ipmb_broadcasts:   %u\n",
+	seq_printf(m, "timed_out_ipmb_broadcasts:   %u\n",
 		       ipmi_get_stat(intf, timed_out_ipmb_broadcasts));
-	out += sprintf(out, "sent_ipmb_responses:         %u\n",
+	seq_printf(m, "sent_ipmb_responses:         %u\n",
 		       ipmi_get_stat(intf, sent_ipmb_responses));
-	out += sprintf(out, "handled_ipmb_responses:      %u\n",
+	seq_printf(m, "handled_ipmb_responses:      %u\n",
 		       ipmi_get_stat(intf, handled_ipmb_responses));
-	out += sprintf(out, "invalid_ipmb_responses:      %u\n",
+	seq_printf(m, "invalid_ipmb_responses:      %u\n",
 		       ipmi_get_stat(intf, invalid_ipmb_responses));
-	out += sprintf(out, "unhandled_ipmb_responses:    %u\n",
+	seq_printf(m, "unhandled_ipmb_responses:    %u\n",
 		       ipmi_get_stat(intf, unhandled_ipmb_responses));
-	out += sprintf(out, "sent_lan_commands:           %u\n",
+	seq_printf(m, "sent_lan_commands:           %u\n",
 		       ipmi_get_stat(intf, sent_lan_commands));
-	out += sprintf(out, "sent_lan_command_errs:       %u\n",
+	seq_printf(m, "sent_lan_command_errs:       %u\n",
 		       ipmi_get_stat(intf, sent_lan_command_errs));
-	out += sprintf(out, "retransmitted_lan_commands:  %u\n",
+	seq_printf(m, "retransmitted_lan_commands:  %u\n",
 		       ipmi_get_stat(intf, retransmitted_lan_commands));
-	out += sprintf(out, "timed_out_lan_commands:      %u\n",
+	seq_printf(m, "timed_out_lan_commands:      %u\n",
 		       ipmi_get_stat(intf, timed_out_lan_commands));
-	out += sprintf(out, "sent_lan_responses:          %u\n",
+	seq_printf(m, "sent_lan_responses:          %u\n",
 		       ipmi_get_stat(intf, sent_lan_responses));
-	out += sprintf(out, "handled_lan_responses:       %u\n",
+	seq_printf(m, "handled_lan_responses:       %u\n",
 		       ipmi_get_stat(intf, handled_lan_responses));
-	out += sprintf(out, "invalid_lan_responses:       %u\n",
+	seq_printf(m, "invalid_lan_responses:       %u\n",
 		       ipmi_get_stat(intf, invalid_lan_responses));
-	out += sprintf(out, "unhandled_lan_responses:     %u\n",
+	seq_printf(m, "unhandled_lan_responses:     %u\n",
 		       ipmi_get_stat(intf, unhandled_lan_responses));
-	out += sprintf(out, "handled_commands:            %u\n",
+	seq_printf(m, "handled_commands:            %u\n",
 		       ipmi_get_stat(intf, handled_commands));
-	out += sprintf(out, "invalid_commands:            %u\n",
+	seq_printf(m, "invalid_commands:            %u\n",
 		       ipmi_get_stat(intf, invalid_commands));
-	out += sprintf(out, "unhandled_commands:          %u\n",
+	seq_printf(m, "unhandled_commands:          %u\n",
 		       ipmi_get_stat(intf, unhandled_commands));
-	out += sprintf(out, "invalid_events:              %u\n",
+	seq_printf(m, "invalid_events:              %u\n",
 		       ipmi_get_stat(intf, invalid_events));
-	out += sprintf(out, "events:                      %u\n",
+	seq_printf(m, "events:                      %u\n",
 		       ipmi_get_stat(intf, events));
-	out += sprintf(out, "failed rexmit LAN msgs:      %u\n",
+	seq_printf(m, "failed rexmit LAN msgs:      %u\n",
 		       ipmi_get_stat(intf, dropped_rexmit_lan_commands));
-	out += sprintf(out, "failed rexmit IPMB msgs:     %u\n",
+	seq_printf(m, "failed rexmit IPMB msgs:     %u\n",
 		       ipmi_get_stat(intf, dropped_rexmit_ipmb_commands));
+	return 0;
+}
 
-	return (out - ((char *) page));
+static int smi_stats_proc_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, smi_stats_proc_show, PDE(inode)->data);
 }
+
+static const struct file_operations smi_stats_proc_ops = {
+	.open		= smi_stats_proc_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
 #endif /* CONFIG_PROC_FS */
 
 int ipmi_smi_add_proc_entry(ipmi_smi_t smi, char *name,
-			    read_proc_t *read_proc,
+			    const struct file_operations *proc_ops,
 			    void *data)
 {
 	int                    rv = 0;
@@ -2010,15 +2037,12 @@
 	}
 	strcpy(entry->name, name);
 
-	file = create_proc_entry(name, 0, smi->proc_dir);
+	file = proc_create_data(name, 0, smi->proc_dir, proc_ops, data);
 	if (!file) {
 		kfree(entry->name);
 		kfree(entry);
 		rv = -ENOMEM;
 	} else {
-		file->data = data;
-		file->read_proc = read_proc;
-
 		mutex_lock(&smi->proc_entry_lock);
 		/* Stick it on the list. */
 		entry->next = smi->proc_entries;
@@ -2043,17 +2067,17 @@
 
 	if (rv == 0)
 		rv = ipmi_smi_add_proc_entry(smi, "stats",
-					     stat_file_read_proc,
+					     &smi_stats_proc_ops,
 					     smi);
 
 	if (rv == 0)
 		rv = ipmi_smi_add_proc_entry(smi, "ipmb",
-					     ipmb_file_read_proc,
+					     &smi_ipmb_proc_ops,
 					     smi);
 
 	if (rv == 0)
 		rv = ipmi_smi_add_proc_entry(smi, "version",
-					     version_file_read_proc,
+					     &smi_version_proc_ops,
 					     smi);
 #endif /* CONFIG_PROC_FS */
 
diff -druN linux-2.6.39-libre/drivers/char/ipmi/ipmi_si_intf.c linux-3.0-rc7-libre/drivers/char/ipmi/ipmi_si_intf.c
--- linux-2.6.39-libre/drivers/char/ipmi/ipmi_si_intf.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/char/ipmi/ipmi_si_intf.c	2011-07-11 19:51:52.000000000 -0400
@@ -43,6 +43,7 @@
 #include <linux/moduleparam.h>
 #include <asm/system.h>
 #include <linux/sched.h>
+#include <linux/seq_file.h>
 #include <linux/timer.h>
 #include <linux/errno.h>
 #include <linux/spinlock.h>
@@ -2805,54 +2806,73 @@
 	return rv;
 }
 
-static int type_file_read_proc(char *page, char **start, off_t off,
-			       int count, int *eof, void *data)
+static int smi_type_proc_show(struct seq_file *m, void *v)
 {
-	struct smi_info *smi = data;
+	struct smi_info *smi = m->private;
 
-	return sprintf(page, "%s\n", si_to_str[smi->si_type]);
+	return seq_printf(m, "%s\n", si_to_str[smi->si_type]);
 }
 
-static int stat_file_read_proc(char *page, char **start, off_t off,
-			       int count, int *eof, void *data)
+static int smi_type_proc_open(struct inode *inode, struct file *file)
 {
-	char            *out = (char *) page;
-	struct smi_info *smi = data;
+	return single_open(file, smi_type_proc_show, PDE(inode)->data);
+}
 
-	out += sprintf(out, "interrupts_enabled:    %d\n",
+static const struct file_operations smi_type_proc_ops = {
+	.open		= smi_type_proc_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
+static int smi_si_stats_proc_show(struct seq_file *m, void *v)
+{
+	struct smi_info *smi = m->private;
+
+	seq_printf(m, "interrupts_enabled:    %d\n",
 		       smi->irq && !smi->interrupt_disabled);
-	out += sprintf(out, "short_timeouts:        %u\n",
+	seq_printf(m, "short_timeouts:        %u\n",
 		       smi_get_stat(smi, short_timeouts));
-	out += sprintf(out, "long_timeouts:         %u\n",
+	seq_printf(m, "long_timeouts:         %u\n",
 		       smi_get_stat(smi, long_timeouts));
-	out += sprintf(out, "idles:                 %u\n",
+	seq_printf(m, "idles:                 %u\n",
 		       smi_get_stat(smi, idles));
-	out += sprintf(out, "interrupts:            %u\n",
+	seq_printf(m, "interrupts:            %u\n",
 		       smi_get_stat(smi, interrupts));
-	out += sprintf(out, "attentions:            %u\n",
+	seq_printf(m, "attentions:            %u\n",
 		       smi_get_stat(smi, attentions));
-	out += sprintf(out, "flag_fetches:          %u\n",
+	seq_printf(m, "flag_fetches:          %u\n",
 		       smi_get_stat(smi, flag_fetches));
-	out += sprintf(out, "hosed_count:           %u\n",
+	seq_printf(m, "hosed_count:           %u\n",
 		       smi_get_stat(smi, hosed_count));
-	out += sprintf(out, "complete_transactions: %u\n",
+	seq_printf(m, "complete_transactions: %u\n",
 		       smi_get_stat(smi, complete_transactions));
-	out += sprintf(out, "events:                %u\n",
+	seq_printf(m, "events:                %u\n",
 		       smi_get_stat(smi, events));
-	out += sprintf(out, "watchdog_pretimeouts:  %u\n",
+	seq_printf(m, "watchdog_pretimeouts:  %u\n",
 		       smi_get_stat(smi, watchdog_pretimeouts));
-	out += sprintf(out, "incoming_messages:     %u\n",
+	seq_printf(m, "incoming_messages:     %u\n",
 		       smi_get_stat(smi, incoming_messages));
+	return 0;
+}
 
-	return out - page;
+static int smi_si_stats_proc_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, smi_si_stats_proc_show, PDE(inode)->data);
 }
 
-static int param_read_proc(char *page, char **start, off_t off,
-			   int count, int *eof, void *data)
+static const struct file_operations smi_si_stats_proc_ops = {
+	.open		= smi_si_stats_proc_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
+static int smi_params_proc_show(struct seq_file *m, void *v)
 {
-	struct smi_info *smi = data;
+	struct smi_info *smi = m->private;
 
-	return sprintf(page,
+	return seq_printf(m,
 		       "%s,%s,0x%lx,rsp=%d,rsi=%d,rsh=%d,irq=%d,ipmb=%d\n",
 		       si_to_str[smi->si_type],
 		       addr_space_to_str[smi->io.addr_type],
@@ -2864,6 +2884,18 @@
 		       smi->slave_addr);
 }
 
+static int smi_params_proc_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, smi_params_proc_show, PDE(inode)->data);
+}
+
+static const struct file_operations smi_params_proc_ops = {
+	.open		= smi_params_proc_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
 /*
  * oem_data_avail_to_receive_msg_avail
  * @info - smi_info structure with msg_flags set
@@ -3257,7 +3289,7 @@
 	}
 
 	rv = ipmi_smi_add_proc_entry(new_smi->intf, "type",
-				     type_file_read_proc,
+				     &smi_type_proc_ops,
 				     new_smi);
 	if (rv) {
 		dev_err(new_smi->dev, "Unable to create proc entry: %d\n", rv);
@@ -3265,7 +3297,7 @@
 	}
 
 	rv = ipmi_smi_add_proc_entry(new_smi->intf, "si_stats",
-				     stat_file_read_proc,
+				     &smi_si_stats_proc_ops,
 				     new_smi);
 	if (rv) {
 		dev_err(new_smi->dev, "Unable to create proc entry: %d\n", rv);
@@ -3273,7 +3305,7 @@
 	}
 
 	rv = ipmi_smi_add_proc_entry(new_smi->intf, "params",
-				     param_read_proc,
+				     &smi_params_proc_ops,
 				     new_smi);
 	if (rv) {
 		dev_err(new_smi->dev, "Unable to create proc entry: %d\n", rv);
diff -druN linux-2.6.39-libre/drivers/char/Kconfig linux-3.0-rc7-libre/drivers/char/Kconfig
--- linux-2.6.39-libre/drivers/char/Kconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/char/Kconfig	2011-07-11 19:51:52.000000000 -0400
@@ -523,7 +523,7 @@
           with the O_DIRECT flag.
 
 config MAX_RAW_DEVS
-	int "Maximum number of RAW devices to support (1-8192)"
+	int "Maximum number of RAW devices to support (1-65536)"
 	depends on RAW_DRIVER
 	default "256"
 	help
diff -druN linux-2.6.39-libre/drivers/char/mem.c linux-3.0-rc7-libre/drivers/char/mem.c
--- linux-2.6.39-libre/drivers/char/mem.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/char/mem.c	2011-07-11 19:51:52.000000000 -0400
@@ -806,29 +806,41 @@
 };
 #endif
 
-static ssize_t kmsg_write(struct file *file, const char __user *buf,
-			  size_t count, loff_t *ppos)
+static ssize_t kmsg_writev(struct kiocb *iocb, const struct iovec *iv,
+			   unsigned long count, loff_t pos)
 {
-	char *tmp;
-	ssize_t ret;
+	char *line, *p;
+	int i;
+	ssize_t ret = -EFAULT;
+	size_t len = iov_length(iv, count);
 
-	tmp = kmalloc(count + 1, GFP_KERNEL);
-	if (tmp == NULL)
+	line = kmalloc(len + 1, GFP_KERNEL);
+	if (line == NULL)
 		return -ENOMEM;
-	ret = -EFAULT;
-	if (!copy_from_user(tmp, buf, count)) {
-		tmp[count] = 0;
-		ret = printk("%s", tmp);
-		if (ret > count)
-			/* printk can add a prefix */
-			ret = count;
+
+	/*
+	 * copy all vectors into a single string, to ensure we do
+	 * not interleave our log line with other printk calls
+	 */
+	p = line;
+	for (i = 0; i < count; i++) {
+		if (copy_from_user(p, iv[i].iov_base, iv[i].iov_len))
+			goto out;
+		p += iv[i].iov_len;
 	}
-	kfree(tmp);
+	p[0] = '\0';
+
+	ret = printk("%s", line);
+	/* printk can add a prefix */
+	if (ret > len)
+		ret = len;
+out:
+	kfree(line);
 	return ret;
 }
 
 static const struct file_operations kmsg_fops = {
-	.write = kmsg_write,
+	.aio_write = kmsg_writev,
 	.llseek = noop_llseek,
 };
 
diff -druN linux-2.6.39-libre/drivers/char/mspec.c linux-3.0-rc7-libre/drivers/char/mspec.c
--- linux-2.6.39-libre/drivers/char/mspec.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/char/mspec.c	2011-07-11 19:51:52.000000000 -0400
@@ -271,14 +271,13 @@
 	pages = (vma->vm_end - vma->vm_start) >> PAGE_SHIFT;
 	vdata_size = sizeof(struct vma_data) + pages * sizeof(long);
 	if (vdata_size <= PAGE_SIZE)
-		vdata = kmalloc(vdata_size, GFP_KERNEL);
+		vdata = kzalloc(vdata_size, GFP_KERNEL);
 	else {
-		vdata = vmalloc(vdata_size);
+		vdata = vzalloc(vdata_size);
 		flags = VMD_VMALLOCED;
 	}
 	if (!vdata)
 		return -ENOMEM;
-	memset(vdata, 0, vdata_size);
 
 	vdata->vm_start = vma->vm_start;
 	vdata->vm_end = vma->vm_end;
diff -druN linux-2.6.39-libre/drivers/char/pcmcia/cm4000_cs.c linux-3.0-rc7-libre/drivers/char/pcmcia/cm4000_cs.c
--- linux-2.6.39-libre/drivers/char/pcmcia/cm4000_cs.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/char/pcmcia/cm4000_cs.c	2011-07-11 19:51:52.000000000 -0400
@@ -1869,7 +1869,7 @@
 	.llseek = no_llseek,
 };
 
-static struct pcmcia_device_id cm4000_ids[] = {
+static const struct pcmcia_device_id cm4000_ids[] = {
 	PCMCIA_DEVICE_MANF_CARD(0x0223, 0x0002),
 	PCMCIA_DEVICE_PROD_ID12("CardMan", "4000", 0x2FB368CA, 0xA2BD8C39),
 	PCMCIA_DEVICE_NULL,
diff -druN linux-2.6.39-libre/drivers/char/pcmcia/cm4040_cs.c linux-3.0-rc7-libre/drivers/char/pcmcia/cm4040_cs.c
--- linux-2.6.39-libre/drivers/char/pcmcia/cm4040_cs.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/char/pcmcia/cm4040_cs.c	2011-07-11 19:51:52.000000000 -0400
@@ -633,7 +633,7 @@
 	.llseek		= no_llseek,
 };
 
-static struct pcmcia_device_id cm4040_ids[] = {
+static const struct pcmcia_device_id cm4040_ids[] = {
 	PCMCIA_DEVICE_MANF_CARD(0x0223, 0x0200),
 	PCMCIA_DEVICE_PROD_ID12("OMNIKEY", "CardMan 4040",
 				0xE32CDD8C, 0x8F23318B),
diff -druN linux-2.6.39-libre/drivers/char/pcmcia/synclink_cs.c linux-3.0-rc7-libre/drivers/char/pcmcia/synclink_cs.c
--- linux-2.6.39-libre/drivers/char/pcmcia/synclink_cs.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/char/pcmcia/synclink_cs.c	2011-07-11 19:51:52.000000000 -0400
@@ -2758,7 +2758,7 @@
 	}
 }
 
-static struct pcmcia_device_id mgslpc_ids[] = {
+static const struct pcmcia_device_id mgslpc_ids[] = {
 	PCMCIA_DEVICE_MANF_CARD(0x02c5, 0x0050),
 	PCMCIA_DEVICE_NULL
 };
diff -druN linux-2.6.39-libre/drivers/char/ppdev.c linux-3.0-rc7-libre/drivers/char/ppdev.c
--- linux-2.6.39-libre/drivers/char/ppdev.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/char/ppdev.c	2011-07-11 19:51:52.000000000 -0400
@@ -457,6 +457,7 @@
 			return -ENODEV;
 
 		modes = port->modes;
+		parport_put_port(port);
 		if (copy_to_user (argp, &modes, sizeof (modes))) {
 			return -EFAULT;
 		}
diff -druN linux-2.6.39-libre/drivers/char/raw.c linux-3.0-rc7-libre/drivers/char/raw.c
--- linux-2.6.39-libre/drivers/char/raw.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/char/raw.c	2011-07-11 19:51:52.000000000 -0400
@@ -21,6 +21,7 @@
 #include <linux/mutex.h>
 #include <linux/gfp.h>
 #include <linux/compat.h>
+#include <linux/vmalloc.h>
 
 #include <asm/uaccess.h>
 
@@ -30,10 +31,15 @@
 };
 
 static struct class *raw_class;
-static struct raw_device_data raw_devices[MAX_RAW_MINORS];
+static struct raw_device_data *raw_devices;
 static DEFINE_MUTEX(raw_mutex);
 static const struct file_operations raw_ctl_fops; /* forward declaration */
 
+static int max_raw_minors = MAX_RAW_MINORS;
+
+module_param(max_raw_minors, int, 0);
+MODULE_PARM_DESC(max_raw_minors, "Maximum number of raw devices (1-65536)");
+
 /*
  * Open/close code for raw IO.
  *
@@ -125,7 +131,7 @@
 	struct raw_device_data *rawdev;
 	int err = 0;
 
-	if (number <= 0 || number >= MAX_RAW_MINORS)
+	if (number <= 0 || number >= max_raw_minors)
 		return -EINVAL;
 
 	if (MAJOR(dev) != major || MINOR(dev) != minor)
@@ -312,14 +318,27 @@
 	dev_t dev = MKDEV(RAW_MAJOR, 0);
 	int ret;
 
-	ret = register_chrdev_region(dev, MAX_RAW_MINORS, "raw");
+	if (max_raw_minors < 1 || max_raw_minors > 65536) {
+		printk(KERN_WARNING "raw: invalid max_raw_minors (must be"
+			" between 1 and 65536), using %d\n", MAX_RAW_MINORS);
+		max_raw_minors = MAX_RAW_MINORS;
+	}
+
+	raw_devices = vmalloc(sizeof(struct raw_device_data) * max_raw_minors);
+	if (!raw_devices) {
+		printk(KERN_ERR "Not enough memory for raw device structures\n");
+		ret = -ENOMEM;
+		goto error;
+	}
+	memset(raw_devices, 0, sizeof(struct raw_device_data) * max_raw_minors);
+
+	ret = register_chrdev_region(dev, max_raw_minors, "raw");
 	if (ret)
 		goto error;
 
 	cdev_init(&raw_cdev, &raw_fops);
-	ret = cdev_add(&raw_cdev, dev, MAX_RAW_MINORS);
+	ret = cdev_add(&raw_cdev, dev, max_raw_minors);
 	if (ret) {
-		kobject_put(&raw_cdev.kobj);
 		goto error_region;
 	}
 
@@ -336,8 +355,9 @@
 	return 0;
 
 error_region:
-	unregister_chrdev_region(dev, MAX_RAW_MINORS);
+	unregister_chrdev_region(dev, max_raw_minors);
 error:
+	vfree(raw_devices);
 	return ret;
 }
 
@@ -346,7 +366,7 @@
 	device_destroy(raw_class, MKDEV(RAW_MAJOR, 0));
 	class_destroy(raw_class);
 	cdev_del(&raw_cdev);
-	unregister_chrdev_region(MKDEV(RAW_MAJOR, 0), MAX_RAW_MINORS);
+	unregister_chrdev_region(MKDEV(RAW_MAJOR, 0), max_raw_minors);
 }
 
 module_init(raw_init);
diff -druN linux-2.6.39-libre/drivers/char/virtio_console.c linux-3.0-rc7-libre/drivers/char/virtio_console.c
--- linux-2.6.39-libre/drivers/char/virtio_console.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/char/virtio_console.c	2011-07-11 19:51:52.000000000 -0400
@@ -1677,17 +1677,12 @@
 	portdev->config.max_nr_ports = 1;
 	if (virtio_has_feature(vdev, VIRTIO_CONSOLE_F_MULTIPORT)) {
 		multiport = true;
-		vdev->features[0] |= 1 << VIRTIO_CONSOLE_F_MULTIPORT;
-
 		vdev->config->get(vdev, offsetof(struct virtio_console_config,
 						 max_nr_ports),
 				  &portdev->config.max_nr_ports,
 				  sizeof(portdev->config.max_nr_ports));
 	}
 
-	/* Let the Host know we support multiple ports.*/
-	vdev->config->finalize_features(vdev);
-
 	err = init_vqs(portdev);
 	if (err < 0) {
 		dev_err(&vdev->dev, "Error %d initializing vqs\n", err);
diff -druN linux-2.6.39-libre/drivers/clocksource/cyclone.c linux-3.0-rc7-libre/drivers/clocksource/cyclone.c
--- linux-2.6.39-libre/drivers/clocksource/cyclone.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/clocksource/cyclone.c	2011-07-11 19:51:52.000000000 -0400
@@ -29,8 +29,6 @@
 	.rating		= 250,
 	.read		= read_cyclone,
 	.mask		= CYCLONE_TIMER_MASK,
-	.mult		= 10,
-	.shift		= 0,
 	.flags		= CLOCK_SOURCE_IS_CONTINUOUS,
 };
 
@@ -108,12 +106,8 @@
 	}
 	cyclone_ptr = cyclone_timer;
 
-	/* sort out mult/shift values: */
-	clocksource_cyclone.shift = 22;
-	clocksource_cyclone.mult = clocksource_hz2mult(CYCLONE_TIMER_FREQ,
-						clocksource_cyclone.shift);
-
-	return clocksource_register(&clocksource_cyclone);
+	return clocksource_register_hz(&clocksource_cyclone,
+					CYCLONE_TIMER_FREQ);
 }
 
 arch_initcall(init_cyclone_clocksource);
diff -druN linux-2.6.39-libre/drivers/clocksource/i8253.c linux-3.0-rc7-libre/drivers/clocksource/i8253.c
--- linux-2.6.39-libre/drivers/clocksource/i8253.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/clocksource/i8253.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,88 @@
+/*
+ * i8253 PIT clocksource
+ */
+#include <linux/clocksource.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/spinlock.h>
+#include <linux/timex.h>
+
+#include <asm/i8253.h>
+
+/*
+ * Since the PIT overflows every tick, its not very useful
+ * to just read by itself. So use jiffies to emulate a free
+ * running counter:
+ */
+static cycle_t i8253_read(struct clocksource *cs)
+{
+	static int old_count;
+	static u32 old_jifs;
+	unsigned long flags;
+	int count;
+	u32 jifs;
+
+	raw_spin_lock_irqsave(&i8253_lock, flags);
+	/*
+	 * Although our caller may have the read side of xtime_lock,
+	 * this is now a seqlock, and we are cheating in this routine
+	 * by having side effects on state that we cannot undo if
+	 * there is a collision on the seqlock and our caller has to
+	 * retry.  (Namely, old_jifs and old_count.)  So we must treat
+	 * jiffies as volatile despite the lock.  We read jiffies
+	 * before latching the timer count to guarantee that although
+	 * the jiffies value might be older than the count (that is,
+	 * the counter may underflow between the last point where
+	 * jiffies was incremented and the point where we latch the
+	 * count), it cannot be newer.
+	 */
+	jifs = jiffies;
+	outb_pit(0x00, PIT_MODE);	/* latch the count ASAP */
+	count = inb_pit(PIT_CH0);	/* read the latched count */
+	count |= inb_pit(PIT_CH0) << 8;
+
+	/* VIA686a test code... reset the latch if count > max + 1 */
+	if (count > LATCH) {
+		outb_pit(0x34, PIT_MODE);
+		outb_pit(PIT_LATCH & 0xff, PIT_CH0);
+		outb_pit(PIT_LATCH >> 8, PIT_CH0);
+		count = PIT_LATCH - 1;
+	}
+
+	/*
+	 * It's possible for count to appear to go the wrong way for a
+	 * couple of reasons:
+	 *
+	 *  1. The timer counter underflows, but we haven't handled the
+	 *     resulting interrupt and incremented jiffies yet.
+	 *  2. Hardware problem with the timer, not giving us continuous time,
+	 *     the counter does small "jumps" upwards on some Pentium systems,
+	 *     (see c't 95/10 page 335 for Neptun bug.)
+	 *
+	 * Previous attempts to handle these cases intelligently were
+	 * buggy, so we just do the simple thing now.
+	 */
+	if (count > old_count && jifs == old_jifs)
+		count = old_count;
+
+	old_count = count;
+	old_jifs = jifs;
+
+	raw_spin_unlock_irqrestore(&i8253_lock, flags);
+
+	count = (PIT_LATCH - 1) - count;
+
+	return (cycle_t)(jifs * PIT_LATCH) + count;
+}
+
+static struct clocksource i8253_cs = {
+	.name		= "pit",
+	.rating		= 110,
+	.read		= i8253_read,
+	.mask		= CLOCKSOURCE_MASK(32),
+};
+
+int __init clocksource_i8253_init(void)
+{
+	return clocksource_register_hz(&i8253_cs, PIT_TICK_RATE);
+}
diff -druN linux-2.6.39-libre/drivers/clocksource/Kconfig linux-3.0-rc7-libre/drivers/clocksource/Kconfig
--- linux-2.6.39-libre/drivers/clocksource/Kconfig	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/clocksource/Kconfig	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,5 @@
+config CLKSRC_I8253
+	bool
+
+config CLKSRC_MMIO
+	bool
diff -druN linux-2.6.39-libre/drivers/clocksource/Makefile linux-3.0-rc7-libre/drivers/clocksource/Makefile
--- linux-2.6.39-libre/drivers/clocksource/Makefile	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/clocksource/Makefile	2011-07-11 19:51:52.000000000 -0400
@@ -6,3 +6,5 @@
 obj-$(CONFIG_SH_TIMER_CMT)	+= sh_cmt.o
 obj-$(CONFIG_SH_TIMER_MTU2)	+= sh_mtu2.o
 obj-$(CONFIG_SH_TIMER_TMU)	+= sh_tmu.o
+obj-$(CONFIG_CLKSRC_I8253)	+= i8253.o
+obj-$(CONFIG_CLKSRC_MMIO)	+= mmio.o
diff -druN linux-2.6.39-libre/drivers/clocksource/mmio.c linux-3.0-rc7-libre/drivers/clocksource/mmio.c
--- linux-2.6.39-libre/drivers/clocksource/mmio.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/clocksource/mmio.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,73 @@
+/*
+ * Generic MMIO clocksource 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/clocksource.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+
+struct clocksource_mmio {
+	void __iomem *reg;
+	struct clocksource clksrc;
+};
+
+static inline struct clocksource_mmio *to_mmio_clksrc(struct clocksource *c)
+{
+	return container_of(c, struct clocksource_mmio, clksrc);
+}
+
+cycle_t clocksource_mmio_readl_up(struct clocksource *c)
+{
+	return readl_relaxed(to_mmio_clksrc(c)->reg);
+}
+
+cycle_t clocksource_mmio_readl_down(struct clocksource *c)
+{
+	return ~readl_relaxed(to_mmio_clksrc(c)->reg);
+}
+
+cycle_t clocksource_mmio_readw_up(struct clocksource *c)
+{
+	return readw_relaxed(to_mmio_clksrc(c)->reg);
+}
+
+cycle_t clocksource_mmio_readw_down(struct clocksource *c)
+{
+	return ~(unsigned)readw_relaxed(to_mmio_clksrc(c)->reg);
+}
+
+/**
+ * clocksource_mmio_init - Initialize a simple mmio based clocksource
+ * @base:	Virtual address of the clock readout register
+ * @name:	Name of the clocksource
+ * @hz:		Frequency of the clocksource in Hz
+ * @rating:	Rating of the clocksource
+ * @bits:	Number of valid bits
+ * @read:	One of clocksource_mmio_read*() above
+ */
+int __init clocksource_mmio_init(void __iomem *base, const char *name,
+	unsigned long hz, int rating, unsigned bits,
+	cycle_t (*read)(struct clocksource *))
+{
+	struct clocksource_mmio *cs;
+
+	if (bits > 32 || bits < 16)
+		return -EINVAL;
+
+	cs = kzalloc(sizeof(struct clocksource_mmio), GFP_KERNEL);
+	if (!cs)
+		return -ENOMEM;
+
+	cs->reg = base;
+	cs->clksrc.name = name;
+	cs->clksrc.rating = rating;
+	cs->clksrc.read = read;
+	cs->clksrc.mask = CLOCKSOURCE_MASK(bits);
+	cs->clksrc.flags = CLOCK_SOURCE_IS_CONTINUOUS;
+
+	return clocksource_register_hz(&cs->clksrc, hz);
+}
diff -druN linux-2.6.39-libre/drivers/clocksource/sh_cmt.c linux-3.0-rc7-libre/drivers/clocksource/sh_cmt.c
--- linux-2.6.39-libre/drivers/clocksource/sh_cmt.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/clocksource/sh_cmt.c	2011-07-11 19:51:52.000000000 -0400
@@ -416,11 +416,15 @@
 
 static int sh_cmt_clocksource_enable(struct clocksource *cs)
 {
+	int ret;
 	struct sh_cmt_priv *p = cs_to_sh_cmt(cs);
 
 	p->total_cycles = 0;
 
-	return sh_cmt_start(p, FLAG_CLOCKSOURCE);
+	ret = sh_cmt_start(p, FLAG_CLOCKSOURCE);
+	if (!ret)
+		__clocksource_updatefreq_hz(cs, p->rate);
+	return ret;
 }
 
 static void sh_cmt_clocksource_disable(struct clocksource *cs)
@@ -448,19 +452,10 @@
 	cs->mask = CLOCKSOURCE_MASK(sizeof(unsigned long) * 8);
 	cs->flags = CLOCK_SOURCE_IS_CONTINUOUS;
 
-	/* clk_get_rate() needs an enabled clock */
-	clk_enable(p->clk);
-	p->rate = clk_get_rate(p->clk) / ((p->width == 16) ? 512 : 8);
-	clk_disable(p->clk);
-
-	/* TODO: calculate good shift from rate and counter bit width */
-	cs->shift = 0;
-	cs->mult = clocksource_hz2mult(p->rate, cs->shift);
-
 	dev_info(&p->pdev->dev, "used as clock source\n");
 
-	clocksource_register(cs);
-
+	/* Register with dummy 1 Hz value, gets updated in ->enable() */
+	clocksource_register_hz(cs, 1);
 	return 0;
 }
 
diff -druN linux-2.6.39-libre/drivers/clocksource/sh_tmu.c linux-3.0-rc7-libre/drivers/clocksource/sh_tmu.c
--- linux-2.6.39-libre/drivers/clocksource/sh_tmu.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/clocksource/sh_tmu.c	2011-07-11 19:51:52.000000000 -0400
@@ -199,8 +199,12 @@
 static int sh_tmu_clocksource_enable(struct clocksource *cs)
 {
 	struct sh_tmu_priv *p = cs_to_sh_tmu(cs);
+	int ret;
 
-	return sh_tmu_enable(p);
+	ret = sh_tmu_enable(p);
+	if (!ret)
+		__clocksource_updatefreq_hz(cs, p->rate);
+	return ret;
 }
 
 static void sh_tmu_clocksource_disable(struct clocksource *cs)
@@ -221,17 +225,10 @@
 	cs->mask = CLOCKSOURCE_MASK(32);
 	cs->flags = CLOCK_SOURCE_IS_CONTINUOUS;
 
-	/* clk_get_rate() needs an enabled clock */
-	clk_enable(p->clk);
-	/* channel will be configured at parent clock / 4 */
-	p->rate = clk_get_rate(p->clk) / 4;
-	clk_disable(p->clk);
-	/* TODO: calculate good shift from rate and counter bit width */
-	cs->shift = 10;
-	cs->mult = clocksource_hz2mult(p->rate, cs->shift);
-
 	dev_info(&p->pdev->dev, "used as clock source\n");
-	clocksource_register(cs);
+
+	/* Register with dummy 1 Hz value, gets updated in ->enable() */
+	clocksource_register_hz(cs, 1);
 	return 0;
 }
 
diff -druN linux-2.6.39-libre/drivers/connector/connector.c linux-3.0-rc7-libre/drivers/connector/connector.c
--- linux-2.6.39-libre/drivers/connector/connector.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/connector/connector.c	2011-07-11 19:51:52.000000000 -0400
@@ -139,6 +139,7 @@
 	spin_unlock_bh(&dev->cbdev->queue_lock);
 
 	if (cbq != NULL) {
+		err = 0;
 		cbq->callback(msg, nsp);
 		kfree_skb(skb);
 		cn_queue_release_callback(cbq);
diff -druN linux-2.6.39-libre/drivers/cpufreq/acpi-cpufreq.c linux-3.0-rc7-libre/drivers/cpufreq/acpi-cpufreq.c
--- linux-2.6.39-libre/drivers/cpufreq/acpi-cpufreq.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/cpufreq/acpi-cpufreq.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,773 @@
+/*
+ * acpi-cpufreq.c - ACPI Processor P-States Driver
+ *
+ *  Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com>
+ *  Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
+ *  Copyright (C) 2002 - 2004 Dominik Brodowski <linux@brodo.de>
+ *  Copyright (C) 2006       Denis Sadykov <denis.m.sadykov@intel.com>
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or (at
+ *  your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful, but
+ *  WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/smp.h>
+#include <linux/sched.h>
+#include <linux/cpufreq.h>
+#include <linux/compiler.h>
+#include <linux/dmi.h>
+#include <linux/slab.h>
+
+#include <linux/acpi.h>
+#include <linux/io.h>
+#include <linux/delay.h>
+#include <linux/uaccess.h>
+
+#include <acpi/processor.h>
+
+#include <asm/msr.h>
+#include <asm/processor.h>
+#include <asm/cpufeature.h>
+#include "mperf.h"
+
+MODULE_AUTHOR("Paul Diefenbaugh, Dominik Brodowski");
+MODULE_DESCRIPTION("ACPI Processor P-States Driver");
+MODULE_LICENSE("GPL");
+
+enum {
+	UNDEFINED_CAPABLE = 0,
+	SYSTEM_INTEL_MSR_CAPABLE,
+	SYSTEM_IO_CAPABLE,
+};
+
+#define INTEL_MSR_RANGE		(0xffff)
+
+struct acpi_cpufreq_data {
+	struct acpi_processor_performance *acpi_data;
+	struct cpufreq_frequency_table *freq_table;
+	unsigned int resume;
+	unsigned int cpu_feature;
+};
+
+static DEFINE_PER_CPU(struct acpi_cpufreq_data *, acfreq_data);
+
+/* acpi_perf_data is a pointer to percpu data. */
+static struct acpi_processor_performance __percpu *acpi_perf_data;
+
+static struct cpufreq_driver acpi_cpufreq_driver;
+
+static unsigned int acpi_pstate_strict;
+
+static int check_est_cpu(unsigned int cpuid)
+{
+	struct cpuinfo_x86 *cpu = &cpu_data(cpuid);
+
+	return cpu_has(cpu, X86_FEATURE_EST);
+}
+
+static unsigned extract_io(u32 value, struct acpi_cpufreq_data *data)
+{
+	struct acpi_processor_performance *perf;
+	int i;
+
+	perf = data->acpi_data;
+
+	for (i = 0; i < perf->state_count; i++) {
+		if (value == perf->states[i].status)
+			return data->freq_table[i].frequency;
+	}
+	return 0;
+}
+
+static unsigned extract_msr(u32 msr, struct acpi_cpufreq_data *data)
+{
+	int i;
+	struct acpi_processor_performance *perf;
+
+	msr &= INTEL_MSR_RANGE;
+	perf = data->acpi_data;
+
+	for (i = 0; data->freq_table[i].frequency != CPUFREQ_TABLE_END; i++) {
+		if (msr == perf->states[data->freq_table[i].index].status)
+			return data->freq_table[i].frequency;
+	}
+	return data->freq_table[0].frequency;
+}
+
+static unsigned extract_freq(u32 val, struct acpi_cpufreq_data *data)
+{
+	switch (data->cpu_feature) {
+	case SYSTEM_INTEL_MSR_CAPABLE:
+		return extract_msr(val, data);
+	case SYSTEM_IO_CAPABLE:
+		return extract_io(val, data);
+	default:
+		return 0;
+	}
+}
+
+struct msr_addr {
+	u32 reg;
+};
+
+struct io_addr {
+	u16 port;
+	u8 bit_width;
+};
+
+struct drv_cmd {
+	unsigned int type;
+	const struct cpumask *mask;
+	union {
+		struct msr_addr msr;
+		struct io_addr io;
+	} addr;
+	u32 val;
+};
+
+/* Called via smp_call_function_single(), on the target CPU */
+static void do_drv_read(void *_cmd)
+{
+	struct drv_cmd *cmd = _cmd;
+	u32 h;
+
+	switch (cmd->type) {
+	case SYSTEM_INTEL_MSR_CAPABLE:
+		rdmsr(cmd->addr.msr.reg, cmd->val, h);
+		break;
+	case SYSTEM_IO_CAPABLE:
+		acpi_os_read_port((acpi_io_address)cmd->addr.io.port,
+				&cmd->val,
+				(u32)cmd->addr.io.bit_width);
+		break;
+	default:
+		break;
+	}
+}
+
+/* Called via smp_call_function_many(), on the target CPUs */
+static void do_drv_write(void *_cmd)
+{
+	struct drv_cmd *cmd = _cmd;
+	u32 lo, hi;
+
+	switch (cmd->type) {
+	case SYSTEM_INTEL_MSR_CAPABLE:
+		rdmsr(cmd->addr.msr.reg, lo, hi);
+		lo = (lo & ~INTEL_MSR_RANGE) | (cmd->val & INTEL_MSR_RANGE);
+		wrmsr(cmd->addr.msr.reg, lo, hi);
+		break;
+	case SYSTEM_IO_CAPABLE:
+		acpi_os_write_port((acpi_io_address)cmd->addr.io.port,
+				cmd->val,
+				(u32)cmd->addr.io.bit_width);
+		break;
+	default:
+		break;
+	}
+}
+
+static void drv_read(struct drv_cmd *cmd)
+{
+	int err;
+	cmd->val = 0;
+
+	err = smp_call_function_any(cmd->mask, do_drv_read, cmd, 1);
+	WARN_ON_ONCE(err);	/* smp_call_function_any() was buggy? */
+}
+
+static void drv_write(struct drv_cmd *cmd)
+{
+	int this_cpu;
+
+	this_cpu = get_cpu();
+	if (cpumask_test_cpu(this_cpu, cmd->mask))
+		do_drv_write(cmd);
+	smp_call_function_many(cmd->mask, do_drv_write, cmd, 1);
+	put_cpu();
+}
+
+static u32 get_cur_val(const struct cpumask *mask)
+{
+	struct acpi_processor_performance *perf;
+	struct drv_cmd cmd;
+
+	if (unlikely(cpumask_empty(mask)))
+		return 0;
+
+	switch (per_cpu(acfreq_data, cpumask_first(mask))->cpu_feature) {
+	case SYSTEM_INTEL_MSR_CAPABLE:
+		cmd.type = SYSTEM_INTEL_MSR_CAPABLE;
+		cmd.addr.msr.reg = MSR_IA32_PERF_STATUS;
+		break;
+	case SYSTEM_IO_CAPABLE:
+		cmd.type = SYSTEM_IO_CAPABLE;
+		perf = per_cpu(acfreq_data, cpumask_first(mask))->acpi_data;
+		cmd.addr.io.port = perf->control_register.address;
+		cmd.addr.io.bit_width = perf->control_register.bit_width;
+		break;
+	default:
+		return 0;
+	}
+
+	cmd.mask = mask;
+	drv_read(&cmd);
+
+	pr_debug("get_cur_val = %u\n", cmd.val);
+
+	return cmd.val;
+}
+
+static unsigned int get_cur_freq_on_cpu(unsigned int cpu)
+{
+	struct acpi_cpufreq_data *data = per_cpu(acfreq_data, cpu);
+	unsigned int freq;
+	unsigned int cached_freq;
+
+	pr_debug("get_cur_freq_on_cpu (%d)\n", cpu);
+
+	if (unlikely(data == NULL ||
+		     data->acpi_data == NULL || data->freq_table == NULL)) {
+		return 0;
+	}
+
+	cached_freq = data->freq_table[data->acpi_data->state].frequency;
+	freq = extract_freq(get_cur_val(cpumask_of(cpu)), data);
+	if (freq != cached_freq) {
+		/*
+		 * The dreaded BIOS frequency change behind our back.
+		 * Force set the frequency on next target call.
+		 */
+		data->resume = 1;
+	}
+
+	pr_debug("cur freq = %u\n", freq);
+
+	return freq;
+}
+
+static unsigned int check_freqs(const struct cpumask *mask, unsigned int freq,
+				struct acpi_cpufreq_data *data)
+{
+	unsigned int cur_freq;
+	unsigned int i;
+
+	for (i = 0; i < 100; i++) {
+		cur_freq = extract_freq(get_cur_val(mask), data);
+		if (cur_freq == freq)
+			return 1;
+		udelay(10);
+	}
+	return 0;
+}
+
+static int acpi_cpufreq_target(struct cpufreq_policy *policy,
+			       unsigned int target_freq, unsigned int relation)
+{
+	struct acpi_cpufreq_data *data = per_cpu(acfreq_data, policy->cpu);
+	struct acpi_processor_performance *perf;
+	struct cpufreq_freqs freqs;
+	struct drv_cmd cmd;
+	unsigned int next_state = 0; /* Index into freq_table */
+	unsigned int next_perf_state = 0; /* Index into perf table */
+	unsigned int i;
+	int result = 0;
+
+	pr_debug("acpi_cpufreq_target %d (%d)\n", target_freq, policy->cpu);
+
+	if (unlikely(data == NULL ||
+	     data->acpi_data == NULL || data->freq_table == NULL)) {
+		return -ENODEV;
+	}
+
+	perf = data->acpi_data;
+	result = cpufreq_frequency_table_target(policy,
+						data->freq_table,
+						target_freq,
+						relation, &next_state);
+	if (unlikely(result)) {
+		result = -ENODEV;
+		goto out;
+	}
+
+	next_perf_state = data->freq_table[next_state].index;
+	if (perf->state == next_perf_state) {
+		if (unlikely(data->resume)) {
+			pr_debug("Called after resume, resetting to P%d\n",
+				next_perf_state);
+			data->resume = 0;
+		} else {
+			pr_debug("Already at target state (P%d)\n",
+				next_perf_state);
+			goto out;
+		}
+	}
+
+	switch (data->cpu_feature) {
+	case SYSTEM_INTEL_MSR_CAPABLE:
+		cmd.type = SYSTEM_INTEL_MSR_CAPABLE;
+		cmd.addr.msr.reg = MSR_IA32_PERF_CTL;
+		cmd.val = (u32) perf->states[next_perf_state].control;
+		break;
+	case SYSTEM_IO_CAPABLE:
+		cmd.type = SYSTEM_IO_CAPABLE;
+		cmd.addr.io.port = perf->control_register.address;
+		cmd.addr.io.bit_width = perf->control_register.bit_width;
+		cmd.val = (u32) perf->states[next_perf_state].control;
+		break;
+	default:
+		result = -ENODEV;
+		goto out;
+	}
+
+	/* cpufreq holds the hotplug lock, so we are safe from here on */
+	if (policy->shared_type != CPUFREQ_SHARED_TYPE_ANY)
+		cmd.mask = policy->cpus;
+	else
+		cmd.mask = cpumask_of(policy->cpu);
+
+	freqs.old = perf->states[perf->state].core_frequency * 1000;
+	freqs.new = data->freq_table[next_state].frequency;
+	for_each_cpu(i, policy->cpus) {
+		freqs.cpu = i;
+		cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
+	}
+
+	drv_write(&cmd);
+
+	if (acpi_pstate_strict) {
+		if (!check_freqs(cmd.mask, freqs.new, data)) {
+			pr_debug("acpi_cpufreq_target failed (%d)\n",
+				policy->cpu);
+			result = -EAGAIN;
+			goto out;
+		}
+	}
+
+	for_each_cpu(i, policy->cpus) {
+		freqs.cpu = i;
+		cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
+	}
+	perf->state = next_perf_state;
+
+out:
+	return result;
+}
+
+static int acpi_cpufreq_verify(struct cpufreq_policy *policy)
+{
+	struct acpi_cpufreq_data *data = per_cpu(acfreq_data, policy->cpu);
+
+	pr_debug("acpi_cpufreq_verify\n");
+
+	return cpufreq_frequency_table_verify(policy, data->freq_table);
+}
+
+static unsigned long
+acpi_cpufreq_guess_freq(struct acpi_cpufreq_data *data, unsigned int cpu)
+{
+	struct acpi_processor_performance *perf = data->acpi_data;
+
+	if (cpu_khz) {
+		/* search the closest match to cpu_khz */
+		unsigned int i;
+		unsigned long freq;
+		unsigned long freqn = perf->states[0].core_frequency * 1000;
+
+		for (i = 0; i < (perf->state_count-1); i++) {
+			freq = freqn;
+			freqn = perf->states[i+1].core_frequency * 1000;
+			if ((2 * cpu_khz) > (freqn + freq)) {
+				perf->state = i;
+				return freq;
+			}
+		}
+		perf->state = perf->state_count-1;
+		return freqn;
+	} else {
+		/* assume CPU is at P0... */
+		perf->state = 0;
+		return perf->states[0].core_frequency * 1000;
+	}
+}
+
+static void free_acpi_perf_data(void)
+{
+	unsigned int i;
+
+	/* Freeing a NULL pointer is OK, and alloc_percpu zeroes. */
+	for_each_possible_cpu(i)
+		free_cpumask_var(per_cpu_ptr(acpi_perf_data, i)
+				 ->shared_cpu_map);
+	free_percpu(acpi_perf_data);
+}
+
+/*
+ * acpi_cpufreq_early_init - initialize ACPI P-States library
+ *
+ * Initialize the ACPI P-States library (drivers/acpi/processor_perflib.c)
+ * in order to determine correct frequency and voltage pairings. We can
+ * do _PDC and _PSD and find out the processor dependency for the
+ * actual init that will happen later...
+ */
+static int __init acpi_cpufreq_early_init(void)
+{
+	unsigned int i;
+	pr_debug("acpi_cpufreq_early_init\n");
+
+	acpi_perf_data = alloc_percpu(struct acpi_processor_performance);
+	if (!acpi_perf_data) {
+		pr_debug("Memory allocation error for acpi_perf_data.\n");
+		return -ENOMEM;
+	}
+	for_each_possible_cpu(i) {
+		if (!zalloc_cpumask_var_node(
+			&per_cpu_ptr(acpi_perf_data, i)->shared_cpu_map,
+			GFP_KERNEL, cpu_to_node(i))) {
+
+			/* Freeing a NULL pointer is OK: alloc_percpu zeroes. */
+			free_acpi_perf_data();
+			return -ENOMEM;
+		}
+	}
+
+	/* Do initialization in ACPI core */
+	acpi_processor_preregister_performance(acpi_perf_data);
+	return 0;
+}
+
+#ifdef CONFIG_SMP
+/*
+ * Some BIOSes do SW_ANY coordination internally, either set it up in hw
+ * or do it in BIOS firmware and won't inform about it to OS. If not
+ * detected, this has a side effect of making CPU run at a different speed
+ * than OS intended it to run at. Detect it and handle it cleanly.
+ */
+static int bios_with_sw_any_bug;
+
+static int sw_any_bug_found(const struct dmi_system_id *d)
+{
+	bios_with_sw_any_bug = 1;
+	return 0;
+}
+
+static const struct dmi_system_id sw_any_bug_dmi_table[] = {
+	{
+		.callback = sw_any_bug_found,
+		.ident = "Supermicro Server X6DLP",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Supermicro"),
+			DMI_MATCH(DMI_BIOS_VERSION, "080010"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "X6DLP"),
+		},
+	},
+	{ }
+};
+
+static int acpi_cpufreq_blacklist(struct cpuinfo_x86 *c)
+{
+	/* Intel Xeon Processor 7100 Series Specification Update
+	 * http://www.intel.com/Assets/PDF/specupdate/314554.pdf
+	 * AL30: A Machine Check Exception (MCE) Occurring during an
+	 * Enhanced Intel SpeedStep Technology Ratio Change May Cause
+	 * Both Processor Cores to Lock Up. */
+	if (c->x86_vendor == X86_VENDOR_INTEL) {
+		if ((c->x86 == 15) &&
+		    (c->x86_model == 6) &&
+		    (c->x86_mask == 8)) {
+			printk(KERN_INFO "acpi-cpufreq: Intel(R) "
+			    "Xeon(R) 7100 Errata AL30, processors may "
+			    "lock up on frequency changes: disabling "
+			    "acpi-cpufreq.\n");
+			return -ENODEV;
+		    }
+		}
+	return 0;
+}
+#endif
+
+static int acpi_cpufreq_cpu_init(struct cpufreq_policy *policy)
+{
+	unsigned int i;
+	unsigned int valid_states = 0;
+	unsigned int cpu = policy->cpu;
+	struct acpi_cpufreq_data *data;
+	unsigned int result = 0;
+	struct cpuinfo_x86 *c = &cpu_data(policy->cpu);
+	struct acpi_processor_performance *perf;
+#ifdef CONFIG_SMP
+	static int blacklisted;
+#endif
+
+	pr_debug("acpi_cpufreq_cpu_init\n");
+
+#ifdef CONFIG_SMP
+	if (blacklisted)
+		return blacklisted;
+	blacklisted = acpi_cpufreq_blacklist(c);
+	if (blacklisted)
+		return blacklisted;
+#endif
+
+	data = kzalloc(sizeof(struct acpi_cpufreq_data), GFP_KERNEL);
+	if (!data)
+		return -ENOMEM;
+
+	data->acpi_data = per_cpu_ptr(acpi_perf_data, cpu);
+	per_cpu(acfreq_data, cpu) = data;
+
+	if (cpu_has(c, X86_FEATURE_CONSTANT_TSC))
+		acpi_cpufreq_driver.flags |= CPUFREQ_CONST_LOOPS;
+
+	result = acpi_processor_register_performance(data->acpi_data, cpu);
+	if (result)
+		goto err_free;
+
+	perf = data->acpi_data;
+	policy->shared_type = perf->shared_type;
+
+	/*
+	 * Will let policy->cpus know about dependency only when software
+	 * coordination is required.
+	 */
+	if (policy->shared_type == CPUFREQ_SHARED_TYPE_ALL ||
+	    policy->shared_type == CPUFREQ_SHARED_TYPE_ANY) {
+		cpumask_copy(policy->cpus, perf->shared_cpu_map);
+	}
+	cpumask_copy(policy->related_cpus, perf->shared_cpu_map);
+
+#ifdef CONFIG_SMP
+	dmi_check_system(sw_any_bug_dmi_table);
+	if (bios_with_sw_any_bug && cpumask_weight(policy->cpus) == 1) {
+		policy->shared_type = CPUFREQ_SHARED_TYPE_ALL;
+		cpumask_copy(policy->cpus, cpu_core_mask(cpu));
+	}
+#endif
+
+	/* capability check */
+	if (perf->state_count <= 1) {
+		pr_debug("No P-States\n");
+		result = -ENODEV;
+		goto err_unreg;
+	}
+
+	if (perf->control_register.space_id != perf->status_register.space_id) {
+		result = -ENODEV;
+		goto err_unreg;
+	}
+
+	switch (perf->control_register.space_id) {
+	case ACPI_ADR_SPACE_SYSTEM_IO:
+		pr_debug("SYSTEM IO addr space\n");
+		data->cpu_feature = SYSTEM_IO_CAPABLE;
+		break;
+	case ACPI_ADR_SPACE_FIXED_HARDWARE:
+		pr_debug("HARDWARE addr space\n");
+		if (!check_est_cpu(cpu)) {
+			result = -ENODEV;
+			goto err_unreg;
+		}
+		data->cpu_feature = SYSTEM_INTEL_MSR_CAPABLE;
+		break;
+	default:
+		pr_debug("Unknown addr space %d\n",
+			(u32) (perf->control_register.space_id));
+		result = -ENODEV;
+		goto err_unreg;
+	}
+
+	data->freq_table = kmalloc(sizeof(struct cpufreq_frequency_table) *
+		    (perf->state_count+1), GFP_KERNEL);
+	if (!data->freq_table) {
+		result = -ENOMEM;
+		goto err_unreg;
+	}
+
+	/* detect transition latency */
+	policy->cpuinfo.transition_latency = 0;
+	for (i = 0; i < perf->state_count; i++) {
+		if ((perf->states[i].transition_latency * 1000) >
+		    policy->cpuinfo.transition_latency)
+			policy->cpuinfo.transition_latency =
+			    perf->states[i].transition_latency * 1000;
+	}
+
+	/* Check for high latency (>20uS) from buggy BIOSes, like on T42 */
+	if (perf->control_register.space_id == ACPI_ADR_SPACE_FIXED_HARDWARE &&
+	    policy->cpuinfo.transition_latency > 20 * 1000) {
+		policy->cpuinfo.transition_latency = 20 * 1000;
+		printk_once(KERN_INFO
+			    "P-state transition latency capped at 20 uS\n");
+	}
+
+	/* table init */
+	for (i = 0; i < perf->state_count; i++) {
+		if (i > 0 && perf->states[i].core_frequency >=
+		    data->freq_table[valid_states-1].frequency / 1000)
+			continue;
+
+		data->freq_table[valid_states].index = i;
+		data->freq_table[valid_states].frequency =
+		    perf->states[i].core_frequency * 1000;
+		valid_states++;
+	}
+	data->freq_table[valid_states].frequency = CPUFREQ_TABLE_END;
+	perf->state = 0;
+
+	result = cpufreq_frequency_table_cpuinfo(policy, data->freq_table);
+	if (result)
+		goto err_freqfree;
+
+	if (perf->states[0].core_frequency * 1000 != policy->cpuinfo.max_freq)
+		printk(KERN_WARNING FW_WARN "P-state 0 is not max freq\n");
+
+	switch (perf->control_register.space_id) {
+	case ACPI_ADR_SPACE_SYSTEM_IO:
+		/* Current speed is unknown and not detectable by IO port */
+		policy->cur = acpi_cpufreq_guess_freq(data, policy->cpu);
+		break;
+	case ACPI_ADR_SPACE_FIXED_HARDWARE:
+		acpi_cpufreq_driver.get = get_cur_freq_on_cpu;
+		policy->cur = get_cur_freq_on_cpu(cpu);
+		break;
+	default:
+		break;
+	}
+
+	/* notify BIOS that we exist */
+	acpi_processor_notify_smm(THIS_MODULE);
+
+	/* Check for APERF/MPERF support in hardware */
+	if (cpu_has(c, X86_FEATURE_APERFMPERF))
+		acpi_cpufreq_driver.getavg = cpufreq_get_measured_perf;
+
+	pr_debug("CPU%u - ACPI performance management activated.\n", cpu);
+	for (i = 0; i < perf->state_count; i++)
+		pr_debug("     %cP%d: %d MHz, %d mW, %d uS\n",
+			(i == perf->state ? '*' : ' '), i,
+			(u32) perf->states[i].core_frequency,
+			(u32) perf->states[i].power,
+			(u32) perf->states[i].transition_latency);
+
+	cpufreq_frequency_table_get_attr(data->freq_table, policy->cpu);
+
+	/*
+	 * the first call to ->target() should result in us actually
+	 * writing something to the appropriate registers.
+	 */
+	data->resume = 1;
+
+	return result;
+
+err_freqfree:
+	kfree(data->freq_table);
+err_unreg:
+	acpi_processor_unregister_performance(perf, cpu);
+err_free:
+	kfree(data);
+	per_cpu(acfreq_data, cpu) = NULL;
+
+	return result;
+}
+
+static int acpi_cpufreq_cpu_exit(struct cpufreq_policy *policy)
+{
+	struct acpi_cpufreq_data *data = per_cpu(acfreq_data, policy->cpu);
+
+	pr_debug("acpi_cpufreq_cpu_exit\n");
+
+	if (data) {
+		cpufreq_frequency_table_put_attr(policy->cpu);
+		per_cpu(acfreq_data, policy->cpu) = NULL;
+		acpi_processor_unregister_performance(data->acpi_data,
+						      policy->cpu);
+		kfree(data->freq_table);
+		kfree(data);
+	}
+
+	return 0;
+}
+
+static int acpi_cpufreq_resume(struct cpufreq_policy *policy)
+{
+	struct acpi_cpufreq_data *data = per_cpu(acfreq_data, policy->cpu);
+
+	pr_debug("acpi_cpufreq_resume\n");
+
+	data->resume = 1;
+
+	return 0;
+}
+
+static struct freq_attr *acpi_cpufreq_attr[] = {
+	&cpufreq_freq_attr_scaling_available_freqs,
+	NULL,
+};
+
+static struct cpufreq_driver acpi_cpufreq_driver = {
+	.verify		= acpi_cpufreq_verify,
+	.target		= acpi_cpufreq_target,
+	.bios_limit	= acpi_processor_get_bios_limit,
+	.init		= acpi_cpufreq_cpu_init,
+	.exit		= acpi_cpufreq_cpu_exit,
+	.resume		= acpi_cpufreq_resume,
+	.name		= "acpi-cpufreq",
+	.owner		= THIS_MODULE,
+	.attr		= acpi_cpufreq_attr,
+};
+
+static int __init acpi_cpufreq_init(void)
+{
+	int ret;
+
+	if (acpi_disabled)
+		return 0;
+
+	pr_debug("acpi_cpufreq_init\n");
+
+	ret = acpi_cpufreq_early_init();
+	if (ret)
+		return ret;
+
+	ret = cpufreq_register_driver(&acpi_cpufreq_driver);
+	if (ret)
+		free_acpi_perf_data();
+
+	return ret;
+}
+
+static void __exit acpi_cpufreq_exit(void)
+{
+	pr_debug("acpi_cpufreq_exit\n");
+
+	cpufreq_unregister_driver(&acpi_cpufreq_driver);
+
+	free_acpi_perf_data();
+}
+
+module_param(acpi_pstate_strict, uint, 0644);
+MODULE_PARM_DESC(acpi_pstate_strict,
+	"value 0 or non-zero. non-zero -> strict ACPI checks are "
+	"performed during frequency changes.");
+
+late_initcall(acpi_cpufreq_init);
+module_exit(acpi_cpufreq_exit);
+
+MODULE_ALIAS("acpi");
diff -druN linux-2.6.39-libre/drivers/cpufreq/cpufreq.c linux-3.0-rc7-libre/drivers/cpufreq/cpufreq.c
--- linux-2.6.39-libre/drivers/cpufreq/cpufreq.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/cpufreq/cpufreq.c	2011-07-11 19:51:52.000000000 -0400
@@ -32,9 +32,6 @@
 
 #include <trace/events/power.h>
 
-#define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_CORE, \
-						"cpufreq-core", msg)
-
 /**
  * The "cpufreq driver" - the arch- or hardware-dependent low
  * level driver of CPUFreq support, and its spinlock. This lock
@@ -181,93 +178,6 @@
 
 
 /*********************************************************************
- *                     UNIFIED DEBUG HELPERS                         *
- *********************************************************************/
-#ifdef CONFIG_CPU_FREQ_DEBUG
-
-/* what part(s) of the CPUfreq subsystem are debugged? */
-static unsigned int debug;
-
-/* is the debug output ratelimit'ed using printk_ratelimit? User can
- * set or modify this value.
- */
-static unsigned int debug_ratelimit = 1;
-
-/* is the printk_ratelimit'ing enabled? It's enabled after a successful
- * loading of a cpufreq driver, temporarily disabled when a new policy
- * is set, and disabled upon cpufreq driver removal
- */
-static unsigned int disable_ratelimit = 1;
-static DEFINE_SPINLOCK(disable_ratelimit_lock);
-
-static void cpufreq_debug_enable_ratelimit(void)
-{
-	unsigned long flags;
-
-	spin_lock_irqsave(&disable_ratelimit_lock, flags);
-	if (disable_ratelimit)
-		disable_ratelimit--;
-	spin_unlock_irqrestore(&disable_ratelimit_lock, flags);
-}
-
-static void cpufreq_debug_disable_ratelimit(void)
-{
-	unsigned long flags;
-
-	spin_lock_irqsave(&disable_ratelimit_lock, flags);
-	disable_ratelimit++;
-	spin_unlock_irqrestore(&disable_ratelimit_lock, flags);
-}
-
-void cpufreq_debug_printk(unsigned int type, const char *prefix,
-			const char *fmt, ...)
-{
-	char s[256];
-	va_list args;
-	unsigned int len;
-	unsigned long flags;
-
-	WARN_ON(!prefix);
-	if (type & debug) {
-		spin_lock_irqsave(&disable_ratelimit_lock, flags);
-		if (!disable_ratelimit && debug_ratelimit
-					&& !printk_ratelimit()) {
-			spin_unlock_irqrestore(&disable_ratelimit_lock, flags);
-			return;
-		}
-		spin_unlock_irqrestore(&disable_ratelimit_lock, flags);
-
-		len = snprintf(s, 256, KERN_DEBUG "%s: ", prefix);
-
-		va_start(args, fmt);
-		len += vsnprintf(&s[len], (256 - len), fmt, args);
-		va_end(args);
-
-		printk(s);
-
-		WARN_ON(len < 5);
-	}
-}
-EXPORT_SYMBOL(cpufreq_debug_printk);
-
-
-module_param(debug, uint, 0644);
-MODULE_PARM_DESC(debug, "CPUfreq debugging: add 1 to debug core,"
-			" 2 to debug drivers, and 4 to debug governors.");
-
-module_param(debug_ratelimit, uint, 0644);
-MODULE_PARM_DESC(debug_ratelimit, "CPUfreq debugging:"
-					" set to 0 to disable ratelimiting.");
-
-#else /* !CONFIG_CPU_FREQ_DEBUG */
-
-static inline void cpufreq_debug_enable_ratelimit(void) { return; }
-static inline void cpufreq_debug_disable_ratelimit(void) { return; }
-
-#endif /* CONFIG_CPU_FREQ_DEBUG */
-
-
-/*********************************************************************
  *            EXTERNALLY AFFECTING FREQUENCY CHANGES                 *
  *********************************************************************/
 
@@ -291,7 +201,7 @@
 	if (!l_p_j_ref_freq) {
 		l_p_j_ref = loops_per_jiffy;
 		l_p_j_ref_freq = ci->old;
-		dprintk("saving %lu as reference value for loops_per_jiffy; "
+		pr_debug("saving %lu as reference value for loops_per_jiffy; "
 			"freq is %u kHz\n", l_p_j_ref, l_p_j_ref_freq);
 	}
 	if ((val == CPUFREQ_PRECHANGE  && ci->old < ci->new) ||
@@ -299,7 +209,7 @@
 	    (val == CPUFREQ_RESUMECHANGE || val == CPUFREQ_SUSPENDCHANGE)) {
 		loops_per_jiffy = cpufreq_scale(l_p_j_ref, l_p_j_ref_freq,
 								ci->new);
-		dprintk("scaling loops_per_jiffy to %lu "
+		pr_debug("scaling loops_per_jiffy to %lu "
 			"for frequency %u kHz\n", loops_per_jiffy, ci->new);
 	}
 }
@@ -326,7 +236,7 @@
 	BUG_ON(irqs_disabled());
 
 	freqs->flags = cpufreq_driver->flags;
-	dprintk("notification %u of frequency transition to %u kHz\n",
+	pr_debug("notification %u of frequency transition to %u kHz\n",
 		state, freqs->new);
 
 	policy = per_cpu(cpufreq_cpu_data, freqs->cpu);
@@ -340,7 +250,7 @@
 		if (!(cpufreq_driver->flags & CPUFREQ_CONST_LOOPS)) {
 			if ((policy) && (policy->cpu == freqs->cpu) &&
 			    (policy->cur) && (policy->cur != freqs->old)) {
-				dprintk("Warning: CPU frequency is"
+				pr_debug("Warning: CPU frequency is"
 					" %u, cpufreq assumed %u kHz.\n",
 					freqs->old, policy->cur);
 				freqs->old = policy->cur;
@@ -353,7 +263,7 @@
 
 	case CPUFREQ_POSTCHANGE:
 		adjust_jiffies(CPUFREQ_POSTCHANGE, freqs);
-		dprintk("FREQ: %lu - CPU: %lu", (unsigned long)freqs->new,
+		pr_debug("FREQ: %lu - CPU: %lu", (unsigned long)freqs->new,
 			(unsigned long)freqs->cpu);
 		trace_power_frequency(POWER_PSTATE, freqs->new, freqs->cpu);
 		trace_cpu_frequency(freqs->new, freqs->cpu);
@@ -411,21 +321,14 @@
 		t = __find_governor(str_governor);
 
 		if (t == NULL) {
-			char *name = kasprintf(GFP_KERNEL, "cpufreq_%s",
-								str_governor);
-
-			if (name) {
-				int ret;
-
-				mutex_unlock(&cpufreq_governor_mutex);
-				ret = request_module("%s", name);
-				mutex_lock(&cpufreq_governor_mutex);
+			int ret;
 
-				if (ret == 0)
-					t = __find_governor(str_governor);
-			}
+			mutex_unlock(&cpufreq_governor_mutex);
+			ret = request_module("cpufreq_%s", str_governor);
+			mutex_lock(&cpufreq_governor_mutex);
 
-			kfree(name);
+			if (ret == 0)
+				t = __find_governor(str_governor);
 		}
 
 		if (t != NULL) {
@@ -753,7 +656,7 @@
 static void cpufreq_sysfs_release(struct kobject *kobj)
 {
 	struct cpufreq_policy *policy = to_policy(kobj);
-	dprintk("last reference is dropped\n");
+	pr_debug("last reference is dropped\n");
 	complete(&policy->kobj_unregister);
 }
 
@@ -788,7 +691,7 @@
 	gov = __find_governor(per_cpu(cpufreq_cpu_governor, cpu));
 	if (gov) {
 		policy->governor = gov;
-		dprintk("Restoring governor %s for cpu %d\n",
+		pr_debug("Restoring governor %s for cpu %d\n",
 		       policy->governor->name, cpu);
 	}
 #endif
@@ -824,7 +727,7 @@
 			per_cpu(cpufreq_cpu_data, cpu) = managed_policy;
 			spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
 
-			dprintk("CPU already managed, adding link\n");
+			pr_debug("CPU already managed, adding link\n");
 			ret = sysfs_create_link(&sys_dev->kobj,
 						&managed_policy->kobj,
 						"cpufreq");
@@ -865,7 +768,7 @@
 		if (!cpu_online(j))
 			continue;
 
-		dprintk("CPU %u already managed, adding link\n", j);
+		pr_debug("CPU %u already managed, adding link\n", j);
 		managed_policy = cpufreq_cpu_get(cpu);
 		cpu_sys_dev = get_cpu_sysdev(j);
 		ret = sysfs_create_link(&cpu_sys_dev->kobj, &policy->kobj,
@@ -941,7 +844,7 @@
 	policy->user_policy.governor = policy->governor;
 
 	if (ret) {
-		dprintk("setting policy failed\n");
+		pr_debug("setting policy failed\n");
 		if (cpufreq_driver->exit)
 			cpufreq_driver->exit(policy);
 	}
@@ -977,8 +880,7 @@
 	if (cpu_is_offline(cpu))
 		return 0;
 
-	cpufreq_debug_disable_ratelimit();
-	dprintk("adding CPU %u\n", cpu);
+	pr_debug("adding CPU %u\n", cpu);
 
 #ifdef CONFIG_SMP
 	/* check whether a different CPU already registered this
@@ -986,7 +888,6 @@
 	policy = cpufreq_cpu_get(cpu);
 	if (unlikely(policy)) {
 		cpufreq_cpu_put(policy);
-		cpufreq_debug_enable_ratelimit();
 		return 0;
 	}
 #endif
@@ -1037,7 +938,7 @@
 	 */
 	ret = cpufreq_driver->init(policy);
 	if (ret) {
-		dprintk("initialization failed\n");
+		pr_debug("initialization failed\n");
 		goto err_unlock_policy;
 	}
 	policy->user_policy.min = policy->min;
@@ -1063,8 +964,7 @@
 
 	kobject_uevent(&policy->kobj, KOBJ_ADD);
 	module_put(cpufreq_driver->owner);
-	dprintk("initialization complete\n");
-	cpufreq_debug_enable_ratelimit();
+	pr_debug("initialization complete\n");
 
 	return 0;
 
@@ -1088,7 +988,6 @@
 nomem_out:
 	module_put(cpufreq_driver->owner);
 module_out:
-	cpufreq_debug_enable_ratelimit();
 	return ret;
 }
 
@@ -1112,15 +1011,13 @@
 	unsigned int j;
 #endif
 
-	cpufreq_debug_disable_ratelimit();
-	dprintk("unregistering CPU %u\n", cpu);
+	pr_debug("unregistering CPU %u\n", cpu);
 
 	spin_lock_irqsave(&cpufreq_driver_lock, flags);
 	data = per_cpu(cpufreq_cpu_data, cpu);
 
 	if (!data) {
 		spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
-		cpufreq_debug_enable_ratelimit();
 		unlock_policy_rwsem_write(cpu);
 		return -EINVAL;
 	}
@@ -1132,12 +1029,11 @@
 	 * only need to unlink, put and exit
 	 */
 	if (unlikely(cpu != data->cpu)) {
-		dprintk("removing link\n");
+		pr_debug("removing link\n");
 		cpumask_clear_cpu(cpu, data->cpus);
 		spin_unlock_irqrestore(&cpufreq_driver_lock, flags);
 		kobj = &sys_dev->kobj;
 		cpufreq_cpu_put(data);
-		cpufreq_debug_enable_ratelimit();
 		unlock_policy_rwsem_write(cpu);
 		sysfs_remove_link(kobj, "cpufreq");
 		return 0;
@@ -1170,7 +1066,7 @@
 		for_each_cpu(j, data->cpus) {
 			if (j == cpu)
 				continue;
-			dprintk("removing link for cpu %u\n", j);
+			pr_debug("removing link for cpu %u\n", j);
 #ifdef CONFIG_HOTPLUG_CPU
 			strncpy(per_cpu(cpufreq_cpu_governor, j),
 				data->governor->name, CPUFREQ_NAME_LEN);
@@ -1199,21 +1095,35 @@
 	 * not referenced anymore by anybody before we proceed with
 	 * unloading.
 	 */
-	dprintk("waiting for dropping of refcount\n");
+	pr_debug("waiting for dropping of refcount\n");
 	wait_for_completion(cmp);
-	dprintk("wait complete\n");
+	pr_debug("wait complete\n");
 
 	lock_policy_rwsem_write(cpu);
 	if (cpufreq_driver->exit)
 		cpufreq_driver->exit(data);
 	unlock_policy_rwsem_write(cpu);
 
+#ifdef CONFIG_HOTPLUG_CPU
+	/* when the CPU which is the parent of the kobj is hotplugged
+	 * offline, check for siblings, and create cpufreq sysfs interface
+	 * and symlinks
+	 */
+	if (unlikely(cpumask_weight(data->cpus) > 1)) {
+		/* first sibling now owns the new sysfs dir */
+		cpumask_clear_cpu(cpu, data->cpus);
+		cpufreq_add_dev(get_cpu_sysdev(cpumask_first(data->cpus)));
+
+		/* finally remove our own symlink */
+		lock_policy_rwsem_write(cpu);
+		__cpufreq_remove_dev(sys_dev);
+	}
+#endif
+
 	free_cpumask_var(data->related_cpus);
 	free_cpumask_var(data->cpus);
 	kfree(data);
-	per_cpu(cpufreq_cpu_data, cpu) = NULL;
 
-	cpufreq_debug_enable_ratelimit();
 	return 0;
 }
 
@@ -1239,7 +1149,7 @@
 	struct cpufreq_policy *policy =
 		container_of(work, struct cpufreq_policy, update);
 	unsigned int cpu = policy->cpu;
-	dprintk("handle_update for cpu %u called\n", cpu);
+	pr_debug("handle_update for cpu %u called\n", cpu);
 	cpufreq_update_policy(cpu);
 }
 
@@ -1257,7 +1167,7 @@
 {
 	struct cpufreq_freqs freqs;
 
-	dprintk("Warning: CPU frequency out of sync: cpufreq and timing "
+	pr_debug("Warning: CPU frequency out of sync: cpufreq and timing "
 	       "core thinks of %u, is %u kHz.\n", old_freq, new_freq);
 
 	freqs.cpu = cpu;
@@ -1360,7 +1270,7 @@
 	int cpu = smp_processor_id();
 	struct cpufreq_policy *cpu_policy;
 
-	dprintk("suspending cpu %u\n", cpu);
+	pr_debug("suspending cpu %u\n", cpu);
 
 	/* If there's no policy for the boot CPU, we have nothing to do. */
 	cpu_policy = cpufreq_cpu_get(cpu);
@@ -1398,7 +1308,7 @@
 	int cpu = smp_processor_id();
 	struct cpufreq_policy *cpu_policy;
 
-	dprintk("resuming cpu %u\n", cpu);
+	pr_debug("resuming cpu %u\n", cpu);
 
 	/* If there's no policy for the boot CPU, we have nothing to do. */
 	cpu_policy = cpufreq_cpu_get(cpu);
@@ -1510,7 +1420,7 @@
 {
 	int retval = -EINVAL;
 
-	dprintk("target for CPU %u: %u kHz, relation %u\n", policy->cpu,
+	pr_debug("target for CPU %u: %u kHz, relation %u\n", policy->cpu,
 		target_freq, relation);
 	if (cpu_online(policy->cpu) && cpufreq_driver->target)
 		retval = cpufreq_driver->target(policy, target_freq, relation);
@@ -1596,7 +1506,7 @@
 	if (!try_module_get(policy->governor->owner))
 		return -EINVAL;
 
-	dprintk("__cpufreq_governor for CPU %u, event %u\n",
+	pr_debug("__cpufreq_governor for CPU %u, event %u\n",
 						policy->cpu, event);
 	ret = policy->governor->governor(policy, event);
 
@@ -1697,8 +1607,7 @@
 {
 	int ret = 0;
 
-	cpufreq_debug_disable_ratelimit();
-	dprintk("setting new policy for CPU %u: %u - %u kHz\n", policy->cpu,
+	pr_debug("setting new policy for CPU %u: %u - %u kHz\n", policy->cpu,
 		policy->min, policy->max);
 
 	memcpy(&policy->cpuinfo, &data->cpuinfo,
@@ -1735,19 +1644,19 @@
 	data->min = policy->min;
 	data->max = policy->max;
 
-	dprintk("new min and max freqs are %u - %u kHz\n",
+	pr_debug("new min and max freqs are %u - %u kHz\n",
 					data->min, data->max);
 
 	if (cpufreq_driver->setpolicy) {
 		data->policy = policy->policy;
-		dprintk("setting range\n");
+		pr_debug("setting range\n");
 		ret = cpufreq_driver->setpolicy(policy);
 	} else {
 		if (policy->governor != data->governor) {
 			/* save old, working values */
 			struct cpufreq_governor *old_gov = data->governor;
 
-			dprintk("governor switch\n");
+			pr_debug("governor switch\n");
 
 			/* end old governor */
 			if (data->governor)
@@ -1757,7 +1666,7 @@
 			data->governor = policy->governor;
 			if (__cpufreq_governor(data, CPUFREQ_GOV_START)) {
 				/* new governor failed, so re-start old one */
-				dprintk("starting governor %s failed\n",
+				pr_debug("starting governor %s failed\n",
 							data->governor->name);
 				if (old_gov) {
 					data->governor = old_gov;
@@ -1769,12 +1678,11 @@
 			}
 			/* might be a policy change, too, so fall through */
 		}
-		dprintk("governor: change or update limits\n");
+		pr_debug("governor: change or update limits\n");
 		__cpufreq_governor(data, CPUFREQ_GOV_LIMITS);
 	}
 
 error_out:
-	cpufreq_debug_enable_ratelimit();
 	return ret;
 }
 
@@ -1801,7 +1709,7 @@
 		goto fail;
 	}
 
-	dprintk("updating policy for CPU %u\n", cpu);
+	pr_debug("updating policy for CPU %u\n", cpu);
 	memcpy(&policy, data, sizeof(struct cpufreq_policy));
 	policy.min = data->user_policy.min;
 	policy.max = data->user_policy.max;
@@ -1813,7 +1721,7 @@
 	if (cpufreq_driver->get) {
 		policy.cur = cpufreq_driver->get(cpu);
 		if (!data->cur) {
-			dprintk("Driver did not initialize current freq");
+			pr_debug("Driver did not initialize current freq");
 			data->cur = policy.cur;
 		} else {
 			if (data->cur != policy.cur)
@@ -1889,7 +1797,7 @@
 	    ((!driver_data->setpolicy) && (!driver_data->target)))
 		return -EINVAL;
 
-	dprintk("trying to register driver %s\n", driver_data->name);
+	pr_debug("trying to register driver %s\n", driver_data->name);
 
 	if (driver_data->setpolicy)
 		driver_data->flags |= CPUFREQ_CONST_LOOPS;
@@ -1920,15 +1828,14 @@
 
 		/* if all ->init() calls failed, unregister */
 		if (ret) {
-			dprintk("no CPU initialized for driver %s\n",
+			pr_debug("no CPU initialized for driver %s\n",
 							driver_data->name);
 			goto err_sysdev_unreg;
 		}
 	}
 
 	register_hotcpu_notifier(&cpufreq_cpu_notifier);
-	dprintk("driver %s up and running\n", driver_data->name);
-	cpufreq_debug_enable_ratelimit();
+	pr_debug("driver %s up and running\n", driver_data->name);
 
 	return 0;
 err_sysdev_unreg:
@@ -1955,14 +1862,10 @@
 {
 	unsigned long flags;
 
-	cpufreq_debug_disable_ratelimit();
-
-	if (!cpufreq_driver || (driver != cpufreq_driver)) {
-		cpufreq_debug_enable_ratelimit();
+	if (!cpufreq_driver || (driver != cpufreq_driver))
 		return -EINVAL;
-	}
 
-	dprintk("unregistering driver %s\n", driver->name);
+	pr_debug("unregistering driver %s\n", driver->name);
 
 	sysdev_driver_unregister(&cpu_sysdev_class, &cpufreq_sysdev_driver);
 	unregister_hotcpu_notifier(&cpufreq_cpu_notifier);
diff -druN linux-2.6.39-libre/drivers/cpufreq/cpufreq-nforce2.c linux-3.0-rc7-libre/drivers/cpufreq/cpufreq-nforce2.c
--- linux-2.6.39-libre/drivers/cpufreq/cpufreq-nforce2.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/cpufreq/cpufreq-nforce2.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,444 @@
+/*
+ * (C) 2004-2006  Sebastian Witt <se.witt@gmx.net>
+ *
+ *  Licensed under the terms of the GNU GPL License version 2.
+ *  Based upon reverse engineered information
+ *
+ *  BIG FAT DISCLAIMER: Work in progress code. Possibly *dangerous*
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/init.h>
+#include <linux/cpufreq.h>
+#include <linux/pci.h>
+#include <linux/delay.h>
+
+#define NFORCE2_XTAL 25
+#define NFORCE2_BOOTFSB 0x48
+#define NFORCE2_PLLENABLE 0xa8
+#define NFORCE2_PLLREG 0xa4
+#define NFORCE2_PLLADR 0xa0
+#define NFORCE2_PLL(mul, div) (0x100000 | (mul << 8) | div)
+
+#define NFORCE2_MIN_FSB 50
+#define NFORCE2_SAFE_DISTANCE 50
+
+/* Delay in ms between FSB changes */
+/* #define NFORCE2_DELAY 10 */
+
+/*
+ * nforce2_chipset:
+ * FSB is changed using the chipset
+ */
+static struct pci_dev *nforce2_dev;
+
+/* fid:
+ * multiplier * 10
+ */
+static int fid;
+
+/* min_fsb, max_fsb:
+ * minimum and maximum FSB (= FSB at boot time)
+ */
+static int min_fsb;
+static int max_fsb;
+
+MODULE_AUTHOR("Sebastian Witt <se.witt@gmx.net>");
+MODULE_DESCRIPTION("nForce2 FSB changing cpufreq driver");
+MODULE_LICENSE("GPL");
+
+module_param(fid, int, 0444);
+module_param(min_fsb, int, 0444);
+
+MODULE_PARM_DESC(fid, "CPU multiplier to use (11.5 = 115)");
+MODULE_PARM_DESC(min_fsb,
+		"Minimum FSB to use, if not defined: current FSB - 50");
+
+#define PFX "cpufreq-nforce2: "
+
+/**
+ * nforce2_calc_fsb - calculate FSB
+ * @pll: PLL value
+ *
+ *   Calculates FSB from PLL value
+ */
+static int nforce2_calc_fsb(int pll)
+{
+	unsigned char mul, div;
+
+	mul = (pll >> 8) & 0xff;
+	div = pll & 0xff;
+
+	if (div > 0)
+		return NFORCE2_XTAL * mul / div;
+
+	return 0;
+}
+
+/**
+ * nforce2_calc_pll - calculate PLL value
+ * @fsb: FSB
+ *
+ *   Calculate PLL value for given FSB
+ */
+static int nforce2_calc_pll(unsigned int fsb)
+{
+	unsigned char xmul, xdiv;
+	unsigned char mul = 0, div = 0;
+	int tried = 0;
+
+	/* Try to calculate multiplier and divider up to 4 times */
+	while (((mul == 0) || (div == 0)) && (tried <= 3)) {
+		for (xdiv = 2; xdiv <= 0x80; xdiv++)
+			for (xmul = 1; xmul <= 0xfe; xmul++)
+				if (nforce2_calc_fsb(NFORCE2_PLL(xmul, xdiv)) ==
+				    fsb + tried) {
+					mul = xmul;
+					div = xdiv;
+				}
+		tried++;
+	}
+
+	if ((mul == 0) || (div == 0))
+		return -1;
+
+	return NFORCE2_PLL(mul, div);
+}
+
+/**
+ * nforce2_write_pll - write PLL value to chipset
+ * @pll: PLL value
+ *
+ *   Writes new FSB PLL value to chipset
+ */
+static void nforce2_write_pll(int pll)
+{
+	int temp;
+
+	/* Set the pll addr. to 0x00 */
+	pci_write_config_dword(nforce2_dev, NFORCE2_PLLADR, 0);
+
+	/* Now write the value in all 64 registers */
+	for (temp = 0; temp <= 0x3f; temp++)
+		pci_write_config_dword(nforce2_dev, NFORCE2_PLLREG, pll);
+
+	return;
+}
+
+/**
+ * nforce2_fsb_read - Read FSB
+ *
+ *   Read FSB from chipset
+ *   If bootfsb != 0, return FSB at boot-time
+ */
+static unsigned int nforce2_fsb_read(int bootfsb)
+{
+	struct pci_dev *nforce2_sub5;
+	u32 fsb, temp = 0;
+
+	/* Get chipset boot FSB from subdevice 5 (FSB at boot-time) */
+	nforce2_sub5 = pci_get_subsys(PCI_VENDOR_ID_NVIDIA, 0x01EF,
+				PCI_ANY_ID, PCI_ANY_ID, NULL);
+	if (!nforce2_sub5)
+		return 0;
+
+	pci_read_config_dword(nforce2_sub5, NFORCE2_BOOTFSB, &fsb);
+	fsb /= 1000000;
+
+	/* Check if PLL register is already set */
+	pci_read_config_byte(nforce2_dev, NFORCE2_PLLENABLE, (u8 *)&temp);
+
+	if (bootfsb || !temp)
+		return fsb;
+
+	/* Use PLL register FSB value */
+	pci_read_config_dword(nforce2_dev, NFORCE2_PLLREG, &temp);
+	fsb = nforce2_calc_fsb(temp);
+
+	return fsb;
+}
+
+/**
+ * nforce2_set_fsb - set new FSB
+ * @fsb: New FSB
+ *
+ *   Sets new FSB
+ */
+static int nforce2_set_fsb(unsigned int fsb)
+{
+	u32 temp = 0;
+	unsigned int tfsb;
+	int diff;
+	int pll = 0;
+
+	if ((fsb > max_fsb) || (fsb < NFORCE2_MIN_FSB)) {
+		printk(KERN_ERR PFX "FSB %d is out of range!\n", fsb);
+		return -EINVAL;
+	}
+
+	tfsb = nforce2_fsb_read(0);
+	if (!tfsb) {
+		printk(KERN_ERR PFX "Error while reading the FSB\n");
+		return -EINVAL;
+	}
+
+	/* First write? Then set actual value */
+	pci_read_config_byte(nforce2_dev, NFORCE2_PLLENABLE, (u8 *)&temp);
+	if (!temp) {
+		pll = nforce2_calc_pll(tfsb);
+
+		if (pll < 0)
+			return -EINVAL;
+
+		nforce2_write_pll(pll);
+	}
+
+	/* Enable write access */
+	temp = 0x01;
+	pci_write_config_byte(nforce2_dev, NFORCE2_PLLENABLE, (u8)temp);
+
+	diff = tfsb - fsb;
+
+	if (!diff)
+		return 0;
+
+	while ((tfsb != fsb) && (tfsb <= max_fsb) && (tfsb >= min_fsb)) {
+		if (diff < 0)
+			tfsb++;
+		else
+			tfsb--;
+
+		/* Calculate the PLL reg. value */
+		pll = nforce2_calc_pll(tfsb);
+		if (pll == -1)
+			return -EINVAL;
+
+		nforce2_write_pll(pll);
+#ifdef NFORCE2_DELAY
+		mdelay(NFORCE2_DELAY);
+#endif
+	}
+
+	temp = 0x40;
+	pci_write_config_byte(nforce2_dev, NFORCE2_PLLADR, (u8)temp);
+
+	return 0;
+}
+
+/**
+ * nforce2_get - get the CPU frequency
+ * @cpu: CPU number
+ *
+ * Returns the CPU frequency
+ */
+static unsigned int nforce2_get(unsigned int cpu)
+{
+	if (cpu)
+		return 0;
+	return nforce2_fsb_read(0) * fid * 100;
+}
+
+/**
+ * nforce2_target - set a new CPUFreq policy
+ * @policy: new policy
+ * @target_freq: the target frequency
+ * @relation: how that frequency relates to achieved frequency
+ *  (CPUFREQ_RELATION_L or CPUFREQ_RELATION_H)
+ *
+ * Sets a new CPUFreq policy.
+ */
+static int nforce2_target(struct cpufreq_policy *policy,
+			  unsigned int target_freq, unsigned int relation)
+{
+/*        unsigned long         flags; */
+	struct cpufreq_freqs freqs;
+	unsigned int target_fsb;
+
+	if ((target_freq > policy->max) || (target_freq < policy->min))
+		return -EINVAL;
+
+	target_fsb = target_freq / (fid * 100);
+
+	freqs.old = nforce2_get(policy->cpu);
+	freqs.new = target_fsb * fid * 100;
+	freqs.cpu = 0;		/* Only one CPU on nForce2 platforms */
+
+	if (freqs.old == freqs.new)
+		return 0;
+
+	pr_debug("Old CPU frequency %d kHz, new %d kHz\n",
+	       freqs.old, freqs.new);
+
+	cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
+
+	/* Disable IRQs */
+	/* local_irq_save(flags); */
+
+	if (nforce2_set_fsb(target_fsb) < 0)
+		printk(KERN_ERR PFX "Changing FSB to %d failed\n",
+			target_fsb);
+	else
+		pr_debug("Changed FSB successfully to %d\n",
+			target_fsb);
+
+	/* Enable IRQs */
+	/* local_irq_restore(flags); */
+
+	cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
+
+	return 0;
+}
+
+/**
+ * nforce2_verify - verifies a new CPUFreq policy
+ * @policy: new policy
+ */
+static int nforce2_verify(struct cpufreq_policy *policy)
+{
+	unsigned int fsb_pol_max;
+
+	fsb_pol_max = policy->max / (fid * 100);
+
+	if (policy->min < (fsb_pol_max * fid * 100))
+		policy->max = (fsb_pol_max + 1) * fid * 100;
+
+	cpufreq_verify_within_limits(policy,
+				     policy->cpuinfo.min_freq,
+				     policy->cpuinfo.max_freq);
+	return 0;
+}
+
+static int nforce2_cpu_init(struct cpufreq_policy *policy)
+{
+	unsigned int fsb;
+	unsigned int rfid;
+
+	/* capability check */
+	if (policy->cpu != 0)
+		return -ENODEV;
+
+	/* Get current FSB */
+	fsb = nforce2_fsb_read(0);
+
+	if (!fsb)
+		return -EIO;
+
+	/* FIX: Get FID from CPU */
+	if (!fid) {
+		if (!cpu_khz) {
+			printk(KERN_WARNING PFX
+			"cpu_khz not set, can't calculate multiplier!\n");
+			return -ENODEV;
+		}
+
+		fid = cpu_khz / (fsb * 100);
+		rfid = fid % 5;
+
+		if (rfid) {
+			if (rfid > 2)
+				fid += 5 - rfid;
+			else
+				fid -= rfid;
+		}
+	}
+
+	printk(KERN_INFO PFX "FSB currently at %i MHz, FID %d.%d\n", fsb,
+	       fid / 10, fid % 10);
+
+	/* Set maximum FSB to FSB at boot time */
+	max_fsb = nforce2_fsb_read(1);
+
+	if (!max_fsb)
+		return -EIO;
+
+	if (!min_fsb)
+		min_fsb = max_fsb - NFORCE2_SAFE_DISTANCE;
+
+	if (min_fsb < NFORCE2_MIN_FSB)
+		min_fsb = NFORCE2_MIN_FSB;
+
+	/* cpuinfo and default policy values */
+	policy->cpuinfo.min_freq = min_fsb * fid * 100;
+	policy->cpuinfo.max_freq = max_fsb * fid * 100;
+	policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL;
+	policy->cur = nforce2_get(policy->cpu);
+	policy->min = policy->cpuinfo.min_freq;
+	policy->max = policy->cpuinfo.max_freq;
+
+	return 0;
+}
+
+static int nforce2_cpu_exit(struct cpufreq_policy *policy)
+{
+	return 0;
+}
+
+static struct cpufreq_driver nforce2_driver = {
+	.name = "nforce2",
+	.verify = nforce2_verify,
+	.target = nforce2_target,
+	.get = nforce2_get,
+	.init = nforce2_cpu_init,
+	.exit = nforce2_cpu_exit,
+	.owner = THIS_MODULE,
+};
+
+/**
+ * nforce2_detect_chipset - detect the Southbridge which contains FSB PLL logic
+ *
+ * Detects nForce2 A2 and C1 stepping
+ *
+ */
+static int nforce2_detect_chipset(void)
+{
+	nforce2_dev = pci_get_subsys(PCI_VENDOR_ID_NVIDIA,
+					PCI_DEVICE_ID_NVIDIA_NFORCE2,
+					PCI_ANY_ID, PCI_ANY_ID, NULL);
+
+	if (nforce2_dev == NULL)
+		return -ENODEV;
+
+	printk(KERN_INFO PFX "Detected nForce2 chipset revision %X\n",
+	       nforce2_dev->revision);
+	printk(KERN_INFO PFX
+	       "FSB changing is maybe unstable and can lead to "
+	       "crashes and data loss.\n");
+
+	return 0;
+}
+
+/**
+ * nforce2_init - initializes the nForce2 CPUFreq driver
+ *
+ * Initializes the nForce2 FSB support. Returns -ENODEV on unsupported
+ * devices, -EINVAL on problems during initiatization, and zero on
+ * success.
+ */
+static int __init nforce2_init(void)
+{
+	/* TODO: do we need to detect the processor? */
+
+	/* detect chipset */
+	if (nforce2_detect_chipset()) {
+		printk(KERN_INFO PFX "No nForce2 chipset.\n");
+		return -ENODEV;
+	}
+
+	return cpufreq_register_driver(&nforce2_driver);
+}
+
+/**
+ * nforce2_exit - unregisters cpufreq module
+ *
+ *   Unregisters nForce2 FSB change support.
+ */
+static void __exit nforce2_exit(void)
+{
+	cpufreq_unregister_driver(&nforce2_driver);
+}
+
+module_init(nforce2_init);
+module_exit(nforce2_exit);
+
diff -druN linux-2.6.39-libre/drivers/cpufreq/cpufreq_performance.c linux-3.0-rc7-libre/drivers/cpufreq/cpufreq_performance.c
--- linux-2.6.39-libre/drivers/cpufreq/cpufreq_performance.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/cpufreq/cpufreq_performance.c	2011-07-11 19:51:52.000000000 -0400
@@ -15,9 +15,6 @@
 #include <linux/cpufreq.h>
 #include <linux/init.h>
 
-#define dprintk(msg...) \
-	cpufreq_debug_printk(CPUFREQ_DEBUG_GOVERNOR, "performance", msg)
-
 
 static int cpufreq_governor_performance(struct cpufreq_policy *policy,
 					unsigned int event)
@@ -25,7 +22,7 @@
 	switch (event) {
 	case CPUFREQ_GOV_START:
 	case CPUFREQ_GOV_LIMITS:
-		dprintk("setting to %u kHz because of event %u\n",
+		pr_debug("setting to %u kHz because of event %u\n",
 						policy->max, event);
 		__cpufreq_driver_target(policy, policy->max,
 						CPUFREQ_RELATION_H);
diff -druN linux-2.6.39-libre/drivers/cpufreq/cpufreq_powersave.c linux-3.0-rc7-libre/drivers/cpufreq/cpufreq_powersave.c
--- linux-2.6.39-libre/drivers/cpufreq/cpufreq_powersave.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/cpufreq/cpufreq_powersave.c	2011-07-11 19:51:52.000000000 -0400
@@ -15,16 +15,13 @@
 #include <linux/cpufreq.h>
 #include <linux/init.h>
 
-#define dprintk(msg...) \
-	cpufreq_debug_printk(CPUFREQ_DEBUG_GOVERNOR, "powersave", msg)
-
 static int cpufreq_governor_powersave(struct cpufreq_policy *policy,
 					unsigned int event)
 {
 	switch (event) {
 	case CPUFREQ_GOV_START:
 	case CPUFREQ_GOV_LIMITS:
-		dprintk("setting to %u kHz because of event %u\n",
+		pr_debug("setting to %u kHz because of event %u\n",
 							policy->min, event);
 		__cpufreq_driver_target(policy, policy->min,
 						CPUFREQ_RELATION_L);
diff -druN linux-2.6.39-libre/drivers/cpufreq/cpufreq_stats.c linux-3.0-rc7-libre/drivers/cpufreq/cpufreq_stats.c
--- linux-2.6.39-libre/drivers/cpufreq/cpufreq_stats.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/cpufreq/cpufreq_stats.c	2011-07-11 19:51:52.000000000 -0400
@@ -165,17 +165,27 @@
 	return -1;
 }
 
+/* should be called late in the CPU removal sequence so that the stats
+ * memory is still available in case someone tries to use it.
+ */
 static void cpufreq_stats_free_table(unsigned int cpu)
 {
 	struct cpufreq_stats *stat = per_cpu(cpufreq_stats_table, cpu);
-	struct cpufreq_policy *policy = cpufreq_cpu_get(cpu);
-	if (policy && policy->cpu == cpu)
-		sysfs_remove_group(&policy->kobj, &stats_attr_group);
 	if (stat) {
 		kfree(stat->time_in_state);
 		kfree(stat);
 	}
 	per_cpu(cpufreq_stats_table, cpu) = NULL;
+}
+
+/* must be called early in the CPU removal sequence (before
+ * cpufreq_remove_dev) so that policy is still valid.
+ */
+static void cpufreq_stats_free_sysfs(unsigned int cpu)
+{
+	struct cpufreq_policy *policy = cpufreq_cpu_get(cpu);
+	if (policy && policy->cpu == cpu)
+		sysfs_remove_group(&policy->kobj, &stats_attr_group);
 	if (policy)
 		cpufreq_cpu_put(policy);
 }
@@ -288,11 +298,13 @@
 	old_index = stat->last_index;
 	new_index = freq_table_get_index(stat, freq->new);
 
-	cpufreq_stats_update(freq->cpu);
-	if (old_index == new_index)
+	/* We can't do stat->time_in_state[-1]= .. */
+	if (old_index == -1 || new_index == -1)
 		return 0;
 
-	if (old_index == -1 || new_index == -1)
+	cpufreq_stats_update(freq->cpu);
+
+	if (old_index == new_index)
 		return 0;
 
 	spin_lock(&cpufreq_stats_lock);
@@ -316,6 +328,9 @@
 	case CPU_ONLINE_FROZEN:
 		cpufreq_update_policy(cpu);
 		break;
+	case CPU_DOWN_PREPARE:
+		cpufreq_stats_free_sysfs(cpu);
+		break;
 	case CPU_DEAD:
 	case CPU_DEAD_FROZEN:
 		cpufreq_stats_free_table(cpu);
@@ -324,9 +339,10 @@
 	return NOTIFY_OK;
 }
 
-static struct notifier_block cpufreq_stat_cpu_notifier __refdata =
-{
+/* priority=1 so this will get called before cpufreq_remove_dev */
+static struct notifier_block cpufreq_stat_cpu_notifier __refdata = {
 	.notifier_call = cpufreq_stat_cpu_callback,
+	.priority = 1,
 };
 
 static struct notifier_block notifier_policy_block = {
@@ -373,6 +389,7 @@
 	unregister_hotcpu_notifier(&cpufreq_stat_cpu_notifier);
 	for_each_online_cpu(cpu) {
 		cpufreq_stats_free_table(cpu);
+		cpufreq_stats_free_sysfs(cpu);
 	}
 }
 
diff -druN linux-2.6.39-libre/drivers/cpufreq/cpufreq_userspace.c linux-3.0-rc7-libre/drivers/cpufreq/cpufreq_userspace.c
--- linux-2.6.39-libre/drivers/cpufreq/cpufreq_userspace.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/cpufreq/cpufreq_userspace.c	2011-07-11 19:51:52.000000000 -0400
@@ -37,9 +37,6 @@
 static DEFINE_MUTEX(userspace_mutex);
 static int cpus_using_userspace_governor;
 
-#define dprintk(msg...) \
-	cpufreq_debug_printk(CPUFREQ_DEBUG_GOVERNOR, "userspace", msg)
-
 /* keep track of frequency transitions */
 static int
 userspace_cpufreq_notifier(struct notifier_block *nb, unsigned long val,
@@ -50,7 +47,7 @@
 	if (!per_cpu(cpu_is_managed, freq->cpu))
 		return 0;
 
-	dprintk("saving cpu_cur_freq of cpu %u to be %u kHz\n",
+	pr_debug("saving cpu_cur_freq of cpu %u to be %u kHz\n",
 			freq->cpu, freq->new);
 	per_cpu(cpu_cur_freq, freq->cpu) = freq->new;
 
@@ -73,7 +70,7 @@
 {
 	int ret = -EINVAL;
 
-	dprintk("cpufreq_set for cpu %u, freq %u kHz\n", policy->cpu, freq);
+	pr_debug("cpufreq_set for cpu %u, freq %u kHz\n", policy->cpu, freq);
 
 	mutex_lock(&userspace_mutex);
 	if (!per_cpu(cpu_is_managed, policy->cpu))
@@ -134,7 +131,7 @@
 		per_cpu(cpu_max_freq, cpu) = policy->max;
 		per_cpu(cpu_cur_freq, cpu) = policy->cur;
 		per_cpu(cpu_set_freq, cpu) = policy->cur;
-		dprintk("managing cpu %u started "
+		pr_debug("managing cpu %u started "
 			"(%u - %u kHz, currently %u kHz)\n",
 				cpu,
 				per_cpu(cpu_min_freq, cpu),
@@ -156,12 +153,12 @@
 		per_cpu(cpu_min_freq, cpu) = 0;
 		per_cpu(cpu_max_freq, cpu) = 0;
 		per_cpu(cpu_set_freq, cpu) = 0;
-		dprintk("managing cpu %u stopped\n", cpu);
+		pr_debug("managing cpu %u stopped\n", cpu);
 		mutex_unlock(&userspace_mutex);
 		break;
 	case CPUFREQ_GOV_LIMITS:
 		mutex_lock(&userspace_mutex);
-		dprintk("limit event for cpu %u: %u - %u kHz, "
+		pr_debug("limit event for cpu %u: %u - %u kHz, "
 			"currently %u kHz, last set to %u kHz\n",
 			cpu, policy->min, policy->max,
 			per_cpu(cpu_cur_freq, cpu),
diff -druN linux-2.6.39-libre/drivers/cpufreq/db8500-cpufreq.c linux-3.0-rc7-libre/drivers/cpufreq/db8500-cpufreq.c
--- linux-2.6.39-libre/drivers/cpufreq/db8500-cpufreq.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/cpufreq/db8500-cpufreq.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,169 @@
+/*
+ * Copyright (C) STMicroelectronics 2009
+ * Copyright (C) ST-Ericsson SA 2010
+ *
+ * License Terms: GNU General Public License v2
+ * Author: Sundar Iyer <sundar.iyer@stericsson.com>
+ * Author: Martin Persson <martin.persson@stericsson.com>
+ * Author: Jonas Aaberg <jonas.aberg@stericsson.com>
+ *
+ */
+#include <linux/kernel.h>
+#include <linux/cpufreq.h>
+#include <linux/delay.h>
+#include <linux/slab.h>
+#include <linux/mfd/db8500-prcmu.h>
+#include <mach/id.h>
+
+static struct cpufreq_frequency_table freq_table[] = {
+	[0] = {
+		.index = 0,
+		.frequency = 300000,
+	},
+	[1] = {
+		.index = 1,
+		.frequency = 600000,
+	},
+	[2] = {
+		/* Used for MAX_OPP, if available */
+		.index = 2,
+		.frequency = CPUFREQ_TABLE_END,
+	},
+	[3] = {
+		.index = 3,
+		.frequency = CPUFREQ_TABLE_END,
+	},
+};
+
+static enum arm_opp idx2opp[] = {
+	ARM_50_OPP,
+	ARM_100_OPP,
+	ARM_MAX_OPP
+};
+
+static struct freq_attr *db8500_cpufreq_attr[] = {
+	&cpufreq_freq_attr_scaling_available_freqs,
+	NULL,
+};
+
+static int db8500_cpufreq_verify_speed(struct cpufreq_policy *policy)
+{
+	return cpufreq_frequency_table_verify(policy, freq_table);
+}
+
+static int db8500_cpufreq_target(struct cpufreq_policy *policy,
+				unsigned int target_freq,
+				unsigned int relation)
+{
+	struct cpufreq_freqs freqs;
+	unsigned int idx;
+
+	/* scale the target frequency to one of the extremes supported */
+	if (target_freq < policy->cpuinfo.min_freq)
+		target_freq = policy->cpuinfo.min_freq;
+	if (target_freq > policy->cpuinfo.max_freq)
+		target_freq = policy->cpuinfo.max_freq;
+
+	/* Lookup the next frequency */
+	if (cpufreq_frequency_table_target
+	    (policy, freq_table, target_freq, relation, &idx)) {
+		return -EINVAL;
+	}
+
+	freqs.old = policy->cur;
+	freqs.new = freq_table[idx].frequency;
+	freqs.cpu = policy->cpu;
+
+	if (freqs.old == freqs.new)
+		return 0;
+
+	/* pre-change notification */
+	cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
+
+	/* request the PRCM unit for opp change */
+	if (prcmu_set_arm_opp(idx2opp[idx])) {
+		pr_err("db8500-cpufreq:  Failed to set OPP level\n");
+		return -EINVAL;
+	}
+
+	/* post change notification */
+	cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
+
+	return 0;
+}
+
+static unsigned int db8500_cpufreq_getspeed(unsigned int cpu)
+{
+	int i;
+	/* request the prcm to get the current ARM opp */
+	for (i = 0; prcmu_get_arm_opp() != idx2opp[i]; i++)
+		;
+	return freq_table[i].frequency;
+}
+
+static int __cpuinit db8500_cpufreq_init(struct cpufreq_policy *policy)
+{
+	int res;
+	int i;
+
+	BUILD_BUG_ON(ARRAY_SIZE(idx2opp) + 1 != ARRAY_SIZE(freq_table));
+
+	if (cpu_is_u8500v2() && !prcmu_is_u8400()) {
+		freq_table[0].frequency = 400000;
+		freq_table[1].frequency = 800000;
+		if (prcmu_has_arm_maxopp())
+			freq_table[2].frequency = 1000000;
+	}
+
+	/* get policy fields based on the table */
+	res = cpufreq_frequency_table_cpuinfo(policy, freq_table);
+	if (!res)
+		cpufreq_frequency_table_get_attr(freq_table, policy->cpu);
+	else {
+		pr_err("db8500-cpufreq : Failed to read policy table\n");
+		return res;
+	}
+
+	policy->min = policy->cpuinfo.min_freq;
+	policy->max = policy->cpuinfo.max_freq;
+	policy->cur = db8500_cpufreq_getspeed(policy->cpu);
+
+	for (i = 0; freq_table[i].frequency != policy->cur; i++)
+		;
+
+	policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
+
+	/*
+	 * FIXME : Need to take time measurement across the target()
+	 *	   function with no/some/all drivers in the notification
+	 *	   list.
+	 */
+	policy->cpuinfo.transition_latency = 20 * 1000; /* in ns */
+
+	/* policy sharing between dual CPUs */
+	cpumask_copy(policy->cpus, &cpu_present_map);
+
+	policy->shared_type = CPUFREQ_SHARED_TYPE_ALL;
+
+	return 0;
+}
+
+static struct cpufreq_driver db8500_cpufreq_driver = {
+	.flags  = CPUFREQ_STICKY,
+	.verify = db8500_cpufreq_verify_speed,
+	.target = db8500_cpufreq_target,
+	.get    = db8500_cpufreq_getspeed,
+	.init   = db8500_cpufreq_init,
+	.name   = "DB8500",
+	.attr   = db8500_cpufreq_attr,
+};
+
+static int __init db8500_cpufreq_register(void)
+{
+	if (!cpu_is_u8500v20_or_later())
+		return -ENODEV;
+
+	pr_info("cpufreq for DB8500 started\n");
+	return cpufreq_register_driver(&db8500_cpufreq_driver);
+}
+device_initcall(db8500_cpufreq_register);
diff -druN linux-2.6.39-libre/drivers/cpufreq/elanfreq.c linux-3.0-rc7-libre/drivers/cpufreq/elanfreq.c
--- linux-2.6.39-libre/drivers/cpufreq/elanfreq.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/cpufreq/elanfreq.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,309 @@
+/*
+ *	elanfreq:	cpufreq driver for the AMD ELAN family
+ *
+ *	(c) Copyright 2002 Robert Schwebel <r.schwebel@pengutronix.de>
+ *
+ *	Parts of this code are (c) Sven Geggus <sven@geggus.net>
+ *
+ *      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.
+ *
+ *	2002-02-13: - initial revision for 2.4.18-pre9 by Robert Schwebel
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+
+#include <linux/delay.h>
+#include <linux/cpufreq.h>
+
+#include <asm/msr.h>
+#include <linux/timex.h>
+#include <linux/io.h>
+
+#define REG_CSCIR 0x22		/* Chip Setup and Control Index Register    */
+#define REG_CSCDR 0x23		/* Chip Setup and Control Data  Register    */
+
+/* Module parameter */
+static int max_freq;
+
+struct s_elan_multiplier {
+	int clock;		/* frequency in kHz                         */
+	int val40h;		/* PMU Force Mode register                  */
+	int val80h;		/* CPU Clock Speed Register                 */
+};
+
+/*
+ * It is important that the frequencies
+ * are listed in ascending order here!
+ */
+static struct s_elan_multiplier elan_multiplier[] = {
+	{1000,	0x02,	0x18},
+	{2000,	0x02,	0x10},
+	{4000,	0x02,	0x08},
+	{8000,	0x00,	0x00},
+	{16000,	0x00,	0x02},
+	{33000,	0x00,	0x04},
+	{66000,	0x01,	0x04},
+	{99000,	0x01,	0x05}
+};
+
+static struct cpufreq_frequency_table elanfreq_table[] = {
+	{0,	1000},
+	{1,	2000},
+	{2,	4000},
+	{3,	8000},
+	{4,	16000},
+	{5,	33000},
+	{6,	66000},
+	{7,	99000},
+	{0,	CPUFREQ_TABLE_END},
+};
+
+
+/**
+ *	elanfreq_get_cpu_frequency: determine current cpu speed
+ *
+ *	Finds out at which frequency the CPU of the Elan SOC runs
+ *	at the moment. Frequencies from 1 to 33 MHz are generated
+ *	the normal way, 66 and 99 MHz are called "Hyperspeed Mode"
+ *	and have the rest of the chip running with 33 MHz.
+ */
+
+static unsigned int elanfreq_get_cpu_frequency(unsigned int cpu)
+{
+	u8 clockspeed_reg;    /* Clock Speed Register */
+
+	local_irq_disable();
+	outb_p(0x80, REG_CSCIR);
+	clockspeed_reg = inb_p(REG_CSCDR);
+	local_irq_enable();
+
+	if ((clockspeed_reg & 0xE0) == 0xE0)
+		return 0;
+
+	/* Are we in CPU clock multiplied mode (66/99 MHz)? */
+	if ((clockspeed_reg & 0xE0) == 0xC0) {
+		if ((clockspeed_reg & 0x01) == 0)
+			return 66000;
+		else
+			return 99000;
+	}
+
+	/* 33 MHz is not 32 MHz... */
+	if ((clockspeed_reg & 0xE0) == 0xA0)
+		return 33000;
+
+	return (1<<((clockspeed_reg & 0xE0) >> 5)) * 1000;
+}
+
+
+/**
+ *	elanfreq_set_cpu_frequency: Change the CPU core frequency
+ *	@cpu: cpu number
+ *	@freq: frequency in kHz
+ *
+ *	This function takes a frequency value and changes the CPU frequency
+ *	according to this. Note that the frequency has to be checked by
+ *	elanfreq_validatespeed() for correctness!
+ *
+ *	There is no return value.
+ */
+
+static void elanfreq_set_cpu_state(unsigned int state)
+{
+	struct cpufreq_freqs    freqs;
+
+	freqs.old = elanfreq_get_cpu_frequency(0);
+	freqs.new = elan_multiplier[state].clock;
+	freqs.cpu = 0; /* elanfreq.c is UP only driver */
+
+	cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
+
+	printk(KERN_INFO "elanfreq: attempting to set frequency to %i kHz\n",
+			elan_multiplier[state].clock);
+
+
+	/*
+	 * Access to the Elan's internal registers is indexed via
+	 * 0x22: Chip Setup & Control Register Index Register (CSCI)
+	 * 0x23: Chip Setup & Control Register Data  Register (CSCD)
+	 *
+	 */
+
+	/*
+	 * 0x40 is the Power Management Unit's Force Mode Register.
+	 * Bit 6 enables Hyperspeed Mode (66/100 MHz core frequency)
+	 */
+
+	local_irq_disable();
+	outb_p(0x40, REG_CSCIR);		/* Disable hyperspeed mode */
+	outb_p(0x00, REG_CSCDR);
+	local_irq_enable();		/* wait till internal pipelines and */
+	udelay(1000);			/* buffers have cleaned up          */
+
+	local_irq_disable();
+
+	/* now, set the CPU clock speed register (0x80) */
+	outb_p(0x80, REG_CSCIR);
+	outb_p(elan_multiplier[state].val80h, REG_CSCDR);
+
+	/* now, the hyperspeed bit in PMU Force Mode Register (0x40) */
+	outb_p(0x40, REG_CSCIR);
+	outb_p(elan_multiplier[state].val40h, REG_CSCDR);
+	udelay(10000);
+	local_irq_enable();
+
+	cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
+};
+
+
+/**
+ *	elanfreq_validatespeed: test if frequency range is valid
+ *	@policy: the policy to validate
+ *
+ *	This function checks if a given frequency range in kHz is valid
+ *	for the hardware supported by the driver.
+ */
+
+static int elanfreq_verify(struct cpufreq_policy *policy)
+{
+	return cpufreq_frequency_table_verify(policy, &elanfreq_table[0]);
+}
+
+static int elanfreq_target(struct cpufreq_policy *policy,
+			    unsigned int target_freq,
+			    unsigned int relation)
+{
+	unsigned int newstate = 0;
+
+	if (cpufreq_frequency_table_target(policy, &elanfreq_table[0],
+				target_freq, relation, &newstate))
+		return -EINVAL;
+
+	elanfreq_set_cpu_state(newstate);
+
+	return 0;
+}
+
+
+/*
+ *	Module init and exit code
+ */
+
+static int elanfreq_cpu_init(struct cpufreq_policy *policy)
+{
+	struct cpuinfo_x86 *c = &cpu_data(0);
+	unsigned int i;
+	int result;
+
+	/* capability check */
+	if ((c->x86_vendor != X86_VENDOR_AMD) ||
+	    (c->x86 != 4) || (c->x86_model != 10))
+		return -ENODEV;
+
+	/* max freq */
+	if (!max_freq)
+		max_freq = elanfreq_get_cpu_frequency(0);
+
+	/* table init */
+	for (i = 0; (elanfreq_table[i].frequency != CPUFREQ_TABLE_END); i++) {
+		if (elanfreq_table[i].frequency > max_freq)
+			elanfreq_table[i].frequency = CPUFREQ_ENTRY_INVALID;
+	}
+
+	/* cpuinfo and default policy values */
+	policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL;
+	policy->cur = elanfreq_get_cpu_frequency(0);
+
+	result = cpufreq_frequency_table_cpuinfo(policy, elanfreq_table);
+	if (result)
+		return result;
+
+	cpufreq_frequency_table_get_attr(elanfreq_table, policy->cpu);
+	return 0;
+}
+
+
+static int elanfreq_cpu_exit(struct cpufreq_policy *policy)
+{
+	cpufreq_frequency_table_put_attr(policy->cpu);
+	return 0;
+}
+
+
+#ifndef MODULE
+/**
+ * elanfreq_setup - elanfreq command line parameter parsing
+ *
+ * elanfreq command line parameter.  Use:
+ *  elanfreq=66000
+ * to set the maximum CPU frequency to 66 MHz. Note that in
+ * case you do not give this boot parameter, the maximum
+ * frequency will fall back to _current_ CPU frequency which
+ * might be lower. If you build this as a module, use the
+ * max_freq module parameter instead.
+ */
+static int __init elanfreq_setup(char *str)
+{
+	max_freq = simple_strtoul(str, &str, 0);
+	printk(KERN_WARNING "You're using the deprecated elanfreq command line option. Use elanfreq.max_freq instead, please!\n");
+	return 1;
+}
+__setup("elanfreq=", elanfreq_setup);
+#endif
+
+
+static struct freq_attr *elanfreq_attr[] = {
+	&cpufreq_freq_attr_scaling_available_freqs,
+	NULL,
+};
+
+
+static struct cpufreq_driver elanfreq_driver = {
+	.get		= elanfreq_get_cpu_frequency,
+	.verify		= elanfreq_verify,
+	.target		= elanfreq_target,
+	.init		= elanfreq_cpu_init,
+	.exit		= elanfreq_cpu_exit,
+	.name		= "elanfreq",
+	.owner		= THIS_MODULE,
+	.attr		= elanfreq_attr,
+};
+
+
+static int __init elanfreq_init(void)
+{
+	struct cpuinfo_x86 *c = &cpu_data(0);
+
+	/* Test if we have the right hardware */
+	if ((c->x86_vendor != X86_VENDOR_AMD) ||
+		(c->x86 != 4) || (c->x86_model != 10)) {
+		printk(KERN_INFO "elanfreq: error: no Elan processor found!\n");
+		return -ENODEV;
+	}
+	return cpufreq_register_driver(&elanfreq_driver);
+}
+
+
+static void __exit elanfreq_exit(void)
+{
+	cpufreq_unregister_driver(&elanfreq_driver);
+}
+
+
+module_param(max_freq, int, 0444);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Robert Schwebel <r.schwebel@pengutronix.de>, "
+		"Sven Geggus <sven@geggus.net>");
+MODULE_DESCRIPTION("cpufreq driver for AMD's Elan CPUs");
+
+module_init(elanfreq_init);
+module_exit(elanfreq_exit);
diff -druN linux-2.6.39-libre/drivers/cpufreq/e_powersaver.c linux-3.0-rc7-libre/drivers/cpufreq/e_powersaver.c
--- linux-2.6.39-libre/drivers/cpufreq/e_powersaver.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/cpufreq/e_powersaver.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,367 @@
+/*
+ *  Based on documentation provided by Dave Jones. Thanks!
+ *
+ *  Licensed under the terms of the GNU GPL License version 2.
+ *
+ *  BIG FAT DISCLAIMER: Work in progress code. Possibly *dangerous*
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/cpufreq.h>
+#include <linux/ioport.h>
+#include <linux/slab.h>
+#include <linux/timex.h>
+#include <linux/io.h>
+#include <linux/delay.h>
+
+#include <asm/msr.h>
+#include <asm/tsc.h>
+
+#define EPS_BRAND_C7M	0
+#define EPS_BRAND_C7	1
+#define EPS_BRAND_EDEN	2
+#define EPS_BRAND_C3	3
+#define EPS_BRAND_C7D	4
+
+struct eps_cpu_data {
+	u32 fsb;
+	struct cpufreq_frequency_table freq_table[];
+};
+
+static struct eps_cpu_data *eps_cpu[NR_CPUS];
+
+
+static unsigned int eps_get(unsigned int cpu)
+{
+	struct eps_cpu_data *centaur;
+	u32 lo, hi;
+
+	if (cpu)
+		return 0;
+	centaur = eps_cpu[cpu];
+	if (centaur == NULL)
+		return 0;
+
+	/* Return current frequency */
+	rdmsr(MSR_IA32_PERF_STATUS, lo, hi);
+	return centaur->fsb * ((lo >> 8) & 0xff);
+}
+
+static int eps_set_state(struct eps_cpu_data *centaur,
+			 unsigned int cpu,
+			 u32 dest_state)
+{
+	struct cpufreq_freqs freqs;
+	u32 lo, hi;
+	int err = 0;
+	int i;
+
+	freqs.old = eps_get(cpu);
+	freqs.new = centaur->fsb * ((dest_state >> 8) & 0xff);
+	freqs.cpu = cpu;
+	cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
+
+	/* Wait while CPU is busy */
+	rdmsr(MSR_IA32_PERF_STATUS, lo, hi);
+	i = 0;
+	while (lo & ((1 << 16) | (1 << 17))) {
+		udelay(16);
+		rdmsr(MSR_IA32_PERF_STATUS, lo, hi);
+		i++;
+		if (unlikely(i > 64)) {
+			err = -ENODEV;
+			goto postchange;
+		}
+	}
+	/* Set new multiplier and voltage */
+	wrmsr(MSR_IA32_PERF_CTL, dest_state & 0xffff, 0);
+	/* Wait until transition end */
+	i = 0;
+	do {
+		udelay(16);
+		rdmsr(MSR_IA32_PERF_STATUS, lo, hi);
+		i++;
+		if (unlikely(i > 64)) {
+			err = -ENODEV;
+			goto postchange;
+		}
+	} while (lo & ((1 << 16) | (1 << 17)));
+
+	/* Return current frequency */
+postchange:
+	rdmsr(MSR_IA32_PERF_STATUS, lo, hi);
+	freqs.new = centaur->fsb * ((lo >> 8) & 0xff);
+
+#ifdef DEBUG
+	{
+	u8 current_multiplier, current_voltage;
+
+	/* Print voltage and multiplier */
+	rdmsr(MSR_IA32_PERF_STATUS, lo, hi);
+	current_voltage = lo & 0xff;
+	printk(KERN_INFO "eps: Current voltage = %dmV\n",
+		current_voltage * 16 + 700);
+	current_multiplier = (lo >> 8) & 0xff;
+	printk(KERN_INFO "eps: Current multiplier = %d\n",
+		current_multiplier);
+	}
+#endif
+	cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
+	return err;
+}
+
+static int eps_target(struct cpufreq_policy *policy,
+			       unsigned int target_freq,
+			       unsigned int relation)
+{
+	struct eps_cpu_data *centaur;
+	unsigned int newstate = 0;
+	unsigned int cpu = policy->cpu;
+	unsigned int dest_state;
+	int ret;
+
+	if (unlikely(eps_cpu[cpu] == NULL))
+		return -ENODEV;
+	centaur = eps_cpu[cpu];
+
+	if (unlikely(cpufreq_frequency_table_target(policy,
+			&eps_cpu[cpu]->freq_table[0],
+			target_freq,
+			relation,
+			&newstate))) {
+		return -EINVAL;
+	}
+
+	/* Make frequency transition */
+	dest_state = centaur->freq_table[newstate].index & 0xffff;
+	ret = eps_set_state(centaur, cpu, dest_state);
+	if (ret)
+		printk(KERN_ERR "eps: Timeout!\n");
+	return ret;
+}
+
+static int eps_verify(struct cpufreq_policy *policy)
+{
+	return cpufreq_frequency_table_verify(policy,
+			&eps_cpu[policy->cpu]->freq_table[0]);
+}
+
+static int eps_cpu_init(struct cpufreq_policy *policy)
+{
+	unsigned int i;
+	u32 lo, hi;
+	u64 val;
+	u8 current_multiplier, current_voltage;
+	u8 max_multiplier, max_voltage;
+	u8 min_multiplier, min_voltage;
+	u8 brand = 0;
+	u32 fsb;
+	struct eps_cpu_data *centaur;
+	struct cpuinfo_x86 *c = &cpu_data(0);
+	struct cpufreq_frequency_table *f_table;
+	int k, step, voltage;
+	int ret;
+	int states;
+
+	if (policy->cpu != 0)
+		return -ENODEV;
+
+	/* Check brand */
+	printk(KERN_INFO "eps: Detected VIA ");
+
+	switch (c->x86_model) {
+	case 10:
+		rdmsr(0x1153, lo, hi);
+		brand = (((lo >> 2) ^ lo) >> 18) & 3;
+		printk(KERN_CONT "Model A ");
+		break;
+	case 13:
+		rdmsr(0x1154, lo, hi);
+		brand = (((lo >> 4) ^ (lo >> 2))) & 0x000000ff;
+		printk(KERN_CONT "Model D ");
+		break;
+	}
+
+	switch (brand) {
+	case EPS_BRAND_C7M:
+		printk(KERN_CONT "C7-M\n");
+		break;
+	case EPS_BRAND_C7:
+		printk(KERN_CONT "C7\n");
+		break;
+	case EPS_BRAND_EDEN:
+		printk(KERN_CONT "Eden\n");
+		break;
+	case EPS_BRAND_C7D:
+		printk(KERN_CONT "C7-D\n");
+		break;
+	case EPS_BRAND_C3:
+		printk(KERN_CONT "C3\n");
+		return -ENODEV;
+		break;
+	}
+	/* Enable Enhanced PowerSaver */
+	rdmsrl(MSR_IA32_MISC_ENABLE, val);
+	if (!(val & MSR_IA32_MISC_ENABLE_ENHANCED_SPEEDSTEP)) {
+		val |= MSR_IA32_MISC_ENABLE_ENHANCED_SPEEDSTEP;
+		wrmsrl(MSR_IA32_MISC_ENABLE, val);
+		/* Can be locked at 0 */
+		rdmsrl(MSR_IA32_MISC_ENABLE, val);
+		if (!(val & MSR_IA32_MISC_ENABLE_ENHANCED_SPEEDSTEP)) {
+			printk(KERN_INFO "eps: Can't enable Enhanced PowerSaver\n");
+			return -ENODEV;
+		}
+	}
+
+	/* Print voltage and multiplier */
+	rdmsr(MSR_IA32_PERF_STATUS, lo, hi);
+	current_voltage = lo & 0xff;
+	printk(KERN_INFO "eps: Current voltage = %dmV\n",
+			current_voltage * 16 + 700);
+	current_multiplier = (lo >> 8) & 0xff;
+	printk(KERN_INFO "eps: Current multiplier = %d\n", current_multiplier);
+
+	/* Print limits */
+	max_voltage = hi & 0xff;
+	printk(KERN_INFO "eps: Highest voltage = %dmV\n",
+			max_voltage * 16 + 700);
+	max_multiplier = (hi >> 8) & 0xff;
+	printk(KERN_INFO "eps: Highest multiplier = %d\n", max_multiplier);
+	min_voltage = (hi >> 16) & 0xff;
+	printk(KERN_INFO "eps: Lowest voltage = %dmV\n",
+			min_voltage * 16 + 700);
+	min_multiplier = (hi >> 24) & 0xff;
+	printk(KERN_INFO "eps: Lowest multiplier = %d\n", min_multiplier);
+
+	/* Sanity checks */
+	if (current_multiplier == 0 || max_multiplier == 0
+	    || min_multiplier == 0)
+		return -EINVAL;
+	if (current_multiplier > max_multiplier
+	    || max_multiplier <= min_multiplier)
+		return -EINVAL;
+	if (current_voltage > 0x1f || max_voltage > 0x1f)
+		return -EINVAL;
+	if (max_voltage < min_voltage)
+		return -EINVAL;
+
+	/* Calc FSB speed */
+	fsb = cpu_khz / current_multiplier;
+	/* Calc number of p-states supported */
+	if (brand == EPS_BRAND_C7M)
+		states = max_multiplier - min_multiplier + 1;
+	else
+		states = 2;
+
+	/* Allocate private data and frequency table for current cpu */
+	centaur = kzalloc(sizeof(struct eps_cpu_data)
+		    + (states + 1) * sizeof(struct cpufreq_frequency_table),
+		    GFP_KERNEL);
+	if (!centaur)
+		return -ENOMEM;
+	eps_cpu[0] = centaur;
+
+	/* Copy basic values */
+	centaur->fsb = fsb;
+
+	/* Fill frequency and MSR value table */
+	f_table = &centaur->freq_table[0];
+	if (brand != EPS_BRAND_C7M) {
+		f_table[0].frequency = fsb * min_multiplier;
+		f_table[0].index = (min_multiplier << 8) | min_voltage;
+		f_table[1].frequency = fsb * max_multiplier;
+		f_table[1].index = (max_multiplier << 8) | max_voltage;
+		f_table[2].frequency = CPUFREQ_TABLE_END;
+	} else {
+		k = 0;
+		step = ((max_voltage - min_voltage) * 256)
+			/ (max_multiplier - min_multiplier);
+		for (i = min_multiplier; i <= max_multiplier; i++) {
+			voltage = (k * step) / 256 + min_voltage;
+			f_table[k].frequency = fsb * i;
+			f_table[k].index = (i << 8) | voltage;
+			k++;
+		}
+		f_table[k].frequency = CPUFREQ_TABLE_END;
+	}
+
+	policy->cpuinfo.transition_latency = 140000; /* 844mV -> 700mV in ns */
+	policy->cur = fsb * current_multiplier;
+
+	ret = cpufreq_frequency_table_cpuinfo(policy, &centaur->freq_table[0]);
+	if (ret) {
+		kfree(centaur);
+		return ret;
+	}
+
+	cpufreq_frequency_table_get_attr(&centaur->freq_table[0], policy->cpu);
+	return 0;
+}
+
+static int eps_cpu_exit(struct cpufreq_policy *policy)
+{
+	unsigned int cpu = policy->cpu;
+	struct eps_cpu_data *centaur;
+	u32 lo, hi;
+
+	if (eps_cpu[cpu] == NULL)
+		return -ENODEV;
+	centaur = eps_cpu[cpu];
+
+	/* Get max frequency */
+	rdmsr(MSR_IA32_PERF_STATUS, lo, hi);
+	/* Set max frequency */
+	eps_set_state(centaur, cpu, hi & 0xffff);
+	/* Bye */
+	cpufreq_frequency_table_put_attr(policy->cpu);
+	kfree(eps_cpu[cpu]);
+	eps_cpu[cpu] = NULL;
+	return 0;
+}
+
+static struct freq_attr *eps_attr[] = {
+	&cpufreq_freq_attr_scaling_available_freqs,
+	NULL,
+};
+
+static struct cpufreq_driver eps_driver = {
+	.verify		= eps_verify,
+	.target		= eps_target,
+	.init		= eps_cpu_init,
+	.exit		= eps_cpu_exit,
+	.get		= eps_get,
+	.name		= "e_powersaver",
+	.owner		= THIS_MODULE,
+	.attr		= eps_attr,
+};
+
+static int __init eps_init(void)
+{
+	struct cpuinfo_x86 *c = &cpu_data(0);
+
+	/* This driver will work only on Centaur C7 processors with
+	 * Enhanced SpeedStep/PowerSaver registers */
+	if (c->x86_vendor != X86_VENDOR_CENTAUR
+	    || c->x86 != 6 || c->x86_model < 10)
+		return -ENODEV;
+	if (!cpu_has(c, X86_FEATURE_EST))
+		return -ENODEV;
+
+	if (cpufreq_register_driver(&eps_driver))
+		return -EINVAL;
+	return 0;
+}
+
+static void __exit eps_exit(void)
+{
+	cpufreq_unregister_driver(&eps_driver);
+}
+
+MODULE_AUTHOR("Rafal Bilski <rafalbilski@interia.pl>");
+MODULE_DESCRIPTION("Enhanced PowerSaver driver for VIA C7 CPU's.");
+MODULE_LICENSE("GPL");
+
+module_init(eps_init);
+module_exit(eps_exit);
diff -druN linux-2.6.39-libre/drivers/cpufreq/freq_table.c linux-3.0-rc7-libre/drivers/cpufreq/freq_table.c
--- linux-2.6.39-libre/drivers/cpufreq/freq_table.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/cpufreq/freq_table.c	2011-07-11 19:51:52.000000000 -0400
@@ -14,9 +14,6 @@
 #include <linux/init.h>
 #include <linux/cpufreq.h>
 
-#define dprintk(msg...) \
-	cpufreq_debug_printk(CPUFREQ_DEBUG_CORE, "freq-table", msg)
-
 /*********************************************************************
  *                     FREQUENCY TABLE HELPERS                       *
  *********************************************************************/
@@ -31,11 +28,11 @@
 	for (i = 0; (table[i].frequency != CPUFREQ_TABLE_END); i++) {
 		unsigned int freq = table[i].frequency;
 		if (freq == CPUFREQ_ENTRY_INVALID) {
-			dprintk("table entry %u is invalid, skipping\n", i);
+			pr_debug("table entry %u is invalid, skipping\n", i);
 
 			continue;
 		}
-		dprintk("table entry %u: %u kHz, %u index\n",
+		pr_debug("table entry %u: %u kHz, %u index\n",
 					i, freq, table[i].index);
 		if (freq < min_freq)
 			min_freq = freq;
@@ -61,7 +58,7 @@
 	unsigned int i;
 	unsigned int count = 0;
 
-	dprintk("request for verification of policy (%u - %u kHz) for cpu %u\n",
+	pr_debug("request for verification of policy (%u - %u kHz) for cpu %u\n",
 					policy->min, policy->max, policy->cpu);
 
 	if (!cpu_online(policy->cpu))
@@ -86,7 +83,7 @@
 	cpufreq_verify_within_limits(policy, policy->cpuinfo.min_freq,
 				     policy->cpuinfo.max_freq);
 
-	dprintk("verification lead to (%u - %u kHz) for cpu %u\n",
+	pr_debug("verification lead to (%u - %u kHz) for cpu %u\n",
 				policy->min, policy->max, policy->cpu);
 
 	return 0;
@@ -110,7 +107,7 @@
 	};
 	unsigned int i;
 
-	dprintk("request for target %u kHz (relation: %u) for cpu %u\n",
+	pr_debug("request for target %u kHz (relation: %u) for cpu %u\n",
 					target_freq, relation, policy->cpu);
 
 	switch (relation) {
@@ -167,7 +164,7 @@
 	} else
 		*index = optimal.index;
 
-	dprintk("target is %u (%u kHz, %u)\n", *index, table[*index].frequency,
+	pr_debug("target is %u (%u kHz, %u)\n", *index, table[*index].frequency,
 		table[*index].index);
 
 	return 0;
@@ -216,14 +213,14 @@
 void cpufreq_frequency_table_get_attr(struct cpufreq_frequency_table *table,
 				      unsigned int cpu)
 {
-	dprintk("setting show_table for cpu %u to %p\n", cpu, table);
+	pr_debug("setting show_table for cpu %u to %p\n", cpu, table);
 	per_cpu(cpufreq_show_table, cpu) = table;
 }
 EXPORT_SYMBOL_GPL(cpufreq_frequency_table_get_attr);
 
 void cpufreq_frequency_table_put_attr(unsigned int cpu)
 {
-	dprintk("clearing show_table for cpu %u\n", cpu);
+	pr_debug("clearing show_table for cpu %u\n", cpu);
 	per_cpu(cpufreq_show_table, cpu) = NULL;
 }
 EXPORT_SYMBOL_GPL(cpufreq_frequency_table_put_attr);
diff -druN linux-2.6.39-libre/drivers/cpufreq/gx-suspmod.c linux-3.0-rc7-libre/drivers/cpufreq/gx-suspmod.c
--- linux-2.6.39-libre/drivers/cpufreq/gx-suspmod.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/cpufreq/gx-suspmod.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,514 @@
+/*
+ *	Cyrix MediaGX and NatSemi Geode Suspend Modulation
+ *	(C) 2002 Zwane Mwaikambo <zwane@commfireservices.com>
+ *	(C) 2002 Hiroshi Miura   <miura@da-cha.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
+ *      version 2 as published by the Free Software Foundation
+ *
+ *      The author(s) of this software shall not be held liable for damages
+ *      of any nature resulting due to the use of this software. This
+ *      software is provided AS-IS with no warranties.
+ *
+ * Theoretical note:
+ *
+ *	(see Geode(tm) CS5530 manual (rev.4.1) page.56)
+ *
+ *	CPU frequency control on NatSemi Geode GX1/GXLV processor and CS55x0
+ *	are based on Suspend Modulation.
+ *
+ *	Suspend Modulation works by asserting and de-asserting the SUSP# pin
+ *	to CPU(GX1/GXLV) for configurable durations. When asserting SUSP#
+ *	the CPU enters an idle state. GX1 stops its core clock when SUSP# is
+ *	asserted then power consumption is reduced.
+ *
+ *	Suspend Modulation's OFF/ON duration are configurable
+ *	with 'Suspend Modulation OFF Count Register'
+ *	and 'Suspend Modulation ON Count Register'.
+ *	These registers are 8bit counters that represent the number of
+ *	32us intervals which the SUSP# pin is asserted(ON)/de-asserted(OFF)
+ *	to the processor.
+ *
+ *	These counters define a ratio which is the effective frequency
+ *	of operation of the system.
+ *
+ *			       OFF Count
+ *	F_eff = Fgx * ----------------------
+ *	                OFF Count + ON Count
+ *
+ *	0 <= On Count, Off Count <= 255
+ *
+ *	From these limits, we can get register values
+ *
+ *	off_duration + on_duration <= MAX_DURATION
+ *	on_duration = off_duration * (stock_freq - freq) / freq
+ *
+ *      off_duration  =  (freq * DURATION) / stock_freq
+ *      on_duration = DURATION - off_duration
+ *
+ *
+ *---------------------------------------------------------------------------
+ *
+ * ChangeLog:
+ *	Dec. 12, 2003	Hiroshi Miura <miura@da-cha.org>
+ *		- fix on/off register mistake
+ *		- fix cpu_khz calc when it stops cpu modulation.
+ *
+ *	Dec. 11, 2002	Hiroshi Miura <miura@da-cha.org>
+ *		- rewrite for Cyrix MediaGX Cx5510/5520 and
+ *		  NatSemi Geode Cs5530(A).
+ *
+ *	Jul. ??, 2002  Zwane Mwaikambo <zwane@commfireservices.com>
+ *		- cs5530_mod patch for 2.4.19-rc1.
+ *
+ *---------------------------------------------------------------------------
+ *
+ * Todo
+ *	Test on machines with 5510, 5530, 5530A
+ */
+
+/************************************************************************
+ *			Suspend Modulation - Definitions		*
+ ************************************************************************/
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/smp.h>
+#include <linux/cpufreq.h>
+#include <linux/pci.h>
+#include <linux/errno.h>
+#include <linux/slab.h>
+
+#include <asm/processor-cyrix.h>
+
+/* PCI config registers, all at F0 */
+#define PCI_PMER1	0x80	/* power management enable register 1 */
+#define PCI_PMER2	0x81	/* power management enable register 2 */
+#define PCI_PMER3	0x82	/* power management enable register 3 */
+#define PCI_IRQTC	0x8c	/* irq speedup timer counter register:typical 2 to 4ms */
+#define PCI_VIDTC	0x8d	/* video speedup timer counter register: typical 50 to 100ms */
+#define PCI_MODOFF	0x94	/* suspend modulation OFF counter register, 1 = 32us */
+#define PCI_MODON	0x95	/* suspend modulation ON counter register */
+#define PCI_SUSCFG	0x96	/* suspend configuration register */
+
+/* PMER1 bits */
+#define GPM		(1<<0)	/* global power management */
+#define GIT		(1<<1)	/* globally enable PM device idle timers */
+#define GTR		(1<<2)	/* globally enable IO traps */
+#define IRQ_SPDUP	(1<<3)	/* disable clock throttle during interrupt handling */
+#define VID_SPDUP	(1<<4)	/* disable clock throttle during vga video handling */
+
+/* SUSCFG bits */
+#define SUSMOD		(1<<0)	/* enable/disable suspend modulation */
+/* the below is supported only with cs5530 (after rev.1.2)/cs5530A */
+#define SMISPDUP	(1<<1)	/* select how SMI re-enable suspend modulation: */
+				/* IRQTC timer or read SMI speedup disable reg.(F1BAR[08-09h]) */
+#define SUSCFG		(1<<2)	/* enable powering down a GXLV processor. "Special 3Volt Suspend" mode */
+/* the below is supported only with cs5530A */
+#define PWRSVE_ISA	(1<<3)	/* stop ISA clock  */
+#define PWRSVE		(1<<4)	/* active idle */
+
+struct gxfreq_params {
+	u8 on_duration;
+	u8 off_duration;
+	u8 pci_suscfg;
+	u8 pci_pmer1;
+	u8 pci_pmer2;
+	struct pci_dev *cs55x0;
+};
+
+static struct gxfreq_params *gx_params;
+static int stock_freq;
+
+/* PCI bus clock - defaults to 30.000 if cpu_khz is not available */
+static int pci_busclk;
+module_param(pci_busclk, int, 0444);
+
+/* maximum duration for which the cpu may be suspended
+ * (32us * MAX_DURATION). If no parameter is given, this defaults
+ * to 255.
+ * Note that this leads to a maximum of 8 ms(!) where the CPU clock
+ * is suspended -- processing power is just 0.39% of what it used to be,
+ * though. 781.25 kHz(!) for a 200 MHz processor -- wow. */
+static int max_duration = 255;
+module_param(max_duration, int, 0444);
+
+/* For the default policy, we want at least some processing power
+ * - let's say 5%. (min = maxfreq / POLICY_MIN_DIV)
+ */
+#define POLICY_MIN_DIV 20
+
+
+/**
+ * we can detect a core multipiler from dir0_lsb
+ * from GX1 datasheet p.56,
+ *	MULT[3:0]:
+ *	0000 = SYSCLK multiplied by 4 (test only)
+ *	0001 = SYSCLK multiplied by 10
+ *	0010 = SYSCLK multiplied by 4
+ *	0011 = SYSCLK multiplied by 6
+ *	0100 = SYSCLK multiplied by 9
+ *	0101 = SYSCLK multiplied by 5
+ *	0110 = SYSCLK multiplied by 7
+ *	0111 = SYSCLK multiplied by 8
+ *              of 33.3MHz
+ **/
+static int gx_freq_mult[16] = {
+		4, 10, 4, 6, 9, 5, 7, 8,
+		0, 0, 0, 0, 0, 0, 0, 0
+};
+
+
+/****************************************************************
+ *	Low Level chipset interface				*
+ ****************************************************************/
+static struct pci_device_id gx_chipset_tbl[] __initdata = {
+	{ PCI_VDEVICE(CYRIX, PCI_DEVICE_ID_CYRIX_5530_LEGACY), },
+	{ PCI_VDEVICE(CYRIX, PCI_DEVICE_ID_CYRIX_5520), },
+	{ PCI_VDEVICE(CYRIX, PCI_DEVICE_ID_CYRIX_5510), },
+	{ 0, },
+};
+
+static void gx_write_byte(int reg, int value)
+{
+	pci_write_config_byte(gx_params->cs55x0, reg, value);
+}
+
+/**
+ * gx_detect_chipset:
+ *
+ **/
+static __init struct pci_dev *gx_detect_chipset(void)
+{
+	struct pci_dev *gx_pci = NULL;
+
+	/* check if CPU is a MediaGX or a Geode. */
+	if ((boot_cpu_data.x86_vendor != X86_VENDOR_NSC) &&
+	    (boot_cpu_data.x86_vendor != X86_VENDOR_CYRIX)) {
+		pr_debug("error: no MediaGX/Geode processor found!\n");
+		return NULL;
+	}
+
+	/* detect which companion chip is used */
+	for_each_pci_dev(gx_pci) {
+		if ((pci_match_id(gx_chipset_tbl, gx_pci)) != NULL)
+			return gx_pci;
+	}
+
+	pr_debug("error: no supported chipset found!\n");
+	return NULL;
+}
+
+/**
+ * gx_get_cpuspeed:
+ *
+ * Finds out at which efficient frequency the Cyrix MediaGX/NatSemi
+ * Geode CPU runs.
+ */
+static unsigned int gx_get_cpuspeed(unsigned int cpu)
+{
+	if ((gx_params->pci_suscfg & SUSMOD) == 0)
+		return stock_freq;
+
+	return (stock_freq * gx_params->off_duration)
+		/ (gx_params->on_duration + gx_params->off_duration);
+}
+
+/**
+ *      gx_validate_speed:
+ *      determine current cpu speed
+ *
+ **/
+
+static unsigned int gx_validate_speed(unsigned int khz, u8 *on_duration,
+		u8 *off_duration)
+{
+	unsigned int i;
+	u8 tmp_on, tmp_off;
+	int old_tmp_freq = stock_freq;
+	int tmp_freq;
+
+	*off_duration = 1;
+	*on_duration = 0;
+
+	for (i = max_duration; i > 0; i--) {
+		tmp_off = ((khz * i) / stock_freq) & 0xff;
+		tmp_on = i - tmp_off;
+		tmp_freq = (stock_freq * tmp_off) / i;
+		/* if this relation is closer to khz, use this. If it's equal,
+		 * prefer it, too - lower latency */
+		if (abs(tmp_freq - khz) <= abs(old_tmp_freq - khz)) {
+			*on_duration = tmp_on;
+			*off_duration = tmp_off;
+			old_tmp_freq = tmp_freq;
+		}
+	}
+
+	return old_tmp_freq;
+}
+
+
+/**
+ * gx_set_cpuspeed:
+ * set cpu speed in khz.
+ **/
+
+static void gx_set_cpuspeed(unsigned int khz)
+{
+	u8 suscfg, pmer1;
+	unsigned int new_khz;
+	unsigned long flags;
+	struct cpufreq_freqs freqs;
+
+	freqs.cpu = 0;
+	freqs.old = gx_get_cpuspeed(0);
+
+	new_khz = gx_validate_speed(khz, &gx_params->on_duration,
+			&gx_params->off_duration);
+
+	freqs.new = new_khz;
+
+	cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
+	local_irq_save(flags);
+
+
+
+	if (new_khz != stock_freq) {
+		/* if new khz == 100% of CPU speed, it is special case */
+		switch (gx_params->cs55x0->device) {
+		case PCI_DEVICE_ID_CYRIX_5530_LEGACY:
+			pmer1 = gx_params->pci_pmer1 | IRQ_SPDUP | VID_SPDUP;
+			/* FIXME: need to test other values -- Zwane,Miura */
+			/* typical 2 to 4ms */
+			gx_write_byte(PCI_IRQTC, 4);
+			/* typical 50 to 100ms */
+			gx_write_byte(PCI_VIDTC, 100);
+			gx_write_byte(PCI_PMER1, pmer1);
+
+			if (gx_params->cs55x0->revision < 0x10) {
+				/* CS5530(rev 1.2, 1.3) */
+				suscfg = gx_params->pci_suscfg|SUSMOD;
+			} else {
+				/* CS5530A,B.. */
+				suscfg = gx_params->pci_suscfg|SUSMOD|PWRSVE;
+			}
+			break;
+		case PCI_DEVICE_ID_CYRIX_5520:
+		case PCI_DEVICE_ID_CYRIX_5510:
+			suscfg = gx_params->pci_suscfg | SUSMOD;
+			break;
+		default:
+			local_irq_restore(flags);
+			pr_debug("fatal: try to set unknown chipset.\n");
+			return;
+		}
+	} else {
+		suscfg = gx_params->pci_suscfg & ~(SUSMOD);
+		gx_params->off_duration = 0;
+		gx_params->on_duration = 0;
+		pr_debug("suspend modulation disabled: cpu runs 100%% speed.\n");
+	}
+
+	gx_write_byte(PCI_MODOFF, gx_params->off_duration);
+	gx_write_byte(PCI_MODON, gx_params->on_duration);
+
+	gx_write_byte(PCI_SUSCFG, suscfg);
+	pci_read_config_byte(gx_params->cs55x0, PCI_SUSCFG, &suscfg);
+
+	local_irq_restore(flags);
+
+	gx_params->pci_suscfg = suscfg;
+
+	cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
+
+	pr_debug("suspend modulation w/ duration of ON:%d us, OFF:%d us\n",
+		gx_params->on_duration * 32, gx_params->off_duration * 32);
+	pr_debug("suspend modulation w/ clock speed: %d kHz.\n", freqs.new);
+}
+
+/****************************************************************
+ *             High level functions                             *
+ ****************************************************************/
+
+/*
+ *	cpufreq_gx_verify: test if frequency range is valid
+ *
+ *	This function checks if a given frequency range in kHz is valid
+ *      for the hardware supported by the driver.
+ */
+
+static int cpufreq_gx_verify(struct cpufreq_policy *policy)
+{
+	unsigned int tmp_freq = 0;
+	u8 tmp1, tmp2;
+
+	if (!stock_freq || !policy)
+		return -EINVAL;
+
+	policy->cpu = 0;
+	cpufreq_verify_within_limits(policy, (stock_freq / max_duration),
+			stock_freq);
+
+	/* it needs to be assured that at least one supported frequency is
+	 * within policy->min and policy->max. If it is not, policy->max
+	 * needs to be increased until one freuqency is supported.
+	 * policy->min may not be decreased, though. This way we guarantee a
+	 * specific processing capacity.
+	 */
+	tmp_freq = gx_validate_speed(policy->min, &tmp1, &tmp2);
+	if (tmp_freq < policy->min)
+		tmp_freq += stock_freq / max_duration;
+	policy->min = tmp_freq;
+	if (policy->min > policy->max)
+		policy->max = tmp_freq;
+	tmp_freq = gx_validate_speed(policy->max, &tmp1, &tmp2);
+	if (tmp_freq > policy->max)
+		tmp_freq -= stock_freq / max_duration;
+	policy->max = tmp_freq;
+	if (policy->max < policy->min)
+		policy->max = policy->min;
+	cpufreq_verify_within_limits(policy, (stock_freq / max_duration),
+			stock_freq);
+
+	return 0;
+}
+
+/*
+ *      cpufreq_gx_target:
+ *
+ */
+static int cpufreq_gx_target(struct cpufreq_policy *policy,
+			     unsigned int target_freq,
+			     unsigned int relation)
+{
+	u8 tmp1, tmp2;
+	unsigned int tmp_freq;
+
+	if (!stock_freq || !policy)
+		return -EINVAL;
+
+	policy->cpu = 0;
+
+	tmp_freq = gx_validate_speed(target_freq, &tmp1, &tmp2);
+	while (tmp_freq < policy->min) {
+		tmp_freq += stock_freq / max_duration;
+		tmp_freq = gx_validate_speed(tmp_freq, &tmp1, &tmp2);
+	}
+	while (tmp_freq > policy->max) {
+		tmp_freq -= stock_freq / max_duration;
+		tmp_freq = gx_validate_speed(tmp_freq, &tmp1, &tmp2);
+	}
+
+	gx_set_cpuspeed(tmp_freq);
+
+	return 0;
+}
+
+static int cpufreq_gx_cpu_init(struct cpufreq_policy *policy)
+{
+	unsigned int maxfreq, curfreq;
+
+	if (!policy || policy->cpu != 0)
+		return -ENODEV;
+
+	/* determine maximum frequency */
+	if (pci_busclk)
+		maxfreq = pci_busclk * gx_freq_mult[getCx86(CX86_DIR1) & 0x0f];
+	else if (cpu_khz)
+		maxfreq = cpu_khz;
+	else
+		maxfreq = 30000 * gx_freq_mult[getCx86(CX86_DIR1) & 0x0f];
+
+	stock_freq = maxfreq;
+	curfreq = gx_get_cpuspeed(0);
+
+	pr_debug("cpu max frequency is %d.\n", maxfreq);
+	pr_debug("cpu current frequency is %dkHz.\n", curfreq);
+
+	/* setup basic struct for cpufreq API */
+	policy->cpu = 0;
+
+	if (max_duration < POLICY_MIN_DIV)
+		policy->min = maxfreq / max_duration;
+	else
+		policy->min = maxfreq / POLICY_MIN_DIV;
+	policy->max = maxfreq;
+	policy->cur = curfreq;
+	policy->cpuinfo.min_freq = maxfreq / max_duration;
+	policy->cpuinfo.max_freq = maxfreq;
+	policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL;
+
+	return 0;
+}
+
+/*
+ * cpufreq_gx_init:
+ *   MediaGX/Geode GX initialize cpufreq driver
+ */
+static struct cpufreq_driver gx_suspmod_driver = {
+	.get		= gx_get_cpuspeed,
+	.verify		= cpufreq_gx_verify,
+	.target		= cpufreq_gx_target,
+	.init		= cpufreq_gx_cpu_init,
+	.name		= "gx-suspmod",
+	.owner		= THIS_MODULE,
+};
+
+static int __init cpufreq_gx_init(void)
+{
+	int ret;
+	struct gxfreq_params *params;
+	struct pci_dev *gx_pci;
+
+	/* Test if we have the right hardware */
+	gx_pci = gx_detect_chipset();
+	if (gx_pci == NULL)
+		return -ENODEV;
+
+	/* check whether module parameters are sane */
+	if (max_duration > 0xff)
+		max_duration = 0xff;
+
+	pr_debug("geode suspend modulation available.\n");
+
+	params = kzalloc(sizeof(struct gxfreq_params), GFP_KERNEL);
+	if (params == NULL)
+		return -ENOMEM;
+
+	params->cs55x0 = gx_pci;
+	gx_params = params;
+
+	/* keep cs55x0 configurations */
+	pci_read_config_byte(params->cs55x0, PCI_SUSCFG, &(params->pci_suscfg));
+	pci_read_config_byte(params->cs55x0, PCI_PMER1, &(params->pci_pmer1));
+	pci_read_config_byte(params->cs55x0, PCI_PMER2, &(params->pci_pmer2));
+	pci_read_config_byte(params->cs55x0, PCI_MODON, &(params->on_duration));
+	pci_read_config_byte(params->cs55x0, PCI_MODOFF,
+			&(params->off_duration));
+
+	ret = cpufreq_register_driver(&gx_suspmod_driver);
+	if (ret) {
+		kfree(params);
+		return ret;                   /* register error! */
+	}
+
+	return 0;
+}
+
+static void __exit cpufreq_gx_exit(void)
+{
+	cpufreq_unregister_driver(&gx_suspmod_driver);
+	pci_dev_put(gx_params->cs55x0);
+	kfree(gx_params);
+}
+
+MODULE_AUTHOR("Hiroshi Miura <miura@da-cha.org>");
+MODULE_DESCRIPTION("Cpufreq driver for Cyrix MediaGX and NatSemi Geode");
+MODULE_LICENSE("GPL");
+
+module_init(cpufreq_gx_init);
+module_exit(cpufreq_gx_exit);
+
diff -druN linux-2.6.39-libre/drivers/cpufreq/Kconfig linux-3.0-rc7-libre/drivers/cpufreq/Kconfig
--- linux-2.6.39-libre/drivers/cpufreq/Kconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/cpufreq/Kconfig	2011-07-11 19:51:52.000000000 -0400
@@ -1,3 +1,5 @@
+menu "CPU Frequency scaling"
+
 config CPU_FREQ
 	bool "CPU Frequency scaling"
 	help
@@ -18,19 +20,6 @@
 config CPU_FREQ_TABLE
 	tristate
 
-config CPU_FREQ_DEBUG
-	bool "Enable CPUfreq debugging"
-	help
-	  Say Y here to enable CPUfreq subsystem (including drivers)
-	  debugging. You will need to activate it via the kernel
-	  command line by passing
-	     cpufreq.debug=<value>
-
-	  To get <value>, add 
-	       1 to activate CPUfreq core debugging,
-	       2 to activate CPUfreq drivers debugging, and
-	       4 to activate CPUfreq governor debugging
-
 config CPU_FREQ_STAT
 	tristate "CPU frequency translation statistics"
 	select CPU_FREQ_TABLE
@@ -190,4 +179,10 @@
 
 	  If in doubt, say N.
 
-endif	# CPU_FREQ
+menu "x86 CPU frequency scaling drivers"
+depends on X86
+source "drivers/cpufreq/Kconfig.x86"
+endmenu
+
+endif
+endmenu
diff -druN linux-2.6.39-libre/drivers/cpufreq/Kconfig.x86 linux-3.0-rc7-libre/drivers/cpufreq/Kconfig.x86
--- linux-2.6.39-libre/drivers/cpufreq/Kconfig.x86	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/cpufreq/Kconfig.x86	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,255 @@
+#
+# x86 CPU Frequency scaling 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
+	depends on ACPI_PROCESSOR
+	help
+	  This driver adds a CPUFreq driver which utilizes the ACPI
+	  Processor Performance States.
+	  This driver also supports Intel Enhanced Speedstep.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called acpi-cpufreq.
+
+	  For details, take a look at <file:Documentation/cpu-freq/>.
+
+	  If in doubt, say N.
+
+config ELAN_CPUFREQ
+	tristate "AMD Elan SC400 and SC410"
+	select CPU_FREQ_TABLE
+	depends on MELAN
+	---help---
+	  This adds the CPUFreq driver for AMD Elan SC400 and SC410
+	  processors.
+
+	  You need to specify the processor maximum speed as boot
+	  parameter: elanfreq=maxspeed (in kHz) or as module
+	  parameter "max_freq".
+
+	  For details, take a look at <file:Documentation/cpu-freq/>.
+
+	  If in doubt, say N.
+
+config SC520_CPUFREQ
+	tristate "AMD Elan SC520"
+	select CPU_FREQ_TABLE
+	depends on MELAN
+	---help---
+	  This adds the CPUFreq driver for AMD Elan SC520 processor.
+
+	  For details, take a look at <file:Documentation/cpu-freq/>.
+
+	  If in doubt, say N.
+
+
+config X86_POWERNOW_K6
+	tristate "AMD Mobile K6-2/K6-3 PowerNow!"
+	select CPU_FREQ_TABLE
+	depends on X86_32
+	help
+	  This adds the CPUFreq driver for mobile AMD K6-2+ and mobile
+	  AMD K6-3+ processors.
+
+	  For details, take a look at <file:Documentation/cpu-freq/>.
+
+	  If in doubt, say N.
+
+config X86_POWERNOW_K7
+	tristate "AMD Mobile Athlon/Duron PowerNow!"
+	select CPU_FREQ_TABLE
+	depends on X86_32
+	help
+	  This adds the CPUFreq driver for mobile AMD K7 mobile processors.
+
+	  For details, take a look at <file:Documentation/cpu-freq/>.
+
+	  If in doubt, say N.
+
+config X86_POWERNOW_K7_ACPI
+	bool
+	depends on X86_POWERNOW_K7 && ACPI_PROCESSOR
+	depends on !(X86_POWERNOW_K7 = y && ACPI_PROCESSOR = m)
+	depends on X86_32
+	default y
+
+config X86_POWERNOW_K8
+	tristate "AMD Opteron/Athlon64 PowerNow!"
+	select CPU_FREQ_TABLE
+	depends on ACPI && ACPI_PROCESSOR
+	help
+	  This adds the CPUFreq driver for K8/K10 Opteron/Athlon64 processors.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called powernow-k8.
+
+	  For details, take a look at <file:Documentation/cpu-freq/>.
+
+config X86_GX_SUSPMOD
+	tristate "Cyrix MediaGX/NatSemi Geode Suspend Modulation"
+	depends on X86_32 && PCI
+	help
+	 This add the CPUFreq driver for NatSemi Geode processors which
+	 support suspend modulation.
+
+	 For details, take a look at <file:Documentation/cpu-freq/>.
+
+	 If in doubt, say N.
+
+config X86_SPEEDSTEP_CENTRINO
+	tristate "Intel Enhanced SpeedStep (deprecated)"
+	select CPU_FREQ_TABLE
+	select X86_SPEEDSTEP_CENTRINO_TABLE if X86_32
+	depends on X86_32 || (X86_64 && ACPI_PROCESSOR)
+	help
+	  This is deprecated and this functionality is now merged into
+	  acpi_cpufreq (X86_ACPI_CPUFREQ). Use that driver instead of
+	  speedstep_centrino.
+	  This adds the CPUFreq driver for Enhanced SpeedStep enabled
+	  mobile CPUs.  This means Intel Pentium M (Centrino) CPUs
+	  or 64bit enabled Intel Xeons.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called speedstep-centrino.
+
+	  For details, take a look at <file:Documentation/cpu-freq/>.
+
+	  If in doubt, say N.
+
+config X86_SPEEDSTEP_CENTRINO_TABLE
+	bool "Built-in tables for Banias CPUs"
+	depends on X86_32 && X86_SPEEDSTEP_CENTRINO
+	default y
+	help
+	  Use built-in tables for Banias CPUs if ACPI encoding
+	  is not available.
+
+	  If in doubt, say N.
+
+config X86_SPEEDSTEP_ICH
+	tristate "Intel Speedstep on ICH-M chipsets (ioport interface)"
+	select CPU_FREQ_TABLE
+	depends on X86_32
+	help
+	  This adds the CPUFreq driver for certain mobile Intel Pentium III
+	  (Coppermine), all mobile Intel Pentium III-M (Tualatin) and all
+	  mobile Intel Pentium 4 P4-M on systems which have an Intel ICH2,
+	  ICH3 or ICH4 southbridge.
+
+	  For details, take a look at <file:Documentation/cpu-freq/>.
+
+	  If in doubt, say N.
+
+config X86_SPEEDSTEP_SMI
+	tristate "Intel SpeedStep on 440BX/ZX/MX chipsets (SMI interface)"
+	select CPU_FREQ_TABLE
+	depends on X86_32 && EXPERIMENTAL
+	help
+	  This adds the CPUFreq driver for certain mobile Intel Pentium III
+	  (Coppermine), all mobile Intel Pentium III-M (Tualatin)
+	  on systems which have an Intel 440BX/ZX/MX southbridge.
+
+	  For details, take a look at <file:Documentation/cpu-freq/>.
+
+	  If in doubt, say N.
+
+config X86_P4_CLOCKMOD
+	tristate "Intel Pentium 4 clock modulation"
+	select CPU_FREQ_TABLE
+	help
+	  This adds the CPUFreq driver for Intel Pentium 4 / XEON
+	  processors.  When enabled it will lower CPU temperature by skipping
+	  clocks.
+
+	  This driver should be only used in exceptional
+	  circumstances when very low power is needed because it causes severe
+	  slowdowns and noticeable latencies.  Normally Speedstep should be used
+	  instead.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called p4-clockmod.
+
+	  For details, take a look at <file:Documentation/cpu-freq/>.
+
+	  Unless you are absolutely sure say N.
+
+config X86_CPUFREQ_NFORCE2
+	tristate "nVidia nForce2 FSB changing"
+	depends on X86_32 && EXPERIMENTAL
+	help
+	  This adds the CPUFreq driver for FSB changing on nVidia nForce2
+	  platforms.
+
+	  For details, take a look at <file:Documentation/cpu-freq/>.
+
+	  If in doubt, say N.
+
+config X86_LONGRUN
+	tristate "Transmeta LongRun"
+	depends on X86_32
+	help
+	  This adds the CPUFreq driver for Transmeta Crusoe and Efficeon processors
+	  which support LongRun.
+
+	  For details, take a look at <file:Documentation/cpu-freq/>.
+
+	  If in doubt, say N.
+
+config X86_LONGHAUL
+	tristate "VIA Cyrix III Longhaul"
+	select CPU_FREQ_TABLE
+	depends on X86_32 && ACPI_PROCESSOR
+	help
+	  This adds the CPUFreq driver for VIA Samuel/CyrixIII,
+	  VIA Cyrix Samuel/C3, VIA Cyrix Ezra and VIA Cyrix Ezra-T
+	  processors.
+
+	  For details, take a look at <file:Documentation/cpu-freq/>.
+
+	  If in doubt, say N.
+
+config X86_E_POWERSAVER
+	tristate "VIA C7 Enhanced PowerSaver (DANGEROUS)"
+	select CPU_FREQ_TABLE
+	depends on X86_32 && EXPERIMENTAL
+	help
+	  This adds the CPUFreq driver for VIA C7 processors.  However, this driver
+	  does not have any safeguards to prevent operating the CPU out of spec
+	  and is thus considered dangerous.  Please use the regular ACPI cpufreq
+	  driver, enabled by CONFIG_X86_ACPI_CPUFREQ.
+
+	  If in doubt, say N.
+
+comment "shared options"
+
+config X86_SPEEDSTEP_LIB
+	tristate
+	default (X86_SPEEDSTEP_ICH || X86_SPEEDSTEP_SMI || X86_P4_CLOCKMOD)
+
+config X86_SPEEDSTEP_RELAXED_CAP_CHECK
+	bool "Relaxed speedstep capability checks"
+	depends on X86_32 && (X86_SPEEDSTEP_SMI || X86_SPEEDSTEP_ICH)
+	help
+	  Don't perform all checks for a speedstep capable system which would
+	  normally be done. Some ancient or strange systems, though speedstep
+	  capable, don't always indicate that they are speedstep capable. This
+	  option lets the probing code bypass some of those checks if the
+	  parameter "relaxed_check=1" is passed to the module.
+
diff -druN linux-2.6.39-libre/drivers/cpufreq/longhaul.c linux-3.0-rc7-libre/drivers/cpufreq/longhaul.c
--- linux-2.6.39-libre/drivers/cpufreq/longhaul.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/cpufreq/longhaul.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,1024 @@
+/*
+ *  (C) 2001-2004  Dave Jones. <davej@redhat.com>
+ *  (C) 2002  Padraig Brady. <padraig@antefacto.com>
+ *
+ *  Licensed under the terms of the GNU GPL License version 2.
+ *  Based upon datasheets & sample CPUs kindly provided by VIA.
+ *
+ *  VIA have currently 3 different versions of Longhaul.
+ *  Version 1 (Longhaul) uses the BCR2 MSR at 0x1147.
+ *   It is present only in Samuel 1 (C5A), Samuel 2 (C5B) stepping 0.
+ *  Version 2 of longhaul is backward compatible with v1, but adds
+ *   LONGHAUL MSR for purpose of both frequency and voltage scaling.
+ *   Present in Samuel 2 (steppings 1-7 only) (C5B), and Ezra (C5C).
+ *  Version 3 of longhaul got renamed to Powersaver and redesigned
+ *   to use only the POWERSAVER MSR at 0x110a.
+ *   It is present in Ezra-T (C5M), Nehemiah (C5X) and above.
+ *   It's pretty much the same feature wise to longhaul v2, though
+ *   there is provision for scaling FSB too, but this doesn't work
+ *   too well in practice so we don't even try to use this.
+ *
+ *  BIG FAT DISCLAIMER: Work in progress code. Possibly *dangerous*
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/init.h>
+#include <linux/cpufreq.h>
+#include <linux/pci.h>
+#include <linux/slab.h>
+#include <linux/string.h>
+#include <linux/delay.h>
+#include <linux/timex.h>
+#include <linux/io.h>
+#include <linux/acpi.h>
+
+#include <asm/msr.h>
+#include <acpi/processor.h>
+
+#include "longhaul.h"
+
+#define PFX "longhaul: "
+
+#define TYPE_LONGHAUL_V1	1
+#define TYPE_LONGHAUL_V2	2
+#define TYPE_POWERSAVER		3
+
+#define	CPU_SAMUEL	1
+#define	CPU_SAMUEL2	2
+#define	CPU_EZRA	3
+#define	CPU_EZRA_T	4
+#define	CPU_NEHEMIAH	5
+#define	CPU_NEHEMIAH_C	6
+
+/* Flags */
+#define USE_ACPI_C3		(1 << 1)
+#define USE_NORTHBRIDGE		(1 << 2)
+
+static int cpu_model;
+static unsigned int numscales = 16;
+static unsigned int fsb;
+
+static const struct mV_pos *vrm_mV_table;
+static const unsigned char *mV_vrm_table;
+
+static unsigned int highest_speed, lowest_speed; /* kHz */
+static unsigned int minmult, maxmult;
+static int can_scale_voltage;
+static struct acpi_processor *pr;
+static struct acpi_processor_cx *cx;
+static u32 acpi_regs_addr;
+static u8 longhaul_flags;
+static unsigned int longhaul_index;
+
+/* Module parameters */
+static int scale_voltage;
+static int disable_acpi_c3;
+static int revid_errata;
+
+
+/* Clock ratios multiplied by 10 */
+static int mults[32];
+static int eblcr[32];
+static int longhaul_version;
+static struct cpufreq_frequency_table *longhaul_table;
+
+static char speedbuffer[8];
+
+static char *print_speed(int speed)
+{
+	if (speed < 1000) {
+		snprintf(speedbuffer, sizeof(speedbuffer), "%dMHz", speed);
+		return speedbuffer;
+	}
+
+	if (speed%1000 == 0)
+		snprintf(speedbuffer, sizeof(speedbuffer),
+			"%dGHz", speed/1000);
+	else
+		snprintf(speedbuffer, sizeof(speedbuffer),
+			"%d.%dGHz", speed/1000, (speed%1000)/100);
+
+	return speedbuffer;
+}
+
+
+static unsigned int calc_speed(int mult)
+{
+	int khz;
+	khz = (mult/10)*fsb;
+	if (mult%10)
+		khz += fsb/2;
+	khz *= 1000;
+	return khz;
+}
+
+
+static int longhaul_get_cpu_mult(void)
+{
+	unsigned long invalue = 0, lo, hi;
+
+	rdmsr(MSR_IA32_EBL_CR_POWERON, lo, hi);
+	invalue = (lo & (1<<22|1<<23|1<<24|1<<25))>>22;
+	if (longhaul_version == TYPE_LONGHAUL_V2 ||
+	    longhaul_version == TYPE_POWERSAVER) {
+		if (lo & (1<<27))
+			invalue += 16;
+	}
+	return eblcr[invalue];
+}
+
+/* For processor with BCR2 MSR */
+
+static void do_longhaul1(unsigned int mults_index)
+{
+	union msr_bcr2 bcr2;
+
+	rdmsrl(MSR_VIA_BCR2, bcr2.val);
+	/* Enable software clock multiplier */
+	bcr2.bits.ESOFTBF = 1;
+	bcr2.bits.CLOCKMUL = mults_index & 0xff;
+
+	/* Sync to timer tick */
+	safe_halt();
+	/* Change frequency on next halt or sleep */
+	wrmsrl(MSR_VIA_BCR2, bcr2.val);
+	/* Invoke transition */
+	ACPI_FLUSH_CPU_CACHE();
+	halt();
+
+	/* Disable software clock multiplier */
+	local_irq_disable();
+	rdmsrl(MSR_VIA_BCR2, bcr2.val);
+	bcr2.bits.ESOFTBF = 0;
+	wrmsrl(MSR_VIA_BCR2, bcr2.val);
+}
+
+/* For processor with Longhaul MSR */
+
+static void do_powersaver(int cx_address, unsigned int mults_index,
+			  unsigned int dir)
+{
+	union msr_longhaul longhaul;
+	u32 t;
+
+	rdmsrl(MSR_VIA_LONGHAUL, longhaul.val);
+	/* Setup new frequency */
+	if (!revid_errata)
+		longhaul.bits.RevisionKey = longhaul.bits.RevisionID;
+	else
+		longhaul.bits.RevisionKey = 0;
+	longhaul.bits.SoftBusRatio = mults_index & 0xf;
+	longhaul.bits.SoftBusRatio4 = (mults_index & 0x10) >> 4;
+	/* Setup new voltage */
+	if (can_scale_voltage)
+		longhaul.bits.SoftVID = (mults_index >> 8) & 0x1f;
+	/* Sync to timer tick */
+	safe_halt();
+	/* Raise voltage if necessary */
+	if (can_scale_voltage && dir) {
+		longhaul.bits.EnableSoftVID = 1;
+		wrmsrl(MSR_VIA_LONGHAUL, longhaul.val);
+		/* Change voltage */
+		if (!cx_address) {
+			ACPI_FLUSH_CPU_CACHE();
+			halt();
+		} else {
+			ACPI_FLUSH_CPU_CACHE();
+			/* Invoke C3 */
+			inb(cx_address);
+			/* Dummy op - must do something useless after P_LVL3
+			 * read */
+			t = inl(acpi_gbl_FADT.xpm_timer_block.address);
+		}
+		longhaul.bits.EnableSoftVID = 0;
+		wrmsrl(MSR_VIA_LONGHAUL, longhaul.val);
+	}
+
+	/* Change frequency on next halt or sleep */
+	longhaul.bits.EnableSoftBusRatio = 1;
+	wrmsrl(MSR_VIA_LONGHAUL, longhaul.val);
+	if (!cx_address) {
+		ACPI_FLUSH_CPU_CACHE();
+		halt();
+	} else {
+		ACPI_FLUSH_CPU_CACHE();
+		/* Invoke C3 */
+		inb(cx_address);
+		/* Dummy op - must do something useless after P_LVL3 read */
+		t = inl(acpi_gbl_FADT.xpm_timer_block.address);
+	}
+	/* Disable bus ratio bit */
+	longhaul.bits.EnableSoftBusRatio = 0;
+	wrmsrl(MSR_VIA_LONGHAUL, longhaul.val);
+
+	/* Reduce voltage if necessary */
+	if (can_scale_voltage && !dir) {
+		longhaul.bits.EnableSoftVID = 1;
+		wrmsrl(MSR_VIA_LONGHAUL, longhaul.val);
+		/* Change voltage */
+		if (!cx_address) {
+			ACPI_FLUSH_CPU_CACHE();
+			halt();
+		} else {
+			ACPI_FLUSH_CPU_CACHE();
+			/* Invoke C3 */
+			inb(cx_address);
+			/* Dummy op - must do something useless after P_LVL3
+			 * read */
+			t = inl(acpi_gbl_FADT.xpm_timer_block.address);
+		}
+		longhaul.bits.EnableSoftVID = 0;
+		wrmsrl(MSR_VIA_LONGHAUL, longhaul.val);
+	}
+}
+
+/**
+ * longhaul_set_cpu_frequency()
+ * @mults_index : bitpattern of the new multiplier.
+ *
+ * Sets a new clock ratio.
+ */
+
+static void longhaul_setstate(unsigned int table_index)
+{
+	unsigned int mults_index;
+	int speed, mult;
+	struct cpufreq_freqs freqs;
+	unsigned long flags;
+	unsigned int pic1_mask, pic2_mask;
+	u16 bm_status = 0;
+	u32 bm_timeout = 1000;
+	unsigned int dir = 0;
+
+	mults_index = longhaul_table[table_index].index;
+	/* Safety precautions */
+	mult = mults[mults_index & 0x1f];
+	if (mult == -1)
+		return;
+	speed = calc_speed(mult);
+	if ((speed > highest_speed) || (speed < lowest_speed))
+		return;
+	/* Voltage transition before frequency transition? */
+	if (can_scale_voltage && longhaul_index < table_index)
+		dir = 1;
+
+	freqs.old = calc_speed(longhaul_get_cpu_mult());
+	freqs.new = speed;
+	freqs.cpu = 0; /* longhaul.c is UP only driver */
+
+	cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
+
+	pr_debug("Setting to FSB:%dMHz Mult:%d.%dx (%s)\n",
+			fsb, mult/10, mult%10, print_speed(speed/1000));
+retry_loop:
+	preempt_disable();
+	local_irq_save(flags);
+
+	pic2_mask = inb(0xA1);
+	pic1_mask = inb(0x21);	/* works on C3. save mask. */
+	outb(0xFF, 0xA1);	/* Overkill */
+	outb(0xFE, 0x21);	/* TMR0 only */
+
+	/* Wait while PCI bus is busy. */
+	if (acpi_regs_addr && (longhaul_flags & USE_NORTHBRIDGE
+	    || ((pr != NULL) && pr->flags.bm_control))) {
+		bm_status = inw(acpi_regs_addr);
+		bm_status &= 1 << 4;
+		while (bm_status && bm_timeout) {
+			outw(1 << 4, acpi_regs_addr);
+			bm_timeout--;
+			bm_status = inw(acpi_regs_addr);
+			bm_status &= 1 << 4;
+		}
+	}
+
+	if (longhaul_flags & USE_NORTHBRIDGE) {
+		/* Disable AGP and PCI arbiters */
+		outb(3, 0x22);
+	} else if ((pr != NULL) && pr->flags.bm_control) {
+		/* Disable bus master arbitration */
+		acpi_write_bit_register(ACPI_BITREG_ARB_DISABLE, 1);
+	}
+	switch (longhaul_version) {
+
+	/*
+	 * Longhaul v1. (Samuel[C5A] and Samuel2 stepping 0[C5B])
+	 * Software controlled multipliers only.
+	 */
+	case TYPE_LONGHAUL_V1:
+		do_longhaul1(mults_index);
+		break;
+
+	/*
+	 * Longhaul v2 appears in Samuel2 Steppings 1->7 [C5B] and Ezra [C5C]
+	 *
+	 * Longhaul v3 (aka Powersaver). (Ezra-T [C5M] & Nehemiah [C5N])
+	 * Nehemiah can do FSB scaling too, but this has never been proven
+	 * to work in practice.
+	 */
+	case TYPE_LONGHAUL_V2:
+	case TYPE_POWERSAVER:
+		if (longhaul_flags & USE_ACPI_C3) {
+			/* Don't allow wakeup */
+			acpi_write_bit_register(ACPI_BITREG_BUS_MASTER_RLD, 0);
+			do_powersaver(cx->address, mults_index, dir);
+		} else {
+			do_powersaver(0, mults_index, dir);
+		}
+		break;
+	}
+
+	if (longhaul_flags & USE_NORTHBRIDGE) {
+		/* Enable arbiters */
+		outb(0, 0x22);
+	} else if ((pr != NULL) && pr->flags.bm_control) {
+		/* Enable bus master arbitration */
+		acpi_write_bit_register(ACPI_BITREG_ARB_DISABLE, 0);
+	}
+	outb(pic2_mask, 0xA1);	/* restore mask */
+	outb(pic1_mask, 0x21);
+
+	local_irq_restore(flags);
+	preempt_enable();
+
+	freqs.new = calc_speed(longhaul_get_cpu_mult());
+	/* Check if requested frequency is set. */
+	if (unlikely(freqs.new != speed)) {
+		printk(KERN_INFO PFX "Failed to set requested frequency!\n");
+		/* Revision ID = 1 but processor is expecting revision key
+		 * equal to 0. Jumpers at the bottom of processor will change
+		 * multiplier and FSB, but will not change bits in Longhaul
+		 * MSR nor enable voltage scaling. */
+		if (!revid_errata) {
+			printk(KERN_INFO PFX "Enabling \"Ignore Revision ID\" "
+						"option.\n");
+			revid_errata = 1;
+			msleep(200);
+			goto retry_loop;
+		}
+		/* Why ACPI C3 sometimes doesn't work is a mystery for me.
+		 * But it does happen. Processor is entering ACPI C3 state,
+		 * but it doesn't change frequency. I tried poking various
+		 * bits in northbridge registers, but without success. */
+		if (longhaul_flags & USE_ACPI_C3) {
+			printk(KERN_INFO PFX "Disabling ACPI C3 support.\n");
+			longhaul_flags &= ~USE_ACPI_C3;
+			if (revid_errata) {
+				printk(KERN_INFO PFX "Disabling \"Ignore "
+						"Revision ID\" option.\n");
+				revid_errata = 0;
+			}
+			msleep(200);
+			goto retry_loop;
+		}
+		/* This shouldn't happen. Longhaul ver. 2 was reported not
+		 * working on processors without voltage scaling, but with
+		 * RevID = 1. RevID errata will make things right. Just
+		 * to be 100% sure. */
+		if (longhaul_version == TYPE_LONGHAUL_V2) {
+			printk(KERN_INFO PFX "Switching to Longhaul ver. 1\n");
+			longhaul_version = TYPE_LONGHAUL_V1;
+			msleep(200);
+			goto retry_loop;
+		}
+	}
+	/* Report true CPU frequency */
+	cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
+
+	if (!bm_timeout)
+		printk(KERN_INFO PFX "Warning: Timeout while waiting for "
+				"idle PCI bus.\n");
+}
+
+/*
+ * Centaur decided to make life a little more tricky.
+ * Only longhaul v1 is allowed to read EBLCR BSEL[0:1].
+ * Samuel2 and above have to try and guess what the FSB is.
+ * We do this by assuming we booted at maximum multiplier, and interpolate
+ * between that value multiplied by possible FSBs and cpu_mhz which
+ * was calculated at boot time. Really ugly, but no other way to do this.
+ */
+
+#define ROUNDING	0xf
+
+static int guess_fsb(int mult)
+{
+	int speed = cpu_khz / 1000;
+	int i;
+	int speeds[] = { 666, 1000, 1333, 2000 };
+	int f_max, f_min;
+
+	for (i = 0; i < 4; i++) {
+		f_max = ((speeds[i] * mult) + 50) / 100;
+		f_max += (ROUNDING / 2);
+		f_min = f_max - ROUNDING;
+		if ((speed <= f_max) && (speed >= f_min))
+			return speeds[i] / 10;
+	}
+	return 0;
+}
+
+
+static int __cpuinit longhaul_get_ranges(void)
+{
+	unsigned int i, j, k = 0;
+	unsigned int ratio;
+	int mult;
+
+	/* Get current frequency */
+	mult = longhaul_get_cpu_mult();
+	if (mult == -1) {
+		printk(KERN_INFO PFX "Invalid (reserved) multiplier!\n");
+		return -EINVAL;
+	}
+	fsb = guess_fsb(mult);
+	if (fsb == 0) {
+		printk(KERN_INFO PFX "Invalid (reserved) FSB!\n");
+		return -EINVAL;
+	}
+	/* Get max multiplier - as we always did.
+	 * Longhaul MSR is useful only when voltage scaling is enabled.
+	 * C3 is booting at max anyway. */
+	maxmult = mult;
+	/* Get min multiplier */
+	switch (cpu_model) {
+	case CPU_NEHEMIAH:
+		minmult = 50;
+		break;
+	case CPU_NEHEMIAH_C:
+		minmult = 40;
+		break;
+	default:
+		minmult = 30;
+		break;
+	}
+
+	pr_debug("MinMult:%d.%dx MaxMult:%d.%dx\n",
+		 minmult/10, minmult%10, maxmult/10, maxmult%10);
+
+	highest_speed = calc_speed(maxmult);
+	lowest_speed = calc_speed(minmult);
+	pr_debug("FSB:%dMHz  Lowest speed: %s   Highest speed:%s\n", fsb,
+		 print_speed(lowest_speed/1000),
+		 print_speed(highest_speed/1000));
+
+	if (lowest_speed == highest_speed) {
+		printk(KERN_INFO PFX "highestspeed == lowest, aborting.\n");
+		return -EINVAL;
+	}
+	if (lowest_speed > highest_speed) {
+		printk(KERN_INFO PFX "nonsense! lowest (%d > %d) !\n",
+			lowest_speed, highest_speed);
+		return -EINVAL;
+	}
+
+	longhaul_table = kmalloc((numscales + 1) * sizeof(*longhaul_table),
+			GFP_KERNEL);
+	if (!longhaul_table)
+		return -ENOMEM;
+
+	for (j = 0; j < numscales; j++) {
+		ratio = mults[j];
+		if (ratio == -1)
+			continue;
+		if (ratio > maxmult || ratio < minmult)
+			continue;
+		longhaul_table[k].frequency = calc_speed(ratio);
+		longhaul_table[k].index	= j;
+		k++;
+	}
+	if (k <= 1) {
+		kfree(longhaul_table);
+		return -ENODEV;
+	}
+	/* Sort */
+	for (j = 0; j < k - 1; j++) {
+		unsigned int min_f, min_i;
+		min_f = longhaul_table[j].frequency;
+		min_i = j;
+		for (i = j + 1; i < k; i++) {
+			if (longhaul_table[i].frequency < min_f) {
+				min_f = longhaul_table[i].frequency;
+				min_i = i;
+			}
+		}
+		if (min_i != j) {
+			swap(longhaul_table[j].frequency,
+			     longhaul_table[min_i].frequency);
+			swap(longhaul_table[j].index,
+			     longhaul_table[min_i].index);
+		}
+	}
+
+	longhaul_table[k].frequency = CPUFREQ_TABLE_END;
+
+	/* Find index we are running on */
+	for (j = 0; j < k; j++) {
+		if (mults[longhaul_table[j].index & 0x1f] == mult) {
+			longhaul_index = j;
+			break;
+		}
+	}
+	return 0;
+}
+
+
+static void __cpuinit longhaul_setup_voltagescaling(void)
+{
+	union msr_longhaul longhaul;
+	struct mV_pos minvid, maxvid, vid;
+	unsigned int j, speed, pos, kHz_step, numvscales;
+	int min_vid_speed;
+
+	rdmsrl(MSR_VIA_LONGHAUL, longhaul.val);
+	if (!(longhaul.bits.RevisionID & 1)) {
+		printk(KERN_INFO PFX "Voltage scaling not supported by CPU.\n");
+		return;
+	}
+
+	if (!longhaul.bits.VRMRev) {
+		printk(KERN_INFO PFX "VRM 8.5\n");
+		vrm_mV_table = &vrm85_mV[0];
+		mV_vrm_table = &mV_vrm85[0];
+	} else {
+		printk(KERN_INFO PFX "Mobile VRM\n");
+		if (cpu_model < CPU_NEHEMIAH)
+			return;
+		vrm_mV_table = &mobilevrm_mV[0];
+		mV_vrm_table = &mV_mobilevrm[0];
+	}
+
+	minvid = vrm_mV_table[longhaul.bits.MinimumVID];
+	maxvid = vrm_mV_table[longhaul.bits.MaximumVID];
+
+	if (minvid.mV == 0 || maxvid.mV == 0 || minvid.mV > maxvid.mV) {
+		printk(KERN_INFO PFX "Bogus values Min:%d.%03d Max:%d.%03d. "
+					"Voltage scaling disabled.\n",
+					minvid.mV/1000, minvid.mV%1000,
+					maxvid.mV/1000, maxvid.mV%1000);
+		return;
+	}
+
+	if (minvid.mV == maxvid.mV) {
+		printk(KERN_INFO PFX "Claims to support voltage scaling but "
+				"min & max are both %d.%03d. "
+				"Voltage scaling disabled\n",
+				maxvid.mV/1000, maxvid.mV%1000);
+		return;
+	}
+
+	/* How many voltage steps*/
+	numvscales = maxvid.pos - minvid.pos + 1;
+	printk(KERN_INFO PFX
+		"Max VID=%d.%03d  "
+		"Min VID=%d.%03d, "
+		"%d possible voltage scales\n",
+		maxvid.mV/1000, maxvid.mV%1000,
+		minvid.mV/1000, minvid.mV%1000,
+		numvscales);
+
+	/* Calculate max frequency at min voltage */
+	j = longhaul.bits.MinMHzBR;
+	if (longhaul.bits.MinMHzBR4)
+		j += 16;
+	min_vid_speed = eblcr[j];
+	if (min_vid_speed == -1)
+		return;
+	switch (longhaul.bits.MinMHzFSB) {
+	case 0:
+		min_vid_speed *= 13333;
+		break;
+	case 1:
+		min_vid_speed *= 10000;
+		break;
+	case 3:
+		min_vid_speed *= 6666;
+		break;
+	default:
+		return;
+		break;
+	}
+	if (min_vid_speed >= highest_speed)
+		return;
+	/* Calculate kHz for one voltage step */
+	kHz_step = (highest_speed - min_vid_speed) / numvscales;
+
+	j = 0;
+	while (longhaul_table[j].frequency != CPUFREQ_TABLE_END) {
+		speed = longhaul_table[j].frequency;
+		if (speed > min_vid_speed)
+			pos = (speed - min_vid_speed) / kHz_step + minvid.pos;
+		else
+			pos = minvid.pos;
+		longhaul_table[j].index |= mV_vrm_table[pos] << 8;
+		vid = vrm_mV_table[mV_vrm_table[pos]];
+		printk(KERN_INFO PFX "f: %d kHz, index: %d, vid: %d mV\n",
+				speed, j, vid.mV);
+		j++;
+	}
+
+	can_scale_voltage = 1;
+	printk(KERN_INFO PFX "Voltage scaling enabled.\n");
+}
+
+
+static int longhaul_verify(struct cpufreq_policy *policy)
+{
+	return cpufreq_frequency_table_verify(policy, longhaul_table);
+}
+
+
+static int longhaul_target(struct cpufreq_policy *policy,
+			    unsigned int target_freq, unsigned int relation)
+{
+	unsigned int table_index = 0;
+	unsigned int i;
+	unsigned int dir = 0;
+	u8 vid, current_vid;
+
+	if (cpufreq_frequency_table_target(policy, longhaul_table, target_freq,
+				relation, &table_index))
+		return -EINVAL;
+
+	/* Don't set same frequency again */
+	if (longhaul_index == table_index)
+		return 0;
+
+	if (!can_scale_voltage)
+		longhaul_setstate(table_index);
+	else {
+		/* On test system voltage transitions exceeding single
+		 * step up or down were turning motherboard off. Both
+		 * "ondemand" and "userspace" are unsafe. C7 is doing
+		 * this in hardware, C3 is old and we need to do this
+		 * in software. */
+		i = longhaul_index;
+		current_vid = (longhaul_table[longhaul_index].index >> 8);
+		current_vid &= 0x1f;
+		if (table_index > longhaul_index)
+			dir = 1;
+		while (i != table_index) {
+			vid = (longhaul_table[i].index >> 8) & 0x1f;
+			if (vid != current_vid) {
+				longhaul_setstate(i);
+				current_vid = vid;
+				msleep(200);
+			}
+			if (dir)
+				i++;
+			else
+				i--;
+		}
+		longhaul_setstate(table_index);
+	}
+	longhaul_index = table_index;
+	return 0;
+}
+
+
+static unsigned int longhaul_get(unsigned int cpu)
+{
+	if (cpu)
+		return 0;
+	return calc_speed(longhaul_get_cpu_mult());
+}
+
+static acpi_status longhaul_walk_callback(acpi_handle obj_handle,
+					  u32 nesting_level,
+					  void *context, void **return_value)
+{
+	struct acpi_device *d;
+
+	if (acpi_bus_get_device(obj_handle, &d))
+		return 0;
+
+	*return_value = acpi_driver_data(d);
+	return 1;
+}
+
+/* VIA don't support PM2 reg, but have something similar */
+static int enable_arbiter_disable(void)
+{
+	struct pci_dev *dev;
+	int status = 1;
+	int reg;
+	u8 pci_cmd;
+
+	/* Find PLE133 host bridge */
+	reg = 0x78;
+	dev = pci_get_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8601_0,
+			     NULL);
+	/* Find PM133/VT8605 host bridge */
+	if (dev == NULL)
+		dev = pci_get_device(PCI_VENDOR_ID_VIA,
+				     PCI_DEVICE_ID_VIA_8605_0, NULL);
+	/* Find CLE266 host bridge */
+	if (dev == NULL) {
+		reg = 0x76;
+		dev = pci_get_device(PCI_VENDOR_ID_VIA,
+				     PCI_DEVICE_ID_VIA_862X_0, NULL);
+		/* Find CN400 V-Link host bridge */
+		if (dev == NULL)
+			dev = pci_get_device(PCI_VENDOR_ID_VIA, 0x7259, NULL);
+	}
+	if (dev != NULL) {
+		/* Enable access to port 0x22 */
+		pci_read_config_byte(dev, reg, &pci_cmd);
+		if (!(pci_cmd & 1<<7)) {
+			pci_cmd |= 1<<7;
+			pci_write_config_byte(dev, reg, pci_cmd);
+			pci_read_config_byte(dev, reg, &pci_cmd);
+			if (!(pci_cmd & 1<<7)) {
+				printk(KERN_ERR PFX
+					"Can't enable access to port 0x22.\n");
+				status = 0;
+			}
+		}
+		pci_dev_put(dev);
+		return status;
+	}
+	return 0;
+}
+
+static int longhaul_setup_southbridge(void)
+{
+	struct pci_dev *dev;
+	u8 pci_cmd;
+
+	/* Find VT8235 southbridge */
+	dev = pci_get_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8235, NULL);
+	if (dev == NULL)
+		/* Find VT8237 southbridge */
+		dev = pci_get_device(PCI_VENDOR_ID_VIA,
+				     PCI_DEVICE_ID_VIA_8237, NULL);
+	if (dev != NULL) {
+		/* Set transition time to max */
+		pci_read_config_byte(dev, 0xec, &pci_cmd);
+		pci_cmd &= ~(1 << 2);
+		pci_write_config_byte(dev, 0xec, pci_cmd);
+		pci_read_config_byte(dev, 0xe4, &pci_cmd);
+		pci_cmd &= ~(1 << 7);
+		pci_write_config_byte(dev, 0xe4, pci_cmd);
+		pci_read_config_byte(dev, 0xe5, &pci_cmd);
+		pci_cmd |= 1 << 7;
+		pci_write_config_byte(dev, 0xe5, pci_cmd);
+		/* Get address of ACPI registers block*/
+		pci_read_config_byte(dev, 0x81, &pci_cmd);
+		if (pci_cmd & 1 << 7) {
+			pci_read_config_dword(dev, 0x88, &acpi_regs_addr);
+			acpi_regs_addr &= 0xff00;
+			printk(KERN_INFO PFX "ACPI I/O at 0x%x\n",
+					acpi_regs_addr);
+		}
+
+		pci_dev_put(dev);
+		return 1;
+	}
+	return 0;
+}
+
+static int __cpuinit longhaul_cpu_init(struct cpufreq_policy *policy)
+{
+	struct cpuinfo_x86 *c = &cpu_data(0);
+	char *cpuname = NULL;
+	int ret;
+	u32 lo, hi;
+
+	/* Check what we have on this motherboard */
+	switch (c->x86_model) {
+	case 6:
+		cpu_model = CPU_SAMUEL;
+		cpuname = "C3 'Samuel' [C5A]";
+		longhaul_version = TYPE_LONGHAUL_V1;
+		memcpy(mults, samuel1_mults, sizeof(samuel1_mults));
+		memcpy(eblcr, samuel1_eblcr, sizeof(samuel1_eblcr));
+		break;
+
+	case 7:
+		switch (c->x86_mask) {
+		case 0:
+			longhaul_version = TYPE_LONGHAUL_V1;
+			cpu_model = CPU_SAMUEL2;
+			cpuname = "C3 'Samuel 2' [C5B]";
+			/* Note, this is not a typo, early Samuel2's had
+			 * Samuel1 ratios. */
+			memcpy(mults, samuel1_mults, sizeof(samuel1_mults));
+			memcpy(eblcr, samuel2_eblcr, sizeof(samuel2_eblcr));
+			break;
+		case 1 ... 15:
+			longhaul_version = TYPE_LONGHAUL_V2;
+			if (c->x86_mask < 8) {
+				cpu_model = CPU_SAMUEL2;
+				cpuname = "C3 'Samuel 2' [C5B]";
+			} else {
+				cpu_model = CPU_EZRA;
+				cpuname = "C3 'Ezra' [C5C]";
+			}
+			memcpy(mults, ezra_mults, sizeof(ezra_mults));
+			memcpy(eblcr, ezra_eblcr, sizeof(ezra_eblcr));
+			break;
+		}
+		break;
+
+	case 8:
+		cpu_model = CPU_EZRA_T;
+		cpuname = "C3 'Ezra-T' [C5M]";
+		longhaul_version = TYPE_POWERSAVER;
+		numscales = 32;
+		memcpy(mults, ezrat_mults, sizeof(ezrat_mults));
+		memcpy(eblcr, ezrat_eblcr, sizeof(ezrat_eblcr));
+		break;
+
+	case 9:
+		longhaul_version = TYPE_POWERSAVER;
+		numscales = 32;
+		memcpy(mults, nehemiah_mults, sizeof(nehemiah_mults));
+		memcpy(eblcr, nehemiah_eblcr, sizeof(nehemiah_eblcr));
+		switch (c->x86_mask) {
+		case 0 ... 1:
+			cpu_model = CPU_NEHEMIAH;
+			cpuname = "C3 'Nehemiah A' [C5XLOE]";
+			break;
+		case 2 ... 4:
+			cpu_model = CPU_NEHEMIAH;
+			cpuname = "C3 'Nehemiah B' [C5XLOH]";
+			break;
+		case 5 ... 15:
+			cpu_model = CPU_NEHEMIAH_C;
+			cpuname = "C3 'Nehemiah C' [C5P]";
+			break;
+		}
+		break;
+
+	default:
+		cpuname = "Unknown";
+		break;
+	}
+	/* Check Longhaul ver. 2 */
+	if (longhaul_version == TYPE_LONGHAUL_V2) {
+		rdmsr(MSR_VIA_LONGHAUL, lo, hi);
+		if (lo == 0 && hi == 0)
+			/* Looks like MSR isn't present */
+			longhaul_version = TYPE_LONGHAUL_V1;
+	}
+
+	printk(KERN_INFO PFX "VIA %s CPU detected.  ", cpuname);
+	switch (longhaul_version) {
+	case TYPE_LONGHAUL_V1:
+	case TYPE_LONGHAUL_V2:
+		printk(KERN_CONT "Longhaul v%d supported.\n", longhaul_version);
+		break;
+	case TYPE_POWERSAVER:
+		printk(KERN_CONT "Powersaver supported.\n");
+		break;
+	};
+
+	/* Doesn't hurt */
+	longhaul_setup_southbridge();
+
+	/* Find ACPI data for processor */
+	acpi_walk_namespace(ACPI_TYPE_PROCESSOR, ACPI_ROOT_OBJECT,
+				ACPI_UINT32_MAX, &longhaul_walk_callback, NULL,
+				NULL, (void *)&pr);
+
+	/* Check ACPI support for C3 state */
+	if (pr != NULL && longhaul_version == TYPE_POWERSAVER) {
+		cx = &pr->power.states[ACPI_STATE_C3];
+		if (cx->address > 0 && cx->latency <= 1000)
+			longhaul_flags |= USE_ACPI_C3;
+	}
+	/* Disable if it isn't working */
+	if (disable_acpi_c3)
+		longhaul_flags &= ~USE_ACPI_C3;
+	/* Check if northbridge is friendly */
+	if (enable_arbiter_disable())
+		longhaul_flags |= USE_NORTHBRIDGE;
+
+	/* Check ACPI support for bus master arbiter disable */
+	if (!(longhaul_flags & USE_ACPI_C3
+	     || longhaul_flags & USE_NORTHBRIDGE)
+	    && ((pr == NULL) || !(pr->flags.bm_control))) {
+		printk(KERN_ERR PFX
+			"No ACPI support. Unsupported northbridge.\n");
+		return -ENODEV;
+	}
+
+	if (longhaul_flags & USE_NORTHBRIDGE)
+		printk(KERN_INFO PFX "Using northbridge support.\n");
+	if (longhaul_flags & USE_ACPI_C3)
+		printk(KERN_INFO PFX "Using ACPI support.\n");
+
+	ret = longhaul_get_ranges();
+	if (ret != 0)
+		return ret;
+
+	if ((longhaul_version != TYPE_LONGHAUL_V1) && (scale_voltage != 0))
+		longhaul_setup_voltagescaling();
+
+	policy->cpuinfo.transition_latency = 200000;	/* nsec */
+	policy->cur = calc_speed(longhaul_get_cpu_mult());
+
+	ret = cpufreq_frequency_table_cpuinfo(policy, longhaul_table);
+	if (ret)
+		return ret;
+
+	cpufreq_frequency_table_get_attr(longhaul_table, policy->cpu);
+
+	return 0;
+}
+
+static int __devexit longhaul_cpu_exit(struct cpufreq_policy *policy)
+{
+	cpufreq_frequency_table_put_attr(policy->cpu);
+	return 0;
+}
+
+static struct freq_attr *longhaul_attr[] = {
+	&cpufreq_freq_attr_scaling_available_freqs,
+	NULL,
+};
+
+static struct cpufreq_driver longhaul_driver = {
+	.verify	= longhaul_verify,
+	.target	= longhaul_target,
+	.get	= longhaul_get,
+	.init	= longhaul_cpu_init,
+	.exit	= __devexit_p(longhaul_cpu_exit),
+	.name	= "longhaul",
+	.owner	= THIS_MODULE,
+	.attr	= longhaul_attr,
+};
+
+
+static int __init longhaul_init(void)
+{
+	struct cpuinfo_x86 *c = &cpu_data(0);
+
+	if (c->x86_vendor != X86_VENDOR_CENTAUR || c->x86 != 6)
+		return -ENODEV;
+
+#ifdef CONFIG_SMP
+	if (num_online_cpus() > 1) {
+		printk(KERN_ERR PFX "More than 1 CPU detected, "
+				"longhaul disabled.\n");
+		return -ENODEV;
+	}
+#endif
+#ifdef CONFIG_X86_IO_APIC
+	if (cpu_has_apic) {
+		printk(KERN_ERR PFX "APIC detected. Longhaul is currently "
+				"broken in this configuration.\n");
+		return -ENODEV;
+	}
+#endif
+	switch (c->x86_model) {
+	case 6 ... 9:
+		return cpufreq_register_driver(&longhaul_driver);
+	case 10:
+		printk(KERN_ERR PFX "Use acpi-cpufreq driver for VIA C7\n");
+	default:
+		;
+	}
+
+	return -ENODEV;
+}
+
+
+static void __exit longhaul_exit(void)
+{
+	int i;
+
+	for (i = 0; i < numscales; i++) {
+		if (mults[i] == maxmult) {
+			longhaul_setstate(i);
+			break;
+		}
+	}
+
+	cpufreq_unregister_driver(&longhaul_driver);
+	kfree(longhaul_table);
+}
+
+/* Even if BIOS is exporting ACPI C3 state, and it is used
+ * with success when CPU is idle, this state doesn't
+ * trigger frequency transition in some cases. */
+module_param(disable_acpi_c3, int, 0644);
+MODULE_PARM_DESC(disable_acpi_c3, "Don't use ACPI C3 support");
+/* Change CPU voltage with frequency. Very useful to save
+ * power, but most VIA C3 processors aren't supporting it. */
+module_param(scale_voltage, int, 0644);
+MODULE_PARM_DESC(scale_voltage, "Scale voltage of processor");
+/* Force revision key to 0 for processors which doesn't
+ * support voltage scaling, but are introducing itself as
+ * such. */
+module_param(revid_errata, int, 0644);
+MODULE_PARM_DESC(revid_errata, "Ignore CPU Revision ID");
+
+MODULE_AUTHOR("Dave Jones <davej@redhat.com>");
+MODULE_DESCRIPTION("Longhaul driver for VIA Cyrix processors.");
+MODULE_LICENSE("GPL");
+
+late_initcall(longhaul_init);
+module_exit(longhaul_exit);
diff -druN linux-2.6.39-libre/drivers/cpufreq/longhaul.h linux-3.0-rc7-libre/drivers/cpufreq/longhaul.h
--- linux-2.6.39-libre/drivers/cpufreq/longhaul.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/cpufreq/longhaul.h	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,353 @@
+/*
+ *  longhaul.h
+ *  (C) 2003 Dave Jones.
+ *
+ *  Licensed under the terms of the GNU GPL License version 2.
+ *
+ *  VIA-specific information
+ */
+
+union msr_bcr2 {
+	struct {
+		unsigned Reseved:19,	// 18:0
+		ESOFTBF:1,		// 19
+		Reserved2:3,		// 22:20
+		CLOCKMUL:4,		// 26:23
+		Reserved3:5;		// 31:27
+	} bits;
+	unsigned long val;
+};
+
+union msr_longhaul {
+	struct {
+		unsigned RevisionID:4,	// 3:0
+		RevisionKey:4,		// 7:4
+		EnableSoftBusRatio:1,	// 8
+		EnableSoftVID:1,	// 9
+		EnableSoftBSEL:1,	// 10
+		Reserved:3,		// 11:13
+		SoftBusRatio4:1,	// 14
+		VRMRev:1,		// 15
+		SoftBusRatio:4,		// 19:16
+		SoftVID:5,		// 24:20
+		Reserved2:3,		// 27:25
+		SoftBSEL:2,		// 29:28
+		Reserved3:2,		// 31:30
+		MaxMHzBR:4,		// 35:32
+		MaximumVID:5,		// 40:36
+		MaxMHzFSB:2,		// 42:41
+		MaxMHzBR4:1,		// 43
+		Reserved4:4,		// 47:44
+		MinMHzBR:4,		// 51:48
+		MinimumVID:5,		// 56:52
+		MinMHzFSB:2,		// 58:57
+		MinMHzBR4:1,		// 59
+		Reserved5:4;		// 63:60
+	} bits;
+	unsigned long long val;
+};
+
+/*
+ * Clock ratio tables. Div/Mod by 10 to get ratio.
+ * The eblcr values specify the ratio read from the CPU.
+ * The mults values specify what to write to the CPU.
+ */
+
+/*
+ * VIA C3 Samuel 1  & Samuel 2 (stepping 0)
+ */
+static const int __cpuinitdata samuel1_mults[16] = {
+	-1, /* 0000 -> RESERVED */
+	30, /* 0001 ->  3.0x */
+	40, /* 0010 ->  4.0x */
+	-1, /* 0011 -> RESERVED */
+	-1, /* 0100 -> RESERVED */
+	35, /* 0101 ->  3.5x */
+	45, /* 0110 ->  4.5x */
+	55, /* 0111 ->  5.5x */
+	60, /* 1000 ->  6.0x */
+	70, /* 1001 ->  7.0x */
+	80, /* 1010 ->  8.0x */
+	50, /* 1011 ->  5.0x */
+	65, /* 1100 ->  6.5x */
+	75, /* 1101 ->  7.5x */
+	-1, /* 1110 -> RESERVED */
+	-1, /* 1111 -> RESERVED */
+};
+
+static const int __cpuinitdata samuel1_eblcr[16] = {
+	50, /* 0000 -> RESERVED */
+	30, /* 0001 ->  3.0x */
+	40, /* 0010 ->  4.0x */
+	-1, /* 0011 -> RESERVED */
+	55, /* 0100 ->  5.5x */
+	35, /* 0101 ->  3.5x */
+	45, /* 0110 ->  4.5x */
+	-1, /* 0111 -> RESERVED */
+	-1, /* 1000 -> RESERVED */
+	70, /* 1001 ->  7.0x */
+	80, /* 1010 ->  8.0x */
+	60, /* 1011 ->  6.0x */
+	-1, /* 1100 -> RESERVED */
+	75, /* 1101 ->  7.5x */
+	-1, /* 1110 -> RESERVED */
+	65, /* 1111 ->  6.5x */
+};
+
+/*
+ * VIA C3 Samuel2 Stepping 1->15
+ */
+static const int __cpuinitdata samuel2_eblcr[16] = {
+	50,  /* 0000 ->  5.0x */
+	30,  /* 0001 ->  3.0x */
+	40,  /* 0010 ->  4.0x */
+	100, /* 0011 -> 10.0x */
+	55,  /* 0100 ->  5.5x */
+	35,  /* 0101 ->  3.5x */
+	45,  /* 0110 ->  4.5x */
+	110, /* 0111 -> 11.0x */
+	90,  /* 1000 ->  9.0x */
+	70,  /* 1001 ->  7.0x */
+	80,  /* 1010 ->  8.0x */
+	60,  /* 1011 ->  6.0x */
+	120, /* 1100 -> 12.0x */
+	75,  /* 1101 ->  7.5x */
+	130, /* 1110 -> 13.0x */
+	65,  /* 1111 ->  6.5x */
+};
+
+/*
+ * VIA C3 Ezra
+ */
+static const int __cpuinitdata ezra_mults[16] = {
+	100, /* 0000 -> 10.0x */
+	30,  /* 0001 ->  3.0x */
+	40,  /* 0010 ->  4.0x */
+	90,  /* 0011 ->  9.0x */
+	95,  /* 0100 ->  9.5x */
+	35,  /* 0101 ->  3.5x */
+	45,  /* 0110 ->  4.5x */
+	55,  /* 0111 ->  5.5x */
+	60,  /* 1000 ->  6.0x */
+	70,  /* 1001 ->  7.0x */
+	80,  /* 1010 ->  8.0x */
+	50,  /* 1011 ->  5.0x */
+	65,  /* 1100 ->  6.5x */
+	75,  /* 1101 ->  7.5x */
+	85,  /* 1110 ->  8.5x */
+	120, /* 1111 -> 12.0x */
+};
+
+static const int __cpuinitdata ezra_eblcr[16] = {
+	50,  /* 0000 ->  5.0x */
+	30,  /* 0001 ->  3.0x */
+	40,  /* 0010 ->  4.0x */
+	100, /* 0011 -> 10.0x */
+	55,  /* 0100 ->  5.5x */
+	35,  /* 0101 ->  3.5x */
+	45,  /* 0110 ->  4.5x */
+	95,  /* 0111 ->  9.5x */
+	90,  /* 1000 ->  9.0x */
+	70,  /* 1001 ->  7.0x */
+	80,  /* 1010 ->  8.0x */
+	60,  /* 1011 ->  6.0x */
+	120, /* 1100 -> 12.0x */
+	75,  /* 1101 ->  7.5x */
+	85,  /* 1110 ->  8.5x */
+	65,  /* 1111 ->  6.5x */
+};
+
+/*
+ * VIA C3 (Ezra-T) [C5M].
+ */
+static const int __cpuinitdata ezrat_mults[32] = {
+	100, /* 0000 -> 10.0x */
+	30,  /* 0001 ->  3.0x */
+	40,  /* 0010 ->  4.0x */
+	90,  /* 0011 ->  9.0x */
+	95,  /* 0100 ->  9.5x */
+	35,  /* 0101 ->  3.5x */
+	45,  /* 0110 ->  4.5x */
+	55,  /* 0111 ->  5.5x */
+	60,  /* 1000 ->  6.0x */
+	70,  /* 1001 ->  7.0x */
+	80,  /* 1010 ->  8.0x */
+	50,  /* 1011 ->  5.0x */
+	65,  /* 1100 ->  6.5x */
+	75,  /* 1101 ->  7.5x */
+	85,  /* 1110 ->  8.5x */
+	120, /* 1111 ->  12.0x */
+
+	-1,  /* 0000 -> RESERVED (10.0x) */
+	110, /* 0001 -> 11.0x */
+	-1, /* 0010 -> 12.0x */
+	-1,  /* 0011 -> RESERVED (9.0x)*/
+	105, /* 0100 -> 10.5x */
+	115, /* 0101 -> 11.5x */
+	125, /* 0110 -> 12.5x */
+	135, /* 0111 -> 13.5x */
+	140, /* 1000 -> 14.0x */
+	150, /* 1001 -> 15.0x */
+	160, /* 1010 -> 16.0x */
+	130, /* 1011 -> 13.0x */
+	145, /* 1100 -> 14.5x */
+	155, /* 1101 -> 15.5x */
+	-1,  /* 1110 -> RESERVED (13.0x) */
+	-1,  /* 1111 -> RESERVED (12.0x) */
+};
+
+static const int __cpuinitdata ezrat_eblcr[32] = {
+	50,  /* 0000 ->  5.0x */
+	30,  /* 0001 ->  3.0x */
+	40,  /* 0010 ->  4.0x */
+	100, /* 0011 -> 10.0x */
+	55,  /* 0100 ->  5.5x */
+	35,  /* 0101 ->  3.5x */
+	45,  /* 0110 ->  4.5x */
+	95,  /* 0111 ->  9.5x */
+	90,  /* 1000 ->  9.0x */
+	70,  /* 1001 ->  7.0x */
+	80,  /* 1010 ->  8.0x */
+	60,  /* 1011 ->  6.0x */
+	120, /* 1100 -> 12.0x */
+	75,  /* 1101 ->  7.5x */
+	85,  /* 1110 ->  8.5x */
+	65,  /* 1111 ->  6.5x */
+
+	-1,  /* 0000 -> RESERVED (9.0x) */
+	110, /* 0001 -> 11.0x */
+	120, /* 0010 -> 12.0x */
+	-1,  /* 0011 -> RESERVED (10.0x)*/
+	135, /* 0100 -> 13.5x */
+	115, /* 0101 -> 11.5x */
+	125, /* 0110 -> 12.5x */
+	105, /* 0111 -> 10.5x */
+	130, /* 1000 -> 13.0x */
+	150, /* 1001 -> 15.0x */
+	160, /* 1010 -> 16.0x */
+	140, /* 1011 -> 14.0x */
+	-1,  /* 1100 -> RESERVED (12.0x) */
+	155, /* 1101 -> 15.5x */
+	-1,  /* 1110 -> RESERVED (13.0x) */
+	145, /* 1111 -> 14.5x */
+};
+
+/*
+ * VIA C3 Nehemiah */
+
+static const int __cpuinitdata nehemiah_mults[32] = {
+	100, /* 0000 -> 10.0x */
+	-1, /* 0001 -> 16.0x */
+	40,  /* 0010 ->  4.0x */
+	90,  /* 0011 ->  9.0x */
+	95,  /* 0100 ->  9.5x */
+	-1,  /* 0101 ->  RESERVED */
+	45,  /* 0110 ->  4.5x */
+	55,  /* 0111 ->  5.5x */
+	60,  /* 1000 ->  6.0x */
+	70,  /* 1001 ->  7.0x */
+	80,  /* 1010 ->  8.0x */
+	50,  /* 1011 ->  5.0x */
+	65,  /* 1100 ->  6.5x */
+	75,  /* 1101 ->  7.5x */
+	85,  /* 1110 ->  8.5x */
+	120, /* 1111 -> 12.0x */
+	-1, /* 0000 -> 10.0x */
+	110, /* 0001 -> 11.0x */
+	-1, /* 0010 -> 12.0x */
+	-1,  /* 0011 ->  9.0x */
+	105, /* 0100 -> 10.5x */
+	115, /* 0101 -> 11.5x */
+	125, /* 0110 -> 12.5x */
+	135, /* 0111 -> 13.5x */
+	140, /* 1000 -> 14.0x */
+	150, /* 1001 -> 15.0x */
+	160, /* 1010 -> 16.0x */
+	130, /* 1011 -> 13.0x */
+	145, /* 1100 -> 14.5x */
+	155, /* 1101 -> 15.5x */
+	-1,  /* 1110 -> RESERVED (13.0x) */
+	-1, /* 1111 -> 12.0x */
+};
+
+static const int __cpuinitdata nehemiah_eblcr[32] = {
+	50,  /* 0000 ->  5.0x */
+	160, /* 0001 -> 16.0x */
+	40,  /* 0010 ->  4.0x */
+	100, /* 0011 -> 10.0x */
+	55,  /* 0100 ->  5.5x */
+	-1,  /* 0101 ->  RESERVED */
+	45,  /* 0110 ->  4.5x */
+	95,  /* 0111 ->  9.5x */
+	90,  /* 1000 ->  9.0x */
+	70,  /* 1001 ->  7.0x */
+	80,  /* 1010 ->  8.0x */
+	60,  /* 1011 ->  6.0x */
+	120, /* 1100 -> 12.0x */
+	75,  /* 1101 ->  7.5x */
+	85,  /* 1110 ->  8.5x */
+	65,  /* 1111 ->  6.5x */
+	90,  /* 0000 ->  9.0x */
+	110, /* 0001 -> 11.0x */
+	120, /* 0010 -> 12.0x */
+	100, /* 0011 -> 10.0x */
+	135, /* 0100 -> 13.5x */
+	115, /* 0101 -> 11.5x */
+	125, /* 0110 -> 12.5x */
+	105, /* 0111 -> 10.5x */
+	130, /* 1000 -> 13.0x */
+	150, /* 1001 -> 15.0x */
+	160, /* 1010 -> 16.0x */
+	140, /* 1011 -> 14.0x */
+	120, /* 1100 -> 12.0x */
+	155, /* 1101 -> 15.5x */
+	-1,  /* 1110 -> RESERVED (13.0x) */
+	145 /* 1111 -> 14.5x */
+};
+
+/*
+ * Voltage scales. Div/Mod by 1000 to get actual voltage.
+ * Which scale to use depends on the VRM type in use.
+ */
+
+struct mV_pos {
+	unsigned short mV;
+	unsigned short pos;
+};
+
+static const struct mV_pos __cpuinitdata vrm85_mV[32] = {
+	{1250, 8},	{1200, 6},	{1150, 4},	{1100, 2},
+	{1050, 0},	{1800, 30},	{1750, 28},	{1700, 26},
+	{1650, 24},	{1600, 22},	{1550, 20},	{1500, 18},
+	{1450, 16},	{1400, 14},	{1350, 12},	{1300, 10},
+	{1275, 9},	{1225, 7},	{1175, 5},	{1125, 3},
+	{1075, 1},	{1825, 31},	{1775, 29},	{1725, 27},
+	{1675, 25},	{1625, 23},	{1575, 21},	{1525, 19},
+	{1475, 17},	{1425, 15},	{1375, 13},	{1325, 11}
+};
+
+static const unsigned char __cpuinitdata mV_vrm85[32] = {
+	0x04,	0x14,	0x03,	0x13,	0x02,	0x12,	0x01,	0x11,
+	0x00,	0x10,	0x0f,	0x1f,	0x0e,	0x1e,	0x0d,	0x1d,
+	0x0c,	0x1c,	0x0b,	0x1b,	0x0a,	0x1a,	0x09,	0x19,
+	0x08,	0x18,	0x07,	0x17,	0x06,	0x16,	0x05,	0x15
+};
+
+static const struct mV_pos __cpuinitdata mobilevrm_mV[32] = {
+	{1750, 31},	{1700, 30},	{1650, 29},	{1600, 28},
+	{1550, 27},	{1500, 26},	{1450, 25},	{1400, 24},
+	{1350, 23},	{1300, 22},	{1250, 21},	{1200, 20},
+	{1150, 19},	{1100, 18},	{1050, 17},	{1000, 16},
+	{975, 15},	{950, 14},	{925, 13},	{900, 12},
+	{875, 11},	{850, 10},	{825, 9},	{800, 8},
+	{775, 7},	{750, 6},	{725, 5},	{700, 4},
+	{675, 3},	{650, 2},	{625, 1},	{600, 0}
+};
+
+static const unsigned char __cpuinitdata mV_mobilevrm[32] = {
+	0x1f,	0x1e,	0x1d,	0x1c,	0x1b,	0x1a,	0x19,	0x18,
+	0x17,	0x16,	0x15,	0x14,	0x13,	0x12,	0x11,	0x10,
+	0x0f,	0x0e,	0x0d,	0x0c,	0x0b,	0x0a,	0x09,	0x08,
+	0x07,	0x06,	0x05,	0x04,	0x03,	0x02,	0x01,	0x00
+};
+
diff -druN linux-2.6.39-libre/drivers/cpufreq/longrun.c linux-3.0-rc7-libre/drivers/cpufreq/longrun.c
--- linux-2.6.39-libre/drivers/cpufreq/longrun.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/cpufreq/longrun.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,324 @@
+/*
+ * (C) 2002 - 2003  Dominik Brodowski <linux@brodo.de>
+ *
+ *  Licensed under the terms of the GNU GPL License version 2.
+ *
+ *  BIG FAT DISCLAIMER: Work in progress code. Possibly *dangerous*
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/cpufreq.h>
+#include <linux/timex.h>
+
+#include <asm/msr.h>
+#include <asm/processor.h>
+
+static struct cpufreq_driver	longrun_driver;
+
+/**
+ * longrun_{low,high}_freq is needed for the conversion of cpufreq kHz
+ * values into per cent values. In TMTA microcode, the following is valid:
+ * performance_pctg = (current_freq - low_freq)/(high_freq - low_freq)
+ */
+static unsigned int longrun_low_freq, longrun_high_freq;
+
+
+/**
+ * longrun_get_policy - get the current LongRun policy
+ * @policy: struct cpufreq_policy where current policy is written into
+ *
+ * Reads the current LongRun policy by access to MSR_TMTA_LONGRUN_FLAGS
+ * and MSR_TMTA_LONGRUN_CTRL
+ */
+static void __cpuinit longrun_get_policy(struct cpufreq_policy *policy)
+{
+	u32 msr_lo, msr_hi;
+
+	rdmsr(MSR_TMTA_LONGRUN_FLAGS, msr_lo, msr_hi);
+	pr_debug("longrun flags are %x - %x\n", msr_lo, msr_hi);
+	if (msr_lo & 0x01)
+		policy->policy = CPUFREQ_POLICY_PERFORMANCE;
+	else
+		policy->policy = CPUFREQ_POLICY_POWERSAVE;
+
+	rdmsr(MSR_TMTA_LONGRUN_CTRL, msr_lo, msr_hi);
+	pr_debug("longrun ctrl is %x - %x\n", msr_lo, msr_hi);
+	msr_lo &= 0x0000007F;
+	msr_hi &= 0x0000007F;
+
+	if (longrun_high_freq <= longrun_low_freq) {
+		/* Assume degenerate Longrun table */
+		policy->min = policy->max = longrun_high_freq;
+	} else {
+		policy->min = longrun_low_freq + msr_lo *
+			((longrun_high_freq - longrun_low_freq) / 100);
+		policy->max = longrun_low_freq + msr_hi *
+			((longrun_high_freq - longrun_low_freq) / 100);
+	}
+	policy->cpu = 0;
+}
+
+
+/**
+ * longrun_set_policy - sets a new CPUFreq policy
+ * @policy: new policy
+ *
+ * Sets a new CPUFreq policy on LongRun-capable processors. This function
+ * has to be called with cpufreq_driver locked.
+ */
+static int longrun_set_policy(struct cpufreq_policy *policy)
+{
+	u32 msr_lo, msr_hi;
+	u32 pctg_lo, pctg_hi;
+
+	if (!policy)
+		return -EINVAL;
+
+	if (longrun_high_freq <= longrun_low_freq) {
+		/* Assume degenerate Longrun table */
+		pctg_lo = pctg_hi = 100;
+	} else {
+		pctg_lo = (policy->min - longrun_low_freq) /
+			((longrun_high_freq - longrun_low_freq) / 100);
+		pctg_hi = (policy->max - longrun_low_freq) /
+			((longrun_high_freq - longrun_low_freq) / 100);
+	}
+
+	if (pctg_hi > 100)
+		pctg_hi = 100;
+	if (pctg_lo > pctg_hi)
+		pctg_lo = pctg_hi;
+
+	/* performance or economy mode */
+	rdmsr(MSR_TMTA_LONGRUN_FLAGS, msr_lo, msr_hi);
+	msr_lo &= 0xFFFFFFFE;
+	switch (policy->policy) {
+	case CPUFREQ_POLICY_PERFORMANCE:
+		msr_lo |= 0x00000001;
+		break;
+	case CPUFREQ_POLICY_POWERSAVE:
+		break;
+	}
+	wrmsr(MSR_TMTA_LONGRUN_FLAGS, msr_lo, msr_hi);
+
+	/* lower and upper boundary */
+	rdmsr(MSR_TMTA_LONGRUN_CTRL, msr_lo, msr_hi);
+	msr_lo &= 0xFFFFFF80;
+	msr_hi &= 0xFFFFFF80;
+	msr_lo |= pctg_lo;
+	msr_hi |= pctg_hi;
+	wrmsr(MSR_TMTA_LONGRUN_CTRL, msr_lo, msr_hi);
+
+	return 0;
+}
+
+
+/**
+ * longrun_verify_poliy - verifies a new CPUFreq policy
+ * @policy: the policy to verify
+ *
+ * Validates a new CPUFreq policy. This function has to be called with
+ * cpufreq_driver locked.
+ */
+static int longrun_verify_policy(struct cpufreq_policy *policy)
+{
+	if (!policy)
+		return -EINVAL;
+
+	policy->cpu = 0;
+	cpufreq_verify_within_limits(policy,
+		policy->cpuinfo.min_freq,
+		policy->cpuinfo.max_freq);
+
+	if ((policy->policy != CPUFREQ_POLICY_POWERSAVE) &&
+	    (policy->policy != CPUFREQ_POLICY_PERFORMANCE))
+		return -EINVAL;
+
+	return 0;
+}
+
+static unsigned int longrun_get(unsigned int cpu)
+{
+	u32 eax, ebx, ecx, edx;
+
+	if (cpu)
+		return 0;
+
+	cpuid(0x80860007, &eax, &ebx, &ecx, &edx);
+	pr_debug("cpuid eax is %u\n", eax);
+
+	return eax * 1000;
+}
+
+/**
+ * longrun_determine_freqs - determines the lowest and highest possible core frequency
+ * @low_freq: an int to put the lowest frequency into
+ * @high_freq: an int to put the highest frequency into
+ *
+ * Determines the lowest and highest possible core frequencies on this CPU.
+ * This is necessary to calculate the performance percentage according to
+ * TMTA rules:
+ * performance_pctg = (target_freq - low_freq)/(high_freq - low_freq)
+ */
+static int __cpuinit longrun_determine_freqs(unsigned int *low_freq,
+						      unsigned int *high_freq)
+{
+	u32 msr_lo, msr_hi;
+	u32 save_lo, save_hi;
+	u32 eax, ebx, ecx, edx;
+	u32 try_hi;
+	struct cpuinfo_x86 *c = &cpu_data(0);
+
+	if (!low_freq || !high_freq)
+		return -EINVAL;
+
+	if (cpu_has(c, X86_FEATURE_LRTI)) {
+		/* if the LongRun Table Interface is present, the
+		 * detection is a bit easier:
+		 * For minimum frequency, read out the maximum
+		 * level (msr_hi), write that into "currently
+		 * selected level", and read out the frequency.
+		 * For maximum frequency, read out level zero.
+		 */
+		/* minimum */
+		rdmsr(MSR_TMTA_LRTI_READOUT, msr_lo, msr_hi);
+		wrmsr(MSR_TMTA_LRTI_READOUT, msr_hi, msr_hi);
+		rdmsr(MSR_TMTA_LRTI_VOLT_MHZ, msr_lo, msr_hi);
+		*low_freq = msr_lo * 1000; /* to kHz */
+
+		/* maximum */
+		wrmsr(MSR_TMTA_LRTI_READOUT, 0, msr_hi);
+		rdmsr(MSR_TMTA_LRTI_VOLT_MHZ, msr_lo, msr_hi);
+		*high_freq = msr_lo * 1000; /* to kHz */
+
+		pr_debug("longrun table interface told %u - %u kHz\n",
+				*low_freq, *high_freq);
+
+		if (*low_freq > *high_freq)
+			*low_freq = *high_freq;
+		return 0;
+	}
+
+	/* set the upper border to the value determined during TSC init */
+	*high_freq = (cpu_khz / 1000);
+	*high_freq = *high_freq * 1000;
+	pr_debug("high frequency is %u kHz\n", *high_freq);
+
+	/* get current borders */
+	rdmsr(MSR_TMTA_LONGRUN_CTRL, msr_lo, msr_hi);
+	save_lo = msr_lo & 0x0000007F;
+	save_hi = msr_hi & 0x0000007F;
+
+	/* if current perf_pctg is larger than 90%, we need to decrease the
+	 * upper limit to make the calculation more accurate.
+	 */
+	cpuid(0x80860007, &eax, &ebx, &ecx, &edx);
+	/* try decreasing in 10% steps, some processors react only
+	 * on some barrier values */
+	for (try_hi = 80; try_hi > 0 && ecx > 90; try_hi -= 10) {
+		/* set to 0 to try_hi perf_pctg */
+		msr_lo &= 0xFFFFFF80;
+		msr_hi &= 0xFFFFFF80;
+		msr_hi |= try_hi;
+		wrmsr(MSR_TMTA_LONGRUN_CTRL, msr_lo, msr_hi);
+
+		/* read out current core MHz and current perf_pctg */
+		cpuid(0x80860007, &eax, &ebx, &ecx, &edx);
+
+		/* restore values */
+		wrmsr(MSR_TMTA_LONGRUN_CTRL, save_lo, save_hi);
+	}
+	pr_debug("percentage is %u %%, freq is %u MHz\n", ecx, eax);
+
+	/* performance_pctg = (current_freq - low_freq)/(high_freq - low_freq)
+	 * eqals
+	 * low_freq * (1 - perf_pctg) = (cur_freq - high_freq * perf_pctg)
+	 *
+	 * high_freq * perf_pctg is stored tempoarily into "ebx".
+	 */
+	ebx = (((cpu_khz / 1000) * ecx) / 100); /* to MHz */
+
+	if ((ecx > 95) || (ecx == 0) || (eax < ebx))
+		return -EIO;
+
+	edx = ((eax - ebx) * 100) / (100 - ecx);
+	*low_freq = edx * 1000; /* back to kHz */
+
+	pr_debug("low frequency is %u kHz\n", *low_freq);
+
+	if (*low_freq > *high_freq)
+		*low_freq = *high_freq;
+
+	return 0;
+}
+
+
+static int __cpuinit longrun_cpu_init(struct cpufreq_policy *policy)
+{
+	int result = 0;
+
+	/* capability check */
+	if (policy->cpu != 0)
+		return -ENODEV;
+
+	/* detect low and high frequency */
+	result = longrun_determine_freqs(&longrun_low_freq, &longrun_high_freq);
+	if (result)
+		return result;
+
+	/* cpuinfo and default policy values */
+	policy->cpuinfo.min_freq = longrun_low_freq;
+	policy->cpuinfo.max_freq = longrun_high_freq;
+	policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL;
+	longrun_get_policy(policy);
+
+	return 0;
+}
+
+
+static struct cpufreq_driver longrun_driver = {
+	.flags		= CPUFREQ_CONST_LOOPS,
+	.verify		= longrun_verify_policy,
+	.setpolicy	= longrun_set_policy,
+	.get		= longrun_get,
+	.init		= longrun_cpu_init,
+	.name		= "longrun",
+	.owner		= THIS_MODULE,
+};
+
+
+/**
+ * longrun_init - initializes the Transmeta Crusoe LongRun CPUFreq driver
+ *
+ * Initializes the LongRun support.
+ */
+static int __init longrun_init(void)
+{
+	struct cpuinfo_x86 *c = &cpu_data(0);
+
+	if (c->x86_vendor != X86_VENDOR_TRANSMETA ||
+	    !cpu_has(c, X86_FEATURE_LONGRUN))
+		return -ENODEV;
+
+	return cpufreq_register_driver(&longrun_driver);
+}
+
+
+/**
+ * longrun_exit - unregisters LongRun support
+ */
+static void __exit longrun_exit(void)
+{
+	cpufreq_unregister_driver(&longrun_driver);
+}
+
+
+MODULE_AUTHOR("Dominik Brodowski <linux@brodo.de>");
+MODULE_DESCRIPTION("LongRun driver for Transmeta Crusoe and "
+		"Efficeon processors.");
+MODULE_LICENSE("GPL");
+
+module_init(longrun_init);
+module_exit(longrun_exit);
diff -druN linux-2.6.39-libre/drivers/cpufreq/Makefile linux-3.0-rc7-libre/drivers/cpufreq/Makefile
--- linux-2.6.39-libre/drivers/cpufreq/Makefile	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/cpufreq/Makefile	2011-07-11 19:51:52.000000000 -0400
@@ -13,3 +13,31 @@
 # CPUfreq cross-arch helpers
 obj-$(CONFIG_CPU_FREQ_TABLE)		+= freq_table.o
 
+##################################################################################d
+# x86 drivers.
+# Link order matters. K8 is preferred to ACPI because of firmware bugs in early
+# K8 systems. ACPI is preferred to all other hardware-specific drivers.
+# speedstep-* is preferred over p4-clockmod.
+
+obj-$(CONFIG_X86_POWERNOW_K8)		+= powernow-k8.o mperf.o
+obj-$(CONFIG_X86_ACPI_CPUFREQ)		+= acpi-cpufreq.o mperf.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
+obj-$(CONFIG_X86_E_POWERSAVER)		+= e_powersaver.o
+obj-$(CONFIG_ELAN_CPUFREQ)		+= elanfreq.o
+obj-$(CONFIG_SC520_CPUFREQ)		+= sc520_freq.o
+obj-$(CONFIG_X86_LONGRUN)		+= longrun.o
+obj-$(CONFIG_X86_GX_SUSPMOD)		+= gx-suspmod.o
+obj-$(CONFIG_X86_SPEEDSTEP_ICH)		+= speedstep-ich.o
+obj-$(CONFIG_X86_SPEEDSTEP_LIB)		+= speedstep-lib.o
+obj-$(CONFIG_X86_SPEEDSTEP_SMI)		+= speedstep-smi.o
+obj-$(CONFIG_X86_SPEEDSTEP_CENTRINO)	+= speedstep-centrino.o
+obj-$(CONFIG_X86_P4_CLOCKMOD)		+= p4-clockmod.o
+obj-$(CONFIG_X86_CPUFREQ_NFORCE2)	+= cpufreq-nforce2.o
+
+##################################################################################d
+
+# ARM SoC drivers
+obj-$(CONFIG_UX500_SOC_DB8500)		+= db8500-cpufreq.o
diff -druN linux-2.6.39-libre/drivers/cpufreq/mperf.c linux-3.0-rc7-libre/drivers/cpufreq/mperf.c
--- linux-2.6.39-libre/drivers/cpufreq/mperf.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/cpufreq/mperf.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,51 @@
+#include <linux/kernel.h>
+#include <linux/smp.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/cpufreq.h>
+#include <linux/slab.h>
+
+#include "mperf.h"
+
+static DEFINE_PER_CPU(struct aperfmperf, acfreq_old_perf);
+
+/* Called via smp_call_function_single(), on the target CPU */
+static void read_measured_perf_ctrs(void *_cur)
+{
+	struct aperfmperf *am = _cur;
+
+	get_aperfmperf(am);
+}
+
+/*
+ * Return the measured active (C0) frequency on this CPU since last call
+ * to this function.
+ * Input: cpu number
+ * Return: Average CPU frequency in terms of max frequency (zero on error)
+ *
+ * We use IA32_MPERF and IA32_APERF MSRs to get the measured performance
+ * over a period of time, while CPU is in C0 state.
+ * IA32_MPERF counts at the rate of max advertised frequency
+ * IA32_APERF counts at the rate of actual CPU frequency
+ * Only IA32_APERF/IA32_MPERF ratio is architecturally defined and
+ * no meaning should be associated with absolute values of these MSRs.
+ */
+unsigned int cpufreq_get_measured_perf(struct cpufreq_policy *policy,
+					unsigned int cpu)
+{
+	struct aperfmperf perf;
+	unsigned long ratio;
+	unsigned int retval;
+
+	if (smp_call_function_single(cpu, read_measured_perf_ctrs, &perf, 1))
+		return 0;
+
+	ratio = calc_aperfmperf_ratio(&per_cpu(acfreq_old_perf, cpu), &perf);
+	per_cpu(acfreq_old_perf, cpu) = perf;
+
+	retval = (policy->cpuinfo.max_freq * ratio) >> APERFMPERF_SHIFT;
+
+	return retval;
+}
+EXPORT_SYMBOL_GPL(cpufreq_get_measured_perf);
+MODULE_LICENSE("GPL");
diff -druN linux-2.6.39-libre/drivers/cpufreq/mperf.h linux-3.0-rc7-libre/drivers/cpufreq/mperf.h
--- linux-2.6.39-libre/drivers/cpufreq/mperf.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/cpufreq/mperf.h	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,9 @@
+/*
+ *  (c) 2010 Advanced Micro Devices, Inc.
+ *  Your use of this code is subject to the terms and conditions of the
+ *  GNU general public license version 2. See "COPYING" or
+ *  http://www.gnu.org/licenses/gpl.html
+ */
+
+unsigned int cpufreq_get_measured_perf(struct cpufreq_policy *policy,
+					unsigned int cpu);
diff -druN linux-2.6.39-libre/drivers/cpufreq/p4-clockmod.c linux-3.0-rc7-libre/drivers/cpufreq/p4-clockmod.c
--- linux-2.6.39-libre/drivers/cpufreq/p4-clockmod.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/cpufreq/p4-clockmod.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,329 @@
+/*
+ *	Pentium 4/Xeon CPU on demand clock modulation/speed scaling
+ *	(C) 2002 - 2003 Dominik Brodowski <linux@brodo.de>
+ *	(C) 2002 Zwane Mwaikambo <zwane@commfireservices.com>
+ *	(C) 2002 Arjan van de Ven <arjanv@redhat.com>
+ *	(C) 2002 Tora T. Engstad
+ *	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.
+ *
+ *      The author(s) of this software shall not be held liable for damages
+ *      of any nature resulting due to the use of this software. This
+ *      software is provided AS-IS with no warranties.
+ *
+ *	Date		Errata			Description
+ *	20020525	N44, O17	12.5% or 25% DC causes lockup
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/smp.h>
+#include <linux/cpufreq.h>
+#include <linux/cpumask.h>
+#include <linux/timex.h>
+
+#include <asm/processor.h>
+#include <asm/msr.h>
+#include <asm/timer.h>
+
+#include "speedstep-lib.h"
+
+#define PFX	"p4-clockmod: "
+
+/*
+ * Duty Cycle (3bits), note DC_DISABLE is not specified in
+ * intel docs i just use it to mean disable
+ */
+enum {
+	DC_RESV, DC_DFLT, DC_25PT, DC_38PT, DC_50PT,
+	DC_64PT, DC_75PT, DC_88PT, DC_DISABLE
+};
+
+#define DC_ENTRIES	8
+
+
+static int has_N44_O17_errata[NR_CPUS];
+static unsigned int stock_freq;
+static struct cpufreq_driver p4clockmod_driver;
+static unsigned int cpufreq_p4_get(unsigned int cpu);
+
+static int cpufreq_p4_setdc(unsigned int cpu, unsigned int newstate)
+{
+	u32 l, h;
+
+	if (!cpu_online(cpu) ||
+	    (newstate > DC_DISABLE) || (newstate == DC_RESV))
+		return -EINVAL;
+
+	rdmsr_on_cpu(cpu, MSR_IA32_THERM_STATUS, &l, &h);
+
+	if (l & 0x01)
+		pr_debug("CPU#%d currently thermal throttled\n", cpu);
+
+	if (has_N44_O17_errata[cpu] &&
+	    (newstate == DC_25PT || newstate == DC_DFLT))
+		newstate = DC_38PT;
+
+	rdmsr_on_cpu(cpu, MSR_IA32_THERM_CONTROL, &l, &h);
+	if (newstate == DC_DISABLE) {
+		pr_debug("CPU#%d disabling modulation\n", cpu);
+		wrmsr_on_cpu(cpu, MSR_IA32_THERM_CONTROL, l & ~(1<<4), h);
+	} else {
+		pr_debug("CPU#%d setting duty cycle to %d%%\n",
+			cpu, ((125 * newstate) / 10));
+		/* bits 63 - 5	: reserved
+		 * bit  4	: enable/disable
+		 * bits 3-1	: duty cycle
+		 * bit  0	: reserved
+		 */
+		l = (l & ~14);
+		l = l | (1<<4) | ((newstate & 0x7)<<1);
+		wrmsr_on_cpu(cpu, MSR_IA32_THERM_CONTROL, l, h);
+	}
+
+	return 0;
+}
+
+
+static struct cpufreq_frequency_table p4clockmod_table[] = {
+	{DC_RESV, CPUFREQ_ENTRY_INVALID},
+	{DC_DFLT, 0},
+	{DC_25PT, 0},
+	{DC_38PT, 0},
+	{DC_50PT, 0},
+	{DC_64PT, 0},
+	{DC_75PT, 0},
+	{DC_88PT, 0},
+	{DC_DISABLE, 0},
+	{DC_RESV, CPUFREQ_TABLE_END},
+};
+
+
+static int cpufreq_p4_target(struct cpufreq_policy *policy,
+			     unsigned int target_freq,
+			     unsigned int relation)
+{
+	unsigned int    newstate = DC_RESV;
+	struct cpufreq_freqs freqs;
+	int i;
+
+	if (cpufreq_frequency_table_target(policy, &p4clockmod_table[0],
+				target_freq, relation, &newstate))
+		return -EINVAL;
+
+	freqs.old = cpufreq_p4_get(policy->cpu);
+	freqs.new = stock_freq * p4clockmod_table[newstate].index / 8;
+
+	if (freqs.new == freqs.old)
+		return 0;
+
+	/* notifiers */
+	for_each_cpu(i, policy->cpus) {
+		freqs.cpu = i;
+		cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
+	}
+
+	/* run on each logical CPU,
+	 * see section 13.15.3 of IA32 Intel Architecture Software
+	 * Developer's Manual, Volume 3
+	 */
+	for_each_cpu(i, policy->cpus)
+		cpufreq_p4_setdc(i, p4clockmod_table[newstate].index);
+
+	/* notifiers */
+	for_each_cpu(i, policy->cpus) {
+		freqs.cpu = i;
+		cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
+	}
+
+	return 0;
+}
+
+
+static int cpufreq_p4_verify(struct cpufreq_policy *policy)
+{
+	return cpufreq_frequency_table_verify(policy, &p4clockmod_table[0]);
+}
+
+
+static unsigned int cpufreq_p4_get_frequency(struct cpuinfo_x86 *c)
+{
+	if (c->x86 == 0x06) {
+		if (cpu_has(c, X86_FEATURE_EST))
+			printk_once(KERN_WARNING PFX "Warning: EST-capable "
+			       "CPU detected. The acpi-cpufreq module offers "
+			       "voltage scaling in addition to frequency "
+			       "scaling. You should use that instead of "
+			       "p4-clockmod, if possible.\n");
+		switch (c->x86_model) {
+		case 0x0E: /* Core */
+		case 0x0F: /* Core Duo */
+		case 0x16: /* Celeron Core */
+		case 0x1C: /* Atom */
+			p4clockmod_driver.flags |= CPUFREQ_CONST_LOOPS;
+			return speedstep_get_frequency(SPEEDSTEP_CPU_PCORE);
+		case 0x0D: /* Pentium M (Dothan) */
+			p4clockmod_driver.flags |= CPUFREQ_CONST_LOOPS;
+			/* fall through */
+		case 0x09: /* Pentium M (Banias) */
+			return speedstep_get_frequency(SPEEDSTEP_CPU_PM);
+		}
+	}
+
+	if (c->x86 != 0xF)
+		return 0;
+
+	/* on P-4s, the TSC runs with constant frequency independent whether
+	 * throttling is active or not. */
+	p4clockmod_driver.flags |= CPUFREQ_CONST_LOOPS;
+
+	if (speedstep_detect_processor() == SPEEDSTEP_CPU_P4M) {
+		printk(KERN_WARNING PFX "Warning: Pentium 4-M detected. "
+		       "The speedstep-ich or acpi cpufreq modules offer "
+		       "voltage scaling in addition of frequency scaling. "
+		       "You should use either one instead of p4-clockmod, "
+		       "if possible.\n");
+		return speedstep_get_frequency(SPEEDSTEP_CPU_P4M);
+	}
+
+	return speedstep_get_frequency(SPEEDSTEP_CPU_P4D);
+}
+
+
+
+static int cpufreq_p4_cpu_init(struct cpufreq_policy *policy)
+{
+	struct cpuinfo_x86 *c = &cpu_data(policy->cpu);
+	int cpuid = 0;
+	unsigned int i;
+
+#ifdef CONFIG_SMP
+	cpumask_copy(policy->cpus, cpu_sibling_mask(policy->cpu));
+#endif
+
+	/* Errata workaround */
+	cpuid = (c->x86 << 8) | (c->x86_model << 4) | c->x86_mask;
+	switch (cpuid) {
+	case 0x0f07:
+	case 0x0f0a:
+	case 0x0f11:
+	case 0x0f12:
+		has_N44_O17_errata[policy->cpu] = 1;
+		pr_debug("has errata -- disabling low frequencies\n");
+	}
+
+	if (speedstep_detect_processor() == SPEEDSTEP_CPU_P4D &&
+	    c->x86_model < 2) {
+		/* switch to maximum frequency and measure result */
+		cpufreq_p4_setdc(policy->cpu, DC_DISABLE);
+		recalibrate_cpu_khz();
+	}
+	/* get max frequency */
+	stock_freq = cpufreq_p4_get_frequency(c);
+	if (!stock_freq)
+		return -EINVAL;
+
+	/* table init */
+	for (i = 1; (p4clockmod_table[i].frequency != CPUFREQ_TABLE_END); i++) {
+		if ((i < 2) && (has_N44_O17_errata[policy->cpu]))
+			p4clockmod_table[i].frequency = CPUFREQ_ENTRY_INVALID;
+		else
+			p4clockmod_table[i].frequency = (stock_freq * i)/8;
+	}
+	cpufreq_frequency_table_get_attr(p4clockmod_table, policy->cpu);
+
+	/* cpuinfo and default policy values */
+
+	/* the transition latency is set to be 1 higher than the maximum
+	 * transition latency of the ondemand governor */
+	policy->cpuinfo.transition_latency = 10000001;
+	policy->cur = stock_freq;
+
+	return cpufreq_frequency_table_cpuinfo(policy, &p4clockmod_table[0]);
+}
+
+
+static int cpufreq_p4_cpu_exit(struct cpufreq_policy *policy)
+{
+	cpufreq_frequency_table_put_attr(policy->cpu);
+	return 0;
+}
+
+static unsigned int cpufreq_p4_get(unsigned int cpu)
+{
+	u32 l, h;
+
+	rdmsr_on_cpu(cpu, MSR_IA32_THERM_CONTROL, &l, &h);
+
+	if (l & 0x10) {
+		l = l >> 1;
+		l &= 0x7;
+	} else
+		l = DC_DISABLE;
+
+	if (l != DC_DISABLE)
+		return stock_freq * l / 8;
+
+	return stock_freq;
+}
+
+static struct freq_attr *p4clockmod_attr[] = {
+	&cpufreq_freq_attr_scaling_available_freqs,
+	NULL,
+};
+
+static struct cpufreq_driver p4clockmod_driver = {
+	.verify		= cpufreq_p4_verify,
+	.target		= cpufreq_p4_target,
+	.init		= cpufreq_p4_cpu_init,
+	.exit		= cpufreq_p4_cpu_exit,
+	.get		= cpufreq_p4_get,
+	.name		= "p4-clockmod",
+	.owner		= THIS_MODULE,
+	.attr		= p4clockmod_attr,
+};
+
+
+static int __init cpufreq_p4_init(void)
+{
+	struct cpuinfo_x86 *c = &cpu_data(0);
+	int ret;
+
+	/*
+	 * THERM_CONTROL is architectural for IA32 now, so
+	 * we can rely on the capability checks
+	 */
+	if (c->x86_vendor != X86_VENDOR_INTEL)
+		return -ENODEV;
+
+	if (!test_cpu_cap(c, X86_FEATURE_ACPI) ||
+				!test_cpu_cap(c, X86_FEATURE_ACC))
+		return -ENODEV;
+
+	ret = cpufreq_register_driver(&p4clockmod_driver);
+	if (!ret)
+		printk(KERN_INFO PFX "P4/Xeon(TM) CPU On-Demand Clock "
+				"Modulation available\n");
+
+	return ret;
+}
+
+
+static void __exit cpufreq_p4_exit(void)
+{
+	cpufreq_unregister_driver(&p4clockmod_driver);
+}
+
+
+MODULE_AUTHOR("Zwane Mwaikambo <zwane@commfireservices.com>");
+MODULE_DESCRIPTION("cpufreq driver for Pentium(TM) 4/Xeon(TM)");
+MODULE_LICENSE("GPL");
+
+late_initcall(cpufreq_p4_init);
+module_exit(cpufreq_p4_exit);
diff -druN linux-2.6.39-libre/drivers/cpufreq/pcc-cpufreq.c linux-3.0-rc7-libre/drivers/cpufreq/pcc-cpufreq.c
--- linux-2.6.39-libre/drivers/cpufreq/pcc-cpufreq.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/cpufreq/pcc-cpufreq.c	2011-07-11 19:51:52.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.10.00"
+#define POLL_LOOPS 	300
+
+#define CMD_COMPLETE 	0x1
+#define CMD_GET_FREQ 	0x0
+#define CMD_SET_FREQ 	0x1
+
+#define BUF_SZ		4
+
+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] = {0x9F, 0x2C, 0x9B, 0x63, 0x91, 0x70, 0x1f, 0x49,
+			  0xBB, 0x4F, 0xA5, 0x98, 0x2F, 0xA1, 0xB5, 0x46};
+
+struct pcc_cpu {
+	u32 input_offset;
+	u32 output_offset;
+};
+
+static struct pcc_cpu __percpu *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);
+
+	pr_debug("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) {
+		pr_debug("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);
+
+	pr_debug("get: SUCCESS: (virtual) output_offset for cpu %d is "
+		"0x%p, 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) {
+		pr_debug("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 0;
+}
+
+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);
+
+	pr_debug("target: CPU %d should go to target freq: %d "
+		"(virtual) input_offset is 0x%p\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) {
+		pr_debug("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);
+	pr_debug("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);
+
+	pr_debug("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;
+	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, pcch_handle;
+	int ret = 0;
+
+	status = acpi_get_handle(NULL, "\\_SB", &handle);
+	if (ACPI_FAILURE(status))
+		return -ENODEV;
+
+	status = acpi_get_handle(handle, "PCCH", &pcch_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)
+			pr_debug("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;
+
+	pr_debug("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) {
+		pr_debug("probe: could not map shared mem region\n");
+		goto out_free;
+	}
+	pcch_hdr = pcch_virt_addr;
+
+	pr_debug("probe: PCCH header (virtual) addr: 0x%p\n", pcch_hdr);
+	pr_debug("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));
+
+	pr_debug("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;
+
+	pr_debug("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;
+
+	pr_debug("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 out;
+	}
+
+	result = pcc_get_offset(cpu);
+	if (result) {
+		pr_debug("init: PCCP evaluation failed\n");
+		goto out;
+	}
+
+	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);
+
+	if (!policy->cur) {
+		pr_debug("init: Unable to get current CPU frequency\n");
+		result = -EINVAL;
+		goto out;
+	}
+
+	pr_debug("init: policy->max is %d, policy->min is %d\n",
+		policy->max, policy->min);
+out:
+	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) {
+		pr_debug("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 -druN linux-2.6.39-libre/drivers/cpufreq/powernow-k6.c linux-3.0-rc7-libre/drivers/cpufreq/powernow-k6.c
--- linux-2.6.39-libre/drivers/cpufreq/powernow-k6.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/cpufreq/powernow-k6.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,261 @@
+/*
+ *  This file was based upon code in Powertweak Linux (http://powertweak.sf.net)
+ *  (C) 2000-2003  Dave Jones, Arjan van de Ven, Janne Pänkälä,
+ *                 Dominik Brodowski.
+ *
+ *  Licensed under the terms of the GNU GPL License version 2.
+ *
+ *  BIG FAT DISCLAIMER: Work in progress code. Possibly *dangerous*
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/cpufreq.h>
+#include <linux/ioport.h>
+#include <linux/timex.h>
+#include <linux/io.h>
+
+#include <asm/msr.h>
+
+#define POWERNOW_IOPORT 0xfff0          /* it doesn't matter where, as long
+					   as it is unused */
+
+#define PFX "powernow-k6: "
+static unsigned int                     busfreq;   /* FSB, in 10 kHz */
+static unsigned int                     max_multiplier;
+
+
+/* Clock ratio multiplied by 10 - see table 27 in AMD#23446 */
+static struct cpufreq_frequency_table clock_ratio[] = {
+	{45,  /* 000 -> 4.5x */ 0},
+	{50,  /* 001 -> 5.0x */ 0},
+	{40,  /* 010 -> 4.0x */ 0},
+	{55,  /* 011 -> 5.5x */ 0},
+	{20,  /* 100 -> 2.0x */ 0},
+	{30,  /* 101 -> 3.0x */ 0},
+	{60,  /* 110 -> 6.0x */ 0},
+	{35,  /* 111 -> 3.5x */ 0},
+	{0, CPUFREQ_TABLE_END}
+};
+
+
+/**
+ * powernow_k6_get_cpu_multiplier - returns the current FSB multiplier
+ *
+ *   Returns the current setting of the frequency multiplier. Core clock
+ * speed is frequency of the Front-Side Bus multiplied with this value.
+ */
+static int powernow_k6_get_cpu_multiplier(void)
+{
+	u64 invalue = 0;
+	u32 msrval;
+
+	msrval = POWERNOW_IOPORT + 0x1;
+	wrmsr(MSR_K6_EPMR, msrval, 0); /* enable the PowerNow port */
+	invalue = inl(POWERNOW_IOPORT + 0x8);
+	msrval = POWERNOW_IOPORT + 0x0;
+	wrmsr(MSR_K6_EPMR, msrval, 0); /* disable it again */
+
+	return clock_ratio[(invalue >> 5)&7].index;
+}
+
+
+/**
+ * powernow_k6_set_state - set the PowerNow! multiplier
+ * @best_i: clock_ratio[best_i] is the target multiplier
+ *
+ *   Tries to change the PowerNow! multiplier
+ */
+static void powernow_k6_set_state(unsigned int best_i)
+{
+	unsigned long outvalue = 0, invalue = 0;
+	unsigned long msrval;
+	struct cpufreq_freqs freqs;
+
+	if (clock_ratio[best_i].index > max_multiplier) {
+		printk(KERN_ERR PFX "invalid target frequency\n");
+		return;
+	}
+
+	freqs.old = busfreq * powernow_k6_get_cpu_multiplier();
+	freqs.new = busfreq * clock_ratio[best_i].index;
+	freqs.cpu = 0; /* powernow-k6.c is UP only driver */
+
+	cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
+
+	/* we now need to transform best_i to the BVC format, see AMD#23446 */
+
+	outvalue = (1<<12) | (1<<10) | (1<<9) | (best_i<<5);
+
+	msrval = POWERNOW_IOPORT + 0x1;
+	wrmsr(MSR_K6_EPMR, msrval, 0); /* enable the PowerNow port */
+	invalue = inl(POWERNOW_IOPORT + 0x8);
+	invalue = invalue & 0xf;
+	outvalue = outvalue | invalue;
+	outl(outvalue , (POWERNOW_IOPORT + 0x8));
+	msrval = POWERNOW_IOPORT + 0x0;
+	wrmsr(MSR_K6_EPMR, msrval, 0); /* disable it again */
+
+	cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
+
+	return;
+}
+
+
+/**
+ * powernow_k6_verify - verifies a new CPUfreq policy
+ * @policy: new policy
+ *
+ * Policy must be within lowest and highest possible CPU Frequency,
+ * and at least one possible state must be within min and max.
+ */
+static int powernow_k6_verify(struct cpufreq_policy *policy)
+{
+	return cpufreq_frequency_table_verify(policy, &clock_ratio[0]);
+}
+
+
+/**
+ * powernow_k6_setpolicy - sets a new CPUFreq policy
+ * @policy: new policy
+ * @target_freq: the target frequency
+ * @relation: how that frequency relates to achieved frequency
+ *  (CPUFREQ_RELATION_L or CPUFREQ_RELATION_H)
+ *
+ * sets a new CPUFreq policy
+ */
+static int powernow_k6_target(struct cpufreq_policy *policy,
+			       unsigned int target_freq,
+			       unsigned int relation)
+{
+	unsigned int newstate = 0;
+
+	if (cpufreq_frequency_table_target(policy, &clock_ratio[0],
+				target_freq, relation, &newstate))
+		return -EINVAL;
+
+	powernow_k6_set_state(newstate);
+
+	return 0;
+}
+
+
+static int powernow_k6_cpu_init(struct cpufreq_policy *policy)
+{
+	unsigned int i, f;
+	int result;
+
+	if (policy->cpu != 0)
+		return -ENODEV;
+
+	/* get frequencies */
+	max_multiplier = powernow_k6_get_cpu_multiplier();
+	busfreq = cpu_khz / max_multiplier;
+
+	/* table init */
+	for (i = 0; (clock_ratio[i].frequency != CPUFREQ_TABLE_END); i++) {
+		f = clock_ratio[i].index;
+		if (f > max_multiplier)
+			clock_ratio[i].frequency = CPUFREQ_ENTRY_INVALID;
+		else
+			clock_ratio[i].frequency = busfreq * f;
+	}
+
+	/* cpuinfo and default policy values */
+	policy->cpuinfo.transition_latency = 200000;
+	policy->cur = busfreq * max_multiplier;
+
+	result = cpufreq_frequency_table_cpuinfo(policy, clock_ratio);
+	if (result)
+		return result;
+
+	cpufreq_frequency_table_get_attr(clock_ratio, policy->cpu);
+
+	return 0;
+}
+
+
+static int powernow_k6_cpu_exit(struct cpufreq_policy *policy)
+{
+	unsigned int i;
+	for (i = 0; i < 8; i++) {
+		if (i == max_multiplier)
+			powernow_k6_set_state(i);
+	}
+	cpufreq_frequency_table_put_attr(policy->cpu);
+	return 0;
+}
+
+static unsigned int powernow_k6_get(unsigned int cpu)
+{
+	unsigned int ret;
+	ret = (busfreq * powernow_k6_get_cpu_multiplier());
+	return ret;
+}
+
+static struct freq_attr *powernow_k6_attr[] = {
+	&cpufreq_freq_attr_scaling_available_freqs,
+	NULL,
+};
+
+static struct cpufreq_driver powernow_k6_driver = {
+	.verify		= powernow_k6_verify,
+	.target		= powernow_k6_target,
+	.init		= powernow_k6_cpu_init,
+	.exit		= powernow_k6_cpu_exit,
+	.get		= powernow_k6_get,
+	.name		= "powernow-k6",
+	.owner		= THIS_MODULE,
+	.attr		= powernow_k6_attr,
+};
+
+
+/**
+ * powernow_k6_init - initializes the k6 PowerNow! CPUFreq driver
+ *
+ *   Initializes the K6 PowerNow! support. Returns -ENODEV on unsupported
+ * devices, -EINVAL or -ENOMEM on problems during initiatization, and zero
+ * on success.
+ */
+static int __init powernow_k6_init(void)
+{
+	struct cpuinfo_x86 *c = &cpu_data(0);
+
+	if ((c->x86_vendor != X86_VENDOR_AMD) || (c->x86 != 5) ||
+		((c->x86_model != 12) && (c->x86_model != 13)))
+		return -ENODEV;
+
+	if (!request_region(POWERNOW_IOPORT, 16, "PowerNow!")) {
+		printk(KERN_INFO PFX "PowerNow IOPORT region already used.\n");
+		return -EIO;
+	}
+
+	if (cpufreq_register_driver(&powernow_k6_driver)) {
+		release_region(POWERNOW_IOPORT, 16);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+
+/**
+ * powernow_k6_exit - unregisters AMD K6-2+/3+ PowerNow! support
+ *
+ *   Unregisters AMD K6-2+ / K6-3+ PowerNow! support.
+ */
+static void __exit powernow_k6_exit(void)
+{
+	cpufreq_unregister_driver(&powernow_k6_driver);
+	release_region(POWERNOW_IOPORT, 16);
+}
+
+
+MODULE_AUTHOR("Arjan van de Ven, Dave Jones <davej@redhat.com>, "
+		"Dominik Brodowski <linux@brodo.de>");
+MODULE_DESCRIPTION("PowerNow! driver for AMD K6-2+ / K6-3+ processors.");
+MODULE_LICENSE("GPL");
+
+module_init(powernow_k6_init);
+module_exit(powernow_k6_exit);
diff -druN linux-2.6.39-libre/drivers/cpufreq/powernow-k7.c linux-3.0-rc7-libre/drivers/cpufreq/powernow-k7.c
--- linux-2.6.39-libre/drivers/cpufreq/powernow-k7.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/cpufreq/powernow-k7.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,747 @@
+/*
+ *  AMD K7 Powernow driver.
+ *  (C) 2003 Dave Jones on behalf of SuSE Labs.
+ *  (C) 2003-2004 Dave Jones <davej@redhat.com>
+ *
+ *  Licensed under the terms of the GNU GPL License version 2.
+ *  Based upon datasheets & sample CPUs kindly provided by AMD.
+ *
+ * Errata 5:
+ *  CPU may fail to execute a FID/VID change in presence of interrupt.
+ *  - We cli/sti on stepping A0 CPUs around the FID/VID transition.
+ * Errata 15:
+ *  CPU with half frequency multipliers may hang upon wakeup from disconnect.
+ *  - We disable half multipliers if ACPI is used on A0 stepping CPUs.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/init.h>
+#include <linux/cpufreq.h>
+#include <linux/slab.h>
+#include <linux/string.h>
+#include <linux/dmi.h>
+#include <linux/timex.h>
+#include <linux/io.h>
+
+#include <asm/timer.h>		/* Needed for recalibrate_cpu_khz() */
+#include <asm/msr.h>
+#include <asm/system.h>
+
+#ifdef CONFIG_X86_POWERNOW_K7_ACPI
+#include <linux/acpi.h>
+#include <acpi/processor.h>
+#endif
+
+#include "powernow-k7.h"
+
+#define PFX "powernow: "
+
+
+struct psb_s {
+	u8 signature[10];
+	u8 tableversion;
+	u8 flags;
+	u16 settlingtime;
+	u8 reserved1;
+	u8 numpst;
+};
+
+struct pst_s {
+	u32 cpuid;
+	u8 fsbspeed;
+	u8 maxfid;
+	u8 startvid;
+	u8 numpstates;
+};
+
+#ifdef CONFIG_X86_POWERNOW_K7_ACPI
+union powernow_acpi_control_t {
+	struct {
+		unsigned long fid:5,
+			vid:5,
+			sgtc:20,
+			res1:2;
+	} bits;
+	unsigned long val;
+};
+#endif
+
+/* divide by 1000 to get VCore voltage in V. */
+static const int mobile_vid_table[32] = {
+    2000, 1950, 1900, 1850, 1800, 1750, 1700, 1650,
+    1600, 1550, 1500, 1450, 1400, 1350, 1300, 0,
+    1275, 1250, 1225, 1200, 1175, 1150, 1125, 1100,
+    1075, 1050, 1025, 1000, 975, 950, 925, 0,
+};
+
+/* divide by 10 to get FID. */
+static const int fid_codes[32] = {
+    110, 115, 120, 125, 50, 55, 60, 65,
+    70, 75, 80, 85, 90, 95, 100, 105,
+    30, 190, 40, 200, 130, 135, 140, 210,
+    150, 225, 160, 165, 170, 180, -1, -1,
+};
+
+/* This parameter is used in order to force ACPI instead of legacy method for
+ * configuration purpose.
+ */
+
+static int acpi_force;
+
+static struct cpufreq_frequency_table *powernow_table;
+
+static unsigned int can_scale_bus;
+static unsigned int can_scale_vid;
+static unsigned int minimum_speed = -1;
+static unsigned int maximum_speed;
+static unsigned int number_scales;
+static unsigned int fsb;
+static unsigned int latency;
+static char have_a0;
+
+static int check_fsb(unsigned int fsbspeed)
+{
+	int delta;
+	unsigned int f = fsb / 1000;
+
+	delta = (fsbspeed > f) ? fsbspeed - f : f - fsbspeed;
+	return delta < 5;
+}
+
+static int check_powernow(void)
+{
+	struct cpuinfo_x86 *c = &cpu_data(0);
+	unsigned int maxei, eax, ebx, ecx, edx;
+
+	if ((c->x86_vendor != X86_VENDOR_AMD) || (c->x86 != 6)) {
+#ifdef MODULE
+		printk(KERN_INFO PFX "This module only works with "
+				"AMD K7 CPUs\n");
+#endif
+		return 0;
+	}
+
+	/* Get maximum capabilities */
+	maxei = cpuid_eax(0x80000000);
+	if (maxei < 0x80000007) {	/* Any powernow info ? */
+#ifdef MODULE
+		printk(KERN_INFO PFX "No powernow capabilities detected\n");
+#endif
+		return 0;
+	}
+
+	if ((c->x86_model == 6) && (c->x86_mask == 0)) {
+		printk(KERN_INFO PFX "K7 660[A0] core detected, "
+				"enabling errata workarounds\n");
+		have_a0 = 1;
+	}
+
+	cpuid(0x80000007, &eax, &ebx, &ecx, &edx);
+
+	/* Check we can actually do something before we say anything.*/
+	if (!(edx & (1 << 1 | 1 << 2)))
+		return 0;
+
+	printk(KERN_INFO PFX "PowerNOW! Technology present. Can scale: ");
+
+	if (edx & 1 << 1) {
+		printk("frequency");
+		can_scale_bus = 1;
+	}
+
+	if ((edx & (1 << 1 | 1 << 2)) == 0x6)
+		printk(" and ");
+
+	if (edx & 1 << 2) {
+		printk("voltage");
+		can_scale_vid = 1;
+	}
+
+	printk(".\n");
+	return 1;
+}
+
+#ifdef CONFIG_X86_POWERNOW_K7_ACPI
+static void invalidate_entry(unsigned int entry)
+{
+	powernow_table[entry].frequency = CPUFREQ_ENTRY_INVALID;
+}
+#endif
+
+static int get_ranges(unsigned char *pst)
+{
+	unsigned int j;
+	unsigned int speed;
+	u8 fid, vid;
+
+	powernow_table = kzalloc((sizeof(struct cpufreq_frequency_table) *
+				(number_scales + 1)), GFP_KERNEL);
+	if (!powernow_table)
+		return -ENOMEM;
+
+	for (j = 0 ; j < number_scales; j++) {
+		fid = *pst++;
+
+		powernow_table[j].frequency = (fsb * fid_codes[fid]) / 10;
+		powernow_table[j].index = fid; /* lower 8 bits */
+
+		speed = powernow_table[j].frequency;
+
+		if ((fid_codes[fid] % 10) == 5) {
+#ifdef CONFIG_X86_POWERNOW_K7_ACPI
+			if (have_a0 == 1)
+				invalidate_entry(j);
+#endif
+		}
+
+		if (speed < minimum_speed)
+			minimum_speed = speed;
+		if (speed > maximum_speed)
+			maximum_speed = speed;
+
+		vid = *pst++;
+		powernow_table[j].index |= (vid << 8); /* upper 8 bits */
+
+		pr_debug("   FID: 0x%x (%d.%dx [%dMHz])  "
+			 "VID: 0x%x (%d.%03dV)\n", fid, fid_codes[fid] / 10,
+			 fid_codes[fid] % 10, speed/1000, vid,
+			 mobile_vid_table[vid]/1000,
+			 mobile_vid_table[vid]%1000);
+	}
+	powernow_table[number_scales].frequency = CPUFREQ_TABLE_END;
+	powernow_table[number_scales].index = 0;
+
+	return 0;
+}
+
+
+static void change_FID(int fid)
+{
+	union msr_fidvidctl fidvidctl;
+
+	rdmsrl(MSR_K7_FID_VID_CTL, fidvidctl.val);
+	if (fidvidctl.bits.FID != fid) {
+		fidvidctl.bits.SGTC = latency;
+		fidvidctl.bits.FID = fid;
+		fidvidctl.bits.VIDC = 0;
+		fidvidctl.bits.FIDC = 1;
+		wrmsrl(MSR_K7_FID_VID_CTL, fidvidctl.val);
+	}
+}
+
+
+static void change_VID(int vid)
+{
+	union msr_fidvidctl fidvidctl;
+
+	rdmsrl(MSR_K7_FID_VID_CTL, fidvidctl.val);
+	if (fidvidctl.bits.VID != vid) {
+		fidvidctl.bits.SGTC = latency;
+		fidvidctl.bits.VID = vid;
+		fidvidctl.bits.FIDC = 0;
+		fidvidctl.bits.VIDC = 1;
+		wrmsrl(MSR_K7_FID_VID_CTL, fidvidctl.val);
+	}
+}
+
+
+static void change_speed(unsigned int index)
+{
+	u8 fid, vid;
+	struct cpufreq_freqs freqs;
+	union msr_fidvidstatus fidvidstatus;
+	int cfid;
+
+	/* fid are the lower 8 bits of the index we stored into
+	 * the cpufreq frequency table in powernow_decode_bios,
+	 * vid are the upper 8 bits.
+	 */
+
+	fid = powernow_table[index].index & 0xFF;
+	vid = (powernow_table[index].index & 0xFF00) >> 8;
+
+	freqs.cpu = 0;
+
+	rdmsrl(MSR_K7_FID_VID_STATUS, fidvidstatus.val);
+	cfid = fidvidstatus.bits.CFID;
+	freqs.old = fsb * fid_codes[cfid] / 10;
+
+	freqs.new = powernow_table[index].frequency;
+
+	cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
+
+	/* Now do the magic poking into the MSRs.  */
+
+	if (have_a0 == 1)	/* A0 errata 5 */
+		local_irq_disable();
+
+	if (freqs.old > freqs.new) {
+		/* Going down, so change FID first */
+		change_FID(fid);
+		change_VID(vid);
+	} else {
+		/* Going up, so change VID first */
+		change_VID(vid);
+		change_FID(fid);
+	}
+
+
+	if (have_a0 == 1)
+		local_irq_enable();
+
+	cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
+}
+
+
+#ifdef CONFIG_X86_POWERNOW_K7_ACPI
+
+static struct acpi_processor_performance *acpi_processor_perf;
+
+static int powernow_acpi_init(void)
+{
+	int i;
+	int retval = 0;
+	union powernow_acpi_control_t pc;
+
+	if (acpi_processor_perf != NULL && powernow_table != NULL) {
+		retval = -EINVAL;
+		goto err0;
+	}
+
+	acpi_processor_perf = kzalloc(sizeof(struct acpi_processor_performance),
+				      GFP_KERNEL);
+	if (!acpi_processor_perf) {
+		retval = -ENOMEM;
+		goto err0;
+	}
+
+	if (!zalloc_cpumask_var(&acpi_processor_perf->shared_cpu_map,
+								GFP_KERNEL)) {
+		retval = -ENOMEM;
+		goto err05;
+	}
+
+	if (acpi_processor_register_performance(acpi_processor_perf, 0)) {
+		retval = -EIO;
+		goto err1;
+	}
+
+	if (acpi_processor_perf->control_register.space_id !=
+			ACPI_ADR_SPACE_FIXED_HARDWARE) {
+		retval = -ENODEV;
+		goto err2;
+	}
+
+	if (acpi_processor_perf->status_register.space_id !=
+			ACPI_ADR_SPACE_FIXED_HARDWARE) {
+		retval = -ENODEV;
+		goto err2;
+	}
+
+	number_scales = acpi_processor_perf->state_count;
+
+	if (number_scales < 2) {
+		retval = -ENODEV;
+		goto err2;
+	}
+
+	powernow_table = kzalloc((sizeof(struct cpufreq_frequency_table) *
+				(number_scales + 1)), GFP_KERNEL);
+	if (!powernow_table) {
+		retval = -ENOMEM;
+		goto err2;
+	}
+
+	pc.val = (unsigned long) acpi_processor_perf->states[0].control;
+	for (i = 0; i < number_scales; i++) {
+		u8 fid, vid;
+		struct acpi_processor_px *state =
+			&acpi_processor_perf->states[i];
+		unsigned int speed, speed_mhz;
+
+		pc.val = (unsigned long) state->control;
+		pr_debug("acpi:  P%d: %d MHz %d mW %d uS control %08x SGTC %d\n",
+			 i,
+			 (u32) state->core_frequency,
+			 (u32) state->power,
+			 (u32) state->transition_latency,
+			 (u32) state->control,
+			 pc.bits.sgtc);
+
+		vid = pc.bits.vid;
+		fid = pc.bits.fid;
+
+		powernow_table[i].frequency = fsb * fid_codes[fid] / 10;
+		powernow_table[i].index = fid; /* lower 8 bits */
+		powernow_table[i].index |= (vid << 8); /* upper 8 bits */
+
+		speed = powernow_table[i].frequency;
+		speed_mhz = speed / 1000;
+
+		/* processor_perflib will multiply the MHz value by 1000 to
+		 * get a KHz value (e.g. 1266000). However, powernow-k7 works
+		 * with true KHz values (e.g. 1266768). To ensure that all
+		 * powernow frequencies are available, we must ensure that
+		 * ACPI doesn't restrict them, so we round up the MHz value
+		 * to ensure that perflib's computed KHz value is greater than
+		 * or equal to powernow's KHz value.
+		 */
+		if (speed % 1000 > 0)
+			speed_mhz++;
+
+		if ((fid_codes[fid] % 10) == 5) {
+			if (have_a0 == 1)
+				invalidate_entry(i);
+		}
+
+		pr_debug("   FID: 0x%x (%d.%dx [%dMHz])  "
+			 "VID: 0x%x (%d.%03dV)\n", fid, fid_codes[fid] / 10,
+			 fid_codes[fid] % 10, speed_mhz, vid,
+			 mobile_vid_table[vid]/1000,
+			 mobile_vid_table[vid]%1000);
+
+		if (state->core_frequency != speed_mhz) {
+			state->core_frequency = speed_mhz;
+			pr_debug("   Corrected ACPI frequency to %d\n",
+				speed_mhz);
+		}
+
+		if (latency < pc.bits.sgtc)
+			latency = pc.bits.sgtc;
+
+		if (speed < minimum_speed)
+			minimum_speed = speed;
+		if (speed > maximum_speed)
+			maximum_speed = speed;
+	}
+
+	powernow_table[i].frequency = CPUFREQ_TABLE_END;
+	powernow_table[i].index = 0;
+
+	/* notify BIOS that we exist */
+	acpi_processor_notify_smm(THIS_MODULE);
+
+	return 0;
+
+err2:
+	acpi_processor_unregister_performance(acpi_processor_perf, 0);
+err1:
+	free_cpumask_var(acpi_processor_perf->shared_cpu_map);
+err05:
+	kfree(acpi_processor_perf);
+err0:
+	printk(KERN_WARNING PFX "ACPI perflib can not be used on "
+			"this platform\n");
+	acpi_processor_perf = NULL;
+	return retval;
+}
+#else
+static int powernow_acpi_init(void)
+{
+	printk(KERN_INFO PFX "no support for ACPI processor found."
+	       "  Please recompile your kernel with ACPI processor\n");
+	return -EINVAL;
+}
+#endif
+
+static void print_pst_entry(struct pst_s *pst, unsigned int j)
+{
+	pr_debug("PST:%d (@%p)\n", j, pst);
+	pr_debug(" cpuid: 0x%x  fsb: %d  maxFID: 0x%x  startvid: 0x%x\n",
+		pst->cpuid, pst->fsbspeed, pst->maxfid, pst->startvid);
+}
+
+static int powernow_decode_bios(int maxfid, int startvid)
+{
+	struct psb_s *psb;
+	struct pst_s *pst;
+	unsigned int i, j;
+	unsigned char *p;
+	unsigned int etuple;
+	unsigned int ret;
+
+	etuple = cpuid_eax(0x80000001);
+
+	for (i = 0xC0000; i < 0xffff0 ; i += 16) {
+
+		p = phys_to_virt(i);
+
+		if (memcmp(p, "AMDK7PNOW!",  10) == 0) {
+			pr_debug("Found PSB header at %p\n", p);
+			psb = (struct psb_s *) p;
+			pr_debug("Table version: 0x%x\n", psb->tableversion);
+			if (psb->tableversion != 0x12) {
+				printk(KERN_INFO PFX "Sorry, only v1.2 tables"
+						" supported right now\n");
+				return -ENODEV;
+			}
+
+			pr_debug("Flags: 0x%x\n", psb->flags);
+			if ((psb->flags & 1) == 0)
+				pr_debug("Mobile voltage regulator\n");
+			else
+				pr_debug("Desktop voltage regulator\n");
+
+			latency = psb->settlingtime;
+			if (latency < 100) {
+				printk(KERN_INFO PFX "BIOS set settling time "
+						"to %d microseconds. "
+						"Should be at least 100. "
+						"Correcting.\n", latency);
+				latency = 100;
+			}
+			pr_debug("Settling Time: %d microseconds.\n",
+					psb->settlingtime);
+			pr_debug("Has %d PST tables. (Only dumping ones "
+					"relevant to this CPU).\n",
+					psb->numpst);
+
+			p += sizeof(struct psb_s);
+
+			pst = (struct pst_s *) p;
+
+			for (j = 0; j < psb->numpst; j++) {
+				pst = (struct pst_s *) p;
+				number_scales = pst->numpstates;
+
+				if ((etuple == pst->cpuid) &&
+				    check_fsb(pst->fsbspeed) &&
+				    (maxfid == pst->maxfid) &&
+				    (startvid == pst->startvid)) {
+					print_pst_entry(pst, j);
+					p = (char *)pst + sizeof(struct pst_s);
+					ret = get_ranges(p);
+					return ret;
+				} else {
+					unsigned int k;
+					p = (char *)pst + sizeof(struct pst_s);
+					for (k = 0; k < number_scales; k++)
+						p += 2;
+				}
+			}
+			printk(KERN_INFO PFX "No PST tables match this cpuid "
+					"(0x%x)\n", etuple);
+			printk(KERN_INFO PFX "This is indicative of a broken "
+					"BIOS.\n");
+
+			return -EINVAL;
+		}
+		p++;
+	}
+
+	return -ENODEV;
+}
+
+
+static int powernow_target(struct cpufreq_policy *policy,
+			    unsigned int target_freq,
+			    unsigned int relation)
+{
+	unsigned int newstate;
+
+	if (cpufreq_frequency_table_target(policy, powernow_table, target_freq,
+				relation, &newstate))
+		return -EINVAL;
+
+	change_speed(newstate);
+
+	return 0;
+}
+
+
+static int powernow_verify(struct cpufreq_policy *policy)
+{
+	return cpufreq_frequency_table_verify(policy, powernow_table);
+}
+
+/*
+ * We use the fact that the bus frequency is somehow
+ * a multiple of 100000/3 khz, then we compute sgtc according
+ * to this multiple.
+ * That way, we match more how AMD thinks all of that work.
+ * We will then get the same kind of behaviour already tested under
+ * the "well-known" other OS.
+ */
+static int __cpuinit fixup_sgtc(void)
+{
+	unsigned int sgtc;
+	unsigned int m;
+
+	m = fsb / 3333;
+	if ((m % 10) >= 5)
+		m += 5;
+
+	m /= 10;
+
+	sgtc = 100 * m * latency;
+	sgtc = sgtc / 3;
+	if (sgtc > 0xfffff) {
+		printk(KERN_WARNING PFX "SGTC too large %d\n", sgtc);
+		sgtc = 0xfffff;
+	}
+	return sgtc;
+}
+
+static unsigned int powernow_get(unsigned int cpu)
+{
+	union msr_fidvidstatus fidvidstatus;
+	unsigned int cfid;
+
+	if (cpu)
+		return 0;
+	rdmsrl(MSR_K7_FID_VID_STATUS, fidvidstatus.val);
+	cfid = fidvidstatus.bits.CFID;
+
+	return fsb * fid_codes[cfid] / 10;
+}
+
+
+static int __cpuinit acer_cpufreq_pst(const struct dmi_system_id *d)
+{
+	printk(KERN_WARNING PFX
+		"%s laptop with broken PST tables in BIOS detected.\n",
+		d->ident);
+	printk(KERN_WARNING PFX
+		"You need to downgrade to 3A21 (09/09/2002), or try a newer "
+		"BIOS than 3A71 (01/20/2003)\n");
+	printk(KERN_WARNING PFX
+		"cpufreq scaling has been disabled as a result of this.\n");
+	return 0;
+}
+
+/*
+ * Some Athlon laptops have really fucked PST tables.
+ * A BIOS update is all that can save them.
+ * Mention this, and disable cpufreq.
+ */
+static struct dmi_system_id __cpuinitdata powernow_dmi_table[] = {
+	{
+		.callback = acer_cpufreq_pst,
+		.ident = "Acer Aspire",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Insyde Software"),
+			DMI_MATCH(DMI_BIOS_VERSION, "3A71"),
+		},
+	},
+	{ }
+};
+
+static int __cpuinit powernow_cpu_init(struct cpufreq_policy *policy)
+{
+	union msr_fidvidstatus fidvidstatus;
+	int result;
+
+	if (policy->cpu != 0)
+		return -ENODEV;
+
+	rdmsrl(MSR_K7_FID_VID_STATUS, fidvidstatus.val);
+
+	recalibrate_cpu_khz();
+
+	fsb = (10 * cpu_khz) / fid_codes[fidvidstatus.bits.CFID];
+	if (!fsb) {
+		printk(KERN_WARNING PFX "can not determine bus frequency\n");
+		return -EINVAL;
+	}
+	pr_debug("FSB: %3dMHz\n", fsb/1000);
+
+	if (dmi_check_system(powernow_dmi_table) || acpi_force) {
+		printk(KERN_INFO PFX "PSB/PST known to be broken.  "
+				"Trying ACPI instead\n");
+		result = powernow_acpi_init();
+	} else {
+		result = powernow_decode_bios(fidvidstatus.bits.MFID,
+				fidvidstatus.bits.SVID);
+		if (result) {
+			printk(KERN_INFO PFX "Trying ACPI perflib\n");
+			maximum_speed = 0;
+			minimum_speed = -1;
+			latency = 0;
+			result = powernow_acpi_init();
+			if (result) {
+				printk(KERN_INFO PFX
+					"ACPI and legacy methods failed\n");
+			}
+		} else {
+			/* SGTC use the bus clock as timer */
+			latency = fixup_sgtc();
+			printk(KERN_INFO PFX "SGTC: %d\n", latency);
+		}
+	}
+
+	if (result)
+		return result;
+
+	printk(KERN_INFO PFX "Minimum speed %d MHz. Maximum speed %d MHz.\n",
+				minimum_speed/1000, maximum_speed/1000);
+
+	policy->cpuinfo.transition_latency =
+		cpufreq_scale(2000000UL, fsb, latency);
+
+	policy->cur = powernow_get(0);
+
+	cpufreq_frequency_table_get_attr(powernow_table, policy->cpu);
+
+	return cpufreq_frequency_table_cpuinfo(policy, powernow_table);
+}
+
+static int powernow_cpu_exit(struct cpufreq_policy *policy)
+{
+	cpufreq_frequency_table_put_attr(policy->cpu);
+
+#ifdef CONFIG_X86_POWERNOW_K7_ACPI
+	if (acpi_processor_perf) {
+		acpi_processor_unregister_performance(acpi_processor_perf, 0);
+		free_cpumask_var(acpi_processor_perf->shared_cpu_map);
+		kfree(acpi_processor_perf);
+	}
+#endif
+
+	kfree(powernow_table);
+	return 0;
+}
+
+static struct freq_attr *powernow_table_attr[] = {
+	&cpufreq_freq_attr_scaling_available_freqs,
+	NULL,
+};
+
+static struct cpufreq_driver powernow_driver = {
+	.verify		= powernow_verify,
+	.target		= powernow_target,
+	.get		= powernow_get,
+#ifdef CONFIG_X86_POWERNOW_K7_ACPI
+	.bios_limit	= acpi_processor_get_bios_limit,
+#endif
+	.init		= powernow_cpu_init,
+	.exit		= powernow_cpu_exit,
+	.name		= "powernow-k7",
+	.owner		= THIS_MODULE,
+	.attr		= powernow_table_attr,
+};
+
+static int __init powernow_init(void)
+{
+	if (check_powernow() == 0)
+		return -ENODEV;
+	return cpufreq_register_driver(&powernow_driver);
+}
+
+
+static void __exit powernow_exit(void)
+{
+	cpufreq_unregister_driver(&powernow_driver);
+}
+
+module_param(acpi_force,  int, 0444);
+MODULE_PARM_DESC(acpi_force, "Force ACPI to be used.");
+
+MODULE_AUTHOR("Dave Jones <davej@redhat.com>");
+MODULE_DESCRIPTION("Powernow driver for AMD K7 processors.");
+MODULE_LICENSE("GPL");
+
+late_initcall(powernow_init);
+module_exit(powernow_exit);
+
diff -druN linux-2.6.39-libre/drivers/cpufreq/powernow-k7.h linux-3.0-rc7-libre/drivers/cpufreq/powernow-k7.h
--- linux-2.6.39-libre/drivers/cpufreq/powernow-k7.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/cpufreq/powernow-k7.h	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,43 @@
+/*
+ *  (C) 2003 Dave Jones.
+ *
+ *  Licensed under the terms of the GNU GPL License version 2.
+ *
+ *  AMD-specific information
+ *
+ */
+
+union msr_fidvidctl {
+	struct {
+		unsigned FID:5,			// 4:0
+		reserved1:3,	// 7:5
+		VID:5,			// 12:8
+		reserved2:3,	// 15:13
+		FIDC:1,			// 16
+		VIDC:1,			// 17
+		reserved3:2,	// 19:18
+		FIDCHGRATIO:1,	// 20
+		reserved4:11,	// 31-21
+		SGTC:20,		// 32:51
+		reserved5:12;	// 63:52
+	} bits;
+	unsigned long long val;
+};
+
+union msr_fidvidstatus {
+	struct {
+		unsigned CFID:5,			// 4:0
+		reserved1:3,	// 7:5
+		SFID:5,			// 12:8
+		reserved2:3,	// 15:13
+		MFID:5,			// 20:16
+		reserved3:11,	// 31:21
+		CVID:5,			// 36:32
+		reserved4:3,	// 39:37
+		SVID:5,			// 44:40
+		reserved5:3,	// 47:45
+		MVID:5,			// 52:48
+		reserved6:11;	// 63:53
+	} bits;
+	unsigned long long val;
+};
diff -druN linux-2.6.39-libre/drivers/cpufreq/powernow-k8.c linux-3.0-rc7-libre/drivers/cpufreq/powernow-k8.c
--- linux-2.6.39-libre/drivers/cpufreq/powernow-k8.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/cpufreq/powernow-k8.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,1611 @@
+/*
+ *   (c) 2003-2010 Advanced Micro Devices, Inc.
+ *  Your use of this code is subject to the terms and conditions of the
+ *  GNU general public license version 2. See "COPYING" or
+ *  http://www.gnu.org/licenses/gpl.html
+ *
+ *  Support : mark.langsdorf@amd.com
+ *
+ *  Based on the powernow-k7.c module written by Dave Jones.
+ *  (C) 2003 Dave Jones on behalf of SuSE Labs
+ *  (C) 2004 Dominik Brodowski <linux@brodo.de>
+ *  (C) 2004 Pavel Machek <pavel@ucw.cz>
+ *  Licensed under the terms of the GNU GPL License version 2.
+ *  Based upon datasheets & sample CPUs kindly provided by AMD.
+ *
+ *  Valuable input gratefully received from Dave Jones, Pavel Machek,
+ *  Dominik Brodowski, Jacob Shin, and others.
+ *  Originally developed by Paul Devriendt.
+ *  Processor information obtained from Chapter 9 (Power and Thermal Management)
+ *  of the "BIOS and Kernel Developer's Guide for the AMD Athlon 64 and AMD
+ *  Opteron Processors" available for download from www.amd.com
+ *
+ *  Tables for specific CPUs can be inferred from
+ *     http://www.amd.com/us-en/assets/content_type/white_papers_and_tech_docs/30430.pdf
+ */
+
+#include <linux/kernel.h>
+#include <linux/smp.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/cpufreq.h>
+#include <linux/slab.h>
+#include <linux/string.h>
+#include <linux/cpumask.h>
+#include <linux/sched.h>	/* for current / set_cpus_allowed() */
+#include <linux/io.h>
+#include <linux/delay.h>
+
+#include <asm/msr.h>
+
+#include <linux/acpi.h>
+#include <linux/mutex.h>
+#include <acpi/processor.h>
+
+#define PFX "powernow-k8: "
+#define VERSION "version 2.20.00"
+#include "powernow-k8.h"
+#include "mperf.h"
+
+/* serialize freq changes  */
+static DEFINE_MUTEX(fidvid_mutex);
+
+static DEFINE_PER_CPU(struct powernow_k8_data *, powernow_data);
+
+static int cpu_family = CPU_OPTERON;
+
+/* core performance boost */
+static bool cpb_capable, cpb_enabled;
+static struct msr __percpu *msrs;
+
+static struct cpufreq_driver cpufreq_amd64_driver;
+
+#ifndef CONFIG_SMP
+static inline const struct cpumask *cpu_core_mask(int cpu)
+{
+	return cpumask_of(0);
+}
+#endif
+
+/* Return a frequency in MHz, given an input fid */
+static u32 find_freq_from_fid(u32 fid)
+{
+	return 800 + (fid * 100);
+}
+
+/* Return a frequency in KHz, given an input fid */
+static u32 find_khz_freq_from_fid(u32 fid)
+{
+	return 1000 * find_freq_from_fid(fid);
+}
+
+static u32 find_khz_freq_from_pstate(struct cpufreq_frequency_table *data,
+		u32 pstate)
+{
+	return data[pstate].frequency;
+}
+
+/* Return the vco fid for an input fid
+ *
+ * Each "low" fid has corresponding "high" fid, and you can get to "low" fids
+ * only from corresponding high fids. This returns "high" fid corresponding to
+ * "low" one.
+ */
+static u32 convert_fid_to_vco_fid(u32 fid)
+{
+	if (fid < HI_FID_TABLE_BOTTOM)
+		return 8 + (2 * fid);
+	else
+		return fid;
+}
+
+/*
+ * Return 1 if the pending bit is set. Unless we just instructed the processor
+ * to transition to a new state, seeing this bit set is really bad news.
+ */
+static int pending_bit_stuck(void)
+{
+	u32 lo, hi;
+
+	if (cpu_family == CPU_HW_PSTATE)
+		return 0;
+
+	rdmsr(MSR_FIDVID_STATUS, lo, hi);
+	return lo & MSR_S_LO_CHANGE_PENDING ? 1 : 0;
+}
+
+/*
+ * Update the global current fid / vid values from the status msr.
+ * Returns 1 on error.
+ */
+static int query_current_values_with_pending_wait(struct powernow_k8_data *data)
+{
+	u32 lo, hi;
+	u32 i = 0;
+
+	if (cpu_family == CPU_HW_PSTATE) {
+		rdmsr(MSR_PSTATE_STATUS, lo, hi);
+		i = lo & HW_PSTATE_MASK;
+		data->currpstate = i;
+
+		/*
+		 * a workaround for family 11h erratum 311 might cause
+		 * an "out-of-range Pstate if the core is in Pstate-0
+		 */
+		if ((boot_cpu_data.x86 == 0x11) && (i >= data->numps))
+			data->currpstate = HW_PSTATE_0;
+
+		return 0;
+	}
+	do {
+		if (i++ > 10000) {
+			pr_debug("detected change pending stuck\n");
+			return 1;
+		}
+		rdmsr(MSR_FIDVID_STATUS, lo, hi);
+	} while (lo & MSR_S_LO_CHANGE_PENDING);
+
+	data->currvid = hi & MSR_S_HI_CURRENT_VID;
+	data->currfid = lo & MSR_S_LO_CURRENT_FID;
+
+	return 0;
+}
+
+/* the isochronous relief time */
+static void count_off_irt(struct powernow_k8_data *data)
+{
+	udelay((1 << data->irt) * 10);
+	return;
+}
+
+/* the voltage stabilization time */
+static void count_off_vst(struct powernow_k8_data *data)
+{
+	udelay(data->vstable * VST_UNITS_20US);
+	return;
+}
+
+/* need to init the control msr to a safe value (for each cpu) */
+static void fidvid_msr_init(void)
+{
+	u32 lo, hi;
+	u8 fid, vid;
+
+	rdmsr(MSR_FIDVID_STATUS, lo, hi);
+	vid = hi & MSR_S_HI_CURRENT_VID;
+	fid = lo & MSR_S_LO_CURRENT_FID;
+	lo = fid | (vid << MSR_C_LO_VID_SHIFT);
+	hi = MSR_C_HI_STP_GNT_BENIGN;
+	pr_debug("cpu%d, init lo 0x%x, hi 0x%x\n", smp_processor_id(), lo, hi);
+	wrmsr(MSR_FIDVID_CTL, lo, hi);
+}
+
+/* write the new fid value along with the other control fields to the msr */
+static int write_new_fid(struct powernow_k8_data *data, u32 fid)
+{
+	u32 lo;
+	u32 savevid = data->currvid;
+	u32 i = 0;
+
+	if ((fid & INVALID_FID_MASK) || (data->currvid & INVALID_VID_MASK)) {
+		printk(KERN_ERR PFX "internal error - overflow on fid write\n");
+		return 1;
+	}
+
+	lo = fid;
+	lo |= (data->currvid << MSR_C_LO_VID_SHIFT);
+	lo |= MSR_C_LO_INIT_FID_VID;
+
+	pr_debug("writing fid 0x%x, lo 0x%x, hi 0x%x\n",
+		fid, lo, data->plllock * PLL_LOCK_CONVERSION);
+
+	do {
+		wrmsr(MSR_FIDVID_CTL, lo, data->plllock * PLL_LOCK_CONVERSION);
+		if (i++ > 100) {
+			printk(KERN_ERR PFX
+				"Hardware error - pending bit very stuck - "
+				"no further pstate changes possible\n");
+			return 1;
+		}
+	} while (query_current_values_with_pending_wait(data));
+
+	count_off_irt(data);
+
+	if (savevid != data->currvid) {
+		printk(KERN_ERR PFX
+			"vid change on fid trans, old 0x%x, new 0x%x\n",
+			savevid, data->currvid);
+		return 1;
+	}
+
+	if (fid != data->currfid) {
+		printk(KERN_ERR PFX
+			"fid trans failed, fid 0x%x, curr 0x%x\n", fid,
+			data->currfid);
+		return 1;
+	}
+
+	return 0;
+}
+
+/* Write a new vid to the hardware */
+static int write_new_vid(struct powernow_k8_data *data, u32 vid)
+{
+	u32 lo;
+	u32 savefid = data->currfid;
+	int i = 0;
+
+	if ((data->currfid & INVALID_FID_MASK) || (vid & INVALID_VID_MASK)) {
+		printk(KERN_ERR PFX "internal error - overflow on vid write\n");
+		return 1;
+	}
+
+	lo = data->currfid;
+	lo |= (vid << MSR_C_LO_VID_SHIFT);
+	lo |= MSR_C_LO_INIT_FID_VID;
+
+	pr_debug("writing vid 0x%x, lo 0x%x, hi 0x%x\n",
+		vid, lo, STOP_GRANT_5NS);
+
+	do {
+		wrmsr(MSR_FIDVID_CTL, lo, STOP_GRANT_5NS);
+		if (i++ > 100) {
+			printk(KERN_ERR PFX "internal error - pending bit "
+					"very stuck - no further pstate "
+					"changes possible\n");
+			return 1;
+		}
+	} while (query_current_values_with_pending_wait(data));
+
+	if (savefid != data->currfid) {
+		printk(KERN_ERR PFX "fid changed on vid trans, old "
+			"0x%x new 0x%x\n",
+		       savefid, data->currfid);
+		return 1;
+	}
+
+	if (vid != data->currvid) {
+		printk(KERN_ERR PFX "vid trans failed, vid 0x%x, "
+				"curr 0x%x\n",
+				vid, data->currvid);
+		return 1;
+	}
+
+	return 0;
+}
+
+/*
+ * Reduce the vid by the max of step or reqvid.
+ * Decreasing vid codes represent increasing voltages:
+ * vid of 0 is 1.550V, vid of 0x1e is 0.800V, vid of VID_OFF is off.
+ */
+static int decrease_vid_code_by_step(struct powernow_k8_data *data,
+		u32 reqvid, u32 step)
+{
+	if ((data->currvid - reqvid) > step)
+		reqvid = data->currvid - step;
+
+	if (write_new_vid(data, reqvid))
+		return 1;
+
+	count_off_vst(data);
+
+	return 0;
+}
+
+/* Change hardware pstate by single MSR write */
+static int transition_pstate(struct powernow_k8_data *data, u32 pstate)
+{
+	wrmsr(MSR_PSTATE_CTRL, pstate, 0);
+	data->currpstate = pstate;
+	return 0;
+}
+
+/* Change Opteron/Athlon64 fid and vid, by the 3 phases. */
+static int transition_fid_vid(struct powernow_k8_data *data,
+		u32 reqfid, u32 reqvid)
+{
+	if (core_voltage_pre_transition(data, reqvid, reqfid))
+		return 1;
+
+	if (core_frequency_transition(data, reqfid))
+		return 1;
+
+	if (core_voltage_post_transition(data, reqvid))
+		return 1;
+
+	if (query_current_values_with_pending_wait(data))
+		return 1;
+
+	if ((reqfid != data->currfid) || (reqvid != data->currvid)) {
+		printk(KERN_ERR PFX "failed (cpu%d): req 0x%x 0x%x, "
+				"curr 0x%x 0x%x\n",
+				smp_processor_id(),
+				reqfid, reqvid, data->currfid, data->currvid);
+		return 1;
+	}
+
+	pr_debug("transitioned (cpu%d): new fid 0x%x, vid 0x%x\n",
+		smp_processor_id(), data->currfid, data->currvid);
+
+	return 0;
+}
+
+/* Phase 1 - core voltage transition ... setup voltage */
+static int core_voltage_pre_transition(struct powernow_k8_data *data,
+		u32 reqvid, u32 reqfid)
+{
+	u32 rvosteps = data->rvo;
+	u32 savefid = data->currfid;
+	u32 maxvid, lo, rvomult = 1;
+
+	pr_debug("ph1 (cpu%d): start, currfid 0x%x, currvid 0x%x, "
+		"reqvid 0x%x, rvo 0x%x\n",
+		smp_processor_id(),
+		data->currfid, data->currvid, reqvid, data->rvo);
+
+	if ((savefid < LO_FID_TABLE_TOP) && (reqfid < LO_FID_TABLE_TOP))
+		rvomult = 2;
+	rvosteps *= rvomult;
+	rdmsr(MSR_FIDVID_STATUS, lo, maxvid);
+	maxvid = 0x1f & (maxvid >> 16);
+	pr_debug("ph1 maxvid=0x%x\n", maxvid);
+	if (reqvid < maxvid) /* lower numbers are higher voltages */
+		reqvid = maxvid;
+
+	while (data->currvid > reqvid) {
+		pr_debug("ph1: curr 0x%x, req vid 0x%x\n",
+			data->currvid, reqvid);
+		if (decrease_vid_code_by_step(data, reqvid, data->vidmvs))
+			return 1;
+	}
+
+	while ((rvosteps > 0) &&
+			((rvomult * data->rvo + data->currvid) > reqvid)) {
+		if (data->currvid == maxvid) {
+			rvosteps = 0;
+		} else {
+			pr_debug("ph1: changing vid for rvo, req 0x%x\n",
+				data->currvid - 1);
+			if (decrease_vid_code_by_step(data, data->currvid-1, 1))
+				return 1;
+			rvosteps--;
+		}
+	}
+
+	if (query_current_values_with_pending_wait(data))
+		return 1;
+
+	if (savefid != data->currfid) {
+		printk(KERN_ERR PFX "ph1 err, currfid changed 0x%x\n",
+				data->currfid);
+		return 1;
+	}
+
+	pr_debug("ph1 complete, currfid 0x%x, currvid 0x%x\n",
+		data->currfid, data->currvid);
+
+	return 0;
+}
+
+/* Phase 2 - core frequency transition */
+static int core_frequency_transition(struct powernow_k8_data *data, u32 reqfid)
+{
+	u32 vcoreqfid, vcocurrfid, vcofiddiff;
+	u32 fid_interval, savevid = data->currvid;
+
+	if (data->currfid == reqfid) {
+		printk(KERN_ERR PFX "ph2 null fid transition 0x%x\n",
+				data->currfid);
+		return 0;
+	}
+
+	pr_debug("ph2 (cpu%d): starting, currfid 0x%x, currvid 0x%x, "
+		"reqfid 0x%x\n",
+		smp_processor_id(),
+		data->currfid, data->currvid, reqfid);
+
+	vcoreqfid = convert_fid_to_vco_fid(reqfid);
+	vcocurrfid = convert_fid_to_vco_fid(data->currfid);
+	vcofiddiff = vcocurrfid > vcoreqfid ? vcocurrfid - vcoreqfid
+	    : vcoreqfid - vcocurrfid;
+
+	if ((reqfid <= LO_FID_TABLE_TOP) && (data->currfid <= LO_FID_TABLE_TOP))
+		vcofiddiff = 0;
+
+	while (vcofiddiff > 2) {
+		(data->currfid & 1) ? (fid_interval = 1) : (fid_interval = 2);
+
+		if (reqfid > data->currfid) {
+			if (data->currfid > LO_FID_TABLE_TOP) {
+				if (write_new_fid(data,
+						data->currfid + fid_interval))
+					return 1;
+			} else {
+				if (write_new_fid
+				    (data,
+				     2 + convert_fid_to_vco_fid(data->currfid)))
+					return 1;
+			}
+		} else {
+			if (write_new_fid(data, data->currfid - fid_interval))
+				return 1;
+		}
+
+		vcocurrfid = convert_fid_to_vco_fid(data->currfid);
+		vcofiddiff = vcocurrfid > vcoreqfid ? vcocurrfid - vcoreqfid
+		    : vcoreqfid - vcocurrfid;
+	}
+
+	if (write_new_fid(data, reqfid))
+		return 1;
+
+	if (query_current_values_with_pending_wait(data))
+		return 1;
+
+	if (data->currfid != reqfid) {
+		printk(KERN_ERR PFX
+			"ph2: mismatch, failed fid transition, "
+			"curr 0x%x, req 0x%x\n",
+			data->currfid, reqfid);
+		return 1;
+	}
+
+	if (savevid != data->currvid) {
+		printk(KERN_ERR PFX "ph2: vid changed, save 0x%x, curr 0x%x\n",
+			savevid, data->currvid);
+		return 1;
+	}
+
+	pr_debug("ph2 complete, currfid 0x%x, currvid 0x%x\n",
+		data->currfid, data->currvid);
+
+	return 0;
+}
+
+/* Phase 3 - core voltage transition flow ... jump to the final vid. */
+static int core_voltage_post_transition(struct powernow_k8_data *data,
+		u32 reqvid)
+{
+	u32 savefid = data->currfid;
+	u32 savereqvid = reqvid;
+
+	pr_debug("ph3 (cpu%d): starting, currfid 0x%x, currvid 0x%x\n",
+		smp_processor_id(),
+		data->currfid, data->currvid);
+
+	if (reqvid != data->currvid) {
+		if (write_new_vid(data, reqvid))
+			return 1;
+
+		if (savefid != data->currfid) {
+			printk(KERN_ERR PFX
+			       "ph3: bad fid change, save 0x%x, curr 0x%x\n",
+			       savefid, data->currfid);
+			return 1;
+		}
+
+		if (data->currvid != reqvid) {
+			printk(KERN_ERR PFX
+			       "ph3: failed vid transition\n, "
+			       "req 0x%x, curr 0x%x",
+			       reqvid, data->currvid);
+			return 1;
+		}
+	}
+
+	if (query_current_values_with_pending_wait(data))
+		return 1;
+
+	if (savereqvid != data->currvid) {
+		pr_debug("ph3 failed, currvid 0x%x\n", data->currvid);
+		return 1;
+	}
+
+	if (savefid != data->currfid) {
+		pr_debug("ph3 failed, currfid changed 0x%x\n",
+			data->currfid);
+		return 1;
+	}
+
+	pr_debug("ph3 complete, currfid 0x%x, currvid 0x%x\n",
+		data->currfid, data->currvid);
+
+	return 0;
+}
+
+static void check_supported_cpu(void *_rc)
+{
+	u32 eax, ebx, ecx, edx;
+	int *rc = _rc;
+
+	*rc = -ENODEV;
+
+	if (__this_cpu_read(cpu_info.x86_vendor) != X86_VENDOR_AMD)
+		return;
+
+	eax = cpuid_eax(CPUID_PROCESSOR_SIGNATURE);
+	if (((eax & CPUID_XFAM) != CPUID_XFAM_K8) &&
+	    ((eax & CPUID_XFAM) < CPUID_XFAM_10H))
+		return;
+
+	if ((eax & CPUID_XFAM) == CPUID_XFAM_K8) {
+		if (((eax & CPUID_USE_XFAM_XMOD) != CPUID_USE_XFAM_XMOD) ||
+		    ((eax & CPUID_XMOD) > CPUID_XMOD_REV_MASK)) {
+			printk(KERN_INFO PFX
+				"Processor cpuid %x not supported\n", eax);
+			return;
+		}
+
+		eax = cpuid_eax(CPUID_GET_MAX_CAPABILITIES);
+		if (eax < CPUID_FREQ_VOLT_CAPABILITIES) {
+			printk(KERN_INFO PFX
+			       "No frequency change capabilities detected\n");
+			return;
+		}
+
+		cpuid(CPUID_FREQ_VOLT_CAPABILITIES, &eax, &ebx, &ecx, &edx);
+		if ((edx & P_STATE_TRANSITION_CAPABLE)
+			!= P_STATE_TRANSITION_CAPABLE) {
+			printk(KERN_INFO PFX
+				"Power state transitions not supported\n");
+			return;
+		}
+	} else { /* must be a HW Pstate capable processor */
+		cpuid(CPUID_FREQ_VOLT_CAPABILITIES, &eax, &ebx, &ecx, &edx);
+		if ((edx & USE_HW_PSTATE) == USE_HW_PSTATE)
+			cpu_family = CPU_HW_PSTATE;
+		else
+			return;
+	}
+
+	*rc = 0;
+}
+
+static int check_pst_table(struct powernow_k8_data *data, struct pst_s *pst,
+		u8 maxvid)
+{
+	unsigned int j;
+	u8 lastfid = 0xff;
+
+	for (j = 0; j < data->numps; j++) {
+		if (pst[j].vid > LEAST_VID) {
+			printk(KERN_ERR FW_BUG PFX "vid %d invalid : 0x%x\n",
+			       j, pst[j].vid);
+			return -EINVAL;
+		}
+		if (pst[j].vid < data->rvo) {
+			/* vid + rvo >= 0 */
+			printk(KERN_ERR FW_BUG PFX "0 vid exceeded with pstate"
+			       " %d\n", j);
+			return -ENODEV;
+		}
+		if (pst[j].vid < maxvid + data->rvo) {
+			/* vid + rvo >= maxvid */
+			printk(KERN_ERR FW_BUG PFX "maxvid exceeded with pstate"
+			       " %d\n", j);
+			return -ENODEV;
+		}
+		if (pst[j].fid > MAX_FID) {
+			printk(KERN_ERR FW_BUG PFX "maxfid exceeded with pstate"
+			       " %d\n", j);
+			return -ENODEV;
+		}
+		if (j && (pst[j].fid < HI_FID_TABLE_BOTTOM)) {
+			/* Only first fid is allowed to be in "low" range */
+			printk(KERN_ERR FW_BUG PFX "two low fids - %d : "
+			       "0x%x\n", j, pst[j].fid);
+			return -EINVAL;
+		}
+		if (pst[j].fid < lastfid)
+			lastfid = pst[j].fid;
+	}
+	if (lastfid & 1) {
+		printk(KERN_ERR FW_BUG PFX "lastfid invalid\n");
+		return -EINVAL;
+	}
+	if (lastfid > LO_FID_TABLE_TOP)
+		printk(KERN_INFO FW_BUG PFX
+			"first fid not from lo freq table\n");
+
+	return 0;
+}
+
+static void invalidate_entry(struct cpufreq_frequency_table *powernow_table,
+		unsigned int entry)
+{
+	powernow_table[entry].frequency = CPUFREQ_ENTRY_INVALID;
+}
+
+static void print_basics(struct powernow_k8_data *data)
+{
+	int j;
+	for (j = 0; j < data->numps; j++) {
+		if (data->powernow_table[j].frequency !=
+				CPUFREQ_ENTRY_INVALID) {
+			if (cpu_family == CPU_HW_PSTATE) {
+				printk(KERN_INFO PFX
+					"   %d : pstate %d (%d MHz)\n", j,
+					data->powernow_table[j].index,
+					data->powernow_table[j].frequency/1000);
+			} else {
+				printk(KERN_INFO PFX
+					"fid 0x%x (%d MHz), vid 0x%x\n",
+					data->powernow_table[j].index & 0xff,
+					data->powernow_table[j].frequency/1000,
+					data->powernow_table[j].index >> 8);
+			}
+		}
+	}
+	if (data->batps)
+		printk(KERN_INFO PFX "Only %d pstates on battery\n",
+				data->batps);
+}
+
+static u32 freq_from_fid_did(u32 fid, u32 did)
+{
+	u32 mhz = 0;
+
+	if (boot_cpu_data.x86 == 0x10)
+		mhz = (100 * (fid + 0x10)) >> did;
+	else if (boot_cpu_data.x86 == 0x11)
+		mhz = (100 * (fid + 8)) >> did;
+	else
+		BUG();
+
+	return mhz * 1000;
+}
+
+static int fill_powernow_table(struct powernow_k8_data *data,
+		struct pst_s *pst, u8 maxvid)
+{
+	struct cpufreq_frequency_table *powernow_table;
+	unsigned int j;
+
+	if (data->batps) {
+		/* use ACPI support to get full speed on mains power */
+		printk(KERN_WARNING PFX
+			"Only %d pstates usable (use ACPI driver for full "
+			"range\n", data->batps);
+		data->numps = data->batps;
+	}
+
+	for (j = 1; j < data->numps; j++) {
+		if (pst[j-1].fid >= pst[j].fid) {
+			printk(KERN_ERR PFX "PST out of sequence\n");
+			return -EINVAL;
+		}
+	}
+
+	if (data->numps < 2) {
+		printk(KERN_ERR PFX "no p states to transition\n");
+		return -ENODEV;
+	}
+
+	if (check_pst_table(data, pst, maxvid))
+		return -EINVAL;
+
+	powernow_table = kmalloc((sizeof(struct cpufreq_frequency_table)
+		* (data->numps + 1)), GFP_KERNEL);
+	if (!powernow_table) {
+		printk(KERN_ERR PFX "powernow_table memory alloc failure\n");
+		return -ENOMEM;
+	}
+
+	for (j = 0; j < data->numps; j++) {
+		int freq;
+		powernow_table[j].index = pst[j].fid; /* lower 8 bits */
+		powernow_table[j].index |= (pst[j].vid << 8); /* upper 8 bits */
+		freq = find_khz_freq_from_fid(pst[j].fid);
+		powernow_table[j].frequency = freq;
+	}
+	powernow_table[data->numps].frequency = CPUFREQ_TABLE_END;
+	powernow_table[data->numps].index = 0;
+
+	if (query_current_values_with_pending_wait(data)) {
+		kfree(powernow_table);
+		return -EIO;
+	}
+
+	pr_debug("cfid 0x%x, cvid 0x%x\n", data->currfid, data->currvid);
+	data->powernow_table = powernow_table;
+	if (cpumask_first(cpu_core_mask(data->cpu)) == data->cpu)
+		print_basics(data);
+
+	for (j = 0; j < data->numps; j++)
+		if ((pst[j].fid == data->currfid) &&
+		    (pst[j].vid == data->currvid))
+			return 0;
+
+	pr_debug("currfid/vid do not match PST, ignoring\n");
+	return 0;
+}
+
+/* Find and validate the PSB/PST table in BIOS. */
+static int find_psb_table(struct powernow_k8_data *data)
+{
+	struct psb_s *psb;
+	unsigned int i;
+	u32 mvs;
+	u8 maxvid;
+	u32 cpst = 0;
+	u32 thiscpuid;
+
+	for (i = 0xc0000; i < 0xffff0; i += 0x10) {
+		/* Scan BIOS looking for the signature. */
+		/* It can not be at ffff0 - it is too big. */
+
+		psb = phys_to_virt(i);
+		if (memcmp(psb, PSB_ID_STRING, PSB_ID_STRING_LEN) != 0)
+			continue;
+
+		pr_debug("found PSB header at 0x%p\n", psb);
+
+		pr_debug("table vers: 0x%x\n", psb->tableversion);
+		if (psb->tableversion != PSB_VERSION_1_4) {
+			printk(KERN_ERR FW_BUG PFX "PSB table is not v1.4\n");
+			return -ENODEV;
+		}
+
+		pr_debug("flags: 0x%x\n", psb->flags1);
+		if (psb->flags1) {
+			printk(KERN_ERR FW_BUG PFX "unknown flags\n");
+			return -ENODEV;
+		}
+
+		data->vstable = psb->vstable;
+		pr_debug("voltage stabilization time: %d(*20us)\n",
+				data->vstable);
+
+		pr_debug("flags2: 0x%x\n", psb->flags2);
+		data->rvo = psb->flags2 & 3;
+		data->irt = ((psb->flags2) >> 2) & 3;
+		mvs = ((psb->flags2) >> 4) & 3;
+		data->vidmvs = 1 << mvs;
+		data->batps = ((psb->flags2) >> 6) & 3;
+
+		pr_debug("ramp voltage offset: %d\n", data->rvo);
+		pr_debug("isochronous relief time: %d\n", data->irt);
+		pr_debug("maximum voltage step: %d - 0x%x\n", mvs, data->vidmvs);
+
+		pr_debug("numpst: 0x%x\n", psb->num_tables);
+		cpst = psb->num_tables;
+		if ((psb->cpuid == 0x00000fc0) ||
+		    (psb->cpuid == 0x00000fe0)) {
+			thiscpuid = cpuid_eax(CPUID_PROCESSOR_SIGNATURE);
+			if ((thiscpuid == 0x00000fc0) ||
+			    (thiscpuid == 0x00000fe0))
+				cpst = 1;
+		}
+		if (cpst != 1) {
+			printk(KERN_ERR FW_BUG PFX "numpst must be 1\n");
+			return -ENODEV;
+		}
+
+		data->plllock = psb->plllocktime;
+		pr_debug("plllocktime: 0x%x (units 1us)\n", psb->plllocktime);
+		pr_debug("maxfid: 0x%x\n", psb->maxfid);
+		pr_debug("maxvid: 0x%x\n", psb->maxvid);
+		maxvid = psb->maxvid;
+
+		data->numps = psb->numps;
+		pr_debug("numpstates: 0x%x\n", data->numps);
+		return fill_powernow_table(data,
+				(struct pst_s *)(psb+1), maxvid);
+	}
+	/*
+	 * If you see this message, complain to BIOS manufacturer. If
+	 * he tells you "we do not support Linux" or some similar
+	 * nonsense, remember that Windows 2000 uses the same legacy
+	 * mechanism that the old Linux PSB driver uses. Tell them it
+	 * is broken with Windows 2000.
+	 *
+	 * The reference to the AMD documentation is chapter 9 in the
+	 * BIOS and Kernel Developer's Guide, which is available on
+	 * www.amd.com
+	 */
+	printk(KERN_ERR FW_BUG PFX "No PSB or ACPI _PSS objects\n");
+	printk(KERN_ERR PFX "Make sure that your BIOS is up to date"
+		" and Cool'N'Quiet support is enabled in BIOS setup\n");
+	return -ENODEV;
+}
+
+static void powernow_k8_acpi_pst_values(struct powernow_k8_data *data,
+		unsigned int index)
+{
+	u64 control;
+
+	if (!data->acpi_data.state_count || (cpu_family == CPU_HW_PSTATE))
+		return;
+
+	control = data->acpi_data.states[index].control;
+	data->irt = (control >> IRT_SHIFT) & IRT_MASK;
+	data->rvo = (control >> RVO_SHIFT) & RVO_MASK;
+	data->exttype = (control >> EXT_TYPE_SHIFT) & EXT_TYPE_MASK;
+	data->plllock = (control >> PLL_L_SHIFT) & PLL_L_MASK;
+	data->vidmvs = 1 << ((control >> MVS_SHIFT) & MVS_MASK);
+	data->vstable = (control >> VST_SHIFT) & VST_MASK;
+}
+
+static int powernow_k8_cpu_init_acpi(struct powernow_k8_data *data)
+{
+	struct cpufreq_frequency_table *powernow_table;
+	int ret_val = -ENODEV;
+	u64 control, status;
+
+	if (acpi_processor_register_performance(&data->acpi_data, data->cpu)) {
+		pr_debug("register performance failed: bad ACPI data\n");
+		return -EIO;
+	}
+
+	/* verify the data contained in the ACPI structures */
+	if (data->acpi_data.state_count <= 1) {
+		pr_debug("No ACPI P-States\n");
+		goto err_out;
+	}
+
+	control = data->acpi_data.control_register.space_id;
+	status = data->acpi_data.status_register.space_id;
+
+	if ((control != ACPI_ADR_SPACE_FIXED_HARDWARE) ||
+	    (status != ACPI_ADR_SPACE_FIXED_HARDWARE)) {
+		pr_debug("Invalid control/status registers (%llx - %llx)\n",
+			control, status);
+		goto err_out;
+	}
+
+	/* fill in data->powernow_table */
+	powernow_table = kmalloc((sizeof(struct cpufreq_frequency_table)
+		* (data->acpi_data.state_count + 1)), GFP_KERNEL);
+	if (!powernow_table) {
+		pr_debug("powernow_table memory alloc failure\n");
+		goto err_out;
+	}
+
+	/* fill in data */
+	data->numps = data->acpi_data.state_count;
+	powernow_k8_acpi_pst_values(data, 0);
+
+	if (cpu_family == CPU_HW_PSTATE)
+		ret_val = fill_powernow_table_pstate(data, powernow_table);
+	else
+		ret_val = fill_powernow_table_fidvid(data, powernow_table);
+	if (ret_val)
+		goto err_out_mem;
+
+	powernow_table[data->acpi_data.state_count].frequency =
+		CPUFREQ_TABLE_END;
+	powernow_table[data->acpi_data.state_count].index = 0;
+	data->powernow_table = powernow_table;
+
+	if (cpumask_first(cpu_core_mask(data->cpu)) == data->cpu)
+		print_basics(data);
+
+	/* notify BIOS that we exist */
+	acpi_processor_notify_smm(THIS_MODULE);
+
+	if (!zalloc_cpumask_var(&data->acpi_data.shared_cpu_map, GFP_KERNEL)) {
+		printk(KERN_ERR PFX
+				"unable to alloc powernow_k8_data cpumask\n");
+		ret_val = -ENOMEM;
+		goto err_out_mem;
+	}
+
+	return 0;
+
+err_out_mem:
+	kfree(powernow_table);
+
+err_out:
+	acpi_processor_unregister_performance(&data->acpi_data, data->cpu);
+
+	/* data->acpi_data.state_count informs us at ->exit()
+	 * whether ACPI was used */
+	data->acpi_data.state_count = 0;
+
+	return ret_val;
+}
+
+static int fill_powernow_table_pstate(struct powernow_k8_data *data,
+		struct cpufreq_frequency_table *powernow_table)
+{
+	int i;
+	u32 hi = 0, lo = 0;
+	rdmsr(MSR_PSTATE_CUR_LIMIT, lo, hi);
+	data->max_hw_pstate = (lo & HW_PSTATE_MAX_MASK) >> HW_PSTATE_MAX_SHIFT;
+
+	for (i = 0; i < data->acpi_data.state_count; i++) {
+		u32 index;
+
+		index = data->acpi_data.states[i].control & HW_PSTATE_MASK;
+		if (index > data->max_hw_pstate) {
+			printk(KERN_ERR PFX "invalid pstate %d - "
+					"bad value %d.\n", i, index);
+			printk(KERN_ERR PFX "Please report to BIOS "
+					"manufacturer\n");
+			invalidate_entry(powernow_table, i);
+			continue;
+		}
+		rdmsr(MSR_PSTATE_DEF_BASE + index, lo, hi);
+		if (!(hi & HW_PSTATE_VALID_MASK)) {
+			pr_debug("invalid pstate %d, ignoring\n", index);
+			invalidate_entry(powernow_table, i);
+			continue;
+		}
+
+		powernow_table[i].index = index;
+
+		/* Frequency may be rounded for these */
+		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
+			powernow_table[i].frequency =
+				data->acpi_data.states[i].core_frequency * 1000;
+	}
+	return 0;
+}
+
+static int fill_powernow_table_fidvid(struct powernow_k8_data *data,
+		struct cpufreq_frequency_table *powernow_table)
+{
+	int i;
+
+	for (i = 0; i < data->acpi_data.state_count; i++) {
+		u32 fid;
+		u32 vid;
+		u32 freq, index;
+		u64 status, control;
+
+		if (data->exttype) {
+			status =  data->acpi_data.states[i].status;
+			fid = status & EXT_FID_MASK;
+			vid = (status >> VID_SHIFT) & EXT_VID_MASK;
+		} else {
+			control =  data->acpi_data.states[i].control;
+			fid = control & FID_MASK;
+			vid = (control >> VID_SHIFT) & VID_MASK;
+		}
+
+		pr_debug("   %d : fid 0x%x, vid 0x%x\n", i, fid, vid);
+
+		index = fid | (vid<<8);
+		powernow_table[i].index = index;
+
+		freq = find_khz_freq_from_fid(fid);
+		powernow_table[i].frequency = freq;
+
+		/* verify frequency is OK */
+		if ((freq > (MAX_FREQ * 1000)) || (freq < (MIN_FREQ * 1000))) {
+			pr_debug("invalid freq %u kHz, ignoring\n", freq);
+			invalidate_entry(powernow_table, i);
+			continue;
+		}
+
+		/* verify voltage is OK -
+		 * BIOSs are using "off" to indicate invalid */
+		if (vid == VID_OFF) {
+			pr_debug("invalid vid %u, ignoring\n", vid);
+			invalidate_entry(powernow_table, i);
+			continue;
+		}
+
+		if (freq != (data->acpi_data.states[i].core_frequency * 1000)) {
+			printk(KERN_INFO PFX "invalid freq entries "
+				"%u kHz vs. %u kHz\n", freq,
+				(unsigned int)
+				(data->acpi_data.states[i].core_frequency
+				 * 1000));
+			invalidate_entry(powernow_table, i);
+			continue;
+		}
+	}
+	return 0;
+}
+
+static void powernow_k8_cpu_exit_acpi(struct powernow_k8_data *data)
+{
+	if (data->acpi_data.state_count)
+		acpi_processor_unregister_performance(&data->acpi_data,
+				data->cpu);
+	free_cpumask_var(data->acpi_data.shared_cpu_map);
+}
+
+static int get_transition_latency(struct powernow_k8_data *data)
+{
+	int max_latency = 0;
+	int i;
+	for (i = 0; i < data->acpi_data.state_count; i++) {
+		int cur_latency = data->acpi_data.states[i].transition_latency
+			+ data->acpi_data.states[i].bus_master_latency;
+		if (cur_latency > max_latency)
+			max_latency = cur_latency;
+	}
+	if (max_latency == 0) {
+		/*
+		 * Fam 11h and later may return 0 as transition latency. This
+		 * is intended and means "very fast". While cpufreq core and
+		 * governors currently can handle that gracefully, better set it
+		 * to 1 to avoid problems in the future.
+		 */
+		if (boot_cpu_data.x86 < 0x11)
+			printk(KERN_ERR FW_WARN PFX "Invalid zero transition "
+				"latency\n");
+		max_latency = 1;
+	}
+	/* value in usecs, needs to be in nanoseconds */
+	return 1000 * max_latency;
+}
+
+/* Take a frequency, and issue the fid/vid transition command */
+static int transition_frequency_fidvid(struct powernow_k8_data *data,
+		unsigned int index)
+{
+	u32 fid = 0;
+	u32 vid = 0;
+	int res, i;
+	struct cpufreq_freqs freqs;
+
+	pr_debug("cpu %d transition to index %u\n", smp_processor_id(), index);
+
+	/* fid/vid correctness check for k8 */
+	/* fid are the lower 8 bits of the index we stored into
+	 * the cpufreq frequency table in find_psb_table, vid
+	 * are the upper 8 bits.
+	 */
+	fid = data->powernow_table[index].index & 0xFF;
+	vid = (data->powernow_table[index].index & 0xFF00) >> 8;
+
+	pr_debug("table matched fid 0x%x, giving vid 0x%x\n", fid, vid);
+
+	if (query_current_values_with_pending_wait(data))
+		return 1;
+
+	if ((data->currvid == vid) && (data->currfid == fid)) {
+		pr_debug("target matches current values (fid 0x%x, vid 0x%x)\n",
+			fid, vid);
+		return 0;
+	}
+
+	pr_debug("cpu %d, changing to fid 0x%x, vid 0x%x\n",
+		smp_processor_id(), fid, vid);
+	freqs.old = find_khz_freq_from_fid(data->currfid);
+	freqs.new = find_khz_freq_from_fid(fid);
+
+	for_each_cpu(i, data->available_cores) {
+		freqs.cpu = i;
+		cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
+	}
+
+	res = transition_fid_vid(data, fid, vid);
+	if (res)
+		return res;
+
+	freqs.new = find_khz_freq_from_fid(data->currfid);
+
+	for_each_cpu(i, data->available_cores) {
+		freqs.cpu = i;
+		cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
+	}
+	return res;
+}
+
+/* Take a frequency, and issue the hardware pstate transition command */
+static int transition_frequency_pstate(struct powernow_k8_data *data,
+		unsigned int index)
+{
+	u32 pstate = 0;
+	int res, i;
+	struct cpufreq_freqs freqs;
+
+	pr_debug("cpu %d transition to index %u\n", smp_processor_id(), index);
+
+	/* get MSR index for hardware pstate transition */
+	pstate = index & HW_PSTATE_MASK;
+	if (pstate > data->max_hw_pstate)
+		return -EINVAL;
+
+	freqs.old = find_khz_freq_from_pstate(data->powernow_table,
+			data->currpstate);
+	freqs.new = find_khz_freq_from_pstate(data->powernow_table, pstate);
+
+	for_each_cpu(i, data->available_cores) {
+		freqs.cpu = i;
+		cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
+	}
+
+	res = transition_pstate(data, pstate);
+	freqs.new = find_khz_freq_from_pstate(data->powernow_table, pstate);
+
+	for_each_cpu(i, data->available_cores) {
+		freqs.cpu = i;
+		cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
+	}
+	return res;
+}
+
+/* Driver entry point to switch to the target frequency */
+static int powernowk8_target(struct cpufreq_policy *pol,
+		unsigned targfreq, unsigned relation)
+{
+	cpumask_var_t oldmask;
+	struct powernow_k8_data *data = per_cpu(powernow_data, pol->cpu);
+	u32 checkfid;
+	u32 checkvid;
+	unsigned int newstate;
+	int ret = -EIO;
+
+	if (!data)
+		return -EINVAL;
+
+	checkfid = data->currfid;
+	checkvid = data->currvid;
+
+	/* only run on specific CPU from here on. */
+	/* This is poor form: use a workqueue or smp_call_function_single */
+	if (!alloc_cpumask_var(&oldmask, GFP_KERNEL))
+		return -ENOMEM;
+
+	cpumask_copy(oldmask, tsk_cpus_allowed(current));
+	set_cpus_allowed_ptr(current, cpumask_of(pol->cpu));
+
+	if (smp_processor_id() != pol->cpu) {
+		printk(KERN_ERR PFX "limiting to cpu %u failed\n", pol->cpu);
+		goto err_out;
+	}
+
+	if (pending_bit_stuck()) {
+		printk(KERN_ERR PFX "failing targ, change pending bit set\n");
+		goto err_out;
+	}
+
+	pr_debug("targ: cpu %d, %d kHz, min %d, max %d, relation %d\n",
+		pol->cpu, targfreq, pol->min, pol->max, relation);
+
+	if (query_current_values_with_pending_wait(data))
+		goto err_out;
+
+	if (cpu_family != CPU_HW_PSTATE) {
+		pr_debug("targ: curr fid 0x%x, vid 0x%x\n",
+		data->currfid, data->currvid);
+
+		if ((checkvid != data->currvid) ||
+		    (checkfid != data->currfid)) {
+			printk(KERN_INFO PFX
+				"error - out of sync, fix 0x%x 0x%x, "
+				"vid 0x%x 0x%x\n",
+				checkfid, data->currfid,
+				checkvid, data->currvid);
+		}
+	}
+
+	if (cpufreq_frequency_table_target(pol, data->powernow_table,
+				targfreq, relation, &newstate))
+		goto err_out;
+
+	mutex_lock(&fidvid_mutex);
+
+	powernow_k8_acpi_pst_values(data, newstate);
+
+	if (cpu_family == CPU_HW_PSTATE)
+		ret = transition_frequency_pstate(data, newstate);
+	else
+		ret = transition_frequency_fidvid(data, newstate);
+	if (ret) {
+		printk(KERN_ERR PFX "transition frequency failed\n");
+		ret = 1;
+		mutex_unlock(&fidvid_mutex);
+		goto err_out;
+	}
+	mutex_unlock(&fidvid_mutex);
+
+	if (cpu_family == CPU_HW_PSTATE)
+		pol->cur = find_khz_freq_from_pstate(data->powernow_table,
+				newstate);
+	else
+		pol->cur = find_khz_freq_from_fid(data->currfid);
+	ret = 0;
+
+err_out:
+	set_cpus_allowed_ptr(current, oldmask);
+	free_cpumask_var(oldmask);
+	return ret;
+}
+
+/* Driver entry point to verify the policy and range of frequencies */
+static int powernowk8_verify(struct cpufreq_policy *pol)
+{
+	struct powernow_k8_data *data = per_cpu(powernow_data, pol->cpu);
+
+	if (!data)
+		return -EINVAL;
+
+	return cpufreq_frequency_table_verify(pol, data->powernow_table);
+}
+
+struct init_on_cpu {
+	struct powernow_k8_data *data;
+	int rc;
+};
+
+static void __cpuinit powernowk8_cpu_init_on_cpu(void *_init_on_cpu)
+{
+	struct init_on_cpu *init_on_cpu = _init_on_cpu;
+
+	if (pending_bit_stuck()) {
+		printk(KERN_ERR PFX "failing init, change pending bit set\n");
+		init_on_cpu->rc = -ENODEV;
+		return;
+	}
+
+	if (query_current_values_with_pending_wait(init_on_cpu->data)) {
+		init_on_cpu->rc = -ENODEV;
+		return;
+	}
+
+	if (cpu_family == CPU_OPTERON)
+		fidvid_msr_init();
+
+	init_on_cpu->rc = 0;
+}
+
+/* per CPU init entry point to the driver */
+static int __cpuinit powernowk8_cpu_init(struct cpufreq_policy *pol)
+{
+	static const char ACPI_PSS_BIOS_BUG_MSG[] =
+		KERN_ERR FW_BUG PFX "No compatible ACPI _PSS objects found.\n"
+		FW_BUG PFX "Try again with latest BIOS.\n";
+	struct powernow_k8_data *data;
+	struct init_on_cpu init_on_cpu;
+	int rc;
+	struct cpuinfo_x86 *c = &cpu_data(pol->cpu);
+
+	if (!cpu_online(pol->cpu))
+		return -ENODEV;
+
+	smp_call_function_single(pol->cpu, check_supported_cpu, &rc, 1);
+	if (rc)
+		return -ENODEV;
+
+	data = kzalloc(sizeof(struct powernow_k8_data), GFP_KERNEL);
+	if (!data) {
+		printk(KERN_ERR PFX "unable to alloc powernow_k8_data");
+		return -ENOMEM;
+	}
+
+	data->cpu = pol->cpu;
+	data->currpstate = HW_PSTATE_INVALID;
+
+	if (powernow_k8_cpu_init_acpi(data)) {
+		/*
+		 * Use the PSB BIOS structure. This is only available on
+		 * an UP version, and is deprecated by AMD.
+		 */
+		if (num_online_cpus() != 1) {
+			printk_once(ACPI_PSS_BIOS_BUG_MSG);
+			goto err_out;
+		}
+		if (pol->cpu != 0) {
+			printk(KERN_ERR FW_BUG PFX "No ACPI _PSS objects for "
+			       "CPU other than CPU0. Complain to your BIOS "
+			       "vendor.\n");
+			goto err_out;
+		}
+		rc = find_psb_table(data);
+		if (rc)
+			goto err_out;
+
+		/* Take a crude guess here.
+		 * That guess was in microseconds, so multiply with 1000 */
+		pol->cpuinfo.transition_latency = (
+			 ((data->rvo + 8) * data->vstable * VST_UNITS_20US) +
+			 ((1 << data->irt) * 30)) * 1000;
+	} else /* ACPI _PSS objects available */
+		pol->cpuinfo.transition_latency = get_transition_latency(data);
+
+	/* only run on specific CPU from here on */
+	init_on_cpu.data = data;
+	smp_call_function_single(data->cpu, powernowk8_cpu_init_on_cpu,
+				 &init_on_cpu, 1);
+	rc = init_on_cpu.rc;
+	if (rc != 0)
+		goto err_out_exit_acpi;
+
+	if (cpu_family == CPU_HW_PSTATE)
+		cpumask_copy(pol->cpus, cpumask_of(pol->cpu));
+	else
+		cpumask_copy(pol->cpus, cpu_core_mask(pol->cpu));
+	data->available_cores = pol->cpus;
+
+	if (cpu_family == CPU_HW_PSTATE)
+		pol->cur = find_khz_freq_from_pstate(data->powernow_table,
+				data->currpstate);
+	else
+		pol->cur = find_khz_freq_from_fid(data->currfid);
+	pr_debug("policy current frequency %d kHz\n", pol->cur);
+
+	/* min/max the cpu is capable of */
+	if (cpufreq_frequency_table_cpuinfo(pol, data->powernow_table)) {
+		printk(KERN_ERR FW_BUG PFX "invalid powernow_table\n");
+		powernow_k8_cpu_exit_acpi(data);
+		kfree(data->powernow_table);
+		kfree(data);
+		return -EINVAL;
+	}
+
+	/* Check for APERF/MPERF support in hardware */
+	if (cpu_has(c, X86_FEATURE_APERFMPERF))
+		cpufreq_amd64_driver.getavg = cpufreq_get_measured_perf;
+
+	cpufreq_frequency_table_get_attr(data->powernow_table, pol->cpu);
+
+	if (cpu_family == CPU_HW_PSTATE)
+		pr_debug("cpu_init done, current pstate 0x%x\n",
+				data->currpstate);
+	else
+		pr_debug("cpu_init done, current fid 0x%x, vid 0x%x\n",
+			data->currfid, data->currvid);
+
+	per_cpu(powernow_data, pol->cpu) = data;
+
+	return 0;
+
+err_out_exit_acpi:
+	powernow_k8_cpu_exit_acpi(data);
+
+err_out:
+	kfree(data);
+	return -ENODEV;
+}
+
+static int __devexit powernowk8_cpu_exit(struct cpufreq_policy *pol)
+{
+	struct powernow_k8_data *data = per_cpu(powernow_data, pol->cpu);
+
+	if (!data)
+		return -EINVAL;
+
+	powernow_k8_cpu_exit_acpi(data);
+
+	cpufreq_frequency_table_put_attr(pol->cpu);
+
+	kfree(data->powernow_table);
+	kfree(data);
+	per_cpu(powernow_data, pol->cpu) = NULL;
+
+	return 0;
+}
+
+static void query_values_on_cpu(void *_err)
+{
+	int *err = _err;
+	struct powernow_k8_data *data = __this_cpu_read(powernow_data);
+
+	*err = query_current_values_with_pending_wait(data);
+}
+
+static unsigned int powernowk8_get(unsigned int cpu)
+{
+	struct powernow_k8_data *data = per_cpu(powernow_data, cpu);
+	unsigned int khz = 0;
+	int err;
+
+	if (!data)
+		return 0;
+
+	smp_call_function_single(cpu, query_values_on_cpu, &err, true);
+	if (err)
+		goto out;
+
+	if (cpu_family == CPU_HW_PSTATE)
+		khz = find_khz_freq_from_pstate(data->powernow_table,
+						data->currpstate);
+	else
+		khz = find_khz_freq_from_fid(data->currfid);
+
+
+out:
+	return khz;
+}
+
+static void _cpb_toggle_msrs(bool t)
+{
+	int cpu;
+
+	get_online_cpus();
+
+	rdmsr_on_cpus(cpu_online_mask, MSR_K7_HWCR, msrs);
+
+	for_each_cpu(cpu, cpu_online_mask) {
+		struct msr *reg = per_cpu_ptr(msrs, cpu);
+		if (t)
+			reg->l &= ~BIT(25);
+		else
+			reg->l |= BIT(25);
+	}
+	wrmsr_on_cpus(cpu_online_mask, MSR_K7_HWCR, msrs);
+
+	put_online_cpus();
+}
+
+/*
+ * Switch on/off core performance boosting.
+ *
+ * 0=disable
+ * 1=enable.
+ */
+static void cpb_toggle(bool t)
+{
+	if (!cpb_capable)
+		return;
+
+	if (t && !cpb_enabled) {
+		cpb_enabled = true;
+		_cpb_toggle_msrs(t);
+		printk(KERN_INFO PFX "Core Boosting enabled.\n");
+	} else if (!t && cpb_enabled) {
+		cpb_enabled = false;
+		_cpb_toggle_msrs(t);
+		printk(KERN_INFO PFX "Core Boosting disabled.\n");
+	}
+}
+
+static ssize_t store_cpb(struct cpufreq_policy *policy, const char *buf,
+				 size_t count)
+{
+	int ret = -EINVAL;
+	unsigned long val = 0;
+
+	ret = strict_strtoul(buf, 10, &val);
+	if (!ret && (val == 0 || val == 1) && cpb_capable)
+		cpb_toggle(val);
+	else
+		return -EINVAL;
+
+	return count;
+}
+
+static ssize_t show_cpb(struct cpufreq_policy *policy, char *buf)
+{
+	return sprintf(buf, "%u\n", cpb_enabled);
+}
+
+#define define_one_rw(_name) \
+static struct freq_attr _name = \
+__ATTR(_name, 0644, show_##_name, store_##_name)
+
+define_one_rw(cpb);
+
+static struct freq_attr *powernow_k8_attr[] = {
+	&cpufreq_freq_attr_scaling_available_freqs,
+	&cpb,
+	NULL,
+};
+
+static struct cpufreq_driver cpufreq_amd64_driver = {
+	.verify		= powernowk8_verify,
+	.target		= powernowk8_target,
+	.bios_limit	= acpi_processor_get_bios_limit,
+	.init		= powernowk8_cpu_init,
+	.exit		= __devexit_p(powernowk8_cpu_exit),
+	.get		= powernowk8_get,
+	.name		= "powernow-k8",
+	.owner		= THIS_MODULE,
+	.attr		= powernow_k8_attr,
+};
+
+/*
+ * Clear the boost-disable flag on the CPU_DOWN path so that this cpu
+ * cannot block the remaining ones from boosting. On the CPU_UP path we
+ * simply keep the boost-disable flag in sync with the current global
+ * state.
+ */
+static int cpb_notify(struct notifier_block *nb, unsigned long action,
+		      void *hcpu)
+{
+	unsigned cpu = (long)hcpu;
+	u32 lo, hi;
+
+	switch (action) {
+	case CPU_UP_PREPARE:
+	case CPU_UP_PREPARE_FROZEN:
+
+		if (!cpb_enabled) {
+			rdmsr_on_cpu(cpu, MSR_K7_HWCR, &lo, &hi);
+			lo |= BIT(25);
+			wrmsr_on_cpu(cpu, MSR_K7_HWCR, lo, hi);
+		}
+		break;
+
+	case CPU_DOWN_PREPARE:
+	case CPU_DOWN_PREPARE_FROZEN:
+		rdmsr_on_cpu(cpu, MSR_K7_HWCR, &lo, &hi);
+		lo &= ~BIT(25);
+		wrmsr_on_cpu(cpu, MSR_K7_HWCR, lo, hi);
+		break;
+
+	default:
+		break;
+	}
+
+	return NOTIFY_OK;
+}
+
+static struct notifier_block cpb_nb = {
+	.notifier_call		= cpb_notify,
+};
+
+/* driver entry point for init */
+static int __cpuinit powernowk8_init(void)
+{
+	unsigned int i, supported_cpus = 0, cpu;
+	int rv;
+
+	for_each_online_cpu(i) {
+		int rc;
+		smp_call_function_single(i, check_supported_cpu, &rc, 1);
+		if (rc == 0)
+			supported_cpus++;
+	}
+
+	if (supported_cpus != num_online_cpus())
+		return -ENODEV;
+
+	printk(KERN_INFO PFX "Found %d %s (%d cpu cores) (" VERSION ")\n",
+		num_online_nodes(), boot_cpu_data.x86_model_id, supported_cpus);
+
+	if (boot_cpu_has(X86_FEATURE_CPB)) {
+
+		cpb_capable = true;
+
+		msrs = msrs_alloc();
+		if (!msrs) {
+			printk(KERN_ERR "%s: Error allocating msrs!\n", __func__);
+			return -ENOMEM;
+		}
+
+		register_cpu_notifier(&cpb_nb);
+
+		rdmsr_on_cpus(cpu_online_mask, MSR_K7_HWCR, msrs);
+
+		for_each_cpu(cpu, cpu_online_mask) {
+			struct msr *reg = per_cpu_ptr(msrs, cpu);
+			cpb_enabled |= !(!!(reg->l & BIT(25)));
+		}
+
+		printk(KERN_INFO PFX "Core Performance Boosting: %s.\n",
+			(cpb_enabled ? "on" : "off"));
+	}
+
+	rv = cpufreq_register_driver(&cpufreq_amd64_driver);
+	if (rv < 0 && boot_cpu_has(X86_FEATURE_CPB)) {
+		unregister_cpu_notifier(&cpb_nb);
+		msrs_free(msrs);
+		msrs = NULL;
+	}
+	return rv;
+}
+
+/* driver entry point for term */
+static void __exit powernowk8_exit(void)
+{
+	pr_debug("exit\n");
+
+	if (boot_cpu_has(X86_FEATURE_CPB)) {
+		msrs_free(msrs);
+		msrs = NULL;
+
+		unregister_cpu_notifier(&cpb_nb);
+	}
+
+	cpufreq_unregister_driver(&cpufreq_amd64_driver);
+}
+
+MODULE_AUTHOR("Paul Devriendt <paul.devriendt@amd.com> and "
+		"Mark Langsdorf <mark.langsdorf@amd.com>");
+MODULE_DESCRIPTION("AMD Athlon 64 and Opteron processor frequency driver.");
+MODULE_LICENSE("GPL");
+
+late_initcall(powernowk8_init);
+module_exit(powernowk8_exit);
diff -druN linux-2.6.39-libre/drivers/cpufreq/powernow-k8.h linux-3.0-rc7-libre/drivers/cpufreq/powernow-k8.h
--- linux-2.6.39-libre/drivers/cpufreq/powernow-k8.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/cpufreq/powernow-k8.h	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,222 @@
+/*
+ *  (c) 2003-2006 Advanced Micro Devices, Inc.
+ *  Your use of this code is subject to the terms and conditions of the
+ *  GNU general public license version 2. See "COPYING" or
+ *  http://www.gnu.org/licenses/gpl.html
+ */
+
+enum pstate {
+	HW_PSTATE_INVALID = 0xff,
+	HW_PSTATE_0 = 0,
+	HW_PSTATE_1 = 1,
+	HW_PSTATE_2 = 2,
+	HW_PSTATE_3 = 3,
+	HW_PSTATE_4 = 4,
+	HW_PSTATE_5 = 5,
+	HW_PSTATE_6 = 6,
+	HW_PSTATE_7 = 7,
+};
+
+struct powernow_k8_data {
+	unsigned int cpu;
+
+	u32 numps;  /* number of p-states */
+	u32 batps;  /* number of p-states supported on battery */
+	u32 max_hw_pstate; /* maximum legal hardware pstate */
+
+	/* these values are constant when the PSB is used to determine
+	 * vid/fid pairings, but are modified during the ->target() call
+	 * when ACPI is used */
+	u32 rvo;     /* ramp voltage offset */
+	u32 irt;     /* isochronous relief time */
+	u32 vidmvs;  /* usable value calculated from mvs */
+	u32 vstable; /* voltage stabilization time, units 20 us */
+	u32 plllock; /* pll lock time, units 1 us */
+        u32 exttype; /* extended interface = 1 */
+
+	/* keep track of the current fid / vid or pstate */
+	u32 currvid;
+	u32 currfid;
+	enum pstate currpstate;
+
+	/* the powernow_table includes all frequency and vid/fid pairings:
+	 * fid are the lower 8 bits of the index, vid are the upper 8 bits.
+	 * frequency is in kHz */
+	struct cpufreq_frequency_table  *powernow_table;
+
+	/* the acpi table needs to be kept. it's only available if ACPI was
+	 * used to determine valid frequency/vid/fid states */
+	struct acpi_processor_performance acpi_data;
+
+	/* we need to keep track of associated cores, but let cpufreq
+	 * handle hotplug events - so just point at cpufreq pol->cpus
+	 * structure */
+	struct cpumask *available_cores;
+};
+
+/* processor's cpuid instruction support */
+#define CPUID_PROCESSOR_SIGNATURE	1	/* function 1 */
+#define CPUID_XFAM			0x0ff00000	/* extended family */
+#define CPUID_XFAM_K8			0
+#define CPUID_XMOD			0x000f0000	/* extended model */
+#define CPUID_XMOD_REV_MASK		0x000c0000
+#define CPUID_XFAM_10H			0x00100000	/* family 0x10 */
+#define CPUID_USE_XFAM_XMOD		0x00000f00
+#define CPUID_GET_MAX_CAPABILITIES	0x80000000
+#define CPUID_FREQ_VOLT_CAPABILITIES	0x80000007
+#define P_STATE_TRANSITION_CAPABLE	6
+
+/* Model Specific Registers for p-state transitions. MSRs are 64-bit. For     */
+/* writes (wrmsr - opcode 0f 30), the register number is placed in ecx, and   */
+/* the value to write is placed in edx:eax. For reads (rdmsr - opcode 0f 32), */
+/* the register number is placed in ecx, and the data is returned in edx:eax. */
+
+#define MSR_FIDVID_CTL      0xc0010041
+#define MSR_FIDVID_STATUS   0xc0010042
+
+/* Field definitions within the FID VID Low Control MSR : */
+#define MSR_C_LO_INIT_FID_VID     0x00010000
+#define MSR_C_LO_NEW_VID          0x00003f00
+#define MSR_C_LO_NEW_FID          0x0000003f
+#define MSR_C_LO_VID_SHIFT        8
+
+/* Field definitions within the FID VID High Control MSR : */
+#define MSR_C_HI_STP_GNT_TO	  0x000fffff
+
+/* Field definitions within the FID VID Low Status MSR : */
+#define MSR_S_LO_CHANGE_PENDING   0x80000000   /* cleared when completed */
+#define MSR_S_LO_MAX_RAMP_VID     0x3f000000
+#define MSR_S_LO_MAX_FID          0x003f0000
+#define MSR_S_LO_START_FID        0x00003f00
+#define MSR_S_LO_CURRENT_FID      0x0000003f
+
+/* Field definitions within the FID VID High Status MSR : */
+#define MSR_S_HI_MIN_WORKING_VID  0x3f000000
+#define MSR_S_HI_MAX_WORKING_VID  0x003f0000
+#define MSR_S_HI_START_VID        0x00003f00
+#define MSR_S_HI_CURRENT_VID      0x0000003f
+#define MSR_C_HI_STP_GNT_BENIGN	  0x00000001
+
+
+/* Hardware Pstate _PSS and MSR definitions */
+#define USE_HW_PSTATE		0x00000080
+#define HW_PSTATE_MASK 		0x00000007
+#define HW_PSTATE_VALID_MASK 	0x80000000
+#define HW_PSTATE_MAX_MASK	0x000000f0
+#define HW_PSTATE_MAX_SHIFT	4
+#define MSR_PSTATE_DEF_BASE 	0xc0010064 /* base of Pstate MSRs */
+#define MSR_PSTATE_STATUS 	0xc0010063 /* Pstate Status MSR */
+#define MSR_PSTATE_CTRL 	0xc0010062 /* Pstate control MSR */
+#define MSR_PSTATE_CUR_LIMIT	0xc0010061 /* pstate current limit MSR */
+
+/* define the two driver architectures */
+#define CPU_OPTERON 0
+#define CPU_HW_PSTATE 1
+
+
+/*
+ * There are restrictions frequencies have to follow:
+ * - only 1 entry in the low fid table ( <=1.4GHz )
+ * - lowest entry in the high fid table must be >= 2 * the entry in the
+ *   low fid table
+ * - lowest entry in the high fid table must be a <= 200MHz + 2 * the entry
+ *   in the low fid table
+ * - the parts can only step at <= 200 MHz intervals, odd fid values are
+ *   supported in revision G and later revisions.
+ * - lowest frequency must be >= interprocessor hypertransport link speed
+ *   (only applies to MP systems obviously)
+ */
+
+/* fids (frequency identifiers) are arranged in 2 tables - lo and hi */
+#define LO_FID_TABLE_TOP     7	/* fid values marking the boundary    */
+#define HI_FID_TABLE_BOTTOM  8	/* between the low and high tables    */
+
+#define LO_VCOFREQ_TABLE_TOP    1400	/* corresponding vco frequency values */
+#define HI_VCOFREQ_TABLE_BOTTOM 1600
+
+#define MIN_FREQ_RESOLUTION  200 /* fids jump by 2 matching freq jumps by 200 */
+
+#define MAX_FID 0x2a	/* Spec only gives FID values as far as 5 GHz */
+#define LEAST_VID 0x3e	/* Lowest (numerically highest) useful vid value */
+
+#define MIN_FREQ 800	/* Min and max freqs, per spec */
+#define MAX_FREQ 5000
+
+#define INVALID_FID_MASK 0xffffffc0  /* not a valid fid if these bits are set */
+#define INVALID_VID_MASK 0xffffffc0  /* not a valid vid if these bits are set */
+
+#define VID_OFF 0x3f
+
+#define STOP_GRANT_5NS 1 /* min poss memory access latency for voltage change */
+
+#define PLL_LOCK_CONVERSION (1000/5) /* ms to ns, then divide by clock period */
+
+#define MAXIMUM_VID_STEPS 1  /* Current cpus only allow a single step of 25mV */
+#define VST_UNITS_20US 20   /* Voltage Stabilization Time is in units of 20us */
+
+/*
+ * Most values of interest are encoded in a single field of the _PSS
+ * entries: the "control" value.
+ */
+
+#define IRT_SHIFT      30
+#define RVO_SHIFT      28
+#define EXT_TYPE_SHIFT 27
+#define PLL_L_SHIFT    20
+#define MVS_SHIFT      18
+#define VST_SHIFT      11
+#define VID_SHIFT       6
+#define IRT_MASK        3
+#define RVO_MASK        3
+#define EXT_TYPE_MASK   1
+#define PLL_L_MASK   0x7f
+#define MVS_MASK        3
+#define VST_MASK     0x7f
+#define VID_MASK     0x1f
+#define FID_MASK     0x1f
+#define EXT_VID_MASK 0x3f
+#define EXT_FID_MASK 0x3f
+
+
+/*
+ * Version 1.4 of the PSB table. This table is constructed by BIOS and is
+ * to tell the OS's power management driver which VIDs and FIDs are
+ * supported by this particular processor.
+ * If the data in the PSB / PST is wrong, then this driver will program the
+ * wrong values into hardware, which is very likely to lead to a crash.
+ */
+
+#define PSB_ID_STRING      "AMDK7PNOW!"
+#define PSB_ID_STRING_LEN  10
+
+#define PSB_VERSION_1_4  0x14
+
+struct psb_s {
+	u8 signature[10];
+	u8 tableversion;
+	u8 flags1;
+	u16 vstable;
+	u8 flags2;
+	u8 num_tables;
+	u32 cpuid;
+	u8 plllocktime;
+	u8 maxfid;
+	u8 maxvid;
+	u8 numps;
+};
+
+/* Pairs of fid/vid values are appended to the version 1.4 PSB table. */
+struct pst_s {
+	u8 fid;
+	u8 vid;
+};
+
+static int core_voltage_pre_transition(struct powernow_k8_data *data,
+	u32 reqvid, u32 regfid);
+static int core_voltage_post_transition(struct powernow_k8_data *data, u32 reqvid);
+static int core_frequency_transition(struct powernow_k8_data *data, u32 reqfid);
+
+static void powernow_k8_acpi_pst_values(struct powernow_k8_data *data, unsigned int index);
+
+static int fill_powernow_table_pstate(struct powernow_k8_data *data, struct cpufreq_frequency_table *powernow_table);
+static int fill_powernow_table_fidvid(struct powernow_k8_data *data, struct cpufreq_frequency_table *powernow_table);
diff -druN linux-2.6.39-libre/drivers/cpufreq/sc520_freq.c linux-3.0-rc7-libre/drivers/cpufreq/sc520_freq.c
--- linux-2.6.39-libre/drivers/cpufreq/sc520_freq.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/cpufreq/sc520_freq.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,192 @@
+/*
+ *	sc520_freq.c: cpufreq driver for the AMD Elan sc520
+ *
+ *	Copyright (C) 2005 Sean Young <sean@mess.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.
+ *
+ *	Based on elanfreq.c
+ *
+ *	2005-03-30: - initial revision
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+
+#include <linux/delay.h>
+#include <linux/cpufreq.h>
+#include <linux/timex.h>
+#include <linux/io.h>
+
+#include <asm/msr.h>
+
+#define MMCR_BASE	0xfffef000	/* The default base address */
+#define OFFS_CPUCTL	0x2   /* CPU Control Register */
+
+static __u8 __iomem *cpuctl;
+
+#define PFX "sc520_freq: "
+
+static struct cpufreq_frequency_table sc520_freq_table[] = {
+	{0x01,	100000},
+	{0x02,	133000},
+	{0,	CPUFREQ_TABLE_END},
+};
+
+static unsigned int sc520_freq_get_cpu_frequency(unsigned int cpu)
+{
+	u8 clockspeed_reg = *cpuctl;
+
+	switch (clockspeed_reg & 0x03) {
+	default:
+		printk(KERN_ERR PFX "error: cpuctl register has unexpected "
+				"value %02x\n", clockspeed_reg);
+	case 0x01:
+		return 100000;
+	case 0x02:
+		return 133000;
+	}
+}
+
+static void sc520_freq_set_cpu_state(unsigned int state)
+{
+
+	struct cpufreq_freqs	freqs;
+	u8 clockspeed_reg;
+
+	freqs.old = sc520_freq_get_cpu_frequency(0);
+	freqs.new = sc520_freq_table[state].frequency;
+	freqs.cpu = 0; /* AMD Elan is UP */
+
+	cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
+
+	pr_debug("attempting to set frequency to %i kHz\n",
+			sc520_freq_table[state].frequency);
+
+	local_irq_disable();
+
+	clockspeed_reg = *cpuctl & ~0x03;
+	*cpuctl = clockspeed_reg | sc520_freq_table[state].index;
+
+	local_irq_enable();
+
+	cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
+};
+
+static int sc520_freq_verify(struct cpufreq_policy *policy)
+{
+	return cpufreq_frequency_table_verify(policy, &sc520_freq_table[0]);
+}
+
+static int sc520_freq_target(struct cpufreq_policy *policy,
+			    unsigned int target_freq,
+			    unsigned int relation)
+{
+	unsigned int newstate = 0;
+
+	if (cpufreq_frequency_table_target(policy, sc520_freq_table,
+				target_freq, relation, &newstate))
+		return -EINVAL;
+
+	sc520_freq_set_cpu_state(newstate);
+
+	return 0;
+}
+
+
+/*
+ *	Module init and exit code
+ */
+
+static int sc520_freq_cpu_init(struct cpufreq_policy *policy)
+{
+	struct cpuinfo_x86 *c = &cpu_data(0);
+	int result;
+
+	/* capability check */
+	if (c->x86_vendor != X86_VENDOR_AMD ||
+	    c->x86 != 4 || c->x86_model != 9)
+		return -ENODEV;
+
+	/* cpuinfo and default policy values */
+	policy->cpuinfo.transition_latency = 1000000; /* 1ms */
+	policy->cur = sc520_freq_get_cpu_frequency(0);
+
+	result = cpufreq_frequency_table_cpuinfo(policy, sc520_freq_table);
+	if (result)
+		return result;
+
+	cpufreq_frequency_table_get_attr(sc520_freq_table, policy->cpu);
+
+	return 0;
+}
+
+
+static int sc520_freq_cpu_exit(struct cpufreq_policy *policy)
+{
+	cpufreq_frequency_table_put_attr(policy->cpu);
+	return 0;
+}
+
+
+static struct freq_attr *sc520_freq_attr[] = {
+	&cpufreq_freq_attr_scaling_available_freqs,
+	NULL,
+};
+
+
+static struct cpufreq_driver sc520_freq_driver = {
+	.get	= sc520_freq_get_cpu_frequency,
+	.verify	= sc520_freq_verify,
+	.target	= sc520_freq_target,
+	.init	= sc520_freq_cpu_init,
+	.exit	= sc520_freq_cpu_exit,
+	.name	= "sc520_freq",
+	.owner	= THIS_MODULE,
+	.attr	= sc520_freq_attr,
+};
+
+
+static int __init sc520_freq_init(void)
+{
+	struct cpuinfo_x86 *c = &cpu_data(0);
+	int err;
+
+	/* Test if we have the right hardware */
+	if (c->x86_vendor != X86_VENDOR_AMD ||
+	    c->x86 != 4 || c->x86_model != 9) {
+		pr_debug("no Elan SC520 processor found!\n");
+		return -ENODEV;
+	}
+	cpuctl = ioremap((unsigned long)(MMCR_BASE + OFFS_CPUCTL), 1);
+	if (!cpuctl) {
+		printk(KERN_ERR "sc520_freq: error: failed to remap memory\n");
+		return -ENOMEM;
+	}
+
+	err = cpufreq_register_driver(&sc520_freq_driver);
+	if (err)
+		iounmap(cpuctl);
+
+	return err;
+}
+
+
+static void __exit sc520_freq_exit(void)
+{
+	cpufreq_unregister_driver(&sc520_freq_driver);
+	iounmap(cpuctl);
+}
+
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Sean Young <sean@mess.org>");
+MODULE_DESCRIPTION("cpufreq driver for AMD's Elan sc520 CPU");
+
+module_init(sc520_freq_init);
+module_exit(sc520_freq_exit);
+
diff -druN linux-2.6.39-libre/drivers/cpufreq/speedstep-centrino.c linux-3.0-rc7-libre/drivers/cpufreq/speedstep-centrino.c
--- linux-2.6.39-libre/drivers/cpufreq/speedstep-centrino.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/cpufreq/speedstep-centrino.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,633 @@
+/*
+ * cpufreq driver for Enhanced SpeedStep, as found in Intel's Pentium
+ * M (part of the Centrino chipset).
+ *
+ * Since the original Pentium M, most new Intel CPUs support Enhanced
+ * SpeedStep.
+ *
+ * Despite the "SpeedStep" in the name, this is almost entirely unlike
+ * traditional SpeedStep.
+ *
+ * Modelled on speedstep.c
+ *
+ * Copyright (C) 2003 Jeremy Fitzhardinge <jeremy@goop.org>
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/cpufreq.h>
+#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>
+#include <asm/cpufeature.h>
+
+#define PFX		"speedstep-centrino: "
+#define MAINTAINER	"cpufreq@vger.kernel.org"
+
+#define INTEL_MSR_RANGE	(0xffff)
+
+struct cpu_id
+{
+	__u8	x86;            /* CPU family */
+	__u8	x86_model;	/* model */
+	__u8	x86_mask;	/* stepping */
+};
+
+enum {
+	CPU_BANIAS,
+	CPU_DOTHAN_A1,
+	CPU_DOTHAN_A2,
+	CPU_DOTHAN_B0,
+	CPU_MP4HT_D0,
+	CPU_MP4HT_E0,
+};
+
+static const struct cpu_id cpu_ids[] = {
+	[CPU_BANIAS]	= { 6,  9, 5 },
+	[CPU_DOTHAN_A1]	= { 6, 13, 1 },
+	[CPU_DOTHAN_A2]	= { 6, 13, 2 },
+	[CPU_DOTHAN_B0]	= { 6, 13, 6 },
+	[CPU_MP4HT_D0]	= {15,  3, 4 },
+	[CPU_MP4HT_E0]	= {15,  4, 1 },
+};
+#define N_IDS	ARRAY_SIZE(cpu_ids)
+
+struct cpu_model
+{
+	const struct cpu_id *cpu_id;
+	const char	*model_name;
+	unsigned	max_freq; /* max clock in kHz */
+
+	struct cpufreq_frequency_table *op_points; /* clock/voltage pairs */
+};
+static int centrino_verify_cpu_id(const struct cpuinfo_x86 *c,
+				  const struct cpu_id *x);
+
+/* Operating points for current CPU */
+static DEFINE_PER_CPU(struct cpu_model *, centrino_model);
+static DEFINE_PER_CPU(const struct cpu_id *, centrino_cpu);
+
+static struct cpufreq_driver centrino_driver;
+
+#ifdef CONFIG_X86_SPEEDSTEP_CENTRINO_TABLE
+
+/* Computes the correct form for IA32_PERF_CTL MSR for a particular
+   frequency/voltage operating point; frequency in MHz, volts in mV.
+   This is stored as "index" in the structure. */
+#define OP(mhz, mv)							\
+	{								\
+		.frequency = (mhz) * 1000,				\
+		.index = (((mhz)/100) << 8) | ((mv - 700) / 16)		\
+	}
+
+/*
+ * These voltage tables were derived from the Intel Pentium M
+ * datasheet, document 25261202.pdf, Table 5.  I have verified they
+ * are consistent with my IBM ThinkPad X31, which has a 1.3GHz Pentium
+ * M.
+ */
+
+/* Ultra Low Voltage Intel Pentium M processor 900MHz (Banias) */
+static struct cpufreq_frequency_table banias_900[] =
+{
+	OP(600,  844),
+	OP(800,  988),
+	OP(900, 1004),
+	{ .frequency = CPUFREQ_TABLE_END }
+};
+
+/* Ultra Low Voltage Intel Pentium M processor 1000MHz (Banias) */
+static struct cpufreq_frequency_table banias_1000[] =
+{
+	OP(600,   844),
+	OP(800,   972),
+	OP(900,   988),
+	OP(1000, 1004),
+	{ .frequency = CPUFREQ_TABLE_END }
+};
+
+/* Low Voltage Intel Pentium M processor 1.10GHz (Banias) */
+static struct cpufreq_frequency_table banias_1100[] =
+{
+	OP( 600,  956),
+	OP( 800, 1020),
+	OP( 900, 1100),
+	OP(1000, 1164),
+	OP(1100, 1180),
+	{ .frequency = CPUFREQ_TABLE_END }
+};
+
+
+/* Low Voltage Intel Pentium M processor 1.20GHz (Banias) */
+static struct cpufreq_frequency_table banias_1200[] =
+{
+	OP( 600,  956),
+	OP( 800, 1004),
+	OP( 900, 1020),
+	OP(1000, 1100),
+	OP(1100, 1164),
+	OP(1200, 1180),
+	{ .frequency = CPUFREQ_TABLE_END }
+};
+
+/* Intel Pentium M processor 1.30GHz (Banias) */
+static struct cpufreq_frequency_table banias_1300[] =
+{
+	OP( 600,  956),
+	OP( 800, 1260),
+	OP(1000, 1292),
+	OP(1200, 1356),
+	OP(1300, 1388),
+	{ .frequency = CPUFREQ_TABLE_END }
+};
+
+/* Intel Pentium M processor 1.40GHz (Banias) */
+static struct cpufreq_frequency_table banias_1400[] =
+{
+	OP( 600,  956),
+	OP( 800, 1180),
+	OP(1000, 1308),
+	OP(1200, 1436),
+	OP(1400, 1484),
+	{ .frequency = CPUFREQ_TABLE_END }
+};
+
+/* Intel Pentium M processor 1.50GHz (Banias) */
+static struct cpufreq_frequency_table banias_1500[] =
+{
+	OP( 600,  956),
+	OP( 800, 1116),
+	OP(1000, 1228),
+	OP(1200, 1356),
+	OP(1400, 1452),
+	OP(1500, 1484),
+	{ .frequency = CPUFREQ_TABLE_END }
+};
+
+/* Intel Pentium M processor 1.60GHz (Banias) */
+static struct cpufreq_frequency_table banias_1600[] =
+{
+	OP( 600,  956),
+	OP( 800, 1036),
+	OP(1000, 1164),
+	OP(1200, 1276),
+	OP(1400, 1420),
+	OP(1600, 1484),
+	{ .frequency = CPUFREQ_TABLE_END }
+};
+
+/* Intel Pentium M processor 1.70GHz (Banias) */
+static struct cpufreq_frequency_table banias_1700[] =
+{
+	OP( 600,  956),
+	OP( 800, 1004),
+	OP(1000, 1116),
+	OP(1200, 1228),
+	OP(1400, 1308),
+	OP(1700, 1484),
+	{ .frequency = CPUFREQ_TABLE_END }
+};
+#undef OP
+
+#define _BANIAS(cpuid, max, name)	\
+{	.cpu_id		= cpuid,	\
+	.model_name	= "Intel(R) Pentium(R) M processor " name "MHz", \
+	.max_freq	= (max)*1000,	\
+	.op_points	= banias_##max,	\
+}
+#define BANIAS(max)	_BANIAS(&cpu_ids[CPU_BANIAS], max, #max)
+
+/* CPU models, their operating frequency range, and freq/voltage
+   operating points */
+static struct cpu_model models[] =
+{
+	_BANIAS(&cpu_ids[CPU_BANIAS], 900, " 900"),
+	BANIAS(1000),
+	BANIAS(1100),
+	BANIAS(1200),
+	BANIAS(1300),
+	BANIAS(1400),
+	BANIAS(1500),
+	BANIAS(1600),
+	BANIAS(1700),
+
+	/* NULL model_name is a wildcard */
+	{ &cpu_ids[CPU_DOTHAN_A1], NULL, 0, NULL },
+	{ &cpu_ids[CPU_DOTHAN_A2], NULL, 0, NULL },
+	{ &cpu_ids[CPU_DOTHAN_B0], NULL, 0, NULL },
+	{ &cpu_ids[CPU_MP4HT_D0], NULL, 0, NULL },
+	{ &cpu_ids[CPU_MP4HT_E0], NULL, 0, NULL },
+
+	{ NULL, }
+};
+#undef _BANIAS
+#undef BANIAS
+
+static int centrino_cpu_init_table(struct cpufreq_policy *policy)
+{
+	struct cpuinfo_x86 *cpu = &cpu_data(policy->cpu);
+	struct cpu_model *model;
+
+	for(model = models; model->cpu_id != NULL; model++)
+		if (centrino_verify_cpu_id(cpu, model->cpu_id) &&
+		    (model->model_name == NULL ||
+		     strcmp(cpu->x86_model_id, model->model_name) == 0))
+			break;
+
+	if (model->cpu_id == NULL) {
+		/* No match at all */
+		pr_debug("no support for CPU model \"%s\": "
+		       "send /proc/cpuinfo to " MAINTAINER "\n",
+		       cpu->x86_model_id);
+		return -ENOENT;
+	}
+
+	if (model->op_points == NULL) {
+		/* Matched a non-match */
+		pr_debug("no table support for CPU model \"%s\"\n",
+		       cpu->x86_model_id);
+		pr_debug("try using the acpi-cpufreq driver\n");
+		return -ENOENT;
+	}
+
+	per_cpu(centrino_model, policy->cpu) = model;
+
+	pr_debug("found \"%s\": max frequency: %dkHz\n",
+	       model->model_name, model->max_freq);
+
+	return 0;
+}
+
+#else
+static inline int centrino_cpu_init_table(struct cpufreq_policy *policy)
+{
+	return -ENODEV;
+}
+#endif /* CONFIG_X86_SPEEDSTEP_CENTRINO_TABLE */
+
+static int centrino_verify_cpu_id(const struct cpuinfo_x86 *c,
+				  const struct cpu_id *x)
+{
+	if ((c->x86 == x->x86) &&
+	    (c->x86_model == x->x86_model) &&
+	    (c->x86_mask == x->x86_mask))
+		return 1;
+	return 0;
+}
+
+/* To be called only after centrino_model is initialized */
+static unsigned extract_clock(unsigned msr, unsigned int cpu, int failsafe)
+{
+	int i;
+
+	/*
+	 * Extract clock in kHz from PERF_CTL value
+	 * for centrino, as some DSDTs are buggy.
+	 * Ideally, this can be done using the acpi_data structure.
+	 */
+	if ((per_cpu(centrino_cpu, cpu) == &cpu_ids[CPU_BANIAS]) ||
+	    (per_cpu(centrino_cpu, cpu) == &cpu_ids[CPU_DOTHAN_A1]) ||
+	    (per_cpu(centrino_cpu, cpu) == &cpu_ids[CPU_DOTHAN_B0])) {
+		msr = (msr >> 8) & 0xff;
+		return msr * 100000;
+	}
+
+	if ((!per_cpu(centrino_model, cpu)) ||
+	    (!per_cpu(centrino_model, cpu)->op_points))
+		return 0;
+
+	msr &= 0xffff;
+	for (i = 0;
+		per_cpu(centrino_model, cpu)->op_points[i].frequency
+							!= CPUFREQ_TABLE_END;
+	     i++) {
+		if (msr == per_cpu(centrino_model, cpu)->op_points[i].index)
+			return per_cpu(centrino_model, cpu)->
+							op_points[i].frequency;
+	}
+	if (failsafe)
+		return per_cpu(centrino_model, cpu)->op_points[i-1].frequency;
+	else
+		return 0;
+}
+
+/* Return the current CPU frequency in kHz */
+static unsigned int get_cur_freq(unsigned int cpu)
+{
+	unsigned l, h;
+	unsigned clock_freq;
+
+	rdmsr_on_cpu(cpu, MSR_IA32_PERF_STATUS, &l, &h);
+	clock_freq = extract_clock(l, cpu, 0);
+
+	if (unlikely(clock_freq == 0)) {
+		/*
+		 * On some CPUs, we can see transient MSR values (which are
+		 * not present in _PSS), while CPU is doing some automatic
+		 * P-state transition (like TM2). Get the last freq set 
+		 * in PERF_CTL.
+		 */
+		rdmsr_on_cpu(cpu, MSR_IA32_PERF_CTL, &l, &h);
+		clock_freq = extract_clock(l, cpu, 1);
+	}
+	return clock_freq;
+}
+
+
+static int centrino_cpu_init(struct cpufreq_policy *policy)
+{
+	struct cpuinfo_x86 *cpu = &cpu_data(policy->cpu);
+	unsigned freq;
+	unsigned l, h;
+	int ret;
+	int i;
+
+	/* Only Intel makes Enhanced Speedstep-capable CPUs */
+	if (cpu->x86_vendor != X86_VENDOR_INTEL ||
+	    !cpu_has(cpu, X86_FEATURE_EST))
+		return -ENODEV;
+
+	if (cpu_has(cpu, X86_FEATURE_CONSTANT_TSC))
+		centrino_driver.flags |= CPUFREQ_CONST_LOOPS;
+
+	if (policy->cpu != 0)
+		return -ENODEV;
+
+	for (i = 0; i < N_IDS; i++)
+		if (centrino_verify_cpu_id(cpu, &cpu_ids[i]))
+			break;
+
+	if (i != N_IDS)
+		per_cpu(centrino_cpu, policy->cpu) = &cpu_ids[i];
+
+	if (!per_cpu(centrino_cpu, policy->cpu)) {
+		pr_debug("found unsupported CPU with "
+		"Enhanced SpeedStep: send /proc/cpuinfo to "
+		MAINTAINER "\n");
+		return -ENODEV;
+	}
+
+	if (centrino_cpu_init_table(policy)) {
+		return -ENODEV;
+	}
+
+	/* Check to see if Enhanced SpeedStep is enabled, and try to
+	   enable it if not. */
+	rdmsr(MSR_IA32_MISC_ENABLE, l, h);
+
+	if (!(l & MSR_IA32_MISC_ENABLE_ENHANCED_SPEEDSTEP)) {
+		l |= MSR_IA32_MISC_ENABLE_ENHANCED_SPEEDSTEP;
+		pr_debug("trying to enable Enhanced SpeedStep (%x)\n", l);
+		wrmsr(MSR_IA32_MISC_ENABLE, l, h);
+
+		/* check to see if it stuck */
+		rdmsr(MSR_IA32_MISC_ENABLE, l, h);
+		if (!(l & MSR_IA32_MISC_ENABLE_ENHANCED_SPEEDSTEP)) {
+			printk(KERN_INFO PFX
+				"couldn't enable Enhanced SpeedStep\n");
+			return -ENODEV;
+		}
+	}
+
+	freq = get_cur_freq(policy->cpu);
+	policy->cpuinfo.transition_latency = 10000;
+						/* 10uS transition latency */
+	policy->cur = freq;
+
+	pr_debug("centrino_cpu_init: cur=%dkHz\n", policy->cur);
+
+	ret = cpufreq_frequency_table_cpuinfo(policy,
+		per_cpu(centrino_model, policy->cpu)->op_points);
+	if (ret)
+		return (ret);
+
+	cpufreq_frequency_table_get_attr(
+		per_cpu(centrino_model, policy->cpu)->op_points, policy->cpu);
+
+	return 0;
+}
+
+static int centrino_cpu_exit(struct cpufreq_policy *policy)
+{
+	unsigned int cpu = policy->cpu;
+
+	if (!per_cpu(centrino_model, cpu))
+		return -ENODEV;
+
+	cpufreq_frequency_table_put_attr(cpu);
+
+	per_cpu(centrino_model, cpu) = NULL;
+
+	return 0;
+}
+
+/**
+ * centrino_verify - verifies a new CPUFreq policy
+ * @policy: new policy
+ *
+ * Limit must be within this model's frequency range at least one
+ * border included.
+ */
+static int centrino_verify (struct cpufreq_policy *policy)
+{
+	return cpufreq_frequency_table_verify(policy,
+			per_cpu(centrino_model, policy->cpu)->op_points);
+}
+
+/**
+ * centrino_setpolicy - set a new CPUFreq policy
+ * @policy: new policy
+ * @target_freq: the target frequency
+ * @relation: how that frequency relates to achieved frequency
+ *	(CPUFREQ_RELATION_L or CPUFREQ_RELATION_H)
+ *
+ * Sets a new CPUFreq policy.
+ */
+static int centrino_target (struct cpufreq_policy *policy,
+			    unsigned int target_freq,
+			    unsigned int relation)
+{
+	unsigned int    newstate = 0;
+	unsigned int	msr, oldmsr = 0, h = 0, cpu = policy->cpu;
+	struct cpufreq_freqs	freqs;
+	int			retval = 0;
+	unsigned int		j, k, first_cpu, tmp;
+	cpumask_var_t covered_cpus;
+
+	if (unlikely(!zalloc_cpumask_var(&covered_cpus, GFP_KERNEL)))
+		return -ENOMEM;
+
+	if (unlikely(per_cpu(centrino_model, cpu) == NULL)) {
+		retval = -ENODEV;
+		goto out;
+	}
+
+	if (unlikely(cpufreq_frequency_table_target(policy,
+			per_cpu(centrino_model, cpu)->op_points,
+			target_freq,
+			relation,
+			&newstate))) {
+		retval = -EINVAL;
+		goto out;
+	}
+
+	first_cpu = 1;
+	for_each_cpu(j, policy->cpus) {
+		int good_cpu;
+
+		/* cpufreq holds the hotplug lock, so we are safe here */
+		if (!cpu_online(j))
+			continue;
+
+		/*
+		 * Support for SMP systems.
+		 * Make sure we are running on CPU that wants to change freq
+		 */
+		if (policy->shared_type == CPUFREQ_SHARED_TYPE_ANY)
+			good_cpu = cpumask_any_and(policy->cpus,
+						   cpu_online_mask);
+		else
+			good_cpu = j;
+
+		if (good_cpu >= nr_cpu_ids) {
+			pr_debug("couldn't limit to CPUs in this domain\n");
+			retval = -EAGAIN;
+			if (first_cpu) {
+				/* We haven't started the transition yet. */
+				goto out;
+			}
+			break;
+		}
+
+		msr = per_cpu(centrino_model, cpu)->op_points[newstate].index;
+
+		if (first_cpu) {
+			rdmsr_on_cpu(good_cpu, MSR_IA32_PERF_CTL, &oldmsr, &h);
+			if (msr == (oldmsr & 0xffff)) {
+				pr_debug("no change needed - msr was and needs "
+					"to be %x\n", oldmsr);
+				retval = 0;
+				goto out;
+			}
+
+			freqs.old = extract_clock(oldmsr, cpu, 0);
+			freqs.new = extract_clock(msr, cpu, 0);
+
+			pr_debug("target=%dkHz old=%d new=%d msr=%04x\n",
+				target_freq, freqs.old, freqs.new, msr);
+
+			for_each_cpu(k, policy->cpus) {
+				if (!cpu_online(k))
+					continue;
+				freqs.cpu = k;
+				cpufreq_notify_transition(&freqs,
+					CPUFREQ_PRECHANGE);
+			}
+
+			first_cpu = 0;
+			/* all but 16 LSB are reserved, treat them with care */
+			oldmsr &= ~0xffff;
+			msr &= 0xffff;
+			oldmsr |= msr;
+		}
+
+		wrmsr_on_cpu(good_cpu, MSR_IA32_PERF_CTL, oldmsr, h);
+		if (policy->shared_type == CPUFREQ_SHARED_TYPE_ANY)
+			break;
+
+		cpumask_set_cpu(j, covered_cpus);
+	}
+
+	for_each_cpu(k, policy->cpus) {
+		if (!cpu_online(k))
+			continue;
+		freqs.cpu = k;
+		cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
+	}
+
+	if (unlikely(retval)) {
+		/*
+		 * We have failed halfway through the frequency change.
+		 * We have sent callbacks to policy->cpus and
+		 * MSRs have already been written on coverd_cpus.
+		 * Best effort undo..
+		 */
+
+		for_each_cpu(j, covered_cpus)
+			wrmsr_on_cpu(j, MSR_IA32_PERF_CTL, oldmsr, h);
+
+		tmp = freqs.new;
+		freqs.new = freqs.old;
+		freqs.old = tmp;
+		for_each_cpu(j, policy->cpus) {
+			if (!cpu_online(j))
+				continue;
+			cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
+			cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
+		}
+	}
+	retval = 0;
+
+out:
+	free_cpumask_var(covered_cpus);
+	return retval;
+}
+
+static struct freq_attr* centrino_attr[] = {
+	&cpufreq_freq_attr_scaling_available_freqs,
+	NULL,
+};
+
+static struct cpufreq_driver centrino_driver = {
+	.name		= "centrino", /* should be speedstep-centrino,
+					 but there's a 16 char limit */
+	.init		= centrino_cpu_init,
+	.exit		= centrino_cpu_exit,
+	.verify		= centrino_verify,
+	.target		= centrino_target,
+	.get		= get_cur_freq,
+	.attr           = centrino_attr,
+	.owner		= THIS_MODULE,
+};
+
+
+/**
+ * centrino_init - initializes the Enhanced SpeedStep CPUFreq driver
+ *
+ * Initializes the Enhanced SpeedStep support. Returns -ENODEV on
+ * unsupported devices, -ENOENT if there's no voltage table for this
+ * particular CPU model, -EINVAL on problems during initiatization,
+ * and zero on success.
+ *
+ * This is quite picky.  Not only does the CPU have to advertise the
+ * "est" flag in the cpuid capability flags, we look for a specific
+ * CPU model and stepping, and we need to have the exact model name in
+ * our voltage tables.  That is, be paranoid about not releasing
+ * someone's valuable magic smoke.
+ */
+static int __init centrino_init(void)
+{
+	struct cpuinfo_x86 *cpu = &cpu_data(0);
+
+	if (!cpu_has(cpu, X86_FEATURE_EST))
+		return -ENODEV;
+
+	return cpufreq_register_driver(&centrino_driver);
+}
+
+static void __exit centrino_exit(void)
+{
+	cpufreq_unregister_driver(&centrino_driver);
+}
+
+MODULE_AUTHOR ("Jeremy Fitzhardinge <jeremy@goop.org>");
+MODULE_DESCRIPTION ("Enhanced SpeedStep driver for Intel Pentium M processors.");
+MODULE_LICENSE ("GPL");
+
+late_initcall(centrino_init);
+module_exit(centrino_exit);
diff -druN linux-2.6.39-libre/drivers/cpufreq/speedstep-ich.c linux-3.0-rc7-libre/drivers/cpufreq/speedstep-ich.c
--- linux-2.6.39-libre/drivers/cpufreq/speedstep-ich.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/cpufreq/speedstep-ich.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,448 @@
+/*
+ * (C) 2001  Dave Jones, Arjan van de ven.
+ * (C) 2002 - 2003  Dominik Brodowski <linux@brodo.de>
+ *
+ *  Licensed under the terms of the GNU GPL License version 2.
+ *  Based upon reverse engineered information, and on Intel documentation
+ *  for chipsets ICH2-M and ICH3-M.
+ *
+ *  Many thanks to Ducrot Bruno for finding and fixing the last
+ *  "missing link" for ICH2-M/ICH3-M support, and to Thomas Winkler
+ *  for extensive testing.
+ *
+ *  BIG FAT DISCLAIMER: Work in progress code. Possibly *dangerous*
+ */
+
+
+/*********************************************************************
+ *                        SPEEDSTEP - DEFINITIONS                    *
+ *********************************************************************/
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/cpufreq.h>
+#include <linux/pci.h>
+#include <linux/sched.h>
+
+#include "speedstep-lib.h"
+
+
+/* speedstep_chipset:
+ *   It is necessary to know which chipset is used. As accesses to
+ * this device occur at various places in this module, we need a
+ * static struct pci_dev * pointing to that device.
+ */
+static struct pci_dev *speedstep_chipset_dev;
+
+
+/* speedstep_processor
+ */
+static enum speedstep_processor speedstep_processor;
+
+static u32 pmbase;
+
+/*
+ *   There are only two frequency states for each processor. Values
+ * are in kHz for the time being.
+ */
+static struct cpufreq_frequency_table speedstep_freqs[] = {
+	{SPEEDSTEP_HIGH,	0},
+	{SPEEDSTEP_LOW,		0},
+	{0,			CPUFREQ_TABLE_END},
+};
+
+
+/**
+ * speedstep_find_register - read the PMBASE address
+ *
+ * Returns: -ENODEV if no register could be found
+ */
+static int speedstep_find_register(void)
+{
+	if (!speedstep_chipset_dev)
+		return -ENODEV;
+
+	/* get PMBASE */
+	pci_read_config_dword(speedstep_chipset_dev, 0x40, &pmbase);
+	if (!(pmbase & 0x01)) {
+		printk(KERN_ERR "speedstep-ich: could not find speedstep register\n");
+		return -ENODEV;
+	}
+
+	pmbase &= 0xFFFFFFFE;
+	if (!pmbase) {
+		printk(KERN_ERR "speedstep-ich: could not find speedstep register\n");
+		return -ENODEV;
+	}
+
+	pr_debug("pmbase is 0x%x\n", pmbase);
+	return 0;
+}
+
+/**
+ * speedstep_set_state - set the SpeedStep state
+ * @state: new processor frequency state (SPEEDSTEP_LOW or SPEEDSTEP_HIGH)
+ *
+ *   Tries to change the SpeedStep state.  Can be called from
+ *   smp_call_function_single.
+ */
+static void speedstep_set_state(unsigned int state)
+{
+	u8 pm2_blk;
+	u8 value;
+	unsigned long flags;
+
+	if (state > 0x1)
+		return;
+
+	/* Disable IRQs */
+	local_irq_save(flags);
+
+	/* read state */
+	value = inb(pmbase + 0x50);
+
+	pr_debug("read at pmbase 0x%x + 0x50 returned 0x%x\n", pmbase, value);
+
+	/* write new state */
+	value &= 0xFE;
+	value |= state;
+
+	pr_debug("writing 0x%x to pmbase 0x%x + 0x50\n", value, pmbase);
+
+	/* Disable bus master arbitration */
+	pm2_blk = inb(pmbase + 0x20);
+	pm2_blk |= 0x01;
+	outb(pm2_blk, (pmbase + 0x20));
+
+	/* Actual transition */
+	outb(value, (pmbase + 0x50));
+
+	/* Restore bus master arbitration */
+	pm2_blk &= 0xfe;
+	outb(pm2_blk, (pmbase + 0x20));
+
+	/* check if transition was successful */
+	value = inb(pmbase + 0x50);
+
+	/* Enable IRQs */
+	local_irq_restore(flags);
+
+	pr_debug("read at pmbase 0x%x + 0x50 returned 0x%x\n", pmbase, value);
+
+	if (state == (value & 0x1))
+		pr_debug("change to %u MHz succeeded\n",
+			speedstep_get_frequency(speedstep_processor) / 1000);
+	else
+		printk(KERN_ERR "cpufreq: change failed - I/O error\n");
+
+	return;
+}
+
+/* Wrapper for smp_call_function_single. */
+static void _speedstep_set_state(void *_state)
+{
+	speedstep_set_state(*(unsigned int *)_state);
+}
+
+/**
+ * speedstep_activate - activate SpeedStep control in the chipset
+ *
+ *   Tries to activate the SpeedStep status and control registers.
+ * Returns -EINVAL on an unsupported chipset, and zero on success.
+ */
+static int speedstep_activate(void)
+{
+	u16 value = 0;
+
+	if (!speedstep_chipset_dev)
+		return -EINVAL;
+
+	pci_read_config_word(speedstep_chipset_dev, 0x00A0, &value);
+	if (!(value & 0x08)) {
+		value |= 0x08;
+		pr_debug("activating SpeedStep (TM) registers\n");
+		pci_write_config_word(speedstep_chipset_dev, 0x00A0, value);
+	}
+
+	return 0;
+}
+
+
+/**
+ * speedstep_detect_chipset - detect the Southbridge which contains SpeedStep logic
+ *
+ *   Detects ICH2-M, ICH3-M and ICH4-M so far. The pci_dev points to
+ * the LPC bridge / PM module which contains all power-management
+ * functions. Returns the SPEEDSTEP_CHIPSET_-number for the detected
+ * chipset, or zero on failure.
+ */
+static unsigned int speedstep_detect_chipset(void)
+{
+	speedstep_chipset_dev = pci_get_subsys(PCI_VENDOR_ID_INTEL,
+			      PCI_DEVICE_ID_INTEL_82801DB_12,
+			      PCI_ANY_ID, PCI_ANY_ID,
+			      NULL);
+	if (speedstep_chipset_dev)
+		return 4; /* 4-M */
+
+	speedstep_chipset_dev = pci_get_subsys(PCI_VENDOR_ID_INTEL,
+			      PCI_DEVICE_ID_INTEL_82801CA_12,
+			      PCI_ANY_ID, PCI_ANY_ID,
+			      NULL);
+	if (speedstep_chipset_dev)
+		return 3; /* 3-M */
+
+
+	speedstep_chipset_dev = pci_get_subsys(PCI_VENDOR_ID_INTEL,
+			      PCI_DEVICE_ID_INTEL_82801BA_10,
+			      PCI_ANY_ID, PCI_ANY_ID,
+			      NULL);
+	if (speedstep_chipset_dev) {
+		/* speedstep.c causes lockups on Dell Inspirons 8000 and
+		 * 8100 which use a pretty old revision of the 82815
+		 * host brige. Abort on these systems.
+		 */
+		static struct pci_dev *hostbridge;
+
+		hostbridge  = pci_get_subsys(PCI_VENDOR_ID_INTEL,
+			      PCI_DEVICE_ID_INTEL_82815_MC,
+			      PCI_ANY_ID, PCI_ANY_ID,
+			      NULL);
+
+		if (!hostbridge)
+			return 2; /* 2-M */
+
+		if (hostbridge->revision < 5) {
+			pr_debug("hostbridge does not support speedstep\n");
+			speedstep_chipset_dev = NULL;
+			pci_dev_put(hostbridge);
+			return 0;
+		}
+
+		pci_dev_put(hostbridge);
+		return 2; /* 2-M */
+	}
+
+	return 0;
+}
+
+static void get_freq_data(void *_speed)
+{
+	unsigned int *speed = _speed;
+
+	*speed = speedstep_get_frequency(speedstep_processor);
+}
+
+static unsigned int speedstep_get(unsigned int cpu)
+{
+	unsigned int speed;
+
+	/* You're supposed to ensure CPU is online. */
+	if (smp_call_function_single(cpu, get_freq_data, &speed, 1) != 0)
+		BUG();
+
+	pr_debug("detected %u kHz as current frequency\n", speed);
+	return speed;
+}
+
+/**
+ * speedstep_target - set a new CPUFreq policy
+ * @policy: new policy
+ * @target_freq: the target frequency
+ * @relation: how that frequency relates to achieved frequency
+ *	(CPUFREQ_RELATION_L or CPUFREQ_RELATION_H)
+ *
+ * Sets a new CPUFreq policy.
+ */
+static int speedstep_target(struct cpufreq_policy *policy,
+			     unsigned int target_freq,
+			     unsigned int relation)
+{
+	unsigned int newstate = 0, policy_cpu;
+	struct cpufreq_freqs freqs;
+	int i;
+
+	if (cpufreq_frequency_table_target(policy, &speedstep_freqs[0],
+				target_freq, relation, &newstate))
+		return -EINVAL;
+
+	policy_cpu = cpumask_any_and(policy->cpus, cpu_online_mask);
+	freqs.old = speedstep_get(policy_cpu);
+	freqs.new = speedstep_freqs[newstate].frequency;
+	freqs.cpu = policy->cpu;
+
+	pr_debug("transiting from %u to %u kHz\n", freqs.old, freqs.new);
+
+	/* no transition necessary */
+	if (freqs.old == freqs.new)
+		return 0;
+
+	for_each_cpu(i, policy->cpus) {
+		freqs.cpu = i;
+		cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
+	}
+
+	smp_call_function_single(policy_cpu, _speedstep_set_state, &newstate,
+				 true);
+
+	for_each_cpu(i, policy->cpus) {
+		freqs.cpu = i;
+		cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
+	}
+
+	return 0;
+}
+
+
+/**
+ * speedstep_verify - verifies a new CPUFreq policy
+ * @policy: new policy
+ *
+ * Limit must be within speedstep_low_freq and speedstep_high_freq, with
+ * at least one border included.
+ */
+static int speedstep_verify(struct cpufreq_policy *policy)
+{
+	return cpufreq_frequency_table_verify(policy, &speedstep_freqs[0]);
+}
+
+struct get_freqs {
+	struct cpufreq_policy *policy;
+	int ret;
+};
+
+static void get_freqs_on_cpu(void *_get_freqs)
+{
+	struct get_freqs *get_freqs = _get_freqs;
+
+	get_freqs->ret =
+		speedstep_get_freqs(speedstep_processor,
+			    &speedstep_freqs[SPEEDSTEP_LOW].frequency,
+			    &speedstep_freqs[SPEEDSTEP_HIGH].frequency,
+			    &get_freqs->policy->cpuinfo.transition_latency,
+			    &speedstep_set_state);
+}
+
+static int speedstep_cpu_init(struct cpufreq_policy *policy)
+{
+	int result;
+	unsigned int policy_cpu, speed;
+	struct get_freqs gf;
+
+	/* only run on CPU to be set, or on its sibling */
+#ifdef CONFIG_SMP
+	cpumask_copy(policy->cpus, cpu_sibling_mask(policy->cpu));
+#endif
+	policy_cpu = cpumask_any_and(policy->cpus, cpu_online_mask);
+
+	/* detect low and high frequency and transition latency */
+	gf.policy = policy;
+	smp_call_function_single(policy_cpu, get_freqs_on_cpu, &gf, 1);
+	if (gf.ret)
+		return gf.ret;
+
+	/* get current speed setting */
+	speed = speedstep_get(policy_cpu);
+	if (!speed)
+		return -EIO;
+
+	pr_debug("currently at %s speed setting - %i MHz\n",
+		(speed == speedstep_freqs[SPEEDSTEP_LOW].frequency)
+		? "low" : "high",
+		(speed / 1000));
+
+	/* cpuinfo and default policy values */
+	policy->cur = speed;
+
+	result = cpufreq_frequency_table_cpuinfo(policy, speedstep_freqs);
+	if (result)
+		return result;
+
+	cpufreq_frequency_table_get_attr(speedstep_freqs, policy->cpu);
+
+	return 0;
+}
+
+
+static int speedstep_cpu_exit(struct cpufreq_policy *policy)
+{
+	cpufreq_frequency_table_put_attr(policy->cpu);
+	return 0;
+}
+
+static struct freq_attr *speedstep_attr[] = {
+	&cpufreq_freq_attr_scaling_available_freqs,
+	NULL,
+};
+
+
+static struct cpufreq_driver speedstep_driver = {
+	.name	= "speedstep-ich",
+	.verify	= speedstep_verify,
+	.target	= speedstep_target,
+	.init	= speedstep_cpu_init,
+	.exit	= speedstep_cpu_exit,
+	.get	= speedstep_get,
+	.owner	= THIS_MODULE,
+	.attr	= speedstep_attr,
+};
+
+
+/**
+ * speedstep_init - initializes the SpeedStep CPUFreq driver
+ *
+ *   Initializes the SpeedStep support. Returns -ENODEV on unsupported
+ * devices, -EINVAL on problems during initiatization, and zero on
+ * success.
+ */
+static int __init speedstep_init(void)
+{
+	/* detect processor */
+	speedstep_processor = speedstep_detect_processor();
+	if (!speedstep_processor) {
+		pr_debug("Intel(R) SpeedStep(TM) capable processor "
+				"not found\n");
+		return -ENODEV;
+	}
+
+	/* detect chipset */
+	if (!speedstep_detect_chipset()) {
+		pr_debug("Intel(R) SpeedStep(TM) for this chipset not "
+				"(yet) available.\n");
+		return -ENODEV;
+	}
+
+	/* activate speedstep support */
+	if (speedstep_activate()) {
+		pci_dev_put(speedstep_chipset_dev);
+		return -EINVAL;
+	}
+
+	if (speedstep_find_register())
+		return -ENODEV;
+
+	return cpufreq_register_driver(&speedstep_driver);
+}
+
+
+/**
+ * speedstep_exit - unregisters SpeedStep support
+ *
+ *   Unregisters SpeedStep support.
+ */
+static void __exit speedstep_exit(void)
+{
+	pci_dev_put(speedstep_chipset_dev);
+	cpufreq_unregister_driver(&speedstep_driver);
+}
+
+
+MODULE_AUTHOR("Dave Jones <davej@redhat.com>, "
+		"Dominik Brodowski <linux@brodo.de>");
+MODULE_DESCRIPTION("Speedstep driver for Intel mobile processors on chipsets "
+		"with ICH-M southbridges.");
+MODULE_LICENSE("GPL");
+
+module_init(speedstep_init);
+module_exit(speedstep_exit);
diff -druN linux-2.6.39-libre/drivers/cpufreq/speedstep-lib.c linux-3.0-rc7-libre/drivers/cpufreq/speedstep-lib.c
--- linux-2.6.39-libre/drivers/cpufreq/speedstep-lib.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/cpufreq/speedstep-lib.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,478 @@
+/*
+ * (C) 2002 - 2003 Dominik Brodowski <linux@brodo.de>
+ *
+ *  Licensed under the terms of the GNU GPL License version 2.
+ *
+ *  Library for common functions for Intel SpeedStep v.1 and v.2 support
+ *
+ *  BIG FAT DISCLAIMER: Work in progress code. Possibly *dangerous*
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/init.h>
+#include <linux/cpufreq.h>
+
+#include <asm/msr.h>
+#include <asm/tsc.h>
+#include "speedstep-lib.h"
+
+#define PFX "speedstep-lib: "
+
+#ifdef CONFIG_X86_SPEEDSTEP_RELAXED_CAP_CHECK
+static int relaxed_check;
+#else
+#define relaxed_check 0
+#endif
+
+/*********************************************************************
+ *                   GET PROCESSOR CORE SPEED IN KHZ                 *
+ *********************************************************************/
+
+static unsigned int pentium3_get_frequency(enum speedstep_processor processor)
+{
+	/* See table 14 of p3_ds.pdf and table 22 of 29834003.pdf */
+	struct {
+		unsigned int ratio;	/* Frequency Multiplier (x10) */
+		u8 bitmap;		/* power on configuration bits
+					[27, 25:22] (in MSR 0x2a) */
+	} msr_decode_mult[] = {
+		{ 30, 0x01 },
+		{ 35, 0x05 },
+		{ 40, 0x02 },
+		{ 45, 0x06 },
+		{ 50, 0x00 },
+		{ 55, 0x04 },
+		{ 60, 0x0b },
+		{ 65, 0x0f },
+		{ 70, 0x09 },
+		{ 75, 0x0d },
+		{ 80, 0x0a },
+		{ 85, 0x26 },
+		{ 90, 0x20 },
+		{ 100, 0x2b },
+		{ 0, 0xff }	/* error or unknown value */
+	};
+
+	/* PIII(-M) FSB settings: see table b1-b of 24547206.pdf */
+	struct {
+		unsigned int value;	/* Front Side Bus speed in MHz */
+		u8 bitmap;		/* power on configuration bits [18: 19]
+					(in MSR 0x2a) */
+	} msr_decode_fsb[] = {
+		{  66, 0x0 },
+		{ 100, 0x2 },
+		{ 133, 0x1 },
+		{   0, 0xff}
+	};
+
+	u32 msr_lo, msr_tmp;
+	int i = 0, j = 0;
+
+	/* read MSR 0x2a - we only need the low 32 bits */
+	rdmsr(MSR_IA32_EBL_CR_POWERON, msr_lo, msr_tmp);
+	pr_debug("P3 - MSR_IA32_EBL_CR_POWERON: 0x%x 0x%x\n", msr_lo, msr_tmp);
+	msr_tmp = msr_lo;
+
+	/* decode the FSB */
+	msr_tmp &= 0x00c0000;
+	msr_tmp >>= 18;
+	while (msr_tmp != msr_decode_fsb[i].bitmap) {
+		if (msr_decode_fsb[i].bitmap == 0xff)
+			return 0;
+		i++;
+	}
+
+	/* decode the multiplier */
+	if (processor == SPEEDSTEP_CPU_PIII_C_EARLY) {
+		pr_debug("workaround for early PIIIs\n");
+		msr_lo &= 0x03c00000;
+	} else
+		msr_lo &= 0x0bc00000;
+	msr_lo >>= 22;
+	while (msr_lo != msr_decode_mult[j].bitmap) {
+		if (msr_decode_mult[j].bitmap == 0xff)
+			return 0;
+		j++;
+	}
+
+	pr_debug("speed is %u\n",
+		(msr_decode_mult[j].ratio * msr_decode_fsb[i].value * 100));
+
+	return msr_decode_mult[j].ratio * msr_decode_fsb[i].value * 100;
+}
+
+
+static unsigned int pentiumM_get_frequency(void)
+{
+	u32 msr_lo, msr_tmp;
+
+	rdmsr(MSR_IA32_EBL_CR_POWERON, msr_lo, msr_tmp);
+	pr_debug("PM - MSR_IA32_EBL_CR_POWERON: 0x%x 0x%x\n", msr_lo, msr_tmp);
+
+	/* see table B-2 of 24547212.pdf */
+	if (msr_lo & 0x00040000) {
+		printk(KERN_DEBUG PFX "PM - invalid FSB: 0x%x 0x%x\n",
+				msr_lo, msr_tmp);
+		return 0;
+	}
+
+	msr_tmp = (msr_lo >> 22) & 0x1f;
+	pr_debug("bits 22-26 are 0x%x, speed is %u\n",
+			msr_tmp, (msr_tmp * 100 * 1000));
+
+	return msr_tmp * 100 * 1000;
+}
+
+static unsigned int pentium_core_get_frequency(void)
+{
+	u32 fsb = 0;
+	u32 msr_lo, msr_tmp;
+	int ret;
+
+	rdmsr(MSR_FSB_FREQ, msr_lo, msr_tmp);
+	/* see table B-2 of 25366920.pdf */
+	switch (msr_lo & 0x07) {
+	case 5:
+		fsb = 100000;
+		break;
+	case 1:
+		fsb = 133333;
+		break;
+	case 3:
+		fsb = 166667;
+		break;
+	case 2:
+		fsb = 200000;
+		break;
+	case 0:
+		fsb = 266667;
+		break;
+	case 4:
+		fsb = 333333;
+		break;
+	default:
+		printk(KERN_ERR "PCORE - MSR_FSB_FREQ undefined value");
+	}
+
+	rdmsr(MSR_IA32_EBL_CR_POWERON, msr_lo, msr_tmp);
+	pr_debug("PCORE - MSR_IA32_EBL_CR_POWERON: 0x%x 0x%x\n",
+			msr_lo, msr_tmp);
+
+	msr_tmp = (msr_lo >> 22) & 0x1f;
+	pr_debug("bits 22-26 are 0x%x, speed is %u\n",
+			msr_tmp, (msr_tmp * fsb));
+
+	ret = (msr_tmp * fsb);
+	return ret;
+}
+
+
+static unsigned int pentium4_get_frequency(void)
+{
+	struct cpuinfo_x86 *c = &boot_cpu_data;
+	u32 msr_lo, msr_hi, mult;
+	unsigned int fsb = 0;
+	unsigned int ret;
+	u8 fsb_code;
+
+	/* Pentium 4 Model 0 and 1 do not have the Core Clock Frequency
+	 * to System Bus Frequency Ratio Field in the Processor Frequency
+	 * Configuration Register of the MSR. Therefore the current
+	 * frequency cannot be calculated and has to be measured.
+	 */
+	if (c->x86_model < 2)
+		return cpu_khz;
+
+	rdmsr(0x2c, msr_lo, msr_hi);
+
+	pr_debug("P4 - MSR_EBC_FREQUENCY_ID: 0x%x 0x%x\n", msr_lo, msr_hi);
+
+	/* decode the FSB: see IA-32 Intel (C) Architecture Software
+	 * Developer's Manual, Volume 3: System Prgramming Guide,
+	 * revision #12 in Table B-1: MSRs in the Pentium 4 and
+	 * Intel Xeon Processors, on page B-4 and B-5.
+	 */
+	fsb_code = (msr_lo >> 16) & 0x7;
+	switch (fsb_code) {
+	case 0:
+		fsb = 100 * 1000;
+		break;
+	case 1:
+		fsb = 13333 * 10;
+		break;
+	case 2:
+		fsb = 200 * 1000;
+		break;
+	}
+
+	if (!fsb)
+		printk(KERN_DEBUG PFX "couldn't detect FSB speed. "
+				"Please send an e-mail to <linux@brodo.de>\n");
+
+	/* Multiplier. */
+	mult = msr_lo >> 24;
+
+	pr_debug("P4 - FSB %u kHz; Multiplier %u; Speed %u kHz\n",
+			fsb, mult, (fsb * mult));
+
+	ret = (fsb * mult);
+	return ret;
+}
+
+
+/* Warning: may get called from smp_call_function_single. */
+unsigned int speedstep_get_frequency(enum speedstep_processor processor)
+{
+	switch (processor) {
+	case SPEEDSTEP_CPU_PCORE:
+		return pentium_core_get_frequency();
+	case SPEEDSTEP_CPU_PM:
+		return pentiumM_get_frequency();
+	case SPEEDSTEP_CPU_P4D:
+	case SPEEDSTEP_CPU_P4M:
+		return pentium4_get_frequency();
+	case SPEEDSTEP_CPU_PIII_T:
+	case SPEEDSTEP_CPU_PIII_C:
+	case SPEEDSTEP_CPU_PIII_C_EARLY:
+		return pentium3_get_frequency(processor);
+	default:
+		return 0;
+	};
+	return 0;
+}
+EXPORT_SYMBOL_GPL(speedstep_get_frequency);
+
+
+/*********************************************************************
+ *                 DETECT SPEEDSTEP-CAPABLE PROCESSOR                *
+ *********************************************************************/
+
+unsigned int speedstep_detect_processor(void)
+{
+	struct cpuinfo_x86 *c = &cpu_data(0);
+	u32 ebx, msr_lo, msr_hi;
+
+	pr_debug("x86: %x, model: %x\n", c->x86, c->x86_model);
+
+	if ((c->x86_vendor != X86_VENDOR_INTEL) ||
+	    ((c->x86 != 6) && (c->x86 != 0xF)))
+		return 0;
+
+	if (c->x86 == 0xF) {
+		/* Intel Mobile Pentium 4-M
+		 * or Intel Mobile Pentium 4 with 533 MHz FSB */
+		if (c->x86_model != 2)
+			return 0;
+
+		ebx = cpuid_ebx(0x00000001);
+		ebx &= 0x000000FF;
+
+		pr_debug("ebx value is %x, x86_mask is %x\n", ebx, c->x86_mask);
+
+		switch (c->x86_mask) {
+		case 4:
+			/*
+			 * B-stepping [M-P4-M]
+			 * sample has ebx = 0x0f, production has 0x0e.
+			 */
+			if ((ebx == 0x0e) || (ebx == 0x0f))
+				return SPEEDSTEP_CPU_P4M;
+			break;
+		case 7:
+			/*
+			 * C-stepping [M-P4-M]
+			 * needs to have ebx=0x0e, else it's a celeron:
+			 * cf. 25130917.pdf / page 7, footnote 5 even
+			 * though 25072120.pdf / page 7 doesn't say
+			 * samples are only of B-stepping...
+			 */
+			if (ebx == 0x0e)
+				return SPEEDSTEP_CPU_P4M;
+			break;
+		case 9:
+			/*
+			 * D-stepping [M-P4-M or M-P4/533]
+			 *
+			 * this is totally strange: CPUID 0x0F29 is
+			 * used by M-P4-M, M-P4/533 and(!) Celeron CPUs.
+			 * The latter need to be sorted out as they don't
+			 * support speedstep.
+			 * Celerons with CPUID 0x0F29 may have either
+			 * ebx=0x8 or 0xf -- 25130917.pdf doesn't say anything
+			 * specific.
+			 * M-P4-Ms may have either ebx=0xe or 0xf [see above]
+			 * M-P4/533 have either ebx=0xe or 0xf. [25317607.pdf]
+			 * also, M-P4M HTs have ebx=0x8, too
+			 * For now, they are distinguished by the model_id
+			 * string
+			 */
+			if ((ebx == 0x0e) ||
+				(strstr(c->x86_model_id,
+				    "Mobile Intel(R) Pentium(R) 4") != NULL))
+				return SPEEDSTEP_CPU_P4M;
+			break;
+		default:
+			break;
+		}
+		return 0;
+	}
+
+	switch (c->x86_model) {
+	case 0x0B: /* Intel PIII [Tualatin] */
+		/* cpuid_ebx(1) is 0x04 for desktop PIII,
+		 * 0x06 for mobile PIII-M */
+		ebx = cpuid_ebx(0x00000001);
+		pr_debug("ebx is %x\n", ebx);
+
+		ebx &= 0x000000FF;
+
+		if (ebx != 0x06)
+			return 0;
+
+		/* So far all PIII-M processors support SpeedStep. See
+		 * Intel's 24540640.pdf of June 2003
+		 */
+		return SPEEDSTEP_CPU_PIII_T;
+
+	case 0x08: /* Intel PIII [Coppermine] */
+
+		/* all mobile PIII Coppermines have FSB 100 MHz
+		 * ==> sort out a few desktop PIIIs. */
+		rdmsr(MSR_IA32_EBL_CR_POWERON, msr_lo, msr_hi);
+		pr_debug("Coppermine: MSR_IA32_EBL_CR_POWERON is 0x%x, 0x%x\n",
+				msr_lo, msr_hi);
+		msr_lo &= 0x00c0000;
+		if (msr_lo != 0x0080000)
+			return 0;
+
+		/*
+		 * If the processor is a mobile version,
+		 * platform ID has bit 50 set
+		 * it has SpeedStep technology if either
+		 * bit 56 or 57 is set
+		 */
+		rdmsr(MSR_IA32_PLATFORM_ID, msr_lo, msr_hi);
+		pr_debug("Coppermine: MSR_IA32_PLATFORM ID is 0x%x, 0x%x\n",
+				msr_lo, msr_hi);
+		if ((msr_hi & (1<<18)) &&
+		    (relaxed_check ? 1 : (msr_hi & (3<<24)))) {
+			if (c->x86_mask == 0x01) {
+				pr_debug("early PIII version\n");
+				return SPEEDSTEP_CPU_PIII_C_EARLY;
+			} else
+				return SPEEDSTEP_CPU_PIII_C;
+		}
+
+	default:
+		return 0;
+	}
+}
+EXPORT_SYMBOL_GPL(speedstep_detect_processor);
+
+
+/*********************************************************************
+ *                     DETECT SPEEDSTEP SPEEDS                       *
+ *********************************************************************/
+
+unsigned int speedstep_get_freqs(enum speedstep_processor processor,
+				  unsigned int *low_speed,
+				  unsigned int *high_speed,
+				  unsigned int *transition_latency,
+				  void (*set_state) (unsigned int state))
+{
+	unsigned int prev_speed;
+	unsigned int ret = 0;
+	unsigned long flags;
+	struct timeval tv1, tv2;
+
+	if ((!processor) || (!low_speed) || (!high_speed) || (!set_state))
+		return -EINVAL;
+
+	pr_debug("trying to determine both speeds\n");
+
+	/* get current speed */
+	prev_speed = speedstep_get_frequency(processor);
+	if (!prev_speed)
+		return -EIO;
+
+	pr_debug("previous speed is %u\n", prev_speed);
+
+	local_irq_save(flags);
+
+	/* switch to low state */
+	set_state(SPEEDSTEP_LOW);
+	*low_speed = speedstep_get_frequency(processor);
+	if (!*low_speed) {
+		ret = -EIO;
+		goto out;
+	}
+
+	pr_debug("low speed is %u\n", *low_speed);
+
+	/* start latency measurement */
+	if (transition_latency)
+		do_gettimeofday(&tv1);
+
+	/* switch to high state */
+	set_state(SPEEDSTEP_HIGH);
+
+	/* end latency measurement */
+	if (transition_latency)
+		do_gettimeofday(&tv2);
+
+	*high_speed = speedstep_get_frequency(processor);
+	if (!*high_speed) {
+		ret = -EIO;
+		goto out;
+	}
+
+	pr_debug("high speed is %u\n", *high_speed);
+
+	if (*low_speed == *high_speed) {
+		ret = -ENODEV;
+		goto out;
+	}
+
+	/* switch to previous state, if necessary */
+	if (*high_speed != prev_speed)
+		set_state(SPEEDSTEP_LOW);
+
+	if (transition_latency) {
+		*transition_latency = (tv2.tv_sec - tv1.tv_sec) * USEC_PER_SEC +
+			tv2.tv_usec - tv1.tv_usec;
+		pr_debug("transition latency is %u uSec\n", *transition_latency);
+
+		/* convert uSec to nSec and add 20% for safety reasons */
+		*transition_latency *= 1200;
+
+		/* check if the latency measurement is too high or too low
+		 * and set it to a safe value (500uSec) in that case
+		 */
+		if (*transition_latency > 10000000 ||
+		    *transition_latency < 50000) {
+			printk(KERN_WARNING PFX "frequency transition "
+					"measured seems out of range (%u "
+					"nSec), falling back to a safe one of"
+					"%u nSec.\n",
+					*transition_latency, 500000);
+			*transition_latency = 500000;
+		}
+	}
+
+out:
+	local_irq_restore(flags);
+	return ret;
+}
+EXPORT_SYMBOL_GPL(speedstep_get_freqs);
+
+#ifdef CONFIG_X86_SPEEDSTEP_RELAXED_CAP_CHECK
+module_param(relaxed_check, int, 0444);
+MODULE_PARM_DESC(relaxed_check,
+		"Don't do all checks for speedstep capability.");
+#endif
+
+MODULE_AUTHOR("Dominik Brodowski <linux@brodo.de>");
+MODULE_DESCRIPTION("Library for Intel SpeedStep 1 or 2 cpufreq drivers.");
+MODULE_LICENSE("GPL");
diff -druN linux-2.6.39-libre/drivers/cpufreq/speedstep-lib.h linux-3.0-rc7-libre/drivers/cpufreq/speedstep-lib.h
--- linux-2.6.39-libre/drivers/cpufreq/speedstep-lib.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/cpufreq/speedstep-lib.h	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,49 @@
+/*
+ * (C) 2002 - 2003 Dominik Brodowski <linux@brodo.de>
+ *
+ *  Licensed under the terms of the GNU GPL License version 2.
+ *
+ *  Library for common functions for Intel SpeedStep v.1 and v.2 support
+ *
+ *  BIG FAT DISCLAIMER: Work in progress code. Possibly *dangerous*
+ */
+
+
+
+/* processors */
+enum speedstep_processor {
+	SPEEDSTEP_CPU_PIII_C_EARLY = 0x00000001,  /* Coppermine core */
+	SPEEDSTEP_CPU_PIII_C	   = 0x00000002,  /* Coppermine core */
+	SPEEDSTEP_CPU_PIII_T	   = 0x00000003,  /* Tualatin core */
+	SPEEDSTEP_CPU_P4M	   = 0x00000004,  /* P4-M  */
+/* the following processors are not speedstep-capable and are not auto-detected
+ * in speedstep_detect_processor(). However, their speed can be detected using
+ * the speedstep_get_frequency() call. */
+	SPEEDSTEP_CPU_PM	   = 0xFFFFFF03,  /* Pentium M  */
+	SPEEDSTEP_CPU_P4D	   = 0xFFFFFF04,  /* desktop P4  */
+	SPEEDSTEP_CPU_PCORE	   = 0xFFFFFF05,  /* Core */
+};
+
+/* speedstep states -- only two of them */
+
+#define SPEEDSTEP_HIGH	0x00000000
+#define SPEEDSTEP_LOW	0x00000001
+
+
+/* detect a speedstep-capable processor */
+extern enum speedstep_processor speedstep_detect_processor(void);
+
+/* detect the current speed (in khz) of the processor */
+extern unsigned int speedstep_get_frequency(enum speedstep_processor processor);
+
+
+/* detect the low and high speeds of the processor. The callback
+ * set_state"'s first argument is either SPEEDSTEP_HIGH or
+ * SPEEDSTEP_LOW; the second argument is zero so that no
+ * cpufreq_notify_transition calls are initiated.
+ */
+extern unsigned int speedstep_get_freqs(enum speedstep_processor processor,
+	unsigned int *low_speed,
+	unsigned int *high_speed,
+	unsigned int *transition_latency,
+	void (*set_state) (unsigned int state));
diff -druN linux-2.6.39-libre/drivers/cpufreq/speedstep-smi.c linux-3.0-rc7-libre/drivers/cpufreq/speedstep-smi.c
--- linux-2.6.39-libre/drivers/cpufreq/speedstep-smi.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/cpufreq/speedstep-smi.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,464 @@
+/*
+ * Intel SpeedStep SMI driver.
+ *
+ * (C) 2003  Hiroshi Miura <miura@da-cha.org>
+ *
+ *  Licensed under the terms of the GNU GPL License version 2.
+ *
+ */
+
+
+/*********************************************************************
+ *                        SPEEDSTEP - DEFINITIONS                    *
+ *********************************************************************/
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/init.h>
+#include <linux/cpufreq.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <asm/ist.h>
+
+#include "speedstep-lib.h"
+
+/* speedstep system management interface port/command.
+ *
+ * These parameters are got from IST-SMI BIOS call.
+ * If user gives it, these are used.
+ *
+ */
+static int smi_port;
+static int smi_cmd;
+static unsigned int smi_sig;
+
+/* info about the processor */
+static enum speedstep_processor speedstep_processor;
+
+/*
+ * There are only two frequency states for each processor. Values
+ * are in kHz for the time being.
+ */
+static struct cpufreq_frequency_table speedstep_freqs[] = {
+	{SPEEDSTEP_HIGH,	0},
+	{SPEEDSTEP_LOW,		0},
+	{0,			CPUFREQ_TABLE_END},
+};
+
+#define GET_SPEEDSTEP_OWNER 0
+#define GET_SPEEDSTEP_STATE 1
+#define SET_SPEEDSTEP_STATE 2
+#define GET_SPEEDSTEP_FREQS 4
+
+/* how often shall the SMI call be tried if it failed, e.g. because
+ * of DMA activity going on? */
+#define SMI_TRIES 5
+
+/**
+ * speedstep_smi_ownership
+ */
+static int speedstep_smi_ownership(void)
+{
+	u32 command, result, magic, dummy;
+	u32 function = GET_SPEEDSTEP_OWNER;
+	unsigned char magic_data[] = "Copyright (c) 1999 Intel Corporation";
+
+	command = (smi_sig & 0xffffff00) | (smi_cmd & 0xff);
+	magic = virt_to_phys(magic_data);
+
+	pr_debug("trying to obtain ownership with command %x at port %x\n",
+			command, smi_port);
+
+	__asm__ __volatile__(
+		"push %%ebp\n"
+		"out %%al, (%%dx)\n"
+		"pop %%ebp\n"
+		: "=D" (result),
+		  "=a" (dummy), "=b" (dummy), "=c" (dummy), "=d" (dummy),
+		  "=S" (dummy)
+		: "a" (command), "b" (function), "c" (0), "d" (smi_port),
+		  "D" (0), "S" (magic)
+		: "memory"
+	);
+
+	pr_debug("result is %x\n", result);
+
+	return result;
+}
+
+/**
+ * speedstep_smi_get_freqs - get SpeedStep preferred & current freq.
+ * @low: the low frequency value is placed here
+ * @high: the high frequency value is placed here
+ *
+ * Only available on later SpeedStep-enabled systems, returns false results or
+ * even hangs [cf. bugme.osdl.org # 1422] on earlier systems. Empirical testing
+ * shows that the latter occurs if !(ist_info.event & 0xFFFF).
+ */
+static int speedstep_smi_get_freqs(unsigned int *low, unsigned int *high)
+{
+	u32 command, result = 0, edi, high_mhz, low_mhz, dummy;
+	u32 state = 0;
+	u32 function = GET_SPEEDSTEP_FREQS;
+
+	if (!(ist_info.event & 0xFFFF)) {
+		pr_debug("bug #1422 -- can't read freqs from BIOS\n");
+		return -ENODEV;
+	}
+
+	command = (smi_sig & 0xffffff00) | (smi_cmd & 0xff);
+
+	pr_debug("trying to determine frequencies with command %x at port %x\n",
+			command, smi_port);
+
+	__asm__ __volatile__(
+		"push %%ebp\n"
+		"out %%al, (%%dx)\n"
+		"pop %%ebp"
+		: "=a" (result),
+		  "=b" (high_mhz),
+		  "=c" (low_mhz),
+		  "=d" (state), "=D" (edi), "=S" (dummy)
+		: "a" (command),
+		  "b" (function),
+		  "c" (state),
+		  "d" (smi_port), "S" (0), "D" (0)
+	);
+
+	pr_debug("result %x, low_freq %u, high_freq %u\n",
+			result, low_mhz, high_mhz);
+
+	/* abort if results are obviously incorrect... */
+	if ((high_mhz + low_mhz) < 600)
+		return -EINVAL;
+
+	*high = high_mhz * 1000;
+	*low  = low_mhz  * 1000;
+
+	return result;
+}
+
+/**
+ * speedstep_get_state - set the SpeedStep state
+ * @state: processor frequency state (SPEEDSTEP_LOW or SPEEDSTEP_HIGH)
+ *
+ */
+static int speedstep_get_state(void)
+{
+	u32 function = GET_SPEEDSTEP_STATE;
+	u32 result, state, edi, command, dummy;
+
+	command = (smi_sig & 0xffffff00) | (smi_cmd & 0xff);
+
+	pr_debug("trying to determine current setting with command %x "
+		"at port %x\n", command, smi_port);
+
+	__asm__ __volatile__(
+		"push %%ebp\n"
+		"out %%al, (%%dx)\n"
+		"pop %%ebp\n"
+		: "=a" (result),
+		  "=b" (state), "=D" (edi),
+		  "=c" (dummy), "=d" (dummy), "=S" (dummy)
+		: "a" (command), "b" (function), "c" (0),
+		  "d" (smi_port), "S" (0), "D" (0)
+	);
+
+	pr_debug("state is %x, result is %x\n", state, result);
+
+	return state & 1;
+}
+
+
+/**
+ * speedstep_set_state - set the SpeedStep state
+ * @state: new processor frequency state (SPEEDSTEP_LOW or SPEEDSTEP_HIGH)
+ *
+ */
+static void speedstep_set_state(unsigned int state)
+{
+	unsigned int result = 0, command, new_state, dummy;
+	unsigned long flags;
+	unsigned int function = SET_SPEEDSTEP_STATE;
+	unsigned int retry = 0;
+
+	if (state > 0x1)
+		return;
+
+	/* Disable IRQs */
+	local_irq_save(flags);
+
+	command = (smi_sig & 0xffffff00) | (smi_cmd & 0xff);
+
+	pr_debug("trying to set frequency to state %u "
+		"with command %x at port %x\n",
+		state, command, smi_port);
+
+	do {
+		if (retry) {
+			pr_debug("retry %u, previous result %u, waiting...\n",
+					retry, result);
+			mdelay(retry * 50);
+		}
+		retry++;
+		__asm__ __volatile__(
+			"push %%ebp\n"
+			"out %%al, (%%dx)\n"
+			"pop %%ebp"
+			: "=b" (new_state), "=D" (result),
+			  "=c" (dummy), "=a" (dummy),
+			  "=d" (dummy), "=S" (dummy)
+			: "a" (command), "b" (function), "c" (state),
+			  "d" (smi_port), "S" (0), "D" (0)
+			);
+	} while ((new_state != state) && (retry <= SMI_TRIES));
+
+	/* enable IRQs */
+	local_irq_restore(flags);
+
+	if (new_state == state)
+		pr_debug("change to %u MHz succeeded after %u tries "
+			"with result %u\n",
+			(speedstep_freqs[new_state].frequency / 1000),
+			retry, result);
+	else
+		printk(KERN_ERR "cpufreq: change to state %u "
+			"failed with new_state %u and result %u\n",
+			state, new_state, result);
+
+	return;
+}
+
+
+/**
+ * speedstep_target - set a new CPUFreq policy
+ * @policy: new policy
+ * @target_freq: new freq
+ * @relation:
+ *
+ * Sets a new CPUFreq policy/freq.
+ */
+static int speedstep_target(struct cpufreq_policy *policy,
+			unsigned int target_freq, unsigned int relation)
+{
+	unsigned int newstate = 0;
+	struct cpufreq_freqs freqs;
+
+	if (cpufreq_frequency_table_target(policy, &speedstep_freqs[0],
+				target_freq, relation, &newstate))
+		return -EINVAL;
+
+	freqs.old = speedstep_freqs[speedstep_get_state()].frequency;
+	freqs.new = speedstep_freqs[newstate].frequency;
+	freqs.cpu = 0; /* speedstep.c is UP only driver */
+
+	if (freqs.old == freqs.new)
+		return 0;
+
+	cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
+	speedstep_set_state(newstate);
+	cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
+
+	return 0;
+}
+
+
+/**
+ * speedstep_verify - verifies a new CPUFreq policy
+ * @policy: new policy
+ *
+ * Limit must be within speedstep_low_freq and speedstep_high_freq, with
+ * at least one border included.
+ */
+static int speedstep_verify(struct cpufreq_policy *policy)
+{
+	return cpufreq_frequency_table_verify(policy, &speedstep_freqs[0]);
+}
+
+
+static int speedstep_cpu_init(struct cpufreq_policy *policy)
+{
+	int result;
+	unsigned int speed, state;
+	unsigned int *low, *high;
+
+	/* capability check */
+	if (policy->cpu != 0)
+		return -ENODEV;
+
+	result = speedstep_smi_ownership();
+	if (result) {
+		pr_debug("fails in acquiring ownership of a SMI interface.\n");
+		return -EINVAL;
+	}
+
+	/* detect low and high frequency */
+	low = &speedstep_freqs[SPEEDSTEP_LOW].frequency;
+	high = &speedstep_freqs[SPEEDSTEP_HIGH].frequency;
+
+	result = speedstep_smi_get_freqs(low, high);
+	if (result) {
+		/* fall back to speedstep_lib.c dection mechanism:
+		 * try both states out */
+		pr_debug("could not detect low and high frequencies "
+				"by SMI call.\n");
+		result = speedstep_get_freqs(speedstep_processor,
+				low, high,
+				NULL,
+				&speedstep_set_state);
+
+		if (result) {
+			pr_debug("could not detect two different speeds"
+					" -- aborting.\n");
+			return result;
+		} else
+			pr_debug("workaround worked.\n");
+	}
+
+	/* get current speed setting */
+	state = speedstep_get_state();
+	speed = speedstep_freqs[state].frequency;
+
+	pr_debug("currently at %s speed setting - %i MHz\n",
+		(speed == speedstep_freqs[SPEEDSTEP_LOW].frequency)
+		? "low" : "high",
+		(speed / 1000));
+
+	/* cpuinfo and default policy values */
+	policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL;
+	policy->cur = speed;
+
+	result = cpufreq_frequency_table_cpuinfo(policy, speedstep_freqs);
+	if (result)
+		return result;
+
+	cpufreq_frequency_table_get_attr(speedstep_freqs, policy->cpu);
+
+	return 0;
+}
+
+static int speedstep_cpu_exit(struct cpufreq_policy *policy)
+{
+	cpufreq_frequency_table_put_attr(policy->cpu);
+	return 0;
+}
+
+static unsigned int speedstep_get(unsigned int cpu)
+{
+	if (cpu)
+		return -ENODEV;
+	return speedstep_get_frequency(speedstep_processor);
+}
+
+
+static int speedstep_resume(struct cpufreq_policy *policy)
+{
+	int result = speedstep_smi_ownership();
+
+	if (result)
+		pr_debug("fails in re-acquiring ownership of a SMI interface.\n");
+
+	return result;
+}
+
+static struct freq_attr *speedstep_attr[] = {
+	&cpufreq_freq_attr_scaling_available_freqs,
+	NULL,
+};
+
+static struct cpufreq_driver speedstep_driver = {
+	.name		= "speedstep-smi",
+	.verify		= speedstep_verify,
+	.target		= speedstep_target,
+	.init		= speedstep_cpu_init,
+	.exit		= speedstep_cpu_exit,
+	.get		= speedstep_get,
+	.resume		= speedstep_resume,
+	.owner		= THIS_MODULE,
+	.attr		= speedstep_attr,
+};
+
+/**
+ * speedstep_init - initializes the SpeedStep CPUFreq driver
+ *
+ *   Initializes the SpeedStep support. Returns -ENODEV on unsupported
+ * BIOS, -EINVAL on problems during initiatization, and zero on
+ * success.
+ */
+static int __init speedstep_init(void)
+{
+	speedstep_processor = speedstep_detect_processor();
+
+	switch (speedstep_processor) {
+	case SPEEDSTEP_CPU_PIII_T:
+	case SPEEDSTEP_CPU_PIII_C:
+	case SPEEDSTEP_CPU_PIII_C_EARLY:
+		break;
+	default:
+		speedstep_processor = 0;
+	}
+
+	if (!speedstep_processor) {
+		pr_debug("No supported Intel CPU detected.\n");
+		return -ENODEV;
+	}
+
+	pr_debug("signature:0x%.8ulx, command:0x%.8ulx, "
+		"event:0x%.8ulx, perf_level:0x%.8ulx.\n",
+		ist_info.signature, ist_info.command,
+		ist_info.event, ist_info.perf_level);
+
+	/* Error if no IST-SMI BIOS or no PARM
+		 sig= 'ISGE' aka 'Intel Speedstep Gate E' */
+	if ((ist_info.signature !=  0x47534943) && (
+	    (smi_port == 0) || (smi_cmd == 0)))
+		return -ENODEV;
+
+	if (smi_sig == 1)
+		smi_sig = 0x47534943;
+	else
+		smi_sig = ist_info.signature;
+
+	/* setup smi_port from MODLULE_PARM or BIOS */
+	if ((smi_port > 0xff) || (smi_port < 0))
+		return -EINVAL;
+	else if (smi_port == 0)
+		smi_port = ist_info.command & 0xff;
+
+	if ((smi_cmd > 0xff) || (smi_cmd < 0))
+		return -EINVAL;
+	else if (smi_cmd == 0)
+		smi_cmd = (ist_info.command >> 16) & 0xff;
+
+	return cpufreq_register_driver(&speedstep_driver);
+}
+
+
+/**
+ * speedstep_exit - unregisters SpeedStep support
+ *
+ *   Unregisters SpeedStep support.
+ */
+static void __exit speedstep_exit(void)
+{
+	cpufreq_unregister_driver(&speedstep_driver);
+}
+
+module_param(smi_port, int, 0444);
+module_param(smi_cmd,  int, 0444);
+module_param(smi_sig, uint, 0444);
+
+MODULE_PARM_DESC(smi_port, "Override the BIOS-given IST port with this value "
+		"-- Intel's default setting is 0xb2");
+MODULE_PARM_DESC(smi_cmd, "Override the BIOS-given IST command with this value "
+		"-- Intel's default setting is 0x82");
+MODULE_PARM_DESC(smi_sig, "Set to 1 to fake the IST signature when using the "
+		"SMI interface.");
+
+MODULE_AUTHOR("Hiroshi Miura");
+MODULE_DESCRIPTION("Speedstep driver for IST applet SMI interface.");
+MODULE_LICENSE("GPL");
+
+module_init(speedstep_init);
+module_exit(speedstep_exit);
diff -druN linux-2.6.39-libre/drivers/cpuidle/governors/menu.c linux-3.0-rc7-libre/drivers/cpuidle/governors/menu.c
--- linux-2.6.39-libre/drivers/cpuidle/governors/menu.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/cpuidle/governors/menu.c	2011-07-11 19:51:52.000000000 -0400
@@ -237,6 +237,7 @@
 	unsigned int power_usage = -1;
 	int i;
 	int multiplier;
+	struct timespec t;
 
 	if (data->needs_update) {
 		menu_update(dev);
@@ -251,8 +252,9 @@
 		return 0;
 
 	/* determine the expected residency time, round up */
+	t = ktime_to_timespec(tick_nohz_get_sleep_length());
 	data->expected_us =
-	    DIV_ROUND_UP((u32)ktime_to_ns(tick_nohz_get_sleep_length()), 1000);
+		t.tv_sec * USEC_PER_SEC + t.tv_nsec / NSEC_PER_USEC;
 
 
 	data->bucket = which_bucket(data->expected_us);
diff -druN linux-2.6.39-libre/drivers/crypto/caam/caamalg.c linux-3.0-rc7-libre/drivers/crypto/caam/caamalg.c
--- linux-2.6.39-libre/drivers/crypto/caam/caamalg.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/crypto/caam/caamalg.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,1268 @@
+/*
+ * caam - Freescale FSL CAAM support for crypto API
+ *
+ * Copyright 2008-2011 Freescale Semiconductor, Inc.
+ *
+ * Based on talitos crypto API driver.
+ *
+ * relationship of job descriptors to shared descriptors (SteveC Dec 10 2008):
+ *
+ * ---------------                     ---------------
+ * | JobDesc #1  |-------------------->|  ShareDesc  |
+ * | *(packet 1) |                     |   (PDB)     |
+ * ---------------      |------------->|  (hashKey)  |
+ *       .              |              | (cipherKey) |
+ *       .              |    |-------->| (operation) |
+ * ---------------      |    |         ---------------
+ * | JobDesc #2  |------|    |
+ * | *(packet 2) |           |
+ * ---------------           |
+ *       .                   |
+ *       .                   |
+ * ---------------           |
+ * | JobDesc #3  |------------
+ * | *(packet 3) |
+ * ---------------
+ *
+ * The SharedDesc never changes for a connection unless rekeyed, but
+ * each packet will likely be in a different place. So all we need
+ * to know to process the packet is where the input is, where the
+ * output goes, and what context we want to process with. Context is
+ * in the SharedDesc, packet references in the JobDesc.
+ *
+ * So, a job desc looks like:
+ *
+ * ---------------------
+ * | Header            |
+ * | ShareDesc Pointer |
+ * | SEQ_OUT_PTR       |
+ * | (output buffer)   |
+ * | SEQ_IN_PTR        |
+ * | (input buffer)    |
+ * | LOAD (to DECO)    |
+ * ---------------------
+ */
+
+#include "compat.h"
+
+#include "regs.h"
+#include "intern.h"
+#include "desc_constr.h"
+#include "jr.h"
+#include "error.h"
+
+/*
+ * crypto alg
+ */
+#define CAAM_CRA_PRIORITY		3000
+/* max key is sum of AES_MAX_KEY_SIZE, max split key size */
+#define CAAM_MAX_KEY_SIZE		(AES_MAX_KEY_SIZE + \
+					 SHA512_DIGEST_SIZE * 2)
+/* max IV is max of AES_BLOCK_SIZE, DES3_EDE_BLOCK_SIZE */
+#define CAAM_MAX_IV_LENGTH		16
+
+/* length of descriptors text */
+#define DESC_AEAD_SHARED_TEXT_LEN	4
+#define DESC_AEAD_ENCRYPT_TEXT_LEN 	21
+#define DESC_AEAD_DECRYPT_TEXT_LEN 	24
+#define DESC_AEAD_GIVENCRYPT_TEXT_LEN 	27
+
+#ifdef DEBUG
+/* for print_hex_dumps with line references */
+#define xstr(s) str(s)
+#define str(s) #s
+#define debug(format, arg...) printk(format, arg)
+#else
+#define debug(format, arg...)
+#endif
+
+/*
+ * per-session context
+ */
+struct caam_ctx {
+	struct device *jrdev;
+	u32 *sh_desc;
+	dma_addr_t shared_desc_phys;
+	u32 class1_alg_type;
+	u32 class2_alg_type;
+	u32 alg_op;
+	u8 *key;
+	dma_addr_t key_phys;
+	unsigned int enckeylen;
+	unsigned int split_key_len;
+	unsigned int split_key_pad_len;
+	unsigned int authsize;
+};
+
+static int aead_authenc_setauthsize(struct crypto_aead *authenc,
+				    unsigned int authsize)
+{
+	struct caam_ctx *ctx = crypto_aead_ctx(authenc);
+
+	ctx->authsize = authsize;
+
+	return 0;
+}
+
+struct split_key_result {
+	struct completion completion;
+	int err;
+};
+
+static void split_key_done(struct device *dev, u32 *desc, u32 err,
+			   void *context)
+{
+	struct split_key_result *res = context;
+
+#ifdef DEBUG
+	dev_err(dev, "%s %d: err 0x%x\n", __func__, __LINE__, err);
+#endif
+	if (err) {
+		char tmp[CAAM_ERROR_STR_MAX];
+
+		dev_err(dev, "%08x: %s\n", err, caam_jr_strstatus(tmp, err));
+	}
+
+	res->err = err;
+
+	complete(&res->completion);
+}
+
+/*
+get a split ipad/opad key
+
+Split key generation-----------------------------------------------
+
+[00] 0xb0810008    jobdesc: stidx=1 share=never len=8
+[01] 0x04000014        key: class2->keyreg len=20
+			@0xffe01000
+[03] 0x84410014  operation: cls2-op sha1 hmac init dec
+[04] 0x24940000     fifold: class2 msgdata-last2 len=0 imm
+[05] 0xa4000001       jump: class2 local all ->1 [06]
+[06] 0x64260028    fifostr: class2 mdsplit-jdk len=40
+			@0xffe04000
+*/
+static u32 gen_split_key(struct caam_ctx *ctx, const u8 *key_in, u32 authkeylen)
+{
+	struct device *jrdev = ctx->jrdev;
+	u32 *desc;
+	struct split_key_result result;
+	dma_addr_t dma_addr_in, dma_addr_out;
+	int ret = 0;
+
+	desc = kmalloc(CAAM_CMD_SZ * 6 + CAAM_PTR_SZ * 2, GFP_KERNEL | GFP_DMA);
+
+	init_job_desc(desc, 0);
+
+	dma_addr_in = dma_map_single(jrdev, (void *)key_in, authkeylen,
+				     DMA_TO_DEVICE);
+	if (dma_mapping_error(jrdev, dma_addr_in)) {
+		dev_err(jrdev, "unable to map key input memory\n");
+		kfree(desc);
+		return -ENOMEM;
+	}
+	append_key(desc, dma_addr_in, authkeylen, CLASS_2 |
+		       KEY_DEST_CLASS_REG);
+
+	/* Sets MDHA up into an HMAC-INIT */
+	append_operation(desc, ctx->alg_op | OP_ALG_DECRYPT |
+			     OP_ALG_AS_INIT);
+
+	/*
+	 * do a FIFO_LOAD of zero, this will trigger the internal key expansion
+	   into both pads inside MDHA
+	 */
+	append_fifo_load_as_imm(desc, NULL, 0, LDST_CLASS_2_CCB |
+				FIFOLD_TYPE_MSG | FIFOLD_TYPE_LAST2);
+
+	/*
+	 * FIFO_STORE with the explicit split-key content store
+	 * (0x26 output type)
+	 */
+	dma_addr_out = dma_map_single(jrdev, ctx->key, ctx->split_key_pad_len,
+				      DMA_FROM_DEVICE);
+	if (dma_mapping_error(jrdev, dma_addr_out)) {
+		dev_err(jrdev, "unable to map key output memory\n");
+		kfree(desc);
+		return -ENOMEM;
+	}
+	append_fifo_store(desc, dma_addr_out, ctx->split_key_len,
+			  LDST_CLASS_2_CCB | FIFOST_TYPE_SPLIT_KEK);
+
+#ifdef DEBUG
+	print_hex_dump(KERN_ERR, "ctx.key@"xstr(__LINE__)": ",
+		       DUMP_PREFIX_ADDRESS, 16, 4, key_in, authkeylen, 1);
+	print_hex_dump(KERN_ERR, "jobdesc@"xstr(__LINE__)": ",
+		       DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc), 1);
+#endif
+
+	result.err = 0;
+	init_completion(&result.completion);
+
+	ret = caam_jr_enqueue(jrdev, desc, split_key_done, &result);
+	if (!ret) {
+		/* in progress */
+		wait_for_completion_interruptible(&result.completion);
+		ret = result.err;
+#ifdef DEBUG
+		print_hex_dump(KERN_ERR, "ctx.key@"xstr(__LINE__)": ",
+			       DUMP_PREFIX_ADDRESS, 16, 4, ctx->key,
+			       ctx->split_key_pad_len, 1);
+#endif
+	}
+
+	dma_unmap_single(jrdev, dma_addr_out, ctx->split_key_pad_len,
+			 DMA_FROM_DEVICE);
+	dma_unmap_single(jrdev, dma_addr_in, authkeylen, DMA_TO_DEVICE);
+
+	kfree(desc);
+
+	return ret;
+}
+
+static int build_sh_desc_ipsec(struct caam_ctx *ctx)
+{
+	struct device *jrdev = ctx->jrdev;
+	u32 *sh_desc;
+	u32 *jump_cmd;
+	bool keys_fit_inline = 0;
+
+	/*
+	 * largest Job Descriptor and its Shared Descriptor
+	 * must both fit into the 64-word Descriptor h/w Buffer
+	 */
+	if ((DESC_AEAD_GIVENCRYPT_TEXT_LEN +
+	     DESC_AEAD_SHARED_TEXT_LEN) * CAAM_CMD_SZ +
+	    ctx->split_key_pad_len + ctx->enckeylen <= CAAM_DESC_BYTES_MAX)
+		keys_fit_inline = 1;
+
+	/* build shared descriptor for this session */
+	sh_desc = kmalloc(CAAM_CMD_SZ * DESC_AEAD_SHARED_TEXT_LEN +
+			  (keys_fit_inline ?
+			   ctx->split_key_pad_len + ctx->enckeylen :
+			   CAAM_PTR_SZ * 2), GFP_DMA | GFP_KERNEL);
+	if (!sh_desc) {
+		dev_err(jrdev, "could not allocate shared descriptor\n");
+		return -ENOMEM;
+	}
+
+	init_sh_desc(sh_desc, HDR_SAVECTX | HDR_SHARE_SERIAL);
+
+	jump_cmd = append_jump(sh_desc, CLASS_BOTH | JUMP_TEST_ALL |
+			       JUMP_COND_SHRD | JUMP_COND_SELF);
+
+	/*
+	 * process keys, starting with class 2/authentication.
+	 */
+	if (keys_fit_inline) {
+		append_key_as_imm(sh_desc, ctx->key, ctx->split_key_pad_len,
+				  ctx->split_key_len,
+				  CLASS_2 | KEY_DEST_MDHA_SPLIT | KEY_ENC);
+
+		append_key_as_imm(sh_desc, (void *)ctx->key +
+				  ctx->split_key_pad_len, ctx->enckeylen,
+				  ctx->enckeylen, CLASS_1 | KEY_DEST_CLASS_REG);
+	} else {
+		append_key(sh_desc, ctx->key_phys, ctx->split_key_len, CLASS_2 |
+			   KEY_DEST_MDHA_SPLIT | KEY_ENC);
+		append_key(sh_desc, ctx->key_phys + ctx->split_key_pad_len,
+			   ctx->enckeylen, CLASS_1 | KEY_DEST_CLASS_REG);
+	}
+
+	/* update jump cmd now that we are at the jump target */
+	set_jump_tgt_here(sh_desc, jump_cmd);
+
+	ctx->shared_desc_phys = dma_map_single(jrdev, sh_desc,
+					       desc_bytes(sh_desc),
+					       DMA_TO_DEVICE);
+	if (dma_mapping_error(jrdev, ctx->shared_desc_phys)) {
+		dev_err(jrdev, "unable to map shared descriptor\n");
+		kfree(sh_desc);
+		return -ENOMEM;
+	}
+
+	ctx->sh_desc = sh_desc;
+
+	return 0;
+}
+
+static int aead_authenc_setkey(struct crypto_aead *aead,
+			       const u8 *key, unsigned int keylen)
+{
+	/* Sizes for MDHA pads (*not* keys): MD5, SHA1, 224, 256, 384, 512 */
+	static const u8 mdpadlen[] = { 16, 20, 32, 32, 64, 64 };
+	struct caam_ctx *ctx = crypto_aead_ctx(aead);
+	struct device *jrdev = ctx->jrdev;
+	struct rtattr *rta = (void *)key;
+	struct crypto_authenc_key_param *param;
+	unsigned int authkeylen;
+	unsigned int enckeylen;
+	int ret = 0;
+
+	param = RTA_DATA(rta);
+	enckeylen = be32_to_cpu(param->enckeylen);
+
+	key += RTA_ALIGN(rta->rta_len);
+	keylen -= RTA_ALIGN(rta->rta_len);
+
+	if (keylen < enckeylen)
+		goto badkey;
+
+	authkeylen = keylen - enckeylen;
+
+	if (keylen > CAAM_MAX_KEY_SIZE)
+		goto badkey;
+
+	/* Pick class 2 key length from algorithm submask */
+	ctx->split_key_len = mdpadlen[(ctx->alg_op & OP_ALG_ALGSEL_SUBMASK) >>
+				      OP_ALG_ALGSEL_SHIFT] * 2;
+	ctx->split_key_pad_len = ALIGN(ctx->split_key_len, 16);
+
+#ifdef DEBUG
+	printk(KERN_ERR "keylen %d enckeylen %d authkeylen %d\n",
+	       keylen, enckeylen, authkeylen);
+	printk(KERN_ERR "split_key_len %d split_key_pad_len %d\n",
+	       ctx->split_key_len, ctx->split_key_pad_len);
+	print_hex_dump(KERN_ERR, "key in @"xstr(__LINE__)": ",
+		       DUMP_PREFIX_ADDRESS, 16, 4, key, keylen, 1);
+#endif
+	ctx->key = kmalloc(ctx->split_key_pad_len + enckeylen,
+			   GFP_KERNEL | GFP_DMA);
+	if (!ctx->key) {
+		dev_err(jrdev, "could not allocate key output memory\n");
+		return -ENOMEM;
+	}
+
+	ret = gen_split_key(ctx, key, authkeylen);
+	if (ret) {
+		kfree(ctx->key);
+		goto badkey;
+	}
+
+	/* postpend encryption key to auth split key */
+	memcpy(ctx->key + ctx->split_key_pad_len, key + authkeylen, enckeylen);
+
+	ctx->key_phys = dma_map_single(jrdev, ctx->key, ctx->split_key_pad_len +
+				       enckeylen, DMA_TO_DEVICE);
+	if (dma_mapping_error(jrdev, ctx->key_phys)) {
+		dev_err(jrdev, "unable to map key i/o memory\n");
+		kfree(ctx->key);
+		return -ENOMEM;
+	}
+#ifdef DEBUG
+	print_hex_dump(KERN_ERR, "ctx.key@"xstr(__LINE__)": ",
+		       DUMP_PREFIX_ADDRESS, 16, 4, ctx->key,
+		       ctx->split_key_pad_len + enckeylen, 1);
+#endif
+
+	ctx->enckeylen = enckeylen;
+
+	ret = build_sh_desc_ipsec(ctx);
+	if (ret) {
+		dma_unmap_single(jrdev, ctx->key_phys, ctx->split_key_pad_len +
+				 enckeylen, DMA_TO_DEVICE);
+		kfree(ctx->key);
+	}
+
+	return ret;
+badkey:
+	crypto_aead_set_flags(aead, CRYPTO_TFM_RES_BAD_KEY_LEN);
+	return -EINVAL;
+}
+
+struct link_tbl_entry {
+	u64 ptr;
+	u32 len;
+	u8 reserved;
+	u8 buf_pool_id;
+	u16 offset;
+};
+
+/*
+ * ipsec_esp_edesc - s/w-extended ipsec_esp descriptor
+ * @src_nents: number of segments in input scatterlist
+ * @dst_nents: number of segments in output scatterlist
+ * @assoc_nents: number of segments in associated data (SPI+Seq) scatterlist
+ * @desc: h/w descriptor (variable length; must not exceed MAX_CAAM_DESCSIZE)
+ * @link_tbl_bytes: length of dma mapped link_tbl space
+ * @link_tbl_dma: bus physical mapped address of h/w link table
+ * @hw_desc: the h/w job descriptor followed by any referenced link tables
+ */
+struct ipsec_esp_edesc {
+	int assoc_nents;
+	int src_nents;
+	int dst_nents;
+	int link_tbl_bytes;
+	dma_addr_t link_tbl_dma;
+	struct link_tbl_entry *link_tbl;
+	u32 hw_desc[0];
+};
+
+static void ipsec_esp_unmap(struct device *dev,
+			    struct ipsec_esp_edesc *edesc,
+			    struct aead_request *areq)
+{
+	dma_unmap_sg(dev, areq->assoc, edesc->assoc_nents, DMA_TO_DEVICE);
+
+	if (unlikely(areq->dst != areq->src)) {
+		dma_unmap_sg(dev, areq->src, edesc->src_nents,
+			     DMA_TO_DEVICE);
+		dma_unmap_sg(dev, areq->dst, edesc->dst_nents,
+			     DMA_FROM_DEVICE);
+	} else {
+		dma_unmap_sg(dev, areq->src, edesc->src_nents,
+			     DMA_BIDIRECTIONAL);
+	}
+
+	if (edesc->link_tbl_bytes)
+		dma_unmap_single(dev, edesc->link_tbl_dma,
+				 edesc->link_tbl_bytes,
+				 DMA_TO_DEVICE);
+}
+
+/*
+ * ipsec_esp descriptor callbacks
+ */
+static void ipsec_esp_encrypt_done(struct device *jrdev, u32 *desc, u32 err,
+				   void *context)
+{
+	struct aead_request *areq = context;
+	struct ipsec_esp_edesc *edesc;
+#ifdef DEBUG
+	struct crypto_aead *aead = crypto_aead_reqtfm(areq);
+	int ivsize = crypto_aead_ivsize(aead);
+	struct caam_ctx *ctx = crypto_aead_ctx(aead);
+
+	dev_err(jrdev, "%s %d: err 0x%x\n", __func__, __LINE__, err);
+#endif
+	edesc = (struct ipsec_esp_edesc *)((char *)desc -
+		 offsetof(struct ipsec_esp_edesc, hw_desc));
+
+	if (err) {
+		char tmp[CAAM_ERROR_STR_MAX];
+
+		dev_err(jrdev, "%08x: %s\n", err, caam_jr_strstatus(tmp, err));
+	}
+
+	ipsec_esp_unmap(jrdev, edesc, areq);
+
+#ifdef DEBUG
+	print_hex_dump(KERN_ERR, "assoc  @"xstr(__LINE__)": ",
+		       DUMP_PREFIX_ADDRESS, 16, 4, sg_virt(areq->assoc),
+		       areq->assoclen , 1);
+	print_hex_dump(KERN_ERR, "dstiv  @"xstr(__LINE__)": ",
+		       DUMP_PREFIX_ADDRESS, 16, 4, sg_virt(areq->src) - ivsize,
+		       edesc->src_nents ? 100 : ivsize, 1);
+	print_hex_dump(KERN_ERR, "dst    @"xstr(__LINE__)": ",
+		       DUMP_PREFIX_ADDRESS, 16, 4, sg_virt(areq->src),
+		       edesc->src_nents ? 100 : areq->cryptlen +
+		       ctx->authsize + 4, 1);
+#endif
+
+	kfree(edesc);
+
+	aead_request_complete(areq, err);
+}
+
+static void ipsec_esp_decrypt_done(struct device *jrdev, u32 *desc, u32 err,
+				   void *context)
+{
+	struct aead_request *areq = context;
+	struct ipsec_esp_edesc *edesc;
+#ifdef DEBUG
+	struct crypto_aead *aead = crypto_aead_reqtfm(areq);
+	struct caam_ctx *ctx = crypto_aead_ctx(aead);
+
+	dev_err(jrdev, "%s %d: err 0x%x\n", __func__, __LINE__, err);
+#endif
+	edesc = (struct ipsec_esp_edesc *)((char *)desc -
+		 offsetof(struct ipsec_esp_edesc, hw_desc));
+
+	if (err) {
+		char tmp[CAAM_ERROR_STR_MAX];
+
+		dev_err(jrdev, "%08x: %s\n", err, caam_jr_strstatus(tmp, err));
+	}
+
+	ipsec_esp_unmap(jrdev, edesc, areq);
+
+	/*
+	 * verify hw auth check passed else return -EBADMSG
+	 */
+	if ((err & JRSTA_CCBERR_ERRID_MASK) == JRSTA_CCBERR_ERRID_ICVCHK)
+		err = -EBADMSG;
+
+#ifdef DEBUG
+	print_hex_dump(KERN_ERR, "iphdrout@"xstr(__LINE__)": ",
+		       DUMP_PREFIX_ADDRESS, 16, 4,
+		       ((char *)sg_virt(areq->assoc) - sizeof(struct iphdr)),
+		       sizeof(struct iphdr) + areq->assoclen +
+		       ((areq->cryptlen > 1500) ? 1500 : areq->cryptlen) +
+		       ctx->authsize + 36, 1);
+	if (!err && edesc->link_tbl_bytes) {
+		struct scatterlist *sg = sg_last(areq->src, edesc->src_nents);
+		print_hex_dump(KERN_ERR, "sglastout@"xstr(__LINE__)": ",
+			       DUMP_PREFIX_ADDRESS, 16, 4, sg_virt(sg),
+			sg->length + ctx->authsize + 16, 1);
+	}
+#endif
+	kfree(edesc);
+
+	aead_request_complete(areq, err);
+}
+
+/*
+ * convert scatterlist to h/w link table format
+ * scatterlist must have been previously dma mapped
+ */
+static void sg_to_link_tbl(struct scatterlist *sg, int sg_count,
+			   struct link_tbl_entry *link_tbl_ptr, u32 offset)
+{
+	while (sg_count) {
+		link_tbl_ptr->ptr = sg_dma_address(sg);
+		link_tbl_ptr->len = sg_dma_len(sg);
+		link_tbl_ptr->reserved = 0;
+		link_tbl_ptr->buf_pool_id = 0;
+		link_tbl_ptr->offset = offset;
+		link_tbl_ptr++;
+		sg = sg_next(sg);
+		sg_count--;
+	}
+
+	/* set Final bit (marks end of link table) */
+	link_tbl_ptr--;
+	link_tbl_ptr->len |= 0x40000000;
+}
+
+/*
+ * fill in and submit ipsec_esp job descriptor
+ */
+static int ipsec_esp(struct ipsec_esp_edesc *edesc, struct aead_request *areq,
+		     u32 encrypt,
+		     void (*callback) (struct device *dev, u32 *desc,
+				       u32 err, void *context))
+{
+	struct crypto_aead *aead = crypto_aead_reqtfm(areq);
+	struct caam_ctx *ctx = crypto_aead_ctx(aead);
+	struct device *jrdev = ctx->jrdev;
+	u32 *desc = edesc->hw_desc, options;
+	int ret, sg_count, assoc_sg_count;
+	int ivsize = crypto_aead_ivsize(aead);
+	int authsize = ctx->authsize;
+	dma_addr_t ptr, dst_dma, src_dma;
+#ifdef DEBUG
+	u32 *sh_desc = ctx->sh_desc;
+
+	debug("assoclen %d cryptlen %d authsize %d\n",
+	      areq->assoclen, areq->cryptlen, authsize);
+	print_hex_dump(KERN_ERR, "assoc  @"xstr(__LINE__)": ",
+		       DUMP_PREFIX_ADDRESS, 16, 4, sg_virt(areq->assoc),
+		       areq->assoclen , 1);
+	print_hex_dump(KERN_ERR, "presciv@"xstr(__LINE__)": ",
+		       DUMP_PREFIX_ADDRESS, 16, 4, sg_virt(areq->src) - ivsize,
+		       edesc->src_nents ? 100 : ivsize, 1);
+	print_hex_dump(KERN_ERR, "src    @"xstr(__LINE__)": ",
+		       DUMP_PREFIX_ADDRESS, 16, 4, sg_virt(areq->src),
+			edesc->src_nents ? 100 : areq->cryptlen + authsize, 1);
+	print_hex_dump(KERN_ERR, "shrdesc@"xstr(__LINE__)": ",
+		       DUMP_PREFIX_ADDRESS, 16, 4, sh_desc,
+		       desc_bytes(sh_desc), 1);
+#endif
+	assoc_sg_count = dma_map_sg(jrdev, areq->assoc, edesc->assoc_nents ?: 1,
+				    DMA_TO_DEVICE);
+	if (areq->src == areq->dst)
+		sg_count = dma_map_sg(jrdev, areq->src, edesc->src_nents ? : 1,
+				      DMA_BIDIRECTIONAL);
+	else
+		sg_count = dma_map_sg(jrdev, areq->src, edesc->src_nents ? : 1,
+				      DMA_TO_DEVICE);
+
+	/* start auth operation */
+	append_operation(desc, ctx->class2_alg_type | OP_ALG_AS_INITFINAL |
+			 (encrypt ? : OP_ALG_ICV_ON));
+
+	/* Load FIFO with data for Class 2 CHA */
+	options = FIFOLD_CLASS_CLASS2 | FIFOLD_TYPE_MSG;
+	if (!edesc->assoc_nents) {
+		ptr = sg_dma_address(areq->assoc);
+	} else {
+		sg_to_link_tbl(areq->assoc, edesc->assoc_nents,
+			       edesc->link_tbl, 0);
+		ptr = edesc->link_tbl_dma;
+		options |= LDST_SGF;
+	}
+	append_fifo_load(desc, ptr, areq->assoclen, options);
+
+	/* copy iv from cipher/class1 input context to class2 infifo */
+	append_move(desc, MOVE_SRC_CLASS1CTX | MOVE_DEST_CLASS2INFIFO | ivsize);
+
+	if (!encrypt) {
+		u32 *jump_cmd, *uncond_jump_cmd;
+
+		/* JUMP if shared */
+		jump_cmd = append_jump(desc, JUMP_TEST_ALL | JUMP_COND_SHRD);
+
+		/* start class 1 (cipher) operation, non-shared version */
+		append_operation(desc, ctx->class1_alg_type |
+				 OP_ALG_AS_INITFINAL);
+
+		uncond_jump_cmd = append_jump(desc, 0);
+
+		set_jump_tgt_here(desc, jump_cmd);
+
+		/* start class 1 (cipher) operation, shared version */
+		append_operation(desc, ctx->class1_alg_type |
+				 OP_ALG_AS_INITFINAL | OP_ALG_AAI_DK);
+		set_jump_tgt_here(desc, uncond_jump_cmd);
+	} else
+		append_operation(desc, ctx->class1_alg_type |
+				 OP_ALG_AS_INITFINAL | encrypt);
+
+	/* load payload & instruct to class2 to snoop class 1 if encrypting */
+	options = 0;
+	if (!edesc->src_nents) {
+		src_dma = sg_dma_address(areq->src);
+	} else {
+		sg_to_link_tbl(areq->src, edesc->src_nents, edesc->link_tbl +
+			       edesc->assoc_nents, 0);
+		src_dma = edesc->link_tbl_dma + edesc->assoc_nents *
+			  sizeof(struct link_tbl_entry);
+		options |= LDST_SGF;
+	}
+	append_seq_in_ptr(desc, src_dma, areq->cryptlen + authsize, options);
+	append_seq_fifo_load(desc, areq->cryptlen, FIFOLD_CLASS_BOTH |
+			     FIFOLD_TYPE_LASTBOTH |
+			     (encrypt ? FIFOLD_TYPE_MSG1OUT2
+				      : FIFOLD_TYPE_MSG));
+
+	/* specify destination */
+	if (areq->src == areq->dst) {
+		dst_dma = src_dma;
+	} else {
+		sg_count = dma_map_sg(jrdev, areq->dst, edesc->dst_nents ? : 1,
+				      DMA_FROM_DEVICE);
+		if (!edesc->dst_nents) {
+			dst_dma = sg_dma_address(areq->dst);
+			options = 0;
+		} else {
+			sg_to_link_tbl(areq->dst, edesc->dst_nents,
+				       edesc->link_tbl + edesc->assoc_nents +
+				       edesc->src_nents, 0);
+			dst_dma = edesc->link_tbl_dma + (edesc->assoc_nents +
+				  edesc->src_nents) *
+				  sizeof(struct link_tbl_entry);
+			options = LDST_SGF;
+		}
+	}
+	append_seq_out_ptr(desc, dst_dma, areq->cryptlen + authsize, options);
+	append_seq_fifo_store(desc, areq->cryptlen, FIFOST_TYPE_MESSAGE_DATA);
+
+	/* ICV */
+	if (encrypt)
+		append_seq_store(desc, authsize, LDST_CLASS_2_CCB |
+				 LDST_SRCDST_BYTE_CONTEXT);
+	else
+		append_seq_fifo_load(desc, authsize, FIFOLD_CLASS_CLASS2 |
+				     FIFOLD_TYPE_LAST2 | FIFOLD_TYPE_ICV);
+
+#ifdef DEBUG
+	debug("job_desc_len %d\n", desc_len(desc));
+	print_hex_dump(KERN_ERR, "jobdesc@"xstr(__LINE__)": ",
+		       DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc) , 1);
+	print_hex_dump(KERN_ERR, "jdlinkt@"xstr(__LINE__)": ",
+		       DUMP_PREFIX_ADDRESS, 16, 4, edesc->link_tbl,
+			edesc->link_tbl_bytes, 1);
+#endif
+
+	ret = caam_jr_enqueue(jrdev, desc, callback, areq);
+	if (!ret)
+		ret = -EINPROGRESS;
+	else {
+		ipsec_esp_unmap(jrdev, edesc, areq);
+		kfree(edesc);
+	}
+
+	return ret;
+}
+
+/*
+ * derive number of elements in scatterlist
+ */
+static int sg_count(struct scatterlist *sg_list, int nbytes, int *chained)
+{
+	struct scatterlist *sg = sg_list;
+	int sg_nents = 0;
+
+	*chained = 0;
+	while (nbytes > 0) {
+		sg_nents++;
+		nbytes -= sg->length;
+		if (!sg_is_last(sg) && (sg + 1)->length == 0)
+			*chained = 1;
+		sg = scatterwalk_sg_next(sg);
+	}
+
+	return sg_nents;
+}
+
+/*
+ * allocate and map the ipsec_esp extended descriptor
+ */
+static struct ipsec_esp_edesc *ipsec_esp_edesc_alloc(struct aead_request *areq,
+						     int desc_bytes)
+{
+	struct crypto_aead *aead = crypto_aead_reqtfm(areq);
+	struct caam_ctx *ctx = crypto_aead_ctx(aead);
+	struct device *jrdev = ctx->jrdev;
+	gfp_t flags = areq->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP ? GFP_KERNEL :
+		      GFP_ATOMIC;
+	int assoc_nents, src_nents, dst_nents = 0, chained, link_tbl_bytes;
+	struct ipsec_esp_edesc *edesc;
+
+	assoc_nents = sg_count(areq->assoc, areq->assoclen, &chained);
+	BUG_ON(chained);
+	if (likely(assoc_nents == 1))
+		assoc_nents = 0;
+
+	src_nents = sg_count(areq->src, areq->cryptlen + ctx->authsize,
+			     &chained);
+	BUG_ON(chained);
+	if (src_nents == 1)
+		src_nents = 0;
+
+	if (unlikely(areq->dst != areq->src)) {
+		dst_nents = sg_count(areq->dst, areq->cryptlen + ctx->authsize,
+				     &chained);
+		BUG_ON(chained);
+		if (dst_nents == 1)
+			dst_nents = 0;
+	}
+
+	link_tbl_bytes = (assoc_nents + src_nents + dst_nents) *
+			 sizeof(struct link_tbl_entry);
+	debug("link_tbl_bytes %d\n", link_tbl_bytes);
+
+	/* allocate space for base edesc and hw desc commands, link tables */
+	edesc = kmalloc(sizeof(struct ipsec_esp_edesc) + desc_bytes +
+			link_tbl_bytes, GFP_DMA | flags);
+	if (!edesc) {
+		dev_err(jrdev, "could not allocate extended descriptor\n");
+		return ERR_PTR(-ENOMEM);
+	}
+
+	edesc->assoc_nents = assoc_nents;
+	edesc->src_nents = src_nents;
+	edesc->dst_nents = dst_nents;
+	edesc->link_tbl = (void *)edesc + sizeof(struct ipsec_esp_edesc) +
+			  desc_bytes;
+	edesc->link_tbl_dma = dma_map_single(jrdev, edesc->link_tbl,
+					     link_tbl_bytes, DMA_TO_DEVICE);
+	edesc->link_tbl_bytes = link_tbl_bytes;
+
+	return edesc;
+}
+
+static int aead_authenc_encrypt(struct aead_request *areq)
+{
+	struct ipsec_esp_edesc *edesc;
+	struct crypto_aead *aead = crypto_aead_reqtfm(areq);
+	struct caam_ctx *ctx = crypto_aead_ctx(aead);
+	struct device *jrdev = ctx->jrdev;
+	int ivsize = crypto_aead_ivsize(aead);
+	u32 *desc;
+	dma_addr_t iv_dma;
+
+	/* allocate extended descriptor */
+	edesc = ipsec_esp_edesc_alloc(areq, DESC_AEAD_ENCRYPT_TEXT_LEN *
+				      CAAM_CMD_SZ);
+	if (IS_ERR(edesc))
+		return PTR_ERR(edesc);
+
+	desc = edesc->hw_desc;
+
+	/* insert shared descriptor pointer */
+	init_job_desc_shared(desc, ctx->shared_desc_phys,
+			     desc_len(ctx->sh_desc), HDR_SHARE_DEFER);
+
+	iv_dma = dma_map_single(jrdev, areq->iv, ivsize, DMA_TO_DEVICE);
+	/* check dma error */
+
+	append_load(desc, iv_dma, ivsize,
+		    LDST_CLASS_1_CCB | LDST_SRCDST_BYTE_CONTEXT);
+
+	return ipsec_esp(edesc, areq, OP_ALG_ENCRYPT, ipsec_esp_encrypt_done);
+}
+
+static int aead_authenc_decrypt(struct aead_request *req)
+{
+	struct crypto_aead *aead = crypto_aead_reqtfm(req);
+	int ivsize = crypto_aead_ivsize(aead);
+	struct caam_ctx *ctx = crypto_aead_ctx(aead);
+	struct device *jrdev = ctx->jrdev;
+	struct ipsec_esp_edesc *edesc;
+	u32 *desc;
+	dma_addr_t iv_dma;
+
+	req->cryptlen -= ctx->authsize;
+
+	/* allocate extended descriptor */
+	edesc = ipsec_esp_edesc_alloc(req, DESC_AEAD_DECRYPT_TEXT_LEN *
+				      CAAM_CMD_SZ);
+	if (IS_ERR(edesc))
+		return PTR_ERR(edesc);
+
+	desc = edesc->hw_desc;
+
+	/* insert shared descriptor pointer */
+	init_job_desc_shared(desc, ctx->shared_desc_phys,
+			     desc_len(ctx->sh_desc), HDR_SHARE_DEFER);
+
+	iv_dma = dma_map_single(jrdev, req->iv, ivsize, DMA_TO_DEVICE);
+	/* check dma error */
+
+	append_load(desc, iv_dma, ivsize,
+		    LDST_CLASS_1_CCB | LDST_SRCDST_BYTE_CONTEXT);
+
+	return ipsec_esp(edesc, req, !OP_ALG_ENCRYPT, ipsec_esp_decrypt_done);
+}
+
+static int aead_authenc_givencrypt(struct aead_givcrypt_request *req)
+{
+	struct aead_request *areq = &req->areq;
+	struct ipsec_esp_edesc *edesc;
+	struct crypto_aead *aead = crypto_aead_reqtfm(areq);
+	struct caam_ctx *ctx = crypto_aead_ctx(aead);
+	struct device *jrdev = ctx->jrdev;
+	int ivsize = crypto_aead_ivsize(aead);
+	dma_addr_t iv_dma;
+	u32 *desc;
+
+	iv_dma = dma_map_single(jrdev, req->giv, ivsize, DMA_FROM_DEVICE);
+
+	debug("%s: giv %p\n", __func__, req->giv);
+
+	/* allocate extended descriptor */
+	edesc = ipsec_esp_edesc_alloc(areq, DESC_AEAD_GIVENCRYPT_TEXT_LEN *
+				      CAAM_CMD_SZ);
+	if (IS_ERR(edesc))
+		return PTR_ERR(edesc);
+
+	desc = edesc->hw_desc;
+
+	/* insert shared descriptor pointer */
+	init_job_desc_shared(desc, ctx->shared_desc_phys,
+			     desc_len(ctx->sh_desc), HDR_SHARE_DEFER);
+
+	/*
+	 * LOAD IMM Info FIFO
+	 * to DECO, Last, Padding, Random, Message, 16 bytes
+	 */
+	append_load_imm_u32(desc, NFIFOENTRY_DEST_DECO | NFIFOENTRY_LC1 |
+			    NFIFOENTRY_STYPE_PAD | NFIFOENTRY_DTYPE_MSG |
+			    NFIFOENTRY_PTYPE_RND | ivsize,
+			    LDST_SRCDST_WORD_INFO_FIFO);
+
+	/*
+	 * disable info fifo entries since the above serves as the entry
+	 * this way, the MOVE command won't generate an entry.
+	 * Note that this isn't required in more recent versions of
+	 * SEC as a MOVE that doesn't do info FIFO entries is available.
+	 */
+	append_cmd(desc, CMD_LOAD | DISABLE_AUTO_INFO_FIFO);
+
+	/* MOVE DECO Alignment -> C1 Context 16 bytes */
+	append_move(desc, MOVE_SRC_INFIFO | MOVE_DEST_CLASS1CTX | ivsize);
+
+	/* re-enable info fifo entries */
+	append_cmd(desc, CMD_LOAD | ENABLE_AUTO_INFO_FIFO);
+
+	/* MOVE C1 Context -> OFIFO 16 bytes */
+	append_move(desc, MOVE_SRC_CLASS1CTX | MOVE_DEST_OUTFIFO | ivsize);
+
+	append_fifo_store(desc, iv_dma, ivsize, FIFOST_TYPE_MESSAGE_DATA);
+
+	return ipsec_esp(edesc, areq, OP_ALG_ENCRYPT, ipsec_esp_encrypt_done);
+}
+
+struct caam_alg_template {
+	char name[CRYPTO_MAX_ALG_NAME];
+	char driver_name[CRYPTO_MAX_ALG_NAME];
+	unsigned int blocksize;
+	struct aead_alg aead;
+	u32 class1_alg_type;
+	u32 class2_alg_type;
+	u32 alg_op;
+};
+
+static struct caam_alg_template driver_algs[] = {
+	/* single-pass ipsec_esp descriptor */
+	{
+		.name = "authenc(hmac(sha1),cbc(aes))",
+		.driver_name = "authenc-hmac-sha1-cbc-aes-caam",
+		.blocksize = AES_BLOCK_SIZE,
+		.aead = {
+			.setkey = aead_authenc_setkey,
+			.setauthsize = aead_authenc_setauthsize,
+			.encrypt = aead_authenc_encrypt,
+			.decrypt = aead_authenc_decrypt,
+			.givencrypt = aead_authenc_givencrypt,
+			.geniv = "<built-in>",
+			.ivsize = AES_BLOCK_SIZE,
+			.maxauthsize = SHA1_DIGEST_SIZE,
+			},
+		.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC,
+		.class2_alg_type = OP_ALG_ALGSEL_SHA1 | OP_ALG_AAI_HMAC_PRECOMP,
+		.alg_op = OP_ALG_ALGSEL_SHA1 | OP_ALG_AAI_HMAC,
+	},
+	{
+		.name = "authenc(hmac(sha256),cbc(aes))",
+		.driver_name = "authenc-hmac-sha256-cbc-aes-caam",
+		.blocksize = AES_BLOCK_SIZE,
+		.aead = {
+			.setkey = aead_authenc_setkey,
+			.setauthsize = aead_authenc_setauthsize,
+			.encrypt = aead_authenc_encrypt,
+			.decrypt = aead_authenc_decrypt,
+			.givencrypt = aead_authenc_givencrypt,
+			.geniv = "<built-in>",
+			.ivsize = AES_BLOCK_SIZE,
+			.maxauthsize = SHA256_DIGEST_SIZE,
+			},
+		.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC,
+		.class2_alg_type = OP_ALG_ALGSEL_SHA256 |
+				   OP_ALG_AAI_HMAC_PRECOMP,
+		.alg_op = OP_ALG_ALGSEL_SHA256 | OP_ALG_AAI_HMAC,
+	},
+	{
+		.name = "authenc(hmac(sha512),cbc(aes))",
+		.driver_name = "authenc-hmac-sha512-cbc-aes-caam",
+		.blocksize = AES_BLOCK_SIZE,
+		.aead = {
+			.setkey = aead_authenc_setkey,
+			.setauthsize = aead_authenc_setauthsize,
+			.encrypt = aead_authenc_encrypt,
+			.decrypt = aead_authenc_decrypt,
+			.givencrypt = aead_authenc_givencrypt,
+			.geniv = "<built-in>",
+			.ivsize = AES_BLOCK_SIZE,
+			.maxauthsize = SHA512_DIGEST_SIZE,
+			},
+		.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC,
+		.class2_alg_type = OP_ALG_ALGSEL_SHA512 |
+				   OP_ALG_AAI_HMAC_PRECOMP,
+		.alg_op = OP_ALG_ALGSEL_SHA512 | OP_ALG_AAI_HMAC,
+	},
+	{
+		.name = "authenc(hmac(sha1),cbc(des3_ede))",
+		.driver_name = "authenc-hmac-sha1-cbc-des3_ede-caam",
+		.blocksize = DES3_EDE_BLOCK_SIZE,
+		.aead = {
+			.setkey = aead_authenc_setkey,
+			.setauthsize = aead_authenc_setauthsize,
+			.encrypt = aead_authenc_encrypt,
+			.decrypt = aead_authenc_decrypt,
+			.givencrypt = aead_authenc_givencrypt,
+			.geniv = "<built-in>",
+			.ivsize = DES3_EDE_BLOCK_SIZE,
+			.maxauthsize = SHA1_DIGEST_SIZE,
+			},
+		.class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC,
+		.class2_alg_type = OP_ALG_ALGSEL_SHA1 | OP_ALG_AAI_HMAC_PRECOMP,
+		.alg_op = OP_ALG_ALGSEL_SHA1 | OP_ALG_AAI_HMAC,
+	},
+	{
+		.name = "authenc(hmac(sha256),cbc(des3_ede))",
+		.driver_name = "authenc-hmac-sha256-cbc-des3_ede-caam",
+		.blocksize = DES3_EDE_BLOCK_SIZE,
+		.aead = {
+			.setkey = aead_authenc_setkey,
+			.setauthsize = aead_authenc_setauthsize,
+			.encrypt = aead_authenc_encrypt,
+			.decrypt = aead_authenc_decrypt,
+			.givencrypt = aead_authenc_givencrypt,
+			.geniv = "<built-in>",
+			.ivsize = DES3_EDE_BLOCK_SIZE,
+			.maxauthsize = SHA256_DIGEST_SIZE,
+			},
+		.class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC,
+		.class2_alg_type = OP_ALG_ALGSEL_SHA256 |
+				   OP_ALG_AAI_HMAC_PRECOMP,
+		.alg_op = OP_ALG_ALGSEL_SHA256 | OP_ALG_AAI_HMAC,
+	},
+	{
+		.name = "authenc(hmac(sha512),cbc(des3_ede))",
+		.driver_name = "authenc-hmac-sha512-cbc-des3_ede-caam",
+		.blocksize = DES3_EDE_BLOCK_SIZE,
+		.aead = {
+			.setkey = aead_authenc_setkey,
+			.setauthsize = aead_authenc_setauthsize,
+			.encrypt = aead_authenc_encrypt,
+			.decrypt = aead_authenc_decrypt,
+			.givencrypt = aead_authenc_givencrypt,
+			.geniv = "<built-in>",
+			.ivsize = DES3_EDE_BLOCK_SIZE,
+			.maxauthsize = SHA512_DIGEST_SIZE,
+			},
+		.class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC,
+		.class2_alg_type = OP_ALG_ALGSEL_SHA512 |
+				   OP_ALG_AAI_HMAC_PRECOMP,
+		.alg_op = OP_ALG_ALGSEL_SHA512 | OP_ALG_AAI_HMAC,
+	},
+	{
+		.name = "authenc(hmac(sha1),cbc(des))",
+		.driver_name = "authenc-hmac-sha1-cbc-des-caam",
+		.blocksize = DES_BLOCK_SIZE,
+		.aead = {
+			.setkey = aead_authenc_setkey,
+			.setauthsize = aead_authenc_setauthsize,
+			.encrypt = aead_authenc_encrypt,
+			.decrypt = aead_authenc_decrypt,
+			.givencrypt = aead_authenc_givencrypt,
+			.geniv = "<built-in>",
+			.ivsize = DES_BLOCK_SIZE,
+			.maxauthsize = SHA1_DIGEST_SIZE,
+			},
+		.class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC,
+		.class2_alg_type = OP_ALG_ALGSEL_SHA1 | OP_ALG_AAI_HMAC_PRECOMP,
+		.alg_op = OP_ALG_ALGSEL_SHA1 | OP_ALG_AAI_HMAC,
+	},
+	{
+		.name = "authenc(hmac(sha256),cbc(des))",
+		.driver_name = "authenc-hmac-sha256-cbc-des-caam",
+		.blocksize = DES_BLOCK_SIZE,
+		.aead = {
+			.setkey = aead_authenc_setkey,
+			.setauthsize = aead_authenc_setauthsize,
+			.encrypt = aead_authenc_encrypt,
+			.decrypt = aead_authenc_decrypt,
+			.givencrypt = aead_authenc_givencrypt,
+			.geniv = "<built-in>",
+			.ivsize = DES_BLOCK_SIZE,
+			.maxauthsize = SHA256_DIGEST_SIZE,
+			},
+		.class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC,
+		.class2_alg_type = OP_ALG_ALGSEL_SHA256 |
+				   OP_ALG_AAI_HMAC_PRECOMP,
+		.alg_op = OP_ALG_ALGSEL_SHA256 | OP_ALG_AAI_HMAC,
+	},
+	{
+		.name = "authenc(hmac(sha512),cbc(des))",
+		.driver_name = "authenc-hmac-sha512-cbc-des-caam",
+		.blocksize = DES_BLOCK_SIZE,
+		.aead = {
+			.setkey = aead_authenc_setkey,
+			.setauthsize = aead_authenc_setauthsize,
+			.encrypt = aead_authenc_encrypt,
+			.decrypt = aead_authenc_decrypt,
+			.givencrypt = aead_authenc_givencrypt,
+			.geniv = "<built-in>",
+			.ivsize = DES_BLOCK_SIZE,
+			.maxauthsize = SHA512_DIGEST_SIZE,
+			},
+		.class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC,
+		.class2_alg_type = OP_ALG_ALGSEL_SHA512 |
+				   OP_ALG_AAI_HMAC_PRECOMP,
+		.alg_op = OP_ALG_ALGSEL_SHA512 | OP_ALG_AAI_HMAC,
+	},
+};
+
+struct caam_crypto_alg {
+	struct list_head entry;
+	struct device *ctrldev;
+	int class1_alg_type;
+	int class2_alg_type;
+	int alg_op;
+	struct crypto_alg crypto_alg;
+};
+
+static int caam_cra_init(struct crypto_tfm *tfm)
+{
+	struct crypto_alg *alg = tfm->__crt_alg;
+	struct caam_crypto_alg *caam_alg =
+		 container_of(alg, struct caam_crypto_alg, crypto_alg);
+	struct caam_ctx *ctx = crypto_tfm_ctx(tfm);
+	struct caam_drv_private *priv = dev_get_drvdata(caam_alg->ctrldev);
+	int tgt_jr = atomic_inc_return(&priv->tfm_count);
+
+	/*
+	 * distribute tfms across job rings to ensure in-order
+	 * crypto request processing per tfm
+	 */
+	ctx->jrdev = priv->algapi_jr[(tgt_jr / 2) % priv->num_jrs_for_algapi];
+
+	/* copy descriptor header template value */
+	ctx->class1_alg_type = OP_TYPE_CLASS1_ALG | caam_alg->class1_alg_type;
+	ctx->class2_alg_type = OP_TYPE_CLASS2_ALG | caam_alg->class2_alg_type;
+	ctx->alg_op = OP_TYPE_CLASS2_ALG | caam_alg->alg_op;
+
+	return 0;
+}
+
+static void caam_cra_exit(struct crypto_tfm *tfm)
+{
+	struct caam_ctx *ctx = crypto_tfm_ctx(tfm);
+
+	if (!dma_mapping_error(ctx->jrdev, ctx->shared_desc_phys))
+		dma_unmap_single(ctx->jrdev, ctx->shared_desc_phys,
+				 desc_bytes(ctx->sh_desc), DMA_TO_DEVICE);
+	kfree(ctx->sh_desc);
+
+	if (!dma_mapping_error(ctx->jrdev, ctx->key_phys))
+		dma_unmap_single(ctx->jrdev, ctx->key_phys,
+				 ctx->split_key_pad_len + ctx->enckeylen,
+				 DMA_TO_DEVICE);
+	kfree(ctx->key);
+}
+
+static void __exit caam_algapi_exit(void)
+{
+
+	struct device_node *dev_node;
+	struct platform_device *pdev;
+	struct device *ctrldev;
+	struct caam_drv_private *priv;
+	struct caam_crypto_alg *t_alg, *n;
+	int i, err;
+
+	dev_node = of_find_compatible_node(NULL, NULL, "fsl,sec-v4.0");
+	if (!dev_node)
+		return;
+
+	pdev = of_find_device_by_node(dev_node);
+	if (!pdev)
+		return;
+
+	ctrldev = &pdev->dev;
+	of_node_put(dev_node);
+	priv = dev_get_drvdata(ctrldev);
+
+	if (!priv->alg_list.next)
+		return;
+
+	list_for_each_entry_safe(t_alg, n, &priv->alg_list, entry) {
+		crypto_unregister_alg(&t_alg->crypto_alg);
+		list_del(&t_alg->entry);
+		kfree(t_alg);
+	}
+
+	for (i = 0; i < priv->total_jobrs; i++) {
+		err = caam_jr_deregister(priv->algapi_jr[i]);
+		if (err < 0)
+			break;
+	}
+	kfree(priv->algapi_jr);
+}
+
+static struct caam_crypto_alg *caam_alg_alloc(struct device *ctrldev,
+					      struct caam_alg_template
+					      *template)
+{
+	struct caam_crypto_alg *t_alg;
+	struct crypto_alg *alg;
+
+	t_alg = kzalloc(sizeof(struct caam_crypto_alg), GFP_KERNEL);
+	if (!t_alg) {
+		dev_err(ctrldev, "failed to allocate t_alg\n");
+		return ERR_PTR(-ENOMEM);
+	}
+
+	alg = &t_alg->crypto_alg;
+
+	snprintf(alg->cra_name, CRYPTO_MAX_ALG_NAME, "%s", template->name);
+	snprintf(alg->cra_driver_name, CRYPTO_MAX_ALG_NAME, "%s",
+		 template->driver_name);
+	alg->cra_module = THIS_MODULE;
+	alg->cra_init = caam_cra_init;
+	alg->cra_exit = caam_cra_exit;
+	alg->cra_priority = CAAM_CRA_PRIORITY;
+	alg->cra_flags = CRYPTO_ALG_TYPE_AEAD | CRYPTO_ALG_ASYNC;
+	alg->cra_blocksize = template->blocksize;
+	alg->cra_alignmask = 0;
+	alg->cra_type = &crypto_aead_type;
+	alg->cra_ctxsize = sizeof(struct caam_ctx);
+	alg->cra_u.aead = template->aead;
+
+	t_alg->class1_alg_type = template->class1_alg_type;
+	t_alg->class2_alg_type = template->class2_alg_type;
+	t_alg->alg_op = template->alg_op;
+	t_alg->ctrldev = ctrldev;
+
+	return t_alg;
+}
+
+static int __init caam_algapi_init(void)
+{
+	struct device_node *dev_node;
+	struct platform_device *pdev;
+	struct device *ctrldev, **jrdev;
+	struct caam_drv_private *priv;
+	int i = 0, err = 0;
+
+	dev_node = of_find_compatible_node(NULL, NULL, "fsl,sec-v4.0");
+	if (!dev_node)
+		return -ENODEV;
+
+	pdev = of_find_device_by_node(dev_node);
+	if (!pdev)
+		return -ENODEV;
+
+	ctrldev = &pdev->dev;
+	priv = dev_get_drvdata(ctrldev);
+	of_node_put(dev_node);
+
+	INIT_LIST_HEAD(&priv->alg_list);
+
+	jrdev = kmalloc(sizeof(*jrdev) * priv->total_jobrs, GFP_KERNEL);
+	if (!jrdev)
+		return -ENOMEM;
+
+	for (i = 0; i < priv->total_jobrs; i++) {
+		err = caam_jr_register(ctrldev, &jrdev[i]);
+		if (err < 0)
+			break;
+	}
+	if (err < 0 && i == 0) {
+		dev_err(ctrldev, "algapi error in job ring registration: %d\n",
+			err);
+		kfree(jrdev);
+		return err;
+	}
+
+	priv->num_jrs_for_algapi = i;
+	priv->algapi_jr = jrdev;
+	atomic_set(&priv->tfm_count, -1);
+
+	/* register crypto algorithms the device supports */
+	for (i = 0; i < ARRAY_SIZE(driver_algs); i++) {
+		/* TODO: check if h/w supports alg */
+		struct caam_crypto_alg *t_alg;
+
+		t_alg = caam_alg_alloc(ctrldev, &driver_algs[i]);
+		if (IS_ERR(t_alg)) {
+			err = PTR_ERR(t_alg);
+			dev_warn(ctrldev, "%s alg allocation failed\n",
+				 driver_algs[i].driver_name);
+			continue;
+		}
+
+		err = crypto_register_alg(&t_alg->crypto_alg);
+		if (err) {
+			dev_warn(ctrldev, "%s alg registration failed\n",
+				t_alg->crypto_alg.cra_driver_name);
+			kfree(t_alg);
+		} else {
+			list_add_tail(&t_alg->entry, &priv->alg_list);
+			dev_info(ctrldev, "%s\n",
+				 t_alg->crypto_alg.cra_driver_name);
+		}
+	}
+
+	return err;
+}
+
+module_init(caam_algapi_init);
+module_exit(caam_algapi_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("FSL CAAM support for crypto API");
+MODULE_AUTHOR("Freescale Semiconductor - NMG/STC");
diff -druN linux-2.6.39-libre/drivers/crypto/caam/compat.h linux-3.0-rc7-libre/drivers/crypto/caam/compat.h
--- linux-2.6.39-libre/drivers/crypto/caam/compat.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/crypto/caam/compat.h	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2008-2011 Freescale Semiconductor, Inc.
+ */
+
+#ifndef CAAM_COMPAT_H
+#define CAAM_COMPAT_H
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/mod_devicetable.h>
+#include <linux/device.h>
+#include <linux/interrupt.h>
+#include <linux/crypto.h>
+#include <linux/hw_random.h>
+#include <linux/of_platform.h>
+#include <linux/dma-mapping.h>
+#include <linux/io.h>
+#include <linux/spinlock.h>
+#include <linux/rtnetlink.h>
+#include <linux/in.h>
+#include <linux/slab.h>
+#include <linux/types.h>
+#include <linux/debugfs.h>
+#include <linux/circ_buf.h>
+#include <net/xfrm.h>
+
+#include <crypto/algapi.h>
+#include <crypto/aes.h>
+#include <crypto/des.h>
+#include <crypto/sha.h>
+#include <crypto/aead.h>
+#include <crypto/authenc.h>
+#include <crypto/scatterwalk.h>
+
+#endif /* !defined(CAAM_COMPAT_H) */
diff -druN linux-2.6.39-libre/drivers/crypto/caam/ctrl.c linux-3.0-rc7-libre/drivers/crypto/caam/ctrl.c
--- linux-2.6.39-libre/drivers/crypto/caam/ctrl.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/crypto/caam/ctrl.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,269 @@
+/*
+ * CAAM control-plane driver backend
+ * Controller-level driver, kernel property detection, initialization
+ *
+ * Copyright 2008-2011 Freescale Semiconductor, Inc.
+ */
+
+#include "compat.h"
+#include "regs.h"
+#include "intern.h"
+#include "jr.h"
+
+static int caam_remove(struct platform_device *pdev)
+{
+	struct device *ctrldev;
+	struct caam_drv_private *ctrlpriv;
+	struct caam_drv_private_jr *jrpriv;
+	struct caam_full __iomem *topregs;
+	int ring, ret = 0;
+
+	ctrldev = &pdev->dev;
+	ctrlpriv = dev_get_drvdata(ctrldev);
+	topregs = (struct caam_full __iomem *)ctrlpriv->ctrl;
+
+	/* shut down JobRs */
+	for (ring = 0; ring < ctrlpriv->total_jobrs; ring++) {
+		ret |= caam_jr_shutdown(ctrlpriv->jrdev[ring]);
+		jrpriv = dev_get_drvdata(ctrlpriv->jrdev[ring]);
+		irq_dispose_mapping(jrpriv->irq);
+	}
+
+	/* Shut down debug views */
+#ifdef CONFIG_DEBUG_FS
+	debugfs_remove_recursive(ctrlpriv->dfs_root);
+#endif
+
+	/* Unmap controller region */
+	iounmap(&topregs->ctrl);
+
+	kfree(ctrlpriv->jrdev);
+	kfree(ctrlpriv);
+
+	return ret;
+}
+
+/* Probe routine for CAAM top (controller) level */
+static int caam_probe(struct platform_device *pdev)
+{
+	int d, ring, rspec;
+	struct device *dev;
+	struct device_node *nprop, *np;
+	struct caam_ctrl __iomem *ctrl;
+	struct caam_full __iomem *topregs;
+	struct caam_drv_private *ctrlpriv;
+	struct caam_perfmon *perfmon;
+	struct caam_deco **deco;
+	u32 deconum;
+
+	ctrlpriv = kzalloc(sizeof(struct caam_drv_private), GFP_KERNEL);
+	if (!ctrlpriv)
+		return -ENOMEM;
+
+	dev = &pdev->dev;
+	dev_set_drvdata(dev, ctrlpriv);
+	ctrlpriv->pdev = pdev;
+	nprop = pdev->dev.of_node;
+
+	/* Get configuration properties from device tree */
+	/* First, get register page */
+	ctrl = of_iomap(nprop, 0);
+	if (ctrl == NULL) {
+		dev_err(dev, "caam: of_iomap() failed\n");
+		return -ENOMEM;
+	}
+	ctrlpriv->ctrl = (struct caam_ctrl __force *)ctrl;
+
+	/* topregs used to derive pointers to CAAM sub-blocks only */
+	topregs = (struct caam_full __iomem *)ctrl;
+
+	/* Get the IRQ of the controller (for security violations only) */
+	ctrlpriv->secvio_irq = of_irq_to_resource(nprop, 0, NULL);
+
+	/*
+	 * Enable DECO watchdogs and, if this is a PHYS_ADDR_T_64BIT kernel,
+	 * 36-bit pointers in master configuration register
+	 */
+	setbits32(&topregs->ctrl.mcr, MCFGR_WDENABLE |
+		  (sizeof(dma_addr_t) == sizeof(u64) ? MCFGR_LONG_PTR : 0));
+
+	if (sizeof(dma_addr_t) == sizeof(u64))
+		dma_set_mask(dev, DMA_BIT_MASK(36));
+
+	/* Find out how many DECOs are present */
+	deconum = (rd_reg64(&topregs->ctrl.perfmon.cha_num) &
+		   CHA_NUM_DECONUM_MASK) >> CHA_NUM_DECONUM_SHIFT;
+
+	ctrlpriv->deco = kmalloc(deconum * sizeof(struct caam_deco *),
+				 GFP_KERNEL);
+
+	deco = (struct caam_deco __force **)&topregs->deco;
+	for (d = 0; d < deconum; d++)
+		ctrlpriv->deco[d] = deco[d];
+
+	/*
+	 * Detect and enable JobRs
+	 * First, find out how many ring spec'ed, allocate references
+	 * for all, then go probe each one.
+	 */
+	rspec = 0;
+	for_each_compatible_node(np, NULL, "fsl,sec-v4.0-job-ring")
+		rspec++;
+	ctrlpriv->jrdev = kzalloc(sizeof(struct device *) * rspec, GFP_KERNEL);
+	if (ctrlpriv->jrdev == NULL) {
+		iounmap(&topregs->ctrl);
+		return -ENOMEM;
+	}
+
+	ring = 0;
+	ctrlpriv->total_jobrs = 0;
+	for_each_compatible_node(np, NULL, "fsl,sec-v4.0-job-ring") {
+		caam_jr_probe(pdev, np, ring);
+		ctrlpriv->total_jobrs++;
+		ring++;
+	}
+
+	/* Check to see if QI present. If so, enable */
+	ctrlpriv->qi_present = !!(rd_reg64(&topregs->ctrl.perfmon.comp_parms) &
+				  CTPR_QI_MASK);
+	if (ctrlpriv->qi_present) {
+		ctrlpriv->qi = (struct caam_queue_if __force *)&topregs->qi;
+		/* This is all that's required to physically enable QI */
+		wr_reg32(&topregs->qi.qi_control_lo, QICTL_DQEN);
+	}
+
+	/* If no QI and no rings specified, quit and go home */
+	if ((!ctrlpriv->qi_present) && (!ctrlpriv->total_jobrs)) {
+		dev_err(dev, "no queues configured, terminating\n");
+		caam_remove(pdev);
+		return -ENOMEM;
+	}
+
+	/* NOTE: RTIC detection ought to go here, around Si time */
+
+	/* Initialize queue allocator lock */
+	spin_lock_init(&ctrlpriv->jr_alloc_lock);
+
+	/* Report "alive" for developer to see */
+	dev_info(dev, "device ID = 0x%016llx\n",
+		 rd_reg64(&topregs->ctrl.perfmon.caam_id));
+	dev_info(dev, "job rings = %d, qi = %d\n",
+		 ctrlpriv->total_jobrs, ctrlpriv->qi_present);
+
+#ifdef CONFIG_DEBUG_FS
+	/*
+	 * FIXME: needs better naming distinction, as some amalgamation of
+	 * "caam" and nprop->full_name. The OF name isn't distinctive,
+	 * but does separate instances
+	 */
+	perfmon = (struct caam_perfmon __force *)&ctrl->perfmon;
+
+	ctrlpriv->dfs_root = debugfs_create_dir("caam", NULL);
+	ctrlpriv->ctl = debugfs_create_dir("ctl", ctrlpriv->dfs_root);
+
+	/* Controller-level - performance monitor counters */
+	ctrlpriv->ctl_rq_dequeued =
+		debugfs_create_u64("rq_dequeued",
+				   S_IFCHR | S_IRUSR | S_IRGRP | S_IROTH,
+				   ctrlpriv->ctl, &perfmon->req_dequeued);
+	ctrlpriv->ctl_ob_enc_req =
+		debugfs_create_u64("ob_rq_encrypted",
+				   S_IFCHR | S_IRUSR | S_IRGRP | S_IROTH,
+				   ctrlpriv->ctl, &perfmon->ob_enc_req);
+	ctrlpriv->ctl_ib_dec_req =
+		debugfs_create_u64("ib_rq_decrypted",
+				   S_IFCHR | S_IRUSR | S_IRGRP | S_IROTH,
+				   ctrlpriv->ctl, &perfmon->ib_dec_req);
+	ctrlpriv->ctl_ob_enc_bytes =
+		debugfs_create_u64("ob_bytes_encrypted",
+				   S_IFCHR | S_IRUSR | S_IRGRP | S_IROTH,
+				   ctrlpriv->ctl, &perfmon->ob_enc_bytes);
+	ctrlpriv->ctl_ob_prot_bytes =
+		debugfs_create_u64("ob_bytes_protected",
+				   S_IFCHR | S_IRUSR | S_IRGRP | S_IROTH,
+				   ctrlpriv->ctl, &perfmon->ob_prot_bytes);
+	ctrlpriv->ctl_ib_dec_bytes =
+		debugfs_create_u64("ib_bytes_decrypted",
+				   S_IFCHR | S_IRUSR | S_IRGRP | S_IROTH,
+				   ctrlpriv->ctl, &perfmon->ib_dec_bytes);
+	ctrlpriv->ctl_ib_valid_bytes =
+		debugfs_create_u64("ib_bytes_validated",
+				   S_IFCHR | S_IRUSR | S_IRGRP | S_IROTH,
+				   ctrlpriv->ctl, &perfmon->ib_valid_bytes);
+
+	/* Controller level - global status values */
+	ctrlpriv->ctl_faultaddr =
+		debugfs_create_u64("fault_addr",
+				   S_IFCHR | S_IRUSR | S_IRGRP | S_IROTH,
+				   ctrlpriv->ctl, &perfmon->faultaddr);
+	ctrlpriv->ctl_faultdetail =
+		debugfs_create_u32("fault_detail",
+				   S_IFCHR | S_IRUSR | S_IRGRP | S_IROTH,
+				   ctrlpriv->ctl, &perfmon->faultdetail);
+	ctrlpriv->ctl_faultstatus =
+		debugfs_create_u32("fault_status",
+				   S_IFCHR | S_IRUSR | S_IRGRP | S_IROTH,
+				   ctrlpriv->ctl, &perfmon->status);
+
+	/* Internal covering keys (useful in non-secure mode only) */
+	ctrlpriv->ctl_kek_wrap.data = &ctrlpriv->ctrl->kek[0];
+	ctrlpriv->ctl_kek_wrap.size = KEK_KEY_SIZE * sizeof(u32);
+	ctrlpriv->ctl_kek = debugfs_create_blob("kek",
+						S_IFCHR | S_IRUSR |
+						S_IRGRP | S_IROTH,
+						ctrlpriv->ctl,
+						&ctrlpriv->ctl_kek_wrap);
+
+	ctrlpriv->ctl_tkek_wrap.data = &ctrlpriv->ctrl->tkek[0];
+	ctrlpriv->ctl_tkek_wrap.size = KEK_KEY_SIZE * sizeof(u32);
+	ctrlpriv->ctl_tkek = debugfs_create_blob("tkek",
+						 S_IFCHR | S_IRUSR |
+						 S_IRGRP | S_IROTH,
+						 ctrlpriv->ctl,
+						 &ctrlpriv->ctl_tkek_wrap);
+
+	ctrlpriv->ctl_tdsk_wrap.data = &ctrlpriv->ctrl->tdsk[0];
+	ctrlpriv->ctl_tdsk_wrap.size = KEK_KEY_SIZE * sizeof(u32);
+	ctrlpriv->ctl_tdsk = debugfs_create_blob("tdsk",
+						 S_IFCHR | S_IRUSR |
+						 S_IRGRP | S_IROTH,
+						 ctrlpriv->ctl,
+						 &ctrlpriv->ctl_tdsk_wrap);
+#endif
+	return 0;
+}
+
+static struct of_device_id caam_match[] = {
+	{
+		.compatible = "fsl,sec-v4.0",
+	},
+	{},
+};
+MODULE_DEVICE_TABLE(of, caam_match);
+
+static struct platform_driver caam_driver = {
+	.driver = {
+		.name = "caam",
+		.owner = THIS_MODULE,
+		.of_match_table = caam_match,
+	},
+	.probe       = caam_probe,
+	.remove      = __devexit_p(caam_remove),
+};
+
+static int __init caam_base_init(void)
+{
+	return platform_driver_register(&caam_driver);
+}
+
+static void __exit caam_base_exit(void)
+{
+	return platform_driver_unregister(&caam_driver);
+}
+
+module_init(caam_base_init);
+module_exit(caam_base_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("FSL CAAM request backend");
+MODULE_AUTHOR("Freescale Semiconductor - NMG/STC");
diff -druN linux-2.6.39-libre/drivers/crypto/caam/desc_constr.h linux-3.0-rc7-libre/drivers/crypto/caam/desc_constr.h
--- linux-2.6.39-libre/drivers/crypto/caam/desc_constr.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/crypto/caam/desc_constr.h	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,205 @@
+/*
+ * caam descriptor construction helper functions
+ *
+ * Copyright 2008-2011 Freescale Semiconductor, Inc.
+ */
+
+#include "desc.h"
+
+#define IMMEDIATE (1 << 23)
+#define CAAM_CMD_SZ sizeof(u32)
+#define CAAM_PTR_SZ sizeof(dma_addr_t)
+#define CAAM_DESC_BYTES_MAX (CAAM_CMD_SZ * 64)
+
+#ifdef DEBUG
+#define PRINT_POS do { printk(KERN_DEBUG "%02d: %s\n", desc_len(desc),\
+			      &__func__[sizeof("append")]); } while (0)
+#else
+#define PRINT_POS
+#endif
+
+#define DISABLE_AUTO_INFO_FIFO (IMMEDIATE | LDST_CLASS_DECO | \
+				LDST_SRCDST_WORD_DECOCTRL | \
+				(LDOFF_DISABLE_AUTO_NFIFO << LDST_OFFSET_SHIFT))
+#define ENABLE_AUTO_INFO_FIFO (IMMEDIATE | LDST_CLASS_DECO | \
+			       LDST_SRCDST_WORD_DECOCTRL | \
+			       (LDOFF_ENABLE_AUTO_NFIFO << LDST_OFFSET_SHIFT))
+
+static inline int desc_len(u32 *desc)
+{
+	return *desc & HDR_DESCLEN_MASK;
+}
+
+static inline int desc_bytes(void *desc)
+{
+	return desc_len(desc) * CAAM_CMD_SZ;
+}
+
+static inline u32 *desc_end(u32 *desc)
+{
+	return desc + desc_len(desc);
+}
+
+static inline void *sh_desc_pdb(u32 *desc)
+{
+	return desc + 1;
+}
+
+static inline void init_desc(u32 *desc, u32 options)
+{
+	*desc = options | HDR_ONE | 1;
+}
+
+static inline void init_sh_desc(u32 *desc, u32 options)
+{
+	PRINT_POS;
+	init_desc(desc, CMD_SHARED_DESC_HDR | options);
+}
+
+static inline void init_sh_desc_pdb(u32 *desc, u32 options, size_t pdb_bytes)
+{
+	u32 pdb_len = pdb_bytes / CAAM_CMD_SZ + 1;
+
+	init_sh_desc(desc, ((pdb_len << HDR_START_IDX_SHIFT) + pdb_len) |
+		     options);
+}
+
+static inline void init_job_desc(u32 *desc, u32 options)
+{
+	init_desc(desc, CMD_DESC_HDR | options);
+}
+
+static inline void append_ptr(u32 *desc, dma_addr_t ptr)
+{
+	dma_addr_t *offset = (dma_addr_t *)desc_end(desc);
+
+	*offset = ptr;
+
+	(*desc) += CAAM_PTR_SZ / CAAM_CMD_SZ;
+}
+
+static inline void init_job_desc_shared(u32 *desc, dma_addr_t ptr, int len,
+					u32 options)
+{
+	PRINT_POS;
+	init_job_desc(desc, HDR_SHARED | options |
+		      (len << HDR_START_IDX_SHIFT));
+	append_ptr(desc, ptr);
+}
+
+static inline void append_data(u32 *desc, void *data, int len)
+{
+	u32 *offset = desc_end(desc);
+
+	if (len) /* avoid sparse warning: memcpy with byte count of 0 */
+		memcpy(offset, data, len);
+
+	(*desc) += (len + CAAM_CMD_SZ - 1) / CAAM_CMD_SZ;
+}
+
+static inline void append_cmd(u32 *desc, u32 command)
+{
+	u32 *cmd = desc_end(desc);
+
+	*cmd = command;
+
+	(*desc)++;
+}
+
+static inline void append_cmd_ptr(u32 *desc, dma_addr_t ptr, int len,
+				  u32 command)
+{
+	append_cmd(desc, command | len);
+	append_ptr(desc, ptr);
+}
+
+static inline void append_cmd_data(u32 *desc, void *data, int len,
+				   u32 command)
+{
+	append_cmd(desc, command | IMMEDIATE | len);
+	append_data(desc, data, len);
+}
+
+static inline u32 *append_jump(u32 *desc, u32 options)
+{
+	u32 *cmd = desc_end(desc);
+
+	PRINT_POS;
+	append_cmd(desc, CMD_JUMP | options);
+
+	return cmd;
+}
+
+static inline void set_jump_tgt_here(u32 *desc, u32 *jump_cmd)
+{
+	*jump_cmd = *jump_cmd | (desc_len(desc) - (jump_cmd - desc));
+}
+
+#define APPEND_CMD(cmd, op) \
+static inline void append_##cmd(u32 *desc, u32 options) \
+{ \
+	PRINT_POS; \
+	append_cmd(desc, CMD_##op | options); \
+}
+APPEND_CMD(operation, OPERATION)
+APPEND_CMD(move, MOVE)
+
+#define APPEND_CMD_LEN(cmd, op) \
+static inline void append_##cmd(u32 *desc, unsigned int len, u32 options) \
+{ \
+	PRINT_POS; \
+	append_cmd(desc, CMD_##op | len | options); \
+}
+APPEND_CMD_LEN(seq_store, SEQ_STORE)
+APPEND_CMD_LEN(seq_fifo_load, SEQ_FIFO_LOAD)
+APPEND_CMD_LEN(seq_fifo_store, SEQ_FIFO_STORE)
+
+#define APPEND_CMD_PTR(cmd, op) \
+static inline void append_##cmd(u32 *desc, dma_addr_t ptr, unsigned int len, \
+				u32 options) \
+{ \
+	PRINT_POS; \
+	append_cmd_ptr(desc, ptr, len, CMD_##op | options); \
+}
+APPEND_CMD_PTR(key, KEY)
+APPEND_CMD_PTR(seq_in_ptr, SEQ_IN_PTR)
+APPEND_CMD_PTR(seq_out_ptr, SEQ_OUT_PTR)
+APPEND_CMD_PTR(load, LOAD)
+APPEND_CMD_PTR(store, STORE)
+APPEND_CMD_PTR(fifo_load, FIFO_LOAD)
+APPEND_CMD_PTR(fifo_store, FIFO_STORE)
+
+#define APPEND_CMD_PTR_TO_IMM(cmd, op) \
+static inline void append_##cmd##_as_imm(u32 *desc, void *data, \
+					 unsigned int len, u32 options) \
+{ \
+	PRINT_POS; \
+	append_cmd_data(desc, data, len, CMD_##op | options); \
+}
+APPEND_CMD_PTR_TO_IMM(load, LOAD);
+APPEND_CMD_PTR_TO_IMM(fifo_load, FIFO_LOAD);
+
+/*
+ * 2nd variant for commands whose specified immediate length differs
+ * from length of immediate data provided, e.g., split keys
+ */
+#define APPEND_CMD_PTR_TO_IMM2(cmd, op) \
+static inline void append_##cmd##_as_imm(u32 *desc, void *data, \
+					 unsigned int data_len, \
+					 unsigned int len, u32 options) \
+{ \
+	PRINT_POS; \
+	append_cmd(desc, CMD_##op | IMMEDIATE | len | options); \
+	append_data(desc, data, data_len); \
+}
+APPEND_CMD_PTR_TO_IMM2(key, KEY);
+
+#define APPEND_CMD_RAW_IMM(cmd, op, type) \
+static inline void append_##cmd##_imm_##type(u32 *desc, type immediate, \
+					     u32 options) \
+{ \
+	PRINT_POS; \
+	append_cmd(desc, CMD_##op | IMMEDIATE | options | sizeof(type)); \
+	append_cmd(desc, immediate); \
+}
+APPEND_CMD_RAW_IMM(load, LOAD, u32);
diff -druN linux-2.6.39-libre/drivers/crypto/caam/desc.h linux-3.0-rc7-libre/drivers/crypto/caam/desc.h
--- linux-2.6.39-libre/drivers/crypto/caam/desc.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/crypto/caam/desc.h	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,1605 @@
+/*
+ * CAAM descriptor composition header
+ * Definitions to support CAAM descriptor instruction generation
+ *
+ * Copyright 2008-2011 Freescale Semiconductor, Inc.
+ */
+
+#ifndef DESC_H
+#define DESC_H
+
+/* Max size of any CAAM descriptor in 32-bit words, inclusive of header */
+#define MAX_CAAM_DESCSIZE       64
+
+/* Block size of any entity covered/uncovered with a KEK/TKEK */
+#define KEK_BLOCKSIZE		16
+
+/*
+ * Supported descriptor command types as they show up
+ * inside a descriptor command word.
+ */
+#define CMD_SHIFT               27
+#define CMD_MASK                0xf8000000
+
+#define CMD_KEY                 (0x00 << CMD_SHIFT)
+#define CMD_SEQ_KEY             (0x01 << CMD_SHIFT)
+#define CMD_LOAD                (0x02 << CMD_SHIFT)
+#define CMD_SEQ_LOAD            (0x03 << CMD_SHIFT)
+#define CMD_FIFO_LOAD           (0x04 << CMD_SHIFT)
+#define CMD_SEQ_FIFO_LOAD       (0x05 << CMD_SHIFT)
+#define CMD_STORE               (0x0a << CMD_SHIFT)
+#define CMD_SEQ_STORE           (0x0b << CMD_SHIFT)
+#define CMD_FIFO_STORE          (0x0c << CMD_SHIFT)
+#define CMD_SEQ_FIFO_STORE      (0x0d << CMD_SHIFT)
+#define CMD_MOVE_LEN            (0x0e << CMD_SHIFT)
+#define CMD_MOVE                (0x0f << CMD_SHIFT)
+#define CMD_OPERATION           (0x10 << CMD_SHIFT)
+#define CMD_SIGNATURE           (0x12 << CMD_SHIFT)
+#define CMD_JUMP                (0x14 << CMD_SHIFT)
+#define CMD_MATH                (0x15 << CMD_SHIFT)
+#define CMD_DESC_HDR            (0x16 << CMD_SHIFT)
+#define CMD_SHARED_DESC_HDR     (0x17 << CMD_SHIFT)
+#define CMD_SEQ_IN_PTR          (0x1e << CMD_SHIFT)
+#define CMD_SEQ_OUT_PTR         (0x1f << CMD_SHIFT)
+
+/* General-purpose class selector for all commands */
+#define CLASS_SHIFT             25
+#define CLASS_MASK              (0x03 << CLASS_SHIFT)
+
+#define CLASS_NONE              (0x00 << CLASS_SHIFT)
+#define CLASS_1                 (0x01 << CLASS_SHIFT)
+#define CLASS_2                 (0x02 << CLASS_SHIFT)
+#define CLASS_BOTH              (0x03 << CLASS_SHIFT)
+
+/*
+ * Descriptor header command constructs
+ * Covers shared, job, and trusted descriptor headers
+ */
+
+/*
+ * Do Not Run - marks a descriptor inexecutable if there was
+ * a preceding error somewhere
+ */
+#define HDR_DNR                 0x01000000
+
+/*
+ * ONE - should always be set. Combination of ONE (always
+ * set) and ZRO (always clear) forms an endianness sanity check
+ */
+#define HDR_ONE                 0x00800000
+#define HDR_ZRO                 0x00008000
+
+/* Start Index or SharedDesc Length */
+#define HDR_START_IDX_MASK      0x3f
+#define HDR_START_IDX_SHIFT     16
+
+/* If shared descriptor header, 6-bit length */
+#define HDR_DESCLEN_SHR_MASK  0x3f
+
+/* If non-shared header, 7-bit length */
+#define HDR_DESCLEN_MASK      0x7f
+
+/* This is a TrustedDesc (if not SharedDesc) */
+#define HDR_TRUSTED             0x00004000
+
+/* Make into TrustedDesc (if not SharedDesc) */
+#define HDR_MAKE_TRUSTED        0x00002000
+
+/* Save context if self-shared (if SharedDesc) */
+#define HDR_SAVECTX             0x00001000
+
+/* Next item points to SharedDesc */
+#define HDR_SHARED              0x00001000
+
+/*
+ * Reverse Execution Order - execute JobDesc first, then
+ * execute SharedDesc (normally SharedDesc goes first).
+ */
+#define HDR_REVERSE             0x00000800
+
+/* Propogate DNR property to SharedDesc */
+#define HDR_PROP_DNR            0x00000800
+
+/* JobDesc/SharedDesc share property */
+#define HDR_SD_SHARE_MASK       0x03
+#define HDR_SD_SHARE_SHIFT      8
+#define HDR_JD_SHARE_MASK       0x07
+#define HDR_JD_SHARE_SHIFT      8
+
+#define HDR_SHARE_NEVER         (0x00 << HDR_SD_SHARE_SHIFT)
+#define HDR_SHARE_WAIT          (0x01 << HDR_SD_SHARE_SHIFT)
+#define HDR_SHARE_SERIAL        (0x02 << HDR_SD_SHARE_SHIFT)
+#define HDR_SHARE_ALWAYS        (0x03 << HDR_SD_SHARE_SHIFT)
+#define HDR_SHARE_DEFER         (0x04 << HDR_SD_SHARE_SHIFT)
+
+/* JobDesc/SharedDesc descriptor length */
+#define HDR_JD_LENGTH_MASK      0x7f
+#define HDR_SD_LENGTH_MASK      0x3f
+
+/*
+ * KEY/SEQ_KEY Command Constructs
+ */
+
+/* Key Destination Class: 01 = Class 1, 02 - Class 2  */
+#define KEY_DEST_CLASS_SHIFT    25  /* use CLASS_1 or CLASS_2 */
+#define KEY_DEST_CLASS_MASK     (0x03 << KEY_DEST_CLASS_SHIFT)
+
+/* Scatter-Gather Table/Variable Length Field */
+#define KEY_SGF                 0x01000000
+#define KEY_VLF                 0x01000000
+
+/* Immediate - Key follows command in the descriptor */
+#define KEY_IMM                 0x00800000
+
+/*
+ * Encrypted - Key is encrypted either with the KEK, or
+ * with the TDKEK if TK is set
+ */
+#define KEY_ENC                 0x00400000
+
+/*
+ * No Write Back - Do not allow key to be FIFO STOREd
+ */
+#define KEY_NWB			0x00200000
+
+/*
+ * Enhanced Encryption of Key
+ */
+#define KEY_EKT			0x00100000
+
+/*
+ * Encrypted with Trusted Key
+ */
+#define KEY_TK			0x00008000
+
+/*
+ * KDEST - Key Destination: 0 - class key register,
+ * 1 - PKHA 'e', 2 - AFHA Sbox, 3 - MDHA split-key
+ */
+#define KEY_DEST_SHIFT          16
+#define KEY_DEST_MASK           (0x03 << KEY_DEST_SHIFT)
+
+#define KEY_DEST_CLASS_REG      (0x00 << KEY_DEST_SHIFT)
+#define KEY_DEST_PKHA_E         (0x01 << KEY_DEST_SHIFT)
+#define KEY_DEST_AFHA_SBOX      (0x02 << KEY_DEST_SHIFT)
+#define KEY_DEST_MDHA_SPLIT     (0x03 << KEY_DEST_SHIFT)
+
+/* Length in bytes */
+#define KEY_LENGTH_MASK         0x000003ff
+
+/*
+ * LOAD/SEQ_LOAD/STORE/SEQ_STORE Command Constructs
+ */
+
+/*
+ * Load/Store Destination: 0 = class independent CCB,
+ * 1 = class 1 CCB, 2 = class 2 CCB, 3 = DECO
+ */
+#define LDST_CLASS_SHIFT        25
+#define LDST_CLASS_MASK         (0x03 << LDST_CLASS_SHIFT)
+#define LDST_CLASS_IND_CCB      (0x00 << LDST_CLASS_SHIFT)
+#define LDST_CLASS_1_CCB        (0x01 << LDST_CLASS_SHIFT)
+#define LDST_CLASS_2_CCB        (0x02 << LDST_CLASS_SHIFT)
+#define LDST_CLASS_DECO         (0x03 << LDST_CLASS_SHIFT)
+
+/* Scatter-Gather Table/Variable Length Field */
+#define LDST_SGF                0x01000000
+#define LDST_VLF		LDST_SGF
+
+/* Immediate - Key follows this command in descriptor    */
+#define LDST_IMM_MASK           1
+#define LDST_IMM_SHIFT          23
+#define LDST_IMM                (LDST_IMM_MASK << LDST_IMM_SHIFT)
+
+/* SRC/DST - Destination for LOAD, Source for STORE   */
+#define LDST_SRCDST_SHIFT       16
+#define LDST_SRCDST_MASK        (0x7f << LDST_SRCDST_SHIFT)
+
+#define LDST_SRCDST_BYTE_CONTEXT	(0x20 << LDST_SRCDST_SHIFT)
+#define LDST_SRCDST_BYTE_KEY		(0x40 << LDST_SRCDST_SHIFT)
+#define LDST_SRCDST_BYTE_INFIFO		(0x7c << LDST_SRCDST_SHIFT)
+#define LDST_SRCDST_BYTE_OUTFIFO	(0x7e << LDST_SRCDST_SHIFT)
+
+#define LDST_SRCDST_WORD_MODE_REG	(0x00 << LDST_SRCDST_SHIFT)
+#define LDST_SRCDST_WORD_KEYSZ_REG	(0x01 << LDST_SRCDST_SHIFT)
+#define LDST_SRCDST_WORD_DATASZ_REG	(0x02 << LDST_SRCDST_SHIFT)
+#define LDST_SRCDST_WORD_ICVSZ_REG	(0x03 << LDST_SRCDST_SHIFT)
+#define LDST_SRCDST_WORD_CHACTRL	(0x06 << LDST_SRCDST_SHIFT)
+#define LDST_SRCDST_WORD_DECOCTRL       (0x06 << LDST_SRCDST_SHIFT)
+#define LDST_SRCDST_WORD_IRQCTRL	(0x07 << LDST_SRCDST_SHIFT)
+#define LDST_SRCDST_WORD_DECO_PCLOVRD   (0x07 << LDST_SRCDST_SHIFT)
+#define LDST_SRCDST_WORD_CLRW		(0x08 << LDST_SRCDST_SHIFT)
+#define LDST_SRCDST_WORD_DECO_MATH0     (0x08 << LDST_SRCDST_SHIFT)
+#define LDST_SRCDST_WORD_STAT		(0x09 << LDST_SRCDST_SHIFT)
+#define LDST_SRCDST_WORD_DECO_MATH1     (0x09 << LDST_SRCDST_SHIFT)
+#define LDST_SRCDST_WORD_DECO_MATH2     (0x0a << LDST_SRCDST_SHIFT)
+#define LDST_SRCDST_WORD_DECO_AAD_SZ    (0x0b << LDST_SRCDST_SHIFT)
+#define LDST_SRCDST_WORD_DECO_MATH3     (0x0b << LDST_SRCDST_SHIFT)
+#define LDST_SRCDST_WORD_CLASS1_ICV_SZ  (0x0c << LDST_SRCDST_SHIFT)
+#define LDST_SRCDST_WORD_ALTDS_CLASS1   (0x0f << LDST_SRCDST_SHIFT)
+#define LDST_SRCDST_WORD_PKHA_A_SZ      (0x10 << LDST_SRCDST_SHIFT)
+#define LDST_SRCDST_WORD_PKHA_B_SZ      (0x11 << LDST_SRCDST_SHIFT)
+#define LDST_SRCDST_WORD_PKHA_N_SZ      (0x12 << LDST_SRCDST_SHIFT)
+#define LDST_SRCDST_WORD_PKHA_E_SZ      (0x13 << LDST_SRCDST_SHIFT)
+#define LDST_SRCDST_WORD_DESCBUF        (0x40 << LDST_SRCDST_SHIFT)
+#define LDST_SRCDST_WORD_INFO_FIFO      (0x7a << LDST_SRCDST_SHIFT)
+
+/* Offset in source/destination                        */
+#define LDST_OFFSET_SHIFT       8
+#define LDST_OFFSET_MASK        (0xff << LDST_OFFSET_SHIFT)
+
+/* LDOFF definitions used when DST = LDST_SRCDST_WORD_DECOCTRL */
+/* These could also be shifted by LDST_OFFSET_SHIFT - this reads better */
+#define LDOFF_CHG_SHARE_SHIFT        0
+#define LDOFF_CHG_SHARE_MASK         (0x3 << LDOFF_CHG_SHARE_SHIFT)
+#define LDOFF_CHG_SHARE_NEVER        (0x1 << LDOFF_CHG_SHARE_SHIFT)
+#define LDOFF_CHG_SHARE_OK_NO_PROP   (0x2 << LDOFF_CHG_SHARE_SHIFT)
+#define LDOFF_CHG_SHARE_OK_PROP      (0x3 << LDOFF_CHG_SHARE_SHIFT)
+
+#define LDOFF_ENABLE_AUTO_NFIFO         (1 << 2)
+#define LDOFF_DISABLE_AUTO_NFIFO        (1 << 3)
+
+#define LDOFF_CHG_NONSEQLIODN_SHIFT     4
+#define LDOFF_CHG_NONSEQLIODN_MASK      (0x3 << LDOFF_CHG_NONSEQLIODN_SHIFT)
+#define LDOFF_CHG_NONSEQLIODN_SEQ       (0x1 << LDOFF_CHG_NONSEQLIODN_SHIFT)
+#define LDOFF_CHG_NONSEQLIODN_NON_SEQ   (0x2 << LDOFF_CHG_NONSEQLIODN_SHIFT)
+#define LDOFF_CHG_NONSEQLIODN_TRUSTED   (0x3 << LDOFF_CHG_NONSEQLIODN_SHIFT)
+
+#define LDOFF_CHG_SEQLIODN_SHIFT     6
+#define LDOFF_CHG_SEQLIODN_MASK      (0x3 << LDOFF_CHG_SEQLIODN_SHIFT)
+#define LDOFF_CHG_SEQLIODN_SEQ       (0x1 << LDOFF_CHG_SEQLIODN_SHIFT)
+#define LDOFF_CHG_SEQLIODN_NON_SEQ   (0x2 << LDOFF_CHG_SEQLIODN_SHIFT)
+#define LDOFF_CHG_SEQLIODN_TRUSTED   (0x3 << LDOFF_CHG_SEQLIODN_SHIFT)
+
+/* Data length in bytes                                 */
+#define LDST_LEN_SHIFT          0
+#define LDST_LEN_MASK           (0xff << LDST_LEN_SHIFT)
+
+/* Special Length definitions when dst=deco-ctrl */
+#define LDLEN_ENABLE_OSL_COUNT      (1 << 7)
+#define LDLEN_RST_CHA_OFIFO_PTR     (1 << 6)
+#define LDLEN_RST_OFIFO             (1 << 5)
+#define LDLEN_SET_OFIFO_OFF_VALID   (1 << 4)
+#define LDLEN_SET_OFIFO_OFF_RSVD    (1 << 3)
+#define LDLEN_SET_OFIFO_OFFSET_SHIFT 0
+#define LDLEN_SET_OFIFO_OFFSET_MASK (3 << LDLEN_SET_OFIFO_OFFSET_SHIFT)
+
+/*
+ * FIFO_LOAD/FIFO_STORE/SEQ_FIFO_LOAD/SEQ_FIFO_STORE
+ * Command Constructs
+ */
+
+/*
+ * Load Destination: 0 = skip (SEQ_FIFO_LOAD only),
+ * 1 = Load for Class1, 2 = Load for Class2, 3 = Load both
+ * Store Source: 0 = normal, 1 = Class1key, 2 = Class2key
+ */
+#define FIFOLD_CLASS_SHIFT      25
+#define FIFOLD_CLASS_MASK       (0x03 << FIFOLD_CLASS_SHIFT)
+#define FIFOLD_CLASS_SKIP       (0x00 << FIFOLD_CLASS_SHIFT)
+#define FIFOLD_CLASS_CLASS1     (0x01 << FIFOLD_CLASS_SHIFT)
+#define FIFOLD_CLASS_CLASS2     (0x02 << FIFOLD_CLASS_SHIFT)
+#define FIFOLD_CLASS_BOTH       (0x03 << FIFOLD_CLASS_SHIFT)
+
+#define FIFOST_CLASS_SHIFT      25
+#define FIFOST_CLASS_MASK       (0x03 << FIFOST_CLASS_SHIFT)
+#define FIFOST_CLASS_NORMAL     (0x00 << FIFOST_CLASS_SHIFT)
+#define FIFOST_CLASS_CLASS1KEY  (0x01 << FIFOST_CLASS_SHIFT)
+#define FIFOST_CLASS_CLASS2KEY  (0x02 << FIFOST_CLASS_SHIFT)
+
+/*
+ * Scatter-Gather Table/Variable Length Field
+ * If set for FIFO_LOAD, refers to a SG table. Within
+ * SEQ_FIFO_LOAD, is variable input sequence
+ */
+#define FIFOLDST_SGF_SHIFT      24
+#define FIFOLDST_SGF_MASK       (1 << FIFOLDST_SGF_SHIFT)
+#define FIFOLDST_VLF_MASK       (1 << FIFOLDST_SGF_SHIFT)
+#define FIFOLDST_SGF            (1 << FIFOLDST_SGF_SHIFT)
+#define FIFOLDST_VLF            (1 << FIFOLDST_SGF_SHIFT)
+
+/* Immediate - Data follows command in descriptor */
+#define FIFOLD_IMM_SHIFT      23
+#define FIFOLD_IMM_MASK       (1 << FIFOLD_IMM_SHIFT)
+#define FIFOLD_IMM            (1 << FIFOLD_IMM_SHIFT)
+
+/* Continue - Not the last FIFO store to come */
+#define FIFOST_CONT_SHIFT     23
+#define FIFOST_CONT_MASK      (1 << FIFOST_CONT_SHIFT)
+#define FIFOST_CONT_MASK      (1 << FIFOST_CONT_SHIFT)
+
+/*
+ * Extended Length - use 32-bit extended length that
+ * follows the pointer field. Illegal with IMM set
+ */
+#define FIFOLDST_EXT_SHIFT      22
+#define FIFOLDST_EXT_MASK       (1 << FIFOLDST_EXT_SHIFT)
+#define FIFOLDST_EXT            (1 << FIFOLDST_EXT_SHIFT)
+
+/* Input data type.*/
+#define FIFOLD_TYPE_SHIFT       16
+#define FIFOLD_CONT_TYPE_SHIFT  19 /* shift past last-flush bits */
+#define FIFOLD_TYPE_MASK        (0x3f << FIFOLD_TYPE_SHIFT)
+
+/* PK types */
+#define FIFOLD_TYPE_PK          (0x00 << FIFOLD_TYPE_SHIFT)
+#define FIFOLD_TYPE_PK_MASK     (0x30 << FIFOLD_TYPE_SHIFT)
+#define FIFOLD_TYPE_PK_TYPEMASK (0x0f << FIFOLD_TYPE_SHIFT)
+#define FIFOLD_TYPE_PK_A0       (0x00 << FIFOLD_TYPE_SHIFT)
+#define FIFOLD_TYPE_PK_A1       (0x01 << FIFOLD_TYPE_SHIFT)
+#define FIFOLD_TYPE_PK_A2       (0x02 << FIFOLD_TYPE_SHIFT)
+#define FIFOLD_TYPE_PK_A3       (0x03 << FIFOLD_TYPE_SHIFT)
+#define FIFOLD_TYPE_PK_B0       (0x04 << FIFOLD_TYPE_SHIFT)
+#define FIFOLD_TYPE_PK_B1       (0x05 << FIFOLD_TYPE_SHIFT)
+#define FIFOLD_TYPE_PK_B2       (0x06 << FIFOLD_TYPE_SHIFT)
+#define FIFOLD_TYPE_PK_B3       (0x07 << FIFOLD_TYPE_SHIFT)
+#define FIFOLD_TYPE_PK_N        (0x08 << FIFOLD_TYPE_SHIFT)
+#define FIFOLD_TYPE_PK_A        (0x0c << FIFOLD_TYPE_SHIFT)
+#define FIFOLD_TYPE_PK_B        (0x0d << FIFOLD_TYPE_SHIFT)
+
+/* Other types. Need to OR in last/flush bits as desired */
+#define FIFOLD_TYPE_MSG_MASK    (0x38 << FIFOLD_TYPE_SHIFT)
+#define FIFOLD_TYPE_MSG         (0x10 << FIFOLD_TYPE_SHIFT)
+#define FIFOLD_TYPE_MSG1OUT2    (0x18 << FIFOLD_TYPE_SHIFT)
+#define FIFOLD_TYPE_IV          (0x20 << FIFOLD_TYPE_SHIFT)
+#define FIFOLD_TYPE_BITDATA     (0x28 << FIFOLD_TYPE_SHIFT)
+#define FIFOLD_TYPE_AAD         (0x30 << FIFOLD_TYPE_SHIFT)
+#define FIFOLD_TYPE_ICV         (0x38 << FIFOLD_TYPE_SHIFT)
+
+/* Last/Flush bits for use with "other" types above */
+#define FIFOLD_TYPE_ACT_MASK    (0x07 << FIFOLD_TYPE_SHIFT)
+#define FIFOLD_TYPE_NOACTION    (0x00 << FIFOLD_TYPE_SHIFT)
+#define FIFOLD_TYPE_FLUSH1      (0x01 << FIFOLD_TYPE_SHIFT)
+#define FIFOLD_TYPE_LAST1       (0x02 << FIFOLD_TYPE_SHIFT)
+#define FIFOLD_TYPE_LAST2FLUSH  (0x03 << FIFOLD_TYPE_SHIFT)
+#define FIFOLD_TYPE_LAST2       (0x04 << FIFOLD_TYPE_SHIFT)
+#define FIFOLD_TYPE_LAST2FLUSH1 (0x05 << FIFOLD_TYPE_SHIFT)
+#define FIFOLD_TYPE_LASTBOTH    (0x06 << FIFOLD_TYPE_SHIFT)
+#define FIFOLD_TYPE_LASTBOTHFL  (0x07 << FIFOLD_TYPE_SHIFT)
+
+#define FIFOLDST_LEN_MASK       0xffff
+#define FIFOLDST_EXT_LEN_MASK   0xffffffff
+
+/* Output data types */
+#define FIFOST_TYPE_SHIFT       16
+#define FIFOST_TYPE_MASK        (0x3f << FIFOST_TYPE_SHIFT)
+
+#define FIFOST_TYPE_PKHA_A0      (0x00 << FIFOST_TYPE_SHIFT)
+#define FIFOST_TYPE_PKHA_A1      (0x01 << FIFOST_TYPE_SHIFT)
+#define FIFOST_TYPE_PKHA_A2      (0x02 << FIFOST_TYPE_SHIFT)
+#define FIFOST_TYPE_PKHA_A3      (0x03 << FIFOST_TYPE_SHIFT)
+#define FIFOST_TYPE_PKHA_B0      (0x04 << FIFOST_TYPE_SHIFT)
+#define FIFOST_TYPE_PKHA_B1      (0x05 << FIFOST_TYPE_SHIFT)
+#define FIFOST_TYPE_PKHA_B2      (0x06 << FIFOST_TYPE_SHIFT)
+#define FIFOST_TYPE_PKHA_B3      (0x07 << FIFOST_TYPE_SHIFT)
+#define FIFOST_TYPE_PKHA_N       (0x08 << FIFOST_TYPE_SHIFT)
+#define FIFOST_TYPE_PKHA_A       (0x0c << FIFOST_TYPE_SHIFT)
+#define FIFOST_TYPE_PKHA_B       (0x0d << FIFOST_TYPE_SHIFT)
+#define FIFOST_TYPE_AF_SBOX_JKEK (0x10 << FIFOST_TYPE_SHIFT)
+#define FIFOST_TYPE_AF_SBOX_TKEK (0x21 << FIFOST_TYPE_SHIFT)
+#define FIFOST_TYPE_PKHA_E_JKEK  (0x22 << FIFOST_TYPE_SHIFT)
+#define FIFOST_TYPE_PKHA_E_TKEK  (0x23 << FIFOST_TYPE_SHIFT)
+#define FIFOST_TYPE_KEY_KEK      (0x24 << FIFOST_TYPE_SHIFT)
+#define FIFOST_TYPE_KEY_TKEK     (0x25 << FIFOST_TYPE_SHIFT)
+#define FIFOST_TYPE_SPLIT_KEK    (0x26 << FIFOST_TYPE_SHIFT)
+#define FIFOST_TYPE_SPLIT_TKEK   (0x27 << FIFOST_TYPE_SHIFT)
+#define FIFOST_TYPE_OUTFIFO_KEK  (0x28 << FIFOST_TYPE_SHIFT)
+#define FIFOST_TYPE_OUTFIFO_TKEK (0x29 << FIFOST_TYPE_SHIFT)
+#define FIFOST_TYPE_MESSAGE_DATA (0x30 << FIFOST_TYPE_SHIFT)
+#define FIFOST_TYPE_RNGSTORE     (0x34 << FIFOST_TYPE_SHIFT)
+#define FIFOST_TYPE_RNGFIFO      (0x35 << FIFOST_TYPE_SHIFT)
+#define FIFOST_TYPE_SKIP         (0x3f << FIFOST_TYPE_SHIFT)
+
+/*
+ * OPERATION Command Constructs
+ */
+
+/* Operation type selectors - OP TYPE */
+#define OP_TYPE_SHIFT           24
+#define OP_TYPE_MASK            (0x07 << OP_TYPE_SHIFT)
+
+#define OP_TYPE_UNI_PROTOCOL    (0x00 << OP_TYPE_SHIFT)
+#define OP_TYPE_PK              (0x01 << OP_TYPE_SHIFT)
+#define OP_TYPE_CLASS1_ALG      (0x02 << OP_TYPE_SHIFT)
+#define OP_TYPE_CLASS2_ALG      (0x04 << OP_TYPE_SHIFT)
+#define OP_TYPE_DECAP_PROTOCOL  (0x06 << OP_TYPE_SHIFT)
+#define OP_TYPE_ENCAP_PROTOCOL  (0x07 << OP_TYPE_SHIFT)
+
+/* ProtocolID selectors - PROTID */
+#define OP_PCLID_SHIFT          16
+#define OP_PCLID_MASK           (0xff << 16)
+
+/* Assuming OP_TYPE = OP_TYPE_UNI_PROTOCOL */
+#define OP_PCLID_IKEV1_PRF      (0x01 << OP_PCLID_SHIFT)
+#define OP_PCLID_IKEV2_PRF      (0x02 << OP_PCLID_SHIFT)
+#define OP_PCLID_SSL30_PRF      (0x08 << OP_PCLID_SHIFT)
+#define OP_PCLID_TLS10_PRF      (0x09 << OP_PCLID_SHIFT)
+#define OP_PCLID_TLS11_PRF      (0x0a << OP_PCLID_SHIFT)
+#define OP_PCLID_DTLS10_PRF     (0x0c << OP_PCLID_SHIFT)
+#define OP_PCLID_PRF            (0x06 << OP_PCLID_SHIFT)
+#define OP_PCLID_BLOB           (0x0d << OP_PCLID_SHIFT)
+#define OP_PCLID_SECRETKEY      (0x11 << OP_PCLID_SHIFT)
+#define OP_PCLID_PUBLICKEYPAIR  (0x14 << OP_PCLID_SHIFT)
+#define OP_PCLID_DSASIGN        (0x15 << OP_PCLID_SHIFT)
+#define OP_PCLID_DSAVERIFY      (0x16 << OP_PCLID_SHIFT)
+
+/* Assuming OP_TYPE = OP_TYPE_DECAP_PROTOCOL/ENCAP_PROTOCOL */
+#define OP_PCLID_IPSEC          (0x01 << OP_PCLID_SHIFT)
+#define OP_PCLID_SRTP           (0x02 << OP_PCLID_SHIFT)
+#define OP_PCLID_MACSEC         (0x03 << OP_PCLID_SHIFT)
+#define OP_PCLID_WIFI           (0x04 << OP_PCLID_SHIFT)
+#define OP_PCLID_WIMAX          (0x05 << OP_PCLID_SHIFT)
+#define OP_PCLID_SSL30          (0x08 << OP_PCLID_SHIFT)
+#define OP_PCLID_TLS10          (0x09 << OP_PCLID_SHIFT)
+#define OP_PCLID_TLS11          (0x0a << OP_PCLID_SHIFT)
+#define OP_PCLID_TLS12          (0x0b << OP_PCLID_SHIFT)
+#define OP_PCLID_DTLS           (0x0c << OP_PCLID_SHIFT)
+
+/*
+ * ProtocolInfo selectors
+ */
+#define OP_PCLINFO_MASK                          0xffff
+
+/* for OP_PCLID_IPSEC */
+#define OP_PCL_IPSEC_CIPHER_MASK                 0xff00
+#define OP_PCL_IPSEC_AUTH_MASK                   0x00ff
+
+#define OP_PCL_IPSEC_DES_IV64                    0x0100
+#define OP_PCL_IPSEC_DES                         0x0200
+#define OP_PCL_IPSEC_3DES                        0x0300
+#define OP_PCL_IPSEC_AES_CBC                     0x0c00
+#define OP_PCL_IPSEC_AES_CTR                     0x0d00
+#define OP_PCL_IPSEC_AES_XTS                     0x1600
+#define OP_PCL_IPSEC_AES_CCM8                    0x0e00
+#define OP_PCL_IPSEC_AES_CCM12                   0x0f00
+#define OP_PCL_IPSEC_AES_CCM16                   0x1000
+#define OP_PCL_IPSEC_AES_GCM8                    0x1200
+#define OP_PCL_IPSEC_AES_GCM12                   0x1300
+#define OP_PCL_IPSEC_AES_GCM16                   0x1400
+
+#define OP_PCL_IPSEC_HMAC_NULL                   0x0000
+#define OP_PCL_IPSEC_HMAC_MD5_96                 0x0001
+#define OP_PCL_IPSEC_HMAC_SHA1_96                0x0002
+#define OP_PCL_IPSEC_AES_XCBC_MAC_96             0x0005
+#define OP_PCL_IPSEC_HMAC_MD5_128                0x0006
+#define OP_PCL_IPSEC_HMAC_SHA1_160               0x0007
+#define OP_PCL_IPSEC_HMAC_SHA2_256_128           0x000c
+#define OP_PCL_IPSEC_HMAC_SHA2_384_192           0x000d
+#define OP_PCL_IPSEC_HMAC_SHA2_512_256           0x000e
+
+/* For SRTP - OP_PCLID_SRTP */
+#define OP_PCL_SRTP_CIPHER_MASK                  0xff00
+#define OP_PCL_SRTP_AUTH_MASK                    0x00ff
+
+#define OP_PCL_SRTP_AES_CTR                      0x0d00
+
+#define OP_PCL_SRTP_HMAC_SHA1_160                0x0007
+
+/* For SSL 3.0 - OP_PCLID_SSL30 */
+#define OP_PCL_SSL30_AES_128_CBC_SHA             0x002f
+#define OP_PCL_SSL30_AES_128_CBC_SHA_2           0x0030
+#define OP_PCL_SSL30_AES_128_CBC_SHA_3           0x0031
+#define OP_PCL_SSL30_AES_128_CBC_SHA_4           0x0032
+#define OP_PCL_SSL30_AES_128_CBC_SHA_5           0x0033
+#define OP_PCL_SSL30_AES_128_CBC_SHA_6           0x0034
+#define OP_PCL_SSL30_AES_128_CBC_SHA_7           0x008c
+#define OP_PCL_SSL30_AES_128_CBC_SHA_8           0x0090
+#define OP_PCL_SSL30_AES_128_CBC_SHA_9           0x0094
+#define OP_PCL_SSL30_AES_128_CBC_SHA_10          0xc004
+#define OP_PCL_SSL30_AES_128_CBC_SHA_11          0xc009
+#define OP_PCL_SSL30_AES_128_CBC_SHA_12          0xc00e
+#define OP_PCL_SSL30_AES_128_CBC_SHA_13          0xc013
+#define OP_PCL_SSL30_AES_128_CBC_SHA_14          0xc018
+#define OP_PCL_SSL30_AES_128_CBC_SHA_15          0xc01d
+#define OP_PCL_SSL30_AES_128_CBC_SHA_16          0xc01e
+#define OP_PCL_SSL30_AES_128_CBC_SHA_17          0xc01f
+
+#define OP_PCL_SSL30_AES_256_CBC_SHA             0x0035
+#define OP_PCL_SSL30_AES_256_CBC_SHA_2           0x0036
+#define OP_PCL_SSL30_AES_256_CBC_SHA_3           0x0037
+#define OP_PCL_SSL30_AES_256_CBC_SHA_4           0x0038
+#define OP_PCL_SSL30_AES_256_CBC_SHA_5           0x0039
+#define OP_PCL_SSL30_AES_256_CBC_SHA_6           0x003a
+#define OP_PCL_SSL30_AES_256_CBC_SHA_7           0x008d
+#define OP_PCL_SSL30_AES_256_CBC_SHA_8           0x0091
+#define OP_PCL_SSL30_AES_256_CBC_SHA_9           0x0095
+#define OP_PCL_SSL30_AES_256_CBC_SHA_10          0xc005
+#define OP_PCL_SSL30_AES_256_CBC_SHA_11          0xc00a
+#define OP_PCL_SSL30_AES_256_CBC_SHA_12          0xc00f
+#define OP_PCL_SSL30_AES_256_CBC_SHA_13          0xc014
+#define OP_PCL_SSL30_AES_256_CBC_SHA_14          0xc019
+#define OP_PCL_SSL30_AES_256_CBC_SHA_15          0xc020
+#define OP_PCL_SSL30_AES_256_CBC_SHA_16          0xc021
+#define OP_PCL_SSL30_AES_256_CBC_SHA_17          0xc022
+
+#define OP_PCL_SSL30_3DES_EDE_CBC_MD5            0x0023
+
+#define OP_PCL_SSL30_3DES_EDE_CBC_SHA            0x001f
+#define OP_PCL_SSL30_3DES_EDE_CBC_SHA_2          0x008b
+#define OP_PCL_SSL30_3DES_EDE_CBC_SHA_3          0x008f
+#define OP_PCL_SSL30_3DES_EDE_CBC_SHA_4          0x0093
+#define OP_PCL_SSL30_3DES_EDE_CBC_SHA_5          0x000a
+#define OP_PCL_SSL30_3DES_EDE_CBC_SHA_6          0x000d
+#define OP_PCL_SSL30_3DES_EDE_CBC_SHA_7          0x0010
+#define OP_PCL_SSL30_3DES_EDE_CBC_SHA_8          0x0013
+#define OP_PCL_SSL30_3DES_EDE_CBC_SHA_9          0x0016
+#define OP_PCL_SSL30_3DES_EDE_CBC_SHA_10         0x001b
+#define OP_PCL_SSL30_3DES_EDE_CBC_SHA_11         0xc003
+#define OP_PCL_SSL30_3DES_EDE_CBC_SHA_12         0xc008
+#define OP_PCL_SSL30_3DES_EDE_CBC_SHA_13         0xc00d
+#define OP_PCL_SSL30_3DES_EDE_CBC_SHA_14         0xc012
+#define OP_PCL_SSL30_3DES_EDE_CBC_SHA_15         0xc017
+#define OP_PCL_SSL30_3DES_EDE_CBC_SHA_16         0xc01a
+#define OP_PCL_SSL30_3DES_EDE_CBC_SHA_17         0xc01b
+#define OP_PCL_SSL30_3DES_EDE_CBC_SHA_18         0xc01c
+
+#define OP_PCL_SSL30_DES40_CBC_MD5               0x0029
+
+#define OP_PCL_SSL30_DES_CBC_MD5                 0x0022
+
+#define OP_PCL_SSL30_DES40_CBC_SHA               0x0008
+#define OP_PCL_SSL30_DES40_CBC_SHA_2             0x000b
+#define OP_PCL_SSL30_DES40_CBC_SHA_3             0x000e
+#define OP_PCL_SSL30_DES40_CBC_SHA_4             0x0011
+#define OP_PCL_SSL30_DES40_CBC_SHA_5             0x0014
+#define OP_PCL_SSL30_DES40_CBC_SHA_6             0x0019
+#define OP_PCL_SSL30_DES40_CBC_SHA_7             0x0026
+
+#define OP_PCL_SSL30_DES_CBC_SHA                 0x001e
+#define OP_PCL_SSL30_DES_CBC_SHA_2               0x0009
+#define OP_PCL_SSL30_DES_CBC_SHA_3               0x000c
+#define OP_PCL_SSL30_DES_CBC_SHA_4               0x000f
+#define OP_PCL_SSL30_DES_CBC_SHA_5               0x0012
+#define OP_PCL_SSL30_DES_CBC_SHA_6               0x0015
+#define OP_PCL_SSL30_DES_CBC_SHA_7               0x001a
+
+#define OP_PCL_SSL30_RC4_128_MD5                 0x0024
+#define OP_PCL_SSL30_RC4_128_MD5_2               0x0004
+#define OP_PCL_SSL30_RC4_128_MD5_3               0x0018
+
+#define OP_PCL_SSL30_RC4_40_MD5                  0x002b
+#define OP_PCL_SSL30_RC4_40_MD5_2                0x0003
+#define OP_PCL_SSL30_RC4_40_MD5_3                0x0017
+
+#define OP_PCL_SSL30_RC4_128_SHA                 0x0020
+#define OP_PCL_SSL30_RC4_128_SHA_2               0x008a
+#define OP_PCL_SSL30_RC4_128_SHA_3               0x008e
+#define OP_PCL_SSL30_RC4_128_SHA_4               0x0092
+#define OP_PCL_SSL30_RC4_128_SHA_5               0x0005
+#define OP_PCL_SSL30_RC4_128_SHA_6               0xc002
+#define OP_PCL_SSL30_RC4_128_SHA_7               0xc007
+#define OP_PCL_SSL30_RC4_128_SHA_8               0xc00c
+#define OP_PCL_SSL30_RC4_128_SHA_9               0xc011
+#define OP_PCL_SSL30_RC4_128_SHA_10              0xc016
+
+#define OP_PCL_SSL30_RC4_40_SHA                  0x0028
+
+
+/* For TLS 1.0 - OP_PCLID_TLS10 */
+#define OP_PCL_TLS10_AES_128_CBC_SHA             0x002f
+#define OP_PCL_TLS10_AES_128_CBC_SHA_2           0x0030
+#define OP_PCL_TLS10_AES_128_CBC_SHA_3           0x0031
+#define OP_PCL_TLS10_AES_128_CBC_SHA_4           0x0032
+#define OP_PCL_TLS10_AES_128_CBC_SHA_5           0x0033
+#define OP_PCL_TLS10_AES_128_CBC_SHA_6           0x0034
+#define OP_PCL_TLS10_AES_128_CBC_SHA_7           0x008c
+#define OP_PCL_TLS10_AES_128_CBC_SHA_8           0x0090
+#define OP_PCL_TLS10_AES_128_CBC_SHA_9           0x0094
+#define OP_PCL_TLS10_AES_128_CBC_SHA_10          0xc004
+#define OP_PCL_TLS10_AES_128_CBC_SHA_11          0xc009
+#define OP_PCL_TLS10_AES_128_CBC_SHA_12          0xc00e
+#define OP_PCL_TLS10_AES_128_CBC_SHA_13          0xc013
+#define OP_PCL_TLS10_AES_128_CBC_SHA_14          0xc018
+#define OP_PCL_TLS10_AES_128_CBC_SHA_15          0xc01d
+#define OP_PCL_TLS10_AES_128_CBC_SHA_16          0xc01e
+#define OP_PCL_TLS10_AES_128_CBC_SHA_17          0xc01f
+
+#define OP_PCL_TLS10_AES_256_CBC_SHA             0x0035
+#define OP_PCL_TLS10_AES_256_CBC_SHA_2           0x0036
+#define OP_PCL_TLS10_AES_256_CBC_SHA_3           0x0037
+#define OP_PCL_TLS10_AES_256_CBC_SHA_4           0x0038
+#define OP_PCL_TLS10_AES_256_CBC_SHA_5           0x0039
+#define OP_PCL_TLS10_AES_256_CBC_SHA_6           0x003a
+#define OP_PCL_TLS10_AES_256_CBC_SHA_7           0x008d
+#define OP_PCL_TLS10_AES_256_CBC_SHA_8           0x0091
+#define OP_PCL_TLS10_AES_256_CBC_SHA_9           0x0095
+#define OP_PCL_TLS10_AES_256_CBC_SHA_10          0xc005
+#define OP_PCL_TLS10_AES_256_CBC_SHA_11          0xc00a
+#define OP_PCL_TLS10_AES_256_CBC_SHA_12          0xc00f
+#define OP_PCL_TLS10_AES_256_CBC_SHA_13          0xc014
+#define OP_PCL_TLS10_AES_256_CBC_SHA_14          0xc019
+#define OP_PCL_TLS10_AES_256_CBC_SHA_15          0xc020
+#define OP_PCL_TLS10_AES_256_CBC_SHA_16          0xc021
+#define OP_PCL_TLS10_AES_256_CBC_SHA_17          0xc022
+
+/* #define OP_PCL_TLS10_3DES_EDE_CBC_MD5            0x0023 */
+
+#define OP_PCL_TLS10_3DES_EDE_CBC_SHA            0x001f
+#define OP_PCL_TLS10_3DES_EDE_CBC_SHA_2          0x008b
+#define OP_PCL_TLS10_3DES_EDE_CBC_SHA_3          0x008f
+#define OP_PCL_TLS10_3DES_EDE_CBC_SHA_4          0x0093
+#define OP_PCL_TLS10_3DES_EDE_CBC_SHA_5          0x000a
+#define OP_PCL_TLS10_3DES_EDE_CBC_SHA_6          0x000d
+#define OP_PCL_TLS10_3DES_EDE_CBC_SHA_7          0x0010
+#define OP_PCL_TLS10_3DES_EDE_CBC_SHA_8          0x0013
+#define OP_PCL_TLS10_3DES_EDE_CBC_SHA_9          0x0016
+#define OP_PCL_TLS10_3DES_EDE_CBC_SHA_10         0x001b
+#define OP_PCL_TLS10_3DES_EDE_CBC_SHA_11         0xc003
+#define OP_PCL_TLS10_3DES_EDE_CBC_SHA_12         0xc008
+#define OP_PCL_TLS10_3DES_EDE_CBC_SHA_13         0xc00d
+#define OP_PCL_TLS10_3DES_EDE_CBC_SHA_14         0xc012
+#define OP_PCL_TLS10_3DES_EDE_CBC_SHA_15         0xc017
+#define OP_PCL_TLS10_3DES_EDE_CBC_SHA_16         0xc01a
+#define OP_PCL_TLS10_3DES_EDE_CBC_SHA_17         0xc01b
+#define OP_PCL_TLS10_3DES_EDE_CBC_SHA_18         0xc01c
+
+#define OP_PCL_TLS10_DES40_CBC_MD5               0x0029
+
+#define OP_PCL_TLS10_DES_CBC_MD5                 0x0022
+
+#define OP_PCL_TLS10_DES40_CBC_SHA               0x0008
+#define OP_PCL_TLS10_DES40_CBC_SHA_2             0x000b
+#define OP_PCL_TLS10_DES40_CBC_SHA_3             0x000e
+#define OP_PCL_TLS10_DES40_CBC_SHA_4             0x0011
+#define OP_PCL_TLS10_DES40_CBC_SHA_5             0x0014
+#define OP_PCL_TLS10_DES40_CBC_SHA_6             0x0019
+#define OP_PCL_TLS10_DES40_CBC_SHA_7             0x0026
+
+
+#define OP_PCL_TLS10_DES_CBC_SHA                 0x001e
+#define OP_PCL_TLS10_DES_CBC_SHA_2               0x0009
+#define OP_PCL_TLS10_DES_CBC_SHA_3               0x000c
+#define OP_PCL_TLS10_DES_CBC_SHA_4               0x000f
+#define OP_PCL_TLS10_DES_CBC_SHA_5               0x0012
+#define OP_PCL_TLS10_DES_CBC_SHA_6               0x0015
+#define OP_PCL_TLS10_DES_CBC_SHA_7               0x001a
+
+#define OP_PCL_TLS10_RC4_128_MD5                 0x0024
+#define OP_PCL_TLS10_RC4_128_MD5_2               0x0004
+#define OP_PCL_TLS10_RC4_128_MD5_3               0x0018
+
+#define OP_PCL_TLS10_RC4_40_MD5                  0x002b
+#define OP_PCL_TLS10_RC4_40_MD5_2                0x0003
+#define OP_PCL_TLS10_RC4_40_MD5_3                0x0017
+
+#define OP_PCL_TLS10_RC4_128_SHA                 0x0020
+#define OP_PCL_TLS10_RC4_128_SHA_2               0x008a
+#define OP_PCL_TLS10_RC4_128_SHA_3               0x008e
+#define OP_PCL_TLS10_RC4_128_SHA_4               0x0092
+#define OP_PCL_TLS10_RC4_128_SHA_5               0x0005
+#define OP_PCL_TLS10_RC4_128_SHA_6               0xc002
+#define OP_PCL_TLS10_RC4_128_SHA_7               0xc007
+#define OP_PCL_TLS10_RC4_128_SHA_8               0xc00c
+#define OP_PCL_TLS10_RC4_128_SHA_9               0xc011
+#define OP_PCL_TLS10_RC4_128_SHA_10              0xc016
+
+#define OP_PCL_TLS10_RC4_40_SHA                  0x0028
+
+#define OP_PCL_TLS10_3DES_EDE_CBC_MD5            0xff23
+#define OP_PCL_TLS10_3DES_EDE_CBC_SHA160         0xff30
+#define OP_PCL_TLS10_3DES_EDE_CBC_SHA224         0xff34
+#define OP_PCL_TLS10_3DES_EDE_CBC_SHA256         0xff36
+#define OP_PCL_TLS10_3DES_EDE_CBC_SHA384         0xff33
+#define OP_PCL_TLS10_3DES_EDE_CBC_SHA512         0xff35
+#define OP_PCL_TLS10_AES_128_CBC_SHA160          0xff80
+#define OP_PCL_TLS10_AES_128_CBC_SHA224          0xff84
+#define OP_PCL_TLS10_AES_128_CBC_SHA256          0xff86
+#define OP_PCL_TLS10_AES_128_CBC_SHA384          0xff83
+#define OP_PCL_TLS10_AES_128_CBC_SHA512          0xff85
+#define OP_PCL_TLS10_AES_192_CBC_SHA160          0xff20
+#define OP_PCL_TLS10_AES_192_CBC_SHA224          0xff24
+#define OP_PCL_TLS10_AES_192_CBC_SHA256          0xff26
+#define OP_PCL_TLS10_AES_192_CBC_SHA384          0xff23
+#define OP_PCL_TLS10_AES_192_CBC_SHA512          0xff25
+#define OP_PCL_TLS10_AES_256_CBC_SHA160          0xff60
+#define OP_PCL_TLS10_AES_256_CBC_SHA224          0xff64
+#define OP_PCL_TLS10_AES_256_CBC_SHA256          0xff66
+#define OP_PCL_TLS10_AES_256_CBC_SHA384          0xff63
+#define OP_PCL_TLS10_AES_256_CBC_SHA512          0xff65
+
+
+
+/* For TLS 1.1 - OP_PCLID_TLS11 */
+#define OP_PCL_TLS11_AES_128_CBC_SHA             0x002f
+#define OP_PCL_TLS11_AES_128_CBC_SHA_2           0x0030
+#define OP_PCL_TLS11_AES_128_CBC_SHA_3           0x0031
+#define OP_PCL_TLS11_AES_128_CBC_SHA_4           0x0032
+#define OP_PCL_TLS11_AES_128_CBC_SHA_5           0x0033
+#define OP_PCL_TLS11_AES_128_CBC_SHA_6           0x0034
+#define OP_PCL_TLS11_AES_128_CBC_SHA_7           0x008c
+#define OP_PCL_TLS11_AES_128_CBC_SHA_8           0x0090
+#define OP_PCL_TLS11_AES_128_CBC_SHA_9           0x0094
+#define OP_PCL_TLS11_AES_128_CBC_SHA_10          0xc004
+#define OP_PCL_TLS11_AES_128_CBC_SHA_11          0xc009
+#define OP_PCL_TLS11_AES_128_CBC_SHA_12          0xc00e
+#define OP_PCL_TLS11_AES_128_CBC_SHA_13          0xc013
+#define OP_PCL_TLS11_AES_128_CBC_SHA_14          0xc018
+#define OP_PCL_TLS11_AES_128_CBC_SHA_15          0xc01d
+#define OP_PCL_TLS11_AES_128_CBC_SHA_16          0xc01e
+#define OP_PCL_TLS11_AES_128_CBC_SHA_17          0xc01f
+
+#define OP_PCL_TLS11_AES_256_CBC_SHA             0x0035
+#define OP_PCL_TLS11_AES_256_CBC_SHA_2           0x0036
+#define OP_PCL_TLS11_AES_256_CBC_SHA_3           0x0037
+#define OP_PCL_TLS11_AES_256_CBC_SHA_4           0x0038
+#define OP_PCL_TLS11_AES_256_CBC_SHA_5           0x0039
+#define OP_PCL_TLS11_AES_256_CBC_SHA_6           0x003a
+#define OP_PCL_TLS11_AES_256_CBC_SHA_7           0x008d
+#define OP_PCL_TLS11_AES_256_CBC_SHA_8           0x0091
+#define OP_PCL_TLS11_AES_256_CBC_SHA_9           0x0095
+#define OP_PCL_TLS11_AES_256_CBC_SHA_10          0xc005
+#define OP_PCL_TLS11_AES_256_CBC_SHA_11          0xc00a
+#define OP_PCL_TLS11_AES_256_CBC_SHA_12          0xc00f
+#define OP_PCL_TLS11_AES_256_CBC_SHA_13          0xc014
+#define OP_PCL_TLS11_AES_256_CBC_SHA_14          0xc019
+#define OP_PCL_TLS11_AES_256_CBC_SHA_15          0xc020
+#define OP_PCL_TLS11_AES_256_CBC_SHA_16          0xc021
+#define OP_PCL_TLS11_AES_256_CBC_SHA_17          0xc022
+
+/* #define OP_PCL_TLS11_3DES_EDE_CBC_MD5            0x0023 */
+
+#define OP_PCL_TLS11_3DES_EDE_CBC_SHA            0x001f
+#define OP_PCL_TLS11_3DES_EDE_CBC_SHA_2          0x008b
+#define OP_PCL_TLS11_3DES_EDE_CBC_SHA_3          0x008f
+#define OP_PCL_TLS11_3DES_EDE_CBC_SHA_4          0x0093
+#define OP_PCL_TLS11_3DES_EDE_CBC_SHA_5          0x000a
+#define OP_PCL_TLS11_3DES_EDE_CBC_SHA_6          0x000d
+#define OP_PCL_TLS11_3DES_EDE_CBC_SHA_7          0x0010
+#define OP_PCL_TLS11_3DES_EDE_CBC_SHA_8          0x0013
+#define OP_PCL_TLS11_3DES_EDE_CBC_SHA_9          0x0016
+#define OP_PCL_TLS11_3DES_EDE_CBC_SHA_10         0x001b
+#define OP_PCL_TLS11_3DES_EDE_CBC_SHA_11         0xc003
+#define OP_PCL_TLS11_3DES_EDE_CBC_SHA_12         0xc008
+#define OP_PCL_TLS11_3DES_EDE_CBC_SHA_13         0xc00d
+#define OP_PCL_TLS11_3DES_EDE_CBC_SHA_14         0xc012
+#define OP_PCL_TLS11_3DES_EDE_CBC_SHA_15         0xc017
+#define OP_PCL_TLS11_3DES_EDE_CBC_SHA_16         0xc01a
+#define OP_PCL_TLS11_3DES_EDE_CBC_SHA_17         0xc01b
+#define OP_PCL_TLS11_3DES_EDE_CBC_SHA_18         0xc01c
+
+#define OP_PCL_TLS11_DES40_CBC_MD5               0x0029
+
+#define OP_PCL_TLS11_DES_CBC_MD5                 0x0022
+
+#define OP_PCL_TLS11_DES40_CBC_SHA               0x0008
+#define OP_PCL_TLS11_DES40_CBC_SHA_2             0x000b
+#define OP_PCL_TLS11_DES40_CBC_SHA_3             0x000e
+#define OP_PCL_TLS11_DES40_CBC_SHA_4             0x0011
+#define OP_PCL_TLS11_DES40_CBC_SHA_5             0x0014
+#define OP_PCL_TLS11_DES40_CBC_SHA_6             0x0019
+#define OP_PCL_TLS11_DES40_CBC_SHA_7             0x0026
+
+#define OP_PCL_TLS11_DES_CBC_SHA                 0x001e
+#define OP_PCL_TLS11_DES_CBC_SHA_2               0x0009
+#define OP_PCL_TLS11_DES_CBC_SHA_3               0x000c
+#define OP_PCL_TLS11_DES_CBC_SHA_4               0x000f
+#define OP_PCL_TLS11_DES_CBC_SHA_5               0x0012
+#define OP_PCL_TLS11_DES_CBC_SHA_6               0x0015
+#define OP_PCL_TLS11_DES_CBC_SHA_7               0x001a
+
+#define OP_PCL_TLS11_RC4_128_MD5                 0x0024
+#define OP_PCL_TLS11_RC4_128_MD5_2               0x0004
+#define OP_PCL_TLS11_RC4_128_MD5_3               0x0018
+
+#define OP_PCL_TLS11_RC4_40_MD5                  0x002b
+#define OP_PCL_TLS11_RC4_40_MD5_2                0x0003
+#define OP_PCL_TLS11_RC4_40_MD5_3                0x0017
+
+#define OP_PCL_TLS11_RC4_128_SHA                 0x0020
+#define OP_PCL_TLS11_RC4_128_SHA_2               0x008a
+#define OP_PCL_TLS11_RC4_128_SHA_3               0x008e
+#define OP_PCL_TLS11_RC4_128_SHA_4               0x0092
+#define OP_PCL_TLS11_RC4_128_SHA_5               0x0005
+#define OP_PCL_TLS11_RC4_128_SHA_6               0xc002
+#define OP_PCL_TLS11_RC4_128_SHA_7               0xc007
+#define OP_PCL_TLS11_RC4_128_SHA_8               0xc00c
+#define OP_PCL_TLS11_RC4_128_SHA_9               0xc011
+#define OP_PCL_TLS11_RC4_128_SHA_10              0xc016
+
+#define OP_PCL_TLS11_RC4_40_SHA                  0x0028
+
+#define OP_PCL_TLS11_3DES_EDE_CBC_MD5            0xff23
+#define OP_PCL_TLS11_3DES_EDE_CBC_SHA160         0xff30
+#define OP_PCL_TLS11_3DES_EDE_CBC_SHA224         0xff34
+#define OP_PCL_TLS11_3DES_EDE_CBC_SHA256         0xff36
+#define OP_PCL_TLS11_3DES_EDE_CBC_SHA384         0xff33
+#define OP_PCL_TLS11_3DES_EDE_CBC_SHA512         0xff35
+#define OP_PCL_TLS11_AES_128_CBC_SHA160          0xff80
+#define OP_PCL_TLS11_AES_128_CBC_SHA224          0xff84
+#define OP_PCL_TLS11_AES_128_CBC_SHA256          0xff86
+#define OP_PCL_TLS11_AES_128_CBC_SHA384          0xff83
+#define OP_PCL_TLS11_AES_128_CBC_SHA512          0xff85
+#define OP_PCL_TLS11_AES_192_CBC_SHA160          0xff20
+#define OP_PCL_TLS11_AES_192_CBC_SHA224          0xff24
+#define OP_PCL_TLS11_AES_192_CBC_SHA256          0xff26
+#define OP_PCL_TLS11_AES_192_CBC_SHA384          0xff23
+#define OP_PCL_TLS11_AES_192_CBC_SHA512          0xff25
+#define OP_PCL_TLS11_AES_256_CBC_SHA160          0xff60
+#define OP_PCL_TLS11_AES_256_CBC_SHA224          0xff64
+#define OP_PCL_TLS11_AES_256_CBC_SHA256          0xff66
+#define OP_PCL_TLS11_AES_256_CBC_SHA384          0xff63
+#define OP_PCL_TLS11_AES_256_CBC_SHA512          0xff65
+
+
+/* For TLS 1.2 - OP_PCLID_TLS12 */
+#define OP_PCL_TLS12_AES_128_CBC_SHA             0x002f
+#define OP_PCL_TLS12_AES_128_CBC_SHA_2           0x0030
+#define OP_PCL_TLS12_AES_128_CBC_SHA_3           0x0031
+#define OP_PCL_TLS12_AES_128_CBC_SHA_4           0x0032
+#define OP_PCL_TLS12_AES_128_CBC_SHA_5           0x0033
+#define OP_PCL_TLS12_AES_128_CBC_SHA_6           0x0034
+#define OP_PCL_TLS12_AES_128_CBC_SHA_7           0x008c
+#define OP_PCL_TLS12_AES_128_CBC_SHA_8           0x0090
+#define OP_PCL_TLS12_AES_128_CBC_SHA_9           0x0094
+#define OP_PCL_TLS12_AES_128_CBC_SHA_10          0xc004
+#define OP_PCL_TLS12_AES_128_CBC_SHA_11          0xc009
+#define OP_PCL_TLS12_AES_128_CBC_SHA_12          0xc00e
+#define OP_PCL_TLS12_AES_128_CBC_SHA_13          0xc013
+#define OP_PCL_TLS12_AES_128_CBC_SHA_14          0xc018
+#define OP_PCL_TLS12_AES_128_CBC_SHA_15          0xc01d
+#define OP_PCL_TLS12_AES_128_CBC_SHA_16          0xc01e
+#define OP_PCL_TLS12_AES_128_CBC_SHA_17          0xc01f
+
+#define OP_PCL_TLS12_AES_256_CBC_SHA             0x0035
+#define OP_PCL_TLS12_AES_256_CBC_SHA_2           0x0036
+#define OP_PCL_TLS12_AES_256_CBC_SHA_3           0x0037
+#define OP_PCL_TLS12_AES_256_CBC_SHA_4           0x0038
+#define OP_PCL_TLS12_AES_256_CBC_SHA_5           0x0039
+#define OP_PCL_TLS12_AES_256_CBC_SHA_6           0x003a
+#define OP_PCL_TLS12_AES_256_CBC_SHA_7           0x008d
+#define OP_PCL_TLS12_AES_256_CBC_SHA_8           0x0091
+#define OP_PCL_TLS12_AES_256_CBC_SHA_9           0x0095
+#define OP_PCL_TLS12_AES_256_CBC_SHA_10          0xc005
+#define OP_PCL_TLS12_AES_256_CBC_SHA_11          0xc00a
+#define OP_PCL_TLS12_AES_256_CBC_SHA_12          0xc00f
+#define OP_PCL_TLS12_AES_256_CBC_SHA_13          0xc014
+#define OP_PCL_TLS12_AES_256_CBC_SHA_14          0xc019
+#define OP_PCL_TLS12_AES_256_CBC_SHA_15          0xc020
+#define OP_PCL_TLS12_AES_256_CBC_SHA_16          0xc021
+#define OP_PCL_TLS12_AES_256_CBC_SHA_17          0xc022
+
+/* #define OP_PCL_TLS12_3DES_EDE_CBC_MD5            0x0023 */
+
+#define OP_PCL_TLS12_3DES_EDE_CBC_SHA            0x001f
+#define OP_PCL_TLS12_3DES_EDE_CBC_SHA_2          0x008b
+#define OP_PCL_TLS12_3DES_EDE_CBC_SHA_3          0x008f
+#define OP_PCL_TLS12_3DES_EDE_CBC_SHA_4          0x0093
+#define OP_PCL_TLS12_3DES_EDE_CBC_SHA_5          0x000a
+#define OP_PCL_TLS12_3DES_EDE_CBC_SHA_6          0x000d
+#define OP_PCL_TLS12_3DES_EDE_CBC_SHA_7          0x0010
+#define OP_PCL_TLS12_3DES_EDE_CBC_SHA_8          0x0013
+#define OP_PCL_TLS12_3DES_EDE_CBC_SHA_9          0x0016
+#define OP_PCL_TLS12_3DES_EDE_CBC_SHA_10         0x001b
+#define OP_PCL_TLS12_3DES_EDE_CBC_SHA_11         0xc003
+#define OP_PCL_TLS12_3DES_EDE_CBC_SHA_12         0xc008
+#define OP_PCL_TLS12_3DES_EDE_CBC_SHA_13         0xc00d
+#define OP_PCL_TLS12_3DES_EDE_CBC_SHA_14         0xc012
+#define OP_PCL_TLS12_3DES_EDE_CBC_SHA_15         0xc017
+#define OP_PCL_TLS12_3DES_EDE_CBC_SHA_16         0xc01a
+#define OP_PCL_TLS12_3DES_EDE_CBC_SHA_17         0xc01b
+#define OP_PCL_TLS12_3DES_EDE_CBC_SHA_18         0xc01c
+
+#define OP_PCL_TLS12_DES40_CBC_MD5               0x0029
+
+#define OP_PCL_TLS12_DES_CBC_MD5                 0x0022
+
+#define OP_PCL_TLS12_DES40_CBC_SHA               0x0008
+#define OP_PCL_TLS12_DES40_CBC_SHA_2             0x000b
+#define OP_PCL_TLS12_DES40_CBC_SHA_3             0x000e
+#define OP_PCL_TLS12_DES40_CBC_SHA_4             0x0011
+#define OP_PCL_TLS12_DES40_CBC_SHA_5             0x0014
+#define OP_PCL_TLS12_DES40_CBC_SHA_6             0x0019
+#define OP_PCL_TLS12_DES40_CBC_SHA_7             0x0026
+
+#define OP_PCL_TLS12_DES_CBC_SHA                 0x001e
+#define OP_PCL_TLS12_DES_CBC_SHA_2               0x0009
+#define OP_PCL_TLS12_DES_CBC_SHA_3               0x000c
+#define OP_PCL_TLS12_DES_CBC_SHA_4               0x000f
+#define OP_PCL_TLS12_DES_CBC_SHA_5               0x0012
+#define OP_PCL_TLS12_DES_CBC_SHA_6               0x0015
+#define OP_PCL_TLS12_DES_CBC_SHA_7               0x001a
+
+#define OP_PCL_TLS12_RC4_128_MD5                 0x0024
+#define OP_PCL_TLS12_RC4_128_MD5_2               0x0004
+#define OP_PCL_TLS12_RC4_128_MD5_3               0x0018
+
+#define OP_PCL_TLS12_RC4_40_MD5                  0x002b
+#define OP_PCL_TLS12_RC4_40_MD5_2                0x0003
+#define OP_PCL_TLS12_RC4_40_MD5_3                0x0017
+
+#define OP_PCL_TLS12_RC4_128_SHA                 0x0020
+#define OP_PCL_TLS12_RC4_128_SHA_2               0x008a
+#define OP_PCL_TLS12_RC4_128_SHA_3               0x008e
+#define OP_PCL_TLS12_RC4_128_SHA_4               0x0092
+#define OP_PCL_TLS12_RC4_128_SHA_5               0x0005
+#define OP_PCL_TLS12_RC4_128_SHA_6               0xc002
+#define OP_PCL_TLS12_RC4_128_SHA_7               0xc007
+#define OP_PCL_TLS12_RC4_128_SHA_8               0xc00c
+#define OP_PCL_TLS12_RC4_128_SHA_9               0xc011
+#define OP_PCL_TLS12_RC4_128_SHA_10              0xc016
+
+#define OP_PCL_TLS12_RC4_40_SHA                  0x0028
+
+/* #define OP_PCL_TLS12_AES_128_CBC_SHA256          0x003c */
+#define OP_PCL_TLS12_AES_128_CBC_SHA256_2        0x003e
+#define OP_PCL_TLS12_AES_128_CBC_SHA256_3        0x003f
+#define OP_PCL_TLS12_AES_128_CBC_SHA256_4        0x0040
+#define OP_PCL_TLS12_AES_128_CBC_SHA256_5        0x0067
+#define OP_PCL_TLS12_AES_128_CBC_SHA256_6        0x006c
+
+/* #define OP_PCL_TLS12_AES_256_CBC_SHA256          0x003d */
+#define OP_PCL_TLS12_AES_256_CBC_SHA256_2        0x0068
+#define OP_PCL_TLS12_AES_256_CBC_SHA256_3        0x0069
+#define OP_PCL_TLS12_AES_256_CBC_SHA256_4        0x006a
+#define OP_PCL_TLS12_AES_256_CBC_SHA256_5        0x006b
+#define OP_PCL_TLS12_AES_256_CBC_SHA256_6        0x006d
+
+/* AEAD_AES_xxx_CCM/GCM remain to be defined... */
+
+#define OP_PCL_TLS12_3DES_EDE_CBC_MD5            0xff23
+#define OP_PCL_TLS12_3DES_EDE_CBC_SHA160         0xff30
+#define OP_PCL_TLS12_3DES_EDE_CBC_SHA224         0xff34
+#define OP_PCL_TLS12_3DES_EDE_CBC_SHA256         0xff36
+#define OP_PCL_TLS12_3DES_EDE_CBC_SHA384         0xff33
+#define OP_PCL_TLS12_3DES_EDE_CBC_SHA512         0xff35
+#define OP_PCL_TLS12_AES_128_CBC_SHA160          0xff80
+#define OP_PCL_TLS12_AES_128_CBC_SHA224          0xff84
+#define OP_PCL_TLS12_AES_128_CBC_SHA256          0xff86
+#define OP_PCL_TLS12_AES_128_CBC_SHA384          0xff83
+#define OP_PCL_TLS12_AES_128_CBC_SHA512          0xff85
+#define OP_PCL_TLS12_AES_192_CBC_SHA160          0xff20
+#define OP_PCL_TLS12_AES_192_CBC_SHA224          0xff24
+#define OP_PCL_TLS12_AES_192_CBC_SHA256          0xff26
+#define OP_PCL_TLS12_AES_192_CBC_SHA384          0xff23
+#define OP_PCL_TLS12_AES_192_CBC_SHA512          0xff25
+#define OP_PCL_TLS12_AES_256_CBC_SHA160          0xff60
+#define OP_PCL_TLS12_AES_256_CBC_SHA224          0xff64
+#define OP_PCL_TLS12_AES_256_CBC_SHA256          0xff66
+#define OP_PCL_TLS12_AES_256_CBC_SHA384          0xff63
+#define OP_PCL_TLS12_AES_256_CBC_SHA512          0xff65
+
+/* For DTLS - OP_PCLID_DTLS */
+
+#define OP_PCL_DTLS_AES_128_CBC_SHA              0x002f
+#define OP_PCL_DTLS_AES_128_CBC_SHA_2            0x0030
+#define OP_PCL_DTLS_AES_128_CBC_SHA_3            0x0031
+#define OP_PCL_DTLS_AES_128_CBC_SHA_4            0x0032
+#define OP_PCL_DTLS_AES_128_CBC_SHA_5            0x0033
+#define OP_PCL_DTLS_AES_128_CBC_SHA_6            0x0034
+#define OP_PCL_DTLS_AES_128_CBC_SHA_7            0x008c
+#define OP_PCL_DTLS_AES_128_CBC_SHA_8            0x0090
+#define OP_PCL_DTLS_AES_128_CBC_SHA_9            0x0094
+#define OP_PCL_DTLS_AES_128_CBC_SHA_10           0xc004
+#define OP_PCL_DTLS_AES_128_CBC_SHA_11           0xc009
+#define OP_PCL_DTLS_AES_128_CBC_SHA_12           0xc00e
+#define OP_PCL_DTLS_AES_128_CBC_SHA_13           0xc013
+#define OP_PCL_DTLS_AES_128_CBC_SHA_14           0xc018
+#define OP_PCL_DTLS_AES_128_CBC_SHA_15           0xc01d
+#define OP_PCL_DTLS_AES_128_CBC_SHA_16           0xc01e
+#define OP_PCL_DTLS_AES_128_CBC_SHA_17           0xc01f
+
+#define OP_PCL_DTLS_AES_256_CBC_SHA              0x0035
+#define OP_PCL_DTLS_AES_256_CBC_SHA_2            0x0036
+#define OP_PCL_DTLS_AES_256_CBC_SHA_3            0x0037
+#define OP_PCL_DTLS_AES_256_CBC_SHA_4            0x0038
+#define OP_PCL_DTLS_AES_256_CBC_SHA_5            0x0039
+#define OP_PCL_DTLS_AES_256_CBC_SHA_6            0x003a
+#define OP_PCL_DTLS_AES_256_CBC_SHA_7            0x008d
+#define OP_PCL_DTLS_AES_256_CBC_SHA_8            0x0091
+#define OP_PCL_DTLS_AES_256_CBC_SHA_9            0x0095
+#define OP_PCL_DTLS_AES_256_CBC_SHA_10           0xc005
+#define OP_PCL_DTLS_AES_256_CBC_SHA_11           0xc00a
+#define OP_PCL_DTLS_AES_256_CBC_SHA_12           0xc00f
+#define OP_PCL_DTLS_AES_256_CBC_SHA_13           0xc014
+#define OP_PCL_DTLS_AES_256_CBC_SHA_14           0xc019
+#define OP_PCL_DTLS_AES_256_CBC_SHA_15           0xc020
+#define OP_PCL_DTLS_AES_256_CBC_SHA_16           0xc021
+#define OP_PCL_DTLS_AES_256_CBC_SHA_17           0xc022
+
+/* #define OP_PCL_DTLS_3DES_EDE_CBC_MD5             0x0023 */
+
+#define OP_PCL_DTLS_3DES_EDE_CBC_SHA             0x001f
+#define OP_PCL_DTLS_3DES_EDE_CBC_SHA_2           0x008b
+#define OP_PCL_DTLS_3DES_EDE_CBC_SHA_3           0x008f
+#define OP_PCL_DTLS_3DES_EDE_CBC_SHA_4           0x0093
+#define OP_PCL_DTLS_3DES_EDE_CBC_SHA_5           0x000a
+#define OP_PCL_DTLS_3DES_EDE_CBC_SHA_6           0x000d
+#define OP_PCL_DTLS_3DES_EDE_CBC_SHA_7           0x0010
+#define OP_PCL_DTLS_3DES_EDE_CBC_SHA_8           0x0013
+#define OP_PCL_DTLS_3DES_EDE_CBC_SHA_9           0x0016
+#define OP_PCL_DTLS_3DES_EDE_CBC_SHA_10          0x001b
+#define OP_PCL_DTLS_3DES_EDE_CBC_SHA_11          0xc003
+#define OP_PCL_DTLS_3DES_EDE_CBC_SHA_12          0xc008
+#define OP_PCL_DTLS_3DES_EDE_CBC_SHA_13          0xc00d
+#define OP_PCL_DTLS_3DES_EDE_CBC_SHA_14          0xc012
+#define OP_PCL_DTLS_3DES_EDE_CBC_SHA_15          0xc017
+#define OP_PCL_DTLS_3DES_EDE_CBC_SHA_16          0xc01a
+#define OP_PCL_DTLS_3DES_EDE_CBC_SHA_17          0xc01b
+#define OP_PCL_DTLS_3DES_EDE_CBC_SHA_18          0xc01c
+
+#define OP_PCL_DTLS_DES40_CBC_MD5                0x0029
+
+#define OP_PCL_DTLS_DES_CBC_MD5                  0x0022
+
+#define OP_PCL_DTLS_DES40_CBC_SHA                0x0008
+#define OP_PCL_DTLS_DES40_CBC_SHA_2              0x000b
+#define OP_PCL_DTLS_DES40_CBC_SHA_3              0x000e
+#define OP_PCL_DTLS_DES40_CBC_SHA_4              0x0011
+#define OP_PCL_DTLS_DES40_CBC_SHA_5              0x0014
+#define OP_PCL_DTLS_DES40_CBC_SHA_6              0x0019
+#define OP_PCL_DTLS_DES40_CBC_SHA_7              0x0026
+
+
+#define OP_PCL_DTLS_DES_CBC_SHA                  0x001e
+#define OP_PCL_DTLS_DES_CBC_SHA_2                0x0009
+#define OP_PCL_DTLS_DES_CBC_SHA_3                0x000c
+#define OP_PCL_DTLS_DES_CBC_SHA_4                0x000f
+#define OP_PCL_DTLS_DES_CBC_SHA_5                0x0012
+#define OP_PCL_DTLS_DES_CBC_SHA_6                0x0015
+#define OP_PCL_DTLS_DES_CBC_SHA_7                0x001a
+
+
+#define OP_PCL_DTLS_3DES_EDE_CBC_MD5             0xff23
+#define OP_PCL_DTLS_3DES_EDE_CBC_SHA160          0xff30
+#define OP_PCL_DTLS_3DES_EDE_CBC_SHA224          0xff34
+#define OP_PCL_DTLS_3DES_EDE_CBC_SHA256          0xff36
+#define OP_PCL_DTLS_3DES_EDE_CBC_SHA384          0xff33
+#define OP_PCL_DTLS_3DES_EDE_CBC_SHA512          0xff35
+#define OP_PCL_DTLS_AES_128_CBC_SHA160           0xff80
+#define OP_PCL_DTLS_AES_128_CBC_SHA224           0xff84
+#define OP_PCL_DTLS_AES_128_CBC_SHA256           0xff86
+#define OP_PCL_DTLS_AES_128_CBC_SHA384           0xff83
+#define OP_PCL_DTLS_AES_128_CBC_SHA512           0xff85
+#define OP_PCL_DTLS_AES_192_CBC_SHA160           0xff20
+#define OP_PCL_DTLS_AES_192_CBC_SHA224           0xff24
+#define OP_PCL_DTLS_AES_192_CBC_SHA256           0xff26
+#define OP_PCL_DTLS_AES_192_CBC_SHA384           0xff23
+#define OP_PCL_DTLS_AES_192_CBC_SHA512           0xff25
+#define OP_PCL_DTLS_AES_256_CBC_SHA160           0xff60
+#define OP_PCL_DTLS_AES_256_CBC_SHA224           0xff64
+#define OP_PCL_DTLS_AES_256_CBC_SHA256           0xff66
+#define OP_PCL_DTLS_AES_256_CBC_SHA384           0xff63
+#define OP_PCL_DTLS_AES_256_CBC_SHA512           0xff65
+
+/* 802.16 WiMAX protinfos */
+#define OP_PCL_WIMAX_OFDM                        0x0201
+#define OP_PCL_WIMAX_OFDMA                       0x0231
+
+/* 802.11 WiFi protinfos */
+#define OP_PCL_WIFI                              0xac04
+
+/* MacSec protinfos */
+#define OP_PCL_MACSEC                            0x0001
+
+/* PKI unidirectional protocol protinfo bits */
+#define OP_PCL_PKPROT_TEST                       0x0008
+#define OP_PCL_PKPROT_DECRYPT                    0x0004
+#define OP_PCL_PKPROT_ECC                        0x0002
+#define OP_PCL_PKPROT_F2M                        0x0001
+
+/* For non-protocol/alg-only op commands */
+#define OP_ALG_TYPE_SHIFT	24
+#define OP_ALG_TYPE_MASK	(0x7 << OP_ALG_TYPE_SHIFT)
+#define OP_ALG_TYPE_CLASS1	2
+#define OP_ALG_TYPE_CLASS2	4
+
+#define OP_ALG_ALGSEL_SHIFT	16
+#define OP_ALG_ALGSEL_MASK	(0xff << OP_ALG_ALGSEL_SHIFT)
+#define OP_ALG_ALGSEL_SUBMASK	(0x0f << OP_ALG_ALGSEL_SHIFT)
+#define OP_ALG_ALGSEL_AES	(0x10 << OP_ALG_ALGSEL_SHIFT)
+#define OP_ALG_ALGSEL_DES	(0x20 << OP_ALG_ALGSEL_SHIFT)
+#define OP_ALG_ALGSEL_3DES	(0x21 << OP_ALG_ALGSEL_SHIFT)
+#define OP_ALG_ALGSEL_ARC4	(0x30 << OP_ALG_ALGSEL_SHIFT)
+#define OP_ALG_ALGSEL_MD5	(0x40 << OP_ALG_ALGSEL_SHIFT)
+#define OP_ALG_ALGSEL_SHA1	(0x41 << OP_ALG_ALGSEL_SHIFT)
+#define OP_ALG_ALGSEL_SHA224	(0x42 << OP_ALG_ALGSEL_SHIFT)
+#define OP_ALG_ALGSEL_SHA256	(0x43 << OP_ALG_ALGSEL_SHIFT)
+#define OP_ALG_ALGSEL_SHA384	(0x44 << OP_ALG_ALGSEL_SHIFT)
+#define OP_ALG_ALGSEL_SHA512	(0x45 << OP_ALG_ALGSEL_SHIFT)
+#define OP_ALG_ALGSEL_RNG	(0x50 << OP_ALG_ALGSEL_SHIFT)
+#define OP_ALG_ALGSEL_SNOW	(0x60 << OP_ALG_ALGSEL_SHIFT)
+#define OP_ALG_ALGSEL_SNOW_F8	(0x60 << OP_ALG_ALGSEL_SHIFT)
+#define OP_ALG_ALGSEL_KASUMI	(0x70 << OP_ALG_ALGSEL_SHIFT)
+#define OP_ALG_ALGSEL_CRC	(0x90 << OP_ALG_ALGSEL_SHIFT)
+#define OP_ALG_ALGSEL_SNOW_F9	(0xA0 << OP_ALG_ALGSEL_SHIFT)
+
+#define OP_ALG_AAI_SHIFT	4
+#define OP_ALG_AAI_MASK		(0x1ff << OP_ALG_AAI_SHIFT)
+
+/* blockcipher AAI set */
+#define OP_ALG_AAI_CTR_MOD128	(0x00 << OP_ALG_AAI_SHIFT)
+#define OP_ALG_AAI_CTR_MOD8	(0x01 << OP_ALG_AAI_SHIFT)
+#define OP_ALG_AAI_CTR_MOD16	(0x02 << OP_ALG_AAI_SHIFT)
+#define OP_ALG_AAI_CTR_MOD24	(0x03 << OP_ALG_AAI_SHIFT)
+#define OP_ALG_AAI_CTR_MOD32	(0x04 << OP_ALG_AAI_SHIFT)
+#define OP_ALG_AAI_CTR_MOD40	(0x05 << OP_ALG_AAI_SHIFT)
+#define OP_ALG_AAI_CTR_MOD48	(0x06 << OP_ALG_AAI_SHIFT)
+#define OP_ALG_AAI_CTR_MOD56	(0x07 << OP_ALG_AAI_SHIFT)
+#define OP_ALG_AAI_CTR_MOD64	(0x08 << OP_ALG_AAI_SHIFT)
+#define OP_ALG_AAI_CTR_MOD72	(0x09 << OP_ALG_AAI_SHIFT)
+#define OP_ALG_AAI_CTR_MOD80	(0x0a << OP_ALG_AAI_SHIFT)
+#define OP_ALG_AAI_CTR_MOD88	(0x0b << OP_ALG_AAI_SHIFT)
+#define OP_ALG_AAI_CTR_MOD96	(0x0c << OP_ALG_AAI_SHIFT)
+#define OP_ALG_AAI_CTR_MOD104	(0x0d << OP_ALG_AAI_SHIFT)
+#define OP_ALG_AAI_CTR_MOD112	(0x0e << OP_ALG_AAI_SHIFT)
+#define OP_ALG_AAI_CTR_MOD120	(0x0f << OP_ALG_AAI_SHIFT)
+#define OP_ALG_AAI_CBC		(0x10 << OP_ALG_AAI_SHIFT)
+#define OP_ALG_AAI_ECB		(0x20 << OP_ALG_AAI_SHIFT)
+#define OP_ALG_AAI_CFB		(0x30 << OP_ALG_AAI_SHIFT)
+#define OP_ALG_AAI_OFB		(0x40 << OP_ALG_AAI_SHIFT)
+#define OP_ALG_AAI_XTS		(0x50 << OP_ALG_AAI_SHIFT)
+#define OP_ALG_AAI_CMAC		(0x60 << OP_ALG_AAI_SHIFT)
+#define OP_ALG_AAI_XCBC_MAC	(0x70 << OP_ALG_AAI_SHIFT)
+#define OP_ALG_AAI_CCM		(0x80 << OP_ALG_AAI_SHIFT)
+#define OP_ALG_AAI_GCM		(0x90 << OP_ALG_AAI_SHIFT)
+#define OP_ALG_AAI_CBC_XCBCMAC	(0xa0 << OP_ALG_AAI_SHIFT)
+#define OP_ALG_AAI_CTR_XCBCMAC	(0xb0 << OP_ALG_AAI_SHIFT)
+#define OP_ALG_AAI_CHECKODD	(0x80 << OP_ALG_AAI_SHIFT)
+#define OP_ALG_AAI_DK		(0x100 << OP_ALG_AAI_SHIFT)
+
+/* randomizer AAI set */
+#define OP_ALG_AAI_RNG		(0x00 << OP_ALG_AAI_SHIFT)
+#define OP_ALG_AAI_RNG_NOZERO	(0x10 << OP_ALG_AAI_SHIFT)
+#define OP_ALG_AAI_RNG_ODD	(0x20 << OP_ALG_AAI_SHIFT)
+
+/* hmac/smac AAI set */
+#define OP_ALG_AAI_HASH		(0x00 << OP_ALG_AAI_SHIFT)
+#define OP_ALG_AAI_HMAC		(0x01 << OP_ALG_AAI_SHIFT)
+#define OP_ALG_AAI_SMAC		(0x02 << OP_ALG_AAI_SHIFT)
+#define OP_ALG_AAI_HMAC_PRECOMP	(0x04 << OP_ALG_AAI_SHIFT)
+
+/* CRC AAI set*/
+#define OP_ALG_AAI_802		(0x01 << OP_ALG_AAI_SHIFT)
+#define OP_ALG_AAI_3385		(0x02 << OP_ALG_AAI_SHIFT)
+#define OP_ALG_AAI_CUST_POLY	(0x04 << OP_ALG_AAI_SHIFT)
+#define OP_ALG_AAI_DIS		(0x10 << OP_ALG_AAI_SHIFT)
+#define OP_ALG_AAI_DOS		(0x20 << OP_ALG_AAI_SHIFT)
+#define OP_ALG_AAI_DOC		(0x40 << OP_ALG_AAI_SHIFT)
+
+/* Kasumi/SNOW AAI set */
+#define OP_ALG_AAI_F8		(0xc0 << OP_ALG_AAI_SHIFT)
+#define OP_ALG_AAI_F9		(0xc8 << OP_ALG_AAI_SHIFT)
+#define OP_ALG_AAI_GSM		(0x10 << OP_ALG_AAI_SHIFT)
+#define OP_ALG_AAI_EDGE		(0x20 << OP_ALG_AAI_SHIFT)
+
+
+#define OP_ALG_AS_SHIFT		2
+#define OP_ALG_AS_MASK		(0x3 << OP_ALG_AS_SHIFT)
+#define OP_ALG_AS_UPDATE	(0 << OP_ALG_AS_SHIFT)
+#define OP_ALG_AS_INIT		(1 << OP_ALG_AS_SHIFT)
+#define OP_ALG_AS_FINALIZE	(2 << OP_ALG_AS_SHIFT)
+#define OP_ALG_AS_INITFINAL	(3 << OP_ALG_AS_SHIFT)
+
+#define OP_ALG_ICV_SHIFT	1
+#define OP_ALG_ICV_MASK		(1 << OP_ALG_ICV_SHIFT)
+#define OP_ALG_ICV_OFF		(0 << OP_ALG_ICV_SHIFT)
+#define OP_ALG_ICV_ON		(1 << OP_ALG_ICV_SHIFT)
+
+#define OP_ALG_DIR_SHIFT	0
+#define OP_ALG_DIR_MASK		1
+#define OP_ALG_DECRYPT		0
+#define OP_ALG_ENCRYPT		1
+
+/* PKHA algorithm type set */
+#define OP_ALG_PK                    0x00800000
+#define OP_ALG_PK_FUN_MASK           0x3f /* clrmem, modmath, or cpymem */
+
+/* PKHA mode clear memory functions */
+#define OP_ALG_PKMODE_A_RAM          0x80000
+#define OP_ALG_PKMODE_B_RAM          0x40000
+#define OP_ALG_PKMODE_E_RAM          0x20000
+#define OP_ALG_PKMODE_N_RAM          0x10000
+#define OP_ALG_PKMODE_CLEARMEM       0x00001
+
+/* PKHA mode modular-arithmetic functions */
+#define OP_ALG_PKMODE_MOD_IN_MONTY   0x80000
+#define OP_ALG_PKMODE_MOD_OUT_MONTY  0x40000
+#define OP_ALG_PKMODE_MOD_F2M        0x20000
+#define OP_ALG_PKMODE_MOD_R2_IN      0x10000
+#define OP_ALG_PKMODE_PRJECTV        0x00800
+#define OP_ALG_PKMODE_TIME_EQ        0x400
+#define OP_ALG_PKMODE_OUT_B          0x000
+#define OP_ALG_PKMODE_OUT_A          0x100
+#define OP_ALG_PKMODE_MOD_ADD        0x002
+#define OP_ALG_PKMODE_MOD_SUB_AB     0x003
+#define OP_ALG_PKMODE_MOD_SUB_BA     0x004
+#define OP_ALG_PKMODE_MOD_MULT       0x005
+#define OP_ALG_PKMODE_MOD_EXPO       0x006
+#define OP_ALG_PKMODE_MOD_REDUCT     0x007
+#define OP_ALG_PKMODE_MOD_INV        0x008
+#define OP_ALG_PKMODE_MOD_ECC_ADD    0x009
+#define OP_ALG_PKMODE_MOD_ECC_DBL    0x00a
+#define OP_ALG_PKMODE_MOD_ECC_MULT   0x00b
+#define OP_ALG_PKMODE_MOD_MONT_CNST  0x00c
+#define OP_ALG_PKMODE_MOD_CRT_CNST   0x00d
+#define OP_ALG_PKMODE_MOD_GCD        0x00e
+#define OP_ALG_PKMODE_MOD_PRIMALITY  0x00f
+
+/* PKHA mode copy-memory functions */
+#define OP_ALG_PKMODE_SRC_REG_SHIFT  13
+#define OP_ALG_PKMODE_SRC_REG_MASK   (7 << OP_ALG_PKMODE_SRC_REG_SHIFT)
+#define OP_ALG_PKMODE_DST_REG_SHIFT  10
+#define OP_ALG_PKMODE_DST_REG_MASK   (7 << OP_ALG_PKMODE_DST_REG_SHIFT)
+#define OP_ALG_PKMODE_SRC_SEG_SHIFT  8
+#define OP_ALG_PKMODE_SRC_SEG_MASK   (3 << OP_ALG_PKMODE_SRC_SEG_SHIFT)
+#define OP_ALG_PKMODE_DST_SEG_SHIFT  6
+#define OP_ALG_PKMODE_DST_SEG_MASK   (3 << OP_ALG_PKMODE_DST_SEG_SHIFT)
+
+#define OP_ALG_PKMODE_SRC_REG_A      (0 << OP_ALG_PKMODE_SRC_REG_SHIFT)
+#define OP_ALG_PKMODE_SRC_REG_B      (1 << OP_ALG_PKMODE_SRC_REG_SHIFT)
+#define OP_ALG_PKMODE_SRC_REG_N      (3 << OP_ALG_PKMODE_SRC_REG_SHIFT)
+#define OP_ALG_PKMODE_DST_REG_A      (0 << OP_ALG_PKMODE_DST_REG_SHIFT)
+#define OP_ALG_PKMODE_DST_REG_B      (1 << OP_ALG_PKMODE_DST_REG_SHIFT)
+#define OP_ALG_PKMODE_DST_REG_E      (2 << OP_ALG_PKMODE_DST_REG_SHIFT)
+#define OP_ALG_PKMODE_DST_REG_N      (3 << OP_ALG_PKMODE_DST_REG_SHIFT)
+#define OP_ALG_PKMODE_SRC_SEG_0      (0 << OP_ALG_PKMODE_SRC_SEG_SHIFT)
+#define OP_ALG_PKMODE_SRC_SEG_1      (1 << OP_ALG_PKMODE_SRC_SEG_SHIFT)
+#define OP_ALG_PKMODE_SRC_SEG_2      (2 << OP_ALG_PKMODE_SRC_SEG_SHIFT)
+#define OP_ALG_PKMODE_SRC_SEG_3      (3 << OP_ALG_PKMODE_SRC_SEG_SHIFT)
+#define OP_ALG_PKMODE_DST_SEG_0      (0 << OP_ALG_PKMODE_DST_SEG_SHIFT)
+#define OP_ALG_PKMODE_DST_SEG_1      (1 << OP_ALG_PKMODE_DST_SEG_SHIFT)
+#define OP_ALG_PKMODE_DST_SEG_2      (2 << OP_ALG_PKMODE_DST_SEG_SHIFT)
+#define OP_ALG_PKMODE_DST_SEG_3      (3 << OP_ALG_PKMODE_DST_SEG_SHIFT)
+#define OP_ALG_PKMODE_CPYMEM_N_SZ    0x80
+#define OP_ALG_PKMODE_CPYMEM_SRC_SZ  0x81
+
+/*
+ * SEQ_IN_PTR Command Constructs
+ */
+
+/* Release Buffers */
+#define SQIN_RBS               0x04000000
+
+/* Sequence pointer is really a descriptor */
+#define SQIN_INL               0x02000000
+
+/* Sequence pointer is a scatter-gather table */
+#define SQIN_SGF               0x01000000
+
+/* Appends to a previous pointer */
+#define SQIN_PRE               0x00800000
+
+/* Use extended length following pointer */
+#define SQIN_EXT               0x00400000
+
+/* Restore sequence with pointer/length */
+#define SQIN_RTO               0x00200000
+
+/* Replace job descriptor */
+#define SQIN_RJD               0x00100000
+
+#define SQIN_LEN_SHIFT           0
+#define SQIN_LEN_MASK           (0xffff << SQIN_LEN_SHIFT)
+
+/*
+ * SEQ_OUT_PTR Command Constructs
+ */
+
+/* Sequence pointer is a scatter-gather table */
+#define SQOUT_SGF              0x01000000
+
+/* Appends to a previous pointer */
+#define SQOUT_PRE              0x00800000
+
+/* Restore sequence with pointer/length */
+#define SQOUT_RTO              0x00200000
+
+/* Use extended length following pointer */
+#define SQOUT_EXT              0x00400000
+
+#define SQOUT_LEN_SHIFT           0
+#define SQOUT_LEN_MASK           (0xffff << SQOUT_LEN_SHIFT)
+
+
+/*
+ * SIGNATURE Command Constructs
+ */
+
+/* TYPE field is all that's relevant */
+#define SIGN_TYPE_SHIFT         16
+#define SIGN_TYPE_MASK          (0x0f << SIGN_TYPE_SHIFT)
+
+#define SIGN_TYPE_FINAL         (0x00 << SIGN_TYPE_SHIFT)
+#define SIGN_TYPE_FINAL_RESTORE (0x01 << SIGN_TYPE_SHIFT)
+#define SIGN_TYPE_FINAL_NONZERO (0x02 << SIGN_TYPE_SHIFT)
+#define SIGN_TYPE_IMM_2         (0x0a << SIGN_TYPE_SHIFT)
+#define SIGN_TYPE_IMM_3         (0x0b << SIGN_TYPE_SHIFT)
+#define SIGN_TYPE_IMM_4         (0x0c << SIGN_TYPE_SHIFT)
+
+/*
+ * MOVE Command Constructs
+ */
+
+#define MOVE_AUX_SHIFT          25
+#define MOVE_AUX_MASK           (3 << MOVE_AUX_SHIFT)
+#define MOVE_AUX_MS             (2 << MOVE_AUX_SHIFT)
+#define MOVE_AUX_LS             (1 << MOVE_AUX_SHIFT)
+
+#define MOVE_WAITCOMP_SHIFT     24
+#define MOVE_WAITCOMP_MASK      (1 << MOVE_WAITCOMP_SHIFT)
+#define MOVE_WAITCOMP           (1 << MOVE_WAITCOMP_SHIFT)
+
+#define MOVE_SRC_SHIFT          20
+#define MOVE_SRC_MASK           (0x0f << MOVE_SRC_SHIFT)
+#define MOVE_SRC_CLASS1CTX      (0x00 << MOVE_SRC_SHIFT)
+#define MOVE_SRC_CLASS2CTX      (0x01 << MOVE_SRC_SHIFT)
+#define MOVE_SRC_OUTFIFO        (0x02 << MOVE_SRC_SHIFT)
+#define MOVE_SRC_DESCBUF        (0x03 << MOVE_SRC_SHIFT)
+#define MOVE_SRC_MATH0          (0x04 << MOVE_SRC_SHIFT)
+#define MOVE_SRC_MATH1          (0x05 << MOVE_SRC_SHIFT)
+#define MOVE_SRC_MATH2          (0x06 << MOVE_SRC_SHIFT)
+#define MOVE_SRC_MATH3          (0x07 << MOVE_SRC_SHIFT)
+#define MOVE_SRC_INFIFO         (0x08 << MOVE_SRC_SHIFT)
+#define MOVE_SRC_INFIFO_CL      (0x09 << MOVE_SRC_SHIFT)
+
+#define MOVE_DEST_SHIFT         16
+#define MOVE_DEST_MASK          (0x0f << MOVE_DEST_SHIFT)
+#define MOVE_DEST_CLASS1CTX     (0x00 << MOVE_DEST_SHIFT)
+#define MOVE_DEST_CLASS2CTX     (0x01 << MOVE_DEST_SHIFT)
+#define MOVE_DEST_OUTFIFO       (0x02 << MOVE_DEST_SHIFT)
+#define MOVE_DEST_DESCBUF       (0x03 << MOVE_DEST_SHIFT)
+#define MOVE_DEST_MATH0         (0x04 << MOVE_DEST_SHIFT)
+#define MOVE_DEST_MATH1         (0x05 << MOVE_DEST_SHIFT)
+#define MOVE_DEST_MATH2         (0x06 << MOVE_DEST_SHIFT)
+#define MOVE_DEST_MATH3         (0x07 << MOVE_DEST_SHIFT)
+#define MOVE_DEST_CLASS1INFIFO  (0x08 << MOVE_DEST_SHIFT)
+#define MOVE_DEST_CLASS2INFIFO  (0x09 << MOVE_DEST_SHIFT)
+#define MOVE_DEST_PK_A          (0x0c << MOVE_DEST_SHIFT)
+#define MOVE_DEST_CLASS1KEY     (0x0d << MOVE_DEST_SHIFT)
+#define MOVE_DEST_CLASS2KEY     (0x0e << MOVE_DEST_SHIFT)
+
+#define MOVE_OFFSET_SHIFT       8
+#define MOVE_OFFSET_MASK        (0xff << MOVE_OFFSET_SHIFT)
+
+#define MOVE_LEN_SHIFT          0
+#define MOVE_LEN_MASK           (0xff << MOVE_LEN_SHIFT)
+
+#define MOVELEN_MRSEL_SHIFT     0
+#define MOVELEN_MRSEL_MASK      (0x3 << MOVE_LEN_SHIFT)
+
+/*
+ * MATH Command Constructs
+ */
+
+#define MATH_IFB_SHIFT          26
+#define MATH_IFB_MASK           (1 << MATH_IFB_SHIFT)
+#define MATH_IFB                (1 << MATH_IFB_SHIFT)
+
+#define MATH_NFU_SHIFT          25
+#define MATH_NFU_MASK           (1 << MATH_NFU_SHIFT)
+#define MATH_NFU                (1 << MATH_NFU_SHIFT)
+
+#define MATH_STL_SHIFT          24
+#define MATH_STL_MASK           (1 << MATH_STL_SHIFT)
+#define MATH_STL                (1 << MATH_STL_SHIFT)
+
+/* Function selectors */
+#define MATH_FUN_SHIFT          20
+#define MATH_FUN_MASK           (0x0f << MATH_FUN_SHIFT)
+#define MATH_FUN_ADD            (0x00 << MATH_FUN_SHIFT)
+#define MATH_FUN_ADDC           (0x01 << MATH_FUN_SHIFT)
+#define MATH_FUN_SUB            (0x02 << MATH_FUN_SHIFT)
+#define MATH_FUN_SUBB           (0x03 << MATH_FUN_SHIFT)
+#define MATH_FUN_OR             (0x04 << MATH_FUN_SHIFT)
+#define MATH_FUN_AND            (0x05 << MATH_FUN_SHIFT)
+#define MATH_FUN_XOR            (0x06 << MATH_FUN_SHIFT)
+#define MATH_FUN_LSHIFT         (0x07 << MATH_FUN_SHIFT)
+#define MATH_FUN_RSHIFT         (0x08 << MATH_FUN_SHIFT)
+#define MATH_FUN_SHLD           (0x09 << MATH_FUN_SHIFT)
+#define MATH_FUN_ZBYT           (0x0a << MATH_FUN_SHIFT)
+
+/* Source 0 selectors */
+#define MATH_SRC0_SHIFT         16
+#define MATH_SRC0_MASK          (0x0f << MATH_SRC0_SHIFT)
+#define MATH_SRC0_REG0          (0x00 << MATH_SRC0_SHIFT)
+#define MATH_SRC0_REG1          (0x01 << MATH_SRC0_SHIFT)
+#define MATH_SRC0_REG2          (0x02 << MATH_SRC0_SHIFT)
+#define MATH_SRC0_REG3          (0x03 << MATH_SRC0_SHIFT)
+#define MATH_SRC0_IMM           (0x04 << MATH_SRC0_SHIFT)
+#define MATH_SRC0_SEQINLEN      (0x08 << MATH_SRC0_SHIFT)
+#define MATH_SRC0_SEQOUTLEN     (0x09 << MATH_SRC0_SHIFT)
+#define MATH_SRC0_VARSEQINLEN   (0x0a << MATH_SRC0_SHIFT)
+#define MATH_SRC0_VARSEQOUTLEN  (0x0b << MATH_SRC0_SHIFT)
+#define MATH_SRC0_ZERO          (0x0c << MATH_SRC0_SHIFT)
+
+/* Source 1 selectors */
+#define MATH_SRC1_SHIFT         12
+#define MATH_SRC1_MASK          (0x0f << MATH_SRC1_SHIFT)
+#define MATH_SRC1_REG0          (0x00 << MATH_SRC1_SHIFT)
+#define MATH_SRC1_REG1          (0x01 << MATH_SRC1_SHIFT)
+#define MATH_SRC1_REG2          (0x02 << MATH_SRC1_SHIFT)
+#define MATH_SRC1_REG3          (0x03 << MATH_SRC1_SHIFT)
+#define MATH_SRC1_IMM           (0x04 << MATH_SRC1_SHIFT)
+#define MATH_SRC1_INFIFO        (0x0a << MATH_SRC1_SHIFT)
+#define MATH_SRC1_OUTFIFO       (0x0b << MATH_SRC1_SHIFT)
+#define MATH_SRC1_ONE           (0x0c << MATH_SRC1_SHIFT)
+
+/* Destination selectors */
+#define MATH_DEST_SHIFT         8
+#define MATH_DEST_MASK          (0x0f << MATH_DEST_SHIFT)
+#define MATH_DEST_REG0          (0x00 << MATH_DEST_SHIFT)
+#define MATH_DEST_REG1          (0x01 << MATH_DEST_SHIFT)
+#define MATH_DEST_REG2          (0x02 << MATH_DEST_SHIFT)
+#define MATH_DEST_REG3          (0x03 << MATH_DEST_SHIFT)
+#define MATH_DEST_SEQINLEN      (0x08 << MATH_DEST_SHIFT)
+#define MATH_DEST_SEQOUTLEN     (0x09 << MATH_DEST_SHIFT)
+#define MATH_DEST_VARSEQINLEN   (0x0a << MATH_DEST_SHIFT)
+#define MATH_DEST_VARSEQOUTLEN  (0x0b << MATH_DEST_SHIFT)
+#define MATH_DEST_NONE          (0x0f << MATH_DEST_SHIFT)
+
+/* Length selectors */
+#define MATH_LEN_SHIFT          0
+#define MATH_LEN_MASK           (0x0f << MATH_LEN_SHIFT)
+#define MATH_LEN_1BYTE          0x01
+#define MATH_LEN_2BYTE          0x02
+#define MATH_LEN_4BYTE          0x04
+#define MATH_LEN_8BYTE          0x08
+
+/*
+ * JUMP Command Constructs
+ */
+
+#define JUMP_CLASS_SHIFT        25
+#define JUMP_CLASS_MASK		(3 << JUMP_CLASS_SHIFT)
+#define JUMP_CLASS_NONE		0
+#define JUMP_CLASS_CLASS1	(1 << JUMP_CLASS_SHIFT)
+#define JUMP_CLASS_CLASS2	(2 << JUMP_CLASS_SHIFT)
+#define JUMP_CLASS_BOTH		(3 << JUMP_CLASS_SHIFT)
+
+#define JUMP_JSL_SHIFT          24
+#define JUMP_JSL_MASK           (1 << JUMP_JSL_SHIFT)
+#define JUMP_JSL                (1 << JUMP_JSL_SHIFT)
+
+#define JUMP_TYPE_SHIFT         22
+#define JUMP_TYPE_MASK          (0x03 << JUMP_TYPE_SHIFT)
+#define JUMP_TYPE_LOCAL         (0x00 << JUMP_TYPE_SHIFT)
+#define JUMP_TYPE_NONLOCAL      (0x01 << JUMP_TYPE_SHIFT)
+#define JUMP_TYPE_HALT          (0x02 << JUMP_TYPE_SHIFT)
+#define JUMP_TYPE_HALT_USER     (0x03 << JUMP_TYPE_SHIFT)
+
+#define JUMP_TEST_SHIFT         16
+#define JUMP_TEST_MASK          (0x03 << JUMP_TEST_SHIFT)
+#define JUMP_TEST_ALL           (0x00 << JUMP_TEST_SHIFT)
+#define JUMP_TEST_INVALL        (0x01 << JUMP_TEST_SHIFT)
+#define JUMP_TEST_ANY           (0x02 << JUMP_TEST_SHIFT)
+#define JUMP_TEST_INVANY        (0x03 << JUMP_TEST_SHIFT)
+
+/* Condition codes. JSL bit is factored in */
+#define JUMP_COND_SHIFT         8
+#define JUMP_COND_MASK          (0x100ff << JUMP_COND_SHIFT)
+#define JUMP_COND_PK_0          (0x80 << JUMP_COND_SHIFT)
+#define JUMP_COND_PK_GCD_1      (0x40 << JUMP_COND_SHIFT)
+#define JUMP_COND_PK_PRIME      (0x20 << JUMP_COND_SHIFT)
+#define JUMP_COND_MATH_N        (0x08 << JUMP_COND_SHIFT)
+#define JUMP_COND_MATH_Z        (0x04 << JUMP_COND_SHIFT)
+#define JUMP_COND_MATH_C        (0x02 << JUMP_COND_SHIFT)
+#define JUMP_COND_MATH_NV       (0x01 << JUMP_COND_SHIFT)
+
+#define JUMP_COND_JRP           ((0x80 << JUMP_COND_SHIFT) | JUMP_JSL)
+#define JUMP_COND_SHRD          ((0x40 << JUMP_COND_SHIFT) | JUMP_JSL)
+#define JUMP_COND_SELF          ((0x20 << JUMP_COND_SHIFT) | JUMP_JSL)
+#define JUMP_COND_CALM          ((0x10 << JUMP_COND_SHIFT) | JUMP_JSL)
+#define JUMP_COND_NIP           ((0x08 << JUMP_COND_SHIFT) | JUMP_JSL)
+#define JUMP_COND_NIFP          ((0x04 << JUMP_COND_SHIFT) | JUMP_JSL)
+#define JUMP_COND_NOP           ((0x02 << JUMP_COND_SHIFT) | JUMP_JSL)
+#define JUMP_COND_NCP           ((0x01 << JUMP_COND_SHIFT) | JUMP_JSL)
+
+#define JUMP_OFFSET_SHIFT       0
+#define JUMP_OFFSET_MASK        (0xff << JUMP_OFFSET_SHIFT)
+
+/*
+ * NFIFO ENTRY
+ * Data Constructs
+ *
+ */
+#define NFIFOENTRY_DEST_SHIFT	30
+#define NFIFOENTRY_DEST_MASK	(3 << NFIFOENTRY_DEST_SHIFT)
+#define NFIFOENTRY_DEST_DECO	(0 << NFIFOENTRY_DEST_SHIFT)
+#define NFIFOENTRY_DEST_CLASS1	(1 << NFIFOENTRY_DEST_SHIFT)
+#define NFIFOENTRY_DEST_CLASS2	(2 << NFIFOENTRY_DEST_SHIFT)
+#define NFIFOENTRY_DEST_BOTH	(3 << NFIFOENTRY_DEST_SHIFT)
+
+#define NFIFOENTRY_LC2_SHIFT	29
+#define NFIFOENTRY_LC2_MASK		(1 << NFIFOENTRY_LC2_SHIFT)
+#define NFIFOENTRY_LC2			(1 << NFIFOENTRY_LC2_SHIFT)
+
+#define NFIFOENTRY_LC1_SHIFT	28
+#define NFIFOENTRY_LC1_MASK		(1 << NFIFOENTRY_LC1_SHIFT)
+#define NFIFOENTRY_LC1			(1 << NFIFOENTRY_LC1_SHIFT)
+
+#define NFIFOENTRY_FC2_SHIFT	27
+#define NFIFOENTRY_FC2_MASK		(1 << NFIFOENTRY_FC2_SHIFT)
+#define NFIFOENTRY_FC2			(1 << NFIFOENTRY_FC2_SHIFT)
+
+#define NFIFOENTRY_FC1_SHIFT	26
+#define NFIFOENTRY_FC1_MASK		(1 << NFIFOENTRY_FC1_SHIFT)
+#define NFIFOENTRY_FC1			(1 << NFIFOENTRY_FC1_SHIFT)
+
+#define NFIFOENTRY_STYPE_SHIFT	24
+#define NFIFOENTRY_STYPE_MASK	(3 << NFIFOENTRY_STYPE_SHIFT)
+#define NFIFOENTRY_STYPE_DFIFO	(0 << NFIFOENTRY_STYPE_SHIFT)
+#define NFIFOENTRY_STYPE_OFIFO	(1 << NFIFOENTRY_STYPE_SHIFT)
+#define NFIFOENTRY_STYPE_PAD	(2 << NFIFOENTRY_STYPE_SHIFT)
+#define NFIFOENTRY_STYPE_SNOOP	(3 << NFIFOENTRY_STYPE_SHIFT)
+
+#define NFIFOENTRY_DTYPE_SHIFT	20
+#define NFIFOENTRY_DTYPE_MASK	(0xF << NFIFOENTRY_DTYPE_SHIFT)
+
+#define NFIFOENTRY_DTYPE_SBOX      (0x0  << NFIFOENTRY_DTYPE_SHIFT)
+#define NFIFOENTRY_DTYPE_AAD       (0x1  << NFIFOENTRY_DTYPE_SHIFT)
+#define NFIFOENTRY_DTYPE_IV        (0x2  << NFIFOENTRY_DTYPE_SHIFT)
+#define NFIFOENTRY_DTYPE_SAD       (0x3  << NFIFOENTRY_DTYPE_SHIFT)
+#define NFIFOENTRY_DTYPE_ICV       (0xA  << NFIFOENTRY_DTYPE_SHIFT)
+#define NFIFOENTRY_DTYPE_SKIP      (0xE  << NFIFOENTRY_DTYPE_SHIFT)
+#define NFIFOENTRY_DTYPE_MSG       (0xF  << NFIFOENTRY_DTYPE_SHIFT)
+
+#define NFIFOENTRY_DTYPE_PK_A0     (0x0  << NFIFOENTRY_DTYPE_SHIFT)
+#define NFIFOENTRY_DTYPE_PK_A1     (0x1  << NFIFOENTRY_DTYPE_SHIFT)
+#define NFIFOENTRY_DTYPE_PK_A2     (0x2  << NFIFOENTRY_DTYPE_SHIFT)
+#define NFIFOENTRY_DTYPE_PK_A3     (0x3  << NFIFOENTRY_DTYPE_SHIFT)
+#define NFIFOENTRY_DTYPE_PK_B0     (0x4  << NFIFOENTRY_DTYPE_SHIFT)
+#define NFIFOENTRY_DTYPE_PK_B1     (0x5  << NFIFOENTRY_DTYPE_SHIFT)
+#define NFIFOENTRY_DTYPE_PK_B2     (0x6  << NFIFOENTRY_DTYPE_SHIFT)
+#define NFIFOENTRY_DTYPE_PK_B3     (0x7  << NFIFOENTRY_DTYPE_SHIFT)
+#define NFIFOENTRY_DTYPE_PK_N      (0x8  << NFIFOENTRY_DTYPE_SHIFT)
+#define NFIFOENTRY_DTYPE_PK_E      (0x9  << NFIFOENTRY_DTYPE_SHIFT)
+#define NFIFOENTRY_DTYPE_PK_A      (0xC  << NFIFOENTRY_DTYPE_SHIFT)
+#define NFIFOENTRY_DTYPE_PK_B      (0xD  << NFIFOENTRY_DTYPE_SHIFT)
+
+
+#define NFIFOENTRY_BND_SHIFT	19
+#define NFIFOENTRY_BND_MASK		(1 << NFIFOENTRY_BND_SHIFT)
+#define NFIFOENTRY_BND			(1 << NFIFOENTRY_BND_SHIFT)
+
+#define NFIFOENTRY_PTYPE_SHIFT	16
+#define NFIFOENTRY_PTYPE_MASK	(0x7 << NFIFOENTRY_PTYPE_SHIFT)
+
+#define NFIFOENTRY_PTYPE_ZEROS         (0x0  << NFIFOENTRY_PTYPE_SHIFT)
+#define NFIFOENTRY_PTYPE_RND_NOZEROS   (0x1  << NFIFOENTRY_PTYPE_SHIFT)
+#define NFIFOENTRY_PTYPE_INCREMENT     (0x2  << NFIFOENTRY_PTYPE_SHIFT)
+#define NFIFOENTRY_PTYPE_RND           (0x3  << NFIFOENTRY_PTYPE_SHIFT)
+#define NFIFOENTRY_PTYPE_ZEROS_NZ      (0x4  << NFIFOENTRY_PTYPE_SHIFT)
+#define NFIFOENTRY_PTYPE_RND_NZ_LZ     (0x5  << NFIFOENTRY_PTYPE_SHIFT)
+#define NFIFOENTRY_PTYPE_N             (0x6  << NFIFOENTRY_PTYPE_SHIFT)
+#define NFIFOENTRY_PTYPE_RND_NZ_N      (0x7  << NFIFOENTRY_PTYPE_SHIFT)
+
+#define NFIFOENTRY_OC_SHIFT		15
+#define NFIFOENTRY_OC_MASK		(1 << NFIFOENTRY_OC_SHIFT)
+#define NFIFOENTRY_OC			(1 << NFIFOENTRY_OC_SHIFT)
+
+#define NFIFOENTRY_AST_SHIFT	14
+#define NFIFOENTRY_AST_MASK		(1 << NFIFOENTRY_OC_SHIFT)
+#define NFIFOENTRY_AST			(1 << NFIFOENTRY_OC_SHIFT)
+
+#define NFIFOENTRY_BM_SHIFT		11
+#define NFIFOENTRY_BM_MASK		(1 << NFIFOENTRY_BM_SHIFT)
+#define NFIFOENTRY_BM			(1 << NFIFOENTRY_BM_SHIFT)
+
+#define NFIFOENTRY_PS_SHIFT		10
+#define NFIFOENTRY_PS_MASK		(1 << NFIFOENTRY_PS_SHIFT)
+#define NFIFOENTRY_PS			(1 << NFIFOENTRY_PS_SHIFT)
+
+
+#define NFIFOENTRY_DLEN_SHIFT	0
+#define NFIFOENTRY_DLEN_MASK	(0xFFF << NFIFOENTRY_DLEN_SHIFT)
+
+#define NFIFOENTRY_PLEN_SHIFT	0
+#define NFIFOENTRY_PLEN_MASK	(0xFF << NFIFOENTRY_PLEN_SHIFT)
+
+/*
+ * PDB internal definitions
+ */
+
+/* IPSec ESP CBC Encap/Decap Options */
+#define PDBOPTS_ESPCBC_ARSNONE  0x00   /* no antireplay window              */
+#define PDBOPTS_ESPCBC_ARS32    0x40   /* 32-entry antireplay window        */
+#define PDBOPTS_ESPCBC_ARS64    0xc0   /* 64-entry antireplay window        */
+#define PDBOPTS_ESPCBC_IVSRC    0x20   /* IV comes from internal random gen */
+#define PDBOPTS_ESPCBC_ESN      0x10   /* extended sequence included        */
+#define PDBOPTS_ESPCBC_OUTFMT   0x08   /* output only decapsulation (decap) */
+#define PDBOPTS_ESPCBC_IPHDRSRC 0x08   /* IP header comes from PDB (encap)  */
+#define PDBOPTS_ESPCBC_INCIPHDR 0x04   /* Prepend IP header to output frame */
+#define PDBOPTS_ESPCBC_IPVSN    0x02   /* process IPv6 header               */
+#define PDBOPTS_ESPCBC_TUNNEL   0x01   /* tunnel mode next-header byte      */
+
+#endif /* DESC_H */
diff -druN linux-2.6.39-libre/drivers/crypto/caam/error.c linux-3.0-rc7-libre/drivers/crypto/caam/error.c
--- linux-2.6.39-libre/drivers/crypto/caam/error.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/crypto/caam/error.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,248 @@
+/*
+ * CAAM Error Reporting
+ *
+ * Copyright 2009-2011 Freescale Semiconductor, Inc.
+ */
+
+#include "compat.h"
+#include "regs.h"
+#include "intern.h"
+#include "desc.h"
+#include "jr.h"
+#include "error.h"
+
+#define SPRINTFCAT(str, format, param, max_alloc)		\
+{								\
+	char *tmp;						\
+								\
+	tmp = kmalloc(sizeof(format) + max_alloc, GFP_ATOMIC);	\
+	sprintf(tmp, format, param);				\
+	strcat(str, tmp);					\
+	kfree(tmp);						\
+}
+
+static void report_jump_idx(u32 status, char *outstr)
+{
+	u8 idx = (status & JRSTA_DECOERR_INDEX_MASK) >>
+		  JRSTA_DECOERR_INDEX_SHIFT;
+
+	if (status & JRSTA_DECOERR_JUMP)
+		strcat(outstr, "jump tgt desc idx ");
+	else
+		strcat(outstr, "desc idx ");
+
+	SPRINTFCAT(outstr, "%d: ", idx, sizeof("255"));
+}
+
+static void report_ccb_status(u32 status, char *outstr)
+{
+	char *cha_id_list[] = {
+		"",
+		"AES",
+		"DES, 3DES",
+		"ARC4",
+		"MD5, SHA-1, SH-224, SHA-256, SHA-384, SHA-512",
+		"RNG",
+		"SNOW f8",
+		"Kasumi f8, f9",
+		"All Public Key Algorithms",
+		"CRC",
+		"SNOW f9",
+	};
+	char *err_id_list[] = {
+		"None. No error.",
+		"Mode error.",
+		"Data size error.",
+		"Key size error.",
+		"PKHA A memory size error.",
+		"PKHA B memory size error.",
+		"Data arrived out of sequence error.",
+		"PKHA divide-by-zero error.",
+		"PKHA modulus even error.",
+		"DES key parity error.",
+		"ICV check failed.",
+		"Hardware error.",
+		"Unsupported CCM AAD size.",
+		"Class 1 CHA is not reset",
+		"Invalid CHA combination was selected",
+		"Invalid CHA selected.",
+	};
+	u8 cha_id = (status & JRSTA_CCBERR_CHAID_MASK) >>
+		    JRSTA_CCBERR_CHAID_SHIFT;
+	u8 err_id = status & JRSTA_CCBERR_ERRID_MASK;
+
+	report_jump_idx(status, outstr);
+
+	if (cha_id < ARRAY_SIZE(cha_id_list)) {
+		SPRINTFCAT(outstr, "%s: ", cha_id_list[cha_id],
+			   strlen(cha_id_list[cha_id]));
+	} else {
+		SPRINTFCAT(outstr, "unidentified cha_id value 0x%02x: ",
+			   cha_id, sizeof("ff"));
+	}
+
+	if (err_id < ARRAY_SIZE(err_id_list)) {
+		SPRINTFCAT(outstr, "%s", err_id_list[err_id],
+			   strlen(err_id_list[err_id]));
+	} else {
+		SPRINTFCAT(outstr, "unidentified err_id value 0x%02x",
+			   err_id, sizeof("ff"));
+	}
+}
+
+static void report_jump_status(u32 status, char *outstr)
+{
+	SPRINTFCAT(outstr, "%s() not implemented", __func__, sizeof(__func__));
+}
+
+static void report_deco_status(u32 status, char *outstr)
+{
+	const struct {
+		u8 value;
+		char *error_text;
+	} desc_error_list[] = {
+		{ 0x00, "None. No error." },
+		{ 0x01, "SGT Length Error. The descriptor is trying to read "
+			"more data than is contained in the SGT table." },
+		{ 0x02, "Reserved." },
+		{ 0x03, "Job Ring Control Error. There is a bad value in the "
+			"Job Ring Control register." },
+		{ 0x04, "Invalid Descriptor Command. The Descriptor Command "
+			"field is invalid." },
+		{ 0x05, "Reserved." },
+		{ 0x06, "Invalid KEY Command" },
+		{ 0x07, "Invalid LOAD Command" },
+		{ 0x08, "Invalid STORE Command" },
+		{ 0x09, "Invalid OPERATION Command" },
+		{ 0x0A, "Invalid FIFO LOAD Command" },
+		{ 0x0B, "Invalid FIFO STORE Command" },
+		{ 0x0C, "Invalid MOVE Command" },
+		{ 0x0D, "Invalid JUMP Command. A nonlocal JUMP Command is "
+			"invalid because the target is not a Job Header "
+			"Command, or the jump is from a Trusted Descriptor to "
+			"a Job Descriptor, or because the target Descriptor "
+			"contains a Shared Descriptor." },
+		{ 0x0E, "Invalid MATH Command" },
+		{ 0x0F, "Invalid SIGNATURE Command" },
+		{ 0x10, "Invalid Sequence Command. A SEQ IN PTR OR SEQ OUT PTR "
+			"Command is invalid or a SEQ KEY, SEQ LOAD, SEQ FIFO "
+			"LOAD, or SEQ FIFO STORE decremented the input or "
+			"output sequence length below 0. This error may result "
+			"if a built-in PROTOCOL Command has encountered a "
+			"malformed PDU." },
+		{ 0x11, "Skip data type invalid. The type must be 0xE or 0xF."},
+		{ 0x12, "Shared Descriptor Header Error" },
+		{ 0x13, "Header Error. Invalid length or parity, or certain "
+			"other problems." },
+		{ 0x14, "Burster Error. Burster has gotten to an illegal "
+			"state" },
+		{ 0x15, "Context Register Length Error. The descriptor is "
+			"trying to read or write past the end of the Context "
+			"Register. A SEQ LOAD or SEQ STORE with the VLF bit "
+			"set was executed with too large a length in the "
+			"variable length register (VSOL for SEQ STORE or VSIL "
+			"for SEQ LOAD)." },
+		{ 0x16, "DMA Error" },
+		{ 0x17, "Reserved." },
+		{ 0x1A, "Job failed due to JR reset" },
+		{ 0x1B, "Job failed due to Fail Mode" },
+		{ 0x1C, "DECO Watchdog timer timeout error" },
+		{ 0x1D, "DECO tried to copy a key from another DECO but the "
+			"other DECO's Key Registers were locked" },
+		{ 0x1E, "DECO attempted to copy data from a DECO that had an "
+			"unmasked Descriptor error" },
+		{ 0x1F, "LIODN error. DECO was trying to share from itself or "
+			"from another DECO but the two Non-SEQ LIODN values "
+			"didn't match or the 'shared from' DECO's Descriptor "
+			"required that the SEQ LIODNs be the same and they "
+			"aren't." },
+		{ 0x20, "DECO has completed a reset initiated via the DRR "
+			"register" },
+		{ 0x21, "Nonce error. When using EKT (CCM) key encryption "
+			"option in the FIFO STORE Command, the Nonce counter "
+			"reached its maximum value and this encryption mode "
+			"can no longer be used." },
+		{ 0x22, "Meta data is too large (> 511 bytes) for TLS decap "
+			"(input frame; block ciphers) and IPsec decap (output "
+			"frame, when doing the next header byte update) and "
+			"DCRC (output frame)." },
+		{ 0x80, "DNR (do not run) error" },
+		{ 0x81, "undefined protocol command" },
+		{ 0x82, "invalid setting in PDB" },
+		{ 0x83, "Anti-replay LATE error" },
+		{ 0x84, "Anti-replay REPLAY error" },
+		{ 0x85, "Sequence number overflow" },
+		{ 0x86, "Sigver invalid signature" },
+		{ 0x87, "DSA Sign Illegal test descriptor" },
+		{ 0x88, "Protocol Format Error - A protocol has seen an error "
+			"in the format of data received. When running RSA, "
+			"this means that formatting with random padding was "
+			"used, and did not follow the form: 0x00, 0x02, 8-to-N "
+			"bytes of non-zero pad, 0x00, F data." },
+		{ 0x89, "Protocol Size Error - A protocol has seen an error in "
+			"size. When running RSA, pdb size N < (size of F) when "
+			"no formatting is used; or pdb size N < (F + 11) when "
+			"formatting is used." },
+		{ 0xC1, "Blob Command error: Undefined mode" },
+		{ 0xC2, "Blob Command error: Secure Memory Blob mode error" },
+		{ 0xC4, "Blob Command error: Black Blob key or input size "
+			"error" },
+		{ 0xC5, "Blob Command error: Invalid key destination" },
+		{ 0xC8, "Blob Command error: Trusted/Secure mode error" },
+		{ 0xF0, "IPsec TTL or hop limit field either came in as 0, "
+			"or was decremented to 0" },
+		{ 0xF1, "3GPP HFN matches or exceeds the Threshold" },
+	};
+	u8 desc_error = status & JRSTA_DECOERR_ERROR_MASK;
+	int i;
+
+	report_jump_idx(status, outstr);
+
+	for (i = 0; i < ARRAY_SIZE(desc_error_list); i++)
+		if (desc_error_list[i].value == desc_error)
+			break;
+
+	if (i != ARRAY_SIZE(desc_error_list) && desc_error_list[i].error_text) {
+		SPRINTFCAT(outstr, "%s", desc_error_list[i].error_text,
+			   strlen(desc_error_list[i].error_text));
+	} else {
+		SPRINTFCAT(outstr, "unidentified error value 0x%02x",
+			   desc_error, sizeof("ff"));
+	}
+}
+
+static void report_jr_status(u32 status, char *outstr)
+{
+	SPRINTFCAT(outstr, "%s() not implemented", __func__, sizeof(__func__));
+}
+
+static void report_cond_code_status(u32 status, char *outstr)
+{
+	SPRINTFCAT(outstr, "%s() not implemented", __func__, sizeof(__func__));
+}
+
+char *caam_jr_strstatus(char *outstr, u32 status)
+{
+	struct stat_src {
+		void (*report_ssed)(u32 status, char *outstr);
+		char *error;
+	} status_src[] = {
+		{ NULL, "No error" },
+		{ NULL, NULL },
+		{ report_ccb_status, "CCB" },
+		{ report_jump_status, "Jump" },
+		{ report_deco_status, "DECO" },
+		{ NULL, NULL },
+		{ report_jr_status, "Job Ring" },
+		{ report_cond_code_status, "Condition Code" },
+	};
+	u32 ssrc = status >> JRSTA_SSRC_SHIFT;
+
+	sprintf(outstr, "%s: ", status_src[ssrc].error);
+
+	if (status_src[ssrc].report_ssed)
+		status_src[ssrc].report_ssed(status, outstr);
+
+	return outstr;
+}
+EXPORT_SYMBOL(caam_jr_strstatus);
diff -druN linux-2.6.39-libre/drivers/crypto/caam/error.h linux-3.0-rc7-libre/drivers/crypto/caam/error.h
--- linux-2.6.39-libre/drivers/crypto/caam/error.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/crypto/caam/error.h	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,11 @@
+/*
+ * CAAM Error Reporting code header
+ *
+ * Copyright 2009-2011 Freescale Semiconductor, Inc.
+ */
+
+#ifndef CAAM_ERROR_H
+#define CAAM_ERROR_H
+#define CAAM_ERROR_STR_MAX 302
+extern char *caam_jr_strstatus(char *outstr, u32 status);
+#endif /* CAAM_ERROR_H */
diff -druN linux-2.6.39-libre/drivers/crypto/caam/intern.h linux-3.0-rc7-libre/drivers/crypto/caam/intern.h
--- linux-2.6.39-libre/drivers/crypto/caam/intern.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/crypto/caam/intern.h	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,113 @@
+/*
+ * CAAM/SEC 4.x driver backend
+ * Private/internal definitions between modules
+ *
+ * Copyright 2008-2011 Freescale Semiconductor, Inc.
+ *
+ */
+
+#ifndef INTERN_H
+#define INTERN_H
+
+#define JOBR_UNASSIGNED 0
+#define JOBR_ASSIGNED 1
+
+/* Currently comes from Kconfig param as a ^2 (driver-required) */
+#define JOBR_DEPTH (1 << CONFIG_CRYPTO_DEV_FSL_CAAM_RINGSIZE)
+
+/* Kconfig params for interrupt coalescing if selected (else zero) */
+#ifdef CONFIG_CRYPTO_DEV_FSL_CAAM_INTC
+#define JOBR_INTC JRCFG_ICEN
+#define JOBR_INTC_TIME_THLD CONFIG_CRYPTO_DEV_FSL_CAAM_INTC_TIME_THLD
+#define JOBR_INTC_COUNT_THLD CONFIG_CRYPTO_DEV_FSL_CAAM_INTC_COUNT_THLD
+#else
+#define JOBR_INTC 0
+#define JOBR_INTC_TIME_THLD 0
+#define JOBR_INTC_COUNT_THLD 0
+#endif
+
+/*
+ * Storage for tracking each in-process entry moving across a ring
+ * Each entry on an output ring needs one of these
+ */
+struct caam_jrentry_info {
+	void (*callbk)(struct device *dev, u32 *desc, u32 status, void *arg);
+	void *cbkarg;	/* Argument per ring entry */
+	u32 *desc_addr_virt;	/* Stored virt addr for postprocessing */
+	dma_addr_t desc_addr_dma;	/* Stored bus addr for done matching */
+	u32 desc_size;	/* Stored size for postprocessing, header derived */
+};
+
+/* Private sub-storage for a single JobR */
+struct caam_drv_private_jr {
+	struct device *parentdev;	/* points back to controller dev */
+	int ridx;
+	struct caam_job_ring __iomem *rregs;	/* JobR's register space */
+	struct tasklet_struct irqtask[NR_CPUS];
+	int irq;			/* One per queue */
+	int assign;			/* busy/free */
+
+	/* Job ring info */
+	int ringsize;	/* Size of rings (assume input = output) */
+	struct caam_jrentry_info *entinfo;	/* Alloc'ed 1 per ring entry */
+	spinlock_t inplock ____cacheline_aligned; /* Input ring index lock */
+	int inp_ring_write_index;	/* Input index "tail" */
+	int head;			/* entinfo (s/w ring) head index */
+	dma_addr_t *inpring;	/* Base of input ring, alloc DMA-safe */
+	spinlock_t outlock ____cacheline_aligned; /* Output ring index lock */
+	int out_ring_read_index;	/* Output index "tail" */
+	int tail;			/* entinfo (s/w ring) tail index */
+	struct jr_outentry *outring;	/* Base of output ring, DMA-safe */
+};
+
+/*
+ * Driver-private storage for a single CAAM block instance
+ */
+struct caam_drv_private {
+
+	struct device *dev;
+	struct device **jrdev; /* Alloc'ed array per sub-device */
+	spinlock_t jr_alloc_lock;
+	struct platform_device *pdev;
+
+	/* Physical-presence section */
+	struct caam_ctrl *ctrl; /* controller region */
+	struct caam_deco **deco; /* DECO/CCB views */
+	struct caam_assurance *ac;
+	struct caam_queue_if *qi; /* QI control region */
+
+	/*
+	 * Detected geometry block. Filled in from device tree if powerpc,
+	 * or from register-based version detection code
+	 */
+	u8 total_jobrs;		/* Total Job Rings in device */
+	u8 qi_present;		/* Nonzero if QI present in device */
+	int secvio_irq;		/* Security violation interrupt number */
+
+	/* which jr allocated to scatterlist crypto */
+	atomic_t tfm_count ____cacheline_aligned;
+	int num_jrs_for_algapi;
+	struct device **algapi_jr;
+	/* list of registered crypto algorithms (mk generic context handle?) */
+	struct list_head alg_list;
+
+	/*
+	 * debugfs entries for developer view into driver/device
+	 * variables at runtime.
+	 */
+#ifdef CONFIG_DEBUG_FS
+	struct dentry *dfs_root;
+	struct dentry *ctl; /* controller dir */
+	struct dentry *ctl_rq_dequeued, *ctl_ob_enc_req, *ctl_ib_dec_req;
+	struct dentry *ctl_ob_enc_bytes, *ctl_ob_prot_bytes;
+	struct dentry *ctl_ib_dec_bytes, *ctl_ib_valid_bytes;
+	struct dentry *ctl_faultaddr, *ctl_faultdetail, *ctl_faultstatus;
+
+	struct debugfs_blob_wrapper ctl_kek_wrap, ctl_tkek_wrap, ctl_tdsk_wrap;
+	struct dentry *ctl_kek, *ctl_tkek, *ctl_tdsk;
+#endif
+};
+
+void caam_jr_algapi_init(struct device *dev);
+void caam_jr_algapi_remove(struct device *dev);
+#endif /* INTERN_H */
diff -druN linux-2.6.39-libre/drivers/crypto/caam/jr.c linux-3.0-rc7-libre/drivers/crypto/caam/jr.c
--- linux-2.6.39-libre/drivers/crypto/caam/jr.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/crypto/caam/jr.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,517 @@
+/*
+ * CAAM/SEC 4.x transport/backend driver
+ * JobR backend functionality
+ *
+ * Copyright 2008-2011 Freescale Semiconductor, Inc.
+ */
+
+#include "compat.h"
+#include "regs.h"
+#include "jr.h"
+#include "desc.h"
+#include "intern.h"
+
+/* Main per-ring interrupt handler */
+static irqreturn_t caam_jr_interrupt(int irq, void *st_dev)
+{
+	struct device *dev = st_dev;
+	struct caam_drv_private_jr *jrp = dev_get_drvdata(dev);
+	u32 irqstate;
+
+	/*
+	 * Check the output ring for ready responses, kick
+	 * tasklet if jobs done.
+	 */
+	irqstate = rd_reg32(&jrp->rregs->jrintstatus);
+	if (!irqstate)
+		return IRQ_NONE;
+
+	/*
+	 * If JobR error, we got more development work to do
+	 * Flag a bug now, but we really need to shut down and
+	 * restart the queue (and fix code).
+	 */
+	if (irqstate & JRINT_JR_ERROR) {
+		dev_err(dev, "job ring error: irqstate: %08x\n", irqstate);
+		BUG();
+	}
+
+	/* mask valid interrupts */
+	setbits32(&jrp->rregs->rconfig_lo, JRCFG_IMSK);
+
+	/* Have valid interrupt at this point, just ACK and trigger */
+	wr_reg32(&jrp->rregs->jrintstatus, irqstate);
+
+	preempt_disable();
+	tasklet_schedule(&jrp->irqtask[smp_processor_id()]);
+	preempt_enable();
+
+	return IRQ_HANDLED;
+}
+
+/* Deferred service handler, run as interrupt-fired tasklet */
+static void caam_jr_dequeue(unsigned long devarg)
+{
+	int hw_idx, sw_idx, i, head, tail;
+	struct device *dev = (struct device *)devarg;
+	struct caam_drv_private_jr *jrp = dev_get_drvdata(dev);
+	void (*usercall)(struct device *dev, u32 *desc, u32 status, void *arg);
+	u32 *userdesc, userstatus;
+	void *userarg;
+	unsigned long flags;
+
+	spin_lock_irqsave(&jrp->outlock, flags);
+
+	head = ACCESS_ONCE(jrp->head);
+	sw_idx = tail = jrp->tail;
+
+	while (CIRC_CNT(head, tail, JOBR_DEPTH) >= 1 &&
+	       rd_reg32(&jrp->rregs->outring_used)) {
+
+		hw_idx = jrp->out_ring_read_index;
+		for (i = 0; CIRC_CNT(head, tail + i, JOBR_DEPTH) >= 1; i++) {
+			sw_idx = (tail + i) & (JOBR_DEPTH - 1);
+
+			smp_read_barrier_depends();
+
+			if (jrp->outring[hw_idx].desc ==
+			    jrp->entinfo[sw_idx].desc_addr_dma)
+				break; /* found */
+		}
+		/* we should never fail to find a matching descriptor */
+		BUG_ON(CIRC_CNT(head, tail + i, JOBR_DEPTH) <= 0);
+
+		/* Unmap just-run descriptor so we can post-process */
+		dma_unmap_single(dev, jrp->outring[hw_idx].desc,
+				 jrp->entinfo[sw_idx].desc_size,
+				 DMA_TO_DEVICE);
+
+		/* mark completed, avoid matching on a recycled desc addr */
+		jrp->entinfo[sw_idx].desc_addr_dma = 0;
+
+		/* Stash callback params for use outside of lock */
+		usercall = jrp->entinfo[sw_idx].callbk;
+		userarg = jrp->entinfo[sw_idx].cbkarg;
+		userdesc = jrp->entinfo[sw_idx].desc_addr_virt;
+		userstatus = jrp->outring[hw_idx].jrstatus;
+
+		smp_mb();
+
+		jrp->out_ring_read_index = (jrp->out_ring_read_index + 1) &
+					   (JOBR_DEPTH - 1);
+
+		/*
+		 * if this job completed out-of-order, do not increment
+		 * the tail.  Otherwise, increment tail by 1 plus the
+		 * number of subsequent jobs already completed out-of-order
+		 */
+		if (sw_idx == tail) {
+			do {
+				tail = (tail + 1) & (JOBR_DEPTH - 1);
+				smp_read_barrier_depends();
+			} while (CIRC_CNT(head, tail, JOBR_DEPTH) >= 1 &&
+				 jrp->entinfo[tail].desc_addr_dma == 0);
+
+			jrp->tail = tail;
+		}
+
+		/* set done */
+		wr_reg32(&jrp->rregs->outring_rmvd, 1);
+
+		spin_unlock_irqrestore(&jrp->outlock, flags);
+
+		/* Finally, execute user's callback */
+		usercall(dev, userdesc, userstatus, userarg);
+
+		spin_lock_irqsave(&jrp->outlock, flags);
+
+		head = ACCESS_ONCE(jrp->head);
+		sw_idx = tail = jrp->tail;
+	}
+
+	spin_unlock_irqrestore(&jrp->outlock, flags);
+
+	/* reenable / unmask IRQs */
+	clrbits32(&jrp->rregs->rconfig_lo, JRCFG_IMSK);
+}
+
+/**
+ * caam_jr_register() - Alloc a ring for someone to use as needed. Returns
+ * an ordinal of the rings allocated, else returns -ENODEV if no rings
+ * are available.
+ * @ctrldev: points to the controller level dev (parent) that
+ *           owns rings available for use.
+ * @dev:     points to where a pointer to the newly allocated queue's
+ *           dev can be written to if successful.
+ **/
+int caam_jr_register(struct device *ctrldev, struct device **rdev)
+{
+	struct caam_drv_private *ctrlpriv = dev_get_drvdata(ctrldev);
+	struct caam_drv_private_jr *jrpriv = NULL;
+	unsigned long flags;
+	int ring;
+
+	/* Lock, if free ring - assign, unlock */
+	spin_lock_irqsave(&ctrlpriv->jr_alloc_lock, flags);
+	for (ring = 0; ring < ctrlpriv->total_jobrs; ring++) {
+		jrpriv = dev_get_drvdata(ctrlpriv->jrdev[ring]);
+		if (jrpriv->assign == JOBR_UNASSIGNED) {
+			jrpriv->assign = JOBR_ASSIGNED;
+			*rdev = ctrlpriv->jrdev[ring];
+			spin_unlock_irqrestore(&ctrlpriv->jr_alloc_lock, flags);
+			return ring;
+		}
+	}
+
+	/* If assigned, write dev where caller needs it */
+	spin_unlock_irqrestore(&ctrlpriv->jr_alloc_lock, flags);
+	*rdev = NULL;
+
+	return -ENODEV;
+}
+EXPORT_SYMBOL(caam_jr_register);
+
+/**
+ * caam_jr_deregister() - Deregister an API and release the queue.
+ * Returns 0 if OK, -EBUSY if queue still contains pending entries
+ * or unprocessed results at the time of the call
+ * @dev     - points to the dev that identifies the queue to
+ *            be released.
+ **/
+int caam_jr_deregister(struct device *rdev)
+{
+	struct caam_drv_private_jr *jrpriv = dev_get_drvdata(rdev);
+	struct caam_drv_private *ctrlpriv;
+	unsigned long flags;
+
+	/* Get the owning controller's private space */
+	ctrlpriv = dev_get_drvdata(jrpriv->parentdev);
+
+	/*
+	 * Make sure ring empty before release
+	 */
+	if (rd_reg32(&jrpriv->rregs->outring_used) ||
+	    (rd_reg32(&jrpriv->rregs->inpring_avail) != JOBR_DEPTH))
+		return -EBUSY;
+
+	/* Release ring */
+	spin_lock_irqsave(&ctrlpriv->jr_alloc_lock, flags);
+	jrpriv->assign = JOBR_UNASSIGNED;
+	spin_unlock_irqrestore(&ctrlpriv->jr_alloc_lock, flags);
+
+	return 0;
+}
+EXPORT_SYMBOL(caam_jr_deregister);
+
+/**
+ * caam_jr_enqueue() - Enqueue a job descriptor head. Returns 0 if OK,
+ * -EBUSY if the queue is full, -EIO if it cannot map the caller's
+ * descriptor.
+ * @dev:  device of the job ring to be used. This device should have
+ *        been assigned prior by caam_jr_register().
+ * @desc: points to a job descriptor that execute our request. All
+ *        descriptors (and all referenced data) must be in a DMAable
+ *        region, and all data references must be physical addresses
+ *        accessible to CAAM (i.e. within a PAMU window granted
+ *        to it).
+ * @cbk:  pointer to a callback function to be invoked upon completion
+ *        of this request. This has the form:
+ *        callback(struct device *dev, u32 *desc, u32 stat, void *arg)
+ *        where:
+ *        @dev:    contains the job ring device that processed this
+ *                 response.
+ *        @desc:   descriptor that initiated the request, same as
+ *                 "desc" being argued to caam_jr_enqueue().
+ *        @status: untranslated status received from CAAM. See the
+ *                 reference manual for a detailed description of
+ *                 error meaning, or see the JRSTA definitions in the
+ *                 register header file
+ *        @areq:   optional pointer to an argument passed with the
+ *                 original request
+ * @areq: optional pointer to a user argument for use at callback
+ *        time.
+ **/
+int caam_jr_enqueue(struct device *dev, u32 *desc,
+		    void (*cbk)(struct device *dev, u32 *desc,
+				u32 status, void *areq),
+		    void *areq)
+{
+	struct caam_drv_private_jr *jrp = dev_get_drvdata(dev);
+	struct caam_jrentry_info *head_entry;
+	unsigned long flags;
+	int head, tail, desc_size;
+	dma_addr_t desc_dma;
+
+	desc_size = (*desc & HDR_JD_LENGTH_MASK) * sizeof(u32);
+	desc_dma = dma_map_single(dev, desc, desc_size, DMA_TO_DEVICE);
+	if (dma_mapping_error(dev, desc_dma)) {
+		dev_err(dev, "caam_jr_enqueue(): can't map jobdesc\n");
+		return -EIO;
+	}
+
+	spin_lock_irqsave(&jrp->inplock, flags);
+
+	head = jrp->head;
+	tail = ACCESS_ONCE(jrp->tail);
+
+	if (!rd_reg32(&jrp->rregs->inpring_avail) ||
+	    CIRC_SPACE(head, tail, JOBR_DEPTH) <= 0) {
+		spin_unlock_irqrestore(&jrp->inplock, flags);
+		dma_unmap_single(dev, desc_dma, desc_size, DMA_TO_DEVICE);
+		return -EBUSY;
+	}
+
+	head_entry = &jrp->entinfo[head];
+	head_entry->desc_addr_virt = desc;
+	head_entry->desc_size = desc_size;
+	head_entry->callbk = (void *)cbk;
+	head_entry->cbkarg = areq;
+	head_entry->desc_addr_dma = desc_dma;
+
+	jrp->inpring[jrp->inp_ring_write_index] = desc_dma;
+
+	smp_wmb();
+
+	jrp->inp_ring_write_index = (jrp->inp_ring_write_index + 1) &
+				    (JOBR_DEPTH - 1);
+	jrp->head = (head + 1) & (JOBR_DEPTH - 1);
+
+	wmb();
+
+	wr_reg32(&jrp->rregs->inpring_jobadd, 1);
+
+	spin_unlock_irqrestore(&jrp->inplock, flags);
+
+	return 0;
+}
+EXPORT_SYMBOL(caam_jr_enqueue);
+
+static int caam_reset_hw_jr(struct device *dev)
+{
+	struct caam_drv_private_jr *jrp = dev_get_drvdata(dev);
+	unsigned int timeout = 100000;
+
+	/*
+	 * mask interrupts since we are going to poll
+	 * for reset completion status
+	 */
+	setbits32(&jrp->rregs->rconfig_lo, JRCFG_IMSK);
+
+	/* initiate flush (required prior to reset) */
+	wr_reg32(&jrp->rregs->jrcommand, JRCR_RESET);
+	while (((rd_reg32(&jrp->rregs->jrintstatus) & JRINT_ERR_HALT_MASK) ==
+		JRINT_ERR_HALT_INPROGRESS) && --timeout)
+		cpu_relax();
+
+	if ((rd_reg32(&jrp->rregs->jrintstatus) & JRINT_ERR_HALT_MASK) !=
+	    JRINT_ERR_HALT_COMPLETE || timeout == 0) {
+		dev_err(dev, "failed to flush job ring %d\n", jrp->ridx);
+		return -EIO;
+	}
+
+	/* initiate reset */
+	timeout = 100000;
+	wr_reg32(&jrp->rregs->jrcommand, JRCR_RESET);
+	while ((rd_reg32(&jrp->rregs->jrcommand) & JRCR_RESET) && --timeout)
+		cpu_relax();
+
+	if (timeout == 0) {
+		dev_err(dev, "failed to reset job ring %d\n", jrp->ridx);
+		return -EIO;
+	}
+
+	/* unmask interrupts */
+	clrbits32(&jrp->rregs->rconfig_lo, JRCFG_IMSK);
+
+	return 0;
+}
+
+/*
+ * Init JobR independent of platform property detection
+ */
+static int caam_jr_init(struct device *dev)
+{
+	struct caam_drv_private_jr *jrp;
+	dma_addr_t inpbusaddr, outbusaddr;
+	int i, error;
+
+	jrp = dev_get_drvdata(dev);
+
+	/* Connect job ring interrupt handler. */
+	for_each_possible_cpu(i)
+		tasklet_init(&jrp->irqtask[i], caam_jr_dequeue,
+			     (unsigned long)dev);
+
+	error = request_irq(jrp->irq, caam_jr_interrupt, IRQF_SHARED,
+			    "caam-jobr", dev);
+	if (error) {
+		dev_err(dev, "can't connect JobR %d interrupt (%d)\n",
+			jrp->ridx, jrp->irq);
+		irq_dispose_mapping(jrp->irq);
+		jrp->irq = 0;
+		return -EINVAL;
+	}
+
+	error = caam_reset_hw_jr(dev);
+	if (error)
+		return error;
+
+	jrp->inpring = kzalloc(sizeof(dma_addr_t) * JOBR_DEPTH,
+			       GFP_KERNEL | GFP_DMA);
+	jrp->outring = kzalloc(sizeof(struct jr_outentry) *
+			       JOBR_DEPTH, GFP_KERNEL | GFP_DMA);
+
+	jrp->entinfo = kzalloc(sizeof(struct caam_jrentry_info) * JOBR_DEPTH,
+			       GFP_KERNEL);
+
+	if ((jrp->inpring == NULL) || (jrp->outring == NULL) ||
+	    (jrp->entinfo == NULL)) {
+		dev_err(dev, "can't allocate job rings for %d\n",
+			jrp->ridx);
+		return -ENOMEM;
+	}
+
+	for (i = 0; i < JOBR_DEPTH; i++)
+		jrp->entinfo[i].desc_addr_dma = !0;
+
+	/* Setup rings */
+	inpbusaddr = dma_map_single(dev, jrp->inpring,
+				    sizeof(u32 *) * JOBR_DEPTH,
+				    DMA_BIDIRECTIONAL);
+	if (dma_mapping_error(dev, inpbusaddr)) {
+		dev_err(dev, "caam_jr_init(): can't map input ring\n");
+		kfree(jrp->inpring);
+		kfree(jrp->outring);
+		kfree(jrp->entinfo);
+		return -EIO;
+	}
+
+	outbusaddr = dma_map_single(dev, jrp->outring,
+				    sizeof(struct jr_outentry) * JOBR_DEPTH,
+				    DMA_BIDIRECTIONAL);
+	if (dma_mapping_error(dev, outbusaddr)) {
+		dev_err(dev, "caam_jr_init(): can't map output ring\n");
+			dma_unmap_single(dev, inpbusaddr,
+					 sizeof(u32 *) * JOBR_DEPTH,
+					 DMA_BIDIRECTIONAL);
+		kfree(jrp->inpring);
+		kfree(jrp->outring);
+		kfree(jrp->entinfo);
+		return -EIO;
+	}
+
+	jrp->inp_ring_write_index = 0;
+	jrp->out_ring_read_index = 0;
+	jrp->head = 0;
+	jrp->tail = 0;
+
+	wr_reg64(&jrp->rregs->inpring_base, inpbusaddr);
+	wr_reg64(&jrp->rregs->outring_base, outbusaddr);
+	wr_reg32(&jrp->rregs->inpring_size, JOBR_DEPTH);
+	wr_reg32(&jrp->rregs->outring_size, JOBR_DEPTH);
+
+	jrp->ringsize = JOBR_DEPTH;
+
+	spin_lock_init(&jrp->inplock);
+	spin_lock_init(&jrp->outlock);
+
+	/* Select interrupt coalescing parameters */
+	setbits32(&jrp->rregs->rconfig_lo, JOBR_INTC |
+		  (JOBR_INTC_COUNT_THLD << JRCFG_ICDCT_SHIFT) |
+		  (JOBR_INTC_TIME_THLD << JRCFG_ICTT_SHIFT));
+
+	jrp->assign = JOBR_UNASSIGNED;
+	return 0;
+}
+
+/*
+ * Shutdown JobR independent of platform property code
+ */
+int caam_jr_shutdown(struct device *dev)
+{
+	struct caam_drv_private_jr *jrp = dev_get_drvdata(dev);
+	dma_addr_t inpbusaddr, outbusaddr;
+	int ret, i;
+
+	ret = caam_reset_hw_jr(dev);
+
+	for_each_possible_cpu(i)
+		tasklet_kill(&jrp->irqtask[i]);
+
+	/* Release interrupt */
+	free_irq(jrp->irq, dev);
+
+	/* Free rings */
+	inpbusaddr = rd_reg64(&jrp->rregs->inpring_base);
+	outbusaddr = rd_reg64(&jrp->rregs->outring_base);
+	dma_unmap_single(dev, outbusaddr,
+			 sizeof(struct jr_outentry) * JOBR_DEPTH,
+			 DMA_BIDIRECTIONAL);
+	dma_unmap_single(dev, inpbusaddr, sizeof(u32 *) * JOBR_DEPTH,
+			 DMA_BIDIRECTIONAL);
+	kfree(jrp->outring);
+	kfree(jrp->inpring);
+	kfree(jrp->entinfo);
+
+	return ret;
+}
+
+/*
+ * Probe routine for each detected JobR subsystem. It assumes that
+ * property detection was picked up externally.
+ */
+int caam_jr_probe(struct platform_device *pdev, struct device_node *np,
+		  int ring)
+{
+	struct device *ctrldev, *jrdev;
+	struct platform_device *jr_pdev;
+	struct caam_drv_private *ctrlpriv;
+	struct caam_drv_private_jr *jrpriv;
+	u32 *jroffset;
+	int error;
+
+	ctrldev = &pdev->dev;
+	ctrlpriv = dev_get_drvdata(ctrldev);
+
+	jrpriv = kmalloc(sizeof(struct caam_drv_private_jr),
+			 GFP_KERNEL);
+	if (jrpriv == NULL) {
+		dev_err(ctrldev, "can't alloc private mem for job ring %d\n",
+			ring);
+		return -ENOMEM;
+	}
+	jrpriv->parentdev = ctrldev; /* point back to parent */
+	jrpriv->ridx = ring; /* save ring identity relative to detection */
+
+	/*
+	 * Derive a pointer to the detected JobRs regs
+	 * Driver has already iomapped the entire space, we just
+	 * need to add in the offset to this JobR. Don't know if I
+	 * like this long-term, but it'll run
+	 */
+	jroffset = (u32 *)of_get_property(np, "reg", NULL);
+	jrpriv->rregs = (struct caam_job_ring __iomem *)((void *)ctrlpriv->ctrl
+							 + *jroffset);
+
+	/* Build a local dev for each detected queue */
+	jr_pdev = of_platform_device_create(np, NULL, ctrldev);
+	if (jr_pdev == NULL) {
+		kfree(jrpriv);
+		return -EINVAL;
+	}
+	jrdev = &jr_pdev->dev;
+	dev_set_drvdata(jrdev, jrpriv);
+	ctrlpriv->jrdev[ring] = jrdev;
+
+	/* Identify the interrupt */
+	jrpriv->irq = of_irq_to_resource(np, 0, NULL);
+
+	/* Now do the platform independent part */
+	error = caam_jr_init(jrdev); /* now turn on hardware */
+	if (error) {
+		kfree(jrpriv);
+		return error;
+	}
+
+	return error;
+}
diff -druN linux-2.6.39-libre/drivers/crypto/caam/jr.h linux-3.0-rc7-libre/drivers/crypto/caam/jr.h
--- linux-2.6.39-libre/drivers/crypto/caam/jr.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/crypto/caam/jr.h	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,21 @@
+/*
+ * CAAM public-level include definitions for the JobR backend
+ *
+ * Copyright 2008-2011 Freescale Semiconductor, Inc.
+ */
+
+#ifndef JR_H
+#define JR_H
+
+/* Prototypes for backend-level services exposed to APIs */
+int caam_jr_register(struct device *ctrldev, struct device **rdev);
+int caam_jr_deregister(struct device *rdev);
+int caam_jr_enqueue(struct device *dev, u32 *desc,
+		    void (*cbk)(struct device *dev, u32 *desc, u32 status,
+				void *areq),
+		    void *areq);
+
+extern int caam_jr_probe(struct platform_device *pdev, struct device_node *np,
+			 int ring);
+extern int caam_jr_shutdown(struct device *dev);
+#endif /* JR_H */
diff -druN linux-2.6.39-libre/drivers/crypto/caam/Kconfig linux-3.0-rc7-libre/drivers/crypto/caam/Kconfig
--- linux-2.6.39-libre/drivers/crypto/caam/Kconfig	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/crypto/caam/Kconfig	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,72 @@
+config CRYPTO_DEV_FSL_CAAM
+	tristate "Freescale CAAM-Multicore driver backend"
+	depends on FSL_SOC
+	help
+	  Enables the driver module for Freescale's Cryptographic Accelerator
+	  and Assurance Module (CAAM), also known as the SEC version 4 (SEC4).
+	  This module adds a job ring operation interface, and configures h/w
+	  to operate as a DPAA component automatically, depending
+	  on h/w feature availability.
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called caam.
+
+config CRYPTO_DEV_FSL_CAAM_RINGSIZE
+	int "Job Ring size"
+	depends on CRYPTO_DEV_FSL_CAAM
+	range 2 9
+	default "9"
+	help
+	  Select size of Job Rings as a power of 2, within the
+	  range 2-9 (ring size 4-512).
+	  Examples:
+		2 => 4
+		3 => 8
+		4 => 16
+		5 => 32
+		6 => 64
+		7 => 128
+		8 => 256
+		9 => 512
+
+config CRYPTO_DEV_FSL_CAAM_INTC
+	bool "Job Ring interrupt coalescing"
+	depends on CRYPTO_DEV_FSL_CAAM
+	default y
+	help
+	  Enable the Job Ring's interrupt coalescing feature.
+
+config CRYPTO_DEV_FSL_CAAM_INTC_COUNT_THLD
+	int "Job Ring interrupt coalescing count threshold"
+	depends on CRYPTO_DEV_FSL_CAAM_INTC
+	range 1 255
+	default 255
+	help
+	  Select number of descriptor completions to queue before
+	  raising an interrupt, in the range 1-255. Note that a selection
+	  of 1 functionally defeats the coalescing feature, and a selection
+	  equal or greater than the job ring size will force timeouts.
+
+config CRYPTO_DEV_FSL_CAAM_INTC_TIME_THLD
+	int "Job Ring interrupt coalescing timer threshold"
+	depends on CRYPTO_DEV_FSL_CAAM_INTC
+	range 1 65535
+	default 2048
+	help
+	  Select number of bus clocks/64 to timeout in the case that one or
+	  more descriptor completions are queued without reaching the count
+	  threshold. Range is 1-65535.
+
+config CRYPTO_DEV_FSL_CAAM_CRYPTO_API
+	tristate "Register algorithm implementations with the Crypto API"
+	depends on CRYPTO_DEV_FSL_CAAM
+	default y
+	select CRYPTO_ALGAPI
+	select CRYPTO_AUTHENC
+	help
+	  Selecting this will offload crypto for users of the
+	  scatterlist crypto API (such as the linux native IPSec
+	  stack) to the SEC4 via job ring.
+
+	  To compile this as a module, choose M here: the module
+	  will be called caamalg.
diff -druN linux-2.6.39-libre/drivers/crypto/caam/Makefile linux-3.0-rc7-libre/drivers/crypto/caam/Makefile
--- linux-2.6.39-libre/drivers/crypto/caam/Makefile	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/crypto/caam/Makefile	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,8 @@
+#
+# Makefile for the CAAM backend and dependent components
+#
+
+obj-$(CONFIG_CRYPTO_DEV_FSL_CAAM) += caam.o
+obj-$(CONFIG_CRYPTO_DEV_FSL_CAAM_CRYPTO_API) += caamalg.o
+
+caam-objs := ctrl.o jr.o error.o
diff -druN linux-2.6.39-libre/drivers/crypto/caam/regs.h linux-3.0-rc7-libre/drivers/crypto/caam/regs.h
--- linux-2.6.39-libre/drivers/crypto/caam/regs.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/crypto/caam/regs.h	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,663 @@
+/*
+ * CAAM hardware register-level view
+ *
+ * Copyright 2008-2011 Freescale Semiconductor, Inc.
+ */
+
+#ifndef REGS_H
+#define REGS_H
+
+#include <linux/types.h>
+#include <linux/io.h>
+
+/*
+ * Architecture-specific register access methods
+ *
+ * CAAM's bus-addressable registers are 64 bits internally.
+ * They have been wired to be safely accessible on 32-bit
+ * architectures, however. Registers were organized such
+ * that (a) they can be contained in 32 bits, (b) if not, then they
+ * can be treated as two 32-bit entities, or finally (c) if they
+ * must be treated as a single 64-bit value, then this can safely
+ * be done with two 32-bit cycles.
+ *
+ * For 32-bit operations on 64-bit values, CAAM follows the same
+ * 64-bit register access conventions as it's predecessors, in that
+ * writes are "triggered" by a write to the register at the numerically
+ * higher address, thus, a full 64-bit write cycle requires a write
+ * to the lower address, followed by a write to the higher address,
+ * which will latch/execute the write cycle.
+ *
+ * For example, let's assume a SW reset of CAAM through the master
+ * configuration register.
+ * - SWRST is in bit 31 of MCFG.
+ * - MCFG begins at base+0x0000.
+ * - Bits 63-32 are a 32-bit word at base+0x0000 (numerically-lower)
+ * - Bits 31-0 are a 32-bit word at base+0x0004 (numerically-higher)
+ *
+ * (and on Power, the convention is 0-31, 32-63, I know...)
+ *
+ * Assuming a 64-bit write to this MCFG to perform a software reset
+ * would then require a write of 0 to base+0x0000, followed by a
+ * write of 0x80000000 to base+0x0004, which would "execute" the
+ * reset.
+ *
+ * Of course, since MCFG 63-32 is all zero, we could cheat and simply
+ * write 0x8000000 to base+0x0004, and the reset would work fine.
+ * However, since CAAM does contain some write-and-read-intended
+ * 64-bit registers, this code defines 64-bit access methods for
+ * the sake of internal consistency and simplicity, and so that a
+ * clean transition to 64-bit is possible when it becomes necessary.
+ *
+ * There are limitations to this that the developer must recognize.
+ * 32-bit architectures cannot enforce an atomic-64 operation,
+ * Therefore:
+ *
+ * - On writes, since the HW is assumed to latch the cycle on the
+ *   write of the higher-numeric-address word, then ordered
+ *   writes work OK.
+ *
+ * - For reads, where a register contains a relevant value of more
+ *   that 32 bits, the hardware employs logic to latch the other
+ *   "half" of the data until read, ensuring an accurate value.
+ *   This is of particular relevance when dealing with CAAM's
+ *   performance counters.
+ *
+ */
+
+#ifdef __BIG_ENDIAN
+#define wr_reg32(reg, data) out_be32(reg, data)
+#define rd_reg32(reg) in_be32(reg)
+#ifdef CONFIG_64BIT
+#define wr_reg64(reg, data) out_be64(reg, data)
+#define rd_reg64(reg) in_be64(reg)
+#endif
+#else
+#ifdef __LITTLE_ENDIAN
+#define wr_reg32(reg, data) __raw_writel(reg, data)
+#define rd_reg32(reg) __raw_readl(reg)
+#ifdef CONFIG_64BIT
+#define wr_reg64(reg, data) __raw_writeq(reg, data)
+#define rd_reg64(reg) __raw_readq(reg)
+#endif
+#endif
+#endif
+
+#ifndef CONFIG_64BIT
+static inline void wr_reg64(u64 __iomem *reg, u64 data)
+{
+	wr_reg32((u32 __iomem *)reg, (data & 0xffffffff00000000ull) >> 32);
+	wr_reg32((u32 __iomem *)reg + 1, data & 0x00000000ffffffffull);
+}
+
+static inline u64 rd_reg64(u64 __iomem *reg)
+{
+	return (((u64)rd_reg32((u32 __iomem *)reg)) << 32) |
+		((u64)rd_reg32((u32 __iomem *)reg + 1));
+}
+#endif
+
+/*
+ * jr_outentry
+ * Represents each entry in a JobR output ring
+ */
+struct jr_outentry {
+	dma_addr_t desc;/* Pointer to completed descriptor */
+	u32 jrstatus;	/* Status for completed descriptor */
+} __packed;
+
+/*
+ * caam_perfmon - Performance Monitor/Secure Memory Status/
+ *                CAAM Global Status/Component Version IDs
+ *
+ * Spans f00-fff wherever instantiated
+ */
+
+/* Number of DECOs */
+#define CHA_NUM_DECONUM_SHIFT	56
+#define CHA_NUM_DECONUM_MASK	(0xfull << CHA_NUM_DECONUM_SHIFT)
+
+struct caam_perfmon {
+	/* Performance Monitor Registers			f00-f9f */
+	u64 req_dequeued;	/* PC_REQ_DEQ - Dequeued Requests	     */
+	u64 ob_enc_req;	/* PC_OB_ENC_REQ - Outbound Encrypt Requests */
+	u64 ib_dec_req;	/* PC_IB_DEC_REQ - Inbound Decrypt Requests  */
+	u64 ob_enc_bytes;	/* PC_OB_ENCRYPT - Outbound Bytes Encrypted  */
+	u64 ob_prot_bytes;	/* PC_OB_PROTECT - Outbound Bytes Protected  */
+	u64 ib_dec_bytes;	/* PC_IB_DECRYPT - Inbound Bytes Decrypted   */
+	u64 ib_valid_bytes;	/* PC_IB_VALIDATED Inbound Bytes Validated   */
+	u64 rsvd[13];
+
+	/* CAAM Hardware Instantiation Parameters		fa0-fbf */
+	u64 cha_rev;		/* CRNR - CHA Revision Number		*/
+#define CTPR_QI_SHIFT		57
+#define CTPR_QI_MASK		(0x1ull << CTPR_QI_SHIFT)
+	u64 comp_parms;	/* CTPR - Compile Parameters Register	*/
+	u64 rsvd1[2];
+
+	/* CAAM Global Status					fc0-fdf */
+	u64 faultaddr;	/* FAR  - Fault Address		*/
+	u32 faultliodn;	/* FALR - Fault Address LIODN	*/
+	u32 faultdetail;	/* FADR - Fault Addr Detail	*/
+	u32 rsvd2;
+	u32 status;		/* CSTA - CAAM Status */
+	u64 rsvd3;
+
+	/* Component Instantiation Parameters			fe0-fff */
+	u32 rtic_id;		/* RVID - RTIC Version ID	*/
+	u32 ccb_id;		/* CCBVID - CCB Version ID	*/
+	u64 cha_id;		/* CHAVID - CHA Version ID	*/
+	u64 cha_num;		/* CHANUM - CHA Number		*/
+	u64 caam_id;		/* CAAMVID - CAAM Version ID	*/
+};
+
+/* LIODN programming for DMA configuration */
+#define MSTRID_LOCK_LIODN	0x80000000
+#define MSTRID_LOCK_MAKETRUSTED	0x00010000	/* only for JR masterid */
+
+#define MSTRID_LIODN_MASK	0x0fff
+struct masterid {
+	u32 liodn_ms;	/* lock and make-trusted control bits */
+	u32 liodn_ls;	/* LIODN for non-sequence and seq access */
+};
+
+/* Partition ID for DMA configuration */
+struct partid {
+	u32 rsvd1;
+	u32 pidr;	/* partition ID, DECO */
+};
+
+/* RNG test mode (replicated twice in some configurations) */
+/* Padded out to 0x100 */
+struct rngtst {
+	u32 mode;		/* RTSTMODEx - Test mode */
+	u32 rsvd1[3];
+	u32 reset;		/* RTSTRESETx - Test reset control */
+	u32 rsvd2[3];
+	u32 status;		/* RTSTSSTATUSx - Test status */
+	u32 rsvd3;
+	u32 errstat;		/* RTSTERRSTATx - Test error status */
+	u32 rsvd4;
+	u32 errctl;		/* RTSTERRCTLx - Test error control */
+	u32 rsvd5;
+	u32 entropy;		/* RTSTENTROPYx - Test entropy */
+	u32 rsvd6[15];
+	u32 verifctl;	/* RTSTVERIFCTLx - Test verification control */
+	u32 rsvd7;
+	u32 verifstat;	/* RTSTVERIFSTATx - Test verification status */
+	u32 rsvd8;
+	u32 verifdata;	/* RTSTVERIFDx - Test verification data */
+	u32 rsvd9;
+	u32 xkey;		/* RTSTXKEYx - Test XKEY */
+	u32 rsvd10;
+	u32 oscctctl;	/* RTSTOSCCTCTLx - Test osc. counter control */
+	u32 rsvd11;
+	u32 oscct;		/* RTSTOSCCTx - Test oscillator counter */
+	u32 rsvd12;
+	u32 oscctstat;	/* RTSTODCCTSTATx - Test osc counter status */
+	u32 rsvd13[2];
+	u32 ofifo[4];	/* RTSTOFIFOx - Test output FIFO */
+	u32 rsvd14[15];
+};
+
+/*
+ * caam_ctrl - basic core configuration
+ * starts base + 0x0000 padded out to 0x1000
+ */
+
+#define KEK_KEY_SIZE		8
+#define TKEK_KEY_SIZE		8
+#define TDSK_KEY_SIZE		8
+
+#define DECO_RESET	1	/* Use with DECO reset/availability regs */
+#define DECO_RESET_0	(DECO_RESET << 0)
+#define DECO_RESET_1	(DECO_RESET << 1)
+#define DECO_RESET_2	(DECO_RESET << 2)
+#define DECO_RESET_3	(DECO_RESET << 3)
+#define DECO_RESET_4	(DECO_RESET << 4)
+
+struct caam_ctrl {
+	/* Basic Configuration Section				000-01f */
+	/* Read/Writable					        */
+	u32 rsvd1;
+	u32 mcr;		/* MCFG      Master Config Register  */
+	u32 rsvd2[2];
+
+	/* Bus Access Configuration Section			010-11f */
+	/* Read/Writable                                                */
+	struct masterid jr_mid[4];	/* JRxLIODNR - JobR LIODN setup */
+	u32 rsvd3[12];
+	struct masterid rtic_mid[4];	/* RTICxLIODNR - RTIC LIODN setup */
+	u32 rsvd4[7];
+	u32 deco_rq;			/* DECORR - DECO Request */
+	struct partid deco_mid[5];	/* DECOxLIODNR - 1 per DECO */
+	u32 rsvd5[22];
+
+	/* DECO Availability/Reset Section			120-3ff */
+	u32 deco_avail;		/* DAR - DECO availability */
+	u32 deco_reset;		/* DRR - DECO reset */
+	u32 rsvd6[182];
+
+	/* Key Encryption/Decryption Configuration              400-5ff */
+	/* Read/Writable only while in Non-secure mode                  */
+	u32 kek[KEK_KEY_SIZE];	/* JDKEKR - Key Encryption Key */
+	u32 tkek[TKEK_KEY_SIZE];	/* TDKEKR - Trusted Desc KEK */
+	u32 tdsk[TDSK_KEY_SIZE];	/* TDSKR - Trusted Desc Signing Key */
+	u32 rsvd7[32];
+	u64 sknonce;			/* SKNR - Secure Key Nonce */
+	u32 rsvd8[70];
+
+	/* RNG Test/Verification/Debug Access                   600-7ff */
+	/* (Useful in Test/Debug modes only...)                         */
+	struct rngtst rtst[2];
+
+	u32 rsvd9[448];
+
+	/* Performance Monitor                                  f00-fff */
+	struct caam_perfmon perfmon;
+};
+
+/*
+ * Controller master config register defs
+ */
+#define MCFGR_SWRESET		0x80000000 /* software reset */
+#define MCFGR_WDENABLE		0x40000000 /* DECO watchdog enable */
+#define MCFGR_WDFAIL		0x20000000 /* DECO watchdog force-fail */
+#define MCFGR_DMA_RESET		0x10000000
+#define MCFGR_LONG_PTR		0x00010000 /* Use >32-bit desc addressing */
+
+/* AXI read cache control */
+#define MCFGR_ARCACHE_SHIFT	12
+#define MCFGR_ARCACHE_MASK	(0xf << MCFGR_ARCACHE_SHIFT)
+
+/* AXI write cache control */
+#define MCFGR_AWCACHE_SHIFT	8
+#define MCFGR_AWCACHE_MASK	(0xf << MCFGR_AWCACHE_SHIFT)
+
+/* AXI pipeline depth */
+#define MCFGR_AXIPIPE_SHIFT	4
+#define MCFGR_AXIPIPE_MASK	(0xf << MCFGR_AXIPIPE_SHIFT)
+
+#define MCFGR_AXIPRI		0x00000008 /* Assert AXI priority sideband */
+#define MCFGR_BURST_64		0x00000001 /* Max burst size */
+
+/*
+ * caam_job_ring - direct job ring setup
+ * 1-4 possible per instantiation, base + 1000/2000/3000/4000
+ * Padded out to 0x1000
+ */
+struct caam_job_ring {
+	/* Input ring */
+	u64 inpring_base;	/* IRBAx -  Input desc ring baseaddr */
+	u32 rsvd1;
+	u32 inpring_size;	/* IRSx - Input ring size */
+	u32 rsvd2;
+	u32 inpring_avail;	/* IRSAx - Input ring room remaining */
+	u32 rsvd3;
+	u32 inpring_jobadd;	/* IRJAx - Input ring jobs added */
+
+	/* Output Ring */
+	u64 outring_base;	/* ORBAx - Output status ring base addr */
+	u32 rsvd4;
+	u32 outring_size;	/* ORSx - Output ring size */
+	u32 rsvd5;
+	u32 outring_rmvd;	/* ORJRx - Output ring jobs removed */
+	u32 rsvd6;
+	u32 outring_used;	/* ORSFx - Output ring slots full */
+
+	/* Status/Configuration */
+	u32 rsvd7;
+	u32 jroutstatus;	/* JRSTAx - JobR output status */
+	u32 rsvd8;
+	u32 jrintstatus;	/* JRINTx - JobR interrupt status */
+	u32 rconfig_hi;	/* JRxCFG - Ring configuration */
+	u32 rconfig_lo;
+
+	/* Indices. CAAM maintains as "heads" of each queue */
+	u32 rsvd9;
+	u32 inp_rdidx;	/* IRRIx - Input ring read index */
+	u32 rsvd10;
+	u32 out_wtidx;	/* ORWIx - Output ring write index */
+
+	/* Command/control */
+	u32 rsvd11;
+	u32 jrcommand;	/* JRCRx - JobR command */
+
+	u32 rsvd12[932];
+
+	/* Performance Monitor                                  f00-fff */
+	struct caam_perfmon perfmon;
+};
+
+#define JR_RINGSIZE_MASK	0x03ff
+/*
+ * jrstatus - Job Ring Output Status
+ * All values in lo word
+ * Also note, same values written out as status through QI
+ * in the command/status field of a frame descriptor
+ */
+#define JRSTA_SSRC_SHIFT            28
+#define JRSTA_SSRC_MASK             0xf0000000
+
+#define JRSTA_SSRC_NONE             0x00000000
+#define JRSTA_SSRC_CCB_ERROR        0x20000000
+#define JRSTA_SSRC_JUMP_HALT_USER   0x30000000
+#define JRSTA_SSRC_DECO             0x40000000
+#define JRSTA_SSRC_JRERROR          0x60000000
+#define JRSTA_SSRC_JUMP_HALT_CC     0x70000000
+
+#define JRSTA_DECOERR_JUMP          0x08000000
+#define JRSTA_DECOERR_INDEX_SHIFT   8
+#define JRSTA_DECOERR_INDEX_MASK    0xff00
+#define JRSTA_DECOERR_ERROR_MASK    0x00ff
+
+#define JRSTA_DECOERR_NONE          0x00
+#define JRSTA_DECOERR_LINKLEN       0x01
+#define JRSTA_DECOERR_LINKPTR       0x02
+#define JRSTA_DECOERR_JRCTRL        0x03
+#define JRSTA_DECOERR_DESCCMD       0x04
+#define JRSTA_DECOERR_ORDER         0x05
+#define JRSTA_DECOERR_KEYCMD        0x06
+#define JRSTA_DECOERR_LOADCMD       0x07
+#define JRSTA_DECOERR_STORECMD      0x08
+#define JRSTA_DECOERR_OPCMD         0x09
+#define JRSTA_DECOERR_FIFOLDCMD     0x0a
+#define JRSTA_DECOERR_FIFOSTCMD     0x0b
+#define JRSTA_DECOERR_MOVECMD       0x0c
+#define JRSTA_DECOERR_JUMPCMD       0x0d
+#define JRSTA_DECOERR_MATHCMD       0x0e
+#define JRSTA_DECOERR_SHASHCMD      0x0f
+#define JRSTA_DECOERR_SEQCMD        0x10
+#define JRSTA_DECOERR_DECOINTERNAL  0x11
+#define JRSTA_DECOERR_SHDESCHDR     0x12
+#define JRSTA_DECOERR_HDRLEN        0x13
+#define JRSTA_DECOERR_BURSTER       0x14
+#define JRSTA_DECOERR_DESCSIGNATURE 0x15
+#define JRSTA_DECOERR_DMA           0x16
+#define JRSTA_DECOERR_BURSTFIFO     0x17
+#define JRSTA_DECOERR_JRRESET       0x1a
+#define JRSTA_DECOERR_JOBFAIL       0x1b
+#define JRSTA_DECOERR_DNRERR        0x80
+#define JRSTA_DECOERR_UNDEFPCL      0x81
+#define JRSTA_DECOERR_PDBERR        0x82
+#define JRSTA_DECOERR_ANRPLY_LATE   0x83
+#define JRSTA_DECOERR_ANRPLY_REPLAY 0x84
+#define JRSTA_DECOERR_SEQOVF        0x85
+#define JRSTA_DECOERR_INVSIGN       0x86
+#define JRSTA_DECOERR_DSASIGN       0x87
+
+#define JRSTA_CCBERR_JUMP           0x08000000
+#define JRSTA_CCBERR_INDEX_MASK     0xff00
+#define JRSTA_CCBERR_INDEX_SHIFT    8
+#define JRSTA_CCBERR_CHAID_MASK     0x00f0
+#define JRSTA_CCBERR_CHAID_SHIFT    4
+#define JRSTA_CCBERR_ERRID_MASK     0x000f
+
+#define JRSTA_CCBERR_CHAID_AES      (0x01 << JRSTA_CCBERR_CHAID_SHIFT)
+#define JRSTA_CCBERR_CHAID_DES      (0x02 << JRSTA_CCBERR_CHAID_SHIFT)
+#define JRSTA_CCBERR_CHAID_ARC4     (0x03 << JRSTA_CCBERR_CHAID_SHIFT)
+#define JRSTA_CCBERR_CHAID_MD       (0x04 << JRSTA_CCBERR_CHAID_SHIFT)
+#define JRSTA_CCBERR_CHAID_RNG      (0x05 << JRSTA_CCBERR_CHAID_SHIFT)
+#define JRSTA_CCBERR_CHAID_SNOW     (0x06 << JRSTA_CCBERR_CHAID_SHIFT)
+#define JRSTA_CCBERR_CHAID_KASUMI   (0x07 << JRSTA_CCBERR_CHAID_SHIFT)
+#define JRSTA_CCBERR_CHAID_PK       (0x08 << JRSTA_CCBERR_CHAID_SHIFT)
+#define JRSTA_CCBERR_CHAID_CRC      (0x09 << JRSTA_CCBERR_CHAID_SHIFT)
+
+#define JRSTA_CCBERR_ERRID_NONE     0x00
+#define JRSTA_CCBERR_ERRID_MODE     0x01
+#define JRSTA_CCBERR_ERRID_DATASIZ  0x02
+#define JRSTA_CCBERR_ERRID_KEYSIZ   0x03
+#define JRSTA_CCBERR_ERRID_PKAMEMSZ 0x04
+#define JRSTA_CCBERR_ERRID_PKBMEMSZ 0x05
+#define JRSTA_CCBERR_ERRID_SEQUENCE 0x06
+#define JRSTA_CCBERR_ERRID_PKDIVZRO 0x07
+#define JRSTA_CCBERR_ERRID_PKMODEVN 0x08
+#define JRSTA_CCBERR_ERRID_KEYPARIT 0x09
+#define JRSTA_CCBERR_ERRID_ICVCHK   0x0a
+#define JRSTA_CCBERR_ERRID_HARDWARE 0x0b
+#define JRSTA_CCBERR_ERRID_CCMAAD   0x0c
+#define JRSTA_CCBERR_ERRID_INVCHA   0x0f
+
+#define JRINT_ERR_INDEX_MASK        0x3fff0000
+#define JRINT_ERR_INDEX_SHIFT       16
+#define JRINT_ERR_TYPE_MASK         0xf00
+#define JRINT_ERR_TYPE_SHIFT        8
+#define JRINT_ERR_HALT_MASK         0xc
+#define JRINT_ERR_HALT_SHIFT        2
+#define JRINT_ERR_HALT_INPROGRESS   0x4
+#define JRINT_ERR_HALT_COMPLETE     0x8
+#define JRINT_JR_ERROR              0x02
+#define JRINT_JR_INT                0x01
+
+#define JRINT_ERR_TYPE_WRITE        1
+#define JRINT_ERR_TYPE_BAD_INPADDR  3
+#define JRINT_ERR_TYPE_BAD_OUTADDR  4
+#define JRINT_ERR_TYPE_INV_INPWRT   5
+#define JRINT_ERR_TYPE_INV_OUTWRT   6
+#define JRINT_ERR_TYPE_RESET        7
+#define JRINT_ERR_TYPE_REMOVE_OFL   8
+#define JRINT_ERR_TYPE_ADD_OFL      9
+
+#define JRCFG_SOE		0x04
+#define JRCFG_ICEN		0x02
+#define JRCFG_IMSK		0x01
+#define JRCFG_ICDCT_SHIFT	8
+#define JRCFG_ICTT_SHIFT	16
+
+#define JRCR_RESET                  0x01
+
+/*
+ * caam_assurance - Assurance Controller View
+ * base + 0x6000 padded out to 0x1000
+ */
+
+struct rtic_element {
+	u64 address;
+	u32 rsvd;
+	u32 length;
+};
+
+struct rtic_block {
+	struct rtic_element element[2];
+};
+
+struct rtic_memhash {
+	u32 memhash_be[32];
+	u32 memhash_le[32];
+};
+
+struct caam_assurance {
+    /* Status/Command/Watchdog */
+	u32 rsvd1;
+	u32 status;		/* RSTA - Status */
+	u32 rsvd2;
+	u32 cmd;		/* RCMD - Command */
+	u32 rsvd3;
+	u32 ctrl;		/* RCTL - Control */
+	u32 rsvd4;
+	u32 throttle;	/* RTHR - Throttle */
+	u32 rsvd5[2];
+	u64 watchdog;	/* RWDOG - Watchdog Timer */
+	u32 rsvd6;
+	u32 rend;		/* REND - Endian corrections */
+	u32 rsvd7[50];
+
+	/* Block access/configuration @ 100/110/120/130 */
+	struct rtic_block memblk[4];	/* Memory Blocks A-D */
+	u32 rsvd8[32];
+
+	/* Block hashes @ 200/300/400/500 */
+	struct rtic_memhash hash[4];	/* Block hash values A-D */
+	u32 rsvd_3[640];
+};
+
+/*
+ * caam_queue_if - QI configuration and control
+ * starts base + 0x7000, padded out to 0x1000 long
+ */
+
+struct caam_queue_if {
+	u32 qi_control_hi;	/* QICTL  - QI Control */
+	u32 qi_control_lo;
+	u32 rsvd1;
+	u32 qi_status;	/* QISTA  - QI Status */
+	u32 qi_deq_cfg_hi;	/* QIDQC  - QI Dequeue Configuration */
+	u32 qi_deq_cfg_lo;
+	u32 qi_enq_cfg_hi;	/* QISEQC - QI Enqueue Command     */
+	u32 qi_enq_cfg_lo;
+	u32 rsvd2[1016];
+};
+
+/* QI control bits - low word */
+#define QICTL_DQEN      0x01              /* Enable frame pop          */
+#define QICTL_STOP      0x02              /* Stop dequeue/enqueue      */
+#define QICTL_SOE       0x04              /* Stop on error             */
+
+/* QI control bits - high word */
+#define QICTL_MBSI	0x01
+#define QICTL_MHWSI	0x02
+#define QICTL_MWSI	0x04
+#define QICTL_MDWSI	0x08
+#define QICTL_CBSI	0x10		/* CtrlDataByteSwapInput     */
+#define QICTL_CHWSI	0x20		/* CtrlDataHalfSwapInput     */
+#define QICTL_CWSI	0x40		/* CtrlDataWordSwapInput     */
+#define QICTL_CDWSI	0x80		/* CtrlDataDWordSwapInput    */
+#define QICTL_MBSO	0x0100
+#define QICTL_MHWSO	0x0200
+#define QICTL_MWSO	0x0400
+#define QICTL_MDWSO	0x0800
+#define QICTL_CBSO	0x1000		/* CtrlDataByteSwapOutput    */
+#define QICTL_CHWSO	0x2000		/* CtrlDataHalfSwapOutput    */
+#define QICTL_CWSO	0x4000		/* CtrlDataWordSwapOutput    */
+#define QICTL_CDWSO     0x8000		/* CtrlDataDWordSwapOutput   */
+#define QICTL_DMBS	0x010000
+#define QICTL_EPO	0x020000
+
+/* QI status bits */
+#define QISTA_PHRDERR   0x01              /* PreHeader Read Error      */
+#define QISTA_CFRDERR   0x02              /* Compound Frame Read Error */
+#define QISTA_OFWRERR   0x04              /* Output Frame Read Error   */
+#define QISTA_BPDERR    0x08              /* Buffer Pool Depleted      */
+#define QISTA_BTSERR    0x10              /* Buffer Undersize          */
+#define QISTA_CFWRERR   0x20              /* Compound Frame Write Err  */
+#define QISTA_STOPD     0x80000000        /* QI Stopped (see QICTL)    */
+
+/* deco_sg_table - DECO view of scatter/gather table */
+struct deco_sg_table {
+	u64 addr;		/* Segment Address */
+	u32 elen;		/* E, F bits + 30-bit length */
+	u32 bpid_offset;	/* Buffer Pool ID + 16-bit length */
+};
+
+/*
+ * caam_deco - descriptor controller - CHA cluster block
+ *
+ * Only accessible when direct DECO access is turned on
+ * (done in DECORR, via MID programmed in DECOxMID
+ *
+ * 5 typical, base + 0x8000/9000/a000/b000
+ * Padded out to 0x1000 long
+ */
+struct caam_deco {
+	u32 rsvd1;
+	u32 cls1_mode;	/* CxC1MR -  Class 1 Mode */
+	u32 rsvd2;
+	u32 cls1_keysize;	/* CxC1KSR - Class 1 Key Size */
+	u32 cls1_datasize_hi;	/* CxC1DSR - Class 1 Data Size */
+	u32 cls1_datasize_lo;
+	u32 rsvd3;
+	u32 cls1_icvsize;	/* CxC1ICVSR - Class 1 ICV size */
+	u32 rsvd4[5];
+	u32 cha_ctrl;	/* CCTLR - CHA control */
+	u32 rsvd5;
+	u32 irq_crtl;	/* CxCIRQ - CCB interrupt done/error/clear */
+	u32 rsvd6;
+	u32 clr_written;	/* CxCWR - Clear-Written */
+	u32 ccb_status_hi;	/* CxCSTA - CCB Status/Error */
+	u32 ccb_status_lo;
+	u32 rsvd7[3];
+	u32 aad_size;	/* CxAADSZR - Current AAD Size */
+	u32 rsvd8;
+	u32 cls1_iv_size;	/* CxC1IVSZR - Current Class 1 IV Size */
+	u32 rsvd9[7];
+	u32 pkha_a_size;	/* PKASZRx - Size of PKHA A */
+	u32 rsvd10;
+	u32 pkha_b_size;	/* PKBSZRx - Size of PKHA B */
+	u32 rsvd11;
+	u32 pkha_n_size;	/* PKNSZRx - Size of PKHA N */
+	u32 rsvd12;
+	u32 pkha_e_size;	/* PKESZRx - Size of PKHA E */
+	u32 rsvd13[24];
+	u32 cls1_ctx[16];	/* CxC1CTXR - Class 1 Context @100 */
+	u32 rsvd14[48];
+	u32 cls1_key[8];	/* CxC1KEYR - Class 1 Key @200 */
+	u32 rsvd15[121];
+	u32 cls2_mode;	/* CxC2MR - Class 2 Mode */
+	u32 rsvd16;
+	u32 cls2_keysize;	/* CxX2KSR - Class 2 Key Size */
+	u32 cls2_datasize_hi;	/* CxC2DSR - Class 2 Data Size */
+	u32 cls2_datasize_lo;
+	u32 rsvd17;
+	u32 cls2_icvsize;	/* CxC2ICVSZR - Class 2 ICV Size */
+	u32 rsvd18[56];
+	u32 cls2_ctx[18];	/* CxC2CTXR - Class 2 Context @500 */
+	u32 rsvd19[46];
+	u32 cls2_key[32];	/* CxC2KEYR - Class2 Key @600 */
+	u32 rsvd20[84];
+	u32 inp_infofifo_hi;	/* CxIFIFO - Input Info FIFO @7d0 */
+	u32 inp_infofifo_lo;
+	u32 rsvd21[2];
+	u64 inp_datafifo;	/* CxDFIFO - Input Data FIFO */
+	u32 rsvd22[2];
+	u64 out_datafifo;	/* CxOFIFO - Output Data FIFO */
+	u32 rsvd23[2];
+	u32 jr_ctl_hi;	/* CxJRR - JobR Control Register      @800 */
+	u32 jr_ctl_lo;
+	u64 jr_descaddr;	/* CxDADR - JobR Descriptor Address */
+	u32 op_status_hi;	/* DxOPSTA - DECO Operation Status */
+	u32 op_status_lo;
+	u32 rsvd24[2];
+	u32 liodn;		/* DxLSR - DECO LIODN Status - non-seq */
+	u32 td_liodn;	/* DxLSR - DECO LIODN Status - trustdesc */
+	u32 rsvd26[6];
+	u64 math[4];		/* DxMTH - Math register */
+	u32 rsvd27[8];
+	struct deco_sg_table gthr_tbl[4];	/* DxGTR - Gather Tables */
+	u32 rsvd28[16];
+	struct deco_sg_table sctr_tbl[4];	/* DxSTR - Scatter Tables */
+	u32 rsvd29[48];
+	u32 descbuf[64];	/* DxDESB - Descriptor buffer */
+	u32 rsvd30[320];
+};
+
+/*
+ * Current top-level view of memory map is:
+ *
+ * 0x0000 - 0x0fff - CAAM Top-Level Control
+ * 0x1000 - 0x1fff - Job Ring 0
+ * 0x2000 - 0x2fff - Job Ring 1
+ * 0x3000 - 0x3fff - Job Ring 2
+ * 0x4000 - 0x4fff - Job Ring 3
+ * 0x5000 - 0x5fff - (unused)
+ * 0x6000 - 0x6fff - Assurance Controller
+ * 0x7000 - 0x7fff - Queue Interface
+ * 0x8000 - 0x8fff - DECO-CCB 0
+ * 0x9000 - 0x9fff - DECO-CCB 1
+ * 0xa000 - 0xafff - DECO-CCB 2
+ * 0xb000 - 0xbfff - DECO-CCB 3
+ * 0xc000 - 0xcfff - DECO-CCB 4
+ *
+ * caam_full describes the full register view of CAAM if useful,
+ * although many configurations may choose to implement parts of
+ * the register map separately, in differing privilege regions
+ */
+struct caam_full {
+	struct caam_ctrl __iomem ctrl;
+	struct caam_job_ring jr[4];
+	u64 rsvd[512];
+	struct caam_assurance assure;
+	struct caam_queue_if qi;
+	struct caam_deco *deco;
+};
+
+#endif /* REGS_H */
diff -druN linux-2.6.39-libre/drivers/crypto/Kconfig linux-3.0-rc7-libre/drivers/crypto/Kconfig
--- linux-2.6.39-libre/drivers/crypto/Kconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/crypto/Kconfig	2011-07-11 19:51:52.000000000 -0400
@@ -74,6 +74,8 @@
 	  + PCI-X Cryptographic Coprocessor (PCIXCC)
 	  + Crypto Express2 Coprocessor (CEX2C)
 	  + Crypto Express2 Accelerator (CEX2A)
+	  + Crypto Express3 Coprocessor (CEX3C)
+	  + Crypto Express3 Accelerator (CEX3A)
 
 config ZCRYPT_MONOLITHIC
 	bool "Monolithic zcrypt module"
@@ -91,6 +93,8 @@
 	  This is the s390 hardware accelerated implementation of the
 	  SHA-1 secure hash standard (FIPS 180-1/DFIPS 180-2).
 
+	  It is available as of z990.
+
 config CRYPTO_SHA256_S390
 	tristate "SHA256 digest algorithm"
 	depends on S390
@@ -99,8 +103,7 @@
 	  This is the s390 hardware accelerated implementation of the
 	  SHA256 secure hash standard (DFIPS 180-2).
 
-	  This version of SHA implements a 256 bit hash with 128 bits of
-	  security against collision attacks.
+	  It is available as of z9.
 
 config CRYPTO_SHA512_S390
 	tristate "SHA384 and SHA512 digest algorithm"
@@ -110,10 +113,7 @@
 	  This is the s390 hardware accelerated implementation of the
 	  SHA512 secure hash standard.
 
-	  This version of SHA implements a 512 bit hash with 256 bits of
-	  security against collision attacks. The code also includes SHA-384,
-	  a 384 bit hash with 192 bits of security against collision attacks.
-
+	  It is available as of z10.
 
 config CRYPTO_DES_S390
 	tristate "DES and Triple DES cipher algorithms"
@@ -121,9 +121,12 @@
 	select CRYPTO_ALGAPI
 	select CRYPTO_BLKCIPHER
 	help
-	  This us the s390 hardware accelerated implementation of the
+	  This is the s390 hardware accelerated implementation of the
 	  DES cipher algorithm (FIPS 46-2), and Triple DES EDE (FIPS 46-3).
 
+	  As of z990 the ECB and CBC mode are hardware accelerated.
+	  As of z196 the CTR mode is hardware accelerated.
+
 config CRYPTO_AES_S390
 	tristate "AES cipher algorithms"
 	depends on S390
@@ -131,20 +134,15 @@
 	select CRYPTO_BLKCIPHER
 	help
 	  This is the s390 hardware accelerated implementation of the
-	  AES cipher algorithms (FIPS-197). AES uses the Rijndael
-	  algorithm.
-
-	  Rijndael appears to be consistently a very good performer in
-	  both hardware and software across a wide range of computing
-	  environments regardless of its use in feedback or non-feedback
-	  modes. Its key setup time is excellent, and its key agility is
-	  good. Rijndael's very low memory requirements make it very well
-	  suited for restricted-space environments, in which it also
-	  demonstrates excellent performance. Rijndael's operations are
-	  among the easiest to defend against power and timing attacks.
+	  AES cipher algorithms (FIPS-197).
 
-	  On s390 the System z9-109 currently only supports the key size
-	  of 128 bit.
+	  As of z9 the ECB and CBC modes are hardware accelerated
+	  for 128 bit keys.
+	  As of z10 the ECB and CBC modes are hardware accelerated
+	  for all AES key sizes.
+	  As of z196 the CTR mode is hardware accelerated for all AES
+	  key sizes and XTS mode is hardware accelerated for 256 and
+	  512 bit keys.
 
 config S390_PRNG
 	tristate "Pseudo random number generator device driver"
@@ -154,8 +152,20 @@
 	  Select this option if you want to use the s390 pseudo random number
 	  generator. The PRNG is part of the cryptographic processor functions
 	  and uses triple-DES to generate secure random numbers like the
-	  ANSI X9.17 standard. The PRNG is usable via the char device
-	  /dev/prandom.
+	  ANSI X9.17 standard. User-space programs access the
+	  pseudo-random-number device through the char device /dev/prandom.
+
+	  It is available as of z9.
+
+config CRYPTO_GHASH_S390
+	tristate "GHASH digest algorithm"
+	depends on S390
+	select CRYPTO_HASH
+	help
+	  This is the s390 hardware accelerated implementation of the
+	  GHASH message digest algorithm for GCM (Galois/Counter Mode).
+
+	  It is available as of z196.
 
 config CRYPTO_DEV_MV_CESA
 	tristate "Marvell's Cryptographic Engine"
@@ -200,6 +210,8 @@
 	  Select this option if you want to enable the random number generator
 	  on the HIFN 795x crypto adapters.
 
+source drivers/crypto/caam/Kconfig
+
 config CRYPTO_DEV_TALITOS
 	tristate "Talitos Freescale Security Engine (SEC)"
 	select CRYPTO_ALGAPI
@@ -269,4 +281,15 @@
 
 	  Saying m here will build a module named pipcoxcell_crypto.
 
+config CRYPTO_DEV_S5P
+	tristate "Support for Samsung S5PV210 crypto accelerator"
+	depends on ARCH_S5PV210
+	select CRYPTO_AES
+	select CRYPTO_ALGAPI
+	select CRYPTO_BLKCIPHER
+	help
+	  This option allows you to have support for S5P crypto acceleration.
+	  Select this to offload Samsung S5PV210 or S5PC110 from AES
+	  algorithms execution.
+
 endif # CRYPTO_HW
diff -druN linux-2.6.39-libre/drivers/crypto/Makefile linux-3.0-rc7-libre/drivers/crypto/Makefile
--- linux-2.6.39-libre/drivers/crypto/Makefile	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/crypto/Makefile	2011-07-11 19:51:52.000000000 -0400
@@ -6,8 +6,10 @@
 obj-$(CONFIG_CRYPTO_DEV_HIFN_795X) += hifn_795x.o
 obj-$(CONFIG_CRYPTO_DEV_MV_CESA) += mv_cesa.o
 obj-$(CONFIG_CRYPTO_DEV_TALITOS) += talitos.o
+obj-$(CONFIG_CRYPTO_DEV_FSL_CAAM) += caam/
 obj-$(CONFIG_CRYPTO_DEV_IXP4XX) += ixp4xx_crypto.o
 obj-$(CONFIG_CRYPTO_DEV_PPC4XX) += amcc/
 obj-$(CONFIG_CRYPTO_DEV_OMAP_SHAM) += omap-sham.o
 obj-$(CONFIG_CRYPTO_DEV_OMAP_AES) += omap-aes.o
 obj-$(CONFIG_CRYPTO_DEV_PICOXCELL) += picoxcell_crypto.o
+obj-$(CONFIG_CRYPTO_DEV_S5P) += s5p-sss.o
diff -druN linux-2.6.39-libre/drivers/crypto/mv_cesa.c linux-3.0-rc7-libre/drivers/crypto/mv_cesa.c
--- linux-2.6.39-libre/drivers/crypto/mv_cesa.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/crypto/mv_cesa.c	2011-07-11 19:51:52.000000000 -0400
@@ -133,7 +133,6 @@
 	int extra_bytes;	/* unprocessed bytes in buffer */
 	enum hash_op op;
 	int count_add;
-	struct scatterlist dummysg;
 };
 
 static void compute_aes_dec_key(struct mv_ctx *ctx)
@@ -187,9 +186,9 @@
 {
 	int ret;
 	void *sbuf;
-	int copied = 0;
+	int copy_len;
 
-	while (1) {
+	while (len) {
 		if (!p->sg_src_left) {
 			ret = sg_miter_next(&p->src_sg_it);
 			BUG_ON(!ret);
@@ -199,19 +198,14 @@
 
 		sbuf = p->src_sg_it.addr + p->src_start;
 
-		if (p->sg_src_left <= len - copied) {
-			memcpy(dbuf + copied, sbuf, p->sg_src_left);
-			copied += p->sg_src_left;
-			p->sg_src_left = 0;
-			if (copied >= len)
-				break;
-		} else {
-			int copy_len = len - copied;
-			memcpy(dbuf + copied, sbuf, copy_len);
-			p->src_start += copy_len;
-			p->sg_src_left -= copy_len;
-			break;
-		}
+		copy_len = min(p->sg_src_left, len);
+		memcpy(dbuf, sbuf, copy_len);
+
+		p->src_start += copy_len;
+		p->sg_src_left -= copy_len;
+
+		len -= copy_len;
+		dbuf += copy_len;
 	}
 }
 
@@ -275,7 +269,6 @@
 	memcpy(cpg->sram + SRAM_CONFIG, &op,
 			sizeof(struct sec_accel_config));
 
-	writel(SRAM_CONFIG, cpg->reg + SEC_ACCEL_DESC_P0);
 	/* GO */
 	writel(SEC_CMD_EN_SEC_ACCL0, cpg->reg + SEC_ACCEL_CMD);
 
@@ -302,6 +295,7 @@
 static void mv_process_hash_current(int first_block)
 {
 	struct ahash_request *req = ahash_request_cast(cpg->cur_req);
+	const struct mv_tfm_hash_ctx *tfm_ctx = crypto_tfm_ctx(req->base.tfm);
 	struct mv_req_hash_ctx *req_ctx = ahash_request_ctx(req);
 	struct req_progress *p = &cpg->p;
 	struct sec_accel_config op = { 0 };
@@ -314,6 +308,8 @@
 		break;
 	case COP_HMAC_SHA1:
 		op.config = CFG_OP_MAC_ONLY | CFG_MACM_HMAC_SHA1;
+		memcpy(cpg->sram + SRAM_HMAC_IV_IN,
+				tfm_ctx->ivs, sizeof(tfm_ctx->ivs));
 		break;
 	}
 
@@ -345,11 +341,16 @@
 			op.config |= CFG_LAST_FRAG;
 		else
 			op.config |= CFG_MID_FRAG;
+
+		writel(req_ctx->state[0], cpg->reg + DIGEST_INITIAL_VAL_A);
+		writel(req_ctx->state[1], cpg->reg + DIGEST_INITIAL_VAL_B);
+		writel(req_ctx->state[2], cpg->reg + DIGEST_INITIAL_VAL_C);
+		writel(req_ctx->state[3], cpg->reg + DIGEST_INITIAL_VAL_D);
+		writel(req_ctx->state[4], cpg->reg + DIGEST_INITIAL_VAL_E);
 	}
 
 	memcpy(cpg->sram + SRAM_CONFIG, &op, sizeof(struct sec_accel_config));
 
-	writel(SRAM_CONFIG, cpg->reg + SEC_ACCEL_DESC_P0);
 	/* GO */
 	writel(SEC_CMD_EN_SEC_ACCL0, cpg->reg + SEC_ACCEL_CMD);
 
@@ -409,12 +410,6 @@
 		copy_src_to_buf(&cpg->p, ctx->buffer, ctx->extra_bytes);
 	sg_miter_stop(&cpg->p.src_sg_it);
 
-	ctx->state[0] = readl(cpg->reg + DIGEST_INITIAL_VAL_A);
-	ctx->state[1] = readl(cpg->reg + DIGEST_INITIAL_VAL_B);
-	ctx->state[2] = readl(cpg->reg + DIGEST_INITIAL_VAL_C);
-	ctx->state[3] = readl(cpg->reg + DIGEST_INITIAL_VAL_D);
-	ctx->state[4] = readl(cpg->reg + DIGEST_INITIAL_VAL_E);
-
 	if (likely(ctx->last_chunk)) {
 		if (likely(ctx->count <= MAX_HW_HASH_SIZE)) {
 			memcpy(req->result, cpg->sram + SRAM_DIGEST_BUF,
@@ -422,6 +417,12 @@
 						       (req)));
 		} else
 			mv_hash_final_fallback(req);
+	} else {
+		ctx->state[0] = readl(cpg->reg + DIGEST_INITIAL_VAL_A);
+		ctx->state[1] = readl(cpg->reg + DIGEST_INITIAL_VAL_B);
+		ctx->state[2] = readl(cpg->reg + DIGEST_INITIAL_VAL_C);
+		ctx->state[3] = readl(cpg->reg + DIGEST_INITIAL_VAL_D);
+		ctx->state[4] = readl(cpg->reg + DIGEST_INITIAL_VAL_E);
 	}
 }
 
@@ -480,7 +481,7 @@
 	int i = 0;
 	size_t cur_len;
 
-	while (1) {
+	while (sl) {
 		cur_len = sl[i].length;
 		++i;
 		if (total_bytes > cur_len)
@@ -517,29 +518,12 @@
 {
 	struct req_progress *p = &cpg->p;
 	struct mv_req_hash_ctx *ctx = ahash_request_ctx(req);
-	const struct mv_tfm_hash_ctx *tfm_ctx = crypto_tfm_ctx(req->base.tfm);
 	int num_sgs, hw_bytes, old_extra_bytes, rc;
 	cpg->cur_req = &req->base;
 	memset(p, 0, sizeof(struct req_progress));
 	hw_bytes = req->nbytes + ctx->extra_bytes;
 	old_extra_bytes = ctx->extra_bytes;
 
-	if (unlikely(ctx->extra_bytes)) {
-		memcpy(cpg->sram + SRAM_DATA_IN_START, ctx->buffer,
-		       ctx->extra_bytes);
-		p->crypt_len = ctx->extra_bytes;
-	}
-
-	memcpy(cpg->sram + SRAM_HMAC_IV_IN, tfm_ctx->ivs, sizeof(tfm_ctx->ivs));
-
-	if (unlikely(!ctx->first_hash)) {
-		writel(ctx->state[0], cpg->reg + DIGEST_INITIAL_VAL_A);
-		writel(ctx->state[1], cpg->reg + DIGEST_INITIAL_VAL_B);
-		writel(ctx->state[2], cpg->reg + DIGEST_INITIAL_VAL_C);
-		writel(ctx->state[3], cpg->reg + DIGEST_INITIAL_VAL_D);
-		writel(ctx->state[4], cpg->reg + DIGEST_INITIAL_VAL_E);
-	}
-
 	ctx->extra_bytes = hw_bytes % SHA1_BLOCK_SIZE;
 	if (ctx->extra_bytes != 0
 	    && (!ctx->last_chunk || ctx->count > MAX_HW_HASH_SIZE))
@@ -555,6 +539,12 @@
 		p->complete = mv_hash_algo_completion;
 		p->process = mv_process_hash_current;
 
+		if (unlikely(old_extra_bytes)) {
+			memcpy(cpg->sram + SRAM_DATA_IN_START, ctx->buffer,
+			       old_extra_bytes);
+			p->crypt_len = old_extra_bytes;
+		}
+
 		mv_process_hash_current(1);
 	} else {
 		copy_src_to_buf(p, ctx->buffer + old_extra_bytes,
@@ -603,9 +593,7 @@
 			if (async_req->tfm->__crt_alg->cra_type !=
 			    &crypto_ahash_type) {
 				struct ablkcipher_request *req =
-				    container_of(async_req,
-						 struct ablkcipher_request,
-						 base);
+				    ablkcipher_request_cast(async_req);
 				mv_start_new_crypt_req(req);
 			} else {
 				struct ahash_request *req =
@@ -722,19 +710,13 @@
 static int mv_hash_final(struct ahash_request *req)
 {
 	struct mv_req_hash_ctx *ctx = ahash_request_ctx(req);
-	/* dummy buffer of 4 bytes */
-	sg_init_one(&ctx->dummysg, ctx->buffer, 4);
-	/* I think I'm allowed to do that... */
-	ahash_request_set_crypt(req, &ctx->dummysg, req->result, 0);
+
 	mv_update_hash_req_ctx(ctx, 1, 0);
 	return mv_handle_req(&req->base);
 }
 
 static int mv_hash_finup(struct ahash_request *req)
 {
-	if (!req->nbytes)
-		return mv_hash_final(req);
-
 	mv_update_hash_req_ctx(ahash_request_ctx(req), 1, req->nbytes);
 	return mv_handle_req(&req->base);
 }
@@ -1065,14 +1047,21 @@
 
 	writel(SEC_INT_ACCEL0_DONE, cpg->reg + SEC_ACCEL_INT_MASK);
 	writel(SEC_CFG_STOP_DIG_ERR, cpg->reg + SEC_ACCEL_CFG);
+	writel(SRAM_CONFIG, cpg->reg + SEC_ACCEL_DESC_P0);
 
 	ret = crypto_register_alg(&mv_aes_alg_ecb);
-	if (ret)
+	if (ret) {
+		printk(KERN_WARNING MV_CESA
+		       "Could not register aes-ecb driver\n");
 		goto err_irq;
+	}
 
 	ret = crypto_register_alg(&mv_aes_alg_cbc);
-	if (ret)
+	if (ret) {
+		printk(KERN_WARNING MV_CESA
+		       "Could not register aes-cbc driver\n");
 		goto err_unreg_ecb;
+	}
 
 	ret = crypto_register_ahash(&mv_sha1_alg);
 	if (ret == 0)
diff -druN linux-2.6.39-libre/drivers/crypto/omap-sham.c linux-3.0-rc7-libre/drivers/crypto/omap-sham.c
--- linux-2.6.39-libre/drivers/crypto/omap-sham.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/crypto/omap-sham.c	2011-07-11 19:51:52.000000000 -0400
@@ -78,7 +78,6 @@
 #define FLAGS_SHA1		0x0010
 #define FLAGS_DMA_ACTIVE	0x0020
 #define FLAGS_OUTPUT_READY	0x0040
-#define FLAGS_CLEAN		0x0080
 #define FLAGS_INIT		0x0100
 #define FLAGS_CPU		0x0200
 #define FLAGS_HMAC		0x0400
@@ -511,26 +510,6 @@
 	return 0;
 }
 
-static void omap_sham_cleanup(struct ahash_request *req)
-{
-	struct omap_sham_reqctx *ctx = ahash_request_ctx(req);
-	struct omap_sham_dev *dd = ctx->dd;
-	unsigned long flags;
-
-	spin_lock_irqsave(&dd->lock, flags);
-	if (ctx->flags & FLAGS_CLEAN) {
-		spin_unlock_irqrestore(&dd->lock, flags);
-		return;
-	}
-	ctx->flags |= FLAGS_CLEAN;
-	spin_unlock_irqrestore(&dd->lock, flags);
-
-	if (ctx->digcnt)
-		omap_sham_copy_ready_hash(req);
-
-	dev_dbg(dd->dev, "digcnt: %d, bufcnt: %d\n", ctx->digcnt, ctx->bufcnt);
-}
-
 static int omap_sham_init(struct ahash_request *req)
 {
 	struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
@@ -618,9 +597,8 @@
 	return err;
 }
 
-static int omap_sham_finish_req_hmac(struct ahash_request *req)
+static int omap_sham_finish_hmac(struct ahash_request *req)
 {
-	struct omap_sham_reqctx *ctx = ahash_request_ctx(req);
 	struct omap_sham_ctx *tctx = crypto_tfm_ctx(req->base.tfm);
 	struct omap_sham_hmac_ctx *bctx = tctx->base;
 	int bs = crypto_shash_blocksize(bctx->shash);
@@ -635,7 +613,24 @@
 
 	return crypto_shash_init(&desc.shash) ?:
 	       crypto_shash_update(&desc.shash, bctx->opad, bs) ?:
-	       crypto_shash_finup(&desc.shash, ctx->digest, ds, ctx->digest);
+	       crypto_shash_finup(&desc.shash, req->result, ds, req->result);
+}
+
+static int omap_sham_finish(struct ahash_request *req)
+{
+	struct omap_sham_reqctx *ctx = ahash_request_ctx(req);
+	struct omap_sham_dev *dd = ctx->dd;
+	int err = 0;
+
+	if (ctx->digcnt) {
+		omap_sham_copy_ready_hash(req);
+		if (ctx->flags & FLAGS_HMAC)
+			err = omap_sham_finish_hmac(req);
+	}
+
+	dev_dbg(dd->dev, "digcnt: %d, bufcnt: %d\n", ctx->digcnt, ctx->bufcnt);
+
+	return err;
 }
 
 static void omap_sham_finish_req(struct ahash_request *req, int err)
@@ -645,15 +640,12 @@
 
 	if (!err) {
 		omap_sham_copy_hash(ctx->dd->req, 1);
-		if (ctx->flags & FLAGS_HMAC)
-			err = omap_sham_finish_req_hmac(req);
+		if (ctx->flags & FLAGS_FINAL)
+			err = omap_sham_finish(req);
 	} else {
 		ctx->flags |= FLAGS_ERROR;
 	}
 
-	if ((ctx->flags & FLAGS_FINAL) || err)
-		omap_sham_cleanup(req);
-
 	clk_disable(dd->iclk);
 	dd->flags &= ~FLAGS_BUSY;
 
@@ -809,22 +801,21 @@
 static int omap_sham_final(struct ahash_request *req)
 {
 	struct omap_sham_reqctx *ctx = ahash_request_ctx(req);
-	int err = 0;
 
 	ctx->flags |= FLAGS_FINUP;
 
-	if (!(ctx->flags & FLAGS_ERROR)) {
-		/* OMAP HW accel works only with buffers >= 9 */
-		/* HMAC is always >= 9 because of ipad */
-		if ((ctx->digcnt + ctx->bufcnt) < 9)
-			err = omap_sham_final_shash(req);
-		else if (ctx->bufcnt)
-			return omap_sham_enqueue(req, OP_FINAL);
-	}
+	if (ctx->flags & FLAGS_ERROR)
+		return 0; /* uncompleted hash is not needed */
 
-	omap_sham_cleanup(req);
+	/* OMAP HW accel works only with buffers >= 9 */
+	/* HMAC is always >= 9 because ipad == block size */
+	if ((ctx->digcnt + ctx->bufcnt) < 9)
+		return omap_sham_final_shash(req);
+	else if (ctx->bufcnt)
+		return omap_sham_enqueue(req, OP_FINAL);
 
-	return err;
+	/* copy ready hash (+ finalize hmac) */
+	return omap_sham_finish(req);
 }
 
 static int omap_sham_finup(struct ahash_request *req)
@@ -835,7 +826,7 @@
 	ctx->flags |= FLAGS_FINUP;
 
 	err1 = omap_sham_update(req);
-	if (err1 == -EINPROGRESS)
+	if (err1 == -EINPROGRESS || err1 == -EBUSY)
 		return err1;
 	/*
 	 * final() has to be always called to cleanup resources
@@ -890,8 +881,6 @@
 	struct omap_sham_ctx *tctx = crypto_tfm_ctx(tfm);
 	const char *alg_name = crypto_tfm_alg_name(tfm);
 
-	pr_info("enter\n");
-
 	/* Allocate a fallback and abort if it failed. */
 	tctx->fallback = crypto_alloc_shash(alg_name, 0,
 					    CRYPTO_ALG_NEED_FALLBACK);
@@ -1297,7 +1286,8 @@
 	pr_info("loading %s driver\n", "omap-sham");
 
 	if (!cpu_class_is_omap2() ||
-		omap_type() != OMAP2_DEVICE_TYPE_SEC) {
+		(omap_type() != OMAP2_DEVICE_TYPE_SEC &&
+			omap_type() != OMAP2_DEVICE_TYPE_EMU)) {
 		pr_err("Unsupported cpu\n");
 		return -ENODEV;
 	}
diff -druN linux-2.6.39-libre/drivers/crypto/padlock-sha.c linux-3.0-rc7-libre/drivers/crypto/padlock-sha.c
--- linux-2.6.39-libre/drivers/crypto/padlock-sha.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/crypto/padlock-sha.c	2011-07-11 19:51:52.000000000 -0400
@@ -288,9 +288,250 @@
 	}
 };
 
+/* Add two shash_alg instance for hardware-implemented *
+* multiple-parts hash supported by VIA Nano Processor.*/
+static int padlock_sha1_init_nano(struct shash_desc *desc)
+{
+	struct sha1_state *sctx = shash_desc_ctx(desc);
+
+	*sctx = (struct sha1_state){
+		.state = { SHA1_H0, SHA1_H1, SHA1_H2, SHA1_H3, SHA1_H4 },
+	};
+
+	return 0;
+}
+
+static int padlock_sha1_update_nano(struct shash_desc *desc,
+			const u8 *data,	unsigned int len)
+{
+	struct sha1_state *sctx = shash_desc_ctx(desc);
+	unsigned int partial, done;
+	const u8 *src;
+	/*The PHE require the out buffer must 128 bytes and 16-bytes aligned*/
+	u8 buf[128 + PADLOCK_ALIGNMENT - STACK_ALIGN] __attribute__
+		((aligned(STACK_ALIGN)));
+	u8 *dst = PTR_ALIGN(&buf[0], PADLOCK_ALIGNMENT);
+	int ts_state;
+
+	partial = sctx->count & 0x3f;
+	sctx->count += len;
+	done = 0;
+	src = data;
+	memcpy(dst, (u8 *)(sctx->state), SHA1_DIGEST_SIZE);
+
+	if ((partial + len) >= SHA1_BLOCK_SIZE) {
+
+		/* Append the bytes in state's buffer to a block to handle */
+		if (partial) {
+			done = -partial;
+			memcpy(sctx->buffer + partial, data,
+				done + SHA1_BLOCK_SIZE);
+			src = sctx->buffer;
+			ts_state = irq_ts_save();
+			asm volatile (".byte 0xf3,0x0f,0xa6,0xc8"
+			: "+S"(src), "+D"(dst) \
+			: "a"((long)-1), "c"((unsigned long)1));
+			irq_ts_restore(ts_state);
+			done += SHA1_BLOCK_SIZE;
+			src = data + done;
+		}
+
+		/* Process the left bytes from the input data */
+		if (len - done >= SHA1_BLOCK_SIZE) {
+			ts_state = irq_ts_save();
+			asm volatile (".byte 0xf3,0x0f,0xa6,0xc8"
+			: "+S"(src), "+D"(dst)
+			: "a"((long)-1),
+			"c"((unsigned long)((len - done) / SHA1_BLOCK_SIZE)));
+			irq_ts_restore(ts_state);
+			done += ((len - done) - (len - done) % SHA1_BLOCK_SIZE);
+			src = data + done;
+		}
+		partial = 0;
+	}
+	memcpy((u8 *)(sctx->state), dst, SHA1_DIGEST_SIZE);
+	memcpy(sctx->buffer + partial, src, len - done);
+
+	return 0;
+}
+
+static int padlock_sha1_final_nano(struct shash_desc *desc, u8 *out)
+{
+	struct sha1_state *state = (struct sha1_state *)shash_desc_ctx(desc);
+	unsigned int partial, padlen;
+	__be64 bits;
+	static const u8 padding[64] = { 0x80, };
+
+	bits = cpu_to_be64(state->count << 3);
+
+	/* Pad out to 56 mod 64 */
+	partial = state->count & 0x3f;
+	padlen = (partial < 56) ? (56 - partial) : ((64+56) - partial);
+	padlock_sha1_update_nano(desc, padding, padlen);
+
+	/* Append length field bytes */
+	padlock_sha1_update_nano(desc, (const u8 *)&bits, sizeof(bits));
+
+	/* Swap to output */
+	padlock_output_block((uint32_t *)(state->state), (uint32_t *)out, 5);
+
+	return 0;
+}
+
+static int padlock_sha256_init_nano(struct shash_desc *desc)
+{
+	struct sha256_state *sctx = shash_desc_ctx(desc);
+
+	*sctx = (struct sha256_state){
+		.state = { SHA256_H0, SHA256_H1, SHA256_H2, SHA256_H3, \
+				SHA256_H4, SHA256_H5, SHA256_H6, SHA256_H7},
+	};
+
+	return 0;
+}
+
+static int padlock_sha256_update_nano(struct shash_desc *desc, const u8 *data,
+			  unsigned int len)
+{
+	struct sha256_state *sctx = shash_desc_ctx(desc);
+	unsigned int partial, done;
+	const u8 *src;
+	/*The PHE require the out buffer must 128 bytes and 16-bytes aligned*/
+	u8 buf[128 + PADLOCK_ALIGNMENT - STACK_ALIGN] __attribute__
+		((aligned(STACK_ALIGN)));
+	u8 *dst = PTR_ALIGN(&buf[0], PADLOCK_ALIGNMENT);
+	int ts_state;
+
+	partial = sctx->count & 0x3f;
+	sctx->count += len;
+	done = 0;
+	src = data;
+	memcpy(dst, (u8 *)(sctx->state), SHA256_DIGEST_SIZE);
+
+	if ((partial + len) >= SHA256_BLOCK_SIZE) {
+
+		/* Append the bytes in state's buffer to a block to handle */
+		if (partial) {
+			done = -partial;
+			memcpy(sctx->buf + partial, data,
+				done + SHA256_BLOCK_SIZE);
+			src = sctx->buf;
+			ts_state = irq_ts_save();
+			asm volatile (".byte 0xf3,0x0f,0xa6,0xd0"
+			: "+S"(src), "+D"(dst)
+			: "a"((long)-1), "c"((unsigned long)1));
+			irq_ts_restore(ts_state);
+			done += SHA256_BLOCK_SIZE;
+			src = data + done;
+		}
+
+		/* Process the left bytes from input data*/
+		if (len - done >= SHA256_BLOCK_SIZE) {
+			ts_state = irq_ts_save();
+			asm volatile (".byte 0xf3,0x0f,0xa6,0xd0"
+			: "+S"(src), "+D"(dst)
+			: "a"((long)-1),
+			"c"((unsigned long)((len - done) / 64)));
+			irq_ts_restore(ts_state);
+			done += ((len - done) - (len - done) % 64);
+			src = data + done;
+		}
+		partial = 0;
+	}
+	memcpy((u8 *)(sctx->state), dst, SHA256_DIGEST_SIZE);
+	memcpy(sctx->buf + partial, src, len - done);
+
+	return 0;
+}
+
+static int padlock_sha256_final_nano(struct shash_desc *desc, u8 *out)
+{
+	struct sha256_state *state =
+		(struct sha256_state *)shash_desc_ctx(desc);
+	unsigned int partial, padlen;
+	__be64 bits;
+	static const u8 padding[64] = { 0x80, };
+
+	bits = cpu_to_be64(state->count << 3);
+
+	/* Pad out to 56 mod 64 */
+	partial = state->count & 0x3f;
+	padlen = (partial < 56) ? (56 - partial) : ((64+56) - partial);
+	padlock_sha256_update_nano(desc, padding, padlen);
+
+	/* Append length field bytes */
+	padlock_sha256_update_nano(desc, (const u8 *)&bits, sizeof(bits));
+
+	/* Swap to output */
+	padlock_output_block((uint32_t *)(state->state), (uint32_t *)out, 8);
+
+	return 0;
+}
+
+static int padlock_sha_export_nano(struct shash_desc *desc,
+				void *out)
+{
+	int statesize = crypto_shash_statesize(desc->tfm);
+	void *sctx = shash_desc_ctx(desc);
+
+	memcpy(out, sctx, statesize);
+	return 0;
+}
+
+static int padlock_sha_import_nano(struct shash_desc *desc,
+				const void *in)
+{
+	int statesize = crypto_shash_statesize(desc->tfm);
+	void *sctx = shash_desc_ctx(desc);
+
+	memcpy(sctx, in, statesize);
+	return 0;
+}
+
+static struct shash_alg sha1_alg_nano = {
+	.digestsize	=	SHA1_DIGEST_SIZE,
+	.init		=	padlock_sha1_init_nano,
+	.update		=	padlock_sha1_update_nano,
+	.final		=	padlock_sha1_final_nano,
+	.export		=	padlock_sha_export_nano,
+	.import		=	padlock_sha_import_nano,
+	.descsize	=	sizeof(struct sha1_state),
+	.statesize	=	sizeof(struct sha1_state),
+	.base		=	{
+		.cra_name		=	"sha1",
+		.cra_driver_name	=	"sha1-padlock-nano",
+		.cra_priority		=	PADLOCK_CRA_PRIORITY,
+		.cra_flags		=	CRYPTO_ALG_TYPE_SHASH,
+		.cra_blocksize		=	SHA1_BLOCK_SIZE,
+		.cra_module		=	THIS_MODULE,
+	}
+};
+
+static struct shash_alg sha256_alg_nano = {
+	.digestsize	=	SHA256_DIGEST_SIZE,
+	.init		=	padlock_sha256_init_nano,
+	.update		=	padlock_sha256_update_nano,
+	.final		=	padlock_sha256_final_nano,
+	.export		=	padlock_sha_export_nano,
+	.import		=	padlock_sha_import_nano,
+	.descsize	=	sizeof(struct sha256_state),
+	.statesize	=	sizeof(struct sha256_state),
+	.base		=	{
+		.cra_name		=	"sha256",
+		.cra_driver_name	=	"sha256-padlock-nano",
+		.cra_priority		=	PADLOCK_CRA_PRIORITY,
+		.cra_flags		=	CRYPTO_ALG_TYPE_SHASH,
+		.cra_blocksize		=	SHA256_BLOCK_SIZE,
+		.cra_module		=	THIS_MODULE,
+	}
+};
+
 static int __init padlock_init(void)
 {
 	int rc = -ENODEV;
+	struct cpuinfo_x86 *c = &cpu_data(0);
+	struct shash_alg *sha1;
+	struct shash_alg *sha256;
 
 	if (!cpu_has_phe) {
 		printk(KERN_NOTICE PFX "VIA PadLock Hash Engine not detected.\n");
@@ -302,11 +543,21 @@
 		return -ENODEV;
 	}
 
-	rc = crypto_register_shash(&sha1_alg);
+	/* Register the newly added algorithm module if on *
+	* VIA Nano processor, or else just do as before */
+	if (c->x86_model < 0x0f) {
+		sha1 = &sha1_alg;
+		sha256 = &sha256_alg;
+	} else {
+		sha1 = &sha1_alg_nano;
+		sha256 = &sha256_alg_nano;
+	}
+
+	rc = crypto_register_shash(sha1);
 	if (rc)
 		goto out;
 
-	rc = crypto_register_shash(&sha256_alg);
+	rc = crypto_register_shash(sha256);
 	if (rc)
 		goto out_unreg1;
 
@@ -315,7 +566,8 @@
 	return 0;
 
 out_unreg1:
-	crypto_unregister_shash(&sha1_alg);
+	crypto_unregister_shash(sha1);
+
 out:
 	printk(KERN_ERR PFX "VIA PadLock SHA1/SHA256 initialization failed.\n");
 	return rc;
@@ -323,8 +575,15 @@
 
 static void __exit padlock_fini(void)
 {
-	crypto_unregister_shash(&sha1_alg);
-	crypto_unregister_shash(&sha256_alg);
+	struct cpuinfo_x86 *c = &cpu_data(0);
+
+	if (c->x86_model >= 0x0f) {
+		crypto_unregister_shash(&sha1_alg_nano);
+		crypto_unregister_shash(&sha256_alg_nano);
+	} else {
+		crypto_unregister_shash(&sha1_alg);
+		crypto_unregister_shash(&sha256_alg);
+	}
 }
 
 module_init(padlock_init);
diff -druN linux-2.6.39-libre/drivers/crypto/picoxcell_crypto.c linux-3.0-rc7-libre/drivers/crypto/picoxcell_crypto.c
--- linux-2.6.39-libre/drivers/crypto/picoxcell_crypto.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/crypto/picoxcell_crypto.c	2011-07-11 19:51:52.000000000 -0400
@@ -176,6 +176,8 @@
 	u8				salt[AES_BLOCK_SIZE];
 };
 
+static int spacc_ablk_submit(struct spacc_req *req);
+
 static inline struct spacc_alg *to_spacc_alg(struct crypto_alg *alg)
 {
 	return alg ? container_of(alg, struct spacc_alg, alg) : NULL;
@@ -666,6 +668,24 @@
 	return -EINPROGRESS;
 }
 
+static int spacc_req_submit(struct spacc_req *req);
+
+static void spacc_push(struct spacc_engine *engine)
+{
+	struct spacc_req *req;
+
+	while (!list_empty(&engine->pending) &&
+	       engine->in_flight + 1 <= engine->fifo_sz) {
+
+		++engine->in_flight;
+		req = list_first_entry(&engine->pending, struct spacc_req,
+				       list);
+		list_move_tail(&req->list, &engine->in_progress);
+
+		req->result = spacc_req_submit(req);
+	}
+}
+
 /*
  * Setup an AEAD request for processing. This will configure the engine, load
  * the context and then start the packet processing.
@@ -698,7 +718,8 @@
 
 	err = -EINPROGRESS;
 	spin_lock_irqsave(&engine->hw_lock, flags);
-	if (unlikely(spacc_fifo_cmd_full(engine))) {
+	if (unlikely(spacc_fifo_cmd_full(engine)) ||
+	    engine->in_flight + 1 > engine->fifo_sz) {
 		if (!(req->base.flags & CRYPTO_TFM_REQ_MAY_BACKLOG)) {
 			err = -EBUSY;
 			spin_unlock_irqrestore(&engine->hw_lock, flags);
@@ -706,9 +727,8 @@
 		}
 		list_add_tail(&dev_req->list, &engine->pending);
 	} else {
-		++engine->in_flight;
-		list_add_tail(&dev_req->list, &engine->in_progress);
-		spacc_aead_submit(dev_req);
+		list_add_tail(&dev_req->list, &engine->pending);
+		spacc_push(engine);
 	}
 	spin_unlock_irqrestore(&engine->hw_lock, flags);
 
@@ -1041,7 +1061,8 @@
 	 * we either stick it on the end of a pending list if we can backlog,
 	 * or bailout with an error if not.
 	 */
-	if (unlikely(spacc_fifo_cmd_full(engine))) {
+	if (unlikely(spacc_fifo_cmd_full(engine)) ||
+	    engine->in_flight + 1 > engine->fifo_sz) {
 		if (!(req->base.flags & CRYPTO_TFM_REQ_MAY_BACKLOG)) {
 			err = -EBUSY;
 			spin_unlock_irqrestore(&engine->hw_lock, flags);
@@ -1049,9 +1070,8 @@
 		}
 		list_add_tail(&dev_req->list, &engine->pending);
 	} else {
-		++engine->in_flight;
-		list_add_tail(&dev_req->list, &engine->in_progress);
-		spacc_ablk_submit(dev_req);
+		list_add_tail(&dev_req->list, &engine->pending);
+		spacc_push(engine);
 	}
 	spin_unlock_irqrestore(&engine->hw_lock, flags);
 
@@ -1139,6 +1159,7 @@
 		req = list_first_entry(&engine->in_progress, struct spacc_req,
 				       list);
 		list_move_tail(&req->list, &engine->completed);
+		--engine->in_flight;
 
 		/* POP the status register. */
 		writel(~0, engine->regs + SPA_STAT_POP_REG_OFFSET);
@@ -1208,36 +1229,21 @@
 	struct spacc_engine *engine = (struct spacc_engine *)data;
 	struct spacc_req *req, *tmp;
 	unsigned long flags;
-	int num_removed = 0;
 	LIST_HEAD(completed);
 
 	spin_lock_irqsave(&engine->hw_lock, flags);
+
 	list_splice_init(&engine->completed, &completed);
+	spacc_push(engine);
+	if (engine->in_flight)
+		mod_timer(&engine->packet_timeout, jiffies + PACKET_TIMEOUT);
+
 	spin_unlock_irqrestore(&engine->hw_lock, flags);
 
 	list_for_each_entry_safe(req, tmp, &completed, list) {
-		++num_removed;
 		req->complete(req);
+		list_del(&req->list);
 	}
-
-	/* Try and fill the engine back up again. */
-	spin_lock_irqsave(&engine->hw_lock, flags);
-
-	engine->in_flight -= num_removed;
-
-	list_for_each_entry_safe(req, tmp, &engine->pending, list) {
-		if (spacc_fifo_cmd_full(engine))
-			break;
-
-		list_move_tail(&req->list, &engine->in_progress);
-		++engine->in_flight;
-		req->result = spacc_req_submit(req);
-	}
-
-	if (engine->in_flight)
-		mod_timer(&engine->packet_timeout, jiffies + PACKET_TIMEOUT);
-
-	spin_unlock_irqrestore(&engine->hw_lock, flags);
 }
 
 #ifdef CONFIG_PM
diff -druN linux-2.6.39-libre/drivers/crypto/s5p-sss.c linux-3.0-rc7-libre/drivers/crypto/s5p-sss.c
--- linux-2.6.39-libre/drivers/crypto/s5p-sss.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/crypto/s5p-sss.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,701 @@
+/*
+ * Cryptographic API.
+ *
+ * Support for Samsung S5PV210 HW acceleration.
+ *
+ * Copyright (C) 2011 NetUP 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/delay.h>
+#include <linux/err.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/clk.h>
+#include <linux/platform_device.h>
+#include <linux/scatterlist.h>
+#include <linux/dma-mapping.h>
+#include <linux/io.h>
+#include <linux/crypto.h>
+#include <linux/interrupt.h>
+
+#include <crypto/algapi.h>
+#include <crypto/aes.h>
+#include <crypto/ctr.h>
+
+#include <plat/cpu.h>
+#include <plat/dma.h>
+
+#define _SBF(s, v)                      ((v) << (s))
+#define _BIT(b)                         _SBF(b, 1)
+
+/* Feed control registers */
+#define SSS_REG_FCINTSTAT               0x0000
+#define SSS_FCINTSTAT_BRDMAINT          _BIT(3)
+#define SSS_FCINTSTAT_BTDMAINT          _BIT(2)
+#define SSS_FCINTSTAT_HRDMAINT          _BIT(1)
+#define SSS_FCINTSTAT_PKDMAINT          _BIT(0)
+
+#define SSS_REG_FCINTENSET              0x0004
+#define SSS_FCINTENSET_BRDMAINTENSET    _BIT(3)
+#define SSS_FCINTENSET_BTDMAINTENSET    _BIT(2)
+#define SSS_FCINTENSET_HRDMAINTENSET    _BIT(1)
+#define SSS_FCINTENSET_PKDMAINTENSET    _BIT(0)
+
+#define SSS_REG_FCINTENCLR              0x0008
+#define SSS_FCINTENCLR_BRDMAINTENCLR    _BIT(3)
+#define SSS_FCINTENCLR_BTDMAINTENCLR    _BIT(2)
+#define SSS_FCINTENCLR_HRDMAINTENCLR    _BIT(1)
+#define SSS_FCINTENCLR_PKDMAINTENCLR    _BIT(0)
+
+#define SSS_REG_FCINTPEND               0x000C
+#define SSS_FCINTPEND_BRDMAINTP         _BIT(3)
+#define SSS_FCINTPEND_BTDMAINTP         _BIT(2)
+#define SSS_FCINTPEND_HRDMAINTP         _BIT(1)
+#define SSS_FCINTPEND_PKDMAINTP         _BIT(0)
+
+#define SSS_REG_FCFIFOSTAT              0x0010
+#define SSS_FCFIFOSTAT_BRFIFOFUL        _BIT(7)
+#define SSS_FCFIFOSTAT_BRFIFOEMP        _BIT(6)
+#define SSS_FCFIFOSTAT_BTFIFOFUL        _BIT(5)
+#define SSS_FCFIFOSTAT_BTFIFOEMP        _BIT(4)
+#define SSS_FCFIFOSTAT_HRFIFOFUL        _BIT(3)
+#define SSS_FCFIFOSTAT_HRFIFOEMP        _BIT(2)
+#define SSS_FCFIFOSTAT_PKFIFOFUL        _BIT(1)
+#define SSS_FCFIFOSTAT_PKFIFOEMP        _BIT(0)
+
+#define SSS_REG_FCFIFOCTRL              0x0014
+#define SSS_FCFIFOCTRL_DESSEL           _BIT(2)
+#define SSS_HASHIN_INDEPENDENT          _SBF(0, 0x00)
+#define SSS_HASHIN_CIPHER_INPUT         _SBF(0, 0x01)
+#define SSS_HASHIN_CIPHER_OUTPUT        _SBF(0, 0x02)
+
+#define SSS_REG_FCBRDMAS                0x0020
+#define SSS_REG_FCBRDMAL                0x0024
+#define SSS_REG_FCBRDMAC                0x0028
+#define SSS_FCBRDMAC_BYTESWAP           _BIT(1)
+#define SSS_FCBRDMAC_FLUSH              _BIT(0)
+
+#define SSS_REG_FCBTDMAS                0x0030
+#define SSS_REG_FCBTDMAL                0x0034
+#define SSS_REG_FCBTDMAC                0x0038
+#define SSS_FCBTDMAC_BYTESWAP           _BIT(1)
+#define SSS_FCBTDMAC_FLUSH              _BIT(0)
+
+#define SSS_REG_FCHRDMAS                0x0040
+#define SSS_REG_FCHRDMAL                0x0044
+#define SSS_REG_FCHRDMAC                0x0048
+#define SSS_FCHRDMAC_BYTESWAP           _BIT(1)
+#define SSS_FCHRDMAC_FLUSH              _BIT(0)
+
+#define SSS_REG_FCPKDMAS                0x0050
+#define SSS_REG_FCPKDMAL                0x0054
+#define SSS_REG_FCPKDMAC                0x0058
+#define SSS_FCPKDMAC_BYTESWAP           _BIT(3)
+#define SSS_FCPKDMAC_DESCEND            _BIT(2)
+#define SSS_FCPKDMAC_TRANSMIT           _BIT(1)
+#define SSS_FCPKDMAC_FLUSH              _BIT(0)
+
+#define SSS_REG_FCPKDMAO                0x005C
+
+/* AES registers */
+#define SSS_REG_AES_CONTROL             0x4000
+#define SSS_AES_BYTESWAP_DI             _BIT(11)
+#define SSS_AES_BYTESWAP_DO             _BIT(10)
+#define SSS_AES_BYTESWAP_IV             _BIT(9)
+#define SSS_AES_BYTESWAP_CNT            _BIT(8)
+#define SSS_AES_BYTESWAP_KEY            _BIT(7)
+#define SSS_AES_KEY_CHANGE_MODE         _BIT(6)
+#define SSS_AES_KEY_SIZE_128            _SBF(4, 0x00)
+#define SSS_AES_KEY_SIZE_192            _SBF(4, 0x01)
+#define SSS_AES_KEY_SIZE_256            _SBF(4, 0x02)
+#define SSS_AES_FIFO_MODE               _BIT(3)
+#define SSS_AES_CHAIN_MODE_ECB          _SBF(1, 0x00)
+#define SSS_AES_CHAIN_MODE_CBC          _SBF(1, 0x01)
+#define SSS_AES_CHAIN_MODE_CTR          _SBF(1, 0x02)
+#define SSS_AES_MODE_DECRYPT            _BIT(0)
+
+#define SSS_REG_AES_STATUS              0x4004
+#define SSS_AES_BUSY                    _BIT(2)
+#define SSS_AES_INPUT_READY             _BIT(1)
+#define SSS_AES_OUTPUT_READY            _BIT(0)
+
+#define SSS_REG_AES_IN_DATA(s)          (0x4010 + (s << 2))
+#define SSS_REG_AES_OUT_DATA(s)         (0x4020 + (s << 2))
+#define SSS_REG_AES_IV_DATA(s)          (0x4030 + (s << 2))
+#define SSS_REG_AES_CNT_DATA(s)         (0x4040 + (s << 2))
+#define SSS_REG_AES_KEY_DATA(s)         (0x4080 + (s << 2))
+
+#define SSS_REG(dev, reg)               ((dev)->ioaddr + (SSS_REG_##reg))
+#define SSS_READ(dev, reg)              __raw_readl(SSS_REG(dev, reg))
+#define SSS_WRITE(dev, reg, val)        __raw_writel((val), SSS_REG(dev, reg))
+
+/* HW engine modes */
+#define FLAGS_AES_DECRYPT               _BIT(0)
+#define FLAGS_AES_MODE_MASK             _SBF(1, 0x03)
+#define FLAGS_AES_CBC                   _SBF(1, 0x01)
+#define FLAGS_AES_CTR                   _SBF(1, 0x02)
+
+#define AES_KEY_LEN         16
+#define CRYPTO_QUEUE_LEN    1
+
+struct s5p_aes_reqctx {
+	unsigned long mode;
+};
+
+struct s5p_aes_ctx {
+	struct s5p_aes_dev         *dev;
+
+	uint8_t                     aes_key[AES_MAX_KEY_SIZE];
+	uint8_t                     nonce[CTR_RFC3686_NONCE_SIZE];
+	int                         keylen;
+};
+
+struct s5p_aes_dev {
+	struct device              *dev;
+	struct clk                 *clk;
+	void __iomem               *ioaddr;
+	int                         irq_hash;
+	int                         irq_fc;
+
+	struct ablkcipher_request  *req;
+	struct s5p_aes_ctx         *ctx;
+	struct scatterlist         *sg_src;
+	struct scatterlist         *sg_dst;
+
+	struct tasklet_struct       tasklet;
+	struct crypto_queue         queue;
+	bool                        busy;
+	spinlock_t                  lock;
+};
+
+static struct s5p_aes_dev *s5p_dev;
+
+static void s5p_set_dma_indata(struct s5p_aes_dev *dev, struct scatterlist *sg)
+{
+	SSS_WRITE(dev, FCBRDMAS, sg_dma_address(sg));
+	SSS_WRITE(dev, FCBRDMAL, sg_dma_len(sg));
+}
+
+static void s5p_set_dma_outdata(struct s5p_aes_dev *dev, struct scatterlist *sg)
+{
+	SSS_WRITE(dev, FCBTDMAS, sg_dma_address(sg));
+	SSS_WRITE(dev, FCBTDMAL, sg_dma_len(sg));
+}
+
+static void s5p_aes_complete(struct s5p_aes_dev *dev, int err)
+{
+	/* holding a lock outside */
+	dev->req->base.complete(&dev->req->base, err);
+	dev->busy = false;
+}
+
+static void s5p_unset_outdata(struct s5p_aes_dev *dev)
+{
+	dma_unmap_sg(dev->dev, dev->sg_dst, 1, DMA_FROM_DEVICE);
+}
+
+static void s5p_unset_indata(struct s5p_aes_dev *dev)
+{
+	dma_unmap_sg(dev->dev, dev->sg_src, 1, DMA_TO_DEVICE);
+}
+
+static int s5p_set_outdata(struct s5p_aes_dev *dev, struct scatterlist *sg)
+{
+	int err;
+
+	if (!IS_ALIGNED(sg_dma_len(sg), AES_BLOCK_SIZE)) {
+		err = -EINVAL;
+		goto exit;
+	}
+	if (!sg_dma_len(sg)) {
+		err = -EINVAL;
+		goto exit;
+	}
+
+	err = dma_map_sg(dev->dev, sg, 1, DMA_FROM_DEVICE);
+	if (!err) {
+		err = -ENOMEM;
+		goto exit;
+	}
+
+	dev->sg_dst = sg;
+	err = 0;
+
+ exit:
+	return err;
+}
+
+static int s5p_set_indata(struct s5p_aes_dev *dev, struct scatterlist *sg)
+{
+	int err;
+
+	if (!IS_ALIGNED(sg_dma_len(sg), AES_BLOCK_SIZE)) {
+		err = -EINVAL;
+		goto exit;
+	}
+	if (!sg_dma_len(sg)) {
+		err = -EINVAL;
+		goto exit;
+	}
+
+	err = dma_map_sg(dev->dev, sg, 1, DMA_TO_DEVICE);
+	if (!err) {
+		err = -ENOMEM;
+		goto exit;
+	}
+
+	dev->sg_src = sg;
+	err = 0;
+
+ exit:
+	return err;
+}
+
+static void s5p_aes_tx(struct s5p_aes_dev *dev)
+{
+	int err = 0;
+
+	s5p_unset_outdata(dev);
+
+	if (!sg_is_last(dev->sg_dst)) {
+		err = s5p_set_outdata(dev, sg_next(dev->sg_dst));
+		if (err) {
+			s5p_aes_complete(dev, err);
+			return;
+		}
+
+		s5p_set_dma_outdata(dev, dev->sg_dst);
+	} else
+		s5p_aes_complete(dev, err);
+}
+
+static void s5p_aes_rx(struct s5p_aes_dev *dev)
+{
+	int err;
+
+	s5p_unset_indata(dev);
+
+	if (!sg_is_last(dev->sg_src)) {
+		err = s5p_set_indata(dev, sg_next(dev->sg_src));
+		if (err) {
+			s5p_aes_complete(dev, err);
+			return;
+		}
+
+		s5p_set_dma_indata(dev, dev->sg_src);
+	}
+}
+
+static irqreturn_t s5p_aes_interrupt(int irq, void *dev_id)
+{
+	struct platform_device *pdev = dev_id;
+	struct s5p_aes_dev     *dev  = platform_get_drvdata(pdev);
+	uint32_t                status;
+	unsigned long           flags;
+
+	spin_lock_irqsave(&dev->lock, flags);
+
+	if (irq == dev->irq_fc) {
+		status = SSS_READ(dev, FCINTSTAT);
+		if (status & SSS_FCINTSTAT_BRDMAINT)
+			s5p_aes_rx(dev);
+		if (status & SSS_FCINTSTAT_BTDMAINT)
+			s5p_aes_tx(dev);
+
+		SSS_WRITE(dev, FCINTPEND, status);
+	}
+
+	spin_unlock_irqrestore(&dev->lock, flags);
+
+	return IRQ_HANDLED;
+}
+
+static void s5p_set_aes(struct s5p_aes_dev *dev,
+			uint8_t *key, uint8_t *iv, unsigned int keylen)
+{
+	void __iomem *keystart;
+
+	memcpy(dev->ioaddr + SSS_REG_AES_IV_DATA(0), iv, 0x10);
+
+	if (keylen == AES_KEYSIZE_256)
+		keystart = dev->ioaddr + SSS_REG_AES_KEY_DATA(0);
+	else if (keylen == AES_KEYSIZE_192)
+		keystart = dev->ioaddr + SSS_REG_AES_KEY_DATA(2);
+	else
+		keystart = dev->ioaddr + SSS_REG_AES_KEY_DATA(4);
+
+	memcpy(keystart, key, keylen);
+}
+
+static void s5p_aes_crypt_start(struct s5p_aes_dev *dev, unsigned long mode)
+{
+	struct ablkcipher_request  *req = dev->req;
+
+	uint32_t                    aes_control;
+	int                         err;
+	unsigned long               flags;
+
+	aes_control = SSS_AES_KEY_CHANGE_MODE;
+	if (mode & FLAGS_AES_DECRYPT)
+		aes_control |= SSS_AES_MODE_DECRYPT;
+
+	if ((mode & FLAGS_AES_MODE_MASK) == FLAGS_AES_CBC)
+		aes_control |= SSS_AES_CHAIN_MODE_CBC;
+	else if ((mode & FLAGS_AES_MODE_MASK) == FLAGS_AES_CTR)
+		aes_control |= SSS_AES_CHAIN_MODE_CTR;
+
+	if (dev->ctx->keylen == AES_KEYSIZE_192)
+		aes_control |= SSS_AES_KEY_SIZE_192;
+	else if (dev->ctx->keylen == AES_KEYSIZE_256)
+		aes_control |= SSS_AES_KEY_SIZE_256;
+
+	aes_control |= SSS_AES_FIFO_MODE;
+
+	/* as a variant it is possible to use byte swapping on DMA side */
+	aes_control |= SSS_AES_BYTESWAP_DI
+		    |  SSS_AES_BYTESWAP_DO
+		    |  SSS_AES_BYTESWAP_IV
+		    |  SSS_AES_BYTESWAP_KEY
+		    |  SSS_AES_BYTESWAP_CNT;
+
+	spin_lock_irqsave(&dev->lock, flags);
+
+	SSS_WRITE(dev, FCINTENCLR,
+		  SSS_FCINTENCLR_BTDMAINTENCLR | SSS_FCINTENCLR_BRDMAINTENCLR);
+	SSS_WRITE(dev, FCFIFOCTRL, 0x00);
+
+	err = s5p_set_indata(dev, req->src);
+	if (err)
+		goto indata_error;
+
+	err = s5p_set_outdata(dev, req->dst);
+	if (err)
+		goto outdata_error;
+
+	SSS_WRITE(dev, AES_CONTROL, aes_control);
+	s5p_set_aes(dev, dev->ctx->aes_key, req->info, dev->ctx->keylen);
+
+	s5p_set_dma_indata(dev,  req->src);
+	s5p_set_dma_outdata(dev, req->dst);
+
+	SSS_WRITE(dev, FCINTENSET,
+		  SSS_FCINTENSET_BTDMAINTENSET | SSS_FCINTENSET_BRDMAINTENSET);
+
+	spin_unlock_irqrestore(&dev->lock, flags);
+
+	return;
+
+ outdata_error:
+	s5p_unset_indata(dev);
+
+ indata_error:
+	s5p_aes_complete(dev, err);
+	spin_unlock_irqrestore(&dev->lock, flags);
+}
+
+static void s5p_tasklet_cb(unsigned long data)
+{
+	struct s5p_aes_dev *dev = (struct s5p_aes_dev *)data;
+	struct crypto_async_request *async_req, *backlog;
+	struct s5p_aes_reqctx *reqctx;
+	unsigned long flags;
+
+	spin_lock_irqsave(&dev->lock, flags);
+	backlog   = crypto_get_backlog(&dev->queue);
+	async_req = crypto_dequeue_request(&dev->queue);
+	spin_unlock_irqrestore(&dev->lock, flags);
+
+	if (!async_req)
+		return;
+
+	if (backlog)
+		backlog->complete(backlog, -EINPROGRESS);
+
+	dev->req = ablkcipher_request_cast(async_req);
+	dev->ctx = crypto_tfm_ctx(dev->req->base.tfm);
+	reqctx   = ablkcipher_request_ctx(dev->req);
+
+	s5p_aes_crypt_start(dev, reqctx->mode);
+}
+
+static int s5p_aes_handle_req(struct s5p_aes_dev *dev,
+			      struct ablkcipher_request *req)
+{
+	unsigned long flags;
+	int err;
+
+	spin_lock_irqsave(&dev->lock, flags);
+	if (dev->busy) {
+		err = -EAGAIN;
+		spin_unlock_irqrestore(&dev->lock, flags);
+		goto exit;
+	}
+	dev->busy = true;
+
+	err = ablkcipher_enqueue_request(&dev->queue, req);
+	spin_unlock_irqrestore(&dev->lock, flags);
+
+	tasklet_schedule(&dev->tasklet);
+
+ exit:
+	return err;
+}
+
+static int s5p_aes_crypt(struct ablkcipher_request *req, unsigned long mode)
+{
+	struct crypto_ablkcipher   *tfm    = crypto_ablkcipher_reqtfm(req);
+	struct s5p_aes_ctx         *ctx    = crypto_ablkcipher_ctx(tfm);
+	struct s5p_aes_reqctx      *reqctx = ablkcipher_request_ctx(req);
+	struct s5p_aes_dev         *dev    = ctx->dev;
+
+	if (!IS_ALIGNED(req->nbytes, AES_BLOCK_SIZE)) {
+		pr_err("request size is not exact amount of AES blocks\n");
+		return -EINVAL;
+	}
+
+	reqctx->mode = mode;
+
+	return s5p_aes_handle_req(dev, req);
+}
+
+static int s5p_aes_setkey(struct crypto_ablkcipher *cipher,
+			  const uint8_t *key, unsigned int keylen)
+{
+	struct crypto_tfm  *tfm = crypto_ablkcipher_tfm(cipher);
+	struct s5p_aes_ctx *ctx = crypto_tfm_ctx(tfm);
+
+	if (keylen != AES_KEYSIZE_128 &&
+	    keylen != AES_KEYSIZE_192 &&
+	    keylen != AES_KEYSIZE_256)
+		return -EINVAL;
+
+	memcpy(ctx->aes_key, key, keylen);
+	ctx->keylen = keylen;
+
+	return 0;
+}
+
+static int s5p_aes_ecb_encrypt(struct ablkcipher_request *req)
+{
+	return s5p_aes_crypt(req, 0);
+}
+
+static int s5p_aes_ecb_decrypt(struct ablkcipher_request *req)
+{
+	return s5p_aes_crypt(req, FLAGS_AES_DECRYPT);
+}
+
+static int s5p_aes_cbc_encrypt(struct ablkcipher_request *req)
+{
+	return s5p_aes_crypt(req, FLAGS_AES_CBC);
+}
+
+static int s5p_aes_cbc_decrypt(struct ablkcipher_request *req)
+{
+	return s5p_aes_crypt(req, FLAGS_AES_DECRYPT | FLAGS_AES_CBC);
+}
+
+static int s5p_aes_cra_init(struct crypto_tfm *tfm)
+{
+	struct s5p_aes_ctx  *ctx = crypto_tfm_ctx(tfm);
+
+	ctx->dev = s5p_dev;
+	tfm->crt_ablkcipher.reqsize = sizeof(struct s5p_aes_reqctx);
+
+	return 0;
+}
+
+static struct crypto_alg algs[] = {
+	{
+		.cra_name		= "ecb(aes)",
+		.cra_driver_name	= "ecb-aes-s5p",
+		.cra_priority		= 100,
+		.cra_flags		= CRYPTO_ALG_TYPE_ABLKCIPHER |
+					  CRYPTO_ALG_ASYNC,
+		.cra_blocksize		= AES_BLOCK_SIZE,
+		.cra_ctxsize		= sizeof(struct s5p_aes_ctx),
+		.cra_alignmask		= 0x0f,
+		.cra_type		= &crypto_ablkcipher_type,
+		.cra_module		= THIS_MODULE,
+		.cra_init		= s5p_aes_cra_init,
+		.cra_u.ablkcipher = {
+			.min_keysize	= AES_MIN_KEY_SIZE,
+			.max_keysize	= AES_MAX_KEY_SIZE,
+			.setkey		= s5p_aes_setkey,
+			.encrypt	= s5p_aes_ecb_encrypt,
+			.decrypt	= s5p_aes_ecb_decrypt,
+		}
+	},
+	{
+		.cra_name		= "cbc(aes)",
+		.cra_driver_name	= "cbc-aes-s5p",
+		.cra_priority		= 100,
+		.cra_flags		= CRYPTO_ALG_TYPE_ABLKCIPHER |
+					  CRYPTO_ALG_ASYNC,
+		.cra_blocksize		= AES_BLOCK_SIZE,
+		.cra_ctxsize		= sizeof(struct s5p_aes_ctx),
+		.cra_alignmask		= 0x0f,
+		.cra_type		= &crypto_ablkcipher_type,
+		.cra_module		= THIS_MODULE,
+		.cra_init		= s5p_aes_cra_init,
+		.cra_u.ablkcipher = {
+			.min_keysize	= AES_MIN_KEY_SIZE,
+			.max_keysize	= AES_MAX_KEY_SIZE,
+			.ivsize		= AES_BLOCK_SIZE,
+			.setkey		= s5p_aes_setkey,
+			.encrypt	= s5p_aes_cbc_encrypt,
+			.decrypt	= s5p_aes_cbc_decrypt,
+		}
+	},
+};
+
+static int s5p_aes_probe(struct platform_device *pdev)
+{
+	int                 i, j, err = -ENODEV;
+	struct s5p_aes_dev *pdata;
+	struct device      *dev = &pdev->dev;
+	struct resource    *res;
+
+	if (s5p_dev)
+		return -EEXIST;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res)
+		return -ENODEV;
+
+	pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
+	if (!pdata)
+		return -ENOMEM;
+
+	if (!devm_request_mem_region(dev, res->start,
+				     resource_size(res), pdev->name))
+		return -EBUSY;
+
+	pdata->clk = clk_get(dev, "secss");
+	if (IS_ERR(pdata->clk)) {
+		dev_err(dev, "failed to find secss clock source\n");
+		return -ENOENT;
+	}
+
+	clk_enable(pdata->clk);
+
+	spin_lock_init(&pdata->lock);
+	pdata->ioaddr = devm_ioremap(dev, res->start,
+				     resource_size(res));
+
+	pdata->irq_hash = platform_get_irq_byname(pdev, "hash");
+	if (pdata->irq_hash < 0) {
+		err = pdata->irq_hash;
+		dev_warn(dev, "hash interrupt is not available.\n");
+		goto err_irq;
+	}
+	err = devm_request_irq(dev, pdata->irq_hash, s5p_aes_interrupt,
+			       IRQF_SHARED, pdev->name, pdev);
+	if (err < 0) {
+		dev_warn(dev, "hash interrupt is not available.\n");
+		goto err_irq;
+	}
+
+	pdata->irq_fc = platform_get_irq_byname(pdev, "feed control");
+	if (pdata->irq_fc < 0) {
+		err = pdata->irq_fc;
+		dev_warn(dev, "feed control interrupt is not available.\n");
+		goto err_irq;
+	}
+	err = devm_request_irq(dev, pdata->irq_fc, s5p_aes_interrupt,
+			       IRQF_SHARED, pdev->name, pdev);
+	if (err < 0) {
+		dev_warn(dev, "feed control interrupt is not available.\n");
+		goto err_irq;
+	}
+
+	pdata->dev = dev;
+	platform_set_drvdata(pdev, pdata);
+	s5p_dev = pdata;
+
+	tasklet_init(&pdata->tasklet, s5p_tasklet_cb, (unsigned long)pdata);
+	crypto_init_queue(&pdata->queue, CRYPTO_QUEUE_LEN);
+
+	for (i = 0; i < ARRAY_SIZE(algs); i++) {
+		INIT_LIST_HEAD(&algs[i].cra_list);
+		err = crypto_register_alg(&algs[i]);
+		if (err)
+			goto err_algs;
+	}
+
+	pr_info("s5p-sss driver registered\n");
+
+	return 0;
+
+ err_algs:
+	dev_err(dev, "can't register '%s': %d\n", algs[i].cra_name, err);
+
+	for (j = 0; j < i; j++)
+		crypto_unregister_alg(&algs[j]);
+
+	tasklet_kill(&pdata->tasklet);
+
+ err_irq:
+	clk_disable(pdata->clk);
+	clk_put(pdata->clk);
+
+	s5p_dev = NULL;
+	platform_set_drvdata(pdev, NULL);
+
+	return err;
+}
+
+static int s5p_aes_remove(struct platform_device *pdev)
+{
+	struct s5p_aes_dev *pdata = platform_get_drvdata(pdev);
+	int i;
+
+	if (!pdata)
+		return -ENODEV;
+
+	for (i = 0; i < ARRAY_SIZE(algs); i++)
+		crypto_unregister_alg(&algs[i]);
+
+	tasklet_kill(&pdata->tasklet);
+
+	clk_disable(pdata->clk);
+	clk_put(pdata->clk);
+
+	s5p_dev = NULL;
+	platform_set_drvdata(pdev, NULL);
+
+	return 0;
+}
+
+static struct platform_driver s5p_aes_crypto = {
+	.probe	= s5p_aes_probe,
+	.remove	= s5p_aes_remove,
+	.driver	= {
+		.owner	= THIS_MODULE,
+		.name	= "s5p-secss",
+	},
+};
+
+static int __init s5p_aes_mod_init(void)
+{
+	return  platform_driver_register(&s5p_aes_crypto);
+}
+
+static void __exit s5p_aes_mod_exit(void)
+{
+	platform_driver_unregister(&s5p_aes_crypto);
+}
+
+module_init(s5p_aes_mod_init);
+module_exit(s5p_aes_mod_exit);
+
+MODULE_DESCRIPTION("S5PV210 AES hw acceleration support.");
+MODULE_LICENSE("GPL v2");
+MODULE_AUTHOR("Vladimir Zapolskiy <vzapolskiy@gmail.com>");
diff -druN linux-2.6.39-libre/drivers/dma/at_hdmac.c linux-3.0-rc7-libre/drivers/dma/at_hdmac.c
--- linux-2.6.39-libre/drivers/dma/at_hdmac.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/dma/at_hdmac.c	2011-07-11 19:51:52.000000000 -0400
@@ -37,8 +37,8 @@
 
 #define	ATC_DEFAULT_CFG		(ATC_FIFOCFG_HALFFIFO)
 #define	ATC_DEFAULT_CTRLA	(0)
-#define	ATC_DEFAULT_CTRLB	(ATC_SIF(0)	\
-				|ATC_DIF(1))
+#define	ATC_DEFAULT_CTRLB	(ATC_SIF(AT_DMA_MEM_IF) \
+				|ATC_DIF(AT_DMA_MEM_IF))
 
 /*
  * Initial number of descriptors to allocate for each channel. This could
@@ -165,6 +165,29 @@
 }
 
 /**
+ * atc_desc_chain - build chain adding a descripor
+ * @first: address of first descripor of the chain
+ * @prev: address of previous descripor of the chain
+ * @desc: descriptor to queue
+ *
+ * Called from prep_* functions
+ */
+static void atc_desc_chain(struct at_desc **first, struct at_desc **prev,
+			   struct at_desc *desc)
+{
+	if (!(*first)) {
+		*first = desc;
+	} else {
+		/* inform the HW lli about chaining */
+		(*prev)->lli.dscr = desc->txd.phys;
+		/* insert the link descriptor to the LD ring */
+		list_add_tail(&desc->desc_node,
+				&(*first)->tx_list);
+	}
+	*prev = desc;
+}
+
+/**
  * atc_assign_cookie - compute and assign new cookie
  * @atchan: channel we work on
  * @desc: descriptor to assign cookie for
@@ -237,16 +260,12 @@
 static void
 atc_chain_complete(struct at_dma_chan *atchan, struct at_desc *desc)
 {
-	dma_async_tx_callback		callback;
-	void				*param;
 	struct dma_async_tx_descriptor	*txd = &desc->txd;
 
 	dev_vdbg(chan2dev(&atchan->chan_common),
 		"descriptor %u complete\n", txd->cookie);
 
 	atchan->completed_cookie = txd->cookie;
-	callback = txd->callback;
-	param = txd->callback_param;
 
 	/* move children to free_list */
 	list_splice_init(&desc->tx_list, &atchan->free_list);
@@ -278,12 +297,19 @@
 		}
 	}
 
-	/*
-	 * The API requires that no submissions are done from a
-	 * callback, so we don't need to drop the lock here
-	 */
-	if (callback)
-		callback(param);
+	/* for cyclic transfers,
+	 * no need to replay callback function while stopping */
+	if (!test_bit(ATC_IS_CYCLIC, &atchan->status)) {
+		dma_async_tx_callback	callback = txd->callback;
+		void			*param = txd->callback_param;
+
+		/*
+		 * The API requires that no submissions are done from a
+		 * callback, so we don't need to drop the lock here
+		 */
+		if (callback)
+			callback(param);
+	}
 
 	dma_run_dependencies(txd);
 }
@@ -419,6 +445,26 @@
 	atc_chain_complete(atchan, bad_desc);
 }
 
+/**
+ * atc_handle_cyclic - at the end of a period, run callback function
+ * @atchan: channel used for cyclic operations
+ *
+ * Called with atchan->lock held and bh disabled
+ */
+static void atc_handle_cyclic(struct at_dma_chan *atchan)
+{
+	struct at_desc			*first = atc_first_active(atchan);
+	struct dma_async_tx_descriptor	*txd = &first->txd;
+	dma_async_tx_callback		callback = txd->callback;
+	void				*param = txd->callback_param;
+
+	dev_vdbg(chan2dev(&atchan->chan_common),
+			"new cyclic period llp 0x%08x\n",
+			channel_readl(atchan, DSCR));
+
+	if (callback)
+		callback(param);
+}
 
 /*--  IRQ & Tasklet  ---------------------------------------------------*/
 
@@ -426,16 +472,11 @@
 {
 	struct at_dma_chan *atchan = (struct at_dma_chan *)data;
 
-	/* Channel cannot be enabled here */
-	if (atc_chan_is_enabled(atchan)) {
-		dev_err(chan2dev(&atchan->chan_common),
-			"BUG: channel enabled in tasklet\n");
-		return;
-	}
-
 	spin_lock(&atchan->lock);
-	if (test_and_clear_bit(0, &atchan->error_status))
+	if (test_and_clear_bit(ATC_IS_ERROR, &atchan->status))
 		atc_handle_error(atchan);
+	else if (test_bit(ATC_IS_CYCLIC, &atchan->status))
+		atc_handle_cyclic(atchan);
 	else
 		atc_advance_work(atchan);
 
@@ -464,12 +505,13 @@
 
 		for (i = 0; i < atdma->dma_common.chancnt; i++) {
 			atchan = &atdma->chan[i];
-			if (pending & (AT_DMA_CBTC(i) | AT_DMA_ERR(i))) {
+			if (pending & (AT_DMA_BTC(i) | AT_DMA_ERR(i))) {
 				if (pending & AT_DMA_ERR(i)) {
 					/* Disable channel on AHB error */
-					dma_writel(atdma, CHDR, atchan->mask);
+					dma_writel(atdma, CHDR,
+						AT_DMA_RES(i) | atchan->mask);
 					/* Give information to tasklet */
-					set_bit(0, &atchan->error_status);
+					set_bit(ATC_IS_ERROR, &atchan->status);
 				}
 				tasklet_schedule(&atchan->tasklet);
 				ret = IRQ_HANDLED;
@@ -549,7 +591,7 @@
 	}
 
 	ctrla =   ATC_DEFAULT_CTRLA;
-	ctrlb =   ATC_DEFAULT_CTRLB
+	ctrlb =   ATC_DEFAULT_CTRLB | ATC_IEN
 		| ATC_SRC_ADDR_MODE_INCR
 		| ATC_DST_ADDR_MODE_INCR
 		| ATC_FC_MEM2MEM;
@@ -584,16 +626,7 @@
 
 		desc->txd.cookie = 0;
 
-		if (!first) {
-			first = desc;
-		} else {
-			/* inform the HW lli about chaining */
-			prev->lli.dscr = desc->txd.phys;
-			/* insert the link descriptor to the LD ring */
-			list_add_tail(&desc->desc_node,
-					&first->tx_list);
-		}
-		prev = desc;
+		atc_desc_chain(&first, &prev, desc);
 	}
 
 	/* First descriptor of the chain embedds additional information */
@@ -639,7 +672,8 @@
 	struct scatterlist	*sg;
 	size_t			total_len = 0;
 
-	dev_vdbg(chan2dev(chan), "prep_slave_sg: %s f0x%lx\n",
+	dev_vdbg(chan2dev(chan), "prep_slave_sg (%d): %s f0x%lx\n",
+			sg_len,
 			direction == DMA_TO_DEVICE ? "TO DEVICE" : "FROM DEVICE",
 			flags);
 
@@ -651,14 +685,15 @@
 	reg_width = atslave->reg_width;
 
 	ctrla = ATC_DEFAULT_CTRLA | atslave->ctrla;
-	ctrlb = ATC_DEFAULT_CTRLB | ATC_IEN;
+	ctrlb = ATC_IEN;
 
 	switch (direction) {
 	case DMA_TO_DEVICE:
 		ctrla |=  ATC_DST_WIDTH(reg_width);
 		ctrlb |=  ATC_DST_ADDR_MODE_FIXED
 			| ATC_SRC_ADDR_MODE_INCR
-			| ATC_FC_MEM2PER;
+			| ATC_FC_MEM2PER
+			| ATC_SIF(AT_DMA_MEM_IF) | ATC_DIF(AT_DMA_PER_IF);
 		reg = atslave->tx_reg;
 		for_each_sg(sgl, sg, sg_len, i) {
 			struct at_desc	*desc;
@@ -682,16 +717,7 @@
 					| len >> mem_width;
 			desc->lli.ctrlb = ctrlb;
 
-			if (!first) {
-				first = desc;
-			} else {
-				/* inform the HW lli about chaining */
-				prev->lli.dscr = desc->txd.phys;
-				/* insert the link descriptor to the LD ring */
-				list_add_tail(&desc->desc_node,
-						&first->tx_list);
-			}
-			prev = desc;
+			atc_desc_chain(&first, &prev, desc);
 			total_len += len;
 		}
 		break;
@@ -699,7 +725,8 @@
 		ctrla |=  ATC_SRC_WIDTH(reg_width);
 		ctrlb |=  ATC_DST_ADDR_MODE_INCR
 			| ATC_SRC_ADDR_MODE_FIXED
-			| ATC_FC_PER2MEM;
+			| ATC_FC_PER2MEM
+			| ATC_SIF(AT_DMA_PER_IF) | ATC_DIF(AT_DMA_MEM_IF);
 
 		reg = atslave->rx_reg;
 		for_each_sg(sgl, sg, sg_len, i) {
@@ -724,16 +751,7 @@
 					| len >> reg_width;
 			desc->lli.ctrlb = ctrlb;
 
-			if (!first) {
-				first = desc;
-			} else {
-				/* inform the HW lli about chaining */
-				prev->lli.dscr = desc->txd.phys;
-				/* insert the link descriptor to the LD ring */
-				list_add_tail(&desc->desc_node,
-						&first->tx_list);
-			}
-			prev = desc;
+			atc_desc_chain(&first, &prev, desc);
 			total_len += len;
 		}
 		break;
@@ -759,41 +777,211 @@
 	return NULL;
 }
 
+/**
+ * atc_dma_cyclic_check_values
+ * Check for too big/unaligned periods and unaligned DMA buffer
+ */
+static int
+atc_dma_cyclic_check_values(unsigned int reg_width, dma_addr_t buf_addr,
+		size_t period_len, enum dma_data_direction direction)
+{
+	if (period_len > (ATC_BTSIZE_MAX << reg_width))
+		goto err_out;
+	if (unlikely(period_len & ((1 << reg_width) - 1)))
+		goto err_out;
+	if (unlikely(buf_addr & ((1 << reg_width) - 1)))
+		goto err_out;
+	if (unlikely(!(direction & (DMA_TO_DEVICE | DMA_FROM_DEVICE))))
+		goto err_out;
+
+	return 0;
+
+err_out:
+	return -EINVAL;
+}
+
+/**
+ * atc_dma_cyclic_fill_desc - Fill one period decriptor
+ */
+static int
+atc_dma_cyclic_fill_desc(struct at_dma_slave *atslave, struct at_desc *desc,
+		unsigned int period_index, dma_addr_t buf_addr,
+		size_t period_len, enum dma_data_direction direction)
+{
+	u32		ctrla;
+	unsigned int	reg_width = atslave->reg_width;
+
+	/* prepare common CRTLA value */
+	ctrla =   ATC_DEFAULT_CTRLA | atslave->ctrla
+		| ATC_DST_WIDTH(reg_width)
+		| ATC_SRC_WIDTH(reg_width)
+		| period_len >> reg_width;
+
+	switch (direction) {
+	case DMA_TO_DEVICE:
+		desc->lli.saddr = buf_addr + (period_len * period_index);
+		desc->lli.daddr = atslave->tx_reg;
+		desc->lli.ctrla = ctrla;
+		desc->lli.ctrlb = ATC_DST_ADDR_MODE_FIXED
+				| ATC_SRC_ADDR_MODE_INCR
+				| ATC_FC_MEM2PER
+				| ATC_SIF(AT_DMA_MEM_IF)
+				| ATC_DIF(AT_DMA_PER_IF);
+		break;
+
+	case DMA_FROM_DEVICE:
+		desc->lli.saddr = atslave->rx_reg;
+		desc->lli.daddr = buf_addr + (period_len * period_index);
+		desc->lli.ctrla = ctrla;
+		desc->lli.ctrlb = ATC_DST_ADDR_MODE_INCR
+				| ATC_SRC_ADDR_MODE_FIXED
+				| ATC_FC_PER2MEM
+				| ATC_SIF(AT_DMA_PER_IF)
+				| ATC_DIF(AT_DMA_MEM_IF);
+		break;
+
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+/**
+ * atc_prep_dma_cyclic - prepare the cyclic DMA transfer
+ * @chan: the DMA channel to prepare
+ * @buf_addr: physical DMA address where the buffer starts
+ * @buf_len: total number of bytes for the entire buffer
+ * @period_len: number of bytes for each period
+ * @direction: transfer direction, to or from device
+ */
+static struct dma_async_tx_descriptor *
+atc_prep_dma_cyclic(struct dma_chan *chan, dma_addr_t buf_addr, size_t buf_len,
+		size_t period_len, enum dma_data_direction direction)
+{
+	struct at_dma_chan	*atchan = to_at_dma_chan(chan);
+	struct at_dma_slave	*atslave = chan->private;
+	struct at_desc		*first = NULL;
+	struct at_desc		*prev = NULL;
+	unsigned long		was_cyclic;
+	unsigned int		periods = buf_len / period_len;
+	unsigned int		i;
+
+	dev_vdbg(chan2dev(chan), "prep_dma_cyclic: %s buf@0x%08x - %d (%d/%d)\n",
+			direction == DMA_TO_DEVICE ? "TO DEVICE" : "FROM DEVICE",
+			buf_addr,
+			periods, buf_len, period_len);
+
+	if (unlikely(!atslave || !buf_len || !period_len)) {
+		dev_dbg(chan2dev(chan), "prep_dma_cyclic: length is zero!\n");
+		return NULL;
+	}
+
+	was_cyclic = test_and_set_bit(ATC_IS_CYCLIC, &atchan->status);
+	if (was_cyclic) {
+		dev_dbg(chan2dev(chan), "prep_dma_cyclic: channel in use!\n");
+		return NULL;
+	}
+
+	/* Check for too big/unaligned periods and unaligned DMA buffer */
+	if (atc_dma_cyclic_check_values(atslave->reg_width, buf_addr,
+					period_len, direction))
+		goto err_out;
+
+	/* build cyclic linked list */
+	for (i = 0; i < periods; i++) {
+		struct at_desc	*desc;
+
+		desc = atc_desc_get(atchan);
+		if (!desc)
+			goto err_desc_get;
+
+		if (atc_dma_cyclic_fill_desc(atslave, desc, i, buf_addr,
+						period_len, direction))
+			goto err_desc_get;
+
+		atc_desc_chain(&first, &prev, desc);
+	}
+
+	/* lets make a cyclic list */
+	prev->lli.dscr = first->txd.phys;
+
+	/* First descriptor of the chain embedds additional information */
+	first->txd.cookie = -EBUSY;
+	first->len = buf_len;
+
+	return &first->txd;
+
+err_desc_get:
+	dev_err(chan2dev(chan), "not enough descriptors available\n");
+	atc_desc_put(atchan, first);
+err_out:
+	clear_bit(ATC_IS_CYCLIC, &atchan->status);
+	return NULL;
+}
+
+
 static int atc_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd,
 		       unsigned long arg)
 {
 	struct at_dma_chan	*atchan = to_at_dma_chan(chan);
 	struct at_dma		*atdma = to_at_dma(chan->device);
-	struct at_desc		*desc, *_desc;
+	int			chan_id = atchan->chan_common.chan_id;
+
 	LIST_HEAD(list);
 
-	/* Only supports DMA_TERMINATE_ALL */
-	if (cmd != DMA_TERMINATE_ALL)
-		return -ENXIO;
+	dev_vdbg(chan2dev(chan), "atc_control (%d)\n", cmd);
 
-	/*
-	 * This is only called when something went wrong elsewhere, so
-	 * we don't really care about the data. Just disable the
-	 * channel. We still have to poll the channel enable bit due
-	 * to AHB/HSB limitations.
-	 */
-	spin_lock_bh(&atchan->lock);
+	if (cmd == DMA_PAUSE) {
+		spin_lock_bh(&atchan->lock);
 
-	dma_writel(atdma, CHDR, atchan->mask);
+		dma_writel(atdma, CHER, AT_DMA_SUSP(chan_id));
+		set_bit(ATC_IS_PAUSED, &atchan->status);
 
-	/* confirm that this channel is disabled */
-	while (dma_readl(atdma, CHSR) & atchan->mask)
-		cpu_relax();
+		spin_unlock_bh(&atchan->lock);
+	} else if (cmd == DMA_RESUME) {
+		if (!test_bit(ATC_IS_PAUSED, &atchan->status))
+			return 0;
 
-	/* active_list entries will end up before queued entries */
-	list_splice_init(&atchan->queue, &list);
-	list_splice_init(&atchan->active_list, &list);
+		spin_lock_bh(&atchan->lock);
 
-	/* Flush all pending and queued descriptors */
-	list_for_each_entry_safe(desc, _desc, &list, desc_node)
-		atc_chain_complete(atchan, desc);
+		dma_writel(atdma, CHDR, AT_DMA_RES(chan_id));
+		clear_bit(ATC_IS_PAUSED, &atchan->status);
 
-	spin_unlock_bh(&atchan->lock);
+		spin_unlock_bh(&atchan->lock);
+	} else if (cmd == DMA_TERMINATE_ALL) {
+		struct at_desc	*desc, *_desc;
+		/*
+		 * This is only called when something went wrong elsewhere, so
+		 * we don't really care about the data. Just disable the
+		 * channel. We still have to poll the channel enable bit due
+		 * to AHB/HSB limitations.
+		 */
+		spin_lock_bh(&atchan->lock);
+
+		/* disabling channel: must also remove suspend state */
+		dma_writel(atdma, CHDR, AT_DMA_RES(chan_id) | atchan->mask);
+
+		/* confirm that this channel is disabled */
+		while (dma_readl(atdma, CHSR) & atchan->mask)
+			cpu_relax();
+
+		/* active_list entries will end up before queued entries */
+		list_splice_init(&atchan->queue, &list);
+		list_splice_init(&atchan->active_list, &list);
+
+		/* Flush all pending and queued descriptors */
+		list_for_each_entry_safe(desc, _desc, &list, desc_node)
+			atc_chain_complete(atchan, desc);
+
+		clear_bit(ATC_IS_PAUSED, &atchan->status);
+		/* if channel dedicated to cyclic operations, free it */
+		clear_bit(ATC_IS_CYCLIC, &atchan->status);
+
+		spin_unlock_bh(&atchan->lock);
+	} else {
+		return -ENXIO;
+	}
 
 	return 0;
 }
@@ -835,9 +1023,17 @@
 
 	spin_unlock_bh(&atchan->lock);
 
-	dma_set_tx_state(txstate, last_complete, last_used, 0);
-	dev_vdbg(chan2dev(chan), "tx_status: %d (d%d, u%d)\n",
-		 cookie, last_complete ? last_complete : 0,
+	if (ret != DMA_SUCCESS)
+		dma_set_tx_state(txstate, last_complete, last_used,
+			atc_first_active(atchan)->len);
+	else
+		dma_set_tx_state(txstate, last_complete, last_used, 0);
+
+	if (test_bit(ATC_IS_PAUSED, &atchan->status))
+		ret = DMA_PAUSED;
+
+	dev_vdbg(chan2dev(chan), "tx_status %d: cookie = %d (d%d, u%d)\n",
+		 ret, cookie, last_complete ? last_complete : 0,
 		 last_used ? last_used : 0);
 
 	return ret;
@@ -853,6 +1049,10 @@
 
 	dev_vdbg(chan2dev(chan), "issue_pending\n");
 
+	/* Not needed for cyclic transfers */
+	if (test_bit(ATC_IS_CYCLIC, &atchan->status))
+		return;
+
 	spin_lock_bh(&atchan->lock);
 	if (!atc_chan_is_enabled(atchan)) {
 		atc_advance_work(atchan);
@@ -959,6 +1159,7 @@
 	}
 	list_splice_init(&atchan->free_list, &list);
 	atchan->descs_allocated = 0;
+	atchan->status = 0;
 
 	dev_vdbg(chan2dev(chan), "free_chan_resources: done\n");
 }
@@ -1092,10 +1293,15 @@
 	if (dma_has_cap(DMA_MEMCPY, atdma->dma_common.cap_mask))
 		atdma->dma_common.device_prep_dma_memcpy = atc_prep_dma_memcpy;
 
-	if (dma_has_cap(DMA_SLAVE, atdma->dma_common.cap_mask)) {
+	if (dma_has_cap(DMA_SLAVE, atdma->dma_common.cap_mask))
 		atdma->dma_common.device_prep_slave_sg = atc_prep_slave_sg;
+
+	if (dma_has_cap(DMA_CYCLIC, atdma->dma_common.cap_mask))
+		atdma->dma_common.device_prep_dma_cyclic = atc_prep_dma_cyclic;
+
+	if (dma_has_cap(DMA_SLAVE, atdma->dma_common.cap_mask) ||
+	    dma_has_cap(DMA_CYCLIC, atdma->dma_common.cap_mask))
 		atdma->dma_common.device_control = atc_control;
-	}
 
 	dma_writel(atdma, EN, AT_DMA_ENABLE);
 
diff -druN linux-2.6.39-libre/drivers/dma/at_hdmac_regs.h linux-3.0-rc7-libre/drivers/dma/at_hdmac_regs.h
--- linux-2.6.39-libre/drivers/dma/at_hdmac_regs.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/dma/at_hdmac_regs.h	2011-07-11 19:51:52.000000000 -0400
@@ -103,6 +103,10 @@
 /* Bitfields in CTRLB */
 #define	ATC_SIF(i)		(0x3 & (i))	/* Src tx done via AHB-Lite Interface i */
 #define	ATC_DIF(i)		((0x3 & (i)) <<  4)	/* Dst tx done via AHB-Lite Interface i */
+				  /* Specify AHB interfaces */
+#define AT_DMA_MEM_IF		0 /* interface 0 as memory interface */
+#define AT_DMA_PER_IF		1 /* interface 1 as peripheral interface */
+
 #define	ATC_SRC_PIP		(0x1 <<  8)	/* Source Picture-in-Picture enabled */
 #define	ATC_DST_PIP		(0x1 << 12)	/* Destination Picture-in-Picture enabled */
 #define	ATC_SRC_DSCR_DIS	(0x1 << 16)	/* Src Descriptor fetch disable */
@@ -181,12 +185,23 @@
 /*--  Channels  --------------------------------------------------------*/
 
 /**
+ * atc_status - information bits stored in channel status flag
+ *
+ * Manipulated with atomic operations.
+ */
+enum atc_status {
+	ATC_IS_ERROR = 0,
+	ATC_IS_PAUSED = 1,
+	ATC_IS_CYCLIC = 24,
+};
+
+/**
  * struct at_dma_chan - internal representation of an Atmel HDMAC channel
  * @chan_common: common dmaengine channel object members
  * @device: parent device
  * @ch_regs: memory mapped register base
  * @mask: channel index in a mask
- * @error_status: transmit error status information from irq handler
+ * @status: transmit status information from irq/prep* functions
  *                to tasklet (use atomic operations)
  * @tasklet: bottom half to finish transaction work
  * @lock: serializes enqueue/dequeue operations to descriptors lists
@@ -201,7 +216,7 @@
 	struct at_dma		*device;
 	void __iomem		*ch_regs;
 	u8			mask;
-	unsigned long		error_status;
+	unsigned long		status;
 	struct tasklet_struct	tasklet;
 
 	spinlock_t		lock;
@@ -309,8 +324,8 @@
 	struct at_dma	*atdma = to_at_dma(atchan->chan_common.device);
 	u32		ebci;
 
-	/* enable interrupts on buffer chain completion & error */
-	ebci =    AT_DMA_CBTC(atchan->chan_common.chan_id)
+	/* enable interrupts on buffer transfer completion & error */
+	ebci =    AT_DMA_BTC(atchan->chan_common.chan_id)
 		| AT_DMA_ERR(atchan->chan_common.chan_id);
 	if (on)
 		dma_writel(atdma, EBCIER, ebci);
@@ -347,7 +362,12 @@
  */
 static void set_desc_eol(struct at_desc *desc)
 {
-	desc->lli.ctrlb |= ATC_SRC_DSCR_DIS | ATC_DST_DSCR_DIS;
+	u32 ctrlb = desc->lli.ctrlb;
+
+	ctrlb &= ~ATC_IEN;
+	ctrlb |= ATC_SRC_DSCR_DIS | ATC_DST_DSCR_DIS;
+
+	desc->lli.ctrlb = ctrlb;
 	desc->lli.dscr = 0;
 }
 
diff -druN linux-2.6.39-libre/drivers/dma/coh901318.c linux-3.0-rc7-libre/drivers/dma/coh901318.c
--- linux-2.6.39-libre/drivers/dma/coh901318.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/dma/coh901318.c	2011-07-11 19:51:52.000000000 -0400
@@ -1610,7 +1610,7 @@
 {
 	return platform_driver_probe(&coh901318_driver, coh901318_probe);
 }
-arch_initcall(coh901318_init);
+subsys_initcall(coh901318_init);
 
 void __exit coh901318_exit(void)
 {
diff -druN linux-2.6.39-libre/drivers/dma/dmatest.c linux-3.0-rc7-libre/drivers/dma/dmatest.c
--- linux-2.6.39-libre/drivers/dma/dmatest.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/dma/dmatest.c	2011-07-11 19:51:52.000000000 -0400
@@ -56,8 +56,8 @@
 
 static int timeout = 3000;
 module_param(timeout, uint, S_IRUGO);
-MODULE_PARM_DESC(timeout, "Transfer Timeout in msec (default: 3000), \
-		Pass -1 for infinite timeout");
+MODULE_PARM_DESC(timeout, "Transfer Timeout in msec (default: 3000), "
+		 "Pass -1 for infinite timeout");
 
 /*
  * Initialization patterns. All bytes in the source buffer has bit 7
@@ -634,5 +634,5 @@
 }
 module_exit(dmatest_exit);
 
-MODULE_AUTHOR("Haavard Skinnemoen <hskinnemoen@atmel.com>");
+MODULE_AUTHOR("Haavard Skinnemoen (Atmel)");
 MODULE_LICENSE("GPL v2");
diff -druN linux-2.6.39-libre/drivers/dma/dw_dmac.c linux-3.0-rc7-libre/drivers/dma/dw_dmac.c
--- linux-2.6.39-libre/drivers/dma/dw_dmac.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/dma/dw_dmac.c	2011-07-11 19:51:52.000000000 -0400
@@ -3,6 +3,7 @@
  * AVR32 systems.)
  *
  * Copyright (C) 2007-2008 Atmel Corporation
+ * Copyright (C) 2010-2011 ST Microelectronics
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
@@ -93,8 +94,9 @@
 	struct dw_desc *desc, *_desc;
 	struct dw_desc *ret = NULL;
 	unsigned int i = 0;
+	unsigned long flags;
 
-	spin_lock_bh(&dwc->lock);
+	spin_lock_irqsave(&dwc->lock, flags);
 	list_for_each_entry_safe(desc, _desc, &dwc->free_list, desc_node) {
 		if (async_tx_test_ack(&desc->txd)) {
 			list_del(&desc->desc_node);
@@ -104,7 +106,7 @@
 		dev_dbg(chan2dev(&dwc->chan), "desc %p not ACKed\n", desc);
 		i++;
 	}
-	spin_unlock_bh(&dwc->lock);
+	spin_unlock_irqrestore(&dwc->lock, flags);
 
 	dev_vdbg(chan2dev(&dwc->chan), "scanned %u descriptors on freelist\n", i);
 
@@ -130,12 +132,14 @@
  */
 static void dwc_desc_put(struct dw_dma_chan *dwc, struct dw_desc *desc)
 {
+	unsigned long flags;
+
 	if (desc) {
 		struct dw_desc *child;
 
 		dwc_sync_desc_for_cpu(dwc, desc);
 
-		spin_lock_bh(&dwc->lock);
+		spin_lock_irqsave(&dwc->lock, flags);
 		list_for_each_entry(child, &desc->tx_list, desc_node)
 			dev_vdbg(chan2dev(&dwc->chan),
 					"moving child desc %p to freelist\n",
@@ -143,7 +147,7 @@
 		list_splice_init(&desc->tx_list, &dwc->free_list);
 		dev_vdbg(chan2dev(&dwc->chan), "moving desc %p to freelist\n", desc);
 		list_add(&desc->desc_node, &dwc->free_list);
-		spin_unlock_bh(&dwc->lock);
+		spin_unlock_irqrestore(&dwc->lock, flags);
 	}
 }
 
@@ -195,18 +199,23 @@
 /*----------------------------------------------------------------------*/
 
 static void
-dwc_descriptor_complete(struct dw_dma_chan *dwc, struct dw_desc *desc)
+dwc_descriptor_complete(struct dw_dma_chan *dwc, struct dw_desc *desc,
+		bool callback_required)
 {
-	dma_async_tx_callback		callback;
-	void				*param;
+	dma_async_tx_callback		callback = NULL;
+	void				*param = NULL;
 	struct dma_async_tx_descriptor	*txd = &desc->txd;
 	struct dw_desc			*child;
+	unsigned long			flags;
 
 	dev_vdbg(chan2dev(&dwc->chan), "descriptor %u complete\n", txd->cookie);
 
+	spin_lock_irqsave(&dwc->lock, flags);
 	dwc->completed = txd->cookie;
-	callback = txd->callback;
-	param = txd->callback_param;
+	if (callback_required) {
+		callback = txd->callback;
+		param = txd->callback_param;
+	}
 
 	dwc_sync_desc_for_cpu(dwc, desc);
 
@@ -238,11 +247,9 @@
 		}
 	}
 
-	/*
-	 * The API requires that no submissions are done from a
-	 * callback, so we don't need to drop the lock here
-	 */
-	if (callback)
+	spin_unlock_irqrestore(&dwc->lock, flags);
+
+	if (callback_required && callback)
 		callback(param);
 }
 
@@ -250,7 +257,9 @@
 {
 	struct dw_desc *desc, *_desc;
 	LIST_HEAD(list);
+	unsigned long flags;
 
+	spin_lock_irqsave(&dwc->lock, flags);
 	if (dma_readl(dw, CH_EN) & dwc->mask) {
 		dev_err(chan2dev(&dwc->chan),
 			"BUG: XFER bit set, but channel not idle!\n");
@@ -271,8 +280,10 @@
 		dwc_dostart(dwc, dwc_first_active(dwc));
 	}
 
+	spin_unlock_irqrestore(&dwc->lock, flags);
+
 	list_for_each_entry_safe(desc, _desc, &list, desc_node)
-		dwc_descriptor_complete(dwc, desc);
+		dwc_descriptor_complete(dwc, desc, true);
 }
 
 static void dwc_scan_descriptors(struct dw_dma *dw, struct dw_dma_chan *dwc)
@@ -281,7 +292,9 @@
 	struct dw_desc *desc, *_desc;
 	struct dw_desc *child;
 	u32 status_xfer;
+	unsigned long flags;
 
+	spin_lock_irqsave(&dwc->lock, flags);
 	/*
 	 * Clear block interrupt flag before scanning so that we don't
 	 * miss any, and read LLP before RAW_XFER to ensure it is
@@ -294,30 +307,47 @@
 	if (status_xfer & dwc->mask) {
 		/* Everything we've submitted is done */
 		dma_writel(dw, CLEAR.XFER, dwc->mask);
+		spin_unlock_irqrestore(&dwc->lock, flags);
+
 		dwc_complete_all(dw, dwc);
 		return;
 	}
 
-	if (list_empty(&dwc->active_list))
+	if (list_empty(&dwc->active_list)) {
+		spin_unlock_irqrestore(&dwc->lock, flags);
 		return;
+	}
 
 	dev_vdbg(chan2dev(&dwc->chan), "scan_descriptors: llp=0x%x\n", llp);
 
 	list_for_each_entry_safe(desc, _desc, &dwc->active_list, desc_node) {
-		if (desc->lli.llp == llp)
+		/* check first descriptors addr */
+		if (desc->txd.phys == llp) {
+			spin_unlock_irqrestore(&dwc->lock, flags);
+			return;
+		}
+
+		/* check first descriptors llp */
+		if (desc->lli.llp == llp) {
 			/* This one is currently in progress */
+			spin_unlock_irqrestore(&dwc->lock, flags);
 			return;
+		}
 
 		list_for_each_entry(child, &desc->tx_list, desc_node)
-			if (child->lli.llp == llp)
+			if (child->lli.llp == llp) {
 				/* Currently in progress */
+				spin_unlock_irqrestore(&dwc->lock, flags);
 				return;
+			}
 
 		/*
 		 * No descriptors so far seem to be in progress, i.e.
 		 * this one must be done.
 		 */
-		dwc_descriptor_complete(dwc, desc);
+		spin_unlock_irqrestore(&dwc->lock, flags);
+		dwc_descriptor_complete(dwc, desc, true);
+		spin_lock_irqsave(&dwc->lock, flags);
 	}
 
 	dev_err(chan2dev(&dwc->chan),
@@ -332,6 +362,7 @@
 		list_move(dwc->queue.next, &dwc->active_list);
 		dwc_dostart(dwc, dwc_first_active(dwc));
 	}
+	spin_unlock_irqrestore(&dwc->lock, flags);
 }
 
 static void dwc_dump_lli(struct dw_dma_chan *dwc, struct dw_lli *lli)
@@ -346,9 +377,12 @@
 {
 	struct dw_desc *bad_desc;
 	struct dw_desc *child;
+	unsigned long flags;
 
 	dwc_scan_descriptors(dw, dwc);
 
+	spin_lock_irqsave(&dwc->lock, flags);
+
 	/*
 	 * The descriptor currently at the head of the active list is
 	 * borked. Since we don't have any way to report errors, we'll
@@ -378,8 +412,10 @@
 	list_for_each_entry(child, &bad_desc->tx_list, desc_node)
 		dwc_dump_lli(dwc, &child->lli);
 
+	spin_unlock_irqrestore(&dwc->lock, flags);
+
 	/* Pretend the descriptor completed successfully */
-	dwc_descriptor_complete(dwc, bad_desc);
+	dwc_descriptor_complete(dwc, bad_desc, true);
 }
 
 /* --------------------- Cyclic DMA API extensions -------------------- */
@@ -402,6 +438,8 @@
 static void dwc_handle_cyclic(struct dw_dma *dw, struct dw_dma_chan *dwc,
 		u32 status_block, u32 status_err, u32 status_xfer)
 {
+	unsigned long flags;
+
 	if (status_block & dwc->mask) {
 		void (*callback)(void *param);
 		void *callback_param;
@@ -412,11 +450,9 @@
 
 		callback = dwc->cdesc->period_callback;
 		callback_param = dwc->cdesc->period_callback_param;
-		if (callback) {
-			spin_unlock(&dwc->lock);
+
+		if (callback)
 			callback(callback_param);
-			spin_lock(&dwc->lock);
-		}
 	}
 
 	/*
@@ -430,6 +466,9 @@
 		dev_err(chan2dev(&dwc->chan), "cyclic DMA unexpected %s "
 				"interrupt, stopping DMA transfer\n",
 				status_xfer ? "xfer" : "error");
+
+		spin_lock_irqsave(&dwc->lock, flags);
+
 		dev_err(chan2dev(&dwc->chan),
 			"  SAR: 0x%x DAR: 0x%x LLP: 0x%x CTL: 0x%x:%08x\n",
 			channel_readl(dwc, SAR),
@@ -453,6 +492,8 @@
 
 		for (i = 0; i < dwc->cdesc->periods; i++)
 			dwc_dump_lli(dwc, &dwc->cdesc->desc[i]->lli);
+
+		spin_unlock_irqrestore(&dwc->lock, flags);
 	}
 }
 
@@ -476,7 +517,6 @@
 
 	for (i = 0; i < dw->dma.chancnt; i++) {
 		dwc = &dw->chan[i];
-		spin_lock(&dwc->lock);
 		if (test_bit(DW_DMA_IS_CYCLIC, &dwc->flags))
 			dwc_handle_cyclic(dw, dwc, status_block, status_err,
 					status_xfer);
@@ -484,7 +524,6 @@
 			dwc_handle_error(dw, dwc);
 		else if ((status_block | status_xfer) & (1 << i))
 			dwc_scan_descriptors(dw, dwc);
-		spin_unlock(&dwc->lock);
 	}
 
 	/*
@@ -539,8 +578,9 @@
 	struct dw_desc		*desc = txd_to_dw_desc(tx);
 	struct dw_dma_chan	*dwc = to_dw_dma_chan(tx->chan);
 	dma_cookie_t		cookie;
+	unsigned long		flags;
 
-	spin_lock_bh(&dwc->lock);
+	spin_lock_irqsave(&dwc->lock, flags);
 	cookie = dwc_assign_cookie(dwc, desc);
 
 	/*
@@ -560,7 +600,7 @@
 		list_add_tail(&desc->desc_node, &dwc->queue);
 	}
 
-	spin_unlock_bh(&dwc->lock);
+	spin_unlock_irqrestore(&dwc->lock, flags);
 
 	return cookie;
 }
@@ -689,9 +729,15 @@
 		reg = dws->tx_reg;
 		for_each_sg(sgl, sg, sg_len, i) {
 			struct dw_desc	*desc;
-			u32		len;
-			u32		mem;
+			u32		len, dlen, mem;
+
+			mem = sg_phys(sg);
+			len = sg_dma_len(sg);
+			mem_width = 2;
+			if (unlikely(mem & 3 || len & 3))
+				mem_width = 0;
 
+slave_sg_todev_fill_desc:
 			desc = dwc_desc_get(dwc);
 			if (!desc) {
 				dev_err(chan2dev(chan),
@@ -699,16 +745,19 @@
 				goto err_desc_get;
 			}
 
-			mem = sg_phys(sg);
-			len = sg_dma_len(sg);
-			mem_width = 2;
-			if (unlikely(mem & 3 || len & 3))
-				mem_width = 0;
-
 			desc->lli.sar = mem;
 			desc->lli.dar = reg;
 			desc->lli.ctllo = ctllo | DWC_CTLL_SRC_WIDTH(mem_width);
-			desc->lli.ctlhi = len >> mem_width;
+			if ((len >> mem_width) > DWC_MAX_COUNT) {
+				dlen = DWC_MAX_COUNT << mem_width;
+				mem += dlen;
+				len -= dlen;
+			} else {
+				dlen = len;
+				len = 0;
+			}
+
+			desc->lli.ctlhi = dlen >> mem_width;
 
 			if (!first) {
 				first = desc;
@@ -722,7 +771,10 @@
 						&first->tx_list);
 			}
 			prev = desc;
-			total_len += len;
+			total_len += dlen;
+
+			if (len)
+				goto slave_sg_todev_fill_desc;
 		}
 		break;
 	case DMA_FROM_DEVICE:
@@ -735,15 +787,7 @@
 		reg = dws->rx_reg;
 		for_each_sg(sgl, sg, sg_len, i) {
 			struct dw_desc	*desc;
-			u32		len;
-			u32		mem;
-
-			desc = dwc_desc_get(dwc);
-			if (!desc) {
-				dev_err(chan2dev(chan),
-					"not enough descriptors available\n");
-				goto err_desc_get;
-			}
+			u32		len, dlen, mem;
 
 			mem = sg_phys(sg);
 			len = sg_dma_len(sg);
@@ -751,10 +795,26 @@
 			if (unlikely(mem & 3 || len & 3))
 				mem_width = 0;
 
+slave_sg_fromdev_fill_desc:
+			desc = dwc_desc_get(dwc);
+			if (!desc) {
+				dev_err(chan2dev(chan),
+						"not enough descriptors available\n");
+				goto err_desc_get;
+			}
+
 			desc->lli.sar = reg;
 			desc->lli.dar = mem;
 			desc->lli.ctllo = ctllo | DWC_CTLL_DST_WIDTH(mem_width);
-			desc->lli.ctlhi = len >> reg_width;
+			if ((len >> reg_width) > DWC_MAX_COUNT) {
+				dlen = DWC_MAX_COUNT << reg_width;
+				mem += dlen;
+				len -= dlen;
+			} else {
+				dlen = len;
+				len = 0;
+			}
+			desc->lli.ctlhi = dlen >> reg_width;
 
 			if (!first) {
 				first = desc;
@@ -768,7 +828,10 @@
 						&first->tx_list);
 			}
 			prev = desc;
-			total_len += len;
+			total_len += dlen;
+
+			if (len)
+				goto slave_sg_fromdev_fill_desc;
 		}
 		break;
 	default:
@@ -799,34 +862,51 @@
 	struct dw_dma_chan	*dwc = to_dw_dma_chan(chan);
 	struct dw_dma		*dw = to_dw_dma(chan->device);
 	struct dw_desc		*desc, *_desc;
+	unsigned long		flags;
+	u32			cfglo;
 	LIST_HEAD(list);
 
-	/* Only supports DMA_TERMINATE_ALL */
-	if (cmd != DMA_TERMINATE_ALL)
-		return -ENXIO;
+	if (cmd == DMA_PAUSE) {
+		spin_lock_irqsave(&dwc->lock, flags);
 
-	/*
-	 * This is only called when something went wrong elsewhere, so
-	 * we don't really care about the data. Just disable the
-	 * channel. We still have to poll the channel enable bit due
-	 * to AHB/HSB limitations.
-	 */
-	spin_lock_bh(&dwc->lock);
+		cfglo = channel_readl(dwc, CFG_LO);
+		channel_writel(dwc, CFG_LO, cfglo | DWC_CFGL_CH_SUSP);
+		while (!(channel_readl(dwc, CFG_LO) & DWC_CFGL_FIFO_EMPTY))
+			cpu_relax();
 
-	channel_clear_bit(dw, CH_EN, dwc->mask);
+		dwc->paused = true;
+		spin_unlock_irqrestore(&dwc->lock, flags);
+	} else if (cmd == DMA_RESUME) {
+		if (!dwc->paused)
+			return 0;
 
-	while (dma_readl(dw, CH_EN) & dwc->mask)
-		cpu_relax();
+		spin_lock_irqsave(&dwc->lock, flags);
 
-	/* active_list entries will end up before queued entries */
-	list_splice_init(&dwc->queue, &list);
-	list_splice_init(&dwc->active_list, &list);
+		cfglo = channel_readl(dwc, CFG_LO);
+		channel_writel(dwc, CFG_LO, cfglo & ~DWC_CFGL_CH_SUSP);
+		dwc->paused = false;
 
-	spin_unlock_bh(&dwc->lock);
+		spin_unlock_irqrestore(&dwc->lock, flags);
+	} else if (cmd == DMA_TERMINATE_ALL) {
+		spin_lock_irqsave(&dwc->lock, flags);
 
-	/* Flush all pending and queued descriptors */
-	list_for_each_entry_safe(desc, _desc, &list, desc_node)
-		dwc_descriptor_complete(dwc, desc);
+		channel_clear_bit(dw, CH_EN, dwc->mask);
+		while (dma_readl(dw, CH_EN) & dwc->mask)
+			cpu_relax();
+
+		dwc->paused = false;
+
+		/* active_list entries will end up before queued entries */
+		list_splice_init(&dwc->queue, &list);
+		list_splice_init(&dwc->active_list, &list);
+
+		spin_unlock_irqrestore(&dwc->lock, flags);
+
+		/* Flush all pending and queued descriptors */
+		list_for_each_entry_safe(desc, _desc, &list, desc_node)
+			dwc_descriptor_complete(dwc, desc, false);
+	} else
+		return -ENXIO;
 
 	return 0;
 }
@@ -846,9 +926,7 @@
 
 	ret = dma_async_is_complete(cookie, last_complete, last_used);
 	if (ret != DMA_SUCCESS) {
-		spin_lock_bh(&dwc->lock);
 		dwc_scan_descriptors(to_dw_dma(chan->device), dwc);
-		spin_unlock_bh(&dwc->lock);
 
 		last_complete = dwc->completed;
 		last_used = chan->cookie;
@@ -856,7 +934,14 @@
 		ret = dma_async_is_complete(cookie, last_complete, last_used);
 	}
 
-	dma_set_tx_state(txstate, last_complete, last_used, 0);
+	if (ret != DMA_SUCCESS)
+		dma_set_tx_state(txstate, last_complete, last_used,
+				dwc_first_active(dwc)->len);
+	else
+		dma_set_tx_state(txstate, last_complete, last_used, 0);
+
+	if (dwc->paused)
+		return DMA_PAUSED;
 
 	return ret;
 }
@@ -865,10 +950,8 @@
 {
 	struct dw_dma_chan	*dwc = to_dw_dma_chan(chan);
 
-	spin_lock_bh(&dwc->lock);
 	if (!list_empty(&dwc->queue))
 		dwc_scan_descriptors(to_dw_dma(chan->device), dwc);
-	spin_unlock_bh(&dwc->lock);
 }
 
 static int dwc_alloc_chan_resources(struct dma_chan *chan)
@@ -880,6 +963,7 @@
 	int			i;
 	u32			cfghi;
 	u32			cfglo;
+	unsigned long		flags;
 
 	dev_vdbg(chan2dev(chan), "alloc_chan_resources\n");
 
@@ -917,16 +1001,16 @@
 	 * doesn't mean what you think it means), and status writeback.
 	 */
 
-	spin_lock_bh(&dwc->lock);
+	spin_lock_irqsave(&dwc->lock, flags);
 	i = dwc->descs_allocated;
 	while (dwc->descs_allocated < NR_DESCS_PER_CHANNEL) {
-		spin_unlock_bh(&dwc->lock);
+		spin_unlock_irqrestore(&dwc->lock, flags);
 
 		desc = kzalloc(sizeof(struct dw_desc), GFP_KERNEL);
 		if (!desc) {
 			dev_info(chan2dev(chan),
 				"only allocated %d descriptors\n", i);
-			spin_lock_bh(&dwc->lock);
+			spin_lock_irqsave(&dwc->lock, flags);
 			break;
 		}
 
@@ -938,7 +1022,7 @@
 				sizeof(desc->lli), DMA_TO_DEVICE);
 		dwc_desc_put(dwc, desc);
 
-		spin_lock_bh(&dwc->lock);
+		spin_lock_irqsave(&dwc->lock, flags);
 		i = ++dwc->descs_allocated;
 	}
 
@@ -947,7 +1031,7 @@
 	channel_set_bit(dw, MASK.BLOCK, dwc->mask);
 	channel_set_bit(dw, MASK.ERROR, dwc->mask);
 
-	spin_unlock_bh(&dwc->lock);
+	spin_unlock_irqrestore(&dwc->lock, flags);
 
 	dev_dbg(chan2dev(chan),
 		"alloc_chan_resources allocated %d descriptors\n", i);
@@ -960,6 +1044,7 @@
 	struct dw_dma_chan	*dwc = to_dw_dma_chan(chan);
 	struct dw_dma		*dw = to_dw_dma(chan->device);
 	struct dw_desc		*desc, *_desc;
+	unsigned long		flags;
 	LIST_HEAD(list);
 
 	dev_dbg(chan2dev(chan), "free_chan_resources (descs allocated=%u)\n",
@@ -970,7 +1055,7 @@
 	BUG_ON(!list_empty(&dwc->queue));
 	BUG_ON(dma_readl(to_dw_dma(chan->device), CH_EN) & dwc->mask);
 
-	spin_lock_bh(&dwc->lock);
+	spin_lock_irqsave(&dwc->lock, flags);
 	list_splice_init(&dwc->free_list, &list);
 	dwc->descs_allocated = 0;
 
@@ -979,7 +1064,7 @@
 	channel_clear_bit(dw, MASK.BLOCK, dwc->mask);
 	channel_clear_bit(dw, MASK.ERROR, dwc->mask);
 
-	spin_unlock_bh(&dwc->lock);
+	spin_unlock_irqrestore(&dwc->lock, flags);
 
 	list_for_each_entry_safe(desc, _desc, &list, desc_node) {
 		dev_vdbg(chan2dev(chan), "  freeing descriptor %p\n", desc);
@@ -1004,13 +1089,14 @@
 {
 	struct dw_dma_chan	*dwc = to_dw_dma_chan(chan);
 	struct dw_dma		*dw = to_dw_dma(dwc->chan.device);
+	unsigned long		flags;
 
 	if (!test_bit(DW_DMA_IS_CYCLIC, &dwc->flags)) {
 		dev_err(chan2dev(&dwc->chan), "missing prep for cyclic DMA\n");
 		return -ENODEV;
 	}
 
-	spin_lock(&dwc->lock);
+	spin_lock_irqsave(&dwc->lock, flags);
 
 	/* assert channel is idle */
 	if (dma_readl(dw, CH_EN) & dwc->mask) {
@@ -1023,7 +1109,7 @@
 			channel_readl(dwc, LLP),
 			channel_readl(dwc, CTL_HI),
 			channel_readl(dwc, CTL_LO));
-		spin_unlock(&dwc->lock);
+		spin_unlock_irqrestore(&dwc->lock, flags);
 		return -EBUSY;
 	}
 
@@ -1038,7 +1124,7 @@
 
 	channel_set_bit(dw, CH_EN, dwc->mask);
 
-	spin_unlock(&dwc->lock);
+	spin_unlock_irqrestore(&dwc->lock, flags);
 
 	return 0;
 }
@@ -1054,14 +1140,15 @@
 {
 	struct dw_dma_chan	*dwc = to_dw_dma_chan(chan);
 	struct dw_dma		*dw = to_dw_dma(dwc->chan.device);
+	unsigned long		flags;
 
-	spin_lock(&dwc->lock);
+	spin_lock_irqsave(&dwc->lock, flags);
 
 	channel_clear_bit(dw, CH_EN, dwc->mask);
 	while (dma_readl(dw, CH_EN) & dwc->mask)
 		cpu_relax();
 
-	spin_unlock(&dwc->lock);
+	spin_unlock_irqrestore(&dwc->lock, flags);
 }
 EXPORT_SYMBOL(dw_dma_cyclic_stop);
 
@@ -1090,17 +1177,18 @@
 	unsigned int			reg_width;
 	unsigned int			periods;
 	unsigned int			i;
+	unsigned long			flags;
 
-	spin_lock_bh(&dwc->lock);
+	spin_lock_irqsave(&dwc->lock, flags);
 	if (!list_empty(&dwc->queue) || !list_empty(&dwc->active_list)) {
-		spin_unlock_bh(&dwc->lock);
+		spin_unlock_irqrestore(&dwc->lock, flags);
 		dev_dbg(chan2dev(&dwc->chan),
 				"queue and/or active list are not empty\n");
 		return ERR_PTR(-EBUSY);
 	}
 
 	was_cyclic = test_and_set_bit(DW_DMA_IS_CYCLIC, &dwc->flags);
-	spin_unlock_bh(&dwc->lock);
+	spin_unlock_irqrestore(&dwc->lock, flags);
 	if (was_cyclic) {
 		dev_dbg(chan2dev(&dwc->chan),
 				"channel already prepared for cyclic DMA\n");
@@ -1214,13 +1302,14 @@
 	struct dw_dma		*dw = to_dw_dma(dwc->chan.device);
 	struct dw_cyclic_desc	*cdesc = dwc->cdesc;
 	int			i;
+	unsigned long		flags;
 
 	dev_dbg(chan2dev(&dwc->chan), "cyclic free\n");
 
 	if (!cdesc)
 		return;
 
-	spin_lock_bh(&dwc->lock);
+	spin_lock_irqsave(&dwc->lock, flags);
 
 	channel_clear_bit(dw, CH_EN, dwc->mask);
 	while (dma_readl(dw, CH_EN) & dwc->mask)
@@ -1230,7 +1319,7 @@
 	dma_writel(dw, CLEAR.ERROR, dwc->mask);
 	dma_writel(dw, CLEAR.XFER, dwc->mask);
 
-	spin_unlock_bh(&dwc->lock);
+	spin_unlock_irqrestore(&dwc->lock, flags);
 
 	for (i = 0; i < cdesc->periods; i++)
 		dwc_desc_put(dwc, cdesc->desc[i]);
@@ -1486,4 +1575,5 @@
 
 MODULE_LICENSE("GPL v2");
 MODULE_DESCRIPTION("Synopsys DesignWare DMA Controller driver");
-MODULE_AUTHOR("Haavard Skinnemoen <haavard.skinnemoen@atmel.com>");
+MODULE_AUTHOR("Haavard Skinnemoen (Atmel)");
+MODULE_AUTHOR("Viresh Kumar <viresh.kumar@st.com>");
diff -druN linux-2.6.39-libre/drivers/dma/dw_dmac_regs.h linux-3.0-rc7-libre/drivers/dma/dw_dmac_regs.h
--- linux-2.6.39-libre/drivers/dma/dw_dmac_regs.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/dma/dw_dmac_regs.h	2011-07-11 19:51:52.000000000 -0400
@@ -2,6 +2,7 @@
  * Driver for the Synopsys DesignWare AHB DMA Controller
  *
  * Copyright (C) 2005-2007 Atmel Corporation
+ * Copyright (C) 2010-2011 ST Microelectronics
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
@@ -138,6 +139,7 @@
 	void __iomem		*ch_regs;
 	u8			mask;
 	u8			priority;
+	bool			paused;
 
 	spinlock_t		lock;
 
diff -druN linux-2.6.39-libre/drivers/dma/intel_mid_dma.c linux-3.0-rc7-libre/drivers/dma/intel_mid_dma.c
--- linux-2.6.39-libre/drivers/dma/intel_mid_dma.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/dma/intel_mid_dma.c	2011-07-11 19:51:52.000000000 -0400
@@ -1292,8 +1292,7 @@
 	if (err)
 		goto err_dma;
 
-	pm_runtime_set_active(&pdev->dev);
-	pm_runtime_enable(&pdev->dev);
+	pm_runtime_put_noidle(&pdev->dev);
 	pm_runtime_allow(&pdev->dev);
 	return 0;
 
@@ -1322,6 +1321,9 @@
 static void __devexit intel_mid_dma_remove(struct pci_dev *pdev)
 {
 	struct middma_device *device = pci_get_drvdata(pdev);
+
+	pm_runtime_get_noresume(&pdev->dev);
+	pm_runtime_forbid(&pdev->dev);
 	middma_shutdown(pdev);
 	pci_dev_put(pdev);
 	kfree(device);
@@ -1385,13 +1387,20 @@
 static int dma_runtime_suspend(struct device *dev)
 {
 	struct pci_dev *pci_dev = to_pci_dev(dev);
-	return dma_suspend(pci_dev, PMSG_SUSPEND);
+	struct middma_device *device = pci_get_drvdata(pci_dev);
+
+	device->state = SUSPENDED;
+	return 0;
 }
 
 static int dma_runtime_resume(struct device *dev)
 {
 	struct pci_dev *pci_dev = to_pci_dev(dev);
-	return dma_resume(pci_dev);
+	struct middma_device *device = pci_get_drvdata(pci_dev);
+
+	device->state = RUNNING;
+	iowrite32(REG_BIT0, device->dma_base + DMA_CFG);
+	return 0;
 }
 
 static int dma_runtime_idle(struct device *dev)
diff -druN linux-2.6.39-libre/drivers/dma/ioat/dma.c linux-3.0-rc7-libre/drivers/dma/ioat/dma.c
--- linux-2.6.39-libre/drivers/dma/ioat/dma.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/dma/ioat/dma.c	2011-07-11 19:51:52.000000000 -0400
@@ -34,6 +34,7 @@
 #include <linux/delay.h>
 #include <linux/dma-mapping.h>
 #include <linux/workqueue.h>
+#include <linux/prefetch.h>
 #include <linux/i7300_idle.h>
 #include "dma.h"
 #include "registers.h"
diff -druN linux-2.6.39-libre/drivers/dma/ioat/dma_v2.c linux-3.0-rc7-libre/drivers/dma/ioat/dma_v2.c
--- linux-2.6.39-libre/drivers/dma/ioat/dma_v2.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/dma/ioat/dma_v2.c	2011-07-11 19:51:52.000000000 -0400
@@ -34,6 +34,7 @@
 #include <linux/delay.h>
 #include <linux/dma-mapping.h>
 #include <linux/workqueue.h>
+#include <linux/prefetch.h>
 #include <linux/i7300_idle.h>
 #include "dma.h"
 #include "dma_v2.h"
@@ -507,6 +508,7 @@
 	struct ioat_ring_ent **ring;
 	u64 status;
 	int order;
+	int i = 0;
 
 	/* have we already been set up? */
 	if (ioat->ring)
@@ -547,8 +549,11 @@
 	ioat2_start_null_desc(ioat);
 
 	/* check that we got off the ground */
-	udelay(5);
-	status = ioat_chansts(chan);
+	do {
+		udelay(1);
+		status = ioat_chansts(chan);
+	} while (i++ < 20 && !is_ioat_active(status) && !is_ioat_idle(status));
+
 	if (is_ioat_active(status) || is_ioat_idle(status)) {
 		set_bit(IOAT_RUN, &chan->state);
 		return 1 << ioat->alloc_order;
diff -druN linux-2.6.39-libre/drivers/dma/ioat/dma_v3.c linux-3.0-rc7-libre/drivers/dma/ioat/dma_v3.c
--- linux-2.6.39-libre/drivers/dma/ioat/dma_v3.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/dma/ioat/dma_v3.c	2011-07-11 19:51:52.000000000 -0400
@@ -60,6 +60,7 @@
 #include <linux/gfp.h>
 #include <linux/dmaengine.h>
 #include <linux/dma-mapping.h>
+#include <linux/prefetch.h>
 #include "registers.h"
 #include "hw.h"
 #include "dma.h"
diff -druN linux-2.6.39-libre/drivers/dma/iop-adma.c linux-3.0-rc7-libre/drivers/dma/iop-adma.c
--- linux-2.6.39-libre/drivers/dma/iop-adma.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/dma/iop-adma.c	2011-07-11 19:51:52.000000000 -0400
@@ -619,7 +619,7 @@
 
 	if (unlikely(!len))
 		return NULL;
-	BUG_ON(unlikely(len > IOP_ADMA_MAX_BYTE_COUNT));
+	BUG_ON(len > IOP_ADMA_MAX_BYTE_COUNT);
 
 	dev_dbg(iop_chan->device->common.dev, "%s len: %u\n",
 		__func__, len);
@@ -652,7 +652,7 @@
 
 	if (unlikely(!len))
 		return NULL;
-	BUG_ON(unlikely(len > IOP_ADMA_MAX_BYTE_COUNT));
+	BUG_ON(len > IOP_ADMA_MAX_BYTE_COUNT);
 
 	dev_dbg(iop_chan->device->common.dev, "%s len: %u\n",
 		__func__, len);
@@ -686,7 +686,7 @@
 
 	if (unlikely(!len))
 		return NULL;
-	BUG_ON(unlikely(len > IOP_ADMA_XOR_MAX_BYTE_COUNT));
+	BUG_ON(len > IOP_ADMA_XOR_MAX_BYTE_COUNT);
 
 	dev_dbg(iop_chan->device->common.dev,
 		"%s src_cnt: %d len: %u flags: %lx\n",
diff -druN linux-2.6.39-libre/drivers/dma/Kconfig linux-3.0-rc7-libre/drivers/dma/Kconfig
--- linux-2.6.39-libre/drivers/dma/Kconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/dma/Kconfig	2011-07-11 19:51:52.000000000 -0400
@@ -200,16 +200,18 @@
 	  platform_data for a dma-pl330 device.
 
 config PCH_DMA
-	tristate "Intel EG20T PCH / OKI SEMICONDUCTOR ML7213 IOH DMA support"
+	tristate "Intel EG20T PCH / OKI Semi IOH(ML7213/ML7223) DMA support"
 	depends on PCI && X86
 	select DMA_ENGINE
 	help
 	  Enable support for Intel EG20T PCH DMA engine.
 
-	  This driver also can be used for OKI SEMICONDUCTOR ML7213 IOH(Input/
-	  Output Hub) which is for IVI(In-Vehicle Infotainment) use.
-	  ML7213 is companion chip for Intel Atom E6xx series.
-	  ML7213 is completely compatible for Intel EG20T PCH.
+	  This driver also can be used for OKI SEMICONDUCTOR IOH(Input/
+	  Output Hub), ML7213 and ML7223.
+	  ML7213 IOH is for IVI(In-Vehicle Infotainment) use and ML7223 IOH is
+	  for MP(Media Phone) use.
+	  ML7213/ML7223 is companion chip for Intel Atom E6xx series.
+	  ML7213/ML7223 is completely compatible for Intel EG20T PCH.
 
 config IMX_SDMA
 	tristate "i.MX SDMA support"
diff -druN linux-2.6.39-libre/drivers/dma/mv_xor.c linux-3.0-rc7-libre/drivers/dma/mv_xor.c
--- linux-2.6.39-libre/drivers/dma/mv_xor.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/dma/mv_xor.c	2011-07-11 19:51:52.000000000 -0400
@@ -671,7 +671,7 @@
 	if (unlikely(len < MV_XOR_MIN_BYTE_COUNT))
 		return NULL;
 
-	BUG_ON(unlikely(len > MV_XOR_MAX_BYTE_COUNT));
+	BUG_ON(len > MV_XOR_MAX_BYTE_COUNT);
 
 	spin_lock_bh(&mv_chan->lock);
 	slot_cnt = mv_chan_memcpy_slot_count(len);
@@ -710,7 +710,7 @@
 	if (unlikely(len < MV_XOR_MIN_BYTE_COUNT))
 		return NULL;
 
-	BUG_ON(unlikely(len > MV_XOR_MAX_BYTE_COUNT));
+	BUG_ON(len > MV_XOR_MAX_BYTE_COUNT);
 
 	spin_lock_bh(&mv_chan->lock);
 	slot_cnt = mv_chan_memset_slot_count(len);
@@ -744,7 +744,7 @@
 	if (unlikely(len < MV_XOR_MIN_BYTE_COUNT))
 		return NULL;
 
-	BUG_ON(unlikely(len > MV_XOR_MAX_BYTE_COUNT));
+	BUG_ON(len > MV_XOR_MAX_BYTE_COUNT);
 
 	dev_dbg(mv_chan->device->common.dev,
 		"%s src_cnt: %d len: dest %x %u flags: %ld\n",
diff -druN linux-2.6.39-libre/drivers/dma/pch_dma.c linux-3.0-rc7-libre/drivers/dma/pch_dma.c
--- linux-2.6.39-libre/drivers/dma/pch_dma.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/dma/pch_dma.c	2011-07-11 19:51:52.000000000 -0400
@@ -77,10 +77,10 @@
 	u32	dma_ctl0;
 	u32	dma_ctl1;
 	u32	dma_ctl2;
-	u32	reserved1;
+	u32	dma_ctl3;
 	u32	dma_sts0;
 	u32	dma_sts1;
-	u32	reserved2;
+	u32	dma_sts2;
 	u32	reserved3;
 	struct pch_dma_desc_regs desc[MAX_CHAN_NR];
 };
@@ -130,6 +130,7 @@
 #define PCH_DMA_CTL0	0x00
 #define PCH_DMA_CTL1	0x04
 #define PCH_DMA_CTL2	0x08
+#define PCH_DMA_CTL3	0x0C
 #define PCH_DMA_STS0	0x10
 #define PCH_DMA_STS1	0x14
 
@@ -138,7 +139,8 @@
 #define dma_writel(pd, name, val) \
 	writel((val), (pd)->membase + PCH_DMA_##name)
 
-static inline struct pch_dma_desc *to_pd_desc(struct dma_async_tx_descriptor *txd)
+static inline
+struct pch_dma_desc *to_pd_desc(struct dma_async_tx_descriptor *txd)
 {
 	return container_of(txd, struct pch_dma_desc, txd);
 }
@@ -163,13 +165,15 @@
 	return chan->dev->device.parent;
 }
 
-static inline struct pch_dma_desc *pdc_first_active(struct pch_dma_chan *pd_chan)
+static inline
+struct pch_dma_desc *pdc_first_active(struct pch_dma_chan *pd_chan)
 {
 	return list_first_entry(&pd_chan->active_list,
 				struct pch_dma_desc, desc_node);
 }
 
-static inline struct pch_dma_desc *pdc_first_queued(struct pch_dma_chan *pd_chan)
+static inline
+struct pch_dma_desc *pdc_first_queued(struct pch_dma_chan *pd_chan)
 {
 	return list_first_entry(&pd_chan->queue,
 				struct pch_dma_desc, desc_node);
@@ -199,16 +203,30 @@
 	struct pch_dma *pd = to_pd(chan->device);
 	u32 val;
 
-	val = dma_readl(pd, CTL0);
+	if (chan->chan_id < 8) {
+		val = dma_readl(pd, CTL0);
 
-	if (pd_chan->dir == DMA_TO_DEVICE)
-		val |= 0x1 << (DMA_CTL0_BITS_PER_CH * chan->chan_id +
-			       DMA_CTL0_DIR_SHIFT_BITS);
-	else
-		val &= ~(0x1 << (DMA_CTL0_BITS_PER_CH * chan->chan_id +
-				 DMA_CTL0_DIR_SHIFT_BITS));
+		if (pd_chan->dir == DMA_TO_DEVICE)
+			val |= 0x1 << (DMA_CTL0_BITS_PER_CH * chan->chan_id +
+				       DMA_CTL0_DIR_SHIFT_BITS);
+		else
+			val &= ~(0x1 << (DMA_CTL0_BITS_PER_CH * chan->chan_id +
+					 DMA_CTL0_DIR_SHIFT_BITS));
 
-	dma_writel(pd, CTL0, val);
+		dma_writel(pd, CTL0, val);
+	} else {
+		int ch = chan->chan_id - 8; /* ch8-->0 ch9-->1 ... ch11->3 */
+		val = dma_readl(pd, CTL3);
+
+		if (pd_chan->dir == DMA_TO_DEVICE)
+			val |= 0x1 << (DMA_CTL0_BITS_PER_CH * ch +
+				       DMA_CTL0_DIR_SHIFT_BITS);
+		else
+			val &= ~(0x1 << (DMA_CTL0_BITS_PER_CH * ch +
+					 DMA_CTL0_DIR_SHIFT_BITS));
+
+		dma_writel(pd, CTL3, val);
+	}
 
 	dev_dbg(chan2dev(chan), "pdc_set_dir: chan %d -> %x\n",
 		chan->chan_id, val);
@@ -219,13 +237,26 @@
 	struct pch_dma *pd = to_pd(chan->device);
 	u32 val;
 
-	val = dma_readl(pd, CTL0);
+	if (chan->chan_id < 8) {
+		val = dma_readl(pd, CTL0);
 
-	val &= ~(DMA_CTL0_MODE_MASK_BITS <<
-		(DMA_CTL0_BITS_PER_CH * chan->chan_id));
-	val |= mode << (DMA_CTL0_BITS_PER_CH * chan->chan_id);
+		val &= ~(DMA_CTL0_MODE_MASK_BITS <<
+			(DMA_CTL0_BITS_PER_CH * chan->chan_id));
+		val |= mode << (DMA_CTL0_BITS_PER_CH * chan->chan_id);
 
-	dma_writel(pd, CTL0, val);
+		dma_writel(pd, CTL0, val);
+	} else {
+		int ch = chan->chan_id - 8; /* ch8-->0 ch9-->1 ... ch11->3 */
+
+		val = dma_readl(pd, CTL3);
+
+		val &= ~(DMA_CTL0_MODE_MASK_BITS <<
+			(DMA_CTL0_BITS_PER_CH * ch));
+		val |= mode << (DMA_CTL0_BITS_PER_CH * ch);
+
+		dma_writel(pd, CTL3, val);
+
+	}
 
 	dev_dbg(chan2dev(chan), "pdc_set_mode: chan %d -> %x\n",
 		chan->chan_id, val);
@@ -251,9 +282,6 @@
 
 static void pdc_dostart(struct pch_dma_chan *pd_chan, struct pch_dma_desc* desc)
 {
-	struct pch_dma *pd = to_pd(pd_chan->chan.device);
-	u32 val;
-
 	if (!pdc_is_idle(pd_chan)) {
 		dev_err(chan2dev(&pd_chan->chan),
 			"BUG: Attempt to start non-idle channel\n");
@@ -279,10 +307,6 @@
 		channel_writel(pd_chan, NEXT, desc->txd.phys);
 		pdc_set_mode(&pd_chan->chan, DMA_CTL0_SG);
 	}
-
-	val = dma_readl(pd, CTL2);
-	val |= 1 << (DMA_CTL2_START_SHIFT_BITS + pd_chan->chan.chan_id);
-	dma_writel(pd, CTL2, val);
 }
 
 static void pdc_chain_complete(struct pch_dma_chan *pd_chan,
@@ -403,7 +427,7 @@
 {
 	struct pch_dma_desc *desc, *_d;
 	struct pch_dma_desc *ret = NULL;
-	int i;
+	int i = 0;
 
 	spin_lock(&pd_chan->lock);
 	list_for_each_entry_safe(desc, _d, &pd_chan->free_list, desc_node) {
@@ -478,7 +502,6 @@
 	spin_unlock_bh(&pd_chan->lock);
 
 	pdc_enable_irq(chan, 1);
-	pdc_set_dir(chan);
 
 	return pd_chan->descs_allocated;
 }
@@ -561,6 +584,9 @@
 	else
 		return NULL;
 
+	pd_chan->dir = direction;
+	pdc_set_dir(chan);
+
 	for_each_sg(sgl, sg, sg_len, i) {
 		desc = pdc_desc_get(pd_chan);
 
@@ -703,6 +729,7 @@
 	pd->regs.dma_ctl0 = dma_readl(pd, CTL0);
 	pd->regs.dma_ctl1 = dma_readl(pd, CTL1);
 	pd->regs.dma_ctl2 = dma_readl(pd, CTL2);
+	pd->regs.dma_ctl3 = dma_readl(pd, CTL3);
 
 	list_for_each_entry_safe(chan, _c, &pd->dma.channels, device_node) {
 		pd_chan = to_pd_chan(chan);
@@ -725,6 +752,7 @@
 	dma_writel(pd, CTL0, pd->regs.dma_ctl0);
 	dma_writel(pd, CTL1, pd->regs.dma_ctl1);
 	dma_writel(pd, CTL2, pd->regs.dma_ctl2);
+	dma_writel(pd, CTL3, pd->regs.dma_ctl3);
 
 	list_for_each_entry_safe(chan, _c, &pd->dma.channels, device_node) {
 		pd_chan = to_pd_chan(chan);
@@ -850,8 +878,6 @@
 
 		pd_chan->membase = &regs->desc[i];
 
-		pd_chan->dir = (i % 2) ? DMA_FROM_DEVICE : DMA_TO_DEVICE;
-
 		spin_lock_init(&pd_chan->lock);
 
 		INIT_LIST_HEAD(&pd_chan->active_list);
@@ -929,13 +955,23 @@
 #define PCI_DEVICE_ID_ML7213_DMA1_8CH	0x8026
 #define PCI_DEVICE_ID_ML7213_DMA2_8CH	0x802B
 #define PCI_DEVICE_ID_ML7213_DMA3_4CH	0x8034
+#define PCI_DEVICE_ID_ML7213_DMA4_12CH	0x8032
+#define PCI_DEVICE_ID_ML7223_DMA1_4CH	0x800B
+#define PCI_DEVICE_ID_ML7223_DMA2_4CH	0x800E
+#define PCI_DEVICE_ID_ML7223_DMA3_4CH	0x8017
+#define PCI_DEVICE_ID_ML7223_DMA4_4CH	0x803B
 
-static const struct pci_device_id pch_dma_id_table[] = {
+DEFINE_PCI_DEVICE_TABLE(pch_dma_id_table) = {
 	{ PCI_VDEVICE(INTEL, PCI_DEVICE_ID_EG20T_PCH_DMA_8CH), 8 },
 	{ PCI_VDEVICE(INTEL, PCI_DEVICE_ID_EG20T_PCH_DMA_4CH), 4 },
 	{ PCI_VDEVICE(ROHM, PCI_DEVICE_ID_ML7213_DMA1_8CH), 8}, /* UART Video */
 	{ PCI_VDEVICE(ROHM, PCI_DEVICE_ID_ML7213_DMA2_8CH), 8}, /* PCMIF SPI */
 	{ PCI_VDEVICE(ROHM, PCI_DEVICE_ID_ML7213_DMA3_4CH), 4}, /* FPGA */
+	{ PCI_VDEVICE(ROHM, PCI_DEVICE_ID_ML7213_DMA4_12CH), 12}, /* I2S */
+	{ PCI_VDEVICE(ROHM, PCI_DEVICE_ID_ML7223_DMA1_4CH), 4}, /* UART */
+	{ PCI_VDEVICE(ROHM, PCI_DEVICE_ID_ML7223_DMA2_4CH), 4}, /* Video SPI */
+	{ PCI_VDEVICE(ROHM, PCI_DEVICE_ID_ML7223_DMA3_4CH), 4}, /* Security */
+	{ PCI_VDEVICE(ROHM, PCI_DEVICE_ID_ML7223_DMA4_4CH), 4}, /* FPGA */
 	{ 0, },
 };
 
diff -druN linux-2.6.39-libre/drivers/dma/ppc4xx/adma.c linux-3.0-rc7-libre/drivers/dma/ppc4xx/adma.c
--- linux-2.6.39-libre/drivers/dma/ppc4xx/adma.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/dma/ppc4xx/adma.c	2011-07-11 19:51:52.000000000 -0400
@@ -2313,7 +2313,7 @@
 	if (unlikely(!len))
 		return NULL;
 
-	BUG_ON(unlikely(len > PPC440SPE_ADMA_DMA_MAX_BYTE_COUNT));
+	BUG_ON(len > PPC440SPE_ADMA_DMA_MAX_BYTE_COUNT);
 
 	spin_lock_bh(&ppc440spe_chan->lock);
 
@@ -2354,7 +2354,7 @@
 	if (unlikely(!len))
 		return NULL;
 
-	BUG_ON(unlikely(len > PPC440SPE_ADMA_DMA_MAX_BYTE_COUNT));
+	BUG_ON(len > PPC440SPE_ADMA_DMA_MAX_BYTE_COUNT);
 
 	spin_lock_bh(&ppc440spe_chan->lock);
 
@@ -2397,7 +2397,7 @@
 				     dma_dest, dma_src, src_cnt));
 	if (unlikely(!len))
 		return NULL;
-	BUG_ON(unlikely(len > PPC440SPE_ADMA_XOR_MAX_BYTE_COUNT));
+	BUG_ON(len > PPC440SPE_ADMA_XOR_MAX_BYTE_COUNT);
 
 	dev_dbg(ppc440spe_chan->device->common.dev,
 		"ppc440spe adma%d: %s src_cnt: %d len: %u int_en: %d\n",
@@ -2887,7 +2887,7 @@
 	ADMA_LL_DBG(prep_dma_pq_dbg(ppc440spe_chan->device->id,
 				    dst, src, src_cnt));
 	BUG_ON(!len);
-	BUG_ON(unlikely(len > PPC440SPE_ADMA_XOR_MAX_BYTE_COUNT));
+	BUG_ON(len > PPC440SPE_ADMA_XOR_MAX_BYTE_COUNT);
 	BUG_ON(!src_cnt);
 
 	if (src_cnt == 1 && dst[1] == src[0]) {
diff -druN linux-2.6.39-libre/drivers/dma/shdma.c linux-3.0-rc7-libre/drivers/dma/shdma.c
--- linux-2.6.39-libre/drivers/dma/shdma.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/dma/shdma.c	2011-07-11 19:51:52.000000000 -0400
@@ -48,7 +48,7 @@
 
 /*
  * Used for write-side mutual exclusion for the global device list,
- * read-side synchronization by way of RCU.
+ * read-side synchronization by way of RCU, and per-controller data.
  */
 static DEFINE_SPINLOCK(sh_dmae_lock);
 static LIST_HEAD(sh_dmae_devices);
@@ -85,22 +85,35 @@
  */
 static void sh_dmae_ctl_stop(struct sh_dmae_device *shdev)
 {
-	unsigned short dmaor = dmaor_read(shdev);
+	unsigned short dmaor;
+	unsigned long flags;
+
+	spin_lock_irqsave(&sh_dmae_lock, flags);
 
+	dmaor = dmaor_read(shdev);
 	dmaor_write(shdev, dmaor & ~(DMAOR_NMIF | DMAOR_AE | DMAOR_DME));
+
+	spin_unlock_irqrestore(&sh_dmae_lock, flags);
 }
 
 static int sh_dmae_rst(struct sh_dmae_device *shdev)
 {
 	unsigned short dmaor;
+	unsigned long flags;
 
-	sh_dmae_ctl_stop(shdev);
-	dmaor = dmaor_read(shdev) | shdev->pdata->dmaor_init;
+	spin_lock_irqsave(&sh_dmae_lock, flags);
 
-	dmaor_write(shdev, dmaor);
-	if (dmaor_read(shdev) & (DMAOR_AE | DMAOR_NMIF)) {
-		pr_warning("dma-sh: Can't initialize DMAOR.\n");
-		return -EINVAL;
+	dmaor = dmaor_read(shdev) & ~(DMAOR_NMIF | DMAOR_AE | DMAOR_DME);
+
+	dmaor_write(shdev, dmaor | shdev->pdata->dmaor_init);
+
+	dmaor = dmaor_read(shdev);
+
+	spin_unlock_irqrestore(&sh_dmae_lock, flags);
+
+	if (dmaor & (DMAOR_AE | DMAOR_NMIF)) {
+		dev_warn(shdev->common.dev, "Can't initialize DMAOR.\n");
+		return -EIO;
 	}
 	return 0;
 }
@@ -184,7 +197,7 @@
 
 static int dmae_set_chcr(struct sh_dmae_chan *sh_chan, u32 val)
 {
-	/* When DMA was working, can not set data to CHCR */
+	/* If DMA is active, cannot set CHCR. TODO: remove this superfluous check */
 	if (dmae_is_busy(sh_chan))
 		return -EBUSY;
 
@@ -200,12 +213,17 @@
 						struct sh_dmae_device, common);
 	struct sh_dmae_pdata *pdata = shdev->pdata;
 	const struct sh_dmae_channel *chan_pdata = &pdata->channel[sh_chan->id];
-	u16 __iomem *addr = shdev->dmars + chan_pdata->dmars / sizeof(u16);
+	u16 __iomem *addr = shdev->dmars;
 	int shift = chan_pdata->dmars_bit;
 
 	if (dmae_is_busy(sh_chan))
 		return -EBUSY;
 
+	/* in the case of a missing DMARS resource use first memory window */
+	if (!addr)
+		addr = (u16 __iomem *)shdev->chan_reg;
+	addr += chan_pdata->dmars / sizeof(u16);
+
 	__raw_writew((__raw_readw(addr) & (0xff00 >> shift)) | (val << shift),
 		     addr);
 
@@ -325,7 +343,7 @@
 
 		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) {
+	} else {
 		dmae_init(sh_chan);
 	}
 
@@ -374,7 +392,12 @@
 	LIST_HEAD(list);
 	int descs = sh_chan->descs_allocated;
 
+	/* Protect against ISR */
+	spin_lock_irq(&sh_chan->desc_lock);
 	dmae_halt(sh_chan);
+	spin_unlock_irq(&sh_chan->desc_lock);
+
+	/* Now no new interrupts will occur */
 
 	/* Prepared and not submitted descriptors can still be on the queue */
 	if (!list_empty(&sh_chan->ld_queue))
@@ -384,6 +407,7 @@
 		/* The caller is holding dma_list_mutex */
 		struct sh_dmae_slave *param = chan->private;
 		clear_bit(param->slave_id, sh_dmae_slave_used);
+		chan->private = NULL;
 	}
 
 	spin_lock_bh(&sh_chan->desc_lock);
@@ -563,8 +587,6 @@
 	if (!chan || !len)
 		return NULL;
 
-	chan->private = NULL;
-
 	sh_chan = to_sh_chan(chan);
 
 	sg_init_table(&sg, 1);
@@ -620,9 +642,9 @@
 	if (!chan)
 		return -EINVAL;
 
+	spin_lock_bh(&sh_chan->desc_lock);
 	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,
@@ -716,6 +738,14 @@
 			list_move(&desc->node, &sh_chan->ld_free);
 		}
 	}
+
+	if (all && !callback)
+		/*
+		 * Terminating and the loop completed normally: forgive
+		 * uncompleted cookies
+		 */
+		sh_chan->completed_cookie = sh_chan->common.cookie;
+
 	spin_unlock_bh(&sh_chan->desc_lock);
 
 	if (callback)
@@ -733,10 +763,6 @@
 {
 	while (__ld_cleanup(sh_chan, all))
 		;
-
-	if (all)
-		/* Terminating - forgive uncompleted cookies */
-		sh_chan->completed_cookie = sh_chan->common.cookie;
 }
 
 static void sh_chan_xfer_ld_queue(struct sh_dmae_chan *sh_chan)
@@ -782,8 +808,10 @@
 
 	sh_dmae_chan_ld_cleanup(sh_chan, false);
 
-	last_used = chan->cookie;
+	/* First read completed cookie to avoid a skew */
 	last_complete = sh_chan->completed_cookie;
+	rmb();
+	last_used = chan->cookie;
 	BUG_ON(last_complete < 0);
 	dma_set_tx_state(txstate, last_complete, last_used, 0);
 
@@ -813,8 +841,12 @@
 static irqreturn_t sh_dmae_interrupt(int irq, void *data)
 {
 	irqreturn_t ret = IRQ_NONE;
-	struct sh_dmae_chan *sh_chan = (struct sh_dmae_chan *)data;
-	u32 chcr = sh_dmae_readl(sh_chan, CHCR);
+	struct sh_dmae_chan *sh_chan = data;
+	u32 chcr;
+
+	spin_lock(&sh_chan->desc_lock);
+
+	chcr = sh_dmae_readl(sh_chan, CHCR);
 
 	if (chcr & CHCR_TE) {
 		/* DMA stop */
@@ -824,10 +856,13 @@
 		tasklet_schedule(&sh_chan->tasklet);
 	}
 
+	spin_unlock(&sh_chan->desc_lock);
+
 	return ret;
 }
 
-static unsigned int sh_dmae_reset(struct sh_dmae_device *shdev)
+/* Called from error IRQ or NMI */
+static bool sh_dmae_reset(struct sh_dmae_device *shdev)
 {
 	unsigned int handled = 0;
 	int i;
@@ -839,22 +874,32 @@
 	for (i = 0; i < SH_DMAC_MAX_CHANNELS; i++) {
 		struct sh_dmae_chan *sh_chan = shdev->chan[i];
 		struct sh_desc *desc;
+		LIST_HEAD(dl);
 
 		if (!sh_chan)
 			continue;
 
+		spin_lock(&sh_chan->desc_lock);
+
 		/* Stop the channel */
 		dmae_halt(sh_chan);
 
+		list_splice_init(&sh_chan->ld_queue, &dl);
+
+		spin_unlock(&sh_chan->desc_lock);
+
 		/* Complete all  */
-		list_for_each_entry(desc, &sh_chan->ld_queue, node) {
+		list_for_each_entry(desc, &dl, node) {
 			struct dma_async_tx_descriptor *tx = &desc->async_tx;
 			desc->mark = DESC_IDLE;
 			if (tx->callback)
 				tx->callback(tx->callback_param);
 		}
 
-		list_splice_init(&sh_chan->ld_queue, &sh_chan->ld_free);
+		spin_lock(&sh_chan->desc_lock);
+		list_splice(&dl, &sh_chan->ld_free);
+		spin_unlock(&sh_chan->desc_lock);
+
 		handled++;
 	}
 
@@ -867,10 +912,11 @@
 {
 	struct sh_dmae_device *shdev = data;
 
-	if (dmaor_read(shdev) & DMAOR_AE)
-		return IRQ_RETVAL(sh_dmae_reset(data));
-	else
+	if (!(dmaor_read(shdev) & DMAOR_AE))
 		return IRQ_NONE;
+
+	sh_dmae_reset(data);
+	return IRQ_HANDLED;
 }
 
 static void dmae_do_tasklet(unsigned long data)
@@ -902,17 +948,11 @@
 
 static bool sh_dmae_nmi_notify(struct sh_dmae_device *shdev)
 {
-	unsigned int handled;
-
 	/* Fast path out if NMIF is not asserted for this controller */
 	if ((dmaor_read(shdev) & DMAOR_NMIF) == 0)
 		return false;
 
-	handled = sh_dmae_reset(shdev);
-	if (handled)
-		return true;
-
-	return false;
+	return sh_dmae_reset(shdev);
 }
 
 static int sh_dmae_nmi_handler(struct notifier_block *self,
@@ -982,9 +1022,6 @@
 	tasklet_init(&new_sh_chan->tasklet, dmae_do_tasklet,
 			(unsigned long)new_sh_chan);
 
-	/* Init the channel */
-	dmae_init(new_sh_chan);
-
 	spin_lock_init(&new_sh_chan->desc_lock);
 
 	/* Init descripter manage list */
@@ -1045,9 +1082,8 @@
 	struct sh_dmae_pdata *pdata = pdev->dev.platform_data;
 	unsigned long irqflags = IRQF_DISABLED,
 		chan_flag[SH_DMAC_MAX_CHANNELS] = {};
-	unsigned long flags;
 	int errirq, chan_irq[SH_DMAC_MAX_CHANNELS];
-	int err, i, irq_cnt = 0, irqres = 0;
+	int err, i, irq_cnt = 0, irqres = 0, irq_cap = 0;
 	struct sh_dmae_device *shdev;
 	struct resource *chan, *dmars, *errirq_res, *chanirq_res;
 
@@ -1056,7 +1092,7 @@
 		return -ENODEV;
 
 	chan = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	/* DMARS area is optional, if absent, this controller cannot do slave DMA */
+	/* DMARS area is optional */
 	dmars = platform_get_resource(pdev, IORESOURCE_MEM, 1);
 	/*
 	 * IRQ resources:
@@ -1108,14 +1144,16 @@
 	/* platform data */
 	shdev->pdata = pdata;
 
+	platform_set_drvdata(pdev, shdev);
+
 	pm_runtime_enable(&pdev->dev);
 	pm_runtime_get_sync(&pdev->dev);
 
-	spin_lock_irqsave(&sh_dmae_lock, flags);
+	spin_lock_irq(&sh_dmae_lock);
 	list_add_tail_rcu(&shdev->node, &sh_dmae_devices);
-	spin_unlock_irqrestore(&sh_dmae_lock, flags);
+	spin_unlock_irq(&sh_dmae_lock);
 
-	/* reset dma controller */
+	/* reset dma controller - only needed as a test */
 	err = sh_dmae_rst(shdev);
 	if (err)
 		goto rst_err;
@@ -1123,7 +1161,7 @@
 	INIT_LIST_HEAD(&shdev->common.channels);
 
 	dma_cap_set(DMA_MEMCPY, shdev->common.cap_mask);
-	if (dmars)
+	if (pdata->slave && pdata->slave_num)
 		dma_cap_set(DMA_SLAVE, shdev->common.cap_mask);
 
 	shdev->common.device_alloc_chan_resources
@@ -1172,12 +1210,22 @@
 	    !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;
+			if (irq_cnt < SH_DMAC_MAX_CHANNELS) {
+				chan_irq[irq_cnt] = chanirq_res->start;
+				chan_flag[irq_cnt] = IRQF_SHARED;
+			} else {
+				irq_cap = 1;
+				break;
+			}
 		}
 	} else {
 		do {
 			for (i = chanirq_res->start; i <= chanirq_res->end; i++) {
+				if (irq_cnt >= SH_DMAC_MAX_CHANNELS) {
+					irq_cap = 1;
+					break;
+				}
+
 				if ((errirq_res->flags & IORESOURCE_BITS) ==
 				    IORESOURCE_IRQ_SHAREABLE)
 					chan_flag[irq_cnt] = IRQF_SHARED;
@@ -1188,45 +1236,55 @@
 					i, irq_cnt);
 				chan_irq[irq_cnt++] = i;
 			}
+
+			if (irq_cnt >= SH_DMAC_MAX_CHANNELS)
+				break;
+
 			chanirq_res = platform_get_resource(pdev,
 						IORESOURCE_IRQ, ++irqres);
 		} while (irq_cnt < pdata->channel_num && chanirq_res);
 	}
 
-	if (irq_cnt < pdata->channel_num)
-		goto eirqres;
-
 	/* Create DMA Channel */
-	for (i = 0; i < pdata->channel_num; i++) {
+	for (i = 0; i < irq_cnt; i++) {
 		err = sh_dmae_chan_probe(shdev, i, chan_irq[i], chan_flag[i]);
 		if (err)
 			goto chan_probe_err;
 	}
 
+	if (irq_cap)
+		dev_notice(&pdev->dev, "Attempting to register %d DMA "
+			   "channels when a maximum of %d are supported.\n",
+			   pdata->channel_num, SH_DMAC_MAX_CHANNELS);
+
 	pm_runtime_put(&pdev->dev);
 
-	platform_set_drvdata(pdev, shdev);
 	dma_async_device_register(&shdev->common);
 
 	return err;
 
 chan_probe_err:
 	sh_dmae_chan_remove(shdev);
-eirqres:
+
 #if defined(CONFIG_CPU_SH4) || defined(CONFIG_ARCH_SHMOBILE)
 	free_irq(errirq, shdev);
 eirq_err:
 #endif
 rst_err:
-	spin_lock_irqsave(&sh_dmae_lock, flags);
+	spin_lock_irq(&sh_dmae_lock);
 	list_del_rcu(&shdev->node);
-	spin_unlock_irqrestore(&sh_dmae_lock, flags);
+	spin_unlock_irq(&sh_dmae_lock);
 
 	pm_runtime_put(&pdev->dev);
+	pm_runtime_disable(&pdev->dev);
+
 	if (dmars)
 		iounmap(shdev->dmars);
+
+	platform_set_drvdata(pdev, NULL);
 emapdmars:
 	iounmap(shdev->chan_reg);
+	synchronize_rcu();
 emapchan:
 	kfree(shdev);
 ealloc:
@@ -1242,7 +1300,6 @@
 {
 	struct sh_dmae_device *shdev = platform_get_drvdata(pdev);
 	struct resource *res;
-	unsigned long flags;
 	int errirq = platform_get_irq(pdev, 0);
 
 	dma_async_device_unregister(&shdev->common);
@@ -1250,9 +1307,9 @@
 	if (errirq > 0)
 		free_irq(errirq, shdev);
 
-	spin_lock_irqsave(&sh_dmae_lock, flags);
+	spin_lock_irq(&sh_dmae_lock);
 	list_del_rcu(&shdev->node);
-	spin_unlock_irqrestore(&sh_dmae_lock, flags);
+	spin_unlock_irq(&sh_dmae_lock);
 
 	/* channel data remove */
 	sh_dmae_chan_remove(shdev);
@@ -1263,6 +1320,9 @@
 		iounmap(shdev->dmars);
 	iounmap(shdev->chan_reg);
 
+	platform_set_drvdata(pdev, NULL);
+
+	synchronize_rcu();
 	kfree(shdev);
 
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -1281,12 +1341,78 @@
 	sh_dmae_ctl_stop(shdev);
 }
 
+static int sh_dmae_runtime_suspend(struct device *dev)
+{
+	return 0;
+}
+
+static int sh_dmae_runtime_resume(struct device *dev)
+{
+	struct sh_dmae_device *shdev = dev_get_drvdata(dev);
+
+	return sh_dmae_rst(shdev);
+}
+
+#ifdef CONFIG_PM
+static int sh_dmae_suspend(struct device *dev)
+{
+	struct sh_dmae_device *shdev = dev_get_drvdata(dev);
+	int i;
+
+	for (i = 0; i < shdev->pdata->channel_num; i++) {
+		struct sh_dmae_chan *sh_chan = shdev->chan[i];
+		if (sh_chan->descs_allocated)
+			sh_chan->pm_error = pm_runtime_put_sync(dev);
+	}
+
+	return 0;
+}
+
+static int sh_dmae_resume(struct device *dev)
+{
+	struct sh_dmae_device *shdev = dev_get_drvdata(dev);
+	int i;
+
+	for (i = 0; i < shdev->pdata->channel_num; i++) {
+		struct sh_dmae_chan *sh_chan = shdev->chan[i];
+		struct sh_dmae_slave *param = sh_chan->common.private;
+
+		if (!sh_chan->descs_allocated)
+			continue;
+
+		if (!sh_chan->pm_error)
+			pm_runtime_get_sync(dev);
+
+		if (param) {
+			const struct sh_dmae_slave_config *cfg = param->config;
+			dmae_set_dmars(sh_chan, cfg->mid_rid);
+			dmae_set_chcr(sh_chan, cfg->chcr);
+		} else {
+			dmae_init(sh_chan);
+		}
+	}
+
+	return 0;
+}
+#else
+#define sh_dmae_suspend NULL
+#define sh_dmae_resume NULL
+#endif
+
+const struct dev_pm_ops sh_dmae_pm = {
+	.suspend		= sh_dmae_suspend,
+	.resume			= sh_dmae_resume,
+	.runtime_suspend	= sh_dmae_runtime_suspend,
+	.runtime_resume		= sh_dmae_runtime_resume,
+};
+
 static struct platform_driver sh_dmae_driver = {
 	.remove		= __exit_p(sh_dmae_remove),
 	.shutdown	= sh_dmae_shutdown,
 	.driver = {
 		.owner	= THIS_MODULE,
 		.name	= "sh-dma-engine",
+		.pm	= &sh_dmae_pm,
 	},
 };
 
diff -druN linux-2.6.39-libre/drivers/dma/shdma.h linux-3.0-rc7-libre/drivers/dma/shdma.h
--- linux-2.6.39-libre/drivers/dma/shdma.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/dma/shdma.h	2011-07-11 19:51:52.000000000 -0400
@@ -17,7 +17,7 @@
 #include <linux/interrupt.h>
 #include <linux/list.h>
 
-#define SH_DMAC_MAX_CHANNELS 6
+#define SH_DMAC_MAX_CHANNELS 20
 #define SH_DMA_SLAVE_NUMBER 256
 #define SH_DMA_TCR_MAX 0x00FFFFFF	/* 16MB */
 
@@ -37,6 +37,7 @@
 	int id;				/* Raw id of this channel */
 	u32 __iomem *base;
 	char dev_id[16];		/* unique name per DMAC of channel */
+	int pm_error;
 };
 
 struct sh_dmae_device {
diff -druN linux-2.6.39-libre/drivers/dma/ste_dma40.c linux-3.0-rc7-libre/drivers/dma/ste_dma40.c
--- linux-2.6.39-libre/drivers/dma/ste_dma40.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/dma/ste_dma40.c	2011-07-11 19:51:52.000000000 -0400
@@ -1829,7 +1829,7 @@
 {
 	struct stedma40_platform_data *plat = chan->base->plat_data;
 	struct stedma40_chan_cfg *cfg = &chan->dma_cfg;
-	dma_addr_t addr;
+	dma_addr_t addr = 0;
 
 	if (chan->runtime_addr)
 		return chan->runtime_addr;
@@ -2962,4 +2962,4 @@
 {
 	return platform_driver_probe(&d40_driver, d40_probe);
 }
-arch_initcall(stedma40_init);
+subsys_initcall(stedma40_init);
diff -druN linux-2.6.39-libre/drivers/dma/timb_dma.c linux-3.0-rc7-libre/drivers/dma/timb_dma.c
--- linux-2.6.39-libre/drivers/dma/timb_dma.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/dma/timb_dma.c	2011-07-11 19:51:52.000000000 -0400
@@ -27,7 +27,6 @@
 #include <linux/io.h>
 #include <linux/module.h>
 #include <linux/platform_device.h>
-#include <linux/mfd/core.h>
 #include <linux/slab.h>
 
 #include <linux/timb_dma.h>
@@ -685,7 +684,7 @@
 
 static int __devinit td_probe(struct platform_device *pdev)
 {
-	struct timb_dma_platform_data *pdata = mfd_get_data(pdev);
+	struct timb_dma_platform_data *pdata = pdev->dev.platform_data;
 	struct timb_dma *td;
 	struct resource *iomem;
 	int irq;
diff -druN linux-2.6.39-libre/drivers/dma/TODO linux-3.0-rc7-libre/drivers/dma/TODO
--- linux-2.6.39-libre/drivers/dma/TODO	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/dma/TODO	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,14 @@
+TODO for slave dma
+
+1. Move remaining drivers to use new slave interface
+2. Remove old slave pointer machansim
+3. Make issue_pending to start the transaction in below drivers
+	- mpc512x_dma
+	- imx-dma
+	- imx-sdma
+	- mxs-dma.c
+	- dw_dmac
+	- intel_mid_dma
+	- ste_dma40
+4. Check other subsystems for dma drivers and merge/move to dmaengine
+5. Remove dma_slave_config's dma direction.
diff -druN linux-2.6.39-libre/drivers/edac/amd76x_edac.c linux-3.0-rc7-libre/drivers/edac/amd76x_edac.c
--- linux-2.6.39-libre/drivers/edac/amd76x_edac.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/edac/amd76x_edac.c	2011-07-11 19:51:52.000000000 -0400
@@ -19,7 +19,7 @@
 #include <linux/edac.h>
 #include "edac_core.h"
 
-#define AMD76X_REVISION	" Ver: 2.0.2 "  __DATE__
+#define AMD76X_REVISION	" Ver: 2.0.2"
 #define EDAC_MOD_STR	"amd76x_edac"
 
 #define amd76x_printk(level, fmt, arg...) \
diff -druN linux-2.6.39-libre/drivers/edac/amd8111_edac.c linux-3.0-rc7-libre/drivers/edac/amd8111_edac.c
--- linux-2.6.39-libre/drivers/edac/amd8111_edac.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/edac/amd8111_edac.c	2011-07-11 19:51:52.000000000 -0400
@@ -33,7 +33,7 @@
 #include "edac_module.h"
 #include "amd8111_edac.h"
 
-#define AMD8111_EDAC_REVISION	" Ver: 1.0.0 " __DATE__
+#define AMD8111_EDAC_REVISION	" Ver: 1.0.0"
 #define AMD8111_EDAC_MOD_STR	"amd8111_edac"
 
 #define PCI_DEVICE_ID_AMD_8111_PCI	0x7460
diff -druN linux-2.6.39-libre/drivers/edac/amd8131_edac.c linux-3.0-rc7-libre/drivers/edac/amd8131_edac.c
--- linux-2.6.39-libre/drivers/edac/amd8131_edac.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/edac/amd8131_edac.c	2011-07-11 19:51:52.000000000 -0400
@@ -33,7 +33,7 @@
 #include "edac_module.h"
 #include "amd8131_edac.h"
 
-#define AMD8131_EDAC_REVISION	" Ver: 1.0.0 " __DATE__
+#define AMD8131_EDAC_REVISION	" Ver: 1.0.0"
 #define AMD8131_EDAC_MOD_STR	"amd8131_edac"
 
 /* Wrapper functions for accessing PCI configuration space */
diff -druN linux-2.6.39-libre/drivers/edac/cpc925_edac.c linux-3.0-rc7-libre/drivers/edac/cpc925_edac.c
--- linux-2.6.39-libre/drivers/edac/cpc925_edac.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/edac/cpc925_edac.c	2011-07-11 19:51:52.000000000 -0400
@@ -30,7 +30,7 @@
 #include "edac_core.h"
 #include "edac_module.h"
 
-#define CPC925_EDAC_REVISION	" Ver: 1.0.0 " __DATE__
+#define CPC925_EDAC_REVISION	" Ver: 1.0.0"
 #define CPC925_EDAC_MOD_STR	"cpc925_edac"
 
 #define cpc925_printk(level, fmt, arg...) \
diff -druN linux-2.6.39-libre/drivers/edac/e752x_edac.c linux-3.0-rc7-libre/drivers/edac/e752x_edac.c
--- linux-2.6.39-libre/drivers/edac/e752x_edac.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/edac/e752x_edac.c	2011-07-11 19:51:52.000000000 -0400
@@ -24,7 +24,7 @@
 #include <linux/edac.h>
 #include "edac_core.h"
 
-#define E752X_REVISION	" Ver: 2.0.2 " __DATE__
+#define E752X_REVISION	" Ver: 2.0.2"
 #define EDAC_MOD_STR	"e752x_edac"
 
 static int report_non_memory_errors;
diff -druN linux-2.6.39-libre/drivers/edac/e7xxx_edac.c linux-3.0-rc7-libre/drivers/edac/e7xxx_edac.c
--- linux-2.6.39-libre/drivers/edac/e7xxx_edac.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/edac/e7xxx_edac.c	2011-07-11 19:51:52.000000000 -0400
@@ -29,7 +29,7 @@
 #include <linux/edac.h>
 #include "edac_core.h"
 
-#define	E7XXX_REVISION " Ver: 2.0.2 " __DATE__
+#define	E7XXX_REVISION " Ver: 2.0.2"
 #define	EDAC_MOD_STR	"e7xxx_edac"
 
 #define e7xxx_printk(level, fmt, arg...) \
diff -druN linux-2.6.39-libre/drivers/edac/edac_core.h linux-3.0-rc7-libre/drivers/edac/edac_core.h
--- linux-2.6.39-libre/drivers/edac/edac_core.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/edac/edac_core.h	2011-07-11 19:51:52.000000000 -0400
@@ -421,10 +421,6 @@
 	u32 ce_count;		/* Total Correctable Errors for this MC */
 	unsigned long start_time;	/* mci load start time (in jiffies) */
 
-	/* this stuff is for safe removal of mc devices from global list while
-	 * NMI handlers may be traversing list
-	 */
-	struct rcu_head rcu;
 	struct completion complete;
 
 	/* edac sysfs device control */
@@ -620,10 +616,6 @@
 
 	unsigned long start_time;	/* edac_device load start time (jiffies) */
 
-	/* these are for safe removal of mc devices from global list while
-	 * NMI handlers may be traversing list
-	 */
-	struct rcu_head rcu;
 	struct completion removal_complete;
 
 	/* sysfs top name under 'edac' directory
@@ -722,10 +714,6 @@
 
 	unsigned long start_time;	/* edac_pci load start time (jiffies) */
 
-	/* these are for safe removal of devices from global list while
-	 * NMI handlers may be traversing list
-	 */
-	struct rcu_head rcu;
 	struct completion complete;
 
 	/* sysfs top name under 'edac' directory
diff -druN linux-2.6.39-libre/drivers/edac/edac_device.c linux-3.0-rc7-libre/drivers/edac/edac_device.c
--- linux-2.6.39-libre/drivers/edac/edac_device.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/edac/edac_device.c	2011-07-11 19:51:52.000000000 -0400
@@ -346,30 +346,18 @@
 }
 
 /*
- * complete_edac_device_list_del
- *
- *	callback function when reference count is zero
- */
-static void complete_edac_device_list_del(struct rcu_head *head)
-{
-	struct edac_device_ctl_info *edac_dev;
-
-	edac_dev = container_of(head, struct edac_device_ctl_info, rcu);
-	INIT_LIST_HEAD(&edac_dev->link);
-}
-
-/*
  * del_edac_device_from_global_list
- *
- *	remove the RCU, setup for a callback call,
- *	then wait for the callback to occur
  */
 static void del_edac_device_from_global_list(struct edac_device_ctl_info
 						*edac_device)
 {
 	list_del_rcu(&edac_device->link);
-	call_rcu(&edac_device->rcu, complete_edac_device_list_del);
-	rcu_barrier();
+
+	/* these are for safe removal of devices from global list while
+	 * NMI handlers may be traversing list
+	 */
+	synchronize_rcu();
+	INIT_LIST_HEAD(&edac_device->link);
 }
 
 /*
diff -druN linux-2.6.39-libre/drivers/edac/edac_mc.c linux-3.0-rc7-libre/drivers/edac/edac_mc.c
--- linux-2.6.39-libre/drivers/edac/edac_mc.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/edac/edac_mc.c	2011-07-11 19:51:52.000000000 -0400
@@ -447,20 +447,16 @@
 	return 1;
 }
 
-static void complete_mc_list_del(struct rcu_head *head)
-{
-	struct mem_ctl_info *mci;
-
-	mci = container_of(head, struct mem_ctl_info, rcu);
-	INIT_LIST_HEAD(&mci->link);
-}
-
 static void del_mc_from_global_list(struct mem_ctl_info *mci)
 {
 	atomic_dec(&edac_handlers);
 	list_del_rcu(&mci->link);
-	call_rcu(&mci->rcu, complete_mc_list_del);
-	rcu_barrier();
+
+	/* these are for safe removal of devices from global list while
+	 * NMI handlers may be traversing list
+	 */
+	synchronize_rcu();
+	INIT_LIST_HEAD(&mci->link);
 }
 
 /**
diff -druN linux-2.6.39-libre/drivers/edac/edac_module.c linux-3.0-rc7-libre/drivers/edac/edac_module.c
--- linux-2.6.39-libre/drivers/edac/edac_module.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/edac/edac_module.c	2011-07-11 19:51:52.000000000 -0400
@@ -15,7 +15,7 @@
 #include "edac_core.h"
 #include "edac_module.h"
 
-#define EDAC_VERSION "Ver: 2.1.0 " __DATE__
+#define EDAC_VERSION "Ver: 2.1.0"
 
 #ifdef CONFIG_EDAC_DEBUG
 /* Values of 0 to 4 will generate output */
diff -druN linux-2.6.39-libre/drivers/edac/edac_pci.c linux-3.0-rc7-libre/drivers/edac/edac_pci.c
--- linux-2.6.39-libre/drivers/edac/edac_pci.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/edac/edac_pci.c	2011-07-11 19:51:52.000000000 -0400
@@ -164,19 +164,6 @@
 }
 
 /*
- * complete_edac_pci_list_del
- *
- *	RCU completion callback to indicate item is deleted
- */
-static void complete_edac_pci_list_del(struct rcu_head *head)
-{
-	struct edac_pci_ctl_info *pci;
-
-	pci = container_of(head, struct edac_pci_ctl_info, rcu);
-	INIT_LIST_HEAD(&pci->link);
-}
-
-/*
  * del_edac_pci_from_global_list
  *
  *	remove the PCI control struct from the global list
@@ -184,8 +171,12 @@
 static void del_edac_pci_from_global_list(struct edac_pci_ctl_info *pci)
 {
 	list_del_rcu(&pci->link);
-	call_rcu(&pci->rcu, complete_edac_pci_list_del);
-	rcu_barrier();
+
+	/* these are for safe removal of devices from global list while
+	 * NMI handlers may be traversing list
+	 */
+	synchronize_rcu();
+	INIT_LIST_HEAD(&pci->link);
 }
 
 #if 0
diff -druN linux-2.6.39-libre/drivers/edac/i3200_edac.c linux-3.0-rc7-libre/drivers/edac/i3200_edac.c
--- linux-2.6.39-libre/drivers/edac/i3200_edac.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/edac/i3200_edac.c	2011-07-11 19:51:52.000000000 -0400
@@ -101,6 +101,19 @@
 
 static int nr_channels;
 
+#ifndef readq
+static inline __u64 readq(const volatile void __iomem *addr)
+{
+	const volatile u32 __iomem *p = addr;
+	u32 low, high;
+
+	low = readl(p);
+	high = readl(p + 1);
+
+	return low + ((u64)high << 32);
+}
+#endif
+
 static int how_many_channels(struct pci_dev *pdev)
 {
 	unsigned char capid0_8b; /* 8th byte of CAPID0 */
diff -druN linux-2.6.39-libre/drivers/edac/i5000_edac.c linux-3.0-rc7-libre/drivers/edac/i5000_edac.c
--- linux-2.6.39-libre/drivers/edac/i5000_edac.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/edac/i5000_edac.c	2011-07-11 19:51:52.000000000 -0400
@@ -27,7 +27,7 @@
 /*
  * Alter this version for the I5000 module when modifications are made
  */
-#define I5000_REVISION    " Ver: 2.0.12 " __DATE__
+#define I5000_REVISION    " Ver: 2.0.12"
 #define EDAC_MOD_STR      "i5000_edac"
 
 #define i5000_printk(level, fmt, arg...) \
diff -druN linux-2.6.39-libre/drivers/edac/i5400_edac.c linux-3.0-rc7-libre/drivers/edac/i5400_edac.c
--- linux-2.6.39-libre/drivers/edac/i5400_edac.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/edac/i5400_edac.c	2011-07-11 19:51:52.000000000 -0400
@@ -33,7 +33,7 @@
 /*
  * Alter this version for the I5400 module when modifications are made
  */
-#define I5400_REVISION    " Ver: 1.0.0 " __DATE__
+#define I5400_REVISION    " Ver: 1.0.0"
 
 #define EDAC_MOD_STR      "i5400_edac"
 
diff -druN linux-2.6.39-libre/drivers/edac/i7300_edac.c linux-3.0-rc7-libre/drivers/edac/i7300_edac.c
--- linux-2.6.39-libre/drivers/edac/i7300_edac.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/edac/i7300_edac.c	2011-07-11 19:51:52.000000000 -0400
@@ -31,7 +31,7 @@
 /*
  * Alter this version for the I7300 module when modifications are made
  */
-#define I7300_REVISION    " Ver: 1.0.0 " __DATE__
+#define I7300_REVISION    " Ver: 1.0.0"
 
 #define EDAC_MOD_STR      "i7300_edac"
 
diff -druN linux-2.6.39-libre/drivers/edac/i7core_edac.c linux-3.0-rc7-libre/drivers/edac/i7core_edac.c
--- linux-2.6.39-libre/drivers/edac/i7core_edac.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/edac/i7core_edac.c	2011-07-11 19:51:52.000000000 -0400
@@ -59,7 +59,7 @@
 /*
  * Alter this version for the module when modifications are made
  */
-#define I7CORE_REVISION    " Ver: 1.0.0 " __DATE__
+#define I7CORE_REVISION    " Ver: 1.0.0"
 #define EDAC_MOD_STR      "i7core_edac"
 
 /*
diff -druN linux-2.6.39-libre/drivers/edac/i82860_edac.c linux-3.0-rc7-libre/drivers/edac/i82860_edac.c
--- linux-2.6.39-libre/drivers/edac/i82860_edac.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/edac/i82860_edac.c	2011-07-11 19:51:52.000000000 -0400
@@ -16,7 +16,7 @@
 #include <linux/edac.h>
 #include "edac_core.h"
 
-#define  I82860_REVISION " Ver: 2.0.2 " __DATE__
+#define  I82860_REVISION " Ver: 2.0.2"
 #define EDAC_MOD_STR	"i82860_edac"
 
 #define i82860_printk(level, fmt, arg...) \
diff -druN linux-2.6.39-libre/drivers/edac/i82875p_edac.c linux-3.0-rc7-libre/drivers/edac/i82875p_edac.c
--- linux-2.6.39-libre/drivers/edac/i82875p_edac.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/edac/i82875p_edac.c	2011-07-11 19:51:52.000000000 -0400
@@ -20,7 +20,7 @@
 #include <linux/edac.h>
 #include "edac_core.h"
 
-#define I82875P_REVISION	" Ver: 2.0.2 " __DATE__
+#define I82875P_REVISION	" Ver: 2.0.2"
 #define EDAC_MOD_STR		"i82875p_edac"
 
 #define i82875p_printk(level, fmt, arg...) \
diff -druN linux-2.6.39-libre/drivers/edac/i82975x_edac.c linux-3.0-rc7-libre/drivers/edac/i82975x_edac.c
--- linux-2.6.39-libre/drivers/edac/i82975x_edac.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/edac/i82975x_edac.c	2011-07-11 19:51:52.000000000 -0400
@@ -16,7 +16,7 @@
 #include <linux/edac.h>
 #include "edac_core.h"
 
-#define I82975X_REVISION	" Ver: 1.0.0 " __DATE__
+#define I82975X_REVISION	" Ver: 1.0.0"
 #define EDAC_MOD_STR		"i82975x_edac"
 
 #define i82975x_printk(level, fmt, arg...) \
diff -druN linux-2.6.39-libre/drivers/edac/mpc85xx_edac.h linux-3.0-rc7-libre/drivers/edac/mpc85xx_edac.h
--- linux-2.6.39-libre/drivers/edac/mpc85xx_edac.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/edac/mpc85xx_edac.h	2011-07-11 19:51:52.000000000 -0400
@@ -11,7 +11,7 @@
 #ifndef _MPC85XX_EDAC_H_
 #define _MPC85XX_EDAC_H_
 
-#define MPC85XX_REVISION " Ver: 2.0.0 " __DATE__
+#define MPC85XX_REVISION " Ver: 2.0.0"
 #define EDAC_MOD_STR	"MPC85xx_edac"
 
 #define mpc85xx_printk(level, fmt, arg...) \
diff -druN linux-2.6.39-libre/drivers/edac/mv64x60_edac.h linux-3.0-rc7-libre/drivers/edac/mv64x60_edac.h
--- linux-2.6.39-libre/drivers/edac/mv64x60_edac.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/edac/mv64x60_edac.h	2011-07-11 19:51:52.000000000 -0400
@@ -12,7 +12,7 @@
 #ifndef _MV64X60_EDAC_H_
 #define _MV64X60_EDAC_H_
 
-#define MV64x60_REVISION " Ver: 2.0.0 " __DATE__
+#define MV64x60_REVISION " Ver: 2.0.0"
 #define EDAC_MOD_STR	"MV64x60_edac"
 
 #define mv64x60_printk(level, fmt, arg...) \
diff -druN linux-2.6.39-libre/drivers/edac/ppc4xx_edac.c linux-3.0-rc7-libre/drivers/edac/ppc4xx_edac.c
--- linux-2.6.39-libre/drivers/edac/ppc4xx_edac.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/edac/ppc4xx_edac.c	2011-07-11 19:51:52.000000000 -0400
@@ -113,7 +113,7 @@
 #define EDAC_OPSTATE_UNKNOWN_STR	"unknown"
 
 #define PPC4XX_EDAC_MODULE_NAME		"ppc4xx_edac"
-#define PPC4XX_EDAC_MODULE_REVISION	"v1.0.0 " __DATE__
+#define PPC4XX_EDAC_MODULE_REVISION	"v1.0.0"
 
 #define PPC4XX_EDAC_MESSAGE_SIZE	256
 
diff -druN linux-2.6.39-libre/drivers/edac/r82600_edac.c linux-3.0-rc7-libre/drivers/edac/r82600_edac.c
--- linux-2.6.39-libre/drivers/edac/r82600_edac.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/edac/r82600_edac.c	2011-07-11 19:51:52.000000000 -0400
@@ -22,7 +22,7 @@
 #include <linux/edac.h>
 #include "edac_core.h"
 
-#define R82600_REVISION	" Ver: 2.0.2 " __DATE__
+#define R82600_REVISION	" Ver: 2.0.2"
 #define EDAC_MOD_STR	"r82600_edac"
 
 #define r82600_printk(level, fmt, arg...) \
diff -druN linux-2.6.39-libre/drivers/firewire/core-card.c linux-3.0-rc7-libre/drivers/firewire/core-card.c
--- linux-2.6.39-libre/drivers/firewire/core-card.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/firewire/core-card.c	2011-07-11 19:51:52.000000000 -0400
@@ -228,8 +228,8 @@
 
 	/* Use an arbitrary short delay to combine multiple reset requests. */
 	fw_card_get(card);
-	if (!schedule_delayed_work(&card->br_work,
-				   delayed ? DIV_ROUND_UP(HZ, 100) : 0))
+	if (!queue_delayed_work(fw_workqueue, &card->br_work,
+				delayed ? DIV_ROUND_UP(HZ, 100) : 0))
 		fw_card_put(card);
 }
 EXPORT_SYMBOL(fw_schedule_bus_reset);
@@ -241,7 +241,7 @@
 	/* Delay for 2s after last reset per IEEE 1394 clause 8.2.1. */
 	if (card->reset_jiffies != 0 &&
 	    time_before64(get_jiffies_64(), card->reset_jiffies + 2 * HZ)) {
-		if (!schedule_delayed_work(&card->br_work, 2 * HZ))
+		if (!queue_delayed_work(fw_workqueue, &card->br_work, 2 * HZ))
 			fw_card_put(card);
 		return;
 	}
@@ -258,8 +258,7 @@
 
 	if (!card->broadcast_channel_allocated) {
 		fw_iso_resource_manage(card, generation, 1ULL << 31,
-				       &channel, &bandwidth, true,
-				       card->bm_transaction_data);
+				       &channel, &bandwidth, true);
 		if (channel != 31) {
 			fw_notify("failed to allocate broadcast channel\n");
 			return;
@@ -294,6 +293,7 @@
 	bool root_device_is_cmc;
 	bool irm_is_1394_1995_only;
 	bool keep_this_irm;
+	__be32 transaction_data[2];
 
 	spin_lock_irq(&card->lock);
 
@@ -355,21 +355,21 @@
 			goto pick_me;
 		}
 
-		card->bm_transaction_data[0] = cpu_to_be32(0x3f);
-		card->bm_transaction_data[1] = cpu_to_be32(local_id);
+		transaction_data[0] = cpu_to_be32(0x3f);
+		transaction_data[1] = cpu_to_be32(local_id);
 
 		spin_unlock_irq(&card->lock);
 
 		rcode = fw_run_transaction(card, TCODE_LOCK_COMPARE_SWAP,
 				irm_id, generation, SCODE_100,
 				CSR_REGISTER_BASE + CSR_BUS_MANAGER_ID,
-				card->bm_transaction_data, 8);
+				transaction_data, 8);
 
 		if (rcode == RCODE_GENERATION)
 			/* Another bus reset, BM work has been rescheduled. */
 			goto out;
 
-		bm_id = be32_to_cpu(card->bm_transaction_data[0]);
+		bm_id = be32_to_cpu(transaction_data[0]);
 
 		spin_lock_irq(&card->lock);
 		if (rcode == RCODE_COMPLETE && generation == card->generation)
@@ -490,11 +490,11 @@
 		/*
 		 * Make sure that the cycle master sends cycle start packets.
 		 */
-		card->bm_transaction_data[0] = cpu_to_be32(CSR_STATE_BIT_CMSTR);
+		transaction_data[0] = cpu_to_be32(CSR_STATE_BIT_CMSTR);
 		rcode = fw_run_transaction(card, TCODE_WRITE_QUADLET_REQUEST,
 				root_id, generation, SCODE_100,
 				CSR_REGISTER_BASE + CSR_STATE_SET,
-				card->bm_transaction_data, 4);
+				transaction_data, 4);
 		if (rcode == RCODE_GENERATION)
 			goto out;
 	}
@@ -630,6 +630,10 @@
 	return -ENODEV;
 }
 
+static void dummy_flush_queue_iso(struct fw_iso_context *ctx)
+{
+}
+
 static const struct fw_card_driver dummy_driver_template = {
 	.read_phy_reg		= dummy_read_phy_reg,
 	.update_phy_reg		= dummy_update_phy_reg,
@@ -641,6 +645,7 @@
 	.start_iso		= dummy_start_iso,
 	.set_iso_channels	= dummy_set_iso_channels,
 	.queue_iso		= dummy_queue_iso,
+	.flush_queue_iso	= dummy_flush_queue_iso,
 };
 
 void fw_card_release(struct kref *kref)
diff -druN linux-2.6.39-libre/drivers/firewire/core-cdev.c linux-3.0-rc7-libre/drivers/firewire/core-cdev.c
--- linux-2.6.39-libre/drivers/firewire/core-cdev.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/firewire/core-cdev.c	2011-07-11 19:51:52.000000000 -0400
@@ -141,7 +141,6 @@
 	int generation;
 	u64 channels;
 	s32 bandwidth;
-	__be32 transaction_data[2];
 	struct iso_resource_event *e_alloc, *e_dealloc;
 };
 
@@ -150,7 +149,7 @@
 static void schedule_iso_resource(struct iso_resource *r, unsigned long delay)
 {
 	client_get(r->client);
-	if (!schedule_delayed_work(&r->work, delay))
+	if (!queue_delayed_work(fw_workqueue, &r->work, delay))
 		client_put(r->client);
 }
 
@@ -1108,6 +1107,7 @@
 		payload += u.packet.payload_length;
 		count++;
 	}
+	fw_iso_context_queue_flush(ctx);
 
 	a->size    -= uptr_to_u64(p) - a->packets;
 	a->packets  = uptr_to_u64(p);
@@ -1229,8 +1229,7 @@
 			r->channels, &channel, &bandwidth,
 			todo == ISO_RES_ALLOC ||
 			todo == ISO_RES_REALLOC ||
-			todo == ISO_RES_ALLOC_ONCE,
-			r->transaction_data);
+			todo == ISO_RES_ALLOC_ONCE);
 	/*
 	 * Is this generation outdated already?  As long as this resource sticks
 	 * in the idr, it will be scheduled again for a newer generation or at
diff -druN linux-2.6.39-libre/drivers/firewire/core-device.c linux-3.0-rc7-libre/drivers/firewire/core-device.c
--- linux-2.6.39-libre/drivers/firewire/core-device.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/firewire/core-device.c	2011-07-11 19:51:52.000000000 -0400
@@ -725,6 +725,15 @@
 	return device;
 }
 
+struct workqueue_struct *fw_workqueue;
+EXPORT_SYMBOL(fw_workqueue);
+
+static void fw_schedule_device_work(struct fw_device *device,
+				    unsigned long delay)
+{
+	queue_delayed_work(fw_workqueue, &device->work, delay);
+}
+
 /*
  * These defines control the retry behavior for reading the config
  * rom.  It shouldn't be necessary to tweak these; if the device
@@ -750,7 +759,7 @@
 	if (time_before64(get_jiffies_64(),
 			  device->card->reset_jiffies + SHUTDOWN_DELAY)
 	    && !list_empty(&device->card->link)) {
-		schedule_delayed_work(&device->work, SHUTDOWN_DELAY);
+		fw_schedule_device_work(device, SHUTDOWN_DELAY);
 		return;
 	}
 
@@ -862,7 +871,7 @@
 		fw_notify("rediscovered device %s\n", dev_name(dev));
 
 		PREPARE_DELAYED_WORK(&old->work, fw_device_update);
-		schedule_delayed_work(&old->work, 0);
+		fw_schedule_device_work(old, 0);
 
 		if (current_node == card->root_node)
 			fw_schedule_bm_work(card, 0);
@@ -953,7 +962,7 @@
 		if (device->config_rom_retries < MAX_RETRIES &&
 		    atomic_read(&device->state) == FW_DEVICE_INITIALIZING) {
 			device->config_rom_retries++;
-			schedule_delayed_work(&device->work, RETRY_DELAY);
+			fw_schedule_device_work(device, RETRY_DELAY);
 		} else {
 			if (device->node->link_on)
 				fw_notify("giving up on config rom for node id %x\n",
@@ -1019,7 +1028,7 @@
 			   FW_DEVICE_INITIALIZING,
 			   FW_DEVICE_RUNNING) == FW_DEVICE_GONE) {
 		PREPARE_DELAYED_WORK(&device->work, fw_device_shutdown);
-		schedule_delayed_work(&device->work, SHUTDOWN_DELAY);
+		fw_schedule_device_work(device, SHUTDOWN_DELAY);
 	} else {
 		if (device->config_rom_retries)
 			fw_notify("created device %s: GUID %08x%08x, S%d00, "
@@ -1098,7 +1107,7 @@
 		if (device->config_rom_retries < MAX_RETRIES / 2 &&
 		    atomic_read(&device->state) == FW_DEVICE_INITIALIZING) {
 			device->config_rom_retries++;
-			schedule_delayed_work(&device->work, RETRY_DELAY / 2);
+			fw_schedule_device_work(device, RETRY_DELAY / 2);
 
 			return;
 		}
@@ -1131,7 +1140,7 @@
 		if (device->config_rom_retries < MAX_RETRIES &&
 		    atomic_read(&device->state) == FW_DEVICE_INITIALIZING) {
 			device->config_rom_retries++;
-			schedule_delayed_work(&device->work, RETRY_DELAY);
+			fw_schedule_device_work(device, RETRY_DELAY);
 
 			return;
 		}
@@ -1158,7 +1167,7 @@
  gone:
 	atomic_set(&device->state, FW_DEVICE_GONE);
 	PREPARE_DELAYED_WORK(&device->work, fw_device_shutdown);
-	schedule_delayed_work(&device->work, SHUTDOWN_DELAY);
+	fw_schedule_device_work(device, SHUTDOWN_DELAY);
  out:
 	if (node_id == card->root_node->node_id)
 		fw_schedule_bm_work(card, 0);
@@ -1214,7 +1223,7 @@
 		 * first config rom scan half a second after bus reset.
 		 */
 		INIT_DELAYED_WORK(&device->work, fw_device_init);
-		schedule_delayed_work(&device->work, INITIAL_DELAY);
+		fw_schedule_device_work(device, INITIAL_DELAY);
 		break;
 
 	case FW_NODE_INITIATED_RESET:
@@ -1230,7 +1239,7 @@
 			    FW_DEVICE_RUNNING,
 			    FW_DEVICE_INITIALIZING) == FW_DEVICE_RUNNING) {
 			PREPARE_DELAYED_WORK(&device->work, fw_device_refresh);
-			schedule_delayed_work(&device->work,
+			fw_schedule_device_work(device,
 				device->is_local ? 0 : INITIAL_DELAY);
 		}
 		break;
@@ -1245,7 +1254,7 @@
 		device->generation = card->generation;
 		if (atomic_read(&device->state) == FW_DEVICE_RUNNING) {
 			PREPARE_DELAYED_WORK(&device->work, fw_device_update);
-			schedule_delayed_work(&device->work, 0);
+			fw_schedule_device_work(device, 0);
 		}
 		break;
 
@@ -1270,7 +1279,7 @@
 		if (atomic_xchg(&device->state,
 				FW_DEVICE_GONE) == FW_DEVICE_RUNNING) {
 			PREPARE_DELAYED_WORK(&device->work, fw_device_shutdown);
-			schedule_delayed_work(&device->work,
+			fw_schedule_device_work(device,
 				list_empty(&card->link) ? 0 : SHUTDOWN_DELAY);
 		}
 		break;
diff -druN linux-2.6.39-libre/drivers/firewire/core.h linux-3.0-rc7-libre/drivers/firewire/core.h
--- linux-2.6.39-libre/drivers/firewire/core.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/firewire/core.h	2011-07-11 19:51:52.000000000 -0400
@@ -97,6 +97,8 @@
 			 struct fw_iso_buffer *buffer,
 			 unsigned long payload);
 
+	void (*flush_queue_iso)(struct fw_iso_context *ctx);
+
 	int (*stop_iso)(struct fw_iso_context *ctx);
 };
 
diff -druN linux-2.6.39-libre/drivers/firewire/core-iso.c linux-3.0-rc7-libre/drivers/firewire/core-iso.c
--- linux-2.6.39-libre/drivers/firewire/core-iso.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/firewire/core-iso.c	2011-07-11 19:51:52.000000000 -0400
@@ -185,6 +185,12 @@
 }
 EXPORT_SYMBOL(fw_iso_context_queue);
 
+void fw_iso_context_queue_flush(struct fw_iso_context *ctx)
+{
+	ctx->card->driver->flush_queue_iso(ctx);
+}
+EXPORT_SYMBOL(fw_iso_context_queue_flush);
+
 int fw_iso_context_stop(struct fw_iso_context *ctx)
 {
 	return ctx->card->driver->stop_iso(ctx);
@@ -196,9 +202,10 @@
  */
 
 static int manage_bandwidth(struct fw_card *card, int irm_id, int generation,
-			    int bandwidth, bool allocate, __be32 data[2])
+			    int bandwidth, bool allocate)
 {
 	int try, new, old = allocate ? BANDWIDTH_AVAILABLE_INITIAL : 0;
+	__be32 data[2];
 
 	/*
 	 * On a 1394a IRM with low contention, try < 1 is enough.
@@ -233,9 +240,10 @@
 }
 
 static int manage_channel(struct fw_card *card, int irm_id, int generation,
-		u32 channels_mask, u64 offset, bool allocate, __be32 data[2])
+		u32 channels_mask, u64 offset, bool allocate)
 {
 	__be32 bit, all, old;
+	__be32 data[2];
 	int channel, ret = -EIO, retry = 5;
 
 	old = all = allocate ? cpu_to_be32(~0) : 0;
@@ -284,7 +292,7 @@
 }
 
 static void deallocate_channel(struct fw_card *card, int irm_id,
-			       int generation, int channel, __be32 buffer[2])
+			       int generation, int channel)
 {
 	u32 mask;
 	u64 offset;
@@ -293,7 +301,7 @@
 	offset = channel < 32 ? CSR_REGISTER_BASE + CSR_CHANNELS_AVAILABLE_HI :
 				CSR_REGISTER_BASE + CSR_CHANNELS_AVAILABLE_LO;
 
-	manage_channel(card, irm_id, generation, mask, offset, false, buffer);
+	manage_channel(card, irm_id, generation, mask, offset, false);
 }
 
 /**
@@ -322,7 +330,7 @@
  */
 void fw_iso_resource_manage(struct fw_card *card, int generation,
 			    u64 channels_mask, int *channel, int *bandwidth,
-			    bool allocate, __be32 buffer[2])
+			    bool allocate)
 {
 	u32 channels_hi = channels_mask;	/* channels 31...0 */
 	u32 channels_lo = channels_mask >> 32;	/* channels 63...32 */
@@ -335,11 +343,11 @@
 	if (channels_hi)
 		c = manage_channel(card, irm_id, generation, channels_hi,
 				CSR_REGISTER_BASE + CSR_CHANNELS_AVAILABLE_HI,
-				allocate, buffer);
+				allocate);
 	if (channels_lo && c < 0) {
 		c = manage_channel(card, irm_id, generation, channels_lo,
 				CSR_REGISTER_BASE + CSR_CHANNELS_AVAILABLE_LO,
-				allocate, buffer);
+				allocate);
 		if (c >= 0)
 			c += 32;
 	}
@@ -351,14 +359,13 @@
 	if (*bandwidth == 0)
 		return;
 
-	ret = manage_bandwidth(card, irm_id, generation, *bandwidth,
-			       allocate, buffer);
+	ret = manage_bandwidth(card, irm_id, generation, *bandwidth, allocate);
 	if (ret < 0)
 		*bandwidth = 0;
 
 	if (allocate && ret < 0) {
 		if (c >= 0)
-			deallocate_channel(card, irm_id, generation, c, buffer);
+			deallocate_channel(card, irm_id, generation, c);
 		*channel = ret;
 	}
 }
diff -druN linux-2.6.39-libre/drivers/firewire/core-transaction.c linux-3.0-rc7-libre/drivers/firewire/core-transaction.c
--- linux-2.6.39-libre/drivers/firewire/core-transaction.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/firewire/core-transaction.c	2011-07-11 19:51:52.000000000 -0400
@@ -36,6 +36,7 @@
 #include <linux/string.h>
 #include <linux/timer.h>
 #include <linux/types.h>
+#include <linux/workqueue.h>
 
 #include <asm/byteorder.h>
 
@@ -326,8 +327,8 @@
  * It will contain tag, channel, and sy data instead of a node ID then.
  *
  * The payload buffer at @data is going to be DMA-mapped except in case of
- * quadlet-sized payload or of local (loopback) requests.  Hence make sure that
- * the buffer complies with the restrictions for DMA-mapped memory.  The
+ * @length <= 8 or of local (loopback) requests.  Hence make sure that the
+ * buffer complies with the restrictions of the streaming DMA mapping API.
  * @payload must not be freed before the @callback is called.
  *
  * In case of request types without payload, @data is NULL and @length is 0.
@@ -411,7 +412,8 @@
  *
  * Returns the RCODE.  See fw_send_request() for parameter documentation.
  * Unlike fw_send_request(), @data points to the payload of the request or/and
- * to the payload of the response.
+ * to the payload of the response.  DMA mapping restrictions apply to outbound
+ * request payloads of >= 8 bytes but not to inbound response payloads.
  */
 int fw_run_transaction(struct fw_card *card, int tcode, int destination_id,
 		       int generation, int speed, unsigned long long offset,
@@ -1212,13 +1214,21 @@
 {
 	int ret;
 
+	fw_workqueue = alloc_workqueue("firewire",
+				       WQ_NON_REENTRANT | WQ_MEM_RECLAIM, 0);
+	if (!fw_workqueue)
+		return -ENOMEM;
+
 	ret = bus_register(&fw_bus_type);
-	if (ret < 0)
+	if (ret < 0) {
+		destroy_workqueue(fw_workqueue);
 		return ret;
+	}
 
 	fw_cdev_major = register_chrdev(0, "firewire", &fw_device_ops);
 	if (fw_cdev_major < 0) {
 		bus_unregister(&fw_bus_type);
+		destroy_workqueue(fw_workqueue);
 		return fw_cdev_major;
 	}
 
@@ -1234,6 +1244,7 @@
 {
 	unregister_chrdev(fw_cdev_major, "firewire");
 	bus_unregister(&fw_bus_type);
+	destroy_workqueue(fw_workqueue);
 	idr_destroy(&fw_device_idr);
 }
 
diff -druN linux-2.6.39-libre/drivers/firewire/net.c linux-3.0-rc7-libre/drivers/firewire/net.c
--- linux-2.6.39-libre/drivers/firewire/net.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/firewire/net.c	2011-07-11 19:51:52.000000000 -0400
@@ -881,7 +881,9 @@
 
 	spin_unlock_irqrestore(&dev->lock, flags);
 
-	if (retval < 0)
+	if (retval >= 0)
+		fw_iso_context_queue_flush(dev->broadcast_rcv_context);
+	else
 		fw_error("requeue failed\n");
 }
 
diff -druN linux-2.6.39-libre/drivers/firewire/ohci.c linux-3.0-rc7-libre/drivers/firewire/ohci.c
--- linux-2.6.39-libre/drivers/firewire/ohci.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/firewire/ohci.c	2011-07-11 19:51:52.000000000 -0400
@@ -264,6 +264,7 @@
 #define PCI_DEVICE_ID_AGERE_FW643	0x5901
 #define PCI_DEVICE_ID_JMICRON_JMB38X_FW	0x2380
 #define PCI_DEVICE_ID_TI_TSB12LV22	0x8009
+#define PCI_VENDOR_ID_PINNACLE_SYSTEMS	0x11bd
 
 #define QUIRK_CYCLE_TIMER		1
 #define QUIRK_RESET_PACKET		2
@@ -1006,13 +1007,12 @@
 
 static struct descriptor *find_branch_descriptor(struct descriptor *d, int z)
 {
-	int b, key;
+	__le16 branch;
 
-	b   = (le16_to_cpu(d->control) & DESCRIPTOR_BRANCH_ALWAYS) >> 2;
-	key = (le16_to_cpu(d->control) & DESCRIPTOR_KEY_IMMEDIATE) >> 8;
+	branch = d->control & cpu_to_le16(DESCRIPTOR_BRANCH_ALWAYS);
 
 	/* figure out which descriptor the branch address goes in */
-	if (z == 2 && (b == 3 || key == 2))
+	if (z == 2 && branch == cpu_to_le16(DESCRIPTOR_BRANCH_ALWAYS))
 		return d;
 	else
 		return d + z - 1;
@@ -1193,9 +1193,6 @@
 	wmb(); /* finish init of new descriptors before branch_address update */
 	ctx->prev->branch_address = cpu_to_le32(d_bus | z);
 	ctx->prev = find_branch_descriptor(d, z);
-
-	reg_write(ctx->ohci, CONTROL_SET(ctx->regs), CONTEXT_WAKE);
-	flush_writes(ctx->ohci);
 }
 
 static void context_stop(struct context *ctx)
@@ -1218,6 +1215,7 @@
 }
 
 struct driver_data {
+	u8 inline_data[8];
 	struct fw_packet *packet;
 };
 
@@ -1301,20 +1299,28 @@
 		return -1;
 	}
 
+	BUILD_BUG_ON(sizeof(struct driver_data) > sizeof(struct descriptor));
 	driver_data = (struct driver_data *) &d[3];
 	driver_data->packet = packet;
 	packet->driver_data = driver_data;
 
 	if (packet->payload_length > 0) {
-		payload_bus =
-			dma_map_single(ohci->card.device, packet->payload,
-				       packet->payload_length, DMA_TO_DEVICE);
-		if (dma_mapping_error(ohci->card.device, payload_bus)) {
-			packet->ack = RCODE_SEND_ERROR;
-			return -1;
+		if (packet->payload_length > sizeof(driver_data->inline_data)) {
+			payload_bus = dma_map_single(ohci->card.device,
+						     packet->payload,
+						     packet->payload_length,
+						     DMA_TO_DEVICE);
+			if (dma_mapping_error(ohci->card.device, payload_bus)) {
+				packet->ack = RCODE_SEND_ERROR;
+				return -1;
+			}
+			packet->payload_bus	= payload_bus;
+			packet->payload_mapped	= true;
+		} else {
+			memcpy(driver_data->inline_data, packet->payload,
+			       packet->payload_length);
+			payload_bus = d_bus + 3 * sizeof(*d);
 		}
-		packet->payload_bus	= payload_bus;
-		packet->payload_mapped	= true;
 
 		d[2].req_count    = cpu_to_le16(packet->payload_length);
 		d[2].data_address = cpu_to_le32(payload_bus);
@@ -1340,8 +1346,12 @@
 
 	context_append(ctx, d, z, 4 - z);
 
-	if (!ctx->running)
+	if (ctx->running) {
+		reg_write(ohci, CONTROL_SET(ctx->regs), CONTEXT_WAKE);
+		flush_writes(ohci);
+	} else {
 		context_run(ctx, 0);
+	}
 
 	return 0;
 }
@@ -2066,8 +2076,6 @@
 
 	reg_write(ohci, OHCI1394_SelfIDBuffer, ohci->self_id_bus);
 	reg_write(ohci, OHCI1394_LinkControlSet,
-		  OHCI1394_LinkControl_rcvSelfID |
-		  OHCI1394_LinkControl_rcvPhyPkt |
 		  OHCI1394_LinkControl_cycleTimerEnable |
 		  OHCI1394_LinkControl_cycleMaster);
 
@@ -2094,9 +2102,6 @@
 	reg_write(ohci, OHCI1394_FairnessControl, 0);
 	card->priority_budget_implemented = ohci->pri_req_max != 0;
 
-	ar_context_run(&ohci->ar_request_ctx);
-	ar_context_run(&ohci->ar_response_ctx);
-
 	reg_write(ohci, OHCI1394_PhyUpperBound, 0x00010000);
 	reg_write(ohci, OHCI1394_IntEventClear, ~0);
 	reg_write(ohci, OHCI1394_IntMaskClear, ~0);
@@ -2186,7 +2191,13 @@
 	reg_write(ohci, OHCI1394_HCControlSet,
 		  OHCI1394_HCControl_linkEnable |
 		  OHCI1394_HCControl_BIBimageValid);
-	flush_writes(ohci);
+
+	reg_write(ohci, OHCI1394_LinkControlSet,
+		  OHCI1394_LinkControl_rcvSelfID |
+		  OHCI1394_LinkControl_rcvPhyPkt);
+
+	ar_context_run(&ohci->ar_request_ctx);
+	ar_context_run(&ohci->ar_response_ctx); /* also flushes writes */
 
 	/* We are ready to go, reset bus to finish initialization. */
 	fw_schedule_bus_reset(&ohci->card, false, true);
@@ -3112,6 +3123,15 @@
 	return ret;
 }
 
+static void ohci_flush_queue_iso(struct fw_iso_context *base)
+{
+	struct context *ctx =
+			&container_of(base, struct iso_context, base)->context;
+
+	reg_write(ctx->ohci, CONTROL_SET(ctx->regs), CONTEXT_WAKE);
+	flush_writes(ctx->ohci);
+}
+
 static const struct fw_card_driver ohci_driver = {
 	.enable			= ohci_enable,
 	.read_phy_reg		= ohci_read_phy_reg,
@@ -3128,6 +3148,7 @@
 	.free_iso_context	= ohci_free_iso_context,
 	.set_iso_channels	= ohci_set_iso_channels,
 	.queue_iso		= ohci_queue_iso,
+	.flush_queue_iso	= ohci_flush_queue_iso,
 	.start_iso		= ohci_start_iso,
 	.stop_iso		= ohci_stop_iso,
 };
@@ -3170,6 +3191,11 @@
 	int i, err;
 	size_t size;
 
+	if (dev->vendor == PCI_VENDOR_ID_PINNACLE_SYSTEMS) {
+		dev_err(&dev->dev, "Pinnacle MovieBoard is not yet supported\n");
+		return -ENOSYS;
+	}
+
 	ohci = kzalloc(sizeof(*ohci), GFP_KERNEL);
 	if (ohci == NULL) {
 		err = -ENOMEM;
diff -druN linux-2.6.39-libre/drivers/firewire/sbp2.c linux-3.0-rc7-libre/drivers/firewire/sbp2.c
--- linux-2.6.39-libre/drivers/firewire/sbp2.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/firewire/sbp2.c	2011-07-11 19:51:52.000000000 -0400
@@ -125,9 +125,6 @@
 	", override internal blacklist = " __stringify(SBP2_WORKAROUND_OVERRIDE)
 	", or a combination)");
 
-/* I don't know why the SCSI stack doesn't define something like this... */
-typedef void (*scsi_done_fn_t)(struct scsi_cmnd *);
-
 static const char sbp2_driver_name[] = "sbp2";
 
 /*
@@ -261,7 +258,6 @@
 	struct kref kref;
 	dma_addr_t request_bus;
 	int rcode;
-	struct sbp2_pointer pointer;
 	void (*callback)(struct sbp2_orb * orb, struct sbp2_status * status);
 	struct list_head link;
 };
@@ -314,7 +310,6 @@
 		u8 command_block[SBP2_MAX_CDB_SIZE];
 	} request;
 	struct scsi_cmnd *cmd;
-	scsi_done_fn_t done;
 	struct sbp2_logical_unit *lu;
 
 	struct sbp2_pointer page_table[SG_ALL] __attribute__((aligned(8)));
@@ -494,10 +489,11 @@
 			  int node_id, int generation, u64 offset)
 {
 	struct fw_device *device = target_device(lu->tgt);
+	struct sbp2_pointer orb_pointer;
 	unsigned long flags;
 
-	orb->pointer.high = 0;
-	orb->pointer.low = cpu_to_be32(orb->request_bus);
+	orb_pointer.high = 0;
+	orb_pointer.low = cpu_to_be32(orb->request_bus);
 
 	spin_lock_irqsave(&device->card->lock, flags);
 	list_add_tail(&orb->link, &lu->orb_list);
@@ -508,7 +504,7 @@
 
 	fw_send_request(device->card, &orb->t, TCODE_WRITE_BLOCK_REQUEST,
 			node_id, generation, device->max_speed, offset,
-			&orb->pointer, 8, complete_transaction, orb);
+			&orb_pointer, 8, complete_transaction, orb);
 }
 
 static int sbp2_cancel_orbs(struct sbp2_logical_unit *lu)
@@ -830,8 +826,6 @@
 	kref_put(&tgt->kref, sbp2_release_target);
 }
 
-static struct workqueue_struct *sbp2_wq;
-
 /*
  * Always get the target's kref when scheduling work on one its units.
  * Each workqueue job is responsible to call sbp2_target_put() upon return.
@@ -839,7 +833,7 @@
 static void sbp2_queue_work(struct sbp2_logical_unit *lu, unsigned long delay)
 {
 	sbp2_target_get(lu->tgt);
-	if (!queue_delayed_work(sbp2_wq, &lu->work, delay))
+	if (!queue_delayed_work(fw_workqueue, &lu->work, delay))
 		sbp2_target_put(lu->tgt);
 }
 
@@ -1398,7 +1392,7 @@
 	sbp2_unmap_scatterlist(device->card->device, orb);
 
 	orb->cmd->result = result;
-	orb->done(orb->cmd);
+	orb->cmd->scsi_done(orb->cmd);
 }
 
 static int sbp2_map_scatterlist(struct sbp2_command_orb *orb,
@@ -1463,7 +1457,8 @@
 
 /* SCSI stack integration */
 
-static int sbp2_scsi_queuecommand_lck(struct scsi_cmnd *cmd, scsi_done_fn_t done)
+static int sbp2_scsi_queuecommand(struct Scsi_Host *shost,
+				  struct scsi_cmnd *cmd)
 {
 	struct sbp2_logical_unit *lu = cmd->device->hostdata;
 	struct fw_device *device = target_device(lu->tgt);
@@ -1477,7 +1472,7 @@
 	if (cmd->sc_data_direction == DMA_BIDIRECTIONAL) {
 		fw_error("Can't handle DMA_BIDIRECTIONAL, rejecting command\n");
 		cmd->result = DID_ERROR << 16;
-		done(cmd);
+		cmd->scsi_done(cmd);
 		return 0;
 	}
 
@@ -1490,11 +1485,8 @@
 	/* Initialize rcode to something not RCODE_COMPLETE. */
 	orb->base.rcode = -1;
 	kref_init(&orb->base.kref);
-
-	orb->lu   = lu;
-	orb->done = done;
-	orb->cmd  = cmd;
-
+	orb->lu = lu;
+	orb->cmd = cmd;
 	orb->request.next.high = cpu_to_be32(SBP2_ORB_NULL);
 	orb->request.misc = cpu_to_be32(
 		COMMAND_ORB_MAX_PAYLOAD(lu->tgt->max_payload) |
@@ -1529,8 +1521,6 @@
 	return retval;
 }
 
-static DEF_SCSI_QCMD(sbp2_scsi_queuecommand)
-
 static int sbp2_scsi_slave_alloc(struct scsi_device *sdev)
 {
 	struct sbp2_logical_unit *lu = sdev->hostdata;
@@ -1653,17 +1643,12 @@
 
 static int __init sbp2_init(void)
 {
-	sbp2_wq = create_singlethread_workqueue(KBUILD_MODNAME);
-	if (!sbp2_wq)
-		return -ENOMEM;
-
 	return driver_register(&sbp2_driver.driver);
 }
 
 static void __exit sbp2_cleanup(void)
 {
 	driver_unregister(&sbp2_driver.driver);
-	destroy_workqueue(sbp2_wq);
 }
 
 module_init(sbp2_init);
diff -druN linux-2.6.39-libre/drivers/firmware/edd.c linux-3.0-rc7-libre/drivers/firmware/edd.c
--- linux-2.6.39-libre/drivers/firmware/edd.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/firmware/edd.c	2011-07-11 19:51:52.000000000 -0400
@@ -531,8 +531,8 @@
 edd_has_edd30(struct edd_device *edev)
 {
 	struct edd_info *info;
-	int i, nonzero_path = 0;
-	char c;
+	int i;
+	u8 csum = 0;
 
 	if (!edev)
 		return 0;
@@ -544,16 +544,16 @@
 		return 0;
 	}
 
-	for (i = 30; i <= 73; i++) {
-		c = *(((uint8_t *) info) + i + 4);
-		if (c) {
-			nonzero_path++;
-			break;
-		}
-	}
-	if (!nonzero_path) {
+
+	/* We support only T13 spec */
+	if (info->params.device_path_info_length != 44)
+		return 0;
+
+	for (i = 30; i < info->params.device_path_info_length + 30; i++)
+		csum += *(((u8 *)&info->params) + i);
+
+	if (csum)
 		return 0;
-	}
 
 	return 1;
 }
diff -druN linux-2.6.39-libre/drivers/firmware/efivars.c linux-3.0-rc7-libre/drivers/firmware/efivars.c
--- linux-2.6.39-libre/drivers/firmware/efivars.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/firmware/efivars.c	2011-07-11 19:51:52.000000000 -0400
@@ -321,7 +321,7 @@
 
 /*
  * Generic read/write functions that call the specific functions of
- * the atttributes...
+ * the attributes...
  */
 static ssize_t efivar_attr_show(struct kobject *kobj, struct attribute *attr,
 				char *buf)
@@ -677,8 +677,8 @@
 
 	return 0;
 out_free:
-	kfree(efivars->new_var);
-	efivars->new_var = NULL;
+	kfree(efivars->del_var);
+	efivars->del_var = NULL;
 	kfree(efivars->new_var);
 	efivars->new_var = NULL;
 	return error;
@@ -803,6 +803,8 @@
 	ops.set_variable = efi.set_variable;
 	ops.get_next_variable = efi.get_next_variable;
 	error = register_efivars(&__efivars, &ops, efi_kobj);
+	if (error)
+		goto err_put;
 
 	/* Don't forget the systab entry */
 	error = sysfs_create_group(efi_kobj, &efi_subsys_attr_group);
@@ -810,18 +812,25 @@
 		printk(KERN_ERR
 		       "efivars: Sysfs attribute export failed with error %d.\n",
 		       error);
-		unregister_efivars(&__efivars);
-		kobject_put(efi_kobj);
+		goto err_unregister;
 	}
 
+	return 0;
+
+err_unregister:
+	unregister_efivars(&__efivars);
+err_put:
+	kobject_put(efi_kobj);
 	return error;
 }
 
 static void __exit
 efivars_exit(void)
 {
-	unregister_efivars(&__efivars);
-	kobject_put(efi_kobj);
+	if (efi_enabled) {
+		unregister_efivars(&__efivars);
+		kobject_put(efi_kobj);
+	}
 }
 
 module_init(efivars_init);
diff -druN linux-2.6.39-libre/drivers/firmware/google/gsmi.c linux-3.0-rc7-libre/drivers/firmware/google/gsmi.c
--- linux-2.6.39-libre/drivers/firmware/google/gsmi.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/firmware/google/gsmi.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,940 @@
+/*
+ * Copyright 2010 Google Inc. All Rights Reserved.
+ * Author: dlaurie@google.com (Duncan Laurie)
+ *
+ * Re-worked to expose sysfs APIs by mikew@google.com (Mike Waychison)
+ *
+ * EFI SMI interface for Google platforms
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/device.h>
+#include <linux/platform_device.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/spinlock.h>
+#include <linux/dma-mapping.h>
+#include <linux/dmapool.h>
+#include <linux/fs.h>
+#include <linux/slab.h>
+#include <linux/ioctl.h>
+#include <linux/acpi.h>
+#include <linux/io.h>
+#include <linux/uaccess.h>
+#include <linux/dmi.h>
+#include <linux/kdebug.h>
+#include <linux/reboot.h>
+#include <linux/efi.h>
+
+#define GSMI_SHUTDOWN_CLEAN	0	/* Clean Shutdown */
+/* TODO(mikew@google.com): Tie in HARDLOCKUP_DETECTOR with NMIWDT */
+#define GSMI_SHUTDOWN_NMIWDT	1	/* NMI Watchdog */
+#define GSMI_SHUTDOWN_PANIC	2	/* Panic */
+#define GSMI_SHUTDOWN_OOPS	3	/* Oops */
+#define GSMI_SHUTDOWN_DIE	4	/* Die -- No longer meaningful */
+#define GSMI_SHUTDOWN_MCE	5	/* Machine Check */
+#define GSMI_SHUTDOWN_SOFTWDT	6	/* Software Watchdog */
+#define GSMI_SHUTDOWN_MBE	7	/* Uncorrected ECC */
+#define GSMI_SHUTDOWN_TRIPLE	8	/* Triple Fault */
+
+#define DRIVER_VERSION		"1.0"
+#define GSMI_GUID_SIZE		16
+#define GSMI_BUF_SIZE		1024
+#define GSMI_BUF_ALIGN		sizeof(u64)
+#define GSMI_CALLBACK		0xef
+
+/* SMI return codes */
+#define GSMI_SUCCESS		0x00
+#define GSMI_UNSUPPORTED2	0x03
+#define GSMI_LOG_FULL		0x0b
+#define GSMI_VAR_NOT_FOUND	0x0e
+#define GSMI_HANDSHAKE_SPIN	0x7d
+#define GSMI_HANDSHAKE_CF	0x7e
+#define GSMI_HANDSHAKE_NONE	0x7f
+#define GSMI_INVALID_PARAMETER	0x82
+#define GSMI_UNSUPPORTED	0x83
+#define GSMI_BUFFER_TOO_SMALL	0x85
+#define GSMI_NOT_READY		0x86
+#define GSMI_DEVICE_ERROR	0x87
+#define GSMI_NOT_FOUND		0x8e
+
+#define QUIRKY_BOARD_HASH 0x78a30a50
+
+/* Internally used commands passed to the firmware */
+#define GSMI_CMD_GET_NVRAM_VAR		0x01
+#define GSMI_CMD_GET_NEXT_VAR		0x02
+#define GSMI_CMD_SET_NVRAM_VAR		0x03
+#define GSMI_CMD_SET_EVENT_LOG		0x08
+#define GSMI_CMD_CLEAR_EVENT_LOG	0x09
+#define GSMI_CMD_CLEAR_CONFIG		0x20
+#define GSMI_CMD_HANDSHAKE_TYPE		0xC1
+
+/* Magic entry type for kernel events */
+#define GSMI_LOG_ENTRY_TYPE_KERNEL     0xDEAD
+
+/* SMI buffers must be in 32bit physical address space */
+struct gsmi_buf {
+	u8 *start;			/* start of buffer */
+	size_t length;			/* length of buffer */
+	dma_addr_t handle;		/* dma allocation handle */
+	u32 address;			/* physical address of buffer */
+};
+
+struct gsmi_device {
+	struct platform_device *pdev;	/* platform device */
+	struct gsmi_buf *name_buf;	/* variable name buffer */
+	struct gsmi_buf *data_buf;	/* generic data buffer */
+	struct gsmi_buf *param_buf;	/* parameter buffer */
+	spinlock_t lock;		/* serialize access to SMIs */
+	u16 smi_cmd;			/* SMI command port */
+	int handshake_type;		/* firmware handler interlock type */
+	struct dma_pool *dma_pool;	/* DMA buffer pool */
+} gsmi_dev;
+
+/* Packed structures for communicating with the firmware */
+struct gsmi_nvram_var_param {
+	efi_guid_t	guid;
+	u32		name_ptr;
+	u32		attributes;
+	u32		data_len;
+	u32		data_ptr;
+} __packed;
+
+struct gsmi_get_next_var_param {
+	u8	guid[GSMI_GUID_SIZE];
+	u32	name_ptr;
+	u32	name_len;
+} __packed;
+
+struct gsmi_set_eventlog_param {
+	u32	data_ptr;
+	u32	data_len;
+	u32	type;
+} __packed;
+
+/* Event log formats */
+struct gsmi_log_entry_type_1 {
+	u16	type;
+	u32	instance;
+} __packed;
+
+
+/*
+ * Some platforms don't have explicit SMI handshake
+ * and need to wait for SMI to complete.
+ */
+#define GSMI_DEFAULT_SPINCOUNT	0x10000
+static unsigned int spincount = GSMI_DEFAULT_SPINCOUNT;
+module_param(spincount, uint, 0600);
+MODULE_PARM_DESC(spincount,
+	"The number of loop iterations to use when using the spin handshake.");
+
+static struct gsmi_buf *gsmi_buf_alloc(void)
+{
+	struct gsmi_buf *smibuf;
+
+	smibuf = kzalloc(sizeof(*smibuf), GFP_KERNEL);
+	if (!smibuf) {
+		printk(KERN_ERR "gsmi: out of memory\n");
+		return NULL;
+	}
+
+	/* allocate buffer in 32bit address space */
+	smibuf->start = dma_pool_alloc(gsmi_dev.dma_pool, GFP_KERNEL,
+				       &smibuf->handle);
+	if (!smibuf->start) {
+		printk(KERN_ERR "gsmi: failed to allocate name buffer\n");
+		kfree(smibuf);
+		return NULL;
+	}
+
+	/* fill in the buffer handle */
+	smibuf->length = GSMI_BUF_SIZE;
+	smibuf->address = (u32)virt_to_phys(smibuf->start);
+
+	return smibuf;
+}
+
+static void gsmi_buf_free(struct gsmi_buf *smibuf)
+{
+	if (smibuf) {
+		if (smibuf->start)
+			dma_pool_free(gsmi_dev.dma_pool, smibuf->start,
+				      smibuf->handle);
+		kfree(smibuf);
+	}
+}
+
+/*
+ * Make a call to gsmi func(sub).  GSMI error codes are translated to
+ * in-kernel errnos (0 on success, -ERRNO on error).
+ */
+static int gsmi_exec(u8 func, u8 sub)
+{
+	u16 cmd = (sub << 8) | func;
+	u16 result = 0;
+	int rc = 0;
+
+	/*
+	 * AH  : Subfunction number
+	 * AL  : Function number
+	 * EBX : Parameter block address
+	 * DX  : SMI command port
+	 *
+	 * Three protocols here. See also the comment in gsmi_init().
+	 */
+	if (gsmi_dev.handshake_type == GSMI_HANDSHAKE_CF) {
+		/*
+		 * If handshake_type == HANDSHAKE_CF then set CF on the
+		 * way in and wait for the handler to clear it; this avoids
+		 * corrupting register state on those chipsets which have
+		 * a delay between writing the SMI trigger register and
+		 * entering SMM.
+		 */
+		asm volatile (
+			"stc\n"
+			"outb %%al, %%dx\n"
+		"1:      jc 1b\n"
+			: "=a" (result)
+			: "0" (cmd),
+			  "d" (gsmi_dev.smi_cmd),
+			  "b" (gsmi_dev.param_buf->address)
+			: "memory", "cc"
+		);
+	} else if (gsmi_dev.handshake_type == GSMI_HANDSHAKE_SPIN) {
+		/*
+		 * If handshake_type == HANDSHAKE_SPIN we spin a
+		 * hundred-ish usecs to ensure the SMI has triggered.
+		 */
+		asm volatile (
+			"outb %%al, %%dx\n"
+		"1:      loop 1b\n"
+			: "=a" (result)
+			: "0" (cmd),
+			  "d" (gsmi_dev.smi_cmd),
+			  "b" (gsmi_dev.param_buf->address),
+			  "c" (spincount)
+			: "memory", "cc"
+		);
+	} else {
+		/*
+		 * If handshake_type == HANDSHAKE_NONE we do nothing;
+		 * either we don't need to or it's legacy firmware that
+		 * doesn't understand the CF protocol.
+		 */
+		asm volatile (
+			"outb %%al, %%dx\n\t"
+			: "=a" (result)
+			: "0" (cmd),
+			  "d" (gsmi_dev.smi_cmd),
+			  "b" (gsmi_dev.param_buf->address)
+			: "memory", "cc"
+		);
+	}
+
+	/* check return code from SMI handler */
+	switch (result) {
+	case GSMI_SUCCESS:
+		break;
+	case GSMI_VAR_NOT_FOUND:
+		/* not really an error, but let the caller know */
+		rc = 1;
+		break;
+	case GSMI_INVALID_PARAMETER:
+		printk(KERN_ERR "gsmi: exec 0x%04x: Invalid parameter\n", cmd);
+		rc = -EINVAL;
+		break;
+	case GSMI_BUFFER_TOO_SMALL:
+		printk(KERN_ERR "gsmi: exec 0x%04x: Buffer too small\n", cmd);
+		rc = -ENOMEM;
+		break;
+	case GSMI_UNSUPPORTED:
+	case GSMI_UNSUPPORTED2:
+		if (sub != GSMI_CMD_HANDSHAKE_TYPE)
+			printk(KERN_ERR "gsmi: exec 0x%04x: Not supported\n",
+			       cmd);
+		rc = -ENOSYS;
+		break;
+	case GSMI_NOT_READY:
+		printk(KERN_ERR "gsmi: exec 0x%04x: Not ready\n", cmd);
+		rc = -EBUSY;
+		break;
+	case GSMI_DEVICE_ERROR:
+		printk(KERN_ERR "gsmi: exec 0x%04x: Device error\n", cmd);
+		rc = -EFAULT;
+		break;
+	case GSMI_NOT_FOUND:
+		printk(KERN_ERR "gsmi: exec 0x%04x: Data not found\n", cmd);
+		rc = -ENOENT;
+		break;
+	case GSMI_LOG_FULL:
+		printk(KERN_ERR "gsmi: exec 0x%04x: Log full\n", cmd);
+		rc = -ENOSPC;
+		break;
+	case GSMI_HANDSHAKE_CF:
+	case GSMI_HANDSHAKE_SPIN:
+	case GSMI_HANDSHAKE_NONE:
+		rc = result;
+		break;
+	default:
+		printk(KERN_ERR "gsmi: exec 0x%04x: Unknown error 0x%04x\n",
+		       cmd, result);
+		rc = -ENXIO;
+	}
+
+	return rc;
+}
+
+/* Return the number of unicode characters in data */
+static size_t
+utf16_strlen(efi_char16_t *data, unsigned long maxlength)
+{
+	unsigned long length = 0;
+
+	while (*data++ != 0 && length < maxlength)
+		length++;
+	return length;
+}
+
+static efi_status_t gsmi_get_variable(efi_char16_t *name,
+				      efi_guid_t *vendor, u32 *attr,
+				      unsigned long *data_size,
+				      void *data)
+{
+	struct gsmi_nvram_var_param param = {
+		.name_ptr = gsmi_dev.name_buf->address,
+		.data_ptr = gsmi_dev.data_buf->address,
+		.data_len = (u32)*data_size,
+	};
+	efi_status_t ret = EFI_SUCCESS;
+	unsigned long flags;
+	size_t name_len = utf16_strlen(name, GSMI_BUF_SIZE / 2);
+	int rc;
+
+	if (name_len >= GSMI_BUF_SIZE / 2)
+		return EFI_BAD_BUFFER_SIZE;
+
+	spin_lock_irqsave(&gsmi_dev.lock, flags);
+
+	/* Vendor guid */
+	memcpy(&param.guid, vendor, sizeof(param.guid));
+
+	/* variable name, already in UTF-16 */
+	memset(gsmi_dev.name_buf->start, 0, gsmi_dev.name_buf->length);
+	memcpy(gsmi_dev.name_buf->start, name, name_len * 2);
+
+	/* data pointer */
+	memset(gsmi_dev.data_buf->start, 0, gsmi_dev.data_buf->length);
+
+	/* parameter buffer */
+	memset(gsmi_dev.param_buf->start, 0, gsmi_dev.param_buf->length);
+	memcpy(gsmi_dev.param_buf->start, &param, sizeof(param));
+
+	rc = gsmi_exec(GSMI_CALLBACK, GSMI_CMD_GET_NVRAM_VAR);
+	if (rc < 0) {
+		printk(KERN_ERR "gsmi: Get Variable failed\n");
+		ret = EFI_LOAD_ERROR;
+	} else if (rc == 1) {
+		/* variable was not found */
+		ret = EFI_NOT_FOUND;
+	} else {
+		/* Get the arguments back */
+		memcpy(&param, gsmi_dev.param_buf->start, sizeof(param));
+
+		/* The size reported is the min of all of our buffers */
+		*data_size = min(*data_size, gsmi_dev.data_buf->length);
+		*data_size = min_t(unsigned long, *data_size, param.data_len);
+
+		/* Copy data back to return buffer. */
+		memcpy(data, gsmi_dev.data_buf->start, *data_size);
+
+		/* All variables are have the following attributes */
+		*attr = EFI_VARIABLE_NON_VOLATILE |
+			EFI_VARIABLE_BOOTSERVICE_ACCESS |
+			EFI_VARIABLE_RUNTIME_ACCESS;
+	}
+
+	spin_unlock_irqrestore(&gsmi_dev.lock, flags);
+
+	return ret;
+}
+
+static efi_status_t gsmi_get_next_variable(unsigned long *name_size,
+					   efi_char16_t *name,
+					   efi_guid_t *vendor)
+{
+	struct gsmi_get_next_var_param param = {
+		.name_ptr = gsmi_dev.name_buf->address,
+		.name_len = gsmi_dev.name_buf->length,
+	};
+	efi_status_t ret = EFI_SUCCESS;
+	int rc;
+	unsigned long flags;
+
+	/* For the moment, only support buffers that exactly match in size */
+	if (*name_size != GSMI_BUF_SIZE)
+		return EFI_BAD_BUFFER_SIZE;
+
+	/* Let's make sure the thing is at least null-terminated */
+	if (utf16_strlen(name, GSMI_BUF_SIZE / 2) == GSMI_BUF_SIZE / 2)
+		return EFI_INVALID_PARAMETER;
+
+	spin_lock_irqsave(&gsmi_dev.lock, flags);
+
+	/* guid */
+	memcpy(&param.guid, vendor, sizeof(param.guid));
+
+	/* variable name, already in UTF-16 */
+	memcpy(gsmi_dev.name_buf->start, name, *name_size);
+
+	/* parameter buffer */
+	memset(gsmi_dev.param_buf->start, 0, gsmi_dev.param_buf->length);
+	memcpy(gsmi_dev.param_buf->start, &param, sizeof(param));
+
+	rc = gsmi_exec(GSMI_CALLBACK, GSMI_CMD_GET_NEXT_VAR);
+	if (rc < 0) {
+		printk(KERN_ERR "gsmi: Get Next Variable Name failed\n");
+		ret = EFI_LOAD_ERROR;
+	} else if (rc == 1) {
+		/* variable not found -- end of list */
+		ret = EFI_NOT_FOUND;
+	} else {
+		/* copy variable data back to return buffer */
+		memcpy(&param, gsmi_dev.param_buf->start, sizeof(param));
+
+		/* Copy the name back */
+		memcpy(name, gsmi_dev.name_buf->start, GSMI_BUF_SIZE);
+		*name_size = utf16_strlen(name, GSMI_BUF_SIZE / 2) * 2;
+
+		/* copy guid to return buffer */
+		memcpy(vendor, &param.guid, sizeof(param.guid));
+		ret = EFI_SUCCESS;
+	}
+
+	spin_unlock_irqrestore(&gsmi_dev.lock, flags);
+
+	return ret;
+}
+
+static efi_status_t gsmi_set_variable(efi_char16_t *name,
+				      efi_guid_t *vendor,
+				      unsigned long attr,
+				      unsigned long data_size,
+				      void *data)
+{
+	struct gsmi_nvram_var_param param = {
+		.name_ptr = gsmi_dev.name_buf->address,
+		.data_ptr = gsmi_dev.data_buf->address,
+		.data_len = (u32)data_size,
+		.attributes = EFI_VARIABLE_NON_VOLATILE |
+			      EFI_VARIABLE_BOOTSERVICE_ACCESS |
+			      EFI_VARIABLE_RUNTIME_ACCESS,
+	};
+	size_t name_len = utf16_strlen(name, GSMI_BUF_SIZE / 2);
+	efi_status_t ret = EFI_SUCCESS;
+	int rc;
+	unsigned long flags;
+
+	if (name_len >= GSMI_BUF_SIZE / 2)
+		return EFI_BAD_BUFFER_SIZE;
+
+	spin_lock_irqsave(&gsmi_dev.lock, flags);
+
+	/* guid */
+	memcpy(&param.guid, vendor, sizeof(param.guid));
+
+	/* variable name, already in UTF-16 */
+	memset(gsmi_dev.name_buf->start, 0, gsmi_dev.name_buf->length);
+	memcpy(gsmi_dev.name_buf->start, name, name_len * 2);
+
+	/* data pointer */
+	memset(gsmi_dev.data_buf->start, 0, gsmi_dev.data_buf->length);
+	memcpy(gsmi_dev.data_buf->start, data, data_size);
+
+	/* parameter buffer */
+	memset(gsmi_dev.param_buf->start, 0, gsmi_dev.param_buf->length);
+	memcpy(gsmi_dev.param_buf->start, &param, sizeof(param));
+
+	rc = gsmi_exec(GSMI_CALLBACK, GSMI_CMD_SET_NVRAM_VAR);
+	if (rc < 0) {
+		printk(KERN_ERR "gsmi: Set Variable failed\n");
+		ret = EFI_INVALID_PARAMETER;
+	}
+
+	spin_unlock_irqrestore(&gsmi_dev.lock, flags);
+
+	return ret;
+}
+
+static const struct efivar_operations efivar_ops = {
+	.get_variable = gsmi_get_variable,
+	.set_variable = gsmi_set_variable,
+	.get_next_variable = gsmi_get_next_variable,
+};
+
+static ssize_t eventlog_write(struct file *filp, struct kobject *kobj,
+			       struct bin_attribute *bin_attr,
+			       char *buf, loff_t pos, size_t count)
+{
+	struct gsmi_set_eventlog_param param = {
+		.data_ptr = gsmi_dev.data_buf->address,
+	};
+	int rc = 0;
+	unsigned long flags;
+
+	/* Pull the type out */
+	if (count < sizeof(u32))
+		return -EINVAL;
+	param.type = *(u32 *)buf;
+	count -= sizeof(u32);
+	buf += sizeof(u32);
+
+	/* The remaining buffer is the data payload */
+	if (count > gsmi_dev.data_buf->length)
+		return -EINVAL;
+	param.data_len = count - sizeof(u32);
+
+	spin_lock_irqsave(&gsmi_dev.lock, flags);
+
+	/* data pointer */
+	memset(gsmi_dev.data_buf->start, 0, gsmi_dev.data_buf->length);
+	memcpy(gsmi_dev.data_buf->start, buf, param.data_len);
+
+	/* parameter buffer */
+	memset(gsmi_dev.param_buf->start, 0, gsmi_dev.param_buf->length);
+	memcpy(gsmi_dev.param_buf->start, &param, sizeof(param));
+
+	rc = gsmi_exec(GSMI_CALLBACK, GSMI_CMD_SET_EVENT_LOG);
+	if (rc < 0)
+		printk(KERN_ERR "gsmi: Set Event Log failed\n");
+
+	spin_unlock_irqrestore(&gsmi_dev.lock, flags);
+
+	return rc;
+
+}
+
+static struct bin_attribute eventlog_bin_attr = {
+	.attr = {.name = "append_to_eventlog", .mode = 0200},
+	.write = eventlog_write,
+};
+
+static ssize_t gsmi_clear_eventlog_store(struct kobject *kobj,
+					 struct kobj_attribute *attr,
+					 const char *buf, size_t count)
+{
+	int rc;
+	unsigned long flags;
+	unsigned long val;
+	struct {
+		u32 percentage;
+		u32 data_type;
+	} param;
+
+	rc = strict_strtoul(buf, 0, &val);
+	if (rc)
+		return rc;
+
+	/*
+	 * Value entered is a percentage, 0 through 100, anything else
+	 * is invalid.
+	 */
+	if (val > 100)
+		return -EINVAL;
+
+	/* data_type here selects the smbios event log. */
+	param.percentage = val;
+	param.data_type = 0;
+
+	spin_lock_irqsave(&gsmi_dev.lock, flags);
+
+	/* parameter buffer */
+	memset(gsmi_dev.param_buf->start, 0, gsmi_dev.param_buf->length);
+	memcpy(gsmi_dev.param_buf->start, &param, sizeof(param));
+
+	rc = gsmi_exec(GSMI_CALLBACK, GSMI_CMD_CLEAR_EVENT_LOG);
+
+	spin_unlock_irqrestore(&gsmi_dev.lock, flags);
+
+	if (rc)
+		return rc;
+	return count;
+}
+
+static struct kobj_attribute gsmi_clear_eventlog_attr = {
+	.attr = {.name = "clear_eventlog", .mode = 0200},
+	.store = gsmi_clear_eventlog_store,
+};
+
+static ssize_t gsmi_clear_config_store(struct kobject *kobj,
+				       struct kobj_attribute *attr,
+				       const char *buf, size_t count)
+{
+	int rc;
+	unsigned long flags;
+
+	spin_lock_irqsave(&gsmi_dev.lock, flags);
+
+	/* clear parameter buffer */
+	memset(gsmi_dev.param_buf->start, 0, gsmi_dev.param_buf->length);
+
+	rc = gsmi_exec(GSMI_CALLBACK, GSMI_CMD_CLEAR_CONFIG);
+
+	spin_unlock_irqrestore(&gsmi_dev.lock, flags);
+
+	if (rc)
+		return rc;
+	return count;
+}
+
+static struct kobj_attribute gsmi_clear_config_attr = {
+	.attr = {.name = "clear_config", .mode = 0200},
+	.store = gsmi_clear_config_store,
+};
+
+static const struct attribute *gsmi_attrs[] = {
+	&gsmi_clear_config_attr.attr,
+	&gsmi_clear_eventlog_attr.attr,
+	NULL,
+};
+
+static int gsmi_shutdown_reason(int reason)
+{
+	struct gsmi_log_entry_type_1 entry = {
+		.type     = GSMI_LOG_ENTRY_TYPE_KERNEL,
+		.instance = reason,
+	};
+	struct gsmi_set_eventlog_param param = {
+		.data_len = sizeof(entry),
+		.type     = 1,
+	};
+	static int saved_reason;
+	int rc = 0;
+	unsigned long flags;
+
+	/* avoid duplicate entries in the log */
+	if (saved_reason & (1 << reason))
+		return 0;
+
+	spin_lock_irqsave(&gsmi_dev.lock, flags);
+
+	saved_reason |= (1 << reason);
+
+	/* data pointer */
+	memset(gsmi_dev.data_buf->start, 0, gsmi_dev.data_buf->length);
+	memcpy(gsmi_dev.data_buf->start, &entry, sizeof(entry));
+
+	/* parameter buffer */
+	param.data_ptr = gsmi_dev.data_buf->address;
+	memset(gsmi_dev.param_buf->start, 0, gsmi_dev.param_buf->length);
+	memcpy(gsmi_dev.param_buf->start, &param, sizeof(param));
+
+	rc = gsmi_exec(GSMI_CALLBACK, GSMI_CMD_SET_EVENT_LOG);
+
+	spin_unlock_irqrestore(&gsmi_dev.lock, flags);
+
+	if (rc < 0)
+		printk(KERN_ERR "gsmi: Log Shutdown Reason failed\n");
+	else
+		printk(KERN_EMERG "gsmi: Log Shutdown Reason 0x%02x\n",
+		       reason);
+
+	return rc;
+}
+
+static int gsmi_reboot_callback(struct notifier_block *nb,
+				unsigned long reason, void *arg)
+{
+	gsmi_shutdown_reason(GSMI_SHUTDOWN_CLEAN);
+	return NOTIFY_DONE;
+}
+
+static struct notifier_block gsmi_reboot_notifier = {
+	.notifier_call = gsmi_reboot_callback
+};
+
+static int gsmi_die_callback(struct notifier_block *nb,
+			     unsigned long reason, void *arg)
+{
+	if (reason == DIE_OOPS)
+		gsmi_shutdown_reason(GSMI_SHUTDOWN_OOPS);
+	return NOTIFY_DONE;
+}
+
+static struct notifier_block gsmi_die_notifier = {
+	.notifier_call = gsmi_die_callback
+};
+
+static int gsmi_panic_callback(struct notifier_block *nb,
+			       unsigned long reason, void *arg)
+{
+	gsmi_shutdown_reason(GSMI_SHUTDOWN_PANIC);
+	return NOTIFY_DONE;
+}
+
+static struct notifier_block gsmi_panic_notifier = {
+	.notifier_call = gsmi_panic_callback,
+};
+
+/*
+ * This hash function was blatantly copied from include/linux/hash.h.
+ * It is used by this driver to obfuscate a board name that requires a
+ * quirk within this driver.
+ *
+ * Please do not remove this copy of the function as any changes to the
+ * global utility hash_64() function would break this driver's ability
+ * to identify a board and provide the appropriate quirk -- mikew@google.com
+ */
+static u64 __init local_hash_64(u64 val, unsigned bits)
+{
+	u64 hash = val;
+
+	/*  Sigh, gcc can't optimise this alone like it does for 32 bits. */
+	u64 n = hash;
+	n <<= 18;
+	hash -= n;
+	n <<= 33;
+	hash -= n;
+	n <<= 3;
+	hash += n;
+	n <<= 3;
+	hash -= n;
+	n <<= 4;
+	hash += n;
+	n <<= 2;
+	hash += n;
+
+	/* High bits are more random, so use them. */
+	return hash >> (64 - bits);
+}
+
+static u32 __init hash_oem_table_id(char s[8])
+{
+	u64 input;
+	memcpy(&input, s, 8);
+	return local_hash_64(input, 32);
+}
+
+static struct dmi_system_id gsmi_dmi_table[] __initdata = {
+	{
+		.ident = "Google Board",
+		.matches = {
+			DMI_MATCH(DMI_BOARD_VENDOR, "Google, Inc."),
+		},
+	},
+	{}
+};
+MODULE_DEVICE_TABLE(dmi, gsmi_dmi_table);
+
+static __init int gsmi_system_valid(void)
+{
+	u32 hash;
+
+	if (!dmi_check_system(gsmi_dmi_table))
+		return -ENODEV;
+
+	/*
+	 * Only newer firmware supports the gsmi interface.  All older
+	 * firmware that didn't support this interface used to plug the
+	 * table name in the first four bytes of the oem_table_id field.
+	 * Newer firmware doesn't do that though, so use that as the
+	 * discriminant factor.  We have to do this in order to
+	 * whitewash our board names out of the public driver.
+	 */
+	if (!strncmp(acpi_gbl_FADT.header.oem_table_id, "FACP", 4)) {
+		printk(KERN_INFO "gsmi: Board is too old\n");
+		return -ENODEV;
+	}
+
+	/* Disable on board with 1.0 BIOS due to Google bug 2602657 */
+	hash = hash_oem_table_id(acpi_gbl_FADT.header.oem_table_id);
+	if (hash == QUIRKY_BOARD_HASH) {
+		const char *bios_ver = dmi_get_system_info(DMI_BIOS_VERSION);
+		if (strncmp(bios_ver, "1.0", 3) == 0) {
+			pr_info("gsmi: disabled on this board's BIOS %s\n",
+				bios_ver);
+			return -ENODEV;
+		}
+	}
+
+	/* check for valid SMI command port in ACPI FADT */
+	if (acpi_gbl_FADT.smi_command == 0) {
+		pr_info("gsmi: missing smi_command\n");
+		return -ENODEV;
+	}
+
+	/* Found */
+	return 0;
+}
+
+static struct kobject *gsmi_kobj;
+static struct efivars efivars;
+
+static __init int gsmi_init(void)
+{
+	unsigned long flags;
+	int ret;
+
+	ret = gsmi_system_valid();
+	if (ret)
+		return ret;
+
+	gsmi_dev.smi_cmd = acpi_gbl_FADT.smi_command;
+
+	/* register device */
+	gsmi_dev.pdev = platform_device_register_simple("gsmi", -1, NULL, 0);
+	if (IS_ERR(gsmi_dev.pdev)) {
+		printk(KERN_ERR "gsmi: unable to register platform device\n");
+		return PTR_ERR(gsmi_dev.pdev);
+	}
+
+	/* SMI access needs to be serialized */
+	spin_lock_init(&gsmi_dev.lock);
+
+	/* SMI callbacks require 32bit addresses */
+	gsmi_dev.pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
+	gsmi_dev.pdev->dev.dma_mask =
+		&gsmi_dev.pdev->dev.coherent_dma_mask;
+	ret = -ENOMEM;
+	gsmi_dev.dma_pool = dma_pool_create("gsmi", &gsmi_dev.pdev->dev,
+					     GSMI_BUF_SIZE, GSMI_BUF_ALIGN, 0);
+	if (!gsmi_dev.dma_pool)
+		goto out_err;
+
+	/*
+	 * pre-allocate buffers because sometimes we are called when
+	 * this is not feasible: oops, panic, die, mce, etc
+	 */
+	gsmi_dev.name_buf = gsmi_buf_alloc();
+	if (!gsmi_dev.name_buf) {
+		printk(KERN_ERR "gsmi: failed to allocate name buffer\n");
+		goto out_err;
+	}
+
+	gsmi_dev.data_buf = gsmi_buf_alloc();
+	if (!gsmi_dev.data_buf) {
+		printk(KERN_ERR "gsmi: failed to allocate data buffer\n");
+		goto out_err;
+	}
+
+	gsmi_dev.param_buf = gsmi_buf_alloc();
+	if (!gsmi_dev.param_buf) {
+		printk(KERN_ERR "gsmi: failed to allocate param buffer\n");
+		goto out_err;
+	}
+
+	/*
+	 * Determine type of handshake used to serialize the SMI
+	 * entry. See also gsmi_exec().
+	 *
+	 * There's a "behavior" present on some chipsets where writing the
+	 * SMI trigger register in the southbridge doesn't result in an
+	 * immediate SMI. Rather, the processor can execute "a few" more
+	 * instructions before the SMI takes effect. To ensure synchronous
+	 * behavior, implement a handshake between the kernel driver and the
+	 * firmware handler to spin until released. This ioctl determines
+	 * the type of handshake.
+	 *
+	 * NONE: The firmware handler does not implement any
+	 * handshake. Either it doesn't need to, or it's legacy firmware
+	 * that doesn't know it needs to and never will.
+	 *
+	 * CF: The firmware handler will clear the CF in the saved
+	 * state before returning. The driver may set the CF and test for
+	 * it to clear before proceeding.
+	 *
+	 * SPIN: The firmware handler does not implement any handshake
+	 * but the driver should spin for a hundred or so microseconds
+	 * to ensure the SMI has triggered.
+	 *
+	 * Finally, the handler will return -ENOSYS if
+	 * GSMI_CMD_HANDSHAKE_TYPE is unimplemented, which implies
+	 * HANDSHAKE_NONE.
+	 */
+	spin_lock_irqsave(&gsmi_dev.lock, flags);
+	gsmi_dev.handshake_type = GSMI_HANDSHAKE_SPIN;
+	gsmi_dev.handshake_type =
+	    gsmi_exec(GSMI_CALLBACK, GSMI_CMD_HANDSHAKE_TYPE);
+	if (gsmi_dev.handshake_type == -ENOSYS)
+		gsmi_dev.handshake_type = GSMI_HANDSHAKE_NONE;
+	spin_unlock_irqrestore(&gsmi_dev.lock, flags);
+
+	/* Remove and clean up gsmi if the handshake could not complete. */
+	if (gsmi_dev.handshake_type == -ENXIO) {
+		printk(KERN_INFO "gsmi version " DRIVER_VERSION
+		       " failed to load\n");
+		ret = -ENODEV;
+		goto out_err;
+	}
+
+	printk(KERN_INFO "gsmi version " DRIVER_VERSION " loaded\n");
+
+	/* Register in the firmware directory */
+	ret = -ENOMEM;
+	gsmi_kobj = kobject_create_and_add("gsmi", firmware_kobj);
+	if (!gsmi_kobj) {
+		printk(KERN_INFO "gsmi: Failed to create firmware kobj\n");
+		goto out_err;
+	}
+
+	/* Setup eventlog access */
+	ret = sysfs_create_bin_file(gsmi_kobj, &eventlog_bin_attr);
+	if (ret) {
+		printk(KERN_INFO "gsmi: Failed to setup eventlog");
+		goto out_err;
+	}
+
+	/* Other attributes */
+	ret = sysfs_create_files(gsmi_kobj, gsmi_attrs);
+	if (ret) {
+		printk(KERN_INFO "gsmi: Failed to add attrs");
+		goto out_err;
+	}
+
+	if (register_efivars(&efivars, &efivar_ops, gsmi_kobj)) {
+		printk(KERN_INFO "gsmi: Failed to register efivars\n");
+		goto out_err;
+	}
+
+	register_reboot_notifier(&gsmi_reboot_notifier);
+	register_die_notifier(&gsmi_die_notifier);
+	atomic_notifier_chain_register(&panic_notifier_list,
+				       &gsmi_panic_notifier);
+
+	return 0;
+
+ out_err:
+	kobject_put(gsmi_kobj);
+	gsmi_buf_free(gsmi_dev.param_buf);
+	gsmi_buf_free(gsmi_dev.data_buf);
+	gsmi_buf_free(gsmi_dev.name_buf);
+	if (gsmi_dev.dma_pool)
+		dma_pool_destroy(gsmi_dev.dma_pool);
+	platform_device_unregister(gsmi_dev.pdev);
+	pr_info("gsmi: failed to load: %d\n", ret);
+	return ret;
+}
+
+static void __exit gsmi_exit(void)
+{
+	unregister_reboot_notifier(&gsmi_reboot_notifier);
+	unregister_die_notifier(&gsmi_die_notifier);
+	atomic_notifier_chain_unregister(&panic_notifier_list,
+					 &gsmi_panic_notifier);
+	unregister_efivars(&efivars);
+
+	kobject_put(gsmi_kobj);
+	gsmi_buf_free(gsmi_dev.param_buf);
+	gsmi_buf_free(gsmi_dev.data_buf);
+	gsmi_buf_free(gsmi_dev.name_buf);
+	dma_pool_destroy(gsmi_dev.dma_pool);
+	platform_device_unregister(gsmi_dev.pdev);
+}
+
+module_init(gsmi_init);
+module_exit(gsmi_exit);
+
+MODULE_AUTHOR("Google, Inc.");
+MODULE_LICENSE("GPL");
diff -druN linux-2.6.39-libre/drivers/firmware/google/Kconfig linux-3.0-rc7-libre/drivers/firmware/google/Kconfig
--- linux-2.6.39-libre/drivers/firmware/google/Kconfig	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/firmware/google/Kconfig	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,32 @@
+config GOOGLE_FIRMWARE
+	bool "Google Firmware Drivers"
+	depends on X86
+	default n
+	help
+	  These firmware drivers are used by Google's servers.  They are
+	  only useful if you are working directly on one of their
+	  proprietary servers.  If in doubt, say "N".
+
+menu "Google Firmware Drivers"
+	depends on GOOGLE_FIRMWARE
+
+config GOOGLE_SMI
+	tristate "SMI interface for Google platforms"
+	depends on ACPI && DMI
+	select EFI
+	select EFI_VARS
+	help
+	  Say Y here if you want to enable SMI callbacks for Google
+	  platforms.  This provides an interface for writing to and
+	  clearing the EFI event log and reading and writing NVRAM
+	  variables.
+
+config GOOGLE_MEMCONSOLE
+	tristate "Firmware Memory Console"
+	depends on DMI
+	help
+	  This option enables the kernel to search for a firmware log in
+	  the EBDA on Google servers.  If found, this log is exported to
+	  userland in the file /sys/firmware/log.
+
+endmenu
diff -druN linux-2.6.39-libre/drivers/firmware/google/Makefile linux-3.0-rc7-libre/drivers/firmware/google/Makefile
--- linux-2.6.39-libre/drivers/firmware/google/Makefile	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/firmware/google/Makefile	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,3 @@
+
+obj-$(CONFIG_GOOGLE_SMI)		+= gsmi.o
+obj-$(CONFIG_GOOGLE_MEMCONSOLE)		+= memconsole.o
diff -druN linux-2.6.39-libre/drivers/firmware/google/memconsole.c linux-3.0-rc7-libre/drivers/firmware/google/memconsole.c
--- linux-2.6.39-libre/drivers/firmware/google/memconsole.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/firmware/google/memconsole.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,166 @@
+/*
+ * memconsole.c
+ *
+ * Infrastructure for importing the BIOS memory based console
+ * into the kernel log ringbuffer.
+ *
+ * Copyright 2010 Google Inc. All rights reserved.
+ */
+
+#include <linux/ctype.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/sysfs.h>
+#include <linux/kobject.h>
+#include <linux/module.h>
+#include <linux/dmi.h>
+#include <asm/bios_ebda.h>
+
+#define BIOS_MEMCONSOLE_V1_MAGIC	0xDEADBABE
+#define BIOS_MEMCONSOLE_V2_MAGIC	(('M')|('C'<<8)|('O'<<16)|('N'<<24))
+
+struct biosmemcon_ebda {
+	u32 signature;
+	union {
+		struct {
+			u8  enabled;
+			u32 buffer_addr;
+			u16 start;
+			u16 end;
+			u16 num_chars;
+			u8  wrapped;
+		} __packed v1;
+		struct {
+			u32 buffer_addr;
+			/* Misdocumented as number of pages! */
+			u16 num_bytes;
+			u16 start;
+			u16 end;
+		} __packed v2;
+	};
+} __packed;
+
+static char *memconsole_baseaddr;
+static size_t memconsole_length;
+
+static ssize_t memconsole_read(struct file *filp, struct kobject *kobp,
+			       struct bin_attribute *bin_attr, char *buf,
+			       loff_t pos, size_t count)
+{
+	return memory_read_from_buffer(buf, count, &pos, memconsole_baseaddr,
+				       memconsole_length);
+}
+
+static struct bin_attribute memconsole_bin_attr = {
+	.attr = {.name = "log", .mode = 0444},
+	.read = memconsole_read,
+};
+
+
+static void found_v1_header(struct biosmemcon_ebda *hdr)
+{
+	printk(KERN_INFO "BIOS console v1 EBDA structure found at %p\n", hdr);
+	printk(KERN_INFO "BIOS console buffer at 0x%.8x, "
+	       "start = %d, end = %d, num = %d\n",
+	       hdr->v1.buffer_addr, hdr->v1.start,
+	       hdr->v1.end, hdr->v1.num_chars);
+
+	memconsole_length = hdr->v1.num_chars;
+	memconsole_baseaddr = phys_to_virt(hdr->v1.buffer_addr);
+}
+
+static void found_v2_header(struct biosmemcon_ebda *hdr)
+{
+	printk(KERN_INFO "BIOS console v2 EBDA structure found at %p\n", hdr);
+	printk(KERN_INFO "BIOS console buffer at 0x%.8x, "
+	       "start = %d, end = %d, num_bytes = %d\n",
+	       hdr->v2.buffer_addr, hdr->v2.start,
+	       hdr->v2.end, hdr->v2.num_bytes);
+
+	memconsole_length = hdr->v2.end - hdr->v2.start;
+	memconsole_baseaddr = phys_to_virt(hdr->v2.buffer_addr
+					   + hdr->v2.start);
+}
+
+/*
+ * Search through the EBDA for the BIOS Memory Console, and
+ * set the global variables to point to it.  Return true if found.
+ */
+static bool found_memconsole(void)
+{
+	unsigned int address;
+	size_t length, cur;
+
+	address = get_bios_ebda();
+	if (!address) {
+		printk(KERN_INFO "BIOS EBDA non-existent.\n");
+		return false;
+	}
+
+	/* EBDA length is byte 0 of EBDA (in KB) */
+	length = *(u8 *)phys_to_virt(address);
+	length <<= 10; /* convert to bytes */
+
+	/*
+	 * Search through EBDA for BIOS memory console structure
+	 * note: signature is not necessarily dword-aligned
+	 */
+	for (cur = 0; cur < length; cur++) {
+		struct biosmemcon_ebda *hdr = phys_to_virt(address + cur);
+
+		/* memconsole v1 */
+		if (hdr->signature == BIOS_MEMCONSOLE_V1_MAGIC) {
+			found_v1_header(hdr);
+			return true;
+		}
+
+		/* memconsole v2 */
+		if (hdr->signature == BIOS_MEMCONSOLE_V2_MAGIC) {
+			found_v2_header(hdr);
+			return true;
+		}
+	}
+
+	printk(KERN_INFO "BIOS console EBDA structure not found!\n");
+	return false;
+}
+
+static struct dmi_system_id memconsole_dmi_table[] __initdata = {
+	{
+		.ident = "Google Board",
+		.matches = {
+			DMI_MATCH(DMI_BOARD_VENDOR, "Google, Inc."),
+		},
+	},
+	{}
+};
+MODULE_DEVICE_TABLE(dmi, memconsole_dmi_table);
+
+static int __init memconsole_init(void)
+{
+	int ret;
+
+	if (!dmi_check_system(memconsole_dmi_table))
+		return -ENODEV;
+
+	if (!found_memconsole())
+		return -ENODEV;
+
+	memconsole_bin_attr.size = memconsole_length;
+
+	ret = sysfs_create_bin_file(firmware_kobj, &memconsole_bin_attr);
+
+	return ret;
+}
+
+static void __exit memconsole_exit(void)
+{
+	sysfs_remove_bin_file(firmware_kobj, &memconsole_bin_attr);
+}
+
+module_init(memconsole_init);
+module_exit(memconsole_exit);
+
+MODULE_AUTHOR("Google, Inc.");
+MODULE_LICENSE("GPL");
diff -druN linux-2.6.39-libre/drivers/firmware/iscsi_ibft.c linux-3.0-rc7-libre/drivers/firmware/iscsi_ibft.c
--- linux-2.6.39-libre/drivers/firmware/iscsi_ibft.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/firmware/iscsi_ibft.c	2011-07-11 19:51:52.000000000 -0400
@@ -87,8 +87,8 @@
 #define IBFT_ISCSI_VERSION "0.5.0"
 #define IBFT_ISCSI_DATE "2010-Feb-25"
 
-MODULE_AUTHOR("Peter Jones <pjones@redhat.com> and \
-Konrad Rzeszutek <ketuzsezr@darnok.org>");
+MODULE_AUTHOR("Peter Jones <pjones@redhat.com> and "
+	      "Konrad Rzeszutek <ketuzsezr@darnok.org>");
 MODULE_DESCRIPTION("sysfs interface to BIOS iBFT information");
 MODULE_LICENSE("GPL");
 MODULE_VERSION(IBFT_ISCSI_VERSION);
diff -druN linux-2.6.39-libre/drivers/firmware/iscsi_ibft_find.c linux-3.0-rc7-libre/drivers/firmware/iscsi_ibft_find.c
--- linux-2.6.39-libre/drivers/firmware/iscsi_ibft_find.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/firmware/iscsi_ibft_find.c	2011-07-11 19:51:52.000000000 -0400
@@ -42,7 +42,20 @@
 struct acpi_table_ibft *ibft_addr;
 EXPORT_SYMBOL_GPL(ibft_addr);
 
-#define IBFT_SIGN "iBFT"
+static const struct {
+	char *sign;
+} ibft_signs[] = {
+#ifdef CONFIG_ACPI
+	/*
+	 * One spec says "IBFT", the other says "iBFT". We have to check
+	 * for both.
+	 */
+	{ ACPI_SIG_IBFT },
+#endif
+	{ "iBFT" },
+	{ "BIFT" },	/* Broadcom iSCSI Offload */
+};
+
 #define IBFT_SIGN_LEN 4
 #define IBFT_START 0x80000 /* 512kB */
 #define IBFT_END 0x100000 /* 1MB */
@@ -62,6 +75,7 @@
 	unsigned long pos;
 	unsigned int len = 0;
 	void *virt;
+	int i;
 
 	for (pos = IBFT_START; pos < IBFT_END; pos += 16) {
 		/* The table can't be inside the VGA BIOS reserved space,
@@ -69,18 +83,23 @@
 		if (pos == VGA_MEM)
 			pos += VGA_SIZE;
 		virt = isa_bus_to_virt(pos);
-		if (memcmp(virt, IBFT_SIGN, IBFT_SIGN_LEN) == 0) {
-			unsigned long *addr =
-			    (unsigned long *)isa_bus_to_virt(pos + 4);
-			len = *addr;
-			/* if the length of the table extends past 1M,
-			 * the table cannot be valid. */
-			if (pos + len <= (IBFT_END-1)) {
-				ibft_addr = (struct acpi_table_ibft *)virt;
-				break;
+
+		for (i = 0; i < ARRAY_SIZE(ibft_signs); i++) {
+			if (memcmp(virt, ibft_signs[i].sign, IBFT_SIGN_LEN) ==
+			    0) {
+				unsigned long *addr =
+				    (unsigned long *)isa_bus_to_virt(pos + 4);
+				len = *addr;
+				/* if the length of the table extends past 1M,
+				 * the table cannot be valid. */
+				if (pos + len <= (IBFT_END-1)) {
+					ibft_addr = (struct acpi_table_ibft *)virt;
+					goto done;
+				}
 			}
 		}
 	}
+done:
 	return len;
 }
 /*
@@ -89,18 +108,14 @@
  */
 unsigned long __init find_ibft_region(unsigned long *sizep)
 {
-
+#ifdef CONFIG_ACPI
+	int i;
+#endif
 	ibft_addr = NULL;
 
 #ifdef CONFIG_ACPI
-	/*
-	 * One spec says "IBFT", the other says "iBFT". We have to check
-	 * for both.
-	 */
-	if (!ibft_addr)
-		acpi_table_parse(ACPI_SIG_IBFT, acpi_find_ibft);
-	if (!ibft_addr)
-		acpi_table_parse(IBFT_SIGN, acpi_find_ibft);
+	for (i = 0; i < ARRAY_SIZE(ibft_signs) && !ibft_addr; i++)
+		acpi_table_parse(ibft_signs[i].sign, acpi_find_ibft);
 #endif /* CONFIG_ACPI */
 
 	/* iBFT 1.03 section 1.4.3.1 mandates that UEFI machines will
diff -druN linux-2.6.39-libre/drivers/firmware/Kconfig linux-3.0-rc7-libre/drivers/firmware/Kconfig
--- linux-2.6.39-libre/drivers/firmware/Kconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/firmware/Kconfig	2011-07-11 19:51:52.000000000 -0400
@@ -157,4 +157,6 @@
 	  If unsure, say N here.  Drivers that need these helpers will select
 	  this option automatically.
 
+source "drivers/firmware/google/Kconfig"
+
 endmenu
diff -druN linux-2.6.39-libre/drivers/firmware/Makefile linux-3.0-rc7-libre/drivers/firmware/Makefile
--- linux-2.6.39-libre/drivers/firmware/Makefile	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/firmware/Makefile	2011-07-11 19:51:52.000000000 -0400
@@ -13,3 +13,5 @@
 obj-$(CONFIG_ISCSI_IBFT)	+= iscsi_ibft.o
 obj-$(CONFIG_FIRMWARE_MEMMAP)	+= memmap.o
 obj-$(CONFIG_SIGMA)		+= sigma.o
+
+obj-$(CONFIG_GOOGLE_FIRMWARE)	+= google/
diff -druN linux-2.6.39-libre/drivers/gpio/ab8500-gpio.c linux-3.0-rc7-libre/drivers/gpio/ab8500-gpio.c
--- linux-2.6.39-libre/drivers/gpio/ab8500-gpio.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/gpio/ab8500-gpio.c	2011-07-11 19:51:52.000000000 -0400
@@ -482,8 +482,8 @@
 
 	ret = gpiochip_remove(&ab8500_gpio->chip);
 	if (ret < 0) {
-		dev_err(ab8500_gpio->dev, "unable to remove gpiochip:\
-				%d\n", ret);
+		dev_err(ab8500_gpio->dev, "unable to remove gpiochip: %d\n",
+			ret);
 		return ret;
 	}
 
@@ -516,7 +516,6 @@
 module_exit(ab8500_gpio_exit);
 
 MODULE_AUTHOR("BIBEK BASU <bibek.basu@stericsson.com>");
-MODULE_DESCRIPTION("Driver allows to use AB8500 unused pins\
-			to be used as GPIO");
+MODULE_DESCRIPTION("Driver allows to use AB8500 unused pins to be used as GPIO");
 MODULE_ALIAS("AB8500 GPIO driver");
 MODULE_LICENSE("GPL v2");
diff -druN linux-2.6.39-libre/drivers/gpio/basic_mmio_gpio.c linux-3.0-rc7-libre/drivers/gpio/basic_mmio_gpio.c
--- linux-2.6.39-libre/drivers/gpio/basic_mmio_gpio.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/gpio/basic_mmio_gpio.c	2011-07-11 19:51:52.000000000 -0400
@@ -45,6 +45,7 @@
  */
 
 #include <linux/init.h>
+#include <linux/err.h>
 #include <linux/bug.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
@@ -61,102 +62,101 @@
 #include <linux/mod_devicetable.h>
 #include <linux/basic_mmio_gpio.h>
 
-struct bgpio_chip {
-	struct gpio_chip gc;
-	void __iomem *reg_dat;
-	void __iomem *reg_set;
-	void __iomem *reg_clr;
-
-	/* Number of bits (GPIOs): <register width> * 8. */
-	int bits;
+static void bgpio_write8(void __iomem *reg, unsigned long data)
+{
+	writeb(data, reg);
+}
 
-	/*
-	 * Some GPIO controllers work with the big-endian bits notation,
-	 * e.g. in a 8-bits register, GPIO7 is the least significant bit.
-	 */
-	int big_endian_bits;
+static unsigned long bgpio_read8(void __iomem *reg)
+{
+	return readb(reg);
+}
 
-	/*
-	 * Used to lock bgpio_chip->data. Also, this is needed to keep
-	 * shadowed and real data registers writes together.
-	 */
-	spinlock_t lock;
+static void bgpio_write16(void __iomem *reg, unsigned long data)
+{
+	writew(data, reg);
+}
 
-	/* Shadowed data register to clear/set bits safely. */
-	unsigned long data;
-};
+static unsigned long bgpio_read16(void __iomem *reg)
+{
+	return readw(reg);
+}
 
-static struct bgpio_chip *to_bgpio_chip(struct gpio_chip *gc)
+static void bgpio_write32(void __iomem *reg, unsigned long data)
 {
-	return container_of(gc, struct bgpio_chip, gc);
+	writel(data, reg);
 }
 
-static unsigned long bgpio_in(struct bgpio_chip *bgc)
+static unsigned long bgpio_read32(void __iomem *reg)
 {
-	switch (bgc->bits) {
-	case 8:
-		return __raw_readb(bgc->reg_dat);
-	case 16:
-		return __raw_readw(bgc->reg_dat);
-	case 32:
-		return __raw_readl(bgc->reg_dat);
+	return readl(reg);
+}
+
 #if BITS_PER_LONG >= 64
-	case 64:
-		return __raw_readq(bgc->reg_dat);
-#endif
-	}
-	return -EINVAL;
+static void bgpio_write64(void __iomem *reg, unsigned long data)
+{
+	writeq(data, reg);
 }
 
-static void bgpio_out(struct bgpio_chip *bgc, void __iomem *reg,
-		      unsigned long data)
+static unsigned long bgpio_read64(void __iomem *reg)
 {
-	switch (bgc->bits) {
-	case 8:
-		__raw_writeb(data, reg);
-		return;
-	case 16:
-		__raw_writew(data, reg);
-		return;
-	case 32:
-		__raw_writel(data, reg);
-		return;
-#if BITS_PER_LONG >= 64
-	case 64:
-		__raw_writeq(data, reg);
-		return;
-#endif
-	}
+	return readq(reg);
 }
+#endif /* BITS_PER_LONG >= 64 */
 
 static unsigned long bgpio_pin2mask(struct bgpio_chip *bgc, unsigned int pin)
 {
-	if (bgc->big_endian_bits)
-		return 1 << (bgc->bits - 1 - pin);
-	else
-		return 1 << pin;
+	return 1 << pin;
+}
+
+static unsigned long bgpio_pin2mask_be(struct bgpio_chip *bgc,
+				       unsigned int pin)
+{
+	return 1 << (bgc->bits - 1 - pin);
 }
 
 static int bgpio_get(struct gpio_chip *gc, unsigned int gpio)
 {
 	struct bgpio_chip *bgc = to_bgpio_chip(gc);
 
-	return bgpio_in(bgc) & bgpio_pin2mask(bgc, gpio);
+	return bgc->read_reg(bgc->reg_dat) & bgc->pin2mask(bgc, gpio);
 }
 
 static void bgpio_set(struct gpio_chip *gc, unsigned int gpio, int val)
 {
 	struct bgpio_chip *bgc = to_bgpio_chip(gc);
-	unsigned long mask = bgpio_pin2mask(bgc, gpio);
+	unsigned long mask = bgc->pin2mask(bgc, gpio);
 	unsigned long flags;
 
-	if (bgc->reg_set) {
-		if (val)
-			bgpio_out(bgc, bgc->reg_set, mask);
-		else
-			bgpio_out(bgc, bgc->reg_clr, mask);
-		return;
-	}
+	spin_lock_irqsave(&bgc->lock, flags);
+
+	if (val)
+		bgc->data |= mask;
+	else
+		bgc->data &= ~mask;
+
+	bgc->write_reg(bgc->reg_dat, bgc->data);
+
+	spin_unlock_irqrestore(&bgc->lock, flags);
+}
+
+static void bgpio_set_with_clear(struct gpio_chip *gc, unsigned int gpio,
+				 int val)
+{
+	struct bgpio_chip *bgc = to_bgpio_chip(gc);
+	unsigned long mask = bgc->pin2mask(bgc, gpio);
+
+	if (val)
+		bgc->write_reg(bgc->reg_set, mask);
+	else
+		bgc->write_reg(bgc->reg_clr, mask);
+}
+
+static void bgpio_set_set(struct gpio_chip *gc, unsigned int gpio, int val)
+{
+	struct bgpio_chip *bgc = to_bgpio_chip(gc);
+	unsigned long mask = bgc->pin2mask(bgc, gpio);
+	unsigned long flags;
 
 	spin_lock_irqsave(&bgc->lock, flags);
 
@@ -165,103 +165,352 @@
 	else
 		bgc->data &= ~mask;
 
-	bgpio_out(bgc, bgc->reg_dat, bgc->data);
+	bgc->write_reg(bgc->reg_set, bgc->data);
 
 	spin_unlock_irqrestore(&bgc->lock, flags);
 }
 
+static int bgpio_simple_dir_in(struct gpio_chip *gc, unsigned int gpio)
+{
+	return 0;
+}
+
+static int bgpio_simple_dir_out(struct gpio_chip *gc, unsigned int gpio,
+				int val)
+{
+	gc->set(gc, gpio, val);
+
+	return 0;
+}
+
 static int bgpio_dir_in(struct gpio_chip *gc, unsigned int gpio)
 {
+	struct bgpio_chip *bgc = to_bgpio_chip(gc);
+	unsigned long flags;
+
+	spin_lock_irqsave(&bgc->lock, flags);
+
+	bgc->dir &= ~bgc->pin2mask(bgc, gpio);
+	bgc->write_reg(bgc->reg_dir, bgc->dir);
+
+	spin_unlock_irqrestore(&bgc->lock, flags);
+
 	return 0;
 }
 
 static int bgpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int val)
 {
-	bgpio_set(gc, gpio, val);
+	struct bgpio_chip *bgc = to_bgpio_chip(gc);
+	unsigned long flags;
+
+	gc->set(gc, gpio, val);
+
+	spin_lock_irqsave(&bgc->lock, flags);
+
+	bgc->dir |= bgc->pin2mask(bgc, gpio);
+	bgc->write_reg(bgc->reg_dir, bgc->dir);
+
+	spin_unlock_irqrestore(&bgc->lock, flags);
+
 	return 0;
 }
 
-static int __devinit bgpio_probe(struct platform_device *pdev)
+static int bgpio_dir_in_inv(struct gpio_chip *gc, unsigned int gpio)
 {
-	const struct platform_device_id *platid = platform_get_device_id(pdev);
-	struct device *dev = &pdev->dev;
-	struct bgpio_pdata *pdata = dev_get_platdata(dev);
-	struct bgpio_chip *bgc;
-	struct resource *res_dat;
-	struct resource *res_set;
-	struct resource *res_clr;
-	resource_size_t dat_sz;
-	int bits;
-	int ret;
+	struct bgpio_chip *bgc = to_bgpio_chip(gc);
+	unsigned long flags;
 
-	res_dat = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dat");
-	if (!res_dat)
-		return -EINVAL;
+	spin_lock_irqsave(&bgc->lock, flags);
 
-	dat_sz = resource_size(res_dat);
-	if (!is_power_of_2(dat_sz))
-		return -EINVAL;
+	bgc->dir |= bgc->pin2mask(bgc, gpio);
+	bgc->write_reg(bgc->reg_dir, bgc->dir);
 
-	bits = dat_sz * 8;
-	if (bits > BITS_PER_LONG)
+	spin_unlock_irqrestore(&bgc->lock, flags);
+
+	return 0;
+}
+
+static int bgpio_dir_out_inv(struct gpio_chip *gc, unsigned int gpio, int val)
+{
+	struct bgpio_chip *bgc = to_bgpio_chip(gc);
+	unsigned long flags;
+
+	gc->set(gc, gpio, val);
+
+	spin_lock_irqsave(&bgc->lock, flags);
+
+	bgc->dir &= ~bgc->pin2mask(bgc, gpio);
+	bgc->write_reg(bgc->reg_dir, bgc->dir);
+
+	spin_unlock_irqrestore(&bgc->lock, flags);
+
+	return 0;
+}
+
+static int bgpio_setup_accessors(struct device *dev,
+				 struct bgpio_chip *bgc,
+				 bool be)
+{
+
+	switch (bgc->bits) {
+	case 8:
+		bgc->read_reg	= bgpio_read8;
+		bgc->write_reg	= bgpio_write8;
+		break;
+	case 16:
+		bgc->read_reg	= bgpio_read16;
+		bgc->write_reg	= bgpio_write16;
+		break;
+	case 32:
+		bgc->read_reg	= bgpio_read32;
+		bgc->write_reg	= bgpio_write32;
+		break;
+#if BITS_PER_LONG >= 64
+	case 64:
+		bgc->read_reg	= bgpio_read64;
+		bgc->write_reg	= bgpio_write64;
+		break;
+#endif /* BITS_PER_LONG >= 64 */
+	default:
+		dev_err(dev, "unsupported data width %u bits\n", bgc->bits);
 		return -EINVAL;
+	}
 
-	bgc = devm_kzalloc(dev, sizeof(*bgc), GFP_KERNEL);
-	if (!bgc)
-		return -ENOMEM;
+	bgc->pin2mask = be ? bgpio_pin2mask_be : bgpio_pin2mask;
 
-	bgc->reg_dat = devm_ioremap(dev, res_dat->start, dat_sz);
+	return 0;
+}
+
+/*
+ * Create the device and allocate the resources.  For setting GPIO's there are
+ * three supported configurations:
+ *
+ *	- single input/output register resource (named "dat").
+ *	- set/clear pair (named "set" and "clr").
+ *	- single output register resource and single input resource ("set" and
+ *	dat").
+ *
+ * For the single output register, this drives a 1 by setting a bit and a zero
+ * by clearing a bit.  For the set clr pair, this drives a 1 by setting a bit
+ * in the set register and clears it by setting a bit in the clear register.
+ * The configuration is detected by which resources are present.
+ *
+ * For setting the GPIO direction, there are three supported configurations:
+ *
+ *	- simple bidirection GPIO that requires no configuration.
+ *	- an output direction register (named "dirout") where a 1 bit
+ *	indicates the GPIO is an output.
+ *	- an input direction register (named "dirin") where a 1 bit indicates
+ *	the GPIO is an input.
+ */
+static int bgpio_setup_io(struct bgpio_chip *bgc,
+			  void __iomem *dat,
+			  void __iomem *set,
+			  void __iomem *clr)
+{
+
+	bgc->reg_dat = dat;
 	if (!bgc->reg_dat)
-		return -ENOMEM;
+		return -EINVAL;
 
-	res_set = platform_get_resource_byname(pdev, IORESOURCE_MEM, "set");
-	res_clr = platform_get_resource_byname(pdev, IORESOURCE_MEM, "clr");
-	if (res_set && res_clr) {
-		if (resource_size(res_set) != resource_size(res_clr) ||
-				resource_size(res_set) != dat_sz)
-			return -EINVAL;
+	if (set && clr) {
+		bgc->reg_set = set;
+		bgc->reg_clr = clr;
+		bgc->gc.set = bgpio_set_with_clear;
+	} else if (set && !clr) {
+		bgc->reg_set = set;
+		bgc->gc.set = bgpio_set_set;
+	} else {
+		bgc->gc.set = bgpio_set;
+	}
 
-		bgc->reg_set = devm_ioremap(dev, res_set->start, dat_sz);
-		bgc->reg_clr = devm_ioremap(dev, res_clr->start, dat_sz);
-		if (!bgc->reg_set || !bgc->reg_clr)
-			return -ENOMEM;
-	} else if (res_set || res_clr) {
+	bgc->gc.get = bgpio_get;
+
+	return 0;
+}
+
+static int bgpio_setup_direction(struct bgpio_chip *bgc,
+				 void __iomem *dirout,
+				 void __iomem *dirin)
+{
+	if (dirout && dirin) {
 		return -EINVAL;
+	} else if (dirout) {
+		bgc->reg_dir = dirout;
+		bgc->gc.direction_output = bgpio_dir_out;
+		bgc->gc.direction_input = bgpio_dir_in;
+	} else if (dirin) {
+		bgc->reg_dir = dirin;
+		bgc->gc.direction_output = bgpio_dir_out_inv;
+		bgc->gc.direction_input = bgpio_dir_in_inv;
+	} else {
+		bgc->gc.direction_output = bgpio_simple_dir_out;
+		bgc->gc.direction_input = bgpio_simple_dir_in;
 	}
 
-	spin_lock_init(&bgc->lock);
+	return 0;
+}
 
-	bgc->bits = bits;
-	bgc->big_endian_bits = !strcmp(platid->name, "basic-mmio-gpio-be");
-	bgc->data = bgpio_in(bgc);
+int __devexit bgpio_remove(struct bgpio_chip *bgc)
+{
+	int err = gpiochip_remove(&bgc->gc);
 
-	bgc->gc.ngpio = bits;
-	bgc->gc.direction_input = bgpio_dir_in;
-	bgc->gc.direction_output = bgpio_dir_out;
-	bgc->gc.get = bgpio_get;
-	bgc->gc.set = bgpio_set;
+	kfree(bgc);
+
+	return err;
+}
+EXPORT_SYMBOL_GPL(bgpio_remove);
+
+int __devinit bgpio_init(struct bgpio_chip *bgc,
+			 struct device *dev,
+			 unsigned long sz,
+			 void __iomem *dat,
+			 void __iomem *set,
+			 void __iomem *clr,
+			 void __iomem *dirout,
+			 void __iomem *dirin,
+			 bool big_endian)
+{
+	int ret;
+
+	if (!is_power_of_2(sz))
+		return -EINVAL;
+
+	bgc->bits = sz * 8;
+	if (bgc->bits > BITS_PER_LONG)
+		return -EINVAL;
+
+	spin_lock_init(&bgc->lock);
 	bgc->gc.dev = dev;
 	bgc->gc.label = dev_name(dev);
+	bgc->gc.base = -1;
+	bgc->gc.ngpio = bgc->bits;
 
-	if (pdata)
-		bgc->gc.base = pdata->base;
-	else
-		bgc->gc.base = -1;
+	ret = bgpio_setup_io(bgc, dat, set, clr);
+	if (ret)
+		return ret;
 
-	dev_set_drvdata(dev, bgc);
+	ret = bgpio_setup_accessors(dev, bgc, big_endian);
+	if (ret)
+		return ret;
 
-	ret = gpiochip_add(&bgc->gc);
+	ret = bgpio_setup_direction(bgc, dirout, dirin);
 	if (ret)
-		dev_err(dev, "gpiochip_add() failed: %d\n", ret);
+		return ret;
+
+	bgc->data = bgc->read_reg(bgc->reg_dat);
 
 	return ret;
 }
+EXPORT_SYMBOL_GPL(bgpio_init);
 
-static int __devexit bgpio_remove(struct platform_device *pdev)
+#ifdef CONFIG_GPIO_BASIC_MMIO
+
+static void __iomem *bgpio_map(struct platform_device *pdev,
+			       const char *name,
+			       resource_size_t sane_sz,
+			       int *err)
 {
-	struct bgpio_chip *bgc = dev_get_drvdata(&pdev->dev);
+	struct device *dev = &pdev->dev;
+	struct resource *r;
+	resource_size_t start;
+	resource_size_t sz;
+	void __iomem *ret;
 
-	return gpiochip_remove(&bgc->gc);
+	*err = 0;
+
+	r = platform_get_resource_byname(pdev, IORESOURCE_MEM, name);
+	if (!r)
+		return NULL;
+
+	sz = resource_size(r);
+	if (sz != sane_sz) {
+		*err = -EINVAL;
+		return NULL;
+	}
+
+	start = r->start;
+	if (!devm_request_mem_region(dev, start, sz, r->name)) {
+		*err = -EBUSY;
+		return NULL;
+	}
+
+	ret = devm_ioremap(dev, start, sz);
+	if (!ret) {
+		*err = -ENOMEM;
+		return NULL;
+	}
+
+	return ret;
+}
+
+static int __devinit bgpio_pdev_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct resource *r;
+	void __iomem *dat;
+	void __iomem *set;
+	void __iomem *clr;
+	void __iomem *dirout;
+	void __iomem *dirin;
+	unsigned long sz;
+	bool be;
+	int err;
+	struct bgpio_chip *bgc;
+	struct bgpio_pdata *pdata = dev_get_platdata(dev);
+
+	r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dat");
+	if (!r)
+		return -EINVAL;
+
+	sz = resource_size(r);
+
+	dat = bgpio_map(pdev, "dat", sz, &err);
+	if (!dat)
+		return err ? err : -EINVAL;
+
+	set = bgpio_map(pdev, "set", sz, &err);
+	if (err)
+		return err;
+
+	clr = bgpio_map(pdev, "clr", sz, &err);
+	if (err)
+		return err;
+
+	dirout = bgpio_map(pdev, "dirout", sz, &err);
+	if (err)
+		return err;
+
+	dirin = bgpio_map(pdev, "dirin", sz, &err);
+	if (err)
+		return err;
+
+	be = !strcmp(platform_get_device_id(pdev)->name, "basic-mmio-gpio-be");
+
+	bgc = devm_kzalloc(&pdev->dev, sizeof(*bgc), GFP_KERNEL);
+	if (!bgc)
+		return -ENOMEM;
+
+	err = bgpio_init(bgc, dev, sz, dat, set, clr, dirout, dirin, be);
+	if (err)
+		return err;
+
+	if (pdata) {
+		bgc->gc.base = pdata->base;
+		if (pdata->ngpio > 0)
+			bgc->gc.ngpio = pdata->ngpio;
+	}
+
+	platform_set_drvdata(pdev, bgc);
+
+	return gpiochip_add(&bgc->gc);
+}
+
+static int __devexit bgpio_pdev_remove(struct platform_device *pdev)
+{
+	struct bgpio_chip *bgc = platform_get_drvdata(pdev);
+
+	return bgpio_remove(bgc);
 }
 
 static const struct platform_device_id bgpio_id_table[] = {
@@ -276,21 +525,23 @@
 		.name = "basic-mmio-gpio",
 	},
 	.id_table = bgpio_id_table,
-	.probe = bgpio_probe,
-	.remove = __devexit_p(bgpio_remove),
+	.probe = bgpio_pdev_probe,
+	.remove = __devexit_p(bgpio_pdev_remove),
 };
 
-static int __init bgpio_init(void)
+static int __init bgpio_platform_init(void)
 {
 	return platform_driver_register(&bgpio_driver);
 }
-module_init(bgpio_init);
+module_init(bgpio_platform_init);
 
-static void __exit bgpio_exit(void)
+static void __exit bgpio_platform_exit(void)
 {
 	platform_driver_unregister(&bgpio_driver);
 }
-module_exit(bgpio_exit);
+module_exit(bgpio_platform_exit);
+
+#endif /* CONFIG_GPIO_BASIC_MMIO */
 
 MODULE_DESCRIPTION("Driver for basic memory-mapped GPIO controllers");
 MODULE_AUTHOR("Anton Vorontsov <cbouatmailru@gmail.com>");
diff -druN linux-2.6.39-libre/drivers/gpio/gpio-exynos4.c linux-3.0-rc7-libre/drivers/gpio/gpio-exynos4.c
--- linux-2.6.39-libre/drivers/gpio/gpio-exynos4.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/gpio/gpio-exynos4.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,386 @@
+/* linux/arch/arm/mach-exynos4/gpiolib.c
+ *
+ * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
+ *		http://www.samsung.com
+ *
+ * EXYNOS4 - GPIOlib support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+#include <linux/gpio.h>
+
+#include <mach/map.h>
+
+#include <plat/gpio-core.h>
+#include <plat/gpio-cfg.h>
+#include <plat/gpio-cfg-helpers.h>
+
+int s3c_gpio_setpull_exynos4(struct s3c_gpio_chip *chip,
+				unsigned int off, s3c_gpio_pull_t pull)
+{
+	if (pull == S3C_GPIO_PULL_UP)
+		pull = 3;
+
+	return s3c_gpio_setpull_updown(chip, off, pull);
+}
+
+s3c_gpio_pull_t s3c_gpio_getpull_exynos4(struct s3c_gpio_chip *chip,
+						unsigned int off)
+{
+	s3c_gpio_pull_t pull;
+
+	pull = s3c_gpio_getpull_updown(chip, off);
+	if (pull == 3)
+		pull = S3C_GPIO_PULL_UP;
+
+	return pull;
+}
+
+static struct s3c_gpio_cfg gpio_cfg = {
+	.set_config	= s3c_gpio_setcfg_s3c64xx_4bit,
+	.set_pull	= s3c_gpio_setpull_exynos4,
+	.get_pull	= s3c_gpio_getpull_exynos4,
+};
+
+static struct s3c_gpio_cfg gpio_cfg_noint = {
+	.set_config	= s3c_gpio_setcfg_s3c64xx_4bit,
+	.set_pull	= s3c_gpio_setpull_exynos4,
+	.get_pull	= s3c_gpio_getpull_exynos4,
+};
+
+/*
+ * Following are the gpio banks in v310.
+ *
+ * The 'config' member when left to NULL, is initialized to the default
+ * structure gpio_cfg in the init function below.
+ *
+ * The 'base' member is also initialized in the init function below.
+ * Note: The initialization of 'base' member of s3c_gpio_chip structure
+ * uses the above macro and depends on the banks being listed in order here.
+ */
+static struct s3c_gpio_chip exynos4_gpio_part1_4bit[] = {
+	{
+		.chip	= {
+			.base	= EXYNOS4_GPA0(0),
+			.ngpio	= EXYNOS4_GPIO_A0_NR,
+			.label	= "GPA0",
+		},
+	}, {
+		.chip	= {
+			.base	= EXYNOS4_GPA1(0),
+			.ngpio	= EXYNOS4_GPIO_A1_NR,
+			.label	= "GPA1",
+		},
+	}, {
+		.chip	= {
+			.base	= EXYNOS4_GPB(0),
+			.ngpio	= EXYNOS4_GPIO_B_NR,
+			.label	= "GPB",
+		},
+	}, {
+		.chip	= {
+			.base	= EXYNOS4_GPC0(0),
+			.ngpio	= EXYNOS4_GPIO_C0_NR,
+			.label	= "GPC0",
+		},
+	}, {
+		.chip	= {
+			.base	= EXYNOS4_GPC1(0),
+			.ngpio	= EXYNOS4_GPIO_C1_NR,
+			.label	= "GPC1",
+		},
+	}, {
+		.chip	= {
+			.base	= EXYNOS4_GPD0(0),
+			.ngpio	= EXYNOS4_GPIO_D0_NR,
+			.label	= "GPD0",
+		},
+	}, {
+		.chip	= {
+			.base	= EXYNOS4_GPD1(0),
+			.ngpio	= EXYNOS4_GPIO_D1_NR,
+			.label	= "GPD1",
+		},
+	}, {
+		.chip	= {
+			.base	= EXYNOS4_GPE0(0),
+			.ngpio	= EXYNOS4_GPIO_E0_NR,
+			.label	= "GPE0",
+		},
+	}, {
+		.chip	= {
+			.base	= EXYNOS4_GPE1(0),
+			.ngpio	= EXYNOS4_GPIO_E1_NR,
+			.label	= "GPE1",
+		},
+	}, {
+		.chip	= {
+			.base	= EXYNOS4_GPE2(0),
+			.ngpio	= EXYNOS4_GPIO_E2_NR,
+			.label	= "GPE2",
+		},
+	}, {
+		.chip	= {
+			.base	= EXYNOS4_GPE3(0),
+			.ngpio	= EXYNOS4_GPIO_E3_NR,
+			.label	= "GPE3",
+		},
+	}, {
+		.chip	= {
+			.base	= EXYNOS4_GPE4(0),
+			.ngpio	= EXYNOS4_GPIO_E4_NR,
+			.label	= "GPE4",
+		},
+	}, {
+		.chip	= {
+			.base	= EXYNOS4_GPF0(0),
+			.ngpio	= EXYNOS4_GPIO_F0_NR,
+			.label	= "GPF0",
+		},
+	}, {
+		.chip	= {
+			.base	= EXYNOS4_GPF1(0),
+			.ngpio	= EXYNOS4_GPIO_F1_NR,
+			.label	= "GPF1",
+		},
+	}, {
+		.chip	= {
+			.base	= EXYNOS4_GPF2(0),
+			.ngpio	= EXYNOS4_GPIO_F2_NR,
+			.label	= "GPF2",
+		},
+	}, {
+		.chip	= {
+			.base	= EXYNOS4_GPF3(0),
+			.ngpio	= EXYNOS4_GPIO_F3_NR,
+			.label	= "GPF3",
+		},
+	},
+};
+
+static struct s3c_gpio_chip exynos4_gpio_part2_4bit[] = {
+	{
+		.chip	= {
+			.base	= EXYNOS4_GPJ0(0),
+			.ngpio	= EXYNOS4_GPIO_J0_NR,
+			.label	= "GPJ0",
+		},
+	}, {
+		.chip	= {
+			.base	= EXYNOS4_GPJ1(0),
+			.ngpio	= EXYNOS4_GPIO_J1_NR,
+			.label	= "GPJ1",
+		},
+	}, {
+		.chip	= {
+			.base	= EXYNOS4_GPK0(0),
+			.ngpio	= EXYNOS4_GPIO_K0_NR,
+			.label	= "GPK0",
+		},
+	}, {
+		.chip	= {
+			.base	= EXYNOS4_GPK1(0),
+			.ngpio	= EXYNOS4_GPIO_K1_NR,
+			.label	= "GPK1",
+		},
+	}, {
+		.chip	= {
+			.base	= EXYNOS4_GPK2(0),
+			.ngpio	= EXYNOS4_GPIO_K2_NR,
+			.label	= "GPK2",
+		},
+	}, {
+		.chip	= {
+			.base	= EXYNOS4_GPK3(0),
+			.ngpio	= EXYNOS4_GPIO_K3_NR,
+			.label	= "GPK3",
+		},
+	}, {
+		.chip	= {
+			.base	= EXYNOS4_GPL0(0),
+			.ngpio	= EXYNOS4_GPIO_L0_NR,
+			.label	= "GPL0",
+		},
+	}, {
+		.chip	= {
+			.base	= EXYNOS4_GPL1(0),
+			.ngpio	= EXYNOS4_GPIO_L1_NR,
+			.label	= "GPL1",
+		},
+	}, {
+		.chip	= {
+			.base	= EXYNOS4_GPL2(0),
+			.ngpio	= EXYNOS4_GPIO_L2_NR,
+			.label	= "GPL2",
+		},
+	}, {
+		.config	= &gpio_cfg_noint,
+		.chip	= {
+			.base	= EXYNOS4_GPY0(0),
+			.ngpio	= EXYNOS4_GPIO_Y0_NR,
+			.label	= "GPY0",
+		},
+	}, {
+		.config	= &gpio_cfg_noint,
+		.chip	= {
+			.base	= EXYNOS4_GPY1(0),
+			.ngpio	= EXYNOS4_GPIO_Y1_NR,
+			.label	= "GPY1",
+		},
+	}, {
+		.config	= &gpio_cfg_noint,
+		.chip	= {
+			.base	= EXYNOS4_GPY2(0),
+			.ngpio	= EXYNOS4_GPIO_Y2_NR,
+			.label	= "GPY2",
+		},
+	}, {
+		.config	= &gpio_cfg_noint,
+		.chip	= {
+			.base	= EXYNOS4_GPY3(0),
+			.ngpio	= EXYNOS4_GPIO_Y3_NR,
+			.label	= "GPY3",
+		},
+	}, {
+		.config	= &gpio_cfg_noint,
+		.chip	= {
+			.base	= EXYNOS4_GPY4(0),
+			.ngpio	= EXYNOS4_GPIO_Y4_NR,
+			.label	= "GPY4",
+		},
+	}, {
+		.config	= &gpio_cfg_noint,
+		.chip	= {
+			.base	= EXYNOS4_GPY5(0),
+			.ngpio	= EXYNOS4_GPIO_Y5_NR,
+			.label	= "GPY5",
+		},
+	}, {
+		.config	= &gpio_cfg_noint,
+		.chip	= {
+			.base	= EXYNOS4_GPY6(0),
+			.ngpio	= EXYNOS4_GPIO_Y6_NR,
+			.label	= "GPY6",
+		},
+	}, {
+		.base	= (S5P_VA_GPIO2 + 0xC00),
+		.config	= &gpio_cfg_noint,
+		.irq_base = IRQ_EINT(0),
+		.chip	= {
+			.base	= EXYNOS4_GPX0(0),
+			.ngpio	= EXYNOS4_GPIO_X0_NR,
+			.label	= "GPX0",
+			.to_irq	= samsung_gpiolib_to_irq,
+		},
+	}, {
+		.base	= (S5P_VA_GPIO2 + 0xC20),
+		.config	= &gpio_cfg_noint,
+		.irq_base = IRQ_EINT(8),
+		.chip	= {
+			.base	= EXYNOS4_GPX1(0),
+			.ngpio	= EXYNOS4_GPIO_X1_NR,
+			.label	= "GPX1",
+			.to_irq	= samsung_gpiolib_to_irq,
+		},
+	}, {
+		.base	= (S5P_VA_GPIO2 + 0xC40),
+		.config	= &gpio_cfg_noint,
+		.irq_base = IRQ_EINT(16),
+		.chip	= {
+			.base	= EXYNOS4_GPX2(0),
+			.ngpio	= EXYNOS4_GPIO_X2_NR,
+			.label	= "GPX2",
+			.to_irq	= samsung_gpiolib_to_irq,
+		},
+	}, {
+		.base	= (S5P_VA_GPIO2 + 0xC60),
+		.config	= &gpio_cfg_noint,
+		.irq_base = IRQ_EINT(24),
+		.chip	= {
+			.base	= EXYNOS4_GPX3(0),
+			.ngpio	= EXYNOS4_GPIO_X3_NR,
+			.label	= "GPX3",
+			.to_irq	= samsung_gpiolib_to_irq,
+		},
+	},
+};
+
+static struct s3c_gpio_chip exynos4_gpio_part3_4bit[] = {
+	{
+		.chip	= {
+			.base	= EXYNOS4_GPZ(0),
+			.ngpio	= EXYNOS4_GPIO_Z_NR,
+			.label	= "GPZ",
+		},
+	},
+};
+
+static __init int exynos4_gpiolib_init(void)
+{
+	struct s3c_gpio_chip *chip;
+	int i;
+	int group = 0;
+	int nr_chips;
+
+	/* GPIO part 1 */
+
+	chip = exynos4_gpio_part1_4bit;
+	nr_chips = ARRAY_SIZE(exynos4_gpio_part1_4bit);
+
+	for (i = 0; i < nr_chips; i++, chip++) {
+		if (chip->config == NULL) {
+			chip->config = &gpio_cfg;
+			/* Assign the GPIO interrupt group */
+			chip->group = group++;
+		}
+		if (chip->base == NULL)
+			chip->base = S5P_VA_GPIO1 + (i) * 0x20;
+	}
+
+	samsung_gpiolib_add_4bit_chips(exynos4_gpio_part1_4bit, nr_chips);
+
+	/* GPIO part 2 */
+
+	chip = exynos4_gpio_part2_4bit;
+	nr_chips = ARRAY_SIZE(exynos4_gpio_part2_4bit);
+
+	for (i = 0; i < nr_chips; i++, chip++) {
+		if (chip->config == NULL) {
+			chip->config = &gpio_cfg;
+			/* Assign the GPIO interrupt group */
+			chip->group = group++;
+		}
+		if (chip->base == NULL)
+			chip->base = S5P_VA_GPIO2 + (i) * 0x20;
+	}
+
+	samsung_gpiolib_add_4bit_chips(exynos4_gpio_part2_4bit, nr_chips);
+
+	/* GPIO part 3 */
+
+	chip = exynos4_gpio_part3_4bit;
+	nr_chips = ARRAY_SIZE(exynos4_gpio_part3_4bit);
+
+	for (i = 0; i < nr_chips; i++, chip++) {
+		if (chip->config == NULL) {
+			chip->config = &gpio_cfg;
+			/* Assign the GPIO interrupt group */
+			chip->group = group++;
+		}
+		if (chip->base == NULL)
+			chip->base = S5P_VA_GPIO3 + (i) * 0x20;
+	}
+
+	samsung_gpiolib_add_4bit_chips(exynos4_gpio_part3_4bit, nr_chips);
+	s5p_register_gpioint_bank(IRQ_GPIO_XA, 0, IRQ_GPIO1_NR_GROUPS);
+	s5p_register_gpioint_bank(IRQ_GPIO_XB, IRQ_GPIO1_NR_GROUPS, IRQ_GPIO2_NR_GROUPS);
+
+	return 0;
+}
+core_initcall(exynos4_gpiolib_init);
diff -druN linux-2.6.39-libre/drivers/gpio/gpiolib.c linux-3.0-rc7-libre/drivers/gpio/gpiolib.c
--- linux-2.6.39-libre/drivers/gpio/gpiolib.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/gpio/gpiolib.c	2011-07-11 19:51:52.000000000 -0400
@@ -12,6 +12,8 @@
 #include <linux/idr.h>
 #include <linux/slab.h>
 
+#define CREATE_TRACE_POINTS
+#include <trace/events/gpio.h>
 
 /* Optional implementation infrastructure for GPIO interfaces.
  *
@@ -1165,6 +1167,7 @@
 
 	return chip;
 }
+EXPORT_SYMBOL_GPL(gpiochip_find);
 
 /* These "optional" allocation calls help prevent drivers from stomping
  * on each other, and help provide better diagnostics in debugfs.
@@ -1293,7 +1296,7 @@
  * @array:	array of the 'struct gpio'
  * @num:	how many GPIOs in the array
  */
-int gpio_request_array(struct gpio *array, size_t num)
+int gpio_request_array(const struct gpio *array, size_t num)
 {
 	int i, err;
 
@@ -1316,7 +1319,7 @@
  * @array:	array of the 'struct gpio'
  * @num:	how many GPIOs in the array
  */
-void gpio_free_array(struct gpio *array, size_t num)
+void gpio_free_array(const struct gpio *array, size_t num)
 {
 	while (num--)
 		gpio_free((array++)->gpio);
@@ -1404,6 +1407,8 @@
 	status = chip->direction_input(chip, gpio);
 	if (status == 0)
 		clear_bit(FLAG_IS_OUT, &desc->flags);
+
+	trace_gpio_direction(chip->base + gpio, 1, status);
 lose:
 	return status;
 fail:
@@ -1457,6 +1462,8 @@
 	status = chip->direction_output(chip, gpio, value);
 	if (status == 0)
 		set_bit(FLAG_IS_OUT, &desc->flags);
+	trace_gpio_value(chip->base + gpio, 0, value);
+	trace_gpio_direction(chip->base + gpio, 0, status);
 lose:
 	return status;
 fail:
@@ -1546,10 +1553,13 @@
 int __gpio_get_value(unsigned gpio)
 {
 	struct gpio_chip	*chip;
+	int value;
 
 	chip = gpio_to_chip(gpio);
 	WARN_ON(chip->can_sleep);
-	return chip->get ? chip->get(chip, gpio - chip->base) : 0;
+	value = chip->get ? chip->get(chip, gpio - chip->base) : 0;
+	trace_gpio_value(gpio, 1, value);
+	return value;
 }
 EXPORT_SYMBOL_GPL(__gpio_get_value);
 
@@ -1568,6 +1578,7 @@
 
 	chip = gpio_to_chip(gpio);
 	WARN_ON(chip->can_sleep);
+	trace_gpio_value(gpio, 0, value);
 	chip->set(chip, gpio - chip->base, value);
 }
 EXPORT_SYMBOL_GPL(__gpio_set_value);
@@ -1618,10 +1629,13 @@
 int gpio_get_value_cansleep(unsigned gpio)
 {
 	struct gpio_chip	*chip;
+	int value;
 
 	might_sleep_if(extra_checks);
 	chip = gpio_to_chip(gpio);
-	return chip->get ? chip->get(chip, gpio - chip->base) : 0;
+	value = chip->get ? chip->get(chip, gpio - chip->base) : 0;
+	trace_gpio_value(gpio, 1, value);
+	return value;
 }
 EXPORT_SYMBOL_GPL(gpio_get_value_cansleep);
 
@@ -1631,6 +1645,7 @@
 
 	might_sleep_if(extra_checks);
 	chip = gpio_to_chip(gpio);
+	trace_gpio_value(gpio, 0, value);
 	chip->set(chip, gpio - chip->base, value);
 }
 EXPORT_SYMBOL_GPL(gpio_set_value_cansleep);
diff -druN linux-2.6.39-libre/drivers/gpio/gpio-nomadik.c linux-3.0-rc7-libre/drivers/gpio/gpio-nomadik.c
--- linux-2.6.39-libre/drivers/gpio/gpio-nomadik.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/gpio/gpio-nomadik.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,1087 @@
+/*
+ * Generic GPIO driver for logic cells found in the Nomadik SoC
+ *
+ * Copyright (C) 2008,2009 STMicroelectronics
+ * Copyright (C) 2009 Alessandro Rubini <rubini@unipv.it>
+ *   Rewritten based on work by Prafulla WADASKAR <prafulla.wadaskar@st.com>
+ * Copyright (C) 2011 Linus Walleij <linus.walleij@linaro.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/gpio.h>
+#include <linux/spinlock.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/slab.h>
+
+#include <asm/mach/irq.h>
+
+#include <plat/pincfg.h>
+#include <mach/hardware.h>
+#include <mach/gpio.h>
+
+/*
+ * The GPIO module in the Nomadik family of Systems-on-Chip is an
+ * AMBA device, managing 32 pins and alternate functions.  The logic block
+ * is currently used in the Nomadik and ux500.
+ *
+ * Symbols in this file are called "nmk_gpio" for "nomadik gpio"
+ */
+
+#define NMK_GPIO_PER_CHIP	32
+
+struct nmk_gpio_chip {
+	struct gpio_chip chip;
+	void __iomem *addr;
+	struct clk *clk;
+	unsigned int bank;
+	unsigned int parent_irq;
+	int secondary_parent_irq;
+	u32 (*get_secondary_status)(unsigned int bank);
+	void (*set_ioforce)(bool enable);
+	spinlock_t lock;
+	bool sleepmode;
+	/* Keep track of configured edges */
+	u32 edge_rising;
+	u32 edge_falling;
+	u32 real_wake;
+	u32 rwimsc;
+	u32 fwimsc;
+	u32 slpm;
+	u32 enabled;
+	u32 pull_up;
+};
+
+static struct nmk_gpio_chip *
+nmk_gpio_chips[DIV_ROUND_UP(ARCH_NR_GPIOS, NMK_GPIO_PER_CHIP)];
+
+static DEFINE_SPINLOCK(nmk_gpio_slpm_lock);
+
+#define NUM_BANKS ARRAY_SIZE(nmk_gpio_chips)
+
+static void __nmk_gpio_set_mode(struct nmk_gpio_chip *nmk_chip,
+				unsigned offset, int gpio_mode)
+{
+	u32 bit = 1 << offset;
+	u32 afunc, bfunc;
+
+	afunc = readl(nmk_chip->addr + NMK_GPIO_AFSLA) & ~bit;
+	bfunc = readl(nmk_chip->addr + NMK_GPIO_AFSLB) & ~bit;
+	if (gpio_mode & NMK_GPIO_ALT_A)
+		afunc |= bit;
+	if (gpio_mode & NMK_GPIO_ALT_B)
+		bfunc |= bit;
+	writel(afunc, nmk_chip->addr + NMK_GPIO_AFSLA);
+	writel(bfunc, nmk_chip->addr + NMK_GPIO_AFSLB);
+}
+
+static void __nmk_gpio_set_slpm(struct nmk_gpio_chip *nmk_chip,
+				unsigned offset, enum nmk_gpio_slpm mode)
+{
+	u32 bit = 1 << offset;
+	u32 slpm;
+
+	slpm = readl(nmk_chip->addr + NMK_GPIO_SLPC);
+	if (mode == NMK_GPIO_SLPM_NOCHANGE)
+		slpm |= bit;
+	else
+		slpm &= ~bit;
+	writel(slpm, nmk_chip->addr + NMK_GPIO_SLPC);
+}
+
+static void __nmk_gpio_set_pull(struct nmk_gpio_chip *nmk_chip,
+				unsigned offset, enum nmk_gpio_pull pull)
+{
+	u32 bit = 1 << offset;
+	u32 pdis;
+
+	pdis = readl(nmk_chip->addr + NMK_GPIO_PDIS);
+	if (pull == NMK_GPIO_PULL_NONE) {
+		pdis |= bit;
+		nmk_chip->pull_up &= ~bit;
+	} else {
+		pdis &= ~bit;
+	}
+
+	writel(pdis, nmk_chip->addr + NMK_GPIO_PDIS);
+
+	if (pull == NMK_GPIO_PULL_UP) {
+		nmk_chip->pull_up |= bit;
+		writel(bit, nmk_chip->addr + NMK_GPIO_DATS);
+	} else if (pull == NMK_GPIO_PULL_DOWN) {
+		nmk_chip->pull_up &= ~bit;
+		writel(bit, nmk_chip->addr + NMK_GPIO_DATC);
+	}
+}
+
+static void __nmk_gpio_make_input(struct nmk_gpio_chip *nmk_chip,
+				  unsigned offset)
+{
+	writel(1 << offset, nmk_chip->addr + NMK_GPIO_DIRC);
+}
+
+static void __nmk_gpio_set_output(struct nmk_gpio_chip *nmk_chip,
+				  unsigned offset, int val)
+{
+	if (val)
+		writel(1 << offset, nmk_chip->addr + NMK_GPIO_DATS);
+	else
+		writel(1 << offset, nmk_chip->addr + NMK_GPIO_DATC);
+}
+
+static void __nmk_gpio_make_output(struct nmk_gpio_chip *nmk_chip,
+				  unsigned offset, int val)
+{
+	writel(1 << offset, nmk_chip->addr + NMK_GPIO_DIRS);
+	__nmk_gpio_set_output(nmk_chip, offset, val);
+}
+
+static void __nmk_gpio_set_mode_safe(struct nmk_gpio_chip *nmk_chip,
+				     unsigned offset, int gpio_mode,
+				     bool glitch)
+{
+	u32 rwimsc = readl(nmk_chip->addr + NMK_GPIO_RWIMSC);
+	u32 fwimsc = readl(nmk_chip->addr + NMK_GPIO_FWIMSC);
+
+	if (glitch && nmk_chip->set_ioforce) {
+		u32 bit = BIT(offset);
+
+		/* Prevent spurious wakeups */
+		writel(rwimsc & ~bit, nmk_chip->addr + NMK_GPIO_RWIMSC);
+		writel(fwimsc & ~bit, nmk_chip->addr + NMK_GPIO_FWIMSC);
+
+		nmk_chip->set_ioforce(true);
+	}
+
+	__nmk_gpio_set_mode(nmk_chip, offset, gpio_mode);
+
+	if (glitch && nmk_chip->set_ioforce) {
+		nmk_chip->set_ioforce(false);
+
+		writel(rwimsc, nmk_chip->addr + NMK_GPIO_RWIMSC);
+		writel(fwimsc, nmk_chip->addr + NMK_GPIO_FWIMSC);
+	}
+}
+
+static void __nmk_config_pin(struct nmk_gpio_chip *nmk_chip, unsigned offset,
+			     pin_cfg_t cfg, bool sleep, unsigned int *slpmregs)
+{
+	static const char *afnames[] = {
+		[NMK_GPIO_ALT_GPIO]	= "GPIO",
+		[NMK_GPIO_ALT_A]	= "A",
+		[NMK_GPIO_ALT_B]	= "B",
+		[NMK_GPIO_ALT_C]	= "C"
+	};
+	static const char *pullnames[] = {
+		[NMK_GPIO_PULL_NONE]	= "none",
+		[NMK_GPIO_PULL_UP]	= "up",
+		[NMK_GPIO_PULL_DOWN]	= "down",
+		[3] /* illegal */	= "??"
+	};
+	static const char *slpmnames[] = {
+		[NMK_GPIO_SLPM_INPUT]		= "input/wakeup",
+		[NMK_GPIO_SLPM_NOCHANGE]	= "no-change/no-wakeup",
+	};
+
+	int pin = PIN_NUM(cfg);
+	int pull = PIN_PULL(cfg);
+	int af = PIN_ALT(cfg);
+	int slpm = PIN_SLPM(cfg);
+	int output = PIN_DIR(cfg);
+	int val = PIN_VAL(cfg);
+	bool glitch = af == NMK_GPIO_ALT_C;
+
+	dev_dbg(nmk_chip->chip.dev, "pin %d [%#lx]: af %s, pull %s, slpm %s (%s%s)\n",
+		pin, cfg, afnames[af], pullnames[pull], slpmnames[slpm],
+		output ? "output " : "input",
+		output ? (val ? "high" : "low") : "");
+
+	if (sleep) {
+		int slpm_pull = PIN_SLPM_PULL(cfg);
+		int slpm_output = PIN_SLPM_DIR(cfg);
+		int slpm_val = PIN_SLPM_VAL(cfg);
+
+		af = NMK_GPIO_ALT_GPIO;
+
+		/*
+		 * The SLPM_* values are normal values + 1 to allow zero to
+		 * mean "same as normal".
+		 */
+		if (slpm_pull)
+			pull = slpm_pull - 1;
+		if (slpm_output)
+			output = slpm_output - 1;
+		if (slpm_val)
+			val = slpm_val - 1;
+
+		dev_dbg(nmk_chip->chip.dev, "pin %d: sleep pull %s, dir %s, val %s\n",
+			pin,
+			slpm_pull ? pullnames[pull] : "same",
+			slpm_output ? (output ? "output" : "input") : "same",
+			slpm_val ? (val ? "high" : "low") : "same");
+	}
+
+	if (output)
+		__nmk_gpio_make_output(nmk_chip, offset, val);
+	else {
+		__nmk_gpio_make_input(nmk_chip, offset);
+		__nmk_gpio_set_pull(nmk_chip, offset, pull);
+	}
+
+	/*
+	 * If we've backed up the SLPM registers (glitch workaround), modify
+	 * the backups since they will be restored.
+	 */
+	if (slpmregs) {
+		if (slpm == NMK_GPIO_SLPM_NOCHANGE)
+			slpmregs[nmk_chip->bank] |= BIT(offset);
+		else
+			slpmregs[nmk_chip->bank] &= ~BIT(offset);
+	} else
+		__nmk_gpio_set_slpm(nmk_chip, offset, slpm);
+
+	__nmk_gpio_set_mode_safe(nmk_chip, offset, af, glitch);
+}
+
+/*
+ * Safe sequence used to switch IOs between GPIO and Alternate-C mode:
+ *  - Save SLPM registers
+ *  - Set SLPM=0 for the IOs you want to switch and others to 1
+ *  - Configure the GPIO registers for the IOs that are being switched
+ *  - Set IOFORCE=1
+ *  - Modify the AFLSA/B registers for the IOs that are being switched
+ *  - Set IOFORCE=0
+ *  - Restore SLPM registers
+ *  - Any spurious wake up event during switch sequence to be ignored and
+ *    cleared
+ */
+static void nmk_gpio_glitch_slpm_init(unsigned int *slpm)
+{
+	int i;
+
+	for (i = 0; i < NUM_BANKS; i++) {
+		struct nmk_gpio_chip *chip = nmk_gpio_chips[i];
+		unsigned int temp = slpm[i];
+
+		if (!chip)
+			break;
+
+		slpm[i] = readl(chip->addr + NMK_GPIO_SLPC);
+		writel(temp, chip->addr + NMK_GPIO_SLPC);
+	}
+}
+
+static void nmk_gpio_glitch_slpm_restore(unsigned int *slpm)
+{
+	int i;
+
+	for (i = 0; i < NUM_BANKS; i++) {
+		struct nmk_gpio_chip *chip = nmk_gpio_chips[i];
+
+		if (!chip)
+			break;
+
+		writel(slpm[i], chip->addr + NMK_GPIO_SLPC);
+	}
+}
+
+static int __nmk_config_pins(pin_cfg_t *cfgs, int num, bool sleep)
+{
+	static unsigned int slpm[NUM_BANKS];
+	unsigned long flags;
+	bool glitch = false;
+	int ret = 0;
+	int i;
+
+	for (i = 0; i < num; i++) {
+		if (PIN_ALT(cfgs[i]) == NMK_GPIO_ALT_C) {
+			glitch = true;
+			break;
+		}
+	}
+
+	spin_lock_irqsave(&nmk_gpio_slpm_lock, flags);
+
+	if (glitch) {
+		memset(slpm, 0xff, sizeof(slpm));
+
+		for (i = 0; i < num; i++) {
+			int pin = PIN_NUM(cfgs[i]);
+			int offset = pin % NMK_GPIO_PER_CHIP;
+
+			if (PIN_ALT(cfgs[i]) == NMK_GPIO_ALT_C)
+				slpm[pin / NMK_GPIO_PER_CHIP] &= ~BIT(offset);
+		}
+
+		nmk_gpio_glitch_slpm_init(slpm);
+	}
+
+	for (i = 0; i < num; i++) {
+		struct nmk_gpio_chip *nmk_chip;
+		int pin = PIN_NUM(cfgs[i]);
+
+		nmk_chip = irq_get_chip_data(NOMADIK_GPIO_TO_IRQ(pin));
+		if (!nmk_chip) {
+			ret = -EINVAL;
+			break;
+		}
+
+		spin_lock(&nmk_chip->lock);
+		__nmk_config_pin(nmk_chip, pin - nmk_chip->chip.base,
+				 cfgs[i], sleep, glitch ? slpm : NULL);
+		spin_unlock(&nmk_chip->lock);
+	}
+
+	if (glitch)
+		nmk_gpio_glitch_slpm_restore(slpm);
+
+	spin_unlock_irqrestore(&nmk_gpio_slpm_lock, flags);
+
+	return ret;
+}
+
+/**
+ * nmk_config_pin - configure a pin's mux attributes
+ * @cfg: pin confguration
+ *
+ * Configures a pin's mode (alternate function or GPIO), its pull up status,
+ * and its sleep mode based on the specified configuration.  The @cfg is
+ * usually one of the SoC specific macros defined in mach/<soc>-pins.h.  These
+ * are constructed using, and can be further enhanced with, the macros in
+ * plat/pincfg.h.
+ *
+ * If a pin's mode is set to GPIO, it is configured as an input to avoid
+ * side-effects.  The gpio can be manipulated later using standard GPIO API
+ * calls.
+ */
+int nmk_config_pin(pin_cfg_t cfg, bool sleep)
+{
+	return __nmk_config_pins(&cfg, 1, sleep);
+}
+EXPORT_SYMBOL(nmk_config_pin);
+
+/**
+ * nmk_config_pins - configure several pins at once
+ * @cfgs: array of pin configurations
+ * @num: number of elments in the array
+ *
+ * Configures several pins using nmk_config_pin().  Refer to that function for
+ * further information.
+ */
+int nmk_config_pins(pin_cfg_t *cfgs, int num)
+{
+	return __nmk_config_pins(cfgs, num, false);
+}
+EXPORT_SYMBOL(nmk_config_pins);
+
+int nmk_config_pins_sleep(pin_cfg_t *cfgs, int num)
+{
+	return __nmk_config_pins(cfgs, num, true);
+}
+EXPORT_SYMBOL(nmk_config_pins_sleep);
+
+/**
+ * nmk_gpio_set_slpm() - configure the sleep mode of a pin
+ * @gpio: pin number
+ * @mode: NMK_GPIO_SLPM_INPUT or NMK_GPIO_SLPM_NOCHANGE,
+ *
+ * This register is actually in the pinmux layer, not the GPIO block itself.
+ * The GPIO1B_SLPM register defines the GPIO mode when SLEEP/DEEP-SLEEP
+ * mode is entered (i.e. when signal IOFORCE is HIGH by the platform code).
+ * Each GPIO can be configured to be forced into GPIO mode when IOFORCE is
+ * HIGH, overriding the normal setting defined by GPIO_AFSELx registers.
+ * When IOFORCE returns LOW (by software, after SLEEP/DEEP-SLEEP exit),
+ * the GPIOs return to the normal setting defined by GPIO_AFSELx registers.
+ *
+ * If @mode is NMK_GPIO_SLPM_INPUT, the corresponding GPIO is switched to GPIO
+ * mode when signal IOFORCE is HIGH (i.e. when SLEEP/DEEP-SLEEP mode is
+ * entered) regardless of the altfunction selected. Also wake-up detection is
+ * ENABLED.
+ *
+ * If @mode is NMK_GPIO_SLPM_NOCHANGE, the corresponding GPIO remains
+ * controlled by NMK_GPIO_DATC, NMK_GPIO_DATS, NMK_GPIO_DIR, NMK_GPIO_PDIS
+ * (for altfunction GPIO) or respective on-chip peripherals (for other
+ * altfuncs) when IOFORCE is HIGH. Also wake-up detection DISABLED.
+ *
+ * Note that enable_irq_wake() will automatically enable wakeup detection.
+ */
+int nmk_gpio_set_slpm(int gpio, enum nmk_gpio_slpm mode)
+{
+	struct nmk_gpio_chip *nmk_chip;
+	unsigned long flags;
+
+	nmk_chip = irq_get_chip_data(NOMADIK_GPIO_TO_IRQ(gpio));
+	if (!nmk_chip)
+		return -EINVAL;
+
+	spin_lock_irqsave(&nmk_gpio_slpm_lock, flags);
+	spin_lock(&nmk_chip->lock);
+
+	__nmk_gpio_set_slpm(nmk_chip, gpio - nmk_chip->chip.base, mode);
+
+	spin_unlock(&nmk_chip->lock);
+	spin_unlock_irqrestore(&nmk_gpio_slpm_lock, flags);
+
+	return 0;
+}
+
+/**
+ * nmk_gpio_set_pull() - enable/disable pull up/down on a gpio
+ * @gpio: pin number
+ * @pull: one of NMK_GPIO_PULL_DOWN, NMK_GPIO_PULL_UP, and NMK_GPIO_PULL_NONE
+ *
+ * Enables/disables pull up/down on a specified pin.  This only takes effect if
+ * the pin is configured as an input (either explicitly or by the alternate
+ * function).
+ *
+ * NOTE: If enabling the pull up/down, the caller must ensure that the GPIO is
+ * configured as an input.  Otherwise, due to the way the controller registers
+ * work, this function will change the value output on the pin.
+ */
+int nmk_gpio_set_pull(int gpio, enum nmk_gpio_pull pull)
+{
+	struct nmk_gpio_chip *nmk_chip;
+	unsigned long flags;
+
+	nmk_chip = irq_get_chip_data(NOMADIK_GPIO_TO_IRQ(gpio));
+	if (!nmk_chip)
+		return -EINVAL;
+
+	spin_lock_irqsave(&nmk_chip->lock, flags);
+	__nmk_gpio_set_pull(nmk_chip, gpio - nmk_chip->chip.base, pull);
+	spin_unlock_irqrestore(&nmk_chip->lock, flags);
+
+	return 0;
+}
+
+/* Mode functions */
+/**
+ * nmk_gpio_set_mode() - set the mux mode of a gpio pin
+ * @gpio: pin number
+ * @gpio_mode: one of NMK_GPIO_ALT_GPIO, NMK_GPIO_ALT_A,
+ *	       NMK_GPIO_ALT_B, and NMK_GPIO_ALT_C
+ *
+ * Sets the mode of the specified pin to one of the alternate functions or
+ * plain GPIO.
+ */
+int nmk_gpio_set_mode(int gpio, int gpio_mode)
+{
+	struct nmk_gpio_chip *nmk_chip;
+	unsigned long flags;
+
+	nmk_chip = irq_get_chip_data(NOMADIK_GPIO_TO_IRQ(gpio));
+	if (!nmk_chip)
+		return -EINVAL;
+
+	spin_lock_irqsave(&nmk_chip->lock, flags);
+	__nmk_gpio_set_mode(nmk_chip, gpio - nmk_chip->chip.base, gpio_mode);
+	spin_unlock_irqrestore(&nmk_chip->lock, flags);
+
+	return 0;
+}
+EXPORT_SYMBOL(nmk_gpio_set_mode);
+
+int nmk_gpio_get_mode(int gpio)
+{
+	struct nmk_gpio_chip *nmk_chip;
+	u32 afunc, bfunc, bit;
+
+	nmk_chip = irq_get_chip_data(NOMADIK_GPIO_TO_IRQ(gpio));
+	if (!nmk_chip)
+		return -EINVAL;
+
+	bit = 1 << (gpio - nmk_chip->chip.base);
+
+	afunc = readl(nmk_chip->addr + NMK_GPIO_AFSLA) & bit;
+	bfunc = readl(nmk_chip->addr + NMK_GPIO_AFSLB) & bit;
+
+	return (afunc ? NMK_GPIO_ALT_A : 0) | (bfunc ? NMK_GPIO_ALT_B : 0);
+}
+EXPORT_SYMBOL(nmk_gpio_get_mode);
+
+
+/* IRQ functions */
+static inline int nmk_gpio_get_bitmask(int gpio)
+{
+	return 1 << (gpio % 32);
+}
+
+static void nmk_gpio_irq_ack(struct irq_data *d)
+{
+	int gpio;
+	struct nmk_gpio_chip *nmk_chip;
+
+	gpio = NOMADIK_IRQ_TO_GPIO(d->irq);
+	nmk_chip = irq_data_get_irq_chip_data(d);
+	if (!nmk_chip)
+		return;
+	writel(nmk_gpio_get_bitmask(gpio), nmk_chip->addr + NMK_GPIO_IC);
+}
+
+enum nmk_gpio_irq_type {
+	NORMAL,
+	WAKE,
+};
+
+static void __nmk_gpio_irq_modify(struct nmk_gpio_chip *nmk_chip,
+				  int gpio, enum nmk_gpio_irq_type which,
+				  bool enable)
+{
+	u32 rimsc = which == WAKE ? NMK_GPIO_RWIMSC : NMK_GPIO_RIMSC;
+	u32 fimsc = which == WAKE ? NMK_GPIO_FWIMSC : NMK_GPIO_FIMSC;
+	u32 bitmask = nmk_gpio_get_bitmask(gpio);
+	u32 reg;
+
+	/* we must individually set/clear the two edges */
+	if (nmk_chip->edge_rising & bitmask) {
+		reg = readl(nmk_chip->addr + rimsc);
+		if (enable)
+			reg |= bitmask;
+		else
+			reg &= ~bitmask;
+		writel(reg, nmk_chip->addr + rimsc);
+	}
+	if (nmk_chip->edge_falling & bitmask) {
+		reg = readl(nmk_chip->addr + fimsc);
+		if (enable)
+			reg |= bitmask;
+		else
+			reg &= ~bitmask;
+		writel(reg, nmk_chip->addr + fimsc);
+	}
+}
+
+static void __nmk_gpio_set_wake(struct nmk_gpio_chip *nmk_chip,
+				int gpio, bool on)
+{
+	if (nmk_chip->sleepmode) {
+		__nmk_gpio_set_slpm(nmk_chip, gpio - nmk_chip->chip.base,
+				    on ? NMK_GPIO_SLPM_WAKEUP_ENABLE
+				    : NMK_GPIO_SLPM_WAKEUP_DISABLE);
+	}
+
+	__nmk_gpio_irq_modify(nmk_chip, gpio, WAKE, on);
+}
+
+static int nmk_gpio_irq_maskunmask(struct irq_data *d, bool enable)
+{
+	int gpio;
+	struct nmk_gpio_chip *nmk_chip;
+	unsigned long flags;
+	u32 bitmask;
+
+	gpio = NOMADIK_IRQ_TO_GPIO(d->irq);
+	nmk_chip = irq_data_get_irq_chip_data(d);
+	bitmask = nmk_gpio_get_bitmask(gpio);
+	if (!nmk_chip)
+		return -EINVAL;
+
+	if (enable)
+		nmk_chip->enabled |= bitmask;
+	else
+		nmk_chip->enabled &= ~bitmask;
+
+	spin_lock_irqsave(&nmk_gpio_slpm_lock, flags);
+	spin_lock(&nmk_chip->lock);
+
+	__nmk_gpio_irq_modify(nmk_chip, gpio, NORMAL, enable);
+
+	if (!(nmk_chip->real_wake & bitmask))
+		__nmk_gpio_set_wake(nmk_chip, gpio, enable);
+
+	spin_unlock(&nmk_chip->lock);
+	spin_unlock_irqrestore(&nmk_gpio_slpm_lock, flags);
+
+	return 0;
+}
+
+static void nmk_gpio_irq_mask(struct irq_data *d)
+{
+	nmk_gpio_irq_maskunmask(d, false);
+}
+
+static void nmk_gpio_irq_unmask(struct irq_data *d)
+{
+	nmk_gpio_irq_maskunmask(d, true);
+}
+
+static int nmk_gpio_irq_set_wake(struct irq_data *d, unsigned int on)
+{
+	struct nmk_gpio_chip *nmk_chip;
+	unsigned long flags;
+	u32 bitmask;
+	int gpio;
+
+	gpio = NOMADIK_IRQ_TO_GPIO(d->irq);
+	nmk_chip = irq_data_get_irq_chip_data(d);
+	if (!nmk_chip)
+		return -EINVAL;
+	bitmask = nmk_gpio_get_bitmask(gpio);
+
+	spin_lock_irqsave(&nmk_gpio_slpm_lock, flags);
+	spin_lock(&nmk_chip->lock);
+
+	if (!(nmk_chip->enabled & bitmask))
+		__nmk_gpio_set_wake(nmk_chip, gpio, on);
+
+	if (on)
+		nmk_chip->real_wake |= bitmask;
+	else
+		nmk_chip->real_wake &= ~bitmask;
+
+	spin_unlock(&nmk_chip->lock);
+	spin_unlock_irqrestore(&nmk_gpio_slpm_lock, flags);
+
+	return 0;
+}
+
+static int nmk_gpio_irq_set_type(struct irq_data *d, unsigned int type)
+{
+	bool enabled, wake = irqd_is_wakeup_set(d);
+	int gpio;
+	struct nmk_gpio_chip *nmk_chip;
+	unsigned long flags;
+	u32 bitmask;
+
+	gpio = NOMADIK_IRQ_TO_GPIO(d->irq);
+	nmk_chip = irq_data_get_irq_chip_data(d);
+	bitmask = nmk_gpio_get_bitmask(gpio);
+	if (!nmk_chip)
+		return -EINVAL;
+
+	if (type & IRQ_TYPE_LEVEL_HIGH)
+		return -EINVAL;
+	if (type & IRQ_TYPE_LEVEL_LOW)
+		return -EINVAL;
+
+	enabled = nmk_chip->enabled & bitmask;
+
+	spin_lock_irqsave(&nmk_chip->lock, flags);
+
+	if (enabled)
+		__nmk_gpio_irq_modify(nmk_chip, gpio, NORMAL, false);
+
+	if (enabled || wake)
+		__nmk_gpio_irq_modify(nmk_chip, gpio, WAKE, false);
+
+	nmk_chip->edge_rising &= ~bitmask;
+	if (type & IRQ_TYPE_EDGE_RISING)
+		nmk_chip->edge_rising |= bitmask;
+
+	nmk_chip->edge_falling &= ~bitmask;
+	if (type & IRQ_TYPE_EDGE_FALLING)
+		nmk_chip->edge_falling |= bitmask;
+
+	if (enabled)
+		__nmk_gpio_irq_modify(nmk_chip, gpio, NORMAL, true);
+
+	if (enabled || wake)
+		__nmk_gpio_irq_modify(nmk_chip, gpio, WAKE, true);
+
+	spin_unlock_irqrestore(&nmk_chip->lock, flags);
+
+	return 0;
+}
+
+static struct irq_chip nmk_gpio_irq_chip = {
+	.name		= "Nomadik-GPIO",
+	.irq_ack	= nmk_gpio_irq_ack,
+	.irq_mask	= nmk_gpio_irq_mask,
+	.irq_unmask	= nmk_gpio_irq_unmask,
+	.irq_set_type	= nmk_gpio_irq_set_type,
+	.irq_set_wake	= nmk_gpio_irq_set_wake,
+};
+
+static void __nmk_gpio_irq_handler(unsigned int irq, struct irq_desc *desc,
+				   u32 status)
+{
+	struct nmk_gpio_chip *nmk_chip;
+	struct irq_chip *host_chip = irq_get_chip(irq);
+	unsigned int first_irq;
+
+	chained_irq_enter(host_chip, desc);
+
+	nmk_chip = irq_get_handler_data(irq);
+	first_irq = NOMADIK_GPIO_TO_IRQ(nmk_chip->chip.base);
+	while (status) {
+		int bit = __ffs(status);
+
+		generic_handle_irq(first_irq + bit);
+		status &= ~BIT(bit);
+	}
+
+	chained_irq_exit(host_chip, desc);
+}
+
+static void nmk_gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
+{
+	struct nmk_gpio_chip *nmk_chip = irq_get_handler_data(irq);
+	u32 status = readl(nmk_chip->addr + NMK_GPIO_IS);
+
+	__nmk_gpio_irq_handler(irq, desc, status);
+}
+
+static void nmk_gpio_secondary_irq_handler(unsigned int irq,
+					   struct irq_desc *desc)
+{
+	struct nmk_gpio_chip *nmk_chip = irq_get_handler_data(irq);
+	u32 status = nmk_chip->get_secondary_status(nmk_chip->bank);
+
+	__nmk_gpio_irq_handler(irq, desc, status);
+}
+
+static int nmk_gpio_init_irq(struct nmk_gpio_chip *nmk_chip)
+{
+	unsigned int first_irq;
+	int i;
+
+	first_irq = NOMADIK_GPIO_TO_IRQ(nmk_chip->chip.base);
+	for (i = first_irq; i < first_irq + nmk_chip->chip.ngpio; i++) {
+		irq_set_chip_and_handler(i, &nmk_gpio_irq_chip,
+					 handle_edge_irq);
+		set_irq_flags(i, IRQF_VALID);
+		irq_set_chip_data(i, nmk_chip);
+		irq_set_irq_type(i, IRQ_TYPE_EDGE_FALLING);
+	}
+
+	irq_set_chained_handler(nmk_chip->parent_irq, nmk_gpio_irq_handler);
+	irq_set_handler_data(nmk_chip->parent_irq, nmk_chip);
+
+	if (nmk_chip->secondary_parent_irq >= 0) {
+		irq_set_chained_handler(nmk_chip->secondary_parent_irq,
+					nmk_gpio_secondary_irq_handler);
+		irq_set_handler_data(nmk_chip->secondary_parent_irq, nmk_chip);
+	}
+
+	return 0;
+}
+
+/* I/O Functions */
+static int nmk_gpio_make_input(struct gpio_chip *chip, unsigned offset)
+{
+	struct nmk_gpio_chip *nmk_chip =
+		container_of(chip, struct nmk_gpio_chip, chip);
+
+	writel(1 << offset, nmk_chip->addr + NMK_GPIO_DIRC);
+	return 0;
+}
+
+static int nmk_gpio_get_input(struct gpio_chip *chip, unsigned offset)
+{
+	struct nmk_gpio_chip *nmk_chip =
+		container_of(chip, struct nmk_gpio_chip, chip);
+	u32 bit = 1 << offset;
+
+	return (readl(nmk_chip->addr + NMK_GPIO_DAT) & bit) != 0;
+}
+
+static void nmk_gpio_set_output(struct gpio_chip *chip, unsigned offset,
+				int val)
+{
+	struct nmk_gpio_chip *nmk_chip =
+		container_of(chip, struct nmk_gpio_chip, chip);
+
+	__nmk_gpio_set_output(nmk_chip, offset, val);
+}
+
+static int nmk_gpio_make_output(struct gpio_chip *chip, unsigned offset,
+				int val)
+{
+	struct nmk_gpio_chip *nmk_chip =
+		container_of(chip, struct nmk_gpio_chip, chip);
+
+	__nmk_gpio_make_output(nmk_chip, offset, val);
+
+	return 0;
+}
+
+static int nmk_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
+{
+	struct nmk_gpio_chip *nmk_chip =
+		container_of(chip, struct nmk_gpio_chip, chip);
+
+	return NOMADIK_GPIO_TO_IRQ(nmk_chip->chip.base) + offset;
+}
+
+#ifdef CONFIG_DEBUG_FS
+
+#include <linux/seq_file.h>
+
+static void nmk_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip)
+{
+	int mode;
+	unsigned		i;
+	unsigned		gpio = chip->base;
+	int			is_out;
+	struct nmk_gpio_chip *nmk_chip =
+		container_of(chip, struct nmk_gpio_chip, chip);
+	const char *modes[] = {
+		[NMK_GPIO_ALT_GPIO]	= "gpio",
+		[NMK_GPIO_ALT_A]	= "altA",
+		[NMK_GPIO_ALT_B]	= "altB",
+		[NMK_GPIO_ALT_C]	= "altC",
+	};
+
+	for (i = 0; i < chip->ngpio; i++, gpio++) {
+		const char *label = gpiochip_is_requested(chip, i);
+		bool pull;
+		u32 bit = 1 << i;
+
+		is_out = readl(nmk_chip->addr + NMK_GPIO_DIR) & bit;
+		pull = !(readl(nmk_chip->addr + NMK_GPIO_PDIS) & bit);
+		mode = nmk_gpio_get_mode(gpio);
+		seq_printf(s, " gpio-%-3d (%-20.20s) %s %s %s %s",
+			gpio, label ?: "(none)",
+			is_out ? "out" : "in ",
+			chip->get
+				? (chip->get(chip, i) ? "hi" : "lo")
+				: "?  ",
+			(mode < 0) ? "unknown" : modes[mode],
+			pull ? "pull" : "none");
+
+		if (label && !is_out) {
+			int		irq = gpio_to_irq(gpio);
+			struct irq_desc	*desc = irq_to_desc(irq);
+
+			/* This races with request_irq(), set_irq_type(),
+			 * and set_irq_wake() ... but those are "rare".
+			 */
+			if (irq >= 0 && desc->action) {
+				char *trigger;
+				u32 bitmask = nmk_gpio_get_bitmask(gpio);
+
+				if (nmk_chip->edge_rising & bitmask)
+					trigger = "edge-rising";
+				else if (nmk_chip->edge_falling & bitmask)
+					trigger = "edge-falling";
+				else
+					trigger = "edge-undefined";
+
+				seq_printf(s, " irq-%d %s%s",
+					irq, trigger,
+					irqd_is_wakeup_set(&desc->irq_data)
+						? " wakeup" : "");
+			}
+		}
+
+		seq_printf(s, "\n");
+	}
+}
+
+#else
+#define nmk_gpio_dbg_show	NULL
+#endif
+
+/* This structure is replicated for each GPIO block allocated at probe time */
+static struct gpio_chip nmk_gpio_template = {
+	.direction_input	= nmk_gpio_make_input,
+	.get			= nmk_gpio_get_input,
+	.direction_output	= nmk_gpio_make_output,
+	.set			= nmk_gpio_set_output,
+	.to_irq			= nmk_gpio_to_irq,
+	.dbg_show		= nmk_gpio_dbg_show,
+	.can_sleep		= 0,
+};
+
+/*
+ * Called from the suspend/resume path to only keep the real wakeup interrupts
+ * (those that have had set_irq_wake() called on them) as wakeup interrupts,
+ * and not the rest of the interrupts which we needed to have as wakeups for
+ * cpuidle.
+ *
+ * PM ops are not used since this needs to be done at the end, after all the
+ * other drivers are done with their suspend callbacks.
+ */
+void nmk_gpio_wakeups_suspend(void)
+{
+	int i;
+
+	for (i = 0; i < NUM_BANKS; i++) {
+		struct nmk_gpio_chip *chip = nmk_gpio_chips[i];
+
+		if (!chip)
+			break;
+
+		chip->rwimsc = readl(chip->addr + NMK_GPIO_RWIMSC);
+		chip->fwimsc = readl(chip->addr + NMK_GPIO_FWIMSC);
+
+		writel(chip->rwimsc & chip->real_wake,
+		       chip->addr + NMK_GPIO_RWIMSC);
+		writel(chip->fwimsc & chip->real_wake,
+		       chip->addr + NMK_GPIO_FWIMSC);
+
+		if (chip->sleepmode) {
+			chip->slpm = readl(chip->addr + NMK_GPIO_SLPC);
+
+			/* 0 -> wakeup enable */
+			writel(~chip->real_wake, chip->addr + NMK_GPIO_SLPC);
+		}
+	}
+}
+
+void nmk_gpio_wakeups_resume(void)
+{
+	int i;
+
+	for (i = 0; i < NUM_BANKS; i++) {
+		struct nmk_gpio_chip *chip = nmk_gpio_chips[i];
+
+		if (!chip)
+			break;
+
+		writel(chip->rwimsc, chip->addr + NMK_GPIO_RWIMSC);
+		writel(chip->fwimsc, chip->addr + NMK_GPIO_FWIMSC);
+
+		if (chip->sleepmode)
+			writel(chip->slpm, chip->addr + NMK_GPIO_SLPC);
+	}
+}
+
+/*
+ * Read the pull up/pull down status.
+ * A bit set in 'pull_up' means that pull up
+ * is selected if pull is enabled in PDIS register.
+ * Note: only pull up/down set via this driver can
+ * be detected due to HW limitations.
+ */
+void nmk_gpio_read_pull(int gpio_bank, u32 *pull_up)
+{
+	if (gpio_bank < NUM_BANKS) {
+		struct nmk_gpio_chip *chip = nmk_gpio_chips[gpio_bank];
+
+		if (!chip)
+			return;
+
+		*pull_up = chip->pull_up;
+	}
+}
+
+static int __devinit nmk_gpio_probe(struct platform_device *dev)
+{
+	struct nmk_gpio_platform_data *pdata = dev->dev.platform_data;
+	struct nmk_gpio_chip *nmk_chip;
+	struct gpio_chip *chip;
+	struct resource *res;
+	struct clk *clk;
+	int secondary_irq;
+	int irq;
+	int ret;
+
+	if (!pdata)
+		return -ENODEV;
+
+	res = platform_get_resource(dev, IORESOURCE_MEM, 0);
+	if (!res) {
+		ret = -ENOENT;
+		goto out;
+	}
+
+	irq = platform_get_irq(dev, 0);
+	if (irq < 0) {
+		ret = irq;
+		goto out;
+	}
+
+	secondary_irq = platform_get_irq(dev, 1);
+	if (secondary_irq >= 0 && !pdata->get_secondary_status) {
+		ret = -EINVAL;
+		goto out;
+	}
+
+	if (request_mem_region(res->start, resource_size(res),
+			       dev_name(&dev->dev)) == NULL) {
+		ret = -EBUSY;
+		goto out;
+	}
+
+	clk = clk_get(&dev->dev, NULL);
+	if (IS_ERR(clk)) {
+		ret = PTR_ERR(clk);
+		goto out_release;
+	}
+
+	clk_enable(clk);
+
+	nmk_chip = kzalloc(sizeof(*nmk_chip), GFP_KERNEL);
+	if (!nmk_chip) {
+		ret = -ENOMEM;
+		goto out_clk;
+	}
+	/*
+	 * The virt address in nmk_chip->addr is in the nomadik register space,
+	 * so we can simply convert the resource address, without remapping
+	 */
+	nmk_chip->bank = dev->id;
+	nmk_chip->clk = clk;
+	nmk_chip->addr = io_p2v(res->start);
+	nmk_chip->chip = nmk_gpio_template;
+	nmk_chip->parent_irq = irq;
+	nmk_chip->secondary_parent_irq = secondary_irq;
+	nmk_chip->get_secondary_status = pdata->get_secondary_status;
+	nmk_chip->set_ioforce = pdata->set_ioforce;
+	nmk_chip->sleepmode = pdata->supports_sleepmode;
+	spin_lock_init(&nmk_chip->lock);
+
+	chip = &nmk_chip->chip;
+	chip->base = pdata->first_gpio;
+	chip->ngpio = pdata->num_gpio;
+	chip->label = pdata->name ?: dev_name(&dev->dev);
+	chip->dev = &dev->dev;
+	chip->owner = THIS_MODULE;
+
+	ret = gpiochip_add(&nmk_chip->chip);
+	if (ret)
+		goto out_free;
+
+	BUG_ON(nmk_chip->bank >= ARRAY_SIZE(nmk_gpio_chips));
+
+	nmk_gpio_chips[nmk_chip->bank] = nmk_chip;
+	platform_set_drvdata(dev, nmk_chip);
+
+	nmk_gpio_init_irq(nmk_chip);
+
+	dev_info(&dev->dev, "Bits %i-%i at address %p\n",
+		 nmk_chip->chip.base, nmk_chip->chip.base+31, nmk_chip->addr);
+	return 0;
+
+out_free:
+	kfree(nmk_chip);
+out_clk:
+	clk_disable(clk);
+	clk_put(clk);
+out_release:
+	release_mem_region(res->start, resource_size(res));
+out:
+	dev_err(&dev->dev, "Failure %i for GPIO %i-%i\n", ret,
+		  pdata->first_gpio, pdata->first_gpio+31);
+	return ret;
+}
+
+static struct platform_driver nmk_gpio_driver = {
+	.driver = {
+		.owner = THIS_MODULE,
+		.name = "gpio",
+	},
+	.probe = nmk_gpio_probe,
+};
+
+static int __init nmk_gpio_init(void)
+{
+	return platform_driver_register(&nmk_gpio_driver);
+}
+
+core_initcall(nmk_gpio_init);
+
+MODULE_AUTHOR("Prafulla WADASKAR and Alessandro Rubini");
+MODULE_DESCRIPTION("Nomadik GPIO Driver");
+MODULE_LICENSE("GPL");
diff -druN linux-2.6.39-libre/drivers/gpio/gpio-omap.c linux-3.0-rc7-libre/drivers/gpio/gpio-omap.c
--- linux-2.6.39-libre/drivers/gpio/gpio-omap.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/gpio/gpio-omap.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,2009 @@
+/*
+ * Support functions for OMAP GPIO
+ *
+ * Copyright (C) 2003-2005 Nokia Corporation
+ * Written by Juha Yrjölä <juha.yrjola@nokia.com>
+ *
+ * Copyright (C) 2009 Texas Instruments
+ * Added OMAP4 support - Santosh Shilimkar <santosh.shilimkar@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/syscore_ops.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/slab.h>
+#include <linux/pm_runtime.h>
+
+#include <mach/hardware.h>
+#include <asm/irq.h>
+#include <mach/irqs.h>
+#include <mach/gpio.h>
+#include <asm/mach/irq.h>
+
+struct gpio_bank {
+	unsigned long pbase;
+	void __iomem *base;
+	u16 irq;
+	u16 virtual_irq_start;
+	int method;
+#if defined(CONFIG_ARCH_OMAP16XX) || defined(CONFIG_ARCH_OMAP2PLUS)
+	u32 suspend_wakeup;
+	u32 saved_wakeup;
+#endif
+	u32 non_wakeup_gpios;
+	u32 enabled_non_wakeup_gpios;
+
+	u32 saved_datain;
+	u32 saved_fallingdetect;
+	u32 saved_risingdetect;
+	u32 level_mask;
+	u32 toggle_mask;
+	spinlock_t lock;
+	struct gpio_chip chip;
+	struct clk *dbck;
+	u32 mod_usage;
+	u32 dbck_enable_mask;
+	struct device *dev;
+	bool dbck_flag;
+	int stride;
+};
+
+#ifdef CONFIG_ARCH_OMAP3
+struct omap3_gpio_regs {
+	u32 irqenable1;
+	u32 irqenable2;
+	u32 wake_en;
+	u32 ctrl;
+	u32 oe;
+	u32 leveldetect0;
+	u32 leveldetect1;
+	u32 risingdetect;
+	u32 fallingdetect;
+	u32 dataout;
+};
+
+static struct omap3_gpio_regs gpio_context[OMAP34XX_NR_GPIOS];
+#endif
+
+/*
+ * TODO: Cleanup gpio_bank usage as it is having information
+ * related to all instances of the device
+ */
+static struct gpio_bank *gpio_bank;
+
+static int bank_width;
+
+/* TODO: Analyze removing gpio_bank_count usage from driver code */
+int gpio_bank_count;
+
+static inline struct gpio_bank *get_gpio_bank(int gpio)
+{
+	if (cpu_is_omap15xx()) {
+		if (OMAP_GPIO_IS_MPUIO(gpio))
+			return &gpio_bank[0];
+		return &gpio_bank[1];
+	}
+	if (cpu_is_omap16xx()) {
+		if (OMAP_GPIO_IS_MPUIO(gpio))
+			return &gpio_bank[0];
+		return &gpio_bank[1 + (gpio >> 4)];
+	}
+	if (cpu_is_omap7xx()) {
+		if (OMAP_GPIO_IS_MPUIO(gpio))
+			return &gpio_bank[0];
+		return &gpio_bank[1 + (gpio >> 5)];
+	}
+	if (cpu_is_omap24xx())
+		return &gpio_bank[gpio >> 5];
+	if (cpu_is_omap34xx() || cpu_is_omap44xx())
+		return &gpio_bank[gpio >> 5];
+	BUG();
+	return NULL;
+}
+
+static inline int get_gpio_index(int gpio)
+{
+	if (cpu_is_omap7xx())
+		return gpio & 0x1f;
+	if (cpu_is_omap24xx())
+		return gpio & 0x1f;
+	if (cpu_is_omap34xx() || cpu_is_omap44xx())
+		return gpio & 0x1f;
+	return gpio & 0x0f;
+}
+
+static inline int gpio_valid(int gpio)
+{
+	if (gpio < 0)
+		return -1;
+	if (cpu_class_is_omap1() && OMAP_GPIO_IS_MPUIO(gpio)) {
+		if (gpio >= OMAP_MAX_GPIO_LINES + 16)
+			return -1;
+		return 0;
+	}
+	if (cpu_is_omap15xx() && gpio < 16)
+		return 0;
+	if ((cpu_is_omap16xx()) && gpio < 64)
+		return 0;
+	if (cpu_is_omap7xx() && gpio < 192)
+		return 0;
+	if (cpu_is_omap2420() && gpio < 128)
+		return 0;
+	if (cpu_is_omap2430() && gpio < 160)
+		return 0;
+	if ((cpu_is_omap34xx() || cpu_is_omap44xx()) && gpio < 192)
+		return 0;
+	return -1;
+}
+
+static int check_gpio(int gpio)
+{
+	if (unlikely(gpio_valid(gpio) < 0)) {
+		printk(KERN_ERR "omap-gpio: invalid GPIO %d\n", gpio);
+		dump_stack();
+		return -1;
+	}
+	return 0;
+}
+
+static void _set_gpio_direction(struct gpio_bank *bank, int gpio, int is_input)
+{
+	void __iomem *reg = bank->base;
+	u32 l;
+
+	switch (bank->method) {
+#ifdef CONFIG_ARCH_OMAP1
+	case METHOD_MPUIO:
+		reg += OMAP_MPUIO_IO_CNTL / bank->stride;
+		break;
+#endif
+#ifdef CONFIG_ARCH_OMAP15XX
+	case METHOD_GPIO_1510:
+		reg += OMAP1510_GPIO_DIR_CONTROL;
+		break;
+#endif
+#ifdef CONFIG_ARCH_OMAP16XX
+	case METHOD_GPIO_1610:
+		reg += OMAP1610_GPIO_DIRECTION;
+		break;
+#endif
+#if defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP850)
+	case METHOD_GPIO_7XX:
+		reg += OMAP7XX_GPIO_DIR_CONTROL;
+		break;
+#endif
+#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_44XX:
+		reg += OMAP4_GPIO_OE;
+		break;
+#endif
+	default:
+		WARN_ON(1);
+		return;
+	}
+	l = __raw_readl(reg);
+	if (is_input)
+		l |= 1 << gpio;
+	else
+		l &= ~(1 << gpio);
+	__raw_writel(l, reg);
+}
+
+static void _set_gpio_dataout(struct gpio_bank *bank, int gpio, int enable)
+{
+	void __iomem *reg = bank->base;
+	u32 l = 0;
+
+	switch (bank->method) {
+#ifdef CONFIG_ARCH_OMAP1
+	case METHOD_MPUIO:
+		reg += OMAP_MPUIO_OUTPUT / bank->stride;
+		l = __raw_readl(reg);
+		if (enable)
+			l |= 1 << gpio;
+		else
+			l &= ~(1 << gpio);
+		break;
+#endif
+#ifdef CONFIG_ARCH_OMAP15XX
+	case METHOD_GPIO_1510:
+		reg += OMAP1510_GPIO_DATA_OUTPUT;
+		l = __raw_readl(reg);
+		if (enable)
+			l |= 1 << gpio;
+		else
+			l &= ~(1 << gpio);
+		break;
+#endif
+#ifdef CONFIG_ARCH_OMAP16XX
+	case METHOD_GPIO_1610:
+		if (enable)
+			reg += OMAP1610_GPIO_SET_DATAOUT;
+		else
+			reg += OMAP1610_GPIO_CLEAR_DATAOUT;
+		l = 1 << gpio;
+		break;
+#endif
+#if defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP850)
+	case METHOD_GPIO_7XX:
+		reg += OMAP7XX_GPIO_DATA_OUTPUT;
+		l = __raw_readl(reg);
+		if (enable)
+			l |= 1 << gpio;
+		else
+			l &= ~(1 << gpio);
+		break;
+#endif
+#if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3)
+	case METHOD_GPIO_24XX:
+		if (enable)
+			reg += OMAP24XX_GPIO_SETDATAOUT;
+		else
+			reg += OMAP24XX_GPIO_CLEARDATAOUT;
+		l = 1 << gpio;
+		break;
+#endif
+#ifdef CONFIG_ARCH_OMAP4
+	case METHOD_GPIO_44XX:
+		if (enable)
+			reg += OMAP4_GPIO_SETDATAOUT;
+		else
+			reg += OMAP4_GPIO_CLEARDATAOUT;
+		l = 1 << gpio;
+		break;
+#endif
+	default:
+		WARN_ON(1);
+		return;
+	}
+	__raw_writel(l, reg);
+}
+
+static int _get_gpio_datain(struct gpio_bank *bank, int gpio)
+{
+	void __iomem *reg;
+
+	if (check_gpio(gpio) < 0)
+		return -EINVAL;
+	reg = bank->base;
+	switch (bank->method) {
+#ifdef CONFIG_ARCH_OMAP1
+	case METHOD_MPUIO:
+		reg += OMAP_MPUIO_INPUT_LATCH / bank->stride;
+		break;
+#endif
+#ifdef CONFIG_ARCH_OMAP15XX
+	case METHOD_GPIO_1510:
+		reg += OMAP1510_GPIO_DATA_INPUT;
+		break;
+#endif
+#ifdef CONFIG_ARCH_OMAP16XX
+	case METHOD_GPIO_1610:
+		reg += OMAP1610_GPIO_DATAIN;
+		break;
+#endif
+#if defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP850)
+	case METHOD_GPIO_7XX:
+		reg += OMAP7XX_GPIO_DATA_INPUT;
+		break;
+#endif
+#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_44XX:
+		reg += OMAP4_GPIO_DATAIN;
+		break;
+#endif
+	default:
+		return -EINVAL;
+	}
+	return (__raw_readl(reg)
+			& (1 << get_gpio_index(gpio))) != 0;
+}
+
+static int _get_gpio_dataout(struct gpio_bank *bank, int gpio)
+{
+	void __iomem *reg;
+
+	if (check_gpio(gpio) < 0)
+		return -EINVAL;
+	reg = bank->base;
+
+	switch (bank->method) {
+#ifdef CONFIG_ARCH_OMAP1
+	case METHOD_MPUIO:
+		reg += OMAP_MPUIO_OUTPUT / bank->stride;
+		break;
+#endif
+#ifdef CONFIG_ARCH_OMAP15XX
+	case METHOD_GPIO_1510:
+		reg += OMAP1510_GPIO_DATA_OUTPUT;
+		break;
+#endif
+#ifdef CONFIG_ARCH_OMAP16XX
+	case METHOD_GPIO_1610:
+		reg += OMAP1610_GPIO_DATAOUT;
+		break;
+#endif
+#if defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP850)
+	case METHOD_GPIO_7XX:
+		reg += OMAP7XX_GPIO_DATA_OUTPUT;
+		break;
+#endif
+#if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3)
+	case METHOD_GPIO_24XX:
+		reg += OMAP24XX_GPIO_DATAOUT;
+		break;
+#endif
+#ifdef CONFIG_ARCH_OMAP4
+	case METHOD_GPIO_44XX:
+		reg += OMAP4_GPIO_DATAOUT;
+		break;
+#endif
+	default:
+		return -EINVAL;
+	}
+
+	return (__raw_readl(reg) & (1 << get_gpio_index(gpio))) != 0;
+}
+
+#define MOD_REG_BIT(reg, bit_mask, set)	\
+do {	\
+	int l = __raw_readl(base + reg); \
+	if (set) l |= bit_mask; \
+	else l &= ~bit_mask; \
+	__raw_writel(l, base + reg); \
+} while(0)
+
+/**
+ * _set_gpio_debounce - low level gpio debounce time
+ * @bank: the gpio bank we're acting upon
+ * @gpio: the gpio number on this @gpio
+ * @debounce: debounce time to use
+ *
+ * OMAP's debounce time is in 31us steps so we need
+ * to convert and round up to the closest unit.
+ */
+static void _set_gpio_debounce(struct gpio_bank *bank, unsigned gpio,
+		unsigned debounce)
+{
+	void __iomem		*reg = bank->base;
+	u32			val;
+	u32			l;
+
+	if (!bank->dbck_flag)
+		return;
+
+	if (debounce < 32)
+		debounce = 0x01;
+	else if (debounce > 7936)
+		debounce = 0xff;
+	else
+		debounce = (debounce / 0x1f) - 1;
+
+	l = 1 << get_gpio_index(gpio);
+
+	if (bank->method == METHOD_GPIO_44XX)
+		reg += OMAP4_GPIO_DEBOUNCINGTIME;
+	else
+		reg += OMAP24XX_GPIO_DEBOUNCE_VAL;
+
+	__raw_writel(debounce, reg);
+
+	reg = bank->base;
+	if (bank->method == METHOD_GPIO_44XX)
+		reg += OMAP4_GPIO_DEBOUNCENABLE;
+	else
+		reg += OMAP24XX_GPIO_DEBOUNCE_EN;
+
+	val = __raw_readl(reg);
+
+	if (debounce) {
+		val |= l;
+		clk_enable(bank->dbck);
+	} else {
+		val &= ~l;
+		clk_disable(bank->dbck);
+	}
+	bank->dbck_enable_mask = val;
+
+	__raw_writel(val, reg);
+}
+
+#ifdef CONFIG_ARCH_OMAP2PLUS
+static inline void set_24xx_gpio_triggering(struct gpio_bank *bank, int gpio,
+						int trigger)
+{
+	void __iomem *base = bank->base;
+	u32 gpio_bit = 1 << gpio;
+
+	if (cpu_is_omap44xx()) {
+		MOD_REG_BIT(OMAP4_GPIO_LEVELDETECT0, gpio_bit,
+			trigger & IRQ_TYPE_LEVEL_LOW);
+		MOD_REG_BIT(OMAP4_GPIO_LEVELDETECT1, gpio_bit,
+			trigger & IRQ_TYPE_LEVEL_HIGH);
+		MOD_REG_BIT(OMAP4_GPIO_RISINGDETECT, gpio_bit,
+			trigger & IRQ_TYPE_EDGE_RISING);
+		MOD_REG_BIT(OMAP4_GPIO_FALLINGDETECT, gpio_bit,
+			trigger & IRQ_TYPE_EDGE_FALLING);
+	} else {
+		MOD_REG_BIT(OMAP24XX_GPIO_LEVELDETECT0, gpio_bit,
+			trigger & IRQ_TYPE_LEVEL_LOW);
+		MOD_REG_BIT(OMAP24XX_GPIO_LEVELDETECT1, gpio_bit,
+			trigger & IRQ_TYPE_LEVEL_HIGH);
+		MOD_REG_BIT(OMAP24XX_GPIO_RISINGDETECT, gpio_bit,
+			trigger & IRQ_TYPE_EDGE_RISING);
+		MOD_REG_BIT(OMAP24XX_GPIO_FALLINGDETECT, gpio_bit,
+			trigger & IRQ_TYPE_EDGE_FALLING);
+	}
+	if (likely(!(bank->non_wakeup_gpios & gpio_bit))) {
+		if (cpu_is_omap44xx()) {
+			MOD_REG_BIT(OMAP4_GPIO_IRQWAKEN0, gpio_bit,
+				trigger != 0);
+		} else {
+			/*
+			 * GPIO wakeup request can only be generated on edge
+			 * transitions
+			 */
+			if (trigger & IRQ_TYPE_EDGE_BOTH)
+				__raw_writel(1 << gpio, bank->base
+					+ OMAP24XX_GPIO_SETWKUENA);
+			else
+				__raw_writel(1 << gpio, bank->base
+					+ OMAP24XX_GPIO_CLEARWKUENA);
+		}
+	}
+	/* This part needs to be executed always for OMAP{34xx, 44xx} */
+	if (cpu_is_omap34xx() || cpu_is_omap44xx() ||
+			(bank->non_wakeup_gpios & gpio_bit)) {
+		/*
+		 * Log the edge gpio and manually trigger the IRQ
+		 * after resume if the input level changes
+		 * to avoid irq lost during PER RET/OFF mode
+		 * Applies for omap2 non-wakeup gpio and all omap3 gpios
+		 */
+		if (trigger & IRQ_TYPE_EDGE_BOTH)
+			bank->enabled_non_wakeup_gpios |= gpio_bit;
+		else
+			bank->enabled_non_wakeup_gpios &= ~gpio_bit;
+	}
+
+	if (cpu_is_omap44xx()) {
+		bank->level_mask =
+			__raw_readl(bank->base + OMAP4_GPIO_LEVELDETECT0) |
+			__raw_readl(bank->base + OMAP4_GPIO_LEVELDETECT1);
+	} else {
+		bank->level_mask =
+			__raw_readl(bank->base + OMAP24XX_GPIO_LEVELDETECT0) |
+			__raw_readl(bank->base + OMAP24XX_GPIO_LEVELDETECT1);
+	}
+}
+#endif
+
+#ifdef CONFIG_ARCH_OMAP1
+/*
+ * This only applies to chips that can't do both rising and falling edge
+ * detection at once.  For all other chips, this function is a noop.
+ */
+static void _toggle_gpio_edge_triggering(struct gpio_bank *bank, int gpio)
+{
+	void __iomem *reg = bank->base;
+	u32 l = 0;
+
+	switch (bank->method) {
+	case METHOD_MPUIO:
+		reg += OMAP_MPUIO_GPIO_INT_EDGE / bank->stride;
+		break;
+#ifdef CONFIG_ARCH_OMAP15XX
+	case METHOD_GPIO_1510:
+		reg += OMAP1510_GPIO_INT_CONTROL;
+		break;
+#endif
+#if defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP850)
+	case METHOD_GPIO_7XX:
+		reg += OMAP7XX_GPIO_INT_CONTROL;
+		break;
+#endif
+	default:
+		return;
+	}
+
+	l = __raw_readl(reg);
+	if ((l >> gpio) & 1)
+		l &= ~(1 << gpio);
+	else
+		l |= 1 << gpio;
+
+	__raw_writel(l, reg);
+}
+#endif
+
+static int _set_gpio_triggering(struct gpio_bank *bank, int gpio, int trigger)
+{
+	void __iomem *reg = bank->base;
+	u32 l = 0;
+
+	switch (bank->method) {
+#ifdef CONFIG_ARCH_OMAP1
+	case METHOD_MPUIO:
+		reg += OMAP_MPUIO_GPIO_INT_EDGE / bank->stride;
+		l = __raw_readl(reg);
+		if ((trigger & IRQ_TYPE_SENSE_MASK) == IRQ_TYPE_EDGE_BOTH)
+			bank->toggle_mask |= 1 << gpio;
+		if (trigger & IRQ_TYPE_EDGE_RISING)
+			l |= 1 << gpio;
+		else if (trigger & IRQ_TYPE_EDGE_FALLING)
+			l &= ~(1 << gpio);
+		else
+			goto bad;
+		break;
+#endif
+#ifdef CONFIG_ARCH_OMAP15XX
+	case METHOD_GPIO_1510:
+		reg += OMAP1510_GPIO_INT_CONTROL;
+		l = __raw_readl(reg);
+		if ((trigger & IRQ_TYPE_SENSE_MASK) == IRQ_TYPE_EDGE_BOTH)
+			bank->toggle_mask |= 1 << gpio;
+		if (trigger & IRQ_TYPE_EDGE_RISING)
+			l |= 1 << gpio;
+		else if (trigger & IRQ_TYPE_EDGE_FALLING)
+			l &= ~(1 << gpio);
+		else
+			goto bad;
+		break;
+#endif
+#ifdef CONFIG_ARCH_OMAP16XX
+	case METHOD_GPIO_1610:
+		if (gpio & 0x08)
+			reg += OMAP1610_GPIO_EDGE_CTRL2;
+		else
+			reg += OMAP1610_GPIO_EDGE_CTRL1;
+		gpio &= 0x07;
+		l = __raw_readl(reg);
+		l &= ~(3 << (gpio << 1));
+		if (trigger & IRQ_TYPE_EDGE_RISING)
+			l |= 2 << (gpio << 1);
+		if (trigger & IRQ_TYPE_EDGE_FALLING)
+			l |= 1 << (gpio << 1);
+		if (trigger)
+			/* Enable wake-up during idle for dynamic tick */
+			__raw_writel(1 << gpio, bank->base + OMAP1610_GPIO_SET_WAKEUPENA);
+		else
+			__raw_writel(1 << gpio, bank->base + OMAP1610_GPIO_CLEAR_WAKEUPENA);
+		break;
+#endif
+#if defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP850)
+	case METHOD_GPIO_7XX:
+		reg += OMAP7XX_GPIO_INT_CONTROL;
+		l = __raw_readl(reg);
+		if ((trigger & IRQ_TYPE_SENSE_MASK) == IRQ_TYPE_EDGE_BOTH)
+			bank->toggle_mask |= 1 << gpio;
+		if (trigger & IRQ_TYPE_EDGE_RISING)
+			l |= 1 << gpio;
+		else if (trigger & IRQ_TYPE_EDGE_FALLING)
+			l &= ~(1 << gpio);
+		else
+			goto bad;
+		break;
+#endif
+#ifdef CONFIG_ARCH_OMAP2PLUS
+	case METHOD_GPIO_24XX:
+	case METHOD_GPIO_44XX:
+		set_24xx_gpio_triggering(bank, gpio, trigger);
+		return 0;
+#endif
+	default:
+		goto bad;
+	}
+	__raw_writel(l, reg);
+	return 0;
+bad:
+	return -EINVAL;
+}
+
+static int gpio_irq_type(struct irq_data *d, unsigned type)
+{
+	struct gpio_bank *bank;
+	unsigned gpio;
+	int retval;
+	unsigned long flags;
+
+	if (!cpu_class_is_omap2() && d->irq > IH_MPUIO_BASE)
+		gpio = OMAP_MPUIO(d->irq - IH_MPUIO_BASE);
+	else
+		gpio = d->irq - IH_GPIO_BASE;
+
+	if (check_gpio(gpio) < 0)
+		return -EINVAL;
+
+	if (type & ~IRQ_TYPE_SENSE_MASK)
+		return -EINVAL;
+
+	/* OMAP1 allows only only edge triggering */
+	if (!cpu_class_is_omap2()
+			&& (type & (IRQ_TYPE_LEVEL_LOW|IRQ_TYPE_LEVEL_HIGH)))
+		return -EINVAL;
+
+	bank = irq_data_get_irq_chip_data(d);
+	spin_lock_irqsave(&bank->lock, flags);
+	retval = _set_gpio_triggering(bank, get_gpio_index(gpio), type);
+	spin_unlock_irqrestore(&bank->lock, flags);
+
+	if (type & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_LEVEL_HIGH))
+		__irq_set_handler_locked(d->irq, handle_level_irq);
+	else if (type & (IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING))
+		__irq_set_handler_locked(d->irq, handle_edge_irq);
+
+	return retval;
+}
+
+static void _clear_gpio_irqbank(struct gpio_bank *bank, int gpio_mask)
+{
+	void __iomem *reg = bank->base;
+
+	switch (bank->method) {
+#ifdef CONFIG_ARCH_OMAP1
+	case METHOD_MPUIO:
+		/* MPUIO irqstatus is reset by reading the status register,
+		 * so do nothing here */
+		return;
+#endif
+#ifdef CONFIG_ARCH_OMAP15XX
+	case METHOD_GPIO_1510:
+		reg += OMAP1510_GPIO_INT_STATUS;
+		break;
+#endif
+#ifdef CONFIG_ARCH_OMAP16XX
+	case METHOD_GPIO_1610:
+		reg += OMAP1610_GPIO_IRQSTATUS1;
+		break;
+#endif
+#if defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP850)
+	case METHOD_GPIO_7XX:
+		reg += OMAP7XX_GPIO_INT_STATUS;
+		break;
+#endif
+#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_44XX:
+		reg += OMAP4_GPIO_IRQSTATUS0;
+		break;
+#endif
+	default:
+		WARN_ON(1);
+		return;
+	}
+	__raw_writel(gpio_mask, reg);
+
+	/* Workaround for clearing DSP GPIO interrupts to allow retention */
+	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);
+
+	/* Flush posted write for the irq status to avoid spurious interrupts */
+	__raw_readl(reg);
+	}
+}
+
+static inline void _clear_gpio_irqstatus(struct gpio_bank *bank, int gpio)
+{
+	_clear_gpio_irqbank(bank, 1 << get_gpio_index(gpio));
+}
+
+static u32 _get_gpio_irqbank_mask(struct gpio_bank *bank)
+{
+	void __iomem *reg = bank->base;
+	int inv = 0;
+	u32 l;
+	u32 mask;
+
+	switch (bank->method) {
+#ifdef CONFIG_ARCH_OMAP1
+	case METHOD_MPUIO:
+		reg += OMAP_MPUIO_GPIO_MASKIT / bank->stride;
+		mask = 0xffff;
+		inv = 1;
+		break;
+#endif
+#ifdef CONFIG_ARCH_OMAP15XX
+	case METHOD_GPIO_1510:
+		reg += OMAP1510_GPIO_INT_MASK;
+		mask = 0xffff;
+		inv = 1;
+		break;
+#endif
+#ifdef CONFIG_ARCH_OMAP16XX
+	case METHOD_GPIO_1610:
+		reg += OMAP1610_GPIO_IRQENABLE1;
+		mask = 0xffff;
+		break;
+#endif
+#if defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP850)
+	case METHOD_GPIO_7XX:
+		reg += OMAP7XX_GPIO_INT_MASK;
+		mask = 0xffffffff;
+		inv = 1;
+		break;
+#endif
+#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_44XX:
+		reg += OMAP4_GPIO_IRQSTATUSSET0;
+		mask = 0xffffffff;
+		break;
+#endif
+	default:
+		WARN_ON(1);
+		return 0;
+	}
+
+	l = __raw_readl(reg);
+	if (inv)
+		l = ~l;
+	l &= mask;
+	return l;
+}
+
+static void _enable_gpio_irqbank(struct gpio_bank *bank, int gpio_mask, int enable)
+{
+	void __iomem *reg = bank->base;
+	u32 l;
+
+	switch (bank->method) {
+#ifdef CONFIG_ARCH_OMAP1
+	case METHOD_MPUIO:
+		reg += OMAP_MPUIO_GPIO_MASKIT / bank->stride;
+		l = __raw_readl(reg);
+		if (enable)
+			l &= ~(gpio_mask);
+		else
+			l |= gpio_mask;
+		break;
+#endif
+#ifdef CONFIG_ARCH_OMAP15XX
+	case METHOD_GPIO_1510:
+		reg += OMAP1510_GPIO_INT_MASK;
+		l = __raw_readl(reg);
+		if (enable)
+			l &= ~(gpio_mask);
+		else
+			l |= gpio_mask;
+		break;
+#endif
+#ifdef CONFIG_ARCH_OMAP16XX
+	case METHOD_GPIO_1610:
+		if (enable)
+			reg += OMAP1610_GPIO_SET_IRQENABLE1;
+		else
+			reg += OMAP1610_GPIO_CLEAR_IRQENABLE1;
+		l = gpio_mask;
+		break;
+#endif
+#if defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP850)
+	case METHOD_GPIO_7XX:
+		reg += OMAP7XX_GPIO_INT_MASK;
+		l = __raw_readl(reg);
+		if (enable)
+			l &= ~(gpio_mask);
+		else
+			l |= gpio_mask;
+		break;
+#endif
+#if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3)
+	case METHOD_GPIO_24XX:
+		if (enable)
+			reg += OMAP24XX_GPIO_SETIRQENABLE1;
+		else
+			reg += OMAP24XX_GPIO_CLEARIRQENABLE1;
+		l = gpio_mask;
+		break;
+#endif
+#ifdef CONFIG_ARCH_OMAP4
+	case METHOD_GPIO_44XX:
+		if (enable)
+			reg += OMAP4_GPIO_IRQSTATUSSET0;
+		else
+			reg += OMAP4_GPIO_IRQSTATUSCLR0;
+		l = gpio_mask;
+		break;
+#endif
+	default:
+		WARN_ON(1);
+		return;
+	}
+	__raw_writel(l, reg);
+}
+
+static inline void _set_gpio_irqenable(struct gpio_bank *bank, int gpio, int enable)
+{
+	_enable_gpio_irqbank(bank, 1 << get_gpio_index(gpio), enable);
+}
+
+/*
+ * Note that ENAWAKEUP needs to be enabled in GPIO_SYSCONFIG register.
+ * 1510 does not seem to have a wake-up register. If JTAG is connected
+ * to the target, system will wake up always on GPIO events. While
+ * system is running all registered GPIO interrupts need to have wake-up
+ * enabled. When system is suspended, only selected GPIO interrupts need
+ * to have wake-up enabled.
+ */
+static int _set_gpio_wakeup(struct gpio_bank *bank, int gpio, int enable)
+{
+	unsigned long uninitialized_var(flags);
+
+	switch (bank->method) {
+#ifdef CONFIG_ARCH_OMAP16XX
+	case METHOD_MPUIO:
+	case METHOD_GPIO_1610:
+		spin_lock_irqsave(&bank->lock, flags);
+		if (enable)
+			bank->suspend_wakeup |= (1 << gpio);
+		else
+			bank->suspend_wakeup &= ~(1 << gpio);
+		spin_unlock_irqrestore(&bank->lock, flags);
+		return 0;
+#endif
+#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",
+					(bank - gpio_bank) * 32 + gpio);
+			return -EINVAL;
+		}
+		spin_lock_irqsave(&bank->lock, flags);
+		if (enable)
+			bank->suspend_wakeup |= (1 << gpio);
+		else
+			bank->suspend_wakeup &= ~(1 << gpio);
+		spin_unlock_irqrestore(&bank->lock, flags);
+		return 0;
+#endif
+	default:
+		printk(KERN_ERR "Can't enable GPIO wakeup for method %i\n",
+		       bank->method);
+		return -EINVAL;
+	}
+}
+
+static void _reset_gpio(struct gpio_bank *bank, int gpio)
+{
+	_set_gpio_direction(bank, get_gpio_index(gpio), 1);
+	_set_gpio_irqenable(bank, gpio, 0);
+	_clear_gpio_irqstatus(bank, gpio);
+	_set_gpio_triggering(bank, get_gpio_index(gpio), IRQ_TYPE_NONE);
+}
+
+/* Use disable_irq_wake() and enable_irq_wake() functions from drivers */
+static int gpio_wake_enable(struct irq_data *d, unsigned int enable)
+{
+	unsigned int gpio = d->irq - IH_GPIO_BASE;
+	struct gpio_bank *bank;
+	int retval;
+
+	if (check_gpio(gpio) < 0)
+		return -ENODEV;
+	bank = irq_data_get_irq_chip_data(d);
+	retval = _set_gpio_wakeup(bank, get_gpio_index(gpio), enable);
+
+	return retval;
+}
+
+static int omap_gpio_request(struct gpio_chip *chip, unsigned offset)
+{
+	struct gpio_bank *bank = container_of(chip, struct gpio_bank, chip);
+	unsigned long flags;
+
+	spin_lock_irqsave(&bank->lock, flags);
+
+	/* Set trigger to none. You need to enable the desired trigger with
+	 * request_irq() or set_irq_type().
+	 */
+	_set_gpio_triggering(bank, offset, IRQ_TYPE_NONE);
+
+#ifdef CONFIG_ARCH_OMAP15XX
+	if (bank->method == METHOD_GPIO_1510) {
+		void __iomem *reg;
+
+		/* Claim the pin for MPU */
+		reg = bank->base + OMAP1510_GPIO_PIN_CONTROL;
+		__raw_writel(__raw_readl(reg) | (1 << offset), reg);
+	}
+#endif
+	if (!cpu_class_is_omap1()) {
+		if (!bank->mod_usage) {
+			void __iomem *reg = bank->base;
+			u32 ctrl;
+
+			if (cpu_is_omap24xx() || cpu_is_omap34xx())
+				reg += OMAP24XX_GPIO_CTRL;
+			else if (cpu_is_omap44xx())
+				reg += OMAP4_GPIO_CTRL;
+			ctrl = __raw_readl(reg);
+			/* Module is enabled, clocks are not gated */
+			ctrl &= 0xFFFFFFFE;
+			__raw_writel(ctrl, reg);
+		}
+		bank->mod_usage |= 1 << offset;
+	}
+	spin_unlock_irqrestore(&bank->lock, flags);
+
+	return 0;
+}
+
+static void omap_gpio_free(struct gpio_chip *chip, unsigned offset)
+{
+	struct gpio_bank *bank = container_of(chip, struct gpio_bank, chip);
+	unsigned long flags;
+
+	spin_lock_irqsave(&bank->lock, flags);
+#ifdef CONFIG_ARCH_OMAP16XX
+	if (bank->method == METHOD_GPIO_1610) {
+		/* Disable wake-up during idle for dynamic tick */
+		void __iomem *reg = bank->base + OMAP1610_GPIO_CLEAR_WAKEUPENA;
+		__raw_writel(1 << offset, reg);
+	}
+#endif
+#if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3)
+	if (bank->method == METHOD_GPIO_24XX) {
+		/* Disable wake-up during idle for dynamic tick */
+		void __iomem *reg = bank->base + OMAP24XX_GPIO_CLEARWKUENA;
+		__raw_writel(1 << offset, reg);
+	}
+#endif
+#ifdef CONFIG_ARCH_OMAP4
+	if (bank->method == METHOD_GPIO_44XX) {
+		/* Disable wake-up during idle for dynamic tick */
+		void __iomem *reg = bank->base + OMAP4_GPIO_IRQWAKEN0;
+		__raw_writel(1 << offset, reg);
+	}
+#endif
+	if (!cpu_class_is_omap1()) {
+		bank->mod_usage &= ~(1 << offset);
+		if (!bank->mod_usage) {
+			void __iomem *reg = bank->base;
+			u32 ctrl;
+
+			if (cpu_is_omap24xx() || cpu_is_omap34xx())
+				reg += OMAP24XX_GPIO_CTRL;
+			else if (cpu_is_omap44xx())
+				reg += OMAP4_GPIO_CTRL;
+			ctrl = __raw_readl(reg);
+			/* Module is disabled, clocks are gated */
+			ctrl |= 1;
+			__raw_writel(ctrl, reg);
+		}
+	}
+	_reset_gpio(bank, bank->chip.base + offset);
+	spin_unlock_irqrestore(&bank->lock, flags);
+}
+
+/*
+ * We need to unmask the GPIO bank interrupt as soon as possible to
+ * avoid missing GPIO interrupts for other lines in the bank.
+ * Then we need to mask-read-clear-unmask the triggered GPIO lines
+ * in the bank to avoid missing nested interrupts for a GPIO line.
+ * If we wait to unmask individual GPIO lines in the bank after the
+ * line's interrupt handler has been run, we may miss some nested
+ * interrupts.
+ */
+static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
+{
+	void __iomem *isr_reg = NULL;
+	u32 isr;
+	unsigned int gpio_irq, gpio_index;
+	struct gpio_bank *bank;
+	u32 retrigger = 0;
+	int unmasked = 0;
+	struct irq_chip *chip = irq_desc_get_chip(desc);
+
+	chained_irq_enter(chip, desc);
+
+	bank = irq_get_handler_data(irq);
+#ifdef CONFIG_ARCH_OMAP1
+	if (bank->method == METHOD_MPUIO)
+		isr_reg = bank->base +
+				OMAP_MPUIO_GPIO_INT / bank->stride;
+#endif
+#ifdef CONFIG_ARCH_OMAP15XX
+	if (bank->method == METHOD_GPIO_1510)
+		isr_reg = bank->base + OMAP1510_GPIO_INT_STATUS;
+#endif
+#if defined(CONFIG_ARCH_OMAP16XX)
+	if (bank->method == METHOD_GPIO_1610)
+		isr_reg = bank->base + OMAP1610_GPIO_IRQSTATUS1;
+#endif
+#if defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP850)
+	if (bank->method == METHOD_GPIO_7XX)
+		isr_reg = bank->base + OMAP7XX_GPIO_INT_STATUS;
+#endif
+#if defined(CONFIG_ARCH_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_44XX)
+		isr_reg = bank->base + OMAP4_GPIO_IRQSTATUS0;
+#endif
+
+	if (WARN_ON(!isr_reg))
+		goto exit;
+
+	while(1) {
+		u32 isr_saved, level_mask = 0;
+		u32 enabled;
+
+		enabled = _get_gpio_irqbank_mask(bank);
+		isr_saved = isr = __raw_readl(isr_reg) & enabled;
+
+		if (cpu_is_omap15xx() && (bank->method == METHOD_MPUIO))
+			isr &= 0x0000ffff;
+
+		if (cpu_class_is_omap2()) {
+			level_mask = bank->level_mask & enabled;
+		}
+
+		/* clear edge sensitive interrupts before handler(s) are
+		called so that we don't miss any interrupt occurred while
+		executing them */
+		_enable_gpio_irqbank(bank, isr_saved & ~level_mask, 0);
+		_clear_gpio_irqbank(bank, isr_saved & ~level_mask);
+		_enable_gpio_irqbank(bank, isr_saved & ~level_mask, 1);
+
+		/* if there is only edge sensitive GPIO pin interrupts
+		configured, we could unmask GPIO bank interrupt immediately */
+		if (!level_mask && !unmasked) {
+			unmasked = 1;
+			chained_irq_exit(chip, desc);
+		}
+
+		isr |= retrigger;
+		retrigger = 0;
+		if (!isr)
+			break;
+
+		gpio_irq = bank->virtual_irq_start;
+		for (; isr != 0; isr >>= 1, gpio_irq++) {
+			gpio_index = get_gpio_index(irq_to_gpio(gpio_irq));
+
+			if (!(isr & 1))
+				continue;
+
+#ifdef CONFIG_ARCH_OMAP1
+			/*
+			 * Some chips can't respond to both rising and falling
+			 * at the same time.  If this irq was requested with
+			 * both flags, we need to flip the ICR data for the IRQ
+			 * to respond to the IRQ for the opposite direction.
+			 * This will be indicated in the bank toggle_mask.
+			 */
+			if (bank->toggle_mask & (1 << gpio_index))
+				_toggle_gpio_edge_triggering(bank, gpio_index);
+#endif
+
+			generic_handle_irq(gpio_irq);
+		}
+	}
+	/* if bank has any level sensitive GPIO pin interrupt
+	configured, we must unmask the bank interrupt only after
+	handler(s) are executed in order to avoid spurious bank
+	interrupt */
+exit:
+	if (!unmasked)
+		chained_irq_exit(chip, desc);
+}
+
+static void gpio_irq_shutdown(struct irq_data *d)
+{
+	unsigned int gpio = d->irq - IH_GPIO_BASE;
+	struct gpio_bank *bank = irq_data_get_irq_chip_data(d);
+	unsigned long flags;
+
+	spin_lock_irqsave(&bank->lock, flags);
+	_reset_gpio(bank, gpio);
+	spin_unlock_irqrestore(&bank->lock, flags);
+}
+
+static void gpio_ack_irq(struct irq_data *d)
+{
+	unsigned int gpio = d->irq - IH_GPIO_BASE;
+	struct gpio_bank *bank = irq_data_get_irq_chip_data(d);
+
+	_clear_gpio_irqstatus(bank, gpio);
+}
+
+static void gpio_mask_irq(struct irq_data *d)
+{
+	unsigned int gpio = d->irq - IH_GPIO_BASE;
+	struct gpio_bank *bank = irq_data_get_irq_chip_data(d);
+	unsigned long flags;
+
+	spin_lock_irqsave(&bank->lock, flags);
+	_set_gpio_irqenable(bank, gpio, 0);
+	_set_gpio_triggering(bank, get_gpio_index(gpio), IRQ_TYPE_NONE);
+	spin_unlock_irqrestore(&bank->lock, flags);
+}
+
+static void gpio_unmask_irq(struct irq_data *d)
+{
+	unsigned int gpio = d->irq - IH_GPIO_BASE;
+	struct gpio_bank *bank = irq_data_get_irq_chip_data(d);
+	unsigned int irq_mask = 1 << get_gpio_index(gpio);
+	u32 trigger = irqd_get_trigger_type(d);
+	unsigned long flags;
+
+	spin_lock_irqsave(&bank->lock, flags);
+	if (trigger)
+		_set_gpio_triggering(bank, get_gpio_index(gpio), trigger);
+
+	/* For level-triggered GPIOs, the clearing must be done after
+	 * the HW source is cleared, thus after the handler has run */
+	if (bank->level_mask & irq_mask) {
+		_set_gpio_irqenable(bank, gpio, 0);
+		_clear_gpio_irqstatus(bank, gpio);
+	}
+
+	_set_gpio_irqenable(bank, gpio, 1);
+	spin_unlock_irqrestore(&bank->lock, flags);
+}
+
+static struct irq_chip gpio_irq_chip = {
+	.name		= "GPIO",
+	.irq_shutdown	= gpio_irq_shutdown,
+	.irq_ack	= gpio_ack_irq,
+	.irq_mask	= gpio_mask_irq,
+	.irq_unmask	= gpio_unmask_irq,
+	.irq_set_type	= gpio_irq_type,
+	.irq_set_wake	= gpio_wake_enable,
+};
+
+/*---------------------------------------------------------------------*/
+
+#ifdef CONFIG_ARCH_OMAP1
+
+/* MPUIO uses the always-on 32k clock */
+
+static void mpuio_ack_irq(struct irq_data *d)
+{
+	/* The ISR is reset automatically, so do nothing here. */
+}
+
+static void mpuio_mask_irq(struct irq_data *d)
+{
+	unsigned int gpio = OMAP_MPUIO(d->irq - IH_MPUIO_BASE);
+	struct gpio_bank *bank = irq_data_get_irq_chip_data(d);
+
+	_set_gpio_irqenable(bank, gpio, 0);
+}
+
+static void mpuio_unmask_irq(struct irq_data *d)
+{
+	unsigned int gpio = OMAP_MPUIO(d->irq - IH_MPUIO_BASE);
+	struct gpio_bank *bank = irq_data_get_irq_chip_data(d);
+
+	_set_gpio_irqenable(bank, gpio, 1);
+}
+
+static struct irq_chip mpuio_irq_chip = {
+	.name		= "MPUIO",
+	.irq_ack	= mpuio_ack_irq,
+	.irq_mask	= mpuio_mask_irq,
+	.irq_unmask	= mpuio_unmask_irq,
+	.irq_set_type	= gpio_irq_type,
+#ifdef CONFIG_ARCH_OMAP16XX
+	/* REVISIT: assuming only 16xx supports MPUIO wake events */
+	.irq_set_wake	= gpio_wake_enable,
+#endif
+};
+
+
+#define bank_is_mpuio(bank)	((bank)->method == METHOD_MPUIO)
+
+
+#ifdef CONFIG_ARCH_OMAP16XX
+
+#include <linux/platform_device.h>
+
+static int omap_mpuio_suspend_noirq(struct device *dev)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct gpio_bank	*bank = platform_get_drvdata(pdev);
+	void __iomem		*mask_reg = bank->base +
+					OMAP_MPUIO_GPIO_MASKIT / bank->stride;
+	unsigned long		flags;
+
+	spin_lock_irqsave(&bank->lock, flags);
+	bank->saved_wakeup = __raw_readl(mask_reg);
+	__raw_writel(0xffff & ~bank->suspend_wakeup, mask_reg);
+	spin_unlock_irqrestore(&bank->lock, flags);
+
+	return 0;
+}
+
+static int omap_mpuio_resume_noirq(struct device *dev)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct gpio_bank	*bank = platform_get_drvdata(pdev);
+	void __iomem		*mask_reg = bank->base +
+					OMAP_MPUIO_GPIO_MASKIT / bank->stride;
+	unsigned long		flags;
+
+	spin_lock_irqsave(&bank->lock, flags);
+	__raw_writel(bank->saved_wakeup, mask_reg);
+	spin_unlock_irqrestore(&bank->lock, flags);
+
+	return 0;
+}
+
+static const struct dev_pm_ops omap_mpuio_dev_pm_ops = {
+	.suspend_noirq = omap_mpuio_suspend_noirq,
+	.resume_noirq = omap_mpuio_resume_noirq,
+};
+
+/* use platform_driver for this. */
+static struct platform_driver omap_mpuio_driver = {
+	.driver		= {
+		.name	= "mpuio",
+		.pm	= &omap_mpuio_dev_pm_ops,
+	},
+};
+
+static struct platform_device omap_mpuio_device = {
+	.name		= "mpuio",
+	.id		= -1,
+	.dev = {
+		.driver = &omap_mpuio_driver.driver,
+	}
+	/* could list the /proc/iomem resources */
+};
+
+static inline void mpuio_init(void)
+{
+	struct gpio_bank *bank = get_gpio_bank(OMAP_MPUIO(0));
+	platform_set_drvdata(&omap_mpuio_device, bank);
+
+	if (platform_driver_register(&omap_mpuio_driver) == 0)
+		(void) platform_device_register(&omap_mpuio_device);
+}
+
+#else
+static inline void mpuio_init(void) {}
+#endif	/* 16xx */
+
+#else
+
+extern struct irq_chip mpuio_irq_chip;
+
+#define bank_is_mpuio(bank)	0
+static inline void mpuio_init(void) {}
+
+#endif
+
+/*---------------------------------------------------------------------*/
+
+/* REVISIT these are stupid implementations!  replace by ones that
+ * don't switch on METHOD_* and which mostly avoid spinlocks
+ */
+
+static int gpio_input(struct gpio_chip *chip, unsigned offset)
+{
+	struct gpio_bank *bank;
+	unsigned long flags;
+
+	bank = container_of(chip, struct gpio_bank, chip);
+	spin_lock_irqsave(&bank->lock, flags);
+	_set_gpio_direction(bank, offset, 1);
+	spin_unlock_irqrestore(&bank->lock, flags);
+	return 0;
+}
+
+static int gpio_is_input(struct gpio_bank *bank, int mask)
+{
+	void __iomem *reg = bank->base;
+
+	switch (bank->method) {
+	case METHOD_MPUIO:
+		reg += OMAP_MPUIO_IO_CNTL / bank->stride;
+		break;
+	case METHOD_GPIO_1510:
+		reg += OMAP1510_GPIO_DIR_CONTROL;
+		break;
+	case METHOD_GPIO_1610:
+		reg += OMAP1610_GPIO_DIRECTION;
+		break;
+	case METHOD_GPIO_7XX:
+		reg += OMAP7XX_GPIO_DIR_CONTROL;
+		break;
+	case METHOD_GPIO_24XX:
+		reg += OMAP24XX_GPIO_OE;
+		break;
+	case METHOD_GPIO_44XX:
+		reg += OMAP4_GPIO_OE;
+		break;
+	default:
+		WARN_ONCE(1, "gpio_is_input: incorrect OMAP GPIO method");
+		return -EINVAL;
+	}
+	return __raw_readl(reg) & mask;
+}
+
+static int gpio_get(struct gpio_chip *chip, unsigned offset)
+{
+	struct gpio_bank *bank;
+	void __iomem *reg;
+	int gpio;
+	u32 mask;
+
+	gpio = chip->base + offset;
+	bank = get_gpio_bank(gpio);
+	reg = bank->base;
+	mask = 1 << get_gpio_index(gpio);
+
+	if (gpio_is_input(bank, mask))
+		return _get_gpio_datain(bank, gpio);
+	else
+		return _get_gpio_dataout(bank, gpio);
+}
+
+static int gpio_output(struct gpio_chip *chip, unsigned offset, int value)
+{
+	struct gpio_bank *bank;
+	unsigned long flags;
+
+	bank = container_of(chip, struct gpio_bank, chip);
+	spin_lock_irqsave(&bank->lock, flags);
+	_set_gpio_dataout(bank, offset, value);
+	_set_gpio_direction(bank, offset, 0);
+	spin_unlock_irqrestore(&bank->lock, flags);
+	return 0;
+}
+
+static int gpio_debounce(struct gpio_chip *chip, unsigned offset,
+		unsigned debounce)
+{
+	struct gpio_bank *bank;
+	unsigned long flags;
+
+	bank = container_of(chip, struct gpio_bank, chip);
+
+	if (!bank->dbck) {
+		bank->dbck = clk_get(bank->dev, "dbclk");
+		if (IS_ERR(bank->dbck))
+			dev_err(bank->dev, "Could not get gpio dbck\n");
+	}
+
+	spin_lock_irqsave(&bank->lock, flags);
+	_set_gpio_debounce(bank, offset, debounce);
+	spin_unlock_irqrestore(&bank->lock, flags);
+
+	return 0;
+}
+
+static void gpio_set(struct gpio_chip *chip, unsigned offset, int value)
+{
+	struct gpio_bank *bank;
+	unsigned long flags;
+
+	bank = container_of(chip, struct gpio_bank, chip);
+	spin_lock_irqsave(&bank->lock, flags);
+	_set_gpio_dataout(bank, offset, value);
+	spin_unlock_irqrestore(&bank->lock, flags);
+}
+
+static int gpio_2irq(struct gpio_chip *chip, unsigned offset)
+{
+	struct gpio_bank *bank;
+
+	bank = container_of(chip, struct gpio_bank, chip);
+	return bank->virtual_irq_start + offset;
+}
+
+/*---------------------------------------------------------------------*/
+
+static void __init omap_gpio_show_rev(struct gpio_bank *bank)
+{
+	u32 rev;
+
+	if (cpu_is_omap16xx() && !(bank->method != METHOD_MPUIO))
+		rev = __raw_readw(bank->base + OMAP1610_GPIO_REVISION);
+	else if (cpu_is_omap24xx() || cpu_is_omap34xx())
+		rev = __raw_readl(bank->base + OMAP24XX_GPIO_REVISION);
+	else if (cpu_is_omap44xx())
+		rev = __raw_readl(bank->base + OMAP4_GPIO_REVISION);
+	else
+		return;
+
+	printk(KERN_INFO "OMAP GPIO hardware version %d.%d\n",
+		(rev >> 4) & 0x0f, rev & 0x0f);
+}
+
+/* This lock class tells lockdep that GPIO irqs are in a different
+ * category than their parents, so it won't report false recursion.
+ */
+static struct lock_class_key gpio_lock_class;
+
+static inline int init_gpio_info(struct platform_device *pdev)
+{
+	/* TODO: Analyze removing gpio_bank_count usage from driver code */
+	gpio_bank = kzalloc(gpio_bank_count * sizeof(struct gpio_bank),
+				GFP_KERNEL);
+	if (!gpio_bank) {
+		dev_err(&pdev->dev, "Memory alloc failed for gpio_bank\n");
+		return -ENOMEM;
+	}
+	return 0;
+}
+
+/* TODO: Cleanup cpu_is_* checks */
+static void omap_gpio_mod_init(struct gpio_bank *bank, int id)
+{
+	if (cpu_class_is_omap2()) {
+		if (cpu_is_omap44xx()) {
+			__raw_writel(0xffffffff, bank->base +
+					OMAP4_GPIO_IRQSTATUSCLR0);
+			__raw_writel(0x00000000, bank->base +
+					 OMAP4_GPIO_DEBOUNCENABLE);
+			/* Initialize interface clk ungated, module enabled */
+			__raw_writel(0, bank->base + OMAP4_GPIO_CTRL);
+		} else if (cpu_is_omap34xx()) {
+			__raw_writel(0x00000000, bank->base +
+					OMAP24XX_GPIO_IRQENABLE1);
+			__raw_writel(0xffffffff, bank->base +
+					OMAP24XX_GPIO_IRQSTATUS1);
+			__raw_writel(0x00000000, bank->base +
+					OMAP24XX_GPIO_DEBOUNCE_EN);
+
+			/* Initialize interface clk ungated, module enabled */
+			__raw_writel(0, bank->base + OMAP24XX_GPIO_CTRL);
+		} else if (cpu_is_omap24xx()) {
+			static const u32 non_wakeup_gpios[] = {
+				0xe203ffc0, 0x08700040
+			};
+			if (id < ARRAY_SIZE(non_wakeup_gpios))
+				bank->non_wakeup_gpios = non_wakeup_gpios[id];
+		}
+	} else if (cpu_class_is_omap1()) {
+		if (bank_is_mpuio(bank))
+			__raw_writew(0xffff, bank->base +
+				OMAP_MPUIO_GPIO_MASKIT / bank->stride);
+		if (cpu_is_omap15xx() && bank->method == METHOD_GPIO_1510) {
+			__raw_writew(0xffff, bank->base
+						+ OMAP1510_GPIO_INT_MASK);
+			__raw_writew(0x0000, bank->base
+						+ OMAP1510_GPIO_INT_STATUS);
+		}
+		if (cpu_is_omap16xx() && bank->method == METHOD_GPIO_1610) {
+			__raw_writew(0x0000, bank->base
+						+ OMAP1610_GPIO_IRQENABLE1);
+			__raw_writew(0xffff, bank->base
+						+ OMAP1610_GPIO_IRQSTATUS1);
+			__raw_writew(0x0014, bank->base
+						+ OMAP1610_GPIO_SYSCONFIG);
+
+			/*
+			 * Enable system clock for GPIO module.
+			 * The CAM_CLK_CTRL *is* really the right place.
+			 */
+			omap_writel(omap_readl(ULPD_CAM_CLK_CTRL) | 0x04,
+						ULPD_CAM_CLK_CTRL);
+		}
+		if (cpu_is_omap7xx() && bank->method == METHOD_GPIO_7XX) {
+			__raw_writel(0xffffffff, bank->base
+						+ OMAP7XX_GPIO_INT_MASK);
+			__raw_writel(0x00000000, bank->base
+						+ OMAP7XX_GPIO_INT_STATUS);
+		}
+	}
+}
+
+static void __devinit omap_gpio_chip_init(struct gpio_bank *bank)
+{
+	int j;
+	static int gpio;
+
+	bank->mod_usage = 0;
+	/*
+	 * REVISIT eventually switch from OMAP-specific gpio structs
+	 * over to the generic ones
+	 */
+	bank->chip.request = omap_gpio_request;
+	bank->chip.free = omap_gpio_free;
+	bank->chip.direction_input = gpio_input;
+	bank->chip.get = gpio_get;
+	bank->chip.direction_output = gpio_output;
+	bank->chip.set_debounce = gpio_debounce;
+	bank->chip.set = gpio_set;
+	bank->chip.to_irq = gpio_2irq;
+	if (bank_is_mpuio(bank)) {
+		bank->chip.label = "mpuio";
+#ifdef CONFIG_ARCH_OMAP16XX
+		bank->chip.dev = &omap_mpuio_device.dev;
+#endif
+		bank->chip.base = OMAP_MPUIO(0);
+	} else {
+		bank->chip.label = "gpio";
+		bank->chip.base = gpio;
+		gpio += bank_width;
+	}
+	bank->chip.ngpio = bank_width;
+
+	gpiochip_add(&bank->chip);
+
+	for (j = bank->virtual_irq_start;
+		     j < bank->virtual_irq_start + bank_width; j++) {
+		irq_set_lockdep_class(j, &gpio_lock_class);
+		irq_set_chip_data(j, bank);
+		if (bank_is_mpuio(bank))
+			irq_set_chip(j, &mpuio_irq_chip);
+		else
+			irq_set_chip(j, &gpio_irq_chip);
+		irq_set_handler(j, handle_simple_irq);
+		set_irq_flags(j, IRQF_VALID);
+	}
+	irq_set_chained_handler(bank->irq, gpio_irq_handler);
+	irq_set_handler_data(bank->irq, bank);
+}
+
+static int __devinit omap_gpio_probe(struct platform_device *pdev)
+{
+	static int gpio_init_done;
+	struct omap_gpio_platform_data *pdata;
+	struct resource *res;
+	int id;
+	struct gpio_bank *bank;
+
+	if (!pdev->dev.platform_data)
+		return -EINVAL;
+
+	pdata = pdev->dev.platform_data;
+
+	if (!gpio_init_done) {
+		int ret;
+
+		ret = init_gpio_info(pdev);
+		if (ret)
+			return ret;
+	}
+
+	id = pdev->id;
+	bank = &gpio_bank[id];
+
+	res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+	if (unlikely(!res)) {
+		dev_err(&pdev->dev, "GPIO Bank %i Invalid IRQ resource\n", id);
+		return -ENODEV;
+	}
+
+	bank->irq = res->start;
+	bank->virtual_irq_start = pdata->virtual_irq_start;
+	bank->method = pdata->bank_type;
+	bank->dev = &pdev->dev;
+	bank->dbck_flag = pdata->dbck_flag;
+	bank->stride = pdata->bank_stride;
+	bank_width = pdata->bank_width;
+
+	spin_lock_init(&bank->lock);
+
+	/* Static mapping, never released */
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (unlikely(!res)) {
+		dev_err(&pdev->dev, "GPIO Bank %i Invalid mem resource\n", id);
+		return -ENODEV;
+	}
+
+	bank->base = ioremap(res->start, resource_size(res));
+	if (!bank->base) {
+		dev_err(&pdev->dev, "Could not ioremap gpio bank%i\n", id);
+		return -ENOMEM;
+	}
+
+	pm_runtime_enable(bank->dev);
+	pm_runtime_get_sync(bank->dev);
+
+	omap_gpio_mod_init(bank, id);
+	omap_gpio_chip_init(bank);
+	omap_gpio_show_rev(bank);
+
+	if (!gpio_init_done)
+		gpio_init_done = 1;
+
+	return 0;
+}
+
+#if defined(CONFIG_ARCH_OMAP16XX) || defined(CONFIG_ARCH_OMAP2PLUS)
+static int omap_gpio_suspend(void)
+{
+	int i;
+
+	if (!cpu_class_is_omap2() && !cpu_is_omap16xx())
+		return 0;
+
+	for (i = 0; i < gpio_bank_count; i++) {
+		struct gpio_bank *bank = &gpio_bank[i];
+		void __iomem *wake_status;
+		void __iomem *wake_clear;
+		void __iomem *wake_set;
+		unsigned long flags;
+
+		switch (bank->method) {
+#ifdef CONFIG_ARCH_OMAP16XX
+		case METHOD_GPIO_1610:
+			wake_status = bank->base + OMAP1610_GPIO_WAKEUPENABLE;
+			wake_clear = bank->base + OMAP1610_GPIO_CLEAR_WAKEUPENA;
+			wake_set = bank->base + OMAP1610_GPIO_SET_WAKEUPENA;
+			break;
+#endif
+#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;
+			wake_set = bank->base + OMAP24XX_GPIO_SETWKUENA;
+			break;
+#endif
+#ifdef CONFIG_ARCH_OMAP4
+		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;
+			break;
+#endif
+		default:
+			continue;
+		}
+
+		spin_lock_irqsave(&bank->lock, flags);
+		bank->saved_wakeup = __raw_readl(wake_status);
+		__raw_writel(0xffffffff, wake_clear);
+		__raw_writel(bank->suspend_wakeup, wake_set);
+		spin_unlock_irqrestore(&bank->lock, flags);
+	}
+
+	return 0;
+}
+
+static void omap_gpio_resume(void)
+{
+	int i;
+
+	if (!cpu_class_is_omap2() && !cpu_is_omap16xx())
+		return;
+
+	for (i = 0; i < gpio_bank_count; i++) {
+		struct gpio_bank *bank = &gpio_bank[i];
+		void __iomem *wake_clear;
+		void __iomem *wake_set;
+		unsigned long flags;
+
+		switch (bank->method) {
+#ifdef CONFIG_ARCH_OMAP16XX
+		case METHOD_GPIO_1610:
+			wake_clear = bank->base + OMAP1610_GPIO_CLEAR_WAKEUPENA;
+			wake_set = bank->base + OMAP1610_GPIO_SET_WAKEUPENA;
+			break;
+#endif
+#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_44XX:
+			wake_clear = bank->base + OMAP4_GPIO_IRQWAKEN0;
+			wake_set = bank->base + OMAP4_GPIO_IRQWAKEN0;
+			break;
+#endif
+		default:
+			continue;
+		}
+
+		spin_lock_irqsave(&bank->lock, flags);
+		__raw_writel(0xffffffff, wake_clear);
+		__raw_writel(bank->saved_wakeup, wake_set);
+		spin_unlock_irqrestore(&bank->lock, flags);
+	}
+}
+
+static struct syscore_ops omap_gpio_syscore_ops = {
+	.suspend	= omap_gpio_suspend,
+	.resume		= omap_gpio_resume,
+};
+
+#endif
+
+#ifdef CONFIG_ARCH_OMAP2PLUS
+
+static int workaround_enabled;
+
+void omap2_gpio_prepare_for_idle(int off_mode)
+{
+	int i, c = 0;
+	int min = 0;
+
+	if (cpu_is_omap34xx())
+		min = 1;
+
+	for (i = min; i < gpio_bank_count; i++) {
+		struct gpio_bank *bank = &gpio_bank[i];
+		u32 l1 = 0, l2 = 0;
+		int j;
+
+		for (j = 0; j < hweight_long(bank->dbck_enable_mask); j++)
+			clk_disable(bank->dbck);
+
+		if (!off_mode)
+			continue;
+
+		/* If going to OFF, remove triggering for all
+		 * non-wakeup GPIOs.  Otherwise spurious IRQs will be
+		 * generated.  See OMAP2420 Errata item 1.101. */
+		if (!(bank->enabled_non_wakeup_gpios))
+			continue;
+
+		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 (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) {
+		workaround_enabled = 0;
+		return;
+	}
+	workaround_enabled = 1;
+}
+
+void omap2_gpio_resume_after_idle(void)
+{
+	int i;
+	int min = 0;
+
+	if (cpu_is_omap34xx())
+		min = 1;
+	for (i = min; i < gpio_bank_count; i++) {
+		struct gpio_bank *bank = &gpio_bank[i];
+		u32 l = 0, gen, gen0, gen1;
+		int j;
+
+		for (j = 0; j < hweight_long(bank->dbck_enable_mask); j++)
+			clk_enable(bank->dbck);
+
+		if (!workaround_enabled)
+			continue;
+
+		if (!(bank->enabled_non_wakeup_gpios))
+			continue;
+
+		if (cpu_is_omap24xx() || cpu_is_omap34xx()) {
+			__raw_writel(bank->saved_fallingdetect,
+				 bank->base + OMAP24XX_GPIO_FALLINGDETECT);
+			__raw_writel(bank->saved_risingdetect,
+				 bank->base + OMAP24XX_GPIO_RISINGDETECT);
+			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,
+				 bank->base + OMAP4_GPIO_RISINGDETECT);
+			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
+		 * this silicon bug. */
+		l ^= bank->saved_datain;
+		l &= bank->enabled_non_wakeup_gpios;
+
+		/*
+		 * No need to generate IRQs for the rising edge for gpio IRQs
+		 * configured with falling edge only; and vice versa.
+		 */
+		gen0 = l & bank->saved_fallingdetect;
+		gen0 &= bank->saved_datain;
+
+		gen1 = l & bank->saved_risingdetect;
+		gen1 &= ~(bank->saved_datain);
+
+		/* FIXME: Consider GPIO IRQs with level detections properly! */
+		gen = l & (~(bank->saved_fallingdetect) &
+				~(bank->saved_risingdetect));
+		/* Consider all GPIO IRQs needed to be updated */
+		gen |= gen0 | gen1;
+
+		if (gen) {
+			u32 old0, old1;
+
+			if (cpu_is_omap24xx() || cpu_is_omap34xx()) {
+				old0 = __raw_readl(bank->base +
+					OMAP24XX_GPIO_LEVELDETECT0);
+				old1 = __raw_readl(bank->base +
+					OMAP24XX_GPIO_LEVELDETECT1);
+				__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 +
+						OMAP4_GPIO_LEVELDETECT1);
+				__raw_writel(old0 | l, bank->base +
+						OMAP4_GPIO_LEVELDETECT0);
+				__raw_writel(old1 | l, bank->base +
+						OMAP4_GPIO_LEVELDETECT1);
+				__raw_writel(old0, bank->base +
+						OMAP4_GPIO_LEVELDETECT0);
+				__raw_writel(old1, bank->base +
+						OMAP4_GPIO_LEVELDETECT1);
+			}
+		}
+	}
+
+}
+
+#endif
+
+#ifdef CONFIG_ARCH_OMAP3
+/* save the registers of bank 2-6 */
+void omap_gpio_save_context(void)
+{
+	int i;
+
+	/* saving banks from 2-6 only since GPIO1 is in WKUP */
+	for (i = 1; i < gpio_bank_count; i++) {
+		struct gpio_bank *bank = &gpio_bank[i];
+		gpio_context[i].irqenable1 =
+			__raw_readl(bank->base + OMAP24XX_GPIO_IRQENABLE1);
+		gpio_context[i].irqenable2 =
+			__raw_readl(bank->base + OMAP24XX_GPIO_IRQENABLE2);
+		gpio_context[i].wake_en =
+			__raw_readl(bank->base + OMAP24XX_GPIO_WAKE_EN);
+		gpio_context[i].ctrl =
+			__raw_readl(bank->base + OMAP24XX_GPIO_CTRL);
+		gpio_context[i].oe =
+			__raw_readl(bank->base + OMAP24XX_GPIO_OE);
+		gpio_context[i].leveldetect0 =
+			__raw_readl(bank->base + OMAP24XX_GPIO_LEVELDETECT0);
+		gpio_context[i].leveldetect1 =
+			__raw_readl(bank->base + OMAP24XX_GPIO_LEVELDETECT1);
+		gpio_context[i].risingdetect =
+			__raw_readl(bank->base + OMAP24XX_GPIO_RISINGDETECT);
+		gpio_context[i].fallingdetect =
+			__raw_readl(bank->base + OMAP24XX_GPIO_FALLINGDETECT);
+		gpio_context[i].dataout =
+			__raw_readl(bank->base + OMAP24XX_GPIO_DATAOUT);
+	}
+}
+
+/* restore the required registers of bank 2-6 */
+void omap_gpio_restore_context(void)
+{
+	int i;
+
+	for (i = 1; i < gpio_bank_count; i++) {
+		struct gpio_bank *bank = &gpio_bank[i];
+		__raw_writel(gpio_context[i].irqenable1,
+				bank->base + OMAP24XX_GPIO_IRQENABLE1);
+		__raw_writel(gpio_context[i].irqenable2,
+				bank->base + OMAP24XX_GPIO_IRQENABLE2);
+		__raw_writel(gpio_context[i].wake_en,
+				bank->base + OMAP24XX_GPIO_WAKE_EN);
+		__raw_writel(gpio_context[i].ctrl,
+				bank->base + OMAP24XX_GPIO_CTRL);
+		__raw_writel(gpio_context[i].oe,
+				bank->base + OMAP24XX_GPIO_OE);
+		__raw_writel(gpio_context[i].leveldetect0,
+				bank->base + OMAP24XX_GPIO_LEVELDETECT0);
+		__raw_writel(gpio_context[i].leveldetect1,
+				bank->base + OMAP24XX_GPIO_LEVELDETECT1);
+		__raw_writel(gpio_context[i].risingdetect,
+				bank->base + OMAP24XX_GPIO_RISINGDETECT);
+		__raw_writel(gpio_context[i].fallingdetect,
+				bank->base + OMAP24XX_GPIO_FALLINGDETECT);
+		__raw_writel(gpio_context[i].dataout,
+				bank->base + OMAP24XX_GPIO_DATAOUT);
+	}
+}
+#endif
+
+static struct platform_driver omap_gpio_driver = {
+	.probe		= omap_gpio_probe,
+	.driver		= {
+		.name	= "omap_gpio",
+	},
+};
+
+/*
+ * gpio driver register needs to be done before
+ * machine_init functions access gpio APIs.
+ * Hence omap_gpio_drv_reg() is a postcore_initcall.
+ */
+static int __init omap_gpio_drv_reg(void)
+{
+	return platform_driver_register(&omap_gpio_driver);
+}
+postcore_initcall(omap_gpio_drv_reg);
+
+static int __init omap_gpio_sysinit(void)
+{
+	mpuio_init();
+
+#if defined(CONFIG_ARCH_OMAP16XX) || defined(CONFIG_ARCH_OMAP2PLUS)
+	if (cpu_is_omap16xx() || cpu_class_is_omap2())
+		register_syscore_ops(&omap_gpio_syscore_ops);
+#endif
+
+	return 0;
+}
+
+arch_initcall(omap_gpio_sysinit);
diff -druN linux-2.6.39-libre/drivers/gpio/gpio-plat-samsung.c linux-3.0-rc7-libre/drivers/gpio/gpio-plat-samsung.c
--- linux-2.6.39-libre/drivers/gpio/gpio-plat-samsung.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/gpio/gpio-plat-samsung.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,206 @@
+/* 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 <linux/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);
+	}
+}
+
+void __init samsung_gpiolib_add_2bit_chips(struct s3c_gpio_chip *chip,
+					   int nr_chips)
+{
+	for (; nr_chips > 0; nr_chips--, chip++)
+		s3c_gpiolib_add(chip);
+}
diff -druN linux-2.6.39-libre/drivers/gpio/gpio-s5pc100.c linux-3.0-rc7-libre/drivers/gpio/gpio-s5pc100.c
--- linux-2.6.39-libre/drivers/gpio/gpio-s5pc100.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/gpio/gpio-s5pc100.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,355 @@
+/* linux/arch/arm/mach-s5pc100/gpiolib.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ *		http://www.samsung.com
+ *
+ *  Copyright 2009 Samsung Electronics Co
+ *  Kyungmin Park <kyungmin.park@samsung.com>
+ *
+ * S5PC100 - GPIOlib support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+#include <linux/gpio.h>
+
+#include <mach/map.h>
+#include <mach/regs-gpio.h>
+
+#include <plat/gpio-core.h>
+#include <plat/gpio-cfg.h>
+#include <plat/gpio-cfg-helpers.h>
+
+/* S5PC100 GPIO bank summary:
+ *
+ * Bank	GPIOs	Style	INT Type
+ * A0	8	4Bit	GPIO_INT0
+ * A1	5	4Bit	GPIO_INT1
+ * B	8	4Bit	GPIO_INT2
+ * C	5	4Bit	GPIO_INT3
+ * D	7	4Bit	GPIO_INT4
+ * E0	8	4Bit	GPIO_INT5
+ * E1	6	4Bit	GPIO_INT6
+ * F0	8	4Bit	GPIO_INT7
+ * F1	8	4Bit	GPIO_INT8
+ * F2	8	4Bit	GPIO_INT9
+ * F3	4	4Bit	GPIO_INT10
+ * G0	8	4Bit	GPIO_INT11
+ * G1	3	4Bit	GPIO_INT12
+ * G2	7	4Bit	GPIO_INT13
+ * G3	7	4Bit	GPIO_INT14
+ * H0	8	4Bit	WKUP_INT
+ * H1	8	4Bit	WKUP_INT
+ * H2	8	4Bit	WKUP_INT
+ * H3	8	4Bit	WKUP_INT
+ * I	8	4Bit	GPIO_INT15
+ * J0	8	4Bit	GPIO_INT16
+ * J1	5	4Bit	GPIO_INT17
+ * J2	8	4Bit	GPIO_INT18
+ * J3	8	4Bit	GPIO_INT19
+ * J4	4	4Bit	GPIO_INT20
+ * K0	8	4Bit	None
+ * K1	6	4Bit	None
+ * K2	8	4Bit	None
+ * K3	8	4Bit	None
+ * L0	8	4Bit	None
+ * L1	8	4Bit	None
+ * L2	8	4Bit	None
+ * L3	8	4Bit	None
+ */
+
+static struct s3c_gpio_cfg gpio_cfg = {
+	.set_config	= s3c_gpio_setcfg_s3c64xx_4bit,
+	.set_pull	= s3c_gpio_setpull_updown,
+	.get_pull	= s3c_gpio_getpull_updown,
+};
+
+static struct s3c_gpio_cfg gpio_cfg_eint = {
+	.cfg_eint	= 0xf,
+	.set_config	= s3c_gpio_setcfg_s3c64xx_4bit,
+	.set_pull	= s3c_gpio_setpull_updown,
+	.get_pull	= s3c_gpio_getpull_updown,
+};
+
+static struct s3c_gpio_cfg gpio_cfg_noint = {
+	.set_config	= s3c_gpio_setcfg_s3c64xx_4bit,
+	.set_pull	= s3c_gpio_setpull_updown,
+	.get_pull	= s3c_gpio_getpull_updown,
+};
+
+/*
+ * GPIO bank's base address given the index of the bank in the
+ * list of all gpio banks.
+ */
+#define S5PC100_BANK_BASE(bank_nr)	(S5P_VA_GPIO + ((bank_nr) * 0x20))
+
+/*
+ * Following are the gpio banks in S5PC100.
+ *
+ * The 'config' member when left to NULL, is initialized to the default
+ * structure gpio_cfg in the init function below.
+ *
+ * The 'base' member is also initialized in the init function below.
+ * Note: The initialization of 'base' member of s3c_gpio_chip structure
+ * uses the above macro and depends on the banks being listed in order here.
+ */
+static struct s3c_gpio_chip s5pc100_gpio_chips[] = {
+	{
+		.chip	= {
+			.base	= S5PC100_GPA0(0),
+			.ngpio	= S5PC100_GPIO_A0_NR,
+			.label	= "GPA0",
+		},
+	}, {
+		.chip	= {
+			.base	= S5PC100_GPA1(0),
+			.ngpio	= S5PC100_GPIO_A1_NR,
+			.label	= "GPA1",
+		},
+	}, {
+		.chip	= {
+			.base	= S5PC100_GPB(0),
+			.ngpio	= S5PC100_GPIO_B_NR,
+			.label	= "GPB",
+		},
+	}, {
+		.chip	= {
+			.base	= S5PC100_GPC(0),
+			.ngpio	= S5PC100_GPIO_C_NR,
+			.label	= "GPC",
+		},
+	}, {
+		.chip	= {
+			.base	= S5PC100_GPD(0),
+			.ngpio	= S5PC100_GPIO_D_NR,
+			.label	= "GPD",
+		},
+	}, {
+		.chip	= {
+			.base	= S5PC100_GPE0(0),
+			.ngpio	= S5PC100_GPIO_E0_NR,
+			.label	= "GPE0",
+		},
+	}, {
+		.chip	= {
+			.base	= S5PC100_GPE1(0),
+			.ngpio	= S5PC100_GPIO_E1_NR,
+			.label	= "GPE1",
+		},
+	}, {
+		.chip	= {
+			.base	= S5PC100_GPF0(0),
+			.ngpio	= S5PC100_GPIO_F0_NR,
+			.label	= "GPF0",
+		},
+	}, {
+		.chip	= {
+			.base	= S5PC100_GPF1(0),
+			.ngpio	= S5PC100_GPIO_F1_NR,
+			.label	= "GPF1",
+		},
+	}, {
+		.chip	= {
+			.base	= S5PC100_GPF2(0),
+			.ngpio	= S5PC100_GPIO_F2_NR,
+			.label	= "GPF2",
+		},
+	}, {
+		.chip	= {
+			.base	= S5PC100_GPF3(0),
+			.ngpio	= S5PC100_GPIO_F3_NR,
+			.label	= "GPF3",
+		},
+	}, {
+		.chip	= {
+			.base	= S5PC100_GPG0(0),
+			.ngpio	= S5PC100_GPIO_G0_NR,
+			.label	= "GPG0",
+		},
+	}, {
+		.chip	= {
+			.base	= S5PC100_GPG1(0),
+			.ngpio	= S5PC100_GPIO_G1_NR,
+			.label	= "GPG1",
+		},
+	}, {
+		.chip	= {
+			.base	= S5PC100_GPG2(0),
+			.ngpio	= S5PC100_GPIO_G2_NR,
+			.label	= "GPG2",
+		},
+	}, {
+		.chip	= {
+			.base	= S5PC100_GPG3(0),
+			.ngpio	= S5PC100_GPIO_G3_NR,
+			.label	= "GPG3",
+		},
+	}, {
+		.chip	= {
+			.base	= S5PC100_GPI(0),
+			.ngpio	= S5PC100_GPIO_I_NR,
+			.label	= "GPI",
+		},
+	}, {
+		.chip	= {
+			.base	= S5PC100_GPJ0(0),
+			.ngpio	= S5PC100_GPIO_J0_NR,
+			.label	= "GPJ0",
+		},
+	}, {
+		.chip	= {
+			.base	= S5PC100_GPJ1(0),
+			.ngpio	= S5PC100_GPIO_J1_NR,
+			.label	= "GPJ1",
+		},
+	}, {
+		.chip	= {
+			.base	= S5PC100_GPJ2(0),
+			.ngpio	= S5PC100_GPIO_J2_NR,
+			.label	= "GPJ2",
+		},
+	}, {
+		.chip	= {
+			.base	= S5PC100_GPJ3(0),
+			.ngpio	= S5PC100_GPIO_J3_NR,
+			.label	= "GPJ3",
+		},
+	}, {
+		.chip	= {
+			.base	= S5PC100_GPJ4(0),
+			.ngpio	= S5PC100_GPIO_J4_NR,
+			.label	= "GPJ4",
+		},
+	}, {
+		.config	= &gpio_cfg_noint,
+		.chip	= {
+			.base	= S5PC100_GPK0(0),
+			.ngpio	= S5PC100_GPIO_K0_NR,
+			.label	= "GPK0",
+		},
+	}, {
+		.config	= &gpio_cfg_noint,
+		.chip	= {
+			.base	= S5PC100_GPK1(0),
+			.ngpio	= S5PC100_GPIO_K1_NR,
+			.label	= "GPK1",
+		},
+	}, {
+		.config	= &gpio_cfg_noint,
+		.chip	= {
+			.base	= S5PC100_GPK2(0),
+			.ngpio	= S5PC100_GPIO_K2_NR,
+			.label	= "GPK2",
+		},
+	}, {
+		.config	= &gpio_cfg_noint,
+		.chip	= {
+			.base	= S5PC100_GPK3(0),
+			.ngpio	= S5PC100_GPIO_K3_NR,
+			.label	= "GPK3",
+		},
+	}, {
+		.config	= &gpio_cfg_noint,
+		.chip	= {
+			.base	= S5PC100_GPL0(0),
+			.ngpio	= S5PC100_GPIO_L0_NR,
+			.label	= "GPL0",
+		},
+	}, {
+		.config	= &gpio_cfg_noint,
+		.chip	= {
+			.base	= S5PC100_GPL1(0),
+			.ngpio	= S5PC100_GPIO_L1_NR,
+			.label	= "GPL1",
+		},
+	}, {
+		.config	= &gpio_cfg_noint,
+		.chip	= {
+			.base	= S5PC100_GPL2(0),
+			.ngpio	= S5PC100_GPIO_L2_NR,
+			.label	= "GPL2",
+		},
+	}, {
+		.config	= &gpio_cfg_noint,
+		.chip	= {
+			.base	= S5PC100_GPL3(0),
+			.ngpio	= S5PC100_GPIO_L3_NR,
+			.label	= "GPL3",
+		},
+	}, {
+		.config	= &gpio_cfg_noint,
+		.chip	= {
+			.base	= S5PC100_GPL4(0),
+			.ngpio	= S5PC100_GPIO_L4_NR,
+			.label	= "GPL4",
+		},
+	}, {
+		.base	= (S5P_VA_GPIO + 0xC00),
+		.config	= &gpio_cfg_eint,
+		.irq_base = IRQ_EINT(0),
+		.chip	= {
+			.base	= S5PC100_GPH0(0),
+			.ngpio	= S5PC100_GPIO_H0_NR,
+			.label	= "GPH0",
+			.to_irq = samsung_gpiolib_to_irq,
+		},
+	}, {
+		.base	= (S5P_VA_GPIO + 0xC20),
+		.config	= &gpio_cfg_eint,
+		.irq_base = IRQ_EINT(8),
+		.chip	= {
+			.base	= S5PC100_GPH1(0),
+			.ngpio	= S5PC100_GPIO_H1_NR,
+			.label	= "GPH1",
+			.to_irq = samsung_gpiolib_to_irq,
+		},
+	}, {
+		.base	= (S5P_VA_GPIO + 0xC40),
+		.config	= &gpio_cfg_eint,
+		.irq_base = IRQ_EINT(16),
+		.chip	= {
+			.base	= S5PC100_GPH2(0),
+			.ngpio	= S5PC100_GPIO_H2_NR,
+			.label	= "GPH2",
+			.to_irq = samsung_gpiolib_to_irq,
+		},
+	}, {
+		.base	= (S5P_VA_GPIO + 0xC60),
+		.config	= &gpio_cfg_eint,
+		.irq_base = IRQ_EINT(24),
+		.chip	= {
+			.base	= S5PC100_GPH3(0),
+			.ngpio	= S5PC100_GPIO_H3_NR,
+			.label	= "GPH3",
+			.to_irq = samsung_gpiolib_to_irq,
+		},
+	},
+};
+
+static __init int s5pc100_gpiolib_init(void)
+{
+	struct s3c_gpio_chip *chip = s5pc100_gpio_chips;
+	int nr_chips = ARRAY_SIZE(s5pc100_gpio_chips);
+	int gpioint_group = 0;
+	int i;
+
+	for (i = 0; i < nr_chips; i++, chip++) {
+		if (chip->config == NULL) {
+			chip->config = &gpio_cfg;
+			chip->group = gpioint_group++;
+		}
+		if (chip->base == NULL)
+			chip->base = S5PC100_BANK_BASE(i);
+	}
+
+	samsung_gpiolib_add_4bit_chips(s5pc100_gpio_chips, nr_chips);
+	s5p_register_gpioint_bank(IRQ_GPIOINT, 0, S5P_GPIOINT_GROUP_MAXNR);
+
+	return 0;
+}
+core_initcall(s5pc100_gpiolib_init);
diff -druN linux-2.6.39-libre/drivers/gpio/gpio-s5pv210.c linux-3.0-rc7-libre/drivers/gpio/gpio-s5pv210.c
--- linux-2.6.39-libre/drivers/gpio/gpio-s5pv210.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/gpio/gpio-s5pv210.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,288 @@
+/* linux/arch/arm/mach-s5pv210/gpiolib.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ *		http://www.samsung.com/
+ *
+ * S5PV210 - GPIOlib support
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+#include <linux/gpio.h>
+#include <plat/gpio-core.h>
+#include <plat/gpio-cfg.h>
+#include <plat/gpio-cfg-helpers.h>
+#include <mach/map.h>
+
+static struct s3c_gpio_cfg gpio_cfg = {
+	.set_config	= s3c_gpio_setcfg_s3c64xx_4bit,
+	.set_pull	= s3c_gpio_setpull_updown,
+	.get_pull	= s3c_gpio_getpull_updown,
+};
+
+static struct s3c_gpio_cfg gpio_cfg_noint = {
+	.set_config	= s3c_gpio_setcfg_s3c64xx_4bit,
+	.set_pull	= s3c_gpio_setpull_updown,
+	.get_pull	= s3c_gpio_getpull_updown,
+};
+
+/* GPIO bank's base address given the index of the bank in the
+ * list of all gpio banks.
+ */
+#define S5PV210_BANK_BASE(bank_nr)	(S5P_VA_GPIO + ((bank_nr) * 0x20))
+
+/*
+ * Following are the gpio banks in v210.
+ *
+ * The 'config' member when left to NULL, is initialized to the default
+ * structure gpio_cfg in the init function below.
+ *
+ * The 'base' member is also initialized in the init function below.
+ * Note: The initialization of 'base' member of s3c_gpio_chip structure
+ * uses the above macro and depends on the banks being listed in order here.
+ */
+static struct s3c_gpio_chip s5pv210_gpio_4bit[] = {
+	{
+		.chip	= {
+			.base	= S5PV210_GPA0(0),
+			.ngpio	= S5PV210_GPIO_A0_NR,
+			.label	= "GPA0",
+		},
+	}, {
+		.chip	= {
+			.base	= S5PV210_GPA1(0),
+			.ngpio	= S5PV210_GPIO_A1_NR,
+			.label	= "GPA1",
+		},
+	}, {
+		.chip	= {
+			.base	= S5PV210_GPB(0),
+			.ngpio	= S5PV210_GPIO_B_NR,
+			.label	= "GPB",
+		},
+	}, {
+		.chip	= {
+			.base	= S5PV210_GPC0(0),
+			.ngpio	= S5PV210_GPIO_C0_NR,
+			.label	= "GPC0",
+		},
+	}, {
+		.chip	= {
+			.base	= S5PV210_GPC1(0),
+			.ngpio	= S5PV210_GPIO_C1_NR,
+			.label	= "GPC1",
+		},
+	}, {
+		.chip	= {
+			.base	= S5PV210_GPD0(0),
+			.ngpio	= S5PV210_GPIO_D0_NR,
+			.label	= "GPD0",
+		},
+	}, {
+		.chip	= {
+			.base	= S5PV210_GPD1(0),
+			.ngpio	= S5PV210_GPIO_D1_NR,
+			.label	= "GPD1",
+		},
+	}, {
+		.chip	= {
+			.base	= S5PV210_GPE0(0),
+			.ngpio	= S5PV210_GPIO_E0_NR,
+			.label	= "GPE0",
+		},
+	}, {
+		.chip	= {
+			.base	= S5PV210_GPE1(0),
+			.ngpio	= S5PV210_GPIO_E1_NR,
+			.label	= "GPE1",
+		},
+	}, {
+		.chip	= {
+			.base	= S5PV210_GPF0(0),
+			.ngpio	= S5PV210_GPIO_F0_NR,
+			.label	= "GPF0",
+		},
+	}, {
+		.chip	= {
+			.base	= S5PV210_GPF1(0),
+			.ngpio	= S5PV210_GPIO_F1_NR,
+			.label	= "GPF1",
+		},
+	}, {
+		.chip	= {
+			.base	= S5PV210_GPF2(0),
+			.ngpio	= S5PV210_GPIO_F2_NR,
+			.label	= "GPF2",
+		},
+	}, {
+		.chip	= {
+			.base	= S5PV210_GPF3(0),
+			.ngpio	= S5PV210_GPIO_F3_NR,
+			.label	= "GPF3",
+		},
+	}, {
+		.chip	= {
+			.base	= S5PV210_GPG0(0),
+			.ngpio	= S5PV210_GPIO_G0_NR,
+			.label	= "GPG0",
+		},
+	}, {
+		.chip	= {
+			.base	= S5PV210_GPG1(0),
+			.ngpio	= S5PV210_GPIO_G1_NR,
+			.label	= "GPG1",
+		},
+	}, {
+		.chip	= {
+			.base	= S5PV210_GPG2(0),
+			.ngpio	= S5PV210_GPIO_G2_NR,
+			.label	= "GPG2",
+		},
+	}, {
+		.chip	= {
+			.base	= S5PV210_GPG3(0),
+			.ngpio	= S5PV210_GPIO_G3_NR,
+			.label	= "GPG3",
+		},
+	}, {
+		.config	= &gpio_cfg_noint,
+		.chip	= {
+			.base	= S5PV210_GPI(0),
+			.ngpio	= S5PV210_GPIO_I_NR,
+			.label	= "GPI",
+		},
+	}, {
+		.chip	= {
+			.base	= S5PV210_GPJ0(0),
+			.ngpio	= S5PV210_GPIO_J0_NR,
+			.label	= "GPJ0",
+		},
+	}, {
+		.chip	= {
+			.base	= S5PV210_GPJ1(0),
+			.ngpio	= S5PV210_GPIO_J1_NR,
+			.label	= "GPJ1",
+		},
+	}, {
+		.chip	= {
+			.base	= S5PV210_GPJ2(0),
+			.ngpio	= S5PV210_GPIO_J2_NR,
+			.label	= "GPJ2",
+		},
+	}, {
+		.chip	= {
+			.base	= S5PV210_GPJ3(0),
+			.ngpio	= S5PV210_GPIO_J3_NR,
+			.label	= "GPJ3",
+		},
+	}, {
+		.chip	= {
+			.base	= S5PV210_GPJ4(0),
+			.ngpio	= S5PV210_GPIO_J4_NR,
+			.label	= "GPJ4",
+		},
+	}, {
+		.config	= &gpio_cfg_noint,
+		.chip	= {
+			.base	= S5PV210_MP01(0),
+			.ngpio	= S5PV210_GPIO_MP01_NR,
+			.label	= "MP01",
+		},
+	}, {
+		.config	= &gpio_cfg_noint,
+		.chip	= {
+			.base	= S5PV210_MP02(0),
+			.ngpio	= S5PV210_GPIO_MP02_NR,
+			.label	= "MP02",
+		},
+	}, {
+		.config	= &gpio_cfg_noint,
+		.chip	= {
+			.base	= S5PV210_MP03(0),
+			.ngpio	= S5PV210_GPIO_MP03_NR,
+			.label	= "MP03",
+		},
+	}, {
+		.config	= &gpio_cfg_noint,
+		.chip	= {
+			.base	= S5PV210_MP04(0),
+			.ngpio	= S5PV210_GPIO_MP04_NR,
+			.label	= "MP04",
+		},
+	}, {
+		.config	= &gpio_cfg_noint,
+		.chip	= {
+			.base	= S5PV210_MP05(0),
+			.ngpio	= S5PV210_GPIO_MP05_NR,
+			.label	= "MP05",
+		},
+	}, {
+		.base	= (S5P_VA_GPIO + 0xC00),
+		.config	= &gpio_cfg_noint,
+		.irq_base = IRQ_EINT(0),
+		.chip	= {
+			.base	= S5PV210_GPH0(0),
+			.ngpio	= S5PV210_GPIO_H0_NR,
+			.label	= "GPH0",
+			.to_irq = samsung_gpiolib_to_irq,
+		},
+	}, {
+		.base	= (S5P_VA_GPIO + 0xC20),
+		.config	= &gpio_cfg_noint,
+		.irq_base = IRQ_EINT(8),
+		.chip	= {
+			.base	= S5PV210_GPH1(0),
+			.ngpio	= S5PV210_GPIO_H1_NR,
+			.label	= "GPH1",
+			.to_irq = samsung_gpiolib_to_irq,
+		},
+	}, {
+		.base	= (S5P_VA_GPIO + 0xC40),
+		.config	= &gpio_cfg_noint,
+		.irq_base = IRQ_EINT(16),
+		.chip	= {
+			.base	= S5PV210_GPH2(0),
+			.ngpio	= S5PV210_GPIO_H2_NR,
+			.label	= "GPH2",
+			.to_irq = samsung_gpiolib_to_irq,
+		},
+	}, {
+		.base	= (S5P_VA_GPIO + 0xC60),
+		.config	= &gpio_cfg_noint,
+		.irq_base = IRQ_EINT(24),
+		.chip	= {
+			.base	= S5PV210_GPH3(0),
+			.ngpio	= S5PV210_GPIO_H3_NR,
+			.label	= "GPH3",
+			.to_irq = samsung_gpiolib_to_irq,
+		},
+	},
+};
+
+static __init int s5pv210_gpiolib_init(void)
+{
+	struct s3c_gpio_chip *chip = s5pv210_gpio_4bit;
+	int nr_chips = ARRAY_SIZE(s5pv210_gpio_4bit);
+	int gpioint_group = 0;
+	int i = 0;
+
+	for (i = 0; i < nr_chips; i++, chip++) {
+		if (chip->config == NULL) {
+			chip->config = &gpio_cfg;
+			chip->group = gpioint_group++;
+		}
+		if (chip->base == NULL)
+			chip->base = S5PV210_BANK_BASE(i);
+	}
+
+	samsung_gpiolib_add_4bit_chips(s5pv210_gpio_4bit, nr_chips);
+	s5p_register_gpioint_bank(IRQ_GPIOINT, 0, S5P_GPIOINT_GROUP_MAXNR);
+
+	return 0;
+}
+core_initcall(s5pv210_gpiolib_init);
diff -druN linux-2.6.39-libre/drivers/gpio/gpio-u300.c linux-3.0-rc7-libre/drivers/gpio/gpio-u300.c
--- linux-2.6.39-libre/drivers/gpio/gpio-u300.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/gpio/gpio-u300.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,700 @@
+/*
+ *
+ * arch/arm/mach-u300/gpio.c
+ *
+ *
+ * Copyright (C) 2007-2009 ST-Ericsson AB
+ * License terms: GNU General Public License (GPL) version 2
+ * U300 GPIO module.
+ * This can driver either of the two basic GPIO cores
+ * available in the U300 platforms:
+ * COH 901 335   - Used in DB3150 (U300 1.0) and DB3200 (U330 1.0)
+ * COH 901 571/3 - Used in DB3210 (U365 2.0) and DB3350 (U335 1.0)
+ * Notice that you also have inline macros in <asm-arch/gpio.h>
+ * Author: Linus Walleij <linus.walleij@stericsson.com>
+ * Author: Jonas Aaberg <jonas.aberg@stericsson.com>
+ *
+ */
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <linux/errno.h>
+#include <linux/io.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/platform_device.h>
+#include <linux/gpio.h>
+
+/* Reference to GPIO block clock */
+static struct clk *clk;
+
+/* Memory resource */
+static struct resource *memres;
+static void __iomem *virtbase;
+static struct device *gpiodev;
+
+struct u300_gpio_port {
+	const char *name;
+	int irq;
+	int number;
+};
+
+
+static struct u300_gpio_port gpio_ports[] = {
+	{
+		.name = "gpio0",
+		.number = 0,
+	},
+	{
+		.name = "gpio1",
+		.number = 1,
+	},
+	{
+		.name = "gpio2",
+		.number = 2,
+	},
+#ifdef U300_COH901571_3
+	{
+		.name = "gpio3",
+		.number = 3,
+	},
+	{
+		.name = "gpio4",
+		.number = 4,
+	},
+#ifdef CONFIG_MACH_U300_BS335
+	{
+		.name = "gpio5",
+		.number = 5,
+	},
+	{
+		.name = "gpio6",
+		.number = 6,
+	},
+#endif
+#endif
+
+};
+
+
+#ifdef U300_COH901571_3
+
+/* Default input value */
+#define DEFAULT_OUTPUT_LOW   0
+#define DEFAULT_OUTPUT_HIGH  1
+
+/* GPIO Pull-Up status */
+#define DISABLE_PULL_UP  0
+#define ENABLE_PULL_UP  1
+
+#define GPIO_NOT_USED 0
+#define GPIO_IN       1
+#define GPIO_OUT      2
+
+struct u300_gpio_configuration_data {
+	unsigned char pin_usage;
+	unsigned char default_output_value;
+	unsigned char pull_up;
+};
+
+/* Initial configuration */
+const struct u300_gpio_configuration_data
+u300_gpio_config[U300_GPIO_NUM_PORTS][U300_GPIO_PINS_PER_PORT] = {
+#ifdef CONFIG_MACH_U300_BS335
+	/* Port 0, pins 0-7 */
+	{
+		{GPIO_IN,  DEFAULT_OUTPUT_LOW,   DISABLE_PULL_UP},
+		{GPIO_OUT, DEFAULT_OUTPUT_HIGH,  DISABLE_PULL_UP},
+		{GPIO_IN,  DEFAULT_OUTPUT_LOW,   DISABLE_PULL_UP},
+		{GPIO_OUT, DEFAULT_OUTPUT_LOW,   DISABLE_PULL_UP},
+		{GPIO_OUT, DEFAULT_OUTPUT_LOW,   DISABLE_PULL_UP},
+		{GPIO_OUT, DEFAULT_OUTPUT_LOW,   DISABLE_PULL_UP},
+		{GPIO_OUT, DEFAULT_OUTPUT_LOW,   DISABLE_PULL_UP},
+		{GPIO_OUT, DEFAULT_OUTPUT_LOW,   DISABLE_PULL_UP}
+	},
+	/* Port 1, pins 0-7 */
+	{
+		{GPIO_OUT, DEFAULT_OUTPUT_LOW,   DISABLE_PULL_UP},
+		{GPIO_OUT, DEFAULT_OUTPUT_LOW,   DISABLE_PULL_UP},
+		{GPIO_OUT, DEFAULT_OUTPUT_LOW,   DISABLE_PULL_UP},
+		{GPIO_IN,  DEFAULT_OUTPUT_LOW,    ENABLE_PULL_UP},
+		{GPIO_IN,  DEFAULT_OUTPUT_LOW,   DISABLE_PULL_UP},
+		{GPIO_OUT, DEFAULT_OUTPUT_HIGH,  DISABLE_PULL_UP},
+		{GPIO_OUT, DEFAULT_OUTPUT_LOW,   DISABLE_PULL_UP},
+		{GPIO_OUT, DEFAULT_OUTPUT_LOW,   DISABLE_PULL_UP}
+	},
+	/* Port 2, pins 0-7 */
+	{
+		{GPIO_IN,  DEFAULT_OUTPUT_LOW,   DISABLE_PULL_UP},
+		{GPIO_IN,  DEFAULT_OUTPUT_LOW,   DISABLE_PULL_UP},
+		{GPIO_IN,  DEFAULT_OUTPUT_LOW,   DISABLE_PULL_UP},
+		{GPIO_IN,  DEFAULT_OUTPUT_LOW,   DISABLE_PULL_UP},
+		{GPIO_OUT, DEFAULT_OUTPUT_LOW,   DISABLE_PULL_UP},
+		{GPIO_IN,  DEFAULT_OUTPUT_LOW,    ENABLE_PULL_UP},
+		{GPIO_OUT, DEFAULT_OUTPUT_LOW,   DISABLE_PULL_UP},
+		{GPIO_IN,  DEFAULT_OUTPUT_LOW,    ENABLE_PULL_UP}
+	},
+	/* Port 3, pins 0-7 */
+	{
+		{GPIO_IN,  DEFAULT_OUTPUT_LOW,    ENABLE_PULL_UP},
+		{GPIO_OUT, DEFAULT_OUTPUT_LOW,   DISABLE_PULL_UP},
+		{GPIO_IN,  DEFAULT_OUTPUT_LOW,   DISABLE_PULL_UP},
+		{GPIO_IN,  DEFAULT_OUTPUT_LOW,   DISABLE_PULL_UP},
+		{GPIO_IN,  DEFAULT_OUTPUT_LOW,   DISABLE_PULL_UP},
+		{GPIO_IN,  DEFAULT_OUTPUT_LOW,   DISABLE_PULL_UP},
+		{GPIO_IN,  DEFAULT_OUTPUT_LOW,   DISABLE_PULL_UP},
+		{GPIO_IN,  DEFAULT_OUTPUT_LOW,   DISABLE_PULL_UP}
+	},
+	/* Port 4, pins 0-7 */
+	{
+		{GPIO_IN,  DEFAULT_OUTPUT_LOW,   DISABLE_PULL_UP},
+		{GPIO_IN,  DEFAULT_OUTPUT_LOW,   DISABLE_PULL_UP},
+		{GPIO_IN,  DEFAULT_OUTPUT_LOW,   DISABLE_PULL_UP},
+		{GPIO_IN,  DEFAULT_OUTPUT_LOW,   DISABLE_PULL_UP},
+		{GPIO_IN,  DEFAULT_OUTPUT_LOW,   DISABLE_PULL_UP},
+		{GPIO_IN,  DEFAULT_OUTPUT_LOW,   DISABLE_PULL_UP},
+		{GPIO_IN,  DEFAULT_OUTPUT_LOW,   DISABLE_PULL_UP},
+		{GPIO_IN,  DEFAULT_OUTPUT_LOW,   DISABLE_PULL_UP}
+	},
+	/* Port 5, pins 0-7 */
+	{
+		{GPIO_IN,  DEFAULT_OUTPUT_LOW,   DISABLE_PULL_UP},
+		{GPIO_IN,  DEFAULT_OUTPUT_LOW,   DISABLE_PULL_UP},
+		{GPIO_IN,  DEFAULT_OUTPUT_LOW,   DISABLE_PULL_UP},
+		{GPIO_IN,  DEFAULT_OUTPUT_LOW,   DISABLE_PULL_UP},
+		{GPIO_IN,  DEFAULT_OUTPUT_LOW,   DISABLE_PULL_UP},
+		{GPIO_IN,  DEFAULT_OUTPUT_LOW,   DISABLE_PULL_UP},
+		{GPIO_IN,  DEFAULT_OUTPUT_LOW,   DISABLE_PULL_UP},
+		{GPIO_IN,  DEFAULT_OUTPUT_LOW,   DISABLE_PULL_UP}
+	},
+	/* Port 6, pind 0-7 */
+	{
+		{GPIO_IN,  DEFAULT_OUTPUT_LOW,   DISABLE_PULL_UP},
+		{GPIO_IN,  DEFAULT_OUTPUT_LOW,   DISABLE_PULL_UP},
+		{GPIO_IN,  DEFAULT_OUTPUT_LOW,   DISABLE_PULL_UP},
+		{GPIO_IN,  DEFAULT_OUTPUT_LOW,   DISABLE_PULL_UP},
+		{GPIO_IN,  DEFAULT_OUTPUT_LOW,   DISABLE_PULL_UP},
+		{GPIO_IN,  DEFAULT_OUTPUT_LOW,   DISABLE_PULL_UP},
+		{GPIO_IN,  DEFAULT_OUTPUT_LOW,   DISABLE_PULL_UP},
+		{GPIO_IN,  DEFAULT_OUTPUT_LOW,   DISABLE_PULL_UP}
+	}
+#endif
+
+#ifdef CONFIG_MACH_U300_BS365
+	/* Port 0, pins 0-7 */
+	{
+		{GPIO_IN,  DEFAULT_OUTPUT_LOW,   DISABLE_PULL_UP},
+		{GPIO_OUT, DEFAULT_OUTPUT_LOW,   DISABLE_PULL_UP},
+		{GPIO_IN,  DEFAULT_OUTPUT_LOW,   DISABLE_PULL_UP},
+		{GPIO_OUT, DEFAULT_OUTPUT_LOW,   DISABLE_PULL_UP},
+		{GPIO_OUT, DEFAULT_OUTPUT_LOW,   DISABLE_PULL_UP},
+		{GPIO_OUT, DEFAULT_OUTPUT_LOW,   DISABLE_PULL_UP},
+		{GPIO_IN,  DEFAULT_OUTPUT_LOW,    ENABLE_PULL_UP},
+		{GPIO_IN,  DEFAULT_OUTPUT_LOW,   DISABLE_PULL_UP}
+	},
+	/* Port 1, pins 0-7 */
+	{
+		{GPIO_OUT, DEFAULT_OUTPUT_LOW,   DISABLE_PULL_UP},
+		{GPIO_IN,  DEFAULT_OUTPUT_LOW,   DISABLE_PULL_UP},
+		{GPIO_OUT, DEFAULT_OUTPUT_LOW,   DISABLE_PULL_UP},
+		{GPIO_IN,  DEFAULT_OUTPUT_LOW,   DISABLE_PULL_UP},
+		{GPIO_IN,  DEFAULT_OUTPUT_LOW,   DISABLE_PULL_UP},
+		{GPIO_OUT, DEFAULT_OUTPUT_HIGH,  DISABLE_PULL_UP},
+		{GPIO_OUT, DEFAULT_OUTPUT_LOW,   DISABLE_PULL_UP},
+		{GPIO_OUT, DEFAULT_OUTPUT_LOW,   DISABLE_PULL_UP}
+	},
+	/* Port 2, pins 0-7 */
+	{
+		{GPIO_IN,  DEFAULT_OUTPUT_LOW,   DISABLE_PULL_UP},
+		{GPIO_IN,  DEFAULT_OUTPUT_LOW,    ENABLE_PULL_UP},
+		{GPIO_OUT, DEFAULT_OUTPUT_LOW,   DISABLE_PULL_UP},
+		{GPIO_OUT, DEFAULT_OUTPUT_LOW,   DISABLE_PULL_UP},
+		{GPIO_IN,  DEFAULT_OUTPUT_LOW,    ENABLE_PULL_UP},
+		{GPIO_IN,  DEFAULT_OUTPUT_LOW,    ENABLE_PULL_UP},
+		{GPIO_IN,  DEFAULT_OUTPUT_LOW,    ENABLE_PULL_UP},
+		{GPIO_IN,  DEFAULT_OUTPUT_LOW,    ENABLE_PULL_UP}
+	},
+	/* Port 3, pins 0-7 */
+	{
+		{GPIO_IN,  DEFAULT_OUTPUT_LOW,    ENABLE_PULL_UP},
+		{GPIO_IN,  DEFAULT_OUTPUT_LOW,    ENABLE_PULL_UP},
+		{GPIO_IN,  DEFAULT_OUTPUT_LOW,    ENABLE_PULL_UP},
+		{GPIO_IN,  DEFAULT_OUTPUT_LOW,    ENABLE_PULL_UP},
+		{GPIO_IN,  DEFAULT_OUTPUT_LOW,    ENABLE_PULL_UP},
+		{GPIO_IN,  DEFAULT_OUTPUT_LOW,    ENABLE_PULL_UP},
+		{GPIO_IN,  DEFAULT_OUTPUT_LOW,    ENABLE_PULL_UP},
+		{GPIO_IN,  DEFAULT_OUTPUT_LOW,    ENABLE_PULL_UP}
+	},
+	/* Port 4, pins 0-7 */
+	{
+		{GPIO_IN,  DEFAULT_OUTPUT_LOW,    ENABLE_PULL_UP},
+		{GPIO_IN,  DEFAULT_OUTPUT_LOW,    ENABLE_PULL_UP},
+		{GPIO_IN,  DEFAULT_OUTPUT_LOW,    ENABLE_PULL_UP},
+		{GPIO_IN,  DEFAULT_OUTPUT_LOW,    ENABLE_PULL_UP},
+		/* These 4 pins doesn't exist on DB3210 */
+		{GPIO_OUT, DEFAULT_OUTPUT_LOW,    ENABLE_PULL_UP},
+		{GPIO_OUT, DEFAULT_OUTPUT_LOW,    ENABLE_PULL_UP},
+		{GPIO_OUT, DEFAULT_OUTPUT_LOW,    ENABLE_PULL_UP},
+		{GPIO_OUT, DEFAULT_OUTPUT_LOW,    ENABLE_PULL_UP}
+	}
+#endif
+};
+#endif
+
+
+/* No users == we can power down GPIO */
+static int gpio_users;
+
+struct gpio_struct {
+	int (*callback)(void *);
+	void *data;
+	int users;
+};
+
+static struct gpio_struct gpio_pin[U300_GPIO_MAX];
+
+/*
+ * Let drivers register callback in order to get notified when there is
+ * an interrupt on the gpio pin
+ */
+int gpio_register_callback(unsigned gpio, int (*func)(void *arg), void *data)
+{
+	if (gpio_pin[gpio].callback)
+		dev_warn(gpiodev, "%s: WARNING: callback already "
+			 "registered for gpio pin#%d\n", __func__, gpio);
+	gpio_pin[gpio].callback = func;
+	gpio_pin[gpio].data = data;
+
+	return 0;
+}
+EXPORT_SYMBOL(gpio_register_callback);
+
+int gpio_unregister_callback(unsigned gpio)
+{
+	if (!gpio_pin[gpio].callback)
+		dev_warn(gpiodev, "%s: WARNING: callback already "
+			 "unregistered for gpio pin#%d\n", __func__, gpio);
+	gpio_pin[gpio].callback = NULL;
+	gpio_pin[gpio].data = NULL;
+
+	return 0;
+}
+EXPORT_SYMBOL(gpio_unregister_callback);
+
+/* Non-zero means valid */
+int gpio_is_valid(int number)
+{
+	if (number >= 0 &&
+	    number < (U300_GPIO_NUM_PORTS * U300_GPIO_PINS_PER_PORT))
+		return 1;
+	return 0;
+}
+EXPORT_SYMBOL(gpio_is_valid);
+
+int gpio_request(unsigned gpio, const char *label)
+{
+	if (gpio_pin[gpio].users)
+		return -EINVAL;
+	else
+		gpio_pin[gpio].users++;
+
+	gpio_users++;
+
+	return 0;
+}
+EXPORT_SYMBOL(gpio_request);
+
+void gpio_free(unsigned gpio)
+{
+	gpio_users--;
+	gpio_pin[gpio].users--;
+	if (unlikely(gpio_pin[gpio].users < 0)) {
+		dev_warn(gpiodev, "warning: gpio#%d release mismatch\n",
+			 gpio);
+		gpio_pin[gpio].users = 0;
+	}
+
+	return;
+}
+EXPORT_SYMBOL(gpio_free);
+
+/* This returns zero or nonzero */
+int gpio_get_value(unsigned gpio)
+{
+	return readl(virtbase + U300_GPIO_PXPDIR +
+	  PIN_TO_PORT(gpio) * U300_GPIO_PORTX_SPACING) & (1 << (gpio & 0x07));
+}
+EXPORT_SYMBOL(gpio_get_value);
+
+/*
+ * We hope that the compiler will optimize away the unused branch
+ * in case "value" is a constant
+ */
+void gpio_set_value(unsigned gpio, int value)
+{
+	u32 val;
+	unsigned long flags;
+
+	local_irq_save(flags);
+	if (value) {
+		/* set */
+		val = readl(virtbase + U300_GPIO_PXPDOR +
+		  PIN_TO_PORT(gpio) * U300_GPIO_PORTX_SPACING)
+		  & (1 << (gpio & 0x07));
+		writel(val | (1 << (gpio & 0x07)), virtbase +
+		  U300_GPIO_PXPDOR +
+		  PIN_TO_PORT(gpio) * U300_GPIO_PORTX_SPACING);
+	} else {
+		/* clear */
+		val = readl(virtbase + U300_GPIO_PXPDOR +
+		  PIN_TO_PORT(gpio) * U300_GPIO_PORTX_SPACING)
+		  & (1 << (gpio & 0x07));
+		writel(val & ~(1 << (gpio & 0x07)), virtbase +
+		  U300_GPIO_PXPDOR +
+		  PIN_TO_PORT(gpio) * U300_GPIO_PORTX_SPACING);
+	}
+	local_irq_restore(flags);
+}
+EXPORT_SYMBOL(gpio_set_value);
+
+int gpio_direction_input(unsigned gpio)
+{
+	unsigned long flags;
+	u32 val;
+
+	if (gpio > U300_GPIO_MAX)
+		return -EINVAL;
+
+	local_irq_save(flags);
+	val = readl(virtbase + U300_GPIO_PXPCR + PIN_TO_PORT(gpio) *
+				U300_GPIO_PORTX_SPACING);
+	/* Mask out this pin*/
+	val &= ~(U300_GPIO_PXPCR_PIN_MODE_MASK << ((gpio & 0x07) << 1));
+	/* This is not needed since it sets the bits to zero.*/
+	/* val |= (U300_GPIO_PXPCR_PIN_MODE_INPUT << (gpio*2)); */
+	writel(val, virtbase + U300_GPIO_PXPCR + PIN_TO_PORT(gpio) *
+				U300_GPIO_PORTX_SPACING);
+	local_irq_restore(flags);
+	return 0;
+}
+EXPORT_SYMBOL(gpio_direction_input);
+
+int gpio_direction_output(unsigned gpio, int value)
+{
+	unsigned long flags;
+	u32 val;
+
+	if (gpio > U300_GPIO_MAX)
+		return -EINVAL;
+
+	local_irq_save(flags);
+	val = readl(virtbase + U300_GPIO_PXPCR + PIN_TO_PORT(gpio) *
+				U300_GPIO_PORTX_SPACING);
+	/* Mask out this pin */
+	val &= ~(U300_GPIO_PXPCR_PIN_MODE_MASK << ((gpio & 0x07) << 1));
+	/*
+	 * FIXME: configure for push/pull, open drain or open source per pin
+	 * in setup. The current driver will only support push/pull.
+	 */
+	val |= (U300_GPIO_PXPCR_PIN_MODE_OUTPUT_PUSH_PULL
+			<< ((gpio & 0x07) << 1));
+	writel(val, virtbase + U300_GPIO_PXPCR + PIN_TO_PORT(gpio) *
+				U300_GPIO_PORTX_SPACING);
+	gpio_set_value(gpio, value);
+	local_irq_restore(flags);
+	return 0;
+}
+EXPORT_SYMBOL(gpio_direction_output);
+
+/*
+ * Enable an IRQ, edge is rising edge (!= 0) or falling edge (==0).
+ */
+void enable_irq_on_gpio_pin(unsigned gpio, int edge)
+{
+	u32 val;
+	unsigned long flags;
+	local_irq_save(flags);
+
+	val = readl(virtbase + U300_GPIO_PXIEN + PIN_TO_PORT(gpio) *
+				U300_GPIO_PORTX_SPACING);
+	val |= (1 << (gpio & 0x07));
+	writel(val, virtbase + U300_GPIO_PXIEN + PIN_TO_PORT(gpio) *
+				U300_GPIO_PORTX_SPACING);
+	val = readl(virtbase + U300_GPIO_PXICR + PIN_TO_PORT(gpio) *
+				U300_GPIO_PORTX_SPACING);
+	if (edge)
+		val |= (1 << (gpio & 0x07));
+	else
+		val &= ~(1 << (gpio & 0x07));
+	writel(val, virtbase + U300_GPIO_PXICR + PIN_TO_PORT(gpio) *
+				U300_GPIO_PORTX_SPACING);
+	local_irq_restore(flags);
+}
+EXPORT_SYMBOL(enable_irq_on_gpio_pin);
+
+void disable_irq_on_gpio_pin(unsigned gpio)
+{
+	u32 val;
+	unsigned long flags;
+
+	local_irq_save(flags);
+	val = readl(virtbase + U300_GPIO_PXIEN + PIN_TO_PORT(gpio) *
+				U300_GPIO_PORTX_SPACING);
+	val &= ~(1 << (gpio & 0x07));
+	writel(val, virtbase + U300_GPIO_PXIEN + PIN_TO_PORT(gpio) *
+				U300_GPIO_PORTX_SPACING);
+	local_irq_restore(flags);
+}
+EXPORT_SYMBOL(disable_irq_on_gpio_pin);
+
+/* Enable (value == 0) or disable (value == 1) internal pullup */
+void gpio_pullup(unsigned gpio, int value)
+{
+	u32 val;
+	unsigned long flags;
+
+	local_irq_save(flags);
+	if (value) {
+		val = readl(virtbase + U300_GPIO_PXPER + PIN_TO_PORT(gpio) *
+					U300_GPIO_PORTX_SPACING);
+		writel(val | (1 << (gpio & 0x07)), virtbase + U300_GPIO_PXPER +
+				PIN_TO_PORT(gpio) * U300_GPIO_PORTX_SPACING);
+	} else {
+		val = readl(virtbase + U300_GPIO_PXPER + PIN_TO_PORT(gpio) *
+					U300_GPIO_PORTX_SPACING);
+		writel(val & ~(1 << (gpio & 0x07)), virtbase + U300_GPIO_PXPER +
+				PIN_TO_PORT(gpio) * U300_GPIO_PORTX_SPACING);
+	}
+	local_irq_restore(flags);
+}
+EXPORT_SYMBOL(gpio_pullup);
+
+static irqreturn_t gpio_irq_handler(int irq, void *dev_id)
+{
+	struct u300_gpio_port *port = dev_id;
+	u32 val;
+	int pin;
+
+	/* Read event register */
+	val = readl(virtbase + U300_GPIO_PXIEV + port->number *
+				U300_GPIO_PORTX_SPACING);
+	/* Mask with enable register */
+	val &= readl(virtbase + U300_GPIO_PXIEV + port->number *
+				U300_GPIO_PORTX_SPACING);
+	/* Mask relevant bits */
+	val &= U300_GPIO_PXIEV_ALL_IRQ_EVENT_MASK;
+	/* ACK IRQ (clear event) */
+	writel(val, virtbase + U300_GPIO_PXIEV + port->number *
+				U300_GPIO_PORTX_SPACING);
+	/* Print message */
+	while (val != 0) {
+		unsigned gpio;
+
+		pin = __ffs(val);
+		/* mask off this pin */
+		val &= ~(1 << pin);
+		gpio = (port->number << 3) + pin;
+
+		if (gpio_pin[gpio].callback)
+			(void)gpio_pin[gpio].callback(gpio_pin[gpio].data);
+		else
+			dev_dbg(gpiodev, "stray GPIO IRQ on line %d\n",
+			       gpio);
+	}
+	return IRQ_HANDLED;
+}
+
+static void gpio_set_initial_values(void)
+{
+#ifdef U300_COH901571_3
+	int i, j;
+	unsigned long flags;
+	u32 val;
+
+	/* Write default values to all pins */
+	for (i = 0; i < U300_GPIO_NUM_PORTS; i++) {
+		val = 0;
+		for (j = 0; j < 8; j++)
+			val |= (u32) (u300_gpio_config[i][j].default_output_value != DEFAULT_OUTPUT_LOW) << j;
+		local_irq_save(flags);
+		writel(val, virtbase + U300_GPIO_PXPDOR + i * U300_GPIO_PORTX_SPACING);
+		local_irq_restore(flags);
+	}
+
+	/*
+	 * Put all pins that are set to either 'GPIO_OUT' or 'GPIO_NOT_USED'
+	 * to output and 'GPIO_IN' to input for each port. And initialize
+	 * default value on outputs.
+	 */
+	for (i = 0; i < U300_GPIO_NUM_PORTS; i++) {
+		for (j = 0; j < U300_GPIO_PINS_PER_PORT; j++) {
+			local_irq_save(flags);
+			val = readl(virtbase + U300_GPIO_PXPCR +
+					 i * U300_GPIO_PORTX_SPACING);
+			/* Mask out this pin */
+			val &= ~(U300_GPIO_PXPCR_PIN_MODE_MASK << (j << 1));
+
+			if (u300_gpio_config[i][j].pin_usage != GPIO_IN)
+				val |= (U300_GPIO_PXPCR_PIN_MODE_OUTPUT_PUSH_PULL << (j << 1));
+			writel(val, virtbase + U300_GPIO_PXPCR +
+					 i * U300_GPIO_PORTX_SPACING);
+			local_irq_restore(flags);
+		}
+	}
+
+	/* Enable or disable the internal pull-ups in the GPIO ASIC block */
+	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);
+		local_irq_save(flags);
+		writel(val, virtbase + U300_GPIO_PXPER + i * U300_GPIO_PORTX_SPACING);
+		local_irq_restore(flags);
+	}
+#endif
+}
+
+static int __init gpio_probe(struct platform_device *pdev)
+{
+	u32 val;
+	int err = 0;
+	int i;
+	int num_irqs;
+
+	gpiodev = &pdev->dev;
+	memset(gpio_pin, 0, sizeof(gpio_pin));
+
+	/* Get GPIO clock */
+	clk = clk_get(&pdev->dev, NULL);
+	if (IS_ERR(clk)) {
+		err = PTR_ERR(clk);
+		dev_err(gpiodev, "could not get GPIO clock\n");
+		goto err_no_clk;
+	}
+	err = clk_enable(clk);
+	if (err) {
+		dev_err(gpiodev, "could not enable GPIO clock\n");
+		goto err_no_clk_enable;
+	}
+
+	memres = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!memres)
+		goto err_no_resource;
+
+	if (request_mem_region(memres->start, memres->end - memres->start, "GPIO Controller")
+	    == NULL) {
+		err = -ENODEV;
+		goto err_no_ioregion;
+	}
+
+	virtbase = ioremap(memres->start, resource_size(memres));
+	if (!virtbase) {
+		err = -ENOMEM;
+		goto err_no_ioremap;
+	}
+	dev_info(gpiodev, "remapped 0x%08x to %p\n",
+		 memres->start, virtbase);
+
+#ifdef U300_COH901335
+	dev_info(gpiodev, "initializing GPIO Controller COH 901 335\n");
+	/* Turn on the GPIO block */
+	writel(U300_GPIO_CR_BLOCK_CLOCK_ENABLE, virtbase + U300_GPIO_CR);
+#endif
+
+#ifdef U300_COH901571_3
+	dev_info(gpiodev, "initializing GPIO Controller COH 901 571/3\n");
+	val = readl(virtbase + U300_GPIO_CR);
+	dev_info(gpiodev, "COH901571/3 block version: %d, " \
+	       "number of cores: %d\n",
+	       ((val & 0x0000FE00) >> 9),
+	       ((val & 0x000001FC) >> 2));
+	writel(U300_GPIO_CR_BLOCK_CLKRQ_ENABLE, virtbase + U300_GPIO_CR);
+#endif
+
+	gpio_set_initial_values();
+
+	for (num_irqs = 0 ; num_irqs < U300_GPIO_NUM_PORTS; num_irqs++) {
+
+		gpio_ports[num_irqs].irq =
+			platform_get_irq_byname(pdev,
+						gpio_ports[num_irqs].name);
+
+		err = request_irq(gpio_ports[num_irqs].irq,
+				  gpio_irq_handler, IRQF_DISABLED,
+				  gpio_ports[num_irqs].name,
+				  &gpio_ports[num_irqs]);
+		if (err) {
+			dev_err(gpiodev, "cannot allocate IRQ for %s!\n",
+				gpio_ports[num_irqs].name);
+			goto err_no_irq;
+		}
+		/* Turns off PortX_irq_force */
+		writel(0x0, virtbase + U300_GPIO_PXIFR +
+				 num_irqs * U300_GPIO_PORTX_SPACING);
+	}
+
+	return 0;
+
+ err_no_irq:
+	for (i = 0; i < num_irqs; i++)
+		free_irq(gpio_ports[i].irq, &gpio_ports[i]);
+	iounmap(virtbase);
+ err_no_ioremap:
+	release_mem_region(memres->start, memres->end - memres->start);
+ err_no_ioregion:
+ err_no_resource:
+	clk_disable(clk);
+ err_no_clk_enable:
+	clk_put(clk);
+ err_no_clk:
+	dev_info(gpiodev, "module ERROR:%d\n", err);
+	return err;
+}
+
+static int __exit gpio_remove(struct platform_device *pdev)
+{
+	int i;
+
+	/* Turn off the GPIO block */
+	writel(0x00000000U, virtbase + U300_GPIO_CR);
+	for (i = 0 ; i < U300_GPIO_NUM_PORTS; i++)
+		free_irq(gpio_ports[i].irq, &gpio_ports[i]);
+	iounmap(virtbase);
+	release_mem_region(memres->start, memres->end - memres->start);
+	clk_disable(clk);
+	clk_put(clk);
+	return 0;
+}
+
+static struct platform_driver gpio_driver = {
+	.driver		= {
+		.name	= "u300-gpio",
+	},
+	.remove		= __exit_p(gpio_remove),
+};
+
+
+static int __init u300_gpio_init(void)
+{
+	return platform_driver_probe(&gpio_driver, gpio_probe);
+}
+
+static void __exit u300_gpio_exit(void)
+{
+	platform_driver_unregister(&gpio_driver);
+}
+
+arch_initcall(u300_gpio_init);
+module_exit(u300_gpio_exit);
+
+MODULE_AUTHOR("Linus Walleij <linus.walleij@stericsson.com>");
+
+#ifdef U300_COH901571_3
+MODULE_DESCRIPTION("ST-Ericsson AB COH 901 571/3 GPIO driver");
+#endif
+
+#ifdef U300_COH901335
+MODULE_DESCRIPTION("ST-Ericsson AB COH 901 335 GPIO driver");
+#endif
+
+MODULE_LICENSE("GPL");
diff -druN linux-2.6.39-libre/drivers/gpio/janz-ttl.c linux-3.0-rc7-libre/drivers/gpio/janz-ttl.c
--- linux-2.6.39-libre/drivers/gpio/janz-ttl.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/gpio/janz-ttl.c	2011-07-11 19:51:52.000000000 -0400
@@ -15,7 +15,6 @@
 #include <linux/interrupt.h>
 #include <linux/delay.h>
 #include <linux/platform_device.h>
-#include <linux/mfd/core.h>
 #include <linux/io.h>
 #include <linux/gpio.h>
 #include <linux/slab.h>
@@ -150,7 +149,7 @@
 	struct resource *res;
 	int ret;
 
-	pdata = mfd_get_data(pdev);
+	pdata = pdev->dev.platform_data;
 	if (!pdata) {
 		dev_err(dev, "no platform data\n");
 		ret = -ENXIO;
diff -druN linux-2.6.39-libre/drivers/gpio/Kconfig linux-3.0-rc7-libre/drivers/gpio/Kconfig
--- linux-2.6.39-libre/drivers/gpio/Kconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/gpio/Kconfig	2011-07-11 19:51:52.000000000 -0400
@@ -1,5 +1,5 @@
 #
-# platform-neutral GPIO infrastructure and expanders
+# GPIO infrastructure and drivers
 #
 
 config ARCH_WANT_OPTIONAL_GPIOLIB
@@ -31,7 +31,7 @@
 	help
 	  This enables GPIO support through the generic GPIO library.
 	  You only need to enable this, if you also want to enable
-	  one or more of the GPIO expansion card drivers below.
+	  one or more of the GPIO drivers below.
 
 	  If unsure, say N.
 
@@ -63,24 +63,45 @@
 	  Kernel drivers may also request that a particular GPIO be
 	  exported to userspace; this can be useful when debugging.
 
-# put expanders in the right section, in alphabetical order
+# put drivers in the right section, in alphabetical order
 
 config GPIO_MAX730X
 	tristate
 
-comment "Memory mapped GPIO expanders:"
+comment "Memory mapped GPIO drivers:"
+
+config GPIO_BASIC_MMIO_CORE
+	tristate
+	help
+	  Provides core functionality for basic memory-mapped GPIO controllers.
 
 config GPIO_BASIC_MMIO
 	tristate "Basic memory-mapped GPIO controllers support"
+	select GPIO_BASIC_MMIO_CORE
 	help
 	  Say yes here to support basic memory-mapped GPIO controllers.
 
 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_EXYNOS4
+	def_bool y
+	depends on CPU_EXYNOS4210
+
+config GPIO_PLAT_SAMSUNG
+	def_bool y
+	depends on SAMSUNG_GPIOLIB_4BIT
+
+config GPIO_S5PC100
+	def_bool y
+	depends on CPU_S5PC100
+
+config GPIO_S5PV210
+	def_bool y
+	depends on CPU_S5PV210
+
 config GPIO_PL061
 	bool "PrimeCell PL061 GPIO support"
 	depends on ARM_AMBA
@@ -101,7 +122,7 @@
 
 config GPIO_SCH
 	tristate "Intel SCH/TunnelCreek GPIO"
-	depends on GPIOLIB && PCI && X86
+	depends on PCI && X86
 	select MFD_CORE
 	select LPC_SCH
 	help
@@ -121,7 +142,7 @@
 
 config GPIO_VX855
 	tristate "VIA VX855/VX875 GPIO"
-	depends on GPIOLIB && MFD_SUPPORT && PCI
+	depends on MFD_SUPPORT && PCI
 	select MFD_CORE
 	select MFD_VX855
 	help
@@ -298,7 +319,7 @@
 
 config GPIO_CS5535
 	tristate "AMD CS5535/CS5536 GPIO support"
-	depends on PCI && X86 && !CS5535_GPIO
+	depends on PCI && X86 && !CS5535_GPIO && MFD_CS5535
 	help
 	  The AMD CS5535 and CS5536 southbridges support 28 GPIO pins that
 	  can be used for quite a number of things.  The CS5535/6 is found on
@@ -329,13 +350,19 @@
 	  Say Y here to support Intel Langwell/Penwell GPIO.
 
 config GPIO_PCH
-	tristate "PCH GPIO of Intel Topcliff"
+	tristate "Intel EG20T PCH / OKI SEMICONDUCTOR ML7223 IOH GPIO"
 	depends on PCI && X86
 	help
 	  This driver is for PCH(Platform controller Hub) GPIO of Intel Topcliff
 	  which is an IOH(Input/Output Hub) for x86 embedded processor.
 	  This driver can access PCH GPIO device.
 
+	  This driver also can be used for OKI SEMICONDUCTOR IOH(Input/
+	  Output Hub), ML7223.
+	  ML7223 IOH is for MP(Media Phone) use.
+	  ML7223 is companion chip for Intel Atom E6xx series.
+	  ML7223 is completely compatible for Intel EG20T PCH.
+
 config GPIO_ML_IOH
 	tristate "OKI SEMICONDUCTOR ML7213 IOH GPIO support"
 	depends on PCI
@@ -347,13 +374,13 @@
 
 config GPIO_TIMBERDALE
 	bool "Support for timberdale GPIO IP"
-	depends on MFD_TIMBERDALE && GPIOLIB && HAS_IOMEM
+	depends on MFD_TIMBERDALE && HAS_IOMEM
 	---help---
 	Add support for the GPIO IP in the timberdale FPGA.
 
 config GPIO_RDC321X
 	tristate "RDC R-321x GPIO support"
-	depends on PCI && GPIOLIB
+	depends on PCI
 	select MFD_SUPPORT
 	select MFD_CORE
 	select MFD_RDC321X
@@ -419,4 +446,11 @@
 	depends on AB8500_CORE && BROKEN
 	help
 	  Select this to enable the AB8500 IC GPIO driver
+
+config GPIO_TPS65910
+	bool "TPS65910 GPIO"
+	depends on MFD_TPS65910
+	help
+	  Select this option to enable GPIO driver for the TPS65910
+	  chip family.
 endif
diff -druN linux-2.6.39-libre/drivers/gpio/langwell_gpio.c linux-3.0-rc7-libre/drivers/gpio/langwell_gpio.c
--- linux-2.6.39-libre/drivers/gpio/langwell_gpio.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/gpio/langwell_gpio.c	2011-07-11 19:51:52.000000000 -0400
@@ -33,6 +33,7 @@
 #include <linux/io.h>
 #include <linux/gpio.h>
 #include <linux/slab.h>
+#include <linux/pm_runtime.h>
 
 /*
  * Langwell chip has 64 pins and thus there are 2 32bit registers to control
@@ -63,6 +64,7 @@
 	void				*reg_base;
 	spinlock_t			lock;
 	unsigned			irq_base;
+	struct pci_dev			*pdev;
 };
 
 static void __iomem *gpio_reg(struct gpio_chip *chip, unsigned offset,
@@ -104,11 +106,18 @@
 	u32 value;
 	unsigned long flags;
 
+	if (lnw->pdev)
+		pm_runtime_get(&lnw->pdev->dev);
+
 	spin_lock_irqsave(&lnw->lock, flags);
 	value = readl(gpdr);
 	value &= ~BIT(offset % 32);
 	writel(value, gpdr);
 	spin_unlock_irqrestore(&lnw->lock, flags);
+
+	if (lnw->pdev)
+		pm_runtime_put(&lnw->pdev->dev);
+
 	return 0;
 }
 
@@ -120,11 +129,19 @@
 	unsigned long flags;
 
 	lnw_gpio_set(chip, offset, value);
+
+	if (lnw->pdev)
+		pm_runtime_get(&lnw->pdev->dev);
+
 	spin_lock_irqsave(&lnw->lock, flags);
 	value = readl(gpdr);
-	value |= BIT(offset % 32);;
+	value |= BIT(offset % 32);
 	writel(value, gpdr);
 	spin_unlock_irqrestore(&lnw->lock, flags);
+
+	if (lnw->pdev)
+		pm_runtime_put(&lnw->pdev->dev);
+
 	return 0;
 }
 
@@ -145,6 +162,10 @@
 
 	if (gpio >= lnw->chip.ngpio)
 		return -EINVAL;
+
+	if (lnw->pdev)
+		pm_runtime_get(&lnw->pdev->dev);
+
 	spin_lock_irqsave(&lnw->lock, flags);
 	if (type & IRQ_TYPE_EDGE_RISING)
 		value = readl(grer) | BIT(gpio % 32);
@@ -159,6 +180,9 @@
 	writel(value, gfer);
 	spin_unlock_irqrestore(&lnw->lock, flags);
 
+	if (lnw->pdev)
+		pm_runtime_put(&lnw->pdev->dev);
+
 	return 0;
 }
 
@@ -199,7 +223,7 @@
 		gedr = gpio_reg(&lnw->chip, base, GEDR);
 		pending = readl(gedr);
 		while (pending) {
-			gpio = __ffs(pending) - 1;
+			gpio = __ffs(pending);
 			mask = BIT(gpio);
 			pending &= ~mask;
 			/* Clear before handling so we can't lose an edge */
@@ -211,6 +235,39 @@
 	chip->irq_eoi(data);
 }
 
+#ifdef CONFIG_PM
+static int lnw_gpio_runtime_resume(struct device *dev)
+{
+	return 0;
+}
+
+static int lnw_gpio_runtime_suspend(struct device *dev)
+{
+	return 0;
+}
+
+static int lnw_gpio_runtime_idle(struct device *dev)
+{
+	int err = pm_schedule_suspend(dev, 500);
+
+	if (!err)
+		return 0;
+
+	return -EBUSY;
+}
+
+#else
+#define lnw_gpio_runtime_suspend	NULL
+#define lnw_gpio_runtime_resume		NULL
+#define lnw_gpio_runtime_idle		NULL
+#endif
+
+static const struct dev_pm_ops lnw_gpio_pm_ops = {
+	.runtime_suspend = lnw_gpio_runtime_suspend,
+	.runtime_resume = lnw_gpio_runtime_resume,
+	.runtime_idle = lnw_gpio_runtime_idle,
+};
+
 static int __devinit lnw_gpio_probe(struct pci_dev *pdev,
 			const struct pci_device_id *id)
 {
@@ -270,6 +327,7 @@
 	lnw->chip.base = gpio_base;
 	lnw->chip.ngpio = id->driver_data;
 	lnw->chip.can_sleep = 0;
+	lnw->pdev = pdev;
 	pci_set_drvdata(pdev, lnw);
 	retval = gpiochip_add(&lnw->chip);
 	if (retval) {
@@ -285,6 +343,10 @@
 	}
 
 	spin_lock_init(&lnw->lock);
+
+	pm_runtime_put_noidle(&pdev->dev);
+	pm_runtime_allow(&pdev->dev);
+
 	goto done;
 err5:
 	kfree(lnw);
@@ -302,6 +364,9 @@
 	.name		= "langwell_gpio",
 	.id_table	= lnw_gpio_ids,
 	.probe		= lnw_gpio_probe,
+	.driver		= {
+		.pm	= &lnw_gpio_pm_ops,
+	},
 };
 
 
diff -druN linux-2.6.39-libre/drivers/gpio/Makefile linux-3.0-rc7-libre/drivers/gpio/Makefile
--- linux-2.6.39-libre/drivers/gpio/Makefile	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/gpio/Makefile	2011-07-11 19:51:52.000000000 -0400
@@ -1,8 +1,4 @@
-# generic gpio support: dedicated expander chips, etc
-#
-# NOTE: platform-specific GPIO drivers don't belong in the
-# drivers/gpio directory; put them with other platform setup
-# code, IRQ controllers, board init, etc.
+# generic gpio support: platform drivers, dedicated expander chips, etc
 
 ccflags-$(CONFIG_DEBUG_GPIO)	+= -DDEBUG
 
@@ -10,7 +6,12 @@
 
 obj-$(CONFIG_GPIO_ADP5520)	+= adp5520-gpio.o
 obj-$(CONFIG_GPIO_ADP5588)	+= adp5588-gpio.o
+obj-$(CONFIG_GPIO_BASIC_MMIO_CORE)	+= basic_mmio_gpio.o
 obj-$(CONFIG_GPIO_BASIC_MMIO)	+= basic_mmio_gpio.o
+obj-$(CONFIG_GPIO_EXYNOS4)	+= gpio-exynos4.o
+obj-$(CONFIG_GPIO_PLAT_SAMSUNG)	+= gpio-plat-samsung.o
+obj-$(CONFIG_GPIO_S5PC100)	+= gpio-s5pc100.o
+obj-$(CONFIG_GPIO_S5PV210)	+= gpio-s5pv210.o
 obj-$(CONFIG_GPIO_LANGWELL)	+= langwell_gpio.o
 obj-$(CONFIG_GPIO_MAX730X)	+= max730x.o
 obj-$(CONFIG_GPIO_MAX7300)	+= max7300.o
@@ -19,6 +20,7 @@
 obj-$(CONFIG_GPIO_MC33880)	+= mc33880.o
 obj-$(CONFIG_GPIO_MCP23S08)	+= mcp23s08.o
 obj-$(CONFIG_GPIO_74X164)	+= 74x164.o
+obj-$(CONFIG_ARCH_OMAP)         += gpio-omap.o
 obj-$(CONFIG_GPIO_PCA953X)	+= pca953x.o
 obj-$(CONFIG_GPIO_PCF857X)	+= pcf857x.o
 obj-$(CONFIG_GPIO_PCH)		+= pch_gpio.o
@@ -37,9 +39,12 @@
 obj-$(CONFIG_GPIO_WM8350)	+= wm8350-gpiolib.o
 obj-$(CONFIG_GPIO_WM8994)	+= wm8994-gpio.o
 obj-$(CONFIG_GPIO_SCH)		+= sch_gpio.o
+obj-$(CONFIG_MACH_U300)		+= gpio-u300.o
+obj-$(CONFIG_PLAT_NOMADIK)	+= gpio-nomadik.o
 obj-$(CONFIG_GPIO_RDC321X)	+= rdc321x-gpio.o
 obj-$(CONFIG_GPIO_JANZ_TTL)	+= janz-ttl.o
 obj-$(CONFIG_GPIO_SX150X)	+= sx150x.o
 obj-$(CONFIG_GPIO_VX855)	+= vx855_gpio.o
 obj-$(CONFIG_GPIO_ML_IOH)	+= ml_ioh_gpio.o
 obj-$(CONFIG_AB8500_GPIO)       += ab8500-gpio.o
+obj-$(CONFIG_GPIO_TPS65910)	+= tps65910-gpio.o
diff -druN linux-2.6.39-libre/drivers/gpio/ml_ioh_gpio.c linux-3.0-rc7-libre/drivers/gpio/ml_ioh_gpio.c
--- linux-2.6.39-libre/drivers/gpio/ml_ioh_gpio.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/gpio/ml_ioh_gpio.c	2011-07-11 19:51:52.000000000 -0400
@@ -15,6 +15,7 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
  */
 #include <linux/kernel.h>
+#include <linux/slab.h>
 #include <linux/pci.h>
 #include <linux/gpio.h>
 
@@ -138,6 +139,7 @@
 	return 0;
 }
 
+#ifdef CONFIG_PM
 /*
  * Save register configuration and disable interrupts.
  */
@@ -157,6 +159,7 @@
 	/* to store contents of PM register */
 	iowrite32(chip->ioh_gpio_reg.pm_reg, &chip->reg->regs[chip->ch].pm);
 }
+#endif
 
 static void ioh_gpio_setup(struct ioh_gpio *chip, int num_port)
 {
diff -druN linux-2.6.39-libre/drivers/gpio/pca953x.c linux-3.0-rc7-libre/drivers/gpio/pca953x.c
--- linux-2.6.39-libre/drivers/gpio/pca953x.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/gpio/pca953x.c	2011-07-11 19:51:52.000000000 -0400
@@ -24,33 +24,46 @@
 #include <linux/of_gpio.h>
 #endif
 
-#define PCA953X_INPUT          0
-#define PCA953X_OUTPUT         1
-#define PCA953X_INVERT         2
-#define PCA953X_DIRECTION      3
+#define PCA953X_INPUT		0
+#define PCA953X_OUTPUT		1
+#define PCA953X_INVERT		2
+#define PCA953X_DIRECTION	3
 
-#define PCA953X_GPIOS	       0x00FF
-#define PCA953X_INT	       0x0100
+#define PCA957X_IN		0
+#define PCA957X_INVRT		1
+#define PCA957X_BKEN		2
+#define PCA957X_PUPD		3
+#define PCA957X_CFG		4
+#define PCA957X_OUT		5
+#define PCA957X_MSK		6
+#define PCA957X_INTS		7
+
+#define PCA_GPIO_MASK		0x00FF
+#define PCA_INT			0x0100
+#define PCA953X_TYPE		0x1000
+#define PCA957X_TYPE		0x2000
 
 static const struct i2c_device_id pca953x_id[] = {
-	{ "pca9534", 8  | PCA953X_INT, },
-	{ "pca9535", 16 | PCA953X_INT, },
-	{ "pca9536", 4, },
-	{ "pca9537", 4  | PCA953X_INT, },
-	{ "pca9538", 8  | PCA953X_INT, },
-	{ "pca9539", 16 | PCA953X_INT, },
-	{ "pca9554", 8  | PCA953X_INT, },
-	{ "pca9555", 16 | PCA953X_INT, },
-	{ "pca9556", 8, },
-	{ "pca9557", 8, },
+	{ "pca9534", 8  | PCA953X_TYPE | PCA_INT, },
+	{ "pca9535", 16 | PCA953X_TYPE | PCA_INT, },
+	{ "pca9536", 4  | PCA953X_TYPE, },
+	{ "pca9537", 4  | PCA953X_TYPE | PCA_INT, },
+	{ "pca9538", 8  | PCA953X_TYPE | PCA_INT, },
+	{ "pca9539", 16 | PCA953X_TYPE | PCA_INT, },
+	{ "pca9554", 8  | PCA953X_TYPE | PCA_INT, },
+	{ "pca9555", 16 | PCA953X_TYPE | PCA_INT, },
+	{ "pca9556", 8  | PCA953X_TYPE, },
+	{ "pca9557", 8  | PCA953X_TYPE, },
+	{ "pca9574", 8  | PCA957X_TYPE | PCA_INT, },
+	{ "pca9575", 16 | PCA957X_TYPE | PCA_INT, },
 
-	{ "max7310", 8, },
-	{ "max7312", 16 | PCA953X_INT, },
-	{ "max7313", 16 | PCA953X_INT, },
-	{ "max7315", 8  | PCA953X_INT, },
-	{ "pca6107", 8  | PCA953X_INT, },
-	{ "tca6408", 8  | PCA953X_INT, },
-	{ "tca6416", 16 | PCA953X_INT, },
+	{ "max7310", 8  | PCA953X_TYPE, },
+	{ "max7312", 16 | PCA953X_TYPE | PCA_INT, },
+	{ "max7313", 16 | PCA953X_TYPE | PCA_INT, },
+	{ "max7315", 8  | PCA953X_TYPE | PCA_INT, },
+	{ "pca6107", 8  | PCA953X_TYPE | PCA_INT, },
+	{ "tca6408", 8  | PCA953X_TYPE | PCA_INT, },
+	{ "tca6416", 16 | PCA953X_TYPE | PCA_INT, },
 	/* NYET:  { "tca6424", 24, }, */
 	{ }
 };
@@ -75,16 +88,32 @@
 	struct pca953x_platform_data *dyn_pdata;
 	struct gpio_chip gpio_chip;
 	const char *const *names;
+	int	chip_type;
 };
 
 static int pca953x_write_reg(struct pca953x_chip *chip, int reg, uint16_t val)
 {
-	int ret;
+	int ret = 0;
 
 	if (chip->gpio_chip.ngpio <= 8)
 		ret = i2c_smbus_write_byte_data(chip->client, reg, val);
-	else
-		ret = i2c_smbus_write_word_data(chip->client, reg << 1, val);
+	else {
+		switch (chip->chip_type) {
+		case PCA953X_TYPE:
+			ret = i2c_smbus_write_word_data(chip->client,
+							reg << 1, val);
+			break;
+		case PCA957X_TYPE:
+			ret = i2c_smbus_write_byte_data(chip->client, reg << 1,
+							val & 0xff);
+			if (ret < 0)
+				break;
+			ret = i2c_smbus_write_byte_data(chip->client,
+							(reg << 1) + 1,
+							(val & 0xff00) >> 8);
+			break;
+		}
+	}
 
 	if (ret < 0) {
 		dev_err(&chip->client->dev, "failed writing register\n");
@@ -116,13 +145,22 @@
 {
 	struct pca953x_chip *chip;
 	uint16_t reg_val;
-	int ret;
+	int ret, offset = 0;
 
 	chip = container_of(gc, struct pca953x_chip, gpio_chip);
 
 	mutex_lock(&chip->i2c_lock);
 	reg_val = chip->reg_direction | (1u << off);
-	ret = pca953x_write_reg(chip, PCA953X_DIRECTION, reg_val);
+
+	switch (chip->chip_type) {
+	case PCA953X_TYPE:
+		offset = PCA953X_DIRECTION;
+		break;
+	case PCA957X_TYPE:
+		offset = PCA957X_CFG;
+		break;
+	}
+	ret = pca953x_write_reg(chip, offset, reg_val);
 	if (ret)
 		goto exit;
 
@@ -138,7 +176,7 @@
 {
 	struct pca953x_chip *chip;
 	uint16_t reg_val;
-	int ret;
+	int ret, offset = 0;
 
 	chip = container_of(gc, struct pca953x_chip, gpio_chip);
 
@@ -149,7 +187,15 @@
 	else
 		reg_val = chip->reg_output & ~(1u << off);
 
-	ret = pca953x_write_reg(chip, PCA953X_OUTPUT, reg_val);
+	switch (chip->chip_type) {
+	case PCA953X_TYPE:
+		offset = PCA953X_OUTPUT;
+		break;
+	case PCA957X_TYPE:
+		offset = PCA957X_OUT;
+		break;
+	}
+	ret = pca953x_write_reg(chip, offset, reg_val);
 	if (ret)
 		goto exit;
 
@@ -157,7 +203,15 @@
 
 	/* then direction */
 	reg_val = chip->reg_direction & ~(1u << off);
-	ret = pca953x_write_reg(chip, PCA953X_DIRECTION, reg_val);
+	switch (chip->chip_type) {
+	case PCA953X_TYPE:
+		offset = PCA953X_DIRECTION;
+		break;
+	case PCA957X_TYPE:
+		offset = PCA957X_CFG;
+		break;
+	}
+	ret = pca953x_write_reg(chip, offset, reg_val);
 	if (ret)
 		goto exit;
 
@@ -172,12 +226,20 @@
 {
 	struct pca953x_chip *chip;
 	uint16_t reg_val;
-	int ret;
+	int ret, offset = 0;
 
 	chip = container_of(gc, struct pca953x_chip, gpio_chip);
 
 	mutex_lock(&chip->i2c_lock);
-	ret = pca953x_read_reg(chip, PCA953X_INPUT, &reg_val);
+	switch (chip->chip_type) {
+	case PCA953X_TYPE:
+		offset = PCA953X_INPUT;
+		break;
+	case PCA957X_TYPE:
+		offset = PCA957X_IN;
+		break;
+	}
+	ret = pca953x_read_reg(chip, offset, &reg_val);
 	mutex_unlock(&chip->i2c_lock);
 	if (ret < 0) {
 		/* NOTE:  diagnostic already emitted; that's all we should
@@ -194,7 +256,7 @@
 {
 	struct pca953x_chip *chip;
 	uint16_t reg_val;
-	int ret;
+	int ret, offset = 0;
 
 	chip = container_of(gc, struct pca953x_chip, gpio_chip);
 
@@ -204,7 +266,15 @@
 	else
 		reg_val = chip->reg_output & ~(1u << off);
 
-	ret = pca953x_write_reg(chip, PCA953X_OUTPUT, reg_val);
+	switch (chip->chip_type) {
+	case PCA953X_TYPE:
+		offset = PCA953X_OUTPUT;
+		break;
+	case PCA957X_TYPE:
+		offset = PCA957X_OUT;
+		break;
+	}
+	ret = pca953x_write_reg(chip, offset, reg_val);
 	if (ret)
 		goto exit;
 
@@ -322,9 +392,17 @@
 	uint16_t old_stat;
 	uint16_t pending;
 	uint16_t trigger;
-	int ret;
+	int ret, offset = 0;
 
-	ret = pca953x_read_reg(chip, PCA953X_INPUT, &cur_stat);
+	switch (chip->chip_type) {
+	case PCA953X_TYPE:
+		offset = PCA953X_INPUT;
+		break;
+	case PCA957X_TYPE:
+		offset = PCA957X_IN;
+		break;
+	}
+	ret = pca953x_read_reg(chip, offset, &cur_stat);
 	if (ret)
 		return 0;
 
@@ -372,14 +450,21 @@
 {
 	struct i2c_client *client = chip->client;
 	struct pca953x_platform_data *pdata = client->dev.platform_data;
-	int ret;
+	int ret, offset = 0;
 
 	if (pdata->irq_base != -1
-			&& (id->driver_data & PCA953X_INT)) {
+			&& (id->driver_data & PCA_INT)) {
 		int lvl;
 
-		ret = pca953x_read_reg(chip, PCA953X_INPUT,
-				       &chip->irq_stat);
+		switch (chip->chip_type) {
+		case PCA953X_TYPE:
+			offset = PCA953X_INPUT;
+			break;
+		case PCA957X_TYPE:
+			offset = PCA957X_IN;
+			break;
+		}
+		ret = pca953x_read_reg(chip, offset, &chip->irq_stat);
 		if (ret)
 			goto out_failed;
 
@@ -397,7 +482,7 @@
 
 			irq_set_chip_data(irq, chip);
 			irq_set_chip_and_handler(irq, &pca953x_irq_chip,
-						 handle_edge_irq);
+						 handle_simple_irq);
 #ifdef CONFIG_ARM
 			set_irq_flags(irq, IRQF_VALID);
 #else
@@ -439,7 +524,7 @@
 	struct i2c_client *client = chip->client;
 	struct pca953x_platform_data *pdata = client->dev.platform_data;
 
-	if (pdata->irq_base != -1 && (id->driver_data & PCA953X_INT))
+	if (pdata->irq_base != -1 && (id->driver_data & PCA_INT))
 		dev_warn(&client->dev, "interrupt support not compiled in\n");
 
 	return 0;
@@ -499,12 +584,65 @@
 }
 #endif
 
+static int __devinit device_pca953x_init(struct pca953x_chip *chip, int invert)
+{
+	int ret;
+
+	ret = pca953x_read_reg(chip, PCA953X_OUTPUT, &chip->reg_output);
+	if (ret)
+		goto out;
+
+	ret = pca953x_read_reg(chip, PCA953X_DIRECTION,
+			       &chip->reg_direction);
+	if (ret)
+		goto out;
+
+	/* set platform specific polarity inversion */
+	ret = pca953x_write_reg(chip, PCA953X_INVERT, invert);
+	if (ret)
+		goto out;
+	return 0;
+out:
+	return ret;
+}
+
+static int __devinit device_pca957x_init(struct pca953x_chip *chip, int invert)
+{
+	int ret;
+	uint16_t val = 0;
+
+	/* Let every port in proper state, that could save power */
+	pca953x_write_reg(chip, PCA957X_PUPD, 0x0);
+	pca953x_write_reg(chip, PCA957X_CFG, 0xffff);
+	pca953x_write_reg(chip, PCA957X_OUT, 0x0);
+
+	ret = pca953x_read_reg(chip, PCA957X_IN, &val);
+	if (ret)
+		goto out;
+	ret = pca953x_read_reg(chip, PCA957X_OUT, &chip->reg_output);
+	if (ret)
+		goto out;
+	ret = pca953x_read_reg(chip, PCA957X_CFG, &chip->reg_direction);
+	if (ret)
+		goto out;
+
+	/* set platform specific polarity inversion */
+	pca953x_write_reg(chip, PCA957X_INVRT, invert);
+
+	/* To enable register 6, 7 to controll pull up and pull down */
+	pca953x_write_reg(chip, PCA957X_BKEN, 0x202);
+
+	return 0;
+out:
+	return ret;
+}
+
 static int __devinit pca953x_probe(struct i2c_client *client,
 				   const struct i2c_device_id *id)
 {
 	struct pca953x_platform_data *pdata;
 	struct pca953x_chip *chip;
-	int ret;
+	int ret = 0;
 
 	chip = kzalloc(sizeof(struct pca953x_chip), GFP_KERNEL);
 	if (chip == NULL)
@@ -531,25 +669,20 @@
 	chip->gpio_start = pdata->gpio_base;
 
 	chip->names = pdata->names;
+	chip->chip_type = id->driver_data & (PCA953X_TYPE | PCA957X_TYPE);
 
 	mutex_init(&chip->i2c_lock);
 
 	/* 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_GPIOS);
-
-	ret = pca953x_read_reg(chip, PCA953X_OUTPUT, &chip->reg_output);
-	if (ret)
-		goto out_failed;
-
-	ret = pca953x_read_reg(chip, PCA953X_DIRECTION, &chip->reg_direction);
-	if (ret)
-		goto out_failed;
+	pca953x_setup_gpio(chip, id->driver_data & PCA_GPIO_MASK);
 
-	/* set platform specific polarity inversion */
-	ret = pca953x_write_reg(chip, PCA953X_INVERT, pdata->invert);
-	if (ret)
+	if (chip->chip_type == PCA953X_TYPE)
+		device_pca953x_init(chip, pdata->invert);
+	else if (chip->chip_type == PCA957X_TYPE)
+		device_pca957x_init(chip, pdata->invert);
+	else
 		goto out_failed;
 
 	ret = pca953x_irq_setup(chip, id);
diff -druN linux-2.6.39-libre/drivers/gpio/pch_gpio.c linux-3.0-rc7-libre/drivers/gpio/pch_gpio.c
--- linux-2.6.39-libre/drivers/gpio/pch_gpio.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/gpio/pch_gpio.c	2011-07-11 19:51:52.000000000 -0400
@@ -283,8 +283,10 @@
 #define pch_gpio_resume NULL
 #endif
 
+#define PCI_VENDOR_ID_ROHM             0x10DB
 static DEFINE_PCI_DEVICE_TABLE(pch_gpio_pcidev_id) = {
 	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x8803) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_ROHM, 0x8014) },
 	{ 0, }
 };
 MODULE_DEVICE_TABLE(pci, pch_gpio_pcidev_id);
diff -druN linux-2.6.39-libre/drivers/gpio/rdc321x-gpio.c linux-3.0-rc7-libre/drivers/gpio/rdc321x-gpio.c
--- linux-2.6.39-libre/drivers/gpio/rdc321x-gpio.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/gpio/rdc321x-gpio.c	2011-07-11 19:51:52.000000000 -0400
@@ -27,7 +27,6 @@
 #include <linux/pci.h>
 #include <linux/gpio.h>
 #include <linux/mfd/rdc321x.h>
-#include <linux/mfd/core.h>
 #include <linux/slab.h>
 
 struct rdc321x_gpio {
@@ -136,7 +135,7 @@
 	struct rdc321x_gpio *rdc321x_gpio_dev;
 	struct rdc321x_gpio_pdata *pdata;
 
-	pdata = mfd_get_data(pdev);
+	pdata = pdev->dev.platform_data;
 	if (!pdata) {
 		dev_err(&pdev->dev, "no platform data supplied\n");
 		return -ENODEV;
diff -druN linux-2.6.39-libre/drivers/gpio/timbgpio.c linux-3.0-rc7-libre/drivers/gpio/timbgpio.c
--- linux-2.6.39-libre/drivers/gpio/timbgpio.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/gpio/timbgpio.c	2011-07-11 19:51:52.000000000 -0400
@@ -23,7 +23,6 @@
 #include <linux/module.h>
 #include <linux/gpio.h>
 #include <linux/platform_device.h>
-#include <linux/mfd/core.h>
 #include <linux/irq.h>
 #include <linux/io.h>
 #include <linux/timb_gpio.h>
@@ -229,7 +228,7 @@
 	struct gpio_chip *gc;
 	struct timbgpio *tgpio;
 	struct resource *iomem;
-	struct timbgpio_platform_data *pdata = mfd_get_data(pdev);
+	struct timbgpio_platform_data *pdata = pdev->dev.platform_data;
 	int irq = platform_get_irq(pdev, 0);
 
 	if (!pdata || pdata->nr_pins > 32) {
@@ -320,13 +319,14 @@
 static int __devexit timbgpio_remove(struct platform_device *pdev)
 {
 	int err;
+	struct timbgpio_platform_data *pdata = pdev->dev.platform_data;
 	struct timbgpio *tgpio = platform_get_drvdata(pdev);
 	struct resource *iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	int irq = platform_get_irq(pdev, 0);
 
 	if (irq >= 0 && tgpio->irq_base > 0) {
 		int i;
-		for (i = 0; i < tgpio->gpio.ngpio; i++) {
+		for (i = 0; i < pdata->nr_pins; i++) {
 			irq_set_chip(tgpio->irq_base + i, NULL);
 			irq_set_chip_data(tgpio->irq_base + i, NULL);
 		}
diff -druN linux-2.6.39-libre/drivers/gpio/tps65910-gpio.c linux-3.0-rc7-libre/drivers/gpio/tps65910-gpio.c
--- linux-2.6.39-libre/drivers/gpio/tps65910-gpio.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/gpio/tps65910-gpio.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,102 @@
+/*
+ * tps65910-gpio.c  --  TI TPS6591x
+ *
+ * Copyright 2010 Texas Instruments Inc.
+ *
+ * Author: Graeme Gregory <gg@slimlogic.co.uk>
+ * Author: Jorge Eduardo Candelaria jedu@slimlogic.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.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/errno.h>
+#include <linux/gpio.h>
+#include <linux/i2c.h>
+#include <linux/mfd/tps65910.h>
+
+static int tps65910_gpio_get(struct gpio_chip *gc, unsigned offset)
+{
+	struct tps65910 *tps65910 = container_of(gc, struct tps65910, gpio);
+	uint8_t val;
+
+	tps65910->read(tps65910, TPS65910_GPIO0 + offset, 1, &val);
+
+	if (val & GPIO_STS_MASK)
+		return 1;
+
+	return 0;
+}
+
+static void tps65910_gpio_set(struct gpio_chip *gc, unsigned offset,
+			      int value)
+{
+	struct tps65910 *tps65910 = container_of(gc, struct tps65910, gpio);
+
+	if (value)
+		tps65910_set_bits(tps65910, TPS65910_GPIO0 + offset,
+						GPIO_SET_MASK);
+	else
+		tps65910_clear_bits(tps65910, TPS65910_GPIO0 + offset,
+						GPIO_SET_MASK);
+}
+
+static int tps65910_gpio_output(struct gpio_chip *gc, unsigned offset,
+				int value)
+{
+	struct tps65910 *tps65910 = container_of(gc, struct tps65910, gpio);
+
+	/* Set the initial value */
+	tps65910_gpio_set(gc, 0, value);
+
+	return tps65910_set_bits(tps65910, TPS65910_GPIO0 + offset,
+						GPIO_CFG_MASK);
+}
+
+static int tps65910_gpio_input(struct gpio_chip *gc, unsigned offset)
+{
+	struct tps65910 *tps65910 = container_of(gc, struct tps65910, gpio);
+
+	return tps65910_clear_bits(tps65910, TPS65910_GPIO0 + offset,
+						GPIO_CFG_MASK);
+}
+
+void tps65910_gpio_init(struct tps65910 *tps65910, int gpio_base)
+{
+	int ret;
+
+	if (!gpio_base)
+		return;
+
+	tps65910->gpio.owner		= THIS_MODULE;
+	tps65910->gpio.label		= tps65910->i2c_client->name;
+	tps65910->gpio.dev		= tps65910->dev;
+	tps65910->gpio.base		= gpio_base;
+
+	switch(tps65910_chip_id(tps65910)) {
+	case TPS65910:
+		tps65910->gpio.ngpio	= 6;
+		break;
+	case TPS65911:
+		tps65910->gpio.ngpio	= 9;
+		break;
+	default:
+		return;
+	}
+	tps65910->gpio.can_sleep	= 1;
+
+	tps65910->gpio.direction_input	= tps65910_gpio_input;
+	tps65910->gpio.direction_output	= tps65910_gpio_output;
+	tps65910->gpio.set		= tps65910_gpio_set;
+	tps65910->gpio.get		= tps65910_gpio_get;
+
+	ret = gpiochip_add(&tps65910->gpio);
+
+	if (ret)
+		dev_warn(tps65910->dev, "GPIO registration failed: %d\n", ret);
+}
diff -druN linux-2.6.39-libre/drivers/gpio/vx855_gpio.c linux-3.0-rc7-libre/drivers/gpio/vx855_gpio.c
--- linux-2.6.39-libre/drivers/gpio/vx855_gpio.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/gpio/vx855_gpio.c	2011-07-11 19:51:52.000000000 -0400
@@ -26,6 +26,7 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/gpio.h>
+#include <linux/slab.h>
 #include <linux/device.h>
 #include <linux/platform_device.h>
 #include <linux/pci.h>
diff -druN linux-2.6.39-libre/drivers/gpu/drm/drm_bufs.c linux-3.0-rc7-libre/drivers/gpu/drm/drm_bufs.c
--- linux-2.6.39-libre/drivers/gpu/drm/drm_bufs.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/gpu/drm/drm_bufs.c	2011-07-11 19:51:52.000000000 -0400
@@ -46,10 +46,11 @@
 	list_for_each_entry(entry, &dev->maplist, head) {
 		/*
 		 * Because the kernel-userspace ABI is fixed at a 32-bit offset
-		 * while PCI resources may live above that, we ignore the map
-		 * offset for maps of type _DRM_FRAMEBUFFER or _DRM_REGISTERS.
-		 * It is assumed that each driver will have only one resource of
-		 * each type.
+		 * while PCI resources may live above that, we only compare the
+		 * lower 32 bits of the map offset for maps of type
+		 * _DRM_FRAMEBUFFER or _DRM_REGISTERS.
+		 * It is assumed that if a driver have more than one resource
+		 * of each type, the lower 32 bits are different.
 		 */
 		if (!entry->map ||
 		    map->type != entry->map->type ||
@@ -59,9 +60,12 @@
 		case _DRM_SHM:
 			if (map->flags != _DRM_CONTAINS_LOCK)
 				break;
+			return entry;
 		case _DRM_REGISTERS:
 		case _DRM_FRAME_BUFFER:
-			return entry;
+			if ((entry->map->offset & 0xffffffff) ==
+			    (map->offset & 0xffffffff))
+				return entry;
 		default: /* Make gcc happy */
 			;
 		}
@@ -183,9 +187,6 @@
 			return -EINVAL;
 		}
 #endif
-#ifdef __alpha__
-		map->offset += dev->hose->mem_space->start;
-#endif
 		/* Some drivers preinitialize some maps, without the X Server
 		 * needing to be aware of it.  Therefore, we just return success
 		 * when the server tries to create a duplicate map.
diff -druN linux-2.6.39-libre/drivers/gpu/drm/drm_crtc.c linux-3.0-rc7-libre/drivers/gpu/drm/drm_crtc.c
--- linux-2.6.39-libre/drivers/gpu/drm/drm_crtc.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/gpu/drm/drm_crtc.c	2011-07-11 19:51:52.000000000 -0400
@@ -886,9 +886,6 @@
 	total_objects += dev->mode_config.num_connector;
 	total_objects += dev->mode_config.num_encoder;
 
-	if (total_objects == 0)
-		return -EINVAL;
-
 	group->id_list = kzalloc(total_objects * sizeof(uint32_t), GFP_KERNEL);
 	if (!group->id_list)
 		return -ENOMEM;
@@ -1113,7 +1110,7 @@
 	if (card_res->count_fbs >= fb_count) {
 		copied = 0;
 		fb_id = (uint32_t __user *)(unsigned long)card_res->fb_id_ptr;
-		list_for_each_entry(fb, &file_priv->fbs, head) {
+		list_for_each_entry(fb, &file_priv->fbs, filp_head) {
 			if (put_user(fb->base.id, fb_id + copied)) {
 				ret = -EFAULT;
 				goto out;
diff -druN linux-2.6.39-libre/drivers/gpu/drm/drm_edid.c linux-3.0-rc7-libre/drivers/gpu/drm/drm_edid.c
--- linux-2.6.39-libre/drivers/gpu/drm/drm_edid.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/gpu/drm/drm_edid.c	2011-07-11 19:51:52.000000000 -0400
@@ -184,9 +184,9 @@
 
 bad:
 	if (raw_edid) {
-		DRM_ERROR("Raw EDID:\n");
+		printk(KERN_ERR "Raw EDID:\n");
 		print_hex_dump_bytes(KERN_ERR, DUMP_PREFIX_NONE, raw_edid, EDID_LENGTH);
-		printk("\n");
+		printk(KERN_ERR "\n");
 	}
 	return 0;
 }
@@ -258,6 +258,17 @@
 	return ret == 2 ? 0 : -1;
 }
 
+static bool drm_edid_is_zero(u8 *in_edid, int length)
+{
+	int i;
+	u32 *raw_edid = (u32 *)in_edid;
+
+	for (i = 0; i < length / 4; i++)
+		if (*(raw_edid + i) != 0)
+			return false;
+	return true;
+}
+
 static u8 *
 drm_do_get_edid(struct drm_connector *connector, struct i2c_adapter *adapter)
 {
@@ -273,6 +284,10 @@
 			goto out;
 		if (drm_edid_block_valid(block))
 			break;
+		if (i == 0 && drm_edid_is_zero(block, EDID_LENGTH)) {
+			connector->null_edid_counter++;
+			goto carp;
+		}
 	}
 	if (i == 4)
 		goto carp;
@@ -1413,6 +1428,64 @@
 EXPORT_SYMBOL(drm_detect_monitor_audio);
 
 /**
+ * drm_add_display_info - pull display info out if present
+ * @edid: EDID data
+ * @info: display info (attached to connector)
+ *
+ * Grab any available display info and stuff it into the drm_display_info
+ * structure that's part of the connector.  Useful for tracking bpp and
+ * color spaces.
+ */
+static void drm_add_display_info(struct edid *edid,
+				 struct drm_display_info *info)
+{
+	info->width_mm = edid->width_cm * 10;
+	info->height_mm = edid->height_cm * 10;
+
+	/* driver figures it out in this case */
+	info->bpc = 0;
+	info->color_formats = 0;
+
+	/* Only defined for 1.4 with digital displays */
+	if (edid->revision < 4)
+		return;
+
+	if (!(edid->input & DRM_EDID_INPUT_DIGITAL))
+		return;
+
+	switch (edid->input & DRM_EDID_DIGITAL_DEPTH_MASK) {
+	case DRM_EDID_DIGITAL_DEPTH_6:
+		info->bpc = 6;
+		break;
+	case DRM_EDID_DIGITAL_DEPTH_8:
+		info->bpc = 8;
+		break;
+	case DRM_EDID_DIGITAL_DEPTH_10:
+		info->bpc = 10;
+		break;
+	case DRM_EDID_DIGITAL_DEPTH_12:
+		info->bpc = 12;
+		break;
+	case DRM_EDID_DIGITAL_DEPTH_14:
+		info->bpc = 14;
+		break;
+	case DRM_EDID_DIGITAL_DEPTH_16:
+		info->bpc = 16;
+		break;
+	case DRM_EDID_DIGITAL_DEPTH_UNDEF:
+	default:
+		info->bpc = 0;
+		break;
+	}
+
+	info->color_formats = DRM_COLOR_FORMAT_RGB444;
+	if (info->color_formats & DRM_EDID_FEATURE_RGB_YCRCB444)
+		info->color_formats = DRM_COLOR_FORMAT_YCRCB444;
+	if (info->color_formats & DRM_EDID_FEATURE_RGB_YCRCB422)
+		info->color_formats = DRM_COLOR_FORMAT_YCRCB422;
+}
+
+/**
  * drm_add_edid_modes - add modes from EDID data, if available
  * @connector: connector we're probing
  * @edid: edid data
@@ -1460,8 +1533,7 @@
 	if (quirks & (EDID_QUIRK_PREFER_LARGE_60 | EDID_QUIRK_PREFER_LARGE_75))
 		edid_fixup_preferred(connector, quirks);
 
-	connector->display_info.width_mm = edid->width_cm * 10;
-	connector->display_info.height_mm = edid->height_cm * 10;
+	drm_add_display_info(edid, &connector->display_info);
 
 	return num_modes;
 }
diff -druN linux-2.6.39-libre/drivers/gpu/drm/drm_fb_helper.c linux-3.0-rc7-libre/drivers/gpu/drm/drm_fb_helper.c
--- linux-2.6.39-libre/drivers/gpu/drm/drm_fb_helper.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/gpu/drm/drm_fb_helper.c	2011-07-11 19:51:52.000000000 -0400
@@ -70,174 +70,50 @@
 }
 EXPORT_SYMBOL(drm_fb_helper_single_add_all_connectors);
 
-/**
- * drm_fb_helper_connector_parse_command_line - parse command line for connector
- * @connector - connector to parse line for
- * @mode_option - per connector mode option
- *
- * This parses the connector specific then generic command lines for
- * modes and options to configure the connector.
- *
- * This uses the same parameters as the fb modedb.c, except for extra
- *	<xres>x<yres>[M][R][-<bpp>][@<refresh>][i][m][eDd]
- *
- * enable/enable Digital/disable bit at the end
- */
-static bool drm_fb_helper_connector_parse_command_line(struct drm_fb_helper_connector *fb_helper_conn,
-						       const char *mode_option)
-{
-	const char *name;
-	unsigned int namelen;
-	int res_specified = 0, bpp_specified = 0, refresh_specified = 0;
-	unsigned int xres = 0, yres = 0, bpp = 32, refresh = 0;
-	int yres_specified = 0, cvt = 0, rb = 0, interlace = 0, margins = 0;
-	int i;
-	enum drm_connector_force force = DRM_FORCE_UNSPECIFIED;
-	struct drm_fb_helper_cmdline_mode *cmdline_mode;
-	struct drm_connector *connector;
-
-	if (!fb_helper_conn)
-		return false;
-	connector = fb_helper_conn->connector;
-
-	cmdline_mode = &fb_helper_conn->cmdline_mode;
-	if (!mode_option)
-		mode_option = fb_mode_option;
-
-	if (!mode_option) {
-		cmdline_mode->specified = false;
-		return false;
-	}
-
-	name = mode_option;
-	namelen = strlen(name);
-	for (i = namelen-1; i >= 0; i--) {
-		switch (name[i]) {
-		case '@':
-			namelen = i;
-			if (!refresh_specified && !bpp_specified &&
-			    !yres_specified) {
-				refresh = simple_strtol(&name[i+1], NULL, 10);
-				refresh_specified = 1;
-				if (cvt || rb)
-					cvt = 0;
-			} else
-				goto done;
-			break;
-		case '-':
-			namelen = i;
-			if (!bpp_specified && !yres_specified) {
-				bpp = simple_strtol(&name[i+1], NULL, 10);
-				bpp_specified = 1;
-				if (cvt || rb)
-					cvt = 0;
-			} else
-				goto done;
-			break;
-		case 'x':
-			if (!yres_specified) {
-				yres = simple_strtol(&name[i+1], NULL, 10);
-				yres_specified = 1;
-			} else
-				goto done;
-		case '0' ... '9':
-			break;
-		case 'M':
-			if (!yres_specified)
-				cvt = 1;
-			break;
-		case 'R':
-			if (cvt)
-				rb = 1;
-			break;
-		case 'm':
-			if (!cvt)
-				margins = 1;
-			break;
-		case 'i':
-			if (!cvt)
-				interlace = 1;
-			break;
-		case 'e':
-			force = DRM_FORCE_ON;
-			break;
-		case 'D':
-			if ((connector->connector_type != DRM_MODE_CONNECTOR_DVII) &&
-			    (connector->connector_type != DRM_MODE_CONNECTOR_HDMIB))
-				force = DRM_FORCE_ON;
-			else
-				force = DRM_FORCE_ON_DIGITAL;
-			break;
-		case 'd':
-			force = DRM_FORCE_OFF;
-			break;
-		default:
-			goto done;
-		}
-	}
-	if (i < 0 && yres_specified) {
-		xres = simple_strtol(name, NULL, 10);
-		res_specified = 1;
-	}
-done:
-
-	DRM_DEBUG_KMS("cmdline mode for connector %s %dx%d@%dHz%s%s%s\n",
-		drm_get_connector_name(connector), xres, yres,
-		(refresh) ? refresh : 60, (rb) ? " reduced blanking" :
-		"", (margins) ? " with margins" : "", (interlace) ?
-		" interlaced" : "");
-
-	if (force) {
-		const char *s;
-		switch (force) {
-		case DRM_FORCE_OFF: s = "OFF"; break;
-		case DRM_FORCE_ON_DIGITAL: s = "ON - dig"; break;
-		default:
-		case DRM_FORCE_ON: s = "ON"; break;
-		}
-
-		DRM_INFO("forcing %s connector %s\n",
-			 drm_get_connector_name(connector), s);
-		connector->force = force;
-	}
-
-	if (res_specified) {
-		cmdline_mode->specified = true;
-		cmdline_mode->xres = xres;
-		cmdline_mode->yres = yres;
-	}
-
-	if (refresh_specified) {
-		cmdline_mode->refresh_specified = true;
-		cmdline_mode->refresh = refresh;
-	}
-
-	if (bpp_specified) {
-		cmdline_mode->bpp_specified = true;
-		cmdline_mode->bpp = bpp;
-	}
-	cmdline_mode->rb = rb ? true : false;
-	cmdline_mode->cvt = cvt  ? true : false;
-	cmdline_mode->interlace = interlace ? true : false;
-
-	return true;
-}
-
 static int drm_fb_helper_parse_command_line(struct drm_fb_helper *fb_helper)
 {
 	struct drm_fb_helper_connector *fb_helper_conn;
 	int i;
 
 	for (i = 0; i < fb_helper->connector_count; i++) {
+		struct drm_cmdline_mode *mode;
+		struct drm_connector *connector;
 		char *option = NULL;
 
 		fb_helper_conn = fb_helper->connector_info[i];
+		connector = fb_helper_conn->connector;
+		mode = &fb_helper_conn->cmdline_mode;
 
 		/* do something on return - turn off connector maybe */
-		if (fb_get_options(drm_get_connector_name(fb_helper_conn->connector), &option))
+		if (fb_get_options(drm_get_connector_name(connector), &option))
 			continue;
 
-		drm_fb_helper_connector_parse_command_line(fb_helper_conn, option);
+		if (drm_mode_parse_command_line_for_connector(option,
+							      connector,
+							      mode)) {
+			if (mode->force) {
+				const char *s;
+				switch (mode->force) {
+				case DRM_FORCE_OFF: s = "OFF"; break;
+				case DRM_FORCE_ON_DIGITAL: s = "ON - dig"; break;
+				default:
+				case DRM_FORCE_ON: s = "ON"; break;
+				}
+
+				DRM_INFO("forcing %s connector %s\n",
+					 drm_get_connector_name(connector), s);
+				connector->force = mode->force;
+			}
+
+			DRM_DEBUG_KMS("cmdline mode for connector %s %dx%d@%dHz%s%s%s\n",
+				      drm_get_connector_name(connector),
+				      mode->xres, mode->yres,
+				      mode->refresh_specified ? mode->refresh : 60,
+				      mode->rb ? " reduced blanking" : "",
+				      mode->margins ? " with margins" : "",
+				      mode->interlace ?  " interlaced" : "");
+		}
+
 	}
 	return 0;
 }
@@ -901,7 +777,7 @@
 	/* first up get a count of crtcs now in use and new min/maxes width/heights */
 	for (i = 0; i < fb_helper->connector_count; i++) {
 		struct drm_fb_helper_connector *fb_helper_conn = fb_helper->connector_info[i];
-		struct drm_fb_helper_cmdline_mode *cmdline_mode;
+		struct drm_cmdline_mode *cmdline_mode;
 
 		cmdline_mode = &fb_helper_conn->cmdline_mode;
 
@@ -1123,7 +999,7 @@
 
 static bool drm_has_cmdline_mode(struct drm_fb_helper_connector *fb_connector)
 {
-	struct drm_fb_helper_cmdline_mode *cmdline_mode;
+	struct drm_cmdline_mode *cmdline_mode;
 	cmdline_mode = &fb_connector->cmdline_mode;
 	return cmdline_mode->specified;
 }
@@ -1131,7 +1007,7 @@
 static struct drm_display_mode *drm_pick_cmdline_mode(struct drm_fb_helper_connector *fb_helper_conn,
 						      int width, int height)
 {
-	struct drm_fb_helper_cmdline_mode *cmdline_mode;
+	struct drm_cmdline_mode *cmdline_mode;
 	struct drm_display_mode *mode = NULL;
 
 	cmdline_mode = &fb_helper_conn->cmdline_mode;
@@ -1163,19 +1039,8 @@
 	}
 
 create_mode:
-	if (cmdline_mode->cvt)
-		mode = drm_cvt_mode(fb_helper_conn->connector->dev,
-				    cmdline_mode->xres, cmdline_mode->yres,
-				    cmdline_mode->refresh_specified ? cmdline_mode->refresh : 60,
-				    cmdline_mode->rb, cmdline_mode->interlace,
-				    cmdline_mode->margins);
-	else
-		mode = drm_gtf_mode(fb_helper_conn->connector->dev,
-				    cmdline_mode->xres, cmdline_mode->yres,
-				    cmdline_mode->refresh_specified ? cmdline_mode->refresh : 60,
-				    cmdline_mode->interlace,
-				    cmdline_mode->margins);
-	drm_mode_set_crtcinfo(mode, CRTC_INTERLACE_HALVE_V);
+	mode = drm_mode_create_from_cmdline_mode(fb_helper_conn->connector->dev,
+						 cmdline_mode);
 	list_add(&mode->head, &fb_helper_conn->connector->modes);
 	return mode;
 }
diff -druN linux-2.6.39-libre/drivers/gpu/drm/drm_gem.c linux-3.0-rc7-libre/drivers/gpu/drm/drm_gem.c
--- linux-2.6.39-libre/drivers/gpu/drm/drm_gem.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/gpu/drm/drm_gem.c	2011-07-11 19:51:52.000000000 -0400
@@ -34,6 +34,7 @@
 #include <linux/module.h>
 #include <linux/mman.h>
 #include <linux/pagemap.h>
+#include <linux/shmem_fs.h>
 #include "drmP.h"
 
 /** @file drm_gem.c
diff -druN linux-2.6.39-libre/drivers/gpu/drm/drm_ioc32.c linux-3.0-rc7-libre/drivers/gpu/drm/drm_ioc32.c
--- linux-2.6.39-libre/drivers/gpu/drm/drm_ioc32.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/gpu/drm/drm_ioc32.c	2011-07-11 19:51:52.000000000 -0400
@@ -28,6 +28,7 @@
  * IN THE SOFTWARE.
  */
 #include <linux/compat.h>
+#include <linux/ratelimit.h>
 
 #include "drmP.h"
 #include "drm_core.h"
@@ -253,10 +254,10 @@
 		return -EFAULT;
 
 	m32.handle = (unsigned long)handle;
-	if (m32.handle != (unsigned long)handle && printk_ratelimit())
-		printk(KERN_ERR "compat_drm_addmap truncated handle"
-		       " %p for type %d offset %x\n",
-		       handle, m32.type, m32.offset);
+	if (m32.handle != (unsigned long)handle)
+		printk_ratelimited(KERN_ERR "compat_drm_addmap truncated handle"
+				   " %p for type %d offset %x\n",
+				   handle, m32.type, m32.offset);
 
 	if (copy_to_user(argp, &m32, sizeof(m32)))
 		return -EFAULT;
diff -druN linux-2.6.39-libre/drivers/gpu/drm/drm_irq.c linux-3.0-rc7-libre/drivers/gpu/drm/drm_irq.c
--- linux-2.6.39-libre/drivers/gpu/drm/drm_irq.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/gpu/drm/drm_irq.c	2011-07-11 19:51:52.000000000 -0400
@@ -684,10 +684,11 @@
 	 */
 	*vblank_time = ns_to_timeval(timeval_to_ns(&raw_time) - delta_ns);
 
-	DRM_DEBUG("crtc %d : v %d p(%d,%d)@ %d.%d -> %d.%d [e %d us, %d rep]\n",
-		  crtc, (int) vbl_status, hpos, vpos, raw_time.tv_sec,
-		  raw_time.tv_usec, vblank_time->tv_sec, vblank_time->tv_usec,
-		  (int) duration_ns/1000, i);
+	DRM_DEBUG("crtc %d : v %d p(%d,%d)@ %ld.%ld -> %ld.%ld [e %d us, %d rep]\n",
+		  crtc, (int)vbl_status, hpos, vpos,
+		  (long)raw_time.tv_sec, (long)raw_time.tv_usec,
+		  (long)vblank_time->tv_sec, (long)vblank_time->tv_usec,
+		  (int)duration_ns/1000, i);
 
 	vbl_status = DRM_VBLANKTIME_SCANOUTPOS_METHOD;
 	if (invbl)
diff -druN linux-2.6.39-libre/drivers/gpu/drm/drm_modes.c linux-3.0-rc7-libre/drivers/gpu/drm/drm_modes.c
--- linux-2.6.39-libre/drivers/gpu/drm/drm_modes.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/gpu/drm/drm_modes.c	2011-07-11 19:51:52.000000000 -0400
@@ -974,3 +974,159 @@
 	}
 }
 EXPORT_SYMBOL(drm_mode_connector_list_update);
+
+/**
+ * drm_mode_parse_command_line_for_connector - parse command line for connector
+ * @mode_option - per connector mode option
+ * @connector - connector to parse line for
+ *
+ * This parses the connector specific then generic command lines for
+ * modes and options to configure the connector.
+ *
+ * This uses the same parameters as the fb modedb.c, except for extra
+ *	<xres>x<yres>[M][R][-<bpp>][@<refresh>][i][m][eDd]
+ *
+ * enable/enable Digital/disable bit at the end
+ */
+bool drm_mode_parse_command_line_for_connector(const char *mode_option,
+					       struct drm_connector *connector,
+					       struct drm_cmdline_mode *mode)
+{
+	const char *name;
+	unsigned int namelen;
+	int res_specified = 0, bpp_specified = 0, refresh_specified = 0;
+	unsigned int xres = 0, yres = 0, bpp = 32, refresh = 0;
+	int yres_specified = 0, cvt = 0, rb = 0, interlace = 0, margins = 0;
+	int i;
+	enum drm_connector_force force = DRM_FORCE_UNSPECIFIED;
+
+#ifdef CONFIG_FB
+	if (!mode_option)
+		mode_option = fb_mode_option;
+#endif
+
+	if (!mode_option) {
+		mode->specified = false;
+		return false;
+	}
+
+	name = mode_option;
+	namelen = strlen(name);
+	for (i = namelen-1; i >= 0; i--) {
+		switch (name[i]) {
+		case '@':
+			namelen = i;
+			if (!refresh_specified && !bpp_specified &&
+			    !yres_specified) {
+				refresh = simple_strtol(&name[i+1], NULL, 10);
+				refresh_specified = 1;
+				if (cvt || rb)
+					cvt = 0;
+			} else
+				goto done;
+			break;
+		case '-':
+			namelen = i;
+			if (!bpp_specified && !yres_specified) {
+				bpp = simple_strtol(&name[i+1], NULL, 10);
+				bpp_specified = 1;
+				if (cvt || rb)
+					cvt = 0;
+			} else
+				goto done;
+			break;
+		case 'x':
+			if (!yres_specified) {
+				yres = simple_strtol(&name[i+1], NULL, 10);
+				yres_specified = 1;
+			} else
+				goto done;
+		case '0' ... '9':
+			break;
+		case 'M':
+			if (!yres_specified)
+				cvt = 1;
+			break;
+		case 'R':
+			if (cvt)
+				rb = 1;
+			break;
+		case 'm':
+			if (!cvt)
+				margins = 1;
+			break;
+		case 'i':
+			if (!cvt)
+				interlace = 1;
+			break;
+		case 'e':
+			force = DRM_FORCE_ON;
+			break;
+		case 'D':
+			if ((connector->connector_type != DRM_MODE_CONNECTOR_DVII) &&
+			    (connector->connector_type != DRM_MODE_CONNECTOR_HDMIB))
+				force = DRM_FORCE_ON;
+			else
+				force = DRM_FORCE_ON_DIGITAL;
+			break;
+		case 'd':
+			force = DRM_FORCE_OFF;
+			break;
+		default:
+			goto done;
+		}
+	}
+	if (i < 0 && yres_specified) {
+		xres = simple_strtol(name, NULL, 10);
+		res_specified = 1;
+	}
+done:
+	if (res_specified) {
+		mode->specified = true;
+		mode->xres = xres;
+		mode->yres = yres;
+	}
+
+	if (refresh_specified) {
+		mode->refresh_specified = true;
+		mode->refresh = refresh;
+	}
+
+	if (bpp_specified) {
+		mode->bpp_specified = true;
+		mode->bpp = bpp;
+	}
+	mode->rb = rb ? true : false;
+	mode->cvt = cvt  ? true : false;
+	mode->interlace = interlace ? true : false;
+	mode->force = force;
+
+	return true;
+}
+EXPORT_SYMBOL(drm_mode_parse_command_line_for_connector);
+
+struct drm_display_mode *
+drm_mode_create_from_cmdline_mode(struct drm_device *dev,
+				  struct drm_cmdline_mode *cmd)
+{
+	struct drm_display_mode *mode;
+
+	if (cmd->cvt)
+		mode = drm_cvt_mode(dev,
+				    cmd->xres, cmd->yres,
+				    cmd->refresh_specified ? cmd->refresh : 60,
+				    cmd->rb, cmd->interlace,
+				    cmd->margins);
+	else
+		mode = drm_gtf_mode(dev,
+				    cmd->xres, cmd->yres,
+				    cmd->refresh_specified ? cmd->refresh : 60,
+				    cmd->interlace,
+				    cmd->margins);
+	if (!mode)
+		return NULL;
+
+	drm_mode_set_crtcinfo(mode, CRTC_INTERLACE_HALVE_V);
+	return mode;
+}
+EXPORT_SYMBOL(drm_mode_create_from_cmdline_mode);
diff -druN linux-2.6.39-libre/drivers/gpu/drm/drm_pci.c linux-3.0-rc7-libre/drivers/gpu/drm/drm_pci.c
--- linux-2.6.39-libre/drivers/gpu/drm/drm_pci.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/gpu/drm/drm_pci.c	2011-07-11 19:51:52.000000000 -0400
@@ -251,7 +251,7 @@
 }
 
 
-int drm_pci_irq_by_busid(struct drm_device *dev, struct drm_irq_busid *p)
+static int drm_pci_irq_by_busid(struct drm_device *dev, struct drm_irq_busid *p)
 {
 	if ((p->busnum >> 8) != drm_get_pci_domain(dev) ||
 	    (p->busnum & 0xff) != dev->pdev->bus->number ||
@@ -292,6 +292,7 @@
 	.get_name = drm_pci_get_name,
 	.set_busid = drm_pci_set_busid,
 	.set_unique = drm_pci_set_unique,
+	.irq_by_busid = drm_pci_irq_by_busid,
 	.agp_init = drm_pci_agp_init,
 };
 
diff -druN linux-2.6.39-libre/drivers/gpu/drm/drm_stub.c linux-3.0-rc7-libre/drivers/gpu/drm/drm_stub.c
--- linux-2.6.39-libre/drivers/gpu/drm/drm_stub.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/gpu/drm/drm_stub.c	2011-07-11 19:51:52.000000000 -0400
@@ -62,6 +62,26 @@
 struct class *drm_class;
 struct proc_dir_entry *drm_proc_root;
 struct dentry *drm_debugfs_root;
+
+int drm_err(const char *func, const char *format, ...)
+{
+	struct va_format vaf;
+	va_list args;
+	int r;
+
+	va_start(args, format);
+
+	vaf.fmt = format;
+	vaf.va = &args;
+
+	r = printk(KERN_ERR "[" DRM_NAME ":%s] *ERROR* %pV", func, &vaf);
+
+	va_end(args);
+
+	return r;
+}
+EXPORT_SYMBOL(drm_err);
+
 void drm_ut_debug_printk(unsigned int request_level,
 			 const char *prefix,
 			 const char *function_name,
@@ -78,6 +98,7 @@
 	}
 }
 EXPORT_SYMBOL(drm_ut_debug_printk);
+
 static int drm_minor_get_id(struct drm_device *dev, int type)
 {
 	int new_id;
diff -druN linux-2.6.39-libre/drivers/gpu/drm/drm_vm.c linux-3.0-rc7-libre/drivers/gpu/drm/drm_vm.c
--- linux-2.6.39-libre/drivers/gpu/drm/drm_vm.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/gpu/drm/drm_vm.c	2011-07-11 19:51:52.000000000 -0400
@@ -526,7 +526,7 @@
 static resource_size_t drm_core_get_reg_ofs(struct drm_device *dev)
 {
 #ifdef __alpha__
-	return dev->hose->dense_mem_base - dev->hose->mem_space->start;
+	return dev->hose->dense_mem_base;
 #else
 	return 0;
 #endif
diff -druN linux-2.6.39-libre/drivers/gpu/drm/i915/i915_debugfs.c linux-3.0-rc7-libre/drivers/gpu/drm/i915/i915_debugfs.c
--- linux-2.6.39-libre/drivers/gpu/drm/i915/i915_debugfs.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/gpu/drm/i915/i915_debugfs.c	2011-07-11 19:51:52.000000000 -0400
@@ -106,11 +106,12 @@
     }
 }
 
-static const char *agp_type_str(int type)
+static const char *cache_level_str(int type)
 {
 	switch (type) {
-	case 0: return " uncached";
-	case 1: return " snooped";
+	case I915_CACHE_NONE: return " uncached";
+	case I915_CACHE_LLC: return " snooped (LLC)";
+	case I915_CACHE_LLC_MLC: return " snooped (LLC+MLC)";
 	default: return "";
 	}
 }
@@ -127,7 +128,7 @@
 		   obj->base.write_domain,
 		   obj->last_rendering_seqno,
 		   obj->last_fenced_seqno,
-		   agp_type_str(obj->agp_type == AGP_USER_CACHED_MEMORY),
+		   cache_level_str(obj->cache_level),
 		   obj->dirty ? " dirty" : "",
 		   obj->madv == I915_MADV_DONTNEED ? " purgeable" : "");
 	if (obj->base.name)
@@ -714,7 +715,7 @@
 			   dirty_flag(err->dirty),
 			   purgeable_flag(err->purgeable),
 			   ring_str(err->ring),
-			   agp_type_str(err->agp_type));
+			   cache_level_str(err->cache_level));
 
 		if (err->name)
 			seq_printf(m, " (name: %d)", err->name);
@@ -775,7 +776,7 @@
 	seq_printf(m, "  INSTPM: 0x%08x\n", error->instpm);
 	seq_printf(m, "  seqno: 0x%08x\n", error->seqno);
 
-	for (i = 0; i < 16; i++)
+	for (i = 0; i < dev_priv->num_fence_regs; i++)
 		seq_printf(m, "  fence[%d] = %08llx\n", i, error->fence[i]);
 
 	if (error->active_bo)
@@ -852,6 +853,7 @@
 	struct drm_info_node *node = (struct drm_info_node *) m->private;
 	struct drm_device *dev = node->minor->dev;
 	drm_i915_private_t *dev_priv = dev->dev_private;
+	int ret;
 
 	if (IS_GEN5(dev)) {
 		u16 rgvswctl = I915_READ16(MEMSWCTL);
@@ -873,7 +875,11 @@
 		int max_freq;
 
 		/* RPSTAT1 is in the GT power well */
-		__gen6_gt_force_wake_get(dev_priv);
+		ret = mutex_lock_interruptible(&dev->struct_mutex);
+		if (ret)
+			return ret;
+
+		gen6_gt_force_wake_get(dev_priv);
 
 		rpstat = I915_READ(GEN6_RPSTAT1);
 		rpupei = I915_READ(GEN6_RP_CUR_UP_EI);
@@ -883,6 +889,9 @@
 		rpcurdown = I915_READ(GEN6_RP_CUR_DOWN);
 		rpprevdown = I915_READ(GEN6_RP_PREV_DOWN);
 
+		gen6_gt_force_wake_put(dev_priv);
+		mutex_unlock(&dev->struct_mutex);
+
 		seq_printf(m, "GT_PERF_STATUS: 0x%08x\n", gt_perf_status);
 		seq_printf(m, "RPSTAT1: 0x%08x\n", rpstat);
 		seq_printf(m, "Render p-state ratio: %d\n",
@@ -917,8 +926,6 @@
 		max_freq = rp_state_cap & 0xff;
 		seq_printf(m, "Max non-overclocked (RP0) frequency: %dMHz\n",
 			   max_freq * 50);
-
-		__gen6_gt_force_wake_put(dev_priv);
 	} else {
 		seq_printf(m, "no P-state info available\n");
 	}
@@ -1058,6 +1065,9 @@
 		case FBC_MULTIPLE_PIPES:
 			seq_printf(m, "multiple pipes are enabled");
 			break;
+		case FBC_MODULE_PARAM:
+			seq_printf(m, "disabled per module param (default off)");
+			break;
 		default:
 			seq_printf(m, "unknown reason");
 		}
@@ -1186,6 +1196,46 @@
 	return 0;
 }
 
+static int i915_context_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;
+	int ret;
+
+	ret = mutex_lock_interruptible(&dev->mode_config.mutex);
+	if (ret)
+		return ret;
+
+	if (dev_priv->pwrctx) {
+		seq_printf(m, "power context ");
+		describe_obj(m, dev_priv->pwrctx);
+		seq_printf(m, "\n");
+	}
+
+	if (dev_priv->renderctx) {
+		seq_printf(m, "render context ");
+		describe_obj(m, dev_priv->renderctx);
+		seq_printf(m, "\n");
+	}
+
+	mutex_unlock(&dev->mode_config.mutex);
+
+	return 0;
+}
+
+static int i915_gen6_forcewake_count_info(struct seq_file *m, void *data)
+{
+	struct drm_info_node *node = (struct drm_info_node *) m->private;
+	struct drm_device *dev = node->minor->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	seq_printf(m, "forcewake count = %d\n",
+		   atomic_read(&dev_priv->forcewake_count));
+
+	return 0;
+}
+
 static int
 i915_wedged_open(struct inode *inode,
 		 struct file *filp)
@@ -1288,6 +1338,67 @@
 	return drm_add_fake_info_node(minor, ent, &i915_wedged_fops);
 }
 
+static int i915_forcewake_open(struct inode *inode, struct file *file)
+{
+	struct drm_device *dev = inode->i_private;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	int ret;
+
+	if (!IS_GEN6(dev))
+		return 0;
+
+	ret = mutex_lock_interruptible(&dev->struct_mutex);
+	if (ret)
+		return ret;
+	gen6_gt_force_wake_get(dev_priv);
+	mutex_unlock(&dev->struct_mutex);
+
+	return 0;
+}
+
+int i915_forcewake_release(struct inode *inode, struct file *file)
+{
+	struct drm_device *dev = inode->i_private;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	if (!IS_GEN6(dev))
+		return 0;
+
+	/*
+	 * It's bad that we can potentially hang userspace if struct_mutex gets
+	 * forever stuck.  However, if we cannot acquire this lock it means that
+	 * almost certainly the driver has hung, is not unload-able. Therefore
+	 * hanging here is probably a minor inconvenience not to be seen my
+	 * almost every user.
+	 */
+	mutex_lock(&dev->struct_mutex);
+	gen6_gt_force_wake_put(dev_priv);
+	mutex_unlock(&dev->struct_mutex);
+
+	return 0;
+}
+
+static const struct file_operations i915_forcewake_fops = {
+	.owner = THIS_MODULE,
+	.open = i915_forcewake_open,
+	.release = i915_forcewake_release,
+};
+
+static int i915_forcewake_create(struct dentry *root, struct drm_minor *minor)
+{
+	struct drm_device *dev = minor->dev;
+	struct dentry *ent;
+
+	ent = debugfs_create_file("i915_forcewake_user",
+				  S_IRUSR,
+				  root, dev,
+				  &i915_forcewake_fops);
+	if (IS_ERR(ent))
+		return PTR_ERR(ent);
+
+	return drm_add_fake_info_node(minor, ent, &i915_forcewake_fops);
+}
+
 static struct drm_info_list i915_debugfs_list[] = {
 	{"i915_capabilities", i915_capabilities, 0},
 	{"i915_gem_objects", i915_gem_object_info, 0},
@@ -1324,6 +1435,8 @@
 	{"i915_sr_status", i915_sr_status, 0},
 	{"i915_opregion", i915_opregion, 0},
 	{"i915_gem_framebuffer", i915_gem_framebuffer_info, 0},
+	{"i915_context_status", i915_context_status, 0},
+	{"i915_gen6_forcewake_count", i915_gen6_forcewake_count_info, 0},
 };
 #define I915_DEBUGFS_ENTRIES ARRAY_SIZE(i915_debugfs_list)
 
@@ -1335,6 +1448,10 @@
 	if (ret)
 		return ret;
 
+	ret = i915_forcewake_create(minor->debugfs_root, minor);
+	if (ret)
+		return ret;
+
 	return drm_debugfs_create_files(i915_debugfs_list,
 					I915_DEBUGFS_ENTRIES,
 					minor->debugfs_root, minor);
@@ -1344,6 +1461,8 @@
 {
 	drm_debugfs_remove_files(i915_debugfs_list,
 				 I915_DEBUGFS_ENTRIES, minor);
+	drm_debugfs_remove_files((struct drm_info_list *) &i915_forcewake_fops,
+				 1, minor);
 	drm_debugfs_remove_files((struct drm_info_list *) &i915_wedged_fops,
 				 1, minor);
 }
diff -druN linux-2.6.39-libre/drivers/gpu/drm/i915/i915_dma.c linux-3.0-rc7-libre/drivers/gpu/drm/i915/i915_dma.c
--- linux-2.6.39-libre/drivers/gpu/drm/i915/i915_dma.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/gpu/drm/i915/i915_dma.c	2011-07-11 19:51:52.000000000 -0400
@@ -571,7 +571,7 @@
 	struct intel_ring_buffer *ring = LP_RING(dev->dev_private);
 
 	i915_kernel_lost_context(dev);
-	return intel_wait_ring_buffer(ring, ring->size - 8);
+	return intel_wait_ring_idle(ring);
 }
 
 static int i915_flush_ioctl(struct drm_device *dev, void *data,
@@ -1176,11 +1176,11 @@
 	return can_switch;
 }
 
-static int i915_load_modeset_init(struct drm_device *dev)
+static int i915_load_gem_init(struct drm_device *dev)
 {
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	unsigned long prealloc_size, gtt_size, mappable_size;
-	int ret = 0;
+	int ret;
 
 	prealloc_size = dev_priv->mm.gtt->stolen_size;
 	gtt_size = dev_priv->mm.gtt->gtt_total_entries << PAGE_SHIFT;
@@ -1204,7 +1204,7 @@
 	ret = i915_gem_init_ringbuffer(dev);
 	mutex_unlock(&dev->struct_mutex);
 	if (ret)
-		goto out;
+		return ret;
 
 	/* Try to set up FBC with a reasonable compressed buffer size */
 	if (I915_HAS_FBC(dev) && i915_powersave) {
@@ -1222,6 +1222,13 @@
 
 	/* Allow hardware batchbuffers unless told otherwise. */
 	dev_priv->allow_batchbuffer = 1;
+	return 0;
+}
+
+static int i915_load_modeset_init(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	int ret;
 
 	ret = intel_parse_bios(dev);
 	if (ret)
@@ -1236,7 +1243,7 @@
 	 */
 	ret = vga_client_register(dev->pdev, dev, NULL, i915_vga_set_decode);
 	if (ret && ret != -ENODEV)
-		goto cleanup_ringbuffer;
+		goto out;
 
 	intel_register_dsm_handler();
 
@@ -1253,10 +1260,16 @@
 
 	intel_modeset_init(dev);
 
-	ret = drm_irq_install(dev);
+	ret = i915_load_gem_init(dev);
 	if (ret)
 		goto cleanup_vga_switcheroo;
 
+	intel_modeset_gem_init(dev);
+
+	ret = drm_irq_install(dev);
+	if (ret)
+		goto cleanup_gem;
+
 	/* Always safe in the mode setting case. */
 	/* FIXME: do pre/post-mode set stuff in core KMS code */
 	dev->vblank_disable_allowed = 1;
@@ -1274,14 +1287,14 @@
 
 cleanup_irq:
 	drm_irq_uninstall(dev);
+cleanup_gem:
+	mutex_lock(&dev->struct_mutex);
+	i915_gem_cleanup_ringbuffer(dev);
+	mutex_unlock(&dev->struct_mutex);
 cleanup_vga_switcheroo:
 	vga_switcheroo_unregister_client(dev->pdev);
 cleanup_vga_client:
 	vga_client_register(dev->pdev, NULL, NULL, NULL);
-cleanup_ringbuffer:
-	mutex_lock(&dev->struct_mutex);
-	i915_gem_cleanup_ringbuffer(dev);
-	mutex_unlock(&dev->struct_mutex);
 out:
 	return ret;
 }
@@ -1980,12 +1993,7 @@
 	/* enable GEM by default */
 	dev_priv->has_gem = 1;
 
-	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_GEN5(dev) || IS_GEN6(dev)) {
-		dev->max_vblank_count = 0xffffffff; /* full 32 bit counter */
-		dev->driver->get_vblank_counter = gm45_get_vblank_counter;
-	}
+	intel_irq_init(dev);
 
 	/* Try to make sure MCHBAR is enabled before poking at it */
 	intel_setup_mchbar(dev);
@@ -2025,6 +2033,7 @@
 
 	spin_lock_init(&dev_priv->irq_lock);
 	spin_lock_init(&dev_priv->error_lock);
+	spin_lock_init(&dev_priv->rps_lock);
 
 	if (IS_MOBILE(dev) || !IS_GEN2(dev))
 		dev_priv->num_pipe = 2;
@@ -2144,9 +2153,8 @@
 		/* Flush any outstanding unpin_work. */
 		flush_workqueue(dev_priv->wq);
 
-		i915_gem_free_all_phys_object(dev);
-
 		mutex_lock(&dev->struct_mutex);
+		i915_gem_free_all_phys_object(dev);
 		i915_gem_cleanup_ringbuffer(dev);
 		mutex_unlock(&dev->struct_mutex);
 		if (I915_HAS_FBC(dev) && i915_powersave)
diff -druN linux-2.6.39-libre/drivers/gpu/drm/i915/i915_drv.c linux-3.0-rc7-libre/drivers/gpu/drm/i915/i915_drv.c
--- linux-2.6.39-libre/drivers/gpu/drm/i915/i915_drv.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/gpu/drm/i915/i915_drv.c	2011-07-11 19:51:52.000000000 -0400
@@ -52,9 +52,12 @@
 unsigned int i915_semaphores = 0;
 module_param_named(semaphores, i915_semaphores, int, 0600);
 
-unsigned int i915_enable_rc6 = 0;
+unsigned int i915_enable_rc6 = 1;
 module_param_named(i915_enable_rc6, i915_enable_rc6, int, 0600);
 
+unsigned int i915_enable_fbc = 0;
+module_param_named(i915_enable_fbc, i915_enable_fbc, int, 0600);
+
 unsigned int i915_lvds_downclock = 0;
 module_param_named(lvds_downclock, i915_lvds_downclock, int, 0400);
 
@@ -169,7 +172,7 @@
 static const struct intel_device_info intel_ironlake_m_info = {
 	.gen = 5, .is_mobile = 1,
 	.need_gfx_hws = 1, .has_hotplug = 1,
-	.has_fbc = 0, /* disabled due to buggy hardware */
+	.has_fbc = 1,
 	.has_bsd_ring = 1,
 };
 
@@ -188,6 +191,21 @@
 	.has_blt_ring = 1,
 };
 
+static const struct intel_device_info intel_ivybridge_d_info = {
+	.is_ivybridge = 1, .gen = 7,
+	.need_gfx_hws = 1, .has_hotplug = 1,
+	.has_bsd_ring = 1,
+	.has_blt_ring = 1,
+};
+
+static const struct intel_device_info intel_ivybridge_m_info = {
+	.is_ivybridge = 1, .gen = 7, .is_mobile = 1,
+	.need_gfx_hws = 1, .has_hotplug = 1,
+	.has_fbc = 0,	/* FBC is not enabled on Ivybridge mobile yet */
+	.has_bsd_ring = 1,
+	.has_blt_ring = 1,
+};
+
 static const struct pci_device_id pciidlist[] = {		/* aka */
 	INTEL_VGA_DEVICE(0x3577, &intel_i830_info),		/* I830_M */
 	INTEL_VGA_DEVICE(0x2562, &intel_845g_info),		/* 845_G */
@@ -227,6 +245,11 @@
 	INTEL_VGA_DEVICE(0x0116, &intel_sandybridge_m_info),
 	INTEL_VGA_DEVICE(0x0126, &intel_sandybridge_m_info),
 	INTEL_VGA_DEVICE(0x010A, &intel_sandybridge_d_info),
+	INTEL_VGA_DEVICE(0x0156, &intel_ivybridge_m_info), /* GT1 mobile */
+	INTEL_VGA_DEVICE(0x0166, &intel_ivybridge_m_info), /* GT2 mobile */
+	INTEL_VGA_DEVICE(0x0152, &intel_ivybridge_d_info), /* GT1 desktop */
+	INTEL_VGA_DEVICE(0x0162, &intel_ivybridge_d_info), /* GT2 desktop */
+	INTEL_VGA_DEVICE(0x015a, &intel_ivybridge_d_info), /* GT1 server */
 	{0, 0, 0}
 };
 
@@ -235,7 +258,9 @@
 #endif
 
 #define INTEL_PCH_DEVICE_ID_MASK	0xff00
+#define INTEL_PCH_IBX_DEVICE_ID_TYPE	0x3b00
 #define INTEL_PCH_CPT_DEVICE_ID_TYPE	0x1c00
+#define INTEL_PCH_PPT_DEVICE_ID_TYPE	0x1e00
 
 void intel_detect_pch (struct drm_device *dev)
 {
@@ -254,16 +279,23 @@
 			int id;
 			id = pch->device & INTEL_PCH_DEVICE_ID_MASK;
 
-			if (id == INTEL_PCH_CPT_DEVICE_ID_TYPE) {
+			if (id == INTEL_PCH_IBX_DEVICE_ID_TYPE) {
+				dev_priv->pch_type = PCH_IBX;
+				DRM_DEBUG_KMS("Found Ibex Peak PCH\n");
+			} else if (id == INTEL_PCH_CPT_DEVICE_ID_TYPE) {
 				dev_priv->pch_type = PCH_CPT;
 				DRM_DEBUG_KMS("Found CougarPoint PCH\n");
+			} else if (id == INTEL_PCH_PPT_DEVICE_ID_TYPE) {
+				/* PantherPoint is CPT compatible */
+				dev_priv->pch_type = PCH_CPT;
+				DRM_DEBUG_KMS("Found PatherPoint PCH\n");
 			}
 		}
 		pci_dev_put(pch);
 	}
 }
 
-void __gen6_gt_force_wake_get(struct drm_i915_private *dev_priv)
+static void __gen6_gt_force_wake_get(struct drm_i915_private *dev_priv)
 {
 	int count;
 
@@ -279,12 +311,38 @@
 		udelay(10);
 }
 
-void __gen6_gt_force_wake_put(struct drm_i915_private *dev_priv)
+/*
+ * Generally this is called implicitly by the register read function. However,
+ * if some sequence requires the GT to not power down then this function should
+ * be called at the beginning of the sequence followed by a call to
+ * gen6_gt_force_wake_put() at the end of the sequence.
+ */
+void gen6_gt_force_wake_get(struct drm_i915_private *dev_priv)
+{
+	WARN_ON(!mutex_is_locked(&dev_priv->dev->struct_mutex));
+
+	/* Forcewake is atomic in case we get in here without the lock */
+	if (atomic_add_return(1, &dev_priv->forcewake_count) == 1)
+		__gen6_gt_force_wake_get(dev_priv);
+}
+
+static void __gen6_gt_force_wake_put(struct drm_i915_private *dev_priv)
 {
 	I915_WRITE_NOTRACE(FORCEWAKE, 0);
 	POSTING_READ(FORCEWAKE);
 }
 
+/*
+ * see gen6_gt_force_wake_get()
+ */
+void gen6_gt_force_wake_put(struct drm_i915_private *dev_priv)
+{
+	WARN_ON(!mutex_is_locked(&dev_priv->dev->struct_mutex));
+
+	if (atomic_dec_and_test(&dev_priv->forcewake_count))
+		__gen6_gt_force_wake_put(dev_priv);
+}
+
 void __gen6_gt_wait_for_fifo(struct drm_i915_private *dev_priv)
 {
 	int loop = 500;
@@ -521,6 +579,9 @@
 	} else switch (INTEL_INFO(dev)->gen) {
 	case 6:
 		ret = gen6_do_reset(dev, flags);
+		/* If reset with a user forcewake, try to restore */
+		if (atomic_read(&dev_priv->forcewake_count))
+			__gen6_gt_force_wake_get(dev_priv);
 		break;
 	case 5:
 		ret = ironlake_do_reset(dev, flags);
@@ -704,14 +765,6 @@
 	.resume = i915_resume,
 
 	.device_is_agp = i915_driver_device_is_agp,
-	.enable_vblank = i915_enable_vblank,
-	.disable_vblank = i915_disable_vblank,
-	.get_vblank_timestamp = i915_get_vblank_timestamp,
-	.get_scanout_position = i915_get_crtc_scanoutpos,
-	.irq_preinstall = i915_driver_irq_preinstall,
-	.irq_postinstall = i915_driver_irq_postinstall,
-	.irq_uninstall = i915_driver_irq_uninstall,
-	.irq_handler = i915_driver_irq_handler,
 	.reclaim_buffers = drm_core_reclaim_buffers,
 	.master_create = i915_master_create,
 	.master_destroy = i915_master_destroy,
diff -druN linux-2.6.39-libre/drivers/gpu/drm/i915/i915_drv.h linux-3.0-rc7-libre/drivers/gpu/drm/i915/i915_drv.h
--- linux-2.6.39-libre/drivers/gpu/drm/i915/i915_drv.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/gpu/drm/i915/i915_drv.h	2011-07-11 19:51:52.000000000 -0400
@@ -188,7 +188,7 @@
 		u32 dirty:1;
 		u32 purgeable:1;
 		u32 ring:4;
-		u32 agp_type:1;
+		u32 cache_level:2;
 	} *active_bo, *pinned_bo;
 	u32 active_bo_count, pinned_bo_count;
 	struct intel_overlay_error_state *overlay;
@@ -203,12 +203,22 @@
 	int (*get_display_clock_speed)(struct drm_device *dev);
 	int (*get_fifo_size)(struct drm_device *dev, int plane);
 	void (*update_wm)(struct drm_device *dev);
+	int (*crtc_mode_set)(struct drm_crtc *crtc,
+			     struct drm_display_mode *mode,
+			     struct drm_display_mode *adjusted_mode,
+			     int x, int y,
+			     struct drm_framebuffer *old_fb);
+	void (*fdi_link_train)(struct drm_crtc *crtc);
+	void (*init_clock_gating)(struct drm_device *dev);
+	void (*init_pch_clock_gating)(struct drm_device *dev);
+	int (*queue_flip)(struct drm_device *dev, struct drm_crtc *crtc,
+			  struct drm_framebuffer *fb,
+			  struct drm_i915_gem_object *obj);
 	/* clock updates for mode set */
 	/* cursor updates */
 	/* render clock increase/decrease */
 	/* display clock increase/decrease */
 	/* pll clock increase/decrease */
-	/* clock gating init */
 };
 
 struct intel_device_info {
@@ -223,6 +233,7 @@
 	u8 is_pineview : 1;
 	u8 is_broadwater : 1;
 	u8 is_crestline : 1;
+	u8 is_ivybridge : 1;
 	u8 has_fbc : 1;
 	u8 has_pipe_cxsr : 1;
 	u8 has_hotplug : 1;
@@ -242,6 +253,7 @@
 	FBC_BAD_PLANE, /* fbc not supported on plane */
 	FBC_NOT_TILED, /* buffer not tiled */
 	FBC_MULTIPLE_PIPES, /* more than one pipe active */
+	FBC_MODULE_PARAM,
 };
 
 enum intel_pch {
@@ -676,6 +688,10 @@
 
 	bool mchbar_need_disable;
 
+	struct work_struct rps_work;
+	spinlock_t rps_lock;
+	u32 pm_iir;
+
 	u8 cur_delay;
 	u8 min_delay;
 	u8 max_delay;
@@ -703,8 +719,17 @@
 	struct intel_fbdev *fbdev;
 
 	struct drm_property *broadcast_rgb_property;
+	struct drm_property *force_audio_property;
+
+	atomic_t forcewake_count;
 } drm_i915_private_t;
 
+enum i915_cache_level {
+	I915_CACHE_NONE,
+	I915_CACHE_LLC,
+	I915_CACHE_LLC_MLC, /* gen6+ */
+};
+
 struct drm_i915_gem_object {
 	struct drm_gem_object base;
 
@@ -791,6 +816,8 @@
 	unsigned int pending_fenced_gpu_access:1;
 	unsigned int fenced_gpu_access:1;
 
+	unsigned int cache_level:2;
+
 	struct page **pages;
 
 	/**
@@ -827,8 +854,6 @@
 	/** Record of address bit 17 of each page at last unbind. */
 	unsigned long *bit_17;
 
-	/** AGP mapping type (AGP_USER_MEMORY or AGP_USER_CACHED_MEMORY */
-	uint32_t agp_type;
 
 	/**
 	 * If present, while GEM_DOMAIN_CPU is in the read domain this array
@@ -888,13 +913,6 @@
 	} mm;
 };
 
-enum intel_chip_family {
-	CHIP_I8XX = 0x01,
-	CHIP_I9XX = 0x02,
-	CHIP_I915 = 0x04,
-	CHIP_I965 = 0x08,
-};
-
 #define INTEL_INFO(dev)	(((struct drm_i915_private *) (dev)->dev_private)->info)
 
 #define IS_I830(dev)		((dev)->pci_device == 0x3577)
@@ -915,13 +933,21 @@
 #define IS_G33(dev)		(INTEL_INFO(dev)->is_g33)
 #define IS_IRONLAKE_D(dev)	((dev)->pci_device == 0x0042)
 #define IS_IRONLAKE_M(dev)	((dev)->pci_device == 0x0046)
+#define IS_IVYBRIDGE(dev)	(INTEL_INFO(dev)->is_ivybridge)
 #define IS_MOBILE(dev)		(INTEL_INFO(dev)->is_mobile)
 
+/*
+ * The genX designation typically refers to the render engine, so render
+ * capability related checks should use IS_GEN, while display and other checks
+ * have their own (e.g. HAS_PCH_SPLIT for ILK+ display, IS_foo for particular
+ * chips, etc.).
+ */
 #define IS_GEN2(dev)	(INTEL_INFO(dev)->gen == 2)
 #define IS_GEN3(dev)	(INTEL_INFO(dev)->gen == 3)
 #define IS_GEN4(dev)	(INTEL_INFO(dev)->gen == 4)
 #define IS_GEN5(dev)	(INTEL_INFO(dev)->gen == 5)
 #define IS_GEN6(dev)	(INTEL_INFO(dev)->gen == 6)
+#define IS_GEN7(dev)	(INTEL_INFO(dev)->gen == 7)
 
 #define HAS_BSD(dev)            (INTEL_INFO(dev)->has_bsd_ring)
 #define HAS_BLT(dev)            (INTEL_INFO(dev)->has_blt_ring)
@@ -948,8 +974,8 @@
 #define HAS_PIPE_CXSR(dev) (INTEL_INFO(dev)->has_pipe_cxsr)
 #define I915_HAS_FBC(dev) (INTEL_INFO(dev)->has_fbc)
 
-#define HAS_PCH_SPLIT(dev) (IS_GEN5(dev) || IS_GEN6(dev))
-#define HAS_PIPE_CONTROL(dev) (IS_GEN5(dev) || IS_GEN6(dev))
+#define HAS_PCH_SPLIT(dev) (IS_GEN5(dev) || IS_GEN6(dev) || IS_IVYBRIDGE(dev))
+#define HAS_PIPE_CONTROL(dev) (INTEL_INFO(dev)->gen >= 5)
 
 #define INTEL_PCH_TYPE(dev) (((struct drm_i915_private *)(dev)->dev_private)->pch_type)
 #define HAS_PCH_CPT(dev) (INTEL_PCH_TYPE(dev) == PCH_CPT)
@@ -967,11 +993,10 @@
 extern unsigned int i915_panel_use_ssc;
 extern int i915_vbt_sdvo_panel_type;
 extern unsigned int i915_enable_rc6;
+extern unsigned int i915_enable_fbc;
 
 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);
 extern void i915_master_destroy(struct drm_device *dev, struct drm_master *master);
 
@@ -1006,18 +1031,12 @@
 extern int i915_irq_wait(struct drm_device *dev, void *data,
 			 struct drm_file *file_priv);
 
-extern irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS);
-extern void i915_driver_irq_preinstall(struct drm_device * dev);
-extern int i915_driver_irq_postinstall(struct drm_device *dev);
-extern void i915_driver_irq_uninstall(struct drm_device * dev);
+extern void intel_irq_init(struct drm_device *dev);
+
 extern int i915_vblank_pipe_set(struct drm_device *dev, void *data,
 				struct drm_file *file_priv);
 extern int i915_vblank_pipe_get(struct drm_device *dev, void *data,
 				struct drm_file *file_priv);
-extern int i915_enable_vblank(struct drm_device *dev, int crtc);
-extern void i915_disable_vblank(struct drm_device *dev, int crtc);
-extern u32 i915_get_vblank_counter(struct drm_device *dev, int crtc);
-extern u32 gm45_get_vblank_counter(struct drm_device *dev, int crtc);
 extern int i915_vblank_swap(struct drm_device *dev, void *data,
 			    struct drm_file *file_priv);
 
@@ -1028,13 +1047,6 @@
 i915_disable_pipestat(drm_i915_private_t *dev_priv, int pipe, u32 mask);
 
 void intel_enable_asle (struct drm_device *dev);
-int i915_get_vblank_timestamp(struct drm_device *dev, int crtc,
-			      int *max_error,
-			      struct timeval *vblank_time,
-			      unsigned flags);
-
-int i915_get_crtc_scanoutpos(struct drm_device *dev, int pipe,
-			     int *vpos, int *hpos);
 
 #ifdef CONFIG_DEBUG_FS
 extern void i915_destroy_error_state(struct drm_device *dev);
@@ -1265,6 +1277,7 @@
 
 /* modesetting */
 extern void intel_modeset_init(struct drm_device *dev);
+extern void intel_modeset_gem_init(struct drm_device *dev);
 extern void intel_modeset_cleanup(struct drm_device *dev);
 extern int intel_modeset_vga_set_state(struct drm_device *dev, bool state);
 extern void i8xx_disable_fbc(struct drm_device *dev);
@@ -1312,13 +1325,34 @@
 		LOCK_TEST_WITH_RETURN(dev, file);			\
 } while (0)
 
+/* On SNB platform, before reading ring registers forcewake bit
+ * must be set to prevent GT core from power down and stale values being
+ * returned.
+ */
+void gen6_gt_force_wake_get(struct drm_i915_private *dev_priv);
+void gen6_gt_force_wake_put(struct drm_i915_private *dev_priv);
+void __gen6_gt_wait_for_fifo(struct drm_i915_private *dev_priv);
+
+/* We give fast paths for the really cool registers */
+#define NEEDS_FORCE_WAKE(dev_priv, reg) \
+	(((dev_priv)->info->gen >= 6) && \
+	((reg) < 0x40000) && \
+	((reg) != FORCEWAKE))
 
 #define __i915_read(x, y) \
 static inline u##x i915_read##x(struct drm_i915_private *dev_priv, u32 reg) { \
-	u##x val = read##y(dev_priv->regs + reg); \
+	u##x val = 0; \
+	if (NEEDS_FORCE_WAKE((dev_priv), (reg))) { \
+		gen6_gt_force_wake_get(dev_priv); \
+		val = read##y(dev_priv->regs + reg); \
+		gen6_gt_force_wake_put(dev_priv); \
+	} else { \
+		val = read##y(dev_priv->regs + reg); \
+	} \
 	trace_i915_reg_rw(false, reg, val, sizeof(val)); \
 	return val; \
 }
+
 __i915_read(8, b)
 __i915_read(16, w)
 __i915_read(32, l)
@@ -1328,6 +1362,9 @@
 #define __i915_write(x, y) \
 static inline void i915_write##x(struct drm_i915_private *dev_priv, u32 reg, u##x val) { \
 	trace_i915_reg_rw(true, reg, val, sizeof(val)); \
+	if (NEEDS_FORCE_WAKE((dev_priv), (reg))) { \
+		__gen6_gt_wait_for_fifo(dev_priv); \
+	} \
 	write##y(val, dev_priv->regs + reg); \
 }
 __i915_write(8, b)
@@ -1356,33 +1393,4 @@
 #define POSTING_READ16(reg)	(void)I915_READ16_NOTRACE(reg)
 
 
-/* On SNB platform, before reading ring registers forcewake bit
- * must be set to prevent GT core from power down and stale values being
- * returned.
- */
-void __gen6_gt_force_wake_get(struct drm_i915_private *dev_priv);
-void __gen6_gt_force_wake_put(struct drm_i915_private *dev_priv);
-void __gen6_gt_wait_for_fifo(struct drm_i915_private *dev_priv);
-
-static inline u32 i915_gt_read(struct drm_i915_private *dev_priv, u32 reg)
-{
-	u32 val;
-
-	if (dev_priv->info->gen >= 6) {
-		__gen6_gt_force_wake_get(dev_priv);
-		val = I915_READ(reg);
-		__gen6_gt_force_wake_put(dev_priv);
-	} else
-		val = I915_READ(reg);
-
-	return val;
-}
-
-static inline void i915_gt_write(struct drm_i915_private *dev_priv,
-				u32 reg, u32 val)
-{
-	if (dev_priv->info->gen >= 6)
-		__gen6_gt_wait_for_fifo(dev_priv);
-	I915_WRITE(reg, val);
-}
 #endif
diff -druN linux-2.6.39-libre/drivers/gpu/drm/i915/i915_gem.c linux-3.0-rc7-libre/drivers/gpu/drm/i915/i915_gem.c
--- linux-2.6.39-libre/drivers/gpu/drm/i915/i915_gem.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/gpu/drm/i915/i915_gem.c	2011-07-11 19:51:52.000000000 -0400
@@ -31,6 +31,7 @@
 #include "i915_drv.h"
 #include "i915_trace.h"
 #include "intel_drv.h"
+#include <linux/shmem_fs.h>
 #include <linux/slab.h>
 #include <linux/swap.h>
 #include <linux/pci.h>
@@ -56,9 +57,7 @@
 static void i915_gem_free_object_tail(struct drm_i915_gem_object *obj);
 
 static int i915_gem_inactive_shrink(struct shrinker *shrinker,
-				    int nr_to_scan,
-				    gfp_t gfp_mask);
-
+				    struct shrink_control *sc);
 
 /* some bookkeeping */
 static void i915_gem_info_add_obj(struct drm_i915_private *dev_priv,
@@ -356,13 +355,12 @@
 		 * page_offset = offset within page
 		 * page_length = bytes to copy for this page
 		 */
-		page_offset = offset & (PAGE_SIZE-1);
+		page_offset = offset_in_page(offset);
 		page_length = remain;
 		if ((page_offset + remain) > PAGE_SIZE)
 			page_length = PAGE_SIZE - page_offset;
 
-		page = read_cache_page_gfp(mapping, offset >> PAGE_SHIFT,
-					   GFP_HIGHUSER | __GFP_RECLAIMABLE);
+		page = shmem_read_mapping_page(mapping, offset >> PAGE_SHIFT);
 		if (IS_ERR(page))
 			return PTR_ERR(page);
 
@@ -455,9 +453,9 @@
 		 * data_page_offset = offset with data_page_index page.
 		 * page_length = bytes to copy for this page
 		 */
-		shmem_page_offset = offset & ~PAGE_MASK;
+		shmem_page_offset = offset_in_page(offset);
 		data_page_index = data_ptr / PAGE_SIZE - first_data_page;
-		data_page_offset = data_ptr & ~PAGE_MASK;
+		data_page_offset = offset_in_page(data_ptr);
 
 		page_length = remain;
 		if ((shmem_page_offset + page_length) > PAGE_SIZE)
@@ -465,10 +463,11 @@
 		if ((data_page_offset + page_length) > PAGE_SIZE)
 			page_length = PAGE_SIZE - data_page_offset;
 
-		page = read_cache_page_gfp(mapping, offset >> PAGE_SHIFT,
-					   GFP_HIGHUSER | __GFP_RECLAIMABLE);
-		if (IS_ERR(page))
-			return PTR_ERR(page);
+		page = shmem_read_mapping_page(mapping, offset >> PAGE_SHIFT);
+		if (IS_ERR(page)) {
+			ret = PTR_ERR(page);
+			goto out;
+		}
 
 		if (do_bit17_swizzling) {
 			slow_shmem_bit17_copy(page,
@@ -640,8 +639,8 @@
 		 * page_offset = offset within page
 		 * page_length = bytes to copy for this page
 		 */
-		page_base = (offset & ~(PAGE_SIZE-1));
-		page_offset = offset & (PAGE_SIZE-1);
+		page_base = offset & PAGE_MASK;
+		page_offset = offset_in_page(offset);
 		page_length = remain;
 		if ((page_offset + remain) > PAGE_SIZE)
 			page_length = PAGE_SIZE - page_offset;
@@ -652,7 +651,6 @@
 		 */
 		if (fast_user_write(dev_priv->mm.gtt_mapping, page_base,
 				    page_offset, user_data, page_length))
-
 			return -EFAULT;
 
 		remain -= page_length;
@@ -732,9 +730,9 @@
 		 * page_length = bytes to copy for this page
 		 */
 		gtt_page_base = offset & PAGE_MASK;
-		gtt_page_offset = offset & ~PAGE_MASK;
+		gtt_page_offset = offset_in_page(offset);
 		data_page_index = data_ptr / PAGE_SIZE - first_data_page;
-		data_page_offset = data_ptr & ~PAGE_MASK;
+		data_page_offset = offset_in_page(data_ptr);
 
 		page_length = remain;
 		if ((gtt_page_offset + page_length) > PAGE_SIZE)
@@ -793,13 +791,12 @@
 		 * page_offset = offset within page
 		 * page_length = bytes to copy for this page
 		 */
-		page_offset = offset & (PAGE_SIZE-1);
+		page_offset = offset_in_page(offset);
 		page_length = remain;
 		if ((page_offset + remain) > PAGE_SIZE)
 			page_length = PAGE_SIZE - page_offset;
 
-		page = read_cache_page_gfp(mapping, offset >> PAGE_SHIFT,
-					   GFP_HIGHUSER | __GFP_RECLAIMABLE);
+		page = shmem_read_mapping_page(mapping, offset >> PAGE_SHIFT);
 		if (IS_ERR(page))
 			return PTR_ERR(page);
 
@@ -898,9 +895,9 @@
 		 * data_page_offset = offset with data_page_index page.
 		 * page_length = bytes to copy for this page
 		 */
-		shmem_page_offset = offset & ~PAGE_MASK;
+		shmem_page_offset = offset_in_page(offset);
 		data_page_index = data_ptr / PAGE_SIZE - first_data_page;
-		data_page_offset = data_ptr & ~PAGE_MASK;
+		data_page_offset = offset_in_page(data_ptr);
 
 		page_length = remain;
 		if ((shmem_page_offset + page_length) > PAGE_SIZE)
@@ -908,8 +905,7 @@
 		if ((data_page_offset + page_length) > PAGE_SIZE)
 			page_length = PAGE_SIZE - data_page_offset;
 
-		page = read_cache_page_gfp(mapping, offset >> PAGE_SHIFT,
-					   GFP_HIGHUSER | __GFP_RECLAIMABLE);
+		page = shmem_read_mapping_page(mapping, offset >> PAGE_SHIFT);
 		if (IS_ERR(page)) {
 			ret = PTR_ERR(page);
 			goto out;
@@ -1220,11 +1216,11 @@
 		ret = i915_gem_object_bind_to_gtt(obj, 0, true);
 		if (ret)
 			goto unlock;
-	}
 
-	ret = i915_gem_object_set_to_gtt_domain(obj, write);
-	if (ret)
-		goto unlock;
+		ret = i915_gem_object_set_to_gtt_domain(obj, write);
+		if (ret)
+			goto unlock;
+	}
 
 	if (obj->tiling_mode == I915_TILING_NONE)
 		ret = i915_gem_object_put_fence(obj);
@@ -1452,8 +1448,9 @@
 	 * edge of an even tile row (where tile rows are counted as if the bo is
 	 * placed in a fenced gtt region).
 	 */
-	if (IS_GEN2(dev) ||
-	    (obj->tiling_mode == I915_TILING_Y && HAS_128_BYTE_Y_TILING(dev)))
+	if (IS_GEN2(dev))
+		tile_height = 16;
+	else if (obj->tiling_mode == I915_TILING_Y && HAS_128_BYTE_Y_TILING(dev))
 		tile_height = 32;
 	else
 		tile_height = 8;
@@ -1558,12 +1555,10 @@
 
 	inode = obj->base.filp->f_path.dentry->d_inode;
 	mapping = inode->i_mapping;
+	gfpmask |= mapping_gfp_mask(mapping);
+
 	for (i = 0; i < page_count; i++) {
-		page = read_cache_page_gfp(mapping, i,
-					   GFP_HIGHUSER |
-					   __GFP_COLD |
-					   __GFP_RECLAIMABLE |
-					   gfpmask);
+		page = shmem_read_mapping_page_gfp(mapping, i, gfpmask);
 		if (IS_ERR(page))
 			goto err_pages;
 
@@ -1701,13 +1696,10 @@
 	/* Our goal here is to return as much of the memory as
 	 * is possible back to the system as we are called from OOM.
 	 * To do this we must instruct the shmfs to drop all of its
-	 * backing pages, *now*. Here we mirror the actions taken
-	 * when by shmem_delete_inode() to release the backing store.
+	 * backing pages, *now*.
 	 */
 	inode = obj->base.filp->f_path.dentry->d_inode;
-	truncate_inode_pages(inode->i_mapping, 0);
-	if (inode->i_op->truncate_range)
-		inode->i_op->truncate_range(inode, 0, (loff_t)-1);
+	shmem_truncate_range(inode, 0, (loff_t)-1);
 
 	obj->madv = __I915_MADV_PURGED;
 }
@@ -2080,8 +2072,8 @@
 		if (!ier) {
 			DRM_ERROR("something (likely vbetool) disabled "
 				  "interrupts, re-enabling\n");
-			i915_driver_irq_preinstall(ring->dev);
-			i915_driver_irq_postinstall(ring->dev);
+			ring->dev->driver->irq_preinstall(ring->dev);
+			ring->dev->driver->irq_postinstall(ring->dev);
 		}
 
 		trace_i915_gem_request_wait_begin(ring, seqno);
@@ -2673,6 +2665,7 @@
 update:
 	obj->tiling_changed = false;
 	switch (INTEL_INFO(dev)->gen) {
+	case 7:
 	case 6:
 		ret = sandybridge_write_fence_reg(obj, pipelined);
 		break;
@@ -2706,6 +2699,7 @@
 	uint32_t fence_reg = reg - dev_priv->fence_regs;
 
 	switch (INTEL_INFO(dev)->gen) {
+	case 7:
 	case 6:
 		I915_WRITE64(FENCE_REG_SANDYBRIDGE_0 + fence_reg*8, 0);
 		break;
@@ -2878,6 +2872,17 @@
 	if (obj->pages == NULL)
 		return;
 
+	/* If the GPU is snooping the contents of the CPU cache,
+	 * we do not need to manually clear the CPU cache lines.  However,
+	 * the caches are only snooped when the render cache is
+	 * flushed/invalidated.  As we always have to emit invalidations
+	 * and flushes when moving into and out of the RENDER domain, correct
+	 * snooping behaviour occurs naturally as the result of our domain
+	 * tracking.
+	 */
+	if (obj->cache_level != I915_CACHE_NONE)
+		return;
+
 	trace_i915_gem_object_clflush(obj);
 
 	drm_clflush_pages(obj->pages, obj->base.size / PAGE_SIZE);
@@ -2913,8 +2918,6 @@
 	 */
 	wmb();
 
-	i915_gem_release_mmap(obj);
-
 	old_write_domain = obj->base.write_domain;
 	obj->base.write_domain = 0;
 
@@ -3554,6 +3557,7 @@
 {
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct drm_i915_gem_object *obj;
+	struct address_space *mapping;
 
 	obj = kzalloc(sizeof(*obj), GFP_KERNEL);
 	if (obj == NULL)
@@ -3564,12 +3568,15 @@
 		return NULL;
 	}
 
+	mapping = obj->base.filp->f_path.dentry->d_inode->i_mapping;
+	mapping_set_gfp_mask(mapping, GFP_HIGHUSER | __GFP_RECLAIMABLE);
+
 	i915_gem_info_add_obj(dev_priv, size);
 
 	obj->base.write_domain = I915_GEM_DOMAIN_CPU;
 	obj->base.read_domains = I915_GEM_DOMAIN_CPU;
 
-	obj->agp_type = AGP_USER_MEMORY;
+	obj->cache_level = I915_CACHE_NONE;
 	obj->base.driver_private = NULL;
 	obj->fence_reg = I915_FENCE_REG_NONE;
 	INIT_LIST_HEAD(&obj->mm_list);
@@ -3845,25 +3852,10 @@
 		dev_priv->num_fence_regs = 8;
 
 	/* Initialize fence registers to zero */
-	switch (INTEL_INFO(dev)->gen) {
-	case 6:
-		for (i = 0; i < 16; i++)
-			I915_WRITE64(FENCE_REG_SANDYBRIDGE_0 + (i * 8), 0);
-		break;
-	case 5:
-	case 4:
-		for (i = 0; i < 16; i++)
-			I915_WRITE64(FENCE_REG_965_0 + (i * 8), 0);
-		break;
-	case 3:
-		if (IS_I945G(dev) || IS_I945GM(dev) || IS_G33(dev))
-			for (i = 0; i < 8; i++)
-				I915_WRITE(FENCE_REG_945_8 + (i * 4), 0);
-	case 2:
-		for (i = 0; i < 8; i++)
-			I915_WRITE(FENCE_REG_830_0 + (i * 4), 0);
-		break;
+	for (i = 0; i < dev_priv->num_fence_regs; i++) {
+		i915_gem_clear_fence_reg(dev, &dev_priv->fence_regs[i]);
 	}
+
 	i915_gem_detect_bit_6_swizzle(dev);
 	init_waitqueue_head(&dev_priv->pending_flip_queue);
 
@@ -3954,8 +3946,7 @@
 
 	page_count = obj->base.size / PAGE_SIZE;
 	for (i = 0; i < page_count; i++) {
-		struct page *page = read_cache_page_gfp(mapping, i,
-							GFP_HIGHUSER | __GFP_RECLAIMABLE);
+		struct page *page = shmem_read_mapping_page(mapping, i);
 		if (!IS_ERR(page)) {
 			char *dst = kmap_atomic(page);
 			memcpy(dst, vaddr + i*PAGE_SIZE, PAGE_SIZE);
@@ -4016,8 +4007,7 @@
 		struct page *page;
 		char *dst, *src;
 
-		page = read_cache_page_gfp(mapping, i,
-					   GFP_HIGHUSER | __GFP_RECLAIMABLE);
+		page = shmem_read_mapping_page(mapping, i);
 		if (IS_ERR(page))
 			return PTR_ERR(page);
 
@@ -4094,9 +4084,7 @@
 }
 
 static int
-i915_gem_inactive_shrink(struct shrinker *shrinker,
-			 int nr_to_scan,
-			 gfp_t gfp_mask)
+i915_gem_inactive_shrink(struct shrinker *shrinker, struct shrink_control *sc)
 {
 	struct drm_i915_private *dev_priv =
 		container_of(shrinker,
@@ -4104,6 +4092,7 @@
 			     mm.inactive_shrinker);
 	struct drm_device *dev = dev_priv->dev;
 	struct drm_i915_gem_object *obj, *next;
+	int nr_to_scan = sc->nr_to_scan;
 	int cnt;
 
 	if (!mutex_trylock(&dev->struct_mutex))
diff -druN linux-2.6.39-libre/drivers/gpu/drm/i915/i915_gem_execbuffer.c linux-3.0-rc7-libre/drivers/gpu/drm/i915/i915_gem_execbuffer.c
--- linux-2.6.39-libre/drivers/gpu/drm/i915/i915_gem_execbuffer.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/gpu/drm/i915/i915_gem_execbuffer.c	2011-07-11 19:51:52.000000000 -0400
@@ -187,10 +187,6 @@
 	if ((flush_domains | invalidate_domains) & I915_GEM_DOMAIN_CPU)
 		i915_gem_clflush_object(obj);
 
-	/* blow away mappings if mapped through GTT */
-	if ((flush_domains | invalidate_domains) & I915_GEM_DOMAIN_GTT)
-		i915_gem_release_mmap(obj);
-
 	if (obj->base.pending_write_domain)
 		cd->flips |= atomic_read(&obj->pending_flip);
 
diff -druN linux-2.6.39-libre/drivers/gpu/drm/i915/i915_gem_gtt.c linux-3.0-rc7-libre/drivers/gpu/drm/i915/i915_gem_gtt.c
--- linux-2.6.39-libre/drivers/gpu/drm/i915/i915_gem_gtt.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/gpu/drm/i915/i915_gem_gtt.c	2011-07-11 19:51:52.000000000 -0400
@@ -29,6 +29,26 @@
 #include "i915_trace.h"
 #include "intel_drv.h"
 
+/* XXX kill agp_type! */
+static unsigned int cache_level_to_agp_type(struct drm_device *dev,
+					    enum i915_cache_level cache_level)
+{
+	switch (cache_level) {
+	case I915_CACHE_LLC_MLC:
+		if (INTEL_INFO(dev)->gen >= 6)
+			return AGP_USER_CACHED_MEMORY_LLC_MLC;
+		/* Older chipsets do not have this extra level of CPU
+		 * cacheing, so fallthrough and request the PTE simply
+		 * as cached.
+		 */
+	case I915_CACHE_LLC:
+		return AGP_USER_CACHED_MEMORY;
+	default:
+	case I915_CACHE_NONE:
+		return AGP_USER_MEMORY;
+	}
+}
+
 void i915_gem_restore_gtt_mappings(struct drm_device *dev)
 {
 	struct drm_i915_private *dev_priv = dev->dev_private;
@@ -39,6 +59,9 @@
 			      (dev_priv->mm.gtt_end - dev_priv->mm.gtt_start) / PAGE_SIZE);
 
 	list_for_each_entry(obj, &dev_priv->mm.gtt_list, gtt_list) {
+		unsigned int agp_type =
+			cache_level_to_agp_type(dev, obj->cache_level);
+
 		i915_gem_clflush_object(obj);
 
 		if (dev_priv->mm.gtt->needs_dmar) {
@@ -46,15 +69,14 @@
 
 			intel_gtt_insert_sg_entries(obj->sg_list,
 						    obj->num_sg,
-						    obj->gtt_space->start
-							>> PAGE_SHIFT,
-						    obj->agp_type);
+						    obj->gtt_space->start >> PAGE_SHIFT,
+						    agp_type);
 		} else
 			intel_gtt_insert_pages(obj->gtt_space->start
 						   >> PAGE_SHIFT,
 					       obj->base.size >> PAGE_SHIFT,
 					       obj->pages,
-					       obj->agp_type);
+					       agp_type);
 	}
 
 	intel_gtt_chipset_flush();
@@ -64,6 +86,7 @@
 {
 	struct drm_device *dev = obj->base.dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
+	unsigned int agp_type = cache_level_to_agp_type(dev, obj->cache_level);
 	int ret;
 
 	if (dev_priv->mm.gtt->needs_dmar) {
@@ -77,12 +100,12 @@
 		intel_gtt_insert_sg_entries(obj->sg_list,
 					    obj->num_sg,
 					    obj->gtt_space->start >> PAGE_SHIFT,
-					    obj->agp_type);
+					    agp_type);
 	} else
 		intel_gtt_insert_pages(obj->gtt_space->start >> PAGE_SHIFT,
 				       obj->base.size >> PAGE_SHIFT,
 				       obj->pages,
-				       obj->agp_type);
+				       agp_type);
 
 	return 0;
 }
diff -druN linux-2.6.39-libre/drivers/gpu/drm/i915/i915_gem_tiling.c linux-3.0-rc7-libre/drivers/gpu/drm/i915/i915_gem_tiling.c
--- linux-2.6.39-libre/drivers/gpu/drm/i915/i915_gem_tiling.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/gpu/drm/i915/i915_gem_tiling.c	2011-07-11 19:51:52.000000000 -0400
@@ -92,7 +92,7 @@
 	uint32_t swizzle_x = I915_BIT_6_SWIZZLE_UNKNOWN;
 	uint32_t swizzle_y = I915_BIT_6_SWIZZLE_UNKNOWN;
 
-	if (IS_GEN5(dev) || IS_GEN6(dev)) {
+	if (INTEL_INFO(dev)->gen >= 5) {
 		/* On Ironlake whatever DRAM config, GPU always do
 		 * same swizzling setup.
 		 */
diff -druN linux-2.6.39-libre/drivers/gpu/drm/i915/i915_irq.c linux-3.0-rc7-libre/drivers/gpu/drm/i915/i915_irq.c
--- linux-2.6.39-libre/drivers/gpu/drm/i915/i915_irq.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/gpu/drm/i915/i915_irq.c	2011-07-11 19:51:52.000000000 -0400
@@ -152,7 +152,7 @@
 /* Called from drm generic code, passed a 'crtc', which
  * we use as a pipe index
  */
-u32 i915_get_vblank_counter(struct drm_device *dev, int pipe)
+static u32 i915_get_vblank_counter(struct drm_device *dev, int pipe)
 {
 	drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
 	unsigned long high_frame;
@@ -184,7 +184,7 @@
 	return (high1 << 8) | low;
 }
 
-u32 gm45_get_vblank_counter(struct drm_device *dev, int pipe)
+static u32 gm45_get_vblank_counter(struct drm_device *dev, int pipe)
 {
 	drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
 	int reg = PIPE_FRMCOUNT_GM45(pipe);
@@ -198,7 +198,7 @@
 	return I915_READ(reg);
 }
 
-int i915_get_crtc_scanoutpos(struct drm_device *dev, int pipe,
+static int i915_get_crtc_scanoutpos(struct drm_device *dev, int pipe,
 			     int *vpos, int *hpos)
 {
 	drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
@@ -264,7 +264,7 @@
 	return ret;
 }
 
-int i915_get_vblank_timestamp(struct drm_device *dev, int pipe,
+static int i915_get_vblank_timestamp(struct drm_device *dev, int pipe,
 			      int *max_error,
 			      struct timeval *vblank_time,
 			      unsigned flags)
@@ -367,22 +367,30 @@
 		  jiffies + msecs_to_jiffies(DRM_I915_HANGCHECK_PERIOD));
 }
 
-static void gen6_pm_irq_handler(struct drm_device *dev)
+static void gen6_pm_rps_work(struct work_struct *work)
 {
-	drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
+	drm_i915_private_t *dev_priv = container_of(work, drm_i915_private_t,
+						    rps_work);
 	u8 new_delay = dev_priv->cur_delay;
-	u32 pm_iir;
+	u32 pm_iir, pm_imr;
+
+	spin_lock_irq(&dev_priv->rps_lock);
+	pm_iir = dev_priv->pm_iir;
+	dev_priv->pm_iir = 0;
+	pm_imr = I915_READ(GEN6_PMIMR);
+	spin_unlock_irq(&dev_priv->rps_lock);
 
-	pm_iir = I915_READ(GEN6_PMIIR);
 	if (!pm_iir)
 		return;
 
+	mutex_lock(&dev_priv->dev->struct_mutex);
 	if (pm_iir & GEN6_PM_RP_UP_THRESHOLD) {
 		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 (pm_iir & (GEN6_PM_RP_DOWN_THRESHOLD | GEN6_PM_RP_DOWN_TIMEOUT)) {
+		gen6_gt_force_wake_get(dev_priv);
 		if (dev_priv->cur_delay != dev_priv->min_delay)
 			new_delay = dev_priv->cur_delay - 1;
 		if (new_delay < dev_priv->min_delay) {
@@ -396,13 +404,19 @@
 			I915_WRITE(GEN6_RP_INTERRUPT_LIMITS,
 				   I915_READ(GEN6_RP_INTERRUPT_LIMITS) & ~0x3f0000);
 		}
-
+		gen6_gt_force_wake_put(dev_priv);
 	}
 
-	gen6_set_rps(dev, new_delay);
+	gen6_set_rps(dev_priv->dev, new_delay);
 	dev_priv->cur_delay = new_delay;
 
-	I915_WRITE(GEN6_PMIIR, pm_iir);
+	/*
+	 * rps_lock not held here because clearing is non-destructive. There is
+	 * an *extremely* unlikely race with gen6_rps_enable() that is prevented
+	 * by holding struct_mutex for the duration of the write.
+	 */
+	I915_WRITE(GEN6_PMIMR, pm_imr & ~pm_iir);
+	mutex_unlock(&dev_priv->dev->struct_mutex);
 }
 
 static void pch_irq_handler(struct drm_device *dev)
@@ -448,8 +462,97 @@
 		DRM_DEBUG_DRIVER("PCH transcoder A underrun interrupt\n");
 }
 
-static irqreturn_t ironlake_irq_handler(struct drm_device *dev)
+static irqreturn_t ivybridge_irq_handler(DRM_IRQ_ARGS)
 {
+	struct drm_device *dev = (struct drm_device *) arg;
+	drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
+	int ret = IRQ_NONE;
+	u32 de_iir, gt_iir, de_ier, pch_iir, pm_iir;
+	struct drm_i915_master_private *master_priv;
+
+	atomic_inc(&dev_priv->irq_received);
+
+	/* disable master interrupt before clearing iir  */
+	de_ier = I915_READ(DEIER);
+	I915_WRITE(DEIER, de_ier & ~DE_MASTER_IRQ_CONTROL);
+	POSTING_READ(DEIER);
+
+	de_iir = I915_READ(DEIIR);
+	gt_iir = I915_READ(GTIIR);
+	pch_iir = I915_READ(SDEIIR);
+	pm_iir = I915_READ(GEN6_PMIIR);
+
+	if (de_iir == 0 && gt_iir == 0 && pch_iir == 0 && pm_iir == 0)
+		goto done;
+
+	ret = IRQ_HANDLED;
+
+	if (dev->primary->master) {
+		master_priv = dev->primary->master->driver_priv;
+		if (master_priv->sarea_priv)
+			master_priv->sarea_priv->last_dispatch =
+				READ_BREADCRUMB(dev_priv);
+	}
+
+	if (gt_iir & (GT_USER_INTERRUPT | GT_PIPE_NOTIFY))
+		notify_ring(dev, &dev_priv->ring[RCS]);
+	if (gt_iir & GT_GEN6_BSD_USER_INTERRUPT)
+		notify_ring(dev, &dev_priv->ring[VCS]);
+	if (gt_iir & GT_BLT_USER_INTERRUPT)
+		notify_ring(dev, &dev_priv->ring[BCS]);
+
+	if (de_iir & DE_GSE_IVB)
+		intel_opregion_gse_intr(dev);
+
+	if (de_iir & DE_PLANEA_FLIP_DONE_IVB) {
+		intel_prepare_page_flip(dev, 0);
+		intel_finish_page_flip_plane(dev, 0);
+	}
+
+	if (de_iir & DE_PLANEB_FLIP_DONE_IVB) {
+		intel_prepare_page_flip(dev, 1);
+		intel_finish_page_flip_plane(dev, 1);
+	}
+
+	if (de_iir & DE_PIPEA_VBLANK_IVB)
+		drm_handle_vblank(dev, 0);
+
+	if (de_iir & DE_PIPEB_VBLANK_IVB)
+		drm_handle_vblank(dev, 1);
+
+	/* check event from PCH */
+	if (de_iir & DE_PCH_EVENT_IVB) {
+		if (pch_iir & SDE_HOTPLUG_MASK_CPT)
+			queue_work(dev_priv->wq, &dev_priv->hotplug_work);
+		pch_irq_handler(dev);
+	}
+
+	if (pm_iir & GEN6_PM_DEFERRED_EVENTS) {
+		unsigned long flags;
+		spin_lock_irqsave(&dev_priv->rps_lock, flags);
+		WARN(dev_priv->pm_iir & pm_iir, "Missed a PM interrupt\n");
+		I915_WRITE(GEN6_PMIMR, pm_iir);
+		dev_priv->pm_iir |= pm_iir;
+		spin_unlock_irqrestore(&dev_priv->rps_lock, flags);
+		queue_work(dev_priv->wq, &dev_priv->rps_work);
+	}
+
+	/* should clear PCH hotplug event before clear CPU irq */
+	I915_WRITE(SDEIIR, pch_iir);
+	I915_WRITE(GTIIR, gt_iir);
+	I915_WRITE(DEIIR, de_iir);
+	I915_WRITE(GEN6_PMIIR, pm_iir);
+
+done:
+	I915_WRITE(DEIER, de_ier);
+	POSTING_READ(DEIER);
+
+	return ret;
+}
+
+static irqreturn_t ironlake_irq_handler(DRM_IRQ_ARGS)
+{
+	struct drm_device *dev = (struct drm_device *) arg;
 	drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
 	int ret = IRQ_NONE;
 	u32 de_iir, gt_iir, de_ier, pch_iir, pm_iir;
@@ -457,6 +560,8 @@
 	struct drm_i915_master_private *master_priv;
 	u32 bsd_usr_interrupt = GT_BSD_USER_INTERRUPT;
 
+	atomic_inc(&dev_priv->irq_received);
+
 	if (IS_GEN6(dev))
 		bsd_usr_interrupt = GT_GEN6_BSD_USER_INTERRUPT;
 
@@ -526,13 +631,30 @@
 		i915_handle_rps_change(dev);
 	}
 
-	if (IS_GEN6(dev))
-		gen6_pm_irq_handler(dev);
+	if (IS_GEN6(dev) && pm_iir & GEN6_PM_DEFERRED_EVENTS) {
+		/*
+		 * IIR bits should never already be set because IMR should
+		 * prevent an interrupt from being shown in IIR. The warning
+		 * displays a case where we've unsafely cleared
+		 * dev_priv->pm_iir. Although missing an interrupt of the same
+		 * type is not a problem, it displays a problem in the logic.
+		 *
+		 * The mask bit in IMR is cleared by rps_work.
+		 */
+		unsigned long flags;
+		spin_lock_irqsave(&dev_priv->rps_lock, flags);
+		WARN(dev_priv->pm_iir & pm_iir, "Missed a PM interrupt\n");
+		I915_WRITE(GEN6_PMIMR, pm_iir);
+		dev_priv->pm_iir |= pm_iir;
+		spin_unlock_irqrestore(&dev_priv->rps_lock, flags);
+		queue_work(dev_priv->wq, &dev_priv->rps_work);
+	}
 
 	/* should clear PCH hotplug event before clear CPU irq */
 	I915_WRITE(SDEIIR, pch_iir);
 	I915_WRITE(GTIIR, gt_iir);
 	I915_WRITE(DEIIR, de_iir);
+	I915_WRITE(GEN6_PMIIR, pm_iir);
 
 done:
 	I915_WRITE(DEIER, de_ier);
@@ -676,7 +798,7 @@
 		err->dirty = obj->dirty;
 		err->purgeable = obj->madv != I915_MADV_WILLNEED;
 		err->ring = obj->ring ? obj->ring->id : 0;
-		err->agp_type = obj->agp_type == AGP_USER_CACHED_MEMORY;
+		err->cache_level = obj->cache_level;
 
 		if (++i == count)
 			break;
@@ -1087,7 +1209,7 @@
 	}
 }
 
-irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
+static irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
 {
 	struct drm_device *dev = (struct drm_device *) arg;
 	drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
@@ -1103,9 +1225,6 @@
 
 	atomic_inc(&dev_priv->irq_received);
 
-	if (HAS_PCH_SPLIT(dev))
-		return ironlake_irq_handler(dev);
-
 	iir = I915_READ(IIR);
 
 	if (INTEL_INFO(dev)->gen >= 4)
@@ -1335,7 +1454,7 @@
 /* Called from drm generic code, passed 'crtc' which
  * we use as a pipe index
  */
-int i915_enable_vblank(struct drm_device *dev, int pipe)
+static int i915_enable_vblank(struct drm_device *dev, int pipe)
 {
 	drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
 	unsigned long irqflags;
@@ -1344,10 +1463,7 @@
 		return -EINVAL;
 
 	spin_lock_irqsave(&dev_priv->irq_lock, irqflags);
-	if (HAS_PCH_SPLIT(dev))
-		ironlake_enable_display_irq(dev_priv, (pipe == 0) ?
-					    DE_PIPEA_VBLANK: DE_PIPEB_VBLANK);
-	else if (INTEL_INFO(dev)->gen >= 4)
+	if (INTEL_INFO(dev)->gen >= 4)
 		i915_enable_pipestat(dev_priv, pipe,
 				     PIPE_START_VBLANK_INTERRUPT_ENABLE);
 	else
@@ -1362,10 +1478,42 @@
 	return 0;
 }
 
+static int ironlake_enable_vblank(struct drm_device *dev, int pipe)
+{
+	drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
+	unsigned long irqflags;
+
+	if (!i915_pipe_enabled(dev, pipe))
+		return -EINVAL;
+
+	spin_lock_irqsave(&dev_priv->irq_lock, irqflags);
+	ironlake_enable_display_irq(dev_priv, (pipe == 0) ?
+				    DE_PIPEA_VBLANK: DE_PIPEB_VBLANK);
+	spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags);
+
+	return 0;
+}
+
+static int ivybridge_enable_vblank(struct drm_device *dev, int pipe)
+{
+	drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
+	unsigned long irqflags;
+
+	if (!i915_pipe_enabled(dev, pipe))
+		return -EINVAL;
+
+	spin_lock_irqsave(&dev_priv->irq_lock, irqflags);
+	ironlake_enable_display_irq(dev_priv, (pipe == 0) ?
+				    DE_PIPEA_VBLANK_IVB : DE_PIPEB_VBLANK_IVB);
+	spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags);
+
+	return 0;
+}
+
 /* Called from drm generic code, passed 'crtc' which
  * we use as a pipe index
  */
-void i915_disable_vblank(struct drm_device *dev, int pipe)
+static void i915_disable_vblank(struct drm_device *dev, int pipe)
 {
 	drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
 	unsigned long irqflags;
@@ -1375,13 +1523,31 @@
 		I915_WRITE(INSTPM,
 			   INSTPM_AGPBUSY_DIS << 16 | INSTPM_AGPBUSY_DIS);
 
-	if (HAS_PCH_SPLIT(dev))
-		ironlake_disable_display_irq(dev_priv, (pipe == 0) ?
-					     DE_PIPEA_VBLANK: DE_PIPEB_VBLANK);
-	else
-		i915_disable_pipestat(dev_priv, pipe,
-				      PIPE_VBLANK_INTERRUPT_ENABLE |
-				      PIPE_START_VBLANK_INTERRUPT_ENABLE);
+	i915_disable_pipestat(dev_priv, pipe,
+			      PIPE_VBLANK_INTERRUPT_ENABLE |
+			      PIPE_START_VBLANK_INTERRUPT_ENABLE);
+	spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags);
+}
+
+static void ironlake_disable_vblank(struct drm_device *dev, int pipe)
+{
+	drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
+	unsigned long irqflags;
+
+	spin_lock_irqsave(&dev_priv->irq_lock, irqflags);
+	ironlake_disable_display_irq(dev_priv, (pipe == 0) ?
+				     DE_PIPEA_VBLANK: DE_PIPEB_VBLANK);
+	spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags);
+}
+
+static void ivybridge_disable_vblank(struct drm_device *dev, int pipe)
+{
+	drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
+	unsigned long irqflags;
+
+	spin_lock_irqsave(&dev_priv->irq_lock, irqflags);
+	ironlake_disable_display_irq(dev_priv, (pipe == 0) ?
+				     DE_PIPEA_VBLANK_IVB : DE_PIPEB_VBLANK_IVB);
 	spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags);
 }
 
@@ -1566,7 +1732,25 @@
 {
 	drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
 
+	atomic_set(&dev_priv->irq_received, 0);
+
+	INIT_WORK(&dev_priv->hotplug_work, i915_hotplug_work_func);
+	INIT_WORK(&dev_priv->error_work, i915_error_work_func);
+	if (IS_GEN6(dev) || IS_IVYBRIDGE(dev))
+		INIT_WORK(&dev_priv->rps_work, gen6_pm_rps_work);
+
 	I915_WRITE(HWSTAM, 0xeffe);
+	if (IS_GEN6(dev) || IS_GEN7(dev)) {
+		/* Workaround stalls observed on Sandy Bridge GPUs by
+		 * making the blitter command streamer generate a
+		 * write to the Hardware Status Page for
+		 * MI_USER_INTERRUPT.  This appears to serialize the
+		 * previous seqno write out before the interrupt
+		 * happens.
+		 */
+		I915_WRITE(GEN6_BLITTER_HWSTAM, ~GEN6_BLITTER_USER_INTERRUPT);
+		I915_WRITE(GEN6_BSD_HWSTAM, ~GEN6_BSD_USER_INTERRUPT);
+	}
 
 	/* XXX hotplug from PCH */
 
@@ -1594,6 +1778,13 @@
 	u32 render_irqs;
 	u32 hotplug_mask;
 
+	DRM_INIT_WAITQUEUE(&dev_priv->ring[RCS].irq_queue);
+	if (HAS_BSD(dev))
+		DRM_INIT_WAITQUEUE(&dev_priv->ring[VCS].irq_queue);
+	if (HAS_BLT(dev))
+		DRM_INIT_WAITQUEUE(&dev_priv->ring[BCS].irq_queue);
+
+	dev_priv->vblank_pipe = DRM_I915_VBLANK_PIPE_A | DRM_I915_VBLANK_PIPE_B;
 	dev_priv->irq_mask = ~display_mask;
 
 	/* should always can generate irq */
@@ -1650,7 +1841,57 @@
 	return 0;
 }
 
-void i915_driver_irq_preinstall(struct drm_device * dev)
+static int ivybridge_irq_postinstall(struct drm_device *dev)
+{
+	drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
+	/* enable kind of interrupts always enabled */
+	u32 display_mask = DE_MASTER_IRQ_CONTROL | DE_GSE_IVB |
+		DE_PCH_EVENT_IVB | DE_PLANEA_FLIP_DONE_IVB |
+		DE_PLANEB_FLIP_DONE_IVB;
+	u32 render_irqs;
+	u32 hotplug_mask;
+
+	DRM_INIT_WAITQUEUE(&dev_priv->ring[RCS].irq_queue);
+	if (HAS_BSD(dev))
+		DRM_INIT_WAITQUEUE(&dev_priv->ring[VCS].irq_queue);
+	if (HAS_BLT(dev))
+		DRM_INIT_WAITQUEUE(&dev_priv->ring[BCS].irq_queue);
+
+	dev_priv->vblank_pipe = DRM_I915_VBLANK_PIPE_A | DRM_I915_VBLANK_PIPE_B;
+	dev_priv->irq_mask = ~display_mask;
+
+	/* should always can generate irq */
+	I915_WRITE(DEIIR, I915_READ(DEIIR));
+	I915_WRITE(DEIMR, dev_priv->irq_mask);
+	I915_WRITE(DEIER, display_mask | DE_PIPEA_VBLANK_IVB |
+		   DE_PIPEB_VBLANK_IVB);
+	POSTING_READ(DEIER);
+
+	dev_priv->gt_irq_mask = ~0;
+
+	I915_WRITE(GTIIR, I915_READ(GTIIR));
+	I915_WRITE(GTIMR, dev_priv->gt_irq_mask);
+
+	render_irqs = GT_USER_INTERRUPT | GT_GEN6_BSD_USER_INTERRUPT |
+		GT_BLT_USER_INTERRUPT;
+	I915_WRITE(GTIER, render_irqs);
+	POSTING_READ(GTIER);
+
+	hotplug_mask = (SDE_CRT_HOTPLUG_CPT |
+			SDE_PORTB_HOTPLUG_CPT |
+			SDE_PORTC_HOTPLUG_CPT |
+			SDE_PORTD_HOTPLUG_CPT);
+	dev_priv->pch_irq_mask = ~hotplug_mask;
+
+	I915_WRITE(SDEIIR, I915_READ(SDEIIR));
+	I915_WRITE(SDEIMR, dev_priv->pch_irq_mask);
+	I915_WRITE(SDEIER, hotplug_mask);
+	POSTING_READ(SDEIER);
+
+	return 0;
+}
+
+static void i915_driver_irq_preinstall(struct drm_device * dev)
 {
 	drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
 	int pipe;
@@ -1660,11 +1901,6 @@
 	INIT_WORK(&dev_priv->hotplug_work, i915_hotplug_work_func);
 	INIT_WORK(&dev_priv->error_work, i915_error_work_func);
 
-	if (HAS_PCH_SPLIT(dev)) {
-		ironlake_irq_preinstall(dev);
-		return;
-	}
-
 	if (I915_HAS_HOTPLUG(dev)) {
 		I915_WRITE(PORT_HOTPLUG_EN, 0);
 		I915_WRITE(PORT_HOTPLUG_STAT, I915_READ(PORT_HOTPLUG_STAT));
@@ -1682,23 +1918,14 @@
  * Must be called after intel_modeset_init or hotplug interrupts won't be
  * enabled correctly.
  */
-int i915_driver_irq_postinstall(struct drm_device *dev)
+static int i915_driver_irq_postinstall(struct drm_device *dev)
 {
 	drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
 	u32 enable_mask = I915_INTERRUPT_ENABLE_FIX | I915_INTERRUPT_ENABLE_VAR;
 	u32 error_mask;
 
-	DRM_INIT_WAITQUEUE(&dev_priv->ring[RCS].irq_queue);
-	if (HAS_BSD(dev))
-		DRM_INIT_WAITQUEUE(&dev_priv->ring[VCS].irq_queue);
-	if (HAS_BLT(dev))
-		DRM_INIT_WAITQUEUE(&dev_priv->ring[BCS].irq_queue);
-
 	dev_priv->vblank_pipe = DRM_I915_VBLANK_PIPE_A | DRM_I915_VBLANK_PIPE_B;
 
-	if (HAS_PCH_SPLIT(dev))
-		return ironlake_irq_postinstall(dev);
-
 	/* Unmask the interrupts that we always want on. */
 	dev_priv->irq_mask = ~I915_INTERRUPT_ENABLE_FIX;
 
@@ -1770,6 +1997,12 @@
 static void ironlake_irq_uninstall(struct drm_device *dev)
 {
 	drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
+
+	if (!dev_priv)
+		return;
+
+	dev_priv->vblank_pipe = 0;
+
 	I915_WRITE(HWSTAM, 0xffffffff);
 
 	I915_WRITE(DEIMR, 0xffffffff);
@@ -1781,7 +2014,7 @@
 	I915_WRITE(GTIIR, I915_READ(GTIIR));
 }
 
-void i915_driver_irq_uninstall(struct drm_device * dev)
+static void i915_driver_irq_uninstall(struct drm_device * dev)
 {
 	drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
 	int pipe;
@@ -1791,11 +2024,6 @@
 
 	dev_priv->vblank_pipe = 0;
 
-	if (HAS_PCH_SPLIT(dev)) {
-		ironlake_irq_uninstall(dev);
-		return;
-	}
-
 	if (I915_HAS_HOTPLUG(dev)) {
 		I915_WRITE(PORT_HOTPLUG_EN, 0);
 		I915_WRITE(PORT_HOTPLUG_STAT, I915_READ(PORT_HOTPLUG_STAT));
@@ -1812,3 +2040,41 @@
 			   I915_READ(PIPESTAT(pipe)) & 0x8000ffff);
 	I915_WRITE(IIR, I915_READ(IIR));
 }
+
+void intel_irq_init(struct drm_device *dev)
+{
+	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_GEN5(dev) || IS_GEN6(dev) || IS_IVYBRIDGE(dev)) {
+		dev->max_vblank_count = 0xffffffff; /* full 32 bit counter */
+		dev->driver->get_vblank_counter = gm45_get_vblank_counter;
+	}
+
+
+	dev->driver->get_vblank_timestamp = i915_get_vblank_timestamp;
+	dev->driver->get_scanout_position = i915_get_crtc_scanoutpos;
+
+	if (IS_IVYBRIDGE(dev)) {
+		/* Share pre & uninstall handlers with ILK/SNB */
+		dev->driver->irq_handler = ivybridge_irq_handler;
+		dev->driver->irq_preinstall = ironlake_irq_preinstall;
+		dev->driver->irq_postinstall = ivybridge_irq_postinstall;
+		dev->driver->irq_uninstall = ironlake_irq_uninstall;
+		dev->driver->enable_vblank = ivybridge_enable_vblank;
+		dev->driver->disable_vblank = ivybridge_disable_vblank;
+	} else if (HAS_PCH_SPLIT(dev)) {
+		dev->driver->irq_handler = ironlake_irq_handler;
+		dev->driver->irq_preinstall = ironlake_irq_preinstall;
+		dev->driver->irq_postinstall = ironlake_irq_postinstall;
+		dev->driver->irq_uninstall = ironlake_irq_uninstall;
+		dev->driver->enable_vblank = ironlake_enable_vblank;
+		dev->driver->disable_vblank = ironlake_disable_vblank;
+	} else {
+		dev->driver->irq_preinstall = i915_driver_irq_preinstall;
+		dev->driver->irq_postinstall = i915_driver_irq_postinstall;
+		dev->driver->irq_uninstall = i915_driver_irq_uninstall;
+		dev->driver->irq_handler = i915_driver_irq_handler;
+		dev->driver->enable_vblank = i915_enable_vblank;
+		dev->driver->disable_vblank = i915_disable_vblank;
+	}
+}
diff -druN linux-2.6.39-libre/drivers/gpu/drm/i915/i915_reg.h linux-3.0-rc7-libre/drivers/gpu/drm/i915/i915_reg.h
--- linux-2.6.39-libre/drivers/gpu/drm/i915/i915_reg.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/gpu/drm/i915/i915_reg.h	2011-07-11 19:51:52.000000000 -0400
@@ -291,6 +291,9 @@
 #define RING_MAX_IDLE(base)	((base)+0x54)
 #define RING_HWS_PGA(base)	((base)+0x80)
 #define RING_HWS_PGA_GEN6(base)	((base)+0x2080)
+#define RENDER_HWS_PGA_GEN7	(0x04080)
+#define BSD_HWS_PGA_GEN7	(0x04180)
+#define BLT_HWS_PGA_GEN7	(0x04280)
 #define RING_ACTHD(base)	((base)+0x74)
 #define RING_NOPID(base)	((base)+0x94)
 #define RING_IMR(base)		((base)+0xa8)
@@ -528,6 +531,7 @@
 #define   GEN6_BSD_SLEEP_PSMI_CONTROL_RC_ILDL_MESSAGE_ENABLE		0
 #define   GEN6_BSD_SLEEP_PSMI_CONTROL_IDLE_INDICATOR			(1 << 3)
 
+#define GEN6_BSD_HWSTAM			0x12098
 #define GEN6_BSD_IMR			0x120a8
 #define   GEN6_BSD_USER_INTERRUPT	(1 << 12)
 
@@ -2778,6 +2782,19 @@
 #define DE_PIPEA_VSYNC          (1 << 3)
 #define DE_PIPEA_FIFO_UNDERRUN  (1 << 0)
 
+/* More Ivybridge lolz */
+#define DE_ERR_DEBUG_IVB		(1<<30)
+#define DE_GSE_IVB			(1<<29)
+#define DE_PCH_EVENT_IVB		(1<<28)
+#define DE_DP_A_HOTPLUG_IVB		(1<<27)
+#define DE_AUX_CHANNEL_A_IVB		(1<<26)
+#define DE_SPRITEB_FLIP_DONE_IVB	(1<<9)
+#define DE_SPRITEA_FLIP_DONE_IVB	(1<<4)
+#define DE_PLANEB_FLIP_DONE_IVB		(1<<8)
+#define DE_PLANEA_FLIP_DONE_IVB		(1<<3)
+#define DE_PIPEB_VBLANK_IVB		(1<<5)
+#define DE_PIPEA_VBLANK_IVB		(1<<0)
+
 #define DEISR   0x44000
 #define DEIMR   0x44004
 #define DEIIR   0x44008
@@ -2809,6 +2826,7 @@
 #define  ILK_eDP_A_DISABLE		(1<<24)
 #define  ILK_DESKTOP			(1<<23)
 #define ILK_DSPCLK_GATE		0x42020
+#define  IVB_VRHUNIT_CLK_GATE	(1<<28)
 #define  ILK_DPARB_CLK_GATE	(1<<5)
 #define  ILK_DPFD_CLK_GATE	(1<<7)
 
@@ -3057,6 +3075,9 @@
 #define  TRANS_6BPC             (2<<5)
 #define  TRANS_12BPC            (3<<5)
 
+#define SOUTH_CHICKEN2		0xc2004
+#define  DPLS_EDP_PPS_FIX_DIS	(1<<0)
+
 #define _FDI_RXA_CHICKEN         0xc200c
 #define _FDI_RXB_CHICKEN         0xc2010
 #define  FDI_RX_PHASE_SYNC_POINTER_OVR	(1<<1)
@@ -3104,7 +3125,15 @@
 #define  FDI_TX_ENHANCE_FRAME_ENABLE    (1<<18)
 /* Ironlake: hardwired to 1 */
 #define  FDI_TX_PLL_ENABLE              (1<<14)
+
+/* Ivybridge has different bits for lolz */
+#define  FDI_LINK_TRAIN_PATTERN_1_IVB       (0<<8)
+#define  FDI_LINK_TRAIN_PATTERN_2_IVB       (1<<8)
+#define  FDI_LINK_TRAIN_PATTERN_IDLE_IVB    (2<<8)
+#define  FDI_LINK_TRAIN_NONE_IVB            (3<<8)
+
 /* both Tx and Rx */
+#define  FDI_LINK_TRAIN_AUTO		(1<<10)
 #define  FDI_SCRAMBLING_ENABLE          (0<<7)
 #define  FDI_SCRAMBLING_DISABLE         (1<<7)
 
@@ -3114,6 +3143,8 @@
 #define FDI_RX_CTL(pipe) _PIPE(pipe, _FDI_RXA_CTL, _FDI_RXB_CTL)
 #define  FDI_RX_ENABLE          (1<<31)
 /* train, dp width same as FDI_TX */
+#define  FDI_FS_ERRC_ENABLE		(1<<27)
+#define  FDI_FE_ERRC_ENABLE		(1<<26)
 #define  FDI_DP_PORT_WIDTH_X8           (7<<19)
 #define  FDI_8BPC                       (0<<16)
 #define  FDI_10BPC                      (1<<16)
@@ -3386,7 +3417,7 @@
 #define GEN6_PMINTRMSK				0xA168
 
 #define GEN6_PMISR				0x44020
-#define GEN6_PMIMR				0x44024
+#define GEN6_PMIMR				0x44024 /* rps_lock */
 #define GEN6_PMIIR				0x44028
 #define GEN6_PMIER				0x4402C
 #define  GEN6_PM_MBOX_EVENT			(1<<25)
@@ -3396,6 +3427,9 @@
 #define  GEN6_PM_RP_DOWN_THRESHOLD		(1<<4)
 #define  GEN6_PM_RP_UP_EI_EXPIRED		(1<<2)
 #define  GEN6_PM_RP_DOWN_EI_EXPIRED		(1<<1)
+#define  GEN6_PM_DEFERRED_EVENTS		(GEN6_PM_RP_UP_THRESHOLD | \
+						 GEN6_PM_RP_DOWN_THRESHOLD | \
+						 GEN6_PM_RP_DOWN_TIMEOUT)
 
 #define GEN6_PCODE_MAILBOX			0x138124
 #define   GEN6_PCODE_READY			(1<<31)
diff -druN linux-2.6.39-libre/drivers/gpu/drm/i915/i915_suspend.c linux-3.0-rc7-libre/drivers/gpu/drm/i915/i915_suspend.c
--- linux-2.6.39-libre/drivers/gpu/drm/i915/i915_suspend.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/gpu/drm/i915/i915_suspend.c	2011-07-11 19:51:52.000000000 -0400
@@ -597,7 +597,7 @@
 	return;
 }
 
-void i915_save_display(struct drm_device *dev)
+static void i915_save_display(struct drm_device *dev)
 {
 	struct drm_i915_private *dev_priv = dev->dev_private;
 
@@ -689,7 +689,7 @@
 	i915_save_vga(dev);
 }
 
-void i915_restore_display(struct drm_device *dev)
+static void i915_restore_display(struct drm_device *dev)
 {
 	struct drm_i915_private *dev_priv = dev->dev_private;
 
@@ -780,6 +780,7 @@
 		I915_WRITE(CPU_VGACNTRL, dev_priv->saveVGACNTRL);
 	else
 		I915_WRITE(VGACNTRL, dev_priv->saveVGACNTRL);
+
 	I915_WRITE(VGA0, dev_priv->saveVGA0);
 	I915_WRITE(VGA1, dev_priv->saveVGA1);
 	I915_WRITE(VGA_PD, dev_priv->saveVGA_PD);
@@ -796,6 +797,8 @@
 
 	pci_read_config_byte(dev->pdev, LBB, &dev_priv->saveLBB);
 
+	mutex_lock(&dev->struct_mutex);
+
 	/* Hardware status page */
 	dev_priv->saveHWS = I915_READ(HWS_PGA);
 
@@ -835,6 +838,8 @@
 	for (i = 0; i < 3; i++)
 		dev_priv->saveSWF2[i] = I915_READ(SWF30 + (i << 2));
 
+	mutex_unlock(&dev->struct_mutex);
+
 	return 0;
 }
 
@@ -845,6 +850,8 @@
 
 	pci_write_config_byte(dev->pdev, LBB, dev_priv->saveLBB);
 
+	mutex_lock(&dev->struct_mutex);
+
 	/* Hardware status page */
 	I915_WRITE(HWS_PGA, dev_priv->saveHWS);
 
@@ -862,9 +869,9 @@
 		I915_WRITE(IER, dev_priv->saveIER);
 		I915_WRITE(IMR, dev_priv->saveIMR);
 	}
+	mutex_unlock(&dev->struct_mutex);
 
-	/* Clock gating state */
-	intel_enable_clock_gating(dev);
+	intel_init_clock_gating(dev);
 
 	if (IS_IRONLAKE_M(dev)) {
 		ironlake_enable_drps(dev);
@@ -874,6 +881,8 @@
 	if (IS_GEN6(dev))
 		gen6_enable_rps(dev_priv);
 
+	mutex_lock(&dev->struct_mutex);
+
 	/* Cache mode state */
 	I915_WRITE (CACHE_MODE_0, dev_priv->saveCACHE_MODE_0 | 0xffff0000);
 
@@ -887,6 +896,8 @@
 	for (i = 0; i < 3; i++)
 		I915_WRITE(SWF30 + (i << 2), dev_priv->saveSWF2[i]);
 
+	mutex_unlock(&dev->struct_mutex);
+
 	intel_i2c_reset(dev);
 
 	return 0;
diff -druN linux-2.6.39-libre/drivers/gpu/drm/i915/intel_bios.c linux-3.0-rc7-libre/drivers/gpu/drm/i915/intel_bios.c
--- linux-2.6.39-libre/drivers/gpu/drm/i915/intel_bios.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/gpu/drm/i915/intel_bios.c	2011-07-11 19:51:52.000000000 -0400
@@ -214,9 +214,9 @@
 	    i915_lvds_downclock) {
 		dev_priv->lvds_downclock_avail = 1;
 		dev_priv->lvds_downclock = temp_downclock;
-		DRM_DEBUG_KMS("LVDS downclock is found in VBT. ",
-				"Normal Clock %dKHz, downclock %dKHz\n",
-				temp_downclock, panel_fixed_mode->clock);
+		DRM_DEBUG_KMS("LVDS downclock is found in VBT. "
+			      "Normal Clock %dKHz, downclock %dKHz\n",
+			      temp_downclock, panel_fixed_mode->clock);
 	}
 	return;
 }
diff -druN linux-2.6.39-libre/drivers/gpu/drm/i915/intel_crt.c linux-3.0-rc7-libre/drivers/gpu/drm/i915/intel_crt.c
--- linux-2.6.39-libre/drivers/gpu/drm/i915/intel_crt.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/gpu/drm/i915/intel_crt.c	2011-07-11 19:51:52.000000000 -0400
@@ -288,6 +288,8 @@
 		 * This may be a DVI-I connector with a shared DDC
 		 * link between analog and digital outputs, so we
 		 * have to check the EDID input spec of the attached device.
+		 *
+		 * On the other hand, what should we do if it is a broken EDID?
 		 */
 		if (edid != NULL) {
 			is_digital = edid->input & DRM_EDID_INPUT_DIGITAL;
@@ -298,6 +300,8 @@
 		if (!is_digital) {
 			DRM_DEBUG_KMS("CRT detected via DDC:0x50 [EDID]\n");
 			return true;
+		} else {
+			DRM_DEBUG_KMS("CRT not detected via DDC:0x50 [EDID reports a digital panel]\n");
 		}
 	}
 
@@ -305,13 +309,11 @@
 }
 
 static enum drm_connector_status
-intel_crt_load_detect(struct drm_crtc *crtc, struct intel_crt *crt)
+intel_crt_load_detect(struct intel_crt *crt)
 {
-	struct drm_encoder *encoder = &crt->base.base;
-	struct drm_device *dev = encoder->dev;
+	struct drm_device *dev = crt->base.base.dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
-	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
-	uint32_t pipe = intel_crtc->pipe;
+	uint32_t pipe = to_intel_crtc(crt->base.base.crtc)->pipe;
 	uint32_t save_bclrpat;
 	uint32_t save_vtotal;
 	uint32_t vtotal, vactive;
@@ -432,7 +434,6 @@
 	struct drm_device *dev = connector->dev;
 	struct intel_crt *crt = intel_attached_crt(connector);
 	struct drm_crtc *crtc;
-	int dpms_mode;
 	enum drm_connector_status status;
 
 	if (I915_HAS_HOTPLUG(dev)) {
@@ -454,17 +455,18 @@
 	/* for pre-945g platforms use load detect */
 	crtc = crt->base.base.crtc;
 	if (crtc && crtc->enabled) {
-		status = intel_crt_load_detect(crtc, crt);
+		status = intel_crt_load_detect(crt);
 	} else {
-		crtc = intel_get_load_detect_pipe(&crt->base, connector,
-						  NULL, &dpms_mode);
-		if (crtc) {
+		struct intel_load_detect_pipe tmp;
+
+		if (intel_get_load_detect_pipe(&crt->base, connector, NULL,
+					       &tmp)) {
 			if (intel_crt_detect_ddc(connector))
 				status = connector_status_connected;
 			else
-				status = intel_crt_load_detect(crtc, crt);
-			intel_release_load_detect_pipe(&crt->base,
-						       connector, dpms_mode);
+				status = intel_crt_load_detect(crt);
+			intel_release_load_detect_pipe(&crt->base, connector,
+						       &tmp);
 		} else
 			status = connector_status_unknown;
 	}
diff -druN linux-2.6.39-libre/drivers/gpu/drm/i915/intel_display.c linux-3.0-rc7-libre/drivers/gpu/drm/i915/intel_display.c
--- linux-2.6.39-libre/drivers/gpu/drm/i915/intel_display.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/gpu/drm/i915/intel_display.c	2011-07-11 19:51:52.000000000 -0400
@@ -76,255 +76,6 @@
 		      int, int, intel_clock_t *);
 };
 
-#define I8XX_DOT_MIN		  25000
-#define I8XX_DOT_MAX		 350000
-#define I8XX_VCO_MIN		 930000
-#define I8XX_VCO_MAX		1400000
-#define I8XX_N_MIN		      3
-#define I8XX_N_MAX		     16
-#define I8XX_M_MIN		     96
-#define I8XX_M_MAX		    140
-#define I8XX_M1_MIN		     18
-#define I8XX_M1_MAX		     26
-#define I8XX_M2_MIN		      6
-#define I8XX_M2_MAX		     16
-#define I8XX_P_MIN		      4
-#define I8XX_P_MAX		    128
-#define I8XX_P1_MIN		      2
-#define I8XX_P1_MAX		     33
-#define I8XX_P1_LVDS_MIN	      1
-#define I8XX_P1_LVDS_MAX	      6
-#define I8XX_P2_SLOW		      4
-#define I8XX_P2_FAST		      2
-#define I8XX_P2_LVDS_SLOW	      14
-#define I8XX_P2_LVDS_FAST	      7
-#define I8XX_P2_SLOW_LIMIT	 165000
-
-#define I9XX_DOT_MIN		  20000
-#define I9XX_DOT_MAX		 400000
-#define I9XX_VCO_MIN		1400000
-#define I9XX_VCO_MAX		2800000
-#define PINEVIEW_VCO_MIN		1700000
-#define PINEVIEW_VCO_MAX		3500000
-#define I9XX_N_MIN		      1
-#define I9XX_N_MAX		      6
-/* Pineview's Ncounter is a ring counter */
-#define PINEVIEW_N_MIN		      3
-#define PINEVIEW_N_MAX		      6
-#define I9XX_M_MIN		     70
-#define I9XX_M_MAX		    120
-#define PINEVIEW_M_MIN		      2
-#define PINEVIEW_M_MAX		    256
-#define I9XX_M1_MIN		     10
-#define I9XX_M1_MAX		     22
-#define I9XX_M2_MIN		      5
-#define I9XX_M2_MAX		      9
-/* Pineview M1 is reserved, and must be 0 */
-#define PINEVIEW_M1_MIN		      0
-#define PINEVIEW_M1_MAX		      0
-#define PINEVIEW_M2_MIN		      0
-#define PINEVIEW_M2_MAX		      254
-#define I9XX_P_SDVO_DAC_MIN	      5
-#define I9XX_P_SDVO_DAC_MAX	     80
-#define I9XX_P_LVDS_MIN		      7
-#define I9XX_P_LVDS_MAX		     98
-#define PINEVIEW_P_LVDS_MIN		      7
-#define PINEVIEW_P_LVDS_MAX		     112
-#define I9XX_P1_MIN		      1
-#define I9XX_P1_MAX		      8
-#define I9XX_P2_SDVO_DAC_SLOW		     10
-#define I9XX_P2_SDVO_DAC_FAST		      5
-#define I9XX_P2_SDVO_DAC_SLOW_LIMIT	 200000
-#define I9XX_P2_LVDS_SLOW		     14
-#define I9XX_P2_LVDS_FAST		      7
-#define I9XX_P2_LVDS_SLOW_LIMIT		 112000
-
-/*The parameter is for SDVO on G4x platform*/
-#define G4X_DOT_SDVO_MIN           25000
-#define G4X_DOT_SDVO_MAX           270000
-#define G4X_VCO_MIN                1750000
-#define G4X_VCO_MAX                3500000
-#define G4X_N_SDVO_MIN             1
-#define G4X_N_SDVO_MAX             4
-#define G4X_M_SDVO_MIN             104
-#define G4X_M_SDVO_MAX             138
-#define G4X_M1_SDVO_MIN            17
-#define G4X_M1_SDVO_MAX            23
-#define G4X_M2_SDVO_MIN            5
-#define G4X_M2_SDVO_MAX            11
-#define G4X_P_SDVO_MIN             10
-#define G4X_P_SDVO_MAX             30
-#define G4X_P1_SDVO_MIN            1
-#define G4X_P1_SDVO_MAX            3
-#define G4X_P2_SDVO_SLOW           10
-#define G4X_P2_SDVO_FAST           10
-#define G4X_P2_SDVO_LIMIT          270000
-
-/*The parameter is for HDMI_DAC on G4x platform*/
-#define G4X_DOT_HDMI_DAC_MIN           22000
-#define G4X_DOT_HDMI_DAC_MAX           400000
-#define G4X_N_HDMI_DAC_MIN             1
-#define G4X_N_HDMI_DAC_MAX             4
-#define G4X_M_HDMI_DAC_MIN             104
-#define G4X_M_HDMI_DAC_MAX             138
-#define G4X_M1_HDMI_DAC_MIN            16
-#define G4X_M1_HDMI_DAC_MAX            23
-#define G4X_M2_HDMI_DAC_MIN            5
-#define G4X_M2_HDMI_DAC_MAX            11
-#define G4X_P_HDMI_DAC_MIN             5
-#define G4X_P_HDMI_DAC_MAX             80
-#define G4X_P1_HDMI_DAC_MIN            1
-#define G4X_P1_HDMI_DAC_MAX            8
-#define G4X_P2_HDMI_DAC_SLOW           10
-#define G4X_P2_HDMI_DAC_FAST           5
-#define G4X_P2_HDMI_DAC_LIMIT          165000
-
-/*The parameter is for SINGLE_CHANNEL_LVDS on G4x platform*/
-#define G4X_DOT_SINGLE_CHANNEL_LVDS_MIN           20000
-#define G4X_DOT_SINGLE_CHANNEL_LVDS_MAX           115000
-#define G4X_N_SINGLE_CHANNEL_LVDS_MIN             1
-#define G4X_N_SINGLE_CHANNEL_LVDS_MAX             3
-#define G4X_M_SINGLE_CHANNEL_LVDS_MIN             104
-#define G4X_M_SINGLE_CHANNEL_LVDS_MAX             138
-#define G4X_M1_SINGLE_CHANNEL_LVDS_MIN            17
-#define G4X_M1_SINGLE_CHANNEL_LVDS_MAX            23
-#define G4X_M2_SINGLE_CHANNEL_LVDS_MIN            5
-#define G4X_M2_SINGLE_CHANNEL_LVDS_MAX            11
-#define G4X_P_SINGLE_CHANNEL_LVDS_MIN             28
-#define G4X_P_SINGLE_CHANNEL_LVDS_MAX             112
-#define G4X_P1_SINGLE_CHANNEL_LVDS_MIN            2
-#define G4X_P1_SINGLE_CHANNEL_LVDS_MAX            8
-#define G4X_P2_SINGLE_CHANNEL_LVDS_SLOW           14
-#define G4X_P2_SINGLE_CHANNEL_LVDS_FAST           14
-#define G4X_P2_SINGLE_CHANNEL_LVDS_LIMIT          0
-
-/*The parameter is for DUAL_CHANNEL_LVDS on G4x platform*/
-#define G4X_DOT_DUAL_CHANNEL_LVDS_MIN           80000
-#define G4X_DOT_DUAL_CHANNEL_LVDS_MAX           224000
-#define G4X_N_DUAL_CHANNEL_LVDS_MIN             1
-#define G4X_N_DUAL_CHANNEL_LVDS_MAX             3
-#define G4X_M_DUAL_CHANNEL_LVDS_MIN             104
-#define G4X_M_DUAL_CHANNEL_LVDS_MAX             138
-#define G4X_M1_DUAL_CHANNEL_LVDS_MIN            17
-#define G4X_M1_DUAL_CHANNEL_LVDS_MAX            23
-#define G4X_M2_DUAL_CHANNEL_LVDS_MIN            5
-#define G4X_M2_DUAL_CHANNEL_LVDS_MAX            11
-#define G4X_P_DUAL_CHANNEL_LVDS_MIN             14
-#define G4X_P_DUAL_CHANNEL_LVDS_MAX             42
-#define G4X_P1_DUAL_CHANNEL_LVDS_MIN            2
-#define G4X_P1_DUAL_CHANNEL_LVDS_MAX            6
-#define G4X_P2_DUAL_CHANNEL_LVDS_SLOW           7
-#define G4X_P2_DUAL_CHANNEL_LVDS_FAST           7
-#define G4X_P2_DUAL_CHANNEL_LVDS_LIMIT          0
-
-/*The parameter is for DISPLAY PORT on G4x platform*/
-#define G4X_DOT_DISPLAY_PORT_MIN           161670
-#define G4X_DOT_DISPLAY_PORT_MAX           227000
-#define G4X_N_DISPLAY_PORT_MIN             1
-#define G4X_N_DISPLAY_PORT_MAX             2
-#define G4X_M_DISPLAY_PORT_MIN             97
-#define G4X_M_DISPLAY_PORT_MAX             108
-#define G4X_M1_DISPLAY_PORT_MIN            0x10
-#define G4X_M1_DISPLAY_PORT_MAX            0x12
-#define G4X_M2_DISPLAY_PORT_MIN            0x05
-#define G4X_M2_DISPLAY_PORT_MAX            0x06
-#define G4X_P_DISPLAY_PORT_MIN             10
-#define G4X_P_DISPLAY_PORT_MAX             20
-#define G4X_P1_DISPLAY_PORT_MIN            1
-#define G4X_P1_DISPLAY_PORT_MAX            2
-#define G4X_P2_DISPLAY_PORT_SLOW           10
-#define G4X_P2_DISPLAY_PORT_FAST           10
-#define G4X_P2_DISPLAY_PORT_LIMIT          0
-
-/* 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).
- */
-#define IRONLAKE_DOT_MIN         25000
-#define IRONLAKE_DOT_MAX         350000
-#define IRONLAKE_VCO_MIN         1760000
-#define IRONLAKE_VCO_MAX         3510000
-#define IRONLAKE_M1_MIN          12
-#define IRONLAKE_M1_MAX          22
-#define IRONLAKE_M2_MIN          5
-#define IRONLAKE_M2_MAX          9
-#define IRONLAKE_P2_DOT_LIMIT    225000 /* 225Mhz */
-
-/* We have parameter ranges for different type of outputs. */
-
-/* DAC & HDMI Refclk 120Mhz */
-#define IRONLAKE_DAC_N_MIN	1
-#define IRONLAKE_DAC_N_MAX	5
-#define IRONLAKE_DAC_M_MIN	79
-#define IRONLAKE_DAC_M_MAX	127
-#define IRONLAKE_DAC_P_MIN	5
-#define IRONLAKE_DAC_P_MAX	80
-#define IRONLAKE_DAC_P1_MIN	1
-#define IRONLAKE_DAC_P1_MAX	8
-#define IRONLAKE_DAC_P2_SLOW	10
-#define IRONLAKE_DAC_P2_FAST	5
-
-/* LVDS single-channel 120Mhz refclk */
-#define IRONLAKE_LVDS_S_N_MIN	1
-#define IRONLAKE_LVDS_S_N_MAX	3
-#define IRONLAKE_LVDS_S_M_MIN	79
-#define IRONLAKE_LVDS_S_M_MAX	118
-#define IRONLAKE_LVDS_S_P_MIN	28
-#define IRONLAKE_LVDS_S_P_MAX	112
-#define IRONLAKE_LVDS_S_P1_MIN	2
-#define IRONLAKE_LVDS_S_P1_MAX	8
-#define IRONLAKE_LVDS_S_P2_SLOW	14
-#define IRONLAKE_LVDS_S_P2_FAST	14
-
-/* LVDS dual-channel 120Mhz refclk */
-#define IRONLAKE_LVDS_D_N_MIN	1
-#define IRONLAKE_LVDS_D_N_MAX	3
-#define IRONLAKE_LVDS_D_M_MIN	79
-#define IRONLAKE_LVDS_D_M_MAX	127
-#define IRONLAKE_LVDS_D_P_MIN	14
-#define IRONLAKE_LVDS_D_P_MAX	56
-#define IRONLAKE_LVDS_D_P1_MIN	2
-#define IRONLAKE_LVDS_D_P1_MAX	8
-#define IRONLAKE_LVDS_D_P2_SLOW	7
-#define IRONLAKE_LVDS_D_P2_FAST	7
-
-/* LVDS single-channel 100Mhz refclk */
-#define IRONLAKE_LVDS_S_SSC_N_MIN	1
-#define IRONLAKE_LVDS_S_SSC_N_MAX	2
-#define IRONLAKE_LVDS_S_SSC_M_MIN	79
-#define IRONLAKE_LVDS_S_SSC_M_MAX	126
-#define IRONLAKE_LVDS_S_SSC_P_MIN	28
-#define IRONLAKE_LVDS_S_SSC_P_MAX	112
-#define IRONLAKE_LVDS_S_SSC_P1_MIN	2
-#define IRONLAKE_LVDS_S_SSC_P1_MAX	8
-#define IRONLAKE_LVDS_S_SSC_P2_SLOW	14
-#define IRONLAKE_LVDS_S_SSC_P2_FAST	14
-
-/* LVDS dual-channel 100Mhz refclk */
-#define IRONLAKE_LVDS_D_SSC_N_MIN	1
-#define IRONLAKE_LVDS_D_SSC_N_MAX	3
-#define IRONLAKE_LVDS_D_SSC_M_MIN	79
-#define IRONLAKE_LVDS_D_SSC_M_MAX	126
-#define IRONLAKE_LVDS_D_SSC_P_MIN	14
-#define IRONLAKE_LVDS_D_SSC_P_MAX	42
-#define IRONLAKE_LVDS_D_SSC_P1_MIN	2
-#define IRONLAKE_LVDS_D_SSC_P1_MAX	6
-#define IRONLAKE_LVDS_D_SSC_P2_SLOW	7
-#define IRONLAKE_LVDS_D_SSC_P2_FAST	7
-
-/* DisplayPort */
-#define IRONLAKE_DP_N_MIN		1
-#define IRONLAKE_DP_N_MAX		2
-#define IRONLAKE_DP_M_MIN		81
-#define IRONLAKE_DP_M_MAX		90
-#define IRONLAKE_DP_P_MIN		10
-#define IRONLAKE_DP_P_MAX		20
-#define IRONLAKE_DP_P2_FAST		10
-#define IRONLAKE_DP_P2_SLOW		10
-#define IRONLAKE_DP_P2_LIMIT		0
-#define IRONLAKE_DP_P1_MIN		1
-#define IRONLAKE_DP_P1_MAX		2
-
 /* FDI */
 #define IRONLAKE_FDI_FREQ		2700000 /* in kHz for mode->clock */
 
@@ -353,292 +104,253 @@
 }
 
 static const intel_limit_t intel_limits_i8xx_dvo = {
-        .dot = { .min = I8XX_DOT_MIN,		.max = I8XX_DOT_MAX },
-        .vco = { .min = I8XX_VCO_MIN,		.max = I8XX_VCO_MAX },
-        .n   = { .min = I8XX_N_MIN,		.max = I8XX_N_MAX },
-        .m   = { .min = I8XX_M_MIN,		.max = I8XX_M_MAX },
-        .m1  = { .min = I8XX_M1_MIN,		.max = I8XX_M1_MAX },
-        .m2  = { .min = I8XX_M2_MIN,		.max = I8XX_M2_MAX },
-        .p   = { .min = I8XX_P_MIN,		.max = I8XX_P_MAX },
-        .p1  = { .min = I8XX_P1_MIN,		.max = I8XX_P1_MAX },
-	.p2  = { .dot_limit = I8XX_P2_SLOW_LIMIT,
-		 .p2_slow = I8XX_P2_SLOW,	.p2_fast = I8XX_P2_FAST },
+        .dot = { .min = 25000, .max = 350000 },
+        .vco = { .min = 930000, .max = 1400000 },
+        .n = { .min = 3, .max = 16 },
+        .m = { .min = 96, .max = 140 },
+        .m1 = { .min = 18, .max = 26 },
+        .m2 = { .min = 6, .max = 16 },
+        .p = { .min = 4, .max = 128 },
+        .p1 = { .min = 2, .max = 33 },
+	.p2 = { .dot_limit = 165000,
+		.p2_slow = 4, .p2_fast = 2 },
 	.find_pll = intel_find_best_PLL,
 };
 
 static const intel_limit_t intel_limits_i8xx_lvds = {
-        .dot = { .min = I8XX_DOT_MIN,		.max = I8XX_DOT_MAX },
-        .vco = { .min = I8XX_VCO_MIN,		.max = I8XX_VCO_MAX },
-        .n   = { .min = I8XX_N_MIN,		.max = I8XX_N_MAX },
-        .m   = { .min = I8XX_M_MIN,		.max = I8XX_M_MAX },
-        .m1  = { .min = I8XX_M1_MIN,		.max = I8XX_M1_MAX },
-        .m2  = { .min = I8XX_M2_MIN,		.max = I8XX_M2_MAX },
-        .p   = { .min = I8XX_P_MIN,		.max = I8XX_P_MAX },
-        .p1  = { .min = I8XX_P1_LVDS_MIN,	.max = I8XX_P1_LVDS_MAX },
-	.p2  = { .dot_limit = I8XX_P2_SLOW_LIMIT,
-		 .p2_slow = I8XX_P2_LVDS_SLOW,	.p2_fast = I8XX_P2_LVDS_FAST },
+        .dot = { .min = 25000, .max = 350000 },
+        .vco = { .min = 930000, .max = 1400000 },
+        .n = { .min = 3, .max = 16 },
+        .m = { .min = 96, .max = 140 },
+        .m1 = { .min = 18, .max = 26 },
+        .m2 = { .min = 6, .max = 16 },
+        .p = { .min = 4, .max = 128 },
+        .p1 = { .min = 1, .max = 6 },
+	.p2 = { .dot_limit = 165000,
+		.p2_slow = 14, .p2_fast = 7 },
 	.find_pll = intel_find_best_PLL,
 };
-	
+
 static const intel_limit_t intel_limits_i9xx_sdvo = {
-        .dot = { .min = I9XX_DOT_MIN,		.max = I9XX_DOT_MAX },
-        .vco = { .min = I9XX_VCO_MIN,		.max = I9XX_VCO_MAX },
-        .n   = { .min = I9XX_N_MIN,		.max = I9XX_N_MAX },
-        .m   = { .min = I9XX_M_MIN,		.max = I9XX_M_MAX },
-        .m1  = { .min = I9XX_M1_MIN,		.max = I9XX_M1_MAX },
-        .m2  = { .min = I9XX_M2_MIN,		.max = I9XX_M2_MAX },
-        .p   = { .min = I9XX_P_SDVO_DAC_MIN,	.max = I9XX_P_SDVO_DAC_MAX },
-        .p1  = { .min = I9XX_P1_MIN,		.max = I9XX_P1_MAX },
-	.p2  = { .dot_limit = I9XX_P2_SDVO_DAC_SLOW_LIMIT,
-		 .p2_slow = I9XX_P2_SDVO_DAC_SLOW,	.p2_fast = I9XX_P2_SDVO_DAC_FAST },
+        .dot = { .min = 20000, .max = 400000 },
+        .vco = { .min = 1400000, .max = 2800000 },
+        .n = { .min = 1, .max = 6 },
+        .m = { .min = 70, .max = 120 },
+        .m1 = { .min = 10, .max = 22 },
+        .m2 = { .min = 5, .max = 9 },
+        .p = { .min = 5, .max = 80 },
+        .p1 = { .min = 1, .max = 8 },
+	.p2 = { .dot_limit = 200000,
+		.p2_slow = 10, .p2_fast = 5 },
 	.find_pll = intel_find_best_PLL,
 };
 
 static const intel_limit_t intel_limits_i9xx_lvds = {
-        .dot = { .min = I9XX_DOT_MIN,		.max = I9XX_DOT_MAX },
-        .vco = { .min = I9XX_VCO_MIN,		.max = I9XX_VCO_MAX },
-        .n   = { .min = I9XX_N_MIN,		.max = I9XX_N_MAX },
-        .m   = { .min = I9XX_M_MIN,		.max = I9XX_M_MAX },
-        .m1  = { .min = I9XX_M1_MIN,		.max = I9XX_M1_MAX },
-        .m2  = { .min = I9XX_M2_MIN,		.max = I9XX_M2_MAX },
-        .p   = { .min = I9XX_P_LVDS_MIN,	.max = I9XX_P_LVDS_MAX },
-        .p1  = { .min = I9XX_P1_MIN,		.max = I9XX_P1_MAX },
-	/* The single-channel range is 25-112Mhz, and dual-channel
-	 * is 80-224Mhz.  Prefer single channel as much as possible.
-	 */
-	.p2  = { .dot_limit = I9XX_P2_LVDS_SLOW_LIMIT,
-		 .p2_slow = I9XX_P2_LVDS_SLOW,	.p2_fast = I9XX_P2_LVDS_FAST },
+        .dot = { .min = 20000, .max = 400000 },
+        .vco = { .min = 1400000, .max = 2800000 },
+        .n = { .min = 1, .max = 6 },
+        .m = { .min = 70, .max = 120 },
+        .m1 = { .min = 10, .max = 22 },
+        .m2 = { .min = 5, .max = 9 },
+        .p = { .min = 7, .max = 98 },
+        .p1 = { .min = 1, .max = 8 },
+	.p2 = { .dot_limit = 112000,
+		.p2_slow = 14, .p2_fast = 7 },
 	.find_pll = intel_find_best_PLL,
 };
 
-    /* below parameter and function is for G4X Chipset Family*/
+
 static const intel_limit_t intel_limits_g4x_sdvo = {
-	.dot = { .min = G4X_DOT_SDVO_MIN,	.max = G4X_DOT_SDVO_MAX },
-	.vco = { .min = G4X_VCO_MIN,	        .max = G4X_VCO_MAX},
-	.n   = { .min = G4X_N_SDVO_MIN,	        .max = G4X_N_SDVO_MAX },
-	.m   = { .min = G4X_M_SDVO_MIN,         .max = G4X_M_SDVO_MAX },
-	.m1  = { .min = G4X_M1_SDVO_MIN,	.max = G4X_M1_SDVO_MAX },
-	.m2  = { .min = G4X_M2_SDVO_MIN,	.max = G4X_M2_SDVO_MAX },
-	.p   = { .min = G4X_P_SDVO_MIN,         .max = G4X_P_SDVO_MAX },
-	.p1  = { .min = G4X_P1_SDVO_MIN,	.max = G4X_P1_SDVO_MAX},
-	.p2  = { .dot_limit = G4X_P2_SDVO_LIMIT,
-		 .p2_slow = G4X_P2_SDVO_SLOW,
-		 .p2_fast = G4X_P2_SDVO_FAST
+	.dot = { .min = 25000, .max = 270000 },
+	.vco = { .min = 1750000, .max = 3500000},
+	.n = { .min = 1, .max = 4 },
+	.m = { .min = 104, .max = 138 },
+	.m1 = { .min = 17, .max = 23 },
+	.m2 = { .min = 5, .max = 11 },
+	.p = { .min = 10, .max = 30 },
+	.p1 = { .min = 1, .max = 3},
+	.p2 = { .dot_limit = 270000,
+		.p2_slow = 10,
+		.p2_fast = 10
 	},
 	.find_pll = intel_g4x_find_best_PLL,
 };
 
 static const intel_limit_t intel_limits_g4x_hdmi = {
-	.dot = { .min = G4X_DOT_HDMI_DAC_MIN,	.max = G4X_DOT_HDMI_DAC_MAX },
-	.vco = { .min = G4X_VCO_MIN,	        .max = G4X_VCO_MAX},
-	.n   = { .min = G4X_N_HDMI_DAC_MIN,	.max = G4X_N_HDMI_DAC_MAX },
-	.m   = { .min = G4X_M_HDMI_DAC_MIN,	.max = G4X_M_HDMI_DAC_MAX },
-	.m1  = { .min = G4X_M1_HDMI_DAC_MIN,	.max = G4X_M1_HDMI_DAC_MAX },
-	.m2  = { .min = G4X_M2_HDMI_DAC_MIN,	.max = G4X_M2_HDMI_DAC_MAX },
-	.p   = { .min = G4X_P_HDMI_DAC_MIN,	.max = G4X_P_HDMI_DAC_MAX },
-	.p1  = { .min = G4X_P1_HDMI_DAC_MIN,	.max = G4X_P1_HDMI_DAC_MAX},
-	.p2  = { .dot_limit = G4X_P2_HDMI_DAC_LIMIT,
-		 .p2_slow = G4X_P2_HDMI_DAC_SLOW,
-		 .p2_fast = G4X_P2_HDMI_DAC_FAST
-	},
+	.dot = { .min = 22000, .max = 400000 },
+	.vco = { .min = 1750000, .max = 3500000},
+	.n = { .min = 1, .max = 4 },
+	.m = { .min = 104, .max = 138 },
+	.m1 = { .min = 16, .max = 23 },
+	.m2 = { .min = 5, .max = 11 },
+	.p = { .min = 5, .max = 80 },
+	.p1 = { .min = 1, .max = 8},
+	.p2 = { .dot_limit = 165000,
+		.p2_slow = 10, .p2_fast = 5 },
 	.find_pll = intel_g4x_find_best_PLL,
 };
 
 static const intel_limit_t intel_limits_g4x_single_channel_lvds = {
-	.dot = { .min = G4X_DOT_SINGLE_CHANNEL_LVDS_MIN,
-		 .max = G4X_DOT_SINGLE_CHANNEL_LVDS_MAX },
-	.vco = { .min = G4X_VCO_MIN,
-		 .max = G4X_VCO_MAX },
-	.n   = { .min = G4X_N_SINGLE_CHANNEL_LVDS_MIN,
-		 .max = G4X_N_SINGLE_CHANNEL_LVDS_MAX },
-	.m   = { .min = G4X_M_SINGLE_CHANNEL_LVDS_MIN,
-		 .max = G4X_M_SINGLE_CHANNEL_LVDS_MAX },
-	.m1  = { .min = G4X_M1_SINGLE_CHANNEL_LVDS_MIN,
-		 .max = G4X_M1_SINGLE_CHANNEL_LVDS_MAX },
-	.m2  = { .min = G4X_M2_SINGLE_CHANNEL_LVDS_MIN,
-		 .max = G4X_M2_SINGLE_CHANNEL_LVDS_MAX },
-	.p   = { .min = G4X_P_SINGLE_CHANNEL_LVDS_MIN,
-		 .max = G4X_P_SINGLE_CHANNEL_LVDS_MAX },
-	.p1  = { .min = G4X_P1_SINGLE_CHANNEL_LVDS_MIN,
-		 .max = G4X_P1_SINGLE_CHANNEL_LVDS_MAX },
-	.p2  = { .dot_limit = G4X_P2_SINGLE_CHANNEL_LVDS_LIMIT,
-		 .p2_slow = G4X_P2_SINGLE_CHANNEL_LVDS_SLOW,
-		 .p2_fast = G4X_P2_SINGLE_CHANNEL_LVDS_FAST
+	.dot = { .min = 20000, .max = 115000 },
+	.vco = { .min = 1750000, .max = 3500000 },
+	.n = { .min = 1, .max = 3 },
+	.m = { .min = 104, .max = 138 },
+	.m1 = { .min = 17, .max = 23 },
+	.m2 = { .min = 5, .max = 11 },
+	.p = { .min = 28, .max = 112 },
+	.p1 = { .min = 2, .max = 8 },
+	.p2 = { .dot_limit = 0,
+		.p2_slow = 14, .p2_fast = 14
 	},
 	.find_pll = intel_g4x_find_best_PLL,
 };
 
 static const intel_limit_t intel_limits_g4x_dual_channel_lvds = {
-	.dot = { .min = G4X_DOT_DUAL_CHANNEL_LVDS_MIN,
-		 .max = G4X_DOT_DUAL_CHANNEL_LVDS_MAX },
-	.vco = { .min = G4X_VCO_MIN,
-		 .max = G4X_VCO_MAX },
-	.n   = { .min = G4X_N_DUAL_CHANNEL_LVDS_MIN,
-		 .max = G4X_N_DUAL_CHANNEL_LVDS_MAX },
-	.m   = { .min = G4X_M_DUAL_CHANNEL_LVDS_MIN,
-		 .max = G4X_M_DUAL_CHANNEL_LVDS_MAX },
-	.m1  = { .min = G4X_M1_DUAL_CHANNEL_LVDS_MIN,
-		 .max = G4X_M1_DUAL_CHANNEL_LVDS_MAX },
-	.m2  = { .min = G4X_M2_DUAL_CHANNEL_LVDS_MIN,
-		 .max = G4X_M2_DUAL_CHANNEL_LVDS_MAX },
-	.p   = { .min = G4X_P_DUAL_CHANNEL_LVDS_MIN,
-		 .max = G4X_P_DUAL_CHANNEL_LVDS_MAX },
-	.p1  = { .min = G4X_P1_DUAL_CHANNEL_LVDS_MIN,
-		 .max = G4X_P1_DUAL_CHANNEL_LVDS_MAX },
-	.p2  = { .dot_limit = G4X_P2_DUAL_CHANNEL_LVDS_LIMIT,
-		 .p2_slow = G4X_P2_DUAL_CHANNEL_LVDS_SLOW,
-		 .p2_fast = G4X_P2_DUAL_CHANNEL_LVDS_FAST
+	.dot = { .min = 80000, .max = 224000 },
+	.vco = { .min = 1750000, .max = 3500000 },
+	.n = { .min = 1, .max = 3 },
+	.m = { .min = 104, .max = 138 },
+	.m1 = { .min = 17, .max = 23 },
+	.m2 = { .min = 5, .max = 11 },
+	.p = { .min = 14, .max = 42 },
+	.p1 = { .min = 2, .max = 6 },
+	.p2 = { .dot_limit = 0,
+		.p2_slow = 7, .p2_fast = 7
 	},
 	.find_pll = intel_g4x_find_best_PLL,
 };
 
 static const intel_limit_t intel_limits_g4x_display_port = {
-        .dot = { .min = G4X_DOT_DISPLAY_PORT_MIN,
-                 .max = G4X_DOT_DISPLAY_PORT_MAX },
-        .vco = { .min = G4X_VCO_MIN,
-                 .max = G4X_VCO_MAX},
-        .n   = { .min = G4X_N_DISPLAY_PORT_MIN,
-                 .max = G4X_N_DISPLAY_PORT_MAX },
-        .m   = { .min = G4X_M_DISPLAY_PORT_MIN,
-                 .max = G4X_M_DISPLAY_PORT_MAX },
-        .m1  = { .min = G4X_M1_DISPLAY_PORT_MIN,
-                 .max = G4X_M1_DISPLAY_PORT_MAX },
-        .m2  = { .min = G4X_M2_DISPLAY_PORT_MIN,
-                 .max = G4X_M2_DISPLAY_PORT_MAX },
-        .p   = { .min = G4X_P_DISPLAY_PORT_MIN,
-                 .max = G4X_P_DISPLAY_PORT_MAX },
-        .p1  = { .min = G4X_P1_DISPLAY_PORT_MIN,
-                 .max = G4X_P1_DISPLAY_PORT_MAX},
-        .p2  = { .dot_limit = G4X_P2_DISPLAY_PORT_LIMIT,
-                 .p2_slow = G4X_P2_DISPLAY_PORT_SLOW,
-                 .p2_fast = G4X_P2_DISPLAY_PORT_FAST },
+        .dot = { .min = 161670, .max = 227000 },
+        .vco = { .min = 1750000, .max = 3500000},
+        .n = { .min = 1, .max = 2 },
+        .m = { .min = 97, .max = 108 },
+        .m1 = { .min = 0x10, .max = 0x12 },
+        .m2 = { .min = 0x05, .max = 0x06 },
+        .p = { .min = 10, .max = 20 },
+        .p1 = { .min = 1, .max = 2},
+        .p2 = { .dot_limit = 0,
+		.p2_slow = 10, .p2_fast = 10 },
         .find_pll = intel_find_pll_g4x_dp,
 };
 
 static const intel_limit_t intel_limits_pineview_sdvo = {
-        .dot = { .min = I9XX_DOT_MIN,		.max = I9XX_DOT_MAX},
-        .vco = { .min = PINEVIEW_VCO_MIN,		.max = PINEVIEW_VCO_MAX },
-        .n   = { .min = PINEVIEW_N_MIN,		.max = PINEVIEW_N_MAX },
-        .m   = { .min = PINEVIEW_M_MIN,		.max = PINEVIEW_M_MAX },
-        .m1  = { .min = PINEVIEW_M1_MIN,		.max = PINEVIEW_M1_MAX },
-        .m2  = { .min = PINEVIEW_M2_MIN,		.max = PINEVIEW_M2_MAX },
-        .p   = { .min = I9XX_P_SDVO_DAC_MIN,    .max = I9XX_P_SDVO_DAC_MAX },
-        .p1  = { .min = I9XX_P1_MIN,		.max = I9XX_P1_MAX },
-	.p2  = { .dot_limit = I9XX_P2_SDVO_DAC_SLOW_LIMIT,
-		 .p2_slow = I9XX_P2_SDVO_DAC_SLOW,	.p2_fast = I9XX_P2_SDVO_DAC_FAST },
+        .dot = { .min = 20000, .max = 400000},
+        .vco = { .min = 1700000, .max = 3500000 },
+	/* Pineview's Ncounter is a ring counter */
+        .n = { .min = 3, .max = 6 },
+        .m = { .min = 2, .max = 256 },
+	/* Pineview only has one combined m divider, which we treat as m2. */
+        .m1 = { .min = 0, .max = 0 },
+        .m2 = { .min = 0, .max = 254 },
+        .p = { .min = 5, .max = 80 },
+        .p1 = { .min = 1, .max = 8 },
+	.p2 = { .dot_limit = 200000,
+		.p2_slow = 10, .p2_fast = 5 },
 	.find_pll = intel_find_best_PLL,
 };
 
 static const intel_limit_t intel_limits_pineview_lvds = {
-        .dot = { .min = I9XX_DOT_MIN,		.max = I9XX_DOT_MAX },
-        .vco = { .min = PINEVIEW_VCO_MIN,		.max = PINEVIEW_VCO_MAX },
-        .n   = { .min = PINEVIEW_N_MIN,		.max = PINEVIEW_N_MAX },
-        .m   = { .min = PINEVIEW_M_MIN,		.max = PINEVIEW_M_MAX },
-        .m1  = { .min = PINEVIEW_M1_MIN,		.max = PINEVIEW_M1_MAX },
-        .m2  = { .min = PINEVIEW_M2_MIN,		.max = PINEVIEW_M2_MAX },
-        .p   = { .min = PINEVIEW_P_LVDS_MIN,	.max = PINEVIEW_P_LVDS_MAX },
-        .p1  = { .min = I9XX_P1_MIN,		.max = I9XX_P1_MAX },
-	/* Pineview only supports single-channel mode. */
-	.p2  = { .dot_limit = I9XX_P2_LVDS_SLOW_LIMIT,
-		 .p2_slow = I9XX_P2_LVDS_SLOW,	.p2_fast = I9XX_P2_LVDS_SLOW },
+        .dot = { .min = 20000, .max = 400000 },
+        .vco = { .min = 1700000, .max = 3500000 },
+        .n = { .min = 3, .max = 6 },
+        .m = { .min = 2, .max = 256 },
+        .m1 = { .min = 0, .max = 0 },
+        .m2 = { .min = 0, .max = 254 },
+        .p = { .min = 7, .max = 112 },
+        .p1 = { .min = 1, .max = 8 },
+	.p2 = { .dot_limit = 112000,
+		.p2_slow = 14, .p2_fast = 14 },
 	.find_pll = intel_find_best_PLL,
 };
 
+/* Ironlake / Sandybridge
+ *
+ * We calculate clock using (register_value + 2) for N/M1/M2, so here
+ * the range value for them is (actual_value - 2).
+ */
 static const intel_limit_t intel_limits_ironlake_dac = {
-	.dot = { .min = IRONLAKE_DOT_MIN,          .max = IRONLAKE_DOT_MAX },
-	.vco = { .min = IRONLAKE_VCO_MIN,          .max = IRONLAKE_VCO_MAX },
-	.n   = { .min = IRONLAKE_DAC_N_MIN,        .max = IRONLAKE_DAC_N_MAX },
-	.m   = { .min = IRONLAKE_DAC_M_MIN,        .max = IRONLAKE_DAC_M_MAX },
-	.m1  = { .min = IRONLAKE_M1_MIN,           .max = IRONLAKE_M1_MAX },
-	.m2  = { .min = IRONLAKE_M2_MIN,           .max = IRONLAKE_M2_MAX },
-	.p   = { .min = IRONLAKE_DAC_P_MIN,	   .max = IRONLAKE_DAC_P_MAX },
-	.p1  = { .min = IRONLAKE_DAC_P1_MIN,       .max = IRONLAKE_DAC_P1_MAX },
-	.p2  = { .dot_limit = IRONLAKE_P2_DOT_LIMIT,
-		 .p2_slow = IRONLAKE_DAC_P2_SLOW,
-		 .p2_fast = IRONLAKE_DAC_P2_FAST },
+	.dot = { .min = 25000, .max = 350000 },
+	.vco = { .min = 1760000, .max = 3510000 },
+	.n = { .min = 1, .max = 5 },
+	.m = { .min = 79, .max = 127 },
+	.m1 = { .min = 12, .max = 22 },
+	.m2 = { .min = 5, .max = 9 },
+	.p = { .min = 5, .max = 80 },
+	.p1 = { .min = 1, .max = 8 },
+	.p2 = { .dot_limit = 225000,
+		.p2_slow = 10, .p2_fast = 5 },
 	.find_pll = intel_g4x_find_best_PLL,
 };
 
 static const intel_limit_t intel_limits_ironlake_single_lvds = {
-	.dot = { .min = IRONLAKE_DOT_MIN,          .max = IRONLAKE_DOT_MAX },
-	.vco = { .min = IRONLAKE_VCO_MIN,          .max = IRONLAKE_VCO_MAX },
-	.n   = { .min = IRONLAKE_LVDS_S_N_MIN,     .max = IRONLAKE_LVDS_S_N_MAX },
-	.m   = { .min = IRONLAKE_LVDS_S_M_MIN,     .max = IRONLAKE_LVDS_S_M_MAX },
-	.m1  = { .min = IRONLAKE_M1_MIN,           .max = IRONLAKE_M1_MAX },
-	.m2  = { .min = IRONLAKE_M2_MIN,           .max = IRONLAKE_M2_MAX },
-	.p   = { .min = IRONLAKE_LVDS_S_P_MIN,     .max = IRONLAKE_LVDS_S_P_MAX },
-	.p1  = { .min = IRONLAKE_LVDS_S_P1_MIN,    .max = IRONLAKE_LVDS_S_P1_MAX },
-	.p2  = { .dot_limit = IRONLAKE_P2_DOT_LIMIT,
-		 .p2_slow = IRONLAKE_LVDS_S_P2_SLOW,
-		 .p2_fast = IRONLAKE_LVDS_S_P2_FAST },
+	.dot = { .min = 25000, .max = 350000 },
+	.vco = { .min = 1760000, .max = 3510000 },
+	.n = { .min = 1, .max = 3 },
+	.m = { .min = 79, .max = 118 },
+	.m1 = { .min = 12, .max = 22 },
+	.m2 = { .min = 5, .max = 9 },
+	.p = { .min = 28, .max = 112 },
+	.p1 = { .min = 2, .max = 8 },
+	.p2 = { .dot_limit = 225000,
+		.p2_slow = 14, .p2_fast = 14 },
 	.find_pll = intel_g4x_find_best_PLL,
 };
 
 static const intel_limit_t intel_limits_ironlake_dual_lvds = {
-	.dot = { .min = IRONLAKE_DOT_MIN,          .max = IRONLAKE_DOT_MAX },
-	.vco = { .min = IRONLAKE_VCO_MIN,          .max = IRONLAKE_VCO_MAX },
-	.n   = { .min = IRONLAKE_LVDS_D_N_MIN,     .max = IRONLAKE_LVDS_D_N_MAX },
-	.m   = { .min = IRONLAKE_LVDS_D_M_MIN,     .max = IRONLAKE_LVDS_D_M_MAX },
-	.m1  = { .min = IRONLAKE_M1_MIN,           .max = IRONLAKE_M1_MAX },
-	.m2  = { .min = IRONLAKE_M2_MIN,           .max = IRONLAKE_M2_MAX },
-	.p   = { .min = IRONLAKE_LVDS_D_P_MIN,     .max = IRONLAKE_LVDS_D_P_MAX },
-	.p1  = { .min = IRONLAKE_LVDS_D_P1_MIN,    .max = IRONLAKE_LVDS_D_P1_MAX },
-	.p2  = { .dot_limit = IRONLAKE_P2_DOT_LIMIT,
-		 .p2_slow = IRONLAKE_LVDS_D_P2_SLOW,
-		 .p2_fast = IRONLAKE_LVDS_D_P2_FAST },
+	.dot = { .min = 25000, .max = 350000 },
+	.vco = { .min = 1760000, .max = 3510000 },
+	.n = { .min = 1, .max = 3 },
+	.m = { .min = 79, .max = 127 },
+	.m1 = { .min = 12, .max = 22 },
+	.m2 = { .min = 5, .max = 9 },
+	.p = { .min = 14, .max = 56 },
+	.p1 = { .min = 2, .max = 8 },
+	.p2 = { .dot_limit = 225000,
+		.p2_slow = 7, .p2_fast = 7 },
 	.find_pll = intel_g4x_find_best_PLL,
 };
 
+/* LVDS 100mhz refclk limits. */
 static const intel_limit_t intel_limits_ironlake_single_lvds_100m = {
-	.dot = { .min = IRONLAKE_DOT_MIN,          .max = IRONLAKE_DOT_MAX },
-	.vco = { .min = IRONLAKE_VCO_MIN,          .max = IRONLAKE_VCO_MAX },
-	.n   = { .min = IRONLAKE_LVDS_S_SSC_N_MIN, .max = IRONLAKE_LVDS_S_SSC_N_MAX },
-	.m   = { .min = IRONLAKE_LVDS_S_SSC_M_MIN, .max = IRONLAKE_LVDS_S_SSC_M_MAX },
-	.m1  = { .min = IRONLAKE_M1_MIN,           .max = IRONLAKE_M1_MAX },
-	.m2  = { .min = IRONLAKE_M2_MIN,           .max = IRONLAKE_M2_MAX },
-	.p   = { .min = IRONLAKE_LVDS_S_SSC_P_MIN, .max = IRONLAKE_LVDS_S_SSC_P_MAX },
-	.p1  = { .min = IRONLAKE_LVDS_S_SSC_P1_MIN,.max = IRONLAKE_LVDS_S_SSC_P1_MAX },
-	.p2  = { .dot_limit = IRONLAKE_P2_DOT_LIMIT,
-		 .p2_slow = IRONLAKE_LVDS_S_SSC_P2_SLOW,
-		 .p2_fast = IRONLAKE_LVDS_S_SSC_P2_FAST },
+	.dot = { .min = 25000, .max = 350000 },
+	.vco = { .min = 1760000, .max = 3510000 },
+	.n = { .min = 1, .max = 2 },
+	.m = { .min = 79, .max = 126 },
+	.m1 = { .min = 12, .max = 22 },
+	.m2 = { .min = 5, .max = 9 },
+	.p = { .min = 28, .max = 112 },
+	.p1 = { .min = 2,.max = 8 },
+	.p2 = { .dot_limit = 225000,
+		.p2_slow = 14, .p2_fast = 14 },
 	.find_pll = intel_g4x_find_best_PLL,
 };
 
 static const intel_limit_t intel_limits_ironlake_dual_lvds_100m = {
-	.dot = { .min = IRONLAKE_DOT_MIN,          .max = IRONLAKE_DOT_MAX },
-	.vco = { .min = IRONLAKE_VCO_MIN,          .max = IRONLAKE_VCO_MAX },
-	.n   = { .min = IRONLAKE_LVDS_D_SSC_N_MIN, .max = IRONLAKE_LVDS_D_SSC_N_MAX },
-	.m   = { .min = IRONLAKE_LVDS_D_SSC_M_MIN, .max = IRONLAKE_LVDS_D_SSC_M_MAX },
-	.m1  = { .min = IRONLAKE_M1_MIN,           .max = IRONLAKE_M1_MAX },
-	.m2  = { .min = IRONLAKE_M2_MIN,           .max = IRONLAKE_M2_MAX },
-	.p   = { .min = IRONLAKE_LVDS_D_SSC_P_MIN, .max = IRONLAKE_LVDS_D_SSC_P_MAX },
-	.p1  = { .min = IRONLAKE_LVDS_D_SSC_P1_MIN,.max = IRONLAKE_LVDS_D_SSC_P1_MAX },
-	.p2  = { .dot_limit = IRONLAKE_P2_DOT_LIMIT,
-		 .p2_slow = IRONLAKE_LVDS_D_SSC_P2_SLOW,
-		 .p2_fast = IRONLAKE_LVDS_D_SSC_P2_FAST },
+	.dot = { .min = 25000, .max = 350000 },
+	.vco = { .min = 1760000, .max = 3510000 },
+	.n = { .min = 1, .max = 3 },
+	.m = { .min = 79, .max = 126 },
+	.m1 = { .min = 12, .max = 22 },
+	.m2 = { .min = 5, .max = 9 },
+	.p = { .min = 14, .max = 42 },
+	.p1 = { .min = 2,.max = 6 },
+	.p2 = { .dot_limit = 225000,
+		.p2_slow = 7, .p2_fast = 7 },
 	.find_pll = intel_g4x_find_best_PLL,
 };
 
 static const intel_limit_t intel_limits_ironlake_display_port = {
-        .dot = { .min = IRONLAKE_DOT_MIN,
-                 .max = IRONLAKE_DOT_MAX },
-        .vco = { .min = IRONLAKE_VCO_MIN,
-                 .max = IRONLAKE_VCO_MAX},
-        .n   = { .min = IRONLAKE_DP_N_MIN,
-                 .max = IRONLAKE_DP_N_MAX },
-        .m   = { .min = IRONLAKE_DP_M_MIN,
-                 .max = IRONLAKE_DP_M_MAX },
-        .m1  = { .min = IRONLAKE_M1_MIN,
-                 .max = IRONLAKE_M1_MAX },
-        .m2  = { .min = IRONLAKE_M2_MIN,
-                 .max = IRONLAKE_M2_MAX },
-        .p   = { .min = IRONLAKE_DP_P_MIN,
-                 .max = IRONLAKE_DP_P_MAX },
-        .p1  = { .min = IRONLAKE_DP_P1_MIN,
-                 .max = IRONLAKE_DP_P1_MAX},
-        .p2  = { .dot_limit = IRONLAKE_DP_P2_LIMIT,
-                 .p2_slow = IRONLAKE_DP_P2_SLOW,
-                 .p2_fast = IRONLAKE_DP_P2_FAST },
+        .dot = { .min = 25000, .max = 350000 },
+        .vco = { .min = 1760000, .max = 3510000},
+        .n = { .min = 1, .max = 2 },
+        .m = { .min = 81, .max = 90 },
+        .m1 = { .min = 12, .max = 22 },
+        .m2 = { .min = 5, .max = 9 },
+        .p = { .min = 10, .max = 20 },
+        .p1 = { .min = 1, .max = 2},
+        .p2 = { .dot_limit = 0,
+		.p2_slow = 10, .p2_fast = 10 },
         .find_pll = intel_find_pll_ironlake_dp,
 };
 
@@ -1828,7 +1540,7 @@
 	u32 blt_ecoskpd;
 
 	/* Make sure blitter notifies FBC of writes */
-	__gen6_gt_force_wake_get(dev_priv);
+	gen6_gt_force_wake_get(dev_priv);
 	blt_ecoskpd = I915_READ(GEN6_BLITTER_ECOSKPD);
 	blt_ecoskpd |= GEN6_BLITTER_FBC_NOTIFY <<
 		GEN6_BLITTER_LOCK_SHIFT;
@@ -1839,7 +1551,7 @@
 			 GEN6_BLITTER_LOCK_SHIFT);
 	I915_WRITE(GEN6_BLITTER_ECOSKPD, blt_ecoskpd);
 	POSTING_READ(GEN6_BLITTER_ECOSKPD);
-	__gen6_gt_force_wake_put(dev_priv);
+	gen6_gt_force_wake_put(dev_priv);
 }
 
 static void ironlake_enable_fbc(struct drm_crtc *crtc, unsigned long interval)
@@ -2019,6 +1731,11 @@
 	intel_fb = to_intel_framebuffer(fb);
 	obj = intel_fb->obj;
 
+	if (!i915_enable_fbc) {
+		DRM_DEBUG_KMS("fbc disabled per module param (default off)\n");
+		dev_priv->no_fbc_reason = FBC_MODULE_PARAM;
+		goto out_disable;
+	}
 	if (intel_fb->obj->base.size > dev_priv->cfb_size) {
 		DRM_DEBUG_KMS("framebuffer too large, disabling "
 			      "compression\n");
@@ -2339,8 +2056,13 @@
 	/* enable normal train */
 	reg = FDI_TX_CTL(pipe);
 	temp = I915_READ(reg);
-	temp &= ~FDI_LINK_TRAIN_NONE;
-	temp |= FDI_LINK_TRAIN_NONE | FDI_TX_ENHANCE_FRAME_ENABLE;
+	if (IS_IVYBRIDGE(dev)) {
+		temp &= ~FDI_LINK_TRAIN_NONE_IVB;
+		temp |= FDI_LINK_TRAIN_NONE_IVB | FDI_TX_ENHANCE_FRAME_ENABLE;
+	} else {
+		temp &= ~FDI_LINK_TRAIN_NONE;
+		temp |= FDI_LINK_TRAIN_NONE | FDI_TX_ENHANCE_FRAME_ENABLE;
+	}
 	I915_WRITE(reg, temp);
 
 	reg = FDI_RX_CTL(pipe);
@@ -2357,6 +2079,11 @@
 	/* wait one idle pattern time */
 	POSTING_READ(reg);
 	udelay(1000);
+
+	/* IVB wants error correction enabled */
+	if (IS_IVYBRIDGE(dev))
+		I915_WRITE(reg, I915_READ(reg) | FDI_FS_ERRC_ENABLE |
+			   FDI_FE_ERRC_ENABLE);
 }
 
 /* The FDI link training functions for ILK/Ibexpeak. */
@@ -2584,7 +2311,116 @@
 	DRM_DEBUG_KMS("FDI train done.\n");
 }
 
-static void ironlake_fdi_enable(struct drm_crtc *crtc)
+/* Manual link training for Ivy Bridge A0 parts */
+static void ivb_manual_fdi_link_train(struct drm_crtc *crtc)
+{
+	struct drm_device *dev = crtc->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+	int pipe = intel_crtc->pipe;
+	u32 reg, temp, i;
+
+	/* Train 1: umask FDI RX Interrupt symbol_lock and bit_lock bit
+	   for train result */
+	reg = FDI_RX_IMR(pipe);
+	temp = I915_READ(reg);
+	temp &= ~FDI_RX_SYMBOL_LOCK;
+	temp &= ~FDI_RX_BIT_LOCK;
+	I915_WRITE(reg, temp);
+
+	POSTING_READ(reg);
+	udelay(150);
+
+	/* enable CPU FDI TX and PCH FDI RX */
+	reg = FDI_TX_CTL(pipe);
+	temp = I915_READ(reg);
+	temp &= ~(7 << 19);
+	temp |= (intel_crtc->fdi_lanes - 1) << 19;
+	temp &= ~(FDI_LINK_TRAIN_AUTO | FDI_LINK_TRAIN_NONE_IVB);
+	temp |= FDI_LINK_TRAIN_PATTERN_1_IVB;
+	temp &= ~FDI_LINK_TRAIN_VOL_EMP_MASK;
+	temp |= FDI_LINK_TRAIN_400MV_0DB_SNB_B;
+	I915_WRITE(reg, temp | FDI_TX_ENABLE);
+
+	reg = FDI_RX_CTL(pipe);
+	temp = I915_READ(reg);
+	temp &= ~FDI_LINK_TRAIN_AUTO;
+	temp &= ~FDI_LINK_TRAIN_PATTERN_MASK_CPT;
+	temp |= FDI_LINK_TRAIN_PATTERN_1_CPT;
+	I915_WRITE(reg, temp | FDI_RX_ENABLE);
+
+	POSTING_READ(reg);
+	udelay(150);
+
+	for (i = 0; i < 4; i++ ) {
+		reg = FDI_TX_CTL(pipe);
+		temp = I915_READ(reg);
+		temp &= ~FDI_LINK_TRAIN_VOL_EMP_MASK;
+		temp |= snb_b_fdi_train_param[i];
+		I915_WRITE(reg, temp);
+
+		POSTING_READ(reg);
+		udelay(500);
+
+		reg = FDI_RX_IIR(pipe);
+		temp = I915_READ(reg);
+		DRM_DEBUG_KMS("FDI_RX_IIR 0x%x\n", temp);
+
+		if (temp & FDI_RX_BIT_LOCK ||
+		    (I915_READ(reg) & FDI_RX_BIT_LOCK)) {
+			I915_WRITE(reg, temp | FDI_RX_BIT_LOCK);
+			DRM_DEBUG_KMS("FDI train 1 done.\n");
+			break;
+		}
+	}
+	if (i == 4)
+		DRM_ERROR("FDI train 1 fail!\n");
+
+	/* Train 2 */
+	reg = FDI_TX_CTL(pipe);
+	temp = I915_READ(reg);
+	temp &= ~FDI_LINK_TRAIN_NONE_IVB;
+	temp |= FDI_LINK_TRAIN_PATTERN_2_IVB;
+	temp &= ~FDI_LINK_TRAIN_VOL_EMP_MASK;
+	temp |= FDI_LINK_TRAIN_400MV_0DB_SNB_B;
+	I915_WRITE(reg, temp);
+
+	reg = FDI_RX_CTL(pipe);
+	temp = I915_READ(reg);
+	temp &= ~FDI_LINK_TRAIN_PATTERN_MASK_CPT;
+	temp |= FDI_LINK_TRAIN_PATTERN_2_CPT;
+	I915_WRITE(reg, temp);
+
+	POSTING_READ(reg);
+	udelay(150);
+
+	for (i = 0; i < 4; i++ ) {
+		reg = FDI_TX_CTL(pipe);
+		temp = I915_READ(reg);
+		temp &= ~FDI_LINK_TRAIN_VOL_EMP_MASK;
+		temp |= snb_b_fdi_train_param[i];
+		I915_WRITE(reg, temp);
+
+		POSTING_READ(reg);
+		udelay(500);
+
+		reg = FDI_RX_IIR(pipe);
+		temp = I915_READ(reg);
+		DRM_DEBUG_KMS("FDI_RX_IIR 0x%x\n", temp);
+
+		if (temp & FDI_RX_SYMBOL_LOCK) {
+			I915_WRITE(reg, temp | FDI_RX_SYMBOL_LOCK);
+			DRM_DEBUG_KMS("FDI train 2 done.\n");
+			break;
+		}
+	}
+	if (i == 4)
+		DRM_ERROR("FDI train 2 fail!\n");
+
+	DRM_DEBUG_KMS("FDI train done.\n");
+}
+
+static void ironlake_fdi_pll_enable(struct drm_crtc *crtc)
 {
 	struct drm_device *dev = crtc->dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
@@ -2757,10 +2593,7 @@
 	u32 reg, temp;
 
 	/* For PCH output, training FDI link */
-	if (IS_GEN6(dev))
-		gen6_fdi_link_train(crtc);
-	else
-		ironlake_fdi_link_train(crtc);
+	dev_priv->display.fdi_link_train(crtc);
 
 	intel_enable_pch_pll(dev_priv, pipe);
 
@@ -2850,7 +2683,7 @@
 	is_pch_port = intel_crtc_driving_pch(crtc);
 
 	if (is_pch_port)
-		ironlake_fdi_enable(crtc);
+		ironlake_fdi_pll_enable(crtc);
 	else
 		ironlake_fdi_disable(crtc);
 
@@ -2873,7 +2706,11 @@
 		ironlake_pch_enable(crtc);
 
 	intel_crtc_load_lut(crtc);
+
+	mutex_lock(&dev->struct_mutex);
 	intel_update_fbc(dev);
+	mutex_unlock(&dev->struct_mutex);
+
 	intel_crtc_update_cursor(crtc, true);
 }
 
@@ -2969,8 +2806,11 @@
 
 	intel_crtc->active = false;
 	intel_update_watermarks(dev);
+
+	mutex_lock(&dev->struct_mutex);
 	intel_update_fbc(dev);
 	intel_clear_scanline_wait(dev);
+	mutex_unlock(&dev->struct_mutex);
 }
 
 static void ironlake_crtc_dpms(struct drm_crtc *crtc, int mode)
@@ -3497,11 +3337,11 @@
 		1000;
 	entries_required = DIV_ROUND_UP(entries_required, wm->cacheline_size);
 
-	DRM_DEBUG_KMS("FIFO entries required for mode: %d\n", entries_required);
+	DRM_DEBUG_KMS("FIFO entries required for mode: %ld\n", entries_required);
 
 	wm_size = fifo_size - (entries_required + wm->guard_size);
 
-	DRM_DEBUG_KMS("FIFO watermark level: %d\n", wm_size);
+	DRM_DEBUG_KMS("FIFO watermark level: %ld\n", wm_size);
 
 	/* Don't promote wm_size to unsigned... */
 	if (wm_size > (long)wm->max_wm)
@@ -3823,13 +3663,13 @@
 		      display_wm, cursor_wm);
 
 	if (display_wm > display->max_wm) {
-		DRM_DEBUG_KMS("display watermark is too large(%d), disabling\n",
+		DRM_DEBUG_KMS("display watermark is too large(%d/%ld), disabling\n",
 			      display_wm, display->max_wm);
 		return false;
 	}
 
 	if (cursor_wm > cursor->max_wm) {
-		DRM_DEBUG_KMS("cursor watermark is too large(%d), disabling\n",
+		DRM_DEBUG_KMS("cursor watermark is too large(%d/%ld), disabling\n",
 			      cursor_wm, cursor->max_wm);
 		return false;
 	}
@@ -4143,54 +3983,6 @@
 #define ILK_LP0_PLANE_LATENCY		700
 #define ILK_LP0_CURSOR_LATENCY		1300
 
-static bool ironlake_compute_wm0(struct drm_device *dev,
-				 int pipe,
-				 const struct intel_watermark_params *display,
-				 int display_latency_ns,
-				 const struct intel_watermark_params *cursor,
-				 int cursor_latency_ns,
-				 int *plane_wm,
-				 int *cursor_wm)
-{
-	struct drm_crtc *crtc;
-	int htotal, hdisplay, clock, pixel_size;
-	int line_time_us, line_count;
-	int entries, tlb_miss;
-
-	crtc = intel_get_crtc_for_pipe(dev, pipe);
-	if (crtc->fb == NULL || !crtc->enabled)
-		return false;
-
-	htotal = crtc->mode.htotal;
-	hdisplay = crtc->mode.hdisplay;
-	clock = crtc->mode.clock;
-	pixel_size = crtc->fb->bits_per_pixel / 8;
-
-	/* Use the small buffer method to calculate plane watermark */
-	entries = ((clock * pixel_size / 1000) * display_latency_ns) / 1000;
-	tlb_miss = display->fifo_size*display->cacheline_size - hdisplay * 8;
-	if (tlb_miss > 0)
-		entries += tlb_miss;
-	entries = DIV_ROUND_UP(entries, display->cacheline_size);
-	*plane_wm = entries + display->guard_size;
-	if (*plane_wm > (int)display->max_wm)
-		*plane_wm = display->max_wm;
-
-	/* Use the large buffer method to calculate cursor watermark */
-	line_time_us = ((htotal * 1000) / clock);
-	line_count = (cursor_latency_ns / line_time_us + 1000) / 1000;
-	entries = line_count * 64 * pixel_size;
-	tlb_miss = cursor->fifo_size*cursor->cacheline_size - hdisplay * 8;
-	if (tlb_miss > 0)
-		entries += tlb_miss;
-	entries = DIV_ROUND_UP(entries, cursor->cacheline_size);
-	*cursor_wm = entries + cursor->guard_size;
-	if (*cursor_wm > (int)cursor->max_wm)
-		*cursor_wm = (int)cursor->max_wm;
-
-	return true;
-}
-
 /*
  * Check the wm result.
  *
@@ -4299,12 +4091,12 @@
 	unsigned int enabled;
 
 	enabled = 0;
-	if (ironlake_compute_wm0(dev, 0,
-				 &ironlake_display_wm_info,
-				 ILK_LP0_PLANE_LATENCY,
-				 &ironlake_cursor_wm_info,
-				 ILK_LP0_CURSOR_LATENCY,
-				 &plane_wm, &cursor_wm)) {
+	if (g4x_compute_wm0(dev, 0,
+			    &ironlake_display_wm_info,
+			    ILK_LP0_PLANE_LATENCY,
+			    &ironlake_cursor_wm_info,
+			    ILK_LP0_CURSOR_LATENCY,
+			    &plane_wm, &cursor_wm)) {
 		I915_WRITE(WM0_PIPEA_ILK,
 			   (plane_wm << WM0_PIPE_PLANE_SHIFT) | cursor_wm);
 		DRM_DEBUG_KMS("FIFO watermarks For pipe A -"
@@ -4313,12 +4105,12 @@
 		enabled |= 1;
 	}
 
-	if (ironlake_compute_wm0(dev, 1,
-				 &ironlake_display_wm_info,
-				 ILK_LP0_PLANE_LATENCY,
-				 &ironlake_cursor_wm_info,
-				 ILK_LP0_CURSOR_LATENCY,
-				 &plane_wm, &cursor_wm)) {
+	if (g4x_compute_wm0(dev, 1,
+			    &ironlake_display_wm_info,
+			    ILK_LP0_PLANE_LATENCY,
+			    &ironlake_cursor_wm_info,
+			    ILK_LP0_CURSOR_LATENCY,
+			    &plane_wm, &cursor_wm)) {
 		I915_WRITE(WM0_PIPEB_ILK,
 			   (plane_wm << WM0_PIPE_PLANE_SHIFT) | cursor_wm);
 		DRM_DEBUG_KMS("FIFO watermarks For pipe B -"
@@ -4383,10 +4175,10 @@
 	unsigned int enabled;
 
 	enabled = 0;
-	if (ironlake_compute_wm0(dev, 0,
-				 &sandybridge_display_wm_info, latency,
-				 &sandybridge_cursor_wm_info, latency,
-				 &plane_wm, &cursor_wm)) {
+	if (g4x_compute_wm0(dev, 0,
+			    &sandybridge_display_wm_info, latency,
+			    &sandybridge_cursor_wm_info, latency,
+			    &plane_wm, &cursor_wm)) {
 		I915_WRITE(WM0_PIPEA_ILK,
 			   (plane_wm << WM0_PIPE_PLANE_SHIFT) | cursor_wm);
 		DRM_DEBUG_KMS("FIFO watermarks For pipe A -"
@@ -4395,10 +4187,10 @@
 		enabled |= 1;
 	}
 
-	if (ironlake_compute_wm0(dev, 1,
-				 &sandybridge_display_wm_info, latency,
-				 &sandybridge_cursor_wm_info, latency,
-				 &plane_wm, &cursor_wm)) {
+	if (g4x_compute_wm0(dev, 1,
+			    &sandybridge_display_wm_info, latency,
+			    &sandybridge_cursor_wm_info, latency,
+			    &plane_wm, &cursor_wm)) {
 		I915_WRITE(WM0_PIPEB_ILK,
 			   (plane_wm << WM0_PIPE_PLANE_SHIFT) | cursor_wm);
 		DRM_DEBUG_KMS("FIFO watermarks For pipe B -"
@@ -4516,34 +4308,28 @@
 	return dev_priv->lvds_use_ssc && i915_panel_use_ssc;
 }
 
-static int intel_crtc_mode_set(struct drm_crtc *crtc,
-			       struct drm_display_mode *mode,
-			       struct drm_display_mode *adjusted_mode,
-			       int x, int y,
-			       struct drm_framebuffer *old_fb)
+static int i9xx_crtc_mode_set(struct drm_crtc *crtc,
+			      struct drm_display_mode *mode,
+			      struct drm_display_mode *adjusted_mode,
+			      int x, int y,
+			      struct drm_framebuffer *old_fb)
 {
 	struct drm_device *dev = crtc->dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
 	int pipe = intel_crtc->pipe;
 	int plane = intel_crtc->plane;
-	u32 fp_reg, dpll_reg;
 	int refclk, num_connectors = 0;
 	intel_clock_t clock, reduced_clock;
 	u32 dpll, fp = 0, fp2 = 0, dspcntr, pipeconf;
 	bool ok, has_reduced_clock = false, is_sdvo = false, is_dvo = false;
 	bool is_crt = false, is_lvds = false, is_tv = false, is_dp = false;
-	struct intel_encoder *has_edp_encoder = NULL;
 	struct drm_mode_config *mode_config = &dev->mode_config;
 	struct intel_encoder *encoder;
 	const intel_limit_t *limit;
 	int ret;
-	struct fdi_m_n m_n = {0};
-	u32 reg, temp;
+	u32 temp;
 	u32 lvds_sync = 0;
-	int target_clock;
-
-	drm_vblank_pre_modeset(dev, pipe);
 
 	list_for_each_entry(encoder, &mode_config->encoder_list, base.head) {
 		if (encoder->base.crtc != crtc)
@@ -4571,9 +4357,6 @@
 		case INTEL_OUTPUT_DISPLAYPORT:
 			is_dp = true;
 			break;
-		case INTEL_OUTPUT_EDP:
-			has_edp_encoder = encoder;
-			break;
 		}
 
 		num_connectors++;
@@ -4585,9 +4368,6 @@
 			      refclk / 1000);
 	} else if (!IS_GEN2(dev)) {
 		refclk = 96000;
-		if (HAS_PCH_SPLIT(dev) &&
-		    (!has_edp_encoder || intel_encoder_is_pch_edp(&has_edp_encoder->base)))
-			refclk = 120000; /* 120Mhz refclk */
 	} else {
 		refclk = 48000;
 	}
@@ -4601,7 +4381,6 @@
 	ok = limit->find_pll(limit, crtc, adjusted_mode->clock, refclk, &clock);
 	if (!ok) {
 		DRM_ERROR("Couldn't find PLL settings for mode!\n");
-		drm_vblank_post_modeset(dev, pipe);
 		return -EINVAL;
 	}
 
@@ -4645,143 +4424,6 @@
 		}
 	}
 
-	/* FDI link */
-	if (HAS_PCH_SPLIT(dev)) {
-		int pixel_multiplier = intel_mode_get_pixel_multiplier(adjusted_mode);
-		int lane = 0, link_bw, bpp;
-		/* CPU eDP doesn't require FDI link, so just set DP M/N
-		   according to current link config */
-		if (has_edp_encoder && !intel_encoder_is_pch_edp(&has_edp_encoder->base)) {
-			target_clock = mode->clock;
-			intel_edp_link_config(has_edp_encoder,
-					      &lane, &link_bw);
-		} else {
-			/* [e]DP over FDI requires target mode clock
-			   instead of link clock */
-			if (is_dp || intel_encoder_is_pch_edp(&has_edp_encoder->base))
-				target_clock = mode->clock;
-			else
-				target_clock = adjusted_mode->clock;
-
-			/* FDI is a binary signal running at ~2.7GHz, encoding
-			 * each output octet as 10 bits. The actual frequency
-			 * is stored as a divider into a 100MHz clock, and the
-			 * mode pixel clock is stored in units of 1KHz.
-			 * Hence the bw of each lane in terms of the mode signal
-			 * is:
-			 */
-			link_bw = intel_fdi_link_freq(dev) * MHz(100)/KHz(1)/10;
-		}
-
-		/* determine panel color depth */
-		temp = I915_READ(PIPECONF(pipe));
-		temp &= ~PIPE_BPC_MASK;
-		if (is_lvds) {
-			/* the BPC will be 6 if it is 18-bit LVDS panel */
-			if ((I915_READ(PCH_LVDS) & LVDS_A3_POWER_MASK) == LVDS_A3_POWER_UP)
-				temp |= PIPE_8BPC;
-			else
-				temp |= PIPE_6BPC;
-		} else if (has_edp_encoder) {
-			switch (dev_priv->edp.bpp/3) {
-			case 8:
-				temp |= PIPE_8BPC;
-				break;
-			case 10:
-				temp |= PIPE_10BPC;
-				break;
-			case 6:
-				temp |= PIPE_6BPC;
-				break;
-			case 12:
-				temp |= PIPE_12BPC;
-				break;
-			}
-		} else
-			temp |= PIPE_8BPC;
-		I915_WRITE(PIPECONF(pipe), temp);
-
-		switch (temp & PIPE_BPC_MASK) {
-		case PIPE_8BPC:
-			bpp = 24;
-			break;
-		case PIPE_10BPC:
-			bpp = 30;
-			break;
-		case PIPE_6BPC:
-			bpp = 18;
-			break;
-		case PIPE_12BPC:
-			bpp = 36;
-			break;
-		default:
-			DRM_ERROR("unknown pipe bpc value\n");
-			bpp = 24;
-		}
-
-		if (!lane) {
-			/* 
-			 * Account for spread spectrum to avoid
-			 * oversubscribing the link. Max center spread
-			 * is 2.5%; use 5% for safety's sake.
-			 */
-			u32 bps = target_clock * bpp * 21 / 20;
-			lane = bps / (link_bw * 8) + 1;
-		}
-
-		intel_crtc->fdi_lanes = lane;
-
-		if (pixel_multiplier > 1)
-			link_bw *= pixel_multiplier;
-		ironlake_compute_m_n(bpp, lane, target_clock, link_bw, &m_n);
-	}
-
-	/* Ironlake: try to setup display ref clock before DPLL
-	 * enabling. This is only under driver's control after
-	 * PCH B stepping, previous chipset stepping should be
-	 * ignoring this setting.
-	 */
-	if (HAS_PCH_SPLIT(dev)) {
-		temp = I915_READ(PCH_DREF_CONTROL);
-		/* Always enable nonspread source */
-		temp &= ~DREF_NONSPREAD_SOURCE_MASK;
-		temp |= DREF_NONSPREAD_SOURCE_ENABLE;
-		temp &= ~DREF_SSC_SOURCE_MASK;
-		temp |= DREF_SSC_SOURCE_ENABLE;
-		I915_WRITE(PCH_DREF_CONTROL, temp);
-
-		POSTING_READ(PCH_DREF_CONTROL);
-		udelay(200);
-
-		if (has_edp_encoder) {
-			if (intel_panel_use_ssc(dev_priv)) {
-				temp |= DREF_SSC1_ENABLE;
-				I915_WRITE(PCH_DREF_CONTROL, temp);
-
-				POSTING_READ(PCH_DREF_CONTROL);
-				udelay(200);
-			}
-			temp &= ~DREF_CPU_SOURCE_OUTPUT_MASK;
-
-			/* Enable CPU source on CPU attached eDP */
-			if (!intel_encoder_is_pch_edp(&has_edp_encoder->base)) {
-				if (intel_panel_use_ssc(dev_priv))
-					temp |= DREF_CPU_SOURCE_OUTPUT_DOWNSPREAD;
-				else
-					temp |= DREF_CPU_SOURCE_OUTPUT_NONSPREAD;
-			} else {
-				/* Enable SSC on PCH eDP if needed */
-				if (intel_panel_use_ssc(dev_priv)) {
-					DRM_ERROR("enabling SSC on PCH\n");
-					temp |= DREF_SUPERSPREAD_SOURCE_ENABLE;
-				}
-			}
-			I915_WRITE(PCH_DREF_CONTROL, temp);
-			POSTING_READ(PCH_DREF_CONTROL);
-			udelay(200);
-		}
-	}
-
 	if (IS_PINEVIEW(dev)) {
 		fp = (1 << clock.n) << 16 | clock.m1 << 8 | clock.m2;
 		if (has_reduced_clock)
@@ -4794,25 +4436,7 @@
 				reduced_clock.m2;
 	}
 
-	/* Enable autotuning of the PLL clock (if permissible) */
-	if (HAS_PCH_SPLIT(dev)) {
-		int factor = 21;
-
-		if (is_lvds) {
-			if ((intel_panel_use_ssc(dev_priv) &&
-			     dev_priv->lvds_ssc_freq == 100) ||
-			    (I915_READ(PCH_LVDS) & LVDS_CLKB_POWER_MASK) == LVDS_CLKB_POWER_UP)
-				factor = 25;
-		} else if (is_sdvo && is_tv)
-			factor = 20;
-
-		if (clock.m1 < factor * clock.n)
-			fp |= FP_CB_TUNE;
-	}
-
-	dpll = 0;
-	if (!HAS_PCH_SPLIT(dev))
-		dpll = DPLL_VGA_MODE_DIS;
+	dpll = DPLL_VGA_MODE_DIS;
 
 	if (!IS_GEN2(dev)) {
 		if (is_lvds)
@@ -4824,12 +4448,10 @@
 			if (pixel_multiplier > 1) {
 				if (IS_I945G(dev) || IS_I945GM(dev) || IS_G33(dev))
 					dpll |= (pixel_multiplier - 1) << SDVO_MULTIPLIER_SHIFT_HIRES;
-				else if (HAS_PCH_SPLIT(dev))
-					dpll |= (pixel_multiplier - 1) << PLL_REF_SDVO_HDMI_MULTIPLIER_SHIFT;
 			}
 			dpll |= DPLL_DVO_HIGH_SPEED;
 		}
-		if (is_dp || intel_encoder_is_pch_edp(&has_edp_encoder->base))
+		if (is_dp)
 			dpll |= DPLL_DVO_HIGH_SPEED;
 
 		/* compute bitmask from p1 value */
@@ -4837,9 +4459,6 @@
 			dpll |= (1 << (clock.p1 - 1)) << DPLL_FPA01_P1_POST_DIV_SHIFT_PINEVIEW;
 		else {
 			dpll |= (1 << (clock.p1 - 1)) << DPLL_FPA01_P1_POST_DIV_SHIFT;
-			/* also FPA1 */
-			if (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;
 		}
@@ -4857,7 +4476,7 @@
 			dpll |= DPLLB_LVDS_P2_CLOCK_DIV_14;
 			break;
 		}
-		if (INTEL_INFO(dev)->gen >= 4 && !HAS_PCH_SPLIT(dev))
+		if (INTEL_INFO(dev)->gen >= 4)
 			dpll |= (6 << PLL_LOAD_PULSE_PHASE_SHIFT);
 	} else {
 		if (is_lvds) {
@@ -4891,12 +4510,10 @@
 
 	/* Ironlake's plane is forced to pipe, bit 24 is to
 	   enable color space conversion */
-	if (!HAS_PCH_SPLIT(dev)) {
-		if (pipe == 0)
-			dspcntr &= ~DISPPLANE_SEL_PIPE_MASK;
-		else
-			dspcntr |= DISPPLANE_SEL_PIPE_B;
-	}
+	if (pipe == 0)
+		dspcntr &= ~DISPPLANE_SEL_PIPE_MASK;
+	else
+		dspcntr |= DISPPLANE_SEL_PIPE_B;
 
 	if (pipe == 0 && INTEL_INFO(dev)->gen < 4) {
 		/* Enable pixel doubling when the dot clock is > 90% of the (display)
@@ -4912,27 +4529,507 @@
 			pipeconf &= ~PIPECONF_DOUBLE_WIDE;
 	}
 
-	if (!HAS_PCH_SPLIT(dev))
-		dpll |= DPLL_VCO_ENABLE;
+	dpll |= DPLL_VCO_ENABLE;
 
 	DRM_DEBUG_KMS("Mode for pipe %c:\n", pipe == 0 ? 'A' : 'B');
 	drm_mode_debug_printmodeline(mode);
 
-	/* assign to Ironlake registers */
-	if (HAS_PCH_SPLIT(dev)) {
-		fp_reg = PCH_FP0(pipe);
-		dpll_reg = PCH_DPLL(pipe);
+	I915_WRITE(FP0(pipe), fp);
+	I915_WRITE(DPLL(pipe), dpll & ~DPLL_VCO_ENABLE);
+
+	POSTING_READ(DPLL(pipe));
+	udelay(150);
+
+	/* The LVDS pin pair needs to be on before the DPLLs are enabled.
+	 * This is an exception to the general rule that mode_set doesn't turn
+	 * things on.
+	 */
+	if (is_lvds) {
+		temp = I915_READ(LVDS);
+		temp |= LVDS_PORT_EN | LVDS_A0A2_CLKA_POWER_UP;
+		if (pipe == 1) {
+			temp |= LVDS_PIPEB_SELECT;
+		} else {
+			temp &= ~LVDS_PIPEB_SELECT;
+		}
+		/* set the corresponsding LVDS_BORDER bit */
+		temp |= dev_priv->lvds_border_bits;
+		/* Set the B0-B3 data pairs corresponding to whether we're going to
+		 * set the DPLLs for dual-channel mode or not.
+		 */
+		if (clock.p2 == 7)
+			temp |= LVDS_B0B3_POWER_UP | LVDS_CLKB_POWER_UP;
+		else
+			temp &= ~(LVDS_B0B3_POWER_UP | LVDS_CLKB_POWER_UP);
+
+		/* It would be nice to set 24 vs 18-bit mode (LVDS_A3_POWER_UP)
+		 * appropriately here, but we need to look more thoroughly into how
+		 * panels behave in the two modes.
+		 */
+		/* set the dithering flag on LVDS as needed */
+		if (INTEL_INFO(dev)->gen >= 4) {
+			if (dev_priv->lvds_dither)
+				temp |= LVDS_ENABLE_DITHER;
+			else
+				temp &= ~LVDS_ENABLE_DITHER;
+		}
+		if (adjusted_mode->flags & DRM_MODE_FLAG_NHSYNC)
+			lvds_sync |= LVDS_HSYNC_POLARITY;
+		if (adjusted_mode->flags & DRM_MODE_FLAG_NVSYNC)
+			lvds_sync |= LVDS_VSYNC_POLARITY;
+		if ((temp & (LVDS_HSYNC_POLARITY | LVDS_VSYNC_POLARITY))
+		    != lvds_sync) {
+			char flags[2] = "-+";
+			DRM_INFO("Changing LVDS panel from "
+				 "(%chsync, %cvsync) to (%chsync, %cvsync)\n",
+				 flags[!(temp & LVDS_HSYNC_POLARITY)],
+				 flags[!(temp & LVDS_VSYNC_POLARITY)],
+				 flags[!(lvds_sync & LVDS_HSYNC_POLARITY)],
+				 flags[!(lvds_sync & LVDS_VSYNC_POLARITY)]);
+			temp &= ~(LVDS_HSYNC_POLARITY | LVDS_VSYNC_POLARITY);
+			temp |= lvds_sync;
+		}
+		I915_WRITE(LVDS, temp);
+	}
+
+	if (is_dp) {
+		intel_dp_set_m_n(crtc, mode, adjusted_mode);
+	}
+
+	I915_WRITE(DPLL(pipe), dpll);
+
+	/* Wait for the clocks to stabilize. */
+	POSTING_READ(DPLL(pipe));
+	udelay(150);
+
+	if (INTEL_INFO(dev)->gen >= 4) {
+		temp = 0;
+		if (is_sdvo) {
+			temp = intel_mode_get_pixel_multiplier(adjusted_mode);
+			if (temp > 1)
+				temp = (temp - 1) << DPLL_MD_UDI_MULTIPLIER_SHIFT;
+			else
+				temp = 0;
+		}
+		I915_WRITE(DPLL_MD(pipe), temp);
 	} else {
-		fp_reg = FP0(pipe);
-		dpll_reg = DPLL(pipe);
+		/* The pixel multiplier can only be updated once the
+		 * DPLL is enabled and the clocks are stable.
+		 *
+		 * So write it again.
+		 */
+		I915_WRITE(DPLL(pipe), dpll);
+	}
+
+	intel_crtc->lowfreq_avail = false;
+	if (is_lvds && has_reduced_clock && i915_powersave) {
+		I915_WRITE(FP1(pipe), fp2);
+		intel_crtc->lowfreq_avail = true;
+		if (HAS_PIPE_CXSR(dev)) {
+			DRM_DEBUG_KMS("enabling CxSR downclocking\n");
+			pipeconf |= PIPECONF_CXSR_DOWNCLOCK;
+		}
+	} else {
+		I915_WRITE(FP1(pipe), fp);
+		if (HAS_PIPE_CXSR(dev)) {
+			DRM_DEBUG_KMS("disabling CxSR downclocking\n");
+			pipeconf &= ~PIPECONF_CXSR_DOWNCLOCK;
+		}
+	}
+
+	if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) {
+		pipeconf |= PIPECONF_INTERLACE_W_FIELD_INDICATION;
+		/* the chip adds 2 halflines automatically */
+		adjusted_mode->crtc_vdisplay -= 1;
+		adjusted_mode->crtc_vtotal -= 1;
+		adjusted_mode->crtc_vblank_start -= 1;
+		adjusted_mode->crtc_vblank_end -= 1;
+		adjusted_mode->crtc_vsync_end -= 1;
+		adjusted_mode->crtc_vsync_start -= 1;
+	} else
+		pipeconf &= ~PIPECONF_INTERLACE_W_FIELD_INDICATION; /* progressive */
+
+	I915_WRITE(HTOTAL(pipe),
+		   (adjusted_mode->crtc_hdisplay - 1) |
+		   ((adjusted_mode->crtc_htotal - 1) << 16));
+	I915_WRITE(HBLANK(pipe),
+		   (adjusted_mode->crtc_hblank_start - 1) |
+		   ((adjusted_mode->crtc_hblank_end - 1) << 16));
+	I915_WRITE(HSYNC(pipe),
+		   (adjusted_mode->crtc_hsync_start - 1) |
+		   ((adjusted_mode->crtc_hsync_end - 1) << 16));
+
+	I915_WRITE(VTOTAL(pipe),
+		   (adjusted_mode->crtc_vdisplay - 1) |
+		   ((adjusted_mode->crtc_vtotal - 1) << 16));
+	I915_WRITE(VBLANK(pipe),
+		   (adjusted_mode->crtc_vblank_start - 1) |
+		   ((adjusted_mode->crtc_vblank_end - 1) << 16));
+	I915_WRITE(VSYNC(pipe),
+		   (adjusted_mode->crtc_vsync_start - 1) |
+		   ((adjusted_mode->crtc_vsync_end - 1) << 16));
+
+	/* pipesrc and dspsize control the size that is scaled from,
+	 * which should always be the user's requested size.
+	 */
+	I915_WRITE(DSPSIZE(plane),
+		   ((mode->vdisplay - 1) << 16) |
+		   (mode->hdisplay - 1));
+	I915_WRITE(DSPPOS(plane), 0);
+	I915_WRITE(PIPESRC(pipe),
+		   ((mode->hdisplay - 1) << 16) | (mode->vdisplay - 1));
+
+	I915_WRITE(PIPECONF(pipe), pipeconf);
+	POSTING_READ(PIPECONF(pipe));
+	intel_enable_pipe(dev_priv, pipe, false);
+
+	intel_wait_for_vblank(dev, pipe);
+
+	I915_WRITE(DSPCNTR(plane), dspcntr);
+	POSTING_READ(DSPCNTR(plane));
+	intel_enable_plane(dev_priv, plane, pipe);
+
+	ret = intel_pipe_set_base(crtc, x, y, old_fb);
+
+	intel_update_watermarks(dev);
+
+	return ret;
+}
+
+static int ironlake_crtc_mode_set(struct drm_crtc *crtc,
+				  struct drm_display_mode *mode,
+				  struct drm_display_mode *adjusted_mode,
+				  int x, int y,
+				  struct drm_framebuffer *old_fb)
+{
+	struct drm_device *dev = crtc->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+	int pipe = intel_crtc->pipe;
+	int plane = intel_crtc->plane;
+	int refclk, num_connectors = 0;
+	intel_clock_t clock, reduced_clock;
+	u32 dpll, fp = 0, fp2 = 0, dspcntr, pipeconf;
+	bool ok, has_reduced_clock = false, is_sdvo = false;
+	bool is_crt = false, is_lvds = false, is_tv = false, is_dp = false;
+	struct intel_encoder *has_edp_encoder = NULL;
+	struct drm_mode_config *mode_config = &dev->mode_config;
+	struct intel_encoder *encoder;
+	const intel_limit_t *limit;
+	int ret;
+	struct fdi_m_n m_n = {0};
+	u32 temp;
+	u32 lvds_sync = 0;
+	int target_clock, pixel_multiplier, lane, link_bw, bpp, factor;
+
+	list_for_each_entry(encoder, &mode_config->encoder_list, base.head) {
+		if (encoder->base.crtc != crtc)
+			continue;
+
+		switch (encoder->type) {
+		case INTEL_OUTPUT_LVDS:
+			is_lvds = true;
+			break;
+		case INTEL_OUTPUT_SDVO:
+		case INTEL_OUTPUT_HDMI:
+			is_sdvo = true;
+			if (encoder->needs_tv_clock)
+				is_tv = true;
+			break;
+		case INTEL_OUTPUT_TVOUT:
+			is_tv = true;
+			break;
+		case INTEL_OUTPUT_ANALOG:
+			is_crt = true;
+			break;
+		case INTEL_OUTPUT_DISPLAYPORT:
+			is_dp = true;
+			break;
+		case INTEL_OUTPUT_EDP:
+			has_edp_encoder = encoder;
+			break;
+		}
+
+		num_connectors++;
+	}
+
+	if (is_lvds && intel_panel_use_ssc(dev_priv) && num_connectors < 2) {
+		refclk = dev_priv->lvds_ssc_freq * 1000;
+		DRM_DEBUG_KMS("using SSC reference clock of %d MHz\n",
+			      refclk / 1000);
+	} else {
+		refclk = 96000;
+		if (!has_edp_encoder ||
+		    intel_encoder_is_pch_edp(&has_edp_encoder->base))
+			refclk = 120000; /* 120Mhz refclk */
+	}
+
+	/*
+	 * Returns a set of divisors for the desired target clock with the given
+	 * refclk, or FALSE.  The returned values represent the clock equation:
+	 * reflck * (5 * (m1 + 2) + (m2 + 2)) / (n + 2) / p1 / p2.
+	 */
+	limit = intel_limit(crtc, refclk);
+	ok = limit->find_pll(limit, crtc, adjusted_mode->clock, refclk, &clock);
+	if (!ok) {
+		DRM_ERROR("Couldn't find PLL settings for mode!\n");
+		return -EINVAL;
+	}
+
+	/* Ensure that the cursor is valid for the new mode before changing... */
+	intel_crtc_update_cursor(crtc, true);
+
+	if (is_lvds && dev_priv->lvds_downclock_avail) {
+		has_reduced_clock = limit->find_pll(limit, crtc,
+						    dev_priv->lvds_downclock,
+						    refclk,
+						    &reduced_clock);
+		if (has_reduced_clock && (clock.p != reduced_clock.p)) {
+			/*
+			 * If the different P is found, it means that we can't
+			 * switch the display clock by using the FP0/FP1.
+			 * In such case we will disable the LVDS downclock
+			 * feature.
+			 */
+			DRM_DEBUG_KMS("Different P is found for "
+				      "LVDS clock/downclock\n");
+			has_reduced_clock = 0;
+		}
+	}
+	/* SDVO TV has fixed PLL values depend on its clock range,
+	   this mirrors vbios setting. */
+	if (is_sdvo && is_tv) {
+		if (adjusted_mode->clock >= 100000
+		    && adjusted_mode->clock < 140500) {
+			clock.p1 = 2;
+			clock.p2 = 10;
+			clock.n = 3;
+			clock.m1 = 16;
+			clock.m2 = 8;
+		} else if (adjusted_mode->clock >= 140500
+			   && adjusted_mode->clock <= 200000) {
+			clock.p1 = 1;
+			clock.p2 = 10;
+			clock.n = 6;
+			clock.m1 = 12;
+			clock.m2 = 8;
+		}
 	}
 
+	/* FDI link */
+	pixel_multiplier = intel_mode_get_pixel_multiplier(adjusted_mode);
+	lane = 0;
+	/* CPU eDP doesn't require FDI link, so just set DP M/N
+	   according to current link config */
+	if (has_edp_encoder &&
+	    !intel_encoder_is_pch_edp(&has_edp_encoder->base)) {
+		target_clock = mode->clock;
+		intel_edp_link_config(has_edp_encoder,
+				      &lane, &link_bw);
+	} else {
+		/* [e]DP over FDI requires target mode clock
+		   instead of link clock */
+		if (is_dp || intel_encoder_is_pch_edp(&has_edp_encoder->base))
+			target_clock = mode->clock;
+		else
+			target_clock = adjusted_mode->clock;
+
+		/* FDI is a binary signal running at ~2.7GHz, encoding
+		 * each output octet as 10 bits. The actual frequency
+		 * is stored as a divider into a 100MHz clock, and the
+		 * mode pixel clock is stored in units of 1KHz.
+		 * Hence the bw of each lane in terms of the mode signal
+		 * is:
+		 */
+		link_bw = intel_fdi_link_freq(dev) * MHz(100)/KHz(1)/10;
+	}
+
+	/* determine panel color depth */
+	temp = I915_READ(PIPECONF(pipe));
+	temp &= ~PIPE_BPC_MASK;
+	if (is_lvds) {
+		/* the BPC will be 6 if it is 18-bit LVDS panel */
+		if ((I915_READ(PCH_LVDS) & LVDS_A3_POWER_MASK) == LVDS_A3_POWER_UP)
+			temp |= PIPE_8BPC;
+		else
+			temp |= PIPE_6BPC;
+	} else if (has_edp_encoder) {
+		switch (dev_priv->edp.bpp/3) {
+		case 8:
+			temp |= PIPE_8BPC;
+			break;
+		case 10:
+			temp |= PIPE_10BPC;
+			break;
+		case 6:
+			temp |= PIPE_6BPC;
+			break;
+		case 12:
+			temp |= PIPE_12BPC;
+			break;
+		}
+	} else
+		temp |= PIPE_8BPC;
+	I915_WRITE(PIPECONF(pipe), temp);
+
+	switch (temp & PIPE_BPC_MASK) {
+	case PIPE_8BPC:
+		bpp = 24;
+		break;
+	case PIPE_10BPC:
+		bpp = 30;
+		break;
+	case PIPE_6BPC:
+		bpp = 18;
+		break;
+	case PIPE_12BPC:
+		bpp = 36;
+		break;
+	default:
+		DRM_ERROR("unknown pipe bpc value\n");
+		bpp = 24;
+	}
+
+	if (!lane) {
+		/*
+		 * Account for spread spectrum to avoid
+		 * oversubscribing the link. Max center spread
+		 * is 2.5%; use 5% for safety's sake.
+		 */
+		u32 bps = target_clock * bpp * 21 / 20;
+		lane = bps / (link_bw * 8) + 1;
+	}
+
+	intel_crtc->fdi_lanes = lane;
+
+	if (pixel_multiplier > 1)
+		link_bw *= pixel_multiplier;
+	ironlake_compute_m_n(bpp, lane, target_clock, link_bw, &m_n);
+
+	/* Ironlake: try to setup display ref clock before DPLL
+	 * enabling. This is only under driver's control after
+	 * PCH B stepping, previous chipset stepping should be
+	 * ignoring this setting.
+	 */
+	temp = I915_READ(PCH_DREF_CONTROL);
+	/* Always enable nonspread source */
+	temp &= ~DREF_NONSPREAD_SOURCE_MASK;
+	temp |= DREF_NONSPREAD_SOURCE_ENABLE;
+	temp &= ~DREF_SSC_SOURCE_MASK;
+	temp |= DREF_SSC_SOURCE_ENABLE;
+	I915_WRITE(PCH_DREF_CONTROL, temp);
+
+	POSTING_READ(PCH_DREF_CONTROL);
+	udelay(200);
+
+	if (has_edp_encoder) {
+		if (intel_panel_use_ssc(dev_priv)) {
+			temp |= DREF_SSC1_ENABLE;
+			I915_WRITE(PCH_DREF_CONTROL, temp);
+
+			POSTING_READ(PCH_DREF_CONTROL);
+			udelay(200);
+		}
+		temp &= ~DREF_CPU_SOURCE_OUTPUT_MASK;
+
+		/* Enable CPU source on CPU attached eDP */
+		if (!intel_encoder_is_pch_edp(&has_edp_encoder->base)) {
+			if (intel_panel_use_ssc(dev_priv))
+				temp |= DREF_CPU_SOURCE_OUTPUT_DOWNSPREAD;
+			else
+				temp |= DREF_CPU_SOURCE_OUTPUT_NONSPREAD;
+		} else {
+			/* Enable SSC on PCH eDP if needed */
+			if (intel_panel_use_ssc(dev_priv)) {
+				DRM_ERROR("enabling SSC on PCH\n");
+				temp |= DREF_SUPERSPREAD_SOURCE_ENABLE;
+			}
+		}
+		I915_WRITE(PCH_DREF_CONTROL, temp);
+		POSTING_READ(PCH_DREF_CONTROL);
+		udelay(200);
+	}
+
+	fp = clock.n << 16 | clock.m1 << 8 | clock.m2;
+	if (has_reduced_clock)
+		fp2 = reduced_clock.n << 16 | reduced_clock.m1 << 8 |
+			reduced_clock.m2;
+
+	/* Enable autotuning of the PLL clock (if permissible) */
+	factor = 21;
+	if (is_lvds) {
+		if ((intel_panel_use_ssc(dev_priv) &&
+		     dev_priv->lvds_ssc_freq == 100) ||
+		    (I915_READ(PCH_LVDS) & LVDS_CLKB_POWER_MASK) == LVDS_CLKB_POWER_UP)
+			factor = 25;
+	} else if (is_sdvo && is_tv)
+		factor = 20;
+
+	if (clock.m1 < factor * clock.n)
+		fp |= FP_CB_TUNE;
+
+	dpll = 0;
+
+	if (is_lvds)
+		dpll |= DPLLB_MODE_LVDS;
+	else
+		dpll |= DPLLB_MODE_DAC_SERIAL;
+	if (is_sdvo) {
+		int pixel_multiplier = intel_mode_get_pixel_multiplier(adjusted_mode);
+		if (pixel_multiplier > 1) {
+			dpll |= (pixel_multiplier - 1) << PLL_REF_SDVO_HDMI_MULTIPLIER_SHIFT;
+		}
+		dpll |= DPLL_DVO_HIGH_SPEED;
+	}
+	if (is_dp || intel_encoder_is_pch_edp(&has_edp_encoder->base))
+		dpll |= DPLL_DVO_HIGH_SPEED;
+
+	/* compute bitmask from p1 value */
+	dpll |= (1 << (clock.p1 - 1)) << DPLL_FPA01_P1_POST_DIV_SHIFT;
+	/* also FPA1 */
+	dpll |= (1 << (clock.p1 - 1)) << DPLL_FPA1_P1_POST_DIV_SHIFT;
+
+	switch (clock.p2) {
+	case 5:
+		dpll |= DPLL_DAC_SERIAL_P2_CLOCK_DIV_5;
+		break;
+	case 7:
+		dpll |= DPLLB_LVDS_P2_CLOCK_DIV_7;
+		break;
+	case 10:
+		dpll |= DPLL_DAC_SERIAL_P2_CLOCK_DIV_10;
+		break;
+	case 14:
+		dpll |= DPLLB_LVDS_P2_CLOCK_DIV_14;
+		break;
+	}
+
+	if (is_sdvo && is_tv)
+		dpll |= PLL_REF_INPUT_TVCLKINBC;
+	else if (is_tv)
+		/* XXX: just matching BIOS for now */
+		/*	dpll |= PLL_REF_INPUT_TVCLKINBC; */
+		dpll |= 3;
+	else if (is_lvds && intel_panel_use_ssc(dev_priv) && num_connectors < 2)
+		dpll |= PLLB_REF_INPUT_SPREADSPECTRUMIN;
+	else
+		dpll |= PLL_REF_INPUT_DREFCLK;
+
+	/* setup pipeconf */
+	pipeconf = I915_READ(PIPECONF(pipe));
+
+	/* Set up the display plane register */
+	dspcntr = DISPPLANE_GAMMA_ENABLE;
+
+	DRM_DEBUG_KMS("Mode for pipe %c:\n", pipe == 0 ? 'A' : 'B');
+	drm_mode_debug_printmodeline(mode);
+
 	/* PCH eDP needs FDI, but CPU eDP does not */
 	if (!has_edp_encoder || intel_encoder_is_pch_edp(&has_edp_encoder->base)) {
-		I915_WRITE(fp_reg, fp);
-		I915_WRITE(dpll_reg, dpll & ~DPLL_VCO_ENABLE);
+		I915_WRITE(PCH_FP0(pipe), fp);
+		I915_WRITE(PCH_DPLL(pipe), dpll & ~DPLL_VCO_ENABLE);
 
-		POSTING_READ(dpll_reg);
+		POSTING_READ(PCH_DPLL(pipe));
 		udelay(150);
 	}
 
@@ -4964,11 +5061,7 @@
 	 * things on.
 	 */
 	if (is_lvds) {
-		reg = LVDS;
-		if (HAS_PCH_SPLIT(dev))
-			reg = PCH_LVDS;
-
-		temp = I915_READ(reg);
+		temp = I915_READ(PCH_LVDS);
 		temp |= LVDS_PORT_EN | LVDS_A0A2_CLKA_POWER_UP;
 		if (pipe == 1) {
 			if (HAS_PCH_CPT(dev))
@@ -4995,13 +5088,6 @@
 		 * appropriately here, but we need to look more thoroughly into how
 		 * panels behave in the two modes.
 		 */
-		/* set the dithering flag on non-PCH LVDS as needed */
-		if (INTEL_INFO(dev)->gen >= 4 && !HAS_PCH_SPLIT(dev)) {
-			if (dev_priv->lvds_dither)
-				temp |= LVDS_ENABLE_DITHER;
-			else
-				temp &= ~LVDS_ENABLE_DITHER;
-		}
 		if (adjusted_mode->flags & DRM_MODE_FLAG_NHSYNC)
 			lvds_sync |= LVDS_HSYNC_POLARITY;
 		if (adjusted_mode->flags & DRM_MODE_FLAG_NVSYNC)
@@ -5018,22 +5104,20 @@
 			temp &= ~(LVDS_HSYNC_POLARITY | LVDS_VSYNC_POLARITY);
 			temp |= lvds_sync;
 		}
-		I915_WRITE(reg, temp);
+		I915_WRITE(PCH_LVDS, temp);
 	}
 
 	/* set the dithering flag and clear for anything other than a panel. */
-	if (HAS_PCH_SPLIT(dev)) {
-		pipeconf &= ~PIPECONF_DITHER_EN;
-		pipeconf &= ~PIPECONF_DITHER_TYPE_MASK;
-		if (dev_priv->lvds_dither && (is_lvds || has_edp_encoder)) {
-			pipeconf |= PIPECONF_DITHER_EN;
-			pipeconf |= PIPECONF_DITHER_TYPE_ST1;
-		}
+	pipeconf &= ~PIPECONF_DITHER_EN;
+	pipeconf &= ~PIPECONF_DITHER_TYPE_MASK;
+	if (dev_priv->lvds_dither && (is_lvds || has_edp_encoder)) {
+		pipeconf |= PIPECONF_DITHER_EN;
+		pipeconf |= PIPECONF_DITHER_TYPE_ST1;
 	}
 
 	if (is_dp || intel_encoder_is_pch_edp(&has_edp_encoder->base)) {
 		intel_dp_set_m_n(crtc, mode, adjusted_mode);
-	} else if (HAS_PCH_SPLIT(dev)) {
+	} else {
 		/* For non-DP output, clear any trans DP clock recovery setting.*/
 		I915_WRITE(TRANSDATA_M1(pipe), 0);
 		I915_WRITE(TRANSDATA_N1(pipe), 0);
@@ -5041,43 +5125,32 @@
 		I915_WRITE(TRANSDPLINK_N1(pipe), 0);
 	}
 
-	if (!has_edp_encoder || intel_encoder_is_pch_edp(&has_edp_encoder->base)) {
-		I915_WRITE(dpll_reg, dpll);
+	if (!has_edp_encoder ||
+	    intel_encoder_is_pch_edp(&has_edp_encoder->base)) {
+		I915_WRITE(PCH_DPLL(pipe), dpll);
 
 		/* Wait for the clocks to stabilize. */
-		POSTING_READ(dpll_reg);
+		POSTING_READ(PCH_DPLL(pipe));
 		udelay(150);
 
-		if (INTEL_INFO(dev)->gen >= 4 && !HAS_PCH_SPLIT(dev)) {
-			temp = 0;
-			if (is_sdvo) {
-				temp = intel_mode_get_pixel_multiplier(adjusted_mode);
-				if (temp > 1)
-					temp = (temp - 1) << DPLL_MD_UDI_MULTIPLIER_SHIFT;
-				else
-					temp = 0;
-			}
-			I915_WRITE(DPLL_MD(pipe), temp);
-		} else {
-			/* The pixel multiplier can only be updated once the
-			 * DPLL is enabled and the clocks are stable.
-			 *
-			 * So write it again.
-			 */
-			I915_WRITE(dpll_reg, dpll);
-		}
+		/* The pixel multiplier can only be updated once the
+		 * DPLL is enabled and the clocks are stable.
+		 *
+		 * So write it again.
+		 */
+		I915_WRITE(PCH_DPLL(pipe), dpll);
 	}
 
 	intel_crtc->lowfreq_avail = false;
 	if (is_lvds && has_reduced_clock && i915_powersave) {
-		I915_WRITE(fp_reg + 4, fp2);
+		I915_WRITE(PCH_FP1(pipe), fp2);
 		intel_crtc->lowfreq_avail = true;
 		if (HAS_PIPE_CXSR(dev)) {
 			DRM_DEBUG_KMS("enabling CxSR downclocking\n");
 			pipeconf |= PIPECONF_CXSR_DOWNCLOCK;
 		}
 	} else {
-		I915_WRITE(fp_reg + 4, fp);
+		I915_WRITE(PCH_FP1(pipe), fp);
 		if (HAS_PIPE_CXSR(dev)) {
 			DRM_DEBUG_KMS("disabling CxSR downclocking\n");
 			pipeconf &= ~PIPECONF_CXSR_DOWNCLOCK;
@@ -5116,33 +5189,24 @@
 		   (adjusted_mode->crtc_vsync_start - 1) |
 		   ((adjusted_mode->crtc_vsync_end - 1) << 16));
 
-	/* pipesrc and dspsize control the size that is scaled from,
-	 * which should always be the user's requested size.
+	/* pipesrc controls the size that is scaled from, which should
+	 * always be the user's requested size.
 	 */
-	if (!HAS_PCH_SPLIT(dev)) {
-		I915_WRITE(DSPSIZE(plane),
-			   ((mode->vdisplay - 1) << 16) |
-			   (mode->hdisplay - 1));
-		I915_WRITE(DSPPOS(plane), 0);
-	}
 	I915_WRITE(PIPESRC(pipe),
 		   ((mode->hdisplay - 1) << 16) | (mode->vdisplay - 1));
 
-	if (HAS_PCH_SPLIT(dev)) {
-		I915_WRITE(PIPE_DATA_M1(pipe), TU_SIZE(m_n.tu) | m_n.gmch_m);
-		I915_WRITE(PIPE_DATA_N1(pipe), m_n.gmch_n);
-		I915_WRITE(PIPE_LINK_M1(pipe), m_n.link_m);
-		I915_WRITE(PIPE_LINK_N1(pipe), m_n.link_n);
+	I915_WRITE(PIPE_DATA_M1(pipe), TU_SIZE(m_n.tu) | m_n.gmch_m);
+	I915_WRITE(PIPE_DATA_N1(pipe), m_n.gmch_n);
+	I915_WRITE(PIPE_LINK_M1(pipe), m_n.link_m);
+	I915_WRITE(PIPE_LINK_N1(pipe), m_n.link_n);
 
-		if (has_edp_encoder && !intel_encoder_is_pch_edp(&has_edp_encoder->base)) {
-			ironlake_set_pll_edp(crtc, adjusted_mode->clock);
-		}
+	if (has_edp_encoder &&
+	    !intel_encoder_is_pch_edp(&has_edp_encoder->base)) {
+		ironlake_set_pll_edp(crtc, adjusted_mode->clock);
 	}
 
 	I915_WRITE(PIPECONF(pipe), pipeconf);
 	POSTING_READ(PIPECONF(pipe));
-	if (!HAS_PCH_SPLIT(dev))
-		intel_enable_pipe(dev_priv, pipe, false);
 
 	intel_wait_for_vblank(dev, pipe);
 
@@ -5154,13 +5218,31 @@
 
 	I915_WRITE(DSPCNTR(plane), dspcntr);
 	POSTING_READ(DSPCNTR(plane));
-	if (!HAS_PCH_SPLIT(dev))
-		intel_enable_plane(dev_priv, plane, pipe);
 
 	ret = intel_pipe_set_base(crtc, x, y, old_fb);
 
 	intel_update_watermarks(dev);
 
+	return ret;
+}
+
+static int intel_crtc_mode_set(struct drm_crtc *crtc,
+			       struct drm_display_mode *mode,
+			       struct drm_display_mode *adjusted_mode,
+			       int x, int y,
+			       struct drm_framebuffer *old_fb)
+{
+	struct drm_device *dev = crtc->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+	int pipe = intel_crtc->pipe;
+	int ret;
+
+	drm_vblank_pre_modeset(dev, pipe);
+
+	ret = dev_priv->display.crtc_mode_set(crtc, mode, adjusted_mode,
+					      x, y, old_fb);
+
 	drm_vblank_post_modeset(dev, pipe);
 
 	return ret;
@@ -5483,43 +5565,140 @@
 		 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_encoder *intel_encoder,
-					    struct drm_connector *connector,
-					    struct drm_display_mode *mode,
-					    int *dpms_mode)
+static struct drm_framebuffer *
+intel_framebuffer_create(struct drm_device *dev,
+			 struct drm_mode_fb_cmd *mode_cmd,
+			 struct drm_i915_gem_object *obj)
+{
+	struct intel_framebuffer *intel_fb;
+	int ret;
+
+	intel_fb = kzalloc(sizeof(*intel_fb), GFP_KERNEL);
+	if (!intel_fb) {
+		drm_gem_object_unreference_unlocked(&obj->base);
+		return ERR_PTR(-ENOMEM);
+	}
+
+	ret = intel_framebuffer_init(dev, intel_fb, mode_cmd, obj);
+	if (ret) {
+		drm_gem_object_unreference_unlocked(&obj->base);
+		kfree(intel_fb);
+		return ERR_PTR(ret);
+	}
+
+	return &intel_fb->base;
+}
+
+static u32
+intel_framebuffer_pitch_for_width(int width, int bpp)
+{
+	u32 pitch = DIV_ROUND_UP(width * bpp, 8);
+	return ALIGN(pitch, 64);
+}
+
+static u32
+intel_framebuffer_size_for_mode(struct drm_display_mode *mode, int bpp)
+{
+	u32 pitch = intel_framebuffer_pitch_for_width(mode->hdisplay, bpp);
+	return ALIGN(pitch * mode->vdisplay, PAGE_SIZE);
+}
+
+static struct drm_framebuffer *
+intel_framebuffer_create_for_mode(struct drm_device *dev,
+				  struct drm_display_mode *mode,
+				  int depth, int bpp)
+{
+	struct drm_i915_gem_object *obj;
+	struct drm_mode_fb_cmd mode_cmd;
+
+	obj = i915_gem_alloc_object(dev,
+				    intel_framebuffer_size_for_mode(mode, bpp));
+	if (obj == NULL)
+		return ERR_PTR(-ENOMEM);
+
+	mode_cmd.width = mode->hdisplay;
+	mode_cmd.height = mode->vdisplay;
+	mode_cmd.depth = depth;
+	mode_cmd.bpp = bpp;
+	mode_cmd.pitch = intel_framebuffer_pitch_for_width(mode_cmd.width, bpp);
+
+	return intel_framebuffer_create(dev, &mode_cmd, obj);
+}
+
+static struct drm_framebuffer *
+mode_fits_in_fbdev(struct drm_device *dev,
+		   struct drm_display_mode *mode)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct drm_i915_gem_object *obj;
+	struct drm_framebuffer *fb;
+
+	if (dev_priv->fbdev == NULL)
+		return NULL;
+
+	obj = dev_priv->fbdev->ifb.obj;
+	if (obj == NULL)
+		return NULL;
+
+	fb = &dev_priv->fbdev->ifb.base;
+	if (fb->pitch < intel_framebuffer_pitch_for_width(mode->hdisplay,
+							  fb->bits_per_pixel))
+		return NULL;
+
+	if (obj->base.size < mode->vdisplay * fb->pitch)
+		return NULL;
+
+	return fb;
+}
+
+bool intel_get_load_detect_pipe(struct intel_encoder *intel_encoder,
+				struct drm_connector *connector,
+				struct drm_display_mode *mode,
+				struct intel_load_detect_pipe *old)
 {
 	struct intel_crtc *intel_crtc;
 	struct drm_crtc *possible_crtc;
-	struct drm_crtc *supported_crtc =NULL;
 	struct drm_encoder *encoder = &intel_encoder->base;
 	struct drm_crtc *crtc = NULL;
 	struct drm_device *dev = encoder->dev;
-	struct drm_encoder_helper_funcs *encoder_funcs = encoder->helper_private;
-	struct drm_crtc_helper_funcs *crtc_funcs;
+	struct drm_framebuffer *old_fb;
 	int i = -1;
 
+	DRM_DEBUG_KMS("[CONNECTOR:%d:%s], [ENCODER:%d:%s]\n",
+		      connector->base.id, drm_get_connector_name(connector),
+		      encoder->base.id, drm_get_encoder_name(encoder));
+
 	/*
 	 * Algorithm gets a little messy:
+	 *
 	 *   - if the connector already has an assigned crtc, use it (but make
 	 *     sure it's on first)
+	 *
 	 *   - try to find the first unused crtc that can drive this connector,
 	 *     and use that if we find one
-	 *   - if there are no unused crtcs available, try to use the first
-	 *     one we found that supports the connector
 	 */
 
 	/* See if we already have a CRTC for this connector */
 	if (encoder->crtc) {
 		crtc = encoder->crtc;
-		/* Make sure the crtc and connector are running */
+
 		intel_crtc = to_intel_crtc(crtc);
-		*dpms_mode = intel_crtc->dpms_mode;
+		old->dpms_mode = intel_crtc->dpms_mode;
+		old->load_detect_temp = false;
+
+		/* Make sure the crtc and connector are running */
 		if (intel_crtc->dpms_mode != DRM_MODE_DPMS_ON) {
+			struct drm_encoder_helper_funcs *encoder_funcs;
+			struct drm_crtc_helper_funcs *crtc_funcs;
+
 			crtc_funcs = crtc->helper_private;
 			crtc_funcs->dpms(crtc, DRM_MODE_DPMS_ON);
+
+			encoder_funcs = encoder->helper_private;
 			encoder_funcs->dpms(encoder, DRM_MODE_DPMS_ON);
 		}
-		return crtc;
+
+		return true;
 	}
 
 	/* Find an unused one (if possible) */
@@ -5531,46 +5710,66 @@
 			crtc = possible_crtc;
 			break;
 		}
-		if (!supported_crtc)
-			supported_crtc = possible_crtc;
 	}
 
 	/*
 	 * If we didn't find an unused CRTC, don't use any.
 	 */
 	if (!crtc) {
-		return NULL;
+		DRM_DEBUG_KMS("no pipe available for load-detect\n");
+		return false;
 	}
 
 	encoder->crtc = crtc;
 	connector->encoder = encoder;
-	intel_encoder->load_detect_temp = true;
 
 	intel_crtc = to_intel_crtc(crtc);
-	*dpms_mode = intel_crtc->dpms_mode;
+	old->dpms_mode = intel_crtc->dpms_mode;
+	old->load_detect_temp = true;
+	old->release_fb = NULL;
 
-	if (!crtc->enabled) {
-		if (!mode)
-			mode = &load_detect_mode;
-		drm_crtc_helper_set_mode(crtc, mode, 0, 0, crtc->fb);
-	} else {
-		if (intel_crtc->dpms_mode != DRM_MODE_DPMS_ON) {
-			crtc_funcs = crtc->helper_private;
-			crtc_funcs->dpms(crtc, DRM_MODE_DPMS_ON);
-		}
+	if (!mode)
+		mode = &load_detect_mode;
 
-		/* Add this connector to the crtc */
-		encoder_funcs->mode_set(encoder, &crtc->mode, &crtc->mode);
-		encoder_funcs->commit(encoder);
+	old_fb = crtc->fb;
+
+	/* We need a framebuffer large enough to accommodate all accesses
+	 * that the plane may generate whilst we perform load detection.
+	 * We can not rely on the fbcon either being present (we get called
+	 * during its initialisation to detect all boot displays, or it may
+	 * not even exist) or that it is large enough to satisfy the
+	 * requested mode.
+	 */
+	crtc->fb = mode_fits_in_fbdev(dev, mode);
+	if (crtc->fb == NULL) {
+		DRM_DEBUG_KMS("creating tmp fb for load-detection\n");
+		crtc->fb = intel_framebuffer_create_for_mode(dev, mode, 24, 32);
+		old->release_fb = crtc->fb;
+	} else
+		DRM_DEBUG_KMS("reusing fbdev for load-detection framebuffer\n");
+	if (IS_ERR(crtc->fb)) {
+		DRM_DEBUG_KMS("failed to allocate framebuffer for load-detection\n");
+		crtc->fb = old_fb;
+		return false;
 	}
+
+	if (!drm_crtc_helper_set_mode(crtc, mode, 0, 0, old_fb)) {
+		DRM_DEBUG_KMS("failed to set mode on load-detect pipe\n");
+		if (old->release_fb)
+			old->release_fb->funcs->destroy(old->release_fb);
+		crtc->fb = old_fb;
+		return false;
+	}
+
 	/* let the connector get through one full cycle before testing */
 	intel_wait_for_vblank(dev, intel_crtc->pipe);
 
-	return crtc;
+	return true;
 }
 
 void intel_release_load_detect_pipe(struct intel_encoder *intel_encoder,
-				    struct drm_connector *connector, int dpms_mode)
+				    struct drm_connector *connector,
+				    struct intel_load_detect_pipe *old)
 {
 	struct drm_encoder *encoder = &intel_encoder->base;
 	struct drm_device *dev = encoder->dev;
@@ -5578,19 +5777,24 @@
 	struct drm_encoder_helper_funcs *encoder_funcs = encoder->helper_private;
 	struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
 
-	if (intel_encoder->load_detect_temp) {
-		encoder->crtc = NULL;
+	DRM_DEBUG_KMS("[CONNECTOR:%d:%s], [ENCODER:%d:%s]\n",
+		      connector->base.id, drm_get_connector_name(connector),
+		      encoder->base.id, drm_get_encoder_name(encoder));
+
+	if (old->load_detect_temp) {
 		connector->encoder = NULL;
-		intel_encoder->load_detect_temp = false;
-		crtc->enabled = drm_helper_crtc_in_use(crtc);
 		drm_helper_disable_unused_functions(dev);
+
+		if (old->release_fb)
+			old->release_fb->funcs->destroy(old->release_fb);
+
+		return;
 	}
 
 	/* 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);
-		crtc_funcs->dpms(crtc, dpms_mode);
+	if (old->dpms_mode != DRM_MODE_DPMS_ON) {
+		encoder_funcs->dpms(encoder, old->dpms_mode);
+		crtc_funcs->dpms(crtc, old->dpms_mode);
 	}
 }
 
@@ -6057,6 +6261,197 @@
 	spin_unlock_irqrestore(&dev->event_lock, flags);
 }
 
+static int intel_gen2_queue_flip(struct drm_device *dev,
+				 struct drm_crtc *crtc,
+				 struct drm_framebuffer *fb,
+				 struct drm_i915_gem_object *obj)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+	unsigned long offset;
+	u32 flip_mask;
+	int ret;
+
+	ret = intel_pin_and_fence_fb_obj(dev, obj, LP_RING(dev_priv));
+	if (ret)
+		goto out;
+
+	/* Offset into the new buffer for cases of shared fbs between CRTCs */
+	offset = crtc->y * fb->pitch + crtc->x * fb->bits_per_pixel/8;
+
+	ret = BEGIN_LP_RING(6);
+	if (ret)
+		goto out;
+
+	/* Can't queue multiple flips, so wait for the previous
+	 * one to finish before executing the next.
+	 */
+	if (intel_crtc->plane)
+		flip_mask = MI_WAIT_FOR_PLANE_B_FLIP;
+	else
+		flip_mask = MI_WAIT_FOR_PLANE_A_FLIP;
+	OUT_RING(MI_WAIT_FOR_EVENT | flip_mask);
+	OUT_RING(MI_NOOP);
+	OUT_RING(MI_DISPLAY_FLIP |
+		 MI_DISPLAY_FLIP_PLANE(intel_crtc->plane));
+	OUT_RING(fb->pitch);
+	OUT_RING(obj->gtt_offset + offset);
+	OUT_RING(MI_NOOP);
+	ADVANCE_LP_RING();
+out:
+	return ret;
+}
+
+static int intel_gen3_queue_flip(struct drm_device *dev,
+				 struct drm_crtc *crtc,
+				 struct drm_framebuffer *fb,
+				 struct drm_i915_gem_object *obj)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+	unsigned long offset;
+	u32 flip_mask;
+	int ret;
+
+	ret = intel_pin_and_fence_fb_obj(dev, obj, LP_RING(dev_priv));
+	if (ret)
+		goto out;
+
+	/* Offset into the new buffer for cases of shared fbs between CRTCs */
+	offset = crtc->y * fb->pitch + crtc->x * fb->bits_per_pixel/8;
+
+	ret = BEGIN_LP_RING(6);
+	if (ret)
+		goto out;
+
+	if (intel_crtc->plane)
+		flip_mask = MI_WAIT_FOR_PLANE_B_FLIP;
+	else
+		flip_mask = MI_WAIT_FOR_PLANE_A_FLIP;
+	OUT_RING(MI_WAIT_FOR_EVENT | flip_mask);
+	OUT_RING(MI_NOOP);
+	OUT_RING(MI_DISPLAY_FLIP_I915 |
+		 MI_DISPLAY_FLIP_PLANE(intel_crtc->plane));
+	OUT_RING(fb->pitch);
+	OUT_RING(obj->gtt_offset + offset);
+	OUT_RING(MI_NOOP);
+
+	ADVANCE_LP_RING();
+out:
+	return ret;
+}
+
+static int intel_gen4_queue_flip(struct drm_device *dev,
+				 struct drm_crtc *crtc,
+				 struct drm_framebuffer *fb,
+				 struct drm_i915_gem_object *obj)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+	uint32_t pf, pipesrc;
+	int ret;
+
+	ret = intel_pin_and_fence_fb_obj(dev, obj, LP_RING(dev_priv));
+	if (ret)
+		goto out;
+
+	ret = BEGIN_LP_RING(4);
+	if (ret)
+		goto out;
+
+	/* i965+ uses the linear or tiled offsets from the
+	 * Display Registers (which do not change across a page-flip)
+	 * so we need only reprogram the base address.
+	 */
+	OUT_RING(MI_DISPLAY_FLIP |
+		 MI_DISPLAY_FLIP_PLANE(intel_crtc->plane));
+	OUT_RING(fb->pitch);
+	OUT_RING(obj->gtt_offset | obj->tiling_mode);
+
+	/* XXX Enabling the panel-fitter across page-flip is so far
+	 * untested on non-native modes, so ignore it for now.
+	 * pf = I915_READ(pipe == 0 ? PFA_CTL_1 : PFB_CTL_1) & PF_ENABLE;
+	 */
+	pf = 0;
+	pipesrc = I915_READ(PIPESRC(intel_crtc->pipe)) & 0x0fff0fff;
+	OUT_RING(pf | pipesrc);
+	ADVANCE_LP_RING();
+out:
+	return ret;
+}
+
+static int intel_gen6_queue_flip(struct drm_device *dev,
+				 struct drm_crtc *crtc,
+				 struct drm_framebuffer *fb,
+				 struct drm_i915_gem_object *obj)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+	uint32_t pf, pipesrc;
+	int ret;
+
+	ret = intel_pin_and_fence_fb_obj(dev, obj, LP_RING(dev_priv));
+	if (ret)
+		goto out;
+
+	ret = BEGIN_LP_RING(4);
+	if (ret)
+		goto out;
+
+	OUT_RING(MI_DISPLAY_FLIP |
+		 MI_DISPLAY_FLIP_PLANE(intel_crtc->plane));
+	OUT_RING(fb->pitch | obj->tiling_mode);
+	OUT_RING(obj->gtt_offset);
+
+	pf = I915_READ(PF_CTL(intel_crtc->pipe)) & PF_ENABLE;
+	pipesrc = I915_READ(PIPESRC(intel_crtc->pipe)) & 0x0fff0fff;
+	OUT_RING(pf | pipesrc);
+	ADVANCE_LP_RING();
+out:
+	return ret;
+}
+
+/*
+ * On gen7 we currently use the blit ring because (in early silicon at least)
+ * the render ring doesn't give us interrpts for page flip completion, which
+ * means clients will hang after the first flip is queued.  Fortunately the
+ * blit ring generates interrupts properly, so use it instead.
+ */
+static int intel_gen7_queue_flip(struct drm_device *dev,
+				 struct drm_crtc *crtc,
+				 struct drm_framebuffer *fb,
+				 struct drm_i915_gem_object *obj)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+	struct intel_ring_buffer *ring = &dev_priv->ring[BCS];
+	int ret;
+
+	ret = intel_pin_and_fence_fb_obj(dev, obj, ring);
+	if (ret)
+		goto out;
+
+	ret = intel_ring_begin(ring, 4);
+	if (ret)
+		goto out;
+
+	intel_ring_emit(ring, MI_DISPLAY_FLIP_I915 | (intel_crtc->plane << 19));
+	intel_ring_emit(ring, (fb->pitch | obj->tiling_mode));
+	intel_ring_emit(ring, (obj->gtt_offset));
+	intel_ring_emit(ring, (MI_NOOP));
+	intel_ring_advance(ring);
+out:
+	return ret;
+}
+
+static int intel_default_queue_flip(struct drm_device *dev,
+				    struct drm_crtc *crtc,
+				    struct drm_framebuffer *fb,
+				    struct drm_i915_gem_object *obj)
+{
+	return -ENODEV;
+}
+
 static int intel_crtc_page_flip(struct drm_crtc *crtc,
 				struct drm_framebuffer *fb,
 				struct drm_pending_vblank_event *event)
@@ -6067,9 +6462,7 @@
 	struct drm_i915_gem_object *obj;
 	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
 	struct intel_unpin_work *work;
-	unsigned long flags, offset;
-	int pipe = intel_crtc->pipe;
-	u32 pf, pipesrc;
+	unsigned long flags;
 	int ret;
 
 	work = kzalloc(sizeof *work, GFP_KERNEL);
@@ -6098,9 +6491,6 @@
 	obj = intel_fb->obj;
 
 	mutex_lock(&dev->struct_mutex);
-	ret = intel_pin_and_fence_fb_obj(dev, obj, LP_RING(dev_priv));
-	if (ret)
-		goto cleanup_work;
 
 	/* Reference the objects for the scheduled work. */
 	drm_gem_object_reference(&work->old_fb_obj->base);
@@ -6112,90 +6502,18 @@
 	if (ret)
 		goto cleanup_objs;
 
-	if (IS_GEN3(dev) || IS_GEN2(dev)) {
-		u32 flip_mask;
-
-		/* Can't queue multiple flips, so wait for the previous
-		 * one to finish before executing the next.
-		 */
-		ret = BEGIN_LP_RING(2);
-		if (ret)
-			goto cleanup_objs;
-
-		if (intel_crtc->plane)
-			flip_mask = MI_WAIT_FOR_PLANE_B_FLIP;
-		else
-			flip_mask = MI_WAIT_FOR_PLANE_A_FLIP;
-		OUT_RING(MI_WAIT_FOR_EVENT | flip_mask);
-		OUT_RING(MI_NOOP);
-		ADVANCE_LP_RING();
-	}
-
 	work->pending_flip_obj = obj;
 
 	work->enable_stall_check = true;
 
-	/* Offset into the new buffer for cases of shared fbs between CRTCs */
-	offset = crtc->y * fb->pitch + crtc->x * fb->bits_per_pixel/8;
-
-	ret = BEGIN_LP_RING(4);
-	if (ret)
-		goto cleanup_objs;
-
 	/* Block clients from rendering to the new back buffer until
 	 * the flip occurs and the object is no longer visible.
 	 */
 	atomic_add(1 << intel_crtc->plane, &work->old_fb_obj->pending_flip);
 
-	switch (INTEL_INFO(dev)->gen) {
-	case 2:
-		OUT_RING(MI_DISPLAY_FLIP |
-			 MI_DISPLAY_FLIP_PLANE(intel_crtc->plane));
-		OUT_RING(fb->pitch);
-		OUT_RING(obj->gtt_offset + offset);
-		OUT_RING(MI_NOOP);
-		break;
-
-	case 3:
-		OUT_RING(MI_DISPLAY_FLIP_I915 |
-			 MI_DISPLAY_FLIP_PLANE(intel_crtc->plane));
-		OUT_RING(fb->pitch);
-		OUT_RING(obj->gtt_offset + offset);
-		OUT_RING(MI_NOOP);
-		break;
-
-	case 4:
-	case 5:
-		/* i965+ uses the linear or tiled offsets from the
-		 * Display Registers (which do not change across a page-flip)
-		 * so we need only reprogram the base address.
-		 */
-		OUT_RING(MI_DISPLAY_FLIP |
-			 MI_DISPLAY_FLIP_PLANE(intel_crtc->plane));
-		OUT_RING(fb->pitch);
-		OUT_RING(obj->gtt_offset | obj->tiling_mode);
-
-		/* XXX Enabling the panel-fitter across page-flip is so far
-		 * untested on non-native modes, so ignore it for now.
-		 * pf = I915_READ(pipe == 0 ? PFA_CTL_1 : PFB_CTL_1) & PF_ENABLE;
-		 */
-		pf = 0;
-		pipesrc = I915_READ(PIPESRC(pipe)) & 0x0fff0fff;
-		OUT_RING(pf | pipesrc);
-		break;
-
-	case 6:
-		OUT_RING(MI_DISPLAY_FLIP |
-			 MI_DISPLAY_FLIP_PLANE(intel_crtc->plane));
-		OUT_RING(fb->pitch | obj->tiling_mode);
-		OUT_RING(obj->gtt_offset);
-
-		pf = I915_READ(PF_CTL(pipe)) & PF_ENABLE;
-		pipesrc = I915_READ(PIPESRC(pipe)) & 0x0fff0fff;
-		OUT_RING(pf | pipesrc);
-		break;
-	}
-	ADVANCE_LP_RING();
+	ret = dev_priv->display.queue_flip(dev, crtc, fb, obj);
+	if (ret)
+		goto cleanup_pending;
 
 	mutex_unlock(&dev->struct_mutex);
 
@@ -6203,10 +6521,11 @@
 
 	return 0;
 
+cleanup_pending:
+	atomic_sub(1 << intel_crtc->plane, &work->old_fb_obj->pending_flip);
 cleanup_objs:
 	drm_gem_object_unreference(&work->old_fb_obj->base);
 	drm_gem_object_unreference(&obj->base);
-cleanup_work:
 	mutex_unlock(&dev->struct_mutex);
 
 	spin_lock_irqsave(&dev->event_lock, flags);
@@ -6504,6 +6823,9 @@
 	}
 
 	intel_panel_setup_backlight(dev);
+
+	/* disable all the possible outputs/crtcs before entering KMS mode */
+	drm_helper_disable_unused_functions(dev);
 }
 
 static void intel_user_framebuffer_destroy(struct drm_framebuffer *fb)
@@ -6571,27 +6893,12 @@
 			      struct drm_mode_fb_cmd *mode_cmd)
 {
 	struct drm_i915_gem_object *obj;
-	struct intel_framebuffer *intel_fb;
-	int ret;
 
 	obj = to_intel_bo(drm_gem_object_lookup(dev, filp, mode_cmd->handle));
 	if (&obj->base == NULL)
 		return ERR_PTR(-ENOENT);
 
-	intel_fb = kzalloc(sizeof(*intel_fb), GFP_KERNEL);
-	if (!intel_fb) {
-		drm_gem_object_unreference_unlocked(&obj->base);
-		return ERR_PTR(-ENOMEM);
-	}
-
-	ret = intel_framebuffer_init(dev, intel_fb, mode_cmd, obj);
-	if (ret) {
-		drm_gem_object_unreference_unlocked(&obj->base);
-		kfree(intel_fb);
-		return ERR_PTR(ret);
-	}
-
-	return &intel_fb->base;
+	return intel_framebuffer_create(dev, mode_cmd, obj);
 }
 
 static const struct drm_mode_config_funcs intel_mode_funcs = {
@@ -6605,13 +6912,14 @@
 	struct drm_i915_gem_object *ctx;
 	int ret;
 
+	WARN_ON(!mutex_is_locked(&dev->struct_mutex));
+
 	ctx = i915_gem_alloc_object(dev, 4096);
 	if (!ctx) {
 		DRM_DEBUG("failed to alloc power context, RC6 disabled\n");
 		return NULL;
 	}
 
-	mutex_lock(&dev->struct_mutex);
 	ret = i915_gem_object_pin(ctx, 4096, true);
 	if (ret) {
 		DRM_ERROR("failed to pin power context: %d\n", ret);
@@ -6623,7 +6931,6 @@
 		DRM_ERROR("failed to set-domain on power context: %d\n", ret);
 		goto err_unpin;
 	}
-	mutex_unlock(&dev->struct_mutex);
 
 	return ctx;
 
@@ -6758,6 +7065,11 @@
 	I915_WRITE(GEN6_RPNSWREQ, 1 << 31);
 	I915_WRITE(GEN6_PMINTRMSK, 0xffffffff);
 	I915_WRITE(GEN6_PMIER, 0);
+
+	spin_lock_irq(&dev_priv->rps_lock);
+	dev_priv->pm_iir = 0;
+	spin_unlock_irq(&dev_priv->rps_lock);
+
 	I915_WRITE(GEN6_PMIIR, I915_READ(GEN6_PMIIR));
 }
 
@@ -6851,7 +7163,7 @@
 {
 	u32 rp_state_cap = I915_READ(GEN6_RP_STATE_CAP);
 	u32 gt_perf_status = I915_READ(GEN6_GT_PERF_STATUS);
-	u32 pcu_mbox;
+	u32 pcu_mbox, rc6_mask = 0;
 	int cur_freq, min_freq, max_freq;
 	int i;
 
@@ -6862,7 +7174,8 @@
 	 * userspace...
 	 */
 	I915_WRITE(GEN6_RC_STATE, 0);
-	__gen6_gt_force_wake_get(dev_priv);
+	mutex_lock(&dev_priv->dev->struct_mutex);
+	gen6_gt_force_wake_get(dev_priv);
 
 	/* disable the counters and set deterministic thresholds */
 	I915_WRITE(GEN6_RC_CONTROL, 0);
@@ -6882,9 +7195,12 @@
 	I915_WRITE(GEN6_RC6p_THRESHOLD, 100000);
 	I915_WRITE(GEN6_RC6pp_THRESHOLD, 64000); /* unused */
 
+	if (i915_enable_rc6)
+		rc6_mask = GEN6_RC_CTL_RC6p_ENABLE |
+			GEN6_RC_CTL_RC6_ENABLE;
+
 	I915_WRITE(GEN6_RC_CONTROL,
-		   GEN6_RC_CTL_RC6p_ENABLE |
-		   GEN6_RC_CTL_RC6_ENABLE |
+		   rc6_mask |
 		   GEN6_RC_CTL_EI_MODE(1) |
 		   GEN6_RC_CTL_HW_ENABLE);
 
@@ -6956,168 +7272,237 @@
 		   GEN6_PM_RP_DOWN_THRESHOLD |
 		   GEN6_PM_RP_UP_EI_EXPIRED |
 		   GEN6_PM_RP_DOWN_EI_EXPIRED);
+	spin_lock_irq(&dev_priv->rps_lock);
+	WARN_ON(dev_priv->pm_iir != 0);
 	I915_WRITE(GEN6_PMIMR, 0);
+	spin_unlock_irq(&dev_priv->rps_lock);
 	/* enable all PM interrupts */
 	I915_WRITE(GEN6_PMINTRMSK, 0);
 
-	__gen6_gt_force_wake_put(dev_priv);
+	gen6_gt_force_wake_put(dev_priv);
+	mutex_unlock(&dev_priv->dev->struct_mutex);
 }
 
-void intel_enable_clock_gating(struct drm_device *dev)
+static void ironlake_init_clock_gating(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	uint32_t dspclk_gate = VRHUNIT_CLOCK_GATE_DISABLE;
+
+	/* Required for FBC */
+	dspclk_gate |= DPFCUNIT_CLOCK_GATE_DISABLE |
+		DPFCRUNIT_CLOCK_GATE_DISABLE |
+		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_3DCGDIS1,
+		   VFMUNIT_CLOCK_GATE_DISABLE);
+
+	I915_WRITE(PCH_DSPCLK_GATE_D, dspclk_gate);
+
+	/*
+	 * According to the spec the following bits should be set in
+	 * order to enable memory self-refresh
+	 * The bit 22/21 of 0x42004
+	 * The bit 5 of 0x42020
+	 * The bit 15 of 0x45000
+	 */
+	I915_WRITE(ILK_DISPLAY_CHICKEN2,
+		   (I915_READ(ILK_DISPLAY_CHICKEN2) |
+		    ILK_DPARB_GATE | ILK_VSDPFD_FULL));
+	I915_WRITE(ILK_DSPCLK_GATE,
+		   (I915_READ(ILK_DSPCLK_GATE) |
+		    ILK_DPARB_CLK_GATE));
+	I915_WRITE(DISP_ARB_CTL,
+		   (I915_READ(DISP_ARB_CTL) |
+		    DISP_FBC_WM_DIS));
+	I915_WRITE(WM3_LP_ILK, 0);
+	I915_WRITE(WM2_LP_ILK, 0);
+	I915_WRITE(WM1_LP_ILK, 0);
+
+	/*
+	 * Based on the document from hardware guys the following bits
+	 * should be set unconditionally in order to enable FBC.
+	 * The bit 22 of 0x42000
+	 * The bit 22 of 0x42004
+	 * The bit 7,8,9 of 0x42020.
+	 */
+	if (IS_IRONLAKE_M(dev)) {
+		I915_WRITE(ILK_DISPLAY_CHICKEN1,
+			   I915_READ(ILK_DISPLAY_CHICKEN1) |
+			   ILK_FBCQ_DIS);
+		I915_WRITE(ILK_DISPLAY_CHICKEN2,
+			   I915_READ(ILK_DISPLAY_CHICKEN2) |
+			   ILK_DPARB_GATE);
+		I915_WRITE(ILK_DSPCLK_GATE,
+			   I915_READ(ILK_DSPCLK_GATE) |
+			   ILK_DPFC_DIS1 |
+			   ILK_DPFC_DIS2 |
+			   ILK_CLK_FBC);
+	}
+
+	I915_WRITE(ILK_DISPLAY_CHICKEN2,
+		   I915_READ(ILK_DISPLAY_CHICKEN2) |
+		   ILK_ELPIN_409_SELECT);
+	I915_WRITE(_3D_CHICKEN2,
+		   _3D_CHICKEN2_WM_READ_PIPELINED << 16 |
+		   _3D_CHICKEN2_WM_READ_PIPELINED);
+}
+
+static void gen6_init_clock_gating(struct drm_device *dev)
 {
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	int pipe;
+	uint32_t dspclk_gate = VRHUNIT_CLOCK_GATE_DISABLE;
+
+	I915_WRITE(PCH_DSPCLK_GATE_D, dspclk_gate);
+
+	I915_WRITE(ILK_DISPLAY_CHICKEN2,
+		   I915_READ(ILK_DISPLAY_CHICKEN2) |
+		   ILK_ELPIN_409_SELECT);
+
+	I915_WRITE(WM3_LP_ILK, 0);
+	I915_WRITE(WM2_LP_ILK, 0);
+	I915_WRITE(WM1_LP_ILK, 0);
 
 	/*
-	 * Disable clock gating reported to work incorrectly according to the
-	 * specs, but enable as much else as we can.
+	 * According to the spec the following bits should be
+	 * set in order to enable memory self-refresh and fbc:
+	 * The bit21 and bit22 of 0x42000
+	 * The bit21 and bit22 of 0x42004
+	 * The bit5 and bit7 of 0x42020
+	 * The bit14 of 0x70180
+	 * The bit14 of 0x71180
 	 */
-	if (HAS_PCH_SPLIT(dev)) {
-		uint32_t dspclk_gate = VRHUNIT_CLOCK_GATE_DISABLE;
+	I915_WRITE(ILK_DISPLAY_CHICKEN1,
+		   I915_READ(ILK_DISPLAY_CHICKEN1) |
+		   ILK_FBCQ_DIS | ILK_PABSTRETCH_DIS);
+	I915_WRITE(ILK_DISPLAY_CHICKEN2,
+		   I915_READ(ILK_DISPLAY_CHICKEN2) |
+		   ILK_DPARB_GATE | ILK_VSDPFD_FULL);
+	I915_WRITE(ILK_DSPCLK_GATE,
+		   I915_READ(ILK_DSPCLK_GATE) |
+		   ILK_DPARB_CLK_GATE  |
+		   ILK_DPFD_CLK_GATE);
 
-		if (IS_GEN5(dev)) {
-			/* Required for FBC */
-			dspclk_gate |= DPFCUNIT_CLOCK_GATE_DISABLE |
-				DPFCRUNIT_CLOCK_GATE_DISABLE |
-				DPFDUNIT_CLOCK_GATE_DISABLE;
-			/* Required for CxSR */
-			dspclk_gate |= DPARBUNIT_CLOCK_GATE_DISABLE;
+	for_each_pipe(pipe)
+		I915_WRITE(DSPCNTR(pipe),
+			   I915_READ(DSPCNTR(pipe)) |
+			   DISPPLANE_TRICKLE_FEED_DISABLE);
+}
 
-			I915_WRITE(PCH_3DCGDIS0,
-				   MARIUNIT_CLOCK_GATE_DISABLE |
-				   SVSMUNIT_CLOCK_GATE_DISABLE);
-			I915_WRITE(PCH_3DCGDIS1,
-				   VFMUNIT_CLOCK_GATE_DISABLE);
-		}
+static void ivybridge_init_clock_gating(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	int pipe;
+	uint32_t dspclk_gate = VRHUNIT_CLOCK_GATE_DISABLE;
 
-		I915_WRITE(PCH_DSPCLK_GATE_D, dspclk_gate);
+	I915_WRITE(PCH_DSPCLK_GATE_D, dspclk_gate);
 
-		/*
-		 * On Ibex Peak and Cougar Point, we need to disable clock
-		 * gating for the panel power sequencer or it will fail to
-		 * start up when no ports are active.
-		 */
-		I915_WRITE(SOUTH_DSPCLK_GATE_D, PCH_DPLSUNIT_CLOCK_GATE_DISABLE);
+	I915_WRITE(WM3_LP_ILK, 0);
+	I915_WRITE(WM2_LP_ILK, 0);
+	I915_WRITE(WM1_LP_ILK, 0);
 
-		/*
-		 * According to the spec the following bits should be set in
-		 * order to enable memory self-refresh
-		 * The bit 22/21 of 0x42004
-		 * The bit 5 of 0x42020
-		 * The bit 15 of 0x45000
-		 */
-		if (IS_GEN5(dev)) {
-			I915_WRITE(ILK_DISPLAY_CHICKEN2,
-					(I915_READ(ILK_DISPLAY_CHICKEN2) |
-					ILK_DPARB_GATE | ILK_VSDPFD_FULL));
-			I915_WRITE(ILK_DSPCLK_GATE,
-					(I915_READ(ILK_DSPCLK_GATE) |
-						ILK_DPARB_CLK_GATE));
-			I915_WRITE(DISP_ARB_CTL,
-					(I915_READ(DISP_ARB_CTL) |
-						DISP_FBC_WM_DIS));
-			I915_WRITE(WM3_LP_ILK, 0);
-			I915_WRITE(WM2_LP_ILK, 0);
-			I915_WRITE(WM1_LP_ILK, 0);
-		}
-		/*
-		 * Based on the document from hardware guys the following bits
-		 * should be set unconditionally in order to enable FBC.
-		 * The bit 22 of 0x42000
-		 * The bit 22 of 0x42004
-		 * The bit 7,8,9 of 0x42020.
-		 */
-		if (IS_IRONLAKE_M(dev)) {
-			I915_WRITE(ILK_DISPLAY_CHICKEN1,
-				   I915_READ(ILK_DISPLAY_CHICKEN1) |
-				   ILK_FBCQ_DIS);
-			I915_WRITE(ILK_DISPLAY_CHICKEN2,
-				   I915_READ(ILK_DISPLAY_CHICKEN2) |
-				   ILK_DPARB_GATE);
-			I915_WRITE(ILK_DSPCLK_GATE,
-				   I915_READ(ILK_DSPCLK_GATE) |
-				   ILK_DPFC_DIS1 |
-				   ILK_DPFC_DIS2 |
-				   ILK_CLK_FBC);
-		}
+	I915_WRITE(ILK_DSPCLK_GATE, IVB_VRHUNIT_CLK_GATE);
 
-		I915_WRITE(ILK_DISPLAY_CHICKEN2,
-			   I915_READ(ILK_DISPLAY_CHICKEN2) |
-			   ILK_ELPIN_409_SELECT);
+	for_each_pipe(pipe)
+		I915_WRITE(DSPCNTR(pipe),
+			   I915_READ(DSPCNTR(pipe)) |
+			   DISPPLANE_TRICKLE_FEED_DISABLE);
+}
 
-		if (IS_GEN5(dev)) {
-			I915_WRITE(_3D_CHICKEN2,
-				   _3D_CHICKEN2_WM_READ_PIPELINED << 16 |
-				   _3D_CHICKEN2_WM_READ_PIPELINED);
-		}
+static void g4x_init_clock_gating(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	uint32_t dspclk_gate;
 
-		if (IS_GEN6(dev)) {
-			I915_WRITE(WM3_LP_ILK, 0);
-			I915_WRITE(WM2_LP_ILK, 0);
-			I915_WRITE(WM1_LP_ILK, 0);
+	I915_WRITE(RENCLK_GATE_D1, 0);
+	I915_WRITE(RENCLK_GATE_D2, VF_UNIT_CLOCK_GATE_DISABLE |
+		   GS_UNIT_CLOCK_GATE_DISABLE |
+		   CL_UNIT_CLOCK_GATE_DISABLE);
+	I915_WRITE(RAMCLK_GATE_D, 0);
+	dspclk_gate = VRHUNIT_CLOCK_GATE_DISABLE |
+		OVRUNIT_CLOCK_GATE_DISABLE |
+		OVCUNIT_CLOCK_GATE_DISABLE;
+	if (IS_GM45(dev))
+		dspclk_gate |= DSSUNIT_CLOCK_GATE_DISABLE;
+	I915_WRITE(DSPCLK_GATE_D, dspclk_gate);
+}
 
-			/*
-			 * According to the spec the following bits should be
-			 * set in order to enable memory self-refresh and fbc:
-			 * The bit21 and bit22 of 0x42000
-			 * The bit21 and bit22 of 0x42004
-			 * The bit5 and bit7 of 0x42020
-			 * The bit14 of 0x70180
-			 * The bit14 of 0x71180
-			 */
-			I915_WRITE(ILK_DISPLAY_CHICKEN1,
-				   I915_READ(ILK_DISPLAY_CHICKEN1) |
-				   ILK_FBCQ_DIS | ILK_PABSTRETCH_DIS);
-			I915_WRITE(ILK_DISPLAY_CHICKEN2,
-				   I915_READ(ILK_DISPLAY_CHICKEN2) |
-				   ILK_DPARB_GATE | ILK_VSDPFD_FULL);
-			I915_WRITE(ILK_DSPCLK_GATE,
-				   I915_READ(ILK_DSPCLK_GATE) |
-				   ILK_DPARB_CLK_GATE  |
-				   ILK_DPFD_CLK_GATE);
+static void crestline_init_clock_gating(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
 
-			for_each_pipe(pipe)
-				I915_WRITE(DSPCNTR(pipe),
-					   I915_READ(DSPCNTR(pipe)) |
-					   DISPPLANE_TRICKLE_FEED_DISABLE);
-		}
-	} else if (IS_G4X(dev)) {
-		uint32_t dspclk_gate;
-		I915_WRITE(RENCLK_GATE_D1, 0);
-		I915_WRITE(RENCLK_GATE_D2, VF_UNIT_CLOCK_GATE_DISABLE |
-		       GS_UNIT_CLOCK_GATE_DISABLE |
-		       CL_UNIT_CLOCK_GATE_DISABLE);
-		I915_WRITE(RAMCLK_GATE_D, 0);
-		dspclk_gate = VRHUNIT_CLOCK_GATE_DISABLE |
-			OVRUNIT_CLOCK_GATE_DISABLE |
-			OVCUNIT_CLOCK_GATE_DISABLE;
-		if (IS_GM45(dev))
-			dspclk_gate |= DSSUNIT_CLOCK_GATE_DISABLE;
-		I915_WRITE(DSPCLK_GATE_D, dspclk_gate);
-	} else if (IS_CRESTLINE(dev)) {
-		I915_WRITE(RENCLK_GATE_D1, I965_RCC_CLOCK_GATE_DISABLE);
-		I915_WRITE(RENCLK_GATE_D2, 0);
-		I915_WRITE(DSPCLK_GATE_D, 0);
-		I915_WRITE(RAMCLK_GATE_D, 0);
-		I915_WRITE16(DEUC, 0);
-	} else if (IS_BROADWATER(dev)) {
-		I915_WRITE(RENCLK_GATE_D1, I965_RCZ_CLOCK_GATE_DISABLE |
-		       I965_RCC_CLOCK_GATE_DISABLE |
-		       I965_RCPB_CLOCK_GATE_DISABLE |
-		       I965_ISC_CLOCK_GATE_DISABLE |
-		       I965_FBC_CLOCK_GATE_DISABLE);
-		I915_WRITE(RENCLK_GATE_D2, 0);
-	} else if (IS_GEN3(dev)) {
-		u32 dstate = I915_READ(D_STATE);
+	I915_WRITE(RENCLK_GATE_D1, I965_RCC_CLOCK_GATE_DISABLE);
+	I915_WRITE(RENCLK_GATE_D2, 0);
+	I915_WRITE(DSPCLK_GATE_D, 0);
+	I915_WRITE(RAMCLK_GATE_D, 0);
+	I915_WRITE16(DEUC, 0);
+}
 
-		dstate |= DSTATE_PLL_D3_OFF | DSTATE_GFX_CLOCK_GATING |
-			DSTATE_DOT_CLOCK_GATING;
-		I915_WRITE(D_STATE, dstate);
-	} else if (IS_I85X(dev) || IS_I865G(dev)) {
-		I915_WRITE(RENCLK_GATE_D1, SV_CLOCK_GATE_DISABLE);
-	} else if (IS_I830(dev)) {
-		I915_WRITE(DSPCLK_GATE_D, OVRUNIT_CLOCK_GATE_DISABLE);
-	}
+static void broadwater_init_clock_gating(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	I915_WRITE(RENCLK_GATE_D1, I965_RCZ_CLOCK_GATE_DISABLE |
+		   I965_RCC_CLOCK_GATE_DISABLE |
+		   I965_RCPB_CLOCK_GATE_DISABLE |
+		   I965_ISC_CLOCK_GATE_DISABLE |
+		   I965_FBC_CLOCK_GATE_DISABLE);
+	I915_WRITE(RENCLK_GATE_D2, 0);
+}
+
+static void gen3_init_clock_gating(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	u32 dstate = I915_READ(D_STATE);
+
+	dstate |= DSTATE_PLL_D3_OFF | DSTATE_GFX_CLOCK_GATING |
+		DSTATE_DOT_CLOCK_GATING;
+	I915_WRITE(D_STATE, dstate);
+}
+
+static void i85x_init_clock_gating(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	I915_WRITE(RENCLK_GATE_D1, SV_CLOCK_GATE_DISABLE);
+}
+
+static void i830_init_clock_gating(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	I915_WRITE(DSPCLK_GATE_D, OVRUNIT_CLOCK_GATE_DISABLE);
+}
+
+static void ibx_init_clock_gating(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	/*
+	 * On Ibex Peak and Cougar Point, we need to disable clock
+	 * gating for the panel power sequencer or it will fail to
+	 * start up when no ports are active.
+	 */
+	I915_WRITE(SOUTH_DSPCLK_GATE_D, PCH_DPLSUNIT_CLOCK_GATE_DISABLE);
+}
+
+static void cpt_init_clock_gating(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	/*
+	 * On Ibex Peak and Cougar Point, we need to disable clock
+	 * gating for the panel power sequencer or it will fail to
+	 * start up when no ports are active.
+	 */
+	I915_WRITE(SOUTH_DSPCLK_GATE_D, PCH_DPLSUNIT_CLOCK_GATE_DISABLE);
+	I915_WRITE(SOUTH_CHICKEN2, I915_READ(SOUTH_CHICKEN2) |
+		   DPLS_EDP_PPS_FIX_DIS);
 }
 
 static void ironlake_teardown_rc6(struct drm_device *dev)
@@ -7187,9 +7572,12 @@
 	if (!i915_enable_rc6)
 		return;
 
+	mutex_lock(&dev->struct_mutex);
 	ret = ironlake_setup_rc6(dev);
-	if (ret)
+	if (ret) {
+		mutex_unlock(&dev->struct_mutex);
 		return;
+	}
 
 	/*
 	 * GPU can automatically power down the render unit if given a page
@@ -7198,6 +7586,7 @@
 	ret = BEGIN_LP_RING(6);
 	if (ret) {
 		ironlake_teardown_rc6(dev);
+		mutex_unlock(&dev->struct_mutex);
 		return;
 	}
 
@@ -7213,10 +7602,33 @@
 	OUT_RING(MI_FLUSH);
 	ADVANCE_LP_RING();
 
+	/*
+	 * Wait for the command parser to advance past MI_SET_CONTEXT. The HW
+	 * does an implicit flush, combined with MI_FLUSH above, it should be
+	 * safe to assume that renderctx is valid
+	 */
+	ret = intel_wait_ring_idle(LP_RING(dev_priv));
+	if (ret) {
+		DRM_ERROR("failed to enable ironlake power power savings\n");
+		ironlake_teardown_rc6(dev);
+		mutex_unlock(&dev->struct_mutex);
+		return;
+	}
+
 	I915_WRITE(PWRCTXA, dev_priv->pwrctx->gtt_offset | PWRCTX_EN);
 	I915_WRITE(RSTDBYCTL, I915_READ(RSTDBYCTL) & ~RCX_SW_EXIT);
+	mutex_unlock(&dev->struct_mutex);
 }
 
+void intel_init_clock_gating(struct drm_device *dev)
+{
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	dev_priv->display.init_clock_gating(dev);
+
+	if (dev_priv->display.init_pch_clock_gating)
+		dev_priv->display.init_pch_clock_gating(dev);
+}
 
 /* Set up chip specific display functions */
 static void intel_init_display(struct drm_device *dev)
@@ -7224,10 +7636,13 @@
 	struct drm_i915_private *dev_priv = dev->dev_private;
 
 	/* We always want a DPMS function */
-	if (HAS_PCH_SPLIT(dev))
+	if (HAS_PCH_SPLIT(dev)) {
 		dev_priv->display.dpms = ironlake_crtc_dpms;
-	else
+		dev_priv->display.crtc_mode_set = ironlake_crtc_mode_set;
+	} else {
 		dev_priv->display.dpms = i9xx_crtc_dpms;
+		dev_priv->display.crtc_mode_set = i9xx_crtc_mode_set;
+	}
 
 	if (I915_HAS_FBC(dev)) {
 		if (HAS_PCH_SPLIT(dev)) {
@@ -7271,6 +7686,11 @@
 
 	/* For FIFO watermark updates */
 	if (HAS_PCH_SPLIT(dev)) {
+		if (HAS_PCH_IBX(dev))
+			dev_priv->display.init_pch_clock_gating = ibx_init_clock_gating;
+		else if (HAS_PCH_CPT(dev))
+			dev_priv->display.init_pch_clock_gating = cpt_init_clock_gating;
+
 		if (IS_GEN5(dev)) {
 			if (I915_READ(MLTR_ILK) & ILK_SRLT_MASK)
 				dev_priv->display.update_wm = ironlake_update_wm;
@@ -7279,6 +7699,8 @@
 					      "Disable CxSR\n");
 				dev_priv->display.update_wm = NULL;
 			}
+			dev_priv->display.fdi_link_train = ironlake_fdi_link_train;
+			dev_priv->display.init_clock_gating = ironlake_init_clock_gating;
 		} else if (IS_GEN6(dev)) {
 			if (SNB_READ_WM0_LATENCY()) {
 				dev_priv->display.update_wm = sandybridge_update_wm;
@@ -7287,6 +7709,20 @@
 					      "Disable CxSR\n");
 				dev_priv->display.update_wm = NULL;
 			}
+			dev_priv->display.fdi_link_train = gen6_fdi_link_train;
+			dev_priv->display.init_clock_gating = gen6_init_clock_gating;
+		} else if (IS_IVYBRIDGE(dev)) {
+			/* FIXME: detect B0+ stepping and use auto training */
+			dev_priv->display.fdi_link_train = ivb_manual_fdi_link_train;
+			if (SNB_READ_WM0_LATENCY()) {
+				dev_priv->display.update_wm = sandybridge_update_wm;
+			} else {
+				DRM_DEBUG_KMS("Failed to read display plane latency. "
+					      "Disable CxSR\n");
+				dev_priv->display.update_wm = NULL;
+			}
+			dev_priv->display.init_clock_gating = ivybridge_init_clock_gating;
+
 		} else
 			dev_priv->display.update_wm = NULL;
 	} else if (IS_PINEVIEW(dev)) {
@@ -7304,23 +7740,61 @@
 			dev_priv->display.update_wm = NULL;
 		} else
 			dev_priv->display.update_wm = pineview_update_wm;
-	} else if (IS_G4X(dev))
+		dev_priv->display.init_clock_gating = gen3_init_clock_gating;
+	} else if (IS_G4X(dev)) {
 		dev_priv->display.update_wm = g4x_update_wm;
-	else if (IS_GEN4(dev))
+		dev_priv->display.init_clock_gating = g4x_init_clock_gating;
+	} else if (IS_GEN4(dev)) {
 		dev_priv->display.update_wm = i965_update_wm;
-	else if (IS_GEN3(dev)) {
+		if (IS_CRESTLINE(dev))
+			dev_priv->display.init_clock_gating = crestline_init_clock_gating;
+		else if (IS_BROADWATER(dev))
+			dev_priv->display.init_clock_gating = broadwater_init_clock_gating;
+	} else if (IS_GEN3(dev)) {
 		dev_priv->display.update_wm = i9xx_update_wm;
 		dev_priv->display.get_fifo_size = i9xx_get_fifo_size;
+		dev_priv->display.init_clock_gating = gen3_init_clock_gating;
+	} else if (IS_I865G(dev)) {
+		dev_priv->display.update_wm = i830_update_wm;
+		dev_priv->display.init_clock_gating = i85x_init_clock_gating;
+		dev_priv->display.get_fifo_size = i830_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;
+		dev_priv->display.init_clock_gating = i85x_init_clock_gating;
 	} else {
 		dev_priv->display.update_wm = i830_update_wm;
+		dev_priv->display.init_clock_gating = i830_init_clock_gating;
 		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;
 	}
+
+	/* Default just returns -ENODEV to indicate unsupported */
+	dev_priv->display.queue_flip = intel_default_queue_flip;
+
+	switch (INTEL_INFO(dev)->gen) {
+	case 2:
+		dev_priv->display.queue_flip = intel_gen2_queue_flip;
+		break;
+
+	case 3:
+		dev_priv->display.queue_flip = intel_gen3_queue_flip;
+		break;
+
+	case 4:
+	case 5:
+		dev_priv->display.queue_flip = intel_gen4_queue_flip;
+		break;
+
+	case 6:
+		dev_priv->display.queue_flip = intel_gen6_queue_flip;
+		break;
+	case 7:
+		dev_priv->display.queue_flip = intel_gen7_queue_flip;
+		break;
+	}
 }
 
 /*
@@ -7441,12 +7915,11 @@
 		intel_crtc_init(dev, i);
 	}
 
-	intel_setup_outputs(dev);
-
-	intel_enable_clock_gating(dev);
-
 	/* Just disable it once at startup */
 	i915_disable_vga(dev);
+	intel_setup_outputs(dev);
+
+	intel_init_clock_gating(dev);
 
 	if (IS_IRONLAKE_M(dev)) {
 		ironlake_enable_drps(dev);
@@ -7456,12 +7929,15 @@
 	if (IS_GEN6(dev))
 		gen6_enable_rps(dev_priv);
 
-	if (IS_IRONLAKE_M(dev))
-		ironlake_enable_rc6(dev);
-
 	INIT_WORK(&dev_priv->idle_work, intel_idle_update);
 	setup_timer(&dev_priv->idle_timer, intel_gpu_idle_timer,
 		    (unsigned long)dev);
+}
+
+void intel_modeset_gem_init(struct drm_device *dev)
+{
+	if (IS_IRONLAKE_M(dev))
+		ironlake_enable_rc6(dev);
 
 	intel_setup_overlay(dev);
 }
diff -druN linux-2.6.39-libre/drivers/gpu/drm/i915/intel_dp.c linux-3.0-rc7-libre/drivers/gpu/drm/i915/intel_dp.c
--- linux-2.6.39-libre/drivers/gpu/drm/i915/intel_dp.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/gpu/drm/i915/intel_dp.c	2011-07-11 19:51:52.000000000 -0400
@@ -59,8 +59,6 @@
 	bool is_pch_edp;
 	uint8_t	train_set[4];
 	uint8_t link_status[DP_LINK_STATUS_SIZE];
-
-	struct drm_property *force_audio_property;
 };
 
 /**
@@ -1702,7 +1700,7 @@
 	if (ret)
 		return ret;
 
-	if (property == intel_dp->force_audio_property) {
+	if (property == dev_priv->force_audio_property) {
 		int i = val;
 		bool has_audio;
 
@@ -1841,16 +1839,7 @@
 static void
 intel_dp_add_properties(struct intel_dp *intel_dp, struct drm_connector *connector)
 {
-	struct drm_device *dev = connector->dev;
-
-	intel_dp->force_audio_property =
-		drm_property_create(dev, DRM_MODE_PROP_RANGE, "force_audio", 2);
-	if (intel_dp->force_audio_property) {
-		intel_dp->force_audio_property->values[0] = -1;
-		intel_dp->force_audio_property->values[1] = 1;
-		drm_connector_attach_property(connector, intel_dp->force_audio_property, 0);
-	}
-
+	intel_attach_force_audio_property(connector);
 	intel_attach_broadcast_rgb_property(connector);
 }
 
diff -druN linux-2.6.39-libre/drivers/gpu/drm/i915/intel_drv.h linux-3.0-rc7-libre/drivers/gpu/drm/i915/intel_drv.h
--- linux-2.6.39-libre/drivers/gpu/drm/i915/intel_drv.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/gpu/drm/i915/intel_drv.h	2011-07-11 19:51:52.000000000 -0400
@@ -140,7 +140,6 @@
 struct intel_encoder {
 	struct drm_encoder base;
 	int type;
-	bool load_detect_temp;
 	bool needs_tv_clock;
 	void (*hot_plug)(struct intel_encoder *);
 	int crtc_mask;
@@ -237,6 +236,7 @@
 int intel_ddc_get_modes(struct drm_connector *c, struct i2c_adapter *adapter);
 extern bool intel_ddc_probe(struct intel_encoder *intel_encoder, int ddc_bus);
 
+extern void intel_attach_force_audio_property(struct drm_connector *connector);
 extern void intel_attach_broadcast_rgb_property(struct drm_connector *connector);
 
 extern void intel_crt_init(struct drm_device *dev);
@@ -291,13 +291,19 @@
 				struct drm_file *file_priv);
 extern void intel_wait_for_vblank(struct drm_device *dev, int pipe);
 extern void intel_wait_for_pipe_off(struct drm_device *dev, int pipe);
-extern struct drm_crtc *intel_get_load_detect_pipe(struct intel_encoder *intel_encoder,
-						   struct drm_connector *connector,
-						   struct drm_display_mode *mode,
-						   int *dpms_mode);
+
+struct intel_load_detect_pipe {
+	struct drm_framebuffer *release_fb;
+	bool load_detect_temp;
+	int dpms_mode;
+};
+extern bool intel_get_load_detect_pipe(struct intel_encoder *intel_encoder,
+				       struct drm_connector *connector,
+				       struct drm_display_mode *mode,
+				       struct intel_load_detect_pipe *old);
 extern void intel_release_load_detect_pipe(struct intel_encoder *intel_encoder,
 					   struct drm_connector *connector,
-					   int dpms_mode);
+					   struct intel_load_detect_pipe *old);
 
 extern struct drm_connector* intel_sdvo_find(struct drm_device *dev, int sdvoB);
 extern int intel_sdvo_supports_hotplug(struct drm_connector *connector);
@@ -339,4 +345,6 @@
 
 extern void intel_fb_output_poll_changed(struct drm_device *dev);
 extern void intel_fb_restore_mode(struct drm_device *dev);
+
+extern void intel_init_clock_gating(struct drm_device *dev);
 #endif /* __INTEL_DRV_H__ */
diff -druN linux-2.6.39-libre/drivers/gpu/drm/i915/intel_hdmi.c linux-3.0-rc7-libre/drivers/gpu/drm/i915/intel_hdmi.c
--- linux-2.6.39-libre/drivers/gpu/drm/i915/intel_hdmi.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/gpu/drm/i915/intel_hdmi.c	2011-07-11 19:51:52.000000000 -0400
@@ -45,7 +45,6 @@
 	bool has_hdmi_sink;
 	bool has_audio;
 	int force_audio;
-	struct drm_property *force_audio_property;
 };
 
 static struct intel_hdmi *enc_to_intel_hdmi(struct drm_encoder *encoder)
@@ -194,7 +193,7 @@
 	if (mode->clock > 165000)
 		return MODE_CLOCK_HIGH;
 	if (mode->clock < 20000)
-		return MODE_CLOCK_HIGH;
+		return MODE_CLOCK_LOW;
 
 	if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
 		return MODE_NO_DBLESCAN;
@@ -287,7 +286,7 @@
 	if (ret)
 		return ret;
 
-	if (property == intel_hdmi->force_audio_property) {
+	if (property == dev_priv->force_audio_property) {
 		int i = val;
 		bool has_audio;
 
@@ -365,16 +364,7 @@
 static void
 intel_hdmi_add_properties(struct intel_hdmi *intel_hdmi, struct drm_connector *connector)
 {
-	struct drm_device *dev = connector->dev;
-
-	intel_hdmi->force_audio_property =
-		drm_property_create(dev, DRM_MODE_PROP_RANGE, "force_audio", 2);
-	if (intel_hdmi->force_audio_property) {
-		intel_hdmi->force_audio_property->values[0] = -1;
-		intel_hdmi->force_audio_property->values[1] = 1;
-		drm_connector_attach_property(connector, intel_hdmi->force_audio_property, 0);
-	}
-
+	intel_attach_force_audio_property(connector);
 	intel_attach_broadcast_rgb_property(connector);
 }
 
diff -druN linux-2.6.39-libre/drivers/gpu/drm/i915/intel_i2c.c linux-3.0-rc7-libre/drivers/gpu/drm/i915/intel_i2c.c
--- linux-2.6.39-libre/drivers/gpu/drm/i915/intel_i2c.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/gpu/drm/i915/intel_i2c.c	2011-07-11 19:51:52.000000000 -0400
@@ -401,8 +401,7 @@
 		bus->reg0 = i | GMBUS_RATE_100KHZ;
 
 		/* XXX force bit banging until GMBUS is fully debugged */
-		if (IS_GEN2(dev))
-			bus->force_bit = intel_gpio_create(dev_priv, i);
+		bus->force_bit = intel_gpio_create(dev_priv, i);
 	}
 
 	intel_i2c_reset(dev_priv->dev);
diff -druN linux-2.6.39-libre/drivers/gpu/drm/i915/intel_lvds.c linux-3.0-rc7-libre/drivers/gpu/drm/i915/intel_lvds.c
--- linux-2.6.39-libre/drivers/gpu/drm/i915/intel_lvds.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/gpu/drm/i915/intel_lvds.c	2011-07-11 19:51:52.000000000 -0400
@@ -727,6 +727,14 @@
 			DMI_MATCH(DMI_PRODUCT_NAME, "U800"),
 		},
 	},
+	{
+		.callback = intel_no_lvds_dmi_callback,
+		.ident = "Asus EeeBox PC EB1007",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK Computer INC."),
+			DMI_MATCH(DMI_PRODUCT_NAME, "EB1007"),
+		},
+	},
 
 	{ }	/* terminating entry */
 };
diff -druN linux-2.6.39-libre/drivers/gpu/drm/i915/intel_modes.c linux-3.0-rc7-libre/drivers/gpu/drm/i915/intel_modes.c
--- linux-2.6.39-libre/drivers/gpu/drm/i915/intel_modes.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/gpu/drm/i915/intel_modes.c	2011-07-11 19:51:52.000000000 -0400
@@ -81,6 +81,36 @@
 	return ret;
 }
 
+static const char *force_audio_names[] = {
+	"off",
+	"auto",
+	"on",
+};
+
+void
+intel_attach_force_audio_property(struct drm_connector *connector)
+{
+	struct drm_device *dev = connector->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct drm_property *prop;
+	int i;
+
+	prop = dev_priv->force_audio_property;
+	if (prop == NULL) {
+		prop = drm_property_create(dev, DRM_MODE_PROP_ENUM,
+					   "audio",
+					   ARRAY_SIZE(force_audio_names));
+		if (prop == NULL)
+			return;
+
+		for (i = 0; i < ARRAY_SIZE(force_audio_names); i++)
+			drm_property_add_enum(prop, i, i-1, force_audio_names[i]);
+
+		dev_priv->force_audio_property = prop;
+	}
+	drm_connector_attach_property(connector, prop, 0);
+}
+
 static const char *broadcast_rgb_names[] = {
 	"Full",
 	"Limited 16:235",
diff -druN linux-2.6.39-libre/drivers/gpu/drm/i915/intel_overlay.c linux-3.0-rc7-libre/drivers/gpu/drm/i915/intel_overlay.c
--- linux-2.6.39-libre/drivers/gpu/drm/i915/intel_overlay.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/gpu/drm/i915/intel_overlay.c	2011-07-11 19:51:52.000000000 -0400
@@ -1409,6 +1409,11 @@
 	overlay = kzalloc(sizeof(struct intel_overlay), GFP_KERNEL);
 	if (!overlay)
 		return;
+
+	mutex_lock(&dev->struct_mutex);
+	if (WARN_ON(dev_priv->overlay))
+		goto out_free;
+
 	overlay->dev = dev;
 
 	reg_bo = i915_gem_alloc_object(dev, PAGE_SIZE);
@@ -1448,7 +1453,7 @@
 
 	regs = intel_overlay_map_regs(overlay);
 	if (!regs)
-		goto out_free_bo;
+		goto out_unpin_bo;
 
 	memset(regs, 0, sizeof(struct overlay_registers));
 	update_polyphase_filter(regs);
@@ -1457,14 +1462,17 @@
 	intel_overlay_unmap_regs(overlay, regs);
 
 	dev_priv->overlay = overlay;
+	mutex_unlock(&dev->struct_mutex);
 	DRM_INFO("initialized overlay support\n");
 	return;
 
 out_unpin_bo:
-	i915_gem_object_unpin(reg_bo);
+	if (!OVERLAY_NEEDS_PHYSICAL(dev))
+		i915_gem_object_unpin(reg_bo);
 out_free_bo:
 	drm_gem_object_unreference(&reg_bo->base);
 out_free:
+	mutex_unlock(&dev->struct_mutex);
 	kfree(overlay);
 	return;
 }
diff -druN linux-2.6.39-libre/drivers/gpu/drm/i915/intel_ringbuffer.c linux-3.0-rc7-libre/drivers/gpu/drm/i915/intel_ringbuffer.c
--- linux-2.6.39-libre/drivers/gpu/drm/i915/intel_ringbuffer.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/gpu/drm/i915/intel_ringbuffer.c	2011-07-11 19:51:52.000000000 -0400
@@ -236,7 +236,7 @@
 		ret = -ENOMEM;
 		goto err;
 	}
-	obj->agp_type = AGP_USER_CACHED_MEMORY;
+	obj->cache_level = I915_CACHE_LLC;
 
 	ret = i915_gem_object_pin(obj, 4096, true);
 	if (ret)
@@ -286,7 +286,7 @@
 
 	if (INTEL_INFO(dev)->gen > 3) {
 		int mode = VS_TIMER_DISPATCH << 16 | VS_TIMER_DISPATCH;
-		if (IS_GEN6(dev))
+		if (IS_GEN6(dev) || IS_GEN7(dev))
 			mode |= MI_FLUSH_ENABLE << 16 | MI_FLUSH_ENABLE;
 		I915_WRITE(MI_MODE, mode);
 	}
@@ -551,10 +551,31 @@
 
 void intel_ring_setup_status_page(struct intel_ring_buffer *ring)
 {
+	struct drm_device *dev = ring->dev;
 	drm_i915_private_t *dev_priv = ring->dev->dev_private;
-	u32 mmio = IS_GEN6(ring->dev) ?
-		RING_HWS_PGA_GEN6(ring->mmio_base) :
-		RING_HWS_PGA(ring->mmio_base);
+	u32 mmio = 0;
+
+	/* The ring status page addresses are no longer next to the rest of
+	 * the ring registers as of gen7.
+	 */
+	if (IS_GEN7(dev)) {
+		switch (ring->id) {
+		case RING_RENDER:
+			mmio = RENDER_HWS_PGA_GEN7;
+			break;
+		case RING_BLT:
+			mmio = BLT_HWS_PGA_GEN7;
+			break;
+		case RING_BSD:
+			mmio = BSD_HWS_PGA_GEN7;
+			break;
+		}
+	} else if (IS_GEN6(ring->dev)) {
+		mmio = RING_HWS_PGA_GEN6(ring->mmio_base);
+	} else {
+		mmio = RING_HWS_PGA(ring->mmio_base);
+	}
+
 	I915_WRITE(mmio, (u32)ring->status_page.gfx_addr);
 	POSTING_READ(mmio);
 }
@@ -600,7 +621,7 @@
 }
 
 static bool
-ring_get_irq(struct intel_ring_buffer *ring, u32 flag)
+gen6_ring_get_irq(struct intel_ring_buffer *ring, u32 gflag, u32 rflag)
 {
 	struct drm_device *dev = ring->dev;
 	drm_i915_private_t *dev_priv = dev->dev_private;
@@ -609,71 +630,67 @@
 	       return false;
 
 	spin_lock(&ring->irq_lock);
-	if (ring->irq_refcount++ == 0)
-		ironlake_enable_irq(dev_priv, flag);
+	if (ring->irq_refcount++ == 0) {
+		ring->irq_mask &= ~rflag;
+		I915_WRITE_IMR(ring, ring->irq_mask);
+		ironlake_enable_irq(dev_priv, gflag);
+	}
 	spin_unlock(&ring->irq_lock);
 
 	return true;
 }
 
 static void
-ring_put_irq(struct intel_ring_buffer *ring, u32 flag)
+gen6_ring_put_irq(struct intel_ring_buffer *ring, u32 gflag, u32 rflag)
 {
 	struct drm_device *dev = ring->dev;
 	drm_i915_private_t *dev_priv = dev->dev_private;
 
 	spin_lock(&ring->irq_lock);
-	if (--ring->irq_refcount == 0)
-		ironlake_disable_irq(dev_priv, flag);
+	if (--ring->irq_refcount == 0) {
+		ring->irq_mask |= rflag;
+		I915_WRITE_IMR(ring, ring->irq_mask);
+		ironlake_disable_irq(dev_priv, gflag);
+	}
 	spin_unlock(&ring->irq_lock);
 }
 
 static bool
-gen6_ring_get_irq(struct intel_ring_buffer *ring, u32 gflag, u32 rflag)
+bsd_ring_get_irq(struct intel_ring_buffer *ring)
 {
 	struct drm_device *dev = ring->dev;
 	drm_i915_private_t *dev_priv = dev->dev_private;
 
 	if (!dev->irq_enabled)
-	       return false;
+		return false;
 
 	spin_lock(&ring->irq_lock);
 	if (ring->irq_refcount++ == 0) {
-		ring->irq_mask &= ~rflag;
-		I915_WRITE_IMR(ring, ring->irq_mask);
-		ironlake_enable_irq(dev_priv, gflag);
+		if (IS_G4X(dev))
+			i915_enable_irq(dev_priv, I915_BSD_USER_INTERRUPT);
+		else
+			ironlake_enable_irq(dev_priv, GT_BSD_USER_INTERRUPT);
 	}
 	spin_unlock(&ring->irq_lock);
 
 	return true;
 }
-
 static void
-gen6_ring_put_irq(struct intel_ring_buffer *ring, u32 gflag, u32 rflag)
+bsd_ring_put_irq(struct intel_ring_buffer *ring)
 {
 	struct drm_device *dev = ring->dev;
 	drm_i915_private_t *dev_priv = dev->dev_private;
 
 	spin_lock(&ring->irq_lock);
 	if (--ring->irq_refcount == 0) {
-		ring->irq_mask |= rflag;
-		I915_WRITE_IMR(ring, ring->irq_mask);
-		ironlake_disable_irq(dev_priv, gflag);
+		if (IS_G4X(dev))
+			i915_disable_irq(dev_priv, I915_BSD_USER_INTERRUPT);
+		else
+			ironlake_disable_irq(dev_priv, GT_BSD_USER_INTERRUPT);
 	}
 	spin_unlock(&ring->irq_lock);
 }
 
-static bool
-bsd_ring_get_irq(struct intel_ring_buffer *ring)
-{
-	return ring_get_irq(ring, GT_BSD_USER_INTERRUPT);
-}
-static void
-bsd_ring_put_irq(struct intel_ring_buffer *ring)
-{
-	ring_put_irq(ring, GT_BSD_USER_INTERRUPT);
-}
-
 static int
 ring_dispatch_execbuffer(struct intel_ring_buffer *ring, u32 offset, u32 length)
 {
@@ -759,7 +776,7 @@
 		ret = -ENOMEM;
 		goto err;
 	}
-	obj->agp_type = AGP_USER_CACHED_MEMORY;
+	obj->cache_level = I915_CACHE_LLC;
 
 	ret = i915_gem_object_pin(obj, 4096, true);
 	if (ret != 0) {
@@ -800,6 +817,7 @@
 	INIT_LIST_HEAD(&ring->request_list);
 	INIT_LIST_HEAD(&ring->gpu_write_list);
 
+	init_waitqueue_head(&ring->irq_queue);
 	spin_lock_init(&ring->irq_lock);
 	ring->irq_mask = ~0;
 
@@ -872,7 +890,7 @@
 
 	/* Disable the ring buffer. The ring must be idle at this point */
 	dev_priv = ring->dev->dev_private;
-	ret = intel_wait_ring_buffer(ring, ring->size - 8);
+	ret = intel_wait_ring_idle(ring);
 	if (ret)
 		DRM_ERROR("failed to quiesce %s whilst cleaning up: %d\n",
 			  ring->name, ret);
@@ -1333,7 +1351,7 @@
 	drm_i915_private_t *dev_priv = dev->dev_private;
 	struct intel_ring_buffer *ring = &dev_priv->ring[VCS];
 
-	if (IS_GEN6(dev))
+	if (IS_GEN6(dev) || IS_GEN7(dev))
 		*ring = gen6_bsd_ring;
 	else
 		*ring = bsd_ring;
diff -druN linux-2.6.39-libre/drivers/gpu/drm/i915/intel_ringbuffer.h linux-3.0-rc7-libre/drivers/gpu/drm/i915/intel_ringbuffer.h
--- linux-2.6.39-libre/drivers/gpu/drm/i915/intel_ringbuffer.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/gpu/drm/i915/intel_ringbuffer.h	2011-07-11 19:51:52.000000000 -0400
@@ -14,27 +14,24 @@
 	struct		drm_i915_gem_object *obj;
 };
 
-#define I915_RING_READ(reg) i915_gt_read(dev_priv, reg)
-#define I915_RING_WRITE(reg, val) i915_gt_write(dev_priv, reg, val)
-
-#define I915_READ_TAIL(ring) I915_RING_READ(RING_TAIL((ring)->mmio_base))
-#define I915_WRITE_TAIL(ring, val) I915_RING_WRITE(RING_TAIL((ring)->mmio_base), val)
+#define I915_READ_TAIL(ring) I915_READ(RING_TAIL((ring)->mmio_base))
+#define I915_WRITE_TAIL(ring, val) I915_WRITE(RING_TAIL((ring)->mmio_base), val)
 
-#define I915_READ_START(ring) I915_RING_READ(RING_START((ring)->mmio_base))
-#define I915_WRITE_START(ring, val) I915_RING_WRITE(RING_START((ring)->mmio_base), val)
+#define I915_READ_START(ring) I915_READ(RING_START((ring)->mmio_base))
+#define I915_WRITE_START(ring, val) I915_WRITE(RING_START((ring)->mmio_base), val)
 
-#define I915_READ_HEAD(ring)  I915_RING_READ(RING_HEAD((ring)->mmio_base))
-#define I915_WRITE_HEAD(ring, val) I915_RING_WRITE(RING_HEAD((ring)->mmio_base), val)
+#define I915_READ_HEAD(ring)  I915_READ(RING_HEAD((ring)->mmio_base))
+#define I915_WRITE_HEAD(ring, val) I915_WRITE(RING_HEAD((ring)->mmio_base), val)
 
-#define I915_READ_CTL(ring) I915_RING_READ(RING_CTL((ring)->mmio_base))
-#define I915_WRITE_CTL(ring, val) I915_RING_WRITE(RING_CTL((ring)->mmio_base), val)
+#define I915_READ_CTL(ring) I915_READ(RING_CTL((ring)->mmio_base))
+#define I915_WRITE_CTL(ring, val) I915_WRITE(RING_CTL((ring)->mmio_base), val)
 
-#define I915_READ_IMR(ring) I915_RING_READ(RING_IMR((ring)->mmio_base))
-#define I915_WRITE_IMR(ring, val) I915_RING_WRITE(RING_IMR((ring)->mmio_base), val)
+#define I915_READ_IMR(ring) I915_READ(RING_IMR((ring)->mmio_base))
+#define I915_WRITE_IMR(ring, val) I915_WRITE(RING_IMR((ring)->mmio_base), val)
 
-#define I915_READ_NOPID(ring) I915_RING_READ(RING_NOPID((ring)->mmio_base))
-#define I915_READ_SYNC_0(ring) I915_RING_READ(RING_SYNC_0((ring)->mmio_base))
-#define I915_READ_SYNC_1(ring) I915_RING_READ(RING_SYNC_1((ring)->mmio_base))
+#define I915_READ_NOPID(ring) I915_READ(RING_NOPID((ring)->mmio_base))
+#define I915_READ_SYNC_0(ring) I915_READ(RING_SYNC_0((ring)->mmio_base))
+#define I915_READ_SYNC_1(ring) I915_READ(RING_SYNC_1((ring)->mmio_base))
 
 struct  intel_ring_buffer {
 	const char	*name;
@@ -164,7 +161,13 @@
 #define I915_BREADCRUMB_INDEX		0x21
 
 void intel_cleanup_ring_buffer(struct intel_ring_buffer *ring);
+
 int __must_check intel_wait_ring_buffer(struct intel_ring_buffer *ring, int n);
+static inline int intel_wait_ring_idle(struct intel_ring_buffer *ring)
+{
+	return intel_wait_ring_buffer(ring, ring->space - 8);
+}
+
 int __must_check intel_ring_begin(struct intel_ring_buffer *ring, int n);
 
 static inline void intel_ring_emit(struct intel_ring_buffer *ring,
diff -druN linux-2.6.39-libre/drivers/gpu/drm/i915/intel_sdvo.c linux-3.0-rc7-libre/drivers/gpu/drm/i915/intel_sdvo.c
--- linux-2.6.39-libre/drivers/gpu/drm/i915/intel_sdvo.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/gpu/drm/i915/intel_sdvo.c	2011-07-11 19:51:52.000000000 -0400
@@ -148,8 +148,6 @@
 	int   format_supported_num;
 	struct drm_property *tv_format;
 
-	struct drm_property *force_audio_property;
-
 	/* add the property for the SDVO-TV */
 	struct drm_property *left;
 	struct drm_property *right;
@@ -1712,7 +1710,7 @@
 	if (ret)
 		return ret;
 
-	if (property == intel_sdvo_connector->force_audio_property) {
+	if (property == dev_priv->force_audio_property) {
 		int i = val;
 		bool has_audio;
 
@@ -2037,15 +2035,7 @@
 {
 	struct drm_device *dev = connector->base.base.dev;
 
-	connector->force_audio_property =
-		drm_property_create(dev, DRM_MODE_PROP_RANGE, "force_audio", 2);
-	if (connector->force_audio_property) {
-		connector->force_audio_property->values[0] = -1;
-		connector->force_audio_property->values[1] = 1;
-		drm_connector_attach_property(&connector->base.base,
-					      connector->force_audio_property, 0);
-	}
-
+	intel_attach_force_audio_property(&connector->base.base);
 	if (INTEL_INFO(dev)->gen >= 4 && IS_MOBILE(dev))
 		intel_attach_broadcast_rgb_property(&connector->base.base);
 }
@@ -2544,21 +2534,19 @@
 	if (!intel_sdvo)
 		return false;
 
+	intel_sdvo->sdvo_reg = sdvo_reg;
+	intel_sdvo->slave_addr = intel_sdvo_get_slave_addr(dev, sdvo_reg) >> 1;
+	intel_sdvo_select_i2c_bus(dev_priv, intel_sdvo, sdvo_reg);
 	if (!intel_sdvo_init_ddc_proxy(intel_sdvo, dev)) {
 		kfree(intel_sdvo);
 		return false;
 	}
 
-	intel_sdvo->sdvo_reg = sdvo_reg;
-
+	/* encoder type will be decided later */
 	intel_encoder = &intel_sdvo->base;
 	intel_encoder->type = INTEL_OUTPUT_SDVO;
-	/* encoder type will be decided later */
 	drm_encoder_init(dev, &intel_encoder->base, &intel_sdvo_enc_funcs, 0);
 
-	intel_sdvo->slave_addr = intel_sdvo_get_slave_addr(dev, sdvo_reg) >> 1;
-	intel_sdvo_select_i2c_bus(dev_priv, intel_sdvo, sdvo_reg);
-
 	/* Read the regs to test if we can talk to the device */
 	for (i = 0; i < 0x40; i++) {
 		u8 byte;
diff -druN linux-2.6.39-libre/drivers/gpu/drm/i915/intel_tv.c linux-3.0-rc7-libre/drivers/gpu/drm/i915/intel_tv.c
--- linux-2.6.39-libre/drivers/gpu/drm/i915/intel_tv.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/gpu/drm/i915/intel_tv.c	2011-07-11 19:51:52.000000000 -0400
@@ -1361,15 +1361,14 @@
 	if (intel_tv->base.base.crtc && intel_tv->base.base.crtc->enabled) {
 		type = intel_tv_detect_type(intel_tv, connector);
 	} else if (force) {
-		struct drm_crtc *crtc;
-		int dpms_mode;
+		struct intel_load_detect_pipe tmp;
 
-		crtc = intel_get_load_detect_pipe(&intel_tv->base, connector,
-						  &mode, &dpms_mode);
-		if (crtc) {
+		if (intel_get_load_detect_pipe(&intel_tv->base, connector,
+					       &mode, &tmp)) {
 			type = intel_tv_detect_type(intel_tv, connector);
-			intel_release_load_detect_pipe(&intel_tv->base, connector,
-						       dpms_mode);
+			intel_release_load_detect_pipe(&intel_tv->base,
+						       connector,
+						       &tmp);
 		} else
 			return connector_status_unknown;
 	} else
diff -druN linux-2.6.39-libre/drivers/gpu/drm/mga/mga_drv.h linux-3.0-rc7-libre/drivers/gpu/drm/mga/mga_drv.h
--- linux-2.6.39-libre/drivers/gpu/drm/mga/mga_drv.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/gpu/drm/mga/mga_drv.h	2011-07-11 19:51:52.000000000 -0400
@@ -195,29 +195,10 @@
 
 #define mga_flush_write_combine()	DRM_WRITEMEMORYBARRIER()
 
-#if defined(__linux__) && defined(__alpha__)
-#define MGA_BASE(reg)		((unsigned long)(dev_priv->mmio->handle))
-#define MGA_ADDR(reg)		(MGA_BASE(reg) + reg)
-
-#define MGA_DEREF(reg)		(*(volatile u32 *)MGA_ADDR(reg))
-#define MGA_DEREF8(reg)		(*(volatile u8 *)MGA_ADDR(reg))
-
-#define MGA_READ(reg)		(_MGA_READ((u32 *)MGA_ADDR(reg)))
-#define MGA_READ8(reg)		(_MGA_READ((u8 *)MGA_ADDR(reg)))
-#define MGA_WRITE(reg, val)	do { DRM_WRITEMEMORYBARRIER(); MGA_DEREF(reg) = val; } while (0)
-#define MGA_WRITE8(reg, val)	do { DRM_WRITEMEMORYBARRIER(); MGA_DEREF8(reg) = val; } while (0)
-
-static inline u32 _MGA_READ(u32 *addr)
-{
-	DRM_MEMORYBARRIER();
-	return *(volatile u32 *)addr;
-}
-#else
 #define MGA_READ8(reg)		DRM_READ8(dev_priv->mmio, (reg))
 #define MGA_READ(reg)		DRM_READ32(dev_priv->mmio, (reg))
 #define MGA_WRITE8(reg, val)	DRM_WRITE8(dev_priv->mmio, (reg), (val))
 #define MGA_WRITE(reg, val)	DRM_WRITE32(dev_priv->mmio, (reg), (val))
-#endif
 
 #define DWGREG0		0x1c00
 #define DWGREG0_END	0x1dff
diff -druN linux-2.6.39-libre/drivers/gpu/drm/nouveau/Kconfig linux-3.0-rc7-libre/drivers/gpu/drm/nouveau/Kconfig
--- linux-2.6.39-libre/drivers/gpu/drm/nouveau/Kconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/gpu/drm/nouveau/Kconfig	2011-07-11 19:51:52.000000000 -0400
@@ -11,6 +11,8 @@
 	select FRAMEBUFFER_CONSOLE if !EXPERT
 	select FB_BACKLIGHT if DRM_NOUVEAU_BACKLIGHT
 	select ACPI_VIDEO if ACPI && X86 && BACKLIGHT_CLASS_DEVICE && VIDEO_OUTPUT_CONTROL && INPUT
+	select ACPI_WMI if ACPI
+	select MXM_WMI if ACPI
 	help
 	  Choose this option for open-source nVidia support.
 
diff -druN linux-2.6.39-libre/drivers/gpu/drm/nouveau/Makefile linux-3.0-rc7-libre/drivers/gpu/drm/nouveau/Makefile
--- linux-2.6.39-libre/drivers/gpu/drm/nouveau/Makefile	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/gpu/drm/nouveau/Makefile	2011-07-11 19:51:52.000000000 -0400
@@ -20,6 +20,8 @@
              nv40_graph.o nv50_graph.o nvc0_graph.o \
              nv40_grctx.o nv50_grctx.o nvc0_grctx.o \
              nv84_crypt.o \
+             nva3_copy.o nvc0_copy.o \
+             nv40_mpeg.o nv50_mpeg.o \
              nv04_instmem.o nv50_instmem.o nvc0_instmem.o \
              nv50_evo.o nv50_crtc.o nv50_dac.o nv50_sor.o \
              nv50_cursor.o nv50_display.o \
diff -druN linux-2.6.39-libre/drivers/gpu/drm/nouveau/nouveau_acpi.c linux-3.0-rc7-libre/drivers/gpu/drm/nouveau/nouveau_acpi.c
--- linux-2.6.39-libre/drivers/gpu/drm/nouveau/nouveau_acpi.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/gpu/drm/nouveau/nouveau_acpi.c	2011-07-11 19:51:52.000000000 -0400
@@ -4,6 +4,8 @@
 #include <acpi/acpi_drivers.h>
 #include <acpi/acpi_bus.h>
 #include <acpi/video.h>
+#include <acpi/acpi.h>
+#include <linux/mxm-wmi.h>
 
 #include "drmP.h"
 #include "drm.h"
@@ -35,15 +37,71 @@
 
 static struct nouveau_dsm_priv {
 	bool dsm_detected;
+	bool optimus_detected;
 	acpi_handle dhandle;
 	acpi_handle rom_handle;
 } nouveau_dsm_priv;
 
+#define NOUVEAU_DSM_HAS_MUX 0x1
+#define NOUVEAU_DSM_HAS_OPT 0x2
+
 static const char nouveau_dsm_muid[] = {
 	0xA0, 0xA0, 0x95, 0x9D, 0x60, 0x00, 0x48, 0x4D,
 	0xB3, 0x4D, 0x7E, 0x5F, 0xEA, 0x12, 0x9F, 0xD4,
 };
 
+static const char nouveau_op_dsm_muid[] = {
+	0xF8, 0xD8, 0x86, 0xA4, 0xDA, 0x0B, 0x1B, 0x47,
+	0xA7, 0x2B, 0x60, 0x42, 0xA6, 0xB5, 0xBE, 0xE0,
+};
+
+static int nouveau_optimus_dsm(acpi_handle handle, int func, int arg, uint32_t *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;
+
+	input.count = 4;
+	input.pointer = params;
+	params[0].type = ACPI_TYPE_BUFFER;
+	params[0].buffer.length = sizeof(nouveau_op_dsm_muid);
+	params[0].buffer.pointer = (char *)nouveau_op_dsm_muid;
+	params[1].type = ACPI_TYPE_INTEGER;
+	params[1].integer.value = 0x00000100;
+	params[2].type = ACPI_TYPE_INTEGER;
+	params[2].integer.value = func;
+	params[3].type = ACPI_TYPE_BUFFER;
+	params[3].buffer.length = 0;
+
+	err = acpi_evaluate_object(handle, "_DSM", &input, &output);
+	if (err) {
+		printk(KERN_INFO "failed to evaluate _DSM: %d\n", err);
+		return err;
+	}
+
+	obj = (union acpi_object *)output.pointer;
+
+	if (obj->type == ACPI_TYPE_INTEGER)
+		if (obj->integer.value == 0x80000002) {
+			return -ENODEV;
+		}
+
+	if (obj->type == ACPI_TYPE_BUFFER) {
+		if (obj->buffer.length == 4 && result) {
+			*result = 0;
+			*result |= obj->buffer.pointer[0];
+			*result |= (obj->buffer.pointer[1] << 8);
+			*result |= (obj->buffer.pointer[2] << 16);
+			*result |= (obj->buffer.pointer[3] << 24);
+		}
+	}
+
+	kfree(output.pointer);
+	return 0;
+}
+
 static int nouveau_dsm(acpi_handle handle, int func, int arg, uint32_t *result)
 {
 	struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL };
@@ -92,6 +150,8 @@
 
 static int nouveau_dsm_switch_mux(acpi_handle handle, int mux_id)
 {
+	mxm_wmi_call_mxmx(mux_id == NOUVEAU_DSM_LED_STAMINA ? MXM_MXDS_ADAPTER_IGD : MXM_MXDS_ADAPTER_0);
+	mxm_wmi_call_mxds(mux_id == NOUVEAU_DSM_LED_STAMINA ? MXM_MXDS_ADAPTER_IGD : MXM_MXDS_ADAPTER_0);
 	return nouveau_dsm(handle, NOUVEAU_DSM_LED, mux_id, NULL);
 }
 
@@ -148,11 +208,11 @@
 	.get_client_id = nouveau_dsm_get_client_id,
 };
 
-static bool nouveau_dsm_pci_probe(struct pci_dev *pdev)
+static int nouveau_dsm_pci_probe(struct pci_dev *pdev)
 {
 	acpi_handle dhandle, nvidia_handle;
 	acpi_status status;
-	int ret;
+	int ret, retval = 0;
 	uint32_t result;
 
 	dhandle = DEVICE_ACPI_HANDLE(&pdev->dev);
@@ -166,11 +226,17 @@
 
 	ret = nouveau_dsm(dhandle, NOUVEAU_DSM_SUPPORTED,
 			  NOUVEAU_DSM_SUPPORTED_FUNCTIONS, &result);
-	if (ret < 0)
-		return false;
+	if (ret == 0)
+		retval |= NOUVEAU_DSM_HAS_MUX;
 
-	nouveau_dsm_priv.dhandle = dhandle;
-	return true;
+	ret = nouveau_optimus_dsm(dhandle, 0, 0, &result);
+	if (ret == 0)
+		retval |= NOUVEAU_DSM_HAS_OPT;
+
+	if (retval)
+		nouveau_dsm_priv.dhandle = dhandle;
+
+	return retval;
 }
 
 static bool nouveau_dsm_detect(void)
@@ -179,22 +245,41 @@
 	struct acpi_buffer buffer = {sizeof(acpi_method_name), acpi_method_name};
 	struct pci_dev *pdev = NULL;
 	int has_dsm = 0;
+	int has_optimus;
 	int vga_count = 0;
+	bool guid_valid;
+	int retval;
+	bool ret = false;
+
+	/* lookup the MXM GUID */
+	guid_valid = mxm_wmi_supported();
+
+	if (guid_valid)
+		printk("MXM: GUID detected in BIOS\n");
 
+	/* now do DSM detection */
 	while ((pdev = pci_get_class(PCI_CLASS_DISPLAY_VGA << 8, pdev)) != NULL) {
 		vga_count++;
 
-		has_dsm |= (nouveau_dsm_pci_probe(pdev) == true);
+		retval = nouveau_dsm_pci_probe(pdev);
+		if (retval & NOUVEAU_DSM_HAS_MUX)
+			has_dsm |= 1;
+		if (retval & NOUVEAU_DSM_HAS_OPT)
+			has_optimus = 1;
 	}
 
-	if (vga_count == 2 && has_dsm) {
+	if (vga_count == 2 && has_dsm && guid_valid) {
 		acpi_get_name(nouveau_dsm_priv.dhandle, 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;
+		ret = true;
 	}
-	return false;
+
+	if (has_optimus == 1)
+		nouveau_dsm_priv.optimus_detected = true;
+
+	return ret;
 }
 
 void nouveau_register_dsm_handler(void)
@@ -247,7 +332,7 @@
 	acpi_status status;
 	acpi_handle dhandle, rom_handle;
 
-	if (!nouveau_dsm_priv.dsm_detected)
+	if (!nouveau_dsm_priv.dsm_detected && !nouveau_dsm_priv.optimus_detected)
 		return false;
 
 	dhandle = DEVICE_ACPI_HANDLE(&pdev->dev);
diff -druN linux-2.6.39-libre/drivers/gpu/drm/nouveau/nouveau_bios.c linux-3.0-rc7-libre/drivers/gpu/drm/nouveau/nouveau_bios.c
--- linux-2.6.39-libre/drivers/gpu/drm/nouveau/nouveau_bios.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/gpu/drm/nouveau/nouveau_bios.c	2011-07-11 19:51:52.000000000 -0400
@@ -5049,11 +5049,7 @@
 		pll_lim->vco1.max_n = record[11];
 		pll_lim->min_p = record[12];
 		pll_lim->max_p = record[13];
-		/* where did this go to?? */
-		if ((entry[0] & 0xf0) == 0x80)
-			pll_lim->refclk = 27000;
-		else
-			pll_lim->refclk = 100000;
+		pll_lim->refclk = ROM16(entry[9]) * 1000;
 	}
 
 	/*
@@ -6035,6 +6031,7 @@
 		case DCB_CONNECTOR_DVI_I:
 		case DCB_CONNECTOR_DVI_D:
 		case DCB_CONNECTOR_LVDS:
+		case DCB_CONNECTOR_LVDS_SPWG:
 		case DCB_CONNECTOR_DP:
 		case DCB_CONNECTOR_eDP:
 		case DCB_CONNECTOR_HDMI_0:
diff -druN linux-2.6.39-libre/drivers/gpu/drm/nouveau/nouveau_bios.h linux-3.0-rc7-libre/drivers/gpu/drm/nouveau/nouveau_bios.h
--- linux-2.6.39-libre/drivers/gpu/drm/nouveau/nouveau_bios.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/gpu/drm/nouveau/nouveau_bios.h	2011-07-11 19:51:52.000000000 -0400
@@ -82,6 +82,7 @@
 	DCB_CONNECTOR_DVI_I = 0x30,
 	DCB_CONNECTOR_DVI_D = 0x31,
 	DCB_CONNECTOR_LVDS = 0x40,
+	DCB_CONNECTOR_LVDS_SPWG = 0x41,
 	DCB_CONNECTOR_DP = 0x46,
 	DCB_CONNECTOR_eDP = 0x47,
 	DCB_CONNECTOR_HDMI_0 = 0x60,
diff -druN linux-2.6.39-libre/drivers/gpu/drm/nouveau/nouveau_channel.c linux-3.0-rc7-libre/drivers/gpu/drm/nouveau/nouveau_channel.c
--- linux-2.6.39-libre/drivers/gpu/drm/nouveau/nouveau_channel.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/gpu/drm/nouveau/nouveau_channel.c	2011-07-11 19:51:52.000000000 -0400
@@ -268,9 +268,8 @@
 	struct drm_device *dev = chan->dev;
 	struct drm_nouveau_private *dev_priv = dev->dev_private;
 	struct nouveau_fifo_engine *pfifo = &dev_priv->engine.fifo;
-	struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph;
-	struct nouveau_crypt_engine *pcrypt = &dev_priv->engine.crypt;
 	unsigned long flags;
+	int i;
 
 	/* decrement the refcount, and we're done if there's still refs */
 	if (likely(!atomic_dec_and_test(&chan->users))) {
@@ -294,19 +293,12 @@
 	/* boot it off the hardware */
 	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 without the context
-	 * switch lock held, otherwise the irq handler is unable to
-	 * process them.
-	 */
-	if (pgraph->channel(dev) == chan)
-		nouveau_wait_for_idle(dev);
-
 	/* destroy the engine specific contexts */
 	pfifo->destroy_context(chan);
-	pgraph->destroy_context(chan);
-	if (pcrypt->destroy_context)
-		pcrypt->destroy_context(chan);
+	for (i = 0; i < NVOBJ_ENGINE_NR; i++) {
+		if (chan->engctx[i])
+			dev_priv->eng[i]->context_del(chan, i);
+	}
 
 	pfifo->reassign(dev, true);
 
@@ -414,7 +406,7 @@
 	struct nouveau_channel *chan;
 	int ret;
 
-	if (dev_priv->engine.graph.accel_blocked)
+	if (!dev_priv->eng[NVOBJ_ENGINE_GR])
 		return -ENODEV;
 
 	if (init->fb_ctxdma_handle == ~0 || init->tt_ctxdma_handle == ~0)
diff -druN linux-2.6.39-libre/drivers/gpu/drm/nouveau/nouveau_connector.c linux-3.0-rc7-libre/drivers/gpu/drm/nouveau/nouveau_connector.c
--- linux-2.6.39-libre/drivers/gpu/drm/nouveau/nouveau_connector.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/gpu/drm/nouveau/nouveau_connector.c	2011-07-11 19:51:52.000000000 -0400
@@ -442,7 +442,7 @@
 		}
 
 		/* LVDS always needs gpu scaling */
-		if (nv_connector->dcb->type == DCB_CONNECTOR_LVDS &&
+		if (connector->connector_type == DRM_MODE_CONNECTOR_LVDS &&
 		    value == DRM_MODE_SCALE_NONE)
 			return -EINVAL;
 
@@ -650,6 +650,7 @@
 		ret = get_slave_funcs(encoder)->get_modes(encoder, connector);
 
 	if (nv_connector->dcb->type == DCB_CONNECTOR_LVDS ||
+	    nv_connector->dcb->type == DCB_CONNECTOR_LVDS_SPWG ||
 	    nv_connector->dcb->type == DCB_CONNECTOR_eDP)
 		ret += nouveau_connector_scaler_modes_add(connector);
 
@@ -810,6 +811,7 @@
 		type = DRM_MODE_CONNECTOR_HDMIA;
 		break;
 	case DCB_CONNECTOR_LVDS:
+	case DCB_CONNECTOR_LVDS_SPWG:
 		type = DRM_MODE_CONNECTOR_LVDS;
 		funcs = &nouveau_connector_funcs_lvds;
 		break;
@@ -838,7 +840,7 @@
 	drm_connector_helper_add(connector, &nouveau_connector_helper_funcs);
 
 	/* Check if we need dithering enabled */
-	if (dcb->type == DCB_CONNECTOR_LVDS) {
+	if (connector->connector_type == DRM_MODE_CONNECTOR_LVDS) {
 		bool dummy, is_24bit = false;
 
 		ret = nouveau_bios_parse_lvds_table(dev, 0, &dummy, &is_24bit);
@@ -883,7 +885,7 @@
 				nv_connector->use_dithering ?
 				DRM_MODE_DITHERING_ON : DRM_MODE_DITHERING_OFF);
 
-		if (dcb->type != DCB_CONNECTOR_LVDS) {
+		if (connector->connector_type != DRM_MODE_CONNECTOR_LVDS) {
 			if (dev_priv->card_type >= NV_50)
 				connector->polled = DRM_CONNECTOR_POLL_HPD;
 			else
diff -druN linux-2.6.39-libre/drivers/gpu/drm/nouveau/nouveau_display.c linux-3.0-rc7-libre/drivers/gpu/drm/nouveau/nouveau_display.c
--- linux-2.6.39-libre/drivers/gpu/drm/nouveau/nouveau_display.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/gpu/drm/nouveau/nouveau_display.c	2011-07-11 19:51:52.000000000 -0400
@@ -276,7 +276,7 @@
 	struct nouveau_fence *fence;
 	int ret;
 
-	if (dev_priv->engine.graph.accel_blocked)
+	if (!dev_priv->channel)
 		return -ENODEV;
 
 	s = kzalloc(sizeof(*s), GFP_KERNEL);
diff -druN linux-2.6.39-libre/drivers/gpu/drm/nouveau/nouveau_drv.c linux-3.0-rc7-libre/drivers/gpu/drm/nouveau/nouveau_drv.c
--- linux-2.6.39-libre/drivers/gpu/drm/nouveau/nouveau_drv.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/gpu/drm/nouveau/nouveau_drv.c	2011-07-11 19:51:52.000000000 -0400
@@ -162,11 +162,10 @@
 	struct drm_device *dev = pci_get_drvdata(pdev);
 	struct drm_nouveau_private *dev_priv = dev->dev_private;
 	struct nouveau_instmem_engine *pinstmem = &dev_priv->engine.instmem;
-	struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph;
 	struct nouveau_fifo_engine *pfifo = &dev_priv->engine.fifo;
 	struct nouveau_channel *chan;
 	struct drm_crtc *crtc;
-	int ret, i;
+	int ret, i, e;
 
 	if (pm_state.event == PM_EVENT_PRETHAW)
 		return 0;
@@ -206,12 +205,17 @@
 			nouveau_channel_idle(chan);
 	}
 
-	pgraph->fifo_access(dev, false);
-	nouveau_wait_for_idle(dev);
 	pfifo->reassign(dev, false);
 	pfifo->disable(dev);
 	pfifo->unload_context(dev);
-	pgraph->unload_context(dev);
+
+	for (e = NVOBJ_ENGINE_NR - 1; e >= 0; e--) {
+		if (dev_priv->eng[e]) {
+			ret = dev_priv->eng[e]->fini(dev, e);
+			if (ret)
+				goto out_abort;
+		}
+	}
 
 	ret = pinstmem->suspend(dev);
 	if (ret) {
@@ -242,9 +246,12 @@
 
 out_abort:
 	NV_INFO(dev, "Re-enabling acceleration..\n");
+	for (e = e + 1; e < NVOBJ_ENGINE_NR; e++) {
+		if (dev_priv->eng[e])
+			dev_priv->eng[e]->init(dev, e);
+	}
 	pfifo->enable(dev);
 	pfifo->reassign(dev, true);
-	pgraph->fifo_access(dev, true);
 	return ret;
 }
 
@@ -299,8 +306,10 @@
 	engine->mc.init(dev);
 	engine->timer.init(dev);
 	engine->fb.init(dev);
-	engine->graph.init(dev);
-	engine->crypt.init(dev);
+	for (i = 0; i < NVOBJ_ENGINE_NR; i++) {
+		if (dev_priv->eng[i])
+			dev_priv->eng[i]->init(dev, i);
+	}
 	engine->fifo.init(dev);
 
 	nouveau_irq_postinstall(dev);
diff -druN linux-2.6.39-libre/drivers/gpu/drm/nouveau/nouveau_drv.h linux-3.0-rc7-libre/drivers/gpu/drm/nouveau/nouveau_drv.h
--- linux-2.6.39-libre/drivers/gpu/drm/nouveau/nouveau_drv.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/gpu/drm/nouveau/nouveau_drv.h	2011-07-11 19:51:52.000000000 -0400
@@ -150,13 +150,12 @@
 
 #define NVOBJ_ENGINE_SW		0
 #define NVOBJ_ENGINE_GR		1
-#define NVOBJ_ENGINE_PPP	2
-#define NVOBJ_ENGINE_COPY	3
-#define NVOBJ_ENGINE_VP		4
-#define NVOBJ_ENGINE_CRYPT      5
-#define NVOBJ_ENGINE_BSP	6
-#define NVOBJ_ENGINE_DISPLAY	0xcafe0001
-#define NVOBJ_ENGINE_INT	0xdeadbeef
+#define NVOBJ_ENGINE_CRYPT	2
+#define NVOBJ_ENGINE_COPY0	3
+#define NVOBJ_ENGINE_COPY1	4
+#define NVOBJ_ENGINE_MPEG	5
+#define NVOBJ_ENGINE_DISPLAY	15
+#define NVOBJ_ENGINE_NR		16
 
 #define NVOBJ_FLAG_DONT_MAP             (1 << 0)
 #define NVOBJ_FLAG_ZERO_ALLOC		(1 << 1)
@@ -245,11 +244,8 @@
 	struct nouveau_gpuobj *cache;
 	void *fifo_priv;
 
-	/* PGRAPH context */
-	/* XXX may be merge 2 pointers as private data ??? */
-	struct nouveau_gpuobj *ramin_grctx;
-	struct nouveau_gpuobj *crypt_ctx;
-	void *pgraph_ctx;
+	/* Execution engine contexts */
+	void *engctx[NVOBJ_ENGINE_NR];
 
 	/* NV50 VM */
 	struct nouveau_vm     *vm;
@@ -298,6 +294,18 @@
 	} debugfs;
 };
 
+struct nouveau_exec_engine {
+	void (*destroy)(struct drm_device *, int engine);
+	int  (*init)(struct drm_device *, int engine);
+	int  (*fini)(struct drm_device *, int engine);
+	int  (*context_new)(struct nouveau_channel *, int engine);
+	void (*context_del)(struct nouveau_channel *, int engine);
+	int  (*object_new)(struct nouveau_channel *, int engine,
+			   u32 handle, u16 class);
+	void (*set_tile_region)(struct drm_device *dev, int i);
+	void (*tlb_flush)(struct drm_device *, int engine);
+};
+
 struct nouveau_instmem_engine {
 	void	*priv;
 
@@ -364,30 +372,6 @@
 	void (*tlb_flush)(struct drm_device *dev);
 };
 
-struct nouveau_pgraph_engine {
-	bool accel_blocked;
-	bool registered;
-	int grctx_size;
-	void *priv;
-
-	/* NV2x/NV3x context table (0x400780) */
-	struct nouveau_gpuobj *ctx_table;
-
-	int  (*init)(struct drm_device *);
-	void (*takedown)(struct drm_device *);
-
-	void (*fifo_access)(struct drm_device *, bool);
-
-	struct nouveau_channel *(*channel)(struct drm_device *);
-	int  (*create_context)(struct nouveau_channel *);
-	void (*destroy_context)(struct nouveau_channel *);
-	int  (*load_context)(struct nouveau_channel *);
-	int  (*unload_context)(struct drm_device *);
-	void (*tlb_flush)(struct drm_device *dev);
-
-	void (*set_tile_region)(struct drm_device *dev, int i);
-};
-
 struct nouveau_display_engine {
 	void *priv;
 	int (*early_init)(struct drm_device *);
@@ -426,6 +410,19 @@
 	int nr_level;
 };
 
+struct nouveau_pm_memtiming {
+	int id;
+	u32 reg_100220;
+	u32 reg_100224;
+	u32 reg_100228;
+	u32 reg_10022c;
+	u32 reg_100230;
+	u32 reg_100234;
+	u32 reg_100238;
+	u32 reg_10023c;
+	u32 reg_100240;
+};
+
 #define NOUVEAU_PM_MAX_LEVEL 8
 struct nouveau_pm_level {
 	struct device_attribute dev_attr;
@@ -436,11 +433,13 @@
 	u32 memory;
 	u32 shader;
 	u32 unk05;
+	u32 unk0a;
 
 	u8 voltage;
 	u8 fanspeed;
 
 	u16 memscript;
+	struct nouveau_pm_memtiming *timing;
 };
 
 struct nouveau_pm_temp_sensor_constants {
@@ -457,17 +456,6 @@
 	s16 fan_boost;
 };
 
-struct nouveau_pm_memtiming {
-	u32 reg_100220;
-	u32 reg_100224;
-	u32 reg_100228;
-	u32 reg_10022c;
-	u32 reg_100230;
-	u32 reg_100234;
-	u32 reg_100238;
-	u32 reg_10023c;
-};
-
 struct nouveau_pm_memtimings {
 	bool supported;
 	struct nouveau_pm_memtiming *timing;
@@ -499,16 +487,6 @@
 	int (*temp_get)(struct drm_device *);
 };
 
-struct nouveau_crypt_engine {
-	bool registered;
-
-	int  (*init)(struct drm_device *);
-	void (*takedown)(struct drm_device *);
-	int  (*create_context)(struct nouveau_channel *);
-	void (*destroy_context)(struct nouveau_channel *);
-	void (*tlb_flush)(struct drm_device *dev);
-};
-
 struct nouveau_vram_engine {
 	int  (*init)(struct drm_device *);
 	int  (*get)(struct drm_device *, u64, u32 align, u32 size_nc,
@@ -523,12 +501,10 @@
 	struct nouveau_mc_engine      mc;
 	struct nouveau_timer_engine   timer;
 	struct nouveau_fb_engine      fb;
-	struct nouveau_pgraph_engine  graph;
 	struct nouveau_fifo_engine    fifo;
 	struct nouveau_display_engine display;
 	struct nouveau_gpio_engine    gpio;
 	struct nouveau_pm_engine      pm;
-	struct nouveau_crypt_engine   crypt;
 	struct nouveau_vram_engine    vram;
 };
 
@@ -637,6 +613,7 @@
 	enum nouveau_card_type card_type;
 	/* exact chipset, derived from NV_PMC_BOOT_0 */
 	int chipset;
+	int stepping;
 	int flags;
 
 	void __iomem *mmio;
@@ -647,6 +624,7 @@
 	u32 ramin_base;
 	bool ramin_available;
 	struct drm_mm ramin_heap;
+	struct nouveau_exec_engine *eng[NVOBJ_ENGINE_NR];
 	struct list_head gpuobj_list;
 	struct list_head classes;
 
@@ -745,10 +723,6 @@
 	uint32_t crtc_owner;
 	uint32_t dac_users[4];
 
-	struct nouveau_suspend_resume {
-		uint32_t *ramin_copy;
-	} susres;
-
 	struct backlight_device *backlight;
 
 	struct {
@@ -757,8 +731,6 @@
 
 	struct nouveau_fbdev *nfbdev;
 	struct apertures_struct *apertures;
-
-	bool powered_down;
 };
 
 static inline struct drm_nouveau_private *
@@ -883,17 +855,27 @@
 extern void nouveau_channel_idle(struct nouveau_channel *chan);
 
 /* nouveau_object.c */
-#define NVOBJ_CLASS(d,c,e) do {                                                \
+#define NVOBJ_ENGINE_ADD(d, e, p) do {                                         \
+	struct drm_nouveau_private *dev_priv = (d)->dev_private;               \
+	dev_priv->eng[NVOBJ_ENGINE_##e] = (p);                                 \
+} while (0)
+
+#define NVOBJ_ENGINE_DEL(d, e) do {                                            \
+	struct drm_nouveau_private *dev_priv = (d)->dev_private;               \
+	dev_priv->eng[NVOBJ_ENGINE_##e] = NULL;                                \
+} while (0)
+
+#define NVOBJ_CLASS(d, c, e) do {                                              \
 	int ret = nouveau_gpuobj_class_new((d), (c), NVOBJ_ENGINE_##e);        \
 	if (ret)                                                               \
 		return ret;                                                    \
-} while(0)
+} while (0)
 
-#define NVOBJ_MTHD(d,c,m,e) do {                                               \
+#define NVOBJ_MTHD(d, c, m, e) do {                                            \
 	int ret = nouveau_gpuobj_mthd_new((d), (c), (m), (e));                 \
 	if (ret)                                                               \
 		return ret;                                                    \
-} while(0)
+} while (0)
 
 extern int  nouveau_gpuobj_early_init(struct drm_device *);
 extern int  nouveau_gpuobj_init(struct drm_device *);
@@ -903,7 +885,7 @@
 extern int  nouveau_gpuobj_class_new(struct drm_device *, u32 class, u32 eng);
 extern int  nouveau_gpuobj_mthd_new(struct drm_device *, u32 class, u32 mthd,
 				    int (*exec)(struct nouveau_channel *,
-					        u32 class, u32 mthd, u32 data));
+						u32 class, u32 mthd, u32 data));
 extern int  nouveau_gpuobj_mthd_call(struct nouveau_channel *, u32, u32, u32);
 extern int  nouveau_gpuobj_mthd_call2(struct drm_device *, int, u32, u32, u32);
 extern int nouveau_gpuobj_channel_init(struct nouveau_channel *,
@@ -1137,81 +1119,50 @@
 extern int  nvc0_fifo_unload_context(struct drm_device *);
 
 /* nv04_graph.c */
-extern int  nv04_graph_init(struct drm_device *);
-extern void nv04_graph_takedown(struct drm_device *);
+extern int  nv04_graph_create(struct drm_device *);
 extern void nv04_graph_fifo_access(struct drm_device *, bool);
-extern struct nouveau_channel *nv04_graph_channel(struct drm_device *);
-extern int  nv04_graph_create_context(struct nouveau_channel *);
-extern void nv04_graph_destroy_context(struct nouveau_channel *);
-extern int  nv04_graph_load_context(struct nouveau_channel *);
-extern int  nv04_graph_unload_context(struct drm_device *);
+extern int  nv04_graph_object_new(struct nouveau_channel *, int, u32, u16);
 extern int  nv04_graph_mthd_page_flip(struct nouveau_channel *chan,
 				      u32 class, u32 mthd, u32 data);
 extern struct nouveau_bitfield nv04_graph_nsource[];
 
 /* nv10_graph.c */
-extern int  nv10_graph_init(struct drm_device *);
-extern void nv10_graph_takedown(struct drm_device *);
+extern int  nv10_graph_create(struct drm_device *);
 extern struct nouveau_channel *nv10_graph_channel(struct drm_device *);
-extern int  nv10_graph_create_context(struct nouveau_channel *);
-extern void nv10_graph_destroy_context(struct nouveau_channel *);
-extern int  nv10_graph_load_context(struct nouveau_channel *);
-extern int  nv10_graph_unload_context(struct drm_device *);
-extern void nv10_graph_set_tile_region(struct drm_device *dev, int i);
 extern struct nouveau_bitfield nv10_graph_intr[];
 extern struct nouveau_bitfield nv10_graph_nstatus[];
 
 /* nv20_graph.c */
-extern int  nv20_graph_create_context(struct nouveau_channel *);
-extern void nv20_graph_destroy_context(struct nouveau_channel *);
-extern int  nv20_graph_load_context(struct nouveau_channel *);
-extern int  nv20_graph_unload_context(struct drm_device *);
-extern int  nv20_graph_init(struct drm_device *);
-extern void nv20_graph_takedown(struct drm_device *);
-extern int  nv30_graph_init(struct drm_device *);
-extern void nv20_graph_set_tile_region(struct drm_device *dev, int i);
+extern int  nv20_graph_create(struct drm_device *);
 
 /* nv40_graph.c */
-extern int  nv40_graph_init(struct drm_device *);
-extern void nv40_graph_takedown(struct drm_device *);
-extern struct nouveau_channel *nv40_graph_channel(struct drm_device *);
-extern int  nv40_graph_create_context(struct nouveau_channel *);
-extern void nv40_graph_destroy_context(struct nouveau_channel *);
-extern int  nv40_graph_load_context(struct nouveau_channel *);
-extern int  nv40_graph_unload_context(struct drm_device *);
+extern int  nv40_graph_create(struct drm_device *);
 extern void nv40_grctx_init(struct nouveau_grctx *);
-extern void nv40_graph_set_tile_region(struct drm_device *dev, int i);
 
 /* nv50_graph.c */
-extern int  nv50_graph_init(struct drm_device *);
-extern void nv50_graph_takedown(struct drm_device *);
-extern void nv50_graph_fifo_access(struct drm_device *, bool);
-extern struct nouveau_channel *nv50_graph_channel(struct drm_device *);
-extern int  nv50_graph_create_context(struct nouveau_channel *);
-extern void nv50_graph_destroy_context(struct nouveau_channel *);
-extern int  nv50_graph_load_context(struct nouveau_channel *);
-extern int  nv50_graph_unload_context(struct drm_device *);
+extern int  nv50_graph_create(struct drm_device *);
 extern int  nv50_grctx_init(struct nouveau_grctx *);
-extern void nv50_graph_tlb_flush(struct drm_device *dev);
-extern void nv84_graph_tlb_flush(struct drm_device *dev);
 extern struct nouveau_enum nv50_data_error_names[];
+extern int  nv50_graph_isr_chid(struct drm_device *dev, u64 inst);
 
 /* nvc0_graph.c */
-extern int  nvc0_graph_init(struct drm_device *);
-extern void nvc0_graph_takedown(struct drm_device *);
-extern void nvc0_graph_fifo_access(struct drm_device *, bool);
-extern struct nouveau_channel *nvc0_graph_channel(struct drm_device *);
-extern int  nvc0_graph_create_context(struct nouveau_channel *);
-extern void nvc0_graph_destroy_context(struct nouveau_channel *);
-extern int  nvc0_graph_load_context(struct nouveau_channel *);
-extern int  nvc0_graph_unload_context(struct drm_device *);
+extern int  nvc0_graph_create(struct drm_device *);
+extern int  nvc0_graph_isr_chid(struct drm_device *dev, u64 inst);
 
 /* nv84_crypt.c */
-extern int  nv84_crypt_init(struct drm_device *dev);
-extern void nv84_crypt_fini(struct drm_device *dev);
-extern int  nv84_crypt_create_context(struct nouveau_channel *);
-extern void nv84_crypt_destroy_context(struct nouveau_channel *);
-extern void nv84_crypt_tlb_flush(struct drm_device *dev);
+extern int  nv84_crypt_create(struct drm_device *);
+
+/* nva3_copy.c */
+extern int  nva3_copy_create(struct drm_device *dev);
+
+/* nvc0_copy.c */
+extern int  nvc0_copy_create(struct drm_device *dev, int engine);
+
+/* nv40_mpeg.c */
+extern int  nv40_mpeg_create(struct drm_device *dev);
+
+/* nv50_mpeg.c */
+extern int  nv50_mpeg_create(struct drm_device *dev);
 
 /* nv04_instmem.c */
 extern int  nv04_instmem_init(struct drm_device *);
@@ -1402,8 +1353,8 @@
 /* nv50_calc. */
 int nv50_calc_pll(struct drm_device *, struct pll_lims *, int clk,
 		  int *N1, int *M1, int *N2, int *M2, int *P);
-int nv50_calc_pll2(struct drm_device *, struct pll_lims *,
-		   int clk, int *N, int *fN, int *M, int *P);
+int nva3_calc_pll(struct drm_device *, struct pll_lims *,
+		  int clk, int *N, int *fN, int *M, int *P);
 
 #ifndef ioread32_native
 #ifdef __BIG_ENDIAN
@@ -1579,6 +1530,13 @@
 		dev->pdev->subsystem_device == sub_device;
 }
 
+static inline void *
+nv_engine(struct drm_device *dev, int engine)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	return (void *)dev_priv->eng[engine];
+}
+
 /* returns 1 if device is one of the nv4x using the 0x4497 object class,
  * helpful to determine a number of other hardware features
  */
diff -druN linux-2.6.39-libre/drivers/gpu/drm/nouveau/nouveau_fence.c linux-3.0-rc7-libre/drivers/gpu/drm/nouveau/nouveau_fence.c
--- linux-2.6.39-libre/drivers/gpu/drm/nouveau/nouveau_fence.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/gpu/drm/nouveau/nouveau_fence.c	2011-07-11 19:51:52.000000000 -0400
@@ -339,11 +339,12 @@
 	int ret;
 
 	if (dev_priv->chipset < 0x84) {
-		ret = RING_SPACE(chan, 3);
+		ret = RING_SPACE(chan, 4);
 		if (ret)
 			return ret;
 
-		BEGIN_RING(chan, NvSubSw, NV_SW_SEMAPHORE_OFFSET, 2);
+		BEGIN_RING(chan, NvSubSw, NV_SW_DMA_SEMAPHORE, 3);
+		OUT_RING  (chan, NvSema);
 		OUT_RING  (chan, sema->mem->start);
 		OUT_RING  (chan, 1);
 	} else
@@ -351,10 +352,12 @@
 		struct nouveau_vma *vma = &dev_priv->fence.bo->vma;
 		u64 offset = vma->offset + sema->mem->start;
 
-		ret = RING_SPACE(chan, 5);
+		ret = RING_SPACE(chan, 7);
 		if (ret)
 			return ret;
 
+		BEGIN_RING(chan, NvSubSw, NV_SW_DMA_SEMAPHORE, 1);
+		OUT_RING  (chan, chan->vram_handle);
 		BEGIN_RING(chan, NvSubSw, 0x0010, 4);
 		OUT_RING  (chan, upper_32_bits(offset));
 		OUT_RING  (chan, lower_32_bits(offset));
@@ -394,11 +397,12 @@
 	int ret;
 
 	if (dev_priv->chipset < 0x84) {
-		ret = RING_SPACE(chan, 4);
+		ret = RING_SPACE(chan, 5);
 		if (ret)
 			return ret;
 
-		BEGIN_RING(chan, NvSubSw, NV_SW_SEMAPHORE_OFFSET, 1);
+		BEGIN_RING(chan, NvSubSw, NV_SW_DMA_SEMAPHORE, 2);
+		OUT_RING  (chan, NvSema);
 		OUT_RING  (chan, sema->mem->start);
 		BEGIN_RING(chan, NvSubSw, NV_SW_SEMAPHORE_RELEASE, 1);
 		OUT_RING  (chan, 1);
@@ -407,10 +411,12 @@
 		struct nouveau_vma *vma = &dev_priv->fence.bo->vma;
 		u64 offset = vma->offset + sema->mem->start;
 
-		ret = RING_SPACE(chan, 5);
+		ret = RING_SPACE(chan, 7);
 		if (ret)
 			return ret;
 
+		BEGIN_RING(chan, NvSubSw, NV_SW_DMA_SEMAPHORE, 1);
+		OUT_RING  (chan, chan->vram_handle);
 		BEGIN_RING(chan, NvSubSw, 0x0010, 4);
 		OUT_RING  (chan, upper_32_bits(offset));
 		OUT_RING  (chan, lower_32_bits(offset));
@@ -504,22 +510,22 @@
 	struct nouveau_gpuobj *obj = NULL;
 	int ret;
 
-	if (dev_priv->card_type >= NV_C0)
-		goto out_initialised;
+	if (dev_priv->card_type < NV_C0) {
+		/* Create an NV_SW object for various sync purposes */
+		ret = nouveau_gpuobj_gr_new(chan, NvSw, NV_SW);
+		if (ret)
+			return ret;
 
-	/* Create an NV_SW object for various sync purposes */
-	ret = nouveau_gpuobj_gr_new(chan, NvSw, NV_SW);
-	if (ret)
-		return ret;
+		ret = RING_SPACE(chan, 2);
+		if (ret)
+			return ret;
 
-	/* we leave subchannel empty for nvc0 */
-	ret = RING_SPACE(chan, 2);
-	if (ret)
-		return ret;
-	BEGIN_RING(chan, NvSubSw, 0, 1);
-	OUT_RING(chan, NvSw);
+		BEGIN_RING(chan, NvSubSw, 0, 1);
+		OUT_RING  (chan, NvSw);
+		FIRE_RING (chan);
+	}
 
-	/* Create a DMA object for the shared cross-channel sync area. */
+	/* Setup area of memory shared between all channels for x-chan sync */
 	if (USE_SEMA(dev) && dev_priv->chipset < 0x84) {
 		struct ttm_mem_reg *mem = &dev_priv->fence.bo->bo.mem;
 
@@ -534,23 +540,8 @@
 		nouveau_gpuobj_ref(NULL, &obj);
 		if (ret)
 			return ret;
-
-		ret = RING_SPACE(chan, 2);
-		if (ret)
-			return ret;
-		BEGIN_RING(chan, NvSubSw, NV_SW_DMA_SEMAPHORE, 1);
-		OUT_RING(chan, NvSema);
-	} else {
-		ret = RING_SPACE(chan, 2);
-		if (ret)
-			return ret;
-		BEGIN_RING(chan, NvSubSw, NV_SW_DMA_SEMAPHORE, 1);
-		OUT_RING  (chan, chan->vram_handle); /* whole VM */
 	}
 
-	FIRE_RING(chan);
-
-out_initialised:
 	INIT_LIST_HEAD(&chan->fence.pending);
 	spin_lock_init(&chan->fence.lock);
 	atomic_set(&chan->fence.last_sequence_irq, 0);
diff -druN linux-2.6.39-libre/drivers/gpu/drm/nouveau/nouveau_grctx.h linux-3.0-rc7-libre/drivers/gpu/drm/nouveau/nouveau_grctx.h
--- linux-2.6.39-libre/drivers/gpu/drm/nouveau/nouveau_grctx.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/gpu/drm/nouveau/nouveau_grctx.h	2011-07-11 19:51:52.000000000 -0400
@@ -87,10 +87,10 @@
 	cp_out(ctx, CP_BRA | (mod << 18) | ip | flag |
 		    (state ? 0 : CP_BRA_IF_CLEAR));
 }
-#define cp_bra(c,f,s,n) _cp_bra((c), 0, CP_FLAG_##f, CP_FLAG_##f##_##s, n)
+#define cp_bra(c, f, s, n) _cp_bra((c), 0, CP_FLAG_##f, CP_FLAG_##f##_##s, n)
 #ifdef CP_BRA_MOD
-#define cp_cal(c,f,s,n) _cp_bra((c), 1, CP_FLAG_##f, CP_FLAG_##f##_##s, n)
-#define cp_ret(c,f,s) _cp_bra((c), 2, CP_FLAG_##f, CP_FLAG_##f##_##s, 0)
+#define cp_cal(c, f, s, n) _cp_bra((c), 1, CP_FLAG_##f, CP_FLAG_##f##_##s, n)
+#define cp_ret(c, f, s) _cp_bra((c), 2, CP_FLAG_##f, CP_FLAG_##f##_##s, 0)
 #endif
 
 static inline void
@@ -98,14 +98,14 @@
 {
 	cp_out(ctx, CP_WAIT | flag | (state ? CP_WAIT_SET : 0));
 }
-#define cp_wait(c,f,s) _cp_wait((c), CP_FLAG_##f, CP_FLAG_##f##_##s)
+#define cp_wait(c, f, s) _cp_wait((c), CP_FLAG_##f, CP_FLAG_##f##_##s)
 
 static inline void
 _cp_set(struct nouveau_grctx *ctx, int flag, int state)
 {
 	cp_out(ctx, CP_SET | flag | (state ? CP_SET_1 : 0));
 }
-#define cp_set(c,f,s) _cp_set((c), CP_FLAG_##f, CP_FLAG_##f##_##s)
+#define cp_set(c, f, s) _cp_set((c), CP_FLAG_##f, CP_FLAG_##f##_##s)
 
 static inline void
 cp_pos(struct nouveau_grctx *ctx, int offset)
diff -druN linux-2.6.39-libre/drivers/gpu/drm/nouveau/nouveau_hw.c linux-3.0-rc7-libre/drivers/gpu/drm/nouveau/nouveau_hw.c
--- linux-2.6.39-libre/drivers/gpu/drm/nouveau/nouveau_hw.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/gpu/drm/nouveau/nouveau_hw.c	2011-07-11 19:51:52.000000000 -0400
@@ -900,6 +900,7 @@
 	}
 	/* NV11 and NV20 don't have this, they stop at 0x52. */
 	if (nv_gf4_disp_arch(dev)) {
+		rd_cio_state(dev, head, regp, NV_CIO_CRE_42);
 		rd_cio_state(dev, head, regp, NV_CIO_CRE_53);
 		rd_cio_state(dev, head, regp, NV_CIO_CRE_54);
 
@@ -1003,6 +1004,7 @@
 			nouveau_wait_eq(dev, 650000000, NV_PRMCIO_INP0__COLOR, 0x8, 0x0);
 		}
 
+		wr_cio_state(dev, head, regp, NV_CIO_CRE_42);
 		wr_cio_state(dev, head, regp, NV_CIO_CRE_53);
 		wr_cio_state(dev, head, regp, NV_CIO_CRE_54);
 
diff -druN linux-2.6.39-libre/drivers/gpu/drm/nouveau/nouveau_mem.c linux-3.0-rc7-libre/drivers/gpu/drm/nouveau/nouveau_mem.c
--- linux-2.6.39-libre/drivers/gpu/drm/nouveau/nouveau_mem.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/gpu/drm/nouveau/nouveau_mem.c	2011-07-11 19:51:52.000000000 -0400
@@ -51,8 +51,7 @@
 	struct drm_nouveau_private *dev_priv = dev->dev_private;
 	struct nouveau_fifo_engine *pfifo = &dev_priv->engine.fifo;
 	struct nouveau_fb_engine *pfb = &dev_priv->engine.fb;
-	struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph;
-	int i = tile - dev_priv->tile.reg;
+	int i = tile - dev_priv->tile.reg, j;
 	unsigned long save;
 
 	nouveau_fence_unref(&tile->fence);
@@ -70,7 +69,10 @@
 	nouveau_wait_for_idle(dev);
 
 	pfb->set_tile_region(dev, i);
-	pgraph->set_tile_region(dev, i);
+	for (j = 0; j < NVOBJ_ENGINE_NR; j++) {
+		if (dev_priv->eng[j] && dev_priv->eng[j]->set_tile_region)
+			dev_priv->eng[j]->set_tile_region(dev, i);
+	}
 
 	pfifo->cache_pull(dev, true);
 	pfifo->reassign(dev, true);
@@ -395,7 +397,7 @@
 		if (pci_dma_supported(dev->pdev, DMA_BIT_MASK(40)))
 			dma_bits = 40;
 	} else
-	if (drm_pci_device_is_pcie(dev) &&
+	if (0 && drm_pci_device_is_pcie(dev) &&
 	    dev_priv->chipset  > 0x40 &&
 	    dev_priv->chipset != 0x45) {
 		if (pci_dma_supported(dev->pdev, DMA_BIT_MASK(39)))
@@ -595,10 +597,10 @@
 	if (!memtimings->timing)
 		return;
 
-	/* Get "some number" from the timing reg for NV_40
+	/* Get "some number" from the timing reg for NV_40 and NV_50
 	 * Used in calculations later */
-	if(dev_priv->card_type == NV_40) {
-		magic_number = (nv_rd32(dev,0x100228) & 0x0f000000) >> 24;
+	if (dev_priv->card_type >= NV_40 && dev_priv->chipset < 0x98) {
+		magic_number = (nv_rd32(dev, 0x100228) & 0x0f000000) >> 24;
 	}
 
 	entry = mem + mem[1];
@@ -641,51 +643,68 @@
 		/* XXX: I don't trust the -1's and +1's... they must come
 		 *      from somewhere! */
 		timing->reg_100224 = (tUNK_0 + tUNK_19 + 1 + magic_number) << 24 |
-				      tUNK_18 << 16 |
+				      max(tUNK_18, (u8) 1) << 16 |
 				      (tUNK_1 + tUNK_19 + 1 + magic_number) << 8;
-		if(dev_priv->chipset == 0xa8) {
+		if (dev_priv->chipset == 0xa8) {
 			timing->reg_100224 |= (tUNK_2 - 1);
 		} else {
 			timing->reg_100224 |= (tUNK_2 + 2 - magic_number);
 		}
 
 		timing->reg_100228 = (tUNK_12 << 16 | tUNK_11 << 8 | tUNK_10);
-		if(dev_priv->chipset >= 0xa3 && dev_priv->chipset < 0xaa) {
+		if (dev_priv->chipset >= 0xa3 && dev_priv->chipset < 0xaa)
 			timing->reg_100228 |= (tUNK_19 - 1) << 24;
-		}
+		else
+			timing->reg_100228 |= magic_number << 24;
 
-		if(dev_priv->card_type == NV_40) {
+		if (dev_priv->card_type == NV_40) {
 			/* NV40: don't know what the rest of the regs are..
 			 * And don't need to know either */
-			timing->reg_100228 |= 0x20200000 | magic_number << 24;
-		} else if(dev_priv->card_type >= NV_50) {
-			/* XXX: reg_10022c */
-			timing->reg_10022c = tUNK_2 - 1;
+			timing->reg_100228 |= 0x20200000;
+		} else if (dev_priv->card_type >= NV_50) {
+			if (dev_priv->chipset < 0x98 ||
+			    (dev_priv->chipset == 0x98 &&
+			     dev_priv->stepping <= 0xa1)) {
+				timing->reg_10022c = (0x14 + tUNK_2) << 24 |
+						     0x16 << 16 |
+						     (tUNK_2 - 1) << 8 |
+						     (tUNK_2 - 1);
+			} else {
+				/* XXX: reg_10022c for recentish cards */
+				timing->reg_10022c = tUNK_2 - 1;
+			}
 
 			timing->reg_100230 = (tUNK_20 << 24 | tUNK_21 << 16 |
 						  tUNK_13 << 8  | tUNK_13);
 
 			timing->reg_100234 = (tRAS << 24 | tRC);
-			timing->reg_100234 += max(tUNK_10,tUNK_11) << 16;
+			timing->reg_100234 += max(tUNK_10, tUNK_11) << 16;
 
-			if(dev_priv->chipset < 0xa3) {
+			if (dev_priv->chipset < 0x98 ||
+			    (dev_priv->chipset == 0x98 &&
+			     dev_priv->stepping <= 0xa1)) {
 				timing->reg_100234 |= (tUNK_2 + 2) << 8;
 			} else {
 				/* XXX: +6? */
 				timing->reg_100234 |= (tUNK_19 + 6) << 8;
 			}
 
-			/* XXX; reg_100238, reg_10023c
-			 * reg_100238: 0x00??????
-			 * reg_10023c: 0x!!??0202 for NV50+ cards (empirical evidence) */
+			/* XXX; reg_100238
+			 * reg_100238: 0x00?????? */
 			timing->reg_10023c = 0x202;
-			if(dev_priv->chipset < 0xa3) {
+			if (dev_priv->chipset < 0x98 ||
+			    (dev_priv->chipset == 0x98 &&
+			     dev_priv->stepping <= 0xa1)) {
 				timing->reg_10023c |= 0x4000000 | (tUNK_2 - 1) << 16;
 			} else {
-				/* currently unknown
+				/* XXX: reg_10023c
+				 * currently unknown
 				 * 10023c seen as 06xxxxxx, 0bxxxxxx or 0fxxxxxx */
 			}
+
+			/* XXX: reg_100240? */
 		}
+		timing->id = i;
 
 		NV_DEBUG(dev, "Entry %d: 220: %08x %08x %08x %08x\n", i,
 			 timing->reg_100220, timing->reg_100224,
@@ -693,10 +712,11 @@
 		NV_DEBUG(dev, "         230: %08x %08x %08x %08x\n",
 			 timing->reg_100230, timing->reg_100234,
 			 timing->reg_100238, timing->reg_10023c);
+		NV_DEBUG(dev, "         240: %08x\n", timing->reg_100240);
 	}
 
 	memtimings->nr_timing = entries;
-	memtimings->supported = true;
+	memtimings->supported = (dev_priv->chipset <= 0x98);
 }
 
 void
@@ -848,7 +868,9 @@
 		nouveau_vm_unmap(&node->tmp_vma);
 		nouveau_vm_put(&node->tmp_vma);
 	}
+
 	mem->mm_node = NULL;
+	kfree(node);
 }
 
 static int
diff -druN linux-2.6.39-libre/drivers/gpu/drm/nouveau/nouveau_object.c linux-3.0-rc7-libre/drivers/gpu/drm/nouveau/nouveau_object.c
--- linux-2.6.39-libre/drivers/gpu/drm/nouveau/nouveau_object.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/gpu/drm/nouveau/nouveau_object.c	2011-07-11 19:51:52.000000000 -0400
@@ -361,20 +361,6 @@
 	return 0;
 }
 
-
-static uint32_t
-nouveau_gpuobj_class_instmem_size(struct drm_device *dev, int class)
-{
-	struct drm_nouveau_private *dev_priv = dev->dev_private;
-
-	/*XXX: dodgy hack for now */
-	if (dev_priv->card_type >= NV_50)
-		return 24;
-	if (dev_priv->card_type >= NV_40)
-		return 32;
-	return 16;
-}
-
 /*
    DMA objects are used to reference a piece of memory in the
    framebuffer, PCI or AGP address space. Each object is 16 bytes big
@@ -606,11 +592,11 @@
    set to 0?
 */
 static int
-nouveau_gpuobj_sw_new(struct nouveau_channel *chan, int class,
-		      struct nouveau_gpuobj **gpuobj_ret)
+nouveau_gpuobj_sw_new(struct nouveau_channel *chan, u32 handle, u16 class)
 {
 	struct drm_nouveau_private *dev_priv = chan->dev->dev_private;
 	struct nouveau_gpuobj *gpuobj;
+	int ret;
 
 	gpuobj = kzalloc(sizeof(*gpuobj), GFP_KERNEL);
 	if (!gpuobj)
@@ -624,8 +610,10 @@
 	spin_lock(&dev_priv->ramin_lock);
 	list_add_tail(&gpuobj->list, &dev_priv->gpuobj_list);
 	spin_unlock(&dev_priv->ramin_lock);
-	*gpuobj_ret = gpuobj;
-	return 0;
+
+	ret = nouveau_ramht_insert(chan, handle, gpuobj);
+	nouveau_gpuobj_ref(NULL, &gpuobj);
+	return ret;
 }
 
 int
@@ -634,101 +622,30 @@
 	struct drm_nouveau_private *dev_priv = chan->dev->dev_private;
 	struct drm_device *dev = chan->dev;
 	struct nouveau_gpuobj_class *oc;
-	struct nouveau_gpuobj *gpuobj;
 	int ret;
 
 	NV_DEBUG(dev, "ch%d class=0x%04x\n", chan->id, class);
 
 	list_for_each_entry(oc, &dev_priv->classes, head) {
-		if (oc->id == class)
-			goto found;
-	}
-
-	NV_ERROR(dev, "illegal object class: 0x%x\n", class);
-	return -EINVAL;
+		struct nouveau_exec_engine *eng = dev_priv->eng[oc->engine];
 
-found:
-	switch (oc->engine) {
-	case NVOBJ_ENGINE_SW:
-		if (dev_priv->card_type < NV_C0) {
-			ret = nouveau_gpuobj_sw_new(chan, class, &gpuobj);
-			if (ret)
-				return ret;
-			goto insert;
-		}
-		break;
-	case NVOBJ_ENGINE_GR:
-		if ((dev_priv->card_type >= NV_20 && !chan->ramin_grctx) ||
-		    (dev_priv->card_type  < NV_20 && !chan->pgraph_ctx)) {
-			struct nouveau_pgraph_engine *pgraph =
-				&dev_priv->engine.graph;
+		if (oc->id != class)
+			continue;
 
-			ret = pgraph->create_context(chan);
-			if (ret)
-				return ret;
-		}
-		break;
-	case NVOBJ_ENGINE_CRYPT:
-		if (!chan->crypt_ctx) {
-			struct nouveau_crypt_engine *pcrypt =
-				&dev_priv->engine.crypt;
+		if (oc->engine == NVOBJ_ENGINE_SW)
+			return nouveau_gpuobj_sw_new(chan, handle, class);
 
-			ret = pcrypt->create_context(chan);
+		if (!chan->engctx[oc->engine]) {
+			ret = eng->context_new(chan, oc->engine);
 			if (ret)
 				return ret;
 		}
-		break;
-	}
-
-	/* we're done if this is fermi */
-	if (dev_priv->card_type >= NV_C0)
-		return 0;
-
-	ret = nouveau_gpuobj_new(dev, chan,
-				 nouveau_gpuobj_class_instmem_size(dev, class),
-				 16,
-				 NVOBJ_FLAG_ZERO_ALLOC | NVOBJ_FLAG_ZERO_FREE,
-				 &gpuobj);
-	if (ret) {
-		NV_ERROR(dev, "error creating gpuobj: %d\n", ret);
-		return ret;
-	}
 
-	if (dev_priv->card_type >= NV_50) {
-		nv_wo32(gpuobj,  0, class);
-		nv_wo32(gpuobj, 20, 0x00010000);
-	} else {
-		switch (class) {
-		case NV_CLASS_NULL:
-			nv_wo32(gpuobj, 0, 0x00001030);
-			nv_wo32(gpuobj, 4, 0xFFFFFFFF);
-			break;
-		default:
-			if (dev_priv->card_type >= NV_40) {
-				nv_wo32(gpuobj, 0, class);
-#ifdef __BIG_ENDIAN
-				nv_wo32(gpuobj, 8, 0x01000000);
-#endif
-			} else {
-#ifdef __BIG_ENDIAN
-				nv_wo32(gpuobj, 0, class | 0x00080000);
-#else
-				nv_wo32(gpuobj, 0, class);
-#endif
-			}
-		}
+		return eng->object_new(chan, oc->engine, handle, class);
 	}
-	dev_priv->engine.instmem.flush(dev);
 
-	gpuobj->engine = oc->engine;
-	gpuobj->class  = oc->id;
-
-insert:
-	ret = nouveau_ramht_insert(chan, handle, gpuobj);
-	if (ret)
-		NV_ERROR(dev, "error adding gpuobj to RAMHT: %d\n", ret);
-	nouveau_gpuobj_ref(NULL, &gpuobj);
-	return ret;
+	NV_ERROR(dev, "illegal object class: 0x%x\n", class);
+	return -EINVAL;
 }
 
 static int
@@ -746,9 +663,6 @@
 	size = 0x2000;
 	base = 0;
 
-	/* PGRAPH context */
-	size += dev_priv->engine.graph.grctx_size;
-
 	if (dev_priv->card_type == NV_50) {
 		/* Various fixed table thingos */
 		size += 0x1400; /* mostly unknown stuff */
diff -druN linux-2.6.39-libre/drivers/gpu/drm/nouveau/nouveau_perf.c linux-3.0-rc7-libre/drivers/gpu/drm/nouveau/nouveau_perf.c
--- linux-2.6.39-libre/drivers/gpu/drm/nouveau/nouveau_perf.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/gpu/drm/nouveau/nouveau_perf.c	2011-07-11 19:51:52.000000000 -0400
@@ -72,6 +72,68 @@
 	pm->nr_perflvl = 1;
 }
 
+static struct nouveau_pm_memtiming *
+nouveau_perf_timing(struct drm_device *dev, struct bit_entry *P,
+		    u16 memclk, u8 *entry, u8 recordlen, u8 entries)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_pm_engine *pm = &dev_priv->engine.pm;
+	struct nvbios *bios = &dev_priv->vbios;
+	u8 ramcfg;
+	int i;
+
+	/* perf v2 has a separate "timing map" table, we have to match
+	 * the target memory clock to a specific entry, *then* use
+	 * ramcfg to select the correct subentry
+	 */
+	if (P->version == 2) {
+		u8 *tmap = ROMPTR(bios, P->data[4]);
+		if (!tmap) {
+			NV_DEBUG(dev, "no timing map pointer\n");
+			return NULL;
+		}
+
+		if (tmap[0] != 0x10) {
+			NV_WARN(dev, "timing map 0x%02x unknown\n", tmap[0]);
+			return NULL;
+		}
+
+		entry = tmap + tmap[1];
+		recordlen = tmap[2] + (tmap[4] * tmap[3]);
+		for (i = 0; i < tmap[5]; i++, entry += recordlen) {
+			if (memclk >= ROM16(entry[0]) &&
+			    memclk <= ROM16(entry[2]))
+				break;
+		}
+
+		if (i == tmap[5]) {
+			NV_WARN(dev, "no match in timing map table\n");
+			return NULL;
+		}
+
+		entry += tmap[2];
+		recordlen = tmap[3];
+		entries   = tmap[4];
+	}
+
+	ramcfg = (nv_rd32(dev, NV_PEXTDEV_BOOT_0) & 0x0000003c) >> 2;
+	if (bios->ram_restrict_tbl_ptr)
+		ramcfg = bios->data[bios->ram_restrict_tbl_ptr + ramcfg];
+
+	if (ramcfg >= entries) {
+		NV_WARN(dev, "ramcfg strap out of bounds!\n");
+		return NULL;
+	}
+
+	entry += ramcfg * recordlen;
+	if (entry[1] >= pm->memtimings.nr_timing) {
+		NV_WARN(dev, "timingset %d does not exist\n", entry[1]);
+		return NULL;
+	}
+
+	return &pm->memtimings.timing[entry[1]];
+}
+
 void
 nouveau_perf_init(struct drm_device *dev)
 {
@@ -120,10 +182,17 @@
 		entries   = perf[2];
 	}
 
+	if (entries > NOUVEAU_PM_MAX_LEVEL) {
+		NV_DEBUG(dev, "perf table has too many entries - buggy vbios?\n");
+		entries = NOUVEAU_PM_MAX_LEVEL;
+	}
+
 	entry = perf + headerlen;
 	for (i = 0; i < entries; i++) {
 		struct nouveau_pm_level *perflvl = &pm->perflvl[pm->nr_perflvl];
 
+		perflvl->timing = NULL;
+
 		if (entry[0] == 0xff) {
 			entry += recordlen;
 			continue;
@@ -174,9 +243,21 @@
 #define subent(n) entry[perf[2] + ((n) * perf[3])]
 			perflvl->fanspeed = 0; /*XXX*/
 			perflvl->voltage = entry[2];
-			perflvl->core = (ROM16(subent(0)) & 0xfff) * 1000;
-			perflvl->shader = (ROM16(subent(1)) & 0xfff) * 1000;
-			perflvl->memory = (ROM16(subent(2)) & 0xfff) * 1000;
+			if (dev_priv->card_type == NV_50) {
+				perflvl->core = ROM16(subent(0)) & 0xfff;
+				perflvl->shader = ROM16(subent(1)) & 0xfff;
+				perflvl->memory = ROM16(subent(2)) & 0xfff;
+			} else {
+				perflvl->shader = ROM16(subent(3)) & 0xfff;
+				perflvl->core   = perflvl->shader / 2;
+				perflvl->unk0a  = ROM16(subent(4)) & 0xfff;
+				perflvl->memory = ROM16(subent(5)) & 0xfff;
+			}
+
+			perflvl->core *= 1000;
+			perflvl->shader *= 1000;
+			perflvl->memory *= 1000;
+			perflvl->unk0a *= 1000;
 			break;
 		}
 
@@ -190,6 +271,16 @@
 			}
 		}
 
+		/* get the corresponding memory timings */
+		if (version > 0x15) {
+			/* last 3 args are for < 0x40, ignored for >= 0x40 */
+			perflvl->timing =
+				nouveau_perf_timing(dev, &P,
+						    perflvl->memory / 1000,
+						    entry + perf[3],
+						    perf[5], perf[4]);
+		}
+
 		snprintf(perflvl->name, sizeof(perflvl->name),
 			 "performance_level_%d", i);
 		perflvl->id = i;
diff -druN linux-2.6.39-libre/drivers/gpu/drm/nouveau/nouveau_pm.c linux-3.0-rc7-libre/drivers/gpu/drm/nouveau/nouveau_pm.c
--- linux-2.6.39-libre/drivers/gpu/drm/nouveau/nouveau_pm.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/gpu/drm/nouveau/nouveau_pm.c	2011-07-11 19:51:52.000000000 -0400
@@ -156,7 +156,7 @@
 static void
 nouveau_pm_perflvl_info(struct nouveau_pm_level *perflvl, char *ptr, int len)
 {
-	char c[16], s[16], v[16], f[16];
+	char c[16], s[16], v[16], f[16], t[16];
 
 	c[0] = '\0';
 	if (perflvl->core)
@@ -174,8 +174,12 @@
 	if (perflvl->fanspeed)
 		snprintf(f, sizeof(f), " fanspeed %d%%", perflvl->fanspeed);
 
-	snprintf(ptr, len, "memory %dMHz%s%s%s%s\n", perflvl->memory / 1000,
-		 c, s, v, f);
+	t[0] = '\0';
+	if (perflvl->timing)
+		snprintf(t, sizeof(t), " timing %d", perflvl->timing->id);
+
+	snprintf(ptr, len, "memory %dMHz%s%s%s%s%s\n", perflvl->memory / 1000,
+		 c, s, v, f, t);
 }
 
 static ssize_t
@@ -449,7 +453,7 @@
 #endif
 }
 
-#ifdef CONFIG_ACPI
+#if defined(CONFIG_ACPI) && defined(CONFIG_POWER_SUPPLY)
 static int
 nouveau_pm_acpi_event(struct notifier_block *nb, unsigned long val, void *data)
 {
@@ -476,10 +480,10 @@
 	char info[256];
 	int ret, i;
 
+	nouveau_mem_timing_init(dev);
 	nouveau_volt_init(dev);
 	nouveau_perf_init(dev);
 	nouveau_temp_init(dev);
-	nouveau_mem_timing_init(dev);
 
 	NV_INFO(dev, "%d available performance level(s)\n", pm->nr_perflvl);
 	for (i = 0; i < pm->nr_perflvl; i++) {
@@ -490,6 +494,7 @@
 	/* determine current ("boot") performance level */
 	ret = nouveau_pm_perflvl_get(dev, &pm->boot);
 	if (ret == 0) {
+		strncpy(pm->boot.name, "boot", 4);
 		pm->cur = &pm->boot;
 
 		nouveau_pm_perflvl_info(&pm->boot, info, sizeof(info));
@@ -507,7 +512,7 @@
 
 	nouveau_sysfs_init(dev);
 	nouveau_hwmon_init(dev);
-#ifdef CONFIG_ACPI
+#if defined(CONFIG_ACPI) && defined(CONFIG_POWER_SUPPLY)
 	pm->acpi_nb.notifier_call = nouveau_pm_acpi_event;
 	register_acpi_notifier(&pm->acpi_nb);
 #endif
@@ -524,12 +529,12 @@
 	if (pm->cur != &pm->boot)
 		nouveau_pm_perflvl_set(dev, &pm->boot);
 
-	nouveau_mem_timing_fini(dev);
 	nouveau_temp_fini(dev);
 	nouveau_perf_fini(dev);
 	nouveau_volt_fini(dev);
+	nouveau_mem_timing_fini(dev);
 
-#ifdef CONFIG_ACPI
+#if defined(CONFIG_ACPI) && defined(CONFIG_POWER_SUPPLY)
 	unregister_acpi_notifier(&pm->acpi_nb);
 #endif
 	nouveau_hwmon_fini(dev);
diff -druN linux-2.6.39-libre/drivers/gpu/drm/nouveau/nouveau_reg.h linux-3.0-rc7-libre/drivers/gpu/drm/nouveau/nouveau_reg.h
--- linux-2.6.39-libre/drivers/gpu/drm/nouveau/nouveau_reg.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/gpu/drm/nouveau/nouveau_reg.h	2011-07-11 19:51:52.000000000 -0400
@@ -639,9 +639,9 @@
 #    define NV50_PCONNECTOR_I2C_PORT_4                      0x0000e240
 #    define NV50_PCONNECTOR_I2C_PORT_5                      0x0000e258
 
-#define NV50_AUXCH_DATA_OUT(i,n)             ((n) * 4 + (i) * 0x50 + 0x0000e4c0)
+#define NV50_AUXCH_DATA_OUT(i, n)            ((n) * 4 + (i) * 0x50 + 0x0000e4c0)
 #define NV50_AUXCH_DATA_OUT__SIZE                                             4
-#define NV50_AUXCH_DATA_IN(i,n)              ((n) * 4 + (i) * 0x50 + 0x0000e4d0)
+#define NV50_AUXCH_DATA_IN(i, n)             ((n) * 4 + (i) * 0x50 + 0x0000e4d0)
 #define NV50_AUXCH_DATA_IN__SIZE                                              4
 #define NV50_AUXCH_ADDR(i)                             ((i) * 0x50 + 0x0000e4e0)
 #define NV50_AUXCH_CTRL(i)                             ((i) * 0x50 + 0x0000e4e4)
@@ -829,7 +829,7 @@
 #define NV50_PDISPLAY_SOR_BACKLIGHT                                  0x0061c084
 #define NV50_PDISPLAY_SOR_BACKLIGHT_ENABLE                           0x80000000
 #define NV50_PDISPLAY_SOR_BACKLIGHT_LEVEL                            0x00000fff
-#define NV50_SOR_DP_CTRL(i,l)            (0x0061c10c + (i) * 0x800 + (l) * 0x80)
+#define NV50_SOR_DP_CTRL(i, l)           (0x0061c10c + (i) * 0x800 + (l) * 0x80)
 #define NV50_SOR_DP_CTRL_ENABLED                                     0x00000001
 #define NV50_SOR_DP_CTRL_ENHANCED_FRAME_ENABLED                      0x00004000
 #define NV50_SOR_DP_CTRL_LANE_MASK                                   0x001f0000
@@ -841,10 +841,10 @@
 #define NV50_SOR_DP_CTRL_TRAINING_PATTERN_DISABLED                   0x00000000
 #define NV50_SOR_DP_CTRL_TRAINING_PATTERN_1                          0x01000000
 #define NV50_SOR_DP_CTRL_TRAINING_PATTERN_2                          0x02000000
-#define NV50_SOR_DP_UNK118(i,l)          (0x0061c118 + (i) * 0x800 + (l) * 0x80)
-#define NV50_SOR_DP_UNK120(i,l)          (0x0061c120 + (i) * 0x800 + (l) * 0x80)
-#define NV50_SOR_DP_UNK128(i,l)          (0x0061c128 + (i) * 0x800 + (l) * 0x80)
-#define NV50_SOR_DP_UNK130(i,l)          (0x0061c130 + (i) * 0x800 + (l) * 0x80)
+#define NV50_SOR_DP_UNK118(i, l)         (0x0061c118 + (i) * 0x800 + (l) * 0x80)
+#define NV50_SOR_DP_UNK120(i, l)         (0x0061c120 + (i) * 0x800 + (l) * 0x80)
+#define NV50_SOR_DP_UNK128(i, l)         (0x0061c128 + (i) * 0x800 + (l) * 0x80)
+#define NV50_SOR_DP_UNK130(i, l)         (0x0061c130 + (i) * 0x800 + (l) * 0x80)
 
 #define NV50_PDISPLAY_USER(i)                        ((i) * 0x1000 + 0x00640000)
 #define NV50_PDISPLAY_USER_PUT(i)                    ((i) * 0x1000 + 0x00640000)
diff -druN linux-2.6.39-libre/drivers/gpu/drm/nouveau/nouveau_sgdma.c linux-3.0-rc7-libre/drivers/gpu/drm/nouveau/nouveau_sgdma.c
--- linux-2.6.39-libre/drivers/gpu/drm/nouveau/nouveau_sgdma.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/gpu/drm/nouveau/nouveau_sgdma.c	2011-07-11 19:51:52.000000000 -0400
@@ -458,7 +458,7 @@
 		dev_priv->gart_info.type = NOUVEAU_GART_HW;
 		dev_priv->gart_info.func = &nv50_sgdma_backend;
 	} else
-	if (drm_pci_device_is_pcie(dev) &&
+	if (0 && drm_pci_device_is_pcie(dev) &&
 	    dev_priv->chipset > 0x40 && dev_priv->chipset != 0x45) {
 		if (nv44_graph_class(dev)) {
 			dev_priv->gart_info.func = &nv44_sgdma_backend;
diff -druN linux-2.6.39-libre/drivers/gpu/drm/nouveau/nouveau_state.c linux-3.0-rc7-libre/drivers/gpu/drm/nouveau/nouveau_state.c
--- linux-2.6.39-libre/drivers/gpu/drm/nouveau/nouveau_state.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/gpu/drm/nouveau/nouveau_state.c	2011-07-11 19:51:52.000000000 -0400
@@ -65,14 +65,6 @@
 		engine->timer.takedown		= nv04_timer_takedown;
 		engine->fb.init			= nv04_fb_init;
 		engine->fb.takedown		= nv04_fb_takedown;
-		engine->graph.init		= nv04_graph_init;
-		engine->graph.takedown		= nv04_graph_takedown;
-		engine->graph.fifo_access	= nv04_graph_fifo_access;
-		engine->graph.channel		= nv04_graph_channel;
-		engine->graph.create_context	= nv04_graph_create_context;
-		engine->graph.destroy_context	= nv04_graph_destroy_context;
-		engine->graph.load_context	= nv04_graph_load_context;
-		engine->graph.unload_context	= nv04_graph_unload_context;
 		engine->fifo.channels		= 16;
 		engine->fifo.init		= nv04_fifo_init;
 		engine->fifo.takedown		= nv04_fifo_fini;
@@ -98,8 +90,6 @@
 		engine->pm.clock_get		= nv04_pm_clock_get;
 		engine->pm.clock_pre		= nv04_pm_clock_pre;
 		engine->pm.clock_set		= nv04_pm_clock_set;
-		engine->crypt.init		= nouveau_stub_init;
-		engine->crypt.takedown		= nouveau_stub_takedown;
 		engine->vram.init		= nouveau_mem_detect;
 		engine->vram.flags_valid	= nouveau_mem_flags_valid;
 		break;
@@ -123,15 +113,6 @@
 		engine->fb.init_tile_region	= nv10_fb_init_tile_region;
 		engine->fb.set_tile_region	= nv10_fb_set_tile_region;
 		engine->fb.free_tile_region	= nv10_fb_free_tile_region;
-		engine->graph.init		= nv10_graph_init;
-		engine->graph.takedown		= nv10_graph_takedown;
-		engine->graph.channel		= nv10_graph_channel;
-		engine->graph.create_context	= nv10_graph_create_context;
-		engine->graph.destroy_context	= nv10_graph_destroy_context;
-		engine->graph.fifo_access	= nv04_graph_fifo_access;
-		engine->graph.load_context	= nv10_graph_load_context;
-		engine->graph.unload_context	= nv10_graph_unload_context;
-		engine->graph.set_tile_region	= nv10_graph_set_tile_region;
 		engine->fifo.channels		= 32;
 		engine->fifo.init		= nv10_fifo_init;
 		engine->fifo.takedown		= nv04_fifo_fini;
@@ -157,8 +138,6 @@
 		engine->pm.clock_get		= nv04_pm_clock_get;
 		engine->pm.clock_pre		= nv04_pm_clock_pre;
 		engine->pm.clock_set		= nv04_pm_clock_set;
-		engine->crypt.init		= nouveau_stub_init;
-		engine->crypt.takedown		= nouveau_stub_takedown;
 		engine->vram.init		= nouveau_mem_detect;
 		engine->vram.flags_valid	= nouveau_mem_flags_valid;
 		break;
@@ -182,15 +161,6 @@
 		engine->fb.init_tile_region	= nv10_fb_init_tile_region;
 		engine->fb.set_tile_region	= nv10_fb_set_tile_region;
 		engine->fb.free_tile_region	= nv10_fb_free_tile_region;
-		engine->graph.init		= nv20_graph_init;
-		engine->graph.takedown		= nv20_graph_takedown;
-		engine->graph.channel		= nv10_graph_channel;
-		engine->graph.create_context	= nv20_graph_create_context;
-		engine->graph.destroy_context	= nv20_graph_destroy_context;
-		engine->graph.fifo_access	= nv04_graph_fifo_access;
-		engine->graph.load_context	= nv20_graph_load_context;
-		engine->graph.unload_context	= nv20_graph_unload_context;
-		engine->graph.set_tile_region	= nv20_graph_set_tile_region;
 		engine->fifo.channels		= 32;
 		engine->fifo.init		= nv10_fifo_init;
 		engine->fifo.takedown		= nv04_fifo_fini;
@@ -216,8 +186,6 @@
 		engine->pm.clock_get		= nv04_pm_clock_get;
 		engine->pm.clock_pre		= nv04_pm_clock_pre;
 		engine->pm.clock_set		= nv04_pm_clock_set;
-		engine->crypt.init		= nouveau_stub_init;
-		engine->crypt.takedown		= nouveau_stub_takedown;
 		engine->vram.init		= nouveau_mem_detect;
 		engine->vram.flags_valid	= nouveau_mem_flags_valid;
 		break;
@@ -241,15 +209,6 @@
 		engine->fb.init_tile_region	= nv30_fb_init_tile_region;
 		engine->fb.set_tile_region	= nv10_fb_set_tile_region;
 		engine->fb.free_tile_region	= nv30_fb_free_tile_region;
-		engine->graph.init		= nv30_graph_init;
-		engine->graph.takedown		= nv20_graph_takedown;
-		engine->graph.fifo_access	= nv04_graph_fifo_access;
-		engine->graph.channel		= nv10_graph_channel;
-		engine->graph.create_context	= nv20_graph_create_context;
-		engine->graph.destroy_context	= nv20_graph_destroy_context;
-		engine->graph.load_context	= nv20_graph_load_context;
-		engine->graph.unload_context	= nv20_graph_unload_context;
-		engine->graph.set_tile_region	= nv20_graph_set_tile_region;
 		engine->fifo.channels		= 32;
 		engine->fifo.init		= nv10_fifo_init;
 		engine->fifo.takedown		= nv04_fifo_fini;
@@ -277,8 +236,6 @@
 		engine->pm.clock_set		= nv04_pm_clock_set;
 		engine->pm.voltage_get		= nouveau_voltage_gpio_get;
 		engine->pm.voltage_set		= nouveau_voltage_gpio_set;
-		engine->crypt.init		= nouveau_stub_init;
-		engine->crypt.takedown		= nouveau_stub_takedown;
 		engine->vram.init		= nouveau_mem_detect;
 		engine->vram.flags_valid	= nouveau_mem_flags_valid;
 		break;
@@ -303,15 +260,6 @@
 		engine->fb.init_tile_region	= nv30_fb_init_tile_region;
 		engine->fb.set_tile_region	= nv40_fb_set_tile_region;
 		engine->fb.free_tile_region	= nv30_fb_free_tile_region;
-		engine->graph.init		= nv40_graph_init;
-		engine->graph.takedown		= nv40_graph_takedown;
-		engine->graph.fifo_access	= nv04_graph_fifo_access;
-		engine->graph.channel		= nv40_graph_channel;
-		engine->graph.create_context	= nv40_graph_create_context;
-		engine->graph.destroy_context	= nv40_graph_destroy_context;
-		engine->graph.load_context	= nv40_graph_load_context;
-		engine->graph.unload_context	= nv40_graph_unload_context;
-		engine->graph.set_tile_region	= nv40_graph_set_tile_region;
 		engine->fifo.channels		= 32;
 		engine->fifo.init		= nv40_fifo_init;
 		engine->fifo.takedown		= nv04_fifo_fini;
@@ -340,8 +288,6 @@
 		engine->pm.voltage_get		= nouveau_voltage_gpio_get;
 		engine->pm.voltage_set		= nouveau_voltage_gpio_set;
 		engine->pm.temp_get		= nv40_temp_get;
-		engine->crypt.init		= nouveau_stub_init;
-		engine->crypt.takedown		= nouveau_stub_takedown;
 		engine->vram.init		= nouveau_mem_detect;
 		engine->vram.flags_valid	= nouveau_mem_flags_valid;
 		break;
@@ -368,19 +314,6 @@
 		engine->timer.takedown		= nv04_timer_takedown;
 		engine->fb.init			= nv50_fb_init;
 		engine->fb.takedown		= nv50_fb_takedown;
-		engine->graph.init		= nv50_graph_init;
-		engine->graph.takedown		= nv50_graph_takedown;
-		engine->graph.fifo_access	= nv50_graph_fifo_access;
-		engine->graph.channel		= nv50_graph_channel;
-		engine->graph.create_context	= nv50_graph_create_context;
-		engine->graph.destroy_context	= nv50_graph_destroy_context;
-		engine->graph.load_context	= nv50_graph_load_context;
-		engine->graph.unload_context	= nv50_graph_unload_context;
-		if (dev_priv->chipset == 0x50 ||
-		    dev_priv->chipset == 0xac)
-			engine->graph.tlb_flush	= nv50_graph_tlb_flush;
-		else
-			engine->graph.tlb_flush	= nv84_graph_tlb_flush;
 		engine->fifo.channels		= 128;
 		engine->fifo.init		= nv50_fifo_init;
 		engine->fifo.takedown		= nv50_fifo_takedown;
@@ -432,24 +365,6 @@
 			engine->pm.temp_get	= nv84_temp_get;
 		else
 			engine->pm.temp_get	= nv40_temp_get;
-		switch (dev_priv->chipset) {
-		case 0x84:
-		case 0x86:
-		case 0x92:
-		case 0x94:
-		case 0x96:
-		case 0xa0:
-			engine->crypt.init	= nv84_crypt_init;
-			engine->crypt.takedown	= nv84_crypt_fini;
-			engine->crypt.create_context = nv84_crypt_create_context;
-			engine->crypt.destroy_context = nv84_crypt_destroy_context;
-			engine->crypt.tlb_flush	= nv84_crypt_tlb_flush;
-			break;
-		default:
-			engine->crypt.init	= nouveau_stub_init;
-			engine->crypt.takedown	= nouveau_stub_takedown;
-			break;
-		}
 		engine->vram.init		= nv50_vram_init;
 		engine->vram.get		= nv50_vram_new;
 		engine->vram.put		= nv50_vram_del;
@@ -472,14 +387,6 @@
 		engine->timer.takedown		= nv04_timer_takedown;
 		engine->fb.init			= nvc0_fb_init;
 		engine->fb.takedown		= nvc0_fb_takedown;
-		engine->graph.init		= nvc0_graph_init;
-		engine->graph.takedown		= nvc0_graph_takedown;
-		engine->graph.fifo_access	= nvc0_graph_fifo_access;
-		engine->graph.channel		= nvc0_graph_channel;
-		engine->graph.create_context	= nvc0_graph_create_context;
-		engine->graph.destroy_context	= nvc0_graph_destroy_context;
-		engine->graph.load_context	= nvc0_graph_load_context;
-		engine->graph.unload_context	= nvc0_graph_unload_context;
 		engine->fifo.channels		= 128;
 		engine->fifo.init		= nvc0_fifo_init;
 		engine->fifo.takedown		= nvc0_fifo_takedown;
@@ -503,8 +410,6 @@
 		engine->gpio.irq_register	= nv50_gpio_irq_register;
 		engine->gpio.irq_unregister	= nv50_gpio_irq_unregister;
 		engine->gpio.irq_enable		= nv50_gpio_irq_enable;
-		engine->crypt.init		= nouveau_stub_init;
-		engine->crypt.takedown		= nouveau_stub_takedown;
 		engine->vram.init		= nvc0_vram_init;
 		engine->vram.get		= nvc0_vram_new;
 		engine->vram.put		= nv50_vram_del;
@@ -593,7 +498,7 @@
 {
 	struct drm_nouveau_private *dev_priv = dev->dev_private;
 	struct nouveau_engine *engine;
-	int ret;
+	int ret, e = 0;
 
 	vga_client_register(dev->pdev, dev, NULL, nouveau_vga_set_decode);
 	vga_switcheroo_register_client(dev->pdev, nouveau_switcheroo_set_state,
@@ -658,23 +563,80 @@
 	if (ret)
 		goto out_timer;
 
-	if (nouveau_noaccel)
-		engine->graph.accel_blocked = true;
-	else {
-		/* PGRAPH */
-		ret = engine->graph.init(dev);
-		if (ret)
-			goto out_fb;
+	if (!nouveau_noaccel) {
+		switch (dev_priv->card_type) {
+		case NV_04:
+			nv04_graph_create(dev);
+			break;
+		case NV_10:
+			nv10_graph_create(dev);
+			break;
+		case NV_20:
+		case NV_30:
+			nv20_graph_create(dev);
+			break;
+		case NV_40:
+			nv40_graph_create(dev);
+			break;
+		case NV_50:
+			nv50_graph_create(dev);
+			break;
+		case NV_C0:
+			nvc0_graph_create(dev);
+			break;
+		default:
+			break;
+		}
 
-		/* PCRYPT */
-		ret = engine->crypt.init(dev);
-		if (ret)
-			goto out_graph;
+		switch (dev_priv->chipset) {
+		case 0x84:
+		case 0x86:
+		case 0x92:
+		case 0x94:
+		case 0x96:
+		case 0xa0:
+			nv84_crypt_create(dev);
+			break;
+		}
+
+		switch (dev_priv->card_type) {
+		case NV_50:
+			switch (dev_priv->chipset) {
+			case 0xa3:
+			case 0xa5:
+			case 0xa8:
+			case 0xaf:
+				nva3_copy_create(dev);
+				break;
+			}
+			break;
+		case NV_C0:
+			nvc0_copy_create(dev, 0);
+			nvc0_copy_create(dev, 1);
+			break;
+		default:
+			break;
+		}
+
+		if (dev_priv->card_type == NV_40)
+			nv40_mpeg_create(dev);
+		else
+		if (dev_priv->card_type == NV_50 &&
+		    (dev_priv->chipset < 0x98 || dev_priv->chipset == 0xa0))
+			nv50_mpeg_create(dev);
+
+		for (e = 0; e < NVOBJ_ENGINE_NR; e++) {
+			if (dev_priv->eng[e]) {
+				ret = dev_priv->eng[e]->init(dev, e);
+				if (ret)
+					goto out_engine;
+			}
+		}
 
 		/* PFIFO */
 		ret = engine->fifo.init(dev);
 		if (ret)
-			goto out_crypt;
+			goto out_engine;
 	}
 
 	ret = engine->display.create(dev);
@@ -691,7 +653,7 @@
 
 	/* what about PVIDEO/PCRTC/PRAMDAC etc? */
 
-	if (!engine->graph.accel_blocked) {
+	if (dev_priv->eng[NVOBJ_ENGINE_GR]) {
 		ret = nouveau_fence_init(dev);
 		if (ret)
 			goto out_irq;
@@ -715,13 +677,16 @@
 out_fifo:
 	if (!nouveau_noaccel)
 		engine->fifo.takedown(dev);
-out_crypt:
-	if (!nouveau_noaccel)
-		engine->crypt.takedown(dev);
-out_graph:
-	if (!nouveau_noaccel)
-		engine->graph.takedown(dev);
-out_fb:
+out_engine:
+	if (!nouveau_noaccel) {
+		for (e = e - 1; e >= 0; e--) {
+			if (!dev_priv->eng[e])
+				continue;
+			dev_priv->eng[e]->fini(dev, e);
+			dev_priv->eng[e]->destroy(dev,e );
+		}
+	}
+
 	engine->fb.takedown(dev);
 out_timer:
 	engine->timer.takedown(dev);
@@ -751,16 +716,21 @@
 {
 	struct drm_nouveau_private *dev_priv = dev->dev_private;
 	struct nouveau_engine *engine = &dev_priv->engine;
+	int e;
 
-	if (!engine->graph.accel_blocked) {
+	if (dev_priv->channel) {
 		nouveau_fence_fini(dev);
 		nouveau_channel_put_unlocked(&dev_priv->channel);
 	}
 
 	if (!nouveau_noaccel) {
 		engine->fifo.takedown(dev);
-		engine->crypt.takedown(dev);
-		engine->graph.takedown(dev);
+		for (e = NVOBJ_ENGINE_NR - 1; e >= 0; e--) {
+			if (dev_priv->eng[e]) {
+				dev_priv->eng[e]->fini(dev, e);
+				dev_priv->eng[e]->destroy(dev,e );
+			}
+		}
 	}
 	engine->fb.takedown(dev);
 	engine->timer.takedown(dev);
@@ -866,7 +836,7 @@
 #ifdef CONFIG_X86
 	primary = dev->pdev->resource[PCI_ROM_RESOURCE].flags & IORESOURCE_ROM_SHADOW;
 #endif
-	
+
 	remove_conflicting_framebuffers(dev_priv->apertures, "nouveaufb", primary);
 	return 0;
 }
@@ -910,19 +880,21 @@
 
 #ifdef __BIG_ENDIAN
 	/* Put the card in BE mode if it's not */
-	if (nv_rd32(dev, NV03_PMC_BOOT_1))
-		nv_wr32(dev, NV03_PMC_BOOT_1, 0x00000001);
+	if (nv_rd32(dev, NV03_PMC_BOOT_1) != 0x01000001)
+		nv_wr32(dev, NV03_PMC_BOOT_1, 0x01000001);
 
 	DRM_MEMORYBARRIER();
 #endif
 
 	/* Time to determine the card architecture */
 	reg0 = nv_rd32(dev, NV03_PMC_BOOT_0);
+	dev_priv->stepping = 0; /* XXX: add stepping for pre-NV10? */
 
 	/* We're dealing with >=NV10 */
 	if ((reg0 & 0x0f000000) > 0) {
 		/* Bit 27-20 contain the architecture in hex */
 		dev_priv->chipset = (reg0 & 0xff00000) >> 20;
+		dev_priv->stepping = (reg0 & 0xff);
 	/* NV04 or NV05 */
 	} else if ((reg0 & 0xff00fff0) == 0x20004000) {
 		if (reg0 & 0x00f00000)
diff -druN linux-2.6.39-libre/drivers/gpu/drm/nouveau/nouveau_vm.c linux-3.0-rc7-libre/drivers/gpu/drm/nouveau/nouveau_vm.c
--- linux-2.6.39-libre/drivers/gpu/drm/nouveau/nouveau_vm.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/gpu/drm/nouveau/nouveau_vm.c	2011-07-11 19:51:52.000000000 -0400
@@ -58,6 +58,7 @@
 			num -= len;
 			pte += len;
 			if (unlikely(end >= max)) {
+				phys += len << (bits + 12);
 				pde++;
 				pte = 0;
 			}
diff -druN linux-2.6.39-libre/drivers/gpu/drm/nouveau/nouveau_vm.h linux-3.0-rc7-libre/drivers/gpu/drm/nouveau/nouveau_vm.h
--- linux-2.6.39-libre/drivers/gpu/drm/nouveau/nouveau_vm.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/gpu/drm/nouveau/nouveau_vm.h	2011-07-11 19:51:52.000000000 -0400
@@ -53,8 +53,7 @@
 	int refcount;
 
 	struct list_head pgd_list;
-	atomic_t pgraph_refs;
-	atomic_t pcrypt_refs;
+	atomic_t engref[16];
 
 	struct nouveau_vm_pgt *pgt;
 	u32 fpde;
diff -druN linux-2.6.39-libre/drivers/gpu/drm/nouveau/nouveau_volt.c linux-3.0-rc7-libre/drivers/gpu/drm/nouveau/nouveau_volt.c
--- linux-2.6.39-libre/drivers/gpu/drm/nouveau/nouveau_volt.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/gpu/drm/nouveau/nouveau_volt.c	2011-07-11 19:51:52.000000000 -0400
@@ -159,8 +159,16 @@
 		headerlen = volt[1];
 		recordlen = volt[2];
 		entries   = volt[3];
-		vidshift  = hweight8(volt[5]);
 		vidmask   = volt[4];
+		/* no longer certain what volt[5] is, if it's related to
+		 * the vid shift then it's definitely not a function of
+		 * how many bits are set.
+		 *
+		 * after looking at a number of nva3+ vbios images, they
+		 * all seem likely to have a static shift of 2.. lets
+		 * go with that for now until proven otherwise.
+		 */
+		vidshift  = 2;
 		break;
 	default:
 		NV_WARN(dev, "voltage table 0x%02x unknown\n", volt[0]);
diff -druN linux-2.6.39-libre/drivers/gpu/drm/nouveau/nv04_crtc.c linux-3.0-rc7-libre/drivers/gpu/drm/nouveau/nv04_crtc.c
--- linux-2.6.39-libre/drivers/gpu/drm/nouveau/nv04_crtc.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/gpu/drm/nouveau/nv04_crtc.c	2011-07-11 19:51:52.000000000 -0400
@@ -376,7 +376,10 @@
 	 */
 
 	/* framebuffer can be larger than crtc scanout area. */
-	regp->CRTC[NV_CIO_CRE_RPC0_INDEX] = XLATE(fb->pitch / 8, 8, NV_CIO_CRE_RPC0_OFFSET_10_8);
+	regp->CRTC[NV_CIO_CRE_RPC0_INDEX] =
+		XLATE(fb->pitch / 8, 8, NV_CIO_CRE_RPC0_OFFSET_10_8);
+	regp->CRTC[NV_CIO_CRE_42] =
+		XLATE(fb->pitch / 8, 11, NV_CIO_CRE_42_OFFSET_11);
 	regp->CRTC[NV_CIO_CRE_RPC1_INDEX] = mode->crtc_hdisplay < 1280 ?
 					    MASK(NV_CIO_CRE_RPC1_LARGE) : 0x00;
 	regp->CRTC[NV_CIO_CRE_LSR_INDEX] = XLATE(horizBlankEnd, 6, NV_CIO_CRE_LSR_HBE_6) |
@@ -790,8 +793,7 @@
 	if (atomic) {
 		drm_fb = passed_fb;
 		fb = nouveau_framebuffer(passed_fb);
-	}
-	else {
+	} else {
 		/* If not atomic, we can go ahead and pin, and unpin the
 		 * old fb we were passed.
 		 */
@@ -825,8 +827,11 @@
 	regp->CRTC[NV_CIO_CR_OFFSET_INDEX] = drm_fb->pitch >> 3;
 	regp->CRTC[NV_CIO_CRE_RPC0_INDEX] =
 		XLATE(drm_fb->pitch >> 3, 8, NV_CIO_CRE_RPC0_OFFSET_10_8);
+	regp->CRTC[NV_CIO_CRE_42] =
+		XLATE(drm_fb->pitch / 8, 11, NV_CIO_CRE_42_OFFSET_11);
 	crtc_wr_cio_state(crtc, regp, NV_CIO_CRE_RPC0_INDEX);
 	crtc_wr_cio_state(crtc, regp, NV_CIO_CR_OFFSET_INDEX);
+	crtc_wr_cio_state(crtc, regp, NV_CIO_CRE_42);
 
 	/* Update the framebuffer location. */
 	regp->fb_start = nv_crtc->fb.offset & ~3;
@@ -944,14 +949,14 @@
 	struct drm_gem_object *gem;
 	int ret = 0;
 
-	if (width != 64 || height != 64)
-		return -EINVAL;
-
 	if (!buffer_handle) {
 		nv_crtc->cursor.hide(nv_crtc, true);
 		return 0;
 	}
 
+	if (width != 64 || height != 64)
+		return -EINVAL;
+
 	gem = drm_gem_object_lookup(dev, file_priv, buffer_handle);
 	if (!gem)
 		return -ENOENT;
diff -druN linux-2.6.39-libre/drivers/gpu/drm/nouveau/nv04_graph.c linux-3.0-rc7-libre/drivers/gpu/drm/nouveau/nv04_graph.c
--- linux-2.6.39-libre/drivers/gpu/drm/nouveau/nv04_graph.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/gpu/drm/nouveau/nv04_graph.c	2011-07-11 19:51:52.000000000 -0400
@@ -28,9 +28,11 @@
 #include "nouveau_drv.h"
 #include "nouveau_hw.h"
 #include "nouveau_util.h"
+#include "nouveau_ramht.h"
 
-static int  nv04_graph_register(struct drm_device *dev);
-static void nv04_graph_isr(struct drm_device *dev);
+struct nv04_graph_engine {
+	struct nouveau_exec_engine base;
+};
 
 static uint32_t nv04_graph_ctx_regs[] = {
 	0x0040053c,
@@ -350,7 +352,7 @@
 	uint32_t nv04[ARRAY_SIZE(nv04_graph_ctx_regs)];
 };
 
-struct nouveau_channel *
+static struct nouveau_channel *
 nv04_graph_channel(struct drm_device *dev)
 {
 	struct drm_nouveau_private *dev_priv = dev->dev_private;
@@ -365,26 +367,6 @@
 	return dev_priv->channels.ptr[chid];
 }
 
-static void
-nv04_graph_context_switch(struct drm_device *dev)
-{
-	struct drm_nouveau_private *dev_priv = dev->dev_private;
-	struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph;
-	struct nouveau_channel *chan = NULL;
-	int chid;
-
-	nouveau_wait_for_idle(dev);
-
-	/* If previous context is valid, we need to save it */
-	pgraph->unload_context(dev);
-
-	/* Load context for next channel */
-	chid = dev_priv->engine.fifo.channel_id(dev);
-	chan = dev_priv->channels.ptr[chid];
-	if (chan)
-		nv04_graph_load_context(chan);
-}
-
 static uint32_t *ctx_reg(struct graph_state *ctx, uint32_t reg)
 {
 	int i;
@@ -397,48 +379,11 @@
 	return NULL;
 }
 
-int nv04_graph_create_context(struct nouveau_channel *chan)
-{
-	struct graph_state *pgraph_ctx;
-	NV_DEBUG(chan->dev, "nv04_graph_context_create %d\n", chan->id);
-
-	chan->pgraph_ctx = pgraph_ctx = kzalloc(sizeof(*pgraph_ctx),
-						GFP_KERNEL);
-	if (pgraph_ctx == NULL)
-		return -ENOMEM;
-
-	*ctx_reg(pgraph_ctx, NV04_PGRAPH_DEBUG_3) = 0xfad4ff31;
-
-	return 0;
-}
-
-void nv04_graph_destroy_context(struct nouveau_channel *chan)
-{
-	struct drm_device *dev = chan->dev;
-	struct drm_nouveau_private *dev_priv = dev->dev_private;
-	struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph;
-	struct graph_state *pgraph_ctx = chan->pgraph_ctx;
-	unsigned long flags;
-
-	spin_lock_irqsave(&dev_priv->context_switch_lock, flags);
-	pgraph->fifo_access(dev, false);
-
-	/* Unload the context if it's the currently active one */
-	if (pgraph->channel(dev) == chan)
-		pgraph->unload_context(dev);
-
-	/* Free the context resources */
-	kfree(pgraph_ctx);
-	chan->pgraph_ctx = NULL;
-
-	pgraph->fifo_access(dev, true);
-	spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags);
-}
-
-int nv04_graph_load_context(struct nouveau_channel *chan)
+static int
+nv04_graph_load_context(struct nouveau_channel *chan)
 {
+	struct graph_state *pgraph_ctx = chan->engctx[NVOBJ_ENGINE_GR];
 	struct drm_device *dev = chan->dev;
-	struct graph_state *pgraph_ctx = chan->pgraph_ctx;
 	uint32_t tmp;
 	int i;
 
@@ -456,20 +401,19 @@
 	return 0;
 }
 
-int
+static int
 nv04_graph_unload_context(struct drm_device *dev)
 {
 	struct drm_nouveau_private *dev_priv = dev->dev_private;
-	struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph;
 	struct nouveau_channel *chan = NULL;
 	struct graph_state *ctx;
 	uint32_t tmp;
 	int i;
 
-	chan = pgraph->channel(dev);
+	chan = nv04_graph_channel(dev);
 	if (!chan)
 		return 0;
-	ctx = chan->pgraph_ctx;
+	ctx = chan->engctx[NVOBJ_ENGINE_GR];
 
 	for (i = 0; i < ARRAY_SIZE(nv04_graph_ctx_regs); i++)
 		ctx->nv04[i] = nv_rd32(dev, nv04_graph_ctx_regs[i]);
@@ -481,23 +425,85 @@
 	return 0;
 }
 
-int nv04_graph_init(struct drm_device *dev)
+static int
+nv04_graph_context_new(struct nouveau_channel *chan, int engine)
+{
+	struct graph_state *pgraph_ctx;
+	NV_DEBUG(chan->dev, "nv04_graph_context_create %d\n", chan->id);
+
+	pgraph_ctx = kzalloc(sizeof(*pgraph_ctx), GFP_KERNEL);
+	if (pgraph_ctx == NULL)
+		return -ENOMEM;
+
+	*ctx_reg(pgraph_ctx, NV04_PGRAPH_DEBUG_3) = 0xfad4ff31;
+
+	chan->engctx[engine] = pgraph_ctx;
+	return 0;
+}
+
+static void
+nv04_graph_context_del(struct nouveau_channel *chan, int engine)
 {
+	struct drm_device *dev = chan->dev;
 	struct drm_nouveau_private *dev_priv = dev->dev_private;
-	uint32_t tmp;
+	struct graph_state *pgraph_ctx = chan->engctx[engine];
+	unsigned long flags;
+
+	spin_lock_irqsave(&dev_priv->context_switch_lock, flags);
+	nv04_graph_fifo_access(dev, false);
+
+	/* Unload the context if it's the currently active one */
+	if (nv04_graph_channel(dev) == chan)
+		nv04_graph_unload_context(dev);
+
+	nv04_graph_fifo_access(dev, true);
+	spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags);
+
+	/* Free the context resources */
+	kfree(pgraph_ctx);
+	chan->engctx[engine] = NULL;
+}
+
+int
+nv04_graph_object_new(struct nouveau_channel *chan, int engine,
+		      u32 handle, u16 class)
+{
+	struct drm_device *dev = chan->dev;
+	struct nouveau_gpuobj *obj = NULL;
 	int ret;
 
+	ret = nouveau_gpuobj_new(dev, chan, 16, 16, NVOBJ_FLAG_ZERO_FREE, &obj);
+	if (ret)
+		return ret;
+	obj->engine = 1;
+	obj->class  = class;
+
+#ifdef __BIG_ENDIAN
+	nv_wo32(obj, 0x00, 0x00080000 | class);
+#else
+	nv_wo32(obj, 0x00, class);
+#endif
+	nv_wo32(obj, 0x04, 0x00000000);
+	nv_wo32(obj, 0x08, 0x00000000);
+	nv_wo32(obj, 0x0c, 0x00000000);
+
+	ret = nouveau_ramht_insert(chan, handle, obj);
+	nouveau_gpuobj_ref(NULL, &obj);
+	return ret;
+}
+
+static int
+nv04_graph_init(struct drm_device *dev, int engine)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	uint32_t tmp;
+
 	nv_wr32(dev, NV03_PMC_ENABLE, nv_rd32(dev, NV03_PMC_ENABLE) &
 			~NV_PMC_ENABLE_PGRAPH);
 	nv_wr32(dev, NV03_PMC_ENABLE, nv_rd32(dev, NV03_PMC_ENABLE) |
 			 NV_PMC_ENABLE_PGRAPH);
 
-	ret = nv04_graph_register(dev);
-	if (ret)
-		return ret;
-
 	/* Enable PGRAPH interrupts */
-	nouveau_irq_register(dev, 12, nv04_graph_isr);
 	nv_wr32(dev, NV03_PGRAPH_INTR, 0xFFFFFFFF);
 	nv_wr32(dev, NV03_PGRAPH_INTR_EN, 0xFFFFFFFF);
 
@@ -507,7 +513,7 @@
 	nv_wr32(dev, NV04_PGRAPH_DEBUG_0, 0x001FFFFF);*/
 	nv_wr32(dev, NV04_PGRAPH_DEBUG_0, 0x1231c000);
 	/*1231C000 blob, 001 haiku*/
-	//*V_WRITE(NV04_PGRAPH_DEBUG_1, 0xf2d91100);*/
+	/*V_WRITE(NV04_PGRAPH_DEBUG_1, 0xf2d91100);*/
 	nv_wr32(dev, NV04_PGRAPH_DEBUG_1, 0x72111100);
 	/*0x72111100 blob , 01 haiku*/
 	/*nv_wr32(dev, NV04_PGRAPH_DEBUG_2, 0x11d5f870);*/
@@ -531,10 +537,12 @@
 	return 0;
 }
 
-void nv04_graph_takedown(struct drm_device *dev)
+static int
+nv04_graph_fini(struct drm_device *dev, int engine)
 {
+	nv04_graph_unload_context(dev);
 	nv_wr32(dev, NV03_PGRAPH_INTR_EN, 0x00000000);
-	nouveau_irq_unregister(dev, 12);
+	return 0;
 }
 
 void
@@ -969,13 +977,138 @@
 	return 1;
 }
 
-static int
-nv04_graph_register(struct drm_device *dev)
+static struct nouveau_bitfield nv04_graph_intr[] = {
+	{ NV_PGRAPH_INTR_NOTIFY, "NOTIFY" },
+	{}
+};
+
+static struct nouveau_bitfield nv04_graph_nstatus[] = {
+	{ NV04_PGRAPH_NSTATUS_STATE_IN_USE,       "STATE_IN_USE" },
+	{ NV04_PGRAPH_NSTATUS_INVALID_STATE,      "INVALID_STATE" },
+	{ NV04_PGRAPH_NSTATUS_BAD_ARGUMENT,       "BAD_ARGUMENT" },
+	{ NV04_PGRAPH_NSTATUS_PROTECTION_FAULT,   "PROTECTION_FAULT" },
+	{}
+};
+
+struct nouveau_bitfield nv04_graph_nsource[] = {
+	{ NV03_PGRAPH_NSOURCE_NOTIFICATION,       "NOTIFICATION" },
+	{ NV03_PGRAPH_NSOURCE_DATA_ERROR,         "DATA_ERROR" },
+	{ NV03_PGRAPH_NSOURCE_PROTECTION_ERROR,   "PROTECTION_ERROR" },
+	{ NV03_PGRAPH_NSOURCE_RANGE_EXCEPTION,    "RANGE_EXCEPTION" },
+	{ NV03_PGRAPH_NSOURCE_LIMIT_COLOR,        "LIMIT_COLOR" },
+	{ NV03_PGRAPH_NSOURCE_LIMIT_ZETA,         "LIMIT_ZETA" },
+	{ NV03_PGRAPH_NSOURCE_ILLEGAL_MTHD,       "ILLEGAL_MTHD" },
+	{ NV03_PGRAPH_NSOURCE_DMA_R_PROTECTION,   "DMA_R_PROTECTION" },
+	{ NV03_PGRAPH_NSOURCE_DMA_W_PROTECTION,   "DMA_W_PROTECTION" },
+	{ NV03_PGRAPH_NSOURCE_FORMAT_EXCEPTION,   "FORMAT_EXCEPTION" },
+	{ NV03_PGRAPH_NSOURCE_PATCH_EXCEPTION,    "PATCH_EXCEPTION" },
+	{ NV03_PGRAPH_NSOURCE_STATE_INVALID,      "STATE_INVALID" },
+	{ NV03_PGRAPH_NSOURCE_DOUBLE_NOTIFY,      "DOUBLE_NOTIFY" },
+	{ NV03_PGRAPH_NSOURCE_NOTIFY_IN_USE,      "NOTIFY_IN_USE" },
+	{ NV03_PGRAPH_NSOURCE_METHOD_CNT,         "METHOD_CNT" },
+	{ NV03_PGRAPH_NSOURCE_BFR_NOTIFICATION,   "BFR_NOTIFICATION" },
+	{ NV03_PGRAPH_NSOURCE_DMA_VTX_PROTECTION, "DMA_VTX_PROTECTION" },
+	{ NV03_PGRAPH_NSOURCE_DMA_WIDTH_A,        "DMA_WIDTH_A" },
+	{ NV03_PGRAPH_NSOURCE_DMA_WIDTH_B,        "DMA_WIDTH_B" },
+	{}
+};
+
+static void
+nv04_graph_context_switch(struct drm_device *dev)
 {
 	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_channel *chan = NULL;
+	int chid;
 
-	if (dev_priv->engine.graph.registered)
-		return 0;
+	nouveau_wait_for_idle(dev);
+
+	/* If previous context is valid, we need to save it */
+	nv04_graph_unload_context(dev);
+
+	/* Load context for next channel */
+	chid = dev_priv->engine.fifo.channel_id(dev);
+	chan = dev_priv->channels.ptr[chid];
+	if (chan)
+		nv04_graph_load_context(chan);
+}
+
+static void
+nv04_graph_isr(struct drm_device *dev)
+{
+	u32 stat;
+
+	while ((stat = nv_rd32(dev, NV03_PGRAPH_INTR))) {
+		u32 nsource = nv_rd32(dev, NV03_PGRAPH_NSOURCE);
+		u32 nstatus = nv_rd32(dev, NV03_PGRAPH_NSTATUS);
+		u32 addr = nv_rd32(dev, NV04_PGRAPH_TRAPPED_ADDR);
+		u32 chid = (addr & 0x0f000000) >> 24;
+		u32 subc = (addr & 0x0000e000) >> 13;
+		u32 mthd = (addr & 0x00001ffc);
+		u32 data = nv_rd32(dev, NV04_PGRAPH_TRAPPED_DATA);
+		u32 class = nv_rd32(dev, 0x400180 + subc * 4) & 0xff;
+		u32 show = stat;
+
+		if (stat & NV_PGRAPH_INTR_NOTIFY) {
+			if (nsource & NV03_PGRAPH_NSOURCE_ILLEGAL_MTHD) {
+				if (!nouveau_gpuobj_mthd_call2(dev, chid, class, mthd, data))
+					show &= ~NV_PGRAPH_INTR_NOTIFY;
+			}
+		}
+
+		if (stat & NV_PGRAPH_INTR_CONTEXT_SWITCH) {
+			nv_wr32(dev, NV03_PGRAPH_INTR, NV_PGRAPH_INTR_CONTEXT_SWITCH);
+			stat &= ~NV_PGRAPH_INTR_CONTEXT_SWITCH;
+			show &= ~NV_PGRAPH_INTR_CONTEXT_SWITCH;
+			nv04_graph_context_switch(dev);
+		}
+
+		nv_wr32(dev, NV03_PGRAPH_INTR, stat);
+		nv_wr32(dev, NV04_PGRAPH_FIFO, 0x00000001);
+
+		if (show && nouveau_ratelimit()) {
+			NV_INFO(dev, "PGRAPH -");
+			nouveau_bitfield_print(nv04_graph_intr, show);
+			printk(" nsource:");
+			nouveau_bitfield_print(nv04_graph_nsource, nsource);
+			printk(" nstatus:");
+			nouveau_bitfield_print(nv04_graph_nstatus, nstatus);
+			printk("\n");
+			NV_INFO(dev, "PGRAPH - ch %d/%d class 0x%04x "
+				     "mthd 0x%04x data 0x%08x\n",
+				chid, subc, class, mthd, data);
+		}
+	}
+}
+
+static void
+nv04_graph_destroy(struct drm_device *dev, int engine)
+{
+	struct nv04_graph_engine *pgraph = nv_engine(dev, engine);
+
+	nouveau_irq_unregister(dev, 12);
+
+	NVOBJ_ENGINE_DEL(dev, GR);
+	kfree(pgraph);
+}
+
+int
+nv04_graph_create(struct drm_device *dev)
+{
+	struct nv04_graph_engine *pgraph;
+
+	pgraph = kzalloc(sizeof(*pgraph), GFP_KERNEL);
+	if (!pgraph)
+		return -ENOMEM;
+
+	pgraph->base.destroy = nv04_graph_destroy;
+	pgraph->base.init = nv04_graph_init;
+	pgraph->base.fini = nv04_graph_fini;
+	pgraph->base.context_new = nv04_graph_context_new;
+	pgraph->base.context_del = nv04_graph_context_del;
+	pgraph->base.object_new = nv04_graph_object_new;
+
+	NVOBJ_ENGINE_ADD(dev, GR, &pgraph->base);
+	nouveau_irq_register(dev, 12, nv04_graph_isr);
 
 	/* dvd subpicture */
 	NVOBJ_CLASS(dev, 0x0038, GR);
@@ -1222,93 +1355,5 @@
 	NVOBJ_CLASS(dev, 0x506e, SW);
 	NVOBJ_MTHD (dev, 0x506e, 0x0150, nv04_graph_mthd_set_ref);
 	NVOBJ_MTHD (dev, 0x506e, 0x0500, nv04_graph_mthd_page_flip);
-
-	dev_priv->engine.graph.registered = true;
 	return 0;
-};
-
-static struct nouveau_bitfield nv04_graph_intr[] = {
-	{ NV_PGRAPH_INTR_NOTIFY, "NOTIFY" },
-	{}
-};
-
-static struct nouveau_bitfield nv04_graph_nstatus[] =
-{
-	{ NV04_PGRAPH_NSTATUS_STATE_IN_USE,       "STATE_IN_USE" },
-	{ NV04_PGRAPH_NSTATUS_INVALID_STATE,      "INVALID_STATE" },
-	{ NV04_PGRAPH_NSTATUS_BAD_ARGUMENT,       "BAD_ARGUMENT" },
-	{ NV04_PGRAPH_NSTATUS_PROTECTION_FAULT,   "PROTECTION_FAULT" },
-	{}
-};
-
-struct nouveau_bitfield nv04_graph_nsource[] =
-{
-	{ NV03_PGRAPH_NSOURCE_NOTIFICATION,       "NOTIFICATION" },
-	{ NV03_PGRAPH_NSOURCE_DATA_ERROR,         "DATA_ERROR" },
-	{ NV03_PGRAPH_NSOURCE_PROTECTION_ERROR,   "PROTECTION_ERROR" },
-	{ NV03_PGRAPH_NSOURCE_RANGE_EXCEPTION,    "RANGE_EXCEPTION" },
-	{ NV03_PGRAPH_NSOURCE_LIMIT_COLOR,        "LIMIT_COLOR" },
-	{ NV03_PGRAPH_NSOURCE_LIMIT_ZETA,         "LIMIT_ZETA" },
-	{ NV03_PGRAPH_NSOURCE_ILLEGAL_MTHD,       "ILLEGAL_MTHD" },
-	{ NV03_PGRAPH_NSOURCE_DMA_R_PROTECTION,   "DMA_R_PROTECTION" },
-	{ NV03_PGRAPH_NSOURCE_DMA_W_PROTECTION,   "DMA_W_PROTECTION" },
-	{ NV03_PGRAPH_NSOURCE_FORMAT_EXCEPTION,   "FORMAT_EXCEPTION" },
-	{ NV03_PGRAPH_NSOURCE_PATCH_EXCEPTION,    "PATCH_EXCEPTION" },
-	{ NV03_PGRAPH_NSOURCE_STATE_INVALID,      "STATE_INVALID" },
-	{ NV03_PGRAPH_NSOURCE_DOUBLE_NOTIFY,      "DOUBLE_NOTIFY" },
-	{ NV03_PGRAPH_NSOURCE_NOTIFY_IN_USE,      "NOTIFY_IN_USE" },
-	{ NV03_PGRAPH_NSOURCE_METHOD_CNT,         "METHOD_CNT" },
-	{ NV03_PGRAPH_NSOURCE_BFR_NOTIFICATION,   "BFR_NOTIFICATION" },
-	{ NV03_PGRAPH_NSOURCE_DMA_VTX_PROTECTION, "DMA_VTX_PROTECTION" },
-	{ NV03_PGRAPH_NSOURCE_DMA_WIDTH_A,        "DMA_WIDTH_A" },
-	{ NV03_PGRAPH_NSOURCE_DMA_WIDTH_B,        "DMA_WIDTH_B" },
-	{}
-};
-
-static void
-nv04_graph_isr(struct drm_device *dev)
-{
-	u32 stat;
-
-	while ((stat = nv_rd32(dev, NV03_PGRAPH_INTR))) {
-		u32 nsource = nv_rd32(dev, NV03_PGRAPH_NSOURCE);
-		u32 nstatus = nv_rd32(dev, NV03_PGRAPH_NSTATUS);
-		u32 addr = nv_rd32(dev, NV04_PGRAPH_TRAPPED_ADDR);
-		u32 chid = (addr & 0x0f000000) >> 24;
-		u32 subc = (addr & 0x0000e000) >> 13;
-		u32 mthd = (addr & 0x00001ffc);
-		u32 data = nv_rd32(dev, NV04_PGRAPH_TRAPPED_DATA);
-		u32 class = nv_rd32(dev, 0x400180 + subc * 4) & 0xff;
-		u32 show = stat;
-
-		if (stat & NV_PGRAPH_INTR_NOTIFY) {
-			if (nsource & NV03_PGRAPH_NSOURCE_ILLEGAL_MTHD) {
-				if (!nouveau_gpuobj_mthd_call2(dev, chid, class, mthd, data))
-					show &= ~NV_PGRAPH_INTR_NOTIFY;
-			}
-		}
-
-		if (stat & NV_PGRAPH_INTR_CONTEXT_SWITCH) {
-			nv_wr32(dev, NV03_PGRAPH_INTR, NV_PGRAPH_INTR_CONTEXT_SWITCH);
-			stat &= ~NV_PGRAPH_INTR_CONTEXT_SWITCH;
-			show &= ~NV_PGRAPH_INTR_CONTEXT_SWITCH;
-			nv04_graph_context_switch(dev);
-		}
-
-		nv_wr32(dev, NV03_PGRAPH_INTR, stat);
-		nv_wr32(dev, NV04_PGRAPH_FIFO, 0x00000001);
-
-		if (show && nouveau_ratelimit()) {
-			NV_INFO(dev, "PGRAPH -");
-			nouveau_bitfield_print(nv04_graph_intr, show);
-			printk(" nsource:");
-			nouveau_bitfield_print(nv04_graph_nsource, nsource);
-			printk(" nstatus:");
-			nouveau_bitfield_print(nv04_graph_nstatus, nstatus);
-			printk("\n");
-			NV_INFO(dev, "PGRAPH - ch %d/%d class 0x%04x "
-				     "mthd 0x%04x data 0x%08x\n",
-				chid, subc, class, mthd, data);
-		}
-	}
 }
diff -druN linux-2.6.39-libre/drivers/gpu/drm/nouveau/nv04_instmem.c linux-3.0-rc7-libre/drivers/gpu/drm/nouveau/nv04_instmem.c
--- linux-2.6.39-libre/drivers/gpu/drm/nouveau/nv04_instmem.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/gpu/drm/nouveau/nv04_instmem.c	2011-07-11 19:51:52.000000000 -0400
@@ -95,6 +95,9 @@
 	nouveau_ramht_ref(NULL, &dev_priv->ramht, NULL);
 	nouveau_gpuobj_ref(NULL, &dev_priv->ramro);
 	nouveau_gpuobj_ref(NULL, &dev_priv->ramfc);
+
+	if (drm_mm_initialized(&dev_priv->ramin_heap))
+		drm_mm_takedown(&dev_priv->ramin_heap);
 }
 
 int
diff -druN linux-2.6.39-libre/drivers/gpu/drm/nouveau/nv10_graph.c linux-3.0-rc7-libre/drivers/gpu/drm/nouveau/nv10_graph.c
--- linux-2.6.39-libre/drivers/gpu/drm/nouveau/nv10_graph.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/gpu/drm/nouveau/nv10_graph.c	2011-07-11 19:51:52.000000000 -0400
@@ -28,10 +28,9 @@
 #include "nouveau_drv.h"
 #include "nouveau_util.h"
 
-static int  nv10_graph_register(struct drm_device *);
-static void nv10_graph_isr(struct drm_device *);
-
-#define NV10_FIFO_NUMBER 32
+struct nv10_graph_engine {
+	struct nouveau_exec_engine base;
+};
 
 struct pipe_state {
 	uint32_t pipe_0x0000[0x040/4];
@@ -414,9 +413,9 @@
 
 static void nv10_graph_save_pipe(struct nouveau_channel *chan)
 {
-	struct drm_device *dev = chan->dev;
-	struct graph_state *pgraph_ctx = chan->pgraph_ctx;
+	struct graph_state *pgraph_ctx = chan->engctx[NVOBJ_ENGINE_GR];
 	struct pipe_state *pipe = &pgraph_ctx->pipe_state;
+	struct drm_device *dev = chan->dev;
 
 	PIPE_SAVE(dev, pipe->pipe_0x4400, 0x4400);
 	PIPE_SAVE(dev, pipe->pipe_0x0200, 0x0200);
@@ -432,9 +431,9 @@
 
 static void nv10_graph_load_pipe(struct nouveau_channel *chan)
 {
-	struct drm_device *dev = chan->dev;
-	struct graph_state *pgraph_ctx = chan->pgraph_ctx;
+	struct graph_state *pgraph_ctx = chan->engctx[NVOBJ_ENGINE_GR];
 	struct pipe_state *pipe = &pgraph_ctx->pipe_state;
+	struct drm_device *dev = chan->dev;
 	uint32_t xfmode0, xfmode1;
 	int i;
 
@@ -482,9 +481,9 @@
 
 static void nv10_graph_create_pipe(struct nouveau_channel *chan)
 {
-	struct drm_device *dev = chan->dev;
-	struct graph_state *pgraph_ctx = chan->pgraph_ctx;
+	struct graph_state *pgraph_ctx = chan->engctx[NVOBJ_ENGINE_GR];
 	struct pipe_state *fifo_pipe_state = &pgraph_ctx->pipe_state;
+	struct drm_device *dev = chan->dev;
 	uint32_t *fifo_pipe_state_addr;
 	int i;
 #define PIPE_INIT(addr) \
@@ -661,8 +660,6 @@
 				       uint32_t inst)
 {
 	struct drm_device *dev = chan->dev;
-	struct drm_nouveau_private *dev_priv = dev->dev_private;
-	struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph;
 	uint32_t st2, st2_dl, st2_dh, fifo_ptr, fifo[0x60/4];
 	uint32_t ctx_user, ctx_switch[5];
 	int i, subchan = -1;
@@ -711,8 +708,8 @@
 		0x2c000000 | chan->id << 20 | subchan << 16 | 0x18c);
 	nv_wr32(dev, NV10_PGRAPH_FFINTFC_ST2_DL, inst);
 	nv_mask(dev, NV10_PGRAPH_CTX_CONTROL, 0, 0x10000);
-	pgraph->fifo_access(dev, true);
-	pgraph->fifo_access(dev, false);
+	nv04_graph_fifo_access(dev, true);
+	nv04_graph_fifo_access(dev, false);
 
 	/* Restore the FIFO state */
 	for (i = 0; i < ARRAY_SIZE(fifo); i++)
@@ -729,11 +726,12 @@
 	nv_wr32(dev, NV10_PGRAPH_CTX_USER, ctx_user);
 }
 
-int nv10_graph_load_context(struct nouveau_channel *chan)
+static int
+nv10_graph_load_context(struct nouveau_channel *chan)
 {
 	struct drm_device *dev = chan->dev;
 	struct drm_nouveau_private *dev_priv = dev->dev_private;
-	struct graph_state *pgraph_ctx = chan->pgraph_ctx;
+	struct graph_state *pgraph_ctx = chan->engctx[NVOBJ_ENGINE_GR];
 	uint32_t tmp;
 	int i;
 
@@ -757,21 +755,20 @@
 	return 0;
 }
 
-int
+static int
 nv10_graph_unload_context(struct drm_device *dev)
 {
 	struct drm_nouveau_private *dev_priv = dev->dev_private;
-	struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph;
 	struct nouveau_fifo_engine *pfifo = &dev_priv->engine.fifo;
 	struct nouveau_channel *chan;
 	struct graph_state *ctx;
 	uint32_t tmp;
 	int i;
 
-	chan = pgraph->channel(dev);
+	chan = nv10_graph_channel(dev);
 	if (!chan)
 		return 0;
-	ctx = chan->pgraph_ctx;
+	ctx = chan->engctx[NVOBJ_ENGINE_GR];
 
 	for (i = 0; i < ARRAY_SIZE(nv10_graph_ctx_regs); i++)
 		ctx->nv10[i] = nv_rd32(dev, nv10_graph_ctx_regs[i]);
@@ -805,7 +802,7 @@
 	/* Load context for next channel */
 	chid = (nv_rd32(dev, NV04_PGRAPH_TRAPPED_ADDR) >> 20) & 0x1f;
 	chan = dev_priv->channels.ptr[chid];
-	if (chan && chan->pgraph_ctx)
+	if (chan && chan->engctx[NVOBJ_ENGINE_GR])
 		nv10_graph_load_context(chan);
 }
 
@@ -836,7 +833,8 @@
 	return dev_priv->channels.ptr[chid];
 }
 
-int nv10_graph_create_context(struct nouveau_channel *chan)
+static int
+nv10_graph_context_new(struct nouveau_channel *chan, int engine)
 {
 	struct drm_device *dev = chan->dev;
 	struct drm_nouveau_private *dev_priv = dev->dev_private;
@@ -844,11 +842,10 @@
 
 	NV_DEBUG(dev, "nv10_graph_context_create %d\n", chan->id);
 
-	chan->pgraph_ctx = pgraph_ctx = kzalloc(sizeof(*pgraph_ctx),
-						GFP_KERNEL);
+	pgraph_ctx = kzalloc(sizeof(*pgraph_ctx), GFP_KERNEL);
 	if (pgraph_ctx == NULL)
 		return -ENOMEM;
-
+	chan->engctx[engine] = pgraph_ctx;
 
 	NV_WRITE_CTX(0x00400e88, 0x08000000);
 	NV_WRITE_CTX(0x00400e9c, 0x4b7fffff);
@@ -873,30 +870,30 @@
 	return 0;
 }
 
-void nv10_graph_destroy_context(struct nouveau_channel *chan)
+static void
+nv10_graph_context_del(struct nouveau_channel *chan, int engine)
 {
 	struct drm_device *dev = chan->dev;
 	struct drm_nouveau_private *dev_priv = dev->dev_private;
-	struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph;
-	struct graph_state *pgraph_ctx = chan->pgraph_ctx;
+	struct graph_state *pgraph_ctx = chan->engctx[engine];
 	unsigned long flags;
 
 	spin_lock_irqsave(&dev_priv->context_switch_lock, flags);
-	pgraph->fifo_access(dev, false);
+	nv04_graph_fifo_access(dev, false);
 
 	/* Unload the context if it's the currently active one */
-	if (pgraph->channel(dev) == chan)
-		pgraph->unload_context(dev);
+	if (nv10_graph_channel(dev) == chan)
+		nv10_graph_unload_context(dev);
+
+	nv04_graph_fifo_access(dev, true);
+	spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags);
 
 	/* Free the context resources */
+	chan->engctx[engine] = NULL;
 	kfree(pgraph_ctx);
-	chan->pgraph_ctx = NULL;
-
-	pgraph->fifo_access(dev, true);
-	spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags);
 }
 
-void
+static void
 nv10_graph_set_tile_region(struct drm_device *dev, int i)
 {
 	struct drm_nouveau_private *dev_priv = dev->dev_private;
@@ -907,22 +904,18 @@
 	nv_wr32(dev, NV10_PGRAPH_TILE(i), tile->addr);
 }
 
-int nv10_graph_init(struct drm_device *dev)
+static int
+nv10_graph_init(struct drm_device *dev, int engine)
 {
 	struct drm_nouveau_private *dev_priv = dev->dev_private;
-	uint32_t tmp;
-	int ret, i;
+	u32 tmp;
+	int i;
 
 	nv_wr32(dev, NV03_PMC_ENABLE, nv_rd32(dev, NV03_PMC_ENABLE) &
 			~NV_PMC_ENABLE_PGRAPH);
 	nv_wr32(dev, NV03_PMC_ENABLE, nv_rd32(dev, NV03_PMC_ENABLE) |
 			 NV_PMC_ENABLE_PGRAPH);
 
-	ret = nv10_graph_register(dev);
-	if (ret)
-		return ret;
-
-	nouveau_irq_register(dev, 12, nv10_graph_isr);
 	nv_wr32(dev, NV03_PGRAPH_INTR   , 0xFFFFFFFF);
 	nv_wr32(dev, NV03_PGRAPH_INTR_EN, 0xFFFFFFFF);
 
@@ -963,18 +956,20 @@
 	return 0;
 }
 
-void nv10_graph_takedown(struct drm_device *dev)
+static int
+nv10_graph_fini(struct drm_device *dev, int engine)
 {
+	nv10_graph_unload_context(dev);
 	nv_wr32(dev, NV03_PGRAPH_INTR_EN, 0x00000000);
-	nouveau_irq_unregister(dev, 12);
+	return 0;
 }
 
 static int
 nv17_graph_mthd_lma_window(struct nouveau_channel *chan,
 			   u32 class, u32 mthd, u32 data)
 {
+	struct graph_state *ctx = chan->engctx[NVOBJ_ENGINE_GR];
 	struct drm_device *dev = chan->dev;
-	struct graph_state *ctx = chan->pgraph_ctx;
 	struct pipe_state *pipe = &ctx->pipe_state;
 	uint32_t pipe_0x0040[1], pipe_0x64c0[8], pipe_0x6a80[3], pipe_0x6ab0[3];
 	uint32_t xfmode0, xfmode1;
@@ -1061,64 +1056,13 @@
 	return 0;
 }
 
-static int
-nv10_graph_register(struct drm_device *dev)
-{
-	struct drm_nouveau_private *dev_priv = dev->dev_private;
-
-	if (dev_priv->engine.graph.registered)
-		return 0;
-
-	NVOBJ_CLASS(dev, 0x506e, SW); /* nvsw */
-	NVOBJ_CLASS(dev, 0x0030, GR); /* null */
-	NVOBJ_CLASS(dev, 0x0039, GR); /* m2mf */
-	NVOBJ_CLASS(dev, 0x004a, GR); /* gdirect */
-	NVOBJ_CLASS(dev, 0x005f, GR); /* imageblit */
-	NVOBJ_CLASS(dev, 0x009f, GR); /* imageblit (nv12) */
-	NVOBJ_CLASS(dev, 0x008a, GR); /* ifc */
-	NVOBJ_CLASS(dev, 0x0089, GR); /* sifm */
-	NVOBJ_CLASS(dev, 0x0062, GR); /* surf2d */
-	NVOBJ_CLASS(dev, 0x0043, GR); /* rop */
-	NVOBJ_CLASS(dev, 0x0012, GR); /* beta1 */
-	NVOBJ_CLASS(dev, 0x0072, GR); /* beta4 */
-	NVOBJ_CLASS(dev, 0x0019, GR); /* cliprect */
-	NVOBJ_CLASS(dev, 0x0044, GR); /* pattern */
-	NVOBJ_CLASS(dev, 0x0052, GR); /* swzsurf */
-	NVOBJ_CLASS(dev, 0x0093, GR); /* surf3d */
-	NVOBJ_CLASS(dev, 0x0094, GR); /* tex_tri */
-	NVOBJ_CLASS(dev, 0x0095, GR); /* multitex_tri */
-
-	/* celcius */
-	if (dev_priv->chipset <= 0x10) {
-		NVOBJ_CLASS(dev, 0x0056, GR);
-	} else
-	if (dev_priv->chipset < 0x17 || dev_priv->chipset == 0x1a) {
-		NVOBJ_CLASS(dev, 0x0096, GR);
-	} else {
-		NVOBJ_CLASS(dev, 0x0099, GR);
-		NVOBJ_MTHD (dev, 0x0099, 0x1638, nv17_graph_mthd_lma_window);
-		NVOBJ_MTHD (dev, 0x0099, 0x163c, nv17_graph_mthd_lma_window);
-		NVOBJ_MTHD (dev, 0x0099, 0x1640, nv17_graph_mthd_lma_window);
-		NVOBJ_MTHD (dev, 0x0099, 0x1644, nv17_graph_mthd_lma_window);
-		NVOBJ_MTHD (dev, 0x0099, 0x1658, nv17_graph_mthd_lma_enable);
-	}
-
-	/* nvsw */
-	NVOBJ_CLASS(dev, 0x506e, SW);
-	NVOBJ_MTHD (dev, 0x506e, 0x0500, nv04_graph_mthd_page_flip);
-
-	dev_priv->engine.graph.registered = true;
-	return 0;
-}
-
 struct nouveau_bitfield nv10_graph_intr[] = {
 	{ NV_PGRAPH_INTR_NOTIFY, "NOTIFY" },
 	{ NV_PGRAPH_INTR_ERROR,  "ERROR"  },
 	{}
 };
 
-struct nouveau_bitfield nv10_graph_nstatus[] =
-{
+struct nouveau_bitfield nv10_graph_nstatus[] = {
 	{ NV10_PGRAPH_NSTATUS_STATE_IN_USE,       "STATE_IN_USE" },
 	{ NV10_PGRAPH_NSTATUS_INVALID_STATE,      "INVALID_STATE" },
 	{ NV10_PGRAPH_NSTATUS_BAD_ARGUMENT,       "BAD_ARGUMENT" },
@@ -1173,3 +1117,73 @@
 		}
 	}
 }
+
+static void
+nv10_graph_destroy(struct drm_device *dev, int engine)
+{
+	struct nv10_graph_engine *pgraph = nv_engine(dev, engine);
+
+	nouveau_irq_unregister(dev, 12);
+	kfree(pgraph);
+}
+
+int
+nv10_graph_create(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nv10_graph_engine *pgraph;
+
+	pgraph = kzalloc(sizeof(*pgraph), GFP_KERNEL);
+	if (!pgraph)
+		return -ENOMEM;
+
+	pgraph->base.destroy = nv10_graph_destroy;
+	pgraph->base.init = nv10_graph_init;
+	pgraph->base.fini = nv10_graph_fini;
+	pgraph->base.context_new = nv10_graph_context_new;
+	pgraph->base.context_del = nv10_graph_context_del;
+	pgraph->base.object_new = nv04_graph_object_new;
+	pgraph->base.set_tile_region = nv10_graph_set_tile_region;
+
+	NVOBJ_ENGINE_ADD(dev, GR, &pgraph->base);
+	nouveau_irq_register(dev, 12, nv10_graph_isr);
+
+	/* nvsw */
+	NVOBJ_CLASS(dev, 0x506e, SW);
+	NVOBJ_MTHD (dev, 0x506e, 0x0500, nv04_graph_mthd_page_flip);
+
+	NVOBJ_CLASS(dev, 0x0030, GR); /* null */
+	NVOBJ_CLASS(dev, 0x0039, GR); /* m2mf */
+	NVOBJ_CLASS(dev, 0x004a, GR); /* gdirect */
+	NVOBJ_CLASS(dev, 0x005f, GR); /* imageblit */
+	NVOBJ_CLASS(dev, 0x009f, GR); /* imageblit (nv12) */
+	NVOBJ_CLASS(dev, 0x008a, GR); /* ifc */
+	NVOBJ_CLASS(dev, 0x0089, GR); /* sifm */
+	NVOBJ_CLASS(dev, 0x0062, GR); /* surf2d */
+	NVOBJ_CLASS(dev, 0x0043, GR); /* rop */
+	NVOBJ_CLASS(dev, 0x0012, GR); /* beta1 */
+	NVOBJ_CLASS(dev, 0x0072, GR); /* beta4 */
+	NVOBJ_CLASS(dev, 0x0019, GR); /* cliprect */
+	NVOBJ_CLASS(dev, 0x0044, GR); /* pattern */
+	NVOBJ_CLASS(dev, 0x0052, GR); /* swzsurf */
+	NVOBJ_CLASS(dev, 0x0093, GR); /* surf3d */
+	NVOBJ_CLASS(dev, 0x0094, GR); /* tex_tri */
+	NVOBJ_CLASS(dev, 0x0095, GR); /* multitex_tri */
+
+	/* celcius */
+	if (dev_priv->chipset <= 0x10) {
+		NVOBJ_CLASS(dev, 0x0056, GR);
+	} else
+	if (dev_priv->chipset < 0x17 || dev_priv->chipset == 0x1a) {
+		NVOBJ_CLASS(dev, 0x0096, GR);
+	} else {
+		NVOBJ_CLASS(dev, 0x0099, GR);
+		NVOBJ_MTHD (dev, 0x0099, 0x1638, nv17_graph_mthd_lma_window);
+		NVOBJ_MTHD (dev, 0x0099, 0x163c, nv17_graph_mthd_lma_window);
+		NVOBJ_MTHD (dev, 0x0099, 0x1640, nv17_graph_mthd_lma_window);
+		NVOBJ_MTHD (dev, 0x0099, 0x1644, nv17_graph_mthd_lma_window);
+		NVOBJ_MTHD (dev, 0x0099, 0x1658, nv17_graph_mthd_lma_enable);
+	}
+
+	return 0;
+}
diff -druN linux-2.6.39-libre/drivers/gpu/drm/nouveau/nv20_graph.c linux-3.0-rc7-libre/drivers/gpu/drm/nouveau/nv20_graph.c
--- linux-2.6.39-libre/drivers/gpu/drm/nouveau/nv20_graph.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/gpu/drm/nouveau/nv20_graph.c	2011-07-11 19:51:52.000000000 -0400
@@ -24,6 +24,14 @@
  *
  */
 
+struct nv20_graph_engine {
+	struct nouveau_exec_engine base;
+	struct nouveau_gpuobj *ctxtab;
+	void (*grctx_init)(struct nouveau_gpuobj *);
+	u32 grctx_size;
+	u32 grctx_user;
+};
+
 #define NV20_GRCTX_SIZE (3580*4)
 #define NV25_GRCTX_SIZE (3529*4)
 #define NV2A_GRCTX_SIZE (3500*4)
@@ -32,12 +40,54 @@
 #define NV34_GRCTX_SIZE    (18140)
 #define NV35_36_GRCTX_SIZE (22396)
 
-static int nv20_graph_register(struct drm_device *);
-static int nv30_graph_register(struct drm_device *);
-static void nv20_graph_isr(struct drm_device *);
+int
+nv20_graph_unload_context(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_fifo_engine *pfifo = &dev_priv->engine.fifo;
+	struct nouveau_channel *chan;
+	struct nouveau_gpuobj *grctx;
+	u32 tmp;
+
+	chan = nv10_graph_channel(dev);
+	if (!chan)
+		return 0;
+	grctx = chan->engctx[NVOBJ_ENGINE_GR];
+
+	nv_wr32(dev, NV20_PGRAPH_CHANNEL_CTX_POINTER, grctx->pinst >> 4);
+	nv_wr32(dev, NV20_PGRAPH_CHANNEL_CTX_XFER,
+		     NV20_PGRAPH_CHANNEL_CTX_XFER_SAVE);
+
+	nouveau_wait_for_idle(dev);
+
+	nv_wr32(dev, NV10_PGRAPH_CTX_CONTROL, 0x10000000);
+	tmp  = nv_rd32(dev, NV10_PGRAPH_CTX_USER) & 0x00ffffff;
+	tmp |= (pfifo->channels - 1) << 24;
+	nv_wr32(dev, NV10_PGRAPH_CTX_USER, tmp);
+	return 0;
+}
 
 static void
-nv20_graph_context_init(struct drm_device *dev, struct nouveau_gpuobj *ctx)
+nv20_graph_rdi(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	int i, writecount = 32;
+	uint32_t rdi_index = 0x2c80000;
+
+	if (dev_priv->chipset == 0x20) {
+		rdi_index = 0x3d0000;
+		writecount = 15;
+	}
+
+	nv_wr32(dev, NV10_PGRAPH_RDI_INDEX, rdi_index);
+	for (i = 0; i < writecount; i++)
+		nv_wr32(dev, NV10_PGRAPH_RDI_DATA, 0);
+
+	nouveau_wait_for_idle(dev);
+}
+
+static void
+nv20_graph_context_init(struct nouveau_gpuobj *ctx)
 {
 	int i;
 
@@ -87,7 +137,7 @@
 }
 
 static void
-nv25_graph_context_init(struct drm_device *dev, struct nouveau_gpuobj *ctx)
+nv25_graph_context_init(struct nouveau_gpuobj *ctx)
 {
 	int i;
 
@@ -146,7 +196,7 @@
 }
 
 static void
-nv2a_graph_context_init(struct drm_device *dev, struct nouveau_gpuobj *ctx)
+nv2a_graph_context_init(struct nouveau_gpuobj *ctx)
 {
 	int i;
 
@@ -196,7 +246,7 @@
 }
 
 static void
-nv30_31_graph_context_init(struct drm_device *dev, struct nouveau_gpuobj *ctx)
+nv30_31_graph_context_init(struct nouveau_gpuobj *ctx)
 {
 	int i;
 
@@ -254,7 +304,7 @@
 }
 
 static void
-nv34_graph_context_init(struct drm_device *dev, struct nouveau_gpuobj *ctx)
+nv34_graph_context_init(struct nouveau_gpuobj *ctx)
 {
 	int i;
 
@@ -312,7 +362,7 @@
 }
 
 static void
-nv35_36_graph_context_init(struct drm_device *dev, struct nouveau_gpuobj *ctx)
+nv35_36_graph_context_init(struct nouveau_gpuobj *ctx)
 {
 	int i;
 
@@ -370,148 +420,57 @@
 }
 
 int
-nv20_graph_create_context(struct nouveau_channel *chan)
+nv20_graph_context_new(struct nouveau_channel *chan, int engine)
 {
+	struct nv20_graph_engine *pgraph = nv_engine(chan->dev, engine);
+	struct nouveau_gpuobj *grctx = NULL;
 	struct drm_device *dev = chan->dev;
-	struct drm_nouveau_private *dev_priv = dev->dev_private;
-	struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph;
-	void (*ctx_init)(struct drm_device *, struct nouveau_gpuobj *);
-	unsigned int idoffs = 0x28;
 	int ret;
 
-	switch (dev_priv->chipset) {
-	case 0x20:
-		ctx_init = nv20_graph_context_init;
-		idoffs = 0;
-		break;
-	case 0x25:
-	case 0x28:
-		ctx_init = nv25_graph_context_init;
-		break;
-	case 0x2a:
-		ctx_init = nv2a_graph_context_init;
-		idoffs = 0;
-		break;
-	case 0x30:
-	case 0x31:
-		ctx_init = nv30_31_graph_context_init;
-		break;
-	case 0x34:
-		ctx_init = nv34_graph_context_init;
-		break;
-	case 0x35:
-	case 0x36:
-		ctx_init = nv35_36_graph_context_init;
-		break;
-	default:
-		BUG_ON(1);
-	}
-
-	ret = nouveau_gpuobj_new(dev, chan, pgraph->grctx_size, 16,
-				 NVOBJ_FLAG_ZERO_ALLOC, &chan->ramin_grctx);
+	ret = nouveau_gpuobj_new(dev, NULL, pgraph->grctx_size, 16,
+				 NVOBJ_FLAG_ZERO_ALLOC, &grctx);
 	if (ret)
 		return ret;
 
 	/* Initialise default context values */
-	ctx_init(dev, chan->ramin_grctx);
+	pgraph->grctx_init(grctx);
 
 	/* nv20: nv_wo32(dev, chan->ramin_grctx->gpuobj, 10, chan->id<<24); */
-	nv_wo32(chan->ramin_grctx, idoffs,
-		(chan->id << 24) | 0x1); /* CTX_USER */
+	/* CTX_USER */
+	nv_wo32(grctx, pgraph->grctx_user, (chan->id << 24) | 0x1);
 
-	nv_wo32(pgraph->ctx_table, chan->id * 4, chan->ramin_grctx->pinst >> 4);
+	nv_wo32(pgraph->ctxtab, chan->id * 4, grctx->pinst >> 4);
+	chan->engctx[engine] = grctx;
 	return 0;
 }
 
 void
-nv20_graph_destroy_context(struct nouveau_channel *chan)
+nv20_graph_context_del(struct nouveau_channel *chan, int engine)
 {
+	struct nv20_graph_engine *pgraph = nv_engine(chan->dev, engine);
+	struct nouveau_gpuobj *grctx = chan->engctx[engine];
 	struct drm_device *dev = chan->dev;
 	struct drm_nouveau_private *dev_priv = dev->dev_private;
-	struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph;
 	unsigned long flags;
 
 	spin_lock_irqsave(&dev_priv->context_switch_lock, flags);
-	pgraph->fifo_access(dev, false);
+	nv04_graph_fifo_access(dev, false);
 
 	/* Unload the context if it's the currently active one */
-	if (pgraph->channel(dev) == chan)
-		pgraph->unload_context(dev);
+	if (nv10_graph_channel(dev) == chan)
+		nv20_graph_unload_context(dev);
 
-	pgraph->fifo_access(dev, true);
+	nv04_graph_fifo_access(dev, true);
 	spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags);
 
 	/* Free the context resources */
-	nv_wo32(pgraph->ctx_table, chan->id * 4, 0);
-	nouveau_gpuobj_ref(NULL, &chan->ramin_grctx);
-}
-
-int
-nv20_graph_load_context(struct nouveau_channel *chan)
-{
-	struct drm_device *dev = chan->dev;
-	uint32_t inst;
-
-	if (!chan->ramin_grctx)
-		return -EINVAL;
-	inst = chan->ramin_grctx->pinst >> 4;
-
-	nv_wr32(dev, NV20_PGRAPH_CHANNEL_CTX_POINTER, inst);
-	nv_wr32(dev, NV20_PGRAPH_CHANNEL_CTX_XFER,
-		     NV20_PGRAPH_CHANNEL_CTX_XFER_LOAD);
-	nv_wr32(dev, NV10_PGRAPH_CTX_CONTROL, 0x10010100);
-
-	nouveau_wait_for_idle(dev);
-	return 0;
-}
-
-int
-nv20_graph_unload_context(struct drm_device *dev)
-{
-	struct drm_nouveau_private *dev_priv = dev->dev_private;
-	struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph;
-	struct nouveau_fifo_engine *pfifo = &dev_priv->engine.fifo;
-	struct nouveau_channel *chan;
-	uint32_t inst, tmp;
-
-	chan = pgraph->channel(dev);
-	if (!chan)
-		return 0;
-	inst = chan->ramin_grctx->pinst >> 4;
-
-	nv_wr32(dev, NV20_PGRAPH_CHANNEL_CTX_POINTER, inst);
-	nv_wr32(dev, NV20_PGRAPH_CHANNEL_CTX_XFER,
-		     NV20_PGRAPH_CHANNEL_CTX_XFER_SAVE);
-
-	nouveau_wait_for_idle(dev);
+	nv_wo32(pgraph->ctxtab, chan->id * 4, 0);
 
-	nv_wr32(dev, NV10_PGRAPH_CTX_CONTROL, 0x10000000);
-	tmp  = nv_rd32(dev, NV10_PGRAPH_CTX_USER) & 0x00ffffff;
-	tmp |= (pfifo->channels - 1) << 24;
-	nv_wr32(dev, NV10_PGRAPH_CTX_USER, tmp);
-	return 0;
+	nouveau_gpuobj_ref(NULL, &grctx);
+	chan->engctx[engine] = NULL;
 }
 
 static void
-nv20_graph_rdi(struct drm_device *dev)
-{
-	struct drm_nouveau_private *dev_priv = dev->dev_private;
-	int i, writecount = 32;
-	uint32_t rdi_index = 0x2c80000;
-
-	if (dev_priv->chipset == 0x20) {
-		rdi_index = 0x3d0000;
-		writecount = 15;
-	}
-
-	nv_wr32(dev, NV10_PGRAPH_RDI_INDEX, rdi_index);
-	for (i = 0; i < writecount; i++)
-		nv_wr32(dev, NV10_PGRAPH_RDI_DATA, 0);
-
-	nouveau_wait_for_idle(dev);
-}
-
-void
 nv20_graph_set_tile_region(struct drm_device *dev, int i)
 {
 	struct drm_nouveau_private *dev_priv = dev->dev_private;
@@ -536,56 +495,22 @@
 }
 
 int
-nv20_graph_init(struct drm_device *dev)
+nv20_graph_init(struct drm_device *dev, int engine)
 {
+	struct nv20_graph_engine *pgraph = nv_engine(dev, engine);
 	struct drm_nouveau_private *dev_priv = dev->dev_private;
-	struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph;
 	uint32_t tmp, vramsz;
-	int ret, i;
-
-	switch (dev_priv->chipset) {
-	case 0x20:
-		pgraph->grctx_size = NV20_GRCTX_SIZE;
-		break;
-	case 0x25:
-	case 0x28:
-		pgraph->grctx_size = NV25_GRCTX_SIZE;
-		break;
-	case 0x2a:
-		pgraph->grctx_size = NV2A_GRCTX_SIZE;
-		break;
-	default:
-		NV_ERROR(dev, "unknown chipset, disabling acceleration\n");
-		pgraph->accel_blocked = true;
-		return 0;
-	}
+	int i;
 
 	nv_wr32(dev, NV03_PMC_ENABLE,
 		nv_rd32(dev, NV03_PMC_ENABLE) & ~NV_PMC_ENABLE_PGRAPH);
 	nv_wr32(dev, NV03_PMC_ENABLE,
 		nv_rd32(dev, NV03_PMC_ENABLE) |  NV_PMC_ENABLE_PGRAPH);
 
-	if (!pgraph->ctx_table) {
-		/* Create Context Pointer Table */
-		ret = nouveau_gpuobj_new(dev, NULL, 32 * 4, 16,
-					 NVOBJ_FLAG_ZERO_ALLOC,
-					 &pgraph->ctx_table);
-		if (ret)
-			return ret;
-	}
-
-	nv_wr32(dev, NV20_PGRAPH_CHANNEL_CTX_TABLE,
-		     pgraph->ctx_table->pinst >> 4);
+	nv_wr32(dev, NV20_PGRAPH_CHANNEL_CTX_TABLE, pgraph->ctxtab->pinst >> 4);
 
 	nv20_graph_rdi(dev);
 
-	ret = nv20_graph_register(dev);
-	if (ret) {
-		nouveau_gpuobj_ref(NULL, &pgraph->ctx_table);
-		return ret;
-	}
-
-	nouveau_irq_register(dev, 12, nv20_graph_isr);
 	nv_wr32(dev, NV03_PGRAPH_INTR   , 0xFFFFFFFF);
 	nv_wr32(dev, NV03_PGRAPH_INTR_EN, 0xFFFFFFFF);
 
@@ -657,67 +582,20 @@
 	return 0;
 }
 
-void
-nv20_graph_takedown(struct drm_device *dev)
-{
-	struct drm_nouveau_private *dev_priv = dev->dev_private;
-	struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph;
-
-	nv_wr32(dev, NV03_PGRAPH_INTR_EN, 0x00000000);
-	nouveau_irq_unregister(dev, 12);
-
-	nouveau_gpuobj_ref(NULL, &pgraph->ctx_table);
-}
-
 int
-nv30_graph_init(struct drm_device *dev)
+nv30_graph_init(struct drm_device *dev, int engine)
 {
+	struct nv20_graph_engine *pgraph = nv_engine(dev, engine);
 	struct drm_nouveau_private *dev_priv = dev->dev_private;
-	struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph;
-	int ret, i;
-
-	switch (dev_priv->chipset) {
-	case 0x30:
-	case 0x31:
-		pgraph->grctx_size = NV30_31_GRCTX_SIZE;
-		break;
-	case 0x34:
-		pgraph->grctx_size = NV34_GRCTX_SIZE;
-		break;
-	case 0x35:
-	case 0x36:
-		pgraph->grctx_size = NV35_36_GRCTX_SIZE;
-		break;
-	default:
-		NV_ERROR(dev, "unknown chipset, disabling acceleration\n");
-		pgraph->accel_blocked = true;
-		return 0;
-	}
+	int i;
 
 	nv_wr32(dev, NV03_PMC_ENABLE,
 		nv_rd32(dev, NV03_PMC_ENABLE) & ~NV_PMC_ENABLE_PGRAPH);
 	nv_wr32(dev, NV03_PMC_ENABLE,
 		nv_rd32(dev, NV03_PMC_ENABLE) |  NV_PMC_ENABLE_PGRAPH);
 
-	if (!pgraph->ctx_table) {
-		/* Create Context Pointer Table */
-		ret = nouveau_gpuobj_new(dev, NULL, 32 * 4, 16,
-					 NVOBJ_FLAG_ZERO_ALLOC,
-					 &pgraph->ctx_table);
-		if (ret)
-			return ret;
-	}
-
-	ret = nv30_graph_register(dev);
-	if (ret) {
-		nouveau_gpuobj_ref(NULL, &pgraph->ctx_table);
-		return ret;
-	}
-
-	nv_wr32(dev, NV20_PGRAPH_CHANNEL_CTX_TABLE,
-		     pgraph->ctx_table->pinst >> 4);
+	nv_wr32(dev, NV20_PGRAPH_CHANNEL_CTX_TABLE, pgraph->ctxtab->pinst >> 4);
 
-	nouveau_irq_register(dev, 12, nv20_graph_isr);
 	nv_wr32(dev, NV03_PGRAPH_INTR   , 0xFFFFFFFF);
 	nv_wr32(dev, NV03_PGRAPH_INTR_EN, 0xFFFFFFFF);
 
@@ -775,85 +653,11 @@
 	return 0;
 }
 
-static int
-nv20_graph_register(struct drm_device *dev)
-{
-	struct drm_nouveau_private *dev_priv = dev->dev_private;
-
-	if (dev_priv->engine.graph.registered)
-		return 0;
-
-	NVOBJ_CLASS(dev, 0x506e, SW); /* nvsw */
-	NVOBJ_CLASS(dev, 0x0030, GR); /* null */
-	NVOBJ_CLASS(dev, 0x0039, GR); /* m2mf */
-	NVOBJ_CLASS(dev, 0x004a, GR); /* gdirect */
-	NVOBJ_CLASS(dev, 0x009f, GR); /* imageblit (nv12) */
-	NVOBJ_CLASS(dev, 0x008a, GR); /* ifc */
-	NVOBJ_CLASS(dev, 0x0089, GR); /* sifm */
-	NVOBJ_CLASS(dev, 0x0062, GR); /* surf2d */
-	NVOBJ_CLASS(dev, 0x0043, GR); /* rop */
-	NVOBJ_CLASS(dev, 0x0012, GR); /* beta1 */
-	NVOBJ_CLASS(dev, 0x0072, GR); /* beta4 */
-	NVOBJ_CLASS(dev, 0x0019, GR); /* cliprect */
-	NVOBJ_CLASS(dev, 0x0044, GR); /* pattern */
-	NVOBJ_CLASS(dev, 0x009e, GR); /* swzsurf */
-	NVOBJ_CLASS(dev, 0x0096, GR); /* celcius */
-
-	/* kelvin */
-	if (dev_priv->chipset < 0x25)
-		NVOBJ_CLASS(dev, 0x0097, GR);
-	else
-		NVOBJ_CLASS(dev, 0x0597, GR);
-
-	/* nvsw */
-	NVOBJ_CLASS(dev, 0x506e, SW);
-	NVOBJ_MTHD (dev, 0x506e, 0x0500, nv04_graph_mthd_page_flip);
-
-	dev_priv->engine.graph.registered = true;
-	return 0;
-}
-
-static int
-nv30_graph_register(struct drm_device *dev)
+int
+nv20_graph_fini(struct drm_device *dev, int engine)
 {
-	struct drm_nouveau_private *dev_priv = dev->dev_private;
-
-	if (dev_priv->engine.graph.registered)
-		return 0;
-
-	NVOBJ_CLASS(dev, 0x506e, SW); /* nvsw */
-	NVOBJ_CLASS(dev, 0x0030, GR); /* null */
-	NVOBJ_CLASS(dev, 0x0039, GR); /* m2mf */
-	NVOBJ_CLASS(dev, 0x004a, GR); /* gdirect */
-	NVOBJ_CLASS(dev, 0x009f, GR); /* imageblit (nv12) */
-	NVOBJ_CLASS(dev, 0x008a, GR); /* ifc */
-	NVOBJ_CLASS(dev, 0x038a, GR); /* ifc (nv30) */
-	NVOBJ_CLASS(dev, 0x0089, GR); /* sifm */
-	NVOBJ_CLASS(dev, 0x0389, GR); /* sifm (nv30) */
-	NVOBJ_CLASS(dev, 0x0062, GR); /* surf2d */
-	NVOBJ_CLASS(dev, 0x0362, GR); /* surf2d (nv30) */
-	NVOBJ_CLASS(dev, 0x0043, GR); /* rop */
-	NVOBJ_CLASS(dev, 0x0012, GR); /* beta1 */
-	NVOBJ_CLASS(dev, 0x0072, GR); /* beta4 */
-	NVOBJ_CLASS(dev, 0x0019, GR); /* cliprect */
-	NVOBJ_CLASS(dev, 0x0044, GR); /* pattern */
-	NVOBJ_CLASS(dev, 0x039e, GR); /* swzsurf */
-
-	/* rankine */
-	if (0x00000003 & (1 << (dev_priv->chipset & 0x0f)))
-		NVOBJ_CLASS(dev, 0x0397, GR);
-	else
-	if (0x00000010 & (1 << (dev_priv->chipset & 0x0f)))
-		NVOBJ_CLASS(dev, 0x0697, GR);
-	else
-	if (0x000001e0 & (1 << (dev_priv->chipset & 0x0f)))
-		NVOBJ_CLASS(dev, 0x0497, GR);
-
-	/* nvsw */
-	NVOBJ_CLASS(dev, 0x506e, SW);
-	NVOBJ_MTHD (dev, 0x506e, 0x0500, nv04_graph_mthd_page_flip);
-
-	dev_priv->engine.graph.registered = true;
+	nv20_graph_unload_context(dev);
+	nv_wr32(dev, NV03_PGRAPH_INTR_EN, 0x00000000);
 	return 0;
 }
 
@@ -897,3 +701,135 @@
 		}
 	}
 }
+
+static void
+nv20_graph_destroy(struct drm_device *dev, int engine)
+{
+	struct nv20_graph_engine *pgraph = nv_engine(dev, engine);
+
+	nouveau_irq_unregister(dev, 12);
+	nouveau_gpuobj_ref(NULL, &pgraph->ctxtab);
+
+	NVOBJ_ENGINE_DEL(dev, GR);
+	kfree(pgraph);
+}
+
+int
+nv20_graph_create(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nv20_graph_engine *pgraph;
+	int ret;
+
+	pgraph = kzalloc(sizeof(*pgraph), GFP_KERNEL);
+	if (!pgraph)
+		return -ENOMEM;
+
+	pgraph->base.destroy = nv20_graph_destroy;
+	pgraph->base.fini = nv20_graph_fini;
+	pgraph->base.context_new = nv20_graph_context_new;
+	pgraph->base.context_del = nv20_graph_context_del;
+	pgraph->base.object_new = nv04_graph_object_new;
+	pgraph->base.set_tile_region = nv20_graph_set_tile_region;
+
+	pgraph->grctx_user = 0x0028;
+	if (dev_priv->card_type == NV_20) {
+		pgraph->base.init = nv20_graph_init;
+		switch (dev_priv->chipset) {
+		case 0x20:
+			pgraph->grctx_init = nv20_graph_context_init;
+			pgraph->grctx_size = NV20_GRCTX_SIZE;
+			pgraph->grctx_user = 0x0000;
+			break;
+		case 0x25:
+		case 0x28:
+			pgraph->grctx_init = nv25_graph_context_init;
+			pgraph->grctx_size = NV25_GRCTX_SIZE;
+			break;
+		case 0x2a:
+			pgraph->grctx_init = nv2a_graph_context_init;
+			pgraph->grctx_size = NV2A_GRCTX_SIZE;
+			pgraph->grctx_user = 0x0000;
+			break;
+		default:
+			NV_ERROR(dev, "PGRAPH: unknown chipset\n");
+			return 0;
+		}
+	} else {
+		pgraph->base.init = nv30_graph_init;
+		switch (dev_priv->chipset) {
+		case 0x30:
+		case 0x31:
+			pgraph->grctx_init = nv30_31_graph_context_init;
+			pgraph->grctx_size = NV30_31_GRCTX_SIZE;
+			break;
+		case 0x34:
+			pgraph->grctx_init = nv34_graph_context_init;
+			pgraph->grctx_size = NV34_GRCTX_SIZE;
+			break;
+		case 0x35:
+		case 0x36:
+			pgraph->grctx_init = nv35_36_graph_context_init;
+			pgraph->grctx_size = NV35_36_GRCTX_SIZE;
+			break;
+		default:
+			NV_ERROR(dev, "PGRAPH: unknown chipset\n");
+			return 0;
+		}
+	}
+
+	/* Create Context Pointer Table */
+	ret = nouveau_gpuobj_new(dev, NULL, 32 * 4, 16, NVOBJ_FLAG_ZERO_ALLOC,
+				 &pgraph->ctxtab);
+	if (ret) {
+		kfree(pgraph);
+		return ret;
+	}
+
+	NVOBJ_ENGINE_ADD(dev, GR, &pgraph->base);
+	nouveau_irq_register(dev, 12, nv20_graph_isr);
+
+	/* nvsw */
+	NVOBJ_CLASS(dev, 0x506e, SW);
+	NVOBJ_MTHD (dev, 0x506e, 0x0500, nv04_graph_mthd_page_flip);
+
+	NVOBJ_CLASS(dev, 0x0030, GR); /* null */
+	NVOBJ_CLASS(dev, 0x0039, GR); /* m2mf */
+	NVOBJ_CLASS(dev, 0x004a, GR); /* gdirect */
+	NVOBJ_CLASS(dev, 0x009f, GR); /* imageblit (nv12) */
+	NVOBJ_CLASS(dev, 0x008a, GR); /* ifc */
+	NVOBJ_CLASS(dev, 0x0089, GR); /* sifm */
+	NVOBJ_CLASS(dev, 0x0062, GR); /* surf2d */
+	NVOBJ_CLASS(dev, 0x0043, GR); /* rop */
+	NVOBJ_CLASS(dev, 0x0012, GR); /* beta1 */
+	NVOBJ_CLASS(dev, 0x0072, GR); /* beta4 */
+	NVOBJ_CLASS(dev, 0x0019, GR); /* cliprect */
+	NVOBJ_CLASS(dev, 0x0044, GR); /* pattern */
+	if (dev_priv->card_type == NV_20) {
+		NVOBJ_CLASS(dev, 0x009e, GR); /* swzsurf */
+		NVOBJ_CLASS(dev, 0x0096, GR); /* celcius */
+
+		/* kelvin */
+		if (dev_priv->chipset < 0x25)
+			NVOBJ_CLASS(dev, 0x0097, GR);
+		else
+			NVOBJ_CLASS(dev, 0x0597, GR);
+	} else {
+		NVOBJ_CLASS(dev, 0x038a, GR); /* ifc (nv30) */
+		NVOBJ_CLASS(dev, 0x0389, GR); /* sifm (nv30) */
+		NVOBJ_CLASS(dev, 0x0362, GR); /* surf2d (nv30) */
+		NVOBJ_CLASS(dev, 0x039e, GR); /* swzsurf */
+
+		/* rankine */
+		if (0x00000003 & (1 << (dev_priv->chipset & 0x0f)))
+			NVOBJ_CLASS(dev, 0x0397, GR);
+		else
+		if (0x00000010 & (1 << (dev_priv->chipset & 0x0f)))
+			NVOBJ_CLASS(dev, 0x0697, GR);
+		else
+		if (0x000001e0 & (1 << (dev_priv->chipset & 0x0f)))
+			NVOBJ_CLASS(dev, 0x0497, GR);
+	}
+
+	return 0;
+}
diff -druN linux-2.6.39-libre/drivers/gpu/drm/nouveau/nv40_fifo.c linux-3.0-rc7-libre/drivers/gpu/drm/nouveau/nv40_fifo.c
--- linux-2.6.39-libre/drivers/gpu/drm/nouveau/nv40_fifo.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/gpu/drm/nouveau/nv40_fifo.c	2011-07-11 19:51:52.000000000 -0400
@@ -115,6 +115,7 @@
 	nv_wr32(dev, 0x32e8, nv_ri32(dev, fc + 68));
 	nv_wr32(dev, 0x2088, nv_ri32(dev, fc + 76));
 	nv_wr32(dev, 0x3300, nv_ri32(dev, fc + 80));
+	nv_wr32(dev, 0x330c, nv_ri32(dev, fc + 84));
 
 	nv_wr32(dev, NV03_PFIFO_CACHE1_GET, 0);
 	nv_wr32(dev, NV03_PFIFO_CACHE1_PUT, 0);
@@ -186,6 +187,7 @@
 	tmp |= (nv_rd32(dev, NV04_PFIFO_CACHE1_PUT) << 16);
 	nv_wi32(dev, fc + 72, tmp);
 #endif
+	nv_wi32(dev, fc + 84, nv_rd32(dev, 0x330c));
 
 	nv40_fifo_do_load_context(dev, pfifo->channels - 1);
 	nv_wr32(dev, NV03_PFIFO_CACHE1_PUSH1,
diff -druN linux-2.6.39-libre/drivers/gpu/drm/nouveau/nv40_graph.c linux-3.0-rc7-libre/drivers/gpu/drm/nouveau/nv40_graph.c
--- linux-2.6.39-libre/drivers/gpu/drm/nouveau/nv40_graph.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/gpu/drm/nouveau/nv40_graph.c	2011-07-11 19:51:52.000000000 -0400
@@ -28,14 +28,18 @@
 #include "drm.h"
 #include "nouveau_drv.h"
 #include "nouveau_grctx.h"
+#include "nouveau_ramht.h"
 
-static int nv40_graph_register(struct drm_device *);
-static void nv40_graph_isr(struct drm_device *);
+struct nv40_graph_engine {
+	struct nouveau_exec_engine base;
+	u32 grctx_size;
+};
 
-struct nouveau_channel *
+static struct nouveau_channel *
 nv40_graph_channel(struct drm_device *dev)
 {
 	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_gpuobj *grctx;
 	uint32_t inst;
 	int i;
 
@@ -45,74 +49,17 @@
 	inst = (inst & NV40_PGRAPH_CTXCTL_CUR_INSTANCE) << 4;
 
 	for (i = 0; i < dev_priv->engine.fifo.channels; i++) {
-		struct nouveau_channel *chan = dev_priv->channels.ptr[i];
+		if (!dev_priv->channels.ptr[i])
+			continue;
 
-		if (chan && chan->ramin_grctx &&
-		    chan->ramin_grctx->pinst == inst)
-			return chan;
+		grctx = dev_priv->channels.ptr[i]->engctx[NVOBJ_ENGINE_GR];
+		if (grctx && grctx->pinst == inst)
+			return dev_priv->channels.ptr[i];
 	}
 
 	return NULL;
 }
 
-int
-nv40_graph_create_context(struct nouveau_channel *chan)
-{
-	struct drm_device *dev = chan->dev;
-	struct drm_nouveau_private *dev_priv = dev->dev_private;
-	struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph;
-	struct nouveau_grctx ctx = {};
-	unsigned long flags;
-	int ret;
-
-	ret = nouveau_gpuobj_new(dev, chan, pgraph->grctx_size, 16,
-				 NVOBJ_FLAG_ZERO_ALLOC, &chan->ramin_grctx);
-	if (ret)
-		return ret;
-
-	/* Initialise default context values */
-	ctx.dev = chan->dev;
-	ctx.mode = NOUVEAU_GRCTX_VALS;
-	ctx.data = chan->ramin_grctx;
-	nv40_grctx_init(&ctx);
-
-	nv_wo32(chan->ramin_grctx, 0, chan->ramin_grctx->pinst);
-
-	/* init grctx pointer in ramfc, and on PFIFO if channel is
-	 * already active there
-	 */
-	spin_lock_irqsave(&dev_priv->context_switch_lock, flags);
-	nv_wo32(chan->ramfc, 0x38, chan->ramin_grctx->pinst >> 4);
-	nv_mask(dev, 0x002500, 0x00000001, 0x00000000);
-	if ((nv_rd32(dev, 0x003204) & 0x0000001f) == chan->id)
-		nv_wr32(dev, 0x0032e0, chan->ramin_grctx->pinst >> 4);
-	nv_mask(dev, 0x002500, 0x00000001, 0x00000001);
-	spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags);
-	return 0;
-}
-
-void
-nv40_graph_destroy_context(struct nouveau_channel *chan)
-{
-	struct drm_device *dev = chan->dev;
-	struct drm_nouveau_private *dev_priv = dev->dev_private;
-	struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph;
-	unsigned long flags;
-
-	spin_lock_irqsave(&dev_priv->context_switch_lock, flags);
-	pgraph->fifo_access(dev, false);
-
-	/* Unload the context if it's the currently active one */
-	if (pgraph->channel(dev) == chan)
-		pgraph->unload_context(dev);
-
-	pgraph->fifo_access(dev, true);
-	spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags);
-
-	/* Free the context resources */
-	nouveau_gpuobj_ref(NULL, &chan->ramin_grctx);
-}
-
 static int
 nv40_graph_transfer_context(struct drm_device *dev, uint32_t inst, int save)
 {
@@ -154,57 +101,115 @@
 	return 0;
 }
 
-/* Restore the context for a specific channel into PGRAPH */
-int
-nv40_graph_load_context(struct nouveau_channel *chan)
+static int
+nv40_graph_unload_context(struct drm_device *dev)
 {
-	struct drm_device *dev = chan->dev;
 	uint32_t inst;
 	int ret;
 
-	if (!chan->ramin_grctx)
-		return -EINVAL;
-	inst = chan->ramin_grctx->pinst >> 4;
+	inst = nv_rd32(dev, NV40_PGRAPH_CTXCTL_CUR);
+	if (!(inst & NV40_PGRAPH_CTXCTL_CUR_LOADED))
+		return 0;
+	inst &= NV40_PGRAPH_CTXCTL_CUR_INSTANCE;
 
-	ret = nv40_graph_transfer_context(dev, inst, 0);
+	ret = nv40_graph_transfer_context(dev, inst, 1);
+
+	nv_wr32(dev, NV40_PGRAPH_CTXCTL_CUR, inst);
+	return ret;
+}
+
+static int
+nv40_graph_context_new(struct nouveau_channel *chan, int engine)
+{
+	struct nv40_graph_engine *pgraph = nv_engine(chan->dev, engine);
+	struct drm_device *dev = chan->dev;
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_gpuobj *grctx = NULL;
+	struct nouveau_grctx ctx = {};
+	unsigned long flags;
+	int ret;
+
+	ret = nouveau_gpuobj_new(dev, NULL, pgraph->grctx_size, 16,
+				 NVOBJ_FLAG_ZERO_ALLOC, &grctx);
 	if (ret)
 		return ret;
 
-	/* 0x40032C, no idea of it's exact function.  Could simply be a
-	 * record of the currently active PGRAPH context.  It's currently
-	 * unknown as to what bit 24 does.  The nv ddx has it set, so we will
-	 * set it here too.
-	 */
-	nv_wr32(dev, NV20_PGRAPH_CHANNEL_CTX_POINTER, inst);
-	nv_wr32(dev, NV40_PGRAPH_CTXCTL_CUR,
-		 (inst & NV40_PGRAPH_CTXCTL_CUR_INSTANCE) |
-		  NV40_PGRAPH_CTXCTL_CUR_LOADED);
-	/* 0x32E0 records the instance address of the active FIFO's PGRAPH
-	 * context.  If at any time this doesn't match 0x40032C, you will
-	 * receive PGRAPH_INTR_CONTEXT_SWITCH
+	/* Initialise default context values */
+	ctx.dev = chan->dev;
+	ctx.mode = NOUVEAU_GRCTX_VALS;
+	ctx.data = grctx;
+	nv40_grctx_init(&ctx);
+
+	nv_wo32(grctx, 0, grctx->vinst);
+
+	/* init grctx pointer in ramfc, and on PFIFO if channel is
+	 * already active there
 	 */
-	nv_wr32(dev, NV40_PFIFO_GRCTX_INSTANCE, inst);
+	spin_lock_irqsave(&dev_priv->context_switch_lock, flags);
+	nv_wo32(chan->ramfc, 0x38, grctx->vinst >> 4);
+	nv_mask(dev, 0x002500, 0x00000001, 0x00000000);
+	if ((nv_rd32(dev, 0x003204) & 0x0000001f) == chan->id)
+		nv_wr32(dev, 0x0032e0, grctx->vinst >> 4);
+	nv_mask(dev, 0x002500, 0x00000001, 0x00000001);
+	spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags);
+
+	chan->engctx[engine] = grctx;
 	return 0;
 }
 
+static void
+nv40_graph_context_del(struct nouveau_channel *chan, int engine)
+{
+	struct nouveau_gpuobj *grctx = chan->engctx[engine];
+	struct drm_device *dev = chan->dev;
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	unsigned long flags;
+
+	spin_lock_irqsave(&dev_priv->context_switch_lock, flags);
+	nv04_graph_fifo_access(dev, false);
+
+	/* Unload the context if it's the currently active one */
+	if (nv40_graph_channel(dev) == chan)
+		nv40_graph_unload_context(dev);
+
+	nv04_graph_fifo_access(dev, true);
+	spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags);
+
+	/* Free the context resources */
+	nouveau_gpuobj_ref(NULL, &grctx);
+	chan->engctx[engine] = NULL;
+}
+
 int
-nv40_graph_unload_context(struct drm_device *dev)
+nv40_graph_object_new(struct nouveau_channel *chan, int engine,
+		      u32 handle, u16 class)
 {
-	uint32_t inst;
+	struct drm_device *dev = chan->dev;
+	struct nouveau_gpuobj *obj = NULL;
 	int ret;
 
-	inst = nv_rd32(dev, NV40_PGRAPH_CTXCTL_CUR);
-	if (!(inst & NV40_PGRAPH_CTXCTL_CUR_LOADED))
-		return 0;
-	inst &= NV40_PGRAPH_CTXCTL_CUR_INSTANCE;
+	ret = nouveau_gpuobj_new(dev, chan, 20, 16, NVOBJ_FLAG_ZERO_FREE, &obj);
+	if (ret)
+		return ret;
+	obj->engine = 1;
+	obj->class  = class;
 
-	ret = nv40_graph_transfer_context(dev, inst, 1);
+	nv_wo32(obj, 0x00, class);
+	nv_wo32(obj, 0x04, 0x00000000);
+#ifndef __BIG_ENDIAN
+	nv_wo32(obj, 0x08, 0x00000000);
+#else
+	nv_wo32(obj, 0x08, 0x01000000);
+#endif
+	nv_wo32(obj, 0x0c, 0x00000000);
+	nv_wo32(obj, 0x10, 0x00000000);
 
-	nv_wr32(dev, NV40_PGRAPH_CTXCTL_CUR, inst);
+	ret = nouveau_ramht_insert(chan, handle, obj);
+	nouveau_gpuobj_ref(NULL, &obj);
 	return ret;
 }
 
-void
+static void
 nv40_graph_set_tile_region(struct drm_device *dev, int i)
 {
 	struct drm_nouveau_private *dev_priv = dev->dev_private;
@@ -257,14 +262,14 @@
  * C51		0x4e
  */
 int
-nv40_graph_init(struct drm_device *dev)
+nv40_graph_init(struct drm_device *dev, int engine)
 {
-	struct drm_nouveau_private *dev_priv =
-		(struct drm_nouveau_private *)dev->dev_private;
+	struct nv40_graph_engine *pgraph = nv_engine(dev, engine);
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
 	struct nouveau_fb_engine *pfb = &dev_priv->engine.fb;
 	struct nouveau_grctx ctx = {};
 	uint32_t vramsz, *cp;
-	int ret, i, j;
+	int i, j;
 
 	nv_wr32(dev, NV03_PMC_ENABLE, nv_rd32(dev, NV03_PMC_ENABLE) &
 			~NV_PMC_ENABLE_PGRAPH);
@@ -280,7 +285,7 @@
 	ctx.data = cp;
 	ctx.ctxprog_max = 256;
 	nv40_grctx_init(&ctx);
-	dev_priv->engine.graph.grctx_size = ctx.ctxvals_pos * 4;
+	pgraph->grctx_size = ctx.ctxvals_pos * 4;
 
 	nv_wr32(dev, NV40_PGRAPH_CTXCTL_UCODE_INDEX, 0);
 	for (i = 0; i < ctx.ctxprog_len; i++)
@@ -288,14 +293,9 @@
 
 	kfree(cp);
 
-	ret = nv40_graph_register(dev);
-	if (ret)
-		return ret;
-
 	/* No context present currently */
 	nv_wr32(dev, NV40_PGRAPH_CTXCTL_CUR, 0x00000000);
 
-	nouveau_irq_register(dev, 12, nv40_graph_isr);
 	nv_wr32(dev, NV03_PGRAPH_INTR   , 0xFFFFFFFF);
 	nv_wr32(dev, NV40_PGRAPH_INTR_EN, 0xFFFFFFFF);
 
@@ -428,47 +428,10 @@
 	return 0;
 }
 
-void nv40_graph_takedown(struct drm_device *dev)
-{
-	nouveau_irq_unregister(dev, 12);
-}
-
 static int
-nv40_graph_register(struct drm_device *dev)
+nv40_graph_fini(struct drm_device *dev, int engine)
 {
-	struct drm_nouveau_private *dev_priv = dev->dev_private;
-
-	if (dev_priv->engine.graph.registered)
-		return 0;
-
-	NVOBJ_CLASS(dev, 0x506e, SW); /* nvsw */
-	NVOBJ_CLASS(dev, 0x0030, GR); /* null */
-	NVOBJ_CLASS(dev, 0x0039, GR); /* m2mf */
-	NVOBJ_CLASS(dev, 0x004a, GR); /* gdirect */
-	NVOBJ_CLASS(dev, 0x009f, GR); /* imageblit (nv12) */
-	NVOBJ_CLASS(dev, 0x008a, GR); /* ifc */
-	NVOBJ_CLASS(dev, 0x0089, GR); /* sifm */
-	NVOBJ_CLASS(dev, 0x3089, GR); /* sifm (nv40) */
-	NVOBJ_CLASS(dev, 0x0062, GR); /* surf2d */
-	NVOBJ_CLASS(dev, 0x3062, GR); /* surf2d (nv40) */
-	NVOBJ_CLASS(dev, 0x0043, GR); /* rop */
-	NVOBJ_CLASS(dev, 0x0012, GR); /* beta1 */
-	NVOBJ_CLASS(dev, 0x0072, GR); /* beta4 */
-	NVOBJ_CLASS(dev, 0x0019, GR); /* cliprect */
-	NVOBJ_CLASS(dev, 0x0044, GR); /* pattern */
-	NVOBJ_CLASS(dev, 0x309e, GR); /* swzsurf */
-
-	/* curie */
-	if (nv44_graph_class(dev))
-		NVOBJ_CLASS(dev, 0x4497, GR);
-	else
-		NVOBJ_CLASS(dev, 0x4097, GR);
-
-	/* nvsw */
-	NVOBJ_CLASS(dev, 0x506e, SW);
-	NVOBJ_MTHD (dev, 0x506e, 0x0500, nv04_graph_mthd_page_flip);
-
-	dev_priv->engine.graph.registered = true;
+	nv40_graph_unload_context(dev);
 	return 0;
 }
 
@@ -476,17 +439,17 @@
 nv40_graph_isr_chid(struct drm_device *dev, u32 inst)
 {
 	struct drm_nouveau_private *dev_priv = dev->dev_private;
-	struct nouveau_channel *chan;
+	struct nouveau_gpuobj *grctx;
 	unsigned long flags;
 	int i;
 
 	spin_lock_irqsave(&dev_priv->channels.lock, flags);
 	for (i = 0; i < dev_priv->engine.fifo.channels; i++) {
-		chan = dev_priv->channels.ptr[i];
-		if (!chan || !chan->ramin_grctx)
+		if (!dev_priv->channels.ptr[i])
 			continue;
+		grctx = dev_priv->channels.ptr[i]->engctx[NVOBJ_ENGINE_GR];
 
-		if (inst == chan->ramin_grctx->pinst)
+		if (grctx && grctx->pinst == inst)
 			break;
 	}
 	spin_unlock_irqrestore(&dev_priv->channels.lock, flags);
@@ -537,3 +500,63 @@
 		}
 	}
 }
+
+static void
+nv40_graph_destroy(struct drm_device *dev, int engine)
+{
+	struct nv40_graph_engine *pgraph = nv_engine(dev, engine);
+
+	nouveau_irq_unregister(dev, 12);
+
+	NVOBJ_ENGINE_DEL(dev, GR);
+	kfree(pgraph);
+}
+
+int
+nv40_graph_create(struct drm_device *dev)
+{
+	struct nv40_graph_engine *pgraph;
+
+	pgraph = kzalloc(sizeof(*pgraph), GFP_KERNEL);
+	if (!pgraph)
+		return -ENOMEM;
+
+	pgraph->base.destroy = nv40_graph_destroy;
+	pgraph->base.init = nv40_graph_init;
+	pgraph->base.fini = nv40_graph_fini;
+	pgraph->base.context_new = nv40_graph_context_new;
+	pgraph->base.context_del = nv40_graph_context_del;
+	pgraph->base.object_new = nv40_graph_object_new;
+	pgraph->base.set_tile_region = nv40_graph_set_tile_region;
+
+	NVOBJ_ENGINE_ADD(dev, GR, &pgraph->base);
+	nouveau_irq_register(dev, 12, nv40_graph_isr);
+
+	NVOBJ_CLASS(dev, 0x506e, SW); /* nvsw */
+	NVOBJ_CLASS(dev, 0x0030, GR); /* null */
+	NVOBJ_CLASS(dev, 0x0039, GR); /* m2mf */
+	NVOBJ_CLASS(dev, 0x004a, GR); /* gdirect */
+	NVOBJ_CLASS(dev, 0x009f, GR); /* imageblit (nv12) */
+	NVOBJ_CLASS(dev, 0x008a, GR); /* ifc */
+	NVOBJ_CLASS(dev, 0x0089, GR); /* sifm */
+	NVOBJ_CLASS(dev, 0x3089, GR); /* sifm (nv40) */
+	NVOBJ_CLASS(dev, 0x0062, GR); /* surf2d */
+	NVOBJ_CLASS(dev, 0x3062, GR); /* surf2d (nv40) */
+	NVOBJ_CLASS(dev, 0x0043, GR); /* rop */
+	NVOBJ_CLASS(dev, 0x0012, GR); /* beta1 */
+	NVOBJ_CLASS(dev, 0x0072, GR); /* beta4 */
+	NVOBJ_CLASS(dev, 0x0019, GR); /* cliprect */
+	NVOBJ_CLASS(dev, 0x0044, GR); /* pattern */
+	NVOBJ_CLASS(dev, 0x309e, GR); /* swzsurf */
+
+	/* curie */
+	if (nv44_graph_class(dev))
+		NVOBJ_CLASS(dev, 0x4497, GR);
+	else
+		NVOBJ_CLASS(dev, 0x4097, GR);
+
+	/* nvsw */
+	NVOBJ_CLASS(dev, 0x506e, SW);
+	NVOBJ_MTHD (dev, 0x506e, 0x0500, nv04_graph_mthd_page_flip);
+	return 0;
+}
diff -druN linux-2.6.39-libre/drivers/gpu/drm/nouveau/nv40_mpeg.c linux-3.0-rc7-libre/drivers/gpu/drm/nouveau/nv40_mpeg.c
--- linux-2.6.39-libre/drivers/gpu/drm/nouveau/nv40_mpeg.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/gpu/drm/nouveau/nv40_mpeg.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,311 @@
+/*
+ * Copyright 2011 Red Hat Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: Ben Skeggs
+ */
+
+#include "drmP.h"
+#include "nouveau_drv.h"
+#include "nouveau_ramht.h"
+
+struct nv40_mpeg_engine {
+	struct nouveau_exec_engine base;
+};
+
+static int
+nv40_mpeg_context_new(struct nouveau_channel *chan, int engine)
+{
+	struct drm_device *dev = chan->dev;
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_gpuobj *ctx = NULL;
+	unsigned long flags;
+	int ret;
+
+	NV_DEBUG(dev, "ch%d\n", chan->id);
+
+	ret = nouveau_gpuobj_new(dev, NULL, 264 * 4, 16, NVOBJ_FLAG_ZERO_ALLOC |
+				 NVOBJ_FLAG_ZERO_FREE, &ctx);
+	if (ret)
+		return ret;
+
+	nv_wo32(ctx, 0x78, 0x02001ec1);
+
+	spin_lock_irqsave(&dev_priv->context_switch_lock, flags);
+	nv_mask(dev, 0x002500, 0x00000001, 0x00000000);
+	if ((nv_rd32(dev, 0x003204) & 0x1f) == chan->id)
+		nv_wr32(dev, 0x00330c, ctx->pinst >> 4);
+	nv_wo32(chan->ramfc, 0x54, ctx->pinst >> 4);
+	nv_mask(dev, 0x002500, 0x00000001, 0x00000001);
+	spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags);
+
+	chan->engctx[engine] = ctx;
+	return 0;
+}
+
+static void
+nv40_mpeg_context_del(struct nouveau_channel *chan, int engine)
+{
+	struct drm_nouveau_private *dev_priv = chan->dev->dev_private;
+	struct nouveau_gpuobj *ctx = chan->engctx[engine];
+	struct drm_device *dev = chan->dev;
+	unsigned long flags;
+	u32 inst = 0x80000000 | (ctx->pinst >> 4);
+
+	spin_lock_irqsave(&dev_priv->context_switch_lock, flags);
+	nv_mask(dev, 0x00b32c, 0x00000001, 0x00000000);
+	if (nv_rd32(dev, 0x00b318) == inst)
+		nv_mask(dev, 0x00b318, 0x80000000, 0x00000000);
+	nv_mask(dev, 0x00b32c, 0x00000001, 0x00000001);
+	spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags);
+
+	nouveau_gpuobj_ref(NULL, &ctx);
+	chan->engctx[engine] = NULL;
+}
+
+static int
+nv40_mpeg_object_new(struct nouveau_channel *chan, int engine,
+		      u32 handle, u16 class)
+{
+	struct drm_device *dev = chan->dev;
+	struct nouveau_gpuobj *obj = NULL;
+	int ret;
+
+	ret = nouveau_gpuobj_new(dev, chan, 20, 16, NVOBJ_FLAG_ZERO_ALLOC |
+				 NVOBJ_FLAG_ZERO_FREE, &obj);
+	if (ret)
+		return ret;
+	obj->engine = 2;
+	obj->class  = class;
+
+	nv_wo32(obj, 0x00, class);
+
+	ret = nouveau_ramht_insert(chan, handle, obj);
+	nouveau_gpuobj_ref(NULL, &obj);
+	return ret;
+}
+
+static int
+nv40_mpeg_init(struct drm_device *dev, int engine)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nv40_mpeg_engine *pmpeg = nv_engine(dev, engine);
+	int i;
+
+	/* VPE init */
+	nv_mask(dev, 0x000200, 0x00000002, 0x00000000);
+	nv_mask(dev, 0x000200, 0x00000002, 0x00000002);
+	nv_wr32(dev, 0x00b0e0, 0x00000020); /* nvidia: rd 0x01, wr 0x20 */
+	nv_wr32(dev, 0x00b0e8, 0x00000020); /* nvidia: rd 0x01, wr 0x20 */
+
+	for (i = 0; i < dev_priv->engine.fb.num_tiles; i++)
+		pmpeg->base.set_tile_region(dev, i);
+
+	/* PMPEG init */
+	nv_wr32(dev, 0x00b32c, 0x00000000);
+	nv_wr32(dev, 0x00b314, 0x00000100);
+	nv_wr32(dev, 0x00b220, 0x00000044);
+	nv_wr32(dev, 0x00b300, 0x02001ec1);
+	nv_mask(dev, 0x00b32c, 0x00000001, 0x00000001);
+
+	nv_wr32(dev, 0x00b100, 0xffffffff);
+	nv_wr32(dev, 0x00b140, 0xffffffff);
+
+	if (!nv_wait(dev, 0x00b200, 0x00000001, 0x00000000)) {
+		NV_ERROR(dev, "PMPEG init: 0x%08x\n", nv_rd32(dev, 0x00b200));
+		return -EBUSY;
+	}
+
+	return 0;
+}
+
+static int
+nv40_mpeg_fini(struct drm_device *dev, int engine)
+{
+	/*XXX: context save? */
+	nv_mask(dev, 0x00b32c, 0x00000001, 0x00000000);
+	nv_wr32(dev, 0x00b140, 0x00000000);
+	return 0;
+}
+
+static int
+nv40_mpeg_mthd_dma(struct nouveau_channel *chan, u32 class, u32 mthd, u32 data)
+{
+	struct drm_device *dev = chan->dev;
+	u32 inst = data << 4;
+	u32 dma0 = nv_ri32(dev, inst + 0);
+	u32 dma1 = nv_ri32(dev, inst + 4);
+	u32 dma2 = nv_ri32(dev, inst + 8);
+	u32 base = (dma2 & 0xfffff000) | (dma0 >> 20);
+	u32 size = dma1 + 1;
+
+	/* only allow linear DMA objects */
+	if (!(dma0 & 0x00002000))
+		return -EINVAL;
+
+	if (mthd == 0x0190) {
+		/* DMA_CMD */
+		nv_mask(dev, 0x00b300, 0x00030000, (dma0 & 0x00030000));
+		nv_wr32(dev, 0x00b334, base);
+		nv_wr32(dev, 0x00b324, size);
+	} else
+	if (mthd == 0x01a0) {
+		/* DMA_DATA */
+		nv_mask(dev, 0x00b300, 0x000c0000, (dma0 & 0x00030000) << 2);
+		nv_wr32(dev, 0x00b360, base);
+		nv_wr32(dev, 0x00b364, size);
+	} else {
+		/* DMA_IMAGE, VRAM only */
+		if (dma0 & 0x000c0000)
+			return -EINVAL;
+
+		nv_wr32(dev, 0x00b370, base);
+		nv_wr32(dev, 0x00b374, size);
+	}
+
+	return 0;
+}
+
+static int
+nv40_mpeg_isr_chid(struct drm_device *dev, u32 inst)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_gpuobj *ctx;
+	unsigned long flags;
+	int i;
+
+	spin_lock_irqsave(&dev_priv->channels.lock, flags);
+	for (i = 0; i < dev_priv->engine.fifo.channels; i++) {
+		if (!dev_priv->channels.ptr[i])
+			continue;
+
+		ctx = dev_priv->channels.ptr[i]->engctx[NVOBJ_ENGINE_MPEG];
+		if (ctx && ctx->pinst == inst)
+			break;
+	}
+	spin_unlock_irqrestore(&dev_priv->channels.lock, flags);
+	return i;
+}
+
+static void
+nv40_vpe_set_tile_region(struct drm_device *dev, int i)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_tile_reg *tile = &dev_priv->tile.reg[i];
+
+	nv_wr32(dev, 0x00b008 + (i * 0x10), tile->pitch);
+	nv_wr32(dev, 0x00b004 + (i * 0x10), tile->limit);
+	nv_wr32(dev, 0x00b000 + (i * 0x10), tile->addr);
+}
+
+static void
+nv40_mpeg_isr(struct drm_device *dev)
+{
+	u32 inst = (nv_rd32(dev, 0x00b318) & 0x000fffff) << 4;
+	u32 chid = nv40_mpeg_isr_chid(dev, inst);
+	u32 stat = nv_rd32(dev, 0x00b100);
+	u32 type = nv_rd32(dev, 0x00b230);
+	u32 mthd = nv_rd32(dev, 0x00b234);
+	u32 data = nv_rd32(dev, 0x00b238);
+	u32 show = stat;
+
+	if (stat & 0x01000000) {
+		/* happens on initial binding of the object */
+		if (type == 0x00000020 && mthd == 0x0000) {
+			nv_mask(dev, 0x00b308, 0x00000000, 0x00000000);
+			show &= ~0x01000000;
+		}
+
+		if (type == 0x00000010) {
+			if (!nouveau_gpuobj_mthd_call2(dev, chid, 0x3174, mthd, data))
+				show &= ~0x01000000;
+		}
+	}
+
+	nv_wr32(dev, 0x00b100, stat);
+	nv_wr32(dev, 0x00b230, 0x00000001);
+
+	if (show && nouveau_ratelimit()) {
+		NV_INFO(dev, "PMPEG: Ch %d [0x%08x] 0x%08x 0x%08x 0x%08x 0x%08x\n",
+			chid, inst, stat, type, mthd, data);
+	}
+}
+
+static void
+nv40_vpe_isr(struct drm_device *dev)
+{
+	if (nv_rd32(dev, 0x00b100))
+		nv40_mpeg_isr(dev);
+
+	if (nv_rd32(dev, 0x00b800)) {
+		u32 stat = nv_rd32(dev, 0x00b800);
+		NV_INFO(dev, "PMSRCH: 0x%08x\n", stat);
+		nv_wr32(dev, 0xb800, stat);
+	}
+}
+
+static void
+nv40_mpeg_destroy(struct drm_device *dev, int engine)
+{
+	struct nv40_mpeg_engine *pmpeg = nv_engine(dev, engine);
+
+	nouveau_irq_unregister(dev, 0);
+
+	NVOBJ_ENGINE_DEL(dev, MPEG);
+	kfree(pmpeg);
+}
+
+int
+nv40_mpeg_create(struct drm_device *dev)
+{
+	struct nv40_mpeg_engine *pmpeg;
+
+	pmpeg = kzalloc(sizeof(*pmpeg), GFP_KERNEL);
+	if (!pmpeg)
+		return -ENOMEM;
+
+	pmpeg->base.destroy = nv40_mpeg_destroy;
+	pmpeg->base.init = nv40_mpeg_init;
+	pmpeg->base.fini = nv40_mpeg_fini;
+	pmpeg->base.context_new = nv40_mpeg_context_new;
+	pmpeg->base.context_del = nv40_mpeg_context_del;
+	pmpeg->base.object_new = nv40_mpeg_object_new;
+
+	/* ISR vector, PMC_ENABLE bit,  and TILE regs are shared between
+	 * all VPE engines, for this driver's purposes the PMPEG engine
+	 * will be treated as the "master" and handle the global VPE
+	 * bits too
+	 */
+	pmpeg->base.set_tile_region = nv40_vpe_set_tile_region;
+	nouveau_irq_register(dev, 0, nv40_vpe_isr);
+
+	NVOBJ_ENGINE_ADD(dev, MPEG, &pmpeg->base);
+	NVOBJ_CLASS(dev, 0x3174, MPEG);
+	NVOBJ_MTHD (dev, 0x3174, 0x0190, nv40_mpeg_mthd_dma);
+	NVOBJ_MTHD (dev, 0x3174, 0x01a0, nv40_mpeg_mthd_dma);
+	NVOBJ_MTHD (dev, 0x3174, 0x01b0, nv40_mpeg_mthd_dma);
+
+#if 0
+	NVOBJ_ENGINE_ADD(dev, ME, &pme->base);
+	NVOBJ_CLASS(dev, 0x4075, ME);
+#endif
+	return 0;
+
+}
diff -druN linux-2.6.39-libre/drivers/gpu/drm/nouveau/nv50_calc.c linux-3.0-rc7-libre/drivers/gpu/drm/nouveau/nv50_calc.c
--- linux-2.6.39-libre/drivers/gpu/drm/nouveau/nv50_calc.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/gpu/drm/nouveau/nv50_calc.c	2011-07-11 19:51:52.000000000 -0400
@@ -23,7 +23,6 @@
  */
 
 #include "drmP.h"
-#include "drm_fixed.h"
 #include "nouveau_drv.h"
 #include "nouveau_hw.h"
 
@@ -47,45 +46,52 @@
 }
 
 int
-nv50_calc_pll2(struct drm_device *dev, struct pll_lims *pll, int clk,
-	       int *N, int *fN, int *M, int *P)
+nva3_calc_pll(struct drm_device *dev, struct pll_lims *pll, int clk,
+	      int *pN, int *pfN, int *pM, int *P)
 {
-	fixed20_12 fb_div, a, b;
-	u32 refclk = pll->refclk / 10;
-	u32 max_vco_freq = pll->vco1.maxfreq / 10;
-	u32 max_vco_inputfreq = pll->vco1.max_inputfreq / 10;
-	clk /= 10;
+	u32 best_err = ~0, err;
+	int M, lM, hM, N, fN;
 
-	*P = max_vco_freq / clk;
+	*P = pll->vco1.maxfreq / clk;
 	if (*P > pll->max_p)
 		*P = pll->max_p;
 	if (*P < pll->min_p)
 		*P = pll->min_p;
 
-	/* *M = floor((refclk + max_vco_inputfreq) / max_vco_inputfreq); */
-	a.full = dfixed_const(refclk + max_vco_inputfreq);
-	b.full = dfixed_const(max_vco_inputfreq);
-	a.full = dfixed_div(a, b);
-	a.full = dfixed_floor(a);
-	*M = dfixed_trunc(a);
+	lM = (pll->refclk + pll->vco1.max_inputfreq) / pll->vco1.max_inputfreq;
+	lM = max(lM, (int)pll->vco1.min_m);
+	hM = (pll->refclk + pll->vco1.min_inputfreq) / pll->vco1.min_inputfreq;
+	hM = min(hM, (int)pll->vco1.max_m);
 
-	/* fb_div = (vco * *M) / refclk; */
-	fb_div.full = dfixed_const(clk * *P);
-	fb_div.full = dfixed_mul(fb_div, a);
-	a.full = dfixed_const(refclk);
-	fb_div.full = dfixed_div(fb_div, a);
+	for (M = lM; M <= hM; M++) {
+		u32 tmp = clk * *P * M;
+		N  = tmp / pll->refclk;
+		fN = tmp % pll->refclk;
+		if (!pfN && fN >= pll->refclk / 2)
+			N++;
 
-	/* *N = floor(fb_div); */
-	a.full = dfixed_floor(fb_div);
-	*N = dfixed_trunc(fb_div);
+		if (N < pll->vco1.min_n)
+			continue;
+		if (N > pll->vco1.max_n)
+			break;
 
-	/* *fN = (fmod(fb_div, 1.0) * 8192) - 4096; */
-	b.full = dfixed_const(8192);
-	a.full = dfixed_mul(a, b);
-	fb_div.full = dfixed_mul(fb_div, b);
-	fb_div.full = fb_div.full - a.full;
-	*fN = dfixed_trunc(fb_div) - 4096;
-	*fN &= 0xffff;
+		err = abs(clk - (pll->refclk * N / M / *P));
+		if (err < best_err) {
+			best_err = err;
+			*pN = N;
+			*pM = M;
+		}
 
-	return clk;
+		if (pfN) {
+			*pfN = (((fN << 13) / pll->refclk) - 4096) & 0xffff;
+			return clk;
+		}
+	}
+
+	if (unlikely(best_err == ~0)) {
+		NV_ERROR(dev, "unable to find matching pll values\n");
+		return -EINVAL;
+	}
+
+	return pll->refclk * *pN / *pM / *P;
 }
diff -druN linux-2.6.39-libre/drivers/gpu/drm/nouveau/nv50_crtc.c linux-3.0-rc7-libre/drivers/gpu/drm/nouveau/nv50_crtc.c
--- linux-2.6.39-libre/drivers/gpu/drm/nouveau/nv50_crtc.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/gpu/drm/nouveau/nv50_crtc.c	2011-07-11 19:51:52.000000000 -0400
@@ -286,7 +286,7 @@
 		nv_wr32(dev, pll.reg + 8, reg2 | (P << 28) | (M2 << 16) | N2);
 	} else
 	if (dev_priv->chipset < NV_C0) {
-		ret = nv50_calc_pll2(dev, &pll, pclk, &N1, &N2, &M1, &P);
+		ret = nva3_calc_pll(dev, &pll, pclk, &N1, &N2, &M1, &P);
 		if (ret <= 0)
 			return 0;
 
@@ -298,7 +298,7 @@
 		nv_wr32(dev, pll.reg + 4, reg1 | (P << 16) | (M1 << 8) | N1);
 		nv_wr32(dev, pll.reg + 8, N2);
 	} else {
-		ret = nv50_calc_pll2(dev, &pll, pclk, &N1, &N2, &M1, &P);
+		ret = nva3_calc_pll(dev, &pll, pclk, &N1, &N2, &M1, &P);
 		if (ret <= 0)
 			return 0;
 
@@ -349,14 +349,14 @@
 	struct drm_gem_object *gem;
 	int ret = 0, i;
 
-	if (width != 64 || height != 64)
-		return -EINVAL;
-
 	if (!buffer_handle) {
 		nv_crtc->cursor.hide(nv_crtc, true);
 		return 0;
 	}
 
+	if (width != 64 || height != 64)
+		return -EINVAL;
+
 	gem = drm_gem_object_lookup(dev, file_priv, buffer_handle);
 	if (!gem)
 		return -ENOENT;
@@ -532,8 +532,7 @@
 	if (atomic) {
 		drm_fb = passed_fb;
 		fb = nouveau_framebuffer(passed_fb);
-	}
-	else {
+	} else {
 		/* If not atomic, we can go ahead and pin, and unpin the
 		 * old fb we were passed.
 		 */
diff -druN linux-2.6.39-libre/drivers/gpu/drm/nouveau/nv50_display.c linux-3.0-rc7-libre/drivers/gpu/drm/nouveau/nv50_display.c
--- linux-2.6.39-libre/drivers/gpu/drm/nouveau/nv50_display.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/gpu/drm/nouveau/nv50_display.c	2011-07-11 19:51:52.000000000 -0400
@@ -409,7 +409,7 @@
 	struct nouveau_channel *evo = dispc->sync;
 	int ret;
 
-	ret = RING_SPACE(evo, 24);
+	ret = RING_SPACE(evo, chan ? 25 : 27);
 	if (unlikely(ret))
 		return ret;
 
@@ -458,8 +458,19 @@
 	/* queue the flip on the crtc's "display sync" channel */
 	BEGIN_RING(evo, 0, 0x0100, 1);
 	OUT_RING  (evo, 0xfffe0000);
-	BEGIN_RING(evo, 0, 0x0084, 5);
-	OUT_RING  (evo, chan ? 0x00000100 : 0x00000010);
+	if (chan) {
+		BEGIN_RING(evo, 0, 0x0084, 1);
+		OUT_RING  (evo, 0x00000100);
+	} else {
+		BEGIN_RING(evo, 0, 0x0084, 1);
+		OUT_RING  (evo, 0x00000010);
+		/* allows gamma somehow, PDISP will bitch at you if
+		 * you don't wait for vblank before changing this..
+		 */
+		BEGIN_RING(evo, 0, 0x00e0, 1);
+		OUT_RING  (evo, 0x40000000);
+	}
+	BEGIN_RING(evo, 0, 0x0088, 4);
 	OUT_RING  (evo, dispc->sem.offset);
 	OUT_RING  (evo, 0xf00d0000 | dispc->sem.value);
 	OUT_RING  (evo, 0x74b1e000);
@@ -517,13 +528,25 @@
 			if (bios->fp.if_is_24bit)
 				script |= 0x0200;
 		} else {
+			/* determine number of lvds links */
+			if (nv_connector && nv_connector->edid &&
+			    nv_connector->dcb->type == DCB_CONNECTOR_LVDS_SPWG) {
+				/* http://www.spwg.org */
+				if (((u8 *)nv_connector->edid)[121] == 2)
+					script |= 0x0100;
+			} else
 			if (pxclk >= bios->fp.duallink_transition_clk) {
 				script |= 0x0100;
+			}
+
+			/* determine panel depth */
+			if (script & 0x0100) {
 				if (bios->fp.strapless_is_24bit & 2)
 					script |= 0x0200;
-			} else
-			if (bios->fp.strapless_is_24bit & 1)
-				script |= 0x0200;
+			} else {
+				if (bios->fp.strapless_is_24bit & 1)
+					script |= 0x0200;
+			}
 
 			if (nv_connector && nv_connector->edid &&
 			    (nv_connector->edid->revision >= 4) &&
diff -druN linux-2.6.39-libre/drivers/gpu/drm/nouveau/nv50_graph.c linux-3.0-rc7-libre/drivers/gpu/drm/nouveau/nv50_graph.c
--- linux-2.6.39-libre/drivers/gpu/drm/nouveau/nv50_graph.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/gpu/drm/nouveau/nv50_graph.c	2011-07-11 19:51:52.000000000 -0400
@@ -31,10 +31,95 @@
 #include "nouveau_grctx.h"
 #include "nouveau_dma.h"
 #include "nouveau_vm.h"
+#include "nouveau_ramht.h"
 #include "nv50_evo.h"
 
-static int  nv50_graph_register(struct drm_device *);
-static void nv50_graph_isr(struct drm_device *);
+struct nv50_graph_engine {
+	struct nouveau_exec_engine base;
+	u32 ctxprog[512];
+	u32 ctxprog_size;
+	u32 grctx_size;
+};
+
+static void
+nv50_graph_fifo_access(struct drm_device *dev, bool enabled)
+{
+	const uint32_t mask = 0x00010001;
+
+	if (enabled)
+		nv_wr32(dev, 0x400500, nv_rd32(dev, 0x400500) | mask);
+	else
+		nv_wr32(dev, 0x400500, nv_rd32(dev, 0x400500) & ~mask);
+}
+
+static struct nouveau_channel *
+nv50_graph_channel(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	uint32_t inst;
+	int i;
+
+	/* Be sure we're not in the middle of a context switch or bad things
+	 * will happen, such as unloading the wrong pgraph context.
+	 */
+	if (!nv_wait(dev, 0x400300, 0x00000001, 0x00000000))
+		NV_ERROR(dev, "Ctxprog is still running\n");
+
+	inst = nv_rd32(dev, NV50_PGRAPH_CTXCTL_CUR);
+	if (!(inst & NV50_PGRAPH_CTXCTL_CUR_LOADED))
+		return NULL;
+	inst = (inst & NV50_PGRAPH_CTXCTL_CUR_INSTANCE) << 12;
+
+	for (i = 0; i < dev_priv->engine.fifo.channels; i++) {
+		struct nouveau_channel *chan = dev_priv->channels.ptr[i];
+
+		if (chan && chan->ramin && chan->ramin->vinst == inst)
+			return chan;
+	}
+
+	return NULL;
+}
+
+static int
+nv50_graph_do_load_context(struct drm_device *dev, uint32_t inst)
+{
+	uint32_t fifo = nv_rd32(dev, 0x400500);
+
+	nv_wr32(dev, 0x400500, fifo & ~1);
+	nv_wr32(dev, 0x400784, inst);
+	nv_wr32(dev, 0x400824, nv_rd32(dev, 0x400824) | 0x40);
+	nv_wr32(dev, 0x400320, nv_rd32(dev, 0x400320) | 0x11);
+	nv_wr32(dev, 0x400040, 0xffffffff);
+	(void)nv_rd32(dev, 0x400040);
+	nv_wr32(dev, 0x400040, 0x00000000);
+	nv_wr32(dev, 0x400304, nv_rd32(dev, 0x400304) | 1);
+
+	if (nouveau_wait_for_idle(dev))
+		nv_wr32(dev, 0x40032c, inst | (1<<31));
+	nv_wr32(dev, 0x400500, fifo);
+
+	return 0;
+}
+
+static int
+nv50_graph_unload_context(struct drm_device *dev)
+{
+	uint32_t inst;
+
+	inst  = nv_rd32(dev, NV50_PGRAPH_CTXCTL_CUR);
+	if (!(inst & NV50_PGRAPH_CTXCTL_CUR_LOADED))
+		return 0;
+	inst &= NV50_PGRAPH_CTXCTL_CUR_INSTANCE;
+
+	nouveau_wait_for_idle(dev);
+	nv_wr32(dev, 0x400784, inst);
+	nv_wr32(dev, 0x400824, nv_rd32(dev, 0x400824) | 0x20);
+	nv_wr32(dev, 0x400304, nv_rd32(dev, 0x400304) | 0x01);
+	nouveau_wait_for_idle(dev);
+
+	nv_wr32(dev, NV50_PGRAPH_CTXCTL_CUR, inst);
+	return 0;
+}
 
 static void
 nv50_graph_init_reset(struct drm_device *dev)
@@ -52,7 +137,6 @@
 {
 	NV_DEBUG(dev, "\n");
 
-	nouveau_irq_register(dev, 12, nv50_graph_isr);
 	nv_wr32(dev, NV03_PGRAPH_INTR, 0xffffffff);
 	nv_wr32(dev, 0x400138, 0xffffffff);
 	nv_wr32(dev, NV40_PGRAPH_INTR_EN, 0xffffffff);
@@ -135,34 +219,14 @@
 static int
 nv50_graph_init_ctxctl(struct drm_device *dev)
 {
-	struct drm_nouveau_private *dev_priv = dev->dev_private;
-	struct nouveau_grctx ctx = {};
-	uint32_t *cp;
+	struct nv50_graph_engine *pgraph = nv_engine(dev, NVOBJ_ENGINE_GR);
 	int i;
 
 	NV_DEBUG(dev, "\n");
 
-	cp = kmalloc(512 * 4, GFP_KERNEL);
-	if (!cp) {
-		NV_ERROR(dev, "failed to allocate ctxprog\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, NV40_PGRAPH_CTXCTL_UCODE_INDEX, 0);
+	for (i = 0; i < pgraph->ctxprog_size; i++)
+		nv_wr32(dev, NV40_PGRAPH_CTXCTL_UCODE_DATA, pgraph->ctxprog[i]);
 
 	nv_wr32(dev, 0x40008c, 0x00000004); /* HW_CTX_SWITCH_ENABLED */
 	nv_wr32(dev, 0x400320, 4);
@@ -171,8 +235,8 @@
 	return 0;
 }
 
-int
-nv50_graph_init(struct drm_device *dev)
+static int
+nv50_graph_init(struct drm_device *dev, int engine)
 {
 	int ret;
 
@@ -186,105 +250,66 @@
 	if (ret)
 		return ret;
 
-	ret = nv50_graph_register(dev);
-	if (ret)
-		return ret;
 	nv50_graph_init_intr(dev);
 	return 0;
 }
 
-void
-nv50_graph_takedown(struct drm_device *dev)
+static int
+nv50_graph_fini(struct drm_device *dev, int engine)
 {
 	NV_DEBUG(dev, "\n");
+	nv50_graph_unload_context(dev);
 	nv_wr32(dev, 0x40013c, 0x00000000);
-	nouveau_irq_unregister(dev, 12);
-}
-
-void
-nv50_graph_fifo_access(struct drm_device *dev, bool enabled)
-{
-	const uint32_t mask = 0x00010001;
-
-	if (enabled)
-		nv_wr32(dev, 0x400500, nv_rd32(dev, 0x400500) | mask);
-	else
-		nv_wr32(dev, 0x400500, nv_rd32(dev, 0x400500) & ~mask);
-}
-
-struct nouveau_channel *
-nv50_graph_channel(struct drm_device *dev)
-{
-	struct drm_nouveau_private *dev_priv = dev->dev_private;
-	uint32_t inst;
-	int i;
-
-	/* Be sure we're not in the middle of a context switch or bad things
-	 * will happen, such as unloading the wrong pgraph context.
-	 */
-	if (!nv_wait(dev, 0x400300, 0x00000001, 0x00000000))
-		NV_ERROR(dev, "Ctxprog is still running\n");
-
-	inst = nv_rd32(dev, NV50_PGRAPH_CTXCTL_CUR);
-	if (!(inst & NV50_PGRAPH_CTXCTL_CUR_LOADED))
-		return NULL;
-	inst = (inst & NV50_PGRAPH_CTXCTL_CUR_INSTANCE) << 12;
-
-	for (i = 0; i < dev_priv->engine.fifo.channels; i++) {
-		struct nouveau_channel *chan = dev_priv->channels.ptr[i];
-
-		if (chan && chan->ramin && chan->ramin->vinst == inst)
-			return chan;
-	}
-
-	return NULL;
+	return 0;
 }
 
-int
-nv50_graph_create_context(struct nouveau_channel *chan)
+static int
+nv50_graph_context_new(struct nouveau_channel *chan, int engine)
 {
 	struct drm_device *dev = chan->dev;
 	struct drm_nouveau_private *dev_priv = dev->dev_private;
 	struct nouveau_gpuobj *ramin = chan->ramin;
-	struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph;
+	struct nouveau_gpuobj *grctx = NULL;
+	struct nv50_graph_engine *pgraph = nv_engine(dev, engine);
 	struct nouveau_grctx ctx = {};
 	int hdr, ret;
 
 	NV_DEBUG(dev, "ch%d\n", chan->id);
 
-	ret = nouveau_gpuobj_new(dev, chan, pgraph->grctx_size, 0,
+	ret = nouveau_gpuobj_new(dev, NULL, pgraph->grctx_size, 0,
 				 NVOBJ_FLAG_ZERO_ALLOC |
-				 NVOBJ_FLAG_ZERO_FREE, &chan->ramin_grctx);
+				 NVOBJ_FLAG_ZERO_FREE, &grctx);
 	if (ret)
 		return ret;
 
 	hdr = (dev_priv->chipset == 0x50) ? 0x200 : 0x20;
 	nv_wo32(ramin, hdr + 0x00, 0x00190002);
-	nv_wo32(ramin, hdr + 0x04, chan->ramin_grctx->vinst +
-				   pgraph->grctx_size - 1);
-	nv_wo32(ramin, hdr + 0x08, chan->ramin_grctx->vinst);
+	nv_wo32(ramin, hdr + 0x04, grctx->vinst + grctx->size - 1);
+	nv_wo32(ramin, hdr + 0x08, grctx->vinst);
 	nv_wo32(ramin, hdr + 0x0c, 0);
 	nv_wo32(ramin, hdr + 0x10, 0);
 	nv_wo32(ramin, hdr + 0x14, 0x00010000);
 
 	ctx.dev = chan->dev;
 	ctx.mode = NOUVEAU_GRCTX_VALS;
-	ctx.data = chan->ramin_grctx;
+	ctx.data = grctx;
 	nv50_grctx_init(&ctx);
 
-	nv_wo32(chan->ramin_grctx, 0x00000, chan->ramin->vinst >> 12);
+	nv_wo32(grctx, 0x00000, chan->ramin->vinst >> 12);
 
 	dev_priv->engine.instmem.flush(dev);
-	atomic_inc(&chan->vm->pgraph_refs);
+
+	atomic_inc(&chan->vm->engref[NVOBJ_ENGINE_GR]);
+	chan->engctx[NVOBJ_ENGINE_GR] = grctx;
 	return 0;
 }
 
-void
-nv50_graph_destroy_context(struct nouveau_channel *chan)
+static void
+nv50_graph_context_del(struct nouveau_channel *chan, int engine)
 {
+	struct nouveau_gpuobj *grctx = chan->engctx[engine];
 	struct drm_device *dev = chan->dev;
 	struct drm_nouveau_private *dev_priv = dev->dev_private;
-	struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph;
 	struct nouveau_fifo_engine *pfifo = &dev_priv->engine.fifo;
 	int i, hdr = (dev_priv->chipset == 0x50) ? 0x200 : 0x20;
 	unsigned long flags;
@@ -296,72 +321,49 @@
 
 	spin_lock_irqsave(&dev_priv->context_switch_lock, flags);
 	pfifo->reassign(dev, false);
-	pgraph->fifo_access(dev, false);
+	nv50_graph_fifo_access(dev, false);
 
-	if (pgraph->channel(dev) == chan)
-		pgraph->unload_context(dev);
+	if (nv50_graph_channel(dev) == chan)
+		nv50_graph_unload_context(dev);
 
 	for (i = hdr; i < hdr + 24; i += 4)
 		nv_wo32(chan->ramin, i, 0);
 	dev_priv->engine.instmem.flush(dev);
 
-	pgraph->fifo_access(dev, true);
+	nv50_graph_fifo_access(dev, true);
 	pfifo->reassign(dev, true);
 	spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags);
 
-	nouveau_gpuobj_ref(NULL, &chan->ramin_grctx);
+	nouveau_gpuobj_ref(NULL, &grctx);
 
-	atomic_dec(&chan->vm->pgraph_refs);
+	atomic_dec(&chan->vm->engref[engine]);
+	chan->engctx[engine] = NULL;
 }
 
 static int
-nv50_graph_do_load_context(struct drm_device *dev, uint32_t inst)
-{
-	uint32_t fifo = nv_rd32(dev, 0x400500);
-
-	nv_wr32(dev, 0x400500, fifo & ~1);
-	nv_wr32(dev, 0x400784, inst);
-	nv_wr32(dev, 0x400824, nv_rd32(dev, 0x400824) | 0x40);
-	nv_wr32(dev, 0x400320, nv_rd32(dev, 0x400320) | 0x11);
-	nv_wr32(dev, 0x400040, 0xffffffff);
-	(void)nv_rd32(dev, 0x400040);
-	nv_wr32(dev, 0x400040, 0x00000000);
-	nv_wr32(dev, 0x400304, nv_rd32(dev, 0x400304) | 1);
-
-	if (nouveau_wait_for_idle(dev))
-		nv_wr32(dev, 0x40032c, inst | (1<<31));
-	nv_wr32(dev, 0x400500, fifo);
-
-	return 0;
-}
-
-int
-nv50_graph_load_context(struct nouveau_channel *chan)
-{
-	uint32_t inst = chan->ramin->vinst >> 12;
-
-	NV_DEBUG(chan->dev, "ch%d\n", chan->id);
-	return nv50_graph_do_load_context(chan->dev, inst);
-}
-
-int
-nv50_graph_unload_context(struct drm_device *dev)
+nv50_graph_object_new(struct nouveau_channel *chan, int engine,
+		      u32 handle, u16 class)
 {
-	uint32_t inst;
+	struct drm_device *dev = chan->dev;
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_gpuobj *obj = NULL;
+	int ret;
 
-	inst  = nv_rd32(dev, NV50_PGRAPH_CTXCTL_CUR);
-	if (!(inst & NV50_PGRAPH_CTXCTL_CUR_LOADED))
-		return 0;
-	inst &= NV50_PGRAPH_CTXCTL_CUR_INSTANCE;
+	ret = nouveau_gpuobj_new(dev, chan, 16, 16, NVOBJ_FLAG_ZERO_FREE, &obj);
+	if (ret)
+		return ret;
+	obj->engine = 1;
+	obj->class  = class;
 
-	nouveau_wait_for_idle(dev);
-	nv_wr32(dev, 0x400784, inst);
-	nv_wr32(dev, 0x400824, nv_rd32(dev, 0x400824) | 0x20);
-	nv_wr32(dev, 0x400304, nv_rd32(dev, 0x400304) | 0x01);
-	nouveau_wait_for_idle(dev);
+	nv_wo32(obj, 0x00, class);
+	nv_wo32(obj, 0x04, 0x00000000);
+	nv_wo32(obj, 0x08, 0x00000000);
+	nv_wo32(obj, 0x0c, 0x00000000);
+	dev_priv->engine.instmem.flush(dev);
 
-	nv_wr32(dev, NV50_PGRAPH_CTXCTL_CUR, inst);
-	return 0;
+	ret = nouveau_ramht_insert(chan, handle, obj);
+	nouveau_gpuobj_ref(NULL, &obj);
+	return ret;
 }
 
 static void
@@ -442,68 +444,15 @@
 	return 0;
 }
 
-static int
-nv50_graph_register(struct drm_device *dev)
-{
-	struct drm_nouveau_private *dev_priv = dev->dev_private;
-
-	if (dev_priv->engine.graph.registered)
-		return 0;
-
-	NVOBJ_CLASS(dev, 0x506e, SW); /* nvsw */
-	NVOBJ_MTHD (dev, 0x506e, 0x018c, nv50_graph_nvsw_dma_vblsem);
-	NVOBJ_MTHD (dev, 0x506e, 0x0400, nv50_graph_nvsw_vblsem_offset);
-	NVOBJ_MTHD (dev, 0x506e, 0x0404, nv50_graph_nvsw_vblsem_release_val);
-	NVOBJ_MTHD (dev, 0x506e, 0x0408, nv50_graph_nvsw_vblsem_release);
-	NVOBJ_MTHD (dev, 0x506e, 0x0500, nv50_graph_nvsw_mthd_page_flip);
-
-	NVOBJ_CLASS(dev, 0x0030, GR); /* null */
-	NVOBJ_CLASS(dev, 0x5039, GR); /* m2mf */
-	NVOBJ_CLASS(dev, 0x502d, GR); /* 2d */
 
-	/* tesla */
-	if (dev_priv->chipset == 0x50)
-		NVOBJ_CLASS(dev, 0x5097, GR); /* tesla (nv50) */
-	else
-	if (dev_priv->chipset < 0xa0)
-		NVOBJ_CLASS(dev, 0x8297, GR); /* tesla (nv8x/nv9x) */
-	else {
-		switch (dev_priv->chipset) {
-		case 0xa0:
-		case 0xaa:
-		case 0xac:
-			NVOBJ_CLASS(dev, 0x8397, GR);
-			break;
-		case 0xa3:
-		case 0xa5:
-		case 0xa8:
-			NVOBJ_CLASS(dev, 0x8597, GR);
-			break;
-		case 0xaf:
-			NVOBJ_CLASS(dev, 0x8697, GR);
-			break;
-		}
-	}
-
-	/* compute */
-	NVOBJ_CLASS(dev, 0x50c0, GR);
-	if (dev_priv->chipset  > 0xa0 &&
-	    dev_priv->chipset != 0xaa &&
-	    dev_priv->chipset != 0xac)
-		NVOBJ_CLASS(dev, 0x85c0, GR);
-
-	dev_priv->engine.graph.registered = true;
-	return 0;
-}
-
-void
-nv50_graph_tlb_flush(struct drm_device *dev)
+static void
+nv50_graph_tlb_flush(struct drm_device *dev, int engine)
 {
 	nv50_vm_flush_engine(dev, 0);
 }
 
-void
-nv84_graph_tlb_flush(struct drm_device *dev)
+static void
+nv84_graph_tlb_flush(struct drm_device *dev, int engine)
 {
 	struct drm_nouveau_private *dev_priv = dev->dev_private;
 	struct nouveau_timer_engine *ptimer = &dev_priv->engine.timer;
@@ -548,8 +497,7 @@
 	spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags);
 }
 
-static struct nouveau_enum nv50_mp_exec_error_names[] =
-{
+static struct nouveau_enum nv50_mp_exec_error_names[] = {
 	{ 3, "STACK_UNDERFLOW", NULL },
 	{ 4, "QUADON_ACTIVE", NULL },
 	{ 8, "TIMEOUT", NULL },
@@ -663,7 +611,7 @@
 			nv_rd32(dev, addr + 0x20);
 			pc = nv_rd32(dev, addr + 0x24);
 			oplow = nv_rd32(dev, addr + 0x70);
-			ophigh= nv_rd32(dev, addr + 0x74);
+			ophigh = nv_rd32(dev, addr + 0x74);
 			NV_INFO(dev, "PGRAPH_TRAP_MP_EXEC - "
 					"TP %d MP %d: ", tpid, i);
 			nouveau_enum_print(nv50_mp_exec_error_names, status);
@@ -991,7 +939,7 @@
 	return 1;
 }
 
-static int
+int
 nv50_graph_isr_chid(struct drm_device *dev, u64 inst)
 {
 	struct drm_nouveau_private *dev_priv = dev->dev_private;
@@ -1073,3 +1021,101 @@
 	if (nv_rd32(dev, 0x400824) & (1 << 31))
 		nv_wr32(dev, 0x400824, nv_rd32(dev, 0x400824) & ~(1 << 31));
 }
+
+static void
+nv50_graph_destroy(struct drm_device *dev, int engine)
+{
+	struct nv50_graph_engine *pgraph = nv_engine(dev, engine);
+
+	NVOBJ_ENGINE_DEL(dev, GR);
+
+	nouveau_irq_unregister(dev, 12);
+	kfree(pgraph);
+}
+
+int
+nv50_graph_create(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nv50_graph_engine *pgraph;
+	struct nouveau_grctx ctx = {};
+	int ret;
+
+	pgraph = kzalloc(sizeof(*pgraph),GFP_KERNEL);
+	if (!pgraph)
+		return -ENOMEM;
+
+	ctx.dev = dev;
+	ctx.mode = NOUVEAU_GRCTX_PROG;
+	ctx.data = pgraph->ctxprog;
+	ctx.ctxprog_max = ARRAY_SIZE(pgraph->ctxprog);
+
+	ret = nv50_grctx_init(&ctx);
+	if (ret) {
+		NV_ERROR(dev, "PGRAPH: ctxprog build failed\n");
+		kfree(pgraph);
+		return 0;
+	}
+
+	pgraph->grctx_size = ctx.ctxvals_pos * 4;
+	pgraph->ctxprog_size = ctx.ctxprog_len;
+
+	pgraph->base.destroy = nv50_graph_destroy;
+	pgraph->base.init = nv50_graph_init;
+	pgraph->base.fini = nv50_graph_fini;
+	pgraph->base.context_new = nv50_graph_context_new;
+	pgraph->base.context_del = nv50_graph_context_del;
+	pgraph->base.object_new = nv50_graph_object_new;
+	if (dev_priv->chipset == 0x50 || dev_priv->chipset == 0xac)
+		pgraph->base.tlb_flush = nv50_graph_tlb_flush;
+	else
+		pgraph->base.tlb_flush = nv84_graph_tlb_flush;
+
+	nouveau_irq_register(dev, 12, nv50_graph_isr);
+
+	/* NVSW really doesn't live here... */
+	NVOBJ_CLASS(dev, 0x506e, SW); /* nvsw */
+	NVOBJ_MTHD (dev, 0x506e, 0x018c, nv50_graph_nvsw_dma_vblsem);
+	NVOBJ_MTHD (dev, 0x506e, 0x0400, nv50_graph_nvsw_vblsem_offset);
+	NVOBJ_MTHD (dev, 0x506e, 0x0404, nv50_graph_nvsw_vblsem_release_val);
+	NVOBJ_MTHD (dev, 0x506e, 0x0408, nv50_graph_nvsw_vblsem_release);
+	NVOBJ_MTHD (dev, 0x506e, 0x0500, nv50_graph_nvsw_mthd_page_flip);
+
+	NVOBJ_ENGINE_ADD(dev, GR, &pgraph->base);
+	NVOBJ_CLASS(dev, 0x0030, GR); /* null */
+	NVOBJ_CLASS(dev, 0x5039, GR); /* m2mf */
+	NVOBJ_CLASS(dev, 0x502d, GR); /* 2d */
+
+	/* tesla */
+	if (dev_priv->chipset == 0x50)
+		NVOBJ_CLASS(dev, 0x5097, GR); /* tesla (nv50) */
+	else
+	if (dev_priv->chipset < 0xa0)
+		NVOBJ_CLASS(dev, 0x8297, GR); /* tesla (nv8x/nv9x) */
+	else {
+		switch (dev_priv->chipset) {
+		case 0xa0:
+		case 0xaa:
+		case 0xac:
+			NVOBJ_CLASS(dev, 0x8397, GR);
+			break;
+		case 0xa3:
+		case 0xa5:
+		case 0xa8:
+			NVOBJ_CLASS(dev, 0x8597, GR);
+			break;
+		case 0xaf:
+			NVOBJ_CLASS(dev, 0x8697, GR);
+			break;
+		}
+	}
+
+	/* compute */
+	NVOBJ_CLASS(dev, 0x50c0, GR);
+	if (dev_priv->chipset  > 0xa0 &&
+	    dev_priv->chipset != 0xaa &&
+	    dev_priv->chipset != 0xac)
+		NVOBJ_CLASS(dev, 0x85c0, GR);
+
+	return 0;
+}
diff -druN linux-2.6.39-libre/drivers/gpu/drm/nouveau/nv50_grctx.c linux-3.0-rc7-libre/drivers/gpu/drm/nouveau/nv50_grctx.c
--- linux-2.6.39-libre/drivers/gpu/drm/nouveau/nv50_grctx.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/gpu/drm/nouveau/nv50_grctx.c	2011-07-11 19:51:52.000000000 -0400
@@ -747,7 +747,7 @@
 				gr_def(ctx, offset + 0x64, 0x0000001f);
 				gr_def(ctx, offset + 0x68, 0x0000000f);
 				gr_def(ctx, offset + 0x6c, 0x0000000f);
-			} else if(dev_priv->chipset < 0xa0) {
+			} else if (dev_priv->chipset < 0xa0) {
 				cp_ctx(ctx, offset + 0x50, 1);
 				cp_ctx(ctx, offset + 0x70, 1);
 			} else {
@@ -924,7 +924,7 @@
 		dd_emit(ctx, 1, 0);	/* 0000007f MULTISAMPLE_SAMPLES_LOG2 */
 	} else {
 		dd_emit(ctx, 1, 0);	/* 0000000f MULTISAMPLE_SAMPLES_LOG2 */
-	} 
+	}
 	dd_emit(ctx, 1, 0xc);		/* 000000ff SEMANTIC_COLOR.BFC0_ID */
 	if (dev_priv->chipset != 0x50)
 		dd_emit(ctx, 1, 0);	/* 00000001 SEMANTIC_COLOR.CLMP_EN */
@@ -1803,9 +1803,7 @@
 		xf_emit(ctx, 1, 0);	/* 1ff */
 		xf_emit(ctx, 8, 0);	/* 0? */
 		xf_emit(ctx, 9, 0);	/* ffffffff, 7ff */
-	}
-	else
-	{
+	} else {
 		xf_emit(ctx, 0xc, 0);	/* RO */
 		/* SEEK */
 		xf_emit(ctx, 0xe10, 0); /* 190 * 9: 8*ffffffff, 7ff */
@@ -2836,7 +2834,7 @@
 	xf_emit(ctx, 1, 1);		/* 00000001 DST_LINEAR */
 	if (IS_NVA3F(dev_priv->chipset))
 		xf_emit(ctx, 1, 1);	/* 0000001f tesla UNK169C */
-	if(dev_priv->chipset == 0x50)
+	if (dev_priv->chipset == 0x50)
 		xf_emit(ctx, 1, 0);	/* ff */
 	else
 		xf_emit(ctx, 3, 0);	/* 1, 7, 3ff */
diff -druN linux-2.6.39-libre/drivers/gpu/drm/nouveau/nv50_mpeg.c linux-3.0-rc7-libre/drivers/gpu/drm/nouveau/nv50_mpeg.c
--- linux-2.6.39-libre/drivers/gpu/drm/nouveau/nv50_mpeg.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/gpu/drm/nouveau/nv50_mpeg.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,256 @@
+/*
+ * Copyright 2011 Red Hat Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: Ben Skeggs
+ */
+
+#include "drmP.h"
+#include "nouveau_drv.h"
+#include "nouveau_ramht.h"
+
+struct nv50_mpeg_engine {
+	struct nouveau_exec_engine base;
+};
+
+static inline u32
+CTX_PTR(struct drm_device *dev, u32 offset)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+
+	if (dev_priv->chipset == 0x50)
+		offset += 0x0260;
+	else
+		offset += 0x0060;
+
+	return offset;
+}
+
+static int
+nv50_mpeg_context_new(struct nouveau_channel *chan, int engine)
+{
+	struct drm_device *dev = chan->dev;
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_gpuobj *ramin = chan->ramin;
+	struct nouveau_gpuobj *ctx = NULL;
+	int ret;
+
+	NV_DEBUG(dev, "ch%d\n", chan->id);
+
+	ret = nouveau_gpuobj_new(dev, chan, 128 * 4, 0, NVOBJ_FLAG_ZERO_ALLOC |
+				 NVOBJ_FLAG_ZERO_FREE, &ctx);
+	if (ret)
+		return ret;
+
+	nv_wo32(ramin, CTX_PTR(dev, 0x00), 0x80190002);
+	nv_wo32(ramin, CTX_PTR(dev, 0x04), ctx->vinst + ctx->size - 1);
+	nv_wo32(ramin, CTX_PTR(dev, 0x08), ctx->vinst);
+	nv_wo32(ramin, CTX_PTR(dev, 0x0c), 0);
+	nv_wo32(ramin, CTX_PTR(dev, 0x10), 0);
+	nv_wo32(ramin, CTX_PTR(dev, 0x14), 0x00010000);
+
+	nv_wo32(ctx, 0x70, 0x00801ec1);
+	nv_wo32(ctx, 0x7c, 0x0000037c);
+	dev_priv->engine.instmem.flush(dev);
+
+	chan->engctx[engine] = ctx;
+	return 0;
+}
+
+static void
+nv50_mpeg_context_del(struct nouveau_channel *chan, int engine)
+{
+	struct drm_nouveau_private *dev_priv = chan->dev->dev_private;
+	struct nouveau_gpuobj *ctx = chan->engctx[engine];
+	struct drm_device *dev = chan->dev;
+	unsigned long flags;
+	u32 inst, i;
+
+	if (!chan->ramin)
+		return;
+
+	inst  = chan->ramin->vinst >> 12;
+	inst |= 0x80000000;
+
+	spin_lock_irqsave(&dev_priv->context_switch_lock, flags);
+	nv_mask(dev, 0x00b32c, 0x00000001, 0x00000000);
+	if (nv_rd32(dev, 0x00b318) == inst)
+		nv_mask(dev, 0x00b318, 0x80000000, 0x00000000);
+	nv_mask(dev, 0x00b32c, 0x00000001, 0x00000001);
+	spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags);
+
+	for (i = 0x00; i <= 0x14; i += 4)
+		nv_wo32(chan->ramin, CTX_PTR(dev, i), 0x00000000);
+	nouveau_gpuobj_ref(NULL, &ctx);
+	chan->engctx[engine] = NULL;
+}
+
+static int
+nv50_mpeg_object_new(struct nouveau_channel *chan, int engine,
+		     u32 handle, u16 class)
+{
+	struct drm_device *dev = chan->dev;
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_gpuobj *obj = NULL;
+	int ret;
+
+	ret = nouveau_gpuobj_new(dev, chan, 16, 16, NVOBJ_FLAG_ZERO_FREE, &obj);
+	if (ret)
+		return ret;
+	obj->engine = 2;
+	obj->class  = class;
+
+	nv_wo32(obj, 0x00, class);
+	nv_wo32(obj, 0x04, 0x00000000);
+	nv_wo32(obj, 0x08, 0x00000000);
+	nv_wo32(obj, 0x0c, 0x00000000);
+	dev_priv->engine.instmem.flush(dev);
+
+	ret = nouveau_ramht_insert(chan, handle, obj);
+	nouveau_gpuobj_ref(NULL, &obj);
+	return ret;
+}
+
+static void
+nv50_mpeg_tlb_flush(struct drm_device *dev, int engine)
+{
+	nv50_vm_flush_engine(dev, 0x08);
+}
+
+static int
+nv50_mpeg_init(struct drm_device *dev, int engine)
+{
+	nv_wr32(dev, 0x00b32c, 0x00000000);
+	nv_wr32(dev, 0x00b314, 0x00000100);
+	nv_wr32(dev, 0x00b0e0, 0x0000001a);
+
+	nv_wr32(dev, 0x00b220, 0x00000044);
+	nv_wr32(dev, 0x00b300, 0x00801ec1);
+	nv_wr32(dev, 0x00b390, 0x00000000);
+	nv_wr32(dev, 0x00b394, 0x00000000);
+	nv_wr32(dev, 0x00b398, 0x00000000);
+	nv_mask(dev, 0x00b32c, 0x00000001, 0x00000001);
+
+	nv_wr32(dev, 0x00b100, 0xffffffff);
+	nv_wr32(dev, 0x00b140, 0xffffffff);
+
+	if (!nv_wait(dev, 0x00b200, 0x00000001, 0x00000000)) {
+		NV_ERROR(dev, "PMPEG init: 0x%08x\n", nv_rd32(dev, 0x00b200));
+		return -EBUSY;
+	}
+
+	return 0;
+}
+
+static int
+nv50_mpeg_fini(struct drm_device *dev, int engine)
+{
+	/*XXX: context save for s/r */
+	nv_mask(dev, 0x00b32c, 0x00000001, 0x00000000);
+	nv_wr32(dev, 0x00b140, 0x00000000);
+	return 0;
+}
+
+static void
+nv50_mpeg_isr(struct drm_device *dev)
+{
+	u32 stat = nv_rd32(dev, 0x00b100);
+	u32 type = nv_rd32(dev, 0x00b230);
+	u32 mthd = nv_rd32(dev, 0x00b234);
+	u32 data = nv_rd32(dev, 0x00b238);
+	u32 show = stat;
+
+	if (stat & 0x01000000) {
+		/* happens on initial binding of the object */
+		if (type == 0x00000020 && mthd == 0x0000) {
+			nv_wr32(dev, 0x00b308, 0x00000100);
+			show &= ~0x01000000;
+		}
+	}
+
+	if (show && nouveau_ratelimit()) {
+		NV_INFO(dev, "PMPEG - 0x%08x 0x%08x 0x%08x 0x%08x\n",
+			stat, type, mthd, data);
+	}
+
+	nv_wr32(dev, 0x00b100, stat);
+	nv_wr32(dev, 0x00b230, 0x00000001);
+	nv50_fb_vm_trap(dev, 1);
+}
+
+static void
+nv50_vpe_isr(struct drm_device *dev)
+{
+	if (nv_rd32(dev, 0x00b100))
+		nv50_mpeg_isr(dev);
+
+	if (nv_rd32(dev, 0x00b800)) {
+		u32 stat = nv_rd32(dev, 0x00b800);
+		NV_INFO(dev, "PMSRCH: 0x%08x\n", stat);
+		nv_wr32(dev, 0xb800, stat);
+	}
+}
+
+static void
+nv50_mpeg_destroy(struct drm_device *dev, int engine)
+{
+	struct nv50_mpeg_engine *pmpeg = nv_engine(dev, engine);
+
+	nouveau_irq_unregister(dev, 0);
+
+	NVOBJ_ENGINE_DEL(dev, MPEG);
+	kfree(pmpeg);
+}
+
+int
+nv50_mpeg_create(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nv50_mpeg_engine *pmpeg;
+
+	pmpeg = kzalloc(sizeof(*pmpeg), GFP_KERNEL);
+	if (!pmpeg)
+		return -ENOMEM;
+
+	pmpeg->base.destroy = nv50_mpeg_destroy;
+	pmpeg->base.init = nv50_mpeg_init;
+	pmpeg->base.fini = nv50_mpeg_fini;
+	pmpeg->base.context_new = nv50_mpeg_context_new;
+	pmpeg->base.context_del = nv50_mpeg_context_del;
+	pmpeg->base.object_new = nv50_mpeg_object_new;
+	pmpeg->base.tlb_flush = nv50_mpeg_tlb_flush;
+
+	if (dev_priv->chipset == 0x50) {
+		nouveau_irq_register(dev, 0, nv50_vpe_isr);
+		NVOBJ_ENGINE_ADD(dev, MPEG, &pmpeg->base);
+		NVOBJ_CLASS(dev, 0x3174, MPEG);
+#if 0
+		NVOBJ_ENGINE_ADD(dev, ME, &pme->base);
+		NVOBJ_CLASS(dev, 0x4075, ME);
+#endif
+	} else {
+		nouveau_irq_register(dev, 0, nv50_mpeg_isr);
+		NVOBJ_ENGINE_ADD(dev, MPEG, &pmpeg->base);
+		NVOBJ_CLASS(dev, 0x8274, MPEG);
+	}
+
+	return 0;
+
+}
diff -druN linux-2.6.39-libre/drivers/gpu/drm/nouveau/nv50_pm.c linux-3.0-rc7-libre/drivers/gpu/drm/nouveau/nv50_pm.c
--- linux-2.6.39-libre/drivers/gpu/drm/nouveau/nv50_pm.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/gpu/drm/nouveau/nv50_pm.c	2011-07-11 19:51:52.000000000 -0400
@@ -47,6 +47,21 @@
 
 	reg0 = nv_rd32(dev, pll.reg + 0);
 	reg1 = nv_rd32(dev, pll.reg + 4);
+
+	if ((reg0 & 0x80000000) == 0) {
+		if (id == PLL_SHADER) {
+			NV_DEBUG(dev, "Shader PLL is disabled. "
+				"Shader clock is twice the core\n");
+			ret = nv50_pm_clock_get(dev, PLL_CORE);
+			if (ret > 0)
+				return ret << 1;
+		} else if (id == PLL_MEMORY) {
+			NV_DEBUG(dev, "Memory PLL is disabled. "
+				"Memory clock is equal to the ref_clk\n");
+			return pll.refclk;
+		}
+	}
+
 	P = (reg0 & 0x00070000) >> 16;
 	N = (reg1 & 0x0000ff00) >> 8;
 	M = (reg1 & 0x000000ff);
diff -druN linux-2.6.39-libre/drivers/gpu/drm/nouveau/nv50_vm.c linux-3.0-rc7-libre/drivers/gpu/drm/nouveau/nv50_vm.c
--- linux-2.6.39-libre/drivers/gpu/drm/nouveau/nv50_vm.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/gpu/drm/nouveau/nv50_vm.c	2011-07-11 19:51:52.000000000 -0400
@@ -151,8 +151,7 @@
 	struct drm_nouveau_private *dev_priv = vm->dev->dev_private;
 	struct nouveau_instmem_engine *pinstmem = &dev_priv->engine.instmem;
 	struct nouveau_fifo_engine *pfifo = &dev_priv->engine.fifo;
-	struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph;
-	struct nouveau_crypt_engine *pcrypt = &dev_priv->engine.crypt;
+	int i;
 
 	pinstmem->flush(vm->dev);
 
@@ -163,11 +162,10 @@
 	}
 
 	pfifo->tlb_flush(vm->dev);
-
-	if (atomic_read(&vm->pgraph_refs))
-		pgraph->tlb_flush(vm->dev);
-	if (atomic_read(&vm->pcrypt_refs))
-		pcrypt->tlb_flush(vm->dev);
+	for (i = 0; i < NVOBJ_ENGINE_NR; i++) {
+		if (atomic_read(&vm->engref[i]))
+			dev_priv->eng[i]->tlb_flush(vm->dev, i);
+	}
 }
 
 void
diff -druN linux-2.6.39-libre/drivers/gpu/drm/nouveau/nv84_crypt.c linux-3.0-rc7-libre/drivers/gpu/drm/nouveau/nv84_crypt.c
--- linux-2.6.39-libre/drivers/gpu/drm/nouveau/nv84_crypt.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/gpu/drm/nouveau/nv84_crypt.c	2011-07-11 19:51:52.000000000 -0400
@@ -26,46 +26,48 @@
 #include "nouveau_drv.h"
 #include "nouveau_util.h"
 #include "nouveau_vm.h"
+#include "nouveau_ramht.h"
 
-static void nv84_crypt_isr(struct drm_device *);
+struct nv84_crypt_engine {
+	struct nouveau_exec_engine base;
+};
 
-int
-nv84_crypt_create_context(struct nouveau_channel *chan)
+static int
+nv84_crypt_context_new(struct nouveau_channel *chan, int engine)
 {
 	struct drm_device *dev = chan->dev;
 	struct drm_nouveau_private *dev_priv = dev->dev_private;
 	struct nouveau_gpuobj *ramin = chan->ramin;
+	struct nouveau_gpuobj *ctx;
 	int ret;
 
 	NV_DEBUG(dev, "ch%d\n", chan->id);
 
-	ret = nouveau_gpuobj_new(dev, chan, 256, 0,
-				 NVOBJ_FLAG_ZERO_ALLOC | NVOBJ_FLAG_ZERO_FREE,
-				 &chan->crypt_ctx);
+	ret = nouveau_gpuobj_new(dev, chan, 256, 0, NVOBJ_FLAG_ZERO_ALLOC |
+				 NVOBJ_FLAG_ZERO_FREE, &ctx);
 	if (ret)
 		return ret;
 
 	nv_wo32(ramin, 0xa0, 0x00190000);
-	nv_wo32(ramin, 0xa4, chan->crypt_ctx->vinst + 0xff);
-	nv_wo32(ramin, 0xa8, chan->crypt_ctx->vinst);
+	nv_wo32(ramin, 0xa4, ctx->vinst + ctx->size - 1);
+	nv_wo32(ramin, 0xa8, ctx->vinst);
 	nv_wo32(ramin, 0xac, 0);
 	nv_wo32(ramin, 0xb0, 0);
 	nv_wo32(ramin, 0xb4, 0);
-
 	dev_priv->engine.instmem.flush(dev);
-	atomic_inc(&chan->vm->pcrypt_refs);
+
+	atomic_inc(&chan->vm->engref[engine]);
+	chan->engctx[engine] = ctx;
 	return 0;
 }
 
-void
-nv84_crypt_destroy_context(struct nouveau_channel *chan)
+static void
+nv84_crypt_context_del(struct nouveau_channel *chan, int engine)
 {
+	struct nouveau_gpuobj *ctx = chan->engctx[engine];
 	struct drm_device *dev = chan->dev;
 	u32 inst;
 
-	if (!chan->crypt_ctx)
-		return;
-
 	inst  = (chan->ramin->vinst >> 12);
 	inst |= 0x80000000;
 
@@ -80,43 +82,39 @@
 		nv_mask(dev, 0x10218c, 0x80000000, 0x00000000);
 	nv_wr32(dev, 0x10200c, 0x00000010);
 
-	nouveau_gpuobj_ref(NULL, &chan->crypt_ctx);
-	atomic_dec(&chan->vm->pcrypt_refs);
-}
+	nouveau_gpuobj_ref(NULL, &ctx);
 
-void
-nv84_crypt_tlb_flush(struct drm_device *dev)
-{
-	nv50_vm_flush_engine(dev, 0x0a);
+	atomic_dec(&chan->vm->engref[engine]);
+	chan->engctx[engine] = NULL;
 }
 
-int
-nv84_crypt_init(struct drm_device *dev)
+static int
+nv84_crypt_object_new(struct nouveau_channel *chan, int engine,
+		      u32 handle, u16 class)
 {
+	struct drm_device *dev = chan->dev;
 	struct drm_nouveau_private *dev_priv = dev->dev_private;
-	struct nouveau_crypt_engine *pcrypt = &dev_priv->engine.crypt;
-
-	if (!pcrypt->registered) {
-		NVOBJ_CLASS(dev, 0x74c1, CRYPT);
-		pcrypt->registered = true;
-	}
+	struct nouveau_gpuobj *obj = NULL;
+	int ret;
 
-	nv_mask(dev, 0x000200, 0x00004000, 0x00000000);
-	nv_mask(dev, 0x000200, 0x00004000, 0x00004000);
+	ret = nouveau_gpuobj_new(dev, chan, 16, 16, NVOBJ_FLAG_ZERO_FREE, &obj);
+	if (ret)
+		return ret;
+	obj->engine = 5;
+	obj->class  = class;
 
-	nouveau_irq_register(dev, 14, nv84_crypt_isr);
-	nv_wr32(dev, 0x102130, 0xffffffff);
-	nv_wr32(dev, 0x102140, 0xffffffbf);
+	nv_wo32(obj, 0x00, class);
+	dev_priv->engine.instmem.flush(dev);
 
-	nv_wr32(dev, 0x10200c, 0x00000010);
-	return 0;
+	ret = nouveau_ramht_insert(chan, handle, obj);
+	nouveau_gpuobj_ref(NULL, &obj);
+	return ret;
 }
 
-void
-nv84_crypt_fini(struct drm_device *dev)
+static void
+nv84_crypt_tlb_flush(struct drm_device *dev, int engine)
 {
-	nv_wr32(dev, 0x102140, 0x00000000);
-	nouveau_irq_unregister(dev, 14);
+	nv50_vm_flush_engine(dev, 0x0a);
 }
 
 static void
@@ -138,3 +136,58 @@
 
 	nv50_fb_vm_trap(dev, show);
 }
+
+static int
+nv84_crypt_fini(struct drm_device *dev, int engine)
+{
+	nv_wr32(dev, 0x102140, 0x00000000);
+	return 0;
+}
+
+static int
+nv84_crypt_init(struct drm_device *dev, int engine)
+{
+	nv_mask(dev, 0x000200, 0x00004000, 0x00000000);
+	nv_mask(dev, 0x000200, 0x00004000, 0x00004000);
+
+	nv_wr32(dev, 0x102130, 0xffffffff);
+	nv_wr32(dev, 0x102140, 0xffffffbf);
+
+	nv_wr32(dev, 0x10200c, 0x00000010);
+	return 0;
+}
+
+static void
+nv84_crypt_destroy(struct drm_device *dev, int engine)
+{
+	struct nv84_crypt_engine *pcrypt = nv_engine(dev, engine);
+
+	NVOBJ_ENGINE_DEL(dev, CRYPT);
+
+	nouveau_irq_unregister(dev, 14);
+	kfree(pcrypt);
+}
+
+int
+nv84_crypt_create(struct drm_device *dev)
+{
+	struct nv84_crypt_engine *pcrypt;
+
+	pcrypt = kzalloc(sizeof(*pcrypt), GFP_KERNEL);
+	if (!pcrypt)
+		return -ENOMEM;
+
+	pcrypt->base.destroy = nv84_crypt_destroy;
+	pcrypt->base.init = nv84_crypt_init;
+	pcrypt->base.fini = nv84_crypt_fini;
+	pcrypt->base.context_new = nv84_crypt_context_new;
+	pcrypt->base.context_del = nv84_crypt_context_del;
+	pcrypt->base.object_new = nv84_crypt_object_new;
+	pcrypt->base.tlb_flush = nv84_crypt_tlb_flush;
+
+	nouveau_irq_register(dev, 14, nv84_crypt_isr);
+
+	NVOBJ_ENGINE_ADD(dev, CRYPT, &pcrypt->base);
+	NVOBJ_CLASS (dev, 0x74c1, CRYPT);
+	return 0;
+}
diff -druN linux-2.6.39-libre/drivers/gpu/drm/nouveau/nva3_copy.c linux-3.0-rc7-libre/drivers/gpu/drm/nouveau/nva3_copy.c
--- linux-2.6.39-libre/drivers/gpu/drm/nouveau/nva3_copy.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/gpu/drm/nouveau/nva3_copy.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,226 @@
+/*
+ * Copyright 2011 Red Hat Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: Ben Skeggs
+ */
+
+#include <linux/firmware.h>
+#include "drmP.h"
+#include "nouveau_drv.h"
+#include "nouveau_util.h"
+#include "nouveau_vm.h"
+#include "nouveau_ramht.h"
+#include "nva3_copy.fuc.h"
+
+struct nva3_copy_engine {
+	struct nouveau_exec_engine base;
+};
+
+static int
+nva3_copy_context_new(struct nouveau_channel *chan, int engine)
+{
+	struct drm_device *dev = chan->dev;
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_gpuobj *ramin = chan->ramin;
+	struct nouveau_gpuobj *ctx = NULL;
+	int ret;
+
+	NV_DEBUG(dev, "ch%d\n", chan->id);
+
+	ret = nouveau_gpuobj_new(dev, chan, 256, 0, NVOBJ_FLAG_ZERO_ALLOC |
+				 NVOBJ_FLAG_ZERO_FREE, &ctx);
+	if (ret)
+		return ret;
+
+	nv_wo32(ramin, 0xc0, 0x00190000);
+	nv_wo32(ramin, 0xc4, ctx->vinst + ctx->size - 1);
+	nv_wo32(ramin, 0xc8, ctx->vinst);
+	nv_wo32(ramin, 0xcc, 0x00000000);
+	nv_wo32(ramin, 0xd0, 0x00000000);
+	nv_wo32(ramin, 0xd4, 0x00000000);
+	dev_priv->engine.instmem.flush(dev);
+
+	atomic_inc(&chan->vm->engref[engine]);
+	chan->engctx[engine] = ctx;
+	return 0;
+}
+
+static int
+nva3_copy_object_new(struct nouveau_channel *chan, int engine,
+		     u32 handle, u16 class)
+{
+	struct nouveau_gpuobj *ctx = chan->engctx[engine];
+
+	/* fuc engine doesn't need an object, our ramht code does.. */
+	ctx->engine = 3;
+	ctx->class  = class;
+	return nouveau_ramht_insert(chan, handle, ctx);
+}
+
+static void
+nva3_copy_context_del(struct nouveau_channel *chan, int engine)
+{
+	struct nouveau_gpuobj *ctx = chan->engctx[engine];
+	struct drm_device *dev = chan->dev;
+	u32 inst;
+
+	inst  = (chan->ramin->vinst >> 12);
+	inst |= 0x40000000;
+
+	/* disable fifo access */
+	nv_wr32(dev, 0x104048, 0x00000000);
+	/* mark channel as unloaded if it's currently active */
+	if (nv_rd32(dev, 0x104050) == inst)
+		nv_mask(dev, 0x104050, 0x40000000, 0x00000000);
+	/* mark next channel as invalid if it's about to be loaded */
+	if (nv_rd32(dev, 0x104054) == inst)
+		nv_mask(dev, 0x104054, 0x40000000, 0x00000000);
+	/* restore fifo access */
+	nv_wr32(dev, 0x104048, 0x00000003);
+
+	for (inst = 0xc0; inst <= 0xd4; inst += 4)
+		nv_wo32(chan->ramin, inst, 0x00000000);
+
+	nouveau_gpuobj_ref(NULL, &ctx);
+
+	atomic_dec(&chan->vm->engref[engine]);
+	chan->engctx[engine] = ctx;
+}
+
+static void
+nva3_copy_tlb_flush(struct drm_device *dev, int engine)
+{
+	nv50_vm_flush_engine(dev, 0x0d);
+}
+
+static int
+nva3_copy_init(struct drm_device *dev, int engine)
+{
+	int i;
+
+	nv_mask(dev, 0x000200, 0x00002000, 0x00000000);
+	nv_mask(dev, 0x000200, 0x00002000, 0x00002000);
+	nv_wr32(dev, 0x104014, 0xffffffff); /* disable all interrupts */
+
+	/* upload ucode */
+	nv_wr32(dev, 0x1041c0, 0x01000000);
+	for (i = 0; i < sizeof(nva3_pcopy_data) / 4; i++)
+		nv_wr32(dev, 0x1041c4, nva3_pcopy_data[i]);
+
+	nv_wr32(dev, 0x104180, 0x01000000);
+	for (i = 0; i < sizeof(nva3_pcopy_code) / 4; i++) {
+		if ((i & 0x3f) == 0)
+			nv_wr32(dev, 0x104188, i >> 6);
+		nv_wr32(dev, 0x104184, nva3_pcopy_code[i]);
+	}
+
+	/* start it running */
+	nv_wr32(dev, 0x10410c, 0x00000000);
+	nv_wr32(dev, 0x104104, 0x00000000); /* ENTRY */
+	nv_wr32(dev, 0x104100, 0x00000002); /* TRIGGER */
+	return 0;
+}
+
+static int
+nva3_copy_fini(struct drm_device *dev, int engine)
+{
+	nv_mask(dev, 0x104048, 0x00000003, 0x00000000);
+
+	/* trigger fuc context unload */
+	nv_wait(dev, 0x104008, 0x0000000c, 0x00000000);
+	nv_mask(dev, 0x104054, 0x40000000, 0x00000000);
+	nv_wr32(dev, 0x104000, 0x00000008);
+	nv_wait(dev, 0x104008, 0x00000008, 0x00000000);
+
+	nv_wr32(dev, 0x104014, 0xffffffff);
+	return 0;
+}
+
+static struct nouveau_enum nva3_copy_isr_error_name[] = {
+	{ 0x0001, "ILLEGAL_MTHD" },
+	{ 0x0002, "INVALID_ENUM" },
+	{ 0x0003, "INVALID_BITFIELD" },
+	{}
+};
+
+static void
+nva3_copy_isr(struct drm_device *dev)
+{
+	u32 dispatch = nv_rd32(dev, 0x10401c);
+	u32 stat = nv_rd32(dev, 0x104008) & dispatch & ~(dispatch >> 16);
+	u32 inst = nv_rd32(dev, 0x104050) & 0x3fffffff;
+	u32 ssta = nv_rd32(dev, 0x104040) & 0x0000ffff;
+	u32 addr = nv_rd32(dev, 0x104040) >> 16;
+	u32 mthd = (addr & 0x07ff) << 2;
+	u32 subc = (addr & 0x3800) >> 11;
+	u32 data = nv_rd32(dev, 0x104044);
+	int chid = nv50_graph_isr_chid(dev, inst);
+
+	if (stat & 0x00000040) {
+		NV_INFO(dev, "PCOPY: DISPATCH_ERROR [");
+		nouveau_enum_print(nva3_copy_isr_error_name, ssta);
+		printk("] ch %d [0x%08x] subc %d mthd 0x%04x data 0x%08x\n",
+			chid, inst, subc, mthd, data);
+		nv_wr32(dev, 0x104004, 0x00000040);
+		stat &= ~0x00000040;
+	}
+
+	if (stat) {
+		NV_INFO(dev, "PCOPY: unhandled intr 0x%08x\n", stat);
+		nv_wr32(dev, 0x104004, stat);
+	}
+	nv50_fb_vm_trap(dev, 1);
+}
+
+static void
+nva3_copy_destroy(struct drm_device *dev, int engine)
+{
+	struct nva3_copy_engine *pcopy = nv_engine(dev, engine);
+
+	nouveau_irq_unregister(dev, 22);
+
+	NVOBJ_ENGINE_DEL(dev, COPY0);
+	kfree(pcopy);
+}
+
+int
+nva3_copy_create(struct drm_device *dev)
+{
+	struct nva3_copy_engine *pcopy;
+
+	pcopy = kzalloc(sizeof(*pcopy), GFP_KERNEL);
+	if (!pcopy)
+		return -ENOMEM;
+
+	pcopy->base.destroy = nva3_copy_destroy;
+	pcopy->base.init = nva3_copy_init;
+	pcopy->base.fini = nva3_copy_fini;
+	pcopy->base.context_new = nva3_copy_context_new;
+	pcopy->base.context_del = nva3_copy_context_del;
+	pcopy->base.object_new = nva3_copy_object_new;
+	pcopy->base.tlb_flush = nva3_copy_tlb_flush;
+
+	nouveau_irq_register(dev, 22, nva3_copy_isr);
+
+	NVOBJ_ENGINE_ADD(dev, COPY0, &pcopy->base);
+	NVOBJ_CLASS(dev, 0x85b5, COPY0);
+	return 0;
+}
diff -druN linux-2.6.39-libre/drivers/gpu/drm/nouveau/nva3_copy.fuc linux-3.0-rc7-libre/drivers/gpu/drm/nouveau/nva3_copy.fuc
--- linux-2.6.39-libre/drivers/gpu/drm/nouveau/nva3_copy.fuc	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/gpu/drm/nouveau/nva3_copy.fuc	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,870 @@
+/* fuc microcode for copy engine on nva3- chipsets
+ *
+ * Copyright 2011 Red Hat Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: Ben Skeggs
+ */
+
+/* To build for nva3:nvc0
+ *    m4 -DNVA3 nva3_copy.fuc | envyas -a -w -m fuc -V nva3 -o nva3_copy.fuc.h
+ *
+ * To build for nvc0-
+ *    m4 -DNVC0 nva3_copy.fuc | envyas -a -w -m fuc -V nva3 -o nvc0_copy.fuc.h
+ */
+
+ifdef(`NVA3',
+.section nva3_pcopy_data,
+.section nvc0_pcopy_data
+)
+
+ctx_object:                   .b32 0
+ifdef(`NVA3',
+ctx_dma:
+ctx_dma_query:                .b32 0
+ctx_dma_src:                  .b32 0
+ctx_dma_dst:                  .b32 0
+,)
+.equ ctx_dma_count 3
+ctx_query_address_high:       .b32 0
+ctx_query_address_low:        .b32 0
+ctx_query_counter:            .b32 0
+ctx_src_address_high:         .b32 0
+ctx_src_address_low:          .b32 0
+ctx_src_pitch:                .b32 0
+ctx_src_tile_mode:            .b32 0
+ctx_src_xsize:                .b32 0
+ctx_src_ysize:                .b32 0
+ctx_src_zsize:                .b32 0
+ctx_src_zoff:                 .b32 0
+ctx_src_xoff:                 .b32 0
+ctx_src_yoff:                 .b32 0
+ctx_src_cpp:                  .b32 0
+ctx_dst_address_high:         .b32 0
+ctx_dst_address_low:          .b32 0
+ctx_dst_pitch:                .b32 0
+ctx_dst_tile_mode:            .b32 0
+ctx_dst_xsize:                .b32 0
+ctx_dst_ysize:                .b32 0
+ctx_dst_zsize:                .b32 0
+ctx_dst_zoff:                 .b32 0
+ctx_dst_xoff:                 .b32 0
+ctx_dst_yoff:                 .b32 0
+ctx_dst_cpp:                  .b32 0
+ctx_format:                   .b32 0
+ctx_swz_const0:               .b32 0
+ctx_swz_const1:               .b32 0
+ctx_xcnt:                     .b32 0
+ctx_ycnt:                     .b32 0
+.align 256
+
+dispatch_table:
+// mthd 0x0000, NAME
+.b16 0x000 1
+.b32 ctx_object                     ~0xffffffff
+// mthd 0x0100, NOP
+.b16 0x040 1
+.b32 0x00010000 + cmd_nop           ~0xffffffff
+// mthd 0x0140, PM_TRIGGER
+.b16 0x050 1
+.b32 0x00010000 + cmd_pm_trigger    ~0xffffffff
+ifdef(`NVA3', `
+// mthd 0x0180-0x018c, DMA_
+.b16 0x060 ctx_dma_count
+dispatch_dma:
+.b32 0x00010000 + cmd_dma           ~0xffffffff
+.b32 0x00010000 + cmd_dma           ~0xffffffff
+.b32 0x00010000 + cmd_dma           ~0xffffffff
+',)
+// mthd 0x0200-0x0218, SRC_TILE
+.b16 0x80 7
+.b32 ctx_src_tile_mode              ~0x00000fff
+.b32 ctx_src_xsize                  ~0x0007ffff
+.b32 ctx_src_ysize                  ~0x00001fff
+.b32 ctx_src_zsize                  ~0x000007ff
+.b32 ctx_src_zoff                   ~0x00000fff
+.b32 ctx_src_xoff                   ~0x0007ffff
+.b32 ctx_src_yoff                   ~0x00001fff
+// mthd 0x0220-0x0238, DST_TILE
+.b16 0x88 7
+.b32 ctx_dst_tile_mode              ~0x00000fff
+.b32 ctx_dst_xsize                  ~0x0007ffff
+.b32 ctx_dst_ysize                  ~0x00001fff
+.b32 ctx_dst_zsize                  ~0x000007ff
+.b32 ctx_dst_zoff                   ~0x00000fff
+.b32 ctx_dst_xoff                   ~0x0007ffff
+.b32 ctx_dst_yoff                   ~0x00001fff
+// mthd 0x0300-0x0304, EXEC, WRCACHE_FLUSH
+.b16 0xc0 2
+.b32 0x00010000 + cmd_exec          ~0xffffffff
+.b32 0x00010000 + cmd_wrcache_flush ~0xffffffff
+// mthd 0x030c-0x0340, various stuff
+.b16 0xc3 14
+.b32 ctx_src_address_high           ~0x000000ff
+.b32 ctx_src_address_low            ~0xfffffff0
+.b32 ctx_dst_address_high           ~0x000000ff
+.b32 ctx_dst_address_low            ~0xfffffff0
+.b32 ctx_src_pitch                  ~0x0007ffff
+.b32 ctx_dst_pitch                  ~0x0007ffff
+.b32 ctx_xcnt                       ~0x0000ffff
+.b32 ctx_ycnt                       ~0x00001fff
+.b32 ctx_format                     ~0x0333ffff
+.b32 ctx_swz_const0                 ~0xffffffff
+.b32 ctx_swz_const1                 ~0xffffffff
+.b32 ctx_query_address_high         ~0x000000ff
+.b32 ctx_query_address_low          ~0xffffffff
+.b32 ctx_query_counter              ~0xffffffff
+.b16 0x800 0
+
+ifdef(`NVA3',
+.section nva3_pcopy_code,
+.section nvc0_pcopy_code
+)
+
+main:
+   clear b32 $r0
+   mov $sp $r0
+
+   // setup i0 handler and route fifo and ctxswitch to it
+   mov $r1 ih
+   mov $iv0 $r1
+   mov $r1 0x400
+   movw $r2 0xfff3
+   sethi $r2 0
+   iowr I[$r2 + 0x300] $r2
+
+   // enable interrupts
+   or $r2 0xc
+   iowr I[$r1] $r2
+   bset $flags ie0
+
+   // enable fifo access and context switching
+   mov $r1 0x1200
+   mov $r2 3
+   iowr I[$r1] $r2
+
+   // sleep forever, waking for interrupts
+   bset $flags $p0
+   spin:
+      sleep $p0
+      bra spin
+
+// i0 handler
+ih:
+   iord $r1 I[$r0 + 0x200]
+
+   and $r2 $r1 0x00000008
+   bra e ih_no_chsw
+      call chsw
+   ih_no_chsw:
+   and $r2 $r1 0x00000004
+   bra e ih_no_cmd
+      call dispatch
+
+   ih_no_cmd:
+   and $r1 $r1 0x0000000c
+   iowr I[$r0 + 0x100] $r1
+   iret
+
+// $p1 direction (0 = unload, 1 = load)
+// $r3 channel
+swctx:
+   mov $r4 0x7700
+   mov $xtargets $r4
+ifdef(`NVA3', `
+   // target 7 hardcoded to ctx dma object
+   mov $xdbase $r0
+', ` // NVC0
+   // read SCRATCH3 to decide if we are PCOPY0 or PCOPY1
+   mov $r4 0x2100
+   iord $r4 I[$r4 + 0]
+   and $r4 1
+   shl b32 $r4 4
+   add b32 $r4 0x30
+
+   // channel is in vram
+   mov $r15 0x61c
+   shl b32 $r15 6
+   mov $r5 0x114
+   iowrs I[$r15] $r5
+
+   // read 16-byte PCOPYn info, containing context pointer, from channel
+   shl b32 $r5 $r3 4
+   add b32 $r5 2
+   mov $xdbase $r5
+   mov $r5 $sp
+   // get a chunk of stack space, aligned to 256 byte boundary
+   sub b32 $r5 0x100
+   mov $r6 0xff
+   not b32 $r6
+   and $r5 $r6
+   sethi $r5 0x00020000
+   xdld $r4 $r5
+   xdwait
+   sethi $r5 0
+
+   // set context pointer, from within channel VM
+   mov $r14 0
+   iowrs I[$r15] $r14
+   ld b32 $r4 D[$r5 + 0]
+   shr b32 $r4 8
+   ld b32 $r6 D[$r5 + 4]
+   shl b32 $r6 24
+   or $r4 $r6
+   mov $xdbase $r4
+')
+   // 256-byte context, at start of data segment
+   mov b32 $r4 $r0
+   sethi $r4 0x60000
+
+   // swap!
+   bra $p1 swctx_load
+      xdst $r0 $r4
+      bra swctx_done
+   swctx_load:
+      xdld $r0 $r4
+   swctx_done:
+   xdwait
+   ret
+
+chsw:
+   // read current channel
+   mov $r2 0x1400
+   iord $r3 I[$r2]
+
+   // if it's active, unload it and return
+   xbit $r15 $r3 0x1e
+   bra e chsw_no_unload
+      bclr $flags $p1
+      call swctx
+      bclr $r3 0x1e
+      iowr I[$r2] $r3
+      mov $r4 1
+      iowr I[$r2 + 0x200] $r4
+      ret
+
+   // read next channel
+   chsw_no_unload:
+   iord $r3 I[$r2 + 0x100]
+
+   // is there a channel waiting to be loaded?
+   xbit $r13 $r3 0x1e
+   bra e chsw_finish_load
+      bset $flags $p1
+      call swctx
+ifdef(`NVA3',
+      // load dma objects back into TARGET regs
+      mov $r5 ctx_dma
+      mov $r6 ctx_dma_count
+      chsw_load_ctx_dma:
+         ld b32 $r7 D[$r5 + $r6 * 4]
+         add b32 $r8 $r6 0x180
+         shl b32 $r8 8
+         iowr I[$r8] $r7
+         sub b32 $r6 1
+         bra nc chsw_load_ctx_dma
+,)
+
+   chsw_finish_load:
+   mov $r3 2
+   iowr I[$r2 + 0x200] $r3
+   ret
+
+dispatch:
+   // read incoming fifo command
+   mov $r3 0x1900
+   iord $r2 I[$r3 + 0x100]
+   iord $r3 I[$r3 + 0x000]
+   and $r4 $r2 0x7ff
+   // $r2 will be used to store exception data
+   shl b32 $r2 0x10
+
+   // lookup method in the dispatch table, ILLEGAL_MTHD if not found
+   mov $r5 dispatch_table
+   clear b32 $r6
+   clear b32 $r7
+   dispatch_loop:
+      ld b16 $r6 D[$r5 + 0]
+      ld b16 $r7 D[$r5 + 2]
+      add b32 $r5 4
+      cmpu b32 $r4 $r6
+      bra c dispatch_illegal_mthd
+      add b32 $r7 $r6
+      cmpu b32 $r4 $r7
+      bra c dispatch_valid_mthd
+      sub b32 $r7 $r6
+      shl b32 $r7 3
+      add b32 $r5 $r7
+      bra dispatch_loop
+
+   // ensure no bits set in reserved fields, INVALID_BITFIELD
+   dispatch_valid_mthd:
+   sub b32 $r4 $r6
+   shl b32 $r4 3
+   add b32 $r4 $r5
+   ld b32 $r5 D[$r4 + 4]
+   and $r5 $r3
+   cmpu b32 $r5 0
+   bra ne dispatch_invalid_bitfield
+
+   // depending on dispatch flags: execute method, or save data as state
+   ld b16 $r5 D[$r4 + 0]
+   ld b16 $r6 D[$r4 + 2]
+   cmpu b32 $r6 0
+   bra ne dispatch_cmd
+      st b32 D[$r5] $r3
+      bra dispatch_done
+   dispatch_cmd:
+      bclr $flags $p1
+      call $r5
+      bra $p1 dispatch_error
+      bra dispatch_done
+
+   dispatch_invalid_bitfield:
+   or $r2 2
+   dispatch_illegal_mthd:
+   or $r2 1
+
+   // store exception data in SCRATCH0/SCRATCH1, signal hostirq
+   dispatch_error:
+   mov $r4 0x1000
+   iowr I[$r4 + 0x000] $r2
+   iowr I[$r4 + 0x100] $r3
+   mov $r2 0x40
+   iowr I[$r0] $r2
+   hostirq_wait:
+      iord $r2 I[$r0 + 0x200]
+      and $r2 0x40
+      cmpu b32 $r2 0
+      bra ne hostirq_wait
+
+   dispatch_done:
+   mov $r2 0x1d00
+   mov $r3 1
+   iowr I[$r2] $r3
+   ret
+
+// No-operation
+//
+// Inputs:
+//    $r1: irqh state
+//    $r2: hostirq state
+//    $r3: data
+//    $r4: dispatch table entry
+// Outputs:
+//    $r1: irqh state
+//    $p1: set on error
+//       $r2: hostirq state
+//       $r3: data
+cmd_nop:
+   ret
+
+// PM_TRIGGER
+//
+// Inputs:
+//    $r1: irqh state
+//    $r2: hostirq state
+//    $r3: data
+//    $r4: dispatch table entry
+// Outputs:
+//    $r1: irqh state
+//    $p1: set on error
+//       $r2: hostirq state
+//       $r3: data
+cmd_pm_trigger:
+   mov $r2 0x2200
+   clear b32 $r3
+   sethi $r3 0x20000
+   iowr I[$r2] $r3
+   ret
+
+ifdef(`NVA3',
+// SET_DMA_* method handler
+//
+// Inputs:
+//    $r1: irqh state
+//    $r2: hostirq state
+//    $r3: data
+//    $r4: dispatch table entry
+// Outputs:
+//    $r1: irqh state
+//    $p1: set on error
+//       $r2: hostirq state
+//       $r3: data
+cmd_dma:
+   sub b32 $r4 dispatch_dma
+   shr b32 $r4 1
+   bset $r3 0x1e
+   st b32 D[$r4 + ctx_dma] $r3
+   add b32 $r4 0x600
+   shl b32 $r4 6
+   iowr I[$r4] $r3
+   ret
+,)
+
+// Calculates the hw swizzle mask and adjusts the surface's xcnt to match
+//
+cmd_exec_set_format:
+   // zero out a chunk of the stack to store the swizzle into
+   add $sp -0x10
+   st b32 D[$sp + 0x00] $r0
+   st b32 D[$sp + 0x04] $r0
+   st b32 D[$sp + 0x08] $r0
+   st b32 D[$sp + 0x0c] $r0
+
+   // extract cpp, src_ncomp and dst_ncomp from FORMAT
+   ld b32 $r4 D[$r0 + ctx_format]
+   extr $r5 $r4 16:17
+   add b32 $r5 1
+   extr $r6 $r4 20:21
+   add b32 $r6 1
+   extr $r7 $r4 24:25
+   add b32 $r7 1
+
+   // convert FORMAT swizzle mask to hw swizzle mask
+   bclr $flags $p2
+   clear b32 $r8
+   clear b32 $r9
+   ncomp_loop:
+      and $r10 $r4 0xf
+      shr b32 $r4 4
+      clear b32 $r11
+      bpc_loop:
+         cmpu b8 $r10 4
+         bra nc cmp_c0
+            mulu $r12 $r10 $r5
+            add b32 $r12 $r11
+            bset $flags $p2
+            bra bpc_next
+         cmp_c0:
+         bra ne cmp_c1
+            mov $r12 0x10
+            add b32 $r12 $r11
+            bra bpc_next
+         cmp_c1:
+         cmpu b8 $r10 6
+         bra nc cmp_zero
+            mov $r12 0x14
+            add b32 $r12 $r11
+            bra bpc_next
+         cmp_zero:
+            mov $r12 0x80
+         bpc_next:
+         st b8 D[$sp + $r8] $r12
+         add b32 $r8 1
+         add b32 $r11 1
+         cmpu b32 $r11 $r5
+         bra c bpc_loop
+      add b32 $r9 1
+      cmpu b32 $r9 $r7
+      bra c ncomp_loop
+
+   // SRC_XCNT = (xcnt * src_cpp), or 0 if no src ref in swz (hw will hang)
+   mulu $r6 $r5
+   st b32 D[$r0 + ctx_src_cpp] $r6
+   ld b32 $r8 D[$r0 + ctx_xcnt]
+   mulu $r6 $r8
+   bra $p2 dst_xcnt
+   clear b32 $r6
+
+   dst_xcnt:
+   mulu $r7 $r5
+   st b32 D[$r0 + ctx_dst_cpp] $r7
+   mulu $r7 $r8
+
+   mov $r5 0x810
+   shl b32 $r5 6
+   iowr I[$r5 + 0x000] $r6
+   iowr I[$r5 + 0x100] $r7
+   add b32 $r5 0x800
+   ld b32 $r6 D[$r0 + ctx_dst_cpp]
+   sub b32 $r6 1
+   shl b32 $r6 8
+   ld b32 $r7 D[$r0 + ctx_src_cpp]
+   sub b32 $r7 1
+   or $r6 $r7
+   iowr I[$r5 + 0x000] $r6
+   add b32 $r5 0x100
+   ld b32 $r6 D[$sp + 0x00]
+   iowr I[$r5 + 0x000] $r6
+   ld b32 $r6 D[$sp + 0x04]
+   iowr I[$r5 + 0x100] $r6
+   ld b32 $r6 D[$sp + 0x08]
+   iowr I[$r5 + 0x200] $r6
+   ld b32 $r6 D[$sp + 0x0c]
+   iowr I[$r5 + 0x300] $r6
+   add b32 $r5 0x400
+   ld b32 $r6 D[$r0 + ctx_swz_const0]
+   iowr I[$r5 + 0x000] $r6
+   ld b32 $r6 D[$r0 + ctx_swz_const1]
+   iowr I[$r5 + 0x100] $r6
+   add $sp 0x10
+   ret
+
+// Setup to handle a tiled surface
+//
+// Calculates a number of parameters the hardware requires in order
+// to correctly handle tiling.
+//
+// Offset calculation is performed as follows (Tp/Th/Td from TILE_MODE):
+//    nTx = round_up(w * cpp, 1 << Tp) >> Tp
+//    nTy = round_up(h, 1 << Th) >> Th
+//    Txo = (x * cpp) & ((1 << Tp) - 1)
+//     Tx = (x * cpp) >> Tp
+//    Tyo = y & ((1 << Th) - 1)
+//     Ty = y >> Th
+//    Tzo = z & ((1 << Td) - 1)
+//     Tz = z >> Td
+//
+//    off  = (Tzo << Tp << Th) + (Tyo << Tp) + Txo
+//    off += ((Tz * nTy * nTx)) + (Ty * nTx) + Tx) << Td << Th << Tp;
+//
+// Inputs:
+//    $r4: hw command (0x104800)
+//    $r5: ctx offset adjustment for src/dst selection
+//    $p2: set if dst surface
+//
+cmd_exec_set_surface_tiled:
+   // translate TILE_MODE into Tp, Th, Td shift values
+   ld b32 $r7 D[$r5 + ctx_src_tile_mode]
+   extr $r9 $r7 8:11
+   extr $r8 $r7 4:7
+ifdef(`NVA3',
+   add b32 $r8 2
+,
+   add b32 $r8 3
+)
+   extr $r7 $r7 0:3
+   cmp b32 $r7 0xe
+   bra ne xtile64
+   mov $r7 4
+   bra xtileok
+   xtile64:
+   xbit $r7 $flags $p2
+   add b32 $r7 17
+   bset $r4 $r7
+   mov $r7 6
+   xtileok:
+
+   // Op = (x * cpp) & ((1 << Tp) - 1)
+   // Tx = (x * cpp) >> Tp
+   ld b32 $r10 D[$r5 + ctx_src_xoff]
+   ld b32 $r11 D[$r5 + ctx_src_cpp]
+   mulu $r10 $r11
+   mov $r11 1
+   shl b32 $r11 $r7
+   sub b32 $r11 1
+   and $r12 $r10 $r11
+   shr b32 $r10 $r7
+
+   // Tyo = y & ((1 << Th) - 1)
+   // Ty  = y >> Th
+   ld b32 $r13 D[$r5 + ctx_src_yoff]
+   mov $r14 1
+   shl b32 $r14 $r8
+   sub b32 $r14 1
+   and $r11 $r13 $r14
+   shr b32 $r13 $r8
+
+   // YTILE = ((1 << Th) << 12) | ((1 << Th) - Tyo)
+   add b32 $r14 1
+   shl b32 $r15 $r14 12
+   sub b32 $r14 $r11
+   or $r15 $r14
+   xbit $r6 $flags $p2
+   add b32 $r6 0x208
+   shl b32 $r6 8
+   iowr I[$r6 + 0x000] $r15
+
+   // Op += Tyo << Tp
+   shl b32 $r11 $r7
+   add b32 $r12 $r11
+
+   // nTx = ((w * cpp) + ((1 << Tp) - 1) >> Tp)
+   ld b32 $r15 D[$r5 + ctx_src_xsize]
+   ld b32 $r11 D[$r5 + ctx_src_cpp]
+   mulu $r15 $r11
+   mov $r11 1
+   shl b32 $r11 $r7
+   sub b32 $r11 1
+   add b32 $r15 $r11
+   shr b32 $r15 $r7
+   push $r15
+
+   // nTy = (h + ((1 << Th) - 1)) >> Th
+   ld b32 $r15 D[$r5 + ctx_src_ysize]
+   mov $r11 1
+   shl b32 $r11 $r8
+   sub b32 $r11 1
+   add b32 $r15 $r11
+   shr b32 $r15 $r8
+   push $r15
+
+   // Tys = Tp + Th
+   // CFG_YZ_TILE_SIZE = ((1 << Th) >> 2) << Td
+   add b32 $r7 $r8
+   sub b32 $r8 2
+   mov $r11 1
+   shl b32 $r11 $r8
+   shl b32 $r11 $r9
+
+   // Tzo = z & ((1 << Td) - 1)
+   // Tz  = z >> Td
+   // Op += Tzo << Tys
+   // Ts  = Tys + Td
+   ld b32 $r8 D[$r5 + ctx_src_zoff]
+   mov $r14 1
+   shl b32 $r14 $r9
+   sub b32 $r14 1
+   and $r15 $r8 $r14
+   shl b32 $r15 $r7
+   add b32 $r12 $r15
+   add b32 $r7 $r9
+   shr b32 $r8 $r9
+
+   // Ot = ((Tz * nTy * nTx) + (Ty * nTx) + Tx) << Ts
+   pop $r15
+   pop $r9
+   mulu $r13 $r9
+   add b32 $r10 $r13
+   mulu $r8 $r9
+   mulu $r8 $r15
+   add b32 $r10 $r8
+   shl b32 $r10 $r7
+
+   // PITCH = (nTx - 1) << Ts
+   sub b32 $r9 1
+   shl b32 $r9 $r7
+   iowr I[$r6 + 0x200] $r9
+
+   // SRC_ADDRESS_LOW   = (Ot + Op) & 0xffffffff
+   // CFG_ADDRESS_HIGH |= ((Ot + Op) >> 32) << 16
+   ld b32 $r7 D[$r5 + ctx_src_address_low]
+   ld b32 $r8 D[$r5 + ctx_src_address_high]
+   add b32 $r10 $r12
+   add b32 $r7 $r10
+   adc b32 $r8 0
+   shl b32 $r8 16
+   or $r8 $r11
+   sub b32 $r6 0x600
+   iowr I[$r6 + 0x000] $r7
+   add b32 $r6 0x400
+   iowr I[$r6 + 0x000] $r8
+   ret
+
+// Setup to handle a linear surface
+//
+// Nothing to see here.. Sets ADDRESS and PITCH, pretty non-exciting
+//
+cmd_exec_set_surface_linear:
+   xbit $r6 $flags $p2
+   add b32 $r6 0x202
+   shl b32 $r6 8
+   ld b32 $r7 D[$r5 + ctx_src_address_low]
+   iowr I[$r6 + 0x000] $r7
+   add b32 $r6 0x400
+   ld b32 $r7 D[$r5 + ctx_src_address_high]
+   shl b32 $r7 16
+   iowr I[$r6 + 0x000] $r7
+   add b32 $r6 0x400
+   ld b32 $r7 D[$r5 + ctx_src_pitch]
+   iowr I[$r6 + 0x000] $r7
+   ret
+
+// wait for regs to be available for use
+cmd_exec_wait:
+   push $r0
+   push $r1
+   mov $r0 0x800
+   shl b32 $r0 6
+   loop:
+      iord $r1 I[$r0]
+      and $r1 1
+      bra ne loop
+   pop $r1
+   pop $r0
+   ret
+
+cmd_exec_query:
+   // if QUERY_SHORT not set, write out { -, 0, TIME_LO, TIME_HI }
+   xbit $r4 $r3 13
+   bra ne query_counter
+      call cmd_exec_wait
+      mov $r4 0x80c
+      shl b32 $r4 6
+      ld b32 $r5 D[$r0 + ctx_query_address_low]
+      add b32 $r5 4
+      iowr I[$r4 + 0x000] $r5
+      iowr I[$r4 + 0x100] $r0
+      mov $r5 0xc
+      iowr I[$r4 + 0x200] $r5
+      add b32 $r4 0x400
+      ld b32 $r5 D[$r0 + ctx_query_address_high]
+      shl b32 $r5 16
+      iowr I[$r4 + 0x000] $r5
+      add b32 $r4 0x500
+      mov $r5 0x00000b00
+      sethi $r5 0x00010000
+      iowr I[$r4 + 0x000] $r5
+      mov $r5 0x00004040
+      shl b32 $r5 1
+      sethi $r5 0x80800000
+      iowr I[$r4 + 0x100] $r5
+      mov $r5 0x00001110
+      sethi $r5 0x13120000
+      iowr I[$r4 + 0x200] $r5
+      mov $r5 0x00001514
+      sethi $r5 0x17160000
+      iowr I[$r4 + 0x300] $r5
+      mov $r5 0x00002601
+      sethi $r5 0x00010000
+      mov $r4 0x800
+      shl b32 $r4 6
+      iowr I[$r4 + 0x000] $r5
+
+   // write COUNTER
+   query_counter:
+   call cmd_exec_wait
+   mov $r4 0x80c
+   shl b32 $r4 6
+   ld b32 $r5 D[$r0 + ctx_query_address_low]
+   iowr I[$r4 + 0x000] $r5
+   iowr I[$r4 + 0x100] $r0
+   mov $r5 0x4
+   iowr I[$r4 + 0x200] $r5
+   add b32 $r4 0x400
+   ld b32 $r5 D[$r0 + ctx_query_address_high]
+   shl b32 $r5 16
+   iowr I[$r4 + 0x000] $r5
+   add b32 $r4 0x500
+   mov $r5 0x00000300
+   iowr I[$r4 + 0x000] $r5
+   mov $r5 0x00001110
+   sethi $r5 0x13120000
+   iowr I[$r4 + 0x100] $r5
+   ld b32 $r5 D[$r0 + ctx_query_counter]
+   add b32 $r4 0x500
+   iowr I[$r4 + 0x000] $r5
+   mov $r5 0x00002601
+   sethi $r5 0x00010000
+   mov $r4 0x800
+   shl b32 $r4 6
+   iowr I[$r4 + 0x000] $r5
+   ret
+
+// Execute a copy operation
+//
+// Inputs:
+//    $r1: irqh state
+//    $r2: hostirq state
+//    $r3: data
+//       000002000 QUERY_SHORT
+//       000001000 QUERY
+//       000000100 DST_LINEAR
+//       000000010 SRC_LINEAR
+//       000000001 FORMAT
+//    $r4: dispatch table entry
+// Outputs:
+//    $r1: irqh state
+//    $p1: set on error
+//       $r2: hostirq state
+//       $r3: data
+cmd_exec:
+   call cmd_exec_wait
+
+   // if format requested, call function to calculate it, otherwise
+   // fill in cpp/xcnt for both surfaces as if (cpp == 1)
+   xbit $r15 $r3 0
+   bra e cmd_exec_no_format
+      call cmd_exec_set_format
+      mov $r4 0x200
+      bra cmd_exec_init_src_surface
+   cmd_exec_no_format:
+      mov $r6 0x810
+      shl b32 $r6 6
+      mov $r7 1
+      st b32 D[$r0 + ctx_src_cpp] $r7
+      st b32 D[$r0 + ctx_dst_cpp] $r7
+      ld b32 $r7 D[$r0 + ctx_xcnt]
+      iowr I[$r6 + 0x000] $r7
+      iowr I[$r6 + 0x100] $r7
+      clear b32 $r4
+
+   cmd_exec_init_src_surface:
+   bclr $flags $p2
+   clear b32 $r5
+   xbit $r15 $r3 4
+   bra e src_tiled
+      call cmd_exec_set_surface_linear
+      bra cmd_exec_init_dst_surface
+   src_tiled:
+      call cmd_exec_set_surface_tiled
+      bset $r4 7
+
+   cmd_exec_init_dst_surface:
+   bset $flags $p2
+   mov $r5 ctx_dst_address_high - ctx_src_address_high
+   xbit $r15 $r3 8
+   bra e dst_tiled
+      call cmd_exec_set_surface_linear
+      bra cmd_exec_kick
+   dst_tiled:
+      call cmd_exec_set_surface_tiled
+      bset $r4 8
+
+   cmd_exec_kick:
+   mov $r5 0x800
+   shl b32 $r5 6
+   ld b32 $r6 D[$r0 + ctx_ycnt]
+   iowr I[$r5 + 0x100] $r6
+   mov $r6 0x0041
+   // SRC_TARGET = 1, DST_TARGET = 2
+   sethi $r6 0x44000000
+   or $r4 $r6
+   iowr I[$r5] $r4
+
+   // if requested, queue up a QUERY write after the copy has completed
+   xbit $r15 $r3 12
+   bra e cmd_exec_done
+      call cmd_exec_query
+
+   cmd_exec_done:
+   ret
+
+// Flush write cache
+//
+// Inputs:
+//    $r1: irqh state
+//    $r2: hostirq state
+//    $r3: data
+//    $r4: dispatch table entry
+// Outputs:
+//    $r1: irqh state
+//    $p1: set on error
+//       $r2: hostirq state
+//       $r3: data
+cmd_wrcache_flush:
+   mov $r2 0x2200
+   clear b32 $r3
+   sethi $r3 0x10000
+   iowr I[$r2] $r3
+   ret
+
+.align 0x100
diff -druN linux-2.6.39-libre/drivers/gpu/drm/nouveau/nva3_copy.fuc.h linux-3.0-rc7-libre/drivers/gpu/drm/nouveau/nva3_copy.fuc.h
--- linux-2.6.39-libre/drivers/gpu/drm/nouveau/nva3_copy.fuc.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/gpu/drm/nouveau/nva3_copy.fuc.h	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,534 @@
+uint32_t nva3_pcopy_data[] = {
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00010000,
+	0x00000000,
+	0x00000000,
+	0x00010040,
+	0x00010160,
+	0x00000000,
+	0x00010050,
+	0x00010162,
+	0x00000000,
+	0x00030060,
+	0x00010170,
+	0x00000000,
+	0x00010170,
+	0x00000000,
+	0x00010170,
+	0x00000000,
+	0x00070080,
+	0x00000028,
+	0xfffff000,
+	0x0000002c,
+	0xfff80000,
+	0x00000030,
+	0xffffe000,
+	0x00000034,
+	0xfffff800,
+	0x00000038,
+	0xfffff000,
+	0x0000003c,
+	0xfff80000,
+	0x00000040,
+	0xffffe000,
+	0x00070088,
+	0x00000054,
+	0xfffff000,
+	0x00000058,
+	0xfff80000,
+	0x0000005c,
+	0xffffe000,
+	0x00000060,
+	0xfffff800,
+	0x00000064,
+	0xfffff000,
+	0x00000068,
+	0xfff80000,
+	0x0000006c,
+	0xffffe000,
+	0x000200c0,
+	0x00010492,
+	0x00000000,
+	0x0001051b,
+	0x00000000,
+	0x000e00c3,
+	0x0000001c,
+	0xffffff00,
+	0x00000020,
+	0x0000000f,
+	0x00000048,
+	0xffffff00,
+	0x0000004c,
+	0x0000000f,
+	0x00000024,
+	0xfff80000,
+	0x00000050,
+	0xfff80000,
+	0x00000080,
+	0xffff0000,
+	0x00000084,
+	0xffffe000,
+	0x00000074,
+	0xfccc0000,
+	0x00000078,
+	0x00000000,
+	0x0000007c,
+	0x00000000,
+	0x00000010,
+	0xffffff00,
+	0x00000014,
+	0x00000000,
+	0x00000018,
+	0x00000000,
+	0x00000800,
+};
+
+uint32_t nva3_pcopy_code[] = {
+	0x04fe04bd,
+	0x3517f000,
+	0xf10010fe,
+	0xf1040017,
+	0xf0fff327,
+	0x22d00023,
+	0x0c25f0c0,
+	0xf40012d0,
+	0x17f11031,
+	0x27f01200,
+	0x0012d003,
+	0xf40031f4,
+	0x0ef40028,
+	0x8001cffd,
+	0xf40812c4,
+	0x21f4060b,
+	0x0412c472,
+	0xf4060bf4,
+	0x11c4c321,
+	0x4001d00c,
+	0x47f101f8,
+	0x4bfe7700,
+	0x0007fe00,
+	0xf00204b9,
+	0x01f40643,
+	0x0604fa09,
+	0xfa060ef4,
+	0x03f80504,
+	0x27f100f8,
+	0x23cf1400,
+	0x1e3fc800,
+	0xf4170bf4,
+	0x21f40132,
+	0x1e3af052,
+	0xf00023d0,
+	0x24d00147,
+	0xcf00f880,
+	0x3dc84023,
+	0x220bf41e,
+	0xf40131f4,
+	0x57f05221,
+	0x0367f004,
+	0xa07856bc,
+	0xb6018068,
+	0x87d00884,
+	0x0162b600,
+	0xf0f018f4,
+	0x23d00237,
+	0xf100f880,
+	0xcf190037,
+	0x33cf4032,
+	0xff24e400,
+	0x1024b607,
+	0x010057f1,
+	0x74bd64bd,
+	0x58005658,
+	0x50b60157,
+	0x0446b804,
+	0xbb4d08f4,
+	0x47b80076,
+	0x0f08f404,
+	0xb60276bb,
+	0x57bb0374,
+	0xdf0ef400,
+	0xb60246bb,
+	0x45bb0344,
+	0x01459800,
+	0xb00453fd,
+	0x1bf40054,
+	0x00455820,
+	0xb0014658,
+	0x1bf40064,
+	0x00538009,
+	0xf4300ef4,
+	0x55f90132,
+	0xf40c01f4,
+	0x25f0250e,
+	0x0125f002,
+	0x100047f1,
+	0xd00042d0,
+	0x27f04043,
+	0x0002d040,
+	0xf08002cf,
+	0x24b04024,
+	0xf71bf400,
+	0x1d0027f1,
+	0xd00137f0,
+	0x00f80023,
+	0x27f100f8,
+	0x34bd2200,
+	0xd00233f0,
+	0x00f80023,
+	0x012842b7,
+	0xf00145b6,
+	0x43801e39,
+	0x0040b701,
+	0x0644b606,
+	0xf80043d0,
+	0xf030f400,
+	0xb00001b0,
+	0x01b00101,
+	0x0301b002,
+	0xc71d0498,
+	0x50b63045,
+	0x3446c701,
+	0xc70160b6,
+	0x70b63847,
+	0x0232f401,
+	0x94bd84bd,
+	0xb60f4ac4,
+	0xb4bd0445,
+	0xf404a430,
+	0xa5ff0f18,
+	0x00cbbbc0,
+	0xf40231f4,
+	0x1bf4220e,
+	0x10c7f00c,
+	0xf400cbbb,
+	0xa430160e,
+	0x0c18f406,
+	0xbb14c7f0,
+	0x0ef400cb,
+	0x80c7f107,
+	0x01c83800,
+	0xb60180b6,
+	0xb5b801b0,
+	0xc308f404,
+	0xb80190b6,
+	0x08f40497,
+	0x0065fdb2,
+	0x98110680,
+	0x68fd2008,
+	0x0502f400,
+	0x75fd64bd,
+	0x1c078000,
+	0xf10078fd,
+	0xb6081057,
+	0x56d00654,
+	0x4057d000,
+	0x080050b7,
+	0xb61c0698,
+	0x64b60162,
+	0x11079808,
+	0xfd0172b6,
+	0x56d00567,
+	0x0050b700,
+	0x0060b401,
+	0xb40056d0,
+	0x56d00160,
+	0x0260b440,
+	0xb48056d0,
+	0x56d00360,
+	0x0050b7c0,
+	0x1e069804,
+	0x980056d0,
+	0x56d01f06,
+	0x1030f440,
+	0x579800f8,
+	0x6879c70a,
+	0xb66478c7,
+	0x77c70280,
+	0x0e76b060,
+	0xf0091bf4,
+	0x0ef40477,
+	0x027cf00f,
+	0xfd1170b6,
+	0x77f00947,
+	0x0f5a9806,
+	0xfd115b98,
+	0xb7f000ab,
+	0x04b7bb01,
+	0xff01b2b6,
+	0xa7bbc4ab,
+	0x105d9805,
+	0xbb01e7f0,
+	0xe2b604e8,
+	0xb4deff01,
+	0xb605d8bb,
+	0xef9401e0,
+	0x02ebbb0c,
+	0xf005fefd,
+	0x60b7026c,
+	0x64b60208,
+	0x006fd008,
+	0xbb04b7bb,
+	0x5f9800cb,
+	0x115b980b,
+	0xf000fbfd,
+	0xb7bb01b7,
+	0x01b2b604,
+	0xbb00fbbb,
+	0xf0f905f7,
+	0xf00c5f98,
+	0xb8bb01b7,
+	0x01b2b604,
+	0xbb00fbbb,
+	0xf0f905f8,
+	0xb60078bb,
+	0xb7f00282,
+	0x04b8bb01,
+	0x9804b9bb,
+	0xe7f00e58,
+	0x04e9bb01,
+	0xff01e2b6,
+	0xf7bbf48e,
+	0x00cfbb04,
+	0xbb0079bb,
+	0xf0fc0589,
+	0xd9fd90fc,
+	0x00adbb00,
+	0xfd0089fd,
+	0xa8bb008f,
+	0x04a7bb00,
+	0xbb0192b6,
+	0x69d00497,
+	0x08579880,
+	0xbb075898,
+	0x7abb00ac,
+	0x0081b600,
+	0xfd1084b6,
+	0x62b7058b,
+	0x67d00600,
+	0x0060b700,
+	0x0068d004,
+	0x6cf000f8,
+	0x0260b702,
+	0x0864b602,
+	0xd0085798,
+	0x60b70067,
+	0x57980400,
+	0x1074b607,
+	0xb70067d0,
+	0x98040060,
+	0x67d00957,
+	0xf900f800,
+	0xf110f900,
+	0xb6080007,
+	0x01cf0604,
+	0x0114f000,
+	0xfcfa1bf4,
+	0xf800fc10,
+	0x0d34c800,
+	0xf5701bf4,
+	0xf103ab21,
+	0xb6080c47,
+	0x05980644,
+	0x0450b605,
+	0xd00045d0,
+	0x57f04040,
+	0x8045d00c,
+	0x040040b7,
+	0xb6040598,
+	0x45d01054,
+	0x0040b700,
+	0x0057f105,
+	0x0153f00b,
+	0xf10045d0,
+	0xb6404057,
+	0x53f10154,
+	0x45d08080,
+	0x1057f140,
+	0x1253f111,
+	0x8045d013,
+	0x151457f1,
+	0x171653f1,
+	0xf1c045d0,
+	0xf0260157,
+	0x47f10153,
+	0x44b60800,
+	0x0045d006,
+	0x03ab21f5,
+	0x080c47f1,
+	0x980644b6,
+	0x45d00505,
+	0x4040d000,
+	0xd00457f0,
+	0x40b78045,
+	0x05980400,
+	0x1054b604,
+	0xb70045d0,
+	0xf1050040,
+	0xd0030057,
+	0x57f10045,
+	0x53f11110,
+	0x45d01312,
+	0x06059840,
+	0x050040b7,
+	0xf10045d0,
+	0xf0260157,
+	0x47f10153,
+	0x44b60800,
+	0x0045d006,
+	0x21f500f8,
+	0x3fc803ab,
+	0x0e0bf400,
+	0x018921f5,
+	0x020047f1,
+	0xf11e0ef4,
+	0xb6081067,
+	0x77f00664,
+	0x11078001,
+	0x981c0780,
+	0x67d02007,
+	0x4067d000,
+	0x32f444bd,
+	0xc854bd02,
+	0x0bf4043f,
+	0x8221f50a,
+	0x0a0ef403,
+	0x027621f5,
+	0xf40749f0,
+	0x57f00231,
+	0x083fc82c,
+	0xf50a0bf4,
+	0xf4038221,
+	0x21f50a0e,
+	0x49f00276,
+	0x0057f108,
+	0x0654b608,
+	0xd0210698,
+	0x67f04056,
+	0x0063f141,
+	0x0546fd44,
+	0xc80054d0,
+	0x0bf40c3f,
+	0xc521f507,
+	0xf100f803,
+	0xbd220027,
+	0x0133f034,
+	0xf80023d0,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+};
diff -druN linux-2.6.39-libre/drivers/gpu/drm/nouveau/nva3_pm.c linux-3.0-rc7-libre/drivers/gpu/drm/nouveau/nva3_pm.c
--- linux-2.6.39-libre/drivers/gpu/drm/nouveau/nva3_pm.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/gpu/drm/nouveau/nva3_pm.c	2011-07-11 19:51:52.000000000 -0400
@@ -27,32 +27,74 @@
 #include "nouveau_bios.h"
 #include "nouveau_pm.h"
 
-/*XXX: boards using limits 0x40 need fixing, the register layout
- *     is correct here, but, there's some other funny magic
- *     that modifies things, so it's not likely we'll set/read
- *     the correct timings yet..  working on it...
+/* This is actually a lot more complex than it appears here, but hopefully
+ * this should be able to deal with what the VBIOS leaves for us..
+ *
+ * If not, well, I'll jump off that bridge when I come to it.
  */
 
 struct nva3_pm_state {
-	struct pll_lims pll;
-	int N, M, P;
+	enum pll_types type;
+	u32 src0;
+	u32 src1;
+	u32 ctrl;
+	u32 coef;
+	u32 old_pnm;
+	u32 new_pnm;
+	u32 new_div;
 };
 
+static int
+nva3_pm_pll_offset(u32 id)
+{
+	static const u32 pll_map[] = {
+		0x00, PLL_CORE,
+		0x01, PLL_SHADER,
+		0x02, PLL_MEMORY,
+		0x00, 0x00
+	};
+	const u32 *map = pll_map;
+
+	while (map[1]) {
+		if (id == map[1])
+			return map[0];
+		map += 2;
+	}
+
+	return -ENOENT;
+}
+
 int
 nva3_pm_clock_get(struct drm_device *dev, u32 id)
 {
+	u32 src0, src1, ctrl, coef;
 	struct pll_lims pll;
-	int P, N, M, ret;
-	u32 reg;
+	int ret, off;
+	int P, N, M;
 
 	ret = get_pll_limits(dev, id, &pll);
 	if (ret)
 		return ret;
 
-	reg = nv_rd32(dev, pll.reg + 4);
-	P = (reg & 0x003f0000) >> 16;
-	N = (reg & 0x0000ff00) >> 8;
-	M = (reg & 0x000000ff);
+	off = nva3_pm_pll_offset(id);
+	if (off < 0)
+		return off;
+
+	src0 = nv_rd32(dev, 0x4120 + (off * 4));
+	src1 = nv_rd32(dev, 0x4160 + (off * 4));
+	ctrl = nv_rd32(dev, pll.reg + 0);
+	coef = nv_rd32(dev, pll.reg + 4);
+	NV_DEBUG(dev, "PLL %02x: 0x%08x 0x%08x 0x%08x 0x%08x\n",
+		      id, src0, src1, ctrl, coef);
+
+	if (ctrl & 0x00000008) {
+		u32 div = ((src1 & 0x003c0000) >> 18) + 1;
+		return (pll.refclk * 2) / div;
+	}
+
+	P = (coef & 0x003f0000) >> 16;
+	N = (coef & 0x0000ff00) >> 8;
+	M = (coef & 0x000000ff);
 	return pll.refclk * N / M / P;
 }
 
@@ -60,36 +102,103 @@
 nva3_pm_clock_pre(struct drm_device *dev, struct nouveau_pm_level *perflvl,
 		  u32 id, int khz)
 {
-	struct nva3_pm_state *state;
-	int dummy, ret;
+	struct nva3_pm_state *pll;
+	struct pll_lims limits;
+	int N, M, P, diff;
+	int ret, off;
 
-	state = kzalloc(sizeof(*state), GFP_KERNEL);
-	if (!state)
+	ret = get_pll_limits(dev, id, &limits);
+	if (ret < 0)
+		return (ret == -ENOENT) ? NULL : ERR_PTR(ret);
+
+	off = nva3_pm_pll_offset(id);
+	if (id < 0)
+		return ERR_PTR(-EINVAL);
+
+
+	pll = kzalloc(sizeof(*pll), GFP_KERNEL);
+	if (!pll)
 		return ERR_PTR(-ENOMEM);
+	pll->type = id;
+	pll->src0 = 0x004120 + (off * 4);
+	pll->src1 = 0x004160 + (off * 4);
+	pll->ctrl = limits.reg + 0;
+	pll->coef = limits.reg + 4;
 
-	ret = get_pll_limits(dev, id, &state->pll);
-	if (ret < 0) {
-		kfree(state);
-		return (ret == -ENOENT) ? NULL : ERR_PTR(ret);
+	/* If target clock is within [-2, 3) MHz of a divisor, we'll
+	 * use that instead of calculating MNP values
+	 */
+	pll->new_div = min((limits.refclk * 2) / (khz - 2999), 16);
+	if (pll->new_div) {
+		diff = khz - ((limits.refclk * 2) / pll->new_div);
+		if (diff < -2000 || diff >= 3000)
+			pll->new_div = 0;
 	}
 
-	ret = nv50_calc_pll2(dev, &state->pll, khz, &state->N, &dummy,
-			     &state->M, &state->P);
-	if (ret < 0) {
-		kfree(state);
-		return ERR_PTR(ret);
+	if (!pll->new_div) {
+		ret = nva3_calc_pll(dev, &limits, khz, &N, NULL, &M, &P);
+		if (ret < 0)
+			return ERR_PTR(ret);
+
+		pll->new_pnm = (P << 16) | (N << 8) | M;
+		pll->new_div = 2 - 1;
+	} else {
+		pll->new_pnm = 0;
+		pll->new_div--;
 	}
 
-	return state;
+	if ((nv_rd32(dev, pll->src1) & 0x00000101) != 0x00000101)
+		pll->old_pnm = nv_rd32(dev, pll->coef);
+	return pll;
 }
 
 void
 nva3_pm_clock_set(struct drm_device *dev, void *pre_state)
 {
-	struct nva3_pm_state *state = pre_state;
-	u32 reg = state->pll.reg;
+	struct nva3_pm_state *pll = pre_state;
+	u32 ctrl = 0;
 
-	nv_wr32(dev, reg + 4, (state->P << 16) | (state->N << 8) | state->M);
-	kfree(state);
+	/* For the memory clock, NVIDIA will build a "script" describing
+	 * the reclocking process and ask PDAEMON to execute it.
+	 */
+	if (pll->type == PLL_MEMORY) {
+		nv_wr32(dev, 0x100210, 0);
+		nv_wr32(dev, 0x1002dc, 1);
+		nv_wr32(dev, 0x004018, 0x00001000);
+		ctrl = 0x18000100;
+	}
+
+	if (pll->old_pnm || !pll->new_pnm) {
+		nv_mask(dev, pll->src1, 0x003c0101, 0x00000101 |
+						    (pll->new_div << 18));
+		nv_wr32(dev, pll->ctrl, 0x0001001d | ctrl);
+		nv_mask(dev, pll->ctrl, 0x00000001, 0x00000000);
+	}
+
+	if (pll->new_pnm) {
+		nv_mask(dev, pll->src0, 0x00000101, 0x00000101);
+		nv_wr32(dev, pll->coef, pll->new_pnm);
+		nv_wr32(dev, pll->ctrl, 0x0001001d | ctrl);
+		nv_mask(dev, pll->ctrl, 0x00000010, 0x00000000);
+		nv_mask(dev, pll->ctrl, 0x00020010, 0x00020010);
+		nv_wr32(dev, pll->ctrl, 0x00010015 | ctrl);
+		nv_mask(dev, pll->src1, 0x00000100, 0x00000000);
+		nv_mask(dev, pll->src1, 0x00000001, 0x00000000);
+		if (pll->type == PLL_MEMORY)
+			nv_wr32(dev, 0x4018, 0x10005000);
+	} else {
+		nv_mask(dev, pll->ctrl, 0x00000001, 0x00000000);
+		nv_mask(dev, pll->src0, 0x00000100, 0x00000000);
+		nv_mask(dev, pll->src0, 0x00000001, 0x00000000);
+		if (pll->type == PLL_MEMORY)
+			nv_wr32(dev, 0x4018, 0x1000d000);
+	}
+
+	if (pll->type == PLL_MEMORY) {
+		nv_wr32(dev, 0x1002dc, 0);
+		nv_wr32(dev, 0x100210, 0x80000000);
+	}
+
+	kfree(pll);
 }
 
diff -druN linux-2.6.39-libre/drivers/gpu/drm/nouveau/nvc0_copy.c linux-3.0-rc7-libre/drivers/gpu/drm/nouveau/nvc0_copy.c
--- linux-2.6.39-libre/drivers/gpu/drm/nouveau/nvc0_copy.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/gpu/drm/nouveau/nvc0_copy.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,243 @@
+/*
+ * Copyright 2011 Red Hat Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: Ben Skeggs
+ */
+
+#include <linux/firmware.h>
+#include "drmP.h"
+#include "nouveau_drv.h"
+#include "nouveau_util.h"
+#include "nouveau_vm.h"
+#include "nouveau_ramht.h"
+#include "nvc0_copy.fuc.h"
+
+struct nvc0_copy_engine {
+	struct nouveau_exec_engine base;
+	u32 irq;
+	u32 pmc;
+	u32 fuc;
+	u32 ctx;
+};
+
+static int
+nvc0_copy_context_new(struct nouveau_channel *chan, int engine)
+{
+	struct nvc0_copy_engine *pcopy = nv_engine(chan->dev, engine);
+	struct drm_device *dev = chan->dev;
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_gpuobj *ramin = chan->ramin;
+	struct nouveau_gpuobj *ctx = NULL;
+	int ret;
+
+	ret = nouveau_gpuobj_new(dev, NULL, 256, 256,
+				 NVOBJ_FLAG_VM | NVOBJ_FLAG_VM_USER |
+				 NVOBJ_FLAG_ZERO_ALLOC, &ctx);
+	if (ret)
+		return ret;
+
+	nv_wo32(ramin, pcopy->ctx + 0, lower_32_bits(ctx->vinst));
+	nv_wo32(ramin, pcopy->ctx + 4, upper_32_bits(ctx->vinst));
+	dev_priv->engine.instmem.flush(dev);
+
+	chan->engctx[engine] = ctx;
+	return 0;
+}
+
+static int
+nvc0_copy_object_new(struct nouveau_channel *chan, int engine,
+		     u32 handle, u16 class)
+{
+	return 0;
+}
+
+static void
+nvc0_copy_context_del(struct nouveau_channel *chan, int engine)
+{
+	struct nvc0_copy_engine *pcopy = nv_engine(chan->dev, engine);
+	struct nouveau_gpuobj *ctx = chan->engctx[engine];
+	struct drm_device *dev = chan->dev;
+	u32 inst;
+
+	inst  = (chan->ramin->vinst >> 12);
+	inst |= 0x40000000;
+
+	/* disable fifo access */
+	nv_wr32(dev, pcopy->fuc + 0x048, 0x00000000);
+	/* mark channel as unloaded if it's currently active */
+	if (nv_rd32(dev, pcopy->fuc + 0x050) == inst)
+		nv_mask(dev, pcopy->fuc + 0x050, 0x40000000, 0x00000000);
+	/* mark next channel as invalid if it's about to be loaded */
+	if (nv_rd32(dev, pcopy->fuc + 0x054) == inst)
+		nv_mask(dev, pcopy->fuc + 0x054, 0x40000000, 0x00000000);
+	/* restore fifo access */
+	nv_wr32(dev, pcopy->fuc + 0x048, 0x00000003);
+
+	nv_wo32(chan->ramin, pcopy->ctx + 0, 0x00000000);
+	nv_wo32(chan->ramin, pcopy->ctx + 4, 0x00000000);
+	nouveau_gpuobj_ref(NULL, &ctx);
+
+	chan->engctx[engine] = ctx;
+}
+
+static int
+nvc0_copy_init(struct drm_device *dev, int engine)
+{
+	struct nvc0_copy_engine *pcopy = nv_engine(dev, engine);
+	int i;
+
+	nv_mask(dev, 0x000200, pcopy->pmc, 0x00000000);
+	nv_mask(dev, 0x000200, pcopy->pmc, pcopy->pmc);
+	nv_wr32(dev, pcopy->fuc + 0x014, 0xffffffff);
+
+	nv_wr32(dev, pcopy->fuc + 0x1c0, 0x01000000);
+	for (i = 0; i < sizeof(nvc0_pcopy_data) / 4; i++)
+		nv_wr32(dev, pcopy->fuc + 0x1c4, nvc0_pcopy_data[i]);
+
+	nv_wr32(dev, pcopy->fuc + 0x180, 0x01000000);
+	for (i = 0; i < sizeof(nvc0_pcopy_code) / 4; i++) {
+		if ((i & 0x3f) == 0)
+			nv_wr32(dev, pcopy->fuc + 0x188, i >> 6);
+		nv_wr32(dev, pcopy->fuc + 0x184, nvc0_pcopy_code[i]);
+	}
+
+	nv_wr32(dev, pcopy->fuc + 0x084, engine - NVOBJ_ENGINE_COPY0);
+	nv_wr32(dev, pcopy->fuc + 0x10c, 0x00000000);
+	nv_wr32(dev, pcopy->fuc + 0x104, 0x00000000); /* ENTRY */
+	nv_wr32(dev, pcopy->fuc + 0x100, 0x00000002); /* TRIGGER */
+	return 0;
+}
+
+static int
+nvc0_copy_fini(struct drm_device *dev, int engine)
+{
+	struct nvc0_copy_engine *pcopy = nv_engine(dev, engine);
+
+	nv_mask(dev, pcopy->fuc + 0x048, 0x00000003, 0x00000000);
+
+	/* trigger fuc context unload */
+	nv_wait(dev, pcopy->fuc + 0x008, 0x0000000c, 0x00000000);
+	nv_mask(dev, pcopy->fuc + 0x054, 0x40000000, 0x00000000);
+	nv_wr32(dev, pcopy->fuc + 0x000, 0x00000008);
+	nv_wait(dev, pcopy->fuc + 0x008, 0x00000008, 0x00000000);
+
+	nv_wr32(dev, pcopy->fuc + 0x014, 0xffffffff);
+	return 0;
+}
+
+static struct nouveau_enum nvc0_copy_isr_error_name[] = {
+	{ 0x0001, "ILLEGAL_MTHD" },
+	{ 0x0002, "INVALID_ENUM" },
+	{ 0x0003, "INVALID_BITFIELD" },
+	{}
+};
+
+static void
+nvc0_copy_isr(struct drm_device *dev, int engine)
+{
+	struct nvc0_copy_engine *pcopy = nv_engine(dev, engine);
+	u32 disp = nv_rd32(dev, pcopy->fuc + 0x01c);
+	u32 stat = nv_rd32(dev, pcopy->fuc + 0x008) & disp & ~(disp >> 16);
+	u64 inst = (u64)(nv_rd32(dev, pcopy->fuc + 0x050) & 0x0fffffff) << 12;
+	u32 chid = nvc0_graph_isr_chid(dev, inst);
+	u32 ssta = nv_rd32(dev, pcopy->fuc + 0x040) & 0x0000ffff;
+	u32 addr = nv_rd32(dev, pcopy->fuc + 0x040) >> 16;
+	u32 mthd = (addr & 0x07ff) << 2;
+	u32 subc = (addr & 0x3800) >> 11;
+	u32 data = nv_rd32(dev, pcopy->fuc + 0x044);
+
+	if (stat & 0x00000040) {
+		NV_INFO(dev, "PCOPY: DISPATCH_ERROR [");
+		nouveau_enum_print(nvc0_copy_isr_error_name, ssta);
+		printk("] ch %d [0x%010llx] subc %d mthd 0x%04x data 0x%08x\n",
+			chid, inst, subc, mthd, data);
+		nv_wr32(dev, pcopy->fuc + 0x004, 0x00000040);
+		stat &= ~0x00000040;
+	}
+
+	if (stat) {
+		NV_INFO(dev, "PCOPY: unhandled intr 0x%08x\n", stat);
+		nv_wr32(dev, pcopy->fuc + 0x004, stat);
+	}
+}
+
+static void
+nvc0_copy_isr_0(struct drm_device *dev)
+{
+	nvc0_copy_isr(dev, NVOBJ_ENGINE_COPY0);
+}
+
+static void
+nvc0_copy_isr_1(struct drm_device *dev)
+{
+	nvc0_copy_isr(dev, NVOBJ_ENGINE_COPY1);
+}
+
+static void
+nvc0_copy_destroy(struct drm_device *dev, int engine)
+{
+	struct nvc0_copy_engine *pcopy = nv_engine(dev, engine);
+
+	nouveau_irq_unregister(dev, pcopy->irq);
+
+	if (engine == NVOBJ_ENGINE_COPY0)
+		NVOBJ_ENGINE_DEL(dev, COPY0);
+	else
+		NVOBJ_ENGINE_DEL(dev, COPY1);
+	kfree(pcopy);
+}
+
+int
+nvc0_copy_create(struct drm_device *dev, int engine)
+{
+	struct nvc0_copy_engine *pcopy;
+
+	pcopy = kzalloc(sizeof(*pcopy), GFP_KERNEL);
+	if (!pcopy)
+		return -ENOMEM;
+
+	pcopy->base.destroy = nvc0_copy_destroy;
+	pcopy->base.init = nvc0_copy_init;
+	pcopy->base.fini = nvc0_copy_fini;
+	pcopy->base.context_new = nvc0_copy_context_new;
+	pcopy->base.context_del = nvc0_copy_context_del;
+	pcopy->base.object_new = nvc0_copy_object_new;
+
+	if (engine == 0) {
+		pcopy->irq = 5;
+		pcopy->pmc = 0x00000040;
+		pcopy->fuc = 0x104000;
+		pcopy->ctx = 0x0230;
+		nouveau_irq_register(dev, pcopy->irq, nvc0_copy_isr_0);
+		NVOBJ_ENGINE_ADD(dev, COPY0, &pcopy->base);
+		NVOBJ_CLASS(dev, 0x90b5, COPY0);
+	} else {
+		pcopy->irq = 6;
+		pcopy->pmc = 0x00000080;
+		pcopy->fuc = 0x105000;
+		pcopy->ctx = 0x0240;
+		nouveau_irq_register(dev, pcopy->irq, nvc0_copy_isr_1);
+		NVOBJ_ENGINE_ADD(dev, COPY1, &pcopy->base);
+		NVOBJ_CLASS(dev, 0x90b8, COPY1);
+	}
+
+	return 0;
+}
diff -druN linux-2.6.39-libre/drivers/gpu/drm/nouveau/nvc0_copy.fuc.h linux-3.0-rc7-libre/drivers/gpu/drm/nouveau/nvc0_copy.fuc.h
--- linux-2.6.39-libre/drivers/gpu/drm/nouveau/nvc0_copy.fuc.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/gpu/drm/nouveau/nvc0_copy.fuc.h	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,527 @@
+uint32_t nvc0_pcopy_data[] = {
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00010000,
+	0x00000000,
+	0x00000000,
+	0x00010040,
+	0x0001019f,
+	0x00000000,
+	0x00010050,
+	0x000101a1,
+	0x00000000,
+	0x00070080,
+	0x0000001c,
+	0xfffff000,
+	0x00000020,
+	0xfff80000,
+	0x00000024,
+	0xffffe000,
+	0x00000028,
+	0xfffff800,
+	0x0000002c,
+	0xfffff000,
+	0x00000030,
+	0xfff80000,
+	0x00000034,
+	0xffffe000,
+	0x00070088,
+	0x00000048,
+	0xfffff000,
+	0x0000004c,
+	0xfff80000,
+	0x00000050,
+	0xffffe000,
+	0x00000054,
+	0xfffff800,
+	0x00000058,
+	0xfffff000,
+	0x0000005c,
+	0xfff80000,
+	0x00000060,
+	0xffffe000,
+	0x000200c0,
+	0x000104b8,
+	0x00000000,
+	0x00010541,
+	0x00000000,
+	0x000e00c3,
+	0x00000010,
+	0xffffff00,
+	0x00000014,
+	0x0000000f,
+	0x0000003c,
+	0xffffff00,
+	0x00000040,
+	0x0000000f,
+	0x00000018,
+	0xfff80000,
+	0x00000044,
+	0xfff80000,
+	0x00000074,
+	0xffff0000,
+	0x00000078,
+	0xffffe000,
+	0x00000068,
+	0xfccc0000,
+	0x0000006c,
+	0x00000000,
+	0x00000070,
+	0x00000000,
+	0x00000004,
+	0xffffff00,
+	0x00000008,
+	0x00000000,
+	0x0000000c,
+	0x00000000,
+	0x00000800,
+};
+
+uint32_t nvc0_pcopy_code[] = {
+	0x04fe04bd,
+	0x3517f000,
+	0xf10010fe,
+	0xf1040017,
+	0xf0fff327,
+	0x22d00023,
+	0x0c25f0c0,
+	0xf40012d0,
+	0x17f11031,
+	0x27f01200,
+	0x0012d003,
+	0xf40031f4,
+	0x0ef40028,
+	0x8001cffd,
+	0xf40812c4,
+	0x21f4060b,
+	0x0412c4ca,
+	0xf5070bf4,
+	0xc4010221,
+	0x01d00c11,
+	0xf101f840,
+	0xfe770047,
+	0x47f1004b,
+	0x44cf2100,
+	0x0144f000,
+	0xb60444b6,
+	0xf7f13040,
+	0xf4b6061c,
+	0x1457f106,
+	0x00f5d101,
+	0xb6043594,
+	0x57fe0250,
+	0x0145fe00,
+	0x010052b7,
+	0x00ff67f1,
+	0x56fd60bd,
+	0x0253f004,
+	0xf80545fa,
+	0x0053f003,
+	0xd100e7f0,
+	0x549800fe,
+	0x0845b600,
+	0xb6015698,
+	0x46fd1864,
+	0x0047fe05,
+	0xf00204b9,
+	0x01f40643,
+	0x0604fa09,
+	0xfa060ef4,
+	0x03f80504,
+	0x27f100f8,
+	0x23cf1400,
+	0x1e3fc800,
+	0xf4170bf4,
+	0x21f40132,
+	0x1e3af053,
+	0xf00023d0,
+	0x24d00147,
+	0xcf00f880,
+	0x3dc84023,
+	0x090bf41e,
+	0xf40131f4,
+	0x37f05321,
+	0x8023d002,
+	0x37f100f8,
+	0x32cf1900,
+	0x0033cf40,
+	0x07ff24e4,
+	0xf11024b6,
+	0xbd010057,
+	0x5874bd64,
+	0x57580056,
+	0x0450b601,
+	0xf40446b8,
+	0x76bb4d08,
+	0x0447b800,
+	0xbb0f08f4,
+	0x74b60276,
+	0x0057bb03,
+	0xbbdf0ef4,
+	0x44b60246,
+	0x0045bb03,
+	0xfd014598,
+	0x54b00453,
+	0x201bf400,
+	0x58004558,
+	0x64b00146,
+	0x091bf400,
+	0xf4005380,
+	0x32f4300e,
+	0xf455f901,
+	0x0ef40c01,
+	0x0225f025,
+	0xf10125f0,
+	0xd0100047,
+	0x43d00042,
+	0x4027f040,
+	0xcf0002d0,
+	0x24f08002,
+	0x0024b040,
+	0xf1f71bf4,
+	0xf01d0027,
+	0x23d00137,
+	0xf800f800,
+	0x0027f100,
+	0xf034bd22,
+	0x23d00233,
+	0xf400f800,
+	0x01b0f030,
+	0x0101b000,
+	0xb00201b0,
+	0x04980301,
+	0x3045c71a,
+	0xc70150b6,
+	0x60b63446,
+	0x3847c701,
+	0xf40170b6,
+	0x84bd0232,
+	0x4ac494bd,
+	0x0445b60f,
+	0xa430b4bd,
+	0x0f18f404,
+	0xbbc0a5ff,
+	0x31f400cb,
+	0x220ef402,
+	0xf00c1bf4,
+	0xcbbb10c7,
+	0x160ef400,
+	0xf406a430,
+	0xc7f00c18,
+	0x00cbbb14,
+	0xf1070ef4,
+	0x380080c7,
+	0x80b601c8,
+	0x01b0b601,
+	0xf404b5b8,
+	0x90b6c308,
+	0x0497b801,
+	0xfdb208f4,
+	0x06800065,
+	0x1d08980e,
+	0xf40068fd,
+	0x64bd0502,
+	0x800075fd,
+	0x78fd1907,
+	0x1057f100,
+	0x0654b608,
+	0xd00056d0,
+	0x50b74057,
+	0x06980800,
+	0x0162b619,
+	0x980864b6,
+	0x72b60e07,
+	0x0567fd01,
+	0xb70056d0,
+	0xb4010050,
+	0x56d00060,
+	0x0160b400,
+	0xb44056d0,
+	0x56d00260,
+	0x0360b480,
+	0xb7c056d0,
+	0x98040050,
+	0x56d01b06,
+	0x1c069800,
+	0xf44056d0,
+	0x00f81030,
+	0xc7075798,
+	0x78c76879,
+	0x0380b664,
+	0xb06077c7,
+	0x1bf40e76,
+	0x0477f009,
+	0xf00f0ef4,
+	0x70b6027c,
+	0x0947fd11,
+	0x980677f0,
+	0x5b980c5a,
+	0x00abfd0e,
+	0xbb01b7f0,
+	0xb2b604b7,
+	0xc4abff01,
+	0x9805a7bb,
+	0xe7f00d5d,
+	0x04e8bb01,
+	0xff01e2b6,
+	0xd8bbb4de,
+	0x01e0b605,
+	0xbb0cef94,
+	0xfefd02eb,
+	0x026cf005,
+	0x020860b7,
+	0xd00864b6,
+	0xb7bb006f,
+	0x00cbbb04,
+	0x98085f98,
+	0xfbfd0e5b,
+	0x01b7f000,
+	0xb604b7bb,
+	0xfbbb01b2,
+	0x05f7bb00,
+	0x5f98f0f9,
+	0x01b7f009,
+	0xb604b8bb,
+	0xfbbb01b2,
+	0x05f8bb00,
+	0x78bbf0f9,
+	0x0282b600,
+	0xbb01b7f0,
+	0xb9bb04b8,
+	0x0b589804,
+	0xbb01e7f0,
+	0xe2b604e9,
+	0xf48eff01,
+	0xbb04f7bb,
+	0x79bb00cf,
+	0x0589bb00,
+	0x90fcf0fc,
+	0xbb00d9fd,
+	0x89fd00ad,
+	0x008ffd00,
+	0xbb00a8bb,
+	0x92b604a7,
+	0x0497bb01,
+	0x988069d0,
+	0x58980557,
+	0x00acbb04,
+	0xb6007abb,
+	0x84b60081,
+	0x058bfd10,
+	0x060062b7,
+	0xb70067d0,
+	0xd0040060,
+	0x00f80068,
+	0xb7026cf0,
+	0xb6020260,
+	0x57980864,
+	0x0067d005,
+	0x040060b7,
+	0xb6045798,
+	0x67d01074,
+	0x0060b700,
+	0x06579804,
+	0xf80067d0,
+	0xf900f900,
+	0x0007f110,
+	0x0604b608,
+	0xf00001cf,
+	0x1bf40114,
+	0xfc10fcfa,
+	0xc800f800,
+	0x1bf40d34,
+	0xd121f570,
+	0x0c47f103,
+	0x0644b608,
+	0xb6020598,
+	0x45d00450,
+	0x4040d000,
+	0xd00c57f0,
+	0x40b78045,
+	0x05980400,
+	0x1054b601,
+	0xb70045d0,
+	0xf1050040,
+	0xf00b0057,
+	0x45d00153,
+	0x4057f100,
+	0x0154b640,
+	0x808053f1,
+	0xf14045d0,
+	0xf1111057,
+	0xd0131253,
+	0x57f18045,
+	0x53f11514,
+	0x45d01716,
+	0x0157f1c0,
+	0x0153f026,
+	0x080047f1,
+	0xd00644b6,
+	0x21f50045,
+	0x47f103d1,
+	0x44b6080c,
+	0x02059806,
+	0xd00045d0,
+	0x57f04040,
+	0x8045d004,
+	0x040040b7,
+	0xb6010598,
+	0x45d01054,
+	0x0040b700,
+	0x0057f105,
+	0x0045d003,
+	0x111057f1,
+	0x131253f1,
+	0x984045d0,
+	0x40b70305,
+	0x45d00500,
+	0x0157f100,
+	0x0153f026,
+	0x080047f1,
+	0xd00644b6,
+	0x00f80045,
+	0x03d121f5,
+	0xf4003fc8,
+	0x21f50e0b,
+	0x47f101af,
+	0x0ef40200,
+	0x1067f11e,
+	0x0664b608,
+	0x800177f0,
+	0x07800e07,
+	0x1d079819,
+	0xd00067d0,
+	0x44bd4067,
+	0xbd0232f4,
+	0x043fc854,
+	0xf50a0bf4,
+	0xf403a821,
+	0x21f50a0e,
+	0x49f0029c,
+	0x0231f407,
+	0xc82c57f0,
+	0x0bf4083f,
+	0xa821f50a,
+	0x0a0ef403,
+	0x029c21f5,
+	0xf10849f0,
+	0xb6080057,
+	0x06980654,
+	0x4056d01e,
+	0xf14167f0,
+	0xfd440063,
+	0x54d00546,
+	0x0c3fc800,
+	0xf5070bf4,
+	0xf803eb21,
+	0x0027f100,
+	0xf034bd22,
+	0x23d00133,
+	0x0000f800,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+};
diff -druN linux-2.6.39-libre/drivers/gpu/drm/nouveau/nvc0_fifo.c linux-3.0-rc7-libre/drivers/gpu/drm/nouveau/nvc0_fifo.c
--- linux-2.6.39-libre/drivers/gpu/drm/nouveau/nvc0_fifo.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/gpu/drm/nouveau/nvc0_fifo.c	2011-07-11 19:51:52.000000000 -0400
@@ -37,7 +37,7 @@
 };
 
 struct nvc0_fifo_chan {
-	struct nouveau_bo *user;
+	struct nouveau_gpuobj *user;
 	struct nouveau_gpuobj *ramfc;
 };
 
@@ -106,7 +106,7 @@
 	struct nouveau_fifo_engine *pfifo = &dev_priv->engine.fifo;
 	struct nvc0_fifo_priv *priv = pfifo->priv;
 	struct nvc0_fifo_chan *fifoch;
-	u64 ib_virt, user_vinst;
+	u64 ib_virt = chan->pushbuf_base + chan->dma.ib_base * 4;
 	int ret;
 
 	chan->fifo_priv = kzalloc(sizeof(*fifoch), GFP_KERNEL);
@@ -115,28 +115,13 @@
 	fifoch = chan->fifo_priv;
 
 	/* allocate vram for control regs, map into polling area */
-	ret = nouveau_bo_new(dev, NULL, 0x1000, 0, TTM_PL_FLAG_VRAM,
-			     0, 0, &fifoch->user);
+	ret = nouveau_gpuobj_new(dev, NULL, 0x1000, 0x1000,
+				 NVOBJ_FLAG_ZERO_ALLOC, &fifoch->user);
 	if (ret)
 		goto error;
 
-	ret = nouveau_bo_pin(fifoch->user, TTM_PL_FLAG_VRAM);
-	if (ret) {
-		nouveau_bo_ref(NULL, &fifoch->user);
-		goto error;
-	}
-
-	user_vinst = fifoch->user->bo.mem.start << PAGE_SHIFT;
-
-	ret = nouveau_bo_map(fifoch->user);
-	if (ret) {
-		nouveau_bo_unpin(fifoch->user);
-		nouveau_bo_ref(NULL, &fifoch->user);
-		goto error;
-	}
-
 	nouveau_vm_map_at(&priv->user_vma, chan->id * 0x1000,
-			  fifoch->user->bo.mem.mm_node);
+			  *(struct nouveau_mem **)fifoch->user->node);
 
 	chan->user = ioremap_wc(pci_resource_start(dev->pdev, 1) +
 				priv->user_vma.offset + (chan->id * 0x1000),
@@ -146,20 +131,6 @@
 		goto error;
 	}
 
-	ib_virt = chan->pushbuf_base + chan->dma.ib_base * 4;
-
-	/* zero channel regs */
-	nouveau_bo_wr32(fifoch->user, 0x0040/4, 0);
-	nouveau_bo_wr32(fifoch->user, 0x0044/4, 0);
-	nouveau_bo_wr32(fifoch->user, 0x0048/4, 0);
-	nouveau_bo_wr32(fifoch->user, 0x004c/4, 0);
-	nouveau_bo_wr32(fifoch->user, 0x0050/4, 0);
-	nouveau_bo_wr32(fifoch->user, 0x0058/4, 0);
-	nouveau_bo_wr32(fifoch->user, 0x005c/4, 0);
-	nouveau_bo_wr32(fifoch->user, 0x0060/4, 0);
-	nouveau_bo_wr32(fifoch->user, 0x0088/4, 0);
-	nouveau_bo_wr32(fifoch->user, 0x008c/4, 0);
-
 	/* ramfc */
 	ret = nouveau_gpuobj_new_fake(dev, chan->ramin->pinst,
 				      chan->ramin->vinst, 0x100,
@@ -167,8 +138,8 @@
 	if (ret)
 		goto error;
 
-	nv_wo32(fifoch->ramfc, 0x08, lower_32_bits(user_vinst));
-	nv_wo32(fifoch->ramfc, 0x0c, upper_32_bits(user_vinst));
+	nv_wo32(fifoch->ramfc, 0x08, lower_32_bits(fifoch->user->vinst));
+	nv_wo32(fifoch->ramfc, 0x0c, upper_32_bits(fifoch->user->vinst));
 	nv_wo32(fifoch->ramfc, 0x10, 0x0000face);
 	nv_wo32(fifoch->ramfc, 0x30, 0xfffff902);
 	nv_wo32(fifoch->ramfc, 0x48, lower_32_bits(ib_virt));
@@ -223,11 +194,7 @@
 		return;
 
 	nouveau_gpuobj_ref(NULL, &fifoch->ramfc);
-	if (fifoch->user) {
-		nouveau_bo_unmap(fifoch->user);
-		nouveau_bo_unpin(fifoch->user);
-		nouveau_bo_ref(NULL, &fifoch->user);
-	}
+	nouveau_gpuobj_ref(NULL, &fifoch->user);
 	kfree(fifoch);
 }
 
@@ -240,6 +207,21 @@
 int
 nvc0_fifo_unload_context(struct drm_device *dev)
 {
+	int i;
+
+	for (i = 0; i < 128; i++) {
+		if (!(nv_rd32(dev, 0x003004 + (i * 4)) & 1))
+			continue;
+
+		nv_mask(dev, 0x003004 + (i * 4), 0x00000001, 0x00000000);
+		nv_wr32(dev, 0x002634, i);
+		if (!nv_wait(dev, 0x002634, 0xffffffff, i)) {
+			NV_INFO(dev, "PFIFO: kick ch %d failed: 0x%08x\n",
+				i, nv_rd32(dev, 0x002634));
+			return -EBUSY;
+		}
+	}
+
 	return 0;
 }
 
@@ -309,6 +291,7 @@
 {
 	struct drm_nouveau_private *dev_priv = dev->dev_private;
 	struct nouveau_fifo_engine *pfifo = &dev_priv->engine.fifo;
+	struct nouveau_channel *chan;
 	struct nvc0_fifo_priv *priv;
 	int ret, i;
 
@@ -351,23 +334,74 @@
 	nv_wr32(dev, 0x002a00, 0xffffffff); /* clears PFIFO.INTR bit 30 */
 	nv_wr32(dev, 0x002100, 0xffffffff);
 	nv_wr32(dev, 0x002140, 0xbfffffff);
+
+	/* restore PFIFO context table */
+	for (i = 0; i < 128; i++) {
+		chan = dev_priv->channels.ptr[i];
+		if (!chan || !chan->fifo_priv)
+			continue;
+
+		nv_wr32(dev, 0x003000 + (i * 8), 0xc0000000 |
+						 (chan->ramin->vinst >> 12));
+		nv_wr32(dev, 0x003004 + (i * 8), 0x001f0001);
+	}
+	nvc0_fifo_playlist_update(dev);
+
 	return 0;
 }
 
 struct nouveau_enum nvc0_fifo_fault_unit[] = {
-	{ 0, "PGRAPH" },
-	{ 3, "PEEPHOLE" },
-	{ 4, "BAR1" },
-	{ 5, "BAR3" },
-	{ 7, "PFIFO" },
+	{ 0x00, "PGRAPH" },
+	{ 0x03, "PEEPHOLE" },
+	{ 0x04, "BAR1" },
+	{ 0x05, "BAR3" },
+	{ 0x07, "PFIFO" },
+	{ 0x10, "PBSP" },
+	{ 0x11, "PPPP" },
+	{ 0x13, "PCOUNTER" },
+	{ 0x14, "PVP" },
+	{ 0x15, "PCOPY0" },
+	{ 0x16, "PCOPY1" },
+	{ 0x17, "PDAEMON" },
 	{}
 };
 
 struct nouveau_enum nvc0_fifo_fault_reason[] = {
-	{ 0, "PT_NOT_PRESENT" },
-	{ 1, "PT_TOO_SHORT" },
-	{ 2, "PAGE_NOT_PRESENT" },
-	{ 3, "VM_LIMIT_EXCEEDED" },
+	{ 0x00, "PT_NOT_PRESENT" },
+	{ 0x01, "PT_TOO_SHORT" },
+	{ 0x02, "PAGE_NOT_PRESENT" },
+	{ 0x03, "VM_LIMIT_EXCEEDED" },
+	{ 0x04, "NO_CHANNEL" },
+	{ 0x05, "PAGE_SYSTEM_ONLY" },
+	{ 0x06, "PAGE_READ_ONLY" },
+	{ 0x0a, "COMPRESSED_SYSRAM" },
+	{ 0x0c, "INVALID_STORAGE_TYPE" },
+	{}
+};
+
+struct nouveau_enum nvc0_fifo_fault_hubclient[] = {
+	{ 0x01, "PCOPY0" },
+	{ 0x02, "PCOPY1" },
+	{ 0x04, "DISPATCH" },
+	{ 0x05, "CTXCTL" },
+	{ 0x06, "PFIFO" },
+	{ 0x07, "BAR_READ" },
+	{ 0x08, "BAR_WRITE" },
+	{ 0x0b, "PVP" },
+	{ 0x0c, "PPPP" },
+	{ 0x0d, "PBSP" },
+	{ 0x11, "PCOUNTER" },
+	{ 0x12, "PDAEMON" },
+	{ 0x14, "CCACHE" },
+	{ 0x15, "CCACHE_POST" },
+	{}
+};
+
+struct nouveau_enum nvc0_fifo_fault_gpcclient[] = {
+	{ 0x01, "TEX" },
+	{ 0x0c, "ESETUP" },
+	{ 0x0e, "CTXCTL" },
+	{ 0x0f, "PROP" },
 	{}
 };
 
@@ -385,12 +419,20 @@
 	u32 valo = nv_rd32(dev, 0x2804 + (unit * 0x10));
 	u32 vahi = nv_rd32(dev, 0x2808 + (unit * 0x10));
 	u32 stat = nv_rd32(dev, 0x280c + (unit * 0x10));
+	u32 client = (stat & 0x00001f00) >> 8;
 
 	NV_INFO(dev, "PFIFO: %s fault at 0x%010llx [",
 		(stat & 0x00000080) ? "write" : "read", (u64)vahi << 32 | valo);
 	nouveau_enum_print(nvc0_fifo_fault_reason, stat & 0x0000000f);
 	printk("] from ");
 	nouveau_enum_print(nvc0_fifo_fault_unit, unit);
+	if (stat & 0x00000040) {
+		printk("/");
+		nouveau_enum_print(nvc0_fifo_fault_hubclient, client);
+	} else {
+		printk("/GPC%d/", (stat & 0x1f000000) >> 24);
+		nouveau_enum_print(nvc0_fifo_fault_gpcclient, client);
+	}
 	printk(" on channel 0x%010llx\n", (u64)inst << 12);
 }
 
diff -druN linux-2.6.39-libre/drivers/gpu/drm/nouveau/nvc0_graph.c linux-3.0-rc7-libre/drivers/gpu/drm/nouveau/nvc0_graph.c
--- linux-2.6.39-libre/drivers/gpu/drm/nouveau/nvc0_graph.c	2011-05-19 02:07:51.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/gpu/drm/nouveau/nvc0_graph.c	2011-07-21 06:49:55.000000000 -0400
@@ -30,27 +30,40 @@
 #include "nouveau_mm.h"
 #include "nvc0_graph.h"
 
-static void nvc0_graph_isr(struct drm_device *);
-static void nvc0_runk140_isr(struct drm_device *);
-static int  nvc0_graph_unload_context_to(struct drm_device *dev, u64 chan);
-
-void
-nvc0_graph_fifo_access(struct drm_device *dev, bool enabled)
+static int
+nvc0_graph_load_context(struct nouveau_channel *chan)
 {
+	struct drm_device *dev = chan->dev;
+
+	nv_wr32(dev, 0x409840, 0x00000030);
+	nv_wr32(dev, 0x409500, 0x80000000 | chan->ramin->vinst >> 12);
+	nv_wr32(dev, 0x409504, 0x00000003);
+	if (!nv_wait(dev, 0x409800, 0x00000010, 0x00000010))
+		NV_ERROR(dev, "PGRAPH: load_ctx timeout\n");
+
+	return 0;
 }
 
-struct nouveau_channel *
-nvc0_graph_channel(struct drm_device *dev)
+static int
+nvc0_graph_unload_context_to(struct drm_device *dev, u64 chan)
 {
-	return NULL;
+	nv_wr32(dev, 0x409840, 0x00000003);
+	nv_wr32(dev, 0x409500, 0x80000000 | chan >> 12);
+	nv_wr32(dev, 0x409504, 0x00000009);
+	if (!nv_wait(dev, 0x409800, 0x00000001, 0x00000000)) {
+		NV_ERROR(dev, "PGRAPH: unload_ctx timeout\n");
+		return -EBUSY;
+	}
+
+	return 0;
 }
 
 static int
 nvc0_graph_construct_context(struct nouveau_channel *chan)
 {
 	struct drm_nouveau_private *dev_priv = chan->dev->dev_private;
-	struct nvc0_graph_priv *priv = dev_priv->engine.graph.priv;
-	struct nvc0_graph_chan *grch = chan->pgraph_ctx;
+	struct nvc0_graph_priv *priv = nv_engine(chan->dev, NVOBJ_ENGINE_GR);
+	struct nvc0_graph_chan *grch = chan->engctx[NVOBJ_ENGINE_GR];
 	struct drm_device *dev = chan->dev;
 	int ret, i;
 	u32 *ctx;
@@ -89,9 +102,8 @@
 static int
 nvc0_graph_create_context_mmio_list(struct nouveau_channel *chan)
 {
-	struct drm_nouveau_private *dev_priv = chan->dev->dev_private;
-	struct nvc0_graph_priv *priv = dev_priv->engine.graph.priv;
-	struct nvc0_graph_chan *grch = chan->pgraph_ctx;
+	struct nvc0_graph_priv *priv = nv_engine(chan->dev, NVOBJ_ENGINE_GR);
+	struct nvc0_graph_chan *grch = chan->engctx[NVOBJ_ENGINE_GR];
 	struct drm_device *dev = chan->dev;
 	int i = 0, gpc, tp, ret;
 	u32 magic;
@@ -158,29 +170,27 @@
 	return 0;
 }
 
-int
-nvc0_graph_create_context(struct nouveau_channel *chan)
+static int
+nvc0_graph_context_new(struct nouveau_channel *chan, int engine)
 {
-	struct drm_nouveau_private *dev_priv = chan->dev->dev_private;
+	struct drm_device *dev = chan->dev;
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
 	struct nouveau_instmem_engine *pinstmem = &dev_priv->engine.instmem;
-	struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph;
-	struct nvc0_graph_priv *priv = pgraph->priv;
+	struct nvc0_graph_priv *priv = nv_engine(dev, engine);
 	struct nvc0_graph_chan *grch;
-	struct drm_device *dev = chan->dev;
 	struct nouveau_gpuobj *grctx;
 	int ret, i;
 
-	chan->pgraph_ctx = kzalloc(sizeof(*grch), GFP_KERNEL);
-	if (!chan->pgraph_ctx)
+	grch = kzalloc(sizeof(*grch), GFP_KERNEL);
+	if (!grch)
 		return -ENOMEM;
-	grch = chan->pgraph_ctx;
+	chan->engctx[NVOBJ_ENGINE_GR] = grch;
 
 	ret = nouveau_gpuobj_new(dev, NULL, priv->grctx_size, 256,
 				 NVOBJ_FLAG_VM | NVOBJ_FLAG_ZERO_ALLOC,
 				 &grch->grctx);
 	if (ret)
 		goto error;
-	chan->ramin_grctx = grch->grctx;
 	grctx = grch->grctx;
 
 	ret = nvc0_graph_create_context_mmio_list(chan);
@@ -200,104 +210,49 @@
 	for (i = 0; i < priv->grctx_size; i += 4)
 		nv_wo32(grctx, i, priv->grctx_vals[i / 4]);
 
-        nv_wo32(grctx, 0xf4, 0);
-        nv_wo32(grctx, 0xf8, 0);
-        nv_wo32(grctx, 0x10, grch->mmio_nr);
-        nv_wo32(grctx, 0x14, lower_32_bits(grch->mmio->vinst));
-        nv_wo32(grctx, 0x18, upper_32_bits(grch->mmio->vinst));
-        nv_wo32(grctx, 0x1c, 1);
-        nv_wo32(grctx, 0x20, 0);
-        nv_wo32(grctx, 0x28, 0);
-        nv_wo32(grctx, 0x2c, 0);
+	nv_wo32(grctx, 0xf4, 0);
+	nv_wo32(grctx, 0xf8, 0);
+	nv_wo32(grctx, 0x10, grch->mmio_nr);
+	nv_wo32(grctx, 0x14, lower_32_bits(grch->mmio->vinst));
+	nv_wo32(grctx, 0x18, upper_32_bits(grch->mmio->vinst));
+	nv_wo32(grctx, 0x1c, 1);
+	nv_wo32(grctx, 0x20, 0);
+	nv_wo32(grctx, 0x28, 0);
+	nv_wo32(grctx, 0x2c, 0);
 	pinstmem->flush(dev);
 	return 0;
 
 error:
-	pgraph->destroy_context(chan);
+	priv->base.context_del(chan, engine);
 	return ret;
 }
 
-void
-nvc0_graph_destroy_context(struct nouveau_channel *chan)
+static void
+nvc0_graph_context_del(struct nouveau_channel *chan, int engine)
 {
-	struct nvc0_graph_chan *grch;
-
-	grch = chan->pgraph_ctx;
-	chan->pgraph_ctx = NULL;
-	if (!grch)
-		return;
+	struct nvc0_graph_chan *grch = chan->engctx[engine];
 
 	nouveau_gpuobj_ref(NULL, &grch->mmio);
 	nouveau_gpuobj_ref(NULL, &grch->unk418810);
 	nouveau_gpuobj_ref(NULL, &grch->unk40800c);
 	nouveau_gpuobj_ref(NULL, &grch->unk408004);
 	nouveau_gpuobj_ref(NULL, &grch->grctx);
-	chan->ramin_grctx = NULL;
+	chan->engctx[engine] = NULL;
 }
 
-int
-nvc0_graph_load_context(struct nouveau_channel *chan)
+static int
+nvc0_graph_object_new(struct nouveau_channel *chan, int engine,
+		      u32 handle, u16 class)
 {
-	struct drm_device *dev = chan->dev;
-
-	nv_wr32(dev, 0x409840, 0x00000030);
-	nv_wr32(dev, 0x409500, 0x80000000 | chan->ramin->vinst >> 12);
-	nv_wr32(dev, 0x409504, 0x00000003);
-	if (!nv_wait(dev, 0x409800, 0x00000010, 0x00000010))
-		NV_ERROR(dev, "PGRAPH: load_ctx timeout\n");
-
 	return 0;
 }
 
 static int
-nvc0_graph_unload_context_to(struct drm_device *dev, u64 chan)
+nvc0_graph_fini(struct drm_device *dev, int engine)
 {
-	nv_wr32(dev, 0x409840, 0x00000003);
-	nv_wr32(dev, 0x409500, 0x80000000 | chan >> 12);
-	nv_wr32(dev, 0x409504, 0x00000009);
-	if (!nv_wait(dev, 0x409800, 0x00000001, 0x00000000)) {
-		NV_ERROR(dev, "PGRAPH: unload_ctx timeout\n");
-		return -EBUSY;
-	}
-
 	return 0;
 }
 
-int
-nvc0_graph_unload_context(struct drm_device *dev)
-{
-	u64 inst = (u64)(nv_rd32(dev, 0x409b00) & 0x0fffffff) << 12;
-	return nvc0_graph_unload_context_to(dev, inst);
-}
-
-static void
-nvc0_graph_destroy(struct drm_device *dev)
-{
-	struct drm_nouveau_private *dev_priv = dev->dev_private;
-	struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph;
-	struct nvc0_graph_priv *priv;
-
-	priv = pgraph->priv;
-	if (!priv)
-		return;
-
-	nouveau_irq_unregister(dev, 12);
-	nouveau_irq_unregister(dev, 25);
-
-	nouveau_gpuobj_ref(NULL, &priv->unk4188b8);
-	nouveau_gpuobj_ref(NULL, &priv->unk4188b4);
-
-	if (priv->grctx_vals)
-		kfree(priv->grctx_vals);
-	kfree(priv);
-}
-
-void
-nvc0_graph_takedown(struct drm_device *dev)
-{
-	nvc0_graph_destroy(dev);
-}
-
 static int
 nvc0_graph_mthd_page_flip(struct nouveau_channel *chan,
 			  u32 class, u32 mthd, u32 data)
@@ -306,119 +261,10 @@
 	return 0;
 }
 
-static int
-nvc0_graph_create(struct drm_device *dev)
-{
-	struct drm_nouveau_private *dev_priv = dev->dev_private;
-	struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph;
-	struct nvc0_graph_priv *priv;
-	int ret, gpc, i;
-
-	priv = kzalloc(sizeof(*priv), GFP_KERNEL);
-	if (!priv)
-		return -ENOMEM;
-	pgraph->priv = priv;
-
-	ret = nouveau_gpuobj_new(dev, NULL, 0x1000, 256, 0, &priv->unk4188b4);
-	if (ret)
-		goto error;
-
-	ret = nouveau_gpuobj_new(dev, NULL, 0x1000, 256, 0, &priv->unk4188b8);
-	if (ret)
-		goto error;
-
-	for (i = 0; i < 0x1000; i += 4) {
-		nv_wo32(priv->unk4188b4, i, 0x00000010);
-		nv_wo32(priv->unk4188b8, i, 0x00000010);
-	}
-
-	priv->gpc_nr  =  nv_rd32(dev, 0x409604) & 0x0000001f;
-	priv->rop_nr = (nv_rd32(dev, 0x409604) & 0x001f0000) >> 16;
-	for (gpc = 0; gpc < priv->gpc_nr; gpc++) {
-		priv->tp_nr[gpc] = nv_rd32(dev, GPC_UNIT(gpc, 0x2608));
-		priv->tp_total += priv->tp_nr[gpc];
-	}
-
-	/*XXX: these need figuring out... */
-	switch (dev_priv->chipset) {
-	case 0xc0:
-		if (priv->tp_total == 11) { /* 465, 3/4/4/0, 4 */
-			priv->magic_not_rop_nr = 0x07;
-			/* filled values up to tp_total, the rest 0 */
-			priv->magicgpc980[0]   = 0x22111000;
-			priv->magicgpc980[1]   = 0x00000233;
-			priv->magicgpc980[2]   = 0x00000000;
-			priv->magicgpc980[3]   = 0x00000000;
-			priv->magicgpc918      = 0x000ba2e9;
-		} else
-		if (priv->tp_total == 14) { /* 470, 3/3/4/4, 5 */
-			priv->magic_not_rop_nr = 0x05;
-			priv->magicgpc980[0]   = 0x11110000;
-			priv->magicgpc980[1]   = 0x00233222;
-			priv->magicgpc980[2]   = 0x00000000;
-			priv->magicgpc980[3]   = 0x00000000;
-			priv->magicgpc918      = 0x00092493;
-		} else
-		if (priv->tp_total == 15) { /* 480, 3/4/4/4, 6 */
-			priv->magic_not_rop_nr = 0x06;
-			priv->magicgpc980[0]   = 0x11110000;
-			priv->magicgpc980[1]   = 0x03332222;
-			priv->magicgpc980[2]   = 0x00000000;
-			priv->magicgpc980[3]   = 0x00000000;
-			priv->magicgpc918      = 0x00088889;
-		}
-		break;
-	case 0xc3: /* 450, 4/0/0/0, 2 */
-		priv->magic_not_rop_nr = 0x03;
-		priv->magicgpc980[0]   = 0x00003210;
-		priv->magicgpc980[1]   = 0x00000000;
-		priv->magicgpc980[2]   = 0x00000000;
-		priv->magicgpc980[3]   = 0x00000000;
-		priv->magicgpc918      = 0x00200000;
-		break;
-	case 0xc4: /* 460, 3/4/0/0, 4 */
-		priv->magic_not_rop_nr = 0x01;
-		priv->magicgpc980[0]   = 0x02321100;
-		priv->magicgpc980[1]   = 0x00000000;
-		priv->magicgpc980[2]   = 0x00000000;
-		priv->magicgpc980[3]   = 0x00000000;
-		priv->magicgpc918      = 0x00124925;
-		break;
-	}
-
-	if (!priv->magic_not_rop_nr) {
-		NV_ERROR(dev, "PGRAPH: unknown config: %d/%d/%d/%d, %d\n",
-			 priv->tp_nr[0], priv->tp_nr[1], priv->tp_nr[2],
-			 priv->tp_nr[3], priv->rop_nr);
-		/* use 0xc3's values... */
-		priv->magic_not_rop_nr = 0x03;
-		priv->magicgpc980[0]   = 0x00003210;
-		priv->magicgpc980[1]   = 0x00000000;
-		priv->magicgpc980[2]   = 0x00000000;
-		priv->magicgpc980[3]   = 0x00000000;
-		priv->magicgpc918      = 0x00200000;
-	}
-
-	nouveau_irq_register(dev, 12, nvc0_graph_isr);
-	nouveau_irq_register(dev, 25, nvc0_runk140_isr);
-	NVOBJ_CLASS(dev, 0x902d, GR); /* 2D */
-	NVOBJ_CLASS(dev, 0x9039, GR); /* M2MF */
-	NVOBJ_MTHD (dev, 0x9039, 0x0500, nvc0_graph_mthd_page_flip);
-	NVOBJ_CLASS(dev, 0x9097, GR); /* 3D */
-	NVOBJ_CLASS(dev, 0x90c0, GR); /* COMPUTE */
-	return 0;
-
-error:
-	nvc0_graph_destroy(dev);
-	return ret;
-}
-
 static void
 nvc0_graph_init_obj418880(struct drm_device *dev)
 {
-	struct drm_nouveau_private *dev_priv = dev->dev_private;
-	struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph;
-	struct nvc0_graph_priv *priv = pgraph->priv;
+	struct nvc0_graph_priv *priv = nv_engine(dev, NVOBJ_ENGINE_GR);
 	int i;
 
 	nv_wr32(dev, GPC_BCAST(0x0880), 0x00000000);
@@ -449,35 +295,42 @@
 static void
 nvc0_graph_init_gpc_0(struct drm_device *dev)
 {
-	struct drm_nouveau_private *dev_priv = dev->dev_private;
-	struct nvc0_graph_priv *priv = dev_priv->engine.graph.priv;
-	int gpc;
-	
-	//      TP      ROP UNKVAL(magic_not_rop_nr)
-	// 450: 4/0/0/0 2        3
-	// 460: 3/4/0/0 4        1
-	// 465: 3/4/4/0 4        7
-	// 470: 3/3/4/4 5        5
-	// 480: 3/4/4/4 6        6
+	struct nvc0_graph_priv *priv = nv_engine(dev, NVOBJ_ENGINE_GR);
+	u32 data[TP_MAX / 8];
+	u8  tpnr[GPC_MAX];
+	int i, gpc, tpc;
 
-	// magicgpc918
-	// 450: 00200000 00000000001000000000000000000000
-	// 460: 00124925 00000000000100100100100100100101
-	// 465: 000ba2e9 00000000000010111010001011101001
-	// 470: 00092493 00000000000010010010010010010011
-	// 480: 00088889 00000000000010001000100010001001
+	/*
+	 *      TP      ROP UNKVAL(magic_not_rop_nr)
+	 * 450: 4/0/0/0 2        3
+	 * 460: 3/4/0/0 4        1
+	 * 465: 3/4/4/0 4        7
+	 * 470: 3/3/4/4 5        5
+	 * 480: 3/4/4/4 6        6
+	 *
+	 * magicgpc918
+	 * 450: 00200000 00000000001000000000000000000000
+	 * 460: 00124925 00000000000100100100100100100101
+	 * 465: 000ba2e9 00000000000010111010001011101001
+	 * 470: 00092493 00000000000010010010010010010011
+	 * 480: 00088889 00000000000010001000100010001001
+	 */
 
-	/* filled values up to tp_total, remainder 0 */
-	// 450: 00003210 00000000 00000000 00000000
-	// 460: 02321100 00000000 00000000 00000000
-	// 465: 22111000 00000233 00000000 00000000
-	// 470: 11110000 00233222 00000000 00000000
-	// 480: 11110000 03332222 00000000 00000000
-	
-	nv_wr32(dev, GPC_BCAST(0x0980), priv->magicgpc980[0]);
-	nv_wr32(dev, GPC_BCAST(0x0984), priv->magicgpc980[1]);
-	nv_wr32(dev, GPC_BCAST(0x0988), priv->magicgpc980[2]);
-	nv_wr32(dev, GPC_BCAST(0x098c), priv->magicgpc980[3]);
+	memset(data, 0x00, sizeof(data));
+	memcpy(tpnr, priv->tp_nr, sizeof(priv->tp_nr));
+	for (i = 0, gpc = -1; i < priv->tp_total; i++) {
+		do {
+			gpc = (gpc + 1) % priv->gpc_nr;
+		} while (!tpnr[gpc]);
+		tpc = priv->tp_nr[gpc] - tpnr[gpc]--;
+
+		data[i / 8] |= tpc << ((i % 8) * 4);
+	}
+
+	nv_wr32(dev, GPC_BCAST(0x0980), data[0]);
+	nv_wr32(dev, GPC_BCAST(0x0984), data[1]);
+	nv_wr32(dev, GPC_BCAST(0x0988), data[2]);
+	nv_wr32(dev, GPC_BCAST(0x098c), data[3]);
 
 	for (gpc = 0; gpc < priv->gpc_nr; gpc++) {
 		nv_wr32(dev, GPC_UNIT(gpc, 0x0914), priv->magic_not_rop_nr << 8 |
@@ -509,8 +362,7 @@
 static void
 nvc0_graph_init_gpc_1(struct drm_device *dev)
 {
-	struct drm_nouveau_private *dev_priv = dev->dev_private;
-	struct nvc0_graph_priv *priv = dev_priv->engine.graph.priv;
+	struct nvc0_graph_priv *priv = nv_engine(dev, NVOBJ_ENGINE_GR);
 	int gpc, tp;
 
 	for (gpc = 0; gpc < priv->gpc_nr; gpc++) {
@@ -535,8 +387,7 @@
 static void
 nvc0_graph_init_rop(struct drm_device *dev)
 {
-	struct drm_nouveau_private *dev_priv = dev->dev_private;
-	struct nvc0_graph_priv *priv = dev_priv->engine.graph.priv;
+	struct nvc0_graph_priv *priv = nv_engine(dev, NVOBJ_ENGINE_GR);
 	int rop;
 
 	for (rop = 0; rop < priv->rop_nr; rop++) {
@@ -547,62 +398,36 @@
 	}
 }
 
-static int
-nvc0_fuc_load_fw(struct drm_device *dev, u32 fuc_base,
-		 const char *code_fw, const char *data_fw)
+static void
+nvc0_graph_init_fuc(struct drm_device *dev, u32 fuc_base,
+		    struct nvc0_graph_fuc *code, struct nvc0_graph_fuc *data)
 {
-	const struct firmware *fw;
-	char name[32];
-	int ret, i;
-
-	snprintf(name, sizeof(name), "nouveau/%s", data_fw);
-	ret = reject_firmware(&fw, name, &dev->pdev->dev);
-	if (ret) {
-		NV_ERROR(dev, "failed to load %s\n", data_fw);
-		return ret;
-	}
+	int i;
 
 	nv_wr32(dev, fuc_base + 0x01c0, 0x01000000);
-	for (i = 0; i < fw->size / 4; i++)
-		nv_wr32(dev, fuc_base + 0x01c4, ((u32 *)fw->data)[i]);
-	release_firmware(fw);
-
-	snprintf(name, sizeof(name), "nouveau/%s", code_fw);
-	ret = reject_firmware(&fw, name, &dev->pdev->dev);
-	if (ret) {
-		NV_ERROR(dev, "failed to load %s\n", code_fw);
-		return ret;
-	}
+	for (i = 0; i < data->size / 4; i++)
+		nv_wr32(dev, fuc_base + 0x01c4, data->data[i]);
 
 	nv_wr32(dev, fuc_base + 0x0180, 0x01000000);
-	for (i = 0; i < fw->size / 4; i++) {
+	for (i = 0; i < code->size / 4; i++) {
 		if ((i & 0x3f) == 0)
 			nv_wr32(dev, fuc_base + 0x0188, i >> 6);
-		nv_wr32(dev, fuc_base + 0x0184, ((u32 *)fw->data)[i]);
+		nv_wr32(dev, fuc_base + 0x0184, code->data[i]);
 	}
-	release_firmware(fw);
-
-	return 0;
 }
 
 static int
 nvc0_graph_init_ctxctl(struct drm_device *dev)
 {
-	struct drm_nouveau_private *dev_priv = dev->dev_private;
-	struct nvc0_graph_priv *priv = dev_priv->engine.graph.priv;
+	struct nvc0_graph_priv *priv = nv_engine(dev, NVOBJ_ENGINE_GR);
 	u32 r000260;
-	int ret;
 
 	/* load fuc microcode */
 	r000260 = nv_mask(dev, 0x000260, 0x00000001, 0x00000000);
-	ret = nvc0_fuc_load_fw(dev, 0x409000, "/*(DEBLOBBED)*/", "/*(DEBLOBBED)*/");
-	if (ret == 0)
-		ret = nvc0_fuc_load_fw(dev, 0x41a000, "/*(DEBLOBBED)*/", "/*(DEBLOBBED)*/");
+	nvc0_graph_init_fuc(dev, 0x409000, &priv->fuc409c, &priv->fuc409d);
+	nvc0_graph_init_fuc(dev, 0x41a000, &priv->fuc41ac, &priv->fuc41ad);
 	nv_wr32(dev, 0x000260, r000260);
 
-	if (ret)
-		return ret;
-
 	/* start both of them running */
 	nv_wr32(dev, 0x409840, 0xffffffff);
 	nv_wr32(dev, 0x41a10c, 0x00000000);
@@ -644,41 +469,19 @@
 	return 0;
 }
 
-int
-nvc0_graph_init(struct drm_device *dev)
+static int
+nvc0_graph_init(struct drm_device *dev, int engine)
 {
-	struct drm_nouveau_private *dev_priv = dev->dev_private;
-	struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph;
 	int ret;
 
-	dev_priv->engine.graph.accel_blocked = true;
-
-	switch (dev_priv->chipset) {
-	case 0xc0:
-	case 0xc3:
-	case 0xc4:
-		break;
-	default:
-		NV_ERROR(dev, "PGRAPH: unsupported chipset, please report!\n");
-		if (nouveau_noaccel != 0)
-			return 0;
-		break;
-	}
-
 	nv_mask(dev, 0x000200, 0x18001000, 0x00000000);
 	nv_mask(dev, 0x000200, 0x18001000, 0x18001000);
 
-	if (!pgraph->priv) {
-		ret = nvc0_graph_create(dev);
-		if (ret)
-			return ret;
-	}
-
 	nvc0_graph_init_obj418880(dev);
 	nvc0_graph_init_regs(dev);
-	//nvc0_graph_init_unitplemented_magics(dev);
+	/*nvc0_graph_init_unitplemented_magics(dev);*/
 	nvc0_graph_init_gpc_0(dev);
-	//nvc0_graph_init_unitplemented_c242(dev);
+	/*nvc0_graph_init_unitplemented_c242(dev);*/
 
 	nv_wr32(dev, 0x400500, 0x00010001);
 	nv_wr32(dev, 0x400100, 0xffffffff);
@@ -697,12 +500,13 @@
 	nv_wr32(dev, 0x400054, 0x34ce3464);
 
 	ret = nvc0_graph_init_ctxctl(dev);
-	if (ret == 0)
-		dev_priv->engine.graph.accel_blocked = false;
+	if (ret)
+		return ret;
+
 	return 0;
 }
 
-static int
+int
 nvc0_graph_isr_chid(struct drm_device *dev, u64 inst)
 {
 	struct drm_nouveau_private *dev_priv = dev->dev_private;
@@ -806,3 +610,172 @@
 		units &= ~(1 << unit);
 	}
 }
+
+static int
+nvc0_graph_create_fw(struct drm_device *dev, const char *fwname,
+		     struct nvc0_graph_fuc *fuc)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	const struct firmware *fw;
+	char f[32];
+	int ret;
+
+	snprintf(f, sizeof(f), "/*(DEBLOBBED)*/", dev_priv->chipset, fwname);
+	ret = reject_firmware(&fw, f, &dev->pdev->dev);
+	if (ret) {
+		snprintf(f, sizeof(f), "/*(DEBLOBBED)*/", fwname);
+		ret = reject_firmware(&fw, f, &dev->pdev->dev);
+		if (ret) {
+			NV_ERROR(dev, "failed to load %s\n", fwname);
+			return ret;
+		}
+	}
+
+	fuc->size = fw->size;
+	fuc->data = kmemdup(fw->data, fuc->size, GFP_KERNEL);
+	release_firmware(fw);
+	return (fuc->data != NULL) ? 0 : -ENOMEM;
+}
+
+static void
+nvc0_graph_destroy_fw(struct nvc0_graph_fuc *fuc)
+{
+	if (fuc->data) {
+		kfree(fuc->data);
+		fuc->data = NULL;
+	}
+}
+
+static void
+nvc0_graph_destroy(struct drm_device *dev, int engine)
+{
+	struct nvc0_graph_priv *priv = nv_engine(dev, engine);
+
+	nvc0_graph_destroy_fw(&priv->fuc409c);
+	nvc0_graph_destroy_fw(&priv->fuc409d);
+	nvc0_graph_destroy_fw(&priv->fuc41ac);
+	nvc0_graph_destroy_fw(&priv->fuc41ad);
+
+	nouveau_irq_unregister(dev, 12);
+	nouveau_irq_unregister(dev, 25);
+
+	nouveau_gpuobj_ref(NULL, &priv->unk4188b8);
+	nouveau_gpuobj_ref(NULL, &priv->unk4188b4);
+
+	if (priv->grctx_vals)
+		kfree(priv->grctx_vals);
+
+	NVOBJ_ENGINE_DEL(dev, GR);
+	kfree(priv);
+}
+
+int
+nvc0_graph_create(struct drm_device *dev)
+{
+	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nvc0_graph_priv *priv;
+	int ret, gpc, i;
+
+	switch (dev_priv->chipset) {
+	case 0xc0:
+	case 0xc3:
+	case 0xc4:
+		break;
+	default:
+		NV_ERROR(dev, "PGRAPH: unsupported chipset, please report!\n");
+		return 0;
+	}
+
+	priv = kzalloc(sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	priv->base.destroy = nvc0_graph_destroy;
+	priv->base.init = nvc0_graph_init;
+	priv->base.fini = nvc0_graph_fini;
+	priv->base.context_new = nvc0_graph_context_new;
+	priv->base.context_del = nvc0_graph_context_del;
+	priv->base.object_new = nvc0_graph_object_new;
+
+	NVOBJ_ENGINE_ADD(dev, GR, &priv->base);
+	nouveau_irq_register(dev, 12, nvc0_graph_isr);
+	nouveau_irq_register(dev, 25, nvc0_runk140_isr);
+
+	if (nvc0_graph_create_fw(dev, "fuc409c", &priv->fuc409c) ||
+	    nvc0_graph_create_fw(dev, "fuc409d", &priv->fuc409d) ||
+	    nvc0_graph_create_fw(dev, "fuc41ac", &priv->fuc41ac) ||
+	    nvc0_graph_create_fw(dev, "fuc41ad", &priv->fuc41ad)) {
+		ret = 0;
+		goto error;
+	}
+
+
+	ret = nouveau_gpuobj_new(dev, NULL, 0x1000, 256, 0, &priv->unk4188b4);
+	if (ret)
+		goto error;
+
+	ret = nouveau_gpuobj_new(dev, NULL, 0x1000, 256, 0, &priv->unk4188b8);
+	if (ret)
+		goto error;
+
+	for (i = 0; i < 0x1000; i += 4) {
+		nv_wo32(priv->unk4188b4, i, 0x00000010);
+		nv_wo32(priv->unk4188b8, i, 0x00000010);
+	}
+
+	priv->gpc_nr  =  nv_rd32(dev, 0x409604) & 0x0000001f;
+	priv->rop_nr = (nv_rd32(dev, 0x409604) & 0x001f0000) >> 16;
+	for (gpc = 0; gpc < priv->gpc_nr; gpc++) {
+		priv->tp_nr[gpc] = nv_rd32(dev, GPC_UNIT(gpc, 0x2608));
+		priv->tp_total += priv->tp_nr[gpc];
+	}
+
+	/*XXX: these need figuring out... */
+	switch (dev_priv->chipset) {
+	case 0xc0:
+		if (priv->tp_total == 11) { /* 465, 3/4/4/0, 4 */
+			priv->magic_not_rop_nr = 0x07;
+			/* filled values up to tp_total, the rest 0 */
+			priv->magicgpc918      = 0x000ba2e9;
+		} else
+		if (priv->tp_total == 14) { /* 470, 3/3/4/4, 5 */
+			priv->magic_not_rop_nr = 0x05;
+			priv->magicgpc918      = 0x00092493;
+		} else
+		if (priv->tp_total == 15) { /* 480, 3/4/4/4, 6 */
+			priv->magic_not_rop_nr = 0x06;
+			priv->magicgpc918      = 0x00088889;
+		}
+		break;
+	case 0xc3: /* 450, 4/0/0/0, 2 */
+		priv->magic_not_rop_nr = 0x03;
+		priv->magicgpc918      = 0x00200000;
+		break;
+	case 0xc4: /* 460, 3/4/0/0, 4 */
+		priv->magic_not_rop_nr = 0x01;
+		priv->magicgpc918      = 0x00124925;
+		break;
+	}
+
+	if (!priv->magic_not_rop_nr) {
+		NV_ERROR(dev, "PGRAPH: unknown config: %d/%d/%d/%d, %d\n",
+			 priv->tp_nr[0], priv->tp_nr[1], priv->tp_nr[2],
+			 priv->tp_nr[3], priv->rop_nr);
+		/* use 0xc3's values... */
+		priv->magic_not_rop_nr = 0x03;
+		priv->magicgpc918      = 0x00200000;
+	}
+
+	NVOBJ_CLASS(dev, 0x902d, GR); /* 2D */
+	NVOBJ_CLASS(dev, 0x9039, GR); /* M2MF */
+	NVOBJ_MTHD (dev, 0x9039, 0x0500, nvc0_graph_mthd_page_flip);
+	NVOBJ_CLASS(dev, 0x9097, GR); /* 3D */
+	NVOBJ_CLASS(dev, 0x90c0, GR); /* COMPUTE */
+	return 0;
+
+error:
+	nvc0_graph_destroy(dev, NVOBJ_ENGINE_GR);
+	return ret;
+}
+
+/*(DEBLOBBED)*/
diff -druN linux-2.6.39-libre/drivers/gpu/drm/nouveau/nvc0_graph.h linux-3.0-rc7-libre/drivers/gpu/drm/nouveau/nvc0_graph.h
--- linux-2.6.39-libre/drivers/gpu/drm/nouveau/nvc0_graph.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/gpu/drm/nouveau/nvc0_graph.h	2011-07-11 19:51:52.000000000 -0400
@@ -28,13 +28,25 @@
 #define GPC_MAX 4
 #define TP_MAX 32
 
-#define ROP_BCAST(r)   (0x408800 + (r))
-#define ROP_UNIT(u,r)  (0x410000 + (u) * 0x400 + (r))
-#define GPC_BCAST(r)   (0x418000 + (r))
-#define GPC_UNIT(t,r)  (0x500000 + (t) * 0x8000 + (r))
-#define TP_UNIT(t,m,r) (0x504000 + (t) * 0x8000 + (m) * 0x800 + (r))
+#define ROP_BCAST(r)     (0x408800 + (r))
+#define ROP_UNIT(u, r)   (0x410000 + (u) * 0x400 + (r))
+#define GPC_BCAST(r)     (0x418000 + (r))
+#define GPC_UNIT(t, r)   (0x500000 + (t) * 0x8000 + (r))
+#define TP_UNIT(t, m, r) (0x504000 + (t) * 0x8000 + (m) * 0x800 + (r))
+
+struct nvc0_graph_fuc {
+	u32 *data;
+	u32  size;
+};
 
 struct nvc0_graph_priv {
+	struct nouveau_exec_engine base;
+
+	struct nvc0_graph_fuc fuc409c;
+	struct nvc0_graph_fuc fuc409d;
+	struct nvc0_graph_fuc fuc41ac;
+	struct nvc0_graph_fuc fuc41ad;
+
 	u8 gpc_nr;
 	u8 rop_nr;
 	u8 tp_nr[GPC_MAX];
@@ -46,15 +58,14 @@
 	struct nouveau_gpuobj *unk4188b8;
 
 	u8  magic_not_rop_nr;
-	u32 magicgpc980[4];
 	u32 magicgpc918;
 };
 
 struct nvc0_graph_chan {
 	struct nouveau_gpuobj *grctx;
-	struct nouveau_gpuobj *unk408004; // 0x418810 too
-	struct nouveau_gpuobj *unk40800c; // 0x419004 too
-	struct nouveau_gpuobj *unk418810; // 0x419848 too
+	struct nouveau_gpuobj *unk408004; /* 0x418810 too */
+	struct nouveau_gpuobj *unk40800c; /* 0x419004 too */
+	struct nouveau_gpuobj *unk418810; /* 0x419848 too */
 	struct nouveau_gpuobj *mmio;
 	int mmio_nr;
 };
diff -druN linux-2.6.39-libre/drivers/gpu/drm/nouveau/nvc0_grctx.c linux-3.0-rc7-libre/drivers/gpu/drm/nouveau/nvc0_grctx.c
--- linux-2.6.39-libre/drivers/gpu/drm/nouveau/nvc0_grctx.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/gpu/drm/nouveau/nvc0_grctx.c	2011-07-11 19:51:52.000000000 -0400
@@ -1623,7 +1623,7 @@
 {
 	struct drm_nouveau_private *dev_priv = dev->dev_private;
 
-	// ROPC_BROADCAST
+	/* ROPC_BROADCAST */
 	nv_wr32(dev, 0x408800, 0x02802a3c);
 	nv_wr32(dev, 0x408804, 0x00000040);
 	nv_wr32(dev, 0x408808, 0x0003e00d);
@@ -1647,7 +1647,7 @@
 {
 	int i;
 
-	// GPC_BROADCAST
+	/* GPC_BROADCAST */
 	nv_wr32(dev, 0x418380, 0x00000016);
 	nv_wr32(dev, 0x418400, 0x38004e00);
 	nv_wr32(dev, 0x418404, 0x71e0ffff);
@@ -1728,7 +1728,7 @@
 {
 	struct drm_nouveau_private *dev_priv = dev->dev_private;
 
-	// GPC_BROADCAST.TP_BROADCAST
+	/* GPC_BROADCAST.TP_BROADCAST */
 	nv_wr32(dev, 0x419848, 0x00000000);
 	nv_wr32(dev, 0x419864, 0x0000012a);
 	nv_wr32(dev, 0x419888, 0x00000000);
@@ -1741,7 +1741,7 @@
 	nv_wr32(dev, 0x419a1c, 0x00000000);
 	nv_wr32(dev, 0x419a20, 0x00000800);
 	if (dev_priv->chipset != 0xc0)
-		nv_wr32(dev, 0x00419ac4, 0x0007f440); // 0xc3
+		nv_wr32(dev, 0x00419ac4, 0x0007f440); /* 0xc3 */
 	nv_wr32(dev, 0x419b00, 0x0a418820);
 	nv_wr32(dev, 0x419b04, 0x062080e6);
 	nv_wr32(dev, 0x419b08, 0x020398a4);
@@ -1797,8 +1797,8 @@
 nvc0_grctx_generate(struct nouveau_channel *chan)
 {
 	struct drm_nouveau_private *dev_priv = chan->dev->dev_private;
-	struct nvc0_graph_priv *priv = dev_priv->engine.graph.priv;
-	struct nvc0_graph_chan *grch = chan->pgraph_ctx;
+	struct nvc0_graph_priv *priv = nv_engine(chan->dev, NVOBJ_ENGINE_GR);
+	struct nvc0_graph_chan *grch = chan->engctx[NVOBJ_ENGINE_GR];
 	struct drm_device *dev = chan->dev;
 	int i, gpc, tp, id;
 	u32 r000260, tmp;
@@ -1912,13 +1912,13 @@
 		for (i = 1; i < 7; i++)
 			data2[1] |= ((1 << (i + 5)) % ntpcv) << ((i - 1) * 5);
 
-		// GPC_BROADCAST
+		/* GPC_BROADCAST */
 		nv_wr32(dev, 0x418bb8, (priv->tp_total << 8) |
 					priv->magic_not_rop_nr);
 		for (i = 0; i < 6; i++)
 			nv_wr32(dev, 0x418b08 + (i * 4), data[i]);
 
-		// GPC_BROADCAST.TP_BROADCAST
+		/* GPC_BROADCAST.TP_BROADCAST */
 		nv_wr32(dev, 0x419bd0, (priv->tp_total << 8) |
 				       priv->magic_not_rop_nr |
 				       data2[0]);
@@ -1926,7 +1926,7 @@
 		for (i = 0; i < 6; i++)
 			nv_wr32(dev, 0x419b00 + (i * 4), data[i]);
 
-		// UNK78xx
+		/* UNK78xx */
 		nv_wr32(dev, 0x4078bc, (priv->tp_total << 8) |
 					priv->magic_not_rop_nr);
 		for (i = 0; i < 6; i++)
@@ -1944,7 +1944,7 @@
 		gpc = -1;
 		for (i = 0, gpc = -1; i < 32; i++) {
 			int ltp = i * (priv->tp_total - 1) / 32;
-			
+
 			do {
 				gpc = (gpc + 1) % priv->gpc_nr;
 			} while (!tpnr[gpc]);
diff -druN linux-2.6.39-libre/drivers/gpu/drm/nouveau/nvreg.h linux-3.0-rc7-libre/drivers/gpu/drm/nouveau/nvreg.h
--- linux-2.6.39-libre/drivers/gpu/drm/nouveau/nvreg.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/gpu/drm/nouveau/nvreg.h	2011-07-11 19:51:52.000000000 -0400
@@ -277,6 +277,8 @@
 #		define NV_CIO_CRE_EBR_VDE_11		2:2
 #		define NV_CIO_CRE_EBR_VRS_11		4:4
 #		define NV_CIO_CRE_EBR_VBS_11		6:6
+#	define NV_CIO_CRE_42			0x42
+#		define NV_CIO_CRE_42_OFFSET_11		6:6
 #	define NV_CIO_CRE_43			0x43
 #	define NV_CIO_CRE_44			0x44	/* head control */
 #	define NV_CIO_CRE_CSB			0x45	/* colour saturation boost */
diff -druN linux-2.6.39-libre/drivers/gpu/drm/radeon/atombios_crtc.c linux-3.0-rc7-libre/drivers/gpu/drm/radeon/atombios_crtc.c
--- linux-2.6.39-libre/drivers/gpu/drm/radeon/atombios_crtc.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/gpu/drm/radeon/atombios_crtc.c	2011-07-11 19:51:52.000000000 -0400
@@ -420,7 +420,7 @@
 
 	if (ASIC_IS_DCE5(rdev)) {
 		args.v3.usSpreadSpectrumAmountFrac = cpu_to_le16(0);
-		args.v3.ucSpreadSpectrumType = ss->type;
+		args.v3.ucSpreadSpectrumType = ss->type & ATOM_SS_CENTRE_SPREAD_MODE_MASK;
 		switch (pll_id) {
 		case ATOM_PPLL1:
 			args.v3.ucSpreadSpectrumType |= ATOM_PPLL_SS_TYPE_V3_P1PLL;
@@ -440,10 +440,12 @@
 		case ATOM_PPLL_INVALID:
 			return;
 		}
-		args.v2.ucEnable = enable;
+		args.v3.ucEnable = enable;
+		if ((ss->percentage == 0) || (ss->type & ATOM_EXTERNAL_SS_MASK))
+			args.v3.ucEnable = ATOM_DISABLE;
 	} else if (ASIC_IS_DCE4(rdev)) {
 		args.v2.usSpreadSpectrumPercentage = cpu_to_le16(ss->percentage);
-		args.v2.ucSpreadSpectrumType = ss->type;
+		args.v2.ucSpreadSpectrumType = ss->type & ATOM_SS_CENTRE_SPREAD_MODE_MASK;
 		switch (pll_id) {
 		case ATOM_PPLL1:
 			args.v2.ucSpreadSpectrumType |= ATOM_PPLL_SS_TYPE_V2_P1PLL;
@@ -464,32 +466,36 @@
 			return;
 		}
 		args.v2.ucEnable = enable;
+		if ((ss->percentage == 0) || (ss->type & ATOM_EXTERNAL_SS_MASK))
+			args.v2.ucEnable = ATOM_DISABLE;
 	} else if (ASIC_IS_DCE3(rdev)) {
 		args.v1.usSpreadSpectrumPercentage = cpu_to_le16(ss->percentage);
-		args.v1.ucSpreadSpectrumType = ss->type;
+		args.v1.ucSpreadSpectrumType = ss->type & ATOM_SS_CENTRE_SPREAD_MODE_MASK;
 		args.v1.ucSpreadSpectrumStep = ss->step;
 		args.v1.ucSpreadSpectrumDelay = ss->delay;
 		args.v1.ucSpreadSpectrumRange = ss->range;
 		args.v1.ucPpll = pll_id;
 		args.v1.ucEnable = enable;
 	} else if (ASIC_IS_AVIVO(rdev)) {
-		if (enable == ATOM_DISABLE) {
+		if ((enable == ATOM_DISABLE) || (ss->percentage == 0) ||
+		    (ss->type & ATOM_EXTERNAL_SS_MASK)) {
 			atombios_disable_ss(crtc);
 			return;
 		}
 		args.lvds_ss_2.usSpreadSpectrumPercentage = cpu_to_le16(ss->percentage);
-		args.lvds_ss_2.ucSpreadSpectrumType = ss->type;
+		args.lvds_ss_2.ucSpreadSpectrumType = ss->type & ATOM_SS_CENTRE_SPREAD_MODE_MASK;
 		args.lvds_ss_2.ucSpreadSpectrumStep = ss->step;
 		args.lvds_ss_2.ucSpreadSpectrumDelay = ss->delay;
 		args.lvds_ss_2.ucSpreadSpectrumRange = ss->range;
 		args.lvds_ss_2.ucEnable = enable;
 	} else {
-		if (enable == ATOM_DISABLE) {
+		if ((enable == ATOM_DISABLE) || (ss->percentage == 0) ||
+		    (ss->type & ATOM_EXTERNAL_SS_MASK)) {
 			atombios_disable_ss(crtc);
 			return;
 		}
 		args.lvds_ss.usSpreadSpectrumPercentage = cpu_to_le16(ss->percentage);
-		args.lvds_ss.ucSpreadSpectrumType = ss->type;
+		args.lvds_ss.ucSpreadSpectrumType = ss->type & ATOM_SS_CENTRE_SPREAD_MODE_MASK;
 		args.lvds_ss.ucSpreadSpectrumStepSize_Delay = (ss->step & 3) << 2;
 		args.lvds_ss.ucSpreadSpectrumStepSize_Delay |= (ss->delay & 7) << 4;
 		args.lvds_ss.ucEnable = enable;
@@ -512,6 +518,7 @@
 	struct radeon_device *rdev = dev->dev_private;
 	struct drm_encoder *encoder = NULL;
 	struct radeon_encoder *radeon_encoder = NULL;
+	struct drm_connector *connector = NULL;
 	u32 adjusted_clock = mode->clock;
 	int encoder_mode = 0;
 	u32 dp_clock = mode->clock;
@@ -546,9 +553,12 @@
 	list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
 		if (encoder->crtc == crtc) {
 			radeon_encoder = to_radeon_encoder(encoder);
+			connector = radeon_get_connector_for_encoder(encoder);
+			if (connector)
+				bpc = connector->display_info.bpc;
 			encoder_mode = atombios_get_encoder_mode(encoder);
-			if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT | ATOM_DEVICE_DFP_SUPPORT)) {
-				struct drm_connector *connector = radeon_get_connector_for_encoder(encoder);
+			if ((radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT | ATOM_DEVICE_DFP_SUPPORT)) ||
+			    radeon_encoder_is_dp_bridge(encoder)) {
 				if (connector) {
 					struct radeon_connector *radeon_connector = to_radeon_connector(connector);
 					struct radeon_connector_atom_dig *dig_connector =
@@ -612,7 +622,7 @@
 				args.v1.usPixelClock = cpu_to_le16(mode->clock / 10);
 				args.v1.ucTransmitterID = radeon_encoder->encoder_id;
 				args.v1.ucEncodeMode = encoder_mode;
-				if (ss_enabled)
+				if (ss_enabled && ss->percentage)
 					args.v1.ucConfig |=
 						ADJUST_DISPLAY_CONFIG_SS_ENABLE;
 
@@ -625,10 +635,11 @@
 				args.v3.sInput.ucTransmitterID = radeon_encoder->encoder_id;
 				args.v3.sInput.ucEncodeMode = encoder_mode;
 				args.v3.sInput.ucDispPllConfig = 0;
-				if (ss_enabled)
+				if (ss_enabled && ss->percentage)
 					args.v3.sInput.ucDispPllConfig |=
 						DISPPLL_CONFIG_SS_ENABLE;
-				if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) {
+				if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT) ||
+				    radeon_encoder_is_dp_bridge(encoder)) {
 					struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
 					if (encoder_mode == ATOM_ENCODER_MODE_DP) {
 						args.v3.sInput.ucDispPllConfig |=
@@ -660,6 +671,13 @@
 								DISPPLL_CONFIG_DUAL_LINK;
 					}
 				}
+				if (radeon_encoder_is_dp_bridge(encoder)) {
+					struct drm_encoder *ext_encoder = radeon_atom_get_external_encoder(encoder);
+					struct radeon_encoder *ext_radeon_encoder = to_radeon_encoder(ext_encoder);
+					args.v3.sInput.ucExtTransmitterID = ext_radeon_encoder->encoder_id;
+				} else
+					args.v3.sInput.ucExtTransmitterID = 0;
+
 				atom_execute_table(rdev->mode_info.atom_context,
 						   index, (uint32_t *)&args);
 				adjusted_clock = le32_to_cpu(args.v3.sOutput.ulDispPllFreq) * 10;
@@ -754,7 +772,10 @@
 				      u32 ref_div,
 				      u32 fb_div,
 				      u32 frac_fb_div,
-				      u32 post_div)
+				      u32 post_div,
+				      int bpc,
+				      bool ss_enabled,
+				      struct radeon_atom_ss *ss)
 {
 	struct drm_device *dev = crtc->dev;
 	struct radeon_device *rdev = dev->dev_private;
@@ -801,6 +822,8 @@
 			args.v3.ucPostDiv = post_div;
 			args.v3.ucPpll = pll_id;
 			args.v3.ucMiscInfo = (pll_id << 2);
+			if (ss_enabled && (ss->type & ATOM_EXTERNAL_SS_MASK))
+				args.v3.ucMiscInfo |= PIXEL_CLOCK_MISC_REF_DIV_SRC;
 			args.v3.ucTransmitterId = encoder_id;
 			args.v3.ucEncoderMode = encoder_mode;
 			break;
@@ -812,6 +835,17 @@
 			args.v5.ulFbDivDecFrac = cpu_to_le32(frac_fb_div * 100000);
 			args.v5.ucPostDiv = post_div;
 			args.v5.ucMiscInfo = 0; /* HDMI depth, etc. */
+			if (ss_enabled && (ss->type & ATOM_EXTERNAL_SS_MASK))
+				args.v5.ucMiscInfo |= PIXEL_CLOCK_V5_MISC_REF_DIV_SRC;
+			switch (bpc) {
+			case 8:
+			default:
+				args.v5.ucMiscInfo |= PIXEL_CLOCK_V5_MISC_HDMI_24BPP;
+				break;
+			case 10:
+				args.v5.ucMiscInfo |= PIXEL_CLOCK_V5_MISC_HDMI_30BPP;
+				break;
+			}
 			args.v5.ucTransmitterID = encoder_id;
 			args.v5.ucEncoderMode = encoder_mode;
 			args.v5.ucPpll = pll_id;
@@ -824,6 +858,23 @@
 			args.v6.ulFbDivDecFrac = cpu_to_le32(frac_fb_div * 100000);
 			args.v6.ucPostDiv = post_div;
 			args.v6.ucMiscInfo = 0; /* HDMI depth, etc. */
+			if (ss_enabled && (ss->type & ATOM_EXTERNAL_SS_MASK))
+				args.v6.ucMiscInfo |= PIXEL_CLOCK_V6_MISC_REF_DIV_SRC;
+			switch (bpc) {
+			case 8:
+			default:
+				args.v6.ucMiscInfo |= PIXEL_CLOCK_V6_MISC_HDMI_24BPP;
+				break;
+			case 10:
+				args.v6.ucMiscInfo |= PIXEL_CLOCK_V6_MISC_HDMI_30BPP;
+				break;
+			case 12:
+				args.v6.ucMiscInfo |= PIXEL_CLOCK_V6_MISC_HDMI_36BPP;
+				break;
+			case 16:
+				args.v6.ucMiscInfo |= PIXEL_CLOCK_V6_MISC_HDMI_48BPP;
+				break;
+			}
 			args.v6.ucTransmitterID = encoder_id;
 			args.v6.ucEncoderMode = encoder_mode;
 			args.v6.ucPpll = pll_id;
@@ -855,6 +906,7 @@
 	int encoder_mode = 0;
 	struct radeon_atom_ss ss;
 	bool ss_enabled = false;
+	int bpc = 8;
 
 	list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
 		if (encoder->crtc == crtc) {
@@ -891,41 +943,30 @@
 		struct radeon_connector_atom_dig *dig_connector =
 			radeon_connector->con_priv;
 		int dp_clock;
+		bpc = connector->display_info.bpc;
 
 		switch (encoder_mode) {
 		case ATOM_ENCODER_MODE_DP:
 			/* DP/eDP */
 			dp_clock = dig_connector->dp_clock / 10;
-			if (radeon_encoder->active_device & (ATOM_DEVICE_LCD_SUPPORT)) {
-				if (ASIC_IS_DCE4(rdev))
-					ss_enabled =
-						radeon_atombios_get_asic_ss_info(rdev, &ss,
-										 dig->lcd_ss_id,
-										 dp_clock);
-				else
+			if (ASIC_IS_DCE4(rdev))
+				ss_enabled =
+					radeon_atombios_get_asic_ss_info(rdev, &ss,
+									 ASIC_INTERNAL_SS_ON_DP,
+									 dp_clock);
+			else {
+				if (dp_clock == 16200) {
 					ss_enabled =
 						radeon_atombios_get_ppll_ss_info(rdev, &ss,
-										 dig->lcd_ss_id);
-			} else {
-				if (ASIC_IS_DCE4(rdev))
-					ss_enabled =
-						radeon_atombios_get_asic_ss_info(rdev, &ss,
-										 ASIC_INTERNAL_SS_ON_DP,
-										 dp_clock);
-				else {
-					if (dp_clock == 16200) {
-						ss_enabled =
-							radeon_atombios_get_ppll_ss_info(rdev, &ss,
-											 ATOM_DP_SS_ID2);
-						if (!ss_enabled)
-							ss_enabled =
-								radeon_atombios_get_ppll_ss_info(rdev, &ss,
-												 ATOM_DP_SS_ID1);
-					} else
+										 ATOM_DP_SS_ID2);
+					if (!ss_enabled)
 						ss_enabled =
 							radeon_atombios_get_ppll_ss_info(rdev, &ss,
 											 ATOM_DP_SS_ID1);
-				}
+				} else
+					ss_enabled =
+						radeon_atombios_get_ppll_ss_info(rdev, &ss,
+										 ATOM_DP_SS_ID1);
 			}
 			break;
 		case ATOM_ENCODER_MODE_LVDS:
@@ -974,7 +1015,7 @@
 
 	atombios_crtc_program_pll(crtc, radeon_crtc->crtc_id, radeon_crtc->pll_id,
 				  encoder_mode, radeon_encoder->encoder_id, mode->clock,
-				  ref_div, fb_div, frac_fb_div, post_div);
+				  ref_div, fb_div, frac_fb_div, post_div, bpc, ss_enabled, &ss);
 
 	if (ss_enabled) {
 		/* calculate ss amount and step size */
@@ -982,7 +1023,7 @@
 			u32 step_size;
 			u32 amount = (((fb_div * 10) + frac_fb_div) * ss.percentage) / 10000;
 			ss.amount = (amount / 10) & ATOM_PPLL_SS_AMOUNT_V2_FBDIV_MASK;
-			ss.amount |= ((amount - (ss.amount * 10)) << ATOM_PPLL_SS_AMOUNT_V2_NFRAC_SHIFT) &
+			ss.amount |= ((amount - (amount / 10)) << ATOM_PPLL_SS_AMOUNT_V2_NFRAC_SHIFT) &
 				ATOM_PPLL_SS_AMOUNT_V2_NFRAC_MASK;
 			if (ss.type & ATOM_PPLL_SS_TYPE_V2_CENTRE_SPREAD)
 				step_size = (4 * amount * ref_div * (ss.rate * 2048)) /
@@ -1011,7 +1052,7 @@
 	uint64_t fb_location;
 	uint32_t fb_format, fb_pitch_pixels, tiling_flags;
 	u32 fb_swap = EVERGREEN_GRPH_ENDIAN_SWAP(EVERGREEN_GRPH_ENDIAN_NONE);
-	u32 tmp;
+	u32 tmp, viewport_w, viewport_h;
 	int r;
 
 	/* no fb bound */
@@ -1137,8 +1178,10 @@
 	y &= ~1;
 	WREG32(EVERGREEN_VIEWPORT_START + radeon_crtc->crtc_offset,
 	       (x << 16) | y);
+	viewport_w = crtc->mode.hdisplay;
+	viewport_h = (crtc->mode.vdisplay + 1) & ~1;
 	WREG32(EVERGREEN_VIEWPORT_SIZE + radeon_crtc->crtc_offset,
-	       (crtc->mode.hdisplay << 16) | crtc->mode.vdisplay);
+	       (viewport_w << 16) | viewport_h);
 
 	/* pageflip setup */
 	/* make sure flip is at vb rather than hb */
@@ -1179,7 +1222,7 @@
 	uint64_t fb_location;
 	uint32_t fb_format, fb_pitch_pixels, tiling_flags;
 	u32 fb_swap = R600_D1GRPH_SWAP_ENDIAN_NONE;
-	u32 tmp;
+	u32 tmp, viewport_w, viewport_h;
 	int r;
 
 	/* no fb bound */
@@ -1304,8 +1347,10 @@
 	y &= ~1;
 	WREG32(AVIVO_D1MODE_VIEWPORT_START + radeon_crtc->crtc_offset,
 	       (x << 16) | y);
+	viewport_w = crtc->mode.hdisplay;
+	viewport_h = (crtc->mode.vdisplay + 1) & ~1;
 	WREG32(AVIVO_D1MODE_VIEWPORT_SIZE + radeon_crtc->crtc_offset,
-	       (crtc->mode.hdisplay << 16) | crtc->mode.vdisplay);
+	       (viewport_w << 16) | viewport_h);
 
 	/* pageflip setup */
 	/* make sure flip is at vb rather than hb */
@@ -1395,11 +1440,19 @@
 	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)) {
+				/* in DP mode, the DP ref clock can come from PPLL, DCPLL, or ext clock,
+				 * depending on the asic:
+				 * DCE4: PPLL or ext clock
+				 * DCE5: DCPLL or ext clock
+				 *
+				 * Setting ATOM_PPLL_INVALID will cause SetPixelClock to skip
+				 * PPLL/DCPLL programming and only program the DP DTO for the
+				 * crtc virtual pixel clock.
+				 */
 				if (atombios_get_encoder_mode(test_encoder) == ATOM_ENCODER_MODE_DP) {
-					if (rdev->clock.dp_extclk)
+					if (ASIC_IS_DCE5(rdev) || rdev->clock.dp_extclk)
 						return ATOM_PPLL_INVALID;
 				}
 			}
@@ -1515,6 +1568,8 @@
 static void atombios_crtc_disable(struct drm_crtc *crtc)
 {
 	struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
+	struct radeon_atom_ss ss;
+
 	atombios_crtc_dpms(crtc, DRM_MODE_DPMS_OFF);
 
 	switch (radeon_crtc->pll_id) {
@@ -1522,7 +1577,7 @@
 	case ATOM_PPLL2:
 		/* disable the ppll */
 		atombios_crtc_program_pll(crtc, radeon_crtc->crtc_id, radeon_crtc->pll_id,
-					  0, 0, ATOM_DISABLE, 0, 0, 0, 0);
+					  0, 0, ATOM_DISABLE, 0, 0, 0, 0, 0, false, &ss);
 		break;
 	default:
 		break;
diff -druN linux-2.6.39-libre/drivers/gpu/drm/radeon/atombios_dp.c linux-3.0-rc7-libre/drivers/gpu/drm/radeon/atombios_dp.c
--- linux-2.6.39-libre/drivers/gpu/drm/radeon/atombios_dp.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/gpu/drm/radeon/atombios_dp.c	2011-07-11 19:51:52.000000000 -0400
@@ -43,158 +43,242 @@
         "0dB", "3.5dB", "6dB", "9.5dB"
 };
 
-static const int dp_clocks[] = {
-	54000,  /* 1 lane, 1.62 Ghz */
-	90000,  /* 1 lane, 2.70 Ghz */
-	108000, /* 2 lane, 1.62 Ghz */
-	180000, /* 2 lane, 2.70 Ghz */
-	216000, /* 4 lane, 1.62 Ghz */
-	360000, /* 4 lane, 2.70 Ghz */
+/***** radeon AUX functions *****/
+union aux_channel_transaction {
+	PROCESS_AUX_CHANNEL_TRANSACTION_PS_ALLOCATION v1;
+	PROCESS_AUX_CHANNEL_TRANSACTION_PARAMETERS_V2 v2;
 };
 
-static const int num_dp_clocks = sizeof(dp_clocks) / sizeof(int);
+static int radeon_process_aux_ch(struct radeon_i2c_chan *chan,
+				 u8 *send, int send_bytes,
+				 u8 *recv, int recv_size,
+				 u8 delay, u8 *ack)
+{
+	struct drm_device *dev = chan->dev;
+	struct radeon_device *rdev = dev->dev_private;
+	union aux_channel_transaction args;
+	int index = GetIndexIntoMasterTable(COMMAND, ProcessAuxChannelTransaction);
+	unsigned char *base;
+	int recv_bytes;
 
-/* common helper functions */
-static int dp_lanes_for_mode_clock(u8 dpcd[DP_DPCD_SIZE], int mode_clock)
+	memset(&args, 0, sizeof(args));
+
+	base = (unsigned char *)rdev->mode_info.atom_context->scratch;
+
+	memcpy(base, send, send_bytes);
+
+	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;
+
+	atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
+
+	*ack = args.v1.ucReplyStatus;
+
+	/* timeout */
+	if (args.v1.ucReplyStatus == 1) {
+		DRM_DEBUG_KMS("dp_aux_ch timeout\n");
+		return -ETIMEDOUT;
+	}
+
+	/* flags not zero */
+	if (args.v1.ucReplyStatus == 2) {
+		DRM_DEBUG_KMS("dp_aux_ch flags not zero\n");
+		return -EBUSY;
+	}
+
+	/* error */
+	if (args.v1.ucReplyStatus == 3) {
+		DRM_DEBUG_KMS("dp_aux_ch error\n");
+		return -EIO;
+	}
+
+	recv_bytes = args.v1.ucDataOutLen;
+	if (recv_bytes > recv_size)
+		recv_bytes = recv_size;
+
+	if (recv && recv_size)
+		memcpy(recv, base + 16, recv_bytes);
+
+	return recv_bytes;
+}
+
+static int radeon_dp_aux_native_write(struct radeon_connector *radeon_connector,
+				      u16 address, u8 *send, u8 send_bytes, u8 delay)
 {
-	int i;
-	u8 max_link_bw;
-	u8 max_lane_count;
+	struct radeon_connector_atom_dig *dig_connector = radeon_connector->con_priv;
+	int ret;
+	u8 msg[20];
+	int msg_bytes = send_bytes + 4;
+	u8 ack;
 
-	if (!dpcd)
-		return 0;
+	if (send_bytes > 16)
+		return -1;
 
-	max_link_bw = dpcd[DP_MAX_LINK_RATE];
-	max_lane_count = dpcd[DP_MAX_LANE_COUNT] & DP_MAX_LANE_COUNT_MASK;
+	msg[0] = address;
+	msg[1] = address >> 8;
+	msg[2] = AUX_NATIVE_WRITE << 4;
+	msg[3] = (msg_bytes << 4) | (send_bytes - 1);
+	memcpy(&msg[4], send, send_bytes);
 
-	switch (max_link_bw) {
-	case DP_LINK_BW_1_62:
-	default:
-		for (i = 0; i < num_dp_clocks; i++) {
-			if (i % 2)
-				continue;
-			switch (max_lane_count) {
-			case 1:
-				if (i > 1)
-					return 0;
-				break;
-			case 2:
-				if (i > 3)
-					return 0;
-				break;
-			case 4:
-			default:
-				break;
-			}
-			if (dp_clocks[i] > mode_clock) {
-				if (i < 2)
-					return 1;
-				else if (i < 4)
-					return 2;
-				else
-					return 4;
-			}
-		}
-		break;
-	case DP_LINK_BW_2_7:
-		for (i = 0; i < num_dp_clocks; i++) {
-			switch (max_lane_count) {
-			case 1:
-				if (i > 1)
-					return 0;
-				break;
-			case 2:
-				if (i > 3)
-					return 0;
-				break;
-			case 4:
-			default:
-				break;
-			}
-			if (dp_clocks[i] > mode_clock) {
-				if (i < 2)
-					return 1;
-				else if (i < 4)
-					return 2;
-				else
-					return 4;
-			}
-		}
-		break;
+	while (1) {
+		ret = radeon_process_aux_ch(dig_connector->dp_i2c_bus,
+					    msg, msg_bytes, NULL, 0, delay, &ack);
+		if (ret < 0)
+			return ret;
+		if ((ack & AUX_NATIVE_REPLY_MASK) == AUX_NATIVE_REPLY_ACK)
+			break;
+		else if ((ack & AUX_NATIVE_REPLY_MASK) == AUX_NATIVE_REPLY_DEFER)
+			udelay(400);
+		else
+			return -EIO;
 	}
 
-	return 0;
+	return send_bytes;
 }
 
-static int dp_link_clock_for_mode_clock(u8 dpcd[DP_DPCD_SIZE], int mode_clock)
+static int radeon_dp_aux_native_read(struct radeon_connector *radeon_connector,
+				     u16 address, u8 *recv, int recv_bytes, u8 delay)
 {
-	int i;
-	u8 max_link_bw;
-	u8 max_lane_count;
+	struct radeon_connector_atom_dig *dig_connector = radeon_connector->con_priv;
+	u8 msg[4];
+	int msg_bytes = 4;
+	u8 ack;
+	int ret;
 
-	if (!dpcd)
-		return 0;
+	msg[0] = address;
+	msg[1] = address >> 8;
+	msg[2] = AUX_NATIVE_READ << 4;
+	msg[3] = (msg_bytes << 4) | (recv_bytes - 1);
 
-	max_link_bw = dpcd[DP_MAX_LINK_RATE];
-	max_lane_count = dpcd[DP_MAX_LANE_COUNT] & DP_MAX_LANE_COUNT_MASK;
+	while (1) {
+		ret = radeon_process_aux_ch(dig_connector->dp_i2c_bus,
+					    msg, msg_bytes, recv, recv_bytes, delay, &ack);
+		if (ret == 0)
+			return -EPROTO;
+		if (ret < 0)
+			return ret;
+		if ((ack & AUX_NATIVE_REPLY_MASK) == AUX_NATIVE_REPLY_ACK)
+			return ret;
+		else if ((ack & AUX_NATIVE_REPLY_MASK) == AUX_NATIVE_REPLY_DEFER)
+			udelay(400);
+		else
+			return -EIO;
+	}
+}
 
-	switch (max_link_bw) {
-	case DP_LINK_BW_1_62:
+static void radeon_write_dpcd_reg(struct radeon_connector *radeon_connector,
+				 u16 reg, u8 val)
+{
+	radeon_dp_aux_native_write(radeon_connector, reg, &val, 1, 0);
+}
+
+static u8 radeon_read_dpcd_reg(struct radeon_connector *radeon_connector,
+			       u16 reg)
+{
+	u8 val = 0;
+
+	radeon_dp_aux_native_read(radeon_connector, reg, &val, 1, 0);
+
+	return val;
+}
+
+int radeon_dp_i2c_aux_ch(struct i2c_adapter *adapter, int mode,
+			 u8 write_byte, u8 *read_byte)
+{
+	struct i2c_algo_dp_aux_data *algo_data = adapter->algo_data;
+	struct radeon_i2c_chan *auxch = (struct radeon_i2c_chan *)adapter;
+	u16 address = algo_data->address;
+	u8 msg[5];
+	u8 reply[2];
+	unsigned retry;
+	int msg_bytes;
+	int reply_bytes = 1;
+	int ret;
+	u8 ack;
+
+	/* Set up the command byte */
+	if (mode & MODE_I2C_READ)
+		msg[2] = AUX_I2C_READ << 4;
+	else
+		msg[2] = AUX_I2C_WRITE << 4;
+
+	if (!(mode & MODE_I2C_STOP))
+		msg[2] |= AUX_I2C_MOT << 4;
+
+	msg[0] = address;
+	msg[1] = address >> 8;
+
+	switch (mode) {
+	case MODE_I2C_WRITE:
+		msg_bytes = 5;
+		msg[3] = msg_bytes << 4;
+		msg[4] = write_byte;
+		break;
+	case MODE_I2C_READ:
+		msg_bytes = 4;
+		msg[3] = msg_bytes << 4;
+		break;
 	default:
-		for (i = 0; i < num_dp_clocks; i++) {
-			if (i % 2)
-				continue;
-			switch (max_lane_count) {
-			case 1:
-				if (i > 1)
-					return 0;
-				break;
-			case 2:
-				if (i > 3)
-					return 0;
-				break;
-			case 4:
-			default:
-				break;
-			}
-			if (dp_clocks[i] > mode_clock)
-				return 162000;
-		}
+		msg_bytes = 4;
+		msg[3] = 3 << 4;
 		break;
-	case DP_LINK_BW_2_7:
-		for (i = 0; i < num_dp_clocks; i++) {
-			switch (max_lane_count) {
-			case 1:
-				if (i > 1)
-					return 0;
-				break;
-			case 2:
-				if (i > 3)
-					return 0;
-				break;
-			case 4:
-			default:
-				break;
-			}
-			if (dp_clocks[i] > mode_clock)
-				return (i % 2) ? 270000 : 162000;
-		}
 	}
 
-	return 0;
-}
+	for (retry = 0; retry < 4; retry++) {
+		ret = radeon_process_aux_ch(auxch,
+					    msg, msg_bytes, reply, reply_bytes, 0, &ack);
+		if (ret < 0) {
+			DRM_DEBUG_KMS("aux_ch failed %d\n", ret);
+			return ret;
+		}
 
-int dp_mode_valid(u8 dpcd[DP_DPCD_SIZE], int mode_clock)
-{
-	int lanes = dp_lanes_for_mode_clock(dpcd, mode_clock);
-	int dp_clock = dp_link_clock_for_mode_clock(dpcd, mode_clock);
+		switch (ack & AUX_NATIVE_REPLY_MASK) {
+		case AUX_NATIVE_REPLY_ACK:
+			/* I2C-over-AUX Reply field is only valid
+			 * when paired with AUX ACK.
+			 */
+			break;
+		case AUX_NATIVE_REPLY_NACK:
+			DRM_DEBUG_KMS("aux_ch native nack\n");
+			return -EREMOTEIO;
+		case AUX_NATIVE_REPLY_DEFER:
+			DRM_DEBUG_KMS("aux_ch native defer\n");
+			udelay(400);
+			continue;
+		default:
+			DRM_ERROR("aux_ch invalid native reply 0x%02x\n", ack);
+			return -EREMOTEIO;
+		}
 
-	if ((lanes == 0) || (dp_clock == 0))
-		return MODE_CLOCK_HIGH;
+		switch (ack & AUX_I2C_REPLY_MASK) {
+		case AUX_I2C_REPLY_ACK:
+			if (mode == MODE_I2C_READ)
+				*read_byte = reply[0];
+			return ret;
+		case AUX_I2C_REPLY_NACK:
+			DRM_DEBUG_KMS("aux_i2c nack\n");
+			return -EREMOTEIO;
+		case AUX_I2C_REPLY_DEFER:
+			DRM_DEBUG_KMS("aux_i2c defer\n");
+			udelay(400);
+			break;
+		default:
+			DRM_ERROR("aux_i2c invalid reply 0x%02x\n", ack);
+			return -EREMOTEIO;
+		}
+	}
 
-	return MODE_OK;
+	DRM_ERROR("aux i2c too many retries, giving up\n");
+	return -EREMOTEIO;
 }
 
+/***** general DP utility functions *****/
+
 static u8 dp_link_status(u8 link_status[DP_LINK_STATUS_SIZE], int r)
 {
 	return link_status[r - DP_LANE0_1_STATUS];
@@ -242,7 +326,7 @@
 	return true;
 }
 
-static u8 dp_get_adjust_request_voltage(uint8_t link_status[DP_LINK_STATUS_SIZE],
+static u8 dp_get_adjust_request_voltage(u8 link_status[DP_LINK_STATUS_SIZE],
 					int lane)
 
 {
@@ -255,7 +339,7 @@
 	return ((l >> s) & 0x3) << DP_TRAIN_VOLTAGE_SWING_SHIFT;
 }
 
-static u8 dp_get_adjust_request_pre_emphasis(uint8_t link_status[DP_LINK_STATUS_SIZE],
+static u8 dp_get_adjust_request_pre_emphasis(u8 link_status[DP_LINK_STATUS_SIZE],
 					     int lane)
 {
 	int i = DP_ADJUST_REQUEST_LANE0_1 + (lane >> 1);
@@ -267,22 +351,8 @@
 	return ((l >> s) & 0x3) << DP_TRAIN_PRE_EMPHASIS_SHIFT;
 }
 
-/* XXX fix me -- chip specific */
 #define DP_VOLTAGE_MAX         DP_TRAIN_VOLTAGE_SWING_1200
-static u8 dp_pre_emphasis_max(u8 voltage_swing)
-{
-	switch (voltage_swing & DP_TRAIN_VOLTAGE_SWING_MASK) {
-	case DP_TRAIN_VOLTAGE_SWING_400:
-		return DP_TRAIN_PRE_EMPHASIS_6;
-	case DP_TRAIN_VOLTAGE_SWING_600:
-		return DP_TRAIN_PRE_EMPHASIS_6;
-	case DP_TRAIN_VOLTAGE_SWING_800:
-		return DP_TRAIN_PRE_EMPHASIS_3_5;
-	case DP_TRAIN_VOLTAGE_SWING_1200:
-	default:
-		return DP_TRAIN_PRE_EMPHASIS_0;
-	}
-}
+#define DP_PRE_EMPHASIS_MAX    DP_TRAIN_PRE_EMPHASIS_9_5
 
 static void dp_get_adjust_train(u8 link_status[DP_LINK_STATUS_SIZE],
 				int lane_count,
@@ -308,10 +378,10 @@
 	}
 
 	if (v >= DP_VOLTAGE_MAX)
-		v = DP_VOLTAGE_MAX | DP_TRAIN_MAX_SWING_REACHED;
+		v |= DP_TRAIN_MAX_SWING_REACHED;
 
-	if (p >= dp_pre_emphasis_max(v))
-		p = dp_pre_emphasis_max(v) | DP_TRAIN_MAX_PRE_EMPHASIS_REACHED;
+	if (p >= DP_PRE_EMPHASIS_MAX)
+		p |= DP_TRAIN_MAX_PRE_EMPHASIS_REACHED;
 
 	DRM_DEBUG_KMS("using signal parameters: voltage %s pre_emph %s\n",
 		  voltage_names[(v & DP_TRAIN_VOLTAGE_SWING_MASK) >> DP_TRAIN_VOLTAGE_SWING_SHIFT],
@@ -321,110 +391,109 @@
 		train_set[lane] = v | p;
 }
 
-union aux_channel_transaction {
-	PROCESS_AUX_CHANNEL_TRANSACTION_PS_ALLOCATION v1;
-	PROCESS_AUX_CHANNEL_TRANSACTION_PARAMETERS_V2 v2;
-};
+/* convert bits per color to bits per pixel */
+/* get bpc from the EDID */
+static int convert_bpc_to_bpp(int bpc)
+{
+	if (bpc == 0)
+		return 24;
+	else
+		return bpc * 3;
+}
 
-/* radeon aux chan functions */
-bool radeon_process_aux_ch(struct radeon_i2c_chan *chan, u8 *req_bytes,
-			   int num_bytes, u8 *read_byte,
-			   u8 read_buf_len, u8 delay)
+/* get the max pix clock supported by the link rate and lane num */
+static int dp_get_max_dp_pix_clock(int link_rate,
+				   int lane_num,
+				   int bpp)
 {
-	struct drm_device *dev = chan->dev;
-	struct radeon_device *rdev = dev->dev_private;
-	union aux_channel_transaction args;
-	int index = GetIndexIntoMasterTable(COMMAND, ProcessAuxChannelTransaction);
-	unsigned char *base;
-	int retry_count = 0;
+	return (link_rate * lane_num * 8) / bpp;
+}
 
-	memset(&args, 0, sizeof(args));
+static int dp_get_max_link_rate(u8 dpcd[DP_DPCD_SIZE])
+{
+	switch (dpcd[DP_MAX_LINK_RATE]) {
+	case DP_LINK_BW_1_62:
+	default:
+		return 162000;
+	case DP_LINK_BW_2_7:
+		return 270000;
+	case DP_LINK_BW_5_4:
+		return 540000;
+	}
+}
 
-	base = (unsigned char *)rdev->mode_info.atom_context->scratch;
+static u8 dp_get_max_lane_number(u8 dpcd[DP_DPCD_SIZE])
+{
+	return dpcd[DP_MAX_LANE_COUNT] & DP_MAX_LANE_COUNT_MASK;
+}
 
-retry:
-	memcpy(base, req_bytes, num_bytes);
+static u8 dp_get_dp_link_rate_coded(int link_rate)
+{
+	switch (link_rate) {
+	case 162000:
+	default:
+		return DP_LINK_BW_1_62;
+	case 270000:
+		return DP_LINK_BW_2_7;
+	case 540000:
+		return DP_LINK_BW_5_4;
+	}
+}
 
-	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;
+/***** radeon specific DP functions *****/
 
-	atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
+/* First get the min lane# when low rate is used according to pixel clock
+ * (prefer low rate), second check max lane# supported by DP panel,
+ * if the max lane# < low rate lane# then use max lane# instead.
+ */
+static int radeon_dp_get_dp_lane_number(struct drm_connector *connector,
+					u8 dpcd[DP_DPCD_SIZE],
+					int pix_clock)
+{
+	int bpp = convert_bpc_to_bpp(connector->display_info.bpc);
+	int max_link_rate = dp_get_max_link_rate(dpcd);
+	int max_lane_num = dp_get_max_lane_number(dpcd);
+	int lane_num;
+	int max_dp_pix_clock;
 
-	if (args.v1.ucReplyStatus && !args.v1.ucDataOutLen) {
-		if (args.v1.ucReplyStatus == 0x20 && retry_count++ < 10)
-			goto retry;
-		DRM_DEBUG_KMS("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.v1.ucReplyStatus, retry_count);
-		return false;
+	for (lane_num = 1; lane_num < max_lane_num; lane_num <<= 1) {
+		max_dp_pix_clock = dp_get_max_dp_pix_clock(max_link_rate, lane_num, bpp);
+		if (pix_clock <= max_dp_pix_clock)
+			break;
 	}
 
-	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.v1.ucDataOutLen);
-			return false;
-		}
-		{
-			int len = min(read_buf_len, args.v1.ucDataOutLen);
-			memcpy(read_byte, base + 16, len);
-		}
-	}
-	return true;
+	return lane_num;
 }
 
-bool radeon_dp_aux_native_write(struct radeon_connector *radeon_connector, uint16_t address,
-				uint8_t send_bytes, uint8_t *send)
+static int radeon_dp_get_dp_link_clock(struct drm_connector *connector,
+				       u8 dpcd[DP_DPCD_SIZE],
+				       int pix_clock)
 {
-	struct radeon_connector_atom_dig *dig_connector = radeon_connector->con_priv;
-	u8 msg[20];
-	u8 msg_len, dp_msg_len;
-	bool ret;
-
-	dp_msg_len = 4;
-	msg[0] = address;
-	msg[1] = address >> 8;
-	msg[2] = AUX_NATIVE_WRITE << 4;
-	dp_msg_len += send_bytes;
-	msg[3] = (dp_msg_len << 4) | (send_bytes - 1);
-
-	if (send_bytes > 16)
-		return false;
+	int bpp = convert_bpc_to_bpp(connector->display_info.bpc);
+	int lane_num, max_pix_clock;
 
-	memcpy(&msg[4], send, send_bytes);
-	msg_len = 4 + send_bytes;
-	ret = radeon_process_aux_ch(dig_connector->dp_i2c_bus, msg, msg_len, NULL, 0, 0);
-	return ret;
-}
+	if (radeon_connector_encoder_is_dp_bridge(connector))
+		return 270000;
 
-bool radeon_dp_aux_native_read(struct radeon_connector *radeon_connector, uint16_t address,
-			       uint8_t delay, uint8_t expected_bytes,
-			       uint8_t *read_p)
-{
-	struct radeon_connector_atom_dig *dig_connector = radeon_connector->con_priv;
-	u8 msg[20];
-	u8 msg_len, dp_msg_len;
-	bool ret = false;
-	msg_len = 4;
-	dp_msg_len = 4;
-	msg[0] = address;
-	msg[1] = address >> 8;
-	msg[2] = AUX_NATIVE_READ << 4;
-	msg[3] = (dp_msg_len) << 4;
-	msg[3] |= expected_bytes - 1;
+	lane_num = radeon_dp_get_dp_lane_number(connector, dpcd, pix_clock);
+	max_pix_clock = dp_get_max_dp_pix_clock(162000, lane_num, bpp);
+	if (pix_clock <= max_pix_clock)
+		return 162000;
+	max_pix_clock = dp_get_max_dp_pix_clock(270000, lane_num, bpp);
+	if (pix_clock <= max_pix_clock)
+		return 270000;
+	if (radeon_connector_is_dp12_capable(connector)) {
+		max_pix_clock = dp_get_max_dp_pix_clock(540000, lane_num, bpp);
+		if (pix_clock <= max_pix_clock)
+			return 540000;
+	}
 
-	ret = radeon_process_aux_ch(dig_connector->dp_i2c_bus, msg, msg_len, read_p, expected_bytes, delay);
-	return ret;
+	return dp_get_max_link_rate(dpcd);
 }
 
-/* radeon dp functions */
-static u8 radeon_dp_encoder_service(struct radeon_device *rdev, int action, int dp_clock,
-				    uint8_t ucconfig, uint8_t lane_num)
+static u8 radeon_dp_encoder_service(struct radeon_device *rdev,
+				    int action, int dp_clock,
+				    u8 ucconfig, u8 lane_num)
 {
 	DP_ENCODER_SERVICE_PARAMETERS args;
 	int index = GetIndexIntoMasterTable(COMMAND, DPEncoderService);
@@ -454,60 +523,86 @@
 {
 	struct radeon_connector_atom_dig *dig_connector = radeon_connector->con_priv;
 	u8 msg[25];
-	int ret;
+	int ret, i;
 
-	ret = radeon_dp_aux_native_read(radeon_connector, DP_DPCD_REV, 0, 8, msg);
-	if (ret) {
+	ret = radeon_dp_aux_native_read(radeon_connector, DP_DPCD_REV, msg, 8, 0);
+	if (ret > 0) {
 		memcpy(dig_connector->dpcd, msg, 8);
-		{
-			int i;
-			DRM_DEBUG_KMS("DPCD: ");
-			for (i = 0; i < 8; i++)
-				DRM_DEBUG_KMS("%02x ", msg[i]);
-			DRM_DEBUG_KMS("\n");
-		}
+		DRM_DEBUG_KMS("DPCD: ");
+		for (i = 0; i < 8; i++)
+			DRM_DEBUG_KMS("%02x ", msg[i]);
+		DRM_DEBUG_KMS("\n");
 		return true;
 	}
 	dig_connector->dpcd[0] = 0;
 	return false;
 }
 
+static void radeon_dp_set_panel_mode(struct drm_encoder *encoder,
+				     struct drm_connector *connector)
+{
+	struct drm_device *dev = encoder->dev;
+	struct radeon_device *rdev = dev->dev_private;
+	int panel_mode = DP_PANEL_MODE_EXTERNAL_DP_MODE;
+
+	if (!ASIC_IS_DCE4(rdev))
+		return;
+
+	if (radeon_connector_encoder_is_dp_bridge(connector))
+		panel_mode = DP_PANEL_MODE_INTERNAL_DP1_MODE;
+
+	atombios_dig_encoder_setup(encoder,
+				   ATOM_ENCODER_CMD_SETUP_PANEL_MODE,
+				   panel_mode);
+}
+
 void radeon_dp_set_link_config(struct drm_connector *connector,
 			       struct drm_display_mode *mode)
 {
-	struct radeon_connector *radeon_connector;
+	struct radeon_connector *radeon_connector = to_radeon_connector(connector);
 	struct radeon_connector_atom_dig *dig_connector;
 
-	if ((connector->connector_type != DRM_MODE_CONNECTOR_DisplayPort) &&
-	    (connector->connector_type != DRM_MODE_CONNECTOR_eDP))
-		return;
-
-	radeon_connector = to_radeon_connector(connector);
 	if (!radeon_connector->con_priv)
 		return;
 	dig_connector = radeon_connector->con_priv;
 
-	dig_connector->dp_clock =
-		dp_link_clock_for_mode_clock(dig_connector->dpcd, mode->clock);
-	dig_connector->dp_lane_count =
-		dp_lanes_for_mode_clock(dig_connector->dpcd, mode->clock);
+	if ((dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) ||
+	    (dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_eDP)) {
+		dig_connector->dp_clock =
+			radeon_dp_get_dp_link_clock(connector, dig_connector->dpcd, mode->clock);
+		dig_connector->dp_lane_count =
+			radeon_dp_get_dp_lane_number(connector, dig_connector->dpcd, mode->clock);
+	}
 }
 
-int radeon_dp_mode_valid_helper(struct radeon_connector *radeon_connector,
+int radeon_dp_mode_valid_helper(struct drm_connector *connector,
 				struct drm_display_mode *mode)
 {
-	struct radeon_connector_atom_dig *dig_connector = radeon_connector->con_priv;
+	struct radeon_connector *radeon_connector = to_radeon_connector(connector);
+	struct radeon_connector_atom_dig *dig_connector;
+	int dp_clock;
 
-	return dp_mode_valid(dig_connector->dpcd, mode->clock);
+	if (!radeon_connector->con_priv)
+		return MODE_CLOCK_HIGH;
+	dig_connector = radeon_connector->con_priv;
+
+	dp_clock =
+		radeon_dp_get_dp_link_clock(connector, dig_connector->dpcd, mode->clock);
+
+	if ((dp_clock == 540000) &&
+	    (!radeon_connector_is_dp12_capable(connector)))
+		return MODE_CLOCK_HIGH;
+
+	return MODE_OK;
 }
 
-static bool atom_dp_get_link_status(struct radeon_connector *radeon_connector,
-				    u8 link_status[DP_LINK_STATUS_SIZE])
+static bool radeon_dp_get_link_status(struct radeon_connector *radeon_connector,
+				      u8 link_status[DP_LINK_STATUS_SIZE])
 {
 	int ret;
-	ret = radeon_dp_aux_native_read(radeon_connector, DP_LANE0_1_STATUS, 100,
-					DP_LINK_STATUS_SIZE, link_status);
-	if (!ret) {
+	ret = radeon_dp_aux_native_read(radeon_connector, DP_LANE0_1_STATUS,
+					link_status, DP_LINK_STATUS_SIZE, 100);
+	if (ret <= 0) {
 		DRM_ERROR("displayport link status failed\n");
 		return false;
 	}
@@ -518,292 +613,309 @@
 	return true;
 }
 
-bool radeon_dp_needs_link_train(struct radeon_connector *radeon_connector)
-{
-	struct radeon_connector_atom_dig *dig_connector = radeon_connector->con_priv;
+struct radeon_dp_link_train_info {
+	struct radeon_device *rdev;
+	struct drm_encoder *encoder;
+	struct drm_connector *connector;
+	struct radeon_connector *radeon_connector;
+	int enc_id;
+	int dp_clock;
+	int dp_lane_count;
+	int rd_interval;
+	bool tp3_supported;
+	u8 dpcd[8];
+	u8 train_set[4];
 	u8 link_status[DP_LINK_STATUS_SIZE];
+	u8 tries;
+};
 
-	if (!atom_dp_get_link_status(radeon_connector, link_status))
-		return false;
-	if (dp_channel_eq_ok(link_status, dig_connector->dp_lane_count))
-		return false;
-	return true;
+static void radeon_dp_update_vs_emph(struct radeon_dp_link_train_info *dp_info)
+{
+	/* set the initial vs/emph on the source */
+	atombios_dig_transmitter_setup(dp_info->encoder,
+				       ATOM_TRANSMITTER_ACTION_SETUP_VSEMPH,
+				       0, dp_info->train_set[0]); /* sets all lanes at once */
+
+	/* set the vs/emph on the sink */
+	radeon_dp_aux_native_write(dp_info->radeon_connector, DP_TRAINING_LANE0_SET,
+				   dp_info->train_set, dp_info->dp_lane_count, 0);
 }
 
-static void dp_set_power(struct radeon_connector *radeon_connector, u8 power_state)
+static void radeon_dp_set_tp(struct radeon_dp_link_train_info *dp_info, int tp)
 {
-	struct radeon_connector_atom_dig *dig_connector = radeon_connector->con_priv;
+	int rtp = 0;
 
-	if (dig_connector->dpcd[0] >= 0x11) {
-		radeon_dp_aux_native_write(radeon_connector, DP_SET_POWER, 1,
-					   &power_state);
+	/* set training pattern on the source */
+	if (ASIC_IS_DCE4(dp_info->rdev)) {
+		switch (tp) {
+		case DP_TRAINING_PATTERN_1:
+			rtp = ATOM_ENCODER_CMD_DP_LINK_TRAINING_PATTERN1;
+			break;
+		case DP_TRAINING_PATTERN_2:
+			rtp = ATOM_ENCODER_CMD_DP_LINK_TRAINING_PATTERN2;
+			break;
+		case DP_TRAINING_PATTERN_3:
+			rtp = ATOM_ENCODER_CMD_DP_LINK_TRAINING_PATTERN3;
+			break;
+		}
+		atombios_dig_encoder_setup(dp_info->encoder, rtp, 0);
+	} else {
+		switch (tp) {
+		case DP_TRAINING_PATTERN_1:
+			rtp = 0;
+			break;
+		case DP_TRAINING_PATTERN_2:
+			rtp = 1;
+			break;
+		}
+		radeon_dp_encoder_service(dp_info->rdev, ATOM_DP_ACTION_TRAINING_PATTERN_SEL,
+					  dp_info->dp_clock, dp_info->enc_id, rtp);
 	}
-}
 
-static void dp_set_downspread(struct radeon_connector *radeon_connector, u8 downspread)
-{
-	radeon_dp_aux_native_write(radeon_connector, DP_DOWNSPREAD_CTRL, 1,
-				   &downspread);
+	/* enable training pattern on the sink */
+	radeon_write_dpcd_reg(dp_info->radeon_connector, DP_TRAINING_PATTERN_SET, tp);
 }
 
-static void dp_set_link_bw_lanes(struct radeon_connector *radeon_connector,
-				 u8 link_configuration[DP_LINK_CONFIGURATION_SIZE])
+static int radeon_dp_link_train_init(struct radeon_dp_link_train_info *dp_info)
 {
-	radeon_dp_aux_native_write(radeon_connector, DP_LINK_BW_SET, 2,
-				   link_configuration);
-}
+	u8 tmp;
 
-static void dp_update_dpvs_emph(struct radeon_connector *radeon_connector,
-				struct drm_encoder *encoder,
-				u8 train_set[4])
-{
-	struct radeon_connector_atom_dig *dig_connector = radeon_connector->con_priv;
-	int i;
+	/* power up the sink */
+	if (dp_info->dpcd[0] >= 0x11)
+		radeon_write_dpcd_reg(dp_info->radeon_connector,
+				      DP_SET_POWER, DP_SET_POWER_D0);
 
-	for (i = 0; i < dig_connector->dp_lane_count; i++)
-		atombios_dig_transmitter_setup(encoder,
-					       ATOM_TRANSMITTER_ACTION_SETUP_VSEMPH,
-					       i, train_set[i]);
+	/* possibly enable downspread on the sink */
+	if (dp_info->dpcd[3] & 0x1)
+		radeon_write_dpcd_reg(dp_info->radeon_connector,
+				      DP_DOWNSPREAD_CTRL, DP_SPREAD_AMP_0_5);
+	else
+		radeon_write_dpcd_reg(dp_info->radeon_connector,
+				      DP_DOWNSPREAD_CTRL, 0);
 
-	radeon_dp_aux_native_write(radeon_connector, DP_TRAINING_LANE0_SET,
-				   dig_connector->dp_lane_count, train_set);
-}
+	radeon_dp_set_panel_mode(dp_info->encoder, dp_info->connector);
 
-static void dp_set_training(struct radeon_connector *radeon_connector,
-			    u8 training)
-{
-	radeon_dp_aux_native_write(radeon_connector, DP_TRAINING_PATTERN_SET,
-				   1, &training);
-}
+	/* set the lane count on the sink */
+	tmp = dp_info->dp_lane_count;
+	if (dp_info->dpcd[0] >= 0x11)
+		tmp |= DP_LANE_COUNT_ENHANCED_FRAME_EN;
+	radeon_write_dpcd_reg(dp_info->radeon_connector, DP_LANE_COUNT_SET, tmp);
 
-void dp_link_train(struct drm_encoder *encoder,
-		   struct drm_connector *connector)
-{
-	struct drm_device *dev = encoder->dev;
-	struct radeon_device *rdev = dev->dev_private;
-	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
-	struct radeon_encoder_atom_dig *dig;
-	struct radeon_connector *radeon_connector;
-	struct radeon_connector_atom_dig *dig_connector;
-	int enc_id = 0;
-	bool clock_recovery, channel_eq;
-	u8 link_status[DP_LINK_STATUS_SIZE];
-	u8 link_configuration[DP_LINK_CONFIGURATION_SIZE];
-	u8 tries, voltage;
-	u8 train_set[4];
-	int i;
+	/* set the link rate on the sink */
+	tmp = dp_get_dp_link_rate_coded(dp_info->dp_clock);
+	radeon_write_dpcd_reg(dp_info->radeon_connector, DP_LINK_BW_SET, tmp);
 
-	if ((connector->connector_type != DRM_MODE_CONNECTOR_DisplayPort) &&
-	    (connector->connector_type != DRM_MODE_CONNECTOR_eDP))
-		return;
+	/* start training on the source */
+	if (ASIC_IS_DCE4(dp_info->rdev))
+		atombios_dig_encoder_setup(dp_info->encoder,
+					   ATOM_ENCODER_CMD_DP_LINK_TRAINING_START, 0);
+	else
+		radeon_dp_encoder_service(dp_info->rdev, ATOM_DP_ACTION_TRAINING_START,
+					  dp_info->dp_clock, dp_info->enc_id, 0);
 
-	if (!radeon_encoder->enc_priv)
-		return;
-	dig = radeon_encoder->enc_priv;
+	/* disable the training pattern on the sink */
+	radeon_write_dpcd_reg(dp_info->radeon_connector,
+			      DP_TRAINING_PATTERN_SET,
+			      DP_TRAINING_PATTERN_DISABLE);
 
-	radeon_connector = to_radeon_connector(connector);
-	if (!radeon_connector->con_priv)
-		return;
-	dig_connector = radeon_connector->con_priv;
+	return 0;
+}
 
-	if (dig->dig_encoder)
-		enc_id |= ATOM_DP_CONFIG_DIG2_ENCODER;
-	else
-		enc_id |= ATOM_DP_CONFIG_DIG1_ENCODER;
-	if (dig->linkb)
-		enc_id |= ATOM_DP_CONFIG_LINK_B;
-	else
-		enc_id |= ATOM_DP_CONFIG_LINK_A;
+static int radeon_dp_link_train_finish(struct radeon_dp_link_train_info *dp_info)
+{
+	udelay(400);
 
-	memset(link_configuration, 0, DP_LINK_CONFIGURATION_SIZE);
-	if (dig_connector->dp_clock == 270000)
-		link_configuration[0] = DP_LINK_BW_2_7;
+	/* disable the training pattern on the sink */
+	radeon_write_dpcd_reg(dp_info->radeon_connector,
+			      DP_TRAINING_PATTERN_SET,
+			      DP_TRAINING_PATTERN_DISABLE);
+
+	/* disable the training pattern on the source */
+	if (ASIC_IS_DCE4(dp_info->rdev))
+		atombios_dig_encoder_setup(dp_info->encoder,
+					   ATOM_ENCODER_CMD_DP_LINK_TRAINING_COMPLETE, 0);
 	else
-		link_configuration[0] = DP_LINK_BW_1_62;
-	link_configuration[1] = dig_connector->dp_lane_count;
-	if (dig_connector->dpcd[0] >= 0x11)
-		link_configuration[1] |= DP_LANE_COUNT_ENHANCED_FRAME_EN;
+		radeon_dp_encoder_service(dp_info->rdev, ATOM_DP_ACTION_TRAINING_COMPLETE,
+					  dp_info->dp_clock, dp_info->enc_id, 0);
 
-	/* power up the sink */
-	dp_set_power(radeon_connector, DP_SET_POWER_D0);
-	/* disable the training pattern on the sink */
-	dp_set_training(radeon_connector, DP_TRAINING_PATTERN_DISABLE);
-	/* set link bw and lanes on the sink */
-	dp_set_link_bw_lanes(radeon_connector, link_configuration);
-	/* disable downspread on the sink */
-	dp_set_downspread(radeon_connector, 0);
-	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);
-	}
+	return 0;
+}
 
-	/* set initial vs/emph */
-	memset(train_set, 0, 4);
-	udelay(400);
-	/* set training pattern 1 on the sink */
-	dp_set_training(radeon_connector, DP_TRAINING_PATTERN_1);
+static int radeon_dp_link_train_cr(struct radeon_dp_link_train_info *dp_info)
+{
+	bool clock_recovery;
+ 	u8 voltage;
+	int i;
 
-	dp_update_dpvs_emph(radeon_connector, encoder, train_set);
+	radeon_dp_set_tp(dp_info, DP_TRAINING_PATTERN_1);
+	memset(dp_info->train_set, 0, 4);
+	radeon_dp_update_vs_emph(dp_info);
+
+	udelay(400);
 
 	/* clock recovery loop */
 	clock_recovery = false;
-	tries = 0;
+	dp_info->tries = 0;
 	voltage = 0xff;
-	for (;;) {
-		udelay(100);
-		if (!atom_dp_get_link_status(radeon_connector, link_status))
+	while (1) {
+		if (dp_info->rd_interval == 0)
+			udelay(100);
+		else
+			mdelay(dp_info->rd_interval * 4);
+
+		if (!radeon_dp_get_link_status(dp_info->radeon_connector, dp_info->link_status))
 			break;
 
-		if (dp_clock_recovery_ok(link_status, dig_connector->dp_lane_count)) {
+		if (dp_clock_recovery_ok(dp_info->link_status, dp_info->dp_lane_count)) {
 			clock_recovery = true;
 			break;
 		}
 
-		for (i = 0; i < dig_connector->dp_lane_count; i++) {
-			if ((train_set[i] & DP_TRAIN_MAX_SWING_REACHED) == 0)
+		for (i = 0; i < dp_info->dp_lane_count; i++) {
+			if ((dp_info->train_set[i] & DP_TRAIN_MAX_SWING_REACHED) == 0)
 				break;
 		}
-		if (i == dig_connector->dp_lane_count) {
+		if (i == dp_info->dp_lane_count) {
 			DRM_ERROR("clock recovery reached max voltage\n");
 			break;
 		}
 
-		if ((train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK) == voltage) {
-			++tries;
-			if (tries == 5) {
+		if ((dp_info->train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK) == voltage) {
+			++dp_info->tries;
+			if (dp_info->tries == 5) {
 				DRM_ERROR("clock recovery tried 5 times\n");
 				break;
 			}
 		} else
-			tries = 0;
+			dp_info->tries = 0;
 
-		voltage = train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK;
+		voltage = dp_info->train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK;
 
 		/* Compute new train_set as requested by sink */
-		dp_get_adjust_train(link_status, dig_connector->dp_lane_count, train_set);
-		dp_update_dpvs_emph(radeon_connector, encoder, train_set);
+		dp_get_adjust_train(dp_info->link_status, dp_info->dp_lane_count, dp_info->train_set);
+
+		radeon_dp_update_vs_emph(dp_info);
 	}
-	if (!clock_recovery)
+	if (!clock_recovery) {
 		DRM_ERROR("clock recovery failed\n");
-	else
+		return -1;
+	} else {
 		DRM_DEBUG_KMS("clock recovery at voltage %d pre-emphasis %d\n",
-			  train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK,
-			  (train_set[0] & DP_TRAIN_PRE_EMPHASIS_MASK) >>
+			  dp_info->train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK,
+			  (dp_info->train_set[0] & DP_TRAIN_PRE_EMPHASIS_MASK) >>
 			  DP_TRAIN_PRE_EMPHASIS_SHIFT);
+		return 0;
+	}
+}
 
+static int radeon_dp_link_train_ce(struct radeon_dp_link_train_info *dp_info)
+{
+	bool channel_eq;
 
-	/* set training pattern 2 on the sink */
-	dp_set_training(radeon_connector, DP_TRAINING_PATTERN_2);
-	/* set training pattern 2 on the source */
-	if (ASIC_IS_DCE4(rdev))
-		atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_DP_LINK_TRAINING_PATTERN2);
+	if (dp_info->tp3_supported)
+		radeon_dp_set_tp(dp_info, DP_TRAINING_PATTERN_3);
 	else
-		radeon_dp_encoder_service(rdev, ATOM_DP_ACTION_TRAINING_PATTERN_SEL,
-					  dig_connector->dp_clock, enc_id, 1);
+		radeon_dp_set_tp(dp_info, DP_TRAINING_PATTERN_2);
 
 	/* channel equalization loop */
-	tries = 0;
+	dp_info->tries = 0;
 	channel_eq = false;
-	for (;;) {
-		udelay(400);
-		if (!atom_dp_get_link_status(radeon_connector, link_status))
+	while (1) {
+		if (dp_info->rd_interval == 0)
+			udelay(400);
+		else
+			mdelay(dp_info->rd_interval * 4);
+
+		if (!radeon_dp_get_link_status(dp_info->radeon_connector, dp_info->link_status))
 			break;
 
-		if (dp_channel_eq_ok(link_status, dig_connector->dp_lane_count)) {
+		if (dp_channel_eq_ok(dp_info->link_status, dp_info->dp_lane_count)) {
 			channel_eq = true;
 			break;
 		}
 
 		/* Try 5 times */
-		if (tries > 5) {
+		if (dp_info->tries > 5) {
 			DRM_ERROR("channel eq failed: 5 tries\n");
 			break;
 		}
 
 		/* Compute new train_set as requested by sink */
-		dp_get_adjust_train(link_status, dig_connector->dp_lane_count, train_set);
-		dp_update_dpvs_emph(radeon_connector, encoder, train_set);
+		dp_get_adjust_train(dp_info->link_status, dp_info->dp_lane_count, dp_info->train_set);
 
-		tries++;
+		radeon_dp_update_vs_emph(dp_info);
+		dp_info->tries++;
 	}
 
-	if (!channel_eq)
+	if (!channel_eq) {
 		DRM_ERROR("channel eq failed\n");
-	else
+		return -1;
+	} else {
 		DRM_DEBUG_KMS("channel eq at voltage %d pre-emphasis %d\n",
-			  train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK,
-			  (train_set[0] & DP_TRAIN_PRE_EMPHASIS_MASK)
+			  dp_info->train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK,
+			  (dp_info->train_set[0] & DP_TRAIN_PRE_EMPHASIS_MASK)
 			  >> DP_TRAIN_PRE_EMPHASIS_SHIFT);
-
-	/* disable the training pattern on the sink */
-	dp_set_training(radeon_connector, DP_TRAINING_PATTERN_DISABLE);
-
-	/* 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);
+		return 0;
+	}
 }
 
-int radeon_dp_i2c_aux_ch(struct i2c_adapter *adapter, int mode,
-			 uint8_t write_byte, uint8_t *read_byte)
+void radeon_dp_link_train(struct drm_encoder *encoder,
+			  struct drm_connector *connector)
 {
-	struct i2c_algo_dp_aux_data *algo_data = adapter->algo_data;
-	struct radeon_i2c_chan *auxch = (struct radeon_i2c_chan *)adapter;
-	int ret = 0;
-	uint16_t address = algo_data->address;
-	uint8_t msg[5];
-	uint8_t reply[2];
-	int msg_len, dp_msg_len;
-	int reply_bytes;
+	struct drm_device *dev = encoder->dev;
+	struct radeon_device *rdev = dev->dev_private;
+	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
+	struct radeon_encoder_atom_dig *dig;
+	struct radeon_connector *radeon_connector;
+	struct radeon_connector_atom_dig *dig_connector;
+	struct radeon_dp_link_train_info dp_info;
+ 	u8 tmp;
 
-	/* Set up the command byte */
-	if (mode & MODE_I2C_READ)
-		msg[2] = AUX_I2C_READ << 4;
-	else
-		msg[2] = AUX_I2C_WRITE << 4;
+	if (!radeon_encoder->enc_priv)
+		return;
+	dig = radeon_encoder->enc_priv;
 
-	if (!(mode & MODE_I2C_STOP))
-		msg[2] |= AUX_I2C_MOT << 4;
+	radeon_connector = to_radeon_connector(connector);
+	if (!radeon_connector->con_priv)
+		return;
+	dig_connector = radeon_connector->con_priv;
 
-	msg[0] = address;
-	msg[1] = address >> 8;
+	if ((dig_connector->dp_sink_type != CONNECTOR_OBJECT_ID_DISPLAYPORT) &&
+	    (dig_connector->dp_sink_type != CONNECTOR_OBJECT_ID_eDP))
+		return;
 
-	reply_bytes = 1;
+	dp_info.enc_id = 0;
+	if (dig->dig_encoder)
+		dp_info.enc_id |= ATOM_DP_CONFIG_DIG2_ENCODER;
+	else
+		dp_info.enc_id |= ATOM_DP_CONFIG_DIG1_ENCODER;
+	if (dig->linkb)
+		dp_info.enc_id |= ATOM_DP_CONFIG_LINK_B;
+	else
+		dp_info.enc_id |= ATOM_DP_CONFIG_LINK_A;
 
-	msg_len = 4;
-	dp_msg_len = 3;
-	switch (mode) {
-	case MODE_I2C_WRITE:
-		msg[4] = write_byte;
-		msg_len++;
-		dp_msg_len += 2;
-		break;
-	case MODE_I2C_READ:
-		dp_msg_len += 1;
-		break;
-	default:
-		break;
-	}
+	dp_info.rd_interval = radeon_read_dpcd_reg(radeon_connector, DP_TRAINING_AUX_RD_INTERVAL);
+	tmp = radeon_read_dpcd_reg(radeon_connector, DP_MAX_LANE_COUNT);
+	if (ASIC_IS_DCE5(rdev) && (tmp & DP_TPS3_SUPPORTED))
+		dp_info.tp3_supported = true;
+	else
+		dp_info.tp3_supported = false;
 
-	msg[3] = (dp_msg_len) << 4;
-	ret = radeon_process_aux_ch(auxch, msg, msg_len, reply, reply_bytes, 0);
+	memcpy(dp_info.dpcd, dig_connector->dpcd, 8);
+	dp_info.rdev = rdev;
+	dp_info.encoder = encoder;
+	dp_info.connector = connector;
+	dp_info.radeon_connector = radeon_connector;
+	dp_info.dp_lane_count = dig_connector->dp_lane_count;
+	dp_info.dp_clock = dig_connector->dp_clock;
 
-	if (ret) {
-		if (read_byte)
-			*read_byte = reply[0];
-		return reply_bytes;
-	}
-	return -EREMOTEIO;
+	if (radeon_dp_link_train_init(&dp_info))
+		goto done;
+	if (radeon_dp_link_train_cr(&dp_info))
+		goto done;
+	if (radeon_dp_link_train_ce(&dp_info))
+		goto done;
+done:
+	if (radeon_dp_link_train_finish(&dp_info))
+		return;
 }
-
diff -druN linux-2.6.39-libre/drivers/gpu/drm/radeon/atombios.h linux-3.0-rc7-libre/drivers/gpu/drm/radeon/atombios.h
--- linux-2.6.39-libre/drivers/gpu/drm/radeon/atombios.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/gpu/drm/radeon/atombios.h	2011-07-11 19:51:52.000000000 -0400
@@ -726,6 +726,7 @@
 #define ATOM_ENCODER_CMD_DP_VIDEO_ON                  0x0d
 #define ATOM_ENCODER_CMD_QUERY_DP_LINK_TRAINING_STATUS    0x0e
 #define ATOM_ENCODER_CMD_SETUP                        0x0f
+#define ATOM_ENCODER_CMD_SETUP_PANEL_MODE             0x10
 
 // ucStatus
 #define ATOM_ENCODER_STATUS_LINK_TRAINING_COMPLETE    0x10
@@ -765,13 +766,19 @@
   USHORT usPixelClock;      // in 10KHz; for bios convenient
   ATOM_DIG_ENCODER_CONFIG_V3 acConfig;
   UCHAR ucAction;                              
-  UCHAR ucEncoderMode;
+  union {
+    UCHAR ucEncoderMode;
                             // =0: DP   encoder      
                             // =1: LVDS encoder          
                             // =2: DVI  encoder  
                             // =3: HDMI encoder
                             // =4: SDVO encoder
                             // =5: DP audio
+    UCHAR ucPanelMode;      // only valid when ucAction == ATOM_ENCODER_CMD_SETUP_PANEL_MODE
+	                    // =0:     external DP
+	                    // =1:     internal DP2
+	                    // =0x11:  internal DP1 for NutMeg/Travis DP translator
+  };
   UCHAR ucLaneNum;          // how many lanes to enable
   UCHAR ucBitPerColor;      // only valid for DP mode when ucAction = ATOM_ENCODER_CMD_SETUP
   UCHAR ucReserved;
@@ -816,13 +823,19 @@
   UCHAR ucConfig;
   };
   UCHAR ucAction;                              
-  UCHAR ucEncoderMode;
+  union {
+    UCHAR ucEncoderMode;
                             // =0: DP   encoder      
                             // =1: LVDS encoder          
                             // =2: DVI  encoder  
                             // =3: HDMI encoder
                             // =4: SDVO encoder
                             // =5: DP audio
+    UCHAR ucPanelMode;      // only valid when ucAction == ATOM_ENCODER_CMD_SETUP_PANEL_MODE
+	                    // =0:     external DP
+	                    // =1:     internal DP2
+	                    // =0x11:  internal DP1 for NutMeg/Travis DP translator
+  };
   UCHAR ucLaneNum;          // how many lanes to enable
   UCHAR ucBitPerColor;      // only valid for DP mode when ucAction = ATOM_ENCODER_CMD_SETUP
   UCHAR ucHPD_ID;           // HPD ID (1-6). =0 means to skip HDP programming. New comparing to previous version
@@ -836,6 +849,11 @@
 #define PANEL_12BIT_PER_COLOR                            0x04
 #define PANEL_16BIT_PER_COLOR                            0x05
 
+//define ucPanelMode
+#define DP_PANEL_MODE_EXTERNAL_DP_MODE                   0x00
+#define DP_PANEL_MODE_INTERNAL_DP2_MODE                  0x01
+#define DP_PANEL_MODE_INTERNAL_DP1_MODE                  0x11
+
 /****************************************************************************/	
 // Structures used by UNIPHYTransmitterControlTable
 //                    LVTMATransmitterControlTable
@@ -1182,6 +1200,7 @@
 #define EXTERNAL_ENCODER_ACTION_V3_ENCODER_BLANKING_OFF   0x10
 #define EXTERNAL_ENCODER_ACTION_V3_ENCODER_BLANKING       0x11
 #define EXTERNAL_ENCODER_ACTION_V3_DACLOAD_DETECTION      0x12
+#define EXTERNAL_ENCODER_ACTION_V3_DDC_SETUP              0x14
 
 // ucConfig
 #define EXTERNAL_ENCODER_CONFIG_V3_DPLINKRATE_MASK				0x03
diff -druN linux-2.6.39-libre/drivers/gpu/drm/radeon/atom.c linux-3.0-rc7-libre/drivers/gpu/drm/radeon/atom.c
--- linux-2.6.39-libre/drivers/gpu/drm/radeon/atom.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/gpu/drm/radeon/atom.c	2011-07-11 19:51:52.000000000 -0400
@@ -652,12 +652,12 @@
 
 static void atom_op_delay(atom_exec_context *ctx, int *ptr, int arg)
 {
-	uint8_t count = U8((*ptr)++);
+	unsigned count = U8((*ptr)++);
 	SDEBUG("   count: %d\n", count);
 	if (arg == ATOM_UNIT_MICROSEC)
 		udelay(count);
 	else
-		schedule_timeout_uninterruptible(msecs_to_jiffies(count));
+		msleep(count);
 }
 
 static void atom_op_div(atom_exec_context *ctx, int *ptr, int arg)
diff -druN linux-2.6.39-libre/drivers/gpu/drm/radeon/cayman_blit_shaders.c linux-3.0-rc7-libre/drivers/gpu/drm/radeon/cayman_blit_shaders.c
--- linux-2.6.39-libre/drivers/gpu/drm/radeon/cayman_blit_shaders.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/gpu/drm/radeon/cayman_blit_shaders.c	2011-07-11 19:51:52.000000000 -0400
@@ -39,17 +39,335 @@
 
 const u32 cayman_default_state[] =
 {
-	/* XXX fill in additional blit state */
+	0xc0066900,
+	0x00000000,
+	0x00000060, /* DB_RENDER_CONTROL */
+	0x00000000, /* DB_COUNT_CONTROL */
+	0x00000000, /* DB_DEPTH_VIEW */
+	0x0000002a, /* DB_RENDER_OVERRIDE */
+	0x00000000, /* DB_RENDER_OVERRIDE2 */
+	0x00000000, /* DB_HTILE_DATA_BASE */
 
 	0xc0026900,
-	0x00000316,
-	0x0000000e, /* VGT_VERTEX_REUSE_BLOCK_CNTL */
-	0x00000010, /*  */
+	0x0000000a,
+	0x00000000, /* DB_STENCIL_CLEAR */
+	0x00000000, /* DB_DEPTH_CLEAR */
+
+	0xc0036900,
+	0x0000000f,
+	0x00000000, /* DB_DEPTH_INFO */
+	0x00000000, /* DB_Z_INFO */
+	0x00000000, /* DB_STENCIL_INFO */
+
+	0xc0016900,
+	0x00000080,
+	0x00000000, /* PA_SC_WINDOW_OFFSET */
+
+	0xc00d6900,
+	0x00000083,
+	0x0000ffff, /* PA_SC_CLIPRECT_RULE */
+	0x00000000, /* PA_SC_CLIPRECT_0_TL */
+	0x20002000, /* PA_SC_CLIPRECT_0_BR */
+	0x00000000,
+	0x20002000,
+	0x00000000,
+	0x20002000,
+	0x00000000,
+	0x20002000,
+	0xaaaaaaaa, /* PA_SC_EDGERULE */
+	0x00000000, /* PA_SU_HARDWARE_SCREEN_OFFSET */
+	0x0000000f, /* CB_TARGET_MASK */
+	0x0000000f, /* CB_SHADER_MASK */
+
+	0xc0226900,
+	0x00000094,
+	0x80000000, /* PA_SC_VPORT_SCISSOR_0_TL */
+	0x20002000, /* PA_SC_VPORT_SCISSOR_0_BR */
+	0x80000000,
+	0x20002000,
+	0x80000000,
+	0x20002000,
+	0x80000000,
+	0x20002000,
+	0x80000000,
+	0x20002000,
+	0x80000000,
+	0x20002000,
+	0x80000000,
+	0x20002000,
+	0x80000000,
+	0x20002000,
+	0x80000000,
+	0x20002000,
+	0x80000000,
+	0x20002000,
+	0x80000000,
+	0x20002000,
+	0x80000000,
+	0x20002000,
+	0x80000000,
+	0x20002000,
+	0x80000000,
+	0x20002000,
+	0x80000000,
+	0x20002000,
+	0x80000000,
+	0x20002000,
+	0x00000000, /* PA_SC_VPORT_ZMIN_0 */
+	0x3f800000, /* PA_SC_VPORT_ZMAX_0 */
+
+	0xc0016900,
+	0x000000d4,
+	0x00000000, /* SX_MISC */
 
 	0xc0026900,
 	0x000000d9,
 	0x00000000, /* CP_RINGID */
 	0x00000000, /* CP_VMID */
+
+	0xc0096900,
+	0x00000100,
+	0x00ffffff, /* VGT_MAX_VTX_INDX */
+	0x00000000, /* VGT_MIN_VTX_INDX */
+	0x00000000, /* VGT_INDX_OFFSET */
+	0x00000000, /* VGT_MULTI_PRIM_IB_RESET_INDX */
+	0x00000000, /* SX_ALPHA_TEST_CONTROL */
+	0x00000000, /* CB_BLEND_RED */
+	0x00000000, /* CB_BLEND_GREEN */
+	0x00000000, /* CB_BLEND_BLUE */
+	0x00000000, /* CB_BLEND_ALPHA */
+
+	0xc0016900,
+	0x00000187,
+	0x00000100, /* SPI_VS_OUT_ID_0 */
+
+	0xc0026900,
+	0x00000191,
+	0x00000100, /* SPI_PS_INPUT_CNTL_0 */
+	0x00000101, /* SPI_PS_INPUT_CNTL_1 */
+
+	0xc0016900,
+	0x000001b1,
+	0x00000000, /* SPI_VS_OUT_CONFIG */
+
+	0xc0106900,
+	0x000001b3,
+	0x20000001, /* SPI_PS_IN_CONTROL_0 */
+	0x00000000, /* SPI_PS_IN_CONTROL_1 */
+	0x00000000, /* SPI_INTERP_CONTROL_0 */
+	0x00000000, /* SPI_INPUT_Z */
+	0x00000000, /* SPI_FOG_CNTL */
+	0x00100000, /* SPI_BARYC_CNTL */
+	0x00000000, /* SPI_PS_IN_CONTROL_2 */
+	0x00000000, /* SPI_COMPUTE_INPUT_CNTL */
+	0x00000000, /* SPI_COMPUTE_NUM_THREAD_X */
+	0x00000000, /* SPI_COMPUTE_NUM_THREAD_Y */
+	0x00000000, /* SPI_COMPUTE_NUM_THREAD_Z */
+	0x00000000, /* SPI_GPR_MGMT */
+	0x00000000, /* SPI_LDS_MGMT */
+	0x00000000, /* SPI_STACK_MGMT */
+	0x00000000, /* SPI_WAVE_MGMT_1 */
+	0x00000000, /* SPI_WAVE_MGMT_2 */
+
+	0xc0016900,
+	0x000001e0,
+	0x00000000, /* CB_BLEND0_CONTROL */
+
+	0xc00e6900,
+	0x00000200,
+	0x00000000, /* DB_DEPTH_CONTROL */
+	0x00000000, /* DB_EQAA */
+	0x00cc0010, /* CB_COLOR_CONTROL */
+	0x00000210, /* DB_SHADER_CONTROL */
+	0x00010000, /* PA_CL_CLIP_CNTL */
+	0x00000004, /* PA_SU_SC_MODE_CNTL */
+	0x00000100, /* PA_CL_VTE_CNTL */
+	0x00000000, /* PA_CL_VS_OUT_CNTL */
+	0x00000000, /* PA_CL_NANINF_CNTL */
+	0x00000000, /* PA_SU_LINE_STIPPLE_CNTL */
+	0x00000000, /* PA_SU_LINE_STIPPLE_SCALE */
+	0x00000000, /* PA_SU_PRIM_FILTER_CNTL */
+	0x00000000, /*  */
+	0x00000000, /*  */
+
+	0xc0026900,
+	0x00000229,
+	0x00000000, /* SQ_PGM_START_FS */
+	0x00000000,
+
+	0xc0016900,
+	0x0000023b,
+	0x00000000, /* SQ_LDS_ALLOC_PS */
+
+	0xc0066900,
+	0x00000240,
+	0x00000000, /* SQ_ESGS_RING_ITEMSIZE */
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+
+	0xc0046900,
+	0x00000247,
+	0x00000000, /* SQ_GS_VERT_ITEMSIZE */
+	0x00000000,
+	0x00000000,
+	0x00000000,
+
+	0xc0116900,
+	0x00000280,
+	0x00000000, /* PA_SU_POINT_SIZE */
+	0x00000000, /* PA_SU_POINT_MINMAX */
+	0x00000008, /* PA_SU_LINE_CNTL */
+	0x00000000, /* PA_SC_LINE_STIPPLE */
+	0x00000000, /* VGT_OUTPUT_PATH_CNTL */
+	0x00000000, /* VGT_HOS_CNTL */
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000, /* VGT_GS_MODE */
+
+	0xc0026900,
+	0x00000292,
+	0x00000000, /* PA_SC_MODE_CNTL_0 */
+	0x00000000, /* PA_SC_MODE_CNTL_1 */
+
+	0xc0016900,
+	0x000002a1,
+	0x00000000, /* VGT_PRIMITIVEID_EN */
+
+	0xc0016900,
+	0x000002a5,
+	0x00000000, /* VGT_MULTI_PRIM_IB_RESET_EN */
+
+	0xc0026900,
+	0x000002a8,
+	0x00000000, /* VGT_INSTANCE_STEP_RATE_0 */
+	0x00000000,
+
+	0xc0026900,
+	0x000002ad,
+	0x00000000, /* VGT_REUSE_OFF */
+	0x00000000,
+
+	0xc0016900,
+	0x000002d5,
+	0x00000000, /* VGT_SHADER_STAGES_EN */
+
+	0xc0016900,
+	0x000002dc,
+	0x0000aa00, /* DB_ALPHA_TO_MASK */
+
+	0xc0066900,
+	0x000002de,
+	0x00000000, /* PA_SU_POLY_OFFSET_DB_FMT_CNTL */
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+
+	0xc0026900,
+	0x000002e5,
+	0x00000000, /* VGT_STRMOUT_CONFIG */
+	0x00000000,
+
+	0xc01b6900,
+	0x000002f5,
+	0x76543210, /* PA_SC_CENTROID_PRIORITY_0 */
+	0xfedcba98, /* PA_SC_CENTROID_PRIORITY_1 */
+	0x00000000, /* PA_SC_LINE_CNTL */
+	0x00000000, /* PA_SC_AA_CONFIG */
+	0x00000005, /* PA_SU_VTX_CNTL */
+	0x3f800000, /* PA_CL_GB_VERT_CLIP_ADJ */
+	0x3f800000, /* PA_CL_GB_VERT_DISC_ADJ */
+	0x3f800000, /* PA_CL_GB_HORZ_CLIP_ADJ */
+	0x3f800000, /* PA_CL_GB_HORZ_DISC_ADJ */
+	0x00000000, /* PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y0_0 */
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0x00000000,
+	0xffffffff, /* PA_SC_AA_MASK_X0Y0_X1Y0 */
+	0xffffffff,
+
+	0xc0026900,
+	0x00000316,
+	0x0000000e, /* VGT_VERTEX_REUSE_BLOCK_CNTL */
+	0x00000010, /*  */
 };
 
+const u32 cayman_vs[] =
+{
+	0x00000004,
+	0x80400400,
+	0x0000a03c,
+	0x95000688,
+	0x00004000,
+	0x15000688,
+	0x00000000,
+	0x88000000,
+	0x04000000,
+	0x67961001,
+#ifdef __BIG_ENDIAN
+	0x00020000,
+#else
+	0x00000000,
+#endif
+	0x00000000,
+	0x04000000,
+	0x67961000,
+#ifdef __BIG_ENDIAN
+	0x00020008,
+#else
+	0x00000008,
+#endif
+	0x00000000,
+};
+
+const u32 cayman_ps[] =
+{
+	0x00000004,
+	0xa00c0000,
+	0x00000008,
+	0x80400000,
+	0x00000000,
+	0x95000688,
+	0x00000000,
+	0x88000000,
+	0x00380400,
+	0x00146b10,
+	0x00380000,
+	0x20146b10,
+	0x00380400,
+	0x40146b00,
+	0x80380000,
+	0x60146b00,
+	0x00000010,
+	0x000d1000,
+	0xb0800000,
+	0x00000000,
+};
+
+const u32 cayman_ps_size = ARRAY_SIZE(cayman_ps);
+const u32 cayman_vs_size = ARRAY_SIZE(cayman_vs);
 const u32 cayman_default_size = ARRAY_SIZE(cayman_default_state);
diff -druN linux-2.6.39-libre/drivers/gpu/drm/radeon/cayman_blit_shaders.h linux-3.0-rc7-libre/drivers/gpu/drm/radeon/cayman_blit_shaders.h
--- linux-2.6.39-libre/drivers/gpu/drm/radeon/cayman_blit_shaders.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/gpu/drm/radeon/cayman_blit_shaders.h	2011-07-11 19:51:52.000000000 -0400
@@ -25,8 +25,11 @@
 #ifndef CAYMAN_BLIT_SHADERS_H
 #define CAYMAN_BLIT_SHADERS_H
 
+extern const u32 cayman_ps[];
+extern const u32 cayman_vs[];
 extern const u32 cayman_default_state[];
 
+extern const u32 cayman_ps_size, cayman_vs_size;
 extern const u32 cayman_default_size;
 
 #endif
diff -druN linux-2.6.39-libre/drivers/gpu/drm/radeon/evergreen_blit_kms.c linux-3.0-rc7-libre/drivers/gpu/drm/radeon/evergreen_blit_kms.c
--- linux-2.6.39-libre/drivers/gpu/drm/radeon/evergreen_blit_kms.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/gpu/drm/radeon/evergreen_blit_kms.c	2011-07-11 19:51:52.000000000 -0400
@@ -31,6 +31,7 @@
 
 #include "evergreend.h"
 #include "evergreen_blit_shaders.h"
+#include "cayman_blit_shaders.h"
 
 #define DI_PT_RECTLIST        0x11
 #define DI_INDEX_SIZE_16_BIT  0x0
@@ -152,6 +153,8 @@
 
 	if ((rdev->family == CHIP_CEDAR) ||
 	    (rdev->family == CHIP_PALM) ||
+	    (rdev->family == CHIP_SUMO) ||
+	    (rdev->family == CHIP_SUMO2) ||
 	    (rdev->family == CHIP_CAICOS))
 		cp_set_surface_sync(rdev,
 				    PACKET3_TC_ACTION_ENA, 48, gpu_addr);
@@ -199,6 +202,16 @@
 set_scissors(struct radeon_device *rdev, int x1, int y1,
 	     int x2, int y2)
 {
+	/* workaround some hw bugs */
+	if (x2 == 0)
+		x1 = 1;
+	if (y2 == 0)
+		y1 = 1;
+	if (rdev->family == CHIP_CAYMAN) {
+		if ((x2 == 1) && (y2 == 1))
+			x2 = 2;
+	}
+
 	radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONTEXT_REG, 2));
 	radeon_ring_write(rdev, (PA_SC_SCREEN_SCISSOR_TL - PACKET3_SET_CONTEXT_REG_START) >> 2);
 	radeon_ring_write(rdev, (x1 << 0) | (y1 << 16));
@@ -255,238 +268,284 @@
 	u64 gpu_addr;
 	int dwords;
 
-	switch (rdev->family) {
-	case CHIP_CEDAR:
-	default:
-		num_ps_gprs = 93;
-		num_vs_gprs = 46;
-		num_temp_gprs = 4;
-		num_gs_gprs = 31;
-		num_es_gprs = 31;
-		num_hs_gprs = 23;
-		num_ls_gprs = 23;
-		num_ps_threads = 96;
-		num_vs_threads = 16;
-		num_gs_threads = 16;
-		num_es_threads = 16;
-		num_hs_threads = 16;
-		num_ls_threads = 16;
-		num_ps_stack_entries = 42;
-		num_vs_stack_entries = 42;
-		num_gs_stack_entries = 42;
-		num_es_stack_entries = 42;
-		num_hs_stack_entries = 42;
-		num_ls_stack_entries = 42;
-		break;
-	case CHIP_REDWOOD:
-		num_ps_gprs = 93;
-		num_vs_gprs = 46;
-		num_temp_gprs = 4;
-		num_gs_gprs = 31;
-		num_es_gprs = 31;
-		num_hs_gprs = 23;
-		num_ls_gprs = 23;
-		num_ps_threads = 128;
-		num_vs_threads = 20;
-		num_gs_threads = 20;
-		num_es_threads = 20;
-		num_hs_threads = 20;
-		num_ls_threads = 20;
-		num_ps_stack_entries = 42;
-		num_vs_stack_entries = 42;
-		num_gs_stack_entries = 42;
-		num_es_stack_entries = 42;
-		num_hs_stack_entries = 42;
-		num_ls_stack_entries = 42;
-		break;
-	case CHIP_JUNIPER:
-		num_ps_gprs = 93;
-		num_vs_gprs = 46;
-		num_temp_gprs = 4;
-		num_gs_gprs = 31;
-		num_es_gprs = 31;
-		num_hs_gprs = 23;
-		num_ls_gprs = 23;
-		num_ps_threads = 128;
-		num_vs_threads = 20;
-		num_gs_threads = 20;
-		num_es_threads = 20;
-		num_hs_threads = 20;
-		num_ls_threads = 20;
-		num_ps_stack_entries = 85;
-		num_vs_stack_entries = 85;
-		num_gs_stack_entries = 85;
-		num_es_stack_entries = 85;
-		num_hs_stack_entries = 85;
-		num_ls_stack_entries = 85;
-		break;
-	case CHIP_CYPRESS:
-	case CHIP_HEMLOCK:
-		num_ps_gprs = 93;
-		num_vs_gprs = 46;
-		num_temp_gprs = 4;
-		num_gs_gprs = 31;
-		num_es_gprs = 31;
-		num_hs_gprs = 23;
-		num_ls_gprs = 23;
-		num_ps_threads = 128;
-		num_vs_threads = 20;
-		num_gs_threads = 20;
-		num_es_threads = 20;
-		num_hs_threads = 20;
-		num_ls_threads = 20;
-		num_ps_stack_entries = 85;
-		num_vs_stack_entries = 85;
-		num_gs_stack_entries = 85;
-		num_es_stack_entries = 85;
-		num_hs_stack_entries = 85;
-		num_ls_stack_entries = 85;
-		break;
-	case CHIP_PALM:
-		num_ps_gprs = 93;
-		num_vs_gprs = 46;
-		num_temp_gprs = 4;
-		num_gs_gprs = 31;
-		num_es_gprs = 31;
-		num_hs_gprs = 23;
-		num_ls_gprs = 23;
-		num_ps_threads = 96;
-		num_vs_threads = 16;
-		num_gs_threads = 16;
-		num_es_threads = 16;
-		num_hs_threads = 16;
-		num_ls_threads = 16;
-		num_ps_stack_entries = 42;
-		num_vs_stack_entries = 42;
-		num_gs_stack_entries = 42;
-		num_es_stack_entries = 42;
-		num_hs_stack_entries = 42;
-		num_ls_stack_entries = 42;
-		break;
-	case CHIP_BARTS:
-		num_ps_gprs = 93;
-		num_vs_gprs = 46;
-		num_temp_gprs = 4;
-		num_gs_gprs = 31;
-		num_es_gprs = 31;
-		num_hs_gprs = 23;
-		num_ls_gprs = 23;
-		num_ps_threads = 128;
-		num_vs_threads = 20;
-		num_gs_threads = 20;
-		num_es_threads = 20;
-		num_hs_threads = 20;
-		num_ls_threads = 20;
-		num_ps_stack_entries = 85;
-		num_vs_stack_entries = 85;
-		num_gs_stack_entries = 85;
-		num_es_stack_entries = 85;
-		num_hs_stack_entries = 85;
-		num_ls_stack_entries = 85;
-		break;
-	case CHIP_TURKS:
-		num_ps_gprs = 93;
-		num_vs_gprs = 46;
-		num_temp_gprs = 4;
-		num_gs_gprs = 31;
-		num_es_gprs = 31;
-		num_hs_gprs = 23;
-		num_ls_gprs = 23;
-		num_ps_threads = 128;
-		num_vs_threads = 20;
-		num_gs_threads = 20;
-		num_es_threads = 20;
-		num_hs_threads = 20;
-		num_ls_threads = 20;
-		num_ps_stack_entries = 42;
-		num_vs_stack_entries = 42;
-		num_gs_stack_entries = 42;
-		num_es_stack_entries = 42;
-		num_hs_stack_entries = 42;
-		num_ls_stack_entries = 42;
-		break;
-	case CHIP_CAICOS:
-		num_ps_gprs = 93;
-		num_vs_gprs = 46;
-		num_temp_gprs = 4;
-		num_gs_gprs = 31;
-		num_es_gprs = 31;
-		num_hs_gprs = 23;
-		num_ls_gprs = 23;
-		num_ps_threads = 128;
-		num_vs_threads = 10;
-		num_gs_threads = 10;
-		num_es_threads = 10;
-		num_hs_threads = 10;
-		num_ls_threads = 10;
-		num_ps_stack_entries = 42;
-		num_vs_stack_entries = 42;
-		num_gs_stack_entries = 42;
-		num_es_stack_entries = 42;
-		num_hs_stack_entries = 42;
-		num_ls_stack_entries = 42;
-		break;
-	}
+	/* set clear context state */
+	radeon_ring_write(rdev, PACKET3(PACKET3_CLEAR_STATE, 0));
+	radeon_ring_write(rdev, 0);
 
-	if ((rdev->family == CHIP_CEDAR) ||
-	    (rdev->family == CHIP_PALM) ||
-	    (rdev->family == CHIP_CAICOS))
-		sq_config = 0;
-	else
-		sq_config = VC_ENABLE;
+	if (rdev->family < CHIP_CAYMAN) {
+		switch (rdev->family) {
+		case CHIP_CEDAR:
+		default:
+			num_ps_gprs = 93;
+			num_vs_gprs = 46;
+			num_temp_gprs = 4;
+			num_gs_gprs = 31;
+			num_es_gprs = 31;
+			num_hs_gprs = 23;
+			num_ls_gprs = 23;
+			num_ps_threads = 96;
+			num_vs_threads = 16;
+			num_gs_threads = 16;
+			num_es_threads = 16;
+			num_hs_threads = 16;
+			num_ls_threads = 16;
+			num_ps_stack_entries = 42;
+			num_vs_stack_entries = 42;
+			num_gs_stack_entries = 42;
+			num_es_stack_entries = 42;
+			num_hs_stack_entries = 42;
+			num_ls_stack_entries = 42;
+			break;
+		case CHIP_REDWOOD:
+			num_ps_gprs = 93;
+			num_vs_gprs = 46;
+			num_temp_gprs = 4;
+			num_gs_gprs = 31;
+			num_es_gprs = 31;
+			num_hs_gprs = 23;
+			num_ls_gprs = 23;
+			num_ps_threads = 128;
+			num_vs_threads = 20;
+			num_gs_threads = 20;
+			num_es_threads = 20;
+			num_hs_threads = 20;
+			num_ls_threads = 20;
+			num_ps_stack_entries = 42;
+			num_vs_stack_entries = 42;
+			num_gs_stack_entries = 42;
+			num_es_stack_entries = 42;
+			num_hs_stack_entries = 42;
+			num_ls_stack_entries = 42;
+			break;
+		case CHIP_JUNIPER:
+			num_ps_gprs = 93;
+			num_vs_gprs = 46;
+			num_temp_gprs = 4;
+			num_gs_gprs = 31;
+			num_es_gprs = 31;
+			num_hs_gprs = 23;
+			num_ls_gprs = 23;
+			num_ps_threads = 128;
+			num_vs_threads = 20;
+			num_gs_threads = 20;
+			num_es_threads = 20;
+			num_hs_threads = 20;
+			num_ls_threads = 20;
+			num_ps_stack_entries = 85;
+			num_vs_stack_entries = 85;
+			num_gs_stack_entries = 85;
+			num_es_stack_entries = 85;
+			num_hs_stack_entries = 85;
+			num_ls_stack_entries = 85;
+			break;
+		case CHIP_CYPRESS:
+		case CHIP_HEMLOCK:
+			num_ps_gprs = 93;
+			num_vs_gprs = 46;
+			num_temp_gprs = 4;
+			num_gs_gprs = 31;
+			num_es_gprs = 31;
+			num_hs_gprs = 23;
+			num_ls_gprs = 23;
+			num_ps_threads = 128;
+			num_vs_threads = 20;
+			num_gs_threads = 20;
+			num_es_threads = 20;
+			num_hs_threads = 20;
+			num_ls_threads = 20;
+			num_ps_stack_entries = 85;
+			num_vs_stack_entries = 85;
+			num_gs_stack_entries = 85;
+			num_es_stack_entries = 85;
+			num_hs_stack_entries = 85;
+			num_ls_stack_entries = 85;
+			break;
+		case CHIP_PALM:
+			num_ps_gprs = 93;
+			num_vs_gprs = 46;
+			num_temp_gprs = 4;
+			num_gs_gprs = 31;
+			num_es_gprs = 31;
+			num_hs_gprs = 23;
+			num_ls_gprs = 23;
+			num_ps_threads = 96;
+			num_vs_threads = 16;
+			num_gs_threads = 16;
+			num_es_threads = 16;
+			num_hs_threads = 16;
+			num_ls_threads = 16;
+			num_ps_stack_entries = 42;
+			num_vs_stack_entries = 42;
+			num_gs_stack_entries = 42;
+			num_es_stack_entries = 42;
+			num_hs_stack_entries = 42;
+			num_ls_stack_entries = 42;
+			break;
+		case CHIP_SUMO:
+			num_ps_gprs = 93;
+			num_vs_gprs = 46;
+			num_temp_gprs = 4;
+			num_gs_gprs = 31;
+			num_es_gprs = 31;
+			num_hs_gprs = 23;
+			num_ls_gprs = 23;
+			num_ps_threads = 96;
+			num_vs_threads = 25;
+			num_gs_threads = 25;
+			num_es_threads = 25;
+			num_hs_threads = 25;
+			num_ls_threads = 25;
+			num_ps_stack_entries = 42;
+			num_vs_stack_entries = 42;
+			num_gs_stack_entries = 42;
+			num_es_stack_entries = 42;
+			num_hs_stack_entries = 42;
+			num_ls_stack_entries = 42;
+			break;
+		case CHIP_SUMO2:
+			num_ps_gprs = 93;
+			num_vs_gprs = 46;
+			num_temp_gprs = 4;
+			num_gs_gprs = 31;
+			num_es_gprs = 31;
+			num_hs_gprs = 23;
+			num_ls_gprs = 23;
+			num_ps_threads = 96;
+			num_vs_threads = 25;
+			num_gs_threads = 25;
+			num_es_threads = 25;
+			num_hs_threads = 25;
+			num_ls_threads = 25;
+			num_ps_stack_entries = 85;
+			num_vs_stack_entries = 85;
+			num_gs_stack_entries = 85;
+			num_es_stack_entries = 85;
+			num_hs_stack_entries = 85;
+			num_ls_stack_entries = 85;
+			break;
+		case CHIP_BARTS:
+			num_ps_gprs = 93;
+			num_vs_gprs = 46;
+			num_temp_gprs = 4;
+			num_gs_gprs = 31;
+			num_es_gprs = 31;
+			num_hs_gprs = 23;
+			num_ls_gprs = 23;
+			num_ps_threads = 128;
+			num_vs_threads = 20;
+			num_gs_threads = 20;
+			num_es_threads = 20;
+			num_hs_threads = 20;
+			num_ls_threads = 20;
+			num_ps_stack_entries = 85;
+			num_vs_stack_entries = 85;
+			num_gs_stack_entries = 85;
+			num_es_stack_entries = 85;
+			num_hs_stack_entries = 85;
+			num_ls_stack_entries = 85;
+			break;
+		case CHIP_TURKS:
+			num_ps_gprs = 93;
+			num_vs_gprs = 46;
+			num_temp_gprs = 4;
+			num_gs_gprs = 31;
+			num_es_gprs = 31;
+			num_hs_gprs = 23;
+			num_ls_gprs = 23;
+			num_ps_threads = 128;
+			num_vs_threads = 20;
+			num_gs_threads = 20;
+			num_es_threads = 20;
+			num_hs_threads = 20;
+			num_ls_threads = 20;
+			num_ps_stack_entries = 42;
+			num_vs_stack_entries = 42;
+			num_gs_stack_entries = 42;
+			num_es_stack_entries = 42;
+			num_hs_stack_entries = 42;
+			num_ls_stack_entries = 42;
+			break;
+		case CHIP_CAICOS:
+			num_ps_gprs = 93;
+			num_vs_gprs = 46;
+			num_temp_gprs = 4;
+			num_gs_gprs = 31;
+			num_es_gprs = 31;
+			num_hs_gprs = 23;
+			num_ls_gprs = 23;
+			num_ps_threads = 128;
+			num_vs_threads = 10;
+			num_gs_threads = 10;
+			num_es_threads = 10;
+			num_hs_threads = 10;
+			num_ls_threads = 10;
+			num_ps_stack_entries = 42;
+			num_vs_stack_entries = 42;
+			num_gs_stack_entries = 42;
+			num_es_stack_entries = 42;
+			num_hs_stack_entries = 42;
+			num_ls_stack_entries = 42;
+			break;
+		}
 
-	sq_config |= (EXPORT_SRC_C |
-		      CS_PRIO(0) |
-		      LS_PRIO(0) |
-		      HS_PRIO(0) |
-		      PS_PRIO(0) |
-		      VS_PRIO(1) |
-		      GS_PRIO(2) |
-		      ES_PRIO(3));
+		if ((rdev->family == CHIP_CEDAR) ||
+		    (rdev->family == CHIP_PALM) ||
+		    (rdev->family == CHIP_SUMO) ||
+		    (rdev->family == CHIP_SUMO2) ||
+		    (rdev->family == CHIP_CAICOS))
+			sq_config = 0;
+		else
+			sq_config = VC_ENABLE;
 
-	sq_gpr_resource_mgmt_1 = (NUM_PS_GPRS(num_ps_gprs) |
-				  NUM_VS_GPRS(num_vs_gprs) |
-				  NUM_CLAUSE_TEMP_GPRS(num_temp_gprs));
-	sq_gpr_resource_mgmt_2 = (NUM_GS_GPRS(num_gs_gprs) |
-				  NUM_ES_GPRS(num_es_gprs));
-	sq_gpr_resource_mgmt_3 = (NUM_HS_GPRS(num_hs_gprs) |
-				  NUM_LS_GPRS(num_ls_gprs));
-	sq_thread_resource_mgmt = (NUM_PS_THREADS(num_ps_threads) |
-				   NUM_VS_THREADS(num_vs_threads) |
-				   NUM_GS_THREADS(num_gs_threads) |
-				   NUM_ES_THREADS(num_es_threads));
-	sq_thread_resource_mgmt_2 = (NUM_HS_THREADS(num_hs_threads) |
-				     NUM_LS_THREADS(num_ls_threads));
-	sq_stack_resource_mgmt_1 = (NUM_PS_STACK_ENTRIES(num_ps_stack_entries) |
-				    NUM_VS_STACK_ENTRIES(num_vs_stack_entries));
-	sq_stack_resource_mgmt_2 = (NUM_GS_STACK_ENTRIES(num_gs_stack_entries) |
-				    NUM_ES_STACK_ENTRIES(num_es_stack_entries));
-	sq_stack_resource_mgmt_3 = (NUM_HS_STACK_ENTRIES(num_hs_stack_entries) |
-				    NUM_LS_STACK_ENTRIES(num_ls_stack_entries));
+		sq_config |= (EXPORT_SRC_C |
+			      CS_PRIO(0) |
+			      LS_PRIO(0) |
+			      HS_PRIO(0) |
+			      PS_PRIO(0) |
+			      VS_PRIO(1) |
+			      GS_PRIO(2) |
+			      ES_PRIO(3));
 
-	/* set clear context state */
-	radeon_ring_write(rdev, PACKET3(PACKET3_CLEAR_STATE, 0));
-	radeon_ring_write(rdev, 0);
+		sq_gpr_resource_mgmt_1 = (NUM_PS_GPRS(num_ps_gprs) |
+					  NUM_VS_GPRS(num_vs_gprs) |
+					  NUM_CLAUSE_TEMP_GPRS(num_temp_gprs));
+		sq_gpr_resource_mgmt_2 = (NUM_GS_GPRS(num_gs_gprs) |
+					  NUM_ES_GPRS(num_es_gprs));
+		sq_gpr_resource_mgmt_3 = (NUM_HS_GPRS(num_hs_gprs) |
+					  NUM_LS_GPRS(num_ls_gprs));
+		sq_thread_resource_mgmt = (NUM_PS_THREADS(num_ps_threads) |
+					   NUM_VS_THREADS(num_vs_threads) |
+					   NUM_GS_THREADS(num_gs_threads) |
+					   NUM_ES_THREADS(num_es_threads));
+		sq_thread_resource_mgmt_2 = (NUM_HS_THREADS(num_hs_threads) |
+					     NUM_LS_THREADS(num_ls_threads));
+		sq_stack_resource_mgmt_1 = (NUM_PS_STACK_ENTRIES(num_ps_stack_entries) |
+					    NUM_VS_STACK_ENTRIES(num_vs_stack_entries));
+		sq_stack_resource_mgmt_2 = (NUM_GS_STACK_ENTRIES(num_gs_stack_entries) |
+					    NUM_ES_STACK_ENTRIES(num_es_stack_entries));
+		sq_stack_resource_mgmt_3 = (NUM_HS_STACK_ENTRIES(num_hs_stack_entries) |
+					    NUM_LS_STACK_ENTRIES(num_ls_stack_entries));
 
-	/* disable dyn gprs */
-	radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONFIG_REG, 1));
-	radeon_ring_write(rdev, (SQ_DYN_GPR_CNTL_PS_FLUSH_REQ - PACKET3_SET_CONFIG_REG_START) >> 2);
-	radeon_ring_write(rdev, 0);
+		/* disable dyn gprs */
+		radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONFIG_REG, 1));
+		radeon_ring_write(rdev, (SQ_DYN_GPR_CNTL_PS_FLUSH_REQ - PACKET3_SET_CONFIG_REG_START) >> 2);
+		radeon_ring_write(rdev, 0);
 
-	/* SQ config */
-	radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONFIG_REG, 11));
-	radeon_ring_write(rdev, (SQ_CONFIG - PACKET3_SET_CONFIG_REG_START) >> 2);
-	radeon_ring_write(rdev, sq_config);
-	radeon_ring_write(rdev, sq_gpr_resource_mgmt_1);
-	radeon_ring_write(rdev, sq_gpr_resource_mgmt_2);
-	radeon_ring_write(rdev, sq_gpr_resource_mgmt_3);
-	radeon_ring_write(rdev, 0);
-	radeon_ring_write(rdev, 0);
-	radeon_ring_write(rdev, sq_thread_resource_mgmt);
-	radeon_ring_write(rdev, sq_thread_resource_mgmt_2);
-	radeon_ring_write(rdev, sq_stack_resource_mgmt_1);
-	radeon_ring_write(rdev, sq_stack_resource_mgmt_2);
-	radeon_ring_write(rdev, sq_stack_resource_mgmt_3);
+		/* SQ config */
+		radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONFIG_REG, 11));
+		radeon_ring_write(rdev, (SQ_CONFIG - PACKET3_SET_CONFIG_REG_START) >> 2);
+		radeon_ring_write(rdev, sq_config);
+		radeon_ring_write(rdev, sq_gpr_resource_mgmt_1);
+		radeon_ring_write(rdev, sq_gpr_resource_mgmt_2);
+		radeon_ring_write(rdev, sq_gpr_resource_mgmt_3);
+		radeon_ring_write(rdev, 0);
+		radeon_ring_write(rdev, 0);
+		radeon_ring_write(rdev, sq_thread_resource_mgmt);
+		radeon_ring_write(rdev, sq_thread_resource_mgmt_2);
+		radeon_ring_write(rdev, sq_stack_resource_mgmt_1);
+		radeon_ring_write(rdev, sq_stack_resource_mgmt_2);
+		radeon_ring_write(rdev, sq_stack_resource_mgmt_3);
+	}
 
 	/* CONTEXT_CONTROL */
 	radeon_ring_write(rdev, 0xc0012800);
@@ -560,7 +619,10 @@
 	mutex_init(&rdev->r600_blit.mutex);
 	rdev->r600_blit.state_offset = 0;
 
-	rdev->r600_blit.state_len = evergreen_default_size;
+	if (rdev->family < CHIP_CAYMAN)
+		rdev->r600_blit.state_len = evergreen_default_size;
+	else
+		rdev->r600_blit.state_len = cayman_default_size;
 
 	dwords = rdev->r600_blit.state_len;
 	while (dwords & 0xf) {
@@ -572,11 +634,17 @@
 	obj_size = ALIGN(obj_size, 256);
 
 	rdev->r600_blit.vs_offset = obj_size;
-	obj_size += evergreen_vs_size * 4;
+	if (rdev->family < CHIP_CAYMAN)
+		obj_size += evergreen_vs_size * 4;
+	else
+		obj_size += cayman_vs_size * 4;
 	obj_size = ALIGN(obj_size, 256);
 
 	rdev->r600_blit.ps_offset = obj_size;
-	obj_size += evergreen_ps_size * 4;
+	if (rdev->family < CHIP_CAYMAN)
+		obj_size += evergreen_ps_size * 4;
+	else
+		obj_size += cayman_ps_size * 4;
 	obj_size = ALIGN(obj_size, 256);
 
 	r = radeon_bo_create(rdev, obj_size, PAGE_SIZE, true, RADEON_GEM_DOMAIN_VRAM,
@@ -599,16 +667,29 @@
 		return r;
 	}
 
-	memcpy_toio(ptr + rdev->r600_blit.state_offset,
-		    evergreen_default_state, rdev->r600_blit.state_len * 4);
+	if (rdev->family < CHIP_CAYMAN) {
+		memcpy_toio(ptr + rdev->r600_blit.state_offset,
+			    evergreen_default_state, rdev->r600_blit.state_len * 4);
 
-	if (num_packet2s)
-		memcpy_toio(ptr + rdev->r600_blit.state_offset + (rdev->r600_blit.state_len * 4),
-			    packet2s, num_packet2s * 4);
-	for (i = 0; i < evergreen_vs_size; i++)
-		*(u32 *)((unsigned long)ptr + rdev->r600_blit.vs_offset + i * 4) = cpu_to_le32(evergreen_vs[i]);
-	for (i = 0; i < evergreen_ps_size; i++)
-		*(u32 *)((unsigned long)ptr + rdev->r600_blit.ps_offset + i * 4) = cpu_to_le32(evergreen_ps[i]);
+		if (num_packet2s)
+			memcpy_toio(ptr + rdev->r600_blit.state_offset + (rdev->r600_blit.state_len * 4),
+				    packet2s, num_packet2s * 4);
+		for (i = 0; i < evergreen_vs_size; i++)
+			*(u32 *)((unsigned long)ptr + rdev->r600_blit.vs_offset + i * 4) = cpu_to_le32(evergreen_vs[i]);
+		for (i = 0; i < evergreen_ps_size; i++)
+			*(u32 *)((unsigned long)ptr + rdev->r600_blit.ps_offset + i * 4) = cpu_to_le32(evergreen_ps[i]);
+	} else {
+		memcpy_toio(ptr + rdev->r600_blit.state_offset,
+			    cayman_default_state, rdev->r600_blit.state_len * 4);
+
+		if (num_packet2s)
+			memcpy_toio(ptr + rdev->r600_blit.state_offset + (rdev->r600_blit.state_len * 4),
+				    packet2s, num_packet2s * 4);
+		for (i = 0; i < cayman_vs_size; i++)
+			*(u32 *)((unsigned long)ptr + rdev->r600_blit.vs_offset + i * 4) = cpu_to_le32(cayman_vs[i]);
+		for (i = 0; i < cayman_ps_size; i++)
+			*(u32 *)((unsigned long)ptr + rdev->r600_blit.ps_offset + i * 4) = cpu_to_le32(cayman_ps[i]);
+	}
 	radeon_bo_kunmap(rdev->r600_blit.shader_obj);
 	radeon_bo_unreserve(rdev->r600_blit.shader_obj);
 
diff -druN linux-2.6.39-libre/drivers/gpu/drm/radeon/evergreen.c linux-3.0-rc7-libre/drivers/gpu/drm/radeon/evergreen.c
--- linux-2.6.39-libre/drivers/gpu/drm/radeon/evergreen.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/gpu/drm/radeon/evergreen.c	2011-07-11 19:51:52.000000000 -0400
@@ -88,21 +88,40 @@
 /* get temperature in millidegrees */
 int evergreen_get_temp(struct radeon_device *rdev)
 {
-	u32 temp = (RREG32(CG_MULT_THERMAL_STATUS) & ASIC_T_MASK) >>
-		ASIC_T_SHIFT;
-	u32 actual_temp = 0;
+	u32 temp, toffset;
+	int actual_temp = 0;
 
-	if (temp & 0x400)
-		actual_temp = -256;
-	else if (temp & 0x200)
-		actual_temp = 255;
-	else if (temp & 0x100) {
-		actual_temp = temp & 0x1ff;
-		actual_temp |= ~0x1ff;
-	} else
-		actual_temp = temp & 0xff;
+	if (rdev->family == CHIP_JUNIPER) {
+		toffset = (RREG32(CG_THERMAL_CTRL) & TOFFSET_MASK) >>
+			TOFFSET_SHIFT;
+		temp = (RREG32(CG_TS0_STATUS) & TS0_ADC_DOUT_MASK) >>
+			TS0_ADC_DOUT_SHIFT;
 
-	return (actual_temp * 1000) / 2;
+		if (toffset & 0x100)
+			actual_temp = temp / 2 - (0x200 - toffset);
+		else
+			actual_temp = temp / 2 + toffset;
+
+		actual_temp = actual_temp * 1000;
+
+	} else {
+		temp = (RREG32(CG_MULT_THERMAL_STATUS) & ASIC_T_MASK) >>
+			ASIC_T_SHIFT;
+
+		if (temp & 0x400)
+			actual_temp = -256;
+		else if (temp & 0x200)
+			actual_temp = 255;
+		else if (temp & 0x100) {
+			actual_temp = temp & 0x1ff;
+			actual_temp |= ~0x1ff;
+		} else
+			actual_temp = temp & 0xff;
+
+		actual_temp = (actual_temp * 1000) / 2;
+	}
+
+	return actual_temp;
 }
 
 int sumo_get_temp(struct radeon_device *rdev)
@@ -121,11 +140,17 @@
 	struct radeon_voltage *voltage = &ps->clock_info[req_cm_idx].voltage;
 
 	if (voltage->type == VOLTAGE_SW) {
+		/* 0xff01 is a flag rather then an actual voltage */
+		if (voltage->voltage == 0xff01)
+			return;
 		if (voltage->voltage && (voltage->voltage != rdev->pm.current_vddc)) {
 			radeon_atom_set_voltage(rdev, voltage->voltage, SET_VOLTAGE_TYPE_ASIC_VDDC);
 			rdev->pm.current_vddc = voltage->voltage;
 			DRM_DEBUG("Setting: vddc: %d\n", voltage->voltage);
 		}
+		/* 0xff01 is a flag rather then an actual voltage */
+		if (voltage->vddci == 0xff01)
+			return;
 		if (voltage->vddci && (voltage->vddci != rdev->pm.current_vddci)) {
 			radeon_atom_set_voltage(rdev, voltage->vddci, SET_VOLTAGE_TYPE_ASIC_VDDCI);
 			rdev->pm.current_vddci = voltage->vddci;
@@ -960,17 +985,19 @@
 {
 	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);
-	if (!(rdev->flags & RADEON_IS_IGP)) {
+	if (rdev->num_crtc >= 4) {
+		save->vga_control[2] = RREG32(EVERGREEN_D3VGA_CONTROL);
+		save->vga_control[3] = RREG32(EVERGREEN_D4VGA_CONTROL);
 		save->crtc_control[2] = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET);
 		save->crtc_control[3] = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET);
+	}
+	if (rdev->num_crtc >= 6) {
+		save->vga_control[4] = RREG32(EVERGREEN_D5VGA_CONTROL);
+		save->vga_control[5] = RREG32(EVERGREEN_D6VGA_CONTROL);
 		save->crtc_control[4] = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET);
 		save->crtc_control[5] = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET);
 	}
@@ -979,35 +1006,45 @@
 	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);
-	if (!(rdev->flags & RADEON_IS_IGP)) {
+	if (rdev->num_crtc >= 4) {
 		WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC2_REGISTER_OFFSET, 1);
 		WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC3_REGISTER_OFFSET, 1);
+	}
+	if (rdev->num_crtc >= 6) {
 		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);
-	if (!(rdev->flags & RADEON_IS_IGP)) {
+	if (rdev->num_crtc >= 4) {
 		WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET, 0);
 		WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET, 0);
+	}
+	if (rdev->num_crtc >= 6) {
 		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);
-	if (!(rdev->flags & RADEON_IS_IGP)) {
+	if (rdev->num_crtc >= 4) {
 		WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC2_REGISTER_OFFSET, 0);
 		WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC3_REGISTER_OFFSET, 0);
+	}
+	if (rdev->num_crtc >= 6) {
 		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);
+	if (rdev->num_crtc >= 4) {
+		WREG32(EVERGREEN_D3VGA_CONTROL, 0);
+		WREG32(EVERGREEN_D4VGA_CONTROL, 0);
+	}
+	if (rdev->num_crtc >= 6) {
+		WREG32(EVERGREEN_D5VGA_CONTROL, 0);
+		WREG32(EVERGREEN_D6VGA_CONTROL, 0);
+	}
 }
 
 void evergreen_mc_resume(struct radeon_device *rdev, struct evergreen_mc_save *save)
@@ -1030,7 +1067,7 @@
 	WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS + EVERGREEN_CRTC1_REGISTER_OFFSET,
 	       (u32)rdev->mc.vram_start);
 
-	if (!(rdev->flags & RADEON_IS_IGP)) {
+	if (rdev->num_crtc >= 4) {
 		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,
@@ -1048,7 +1085,8 @@
 		       (u32)rdev->mc.vram_start);
 		WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS + EVERGREEN_CRTC3_REGISTER_OFFSET,
 		       (u32)rdev->mc.vram_start);
-
+	}
+	if (rdev->num_crtc >= 6) {
 		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,
@@ -1076,31 +1114,41 @@
 	/* 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]);
+	if (rdev->num_crtc >= 4) {
+		WREG32(EVERGREEN_D3VGA_CONTROL, save->vga_control[2]);
+		WREG32(EVERGREEN_D4VGA_CONTROL, save->vga_control[3]);
+	}
+	if (rdev->num_crtc >= 6) {
+		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);
-	if (!(rdev->flags & RADEON_IS_IGP)) {
+	if (rdev->num_crtc >= 4) {
 		WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC2_REGISTER_OFFSET, 1);
 		WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC3_REGISTER_OFFSET, 1);
+	}
+	if (rdev->num_crtc >= 6) {
 		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]);
-	if (!(rdev->flags & RADEON_IS_IGP)) {
+	if (rdev->num_crtc >= 4) {
 		WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET, save->crtc_control[2]);
 		WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET, save->crtc_control[3]);
+	}
+	if (rdev->num_crtc >= 6) {
 		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);
-	if (!(rdev->flags & RADEON_IS_IGP)) {
+	if (rdev->num_crtc >= 4) {
 		WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC2_REGISTER_OFFSET, 0);
 		WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC3_REGISTER_OFFSET, 0);
+	}
+	if (rdev->num_crtc >= 6) {
 		WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC4_REGISTER_OFFSET, 0);
 		WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC5_REGISTER_OFFSET, 0);
 	}
@@ -1415,6 +1463,8 @@
 	case CHIP_CEDAR:
 	case CHIP_REDWOOD:
 	case CHIP_PALM:
+	case CHIP_SUMO:
+	case CHIP_SUMO2:
 	case CHIP_TURKS:
 	case CHIP_CAICOS:
 		force_no_swizzle = false;
@@ -1544,6 +1594,8 @@
 	case CHIP_REDWOOD:
 	case CHIP_CEDAR:
 	case CHIP_PALM:
+	case CHIP_SUMO:
+	case CHIP_SUMO2:
 	case CHIP_TURKS:
 	case CHIP_CAICOS:
 	default:
@@ -1578,7 +1630,7 @@
 	u32 sq_stack_resource_mgmt_2;
 	u32 sq_stack_resource_mgmt_3;
 	u32 vgt_cache_invalidation;
-	u32 hdp_host_path_cntl;
+	u32 hdp_host_path_cntl, tmp;
 	int i, j, num_shader_engines, ps_thread_count;
 
 	switch (rdev->family) {
@@ -1689,6 +1741,54 @@
 		rdev->config.evergreen.sc_hiz_tile_fifo_size = 0x30;
 		rdev->config.evergreen.sc_earlyz_tile_fifo_size = 0x130;
 		break;
+	case CHIP_SUMO:
+		rdev->config.evergreen.num_ses = 1;
+		rdev->config.evergreen.max_pipes = 4;
+		rdev->config.evergreen.max_tile_pipes = 2;
+		if (rdev->pdev->device == 0x9648)
+			rdev->config.evergreen.max_simds = 3;
+		else if ((rdev->pdev->device == 0x9647) ||
+			 (rdev->pdev->device == 0x964a))
+			rdev->config.evergreen.max_simds = 4;
+		else
+			rdev->config.evergreen.max_simds = 5;
+		rdev->config.evergreen.max_backends = 2 * rdev->config.evergreen.num_ses;
+		rdev->config.evergreen.max_gprs = 256;
+		rdev->config.evergreen.max_threads = 248;
+		rdev->config.evergreen.max_gs_threads = 32;
+		rdev->config.evergreen.max_stack_entries = 256;
+		rdev->config.evergreen.sx_num_of_sets = 4;
+		rdev->config.evergreen.sx_max_export_size = 256;
+		rdev->config.evergreen.sx_max_export_pos_size = 64;
+		rdev->config.evergreen.sx_max_export_smx_size = 192;
+		rdev->config.evergreen.max_hw_contexts = 8;
+		rdev->config.evergreen.sq_num_cf_insts = 2;
+
+		rdev->config.evergreen.sc_prim_fifo_size = 0x40;
+		rdev->config.evergreen.sc_hiz_tile_fifo_size = 0x30;
+		rdev->config.evergreen.sc_earlyz_tile_fifo_size = 0x130;
+		break;
+	case CHIP_SUMO2:
+		rdev->config.evergreen.num_ses = 1;
+		rdev->config.evergreen.max_pipes = 4;
+		rdev->config.evergreen.max_tile_pipes = 4;
+		rdev->config.evergreen.max_simds = 2;
+		rdev->config.evergreen.max_backends = 1 * rdev->config.evergreen.num_ses;
+		rdev->config.evergreen.max_gprs = 256;
+		rdev->config.evergreen.max_threads = 248;
+		rdev->config.evergreen.max_gs_threads = 32;
+		rdev->config.evergreen.max_stack_entries = 512;
+		rdev->config.evergreen.sx_num_of_sets = 4;
+		rdev->config.evergreen.sx_max_export_size = 256;
+		rdev->config.evergreen.sx_max_export_pos_size = 64;
+		rdev->config.evergreen.sx_max_export_smx_size = 192;
+		rdev->config.evergreen.max_hw_contexts = 8;
+		rdev->config.evergreen.sq_num_cf_insts = 2;
+
+		rdev->config.evergreen.sc_prim_fifo_size = 0x40;
+		rdev->config.evergreen.sc_hiz_tile_fifo_size = 0x30;
+		rdev->config.evergreen.sc_earlyz_tile_fifo_size = 0x130;
+		break;
 	case CHIP_BARTS:
 		rdev->config.evergreen.num_ses = 2;
 		rdev->config.evergreen.max_pipes = 4;
@@ -1936,8 +2036,12 @@
 		rdev->config.evergreen.tile_config |= (3 << 0);
 		break;
 	}
-	rdev->config.evergreen.tile_config |=
-		((mc_arb_ramcfg & NOOFBANK_MASK) >> NOOFBANK_SHIFT) << 4;
+	/* num banks is 8 on all fusion asics. 0 = 4, 1 = 8, 2 = 16 */
+	if (rdev->flags & RADEON_IS_IGP)
+		rdev->config.evergreen.tile_config |= 1 << 4;
+	else
+		rdev->config.evergreen.tile_config |=
+			((mc_arb_ramcfg & NOOFBANK_MASK) >> NOOFBANK_SHIFT) << 4;
 	rdev->config.evergreen.tile_config |=
 		((mc_arb_ramcfg & BURSTLENGTH_MASK) >> BURSTLENGTH_SHIFT) << 8;
 	rdev->config.evergreen.tile_config |=
@@ -2035,6 +2139,8 @@
 	switch (rdev->family) {
 	case CHIP_CEDAR:
 	case CHIP_PALM:
+	case CHIP_SUMO:
+	case CHIP_SUMO2:
 	case CHIP_CAICOS:
 		/* no vertex cache */
 		sq_config &= ~VC_ENABLE;
@@ -2056,6 +2162,8 @@
 	switch (rdev->family) {
 	case CHIP_CEDAR:
 	case CHIP_PALM:
+	case CHIP_SUMO:
+	case CHIP_SUMO2:
 		ps_thread_count = 96;
 		break;
 	default:
@@ -2095,6 +2203,8 @@
 	switch (rdev->family) {
 	case CHIP_CEDAR:
 	case CHIP_PALM:
+	case CHIP_SUMO:
+	case CHIP_SUMO2:
 	case CHIP_CAICOS:
 		vgt_cache_invalidation = CACHE_INVALIDATION(TC_ONLY);
 		break;
@@ -2141,6 +2251,10 @@
 	for (i = SQ_ALU_CONST_BUFFER_SIZE_HS_0; i < 0x29000; i += 4)
 		WREG32(i, 0);
 
+	tmp = RREG32(HDP_MISC_CNTL);
+	tmp |= HDP_FLUSH_INVALIDATE_CACHE;
+	WREG32(HDP_MISC_CNTL, tmp);
+
 	hdp_host_path_cntl = RREG32(HDP_HOST_PATH_CNTL);
 	WREG32(HDP_HOST_PATH_CNTL, hdp_host_path_cntl);
 
@@ -2157,7 +2271,10 @@
 
 	/* Get VRAM informations */
 	rdev->mc.vram_is_ddr = true;
-	tmp = RREG32(MC_ARB_RAMCFG);
+	if (rdev->flags & RADEON_IS_IGP)
+		tmp = RREG32(FUS_MC_ARB_RAMCFG);
+	else
+		tmp = RREG32(MC_ARB_RAMCFG);
 	if (tmp & CHANSIZE_OVERRIDE) {
 		chansize = 16;
 	} else if (tmp & CHANSIZE_MASK) {
@@ -2323,18 +2440,22 @@
 	WREG32(GRBM_INT_CNTL, 0);
 	WREG32(INT_MASK + EVERGREEN_CRTC0_REGISTER_OFFSET, 0);
 	WREG32(INT_MASK + EVERGREEN_CRTC1_REGISTER_OFFSET, 0);
-	if (!(rdev->flags & RADEON_IS_IGP)) {
+	if (rdev->num_crtc >= 4) {
 		WREG32(INT_MASK + EVERGREEN_CRTC2_REGISTER_OFFSET, 0);
 		WREG32(INT_MASK + EVERGREEN_CRTC3_REGISTER_OFFSET, 0);
+	}
+	if (rdev->num_crtc >= 6) {
 		WREG32(INT_MASK + EVERGREEN_CRTC4_REGISTER_OFFSET, 0);
 		WREG32(INT_MASK + EVERGREEN_CRTC5_REGISTER_OFFSET, 0);
 	}
 
 	WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET, 0);
 	WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET, 0);
-	if (!(rdev->flags & RADEON_IS_IGP)) {
+	if (rdev->num_crtc >= 4) {
 		WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET, 0);
 		WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET, 0);
+	}
+	if (rdev->num_crtc >= 6) {
 		WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET, 0);
 		WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET, 0);
 	}
@@ -2453,19 +2574,25 @@
 
 	WREG32(INT_MASK + EVERGREEN_CRTC0_REGISTER_OFFSET, crtc1);
 	WREG32(INT_MASK + EVERGREEN_CRTC1_REGISTER_OFFSET, crtc2);
-	if (!(rdev->flags & RADEON_IS_IGP)) {
+	if (rdev->num_crtc >= 4) {
 		WREG32(INT_MASK + EVERGREEN_CRTC2_REGISTER_OFFSET, crtc3);
 		WREG32(INT_MASK + EVERGREEN_CRTC3_REGISTER_OFFSET, crtc4);
+	}
+	if (rdev->num_crtc >= 6) {
 		WREG32(INT_MASK + EVERGREEN_CRTC4_REGISTER_OFFSET, crtc5);
 		WREG32(INT_MASK + EVERGREEN_CRTC5_REGISTER_OFFSET, crtc6);
 	}
 
 	WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET, grph1);
 	WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET, grph2);
-	WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET, grph3);
-	WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET, grph4);
-	WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET, grph5);
-	WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET, grph6);
+	if (rdev->num_crtc >= 4) {
+		WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET, grph3);
+		WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET, grph4);
+	}
+	if (rdev->num_crtc >= 6) {
+		WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET, grph5);
+		WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET, grph6);
+	}
 
 	WREG32(DC_HPD1_INT_CONTROL, hpd1);
 	WREG32(DC_HPD2_INT_CONTROL, hpd2);
@@ -2489,53 +2616,57 @@
 	rdev->irq.stat_regs.evergreen.disp_int_cont5 = RREG32(DISP_INTERRUPT_STATUS_CONTINUE5);
 	rdev->irq.stat_regs.evergreen.d1grph_int = RREG32(GRPH_INT_STATUS + EVERGREEN_CRTC0_REGISTER_OFFSET);
 	rdev->irq.stat_regs.evergreen.d2grph_int = RREG32(GRPH_INT_STATUS + EVERGREEN_CRTC1_REGISTER_OFFSET);
-	rdev->irq.stat_regs.evergreen.d3grph_int = RREG32(GRPH_INT_STATUS + EVERGREEN_CRTC2_REGISTER_OFFSET);
-	rdev->irq.stat_regs.evergreen.d4grph_int = RREG32(GRPH_INT_STATUS + EVERGREEN_CRTC3_REGISTER_OFFSET);
-	rdev->irq.stat_regs.evergreen.d5grph_int = RREG32(GRPH_INT_STATUS + EVERGREEN_CRTC4_REGISTER_OFFSET);
-	rdev->irq.stat_regs.evergreen.d6grph_int = RREG32(GRPH_INT_STATUS + EVERGREEN_CRTC5_REGISTER_OFFSET);
+	if (rdev->num_crtc >= 4) {
+		rdev->irq.stat_regs.evergreen.d3grph_int = RREG32(GRPH_INT_STATUS + EVERGREEN_CRTC2_REGISTER_OFFSET);
+		rdev->irq.stat_regs.evergreen.d4grph_int = RREG32(GRPH_INT_STATUS + EVERGREEN_CRTC3_REGISTER_OFFSET);
+	}
+	if (rdev->num_crtc >= 6) {
+		rdev->irq.stat_regs.evergreen.d5grph_int = RREG32(GRPH_INT_STATUS + EVERGREEN_CRTC4_REGISTER_OFFSET);
+		rdev->irq.stat_regs.evergreen.d6grph_int = RREG32(GRPH_INT_STATUS + EVERGREEN_CRTC5_REGISTER_OFFSET);
+	}
 
 	if (rdev->irq.stat_regs.evergreen.d1grph_int & GRPH_PFLIP_INT_OCCURRED)
 		WREG32(GRPH_INT_STATUS + EVERGREEN_CRTC0_REGISTER_OFFSET, GRPH_PFLIP_INT_CLEAR);
 	if (rdev->irq.stat_regs.evergreen.d2grph_int & GRPH_PFLIP_INT_OCCURRED)
 		WREG32(GRPH_INT_STATUS + EVERGREEN_CRTC1_REGISTER_OFFSET, GRPH_PFLIP_INT_CLEAR);
-	if (rdev->irq.stat_regs.evergreen.d3grph_int & GRPH_PFLIP_INT_OCCURRED)
-		WREG32(GRPH_INT_STATUS + EVERGREEN_CRTC2_REGISTER_OFFSET, GRPH_PFLIP_INT_CLEAR);
-	if (rdev->irq.stat_regs.evergreen.d4grph_int & GRPH_PFLIP_INT_OCCURRED)
-		WREG32(GRPH_INT_STATUS + EVERGREEN_CRTC3_REGISTER_OFFSET, GRPH_PFLIP_INT_CLEAR);
-	if (rdev->irq.stat_regs.evergreen.d5grph_int & GRPH_PFLIP_INT_OCCURRED)
-		WREG32(GRPH_INT_STATUS + EVERGREEN_CRTC4_REGISTER_OFFSET, GRPH_PFLIP_INT_CLEAR);
-	if (rdev->irq.stat_regs.evergreen.d6grph_int & GRPH_PFLIP_INT_OCCURRED)
-		WREG32(GRPH_INT_STATUS + EVERGREEN_CRTC5_REGISTER_OFFSET, GRPH_PFLIP_INT_CLEAR);
-
 	if (rdev->irq.stat_regs.evergreen.disp_int & LB_D1_VBLANK_INTERRUPT)
 		WREG32(VBLANK_STATUS + EVERGREEN_CRTC0_REGISTER_OFFSET, VBLANK_ACK);
 	if (rdev->irq.stat_regs.evergreen.disp_int & LB_D1_VLINE_INTERRUPT)
 		WREG32(VLINE_STATUS + EVERGREEN_CRTC0_REGISTER_OFFSET, VLINE_ACK);
-
 	if (rdev->irq.stat_regs.evergreen.disp_int_cont & LB_D2_VBLANK_INTERRUPT)
 		WREG32(VBLANK_STATUS + EVERGREEN_CRTC1_REGISTER_OFFSET, VBLANK_ACK);
 	if (rdev->irq.stat_regs.evergreen.disp_int_cont & LB_D2_VLINE_INTERRUPT)
 		WREG32(VLINE_STATUS + EVERGREEN_CRTC1_REGISTER_OFFSET, VLINE_ACK);
 
-	if (rdev->irq.stat_regs.evergreen.disp_int_cont2 & LB_D3_VBLANK_INTERRUPT)
-		WREG32(VBLANK_STATUS + EVERGREEN_CRTC2_REGISTER_OFFSET, VBLANK_ACK);
-	if (rdev->irq.stat_regs.evergreen.disp_int_cont2 & LB_D3_VLINE_INTERRUPT)
-		WREG32(VLINE_STATUS + EVERGREEN_CRTC2_REGISTER_OFFSET, VLINE_ACK);
-
-	if (rdev->irq.stat_regs.evergreen.disp_int_cont3 & LB_D4_VBLANK_INTERRUPT)
-		WREG32(VBLANK_STATUS + EVERGREEN_CRTC3_REGISTER_OFFSET, VBLANK_ACK);
-	if (rdev->irq.stat_regs.evergreen.disp_int_cont3 & LB_D4_VLINE_INTERRUPT)
-		WREG32(VLINE_STATUS + EVERGREEN_CRTC3_REGISTER_OFFSET, VLINE_ACK);
-
-	if (rdev->irq.stat_regs.evergreen.disp_int_cont4 & LB_D5_VBLANK_INTERRUPT)
-		WREG32(VBLANK_STATUS + EVERGREEN_CRTC4_REGISTER_OFFSET, VBLANK_ACK);
-	if (rdev->irq.stat_regs.evergreen.disp_int_cont4 & LB_D5_VLINE_INTERRUPT)
-		WREG32(VLINE_STATUS + EVERGREEN_CRTC4_REGISTER_OFFSET, VLINE_ACK);
+	if (rdev->num_crtc >= 4) {
+		if (rdev->irq.stat_regs.evergreen.d3grph_int & GRPH_PFLIP_INT_OCCURRED)
+			WREG32(GRPH_INT_STATUS + EVERGREEN_CRTC2_REGISTER_OFFSET, GRPH_PFLIP_INT_CLEAR);
+		if (rdev->irq.stat_regs.evergreen.d4grph_int & GRPH_PFLIP_INT_OCCURRED)
+			WREG32(GRPH_INT_STATUS + EVERGREEN_CRTC3_REGISTER_OFFSET, GRPH_PFLIP_INT_CLEAR);
+		if (rdev->irq.stat_regs.evergreen.disp_int_cont2 & LB_D3_VBLANK_INTERRUPT)
+			WREG32(VBLANK_STATUS + EVERGREEN_CRTC2_REGISTER_OFFSET, VBLANK_ACK);
+		if (rdev->irq.stat_regs.evergreen.disp_int_cont2 & LB_D3_VLINE_INTERRUPT)
+			WREG32(VLINE_STATUS + EVERGREEN_CRTC2_REGISTER_OFFSET, VLINE_ACK);
+		if (rdev->irq.stat_regs.evergreen.disp_int_cont3 & LB_D4_VBLANK_INTERRUPT)
+			WREG32(VBLANK_STATUS + EVERGREEN_CRTC3_REGISTER_OFFSET, VBLANK_ACK);
+		if (rdev->irq.stat_regs.evergreen.disp_int_cont3 & LB_D4_VLINE_INTERRUPT)
+			WREG32(VLINE_STATUS + EVERGREEN_CRTC3_REGISTER_OFFSET, VLINE_ACK);
+	}
 
-	if (rdev->irq.stat_regs.evergreen.disp_int_cont5 & LB_D6_VBLANK_INTERRUPT)
-		WREG32(VBLANK_STATUS + EVERGREEN_CRTC5_REGISTER_OFFSET, VBLANK_ACK);
-	if (rdev->irq.stat_regs.evergreen.disp_int_cont5 & LB_D6_VLINE_INTERRUPT)
-		WREG32(VLINE_STATUS + EVERGREEN_CRTC5_REGISTER_OFFSET, VLINE_ACK);
+	if (rdev->num_crtc >= 6) {
+		if (rdev->irq.stat_regs.evergreen.d5grph_int & GRPH_PFLIP_INT_OCCURRED)
+			WREG32(GRPH_INT_STATUS + EVERGREEN_CRTC4_REGISTER_OFFSET, GRPH_PFLIP_INT_CLEAR);
+		if (rdev->irq.stat_regs.evergreen.d6grph_int & GRPH_PFLIP_INT_OCCURRED)
+			WREG32(GRPH_INT_STATUS + EVERGREEN_CRTC5_REGISTER_OFFSET, GRPH_PFLIP_INT_CLEAR);
+		if (rdev->irq.stat_regs.evergreen.disp_int_cont4 & LB_D5_VBLANK_INTERRUPT)
+			WREG32(VBLANK_STATUS + EVERGREEN_CRTC4_REGISTER_OFFSET, VBLANK_ACK);
+		if (rdev->irq.stat_regs.evergreen.disp_int_cont4 & LB_D5_VLINE_INTERRUPT)
+			WREG32(VLINE_STATUS + EVERGREEN_CRTC4_REGISTER_OFFSET, VLINE_ACK);
+		if (rdev->irq.stat_regs.evergreen.disp_int_cont5 & LB_D6_VBLANK_INTERRUPT)
+			WREG32(VBLANK_STATUS + EVERGREEN_CRTC5_REGISTER_OFFSET, VBLANK_ACK);
+		if (rdev->irq.stat_regs.evergreen.disp_int_cont5 & LB_D6_VLINE_INTERRUPT)
+			WREG32(VLINE_STATUS + EVERGREEN_CRTC5_REGISTER_OFFSET, VLINE_ACK);
+	}
 
 	if (rdev->irq.stat_regs.evergreen.disp_int & DC_HPD1_INTERRUPT) {
 		tmp = RREG32(DC_HPD1_INT_CONTROL);
@@ -2610,28 +2741,25 @@
 
 int evergreen_irq_process(struct radeon_device *rdev)
 {
-	u32 wptr = evergreen_get_ih_wptr(rdev);
-	u32 rptr = rdev->ih.rptr;
+	u32 wptr;
+	u32 rptr;
 	u32 src_id, src_data;
 	u32 ring_index;
 	unsigned long flags;
 	bool queue_hotplug = false;
 
-	DRM_DEBUG("r600_irq_process start: rptr %d, wptr %d\n", rptr, wptr);
-	if (!rdev->ih.enabled)
+	if (!rdev->ih.enabled || rdev->shutdown)
 		return IRQ_NONE;
 
-	spin_lock_irqsave(&rdev->ih.lock, flags);
+	wptr = evergreen_get_ih_wptr(rdev);
+	rptr = rdev->ih.rptr;
+	DRM_DEBUG("r600_irq_process start: rptr %d, wptr %d\n", rptr, wptr);
 
+	spin_lock_irqsave(&rdev->ih.lock, flags);
 	if (rptr == wptr) {
 		spin_unlock_irqrestore(&rdev->ih.lock, flags);
 		return IRQ_NONE;
 	}
-	if (rdev->shutdown) {
-		spin_unlock_irqrestore(&rdev->ih.lock, flags);
-		return IRQ_NONE;
-	}
-
 restart_ih:
 	/* display interrupts */
 	evergreen_irq_ack(rdev);
@@ -2860,7 +2988,7 @@
 			radeon_fence_process(rdev);
 			break;
 		case 233: /* GUI IDLE */
-			DRM_DEBUG("IH: CP EOP\n");
+			DRM_DEBUG("IH: GUI idle\n");
 			rdev->pm.gui_idle = true;
 			wake_up(&rdev->irq.idle_queue);
 			break;
@@ -3146,6 +3274,7 @@
 	r700_cp_fini(rdev);
 	r600_irq_fini(rdev);
 	radeon_wb_fini(rdev);
+	radeon_ib_pool_fini(rdev);
 	radeon_irq_kms_fini(rdev);
 	evergreen_pcie_gart_fini(rdev);
 	radeon_gem_fini(rdev);
diff -druN linux-2.6.39-libre/drivers/gpu/drm/radeon/evergreend.h linux-3.0-rc7-libre/drivers/gpu/drm/radeon/evergreend.h
--- linux-2.6.39-libre/drivers/gpu/drm/radeon/evergreend.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/gpu/drm/radeon/evergreend.h	2011-07-11 19:51:52.000000000 -0400
@@ -64,6 +64,8 @@
 #define GB_BACKEND_MAP  				0x98FC
 #define DMIF_ADDR_CONFIG  				0xBD4
 #define HDP_ADDR_CONFIG  				0x2F48
+#define HDP_MISC_CNTL  					0x2F4C
+#define		HDP_FLUSH_INVALIDATE_CACHE      	(1 << 0)
 
 #define	CC_SYS_RB_BACKEND_DISABLE			0x3F88
 #define	GC_USER_RB_BACKEND_DISABLE			0x9B7C
@@ -166,10 +168,16 @@
 #define		SE_DB_BUSY					(1 << 30)
 #define		SE_CB_BUSY					(1 << 31)
 /* evergreen */
+#define	CG_THERMAL_CTRL					0x72c
+#define		TOFFSET_MASK			        0x00003FE0
+#define		TOFFSET_SHIFT			        5
 #define	CG_MULT_THERMAL_STATUS				0x740
 #define		ASIC_T(x)			        ((x) << 16)
-#define		ASIC_T_MASK			        0x7FF0000
+#define		ASIC_T_MASK			        0x07FF0000
 #define		ASIC_T_SHIFT			        16
+#define	CG_TS0_STATUS					0x760
+#define		TS0_ADC_DOUT_MASK			0x000003FF
+#define		TS0_ADC_DOUT_SHIFT			0
 /* APU */
 #define	CG_THERMAL_STATUS			        0x678
 
@@ -458,7 +466,7 @@
 #define IH_RB_WPTR_ADDR_LO                                0x3e14
 #define IH_CNTL                                           0x3e18
 #       define ENABLE_INTR                                (1 << 0)
-#       define IH_MC_SWAP(x)                              ((x) << 2)
+#       define IH_MC_SWAP(x)                              ((x) << 1)
 #       define IH_MC_SWAP_NONE                            0
 #       define IH_MC_SWAP_16BIT                           1
 #       define IH_MC_SWAP_32BIT                           2
@@ -539,7 +547,7 @@
 #       define LB_D5_VBLANK_INTERRUPT                   (1 << 3)
 #       define DC_HPD5_INTERRUPT                        (1 << 17)
 #       define DC_HPD5_RX_INTERRUPT                     (1 << 18)
-#define DISP_INTERRUPT_STATUS_CONTINUE5                 0x6050
+#define DISP_INTERRUPT_STATUS_CONTINUE5                 0x6150
 #       define LB_D6_VLINE_INTERRUPT                    (1 << 2)
 #       define LB_D6_VBLANK_INTERRUPT                   (1 << 3)
 #       define DC_HPD6_INTERRUPT                        (1 << 17)
diff -druN linux-2.6.39-libre/drivers/gpu/drm/radeon/Kconfig linux-3.0-rc7-libre/drivers/gpu/drm/radeon/Kconfig
--- linux-2.6.39-libre/drivers/gpu/drm/radeon/Kconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/gpu/drm/radeon/Kconfig	2011-07-11 19:51:52.000000000 -0400
@@ -28,11 +28,4 @@
 	  The kernel will also perform security check on command stream
 	  provided by the user, we want to catch and forbid any illegal use
 	  of the GPU such as DMA into random system memory or into memory
-	  not owned by the process supplying the command stream. This part
-	  of the code is still incomplete and this why we propose that patch
-	  as a staging driver addition, future security might forbid current
-	  experimental userspace to run.
-
-	  This code support the following hardware : R1XX,R2XX,R3XX,R4XX,R5XX
-	  (radeon up to X1950). Works is underway to provide support for R6XX,
-	  R7XX and newer hardware (radeon from HD2XXX to HD4XXX).
+	  not owned by the process supplying the command stream.
diff -druN linux-2.6.39-libre/drivers/gpu/drm/radeon/ni.c linux-3.0-rc7-libre/drivers/gpu/drm/radeon/ni.c
--- linux-2.6.39-libre/drivers/gpu/drm/radeon/ni.c	2011-05-19 02:08:13.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/gpu/drm/radeon/ni.c	2011-07-21 06:50:23.000000000 -0400
@@ -376,7 +376,7 @@
 		num_shader_engines = 1;
 	if (num_shader_engines > rdev->config.cayman.max_shader_engines)
 		num_shader_engines = rdev->config.cayman.max_shader_engines;
-	if (num_backends_per_asic > num_shader_engines)
+	if (num_backends_per_asic < num_shader_engines)
 		num_backends_per_asic = num_shader_engines;
 	if (num_backends_per_asic > (rdev->config.cayman.max_backends_per_se * num_shader_engines))
 		num_backends_per_asic = rdev->config.cayman.max_backends_per_se * num_shader_engines;
@@ -788,7 +788,7 @@
 	rdev->config.cayman.tile_config |=
 		((mc_arb_ramcfg & NOOFBANK_MASK) >> NOOFBANK_SHIFT) << 4;
 	rdev->config.cayman.tile_config |=
-		(gb_addr_config & PIPE_INTERLEAVE_SIZE_MASK) >> PIPE_INTERLEAVE_SIZE_SHIFT;
+		((gb_addr_config & PIPE_INTERLEAVE_SIZE_MASK) >> PIPE_INTERLEAVE_SIZE_SHIFT) << 8;
 	rdev->config.cayman.tile_config |=
 		((gb_addr_config & ROW_SIZE_MASK) >> ROW_SIZE_SHIFT) << 12;
 
@@ -890,6 +890,10 @@
 	WREG32(CB_PERF_CTR3_SEL_0, 0);
 	WREG32(CB_PERF_CTR3_SEL_1, 0);
 
+	tmp = RREG32(HDP_MISC_CNTL);
+	tmp |= HDP_FLUSH_INVALIDATE_CACHE;
+	WREG32(HDP_MISC_CNTL, tmp);
+
 	hdp_host_path_cntl = RREG32(HDP_HOST_PATH_CNTL);
 	WREG32(HDP_HOST_PATH_CNTL, hdp_host_path_cntl);
 
@@ -1342,14 +1346,12 @@
 		return r;
 	cayman_gpu_init(rdev);
 
-#if 0
-	r = cayman_blit_init(rdev);
+	r = evergreen_blit_init(rdev);
 	if (r) {
-		cayman_blit_fini(rdev);
+		evergreen_blit_fini(rdev);
 		rdev->asic->copy = NULL;
 		dev_warn(rdev->dev, "failed blitter (%d) falling back to memcpy\n", r);
 	}
-#endif
 
 	/* allocate wb buffer */
 	r = radeon_wb_init(rdev);
@@ -1407,7 +1409,7 @@
 
 int cayman_suspend(struct radeon_device *rdev)
 {
-	/* int r; */
+	int r;
 
 	/* FIXME: we should wait for ring to be empty */
 	cayman_cp_enable(rdev, false);
@@ -1416,14 +1418,13 @@
 	radeon_wb_disable(rdev);
 	cayman_pcie_gart_disable(rdev);
 
-#if 0
 	/* 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;
 }
 
@@ -1535,10 +1536,11 @@
 
 void cayman_fini(struct radeon_device *rdev)
 {
-	/* cayman_blit_fini(rdev); */
+	evergreen_blit_fini(rdev);
 	cayman_cp_fini(rdev);
 	r600_irq_fini(rdev);
 	radeon_wb_fini(rdev);
+	radeon_ib_pool_fini(rdev);
 	radeon_irq_kms_fini(rdev);
 	cayman_pcie_gart_fini(rdev);
 	radeon_gem_fini(rdev);
diff -druN linux-2.6.39-libre/drivers/gpu/drm/radeon/nid.h linux-3.0-rc7-libre/drivers/gpu/drm/radeon/nid.h
--- linux-2.6.39-libre/drivers/gpu/drm/radeon/nid.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/gpu/drm/radeon/nid.h	2011-07-11 19:51:52.000000000 -0400
@@ -136,6 +136,8 @@
 #define	HDP_NONSURFACE_INFO				0x2C08
 #define	HDP_NONSURFACE_SIZE				0x2C0C
 #define HDP_ADDR_CONFIG  				0x2F48
+#define HDP_MISC_CNTL					0x2F4C
+#define 	HDP_FLUSH_INVALIDATE_CACHE			(1 << 0)
 
 #define	CC_SYS_RB_BACKEND_DISABLE			0x3F88
 #define	GC_USER_SYS_RB_BACKEND_DISABLE			0x3F8C
@@ -318,7 +320,7 @@
 #define	CGTS_USER_TCC_DISABLE				0x914C
 #define		TCC_DISABLE_MASK				0xFFFF0000
 #define		TCC_DISABLE_SHIFT				16
-#define	CGTS_SM_CTRL_REG				0x915C
+#define	CGTS_SM_CTRL_REG				0x9150
 #define		OVERRIDE				(1 << 21)
 
 #define	TA_CNTL_AUX					0x9508
@@ -351,7 +353,7 @@
 #define		MULTI_GPU_TILE_SIZE_MASK		0x03000000
 #define		MULTI_GPU_TILE_SIZE_SHIFT		24
 #define		ROW_SIZE(x)             		((x) << 28)
-#define		ROW_SIZE_MASK				0x30000007
+#define		ROW_SIZE_MASK				0x30000000
 #define		ROW_SIZE_SHIFT				28
 #define		NUM_LOWER_PIPES(x)			((x) << 30)
 #define		NUM_LOWER_PIPES_MASK			0x40000000
diff -druN linux-2.6.39-libre/drivers/gpu/drm/radeon/r100_track.h linux-3.0-rc7-libre/drivers/gpu/drm/radeon/r100_track.h
--- linux-2.6.39-libre/drivers/gpu/drm/radeon/r100_track.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/gpu/drm/radeon/r100_track.h	2011-07-11 19:51:52.000000000 -0400
@@ -63,7 +63,7 @@
 	unsigned			num_arrays;
 	unsigned			max_indx;
 	unsigned			color_channel_mask;
-	struct r100_cs_track_array	arrays[11];
+	struct r100_cs_track_array	arrays[16];
 	struct r100_cs_track_cb 	cb[R300_MAX_CB];
 	struct r100_cs_track_cb 	zb;
 	struct r100_cs_track_cb 	aa;
@@ -146,6 +146,12 @@
 	ib = p->ib->ptr;
 	track = (struct r100_cs_track *)p->track;
 	c = radeon_get_ib_value(p, idx++) & 0x1F;
+	if (c > 16) {
+	    DRM_ERROR("Only 16 vertex buffers are allowed %d\n",
+		      pkt->opcode);
+	    r100_cs_dump_packet(p, pkt);
+	    return -EINVAL;
+	}
 	track->num_arrays = c;
 	for (i = 0; i < (c - 1); i+=2, idx+=3) {
 		r = r100_cs_packet_next_reloc(p, &reloc);
diff -druN linux-2.6.39-libre/drivers/gpu/drm/radeon/r600.c linux-3.0-rc7-libre/drivers/gpu/drm/radeon/r600.c
--- linux-2.6.39-libre/drivers/gpu/drm/radeon/r600.c	2011-05-19 02:08:08.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/gpu/drm/radeon/r600.c	2011-07-21 06:50:17.000000000 -0400
@@ -550,6 +550,9 @@
 	struct radeon_voltage *voltage = &ps->clock_info[req_cm_idx].voltage;
 
 	if ((voltage->type == VOLTAGE_SW) && voltage->voltage) {
+		/* 0xff01 is a flag rather then an actual voltage */
+		if (voltage->voltage == 0xff01)
+			return;
 		if (voltage->voltage != rdev->pm.current_vddc) {
 			radeon_atom_set_voltage(rdev, voltage->voltage, SET_VOLTAGE_TYPE_ASIC_VDDC);
 			rdev->pm.current_vddc = voltage->voltage;
@@ -1988,6 +1991,14 @@
 		chip_name = "PALM";
 		rlc_chip_name = "SUMO";
 		break;
+	case CHIP_SUMO:
+		chip_name = "SUMO";
+		rlc_chip_name = "SUMO";
+		break;
+	case CHIP_SUMO2:
+		chip_name = "SUMO2";
+		rlc_chip_name = "SUMO";
+		break;
 	default: BUG();
 	}
 
@@ -2577,6 +2588,7 @@
 	r600_cp_fini(rdev);
 	r600_irq_fini(rdev);
 	radeon_wb_fini(rdev);
+	radeon_ib_pool_fini(rdev);
 	radeon_irq_kms_fini(rdev);
 	r600_pcie_gart_fini(rdev);
 	radeon_agp_fini(rdev);
@@ -3246,27 +3258,26 @@
 
 int r600_irq_process(struct radeon_device *rdev)
 {
-	u32 wptr = r600_get_ih_wptr(rdev);
-	u32 rptr = rdev->ih.rptr;
+	u32 wptr;
+	u32 rptr;
 	u32 src_id, src_data;
 	u32 ring_index;
 	unsigned long flags;
 	bool queue_hotplug = false;
 
-	DRM_DEBUG("r600_irq_process start: rptr %d, wptr %d\n", rptr, wptr);
-	if (!rdev->ih.enabled)
+	if (!rdev->ih.enabled || rdev->shutdown)
 		return IRQ_NONE;
 
+	wptr = r600_get_ih_wptr(rdev);
+	rptr = rdev->ih.rptr;
+	DRM_DEBUG("r600_irq_process start: rptr %d, wptr %d\n", rptr, wptr);
+
 	spin_lock_irqsave(&rdev->ih.lock, flags);
 
 	if (rptr == wptr) {
 		spin_unlock_irqrestore(&rdev->ih.lock, flags);
 		return IRQ_NONE;
 	}
-	if (rdev->shutdown) {
-		spin_unlock_irqrestore(&rdev->ih.lock, flags);
-		return IRQ_NONE;
-	}
 
 restart_ih:
 	/* display interrupts */
@@ -3396,7 +3407,7 @@
 			radeon_fence_process(rdev);
 			break;
 		case 233: /* GUI IDLE */
-			DRM_DEBUG("IH: CP EOP\n");
+			DRM_DEBUG("IH: GUI idle\n");
 			rdev->pm.gui_idle = true;
 			wake_up(&rdev->irq.idle_queue);
 			break;
diff -druN linux-2.6.39-libre/drivers/gpu/drm/radeon/r600_cs.c linux-3.0-rc7-libre/drivers/gpu/drm/radeon/r600_cs.c
--- linux-2.6.39-libre/drivers/gpu/drm/radeon/r600_cs.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/gpu/drm/radeon/r600_cs.c	2011-07-11 19:51:52.000000000 -0400
@@ -71,20 +71,21 @@
 	u64			db_bo_mc;
 };
 
-#define FMT_8_BIT(fmt, vc) [fmt] = { 1, 1, 1, vc }
-#define FMT_16_BIT(fmt, vc) [fmt] = { 1, 1, 2, vc }
-#define FMT_24_BIT(fmt) [fmt] = { 1, 1, 3, 0 }
-#define FMT_32_BIT(fmt, vc) [fmt] = { 1, 1, 4, vc }
-#define FMT_48_BIT(fmt) [fmt] = { 1, 1, 6, 0 }
-#define FMT_64_BIT(fmt, vc) [fmt] = { 1, 1, 8, vc }
-#define FMT_96_BIT(fmt) [fmt] = { 1, 1, 12, 0 }
-#define FMT_128_BIT(fmt, vc) [fmt] = { 1, 1, 16, vc }
+#define FMT_8_BIT(fmt, vc)   [fmt] = { 1, 1, 1, vc, CHIP_R600 }
+#define FMT_16_BIT(fmt, vc)  [fmt] = { 1, 1, 2, vc, CHIP_R600 }
+#define FMT_24_BIT(fmt)      [fmt] = { 1, 1, 3,  0, CHIP_R600 }
+#define FMT_32_BIT(fmt, vc)  [fmt] = { 1, 1, 4, vc, CHIP_R600 }
+#define FMT_48_BIT(fmt)      [fmt] = { 1, 1, 6,  0, CHIP_R600 }
+#define FMT_64_BIT(fmt, vc)  [fmt] = { 1, 1, 8, vc, CHIP_R600 }
+#define FMT_96_BIT(fmt)      [fmt] = { 1, 1, 12, 0, CHIP_R600 }
+#define FMT_128_BIT(fmt, vc) [fmt] = { 1, 1, 16,vc, CHIP_R600 }
 
 struct gpu_formats {
 	unsigned blockwidth;
 	unsigned blockheight;
 	unsigned blocksize;
 	unsigned valid_color;
+	enum radeon_family min_family;
 };
 
 static const struct gpu_formats color_formats_table[] = {
@@ -154,7 +155,11 @@
 	[V_038004_FMT_BC3] = { 4, 4, 16, 0 },
 	[V_038004_FMT_BC4] = { 4, 4, 8, 0 },
 	[V_038004_FMT_BC5] = { 4, 4, 16, 0},
+	[V_038004_FMT_BC6] = { 4, 4, 16, 0, CHIP_CEDAR}, /* Evergreen-only */
+	[V_038004_FMT_BC7] = { 4, 4, 16, 0, CHIP_CEDAR}, /* Evergreen-only */
 
+	/* The other Evergreen formats */
+	[V_038004_FMT_32_AS_32_32_32_32] = { 1, 1, 4, 0, CHIP_CEDAR},
 };
 
 static inline bool fmt_is_valid_color(u32 format)
@@ -168,11 +173,14 @@
 	return false;
 }
 
-static inline bool fmt_is_valid_texture(u32 format)
+static inline bool fmt_is_valid_texture(u32 format, enum radeon_family family)
 {
 	if (format >= ARRAY_SIZE(color_formats_table))
 		return false;
 	
+	if (family < color_formats_table[format].min_family)
+		return false;
+
 	if (color_formats_table[format].blockwidth > 0)
 		return true;
 
@@ -1325,7 +1333,7 @@
 		return -EINVAL;
 	}
 	format = G_038004_DATA_FORMAT(word1);
-	if (!fmt_is_valid_texture(format)) {
+	if (!fmt_is_valid_texture(format, p->family)) {
 		dev_warn(p->dev, "%s:%d texture invalid format %d\n",
 			 __func__, __LINE__, format);
 		return -EINVAL;
diff -druN linux-2.6.39-libre/drivers/gpu/drm/radeon/r600d.h linux-3.0-rc7-libre/drivers/gpu/drm/radeon/r600d.h
--- linux-2.6.39-libre/drivers/gpu/drm/radeon/r600d.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/gpu/drm/radeon/r600d.h	2011-07-11 19:51:52.000000000 -0400
@@ -536,7 +536,7 @@
 #define IH_RB_WPTR_ADDR_LO                                0x3e14
 #define IH_CNTL                                           0x3e18
 #       define ENABLE_INTR                                (1 << 0)
-#       define IH_MC_SWAP(x)                              ((x) << 2)
+#       define IH_MC_SWAP(x)                              ((x) << 1)
 #       define IH_MC_SWAP_NONE                            0
 #       define IH_MC_SWAP_16BIT                           1
 #       define IH_MC_SWAP_32BIT                           2
@@ -1309,6 +1309,9 @@
 #define     V_038004_FMT_BC3                           0x00000033
 #define     V_038004_FMT_BC4                           0x00000034
 #define     V_038004_FMT_BC5                           0x00000035
+#define     V_038004_FMT_BC6                           0x00000036
+#define     V_038004_FMT_BC7                           0x00000037
+#define     V_038004_FMT_32_AS_32_32_32_32             0x00000038
 #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)
diff -druN linux-2.6.39-libre/drivers/gpu/drm/radeon/radeon_asic.c linux-3.0-rc7-libre/drivers/gpu/drm/radeon/radeon_asic.c
--- linux-2.6.39-libre/drivers/gpu/drm/radeon/radeon_asic.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/gpu/drm/radeon/radeon_asic.c	2011-07-11 19:51:52.000000000 -0400
@@ -782,6 +782,7 @@
 	.hpd_fini = &evergreen_hpd_fini,
 	.hpd_sense = &evergreen_hpd_sense,
 	.hpd_set_polarity = &evergreen_hpd_set_polarity,
+	.ioctl_wait_idle = r600_ioctl_wait_idle,
 	.gui_idle = &r600_gui_idle,
 	.pm_misc = &evergreen_pm_misc,
 	.pm_prepare = &evergreen_pm_prepare,
@@ -828,6 +829,7 @@
 	.hpd_fini = &evergreen_hpd_fini,
 	.hpd_sense = &evergreen_hpd_sense,
 	.hpd_set_polarity = &evergreen_hpd_set_polarity,
+	.ioctl_wait_idle = r600_ioctl_wait_idle,
 	.gui_idle = &r600_gui_idle,
 	.pm_misc = &evergreen_pm_misc,
 	.pm_prepare = &evergreen_pm_prepare,
@@ -874,6 +876,7 @@
 	.hpd_fini = &evergreen_hpd_fini,
 	.hpd_sense = &evergreen_hpd_sense,
 	.hpd_set_polarity = &evergreen_hpd_set_polarity,
+	.ioctl_wait_idle = r600_ioctl_wait_idle,
 	.gui_idle = &r600_gui_idle,
 	.pm_misc = &evergreen_pm_misc,
 	.pm_prepare = &evergreen_pm_prepare,
@@ -903,9 +906,9 @@
 	.get_vblank_counter = &evergreen_get_vblank_counter,
 	.fence_ring_emit = &r600_fence_ring_emit,
 	.cs_parse = &evergreen_cs_parse,
-	.copy_blit = NULL,
-	.copy_dma = NULL,
-	.copy = NULL,
+	.copy_blit = &evergreen_copy_blit,
+	.copy_dma = &evergreen_copy_blit,
+	.copy = &evergreen_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,
@@ -920,6 +923,7 @@
 	.hpd_fini = &evergreen_hpd_fini,
 	.hpd_sense = &evergreen_hpd_sense,
 	.hpd_set_polarity = &evergreen_hpd_set_polarity,
+	.ioctl_wait_idle = r600_ioctl_wait_idle,
 	.gui_idle = &r600_gui_idle,
 	.pm_misc = &evergreen_pm_misc,
 	.pm_prepare = &evergreen_pm_prepare,
@@ -934,6 +938,13 @@
 int radeon_asic_init(struct radeon_device *rdev)
 {
 	radeon_register_accessor_init(rdev);
+
+	/* set the number of crtcs */
+	if (rdev->flags & RADEON_SINGLE_CRTC)
+		rdev->num_crtc = 1;
+	else
+		rdev->num_crtc = 2;
+
 	switch (rdev->family) {
 	case CHIP_R100:
 	case CHIP_RV100:
@@ -1013,18 +1024,32 @@
 	case CHIP_JUNIPER:
 	case CHIP_CYPRESS:
 	case CHIP_HEMLOCK:
+		/* set num crtcs */
+		if (rdev->family == CHIP_CEDAR)
+			rdev->num_crtc = 4;
+		else
+			rdev->num_crtc = 6;
 		rdev->asic = &evergreen_asic;
 		break;
 	case CHIP_PALM:
+	case CHIP_SUMO:
+	case CHIP_SUMO2:
 		rdev->asic = &sumo_asic;
 		break;
 	case CHIP_BARTS:
 	case CHIP_TURKS:
 	case CHIP_CAICOS:
+		/* set num crtcs */
+		if (rdev->family == CHIP_CAICOS)
+			rdev->num_crtc = 4;
+		else
+			rdev->num_crtc = 6;
 		rdev->asic = &btc_asic;
 		break;
 	case CHIP_CAYMAN:
 		rdev->asic = &cayman_asic;
+		/* set num crtcs */
+		rdev->num_crtc = 6;
 		break;
 	default:
 		/* FIXME: not supported yet */
@@ -1036,18 +1061,6 @@
 		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_DCE41(rdev))
-			rdev->num_crtc = 2;
-		else if (ASIC_IS_DCE4(rdev))
-			rdev->num_crtc = 6;
-		else
-			rdev->num_crtc = 2;
-	}
-
 	return 0;
 }
 
diff -druN linux-2.6.39-libre/drivers/gpu/drm/radeon/radeon_atombios.c linux-3.0-rc7-libre/drivers/gpu/drm/radeon/radeon_atombios.c
--- linux-2.6.39-libre/drivers/gpu/drm/radeon/radeon_atombios.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/gpu/drm/radeon/radeon_atombios.c	2011-07-11 19:51:52.000000000 -0400
@@ -1246,6 +1246,10 @@
 		}
 		*dcpll = *p1pll;
 
+		rdev->clock.max_pixel_clock = le16_to_cpu(firmware_info->info.usMaxPixelClock);
+		if (rdev->clock.max_pixel_clock == 0)
+			rdev->clock.max_pixel_clock = 40000;
+
 		return true;
 	}
 
@@ -2316,6 +2320,14 @@
 			le16_to_cpu(clock_info->r600.usVDDC);
 	}
 
+	/* patch up vddc if necessary */
+	if (rdev->pm.power_state[state_index].clock_info[mode_index].voltage.voltage == 0xff01) {
+		u16 vddc;
+
+		if (radeon_atom_get_max_vddc(rdev, &vddc) == 0)
+			rdev->pm.power_state[state_index].clock_info[mode_index].voltage.voltage = vddc;
+	}
+
 	if (rdev->flags & RADEON_IS_IGP) {
 		/* skip invalid modes */
 		if (rdev->pm.power_state[state_index].clock_info[mode_index].sclk == 0)
@@ -2603,6 +2615,10 @@
 	if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev))
 		return;
 
+	/* 0xff01 is a flag rather then an actual voltage */
+	if (voltage_level == 0xff01)
+		return;
+
 	switch (crev) {
 	case 1:
 		args.v1.ucVoltageType = voltage_type;
@@ -2622,7 +2638,35 @@
 	atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
 }
 
+int radeon_atom_get_max_vddc(struct radeon_device *rdev,
+			     u16 *voltage)
+{
+	union set_voltage args;
+	int index = GetIndexIntoMasterTable(COMMAND, SetVoltage);
+	u8 frev, crev;
+
+	if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev))
+		return -EINVAL;
+
+	switch (crev) {
+	case 1:
+		return -EINVAL;
+	case 2:
+		args.v2.ucVoltageType = SET_VOLTAGE_GET_MAX_VOLTAGE;
+		args.v2.ucVoltageMode = 0;
+		args.v2.usVoltageLevel = 0;
+
+		atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
 
+		*voltage = le16_to_cpu(args.v2.usVoltageLevel);
+		break;
+	default:
+		DRM_ERROR("Unknown table version %d, %d\n", frev, crev);
+		return -EINVAL;
+	}
+
+	return 0;
+}
 
 void radeon_atom_initialize_bios_scratch_regs(struct drm_device *dev)
 {
diff -druN linux-2.6.39-libre/drivers/gpu/drm/radeon/radeon_bios.c linux-3.0-rc7-libre/drivers/gpu/drm/radeon/radeon_bios.c
--- linux-2.6.39-libre/drivers/gpu/drm/radeon/radeon_bios.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/gpu/drm/radeon/radeon_bios.c	2011-07-11 19:51:52.000000000 -0400
@@ -104,7 +104,7 @@
 static bool radeon_atrm_get_bios(struct radeon_device *rdev)
 {
 	int ret;
-	int size = 64 * 1024;
+	int size = 256 * 1024;
 	int i;
 
 	if (!radeon_atrm_supported(rdev->pdev))
diff -druN linux-2.6.39-libre/drivers/gpu/drm/radeon/radeon_clocks.c linux-3.0-rc7-libre/drivers/gpu/drm/radeon/radeon_clocks.c
--- linux-2.6.39-libre/drivers/gpu/drm/radeon/radeon_clocks.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/gpu/drm/radeon/radeon_clocks.c	2011-07-11 19:51:52.000000000 -0400
@@ -117,7 +117,7 @@
 	p1pll->reference_div = RREG32_PLL(RADEON_PPLL_REF_DIV) & 0x3ff;
 	if (p1pll->reference_div < 2)
 		p1pll->reference_div = 12;
-	p2pll->reference_div = p1pll->reference_div;	
+	p2pll->reference_div = p1pll->reference_div;
 
 	/* These aren't in the device-tree */
 	if (rdev->family >= CHIP_R420) {
@@ -139,6 +139,8 @@
 		p2pll->pll_out_min = 12500;
 		p2pll->pll_out_max = 35000;
 	}
+	/* not sure what the max should be in all cases */
+	rdev->clock.max_pixel_clock = 35000;
 
 	spll->reference_freq = mpll->reference_freq = p1pll->reference_freq;
 	spll->reference_div = mpll->reference_div =
@@ -151,7 +153,7 @@
 	else
 		rdev->clock.default_sclk =
 			radeon_legacy_get_engine_clock(rdev);
-			
+
 	val = of_get_property(dp, "ATY,MCLK", NULL);
 	if (val && *val)
 		rdev->clock.default_mclk = (*val) / 10;
@@ -160,7 +162,7 @@
 			radeon_legacy_get_memory_clock(rdev);
 
 	DRM_INFO("Using device-tree clock info\n");
-	
+
 	return true;
 }
 #else
diff -druN linux-2.6.39-libre/drivers/gpu/drm/radeon/radeon_combios.c linux-3.0-rc7-libre/drivers/gpu/drm/radeon/radeon_combios.c
--- linux-2.6.39-libre/drivers/gpu/drm/radeon/radeon_combios.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/gpu/drm/radeon/radeon_combios.c	2011-07-11 19:51:52.000000000 -0400
@@ -505,12 +505,18 @@
 	 * DDC_VGA           = RADEON_GPIO_VGA_DDC
 	 * DDC_LCD           = RADEON_GPIOPAD_MASK
 	 * DDC_GPIO          = RADEON_MDGPIO_MASK
-	 * r1xx/r2xx
+	 * r1xx
 	 * DDC_MONID         = RADEON_GPIO_MONID
 	 * DDC_CRT2          = RADEON_GPIO_CRT2_DDC
-	 * r3xx
+	 * r200
 	 * DDC_MONID         = RADEON_GPIO_MONID
 	 * DDC_CRT2          = RADEON_GPIO_DVI_DDC
+	 * r300/r350
+	 * DDC_MONID         = RADEON_GPIO_DVI_DDC
+	 * DDC_CRT2          = RADEON_GPIO_DVI_DDC
+	 * rv2xx/rv3xx
+	 * DDC_MONID         = RADEON_GPIO_MONID
+	 * DDC_CRT2          = RADEON_GPIO_MONID
 	 * rs3xx/rs4xx
 	 * DDC_MONID         = RADEON_GPIOPAD_MASK
 	 * DDC_CRT2          = RADEON_GPIO_MONID
@@ -537,17 +543,26 @@
 		    rdev->family == CHIP_RS400 ||
 		    rdev->family == CHIP_RS480)
 			ddc_line = RADEON_GPIOPAD_MASK;
-		else
+		else if (rdev->family == CHIP_R300 ||
+			 rdev->family == CHIP_R350) {
+			ddc_line = RADEON_GPIO_DVI_DDC;
+			ddc = DDC_DVI;
+		} else
 			ddc_line = RADEON_GPIO_MONID;
 		break;
 	case DDC_CRT2:
-		if (rdev->family == CHIP_RS300 ||
-		    rdev->family == CHIP_RS400 ||
-		    rdev->family == CHIP_RS480)
-			ddc_line = RADEON_GPIO_MONID;
-		else if (rdev->family >= CHIP_R300) {
+		if (rdev->family == CHIP_R200 ||
+		    rdev->family == CHIP_R300 ||
+		    rdev->family == CHIP_R350) {
 			ddc_line = RADEON_GPIO_DVI_DDC;
 			ddc = DDC_DVI;
+		} else if (rdev->family == CHIP_RS300 ||
+			   rdev->family == CHIP_RS400 ||
+			   rdev->family == CHIP_RS480)
+			ddc_line = RADEON_GPIO_MONID;
+		else if (rdev->family >= CHIP_RV350) {
+			ddc_line = RADEON_GPIO_MONID;
+			ddc = DDC_MONID;
 		} else
 			ddc_line = RADEON_GPIO_CRT2_DDC;
 		break;
@@ -709,26 +724,42 @@
 	struct drm_device *dev = rdev->ddev;
 	struct radeon_i2c_bus_rec i2c;
 
+	/* actual hw pads
+	 * r1xx/rs2xx/rs3xx
+	 * 0x60, 0x64, 0x68, 0x6c, gpiopads, mm
+	 * r200
+	 * 0x60, 0x64, 0x68, mm
+	 * r300/r350
+	 * 0x60, 0x64, mm
+	 * rv2xx/rv3xx/rs4xx
+	 * 0x60, 0x64, 0x68, gpiopads, mm
+	 */
 
+	/* 0x60 */
 	i2c = combios_setup_i2c_bus(rdev, DDC_DVI, 0, 0);
 	rdev->i2c_bus[0] = radeon_i2c_create(dev, &i2c, "DVI_DDC");
-
+	/* 0x64 */
 	i2c = combios_setup_i2c_bus(rdev, DDC_VGA, 0, 0);
 	rdev->i2c_bus[1] = radeon_i2c_create(dev, &i2c, "VGA_DDC");
 
+	/* mm i2c */
 	i2c.valid = true;
 	i2c.hw_capable = true;
 	i2c.mm_i2c = true;
 	i2c.i2c_id = 0xa0;
 	rdev->i2c_bus[2] = radeon_i2c_create(dev, &i2c, "MM_I2C");
 
-	if (rdev->family == CHIP_RS300 ||
-	    rdev->family == CHIP_RS400 ||
-	    rdev->family == CHIP_RS480) {
+	if (rdev->family == CHIP_R300 ||
+	    rdev->family == CHIP_R350) {
+		/* only 2 sw i2c pads */
+	} else if (rdev->family == CHIP_RS300 ||
+		   rdev->family == CHIP_RS400 ||
+		   rdev->family == CHIP_RS480) {
 		u16 offset;
 		u8 id, blocks, clk, data;
 		int i;
 
+		/* 0x68 */
 		i2c = combios_setup_i2c_bus(rdev, DDC_CRT2, 0, 0);
 		rdev->i2c_bus[3] = radeon_i2c_create(dev, &i2c, "MONID");
 
@@ -740,6 +771,7 @@
 				if (id == 136) {
 					clk = RBIOS8(offset + 3 + (i * 5) + 3);
 					data = RBIOS8(offset + 3 + (i * 5) + 4);
+					/* gpiopad */
 					i2c = combios_setup_i2c_bus(rdev, DDC_MONID,
 								    (1 << clk), (1 << data));
 					rdev->i2c_bus[4] = radeon_i2c_create(dev, &i2c, "GPIOPAD_MASK");
@@ -747,14 +779,15 @@
 				}
 			}
 		}
-
-	} else if (rdev->family >= CHIP_R300) {
+	} else if (rdev->family >= CHIP_R200) {
+		/* 0x68 */
 		i2c = combios_setup_i2c_bus(rdev, DDC_MONID, 0, 0);
 		rdev->i2c_bus[3] = radeon_i2c_create(dev, &i2c, "MONID");
 	} else {
+		/* 0x68 */
 		i2c = combios_setup_i2c_bus(rdev, DDC_MONID, 0, 0);
 		rdev->i2c_bus[3] = radeon_i2c_create(dev, &i2c, "MONID");
-
+		/* 0x6c */
 		i2c = combios_setup_i2c_bus(rdev, DDC_CRT2, 0, 0);
 		rdev->i2c_bus[4] = radeon_i2c_create(dev, &i2c, "CRT2_DDC");
 	}
@@ -833,6 +866,11 @@
 		rdev->clock.default_sclk = sclk;
 		rdev->clock.default_mclk = mclk;
 
+		if (RBIOS32(pll_info + 0x16))
+			rdev->clock.max_pixel_clock = RBIOS32(pll_info + 0x16);
+		else
+			rdev->clock.max_pixel_clock = 35000; /* might need something asic specific */
+
 		return true;
 	}
 	return false;
@@ -1515,10 +1553,12 @@
 			   (rdev->pdev->subsystem_device == 0x4a48)) {
 			/* Mac X800 */
 			rdev->mode_info.connector_table = CT_MAC_X800;
-		} else if ((rdev->pdev->device == 0x4150) &&
+		} else if ((of_machine_is_compatible("PowerMac7,2") ||
+			    of_machine_is_compatible("PowerMac7,3")) &&
+			   (rdev->pdev->device == 0x4150) &&
 			   (rdev->pdev->subsystem_vendor == 0x1002) &&
 			   (rdev->pdev->subsystem_device == 0x4150)) {
-			/* Mac G5 9600 */
+			/* Mac G5 tower 9600 */
 			rdev->mode_info.connector_table = CT_MAC_G5_9600;
 		} else
 #endif /* CONFIG_PPC_PMAC */
@@ -2504,6 +2544,12 @@
 	return true;
 }
 
+static const char *thermal_controller_names[] = {
+	"NONE",
+	"lm63",
+	"adm1032",
+};
+
 void radeon_combios_get_power_modes(struct radeon_device *rdev)
 {
 	struct drm_device *dev = rdev->ddev;
@@ -2524,6 +2570,54 @@
 		return;
 	}
 
+	/* check for a thermal chip */
+	offset = combios_get_table_offset(dev, COMBIOS_OVERDRIVE_INFO_TABLE);
+	if (offset) {
+		u8 thermal_controller = 0, gpio = 0, i2c_addr = 0, clk_bit = 0, data_bit = 0;
+		struct radeon_i2c_bus_rec i2c_bus;
+
+		rev = RBIOS8(offset);
+
+		if (rev == 0) {
+			thermal_controller = RBIOS8(offset + 3);
+			gpio = RBIOS8(offset + 4) & 0x3f;
+			i2c_addr = RBIOS8(offset + 5);
+		} else if (rev == 1) {
+			thermal_controller = RBIOS8(offset + 4);
+			gpio = RBIOS8(offset + 5) & 0x3f;
+			i2c_addr = RBIOS8(offset + 6);
+		} else if (rev == 2) {
+			thermal_controller = RBIOS8(offset + 4);
+			gpio = RBIOS8(offset + 5) & 0x3f;
+			i2c_addr = RBIOS8(offset + 6);
+			clk_bit = RBIOS8(offset + 0xa);
+			data_bit = RBIOS8(offset + 0xb);
+		}
+		if ((thermal_controller > 0) && (thermal_controller < 3)) {
+			DRM_INFO("Possible %s thermal controller at 0x%02x\n",
+				 thermal_controller_names[thermal_controller],
+				 i2c_addr >> 1);
+			if (gpio == DDC_LCD) {
+				/* MM i2c */
+				i2c_bus.valid = true;
+				i2c_bus.hw_capable = true;
+				i2c_bus.mm_i2c = true;
+				i2c_bus.i2c_id = 0xa0;
+			} else if (gpio == DDC_GPIO)
+				i2c_bus = combios_setup_i2c_bus(rdev, gpio, 1 << clk_bit, 1 << data_bit);
+			else
+				i2c_bus = combios_setup_i2c_bus(rdev, gpio, 0, 0);
+			rdev->pm.i2c_bus = radeon_i2c_lookup(rdev, &i2c_bus);
+			if (rdev->pm.i2c_bus) {
+				struct i2c_board_info info = { };
+				const char *name = thermal_controller_names[thermal_controller];
+				info.addr = i2c_addr >> 1;
+				strlcpy(info.type, name, sizeof(info.type));
+				i2c_new_device(&rdev->pm.i2c_bus->adapter, &info);
+			}
+		}
+	}
+
 	if (rdev->flags & RADEON_IS_MOBILITY) {
 		offset = combios_get_table_offset(dev, COMBIOS_POWERPLAY_INFO_TABLE);
 		if (offset) {
diff -druN linux-2.6.39-libre/drivers/gpu/drm/radeon/radeon_connectors.c linux-3.0-rc7-libre/drivers/gpu/drm/radeon/radeon_connectors.c
--- linux-2.6.39-libre/drivers/gpu/drm/radeon/radeon_connectors.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/gpu/drm/radeon/radeon_connectors.c	2011-07-11 19:51:52.000000000 -0400
@@ -44,26 +44,29 @@
 radeon_legacy_backlight_init(struct radeon_encoder *radeon_encoder,
 			     struct drm_connector *drm_connector);
 
+bool radeon_connector_encoder_is_dp_bridge(struct drm_connector *connector);
+
 void radeon_connector_hotplug(struct drm_connector *connector)
 {
 	struct drm_device *dev = connector->dev;
 	struct radeon_device *rdev = dev->dev_private;
 	struct radeon_connector *radeon_connector = to_radeon_connector(connector);
 
-	if (radeon_connector->hpd.hpd != RADEON_HPD_NONE)
-		radeon_hpd_set_polarity(rdev, radeon_connector->hpd.hpd);
+	radeon_hpd_set_polarity(rdev, radeon_connector->hpd.hpd);
 
-	if ((connector->connector_type == DRM_MODE_CONNECTOR_DisplayPort) ||
-	    (connector->connector_type == DRM_MODE_CONNECTOR_eDP)) {
-		if ((radeon_dp_getsinktype(radeon_connector) == CONNECTOR_OBJECT_ID_DISPLAYPORT) ||
-		    (radeon_dp_getsinktype(radeon_connector) == CONNECTOR_OBJECT_ID_eDP)) {
-			if (radeon_dp_needs_link_train(radeon_connector)) {
-				if (connector->encoder)
-					dp_link_train(connector->encoder, connector);
-			}
-		}
-	}
+	/* powering up/down the eDP panel generates hpd events which
+	 * can interfere with modesetting.
+	 */
+	if (connector->connector_type == DRM_MODE_CONNECTOR_eDP)
+		return;
 
+	/* pre-r600 did not always have the hpd pins mapped accurately to connectors */
+	if (rdev->family >= CHIP_R600) {
+		if (radeon_hpd_sense(rdev, radeon_connector->hpd.hpd))
+			drm_helper_connector_dpms(connector, DRM_MODE_DPMS_ON);
+		else
+			drm_helper_connector_dpms(connector, DRM_MODE_DPMS_OFF);
+	}
 }
 
 static void radeon_property_change_mode(struct drm_encoder *encoder)
@@ -625,8 +628,14 @@
 static int radeon_vga_mode_valid(struct drm_connector *connector,
 				  struct drm_display_mode *mode)
 {
+	struct drm_device *dev = connector->dev;
+	struct radeon_device *rdev = dev->dev_private;
+
 	/* XXX check mode bandwidth */
-	/* XXX verify against max DAC output frequency */
+
+	if ((mode->clock / 10) > rdev->clock.max_pixel_clock)
+		return MODE_CLOCK_HIGH;
+
 	return MODE_OK;
 }
 
@@ -829,6 +838,13 @@
 		if (!radeon_connector->edid) {
 			DRM_ERROR("%s: probed a monitor but no|invalid EDID\n",
 					drm_get_connector_name(connector));
+			/* rs690 seems to have a problem with connectors not existing and always
+			 * return a block of 0's. If we see this just stop polling on this output */
+			if ((rdev->family == CHIP_RS690 || rdev->family == CHIP_RS740) && radeon_connector->base.null_edid_counter) {
+				ret = connector_status_disconnected;
+				DRM_ERROR("%s: detected RS690 floating bus bug, stopping ddc detect\n", drm_get_connector_name(connector));
+				radeon_connector->ddc_bus = NULL;
+			}
 		} else {
 			radeon_connector->use_digital = !!(radeon_connector->edid->input & DRM_EDID_INPUT_DIGITAL);
 
@@ -1014,6 +1030,11 @@
 		} else
 			return MODE_CLOCK_HIGH;
 	}
+
+	/* check against the max pixel clock */
+	if ((mode->clock / 10) > rdev->clock.max_pixel_clock)
+		return MODE_CLOCK_HIGH;
+
 	return MODE_OK;
 }
 
@@ -1051,36 +1072,153 @@
 {
 	struct radeon_connector *radeon_connector = to_radeon_connector(connector);
 	struct radeon_connector_atom_dig *radeon_dig_connector = radeon_connector->con_priv;
+	struct drm_encoder *encoder = radeon_best_single_encoder(connector);
 	int ret;
 
-	if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) {
+	if ((connector->connector_type == DRM_MODE_CONNECTOR_eDP) ||
+	    (connector->connector_type == DRM_MODE_CONNECTOR_LVDS)) {
+		struct drm_display_mode *mode;
+
 		if (!radeon_dig_connector->edp_on)
 			atombios_set_edp_panel_power(connector,
 						     ATOM_TRANSMITTER_ACTION_POWER_ON);
-	}
-	ret = radeon_ddc_get_modes(radeon_connector);
-	if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) {
+		ret = radeon_ddc_get_modes(radeon_connector);
 		if (!radeon_dig_connector->edp_on)
 			atombios_set_edp_panel_power(connector,
 						     ATOM_TRANSMITTER_ACTION_POWER_OFF);
+
+		if (ret > 0) {
+			if (encoder) {
+				radeon_fixup_lvds_native_mode(encoder, connector);
+				/* add scaled modes */
+				radeon_add_common_modes(encoder, connector);
+			}
+			return ret;
+		}
+
+		encoder = radeon_best_single_encoder(connector);
+		if (!encoder)
+			return 0;
+
+		/* we have no EDID modes */
+		mode = radeon_fp_native_mode(encoder);
+		if (mode) {
+			ret = 1;
+			drm_mode_probed_add(connector, mode);
+			/* add the width/height from vbios tables if available */
+			connector->display_info.width_mm = mode->width_mm;
+			connector->display_info.height_mm = mode->height_mm;
+			/* add scaled modes */
+			radeon_add_common_modes(encoder, connector);
+		}
+	} else {
+		/* need to setup ddc on the bridge */
+		if (radeon_connector_encoder_is_dp_bridge(connector)) {
+			if (encoder)
+				radeon_atom_ext_encoder_setup_ddc(encoder);
+		}
+		ret = radeon_ddc_get_modes(radeon_connector);
 	}
 
 	return ret;
 }
 
+bool radeon_connector_encoder_is_dp_bridge(struct drm_connector *connector)
+{
+	struct drm_mode_object *obj;
+	struct drm_encoder *encoder;
+	struct radeon_encoder *radeon_encoder;
+	int i;
+	bool found = false;
+
+	for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) {
+		if (connector->encoder_ids[i] == 0)
+			break;
+
+		obj = drm_mode_object_find(connector->dev, connector->encoder_ids[i], DRM_MODE_OBJECT_ENCODER);
+		if (!obj)
+			continue;
+
+		encoder = obj_to_encoder(obj);
+		radeon_encoder = to_radeon_encoder(encoder);
+
+		switch (radeon_encoder->encoder_id) {
+		case ENCODER_OBJECT_ID_TRAVIS:
+		case ENCODER_OBJECT_ID_NUTMEG:
+			found = true;
+			break;
+		default:
+			break;
+		}
+	}
+
+	return found;
+}
+
+bool radeon_connector_encoder_is_hbr2(struct drm_connector *connector)
+{
+	struct drm_mode_object *obj;
+	struct drm_encoder *encoder;
+	struct radeon_encoder *radeon_encoder;
+	int i;
+	bool found = false;
+
+	for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) {
+		if (connector->encoder_ids[i] == 0)
+			break;
+
+		obj = drm_mode_object_find(connector->dev, connector->encoder_ids[i], DRM_MODE_OBJECT_ENCODER);
+		if (!obj)
+			continue;
+
+		encoder = obj_to_encoder(obj);
+		radeon_encoder = to_radeon_encoder(encoder);
+		if (radeon_encoder->caps & ATOM_ENCODER_CAP_RECORD_HBR2)
+			found = true;
+	}
+
+	return found;
+}
+
+bool radeon_connector_is_dp12_capable(struct drm_connector *connector)
+{
+	struct drm_device *dev = connector->dev;
+	struct radeon_device *rdev = dev->dev_private;
+
+	if (ASIC_IS_DCE5(rdev) &&
+	    (rdev->clock.dp_extclk >= 53900) &&
+	    radeon_connector_encoder_is_hbr2(connector)) {
+		return true;
+	}
+
+	return false;
+}
+
 static enum drm_connector_status
 radeon_dp_detect(struct drm_connector *connector, bool force)
 {
+	struct drm_device *dev = connector->dev;
+	struct radeon_device *rdev = dev->dev_private;
 	struct radeon_connector *radeon_connector = to_radeon_connector(connector);
 	enum drm_connector_status ret = connector_status_disconnected;
 	struct radeon_connector_atom_dig *radeon_dig_connector = radeon_connector->con_priv;
+	struct drm_encoder *encoder = radeon_best_single_encoder(connector);
 
 	if (radeon_connector->edid) {
 		kfree(radeon_connector->edid);
 		radeon_connector->edid = NULL;
 	}
 
-	if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) {
+	if ((connector->connector_type == DRM_MODE_CONNECTOR_eDP) ||
+	    (connector->connector_type == DRM_MODE_CONNECTOR_LVDS)) {
+		if (encoder) {
+			struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
+			struct drm_display_mode *native_mode = &radeon_encoder->native_mode;
+
+			/* check if panel is valid */
+			if (native_mode->hdisplay >= 320 && native_mode->vdisplay >= 240)
+				ret = connector_status_connected;
+		}
 		/* eDP is always DP */
 		radeon_dig_connector->dp_sink_type = CONNECTOR_OBJECT_ID_DISPLAYPORT;
 		if (!radeon_dig_connector->edp_on)
@@ -1092,13 +1230,34 @@
 			atombios_set_edp_panel_power(connector,
 						     ATOM_TRANSMITTER_ACTION_POWER_OFF);
 	} else {
+		/* need to setup ddc on the bridge */
+		if (radeon_connector_encoder_is_dp_bridge(connector)) {
+			if (encoder)
+				radeon_atom_ext_encoder_setup_ddc(encoder);
+		}
 		radeon_dig_connector->dp_sink_type = radeon_dp_getsinktype(radeon_connector);
-		if (radeon_dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) {
-			if (radeon_dp_getdpcd(radeon_connector))
-				ret = connector_status_connected;
+		if (radeon_hpd_sense(rdev, radeon_connector->hpd.hpd)) {
+			ret = connector_status_connected;
+			if (radeon_dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT)
+				radeon_dp_getdpcd(radeon_connector);
 		} else {
-			if (radeon_ddc_probe(radeon_connector))
-				ret = connector_status_connected;
+			if (radeon_dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) {
+				if (radeon_dp_getdpcd(radeon_connector))
+					ret = connector_status_connected;
+			} else {
+				if (radeon_ddc_probe(radeon_connector))
+					ret = connector_status_connected;
+			}
+		}
+
+		if ((ret == connector_status_disconnected) &&
+		    radeon_connector->dac_load_detect) {
+			struct drm_encoder *encoder = radeon_best_single_encoder(connector);
+			struct drm_encoder_helper_funcs *encoder_funcs;
+			if (encoder) {
+				encoder_funcs = encoder->helper_private;
+				ret = encoder_funcs->detect(encoder, connector);
+			}
 		}
 	}
 
@@ -1114,11 +1273,39 @@
 
 	/* XXX check mode bandwidth */
 
-	if ((radeon_dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) ||
-	    (radeon_dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_eDP))
-		return radeon_dp_mode_valid_helper(radeon_connector, mode);
-	else
+	if ((connector->connector_type == DRM_MODE_CONNECTOR_eDP) ||
+	    (connector->connector_type == DRM_MODE_CONNECTOR_LVDS)) {
+		struct drm_encoder *encoder = radeon_best_single_encoder(connector);
+
+		if ((mode->hdisplay < 320) || (mode->vdisplay < 240))
+			return MODE_PANEL;
+
+		if (encoder) {
+			struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
+			struct drm_display_mode *native_mode = &radeon_encoder->native_mode;
+
+			/* AVIVO hardware supports downscaling modes larger than the panel
+			 * to the panel size, but I'm not sure this is desirable.
+			 */
+			if ((mode->hdisplay > native_mode->hdisplay) ||
+			    (mode->vdisplay > native_mode->vdisplay))
+				return MODE_PANEL;
+
+			/* if scaling is disabled, block non-native modes */
+			if (radeon_encoder->rmx_type == RMX_OFF) {
+				if ((mode->hdisplay != native_mode->hdisplay) ||
+				    (mode->vdisplay != native_mode->vdisplay))
+					return MODE_PANEL;
+			}
+		}
 		return MODE_OK;
+	} else {
+		if ((radeon_dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) ||
+		    (radeon_dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_eDP))
+			return radeon_dp_mode_valid_helper(connector, mode);
+		else
+			return MODE_OK;
+	}
 }
 
 struct drm_connector_helper_funcs radeon_dp_connector_helper_funcs = {
@@ -1151,8 +1338,11 @@
 	struct drm_connector *connector;
 	struct radeon_connector *radeon_connector;
 	struct radeon_connector_atom_dig *radeon_dig_connector;
+	struct drm_encoder *encoder;
+	struct radeon_encoder *radeon_encoder;
 	uint32_t subpixel_order = SubPixelNone;
 	bool shared_ddc = false;
+	bool is_dp_bridge = false;
 
 	if (connector_type == DRM_MODE_CONNECTOR_Unknown)
 		return;
@@ -1184,6 +1374,21 @@
 		}
 	}
 
+	/* check if it's a dp bridge */
+	list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
+		radeon_encoder = to_radeon_encoder(encoder);
+		if (radeon_encoder->devices & supported_device) {
+			switch (radeon_encoder->encoder_id) {
+			case ENCODER_OBJECT_ID_TRAVIS:
+			case ENCODER_OBJECT_ID_NUTMEG:
+				is_dp_bridge = true;
+				break;
+			default:
+				break;
+			}
+		}
+	}
+
 	radeon_connector = kzalloc(sizeof(struct radeon_connector), GFP_KERNEL);
 	if (!radeon_connector)
 		return;
@@ -1201,61 +1406,43 @@
 		if (!radeon_connector->router_bus)
 			DRM_ERROR("Failed to assign router i2c bus! Check dmesg for i2c errors.\n");
 	}
-	switch (connector_type) {
-	case DRM_MODE_CONNECTOR_VGA:
-		drm_connector_init(dev, &radeon_connector->base, &radeon_vga_connector_funcs, connector_type);
-		drm_connector_helper_add(&radeon_connector->base, &radeon_vga_connector_helper_funcs);
-		if (i2c_bus->valid) {
-			radeon_connector->ddc_bus = radeon_i2c_lookup(rdev, i2c_bus);
-			if (!radeon_connector->ddc_bus)
-				DRM_ERROR("VGA: Failed to assign ddc bus! Check dmesg for i2c errors.\n");
-		}
-		radeon_connector->dac_load_detect = true;
-		drm_connector_attach_property(&radeon_connector->base,
-					      rdev->mode_info.load_detect_property,
-					      1);
-		/* no HPD on analog connectors */
-		radeon_connector->hpd.hpd = RADEON_HPD_NONE;
-		connector->polled = DRM_CONNECTOR_POLL_CONNECT;
-		connector->interlace_allowed = true;
-		connector->doublescan_allowed = true;
-		break;
-	case DRM_MODE_CONNECTOR_DVIA:
-		drm_connector_init(dev, &radeon_connector->base, &radeon_vga_connector_funcs, connector_type);
-		drm_connector_helper_add(&radeon_connector->base, &radeon_vga_connector_helper_funcs);
-		if (i2c_bus->valid) {
-			radeon_connector->ddc_bus = radeon_i2c_lookup(rdev, i2c_bus);
-			if (!radeon_connector->ddc_bus)
-				DRM_ERROR("DVIA: Failed to assign ddc bus! Check dmesg for i2c errors.\n");
-		}
-		radeon_connector->dac_load_detect = true;
-		drm_connector_attach_property(&radeon_connector->base,
-					      rdev->mode_info.load_detect_property,
-					      1);
-		/* no HPD on analog connectors */
-		radeon_connector->hpd.hpd = RADEON_HPD_NONE;
-		connector->interlace_allowed = true;
-		connector->doublescan_allowed = true;
-		break;
-	case DRM_MODE_CONNECTOR_DVII:
-	case DRM_MODE_CONNECTOR_DVID:
+
+	if (is_dp_bridge) {
 		radeon_dig_connector = kzalloc(sizeof(struct radeon_connector_atom_dig), GFP_KERNEL);
 		if (!radeon_dig_connector)
 			goto failed;
 		radeon_dig_connector->igp_lane_info = igp_lane_info;
 		radeon_connector->con_priv = radeon_dig_connector;
-		drm_connector_init(dev, &radeon_connector->base, &radeon_dvi_connector_funcs, connector_type);
-		drm_connector_helper_add(&radeon_connector->base, &radeon_dvi_connector_helper_funcs);
+		drm_connector_init(dev, &radeon_connector->base, &radeon_dp_connector_funcs, connector_type);
+		drm_connector_helper_add(&radeon_connector->base, &radeon_dp_connector_helper_funcs);
 		if (i2c_bus->valid) {
+			/* add DP i2c bus */
+			if (connector_type == DRM_MODE_CONNECTOR_eDP)
+				radeon_dig_connector->dp_i2c_bus = radeon_i2c_create_dp(dev, i2c_bus, "eDP-auxch");
+			else
+				radeon_dig_connector->dp_i2c_bus = radeon_i2c_create_dp(dev, i2c_bus, "DP-auxch");
+			if (!radeon_dig_connector->dp_i2c_bus)
+				DRM_ERROR("DP: Failed to assign dp ddc bus! Check dmesg for i2c errors.\n");
 			radeon_connector->ddc_bus = radeon_i2c_lookup(rdev, i2c_bus);
 			if (!radeon_connector->ddc_bus)
-				DRM_ERROR("DVI: Failed to assign ddc bus! Check dmesg for i2c errors.\n");
+				DRM_ERROR("DP: Failed to assign ddc bus! Check dmesg for i2c errors.\n");
 		}
-		subpixel_order = SubPixelHorizontalRGB;
-		drm_connector_attach_property(&radeon_connector->base,
-					      rdev->mode_info.coherent_mode_property,
-					      1);
-		if (ASIC_IS_AVIVO(rdev)) {
+		switch (connector_type) {
+		case DRM_MODE_CONNECTOR_VGA:
+		case DRM_MODE_CONNECTOR_DVIA:
+		default:
+			connector->interlace_allowed = true;
+			connector->doublescan_allowed = true;
+			radeon_connector->dac_load_detect = true;
+			drm_connector_attach_property(&radeon_connector->base,
+						      rdev->mode_info.load_detect_property,
+						      1);
+			break;
+		case DRM_MODE_CONNECTOR_DVII:
+		case DRM_MODE_CONNECTOR_DVID:
+		case DRM_MODE_CONNECTOR_HDMIA:
+		case DRM_MODE_CONNECTOR_HDMIB:
+		case DRM_MODE_CONNECTOR_DisplayPort:
 			drm_connector_attach_property(&radeon_connector->base,
 						      rdev->mode_info.underscan_property,
 						      UNDERSCAN_OFF);
@@ -1265,131 +1452,240 @@
 			drm_connector_attach_property(&radeon_connector->base,
 						      rdev->mode_info.underscan_vborder_property,
 						      0);
+			subpixel_order = SubPixelHorizontalRGB;
+			connector->interlace_allowed = true;
+			if (connector_type == DRM_MODE_CONNECTOR_HDMIB)
+				connector->doublescan_allowed = true;
+			else
+				connector->doublescan_allowed = false;
+			if (connector_type == DRM_MODE_CONNECTOR_DVII) {
+				radeon_connector->dac_load_detect = true;
+				drm_connector_attach_property(&radeon_connector->base,
+							      rdev->mode_info.load_detect_property,
+							      1);
+			}
+			break;
+		case DRM_MODE_CONNECTOR_LVDS:
+		case DRM_MODE_CONNECTOR_eDP:
+			drm_connector_attach_property(&radeon_connector->base,
+						      dev->mode_config.scaling_mode_property,
+						      DRM_MODE_SCALE_FULLSCREEN);
+			subpixel_order = SubPixelHorizontalRGB;
+			connector->interlace_allowed = false;
+			connector->doublescan_allowed = false;
+			break;
 		}
-		if (connector_type == DRM_MODE_CONNECTOR_DVII) {
+	} else {
+		switch (connector_type) {
+		case DRM_MODE_CONNECTOR_VGA:
+			drm_connector_init(dev, &radeon_connector->base, &radeon_vga_connector_funcs, connector_type);
+			drm_connector_helper_add(&radeon_connector->base, &radeon_vga_connector_helper_funcs);
+			if (i2c_bus->valid) {
+				radeon_connector->ddc_bus = radeon_i2c_lookup(rdev, i2c_bus);
+				if (!radeon_connector->ddc_bus)
+					DRM_ERROR("VGA: Failed to assign ddc bus! Check dmesg for i2c errors.\n");
+			}
 			radeon_connector->dac_load_detect = true;
 			drm_connector_attach_property(&radeon_connector->base,
 						      rdev->mode_info.load_detect_property,
 						      1);
-		}
-		connector->interlace_allowed = true;
-		if (connector_type == DRM_MODE_CONNECTOR_DVII)
+			/* no HPD on analog connectors */
+			radeon_connector->hpd.hpd = RADEON_HPD_NONE;
+			connector->polled = DRM_CONNECTOR_POLL_CONNECT;
+			connector->interlace_allowed = true;
 			connector->doublescan_allowed = true;
-		else
-			connector->doublescan_allowed = false;
-		break;
-	case DRM_MODE_CONNECTOR_HDMIA:
-	case DRM_MODE_CONNECTOR_HDMIB:
-		radeon_dig_connector = kzalloc(sizeof(struct radeon_connector_atom_dig), GFP_KERNEL);
-		if (!radeon_dig_connector)
-			goto failed;
-		radeon_dig_connector->igp_lane_info = igp_lane_info;
-		radeon_connector->con_priv = radeon_dig_connector;
-		drm_connector_init(dev, &radeon_connector->base, &radeon_dvi_connector_funcs, connector_type);
-		drm_connector_helper_add(&radeon_connector->base, &radeon_dvi_connector_helper_funcs);
-		if (i2c_bus->valid) {
-			radeon_connector->ddc_bus = radeon_i2c_lookup(rdev, i2c_bus);
-			if (!radeon_connector->ddc_bus)
-				DRM_ERROR("HDMI: Failed to assign ddc bus! Check dmesg for i2c errors.\n");
-		}
-		drm_connector_attach_property(&radeon_connector->base,
-					      rdev->mode_info.coherent_mode_property,
-					      1);
-		if (ASIC_IS_AVIVO(rdev)) {
+			break;
+		case DRM_MODE_CONNECTOR_DVIA:
+			drm_connector_init(dev, &radeon_connector->base, &radeon_vga_connector_funcs, connector_type);
+			drm_connector_helper_add(&radeon_connector->base, &radeon_vga_connector_helper_funcs);
+			if (i2c_bus->valid) {
+				radeon_connector->ddc_bus = radeon_i2c_lookup(rdev, i2c_bus);
+				if (!radeon_connector->ddc_bus)
+					DRM_ERROR("DVIA: Failed to assign ddc bus! Check dmesg for i2c errors.\n");
+			}
+			radeon_connector->dac_load_detect = true;
 			drm_connector_attach_property(&radeon_connector->base,
-						      rdev->mode_info.underscan_property,
-						      UNDERSCAN_OFF);
+						      rdev->mode_info.load_detect_property,
+						      1);
+			/* no HPD on analog connectors */
+			radeon_connector->hpd.hpd = RADEON_HPD_NONE;
+			connector->interlace_allowed = true;
+			connector->doublescan_allowed = true;
+			break;
+		case DRM_MODE_CONNECTOR_DVII:
+		case DRM_MODE_CONNECTOR_DVID:
+			radeon_dig_connector = kzalloc(sizeof(struct radeon_connector_atom_dig), GFP_KERNEL);
+			if (!radeon_dig_connector)
+				goto failed;
+			radeon_dig_connector->igp_lane_info = igp_lane_info;
+			radeon_connector->con_priv = radeon_dig_connector;
+			drm_connector_init(dev, &radeon_connector->base, &radeon_dvi_connector_funcs, connector_type);
+			drm_connector_helper_add(&radeon_connector->base, &radeon_dvi_connector_helper_funcs);
+			if (i2c_bus->valid) {
+				radeon_connector->ddc_bus = radeon_i2c_lookup(rdev, i2c_bus);
+				if (!radeon_connector->ddc_bus)
+					DRM_ERROR("DVI: Failed to assign ddc bus! Check dmesg for i2c errors.\n");
+			}
+			subpixel_order = SubPixelHorizontalRGB;
 			drm_connector_attach_property(&radeon_connector->base,
-						      rdev->mode_info.underscan_hborder_property,
-						      0);
+						      rdev->mode_info.coherent_mode_property,
+						      1);
+			if (ASIC_IS_AVIVO(rdev)) {
+				drm_connector_attach_property(&radeon_connector->base,
+							      rdev->mode_info.underscan_property,
+							      UNDERSCAN_OFF);
+				drm_connector_attach_property(&radeon_connector->base,
+							      rdev->mode_info.underscan_hborder_property,
+							      0);
+				drm_connector_attach_property(&radeon_connector->base,
+							      rdev->mode_info.underscan_vborder_property,
+							      0);
+			}
+			if (connector_type == DRM_MODE_CONNECTOR_DVII) {
+				radeon_connector->dac_load_detect = true;
+				drm_connector_attach_property(&radeon_connector->base,
+							      rdev->mode_info.load_detect_property,
+							      1);
+			}
+			connector->interlace_allowed = true;
+			if (connector_type == DRM_MODE_CONNECTOR_DVII)
+				connector->doublescan_allowed = true;
+			else
+				connector->doublescan_allowed = false;
+			break;
+		case DRM_MODE_CONNECTOR_HDMIA:
+		case DRM_MODE_CONNECTOR_HDMIB:
+			radeon_dig_connector = kzalloc(sizeof(struct radeon_connector_atom_dig), GFP_KERNEL);
+			if (!radeon_dig_connector)
+				goto failed;
+			radeon_dig_connector->igp_lane_info = igp_lane_info;
+			radeon_connector->con_priv = radeon_dig_connector;
+			drm_connector_init(dev, &radeon_connector->base, &radeon_dvi_connector_funcs, connector_type);
+			drm_connector_helper_add(&radeon_connector->base, &radeon_dvi_connector_helper_funcs);
+			if (i2c_bus->valid) {
+				radeon_connector->ddc_bus = radeon_i2c_lookup(rdev, i2c_bus);
+				if (!radeon_connector->ddc_bus)
+					DRM_ERROR("HDMI: Failed to assign ddc bus! Check dmesg for i2c errors.\n");
+			}
 			drm_connector_attach_property(&radeon_connector->base,
-						      rdev->mode_info.underscan_vborder_property,
-						      0);
-		}
-		subpixel_order = SubPixelHorizontalRGB;
-		connector->interlace_allowed = true;
-		if (connector_type == DRM_MODE_CONNECTOR_HDMIB)
-			connector->doublescan_allowed = true;
-		else
-			connector->doublescan_allowed = false;
-		break;
-	case DRM_MODE_CONNECTOR_DisplayPort:
-	case DRM_MODE_CONNECTOR_eDP:
-		radeon_dig_connector = kzalloc(sizeof(struct radeon_connector_atom_dig), GFP_KERNEL);
-		if (!radeon_dig_connector)
-			goto failed;
-		radeon_dig_connector->igp_lane_info = igp_lane_info;
-		radeon_connector->con_priv = radeon_dig_connector;
-		drm_connector_init(dev, &radeon_connector->base, &radeon_dp_connector_funcs, connector_type);
-		drm_connector_helper_add(&radeon_connector->base, &radeon_dp_connector_helper_funcs);
-		if (i2c_bus->valid) {
-			/* add DP i2c bus */
-			if (connector_type == DRM_MODE_CONNECTOR_eDP)
-				radeon_dig_connector->dp_i2c_bus = radeon_i2c_create_dp(dev, i2c_bus, "eDP-auxch");
+						      rdev->mode_info.coherent_mode_property,
+						      1);
+			if (ASIC_IS_AVIVO(rdev)) {
+				drm_connector_attach_property(&radeon_connector->base,
+							      rdev->mode_info.underscan_property,
+							      UNDERSCAN_OFF);
+				drm_connector_attach_property(&radeon_connector->base,
+							      rdev->mode_info.underscan_hborder_property,
+							      0);
+				drm_connector_attach_property(&radeon_connector->base,
+							      rdev->mode_info.underscan_vborder_property,
+							      0);
+			}
+			subpixel_order = SubPixelHorizontalRGB;
+			connector->interlace_allowed = true;
+			if (connector_type == DRM_MODE_CONNECTOR_HDMIB)
+				connector->doublescan_allowed = true;
 			else
+				connector->doublescan_allowed = false;
+			break;
+		case DRM_MODE_CONNECTOR_DisplayPort:
+			radeon_dig_connector = kzalloc(sizeof(struct radeon_connector_atom_dig), GFP_KERNEL);
+			if (!radeon_dig_connector)
+				goto failed;
+			radeon_dig_connector->igp_lane_info = igp_lane_info;
+			radeon_connector->con_priv = radeon_dig_connector;
+			drm_connector_init(dev, &radeon_connector->base, &radeon_dp_connector_funcs, connector_type);
+			drm_connector_helper_add(&radeon_connector->base, &radeon_dp_connector_helper_funcs);
+			if (i2c_bus->valid) {
+				/* add DP i2c bus */
 				radeon_dig_connector->dp_i2c_bus = radeon_i2c_create_dp(dev, i2c_bus, "DP-auxch");
-			if (!radeon_dig_connector->dp_i2c_bus)
-				DRM_ERROR("DP: Failed to assign dp ddc bus! Check dmesg for i2c errors.\n");
-			radeon_connector->ddc_bus = radeon_i2c_lookup(rdev, i2c_bus);
-			if (!radeon_connector->ddc_bus)
-				DRM_ERROR("DP: Failed to assign ddc bus! Check dmesg for i2c errors.\n");
-		}
-		subpixel_order = SubPixelHorizontalRGB;
-		drm_connector_attach_property(&radeon_connector->base,
-					      rdev->mode_info.coherent_mode_property,
-					      1);
-		if (ASIC_IS_AVIVO(rdev)) {
+				if (!radeon_dig_connector->dp_i2c_bus)
+					DRM_ERROR("DP: Failed to assign dp ddc bus! Check dmesg for i2c errors.\n");
+				radeon_connector->ddc_bus = radeon_i2c_lookup(rdev, i2c_bus);
+				if (!radeon_connector->ddc_bus)
+					DRM_ERROR("DP: Failed to assign ddc bus! Check dmesg for i2c errors.\n");
+			}
+			subpixel_order = SubPixelHorizontalRGB;
 			drm_connector_attach_property(&radeon_connector->base,
-						      rdev->mode_info.underscan_property,
-						      UNDERSCAN_OFF);
+						      rdev->mode_info.coherent_mode_property,
+						      1);
+			if (ASIC_IS_AVIVO(rdev)) {
+				drm_connector_attach_property(&radeon_connector->base,
+							      rdev->mode_info.underscan_property,
+							      UNDERSCAN_OFF);
+				drm_connector_attach_property(&radeon_connector->base,
+							      rdev->mode_info.underscan_hborder_property,
+							      0);
+				drm_connector_attach_property(&radeon_connector->base,
+							      rdev->mode_info.underscan_vborder_property,
+							      0);
+			}
+			connector->interlace_allowed = true;
+			/* in theory with a DP to VGA converter... */
+			connector->doublescan_allowed = false;
+			break;
+		case DRM_MODE_CONNECTOR_eDP:
+			radeon_dig_connector = kzalloc(sizeof(struct radeon_connector_atom_dig), GFP_KERNEL);
+			if (!radeon_dig_connector)
+				goto failed;
+			radeon_dig_connector->igp_lane_info = igp_lane_info;
+			radeon_connector->con_priv = radeon_dig_connector;
+			drm_connector_init(dev, &radeon_connector->base, &radeon_dp_connector_funcs, connector_type);
+			drm_connector_helper_add(&radeon_connector->base, &radeon_dp_connector_helper_funcs);
+			if (i2c_bus->valid) {
+				/* add DP i2c bus */
+				radeon_dig_connector->dp_i2c_bus = radeon_i2c_create_dp(dev, i2c_bus, "eDP-auxch");
+				if (!radeon_dig_connector->dp_i2c_bus)
+					DRM_ERROR("DP: Failed to assign dp ddc bus! Check dmesg for i2c errors.\n");
+				radeon_connector->ddc_bus = radeon_i2c_lookup(rdev, i2c_bus);
+				if (!radeon_connector->ddc_bus)
+					DRM_ERROR("DP: Failed to assign ddc bus! Check dmesg for i2c errors.\n");
+			}
 			drm_connector_attach_property(&radeon_connector->base,
-						      rdev->mode_info.underscan_hborder_property,
-						      0);
+						      dev->mode_config.scaling_mode_property,
+						      DRM_MODE_SCALE_FULLSCREEN);
+			subpixel_order = SubPixelHorizontalRGB;
+			connector->interlace_allowed = false;
+			connector->doublescan_allowed = false;
+			break;
+		case DRM_MODE_CONNECTOR_SVIDEO:
+		case DRM_MODE_CONNECTOR_Composite:
+		case DRM_MODE_CONNECTOR_9PinDIN:
+			drm_connector_init(dev, &radeon_connector->base, &radeon_tv_connector_funcs, connector_type);
+			drm_connector_helper_add(&radeon_connector->base, &radeon_tv_connector_helper_funcs);
+			radeon_connector->dac_load_detect = true;
 			drm_connector_attach_property(&radeon_connector->base,
-						      rdev->mode_info.underscan_vborder_property,
-						      0);
-		}
-		connector->interlace_allowed = true;
-		/* in theory with a DP to VGA converter... */
-		connector->doublescan_allowed = false;
-		break;
-	case DRM_MODE_CONNECTOR_SVIDEO:
-	case DRM_MODE_CONNECTOR_Composite:
-	case DRM_MODE_CONNECTOR_9PinDIN:
-		drm_connector_init(dev, &radeon_connector->base, &radeon_tv_connector_funcs, connector_type);
-		drm_connector_helper_add(&radeon_connector->base, &radeon_tv_connector_helper_funcs);
-		radeon_connector->dac_load_detect = true;
-		drm_connector_attach_property(&radeon_connector->base,
-					      rdev->mode_info.load_detect_property,
-					      1);
-		drm_connector_attach_property(&radeon_connector->base,
-					      rdev->mode_info.tv_std_property,
-					      radeon_atombios_get_tv_info(rdev));
-		/* no HPD on analog connectors */
-		radeon_connector->hpd.hpd = RADEON_HPD_NONE;
-		connector->interlace_allowed = false;
-		connector->doublescan_allowed = false;
-		break;
-	case DRM_MODE_CONNECTOR_LVDS:
-		radeon_dig_connector = kzalloc(sizeof(struct radeon_connector_atom_dig), GFP_KERNEL);
-		if (!radeon_dig_connector)
-			goto failed;
-		radeon_dig_connector->igp_lane_info = igp_lane_info;
-		radeon_connector->con_priv = radeon_dig_connector;
-		drm_connector_init(dev, &radeon_connector->base, &radeon_lvds_connector_funcs, connector_type);
-		drm_connector_helper_add(&radeon_connector->base, &radeon_lvds_connector_helper_funcs);
-		if (i2c_bus->valid) {
-			radeon_connector->ddc_bus = radeon_i2c_lookup(rdev, i2c_bus);
-			if (!radeon_connector->ddc_bus)
-				DRM_ERROR("LVDS: Failed to assign ddc bus! Check dmesg for i2c errors.\n");
+						      rdev->mode_info.load_detect_property,
+						      1);
+			drm_connector_attach_property(&radeon_connector->base,
+						      rdev->mode_info.tv_std_property,
+						      radeon_atombios_get_tv_info(rdev));
+			/* no HPD on analog connectors */
+			radeon_connector->hpd.hpd = RADEON_HPD_NONE;
+			connector->interlace_allowed = false;
+			connector->doublescan_allowed = false;
+			break;
+		case DRM_MODE_CONNECTOR_LVDS:
+			radeon_dig_connector = kzalloc(sizeof(struct radeon_connector_atom_dig), GFP_KERNEL);
+			if (!radeon_dig_connector)
+				goto failed;
+			radeon_dig_connector->igp_lane_info = igp_lane_info;
+			radeon_connector->con_priv = radeon_dig_connector;
+			drm_connector_init(dev, &radeon_connector->base, &radeon_lvds_connector_funcs, connector_type);
+			drm_connector_helper_add(&radeon_connector->base, &radeon_lvds_connector_helper_funcs);
+			if (i2c_bus->valid) {
+				radeon_connector->ddc_bus = radeon_i2c_lookup(rdev, i2c_bus);
+				if (!radeon_connector->ddc_bus)
+					DRM_ERROR("LVDS: Failed to assign ddc bus! Check dmesg for i2c errors.\n");
+			}
+			drm_connector_attach_property(&radeon_connector->base,
+						      dev->mode_config.scaling_mode_property,
+						      DRM_MODE_SCALE_FULLSCREEN);
+			subpixel_order = SubPixelHorizontalRGB;
+			connector->interlace_allowed = false;
+			connector->doublescan_allowed = false;
+			break;
 		}
-		drm_connector_attach_property(&radeon_connector->base,
-					      dev->mode_config.scaling_mode_property,
-					      DRM_MODE_SCALE_FULLSCREEN);
-		subpixel_order = SubPixelHorizontalRGB;
-		connector->interlace_allowed = false;
-		connector->doublescan_allowed = false;
-		break;
 	}
 
 	if (radeon_connector->hpd.hpd == RADEON_HPD_NONE) {
diff -druN linux-2.6.39-libre/drivers/gpu/drm/radeon/radeon_cs.c linux-3.0-rc7-libre/drivers/gpu/drm/radeon/radeon_cs.c
--- linux-2.6.39-libre/drivers/gpu/drm/radeon/radeon_cs.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/gpu/drm/radeon/radeon_cs.c	2011-07-11 19:51:52.000000000 -0400
@@ -228,6 +228,7 @@
 	parser.filp = filp;
 	parser.rdev = rdev;
 	parser.dev = rdev->dev;
+	parser.family = rdev->family;
 	r = radeon_cs_parser_init(&parser, data);
 	if (r) {
 		DRM_ERROR("Failed to initialize parser !\n");
diff -druN linux-2.6.39-libre/drivers/gpu/drm/radeon/radeon_device.c linux-3.0-rc7-libre/drivers/gpu/drm/radeon/radeon_device.c
--- linux-2.6.39-libre/drivers/gpu/drm/radeon/radeon_device.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/gpu/drm/radeon/radeon_device.c	2011-07-11 19:51:52.000000000 -0400
@@ -82,6 +82,8 @@
 	"CYPRESS",
 	"HEMLOCK",
 	"PALM",
+	"SUMO",
+	"SUMO2",
 	"BARTS",
 	"TURKS",
 	"CAICOS",
@@ -213,6 +215,8 @@
 		return r;
 	}
 
+	/* clear wb memory */
+	memset((char *)rdev->wb.wb, 0, RADEON_GPU_PAGE_SIZE);
 	/* disable event_write fences */
 	rdev->wb.use_event = false;
 	/* disabled via module param */
@@ -752,6 +756,7 @@
 	dma_bits = rdev->need_dma32 ? 32 : 40;
 	r = pci_set_dma_mask(rdev->pdev, DMA_BIT_MASK(dma_bits));
 	if (r) {
+		rdev->need_dma32 = true;
 		printk(KERN_WARNING "radeon: No suitable DMA available.\n");
 	}
 
@@ -923,6 +928,9 @@
 	radeon_fbdev_set_suspend(rdev, 0);
 	console_unlock();
 
+	/* init dig PHYs */
+	if (rdev->is_atom_bios)
+		radeon_atom_encoder_init(rdev);
 	/* reset hpd state */
 	radeon_hpd_init(rdev);
 	/* blat the mode back in */
diff -druN linux-2.6.39-libre/drivers/gpu/drm/radeon/radeon_display.c linux-3.0-rc7-libre/drivers/gpu/drm/radeon/radeon_display.c
--- linux-2.6.39-libre/drivers/gpu/drm/radeon/radeon_display.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/gpu/drm/radeon/radeon_display.c	2011-07-11 19:51:52.000000000 -0400
@@ -264,6 +264,8 @@
 		radeon_bo_unreserve(work->old_rbo);
 	} else
 		DRM_ERROR("failed to reserve buffer after flip\n");
+
+	drm_gem_object_unreference_unlocked(&work->old_rbo->gem_base);
 	kfree(work);
 }
 
@@ -371,6 +373,8 @@
 	new_radeon_fb = to_radeon_framebuffer(fb);
 	/* schedule unpin of the old buffer */
 	obj = old_radeon_fb->obj;
+	/* take a reference to the old object */
+	drm_gem_object_reference(obj);
 	rbo = gem_to_radeon_bo(obj);
 	work->old_rbo = rbo;
 	INIT_WORK(&work->work, radeon_unpin_work_func);
@@ -378,12 +382,9 @@
 	/* We borrow the event spin lock for protecting unpin_work */
 	spin_lock_irqsave(&dev->event_lock, flags);
 	if (radeon_crtc->unpin_work) {
-		spin_unlock_irqrestore(&dev->event_lock, flags);
-		kfree(work);
-		radeon_fence_unref(&fence);
-
 		DRM_DEBUG_DRIVER("flip queue: crtc already busy\n");
-		return -EBUSY;
+		r = -EBUSY;
+		goto unlock_free;
 	}
 	radeon_crtc->unpin_work = work;
 	radeon_crtc->deferred_flip_completion = 0;
@@ -497,6 +498,8 @@
 pflip_cleanup:
 	spin_lock_irqsave(&dev->event_lock, flags);
 	radeon_crtc->unpin_work = NULL;
+unlock_free:
+	drm_gem_object_unreference_unlocked(old_radeon_fb->obj);
 	spin_unlock_irqrestore(&dev->event_lock, flags);
 	radeon_fence_unref(&fence);
 	kfree(work);
@@ -1087,8 +1090,9 @@
 	*frac_fb_div_p = best_frac_feedback_div;
 	*ref_div_p = best_ref_div;
 	*post_div_p = best_post_div;
-	DRM_DEBUG_KMS("%d %d, pll dividers - fb: %d.%d ref: %d, post %d\n",
-		      freq, best_freq / 1000, best_feedback_div, best_frac_feedback_div,
+	DRM_DEBUG_KMS("%lld %d, pll dividers - fb: %d.%d ref: %d, post %d\n",
+		      (long long)freq,
+		      best_freq / 1000, best_feedback_div, best_frac_feedback_div,
 		      best_ref_div, best_post_div);
 
 }
@@ -1344,6 +1348,11 @@
 	if (!ret) {
 		return ret;
 	}
+
+	/* init dig PHYs */
+	if (rdev->is_atom_bios)
+		radeon_atom_encoder_init(rdev);
+
 	/* initialize hpd */
 	radeon_hpd_init(rdev);
 
diff -druN linux-2.6.39-libre/drivers/gpu/drm/radeon/radeon_drv.c linux-3.0-rc7-libre/drivers/gpu/drm/radeon/radeon_drv.c
--- linux-2.6.39-libre/drivers/gpu/drm/radeon/radeon_drv.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/gpu/drm/radeon/radeon_drv.c	2011-07-11 19:51:52.000000000 -0400
@@ -50,9 +50,10 @@
  *   2.7.0 - fixups for r600 2D tiling support. (no external ABI change), add eg dyn gpr regs
  *   2.8.0 - pageflip support, r500 US_FORMAT regs. r500 ARGB2101010 colorbuf, r300->r500 CMASK, clock crystal query
  *   2.9.0 - r600 tiling (s3tc,rgtc) working, SET_PREDICATION packet 3 on r600 + eg, backend query
+ *   2.10.0 - fusion 2D tiling
  */
 #define KMS_DRIVER_MAJOR	2
-#define KMS_DRIVER_MINOR	9
+#define KMS_DRIVER_MINOR	10
 #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);
@@ -112,7 +113,7 @@
 int radeon_testing = 0;
 int radeon_connector_table = 0;
 int radeon_tv = 1;
-int radeon_audio = 1;
+int radeon_audio = 0;
 int radeon_disp_priority = 0;
 int radeon_hw_i2c = 0;
 int radeon_pcie_gen2 = 0;
@@ -150,7 +151,7 @@
 MODULE_PARM_DESC(tv, "TV enable (0 = disable)");
 module_param_named(tv, radeon_tv, int, 0444);
 
-MODULE_PARM_DESC(audio, "Audio enable (0 = disable)");
+MODULE_PARM_DESC(audio, "Audio enable (1 = enable)");
 module_param_named(audio, radeon_audio, int, 0444);
 
 MODULE_PARM_DESC(disp_priority, "Display Priority (0 = auto, 1 = normal, 2 = high)");
diff -druN linux-2.6.39-libre/drivers/gpu/drm/radeon/radeon_encoders.c linux-3.0-rc7-libre/drivers/gpu/drm/radeon/radeon_encoders.c
--- linux-2.6.39-libre/drivers/gpu/drm/radeon/radeon_encoders.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/gpu/drm/radeon/radeon_encoders.c	2011-07-11 19:51:52.000000000 -0400
@@ -229,6 +229,22 @@
 	return NULL;
 }
 
+static struct drm_connector *
+radeon_get_connector_for_encoder_init(struct drm_encoder *encoder)
+{
+	struct drm_device *dev = encoder->dev;
+	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
+	struct drm_connector *connector;
+	struct radeon_connector *radeon_connector;
+
+	list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
+		radeon_connector = to_radeon_connector(connector);
+		if (radeon_encoder->devices & radeon_connector->devices)
+			return connector;
+	}
+	return NULL;
+}
+
 struct drm_encoder *radeon_atom_get_external_encoder(struct drm_encoder *encoder)
 {
 	struct drm_device *dev = encoder->dev;
@@ -250,6 +266,25 @@
 	return NULL;
 }
 
+bool radeon_encoder_is_dp_bridge(struct drm_encoder *encoder)
+{
+	struct drm_encoder *other_encoder = radeon_atom_get_external_encoder(encoder);
+
+	if (other_encoder) {
+		struct radeon_encoder *radeon_encoder = to_radeon_encoder(other_encoder);
+
+		switch (radeon_encoder->encoder_id) {
+		case ENCODER_OBJECT_ID_TRAVIS:
+		case ENCODER_OBJECT_ID_NUTMEG:
+			return true;
+		default:
+			return false;
+		}
+	}
+
+	return false;
+}
+
 void radeon_panel_mode_fixup(struct drm_encoder *encoder,
 			     struct drm_display_mode *adjusted_mode)
 {
@@ -332,7 +367,8 @@
 	}
 
 	if (ASIC_IS_DCE3(rdev) &&
-	    (radeon_encoder->active_device & (ATOM_DEVICE_DFP_SUPPORT | ATOM_DEVICE_LCD_SUPPORT))) {
+	    ((radeon_encoder->active_device & (ATOM_DEVICE_DFP_SUPPORT | ATOM_DEVICE_LCD_SUPPORT)) ||
+	     radeon_encoder_is_dp_bridge(encoder))) {
 		struct drm_connector *connector = radeon_get_connector_for_encoder(encoder);
 		radeon_dp_set_link_config(connector, mode);
 	}
@@ -621,21 +657,20 @@
 	struct radeon_connector *radeon_connector;
 	struct radeon_connector_atom_dig *dig_connector;
 
+	/* dp bridges are always DP */
+	if (radeon_encoder_is_dp_bridge(encoder))
+		return ATOM_ENCODER_MODE_DP;
+
+	/* DVO is always DVO */
+	if (radeon_encoder->encoder_id == ATOM_ENCODER_MODE_DVO)
+		return ATOM_ENCODER_MODE_DVO;
+
 	connector = radeon_get_connector_for_encoder(encoder);
-	if (!connector) {
-		switch (radeon_encoder->encoder_id) {
-		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:
-		case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1:
-			return ATOM_ENCODER_MODE_DVI;
-		case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1:
-		case ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2:
-		default:
-			return ATOM_ENCODER_MODE_CRT;
-		}
-	}
+	/* if we don't have an active device yet, just use one of
+	 * the connectors tied to the encoder.
+	 */
+	if (!connector)
+		connector = radeon_get_connector_for_encoder_init(encoder);
 	radeon_connector = to_radeon_connector(connector);
 
 	switch (connector->connector_type) {
@@ -668,7 +703,6 @@
 		return ATOM_ENCODER_MODE_LVDS;
 		break;
 	case DRM_MODE_CONNECTOR_DisplayPort:
-	case DRM_MODE_CONNECTOR_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))
@@ -682,6 +716,8 @@
 		} else
 			return ATOM_ENCODER_MODE_DVI;
 		break;
+	case DRM_MODE_CONNECTOR_eDP:
+		return ATOM_ENCODER_MODE_DP;
 	case DRM_MODE_CONNECTOR_DVIA:
 	case DRM_MODE_CONNECTOR_VGA:
 		return ATOM_ENCODER_MODE_CRT;
@@ -747,7 +783,7 @@
 };
 
 void
-atombios_dig_encoder_setup(struct drm_encoder *encoder, int action)
+atombios_dig_encoder_setup(struct drm_encoder *encoder, int action, int panel_mode)
 {
 	struct drm_device *dev = encoder->dev;
 	struct radeon_device *rdev = dev->dev_private;
@@ -760,6 +796,7 @@
 	int dp_clock = 0;
 	int dp_lane_count = 0;
 	int hpd_id = RADEON_HPD_NONE;
+	int bpc = 8;
 
 	if (connector) {
 		struct radeon_connector *radeon_connector = to_radeon_connector(connector);
@@ -769,6 +806,7 @@
 		dp_clock = dig_connector->dp_clock;
 		dp_lane_count = dig_connector->dp_lane_count;
 		hpd_id = radeon_connector->hpd.hpd;
+		bpc = connector->display_info.bpc;
 	}
 
 	/* no dig encoder assigned */
@@ -791,7 +829,10 @@
 
 	args.v1.ucAction = action;
 	args.v1.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10);
-	args.v1.ucEncoderMode = atombios_get_encoder_mode(encoder);
+	if (action == ATOM_ENCODER_CMD_SETUP_PANEL_MODE)
+		args.v3.ucPanelMode = panel_mode;
+	else
+		args.v1.ucEncoderMode = atombios_get_encoder_mode(encoder);
 
 	if ((args.v1.ucEncoderMode == ATOM_ENCODER_MODE_DP) ||
 	    (args.v1.ucEncoderMode == ATOM_ENCODER_MODE_DP_MST))
@@ -810,7 +851,27 @@
 				args.v1.ucConfig |= ATOM_ENCODER_CONFIG_V4_DPLINKRATE_5_40GHZ;
 		}
 		args.v4.acConfig.ucDigSel = dig->dig_encoder;
-		args.v4.ucBitPerColor = PANEL_8BIT_PER_COLOR;
+		switch (bpc) {
+		case 0:
+			args.v4.ucBitPerColor = PANEL_BPC_UNDEFINE;
+			break;
+		case 6:
+			args.v4.ucBitPerColor = PANEL_6BIT_PER_COLOR;
+			break;
+		case 8:
+		default:
+			args.v4.ucBitPerColor = PANEL_8BIT_PER_COLOR;
+			break;
+		case 10:
+			args.v4.ucBitPerColor = PANEL_10BIT_PER_COLOR;
+			break;
+		case 12:
+			args.v4.ucBitPerColor = PANEL_12BIT_PER_COLOR;
+			break;
+		case 16:
+			args.v4.ucBitPerColor = PANEL_16BIT_PER_COLOR;
+			break;
+		}
 		if (hpd_id == RADEON_HPD_NONE)
 			args.v4.ucHPD_ID = 0;
 		else
@@ -819,7 +880,27 @@
 		if ((args.v1.ucEncoderMode == ATOM_ENCODER_MODE_DP) && (dp_clock == 270000))
 			args.v1.ucConfig |= ATOM_ENCODER_CONFIG_V3_DPLINKRATE_2_70GHZ;
 		args.v3.acConfig.ucDigSel = dig->dig_encoder;
-		args.v3.ucBitPerColor = PANEL_8BIT_PER_COLOR;
+		switch (bpc) {
+		case 0:
+			args.v3.ucBitPerColor = PANEL_BPC_UNDEFINE;
+			break;
+		case 6:
+			args.v3.ucBitPerColor = PANEL_6BIT_PER_COLOR;
+			break;
+		case 8:
+		default:
+			args.v3.ucBitPerColor = PANEL_8BIT_PER_COLOR;
+			break;
+		case 10:
+			args.v3.ucBitPerColor = PANEL_10BIT_PER_COLOR;
+			break;
+		case 12:
+			args.v3.ucBitPerColor = PANEL_12BIT_PER_COLOR;
+			break;
+		case 16:
+			args.v3.ucBitPerColor = PANEL_16BIT_PER_COLOR;
+			break;
+		}
 	} else {
 		if ((args.v1.ucEncoderMode == ATOM_ENCODER_MODE_DP) && (dp_clock == 270000))
 			args.v1.ucConfig |= ATOM_ENCODER_CONFIG_DPLINKRATE_2_70GHZ;
@@ -859,7 +940,7 @@
 	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 drm_connector *connector = radeon_get_connector_for_encoder(encoder);
+	struct drm_connector *connector;
 	union dig_transmitter_control args;
 	int index = 0;
 	uint8_t frev, crev;
@@ -869,6 +950,16 @@
 	int dp_lane_count = 0;
 	int connector_object_id = 0;
 	int igp_lane_info = 0;
+	int dig_encoder = dig->dig_encoder;
+
+	if (action == ATOM_TRANSMITTER_ACTION_INIT) {
+		connector = radeon_get_connector_for_encoder_init(encoder);
+		/* just needed to avoid bailing in the encoder check.  the encoder
+		 * isn't used for init
+		 */
+		dig_encoder = 0;
+	} else
+		connector = radeon_get_connector_for_encoder(encoder);
 
 	if (connector) {
 		struct radeon_connector *radeon_connector = to_radeon_connector(connector);
@@ -883,7 +974,7 @@
 	}
 
 	/* no dig encoder assigned */
-	if (dig->dig_encoder == -1)
+	if (dig_encoder == -1)
 		return;
 
 	if (atombios_get_encoder_mode(encoder) == ATOM_ENCODER_MODE_DP)
@@ -931,10 +1022,10 @@
 		else
 			args.v3.ucLaneNum = 4;
 
-		if (dig->linkb) {
+		if (dig->linkb)
 			args.v3.acConfig.ucLinkSel = 1;
+		if (dig_encoder & 1)
 			args.v3.acConfig.ucEncoderSel = 1;
-		}
 
 		/* Select the PLL for the PHY
 		 * DP PHY should be clocked from external src if there is
@@ -946,11 +1037,16 @@
 		}
 
 		if (ASIC_IS_DCE5(rdev)) {
-			if (is_dp && rdev->clock.dp_extclk)
-				args.v4.acConfig.ucRefClkSource = 3; /* external src */
-			else
+			/* On DCE5 DCPLL usually generates the DP ref clock */
+			if (is_dp) {
+				if (rdev->clock.dp_extclk)
+					args.v4.acConfig.ucRefClkSource = ENCODER_REFCLK_SRC_EXTCLK;
+				else
+					args.v4.acConfig.ucRefClkSource = ENCODER_REFCLK_SRC_DCPLL;
+			} else
 				args.v4.acConfig.ucRefClkSource = pll_id;
 		} else {
+			/* On DCE4, if there is an external clock, it generates the DP ref clock */
 			if (is_dp && rdev->clock.dp_extclk)
 				args.v3.acConfig.ucRefClkSource = 2; /* external src */
 			else
@@ -978,7 +1074,7 @@
 				args.v3.acConfig.fDualLinkConnector = 1;
 		}
 	} else if (ASIC_IS_DCE32(rdev)) {
-		args.v2.acConfig.ucEncoderSel = dig->dig_encoder;
+		args.v2.acConfig.ucEncoderSel = dig_encoder;
 		if (dig->linkb)
 			args.v2.acConfig.ucLinkSel = 1;
 
@@ -994,9 +1090,10 @@
 			break;
 		}
 
-		if (is_dp)
+		if (is_dp) {
 			args.v2.acConfig.fCoherentMode = 1;
-		else if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) {
+			args.v2.acConfig.fDPConnector = 1;
+		} else if (radeon_encoder->devices & (ATOM_DEVICE_DFP_SUPPORT)) {
 			if (dig->coherent_mode)
 				args.v2.acConfig.fCoherentMode = 1;
 			if (radeon_encoder->pixel_clock > 165000)
@@ -1005,7 +1102,7 @@
 	} else {
 		args.v1.ucConfig = ATOM_TRANSMITTER_CONFIG_CLKSRC_PPLL;
 
-		if (dig->dig_encoder)
+		if (dig_encoder)
 			args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_DIG2_ENCODER;
 		else
 			args.v1.ucConfig |= ATOM_TRANSMITTER_CONFIG_DIG1_ENCODER;
@@ -1047,7 +1144,7 @@
 	atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
 }
 
-void
+bool
 atombios_set_edp_panel_power(struct drm_connector *connector, int action)
 {
 	struct radeon_connector *radeon_connector = to_radeon_connector(connector);
@@ -1058,23 +1155,37 @@
 	uint8_t frev, crev;
 
 	if (connector->connector_type != DRM_MODE_CONNECTOR_eDP)
-		return;
+		goto done;
 
 	if (!ASIC_IS_DCE4(rdev))
-		return;
+		goto done;
 
 	if ((action != ATOM_TRANSMITTER_ACTION_POWER_ON) &&
 	    (action != ATOM_TRANSMITTER_ACTION_POWER_OFF))
-		return;
+		goto done;
 
 	if (!atom_parse_cmd_header(rdev->mode_info.atom_context, index, &frev, &crev))
-		return;
+		goto done;
 
 	memset(&args, 0, sizeof(args));
 
 	args.v1.ucAction = action;
 
 	atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args);
+
+	/* wait for the panel to power up */
+	if (action == ATOM_TRANSMITTER_ACTION_POWER_ON) {
+		int i;
+
+		for (i = 0; i < 300; i++) {
+			if (radeon_hpd_sense(rdev, radeon_connector->hpd.hpd))
+				return true;
+			mdelay(1);
+		}
+		return false;
+	}
+done:
+	return true;
 }
 
 union external_encoder_control {
@@ -1092,13 +1203,19 @@
 	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
 	struct radeon_encoder *ext_radeon_encoder = to_radeon_encoder(ext_encoder);
 	union external_encoder_control args;
-	struct drm_connector *connector = radeon_get_connector_for_encoder(encoder);
+	struct drm_connector *connector;
 	int index = GetIndexIntoMasterTable(COMMAND, ExternalEncoderControl);
 	u8 frev, crev;
 	int dp_clock = 0;
 	int dp_lane_count = 0;
 	int connector_object_id = 0;
 	u32 ext_enum = (ext_radeon_encoder->encoder_enum & ENUM_ID_MASK) >> ENUM_ID_SHIFT;
+	int bpc = 8;
+
+	if (action == EXTERNAL_ENCODER_ACTION_V3_ENCODER_INIT)
+		connector = radeon_get_connector_for_encoder_init(encoder);
+	else
+		connector = radeon_get_connector_for_encoder(encoder);
 
 	if (connector) {
 		struct radeon_connector *radeon_connector = to_radeon_connector(connector);
@@ -1109,6 +1226,7 @@
 		dp_lane_count = dig_connector->dp_lane_count;
 		connector_object_id =
 			(radeon_connector->connector_object_id & OBJECT_ID_MASK) >> OBJECT_ID_SHIFT;
+		bpc = connector->display_info.bpc;
 	}
 
 	memset(&args, 0, sizeof(args));
@@ -1166,7 +1284,27 @@
 				args.v3.sExtEncoder.ucConfig |= EXTERNAL_ENCODER_CONFIG_V3_ENCODER3;
 				break;
 			}
-			args.v3.sExtEncoder.ucBitPerColor = PANEL_8BIT_PER_COLOR;
+			switch (bpc) {
+			case 0:
+				args.v3.sExtEncoder.ucBitPerColor = PANEL_BPC_UNDEFINE;
+				break;
+			case 6:
+				args.v3.sExtEncoder.ucBitPerColor = PANEL_6BIT_PER_COLOR;
+				break;
+			case 8:
+			default:
+				args.v3.sExtEncoder.ucBitPerColor = PANEL_8BIT_PER_COLOR;
+				break;
+			case 10:
+				args.v3.sExtEncoder.ucBitPerColor = PANEL_10BIT_PER_COLOR;
+				break;
+			case 12:
+				args.v3.sExtEncoder.ucBitPerColor = PANEL_12BIT_PER_COLOR;
+				break;
+			case 16:
+				args.v3.sExtEncoder.ucBitPerColor = PANEL_16BIT_PER_COLOR;
+				break;
+			}
 			break;
 		default:
 			DRM_ERROR("Unknown table version: %d, %d\n", frev, crev);
@@ -1294,7 +1432,11 @@
 	if (is_dig) {
 		switch (mode) {
 		case DRM_MODE_DPMS_ON:
-			atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE_OUTPUT, 0, 0);
+			/* some early dce3.2 boards have a bug in their transmitter control table */
+			if ((rdev->family == CHIP_RV710) || (rdev->family == CHIP_RV730))
+				atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE, 0, 0);
+			else
+				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);
 
@@ -1307,9 +1449,11 @@
 								     ATOM_TRANSMITTER_ACTION_POWER_ON);
 					radeon_dig_connector->edp_on = true;
 				}
-				dp_link_train(encoder, connector);
 				if (ASIC_IS_DCE4(rdev))
-					atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_DP_VIDEO_ON);
+					atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_DP_VIDEO_OFF, 0);
+				radeon_dp_link_train(encoder, connector);
+				if (ASIC_IS_DCE4(rdev))
+					atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_DP_VIDEO_ON, 0);
 			}
 			if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT))
 				atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_LCD_BLON, 0, 0);
@@ -1322,7 +1466,7 @@
 				struct drm_connector *connector = radeon_get_connector_for_encoder(encoder);
 
 				if (ASIC_IS_DCE4(rdev))
-					atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_DP_VIDEO_OFF);
+					atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_DP_VIDEO_OFF, 0);
 				if (connector &&
 				    (connector->connector_type == DRM_MODE_CONNECTOR_eDP)) {
 					struct radeon_connector *radeon_connector = to_radeon_connector(connector);
@@ -1383,26 +1527,29 @@
 	}
 
 	if (ext_encoder) {
-		int action;
-
 		switch (mode) {
 		case DRM_MODE_DPMS_ON:
 		default:
-			if (ASIC_IS_DCE41(rdev))
-				action = EXTERNAL_ENCODER_ACTION_V3_ENABLE_OUTPUT;
-			else
-				action = ATOM_ENABLE;
+			if (ASIC_IS_DCE41(rdev)) {
+				atombios_external_encoder_setup(encoder, ext_encoder,
+								EXTERNAL_ENCODER_ACTION_V3_ENABLE_OUTPUT);
+				atombios_external_encoder_setup(encoder, ext_encoder,
+								EXTERNAL_ENCODER_ACTION_V3_ENCODER_BLANKING_OFF);
+			} else
+				atombios_external_encoder_setup(encoder, ext_encoder, ATOM_ENABLE);
 			break;
 		case DRM_MODE_DPMS_STANDBY:
 		case DRM_MODE_DPMS_SUSPEND:
 		case DRM_MODE_DPMS_OFF:
-			if (ASIC_IS_DCE41(rdev))
-				action = EXTERNAL_ENCODER_ACTION_V3_DISABLE_OUTPUT;
-			else
-				action = ATOM_DISABLE;
+			if (ASIC_IS_DCE41(rdev)) {
+				atombios_external_encoder_setup(encoder, ext_encoder,
+								EXTERNAL_ENCODER_ACTION_V3_ENCODER_BLANKING);
+				atombios_external_encoder_setup(encoder, ext_encoder,
+								EXTERNAL_ENCODER_ACTION_V3_DISABLE_OUTPUT);
+			} else
+				atombios_external_encoder_setup(encoder, ext_encoder, ATOM_DISABLE);
 			break;
 		}
-		atombios_external_encoder_setup(encoder, ext_encoder, action);
 	}
 
 	radeon_atombios_encoder_dpms_scratch_regs(encoder, (mode == DRM_MODE_DPMS_ON) ? true : false);
@@ -1601,12 +1748,9 @@
 	/* DCE4/5 */
 	if (ASIC_IS_DCE4(rdev)) {
 		dig = radeon_encoder->enc_priv;
-		if (ASIC_IS_DCE41(rdev)) {
-			if (dig->linkb)
-				return 1;
-			else
-				return 0;
-		} else {
+		if (ASIC_IS_DCE41(rdev))
+			return radeon_crtc->crtc_id;
+		else {
 			switch (radeon_encoder->encoder_id) {
 			case ENCODER_OBJECT_ID_INTERNAL_UNIPHY:
 				if (dig->linkb)
@@ -1662,6 +1806,34 @@
 	return 1;
 }
 
+/* This only needs to be called once at startup */
+void
+radeon_atom_encoder_init(struct radeon_device *rdev)
+{
+	struct drm_device *dev = rdev->ddev;
+	struct drm_encoder *encoder;
+
+	list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
+		struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
+		struct drm_encoder *ext_encoder = radeon_atom_get_external_encoder(encoder);
+
+		switch (radeon_encoder->encoder_id) {
+		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:
+			atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_INIT, 0, 0);
+			break;
+		default:
+			break;
+		}
+
+		if (ext_encoder && ASIC_IS_DCE41(rdev))
+			atombios_external_encoder_setup(encoder, ext_encoder,
+							EXTERNAL_ENCODER_ACTION_V3_ENCODER_INIT);
+	}
+}
+
 static void
 radeon_atom_encoder_mode_set(struct drm_encoder *encoder,
 			     struct drm_display_mode *mode,
@@ -1696,19 +1868,17 @@
 			/* 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);
+			atombios_dig_encoder_setup(encoder, ATOM_ENCODER_CMD_SETUP, 0);
 
-			/* init and enable the transmitter */
-			atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_INIT, 0, 0);
+			/* enable the transmitter */
 			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);
+			atombios_dig_encoder_setup(encoder, ATOM_DISABLE, 0);
 
 			/* 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_encoder_setup(encoder, ATOM_ENABLE, 0);
 			atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_SETUP, 0, 0);
 			atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_ENABLE, 0, 0);
 		}
@@ -1733,12 +1903,10 @@
 	}
 
 	if (ext_encoder) {
-		if (ASIC_IS_DCE41(rdev)) {
-			atombios_external_encoder_setup(encoder, ext_encoder,
-							EXTERNAL_ENCODER_ACTION_V3_ENCODER_INIT);
+		if (ASIC_IS_DCE41(rdev))
 			atombios_external_encoder_setup(encoder, ext_encoder,
 							EXTERNAL_ENCODER_ACTION_V3_ENCODER_SETUP);
-		} else
+		else
 			atombios_external_encoder_setup(encoder, ext_encoder, ATOM_ENABLE);
 	}
 
@@ -1840,13 +2008,73 @@
 	return connector_status_disconnected;
 }
 
+static enum drm_connector_status
+radeon_atom_dig_detect(struct drm_encoder *encoder, struct drm_connector *connector)
+{
+	struct drm_device *dev = encoder->dev;
+	struct radeon_device *rdev = dev->dev_private;
+	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
+	struct radeon_connector *radeon_connector = to_radeon_connector(connector);
+	struct drm_encoder *ext_encoder = radeon_atom_get_external_encoder(encoder);
+	u32 bios_0_scratch;
+
+	if (!ASIC_IS_DCE4(rdev))
+		return connector_status_unknown;
+
+	if (!ext_encoder)
+		return connector_status_unknown;
+
+	if ((radeon_connector->devices & ATOM_DEVICE_CRT_SUPPORT) == 0)
+		return connector_status_unknown;
+
+	/* load detect on the dp bridge */
+	atombios_external_encoder_setup(encoder, ext_encoder,
+					EXTERNAL_ENCODER_ACTION_V3_DACLOAD_DETECTION);
+
+	bios_0_scratch = RREG32(R600_BIOS_0_SCRATCH);
+
+	DRM_DEBUG_KMS("Bios 0 scratch %x %08x\n", bios_0_scratch, radeon_encoder->devices);
+	if (radeon_connector->devices & ATOM_DEVICE_CRT1_SUPPORT) {
+		if (bios_0_scratch & ATOM_S0_CRT1_MASK)
+			return connector_status_connected;
+	}
+	if (radeon_connector->devices & ATOM_DEVICE_CRT2_SUPPORT) {
+		if (bios_0_scratch & ATOM_S0_CRT2_MASK)
+			return connector_status_connected;
+	}
+	if (radeon_connector->devices & ATOM_DEVICE_CV_SUPPORT) {
+		if (bios_0_scratch & (ATOM_S0_CV_MASK|ATOM_S0_CV_MASK_A))
+			return connector_status_connected;
+	}
+	if (radeon_connector->devices & ATOM_DEVICE_TV1_SUPPORT) {
+		if (bios_0_scratch & (ATOM_S0_TV1_COMPOSITE | ATOM_S0_TV1_COMPOSITE_A))
+			return connector_status_connected; /* CTV */
+		else if (bios_0_scratch & (ATOM_S0_TV1_SVIDEO | ATOM_S0_TV1_SVIDEO_A))
+			return connector_status_connected; /* STV */
+	}
+	return connector_status_disconnected;
+}
+
+void
+radeon_atom_ext_encoder_setup_ddc(struct drm_encoder *encoder)
+{
+	struct drm_encoder *ext_encoder = radeon_atom_get_external_encoder(encoder);
+
+	if (ext_encoder)
+		/* ddc_setup on the dp bridge */
+		atombios_external_encoder_setup(encoder, ext_encoder,
+						EXTERNAL_ENCODER_ACTION_V3_DDC_SETUP);
+
+}
+
 static void radeon_atom_encoder_prepare(struct drm_encoder *encoder)
 {
 	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
 	struct drm_connector *connector = radeon_get_connector_for_encoder(encoder);
 
-	if (radeon_encoder->active_device &
-	    (ATOM_DEVICE_DFP_SUPPORT | ATOM_DEVICE_LCD_SUPPORT)) {
+	if ((radeon_encoder->active_device &
+	     (ATOM_DEVICE_DFP_SUPPORT | ATOM_DEVICE_LCD_SUPPORT)) ||
+	    radeon_encoder_is_dp_bridge(encoder)) {
 		struct radeon_encoder_atom_dig *dig = radeon_encoder->enc_priv;
 		if (dig)
 			dig->dig_encoder = radeon_atom_pick_dig_encoder(encoder);
@@ -1855,11 +2083,17 @@
 	radeon_atom_output_lock(encoder, true);
 	radeon_atom_encoder_dpms(encoder, DRM_MODE_DPMS_OFF);
 
-	/* select the clock/data port if it uses a router */
 	if (connector) {
 		struct radeon_connector *radeon_connector = to_radeon_connector(connector);
+
+		/* select the clock/data port if it uses a router */
 		if (radeon_connector->router.cd_valid)
 			radeon_router_select_cd_port(radeon_connector);
+
+		/* turn eDP panel on for mode set */
+		if (connector->connector_type == DRM_MODE_CONNECTOR_eDP)
+			atombios_set_edp_panel_power(connector,
+						     ATOM_TRANSMITTER_ACTION_POWER_ON);
 	}
 
 	/* this is needed for the pll/ss setup to work correctly in some cases */
@@ -1914,7 +2148,7 @@
 		else {
 			/* disable the encoder and transmitter */
 			atombios_dig_transmitter_setup(encoder, ATOM_TRANSMITTER_ACTION_DISABLE, 0, 0);
-			atombios_dig_encoder_setup(encoder, ATOM_DISABLE);
+			atombios_dig_encoder_setup(encoder, ATOM_DISABLE, 0);
 		}
 		break;
 	case ENCODER_OBJECT_ID_INTERNAL_DDI:
@@ -1996,7 +2230,7 @@
 	.mode_set = radeon_atom_encoder_mode_set,
 	.commit = radeon_atom_encoder_commit,
 	.disable = radeon_atom_encoder_disable,
-	/* no detect for TMDS/LVDS yet */
+	.detect = radeon_atom_dig_detect,
 };
 
 static const struct drm_encoder_helper_funcs radeon_atom_dac_helper_funcs = {
@@ -2116,8 +2350,6 @@
 		} else {
 			drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs, DRM_MODE_ENCODER_TMDS);
 			radeon_encoder->enc_priv = radeon_atombios_set_dig_info(radeon_encoder);
-			if (ASIC_IS_AVIVO(rdev))
-				radeon_encoder->underscan_type = UNDERSCAN_AUTO;
 		}
 		drm_encoder_helper_add(encoder, &radeon_atom_dig_helper_funcs);
 		break;
@@ -2150,8 +2382,6 @@
 		} else {
 			drm_encoder_init(dev, encoder, &radeon_atom_enc_funcs, DRM_MODE_ENCODER_TMDS);
 			radeon_encoder->enc_priv = radeon_atombios_set_dig_info(radeon_encoder);
-			if (ASIC_IS_AVIVO(rdev))
-				radeon_encoder->underscan_type = UNDERSCAN_AUTO;
 		}
 		drm_encoder_helper_add(encoder, &radeon_atom_dig_helper_funcs);
 		break;
diff -druN linux-2.6.39-libre/drivers/gpu/drm/radeon/radeon_family.h linux-3.0-rc7-libre/drivers/gpu/drm/radeon/radeon_family.h
--- linux-2.6.39-libre/drivers/gpu/drm/radeon/radeon_family.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/gpu/drm/radeon/radeon_family.h	2011-07-11 19:51:52.000000000 -0400
@@ -81,6 +81,8 @@
 	CHIP_CYPRESS,
 	CHIP_HEMLOCK,
 	CHIP_PALM,
+	CHIP_SUMO,
+	CHIP_SUMO2,
 	CHIP_BARTS,
 	CHIP_TURKS,
 	CHIP_CAICOS,
diff -druN linux-2.6.39-libre/drivers/gpu/drm/radeon/radeon_fence.c linux-3.0-rc7-libre/drivers/gpu/drm/radeon/radeon_fence.c
--- linux-2.6.39-libre/drivers/gpu/drm/radeon/radeon_fence.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/gpu/drm/radeon/radeon_fence.c	2011-07-11 19:51:52.000000000 -0400
@@ -40,6 +40,35 @@
 #include "radeon.h"
 #include "radeon_trace.h"
 
+static void radeon_fence_write(struct radeon_device *rdev, u32 seq)
+{
+	if (rdev->wb.enabled) {
+		u32 scratch_index;
+		if (rdev->wb.use_event)
+			scratch_index = R600_WB_EVENT_OFFSET + rdev->fence_drv.scratch_reg - rdev->scratch.reg_base;
+		else
+			scratch_index = RADEON_WB_SCRATCH_OFFSET + rdev->fence_drv.scratch_reg - rdev->scratch.reg_base;
+		rdev->wb.wb[scratch_index/4] = cpu_to_le32(seq);;
+	} else
+		WREG32(rdev->fence_drv.scratch_reg, seq);
+}
+
+static u32 radeon_fence_read(struct radeon_device *rdev)
+{
+	u32 seq;
+
+	if (rdev->wb.enabled) {
+		u32 scratch_index;
+		if (rdev->wb.use_event)
+			scratch_index = R600_WB_EVENT_OFFSET + rdev->fence_drv.scratch_reg - rdev->scratch.reg_base;
+		else
+			scratch_index = RADEON_WB_SCRATCH_OFFSET + rdev->fence_drv.scratch_reg - rdev->scratch.reg_base;
+		seq = le32_to_cpu(rdev->wb.wb[scratch_index/4]);
+	} else
+		seq = RREG32(rdev->fence_drv.scratch_reg);
+	return seq;
+}
+
 int radeon_fence_emit(struct radeon_device *rdev, struct radeon_fence *fence)
 {
 	unsigned long irq_flags;
@@ -50,12 +79,12 @@
 		return 0;
 	}
 	fence->seq = atomic_add_return(1, &rdev->fence_drv.seq);
-	if (!rdev->cp.ready) {
+	if (!rdev->cp.ready)
 		/* FIXME: cp is not running assume everythings is done right
 		 * away
 		 */
-		WREG32(rdev->fence_drv.scratch_reg, fence->seq);
-	} else
+		radeon_fence_write(rdev, fence->seq);
+	else
 		radeon_fence_ring_emit(rdev, fence);
 
 	trace_radeon_fence_emit(rdev->ddev, fence->seq);
@@ -73,15 +102,7 @@
 	bool wake = false;
 	unsigned long cjiffies;
 
-	if (rdev->wb.enabled) {
-		u32 scratch_index;
-		if (rdev->wb.use_event)
-			scratch_index = R600_WB_EVENT_OFFSET + rdev->fence_drv.scratch_reg - rdev->scratch.reg_base;
-		else
-			scratch_index = RADEON_WB_SCRATCH_OFFSET + rdev->fence_drv.scratch_reg - rdev->scratch.reg_base;
-		seq = le32_to_cpu(rdev->wb.wb[scratch_index/4]);
-	} else
-		seq = RREG32(rdev->fence_drv.scratch_reg);
+	seq = radeon_fence_read(rdev);
 	if (seq != rdev->fence_drv.last_seq) {
 		rdev->fence_drv.last_seq = seq;
 		rdev->fence_drv.last_jiffies = jiffies;
@@ -251,7 +272,7 @@
 			r = radeon_gpu_reset(rdev);
 			if (r)
 				return r;
-			WREG32(rdev->fence_drv.scratch_reg, fence->seq);
+			radeon_fence_write(rdev, fence->seq);
 			rdev->gpu_lockup = false;
 		}
 		timeout = RADEON_FENCE_JIFFIES_TIMEOUT;
@@ -322,7 +343,7 @@
 
 	*fence = NULL;
 	if (tmp) {
-		kref_put(&tmp->kref, &radeon_fence_destroy);
+		kref_put(&tmp->kref, radeon_fence_destroy);
 	}
 }
 
@@ -351,7 +372,7 @@
 		write_unlock_irqrestore(&rdev->fence_drv.lock, irq_flags);
 		return r;
 	}
-	WREG32(rdev->fence_drv.scratch_reg, 0);
+	radeon_fence_write(rdev, 0);
 	atomic_set(&rdev->fence_drv.seq, 0);
 	INIT_LIST_HEAD(&rdev->fence_drv.created);
 	INIT_LIST_HEAD(&rdev->fence_drv.emited);
@@ -391,7 +412,7 @@
 	struct radeon_fence *fence;
 
 	seq_printf(m, "Last signaled fence 0x%08X\n",
-		   RREG32(rdev->fence_drv.scratch_reg));
+		   radeon_fence_read(rdev));
 	if (!list_empty(&rdev->fence_drv.emited)) {
 		   fence = list_entry(rdev->fence_drv.emited.prev,
 				      struct radeon_fence, list);
diff -druN linux-2.6.39-libre/drivers/gpu/drm/radeon/radeon.h linux-3.0-rc7-libre/drivers/gpu/drm/radeon/radeon.h
--- linux-2.6.39-libre/drivers/gpu/drm/radeon/radeon.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/gpu/drm/radeon/radeon.h	2011-07-11 19:51:52.000000000 -0400
@@ -165,6 +165,7 @@
 	uint32_t default_sclk;
 	uint32_t default_dispclk;
 	uint32_t dp_extclk;
+	uint32_t max_pixel_clock;
 };
 
 /*
@@ -178,6 +179,7 @@
 void radeon_combios_get_power_modes(struct radeon_device *rdev);
 void radeon_atombios_get_power_modes(struct radeon_device *rdev);
 void radeon_atom_set_voltage(struct radeon_device *rdev, u16 voltage_level, u8 voltage_type);
+int radeon_atom_get_max_vddc(struct radeon_device *rdev, u16 *voltage);
 void rs690_pm_info(struct radeon_device *rdev);
 extern int rv6xx_get_temp(struct radeon_device *rdev);
 extern int rv770_get_temp(struct radeon_device *rdev);
diff -druN linux-2.6.39-libre/drivers/gpu/drm/radeon/radeon_i2c.c linux-3.0-rc7-libre/drivers/gpu/drm/radeon/radeon_i2c.c
--- linux-2.6.39-libre/drivers/gpu/drm/radeon/radeon_i2c.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/gpu/drm/radeon/radeon_i2c.c	2011-07-11 19:51:52.000000000 -0400
@@ -888,6 +888,7 @@
 
 	i2c->rec = *rec;
 	i2c->adapter.owner = THIS_MODULE;
+	i2c->adapter.class = I2C_CLASS_DDC;
 	i2c->dev = dev;
 	i2c_set_adapdata(&i2c->adapter, i2c);
 	if (rec->mm_i2c ||
@@ -947,6 +948,7 @@
 
 	i2c->rec = *rec;
 	i2c->adapter.owner = THIS_MODULE;
+	i2c->adapter.class = I2C_CLASS_DDC;
 	i2c->dev = dev;
 	snprintf(i2c->adapter.name, sizeof(i2c->adapter.name),
 		 "Radeon aux bus %s", name);
diff -druN linux-2.6.39-libre/drivers/gpu/drm/radeon/radeon_mode.h linux-3.0-rc7-libre/drivers/gpu/drm/radeon/radeon_mode.h
--- linux-2.6.39-libre/drivers/gpu/drm/radeon/radeon_mode.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/gpu/drm/radeon/radeon_mode.h	2011-07-11 19:51:52.000000000 -0400
@@ -464,22 +464,29 @@
 extern struct drm_connector *
 radeon_get_connector_for_encoder(struct drm_encoder *encoder);
 
+extern bool radeon_encoder_is_dp_bridge(struct drm_encoder *encoder);
+extern bool radeon_connector_encoder_is_dp_bridge(struct drm_connector *connector);
+extern bool radeon_connector_encoder_is_hbr2(struct drm_connector *connector);
+extern bool radeon_connector_is_dp12_capable(struct drm_connector *connector);
+
 extern void radeon_connector_hotplug(struct drm_connector *connector);
-extern bool radeon_dp_needs_link_train(struct radeon_connector *radeon_connector);
-extern int radeon_dp_mode_valid_helper(struct radeon_connector *radeon_connector,
+extern int radeon_dp_mode_valid_helper(struct drm_connector *connector,
 				       struct drm_display_mode *mode);
 extern void radeon_dp_set_link_config(struct drm_connector *connector,
 				      struct drm_display_mode *mode);
-extern void dp_link_train(struct drm_encoder *encoder,
-			  struct drm_connector *connector);
+extern void radeon_dp_link_train(struct drm_encoder *encoder,
+				 struct drm_connector *connector);
 extern u8 radeon_dp_getsinktype(struct radeon_connector *radeon_connector);
 extern bool radeon_dp_getdpcd(struct radeon_connector *radeon_connector);
-extern void atombios_dig_encoder_setup(struct drm_encoder *encoder, int action);
+extern void atombios_dig_encoder_setup(struct drm_encoder *encoder, int action, int panel_mode);
+extern void radeon_atom_encoder_init(struct radeon_device *rdev);
 extern void atombios_dig_transmitter_setup(struct drm_encoder *encoder,
 					   int action, uint8_t lane_num,
 					   uint8_t lane_set);
+extern void radeon_atom_ext_encoder_setup_ddc(struct drm_encoder *encoder);
+extern struct drm_encoder *radeon_atom_get_external_encoder(struct drm_encoder *encoder);
 extern int radeon_dp_i2c_aux_ch(struct i2c_adapter *adapter, int mode,
-				uint8_t write_byte, uint8_t *read_byte);
+				u8 write_byte, u8 *read_byte);
 
 extern void radeon_i2c_init(struct radeon_device *rdev);
 extern void radeon_i2c_fini(struct radeon_device *rdev);
@@ -545,7 +552,7 @@
 extern void atombios_dvo_setup(struct drm_encoder *encoder, int action);
 extern void atombios_digital_setup(struct drm_encoder *encoder, int action);
 extern int atombios_get_encoder_mode(struct drm_encoder *encoder);
-extern void atombios_set_edp_panel_power(struct drm_connector *connector, int action);
+extern bool atombios_set_edp_panel_power(struct drm_connector *connector, int action);
 extern void radeon_encoder_set_active_device(struct drm_encoder *encoder);
 
 extern void radeon_crtc_load_lut(struct drm_crtc *crtc);
diff -druN linux-2.6.39-libre/drivers/gpu/drm/radeon/radeon_pm.c linux-3.0-rc7-libre/drivers/gpu/drm/radeon/radeon_pm.c
--- linux-2.6.39-libre/drivers/gpu/drm/radeon/radeon_pm.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/gpu/drm/radeon/radeon_pm.c	2011-07-11 19:51:52.000000000 -0400
@@ -487,6 +487,7 @@
 	case THERMAL_TYPE_RV6XX:
 	case THERMAL_TYPE_RV770:
 	case THERMAL_TYPE_EVERGREEN:
+	case THERMAL_TYPE_NI:
 	case THERMAL_TYPE_SUMO:
 		rdev->pm.int_hwmon_dev = hwmon_device_register(rdev->dev);
 		if (IS_ERR(rdev->pm.int_hwmon_dev)) {
diff -druN linux-2.6.39-libre/drivers/gpu/drm/radeon/radeon_ring.c linux-3.0-rc7-libre/drivers/gpu/drm/radeon/radeon_ring.c
--- linux-2.6.39-libre/drivers/gpu/drm/radeon/radeon_ring.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/gpu/drm/radeon/radeon_ring.c	2011-07-11 19:51:52.000000000 -0400
@@ -194,7 +194,7 @@
 	r = radeon_bo_kmap(rdev->ib_pool.robj, &ptr);
 	radeon_bo_unreserve(rdev->ib_pool.robj);
 	if (r) {
-		DRM_ERROR("radeon: failed to map ib poll (%d).\n", r);
+		DRM_ERROR("radeon: failed to map ib pool (%d).\n", r);
 		return r;
 	}
 	for (i = 0; i < RADEON_IB_POOL_SIZE; i++) {
diff -druN linux-2.6.39-libre/drivers/gpu/drm/radeon/reg_srcs/r600 linux-3.0-rc7-libre/drivers/gpu/drm/radeon/reg_srcs/r600
--- linux-2.6.39-libre/drivers/gpu/drm/radeon/reg_srcs/r600	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/gpu/drm/radeon/reg_srcs/r600	2011-07-11 19:51:52.000000000 -0400
@@ -758,6 +758,5 @@
 0x00009714 VC_ENHANCE
 0x00009830 DB_DEBUG
 0x00009838 DB_WATERMARKS
-0x00028D28 DB_SRESULTS_COMPARE_STATE0
 0x00028D44 DB_ALPHA_TO_MASK
 0x00009700 VC_CNTL
diff -druN linux-2.6.39-libre/drivers/gpu/drm/radeon/rv770.c linux-3.0-rc7-libre/drivers/gpu/drm/radeon/rv770.c
--- linux-2.6.39-libre/drivers/gpu/drm/radeon/rv770.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/gpu/drm/radeon/rv770.c	2011-07-11 19:51:52.000000000 -0400
@@ -105,6 +105,9 @@
 	struct radeon_voltage *voltage = &ps->clock_info[req_cm_idx].voltage;
 
 	if ((voltage->type == VOLTAGE_SW) && voltage->voltage) {
+		/* 0xff01 is a flag rather then an actual voltage */
+		if (voltage->voltage == 0xff01)
+			return;
 		if (voltage->voltage != rdev->pm.current_vddc) {
 			radeon_atom_set_voltage(rdev, voltage->voltage, SET_VOLTAGE_TYPE_ASIC_VDDC);
 			rdev->pm.current_vddc = voltage->voltage;
@@ -572,6 +575,12 @@
 	else
 		tcp_chan_steer = 0x00fac688;
 
+	/* RV770 CE has special chremap setup */
+	if (rdev->pdev->device == 0x944e) {
+		tcp_chan_steer = 0x00b08b08;
+		mc_shared_chremap = 0x00b08b08;
+	}
+
 	WREG32(TCP_CHAN_STEER, tcp_chan_steer);
 	WREG32(MC_SHARED_CHREMAP, mc_shared_chremap);
 }
@@ -1359,6 +1368,7 @@
 	r700_cp_fini(rdev);
 	r600_irq_fini(rdev);
 	radeon_wb_fini(rdev);
+	radeon_ib_pool_fini(rdev);
 	radeon_irq_kms_fini(rdev);
 	rv770_pcie_gart_fini(rdev);
 	rv770_vram_scratch_fini(rdev);
diff -druN linux-2.6.39-libre/drivers/gpu/drm/savage/savage_bci.c linux-3.0-rc7-libre/drivers/gpu/drm/savage/savage_bci.c
--- linux-2.6.39-libre/drivers/gpu/drm/savage/savage_bci.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/gpu/drm/savage/savage_bci.c	2011-07-11 19:51:52.000000000 -0400
@@ -647,9 +647,6 @@
 	ret = drm_addmap(dev, aperture_base, SAVAGE_APERTURE_SIZE,
 			 _DRM_FRAME_BUFFER, _DRM_WRITE_COMBINING,
 			 &dev_priv->aperture);
-	if (ret)
-		return ret;
-
 	return ret;
 }
 
diff -druN linux-2.6.39-libre/drivers/gpu/drm/ttm/ttm_object.c linux-3.0-rc7-libre/drivers/gpu/drm/ttm/ttm_object.c
--- linux-2.6.39-libre/drivers/gpu/drm/ttm/ttm_object.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/gpu/drm/ttm/ttm_object.c	2011-07-11 19:51:52.000000000 -0400
@@ -206,7 +206,7 @@
 	 */
 
 	write_lock(&tdev->object_lock);
-	(void)kref_put(&base->refcount, &ttm_release_base);
+	kref_put(&base->refcount, ttm_release_base);
 	write_unlock(&tdev->object_lock);
 }
 EXPORT_SYMBOL(ttm_base_object_unref);
diff -druN linux-2.6.39-libre/drivers/gpu/drm/ttm/ttm_page_alloc.c linux-3.0-rc7-libre/drivers/gpu/drm/ttm/ttm_page_alloc.c
--- linux-2.6.39-libre/drivers/gpu/drm/ttm/ttm_page_alloc.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/gpu/drm/ttm/ttm_page_alloc.c	2011-07-11 19:51:52.000000000 -0400
@@ -395,12 +395,14 @@
 /**
  * Callback for mm to request pool to reduce number of page held.
  */
-static int ttm_pool_mm_shrink(struct shrinker *shrink, int shrink_pages, gfp_t gfp_mask)
+static int ttm_pool_mm_shrink(struct shrinker *shrink,
+			      struct shrink_control *sc)
 {
 	static atomic_t start_pool = ATOMIC_INIT(0);
 	unsigned i;
 	unsigned pool_offset = atomic_add_return(1, &start_pool);
 	struct ttm_page_pool *pool;
+	int shrink_pages = sc->nr_to_scan;
 
 	pool_offset = pool_offset % NUM_POOLS;
 	/* select start pool in round robin fashion */
diff -druN linux-2.6.39-libre/drivers/gpu/drm/ttm/ttm_tt.c linux-3.0-rc7-libre/drivers/gpu/drm/ttm/ttm_tt.c
--- linux-2.6.39-libre/drivers/gpu/drm/ttm/ttm_tt.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/gpu/drm/ttm/ttm_tt.c	2011-07-11 19:51:52.000000000 -0400
@@ -31,6 +31,7 @@
 #include <linux/sched.h>
 #include <linux/highmem.h>
 #include <linux/pagemap.h>
+#include <linux/shmem_fs.h>
 #include <linux/file.h>
 #include <linux/swap.h>
 #include <linux/slab.h>
@@ -484,7 +485,7 @@
 	swap_space = swap_storage->f_path.dentry->d_inode->i_mapping;
 
 	for (i = 0; i < ttm->num_pages; ++i) {
-		from_page = read_mapping_page(swap_space, i, NULL);
+		from_page = shmem_read_mapping_page(swap_space, i);
 		if (IS_ERR(from_page)) {
 			ret = PTR_ERR(from_page);
 			goto out_err;
@@ -557,7 +558,7 @@
 		from_page = ttm->pages[i];
 		if (unlikely(from_page == NULL))
 			continue;
-		to_page = read_mapping_page(swap_space, i, NULL);
+		to_page = shmem_read_mapping_page(swap_space, i);
 		if (unlikely(IS_ERR(to_page))) {
 			ret = PTR_ERR(to_page);
 			goto out_err;
diff -druN linux-2.6.39-libre/drivers/gpu/vga/vgaarb.c linux-3.0-rc7-libre/drivers/gpu/vga/vgaarb.c
--- linux-2.6.39-libre/drivers/gpu/vga/vgaarb.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/gpu/vga/vgaarb.c	2011-07-11 19:51:52.000000000 -0400
@@ -61,7 +61,7 @@
 	unsigned int mem_lock_cnt;	/* legacy MEM lock count */
 	unsigned int io_norm_cnt;	/* normal IO count */
 	unsigned int mem_norm_cnt;	/* normal MEM count */
-
+	bool bridge_has_one_vga;
 	/* allow IRQ enable/disable hook */
 	void *cookie;
 	void (*irq_set_state)(void *cookie, bool enable);
@@ -165,6 +165,8 @@
 	unsigned int wants, legacy_wants, match;
 	struct vga_device *conflict;
 	unsigned int pci_bits;
+	u32 flags = 0;
+
 	/* Account for "normal" resources to lock. If we decode the legacy,
 	 * counterpart, we need to request it as well
 	 */
@@ -237,16 +239,23 @@
 		/* looks like he doesn't have a lock, we can steal
 		 * them from him
 		 */
-		vga_irq_set_state(conflict, false);
 
+		flags = 0;
 		pci_bits = 0;
-		if (lwants & (VGA_RSRC_LEGACY_MEM|VGA_RSRC_NORMAL_MEM))
-			pci_bits |= PCI_COMMAND_MEMORY;
-		if (lwants & (VGA_RSRC_LEGACY_IO|VGA_RSRC_NORMAL_IO))
-			pci_bits |= PCI_COMMAND_IO;
 
-		pci_set_vga_state(conflict->pdev, false, pci_bits,
-				  change_bridge);
+		if (!conflict->bridge_has_one_vga) {
+			vga_irq_set_state(conflict, false);
+			flags |= PCI_VGA_STATE_CHANGE_DECODES;
+			if (lwants & (VGA_RSRC_LEGACY_MEM|VGA_RSRC_NORMAL_MEM))
+				pci_bits |= PCI_COMMAND_MEMORY;
+			if (lwants & (VGA_RSRC_LEGACY_IO|VGA_RSRC_NORMAL_IO))
+				pci_bits |= PCI_COMMAND_IO;
+		}
+
+		if (change_bridge)
+			flags |= PCI_VGA_STATE_CHANGE_BRIDGE;
+
+		pci_set_vga_state(conflict->pdev, false, pci_bits, flags);
 		conflict->owns &= ~lwants;
 		/* If he also owned non-legacy, that is no longer the case */
 		if (lwants & VGA_RSRC_LEGACY_MEM)
@@ -261,14 +270,24 @@
 	 * also have in "decodes". We can lock resources we don't decode but
 	 * not own them.
 	 */
+	flags = 0;
 	pci_bits = 0;
-	if (wants & (VGA_RSRC_LEGACY_MEM|VGA_RSRC_NORMAL_MEM))
-		pci_bits |= PCI_COMMAND_MEMORY;
-	if (wants & (VGA_RSRC_LEGACY_IO|VGA_RSRC_NORMAL_IO))
-		pci_bits |= PCI_COMMAND_IO;
-	pci_set_vga_state(vgadev->pdev, true, pci_bits, !!(wants & VGA_RSRC_LEGACY_MASK));
 
-	vga_irq_set_state(vgadev, true);
+	if (!vgadev->bridge_has_one_vga) {
+		flags |= PCI_VGA_STATE_CHANGE_DECODES;
+		if (wants & (VGA_RSRC_LEGACY_MEM|VGA_RSRC_NORMAL_MEM))
+			pci_bits |= PCI_COMMAND_MEMORY;
+		if (wants & (VGA_RSRC_LEGACY_IO|VGA_RSRC_NORMAL_IO))
+			pci_bits |= PCI_COMMAND_IO;
+	}
+	if (!!(wants & VGA_RSRC_LEGACY_MASK))
+		flags |= PCI_VGA_STATE_CHANGE_BRIDGE;
+
+	pci_set_vga_state(vgadev->pdev, true, pci_bits, flags);
+
+	if (!vgadev->bridge_has_one_vga) {
+		vga_irq_set_state(vgadev, true);
+	}
 	vgadev->owns |= (wants & vgadev->decodes);
 lock_them:
 	vgadev->locks |= (rsrc & VGA_RSRC_LEGACY_MASK);
@@ -421,6 +440,62 @@
 }
 EXPORT_SYMBOL(vga_put);
 
+/* Rules for using a bridge to control a VGA descendant decoding:
+   if a bridge has only one VGA descendant then it can be used
+   to control the VGA routing for that device.
+   It should always use the bridge closest to the device to control it.
+   If a bridge has a direct VGA descendant, but also have a sub-bridge
+   VGA descendant then we cannot use that bridge to control the direct VGA descendant.
+   So for every device we register, we need to iterate all its parent bridges
+   so we can invalidate any devices using them properly.
+*/
+static void vga_arbiter_check_bridge_sharing(struct vga_device *vgadev)
+{
+	struct vga_device *same_bridge_vgadev;
+	struct pci_bus *new_bus, *bus;
+	struct pci_dev *new_bridge, *bridge;
+
+	vgadev->bridge_has_one_vga = true;
+
+	if (list_empty(&vga_list))
+		return;
+
+	/* okay iterate the new devices bridge hierarachy */
+	new_bus = vgadev->pdev->bus;
+	while (new_bus) {
+		new_bridge = new_bus->self;
+
+		if (new_bridge) {
+			/* go through list of devices already registered */
+			list_for_each_entry(same_bridge_vgadev, &vga_list, list) {
+				bus = same_bridge_vgadev->pdev->bus;
+				bridge = bus->self;
+
+				/* see if the share a bridge with this device */
+				if (new_bridge == bridge) {
+					/* if their direct parent bridge is the same
+					   as any bridge of this device then it can't be used
+					   for that device */
+					same_bridge_vgadev->bridge_has_one_vga = false;
+				}
+
+				/* now iterate the previous devices bridge hierarchy */
+				/* if the new devices parent bridge is in the other devices
+				   hierarchy then we can't use it to control this device */
+				while (bus) {
+					bridge = bus->self;
+					if (bridge) {
+						if (bridge == vgadev->pdev->bus->self)
+							vgadev->bridge_has_one_vga = false;
+					}
+					bus = bus->parent;
+				}
+			}
+		}
+		new_bus = new_bus->parent;
+	}
+}
+
 /*
  * Currently, we assume that the "initial" setup of the system is
  * not sane, that is we come up with conflicting devices and let
@@ -500,6 +575,8 @@
 		vga_default = pci_dev_get(pdev);
 #endif
 
+	vga_arbiter_check_bridge_sharing(vgadev);
+
 	/* Add to the list */
 	list_add(&vgadev->list, &vga_list);
 	vga_count++;
@@ -1222,6 +1299,7 @@
 {
 	int rc;
 	struct pci_dev *pdev;
+	struct vga_device *vgadev;
 
 	rc = misc_register(&vga_arb_device);
 	if (rc < 0)
@@ -1238,6 +1316,13 @@
 		vga_arbiter_add_pci_device(pdev);
 
 	pr_info("vgaarb: loaded\n");
+
+	list_for_each_entry(vgadev, &vga_list, list) {
+		if (vgadev->bridge_has_one_vga)
+			pr_info("vgaarb: bridge control possible %s\n", pci_name(vgadev->pdev));
+		else
+			pr_info("vgaarb: no bridge control possible %s\n", pci_name(vgadev->pdev));
+	}
 	return rc;
 }
 subsys_initcall(vga_arb_device_init);
diff -druN linux-2.6.39-libre/drivers/gpu/vga/vga_switcheroo.c linux-3.0-rc7-libre/drivers/gpu/vga/vga_switcheroo.c
--- linux-2.6.39-libre/drivers/gpu/vga/vga_switcheroo.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/gpu/vga/vga_switcheroo.c	2011-07-11 19:51:52.000000000 -0400
@@ -215,7 +215,6 @@
 /* stage one happens before delay */
 static int vga_switchto_stage1(struct vga_switcheroo_client *new_client)
 {
-	int ret;
 	int i;
 	struct vga_switcheroo_client *active = NULL;
 
@@ -228,11 +227,6 @@
 	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);
 
diff -druN linux-2.6.39-libre/drivers/hid/hid-3m-pct.c linux-3.0-rc7-libre/drivers/hid/hid-3m-pct.c
--- linux-2.6.39-libre/drivers/hid/hid-3m-pct.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/hid/hid-3m-pct.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,305 +0,0 @@
-/*
- *  HID driver for 3M PCT multitouch panels
- *
- *  Copyright (c) 2009-2010 Stephane Chatty <chatty@enac.fr>
- *  Copyright (c) 2010      Henrik Rydberg <rydberg@euromail.se>
- *  Copyright (c) 2010      Canonical, Ltd.
- *
- */
-
-/*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the Free
- * Software Foundation; either version 2 of the License, or (at your option)
- * any later version.
- */
-
-#include <linux/device.h>
-#include <linux/hid.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/usb.h>
-#include <linux/input/mt.h>
-
-MODULE_AUTHOR("Stephane Chatty <chatty@enac.fr>");
-MODULE_DESCRIPTION("3M PCT multitouch panels");
-MODULE_LICENSE("GPL");
-
-#include "hid-ids.h"
-
-#define MAX_SLOTS		60
-
-/* estimated signal-to-noise ratios */
-#define SN_MOVE			2048
-#define SN_WIDTH		128
-
-struct mmm_finger {
-	__s32 x, y, w, h;
-	bool touch, valid;
-};
-
-struct mmm_data {
-	struct mmm_finger f[MAX_SLOTS];
-	__u8 curid;
-	__u8 nexp, nreal;
-	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)
-{
-	int f1 = field->logical_minimum;
-	int f2 = field->logical_maximum;
-	int df = f2 - f1;
-
-	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);
-			input_set_abs_params(hi->input, ABS_MT_POSITION_X,
-					     f1, f2, df / SN_MOVE, 0);
-			/* touchscreen emulation */
-			input_set_abs_params(hi->input, ABS_X,
-					     f1, f2, df / SN_MOVE, 0);
-			return 1;
-		case HID_GD_Y:
-			hid_map_usage(hi, usage, bit, max,
-					EV_ABS, ABS_MT_POSITION_Y);
-			input_set_abs_params(hi->input, ABS_MT_POSITION_Y,
-					     f1, f2, df / SN_MOVE, 0);
-			/* touchscreen emulation */
-			input_set_abs_params(hi->input, ABS_Y,
-					     f1, f2, df / SN_MOVE, 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);
-			input_set_capability(hi->input, EV_KEY, BTN_TOUCH);
-			return 1;
-		case HID_DG_WIDTH:
-			hid_map_usage(hi, usage, bit, max,
-					EV_ABS, ABS_MT_TOUCH_MAJOR);
-			input_set_abs_params(hi->input, ABS_MT_TOUCH_MAJOR,
-					     f1, f2, df / SN_WIDTH, 0);
-			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_TOUCH_MINOR,
-					     f1, f2, df / SN_WIDTH, 0);
-			input_set_abs_params(hi->input, ABS_MT_ORIENTATION,
-					0, 1, 0, 0);
-			return 1;
-		case HID_DG_CONTACTID:
-			input_mt_init_slots(hi->input, MAX_SLOTS);
-			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)
-{
-	/* tell hid-input to skip setup of these event types */
-	if (usage->type == EV_KEY || usage->type == EV_ABS)
-		set_bit(usage->type, hi->input->evbit);
-	return -1;
-}
-
-/*
- * 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)
-{
-	int i;
-	for (i = 0; i < MAX_SLOTS; ++i) {
-		struct mmm_finger *f = &md->f[i];
-		if (!f->valid) {
-			/* this finger is just placeholder data, ignore */
-			continue;
-		}
-		input_mt_slot(input, i);
-		input_mt_report_slot_state(input, MT_TOOL_FINGER, f->touch);
-		if (f->touch) {
-			/* this finger is on the screen */
-			int wide = (f->w > f->h);
-			/* divided by two to match visual scale of touch */
-			int major = max(f->w, f->h) >> 1;
-			int minor = min(f->w, f->h) >> 1;
-
-			input_event(input, EV_ABS, ABS_MT_POSITION_X, f->x);
-			input_event(input, EV_ABS, ABS_MT_POSITION_Y, f->y);
-			input_event(input, EV_ABS, ABS_MT_ORIENTATION, wide);
-			input_event(input, EV_ABS, ABS_MT_TOUCH_MAJOR, major);
-			input_event(input, EV_ABS, ABS_MT_TOUCH_MINOR, minor);
-		}
-		f->valid = 0;
-	}
-
-	input_mt_report_pointer_emulation(input, true);
-	input_sync(input);
-}
-
-/*
- * 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_WIDTH:
-			if (md->valid)
-				md->f[md->curid].w = value;
-			break;
-		case HID_DG_HEIGHT:
-			if (md->valid)
-				md->f[md->curid].h = value;
-			break;
-		case HID_DG_CONTACTID:
-			value = clamp_val(value, 0, MAX_SLOTS - 1);
-			if (md->valid) {
-				md->curid = value;
-				md->f[value].touch = md->touch;
-				md->f[value].valid = 1;
-				md->nreal++;
-			}
-			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:
-			if (value)
-				md->nexp = value;
-			if (md->nreal >= md->nexp) {
-				mmm_filter_event(md, input);
-				md->nreal = 0;
-			}
-			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;
-
-	hdev->quirks |= HID_QUIRK_NO_INPUT_SYNC;
-
-	md = kzalloc(sizeof(struct mmm_data), GFP_KERNEL);
-	if (!md) {
-		hid_err(hdev, "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) },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_3M, USB_DEVICE_ID_3M2256) },
-	{ }
-};
-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);
-
diff -druN linux-2.6.39-libre/drivers/hid/hid-cando.c linux-3.0-rc7-libre/drivers/hid/hid-cando.c
--- linux-2.6.39-libre/drivers/hid/hid-cando.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/hid/hid-cando.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,276 +0,0 @@
-/*
- *  HID driver for Cando dual-touch panels
- *
- *  Copyright (c) 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("Cando dual-touch panel");
-MODULE_LICENSE("GPL");
-
-#include "hid-ids.h"
-
-struct cando_data {
-	__u16 x, y;
-	__u8 id;
-	__s8 oldest;		/* id of the oldest finger in previous frame */
-	bool valid;		/* valid finger data, or just placeholder? */
-	bool first;		/* is this the first finger in this frame? */
-	__s8 firstid;		/* id of the first finger in the frame */
-	__u16 firstx, firsty;	/* (x, y) of the first finger in the frame */
-};
-
-static int cando_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_TIPSWITCH:
-		case HID_DG_CONTACTMAX:
-			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;
-	}
-
-	return 0;
-}
-
-static int cando_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 cando_filter_event(struct cando_data *td, struct input_dev *input)
-{
-	td->first = !td->first; /* touchscreen emulation */
-
-	if (!td->valid) {
-		/*
-		 * touchscreen emulation: if this is the second finger and
-		 * the first was valid, the first was the oldest; if the
-		 * first was not valid and there was a valid finger in the
-		 * previous frame, this is a release.
-		 */
-		if (td->first) {
-			td->firstid = -1;
-		} else if (td->firstid >= 0) {
-			input_event(input, EV_ABS, ABS_X, td->firstx);
-			input_event(input, EV_ABS, ABS_Y, td->firsty);
-			td->oldest = td->firstid;
-		} else if (td->oldest >= 0) {
-			input_event(input, EV_KEY, BTN_TOUCH, 0);
-			td->oldest = -1;
-		}
-
-		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);
-
-	/*
-	 * touchscreen emulation: if there was no touching finger previously,
-	 * emit touch event
-	 */
-	if (td->oldest < 0) {
-		input_event(input, EV_KEY, BTN_TOUCH, 1);
-		td->oldest = td->id;
-	}
-
-	/*
-	 * touchscreen emulation: if this is the first finger, wait for the
-	 * second; the oldest is then the second if it was the oldest already
-	 * or if there was no first, the first otherwise.
-	 */
-	if (td->first) {
-		td->firstx = td->x;
-		td->firsty = td->y;
-		td->firstid = td->id;
-	} else {
-		int x, y, oldest;
-		if (td->id == td->oldest || td->firstid < 0) {
-			x = td->x;
-			y = td->y;
-			oldest = td->id;
-		} else {
-			x = td->firstx;
-			y = td->firsty;
-			oldest = td->firstid;
-		}
-		input_event(input, EV_ABS, ABS_X, x);
-		input_event(input, EV_ABS, ABS_Y, y);
-		td->oldest = oldest;
-	}
-}
-
-
-static int cando_event(struct hid_device *hid, struct hid_field *field,
-				struct hid_usage *usage, __s32 value)
-{
-	struct cando_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_DG_CONTACTID:
-			td->id = value;
-			break;
-		case HID_GD_X:
-			td->x = value;
-			break;
-		case HID_GD_Y:
-			td->y = value;
-			cando_filter_event(td, input);
-			break;
-		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 cando_probe(struct hid_device *hdev, const struct hid_device_id *id)
-{
-	int ret;
-	struct cando_data *td;
-
-	td = kmalloc(sizeof(struct cando_data), GFP_KERNEL);
-	if (!td) {
-		hid_err(hdev, "cannot allocate Cando Touch data\n");
-		return -ENOMEM;
-	}
-	hid_set_drvdata(hdev, td);
-	td->first = false;
-	td->oldest = -1;
-	td->valid = false;
-
-	ret = hid_parse(hdev);
-	if (!ret)
-		ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
-
-	if (ret)
-		kfree(td);
-
-	return ret;
-}
-
-static void cando_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 cando_devices[] = {
-	{ HID_USB_DEVICE(USB_VENDOR_ID_CANDO,
-			USB_DEVICE_ID_CANDO_MULTI_TOUCH) },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_CANDO,
-			USB_DEVICE_ID_CANDO_MULTI_TOUCH_10_1) },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_CANDO,
-			USB_DEVICE_ID_CANDO_MULTI_TOUCH_11_6) },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_CANDO,
-		USB_DEVICE_ID_CANDO_MULTI_TOUCH_15_6) },
-	{ }
-};
-MODULE_DEVICE_TABLE(hid, cando_devices);
-
-static const struct hid_usage_id cando_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 cando_driver = {
-	.name = "cando-touch",
-	.id_table = cando_devices,
-	.probe = cando_probe,
-	.remove = cando_remove,
-	.input_mapping = cando_input_mapping,
-	.input_mapped = cando_input_mapped,
-	.usage_table = cando_grabbed_usages,
-	.event = cando_event,
-};
-
-static int __init cando_init(void)
-{
-	return hid_register_driver(&cando_driver);
-}
-
-static void __exit cando_exit(void)
-{
-	hid_unregister_driver(&cando_driver);
-}
-
-module_init(cando_init);
-module_exit(cando_exit);
-
diff -druN linux-2.6.39-libre/drivers/hid/hid-core.c linux-3.0-rc7-libre/drivers/hid/hid-core.c
--- linux-2.6.39-libre/drivers/hid/hid-core.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/hid/hid-core.c	2011-07-11 19:51:52.000000000 -0400
@@ -1045,6 +1045,9 @@
 
 	rsize = ((report->size - 1) >> 3) + 1;
 
+	if (rsize > HID_MAX_BUFFER_SIZE)
+		rsize = HID_MAX_BUFFER_SIZE;
+
 	if (csize < rsize) {
 		dbg_hid("report %d is too short, (%d < %d)\n", report->id,
 				csize, rsize);
@@ -1290,6 +1293,7 @@
 	{ HID_USB_DEVICE(USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_X5_005D) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_RP_649) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_ACRUX, 0x0802) },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_ACTIONSTAR, USB_DEVICE_ID_ACTIONSTAR_1011) },
 	{ 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) },
@@ -1355,7 +1359,9 @@
 	{ 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_CHICONY, USB_DEVICE_ID_CHICONY_WIRELESS) },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_CHUNGHWAT, USB_DEVICE_ID_CHUNGHWAT_MULTITOUCH) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_CREATIVELABS, USB_DEVICE_ID_PRODIKEYS_PCMIDI) },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_CVTOUCH, USB_DEVICE_ID_CVTOUCH_SCREEN) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_1) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_2) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_3) },
@@ -1369,17 +1375,20 @@
 	{ HID_USB_DEVICE(USB_VENDOR_ID_DWAV, USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH3) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_DWAV, USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH4) },
 	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_BM084) },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_ELO, USB_DEVICE_ID_ELO_TS2515) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_EMS, USB_DEVICE_ID_EMS_TRIO_LINKER_PLUS_II) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_EZKEY, USB_DEVICE_ID_BTC_8193) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_GAMERON, USB_DEVICE_ID_GAMERON_DUAL_PSX_ADAPTOR) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_GAMERON, USB_DEVICE_ID_GAMERON_DUAL_PCS_ADAPTOR) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_GENERAL_TOUCH, USB_DEVICE_ID_GENERAL_TOUCH_WIN7_TWOFINGERS) },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_GOODTOUCH, USB_DEVICE_ID_GOODTOUCH_000f) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_GREENASIA, 0x0003) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_GREENASIA, 0x0012) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_GYRATION, USB_DEVICE_ID_GYRATION_REMOTE) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_GYRATION, USB_DEVICE_ID_GYRATION_REMOTE_2) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_GYRATION, USB_DEVICE_ID_GYRATION_REMOTE_3) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_HANVON, USB_DEVICE_ID_HANVON_MULTITOUCH) },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_ILITEK, USB_DEVICE_ID_ILITEK_MULTITOUCH) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_IRTOUCHSYSTEMS, USB_DEVICE_ID_IRTOUCH_INFRARED_USB) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_KENSINGTON, USB_DEVICE_ID_KS_SLIMBLADE) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_KEYTOUCH, USB_DEVICE_ID_KEYTOUCH_IEC) },
@@ -1408,10 +1417,13 @@
 	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MOMO_WHEEL2) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_DFP_WHEEL) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_G25_WHEEL) },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_G27_WHEEL) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WII_WHEEL) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RUMBLEPAD2) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_SPACETRAVELLER) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_SPACENAVIGATOR) },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_LUMIO, USB_DEVICE_ID_CRYSTALTOUCH) },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_LUMIO, USB_DEVICE_ID_CRYSTALTOUCH_DUAL) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_MICROCHIP, USB_DEVICE_ID_PICOLCD) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_MICROCHIP, USB_DEVICE_ID_PICOLCD_BOOTLOADER) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_SIDEWINDER_GV) },
@@ -1441,6 +1453,7 @@
 	{ HID_USB_DEVICE(USB_VENDOR_ID_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN_18) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_ORTEK, USB_DEVICE_ID_ORTEK_PKB1700) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_ORTEK, USB_DEVICE_ID_ORTEK_WKB2000) },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_PENMOUNT, USB_DEVICE_ID_PENMOUNT_PCI) },
 	{ 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) },
@@ -1454,6 +1467,7 @@
 	{ HID_USB_DEVICE(USB_VENDOR_ID_SAMSUNG, USB_DEVICE_ID_SAMSUNG_WIRELESS_KBD_MOUSE) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_SKYCABLE, USB_DEVICE_ID_SKYCABLE_WIRELESS_PRESENTER) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER) },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_NAVIGATION_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) },
@@ -1470,12 +1484,15 @@
 	{ HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb65a) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_TOPSEED, USB_DEVICE_ID_TOPSEED_CYBERLINK) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_TOPSEED2, USB_DEVICE_ID_TOPSEED2_RF_COMBO) },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_TOUCH_INTL, USB_DEVICE_ID_TOUCH_INTL_MULTI_TOUCH) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_TWINHAN, USB_DEVICE_ID_TWINHAN_IR_REMOTE) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_TURBOX, USB_DEVICE_ID_TURBOX_TOUCHSCREEN_MOSART) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_PF1209) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_WP4030U) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_WP5540U) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_WP8060U) },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_UNITEC, USB_DEVICE_ID_UNITEC_USB_TOUCH_0709) },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_UNITEC, USB_DEVICE_ID_UNITEC_USB_TOUCH_0A19) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_SMARTJOY_PLUS) },
 	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_GRAPHIRE_BLUETOOTH) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_SLIM_TABLET_5_8_INCH) },
@@ -1760,19 +1777,37 @@
 	{ HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_GPEN_560) },
 	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_KYE, 0x0058) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_CASSY) },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_CASSY2) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_POCKETCASSY) },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_POCKETCASSY2) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_MOBILECASSY) },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_MOBILECASSY2) },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_MICROCASSYVOLTAGE) },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_MICROCASSYCURRENT) },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_MICROCASSYTIME) },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_MICROCASSYTEMPERATURE) },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_MICROCASSYPH) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_JWM) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_DMMP) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_UMIP) },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_XRAY1) },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_UMIC) },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_UMIB) },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_XRAY) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_XRAY2) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_VIDEOCOM) },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_MOTOR) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_COM3LAB) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_TELEPORT) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_NETWORKANALYSER) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_POWERCONTROL) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_MACHINETEST) },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_MOSTANALYSER) },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_MOSTANALYSER2) },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_ABSESP) },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_AUTODATABUS) },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_MCT) },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_HYBRID) },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_HEATCONTROL) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_MCC, USB_DEVICE_ID_MCC_PMD1024LS) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_MCC, USB_DEVICE_ID_MCC_PMD1208LS) },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_MICROCHIP, USB_DEVICE_ID_PICKIT1) },
diff -druN linux-2.6.39-libre/drivers/hid/hid-ids.h linux-3.0-rc7-libre/drivers/hid/hid-ids.h
--- linux-2.6.39-libre/drivers/hid/hid-ids.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/hid/hid-ids.h	2011-07-11 19:51:52.000000000 -0400
@@ -37,6 +37,9 @@
 
 #define USB_VENDOR_ID_ACRUX		0x1a34
 
+#define USB_VENDOR_ID_ACTIONSTAR	0x2101
+#define USB_DEVICE_ID_ACTIONSTAR_1011	0x1011
+
 #define USB_VENDOR_ID_ADS_TECH 		0x06e1
 #define USB_DEVICE_ID_ADS_TECH_RADIO_SI470X	0xa155
 
@@ -170,6 +173,9 @@
 #define USB_DEVICE_ID_CHICONY_MULTI_TOUCH	0xb19d
 #define USB_DEVICE_ID_CHICONY_WIRELESS	0x0618
 
+#define USB_VENDOR_ID_CHUNGHWAT		0x2247
+#define USB_DEVICE_ID_CHUNGHWAT_MULTITOUCH	0x0001
+
 #define USB_VENDOR_ID_CIDC		0x1677
 
 #define USB_VENDOR_ID_CMEDIA		0x0d8c
@@ -182,6 +188,9 @@
 #define USB_VENDOR_ID_CREATIVELABS	0x041e
 #define USB_DEVICE_ID_PRODIKEYS_PCMIDI	0x2801
 
+#define USB_VENDOR_ID_CVTOUCH		0x1ff7
+#define USB_DEVICE_ID_CVTOUCH_SCREEN	0x0013
+
 #define USB_VENDOR_ID_CYGNAL		0x10c4
 #define USB_DEVICE_ID_CYGNAL_RADIO_SI470X	0x818a
 
@@ -220,6 +229,7 @@
 #define USB_VENDOR_ID_DREAM_CHEEKY	0x1d34
 
 #define USB_VENDOR_ID_ELO		0x04E7
+#define USB_DEVICE_ID_ELO_TS2515	0x0022
 #define USB_DEVICE_ID_ELO_TS2700	0x0020
 
 #define USB_VENDOR_ID_EMS		0x2006
@@ -255,6 +265,9 @@
 #define USB_DEVICE_ID_0_8_8_IF_KIT	0x0053
 #define USB_DEVICE_ID_PHIDGET_MOTORCONTROL	0x0058
 
+#define USB_VENDOR_ID_GOODTOUCH		0x1aad
+#define USB_DEVICE_ID_GOODTOUCH_000f	0x000f
+
 #define USB_VENDOR_ID_GOTOP		0x08f2
 #define USB_DEVICE_ID_SUPER_Q2		0x007f
 #define USB_DEVICE_ID_GOGOPEN		0x00ce
@@ -334,6 +347,9 @@
 #define USB_DEVICE_ID_UGCI_FLYING	0x0020
 #define USB_DEVICE_ID_UGCI_FIGHTING	0x0030
 
+#define USB_VENDOR_ID_ILITEK		0x222a
+#define USB_DEVICE_ID_ILITEK_MULTITOUCH	0x0001
+
 #define USB_VENDOR_ID_IMATION		0x0718
 #define USB_DEVICE_ID_DISC_STAKKA	0xd000
 
@@ -367,19 +383,38 @@
 
 #define USB_VENDOR_ID_LD		0x0f11
 #define USB_DEVICE_ID_LD_CASSY		0x1000
+#define USB_DEVICE_ID_LD_CASSY2		0x1001
 #define USB_DEVICE_ID_LD_POCKETCASSY	0x1010
+#define USB_DEVICE_ID_LD_POCKETCASSY2	0x1011
 #define USB_DEVICE_ID_LD_MOBILECASSY	0x1020
+#define USB_DEVICE_ID_LD_MOBILECASSY2	0x1021
+#define USB_DEVICE_ID_LD_MICROCASSYVOLTAGE	0x1031
+#define USB_DEVICE_ID_LD_MICROCASSYCURRENT	0x1032
+#define USB_DEVICE_ID_LD_MICROCASSYTIME		0x1033
+#define USB_DEVICE_ID_LD_MICROCASSYTEMPERATURE	0x1035
+#define USB_DEVICE_ID_LD_MICROCASSYPH		0x1038
 #define USB_DEVICE_ID_LD_JWM		0x1080
 #define USB_DEVICE_ID_LD_DMMP		0x1081
 #define USB_DEVICE_ID_LD_UMIP		0x1090
-#define USB_DEVICE_ID_LD_XRAY1		0x1100
+#define USB_DEVICE_ID_LD_UMIC		0x10A0
+#define USB_DEVICE_ID_LD_UMIB		0x10B0
+#define USB_DEVICE_ID_LD_XRAY		0x1100
 #define USB_DEVICE_ID_LD_XRAY2		0x1101
+#define USB_DEVICE_ID_LD_XRAYCT		0x1110
 #define USB_DEVICE_ID_LD_VIDEOCOM	0x1200
+#define USB_DEVICE_ID_LD_MOTOR		0x1210
 #define USB_DEVICE_ID_LD_COM3LAB	0x2000
 #define USB_DEVICE_ID_LD_TELEPORT	0x2010
 #define USB_DEVICE_ID_LD_NETWORKANALYSER 0x2020
 #define USB_DEVICE_ID_LD_POWERCONTROL	0x2030
 #define USB_DEVICE_ID_LD_MACHINETEST	0x2040
+#define USB_DEVICE_ID_LD_MOSTANALYSER	0x2050
+#define USB_DEVICE_ID_LD_MOSTANALYSER2	0x2051
+#define USB_DEVICE_ID_LD_ABSESP		0x2060
+#define USB_DEVICE_ID_LD_AUTODATABUS	0x2070
+#define USB_DEVICE_ID_LD_MCT		0x2080
+#define USB_DEVICE_ID_LD_HYBRID		0x2090
+#define USB_DEVICE_ID_LD_HEATCONTROL	0x20A0
 
 #define USB_VENDOR_ID_LOGITECH		0x046d
 #define USB_DEVICE_ID_LOGITECH_RECEIVER	0xc101
@@ -398,6 +433,7 @@
 #define USB_DEVICE_ID_LOGITECH_MOMO_WHEEL	0xc295
 #define USB_DEVICE_ID_LOGITECH_DFP_WHEEL	0xc298
 #define USB_DEVICE_ID_LOGITECH_G25_WHEEL	0xc299
+#define USB_DEVICE_ID_LOGITECH_G27_WHEEL	0xc29b
 #define USB_DEVICE_ID_LOGITECH_WII_WHEEL	0xc29c
 #define USB_DEVICE_ID_LOGITECH_ELITE_KBD	0xc30a
 #define USB_DEVICE_ID_S510_RECEIVER	0xc50c
@@ -411,6 +447,10 @@
 #define USB_DEVICE_ID_DINOVO_MINI	0xc71f
 #define USB_DEVICE_ID_LOGITECH_MOMO_WHEEL2	0xca03
 
+#define USB_VENDOR_ID_LUMIO		0x202e
+#define USB_DEVICE_ID_CRYSTALTOUCH	0x0006
+#define USB_DEVICE_ID_CRYSTALTOUCH_DUAL	0x0007
+
 #define USB_VENDOR_ID_MCC		0x09db
 #define USB_DEVICE_ID_MCC_PMD1024LS	0x0076
 #define USB_DEVICE_ID_MCC_PMD1208LS	0x007a
@@ -488,6 +528,9 @@
 #define USB_VENDOR_ID_PANTHERLORD	0x0810
 #define USB_DEVICE_ID_PANTHERLORD_TWIN_USB_JOYSTICK	0x0001
 
+#define USB_VENDOR_ID_PENMOUNT		0x14e1
+#define USB_DEVICE_ID_PENMOUNT_PCI	0x3500
+
 #define USB_VENDOR_ID_PETALYNX		0x18b1
 #define USB_DEVICE_ID_PETALYNX_MAXTER_REMOTE	0x0037
 
@@ -531,6 +574,7 @@
 #define USB_VENDOR_ID_SONY			0x054c
 #define USB_DEVICE_ID_SONY_VAIO_VGX_MOUSE	0x024b
 #define USB_DEVICE_ID_SONY_PS3_CONTROLLER	0x0268
+#define USB_DEVICE_ID_SONY_NAVIGATION_CONTROLLER	0x042f
 
 #define USB_VENDOR_ID_SOUNDGRAPH	0x15c2
 #define USB_DEVICE_ID_SOUNDGRAPH_IMON_FIRST	0x0034
@@ -551,6 +595,10 @@
 #define USB_VENDOR_ID_SUNPLUS		0x04fc
 #define USB_DEVICE_ID_SUNPLUS_WDESKTOP	0x05d8
 
+#define USB_VENDOR_ID_SYMBOL		0x05e0
+#define USB_DEVICE_ID_SYMBOL_SCANNER_1	0x0800
+#define USB_DEVICE_ID_SYMBOL_SCANNER_2	0x1300
+
 #define USB_VENDOR_ID_THRUSTMASTER	0x044f
 
 #define USB_VENDOR_ID_TOPSEED		0x0766
@@ -562,6 +610,9 @@
 #define USB_VENDOR_ID_TOPMAX		0x0663
 #define USB_DEVICE_ID_TOPMAX_COBRAPAD	0x0103
 
+#define USB_VENDOR_ID_TOUCH_INTL	0x1e5e
+#define USB_DEVICE_ID_TOUCH_INTL_MULTI_TOUCH	0x0313
+
 #define USB_VENDOR_ID_TOUCHPACK		0x1bfd
 #define USB_DEVICE_ID_TOUCHPACK_RTS	0x1688
 
@@ -575,10 +626,15 @@
 #define USB_VENDOR_ID_UCLOGIC		0x5543
 #define USB_DEVICE_ID_UCLOGIC_TABLET_PF1209	0x0042
 #define USB_DEVICE_ID_UCLOGIC_TABLET_KNA5	0x6001
+#define USB_DEVICE_ID_UCLOGIC_TABLET_TWA60	0x0064
 #define USB_DEVICE_ID_UCLOGIC_TABLET_WP4030U	0x0003
 #define USB_DEVICE_ID_UCLOGIC_TABLET_WP5540U	0x0004
 #define USB_DEVICE_ID_UCLOGIC_TABLET_WP8060U	0x0005
 
+#define USB_VENDOR_ID_UNITEC	0x227d
+#define USB_DEVICE_ID_UNITEC_USB_TOUCH_0709	0x0709
+#define USB_DEVICE_ID_UNITEC_USB_TOUCH_0A19	0x0a19
+
 #define USB_VENDOR_ID_VERNIER		0x08f7
 #define USB_DEVICE_ID_VERNIER_LABPRO	0x0001
 #define USB_DEVICE_ID_VERNIER_GOTEMP	0x0002
diff -druN linux-2.6.39-libre/drivers/hid/hid-input.c linux-3.0-rc7-libre/drivers/hid/hid-input.c
--- linux-2.6.39-libre/drivers/hid/hid-input.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/hid/hid-input.c	2011-07-11 19:51:52.000000000 -0400
@@ -44,11 +44,11 @@
 	 72, 73, 82, 83, 86,127,116,117,183,184,185,186,187,188,189,190,
 	191,192,193,194,134,138,130,132,128,129,131,137,133,135,136,113,
 	115,114,unk,unk,unk,121,unk, 89, 93,124, 92, 94, 95,unk,unk,unk,
-	122,123, 90, 91, 85,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,
+	122,123, 90, 91, 85,unk,unk,unk,unk,unk,unk,unk,111,unk,unk,unk,
 	unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,
 	unk,unk,unk,unk,unk,unk,179,180,unk,unk,unk,unk,unk,unk,unk,unk,
 	unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,
-	unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,
+	unk,unk,unk,unk,unk,unk,unk,unk,111,unk,unk,unk,unk,unk,unk,unk,
 	 29, 42, 56,125, 97, 54,100,126,164,166,165,163,161,115,114,113,
 	150,158,159,128,136,177,178,176,142,152,173,140,unk,unk,unk,unk
 };
@@ -357,6 +357,18 @@
 			case 0x1: map_key_clear(KEY_POWER);  break;
 			case 0x2: map_key_clear(KEY_SLEEP);  break;
 			case 0x3: map_key_clear(KEY_WAKEUP); break;
+			case 0x4: map_key_clear(KEY_CONTEXT_MENU); break;
+			case 0x5: map_key_clear(KEY_MENU); break;
+			case 0x6: map_key_clear(KEY_PROG1); break;
+			case 0x7: map_key_clear(KEY_HELP); break;
+			case 0x8: map_key_clear(KEY_EXIT); break;
+			case 0x9: map_key_clear(KEY_SELECT); break;
+			case 0xa: map_key_clear(KEY_RIGHT); break;
+			case 0xb: map_key_clear(KEY_LEFT); break;
+			case 0xc: map_key_clear(KEY_UP); break;
+			case 0xd: map_key_clear(KEY_DOWN); break;
+			case 0xe: map_key_clear(KEY_POWER2); break;
+			case 0xf: map_key_clear(KEY_RESTART); break;
 			default: goto unknown;
 			}
 			break;
@@ -466,16 +478,39 @@
 		}
 		break;
 
-	case HID_UP_CONSUMER:	/* USB HUT v1.1, pages 56-62 */
+	case HID_UP_CONSUMER:	/* USB HUT v1.12, pages 75-84 */
 		switch (usage->hid & HID_USAGE) {
 		case 0x000: goto ignore;
+		case 0x030: map_key_clear(KEY_POWER);		break;
+		case 0x031: map_key_clear(KEY_RESTART);		break;
+		case 0x032: map_key_clear(KEY_SLEEP);		break;
 		case 0x034: map_key_clear(KEY_SLEEP);		break;
+		case 0x035: map_key_clear(KEY_KBDILLUMTOGGLE);	break;
 		case 0x036: map_key_clear(BTN_MISC);		break;
 
-		case 0x040: map_key_clear(KEY_MENU);		break;
-		case 0x045: map_key_clear(KEY_RADIO);		break;
+		case 0x040: map_key_clear(KEY_MENU);		break; /* Menu */
+		case 0x041: map_key_clear(KEY_SELECT);		break; /* Menu Pick */
+		case 0x042: map_key_clear(KEY_UP);		break; /* Menu Up */
+		case 0x043: map_key_clear(KEY_DOWN);		break; /* Menu Down */
+		case 0x044: map_key_clear(KEY_LEFT);		break; /* Menu Left */
+		case 0x045: map_key_clear(KEY_RIGHT);		break; /* Menu Right */
+		case 0x046: map_key_clear(KEY_ESC);		break; /* Menu Escape */
+		case 0x047: map_key_clear(KEY_KPPLUS);		break; /* Menu Value Increase */
+		case 0x048: map_key_clear(KEY_KPMINUS);		break; /* Menu Value Decrease */
 
+		case 0x060: map_key_clear(KEY_INFO);		break; /* Data On Screen */
+		case 0x061: map_key_clear(KEY_SUBTITLE);	break; /* Closed Caption */
+		case 0x063: map_key_clear(KEY_VCR);		break; /* VCR/TV */
+		case 0x065: map_key_clear(KEY_CAMERA);		break; /* Snapshot */
+		case 0x069: map_key_clear(KEY_RED);		break;
+		case 0x06a: map_key_clear(KEY_GREEN);		break;
+		case 0x06b: map_key_clear(KEY_BLUE);		break;
+		case 0x06c: map_key_clear(KEY_YELLOW);		break;
+		case 0x06d: map_key_clear(KEY_ZOOM);		break;
+
+		case 0x082: map_key_clear(KEY_VIDEO_NEXT);	break;
 		case 0x083: map_key_clear(KEY_LAST);		break;
+		case 0x084: map_key_clear(KEY_ENTER);		break;
 		case 0x088: map_key_clear(KEY_PC);		break;
 		case 0x089: map_key_clear(KEY_TV);		break;
 		case 0x08a: map_key_clear(KEY_WWW);		break;
@@ -509,6 +544,8 @@
 		case 0x0b7: map_key_clear(KEY_STOPCD);		break;
 		case 0x0b8: map_key_clear(KEY_EJECTCD);		break;
 		case 0x0bc: map_key_clear(KEY_MEDIA_REPEAT);	break;
+		case 0x0b9: map_key_clear(KEY_SHUFFLE);		break;
+		case 0x0bf: map_key_clear(KEY_SLOW);		break;
 
 		case 0x0cd: map_key_clear(KEY_PLAYPAUSE);	break;
 		case 0x0e0: map_abs_clear(ABS_VOLUME);		break;
@@ -516,6 +553,7 @@
 		case 0x0e5: map_key_clear(KEY_BASSBOOST);	break;
 		case 0x0e9: map_key_clear(KEY_VOLUMEUP);	break;
 		case 0x0ea: map_key_clear(KEY_VOLUMEDOWN);	break;
+		case 0x0f5: map_key_clear(KEY_SLOW);		break;
 
 		case 0x182: map_key_clear(KEY_BOOKMARKS);	break;
 		case 0x183: map_key_clear(KEY_CONFIG);		break;
@@ -532,6 +570,7 @@
 		case 0x18e: map_key_clear(KEY_CALENDAR);	break;
 		case 0x191: map_key_clear(KEY_FINANCE);		break;
 		case 0x192: map_key_clear(KEY_CALC);		break;
+		case 0x193: map_key_clear(KEY_PLAYER);		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;
@@ -540,8 +579,10 @@
 		case 0x1a6: map_key_clear(KEY_HELP);		break;
 		case 0x1a7: map_key_clear(KEY_DOCUMENTS);	break;
 		case 0x1ab: map_key_clear(KEY_SPELLCHECK);	break;
-		case 0x1b6: map_key_clear(KEY_MEDIA);		break;
-		case 0x1b7: map_key_clear(KEY_SOUND);		break;
+		case 0x1ae: map_key_clear(KEY_KEYBOARD);	break;
+		case 0x1b6: map_key_clear(KEY_IMAGES);		break;
+		case 0x1b7: map_key_clear(KEY_AUDIO);		break;
+		case 0x1b8: map_key_clear(KEY_VIDEO);		break;
 		case 0x1bc: map_key_clear(KEY_MESSENGER);	break;
 		case 0x1bd: map_key_clear(KEY_INFO);		break;
 		case 0x201: map_key_clear(KEY_NEW);		break;
@@ -570,7 +611,10 @@
 		case 0x233: map_key_clear(KEY_SCROLLUP);	break;
 		case 0x234: map_key_clear(KEY_SCROLLDOWN);	break;
 		case 0x238: map_rel(REL_HWHEEL);		break;
+		case 0x23d: map_key_clear(KEY_EDIT);		break;
 		case 0x25f: map_key_clear(KEY_CANCEL);		break;
+		case 0x269: map_key_clear(KEY_INSERT);		break;
+		case 0x26a: map_key_clear(KEY_DELETE);		break;
 		case 0x279: map_key_clear(KEY_REDO);		break;
 
 		case 0x289: map_key_clear(KEY_REPLY);		break;
diff -druN linux-2.6.39-libre/drivers/hid/hid-lg.c linux-3.0-rc7-libre/drivers/hid/hid-lg.c
--- linux-2.6.39-libre/drivers/hid/hid-lg.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/hid/hid-lg.c	2011-07-11 19:51:52.000000000 -0400
@@ -377,6 +377,8 @@
 		.driver_data = LG_FF },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_G25_WHEEL),
 		.driver_data = LG_FF },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_G27_WHEEL),
+		.driver_data = LG_FF },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_DFP_WHEEL),
 		.driver_data = LG_FF },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_WII_WHEEL),
diff -druN linux-2.6.39-libre/drivers/hid/hid-lgff.c linux-3.0-rc7-libre/drivers/hid/hid-lgff.c
--- linux-2.6.39-libre/drivers/hid/hid-lgff.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/hid/hid-lgff.c	2011-07-11 19:51:52.000000000 -0400
@@ -72,6 +72,9 @@
 	{ 0x046d, 0xc287, ff_joystick_ac },
 	{ 0x046d, 0xc293, ff_joystick },
 	{ 0x046d, 0xc294, ff_wheel },
+	{ 0x046d, 0xc298, ff_wheel },
+	{ 0x046d, 0xc299, ff_wheel },
+	{ 0x046d, 0xc29b, ff_wheel },
 	{ 0x046d, 0xc295, ff_joystick },
 	{ 0x046d, 0xc298, ff_wheel },
 	{ 0x046d, 0xc299, ff_wheel },
diff -druN linux-2.6.39-libre/drivers/hid/hid-mosart.c linux-3.0-rc7-libre/drivers/hid/hid-mosart.c
--- linux-2.6.39-libre/drivers/hid/hid-mosart.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/hid/hid-mosart.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,296 +0,0 @@
-/*
- *  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;
-
-	case HID_UP_BUTTON:
-		/* ignore buttons */
-		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) {
-		hid_err(hdev, "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;
-}
-
-#ifdef CONFIG_PM
-static int mosart_reset_resume(struct hid_device *hdev)
-{
-	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);
-	return 0;
-}
-#endif
-
-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) },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_ASUS, USB_DEVICE_ID_ASUSTEK_MULTITOUCH_YFO) },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_TURBOX, USB_DEVICE_ID_TURBOX_TOUCHSCREEN_MOSART) },
-	{ }
-};
-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,
-#ifdef CONFIG_PM
-	.reset_resume = mosart_reset_resume,
-#endif
-};
-
-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 -druN linux-2.6.39-libre/drivers/hid/hid-multitouch.c linux-3.0-rc7-libre/drivers/hid/hid-multitouch.c
--- linux-2.6.39-libre/drivers/hid/hid-multitouch.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/hid/hid-multitouch.c	2011-07-11 19:51:52.000000000 -0400
@@ -11,6 +11,12 @@
  *  Copyright (c) 2010 Henrik Rydberg <rydberg@euromail.se>
  *  Copyright (c) 2010 Canonical, Ltd.
  *
+ *  This code is partly based on hid-3m-pct.c:
+ *
+ *  Copyright (c) 2009-2010 Stephane Chatty <chatty@enac.fr>
+ *  Copyright (c) 2010      Henrik Rydberg <rydberg@euromail.se>
+ *  Copyright (c) 2010      Canonical, Ltd.
+ *
  */
 
 /*
@@ -44,6 +50,7 @@
 #define MT_QUIRK_VALID_IS_INRANGE	(1 << 4)
 #define MT_QUIRK_VALID_IS_CONFIDENCE	(1 << 5)
 #define MT_QUIRK_EGALAX_XYZ_FIXUP	(1 << 6)
+#define MT_QUIRK_SLOT_IS_CONTACTID_MINUS_ONE	(1 << 7)
 
 struct mt_slot {
 	__s32 x, y, p, w, h;
@@ -57,27 +64,40 @@
 	struct mt_class *mtclass;	/* our mt device class */
 	unsigned last_field_index;	/* last field index of the report */
 	unsigned last_slot_field;	/* the last field of a slot */
+	int last_mt_collection;	/* last known mt-related collection */
 	__s8 inputmode;		/* InputMode HID feature, -1 if non-existent */
 	__u8 num_received;	/* how many contacts we received */
 	__u8 num_expected;	/* expected last contact index */
+	__u8 maxcontacts;
 	bool curvalid;		/* is the current contact valid? */
-	struct mt_slot slots[0];	/* first slot */
+	struct mt_slot *slots;
 };
 
 struct mt_class {
 	__s32 name;	/* MT_CLS */
 	__s32 quirks;
 	__s32 sn_move;	/* Signal/noise ratio for move events */
+	__s32 sn_width;	/* Signal/noise ratio for width events */
+	__s32 sn_height;	/* Signal/noise ratio for height events */
 	__s32 sn_pressure;	/* Signal/noise ratio for pressure events */
 	__u8 maxcontacts;
 };
 
 /* classes of device behavior */
-#define MT_CLS_DEFAULT				1
-#define MT_CLS_DUAL_INRANGE_CONTACTID		2
-#define MT_CLS_DUAL_INRANGE_CONTACTNUMBER	3
-#define MT_CLS_CYPRESS				4
-#define MT_CLS_EGALAX				5
+#define MT_CLS_DEFAULT				0x0001
+
+#define MT_CLS_CONFIDENCE			0x0002
+#define MT_CLS_CONFIDENCE_MINUS_ONE		0x0003
+#define MT_CLS_DUAL_INRANGE_CONTACTID		0x0004
+#define MT_CLS_DUAL_INRANGE_CONTACTNUMBER	0x0005
+#define MT_CLS_DUAL_NSMU_CONTACTID		0x0006
+
+/* vendor specific classes */
+#define MT_CLS_3M				0x0101
+#define MT_CLS_CYPRESS				0x0102
+#define MT_CLS_EGALAX				0x0103
+
+#define MT_DEFAULT_MAXCONTACT	10
 
 /*
  * these device-dependent functions determine what slot corresponds
@@ -95,12 +115,12 @@
 static int find_slot_from_contactid(struct mt_device *td)
 {
 	int i;
-	for (i = 0; i < td->mtclass->maxcontacts; ++i) {
+	for (i = 0; i < td->maxcontacts; ++i) {
 		if (td->slots[i].contactid == td->curdata.contactid &&
 			td->slots[i].touch_state)
 			return i;
 	}
-	for (i = 0; i < td->mtclass->maxcontacts; ++i) {
+	for (i = 0; i < td->maxcontacts; ++i) {
 		if (!td->slots[i].seen_in_this_frame &&
 			!td->slots[i].touch_state)
 			return i;
@@ -113,8 +133,12 @@
 
 struct mt_class mt_classes[] = {
 	{ .name = MT_CLS_DEFAULT,
-		.quirks = MT_QUIRK_NOT_SEEN_MEANS_UP,
-		.maxcontacts = 10 },
+		.quirks = MT_QUIRK_NOT_SEEN_MEANS_UP },
+	{ .name = MT_CLS_CONFIDENCE,
+		.quirks = MT_QUIRK_VALID_IS_CONFIDENCE },
+	{ .name = MT_CLS_CONFIDENCE_MINUS_ONE,
+		.quirks = MT_QUIRK_VALID_IS_CONFIDENCE |
+			MT_QUIRK_SLOT_IS_CONTACTID_MINUS_ONE },
 	{ .name = MT_CLS_DUAL_INRANGE_CONTACTID,
 		.quirks = MT_QUIRK_VALID_IS_INRANGE |
 			MT_QUIRK_SLOT_IS_CONTACTID,
@@ -123,11 +147,24 @@
 		.quirks = MT_QUIRK_VALID_IS_INRANGE |
 			MT_QUIRK_SLOT_IS_CONTACTNUMBER,
 		.maxcontacts = 2 },
+	{ .name = MT_CLS_DUAL_NSMU_CONTACTID,
+		.quirks = MT_QUIRK_NOT_SEEN_MEANS_UP |
+			MT_QUIRK_SLOT_IS_CONTACTID,
+		.maxcontacts = 2 },
+
+	/*
+	 * vendor specific classes
+	 */
+	{ .name = MT_CLS_3M,
+		.quirks = MT_QUIRK_VALID_IS_CONFIDENCE |
+			MT_QUIRK_SLOT_IS_CONTACTID,
+		.sn_move = 2048,
+		.sn_width = 128,
+		.sn_height = 128 },
 	{ .name = MT_CLS_CYPRESS,
 		.quirks = MT_QUIRK_NOT_SEEN_MEANS_UP |
 			MT_QUIRK_CYPRESS,
 		.maxcontacts = 10 },
-
 	{ .name = MT_CLS_EGALAX,
 		.quirks =  MT_QUIRK_SLOT_IS_CONTACTID |
 			MT_QUIRK_VALID_IS_INRANGE |
@@ -136,15 +173,26 @@
 		.sn_move = 4096,
 		.sn_pressure = 32,
 	},
+
 	{ }
 };
 
 static void mt_feature_mapping(struct hid_device *hdev,
 		struct hid_field *field, struct hid_usage *usage)
 {
-	if (usage->hid == HID_DG_INPUTMODE) {
-		struct mt_device *td = hid_get_drvdata(hdev);
+	struct mt_device *td = hid_get_drvdata(hdev);
+
+	switch (usage->hid) {
+	case HID_DG_INPUTMODE:
 		td->inputmode = field->report->id;
+		break;
+	case HID_DG_CONTACTMAX:
+		td->maxcontacts = field->value[0];
+		if (td->mtclass->maxcontacts)
+			/* check if the maxcontacts is given by the class */
+			td->maxcontacts = td->mtclass->maxcontacts;
+
+		break;
 	}
 }
 
@@ -178,7 +226,10 @@
 				cls->sn_move);
 			/* touchscreen emulation */
 			set_abs(hi->input, ABS_X, field, cls->sn_move);
-			td->last_slot_field = usage->hid;
+			if (td->last_mt_collection == usage->collection_index) {
+				td->last_slot_field = usage->hid;
+				td->last_field_index = field->index;
+			}
 			return 1;
 		case HID_GD_Y:
 			if (quirks & MT_QUIRK_EGALAX_XYZ_FIXUP)
@@ -189,7 +240,10 @@
 				cls->sn_move);
 			/* touchscreen emulation */
 			set_abs(hi->input, ABS_Y, field, cls->sn_move);
-			td->last_slot_field = usage->hid;
+			if (td->last_mt_collection == usage->collection_index) {
+				td->last_slot_field = usage->hid;
+				td->last_field_index = field->index;
+			}
 			return 1;
 		}
 		return 0;
@@ -197,33 +251,54 @@
 	case HID_UP_DIGITIZER:
 		switch (usage->hid) {
 		case HID_DG_INRANGE:
-			td->last_slot_field = usage->hid;
+			if (td->last_mt_collection == usage->collection_index) {
+				td->last_slot_field = usage->hid;
+				td->last_field_index = field->index;
+			}
 			return 1;
 		case HID_DG_CONFIDENCE:
-			td->last_slot_field = usage->hid;
+			if (td->last_mt_collection == usage->collection_index) {
+				td->last_slot_field = usage->hid;
+				td->last_field_index = field->index;
+			}
 			return 1;
 		case HID_DG_TIPSWITCH:
 			hid_map_usage(hi, usage, bit, max, EV_KEY, BTN_TOUCH);
 			input_set_capability(hi->input, EV_KEY, BTN_TOUCH);
-			td->last_slot_field = usage->hid;
+			if (td->last_mt_collection == usage->collection_index) {
+				td->last_slot_field = usage->hid;
+				td->last_field_index = field->index;
+			}
 			return 1;
 		case HID_DG_CONTACTID:
-			input_mt_init_slots(hi->input,
-					td->mtclass->maxcontacts);
+			if (!td->maxcontacts)
+				td->maxcontacts = MT_DEFAULT_MAXCONTACT;
+			input_mt_init_slots(hi->input, td->maxcontacts);
 			td->last_slot_field = usage->hid;
+			td->last_field_index = field->index;
+			td->last_mt_collection = usage->collection_index;
 			return 1;
 		case HID_DG_WIDTH:
 			hid_map_usage(hi, usage, bit, max,
 					EV_ABS, ABS_MT_TOUCH_MAJOR);
-			td->last_slot_field = usage->hid;
+			set_abs(hi->input, ABS_MT_TOUCH_MAJOR, field,
+				cls->sn_width);
+			if (td->last_mt_collection == usage->collection_index) {
+				td->last_slot_field = usage->hid;
+				td->last_field_index = field->index;
+			}
 			return 1;
 		case HID_DG_HEIGHT:
 			hid_map_usage(hi, usage, bit, max,
 					EV_ABS, ABS_MT_TOUCH_MINOR);
-			field->logical_maximum = 1;
-			field->logical_minimum = 0;
-			set_abs(hi->input, ABS_MT_ORIENTATION, field, 0);
-			td->last_slot_field = usage->hid;
+			set_abs(hi->input, ABS_MT_TOUCH_MINOR, field,
+				cls->sn_height);
+			input_set_abs_params(hi->input,
+					ABS_MT_ORIENTATION, 0, 1, 0, 0);
+			if (td->last_mt_collection == usage->collection_index) {
+				td->last_slot_field = usage->hid;
+				td->last_field_index = field->index;
+			}
 			return 1;
 		case HID_DG_TIPPRESSURE:
 			if (quirks & MT_QUIRK_EGALAX_XYZ_FIXUP)
@@ -235,14 +310,20 @@
 			/* touchscreen emulation */
 			set_abs(hi->input, ABS_PRESSURE, field,
 				cls->sn_pressure);
-			td->last_slot_field = usage->hid;
+			if (td->last_mt_collection == usage->collection_index) {
+				td->last_slot_field = usage->hid;
+				td->last_field_index = field->index;
+			}
 			return 1;
 		case HID_DG_CONTACTCOUNT:
-			td->last_field_index = field->report->maxfield - 1;
+			if (td->last_mt_collection == usage->collection_index)
+				td->last_field_index = field->index;
 			return 1;
 		case HID_DG_CONTACTMAX:
 			/* we don't set td->last_slot_field as contactcount and
 			 * contact max are global to the report */
+			if (td->last_mt_collection == usage->collection_index)
+				td->last_field_index = field->index;
 			return -1;
 		}
 		/* let hid-input decide for the others */
@@ -279,6 +360,9 @@
 	if (quirks & MT_QUIRK_SLOT_IS_CONTACTNUMBER)
 		return td->num_received;
 
+	if (quirks & MT_QUIRK_SLOT_IS_CONTACTID_MINUS_ONE)
+		return td->curdata.contactid - 1;
+
 	return find_slot_from_contactid(td);
 }
 
@@ -292,7 +376,7 @@
 	if (td->curvalid) {
 		int slotnum = mt_compute_slot(td);
 
-		if (slotnum >= 0 && slotnum < td->mtclass->maxcontacts)
+		if (slotnum >= 0 && slotnum < td->maxcontacts)
 			td->slots[slotnum] = td->curdata;
 	}
 	td->num_received++;
@@ -307,7 +391,7 @@
 {
 	int i;
 
-	for (i = 0; i < td->mtclass->maxcontacts; ++i) {
+	for (i = 0; i < td->maxcontacts; ++i) {
 		struct mt_slot *s = &(td->slots[i]);
 		if ((td->mtclass->quirks & MT_QUIRK_NOT_SEEN_MEANS_UP) &&
 			!s->seen_in_this_frame) {
@@ -318,11 +402,18 @@
 		input_mt_report_slot_state(input, MT_TOOL_FINGER,
 			s->touch_state);
 		if (s->touch_state) {
+			/* this finger is on the screen */
+			int wide = (s->w > s->h);
+			/* divided by two to match visual scale of touch */
+			int major = max(s->w, s->h) >> 1;
+			int minor = min(s->w, s->h) >> 1;
+
 			input_event(input, EV_ABS, ABS_MT_POSITION_X, s->x);
 			input_event(input, EV_ABS, ABS_MT_POSITION_Y, s->y);
+			input_event(input, EV_ABS, ABS_MT_ORIENTATION, wide);
 			input_event(input, EV_ABS, ABS_MT_PRESSURE, s->p);
-			input_event(input, EV_ABS, ABS_MT_TOUCH_MAJOR, s->w);
-			input_event(input, EV_ABS, ABS_MT_TOUCH_MINOR, s->h);
+			input_event(input, EV_ABS, ABS_MT_TOUCH_MAJOR, major);
+			input_event(input, EV_ABS, ABS_MT_TOUCH_MINOR, minor);
 		}
 		s->seen_in_this_frame = false;
 
@@ -341,7 +432,7 @@
 	struct mt_device *td = hid_get_drvdata(hid);
 	__s32 quirks = td->mtclass->quirks;
 
-	if (hid->claimed & HID_CLAIMED_INPUT) {
+	if (hid->claimed & HID_CLAIMED_INPUT && td->slots) {
 		switch (usage->hid) {
 		case HID_DG_INRANGE:
 			if (quirks & MT_QUIRK_VALID_IS_INRANGE)
@@ -390,8 +481,6 @@
 
 		if (usage->hid == td->last_slot_field) {
 			mt_complete_slot(td);
-			if (!td->last_field_index)
-				mt_emit_event(td, field->hidinput->input);
 		}
 
 		if (field->index == td->last_field_index
@@ -442,15 +531,14 @@
 	 */
 	hdev->quirks |= HID_QUIRK_NO_INPUT_SYNC;
 
-	td = kzalloc(sizeof(struct mt_device) +
-				mtclass->maxcontacts * sizeof(struct mt_slot),
-				GFP_KERNEL);
+	td = kzalloc(sizeof(struct mt_device), GFP_KERNEL);
 	if (!td) {
 		dev_err(&hdev->dev, "cannot allocate multitouch data\n");
 		return -ENOMEM;
 	}
 	td->mtclass = mtclass;
 	td->inputmode = -1;
+	td->last_mt_collection = -1;
 	hid_set_drvdata(hdev, td);
 
 	ret = hid_parse(hdev);
@@ -461,6 +549,15 @@
 	if (ret)
 		goto fail;
 
+	td->slots = kzalloc(td->maxcontacts * sizeof(struct mt_slot),
+				GFP_KERNEL);
+	if (!td->slots) {
+		dev_err(&hdev->dev, "cannot allocate multitouch slots\n");
+		hid_hw_stop(hdev);
+		ret = -ENOMEM;
+		goto fail;
+	}
+
 	mt_set_input_mode(hdev);
 
 	return 0;
@@ -482,27 +579,123 @@
 {
 	struct mt_device *td = hid_get_drvdata(hdev);
 	hid_hw_stop(hdev);
+	kfree(td->slots);
 	kfree(td);
 	hid_set_drvdata(hdev, NULL);
 }
 
 static const struct hid_device_id mt_devices[] = {
 
+	/* 3M panels */
+	{ .driver_data = MT_CLS_3M,
+		HID_USB_DEVICE(USB_VENDOR_ID_3M,
+			USB_DEVICE_ID_3M1968) },
+	{ .driver_data = MT_CLS_3M,
+		HID_USB_DEVICE(USB_VENDOR_ID_3M,
+			USB_DEVICE_ID_3M2256) },
+
+	/* ActionStar panels */
+	{ .driver_data = MT_CLS_DEFAULT,
+		HID_USB_DEVICE(USB_VENDOR_ID_ACTIONSTAR,
+			USB_DEVICE_ID_ACTIONSTAR_1011) },
+
+	/* Cando panels */
+	{ .driver_data = MT_CLS_DUAL_INRANGE_CONTACTNUMBER,
+		HID_USB_DEVICE(USB_VENDOR_ID_CANDO,
+			USB_DEVICE_ID_CANDO_MULTI_TOUCH) },
+	{ .driver_data = MT_CLS_DUAL_INRANGE_CONTACTNUMBER,
+		HID_USB_DEVICE(USB_VENDOR_ID_CANDO,
+			USB_DEVICE_ID_CANDO_MULTI_TOUCH_10_1) },
+	{ .driver_data = MT_CLS_DUAL_INRANGE_CONTACTNUMBER,
+		HID_USB_DEVICE(USB_VENDOR_ID_CANDO,
+			USB_DEVICE_ID_CANDO_MULTI_TOUCH_11_6) },
+	{ .driver_data = MT_CLS_DUAL_INRANGE_CONTACTNUMBER,
+		HID_USB_DEVICE(USB_VENDOR_ID_CANDO,
+			USB_DEVICE_ID_CANDO_MULTI_TOUCH_15_6) },
+
+	/* Chunghwa Telecom touch panels */
+	{  .driver_data = MT_CLS_DEFAULT,
+		HID_USB_DEVICE(USB_VENDOR_ID_CHUNGHWAT,
+			USB_DEVICE_ID_CHUNGHWAT_MULTITOUCH) },
+
+	/* CVTouch panels */
+	{ .driver_data = MT_CLS_DEFAULT,
+		HID_USB_DEVICE(USB_VENDOR_ID_CVTOUCH,
+			USB_DEVICE_ID_CVTOUCH_SCREEN) },
+
 	/* Cypress panel */
 	{ .driver_data = MT_CLS_CYPRESS,
 		HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS,
 			USB_DEVICE_ID_CYPRESS_TRUETOUCH) },
 
+	/* eGalax devices (resistive) */
+	{  .driver_data = MT_CLS_EGALAX,
+		HID_USB_DEVICE(USB_VENDOR_ID_DWAV,
+			USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH) },
+	{  .driver_data = MT_CLS_EGALAX,
+		HID_USB_DEVICE(USB_VENDOR_ID_DWAV,
+			USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH3) },
+
+	/* eGalax devices (capacitive) */
+	{  .driver_data = MT_CLS_EGALAX,
+		HID_USB_DEVICE(USB_VENDOR_ID_DWAV,
+			USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH1) },
+	{  .driver_data = MT_CLS_EGALAX,
+		HID_USB_DEVICE(USB_VENDOR_ID_DWAV,
+			USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH2) },
+	{  .driver_data = MT_CLS_EGALAX,
+		HID_USB_DEVICE(USB_VENDOR_ID_DWAV,
+			USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH4) },
+
+	/* Elo TouchSystems IntelliTouch Plus panel */
+	{ .driver_data = MT_CLS_DUAL_NSMU_CONTACTID,
+		HID_USB_DEVICE(USB_VENDOR_ID_ELO,
+			USB_DEVICE_ID_ELO_TS2515) },
+
 	/* GeneralTouch panel */
 	{ .driver_data = MT_CLS_DUAL_INRANGE_CONTACTNUMBER,
 		HID_USB_DEVICE(USB_VENDOR_ID_GENERAL_TOUCH,
 			USB_DEVICE_ID_GENERAL_TOUCH_WIN7_TWOFINGERS) },
 
+	/* GoodTouch panels */
+	{ .driver_data = MT_CLS_DEFAULT,
+		HID_USB_DEVICE(USB_VENDOR_ID_GOODTOUCH,
+			USB_DEVICE_ID_GOODTOUCH_000f) },
+
+	/* Ilitek dual touch panel */
+	{  .driver_data = MT_CLS_DEFAULT,
+		HID_USB_DEVICE(USB_VENDOR_ID_ILITEK,
+			USB_DEVICE_ID_ILITEK_MULTITOUCH) },
+
 	/* IRTOUCH panels */
 	{ .driver_data = MT_CLS_DUAL_INRANGE_CONTACTID,
 		HID_USB_DEVICE(USB_VENDOR_ID_IRTOUCHSYSTEMS,
 			USB_DEVICE_ID_IRTOUCH_INFRARED_USB) },
 
+	/* Lumio panels */
+	{ .driver_data = MT_CLS_CONFIDENCE_MINUS_ONE,
+		HID_USB_DEVICE(USB_VENDOR_ID_LUMIO,
+			USB_DEVICE_ID_CRYSTALTOUCH) },
+	{ .driver_data = MT_CLS_CONFIDENCE_MINUS_ONE,
+		HID_USB_DEVICE(USB_VENDOR_ID_LUMIO,
+			USB_DEVICE_ID_CRYSTALTOUCH_DUAL) },
+
+	/* MosArt panels */
+	{ .driver_data = MT_CLS_CONFIDENCE_MINUS_ONE,
+		HID_USB_DEVICE(USB_VENDOR_ID_ASUS,
+			USB_DEVICE_ID_ASUS_T91MT)},
+	{ .driver_data = MT_CLS_CONFIDENCE_MINUS_ONE,
+		HID_USB_DEVICE(USB_VENDOR_ID_ASUS,
+			USB_DEVICE_ID_ASUSTEK_MULTITOUCH_YFO) },
+	{ .driver_data = MT_CLS_CONFIDENCE_MINUS_ONE,
+		HID_USB_DEVICE(USB_VENDOR_ID_TURBOX,
+			USB_DEVICE_ID_TURBOX_TOUCHSCREEN_MOSART) },
+
+	/* PenMount panels */
+	{ .driver_data = MT_CLS_CONFIDENCE,
+		HID_USB_DEVICE(USB_VENDOR_ID_PENMOUNT,
+			USB_DEVICE_ID_PENMOUNT_PCI) },
+
 	/* PixCir-based panels */
 	{ .driver_data = MT_CLS_DUAL_INRANGE_CONTACTID,
 		HID_USB_DEVICE(USB_VENDOR_ID_HANVON,
@@ -511,24 +704,29 @@
 		HID_USB_DEVICE(USB_VENDOR_ID_CANDO,
 			USB_DEVICE_ID_CANDO_PIXCIR_MULTI_TOUCH) },
 
-	/* Resistive eGalax devices */
-	{  .driver_data = MT_CLS_EGALAX,
-		HID_USB_DEVICE(USB_VENDOR_ID_DWAV,
-			USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH) },
-	{  .driver_data = MT_CLS_EGALAX,
-		HID_USB_DEVICE(USB_VENDOR_ID_DWAV,
-			USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH3) },
+	/* Stantum panels */
+	{ .driver_data = MT_CLS_CONFIDENCE,
+		HID_USB_DEVICE(USB_VENDOR_ID_STANTUM,
+			USB_DEVICE_ID_MTP)},
+	{ .driver_data = MT_CLS_CONFIDENCE,
+		HID_USB_DEVICE(USB_VENDOR_ID_STANTUM_STM,
+			USB_DEVICE_ID_MTP_STM)},
+	{ .driver_data = MT_CLS_CONFIDENCE,
+		HID_USB_DEVICE(USB_VENDOR_ID_STANTUM_SITRONIX,
+			USB_DEVICE_ID_MTP_SITRONIX)},
 
-	/* Capacitive eGalax devices */
-	{  .driver_data = MT_CLS_EGALAX,
-		HID_USB_DEVICE(USB_VENDOR_ID_DWAV,
-			USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH1) },
-	{  .driver_data = MT_CLS_EGALAX,
-		HID_USB_DEVICE(USB_VENDOR_ID_DWAV,
-			USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH2) },
-	{  .driver_data = MT_CLS_EGALAX,
-		HID_USB_DEVICE(USB_VENDOR_ID_DWAV,
-			USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH4) },
+	/* Touch International panels */
+	{ .driver_data = MT_CLS_DEFAULT,
+		HID_USB_DEVICE(USB_VENDOR_ID_TOUCH_INTL,
+			USB_DEVICE_ID_TOUCH_INTL_MULTI_TOUCH) },
+
+	/* Unitec panels */
+	{ .driver_data = MT_CLS_DEFAULT,
+		HID_USB_DEVICE(USB_VENDOR_ID_UNITEC,
+			USB_DEVICE_ID_UNITEC_USB_TOUCH_0709) },
+	{ .driver_data = MT_CLS_DEFAULT,
+		HID_USB_DEVICE(USB_VENDOR_ID_UNITEC,
+			USB_DEVICE_ID_UNITEC_USB_TOUCH_0A19) },
 
 	{ }
 };
diff -druN linux-2.6.39-libre/drivers/hid/hid-picolcd.c linux-3.0-rc7-libre/drivers/hid/hid-picolcd.c
--- linux-2.6.39-libre/drivers/hid/hid-picolcd.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/hid/hid-picolcd.c	2011-07-11 19:51:52.000000000 -0400
@@ -1585,11 +1585,11 @@
 	memset(raw_data, 0, sizeof(raw_data));
 	raw_data[0] = *off & 0xff;
 	raw_data[1] = (*off >> 8) & 0xff;
-	raw_data[2] = s < 20 ? s : 20;
+	raw_data[2] = min((size_t)20, s);
 	if (*off + raw_data[2] > 0xff)
 		raw_data[2] = 0x100 - *off;
 
-	if (copy_from_user(raw_data+3, u, raw_data[2]))
+	if (copy_from_user(raw_data+3, u, min((u8)20, raw_data[2])))
 		return -EFAULT;
 	resp = picolcd_send_and_wait(data->hdev, REPORT_EE_WRITE, raw_data,
 			sizeof(raw_data));
diff -druN linux-2.6.39-libre/drivers/hid/hidraw.c linux-3.0-rc7-libre/drivers/hid/hidraw.c
--- linux-2.6.39-libre/drivers/hid/hidraw.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/hid/hidraw.c	2011-07-11 19:51:52.000000000 -0400
@@ -101,8 +101,8 @@
 	return ret;
 }
 
-/* the first byte is expected to be a report number */
-/* This function is to be called with the minors_lock mutex held */
+/* The first byte is expected to be a report number.
+ * This function is to be called with the minors_lock mutex held */
 static ssize_t hidraw_send_report(struct file *file, const char __user *buffer, size_t count, unsigned char report_type)
 {
 	unsigned int minor = iminor(file->f_path.dentry->d_inode);
@@ -166,11 +166,11 @@
 
 
 /* This function performs a Get_Report transfer over the control endpoint
-   per section 7.2.1 of the HID specification, version 1.1.  The first byte
-   of buffer is the report number to request, or 0x0 if the defice does not
-   use numbered reports. The report_type parameter can be HID_FEATURE_REPORT
-   or HID_INPUT_REPORT.  This function is to be called with the minors_lock
-   mutex held.  */
+ * per section 7.2.1 of the HID specification, version 1.1.  The first byte
+ * of buffer is the report number to request, or 0x0 if the defice does not
+ * use numbered reports. The report_type parameter can be HID_FEATURE_REPORT
+ * or HID_INPUT_REPORT.  This function is to be called with the minors_lock
+ *  mutex held. */
 static ssize_t hidraw_get_report(struct file *file, char __user *buffer, size_t count, unsigned char report_type)
 {
 	unsigned int minor = iminor(file->f_path.dentry->d_inode);
@@ -207,7 +207,7 @@
 	}
 
 	/* Read the first byte from the user. This is the report number,
-	   which is passed to dev->hid_get_raw_report(). */
+	 * which is passed to dev->hid_get_raw_report(). */
 	if (copy_from_user(&report_number, buffer, 1)) {
 		ret = -EFAULT;
 		goto out_free;
@@ -395,12 +395,7 @@
 				}
 
 				if (_IOC_NR(cmd) == _IOC_NR(HIDIOCGRAWNAME(0))) {
-					int len;
-					if (!hid->name) {
-						ret = 0;
-						break;
-					}
-					len = strlen(hid->name) + 1;
+					int len = strlen(hid->name) + 1;
 					if (len > _IOC_SIZE(cmd))
 						len = _IOC_SIZE(cmd);
 					ret = copy_to_user(user_arg, hid->name, len) ?
@@ -409,12 +404,7 @@
 				}
 
 				if (_IOC_NR(cmd) == _IOC_NR(HIDIOCGRAWPHYS(0))) {
-					int len;
-					if (!hid->phys) {
-						ret = 0;
-						break;
-					}
-					len = strlen(hid->phys) + 1;
+					int len = strlen(hid->phys) + 1;
 					if (len > _IOC_SIZE(cmd))
 						len = _IOC_SIZE(cmd);
 					ret = copy_to_user(user_arg, hid->phys, len) ?
diff -druN linux-2.6.39-libre/drivers/hid/hid-roccat-koneplus.c linux-3.0-rc7-libre/drivers/hid/hid-roccat-koneplus.c
--- linux-2.6.39-libre/drivers/hid/hid-roccat-koneplus.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/hid/hid-roccat-koneplus.c	2011-07-11 19:51:52.000000000 -0400
@@ -167,28 +167,28 @@
 }
 
 /* retval is 0-4 on success, < 0 on error */
-static int koneplus_get_startup_profile(struct usb_device *usb_dev)
+static int koneplus_get_actual_profile(struct usb_device *usb_dev)
 {
-	struct koneplus_startup_profile buf;
+	struct koneplus_actual_profile buf;
 	int retval;
 
-	retval = roccat_common_receive(usb_dev, KONEPLUS_USB_COMMAND_STARTUP_PROFILE,
-			&buf, sizeof(struct koneplus_startup_profile));
+	retval = roccat_common_receive(usb_dev, KONEPLUS_USB_COMMAND_ACTUAL_PROFILE,
+			&buf, sizeof(struct koneplus_actual_profile));
 
-	return retval ? retval : buf.startup_profile;
+	return retval ? retval : buf.actual_profile;
 }
 
-static int koneplus_set_startup_profile(struct usb_device *usb_dev,
-		int startup_profile)
+static int koneplus_set_actual_profile(struct usb_device *usb_dev,
+		int new_profile)
 {
-	struct koneplus_startup_profile buf;
+	struct koneplus_actual_profile buf;
 
-	buf.command = KONEPLUS_COMMAND_STARTUP_PROFILE;
-	buf.size = sizeof(struct koneplus_startup_profile);
-	buf.startup_profile = startup_profile;
+	buf.command = KONEPLUS_COMMAND_ACTUAL_PROFILE;
+	buf.size = sizeof(struct koneplus_actual_profile);
+	buf.actual_profile = new_profile;
 
-	return koneplus_send(usb_dev, KONEPLUS_USB_COMMAND_STARTUP_PROFILE,
-			&buf, sizeof(struct koneplus_profile_buttons));
+	return koneplus_send(usb_dev, KONEPLUS_USB_COMMAND_ACTUAL_PROFILE,
+			&buf, sizeof(struct koneplus_actual_profile));
 }
 
 static ssize_t koneplus_sysfs_read(struct file *fp, struct kobject *kobj,
@@ -398,21 +398,22 @@
 	return sizeof(struct koneplus_profile_buttons);
 }
 
-static ssize_t koneplus_sysfs_show_startup_profile(struct device *dev,
+static ssize_t koneplus_sysfs_show_actual_profile(struct device *dev,
 		struct device_attribute *attr, char *buf)
 {
 	struct koneplus_device *koneplus =
 			hid_get_drvdata(dev_get_drvdata(dev->parent->parent));
-	return snprintf(buf, PAGE_SIZE, "%d\n", koneplus->startup_profile);
+	return snprintf(buf, PAGE_SIZE, "%d\n", koneplus->actual_profile);
 }
 
-static ssize_t koneplus_sysfs_set_startup_profile(struct device *dev,
+static ssize_t koneplus_sysfs_set_actual_profile(struct device *dev,
 		struct device_attribute *attr, char const *buf, size_t size)
 {
 	struct koneplus_device *koneplus;
 	struct usb_device *usb_dev;
 	unsigned long profile;
 	int retval;
+	struct koneplus_roccat_report roccat_report;
 
 	dev = dev->parent->parent;
 	koneplus = hid_get_drvdata(dev_get_drvdata(dev));
@@ -423,20 +424,25 @@
 		return retval;
 
 	mutex_lock(&koneplus->koneplus_lock);
-	retval = koneplus_set_startup_profile(usb_dev, profile);
-	mutex_unlock(&koneplus->koneplus_lock);
-	if (retval)
+
+	retval = koneplus_set_actual_profile(usb_dev, profile);
+	if (retval) {
+		mutex_unlock(&koneplus->koneplus_lock);
 		return retval;
+	}
 
-	return size;
-}
+	koneplus->actual_profile = profile;
 
-static ssize_t koneplus_sysfs_show_actual_profile(struct device *dev,
-		struct device_attribute *attr, char *buf)
-{
-	struct koneplus_device *koneplus =
-			hid_get_drvdata(dev_get_drvdata(dev->parent->parent));
-	return snprintf(buf, PAGE_SIZE, "%d\n", koneplus->actual_profile);
+	roccat_report.type = KONEPLUS_MOUSE_REPORT_BUTTON_TYPE_PROFILE;
+	roccat_report.data1 = profile + 1;
+	roccat_report.data2 = 0;
+	roccat_report.profile = profile + 1;
+	roccat_report_event(koneplus->chrdev_minor,
+			(uint8_t const *)&roccat_report);
+
+	mutex_unlock(&koneplus->koneplus_lock);
+
+	return size;
 }
 
 static ssize_t koneplus_sysfs_show_firmware_version(struct device *dev,
@@ -448,11 +454,12 @@
 }
 
 static struct device_attribute koneplus_attributes[] = {
+	__ATTR(actual_profile, 0660,
+			koneplus_sysfs_show_actual_profile,
+			koneplus_sysfs_set_actual_profile),
 	__ATTR(startup_profile, 0660,
-			koneplus_sysfs_show_startup_profile,
-			koneplus_sysfs_set_startup_profile),
-	__ATTR(actual_profile, 0440,
-			koneplus_sysfs_show_actual_profile, NULL),
+			koneplus_sysfs_show_actual_profile,
+			koneplus_sysfs_set_actual_profile),
 	__ATTR(firmware_version, 0440,
 			koneplus_sysfs_show_firmware_version, NULL),
 	__ATTR_NULL
@@ -557,15 +564,10 @@
 		struct koneplus_device *koneplus)
 {
 	int retval, i;
-	static uint wait = 100; /* device will freeze with just 60 */
+	static uint wait = 200;
 
 	mutex_init(&koneplus->koneplus_lock);
 
-	koneplus->startup_profile = koneplus_get_startup_profile(usb_dev);
-	if (koneplus->startup_profile < 0)
-		return koneplus->startup_profile;
-
-	msleep(wait);
 	retval = koneplus_get_info(usb_dev, &koneplus->info);
 	if (retval)
 		return retval;
@@ -584,7 +586,11 @@
 			return retval;
 	}
 
-	koneplus_profile_activated(koneplus, koneplus->startup_profile);
+	msleep(wait);
+	retval = koneplus_get_actual_profile(usb_dev);
+	if (retval < 0)
+		return retval;
+	koneplus_profile_activated(koneplus, retval);
 
 	return 0;
 }
diff -druN linux-2.6.39-libre/drivers/hid/hid-roccat-koneplus.h linux-3.0-rc7-libre/drivers/hid/hid-roccat-koneplus.h
--- linux-2.6.39-libre/drivers/hid/hid-roccat-koneplus.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/hid/hid-roccat-koneplus.h	2011-07-11 19:51:52.000000000 -0400
@@ -40,10 +40,10 @@
 	KONEPLUS_CONTROL_REQUEST_STATUS_WAIT = 3,
 };
 
-struct koneplus_startup_profile {
-	uint8_t command; /* KONEPLUS_COMMAND_STARTUP_PROFILE */
+struct koneplus_actual_profile {
+	uint8_t command; /* KONEPLUS_COMMAND_ACTUAL_PROFILE */
 	uint8_t size; /* always 3 */
-	uint8_t startup_profile; /* Range 0-4! */
+	uint8_t actual_profile; /* Range 0-4! */
 } __attribute__ ((__packed__));
 
 struct koneplus_profile_settings {
@@ -132,7 +132,7 @@
 
 enum koneplus_commands {
 	KONEPLUS_COMMAND_CONTROL = 0x4,
-	KONEPLUS_COMMAND_STARTUP_PROFILE = 0x5,
+	KONEPLUS_COMMAND_ACTUAL_PROFILE = 0x5,
 	KONEPLUS_COMMAND_PROFILE_SETTINGS = 0x6,
 	KONEPLUS_COMMAND_PROFILE_BUTTONS = 0x7,
 	KONEPLUS_COMMAND_MACRO = 0x8,
@@ -145,7 +145,7 @@
 
 enum koneplus_usb_commands {
 	KONEPLUS_USB_COMMAND_CONTROL = 0x304,
-	KONEPLUS_USB_COMMAND_STARTUP_PROFILE = 0x305,
+	KONEPLUS_USB_COMMAND_ACTUAL_PROFILE = 0x305,
 	KONEPLUS_USB_COMMAND_PROFILE_SETTINGS = 0x306,
 	KONEPLUS_USB_COMMAND_PROFILE_BUTTONS = 0x307,
 	KONEPLUS_USB_COMMAND_MACRO = 0x308,
@@ -215,7 +215,6 @@
 
 	struct mutex koneplus_lock;
 
-	int startup_profile;
 	struct koneplus_info info;
 	struct koneplus_profile_settings profile_settings[5];
 	struct koneplus_profile_buttons profile_buttons[5];
diff -druN linux-2.6.39-libre/drivers/hid/hid-sony.c linux-3.0-rc7-libre/drivers/hid/hid-sony.c
--- linux-2.6.39-libre/drivers/hid/hid-sony.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/hid/hid-sony.c	2011-07-11 19:51:52.000000000 -0400
@@ -178,6 +178,8 @@
 static const struct hid_device_id sony_devices[] = {
 	{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER),
 		.driver_data = SIXAXIS_CONTROLLER_USB },
+	{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_NAVIGATION_CONTROLLER),
+		.driver_data = SIXAXIS_CONTROLLER_USB },
 	{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER),
 		.driver_data = SIXAXIS_CONTROLLER_BT },
 	{ HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_VAIO_VGX_MOUSE),
diff -druN linux-2.6.39-libre/drivers/hid/hid-stantum.c linux-3.0-rc7-libre/drivers/hid/hid-stantum.c
--- linux-2.6.39-libre/drivers/hid/hid-stantum.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/hid/hid-stantum.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,286 +0,0 @@
-/*
- *  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) {
-		hid_err(hdev, "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) },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_STANTUM_STM, USB_DEVICE_ID_MTP_STM) },
-	{ HID_USB_DEVICE(USB_VENDOR_ID_STANTUM_SITRONIX, USB_DEVICE_ID_MTP_SITRONIX) },
-	{ }
-};
-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 -druN linux-2.6.39-libre/drivers/hid/Kconfig linux-3.0-rc7-libre/drivers/hid/Kconfig
--- linux-2.6.39-libre/drivers/hid/Kconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/hid/Kconfig	2011-07-11 19:51:52.000000000 -0400
@@ -55,12 +55,6 @@
 menu "Special HID drivers"
 	depends on HID
 
-config HID_3M_PCT
-	tristate "3M PCT touchscreen"
-	depends on USB_HID
-	---help---
-	Support for 3M PCT touch screens.
-
 config HID_A4TECH
 	tristate "A4 tech mice" if EXPERT
 	depends on USB_HID
@@ -100,12 +94,6 @@
 	---help---
 	Support for Belkin Flip KVM and Wireless keyboard.
 
-config HID_CANDO
-	tristate "Cando dual touch panel"
-	depends on USB_HID
-	---help---
-	Support for Cando dual touch panel.
-
 config HID_CHERRY
 	tristate "Cherry Cymotion keyboard" if EXPERT
 	depends on USB_HID
@@ -300,12 +288,6 @@
 	---help---
 	Support for Microsoft devices that are not fully compliant with HID standard.
 
-config HID_MOSART
-	tristate "MosArt dual-touch panels"
-	depends on USB_HID
-	---help---
-	Support for MosArt dual-touch panels.
-
 config HID_MONTEREY
 	tristate "Monterey Genius KB29E keyboard" if EXPERT
 	depends on USB_HID
@@ -320,13 +302,26 @@
 	  Generic support for HID multitouch panels.
 
 	  Say Y here if you have one of the following devices:
+	  - 3M PCT touch screens
+	  - ActionStar dual touch panels
+	  - Cando dual touch panels
+	  - Chunghwa panels
+	  - CVTouch panels
 	  - Cypress TrueTouch panels
+	  - Elo TouchSystems IntelliTouch Plus panels
+	  - GeneralTouch 'Sensing Win7-TwoFinger' panels
+	  - GoodTouch panels
 	  - Hanvon dual touch panels
+	  - Ilitek dual touch panels
 	  - IrTouch Infrared USB panels
+	  - Lumio CrystalTouch panels
+	  - MosArt dual-touch panels
+	  - PenMount dual touch panels
 	  - Pixcir dual touch panels
-	  - 'Sensing Win7-TwoFinger' panel by GeneralTouch
-          - eGalax dual-touch panels, including the
-	    Joojoo and Wetab tablets
+	  - eGalax dual-touch panels, including the Joojoo and Wetab tablets
+	  - Stantum multitouch panels
+	  - Touch International Panels
+	  - Unitec Panels
 
 	  If unsure, say N.
 
@@ -500,12 +495,6 @@
 	---help---
 	Support for Sony PS3 controller.
 
-config HID_STANTUM
-	tristate "Stantum multitouch panel"
-	depends on USB_HID
-	---help---
-	Support for Stantum multitouch panel.
-
 config HID_SUNPLUS
 	tristate "Sunplus wireless desktop"
 	depends on USB_HID
diff -druN linux-2.6.39-libre/drivers/hid/Makefile linux-3.0-rc7-libre/drivers/hid/Makefile
--- linux-2.6.39-libre/drivers/hid/Makefile	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/hid/Makefile	2011-07-11 19:51:52.000000000 -0400
@@ -25,12 +25,10 @@
 	hid-logitech-y	+= hid-lg4ff.o
 endif
 
-obj-$(CONFIG_HID_3M_PCT)	+= hid-3m-pct.o
 obj-$(CONFIG_HID_A4TECH)	+= hid-a4tech.o
 obj-$(CONFIG_HID_ACRUX)		+= hid-axff.o
 obj-$(CONFIG_HID_APPLE)		+= hid-apple.o
 obj-$(CONFIG_HID_BELKIN)	+= hid-belkin.o
-obj-$(CONFIG_HID_CANDO)		+= hid-cando.o
 obj-$(CONFIG_HID_CHERRY)	+= hid-cherry.o
 obj-$(CONFIG_HID_CHICONY)	+= hid-chicony.o
 obj-$(CONFIG_HID_CYPRESS)	+= hid-cypress.o
@@ -47,7 +45,6 @@
 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_MULTITOUCH)	+= hid-multitouch.o
 obj-$(CONFIG_HID_NTRIG)		+= hid-ntrig.o
 obj-$(CONFIG_HID_ORTEK)		+= hid-ortek.o
@@ -66,7 +63,6 @@
 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 -druN linux-2.6.39-libre/drivers/hid/usbhid/hiddev.c linux-3.0-rc7-libre/drivers/hid/usbhid/hiddev.c
--- linux-2.6.39-libre/drivers/hid/usbhid/hiddev.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/hid/usbhid/hiddev.c	2011-07-11 19:51:52.000000000 -0400
@@ -242,15 +242,20 @@
 	list_del(&list->node);
 	spin_unlock_irqrestore(&list->hiddev->list_lock, flags);
 
+	mutex_lock(&list->hiddev->existancelock);
 	if (!--list->hiddev->open) {
 		if (list->hiddev->exist) {
 			usbhid_close(list->hiddev->hid);
 			usbhid_put_power(list->hiddev->hid);
 		} else {
+			mutex_unlock(&list->hiddev->existancelock);
 			kfree(list->hiddev);
+			kfree(list);
+			return 0;
 		}
 	}
 
+	mutex_unlock(&list->hiddev->existancelock);
 	kfree(list);
 
 	return 0;
@@ -300,17 +305,21 @@
 	list_add_tail(&list->node, &hiddev->list);
 	spin_unlock_irq(&list->hiddev->list_lock);
 
+	mutex_lock(&hiddev->existancelock);
 	if (!list->hiddev->open++)
 		if (list->hiddev->exist) {
 			struct hid_device *hid = hiddev->hid;
 			res = usbhid_get_power(hid);
 			if (res < 0) {
 				res = -EIO;
-				goto bail;
+				goto bail_unlock;
 			}
 			usbhid_open(hid);
 		}
+	mutex_unlock(&hiddev->existancelock);
 	return 0;
+bail_unlock:
+	mutex_unlock(&hiddev->existancelock);
 bail:
 	file->private_data = NULL;
 	kfree(list);
@@ -367,8 +376,10 @@
 				/* let O_NONBLOCK tasks run */
 				mutex_unlock(&list->thread_lock);
 				schedule();
-				if (mutex_lock_interruptible(&list->thread_lock))
+				if (mutex_lock_interruptible(&list->thread_lock)) {
+					finish_wait(&list->hiddev->wait, &wait);
 					return -EINTR;
+				}
 				set_current_state(TASK_INTERRUPTIBLE);
 			}
 			finish_wait(&list->hiddev->wait, &wait);
@@ -509,7 +520,7 @@
 				 (uref_multi->num_values > HID_MAX_MULTI_USAGES ||
 				  uref->usage_index + uref_multi->num_values > field->report_count))
 				goto inval;
-			}
+		}
 
 		switch (cmd) {
 		case HIDIOCGUSAGE:
@@ -801,14 +812,7 @@
 			break;
 
 		if (_IOC_NR(cmd) == _IOC_NR(HIDIOCGNAME(0))) {
-			int len;
-
-			if (!hid->name) {
-				r = 0;
-				break;
-			}
-
-			len = strlen(hid->name) + 1;
+			int len = strlen(hid->name) + 1;
 			if (len > _IOC_SIZE(cmd))
 				 len = _IOC_SIZE(cmd);
 			r = copy_to_user(user_arg, hid->name, len) ?
@@ -817,14 +821,7 @@
 		}
 
 		if (_IOC_NR(cmd) == _IOC_NR(HIDIOCGPHYS(0))) {
-			int len;
-
-			if (!hid->phys) {
-				r = 0;
-				break;
-			}
-
-			len = strlen(hid->phys) + 1;
+			int len = strlen(hid->phys) + 1;
 			if (len > _IOC_SIZE(cmd))
 				len = _IOC_SIZE(cmd);
 			r = copy_to_user(user_arg, hid->phys, len) ?
@@ -925,14 +922,15 @@
 
 	mutex_lock(&hiddev->existancelock);
 	hiddev->exist = 0;
-	mutex_unlock(&hiddev->existancelock);
 
 	usb_deregister_dev(usbhid->intf, &hiddev_class);
 
 	if (hiddev->open) {
+		mutex_unlock(&hiddev->existancelock);
 		usbhid_close(hiddev->hid);
 		wake_up_interruptible(&hiddev->wait);
 	} else {
+		mutex_unlock(&hiddev->existancelock);
 		kfree(hiddev);
 	}
 }
diff -druN linux-2.6.39-libre/drivers/hid/usbhid/hid-quirks.c linux-3.0-rc7-libre/drivers/hid/usbhid/hid-quirks.c
--- linux-2.6.39-libre/drivers/hid/usbhid/hid-quirks.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/hid/usbhid/hid-quirks.c	2011-07-11 19:51:52.000000000 -0400
@@ -68,10 +68,13 @@
 	{ 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_SYMBOL, USB_DEVICE_ID_SYMBOL_SCANNER_1, HID_QUIRK_NOGET },
+	{ USB_VENDOR_ID_SYMBOL, USB_DEVICE_ID_SYMBOL_SCANNER_2, 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_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_KNA5, HID_QUIRK_MULTI_INPUT },
+	{ USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_TWA60, HID_QUIRK_MULTI_INPUT },
 	{ USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_WP5540U, HID_QUIRK_MULTI_INPUT },
 	{ USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_WP8060U, HID_QUIRK_MULTI_INPUT },
 	{ USB_VENDOR_ID_WALTOP, USB_DEVICE_ID_WALTOP_MEDIA_TABLET_10_6_INCH, HID_QUIRK_MULTI_INPUT },
diff -druN linux-2.6.39-libre/drivers/hwmon/abituguru3.c linux-3.0-rc7-libre/drivers/hwmon/abituguru3.c
--- linux-2.6.39-libre/drivers/hwmon/abituguru3.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/hwmon/abituguru3.c	2011-07-11 19:51:52.000000000 -0400
@@ -1119,8 +1119,6 @@
 	.resume = abituguru3_resume
 };
 
-#ifdef CONFIG_DMI
-
 static int __init abituguru3_dmi_detect(void)
 {
 	const char *board_vendor, *board_name;
@@ -1159,15 +1157,6 @@
 	return 1;
 }
 
-#else /* !CONFIG_DMI */
-
-static inline int abituguru3_dmi_detect(void)
-{
-	return 1;
-}
-
-#endif /* CONFIG_DMI */
-
 /* FIXME: Manual detection should die eventually; we need to collect stable
  *        DMI model names first before we can rely entirely on CONFIG_DMI.
  */
@@ -1216,10 +1205,8 @@
 		if (err)
 			return err;
 
-#ifdef CONFIG_DMI
 		pr_warn("this motherboard was not detected using DMI. "
 			"Please send the output of \"dmidecode\" to the abituguru3 maintainer (see MAINTAINERS)\n");
-#endif
 	}
 
 	err = platform_driver_register(&abituguru3_driver);
diff -druN linux-2.6.39-libre/drivers/hwmon/abituguru.c linux-3.0-rc7-libre/drivers/hwmon/abituguru.c
--- linux-2.6.39-libre/drivers/hwmon/abituguru.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/hwmon/abituguru.c	2011-07-11 19:51:52.000000000 -0400
@@ -1448,15 +1448,12 @@
 {
 	int address, err;
 	struct resource res = { .flags = IORESOURCE_IO };
-
-#ifdef CONFIG_DMI
 	const char *board_vendor = dmi_get_system_info(DMI_BOARD_VENDOR);
 
 	/* safety check, refuse to load on non Abit motherboards */
 	if (!force && (!board_vendor ||
 			strcmp(board_vendor, "http://www.abit.com.tw/")))
 		return -ENODEV;
-#endif
 
 	address = abituguru_detect();
 	if (address < 0)
diff -druN linux-2.6.39-libre/drivers/hwmon/acpi_power_meter.c linux-3.0-rc7-libre/drivers/hwmon/acpi_power_meter.c
--- linux-2.6.39-libre/drivers/hwmon/acpi_power_meter.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/hwmon/acpi_power_meter.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,1023 @@
+/*
+ * A hwmon driver for ACPI 4.0 power meters
+ * Copyright (C) 2009 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/hwmon.h>
+#include <linux/hwmon-sysfs.h>
+#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>
+#include <acpi/acpi_drivers.h>
+#include <acpi/acpi_bus.h>
+
+#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		"pwr_meter_resource"
+
+#define NUM_SENSORS			17
+
+#define POWER_METER_CAN_MEASURE	(1 << 0)
+#define POWER_METER_CAN_TRIP	(1 << 1)
+#define POWER_METER_CAN_CAP	(1 << 2)
+#define POWER_METER_CAN_NOTIFY	(1 << 3)
+#define POWER_METER_IS_BATTERY	(1 << 8)
+#define UNKNOWN_HYSTERESIS	0xFFFFFFFF
+
+#define METER_NOTIFY_CONFIG	0x80
+#define METER_NOTIFY_TRIP	0x81
+#define METER_NOTIFY_CAP	0x82
+#define METER_NOTIFY_CAPPING	0x83
+#define METER_NOTIFY_INTERVAL	0x84
+
+#define POWER_AVERAGE_NAME	"power1_average"
+#define POWER_CAP_NAME		"power1_cap"
+#define POWER_AVG_INTERVAL_NAME	"power1_average_interval"
+#define POWER_ALARM_NAME	"power1_alarm"
+
+static int cap_in_hardware;
+static int force_cap_on;
+
+static int can_cap_in_hardware(void)
+{
+	return force_cap_on || cap_in_hardware;
+}
+
+static const struct acpi_device_id power_meter_ids[] = {
+	{"ACPI000D", 0},
+	{"", 0},
+};
+MODULE_DEVICE_TABLE(acpi, power_meter_ids);
+
+struct acpi_power_meter_capabilities {
+	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 {
+	struct acpi_device	*acpi_dev;
+	acpi_bus_id		name;
+	struct mutex		lock;
+	struct device		*hwmon_dev;
+	struct acpi_power_meter_capabilities	caps;
+	acpi_string		model_number;
+	acpi_string		serial_number;
+	acpi_string		oem_info;
+	u64		power;
+	u64		cap;
+	u64		avg_interval;
+	int			sensors_valid;
+	unsigned long		sensors_last_updated;
+	struct sensor_device_attribute	sensors[NUM_SENSORS];
+	int			num_sensors;
+	int			trip[2];
+	int			num_domain_devices;
+	struct acpi_device	**domain_devices;
+	struct kobject		*holders_dir;
+};
+
+struct ro_sensor_template {
+	char *label;
+	ssize_t (*show)(struct device *dev,
+			struct device_attribute *devattr,
+			char *buf);
+	int index;
+};
+
+struct rw_sensor_template {
+	char *label;
+	ssize_t (*show)(struct device *dev,
+			struct device_attribute *devattr,
+			char *buf);
+	ssize_t (*set)(struct device *dev,
+		       struct device_attribute *devattr,
+		       const char *buf, size_t count);
+	int index;
+};
+
+/* Averaging interval */
+static int update_avg_interval(struct acpi_power_meter_resource *resource)
+{
+	unsigned long long data;
+	acpi_status status;
+
+	status = acpi_evaluate_integer(resource->acpi_dev->handle, "_GAI",
+				       NULL, &data);
+	if (ACPI_FAILURE(status)) {
+		ACPI_EXCEPTION((AE_INFO, status, "Evaluating _GAI"));
+		return -ENODEV;
+	}
+
+	resource->avg_interval = data;
+	return 0;
+}
+
+static ssize_t show_avg_interval(struct device *dev,
+				 struct device_attribute *devattr,
+				 char *buf)
+{
+	struct acpi_device *acpi_dev = to_acpi_device(dev);
+	struct acpi_power_meter_resource *resource = acpi_dev->driver_data;
+
+	mutex_lock(&resource->lock);
+	update_avg_interval(resource);
+	mutex_unlock(&resource->lock);
+
+	return sprintf(buf, "%llu\n", resource->avg_interval);
+}
+
+static ssize_t set_avg_interval(struct device *dev,
+				struct device_attribute *devattr,
+				const char *buf, size_t count)
+{
+	struct acpi_device *acpi_dev = to_acpi_device(dev);
+	struct acpi_power_meter_resource *resource = acpi_dev->driver_data;
+	union acpi_object arg0 = { ACPI_TYPE_INTEGER };
+	struct acpi_object_list args = { 1, &arg0 };
+	int res;
+	unsigned long temp;
+	unsigned long long data;
+	acpi_status status;
+
+	res = strict_strtoul(buf, 10, &temp);
+	if (res)
+		return res;
+
+	if (temp > resource->caps.max_avg_interval ||
+	    temp < resource->caps.min_avg_interval)
+		return -EINVAL;
+	arg0.integer.value = temp;
+
+	mutex_lock(&resource->lock);
+	status = acpi_evaluate_integer(resource->acpi_dev->handle, "_PAI",
+				       &args, &data);
+	if (!ACPI_FAILURE(status))
+		resource->avg_interval = temp;
+	mutex_unlock(&resource->lock);
+
+	if (ACPI_FAILURE(status)) {
+		ACPI_EXCEPTION((AE_INFO, status, "Evaluating _PAI"));
+		return -EINVAL;
+	}
+
+	/* _PAI returns 0 on success, nonzero otherwise */
+	if (data)
+		return -EINVAL;
+
+	return count;
+}
+
+/* Cap functions */
+static int update_cap(struct acpi_power_meter_resource *resource)
+{
+	unsigned long long data;
+	acpi_status status;
+
+	status = acpi_evaluate_integer(resource->acpi_dev->handle, "_GHL",
+				       NULL, &data);
+	if (ACPI_FAILURE(status)) {
+		ACPI_EXCEPTION((AE_INFO, status, "Evaluating _GHL"));
+		return -ENODEV;
+	}
+
+	resource->cap = data;
+	return 0;
+}
+
+static ssize_t show_cap(struct device *dev,
+			struct device_attribute *devattr,
+			char *buf)
+{
+	struct acpi_device *acpi_dev = to_acpi_device(dev);
+	struct acpi_power_meter_resource *resource = acpi_dev->driver_data;
+
+	mutex_lock(&resource->lock);
+	update_cap(resource);
+	mutex_unlock(&resource->lock);
+
+	return sprintf(buf, "%llu\n", resource->cap * 1000);
+}
+
+static ssize_t set_cap(struct device *dev, struct device_attribute *devattr,
+		       const char *buf, size_t count)
+{
+	struct acpi_device *acpi_dev = to_acpi_device(dev);
+	struct acpi_power_meter_resource *resource = acpi_dev->driver_data;
+	union acpi_object arg0 = { ACPI_TYPE_INTEGER };
+	struct acpi_object_list args = { 1, &arg0 };
+	int res;
+	unsigned long temp;
+	unsigned long long data;
+	acpi_status status;
+
+	res = strict_strtoul(buf, 10, &temp);
+	if (res)
+		return res;
+
+	temp /= 1000;
+	if (temp > resource->caps.max_cap || temp < resource->caps.min_cap)
+		return -EINVAL;
+	arg0.integer.value = temp;
+
+	mutex_lock(&resource->lock);
+	status = acpi_evaluate_integer(resource->acpi_dev->handle, "_SHL",
+				       &args, &data);
+	if (!ACPI_FAILURE(status))
+		resource->cap = temp;
+	mutex_unlock(&resource->lock);
+
+	if (ACPI_FAILURE(status)) {
+		ACPI_EXCEPTION((AE_INFO, status, "Evaluating _SHL"));
+		return -EINVAL;
+	}
+
+	/* _SHL returns 0 on success, nonzero otherwise */
+	if (data)
+		return -EINVAL;
+
+	return count;
+}
+
+/* Power meter trip points */
+static int set_acpi_trip(struct acpi_power_meter_resource *resource)
+{
+	union acpi_object arg_objs[] = {
+		{ACPI_TYPE_INTEGER},
+		{ACPI_TYPE_INTEGER}
+	};
+	struct acpi_object_list args = { 2, arg_objs };
+	unsigned long long data;
+	acpi_status status;
+
+	/* Both trip levels must be set */
+	if (resource->trip[0] < 0 || resource->trip[1] < 0)
+		return 0;
+
+	/* This driver stores min, max; ACPI wants max, min. */
+	arg_objs[0].integer.value = resource->trip[1];
+	arg_objs[1].integer.value = resource->trip[0];
+
+	status = acpi_evaluate_integer(resource->acpi_dev->handle, "_PTP",
+				       &args, &data);
+	if (ACPI_FAILURE(status)) {
+		ACPI_EXCEPTION((AE_INFO, status, "Evaluating _PTP"));
+		return -EINVAL;
+	}
+
+	/* _PTP returns 0 on success, nonzero otherwise */
+	if (data)
+		return -EINVAL;
+
+	return 0;
+}
+
+static ssize_t set_trip(struct device *dev, struct device_attribute *devattr,
+			const char *buf, size_t count)
+{
+	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;
+	int res;
+	unsigned long temp;
+
+	res = strict_strtoul(buf, 10, &temp);
+	if (res)
+		return res;
+
+	temp /= 1000;
+	if (temp < 0)
+		return -EINVAL;
+
+	mutex_lock(&resource->lock);
+	resource->trip[attr->index - 7] = temp;
+	res = set_acpi_trip(resource);
+	mutex_unlock(&resource->lock);
+
+	if (res)
+		return res;
+
+	return count;
+}
+
+/* Power meter */
+static int update_meter(struct acpi_power_meter_resource *resource)
+{
+	unsigned long long data;
+	acpi_status status;
+	unsigned long local_jiffies = jiffies;
+
+	if (time_before(local_jiffies, resource->sensors_last_updated +
+			msecs_to_jiffies(resource->caps.sampling_time)) &&
+			resource->sensors_valid)
+		return 0;
+
+	status = acpi_evaluate_integer(resource->acpi_dev->handle, "_PMM",
+				       NULL, &data);
+	if (ACPI_FAILURE(status)) {
+		ACPI_EXCEPTION((AE_INFO, status, "Evaluating _PMM"));
+		return -ENODEV;
+	}
+
+	resource->power = data;
+	resource->sensors_valid = 1;
+	resource->sensors_last_updated = jiffies;
+	return 0;
+}
+
+static ssize_t show_power(struct device *dev,
+			  struct device_attribute *devattr,
+			  char *buf)
+{
+	struct acpi_device *acpi_dev = to_acpi_device(dev);
+	struct acpi_power_meter_resource *resource = acpi_dev->driver_data;
+
+	mutex_lock(&resource->lock);
+	update_meter(resource);
+	mutex_unlock(&resource->lock);
+
+	return sprintf(buf, "%llu\n", resource->power * 1000);
+}
+
+/* Miscellaneous */
+static ssize_t show_str(struct device *dev,
+			struct device_attribute *devattr,
+			char *buf)
+{
+	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_string val;
+
+	switch (attr->index) {
+	case 0:
+		val = resource->model_number;
+		break;
+	case 1:
+		val = resource->serial_number;
+		break;
+	case 2:
+		val = resource->oem_info;
+		break;
+	default:
+		BUG();
+	}
+
+	return sprintf(buf, "%s\n", val);
+}
+
+static ssize_t show_val(struct device *dev,
+			struct device_attribute *devattr,
+			char *buf)
+{
+	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;
+	u64 val = 0;
+
+	switch (attr->index) {
+	case 0:
+		val = resource->caps.min_avg_interval;
+		break;
+	case 1:
+		val = resource->caps.max_avg_interval;
+		break;
+	case 2:
+		val = resource->caps.min_cap * 1000;
+		break;
+	case 3:
+		val = resource->caps.max_cap * 1000;
+		break;
+	case 4:
+		if (resource->caps.hysteresis == UNKNOWN_HYSTERESIS)
+			return sprintf(buf, "unknown\n");
+
+		val = resource->caps.hysteresis * 1000;
+		break;
+	case 5:
+		if (resource->caps.flags & POWER_METER_IS_BATTERY)
+			val = 1;
+		else
+			val = 0;
+		break;
+	case 6:
+		if (resource->power > resource->cap)
+			val = 1;
+		else
+			val = 0;
+		break;
+	case 7:
+	case 8:
+		if (resource->trip[attr->index - 7] < 0)
+			return sprintf(buf, "unknown\n");
+
+		val = resource->trip[attr->index - 7] * 1000;
+		break;
+	default:
+		BUG();
+	}
+
+	return sprintf(buf, "%llu\n", val);
+}
+
+static ssize_t show_accuracy(struct device *dev,
+			     struct device_attribute *devattr,
+			     char *buf)
+{
+	struct acpi_device *acpi_dev = to_acpi_device(dev);
+	struct acpi_power_meter_resource *resource = acpi_dev->driver_data;
+	unsigned int acc = resource->caps.accuracy;
+
+	return sprintf(buf, "%u.%u%%\n", acc / 1000, acc % 1000);
+}
+
+static ssize_t show_name(struct device *dev,
+			 struct device_attribute *devattr,
+			 char *buf)
+{
+	return sprintf(buf, "%s\n", ACPI_POWER_METER_NAME);
+}
+
+/* Sensor descriptions.  If you add a sensor, update NUM_SENSORS above! */
+static struct ro_sensor_template meter_ro_attrs[] = {
+{POWER_AVERAGE_NAME, show_power, 0},
+{"power1_accuracy", show_accuracy, 0},
+{"power1_average_interval_min", show_val, 0},
+{"power1_average_interval_max", show_val, 1},
+{"power1_is_battery", show_val, 5},
+{NULL, NULL, 0},
+};
+
+static struct rw_sensor_template meter_rw_attrs[] = {
+{POWER_AVG_INTERVAL_NAME, show_avg_interval, set_avg_interval, 0},
+{NULL, NULL, NULL, 0},
+};
+
+static struct ro_sensor_template misc_cap_attrs[] = {
+{"power1_cap_min", show_val, 2},
+{"power1_cap_max", show_val, 3},
+{"power1_cap_hyst", show_val, 4},
+{POWER_ALARM_NAME, show_val, 6},
+{NULL, NULL, 0},
+};
+
+static struct ro_sensor_template ro_cap_attrs[] = {
+{POWER_CAP_NAME, show_cap, 0},
+{NULL, NULL, 0},
+};
+
+static struct rw_sensor_template rw_cap_attrs[] = {
+{POWER_CAP_NAME, show_cap, set_cap, 0},
+{NULL, NULL, NULL, 0},
+};
+
+static struct rw_sensor_template trip_attrs[] = {
+{"power1_average_min", show_val, set_trip, 7},
+{"power1_average_max", show_val, set_trip, 8},
+{NULL, NULL, NULL, 0},
+};
+
+static struct ro_sensor_template misc_attrs[] = {
+{"name", show_name, 0},
+{"power1_model_number", show_str, 0},
+{"power1_oem_info", show_str, 2},
+{"power1_serial_number", show_str, 1},
+{NULL, NULL, 0},
+};
+
+/* Read power domain data */
+static void remove_domain_devices(struct acpi_power_meter_resource *resource)
+{
+	int i;
+
+	if (!resource->num_domain_devices)
+		return;
+
+	for (i = 0; i < resource->num_domain_devices; i++) {
+		struct acpi_device *obj = resource->domain_devices[i];
+		if (!obj)
+			continue;
+
+		sysfs_remove_link(resource->holders_dir,
+				  kobject_name(&obj->dev.kobj));
+		put_device(&obj->dev);
+	}
+
+	kfree(resource->domain_devices);
+	kobject_put(resource->holders_dir);
+	resource->num_domain_devices = 0;
+}
+
+static int read_domain_devices(struct acpi_power_meter_resource *resource)
+{
+	int res = 0;
+	int i;
+	struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
+	union acpi_object *pss;
+	acpi_status status;
+
+	status = acpi_evaluate_object(resource->acpi_dev->handle, "_PMD", NULL,
+				      &buffer);
+	if (ACPI_FAILURE(status)) {
+		ACPI_EXCEPTION((AE_INFO, status, "Evaluating _PMD"));
+		return -ENODEV;
+	}
+
+	pss = buffer.pointer;
+	if (!pss ||
+	    pss->type != ACPI_TYPE_PACKAGE) {
+		dev_err(&resource->acpi_dev->dev, ACPI_POWER_METER_NAME
+			"Invalid _PMD data\n");
+		res = -EFAULT;
+		goto end;
+	}
+
+	if (!pss->package.count)
+		goto end;
+
+	resource->domain_devices = kzalloc(sizeof(struct acpi_device *) *
+					   pss->package.count, GFP_KERNEL);
+	if (!resource->domain_devices) {
+		res = -ENOMEM;
+		goto end;
+	}
+
+	resource->holders_dir = kobject_create_and_add("measures",
+					&resource->acpi_dev->dev.kobj);
+	if (!resource->holders_dir) {
+		res = -ENOMEM;
+		goto exit_free;
+	}
+
+	resource->num_domain_devices = pss->package.count;
+
+	for (i = 0; i < pss->package.count; i++) {
+		struct acpi_device *obj;
+		union acpi_object *element = &(pss->package.elements[i]);
+
+		/* Refuse non-references */
+		if (element->type != ACPI_TYPE_LOCAL_REFERENCE)
+			continue;
+
+		/* Create a symlink to domain objects */
+		resource->domain_devices[i] = NULL;
+		status = acpi_bus_get_device(element->reference.handle,
+					     &resource->domain_devices[i]);
+		if (ACPI_FAILURE(status))
+			continue;
+
+		obj = resource->domain_devices[i];
+		get_device(&obj->dev);
+
+		res = sysfs_create_link(resource->holders_dir, &obj->dev.kobj,
+				      kobject_name(&obj->dev.kobj));
+		if (res) {
+			put_device(&obj->dev);
+			resource->domain_devices[i] = NULL;
+		}
+	}
+
+	res = 0;
+	goto end;
+
+exit_free:
+	kfree(resource->domain_devices);
+end:
+	kfree(buffer.pointer);
+	return res;
+}
+
+/* Registration and deregistration */
+static int register_ro_attrs(struct acpi_power_meter_resource *resource,
+			     struct ro_sensor_template *ro)
+{
+	struct device *dev = &resource->acpi_dev->dev;
+	struct sensor_device_attribute *sensors =
+		&resource->sensors[resource->num_sensors];
+	int res = 0;
+
+	while (ro->label) {
+		sensors->dev_attr.attr.name = ro->label;
+		sensors->dev_attr.attr.mode = S_IRUGO;
+		sensors->dev_attr.show = ro->show;
+		sensors->index = ro->index;
+
+		res = device_create_file(dev, &sensors->dev_attr);
+		if (res) {
+			sensors->dev_attr.attr.name = NULL;
+			goto error;
+		}
+		sensors++;
+		resource->num_sensors++;
+		ro++;
+	}
+
+error:
+	return res;
+}
+
+static int register_rw_attrs(struct acpi_power_meter_resource *resource,
+			     struct rw_sensor_template *rw)
+{
+	struct device *dev = &resource->acpi_dev->dev;
+	struct sensor_device_attribute *sensors =
+		&resource->sensors[resource->num_sensors];
+	int res = 0;
+
+	while (rw->label) {
+		sensors->dev_attr.attr.name = rw->label;
+		sensors->dev_attr.attr.mode = S_IRUGO | S_IWUSR;
+		sensors->dev_attr.show = rw->show;
+		sensors->dev_attr.store = rw->set;
+		sensors->index = rw->index;
+
+		res = device_create_file(dev, &sensors->dev_attr);
+		if (res) {
+			sensors->dev_attr.attr.name = NULL;
+			goto error;
+		}
+		sensors++;
+		resource->num_sensors++;
+		rw++;
+	}
+
+error:
+	return res;
+}
+
+static void remove_attrs(struct acpi_power_meter_resource *resource)
+{
+	int i;
+
+	for (i = 0; i < resource->num_sensors; i++) {
+		if (!resource->sensors[i].dev_attr.attr.name)
+			continue;
+		device_remove_file(&resource->acpi_dev->dev,
+				   &resource->sensors[i].dev_attr);
+	}
+
+	remove_domain_devices(resource);
+
+	resource->num_sensors = 0;
+}
+
+static int setup_attrs(struct acpi_power_meter_resource *resource)
+{
+	int res = 0;
+
+	res = read_domain_devices(resource);
+	if (res)
+		return res;
+
+	if (resource->caps.flags & POWER_METER_CAN_MEASURE) {
+		res = register_ro_attrs(resource, meter_ro_attrs);
+		if (res)
+			goto error;
+		res = register_rw_attrs(resource, meter_rw_attrs);
+		if (res)
+			goto error;
+	}
+
+	if (resource->caps.flags & POWER_METER_CAN_CAP) {
+		if (!can_cap_in_hardware()) {
+			dev_err(&resource->acpi_dev->dev,
+				"Ignoring unsafe software power cap!\n");
+			goto skip_unsafe_cap;
+		}
+
+		if (resource->caps.configurable_cap) {
+			res = register_rw_attrs(resource, rw_cap_attrs);
+			if (res)
+				goto error;
+		} else {
+			res = register_ro_attrs(resource, ro_cap_attrs);
+			if (res)
+				goto error;
+		}
+		res = register_ro_attrs(resource, misc_cap_attrs);
+		if (res)
+			goto error;
+	}
+skip_unsafe_cap:
+
+	if (resource->caps.flags & POWER_METER_CAN_TRIP) {
+		res = register_rw_attrs(resource, trip_attrs);
+		if (res)
+			goto error;
+	}
+
+	res = register_ro_attrs(resource, misc_attrs);
+	if (res)
+		goto error;
+
+	return res;
+error:
+	remove_attrs(resource);
+	return res;
+}
+
+static void free_capabilities(struct acpi_power_meter_resource *resource)
+{
+	acpi_string *str;
+	int i;
+
+	str = &resource->model_number;
+	for (i = 0; i < 3; i++, str++)
+		kfree(*str);
+}
+
+static int read_capabilities(struct acpi_power_meter_resource *resource)
+{
+	int res = 0;
+	int i;
+	struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
+	struct acpi_buffer state = { 0, NULL };
+	struct acpi_buffer format = { sizeof("NNNNNNNNNNN"), "NNNNNNNNNNN" };
+	union acpi_object *pss;
+	acpi_string *str;
+	acpi_status status;
+
+	status = acpi_evaluate_object(resource->acpi_dev->handle, "_PMC", NULL,
+				      &buffer);
+	if (ACPI_FAILURE(status)) {
+		ACPI_EXCEPTION((AE_INFO, status, "Evaluating _PMC"));
+		return -ENODEV;
+	}
+
+	pss = buffer.pointer;
+	if (!pss ||
+	    pss->type != ACPI_TYPE_PACKAGE ||
+	    pss->package.count != 14) {
+		dev_err(&resource->acpi_dev->dev, ACPI_POWER_METER_NAME
+			"Invalid _PMC data\n");
+		res = -EFAULT;
+		goto end;
+	}
+
+	/* Grab all the integer data at once */
+	state.length = sizeof(struct acpi_power_meter_capabilities);
+	state.pointer = &resource->caps;
+
+	status = acpi_extract_package(pss, &format, &state);
+	if (ACPI_FAILURE(status)) {
+		ACPI_EXCEPTION((AE_INFO, status, "Invalid data"));
+		res = -EFAULT;
+		goto end;
+	}
+
+	if (resource->caps.units) {
+		dev_err(&resource->acpi_dev->dev, ACPI_POWER_METER_NAME
+			"Unknown units %llu.\n",
+			resource->caps.units);
+		res = -EINVAL;
+		goto end;
+	}
+
+	/* Grab the string data */
+	str = &resource->model_number;
+
+	for (i = 11; i < 14; i++) {
+		union acpi_object *element = &(pss->package.elements[i]);
+
+		if (element->type != ACPI_TYPE_STRING) {
+			res = -EINVAL;
+			goto error;
+		}
+
+		*str = kzalloc(sizeof(u8) * (element->string.length + 1),
+			       GFP_KERNEL);
+		if (!*str) {
+			res = -ENOMEM;
+			goto error;
+		}
+
+		strncpy(*str, element->string.pointer, element->string.length);
+		str++;
+	}
+
+	dev_info(&resource->acpi_dev->dev, "Found ACPI power meter.\n");
+	goto end;
+error:
+	str = &resource->model_number;
+	for (i = 0; i < 3; i++, str++)
+		kfree(*str);
+end:
+	kfree(buffer.pointer);
+	return res;
+}
+
+/* Handle ACPI event notifications */
+static void acpi_power_meter_notify(struct acpi_device *device, u32 event)
+{
+	struct acpi_power_meter_resource *resource;
+	int res;
+
+	if (!device || !acpi_driver_data(device))
+		return;
+
+	resource = acpi_driver_data(device);
+
+	mutex_lock(&resource->lock);
+	switch (event) {
+	case METER_NOTIFY_CONFIG:
+		free_capabilities(resource);
+		res = read_capabilities(resource);
+		if (res)
+			break;
+
+		remove_attrs(resource);
+		setup_attrs(resource);
+		break;
+	case METER_NOTIFY_TRIP:
+		sysfs_notify(&device->dev.kobj, NULL, POWER_AVERAGE_NAME);
+		update_meter(resource);
+		break;
+	case METER_NOTIFY_CAP:
+		sysfs_notify(&device->dev.kobj, NULL, POWER_CAP_NAME);
+		update_cap(resource);
+		break;
+	case METER_NOTIFY_INTERVAL:
+		sysfs_notify(&device->dev.kobj, NULL, POWER_AVG_INTERVAL_NAME);
+		update_avg_interval(resource);
+		break;
+	case METER_NOTIFY_CAPPING:
+		sysfs_notify(&device->dev.kobj, NULL, POWER_ALARM_NAME);
+		dev_info(&device->dev, "Capping in progress.\n");
+		break;
+	default:
+		BUG();
+	}
+	mutex_unlock(&resource->lock);
+
+	acpi_bus_generate_netlink_event(ACPI_POWER_METER_CLASS,
+					dev_name(&device->dev), event, 0);
+}
+
+static int acpi_power_meter_add(struct acpi_device *device)
+{
+	int res;
+	struct acpi_power_meter_resource *resource;
+
+	if (!device)
+		return -EINVAL;
+
+	resource = kzalloc(sizeof(struct acpi_power_meter_resource),
+			   GFP_KERNEL);
+	if (!resource)
+		return -ENOMEM;
+
+	resource->sensors_valid = 0;
+	resource->acpi_dev = device;
+	mutex_init(&resource->lock);
+	strcpy(acpi_device_name(device), ACPI_POWER_METER_DEVICE_NAME);
+	strcpy(acpi_device_class(device), ACPI_POWER_METER_CLASS);
+	device->driver_data = resource;
+
+	free_capabilities(resource);
+	res = read_capabilities(resource);
+	if (res)
+		goto exit_free;
+
+	resource->trip[0] = resource->trip[1] = -1;
+
+	res = setup_attrs(resource);
+	if (res)
+		goto exit_free;
+
+	resource->hwmon_dev = hwmon_device_register(&device->dev);
+	if (IS_ERR(resource->hwmon_dev)) {
+		res = PTR_ERR(resource->hwmon_dev);
+		goto exit_remove;
+	}
+
+	res = 0;
+	goto exit;
+
+exit_remove:
+	remove_attrs(resource);
+exit_free:
+	kfree(resource);
+exit:
+	return res;
+}
+
+static int acpi_power_meter_remove(struct acpi_device *device, int type)
+{
+	struct acpi_power_meter_resource *resource;
+
+	if (!device || !acpi_driver_data(device))
+		return -EINVAL;
+
+	resource = acpi_driver_data(device);
+	hwmon_device_unregister(resource->hwmon_dev);
+
+	free_capabilities(resource);
+	remove_attrs(resource);
+
+	kfree(resource);
+	return 0;
+}
+
+static int acpi_power_meter_resume(struct acpi_device *device)
+{
+	struct acpi_power_meter_resource *resource;
+
+	if (!device || !acpi_driver_data(device))
+		return -EINVAL;
+
+	resource = acpi_driver_data(device);
+	free_capabilities(resource);
+	read_capabilities(resource);
+
+	return 0;
+}
+
+static struct acpi_driver acpi_power_meter_driver = {
+	.name = "power_meter",
+	.class = ACPI_POWER_METER_CLASS,
+	.ids = power_meter_ids,
+	.ops = {
+		.add = acpi_power_meter_add,
+		.remove = acpi_power_meter_remove,
+		.resume = acpi_power_meter_resume,
+		.notify = acpi_power_meter_notify,
+		},
+};
+
+/* Module init/exit routines */
+static int __init enable_cap_knobs(const struct dmi_system_id *d)
+{
+	cap_in_hardware = 1;
+	return 0;
+}
+
+static struct dmi_system_id __initdata pm_dmi_table[] = {
+	{
+		enable_cap_knobs, "IBM Active Energy Manager",
+		{
+			DMI_MATCH(DMI_SYS_VENDOR, "IBM")
+		},
+	},
+	{}
+};
+
+static int __init acpi_power_meter_init(void)
+{
+	int result;
+
+	if (acpi_disabled)
+		return -ENODEV;
+
+	dmi_check_system(pm_dmi_table);
+
+	result = acpi_bus_register_driver(&acpi_power_meter_driver);
+	if (result < 0)
+		return -ENODEV;
+
+	return 0;
+}
+
+static void __exit acpi_power_meter_exit(void)
+{
+	acpi_bus_unregister_driver(&acpi_power_meter_driver);
+}
+
+MODULE_AUTHOR("Darrick J. Wong <djwong@us.ibm.com>");
+MODULE_DESCRIPTION("ACPI 4.0 power meter driver");
+MODULE_LICENSE("GPL");
+
+module_param(force_cap_on, bool, 0644);
+MODULE_PARM_DESC(force_cap_on, "Enable power cap even it is unsafe to do so.");
+
+module_init(acpi_power_meter_init);
+module_exit(acpi_power_meter_exit);
diff -druN linux-2.6.39-libre/drivers/hwmon/adcxx.c linux-3.0-rc7-libre/drivers/hwmon/adcxx.c
--- linux-2.6.39-libre/drivers/hwmon/adcxx.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/hwmon/adcxx.c	2011-07-11 19:51:52.000000000 -0400
@@ -62,7 +62,7 @@
 {
 	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);
+	struct adcxx *adc = spi_get_drvdata(spi);
 	u8 tx_buf[2];
 	u8 rx_buf[2];
 	int status;
@@ -105,7 +105,7 @@
 		struct device_attribute *devattr, char *buf)
 {
 	struct spi_device *spi = to_spi_device(dev);
-	struct adcxx *adc = dev_get_drvdata(&spi->dev);
+	struct adcxx *adc = spi_get_drvdata(spi);
 	u32 reference;
 
 	if (mutex_lock_interruptible(&adc->lock))
@@ -122,7 +122,7 @@
 	struct device_attribute *devattr, const char *buf, size_t count)
 {
 	struct spi_device *spi = to_spi_device(dev);
-	struct adcxx *adc = dev_get_drvdata(&spi->dev);
+	struct adcxx *adc = spi_get_drvdata(spi);
 	unsigned long value;
 
 	if (strict_strtoul(buf, 10, &value))
@@ -142,7 +142,7 @@
 			      *devattr, char *buf)
 {
 	struct spi_device *spi = to_spi_device(dev);
-	struct adcxx *adc = dev_get_drvdata(&spi->dev);
+	struct adcxx *adc = spi_get_drvdata(spi);
 
 	return sprintf(buf, "adcxx%ds\n", adc->channels);
 }
@@ -182,7 +182,7 @@
 
 	mutex_lock(&adc->lock);
 
-	dev_set_drvdata(&spi->dev, adc);
+	spi_set_drvdata(spi, adc);
 
 	for (i = 0; i < 3 + adc->channels; i++) {
 		status = device_create_file(&spi->dev, &ad_input[i].dev_attr);
@@ -206,7 +206,7 @@
 	for (i--; i >= 0; i--)
 		device_remove_file(&spi->dev, &ad_input[i].dev_attr);
 
-	dev_set_drvdata(&spi->dev, NULL);
+	spi_set_drvdata(spi, NULL);
 	mutex_unlock(&adc->lock);
 	kfree(adc);
 	return status;
@@ -214,7 +214,7 @@
 
 static int __devexit adcxx_remove(struct spi_device *spi)
 {
-	struct adcxx *adc = dev_get_drvdata(&spi->dev);
+	struct adcxx *adc = spi_get_drvdata(spi);
 	int i;
 
 	mutex_lock(&adc->lock);
@@ -222,7 +222,7 @@
 	for (i = 0; i < 3 + adc->channels; i++)
 		device_remove_file(&spi->dev, &ad_input[i].dev_attr);
 
-	dev_set_drvdata(&spi->dev, NULL);
+	spi_set_drvdata(spi, NULL);
 	mutex_unlock(&adc->lock);
 	kfree(adc);
 
diff -druN linux-2.6.39-libre/drivers/hwmon/adm1275.c linux-3.0-rc7-libre/drivers/hwmon/adm1275.c
--- linux-2.6.39-libre/drivers/hwmon/adm1275.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/hwmon/adm1275.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,131 @@
+/*
+ * Hardware monitoring driver for Analog Devices ADM1275 Hot-Swap Controller
+ * and Digital Power Monitor
+ *
+ * Copyright (c) 2011 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 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/err.h>
+#include <linux/slab.h>
+#include <linux/i2c.h>
+#include "pmbus.h"
+
+#define ADM1275_PMON_CONFIG		0xd4
+
+#define ADM1275_VIN_VOUT_SELECT		(1 << 6)
+#define ADM1275_VRANGE			(1 << 5)
+
+static int adm1275_probe(struct i2c_client *client,
+			 const struct i2c_device_id *id)
+{
+	int config;
+	int ret;
+	struct pmbus_driver_info *info;
+
+	if (!i2c_check_functionality(client->adapter,
+				     I2C_FUNC_SMBUS_READ_BYTE_DATA))
+		return -ENODEV;
+
+	info = kzalloc(sizeof(struct pmbus_driver_info), GFP_KERNEL);
+	if (!info)
+		return -ENOMEM;
+
+	config = i2c_smbus_read_byte_data(client, ADM1275_PMON_CONFIG);
+	if (config < 0) {
+		ret = config;
+		goto err_mem;
+	}
+
+	info->pages = 1;
+	info->direct[PSC_VOLTAGE_IN] = true;
+	info->direct[PSC_VOLTAGE_OUT] = true;
+	info->direct[PSC_CURRENT_OUT] = true;
+	info->m[PSC_CURRENT_OUT] = 800;
+	info->b[PSC_CURRENT_OUT] = 20475;
+	info->R[PSC_CURRENT_OUT] = -1;
+	info->func[0] = PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT;
+
+	if (config & ADM1275_VRANGE) {
+		info->m[PSC_VOLTAGE_IN] = 19045;
+		info->b[PSC_VOLTAGE_IN] = 0;
+		info->R[PSC_VOLTAGE_IN] = -2;
+		info->m[PSC_VOLTAGE_OUT] = 19045;
+		info->b[PSC_VOLTAGE_OUT] = 0;
+		info->R[PSC_VOLTAGE_OUT] = -2;
+	} else {
+		info->m[PSC_VOLTAGE_IN] = 6666;
+		info->b[PSC_VOLTAGE_IN] = 0;
+		info->R[PSC_VOLTAGE_IN] = -1;
+		info->m[PSC_VOLTAGE_OUT] = 6666;
+		info->b[PSC_VOLTAGE_OUT] = 0;
+		info->R[PSC_VOLTAGE_OUT] = -1;
+	}
+
+	if (config & ADM1275_VIN_VOUT_SELECT)
+		info->func[0] |= PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT;
+	else
+		info->func[0] |= PMBUS_HAVE_VIN | PMBUS_HAVE_STATUS_INPUT;
+
+	ret = pmbus_do_probe(client, id, info);
+	if (ret)
+		goto err_mem;
+	return 0;
+
+err_mem:
+	kfree(info);
+	return ret;
+}
+
+static int adm1275_remove(struct i2c_client *client)
+{
+	const struct pmbus_driver_info *info = pmbus_get_driver_info(client);
+	int ret;
+
+	ret = pmbus_do_remove(client);
+	kfree(info);
+	return ret;
+}
+
+static const struct i2c_device_id adm1275_id[] = {
+	{"adm1275", 0},
+	{ }
+};
+MODULE_DEVICE_TABLE(i2c, adm1275_id);
+
+static struct i2c_driver adm1275_driver = {
+	.driver = {
+		   .name = "adm1275",
+		   },
+	.probe = adm1275_probe,
+	.remove = adm1275_remove,
+	.id_table = adm1275_id,
+};
+
+static int __init adm1275_init(void)
+{
+	return i2c_add_driver(&adm1275_driver);
+}
+
+static void __exit adm1275_exit(void)
+{
+	i2c_del_driver(&adm1275_driver);
+}
+
+MODULE_AUTHOR("Guenter Roeck");
+MODULE_DESCRIPTION("PMBus driver for Analog Devices ADM1275");
+MODULE_LICENSE("GPL");
+module_init(adm1275_init);
+module_exit(adm1275_exit);
diff -druN linux-2.6.39-libre/drivers/hwmon/asus_atk0110.c linux-3.0-rc7-libre/drivers/hwmon/asus_atk0110.c
--- linux-2.6.39-libre/drivers/hwmon/asus_atk0110.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/hwmon/asus_atk0110.c	2011-07-11 19:51:52.000000000 -0400
@@ -268,6 +268,7 @@
 static void atk_init_attribute(struct device_attribute *attr, char *name,
 		sysfs_show_func show)
 {
+	sysfs_attr_init(&attr->attr);
 	attr->attr.name = name;
 	attr->attr.mode = 0444;
 	attr->show = show;
@@ -1188,19 +1189,15 @@
 	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 -druN linux-2.6.39-libre/drivers/hwmon/coretemp.c linux-3.0-rc7-libre/drivers/hwmon/coretemp.c
--- linux-2.6.39-libre/drivers/hwmon/coretemp.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/hwmon/coretemp.c	2011-07-11 19:51:52.000000000 -0400
@@ -35,128 +35,152 @@
 #include <linux/platform_device.h>
 #include <linux/cpu.h>
 #include <linux/pci.h>
+#include <linux/smp.h>
 #include <asm/msr.h>
 #include <asm/processor.h>
-#include <asm/smp.h>
 
 #define DRVNAME	"coretemp"
 
-typedef enum { SHOW_TEMP, SHOW_TJMAX, SHOW_TTARGET, SHOW_LABEL,
-		SHOW_NAME } SHOW;
+#define BASE_SYSFS_ATTR_NO	2	/* Sysfs Base attr no for coretemp */
+#define NUM_REAL_CORES		16	/* Number of Real cores per cpu */
+#define CORETEMP_NAME_LENGTH	17	/* String Length of attrs */
+#define MAX_ATTRS		5	/* Maximum no of per-core attrs */
+#define MAX_CORE_DATA		(NUM_REAL_CORES + BASE_SYSFS_ATTR_NO)
+
+#ifdef CONFIG_SMP
+#define TO_PHYS_ID(cpu)		cpu_data(cpu).phys_proc_id
+#define TO_CORE_ID(cpu)		cpu_data(cpu).cpu_core_id
+#define TO_ATTR_NO(cpu)		(TO_CORE_ID(cpu) + BASE_SYSFS_ATTR_NO)
+#define for_each_sibling(i, cpu)	for_each_cpu(i, cpu_sibling_mask(cpu))
+#else
+#define TO_PHYS_ID(cpu)		(cpu)
+#define TO_CORE_ID(cpu)		(cpu)
+#define TO_ATTR_NO(cpu)		(cpu)
+#define for_each_sibling(i, cpu)	for (i = 0; false; )
+#endif
 
 /*
- * Functions declaration
+ * Per-Core Temperature Data
+ * @last_updated: The time when the current temperature value was updated
+ *		earlier (in jiffies).
+ * @cpu_core_id: The CPU Core from which temperature values should be read
+ *		This value is passed as "id" field to rdmsr/wrmsr functions.
+ * @status_reg: One of IA32_THERM_STATUS or IA32_PACKAGE_THERM_STATUS,
+ *		from where the temperature values should be read.
+ * @is_pkg_data: If this is 1, the temp_data holds pkgtemp data.
+ *		Otherwise, temp_data holds coretemp data.
+ * @valid: If this is 1, the current temperature is valid.
  */
-
-static struct coretemp_data *coretemp_update_device(struct device *dev);
-
-struct coretemp_data {
-	struct device *hwmon_dev;
-	struct mutex update_lock;
-	const char *name;
-	u32 id;
-	u16 core_id;
-	char valid;		/* zero until following fields are valid */
-	unsigned long last_updated;	/* in jiffies */
+struct temp_data {
 	int temp;
-	int tjmax;
 	int ttarget;
-	u8 alarm;
+	int tjmax;
+	unsigned long last_updated;
+	unsigned int cpu;
+	u32 cpu_core_id;
+	u32 status_reg;
+	bool is_pkg_data;
+	bool valid;
+	struct sensor_device_attribute sd_attrs[MAX_ATTRS];
+	char attr_name[MAX_ATTRS][CORETEMP_NAME_LENGTH];
+	struct mutex update_lock;
 };
 
-/*
- * Sysfs stuff
- */
+/* Platform Data per Physical CPU */
+struct platform_data {
+	struct device *hwmon_dev;
+	u16 phys_proc_id;
+	struct temp_data *core_data[MAX_CORE_DATA];
+	struct device_attribute name_attr;
+};
 
-static ssize_t show_name(struct device *dev, struct device_attribute
-			  *devattr, char *buf)
+struct pdev_entry {
+	struct list_head list;
+	struct platform_device *pdev;
+	u16 phys_proc_id;
+};
+
+static LIST_HEAD(pdev_list);
+static DEFINE_MUTEX(pdev_list_mutex);
+
+static ssize_t show_name(struct device *dev,
+			struct device_attribute *devattr, char *buf)
+{
+	return sprintf(buf, "%s\n", DRVNAME);
+}
+
+static ssize_t show_label(struct device *dev,
+				struct device_attribute *devattr, char *buf)
 {
-	int ret;
 	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
-	struct coretemp_data *data = dev_get_drvdata(dev);
+	struct platform_data *pdata = dev_get_drvdata(dev);
+	struct temp_data *tdata = pdata->core_data[attr->index];
 
-	if (attr->index == SHOW_NAME)
-		ret = sprintf(buf, "%s\n", data->name);
-	else	/* show label */
-		ret = sprintf(buf, "Core %d\n", data->core_id);
-	return ret;
+	if (tdata->is_pkg_data)
+		return sprintf(buf, "Physical id %u\n", pdata->phys_proc_id);
+
+	return sprintf(buf, "Core %u\n", tdata->cpu_core_id);
 }
 
-static ssize_t show_alarm(struct device *dev, struct device_attribute
-			  *devattr, char *buf)
+static ssize_t show_crit_alarm(struct device *dev,
+				struct device_attribute *devattr, char *buf)
 {
-	struct coretemp_data *data = coretemp_update_device(dev);
-	/* read the Out-of-spec log, never clear */
-	return sprintf(buf, "%d\n", data->alarm);
+	u32 eax, edx;
+	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+	struct platform_data *pdata = dev_get_drvdata(dev);
+	struct temp_data *tdata = pdata->core_data[attr->index];
+
+	rdmsr_on_cpu(tdata->cpu, tdata->status_reg, &eax, &edx);
+
+	return sprintf(buf, "%d\n", (eax >> 5) & 1);
 }
 
-static ssize_t show_temp(struct device *dev,
-			 struct device_attribute *devattr, char *buf)
+static ssize_t show_tjmax(struct device *dev,
+			struct device_attribute *devattr, char *buf)
 {
 	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
-	struct coretemp_data *data = coretemp_update_device(dev);
-	int err;
+	struct platform_data *pdata = dev_get_drvdata(dev);
 
-	if (attr->index == SHOW_TEMP)
-		err = data->valid ? sprintf(buf, "%d\n", data->temp) : -EAGAIN;
-	else if (attr->index == SHOW_TJMAX)
-		err = sprintf(buf, "%d\n", data->tjmax);
-	else
-		err = sprintf(buf, "%d\n", data->ttarget);
-	return err;
+	return sprintf(buf, "%d\n", pdata->core_data[attr->index]->tjmax);
 }
 
-static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp, NULL,
-			  SHOW_TEMP);
-static SENSOR_DEVICE_ATTR(temp1_crit, S_IRUGO, show_temp, NULL,
-			  SHOW_TJMAX);
-static SENSOR_DEVICE_ATTR(temp1_max, S_IRUGO, show_temp, NULL,
-			  SHOW_TTARGET);
-static DEVICE_ATTR(temp1_crit_alarm, S_IRUGO, show_alarm, NULL);
-static SENSOR_DEVICE_ATTR(temp1_label, S_IRUGO, show_name, NULL, SHOW_LABEL);
-static SENSOR_DEVICE_ATTR(name, S_IRUGO, show_name, NULL, SHOW_NAME);
-
-static struct attribute *coretemp_attributes[] = {
-	&sensor_dev_attr_name.dev_attr.attr,
-	&sensor_dev_attr_temp1_label.dev_attr.attr,
-	&dev_attr_temp1_crit_alarm.attr,
-	&sensor_dev_attr_temp1_input.dev_attr.attr,
-	&sensor_dev_attr_temp1_crit.dev_attr.attr,
-	NULL
-};
+static ssize_t show_ttarget(struct device *dev,
+				struct device_attribute *devattr, char *buf)
+{
+	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+	struct platform_data *pdata = dev_get_drvdata(dev);
 
-static const struct attribute_group coretemp_group = {
-	.attrs = coretemp_attributes,
-};
+	return sprintf(buf, "%d\n", pdata->core_data[attr->index]->ttarget);
+}
 
-static struct coretemp_data *coretemp_update_device(struct device *dev)
+static ssize_t show_temp(struct device *dev,
+			struct device_attribute *devattr, char *buf)
 {
-	struct coretemp_data *data = dev_get_drvdata(dev);
-
-	mutex_lock(&data->update_lock);
+	u32 eax, edx;
+	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+	struct platform_data *pdata = dev_get_drvdata(dev);
+	struct temp_data *tdata = pdata->core_data[attr->index];
 
-	if (!data->valid || time_after(jiffies, data->last_updated + HZ)) {
-		u32 eax, edx;
+	mutex_lock(&tdata->update_lock);
 
-		data->valid = 0;
-		rdmsr_on_cpu(data->id, MSR_IA32_THERM_STATUS, &eax, &edx);
-		data->alarm = (eax >> 5) & 1;
-		/* update only if data has been valid */
+	/* Check whether the time interval has elapsed */
+	if (!tdata->valid || time_after(jiffies, tdata->last_updated + HZ)) {
+		rdmsr_on_cpu(tdata->cpu, tdata->status_reg, &eax, &edx);
+		tdata->valid = 0;
+		/* Check whether the data is valid */
 		if (eax & 0x80000000) {
-			data->temp = data->tjmax - (((eax >> 16)
-							& 0x7f) * 1000);
-			data->valid = 1;
-		} else {
-			dev_dbg(dev, "Temperature data invalid (0x%x)\n", eax);
+			tdata->temp = tdata->tjmax -
+					((eax >> 16) & 0x7f) * 1000;
+			tdata->valid = 1;
 		}
-		data->last_updated = jiffies;
+		tdata->last_updated = jiffies;
 	}
 
-	mutex_unlock(&data->update_lock);
-	return data;
+	mutex_unlock(&tdata->update_lock);
+	return tdata->valid ? sprintf(buf, "%d\n", tdata->temp) : -EAGAIN;
 }
 
-static int __devinit adjust_tjmax(struct cpuinfo_x86 *c, u32 id, struct device *dev)
+static int adjust_tjmax(struct cpuinfo_x86 *c, u32 id, struct device *dev)
 {
 	/* The 100C is default for both mobile and non mobile CPUs */
 
@@ -169,9 +193,8 @@
 
 	/* Early chips have no MSR for TjMax */
 
-	if ((c->x86_model == 0xf) && (c->x86_mask < 4)) {
+	if (c->x86_model == 0xf && c->x86_mask < 4)
 		usemsr_ee = 0;
-	}
 
 	/* Atom CPUs */
 
@@ -190,14 +213,14 @@
 		pci_dev_put(host_bridge);
 	}
 
-	if ((c->x86_model > 0xe) && (usemsr_ee)) {
+	if (c->x86_model > 0xe && usemsr_ee) {
 		u8 platform_id;
 
-		/* Now we can detect the mobile CPU using Intel provided table
-		   http://softwarecommunity.intel.com/Wiki/Mobility/720.htm
-		   For Core2 cores, check MSR 0x17, bit 28 1 = Mobile CPU
-		*/
-
+		/*
+		 * Now we can detect the mobile CPU using Intel provided table
+		 * http://softwarecommunity.intel.com/Wiki/Mobility/720.htm
+		 * For Core2 cores, check MSR 0x17, bit 28 1 = Mobile CPU
+		 */
 		err = rdmsr_safe_on_cpu(id, 0x17, &eax, &edx);
 		if (err) {
 			dev_warn(dev,
@@ -205,20 +228,26 @@
 				 " CPU\n");
 			usemsr_ee = 0;
 		} else if (c->x86_model < 0x17 && !(eax & 0x10000000)) {
-			/* Trust bit 28 up to Penryn, I could not find any
-			   documentation on that; if you happen to know
-			   someone at Intel please ask */
+			/*
+			 * Trust bit 28 up to Penryn, I could not find any
+			 * documentation on that; if you happen to know
+			 * someone at Intel please ask
+			 */
 			usemsr_ee = 0;
 		} else {
 			/* Platform ID bits 52:50 (EDX starts at bit 32) */
 			platform_id = (edx >> 18) & 0x7;
 
-			/* Mobile Penryn CPU seems to be platform ID 7 or 5
-			  (guesswork) */
-			if ((c->x86_model == 0x17) &&
-			    ((platform_id == 5) || (platform_id == 7))) {
-				/* If MSR EE bit is set, set it to 90 degrees C,
-				   otherwise 105 degrees C */
+			/*
+			 * Mobile Penryn CPU seems to be platform ID 7 or 5
+			 * (guesswork)
+			 */
+			if (c->x86_model == 0x17 &&
+			    (platform_id == 5 || platform_id == 7)) {
+				/*
+				 * If MSR EE bit is set, set it to 90 degrees C,
+				 * otherwise 105 degrees C
+				 */
 				tjmax_ee = 90000;
 				tjmax = 105000;
 			}
@@ -226,7 +255,6 @@
 	}
 
 	if (usemsr_ee) {
-
 		err = rdmsr_safe_on_cpu(id, 0xee, &eax, &edx);
 		if (err) {
 			dev_warn(dev,
@@ -235,25 +263,28 @@
 		} else if (eax & 0x40000000) {
 			tjmax = tjmax_ee;
 		}
-	/* if we dont use msr EE it means we are desktop CPU (with exeception
-	   of Atom) */
 	} else if (tjmax == 100000) {
+		/*
+		 * If we don't use msr EE it means we are desktop CPU
+		 * (with exeception of Atom)
+		 */
 		dev_warn(dev, "Using relative temperature scale!\n");
 	}
 
 	return tjmax;
 }
 
-static int __devinit get_tjmax(struct cpuinfo_x86 *c, u32 id,
-			       struct device *dev)
+static int get_tjmax(struct cpuinfo_x86 *c, u32 id, struct device *dev)
 {
 	/* The 100C is default for both mobile and non mobile CPUs */
 	int err;
 	u32 eax, edx;
 	u32 val;
 
-	/* A new feature of current Intel(R) processors, the
-	   IA32_TEMPERATURE_TARGET contains the TjMax value */
+	/*
+	 * A new feature of current Intel(R) processors, the
+	 * IA32_TEMPERATURE_TARGET contains the TjMax value
+	 */
 	err = rdmsr_safe_on_cpu(id, MSR_IA32_TEMPERATURE_TARGET, &eax, &edx);
 	if (err) {
 		dev_warn(dev, "Unable to read TjMax from CPU.\n");
@@ -263,7 +294,7 @@
 		 * If the TjMax is not plausible, an assumption
 		 * will be used
 		 */
-		if ((val > 80) && (val < 120)) {
+		if (val) {
 			dev_info(dev, "TjMax is %d C.\n", val);
 			return val * 1000;
 		}
@@ -271,24 +302,9 @@
 
 	/*
 	 * An assumption is made for early CPUs and unreadable MSR.
-	 * NOTE: the given value may not be correct.
+	 * NOTE: the calculated value may not be correct.
 	 */
-
-	switch (c->x86_model) {
-	case 0xe:
-	case 0xf:
-	case 0x16:
-	case 0x1a:
-		dev_warn(dev, "TjMax is assumed as 100 C!\n");
-		return 100000;
-	case 0x17:
-	case 0x1c:		/* Atom CPUs */
-		return adjust_tjmax(c, id, dev);
-	default:
-		dev_warn(dev, "CPU (model=0x%x) is not supported yet,"
-			" using default TjMax of 100C.\n", c->x86_model);
-		return 100000;
-	}
+	return adjust_tjmax(c, id, dev);
 }
 
 static void __devinit get_ucode_rev_on_cpu(void *edx)
@@ -300,115 +316,301 @@
 	rdmsr(MSR_IA32_UCODE_REV, eax, *(u32 *)edx);
 }
 
-static int __devinit coretemp_probe(struct platform_device *pdev)
+static int get_pkg_tjmax(unsigned int cpu, struct device *dev)
 {
-	struct coretemp_data *data;
-	struct cpuinfo_x86 *c = &cpu_data(pdev->id);
 	int err;
-	u32 eax, edx;
+	u32 eax, edx, val;
 
-	if (!(data = kzalloc(sizeof(struct coretemp_data), GFP_KERNEL))) {
-		err = -ENOMEM;
-		dev_err(&pdev->dev, "Out of memory\n");
-		goto exit;
+	err = rdmsr_safe_on_cpu(cpu, MSR_IA32_TEMPERATURE_TARGET, &eax, &edx);
+	if (!err) {
+		val = (eax >> 16) & 0xff;
+		if (val)
+			return val * 1000;
 	}
+	dev_warn(dev, "Unable to read Pkg-TjMax from CPU:%u\n", cpu);
+	return 100000; /* Default TjMax: 100 degree celsius */
+}
 
-	data->id = pdev->id;
-#ifdef CONFIG_SMP
-	data->core_id = c->cpu_core_id;
-#endif
-	data->name = "coretemp";
-	mutex_init(&data->update_lock);
+static int create_name_attr(struct platform_data *pdata, struct device *dev)
+{
+	sysfs_attr_init(&pdata->name_attr.attr);
+	pdata->name_attr.attr.name = "name";
+	pdata->name_attr.attr.mode = S_IRUGO;
+	pdata->name_attr.show = show_name;
+	return device_create_file(dev, &pdata->name_attr);
+}
 
-	/* test if we can access the THERM_STATUS MSR */
-	err = rdmsr_safe_on_cpu(data->id, MSR_IA32_THERM_STATUS, &eax, &edx);
-	if (err) {
-		dev_err(&pdev->dev,
-			"Unable to access THERM_STATUS MSR, giving up\n");
-		goto exit_free;
+static int create_core_attrs(struct temp_data *tdata, struct device *dev,
+				int attr_no)
+{
+	int err, i;
+	static ssize_t (*rd_ptr[MAX_ATTRS]) (struct device *dev,
+			struct device_attribute *devattr, char *buf) = {
+			show_label, show_crit_alarm, show_ttarget,
+			show_temp, show_tjmax };
+	static const char *names[MAX_ATTRS] = {
+					"temp%d_label", "temp%d_crit_alarm",
+					"temp%d_max", "temp%d_input",
+					"temp%d_crit" };
+
+	for (i = 0; i < MAX_ATTRS; i++) {
+		snprintf(tdata->attr_name[i], CORETEMP_NAME_LENGTH, names[i],
+			attr_no);
+		sysfs_attr_init(&tdata->sd_attrs[i].dev_attr.attr);
+		tdata->sd_attrs[i].dev_attr.attr.name = tdata->attr_name[i];
+		tdata->sd_attrs[i].dev_attr.attr.mode = S_IRUGO;
+		tdata->sd_attrs[i].dev_attr.show = rd_ptr[i];
+		tdata->sd_attrs[i].dev_attr.store = NULL;
+		tdata->sd_attrs[i].index = attr_no;
+		err = device_create_file(dev, &tdata->sd_attrs[i].dev_attr);
+		if (err)
+			goto exit_free;
 	}
+	return 0;
 
-	/* Check if we have problem with errata AE18 of Core processors:
-	   Readings might stop update when processor visited too deep sleep,
-	   fixed for stepping D0 (6EC).
-	*/
+exit_free:
+	while (--i >= 0)
+		device_remove_file(dev, &tdata->sd_attrs[i].dev_attr);
+	return err;
+}
 
-	if ((c->x86_model == 0xe) && (c->x86_mask < 0xc)) {
+static void update_ttarget(__u8 cpu_model, struct temp_data *tdata,
+				struct device *dev)
+{
+	int err;
+	u32 eax, edx;
+
+	/*
+	 * Initialize ttarget value. Eventually this will be
+	 * initialized with the value from MSR_IA32_THERM_INTERRUPT
+	 * register. If IA32_TEMPERATURE_TARGET is supported, this
+	 * value will be over written below.
+	 * To Do: Patch to initialize ttarget from MSR_IA32_THERM_INTERRUPT
+	 */
+	tdata->ttarget = tdata->tjmax - 20000;
+
+	/*
+	 * Read the still undocumented IA32_TEMPERATURE_TARGET. It exists
+	 * on older CPUs but not in this register,
+	 * Atoms don't have it either.
+	 */
+	if (cpu_model > 0xe && cpu_model != 0x1c) {
+		err = rdmsr_safe_on_cpu(tdata->cpu,
+				MSR_IA32_TEMPERATURE_TARGET, &eax, &edx);
+		if (err) {
+			dev_warn(dev,
+			"Unable to read IA32_TEMPERATURE_TARGET MSR\n");
+		} else {
+			tdata->ttarget = tdata->tjmax -
+					((eax >> 8) & 0xff) * 1000;
+		}
+	}
+}
+
+static int __devinit chk_ucode_version(struct platform_device *pdev)
+{
+	struct cpuinfo_x86 *c = &cpu_data(pdev->id);
+	int err;
+	u32 edx;
+
+	/*
+	 * Check if we have problem with errata AE18 of Core processors:
+	 * Readings might stop update when processor visited too deep sleep,
+	 * fixed for stepping D0 (6EC).
+	 */
+	if (c->x86_model == 0xe && c->x86_mask < 0xc) {
 		/* check for microcode update */
-		err = smp_call_function_single(data->id, get_ucode_rev_on_cpu,
+		err = smp_call_function_single(pdev->id, get_ucode_rev_on_cpu,
 					       &edx, 1);
 		if (err) {
 			dev_err(&pdev->dev,
 				"Cannot determine microcode revision of "
-				"CPU#%u (%d)!\n", data->id, err);
-			err = -ENODEV;
-			goto exit_free;
+				"CPU#%u (%d)!\n", pdev->id, err);
+			return -ENODEV;
 		} else if (edx < 0x39) {
-			err = -ENODEV;
 			dev_err(&pdev->dev,
 				"Errata AE18 not fixed, update BIOS or "
 				"microcode of the CPU!\n");
-			goto exit_free;
+			return -ENODEV;
 		}
 	}
+	return 0;
+}
 
-	data->tjmax = get_tjmax(c, data->id, &pdev->dev);
-	platform_set_drvdata(pdev, data);
+static struct platform_device *coretemp_get_pdev(unsigned int cpu)
+{
+	u16 phys_proc_id = TO_PHYS_ID(cpu);
+	struct pdev_entry *p;
+
+	mutex_lock(&pdev_list_mutex);
+
+	list_for_each_entry(p, &pdev_list, list)
+		if (p->phys_proc_id == phys_proc_id) {
+			mutex_unlock(&pdev_list_mutex);
+			return p->pdev;
+		}
+
+	mutex_unlock(&pdev_list_mutex);
+	return NULL;
+}
+
+static struct temp_data *init_temp_data(unsigned int cpu, int pkg_flag)
+{
+	struct temp_data *tdata;
+
+	tdata = kzalloc(sizeof(struct temp_data), GFP_KERNEL);
+	if (!tdata)
+		return NULL;
+
+	tdata->status_reg = pkg_flag ? MSR_IA32_PACKAGE_THERM_STATUS :
+							MSR_IA32_THERM_STATUS;
+	tdata->is_pkg_data = pkg_flag;
+	tdata->cpu = cpu;
+	tdata->cpu_core_id = TO_CORE_ID(cpu);
+	mutex_init(&tdata->update_lock);
+	return tdata;
+}
+
+static int create_core_data(struct platform_data *pdata,
+				struct platform_device *pdev,
+				unsigned int cpu, int pkg_flag)
+{
+	struct temp_data *tdata;
+	struct cpuinfo_x86 *c = &cpu_data(cpu);
+	u32 eax, edx;
+	int err, attr_no;
 
 	/*
-	 * read the still undocumented IA32_TEMPERATURE_TARGET. It exists
-	 * on older CPUs but not in this register,
-	 * Atoms don't have it either.
+	 * Find attr number for sysfs:
+	 * We map the attr number to core id of the CPU
+	 * The attr number is always core id + 2
+	 * The Pkgtemp will always show up as temp1_*, if available
 	 */
+	attr_no = pkg_flag ? 1 : TO_ATTR_NO(cpu);
 
-	if ((c->x86_model > 0xe) && (c->x86_model != 0x1c)) {
-		err = rdmsr_safe_on_cpu(data->id, MSR_IA32_TEMPERATURE_TARGET,
-		    &eax, &edx);
-		if (err) {
-			dev_warn(&pdev->dev, "Unable to read"
-					" IA32_TEMPERATURE_TARGET MSR\n");
-		} else {
-			data->ttarget = data->tjmax -
-					(((eax >> 8) & 0xff) * 1000);
-			err = device_create_file(&pdev->dev,
-					&sensor_dev_attr_temp1_max.dev_attr);
-			if (err)
-				goto exit_free;
-		}
-	}
+	if (attr_no > MAX_CORE_DATA - 1)
+		return -ERANGE;
 
-	if ((err = sysfs_create_group(&pdev->dev.kobj, &coretemp_group)))
-		goto exit_dev;
+	/*
+	 * Provide a single set of attributes for all HT siblings of a core
+	 * to avoid duplicate sensors (the processor ID and core ID of all
+	 * HT siblings of a core are the same).
+	 * Skip if a HT sibling of this core is already registered.
+	 * This is not an error.
+	 */
+	if (pdata->core_data[attr_no] != NULL)
+		return 0;
 
-	data->hwmon_dev = hwmon_device_register(&pdev->dev);
-	if (IS_ERR(data->hwmon_dev)) {
-		err = PTR_ERR(data->hwmon_dev);
-		dev_err(&pdev->dev, "Class registration failed (%d)\n",
-			err);
-		goto exit_class;
-	}
+	tdata = init_temp_data(cpu, pkg_flag);
+	if (!tdata)
+		return -ENOMEM;
+
+	/* Test if we can access the status register */
+	err = rdmsr_safe_on_cpu(cpu, tdata->status_reg, &eax, &edx);
+	if (err)
+		goto exit_free;
+
+	/* We can access status register. Get Critical Temperature */
+	if (pkg_flag)
+		tdata->tjmax = get_pkg_tjmax(pdev->id, &pdev->dev);
+	else
+		tdata->tjmax = get_tjmax(c, cpu, &pdev->dev);
+
+	update_ttarget(c->x86_model, tdata, &pdev->dev);
+	pdata->core_data[attr_no] = tdata;
+
+	/* Create sysfs interfaces */
+	err = create_core_attrs(tdata, &pdev->dev, attr_no);
+	if (err)
+		goto exit_free;
 
 	return 0;
+exit_free:
+	kfree(tdata);
+	return err;
+}
 
-exit_class:
-	sysfs_remove_group(&pdev->dev.kobj, &coretemp_group);
-exit_dev:
-	device_remove_file(&pdev->dev, &sensor_dev_attr_temp1_max.dev_attr);
+static void coretemp_add_core(unsigned int cpu, int pkg_flag)
+{
+	struct platform_data *pdata;
+	struct platform_device *pdev = coretemp_get_pdev(cpu);
+	int err;
+
+	if (!pdev)
+		return;
+
+	pdata = platform_get_drvdata(pdev);
+
+	err = create_core_data(pdata, pdev, cpu, pkg_flag);
+	if (err)
+		dev_err(&pdev->dev, "Adding Core %u failed\n", cpu);
+}
+
+static void coretemp_remove_core(struct platform_data *pdata,
+				struct device *dev, int indx)
+{
+	int i;
+	struct temp_data *tdata = pdata->core_data[indx];
+
+	/* Remove the sysfs attributes */
+	for (i = 0; i < MAX_ATTRS; i++)
+		device_remove_file(dev, &tdata->sd_attrs[i].dev_attr);
+
+	kfree(pdata->core_data[indx]);
+	pdata->core_data[indx] = NULL;
+}
+
+static int __devinit coretemp_probe(struct platform_device *pdev)
+{
+	struct platform_data *pdata;
+	int err;
+
+	/* Check the microcode version of the CPU */
+	err = chk_ucode_version(pdev);
+	if (err)
+		return err;
+
+	/* Initialize the per-package data structures */
+	pdata = kzalloc(sizeof(struct platform_data), GFP_KERNEL);
+	if (!pdata)
+		return -ENOMEM;
+
+	err = create_name_attr(pdata, &pdev->dev);
+	if (err)
+		goto exit_free;
+
+	pdata->phys_proc_id = TO_PHYS_ID(pdev->id);
+	platform_set_drvdata(pdev, pdata);
+
+	pdata->hwmon_dev = hwmon_device_register(&pdev->dev);
+	if (IS_ERR(pdata->hwmon_dev)) {
+		err = PTR_ERR(pdata->hwmon_dev);
+		dev_err(&pdev->dev, "Class registration failed (%d)\n", err);
+		goto exit_name;
+	}
+	return 0;
+
+exit_name:
+	device_remove_file(&pdev->dev, &pdata->name_attr);
+	platform_set_drvdata(pdev, NULL);
 exit_free:
-	kfree(data);
-exit:
+	kfree(pdata);
 	return err;
 }
 
 static int __devexit coretemp_remove(struct platform_device *pdev)
 {
-	struct coretemp_data *data = platform_get_drvdata(pdev);
+	struct platform_data *pdata = platform_get_drvdata(pdev);
+	int i;
 
-	hwmon_device_unregister(data->hwmon_dev);
-	sysfs_remove_group(&pdev->dev.kobj, &coretemp_group);
-	device_remove_file(&pdev->dev, &sensor_dev_attr_temp1_max.dev_attr);
+	for (i = MAX_CORE_DATA - 1; i >= 0; --i)
+		if (pdata->core_data[i])
+			coretemp_remove_core(pdata, &pdev->dev, i);
+
+	device_remove_file(&pdev->dev, &pdata->name_attr);
+	hwmon_device_unregister(pdata->hwmon_dev);
 	platform_set_drvdata(pdev, NULL);
-	kfree(data);
+	kfree(pdata);
 	return 0;
 }
 
@@ -421,50 +623,14 @@
 	.remove = __devexit_p(coretemp_remove),
 };
 
-struct pdev_entry {
-	struct list_head list;
-	struct platform_device *pdev;
-	unsigned int cpu;
-#ifdef CONFIG_SMP
-	u16 phys_proc_id;
-	u16 cpu_core_id;
-#endif
-};
-
-static LIST_HEAD(pdev_list);
-static DEFINE_MUTEX(pdev_list_mutex);
-
 static int __cpuinit coretemp_device_add(unsigned int cpu)
 {
 	int err;
 	struct platform_device *pdev;
 	struct pdev_entry *pdev_entry;
-	struct cpuinfo_x86 *c = &cpu_data(cpu);
-
-	/*
-	 * CPUID.06H.EAX[0] indicates whether the CPU has thermal
-	 * sensors. We check this bit only, all the early CPUs
-	 * without thermal sensors will be filtered out.
-	 */
-	if (!cpu_has(c, X86_FEATURE_DTS)) {
-		pr_info("CPU (model=0x%x) has no thermal sensor\n",
-			c->x86_model);
-		return 0;
-	}
 
 	mutex_lock(&pdev_list_mutex);
 
-#ifdef CONFIG_SMP
-	/* Skip second HT entry of each core */
-	list_for_each_entry(pdev_entry, &pdev_list, list) {
-		if (c->phys_proc_id == pdev_entry->phys_proc_id &&
-		    c->cpu_core_id == pdev_entry->cpu_core_id) {
-			err = 0;	/* Not an error */
-			goto exit;
-		}
-	}
-#endif
-
 	pdev = platform_device_alloc(DRVNAME, cpu);
 	if (!pdev) {
 		err = -ENOMEM;
@@ -485,11 +651,8 @@
 	}
 
 	pdev_entry->pdev = pdev;
-	pdev_entry->cpu = cpu;
-#ifdef CONFIG_SMP
-	pdev_entry->phys_proc_id = c->phys_proc_id;
-	pdev_entry->cpu_core_id = c->cpu_core_id;
-#endif
+	pdev_entry->phys_proc_id = TO_PHYS_ID(cpu);
+
 	list_add_tail(&pdev_entry->list, &pdev_list);
 	mutex_unlock(&pdev_list_mutex);
 
@@ -504,28 +667,118 @@
 	return err;
 }
 
-static void __cpuinit coretemp_device_remove(unsigned int cpu)
+static void coretemp_device_remove(unsigned int cpu)
 {
-	struct pdev_entry *p;
-	unsigned int i;
+	struct pdev_entry *p, *n;
+	u16 phys_proc_id = TO_PHYS_ID(cpu);
 
 	mutex_lock(&pdev_list_mutex);
-	list_for_each_entry(p, &pdev_list, list) {
-		if (p->cpu != cpu)
+	list_for_each_entry_safe(p, n, &pdev_list, list) {
+		if (p->phys_proc_id != phys_proc_id)
 			continue;
-
 		platform_device_unregister(p->pdev);
 		list_del(&p->list);
-		mutex_unlock(&pdev_list_mutex);
 		kfree(p);
-		for_each_cpu(i, cpu_sibling_mask(cpu))
-			if (i != cpu && !coretemp_device_add(i))
-				break;
-		return;
 	}
 	mutex_unlock(&pdev_list_mutex);
 }
 
+static bool is_any_core_online(struct platform_data *pdata)
+{
+	int i;
+
+	/* Find online cores, except pkgtemp data */
+	for (i = MAX_CORE_DATA - 1; i >= 0; --i) {
+		if (pdata->core_data[i] &&
+			!pdata->core_data[i]->is_pkg_data) {
+			return true;
+		}
+	}
+	return false;
+}
+
+static void __cpuinit get_core_online(unsigned int cpu)
+{
+	struct cpuinfo_x86 *c = &cpu_data(cpu);
+	struct platform_device *pdev = coretemp_get_pdev(cpu);
+	int err;
+
+	/*
+	 * CPUID.06H.EAX[0] indicates whether the CPU has thermal
+	 * sensors. We check this bit only, all the early CPUs
+	 * without thermal sensors will be filtered out.
+	 */
+	if (!cpu_has(c, X86_FEATURE_DTS))
+		return;
+
+	if (!pdev) {
+		/*
+		 * Alright, we have DTS support.
+		 * We are bringing the _first_ core in this pkg
+		 * online. So, initialize per-pkg data structures and
+		 * then bring this core online.
+		 */
+		err = coretemp_device_add(cpu);
+		if (err)
+			return;
+		/*
+		 * Check whether pkgtemp support is available.
+		 * If so, add interfaces for pkgtemp.
+		 */
+		if (cpu_has(c, X86_FEATURE_PTS))
+			coretemp_add_core(cpu, 1);
+	}
+	/*
+	 * Physical CPU device already exists.
+	 * So, just add interfaces for this core.
+	 */
+	coretemp_add_core(cpu, 0);
+}
+
+static void __cpuinit put_core_offline(unsigned int cpu)
+{
+	int i, indx;
+	struct platform_data *pdata;
+	struct platform_device *pdev = coretemp_get_pdev(cpu);
+
+	/* If the physical CPU device does not exist, just return */
+	if (!pdev)
+		return;
+
+	pdata = platform_get_drvdata(pdev);
+
+	indx = TO_ATTR_NO(cpu);
+
+	if (pdata->core_data[indx] && pdata->core_data[indx]->cpu == cpu)
+		coretemp_remove_core(pdata, &pdev->dev, indx);
+
+	/*
+	 * If a HT sibling of a core is taken offline, but another HT sibling
+	 * of the same core is still online, register the alternate sibling.
+	 * This ensures that exactly one set of attributes is provided as long
+	 * as at least one HT sibling of a core is online.
+	 */
+	for_each_sibling(i, cpu) {
+		if (i != cpu) {
+			get_core_online(i);
+			/*
+			 * Display temperature sensor data for one HT sibling
+			 * per core only, so abort the loop after one such
+			 * sibling has been found.
+			 */
+			break;
+		}
+	}
+	/*
+	 * If all cores in this pkg are offline, remove the device.
+	 * coretemp_device_remove calls unregister_platform_device,
+	 * which in turn calls coretemp_remove. This removes the
+	 * pkgtemp entry and does other clean ups.
+	 */
+	if (!is_any_core_online(pdata))
+		coretemp_device_remove(cpu);
+}
+
 static int __cpuinit coretemp_cpu_callback(struct notifier_block *nfb,
 				 unsigned long action, void *hcpu)
 {
@@ -534,10 +787,10 @@
 	switch (action) {
 	case CPU_ONLINE:
 	case CPU_DOWN_FAILED:
-		coretemp_device_add(cpu);
+		get_core_online(cpu);
 		break;
 	case CPU_DOWN_PREPARE:
-		coretemp_device_remove(cpu);
+		put_core_offline(cpu);
 		break;
 	}
 	return NOTIFY_OK;
@@ -560,7 +813,7 @@
 		goto exit;
 
 	for_each_online_cpu(i)
-		coretemp_device_add(i);
+		get_core_online(i);
 
 #ifndef CONFIG_HOTPLUG_CPU
 	if (list_empty(&pdev_list)) {
diff -druN linux-2.6.39-libre/drivers/hwmon/emc6w201.c linux-3.0-rc7-libre/drivers/hwmon/emc6w201.c
--- linux-2.6.39-libre/drivers/hwmon/emc6w201.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/hwmon/emc6w201.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,569 @@
+/*
+ * emc6w201.c - Hardware monitoring driver for the SMSC EMC6W201
+ * Copyright (C) 2011  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/delay.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/jiffies.h>
+#include <linux/i2c.h>
+#include <linux/hwmon.h>
+#include <linux/hwmon-sysfs.h>
+#include <linux/err.h>
+#include <linux/mutex.h>
+
+/*
+ * Addresses to scan
+ */
+
+static const unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, I2C_CLIENT_END };
+
+/*
+ * The EMC6W201 registers
+ */
+
+#define EMC6W201_REG_IN(nr)		(0x20 + (nr))
+#define EMC6W201_REG_TEMP(nr)		(0x26 + (nr))
+#define EMC6W201_REG_FAN(nr)		(0x2C + (nr) * 2)
+#define EMC6W201_REG_COMPANY		0x3E
+#define EMC6W201_REG_VERSTEP		0x3F
+#define EMC6W201_REG_CONFIG		0x40
+#define EMC6W201_REG_IN_LOW(nr)		(0x4A + (nr) * 2)
+#define EMC6W201_REG_IN_HIGH(nr)	(0x4B + (nr) * 2)
+#define EMC6W201_REG_TEMP_LOW(nr)	(0x56 + (nr) * 2)
+#define EMC6W201_REG_TEMP_HIGH(nr)	(0x57 + (nr) * 2)
+#define EMC6W201_REG_FAN_MIN(nr)	(0x62 + (nr) * 2)
+
+enum { input, min, max } subfeature;
+
+/*
+ * Per-device data
+ */
+
+struct emc6w201_data {
+	struct device *hwmon_dev;
+	struct mutex update_lock;
+	char valid; /* zero until following fields are valid */
+	unsigned long last_updated; /* in jiffies */
+
+	/* registers values */
+	u8 in[3][6];
+	s8 temp[3][6];
+	u16 fan[2][5];
+};
+
+/*
+ * Combine LSB and MSB registers in a single value
+ * Locking: must be called with data->update_lock held
+ */
+static u16 emc6w201_read16(struct i2c_client *client, u8 reg)
+{
+	int lsb, msb;
+
+	lsb = i2c_smbus_read_byte_data(client, reg);
+	msb = i2c_smbus_read_byte_data(client, reg + 1);
+	if (unlikely(lsb < 0 || msb < 0)) {
+		dev_err(&client->dev, "%d-bit %s failed at 0x%02x\n",
+			16, "read", reg);
+		return 0xFFFF;	/* Arbitrary value */
+	}
+
+	return (msb << 8) | lsb;
+}
+
+/*
+ * Write 16-bit value to LSB and MSB registers
+ * Locking: must be called with data->update_lock held
+ */
+static int emc6w201_write16(struct i2c_client *client, u8 reg, u16 val)
+{
+	int err;
+
+	err = i2c_smbus_write_byte_data(client, reg, val & 0xff);
+	if (likely(!err))
+		err = i2c_smbus_write_byte_data(client, reg + 1, val >> 8);
+	if (unlikely(err < 0))
+		dev_err(&client->dev, "%d-bit %s failed at 0x%02x\n",
+			16, "write", reg);
+
+	return err;
+}
+
+/* Read 8-bit value from register */
+static u8 emc6w201_read8(struct i2c_client *client, u8 reg)
+{
+	int val;
+
+	val = i2c_smbus_read_byte_data(client, reg);
+	if (unlikely(val < 0)) {
+		dev_err(&client->dev, "%d-bit %s failed at 0x%02x\n",
+			8, "read", reg);
+		return 0x00;	/* Arbitrary value */
+	}
+
+	return val;
+}
+
+/* Write 8-bit value to register */
+static int emc6w201_write8(struct i2c_client *client, u8 reg, u8 val)
+{
+	int err;
+
+	err = i2c_smbus_write_byte_data(client, reg, val);
+	if (unlikely(err < 0))
+		dev_err(&client->dev, "%d-bit %s failed at 0x%02x\n",
+			8, "write", reg);
+
+	return err;
+}
+
+static struct emc6w201_data *emc6w201_update_device(struct device *dev)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct emc6w201_data *data = i2c_get_clientdata(client);
+	int nr;
+
+	mutex_lock(&data->update_lock);
+
+	if (time_after(jiffies, data->last_updated + HZ) || !data->valid) {
+		for (nr = 0; nr < 6; nr++) {
+			data->in[input][nr] =
+				emc6w201_read8(client,
+						EMC6W201_REG_IN(nr));
+			data->in[min][nr] =
+				emc6w201_read8(client,
+						EMC6W201_REG_IN_LOW(nr));
+			data->in[max][nr] =
+				emc6w201_read8(client,
+						EMC6W201_REG_IN_HIGH(nr));
+		}
+
+		for (nr = 0; nr < 6; nr++) {
+			data->temp[input][nr] =
+				emc6w201_read8(client,
+						EMC6W201_REG_TEMP(nr));
+			data->temp[min][nr] =
+				emc6w201_read8(client,
+						EMC6W201_REG_TEMP_LOW(nr));
+			data->temp[max][nr] =
+				emc6w201_read8(client,
+						EMC6W201_REG_TEMP_HIGH(nr));
+		}
+
+		for (nr = 0; nr < 5; nr++) {
+			data->fan[input][nr] =
+				emc6w201_read16(client,
+						EMC6W201_REG_FAN(nr));
+			data->fan[min][nr] =
+				emc6w201_read16(client,
+						EMC6W201_REG_FAN_MIN(nr));
+		}
+
+		data->last_updated = jiffies;
+		data->valid = 1;
+	}
+
+	mutex_unlock(&data->update_lock);
+
+	return data;
+}
+
+/*
+ * Sysfs callback functions
+ */
+
+static const u16 nominal_mv[6] = { 2500, 1500, 3300, 5000, 1500, 1500 };
+
+static ssize_t show_in(struct device *dev, struct device_attribute *devattr,
+	char *buf)
+{
+	struct emc6w201_data *data = emc6w201_update_device(dev);
+	int sf = to_sensor_dev_attr_2(devattr)->index;
+	int nr = to_sensor_dev_attr_2(devattr)->nr;
+
+	return sprintf(buf, "%u\n",
+		       (unsigned)data->in[sf][nr] * nominal_mv[nr] / 0xC0);
+}
+
+static ssize_t set_in(struct device *dev, struct device_attribute *devattr,
+		      const char *buf, size_t count)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct emc6w201_data *data = i2c_get_clientdata(client);
+	int sf = to_sensor_dev_attr_2(devattr)->index;
+	int nr = to_sensor_dev_attr_2(devattr)->nr;
+	int err;
+	long val;
+	u8 reg;
+
+	err = strict_strtol(buf, 10, &val);
+	if (err < 0)
+		return err;
+
+	val = DIV_ROUND_CLOSEST(val * 0xC0, nominal_mv[nr]);
+	reg = (sf == min) ? EMC6W201_REG_IN_LOW(nr)
+			  : EMC6W201_REG_IN_HIGH(nr);
+
+	mutex_lock(&data->update_lock);
+	data->in[sf][nr] = SENSORS_LIMIT(val, 0, 255);
+	err = emc6w201_write8(client, reg, data->in[sf][nr]);
+	mutex_unlock(&data->update_lock);
+
+	return err < 0 ? err : count;
+}
+
+static ssize_t show_temp(struct device *dev, struct device_attribute *devattr,
+	char *buf)
+{
+	struct emc6w201_data *data = emc6w201_update_device(dev);
+	int sf = to_sensor_dev_attr_2(devattr)->index;
+	int nr = to_sensor_dev_attr_2(devattr)->nr;
+
+	return sprintf(buf, "%d\n", (int)data->temp[sf][nr] * 1000);
+}
+
+static ssize_t set_temp(struct device *dev, struct device_attribute *devattr,
+			const char *buf, size_t count)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct emc6w201_data *data = i2c_get_clientdata(client);
+	int sf = to_sensor_dev_attr_2(devattr)->index;
+	int nr = to_sensor_dev_attr_2(devattr)->nr;
+	int err;
+	long val;
+	u8 reg;
+
+	err = strict_strtol(buf, 10, &val);
+	if (err < 0)
+		return err;
+
+	val /= 1000;
+	reg = (sf == min) ? EMC6W201_REG_TEMP_LOW(nr)
+			  : EMC6W201_REG_TEMP_HIGH(nr);
+
+	mutex_lock(&data->update_lock);
+	data->temp[sf][nr] = SENSORS_LIMIT(val, -127, 128);
+	err = emc6w201_write8(client, reg, data->temp[sf][nr]);
+	mutex_unlock(&data->update_lock);
+
+	return err < 0 ? err : count;
+}
+
+static ssize_t show_fan(struct device *dev, struct device_attribute *devattr,
+	char *buf)
+{
+	struct emc6w201_data *data = emc6w201_update_device(dev);
+	int sf = to_sensor_dev_attr_2(devattr)->index;
+	int nr = to_sensor_dev_attr_2(devattr)->nr;
+	unsigned rpm;
+
+	if (data->fan[sf][nr] == 0 || data->fan[sf][nr] == 0xFFFF)
+		rpm = 0;
+	else
+		rpm = 5400000U / data->fan[sf][nr];
+
+	return sprintf(buf, "%u\n", rpm);
+}
+
+static ssize_t set_fan(struct device *dev, struct device_attribute *devattr,
+		       const char *buf, size_t count)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct emc6w201_data *data = i2c_get_clientdata(client);
+	int sf = to_sensor_dev_attr_2(devattr)->index;
+	int nr = to_sensor_dev_attr_2(devattr)->nr;
+	int err;
+	unsigned long val;
+
+	err = strict_strtoul(buf, 10, &val);
+	if (err < 0)
+		return err;
+
+	if (val == 0) {
+		val = 0xFFFF;
+	} else {
+		val = DIV_ROUND_CLOSEST(5400000U, val);
+		val = SENSORS_LIMIT(val, 0, 0xFFFE);
+	}
+
+	mutex_lock(&data->update_lock);
+	data->fan[sf][nr] = val;
+	err = emc6w201_write16(client, EMC6W201_REG_FAN_MIN(nr),
+			       data->fan[sf][nr]);
+	mutex_unlock(&data->update_lock);
+
+	return err < 0 ? err : count;
+}
+
+static SENSOR_DEVICE_ATTR_2(in0_input, S_IRUGO, show_in, NULL, 0, input);
+static SENSOR_DEVICE_ATTR_2(in0_min, S_IRUGO | S_IWUSR, show_in, set_in,
+			    0, min);
+static SENSOR_DEVICE_ATTR_2(in0_max, S_IRUGO | S_IWUSR, show_in, set_in,
+			    0, max);
+static SENSOR_DEVICE_ATTR_2(in1_input, S_IRUGO, show_in, NULL, 1, input);
+static SENSOR_DEVICE_ATTR_2(in1_min, S_IRUGO | S_IWUSR, show_in, set_in,
+			    1, min);
+static SENSOR_DEVICE_ATTR_2(in1_max, S_IRUGO | S_IWUSR, show_in, set_in,
+			    1, max);
+static SENSOR_DEVICE_ATTR_2(in2_input, S_IRUGO, show_in, NULL, 2, input);
+static SENSOR_DEVICE_ATTR_2(in2_min, S_IRUGO | S_IWUSR, show_in, set_in,
+			    2, min);
+static SENSOR_DEVICE_ATTR_2(in2_max, S_IRUGO | S_IWUSR, show_in, set_in,
+			    2, max);
+static SENSOR_DEVICE_ATTR_2(in3_input, S_IRUGO, show_in, NULL, 3, input);
+static SENSOR_DEVICE_ATTR_2(in3_min, S_IRUGO | S_IWUSR, show_in, set_in,
+			    3, min);
+static SENSOR_DEVICE_ATTR_2(in3_max, S_IRUGO | S_IWUSR, show_in, set_in,
+			    3, max);
+static SENSOR_DEVICE_ATTR_2(in4_input, S_IRUGO, show_in, NULL, 4, input);
+static SENSOR_DEVICE_ATTR_2(in4_min, S_IRUGO | S_IWUSR, show_in, set_in,
+			    4, min);
+static SENSOR_DEVICE_ATTR_2(in4_max, S_IRUGO | S_IWUSR, show_in, set_in,
+			    4, max);
+static SENSOR_DEVICE_ATTR_2(in5_input, S_IRUGO, show_in, NULL, 5, input);
+static SENSOR_DEVICE_ATTR_2(in5_min, S_IRUGO | S_IWUSR, show_in, set_in,
+			    5, min);
+static SENSOR_DEVICE_ATTR_2(in5_max, S_IRUGO | S_IWUSR, show_in, set_in,
+			    5, max);
+
+static SENSOR_DEVICE_ATTR_2(temp1_input, S_IRUGO, show_temp, NULL, 0, input);
+static SENSOR_DEVICE_ATTR_2(temp1_min, S_IRUGO | S_IWUSR, show_temp, set_temp,
+			    0, min);
+static SENSOR_DEVICE_ATTR_2(temp1_max, S_IRUGO | S_IWUSR, show_temp, set_temp,
+			    0, max);
+static SENSOR_DEVICE_ATTR_2(temp2_input, S_IRUGO, show_temp, NULL, 1, input);
+static SENSOR_DEVICE_ATTR_2(temp2_min, S_IRUGO | S_IWUSR, show_temp, set_temp,
+			    1, min);
+static SENSOR_DEVICE_ATTR_2(temp2_max, S_IRUGO | S_IWUSR, show_temp, set_temp,
+			    1, max);
+static SENSOR_DEVICE_ATTR_2(temp3_input, S_IRUGO, show_temp, NULL, 2, input);
+static SENSOR_DEVICE_ATTR_2(temp3_min, S_IRUGO | S_IWUSR, show_temp, set_temp,
+			    2, min);
+static SENSOR_DEVICE_ATTR_2(temp3_max, S_IRUGO | S_IWUSR, show_temp, set_temp,
+			    2, max);
+static SENSOR_DEVICE_ATTR_2(temp4_input, S_IRUGO, show_temp, NULL, 3, input);
+static SENSOR_DEVICE_ATTR_2(temp4_min, S_IRUGO | S_IWUSR, show_temp, set_temp,
+			    3, min);
+static SENSOR_DEVICE_ATTR_2(temp4_max, S_IRUGO | S_IWUSR, show_temp, set_temp,
+			    3, max);
+static SENSOR_DEVICE_ATTR_2(temp5_input, S_IRUGO, show_temp, NULL, 4, input);
+static SENSOR_DEVICE_ATTR_2(temp5_min, S_IRUGO | S_IWUSR, show_temp, set_temp,
+			    4, min);
+static SENSOR_DEVICE_ATTR_2(temp5_max, S_IRUGO | S_IWUSR, show_temp, set_temp,
+			    4, max);
+static SENSOR_DEVICE_ATTR_2(temp6_input, S_IRUGO, show_temp, NULL, 5, input);
+static SENSOR_DEVICE_ATTR_2(temp6_min, S_IRUGO | S_IWUSR, show_temp, set_temp,
+			    5, min);
+static SENSOR_DEVICE_ATTR_2(temp6_max, S_IRUGO | S_IWUSR, show_temp, set_temp,
+			    5, max);
+
+static SENSOR_DEVICE_ATTR_2(fan1_input, S_IRUGO, show_fan, NULL, 0, input);
+static SENSOR_DEVICE_ATTR_2(fan1_min, S_IRUGO | S_IWUSR, show_fan, set_fan,
+			    0, min);
+static SENSOR_DEVICE_ATTR_2(fan2_input, S_IRUGO, show_fan, NULL, 1, input);
+static SENSOR_DEVICE_ATTR_2(fan2_min, S_IRUGO | S_IWUSR, show_fan, set_fan,
+			    1, min);
+static SENSOR_DEVICE_ATTR_2(fan3_input, S_IRUGO, show_fan, NULL, 2, input);
+static SENSOR_DEVICE_ATTR_2(fan3_min, S_IRUGO | S_IWUSR, show_fan, set_fan,
+			    2, min);
+static SENSOR_DEVICE_ATTR_2(fan4_input, S_IRUGO, show_fan, NULL, 3, input);
+static SENSOR_DEVICE_ATTR_2(fan4_min, S_IRUGO | S_IWUSR, show_fan, set_fan,
+			    3, min);
+static SENSOR_DEVICE_ATTR_2(fan5_input, S_IRUGO, show_fan, NULL, 4, input);
+static SENSOR_DEVICE_ATTR_2(fan5_min, S_IRUGO | S_IWUSR, show_fan, set_fan,
+			    4, min);
+
+static struct attribute *emc6w201_attributes[] = {
+	&sensor_dev_attr_in0_input.dev_attr.attr,
+	&sensor_dev_attr_in0_min.dev_attr.attr,
+	&sensor_dev_attr_in0_max.dev_attr.attr,
+	&sensor_dev_attr_in1_input.dev_attr.attr,
+	&sensor_dev_attr_in1_min.dev_attr.attr,
+	&sensor_dev_attr_in1_max.dev_attr.attr,
+	&sensor_dev_attr_in2_input.dev_attr.attr,
+	&sensor_dev_attr_in2_min.dev_attr.attr,
+	&sensor_dev_attr_in2_max.dev_attr.attr,
+	&sensor_dev_attr_in3_input.dev_attr.attr,
+	&sensor_dev_attr_in3_min.dev_attr.attr,
+	&sensor_dev_attr_in3_max.dev_attr.attr,
+	&sensor_dev_attr_in4_input.dev_attr.attr,
+	&sensor_dev_attr_in4_min.dev_attr.attr,
+	&sensor_dev_attr_in4_max.dev_attr.attr,
+	&sensor_dev_attr_in5_input.dev_attr.attr,
+	&sensor_dev_attr_in5_min.dev_attr.attr,
+	&sensor_dev_attr_in5_max.dev_attr.attr,
+
+	&sensor_dev_attr_temp1_input.dev_attr.attr,
+	&sensor_dev_attr_temp1_min.dev_attr.attr,
+	&sensor_dev_attr_temp1_max.dev_attr.attr,
+	&sensor_dev_attr_temp2_input.dev_attr.attr,
+	&sensor_dev_attr_temp2_min.dev_attr.attr,
+	&sensor_dev_attr_temp2_max.dev_attr.attr,
+	&sensor_dev_attr_temp3_input.dev_attr.attr,
+	&sensor_dev_attr_temp3_min.dev_attr.attr,
+	&sensor_dev_attr_temp3_max.dev_attr.attr,
+	&sensor_dev_attr_temp4_input.dev_attr.attr,
+	&sensor_dev_attr_temp4_min.dev_attr.attr,
+	&sensor_dev_attr_temp4_max.dev_attr.attr,
+	&sensor_dev_attr_temp5_input.dev_attr.attr,
+	&sensor_dev_attr_temp5_min.dev_attr.attr,
+	&sensor_dev_attr_temp5_max.dev_attr.attr,
+	&sensor_dev_attr_temp6_input.dev_attr.attr,
+	&sensor_dev_attr_temp6_min.dev_attr.attr,
+	&sensor_dev_attr_temp6_max.dev_attr.attr,
+
+	&sensor_dev_attr_fan1_input.dev_attr.attr,
+	&sensor_dev_attr_fan1_min.dev_attr.attr,
+	&sensor_dev_attr_fan2_input.dev_attr.attr,
+	&sensor_dev_attr_fan2_min.dev_attr.attr,
+	&sensor_dev_attr_fan3_input.dev_attr.attr,
+	&sensor_dev_attr_fan3_min.dev_attr.attr,
+	&sensor_dev_attr_fan4_input.dev_attr.attr,
+	&sensor_dev_attr_fan4_min.dev_attr.attr,
+	&sensor_dev_attr_fan5_input.dev_attr.attr,
+	&sensor_dev_attr_fan5_min.dev_attr.attr,
+	NULL
+};
+
+static const struct attribute_group emc6w201_group = {
+	.attrs = emc6w201_attributes,
+};
+
+/*
+ * Driver interface
+ */
+
+/* Return 0 if detection is successful, -ENODEV otherwise */
+static int emc6w201_detect(struct i2c_client *client,
+			   struct i2c_board_info *info)
+{
+	struct i2c_adapter *adapter = client->adapter;
+	int company, verstep, config;
+
+	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
+		return -ENODEV;
+
+	/* Identification */
+	company = i2c_smbus_read_byte_data(client, EMC6W201_REG_COMPANY);
+	if (company != 0x5C)
+		return -ENODEV;
+	verstep = i2c_smbus_read_byte_data(client, EMC6W201_REG_VERSTEP);
+	if (verstep < 0 || (verstep & 0xF0) != 0xB0)
+		return -ENODEV;
+	if ((verstep & 0x0F) > 2) {
+		dev_dbg(&client->dev, "Unknwown EMC6W201 stepping %d\n",
+			verstep & 0x0F);
+		return -ENODEV;
+	}
+
+	/* Check configuration */
+	config = i2c_smbus_read_byte_data(client, EMC6W201_REG_CONFIG);
+	if (config < 0 || (config & 0xF4) != 0x04)
+		return -ENODEV;
+	if (!(config & 0x01)) {
+		dev_err(&client->dev, "Monitoring not enabled\n");
+		return -ENODEV;
+	}
+
+	strlcpy(info->type, "emc6w201", I2C_NAME_SIZE);
+
+	return 0;
+}
+
+static int emc6w201_probe(struct i2c_client *client,
+			  const struct i2c_device_id *id)
+{
+	struct emc6w201_data *data;
+	int err;
+
+	data = kzalloc(sizeof(struct emc6w201_data), GFP_KERNEL);
+	if (!data) {
+		err = -ENOMEM;
+		goto exit;
+	}
+
+	i2c_set_clientdata(client, data);
+	mutex_init(&data->update_lock);
+
+	/* Create sysfs attribute */
+	err = sysfs_create_group(&client->dev.kobj, &emc6w201_group);
+	if (err)
+		goto exit_free;
+
+	/* Expose as a hwmon device */
+	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, &emc6w201_group);
+ exit_free:
+	kfree(data);
+ exit:
+	return err;
+}
+
+static int emc6w201_remove(struct i2c_client *client)
+{
+	struct emc6w201_data *data = i2c_get_clientdata(client);
+
+	hwmon_device_unregister(data->hwmon_dev);
+	sysfs_remove_group(&client->dev.kobj, &emc6w201_group);
+	kfree(data);
+
+	return 0;
+}
+
+static const struct i2c_device_id emc6w201_id[] = {
+	{ "emc6w201", 0 },
+	{ }
+};
+MODULE_DEVICE_TABLE(i2c, emc6w201_id);
+
+static struct i2c_driver emc6w201_driver = {
+	.class		= I2C_CLASS_HWMON,
+	.driver = {
+		.name	= "emc6w201",
+	},
+	.probe		= emc6w201_probe,
+	.remove		= emc6w201_remove,
+	.id_table	= emc6w201_id,
+	.detect		= emc6w201_detect,
+	.address_list	= normal_i2c,
+};
+
+static int __init sensors_emc6w201_init(void)
+{
+	return i2c_add_driver(&emc6w201_driver);
+}
+module_init(sensors_emc6w201_init);
+
+static void __exit sensors_emc6w201_exit(void)
+{
+	i2c_del_driver(&emc6w201_driver);
+}
+module_exit(sensors_emc6w201_exit);
+
+MODULE_AUTHOR("Jean Delvare <khali@linux-fr.org>");
+MODULE_DESCRIPTION("SMSC EMC6W201 hardware monitoring driver");
+MODULE_LICENSE("GPL");
diff -druN linux-2.6.39-libre/drivers/hwmon/f71882fg.c linux-3.0-rc7-libre/drivers/hwmon/f71882fg.c
--- linux-2.6.39-libre/drivers/hwmon/f71882fg.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/hwmon/f71882fg.c	2011-07-11 19:51:52.000000000 -0400
@@ -48,9 +48,11 @@
 
 #define SIO_FINTEK_ID		0x1934	/* Manufacturers ID */
 #define SIO_F71808E_ID		0x0901	/* Chipset ID */
+#define SIO_F71808A_ID		0x1001	/* Chipset ID */
 #define SIO_F71858_ID		0x0507  /* Chipset ID */
 #define SIO_F71862_ID		0x0601	/* Chipset ID */
 #define SIO_F71869_ID		0x0814	/* Chipset ID */
+#define SIO_F71869A_ID		0x1007	/* Chipset ID */
 #define SIO_F71882_ID		0x0541	/* Chipset ID */
 #define SIO_F71889_ID		0x0723	/* Chipset ID */
 #define SIO_F71889E_ID		0x0909	/* Chipset ID */
@@ -107,14 +109,16 @@
 module_param(force_id, ushort, 0);
 MODULE_PARM_DESC(force_id, "Override the detected device ID");
 
-enum chips { f71808e, f71858fg, f71862fg, f71869, f71882fg, f71889fg,
-	     f71889ed, f71889a, f8000, f81865f };
+enum chips { f71808e, f71808a, f71858fg, f71862fg, f71869, f71869a, f71882fg,
+	     f71889fg, f71889ed, f71889a, f8000, f81865f };
 
 static const char *f71882fg_names[] = {
 	"f71808e",
+	"f71808a",
 	"f71858fg",
 	"f71862fg",
 	"f71869", /* Both f71869f and f71869e, reg. compatible and same id */
+	"f71869a",
 	"f71882fg",
 	"f71889fg", /* f81801u too, same id */
 	"f71889ed",
@@ -125,9 +129,11 @@
 
 static const char f71882fg_has_in[][F71882FG_MAX_INS] = {
 	[f71808e]	= { 1, 1, 1, 1, 1, 1, 0, 1, 1 },
+	[f71808a]	= { 1, 1, 1, 1, 0, 0, 0, 1, 1 },
 	[f71858fg]	= { 1, 1, 1, 0, 0, 0, 0, 0, 0 },
 	[f71862fg]	= { 1, 1, 1, 1, 1, 1, 1, 1, 1 },
 	[f71869]	= { 1, 1, 1, 1, 1, 1, 1, 1, 1 },
+	[f71869a]	= { 1, 1, 1, 1, 1, 1, 1, 1, 1 },
 	[f71882fg]	= { 1, 1, 1, 1, 1, 1, 1, 1, 1 },
 	[f71889fg]	= { 1, 1, 1, 1, 1, 1, 1, 1, 1 },
 	[f71889ed]	= { 1, 1, 1, 1, 1, 1, 1, 1, 1 },
@@ -138,9 +144,11 @@
 
 static const char f71882fg_has_in1_alarm[] = {
 	[f71808e]	= 0,
+	[f71808a]	= 0,
 	[f71858fg]	= 0,
 	[f71862fg]	= 0,
 	[f71869]	= 0,
+	[f71869a]	= 0,
 	[f71882fg]	= 1,
 	[f71889fg]	= 1,
 	[f71889ed]	= 1,
@@ -149,11 +157,13 @@
 	[f81865f]	= 1,
 };
 
-static const char f71882fg_has_beep[] = {
+static const char f71882fg_fan_has_beep[] = {
 	[f71808e]	= 0,
+	[f71808a]	= 0,
 	[f71858fg]	= 0,
 	[f71862fg]	= 1,
 	[f71869]	= 1,
+	[f71869a]	= 1,
 	[f71882fg]	= 1,
 	[f71889fg]	= 1,
 	[f71889ed]	= 1,
@@ -164,22 +174,41 @@
 
 static const char f71882fg_nr_fans[] = {
 	[f71808e]	= 3,
+	[f71808a]	= 2, /* +1 fan which is monitor + simple pwm only */
 	[f71858fg]	= 3,
 	[f71862fg]	= 3,
 	[f71869]	= 3,
+	[f71869a]	= 3,
 	[f71882fg]	= 4,
 	[f71889fg]	= 3,
 	[f71889ed]	= 3,
 	[f71889a]	= 3,
-	[f8000]		= 3,
+	[f8000]		= 3, /* +1 fan which is monitor only */
 	[f81865f]	= 2,
 };
 
+static const char f71882fg_temp_has_beep[] = {
+	[f71808e]	= 0,
+	[f71808a]	= 1,
+	[f71858fg]	= 0,
+	[f71862fg]	= 1,
+	[f71869]	= 1,
+	[f71869a]	= 1,
+	[f71882fg]	= 1,
+	[f71889fg]	= 1,
+	[f71889ed]	= 1,
+	[f71889a]	= 1,
+	[f8000]		= 0,
+	[f81865f]	= 1,
+};
+
 static const char f71882fg_nr_temps[] = {
 	[f71808e]	= 2,
+	[f71808a]	= 2,
 	[f71858fg]	= 3,
 	[f71862fg]	= 3,
 	[f71869]	= 3,
+	[f71869a]	= 3,
 	[f71882fg]	= 3,
 	[f71889fg]	= 3,
 	[f71889ed]	= 3,
@@ -301,6 +330,10 @@
 	char *buf);
 static ssize_t store_pwm(struct device *dev, struct device_attribute *devattr,
 	const char *buf, size_t count);
+static ssize_t show_simple_pwm(struct device *dev,
+	struct device_attribute *devattr, char *buf);
+static ssize_t store_simple_pwm(struct device *dev,
+	struct device_attribute *devattr, const char *buf, size_t count);
 static ssize_t show_pwm_enable(struct device *dev,
 	struct device_attribute *devattr, char *buf);
 static ssize_t store_pwm_enable(struct device *dev,
@@ -550,6 +583,14 @@
 		      show_pwm_interpolate, store_pwm_interpolate, 0, 3),
 } };
 
+/* Attr for the third fan of the f71808a, which only has manual pwm */
+static struct sensor_device_attribute_2 f71808a_fan3_attr[] = {
+	SENSOR_ATTR_2(fan3_input, S_IRUGO, show_fan, NULL, 0, 2),
+	SENSOR_ATTR_2(fan3_alarm, S_IRUGO, show_fan_alarm, NULL, 0, 2),
+	SENSOR_ATTR_2(pwm3, S_IRUGO|S_IWUSR,
+		      show_simple_pwm, store_simple_pwm, 0, 2),
+};
+
 /* Attr for models which can beep on Fan alarm */
 static struct sensor_device_attribute_2 fxxxx_fan_beep_attr[] = {
 	SENSOR_ATTR_2(fan1_beep, S_IRUGO|S_IWUSR, show_fan_beep,
@@ -1146,12 +1187,13 @@
 			data->temp_type[3] = (reg & 0x08) ? 2 : 4;
 		}
 
-		if (f71882fg_has_beep[data->type]) {
+		if (f71882fg_fan_has_beep[data->type])
 			data->fan_beep = f71882fg_read8(data,
 						F71882FG_REG_FAN_BEEP);
+
+		if (f71882fg_temp_has_beep[data->type])
 			data->temp_beep = f71882fg_read8(data,
 						F71882FG_REG_TEMP_BEEP);
-		}
 
 		data->pwm_enable = f71882fg_read8(data,
 						  F71882FG_REG_PWM_ENABLE);
@@ -1232,7 +1274,13 @@
 			data->pwm[nr] =
 			    f71882fg_read8(data, F71882FG_REG_PWM(nr));
 		}
-		/* The f8000 can monitor 1 more fan, but has no pwm for it */
+		/* Some models have 1 more fan with limited capabilities */
+		if (data->type == f71808a) {
+			data->fan[2] = f71882fg_read16(data,
+						F71882FG_REG_FAN(2));
+			data->pwm[2] = f71882fg_read8(data,
+							F71882FG_REG_PWM(2));
+		}
 		if (data->type == f8000)
 			data->fan[3] = f71882fg_read16(data,
 						F71882FG_REG_FAN(3));
@@ -1722,6 +1770,38 @@
 	return count;
 }
 
+static ssize_t show_simple_pwm(struct device *dev,
+			       struct device_attribute *devattr, char *buf)
+{
+	struct f71882fg_data *data = f71882fg_update_device(dev);
+	int val, nr = to_sensor_dev_attr_2(devattr)->index;
+
+	val = data->pwm[nr];
+	return sprintf(buf, "%d\n", val);
+}
+
+static ssize_t store_simple_pwm(struct device *dev,
+				struct device_attribute *devattr,
+				const char *buf, size_t count)
+{
+	struct f71882fg_data *data = dev_get_drvdata(dev);
+	int err, nr = to_sensor_dev_attr_2(devattr)->index;
+	long val;
+
+	err = strict_strtol(buf, 10, &val);
+	if (err)
+		return err;
+
+	val = SENSORS_LIMIT(val, 0, 255);
+
+	mutex_lock(&data->update_lock);
+	f71882fg_write8(data, F71882FG_REG_PWM(nr), val);
+	data->pwm[nr] = val;
+	mutex_unlock(&data->update_lock);
+
+	return count;
+}
+
 static ssize_t show_pwm_enable(struct device *dev,
 			       struct device_attribute *devattr, char *buf)
 {
@@ -2140,7 +2220,7 @@
 		if (err)
 			goto exit_unregister_sysfs;
 
-		if (f71882fg_has_beep[data->type]) {
+		if (f71882fg_temp_has_beep[data->type]) {
 			err = f71882fg_create_sysfs_files(pdev,
 					&fxxxx_temp_beep_attr[0][0],
 					ARRAY_SIZE(fxxxx_temp_beep_attr[0])
@@ -2169,7 +2249,9 @@
 	if (start_reg & 0x02) {
 		switch (data->type) {
 		case f71808e:
+		case f71808a:
 		case f71869:
+		case f71869a:
 			/* These always have signed auto point temps */
 			data->auto_point_temp_signed = 1;
 			/* Fall through to select correct fan/pwm reg bank! */
@@ -2221,7 +2303,7 @@
 		if (err)
 			goto exit_unregister_sysfs;
 
-		if (f71882fg_has_beep[data->type]) {
+		if (f71882fg_fan_has_beep[data->type]) {
 			err = f71882fg_create_sysfs_files(pdev,
 					fxxxx_fan_beep_attr, nr_fans);
 			if (err)
@@ -2230,7 +2312,9 @@
 
 		switch (data->type) {
 		case f71808e:
+		case f71808a:
 		case f71869:
+		case f71869a:
 		case f71889fg:
 		case f71889ed:
 		case f71889a:
@@ -2255,6 +2339,16 @@
 		}
 
 		switch (data->type) {
+		case f71808a:
+			err = f71882fg_create_sysfs_files(pdev,
+				&fxxxx_auto_pwm_attr[0][0],
+				ARRAY_SIZE(fxxxx_auto_pwm_attr[0]) * nr_fans);
+			if (err)
+				goto exit_unregister_sysfs;
+			err = f71882fg_create_sysfs_files(pdev,
+					f71808a_fan3_attr,
+					ARRAY_SIZE(f71808a_fan3_attr));
+			break;
 		case f71862fg:
 			err = f71882fg_create_sysfs_files(pdev,
 					f71862fg_auto_pwm_attr,
@@ -2343,7 +2437,7 @@
 				&fxxxx_temp_attr[0][0],
 				ARRAY_SIZE(fxxxx_temp_attr[0]) * nr_temps);
 		}
-		if (f71882fg_has_beep[data->type]) {
+		if (f71882fg_temp_has_beep[data->type]) {
 			f71882fg_remove_sysfs_files(pdev,
 			       &fxxxx_temp_beep_attr[0][0],
 			       ARRAY_SIZE(fxxxx_temp_beep_attr[0]) * nr_temps);
@@ -2366,12 +2460,20 @@
 		f71882fg_remove_sysfs_files(pdev, &fxxxx_fan_attr[0][0],
 				ARRAY_SIZE(fxxxx_fan_attr[0]) * nr_fans);
 
-		if (f71882fg_has_beep[data->type]) {
+		if (f71882fg_fan_has_beep[data->type]) {
 			f71882fg_remove_sysfs_files(pdev,
 					fxxxx_fan_beep_attr, nr_fans);
 		}
 
 		switch (data->type) {
+		case f71808a:
+			f71882fg_remove_sysfs_files(pdev,
+				&fxxxx_auto_pwm_attr[0][0],
+				ARRAY_SIZE(fxxxx_auto_pwm_attr[0]) * nr_fans);
+			f71882fg_remove_sysfs_files(pdev,
+					f71808a_fan3_attr,
+					ARRAY_SIZE(f71808a_fan3_attr));
+			break;
 		case f71862fg:
 			f71882fg_remove_sysfs_files(pdev,
 					f71862fg_auto_pwm_attr,
@@ -2424,6 +2526,9 @@
 	case SIO_F71808E_ID:
 		sio_data->type = f71808e;
 		break;
+	case SIO_F71808A_ID:
+		sio_data->type = f71808a;
+		break;
 	case SIO_F71858_ID:
 		sio_data->type = f71858fg;
 		break;
@@ -2433,6 +2538,9 @@
 	case SIO_F71869_ID:
 		sio_data->type = f71869;
 		break;
+	case SIO_F71869A_ID:
+		sio_data->type = f71869a;
+		break;
 	case SIO_F71882_ID:
 		sio_data->type = f71882fg;
 		break;
@@ -2567,7 +2675,7 @@
 }
 
 MODULE_DESCRIPTION("F71882FG Hardware Monitoring Driver");
-MODULE_AUTHOR("Hans Edgington, Hans de Goede (hdegoede@redhat.com)");
+MODULE_AUTHOR("Hans Edgington, Hans de Goede <hdegoede@redhat.com>");
 MODULE_LICENSE("GPL");
 
 module_init(f71882fg_init);
diff -druN linux-2.6.39-libre/drivers/hwmon/fam15h_power.c linux-3.0-rc7-libre/drivers/hwmon/fam15h_power.c
--- linux-2.6.39-libre/drivers/hwmon/fam15h_power.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/hwmon/fam15h_power.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,229 @@
+/*
+ * fam15h_power.c - AMD Family 15h processor power monitoring
+ *
+ * Copyright (c) 2011 Advanced Micro Devices, Inc.
+ * Author: Andreas Herrmann <andreas.herrmann3@amd.com>
+ *
+ *
+ * This driver is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This driver is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this driver; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/err.h>
+#include <linux/hwmon.h>
+#include <linux/hwmon-sysfs.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/bitops.h>
+#include <asm/processor.h>
+
+MODULE_DESCRIPTION("AMD Family 15h CPU processor power monitor");
+MODULE_AUTHOR("Andreas Herrmann <andreas.herrmann3@amd.com>");
+MODULE_LICENSE("GPL");
+
+/* D18F3 */
+#define REG_NORTHBRIDGE_CAP		0xe8
+
+/* D18F4 */
+#define REG_PROCESSOR_TDP		0x1b8
+
+/* D18F5 */
+#define REG_TDP_RUNNING_AVERAGE		0xe0
+#define REG_TDP_LIMIT3			0xe8
+
+struct fam15h_power_data {
+	struct device *hwmon_dev;
+	unsigned int tdp_to_watts;
+	unsigned int base_tdp;
+	unsigned int processor_pwr_watts;
+};
+
+static ssize_t show_power(struct device *dev,
+			  struct device_attribute *attr, char *buf)
+{
+	u32 val, tdp_limit, running_avg_range;
+	s32 running_avg_capture;
+	u64 curr_pwr_watts;
+	struct pci_dev *f4 = to_pci_dev(dev);
+	struct fam15h_power_data *data = dev_get_drvdata(dev);
+
+	pci_bus_read_config_dword(f4->bus, PCI_DEVFN(PCI_SLOT(f4->devfn), 5),
+				  REG_TDP_RUNNING_AVERAGE, &val);
+	running_avg_capture = (val >> 4) & 0x3fffff;
+	running_avg_capture = sign_extend32(running_avg_capture, 22);
+	running_avg_range = val & 0xf;
+
+	pci_bus_read_config_dword(f4->bus, PCI_DEVFN(PCI_SLOT(f4->devfn), 5),
+				  REG_TDP_LIMIT3, &val);
+
+	tdp_limit = val >> 16;
+	curr_pwr_watts = tdp_limit + data->base_tdp -
+		(s32)(running_avg_capture >> (running_avg_range + 1));
+	curr_pwr_watts *= data->tdp_to_watts;
+
+	/*
+	 * Convert to microWatt
+	 *
+	 * power is in Watt provided as fixed point integer with
+	 * scaling factor 1/(2^16).  For conversion we use
+	 * (10^6)/(2^16) = 15625/(2^10)
+	 */
+	curr_pwr_watts = (curr_pwr_watts * 15625) >> 10;
+	return sprintf(buf, "%u\n", (unsigned int) curr_pwr_watts);
+}
+static DEVICE_ATTR(power1_input, S_IRUGO, show_power, NULL);
+
+static ssize_t show_power_crit(struct device *dev,
+			       struct device_attribute *attr, char *buf)
+{
+	struct fam15h_power_data *data = dev_get_drvdata(dev);
+
+	return sprintf(buf, "%u\n", data->processor_pwr_watts);
+}
+static DEVICE_ATTR(power1_crit, S_IRUGO, show_power_crit, NULL);
+
+static ssize_t show_name(struct device *dev,
+			 struct device_attribute *attr, char *buf)
+{
+	return sprintf(buf, "fam15h_power\n");
+}
+static DEVICE_ATTR(name, S_IRUGO, show_name, NULL);
+
+static struct attribute *fam15h_power_attrs[] = {
+	&dev_attr_power1_input.attr,
+	&dev_attr_power1_crit.attr,
+	&dev_attr_name.attr,
+	NULL
+};
+
+static const struct attribute_group fam15h_power_attr_group = {
+	.attrs	= fam15h_power_attrs,
+};
+
+static bool __devinit fam15h_power_is_internal_node0(struct pci_dev *f4)
+{
+	u32 val;
+
+	pci_bus_read_config_dword(f4->bus, PCI_DEVFN(PCI_SLOT(f4->devfn), 3),
+				  REG_NORTHBRIDGE_CAP, &val);
+	if ((val & BIT(29)) && ((val >> 30) & 3))
+		return false;
+
+	return true;
+}
+
+static void __devinit fam15h_power_init_data(struct pci_dev *f4,
+					     struct fam15h_power_data *data)
+{
+	u32 val;
+	u64 tmp;
+
+	pci_read_config_dword(f4, REG_PROCESSOR_TDP, &val);
+	data->base_tdp = val >> 16;
+	tmp = val & 0xffff;
+
+	pci_bus_read_config_dword(f4->bus, PCI_DEVFN(PCI_SLOT(f4->devfn), 5),
+				  REG_TDP_LIMIT3, &val);
+
+	data->tdp_to_watts = ((val & 0x3ff) << 6) | ((val >> 10) & 0x3f);
+	tmp *= data->tdp_to_watts;
+
+	/* result not allowed to be >= 256W */
+	if ((tmp >> 16) >= 256)
+		dev_warn(&f4->dev, "Bogus value for ProcessorPwrWatts "
+			 "(processor_pwr_watts>=%u)\n",
+			 (unsigned int) (tmp >> 16));
+
+	/* convert to microWatt */
+	data->processor_pwr_watts = (tmp * 15625) >> 10;
+}
+
+static int __devinit fam15h_power_probe(struct pci_dev *pdev,
+					const struct pci_device_id *id)
+{
+	struct fam15h_power_data *data;
+	struct device *dev;
+	int err;
+
+	if (!fam15h_power_is_internal_node0(pdev)) {
+		err = -ENODEV;
+		goto exit;
+	}
+
+	data = kzalloc(sizeof(struct fam15h_power_data), GFP_KERNEL);
+	if (!data) {
+		err = -ENOMEM;
+		goto exit;
+	}
+	fam15h_power_init_data(pdev, data);
+	dev = &pdev->dev;
+
+	dev_set_drvdata(dev, data);
+	err = sysfs_create_group(&dev->kobj, &fam15h_power_attr_group);
+	if (err)
+		goto exit_free_data;
+
+	data->hwmon_dev = hwmon_device_register(dev);
+	if (IS_ERR(data->hwmon_dev)) {
+		err = PTR_ERR(data->hwmon_dev);
+		goto exit_remove_group;
+	}
+
+	return 0;
+
+exit_remove_group:
+	sysfs_remove_group(&dev->kobj, &fam15h_power_attr_group);
+exit_free_data:
+	kfree(data);
+exit:
+	return err;
+}
+
+static void __devexit fam15h_power_remove(struct pci_dev *pdev)
+{
+	struct device *dev;
+	struct fam15h_power_data *data;
+
+	dev = &pdev->dev;
+	data = dev_get_drvdata(dev);
+	hwmon_device_unregister(data->hwmon_dev);
+	sysfs_remove_group(&dev->kobj, &fam15h_power_attr_group);
+	dev_set_drvdata(dev, NULL);
+	kfree(data);
+}
+
+static DEFINE_PCI_DEVICE_TABLE(fam15h_power_id_table) = {
+	{ PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_15H_NB_F4) },
+	{}
+};
+MODULE_DEVICE_TABLE(pci, fam15h_power_id_table);
+
+static struct pci_driver fam15h_power_driver = {
+	.name = "fam15h_power",
+	.id_table = fam15h_power_id_table,
+	.probe = fam15h_power_probe,
+	.remove = __devexit_p(fam15h_power_remove),
+};
+
+static int __init fam15h_power_init(void)
+{
+	return pci_register_driver(&fam15h_power_driver);
+}
+
+static void __exit fam15h_power_exit(void)
+{
+	pci_unregister_driver(&fam15h_power_driver);
+}
+
+module_init(fam15h_power_init)
+module_exit(fam15h_power_exit)
diff -druN linux-2.6.39-libre/drivers/hwmon/hwmon-vid.c linux-3.0-rc7-libre/drivers/hwmon/hwmon-vid.c
--- linux-2.6.39-libre/drivers/hwmon/hwmon-vid.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/hwmon/hwmon-vid.c	2011-07-11 19:51:52.000000000 -0400
@@ -202,7 +202,7 @@
 
 	{X86_VENDOR_CENTAUR, 0x6, 0x7, ANY, 85},	/* Eden ESP/Ezra */
 	{X86_VENDOR_CENTAUR, 0x6, 0x8, 0x7, 85},	/* Ezra T */
-	{X86_VENDOR_CENTAUR, 0x6, 0x9, 0x7, 85},	/* Nemiah */
+	{X86_VENDOR_CENTAUR, 0x6, 0x9, 0x7, 85},	/* Nehemiah */
 	{X86_VENDOR_CENTAUR, 0x6, 0x9, ANY, 17},	/* C3-M, Eden-N */
 	{X86_VENDOR_CENTAUR, 0x6, 0xA, 0x7, 0},		/* No information */
 	{X86_VENDOR_CENTAUR, 0x6, 0xA, ANY, 13},	/* C7, Esther */
diff -druN linux-2.6.39-libre/drivers/hwmon/ibmaem.c linux-3.0-rc7-libre/drivers/hwmon/ibmaem.c
--- linux-2.6.39-libre/drivers/hwmon/ibmaem.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/hwmon/ibmaem.c	2011-07-11 19:51:52.000000000 -0400
@@ -523,7 +523,7 @@
 	aem_remove_sensors(data);
 	hwmon_device_unregister(data->hwmon_dev);
 	ipmi_destroy_user(data->ipmi.user);
-	dev_set_drvdata(&data->pdev->dev, NULL);
+	platform_set_drvdata(data->pdev, NULL);
 	platform_device_unregister(data->pdev);
 	aem_idr_put(data->id);
 	kfree(data);
@@ -594,7 +594,7 @@
 	if (res)
 		goto ipmi_err;
 
-	dev_set_drvdata(&data->pdev->dev, data);
+	platform_set_drvdata(data->pdev, data);
 
 	/* Set up IPMI interface */
 	if (aem_init_ipmi_data(&data->ipmi, probe->interface,
@@ -630,7 +630,7 @@
 hwmon_reg_err:
 	ipmi_destroy_user(data->ipmi.user);
 ipmi_err:
-	dev_set_drvdata(&data->pdev->dev, NULL);
+	platform_set_drvdata(data->pdev, NULL);
 	platform_device_unregister(data->pdev);
 dev_err:
 	aem_idr_put(data->id);
@@ -727,7 +727,7 @@
 	if (res)
 		goto ipmi_err;
 
-	dev_set_drvdata(&data->pdev->dev, data);
+	platform_set_drvdata(data->pdev, data);
 
 	/* Set up IPMI interface */
 	if (aem_init_ipmi_data(&data->ipmi, probe->interface,
@@ -763,7 +763,7 @@
 hwmon_reg_err:
 	ipmi_destroy_user(data->ipmi.user);
 ipmi_err:
-	dev_set_drvdata(&data->pdev->dev, NULL);
+	platform_set_drvdata(data->pdev, NULL);
 	platform_device_unregister(data->pdev);
 dev_err:
 	aem_idr_put(data->id);
@@ -947,6 +947,7 @@
 
 	/* Set up read-only sensors */
 	while (ro->label) {
+		sysfs_attr_init(&sensors->dev_attr.attr);
 		sensors->dev_attr.attr.name = ro->label;
 		sensors->dev_attr.attr.mode = S_IRUGO;
 		sensors->dev_attr.show = ro->show;
@@ -963,6 +964,7 @@
 
 	/* Set up read-write sensors */
 	while (rw->label) {
+		sysfs_attr_init(&sensors->dev_attr.attr);
 		sensors->dev_attr.attr.name = rw->label;
 		sensors->dev_attr.attr.mode = S_IRUGO | S_IWUSR;
 		sensors->dev_attr.show = rw->show;
diff -druN linux-2.6.39-libre/drivers/hwmon/ibmpex.c linux-3.0-rc7-libre/drivers/hwmon/ibmpex.c
--- linux-2.6.39-libre/drivers/hwmon/ibmpex.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/hwmon/ibmpex.c	2011-07-11 19:51:52.000000000 -0400
@@ -358,6 +358,7 @@
 	else if (type == POWER_SENSOR)
 		sprintf(n, power_sensor_name_templates[func], "power", counter);
 
+	sysfs_attr_init(&data->sensors[sensor].attr[func].dev_attr.attr);
 	data->sensors[sensor].attr[func].dev_attr.attr.name = n;
 	data->sensors[sensor].attr[func].dev_attr.attr.mode = S_IRUGO;
 	data->sensors[sensor].attr[func].dev_attr.show = ibmpex_show_sensor;
diff -druN linux-2.6.39-libre/drivers/hwmon/it87.c linux-3.0-rc7-libre/drivers/hwmon/it87.c
--- linux-2.6.39-libre/drivers/hwmon/it87.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/hwmon/it87.c	2011-07-11 19:51:52.000000000 -0400
@@ -77,15 +77,13 @@
 #define	DEVID	0x20	/* Register: Device ID */
 #define	DEVREV	0x22	/* Register: Device Revision */
 
-static inline int
-superio_inb(int reg)
+static inline int superio_inb(int reg)
 {
 	outb(reg, REG);
 	return inb(VAL);
 }
 
-static inline void
-superio_outb(int reg, int val)
+static inline void superio_outb(int reg, int val)
 {
 	outb(reg, REG);
 	outb(val, VAL);
@@ -101,27 +99,32 @@
 	return val;
 }
 
-static inline void
-superio_select(int ldn)
+static inline void superio_select(int ldn)
 {
 	outb(DEV, REG);
 	outb(ldn, VAL);
 }
 
-static inline void
-superio_enter(void)
+static inline int superio_enter(void)
 {
+	/*
+	 * Try to reserve REG and REG + 1 for exclusive access.
+	 */
+	if (!request_muxed_region(REG, 2, DRVNAME))
+		return -EBUSY;
+
 	outb(0x87, REG);
 	outb(0x01, REG);
 	outb(0x55, REG);
 	outb(0x55, REG);
+	return 0;
 }
 
-static inline void
-superio_exit(void)
+static inline void superio_exit(void)
 {
 	outb(0x02, REG);
 	outb(0x02, VAL);
+	release_region(REG, 2);
 }
 
 /* Logical device 4 registers */
@@ -1542,11 +1545,15 @@
 static int __init it87_find(unsigned short *address,
 	struct it87_sio_data *sio_data)
 {
-	int err = -ENODEV;
+	int err;
 	u16 chip_type;
 	const char *board_vendor, *board_name;
 
-	superio_enter();
+	err = superio_enter();
+	if (err)
+		return err;
+
+	err = -ENODEV;
 	chip_type = force_id ? force_id : superio_inw(DEVID);
 
 	switch (chip_type) {
diff -druN linux-2.6.39-libre/drivers/hwmon/jc42.c linux-3.0-rc7-libre/drivers/hwmon/jc42.c
--- linux-2.6.39-libre/drivers/hwmon/jc42.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/hwmon/jc42.c	2011-07-11 19:51:52.000000000 -0400
@@ -213,7 +213,7 @@
 
 /* This is the driver that will be inserted */
 static struct i2c_driver jc42_driver = {
-	.class		= I2C_CLASS_HWMON,
+	.class		= I2C_CLASS_SPD,
 	.driver = {
 		.name	= "jc42",
 		.pm = JC42_DEV_PM_OPS,
diff -druN linux-2.6.39-libre/drivers/hwmon/k10temp.c linux-3.0-rc7-libre/drivers/hwmon/k10temp.c
--- linux-2.6.39-libre/drivers/hwmon/k10temp.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/hwmon/k10temp.c	2011-07-11 19:51:52.000000000 -0400
@@ -1,5 +1,5 @@
 /*
- * k10temp.c - AMD Family 10h/11h/12h/14h processor hardware monitoring
+ * k10temp.c - AMD Family 10h/11h/12h/14h/15h processor hardware monitoring
  *
  * Copyright (c) 2009 Clemens Ladisch <clemens@ladisch.de>
  *
@@ -25,7 +25,7 @@
 #include <linux/pci.h>
 #include <asm/processor.h>
 
-MODULE_DESCRIPTION("AMD Family 10h/11h/12h/14h CPU core temperature monitor");
+MODULE_DESCRIPTION("AMD Family 10h+ CPU core temperature monitor");
 MODULE_AUTHOR("Clemens Ladisch <clemens@ladisch.de>");
 MODULE_LICENSE("GPL");
 
@@ -173,7 +173,7 @@
 		err = PTR_ERR(hwmon_dev);
 		goto exit_remove;
 	}
-	dev_set_drvdata(&pdev->dev, hwmon_dev);
+	pci_set_drvdata(pdev, hwmon_dev);
 
 	if (unreliable && force)
 		dev_warn(&pdev->dev,
@@ -194,7 +194,7 @@
 
 static void __devexit k10temp_remove(struct pci_dev *pdev)
 {
-	hwmon_device_unregister(dev_get_drvdata(&pdev->dev));
+	hwmon_device_unregister(pci_get_drvdata(pdev));
 	device_remove_file(&pdev->dev, &dev_attr_name);
 	device_remove_file(&pdev->dev, &dev_attr_temp1_input);
 	device_remove_file(&pdev->dev, &dev_attr_temp1_max);
@@ -202,13 +202,14 @@
 			   &sensor_dev_attr_temp1_crit.dev_attr);
 	device_remove_file(&pdev->dev,
 			   &sensor_dev_attr_temp1_crit_hyst.dev_attr);
-	dev_set_drvdata(&pdev->dev, NULL);
+	pci_set_drvdata(pdev, NULL);
 }
 
 static const struct pci_device_id k10temp_id_table[] = {
 	{ PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_10H_NB_MISC) },
 	{ PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_11H_NB_MISC) },
 	{ PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_CNB17H_F3) },
+	{ PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_15H_NB_F3) },
 	{}
 };
 MODULE_DEVICE_TABLE(pci, k10temp_id_table);
diff -druN linux-2.6.39-libre/drivers/hwmon/k8temp.c linux-3.0-rc7-libre/drivers/hwmon/k8temp.c
--- linux-2.6.39-libre/drivers/hwmon/k8temp.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/hwmon/k8temp.c	2011-07-11 19:51:52.000000000 -0400
@@ -252,7 +252,7 @@
 
 	data->name = "k8temp";
 	mutex_init(&data->update_lock);
-	dev_set_drvdata(&pdev->dev, data);
+	pci_set_drvdata(pdev, data);
 
 	/* Register sysfs hooks */
 	err = device_create_file(&pdev->dev,
@@ -307,7 +307,7 @@
 			   &sensor_dev_attr_temp4_input.dev_attr);
 	device_remove_file(&pdev->dev, &dev_attr_name);
 exit_free:
-	dev_set_drvdata(&pdev->dev, NULL);
+	pci_set_drvdata(pdev, NULL);
 	kfree(data);
 exit:
 	return err;
@@ -315,7 +315,7 @@
 
 static void __devexit k8temp_remove(struct pci_dev *pdev)
 {
-	struct k8temp_data *data = dev_get_drvdata(&pdev->dev);
+	struct k8temp_data *data = pci_get_drvdata(pdev);
 
 	hwmon_device_unregister(data->hwmon_dev);
 	device_remove_file(&pdev->dev,
@@ -327,7 +327,7 @@
 	device_remove_file(&pdev->dev,
 			   &sensor_dev_attr_temp4_input.dev_attr);
 	device_remove_file(&pdev->dev, &dev_attr_name);
-	dev_set_drvdata(&pdev->dev, NULL);
+	pci_set_drvdata(pdev, NULL);
 	kfree(data);
 }
 
diff -druN linux-2.6.39-libre/drivers/hwmon/Kconfig linux-3.0-rc7-libre/drivers/hwmon/Kconfig
--- linux-2.6.39-libre/drivers/hwmon/Kconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/hwmon/Kconfig	2011-07-11 19:51:52.000000000 -0400
@@ -41,7 +41,7 @@
 
 config SENSORS_ABITUGURU
 	tristate "Abit uGuru (rev 1 & 2)"
-	depends on X86 && EXPERIMENTAL
+	depends on X86 && DMI && EXPERIMENTAL
 	help
 	  If you say yes here you get support for the sensor part of the first
 	  and second revision of the Abit uGuru chip. The voltage and frequency
@@ -56,7 +56,7 @@
 
 config SENSORS_ABITUGURU3
 	tristate "Abit uGuru (rev 3)"
-	depends on X86 && EXPERIMENTAL
+	depends on X86 && DMI && EXPERIMENTAL
 	help
 	  If you say yes here you get support for the sensor part of the
 	  third revision of the Abit uGuru chip. Only reading the sensors
@@ -213,7 +213,7 @@
 
 config SENSORS_ASC7621
 	tristate "Andigilog aSC7621"
-	depends on HWMON && I2C
+	depends on 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,
@@ -237,17 +237,27 @@
 	  will be called k8temp.
 
 config SENSORS_K10TEMP
-	tristate "AMD Family 10h/11h/12h/14h temperature sensor"
+	tristate "AMD Family 10h+ temperature sensor"
 	depends on X86 && PCI
 	help
 	  If you say yes here you get support for the temperature
 	  sensor(s) inside your CPU. Supported are later revisions of
 	  the AMD Family 10h and all revisions of the AMD Family 11h,
-	  12h (Llano), and 14h (Brazos) microarchitectures.
+	  12h (Llano), 14h (Brazos) and 15h (Bulldozer) microarchitectures.
 
 	  This driver can also be built as a module.  If so, the module
 	  will be called k10temp.
 
+config SENSORS_FAM15H_POWER
+	tristate "AMD Family 15h processor power"
+	depends on X86 && PCI
+	help
+	  If you say yes here you get support for processor power
+	  information of your AMD family 15h CPU.
+
+	  This driver can also be built as a module.  If so, the module
+	  will be called fam15h_power.
+
 config SENSORS_ASB100
 	tristate "Asus ASB100 Bach"
 	depends on X86 && I2C && EXPERIMENTAL
@@ -319,11 +329,11 @@
 	  If you say yes here you get support for hardware monitoring
 	  features of many Fintek Super-I/O (LPC) chips. The currently
 	  supported chips are:
-	    F71808E
+	    F71808E/A
 	    F71858FG
 	    F71862FG
 	    F71863FG
-	    F71869F/E
+	    F71869F/E/A
 	    F71882FG
 	    F71883FG
 	    F71889FG/ED/A
@@ -408,13 +418,6 @@
 	  sensor inside your CPU. Most of the family 6 CPUs
 	  are supported. Check Documentation/hwmon/coretemp for details.
 
-config SENSORS_PKGTEMP
-	tristate "Intel processor package temperature sensor"
-	depends on X86 && EXPERIMENTAL
-	help
-	  If you say yes here you get support for the package level temperature
-	  sensor inside your CPU. Check documentation/driver for details.
-
 config SENSORS_IBMAEM
 	tristate "IBM Active Energy Manager temperature/power sensors and control"
 	select IPMI_SI
@@ -708,6 +711,22 @@
 	  This driver can also be built as a module.  If so, the module
 	  will be called max1111.
 
+config SENSORS_MAX16065
+	tristate "Maxim MAX16065 System Manager and compatibles"
+	depends on I2C
+	help
+	  If you say yes here you get support for hardware monitoring
+	  capabilities of the following Maxim System Manager chips.
+	    MAX16065
+	    MAX16066
+	    MAX16067
+	    MAX16068
+	    MAX16070
+	    MAX16071
+
+	  This driver can also be built as a module.  If so, the module
+	  will be called max16065.
+
 config SENSORS_MAX1619
 	tristate "Maxim MAX1619 sensor chip"
 	depends on I2C
@@ -727,6 +746,17 @@
 	  This driver can also be built as a module.  If so, the module
 	  will be called max6639.
 
+config SENSORS_MAX6642
+	tristate "Maxim MAX6642 sensor chip"
+	depends on I2C && EXPERIMENTAL
+	help
+	  If you say yes here you get support for MAX6642 sensor chip.
+	  MAX6642 is a SMBus-Compatible Remote/Local Temperature Sensor
+	  with Overtemperature Alarm from Maxim.
+
+	  This driver can also be built as a module.  If so, the module
+	  will be called max6642.
+
 config SENSORS_MAX6650
 	tristate "Maxim MAX6650 sensor chip"
 	depends on I2C && EXPERIMENTAL
@@ -800,6 +830,16 @@
 	  This driver can also be built as a module. If so, the module will
 	  be called pmbus.
 
+config SENSORS_ADM1275
+	tristate "Analog Devices ADM1275"
+	default n
+	help
+	  If you say yes here you get hardware monitoring support for Analog
+	  Devices ADM1275 Hot-Swap Controller and Digital Power Monitor.
+
+	  This driver can also be built as a module. If so, the module will
+	  be called adm1275.
+
 config SENSORS_MAX16064
 	tristate "Maxim MAX16064"
 	default n
@@ -830,6 +870,28 @@
 	  This driver can also be built as a module. If so, the module will
 	  be called max8688.
 
+config SENSORS_UCD9000
+	tristate "TI UCD90120, UCD90124, UCD9090, UCD90910"
+	default n
+	help
+	  If you say yes here you get hardware monitoring support for TI
+	  UCD90120, UCD90124, UCD9090, UCD90910 Sequencer and System Health
+	  Controllers.
+
+	  This driver can also be built as a module. If so, the module will
+	  be called ucd9000.
+
+config SENSORS_UCD9200
+	tristate "TI UCD9220, UCD9222, UCD9224, UCD9240, UCD9244, UCD9246, UCD9248"
+	default n
+	help
+	  If you say yes here you get hardware monitoring support for TI
+	  UCD9220, UCD9222, UCD9224, UCD9240, UCD9244, UCD9246, and UCD9248
+	  Digital PWM System Controllers.
+
+	  This driver can also be built as a module. If so, the module will
+	  be called ucd9200.
+
 endif # PMBUS
 
 config SENSORS_SHT15
@@ -926,6 +988,16 @@
 	  This driver can also be built as a module.  If so, the module
 	  will be called emc2103.
 
+config SENSORS_EMC6W201
+	tristate "SMSC EMC6W201"
+	depends on I2C
+	help
+	  If you say yes here you get support for the SMSC EMC6W201
+	  hardware monitoring chip.
+
+	  This driver can also be built as a module.  If so, the module
+	  will be called emc6w201.
+
 config SENSORS_SMSC47M1
 	tristate "SMSC LPC47M10x and compatibles"
 	help
@@ -1289,6 +1361,16 @@
 
 comment "ACPI drivers"
 
+config SENSORS_ACPI_POWER
+	tristate "ACPI 4.0 power meter"
+	help
+	  This driver exposes ACPI 4.0 power meters as hardware monitoring
+	  devices.  Say Y (or M) if you have a computer with ACPI 4.0 firmware
+	  and a power meter.
+
+	  To compile this driver as a module, choose M here:
+	  the module will be called acpi_power_meter.
+
 config SENSORS_ATK0110
 	tristate "ASUS ATK0110"
 	depends on X86 && EXPERIMENTAL
diff -druN linux-2.6.39-libre/drivers/hwmon/lm70.c linux-3.0-rc7-libre/drivers/hwmon/lm70.c
--- linux-2.6.39-libre/drivers/hwmon/lm70.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/hwmon/lm70.c	2011-07-11 19:51:52.000000000 -0400
@@ -58,7 +58,7 @@
 	int status, val = 0;
 	u8 rxbuf[2];
 	s16 raw=0;
-	struct lm70 *p_lm70 = dev_get_drvdata(&spi->dev);
+	struct lm70 *p_lm70 = spi_get_drvdata(spi);
 
 	if (mutex_lock_interruptible(&p_lm70->lock))
 		return -ERESTARTSYS;
@@ -163,7 +163,7 @@
 		status = PTR_ERR(p_lm70->hwmon_dev);
 		goto out_dev_reg_failed;
 	}
-	dev_set_drvdata(&spi->dev, p_lm70);
+	spi_set_drvdata(spi, p_lm70);
 
 	if ((status = device_create_file(&spi->dev, &dev_attr_temp1_input))
 	 || (status = device_create_file(&spi->dev, &dev_attr_name))) {
@@ -177,19 +177,19 @@
 	device_remove_file(&spi->dev, &dev_attr_temp1_input);
 	hwmon_device_unregister(p_lm70->hwmon_dev);
 out_dev_reg_failed:
-	dev_set_drvdata(&spi->dev, NULL);
+	spi_set_drvdata(spi, NULL);
 	kfree(p_lm70);
 	return status;
 }
 
 static int __devexit lm70_remove(struct spi_device *spi)
 {
-	struct lm70 *p_lm70 = dev_get_drvdata(&spi->dev);
+	struct lm70 *p_lm70 = spi_get_drvdata(spi);
 
 	device_remove_file(&spi->dev, &dev_attr_temp1_input);
 	device_remove_file(&spi->dev, &dev_attr_name);
 	hwmon_device_unregister(p_lm70->hwmon_dev);
-	dev_set_drvdata(&spi->dev, NULL);
+	spi_set_drvdata(spi, NULL);
 	kfree(p_lm70);
 
 	return 0;
diff -druN linux-2.6.39-libre/drivers/hwmon/lm95241.c linux-3.0-rc7-libre/drivers/hwmon/lm95241.c
--- linux-2.6.39-libre/drivers/hwmon/lm95241.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/hwmon/lm95241.c	2011-07-11 19:51:52.000000000 -0400
@@ -98,11 +98,16 @@
 };
 
 /* Conversions */
-static int TempFromReg(u8 val_h, u8 val_l)
+static int temp_from_reg_signed(u8 val_h, u8 val_l)
 {
-	if (val_h & 0x80)
-		return val_h - 0x100;
-	return val_h * 1000 + val_l * 1000 / 256;
+	s16 val_hl = (val_h << 8) | val_l;
+	return val_hl * 1000 / 256;
+}
+
+static int temp_from_reg_unsigned(u8 val_h, u8 val_l)
+{
+	u16 val_hl = (val_h << 8) | val_l;
+	return val_hl * 1000 / 256;
 }
 
 static struct lm95241_data *lm95241_update_device(struct device *dev)
@@ -135,10 +140,13 @@
 			  char *buf)
 {
 	struct lm95241_data *data = lm95241_update_device(dev);
+	int index = to_sensor_dev_attr(attr)->index;
 
 	return snprintf(buf, PAGE_SIZE - 1, "%d\n",
-		TempFromReg(data->temp[to_sensor_dev_attr(attr)->index],
-			    data->temp[to_sensor_dev_attr(attr)->index + 1]));
+			index == 0 || (data->config & (1 << (index / 2))) ?
+		temp_from_reg_signed(data->temp[index], data->temp[index + 1]) :
+		temp_from_reg_unsigned(data->temp[index],
+				       data->temp[index + 1]));
 }
 
 static ssize_t show_type(struct device *dev, struct device_attribute *attr,
@@ -339,7 +347,7 @@
 	if ((i2c_smbus_read_byte_data(new_client, LM95241_REG_R_MAN_ID)
 	     == MANUFACTURER_ID)
 	    && (i2c_smbus_read_byte_data(new_client, LM95241_REG_R_CHIP_ID)
-		>= DEFAULT_REVISION)) {
+		== DEFAULT_REVISION)) {
 		name = DEVNAME;
 	} else {
 		dev_dbg(&adapter->dev, "LM95241 detection failed at 0x%02x\n",
diff -druN linux-2.6.39-libre/drivers/hwmon/Makefile linux-3.0-rc7-libre/drivers/hwmon/Makefile
--- linux-2.6.39-libre/drivers/hwmon/Makefile	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/hwmon/Makefile	2011-07-11 19:51:52.000000000 -0400
@@ -6,6 +6,7 @@
 obj-$(CONFIG_HWMON_VID)		+= hwmon-vid.o
 
 # APCI drivers
+obj-$(CONFIG_SENSORS_ACPI_POWER) += acpi_power_meter.o
 obj-$(CONFIG_SENSORS_ATK0110)	+= asus_atk0110.o
 
 # Native drivers
@@ -40,15 +41,16 @@
 obj-$(CONFIG_SENSORS_ASC7621)	+= asc7621.o
 obj-$(CONFIG_SENSORS_ATXP1)	+= atxp1.o
 obj-$(CONFIG_SENSORS_CORETEMP)	+= coretemp.o
-obj-$(CONFIG_SENSORS_PKGTEMP)	+= pkgtemp.o
 obj-$(CONFIG_SENSORS_DME1737)	+= dme1737.o
 obj-$(CONFIG_SENSORS_DS620)	+= ds620.o
 obj-$(CONFIG_SENSORS_DS1621)	+= ds1621.o
 obj-$(CONFIG_SENSORS_EMC1403)	+= emc1403.o
 obj-$(CONFIG_SENSORS_EMC2103)	+= emc2103.o
+obj-$(CONFIG_SENSORS_EMC6W201)	+= emc6w201.o
 obj-$(CONFIG_SENSORS_F71805F)	+= f71805f.o
 obj-$(CONFIG_SENSORS_F71882FG)	+= f71882fg.o
 obj-$(CONFIG_SENSORS_F75375S)	+= f75375s.o
+obj-$(CONFIG_SENSORS_FAM15H_POWER) += fam15h_power.o
 obj-$(CONFIG_SENSORS_FSCHMD)	+= fschmd.o
 obj-$(CONFIG_SENSORS_G760A)	+= g760a.o
 obj-$(CONFIG_SENSORS_GL518SM)	+= gl518sm.o
@@ -83,8 +85,10 @@
 obj-$(CONFIG_SENSORS_LTC4245)	+= ltc4245.o
 obj-$(CONFIG_SENSORS_LTC4261)	+= ltc4261.o
 obj-$(CONFIG_SENSORS_MAX1111)	+= max1111.o
+obj-$(CONFIG_SENSORS_MAX16065)	+= max16065.o
 obj-$(CONFIG_SENSORS_MAX1619)	+= max1619.o
 obj-$(CONFIG_SENSORS_MAX6639)	+= max6639.o
+obj-$(CONFIG_SENSORS_MAX6642)	+= max6642.o
 obj-$(CONFIG_SENSORS_MAX6650)	+= max6650.o
 obj-$(CONFIG_SENSORS_MC13783_ADC)+= mc13783-adc.o
 obj-$(CONFIG_SENSORS_PC87360)	+= pc87360.o
@@ -118,9 +122,12 @@
 # PMBus drivers
 obj-$(CONFIG_PMBUS)		+= pmbus_core.o
 obj-$(CONFIG_SENSORS_PMBUS)	+= pmbus.o
+obj-$(CONFIG_SENSORS_ADM1275)	+= adm1275.o
 obj-$(CONFIG_SENSORS_MAX16064)	+= max16064.o
 obj-$(CONFIG_SENSORS_MAX34440)	+= max34440.o
 obj-$(CONFIG_SENSORS_MAX8688)	+= max8688.o
+obj-$(CONFIG_SENSORS_UCD9000)	+= ucd9000.o
+obj-$(CONFIG_SENSORS_UCD9200)	+= ucd9200.o
 
 ccflags-$(CONFIG_HWMON_DEBUG_CHIP) := -DDEBUG
 
diff -druN linux-2.6.39-libre/drivers/hwmon/max16065.c linux-3.0-rc7-libre/drivers/hwmon/max16065.c
--- linux-2.6.39-libre/drivers/hwmon/max16065.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/hwmon/max16065.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,717 @@
+/*
+ * Driver for
+ *  Maxim MAX16065/MAX16066 12-Channel/8-Channel, Flash-Configurable
+ *  System Managers with Nonvolatile Fault Registers
+ *  Maxim MAX16067/MAX16068 6-Channel, Flash-Configurable System Managers
+ *  with Nonvolatile Fault Registers
+ *  Maxim MAX16070/MAX16071 12-Channel/8-Channel, Flash-Configurable System
+ *  Monitors with Nonvolatile Fault Registers
+ *
+ * Copyright (C) 2011 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; version 2 of the License.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/err.h>
+#include <linux/slab.h>
+#include <linux/i2c.h>
+#include <linux/hwmon.h>
+#include <linux/hwmon-sysfs.h>
+#include <linux/delay.h>
+#include <linux/jiffies.h>
+
+enum chips { max16065, max16066, max16067, max16068, max16070, max16071 };
+
+/*
+ * Registers
+ */
+#define MAX16065_ADC(x)		((x) * 2)
+
+#define MAX16065_CURR_SENSE	0x18
+#define MAX16065_CSP_ADC	0x19
+#define MAX16065_FAULT(x)	(0x1b + (x))
+#define MAX16065_SCALE(x)	(0x43 + (x))
+#define MAX16065_CURR_CONTROL	0x47
+#define MAX16065_LIMIT(l, x)	(0x48 + (l) + (x) * 3)	/*
+							 * l: limit
+							 *  0: min/max
+							 *  1: crit
+							 *  2: lcrit
+							 * x: ADC index
+							 */
+
+#define MAX16065_SW_ENABLE	0x73
+
+#define MAX16065_WARNING_OV	(1 << 3) /* Set if secondary threshold is OV
+					    warning */
+
+#define MAX16065_CURR_ENABLE	(1 << 0)
+
+#define MAX16065_NUM_LIMIT	3
+#define MAX16065_NUM_ADC	12	/* maximum number of ADC channels */
+
+static const int max16065_num_adc[] = {
+	[max16065] = 12,
+	[max16066] = 8,
+	[max16067] = 6,
+	[max16068] = 6,
+	[max16070] = 12,
+	[max16071] = 8,
+};
+
+static const bool max16065_have_secondary[] = {
+	[max16065] = true,
+	[max16066] = true,
+	[max16067] = false,
+	[max16068] = false,
+	[max16070] = true,
+	[max16071] = true,
+};
+
+static const bool max16065_have_current[] = {
+	[max16065] = true,
+	[max16066] = true,
+	[max16067] = false,
+	[max16068] = false,
+	[max16070] = true,
+	[max16071] = true,
+};
+
+struct max16065_data {
+	enum chips type;
+	struct device *hwmon_dev;
+	struct mutex update_lock;
+	bool valid;
+	unsigned long last_updated; /* in jiffies */
+	int num_adc;
+	bool have_current;
+	int curr_gain;
+	/* limits are in mV */
+	int limit[MAX16065_NUM_LIMIT][MAX16065_NUM_ADC];
+	int range[MAX16065_NUM_ADC + 1];/* voltage range */
+	int adc[MAX16065_NUM_ADC + 1];	/* adc values (raw) including csp_adc */
+	int curr_sense;
+	int fault[2];
+};
+
+static const int max16065_adc_range[] = { 5560, 2780, 1390, 0 };
+static const int max16065_csp_adc_range[] = { 7000, 14000 };
+
+/* ADC registers have 10 bit resolution. */
+static inline int ADC_TO_MV(int adc, int range)
+{
+	return (adc * range) / 1024;
+}
+
+/*
+ * Limit registers have 8 bit resolution and match upper 8 bits of ADC
+ * registers.
+ */
+static inline int LIMIT_TO_MV(int limit, int range)
+{
+	return limit * range / 256;
+}
+
+static inline int MV_TO_LIMIT(int mv, int range)
+{
+	return SENSORS_LIMIT(DIV_ROUND_CLOSEST(mv * 256, range), 0, 255);
+}
+
+static inline int ADC_TO_CURR(int adc, int gain)
+{
+	return adc * 1400000 / gain * 255;
+}
+
+/*
+ * max16065_read_adc()
+ *
+ * Read 16 bit value from <reg>, <reg+1>.
+ * Upper 8 bits are in <reg>, lower 2 bits are in bits 7:6 of <reg+1>.
+ */
+static int max16065_read_adc(struct i2c_client *client, int reg)
+{
+	int rv;
+
+	rv = i2c_smbus_read_word_data(client, reg);
+	if (unlikely(rv < 0))
+		return rv;
+	return ((rv & 0xff) << 2) | ((rv >> 14) & 0x03);
+}
+
+static struct max16065_data *max16065_update_device(struct device *dev)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct max16065_data *data = i2c_get_clientdata(client);
+
+	mutex_lock(&data->update_lock);
+	if (time_after(jiffies, data->last_updated + HZ) || !data->valid) {
+		int i;
+
+		for (i = 0; i < data->num_adc; i++)
+			data->adc[i]
+			  = max16065_read_adc(client, MAX16065_ADC(i));
+
+		if (data->have_current) {
+			data->adc[MAX16065_NUM_ADC]
+			  = max16065_read_adc(client, MAX16065_CSP_ADC);
+			data->curr_sense
+			  = i2c_smbus_read_byte_data(client,
+						     MAX16065_CURR_SENSE);
+		}
+
+		for (i = 0; i < DIV_ROUND_UP(data->num_adc, 8); i++)
+			data->fault[i]
+			  = i2c_smbus_read_byte_data(client, MAX16065_FAULT(i));
+
+		data->last_updated = jiffies;
+		data->valid = 1;
+	}
+	mutex_unlock(&data->update_lock);
+	return data;
+}
+
+static ssize_t max16065_show_alarm(struct device *dev,
+				   struct device_attribute *da, char *buf)
+{
+	struct sensor_device_attribute_2 *attr2 = to_sensor_dev_attr_2(da);
+	struct max16065_data *data = max16065_update_device(dev);
+	int val = data->fault[attr2->nr];
+
+	if (val < 0)
+		return val;
+
+	val &= (1 << attr2->index);
+	if (val)
+		i2c_smbus_write_byte_data(to_i2c_client(dev),
+					  MAX16065_FAULT(attr2->nr), val);
+
+	return snprintf(buf, PAGE_SIZE, "%d\n", !!val);
+}
+
+static ssize_t max16065_show_input(struct device *dev,
+				   struct device_attribute *da, char *buf)
+{
+	struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
+	struct max16065_data *data = max16065_update_device(dev);
+	int adc = data->adc[attr->index];
+
+	if (unlikely(adc < 0))
+		return adc;
+
+	return snprintf(buf, PAGE_SIZE, "%d\n",
+			ADC_TO_MV(adc, data->range[attr->index]));
+}
+
+static ssize_t max16065_show_current(struct device *dev,
+				     struct device_attribute *da, char *buf)
+{
+	struct max16065_data *data = max16065_update_device(dev);
+
+	if (unlikely(data->curr_sense < 0))
+		return data->curr_sense;
+
+	return snprintf(buf, PAGE_SIZE, "%d\n",
+			ADC_TO_CURR(data->curr_sense, data->curr_gain));
+}
+
+static ssize_t max16065_set_limit(struct device *dev,
+				  struct device_attribute *da,
+				  const char *buf, size_t count)
+{
+	struct sensor_device_attribute_2 *attr2 = to_sensor_dev_attr_2(da);
+	struct i2c_client *client = to_i2c_client(dev);
+	struct max16065_data *data = i2c_get_clientdata(client);
+	unsigned long val;
+	int err;
+	int limit;
+
+	err = strict_strtoul(buf, 10, &val);
+	if (unlikely(err < 0))
+		return err;
+
+	limit = MV_TO_LIMIT(val, data->range[attr2->index]);
+
+	mutex_lock(&data->update_lock);
+	data->limit[attr2->nr][attr2->index]
+	  = LIMIT_TO_MV(limit, data->range[attr2->index]);
+	i2c_smbus_write_byte_data(client,
+				  MAX16065_LIMIT(attr2->nr, attr2->index),
+				  limit);
+	mutex_unlock(&data->update_lock);
+
+	return count;
+}
+
+static ssize_t max16065_show_limit(struct device *dev,
+				   struct device_attribute *da, char *buf)
+{
+	struct sensor_device_attribute_2 *attr2 = to_sensor_dev_attr_2(da);
+	struct i2c_client *client = to_i2c_client(dev);
+	struct max16065_data *data = i2c_get_clientdata(client);
+
+	return snprintf(buf, PAGE_SIZE, "%d\n",
+			data->limit[attr2->nr][attr2->index]);
+}
+
+/* Construct a sensor_device_attribute structure for each register */
+
+/* Input voltages */
+static SENSOR_DEVICE_ATTR(in0_input, S_IRUGO, max16065_show_input, NULL, 0);
+static SENSOR_DEVICE_ATTR(in1_input, S_IRUGO, max16065_show_input, NULL, 1);
+static SENSOR_DEVICE_ATTR(in2_input, S_IRUGO, max16065_show_input, NULL, 2);
+static SENSOR_DEVICE_ATTR(in3_input, S_IRUGO, max16065_show_input, NULL, 3);
+static SENSOR_DEVICE_ATTR(in4_input, S_IRUGO, max16065_show_input, NULL, 4);
+static SENSOR_DEVICE_ATTR(in5_input, S_IRUGO, max16065_show_input, NULL, 5);
+static SENSOR_DEVICE_ATTR(in6_input, S_IRUGO, max16065_show_input, NULL, 6);
+static SENSOR_DEVICE_ATTR(in7_input, S_IRUGO, max16065_show_input, NULL, 7);
+static SENSOR_DEVICE_ATTR(in8_input, S_IRUGO, max16065_show_input, NULL, 8);
+static SENSOR_DEVICE_ATTR(in9_input, S_IRUGO, max16065_show_input, NULL, 9);
+static SENSOR_DEVICE_ATTR(in10_input, S_IRUGO, max16065_show_input, NULL, 10);
+static SENSOR_DEVICE_ATTR(in11_input, S_IRUGO, max16065_show_input, NULL, 11);
+static SENSOR_DEVICE_ATTR(in12_input, S_IRUGO, max16065_show_input, NULL, 12);
+
+/* Input voltages lcrit */
+static SENSOR_DEVICE_ATTR_2(in0_lcrit, S_IWUSR | S_IRUGO, max16065_show_limit,
+			    max16065_set_limit, 2, 0);
+static SENSOR_DEVICE_ATTR_2(in1_lcrit, S_IWUSR | S_IRUGO, max16065_show_limit,
+			    max16065_set_limit, 2, 1);
+static SENSOR_DEVICE_ATTR_2(in2_lcrit, S_IWUSR | S_IRUGO, max16065_show_limit,
+			    max16065_set_limit, 2, 2);
+static SENSOR_DEVICE_ATTR_2(in3_lcrit, S_IWUSR | S_IRUGO, max16065_show_limit,
+			    max16065_set_limit, 2, 3);
+static SENSOR_DEVICE_ATTR_2(in4_lcrit, S_IWUSR | S_IRUGO, max16065_show_limit,
+			    max16065_set_limit, 2, 4);
+static SENSOR_DEVICE_ATTR_2(in5_lcrit, S_IWUSR | S_IRUGO, max16065_show_limit,
+			    max16065_set_limit, 2, 5);
+static SENSOR_DEVICE_ATTR_2(in6_lcrit, S_IWUSR | S_IRUGO, max16065_show_limit,
+			    max16065_set_limit, 2, 6);
+static SENSOR_DEVICE_ATTR_2(in7_lcrit, S_IWUSR | S_IRUGO, max16065_show_limit,
+			    max16065_set_limit, 2, 7);
+static SENSOR_DEVICE_ATTR_2(in8_lcrit, S_IWUSR | S_IRUGO, max16065_show_limit,
+			    max16065_set_limit, 2, 8);
+static SENSOR_DEVICE_ATTR_2(in9_lcrit, S_IWUSR | S_IRUGO, max16065_show_limit,
+			    max16065_set_limit, 2, 9);
+static SENSOR_DEVICE_ATTR_2(in10_lcrit, S_IWUSR | S_IRUGO, max16065_show_limit,
+			    max16065_set_limit, 2, 10);
+static SENSOR_DEVICE_ATTR_2(in11_lcrit, S_IWUSR | S_IRUGO, max16065_show_limit,
+			    max16065_set_limit, 2, 11);
+
+/* Input voltages crit */
+static SENSOR_DEVICE_ATTR_2(in0_crit, S_IWUSR | S_IRUGO, max16065_show_limit,
+			    max16065_set_limit, 1, 0);
+static SENSOR_DEVICE_ATTR_2(in1_crit, S_IWUSR | S_IRUGO, max16065_show_limit,
+			    max16065_set_limit, 1, 1);
+static SENSOR_DEVICE_ATTR_2(in2_crit, S_IWUSR | S_IRUGO, max16065_show_limit,
+			    max16065_set_limit, 1, 2);
+static SENSOR_DEVICE_ATTR_2(in3_crit, S_IWUSR | S_IRUGO, max16065_show_limit,
+			    max16065_set_limit, 1, 3);
+static SENSOR_DEVICE_ATTR_2(in4_crit, S_IWUSR | S_IRUGO, max16065_show_limit,
+			    max16065_set_limit, 1, 4);
+static SENSOR_DEVICE_ATTR_2(in5_crit, S_IWUSR | S_IRUGO, max16065_show_limit,
+			    max16065_set_limit, 1, 5);
+static SENSOR_DEVICE_ATTR_2(in6_crit, S_IWUSR | S_IRUGO, max16065_show_limit,
+			    max16065_set_limit, 1, 6);
+static SENSOR_DEVICE_ATTR_2(in7_crit, S_IWUSR | S_IRUGO, max16065_show_limit,
+			    max16065_set_limit, 1, 7);
+static SENSOR_DEVICE_ATTR_2(in8_crit, S_IWUSR | S_IRUGO, max16065_show_limit,
+			    max16065_set_limit, 1, 8);
+static SENSOR_DEVICE_ATTR_2(in9_crit, S_IWUSR | S_IRUGO, max16065_show_limit,
+			    max16065_set_limit, 1, 9);
+static SENSOR_DEVICE_ATTR_2(in10_crit, S_IWUSR | S_IRUGO, max16065_show_limit,
+			    max16065_set_limit, 1, 10);
+static SENSOR_DEVICE_ATTR_2(in11_crit, S_IWUSR | S_IRUGO, max16065_show_limit,
+			    max16065_set_limit, 1, 11);
+
+/* Input voltages min */
+static SENSOR_DEVICE_ATTR_2(in0_min, S_IWUSR | S_IRUGO, max16065_show_limit,
+			    max16065_set_limit, 0, 0);
+static SENSOR_DEVICE_ATTR_2(in1_min, S_IWUSR | S_IRUGO, max16065_show_limit,
+			    max16065_set_limit, 0, 1);
+static SENSOR_DEVICE_ATTR_2(in2_min, S_IWUSR | S_IRUGO, max16065_show_limit,
+			    max16065_set_limit, 0, 2);
+static SENSOR_DEVICE_ATTR_2(in3_min, S_IWUSR | S_IRUGO, max16065_show_limit,
+			    max16065_set_limit, 0, 3);
+static SENSOR_DEVICE_ATTR_2(in4_min, S_IWUSR | S_IRUGO, max16065_show_limit,
+			    max16065_set_limit, 0, 4);
+static SENSOR_DEVICE_ATTR_2(in5_min, S_IWUSR | S_IRUGO, max16065_show_limit,
+			    max16065_set_limit, 0, 5);
+static SENSOR_DEVICE_ATTR_2(in6_min, S_IWUSR | S_IRUGO, max16065_show_limit,
+			    max16065_set_limit, 0, 6);
+static SENSOR_DEVICE_ATTR_2(in7_min, S_IWUSR | S_IRUGO, max16065_show_limit,
+			    max16065_set_limit, 0, 7);
+static SENSOR_DEVICE_ATTR_2(in8_min, S_IWUSR | S_IRUGO, max16065_show_limit,
+			    max16065_set_limit, 0, 8);
+static SENSOR_DEVICE_ATTR_2(in9_min, S_IWUSR | S_IRUGO, max16065_show_limit,
+			    max16065_set_limit, 0, 9);
+static SENSOR_DEVICE_ATTR_2(in10_min, S_IWUSR | S_IRUGO, max16065_show_limit,
+			    max16065_set_limit, 0, 10);
+static SENSOR_DEVICE_ATTR_2(in11_min, S_IWUSR | S_IRUGO, max16065_show_limit,
+			    max16065_set_limit, 0, 11);
+
+/* Input voltages max */
+static SENSOR_DEVICE_ATTR_2(in0_max, S_IWUSR | S_IRUGO, max16065_show_limit,
+			    max16065_set_limit, 0, 0);
+static SENSOR_DEVICE_ATTR_2(in1_max, S_IWUSR | S_IRUGO, max16065_show_limit,
+			    max16065_set_limit, 0, 1);
+static SENSOR_DEVICE_ATTR_2(in2_max, S_IWUSR | S_IRUGO, max16065_show_limit,
+			    max16065_set_limit, 0, 2);
+static SENSOR_DEVICE_ATTR_2(in3_max, S_IWUSR | S_IRUGO, max16065_show_limit,
+			    max16065_set_limit, 0, 3);
+static SENSOR_DEVICE_ATTR_2(in4_max, S_IWUSR | S_IRUGO, max16065_show_limit,
+			    max16065_set_limit, 0, 4);
+static SENSOR_DEVICE_ATTR_2(in5_max, S_IWUSR | S_IRUGO, max16065_show_limit,
+			    max16065_set_limit, 0, 5);
+static SENSOR_DEVICE_ATTR_2(in6_max, S_IWUSR | S_IRUGO, max16065_show_limit,
+			    max16065_set_limit, 0, 6);
+static SENSOR_DEVICE_ATTR_2(in7_max, S_IWUSR | S_IRUGO, max16065_show_limit,
+			    max16065_set_limit, 0, 7);
+static SENSOR_DEVICE_ATTR_2(in8_max, S_IWUSR | S_IRUGO, max16065_show_limit,
+			    max16065_set_limit, 0, 8);
+static SENSOR_DEVICE_ATTR_2(in9_max, S_IWUSR | S_IRUGO, max16065_show_limit,
+			    max16065_set_limit, 0, 9);
+static SENSOR_DEVICE_ATTR_2(in10_max, S_IWUSR | S_IRUGO, max16065_show_limit,
+			    max16065_set_limit, 0, 10);
+static SENSOR_DEVICE_ATTR_2(in11_max, S_IWUSR | S_IRUGO, max16065_show_limit,
+			    max16065_set_limit, 0, 11);
+
+/* alarms */
+static SENSOR_DEVICE_ATTR_2(in0_alarm, S_IRUGO, max16065_show_alarm, NULL,
+			    0, 0);
+static SENSOR_DEVICE_ATTR_2(in1_alarm, S_IRUGO, max16065_show_alarm, NULL,
+			    0, 1);
+static SENSOR_DEVICE_ATTR_2(in2_alarm, S_IRUGO, max16065_show_alarm, NULL,
+			    0, 2);
+static SENSOR_DEVICE_ATTR_2(in3_alarm, S_IRUGO, max16065_show_alarm, NULL,
+			    0, 3);
+static SENSOR_DEVICE_ATTR_2(in4_alarm, S_IRUGO, max16065_show_alarm, NULL,
+			    0, 4);
+static SENSOR_DEVICE_ATTR_2(in5_alarm, S_IRUGO, max16065_show_alarm, NULL,
+			    0, 5);
+static SENSOR_DEVICE_ATTR_2(in6_alarm, S_IRUGO, max16065_show_alarm, NULL,
+			    0, 6);
+static SENSOR_DEVICE_ATTR_2(in7_alarm, S_IRUGO, max16065_show_alarm, NULL,
+			    0, 7);
+static SENSOR_DEVICE_ATTR_2(in8_alarm, S_IRUGO, max16065_show_alarm, NULL,
+			    1, 0);
+static SENSOR_DEVICE_ATTR_2(in9_alarm, S_IRUGO, max16065_show_alarm, NULL,
+			    1, 1);
+static SENSOR_DEVICE_ATTR_2(in10_alarm, S_IRUGO, max16065_show_alarm, NULL,
+			    1, 2);
+static SENSOR_DEVICE_ATTR_2(in11_alarm, S_IRUGO, max16065_show_alarm, NULL,
+			    1, 3);
+
+/* Current and alarm */
+static SENSOR_DEVICE_ATTR(curr1_input, S_IRUGO, max16065_show_current, NULL, 0);
+static SENSOR_DEVICE_ATTR_2(curr1_alarm, S_IRUGO, max16065_show_alarm, NULL,
+			    1, 4);
+
+/*
+ * Finally, construct an array of pointers to members of the above objects,
+ * as required for sysfs_create_group()
+ */
+static struct attribute *max16065_basic_attributes[] = {
+	&sensor_dev_attr_in0_input.dev_attr.attr,
+	&sensor_dev_attr_in0_lcrit.dev_attr.attr,
+	&sensor_dev_attr_in0_crit.dev_attr.attr,
+	&sensor_dev_attr_in0_alarm.dev_attr.attr,
+
+	&sensor_dev_attr_in1_input.dev_attr.attr,
+	&sensor_dev_attr_in1_lcrit.dev_attr.attr,
+	&sensor_dev_attr_in1_crit.dev_attr.attr,
+	&sensor_dev_attr_in1_alarm.dev_attr.attr,
+
+	&sensor_dev_attr_in2_input.dev_attr.attr,
+	&sensor_dev_attr_in2_lcrit.dev_attr.attr,
+	&sensor_dev_attr_in2_crit.dev_attr.attr,
+	&sensor_dev_attr_in2_alarm.dev_attr.attr,
+
+	&sensor_dev_attr_in3_input.dev_attr.attr,
+	&sensor_dev_attr_in3_lcrit.dev_attr.attr,
+	&sensor_dev_attr_in3_crit.dev_attr.attr,
+	&sensor_dev_attr_in3_alarm.dev_attr.attr,
+
+	&sensor_dev_attr_in4_input.dev_attr.attr,
+	&sensor_dev_attr_in4_lcrit.dev_attr.attr,
+	&sensor_dev_attr_in4_crit.dev_attr.attr,
+	&sensor_dev_attr_in4_alarm.dev_attr.attr,
+
+	&sensor_dev_attr_in5_input.dev_attr.attr,
+	&sensor_dev_attr_in5_lcrit.dev_attr.attr,
+	&sensor_dev_attr_in5_crit.dev_attr.attr,
+	&sensor_dev_attr_in5_alarm.dev_attr.attr,
+
+	&sensor_dev_attr_in6_input.dev_attr.attr,
+	&sensor_dev_attr_in6_lcrit.dev_attr.attr,
+	&sensor_dev_attr_in6_crit.dev_attr.attr,
+	&sensor_dev_attr_in6_alarm.dev_attr.attr,
+
+	&sensor_dev_attr_in7_input.dev_attr.attr,
+	&sensor_dev_attr_in7_lcrit.dev_attr.attr,
+	&sensor_dev_attr_in7_crit.dev_attr.attr,
+	&sensor_dev_attr_in7_alarm.dev_attr.attr,
+
+	&sensor_dev_attr_in8_input.dev_attr.attr,
+	&sensor_dev_attr_in8_lcrit.dev_attr.attr,
+	&sensor_dev_attr_in8_crit.dev_attr.attr,
+	&sensor_dev_attr_in8_alarm.dev_attr.attr,
+
+	&sensor_dev_attr_in9_input.dev_attr.attr,
+	&sensor_dev_attr_in9_lcrit.dev_attr.attr,
+	&sensor_dev_attr_in9_crit.dev_attr.attr,
+	&sensor_dev_attr_in9_alarm.dev_attr.attr,
+
+	&sensor_dev_attr_in10_input.dev_attr.attr,
+	&sensor_dev_attr_in10_lcrit.dev_attr.attr,
+	&sensor_dev_attr_in10_crit.dev_attr.attr,
+	&sensor_dev_attr_in10_alarm.dev_attr.attr,
+
+	&sensor_dev_attr_in11_input.dev_attr.attr,
+	&sensor_dev_attr_in11_lcrit.dev_attr.attr,
+	&sensor_dev_attr_in11_crit.dev_attr.attr,
+	&sensor_dev_attr_in11_alarm.dev_attr.attr,
+
+	NULL
+};
+
+static struct attribute *max16065_current_attributes[] = {
+	&sensor_dev_attr_in12_input.dev_attr.attr,
+	&sensor_dev_attr_curr1_input.dev_attr.attr,
+	&sensor_dev_attr_curr1_alarm.dev_attr.attr,
+	NULL
+};
+
+static struct attribute *max16065_min_attributes[] = {
+	&sensor_dev_attr_in0_min.dev_attr.attr,
+	&sensor_dev_attr_in1_min.dev_attr.attr,
+	&sensor_dev_attr_in2_min.dev_attr.attr,
+	&sensor_dev_attr_in3_min.dev_attr.attr,
+	&sensor_dev_attr_in4_min.dev_attr.attr,
+	&sensor_dev_attr_in5_min.dev_attr.attr,
+	&sensor_dev_attr_in6_min.dev_attr.attr,
+	&sensor_dev_attr_in7_min.dev_attr.attr,
+	&sensor_dev_attr_in8_min.dev_attr.attr,
+	&sensor_dev_attr_in9_min.dev_attr.attr,
+	&sensor_dev_attr_in10_min.dev_attr.attr,
+	&sensor_dev_attr_in11_min.dev_attr.attr,
+	NULL
+};
+
+static struct attribute *max16065_max_attributes[] = {
+	&sensor_dev_attr_in0_max.dev_attr.attr,
+	&sensor_dev_attr_in1_max.dev_attr.attr,
+	&sensor_dev_attr_in2_max.dev_attr.attr,
+	&sensor_dev_attr_in3_max.dev_attr.attr,
+	&sensor_dev_attr_in4_max.dev_attr.attr,
+	&sensor_dev_attr_in5_max.dev_attr.attr,
+	&sensor_dev_attr_in6_max.dev_attr.attr,
+	&sensor_dev_attr_in7_max.dev_attr.attr,
+	&sensor_dev_attr_in8_max.dev_attr.attr,
+	&sensor_dev_attr_in9_max.dev_attr.attr,
+	&sensor_dev_attr_in10_max.dev_attr.attr,
+	&sensor_dev_attr_in11_max.dev_attr.attr,
+	NULL
+};
+
+static const struct attribute_group max16065_basic_group = {
+	.attrs = max16065_basic_attributes,
+};
+
+static const struct attribute_group max16065_current_group = {
+	.attrs = max16065_current_attributes,
+};
+
+static const struct attribute_group max16065_min_group = {
+	.attrs = max16065_min_attributes,
+};
+
+static const struct attribute_group max16065_max_group = {
+	.attrs = max16065_max_attributes,
+};
+
+static void max16065_cleanup(struct i2c_client *client)
+{
+	sysfs_remove_group(&client->dev.kobj, &max16065_max_group);
+	sysfs_remove_group(&client->dev.kobj, &max16065_min_group);
+	sysfs_remove_group(&client->dev.kobj, &max16065_current_group);
+	sysfs_remove_group(&client->dev.kobj, &max16065_basic_group);
+}
+
+static int max16065_probe(struct i2c_client *client,
+			  const struct i2c_device_id *id)
+{
+	struct i2c_adapter *adapter = client->adapter;
+	struct max16065_data *data;
+	int i, j, val, ret;
+	bool have_secondary;		/* true if chip has secondary limits */
+	bool secondary_is_max = false;	/* secondary limits reflect max */
+
+	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA
+				     | I2C_FUNC_SMBUS_READ_WORD_DATA))
+		return -ENODEV;
+
+	data = kzalloc(sizeof(*data), GFP_KERNEL);
+	if (unlikely(!data))
+		return -ENOMEM;
+
+	i2c_set_clientdata(client, data);
+	mutex_init(&data->update_lock);
+
+	data->num_adc = max16065_num_adc[id->driver_data];
+	data->have_current = max16065_have_current[id->driver_data];
+	have_secondary = max16065_have_secondary[id->driver_data];
+
+	if (have_secondary) {
+		val = i2c_smbus_read_byte_data(client, MAX16065_SW_ENABLE);
+		if (unlikely(val < 0)) {
+			ret = val;
+			goto out_free;
+		}
+		secondary_is_max = val & MAX16065_WARNING_OV;
+	}
+
+	/* Read scale registers, convert to range */
+	for (i = 0; i < DIV_ROUND_UP(data->num_adc, 4); i++) {
+		val = i2c_smbus_read_byte_data(client, MAX16065_SCALE(i));
+		if (unlikely(val < 0)) {
+			ret = val;
+			goto out_free;
+		}
+		for (j = 0; j < 4 && i * 4 + j < data->num_adc; j++) {
+			data->range[i * 4 + j] =
+			  max16065_adc_range[(val >> (j * 2)) & 0x3];
+		}
+	}
+
+	/* Read limits */
+	for (i = 0; i < MAX16065_NUM_LIMIT; i++) {
+		if (i == 0 && !have_secondary)
+			continue;
+
+		for (j = 0; j < data->num_adc; j++) {
+			val = i2c_smbus_read_byte_data(client,
+						       MAX16065_LIMIT(i, j));
+			if (unlikely(val < 0)) {
+				ret = val;
+				goto out_free;
+			}
+			data->limit[i][j] = LIMIT_TO_MV(val, data->range[j]);
+		}
+	}
+
+	/* Register sysfs hooks */
+	for (i = 0; i < data->num_adc * 4; i++) {
+		/* Do not create sysfs entry if channel is disabled */
+		if (!data->range[i / 4])
+			continue;
+
+		ret = sysfs_create_file(&client->dev.kobj,
+					max16065_basic_attributes[i]);
+		if (unlikely(ret))
+			goto out;
+	}
+
+	if (have_secondary) {
+		struct attribute **attr = secondary_is_max ?
+		  max16065_max_attributes : max16065_min_attributes;
+
+		for (i = 0; i < data->num_adc; i++) {
+			if (!data->range[i])
+				continue;
+
+			ret = sysfs_create_file(&client->dev.kobj, attr[i]);
+			if (unlikely(ret))
+				goto out;
+		}
+	}
+
+	if (data->have_current) {
+		val = i2c_smbus_read_byte_data(client, MAX16065_CURR_CONTROL);
+		if (unlikely(val < 0)) {
+			ret = val;
+			goto out;
+		}
+		if (val & MAX16065_CURR_ENABLE) {
+			/*
+			 * Current gain is 6, 12, 24, 48 based on values in
+			 * bit 2,3.
+			 */
+			data->curr_gain = 6 << ((val >> 2) & 0x03);
+			data->range[MAX16065_NUM_ADC]
+			  = max16065_csp_adc_range[(val >> 1) & 0x01];
+			ret = sysfs_create_group(&client->dev.kobj,
+						 &max16065_current_group);
+			if (unlikely(ret))
+				goto out;
+		} else {
+			data->have_current = false;
+		}
+	}
+
+	data->hwmon_dev = hwmon_device_register(&client->dev);
+	if (unlikely(IS_ERR(data->hwmon_dev))) {
+		ret = PTR_ERR(data->hwmon_dev);
+		goto out;
+	}
+	return 0;
+
+out:
+	max16065_cleanup(client);
+out_free:
+	kfree(data);
+	return ret;
+}
+
+static int max16065_remove(struct i2c_client *client)
+{
+	struct max16065_data *data = i2c_get_clientdata(client);
+
+	hwmon_device_unregister(data->hwmon_dev);
+	max16065_cleanup(client);
+	kfree(data);
+
+	return 0;
+}
+
+static const struct i2c_device_id max16065_id[] = {
+	{ "max16065", max16065 },
+	{ "max16066", max16066 },
+	{ "max16067", max16067 },
+	{ "max16068", max16068 },
+	{ "max16070", max16070 },
+	{ "max16071", max16071 },
+	{ }
+};
+
+MODULE_DEVICE_TABLE(i2c, max16065_id);
+
+/* This is the driver that will be inserted */
+static struct i2c_driver max16065_driver = {
+	.driver = {
+		.name = "max16065",
+	},
+	.probe = max16065_probe,
+	.remove = max16065_remove,
+	.id_table = max16065_id,
+};
+
+static int __init max16065_init(void)
+{
+	return i2c_add_driver(&max16065_driver);
+}
+
+static void __exit max16065_exit(void)
+{
+	i2c_del_driver(&max16065_driver);
+}
+
+MODULE_AUTHOR("Guenter Roeck <guenter.roeck@ericsson.com>");
+MODULE_DESCRIPTION("MAX16065 driver");
+MODULE_LICENSE("GPL");
+
+module_init(max16065_init);
+module_exit(max16065_exit);
diff -druN linux-2.6.39-libre/drivers/hwmon/max34440.c linux-3.0-rc7-libre/drivers/hwmon/max34440.c
--- linux-2.6.39-libre/drivers/hwmon/max34440.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/hwmon/max34440.c	2011-07-11 19:51:52.000000000 -0400
@@ -32,7 +32,7 @@
 #define MAX34440_STATUS_OT_FAULT	(1 << 5)
 #define MAX34440_STATUS_OT_WARN		(1 << 6)
 
-static int max34440_get_status(struct i2c_client *client, int page, int reg)
+static int max34440_read_byte_data(struct i2c_client *client, int page, int reg)
 {
 	int ret;
 	int mfg_status;
@@ -108,7 +108,7 @@
 		.func[11] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
 		.func[12] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
 		.func[13] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
-		.get_status = max34440_get_status,
+		.read_byte_data = max34440_read_byte_data,
 	},
 	[max34441] = {
 		.pages = 12,
@@ -149,7 +149,7 @@
 		.func[9] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
 		.func[10] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
 		.func[11] = PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP,
-		.get_status = max34440_get_status,
+		.read_byte_data = max34440_read_byte_data,
 	},
 };
 
diff -druN linux-2.6.39-libre/drivers/hwmon/max6642.c linux-3.0-rc7-libre/drivers/hwmon/max6642.c
--- linux-2.6.39-libre/drivers/hwmon/max6642.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/hwmon/max6642.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,370 @@
+/*
+ * Driver for +/-1 degree C, SMBus-Compatible Remote/Local Temperature Sensor
+ * with Overtemperature Alarm
+ *
+ * Copyright (C) 2011 AppearTV AS
+ *
+ * Derived from:
+ *
+ *  Based on the max1619 driver.
+ *  Copyright (C) 2003-2004 Alexey Fisher <fishor@mail.ru>
+ *                          Jean Delvare <khali@linux-fr.org>
+ *
+ * The MAX6642 is a sensor chip made by Maxim.
+ * It reports up to two temperatures (its own plus up to
+ * one external one). Complete datasheet can be
+ * obtained from Maxim's website at:
+ *   http://datasheets.maxim-ic.com/en/ds/MAX6642.pdf
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/jiffies.h>
+#include <linux/i2c.h>
+#include <linux/hwmon.h>
+#include <linux/hwmon-sysfs.h>
+#include <linux/err.h>
+#include <linux/mutex.h>
+#include <linux/sysfs.h>
+
+static const unsigned short normal_i2c[] = {
+	0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, I2C_CLIENT_END };
+
+/*
+ * The MAX6642 registers
+ */
+
+#define MAX6642_REG_R_MAN_ID		0xFE
+#define MAX6642_REG_R_CONFIG		0x03
+#define MAX6642_REG_W_CONFIG		0x09
+#define MAX6642_REG_R_STATUS		0x02
+#define MAX6642_REG_R_LOCAL_TEMP	0x00
+#define MAX6642_REG_R_LOCAL_TEMPL	0x11
+#define MAX6642_REG_R_LOCAL_HIGH	0x05
+#define MAX6642_REG_W_LOCAL_HIGH	0x0B
+#define MAX6642_REG_R_REMOTE_TEMP	0x01
+#define MAX6642_REG_R_REMOTE_TEMPL	0x10
+#define MAX6642_REG_R_REMOTE_HIGH	0x07
+#define MAX6642_REG_W_REMOTE_HIGH	0x0D
+
+/*
+ * Conversions
+ */
+
+static int temp_from_reg10(int val)
+{
+	return val * 250;
+}
+
+static int temp_from_reg(int val)
+{
+	return val * 1000;
+}
+
+static int temp_to_reg(int val)
+{
+	return val / 1000;
+}
+
+/*
+ * Client data (each client gets its own)
+ */
+
+struct max6642_data {
+	struct device *hwmon_dev;
+	struct mutex update_lock;
+	bool valid; /* zero until following fields are valid */
+	unsigned long last_updated; /* in jiffies */
+
+	/* registers values */
+	u16 temp_input[2]; /* local/remote */
+	u16 temp_high[2]; /* local/remote */
+	u8 alarms;
+};
+
+/*
+ * Real code
+ */
+
+static void max6642_init_client(struct i2c_client *client)
+{
+	u8 config;
+	struct max6642_data *data = i2c_get_clientdata(client);
+
+	/*
+	 * Start the conversions.
+	 */
+	config = i2c_smbus_read_byte_data(client, MAX6642_REG_R_CONFIG);
+	if (config & 0x40)
+		i2c_smbus_write_byte_data(client, MAX6642_REG_W_CONFIG,
+					  config & 0xBF); /* run */
+
+	data->temp_high[0] = i2c_smbus_read_byte_data(client,
+				MAX6642_REG_R_LOCAL_HIGH);
+	data->temp_high[1] = i2c_smbus_read_byte_data(client,
+				MAX6642_REG_R_REMOTE_HIGH);
+}
+
+/* Return 0 if detection is successful, -ENODEV otherwise */
+static int max6642_detect(struct i2c_client *client,
+			  struct i2c_board_info *info)
+{
+	struct i2c_adapter *adapter = client->adapter;
+	u8 reg_config, reg_status, man_id;
+
+	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
+		return -ENODEV;
+
+	/* identification */
+	man_id = i2c_smbus_read_byte_data(client, MAX6642_REG_R_MAN_ID);
+	if (man_id != 0x4D)
+		return -ENODEV;
+
+	/* sanity check */
+	if (i2c_smbus_read_byte_data(client, 0x04) != 0x4D
+	    || i2c_smbus_read_byte_data(client, 0x06) != 0x4D
+	    || i2c_smbus_read_byte_data(client, 0xff) != 0x4D)
+		return -ENODEV;
+
+	/*
+	 * We read the config and status register, the 4 lower bits in the
+	 * config register should be zero and bit 5, 3, 1 and 0 should be
+	 * zero in the status register.
+	 */
+	reg_config = i2c_smbus_read_byte_data(client, MAX6642_REG_R_CONFIG);
+	if ((reg_config & 0x0f) != 0x00)
+		return -ENODEV;
+
+	/* in between, another round of sanity checks */
+	if (i2c_smbus_read_byte_data(client, 0x04) != reg_config
+	    || i2c_smbus_read_byte_data(client, 0x06) != reg_config
+	    || i2c_smbus_read_byte_data(client, 0xff) != reg_config)
+		return -ENODEV;
+
+	reg_status = i2c_smbus_read_byte_data(client, MAX6642_REG_R_STATUS);
+	if ((reg_status & 0x2b) != 0x00)
+		return -ENODEV;
+
+	strlcpy(info->type, "max6642", I2C_NAME_SIZE);
+
+	return 0;
+}
+
+static struct max6642_data *max6642_update_device(struct device *dev)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct max6642_data *data = i2c_get_clientdata(client);
+	u16 val, tmp;
+
+	mutex_lock(&data->update_lock);
+
+	if (time_after(jiffies, data->last_updated + HZ) || !data->valid) {
+		dev_dbg(&client->dev, "Updating max6642 data.\n");
+		val = i2c_smbus_read_byte_data(client,
+					MAX6642_REG_R_LOCAL_TEMPL);
+		tmp = (val >> 6) & 3;
+		val = i2c_smbus_read_byte_data(client,
+					MAX6642_REG_R_LOCAL_TEMP);
+		val = (val << 2) | tmp;
+		data->temp_input[0] = val;
+		val = i2c_smbus_read_byte_data(client,
+					MAX6642_REG_R_REMOTE_TEMPL);
+		tmp = (val >> 6) & 3;
+		val = i2c_smbus_read_byte_data(client,
+					MAX6642_REG_R_REMOTE_TEMP);
+		val = (val << 2) | tmp;
+		data->temp_input[1] = val;
+		data->alarms = i2c_smbus_read_byte_data(client,
+					MAX6642_REG_R_STATUS);
+
+		data->last_updated = jiffies;
+		data->valid = 1;
+	}
+
+	mutex_unlock(&data->update_lock);
+
+	return data;
+}
+
+/*
+ * Sysfs stuff
+ */
+
+static ssize_t show_temp_max10(struct device *dev,
+			       struct device_attribute *dev_attr, char *buf)
+{
+	struct max6642_data *data = max6642_update_device(dev);
+	struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr);
+
+	return sprintf(buf, "%d\n",
+		       temp_from_reg10(data->temp_input[attr->index]));
+}
+
+static ssize_t show_temp_max(struct device *dev, struct device_attribute *attr,
+			     char *buf)
+{
+	struct max6642_data *data = max6642_update_device(dev);
+	struct sensor_device_attribute_2 *attr2 = to_sensor_dev_attr_2(attr);
+
+	return sprintf(buf, "%d\n", temp_from_reg(data->temp_high[attr2->nr]));
+}
+
+static ssize_t set_temp_max(struct device *dev, struct device_attribute *attr,
+			    const char *buf, size_t count)
+{
+	unsigned long val;
+	int err;
+	struct i2c_client *client = to_i2c_client(dev);
+	struct max6642_data *data = i2c_get_clientdata(client);
+	struct sensor_device_attribute_2 *attr2 = to_sensor_dev_attr_2(attr);
+
+	err = strict_strtoul(buf, 10, &val);
+	if (err < 0)
+		return err;
+
+	mutex_lock(&data->update_lock);
+	data->temp_high[attr2->nr] = SENSORS_LIMIT(temp_to_reg(val), 0, 255);
+	i2c_smbus_write_byte_data(client, attr2->index,
+				  data->temp_high[attr2->nr]);
+	mutex_unlock(&data->update_lock);
+	return count;
+}
+
+static ssize_t show_alarm(struct device *dev, struct device_attribute *attr,
+			  char *buf)
+{
+	int bitnr = to_sensor_dev_attr(attr)->index;
+	struct max6642_data *data = max6642_update_device(dev);
+	return sprintf(buf, "%d\n", (data->alarms >> bitnr) & 1);
+}
+
+static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp_max10, NULL, 0);
+static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO, show_temp_max10, NULL, 1);
+static SENSOR_DEVICE_ATTR_2(temp1_max, S_IWUSR | S_IRUGO, show_temp_max,
+			    set_temp_max, 0, MAX6642_REG_W_LOCAL_HIGH);
+static SENSOR_DEVICE_ATTR_2(temp2_max, S_IWUSR | S_IRUGO, show_temp_max,
+			    set_temp_max, 1, MAX6642_REG_W_REMOTE_HIGH);
+static SENSOR_DEVICE_ATTR(temp2_fault, S_IRUGO, show_alarm, NULL, 2);
+static SENSOR_DEVICE_ATTR(temp1_max_alarm, S_IRUGO, show_alarm, NULL, 6);
+static SENSOR_DEVICE_ATTR(temp2_max_alarm, S_IRUGO, show_alarm, NULL, 4);
+
+static struct attribute *max6642_attributes[] = {
+	&sensor_dev_attr_temp1_input.dev_attr.attr,
+	&sensor_dev_attr_temp2_input.dev_attr.attr,
+	&sensor_dev_attr_temp1_max.dev_attr.attr,
+	&sensor_dev_attr_temp2_max.dev_attr.attr,
+
+	&sensor_dev_attr_temp2_fault.dev_attr.attr,
+	&sensor_dev_attr_temp1_max_alarm.dev_attr.attr,
+	&sensor_dev_attr_temp2_max_alarm.dev_attr.attr,
+	NULL
+};
+
+static const struct attribute_group max6642_group = {
+	.attrs = max6642_attributes,
+};
+
+static int max6642_probe(struct i2c_client *new_client,
+			 const struct i2c_device_id *id)
+{
+	struct max6642_data *data;
+	int err;
+
+	data = kzalloc(sizeof(struct max6642_data), GFP_KERNEL);
+	if (!data) {
+		err = -ENOMEM;
+		goto exit;
+	}
+
+	i2c_set_clientdata(new_client, data);
+	mutex_init(&data->update_lock);
+
+	/* Initialize the MAX6642 chip */
+	max6642_init_client(new_client);
+
+	/* Register sysfs hooks */
+	err = sysfs_create_group(&new_client->dev.kobj, &max6642_group);
+	if (err)
+		goto exit_free;
+
+	data->hwmon_dev = hwmon_device_register(&new_client->dev);
+	if (IS_ERR(data->hwmon_dev)) {
+		err = PTR_ERR(data->hwmon_dev);
+		goto exit_remove_files;
+	}
+
+	return 0;
+
+exit_remove_files:
+	sysfs_remove_group(&new_client->dev.kobj, &max6642_group);
+exit_free:
+	kfree(data);
+exit:
+	return err;
+}
+
+static int max6642_remove(struct i2c_client *client)
+{
+	struct max6642_data *data = i2c_get_clientdata(client);
+
+	hwmon_device_unregister(data->hwmon_dev);
+	sysfs_remove_group(&client->dev.kobj, &max6642_group);
+
+	kfree(data);
+	return 0;
+}
+
+/*
+ * Driver data (common to all clients)
+ */
+
+static const struct i2c_device_id max6642_id[] = {
+	{ "max6642", 0 },
+	{ }
+};
+MODULE_DEVICE_TABLE(i2c, max6642_id);
+
+static struct i2c_driver max6642_driver = {
+	.class		= I2C_CLASS_HWMON,
+	.driver = {
+		.name	= "max6642",
+	},
+	.probe		= max6642_probe,
+	.remove		= max6642_remove,
+	.id_table	= max6642_id,
+	.detect		= max6642_detect,
+	.address_list	= normal_i2c,
+};
+
+static int __init max6642_init(void)
+{
+	return i2c_add_driver(&max6642_driver);
+}
+
+static void __exit max6642_exit(void)
+{
+	i2c_del_driver(&max6642_driver);
+}
+
+MODULE_AUTHOR("Per Dalen <per.dalen@appeartv.com>");
+MODULE_DESCRIPTION("MAX6642 sensor driver");
+MODULE_LICENSE("GPL");
+
+module_init(max6642_init);
+module_exit(max6642_exit);
diff -druN linux-2.6.39-libre/drivers/hwmon/max6650.c linux-3.0-rc7-libre/drivers/hwmon/max6650.c
--- linux-2.6.39-libre/drivers/hwmon/max6650.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/hwmon/max6650.c	2011-07-11 19:51:52.000000000 -0400
@@ -41,13 +41,6 @@
 #include <linux/err.h>
 
 /*
- * Addresses to scan. There are four disjoint possibilities, by pin config.
- */
-
-static const unsigned short normal_i2c[] = {0x1b, 0x1f, 0x48, 0x4b,
-						I2C_CLIENT_END};
-
-/*
  * Insmod parameters
  */
 
@@ -114,8 +107,6 @@
 
 static int max6650_probe(struct i2c_client *client,
 			 const struct i2c_device_id *id);
-static int max6650_detect(struct i2c_client *client,
-			  struct i2c_board_info *info);
 static int max6650_init_client(struct i2c_client *client);
 static int max6650_remove(struct i2c_client *client);
 static struct max6650_data *max6650_update_device(struct device *dev);
@@ -125,21 +116,19 @@
  */
 
 static const struct i2c_device_id max6650_id[] = {
-	{ "max6650", 0 },
+	{ "max6650", 1 },
+	{ "max6651", 4 },
 	{ }
 };
 MODULE_DEVICE_TABLE(i2c, max6650_id);
 
 static struct i2c_driver max6650_driver = {
-	.class		= I2C_CLASS_HWMON,
 	.driver = {
 		.name	= "max6650",
 	},
 	.probe		= max6650_probe,
 	.remove		= max6650_remove,
 	.id_table	= max6650_id,
-	.detect		= max6650_detect,
-	.address_list	= normal_i2c,
 };
 
 /*
@@ -150,6 +139,7 @@
 {
 	struct device *hwmon_dev;
 	struct mutex update_lock;
+	int nr_fans;
 	char valid; /* zero until following fields are valid */
 	unsigned long last_updated; /* in jiffies */
 
@@ -501,9 +491,6 @@
 
 static struct attribute *max6650_attrs[] = {
 	&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,
 	&dev_attr_fan1_target.attr,
 	&dev_attr_fan1_div.attr,
 	&dev_attr_pwm1_enable.attr,
@@ -521,42 +508,21 @@
 	.is_visible = max6650_attrs_visible,
 };
 
+static struct attribute *max6651_attrs[] = {
+	&sensor_dev_attr_fan2_input.dev_attr.attr,
+	&sensor_dev_attr_fan3_input.dev_attr.attr,
+	&sensor_dev_attr_fan4_input.dev_attr.attr,
+	NULL
+};
+
+static const struct attribute_group max6651_attr_grp = {
+	.attrs = max6651_attrs,
+};
+
 /*
  * Real code
  */
 
-/* Return 0 if detection is successful, -ENODEV otherwise */
-static int max6650_detect(struct i2c_client *client,
-			  struct i2c_board_info *info)
-{
-	struct i2c_adapter *adapter = client->adapter;
-	int address = client->addr;
-
-	dev_dbg(&adapter->dev, "max6650_detect called\n");
-
-	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) {
-		dev_dbg(&adapter->dev, "max6650: I2C bus doesn't support "
-					"byte read mode, skipping.\n");
-		return -ENODEV;
-	}
-
-	if (((i2c_smbus_read_byte_data(client, MAX6650_REG_CONFIG) & 0xC0)
-	    ||(i2c_smbus_read_byte_data(client, MAX6650_REG_GPIO_STAT) & 0xE0)
-	    ||(i2c_smbus_read_byte_data(client, MAX6650_REG_ALARM_EN) & 0xE0)
-	    ||(i2c_smbus_read_byte_data(client, MAX6650_REG_ALARM) & 0xE0)
-	    ||(i2c_smbus_read_byte_data(client, MAX6650_REG_COUNT) & 0xFC))) {
-		dev_dbg(&adapter->dev,
-			"max6650: detection failed at 0x%02x.\n", address);
-		return -ENODEV;
-	}
-
-	dev_info(&adapter->dev, "max6650: chip found at 0x%02x.\n", address);
-
-	strlcpy(info->type, "max6650", I2C_NAME_SIZE);
-
-	return 0;
-}
-
 static int max6650_probe(struct i2c_client *client,
 			 const struct i2c_device_id *id)
 {
@@ -570,6 +536,7 @@
 
 	i2c_set_clientdata(client, data);
 	mutex_init(&data->update_lock);
+	data->nr_fans = id->driver_data;
 
 	/*
 	 * Initialize the max6650 chip
@@ -581,6 +548,12 @@
 	err = sysfs_create_group(&client->dev.kobj, &max6650_attr_grp);
 	if (err)
 		goto err_free;
+	/* 3 additional fan inputs for the MAX6651 */
+	if (data->nr_fans == 4) {
+		err = sysfs_create_group(&client->dev.kobj, &max6651_attr_grp);
+		if (err)
+			goto err_remove;
+	}
 
 	data->hwmon_dev = hwmon_device_register(&client->dev);
 	if (!IS_ERR(data->hwmon_dev))
@@ -588,6 +561,9 @@
 
 	err = PTR_ERR(data->hwmon_dev);
 	dev_err(&client->dev, "error registering hwmon device.\n");
+	if (data->nr_fans == 4)
+		sysfs_remove_group(&client->dev.kobj, &max6651_attr_grp);
+err_remove:
 	sysfs_remove_group(&client->dev.kobj, &max6650_attr_grp);
 err_free:
 	kfree(data);
@@ -598,8 +574,10 @@
 {
 	struct max6650_data *data = i2c_get_clientdata(client);
 
-	sysfs_remove_group(&client->dev.kobj, &max6650_attr_grp);
 	hwmon_device_unregister(data->hwmon_dev);
+	if (data->nr_fans == 4)
+		sysfs_remove_group(&client->dev.kobj, &max6651_attr_grp);
+	sysfs_remove_group(&client->dev.kobj, &max6650_attr_grp);
 	kfree(data);
 	return 0;
 }
@@ -712,7 +690,7 @@
 						       MAX6650_REG_SPEED);
 		data->config = i2c_smbus_read_byte_data(client,
 							MAX6650_REG_CONFIG);
-		for (i = 0; i < 4; i++) {
+		for (i = 0; i < data->nr_fans; i++) {
 			data->tach[i] = i2c_smbus_read_byte_data(client,
 								 tach_reg[i]);
 		}
diff -druN linux-2.6.39-libre/drivers/hwmon/max8688.c linux-3.0-rc7-libre/drivers/hwmon/max8688.c
--- linux-2.6.39-libre/drivers/hwmon/max8688.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/hwmon/max8688.c	2011-07-11 19:51:52.000000000 -0400
@@ -37,7 +37,7 @@
 #define MAX8688_STATUS_OT_FAULT		(1 << 13)
 #define MAX8688_STATUS_OT_WARNING	(1 << 14)
 
-static int max8688_get_status(struct i2c_client *client, int page, int reg)
+static int max8688_read_byte_data(struct i2c_client *client, int page, int reg)
 {
 	int ret = 0;
 	int mfg_status;
@@ -110,7 +110,7 @@
 	.func[0] = PMBUS_HAVE_VOUT | PMBUS_HAVE_IOUT | PMBUS_HAVE_TEMP
 		| PMBUS_HAVE_STATUS_VOUT | PMBUS_HAVE_STATUS_IOUT
 		| PMBUS_HAVE_STATUS_TEMP,
-	.get_status = max8688_get_status,
+	.read_byte_data = max8688_read_byte_data,
 };
 
 static int max8688_probe(struct i2c_client *client,
diff -druN linux-2.6.39-libre/drivers/hwmon/pkgtemp.c linux-3.0-rc7-libre/drivers/hwmon/pkgtemp.c
--- linux-2.6.39-libre/drivers/hwmon/pkgtemp.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/hwmon/pkgtemp.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,444 +0,0 @@
-/*
- * pkgtemp.c - Linux kernel module for processor package hardware monitoring
- *
- * Copyright (C) 2010 Fenghua Yu <fenghua.yu@intel.com>
- *
- * Inspired from many hwmon drivers especially coretemp.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301 USA.
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/jiffies.h>
-#include <linux/hwmon.h>
-#include <linux/sysfs.h>
-#include <linux/hwmon-sysfs.h>
-#include <linux/err.h>
-#include <linux/mutex.h>
-#include <linux/list.h>
-#include <linux/platform_device.h>
-#include <linux/cpu.h>
-#include <asm/msr.h>
-#include <asm/processor.h>
-#include <asm/smp.h>
-
-#define DRVNAME	"pkgtemp"
-
-enum { SHOW_TEMP, SHOW_TJMAX, SHOW_TTARGET, SHOW_LABEL, SHOW_NAME };
-
-/*
- * Functions declaration
- */
-
-static struct pkgtemp_data *pkgtemp_update_device(struct device *dev);
-
-struct pkgtemp_data {
-	struct device *hwmon_dev;
-	struct mutex update_lock;
-	const char *name;
-	u32 id;
-	u16 phys_proc_id;
-	char valid;		/* zero until following fields are valid */
-	unsigned long last_updated;	/* in jiffies */
-	int temp;
-	int tjmax;
-	int ttarget;
-	u8 alarm;
-};
-
-/*
- * Sysfs stuff
- */
-
-static ssize_t show_name(struct device *dev, struct device_attribute
-			  *devattr, char *buf)
-{
-	int ret;
-	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
-	struct pkgtemp_data *data = dev_get_drvdata(dev);
-
-	if (attr->index == SHOW_NAME)
-		ret = sprintf(buf, "%s\n", data->name);
-	else	/* show label */
-		ret = sprintf(buf, "physical id %d\n",
-			      data->phys_proc_id);
-	return ret;
-}
-
-static ssize_t show_alarm(struct device *dev, struct device_attribute
-			  *devattr, char *buf)
-{
-	struct pkgtemp_data *data = pkgtemp_update_device(dev);
-	/* read the Out-of-spec log, never clear */
-	return sprintf(buf, "%d\n", data->alarm);
-}
-
-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 pkgtemp_data *data = pkgtemp_update_device(dev);
-	int err = 0;
-
-	if (attr->index == SHOW_TEMP)
-		err = data->valid ? sprintf(buf, "%d\n", data->temp) : -EAGAIN;
-	else if (attr->index == SHOW_TJMAX)
-		err = sprintf(buf, "%d\n", data->tjmax);
-	else
-		err = sprintf(buf, "%d\n", data->ttarget);
-	return err;
-}
-
-static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp, NULL, SHOW_TEMP);
-static SENSOR_DEVICE_ATTR(temp1_crit, S_IRUGO, show_temp, NULL, SHOW_TJMAX);
-static SENSOR_DEVICE_ATTR(temp1_max, S_IRUGO, show_temp, NULL, SHOW_TTARGET);
-static DEVICE_ATTR(temp1_crit_alarm, S_IRUGO, show_alarm, NULL);
-static SENSOR_DEVICE_ATTR(temp1_label, S_IRUGO, show_name, NULL, SHOW_LABEL);
-static SENSOR_DEVICE_ATTR(name, S_IRUGO, show_name, NULL, SHOW_NAME);
-
-static struct attribute *pkgtemp_attributes[] = {
-	&sensor_dev_attr_name.dev_attr.attr,
-	&sensor_dev_attr_temp1_label.dev_attr.attr,
-	&dev_attr_temp1_crit_alarm.attr,
-	&sensor_dev_attr_temp1_input.dev_attr.attr,
-	&sensor_dev_attr_temp1_crit.dev_attr.attr,
-	NULL
-};
-
-static const struct attribute_group pkgtemp_group = {
-	.attrs = pkgtemp_attributes,
-};
-
-static struct pkgtemp_data *pkgtemp_update_device(struct device *dev)
-{
-	struct pkgtemp_data *data = dev_get_drvdata(dev);
-	unsigned int cpu;
-	int err;
-
-	mutex_lock(&data->update_lock);
-
-	if (!data->valid || time_after(jiffies, data->last_updated + HZ)) {
-		u32 eax, edx;
-
-		data->valid = 0;
-		cpu = data->id;
-		err = rdmsr_on_cpu(cpu, MSR_IA32_PACKAGE_THERM_STATUS,
-				   &eax, &edx);
-		if (!err) {
-			data->alarm = (eax >> 5) & 1;
-			data->temp = data->tjmax - (((eax >> 16)
-							& 0x7f) * 1000);
-			data->valid = 1;
-		} else
-			dev_dbg(dev, "Temperature data invalid (0x%x)\n", eax);
-
-		data->last_updated = jiffies;
-	}
-
-	mutex_unlock(&data->update_lock);
-	return data;
-}
-
-static int get_tjmax(int cpu, struct device *dev)
-{
-	int default_tjmax = 100000;
-	int err;
-	u32 eax, edx;
-	u32 val;
-
-	/* IA32_TEMPERATURE_TARGET contains the TjMax value */
-	err = rdmsr_safe_on_cpu(cpu, MSR_IA32_TEMPERATURE_TARGET, &eax, &edx);
-	if (!err) {
-		val = (eax >> 16) & 0xff;
-		if ((val > 80) && (val < 120)) {
-			dev_info(dev, "TjMax is %d C.\n", val);
-			return val * 1000;
-		}
-	}
-	dev_warn(dev, "Unable to read TjMax from CPU.\n");
-	return default_tjmax;
-}
-
-static int __devinit pkgtemp_probe(struct platform_device *pdev)
-{
-	struct pkgtemp_data *data;
-	int err;
-	u32 eax, edx;
-#ifdef CONFIG_SMP
-	struct cpuinfo_x86 *c = &cpu_data(pdev->id);
-#endif
-
-	data = kzalloc(sizeof(struct pkgtemp_data), GFP_KERNEL);
-	if (!data) {
-		err = -ENOMEM;
-		dev_err(&pdev->dev, "Out of memory\n");
-		goto exit;
-	}
-
-	data->id = pdev->id;
-#ifdef CONFIG_SMP
-	data->phys_proc_id = c->phys_proc_id;
-#endif
-	data->name = "pkgtemp";
-	mutex_init(&data->update_lock);
-
-	/* test if we can access the THERM_STATUS MSR */
-	err = rdmsr_safe_on_cpu(data->id, MSR_IA32_PACKAGE_THERM_STATUS,
-				&eax, &edx);
-	if (err) {
-		dev_err(&pdev->dev,
-			"Unable to access THERM_STATUS MSR, giving up\n");
-		goto exit_free;
-	}
-
-	data->tjmax = get_tjmax(data->id, &pdev->dev);
-	platform_set_drvdata(pdev, data);
-
-	err = rdmsr_safe_on_cpu(data->id, MSR_IA32_TEMPERATURE_TARGET,
-				&eax, &edx);
-	if (err) {
-		dev_warn(&pdev->dev, "Unable to read"
-				" IA32_TEMPERATURE_TARGET MSR\n");
-	} else {
-		data->ttarget = data->tjmax - (((eax >> 8) & 0xff) * 1000);
-		err = device_create_file(&pdev->dev,
-				&sensor_dev_attr_temp1_max.dev_attr);
-		if (err)
-			goto exit_free;
-	}
-
-	err = sysfs_create_group(&pdev->dev.kobj, &pkgtemp_group);
-	if (err)
-		goto exit_dev;
-
-	data->hwmon_dev = hwmon_device_register(&pdev->dev);
-	if (IS_ERR(data->hwmon_dev)) {
-		err = PTR_ERR(data->hwmon_dev);
-		dev_err(&pdev->dev, "Class registration failed (%d)\n",
-			err);
-		goto exit_class;
-	}
-
-	return 0;
-
-exit_class:
-	sysfs_remove_group(&pdev->dev.kobj, &pkgtemp_group);
-exit_dev:
-	device_remove_file(&pdev->dev, &sensor_dev_attr_temp1_max.dev_attr);
-exit_free:
-	kfree(data);
-exit:
-	return err;
-}
-
-static int __devexit pkgtemp_remove(struct platform_device *pdev)
-{
-	struct pkgtemp_data *data = platform_get_drvdata(pdev);
-
-	hwmon_device_unregister(data->hwmon_dev);
-	sysfs_remove_group(&pdev->dev.kobj, &pkgtemp_group);
-	device_remove_file(&pdev->dev, &sensor_dev_attr_temp1_max.dev_attr);
-	platform_set_drvdata(pdev, NULL);
-	kfree(data);
-	return 0;
-}
-
-static struct platform_driver pkgtemp_driver = {
-	.driver = {
-		.owner = THIS_MODULE,
-		.name = DRVNAME,
-	},
-	.probe = pkgtemp_probe,
-	.remove = __devexit_p(pkgtemp_remove),
-};
-
-struct pdev_entry {
-	struct list_head list;
-	struct platform_device *pdev;
-	unsigned int cpu;
-#ifdef CONFIG_SMP
-	u16 phys_proc_id;
-#endif
-};
-
-static LIST_HEAD(pdev_list);
-static DEFINE_MUTEX(pdev_list_mutex);
-
-static int __cpuinit pkgtemp_device_add(unsigned int cpu)
-{
-	int err;
-	struct platform_device *pdev;
-	struct pdev_entry *pdev_entry;
-	struct cpuinfo_x86 *c = &cpu_data(cpu);
-
-	if (!cpu_has(c, X86_FEATURE_PTS))
-		return 0;
-
-	mutex_lock(&pdev_list_mutex);
-
-#ifdef CONFIG_SMP
-	/* Only keep the first entry in each package */
-	list_for_each_entry(pdev_entry, &pdev_list, list) {
-		if (c->phys_proc_id == pdev_entry->phys_proc_id) {
-			err = 0;        /* Not an error */
-			goto exit;
-		}
-	}
-#endif
-
-	pdev = platform_device_alloc(DRVNAME, cpu);
-	if (!pdev) {
-		err = -ENOMEM;
-		pr_err("Device allocation failed\n");
-		goto exit;
-	}
-
-	pdev_entry = kzalloc(sizeof(struct pdev_entry), GFP_KERNEL);
-	if (!pdev_entry) {
-		err = -ENOMEM;
-		goto exit_device_put;
-	}
-
-	err = platform_device_add(pdev);
-	if (err) {
-		pr_err("Device addition failed (%d)\n", err);
-		goto exit_device_free;
-	}
-
-#ifdef CONFIG_SMP
-	pdev_entry->phys_proc_id = c->phys_proc_id;
-#endif
-	pdev_entry->pdev = pdev;
-	pdev_entry->cpu = cpu;
-	list_add_tail(&pdev_entry->list, &pdev_list);
-	mutex_unlock(&pdev_list_mutex);
-
-	return 0;
-
-exit_device_free:
-	kfree(pdev_entry);
-exit_device_put:
-	platform_device_put(pdev);
-exit:
-	mutex_unlock(&pdev_list_mutex);
-	return err;
-}
-
-static void __cpuinit pkgtemp_device_remove(unsigned int cpu)
-{
-	struct pdev_entry *p;
-	unsigned int i;
-	int err;
-
-	mutex_lock(&pdev_list_mutex);
-	list_for_each_entry(p, &pdev_list, list) {
-		if (p->cpu != cpu)
-			continue;
-
-		platform_device_unregister(p->pdev);
-		list_del(&p->list);
-		mutex_unlock(&pdev_list_mutex);
-		kfree(p);
-		for_each_cpu(i, cpu_core_mask(cpu)) {
-			if (i != cpu) {
-				err = pkgtemp_device_add(i);
-				if (!err)
-					break;
-			}
-		}
-		return;
-	}
-	mutex_unlock(&pdev_list_mutex);
-}
-
-static int __cpuinit pkgtemp_cpu_callback(struct notifier_block *nfb,
-				 unsigned long action, void *hcpu)
-{
-	unsigned int cpu = (unsigned long) hcpu;
-
-	switch (action) {
-	case CPU_ONLINE:
-	case CPU_DOWN_FAILED:
-		pkgtemp_device_add(cpu);
-		break;
-	case CPU_DOWN_PREPARE:
-		pkgtemp_device_remove(cpu);
-		break;
-	}
-	return NOTIFY_OK;
-}
-
-static struct notifier_block pkgtemp_cpu_notifier __refdata = {
-	.notifier_call = pkgtemp_cpu_callback,
-};
-
-static int __init pkgtemp_init(void)
-{
-	int i, err = -ENODEV;
-
-	/* quick check if we run Intel */
-	if (cpu_data(0).x86_vendor != X86_VENDOR_INTEL)
-		goto exit;
-
-	err = platform_driver_register(&pkgtemp_driver);
-	if (err)
-		goto exit;
-
-	for_each_online_cpu(i)
-		pkgtemp_device_add(i);
-
-#ifndef CONFIG_HOTPLUG_CPU
-	if (list_empty(&pdev_list)) {
-		err = -ENODEV;
-		goto exit_driver_unreg;
-	}
-#endif
-
-	register_hotcpu_notifier(&pkgtemp_cpu_notifier);
-	return 0;
-
-#ifndef CONFIG_HOTPLUG_CPU
-exit_driver_unreg:
-	platform_driver_unregister(&pkgtemp_driver);
-#endif
-exit:
-	return err;
-}
-
-static void __exit pkgtemp_exit(void)
-{
-	struct pdev_entry *p, *n;
-
-	unregister_hotcpu_notifier(&pkgtemp_cpu_notifier);
-	mutex_lock(&pdev_list_mutex);
-	list_for_each_entry_safe(p, n, &pdev_list, list) {
-		platform_device_unregister(p->pdev);
-		list_del(&p->list);
-		kfree(p);
-	}
-	mutex_unlock(&pdev_list_mutex);
-	platform_driver_unregister(&pkgtemp_driver);
-}
-
-MODULE_AUTHOR("Fenghua Yu <fenghua.yu@intel.com>");
-MODULE_DESCRIPTION("Intel processor package temperature monitor");
-MODULE_LICENSE("GPL");
-
-module_init(pkgtemp_init)
-module_exit(pkgtemp_exit)
diff -druN linux-2.6.39-libre/drivers/hwmon/pmbus.c linux-3.0-rc7-libre/drivers/hwmon/pmbus.c
--- linux-2.6.39-libre/drivers/hwmon/pmbus.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/hwmon/pmbus.c	2011-07-11 19:51:52.000000000 -0400
@@ -47,22 +47,29 @@
 	if (info->func[0]
 	    && pmbus_check_byte_register(client, 0, PMBUS_STATUS_INPUT))
 		info->func[0] |= PMBUS_HAVE_STATUS_INPUT;
-	if (pmbus_check_word_register(client, 0, PMBUS_READ_FAN_SPEED_1)) {
+	if (pmbus_check_byte_register(client, 0, PMBUS_FAN_CONFIG_12) &&
+	    pmbus_check_word_register(client, 0, PMBUS_READ_FAN_SPEED_1)) {
 		info->func[0] |= PMBUS_HAVE_FAN12;
 		if (pmbus_check_byte_register(client, 0, PMBUS_STATUS_FAN_12))
 			info->func[0] |= PMBUS_HAVE_STATUS_FAN12;
 	}
-	if (pmbus_check_word_register(client, 0, PMBUS_READ_FAN_SPEED_3)) {
+	if (pmbus_check_byte_register(client, 0, PMBUS_FAN_CONFIG_34) &&
+	    pmbus_check_word_register(client, 0, PMBUS_READ_FAN_SPEED_3)) {
 		info->func[0] |= PMBUS_HAVE_FAN34;
 		if (pmbus_check_byte_register(client, 0, PMBUS_STATUS_FAN_34))
 			info->func[0] |= PMBUS_HAVE_STATUS_FAN34;
 	}
-	if (pmbus_check_word_register(client, 0, PMBUS_READ_TEMPERATURE_1)) {
+	if (pmbus_check_word_register(client, 0, PMBUS_READ_TEMPERATURE_1))
 		info->func[0] |= PMBUS_HAVE_TEMP;
-		if (pmbus_check_byte_register(client, 0,
-					      PMBUS_STATUS_TEMPERATURE))
+	if (pmbus_check_word_register(client, 0, PMBUS_READ_TEMPERATURE_2))
+		info->func[0] |= PMBUS_HAVE_TEMP2;
+	if (pmbus_check_word_register(client, 0, PMBUS_READ_TEMPERATURE_3))
+		info->func[0] |= PMBUS_HAVE_TEMP3;
+	if (info->func[0] & (PMBUS_HAVE_TEMP | PMBUS_HAVE_TEMP2
+			     | PMBUS_HAVE_TEMP3)
+	    && pmbus_check_byte_register(client, 0,
+					 PMBUS_STATUS_TEMPERATURE))
 			info->func[0] |= PMBUS_HAVE_STATUS_TEMP;
-	}
 
 	/* Sensors detected on all pages */
 	for (page = 0; page < info->pages; page++) {
diff -druN linux-2.6.39-libre/drivers/hwmon/pmbus_core.c linux-3.0-rc7-libre/drivers/hwmon/pmbus_core.c
--- linux-2.6.39-libre/drivers/hwmon/pmbus_core.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/hwmon/pmbus_core.c	2011-07-11 19:51:52.000000000 -0400
@@ -270,18 +270,22 @@
 }
 EXPORT_SYMBOL_GPL(pmbus_get_driver_info);
 
-static int pmbus_get_status(struct i2c_client *client, int page, int reg)
+/*
+ * _pmbus_read_byte_data() is similar to pmbus_read_byte_data(), but checks if
+ * a device specific mapping funcion exists and calls it if necessary.
+ */
+static int _pmbus_read_byte_data(struct i2c_client *client, int page, int reg)
 {
 	struct pmbus_data *data = i2c_get_clientdata(client);
 	const struct pmbus_driver_info *info = data->info;
 	int status;
 
-	if (info->get_status) {
-		status = info->get_status(client, page, reg);
+	if (info->read_byte_data) {
+		status = info->read_byte_data(client, page, reg);
 		if (status != -ENODATA)
 			return status;
 	}
-	return  pmbus_read_byte_data(client, page, reg);
+	return pmbus_read_byte_data(client, page, reg);
 }
 
 static struct pmbus_data *pmbus_update_device(struct device *dev)
@@ -302,38 +306,41 @@
 			if (!(info->func[i] & PMBUS_HAVE_STATUS_VOUT))
 				continue;
 			data->status[PB_STATUS_VOUT_BASE + i]
-			  = pmbus_get_status(client, i, PMBUS_STATUS_VOUT);
+			  = _pmbus_read_byte_data(client, i, PMBUS_STATUS_VOUT);
 		}
 		for (i = 0; i < info->pages; i++) {
 			if (!(info->func[i] & PMBUS_HAVE_STATUS_IOUT))
 				continue;
 			data->status[PB_STATUS_IOUT_BASE + i]
-			  = pmbus_get_status(client, i, PMBUS_STATUS_IOUT);
+			  = _pmbus_read_byte_data(client, i, PMBUS_STATUS_IOUT);
 		}
 		for (i = 0; i < info->pages; i++) {
 			if (!(info->func[i] & PMBUS_HAVE_STATUS_TEMP))
 				continue;
 			data->status[PB_STATUS_TEMP_BASE + i]
-			  = pmbus_get_status(client, i,
-					     PMBUS_STATUS_TEMPERATURE);
+			  = _pmbus_read_byte_data(client, i,
+						  PMBUS_STATUS_TEMPERATURE);
 		}
 		for (i = 0; i < info->pages; i++) {
 			if (!(info->func[i] & PMBUS_HAVE_STATUS_FAN12))
 				continue;
 			data->status[PB_STATUS_FAN_BASE + i]
-			  = pmbus_get_status(client, i, PMBUS_STATUS_FAN_12);
+			  = _pmbus_read_byte_data(client, i,
+						  PMBUS_STATUS_FAN_12);
 		}
 
 		for (i = 0; i < info->pages; i++) {
 			if (!(info->func[i] & PMBUS_HAVE_STATUS_FAN34))
 				continue;
 			data->status[PB_STATUS_FAN34_BASE + i]
-			  = pmbus_get_status(client, i, PMBUS_STATUS_FAN_34);
+			  = _pmbus_read_byte_data(client, i,
+						  PMBUS_STATUS_FAN_34);
 		}
 
 		if (info->func[0] & PMBUS_HAVE_STATUS_INPUT)
 			data->status[PB_STATUS_INPUT_BASE]
-			  = pmbus_get_status(client, 0, PMBUS_STATUS_INPUT);
+			  = _pmbus_read_byte_data(client, 0,
+						  PMBUS_STATUS_INPUT);
 
 		for (i = 0; i < data->num_sensors; i++) {
 			struct pmbus_sensor *sensor = &data->sensors[i];
@@ -700,6 +707,7 @@
 	struct sensor_device_attribute *a				\
 	    = &data->_type##s[data->num_##_type##s].attribute;		\
 	BUG_ON(data->num_attributes >= data->max_attributes);		\
+	sysfs_attr_init(&a->dev_attr.attr);				\
 	a->dev_attr.attr.name = _name;					\
 	a->dev_attr.attr.mode = _mode;					\
 	a->dev_attr.show = _show;					\
@@ -793,53 +801,6 @@
 	data->num_labels++;
 }
 
-static const int pmbus_temp_registers[] = {
-	PMBUS_READ_TEMPERATURE_1,
-	PMBUS_READ_TEMPERATURE_2,
-	PMBUS_READ_TEMPERATURE_3
-};
-
-static const int pmbus_temp_flags[] = {
-	PMBUS_HAVE_TEMP,
-	PMBUS_HAVE_TEMP2,
-	PMBUS_HAVE_TEMP3
-};
-
-static const int pmbus_fan_registers[] = {
-	PMBUS_READ_FAN_SPEED_1,
-	PMBUS_READ_FAN_SPEED_2,
-	PMBUS_READ_FAN_SPEED_3,
-	PMBUS_READ_FAN_SPEED_4
-};
-
-static const int pmbus_fan_config_registers[] = {
-	PMBUS_FAN_CONFIG_12,
-	PMBUS_FAN_CONFIG_12,
-	PMBUS_FAN_CONFIG_34,
-	PMBUS_FAN_CONFIG_34
-};
-
-static const int pmbus_fan_status_registers[] = {
-	PMBUS_STATUS_FAN_12,
-	PMBUS_STATUS_FAN_12,
-	PMBUS_STATUS_FAN_34,
-	PMBUS_STATUS_FAN_34
-};
-
-static const u32 pmbus_fan_flags[] = {
-	PMBUS_HAVE_FAN12,
-	PMBUS_HAVE_FAN12,
-	PMBUS_HAVE_FAN34,
-	PMBUS_HAVE_FAN34
-};
-
-static const u32 pmbus_fan_status_flags[] = {
-	PMBUS_HAVE_STATUS_FAN12,
-	PMBUS_HAVE_STATUS_FAN12,
-	PMBUS_HAVE_STATUS_FAN34,
-	PMBUS_HAVE_STATUS_FAN34
-};
-
 /*
  * Determine maximum number of sensors, booleans, and labels.
  * To keep things simple, only make a rough high estimate.
@@ -900,499 +861,431 @@
 /*
  * Search for attributes. Allocate sensors, booleans, and labels as needed.
  */
-static void pmbus_find_attributes(struct i2c_client *client,
-				  struct pmbus_data *data)
-{
-	const struct pmbus_driver_info *info = data->info;
-	int page, i0, i1, in_index;
 
-	/*
-	 * Input voltage sensors
-	 */
-	in_index = 1;
-	if (info->func[0] & PMBUS_HAVE_VIN) {
-		bool have_alarm = false;
+/*
+ * The pmbus_limit_attr structure describes a single limit attribute
+ * and its associated alarm attribute.
+ */
+struct pmbus_limit_attr {
+	u8 reg;			/* Limit register */
+	const char *attr;	/* Attribute name */
+	const char *alarm;	/* Alarm attribute name */
+	u32 sbit;		/* Alarm attribute status bit */
+};
 
-		i0 = data->num_sensors;
-		pmbus_add_label(data, "in", in_index, "vin", 0);
-		pmbus_add_sensor(data, "in", "input", in_index, 0,
-				 PMBUS_READ_VIN, PSC_VOLTAGE_IN, true, true);
-		if (pmbus_check_word_register(client, 0,
-					      PMBUS_VIN_UV_WARN_LIMIT)) {
-			i1 = data->num_sensors;
-			pmbus_add_sensor(data, "in", "min", in_index,
-					 0, PMBUS_VIN_UV_WARN_LIMIT,
-					 PSC_VOLTAGE_IN, false, false);
-			if (info->func[0] & PMBUS_HAVE_STATUS_INPUT) {
-				pmbus_add_boolean_reg(data, "in", "min_alarm",
-						      in_index,
-						      PB_STATUS_INPUT_BASE,
-						      PB_VOLTAGE_UV_WARNING);
-				have_alarm = true;
-			}
-		}
-		if (pmbus_check_word_register(client, 0,
-					      PMBUS_VIN_UV_FAULT_LIMIT)) {
-			i1 = data->num_sensors;
-			pmbus_add_sensor(data, "in", "lcrit", in_index,
-					 0, PMBUS_VIN_UV_FAULT_LIMIT,
-					 PSC_VOLTAGE_IN, false, false);
-			if (info->func[0] & PMBUS_HAVE_STATUS_INPUT) {
-				pmbus_add_boolean_reg(data, "in", "lcrit_alarm",
-						      in_index,
-						      PB_STATUS_INPUT_BASE,
-						      PB_VOLTAGE_UV_FAULT);
-				have_alarm = true;
-			}
-		}
-		if (pmbus_check_word_register(client, 0,
-					      PMBUS_VIN_OV_WARN_LIMIT)) {
-			i1 = data->num_sensors;
-			pmbus_add_sensor(data, "in", "max", in_index,
-					 0, PMBUS_VIN_OV_WARN_LIMIT,
-					 PSC_VOLTAGE_IN, false, false);
-			if (info->func[0] & PMBUS_HAVE_STATUS_INPUT) {
-				pmbus_add_boolean_reg(data, "in", "max_alarm",
-						      in_index,
-						      PB_STATUS_INPUT_BASE,
-						      PB_VOLTAGE_OV_WARNING);
-				have_alarm = true;
-			}
-		}
-		if (pmbus_check_word_register(client, 0,
-					      PMBUS_VIN_OV_FAULT_LIMIT)) {
-			i1 = data->num_sensors;
-			pmbus_add_sensor(data, "in", "crit", in_index,
-					 0, PMBUS_VIN_OV_FAULT_LIMIT,
-					 PSC_VOLTAGE_IN, false, false);
-			if (info->func[0] & PMBUS_HAVE_STATUS_INPUT) {
-				pmbus_add_boolean_reg(data, "in", "crit_alarm",
-						      in_index,
-						      PB_STATUS_INPUT_BASE,
-						      PB_VOLTAGE_OV_FAULT);
+/*
+ * The pmbus_sensor_attr structure describes one sensor attribute. This
+ * description includes a reference to the associated limit attributes.
+ */
+struct pmbus_sensor_attr {
+	u8 reg;				/* sensor register */
+	enum pmbus_sensor_classes class;/* sensor class */
+	const char *label;		/* sensor label */
+	bool paged;			/* true if paged sensor */
+	bool update;			/* true if update needed */
+	bool compare;			/* true if compare function needed */
+	u32 func;			/* sensor mask */
+	u32 sfunc;			/* sensor status mask */
+	int sbase;			/* status base register */
+	u32 gbit;			/* generic status bit */
+	const struct pmbus_limit_attr *limit;/* limit registers */
+	int nlimit;			/* # of limit registers */
+};
+
+/*
+ * Add a set of limit attributes and, if supported, the associated
+ * alarm attributes.
+ */
+static bool pmbus_add_limit_attrs(struct i2c_client *client,
+				  struct pmbus_data *data,
+				  const struct pmbus_driver_info *info,
+				  const char *name, int index, int page,
+				  int cbase,
+				  const struct pmbus_sensor_attr *attr)
+{
+	const struct pmbus_limit_attr *l = attr->limit;
+	int nlimit = attr->nlimit;
+	bool have_alarm = false;
+	int i, cindex;
+
+	for (i = 0; i < nlimit; i++) {
+		if (pmbus_check_word_register(client, page, l->reg)) {
+			cindex = data->num_sensors;
+			pmbus_add_sensor(data, name, l->attr, index, page,
+					 l->reg, attr->class, attr->update,
+					 false);
+			if (info->func[page] & attr->sfunc) {
+				if (attr->compare) {
+					pmbus_add_boolean_cmp(data, name,
+						l->alarm, index,
+						cbase, cindex,
+						attr->sbase + page, l->sbit);
+				} else {
+					pmbus_add_boolean_reg(data, name,
+						l->alarm, index,
+						attr->sbase + page, l->sbit);
+				}
 				have_alarm = true;
 			}
 		}
-		/*
-		 * Add generic alarm attribute only if there are no individual
-		 * attributes.
-		 */
-		if (!have_alarm)
-			pmbus_add_boolean_reg(data, "in", "alarm",
-					      in_index,
-					      PB_STATUS_BASE,
-					      PB_STATUS_VIN_UV);
-		in_index++;
-	}
-	if (info->func[0] & PMBUS_HAVE_VCAP) {
-		pmbus_add_label(data, "in", in_index, "vcap", 0);
-		pmbus_add_sensor(data, "in", "input", in_index, 0,
-				 PMBUS_READ_VCAP, PSC_VOLTAGE_IN, true, true);
-		in_index++;
+		l++;
 	}
+	return have_alarm;
+}
 
-	/*
-	 * Output voltage sensors
-	 */
-	for (page = 0; page < info->pages; page++) {
-		bool have_alarm = false;
-
-		if (!(info->func[page] & PMBUS_HAVE_VOUT))
-			continue;
+static void pmbus_add_sensor_attrs_one(struct i2c_client *client,
+				       struct pmbus_data *data,
+				       const struct pmbus_driver_info *info,
+				       const char *name,
+				       int index, int page,
+				       const struct pmbus_sensor_attr *attr)
+{
+	bool have_alarm;
+	int cbase = data->num_sensors;
 
-		i0 = data->num_sensors;
-		pmbus_add_label(data, "in", in_index, "vout", page + 1);
-		pmbus_add_sensor(data, "in", "input", in_index, page,
-				 PMBUS_READ_VOUT, PSC_VOLTAGE_OUT, true, true);
-		if (pmbus_check_word_register(client, page,
-					      PMBUS_VOUT_UV_WARN_LIMIT)) {
-			i1 = data->num_sensors;
-			pmbus_add_sensor(data, "in", "min", in_index, page,
-					 PMBUS_VOUT_UV_WARN_LIMIT,
-					 PSC_VOLTAGE_OUT, false, false);
-			if (info->func[page] & PMBUS_HAVE_STATUS_VOUT) {
-				pmbus_add_boolean_reg(data, "in", "min_alarm",
-						      in_index,
-						      PB_STATUS_VOUT_BASE +
-						      page,
-						      PB_VOLTAGE_UV_WARNING);
-				have_alarm = true;
-			}
-		}
-		if (pmbus_check_word_register(client, page,
-					      PMBUS_VOUT_UV_FAULT_LIMIT)) {
-			i1 = data->num_sensors;
-			pmbus_add_sensor(data, "in", "lcrit", in_index, page,
-					 PMBUS_VOUT_UV_FAULT_LIMIT,
-					 PSC_VOLTAGE_OUT, false, false);
-			if (info->func[page] & PMBUS_HAVE_STATUS_VOUT) {
-				pmbus_add_boolean_reg(data, "in", "lcrit_alarm",
-						      in_index,
-						      PB_STATUS_VOUT_BASE +
-						      page,
-						      PB_VOLTAGE_UV_FAULT);
-				have_alarm = true;
-			}
-		}
-		if (pmbus_check_word_register(client, page,
-					      PMBUS_VOUT_OV_WARN_LIMIT)) {
-			i1 = data->num_sensors;
-			pmbus_add_sensor(data, "in", "max", in_index, page,
-					 PMBUS_VOUT_OV_WARN_LIMIT,
-					 PSC_VOLTAGE_OUT, false, false);
-			if (info->func[page] & PMBUS_HAVE_STATUS_VOUT) {
-				pmbus_add_boolean_reg(data, "in", "max_alarm",
-						      in_index,
-						      PB_STATUS_VOUT_BASE +
-						      page,
-						      PB_VOLTAGE_OV_WARNING);
-				have_alarm = true;
-			}
-		}
-		if (pmbus_check_word_register(client, page,
-					      PMBUS_VOUT_OV_FAULT_LIMIT)) {
-			i1 = data->num_sensors;
-			pmbus_add_sensor(data, "in", "crit", in_index, page,
-					 PMBUS_VOUT_OV_FAULT_LIMIT,
-					 PSC_VOLTAGE_OUT, false, false);
-			if (info->func[page] & PMBUS_HAVE_STATUS_VOUT) {
-				pmbus_add_boolean_reg(data, "in", "crit_alarm",
-						      in_index,
-						      PB_STATUS_VOUT_BASE +
-						      page,
-						      PB_VOLTAGE_OV_FAULT);
-				have_alarm = true;
-			}
-		}
+	if (attr->label)
+		pmbus_add_label(data, name, index, attr->label,
+				attr->paged ? page + 1 : 0);
+	pmbus_add_sensor(data, name, "input", index, page, attr->reg,
+			 attr->class, true, true);
+	if (attr->sfunc) {
+		have_alarm = pmbus_add_limit_attrs(client, data, info, name,
+						   index, page, cbase, attr);
 		/*
 		 * Add generic alarm attribute only if there are no individual
-		 * attributes.
+		 * alarm attributes, and if there is a global alarm bit.
 		 */
-		if (!have_alarm)
-			pmbus_add_boolean_reg(data, "in", "alarm",
-					      in_index,
+		if (!have_alarm && attr->gbit)
+			pmbus_add_boolean_reg(data, name, "alarm", index,
 					      PB_STATUS_BASE + page,
-					      PB_STATUS_VOUT_OV);
-		in_index++;
+					      attr->gbit);
 	}
+}
 
-	/*
-	 * Current sensors
-	 */
+static void pmbus_add_sensor_attrs(struct i2c_client *client,
+				   struct pmbus_data *data,
+				   const char *name,
+				   const struct pmbus_sensor_attr *attrs,
+				   int nattrs)
+{
+	const struct pmbus_driver_info *info = data->info;
+	int index, i;
 
-	/*
-	 * Input current sensors
-	 */
-	in_index = 1;
-	if (info->func[0] & PMBUS_HAVE_IIN) {
-		i0 = data->num_sensors;
-		pmbus_add_label(data, "curr", in_index, "iin", 0);
-		pmbus_add_sensor(data, "curr", "input", in_index, 0,
-				 PMBUS_READ_IIN, PSC_CURRENT_IN, true, true);
-		if (pmbus_check_word_register(client, 0,
-					      PMBUS_IIN_OC_WARN_LIMIT)) {
-			i1 = data->num_sensors;
-			pmbus_add_sensor(data, "curr", "max", in_index,
-					 0, PMBUS_IIN_OC_WARN_LIMIT,
-					 PSC_CURRENT_IN, false, false);
-			if (info->func[0] & PMBUS_HAVE_STATUS_INPUT) {
-				pmbus_add_boolean_reg(data, "curr", "max_alarm",
-						      in_index,
-						      PB_STATUS_INPUT_BASE,
-						      PB_IIN_OC_WARNING);
-			}
-		}
-		if (pmbus_check_word_register(client, 0,
-					      PMBUS_IIN_OC_FAULT_LIMIT)) {
-			i1 = data->num_sensors;
-			pmbus_add_sensor(data, "curr", "crit", in_index,
-					 0, PMBUS_IIN_OC_FAULT_LIMIT,
-					 PSC_CURRENT_IN, false, false);
-			if (info->func[0] & PMBUS_HAVE_STATUS_INPUT)
-				pmbus_add_boolean_reg(data, "curr",
-						      "crit_alarm",
-						      in_index,
-						      PB_STATUS_INPUT_BASE,
-						      PB_IIN_OC_FAULT);
+	index = 1;
+	for (i = 0; i < nattrs; i++) {
+		int page, pages;
+
+		pages = attrs->paged ? info->pages : 1;
+		for (page = 0; page < pages; page++) {
+			if (!(info->func[page] & attrs->func))
+				continue;
+			pmbus_add_sensor_attrs_one(client, data, info, name,
+						   index, page, attrs);
+			index++;
 		}
-		in_index++;
+		attrs++;
 	}
+}
 
-	/*
-	 * Output current sensors
-	 */
-	for (page = 0; page < info->pages; page++) {
-		bool have_alarm = false;
-
-		if (!(info->func[page] & PMBUS_HAVE_IOUT))
-			continue;
+static const struct pmbus_limit_attr vin_limit_attrs[] = {
+	{
+		.reg = PMBUS_VIN_UV_WARN_LIMIT,
+		.attr = "min",
+		.alarm = "min_alarm",
+		.sbit = PB_VOLTAGE_UV_WARNING,
+	}, {
+		.reg = PMBUS_VIN_UV_FAULT_LIMIT,
+		.attr = "lcrit",
+		.alarm = "lcrit_alarm",
+		.sbit = PB_VOLTAGE_UV_FAULT,
+	}, {
+		.reg = PMBUS_VIN_OV_WARN_LIMIT,
+		.attr = "max",
+		.alarm = "max_alarm",
+		.sbit = PB_VOLTAGE_OV_WARNING,
+	}, {
+		.reg = PMBUS_VIN_OV_FAULT_LIMIT,
+		.attr = "crit",
+		.alarm = "crit_alarm",
+		.sbit = PB_VOLTAGE_OV_FAULT,
+	},
+};
 
-		i0 = data->num_sensors;
-		pmbus_add_label(data, "curr", in_index, "iout", page + 1);
-		pmbus_add_sensor(data, "curr", "input", in_index, page,
-				 PMBUS_READ_IOUT, PSC_CURRENT_OUT, true, true);
-		if (pmbus_check_word_register(client, page,
-					      PMBUS_IOUT_OC_WARN_LIMIT)) {
-			i1 = data->num_sensors;
-			pmbus_add_sensor(data, "curr", "max", in_index, page,
-					 PMBUS_IOUT_OC_WARN_LIMIT,
-					 PSC_CURRENT_OUT, false, false);
-			if (info->func[page] & PMBUS_HAVE_STATUS_IOUT) {
-				pmbus_add_boolean_reg(data, "curr", "max_alarm",
-						      in_index,
-						      PB_STATUS_IOUT_BASE +
-						      page, PB_IOUT_OC_WARNING);
-				have_alarm = true;
-			}
-		}
-		if (pmbus_check_word_register(client, page,
-					      PMBUS_IOUT_UC_FAULT_LIMIT)) {
-			i1 = data->num_sensors;
-			pmbus_add_sensor(data, "curr", "lcrit", in_index, page,
-					 PMBUS_IOUT_UC_FAULT_LIMIT,
-					 PSC_CURRENT_OUT, false, false);
-			if (info->func[page] & PMBUS_HAVE_STATUS_IOUT) {
-				pmbus_add_boolean_reg(data, "curr",
-						      "lcrit_alarm",
-						      in_index,
-						      PB_STATUS_IOUT_BASE +
-						      page, PB_IOUT_UC_FAULT);
-				have_alarm = true;
-			}
-		}
-		if (pmbus_check_word_register(client, page,
-					      PMBUS_IOUT_OC_FAULT_LIMIT)) {
-			i1 = data->num_sensors;
-			pmbus_add_sensor(data, "curr", "crit", in_index, page,
-					 PMBUS_IOUT_OC_FAULT_LIMIT,
-					 PSC_CURRENT_OUT, false, false);
-			if (info->func[page] & PMBUS_HAVE_STATUS_IOUT) {
-				pmbus_add_boolean_reg(data, "curr",
-						      "crit_alarm",
-						      in_index,
-						      PB_STATUS_IOUT_BASE +
-						      page, PB_IOUT_OC_FAULT);
-				have_alarm = true;
-			}
-		}
-		/*
-		 * Add generic alarm attribute only if there are no individual
-		 * attributes.
-		 */
-		if (!have_alarm)
-			pmbus_add_boolean_reg(data, "curr", "alarm",
-					      in_index,
-					      PB_STATUS_BASE + page,
-					      PB_STATUS_IOUT_OC);
-		in_index++;
+static const struct pmbus_limit_attr vout_limit_attrs[] = {
+	{
+		.reg = PMBUS_VOUT_UV_WARN_LIMIT,
+		.attr = "min",
+		.alarm = "min_alarm",
+		.sbit = PB_VOLTAGE_UV_WARNING,
+	}, {
+		.reg = PMBUS_VOUT_UV_FAULT_LIMIT,
+		.attr = "lcrit",
+		.alarm = "lcrit_alarm",
+		.sbit = PB_VOLTAGE_UV_FAULT,
+	}, {
+		.reg = PMBUS_VOUT_OV_WARN_LIMIT,
+		.attr = "max",
+		.alarm = "max_alarm",
+		.sbit = PB_VOLTAGE_OV_WARNING,
+	}, {
+		.reg = PMBUS_VOUT_OV_FAULT_LIMIT,
+		.attr = "crit",
+		.alarm = "crit_alarm",
+		.sbit = PB_VOLTAGE_OV_FAULT,
 	}
+};
 
-	/*
-	 * Power sensors
-	 */
-	/*
-	 * Input Power sensors
-	 */
-	in_index = 1;
-	if (info->func[0] & PMBUS_HAVE_PIN) {
-		i0 = data->num_sensors;
-		pmbus_add_label(data, "power", in_index, "pin", 0);
-		pmbus_add_sensor(data, "power", "input", in_index,
-				 0, PMBUS_READ_PIN, PSC_POWER, true, true);
-		if (pmbus_check_word_register(client, 0,
-					      PMBUS_PIN_OP_WARN_LIMIT)) {
-			i1 = data->num_sensors;
-			pmbus_add_sensor(data, "power", "max", in_index,
-					 0, PMBUS_PIN_OP_WARN_LIMIT, PSC_POWER,
-					 false, false);
-			if (info->func[0] & PMBUS_HAVE_STATUS_INPUT)
-				pmbus_add_boolean_reg(data, "power",
-						      "alarm",
-						      in_index,
-						      PB_STATUS_INPUT_BASE,
-						      PB_PIN_OP_WARNING);
-		}
-		in_index++;
+static const struct pmbus_sensor_attr voltage_attributes[] = {
+	{
+		.reg = PMBUS_READ_VIN,
+		.class = PSC_VOLTAGE_IN,
+		.label = "vin",
+		.func = PMBUS_HAVE_VIN,
+		.sfunc = PMBUS_HAVE_STATUS_INPUT,
+		.sbase = PB_STATUS_INPUT_BASE,
+		.gbit = PB_STATUS_VIN_UV,
+		.limit = vin_limit_attrs,
+		.nlimit = ARRAY_SIZE(vin_limit_attrs),
+	}, {
+		.reg = PMBUS_READ_VCAP,
+		.class = PSC_VOLTAGE_IN,
+		.label = "vcap",
+		.func = PMBUS_HAVE_VCAP,
+	}, {
+		.reg = PMBUS_READ_VOUT,
+		.class = PSC_VOLTAGE_OUT,
+		.label = "vout",
+		.paged = true,
+		.func = PMBUS_HAVE_VOUT,
+		.sfunc = PMBUS_HAVE_STATUS_VOUT,
+		.sbase = PB_STATUS_VOUT_BASE,
+		.gbit = PB_STATUS_VOUT_OV,
+		.limit = vout_limit_attrs,
+		.nlimit = ARRAY_SIZE(vout_limit_attrs),
 	}
+};
 
-	/*
-	 * Output Power sensors
-	 */
-	for (page = 0; page < info->pages; page++) {
-		bool need_alarm = false;
+/* Current attributes */
 
-		if (!(info->func[page] & PMBUS_HAVE_POUT))
-			continue;
+static const struct pmbus_limit_attr iin_limit_attrs[] = {
+	{
+		.reg = PMBUS_IIN_OC_WARN_LIMIT,
+		.attr = "max",
+		.alarm = "max_alarm",
+		.sbit = PB_IIN_OC_WARNING,
+	}, {
+		.reg = PMBUS_IIN_OC_FAULT_LIMIT,
+		.attr = "crit",
+		.alarm = "crit_alarm",
+		.sbit = PB_IIN_OC_FAULT,
+	}
+};
 
-		i0 = data->num_sensors;
-		pmbus_add_label(data, "power", in_index, "pout", page + 1);
-		pmbus_add_sensor(data, "power", "input", in_index, page,
-				 PMBUS_READ_POUT, PSC_POWER, true, true);
-		/*
-		 * Per hwmon sysfs API, power_cap is to be used to limit output
-		 * power.
-		 * We have two registers related to maximum output power,
-		 * PMBUS_POUT_MAX and PMBUS_POUT_OP_WARN_LIMIT.
-		 * PMBUS_POUT_MAX matches the powerX_cap attribute definition.
-		 * There is no attribute in the API to match
-		 * PMBUS_POUT_OP_WARN_LIMIT. We use powerX_max for now.
-		 */
-		if (pmbus_check_word_register(client, page, PMBUS_POUT_MAX)) {
-			i1 = data->num_sensors;
-			pmbus_add_sensor(data, "power", "cap", in_index, page,
-					 PMBUS_POUT_MAX, PSC_POWER,
-					 false, false);
-			need_alarm = true;
-		}
-		if (pmbus_check_word_register(client, page,
-					      PMBUS_POUT_OP_WARN_LIMIT)) {
-			i1 = data->num_sensors;
-			pmbus_add_sensor(data, "power", "max", in_index, page,
-					 PMBUS_POUT_OP_WARN_LIMIT, PSC_POWER,
-					 false, false);
-			need_alarm = true;
-		}
-		if (need_alarm && (info->func[page] & PMBUS_HAVE_STATUS_IOUT))
-			pmbus_add_boolean_reg(data, "power", "alarm",
-					      in_index,
-					      PB_STATUS_IOUT_BASE + page,
-					      PB_POUT_OP_WARNING
-					      | PB_POWER_LIMITING);
+static const struct pmbus_limit_attr iout_limit_attrs[] = {
+	{
+		.reg = PMBUS_IOUT_OC_WARN_LIMIT,
+		.attr = "max",
+		.alarm = "max_alarm",
+		.sbit = PB_IOUT_OC_WARNING,
+	}, {
+		.reg = PMBUS_IOUT_UC_FAULT_LIMIT,
+		.attr = "lcrit",
+		.alarm = "lcrit_alarm",
+		.sbit = PB_IOUT_UC_FAULT,
+	}, {
+		.reg = PMBUS_IOUT_OC_FAULT_LIMIT,
+		.attr = "crit",
+		.alarm = "crit_alarm",
+		.sbit = PB_IOUT_OC_FAULT,
+	}
+};
 
-		if (pmbus_check_word_register(client, page,
-					      PMBUS_POUT_OP_FAULT_LIMIT)) {
-			i1 = data->num_sensors;
-			pmbus_add_sensor(data, "power", "crit", in_index, page,
-					 PMBUS_POUT_OP_FAULT_LIMIT, PSC_POWER,
-					 false, false);
-			if (info->func[page] & PMBUS_HAVE_STATUS_IOUT)
-				pmbus_add_boolean_reg(data, "power",
-						      "crit_alarm",
-						      in_index,
-						      PB_STATUS_IOUT_BASE
-						      + page,
-						      PB_POUT_OP_FAULT);
-		}
-		in_index++;
+static const struct pmbus_sensor_attr current_attributes[] = {
+	{
+		.reg = PMBUS_READ_IIN,
+		.class = PSC_CURRENT_IN,
+		.label = "iin",
+		.func = PMBUS_HAVE_IIN,
+		.sfunc = PMBUS_HAVE_STATUS_INPUT,
+		.sbase = PB_STATUS_INPUT_BASE,
+		.limit = iin_limit_attrs,
+		.nlimit = ARRAY_SIZE(iin_limit_attrs),
+	}, {
+		.reg = PMBUS_READ_IOUT,
+		.class = PSC_CURRENT_OUT,
+		.label = "iout",
+		.paged = true,
+		.func = PMBUS_HAVE_IOUT,
+		.sfunc = PMBUS_HAVE_STATUS_IOUT,
+		.sbase = PB_STATUS_IOUT_BASE,
+		.gbit = PB_STATUS_IOUT_OC,
+		.limit = iout_limit_attrs,
+		.nlimit = ARRAY_SIZE(iout_limit_attrs),
 	}
+};
 
-	/*
-	 * Temperature sensors
-	 */
-	in_index = 1;
-	for (page = 0; page < info->pages; page++) {
-		int t;
+/* Power attributes */
 
-		for (t = 0; t < ARRAY_SIZE(pmbus_temp_registers); t++) {
-			bool have_alarm = false;
+static const struct pmbus_limit_attr pin_limit_attrs[] = {
+	{
+		.reg = PMBUS_PIN_OP_WARN_LIMIT,
+		.attr = "max",
+		.alarm = "alarm",
+		.sbit = PB_PIN_OP_WARNING,
+	}
+};
 
-			/*
-			 * A PMBus chip may support any combination of
-			 * temperature registers on any page. So we can not
-			 * abort after a failure to detect a register, but have
-			 * to continue checking for all registers on all pages.
-			 */
-			if (!(info->func[page] & pmbus_temp_flags[t]))
-				continue;
+static const struct pmbus_limit_attr pout_limit_attrs[] = {
+	{
+		.reg = PMBUS_POUT_MAX,
+		.attr = "cap",
+		.alarm = "cap_alarm",
+		.sbit = PB_POWER_LIMITING,
+	}, {
+		.reg = PMBUS_POUT_OP_WARN_LIMIT,
+		.attr = "max",
+		.alarm = "max_alarm",
+		.sbit = PB_POUT_OP_WARNING,
+	}, {
+		.reg = PMBUS_POUT_OP_FAULT_LIMIT,
+		.attr = "crit",
+		.alarm = "crit_alarm",
+		.sbit = PB_POUT_OP_FAULT,
+	}
+};
 
-			if (!pmbus_check_word_register
-			    (client, page, pmbus_temp_registers[t]))
-				continue;
+static const struct pmbus_sensor_attr power_attributes[] = {
+	{
+		.reg = PMBUS_READ_PIN,
+		.class = PSC_POWER,
+		.label = "pin",
+		.func = PMBUS_HAVE_PIN,
+		.sfunc = PMBUS_HAVE_STATUS_INPUT,
+		.sbase = PB_STATUS_INPUT_BASE,
+		.limit = pin_limit_attrs,
+		.nlimit = ARRAY_SIZE(pin_limit_attrs),
+	}, {
+		.reg = PMBUS_READ_POUT,
+		.class = PSC_POWER,
+		.label = "pout",
+		.paged = true,
+		.func = PMBUS_HAVE_POUT,
+		.sfunc = PMBUS_HAVE_STATUS_IOUT,
+		.sbase = PB_STATUS_IOUT_BASE,
+		.limit = pout_limit_attrs,
+		.nlimit = ARRAY_SIZE(pout_limit_attrs),
+	}
+};
 
-			i0 = data->num_sensors;
-			pmbus_add_sensor(data, "temp", "input", in_index, page,
-					 pmbus_temp_registers[t],
-					 PSC_TEMPERATURE, true, true);
+/* Temperature atributes */
 
-			/*
-			 * PMBus provides only one status register for TEMP1-3.
-			 * Thus, we can not use the status register to determine
-			 * which of the three sensors actually caused an alarm.
-			 * Always compare current temperature against the limit
-			 * registers to determine alarm conditions for a
-			 * specific sensor.
-			 *
-			 * Since there is only one set of limit registers for
-			 * up to three temperature sensors, we need to update
-			 * all limit registers after the limit was changed for
-			 * one of the sensors. This ensures that correct limits
-			 * are reported for all temperature sensors.
-			 */
-			if (pmbus_check_word_register
-			    (client, page, PMBUS_UT_WARN_LIMIT)) {
-				i1 = data->num_sensors;
-				pmbus_add_sensor(data, "temp", "min", in_index,
-						 page, PMBUS_UT_WARN_LIMIT,
-						 PSC_TEMPERATURE, true, false);
-				if (info->func[page] & PMBUS_HAVE_STATUS_TEMP) {
-					pmbus_add_boolean_cmp(data, "temp",
-						"min_alarm", in_index, i1, i0,
-						PB_STATUS_TEMP_BASE + page,
-						PB_TEMP_UT_WARNING);
-					have_alarm = true;
-				}
-			}
-			if (pmbus_check_word_register(client, page,
-						      PMBUS_UT_FAULT_LIMIT)) {
-				i1 = data->num_sensors;
-				pmbus_add_sensor(data, "temp", "lcrit",
-						 in_index, page,
-						 PMBUS_UT_FAULT_LIMIT,
-						 PSC_TEMPERATURE, true, false);
-				if (info->func[page] & PMBUS_HAVE_STATUS_TEMP) {
-					pmbus_add_boolean_cmp(data, "temp",
-						"lcrit_alarm", in_index, i1, i0,
-						PB_STATUS_TEMP_BASE + page,
-						PB_TEMP_UT_FAULT);
-					have_alarm = true;
-				}
-			}
-			if (pmbus_check_word_register
-			    (client, page, PMBUS_OT_WARN_LIMIT)) {
-				i1 = data->num_sensors;
-				pmbus_add_sensor(data, "temp", "max", in_index,
-						 page, PMBUS_OT_WARN_LIMIT,
-						 PSC_TEMPERATURE, true, false);
-				if (info->func[page] & PMBUS_HAVE_STATUS_TEMP) {
-					pmbus_add_boolean_cmp(data, "temp",
-						"max_alarm", in_index, i0, i1,
-						PB_STATUS_TEMP_BASE + page,
-						PB_TEMP_OT_WARNING);
-					have_alarm = true;
-				}
-			}
-			if (pmbus_check_word_register(client, page,
-						      PMBUS_OT_FAULT_LIMIT)) {
-				i1 = data->num_sensors;
-				pmbus_add_sensor(data, "temp", "crit", in_index,
-						 page, PMBUS_OT_FAULT_LIMIT,
-						 PSC_TEMPERATURE, true, false);
-				if (info->func[page] & PMBUS_HAVE_STATUS_TEMP) {
-					pmbus_add_boolean_cmp(data, "temp",
-						"crit_alarm", in_index, i0, i1,
-						PB_STATUS_TEMP_BASE + page,
-						PB_TEMP_OT_FAULT);
-					have_alarm = true;
-				}
-			}
-			/*
-			 * Last resort - we were not able to create any alarm
-			 * registers. Report alarm for all sensors using the
-			 * status register temperature alarm bit.
-			 */
-			if (!have_alarm)
-				pmbus_add_boolean_reg(data, "temp", "alarm",
-						      in_index,
-						      PB_STATUS_BASE + page,
-						      PB_STATUS_TEMPERATURE);
-			in_index++;
-		}
+static const struct pmbus_limit_attr temp_limit_attrs[] = {
+	{
+		.reg = PMBUS_UT_WARN_LIMIT,
+		.attr = "min",
+		.alarm = "min_alarm",
+		.sbit = PB_TEMP_UT_WARNING,
+	}, {
+		.reg = PMBUS_UT_FAULT_LIMIT,
+		.attr = "lcrit",
+		.alarm = "lcrit_alarm",
+		.sbit = PB_TEMP_UT_FAULT,
+	}, {
+		.reg = PMBUS_OT_WARN_LIMIT,
+		.attr = "max",
+		.alarm = "max_alarm",
+		.sbit = PB_TEMP_OT_WARNING,
+	}, {
+		.reg = PMBUS_OT_FAULT_LIMIT,
+		.attr = "crit",
+		.alarm = "crit_alarm",
+		.sbit = PB_TEMP_OT_FAULT,
 	}
+};
+
+static const struct pmbus_sensor_attr temp_attributes[] = {
+	{
+		.reg = PMBUS_READ_TEMPERATURE_1,
+		.class = PSC_TEMPERATURE,
+		.paged = true,
+		.update = true,
+		.compare = true,
+		.func = PMBUS_HAVE_TEMP,
+		.sfunc = PMBUS_HAVE_STATUS_TEMP,
+		.sbase = PB_STATUS_TEMP_BASE,
+		.gbit = PB_STATUS_TEMPERATURE,
+		.limit = temp_limit_attrs,
+		.nlimit = ARRAY_SIZE(temp_limit_attrs),
+	}, {
+		.reg = PMBUS_READ_TEMPERATURE_2,
+		.class = PSC_TEMPERATURE,
+		.paged = true,
+		.update = true,
+		.compare = true,
+		.func = PMBUS_HAVE_TEMP2,
+		.sfunc = PMBUS_HAVE_STATUS_TEMP,
+		.sbase = PB_STATUS_TEMP_BASE,
+		.gbit = PB_STATUS_TEMPERATURE,
+		.limit = temp_limit_attrs,
+		.nlimit = ARRAY_SIZE(temp_limit_attrs),
+	}, {
+		.reg = PMBUS_READ_TEMPERATURE_3,
+		.class = PSC_TEMPERATURE,
+		.paged = true,
+		.update = true,
+		.compare = true,
+		.func = PMBUS_HAVE_TEMP3,
+		.sfunc = PMBUS_HAVE_STATUS_TEMP,
+		.sbase = PB_STATUS_TEMP_BASE,
+		.gbit = PB_STATUS_TEMPERATURE,
+		.limit = temp_limit_attrs,
+		.nlimit = ARRAY_SIZE(temp_limit_attrs),
+	}
+};
+
+static const int pmbus_fan_registers[] = {
+	PMBUS_READ_FAN_SPEED_1,
+	PMBUS_READ_FAN_SPEED_2,
+	PMBUS_READ_FAN_SPEED_3,
+	PMBUS_READ_FAN_SPEED_4
+};
+
+static const int pmbus_fan_config_registers[] = {
+	PMBUS_FAN_CONFIG_12,
+	PMBUS_FAN_CONFIG_12,
+	PMBUS_FAN_CONFIG_34,
+	PMBUS_FAN_CONFIG_34
+};
+
+static const int pmbus_fan_status_registers[] = {
+	PMBUS_STATUS_FAN_12,
+	PMBUS_STATUS_FAN_12,
+	PMBUS_STATUS_FAN_34,
+	PMBUS_STATUS_FAN_34
+};
+
+static const u32 pmbus_fan_flags[] = {
+	PMBUS_HAVE_FAN12,
+	PMBUS_HAVE_FAN12,
+	PMBUS_HAVE_FAN34,
+	PMBUS_HAVE_FAN34
+};
+
+static const u32 pmbus_fan_status_flags[] = {
+	PMBUS_HAVE_STATUS_FAN12,
+	PMBUS_HAVE_STATUS_FAN12,
+	PMBUS_HAVE_STATUS_FAN34,
+	PMBUS_HAVE_STATUS_FAN34
+};
+
+/* Fans */
+static void pmbus_add_fan_attributes(struct i2c_client *client,
+				     struct pmbus_data *data)
+{
+	const struct pmbus_driver_info *info = data->info;
+	int index = 1;
+	int page;
 
-	/*
-	 * Fans
-	 */
-	in_index = 1;
 	for (page = 0; page < info->pages; page++) {
 		int f;
 
@@ -1403,9 +1296,7 @@
 				break;
 
 			if (!pmbus_check_word_register(client, page,
-						       pmbus_fan_registers[f])
-			    || !pmbus_check_byte_register(client, page,
-						pmbus_fan_config_registers[f]))
+						       pmbus_fan_registers[f]))
 				break;
 
 			/*
@@ -1413,14 +1304,13 @@
 			 * Each fan configuration register covers multiple fans,
 			 * so we have to do some magic.
 			 */
-			regval = pmbus_read_byte_data(client, page,
+			regval = _pmbus_read_byte_data(client, page,
 				pmbus_fan_config_registers[f]);
 			if (regval < 0 ||
 			    (!(regval & (PB_FAN_1_INSTALLED >> ((f & 1) * 4)))))
 				continue;
 
-			i0 = data->num_sensors;
-			pmbus_add_sensor(data, "fan", "input", in_index, page,
+			pmbus_add_sensor(data, "fan", "input", index, page,
 					 pmbus_fan_registers[f], PSC_FAN, true,
 					 true);
 
@@ -1438,17 +1328,40 @@
 				else
 					base = PB_STATUS_FAN_BASE + page;
 				pmbus_add_boolean_reg(data, "fan", "alarm",
-					in_index, base,
+					index, base,
 					PB_FAN_FAN1_WARNING >> (f & 1));
 				pmbus_add_boolean_reg(data, "fan", "fault",
-					in_index, base,
+					index, base,
 					PB_FAN_FAN1_FAULT >> (f & 1));
 			}
-			in_index++;
+			index++;
 		}
 	}
 }
 
+static void pmbus_find_attributes(struct i2c_client *client,
+				  struct pmbus_data *data)
+{
+	/* Voltage sensors */
+	pmbus_add_sensor_attrs(client, data, "in", voltage_attributes,
+			       ARRAY_SIZE(voltage_attributes));
+
+	/* Current sensors */
+	pmbus_add_sensor_attrs(client, data, "curr", current_attributes,
+			       ARRAY_SIZE(current_attributes));
+
+	/* Power sensors */
+	pmbus_add_sensor_attrs(client, data, "power", power_attributes,
+			       ARRAY_SIZE(power_attributes));
+
+	/* Temperature sensors */
+	pmbus_add_sensor_attrs(client, data, "temp", temp_attributes,
+			       ARRAY_SIZE(temp_attributes));
+
+	/* Fans */
+	pmbus_add_fan_attributes(client, data);
+}
+
 /*
  * Identify chip parameters.
  * This function is called for all chips.
@@ -1517,14 +1430,9 @@
 	i2c_set_clientdata(client, data);
 	mutex_init(&data->update_lock);
 
-	/*
-	 * Bail out if status register or PMBus revision register
-	 * does not exist.
-	 */
-	if (i2c_smbus_read_byte_data(client, PMBUS_STATUS_BYTE) < 0
-	    || i2c_smbus_read_byte_data(client, PMBUS_REVISION) < 0) {
-		dev_err(&client->dev,
-			"Status or revision register not found\n");
+	/* Bail out if PMBus status register does not exist. */
+	if (i2c_smbus_read_byte_data(client, PMBUS_STATUS_BYTE) < 0) {
+		dev_err(&client->dev, "PMBus status register not found\n");
 		ret = -ENODEV;
 		goto out_data;
 	}
diff -druN linux-2.6.39-libre/drivers/hwmon/pmbus.h linux-3.0-rc7-libre/drivers/hwmon/pmbus.h
--- linux-2.6.39-libre/drivers/hwmon/pmbus.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/hwmon/pmbus.h	2011-07-11 19:51:52.000000000 -0400
@@ -281,13 +281,11 @@
 
 	u32 func[PMBUS_PAGES];	/* Functionality, per page */
 	/*
-	 * The get_status function maps manufacturing specific status values
-	 * into PMBus standard status values.
-	 * This function is optional and only necessary if chip specific status
-	 * register values have to be mapped into standard PMBus status register
-	 * values.
+	 * The following functions map manufacturing specific register values
+	 * to PMBus standard register values. Specify only if mapping is
+	 * necessary.
 	 */
-	int (*get_status)(struct i2c_client *client, int page, int reg);
+	int (*read_byte_data)(struct i2c_client *client, int page, int reg);
 	/*
 	 * The identify function determines supported PMBus functionality.
 	 * This function is only necessary if a chip driver supports multiple
diff -druN linux-2.6.39-libre/drivers/hwmon/s3c-hwmon.c linux-3.0-rc7-libre/drivers/hwmon/s3c-hwmon.c
--- linux-2.6.39-libre/drivers/hwmon/s3c-hwmon.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/hwmon/s3c-hwmon.c	2011-07-11 19:51:52.000000000 -0400
@@ -232,6 +232,7 @@
 
 	attr = &attrs->in;
 	attr->index = channel;
+	sysfs_attr_init(&attr->dev_attr.attr);
 	attr->dev_attr.attr.name  = attrs->in_name;
 	attr->dev_attr.attr.mode  = S_IRUGO;
 	attr->dev_attr.show = s3c_hwmon_ch_show;
@@ -249,6 +250,7 @@
 
 		attr = &attrs->label;
 		attr->index = channel;
+		sysfs_attr_init(&attr->dev_attr.attr);
 		attr->dev_attr.attr.name  = attrs->label_name;
 		attr->dev_attr.attr.mode  = S_IRUGO;
 		attr->dev_attr.show = s3c_hwmon_label_show;
diff -druN linux-2.6.39-libre/drivers/hwmon/sch5627.c linux-3.0-rc7-libre/drivers/hwmon/sch5627.c
--- linux-2.6.39-libre/drivers/hwmon/sch5627.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/hwmon/sch5627.c	2011-07-11 19:51:52.000000000 -0400
@@ -52,6 +52,9 @@
 #define SCH5627_COMPANY_ID		0x5c
 #define SCH5627_PRIMARY_ID		0xa0
 
+#define SCH5627_CMD_READ		0x02
+#define SCH5627_CMD_WRITE		0x03
+
 #define SCH5627_REG_BUILD_CODE		0x39
 #define SCH5627_REG_BUILD_ID		0x3a
 #define SCH5627_REG_HWMON_ID		0x3c
@@ -94,11 +97,13 @@
 struct sch5627_data {
 	unsigned short addr;
 	struct device *hwmon_dev;
+	u8 control;
 	u8 temp_max[SCH5627_NO_TEMPS];
 	u8 temp_crit[SCH5627_NO_TEMPS];
 	u16 fan_min[SCH5627_NO_FANS];
 
 	struct mutex update_lock;
+	unsigned long last_battery;	/* In jiffies */
 	char valid;			/* !=0 if following fields are valid */
 	unsigned long last_updated;	/* In jiffies */
 	u16 temp[SCH5627_NO_TEMPS];
@@ -140,7 +145,7 @@
 	release_region(base, 2);
 }
 
-static int sch5627_read_virtual_reg(struct sch5627_data *data, u16 reg)
+static int sch5627_send_cmd(struct sch5627_data *data, u8 cmd, u16 reg, u8 v)
 {
 	u8 val;
 	int i;
@@ -163,10 +168,14 @@
 	outb(0x80, data->addr + 3);
 
 	/* Write Request Packet Header */
-	outb(0x02, data->addr + 4); /* Access Type: VREG read */
+	outb(cmd, data->addr + 4); /* VREG Access Type read:0x02 write:0x03 */
 	outb(0x01, data->addr + 5); /* # of Entries: 1 Byte (8-bit) */
 	outb(0x04, data->addr + 2); /* Mailbox AP to first data entry loc. */
 
+	/* Write Value field */
+	if (cmd == SCH5627_CMD_WRITE)
+		outb(v, data->addr + 4);
+
 	/* Write Address field */
 	outb(reg & 0xff, data->addr + 6);
 	outb(reg >> 8, data->addr + 7);
@@ -224,8 +233,22 @@
 	 * But if we do that things don't work, so let's not.
 	 */
 
-	/* Read Data from Mailbox */
-	return inb(data->addr + 4);
+	/* Read Value field */
+	if (cmd == SCH5627_CMD_READ)
+		return inb(data->addr + 4);
+
+	return 0;
+}
+
+static int sch5627_read_virtual_reg(struct sch5627_data *data, u16 reg)
+{
+	return sch5627_send_cmd(data, SCH5627_CMD_READ, reg, 0);
+}
+
+static int sch5627_write_virtual_reg(struct sch5627_data *data,
+				     u16 reg, u8 val)
+{
+	return sch5627_send_cmd(data, SCH5627_CMD_WRITE, reg, val);
 }
 
 static int sch5627_read_virtual_reg16(struct sch5627_data *data, u16 reg)
@@ -272,6 +295,13 @@
 
 	mutex_lock(&data->update_lock);
 
+	/* Trigger a Vbat voltage measurement every 5 minutes */
+	if (time_after(jiffies, data->last_battery + 300 * HZ)) {
+		sch5627_write_virtual_reg(data, SCH5627_REG_CTRL,
+					  data->control | 0x10);
+		data->last_battery = jiffies;
+	}
+
 	/* Cache the values for 1 second */
 	if (time_after(jiffies, data->last_updated + HZ) || !data->valid) {
 		for (i = 0; i < SCH5627_NO_TEMPS; i++) {
@@ -696,11 +726,17 @@
 		err = val;
 		goto error;
 	}
-	if (!(val & 0x01)) {
+	data->control = val;
+	if (!(data->control & 0x01)) {
 		pr_err("hardware monitoring not enabled\n");
 		err = -ENODEV;
 		goto error;
 	}
+	/* Trigger a Vbat voltage measurement, so that we get a valid reading
+	   the first time we read Vbat */
+	sch5627_write_virtual_reg(data, SCH5627_REG_CTRL,
+				  data->control | 0x10);
+	data->last_battery = jiffies;
 
 	/*
 	 * Read limits, we do this only once as reading a register on
@@ -851,7 +887,7 @@
 }
 
 MODULE_DESCRIPTION("SMSC SCH5627 Hardware Monitoring Driver");
-MODULE_AUTHOR("Hans de Goede (hdegoede@redhat.com)");
+MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>");
 MODULE_LICENSE("GPL");
 
 module_init(sch5627_init);
diff -druN linux-2.6.39-libre/drivers/hwmon/sht15.c linux-3.0-rc7-libre/drivers/hwmon/sht15.c
--- linux-2.6.39-libre/drivers/hwmon/sht15.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/hwmon/sht15.c	2011-07-11 19:51:52.000000000 -0400
@@ -1,6 +1,10 @@
 /*
  * sht15.c - support for the SHT15 Temperature and Humidity Sensor
  *
+ * Portions Copyright (c) 2010-2011 Savoir-faire Linux Inc.
+ *          Jerome Oufella <jerome.oufella@savoirfairelinux.com>
+ *          Vivien Didelot <vivien.didelot@savoirfairelinux.com>
+ *
  * Copyright (c) 2009 Jonathan Cameron
  *
  * Copyright (c) 2007 Wouter Horre
@@ -9,16 +13,7 @@
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  *
- * Currently ignoring checksum on readings.
- * Default resolution only (14bit temp, 12bit humidity)
- * Ignoring battery status.
- * Heater not enabled.
- * Timings are all conservative.
- *
- * Data sheet available (1/2009) at
- * http://www.sensirion.ch/en/pdf/product_information/Datasheet-humidity-sensor-SHT1x.pdf
- *
- * Regulator supply name = vcc
+ * For further information, see the Documentation/hwmon/sht15 file.
  */
 
 #include <linux/interrupt.h>
@@ -39,17 +34,31 @@
 #include <linux/slab.h>
 #include <asm/atomic.h>
 
-#define SHT15_MEASURE_TEMP	3
-#define SHT15_MEASURE_RH	5
+/* Commands */
+#define SHT15_MEASURE_TEMP		0x03
+#define SHT15_MEASURE_RH		0x05
+#define SHT15_WRITE_STATUS		0x06
+#define SHT15_READ_STATUS		0x07
+#define SHT15_SOFT_RESET		0x1E
 
-#define SHT15_READING_NOTHING	0
-#define SHT15_READING_TEMP	1
-#define SHT15_READING_HUMID	2
+/* Min timings */
+#define SHT15_TSCKL			100	/* (nsecs) clock low */
+#define SHT15_TSCKH			100	/* (nsecs) clock high */
+#define SHT15_TSU			150	/* (nsecs) data setup time */
+#define SHT15_TSRST			11	/* (msecs) soft reset time */
 
-/* Min timings in nsecs */
-#define SHT15_TSCKL		100	/* clock low */
-#define SHT15_TSCKH		100	/* clock high */
-#define SHT15_TSU		150	/* data setup time */
+/* Status Register Bits */
+#define SHT15_STATUS_LOW_RESOLUTION	0x01
+#define SHT15_STATUS_NO_OTP_RELOAD	0x02
+#define SHT15_STATUS_HEATER		0x04
+#define SHT15_STATUS_LOW_BATTERY	0x40
+
+/* Actions the driver may be doing */
+enum sht15_state {
+	SHT15_READING_NOTHING,
+	SHT15_READING_TEMP,
+	SHT15_READING_HUMID
+};
 
 /**
  * struct sht15_temppair - elements of voltage dependent temp calc
@@ -61,9 +70,7 @@
 	int d1;
 };
 
-/* Table 9 from data sheet - relates temperature calculation
- * to supply voltage.
- */
+/* Table 9 from datasheet - relates temperature calculation to supply voltage */
 static const struct sht15_temppair temppoints[] = {
 	{ 2500000, -39400 },
 	{ 3000000, -39600 },
@@ -72,29 +79,70 @@
 	{ 5000000, -40100 },
 };
 
+/* Table from CRC datasheet, section 2.4 */
+static const u8 sht15_crc8_table[] = {
+	0,	49,	98,	83,	196,	245,	166,	151,
+	185,	136,	219,	234,	125,	76,	31,	46,
+	67,	114,	33,	16,	135,	182,	229,	212,
+	250,	203,	152,	169,	62,	15,	92,	109,
+	134,	183,	228,	213,	66,	115,	32,	17,
+	63,	14,	93,	108,	251,	202,	153,	168,
+	197,	244,	167,	150,	1,	48,	99,	82,
+	124,	77,	30,	47,	184,	137,	218,	235,
+	61,	12,	95,	110,	249,	200,	155,	170,
+	132,	181,	230,	215,	64,	113,	34,	19,
+	126,	79,	28,	45,	186,	139,	216,	233,
+	199,	246,	165,	148,	3,	50,	97,	80,
+	187,	138,	217,	232,	127,	78,	29,	44,
+	2,	51,	96,	81,	198,	247,	164,	149,
+	248,	201,	154,	171,	60,	13,	94,	111,
+	65,	112,	35,	18,	133,	180,	231,	214,
+	122,	75,	24,	41,	190,	143,	220,	237,
+	195,	242,	161,	144,	7,	54,	101,	84,
+	57,	8,	91,	106,	253,	204,	159,	174,
+	128,	177,	226,	211,	68,	117,	38,	23,
+	252,	205,	158,	175,	56,	9,	90,	107,
+	69,	116,	39,	22,	129,	176,	227,	210,
+	191,	142,	221,	236,	123,	74,	25,	40,
+	6,	55,	100,	85,	194,	243,	160,	145,
+	71,	118,	37,	20,	131,	178,	225,	208,
+	254,	207,	156,	173,	58,	11,	88,	105,
+	4,	53,	102,	87,	192,	241,	162,	147,
+	189,	140,	223,	238,	121,	72,	27,	42,
+	193,	240,	163,	146,	5,	52,	103,	86,
+	120,	73,	26,	43,	188,	141,	222,	239,
+	130,	179,	224,	209,	70,	119,	36,	21,
+	59,	10,	89,	104,	255,	206,	157,	172
+};
+
 /**
  * struct sht15_data - device instance specific data
- * @pdata:	platform data (gpio's etc)
- * @read_work:	bh of interrupt handler
- * @wait_queue:	wait queue for getting values from device
- * @val_temp:	last temperature value read from device
- * @val_humid: 	last humidity value read from device
- * @flag:	status flag used to identify what the last request was
- * @valid:	are the current stored values valid (start condition)
- * @last_updat:	time of last update
- * @read_lock:	mutex to ensure only one read in progress
- *		at a time.
- * @dev:	associate device structure
- * @hwmon_dev:	device associated with hwmon subsystem
- * @reg:	associated regulator (if specified)
- * @nb:		notifier block to handle notifications of voltage changes
- * @supply_uV:	local copy of supply voltage used to allow
- *		use of regulator consumer if available
- * @supply_uV_valid:   indicates that an updated value has not yet
- *		been obtained from the regulator and so any calculations
- *		based upon it will be invalid.
- * @update_supply_work:	work struct that is used to update the supply_uV
- * @interrupt_handled:	flag used to indicate a hander has been scheduled
+ * @pdata:		platform data (gpio's etc).
+ * @read_work:		bh of interrupt handler.
+ * @wait_queue:		wait queue for getting values from device.
+ * @val_temp:		last temperature value read from device.
+ * @val_humid:		last humidity value read from device.
+ * @val_status:		last status register value read from device.
+ * @checksum_ok:	last value read from the device passed CRC validation.
+ * @checksumming:	flag used to enable the data validation with CRC.
+ * @state:		state identifying the action the driver is doing.
+ * @measurements_valid:	are the current stored measures valid (start condition).
+ * @status_valid:	is the current stored status valid (start condition).
+ * @last_measurement:	time of last measure.
+ * @last_status:	time of last status reading.
+ * @read_lock:		mutex to ensure only one read in progress at a time.
+ * @dev:		associate device structure.
+ * @hwmon_dev:		device associated with hwmon subsystem.
+ * @reg:		associated regulator (if specified).
+ * @nb:			notifier block to handle notifications of voltage
+ *                      changes.
+ * @supply_uV:		local copy of supply voltage used to allow use of
+ *                      regulator consumer if available.
+ * @supply_uV_valid:	indicates that an updated value has not yet been
+ *			obtained from the regulator and so any calculations
+ *			based upon it will be invalid.
+ * @update_supply_work:	work struct that is used to update the supply_uV.
+ * @interrupt_handled:	flag used to indicate a handler has been scheduled.
  */
 struct sht15_data {
 	struct sht15_platform_data	*pdata;
@@ -102,21 +150,60 @@
 	wait_queue_head_t		wait_queue;
 	uint16_t			val_temp;
 	uint16_t			val_humid;
-	u8				flag;
-	u8				valid;
-	unsigned long			last_updat;
+	u8				val_status;
+	bool				checksum_ok;
+	bool				checksumming;
+	enum sht15_state		state;
+	bool				measurements_valid;
+	bool				status_valid;
+	unsigned long			last_measurement;
+	unsigned long			last_status;
 	struct mutex			read_lock;
 	struct device			*dev;
 	struct device			*hwmon_dev;
 	struct regulator		*reg;
 	struct notifier_block		nb;
 	int				supply_uV;
-	int				supply_uV_valid;
+	bool				supply_uV_valid;
 	struct work_struct		update_supply_work;
 	atomic_t			interrupt_handled;
 };
 
 /**
+ * sht15_reverse() - reverse a byte
+ * @byte:    byte to reverse.
+ */
+static u8 sht15_reverse(u8 byte)
+{
+	u8 i, c;
+
+	for (c = 0, i = 0; i < 8; i++)
+		c |= (!!(byte & (1 << i))) << (7 - i);
+	return c;
+}
+
+/**
+ * sht15_crc8() - compute crc8
+ * @data:	sht15 specific data.
+ * @value:	sht15 retrieved data.
+ *
+ * This implements section 2 of the CRC datasheet.
+ */
+static u8 sht15_crc8(struct sht15_data *data,
+		const u8 *value,
+		int len)
+{
+	u8 crc = sht15_reverse(data->val_status & 0x0F);
+
+	while (len--) {
+		crc = sht15_crc8_table[*value ^ crc];
+		value++;
+	}
+
+	return crc;
+}
+
+/**
  * sht15_connection_reset() - reset the comms interface
  * @data:	sht15 specific data
  *
@@ -125,6 +212,7 @@
 static void sht15_connection_reset(struct sht15_data *data)
 {
 	int i;
+
 	gpio_direction_output(data->pdata->gpio_data, 1);
 	ndelay(SHT15_TSCKL);
 	gpio_set_value(data->pdata->gpio_sck, 0);
@@ -136,14 +224,14 @@
 		ndelay(SHT15_TSCKL);
 	}
 }
+
 /**
  * sht15_send_bit() - send an individual bit to the device
  * @data:	device state data
  * @val:	value of bit to be sent
- **/
+ */
 static inline void sht15_send_bit(struct sht15_data *data, int val)
 {
-
 	gpio_set_value(data->pdata->gpio_data, val);
 	ndelay(SHT15_TSU);
 	gpio_set_value(data->pdata->gpio_sck, 1);
@@ -154,12 +242,12 @@
 
 /**
  * sht15_transmission_start() - specific sequence for new transmission
- *
  * @data:	device state data
+ *
  * Timings for this are not documented on the data sheet, so very
  * conservative ones used in implementation. This implements
  * figure 12 on the data sheet.
- **/
+ */
 static void sht15_transmission_start(struct sht15_data *data)
 {
 	/* ensure data is high and output */
@@ -180,23 +268,26 @@
 	gpio_set_value(data->pdata->gpio_sck, 0);
 	ndelay(SHT15_TSCKL);
 }
+
 /**
  * sht15_send_byte() - send a single byte to the device
  * @data:	device state
  * @byte:	value to be sent
- **/
+ */
 static void sht15_send_byte(struct sht15_data *data, u8 byte)
 {
 	int i;
+
 	for (i = 0; i < 8; i++) {
 		sht15_send_bit(data, !!(byte & 0x80));
 		byte <<= 1;
 	}
 }
+
 /**
  * sht15_wait_for_response() - checks for ack from device
  * @data:	device state
- **/
+ */
 static int sht15_wait_for_response(struct sht15_data *data)
 {
 	gpio_direction_input(data->pdata->gpio_data);
@@ -220,27 +311,199 @@
  *
  * On entry, sck is output low, data is output pull high
  * and the interrupt disabled.
- **/
+ */
 static int sht15_send_cmd(struct sht15_data *data, u8 cmd)
 {
 	int ret = 0;
+
 	sht15_transmission_start(data);
 	sht15_send_byte(data, cmd);
 	ret = sht15_wait_for_response(data);
 	return ret;
 }
+
 /**
- * sht15_update_single_val() - get a new value from device
+ * sht15_soft_reset() - send a soft reset command
+ * @data:	sht15 specific data.
+ *
+ * As described in section 3.2 of the datasheet.
+ */
+static int sht15_soft_reset(struct sht15_data *data)
+{
+	int ret;
+
+	ret = sht15_send_cmd(data, SHT15_SOFT_RESET);
+	if (ret)
+		return ret;
+	msleep(SHT15_TSRST);
+	/* device resets default hardware status register value */
+	data->val_status = 0;
+
+	return ret;
+}
+
+/**
+ * sht15_ack() - send a ack
+ * @data:	sht15 specific data.
+ *
+ * Each byte of data is acknowledged by pulling the data line
+ * low for one clock pulse.
+ */
+static void sht15_ack(struct sht15_data *data)
+{
+	gpio_direction_output(data->pdata->gpio_data, 0);
+	ndelay(SHT15_TSU);
+	gpio_set_value(data->pdata->gpio_sck, 1);
+	ndelay(SHT15_TSU);
+	gpio_set_value(data->pdata->gpio_sck, 0);
+	ndelay(SHT15_TSU);
+	gpio_set_value(data->pdata->gpio_data, 1);
+
+	gpio_direction_input(data->pdata->gpio_data);
+}
+
+/**
+ * sht15_end_transmission() - notify device of end of transmission
+ * @data:	device state.
+ *
+ * This is basically a NAK (single clock pulse, data high).
+ */
+static void sht15_end_transmission(struct sht15_data *data)
+{
+	gpio_direction_output(data->pdata->gpio_data, 1);
+	ndelay(SHT15_TSU);
+	gpio_set_value(data->pdata->gpio_sck, 1);
+	ndelay(SHT15_TSCKH);
+	gpio_set_value(data->pdata->gpio_sck, 0);
+	ndelay(SHT15_TSCKL);
+}
+
+/**
+ * sht15_read_byte() - Read a byte back from the device
+ * @data:	device state.
+ */
+static u8 sht15_read_byte(struct sht15_data *data)
+{
+	int i;
+	u8 byte = 0;
+
+	for (i = 0; i < 8; ++i) {
+		byte <<= 1;
+		gpio_set_value(data->pdata->gpio_sck, 1);
+		ndelay(SHT15_TSCKH);
+		byte |= !!gpio_get_value(data->pdata->gpio_data);
+		gpio_set_value(data->pdata->gpio_sck, 0);
+		ndelay(SHT15_TSCKL);
+	}
+	return byte;
+}
+
+/**
+ * sht15_send_status() - write the status register byte
+ * @data:	sht15 specific data.
+ * @status:	the byte to set the status register with.
+ *
+ * As described in figure 14 and table 5 of the datasheet.
+ */
+static int sht15_send_status(struct sht15_data *data, u8 status)
+{
+	int ret;
+
+	ret = sht15_send_cmd(data, SHT15_WRITE_STATUS);
+	if (ret)
+		return ret;
+	gpio_direction_output(data->pdata->gpio_data, 1);
+	ndelay(SHT15_TSU);
+	sht15_send_byte(data, status);
+	ret = sht15_wait_for_response(data);
+	if (ret)
+		return ret;
+
+	data->val_status = status;
+	return 0;
+}
+
+/**
+ * sht15_update_status() - get updated status register from device if too old
+ * @data:	device instance specific data.
+ *
+ * As described in figure 15 and table 5 of the datasheet.
+ */
+static int sht15_update_status(struct sht15_data *data)
+{
+	int ret = 0;
+	u8 status;
+	u8 previous_config;
+	u8 dev_checksum = 0;
+	u8 checksum_vals[2];
+	int timeout = HZ;
+
+	mutex_lock(&data->read_lock);
+	if (time_after(jiffies, data->last_status + timeout)
+			|| !data->status_valid) {
+		ret = sht15_send_cmd(data, SHT15_READ_STATUS);
+		if (ret)
+			goto error_ret;
+		status = sht15_read_byte(data);
+
+		if (data->checksumming) {
+			sht15_ack(data);
+			dev_checksum = sht15_reverse(sht15_read_byte(data));
+			checksum_vals[0] = SHT15_READ_STATUS;
+			checksum_vals[1] = status;
+			data->checksum_ok = (sht15_crc8(data, checksum_vals, 2)
+					== dev_checksum);
+		}
+
+		sht15_end_transmission(data);
+
+		/*
+		 * Perform checksum validation on the received data.
+		 * Specification mentions that in case a checksum verification
+		 * fails, a soft reset command must be sent to the device.
+		 */
+		if (data->checksumming && !data->checksum_ok) {
+			previous_config = data->val_status & 0x07;
+			ret = sht15_soft_reset(data);
+			if (ret)
+				goto error_ret;
+			if (previous_config) {
+				ret = sht15_send_status(data, previous_config);
+				if (ret) {
+					dev_err(data->dev,
+						"CRC validation failed, unable "
+						"to restore device settings\n");
+					goto error_ret;
+				}
+			}
+			ret = -EAGAIN;
+			goto error_ret;
+		}
+
+		data->val_status = status;
+		data->status_valid = true;
+		data->last_status = jiffies;
+	}
+error_ret:
+	mutex_unlock(&data->read_lock);
+
+	return ret;
+}
+
+/**
+ * sht15_measurement() - get a new value from device
  * @data:		device instance specific data
  * @command:		command sent to request value
  * @timeout_msecs:	timeout after which comms are assumed
  *			to have failed are reset.
- **/
-static inline int sht15_update_single_val(struct sht15_data *data,
-					  int command,
-					  int timeout_msecs)
+ */
+static int sht15_measurement(struct sht15_data *data,
+			     int command,
+			     int timeout_msecs)
 {
 	int ret;
+	u8 previous_config;
+
 	ret = sht15_send_cmd(data, command);
 	if (ret)
 		return ret;
@@ -256,38 +519,61 @@
 			schedule_work(&data->read_work);
 	}
 	ret = wait_event_timeout(data->wait_queue,
-				 (data->flag == SHT15_READING_NOTHING),
+				 (data->state == SHT15_READING_NOTHING),
 				 msecs_to_jiffies(timeout_msecs));
 	if (ret == 0) {/* timeout occurred */
 		disable_irq_nosync(gpio_to_irq(data->pdata->gpio_data));
 		sht15_connection_reset(data);
 		return -ETIME;
 	}
+
+	/*
+	 *  Perform checksum validation on the received data.
+	 *  Specification mentions that in case a checksum verification fails,
+	 *  a soft reset command must be sent to the device.
+	 */
+	if (data->checksumming && !data->checksum_ok) {
+		previous_config = data->val_status & 0x07;
+		ret = sht15_soft_reset(data);
+		if (ret)
+			return ret;
+		if (previous_config) {
+			ret = sht15_send_status(data, previous_config);
+			if (ret) {
+				dev_err(data->dev,
+					"CRC validation failed, unable "
+					"to restore device settings\n");
+				return ret;
+			}
+		}
+		return -EAGAIN;
+	}
+
 	return 0;
 }
 
 /**
- * sht15_update_vals() - get updated readings from device if too old
+ * sht15_update_measurements() - get updated measures from device if too old
  * @data:	device state
- **/
-static int sht15_update_vals(struct sht15_data *data)
+ */
+static int sht15_update_measurements(struct sht15_data *data)
 {
 	int ret = 0;
 	int timeout = HZ;
 
 	mutex_lock(&data->read_lock);
-	if (time_after(jiffies, data->last_updat + timeout)
-	    || !data->valid) {
-		data->flag = SHT15_READING_HUMID;
-		ret = sht15_update_single_val(data, SHT15_MEASURE_RH, 160);
+	if (time_after(jiffies, data->last_measurement + timeout)
+	    || !data->measurements_valid) {
+		data->state = SHT15_READING_HUMID;
+		ret = sht15_measurement(data, SHT15_MEASURE_RH, 160);
 		if (ret)
 			goto error_ret;
-		data->flag = SHT15_READING_TEMP;
-		ret = sht15_update_single_val(data, SHT15_MEASURE_TEMP, 400);
+		data->state = SHT15_READING_TEMP;
+		ret = sht15_measurement(data, SHT15_MEASURE_TEMP, 400);
 		if (ret)
 			goto error_ret;
-		data->valid = 1;
-		data->last_updat = jiffies;
+		data->measurements_valid = true;
+		data->last_measurement = jiffies;
 	}
 error_ret:
 	mutex_unlock(&data->read_lock);
@@ -300,10 +586,11 @@
  * @data:	device state
  *
  * As per section 4.3 of the data sheet.
- **/
+ */
 static inline int sht15_calc_temp(struct sht15_data *data)
 {
 	int d1 = temppoints[0].d1;
+	int d2 = (data->val_status & SHT15_STATUS_LOW_RESOLUTION) ? 40 : 10;
 	int i;
 
 	for (i = ARRAY_SIZE(temppoints) - 1; i > 0; i--)
@@ -316,7 +603,7 @@
 			break;
 		}
 
-	return data->val_temp*10 + d1;
+	return data->val_temp * d2 + d1;
 }
 
 /**
@@ -325,23 +612,102 @@
  *
  * This is the temperature compensated version as per section 4.2 of
  * the data sheet.
- **/
+ *
+ * The sensor is assumed to be V3, which is compatible with V4.
+ * Humidity conversion coefficients are shown in table 7 of the datasheet.
+ */
 static inline int sht15_calc_humid(struct sht15_data *data)
 {
-	int RHlinear; /* milli percent */
+	int rh_linear; /* milli percent */
 	int temp = sht15_calc_temp(data);
-
+	int c2, c3;
+	int t2;
 	const int c1 = -4;
-	const int c2 = 40500; /* x 10 ^ -6 */
-	const int c3 = -28; /* x 10 ^ -7 */
 
-	RHlinear = c1*1000
-		+ c2 * data->val_humid/1000
+	if (data->val_status & SHT15_STATUS_LOW_RESOLUTION) {
+		c2 = 648000; /* x 10 ^ -6 */
+		c3 = -7200;  /* x 10 ^ -7 */
+		t2 = 1280;
+	} else {
+		c2 = 40500;  /* x 10 ^ -6 */
+		c3 = -28;    /* x 10 ^ -7 */
+		t2 = 80;
+	}
+
+	rh_linear = c1 * 1000
+		+ c2 * data->val_humid / 1000
 		+ (data->val_humid * data->val_humid * c3) / 10000;
-	return (temp - 25000) * (10000 + 80 * data->val_humid)
-		/ 1000000 + RHlinear;
+	return (temp - 25000) * (10000 + t2 * data->val_humid)
+		/ 1000000 + rh_linear;
 }
 
+/**
+ * sht15_show_status() - show status information in sysfs
+ * @dev:	device.
+ * @attr:	device attribute.
+ * @buf:	sysfs buffer where information is written to.
+ *
+ * Will be called on read access to temp1_fault, humidity1_fault
+ * and heater_enable sysfs attributes.
+ * Returns number of bytes written into buffer, negative errno on error.
+ */
+static ssize_t sht15_show_status(struct device *dev,
+				 struct device_attribute *attr,
+				 char *buf)
+{
+	int ret;
+	struct sht15_data *data = dev_get_drvdata(dev);
+	u8 bit = to_sensor_dev_attr(attr)->index;
+
+	ret = sht15_update_status(data);
+
+	return ret ? ret : sprintf(buf, "%d\n", !!(data->val_status & bit));
+}
+
+/**
+ * sht15_store_heater() - change heater state via sysfs
+ * @dev:	device.
+ * @attr:	device attribute.
+ * @buf:	sysfs buffer to read the new heater state from.
+ * @count:	length of the data.
+ *
+ * Will be called on read access to heater_enable sysfs attribute.
+ * Returns number of bytes actually decoded, negative errno on error.
+ */
+static ssize_t sht15_store_heater(struct device *dev,
+				  struct device_attribute *attr,
+				  const char *buf, size_t count)
+{
+	int ret;
+	struct sht15_data *data = dev_get_drvdata(dev);
+	long value;
+	u8 status;
+
+	if (strict_strtol(buf, 10, &value))
+		return -EINVAL;
+
+	mutex_lock(&data->read_lock);
+	status = data->val_status & 0x07;
+	if (!!value)
+		status |= SHT15_STATUS_HEATER;
+	else
+		status &= ~SHT15_STATUS_HEATER;
+
+	ret = sht15_send_status(data, status);
+	mutex_unlock(&data->read_lock);
+
+	return ret ? ret : count;
+}
+
+/**
+ * sht15_show_temp() - show temperature measurement value in sysfs
+ * @dev:	device.
+ * @attr:	device attribute.
+ * @buf:	sysfs buffer where measurement values are written to.
+ *
+ * Will be called on read access to temp1_input sysfs attribute.
+ * Returns number of bytes written into buffer, negative errno on error.
+ */
 static ssize_t sht15_show_temp(struct device *dev,
 			       struct device_attribute *attr,
 			       char *buf)
@@ -350,12 +716,21 @@
 	struct sht15_data *data = dev_get_drvdata(dev);
 
 	/* Technically no need to read humidity as well */
-	ret = sht15_update_vals(data);
+	ret = sht15_update_measurements(data);
 
 	return ret ? ret : sprintf(buf, "%d\n",
 				   sht15_calc_temp(data));
 }
 
+/**
+ * sht15_show_humidity() - show humidity measurement value in sysfs
+ * @dev:	device.
+ * @attr:	device attribute.
+ * @buf:	sysfs buffer where measurement values are written to.
+ *
+ * Will be called on read access to humidity1_input sysfs attribute.
+ * Returns number of bytes written into buffer, negative errno on error.
+ */
 static ssize_t sht15_show_humidity(struct device *dev,
 				   struct device_attribute *attr,
 				   char *buf)
@@ -363,11 +738,11 @@
 	int ret;
 	struct sht15_data *data = dev_get_drvdata(dev);
 
-	ret = sht15_update_vals(data);
+	ret = sht15_update_measurements(data);
 
 	return ret ? ret : sprintf(buf, "%d\n", sht15_calc_humid(data));
+}
 
-};
 static ssize_t show_name(struct device *dev,
 			 struct device_attribute *attr,
 			 char *buf)
@@ -376,16 +751,23 @@
 	return sprintf(buf, "%s\n", pdev->name);
 }
 
-static SENSOR_DEVICE_ATTR(temp1_input,
-			  S_IRUGO, sht15_show_temp,
-			  NULL, 0);
-static SENSOR_DEVICE_ATTR(humidity1_input,
-			  S_IRUGO, sht15_show_humidity,
-			  NULL, 0);
+static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO,
+			  sht15_show_temp, NULL, 0);
+static SENSOR_DEVICE_ATTR(humidity1_input, S_IRUGO,
+			  sht15_show_humidity, NULL, 0);
+static SENSOR_DEVICE_ATTR(temp1_fault, S_IRUGO, sht15_show_status, NULL,
+			  SHT15_STATUS_LOW_BATTERY);
+static SENSOR_DEVICE_ATTR(humidity1_fault, S_IRUGO, sht15_show_status, NULL,
+			  SHT15_STATUS_LOW_BATTERY);
+static SENSOR_DEVICE_ATTR(heater_enable, S_IRUGO | S_IWUSR, sht15_show_status,
+			  sht15_store_heater, SHT15_STATUS_HEATER);
 static DEVICE_ATTR(name, S_IRUGO, show_name, NULL);
 static struct attribute *sht15_attrs[] = {
 	&sensor_dev_attr_temp1_input.dev_attr.attr,
 	&sensor_dev_attr_humidity1_input.dev_attr.attr,
+	&sensor_dev_attr_temp1_fault.dev_attr.attr,
+	&sensor_dev_attr_humidity1_fault.dev_attr.attr,
+	&sensor_dev_attr_heater_enable.dev_attr.attr,
 	&dev_attr_name.attr,
 	NULL,
 };
@@ -397,59 +779,31 @@
 static irqreturn_t sht15_interrupt_fired(int irq, void *d)
 {
 	struct sht15_data *data = d;
+
 	/* First disable the interrupt */
 	disable_irq_nosync(irq);
 	atomic_inc(&data->interrupt_handled);
 	/* Then schedule a reading work struct */
-	if (data->flag != SHT15_READING_NOTHING)
+	if (data->state != SHT15_READING_NOTHING)
 		schedule_work(&data->read_work);
 	return IRQ_HANDLED;
 }
 
-/* Each byte of data is acknowledged by pulling the data line
- * low for one clock pulse.
- */
-static void sht15_ack(struct sht15_data *data)
-{
-	gpio_direction_output(data->pdata->gpio_data, 0);
-	ndelay(SHT15_TSU);
-	gpio_set_value(data->pdata->gpio_sck, 1);
-	ndelay(SHT15_TSU);
-	gpio_set_value(data->pdata->gpio_sck, 0);
-	ndelay(SHT15_TSU);
-	gpio_set_value(data->pdata->gpio_data, 1);
-
-	gpio_direction_input(data->pdata->gpio_data);
-}
-/**
- * sht15_end_transmission() - notify device of end of transmission
- * @data:	device state
- *
- * This is basically a NAK. (single clock pulse, data high)
- **/
-static void sht15_end_transmission(struct sht15_data *data)
-{
-	gpio_direction_output(data->pdata->gpio_data, 1);
-	ndelay(SHT15_TSU);
-	gpio_set_value(data->pdata->gpio_sck, 1);
-	ndelay(SHT15_TSCKH);
-	gpio_set_value(data->pdata->gpio_sck, 0);
-	ndelay(SHT15_TSCKL);
-}
-
 static void sht15_bh_read_data(struct work_struct *work_s)
 {
-	int i;
 	uint16_t val = 0;
+	u8 dev_checksum = 0;
+	u8 checksum_vals[3];
 	struct sht15_data *data
 		= container_of(work_s, struct sht15_data,
 			       read_work);
+
 	/* Firstly, verify the line is low */
 	if (gpio_get_value(data->pdata->gpio_data)) {
-		/* If not, then start the interrupt again - care
-		   here as could have gone low in meantime so verify
-		   it hasn't!
-		*/
+		/*
+		 * If not, then start the interrupt again - care here as could
+		 * have gone low in meantime so verify it hasn't!
+		 */
 		atomic_set(&data->interrupt_handled, 0);
 		enable_irq(gpio_to_irq(data->pdata->gpio_data));
 		/* If still not occurred or another handler has been scheduled */
@@ -457,30 +811,43 @@
 		    || atomic_read(&data->interrupt_handled))
 			return;
 	}
+
 	/* Read the data back from the device */
-	for (i = 0; i < 16; ++i) {
-		val <<= 1;
-		gpio_set_value(data->pdata->gpio_sck, 1);
-		ndelay(SHT15_TSCKH);
-		val |= !!gpio_get_value(data->pdata->gpio_data);
-		gpio_set_value(data->pdata->gpio_sck, 0);
-		ndelay(SHT15_TSCKL);
-		if (i == 7)
-			sht15_ack(data);
+	val = sht15_read_byte(data);
+	val <<= 8;
+	sht15_ack(data);
+	val |= sht15_read_byte(data);
+
+	if (data->checksumming) {
+		/*
+		 * Ask the device for a checksum and read it back.
+		 * Note: the device sends the checksum byte reversed.
+		 */
+		sht15_ack(data);
+		dev_checksum = sht15_reverse(sht15_read_byte(data));
+		checksum_vals[0] = (data->state == SHT15_READING_TEMP) ?
+			SHT15_MEASURE_TEMP : SHT15_MEASURE_RH;
+		checksum_vals[1] = (u8) (val >> 8);
+		checksum_vals[2] = (u8) val;
+		data->checksum_ok
+			= (sht15_crc8(data, checksum_vals, 3) == dev_checksum);
 	}
+
 	/* Tell the device we are done */
 	sht15_end_transmission(data);
 
-	switch (data->flag) {
+	switch (data->state) {
 	case SHT15_READING_TEMP:
 		data->val_temp = val;
 		break;
 	case SHT15_READING_HUMID:
 		data->val_humid = val;
 		break;
+	default:
+		break;
 	}
 
-	data->flag = SHT15_READING_NOTHING;
+	data->state = SHT15_READING_NOTHING;
 	wake_up(&data->wait_queue);
 }
 
@@ -500,10 +867,10 @@
  *
  * Note that as the notification code holds the regulator lock, we have
  * to schedule an update of the supply voltage rather than getting it directly.
- **/
+ */
 static int sht15_invalidate_voltage(struct notifier_block *nb,
-				unsigned long event,
-				void *ignored)
+				    unsigned long event,
+				    void *ignored)
 {
 	struct sht15_data *data = container_of(nb, struct sht15_data, nb);
 
@@ -518,10 +885,11 @@
 {
 	int ret = 0;
 	struct sht15_data *data = kzalloc(sizeof(*data), GFP_KERNEL);
+	u8 status = 0;
 
 	if (!data) {
 		ret = -ENOMEM;
-		dev_err(&pdev->dev, "kzalloc failed");
+		dev_err(&pdev->dev, "kzalloc failed\n");
 		goto error_ret;
 	}
 
@@ -533,13 +901,22 @@
 	init_waitqueue_head(&data->wait_queue);
 
 	if (pdev->dev.platform_data == NULL) {
-		dev_err(&pdev->dev, "no platform data supplied");
+		dev_err(&pdev->dev, "no platform data supplied\n");
 		goto err_free_data;
 	}
 	data->pdata = pdev->dev.platform_data;
-	data->supply_uV = data->pdata->supply_mv*1000;
+	data->supply_uV = data->pdata->supply_mv * 1000;
+	if (data->pdata->checksum)
+		data->checksumming = true;
+	if (data->pdata->no_otp_reload)
+		status |= SHT15_STATUS_NO_OTP_RELOAD;
+	if (data->pdata->low_resolution)
+		status |= SHT15_STATUS_LOW_RESOLUTION;
 
-/* If a regulator is available, query what the supply voltage actually is!*/
+	/*
+	 * If a regulator is available,
+	 * query what the supply voltage actually is!
+	 */
 	data->reg = regulator_get(data->dev, "vcc");
 	if (!IS_ERR(data->reg)) {
 		int voltage;
@@ -549,28 +926,34 @@
 			data->supply_uV = voltage;
 
 		regulator_enable(data->reg);
-		/* setup a notifier block to update this if another device
-		 *  causes the voltage to change */
+		/*
+		 * Setup a notifier block to update this if another device
+		 * causes the voltage to change
+		 */
 		data->nb.notifier_call = &sht15_invalidate_voltage;
 		ret = regulator_register_notifier(data->reg, &data->nb);
+		if (ret) {
+			dev_err(&pdev->dev,
+				"regulator notifier request failed\n");
+			regulator_disable(data->reg);
+			regulator_put(data->reg);
+			goto err_free_data;
+		}
 	}
-/* Try requesting the GPIOs */
+
+	/* Try requesting the GPIOs */
 	ret = gpio_request(data->pdata->gpio_sck, "SHT15 sck");
 	if (ret) {
-		dev_err(&pdev->dev, "gpio request failed");
-		goto err_free_data;
+		dev_err(&pdev->dev, "gpio request failed\n");
+		goto err_release_reg;
 	}
 	gpio_direction_output(data->pdata->gpio_sck, 0);
+
 	ret = gpio_request(data->pdata->gpio_data, "SHT15 data");
 	if (ret) {
-		dev_err(&pdev->dev, "gpio request failed");
+		dev_err(&pdev->dev, "gpio request failed\n");
 		goto err_release_gpio_sck;
 	}
-	ret = sysfs_create_group(&pdev->dev.kobj, &sht15_attr_group);
-	if (ret) {
-		dev_err(&pdev->dev, "sysfs create failed");
-		goto err_release_gpio_data;
-	}
 
 	ret = request_irq(gpio_to_irq(data->pdata->gpio_data),
 			  sht15_interrupt_fired,
@@ -578,30 +961,53 @@
 			  "sht15 data",
 			  data);
 	if (ret) {
-		dev_err(&pdev->dev, "failed to get irq for data line");
+		dev_err(&pdev->dev, "failed to get irq for data line\n");
 		goto err_release_gpio_data;
 	}
 	disable_irq_nosync(gpio_to_irq(data->pdata->gpio_data));
 	sht15_connection_reset(data);
-	sht15_send_cmd(data, 0x1E);
+	ret = sht15_soft_reset(data);
+	if (ret)
+		goto err_release_irq;
+
+	/* write status with platform data options */
+	if (status) {
+		ret = sht15_send_status(data, status);
+		if (ret)
+			goto err_release_irq;
+	}
+
+	ret = sysfs_create_group(&pdev->dev.kobj, &sht15_attr_group);
+	if (ret) {
+		dev_err(&pdev->dev, "sysfs create failed\n");
+		goto err_release_irq;
+	}
 
 	data->hwmon_dev = hwmon_device_register(data->dev);
 	if (IS_ERR(data->hwmon_dev)) {
 		ret = PTR_ERR(data->hwmon_dev);
-		goto err_release_irq;
+		goto err_release_sysfs_group;
 	}
+
 	return 0;
 
+err_release_sysfs_group:
+	sysfs_remove_group(&pdev->dev.kobj, &sht15_attr_group);
 err_release_irq:
 	free_irq(gpio_to_irq(data->pdata->gpio_data), data);
 err_release_gpio_data:
 	gpio_free(data->pdata->gpio_data);
 err_release_gpio_sck:
 	gpio_free(data->pdata->gpio_sck);
+err_release_reg:
+	if (!IS_ERR(data->reg)) {
+		regulator_unregister_notifier(data->reg, &data->nb);
+		regulator_disable(data->reg);
+		regulator_put(data->reg);
+	}
 err_free_data:
 	kfree(data);
 error_ret:
-
 	return ret;
 }
 
@@ -609,9 +1015,15 @@
 {
 	struct sht15_data *data = platform_get_drvdata(pdev);
 
-	/* Make sure any reads from the device are done and
-	 * prevent new ones from beginning */
+	/*
+	 * Make sure any reads from the device are done and
+	 * prevent new ones beginning
+	 */
 	mutex_lock(&data->read_lock);
+	if (sht15_soft_reset(data)) {
+		mutex_unlock(&data->read_lock);
+		return -EFAULT;
+	}
 	hwmon_device_unregister(data->hwmon_dev);
 	sysfs_remove_group(&pdev->dev.kobj, &sht15_attr_group);
 	if (!IS_ERR(data->reg)) {
@@ -625,10 +1037,10 @@
 	gpio_free(data->pdata->gpio_sck);
 	mutex_unlock(&data->read_lock);
 	kfree(data);
+
 	return 0;
 }
 
-
 /*
  * sht_drivers simultaneously refers to __devinit and __devexit function
  * which causes spurious section mismatch warning. So use __refdata to
@@ -673,7 +1085,6 @@
 	},
 };
 
-
 static int __init sht15_init(void)
 {
 	int ret;
diff -druN linux-2.6.39-libre/drivers/hwmon/ucd9000.c linux-3.0-rc7-libre/drivers/hwmon/ucd9000.c
--- linux-2.6.39-libre/drivers/hwmon/ucd9000.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/hwmon/ucd9000.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,278 @@
+/*
+ * Hardware monitoring driver for UCD90xxx Sequencer and System Health
+ * Controller series
+ *
+ * Copyright (C) 2011 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 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the 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/err.h>
+#include <linux/slab.h>
+#include <linux/i2c.h>
+#include <linux/i2c/pmbus.h>
+#include "pmbus.h"
+
+enum chips { ucd9000, ucd90120, ucd90124, ucd9090, ucd90910 };
+
+#define UCD9000_MONITOR_CONFIG		0xd5
+#define UCD9000_NUM_PAGES		0xd6
+#define UCD9000_FAN_CONFIG_INDEX	0xe7
+#define UCD9000_FAN_CONFIG		0xe8
+#define UCD9000_DEVICE_ID		0xfd
+
+#define UCD9000_MON_TYPE(x)	(((x) >> 5) & 0x07)
+#define UCD9000_MON_PAGE(x)	((x) & 0x0f)
+
+#define UCD9000_MON_VOLTAGE	1
+#define UCD9000_MON_TEMPERATURE	2
+#define UCD9000_MON_CURRENT	3
+#define UCD9000_MON_VOLTAGE_HW	4
+
+#define UCD9000_NUM_FAN		4
+
+struct ucd9000_data {
+	u8 fan_data[UCD9000_NUM_FAN][I2C_SMBUS_BLOCK_MAX];
+	struct pmbus_driver_info info;
+};
+#define to_ucd9000_data(_info) container_of(_info, struct ucd9000_data, info)
+
+static int ucd9000_get_fan_config(struct i2c_client *client, int fan)
+{
+	int fan_config = 0;
+	struct ucd9000_data *data
+	  = to_ucd9000_data(pmbus_get_driver_info(client));
+
+	if (data->fan_data[fan][3] & 1)
+		fan_config |= PB_FAN_2_INSTALLED;   /* Use lower bit position */
+
+	/* Pulses/revolution */
+	fan_config |= (data->fan_data[fan][3] & 0x06) >> 1;
+
+	return fan_config;
+}
+
+static int ucd9000_read_byte_data(struct i2c_client *client, int page, int reg)
+{
+	int ret = 0;
+	int fan_config;
+
+	switch (reg) {
+	case PMBUS_FAN_CONFIG_12:
+		if (page)
+			return -EINVAL;
+
+		ret = ucd9000_get_fan_config(client, 0);
+		if (ret < 0)
+			return ret;
+		fan_config = ret << 4;
+		ret = ucd9000_get_fan_config(client, 1);
+		if (ret < 0)
+			return ret;
+		fan_config |= ret;
+		ret = fan_config;
+		break;
+	case PMBUS_FAN_CONFIG_34:
+		if (page)
+			return -EINVAL;
+
+		ret = ucd9000_get_fan_config(client, 2);
+		if (ret < 0)
+			return ret;
+		fan_config = ret << 4;
+		ret = ucd9000_get_fan_config(client, 3);
+		if (ret < 0)
+			return ret;
+		fan_config |= ret;
+		ret = fan_config;
+		break;
+	default:
+		ret = -ENODATA;
+		break;
+	}
+	return ret;
+}
+
+static const struct i2c_device_id ucd9000_id[] = {
+	{"ucd9000", ucd9000},
+	{"ucd90120", ucd90120},
+	{"ucd90124", ucd90124},
+	{"ucd9090", ucd9090},
+	{"ucd90910", ucd90910},
+	{}
+};
+MODULE_DEVICE_TABLE(i2c, ucd9000_id);
+
+static int ucd9000_probe(struct i2c_client *client,
+			 const struct i2c_device_id *id)
+{
+	u8 block_buffer[I2C_SMBUS_BLOCK_MAX + 1];
+	struct ucd9000_data *data;
+	struct pmbus_driver_info *info;
+	const struct i2c_device_id *mid;
+	int i, ret;
+
+	if (!i2c_check_functionality(client->adapter,
+				     I2C_FUNC_SMBUS_BYTE_DATA |
+				     I2C_FUNC_SMBUS_BLOCK_DATA))
+		return -ENODEV;
+
+	ret = i2c_smbus_read_block_data(client, UCD9000_DEVICE_ID,
+					block_buffer);
+	if (ret < 0) {
+		dev_err(&client->dev, "Failed to read device ID\n");
+		return ret;
+	}
+	block_buffer[ret] = '\0';
+	dev_info(&client->dev, "Device ID %s\n", block_buffer);
+
+	mid = NULL;
+	for (i = 0; i < ARRAY_SIZE(ucd9000_id); i++) {
+		mid = &ucd9000_id[i];
+		if (!strncasecmp(mid->name, block_buffer, strlen(mid->name)))
+			break;
+	}
+	if (!mid || !strlen(mid->name)) {
+		dev_err(&client->dev, "Unsupported device\n");
+		return -ENODEV;
+	}
+
+	if (id->driver_data != ucd9000 && id->driver_data != mid->driver_data)
+		dev_notice(&client->dev,
+			   "Device mismatch: Configured %s, detected %s\n",
+			   id->name, mid->name);
+
+	data = kzalloc(sizeof(struct ucd9000_data), GFP_KERNEL);
+	if (!data)
+		return -ENOMEM;
+	info = &data->info;
+
+	ret = i2c_smbus_read_byte_data(client, UCD9000_NUM_PAGES);
+	if (ret < 0) {
+		dev_err(&client->dev,
+			"Failed to read number of active pages\n");
+		goto out;
+	}
+	info->pages = ret;
+	if (!info->pages) {
+		dev_err(&client->dev, "No pages configured\n");
+		ret = -ENODEV;
+		goto out;
+	}
+
+	/* The internal temperature sensor is always active */
+	info->func[0] = PMBUS_HAVE_TEMP;
+
+	/* Everything else is configurable */
+	ret = i2c_smbus_read_block_data(client, UCD9000_MONITOR_CONFIG,
+					block_buffer);
+	if (ret <= 0) {
+		dev_err(&client->dev, "Failed to read configuration data\n");
+		ret = -ENODEV;
+		goto out;
+	}
+	for (i = 0; i < ret; i++) {
+		int page = UCD9000_MON_PAGE(block_buffer[i]);
+
+		if (page >= info->pages)
+			continue;
+
+		switch (UCD9000_MON_TYPE(block_buffer[i])) {
+		case UCD9000_MON_VOLTAGE:
+		case UCD9000_MON_VOLTAGE_HW:
+			info->func[page] |= PMBUS_HAVE_VOUT
+			  | PMBUS_HAVE_STATUS_VOUT;
+			break;
+		case UCD9000_MON_TEMPERATURE:
+			info->func[page] |= PMBUS_HAVE_TEMP2
+			  | PMBUS_HAVE_STATUS_TEMP;
+			break;
+		case UCD9000_MON_CURRENT:
+			info->func[page] |= PMBUS_HAVE_IOUT
+			  | PMBUS_HAVE_STATUS_IOUT;
+			break;
+		default:
+			break;
+		}
+	}
+
+	/* Fan configuration */
+	if (mid->driver_data == ucd90124) {
+		for (i = 0; i < UCD9000_NUM_FAN; i++) {
+			i2c_smbus_write_byte_data(client,
+						  UCD9000_FAN_CONFIG_INDEX, i);
+			ret = i2c_smbus_read_block_data(client,
+							UCD9000_FAN_CONFIG,
+							data->fan_data[i]);
+			if (ret < 0)
+				goto out;
+		}
+		i2c_smbus_write_byte_data(client, UCD9000_FAN_CONFIG_INDEX, 0);
+
+		info->read_byte_data = ucd9000_read_byte_data;
+		info->func[0] |= PMBUS_HAVE_FAN12 | PMBUS_HAVE_STATUS_FAN12
+		  | PMBUS_HAVE_FAN34 | PMBUS_HAVE_STATUS_FAN34;
+	}
+
+	ret = pmbus_do_probe(client, mid, info);
+	if (ret < 0)
+		goto out;
+	return 0;
+
+out:
+	kfree(data);
+	return ret;
+}
+
+static int ucd9000_remove(struct i2c_client *client)
+{
+	int ret;
+	struct ucd9000_data *data;
+
+	data = to_ucd9000_data(pmbus_get_driver_info(client));
+	ret = pmbus_do_remove(client);
+	kfree(data);
+	return ret;
+}
+
+
+/* This is the driver that will be inserted */
+static struct i2c_driver ucd9000_driver = {
+	.driver = {
+		.name = "ucd9000",
+	},
+	.probe = ucd9000_probe,
+	.remove = ucd9000_remove,
+	.id_table = ucd9000_id,
+};
+
+static int __init ucd9000_init(void)
+{
+	return i2c_add_driver(&ucd9000_driver);
+}
+
+static void __exit ucd9000_exit(void)
+{
+	i2c_del_driver(&ucd9000_driver);
+}
+
+MODULE_AUTHOR("Guenter Roeck");
+MODULE_DESCRIPTION("PMBus driver for TI UCD90xxx");
+MODULE_LICENSE("GPL");
+module_init(ucd9000_init);
+module_exit(ucd9000_exit);
diff -druN linux-2.6.39-libre/drivers/hwmon/ucd9200.c linux-3.0-rc7-libre/drivers/hwmon/ucd9200.c
--- linux-2.6.39-libre/drivers/hwmon/ucd9200.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/hwmon/ucd9200.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,210 @@
+/*
+ * Hardware monitoring driver for ucd9200 series Digital PWM System Controllers
+ *
+ * Copyright (C) 2011 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 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the 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/err.h>
+#include <linux/slab.h>
+#include <linux/i2c.h>
+#include <linux/i2c/pmbus.h>
+#include "pmbus.h"
+
+#define UCD9200_PHASE_INFO	0xd2
+#define UCD9200_DEVICE_ID	0xfd
+
+enum chips { ucd9200, ucd9220, ucd9222, ucd9224, ucd9240, ucd9244, ucd9246,
+	     ucd9248 };
+
+static const struct i2c_device_id ucd9200_id[] = {
+	{"ucd9200", ucd9200},
+	{"ucd9220", ucd9220},
+	{"ucd9222", ucd9222},
+	{"ucd9224", ucd9224},
+	{"ucd9240", ucd9240},
+	{"ucd9244", ucd9244},
+	{"ucd9246", ucd9246},
+	{"ucd9248", ucd9248},
+	{}
+};
+MODULE_DEVICE_TABLE(i2c, ucd9200_id);
+
+static int ucd9200_probe(struct i2c_client *client,
+			 const struct i2c_device_id *id)
+{
+	u8 block_buffer[I2C_SMBUS_BLOCK_MAX + 1];
+	struct pmbus_driver_info *info;
+	const struct i2c_device_id *mid;
+	int i, j, ret;
+
+	if (!i2c_check_functionality(client->adapter,
+				     I2C_FUNC_SMBUS_BYTE_DATA |
+				     I2C_FUNC_SMBUS_BLOCK_DATA))
+		return -ENODEV;
+
+	ret = i2c_smbus_read_block_data(client, UCD9200_DEVICE_ID,
+					block_buffer);
+	if (ret < 0) {
+		dev_err(&client->dev, "Failed to read device ID\n");
+		return ret;
+	}
+	block_buffer[ret] = '\0';
+	dev_info(&client->dev, "Device ID %s\n", block_buffer);
+
+	mid = NULL;
+	for (i = 0; i < ARRAY_SIZE(ucd9200_id); i++) {
+		mid = &ucd9200_id[i];
+		if (!strncasecmp(mid->name, block_buffer, strlen(mid->name)))
+			break;
+	}
+	if (!mid || !strlen(mid->name)) {
+		dev_err(&client->dev, "Unsupported device\n");
+		return -ENODEV;
+	}
+	if (id->driver_data != ucd9200 && id->driver_data != mid->driver_data)
+		dev_notice(&client->dev,
+			   "Device mismatch: Configured %s, detected %s\n",
+			   id->name, mid->name);
+
+	info = kzalloc(sizeof(struct pmbus_driver_info), GFP_KERNEL);
+	if (!info)
+		return -ENOMEM;
+
+	ret = i2c_smbus_read_block_data(client, UCD9200_PHASE_INFO,
+					block_buffer);
+	if (ret < 0) {
+		dev_err(&client->dev, "Failed to read phase information\n");
+		goto out;
+	}
+
+	/*
+	 * Calculate number of configured pages (rails) from PHASE_INFO
+	 * register.
+	 * Rails have to be sequential, so we can abort after finding
+	 * the first unconfigured rail.
+	 */
+	info->pages = 0;
+	for (i = 0; i < ret; i++) {
+		if (!block_buffer[i])
+			break;
+		info->pages++;
+	}
+	if (!info->pages) {
+		dev_err(&client->dev, "No rails configured\n");
+		ret = -ENODEV;
+		goto out;
+	}
+	dev_info(&client->dev, "%d rails configured\n", info->pages);
+
+	/*
+	 * Set PHASE registers on all pages to 0xff to ensure that phase
+	 * specific commands will apply to all phases of a given page (rail).
+	 * This only affects the READ_IOUT and READ_TEMPERATURE2 registers.
+	 * READ_IOUT will return the sum of currents of all phases of a rail,
+	 * and READ_TEMPERATURE2 will return the maximum temperature detected
+	 * for the the phases of the rail.
+	 */
+	for (i = 0; i < info->pages; i++) {
+		/*
+		 * Setting PAGE & PHASE fails once in a while for no obvious
+		 * reason, so we need to retry a couple of times.
+		 */
+		for (j = 0; j < 3; j++) {
+			ret = i2c_smbus_write_byte_data(client, PMBUS_PAGE, i);
+			if (ret < 0)
+				continue;
+			ret = i2c_smbus_write_byte_data(client, PMBUS_PHASE,
+							0xff);
+			if (ret < 0)
+				continue;
+			break;
+		}
+		if (ret < 0) {
+			dev_err(&client->dev,
+				"Failed to initialize PHASE registers\n");
+			goto out;
+		}
+	}
+	if (info->pages > 1)
+		i2c_smbus_write_byte_data(client, PMBUS_PAGE, 0);
+
+	info->func[0] = PMBUS_HAVE_VIN | PMBUS_HAVE_STATUS_INPUT |
+			PMBUS_HAVE_IIN | PMBUS_HAVE_PIN |
+			PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT |
+			PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT |
+			PMBUS_HAVE_POUT | PMBUS_HAVE_TEMP |
+			PMBUS_HAVE_TEMP2 | PMBUS_HAVE_STATUS_TEMP;
+
+	for (i = 1; i < info->pages; i++)
+		info->func[i] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT |
+			PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT |
+			PMBUS_HAVE_POUT |
+			PMBUS_HAVE_TEMP2 | PMBUS_HAVE_STATUS_TEMP;
+
+	/* ucd9240 supports a single fan */
+	if (mid->driver_data == ucd9240)
+		info->func[0] |= PMBUS_HAVE_FAN12 | PMBUS_HAVE_STATUS_FAN12;
+
+	ret = pmbus_do_probe(client, mid, info);
+	if (ret < 0)
+		goto out;
+	return 0;
+out:
+	kfree(info);
+	return ret;
+}
+
+static int ucd9200_remove(struct i2c_client *client)
+{
+	int ret;
+	const struct pmbus_driver_info *info;
+
+	info = pmbus_get_driver_info(client);
+	ret = pmbus_do_remove(client);
+	kfree(info);
+	return ret;
+}
+
+
+/* This is the driver that will be inserted */
+static struct i2c_driver ucd9200_driver = {
+	.driver = {
+		.name = "ucd9200",
+	},
+	.probe = ucd9200_probe,
+	.remove = ucd9200_remove,
+	.id_table = ucd9200_id,
+};
+
+static int __init ucd9200_init(void)
+{
+	return i2c_add_driver(&ucd9200_driver);
+}
+
+static void __exit ucd9200_exit(void)
+{
+	i2c_del_driver(&ucd9200_driver);
+}
+
+MODULE_AUTHOR("Guenter Roeck");
+MODULE_DESCRIPTION("PMBus driver for TI UCD922x, UCD924x");
+MODULE_LICENSE("GPL");
+module_init(ucd9200_init);
+module_exit(ucd9200_exit);
diff -druN linux-2.6.39-libre/drivers/hwmon/ultra45_env.c linux-3.0-rc7-libre/drivers/hwmon/ultra45_env.c
--- linux-2.6.39-libre/drivers/hwmon/ultra45_env.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/hwmon/ultra45_env.c	2011-07-11 19:51:52.000000000 -0400
@@ -258,7 +258,7 @@
 		goto out_sysfs_remove_group;
 	}
 
-	dev_set_drvdata(&op->dev, p);
+	platform_set_drvdata(op, p);
 	err = 0;
 
 out:
@@ -277,7 +277,7 @@
 
 static int __devexit env_remove(struct platform_device *op)
 {
-	struct env *p = dev_get_drvdata(&op->dev);
+	struct env *p = platform_get_drvdata(op);
 
 	if (p) {
 		sysfs_remove_group(&op->dev.kobj, &env_group);
diff -druN linux-2.6.39-libre/drivers/i2c/busses/i2c-bfin-twi.c linux-3.0-rc7-libre/drivers/i2c/busses/i2c-bfin-twi.c
--- linux-2.6.39-libre/drivers/i2c/busses/i2c-bfin-twi.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/i2c/busses/i2c-bfin-twi.c	2011-07-11 19:51:52.000000000 -0400
@@ -193,7 +193,13 @@
 		return;
 	}
 	if (twi_int_status & MCOMP) {
-		if (iface->cur_mode == TWI_I2C_MODE_COMBINED) {
+		if ((read_MASTER_CTL(iface) & MEN) == 0 &&
+			(iface->cur_mode == TWI_I2C_MODE_REPEAT ||
+			iface->cur_mode == TWI_I2C_MODE_COMBINED)) {
+			iface->result = -1;
+			write_INT_MASK(iface, 0);
+			write_MASTER_CTL(iface, 0);
+		} else if (iface->cur_mode == TWI_I2C_MODE_COMBINED) {
 			if (iface->readNum == 0) {
 				/* set the read number to 1 and ask for manual
 				 * stop in block combine mode
diff -druN linux-2.6.39-libre/drivers/i2c/busses/i2c-eg20t.c linux-3.0-rc7-libre/drivers/i2c/busses/i2c-eg20t.c
--- linux-2.6.39-libre/drivers/i2c/busses/i2c-eg20t.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/i2c/busses/i2c-eg20t.c	2011-07-11 19:51:52.000000000 -0400
@@ -182,10 +182,12 @@
 /* Definition for ML7213 by OKI SEMICONDUCTOR */
 #define PCI_VENDOR_ID_ROHM		0x10DB
 #define PCI_DEVICE_ID_ML7213_I2C	0x802D
+#define PCI_DEVICE_ID_ML7223_I2C	0x8010
 
 static struct pci_device_id __devinitdata pch_pcidev_id[] = {
 	{ PCI_VDEVICE(INTEL, PCI_DEVICE_ID_PCH_I2C),   1, },
 	{ PCI_VDEVICE(ROHM, PCI_DEVICE_ID_ML7213_I2C), 2, },
+	{ PCI_VDEVICE(ROHM, PCI_DEVICE_ID_ML7223_I2C), 1, },
 	{0,}
 };
 
diff -druN linux-2.6.39-libre/drivers/i2c/busses/i2c-gpio.c linux-3.0-rc7-libre/drivers/i2c/busses/i2c-gpio.c
--- linux-2.6.39-libre/drivers/i2c/busses/i2c-gpio.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/i2c/busses/i2c-gpio.c	2011-07-11 19:51:52.000000000 -0400
@@ -219,7 +219,7 @@
 }
 module_exit(i2c_gpio_exit);
 
-MODULE_AUTHOR("Haavard Skinnemoen <hskinnemoen@atmel.com>");
+MODULE_AUTHOR("Haavard Skinnemoen (Atmel)");
 MODULE_DESCRIPTION("Platform-independent bitbanging I2C driver");
 MODULE_LICENSE("GPL");
 MODULE_ALIAS("platform:i2c-gpio");
diff -druN linux-2.6.39-libre/drivers/i2c/busses/i2c-i801.c linux-3.0-rc7-libre/drivers/i2c/busses/i2c-i801.c
--- linux-2.6.39-libre/drivers/i2c/busses/i2c-i801.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/i2c/busses/i2c-i801.c	2011-07-11 19:51:52.000000000 -0400
@@ -50,6 +50,7 @@
   Patsburg (PCH) IDF    0x1d71     32     hard     yes     yes     yes
   Patsburg (PCH) IDF    0x1d72     32     hard     yes     yes     yes
   DH89xxCC (PCH)        0x2330     32     hard     yes     yes     yes
+  Panther Point (PCH)   0x1e22     32     hard     yes     yes     yes
 
   Features supported by this driver:
   Software PEC                     no
@@ -141,6 +142,7 @@
 #define PCI_DEVICE_ID_INTEL_PATSBURG_SMBUS_IDF0	0x1d70
 #define PCI_DEVICE_ID_INTEL_PATSBURG_SMBUS_IDF1	0x1d71
 #define PCI_DEVICE_ID_INTEL_PATSBURG_SMBUS_IDF2	0x1d72
+#define PCI_DEVICE_ID_INTEL_PANTHERPOINT_SMBUS	0x1e22
 #define PCI_DEVICE_ID_INTEL_DH89XXCC_SMBUS	0x2330
 #define PCI_DEVICE_ID_INTEL_5_3400_SERIES_SMBUS	0x3b30
 
@@ -158,6 +160,8 @@
 #define FEATURE_BLOCK_BUFFER	(1 << 1)
 #define FEATURE_BLOCK_PROC	(1 << 2)
 #define FEATURE_I2C_BLOCK_READ	(1 << 3)
+/* Not really a feature, but it's convenient to handle it as such */
+#define FEATURE_IDF		(1 << 15)
 
 static const char *i801_feature_names[] = {
 	"SMBus PEC",
@@ -628,12 +632,13 @@
 	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_PATSBURG_SMBUS_IDF1) },
 	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_PATSBURG_SMBUS_IDF2) },
 	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_DH89XXCC_SMBUS) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_PANTHERPOINT_SMBUS) },
 	{ 0, }
 };
 
 MODULE_DEVICE_TABLE(pci, i801_ids);
 
-#if defined CONFIG_INPUT_APANEL || defined CONFIG_INPUT_APANEL_MODULE
+#if defined CONFIG_X86 && defined CONFIG_DMI
 static unsigned char apanel_addr;
 
 /* Scan the system ROM for the signature "FJKEYINF" */
@@ -663,11 +668,7 @@
 	}
 	iounmap(bios);
 }
-#else
-static void __init input_apanel_init(void) {}
-#endif
 
-#if defined CONFIG_SENSORS_FSCHMD || defined CONFIG_SENSORS_FSCHMD_MODULE
 struct dmi_onboard_device_info {
 	const char *name;
 	u8 type;
@@ -733,7 +734,30 @@
 		dmi_check_onboard_device(type, name, adap);
 	}
 }
-#endif
+
+/* Register optional slaves */
+static void __devinit i801_probe_optional_slaves(struct i801_priv *priv)
+{
+	/* Only register slaves on main SMBus channel */
+	if (priv->features & FEATURE_IDF)
+		return;
+
+	if (apanel_addr) {
+		struct i2c_board_info info;
+
+		memset(&info, 0, sizeof(struct i2c_board_info));
+		info.addr = apanel_addr;
+		strlcpy(info.type, "fujitsu_apanel", I2C_NAME_SIZE);
+		i2c_new_device(&priv->adapter, &info);
+	}
+
+	if (dmi_name_in_vendors("FUJITSU"))
+		dmi_walk(dmi_check_onboard_devices, &priv->adapter);
+}
+#else
+static void __init input_apanel_init(void) {}
+static void __devinit i801_probe_optional_slaves(struct i801_priv *priv) {}
+#endif	/* CONFIG_X86 && CONFIG_DMI */
 
 static int __devinit i801_probe(struct pci_dev *dev,
 				const struct pci_device_id *id)
@@ -753,6 +777,11 @@
 
 	priv->pci_dev = dev;
 	switch (dev->device) {
+	case PCI_DEVICE_ID_INTEL_PATSBURG_SMBUS_IDF0:
+	case PCI_DEVICE_ID_INTEL_PATSBURG_SMBUS_IDF1:
+	case PCI_DEVICE_ID_INTEL_PATSBURG_SMBUS_IDF2:
+		priv->features |= FEATURE_IDF;
+		/* fall through */
 	default:
 		priv->features |= FEATURE_I2C_BLOCK_READ;
 		/* fall through */
@@ -838,21 +867,7 @@
 		goto exit_release;
 	}
 
-	/* Register optional slaves */
-#if defined CONFIG_INPUT_APANEL || defined CONFIG_INPUT_APANEL_MODULE
-	if (apanel_addr) {
-		struct i2c_board_info info;
-
-		memset(&info, 0, sizeof(struct i2c_board_info));
-		info.addr = apanel_addr;
-		strlcpy(info.type, "fujitsu_apanel", I2C_NAME_SIZE);
-		i2c_new_device(&priv->adapter, &info);
-	}
-#endif
-#if defined CONFIG_SENSORS_FSCHMD || defined CONFIG_SENSORS_FSCHMD_MODULE
-	if (dmi_name_in_vendors("FUJITSU"))
-		dmi_walk(dmi_check_onboard_devices, &priv->adapter);
-#endif
+	i801_probe_optional_slaves(priv);
 
 	pci_set_drvdata(dev, priv);
 	return 0;
@@ -912,7 +927,8 @@
 
 static int __init i2c_i801_init(void)
 {
-	input_apanel_init();
+	if (dmi_name_in_vendors("FUJITSU"))
+		input_apanel_init();
 	return pci_register_driver(&i801_driver);
 }
 
diff -druN linux-2.6.39-libre/drivers/i2c/busses/i2c-nomadik.c linux-3.0-rc7-libre/drivers/i2c/busses/i2c-nomadik.c
--- linux-2.6.39-libre/drivers/i2c/busses/i2c-nomadik.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/i2c/busses/i2c-nomadik.c	2011-07-11 19:51:52.000000000 -0400
@@ -15,13 +15,14 @@
 #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 <linux/regulator/consumer.h>
+#include <linux/pm_runtime.h>
 
 #include <plat/i2c.h>
 
@@ -103,9 +104,6 @@
 /* maximum threshold value */
 #define MAX_I2C_FIFO_THRESHOLD	15
 
-/* per-transfer delay, required for the hardware to stabilize */
-#define I2C_DELAY		150
-
 enum i2c_status {
 	I2C_NOP,
 	I2C_ON_GOING,
@@ -120,9 +118,6 @@
 	I2C_READ = 0x01
 };
 
-/* controller response timeout in ms */
-#define I2C_TIMEOUT_MS	2000
-
 /**
  * struct i2c_nmk_client - client specific data
  * @slave_adr: 7-bit slave address
@@ -151,6 +146,7 @@
  * @stop: stop condition
  * @xfer_complete: acknowledge completion for a I2C message
  * @result: controller propogated result
+ * @busy: Busy doing transfer
  */
 struct nmk_i2c_dev {
 	struct platform_device		*pdev;
@@ -163,6 +159,8 @@
 	int 				stop;
 	struct completion		xfer_complete;
 	int 				result;
+	struct regulator		*regulator;
+	bool				busy;
 };
 
 /* controller's abort causes */
@@ -209,7 +207,7 @@
 	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);
+		timeout = jiffies + dev->adap.timeout;
 
 		while (!time_after(jiffies, timeout)) {
 			if ((readl(dev->virtbase + I2C_CR) &
@@ -253,11 +251,9 @@
 {
 	int stat;
 
-	clk_enable(dev->clk);
-
 	stat = flush_i2c_fifo(dev);
 	if (stat)
-		return stat;
+		goto exit;
 
 	/* disable the controller */
 	i2c_clr_bit(dev->virtbase + I2C_CR , I2C_CR_PE);
@@ -268,10 +264,8 @@
 
 	dev->cli.operation = I2C_NO_OPERATION;
 
-	clk_disable(dev->clk);
-
-	udelay(I2C_DELAY);
-	return 0;
+exit:
+	return stat;
 }
 
 /* enable peripheral, master mode operation */
@@ -424,7 +418,7 @@
 			dev->virtbase + I2C_IMSCR);
 
 	timeout = wait_for_completion_interruptible_timeout(
-		&dev->xfer_complete, msecs_to_jiffies(I2C_TIMEOUT_MS));
+		&dev->xfer_complete, dev->adap.timeout);
 
 	if (timeout < 0) {
 		dev_err(&dev->pdev->dev,
@@ -434,14 +428,32 @@
 	}
 
 	if (timeout == 0) {
-		/* controller has timedout, re-init the h/w */
-		dev_err(&dev->pdev->dev, "controller timed out, re-init h/w\n");
-		(void) init_hw(dev);
+		/* Controller timed out */
+		dev_err(&dev->pdev->dev, "read from slave 0x%x timed out\n",
+				dev->cli.slave_adr);
 		status = -ETIMEDOUT;
 	}
 	return status;
 }
 
+static void fill_tx_fifo(struct nmk_i2c_dev *dev, int no_bytes)
+{
+	int count;
+
+	for (count = (no_bytes - 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++;
+	}
+
+}
+
 /**
  * write_i2c() - Write data to I2C client.
  * @dev: private data of I2C Driver
@@ -469,8 +481,13 @@
 	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);
+	irq_mask = (I2C_IT_TXFOVR | I2C_IT_MAL | I2C_IT_BERR);
+
+	/* Fill the TX FIFO with transmit data */
+	fill_tx_fifo(dev, MAX_I2C_FIFO_THRESHOLD);
+
+	if (dev->cli.count != 0)
+		irq_mask |= I2C_IT_TXFNE;
 
 	/*
 	 * check if we want to transfer a single or multiple bytes, if so
@@ -488,7 +505,7 @@
 			dev->virtbase + I2C_IMSCR);
 
 	timeout = wait_for_completion_interruptible_timeout(
-		&dev->xfer_complete, msecs_to_jiffies(I2C_TIMEOUT_MS));
+		&dev->xfer_complete, dev->adap.timeout);
 
 	if (timeout < 0) {
 		dev_err(&dev->pdev->dev,
@@ -498,9 +515,9 @@
 	}
 
 	if (timeout == 0) {
-		/* controller has timedout, re-init the h/w */
-		dev_err(&dev->pdev->dev, "controller timed out, re-init h/w\n");
-		(void) init_hw(dev);
+		/* Controller timed out */
+		dev_err(&dev->pdev->dev, "write to slave 0x%x timed out\n",
+				dev->cli.slave_adr);
 		status = -ETIMEDOUT;
 	}
 
@@ -508,6 +525,51 @@
 }
 
 /**
+ * nmk_i2c_xfer_one() - transmit a single I2C message
+ * @dev: device with a message encoded into it
+ * @flags: message flags
+ */
+static int nmk_i2c_xfer_one(struct nmk_i2c_dev *dev, u16 flags)
+{
+	int status;
+
+	if (flags & I2C_M_RD) {
+		/* 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)) {
+		u32 i2c_sr;
+		u32 cause;
+
+		i2c_sr = readl(dev->virtbase + I2C_SR);
+		/*
+		 * Check if the controller I2C operation status
+		 * is set to ABORT(11b).
+		 */
+		if (((i2c_sr >> 2) & 0x3) == 0x3) {
+			/* get the abort cause */
+			cause =	(i2c_sr >> 4) & 0x7;
+			dev_err(&dev->pdev->dev, "%s\n", cause
+				>= ARRAY_SIZE(abort_causes) ?
+				"unknown reason" :
+				abort_causes[cause]);
+		}
+
+		(void) init_hw(dev);
+
+		status = status ? status : dev->result;
+	}
+
+	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.
@@ -559,53 +621,55 @@
 {
 	int status;
 	int i;
-	u32 cause;
 	struct nmk_i2c_dev *dev = i2c_get_adapdata(i2c_adap);
+	int j;
+
+	dev->busy = true;
+
+	if (dev->regulator)
+		regulator_enable(dev->regulator);
+	pm_runtime_get_sync(&dev->pdev->dev);
+
+	clk_enable(dev->clk);
 
 	status = init_hw(dev);
 	if (status)
-		return status;
+		goto out;
 
-	clk_enable(dev->clk);
+	/* Attempt three times to send the message queue */
+	for (j = 0; j < 3; j++) {
+		/* setup the i2c controller */
+		setup_i2c_controller(dev);
 
-	/* 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");
 
-	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;
+				status = -EINVAL;
+				goto out;
+			}
+			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]);
-			clk_disable(dev->clk);
-			return status;
+			status = nmk_i2c_xfer_one(dev, msgs[i].flags);
+			if (status != 0)
+				break;
 		}
-		udelay(I2C_DELAY);
+		if (status == 0)
+			break;
 	}
+
+out:
 	clk_disable(dev->clk);
+	pm_runtime_put_sync(&dev->pdev->dev);
+	if (dev->regulator)
+		regulator_disable(dev->regulator);
+
+	dev->busy = false;
 
 	/* return the no. messages processed */
 	if (status)
@@ -666,17 +730,7 @@
 			 */
 			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++;
-			}
+			fill_tx_fifo(dev, (MAX_I2C_FIFO_THRESHOLD - tft));
 			/*
 			 * if done, close the transfer by disabling the
 			 * corresponding TXFNE interrupt
@@ -729,16 +783,11 @@
 			}
 		}
 
-		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));
+		disable_all_interrupts(dev);
+		clear_all_interrupts(dev);
 
 		if (dev->cli.count) {
-			dev->result = -1;
+			dev->result = -EIO;
 			dev_err(&dev->pdev->dev, "%lu bytes still remain to be"
 					"xfered\n", dev->cli.count);
 			(void) init_hw(dev);
@@ -749,7 +798,7 @@
 
 	/* Master Arbitration lost interrupt */
 	case I2C_IT_MAL:
-		dev->result = -1;
+		dev->result = -EIO;
 		(void) init_hw(dev);
 
 		i2c_set_bit(dev->virtbase + I2C_ICR, I2C_IT_MAL);
@@ -763,7 +812,7 @@
 	 * during the transaction.
 	 */
 	case I2C_IT_BERR:
-		dev->result = -1;
+		dev->result = -EIO;
 		/* get the status */
 		if (((readl(dev->virtbase + I2C_SR) >> 2) & 0x3) == I2C_ABORT)
 			(void) init_hw(dev);
@@ -779,7 +828,7 @@
 	 * the Tx FIFO is full.
 	 */
 	case I2C_IT_TXFOVR:
-		dev->result = -1;
+		dev->result = -EIO;
 		(void) init_hw(dev);
 
 		dev_err(&dev->pdev->dev, "Tx Fifo Over run\n");
@@ -805,6 +854,38 @@
 	return IRQ_HANDLED;
 }
 
+
+#ifdef CONFIG_PM
+static int nmk_i2c_suspend(struct device *dev)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct nmk_i2c_dev *nmk_i2c = platform_get_drvdata(pdev);
+
+	if (nmk_i2c->busy)
+		return -EBUSY;
+
+	return 0;
+}
+
+static int nmk_i2c_resume(struct device *dev)
+{
+	return 0;
+}
+#else
+#define nmk_i2c_suspend	NULL
+#define nmk_i2c_resume	NULL
+#endif
+
+/*
+ * We use noirq so that we suspend late and resume before the wakeup interrupt
+ * to ensure that we do the !pm_runtime_suspended() check in resume before
+ * there has been a regular pm runtime resume (via pm_runtime_get_sync()).
+ */
+static const struct dev_pm_ops nmk_i2c_pm = {
+	.suspend_noirq	= nmk_i2c_suspend,
+	.resume_noirq	= nmk_i2c_resume,
+};
+
 static unsigned int nmk_i2c_functionality(struct i2c_adapter *adap)
 {
 	return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
@@ -830,7 +911,7 @@
 		ret = -ENOMEM;
 		goto err_no_mem;
 	}
-
+	dev->busy = false;
 	dev->pdev = pdev;
 	platform_set_drvdata(pdev, dev);
 
@@ -860,6 +941,15 @@
 		goto err_irq;
 	}
 
+	dev->regulator = regulator_get(&pdev->dev, "v-i2c");
+	if (IS_ERR(dev->regulator)) {
+		dev_warn(&pdev->dev, "could not get i2c regulator\n");
+		dev->regulator = NULL;
+	}
+
+	pm_suspend_ignore_children(&pdev->dev, true);
+	pm_runtime_enable(&pdev->dev);
+
 	dev->clk = clk_get(&pdev->dev, NULL);
 	if (IS_ERR(dev->clk)) {
 		dev_err(&pdev->dev, "could not get i2c clock\n");
@@ -872,6 +962,8 @@
 	adap->owner	= THIS_MODULE;
 	adap->class	= I2C_CLASS_HWMON | I2C_CLASS_SPD;
 	adap->algo	= &nmk_i2c_algo;
+	adap->timeout	= pdata->timeout ? msecs_to_jiffies(pdata->timeout) :
+		msecs_to_jiffies(20000);
 	snprintf(adap->name, sizeof(adap->name),
 		 "Nomadik I2C%d at %lx", pdev->id, (unsigned long)res->start);
 
@@ -887,12 +979,6 @@
 
 	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_info(&pdev->dev, "initialize %s on virtual "
 		"base %p\n", adap->name, dev->virtbase);
 
@@ -904,10 +990,12 @@
 
 	return 0;
 
- err_init_hw:
  err_add_adap:
 	clk_put(dev->clk);
  err_no_clk:
+	if (dev->regulator)
+		regulator_put(dev->regulator);
+	pm_runtime_disable(&pdev->dev);
 	free_irq(dev->irq, dev);
  err_irq:
 	iounmap(dev->virtbase);
@@ -938,6 +1026,9 @@
 	if (res)
 		release_mem_region(res->start, resource_size(res));
 	clk_put(dev->clk);
+	if (dev->regulator)
+		regulator_put(dev->regulator);
+	pm_runtime_disable(&pdev->dev);
 	platform_set_drvdata(pdev, NULL);
 	kfree(dev);
 
@@ -948,6 +1039,7 @@
 	.driver = {
 		.owner = THIS_MODULE,
 		.name = DRIVER_NAME,
+		.pm = &nmk_i2c_pm,
 	},
 	.probe = nmk_i2c_probe,
 	.remove = __devexit_p(nmk_i2c_remove),
diff -druN linux-2.6.39-libre/drivers/i2c/busses/i2c-ocores.c linux-3.0-rc7-libre/drivers/i2c/busses/i2c-ocores.c
--- linux-2.6.39-libre/drivers/i2c/busses/i2c-ocores.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/i2c/busses/i2c-ocores.c	2011-07-11 19:51:52.000000000 -0400
@@ -49,7 +49,6 @@
 #include <linux/init.h>
 #include <linux/errno.h>
 #include <linux/platform_device.h>
-#include <linux/mfd/core.h>
 #include <linux/i2c.h>
 #include <linux/interrupt.h>
 #include <linux/wait.h>
@@ -306,7 +305,7 @@
 		return -EIO;
 	}
 
-	pdata = mfd_get_data(pdev);
+	pdata = pdev->dev.platform_data;
 	if (pdata) {
 		i2c->regstep = pdata->regstep;
 		i2c->clock_khz = pdata->clock_khz;
diff -druN linux-2.6.39-libre/drivers/i2c/busses/i2c-parport.c linux-3.0-rc7-libre/drivers/i2c/busses/i2c-parport.c
--- linux-2.6.39-libre/drivers/i2c/busses/i2c-parport.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/i2c/busses/i2c-parport.c	2011-07-11 19:51:52.000000000 -0400
@@ -2,13 +2,13 @@
  * i2c-parport.c I2C bus over parallel port                                 *
  * ------------------------------------------------------------------------ *
    Copyright (C) 2003-2011 Jean Delvare <khali@linux-fr.org>
-   
+
    Based on older i2c-philips-par.c driver
    Copyright (C) 1995-2000 Simon G. Vogl
    With some changes from:
    Frodo Looijaard <frodol@dds.nl>
    Kyösti Mälkki <kmalkki@cc.hut.fi>
-   
+
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
@@ -78,13 +78,13 @@
 	return parport_read_control(p);
 }
 
-static void (*port_write[])(struct parport *, unsigned char) = {
+static void (* const port_write[])(struct parport *, unsigned char) = {
 	port_write_data,
 	NULL,
 	port_write_control,
 };
 
-static unsigned char (*port_read[])(struct parport *) = {
+static unsigned char (* const port_read[])(struct parport *) = {
 	port_read_data,
 	port_read_status,
 	port_read_control,
@@ -147,7 +147,7 @@
 	.getscl		= parport_getscl,
 	.udelay		= 10, /* ~50 kbps */
 	.timeout	= HZ,
-}; 
+};
 
 /* ----- I2c and parallel port call-back functions and structures --------- */
 
@@ -164,10 +164,10 @@
 			"SMBus alert received but no ARA client!\n");
 }
 
-static void i2c_parport_attach (struct parport *port)
+static void i2c_parport_attach(struct parport *port)
 {
 	struct i2c_par *adapter;
-	
+
 	adapter = kzalloc(sizeof(struct i2c_par), GFP_KERNEL);
 	if (adapter == NULL) {
 		printk(KERN_ERR "i2c-parport: Failed to kzalloc\n");
@@ -180,7 +180,7 @@
 		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;
+		goto err_free;
 	}
 
 	/* Fill the rest of the structure */
@@ -200,7 +200,7 @@
 
 	if (parport_claim_or_block(adapter->pdev) < 0) {
 		printk(KERN_ERR "i2c-parport: Could not claim parallel port\n");
-		goto ERROR1;
+		goto err_unregister;
 	}
 
 	/* Reset hardware to a sane state (SCL and SDA high) */
@@ -215,7 +215,7 @@
 
 	if (i2c_bit_add_bus(&adapter->adapter) < 0) {
 		printk(KERN_ERR "i2c-parport: Unable to register with I2C\n");
-		goto ERROR1;
+		goto err_unregister;
 	}
 
 	/* Setup SMBus alert if supported */
@@ -234,16 +234,16 @@
 	mutex_lock(&adapter_list_lock);
 	list_add_tail(&adapter->node, &adapter_list);
 	mutex_unlock(&adapter_list_lock);
-        return;
+	return;
 
-ERROR1:
+ err_unregister:
 	parport_release(adapter->pdev);
 	parport_unregister_device(adapter->pdev);
-ERROR0:
+ err_free:
 	kfree(adapter);
 }
 
-static void i2c_parport_detach (struct parport *port)
+static void i2c_parport_detach(struct parport *port)
 {
 	struct i2c_par *adapter, *_n;
 
@@ -260,7 +260,7 @@
 			/* Un-init if needed (power off...) */
 			if (adapter_parm[type].init.val)
 				line_set(port, 0, &adapter_parm[type].init);
-				
+
 			parport_release(adapter->pdev);
 			parport_unregister_device(adapter->pdev);
 			list_del(&adapter->node);
diff -druN linux-2.6.39-libre/drivers/i2c/busses/i2c-parport.h linux-3.0-rc7-libre/drivers/i2c/busses/i2c-parport.h
--- linux-2.6.39-libre/drivers/i2c/busses/i2c-parport.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/i2c/busses/i2c-parport.h	2011-07-11 19:51:52.000000000 -0400
@@ -2,7 +2,7 @@
  * i2c-parport.h I2C bus over parallel port                                 *
  * ------------------------------------------------------------------------ *
    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
    the Free Software Foundation; either version 2 of the License, or
@@ -18,13 +18,9 @@
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  * ------------------------------------------------------------------------ */
 
-#ifdef DATA
-#undef DATA
-#endif
-
-#define DATA	0
-#define STAT	1
-#define CTRL	2
+#define PORT_DATA	0
+#define PORT_STAT	1
+#define PORT_CTRL	2
 
 struct lineop {
 	u8 val;
@@ -41,61 +37,61 @@
 	unsigned int smbus_alert:1;
 };
 
-static struct adapter_parm adapter_parm[] = {
+static const struct adapter_parm adapter_parm[] = {
 	/* type 0: Philips adapter */
 	{
-		.setsda	= { 0x80, DATA, 1 },
-		.setscl	= { 0x08, CTRL, 0 },
-		.getsda	= { 0x80, STAT, 0 },
-		.getscl	= { 0x08, STAT, 0 },
+		.setsda	= { 0x80, PORT_DATA, 1 },
+		.setscl	= { 0x08, PORT_CTRL, 0 },
+		.getsda	= { 0x80, PORT_STAT, 0 },
+		.getscl	= { 0x08, PORT_STAT, 0 },
 	},
 	/* type 1: home brew teletext adapter */
 	{
-		.setsda	= { 0x02, DATA, 0 },
-		.setscl	= { 0x01, DATA, 0 },
-		.getsda	= { 0x80, STAT, 1 },
+		.setsda	= { 0x02, PORT_DATA, 0 },
+		.setscl	= { 0x01, PORT_DATA, 0 },
+		.getsda	= { 0x80, PORT_STAT, 1 },
 	},
 	/* type 2: Velleman K8000 adapter */
 	{
-		.setsda	= { 0x02, CTRL, 1 },
-		.setscl	= { 0x08, CTRL, 1 },
-		.getsda	= { 0x10, STAT, 0 },
+		.setsda	= { 0x02, PORT_CTRL, 1 },
+		.setscl	= { 0x08, PORT_CTRL, 1 },
+		.getsda	= { 0x10, PORT_STAT, 0 },
 	},
 	/* type 3: ELV adapter */
 	{
-		.setsda	= { 0x02, DATA, 1 },
-		.setscl	= { 0x01, DATA, 1 },
-		.getsda	= { 0x40, STAT, 1 },
-		.getscl	= { 0x08, STAT, 1 },
+		.setsda	= { 0x02, PORT_DATA, 1 },
+		.setscl	= { 0x01, PORT_DATA, 1 },
+		.getsda	= { 0x40, PORT_STAT, 1 },
+		.getscl	= { 0x08, PORT_STAT, 1 },
 	},
 	/* type 4: ADM1032 evaluation board */
 	{
-		.setsda	= { 0x02, DATA, 1 },
-		.setscl	= { 0x01, DATA, 1 },
-		.getsda	= { 0x10, STAT, 1 },
-		.init	= { 0xf0, DATA, 0 },
+		.setsda	= { 0x02, PORT_DATA, 1 },
+		.setscl	= { 0x01, PORT_DATA, 1 },
+		.getsda	= { 0x10, PORT_STAT, 1 },
+		.init	= { 0xf0, PORT_DATA, 0 },
 		.smbus_alert = 1,
 	},
 	/* type 5: ADM1025, ADM1030 and ADM1031 evaluation boards */
 	{
-		.setsda	= { 0x02, DATA, 1 },
-		.setscl	= { 0x01, DATA, 1 },
-		.getsda	= { 0x10, STAT, 1 },
+		.setsda	= { 0x02, PORT_DATA, 1 },
+		.setscl	= { 0x01, PORT_DATA, 1 },
+		.getsda	= { 0x10, PORT_STAT, 1 },
 	},
 	/* type 6: Barco LPT->DVI (K5800236) adapter */
 	{
-		.setsda	= { 0x02, DATA, 1 },
-		.setscl	= { 0x01, DATA, 1 },
-		.getsda	= { 0x20, STAT, 0 },
-		.getscl	= { 0x40, STAT, 0 },
-		.init	= { 0xfc, DATA, 0 },
+		.setsda	= { 0x02, PORT_DATA, 1 },
+		.setscl	= { 0x01, PORT_DATA, 1 },
+		.getsda	= { 0x20, PORT_STAT, 0 },
+		.getscl	= { 0x40, PORT_STAT, 0 },
+		.init	= { 0xfc, PORT_DATA, 0 },
 	},
 	/* type 7: One For All JP1 parallel port adapter */
 	{
-		.setsda	= { 0x01, DATA, 0 },
-		.setscl	= { 0x02, DATA, 0 },
-		.getsda	= { 0x80, STAT, 1 },
-		.init	= { 0x04, DATA, 1 },
+		.setsda	= { 0x01, PORT_DATA, 0 },
+		.setscl	= { 0x02, PORT_DATA, 0 },
+		.getsda	= { 0x80, PORT_STAT, 1 },
+		.init	= { 0x04, PORT_DATA, 1 },
 	},
 };
 
diff -druN linux-2.6.39-libre/drivers/i2c/busses/i2c-parport-light.c linux-3.0-rc7-libre/drivers/i2c/busses/i2c-parport-light.c
--- linux-2.6.39-libre/drivers/i2c/busses/i2c-parport-light.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/i2c/busses/i2c-parport-light.c	2011-07-11 19:51:52.000000000 -0400
@@ -2,13 +2,13 @@
  * i2c-parport-light.c I2C bus over parallel port                           *
  * ------------------------------------------------------------------------ *
    Copyright (C) 2003-2010 Jean Delvare <khali@linux-fr.org>
-   
+
    Based on older i2c-velleman.c driver
    Copyright (C) 1995-2000 Simon G. Vogl
    With some changes from:
    Frodo Looijaard <frodol@dds.nl>
    Kyösti Mälkki <kmalkki@cc.hut.fi>
-   
+
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
@@ -114,7 +114,7 @@
 	.getscl		= parport_getscl,
 	.udelay		= 50,
 	.timeout	= HZ,
-}; 
+};
 
 /* ----- Driver registration ---------------------------------------------- */
 
@@ -132,7 +132,7 @@
 static struct i2c_client *ara;
 static struct lineop parport_ctrl_irq = {
 	.val		= (1 << 4),
-	.port		= CTRL,
+	.port		= PORT_CTRL,
 };
 
 static int __devinit i2c_parport_probe(struct platform_device *pdev)
@@ -245,7 +245,7 @@
 	if (irq != 0)
 		pr_info(DRVNAME ": using irq %d\n", irq);
 
-        if (!adapter_parm[type].getscl.val)
+	if (!adapter_parm[type].getscl.val)
 		parport_algo_data.getscl = NULL;
 
 	/* Sets global pdev as a side effect */
diff -druN linux-2.6.39-libre/drivers/i2c/busses/i2c-s3c2410.c linux-3.0-rc7-libre/drivers/i2c/busses/i2c-s3c2410.c
--- linux-2.6.39-libre/drivers/i2c/busses/i2c-s3c2410.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/i2c/busses/i2c-s3c2410.c	2011-07-11 19:51:52.000000000 -0400
@@ -248,12 +248,12 @@
 	return i2c->msg_ptr >= i2c->msg->len;
 }
 
-/* i2s_s3c_irq_nextbyte
+/* i2c_s3c_irq_nextbyte
  *
  * process an interrupt and work out what to do
  */
 
-static int i2s_s3c_irq_nextbyte(struct s3c24xx_i2c *i2c, unsigned long iicstat)
+static int i2c_s3c_irq_nextbyte(struct s3c24xx_i2c *i2c, unsigned long iicstat)
 {
 	unsigned long tmp;
 	unsigned char byte;
@@ -264,7 +264,6 @@
 	case STATE_IDLE:
 		dev_err(i2c->dev, "%s: called in STATE_IDLE\n", __func__);
 		goto out;
-		break;
 
 	case STATE_STOP:
 		dev_err(i2c->dev, "%s: called in STATE_STOP\n", __func__);
@@ -444,7 +443,7 @@
 	/* pretty much this leaves us with the fact that we've
 	 * transmitted or received whatever byte we last sent */
 
-	i2s_s3c_irq_nextbyte(i2c, status);
+	i2c_s3c_irq_nextbyte(i2c, status);
 
  out:
 	return IRQ_HANDLED;
diff -druN linux-2.6.39-libre/drivers/i2c/busses/i2c-sh_mobile.c linux-3.0-rc7-libre/drivers/i2c/busses/i2c-sh_mobile.c
--- linux-2.6.39-libre/drivers/i2c/busses/i2c-sh_mobile.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/i2c/busses/i2c-sh_mobile.c	2011-07-11 19:51:52.000000000 -0400
@@ -32,6 +32,7 @@
 #include <linux/clk.h>
 #include <linux/io.h>
 #include <linux/slab.h>
+#include <linux/i2c/i2c-sh_mobile.h>
 
 /* Transmit operation:                                                      */
 /*                                                                          */
@@ -117,7 +118,7 @@
 	struct device *dev;
 	void __iomem *reg;
 	struct i2c_adapter adap;
-
+	unsigned long bus_speed;
 	struct clk *clk;
 	u_int8_t icic;
 	u_int8_t iccl;
@@ -205,7 +206,7 @@
 	 * We also round off the result.
 	 */
 	num = i2c_clk * 5;
-	denom = NORMAL_SPEED * 9;
+	denom = pd->bus_speed * 9;
 	tmp = num * 10 / denom;
 	if (tmp % 10 >= 5)
 		pd->iccl = (u_int8_t)((num/denom) + 1);
@@ -574,10 +575,10 @@
 
 static int sh_mobile_i2c_probe(struct platform_device *dev)
 {
+	struct i2c_sh_mobile_platform_data *pdata = dev->dev.platform_data;
 	struct sh_mobile_i2c_data *pd;
 	struct i2c_adapter *adap;
 	struct resource *res;
-	char clk_name[8];
 	int size;
 	int ret;
 
@@ -587,10 +588,9 @@
 		return -ENOMEM;
 	}
 
-	snprintf(clk_name, sizeof(clk_name), "i2c%d", dev->id);
-	pd->clk = clk_get(&dev->dev, clk_name);
+	pd->clk = clk_get(&dev->dev, NULL);
 	if (IS_ERR(pd->clk)) {
-		dev_err(&dev->dev, "cannot get clock \"%s\"\n", clk_name);
+		dev_err(&dev->dev, "cannot get clock\n");
 		ret = PTR_ERR(pd->clk);
 		goto err;
 	}
@@ -620,6 +620,11 @@
 		goto err_irq;
 	}
 
+	/* Use platformd data bus speed or NORMAL_SPEED */
+	pd->bus_speed = NORMAL_SPEED;
+	if (pdata && pdata->bus_speed)
+		pd->bus_speed = pdata->bus_speed;
+
 	/* The IIC blocks on SH-Mobile ARM processors
 	 * come with two new bits in ICIC.
 	 */
@@ -660,6 +665,8 @@
 		goto err_all;
 	}
 
+	dev_info(&dev->dev, "I2C adapter %d with bus speed %lu Hz\n",
+		 adap->nr, pd->bus_speed);
 	return 0;
 
  err_all:
@@ -729,3 +736,4 @@
 MODULE_DESCRIPTION("SuperH Mobile I2C Bus Controller driver");
 MODULE_AUTHOR("Magnus Damm");
 MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:i2c-sh_mobile");
diff -druN linux-2.6.39-libre/drivers/i2c/busses/i2c-taos-evm.c linux-3.0-rc7-libre/drivers/i2c/busses/i2c-taos-evm.c
--- linux-2.6.39-libre/drivers/i2c/busses/i2c-taos-evm.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/i2c/busses/i2c-taos-evm.c	2011-07-11 19:51:52.000000000 -0400
@@ -234,7 +234,7 @@
 
 	if (taos->state != TAOS_STATE_IDLE) {
 		err = -ENODEV;
-		dev_dbg(&serio->dev, "TAOS EVM reset failed (state=%d, "
+		dev_err(&serio->dev, "TAOS EVM reset failed (state=%d, "
 			"pos=%d)\n", taos->state, taos->pos);
 		goto exit_close;
 	}
@@ -255,7 +255,7 @@
 					 msecs_to_jiffies(250));
 	if (taos->state != TAOS_STATE_IDLE) {
 		err = -ENODEV;
-		dev_err(&adapter->dev, "Echo off failed "
+		dev_err(&serio->dev, "TAOS EVM echo off failed "
 			"(state=%d)\n", taos->state);
 		goto exit_close;
 	}
@@ -263,7 +263,7 @@
 	err = i2c_add_adapter(adapter);
 	if (err)
 		goto exit_close;
-	dev_dbg(&serio->dev, "Connected to TAOS EVM\n");
+	dev_info(&serio->dev, "Connected to TAOS EVM\n");
 
 	taos->client = taos_instantiate_device(adapter);
 	return 0;
@@ -288,7 +288,7 @@
 	serio_set_drvdata(serio, NULL);
 	kfree(taos);
 
-	dev_dbg(&serio->dev, "Disconnected from TAOS EVM\n");
+	dev_info(&serio->dev, "Disconnected from TAOS EVM\n");
 }
 
 static struct serio_device_id taos_serio_ids[] = {
diff -druN linux-2.6.39-libre/drivers/i2c/busses/i2c-tegra.c linux-3.0-rc7-libre/drivers/i2c/busses/i2c-tegra.c
--- linux-2.6.39-libre/drivers/i2c/busses/i2c-tegra.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/i2c/busses/i2c-tegra.c	2011-07-11 19:51:52.000000000 -0400
@@ -35,11 +35,15 @@
 #define BYTES_PER_FIFO_WORD 4
 
 #define I2C_CNFG				0x000
+#define I2C_CNFG_DEBOUNCE_CNT_SHIFT		12
 #define I2C_CNFG_PACKET_MODE_EN			(1<<10)
 #define I2C_CNFG_NEW_MASTER_FSM			(1<<11)
+#define I2C_STATUS				0x01C
 #define I2C_SL_CNFG				0x020
+#define I2C_SL_CNFG_NACK			(1<<1)
 #define I2C_SL_CNFG_NEWSL			(1<<2)
 #define I2C_SL_ADDR1				0x02c
+#define I2C_SL_ADDR2				0x030
 #define I2C_TX_FIFO				0x050
 #define I2C_RX_FIFO				0x054
 #define I2C_PACKET_TRANSFER_STATUS		0x058
@@ -77,6 +81,7 @@
 #define I2C_ERR_NONE				0x00
 #define I2C_ERR_NO_ACK				0x01
 #define I2C_ERR_ARBITRATION_LOST		0x02
+#define I2C_ERR_UNKNOWN_INTERRUPT		0x04
 
 #define PACKET_HEADER0_HEADER_SIZE_SHIFT	28
 #define PACKET_HEADER0_PACKET_ID_SHIFT		16
@@ -121,6 +126,7 @@
 	void __iomem *base;
 	int cont_id;
 	int irq;
+	bool irq_disabled;
 	int is_dvc;
 	struct completion msg_complete;
 	int msg_err;
@@ -325,11 +331,21 @@
 	if (i2c_dev->is_dvc)
 		tegra_dvc_init(i2c_dev);
 
-	val = I2C_CNFG_NEW_MASTER_FSM | I2C_CNFG_PACKET_MODE_EN;
+	val = I2C_CNFG_NEW_MASTER_FSM | I2C_CNFG_PACKET_MODE_EN |
+		(0x2 << I2C_CNFG_DEBOUNCE_CNT_SHIFT);
 	i2c_writel(i2c_dev, val, I2C_CNFG);
 	i2c_writel(i2c_dev, 0, I2C_INT_MASK);
 	clk_set_rate(i2c_dev->clk, i2c_dev->bus_clk_rate * 8);
 
+	if (!i2c_dev->is_dvc) {
+		u32 sl_cfg = i2c_readl(i2c_dev, I2C_SL_CNFG);
+		sl_cfg |= I2C_SL_CNFG_NACK | I2C_SL_CNFG_NEWSL;
+		i2c_writel(i2c_dev, sl_cfg, I2C_SL_CNFG);
+		i2c_writel(i2c_dev, 0xfc, I2C_SL_ADDR1);
+		i2c_writel(i2c_dev, 0x00, I2C_SL_ADDR2);
+
+	}
+
 	val = 7 << I2C_FIFO_CONTROL_TX_TRIG_SHIFT |
 		0 << I2C_FIFO_CONTROL_RX_TRIG_SHIFT;
 	i2c_writel(i2c_dev, val, I2C_FIFO_CONTROL);
@@ -338,6 +354,12 @@
 		err = -ETIMEDOUT;
 
 	clk_disable(i2c_dev->clk);
+
+	if (i2c_dev->irq_disabled) {
+		i2c_dev->irq_disabled = 0;
+		enable_irq(i2c_dev->irq);
+	}
+
 	return err;
 }
 
@@ -350,8 +372,19 @@
 	status = i2c_readl(i2c_dev, I2C_INT_STATUS);
 
 	if (status == 0) {
-		dev_warn(i2c_dev->dev, "interrupt with no status\n");
-		return IRQ_NONE;
+		dev_warn(i2c_dev->dev, "irq status 0 %08x %08x %08x\n",
+			 i2c_readl(i2c_dev, I2C_PACKET_TRANSFER_STATUS),
+			 i2c_readl(i2c_dev, I2C_STATUS),
+			 i2c_readl(i2c_dev, I2C_CNFG));
+		i2c_dev->msg_err |= I2C_ERR_UNKNOWN_INTERRUPT;
+
+		if (!i2c_dev->irq_disabled) {
+			disable_irq_nosync(i2c_dev->irq);
+			i2c_dev->irq_disabled = 1;
+		}
+
+		complete(&i2c_dev->msg_complete);
+		goto err;
 	}
 
 	if (unlikely(status & status_err)) {
@@ -391,6 +424,8 @@
 		I2C_INT_PACKET_XFER_COMPLETE | I2C_INT_TX_FIFO_DATA_REQ |
 		I2C_INT_RX_FIFO_DATA_REQ);
 	i2c_writel(i2c_dev, status, I2C_INT_STATUS);
+	if (i2c_dev->is_dvc)
+		dvc_writel(i2c_dev, DVC_STATUS_I2C_DONE_INTR, DVC_STATUS);
 	return IRQ_HANDLED;
 }
 
@@ -424,12 +459,12 @@
 
 	packet_header = msg->addr << I2C_HEADER_SLAVE_ADDR_SHIFT;
 	packet_header |= I2C_HEADER_IE_ENABLE;
+	if (!stop)
+		packet_header |= I2C_HEADER_REPEAT_START;
 	if (msg->flags & I2C_M_TEN)
 		packet_header |= I2C_HEADER_10BIT_ADDR;
 	if (msg->flags & I2C_M_IGNORE_NAK)
 		packet_header |= I2C_HEADER_CONT_ON_NAK;
-	if (msg->flags & I2C_M_NOSTART)
-		packet_header |= I2C_HEADER_REPEAT_START;
 	if (msg->flags & I2C_M_RD)
 		packet_header |= I2C_HEADER_READ;
 	i2c_writel(i2c_dev, packet_header, I2C_TX_FIFO);
diff -druN linux-2.6.39-libre/drivers/i2c/busses/i2c-xiic.c linux-3.0-rc7-libre/drivers/i2c/busses/i2c-xiic.c
--- linux-2.6.39-libre/drivers/i2c/busses/i2c-xiic.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/i2c/busses/i2c-xiic.c	2011-07-11 19:51:52.000000000 -0400
@@ -34,7 +34,6 @@
 #include <linux/errno.h>
 #include <linux/delay.h>
 #include <linux/platform_device.h>
-#include <linux/mfd/core.h>
 #include <linux/i2c.h>
 #include <linux/interrupt.h>
 #include <linux/wait.h>
@@ -705,7 +704,7 @@
 	if (irq < 0)
 		goto resource_missing;
 
-	pdata = mfd_get_data(pdev);
+	pdata = (struct xiic_i2c_platform_data *) pdev->dev.platform_data;
 	if (!pdata)
 		return -EINVAL;
 
diff -druN linux-2.6.39-libre/drivers/i2c/busses/Kconfig linux-3.0-rc7-libre/drivers/i2c/busses/Kconfig
--- linux-2.6.39-libre/drivers/i2c/busses/Kconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/i2c/busses/Kconfig	2011-07-11 19:51:52.000000000 -0400
@@ -79,6 +79,7 @@
 config I2C_I801
 	tristate "Intel 82801 (ICH/PCH)"
 	depends on PCI
+	select CHECK_SIGNATURE if X86 && DMI
 	help
 	  If you say yes to this option, support will be included for the Intel
 	  801 family of mainboard I2C interfaces.  Specifically, the following
@@ -101,6 +102,7 @@
 	    6 Series (PCH)
 	    Patsburg (PCH)
 	    DH89xxCC (PCH)
+	    Panther Point (PCH)
 
 	  This driver can also be built as a module.  If so, the module
 	  will be called i2c-i801.
@@ -671,15 +673,19 @@
 	  will be called xilinx_i2c.
 
 config I2C_EG20T
-	tristate "Intel EG20T PCH/OKI SEMICONDUCTOR ML7213 IOH"
+	tristate "Intel EG20T PCH / OKI SEMICONDUCTOR IOH(ML7213/ML7223)"
 	depends on PCI
 	help
 	  This driver is for PCH(Platform controller Hub) I2C of EG20T which
 	  is an IOH(Input/Output Hub) for x86 embedded processor.
 	  This driver can access PCH I2C bus device.
 
-	  This driver also supports the ML7213, a companion chip for the
-	  Atom E6xx series and compatible with the Intel EG20T PCH.
+	  This driver also can be used for OKI SEMICONDUCTOR IOH(Input/
+	  Output Hub), ML7213 and ML7223.
+	  ML7213 IOH is for IVI(In-Vehicle Infotainment) use and ML7223 IOH is
+	  for MP(Media Phone) use.
+	  ML7213/ML7223 is companion chip for Intel Atom E6xx series.
+	  ML7213/ML7223 is completely compatible for Intel EG20T PCH.
 
 comment "External I2C/SMBus adapter drivers"
 
diff -druN linux-2.6.39-libre/drivers/i2c/muxes/pca954x.c linux-3.0-rc7-libre/drivers/i2c/muxes/pca954x.c
--- linux-2.6.39-libre/drivers/i2c/muxes/pca954x.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/i2c/muxes/pca954x.c	2011-07-11 19:51:52.000000000 -0400
@@ -201,10 +201,11 @@
 
 	i2c_set_clientdata(client, data);
 
-	/* Read the mux register at addr to verify
-	 * that the mux is in fact present.
+	/* Write the mux register at addr to verify
+	 * that the mux is in fact present. This also
+	 * initializes the mux to disconnected state.
 	 */
-	if (i2c_smbus_read_byte(client) < 0) {
+	if (i2c_smbus_write_byte(client, 0) < 0) {
 		dev_warn(&client->dev, "probe failed\n");
 		goto exit_free;
 	}
diff -druN linux-2.6.39-libre/drivers/ide/ide-acpi.c linux-3.0-rc7-libre/drivers/ide/ide-acpi.c
--- linux-2.6.39-libre/drivers/ide/ide-acpi.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/ide/ide-acpi.c	2011-07-11 19:51:52.000000000 -0400
@@ -416,21 +416,21 @@
 
 	out_obj = output.pointer;
 	if (out_obj->type != ACPI_TYPE_BUFFER) {
-		kfree(output.pointer);
 		DEBPRINT("Run _GTM: error: "
 		       "expected object type of ACPI_TYPE_BUFFER, "
 		       "got 0x%x\n", out_obj->type);
+		kfree(output.pointer);
 		return;
 	}
 
 	if (!out_obj->buffer.length || !out_obj->buffer.pointer ||
 	    out_obj->buffer.length != sizeof(struct GTM_buffer)) {
-		kfree(output.pointer);
 		printk(KERN_ERR
 			"%s: unexpected _GTM length (0x%x)[should be 0x%zx] or "
 			"addr (0x%p)\n",
 			__func__, out_obj->buffer.length,
 			sizeof(struct GTM_buffer), out_obj->buffer.pointer);
+		kfree(output.pointer);
 		return;
 	}
 
diff -druN linux-2.6.39-libre/drivers/ide/ide-cd.c linux-3.0-rc7-libre/drivers/ide/ide-cd.c
--- linux-2.6.39-libre/drivers/ide/ide-cd.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/ide/ide-cd.c	2011-07-11 19:51:52.000000000 -0400
@@ -778,7 +778,8 @@
 					sector_t block)
 {
 	struct ide_cmd cmd;
-	int uptodate = 0, nsectors;
+	int uptodate = 0;
+	unsigned int nsectors;
 
 	ide_debug_log(IDE_DBG_RQ, "cmd: 0x%x, block: %llu",
 				  rq->cmd[0], (unsigned long long)block);
@@ -1781,7 +1782,7 @@
 
 	ide_cd_read_toc(drive, &sense);
 	g->fops = &idecd_ops;
-	g->flags |= GENHD_FL_REMOVABLE;
+	g->flags |= GENHD_FL_REMOVABLE | GENHD_FL_BLOCK_EVENTS_ON_EXCL_WRITE;
 	add_disk(g);
 	return 0;
 
diff -druN linux-2.6.39-libre/drivers/ide/ide-cs.c linux-3.0-rc7-libre/drivers/ide/ide-cs.c
--- linux-2.6.39-libre/drivers/ide/ide-cs.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/ide/ide-cs.c	2011-07-11 19:51:52.000000000 -0400
@@ -272,7 +272,7 @@
 } /* ide_release */
 
 
-static struct pcmcia_device_id ide_ids[] = {
+static const struct pcmcia_device_id ide_ids[] = {
 	PCMCIA_DEVICE_FUNC_ID(4),
 	PCMCIA_DEVICE_MANF_CARD(0x0000, 0x0000),	/* Corsair */
 	PCMCIA_DEVICE_MANF_CARD(0x0007, 0x0000),	/* Hitachi */
diff -druN linux-2.6.39-libre/drivers/ide/ide-floppy.c linux-3.0-rc7-libre/drivers/ide/ide-floppy.c
--- linux-2.6.39-libre/drivers/ide/ide-floppy.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/ide/ide-floppy.c	2011-07-11 19:51:52.000000000 -0400
@@ -73,7 +73,7 @@
 		drive->failed_pc = NULL;
 
 	if (pc->c[0] == GPCMD_READ_10 || pc->c[0] == GPCMD_WRITE_10 ||
-	    (rq && rq->cmd_type == REQ_TYPE_BLOCK_PC))
+	    rq->cmd_type == REQ_TYPE_BLOCK_PC)
 		uptodate = 1; /* FIXME */
 	else if (pc->c[0] == GPCMD_REQUEST_SENSE) {
 
diff -druN linux-2.6.39-libre/drivers/ide/ide-scan-pci.c linux-3.0-rc7-libre/drivers/ide/ide-scan-pci.c
--- linux-2.6.39-libre/drivers/ide/ide-scan-pci.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/ide/ide-scan-pci.c	2011-07-11 19:51:52.000000000 -0400
@@ -88,7 +88,7 @@
 	struct list_head *l, *n;
 
 	pre_init = 0;
-	while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)))
+	for_each_pci_dev(dev)
 		ide_scan_pcidev(dev);
 
 	/*
diff -druN linux-2.6.39-libre/drivers/ide/pmac.c linux-3.0-rc7-libre/drivers/ide/pmac.c
--- linux-2.6.39-libre/drivers/ide/pmac.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/ide/pmac.c	2011-07-11 19:51:52.000000000 -0400
@@ -1334,7 +1334,7 @@
 static int
 pmac_ide_pci_suspend(struct pci_dev *pdev, pm_message_t mesg)
 {
-	pmac_ide_hwif_t *pmif = (pmac_ide_hwif_t *)pci_get_drvdata(pdev);
+	pmac_ide_hwif_t *pmif = pci_get_drvdata(pdev);
 	int rc = 0;
 
 	if (mesg.event != pdev->dev.power.power_state.event
@@ -1350,7 +1350,7 @@
 static int
 pmac_ide_pci_resume(struct pci_dev *pdev)
 {
-	pmac_ide_hwif_t *pmif = (pmac_ide_hwif_t *)pci_get_drvdata(pdev);
+	pmac_ide_hwif_t *pmif = pci_get_drvdata(pdev);
 	int rc = 0;
 
 	if (pdev->dev.power.power_state.event != PM_EVENT_ON) {
diff -druN linux-2.6.39-libre/drivers/ieee802154/fakehard.c linux-3.0-rc7-libre/drivers/ieee802154/fakehard.c
--- linux-2.6.39-libre/drivers/ieee802154/fakehard.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/ieee802154/fakehard.c	2011-07-11 19:51:52.000000000 -0400
@@ -393,16 +393,6 @@
 	priv = netdev_priv(dev);
 	priv->phy = phy;
 
-	/*
-	 * If the name is a format string the caller wants us to do a
-	 * name allocation.
-	 */
-	if (strchr(dev->name, '%')) {
-		err = dev_alloc_name(dev, dev->name);
-		if (err < 0)
-			goto out;
-	}
-
 	wpan_phy_set_dev(phy, &pdev->dev);
 	SET_NETDEV_DEV(dev, &phy->dev);
 
diff -druN linux-2.6.39-libre/drivers/infiniband/core/addr.c linux-3.0-rc7-libre/drivers/infiniband/core/addr.c
--- linux-2.6.39-libre/drivers/infiniband/core/addr.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/infiniband/core/addr.c	2011-07-11 19:51:52.000000000 -0400
@@ -185,15 +185,20 @@
 	__be32 dst_ip = dst_in->sin_addr.s_addr;
 	struct rtable *rt;
 	struct neighbour *neigh;
+	struct flowi4 fl4;
 	int ret;
 
-	rt = ip_route_output(&init_net, dst_ip, src_ip, 0, addr->bound_dev_if);
+	memset(&fl4, 0, sizeof(fl4));
+	fl4.daddr = dst_ip;
+	fl4.saddr = src_ip;
+	fl4.flowi4_oif = addr->bound_dev_if;
+	rt = ip_route_output_key(&init_net, &fl4);
 	if (IS_ERR(rt)) {
 		ret = PTR_ERR(rt);
 		goto out;
 	}
 	src_in->sin_family = AF_INET;
-	src_in->sin_addr.s_addr = rt->rt_src;
+	src_in->sin_addr.s_addr = fl4.saddr;
 
 	if (rt->dst.dev->flags & IFF_LOOPBACK) {
 		ret = rdma_translate_ip((struct sockaddr *) dst_in, addr);
diff -druN linux-2.6.39-libre/drivers/infiniband/core/cma.c linux-3.0-rc7-libre/drivers/infiniband/core/cma.c
--- linux-2.6.39-libre/drivers/infiniband/core/cma.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/infiniband/core/cma.c	2011-07-11 19:51:52.000000000 -0400
@@ -47,6 +47,7 @@
 
 #include <rdma/rdma_cm.h>
 #include <rdma/rdma_cm_ib.h>
+#include <rdma/rdma_netlink.h>
 #include <rdma/ib_cache.h>
 #include <rdma/ib_cm.h>
 #include <rdma/ib_sa.h>
@@ -89,20 +90,6 @@
 	struct list_head	id_list;
 };
 
-enum cma_state {
-	CMA_IDLE,
-	CMA_ADDR_QUERY,
-	CMA_ADDR_RESOLVED,
-	CMA_ROUTE_QUERY,
-	CMA_ROUTE_RESOLVED,
-	CMA_CONNECT,
-	CMA_DISCONNECT,
-	CMA_ADDR_BOUND,
-	CMA_LISTEN,
-	CMA_DEVICE_REMOVAL,
-	CMA_DESTROYING
-};
-
 struct rdma_bind_list {
 	struct idr		*ps;
 	struct hlist_head	owners;
@@ -126,7 +113,7 @@
 	struct list_head	mc_list;
 
 	int			internal_id;
-	enum cma_state		state;
+	enum rdma_cm_state	state;
 	spinlock_t		lock;
 	struct mutex		qp_mutex;
 
@@ -146,8 +133,10 @@
 	u32			seq_num;
 	u32			qkey;
 	u32			qp_num;
+	pid_t			owner;
 	u8			srq;
 	u8			tos;
+	u8			reuseaddr;
 };
 
 struct cma_multicast {
@@ -164,8 +153,8 @@
 struct cma_work {
 	struct work_struct	work;
 	struct rdma_id_private	*id;
-	enum cma_state		old_state;
-	enum cma_state		new_state;
+	enum rdma_cm_state	old_state;
+	enum rdma_cm_state	new_state;
 	struct rdma_cm_event	event;
 };
 
@@ -216,7 +205,7 @@
 #define CMA_VERSION 0x00
 #define SDP_MAJ_VERSION 0x2
 
-static int cma_comp(struct rdma_id_private *id_priv, enum cma_state comp)
+static int cma_comp(struct rdma_id_private *id_priv, enum rdma_cm_state comp)
 {
 	unsigned long flags;
 	int ret;
@@ -228,7 +217,7 @@
 }
 
 static int cma_comp_exch(struct rdma_id_private *id_priv,
-			 enum cma_state comp, enum cma_state exch)
+			 enum rdma_cm_state comp, enum rdma_cm_state exch)
 {
 	unsigned long flags;
 	int ret;
@@ -240,11 +229,11 @@
 	return ret;
 }
 
-static enum cma_state cma_exch(struct rdma_id_private *id_priv,
-			       enum cma_state exch)
+static enum rdma_cm_state cma_exch(struct rdma_id_private *id_priv,
+				   enum rdma_cm_state exch)
 {
 	unsigned long flags;
-	enum cma_state old;
+	enum rdma_cm_state old;
 
 	spin_lock_irqsave(&id_priv->lock, flags);
 	old = id_priv->state;
@@ -278,11 +267,6 @@
 	hh->ip_version = (ip_ver << 4) | (hh->ip_version & 0xF);
 }
 
-static inline int cma_is_ud_ps(enum rdma_port_space ps)
-{
-	return (ps == RDMA_PS_UDP || ps == RDMA_PS_IPOIB);
-}
-
 static void cma_attach_to_dev(struct rdma_id_private *id_priv,
 			      struct cma_device *cma_dev)
 {
@@ -412,7 +396,7 @@
 }
 
 static int cma_disable_callback(struct rdma_id_private *id_priv,
-			      enum cma_state state)
+				enum rdma_cm_state state)
 {
 	mutex_lock(&id_priv->handler_mutex);
 	if (id_priv->state != state) {
@@ -428,7 +412,8 @@
 }
 
 struct rdma_cm_id *rdma_create_id(rdma_cm_event_handler event_handler,
-				  void *context, enum rdma_port_space ps)
+				  void *context, enum rdma_port_space ps,
+				  enum ib_qp_type qp_type)
 {
 	struct rdma_id_private *id_priv;
 
@@ -436,10 +421,12 @@
 	if (!id_priv)
 		return ERR_PTR(-ENOMEM);
 
-	id_priv->state = CMA_IDLE;
+	id_priv->owner = task_pid_nr(current);
+	id_priv->state = RDMA_CM_IDLE;
 	id_priv->id.context = context;
 	id_priv->id.event_handler = event_handler;
 	id_priv->id.ps = ps;
+	id_priv->id.qp_type = qp_type;
 	spin_lock_init(&id_priv->lock);
 	mutex_init(&id_priv->qp_mutex);
 	init_completion(&id_priv->comp);
@@ -507,7 +494,7 @@
 	if (IS_ERR(qp))
 		return PTR_ERR(qp);
 
-	if (cma_is_ud_ps(id_priv->id.ps))
+	if (id->qp_type == IB_QPT_UD)
 		ret = cma_init_ud_qp(id_priv, qp);
 	else
 		ret = cma_init_conn_qp(id_priv, qp);
@@ -635,7 +622,7 @@
 	qp_attr->port_num = id_priv->id.port_num;
 	*qp_attr_mask = IB_QP_STATE | IB_QP_PKEY_INDEX | IB_QP_PORT;
 
-	if (cma_is_ud_ps(id_priv->id.ps)) {
+	if (id_priv->id.qp_type == IB_QPT_UD) {
 		ret = cma_set_qkey(id_priv);
 		if (ret)
 			return ret;
@@ -658,7 +645,7 @@
 	id_priv = container_of(id, struct rdma_id_private, id);
 	switch (rdma_node_get_transport(id_priv->id.device->node_type)) {
 	case RDMA_TRANSPORT_IB:
-		if (!id_priv->cm_id.ib || cma_is_ud_ps(id_priv->id.ps))
+		if (!id_priv->cm_id.ib || (id_priv->id.qp_type == IB_QPT_UD))
 			ret = cma_ib_init_qp_attr(id_priv, qp_attr, qp_attr_mask);
 		else
 			ret = ib_cm_init_qp_attr(id_priv->cm_id.ib, qp_attr,
@@ -712,6 +699,21 @@
 	return cma_zero_addr(addr) || cma_loopback_addr(addr);
 }
 
+static int cma_addr_cmp(struct sockaddr *src, struct sockaddr *dst)
+{
+	if (src->sa_family != dst->sa_family)
+		return -1;
+
+	switch (src->sa_family) {
+	case AF_INET:
+		return ((struct sockaddr_in *) src)->sin_addr.s_addr !=
+		       ((struct sockaddr_in *) dst)->sin_addr.s_addr;
+	default:
+		return ipv6_addr_cmp(&((struct sockaddr_in6 *) src)->sin6_addr,
+				     &((struct sockaddr_in6 *) dst)->sin6_addr);
+	}
+}
+
 static inline __be16 cma_port(struct sockaddr *addr)
 {
 	if (addr->sa_family == AF_INET)
@@ -842,16 +844,16 @@
 }
 
 static void cma_cancel_operation(struct rdma_id_private *id_priv,
-				 enum cma_state state)
+				 enum rdma_cm_state state)
 {
 	switch (state) {
-	case CMA_ADDR_QUERY:
+	case RDMA_CM_ADDR_QUERY:
 		rdma_addr_cancel(&id_priv->id.route.addr.dev_addr);
 		break;
-	case CMA_ROUTE_QUERY:
+	case RDMA_CM_ROUTE_QUERY:
 		cma_cancel_route(id_priv);
 		break;
-	case CMA_LISTEN:
+	case RDMA_CM_LISTEN:
 		if (cma_any_addr((struct sockaddr *) &id_priv->id.route.addr.src_addr)
 				&& !id_priv->cma_dev)
 			cma_cancel_listens(id_priv);
@@ -902,10 +904,10 @@
 void rdma_destroy_id(struct rdma_cm_id *id)
 {
 	struct rdma_id_private *id_priv;
-	enum cma_state state;
+	enum rdma_cm_state state;
 
 	id_priv = container_of(id, struct rdma_id_private, id);
-	state = cma_exch(id_priv, CMA_DESTROYING);
+	state = cma_exch(id_priv, RDMA_CM_DESTROYING);
 	cma_cancel_operation(id_priv, state);
 
 	/*
@@ -999,9 +1001,9 @@
 	int ret = 0;
 
 	if ((ib_event->event != IB_CM_TIMEWAIT_EXIT &&
-		cma_disable_callback(id_priv, CMA_CONNECT)) ||
+		cma_disable_callback(id_priv, RDMA_CM_CONNECT)) ||
 	    (ib_event->event == IB_CM_TIMEWAIT_EXIT &&
-		cma_disable_callback(id_priv, CMA_DISCONNECT)))
+		cma_disable_callback(id_priv, RDMA_CM_DISCONNECT)))
 		return 0;
 
 	memset(&event, 0, sizeof event);
@@ -1032,7 +1034,8 @@
 		event.status = -ETIMEDOUT; /* fall through */
 	case IB_CM_DREQ_RECEIVED:
 	case IB_CM_DREP_RECEIVED:
-		if (!cma_comp_exch(id_priv, CMA_CONNECT, CMA_DISCONNECT))
+		if (!cma_comp_exch(id_priv, RDMA_CM_CONNECT,
+				   RDMA_CM_DISCONNECT))
 			goto out;
 		event.event = RDMA_CM_EVENT_DISCONNECTED;
 		break;
@@ -1059,7 +1062,7 @@
 	if (ret) {
 		/* Destroy the CM ID by returning a non-zero value. */
 		id_priv->cm_id.ib = NULL;
-		cma_exch(id_priv, CMA_DESTROYING);
+		cma_exch(id_priv, RDMA_CM_DESTROYING);
 		mutex_unlock(&id_priv->handler_mutex);
 		rdma_destroy_id(&id_priv->id);
 		return ret;
@@ -1085,7 +1088,7 @@
 		goto err;
 
 	id = rdma_create_id(listen_id->event_handler, listen_id->context,
-			    listen_id->ps);
+			    listen_id->ps, ib_event->param.req_rcvd.qp_type);
 	if (IS_ERR(id))
 		goto err;
 
@@ -1116,7 +1119,7 @@
 	rdma_addr_set_dgid(&rt->addr.dev_addr, &rt->path_rec[0].dgid);
 
 	id_priv = container_of(id, struct rdma_id_private, id);
-	id_priv->state = CMA_CONNECT;
+	id_priv->state = RDMA_CM_CONNECT;
 	return id_priv;
 
 destroy_id:
@@ -1136,7 +1139,7 @@
 	int ret;
 
 	id = rdma_create_id(listen_id->event_handler, listen_id->context,
-			    listen_id->ps);
+			    listen_id->ps, IB_QPT_UD);
 	if (IS_ERR(id))
 		return NULL;
 
@@ -1156,7 +1159,7 @@
 	}
 
 	id_priv = container_of(id, struct rdma_id_private, id);
-	id_priv->state = CMA_CONNECT;
+	id_priv->state = RDMA_CM_CONNECT;
 	return id_priv;
 err:
 	rdma_destroy_id(id);
@@ -1185,13 +1188,13 @@
 	int offset, ret;
 
 	listen_id = cm_id->context;
-	if (cma_disable_callback(listen_id, CMA_LISTEN))
+	if (cma_disable_callback(listen_id, RDMA_CM_LISTEN))
 		return -ECONNABORTED;
 
 	memset(&event, 0, sizeof event);
 	offset = cma_user_data_offset(listen_id->id.ps);
 	event.event = RDMA_CM_EVENT_CONNECT_REQUEST;
-	if (cma_is_ud_ps(listen_id->id.ps)) {
+	if (listen_id->id.qp_type == IB_QPT_UD) {
 		conn_id = cma_new_udp_id(&listen_id->id, ib_event);
 		event.param.ud.private_data = ib_event->private_data + offset;
 		event.param.ud.private_data_len =
@@ -1227,8 +1230,7 @@
 		 * while we're accessing the cm_id.
 		 */
 		mutex_lock(&lock);
-		if (cma_comp(conn_id, CMA_CONNECT) &&
-		    !cma_is_ud_ps(conn_id->id.ps))
+		if (cma_comp(conn_id, RDMA_CM_CONNECT) && (conn_id->id.qp_type != IB_QPT_UD))
 			ib_send_cm_mra(cm_id, CMA_CM_MRA_SETTING, NULL, 0);
 		mutex_unlock(&lock);
 		mutex_unlock(&conn_id->handler_mutex);
@@ -1241,7 +1243,7 @@
 	conn_id->cm_id.ib = NULL;
 
 release_conn_id:
-	cma_exch(conn_id, CMA_DESTROYING);
+	cma_exch(conn_id, RDMA_CM_DESTROYING);
 	mutex_unlock(&conn_id->handler_mutex);
 	rdma_destroy_id(&conn_id->id);
 
@@ -1312,7 +1314,7 @@
 	struct sockaddr_in *sin;
 	int ret = 0;
 
-	if (cma_disable_callback(id_priv, CMA_CONNECT))
+	if (cma_disable_callback(id_priv, RDMA_CM_CONNECT))
 		return 0;
 
 	memset(&event, 0, sizeof event);
@@ -1355,7 +1357,7 @@
 	if (ret) {
 		/* Destroy the CM ID by returning a non-zero value. */
 		id_priv->cm_id.iw = NULL;
-		cma_exch(id_priv, CMA_DESTROYING);
+		cma_exch(id_priv, RDMA_CM_DESTROYING);
 		mutex_unlock(&id_priv->handler_mutex);
 		rdma_destroy_id(&id_priv->id);
 		return ret;
@@ -1377,20 +1379,20 @@
 	struct ib_device_attr attr;
 
 	listen_id = cm_id->context;
-	if (cma_disable_callback(listen_id, CMA_LISTEN))
+	if (cma_disable_callback(listen_id, RDMA_CM_LISTEN))
 		return -ECONNABORTED;
 
 	/* Create a new RDMA id for the new IW CM ID */
 	new_cm_id = rdma_create_id(listen_id->id.event_handler,
 				   listen_id->id.context,
-				   RDMA_PS_TCP);
+				   RDMA_PS_TCP, IB_QPT_RC);
 	if (IS_ERR(new_cm_id)) {
 		ret = -ENOMEM;
 		goto out;
 	}
 	conn_id = container_of(new_cm_id, struct rdma_id_private, id);
 	mutex_lock_nested(&conn_id->handler_mutex, SINGLE_DEPTH_NESTING);
-	conn_id->state = CMA_CONNECT;
+	conn_id->state = RDMA_CM_CONNECT;
 
 	dev = ip_dev_find(&init_net, iw_event->local_addr.sin_addr.s_addr);
 	if (!dev) {
@@ -1445,7 +1447,7 @@
 	if (ret) {
 		/* User wants to destroy the CM ID */
 		conn_id->cm_id.iw = NULL;
-		cma_exch(conn_id, CMA_DESTROYING);
+		cma_exch(conn_id, RDMA_CM_DESTROYING);
 		mutex_unlock(&conn_id->handler_mutex);
 		cma_deref_id(conn_id);
 		rdma_destroy_id(&conn_id->id);
@@ -1532,13 +1534,14 @@
 	struct rdma_cm_id *id;
 	int ret;
 
-	id = rdma_create_id(cma_listen_handler, id_priv, id_priv->id.ps);
+	id = rdma_create_id(cma_listen_handler, id_priv, id_priv->id.ps,
+			    id_priv->id.qp_type);
 	if (IS_ERR(id))
 		return;
 
 	dev_id_priv = container_of(id, struct rdma_id_private, id);
 
-	dev_id_priv->state = CMA_ADDR_BOUND;
+	dev_id_priv->state = RDMA_CM_ADDR_BOUND;
 	memcpy(&id->route.addr.src_addr, &id_priv->id.route.addr.src_addr,
 	       ip_addr_size((struct sockaddr *) &id_priv->id.route.addr.src_addr));
 
@@ -1564,50 +1567,6 @@
 	mutex_unlock(&lock);
 }
 
-int rdma_listen(struct rdma_cm_id *id, int backlog)
-{
-	struct rdma_id_private *id_priv;
-	int ret;
-
-	id_priv = container_of(id, struct rdma_id_private, id);
-	if (id_priv->state == CMA_IDLE) {
-		((struct sockaddr *) &id->route.addr.src_addr)->sa_family = AF_INET;
-		ret = rdma_bind_addr(id, (struct sockaddr *) &id->route.addr.src_addr);
-		if (ret)
-			return ret;
-	}
-
-	if (!cma_comp_exch(id_priv, CMA_ADDR_BOUND, CMA_LISTEN))
-		return -EINVAL;
-
-	id_priv->backlog = backlog;
-	if (id->device) {
-		switch (rdma_node_get_transport(id->device->node_type)) {
-		case RDMA_TRANSPORT_IB:
-			ret = cma_ib_listen(id_priv);
-			if (ret)
-				goto err;
-			break;
-		case RDMA_TRANSPORT_IWARP:
-			ret = cma_iw_listen(id_priv, backlog);
-			if (ret)
-				goto err;
-			break;
-		default:
-			ret = -ENOSYS;
-			goto err;
-		}
-	} else
-		cma_listen_on_all(id_priv);
-
-	return 0;
-err:
-	id_priv->backlog = 0;
-	cma_comp_exch(id_priv, CMA_LISTEN, CMA_ADDR_BOUND);
-	return ret;
-}
-EXPORT_SYMBOL(rdma_listen);
-
 void rdma_set_service_type(struct rdma_cm_id *id, int tos)
 {
 	struct rdma_id_private *id_priv;
@@ -1629,8 +1588,8 @@
 		route->num_paths = 1;
 		*route->path_rec = *path_rec;
 	} else {
-		work->old_state = CMA_ROUTE_QUERY;
-		work->new_state = CMA_ADDR_RESOLVED;
+		work->old_state = RDMA_CM_ROUTE_QUERY;
+		work->new_state = RDMA_CM_ADDR_RESOLVED;
 		work->event.event = RDMA_CM_EVENT_ROUTE_ERROR;
 		work->event.status = status;
 	}
@@ -1688,7 +1647,7 @@
 		goto out;
 
 	if (id_priv->id.event_handler(&id_priv->id, &work->event)) {
-		cma_exch(id_priv, CMA_DESTROYING);
+		cma_exch(id_priv, RDMA_CM_DESTROYING);
 		destroy = 1;
 	}
 out:
@@ -1706,12 +1665,12 @@
 	int destroy = 0;
 
 	mutex_lock(&id_priv->handler_mutex);
-	if (id_priv->state == CMA_DESTROYING ||
-	    id_priv->state == CMA_DEVICE_REMOVAL)
+	if (id_priv->state == RDMA_CM_DESTROYING ||
+	    id_priv->state == RDMA_CM_DEVICE_REMOVAL)
 		goto out;
 
 	if (id_priv->id.event_handler(&id_priv->id, &work->event)) {
-		cma_exch(id_priv, CMA_DESTROYING);
+		cma_exch(id_priv, RDMA_CM_DESTROYING);
 		destroy = 1;
 	}
 
@@ -1735,8 +1694,8 @@
 
 	work->id = id_priv;
 	INIT_WORK(&work->work, cma_work_handler);
-	work->old_state = CMA_ROUTE_QUERY;
-	work->new_state = CMA_ROUTE_RESOLVED;
+	work->old_state = RDMA_CM_ROUTE_QUERY;
+	work->new_state = RDMA_CM_ROUTE_RESOLVED;
 	work->event.event = RDMA_CM_EVENT_ROUTE_RESOLVED;
 
 	route->path_rec = kmalloc(sizeof *route->path_rec, GFP_KERNEL);
@@ -1765,7 +1724,8 @@
 	int ret;
 
 	id_priv = container_of(id, struct rdma_id_private, id);
-	if (!cma_comp_exch(id_priv, CMA_ADDR_RESOLVED, CMA_ROUTE_RESOLVED))
+	if (!cma_comp_exch(id_priv, RDMA_CM_ADDR_RESOLVED,
+			   RDMA_CM_ROUTE_RESOLVED))
 		return -EINVAL;
 
 	id->route.path_rec = kmemdup(path_rec, sizeof *path_rec * num_paths,
@@ -1778,7 +1738,7 @@
 	id->route.num_paths = num_paths;
 	return 0;
 err:
-	cma_comp_exch(id_priv, CMA_ROUTE_RESOLVED, CMA_ADDR_RESOLVED);
+	cma_comp_exch(id_priv, RDMA_CM_ROUTE_RESOLVED, RDMA_CM_ADDR_RESOLVED);
 	return ret;
 }
 EXPORT_SYMBOL(rdma_set_ib_paths);
@@ -1793,8 +1753,8 @@
 
 	work->id = id_priv;
 	INIT_WORK(&work->work, cma_work_handler);
-	work->old_state = CMA_ROUTE_QUERY;
-	work->new_state = CMA_ROUTE_RESOLVED;
+	work->old_state = RDMA_CM_ROUTE_QUERY;
+	work->new_state = RDMA_CM_ROUTE_RESOLVED;
 	work->event.event = RDMA_CM_EVENT_ROUTE_RESOLVED;
 	queue_work(cma_wq, &work->work);
 	return 0;
@@ -1858,8 +1818,8 @@
 		goto err2;
 	}
 
-	work->old_state = CMA_ROUTE_QUERY;
-	work->new_state = CMA_ROUTE_RESOLVED;
+	work->old_state = RDMA_CM_ROUTE_QUERY;
+	work->new_state = RDMA_CM_ROUTE_RESOLVED;
 	work->event.event = RDMA_CM_EVENT_ROUTE_RESOLVED;
 	work->event.status = 0;
 
@@ -1881,7 +1841,7 @@
 	int ret;
 
 	id_priv = container_of(id, struct rdma_id_private, id);
-	if (!cma_comp_exch(id_priv, CMA_ADDR_RESOLVED, CMA_ROUTE_QUERY))
+	if (!cma_comp_exch(id_priv, RDMA_CM_ADDR_RESOLVED, RDMA_CM_ROUTE_QUERY))
 		return -EINVAL;
 
 	atomic_inc(&id_priv->refcount);
@@ -1910,7 +1870,7 @@
 
 	return 0;
 err:
-	cma_comp_exch(id_priv, CMA_ROUTE_QUERY, CMA_ADDR_RESOLVED);
+	cma_comp_exch(id_priv, RDMA_CM_ROUTE_QUERY, RDMA_CM_ADDR_RESOLVED);
 	cma_deref_id(id_priv);
 	return ret;
 }
@@ -1969,14 +1929,16 @@
 
 	memset(&event, 0, sizeof event);
 	mutex_lock(&id_priv->handler_mutex);
-	if (!cma_comp_exch(id_priv, CMA_ADDR_QUERY, CMA_ADDR_RESOLVED))
+	if (!cma_comp_exch(id_priv, RDMA_CM_ADDR_QUERY,
+			   RDMA_CM_ADDR_RESOLVED))
 		goto out;
 
 	if (!status && !id_priv->cma_dev)
 		status = cma_acquire_dev(id_priv);
 
 	if (status) {
-		if (!cma_comp_exch(id_priv, CMA_ADDR_RESOLVED, CMA_ADDR_BOUND))
+		if (!cma_comp_exch(id_priv, RDMA_CM_ADDR_RESOLVED,
+				   RDMA_CM_ADDR_BOUND))
 			goto out;
 		event.event = RDMA_CM_EVENT_ADDR_ERROR;
 		event.status = status;
@@ -1987,7 +1949,7 @@
 	}
 
 	if (id_priv->id.event_handler(&id_priv->id, &event)) {
-		cma_exch(id_priv, CMA_DESTROYING);
+		cma_exch(id_priv, RDMA_CM_DESTROYING);
 		mutex_unlock(&id_priv->handler_mutex);
 		cma_deref_id(id_priv);
 		rdma_destroy_id(&id_priv->id);
@@ -2032,8 +1994,8 @@
 
 	work->id = id_priv;
 	INIT_WORK(&work->work, cma_work_handler);
-	work->old_state = CMA_ADDR_QUERY;
-	work->new_state = CMA_ADDR_RESOLVED;
+	work->old_state = RDMA_CM_ADDR_QUERY;
+	work->new_state = RDMA_CM_ADDR_RESOLVED;
 	work->event.event = RDMA_CM_EVENT_ADDR_RESOLVED;
 	queue_work(cma_wq, &work->work);
 	return 0;
@@ -2062,13 +2024,13 @@
 	int ret;
 
 	id_priv = container_of(id, struct rdma_id_private, id);
-	if (id_priv->state == CMA_IDLE) {
+	if (id_priv->state == RDMA_CM_IDLE) {
 		ret = cma_bind_addr(id, src_addr, dst_addr);
 		if (ret)
 			return ret;
 	}
 
-	if (!cma_comp_exch(id_priv, CMA_ADDR_BOUND, CMA_ADDR_QUERY))
+	if (!cma_comp_exch(id_priv, RDMA_CM_ADDR_BOUND, RDMA_CM_ADDR_QUERY))
 		return -EINVAL;
 
 	atomic_inc(&id_priv->refcount);
@@ -2084,12 +2046,31 @@
 
 	return 0;
 err:
-	cma_comp_exch(id_priv, CMA_ADDR_QUERY, CMA_ADDR_BOUND);
+	cma_comp_exch(id_priv, RDMA_CM_ADDR_QUERY, RDMA_CM_ADDR_BOUND);
 	cma_deref_id(id_priv);
 	return ret;
 }
 EXPORT_SYMBOL(rdma_resolve_addr);
 
+int rdma_set_reuseaddr(struct rdma_cm_id *id, int reuse)
+{
+	struct rdma_id_private *id_priv;
+	unsigned long flags;
+	int ret;
+
+	id_priv = container_of(id, struct rdma_id_private, id);
+	spin_lock_irqsave(&id_priv->lock, flags);
+	if (id_priv->state == RDMA_CM_IDLE) {
+		id_priv->reuseaddr = reuse;
+		ret = 0;
+	} else {
+		ret = -EINVAL;
+	}
+	spin_unlock_irqrestore(&id_priv->lock, flags);
+	return ret;
+}
+EXPORT_SYMBOL(rdma_set_reuseaddr);
+
 static void cma_bind_port(struct rdma_bind_list *bind_list,
 			  struct rdma_id_private *id_priv)
 {
@@ -2165,41 +2146,71 @@
 	return -EADDRNOTAVAIL;
 }
 
-static int cma_use_port(struct idr *ps, struct rdma_id_private *id_priv)
+/*
+ * Check that the requested port is available.  This is called when trying to
+ * bind to a specific port, or when trying to listen on a bound port.  In
+ * the latter case, the provided id_priv may already be on the bind_list, but
+ * we still need to check that it's okay to start listening.
+ */
+static int cma_check_port(struct rdma_bind_list *bind_list,
+			  struct rdma_id_private *id_priv, uint8_t reuseaddr)
 {
 	struct rdma_id_private *cur_id;
-	struct sockaddr_in *sin, *cur_sin;
-	struct rdma_bind_list *bind_list;
+	struct sockaddr *addr, *cur_addr;
 	struct hlist_node *node;
+
+	addr = (struct sockaddr *) &id_priv->id.route.addr.src_addr;
+	if (cma_any_addr(addr) && !reuseaddr)
+		return -EADDRNOTAVAIL;
+
+	hlist_for_each_entry(cur_id, node, &bind_list->owners, node) {
+		if (id_priv == cur_id)
+			continue;
+
+		if ((cur_id->state == RDMA_CM_LISTEN) ||
+		    !reuseaddr || !cur_id->reuseaddr) {
+			cur_addr = (struct sockaddr *) &cur_id->id.route.addr.src_addr;
+			if (cma_any_addr(cur_addr))
+				return -EADDRNOTAVAIL;
+
+			if (!cma_addr_cmp(addr, cur_addr))
+				return -EADDRINUSE;
+		}
+	}
+	return 0;
+}
+
+static int cma_use_port(struct idr *ps, struct rdma_id_private *id_priv)
+{
+	struct rdma_bind_list *bind_list;
 	unsigned short snum;
+	int ret;
 
-	sin = (struct sockaddr_in *) &id_priv->id.route.addr.src_addr;
-	snum = ntohs(sin->sin_port);
+	snum = ntohs(cma_port((struct sockaddr *) &id_priv->id.route.addr.src_addr));
 	if (snum < PROT_SOCK && !capable(CAP_NET_BIND_SERVICE))
 		return -EACCES;
 
 	bind_list = idr_find(ps, snum);
-	if (!bind_list)
-		return cma_alloc_port(ps, id_priv, snum);
-
-	/*
-	 * We don't support binding to any address if anyone is bound to
-	 * a specific address on the same port.
-	 */
-	if (cma_any_addr((struct sockaddr *) &id_priv->id.route.addr.src_addr))
-		return -EADDRNOTAVAIL;
-
-	hlist_for_each_entry(cur_id, node, &bind_list->owners, node) {
-		if (cma_any_addr((struct sockaddr *) &cur_id->id.route.addr.src_addr))
-			return -EADDRNOTAVAIL;
-
-		cur_sin = (struct sockaddr_in *) &cur_id->id.route.addr.src_addr;
-		if (sin->sin_addr.s_addr == cur_sin->sin_addr.s_addr)
-			return -EADDRINUSE;
+	if (!bind_list) {
+		ret = cma_alloc_port(ps, id_priv, snum);
+	} else {
+		ret = cma_check_port(bind_list, id_priv, id_priv->reuseaddr);
+		if (!ret)
+			cma_bind_port(bind_list, id_priv);
 	}
+	return ret;
+}
 
-	cma_bind_port(bind_list, id_priv);
-	return 0;
+static int cma_bind_listen(struct rdma_id_private *id_priv)
+{
+	struct rdma_bind_list *bind_list = id_priv->bind_list;
+	int ret = 0;
+
+	mutex_lock(&lock);
+	if (bind_list->owners.first->next)
+		ret = cma_check_port(bind_list, id_priv, 0);
+	mutex_unlock(&lock);
+	return ret;
 }
 
 static int cma_get_port(struct rdma_id_private *id_priv)
@@ -2253,6 +2264,56 @@
 	return 0;
 }
 
+int rdma_listen(struct rdma_cm_id *id, int backlog)
+{
+	struct rdma_id_private *id_priv;
+	int ret;
+
+	id_priv = container_of(id, struct rdma_id_private, id);
+	if (id_priv->state == RDMA_CM_IDLE) {
+		((struct sockaddr *) &id->route.addr.src_addr)->sa_family = AF_INET;
+		ret = rdma_bind_addr(id, (struct sockaddr *) &id->route.addr.src_addr);
+		if (ret)
+			return ret;
+	}
+
+	if (!cma_comp_exch(id_priv, RDMA_CM_ADDR_BOUND, RDMA_CM_LISTEN))
+		return -EINVAL;
+
+	if (id_priv->reuseaddr) {
+		ret = cma_bind_listen(id_priv);
+		if (ret)
+			goto err;
+	}
+
+	id_priv->backlog = backlog;
+	if (id->device) {
+		switch (rdma_node_get_transport(id->device->node_type)) {
+		case RDMA_TRANSPORT_IB:
+			ret = cma_ib_listen(id_priv);
+			if (ret)
+				goto err;
+			break;
+		case RDMA_TRANSPORT_IWARP:
+			ret = cma_iw_listen(id_priv, backlog);
+			if (ret)
+				goto err;
+			break;
+		default:
+			ret = -ENOSYS;
+			goto err;
+		}
+	} else
+		cma_listen_on_all(id_priv);
+
+	return 0;
+err:
+	id_priv->backlog = 0;
+	cma_comp_exch(id_priv, RDMA_CM_LISTEN, RDMA_CM_ADDR_BOUND);
+	return ret;
+}
+EXPORT_SYMBOL(rdma_listen);
+
 int rdma_bind_addr(struct rdma_cm_id *id, struct sockaddr *addr)
 {
 	struct rdma_id_private *id_priv;
@@ -2262,7 +2323,7 @@
 		return -EAFNOSUPPORT;
 
 	id_priv = container_of(id, struct rdma_id_private, id);
-	if (!cma_comp_exch(id_priv, CMA_IDLE, CMA_ADDR_BOUND))
+	if (!cma_comp_exch(id_priv, RDMA_CM_IDLE, RDMA_CM_ADDR_BOUND))
 		return -EINVAL;
 
 	ret = cma_check_linklocal(&id->route.addr.dev_addr, addr);
@@ -2289,7 +2350,7 @@
 	if (id_priv->cma_dev)
 		cma_release_dev(id_priv);
 err1:
-	cma_comp_exch(id_priv, CMA_ADDR_BOUND, CMA_IDLE);
+	cma_comp_exch(id_priv, RDMA_CM_ADDR_BOUND, RDMA_CM_IDLE);
 	return ret;
 }
 EXPORT_SYMBOL(rdma_bind_addr);
@@ -2362,7 +2423,7 @@
 	struct ib_cm_sidr_rep_event_param *rep = &ib_event->param.sidr_rep_rcvd;
 	int ret = 0;
 
-	if (cma_disable_callback(id_priv, CMA_CONNECT))
+	if (cma_disable_callback(id_priv, RDMA_CM_CONNECT))
 		return 0;
 
 	memset(&event, 0, sizeof event);
@@ -2408,7 +2469,7 @@
 	if (ret) {
 		/* Destroy the CM ID by returning a non-zero value. */
 		id_priv->cm_id.ib = NULL;
-		cma_exch(id_priv, CMA_DESTROYING);
+		cma_exch(id_priv, RDMA_CM_DESTROYING);
 		mutex_unlock(&id_priv->handler_mutex);
 		rdma_destroy_id(&id_priv->id);
 		return ret;
@@ -2574,7 +2635,7 @@
 	int ret;
 
 	id_priv = container_of(id, struct rdma_id_private, id);
-	if (!cma_comp_exch(id_priv, CMA_ROUTE_RESOLVED, CMA_CONNECT))
+	if (!cma_comp_exch(id_priv, RDMA_CM_ROUTE_RESOLVED, RDMA_CM_CONNECT))
 		return -EINVAL;
 
 	if (!id->qp) {
@@ -2584,7 +2645,7 @@
 
 	switch (rdma_node_get_transport(id->device->node_type)) {
 	case RDMA_TRANSPORT_IB:
-		if (cma_is_ud_ps(id->ps))
+		if (id->qp_type == IB_QPT_UD)
 			ret = cma_resolve_ib_udp(id_priv, conn_param);
 		else
 			ret = cma_connect_ib(id_priv, conn_param);
@@ -2601,7 +2662,7 @@
 
 	return 0;
 err:
-	cma_comp_exch(id_priv, CMA_CONNECT, CMA_ROUTE_RESOLVED);
+	cma_comp_exch(id_priv, RDMA_CM_CONNECT, RDMA_CM_ROUTE_RESOLVED);
 	return ret;
 }
 EXPORT_SYMBOL(rdma_connect);
@@ -2687,7 +2748,10 @@
 	int ret;
 
 	id_priv = container_of(id, struct rdma_id_private, id);
-	if (!cma_comp(id_priv, CMA_CONNECT))
+
+	id_priv->owner = task_pid_nr(current);
+
+	if (!cma_comp(id_priv, RDMA_CM_CONNECT))
 		return -EINVAL;
 
 	if (!id->qp && conn_param) {
@@ -2697,7 +2761,7 @@
 
 	switch (rdma_node_get_transport(id->device->node_type)) {
 	case RDMA_TRANSPORT_IB:
-		if (cma_is_ud_ps(id->ps))
+		if (id->qp_type == IB_QPT_UD)
 			ret = cma_send_sidr_rep(id_priv, IB_SIDR_SUCCESS,
 						conn_param->private_data,
 						conn_param->private_data_len);
@@ -2758,7 +2822,7 @@
 
 	switch (rdma_node_get_transport(id->device->node_type)) {
 	case RDMA_TRANSPORT_IB:
-		if (cma_is_ud_ps(id->ps))
+		if (id->qp_type == IB_QPT_UD)
 			ret = cma_send_sidr_rep(id_priv, IB_SIDR_REJECT,
 						private_data, private_data_len);
 		else
@@ -2816,8 +2880,8 @@
 	int ret;
 
 	id_priv = mc->id_priv;
-	if (cma_disable_callback(id_priv, CMA_ADDR_BOUND) &&
-	    cma_disable_callback(id_priv, CMA_ADDR_RESOLVED))
+	if (cma_disable_callback(id_priv, RDMA_CM_ADDR_BOUND) &&
+	    cma_disable_callback(id_priv, RDMA_CM_ADDR_RESOLVED))
 		return 0;
 
 	mutex_lock(&id_priv->qp_mutex);
@@ -2841,7 +2905,7 @@
 
 	ret = id_priv->id.event_handler(&id_priv->id, &event);
 	if (ret) {
-		cma_exch(id_priv, CMA_DESTROYING);
+		cma_exch(id_priv, RDMA_CM_DESTROYING);
 		mutex_unlock(&id_priv->handler_mutex);
 		rdma_destroy_id(&id_priv->id);
 		return 0;
@@ -3024,8 +3088,8 @@
 	int ret;
 
 	id_priv = container_of(id, struct rdma_id_private, id);
-	if (!cma_comp(id_priv, CMA_ADDR_BOUND) &&
-	    !cma_comp(id_priv, CMA_ADDR_RESOLVED))
+	if (!cma_comp(id_priv, RDMA_CM_ADDR_BOUND) &&
+	    !cma_comp(id_priv, RDMA_CM_ADDR_RESOLVED))
 		return -EINVAL;
 
 	mc = kmalloc(sizeof *mc, GFP_KERNEL);
@@ -3190,19 +3254,19 @@
 static int cma_remove_id_dev(struct rdma_id_private *id_priv)
 {
 	struct rdma_cm_event event;
-	enum cma_state state;
+	enum rdma_cm_state state;
 	int ret = 0;
 
 	/* Record that we want to remove the device */
-	state = cma_exch(id_priv, CMA_DEVICE_REMOVAL);
-	if (state == CMA_DESTROYING)
+	state = cma_exch(id_priv, RDMA_CM_DEVICE_REMOVAL);
+	if (state == RDMA_CM_DESTROYING)
 		return 0;
 
 	cma_cancel_operation(id_priv, state);
 	mutex_lock(&id_priv->handler_mutex);
 
 	/* Check for destruction from another callback. */
-	if (!cma_comp(id_priv, CMA_DEVICE_REMOVAL))
+	if (!cma_comp(id_priv, RDMA_CM_DEVICE_REMOVAL))
 		goto out;
 
 	memset(&event, 0, sizeof event);
@@ -3257,6 +3321,100 @@
 	kfree(cma_dev);
 }
 
+static int cma_get_id_stats(struct sk_buff *skb, struct netlink_callback *cb)
+{
+	struct nlmsghdr *nlh;
+	struct rdma_cm_id_stats *id_stats;
+	struct rdma_id_private *id_priv;
+	struct rdma_cm_id *id = NULL;
+	struct cma_device *cma_dev;
+	int i_dev = 0, i_id = 0;
+
+	/*
+	 * We export all of the IDs as a sequence of messages.  Each
+	 * ID gets its own netlink message.
+	 */
+	mutex_lock(&lock);
+
+	list_for_each_entry(cma_dev, &dev_list, list) {
+		if (i_dev < cb->args[0]) {
+			i_dev++;
+			continue;
+		}
+
+		i_id = 0;
+		list_for_each_entry(id_priv, &cma_dev->id_list, list) {
+			if (i_id < cb->args[1]) {
+				i_id++;
+				continue;
+			}
+
+			id_stats = ibnl_put_msg(skb, &nlh, cb->nlh->nlmsg_seq,
+						sizeof *id_stats, RDMA_NL_RDMA_CM,
+						RDMA_NL_RDMA_CM_ID_STATS);
+			if (!id_stats)
+				goto out;
+
+			memset(id_stats, 0, sizeof *id_stats);
+			id = &id_priv->id;
+			id_stats->node_type = id->route.addr.dev_addr.dev_type;
+			id_stats->port_num = id->port_num;
+			id_stats->bound_dev_if =
+				id->route.addr.dev_addr.bound_dev_if;
+
+			if (id->route.addr.src_addr.ss_family == AF_INET) {
+				if (ibnl_put_attr(skb, nlh,
+						  sizeof(struct sockaddr_in),
+						  &id->route.addr.src_addr,
+						  RDMA_NL_RDMA_CM_ATTR_SRC_ADDR)) {
+					goto out;
+				}
+				if (ibnl_put_attr(skb, nlh,
+						  sizeof(struct sockaddr_in),
+						  &id->route.addr.dst_addr,
+						  RDMA_NL_RDMA_CM_ATTR_DST_ADDR)) {
+					goto out;
+				}
+			} else if (id->route.addr.src_addr.ss_family == AF_INET6) {
+				if (ibnl_put_attr(skb, nlh,
+						  sizeof(struct sockaddr_in6),
+						  &id->route.addr.src_addr,
+						  RDMA_NL_RDMA_CM_ATTR_SRC_ADDR)) {
+					goto out;
+				}
+				if (ibnl_put_attr(skb, nlh,
+						  sizeof(struct sockaddr_in6),
+						  &id->route.addr.dst_addr,
+						  RDMA_NL_RDMA_CM_ATTR_DST_ADDR)) {
+					goto out;
+				}
+			}
+
+			id_stats->pid		= id_priv->owner;
+			id_stats->port_space	= id->ps;
+			id_stats->cm_state	= id_priv->state;
+			id_stats->qp_num	= id_priv->qp_num;
+			id_stats->qp_type	= id->qp_type;
+
+			i_id++;
+		}
+
+		cb->args[1] = 0;
+		i_dev++;
+	}
+
+out:
+	mutex_unlock(&lock);
+	cb->args[0] = i_dev;
+	cb->args[1] = i_id;
+
+	return skb->len;
+}
+
+static const struct ibnl_client_cbs cma_cb_table[] = {
+	[RDMA_NL_RDMA_CM_ID_STATS] = { .dump = cma_get_id_stats },
+};
+
 static int __init cma_init(void)
 {
 	int ret;
@@ -3272,6 +3430,10 @@
 	ret = ib_register_client(&cma_client);
 	if (ret)
 		goto err;
+
+	if (ibnl_add_client(RDMA_NL_RDMA_CM, RDMA_NL_RDMA_CM_NUM_OPS, cma_cb_table))
+		printk(KERN_WARNING "RDMA CMA: failed to add netlink callback\n");
+
 	return 0;
 
 err:
@@ -3284,6 +3446,7 @@
 
 static void __exit cma_cleanup(void)
 {
+	ibnl_remove_client(RDMA_NL_RDMA_CM);
 	ib_unregister_client(&cma_client);
 	unregister_netdevice_notifier(&cma_nb);
 	rdma_addr_unregister_client(&addr_client);
diff -druN linux-2.6.39-libre/drivers/infiniband/core/cm.c linux-3.0-rc7-libre/drivers/infiniband/core/cm.c
--- linux-2.6.39-libre/drivers/infiniband/core/cm.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/infiniband/core/cm.c	2011-07-11 19:51:52.000000000 -0400
@@ -3639,8 +3639,17 @@
 	.release = cm_release_port_obj
 };
 
+static char *cm_devnode(struct device *dev, mode_t *mode)
+{
+	if (mode)
+		*mode = 0666;
+	return kasprintf(GFP_KERNEL, "infiniband/%s", dev_name(dev));
+}
+
 struct class cm_class = {
+	.owner   = THIS_MODULE,
 	.name    = "infiniband_cm",
+	.devnode = cm_devnode,
 };
 EXPORT_SYMBOL(cm_class);
 
diff -druN linux-2.6.39-libre/drivers/infiniband/core/device.c linux-3.0-rc7-libre/drivers/infiniband/core/device.c
--- linux-2.6.39-libre/drivers/infiniband/core/device.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/infiniband/core/device.c	2011-07-11 19:51:52.000000000 -0400
@@ -38,6 +38,7 @@
 #include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/mutex.h>
+#include <rdma/rdma_netlink.h>
 
 #include "core_priv.h"
 
@@ -725,22 +726,40 @@
 		return -ENOMEM;
 
 	ret = ib_sysfs_setup();
-	if (ret)
+	if (ret) {
 		printk(KERN_WARNING "Couldn't create InfiniBand device class\n");
+		goto err;
+	}
+
+	ret = ibnl_init();
+	if (ret) {
+		printk(KERN_WARNING "Couldn't init IB netlink interface\n");
+		goto err_sysfs;
+	}
 
 	ret = ib_cache_setup();
 	if (ret) {
 		printk(KERN_WARNING "Couldn't set up InfiniBand P_Key/GID cache\n");
-		ib_sysfs_cleanup();
-		destroy_workqueue(ib_wq);
+		goto err_nl;
 	}
 
+	return 0;
+
+err_nl:
+	ibnl_cleanup();
+
+err_sysfs:
+	ib_sysfs_cleanup();
+
+err:
+	destroy_workqueue(ib_wq);
 	return ret;
 }
 
 static void __exit ib_core_cleanup(void)
 {
 	ib_cache_cleanup();
+	ibnl_cleanup();
 	ib_sysfs_cleanup();
 	/* Make sure that any pending umem accounting work is done. */
 	destroy_workqueue(ib_wq);
diff -druN linux-2.6.39-libre/drivers/infiniband/core/iwcm.c linux-3.0-rc7-libre/drivers/infiniband/core/iwcm.c
--- linux-2.6.39-libre/drivers/infiniband/core/iwcm.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/infiniband/core/iwcm.c	2011-07-11 19:51:52.000000000 -0400
@@ -725,7 +725,7 @@
 	 */
 	clear_bit(IWCM_F_CONNECT_WAIT, &cm_id_priv->flags);
 	BUG_ON(cm_id_priv->state != IW_CM_STATE_CONN_SENT);
-	if (iw_event->status == IW_CM_EVENT_STATUS_ACCEPTED) {
+	if (iw_event->status == 0) {
 		cm_id_priv->id.local_addr = iw_event->local_addr;
 		cm_id_priv->id.remote_addr = iw_event->remote_addr;
 		cm_id_priv->state = IW_CM_STATE_ESTABLISHED;
diff -druN linux-2.6.39-libre/drivers/infiniband/core/mad.c linux-3.0-rc7-libre/drivers/infiniband/core/mad.c
--- linux-2.6.39-libre/drivers/infiniband/core/mad.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/infiniband/core/mad.c	2011-07-11 19:51:52.000000000 -0400
@@ -276,6 +276,13 @@
 		goto error1;
 	}
 
+	/* Verify the QP requested is supported.  For example, Ethernet devices
+	 * will not have QP0 */
+	if (!port_priv->qp_info[qpn].qp) {
+		ret = ERR_PTR(-EPROTONOSUPPORT);
+		goto error1;
+	}
+
 	/* Allocate structures */
 	mad_agent_priv = kzalloc(sizeof *mad_agent_priv, GFP_KERNEL);
 	if (!mad_agent_priv) {
diff -druN linux-2.6.39-libre/drivers/infiniband/core/Makefile linux-3.0-rc7-libre/drivers/infiniband/core/Makefile
--- linux-2.6.39-libre/drivers/infiniband/core/Makefile	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/infiniband/core/Makefile	2011-07-11 19:51:52.000000000 -0400
@@ -8,7 +8,7 @@
 					$(user_access-y)
 
 ib_core-y :=			packer.o ud_header.o verbs.o sysfs.o \
-				device.o fmr_pool.o cache.o
+				device.o fmr_pool.o cache.o netlink.o
 ib_core-$(CONFIG_INFINIBAND_USER_MEM) += umem.o
 
 ib_mad-y :=			mad.o smi.o agent.o mad_rmpp.o
diff -druN linux-2.6.39-libre/drivers/infiniband/core/netlink.c linux-3.0-rc7-libre/drivers/infiniband/core/netlink.c
--- linux-2.6.39-libre/drivers/infiniband/core/netlink.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/infiniband/core/netlink.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,190 @@
+/*
+ * Copyright (c) 2010 Voltaire 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) "%s:%s: " fmt, KBUILD_MODNAME, __func__
+
+#include <net/netlink.h>
+#include <net/net_namespace.h>
+#include <net/sock.h>
+#include <rdma/rdma_netlink.h>
+
+struct ibnl_client {
+	struct list_head		list;
+	int				index;
+	int				nops;
+	const struct ibnl_client_cbs   *cb_table;
+};
+
+static DEFINE_MUTEX(ibnl_mutex);
+static struct sock *nls;
+static LIST_HEAD(client_list);
+
+int ibnl_add_client(int index, int nops,
+		    const struct ibnl_client_cbs cb_table[])
+{
+	struct ibnl_client *cur;
+	struct ibnl_client *nl_client;
+
+	nl_client = kmalloc(sizeof *nl_client, GFP_KERNEL);
+	if (!nl_client)
+		return -ENOMEM;
+
+	nl_client->index	= index;
+	nl_client->nops		= nops;
+	nl_client->cb_table	= cb_table;
+
+	mutex_lock(&ibnl_mutex);
+
+	list_for_each_entry(cur, &client_list, list) {
+		if (cur->index == index) {
+			pr_warn("Client for %d already exists\n", index);
+			mutex_unlock(&ibnl_mutex);
+			kfree(nl_client);
+			return -EINVAL;
+		}
+	}
+
+	list_add_tail(&nl_client->list, &client_list);
+
+	mutex_unlock(&ibnl_mutex);
+
+	return 0;
+}
+EXPORT_SYMBOL(ibnl_add_client);
+
+int ibnl_remove_client(int index)
+{
+	struct ibnl_client *cur, *next;
+
+	mutex_lock(&ibnl_mutex);
+	list_for_each_entry_safe(cur, next, &client_list, list) {
+		if (cur->index == index) {
+			list_del(&(cur->list));
+			mutex_unlock(&ibnl_mutex);
+			kfree(cur);
+			return 0;
+		}
+	}
+	pr_warn("Can't remove callback for client idx %d. Not found\n", index);
+	mutex_unlock(&ibnl_mutex);
+
+	return -EINVAL;
+}
+EXPORT_SYMBOL(ibnl_remove_client);
+
+void *ibnl_put_msg(struct sk_buff *skb, struct nlmsghdr **nlh, int seq,
+		   int len, int client, int op)
+{
+	unsigned char *prev_tail;
+
+	prev_tail = skb_tail_pointer(skb);
+	*nlh = NLMSG_NEW(skb, 0, seq, RDMA_NL_GET_TYPE(client, op),
+			len, NLM_F_MULTI);
+	(*nlh)->nlmsg_len = skb_tail_pointer(skb) - prev_tail;
+	return NLMSG_DATA(*nlh);
+
+nlmsg_failure:
+	nlmsg_trim(skb, prev_tail);
+	return NULL;
+}
+EXPORT_SYMBOL(ibnl_put_msg);
+
+int ibnl_put_attr(struct sk_buff *skb, struct nlmsghdr *nlh,
+		  int len, void *data, int type)
+{
+	unsigned char *prev_tail;
+
+	prev_tail = skb_tail_pointer(skb);
+	NLA_PUT(skb, type, len, data);
+	nlh->nlmsg_len += skb_tail_pointer(skb) - prev_tail;
+	return 0;
+
+nla_put_failure:
+	nlmsg_trim(skb, prev_tail - nlh->nlmsg_len);
+	return -EMSGSIZE;
+}
+EXPORT_SYMBOL(ibnl_put_attr);
+
+static int ibnl_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
+{
+	struct ibnl_client *client;
+	int type = nlh->nlmsg_type;
+	int index = RDMA_NL_GET_CLIENT(type);
+	int op = RDMA_NL_GET_OP(type);
+
+	list_for_each_entry(client, &client_list, list) {
+		if (client->index == index) {
+			if (op < 0 || op >= client->nops ||
+			    !client->cb_table[RDMA_NL_GET_OP(op)].dump)
+				return -EINVAL;
+			return netlink_dump_start(nls, skb, nlh,
+						  client->cb_table[op].dump,
+						  NULL);
+		}
+	}
+
+	pr_info("Index %d wasn't found in client list\n", index);
+	return -EINVAL;
+}
+
+static void ibnl_rcv(struct sk_buff *skb)
+{
+	mutex_lock(&ibnl_mutex);
+	netlink_rcv_skb(skb, &ibnl_rcv_msg);
+	mutex_unlock(&ibnl_mutex);
+}
+
+int __init ibnl_init(void)
+{
+	nls = netlink_kernel_create(&init_net, NETLINK_RDMA, 0, ibnl_rcv,
+				    NULL, THIS_MODULE);
+	if (!nls) {
+		pr_warn("Failed to create netlink socket\n");
+		return -ENOMEM;
+	}
+
+	return 0;
+}
+
+void ibnl_cleanup(void)
+{
+	struct ibnl_client *cur, *next;
+
+	mutex_lock(&ibnl_mutex);
+	list_for_each_entry_safe(cur, next, &client_list, list) {
+		list_del(&(cur->list));
+		kfree(cur);
+	}
+	mutex_unlock(&ibnl_mutex);
+
+	netlink_kernel_release(nls);
+}
diff -druN linux-2.6.39-libre/drivers/infiniband/core/ucma.c linux-3.0-rc7-libre/drivers/infiniband/core/ucma.c
--- linux-2.6.39-libre/drivers/infiniband/core/ucma.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/infiniband/core/ucma.c	2011-07-11 19:51:52.000000000 -0400
@@ -367,13 +367,28 @@
 	return ret;
 }
 
-static ssize_t ucma_create_id(struct ucma_file *file,
-				const char __user *inbuf,
-				int in_len, int out_len)
+static int ucma_get_qp_type(struct rdma_ucm_create_id *cmd, enum ib_qp_type *qp_type)
+{
+	switch (cmd->ps) {
+	case RDMA_PS_TCP:
+		*qp_type = IB_QPT_RC;
+		return 0;
+	case RDMA_PS_UDP:
+	case RDMA_PS_IPOIB:
+		*qp_type = IB_QPT_UD;
+		return 0;
+	default:
+		return -EINVAL;
+	}
+}
+
+static ssize_t ucma_create_id(struct ucma_file *file, const char __user *inbuf,
+			      int in_len, int out_len)
 {
 	struct rdma_ucm_create_id cmd;
 	struct rdma_ucm_create_id_resp resp;
 	struct ucma_context *ctx;
+	enum ib_qp_type qp_type;
 	int ret;
 
 	if (out_len < sizeof(resp))
@@ -382,6 +397,10 @@
 	if (copy_from_user(&cmd, inbuf, sizeof(cmd)))
 		return -EFAULT;
 
+	ret = ucma_get_qp_type(&cmd, &qp_type);
+	if (ret)
+		return ret;
+
 	mutex_lock(&file->mut);
 	ctx = ucma_alloc_ctx(file);
 	mutex_unlock(&file->mut);
@@ -389,7 +408,7 @@
 		return -ENOMEM;
 
 	ctx->uid = cmd.uid;
-	ctx->cm_id = rdma_create_id(ucma_event_handler, ctx, cmd.ps);
+	ctx->cm_id = rdma_create_id(ucma_event_handler, ctx, cmd.ps, qp_type);
 	if (IS_ERR(ctx->cm_id)) {
 		ret = PTR_ERR(ctx->cm_id);
 		goto err1;
@@ -883,6 +902,13 @@
 		}
 		rdma_set_service_type(ctx->cm_id, *((u8 *) optval));
 		break;
+	case RDMA_OPTION_ID_REUSEADDR:
+		if (optlen != sizeof(int)) {
+			ret = -EINVAL;
+			break;
+		}
+		ret = rdma_set_reuseaddr(ctx->cm_id, *((int *) optval) ? 1 : 0);
+		break;
 	default:
 		ret = -ENOSYS;
 	}
@@ -1331,9 +1357,11 @@
 };
 
 static struct miscdevice ucma_misc = {
-	.minor	= MISC_DYNAMIC_MINOR,
-	.name	= "rdma_cm",
-	.fops	= &ucma_fops,
+	.minor		= MISC_DYNAMIC_MINOR,
+	.name		= "rdma_cm",
+	.nodename	= "infiniband/rdma_cm",
+	.mode		= 0666,
+	.fops		= &ucma_fops,
 };
 
 static ssize_t show_abi_version(struct device *dev,
diff -druN linux-2.6.39-libre/drivers/infiniband/core/user_mad.c linux-3.0-rc7-libre/drivers/infiniband/core/user_mad.c
--- linux-2.6.39-libre/drivers/infiniband/core/user_mad.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/infiniband/core/user_mad.c	2011-07-11 19:51:52.000000000 -0400
@@ -1176,6 +1176,11 @@
 	kref_put(&umad_dev->ref, ib_umad_release_dev);
 }
 
+static char *umad_devnode(struct device *dev, mode_t *mode)
+{
+	return kasprintf(GFP_KERNEL, "infiniband/%s", dev_name(dev));
+}
+
 static int __init ib_umad_init(void)
 {
 	int ret;
@@ -1194,6 +1199,8 @@
 		goto out_chrdev;
 	}
 
+	umad_class->devnode = umad_devnode;
+
 	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");
diff -druN linux-2.6.39-libre/drivers/infiniband/core/uverbs_main.c linux-3.0-rc7-libre/drivers/infiniband/core/uverbs_main.c
--- linux-2.6.39-libre/drivers/infiniband/core/uverbs_main.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/infiniband/core/uverbs_main.c	2011-07-11 19:51:52.000000000 -0400
@@ -824,6 +824,13 @@
 	kfree(uverbs_dev);
 }
 
+static char *uverbs_devnode(struct device *dev, mode_t *mode)
+{
+	if (mode)
+		*mode = 0666;
+	return kasprintf(GFP_KERNEL, "infiniband/%s", dev_name(dev));
+}
+
 static int __init ib_uverbs_init(void)
 {
 	int ret;
@@ -842,6 +849,8 @@
 		goto out_chrdev;
 	}
 
+	uverbs_class->devnode = uverbs_devnode;
+
 	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");
diff -druN linux-2.6.39-libre/drivers/infiniband/hw/amso1100/c2.c linux-3.0-rc7-libre/drivers/infiniband/hw/amso1100/c2.c
--- linux-2.6.39-libre/drivers/infiniband/hw/amso1100/c2.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/infiniband/hw/amso1100/c2.c	2011-07-11 19:51:52.000000000 -0400
@@ -47,6 +47,7 @@
 #include <linux/init.h>
 #include <linux/dma-mapping.h>
 #include <linux/slab.h>
+#include <linux/prefetch.h>
 
 #include <asm/io.h>
 #include <asm/irq.h>
diff -druN linux-2.6.39-libre/drivers/infiniband/hw/cxgb3/iwch_cm.c linux-3.0-rc7-libre/drivers/infiniband/hw/cxgb3/iwch_cm.c
--- linux-2.6.39-libre/drivers/infiniband/hw/cxgb3/iwch_cm.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/infiniband/hw/cxgb3/iwch_cm.c	2011-07-11 19:51:52.000000000 -0400
@@ -338,8 +338,9 @@
 				 __be16 peer_port, u8 tos)
 {
 	struct rtable *rt;
+	struct flowi4 fl4;
 
-	rt = ip_route_output_ports(&init_net, NULL, peer_ip, local_ip,
+	rt = ip_route_output_ports(&init_net, &fl4, NULL, peer_ip, local_ip,
 				   peer_port, local_port, IPPROTO_TCP,
 				   tos, 0);
 	if (IS_ERR(rt))
@@ -913,7 +914,7 @@
 		goto err;
 
 	if (peer2peer && iwch_rqes_posted(ep->com.qp) == 0) {
-		iwch_post_zb_read(ep->com.qp);
+		iwch_post_zb_read(ep);
 	}
 
 	goto out;
@@ -1077,6 +1078,8 @@
 	struct iwch_ep *ep = ctx;
 	struct cpl_wr_ack *hdr = cplhdr(skb);
 	unsigned int credits = ntohs(hdr->credits);
+	unsigned long flags;
+	int post_zb = 0;
 
 	PDBG("%s ep %p credits %u\n", __func__, ep, credits);
 
@@ -1086,28 +1089,34 @@
 		return CPL_RET_BUF_DONE;
 	}
 
+	spin_lock_irqsave(&ep->com.lock, flags);
 	BUG_ON(credits != 1);
 	dst_confirm(ep->dst);
 	if (!ep->mpa_skb) {
 		PDBG("%s rdma_init wr_ack ep %p state %u\n",
-			__func__, ep, state_read(&ep->com));
+			__func__, ep, ep->com.state);
 		if (ep->mpa_attr.initiator) {
 			PDBG("%s initiator ep %p state %u\n",
-				__func__, ep, state_read(&ep->com));
-			if (peer2peer)
-				iwch_post_zb_read(ep->com.qp);
+				__func__, ep, ep->com.state);
+			if (peer2peer && ep->com.state == FPDU_MODE)
+				post_zb = 1;
 		} else {
 			PDBG("%s responder ep %p state %u\n",
-				__func__, ep, state_read(&ep->com));
-			ep->com.rpl_done = 1;
-			wake_up(&ep->com.waitq);
+				__func__, ep, ep->com.state);
+			if (ep->com.state == MPA_REQ_RCVD) {
+				ep->com.rpl_done = 1;
+				wake_up(&ep->com.waitq);
+			}
 		}
 	} else {
 		PDBG("%s lsm ack ep %p state %u freeing skb\n",
-			__func__, ep, state_read(&ep->com));
+			__func__, ep, ep->com.state);
 		kfree_skb(ep->mpa_skb);
 		ep->mpa_skb = NULL;
 	}
+	spin_unlock_irqrestore(&ep->com.lock, flags);
+	if (post_zb)
+		iwch_post_zb_read(ep);
 	return CPL_RET_BUF_DONE;
 }
 
diff -druN linux-2.6.39-libre/drivers/infiniband/hw/cxgb3/iwch_provider.h linux-3.0-rc7-libre/drivers/infiniband/hw/cxgb3/iwch_provider.h
--- linux-2.6.39-libre/drivers/infiniband/hw/cxgb3/iwch_provider.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/infiniband/hw/cxgb3/iwch_provider.h	2011-07-11 19:51:52.000000000 -0400
@@ -332,7 +332,7 @@
 			     struct ib_mw_bind *mw_bind);
 int iwch_poll_cq(struct ib_cq *ibcq, int num_entries, struct ib_wc *wc);
 int iwch_post_terminate(struct iwch_qp *qhp, struct respQ_msg_t *rsp_msg);
-int iwch_post_zb_read(struct iwch_qp *qhp);
+int iwch_post_zb_read(struct iwch_ep *ep);
 int iwch_register_device(struct iwch_dev *dev);
 void iwch_unregister_device(struct iwch_dev *dev);
 void stop_read_rep_timer(struct iwch_qp *qhp);
diff -druN linux-2.6.39-libre/drivers/infiniband/hw/cxgb3/iwch_qp.c linux-3.0-rc7-libre/drivers/infiniband/hw/cxgb3/iwch_qp.c
--- linux-2.6.39-libre/drivers/infiniband/hw/cxgb3/iwch_qp.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/infiniband/hw/cxgb3/iwch_qp.c	2011-07-11 19:51:52.000000000 -0400
@@ -738,7 +738,7 @@
 	}
 }
 
-int iwch_post_zb_read(struct iwch_qp *qhp)
+int iwch_post_zb_read(struct iwch_ep *ep)
 {
 	union t3_wr *wqe;
 	struct sk_buff *skb;
@@ -761,10 +761,10 @@
 	wqe->read.local_len = cpu_to_be32(0);
 	wqe->read.local_to = cpu_to_be64(1);
 	wqe->send.wrh.op_seop_flags = cpu_to_be32(V_FW_RIWR_OP(T3_WR_READ));
-	wqe->send.wrh.gen_tid_len = cpu_to_be32(V_FW_RIWR_TID(qhp->ep->hwtid)|
+	wqe->send.wrh.gen_tid_len = cpu_to_be32(V_FW_RIWR_TID(ep->hwtid)|
 						V_FW_RIWR_LEN(flit_cnt));
 	skb->priority = CPL_PRIORITY_DATA;
-	return iwch_cxgb3_ofld_send(qhp->rhp->rdev.t3cdev_p, skb);
+	return iwch_cxgb3_ofld_send(ep->com.qp->rhp->rdev.t3cdev_p, skb);
 }
 
 /*
diff -druN linux-2.6.39-libre/drivers/infiniband/hw/cxgb4/cm.c linux-3.0-rc7-libre/drivers/infiniband/hw/cxgb4/cm.c
--- linux-2.6.39-libre/drivers/infiniband/hw/cxgb4/cm.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/infiniband/hw/cxgb4/cm.c	2011-07-11 19:51:52.000000000 -0400
@@ -315,8 +315,9 @@
 				 __be16 peer_port, u8 tos)
 {
 	struct rtable *rt;
+	struct flowi4 fl4;
 
-	rt = ip_route_output_ports(&init_net, NULL, peer_ip, local_ip,
+	rt = ip_route_output_ports(&init_net, &fl4, NULL, peer_ip, local_ip,
 				   peer_port, local_port, IPPROTO_TCP,
 				   tos, 0);
 	if (IS_ERR(rt))
@@ -1198,9 +1199,7 @@
 	}
 	PDBG("%s ep %p status %d error %d\n", __func__, ep,
 	     rpl->status, status2errno(rpl->status));
-	ep->com.wr_wait.ret = status2errno(rpl->status);
-	ep->com.wr_wait.done = 1;
-	wake_up(&ep->com.wr_wait.wait);
+	c4iw_wake_up(&ep->com.wr_wait, status2errno(rpl->status));
 
 	return 0;
 }
@@ -1234,9 +1233,7 @@
 	struct c4iw_listen_ep *ep = lookup_stid(t, stid);
 
 	PDBG("%s ep %p\n", __func__, ep);
-	ep->com.wr_wait.ret = status2errno(rpl->status);
-	ep->com.wr_wait.done = 1;
-	wake_up(&ep->com.wr_wait.wait);
+	c4iw_wake_up(&ep->com.wr_wait, status2errno(rpl->status));
 	return 0;
 }
 
@@ -1466,9 +1463,9 @@
 	struct c4iw_qp_attributes attrs;
 	int disconnect = 1;
 	int release = 0;
-	int closing = 0;
 	struct tid_info *t = dev->rdev.lldi.tids;
 	unsigned int tid = GET_TID(hdr);
+	int ret;
 
 	ep = lookup_tid(t, tid);
 	PDBG("%s ep %p tid %u\n", __func__, ep, ep->hwtid);
@@ -1492,23 +1489,24 @@
 		 * in rdma connection migration (see c4iw_accept_cr()).
 		 */
 		__state_set(&ep->com, CLOSING);
-		ep->com.wr_wait.done = 1;
-		ep->com.wr_wait.ret = -ECONNRESET;
 		PDBG("waking up ep %p tid %u\n", ep, ep->hwtid);
-		wake_up(&ep->com.wr_wait.wait);
+		c4iw_wake_up(&ep->com.wr_wait, -ECONNRESET);
 		break;
 	case MPA_REP_SENT:
 		__state_set(&ep->com, CLOSING);
-		ep->com.wr_wait.done = 1;
-		ep->com.wr_wait.ret = -ECONNRESET;
 		PDBG("waking up ep %p tid %u\n", ep, ep->hwtid);
-		wake_up(&ep->com.wr_wait.wait);
+		c4iw_wake_up(&ep->com.wr_wait, -ECONNRESET);
 		break;
 	case FPDU_MODE:
 		start_ep_timer(ep);
 		__state_set(&ep->com, CLOSING);
-		closing = 1;
-		peer_close_upcall(ep);
+		attrs.next_state = C4IW_QP_STATE_CLOSING;
+		ret = c4iw_modify_qp(ep->com.qp->rhp, ep->com.qp,
+				       C4IW_QP_ATTR_NEXT_STATE, &attrs, 1);
+		if (ret != -ECONNRESET) {
+			peer_close_upcall(ep);
+			disconnect = 1;
+		}
 		break;
 	case ABORTING:
 		disconnect = 0;
@@ -1536,11 +1534,6 @@
 		BUG_ON(1);
 	}
 	mutex_unlock(&ep->com.mutex);
-	if (closing) {
-		attrs.next_state = C4IW_QP_STATE_CLOSING;
-		c4iw_modify_qp(ep->com.qp->rhp, ep->com.qp,
-			       C4IW_QP_ATTR_NEXT_STATE, &attrs, 1);
-	}
 	if (disconnect)
 		c4iw_ep_disconnect(ep, 0, GFP_KERNEL);
 	if (release)
@@ -1581,9 +1574,7 @@
 	/*
 	 * Wake up any threads in rdma_init() or rdma_fini().
 	 */
-	ep->com.wr_wait.done = 1;
-	ep->com.wr_wait.ret = -ECONNRESET;
-	wake_up(&ep->com.wr_wait.wait);
+	c4iw_wake_up(&ep->com.wr_wait, -ECONNRESET);
 
 	mutex_lock(&ep->com.mutex);
 	switch (ep->com.state) {
@@ -1710,14 +1701,14 @@
 	ep = lookup_tid(t, tid);
 	BUG_ON(!ep);
 
-	if (ep->com.qp) {
+	if (ep && ep->com.qp) {
 		printk(KERN_WARNING MOD "TERM received tid %u qpid %u\n", tid,
 		       ep->com.qp->wq.sq.qid);
 		attrs.next_state = C4IW_QP_STATE_TERMINATE;
 		c4iw_modify_qp(ep->com.qp->rhp, ep->com.qp,
 			       C4IW_QP_ATTR_NEXT_STATE, &attrs, 1);
 	} else
-		printk(KERN_WARNING MOD "TERM received tid %u no qp\n", tid);
+		printk(KERN_WARNING MOD "TERM received tid %u no ep/qp\n", tid);
 
 	return 0;
 }
@@ -2120,15 +2111,16 @@
 		break;
 	}
 
-	mutex_unlock(&ep->com.mutex);
 	if (close) {
-		if (abrupt)
-			ret = abort_connection(ep, NULL, gfp);
-		else
+		if (abrupt) {
+			close_complete_upcall(ep);
+			ret = send_abort(ep, NULL, gfp);
+		} else
 			ret = send_halfclose(ep, gfp);
 		if (ret)
 			fatal = 1;
 	}
+	mutex_unlock(&ep->com.mutex);
 	if (fatal)
 		release_ep_resources(ep);
 	return ret;
@@ -2296,14 +2288,8 @@
 		ret = (int)((be64_to_cpu(rpl->data[0]) >> 8) & 0xff);
 		wr_waitp = (struct c4iw_wr_wait *)(__force unsigned long) rpl->data[1];
 		PDBG("%s wr_waitp %p ret %u\n", __func__, wr_waitp, ret);
-		if (wr_waitp) {
-			if (ret)
-				wr_waitp->ret = -ret;
-			else
-				wr_waitp->ret = 0;
-			wr_waitp->done = 1;
-			wake_up(&wr_waitp->wait);
-		}
+		if (wr_waitp)
+			c4iw_wake_up(wr_waitp, ret ? -ret : 0);
 		kfree_skb(skb);
 		break;
 	case 2:
@@ -2318,6 +2304,31 @@
 	return 0;
 }
 
+static int peer_abort_intr(struct c4iw_dev *dev, struct sk_buff *skb)
+{
+	struct cpl_abort_req_rss *req = cplhdr(skb);
+	struct c4iw_ep *ep;
+	struct tid_info *t = dev->rdev.lldi.tids;
+	unsigned int tid = GET_TID(req);
+
+	ep = lookup_tid(t, tid);
+	if (is_neg_adv_abort(req->status)) {
+		PDBG("%s neg_adv_abort ep %p tid %u\n", __func__, ep,
+		     ep->hwtid);
+		kfree_skb(skb);
+		return 0;
+	}
+	PDBG("%s ep %p tid %u state %u\n", __func__, ep, ep->hwtid,
+	     ep->com.state);
+
+	/*
+	 * Wake up any threads in rdma_init() or rdma_fini().
+	 */
+	c4iw_wake_up(&ep->com.wr_wait, -ECONNRESET);
+	sched(dev, skb);
+	return 0;
+}
+
 /*
  * Most upcalls from the T4 Core go to sched() to
  * schedule the processing on a work queue.
@@ -2334,7 +2345,7 @@
 	[CPL_PASS_ESTABLISH] = sched,
 	[CPL_PEER_CLOSE] = sched,
 	[CPL_CLOSE_CON_RPL] = sched,
-	[CPL_ABORT_REQ_RSS] = sched,
+	[CPL_ABORT_REQ_RSS] = peer_abort_intr,
 	[CPL_RDMA_TERMINATE] = sched,
 	[CPL_FW4_ACK] = sched,
 	[CPL_SET_TCB_RPL] = set_tcb_rpl,
diff -druN linux-2.6.39-libre/drivers/infiniband/hw/cxgb4/cq.c linux-3.0-rc7-libre/drivers/infiniband/hw/cxgb4/cq.c
--- linux-2.6.39-libre/drivers/infiniband/hw/cxgb4/cq.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/infiniband/hw/cxgb4/cq.c	2011-07-11 19:51:52.000000000 -0400
@@ -801,6 +801,10 @@
 	if (ucontext) {
 		memsize = roundup(memsize, PAGE_SIZE);
 		hwentries = memsize / sizeof *chp->cq.queue;
+		while (hwentries > T4_MAX_IQ_SIZE) {
+			memsize -= PAGE_SIZE;
+			hwentries = memsize / sizeof *chp->cq.queue;
+		}
 	}
 	chp->cq.size = hwentries;
 	chp->cq.memsize = memsize;
diff -druN linux-2.6.39-libre/drivers/infiniband/hw/cxgb4/device.c linux-3.0-rc7-libre/drivers/infiniband/hw/cxgb4/device.c
--- linux-2.6.39-libre/drivers/infiniband/hw/cxgb4/device.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/infiniband/hw/cxgb4/device.c	2011-07-11 19:51:52.000000000 -0400
@@ -44,7 +44,7 @@
 MODULE_LICENSE("Dual BSD/GPL");
 MODULE_VERSION(DRV_VERSION);
 
-static LIST_HEAD(dev_list);
+static LIST_HEAD(uld_ctx_list);
 static DEFINE_MUTEX(dev_mutex);
 
 static struct dentry *c4iw_debugfs_root;
@@ -370,18 +370,23 @@
 	c4iw_destroy_resource(&rdev->resource);
 }
 
-static void c4iw_remove(struct c4iw_dev *dev)
+struct uld_ctx {
+	struct list_head entry;
+	struct cxgb4_lld_info lldi;
+	struct c4iw_dev *dev;
+};
+
+static void c4iw_remove(struct uld_ctx *ctx)
 {
-	PDBG("%s c4iw_dev %p\n", __func__,  dev);
-	list_del(&dev->entry);
-	if (dev->registered)
-		c4iw_unregister_device(dev);
-	c4iw_rdev_close(&dev->rdev);
-	idr_destroy(&dev->cqidr);
-	idr_destroy(&dev->qpidr);
-	idr_destroy(&dev->mmidr);
-	iounmap(dev->rdev.oc_mw_kva);
-	ib_dealloc_device(&dev->ibdev);
+	PDBG("%s c4iw_dev %p\n", __func__,  ctx->dev);
+	c4iw_unregister_device(ctx->dev);
+	c4iw_rdev_close(&ctx->dev->rdev);
+	idr_destroy(&ctx->dev->cqidr);
+	idr_destroy(&ctx->dev->qpidr);
+	idr_destroy(&ctx->dev->mmidr);
+	iounmap(ctx->dev->rdev.oc_mw_kva);
+	ib_dealloc_device(&ctx->dev->ibdev);
+	ctx->dev = NULL;
 }
 
 static struct c4iw_dev *c4iw_alloc(const struct cxgb4_lld_info *infop)
@@ -392,7 +397,7 @@
 	devp = (struct c4iw_dev *)ib_alloc_device(sizeof(*devp));
 	if (!devp) {
 		printk(KERN_ERR MOD "Cannot allocate ib device\n");
-		return NULL;
+		return ERR_PTR(-ENOMEM);
 	}
 	devp->rdev.lldi = *infop;
 
@@ -402,27 +407,23 @@
 	devp->rdev.oc_mw_kva = ioremap_wc(devp->rdev.oc_mw_pa,
 					       devp->rdev.lldi.vr->ocq.size);
 
-	printk(KERN_INFO MOD "ocq memory: "
+	PDBG(KERN_INFO MOD "ocq memory: "
 	       "hw_start 0x%x size %u mw_pa 0x%lx mw_kva %p\n",
 	       devp->rdev.lldi.vr->ocq.start, devp->rdev.lldi.vr->ocq.size,
 	       devp->rdev.oc_mw_pa, devp->rdev.oc_mw_kva);
 
-	mutex_lock(&dev_mutex);
-
 	ret = c4iw_rdev_open(&devp->rdev);
 	if (ret) {
 		mutex_unlock(&dev_mutex);
 		printk(KERN_ERR MOD "Unable to open CXIO rdev err %d\n", ret);
 		ib_dealloc_device(&devp->ibdev);
-		return NULL;
+		return ERR_PTR(ret);
 	}
 
 	idr_init(&devp->cqidr);
 	idr_init(&devp->qpidr);
 	idr_init(&devp->mmidr);
 	spin_lock_init(&devp->lock);
-	list_add_tail(&devp->entry, &dev_list);
-	mutex_unlock(&dev_mutex);
 
 	if (c4iw_debugfs_root) {
 		devp->debugfs_root = debugfs_create_dir(
@@ -435,7 +436,7 @@
 
 static void *c4iw_uld_add(const struct cxgb4_lld_info *infop)
 {
-	struct c4iw_dev *dev;
+	struct uld_ctx *ctx;
 	static int vers_printed;
 	int i;
 
@@ -443,25 +444,33 @@
 		printk(KERN_INFO MOD "Chelsio T4 RDMA Driver - version %s\n",
 		       DRV_VERSION);
 
-	dev = c4iw_alloc(infop);
-	if (!dev)
+	ctx = kzalloc(sizeof *ctx, GFP_KERNEL);
+	if (!ctx) {
+		ctx = ERR_PTR(-ENOMEM);
 		goto out;
+	}
+	ctx->lldi = *infop;
 
 	PDBG("%s found device %s nchan %u nrxq %u ntxq %u nports %u\n",
-	     __func__, pci_name(dev->rdev.lldi.pdev),
-	     dev->rdev.lldi.nchan, dev->rdev.lldi.nrxq,
-	     dev->rdev.lldi.ntxq, dev->rdev.lldi.nports);
+	     __func__, pci_name(ctx->lldi.pdev),
+	     ctx->lldi.nchan, ctx->lldi.nrxq,
+	     ctx->lldi.ntxq, ctx->lldi.nports);
 
-	for (i = 0; i < dev->rdev.lldi.nrxq; i++)
-		PDBG("rxqid[%u] %u\n", i, dev->rdev.lldi.rxq_ids[i]);
+	mutex_lock(&dev_mutex);
+	list_add_tail(&ctx->entry, &uld_ctx_list);
+	mutex_unlock(&dev_mutex);
+
+	for (i = 0; i < ctx->lldi.nrxq; i++)
+		PDBG("rxqid[%u] %u\n", i, ctx->lldi.rxq_ids[i]);
 out:
-	return dev;
+	return ctx;
 }
 
 static int c4iw_uld_rx_handler(void *handle, const __be64 *rsp,
 			const struct pkt_gl *gl)
 {
-	struct c4iw_dev *dev = handle;
+	struct uld_ctx *ctx = handle;
+	struct c4iw_dev *dev = ctx->dev;
 	struct sk_buff *skb;
 	const struct cpl_act_establish *rpl;
 	unsigned int opcode;
@@ -503,47 +512,49 @@
 
 static int c4iw_uld_state_change(void *handle, enum cxgb4_state new_state)
 {
-	struct c4iw_dev *dev = handle;
+	struct uld_ctx *ctx = handle;
 
 	PDBG("%s new_state %u\n", __func__, new_state);
 	switch (new_state) {
 	case CXGB4_STATE_UP:
-		printk(KERN_INFO MOD "%s: Up\n", pci_name(dev->rdev.lldi.pdev));
-		if (!dev->registered) {
-			int ret;
-			ret = c4iw_register_device(dev);
-			if (ret)
+		printk(KERN_INFO MOD "%s: Up\n", pci_name(ctx->lldi.pdev));
+		if (!ctx->dev) {
+			int ret = 0;
+
+			ctx->dev = c4iw_alloc(&ctx->lldi);
+			if (!IS_ERR(ctx->dev))
+				ret = c4iw_register_device(ctx->dev);
+			if (IS_ERR(ctx->dev) || ret)
 				printk(KERN_ERR MOD
 				       "%s: RDMA registration failed: %d\n",
-				       pci_name(dev->rdev.lldi.pdev), ret);
+				       pci_name(ctx->lldi.pdev), ret);
 		}
 		break;
 	case CXGB4_STATE_DOWN:
 		printk(KERN_INFO MOD "%s: Down\n",
-		       pci_name(dev->rdev.lldi.pdev));
-		if (dev->registered)
-			c4iw_unregister_device(dev);
+		       pci_name(ctx->lldi.pdev));
+		if (ctx->dev)
+			c4iw_remove(ctx);
 		break;
 	case CXGB4_STATE_START_RECOVERY:
 		printk(KERN_INFO MOD "%s: Fatal Error\n",
-		       pci_name(dev->rdev.lldi.pdev));
-		dev->rdev.flags |= T4_FATAL_ERROR;
-		if (dev->registered) {
+		       pci_name(ctx->lldi.pdev));
+		if (ctx->dev) {
 			struct ib_event event;
 
+			ctx->dev->rdev.flags |= T4_FATAL_ERROR;
 			memset(&event, 0, sizeof event);
 			event.event  = IB_EVENT_DEVICE_FATAL;
-			event.device = &dev->ibdev;
+			event.device = &ctx->dev->ibdev;
 			ib_dispatch_event(&event);
-			c4iw_unregister_device(dev);
+			c4iw_remove(ctx);
 		}
 		break;
 	case CXGB4_STATE_DETACH:
 		printk(KERN_INFO MOD "%s: Detach\n",
-		       pci_name(dev->rdev.lldi.pdev));
-		mutex_lock(&dev_mutex);
-		c4iw_remove(dev);
-		mutex_unlock(&dev_mutex);
+		       pci_name(ctx->lldi.pdev));
+		if (ctx->dev)
+			c4iw_remove(ctx);
 		break;
 	}
 	return 0;
@@ -576,11 +587,13 @@
 
 static void __exit c4iw_exit_module(void)
 {
-	struct c4iw_dev *dev, *tmp;
+	struct uld_ctx *ctx, *tmp;
 
 	mutex_lock(&dev_mutex);
-	list_for_each_entry_safe(dev, tmp, &dev_list, entry) {
-		c4iw_remove(dev);
+	list_for_each_entry_safe(ctx, tmp, &uld_ctx_list, entry) {
+		if (ctx->dev)
+			c4iw_remove(ctx);
+		kfree(ctx);
 	}
 	mutex_unlock(&dev_mutex);
 	cxgb4_unregister_uld(CXGB4_ULD_RDMA);
diff -druN linux-2.6.39-libre/drivers/infiniband/hw/cxgb4/iw_cxgb4.h linux-3.0-rc7-libre/drivers/infiniband/hw/cxgb4/iw_cxgb4.h
--- linux-2.6.39-libre/drivers/infiniband/hw/cxgb4/iw_cxgb4.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/infiniband/hw/cxgb4/iw_cxgb4.h	2011-07-11 19:51:52.000000000 -0400
@@ -35,7 +35,7 @@
 #include <linux/list.h>
 #include <linux/spinlock.h>
 #include <linux/idr.h>
-#include <linux/workqueue.h>
+#include <linux/completion.h>
 #include <linux/netdevice.h>
 #include <linux/sched.h>
 #include <linux/pci.h>
@@ -132,16 +132,20 @@
 #define C4IW_WR_TO (10*HZ)
 
 struct c4iw_wr_wait {
-	wait_queue_head_t wait;
-	int done;
+	struct completion completion;
 	int ret;
 };
 
 static inline void c4iw_init_wr_wait(struct c4iw_wr_wait *wr_waitp)
 {
 	wr_waitp->ret = 0;
-	wr_waitp->done = 0;
-	init_waitqueue_head(&wr_waitp->wait);
+	init_completion(&wr_waitp->completion);
+}
+
+static inline void c4iw_wake_up(struct c4iw_wr_wait *wr_waitp, int ret)
+{
+	wr_waitp->ret = ret;
+	complete(&wr_waitp->completion);
 }
 
 static inline int c4iw_wait_for_reply(struct c4iw_rdev *rdev,
@@ -150,23 +154,27 @@
 				 const char *func)
 {
 	unsigned to = C4IW_WR_TO;
-	do {
+	int ret;
 
-		wait_event_timeout(wr_waitp->wait, wr_waitp->done, to);
-		if (!wr_waitp->done) {
+	do {
+		ret = wait_for_completion_timeout(&wr_waitp->completion, to);
+		if (!ret) {
 			printk(KERN_ERR MOD "%s - Device %s not responding - "
 			       "tid %u qpid %u\n", func,
 			       pci_name(rdev->lldi.pdev), hwtid, qpid);
+			if (c4iw_fatal_error(rdev)) {
+				wr_waitp->ret = -EIO;
+				break;
+			}
 			to = to << 2;
 		}
-	} while (!wr_waitp->done);
+	} while (!ret);
 	if (wr_waitp->ret)
-		printk(KERN_WARNING MOD "%s: FW reply %d tid %u qpid %u\n",
-		       pci_name(rdev->lldi.pdev), wr_waitp->ret, hwtid, qpid);
+		PDBG("%s: FW reply %d tid %u qpid %u\n",
+		     pci_name(rdev->lldi.pdev), wr_waitp->ret, hwtid, qpid);
 	return wr_waitp->ret;
 }
 
-
 struct c4iw_dev {
 	struct ib_device ibdev;
 	struct c4iw_rdev rdev;
@@ -175,9 +183,7 @@
 	struct idr qpidr;
 	struct idr mmidr;
 	spinlock_t lock;
-	struct list_head entry;
 	struct dentry *debugfs_root;
-	u8 registered;
 };
 
 static inline struct c4iw_dev *to_c4iw_dev(struct ib_device *ibdev)
diff -druN linux-2.6.39-libre/drivers/infiniband/hw/cxgb4/mem.c linux-3.0-rc7-libre/drivers/infiniband/hw/cxgb4/mem.c
--- linux-2.6.39-libre/drivers/infiniband/hw/cxgb4/mem.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/infiniband/hw/cxgb4/mem.c	2011-07-11 19:51:52.000000000 -0400
@@ -625,7 +625,7 @@
 	mhp->attr.perms = c4iw_ib_to_tpt_access(acc);
 	mhp->attr.va_fbo = virt;
 	mhp->attr.page_size = shift - 12;
-	mhp->attr.len = (u32) length;
+	mhp->attr.len = length;
 
 	err = register_mem(rhp, php, mhp, shift);
 	if (err)
diff -druN linux-2.6.39-libre/drivers/infiniband/hw/cxgb4/provider.c linux-3.0-rc7-libre/drivers/infiniband/hw/cxgb4/provider.c
--- linux-2.6.39-libre/drivers/infiniband/hw/cxgb4/provider.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/infiniband/hw/cxgb4/provider.c	2011-07-11 19:51:52.000000000 -0400
@@ -516,7 +516,6 @@
 		if (ret)
 			goto bail2;
 	}
-	dev->registered = 1;
 	return 0;
 bail2:
 	ib_unregister_device(&dev->ibdev);
@@ -535,6 +534,5 @@
 				   c4iw_class_attributes[i]);
 	ib_unregister_device(&dev->ibdev);
 	kfree(dev->ibdev.iwcm);
-	dev->registered = 0;
 	return;
 }
diff -druN linux-2.6.39-libre/drivers/infiniband/hw/cxgb4/qp.c linux-3.0-rc7-libre/drivers/infiniband/hw/cxgb4/qp.c
--- linux-2.6.39-libre/drivers/infiniband/hw/cxgb4/qp.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/infiniband/hw/cxgb4/qp.c	2011-07-11 19:51:52.000000000 -0400
@@ -214,7 +214,7 @@
 		V_FW_RI_RES_WR_HOSTFCMODE(0) |	/* no host cidx updates */
 		V_FW_RI_RES_WR_CPRIO(0) |	/* don't keep in chip cache */
 		V_FW_RI_RES_WR_PCIECHN(0) |	/* set by uP at ri_init time */
-		t4_sq_onchip(&wq->sq) ? F_FW_RI_RES_WR_ONCHIP : 0 |
+		(t4_sq_onchip(&wq->sq) ? F_FW_RI_RES_WR_ONCHIP : 0) |
 		V_FW_RI_RES_WR_IQID(scq->cqid));
 	res->u.sqrq.dcaen_to_eqsize = cpu_to_be32(
 		V_FW_RI_RES_WR_DCAEN(0) |
@@ -1207,12 +1207,8 @@
 				c4iw_get_ep(&qhp->ep->com);
 			}
 			ret = rdma_fini(rhp, qhp, ep);
-			if (ret) {
-				if (internal)
-					c4iw_get_ep(&qhp->ep->com);
-				disconnect = abort = 1;
+			if (ret)
 				goto err;
-			}
 			break;
 		case C4IW_QP_STATE_TERMINATE:
 			set_state(qhp, C4IW_QP_STATE_TERMINATE);
diff -druN linux-2.6.39-libre/drivers/infiniband/hw/cxgb4/t4.h linux-3.0-rc7-libre/drivers/infiniband/hw/cxgb4/t4.h
--- linux-2.6.39-libre/drivers/infiniband/hw/cxgb4/t4.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/infiniband/hw/cxgb4/t4.h	2011-07-11 19:51:52.000000000 -0400
@@ -269,11 +269,8 @@
 
 static inline pgprot_t t4_pgprot_wc(pgprot_t prot)
 {
-#if defined(__i386__) || defined(__x86_64__)
+#if defined(__i386__) || defined(__x86_64__) || defined(CONFIG_PPC64)
 	return pgprot_writecombine(prot);
-#elif defined(CONFIG_PPC64)
-	return __pgprot((pgprot_val(prot) | _PAGE_NO_CACHE) &
-			~(pgprot_t)_PAGE_GUARDED);
 #else
 	return pgprot_noncached(prot);
 #endif
diff -druN linux-2.6.39-libre/drivers/infiniband/hw/ipath/ipath_driver.c linux-3.0-rc7-libre/drivers/infiniband/hw/ipath/ipath_driver.c
--- linux-2.6.39-libre/drivers/infiniband/hw/ipath/ipath_driver.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/infiniband/hw/ipath/ipath_driver.c	2011-07-11 19:51:52.000000000 -0400
@@ -398,7 +398,6 @@
 	struct ipath_devdata *dd;
 	unsigned long long addr;
 	u32 bar0 = 0, bar1 = 0;
-	u8 rev;
 
 	dd = ipath_alloc_devdata(pdev);
 	if (IS_ERR(dd)) {
@@ -540,13 +539,7 @@
 		goto bail_regions;
 	}
 
-	ret = pci_read_config_byte(pdev, PCI_REVISION_ID, &rev);
-	if (ret) {
-		ipath_dev_err(dd, "Failed to read PCI revision ID unit "
-			      "%u: err %d\n", dd->ipath_unit, -ret);
-		goto bail_regions;	/* shouldn't ever happen */
-	}
-	dd->ipath_pcirev = rev;
+	dd->ipath_pcirev = pdev->revision;
 
 #if defined(__powerpc__)
 	/* There isn't a generic way to specify writethrough mappings */
diff -druN linux-2.6.39-libre/drivers/infiniband/hw/nes/nes.c linux-3.0-rc7-libre/drivers/infiniband/hw/nes/nes.c
--- linux-2.6.39-libre/drivers/infiniband/hw/nes/nes.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/infiniband/hw/nes/nes.c	2011-07-11 19:51:52.000000000 -0400
@@ -1138,7 +1138,9 @@
 	u32 i = 0;
 	struct nes_device *nesdev;
 
-	strict_strtoul(buf, 0, &wqm_quanta_value);
+	if (kstrtoul(buf, 0, &wqm_quanta_value) < 0)
+		return -EINVAL;
+
 	list_for_each_entry(nesdev, &nes_dev_list, list) {
 		if (i == ee_flsh_adapter) {
 			nesdev->nesadapter->wqm_quanta = wqm_quanta_value;
diff -druN linux-2.6.39-libre/drivers/infiniband/hw/nes/nes_cm.c linux-3.0-rc7-libre/drivers/infiniband/hw/nes/nes_cm.c
--- linux-2.6.39-libre/drivers/infiniband/hw/nes/nes_cm.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/infiniband/hw/nes/nes_cm.c	2011-07-11 19:51:52.000000000 -0400
@@ -2563,7 +2563,7 @@
 	u16 last_ae;
 	u8 original_hw_tcp_state;
 	u8 original_ibqp_state;
-	enum iw_cm_event_status disconn_status = IW_CM_EVENT_STATUS_OK;
+	int disconn_status = 0;
 	int issue_disconn = 0;
 	int issue_close = 0;
 	int issue_flush = 0;
@@ -2605,7 +2605,7 @@
 			(last_ae == NES_AEQE_AEID_LLP_CONNECTION_RESET))) {
 		issue_disconn = 1;
 		if (last_ae == NES_AEQE_AEID_LLP_CONNECTION_RESET)
-			disconn_status = IW_CM_EVENT_STATUS_RESET;
+			disconn_status = -ECONNRESET;
 	}
 
 	if (((original_hw_tcp_state == NES_AEQE_TCP_STATE_CLOSED) ||
@@ -2666,7 +2666,7 @@
 			cm_id->provider_data = nesqp;
 			/* Send up the close complete event */
 			cm_event.event = IW_CM_EVENT_CLOSE;
-			cm_event.status = IW_CM_EVENT_STATUS_OK;
+			cm_event.status = 0;
 			cm_event.provider_data = cm_id->provider_data;
 			cm_event.local_addr = cm_id->local_addr;
 			cm_event.remote_addr = cm_id->remote_addr;
@@ -2966,7 +2966,7 @@
 	nes_add_ref(&nesqp->ibqp);
 
 	cm_event.event = IW_CM_EVENT_ESTABLISHED;
-	cm_event.status = IW_CM_EVENT_STATUS_ACCEPTED;
+	cm_event.status = 0;
 	cm_event.provider_data = (void *)nesqp;
 	cm_event.local_addr = cm_id->local_addr;
 	cm_event.remote_addr = cm_id->remote_addr;
@@ -3377,7 +3377,7 @@
 
 	/* notify OF layer we successfully created the requested connection */
 	cm_event.event = IW_CM_EVENT_CONNECT_REPLY;
-	cm_event.status = IW_CM_EVENT_STATUS_ACCEPTED;
+	cm_event.status = 0;
 	cm_event.provider_data = cm_id->provider_data;
 	cm_event.local_addr.sin_family = AF_INET;
 	cm_event.local_addr.sin_port = cm_id->local_addr.sin_port;
@@ -3484,7 +3484,7 @@
 	nesqp->cm_id = NULL;
 	/* cm_id->provider_data = NULL; */
 	cm_event.event = IW_CM_EVENT_DISCONNECT;
-	cm_event.status = IW_CM_EVENT_STATUS_RESET;
+	cm_event.status = -ECONNRESET;
 	cm_event.provider_data = cm_id->provider_data;
 	cm_event.local_addr = cm_id->local_addr;
 	cm_event.remote_addr = cm_id->remote_addr;
@@ -3495,7 +3495,7 @@
 	ret = cm_id->event_handler(cm_id, &cm_event);
 	atomic_inc(&cm_closes);
 	cm_event.event = IW_CM_EVENT_CLOSE;
-	cm_event.status = IW_CM_EVENT_STATUS_OK;
+	cm_event.status = 0;
 	cm_event.provider_data = cm_id->provider_data;
 	cm_event.local_addr = cm_id->local_addr;
 	cm_event.remote_addr = cm_id->remote_addr;
@@ -3534,7 +3534,7 @@
 			cm_node, cm_id, jiffies);
 
 	cm_event.event = IW_CM_EVENT_CONNECT_REQUEST;
-	cm_event.status = IW_CM_EVENT_STATUS_OK;
+	cm_event.status = 0;
 	cm_event.provider_data = (void *)cm_node;
 
 	cm_event.local_addr.sin_family = AF_INET;
diff -druN linux-2.6.39-libre/drivers/infiniband/hw/nes/nes_hw.c linux-3.0-rc7-libre/drivers/infiniband/hw/nes/nes_hw.c
--- linux-2.6.39-libre/drivers/infiniband/hw/nes/nes_hw.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/infiniband/hw/nes/nes_hw.c	2011-07-11 19:51:52.000000000 -0400
@@ -2885,9 +2885,8 @@
 					if ((cqe_errv &
 							(NES_NIC_ERRV_BITS_IPV4_CSUM_ERR | NES_NIC_ERRV_BITS_TCPUDP_CSUM_ERR |
 							NES_NIC_ERRV_BITS_IPH_ERR | NES_NIC_ERRV_BITS_WQE_OVERRUN)) == 0) {
-						if (nesvnic->rx_checksum_disabled == 0) {
+						if (nesvnic->netdev->features & NETIF_F_RXCSUM)
 							rx_skb->ip_summed = CHECKSUM_UNNECESSARY;
-						}
 					} else
 						nes_debug(NES_DBG_CQ, "%s: unsuccessfully checksummed TCP or UDP packet."
 								" errv = 0x%X, pkt_type = 0x%X.\n",
@@ -2897,7 +2896,7 @@
 					if ((cqe_errv &
 							(NES_NIC_ERRV_BITS_IPV4_CSUM_ERR | NES_NIC_ERRV_BITS_IPH_ERR |
 							NES_NIC_ERRV_BITS_WQE_OVERRUN)) == 0) {
-						if (nesvnic->rx_checksum_disabled == 0) {
+						if (nesvnic->netdev->features & NETIF_F_RXCSUM) {
 							rx_skb->ip_summed = CHECKSUM_UNNECESSARY;
 							/* nes_debug(NES_DBG_CQ, "%s: Reporting successfully checksummed IPv4 packet.\n",
 								  nesvnic->netdev->name); */
diff -druN linux-2.6.39-libre/drivers/infiniband/hw/nes/nes_hw.h linux-3.0-rc7-libre/drivers/infiniband/hw/nes/nes_hw.h
--- linux-2.6.39-libre/drivers/infiniband/hw/nes/nes_hw.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/infiniband/hw/nes/nes_hw.h	2011-07-11 19:51:52.000000000 -0400
@@ -1245,7 +1245,6 @@
 	u8  next_qp_nic_index;
 	u8  of_device_registered;
 	u8  rdma_enabled;
-	u8  rx_checksum_disabled;
 	u32 lro_max_aggr;
 	struct net_lro_mgr lro_mgr;
 	struct net_lro_desc lro_desc[NES_MAX_LRO_DESCRIPTORS];
diff -druN linux-2.6.39-libre/drivers/infiniband/hw/nes/nes_nic.c linux-3.0-rc7-libre/drivers/infiniband/hw/nes/nes_nic.c
--- linux-2.6.39-libre/drivers/infiniband/hw/nes/nes_nic.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/infiniband/hw/nes/nes_nic.c	2011-07-11 19:51:52.000000000 -0400
@@ -1093,34 +1093,6 @@
 };
 #define NES_ETHTOOL_STAT_COUNT  ARRAY_SIZE(nes_ethtool_stringset)
 
-/**
- * nes_netdev_get_rx_csum
- */
-static u32 nes_netdev_get_rx_csum (struct net_device *netdev)
-{
-	struct nes_vnic *nesvnic = netdev_priv(netdev);
-
-	if (nesvnic->rx_checksum_disabled)
-		return 0;
-	else
-		return 1;
-}
-
-
-/**
- * nes_netdev_set_rc_csum
- */
-static int nes_netdev_set_rx_csum(struct net_device *netdev, u32 enable)
-{
-	struct nes_vnic *nesvnic = netdev_priv(netdev);
-
-	if (enable)
-		nesvnic->rx_checksum_disabled = 0;
-	else
-		nesvnic->rx_checksum_disabled = 1;
-	return 0;
-}
-
 
 /**
  * nes_netdev_get_sset_count
@@ -1521,7 +1493,7 @@
 	et_cmd->maxrxpkt = 511;
 
 	if (nesadapter->OneG_Mode) {
-		et_cmd->speed = SPEED_1000;
+		ethtool_cmd_speed_set(et_cmd, SPEED_1000);
 		if (phy_type == NES_PHY_TYPE_PUMA_1G) {
 			et_cmd->supported   = SUPPORTED_1000baseT_Full;
 			et_cmd->advertising = ADVERTISED_1000baseT_Full;
@@ -1560,7 +1532,7 @@
 		et_cmd->advertising = ADVERTISED_10000baseT_Full;
 		et_cmd->phy_address = mac_index;
 	}
-	et_cmd->speed = SPEED_10000;
+	ethtool_cmd_speed_set(et_cmd, SPEED_10000);
 	et_cmd->autoneg = AUTONEG_DISABLE;
 	return 0;
 }
@@ -1598,19 +1570,10 @@
 }
 
 
-static int nes_netdev_set_flags(struct net_device *netdev, u32 flags)
-{
-	return ethtool_op_set_flags(netdev, flags, ETH_FLAG_LRO);
-}
-
-
 static const struct ethtool_ops nes_ethtool_ops = {
 	.get_link = ethtool_op_get_link,
 	.get_settings = nes_netdev_get_settings,
 	.set_settings = nes_netdev_set_settings,
-	.get_tx_csum = ethtool_op_get_tx_csum,
-	.get_rx_csum = nes_netdev_get_rx_csum,
-	.get_sg = ethtool_op_get_sg,
 	.get_strings = nes_netdev_get_strings,
 	.get_sset_count = nes_netdev_get_sset_count,
 	.get_ethtool_stats = nes_netdev_get_ethtool_stats,
@@ -1619,13 +1582,6 @@
 	.set_coalesce = nes_netdev_set_coalesce,
 	.get_pauseparam = nes_netdev_get_pauseparam,
 	.set_pauseparam = nes_netdev_set_pauseparam,
-	.set_tx_csum = ethtool_op_set_tx_csum,
-	.set_rx_csum = nes_netdev_set_rx_csum,
-	.set_sg = ethtool_op_set_sg,
-	.get_tso = ethtool_op_get_tso,
-	.set_tso = ethtool_op_set_tso,
-	.get_flags = ethtool_op_get_flags,
-	.set_flags = nes_netdev_set_flags,
 };
 
 
@@ -1727,12 +1683,11 @@
 	netdev->dev_addr[5] = (u8)u64temp;
 	memcpy(netdev->perm_addr, netdev->dev_addr, 6);
 
-	if ((nesvnic->logical_port < 2) || (nesdev->nesadapter->hw_rev != NE020_REV)) {
-		netdev->features |= NETIF_F_TSO | NETIF_F_SG | NETIF_F_IP_CSUM;
-		netdev->features |= NETIF_F_GSO | NETIF_F_TSO | NETIF_F_SG | NETIF_F_IP_CSUM;
-	} else {
-		netdev->features |= NETIF_F_SG | NETIF_F_IP_CSUM;
-	}
+	netdev->hw_features = NETIF_F_RXCSUM | NETIF_F_SG | NETIF_F_IP_CSUM;
+	if ((nesvnic->logical_port < 2) || (nesdev->nesadapter->hw_rev != NE020_REV))
+		netdev->hw_features |= NETIF_F_TSO;
+	netdev->features |= netdev->hw_features;
+	netdev->hw_features |= NETIF_F_LRO;
 
 	nes_debug(NES_DBG_INIT, "nesvnic = %p, reported features = 0x%lX, QPid = %d,"
 			" nic_index = %d, logical_port = %d, mac_index = %d.\n",
diff -druN linux-2.6.39-libre/drivers/infiniband/hw/nes/nes_verbs.c linux-3.0-rc7-libre/drivers/infiniband/hw/nes/nes_verbs.c
--- linux-2.6.39-libre/drivers/infiniband/hw/nes/nes_verbs.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/infiniband/hw/nes/nes_verbs.c	2011-07-11 19:51:52.000000000 -0400
@@ -1484,7 +1484,7 @@
 			(nesqp->ibqp_state == IB_QPS_RTR)) && (nesqp->cm_id)) {
 		cm_id = nesqp->cm_id;
 		cm_event.event = IW_CM_EVENT_CONNECT_REPLY;
-		cm_event.status = IW_CM_EVENT_STATUS_TIMEOUT;
+		cm_event.status = -ETIMEDOUT;
 		cm_event.local_addr = cm_id->local_addr;
 		cm_event.remote_addr = cm_id->remote_addr;
 		cm_event.private_data = NULL;
diff -druN linux-2.6.39-libre/drivers/infiniband/hw/qib/Kconfig linux-3.0-rc7-libre/drivers/infiniband/hw/qib/Kconfig
--- linux-2.6.39-libre/drivers/infiniband/hw/qib/Kconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/infiniband/hw/qib/Kconfig	2011-07-11 19:51:52.000000000 -0400
@@ -1,6 +1,6 @@
 config INFINIBAND_QIB
 	tristate "QLogic PCIe HCA support"
-	depends on 64BIT && NET
+	depends on 64BIT
 	---help---
 	This is a low-level driver for QLogic PCIe QLE InfiniBand host
 	channel adapters.  This driver does not support the QLogic
diff -druN linux-2.6.39-libre/drivers/infiniband/hw/qib/qib_iba7322.c linux-3.0-rc7-libre/drivers/infiniband/hw/qib/qib_iba7322.c
--- linux-2.6.39-libre/drivers/infiniband/hw/qib/qib_iba7322.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/infiniband/hw/qib/qib_iba7322.c	2011-07-11 19:51:52.000000000 -0400
@@ -469,6 +469,8 @@
 #define IB_7322_LT_STATE_RECOVERIDLE     0x0f
 #define IB_7322_LT_STATE_CFGENH          0x10
 #define IB_7322_LT_STATE_CFGTEST         0x11
+#define IB_7322_LT_STATE_CFGWAITRMTTEST  0x12
+#define IB_7322_LT_STATE_CFGWAITENH      0x13
 
 /* link state machine states from IBC */
 #define IB_7322_L_STATE_DOWN             0x0
@@ -498,8 +500,10 @@
 		IB_PHYSPORTSTATE_LINK_ERR_RECOVER,
 	[IB_7322_LT_STATE_CFGENH] = IB_PHYSPORTSTATE_CFG_ENH,
 	[IB_7322_LT_STATE_CFGTEST] = IB_PHYSPORTSTATE_CFG_TRAIN,
-	[0x12] = IB_PHYSPORTSTATE_CFG_TRAIN,
-	[0x13] = IB_PHYSPORTSTATE_CFG_WAIT_ENH,
+	[IB_7322_LT_STATE_CFGWAITRMTTEST] =
+		IB_PHYSPORTSTATE_CFG_TRAIN,
+	[IB_7322_LT_STATE_CFGWAITENH] =
+		IB_PHYSPORTSTATE_CFG_WAIT_ENH,
 	[0x14] = IB_PHYSPORTSTATE_CFG_TRAIN,
 	[0x15] = IB_PHYSPORTSTATE_CFG_TRAIN,
 	[0x16] = IB_PHYSPORTSTATE_CFG_TRAIN,
@@ -1692,7 +1696,9 @@
 		break;
 	}
 
-	if (ibclt == IB_7322_LT_STATE_CFGTEST &&
+	if (((ibclt >= IB_7322_LT_STATE_CFGTEST &&
+	      ibclt <= IB_7322_LT_STATE_CFGWAITENH) ||
+	     ibclt == IB_7322_LT_STATE_LINKUP) &&
 	    (ibcst & SYM_MASK(IBCStatusA_0, LinkSpeedQDR))) {
 		force_h1(ppd);
 		ppd->cpspec->qdr_reforce = 1;
@@ -7301,12 +7307,17 @@
 static void serdes_7322_los_enable(struct qib_pportdata *ppd, int enable)
 {
 	u64 data = qib_read_kreg_port(ppd, krp_serdesctrl);
-	printk(KERN_INFO QIB_DRV_NAME " IB%u:%u Turning LOS %s\n",
-		ppd->dd->unit, ppd->port, (enable ? "on" : "off"));
-	if (enable)
+	u8 state = SYM_FIELD(data, IBSerdesCtrl_0, RXLOSEN);
+
+	if (enable && !state) {
+		printk(KERN_INFO QIB_DRV_NAME " IB%u:%u Turning LOS on\n",
+			ppd->dd->unit, ppd->port);
 		data |= SYM_MASK(IBSerdesCtrl_0, RXLOSEN);
-	else
+	} else if (!enable && state) {
+		printk(KERN_INFO QIB_DRV_NAME " IB%u:%u Turning LOS off\n",
+			ppd->dd->unit, ppd->port);
 		data &= ~SYM_MASK(IBSerdesCtrl_0, RXLOSEN);
+	}
 	qib_write_kreg_port(ppd, krp_serdesctrl, data);
 }
 
@@ -7534,7 +7545,8 @@
 	ibsd_wr_allchans(ppd, 4, (1 << 10), BMASK(10, 10));
 	tstart = get_jiffies_64();
 	while (chan_done &&
-	       !time_after64(tstart, tstart + msecs_to_jiffies(500))) {
+	       !time_after64(get_jiffies_64(),
+			tstart + msecs_to_jiffies(500))) {
 		msleep(20);
 		for (chan = 0; chan < SERDES_CHANS; ++chan) {
 			rxcaldone = ahb_mod(ppd->dd, IBSD(ppd->hw_pidx),
diff -druN linux-2.6.39-libre/drivers/infiniband/hw/qib/qib_intr.c linux-3.0-rc7-libre/drivers/infiniband/hw/qib/qib_intr.c
--- linux-2.6.39-libre/drivers/infiniband/hw/qib/qib_intr.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/infiniband/hw/qib/qib_intr.c	2011-07-11 19:51:52.000000000 -0400
@@ -96,8 +96,12 @@
 	 * states, or if it transitions from any of the up (INIT or better)
 	 * states into any of the down states (except link recovery), then
 	 * call the chip-specific code to take appropriate actions.
+	 *
+	 * ppd->lflags could be 0 if this is the first time the interrupt
+	 * handlers has been called but the link is already up.
 	 */
-	if (lstate >= IB_PORT_INIT && (ppd->lflags & QIBL_LINKDOWN) &&
+	if (lstate >= IB_PORT_INIT &&
+	    (!ppd->lflags || (ppd->lflags & QIBL_LINKDOWN)) &&
 	    ltstate == IB_PHYSPORTSTATE_LINKUP) {
 		/* transitioned to UP */
 		if (dd->f_ib_updown(ppd, 1, ibcs))
diff -druN linux-2.6.39-libre/drivers/infiniband/hw/qib/qib_pcie.c linux-3.0-rc7-libre/drivers/infiniband/hw/qib/qib_pcie.c
--- linux-2.6.39-libre/drivers/infiniband/hw/qib/qib_pcie.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/infiniband/hw/qib/qib_pcie.c	2011-07-11 19:51:52.000000000 -0400
@@ -526,11 +526,8 @@
 	 */
 	devid = parent->device;
 	if (devid >= 0x25e2 && devid <= 0x25fa) {
-		u8 rev;
-
 		/* 5000 P/V/X/Z */
-		pci_read_config_byte(parent, PCI_REVISION_ID, &rev);
-		if (rev <= 0xb2)
+		if (parent->revision <= 0xb2)
 			bits = 1U << 10;
 		else
 			bits = 7U << 10;
diff -druN linux-2.6.39-libre/drivers/infiniband/Kconfig linux-3.0-rc7-libre/drivers/infiniband/Kconfig
--- linux-2.6.39-libre/drivers/infiniband/Kconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/infiniband/Kconfig	2011-07-11 19:51:52.000000000 -0400
@@ -2,6 +2,7 @@
 	tristate "InfiniBand support"
 	depends on PCI || BROKEN
 	depends on HAS_IOMEM
+	depends on NET
 	---help---
 	  Core support for InfiniBand (IB).  Make sure to also select
 	  any protocols you wish to use as well as drivers for your
diff -druN linux-2.6.39-libre/drivers/infiniband/ulp/ipoib/ipoib_cm.c linux-3.0-rc7-libre/drivers/infiniband/ulp/ipoib/ipoib_cm.c
--- linux-2.6.39-libre/drivers/infiniband/ulp/ipoib/ipoib_cm.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/infiniband/ulp/ipoib/ipoib_cm.c	2011-07-11 19:51:52.000000000 -0400
@@ -1463,8 +1463,7 @@
 		set_bit(IPOIB_FLAG_ADMIN_CM, &priv->flags);
 		ipoib_warn(priv, "enabling connected mode "
 			   "will cause multicast packet drops\n");
-
-		dev->features &= ~(NETIF_F_IP_CSUM | NETIF_F_SG | NETIF_F_TSO);
+		netdev_update_features(dev);
 		rtnl_unlock();
 		priv->tx_wr.send_flags &= ~IB_SEND_IP_CSUM;
 
@@ -1474,13 +1473,7 @@
 
 	if (!strcmp(buf, "datagram\n")) {
 		clear_bit(IPOIB_FLAG_ADMIN_CM, &priv->flags);
-
-		if (test_bit(IPOIB_FLAG_CSUM, &priv->flags)) {
-			dev->features |= NETIF_F_IP_CSUM | NETIF_F_SG;
-			priv->dev->features |= NETIF_F_GRO;
-			if (priv->hca_caps & IB_DEVICE_UD_TSO)
-				dev->features |= NETIF_F_TSO;
-		}
+		netdev_update_features(dev);
 		dev_set_mtu(dev, min(priv->mcast_mtu, dev->mtu));
 		rtnl_unlock();
 		ipoib_flush_paths(dev);
diff -druN linux-2.6.39-libre/drivers/infiniband/ulp/ipoib/ipoib_ethtool.c linux-3.0-rc7-libre/drivers/infiniband/ulp/ipoib/ipoib_ethtool.c
--- linux-2.6.39-libre/drivers/infiniband/ulp/ipoib/ipoib_ethtool.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/infiniband/ulp/ipoib/ipoib_ethtool.c	2011-07-11 19:51:52.000000000 -0400
@@ -42,32 +42,6 @@
 	strncpy(drvinfo->driver, "ipoib", sizeof(drvinfo->driver) - 1);
 }
 
-static u32 ipoib_get_rx_csum(struct net_device *dev)
-{
-	struct ipoib_dev_priv *priv = netdev_priv(dev);
-	return test_bit(IPOIB_FLAG_CSUM, &priv->flags) &&
-		!test_bit(IPOIB_FLAG_ADMIN_CM, &priv->flags);
-}
-
-static int ipoib_set_tso(struct net_device *dev, u32 data)
-{
-	struct ipoib_dev_priv *priv = netdev_priv(dev);
-
-	if (data) {
-		if (!test_bit(IPOIB_FLAG_ADMIN_CM, &priv->flags) &&
-		    (dev->features & NETIF_F_SG) &&
-		    (priv->hca_caps & IB_DEVICE_UD_TSO)) {
-			dev->features |= NETIF_F_TSO;
-		} else {
-			ipoib_warn(priv, "can't set TSO on\n");
-			return -EOPNOTSUPP;
-		}
-	} else
-		dev->features &= ~NETIF_F_TSO;
-
-	return 0;
-}
-
 static int ipoib_get_coalesce(struct net_device *dev,
 			      struct ethtool_coalesce *coal)
 {
@@ -108,8 +82,6 @@
 
 static const struct ethtool_ops ipoib_ethtool_ops = {
 	.get_drvinfo		= ipoib_get_drvinfo,
-	.get_rx_csum		= ipoib_get_rx_csum,
-	.set_tso		= ipoib_set_tso,
 	.get_coalesce		= ipoib_get_coalesce,
 	.set_coalesce		= ipoib_set_coalesce,
 };
diff -druN linux-2.6.39-libre/drivers/infiniband/ulp/ipoib/ipoib.h linux-3.0-rc7-libre/drivers/infiniband/ulp/ipoib/ipoib.h
--- linux-2.6.39-libre/drivers/infiniband/ulp/ipoib/ipoib.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/infiniband/ulp/ipoib/ipoib.h	2011-07-11 19:51:52.000000000 -0400
@@ -91,7 +91,6 @@
 	IPOIB_STOP_REAPER	  = 7,
 	IPOIB_FLAG_ADMIN_CM	  = 9,
 	IPOIB_FLAG_UMCAST	  = 10,
-	IPOIB_FLAG_CSUM		  = 11,
 
 	IPOIB_MAX_BACKOFF_SECONDS = 16,
 
diff -druN linux-2.6.39-libre/drivers/infiniband/ulp/ipoib/ipoib_ib.c linux-3.0-rc7-libre/drivers/infiniband/ulp/ipoib/ipoib_ib.c
--- linux-2.6.39-libre/drivers/infiniband/ulp/ipoib/ipoib_ib.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/infiniband/ulp/ipoib/ipoib_ib.c	2011-07-11 19:51:52.000000000 -0400
@@ -292,7 +292,7 @@
 	dev->stats.rx_bytes += skb->len;
 
 	skb->dev = dev;
-	if (test_bit(IPOIB_FLAG_CSUM, &priv->flags) && likely(wc->csum_ok))
+	if ((dev->features & NETIF_F_RXCSUM) && likely(wc->csum_ok))
 		skb->ip_summed = CHECKSUM_UNNECESSARY;
 
 	napi_gro_receive(&priv->napi, skb);
diff -druN linux-2.6.39-libre/drivers/infiniband/ulp/ipoib/ipoib_main.c linux-3.0-rc7-libre/drivers/infiniband/ulp/ipoib/ipoib_main.c
--- linux-2.6.39-libre/drivers/infiniband/ulp/ipoib/ipoib_main.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/infiniband/ulp/ipoib/ipoib_main.c	2011-07-11 19:51:52.000000000 -0400
@@ -171,6 +171,16 @@
 	return 0;
 }
 
+static u32 ipoib_fix_features(struct net_device *dev, u32 features)
+{
+	struct ipoib_dev_priv *priv = netdev_priv(dev);
+
+	if (test_bit(IPOIB_FLAG_ADMIN_CM, &priv->flags))
+		features &= ~(NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO);
+
+	return features;
+}
+
 static int ipoib_change_mtu(struct net_device *dev, int new_mtu)
 {
 	struct ipoib_dev_priv *priv = netdev_priv(dev);
@@ -970,6 +980,7 @@
 	.ndo_open		 = ipoib_open,
 	.ndo_stop		 = ipoib_stop,
 	.ndo_change_mtu		 = ipoib_change_mtu,
+	.ndo_fix_features	 = ipoib_fix_features,
 	.ndo_start_xmit	 	 = ipoib_start_xmit,
 	.ndo_tx_timeout		 = ipoib_timeout,
 	.ndo_set_multicast_list	 = ipoib_set_mcast_list,
@@ -1154,19 +1165,18 @@
 	kfree(device_attr);
 
 	if (priv->hca_caps & IB_DEVICE_UD_IP_CSUM) {
-		set_bit(IPOIB_FLAG_CSUM, &priv->flags);
-		priv->dev->features |= NETIF_F_SG | NETIF_F_IP_CSUM;
-	}
+		priv->dev->hw_features = NETIF_F_SG |
+			NETIF_F_IP_CSUM | NETIF_F_RXCSUM;
 
-	priv->dev->features |= NETIF_F_GRO;
+		if (priv->hca_caps & IB_DEVICE_UD_TSO)
+			priv->dev->hw_features |= NETIF_F_TSO;
 
-	if (priv->dev->features & NETIF_F_SG && priv->hca_caps & IB_DEVICE_UD_TSO)
-		priv->dev->features |= NETIF_F_TSO;
+		priv->dev->features |= priv->dev->hw_features;
+	}
 
 	return 0;
 }
 
-
 static struct net_device *ipoib_add_port(const char *format,
 					 struct ib_device *hca, u8 port)
 {
diff -druN linux-2.6.39-libre/drivers/infiniband/ulp/iser/iser_verbs.c linux-3.0-rc7-libre/drivers/infiniband/ulp/iser/iser_verbs.c
--- linux-2.6.39-libre/drivers/infiniband/ulp/iser/iser_verbs.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/infiniband/ulp/iser/iser_verbs.c	2011-07-11 19:51:52.000000000 -0400
@@ -548,7 +548,7 @@
 	iser_conn_get(ib_conn); /* ref ib conn's cma id */
 	ib_conn->cma_id = rdma_create_id(iser_cma_handler,
 					     (void *)ib_conn,
-					     RDMA_PS_TCP);
+					     RDMA_PS_TCP, IB_QPT_RC);
 	if (IS_ERR(ib_conn->cma_id)) {
 		err = PTR_ERR(ib_conn->cma_id);
 		iser_err("rdma_create_id failed: %d\n", err);
diff -druN linux-2.6.39-libre/drivers/infiniband/ulp/srp/ib_srp.c linux-3.0-rc7-libre/drivers/infiniband/ulp/srp/ib_srp.c
--- linux-2.6.39-libre/drivers/infiniband/ulp/srp/ib_srp.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/infiniband/ulp/srp/ib_srp.c	2011-07-11 19:51:52.000000000 -0400
@@ -1147,7 +1147,7 @@
 static void srp_handle_recv(struct srp_target_port *target, struct ib_wc *wc)
 {
 	struct ib_device *dev = target->srp_host->srp_dev->dev;
-	struct srp_iu *iu = (struct srp_iu *) wc->wr_id;
+	struct srp_iu *iu = (struct srp_iu *) (uintptr_t) wc->wr_id;
 	int res;
 	u8 opcode;
 
@@ -1231,7 +1231,7 @@
 			break;
 		}
 
-		iu = (struct srp_iu *) wc.wr_id;
+		iu = (struct srp_iu *) (uintptr_t) wc.wr_id;
 		list_add(&iu->list, &target->free_tx);
 	}
 }
diff -druN linux-2.6.39-libre/drivers/input/evdev.c linux-3.0-rc7-libre/drivers/input/evdev.c
--- linux-2.6.39-libre/drivers/input/evdev.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/input/evdev.c	2011-07-11 19:51:52.000000000 -0400
@@ -41,6 +41,7 @@
 struct evdev_client {
 	unsigned int head;
 	unsigned int tail;
+	unsigned int packet_head; /* [future] position of the first element of next packet */
 	spinlock_t buffer_lock; /* protects access to buffer, head and tail */
 	struct fasync_struct *fasync;
 	struct evdev *evdev;
@@ -72,12 +73,16 @@
 		client->buffer[client->tail].type = EV_SYN;
 		client->buffer[client->tail].code = SYN_DROPPED;
 		client->buffer[client->tail].value = 0;
-	}
 
-	spin_unlock(&client->buffer_lock);
+		client->packet_head = client->tail;
+	}
 
-	if (event->type == EV_SYN)
+	if (event->type == EV_SYN && event->code == SYN_REPORT) {
+		client->packet_head = client->head;
 		kill_fasync(&client->fasync, SIGIO, POLL_IN);
+	}
+
+	spin_unlock(&client->buffer_lock);
 }
 
 /*
@@ -106,7 +111,8 @@
 
 	rcu_read_unlock();
 
-	wake_up_interruptible(&evdev->wait);
+	if (type == EV_SYN && code == SYN_REPORT)
+		wake_up_interruptible(&evdev->wait);
 }
 
 static int evdev_fasync(int fd, struct file *file, int on)
@@ -159,7 +165,6 @@
 		return error;
 
 	rcu_assign_pointer(evdev->grab, client);
-	synchronize_rcu();
 
 	return 0;
 }
@@ -182,7 +187,6 @@
 	spin_lock(&evdev->client_lock);
 	list_add_tail_rcu(&client->node, &evdev->client_list);
 	spin_unlock(&evdev->client_lock);
-	synchronize_rcu();
 }
 
 static void evdev_detach_client(struct evdev *evdev,
@@ -387,12 +391,12 @@
 	if (count < input_event_size())
 		return -EINVAL;
 
-	if (client->head == client->tail && evdev->exist &&
+	if (client->packet_head == client->tail && evdev->exist &&
 	    (file->f_flags & O_NONBLOCK))
 		return -EAGAIN;
 
 	retval = wait_event_interruptible(evdev->wait,
-		client->head != client->tail || !evdev->exist);
+		client->packet_head != client->tail || !evdev->exist);
 	if (retval)
 		return retval;
 
@@ -421,7 +425,7 @@
 	poll_wait(file, &evdev->wait, wait);
 
 	mask = evdev->exist ? POLLOUT | POLLWRNORM : POLLHUP | POLLERR;
-	if (client->head != client->tail)
+	if (client->packet_head != client->tail)
 		mask |= POLLIN | POLLRDNORM;
 
 	return mask;
diff -druN linux-2.6.39-libre/drivers/input/input.c linux-3.0-rc7-libre/drivers/input/input.c
--- linux-2.6.39-libre/drivers/input/input.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/input/input.c	2011-07-11 19:51:52.000000000 -0400
@@ -451,7 +451,6 @@
 	}
 
 	rcu_assign_pointer(dev->grab, handle);
-	synchronize_rcu();
 
  out:
 	mutex_unlock(&dev->mutex);
@@ -1757,7 +1756,7 @@
 	} else if (test_bit(ABS_MT_TRACKING_ID, dev->absbit)) {
 		mt_slots = dev->absinfo[ABS_MT_TRACKING_ID].maximum -
 			   dev->absinfo[ABS_MT_TRACKING_ID].minimum + 1,
-		clamp(mt_slots, 2, 32);
+		mt_slots = clamp(mt_slots, 2, 32);
 	} else if (test_bit(ABS_MT_POSITION_X, dev->absbit)) {
 		mt_slots = 2;
 	} else {
diff -druN linux-2.6.39-libre/drivers/input/input-compat.h linux-3.0-rc7-libre/drivers/input/input-compat.h
--- linux-2.6.39-libre/drivers/input/input-compat.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/input/input-compat.h	2011-07-11 19:51:52.000000000 -0400
@@ -19,7 +19,7 @@
 
 /* Note to the author of this code: did it ever occur to
    you why the ifdefs are needed? Think about it again. -AK */
-#ifdef CONFIG_X86_64
+#if defined(CONFIG_X86_64) || defined(CONFIG_TILE)
 #  define INPUT_COMPAT_TEST is_compat_task()
 #elif defined(CONFIG_S390)
 #  define INPUT_COMPAT_TEST test_thread_flag(TIF_31BIT)
diff -druN linux-2.6.39-libre/drivers/input/input-polldev.c linux-3.0-rc7-libre/drivers/input/input-polldev.c
--- linux-2.6.39-libre/drivers/input/input-polldev.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/input/input-polldev.c	2011-07-11 19:51:52.000000000 -0400
@@ -13,6 +13,7 @@
 #include <linux/jiffies.h>
 #include <linux/slab.h>
 #include <linux/mutex.h>
+#include <linux/workqueue.h>
 #include <linux/input-polldev.h>
 
 MODULE_AUTHOR("Dmitry Torokhov <dtor@mail.ru>");
@@ -20,44 +21,6 @@
 MODULE_LICENSE("GPL v2");
 MODULE_VERSION("0.1");
 
-static DEFINE_MUTEX(polldev_mutex);
-static int polldev_users;
-static struct workqueue_struct *polldev_wq;
-
-static int input_polldev_start_workqueue(void)
-{
-	int retval;
-
-	retval = mutex_lock_interruptible(&polldev_mutex);
-	if (retval)
-		return retval;
-
-	if (!polldev_users) {
-		polldev_wq = create_singlethread_workqueue("ipolldevd");
-		if (!polldev_wq) {
-			pr_err("failed to create ipolldevd workqueue\n");
-			retval = -ENOMEM;
-			goto out;
-		}
-	}
-
-	polldev_users++;
-
- out:
-	mutex_unlock(&polldev_mutex);
-	return retval;
-}
-
-static void input_polldev_stop_workqueue(void)
-{
-	mutex_lock(&polldev_mutex);
-
-	if (!--polldev_users)
-		destroy_workqueue(polldev_wq);
-
-	mutex_unlock(&polldev_mutex);
-}
-
 static void input_polldev_queue_work(struct input_polled_dev *dev)
 {
 	unsigned long delay;
@@ -66,7 +29,7 @@
 	if (delay >= HZ)
 		delay = round_jiffies_relative(delay);
 
-	queue_delayed_work(polldev_wq, &dev->work, delay);
+	queue_delayed_work(system_freezable_wq, &dev->work, delay);
 }
 
 static void input_polled_device_work(struct work_struct *work)
@@ -81,18 +44,13 @@
 static int input_open_polled_device(struct input_dev *input)
 {
 	struct input_polled_dev *dev = input_get_drvdata(input);
-	int error;
-
-	error = input_polldev_start_workqueue();
-	if (error)
-		return error;
 
 	if (dev->open)
 		dev->open(dev);
 
 	/* Only start polling if polling is enabled */
 	if (dev->poll_interval > 0)
-		queue_delayed_work(polldev_wq, &dev->work, 0);
+		queue_delayed_work(system_freezable_wq, &dev->work, 0);
 
 	return 0;
 }
@@ -102,13 +60,6 @@
 	struct input_polled_dev *dev = input_get_drvdata(input);
 
 	cancel_delayed_work_sync(&dev->work);
-	/*
-	 * Clean up work struct to remove references to the workqueue.
-	 * It may be destroyed by the next call. This causes problems
-	 * at next device open-close in case of poll_interval == 0.
-	 */
-	INIT_DELAYED_WORK(&dev->work, dev->work.work.func);
-	input_polldev_stop_workqueue();
 
 	if (dev->close)
 		dev->close(dev);
@@ -295,4 +246,3 @@
 	input_unregister_device(dev->input);
 }
 EXPORT_SYMBOL(input_unregister_polled_device);
-
diff -druN linux-2.6.39-libre/drivers/input/joydev.c linux-3.0-rc7-libre/drivers/input/joydev.c
--- linux-2.6.39-libre/drivers/input/joydev.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/input/joydev.c	2011-07-11 19:51:52.000000000 -0400
@@ -180,7 +180,6 @@
 	spin_lock(&joydev->client_lock);
 	list_add_tail_rcu(&client->node, &joydev->client_list);
 	spin_unlock(&joydev->client_lock);
-	synchronize_rcu();
 }
 
 static void joydev_detach_client(struct joydev *joydev,
diff -druN linux-2.6.39-libre/drivers/input/keyboard/adp5589-keys.c linux-3.0-rc7-libre/drivers/input/keyboard/adp5589-keys.c
--- linux-2.6.39-libre/drivers/input/keyboard/adp5589-keys.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/input/keyboard/adp5589-keys.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,771 @@
+/*
+ * Description:  keypad driver for ADP5589
+ *		 I2C QWERTY Keypad and IO Expander
+ * Bugs: Enter bugs at http://blackfin.uclinux.org/
+ *
+ * Copyright (C) 2010-2011 Analog Devices Inc.
+ * Licensed under the GPL-2.
+ */
+
+#include <linux/module.h>
+#include <linux/version.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/workqueue.h>
+#include <linux/errno.h>
+#include <linux/pm.h>
+#include <linux/platform_device.h>
+#include <linux/input.h>
+#include <linux/i2c.h>
+#include <linux/gpio.h>
+#include <linux/slab.h>
+
+#include <linux/input/adp5589.h>
+
+/* GENERAL_CFG Register */
+#define OSC_EN		(1 << 7)
+#define CORE_CLK(x)	(((x) & 0x3) << 5)
+#define LCK_TRK_LOGIC	(1 << 4)
+#define LCK_TRK_GPI	(1 << 3)
+#define INT_CFG		(1 << 1)
+#define RST_CFG		(1 << 0)
+
+/* INT_EN Register */
+#define LOGIC2_IEN	(1 << 5)
+#define LOGIC1_IEN	(1 << 4)
+#define LOCK_IEN	(1 << 3)
+#define OVRFLOW_IEN	(1 << 2)
+#define GPI_IEN		(1 << 1)
+#define EVENT_IEN	(1 << 0)
+
+/* Interrupt Status Register */
+#define LOGIC2_INT	(1 << 5)
+#define LOGIC1_INT	(1 << 4)
+#define LOCK_INT	(1 << 3)
+#define OVRFLOW_INT	(1 << 2)
+#define GPI_INT		(1 << 1)
+#define EVENT_INT	(1 << 0)
+
+/* STATUS Register */
+
+#define LOGIC2_STAT	(1 << 7)
+#define LOGIC1_STAT	(1 << 6)
+#define LOCK_STAT	(1 << 5)
+#define KEC		0xF
+
+/* PIN_CONFIG_D Register */
+#define C4_EXTEND_CFG	(1 << 6)	/* RESET2 */
+#define R4_EXTEND_CFG	(1 << 5)	/* RESET1 */
+
+/* LOCK_CFG */
+#define LOCK_EN		(1 << 0)
+
+#define PTIME_MASK	0x3
+#define LTIME_MASK	0x3
+
+/* Key Event Register xy */
+#define KEY_EV_PRESSED		(1 << 7)
+#define KEY_EV_MASK		(0x7F)
+
+#define KEYP_MAX_EVENT		16
+
+#define MAXGPIO			19
+#define ADP_BANK(offs)		((offs) >> 3)
+#define ADP_BIT(offs)		(1u << ((offs) & 0x7))
+
+struct adp5589_kpad {
+	struct i2c_client *client;
+	struct input_dev *input;
+	unsigned short keycode[ADP5589_KEYMAPSIZE];
+	const struct adp5589_gpi_map *gpimap;
+	unsigned short gpimapsize;
+	unsigned extend_cfg;
+#ifdef CONFIG_GPIOLIB
+	unsigned char gpiomap[MAXGPIO];
+	bool export_gpio;
+	struct gpio_chip gc;
+	struct mutex gpio_lock;	/* Protect cached dir, dat_out */
+	u8 dat_out[3];
+	u8 dir[3];
+#endif
+};
+
+static int adp5589_read(struct i2c_client *client, u8 reg)
+{
+	int ret = i2c_smbus_read_byte_data(client, reg);
+
+	if (ret < 0)
+		dev_err(&client->dev, "Read Error\n");
+
+	return ret;
+}
+
+static int adp5589_write(struct i2c_client *client, u8 reg, u8 val)
+{
+	return i2c_smbus_write_byte_data(client, reg, val);
+}
+
+#ifdef CONFIG_GPIOLIB
+static int adp5589_gpio_get_value(struct gpio_chip *chip, unsigned off)
+{
+	struct adp5589_kpad *kpad = container_of(chip, struct adp5589_kpad, gc);
+	unsigned int bank = ADP_BANK(kpad->gpiomap[off]);
+	unsigned int bit = ADP_BIT(kpad->gpiomap[off]);
+
+	return !!(adp5589_read(kpad->client, ADP5589_GPI_STATUS_A + bank) &
+		  bit);
+}
+
+static void adp5589_gpio_set_value(struct gpio_chip *chip,
+				   unsigned off, int val)
+{
+	struct adp5589_kpad *kpad = container_of(chip, struct adp5589_kpad, gc);
+	unsigned int bank = ADP_BANK(kpad->gpiomap[off]);
+	unsigned int bit = ADP_BIT(kpad->gpiomap[off]);
+
+	mutex_lock(&kpad->gpio_lock);
+
+	if (val)
+		kpad->dat_out[bank] |= bit;
+	else
+		kpad->dat_out[bank] &= ~bit;
+
+	adp5589_write(kpad->client, ADP5589_GPO_DATA_OUT_A + bank,
+		      kpad->dat_out[bank]);
+
+	mutex_unlock(&kpad->gpio_lock);
+}
+
+static int adp5589_gpio_direction_input(struct gpio_chip *chip, unsigned off)
+{
+	struct adp5589_kpad *kpad = container_of(chip, struct adp5589_kpad, gc);
+	unsigned int bank = ADP_BANK(kpad->gpiomap[off]);
+	unsigned int bit = ADP_BIT(kpad->gpiomap[off]);
+	int ret;
+
+	mutex_lock(&kpad->gpio_lock);
+
+	kpad->dir[bank] &= ~bit;
+	ret = adp5589_write(kpad->client, ADP5589_GPIO_DIRECTION_A + bank,
+			    kpad->dir[bank]);
+
+	mutex_unlock(&kpad->gpio_lock);
+
+	return ret;
+}
+
+static int adp5589_gpio_direction_output(struct gpio_chip *chip,
+					 unsigned off, int val)
+{
+	struct adp5589_kpad *kpad = container_of(chip, struct adp5589_kpad, gc);
+	unsigned int bank = ADP_BANK(kpad->gpiomap[off]);
+	unsigned int bit = ADP_BIT(kpad->gpiomap[off]);
+	int ret;
+
+	mutex_lock(&kpad->gpio_lock);
+
+	kpad->dir[bank] |= bit;
+
+	if (val)
+		kpad->dat_out[bank] |= bit;
+	else
+		kpad->dat_out[bank] &= ~bit;
+
+	ret = adp5589_write(kpad->client, ADP5589_GPO_DATA_OUT_A + bank,
+			    kpad->dat_out[bank]);
+	ret |= adp5589_write(kpad->client, ADP5589_GPIO_DIRECTION_A + bank,
+			     kpad->dir[bank]);
+
+	mutex_unlock(&kpad->gpio_lock);
+
+	return ret;
+}
+
+static int __devinit adp5589_build_gpiomap(struct adp5589_kpad *kpad,
+				const struct adp5589_kpad_platform_data *pdata)
+{
+	bool pin_used[MAXGPIO];
+	int n_unused = 0;
+	int i;
+
+	memset(pin_used, false, sizeof(pin_used));
+
+	for (i = 0; i < MAXGPIO; i++)
+		if (pdata->keypad_en_mask & (1 << i))
+			pin_used[i] = true;
+
+	for (i = 0; i < kpad->gpimapsize; i++)
+		pin_used[kpad->gpimap[i].pin - ADP5589_GPI_PIN_BASE] = true;
+
+	if (kpad->extend_cfg & R4_EXTEND_CFG)
+		pin_used[4] = true;
+
+	if (kpad->extend_cfg & C4_EXTEND_CFG)
+		pin_used[12] = true;
+
+	for (i = 0; i < MAXGPIO; i++)
+		if (!pin_used[i])
+			kpad->gpiomap[n_unused++] = i;
+
+	return n_unused;
+}
+
+static int __devinit adp5589_gpio_add(struct adp5589_kpad *kpad)
+{
+	struct device *dev = &kpad->client->dev;
+	const struct adp5589_kpad_platform_data *pdata = dev->platform_data;
+	const struct adp5589_gpio_platform_data *gpio_data = pdata->gpio_data;
+	int i, error;
+
+	if (!gpio_data)
+		return 0;
+
+	kpad->gc.ngpio = adp5589_build_gpiomap(kpad, pdata);
+	if (kpad->gc.ngpio == 0) {
+		dev_info(dev, "No unused gpios left to export\n");
+		return 0;
+	}
+
+	kpad->export_gpio = true;
+
+	kpad->gc.direction_input = adp5589_gpio_direction_input;
+	kpad->gc.direction_output = adp5589_gpio_direction_output;
+	kpad->gc.get = adp5589_gpio_get_value;
+	kpad->gc.set = adp5589_gpio_set_value;
+	kpad->gc.can_sleep = 1;
+
+	kpad->gc.base = gpio_data->gpio_start;
+	kpad->gc.label = kpad->client->name;
+	kpad->gc.owner = THIS_MODULE;
+
+	mutex_init(&kpad->gpio_lock);
+
+	error = gpiochip_add(&kpad->gc);
+	if (error) {
+		dev_err(dev, "gpiochip_add failed, err: %d\n", error);
+		return error;
+	}
+
+	for (i = 0; i <= ADP_BANK(MAXGPIO); i++) {
+		kpad->dat_out[i] = adp5589_read(kpad->client,
+						ADP5589_GPO_DATA_OUT_A + i);
+		kpad->dir[i] = adp5589_read(kpad->client,
+					    ADP5589_GPIO_DIRECTION_A + i);
+	}
+
+	if (gpio_data->setup) {
+		error = gpio_data->setup(kpad->client,
+					 kpad->gc.base, kpad->gc.ngpio,
+					 gpio_data->context);
+		if (error)
+			dev_warn(dev, "setup failed, %d\n", error);
+	}
+
+	return 0;
+}
+
+static void __devexit adp5589_gpio_remove(struct adp5589_kpad *kpad)
+{
+	struct device *dev = &kpad->client->dev;
+	const struct adp5589_kpad_platform_data *pdata = dev->platform_data;
+	const struct adp5589_gpio_platform_data *gpio_data = pdata->gpio_data;
+	int error;
+
+	if (!kpad->export_gpio)
+		return;
+
+	if (gpio_data->teardown) {
+		error = gpio_data->teardown(kpad->client,
+					    kpad->gc.base, kpad->gc.ngpio,
+					    gpio_data->context);
+		if (error)
+			dev_warn(dev, "teardown failed %d\n", error);
+	}
+
+	error = gpiochip_remove(&kpad->gc);
+	if (error)
+		dev_warn(dev, "gpiochip_remove failed %d\n", error);
+}
+#else
+static inline int adp5589_gpio_add(struct adp5589_kpad *kpad)
+{
+	return 0;
+}
+
+static inline void adp5589_gpio_remove(struct adp5589_kpad *kpad)
+{
+}
+#endif
+
+static void adp5589_report_switches(struct adp5589_kpad *kpad,
+				    int key, int key_val)
+{
+	int i;
+
+	for (i = 0; i < kpad->gpimapsize; i++) {
+		if (key_val == kpad->gpimap[i].pin) {
+			input_report_switch(kpad->input,
+					    kpad->gpimap[i].sw_evt,
+					    key & KEY_EV_PRESSED);
+			break;
+		}
+	}
+}
+
+static void adp5589_report_events(struct adp5589_kpad *kpad, int ev_cnt)
+{
+	int i;
+
+	for (i = 0; i < ev_cnt; i++) {
+		int key = adp5589_read(kpad->client, ADP5589_FIFO_1 + i);
+		int key_val = key & KEY_EV_MASK;
+
+		if (key_val >= ADP5589_GPI_PIN_BASE &&
+		    key_val <= ADP5589_GPI_PIN_END) {
+			adp5589_report_switches(kpad, key, key_val);
+		} else {
+			input_report_key(kpad->input,
+					 kpad->keycode[key_val - 1],
+					 key & KEY_EV_PRESSED);
+		}
+	}
+}
+
+static irqreturn_t adp5589_irq(int irq, void *handle)
+{
+	struct adp5589_kpad *kpad = handle;
+	struct i2c_client *client = kpad->client;
+	int status, ev_cnt;
+
+	status = adp5589_read(client, ADP5589_INT_STATUS);
+
+	if (status & OVRFLOW_INT)	/* Unlikely and should never happen */
+		dev_err(&client->dev, "Event Overflow Error\n");
+
+	if (status & EVENT_INT) {
+		ev_cnt = adp5589_read(client, ADP5589_STATUS) & KEC;
+		if (ev_cnt) {
+			adp5589_report_events(kpad, ev_cnt);
+			input_sync(kpad->input);
+		}
+	}
+
+	adp5589_write(client, ADP5589_INT_STATUS, status);	/* Status is W1C */
+
+	return IRQ_HANDLED;
+}
+
+static int __devinit adp5589_get_evcode(struct adp5589_kpad *kpad, unsigned short key)
+{
+	int i;
+
+	for (i = 0; i < ADP5589_KEYMAPSIZE; i++)
+		if (key == kpad->keycode[i])
+			return (i + 1) | KEY_EV_PRESSED;
+
+	dev_err(&kpad->client->dev, "RESET/UNLOCK key not in keycode map\n");
+
+	return -EINVAL;
+}
+
+static int __devinit adp5589_setup(struct adp5589_kpad *kpad)
+{
+	struct i2c_client *client = kpad->client;
+	const struct adp5589_kpad_platform_data *pdata =
+	    client->dev.platform_data;
+	int i, ret;
+	unsigned char evt_mode1 = 0, evt_mode2 = 0, evt_mode3 = 0;
+	unsigned char pull_mask = 0;
+
+	ret = adp5589_write(client, ADP5589_PIN_CONFIG_A,
+			    pdata->keypad_en_mask & 0xFF);
+	ret |= adp5589_write(client, ADP5589_PIN_CONFIG_B,
+			     (pdata->keypad_en_mask >> 8) & 0xFF);
+	ret |= adp5589_write(client, ADP5589_PIN_CONFIG_C,
+			     (pdata->keypad_en_mask >> 16) & 0xFF);
+
+	if (pdata->en_keylock) {
+		ret |= adp5589_write(client, ADP5589_UNLOCK1,
+				     pdata->unlock_key1);
+		ret |= adp5589_write(client, ADP5589_UNLOCK2,
+				     pdata->unlock_key2);
+		ret |= adp5589_write(client, ADP5589_UNLOCK_TIMERS,
+				     pdata->unlock_timer & LTIME_MASK);
+		ret |= adp5589_write(client, ADP5589_LOCK_CFG, LOCK_EN);
+	}
+
+	for (i = 0; i < KEYP_MAX_EVENT; i++)
+		ret |= adp5589_read(client, ADP5589_FIFO_1 + i);
+
+	for (i = 0; i < pdata->gpimapsize; i++) {
+		unsigned short pin = pdata->gpimap[i].pin;
+
+		if (pin <= ADP5589_GPI_PIN_ROW_END) {
+			evt_mode1 |= (1 << (pin - ADP5589_GPI_PIN_ROW_BASE));
+		} else {
+			evt_mode2 |=
+			    ((1 << (pin - ADP5589_GPI_PIN_COL_BASE)) & 0xFF);
+			evt_mode3 |=
+			    ((1 << (pin - ADP5589_GPI_PIN_COL_BASE)) >> 8);
+		}
+	}
+
+	if (pdata->gpimapsize) {
+		ret |= adp5589_write(client, ADP5589_GPI_EVENT_EN_A, evt_mode1);
+		ret |= adp5589_write(client, ADP5589_GPI_EVENT_EN_B, evt_mode2);
+		ret |= adp5589_write(client, ADP5589_GPI_EVENT_EN_C, evt_mode3);
+	}
+
+	if (pdata->pull_dis_mask & pdata->pullup_en_100k &
+	    pdata->pullup_en_300k & pdata->pulldown_en_300k)
+		dev_warn(&client->dev, "Conflicting pull resistor config\n");
+
+	for (i = 0; i < MAXGPIO; i++) {
+		unsigned val = 0;
+
+		if (pdata->pullup_en_300k & (1 << i))
+			val = 0;
+		else if (pdata->pulldown_en_300k & (1 << i))
+			val = 1;
+		else if (pdata->pullup_en_100k & (1 << i))
+			val = 2;
+		else if (pdata->pull_dis_mask & (1 << i))
+			val = 3;
+
+		pull_mask |= val << (2 * (i & 0x3));
+
+		if ((i & 0x3) == 0x3 || i == MAXGPIO - 1) {
+			ret |= adp5589_write(client,
+					     ADP5589_RPULL_CONFIG_A + (i >> 2),
+					     pull_mask);
+			pull_mask = 0;
+		}
+	}
+
+	if (pdata->reset1_key_1 && pdata->reset1_key_2 && pdata->reset1_key_3) {
+		ret |= adp5589_write(client, ADP5589_RESET1_EVENT_A,
+				     adp5589_get_evcode(kpad,
+							pdata->reset1_key_1));
+		ret |= adp5589_write(client, ADP5589_RESET1_EVENT_B,
+				     adp5589_get_evcode(kpad,
+							pdata->reset1_key_2));
+		ret |= adp5589_write(client, ADP5589_RESET1_EVENT_C,
+				     adp5589_get_evcode(kpad,
+							pdata->reset1_key_3));
+		kpad->extend_cfg |= R4_EXTEND_CFG;
+	}
+
+	if (pdata->reset2_key_1 && pdata->reset2_key_2) {
+		ret |= adp5589_write(client, ADP5589_RESET2_EVENT_A,
+				     adp5589_get_evcode(kpad,
+							pdata->reset2_key_1));
+		ret |= adp5589_write(client, ADP5589_RESET2_EVENT_B,
+				     adp5589_get_evcode(kpad,
+							pdata->reset2_key_2));
+		kpad->extend_cfg |= C4_EXTEND_CFG;
+	}
+
+	if (kpad->extend_cfg) {
+		ret |= adp5589_write(client, ADP5589_RESET_CFG,
+				     pdata->reset_cfg);
+		ret |= adp5589_write(client, ADP5589_PIN_CONFIG_D,
+				     kpad->extend_cfg);
+	}
+
+	for (i = 0; i <= ADP_BANK(MAXGPIO); i++)
+		ret |= adp5589_write(client, ADP5589_DEBOUNCE_DIS_A + i,
+				     pdata->debounce_dis_mask >> (i * 8));
+
+	ret |= adp5589_write(client, ADP5589_POLL_PTIME_CFG,
+			     pdata->scan_cycle_time & PTIME_MASK);
+	ret |= adp5589_write(client, ADP5589_INT_STATUS, LOGIC2_INT |
+			     LOGIC1_INT | OVRFLOW_INT | LOCK_INT |
+			     GPI_INT | EVENT_INT);	/* Status is W1C */
+
+	ret |= adp5589_write(client, ADP5589_GENERAL_CFG,
+			     INT_CFG | OSC_EN | CORE_CLK(3));
+	ret |= adp5589_write(client, ADP5589_INT_EN,
+			     OVRFLOW_IEN | GPI_IEN | EVENT_IEN);
+
+	if (ret < 0) {
+		dev_err(&client->dev, "Write Error\n");
+		return ret;
+	}
+
+	return 0;
+}
+
+static void __devinit adp5589_report_switch_state(struct adp5589_kpad *kpad)
+{
+	int gpi_stat1 = adp5589_read(kpad->client, ADP5589_GPI_STATUS_A);
+	int gpi_stat2 = adp5589_read(kpad->client, ADP5589_GPI_STATUS_B);
+	int gpi_stat3 = adp5589_read(kpad->client, ADP5589_GPI_STATUS_C);
+	int gpi_stat_tmp, pin_loc;
+	int i;
+
+	for (i = 0; i < kpad->gpimapsize; i++) {
+		unsigned short pin = kpad->gpimap[i].pin;
+
+		if (pin <= ADP5589_GPI_PIN_ROW_END) {
+			gpi_stat_tmp = gpi_stat1;
+			pin_loc = pin - ADP5589_GPI_PIN_ROW_BASE;
+		} else if ((pin - ADP5589_GPI_PIN_COL_BASE) < 8) {
+			gpi_stat_tmp = gpi_stat2;
+			pin_loc = pin - ADP5589_GPI_PIN_COL_BASE;
+		} else {
+			gpi_stat_tmp = gpi_stat3;
+			pin_loc = pin - ADP5589_GPI_PIN_COL_BASE - 8;
+		}
+
+		if (gpi_stat_tmp < 0) {
+			dev_err(&kpad->client->dev,
+				"Can't read GPIO_DAT_STAT switch"
+				" %d default to OFF\n", pin);
+			gpi_stat_tmp = 0;
+		}
+
+		input_report_switch(kpad->input,
+				    kpad->gpimap[i].sw_evt,
+				    !(gpi_stat_tmp & (1 << pin_loc)));
+	}
+
+	input_sync(kpad->input);
+}
+
+static int __devinit adp5589_probe(struct i2c_client *client,
+				   const struct i2c_device_id *id)
+{
+	struct adp5589_kpad *kpad;
+	const struct adp5589_kpad_platform_data *pdata;
+	struct input_dev *input;
+	unsigned int revid;
+	int ret, i;
+	int error;
+
+	if (!i2c_check_functionality(client->adapter,
+				     I2C_FUNC_SMBUS_BYTE_DATA)) {
+		dev_err(&client->dev, "SMBUS Byte Data not Supported\n");
+		return -EIO;
+	}
+
+	pdata = client->dev.platform_data;
+	if (!pdata) {
+		dev_err(&client->dev, "no platform data?\n");
+		return -EINVAL;
+	}
+
+	if (!((pdata->keypad_en_mask & 0xFF) &&
+			(pdata->keypad_en_mask >> 8)) || !pdata->keymap) {
+		dev_err(&client->dev, "no rows, cols or keymap from pdata\n");
+		return -EINVAL;
+	}
+
+	if (pdata->keymapsize != ADP5589_KEYMAPSIZE) {
+		dev_err(&client->dev, "invalid keymapsize\n");
+		return -EINVAL;
+	}
+
+	if (!pdata->gpimap && pdata->gpimapsize) {
+		dev_err(&client->dev, "invalid gpimap from pdata\n");
+		return -EINVAL;
+	}
+
+	if (pdata->gpimapsize > ADP5589_GPIMAPSIZE_MAX) {
+		dev_err(&client->dev, "invalid gpimapsize\n");
+		return -EINVAL;
+	}
+
+	for (i = 0; i < pdata->gpimapsize; i++) {
+		unsigned short pin = pdata->gpimap[i].pin;
+
+		if (pin < ADP5589_GPI_PIN_BASE || pin > ADP5589_GPI_PIN_END) {
+			dev_err(&client->dev, "invalid gpi pin data\n");
+			return -EINVAL;
+		}
+
+		if ((1 << (pin - ADP5589_GPI_PIN_ROW_BASE)) &
+				pdata->keypad_en_mask) {
+			dev_err(&client->dev, "invalid gpi row/col data\n");
+			return -EINVAL;
+		}
+	}
+
+	if (!client->irq) {
+		dev_err(&client->dev, "no IRQ?\n");
+		return -EINVAL;
+	}
+
+	kpad = kzalloc(sizeof(*kpad), GFP_KERNEL);
+	input = input_allocate_device();
+	if (!kpad || !input) {
+		error = -ENOMEM;
+		goto err_free_mem;
+	}
+
+	kpad->client = client;
+	kpad->input = input;
+
+	ret = adp5589_read(client, ADP5589_ID);
+	if (ret < 0) {
+		error = ret;
+		goto err_free_mem;
+	}
+
+	revid = (u8) ret & ADP5589_DEVICE_ID_MASK;
+
+	input->name = client->name;
+	input->phys = "adp5589-keys/input0";
+	input->dev.parent = &client->dev;
+
+	input_set_drvdata(input, kpad);
+
+	input->id.bustype = BUS_I2C;
+	input->id.vendor = 0x0001;
+	input->id.product = 0x0001;
+	input->id.version = revid;
+
+	input->keycodesize = sizeof(kpad->keycode[0]);
+	input->keycodemax = pdata->keymapsize;
+	input->keycode = kpad->keycode;
+
+	memcpy(kpad->keycode, pdata->keymap,
+	       pdata->keymapsize * input->keycodesize);
+
+	kpad->gpimap = pdata->gpimap;
+	kpad->gpimapsize = pdata->gpimapsize;
+
+	/* setup input device */
+	__set_bit(EV_KEY, input->evbit);
+
+	if (pdata->repeat)
+		__set_bit(EV_REP, input->evbit);
+
+	for (i = 0; i < input->keycodemax; i++)
+		__set_bit(kpad->keycode[i] & KEY_MAX, input->keybit);
+	__clear_bit(KEY_RESERVED, input->keybit);
+
+	if (kpad->gpimapsize)
+		__set_bit(EV_SW, input->evbit);
+	for (i = 0; i < kpad->gpimapsize; i++)
+		__set_bit(kpad->gpimap[i].sw_evt, input->swbit);
+
+	error = input_register_device(input);
+	if (error) {
+		dev_err(&client->dev, "unable to register input device\n");
+		goto err_free_mem;
+	}
+
+	error = request_threaded_irq(client->irq, NULL, adp5589_irq,
+				     IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
+				     client->dev.driver->name, kpad);
+	if (error) {
+		dev_err(&client->dev, "irq %d busy?\n", client->irq);
+		goto err_unreg_dev;
+	}
+
+	error = adp5589_setup(kpad);
+	if (error)
+		goto err_free_irq;
+
+	if (kpad->gpimapsize)
+		adp5589_report_switch_state(kpad);
+
+	error = adp5589_gpio_add(kpad);
+	if (error)
+		goto err_free_irq;
+
+	device_init_wakeup(&client->dev, 1);
+	i2c_set_clientdata(client, kpad);
+
+	dev_info(&client->dev, "Rev.%d keypad, irq %d\n", revid, client->irq);
+	return 0;
+
+err_free_irq:
+	free_irq(client->irq, kpad);
+err_unreg_dev:
+	input_unregister_device(input);
+	input = NULL;
+err_free_mem:
+	input_free_device(input);
+	kfree(kpad);
+
+	return error;
+}
+
+static int __devexit adp5589_remove(struct i2c_client *client)
+{
+	struct adp5589_kpad *kpad = i2c_get_clientdata(client);
+
+	adp5589_write(client, ADP5589_GENERAL_CFG, 0);
+	free_irq(client->irq, kpad);
+	input_unregister_device(kpad->input);
+	adp5589_gpio_remove(kpad);
+	kfree(kpad);
+
+	return 0;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int adp5589_suspend(struct device *dev)
+{
+	struct adp5589_kpad *kpad = dev_get_drvdata(dev);
+	struct i2c_client *client = kpad->client;
+
+	disable_irq(client->irq);
+
+	if (device_may_wakeup(&client->dev))
+		enable_irq_wake(client->irq);
+
+	return 0;
+}
+
+static int adp5589_resume(struct device *dev)
+{
+	struct adp5589_kpad *kpad = dev_get_drvdata(dev);
+	struct i2c_client *client = kpad->client;
+
+	if (device_may_wakeup(&client->dev))
+		disable_irq_wake(client->irq);
+
+	enable_irq(client->irq);
+
+	return 0;
+}
+#endif
+
+static SIMPLE_DEV_PM_OPS(adp5589_dev_pm_ops, adp5589_suspend, adp5589_resume);
+
+static const struct i2c_device_id adp5589_id[] = {
+	{"adp5589-keys", 0},
+	{}
+};
+
+MODULE_DEVICE_TABLE(i2c, adp5589_id);
+
+static struct i2c_driver adp5589_driver = {
+	.driver = {
+		.name = KBUILD_MODNAME,
+		.owner = THIS_MODULE,
+		.pm = &adp5589_dev_pm_ops,
+	},
+	.probe = adp5589_probe,
+	.remove = __devexit_p(adp5589_remove),
+	.id_table = adp5589_id,
+};
+
+static int __init adp5589_init(void)
+{
+	return i2c_add_driver(&adp5589_driver);
+}
+module_init(adp5589_init);
+
+static void __exit adp5589_exit(void)
+{
+	i2c_del_driver(&adp5589_driver);
+}
+module_exit(adp5589_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>");
+MODULE_DESCRIPTION("ADP5589 Keypad driver");
diff -druN linux-2.6.39-libre/drivers/input/keyboard/atakbd.c linux-3.0-rc7-libre/drivers/input/keyboard/atakbd.c
--- linux-2.6.39-libre/drivers/input/keyboard/atakbd.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/input/keyboard/atakbd.c	2011-07-11 19:51:52.000000000 -0400
@@ -223,8 +223,9 @@
 		return -ENODEV;
 
 	// need to init core driver if not already done so
-	if (atari_keyb_init())
-		return -ENODEV;
+	error = atari_keyb_init();
+	if (error)
+		return error;
 
 	atakbd_dev = input_allocate_device();
 	if (!atakbd_dev)
diff -druN linux-2.6.39-libre/drivers/input/keyboard/gpio_keys.c linux-3.0-rc7-libre/drivers/input/keyboard/gpio_keys.c
--- linux-2.6.39-libre/drivers/input/keyboard/gpio_keys.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/input/keyboard/gpio_keys.c	2011-07-11 19:51:52.000000000 -0400
@@ -324,7 +324,12 @@
 	unsigned int type = button->type ?: EV_KEY;
 	int state = (gpio_get_value_cansleep(button->gpio) ? 1 : 0) ^ button->active_low;
 
-	input_event(input, type, button->code, !!state);
+	if (type == EV_ABS) {
+		if (state)
+			input_event(input, type, button->code, button->value);
+	} else {
+		input_event(input, type, button->code, !!state);
+	}
 	input_sync(input);
 }
 
@@ -363,7 +368,7 @@
 					 struct gpio_button_data *bdata,
 					 struct gpio_keys_button *button)
 {
-	char *desc = button->desc ? button->desc : "gpio_keys";
+	const char *desc = button->desc ? button->desc : "gpio_keys";
 	struct device *dev = &pdev->dev;
 	unsigned long irqflags;
 	int irq, error;
@@ -468,7 +473,7 @@
 	platform_set_drvdata(pdev, ddata);
 	input_set_drvdata(input, ddata);
 
-	input->name = pdev->name;
+	input->name = pdata->name ? : pdev->name;
 	input->phys = "gpio-keys/input0";
 	input->dev.parent = &pdev->dev;
 	input->open = gpio_keys_open;
diff -druN linux-2.6.39-libre/drivers/input/keyboard/Kconfig linux-3.0-rc7-libre/drivers/input/keyboard/Kconfig
--- linux-2.6.39-libre/drivers/input/keyboard/Kconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/input/keyboard/Kconfig	2011-07-11 19:51:52.000000000 -0400
@@ -32,6 +32,16 @@
 	  To compile this driver as a module, choose M here: the
 	  module will be called adp5588-keys.
 
+config KEYBOARD_ADP5589
+	tristate "ADP5589 I2C QWERTY Keypad and IO Expander"
+	depends on I2C
+	help
+	  Say Y here if you want to use a ADP5589 attached to your
+	  system I2C bus.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called adp5589-keys.
+
 config KEYBOARD_AMIGA
 	tristate "Amiga keyboard"
 	depends on AMIGA
@@ -325,6 +335,18 @@
 	  To compile this driver as a module, choose M here: the
 	  module will be called mcs_touchkey.
 
+config KEYBOARD_MPR121
+	tristate "Freescale MPR121 Touchkey"
+	depends on I2C
+	help
+	  Say Y here if you have Freescale MPR121 touchkey controller
+	  chip in your system.
+
+	  If unsure, say N.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called mpr121_touchkey.
+
 config KEYBOARD_IMX
 	tristate "IMX keypad support"
 	depends on ARCH_MXC
@@ -390,6 +412,17 @@
 	  To compile this driver as a module, choose M here: the
 	  module will be called pxa930_rotary.
 
+config KEYBOARD_PMIC8XXX
+	tristate "Qualcomm PMIC8XXX keypad support"
+	depends on MFD_PM8XXX
+	help
+	  Say Y here if you want to enable the driver for the PMIC8XXX
+	  keypad provided as a reference design from Qualcomm. This is intended
+	  to support upto 18x8 matrix based keypad design.
+
+	  To compile this driver as a module, choose M here: the module will
+	  be called pmic8xxx-keypad.
+
 config KEYBOARD_SAMSUNG
 	tristate "Samsung keypad support"
 	depends on SAMSUNG_DEV_KEYPAD
diff -druN linux-2.6.39-libre/drivers/input/keyboard/Makefile linux-3.0-rc7-libre/drivers/input/keyboard/Makefile
--- linux-2.6.39-libre/drivers/input/keyboard/Makefile	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/input/keyboard/Makefile	2011-07-11 19:51:52.000000000 -0400
@@ -6,6 +6,7 @@
 
 obj-$(CONFIG_KEYBOARD_ADP5520)		+= adp5520-keys.o
 obj-$(CONFIG_KEYBOARD_ADP5588)		+= adp5588-keys.o
+obj-$(CONFIG_KEYBOARD_ADP5589)		+= adp5589-keys.o
 obj-$(CONFIG_KEYBOARD_AMIGA)		+= amikbd.o
 obj-$(CONFIG_KEYBOARD_ATARI)		+= atakbd.o
 obj-$(CONFIG_KEYBOARD_ATKBD)		+= atkbd.o
@@ -27,11 +28,13 @@
 obj-$(CONFIG_KEYBOARD_MATRIX)		+= matrix_keypad.o
 obj-$(CONFIG_KEYBOARD_MAX7359)		+= max7359_keypad.o
 obj-$(CONFIG_KEYBOARD_MCS)		+= mcs_touchkey.o
+obj-$(CONFIG_KEYBOARD_MPR121)		+= mpr121_touchkey.o
 obj-$(CONFIG_KEYBOARD_NEWTON)		+= newtonkbd.o
 obj-$(CONFIG_KEYBOARD_NOMADIK)		+= nomadik-ske-keypad.o
 obj-$(CONFIG_KEYBOARD_OMAP)		+= omap-keypad.o
 obj-$(CONFIG_KEYBOARD_OMAP4)		+= omap4-keypad.o
 obj-$(CONFIG_KEYBOARD_OPENCORES)	+= opencores-kbd.o
+obj-$(CONFIG_KEYBOARD_PMIC8XXX)		+= pmic8xxx-keypad.o
 obj-$(CONFIG_KEYBOARD_PXA27x)		+= pxa27x_keypad.o
 obj-$(CONFIG_KEYBOARD_PXA930_ROTARY)	+= pxa930_rotary.o
 obj-$(CONFIG_KEYBOARD_QT1070)           += qt1070.o
diff -druN linux-2.6.39-libre/drivers/input/keyboard/mpr121_touchkey.c linux-3.0-rc7-libre/drivers/input/keyboard/mpr121_touchkey.c
--- linux-2.6.39-libre/drivers/input/keyboard/mpr121_touchkey.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/input/keyboard/mpr121_touchkey.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,339 @@
+/*
+ * Touchkey driver for Freescale MPR121 Controllor
+ *
+ * Copyright (C) 2011 Freescale Semiconductor, Inc.
+ * Author: Zhang Jiejing <jiejing.zhang@freescale.com>
+ *
+ * Based on mcs_touchkey.c
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/input.h>
+#include <linux/i2c.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include <linux/bitops.h>
+#include <linux/interrupt.h>
+#include <linux/i2c/mpr121_touchkey.h>
+
+/* Register definitions */
+#define ELE_TOUCH_STATUS_0_ADDR	0x0
+#define ELE_TOUCH_STATUS_1_ADDR	0X1
+#define MHD_RISING_ADDR		0x2b
+#define NHD_RISING_ADDR		0x2c
+#define NCL_RISING_ADDR		0x2d
+#define FDL_RISING_ADDR		0x2e
+#define MHD_FALLING_ADDR	0x2f
+#define NHD_FALLING_ADDR	0x30
+#define NCL_FALLING_ADDR	0x31
+#define FDL_FALLING_ADDR	0x32
+#define ELE0_TOUCH_THRESHOLD_ADDR	0x41
+#define ELE0_RELEASE_THRESHOLD_ADDR	0x42
+#define AFE_CONF_ADDR			0x5c
+#define FILTER_CONF_ADDR		0x5d
+
+/*
+ * ELECTRODE_CONF_ADDR: This register configures the number of
+ * enabled capacitance sensing inputs and its run/suspend mode.
+ */
+#define ELECTRODE_CONF_ADDR		0x5e
+#define AUTO_CONFIG_CTRL_ADDR		0x7b
+#define AUTO_CONFIG_USL_ADDR		0x7d
+#define AUTO_CONFIG_LSL_ADDR		0x7e
+#define AUTO_CONFIG_TL_ADDR		0x7f
+
+/* Threshold of touch/release trigger */
+#define TOUCH_THRESHOLD			0x0f
+#define RELEASE_THRESHOLD		0x0a
+/* Masks for touch and release triggers */
+#define TOUCH_STATUS_MASK		0xfff
+/* MPR121 has 12 keys */
+#define MPR121_MAX_KEY_COUNT		12
+
+struct mpr121_touchkey {
+	struct i2c_client	*client;
+	struct input_dev	*input_dev;
+	unsigned int		key_val;
+	unsigned int		statusbits;
+	unsigned int		keycount;
+	u16			keycodes[MPR121_MAX_KEY_COUNT];
+};
+
+struct mpr121_init_register {
+	int addr;
+	u8 val;
+};
+
+static const struct mpr121_init_register init_reg_table[] __devinitconst = {
+	{ MHD_RISING_ADDR,	0x1 },
+	{ NHD_RISING_ADDR,	0x1 },
+	{ MHD_FALLING_ADDR,	0x1 },
+	{ NHD_FALLING_ADDR,	0x1 },
+	{ NCL_FALLING_ADDR,	0xff },
+	{ FDL_FALLING_ADDR,	0x02 },
+	{ FILTER_CONF_ADDR,	0x04 },
+	{ AFE_CONF_ADDR,	0x0b },
+	{ AUTO_CONFIG_CTRL_ADDR, 0x0b },
+};
+
+static irqreturn_t mpr_touchkey_interrupt(int irq, void *dev_id)
+{
+	struct mpr121_touchkey *mpr121 = dev_id;
+	struct i2c_client *client = mpr121->client;
+	struct input_dev *input = mpr121->input_dev;
+	unsigned int key_num, key_val, pressed;
+	int reg;
+
+	reg = i2c_smbus_read_byte_data(client, ELE_TOUCH_STATUS_1_ADDR);
+	if (reg < 0) {
+		dev_err(&client->dev, "i2c read error [%d]\n", reg);
+		goto out;
+	}
+
+	reg <<= 8;
+	reg |= i2c_smbus_read_byte_data(client, ELE_TOUCH_STATUS_0_ADDR);
+	if (reg < 0) {
+		dev_err(&client->dev, "i2c read error [%d]\n", reg);
+		goto out;
+	}
+
+	reg &= TOUCH_STATUS_MASK;
+	/* use old press bit to figure out which bit changed */
+	key_num = ffs(reg ^ mpr121->statusbits) - 1;
+	pressed = reg & (1 << key_num);
+	mpr121->statusbits = reg;
+
+	key_val = mpr121->keycodes[key_num];
+
+	input_event(input, EV_MSC, MSC_SCAN, key_num);
+	input_report_key(input, key_val, pressed);
+	input_sync(input);
+
+	dev_dbg(&client->dev, "key %d %d %s\n", key_num, key_val,
+		pressed ? "pressed" : "released");
+
+out:
+	return IRQ_HANDLED;
+}
+
+static int __devinit mpr121_phys_init(const struct mpr121_platform_data *pdata,
+				      struct mpr121_touchkey *mpr121,
+				      struct i2c_client *client)
+{
+	const struct mpr121_init_register *reg;
+	unsigned char usl, lsl, tl;
+	int i, t, vdd, ret;
+
+	/* Set up touch/release threshold for ele0-ele11 */
+	for (i = 0; i <= MPR121_MAX_KEY_COUNT; i++) {
+		t = ELE0_TOUCH_THRESHOLD_ADDR + (i * 2);
+		ret = i2c_smbus_write_byte_data(client, t, TOUCH_THRESHOLD);
+		if (ret < 0)
+			goto err_i2c_write;
+		ret = i2c_smbus_write_byte_data(client, t + 1,
+						RELEASE_THRESHOLD);
+		if (ret < 0)
+			goto err_i2c_write;
+	}
+
+	/* Set up init register */
+	for (i = 0; i < ARRAY_SIZE(init_reg_table); i++) {
+		reg = &init_reg_table[i];
+		ret = i2c_smbus_write_byte_data(client, reg->addr, reg->val);
+		if (ret < 0)
+			goto err_i2c_write;
+	}
+
+
+	/*
+	 * Capacitance on sensing input varies and needs to be compensated.
+	 * The internal MPR121-auto-configuration can do this if it's
+	 * registers are set properly (based on pdata->vdd_uv).
+	 */
+	vdd = pdata->vdd_uv / 1000;
+	usl = ((vdd - 700) * 256) / vdd;
+	lsl = (usl * 65) / 100;
+	tl = (usl * 90) / 100;
+	ret = i2c_smbus_write_byte_data(client, AUTO_CONFIG_USL_ADDR, usl);
+	ret |= i2c_smbus_write_byte_data(client, AUTO_CONFIG_LSL_ADDR, lsl);
+	ret |= i2c_smbus_write_byte_data(client, AUTO_CONFIG_TL_ADDR, tl);
+	ret |= i2c_smbus_write_byte_data(client, ELECTRODE_CONF_ADDR,
+					 mpr121->keycount);
+	if (ret != 0)
+		goto err_i2c_write;
+
+	dev_dbg(&client->dev, "set up with %x keys.\n", mpr121->keycount);
+
+	return 0;
+
+err_i2c_write:
+	dev_err(&client->dev, "i2c write error: %d\n", ret);
+	return ret;
+}
+
+static int __devinit mpr_touchkey_probe(struct i2c_client *client,
+					const struct i2c_device_id *id)
+{
+	const struct mpr121_platform_data *pdata = client->dev.platform_data;
+	struct mpr121_touchkey *mpr121;
+	struct input_dev *input_dev;
+	int error;
+	int i;
+
+	if (!pdata) {
+		dev_err(&client->dev, "no platform data defined\n");
+		return -EINVAL;
+	}
+
+	if (!pdata->keymap || !pdata->keymap_size) {
+		dev_err(&client->dev, "missing keymap data\n");
+		return -EINVAL;
+	}
+
+	if (pdata->keymap_size > MPR121_MAX_KEY_COUNT) {
+		dev_err(&client->dev, "too many keys defined\n");
+		return -EINVAL;
+	}
+
+	if (!client->irq) {
+		dev_err(&client->dev, "irq number should not be zero\n");
+		return -EINVAL;
+	}
+
+	mpr121 = kzalloc(sizeof(struct mpr121_touchkey), GFP_KERNEL);
+	input_dev = input_allocate_device();
+	if (!mpr121 || !input_dev) {
+		dev_err(&client->dev, "Failed to allocate memory\n");
+		error = -ENOMEM;
+		goto err_free_mem;
+	}
+
+	mpr121->client = client;
+	mpr121->input_dev = input_dev;
+	mpr121->keycount = pdata->keymap_size;
+
+	input_dev->name = "Freescale MPR121 Touchkey";
+	input_dev->id.bustype = BUS_I2C;
+	input_dev->dev.parent = &client->dev;
+	input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP);
+
+	input_dev->keycode = mpr121->keycodes;
+	input_dev->keycodesize = sizeof(mpr121->keycodes[0]);
+	input_dev->keycodemax = mpr121->keycount;
+
+	for (i = 0; i < pdata->keymap_size; i++) {
+		input_set_capability(input_dev, EV_KEY, pdata->keymap[i]);
+		mpr121->keycodes[i] = pdata->keymap[i];
+	}
+
+	error = mpr121_phys_init(pdata, mpr121, client);
+	if (error) {
+		dev_err(&client->dev, "Failed to init register\n");
+		goto err_free_mem;
+	}
+
+	error = request_threaded_irq(client->irq, NULL,
+				     mpr_touchkey_interrupt,
+				     IRQF_TRIGGER_FALLING,
+				     client->dev.driver->name, mpr121);
+	if (error) {
+		dev_err(&client->dev, "Failed to register interrupt\n");
+		goto err_free_mem;
+	}
+
+	error = input_register_device(input_dev);
+	if (error)
+		goto err_free_irq;
+
+	i2c_set_clientdata(client, mpr121);
+	device_init_wakeup(&client->dev, pdata->wakeup);
+
+	return 0;
+
+err_free_irq:
+	free_irq(client->irq, mpr121);
+err_free_mem:
+	input_free_device(input_dev);
+	kfree(mpr121);
+	return error;
+}
+
+static int __devexit mpr_touchkey_remove(struct i2c_client *client)
+{
+	struct mpr121_touchkey *mpr121 = i2c_get_clientdata(client);
+
+	free_irq(client->irq, mpr121);
+	input_unregister_device(mpr121->input_dev);
+	kfree(mpr121);
+
+	return 0;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int mpr_suspend(struct device *dev)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+
+	if (device_may_wakeup(&client->dev))
+		enable_irq_wake(client->irq);
+
+	i2c_smbus_write_byte_data(client, ELECTRODE_CONF_ADDR, 0x00);
+
+	return 0;
+}
+
+static int mpr_resume(struct device *dev)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct mpr121_touchkey *mpr121 = i2c_get_clientdata(client);
+
+	if (device_may_wakeup(&client->dev))
+		disable_irq_wake(client->irq);
+
+	i2c_smbus_write_byte_data(client, ELECTRODE_CONF_ADDR,
+				  mpr121->keycount);
+
+	return 0;
+}
+#endif
+
+static SIMPLE_DEV_PM_OPS(mpr121_touchkey_pm_ops, mpr_suspend, mpr_resume);
+
+static const struct i2c_device_id mpr121_id[] = {
+	{ "mpr121_touchkey", 0 },
+	{ }
+};
+MODULE_DEVICE_TABLE(i2c, mpr121_id);
+
+static struct i2c_driver mpr_touchkey_driver = {
+	.driver = {
+		.name	= "mpr121",
+		.owner	= THIS_MODULE,
+		.pm	= &mpr121_touchkey_pm_ops,
+	},
+	.id_table	= mpr121_id,
+	.probe		= mpr_touchkey_probe,
+	.remove		= __devexit_p(mpr_touchkey_remove),
+};
+
+static int __init mpr_touchkey_init(void)
+{
+	return i2c_add_driver(&mpr_touchkey_driver);
+}
+module_init(mpr_touchkey_init);
+
+static void __exit mpr_touchkey_exit(void)
+{
+	i2c_del_driver(&mpr_touchkey_driver);
+}
+module_exit(mpr_touchkey_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Zhang Jiejing <jiejing.zhang@freescale.com>");
+MODULE_DESCRIPTION("Touch Key driver for Freescale MPR121 Chip");
diff -druN linux-2.6.39-libre/drivers/input/keyboard/omap-keypad.c linux-3.0-rc7-libre/drivers/input/keyboard/omap-keypad.c
--- linux-2.6.39-libre/drivers/input/keyboard/omap-keypad.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/input/keyboard/omap-keypad.c	2011-07-11 19:51:52.000000000 -0400
@@ -209,6 +209,7 @@
 #endif
 		}
 	}
+	input_sync(omap_kp_data->input);
 	memcpy(keypad_state, new_state, sizeof(keypad_state));
 
 	if (key_down) {
@@ -413,7 +414,7 @@
 	return 0;
 err5:
 	for (i = irq_idx - 1; i >=0; i--)
-		free_irq(row_gpios[i], NULL);
+		free_irq(row_gpios[i], omap_kp);
 err4:
 	input_unregister_device(omap_kp->input);
 	input_dev = NULL;
@@ -444,11 +445,11 @@
 			gpio_free(col_gpios[i]);
 		for (i = 0; i < omap_kp->rows; i++) {
 			gpio_free(row_gpios[i]);
-			free_irq(gpio_to_irq(row_gpios[i]), NULL);
+			free_irq(gpio_to_irq(row_gpios[i]), omap_kp);
 		}
 	} else {
 		omap_writew(1, OMAP1_MPUIO_BASE + OMAP_MPUIO_KBD_MASKIT);
-		free_irq(omap_kp->irq, NULL);
+		free_irq(omap_kp->irq, omap_kp);
 	}
 
 	del_timer_sync(&omap_kp->timer);
diff -druN linux-2.6.39-libre/drivers/input/keyboard/pmic8xxx-keypad.c linux-3.0-rc7-libre/drivers/input/keyboard/pmic8xxx-keypad.c
--- linux-2.6.39-libre/drivers/input/keyboard/pmic8xxx-keypad.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/input/keyboard/pmic8xxx-keypad.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,800 @@
+/* Copyright (c) 2009-2011, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/kernel.h>
+#include <linux/interrupt.h>
+#include <linux/slab.h>
+#include <linux/input.h>
+#include <linux/bitops.h>
+#include <linux/delay.h>
+#include <linux/mutex.h>
+
+#include <linux/mfd/pm8xxx/core.h>
+#include <linux/mfd/pm8xxx/gpio.h>
+#include <linux/input/pmic8xxx-keypad.h>
+
+#define PM8XXX_MAX_ROWS		18
+#define PM8XXX_MAX_COLS		8
+#define PM8XXX_ROW_SHIFT	3
+#define PM8XXX_MATRIX_MAX_SIZE	(PM8XXX_MAX_ROWS * PM8XXX_MAX_COLS)
+
+#define PM8XXX_MIN_ROWS		5
+#define PM8XXX_MIN_COLS		5
+
+#define MAX_SCAN_DELAY		128
+#define MIN_SCAN_DELAY		1
+
+/* in nanoseconds */
+#define MAX_ROW_HOLD_DELAY	122000
+#define MIN_ROW_HOLD_DELAY	30500
+
+#define MAX_DEBOUNCE_TIME	20
+#define MIN_DEBOUNCE_TIME	5
+
+#define KEYP_CTRL			0x148
+
+#define KEYP_CTRL_EVNTS			BIT(0)
+#define KEYP_CTRL_EVNTS_MASK		0x3
+
+#define KEYP_CTRL_SCAN_COLS_SHIFT	5
+#define KEYP_CTRL_SCAN_COLS_MIN		5
+#define KEYP_CTRL_SCAN_COLS_BITS	0x3
+
+#define KEYP_CTRL_SCAN_ROWS_SHIFT	2
+#define KEYP_CTRL_SCAN_ROWS_MIN		5
+#define KEYP_CTRL_SCAN_ROWS_BITS	0x7
+
+#define KEYP_CTRL_KEYP_EN		BIT(7)
+
+#define KEYP_SCAN			0x149
+
+#define KEYP_SCAN_READ_STATE		BIT(0)
+#define KEYP_SCAN_DBOUNCE_SHIFT		1
+#define KEYP_SCAN_PAUSE_SHIFT		3
+#define KEYP_SCAN_ROW_HOLD_SHIFT	6
+
+#define KEYP_TEST			0x14A
+
+#define KEYP_TEST_CLEAR_RECENT_SCAN	BIT(6)
+#define KEYP_TEST_CLEAR_OLD_SCAN	BIT(5)
+#define KEYP_TEST_READ_RESET		BIT(4)
+#define KEYP_TEST_DTEST_EN		BIT(3)
+#define KEYP_TEST_ABORT_READ		BIT(0)
+
+#define KEYP_TEST_DBG_SELECT_SHIFT	1
+
+/* bits of these registers represent
+ * '0' for key press
+ * '1' for key release
+ */
+#define KEYP_RECENT_DATA		0x14B
+#define KEYP_OLD_DATA			0x14C
+
+#define KEYP_CLOCK_FREQ			32768
+
+/**
+ * struct pmic8xxx_kp - internal keypad data structure
+ * @pdata - keypad platform data pointer
+ * @input - input device pointer for keypad
+ * @key_sense_irq - key press/release irq number
+ * @key_stuck_irq - key stuck notification irq number
+ * @keycodes - array to hold the key codes
+ * @dev - parent device pointer
+ * @keystate - present key press/release state
+ * @stuckstate - present state when key stuck irq
+ * @ctrl_reg - control register value
+ */
+struct pmic8xxx_kp {
+	const struct pm8xxx_keypad_platform_data *pdata;
+	struct input_dev *input;
+	int key_sense_irq;
+	int key_stuck_irq;
+
+	unsigned short keycodes[PM8XXX_MATRIX_MAX_SIZE];
+
+	struct device *dev;
+	u16 keystate[PM8XXX_MAX_ROWS];
+	u16 stuckstate[PM8XXX_MAX_ROWS];
+
+	u8 ctrl_reg;
+};
+
+static int pmic8xxx_kp_write_u8(struct pmic8xxx_kp *kp,
+				 u8 data, u16 reg)
+{
+	int rc;
+
+	rc = pm8xxx_writeb(kp->dev->parent, reg, data);
+	return rc;
+}
+
+static int pmic8xxx_kp_read(struct pmic8xxx_kp *kp,
+				 u8 *data, u16 reg, unsigned num_bytes)
+{
+	int rc;
+
+	rc = pm8xxx_read_buf(kp->dev->parent, reg, data, num_bytes);
+	return rc;
+}
+
+static int pmic8xxx_kp_read_u8(struct pmic8xxx_kp *kp,
+				 u8 *data, u16 reg)
+{
+	int rc;
+
+	rc = pmic8xxx_kp_read(kp, data, reg, 1);
+	return rc;
+}
+
+static u8 pmic8xxx_col_state(struct pmic8xxx_kp *kp, u8 col)
+{
+	/* all keys pressed on that particular row? */
+	if (col == 0x00)
+		return 1 << kp->pdata->num_cols;
+	else
+		return col & ((1 << kp->pdata->num_cols) - 1);
+}
+
+/*
+ * Synchronous read protocol for RevB0 onwards:
+ *
+ * 1. Write '1' to ReadState bit in KEYP_SCAN register
+ * 2. Wait 2*32KHz clocks, so that HW can successfully enter read mode
+ *    synchronously
+ * 3. Read rows in old array first if events are more than one
+ * 4. Read rows in recent array
+ * 5. Wait 4*32KHz clocks
+ * 6. Write '0' to ReadState bit of KEYP_SCAN register so that hw can
+ *    synchronously exit read mode.
+ */
+static int pmic8xxx_chk_sync_read(struct pmic8xxx_kp *kp)
+{
+	int rc;
+	u8 scan_val;
+
+	rc = pmic8xxx_kp_read_u8(kp, &scan_val, KEYP_SCAN);
+	if (rc < 0) {
+		dev_err(kp->dev, "Error reading KEYP_SCAN reg, rc=%d\n", rc);
+		return rc;
+	}
+
+	scan_val |= 0x1;
+
+	rc = pmic8xxx_kp_write_u8(kp, scan_val, KEYP_SCAN);
+	if (rc < 0) {
+		dev_err(kp->dev, "Error writing KEYP_SCAN reg, rc=%d\n", rc);
+		return rc;
+	}
+
+	/* 2 * 32KHz clocks */
+	udelay((2 * DIV_ROUND_UP(USEC_PER_SEC, KEYP_CLOCK_FREQ)) + 1);
+
+	return rc;
+}
+
+static int pmic8xxx_kp_read_data(struct pmic8xxx_kp *kp, u16 *state,
+					u16 data_reg, int read_rows)
+{
+	int rc, row;
+	u8 new_data[PM8XXX_MAX_ROWS];
+
+	rc = pmic8xxx_kp_read(kp, new_data, data_reg, read_rows);
+	if (rc)
+		return rc;
+
+	for (row = 0; row < kp->pdata->num_rows; row++) {
+		dev_dbg(kp->dev, "new_data[%d] = %d\n", row,
+					new_data[row]);
+		state[row] = pmic8xxx_col_state(kp, new_data[row]);
+	}
+
+	return rc;
+}
+
+static int pmic8xxx_kp_read_matrix(struct pmic8xxx_kp *kp, u16 *new_state,
+					 u16 *old_state)
+{
+	int rc, read_rows;
+	u8 scan_val;
+
+	if (kp->pdata->num_rows < PM8XXX_MIN_ROWS)
+		read_rows = PM8XXX_MIN_ROWS;
+	else
+		read_rows = kp->pdata->num_rows;
+
+	pmic8xxx_chk_sync_read(kp);
+
+	if (old_state) {
+		rc = pmic8xxx_kp_read_data(kp, old_state, KEYP_OLD_DATA,
+						read_rows);
+		if (rc < 0) {
+			dev_err(kp->dev,
+				"Error reading KEYP_OLD_DATA, rc=%d\n", rc);
+			return rc;
+		}
+	}
+
+	rc = pmic8xxx_kp_read_data(kp, new_state, KEYP_RECENT_DATA,
+					 read_rows);
+	if (rc < 0) {
+		dev_err(kp->dev,
+			"Error reading KEYP_RECENT_DATA, rc=%d\n", rc);
+		return rc;
+	}
+
+	/* 4 * 32KHz clocks */
+	udelay((4 * DIV_ROUND_UP(USEC_PER_SEC, KEYP_CLOCK_FREQ)) + 1);
+
+	rc = pmic8xxx_kp_read_u8(kp, &scan_val, KEYP_SCAN);
+	if (rc < 0) {
+		dev_err(kp->dev, "Error reading KEYP_SCAN reg, rc=%d\n", rc);
+		return rc;
+	}
+
+	scan_val &= 0xFE;
+	rc = pmic8xxx_kp_write_u8(kp, scan_val, KEYP_SCAN);
+	if (rc < 0)
+		dev_err(kp->dev, "Error writing KEYP_SCAN reg, rc=%d\n", rc);
+
+	return rc;
+}
+
+static void __pmic8xxx_kp_scan_matrix(struct pmic8xxx_kp *kp, u16 *new_state,
+					 u16 *old_state)
+{
+	int row, col, code;
+
+	for (row = 0; row < kp->pdata->num_rows; row++) {
+		int bits_changed = new_state[row] ^ old_state[row];
+
+		if (!bits_changed)
+			continue;
+
+		for (col = 0; col < kp->pdata->num_cols; col++) {
+			if (!(bits_changed & (1 << col)))
+				continue;
+
+			dev_dbg(kp->dev, "key [%d:%d] %s\n", row, col,
+					!(new_state[row] & (1 << col)) ?
+					"pressed" : "released");
+
+			code = MATRIX_SCAN_CODE(row, col, PM8XXX_ROW_SHIFT);
+
+			input_event(kp->input, EV_MSC, MSC_SCAN, code);
+			input_report_key(kp->input,
+					kp->keycodes[code],
+					!(new_state[row] & (1 << col)));
+
+			input_sync(kp->input);
+		}
+	}
+}
+
+static bool pmic8xxx_detect_ghost_keys(struct pmic8xxx_kp *kp, u16 *new_state)
+{
+	int row, found_first = -1;
+	u16 check, row_state;
+
+	check = 0;
+	for (row = 0; row < kp->pdata->num_rows; row++) {
+		row_state = (~new_state[row]) &
+				 ((1 << kp->pdata->num_cols) - 1);
+
+		if (hweight16(row_state) > 1) {
+			if (found_first == -1)
+				found_first = row;
+			if (check & row_state) {
+				dev_dbg(kp->dev, "detected ghost key on row[%d]"
+					 " and row[%d]\n", found_first, row);
+				return true;
+			}
+		}
+		check |= row_state;
+	}
+	return false;
+}
+
+static int pmic8xxx_kp_scan_matrix(struct pmic8xxx_kp *kp, unsigned int events)
+{
+	u16 new_state[PM8XXX_MAX_ROWS];
+	u16 old_state[PM8XXX_MAX_ROWS];
+	int rc;
+
+	switch (events) {
+	case 0x1:
+		rc = pmic8xxx_kp_read_matrix(kp, new_state, NULL);
+		if (rc < 0)
+			return rc;
+
+		/* detecting ghost key is not an error */
+		if (pmic8xxx_detect_ghost_keys(kp, new_state))
+			return 0;
+		__pmic8xxx_kp_scan_matrix(kp, new_state, kp->keystate);
+		memcpy(kp->keystate, new_state, sizeof(new_state));
+	break;
+	case 0x3: /* two events - eventcounter is gray-coded */
+		rc = pmic8xxx_kp_read_matrix(kp, new_state, old_state);
+		if (rc < 0)
+			return rc;
+
+		__pmic8xxx_kp_scan_matrix(kp, old_state, kp->keystate);
+		__pmic8xxx_kp_scan_matrix(kp, new_state, old_state);
+		memcpy(kp->keystate, new_state, sizeof(new_state));
+	break;
+	case 0x2:
+		dev_dbg(kp->dev, "Some key events were lost\n");
+		rc = pmic8xxx_kp_read_matrix(kp, new_state, old_state);
+		if (rc < 0)
+			return rc;
+		__pmic8xxx_kp_scan_matrix(kp, old_state, kp->keystate);
+		__pmic8xxx_kp_scan_matrix(kp, new_state, old_state);
+		memcpy(kp->keystate, new_state, sizeof(new_state));
+	break;
+	default:
+		rc = -EINVAL;
+	}
+	return rc;
+}
+
+/*
+ * NOTE: We are reading recent and old data registers blindly
+ * whenever key-stuck interrupt happens, because events counter doesn't
+ * get updated when this interrupt happens due to key stuck doesn't get
+ * considered as key state change.
+ *
+ * We are not using old data register contents after they are being read
+ * because it might report the key which was pressed before the key being stuck
+ * as stuck key because it's pressed status is stored in the old data
+ * register.
+ */
+static irqreturn_t pmic8xxx_kp_stuck_irq(int irq, void *data)
+{
+	u16 new_state[PM8XXX_MAX_ROWS];
+	u16 old_state[PM8XXX_MAX_ROWS];
+	int rc;
+	struct pmic8xxx_kp *kp = data;
+
+	rc = pmic8xxx_kp_read_matrix(kp, new_state, old_state);
+	if (rc < 0) {
+		dev_err(kp->dev, "failed to read keypad matrix\n");
+		return IRQ_HANDLED;
+	}
+
+	__pmic8xxx_kp_scan_matrix(kp, new_state, kp->stuckstate);
+
+	return IRQ_HANDLED;
+}
+
+static irqreturn_t pmic8xxx_kp_irq(int irq, void *data)
+{
+	struct pmic8xxx_kp *kp = data;
+	u8 ctrl_val, events;
+	int rc;
+
+	rc = pmic8xxx_kp_read(kp, &ctrl_val, KEYP_CTRL, 1);
+	if (rc < 0) {
+		dev_err(kp->dev, "failed to read keyp_ctrl register\n");
+		return IRQ_HANDLED;
+	}
+
+	events = ctrl_val & KEYP_CTRL_EVNTS_MASK;
+
+	rc = pmic8xxx_kp_scan_matrix(kp, events);
+	if (rc < 0)
+		dev_err(kp->dev, "failed to scan matrix\n");
+
+	return IRQ_HANDLED;
+}
+
+static int __devinit pmic8xxx_kpd_init(struct pmic8xxx_kp *kp)
+{
+	int bits, rc, cycles;
+	u8 scan_val = 0, ctrl_val = 0;
+	static const u8 row_bits[] = {
+		0, 1, 2, 3, 4, 4, 5, 5, 6, 6, 6, 7, 7, 7,
+	};
+
+	/* Find column bits */
+	if (kp->pdata->num_cols < KEYP_CTRL_SCAN_COLS_MIN)
+		bits = 0;
+	else
+		bits = kp->pdata->num_cols - KEYP_CTRL_SCAN_COLS_MIN;
+	ctrl_val = (bits & KEYP_CTRL_SCAN_COLS_BITS) <<
+		KEYP_CTRL_SCAN_COLS_SHIFT;
+
+	/* Find row bits */
+	if (kp->pdata->num_rows < KEYP_CTRL_SCAN_ROWS_MIN)
+		bits = 0;
+	else
+		bits = row_bits[kp->pdata->num_rows - KEYP_CTRL_SCAN_ROWS_MIN];
+
+	ctrl_val |= (bits << KEYP_CTRL_SCAN_ROWS_SHIFT);
+
+	rc = pmic8xxx_kp_write_u8(kp, ctrl_val, KEYP_CTRL);
+	if (rc < 0) {
+		dev_err(kp->dev, "Error writing KEYP_CTRL reg, rc=%d\n", rc);
+		return rc;
+	}
+
+	bits = (kp->pdata->debounce_ms / 5) - 1;
+
+	scan_val |= (bits << KEYP_SCAN_DBOUNCE_SHIFT);
+
+	bits = fls(kp->pdata->scan_delay_ms) - 1;
+	scan_val |= (bits << KEYP_SCAN_PAUSE_SHIFT);
+
+	/* Row hold time is a multiple of 32KHz cycles. */
+	cycles = (kp->pdata->row_hold_ns * KEYP_CLOCK_FREQ) / NSEC_PER_SEC;
+
+	scan_val |= (cycles << KEYP_SCAN_ROW_HOLD_SHIFT);
+
+	rc = pmic8xxx_kp_write_u8(kp, scan_val, KEYP_SCAN);
+	if (rc)
+		dev_err(kp->dev, "Error writing KEYP_SCAN reg, rc=%d\n", rc);
+
+	return rc;
+
+}
+
+static int  __devinit pmic8xxx_kp_config_gpio(int gpio_start, int num_gpios,
+			struct pmic8xxx_kp *kp, struct pm_gpio *gpio_config)
+{
+	int	rc, i;
+
+	if (gpio_start < 0 || num_gpios < 0)
+		return -EINVAL;
+
+	for (i = 0; i < num_gpios; i++) {
+		rc = pm8xxx_gpio_config(gpio_start + i, gpio_config);
+		if (rc) {
+			dev_err(kp->dev, "%s: FAIL pm8xxx_gpio_config():"
+					"for PM GPIO [%d] rc=%d.\n",
+					__func__, gpio_start + i, rc);
+			return rc;
+		}
+	 }
+
+	return 0;
+}
+
+static int pmic8xxx_kp_enable(struct pmic8xxx_kp *kp)
+{
+	int rc;
+
+	kp->ctrl_reg |= KEYP_CTRL_KEYP_EN;
+
+	rc = pmic8xxx_kp_write_u8(kp, kp->ctrl_reg, KEYP_CTRL);
+	if (rc < 0)
+		dev_err(kp->dev, "Error writing KEYP_CTRL reg, rc=%d\n", rc);
+
+	return rc;
+}
+
+static int pmic8xxx_kp_disable(struct pmic8xxx_kp *kp)
+{
+	int rc;
+
+	kp->ctrl_reg &= ~KEYP_CTRL_KEYP_EN;
+
+	rc = pmic8xxx_kp_write_u8(kp, kp->ctrl_reg, KEYP_CTRL);
+	if (rc < 0)
+		return rc;
+
+	return rc;
+}
+
+static int pmic8xxx_kp_open(struct input_dev *dev)
+{
+	struct pmic8xxx_kp *kp = input_get_drvdata(dev);
+
+	return pmic8xxx_kp_enable(kp);
+}
+
+static void pmic8xxx_kp_close(struct input_dev *dev)
+{
+	struct pmic8xxx_kp *kp = input_get_drvdata(dev);
+
+	pmic8xxx_kp_disable(kp);
+}
+
+/*
+ * keypad controller should be initialized in the following sequence
+ * only, otherwise it might get into FSM stuck state.
+ *
+ * - Initialize keypad control parameters, like no. of rows, columns,
+ *   timing values etc.,
+ * - configure rows and column gpios pull up/down.
+ * - set irq edge type.
+ * - enable the keypad controller.
+ */
+static int __devinit pmic8xxx_kp_probe(struct platform_device *pdev)
+{
+	const struct pm8xxx_keypad_platform_data *pdata =
+					dev_get_platdata(&pdev->dev);
+	const struct matrix_keymap_data *keymap_data;
+	struct pmic8xxx_kp *kp;
+	int rc;
+	u8 ctrl_val;
+
+	struct pm_gpio kypd_drv = {
+		.direction	= PM_GPIO_DIR_OUT,
+		.output_buffer	= PM_GPIO_OUT_BUF_OPEN_DRAIN,
+		.output_value	= 0,
+		.pull		= PM_GPIO_PULL_NO,
+		.vin_sel	= PM_GPIO_VIN_S3,
+		.out_strength	= PM_GPIO_STRENGTH_LOW,
+		.function	= PM_GPIO_FUNC_1,
+		.inv_int_pol	= 1,
+	};
+
+	struct pm_gpio kypd_sns = {
+		.direction	= PM_GPIO_DIR_IN,
+		.pull		= PM_GPIO_PULL_UP_31P5,
+		.vin_sel	= PM_GPIO_VIN_S3,
+		.out_strength	= PM_GPIO_STRENGTH_NO,
+		.function	= PM_GPIO_FUNC_NORMAL,
+		.inv_int_pol	= 1,
+	};
+
+
+	if (!pdata || !pdata->num_cols || !pdata->num_rows ||
+		pdata->num_cols > PM8XXX_MAX_COLS ||
+		pdata->num_rows > PM8XXX_MAX_ROWS ||
+		pdata->num_cols < PM8XXX_MIN_COLS) {
+		dev_err(&pdev->dev, "invalid platform data\n");
+		return -EINVAL;
+	}
+
+	if (!pdata->scan_delay_ms ||
+		pdata->scan_delay_ms > MAX_SCAN_DELAY ||
+		pdata->scan_delay_ms < MIN_SCAN_DELAY ||
+		!is_power_of_2(pdata->scan_delay_ms)) {
+		dev_err(&pdev->dev, "invalid keypad scan time supplied\n");
+		return -EINVAL;
+	}
+
+	if (!pdata->row_hold_ns ||
+		pdata->row_hold_ns > MAX_ROW_HOLD_DELAY ||
+		pdata->row_hold_ns < MIN_ROW_HOLD_DELAY ||
+		((pdata->row_hold_ns % MIN_ROW_HOLD_DELAY) != 0)) {
+		dev_err(&pdev->dev, "invalid keypad row hold time supplied\n");
+		return -EINVAL;
+	}
+
+	if (!pdata->debounce_ms ||
+		((pdata->debounce_ms % 5) != 0) ||
+		pdata->debounce_ms > MAX_DEBOUNCE_TIME ||
+		pdata->debounce_ms < MIN_DEBOUNCE_TIME) {
+		dev_err(&pdev->dev, "invalid debounce time supplied\n");
+		return -EINVAL;
+	}
+
+	keymap_data = pdata->keymap_data;
+	if (!keymap_data) {
+		dev_err(&pdev->dev, "no keymap data supplied\n");
+		return -EINVAL;
+	}
+
+	kp = kzalloc(sizeof(*kp), GFP_KERNEL);
+	if (!kp)
+		return -ENOMEM;
+
+	platform_set_drvdata(pdev, kp);
+
+	kp->pdata	= pdata;
+	kp->dev		= &pdev->dev;
+
+	kp->input = input_allocate_device();
+	if (!kp->input) {
+		dev_err(&pdev->dev, "unable to allocate input device\n");
+		rc = -ENOMEM;
+		goto err_alloc_device;
+	}
+
+	kp->key_sense_irq = platform_get_irq(pdev, 0);
+	if (kp->key_sense_irq < 0) {
+		dev_err(&pdev->dev, "unable to get keypad sense irq\n");
+		rc = -ENXIO;
+		goto err_get_irq;
+	}
+
+	kp->key_stuck_irq = platform_get_irq(pdev, 1);
+	if (kp->key_stuck_irq < 0) {
+		dev_err(&pdev->dev, "unable to get keypad stuck irq\n");
+		rc = -ENXIO;
+		goto err_get_irq;
+	}
+
+	kp->input->name = pdata->input_name ? : "PMIC8XXX keypad";
+	kp->input->phys = pdata->input_phys_device ? : "pmic8xxx_keypad/input0";
+
+	kp->input->dev.parent	= &pdev->dev;
+
+	kp->input->id.bustype	= BUS_I2C;
+	kp->input->id.version	= 0x0001;
+	kp->input->id.product	= 0x0001;
+	kp->input->id.vendor	= 0x0001;
+
+	kp->input->evbit[0]	= BIT_MASK(EV_KEY);
+
+	if (pdata->rep)
+		__set_bit(EV_REP, kp->input->evbit);
+
+	kp->input->keycode	= kp->keycodes;
+	kp->input->keycodemax	= PM8XXX_MATRIX_MAX_SIZE;
+	kp->input->keycodesize	= sizeof(kp->keycodes);
+	kp->input->open		= pmic8xxx_kp_open;
+	kp->input->close	= pmic8xxx_kp_close;
+
+	matrix_keypad_build_keymap(keymap_data, PM8XXX_ROW_SHIFT,
+					kp->input->keycode, kp->input->keybit);
+
+	input_set_capability(kp->input, EV_MSC, MSC_SCAN);
+	input_set_drvdata(kp->input, kp);
+
+	/* initialize keypad state */
+	memset(kp->keystate, 0xff, sizeof(kp->keystate));
+	memset(kp->stuckstate, 0xff, sizeof(kp->stuckstate));
+
+	rc = pmic8xxx_kpd_init(kp);
+	if (rc < 0) {
+		dev_err(&pdev->dev, "unable to initialize keypad controller\n");
+		goto err_get_irq;
+	}
+
+	rc = pmic8xxx_kp_config_gpio(pdata->cols_gpio_start,
+					pdata->num_cols, kp, &kypd_sns);
+	if (rc < 0) {
+		dev_err(&pdev->dev, "unable to configure keypad sense lines\n");
+		goto err_gpio_config;
+	}
+
+	rc = pmic8xxx_kp_config_gpio(pdata->rows_gpio_start,
+					pdata->num_rows, kp, &kypd_drv);
+	if (rc < 0) {
+		dev_err(&pdev->dev, "unable to configure keypad drive lines\n");
+		goto err_gpio_config;
+	}
+
+	rc = request_any_context_irq(kp->key_sense_irq, pmic8xxx_kp_irq,
+				 IRQF_TRIGGER_RISING, "pmic-keypad", kp);
+	if (rc < 0) {
+		dev_err(&pdev->dev, "failed to request keypad sense irq\n");
+		goto err_get_irq;
+	}
+
+	rc = request_any_context_irq(kp->key_stuck_irq, pmic8xxx_kp_stuck_irq,
+				 IRQF_TRIGGER_RISING, "pmic-keypad-stuck", kp);
+	if (rc < 0) {
+		dev_err(&pdev->dev, "failed to request keypad stuck irq\n");
+		goto err_req_stuck_irq;
+	}
+
+	rc = pmic8xxx_kp_read_u8(kp, &ctrl_val, KEYP_CTRL);
+	if (rc < 0) {
+		dev_err(&pdev->dev, "failed to read KEYP_CTRL register\n");
+		goto err_pmic_reg_read;
+	}
+
+	kp->ctrl_reg = ctrl_val;
+
+	rc = input_register_device(kp->input);
+	if (rc < 0) {
+		dev_err(&pdev->dev, "unable to register keypad input device\n");
+		goto err_pmic_reg_read;
+	}
+
+	device_init_wakeup(&pdev->dev, pdata->wakeup);
+
+	return 0;
+
+err_pmic_reg_read:
+	free_irq(kp->key_stuck_irq, NULL);
+err_req_stuck_irq:
+	free_irq(kp->key_sense_irq, NULL);
+err_gpio_config:
+err_get_irq:
+	input_free_device(kp->input);
+err_alloc_device:
+	platform_set_drvdata(pdev, NULL);
+	kfree(kp);
+	return rc;
+}
+
+static int __devexit pmic8xxx_kp_remove(struct platform_device *pdev)
+{
+	struct pmic8xxx_kp *kp = platform_get_drvdata(pdev);
+
+	device_init_wakeup(&pdev->dev, 0);
+	free_irq(kp->key_stuck_irq, NULL);
+	free_irq(kp->key_sense_irq, NULL);
+	input_unregister_device(kp->input);
+	kfree(kp);
+
+	platform_set_drvdata(pdev, NULL);
+	return 0;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int pmic8xxx_kp_suspend(struct device *dev)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct pmic8xxx_kp *kp = platform_get_drvdata(pdev);
+	struct input_dev *input_dev = kp->input;
+
+	if (device_may_wakeup(dev)) {
+		enable_irq_wake(kp->key_sense_irq);
+	} else {
+		mutex_lock(&input_dev->mutex);
+
+		if (input_dev->users)
+			pmic8xxx_kp_disable(kp);
+
+		mutex_unlock(&input_dev->mutex);
+	}
+
+	return 0;
+}
+
+static int pmic8xxx_kp_resume(struct device *dev)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct pmic8xxx_kp *kp = platform_get_drvdata(pdev);
+	struct input_dev *input_dev = kp->input;
+
+	if (device_may_wakeup(dev)) {
+		disable_irq_wake(kp->key_sense_irq);
+	} else {
+		mutex_lock(&input_dev->mutex);
+
+		if (input_dev->users)
+			pmic8xxx_kp_enable(kp);
+
+		mutex_unlock(&input_dev->mutex);
+	}
+
+	return 0;
+}
+#endif
+
+static SIMPLE_DEV_PM_OPS(pm8xxx_kp_pm_ops,
+			 pmic8xxx_kp_suspend, pmic8xxx_kp_resume);
+
+static struct platform_driver pmic8xxx_kp_driver = {
+	.probe		= pmic8xxx_kp_probe,
+	.remove		= __devexit_p(pmic8xxx_kp_remove),
+	.driver		= {
+		.name = PM8XXX_KEYPAD_DEV_NAME,
+		.owner = THIS_MODULE,
+		.pm = &pm8xxx_kp_pm_ops,
+	},
+};
+
+static int __init pmic8xxx_kp_init(void)
+{
+	return platform_driver_register(&pmic8xxx_kp_driver);
+}
+module_init(pmic8xxx_kp_init);
+
+static void __exit pmic8xxx_kp_exit(void)
+{
+	platform_driver_unregister(&pmic8xxx_kp_driver);
+}
+module_exit(pmic8xxx_kp_exit);
+
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("PMIC8XXX keypad driver");
+MODULE_VERSION("1.0");
+MODULE_ALIAS("platform:pmic8xxx_keypad");
+MODULE_AUTHOR("Trilok Soni <tsoni@codeaurora.org>");
diff -druN linux-2.6.39-libre/drivers/input/keyboard/qt1070.c linux-3.0-rc7-libre/drivers/input/keyboard/qt1070.c
--- linux-2.6.39-libre/drivers/input/keyboard/qt1070.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/input/keyboard/qt1070.c	2011-07-11 19:51:52.000000000 -0400
@@ -248,6 +248,7 @@
 	{ "qt1070", 0 },
 	{ },
 };
+MODULE_DEVICE_TABLE(i2c, qt1070_id);
 
 static struct i2c_driver qt1070_driver = {
 	.driver	= {
diff -druN linux-2.6.39-libre/drivers/input/keyboard/sh_keysc.c linux-3.0-rc7-libre/drivers/input/keyboard/sh_keysc.c
--- linux-2.6.39-libre/drivers/input/keyboard/sh_keysc.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/input/keyboard/sh_keysc.c	2011-07-11 19:51:52.000000000 -0400
@@ -20,7 +20,7 @@
 #include <linux/input.h>
 #include <linux/input/sh_keysc.h>
 #include <linux/bitmap.h>
-#include <linux/clk.h>
+#include <linux/pm_runtime.h>
 #include <linux/io.h>
 #include <linux/slab.h>
 
@@ -32,12 +32,11 @@
 	[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 },
+	[SH_KEYSC_MODE_6] = { 5, 8, 8 },
 };
 
 struct sh_keysc_priv {
 	void __iomem *iomem_base;
-	struct clk *clk;
 	DECLARE_BITMAP(last_keys, SH_KEYSC_MAXKEYS);
 	struct input_dev *input;
 	struct sh_keysc_info pdata;
@@ -169,7 +168,6 @@
 	struct sh_keysc_info *pdata;
 	struct resource *res;
 	struct input_dev *input;
-	char clk_name[8];
 	int i;
 	int irq, error;
 
@@ -210,19 +208,11 @@
 		goto err1;
 	}
 
-	snprintf(clk_name, sizeof(clk_name), "keysc%d", pdev->id);
-	priv->clk = clk_get(&pdev->dev, clk_name);
-	if (IS_ERR(priv->clk)) {
-		dev_err(&pdev->dev, "cannot get clock \"%s\"\n", clk_name);
-		error = PTR_ERR(priv->clk);
-		goto err2;
-	}
-
 	priv->input = input_allocate_device();
 	if (!priv->input) {
 		dev_err(&pdev->dev, "failed to allocate input device\n");
 		error = -ENOMEM;
-		goto err3;
+		goto err2;
 	}
 
 	input = priv->input;
@@ -241,10 +231,11 @@
 	input->keycodesize = sizeof(pdata->keycodes[0]);
 	input->keycodemax = ARRAY_SIZE(pdata->keycodes);
 
-	error = request_irq(irq, sh_keysc_isr, 0, pdev->name, pdev);
+	error = request_threaded_irq(irq, NULL, sh_keysc_isr, IRQF_ONESHOT,
+				     dev_name(&pdev->dev), pdev);
 	if (error) {
 		dev_err(&pdev->dev, "failed to request IRQ\n");
-		goto err4;
+		goto err3;
 	}
 
 	for (i = 0; i < SH_KEYSC_MAXKEYS; i++)
@@ -254,10 +245,11 @@
 	error = input_register_device(input);
 	if (error) {
 		dev_err(&pdev->dev, "failed to register input device\n");
-		goto err5;
+		goto err4;
 	}
 
-	clk_enable(priv->clk);
+	pm_runtime_enable(&pdev->dev);
+	pm_runtime_get_sync(&pdev->dev);
 
 	sh_keysc_write(priv, KYCR1, (sh_keysc_mode[pdata->mode].kymd << 8) |
 		       pdata->scan_timing);
@@ -267,12 +259,10 @@
 
 	return 0;
 
- err5:
-	free_irq(irq, pdev);
  err4:
-	input_free_device(input);
+	free_irq(irq, pdev);
  err3:
-	clk_put(priv->clk);
+	input_free_device(input);
  err2:
 	iounmap(priv->iomem_base);
  err1:
@@ -292,8 +282,8 @@
 	free_irq(platform_get_irq(pdev, 0), pdev);
 	iounmap(priv->iomem_base);
 
-	clk_disable(priv->clk);
-	clk_put(priv->clk);
+	pm_runtime_put_sync(&pdev->dev);
+	pm_runtime_disable(&pdev->dev);
 
 	platform_set_drvdata(pdev, NULL);
 	kfree(priv);
@@ -301,6 +291,7 @@
 	return 0;
 }
 
+#if CONFIG_PM_SLEEP
 static int sh_keysc_suspend(struct device *dev)
 {
 	struct platform_device *pdev = to_platform_device(dev);
@@ -311,14 +302,13 @@
 	value = sh_keysc_read(priv, KYCR1);
 
 	if (device_may_wakeup(dev)) {
-		value |= 0x80;
+		sh_keysc_write(priv, KYCR1, value | 0x80);
 		enable_irq_wake(irq);
 	} else {
-		value &= ~0x80;
+		sh_keysc_write(priv, KYCR1, value & ~0x80);
+		pm_runtime_put_sync(dev);
 	}
 
-	sh_keysc_write(priv, KYCR1, value);
-
 	return 0;
 }
 
@@ -329,16 +319,17 @@
 
 	if (device_may_wakeup(dev))
 		disable_irq_wake(irq);
+	else
+		pm_runtime_get_sync(dev);
 
 	return 0;
 }
+#endif
 
-static const struct dev_pm_ops sh_keysc_dev_pm_ops = {
-	.suspend = sh_keysc_suspend,
-	.resume = sh_keysc_resume,
-};
+static SIMPLE_DEV_PM_OPS(sh_keysc_dev_pm_ops,
+			 sh_keysc_suspend, sh_keysc_resume);
 
-struct platform_driver sh_keysc_device_driver = {
+static struct platform_driver sh_keysc_device_driver = {
 	.probe		= sh_keysc_probe,
 	.remove		= __devexit_p(sh_keysc_remove),
 	.driver		= {
diff -druN linux-2.6.39-libre/drivers/input/keyboard/tegra-kbc.c linux-3.0-rc7-libre/drivers/input/keyboard/tegra-kbc.c
--- linux-2.6.39-libre/drivers/input/keyboard/tegra-kbc.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/input/keyboard/tegra-kbc.c	2011-07-11 19:51:52.000000000 -0400
@@ -66,12 +66,11 @@
 	void __iomem *mmio;
 	struct input_dev *idev;
 	unsigned int irq;
-	unsigned int wake_enable_rows;
-	unsigned int wake_enable_cols;
 	spinlock_t lock;
 	unsigned int repoll_dly;
 	unsigned long cp_dly_jiffies;
 	bool use_fn_map;
+	bool use_ghost_filter;
 	const struct tegra_kbc_platform_data *pdata;
 	unsigned short keycode[KBC_MAX_KEY * 2];
 	unsigned short current_keys[KBC_MAX_KPENT];
@@ -260,6 +259,8 @@
 	unsigned int num_down = 0;
 	unsigned long flags;
 	bool fn_keypress = false;
+	bool key_in_same_row = false;
+	bool key_in_same_col = false;
 
 	spin_lock_irqsave(&kbc->lock, flags);
 	for (i = 0; i < KBC_MAX_KPENT; i++) {
@@ -285,6 +286,34 @@
 	}
 
 	/*
+	 * Matrix keyboard designs are prone to keyboard ghosting.
+	 * Ghosting occurs if there are 3 keys such that -
+	 * any 2 of the 3 keys share a row, and any 2 of them share a column.
+	 * If so ignore the key presses for this iteration.
+	 */
+	if ((kbc->use_ghost_filter) && (num_down >= 3)) {
+		for (i = 0; i < num_down; i++) {
+			unsigned int j;
+			u8 curr_col = scancodes[i] & 0x07;
+			u8 curr_row = scancodes[i] >> KBC_ROW_SHIFT;
+
+			/*
+			 * Find 2 keys such that one key is in the same row
+			 * and the other is in the same column as the i-th key.
+			 */
+			for (j = i + 1; j < num_down; j++) {
+				u8 col = scancodes[j] & 0x07;
+				u8 row = scancodes[j] >> KBC_ROW_SHIFT;
+
+				if (col == curr_col)
+					key_in_same_col = true;
+				if (row == curr_row)
+					key_in_same_row = true;
+			}
+		}
+	}
+
+	/*
 	 * If the platform uses Fn keymaps, translate keys on a Fn keypress.
 	 * Function keycodes are KBC_MAX_KEY apart from the plain keycodes.
 	 */
@@ -297,6 +326,10 @@
 
 	spin_unlock_irqrestore(&kbc->lock, flags);
 
+	/* Ignore the key presses for this iteration? */
+	if (key_in_same_col && key_in_same_row)
+		return;
+
 	tegra_kbc_report_released_keys(kbc->idev,
 				       kbc->current_keys, kbc->num_pressed_keys,
 				       keycodes, num_down);
@@ -383,21 +416,11 @@
 	int i;
 	unsigned int rst_val;
 
-	BUG_ON(pdata->wake_cnt > KBC_MAX_KEY);
-	rst_val = (filter && pdata->wake_cnt) ? ~0 : 0;
+	/* Either mask all keys or none. */
+	rst_val = (filter && !pdata->wakeup) ? ~0 : 0;
 
 	for (i = 0; i < KBC_MAX_ROW; i++)
 		writel(rst_val, kbc->mmio + KBC_ROW0_MASK_0 + i * 4);
-
-	if (filter) {
-		for (i = 0; i < pdata->wake_cnt; i++) {
-			u32 val, addr;
-			addr = pdata->wake_cfg[i].row * 4 + KBC_ROW0_MASK_0;
-			val = readl(kbc->mmio + addr);
-			val &= ~(1 << pdata->wake_cfg[i].col);
-			writel(val, kbc->mmio + addr);
-		}
-	}
 }
 
 static void tegra_kbc_config_pins(struct tegra_kbc *kbc)
@@ -559,7 +582,6 @@
 	struct resource *res;
 	int irq;
 	int err;
-	int i;
 	int num_rows = 0;
 	unsigned int debounce_cnt;
 	unsigned int scan_time_rows;
@@ -616,13 +638,6 @@
 		goto err_iounmap;
 	}
 
-	kbc->wake_enable_rows = 0;
-	kbc->wake_enable_cols = 0;
-	for (i = 0; i < pdata->wake_cnt; i++) {
-		kbc->wake_enable_rows |= (1 << pdata->wake_cfg[i].row);
-		kbc->wake_enable_cols |= (1 << pdata->wake_cfg[i].col);
-	}
-
 	/*
 	 * The time delay between two consecutive reads of the FIFO is
 	 * the sum of the repeat time and the time taken for scanning
@@ -652,6 +667,7 @@
 		input_dev->keycodemax *= 2;
 
 	kbc->use_fn_map = pdata->use_fn_map;
+	kbc->use_ghost_filter = pdata->use_ghost_filter;
 	keymap_data = pdata->keymap_data ?: &tegra_kbc_default_keymap_data;
 	matrix_keypad_build_keymap(keymap_data, KBC_ROW_SHIFT,
 				   input_dev->keycode, input_dev->keybit);
diff -druN linux-2.6.39-libre/drivers/input/misc/ad714x.c linux-3.0-rc7-libre/drivers/input/misc/ad714x.c
--- linux-2.6.39-libre/drivers/input/misc/ad714x.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/input/misc/ad714x.c	2011-07-11 19:51:52.000000000 -0400
@@ -79,13 +79,7 @@
 struct ad714x_wheel_drv {
 	int abs_pos;
 	int flt_pos;
-	int pre_mean_value;
 	int pre_highest_stage;
-	int pre_mean_value_no_offset;
-	int mean_value;
-	int mean_value_no_offset;
-	int pos_offset;
-	int pos_ratio;
 	int highest_stage;
 	enum ad714x_device_state state;
 	struct input_dev *input;
@@ -158,10 +152,10 @@
 	unsigned short data;
 	unsigned short mask;
 
-	mask = ((1 << (end_stage + 1)) - 1) - (1 << start_stage);
+	mask = ((1 << (end_stage + 1)) - 1) - ((1 << start_stage) - 1);
 
 	ad714x->read(ad714x->dev, STG_COM_INT_EN_REG, &data);
-	data |= 1 << start_stage;
+	data |= 1 << end_stage;
 	ad714x->write(ad714x->dev, STG_COM_INT_EN_REG, data);
 
 	ad714x->read(ad714x->dev, STG_HIGH_INT_EN_REG, &data);
@@ -175,10 +169,10 @@
 	unsigned short data;
 	unsigned short mask;
 
-	mask = ((1 << (end_stage + 1)) - 1) - (1 << start_stage);
+	mask = ((1 << (end_stage + 1)) - 1) - ((1 << start_stage) - 1);
 
 	ad714x->read(ad714x->dev, STG_COM_INT_EN_REG, &data);
-	data &= ~(1 << start_stage);
+	data &= ~(1 << end_stage);
 	ad714x->write(ad714x->dev, STG_COM_INT_EN_REG, data);
 
 	ad714x->read(ad714x->dev, STG_HIGH_INT_EN_REG, &data);
@@ -404,7 +398,6 @@
 				ad714x_slider_cal_highest_stage(ad714x, idx);
 				ad714x_slider_cal_abs_pos(ad714x, idx);
 				ad714x_slider_cal_flt_pos(ad714x, idx);
-
 				input_report_abs(sw->input, ABS_X, sw->flt_pos);
 				input_report_key(sw->input, BTN_TOUCH, 1);
 			} else {
@@ -468,104 +461,41 @@
 /*
  * When the scroll wheel is activated, we compute the absolute position based
  * on the sensor values. To calculate the position, we first determine the
- * sensor that has the greatest response among the 8 sensors that constitutes
- * the scrollwheel. Then we determined the 2 sensors on either sides of the
+ * sensor that has the greatest response among the sensors that constitutes
+ * the scrollwheel. Then we determined the sensors on either sides of the
  * sensor with the highest response and we apply weights to these sensors. The
- * result of this computation gives us the mean value which defined by the
- * following formula:
- * For i= second_before_highest_stage to i= second_after_highest_stage
- *         v += Sensor response(i)*WEIGHT*(i+3)
- *         w += Sensor response(i)
- * Mean_Value=v/w
- * pos_on_scrollwheel = (Mean_Value - position_offset) / position_ratio
+ * result of this computation gives us the mean value.
  */
 
-#define WEIGHT_FACTOR 30
-/* This constant prevents the "PositionOffset" from reaching a big value */
-#define OFFSET_POSITION_CLAMP	120
 static void ad714x_wheel_cal_abs_pos(struct ad714x_chip *ad714x, int idx)
 {
 	struct ad714x_wheel_plat *hw = &ad714x->hw->wheel[idx];
 	struct ad714x_wheel_drv *sw = &ad714x->sw->wheel[idx];
 	int stage_num = hw->end_stage - hw->start_stage + 1;
-	int second_before, first_before, highest, first_after, second_after;
+	int first_before, highest, first_after;
 	int a_param, b_param;
 
-	/* Calculate Mean value */
-
-	second_before = (sw->highest_stage + stage_num - 2) % stage_num;
 	first_before = (sw->highest_stage + stage_num - 1) % stage_num;
 	highest = sw->highest_stage;
 	first_after = (sw->highest_stage + stage_num + 1) % stage_num;
-	second_after = (sw->highest_stage + stage_num + 2) % stage_num;
 
-	if (((sw->highest_stage - hw->start_stage) > 1) &&
-	    ((hw->end_stage - sw->highest_stage) > 1)) {
-		a_param = ad714x->sensor_val[second_before] *
-			(second_before - hw->start_stage + 3) +
-			ad714x->sensor_val[first_before] *
-			(second_before - hw->start_stage + 3) +
-			ad714x->sensor_val[highest] *
-			(second_before - hw->start_stage + 3) +
-			ad714x->sensor_val[first_after] *
-			(first_after - hw->start_stage + 3) +
-			ad714x->sensor_val[second_after] *
-			(second_after - hw->start_stage + 3);
-	} else {
-		a_param = ad714x->sensor_val[second_before] *
-			(second_before - hw->start_stage + 1) +
-			ad714x->sensor_val[first_before] *
-			(second_before - hw->start_stage + 2) +
-			ad714x->sensor_val[highest] *
-			(second_before - hw->start_stage + 3) +
-			ad714x->sensor_val[first_after] *
-			(first_after - hw->start_stage + 4) +
-			ad714x->sensor_val[second_after] *
-			(second_after - hw->start_stage + 5);
-	}
-	a_param *= WEIGHT_FACTOR;
-
-	b_param = ad714x->sensor_val[second_before] +
+	a_param = ad714x->sensor_val[highest] *
+		(highest - hw->start_stage) +
+		ad714x->sensor_val[first_before] *
+		(highest - hw->start_stage - 1) +
+		ad714x->sensor_val[first_after] *
+		(highest - hw->start_stage + 1);
+	b_param = ad714x->sensor_val[highest] +
 		ad714x->sensor_val[first_before] +
-		ad714x->sensor_val[highest] +
-		ad714x->sensor_val[first_after] +
-		ad714x->sensor_val[second_after];
-
-	sw->pre_mean_value = sw->mean_value;
-	sw->mean_value = a_param / b_param;
-
-	/* Calculate the offset */
-
-	if ((sw->pre_highest_stage == hw->end_stage) &&
-			(sw->highest_stage == hw->start_stage))
-		sw->pos_offset = sw->mean_value;
-	else if ((sw->pre_highest_stage == hw->start_stage) &&
-			(sw->highest_stage == hw->end_stage))
-		sw->pos_offset = sw->pre_mean_value;
-
-	if (sw->pos_offset > OFFSET_POSITION_CLAMP)
-		sw->pos_offset = OFFSET_POSITION_CLAMP;
-
-	/* Calculate the mean value without the offset */
-
-	sw->pre_mean_value_no_offset = sw->mean_value_no_offset;
-	sw->mean_value_no_offset = sw->mean_value - sw->pos_offset;
-	if (sw->mean_value_no_offset < 0)
-		sw->mean_value_no_offset = 0;
+		ad714x->sensor_val[first_after];
 
-	/* Calculate ratio to scale down to NUMBER_OF_WANTED_POSITIONS */
+	sw->abs_pos = ((hw->max_coord / (hw->end_stage - hw->start_stage)) *
+			a_param) / b_param;
 
-	if ((sw->pre_highest_stage == hw->end_stage) &&
-			(sw->highest_stage == hw->start_stage))
-		sw->pos_ratio = (sw->pre_mean_value_no_offset * 100) /
-			hw->max_coord;
-	else if ((sw->pre_highest_stage == hw->start_stage) &&
-			(sw->highest_stage == hw->end_stage))
-		sw->pos_ratio = (sw->mean_value_no_offset * 100) /
-			hw->max_coord;
-	sw->abs_pos = (sw->mean_value_no_offset * 100) / sw->pos_ratio;
 	if (sw->abs_pos > hw->max_coord)
 		sw->abs_pos = hw->max_coord;
+	else if (sw->abs_pos < 0)
+		sw->abs_pos = 0;
 }
 
 static void ad714x_wheel_cal_flt_pos(struct ad714x_chip *ad714x, int idx)
@@ -639,9 +569,8 @@
 				ad714x_wheel_cal_highest_stage(ad714x, idx);
 				ad714x_wheel_cal_abs_pos(ad714x, idx);
 				ad714x_wheel_cal_flt_pos(ad714x, idx);
-
 				input_report_abs(sw->input, ABS_WHEEL,
-					sw->abs_pos);
+					sw->flt_pos);
 				input_report_key(sw->input, BTN_TOUCH, 1);
 			} else {
 				/* When the user lifts off the sensor, configure
@@ -1149,6 +1078,8 @@
 			input[alloc_idx]->id.bustype = bus_type;
 			input[alloc_idx]->id.product = ad714x->product;
 			input[alloc_idx]->id.version = ad714x->version;
+			input[alloc_idx]->name = "ad714x_captouch_slider";
+			input[alloc_idx]->dev.parent = dev;
 
 			error = input_register_device(input[alloc_idx]);
 			if (error)
@@ -1179,6 +1110,8 @@
 			input[alloc_idx]->id.bustype = bus_type;
 			input[alloc_idx]->id.product = ad714x->product;
 			input[alloc_idx]->id.version = ad714x->version;
+			input[alloc_idx]->name = "ad714x_captouch_wheel";
+			input[alloc_idx]->dev.parent = dev;
 
 			error = input_register_device(input[alloc_idx]);
 			if (error)
@@ -1212,6 +1145,8 @@
 			input[alloc_idx]->id.bustype = bus_type;
 			input[alloc_idx]->id.product = ad714x->product;
 			input[alloc_idx]->id.version = ad714x->version;
+			input[alloc_idx]->name = "ad714x_captouch_pad";
+			input[alloc_idx]->dev.parent = dev;
 
 			error = input_register_device(input[alloc_idx]);
 			if (error)
@@ -1240,6 +1175,8 @@
 		input[alloc_idx]->id.bustype = bus_type;
 		input[alloc_idx]->id.product = ad714x->product;
 		input[alloc_idx]->id.version = ad714x->version;
+		input[alloc_idx]->name = "ad714x_captouch_button";
+		input[alloc_idx]->dev.parent = dev;
 
 		error = input_register_device(input[alloc_idx]);
 		if (error)
@@ -1249,7 +1186,9 @@
 	}
 
 	error = request_threaded_irq(ad714x->irq, NULL, ad714x_interrupt_thread,
-			IRQF_TRIGGER_FALLING, "ad714x_captouch", ad714x);
+				plat_data->irqflags ?
+					plat_data->irqflags : IRQF_TRIGGER_FALLING,
+				"ad714x_captouch", ad714x);
 	if (error) {
 		dev_err(dev, "can't allocate irq %d\n", ad714x->irq);
 		goto err_unreg_dev;
diff -druN linux-2.6.39-libre/drivers/input/misc/ati_remote2.c linux-3.0-rc7-libre/drivers/input/misc/ati_remote2.c
--- linux-2.6.39-libre/drivers/input/misc/ati_remote2.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/input/misc/ati_remote2.c	2011-07-11 19:51:52.000000000 -0400
@@ -737,14 +737,17 @@
 
 	mutex_lock(&ati_remote2_mutex);
 
-	if (mask != ar2->channel_mask && !ati_remote2_setup(ar2, mask))
-		ar2->channel_mask = mask;
+	if (mask != ar2->channel_mask) {
+		r = ati_remote2_setup(ar2, mask);
+		if (!r)
+			ar2->channel_mask = mask;
+	}
 
 	mutex_unlock(&ati_remote2_mutex);
 
 	usb_autopm_put_interface(ar2->intf[0]);
 
-	return count;
+	return r ? r : count;
 }
 
 static ssize_t ati_remote2_show_mode_mask(struct device *dev,
diff -druN linux-2.6.39-libre/drivers/input/misc/Kconfig linux-3.0-rc7-libre/drivers/input/misc/Kconfig
--- linux-2.6.39-libre/drivers/input/misc/Kconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/input/misc/Kconfig	2011-07-11 19:51:52.000000000 -0400
@@ -330,6 +330,17 @@
 	  To compile this driver as a module, choose M here: the module will be
 	  called pwm-beeper.
 
+config INPUT_PMIC8XXX_PWRKEY
+	tristate "PMIC8XXX power key support"
+	depends on MFD_PM8XXX
+	help
+	  Say Y here if you want support for the PMIC8XXX power key.
+
+	  If unsure, say N.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called pmic8xxx-pwrkey.
+
 config INPUT_GPIO_ROTARY_ENCODER
 	tristate "Rotary encoders connected to GPIO pins"
 	depends on GPIOLIB && GENERIC_GPIO
diff -druN linux-2.6.39-libre/drivers/input/misc/Makefile linux-3.0-rc7-libre/drivers/input/misc/Makefile
--- linux-2.6.39-libre/drivers/input/misc/Makefile	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/input/misc/Makefile	2011-07-11 19:51:52.000000000 -0400
@@ -33,6 +33,7 @@
 obj-$(CONFIG_INPUT_PCSPKR)		+= pcspkr.o
 obj-$(CONFIG_INPUT_POWERMATE)		+= powermate.o
 obj-$(CONFIG_INPUT_PWM_BEEPER)		+= pwm-beeper.o
+obj-$(CONFIG_INPUT_PMIC8XXX_PWRKEY)	+= pmic8xxx-pwrkey.o
 obj-$(CONFIG_INPUT_RB532_BUTTON)	+= rb532_button.o
 obj-$(CONFIG_INPUT_GPIO_ROTARY_ENCODER)	+= rotary_encoder.o
 obj-$(CONFIG_INPUT_SGI_BTNS)		+= sgi_btns.o
diff -druN linux-2.6.39-libre/drivers/input/misc/pmic8xxx-pwrkey.c linux-3.0-rc7-libre/drivers/input/misc/pmic8xxx-pwrkey.c
--- linux-2.6.39-libre/drivers/input/misc/pmic8xxx-pwrkey.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/input/misc/pmic8xxx-pwrkey.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,232 @@
+/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/slab.h>
+#include <linux/input.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+#include <linux/log2.h>
+
+#include <linux/mfd/pm8xxx/core.h>
+#include <linux/input/pmic8xxx-pwrkey.h>
+
+#define PON_CNTL_1 0x1C
+#define PON_CNTL_PULL_UP BIT(7)
+#define PON_CNTL_TRIG_DELAY_MASK (0x7)
+
+/**
+ * struct pmic8xxx_pwrkey - pmic8xxx pwrkey information
+ * @key_press_irq: key press irq number
+ */
+struct pmic8xxx_pwrkey {
+	struct input_dev *pwr;
+	int key_press_irq;
+};
+
+static irqreturn_t pwrkey_press_irq(int irq, void *_pwrkey)
+{
+	struct pmic8xxx_pwrkey *pwrkey = _pwrkey;
+
+	input_report_key(pwrkey->pwr, KEY_POWER, 1);
+	input_sync(pwrkey->pwr);
+
+	return IRQ_HANDLED;
+}
+
+static irqreturn_t pwrkey_release_irq(int irq, void *_pwrkey)
+{
+	struct pmic8xxx_pwrkey *pwrkey = _pwrkey;
+
+	input_report_key(pwrkey->pwr, KEY_POWER, 0);
+	input_sync(pwrkey->pwr);
+
+	return IRQ_HANDLED;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int pmic8xxx_pwrkey_suspend(struct device *dev)
+{
+	struct pmic8xxx_pwrkey *pwrkey = dev_get_drvdata(dev);
+
+	if (device_may_wakeup(dev))
+		enable_irq_wake(pwrkey->key_press_irq);
+
+	return 0;
+}
+
+static int pmic8xxx_pwrkey_resume(struct device *dev)
+{
+	struct pmic8xxx_pwrkey *pwrkey = dev_get_drvdata(dev);
+
+	if (device_may_wakeup(dev))
+		disable_irq_wake(pwrkey->key_press_irq);
+
+	return 0;
+}
+#endif
+
+static SIMPLE_DEV_PM_OPS(pm8xxx_pwr_key_pm_ops,
+		pmic8xxx_pwrkey_suspend, pmic8xxx_pwrkey_resume);
+
+static int __devinit pmic8xxx_pwrkey_probe(struct platform_device *pdev)
+{
+	struct input_dev *pwr;
+	int key_release_irq = platform_get_irq(pdev, 0);
+	int key_press_irq = platform_get_irq(pdev, 1);
+	int err;
+	unsigned int delay;
+	u8 pon_cntl;
+	struct pmic8xxx_pwrkey *pwrkey;
+	const struct pm8xxx_pwrkey_platform_data *pdata =
+					dev_get_platdata(&pdev->dev);
+
+	if (!pdata) {
+		dev_err(&pdev->dev, "power key platform data not supplied\n");
+		return -EINVAL;
+	}
+
+	if (pdata->kpd_trigger_delay_us > 62500) {
+		dev_err(&pdev->dev, "invalid power key trigger delay\n");
+		return -EINVAL;
+	}
+
+	pwrkey = kzalloc(sizeof(*pwrkey), GFP_KERNEL);
+	if (!pwrkey)
+		return -ENOMEM;
+
+	pwr = input_allocate_device();
+	if (!pwr) {
+		dev_dbg(&pdev->dev, "Can't allocate power button\n");
+		err = -ENOMEM;
+		goto free_pwrkey;
+	}
+
+	input_set_capability(pwr, EV_KEY, KEY_POWER);
+
+	pwr->name = "pmic8xxx_pwrkey";
+	pwr->phys = "pmic8xxx_pwrkey/input0";
+	pwr->dev.parent = &pdev->dev;
+
+	delay = (pdata->kpd_trigger_delay_us << 10) / USEC_PER_SEC;
+	delay = 1 + ilog2(delay);
+
+	err = pm8xxx_readb(pdev->dev.parent, PON_CNTL_1, &pon_cntl);
+	if (err < 0) {
+		dev_err(&pdev->dev, "failed reading PON_CNTL_1 err=%d\n", err);
+		goto free_input_dev;
+	}
+
+	pon_cntl &= ~PON_CNTL_TRIG_DELAY_MASK;
+	pon_cntl |= (delay & PON_CNTL_TRIG_DELAY_MASK);
+	if (pdata->pull_up)
+		pon_cntl |= PON_CNTL_PULL_UP;
+	else
+		pon_cntl &= ~PON_CNTL_PULL_UP;
+
+	err = pm8xxx_writeb(pdev->dev.parent, PON_CNTL_1, pon_cntl);
+	if (err < 0) {
+		dev_err(&pdev->dev, "failed writing PON_CNTL_1 err=%d\n", err);
+		goto free_input_dev;
+	}
+
+	err = input_register_device(pwr);
+	if (err) {
+		dev_dbg(&pdev->dev, "Can't register power key: %d\n", err);
+		goto free_input_dev;
+	}
+
+	pwrkey->key_press_irq = key_press_irq;
+	pwrkey->pwr = pwr;
+
+	platform_set_drvdata(pdev, pwrkey);
+
+	err = request_irq(key_press_irq, pwrkey_press_irq,
+		IRQF_TRIGGER_RISING, "pmic8xxx_pwrkey_press", pwrkey);
+	if (err < 0) {
+		dev_dbg(&pdev->dev, "Can't get %d IRQ for pwrkey: %d\n",
+				 key_press_irq, err);
+		goto unreg_input_dev;
+	}
+
+	err = request_irq(key_release_irq, pwrkey_release_irq,
+		 IRQF_TRIGGER_RISING, "pmic8xxx_pwrkey_release", pwrkey);
+	if (err < 0) {
+		dev_dbg(&pdev->dev, "Can't get %d IRQ for pwrkey: %d\n",
+				 key_release_irq, err);
+
+		goto free_press_irq;
+	}
+
+	device_init_wakeup(&pdev->dev, pdata->wakeup);
+
+	return 0;
+
+free_press_irq:
+	free_irq(key_press_irq, NULL);
+unreg_input_dev:
+	platform_set_drvdata(pdev, NULL);
+	input_unregister_device(pwr);
+	pwr = NULL;
+free_input_dev:
+	input_free_device(pwr);
+free_pwrkey:
+	kfree(pwrkey);
+	return err;
+}
+
+static int __devexit pmic8xxx_pwrkey_remove(struct platform_device *pdev)
+{
+	struct pmic8xxx_pwrkey *pwrkey = platform_get_drvdata(pdev);
+	int key_release_irq = platform_get_irq(pdev, 0);
+	int key_press_irq = platform_get_irq(pdev, 1);
+
+	device_init_wakeup(&pdev->dev, 0);
+
+	free_irq(key_press_irq, pwrkey);
+	free_irq(key_release_irq, pwrkey);
+	input_unregister_device(pwrkey->pwr);
+	platform_set_drvdata(pdev, NULL);
+	kfree(pwrkey);
+
+	return 0;
+}
+
+static struct platform_driver pmic8xxx_pwrkey_driver = {
+	.probe		= pmic8xxx_pwrkey_probe,
+	.remove		= __devexit_p(pmic8xxx_pwrkey_remove),
+	.driver		= {
+		.name	= PM8XXX_PWRKEY_DEV_NAME,
+		.owner	= THIS_MODULE,
+		.pm	= &pm8xxx_pwr_key_pm_ops,
+	},
+};
+
+static int __init pmic8xxx_pwrkey_init(void)
+{
+	return platform_driver_register(&pmic8xxx_pwrkey_driver);
+}
+module_init(pmic8xxx_pwrkey_init);
+
+static void __exit pmic8xxx_pwrkey_exit(void)
+{
+	platform_driver_unregister(&pmic8xxx_pwrkey_driver);
+}
+module_exit(pmic8xxx_pwrkey_exit);
+
+MODULE_ALIAS("platform:pmic8xxx_pwrkey");
+MODULE_DESCRIPTION("PMIC8XXX Power Key driver");
+MODULE_LICENSE("GPL v2");
+MODULE_AUTHOR("Trilok Soni <tsoni@codeaurora.org>");
diff -druN linux-2.6.39-libre/drivers/input/misc/rotary_encoder.c linux-3.0-rc7-libre/drivers/input/misc/rotary_encoder.c
--- linux-2.6.39-libre/drivers/input/misc/rotary_encoder.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/input/misc/rotary_encoder.c	2011-07-11 19:51:52.000000000 -0400
@@ -2,6 +2,7 @@
  * rotary_encoder.c
  *
  * (c) 2009 Daniel Mack <daniel@caiaq.de>
+ * Copyright (C) 2011 Johan Hovold <jhovold@gmail.com>
  *
  * state machine code inspired by code from Tim Ruetz
  *
@@ -38,52 +39,66 @@
 
 	bool armed;
 	unsigned char dir;	/* 0 - clockwise, 1 - CCW */
+
+	char last_stable;
 };
 
-static irqreturn_t rotary_encoder_irq(int irq, void *dev_id)
+static int rotary_encoder_get_state(struct rotary_encoder_platform_data *pdata)
 {
-	struct rotary_encoder *encoder = dev_id;
-	struct rotary_encoder_platform_data *pdata = encoder->pdata;
 	int a = !!gpio_get_value(pdata->gpio_a);
 	int b = !!gpio_get_value(pdata->gpio_b);
-	int state;
 
 	a ^= pdata->inverted_a;
 	b ^= pdata->inverted_b;
-	state = (a << 1) | b;
 
-	switch (state) {
+	return ((a << 1) | b);
+}
 
-	case 0x0:
-		if (!encoder->armed)
-			break;
+static void rotary_encoder_report_event(struct rotary_encoder *encoder)
+{
+	struct rotary_encoder_platform_data *pdata = encoder->pdata;
 
-		if (pdata->relative_axis) {
-			input_report_rel(encoder->input, pdata->axis,
-					 encoder->dir ? -1 : 1);
-		} else {
-			unsigned int pos = encoder->pos;
+	if (pdata->relative_axis) {
+		input_report_rel(encoder->input,
+				 pdata->axis, encoder->dir ? -1 : 1);
+	} else {
+		unsigned int pos = encoder->pos;
 
-			if (encoder->dir) {
-				/* turning counter-clockwise */
-				if (pdata->rollover)
-					pos += pdata->steps;
-				if (pos)
-					pos--;
-			} else {
-				/* turning clockwise */
-				if (pdata->rollover || pos < pdata->steps)
-					pos++;
-			}
+		if (encoder->dir) {
+			/* turning counter-clockwise */
 			if (pdata->rollover)
-				pos %= pdata->steps;
-			encoder->pos = pos;
-			input_report_abs(encoder->input, pdata->axis,
-					 encoder->pos);
+				pos += pdata->steps;
+			if (pos)
+				pos--;
+		} else {
+			/* turning clockwise */
+			if (pdata->rollover || pos < pdata->steps)
+				pos++;
 		}
-		input_sync(encoder->input);
 
-		encoder->armed = false;
+		if (pdata->rollover)
+			pos %= pdata->steps;
+
+		encoder->pos = pos;
+		input_report_abs(encoder->input, pdata->axis, encoder->pos);
+	}
+
+	input_sync(encoder->input);
+}
+
+static irqreturn_t rotary_encoder_irq(int irq, void *dev_id)
+{
+	struct rotary_encoder *encoder = dev_id;
+	int state;
+
+	state = rotary_encoder_get_state(encoder->pdata);
+
+	switch (state) {
+	case 0x0:
+		if (encoder->armed) {
+			rotary_encoder_report_event(encoder);
+			encoder->armed = false;
+		}
 		break;
 
 	case 0x1:
@@ -100,11 +115,37 @@
 	return IRQ_HANDLED;
 }
 
+static irqreturn_t rotary_encoder_half_period_irq(int irq, void *dev_id)
+{
+	struct rotary_encoder *encoder = dev_id;
+	int state;
+
+	state = rotary_encoder_get_state(encoder->pdata);
+
+	switch (state) {
+	case 0x00:
+	case 0x03:
+		if (state != encoder->last_stable) {
+			rotary_encoder_report_event(encoder);
+			encoder->last_stable = state;
+		}
+		break;
+
+	case 0x01:
+	case 0x02:
+		encoder->dir = (encoder->last_stable + state) & 0x01;
+		break;
+	}
+
+	return IRQ_HANDLED;
+}
+
 static int __devinit rotary_encoder_probe(struct platform_device *pdev)
 {
 	struct rotary_encoder_platform_data *pdata = pdev->dev.platform_data;
 	struct rotary_encoder *encoder;
 	struct input_dev *input;
+	irq_handler_t handler;
 	int err;
 
 	if (!pdata) {
@@ -175,7 +216,14 @@
 	}
 
 	/* request the IRQs */
-	err = request_irq(encoder->irq_a, &rotary_encoder_irq,
+	if (pdata->half_period) {
+		handler = &rotary_encoder_half_period_irq;
+		encoder->last_stable = rotary_encoder_get_state(pdata);
+	} else {
+		handler = &rotary_encoder_irq;
+	}
+
+	err = request_irq(encoder->irq_a, handler,
 			  IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
 			  DRV_NAME, encoder);
 	if (err) {
@@ -184,7 +232,7 @@
 		goto exit_free_gpio_b;
 	}
 
-	err = request_irq(encoder->irq_b, &rotary_encoder_irq,
+	err = request_irq(encoder->irq_b, handler,
 			  IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
 			  DRV_NAME, encoder);
 	if (err) {
@@ -252,6 +300,5 @@
 
 MODULE_ALIAS("platform:" DRV_NAME);
 MODULE_DESCRIPTION("GPIO rotary encoder driver");
-MODULE_AUTHOR("Daniel Mack <daniel@caiaq.de>");
+MODULE_AUTHOR("Daniel Mack <daniel@caiaq.de>, Johan Hovold");
 MODULE_LICENSE("GPL v2");
-
diff -druN linux-2.6.39-libre/drivers/input/misc/twl4030-pwrbutton.c linux-3.0-rc7-libre/drivers/input/misc/twl4030-pwrbutton.c
--- linux-2.6.39-libre/drivers/input/misc/twl4030-pwrbutton.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/input/misc/twl4030-pwrbutton.c	2011-07-11 19:51:52.000000000 -0400
@@ -89,7 +89,7 @@
 	return 0;
 
 free_irq:
-	free_irq(irq, NULL);
+	free_irq(irq, pwr);
 free_input_dev:
 	input_free_device(pwr);
 	return err;
diff -druN linux-2.6.39-libre/drivers/input/misc/twl4030-vibra.c linux-3.0-rc7-libre/drivers/input/misc/twl4030-vibra.c
--- linux-2.6.39-libre/drivers/input/misc/twl4030-vibra.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/input/misc/twl4030-vibra.c	2011-07-11 19:51:52.000000000 -0400
@@ -29,7 +29,6 @@
 #include <linux/workqueue.h>
 #include <linux/i2c/twl.h>
 #include <linux/mfd/twl4030-codec.h>
-#include <linux/mfd/core.h>
 #include <linux/input.h>
 #include <linux/slab.h>
 
@@ -197,7 +196,7 @@
 
 static int __devinit twl4030_vibra_probe(struct platform_device *pdev)
 {
-	struct twl4030_codec_vibra_data *pdata = mfd_get_data(pdev);
+	struct twl4030_codec_vibra_data *pdata = pdev->dev.platform_data;
 	struct vibra_info *info;
 	int ret;
 
diff -druN linux-2.6.39-libre/drivers/input/mouse/atarimouse.c linux-3.0-rc7-libre/drivers/input/mouse/atarimouse.c
--- linux-2.6.39-libre/drivers/input/mouse/atarimouse.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/input/mouse/atarimouse.c	2011-07-11 19:51:52.000000000 -0400
@@ -77,15 +77,15 @@
 #endif
 
 	/* only relative events get here */
-	dx =  buf[1];
-	dy = -buf[2];
+	dx = buf[1];
+	dy = buf[2];
 
 	input_report_rel(atamouse_dev, REL_X, dx);
 	input_report_rel(atamouse_dev, REL_Y, dy);
 
-	input_report_key(atamouse_dev, BTN_LEFT,   buttons & 0x1);
+	input_report_key(atamouse_dev, BTN_LEFT,   buttons & 0x4);
 	input_report_key(atamouse_dev, BTN_MIDDLE, buttons & 0x2);
-	input_report_key(atamouse_dev, BTN_RIGHT,  buttons & 0x4);
+	input_report_key(atamouse_dev, BTN_RIGHT,  buttons & 0x1);
 
 	input_sync(atamouse_dev);
 
@@ -108,7 +108,7 @@
 static void atamouse_close(struct input_dev *dev)
 {
 	ikbd_mouse_disable();
-	atari_mouse_interrupt_hook = NULL;
+	atari_input_mouse_interrupt_hook = NULL;
 }
 
 static int __init atamouse_init(void)
@@ -118,8 +118,9 @@
 	if (!MACH_IS_ATARI || !ATARIHW_PRESENT(ST_MFP))
 		return -ENODEV;
 
-	if (!atari_keyb_init())
-		return -ENODEV;
+	error = atari_keyb_init();
+	if (error)
+		return error;
 
 	atamouse_dev = input_allocate_device();
 	if (!atamouse_dev)
diff -druN linux-2.6.39-libre/drivers/input/mouse/elantech.c linux-3.0-rc7-libre/drivers/input/mouse/elantech.c
--- linux-2.6.39-libre/drivers/input/mouse/elantech.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/input/mouse/elantech.c	2011-07-11 19:51:52.000000000 -0400
@@ -16,6 +16,7 @@
 #include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/input.h>
+#include <linux/input/mt.h>
 #include <linux/serio.h>
 #include <linux/libps2.h>
 #include "psmouse.h"
@@ -242,15 +243,37 @@
 	input_sync(dev);
 }
 
+static void elantech_set_slot(struct input_dev *dev, int slot, bool active,
+			      unsigned int x, unsigned int y)
+{
+	input_mt_slot(dev, slot);
+	input_mt_report_slot_state(dev, MT_TOOL_FINGER, active);
+	if (active) {
+		input_report_abs(dev, ABS_MT_POSITION_X, x);
+		input_report_abs(dev, ABS_MT_POSITION_Y, y);
+	}
+}
+
+/* x1 < x2 and y1 < y2 when two fingers, x = y = 0 when not pressed */
+static void elantech_report_semi_mt_data(struct input_dev *dev,
+					 unsigned int num_fingers,
+					 unsigned int x1, unsigned int y1,
+					 unsigned int x2, unsigned int y2)
+{
+	elantech_set_slot(dev, 0, num_fingers != 0, x1, y1);
+	elantech_set_slot(dev, 1, num_fingers == 2, x2, y2);
+}
+
 /*
  * Interpret complete data packets and report absolute mode input events for
  * hardware version 2. (6 byte packets)
  */
 static void elantech_report_absolute_v2(struct psmouse *psmouse)
 {
+	struct elantech_data *etd = psmouse->private;
 	struct input_dev *dev = psmouse->dev;
 	unsigned char *packet = psmouse->packet;
-	int fingers, x1, y1, x2, y2;
+	unsigned int fingers, x1 = 0, y1 = 0, x2 = 0, y2 = 0, width = 0, pres = 0;
 
 	/* byte 0: n1  n0   .   .   .   .   R   L */
 	fingers = (packet[0] & 0xc0) >> 6;
@@ -270,14 +293,18 @@
 		 * 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]);
+		x1 = ((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]));
+		y1 = ETP_YMAX_V2 - (((packet[4] & 0x03) << 8) | packet[5]);
+
+		input_report_abs(dev, ABS_X, x1);
+		input_report_abs(dev, ABS_Y, y1);
+
+		pres = (packet[1] & 0xf0) | ((packet[4] & 0xf0) >> 4);
+		width = ((packet[0] & 0x30) >> 2) | ((packet[3] & 0x30) >> 4);
 		break;
 
 	case 2:
@@ -303,23 +330,24 @@
 		 */
 		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
-		 */
-		input_report_abs(dev, ABS_HAT0X, x1);
-		input_report_abs(dev, ABS_HAT0Y, y1);
-		input_report_abs(dev, ABS_HAT1X, x2);
-		input_report_abs(dev, ABS_HAT1Y, y2);
+
+		/* Unknown so just report sensible values */
+		pres = 127;
+		width = 7;
 		break;
 	}
 
+	elantech_report_semi_mt_data(dev, fingers, x1, y1, x2, y2);
 	input_report_key(dev, BTN_TOOL_FINGER, fingers == 1);
 	input_report_key(dev, BTN_TOOL_DOUBLETAP, fingers == 2);
 	input_report_key(dev, BTN_TOOL_TRIPLETAP, fingers == 3);
 	input_report_key(dev, BTN_TOOL_QUADTAP, fingers == 4);
 	input_report_key(dev, BTN_LEFT, packet[0] & 0x01);
 	input_report_key(dev, BTN_RIGHT, packet[0] & 0x02);
+	if (etd->reports_pressure) {
+		input_report_abs(dev, ABS_PRESSURE, pres);
+		input_report_abs(dev, ABS_TOOL_WIDTH, width);
+	}
 
 	input_sync(dev);
 }
@@ -478,10 +506,16 @@
 		__set_bit(BTN_TOOL_QUADTAP, dev->keybit);
 		input_set_abs_params(dev, ABS_X, ETP_XMIN_V2, ETP_XMAX_V2, 0, 0);
 		input_set_abs_params(dev, ABS_Y, ETP_YMIN_V2, ETP_YMAX_V2, 0, 0);
-		input_set_abs_params(dev, ABS_HAT0X, ETP_2FT_XMIN, ETP_2FT_XMAX, 0, 0);
-		input_set_abs_params(dev, ABS_HAT0Y, ETP_2FT_YMIN, ETP_2FT_YMAX, 0, 0);
-		input_set_abs_params(dev, ABS_HAT1X, ETP_2FT_XMIN, ETP_2FT_XMAX, 0, 0);
-		input_set_abs_params(dev, ABS_HAT1Y, ETP_2FT_YMIN, ETP_2FT_YMAX, 0, 0);
+		if (etd->reports_pressure) {
+			input_set_abs_params(dev, ABS_PRESSURE, ETP_PMIN_V2,
+					     ETP_PMAX_V2, 0, 0);
+			input_set_abs_params(dev, ABS_TOOL_WIDTH, ETP_WMIN_V2,
+					     ETP_WMAX_V2, 0, 0);
+		}
+		__set_bit(INPUT_PROP_SEMI_MT, dev->propbit);
+		input_mt_init_slots(dev, 2);
+		input_set_abs_params(dev, ABS_MT_POSITION_X, ETP_XMIN_V2, ETP_XMAX_V2, 0, 0);
+		input_set_abs_params(dev, ABS_MT_POSITION_Y, ETP_YMIN_V2, ETP_YMAX_V2, 0, 0);
 		break;
 	}
 }
@@ -725,6 +759,10 @@
 		etd->debug = 1;
 		/* Don't know how to do parity checking for version 2 */
 		etd->paritycheck = 0;
+
+		if (etd->fw_version >= 0x020800)
+			etd->reports_pressure = true;
+
 	} else {
 		etd->hw_version = 1;
 		etd->paritycheck = 1;
diff -druN linux-2.6.39-libre/drivers/input/mouse/elantech.h linux-3.0-rc7-libre/drivers/input/mouse/elantech.h
--- linux-2.6.39-libre/drivers/input/mouse/elantech.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/input/mouse/elantech.h	2011-07-11 19:51:52.000000000 -0400
@@ -77,6 +77,11 @@
 #define ETP_YMIN_V2			(   0 + ETP_EDGE_FUZZ_V2)
 #define ETP_YMAX_V2			( 768 - ETP_EDGE_FUZZ_V2)
 
+#define ETP_PMIN_V2			0
+#define ETP_PMAX_V2			255
+#define ETP_WMIN_V2			0
+#define ETP_WMAX_V2			15
+
 /*
  * For two finger touches the coordinate of each finger gets reported
  * separately but with reduced resolution.
@@ -102,6 +107,7 @@
 	unsigned char capabilities;
 	bool paritycheck;
 	bool jumpy_cursor;
+	bool reports_pressure;
 	unsigned char hw_version;
 	unsigned int fw_version;
 	unsigned int single_finger_reports;
diff -druN linux-2.6.39-libre/drivers/input/mousedev.c linux-3.0-rc7-libre/drivers/input/mousedev.c
--- linux-2.6.39-libre/drivers/input/mousedev.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/input/mousedev.c	2011-07-11 19:51:52.000000000 -0400
@@ -187,7 +187,7 @@
 		if (size == 0)
 			size = xres ? : 1;
 
-		clamp(value, min, max);
+		value = clamp(value, min, max);
 
 		mousedev->packet.x = ((value - min) * xres) / size;
 		mousedev->packet.abs_event = 1;
@@ -201,7 +201,7 @@
 		if (size == 0)
 			size = yres ? : 1;
 
-		clamp(value, min, max);
+		value = clamp(value, min, max);
 
 		mousedev->packet.y = yres - ((value - min) * yres) / size;
 		mousedev->packet.abs_event = 1;
@@ -508,7 +508,6 @@
 	spin_lock(&mousedev->client_lock);
 	list_add_tail_rcu(&client->node, &mousedev->client_list);
 	spin_unlock(&mousedev->client_lock);
-	synchronize_rcu();
 }
 
 static void mousedev_detach_client(struct mousedev *mousedev,
diff -druN linux-2.6.39-libre/drivers/input/touchscreen/ads7846.c linux-3.0-rc7-libre/drivers/input/touchscreen/ads7846.c
--- linux-2.6.39-libre/drivers/input/touchscreen/ads7846.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/input/touchscreen/ads7846.c	2011-07-11 19:51:52.000000000 -0400
@@ -109,6 +109,7 @@
 	u16			pressure_max;
 
 	bool			swap_xy;
+	bool			use_internal;
 
 	struct ads7846_packet	*packet;
 
@@ -307,7 +308,6 @@
 	struct ads7846 *ts = dev_get_drvdata(dev);
 	struct ser_req *req;
 	int status;
-	int use_internal;
 
 	req = kzalloc(sizeof *req, GFP_KERNEL);
 	if (!req)
@@ -315,11 +315,8 @@
 
 	spi_message_init(&req->msg);
 
-	/* FIXME boards with ads7846 might use external vref instead ... */
-	use_internal = (ts->model == 7846);
-
 	/* maybe turn on internal vREF, and let it settle */
-	if (use_internal) {
+	if (ts->use_internal) {
 		req->ref_on = REF_ON;
 		req->xfer[0].tx_buf = &req->ref_on;
 		req->xfer[0].len = 1;
@@ -331,8 +328,14 @@
 		/* for 1uF, settle for 800 usec; no cap, 100 usec.  */
 		req->xfer[1].delay_usecs = ts->vref_delay_usecs;
 		spi_message_add_tail(&req->xfer[1], &req->msg);
+
+		/* Enable reference voltage */
+		command |= ADS_PD10_REF_ON;
 	}
 
+	/* Enable ADC in every case */
+	command |= ADS_PD10_ADC_ON;
+
 	/* take sample */
 	req->command = (u8) command;
 	req->xfer[2].tx_buf = &req->command;
@@ -416,7 +419,7 @@
 { \
 	struct ads7846 *ts = dev_get_drvdata(dev); \
 	ssize_t v = ads7846_read12_ser(dev, \
-			READ_12BIT_SER(var) | ADS_PD10_ALL_ON); \
+			READ_12BIT_SER(var)); \
 	if (v < 0) \
 		return v; \
 	return sprintf(buf, "%u\n", adjust(ts, v)); \
@@ -509,6 +512,7 @@
 		if (!ts->vref_mv) {
 			dev_dbg(&spi->dev, "assuming 2.5V internal vREF\n");
 			ts->vref_mv = 2500;
+			ts->use_internal = true;
 		}
 		break;
 	case 7845:
@@ -969,6 +973,13 @@
 				pdata->gpio_pendown);
 			return err;
 		}
+		err = gpio_direction_input(pdata->gpio_pendown);
+		if (err) {
+			dev_err(&spi->dev, "failed to setup pendown GPIO%d\n",
+				pdata->gpio_pendown);
+			gpio_free(pdata->gpio_pendown);
+			return err;
+		}
 
 		ts->gpio_pendown = pdata->gpio_pendown;
 
@@ -1340,8 +1351,7 @@
 	if (ts->model == 7845)
 		ads7845_read12_ser(&spi->dev, PWRDOWN);
 	else
-		(void) ads7846_read12_ser(&spi->dev,
-				READ_12BIT_SER(vaux) | ADS_PD10_ALL_ON);
+		(void) ads7846_read12_ser(&spi->dev, READ_12BIT_SER(vaux));
 
 	err = sysfs_create_group(&spi->dev.kobj, &ads784x_attr_group);
 	if (err)
diff -druN linux-2.6.39-libre/drivers/input/touchscreen/atmel_mxt_ts.c linux-3.0-rc7-libre/drivers/input/touchscreen/atmel_mxt_ts.c
--- linux-2.6.39-libre/drivers/input/touchscreen/atmel_mxt_ts.c	2011-05-19 02:17:17.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/input/touchscreen/atmel_mxt_ts.c	2011-07-21 06:59:15.000000000 -0400
@@ -17,7 +17,7 @@
 #include <linux/firmware.h>
 #include <linux/i2c.h>
 #include <linux/i2c/atmel_mxt_ts.h>
-#include <linux/input.h>
+#include <linux/input/mt.h>
 #include <linux/interrupt.h>
 #include <linux/slab.h>
 
@@ -196,9 +196,12 @@
 #define MXT_PRESS		(1 << 6)
 #define MXT_DETECT		(1 << 7)
 
+/* Touch orient bits */
+#define MXT_XY_SWITCH		(1 << 0)
+#define MXT_X_INVERT		(1 << 1)
+#define MXT_Y_INVERT		(1 << 2)
+
 /* Touchscreen absolute values */
-#define MXT_MAX_XC		0x3ff
-#define MXT_MAX_YC		0x3ff
 #define MXT_MAX_AREA		0xff
 
 #define MXT_MAX_FINGER		10
@@ -246,6 +249,8 @@
 	struct mxt_info info;
 	struct mxt_finger finger[MXT_MAX_FINGER];
 	unsigned int irq;
+	unsigned int max_x;
+	unsigned int max_y;
 };
 
 static bool mxt_object_readable(unsigned int type)
@@ -499,19 +504,21 @@
 		if (!finger[id].status)
 			continue;
 
-		input_report_abs(input_dev, ABS_MT_TOUCH_MAJOR,
-				finger[id].status != MXT_RELEASE ?
-				finger[id].area : 0);
-		input_report_abs(input_dev, ABS_MT_POSITION_X,
-				finger[id].x);
-		input_report_abs(input_dev, ABS_MT_POSITION_Y,
-				finger[id].y);
-		input_mt_sync(input_dev);
+		input_mt_slot(input_dev, id);
+		input_mt_report_slot_state(input_dev, MT_TOOL_FINGER,
+				finger[id].status != MXT_RELEASE);
 
-		if (finger[id].status == MXT_RELEASE)
-			finger[id].status = 0;
-		else
+		if (finger[id].status != MXT_RELEASE) {
 			finger_num++;
+			input_report_abs(input_dev, ABS_MT_TOUCH_MAJOR,
+					finger[id].area);
+			input_report_abs(input_dev, ABS_MT_POSITION_X,
+					finger[id].x);
+			input_report_abs(input_dev, ABS_MT_POSITION_Y,
+					finger[id].y);
+		} else {
+			finger[id].status = 0;
+		}
 	}
 
 	input_report_key(input_dev, BTN_TOUCH, finger_num > 0);
@@ -549,8 +556,13 @@
 	if (!(status & (MXT_PRESS | MXT_MOVE)))
 		return;
 
-	x = (message->message[1] << 2) | ((message->message[3] & ~0x3f) >> 6);
-	y = (message->message[2] << 2) | ((message->message[3] & ~0xf3) >> 2);
+	x = (message->message[1] << 4) | ((message->message[3] >> 4) & 0xf);
+	y = (message->message[2] << 4) | ((message->message[3] & 0xf));
+	if (data->max_x < 1024)
+		x = x >> 2;
+	if (data->max_y < 1024)
+		y = y >> 2;
+
 	area = message->message[4];
 
 	dev_dbg(dev, "[%d] %s x: %d, y: %d, area: %d\n", id,
@@ -804,10 +816,6 @@
 	if (error)
 		return error;
 
-	error = mxt_make_highchg(data);
-	if (error)
-		return error;
-
 	mxt_handle_pdata(data);
 
 	/* Backup to memory */
@@ -845,6 +853,20 @@
 	return 0;
 }
 
+static void mxt_calc_resolution(struct mxt_data *data)
+{
+	unsigned int max_x = data->pdata->x_size - 1;
+	unsigned int max_y = data->pdata->y_size - 1;
+
+	if (data->pdata->orient & MXT_XY_SWITCH) {
+		data->max_x = max_y;
+		data->max_y = max_x;
+	} else {
+		data->max_x = max_x;
+		data->max_y = max_y;
+	}
+}
+
 static ssize_t mxt_object_show(struct device *dev,
 				    struct device_attribute *attr, char *buf)
 {
@@ -981,6 +1003,10 @@
 
 	enable_irq(data->irq);
 
+	error = mxt_make_highchg(data);
+	if (error)
+		return error;
+
 	return count;
 }
 
@@ -1052,31 +1078,33 @@
 	input_dev->open = mxt_input_open;
 	input_dev->close = mxt_input_close;
 
+	data->client = client;
+	data->input_dev = input_dev;
+	data->pdata = pdata;
+	data->irq = client->irq;
+
+	mxt_calc_resolution(data);
+
 	__set_bit(EV_ABS, input_dev->evbit);
 	__set_bit(EV_KEY, input_dev->evbit);
 	__set_bit(BTN_TOUCH, input_dev->keybit);
 
 	/* For single touch */
 	input_set_abs_params(input_dev, ABS_X,
-			     0, MXT_MAX_XC, 0, 0);
+			     0, data->max_x, 0, 0);
 	input_set_abs_params(input_dev, ABS_Y,
-			     0, MXT_MAX_YC, 0, 0);
+			     0, data->max_y, 0, 0);
 
 	/* For multi touch */
+	input_mt_init_slots(input_dev, MXT_MAX_FINGER);
 	input_set_abs_params(input_dev, ABS_MT_TOUCH_MAJOR,
 			     0, MXT_MAX_AREA, 0, 0);
 	input_set_abs_params(input_dev, ABS_MT_POSITION_X,
-			     0, MXT_MAX_XC, 0, 0);
+			     0, data->max_x, 0, 0);
 	input_set_abs_params(input_dev, ABS_MT_POSITION_Y,
-			     0, MXT_MAX_YC, 0, 0);
+			     0, data->max_y, 0, 0);
 
 	input_set_drvdata(input_dev, data);
-
-	data->client = client;
-	data->input_dev = input_dev;
-	data->pdata = pdata;
-	data->irq = client->irq;
-
 	i2c_set_clientdata(client, data);
 
 	error = mxt_initialize(data);
@@ -1090,6 +1118,10 @@
 		goto err_free_object;
 	}
 
+	error = mxt_make_highchg(data);
+	if (error)
+		goto err_free_irq;
+
 	error = input_register_device(input_dev);
 	if (error)
 		goto err_free_irq;
diff -druN linux-2.6.39-libre/drivers/input/touchscreen/atmel_tsadcc.c linux-3.0-rc7-libre/drivers/input/touchscreen/atmel_tsadcc.c
--- linux-2.6.39-libre/drivers/input/touchscreen/atmel_tsadcc.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/input/touchscreen/atmel_tsadcc.c	2011-07-11 19:51:52.000000000 -0400
@@ -317,7 +317,7 @@
 err_release_mem:
 	release_mem_region(res->start, resource_size(res));
 err_free_dev:
-	input_free_device(ts_dev->input);
+	input_free_device(input_dev);
 err_free_mem:
 	kfree(ts_dev);
 	return err;
diff -druN linux-2.6.39-libre/drivers/input/touchscreen/h3600_ts_input.c linux-3.0-rc7-libre/drivers/input/touchscreen/h3600_ts_input.c
--- linux-2.6.39-libre/drivers/input/touchscreen/h3600_ts_input.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/input/touchscreen/h3600_ts_input.c	2011-07-11 19:51:52.000000000 -0400
@@ -396,14 +396,14 @@
 	set_GPIO_IRQ_edge(GPIO_BITSY_NPOWER_BUTTON, GPIO_RISING_EDGE);
 
 	if (request_irq(IRQ_GPIO_BITSY_ACTION_BUTTON, action_button_handler,
-			IRQF_SHARED | IRQF_DISABLED, "h3600_action", &ts->dev)) {
+			IRQF_SHARED | IRQF_DISABLED, "h3600_action", ts->dev)) {
 		printk(KERN_ERR "h3600ts.c: Could not allocate Action Button IRQ!\n");
 		err = -EBUSY;
 		goto fail1;
 	}
 
 	if (request_irq(IRQ_GPIO_BITSY_NPOWER_BUTTON, npower_button_handler,
-			IRQF_SHARED | IRQF_DISABLED, "h3600_suspend", &ts->dev)) {
+			IRQF_SHARED | IRQF_DISABLED, "h3600_suspend", ts->dev)) {
 		printk(KERN_ERR "h3600ts.c: Could not allocate Power Button IRQ!\n");
 		err = -EBUSY;
 		goto fail2;
@@ -439,8 +439,8 @@
 {
 	struct h3600_dev *ts = serio_get_drvdata(serio);
 
-	free_irq(IRQ_GPIO_BITSY_ACTION_BUTTON, &ts->dev);
-	free_irq(IRQ_GPIO_BITSY_NPOWER_BUTTON, &ts->dev);
+	free_irq(IRQ_GPIO_BITSY_ACTION_BUTTON, ts->dev);
+	free_irq(IRQ_GPIO_BITSY_NPOWER_BUTTON, ts->dev);
 	input_get_device(ts->dev);
 	input_unregister_device(ts->dev);
 	serio_close(serio);
diff -druN linux-2.6.39-libre/drivers/input/touchscreen/Kconfig linux-3.0-rc7-libre/drivers/input/touchscreen/Kconfig
--- linux-2.6.39-libre/drivers/input/touchscreen/Kconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/input/touchscreen/Kconfig	2011-07-11 19:51:52.000000000 -0400
@@ -248,6 +248,18 @@
 	  To compile this driver as a module, choose M here: the
 	  module will be called lpc32xx_ts.
 
+config TOUCHSCREEN_MAX11801
+	tristate "MAX11801 based touchscreens"
+	depends on I2C
+	help
+	  Say Y here if you have a MAX11801 based touchscreen
+	  controller.
+
+	  If unsure, say N.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called max11801_ts.
+
 config TOUCHSCREEN_MCS5000
 	tristate "MELFAS MCS-5000 touchscreen"
 	depends on I2C
diff -druN linux-2.6.39-libre/drivers/input/touchscreen/Makefile linux-3.0-rc7-libre/drivers/input/touchscreen/Makefile
--- linux-2.6.39-libre/drivers/input/touchscreen/Makefile	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/input/touchscreen/Makefile	2011-07-11 19:51:52.000000000 -0400
@@ -27,6 +27,7 @@
 obj-$(CONFIG_TOUCHSCREEN_INEXIO)	+= inexio.o
 obj-$(CONFIG_TOUCHSCREEN_INTEL_MID)	+= intel-mid-touch.o
 obj-$(CONFIG_TOUCHSCREEN_LPC32XX)	+= lpc32xx_ts.o
+obj-$(CONFIG_TOUCHSCREEN_MAX11801)	+= max11801_ts.o
 obj-$(CONFIG_TOUCHSCREEN_MC13783)	+= mc13783_ts.o
 obj-$(CONFIG_TOUCHSCREEN_MCS5000)	+= mcs5000_ts.o
 obj-$(CONFIG_TOUCHSCREEN_MIGOR)		+= migor_ts.o
diff -druN linux-2.6.39-libre/drivers/input/touchscreen/max11801_ts.c linux-3.0-rc7-libre/drivers/input/touchscreen/max11801_ts.c
--- linux-2.6.39-libre/drivers/input/touchscreen/max11801_ts.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/input/touchscreen/max11801_ts.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,272 @@
+/*
+ * Driver for MAXI MAX11801 - A Resistive touch screen controller with
+ * i2c interface
+ *
+ * Copyright (C) 2011 Freescale Semiconductor, Inc.
+ * Author: Zhang Jiejing <jiejing.zhang@freescale.com>
+ *
+ * Based on mcs5000_ts.c
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License.
+ */
+
+/*
+ * This driver aims to support the series of MAXI touch chips max11801
+ * through max11803. The main difference between these 4 chips can be
+ * found in the table below:
+ * -----------------------------------------------------
+ * | CHIP     |  AUTO MODE SUPPORT(FIFO) | INTERFACE    |
+ * |----------------------------------------------------|
+ * | max11800 |  YES                     |   SPI        |
+ * | max11801 |  YES                     |   I2C        |
+ * | max11802 |  NO                      |   SPI        |
+ * | max11803 |  NO                      |   I2C        |
+ * ------------------------------------------------------
+ *
+ * Currently, this driver only supports max11801.
+ *
+ * Data Sheet:
+ * http://www.maxim-ic.com/datasheet/index.mvp/id/5943
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/i2c.h>
+#include <linux/interrupt.h>
+#include <linux/input.h>
+#include <linux/slab.h>
+#include <linux/bitops.h>
+
+/* Register Address define */
+#define GENERNAL_STATUS_REG		0x00
+#define GENERNAL_CONF_REG		0x01
+#define MESURE_RES_CONF_REG		0x02
+#define MESURE_AVER_CONF_REG		0x03
+#define ADC_SAMPLE_TIME_CONF_REG	0x04
+#define PANEL_SETUPTIME_CONF_REG	0x05
+#define DELAY_CONVERSION_CONF_REG	0x06
+#define TOUCH_DETECT_PULLUP_CONF_REG	0x07
+#define AUTO_MODE_TIME_CONF_REG		0x08 /* only for max11800/max11801 */
+#define APERTURE_CONF_REG		0x09 /* only for max11800/max11801 */
+#define AUX_MESURE_CONF_REG		0x0a
+#define OP_MODE_CONF_REG		0x0b
+
+/* FIFO is found only in max11800 and max11801 */
+#define FIFO_RD_CMD			(0x50 << 1)
+#define MAX11801_FIFO_INT		(1 << 2)
+#define MAX11801_FIFO_OVERFLOW		(1 << 3)
+
+#define XY_BUFSIZE			4
+#define XY_BUF_OFFSET			4
+
+#define MAX11801_MAX_X			0xfff
+#define MAX11801_MAX_Y			0xfff
+
+#define MEASURE_TAG_OFFSET		2
+#define MEASURE_TAG_MASK		(3 << MEASURE_TAG_OFFSET)
+#define EVENT_TAG_OFFSET		0
+#define EVENT_TAG_MASK			(3 << EVENT_TAG_OFFSET)
+#define MEASURE_X_TAG			(0 << MEASURE_TAG_OFFSET)
+#define MEASURE_Y_TAG			(1 << MEASURE_TAG_OFFSET)
+
+/* These are the state of touch event state machine */
+enum {
+	EVENT_INIT,
+	EVENT_MIDDLE,
+	EVENT_RELEASE,
+	EVENT_FIFO_END
+};
+
+struct max11801_data {
+	struct i2c_client		*client;
+	struct input_dev		*input_dev;
+};
+
+static u8 read_register(struct i2c_client *client, int addr)
+{
+	/* XXX: The chip ignores LSB of register address */
+	return i2c_smbus_read_byte_data(client, addr << 1);
+}
+
+static int max11801_write_reg(struct i2c_client *client, int addr, int data)
+{
+	/* XXX: The chip ignores LSB of register address */
+	return i2c_smbus_write_byte_data(client, addr << 1, data);
+}
+
+static irqreturn_t max11801_ts_interrupt(int irq, void *dev_id)
+{
+	struct max11801_data *data = dev_id;
+	struct i2c_client *client = data->client;
+	int status, i, ret;
+	u8 buf[XY_BUFSIZE];
+	int x = -1;
+	int y = -1;
+
+	status = read_register(data->client, GENERNAL_STATUS_REG);
+
+	if (status & (MAX11801_FIFO_INT | MAX11801_FIFO_OVERFLOW)) {
+		status = read_register(data->client, GENERNAL_STATUS_REG);
+
+		ret = i2c_smbus_read_i2c_block_data(client, FIFO_RD_CMD,
+						    XY_BUFSIZE, buf);
+
+		/*
+		 * We should get 4 bytes buffer that contains X,Y
+		 * and event tag
+		 */
+		if (ret < XY_BUFSIZE)
+			goto out;
+
+		for (i = 0; i < XY_BUFSIZE; i += XY_BUFSIZE / 2) {
+			if ((buf[i + 1] & MEASURE_TAG_MASK) == MEASURE_X_TAG)
+				x = (buf[i] << XY_BUF_OFFSET) +
+				    (buf[i + 1] >> XY_BUF_OFFSET);
+			else if ((buf[i + 1] & MEASURE_TAG_MASK) == MEASURE_Y_TAG)
+				y = (buf[i] << XY_BUF_OFFSET) +
+				    (buf[i + 1] >> XY_BUF_OFFSET);
+		}
+
+		if ((buf[1] & EVENT_TAG_MASK) != (buf[3] & EVENT_TAG_MASK))
+			goto out;
+
+		switch (buf[1] & EVENT_TAG_MASK) {
+		case EVENT_INIT:
+			/* fall through */
+		case EVENT_MIDDLE:
+			input_report_abs(data->input_dev, ABS_X, x);
+			input_report_abs(data->input_dev, ABS_Y, y);
+			input_event(data->input_dev, EV_KEY, BTN_TOUCH, 1);
+			input_sync(data->input_dev);
+			break;
+
+		case EVENT_RELEASE:
+			input_event(data->input_dev, EV_KEY, BTN_TOUCH, 0);
+			input_sync(data->input_dev);
+			break;
+
+		case EVENT_FIFO_END:
+			break;
+		}
+	}
+out:
+	return IRQ_HANDLED;
+}
+
+static void __devinit max11801_ts_phy_init(struct max11801_data *data)
+{
+	struct i2c_client *client = data->client;
+
+	/* Average X,Y, take 16 samples, average eight media sample */
+	max11801_write_reg(client, MESURE_AVER_CONF_REG, 0xff);
+	/* X,Y panel setup time set to 20us */
+	max11801_write_reg(client, PANEL_SETUPTIME_CONF_REG, 0x11);
+	/* Rough pullup time (2uS), Fine pullup time (10us)  */
+	max11801_write_reg(client, TOUCH_DETECT_PULLUP_CONF_REG, 0x10);
+	/* Auto mode init period = 5ms , scan period = 5ms*/
+	max11801_write_reg(client, AUTO_MODE_TIME_CONF_REG, 0xaa);
+	/* Aperture X,Y set to +- 4LSB */
+	max11801_write_reg(client, APERTURE_CONF_REG, 0x33);
+	/* Enable Power, enable Automode, enable Aperture, enable Average X,Y */
+	max11801_write_reg(client, OP_MODE_CONF_REG, 0x36);
+}
+
+static int __devinit max11801_ts_probe(struct i2c_client *client,
+				       const struct i2c_device_id *id)
+{
+	struct max11801_data *data;
+	struct input_dev *input_dev;
+	int error;
+
+	data = kzalloc(sizeof(struct max11801_data), GFP_KERNEL);
+	input_dev = input_allocate_device();
+	if (!data || !input_dev) {
+		dev_err(&client->dev, "Failed to allocate memory\n");
+		error = -ENOMEM;
+		goto err_free_mem;
+	}
+
+	data->client = client;
+	data->input_dev = input_dev;
+
+	input_dev->name = "max11801_ts";
+	input_dev->id.bustype = BUS_I2C;
+	input_dev->dev.parent = &client->dev;
+
+	__set_bit(EV_ABS, input_dev->evbit);
+	__set_bit(EV_KEY, input_dev->evbit);
+	__set_bit(BTN_TOUCH, input_dev->keybit);
+	input_set_abs_params(input_dev, ABS_X, 0, MAX11801_MAX_X, 0, 0);
+	input_set_abs_params(input_dev, ABS_Y, 0, MAX11801_MAX_Y, 0, 0);
+	input_set_drvdata(input_dev, data);
+
+	max11801_ts_phy_init(data);
+
+	error = request_threaded_irq(client->irq, NULL, max11801_ts_interrupt,
+				     IRQF_TRIGGER_LOW | IRQF_ONESHOT,
+				     "max11801_ts", data);
+	if (error) {
+		dev_err(&client->dev, "Failed to register interrupt\n");
+		goto err_free_mem;
+	}
+
+	error = input_register_device(data->input_dev);
+	if (error)
+		goto err_free_irq;
+
+	i2c_set_clientdata(client, data);
+	return 0;
+
+err_free_irq:
+	free_irq(client->irq, data);
+err_free_mem:
+	input_free_device(input_dev);
+	kfree(data);
+	return error;
+}
+
+static __devexit int max11801_ts_remove(struct i2c_client *client)
+{
+	struct max11801_data *data = i2c_get_clientdata(client);
+
+	free_irq(client->irq, data);
+	input_unregister_device(data->input_dev);
+	kfree(data);
+
+	return 0;
+}
+
+static const struct i2c_device_id max11801_ts_id[] = {
+	{"max11801", 0},
+	{ }
+};
+MODULE_DEVICE_TABLE(i2c, max11801_ts_id);
+
+static struct i2c_driver max11801_ts_driver = {
+	.driver = {
+		.name	= "max11801_ts",
+		.owner	= THIS_MODULE,
+	},
+	.id_table	= max11801_ts_id,
+	.probe		= max11801_ts_probe,
+	.remove		= __devexit_p(max11801_ts_remove),
+};
+
+static int __init max11801_ts_init(void)
+{
+	return i2c_add_driver(&max11801_ts_driver);
+}
+
+static void __exit max11801_ts_exit(void)
+{
+	i2c_del_driver(&max11801_ts_driver);
+}
+
+module_init(max11801_ts_init);
+module_exit(max11801_ts_exit);
+
+MODULE_AUTHOR("Zhang Jiejing <jiejing.zhang@freescale.com>");
+MODULE_DESCRIPTION("Touchscreen driver for MAXI MAX11801 controller");
+MODULE_LICENSE("GPL");
diff -druN linux-2.6.39-libre/drivers/input/touchscreen/tsc2007.c linux-3.0-rc7-libre/drivers/input/touchscreen/tsc2007.c
--- linux-2.6.39-libre/drivers/input/touchscreen/tsc2007.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/input/touchscreen/tsc2007.c	2011-07-11 19:51:52.000000000 -0400
@@ -27,9 +27,6 @@
 #include <linux/i2c.h>
 #include <linux/i2c/tsc2007.h>
 
-#define TS_POLL_DELAY			1 /* ms delay between samples */
-#define TS_POLL_PERIOD			1 /* ms delay between samples */
-
 #define TSC2007_MEASURE_TEMP0		(0x0 << 4)
 #define TSC2007_MEASURE_AUX		(0x2 << 4)
 #define TSC2007_MEASURE_TEMP1		(0x4 << 4)
@@ -75,6 +72,9 @@
 
 	u16			model;
 	u16			x_plate_ohms;
+	u16			max_rt;
+	unsigned long		poll_delay;
+	unsigned long		poll_period;
 
 	bool			pendown;
 	int			irq;
@@ -156,6 +156,7 @@
 {
 	struct tsc2007 *ts =
 		container_of(to_delayed_work(work), struct tsc2007, work);
+	bool debounced = false;
 	struct ts_event tc;
 	u32 rt;
 
@@ -184,13 +185,14 @@
 	tsc2007_read_values(ts, &tc);
 
 	rt = tsc2007_calculate_pressure(ts, &tc);
-	if (rt > MAX_12BIT) {
+	if (rt > ts->max_rt) {
 		/*
 		 * Sample found inconsistent by debouncing or pressure is
 		 * beyond the maximum. Don't report it to user space,
 		 * repeat at least once more the measurement.
 		 */
 		dev_dbg(&ts->client->dev, "ignored pressure %d\n", rt);
+		debounced = true;
 		goto out;
 
 	}
@@ -225,9 +227,9 @@
 	}
 
  out:
-	if (ts->pendown)
+	if (ts->pendown || debounced)
 		schedule_delayed_work(&ts->work,
-				      msecs_to_jiffies(TS_POLL_PERIOD));
+				      msecs_to_jiffies(ts->poll_period));
 	else
 		enable_irq(ts->irq);
 }
@@ -239,7 +241,7 @@
 	if (!ts->get_pendown_state || likely(ts->get_pendown_state())) {
 		disable_irq_nosync(ts->irq);
 		schedule_delayed_work(&ts->work,
-				      msecs_to_jiffies(TS_POLL_DELAY));
+				      msecs_to_jiffies(ts->poll_delay));
 	}
 
 	if (ts->clear_penirq)
@@ -292,6 +294,9 @@
 
 	ts->model             = pdata->model;
 	ts->x_plate_ohms      = pdata->x_plate_ohms;
+	ts->max_rt            = pdata->max_rt ? : MAX_12BIT;
+	ts->poll_delay        = pdata->poll_delay ? : 1;
+	ts->poll_period       = pdata->poll_period ? : 1;
 	ts->get_pendown_state = pdata->get_pendown_state;
 	ts->clear_penirq      = pdata->clear_penirq;
 
@@ -305,9 +310,10 @@
 	input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
 	input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
 
-	input_set_abs_params(input_dev, ABS_X, 0, MAX_12BIT, 0, 0);
-	input_set_abs_params(input_dev, ABS_Y, 0, MAX_12BIT, 0, 0);
-	input_set_abs_params(input_dev, ABS_PRESSURE, 0, MAX_12BIT, 0, 0);
+	input_set_abs_params(input_dev, ABS_X, 0, MAX_12BIT, pdata->fuzzx, 0);
+	input_set_abs_params(input_dev, ABS_Y, 0, MAX_12BIT, pdata->fuzzy, 0);
+	input_set_abs_params(input_dev, ABS_PRESSURE, 0, MAX_12BIT,
+			pdata->fuzzz, 0);
 
 	if (pdata->init_platform_hw)
 		pdata->init_platform_hw();
diff -druN linux-2.6.39-libre/drivers/isdn/capi/capi.c linux-3.0-rc7-libre/drivers/isdn/capi/capi.c
--- linux-2.6.39-libre/drivers/isdn/capi/capi.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/isdn/capi/capi.c	2011-07-11 19:51:52.000000000 -0400
@@ -38,15 +38,10 @@
 #include <linux/isdn/capiutil.h>
 #include <linux/isdn/capicmd.h>
 
-#include "capifs.h"
-
 MODULE_DESCRIPTION("CAPI4Linux: Userspace /dev/capi20 interface");
 MODULE_AUTHOR("Carsten Paeth");
 MODULE_LICENSE("GPL");
 
-#undef _DEBUG_TTYFUNCS		/* call to tty_driver */
-#undef _DEBUG_DATAFLOW		/* data flow */
-
 /* -------- driver information -------------------------------------- */
 
 static DEFINE_MUTEX(capi_mutex);
@@ -85,7 +80,6 @@
 	struct kref kref;
 
 	unsigned int      minor;
-	struct dentry *capifs_dentry;
 
 	struct capi20_appl	*ap;
 	u32			ncci;
@@ -300,17 +294,8 @@
 
 static void capincci_alloc_minor(struct capidev *cdev, struct capincci *np)
 {
-	struct capiminor *mp;
-	dev_t device;
-
-	if (!(cdev->userflags & CAPIFLAG_HIGHJACKING))
-		return;
-
-	mp = np->minorp = capiminor_alloc(&cdev->ap, np->ncci);
-	if (mp) {
-		device = MKDEV(capinc_tty_driver->major, mp->minor);
-		mp->capifs_dentry = capifs_new_ncci(mp->minor, device);
-	}
+	if (cdev->userflags & CAPIFLAG_HIGHJACKING)
+		np->minorp = capiminor_alloc(&cdev->ap, np->ncci);
 }
 
 static void capincci_free_minor(struct capincci *np)
@@ -319,8 +304,6 @@
 	struct tty_struct *tty;
 
 	if (mp) {
-		capifs_free_ncci(mp->capifs_dentry);
-
 		tty = tty_port_tty_get(&mp->port);
 		if (tty) {
 			tty_vhangup(tty);
@@ -432,9 +415,7 @@
 
 	tty = tty_port_tty_get(&mp->port);
 	if (!tty) {
-#ifdef _DEBUG_DATAFLOW
-		printk(KERN_DEBUG "capi: currently no receiver\n");
-#endif
+		pr_debug("capi: currently no receiver\n");
 		return -1;
 	}
 	
@@ -447,23 +428,17 @@
 	}
 
 	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
+		pr_debug("capi: ldisc has no receive_buf function\n");
 		/* 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
+		pr_debug("capi: recv tty throttled\n");
 		goto deref_ldisc;
 	}
 
 	if (tty->receive_room < datalen) {
-#if defined(_DEBUG_DATAFLOW) || defined(_DEBUG_TTYFUNCS)
-		printk(KERN_DEBUG "capi: no room in tty\n");
-#endif
+		pr_debug("capi: no room in tty\n");
 		goto deref_ldisc;
 	}
 
@@ -479,10 +454,8 @@
 
 	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
+		pr_debug("capi: DATA_B3_RESP %u len=%d => ldisc\n",
+			 datahandle, skb->len);
 		ld->ops->receive_buf(tty, skb->data, NULL, skb->len);
 	} else {
 		printk(KERN_ERR "capi: send DATA_B3_RESP failed=%x\n",
@@ -529,9 +502,7 @@
 		return;
 
 	if (mp->ttyoutstop) {
-#if defined(_DEBUG_DATAFLOW) || defined(_DEBUG_TTYFUNCS)
-		printk(KERN_DEBUG "capi: send: tty stopped\n");
-#endif
+		pr_debug("capi: send: tty stopped\n");
 		tty_kref_put(tty);
 		return;
 	}
@@ -573,10 +544,8 @@
 		}
 		errcode = capi20_put_message(mp->ap, skb);
 		if (errcode == CAPI_NOERROR) {
-#ifdef _DEBUG_DATAFLOW
-			printk(KERN_DEBUG "capi: DATA_B3_REQ %u len=%u\n",
-							datahandle, len);
-#endif
+			pr_debug("capi: DATA_B3_REQ %u len=%u\n",
+				 datahandle, len);
 			continue;
 		}
 		capiminor_del_ack(mp, datahandle);
@@ -650,10 +619,8 @@
 	}
 	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
+		pr_debug("capi_signal: DATA_B3_IND %u len=%d\n",
+			 datahandle, skb->len-CAPIMSG_LEN(skb->data));
 		skb_queue_tail(&mp->inqueue, skb);
 
 		handle_minor_recv(mp);
@@ -661,11 +628,9 @@
 	} else if (CAPIMSG_SUBCOMMAND(skb->data) == CAPI_CONF) {
 
 		datahandle = CAPIMSG_U16(skb->data, CAPIMSG_BASELEN+4);
-#ifdef _DEBUG_DATAFLOW
-		printk(KERN_DEBUG "capi_signal: DATA_B3_CONF %u 0x%x\n",
-				datahandle,
-				CAPIMSG_U16(skb->data, CAPIMSG_BASELEN+4+2));
-#endif
+		pr_debug("capi_signal: DATA_B3_CONF %u 0x%x\n",
+			 datahandle,
+			 CAPIMSG_U16(skb->data, CAPIMSG_BASELEN+4+2));
 		kfree_skb(skb);
 		capiminor_del_ack(mp, datahandle);
 		tty = tty_port_tty_get(&mp->port);
@@ -1095,9 +1060,7 @@
 	struct capiminor *mp = tty->driver_data;
 	struct sk_buff *skb;
 
-#ifdef _DEBUG_TTYFUNCS
-	printk(KERN_DEBUG "capinc_tty_write(count=%d)\n", count);
-#endif
+	pr_debug("capinc_tty_write(count=%d)\n", count);
 
 	spin_lock_bh(&mp->outlock);
 	skb = mp->outskb;
@@ -1133,9 +1096,7 @@
 	struct sk_buff *skb;
 	int ret = 1;
 
-#ifdef _DEBUG_TTYFUNCS
-	printk(KERN_DEBUG "capinc_put_char(%u)\n", ch);
-#endif
+	pr_debug("capinc_put_char(%u)\n", ch);
 
 	spin_lock_bh(&mp->outlock);
 	skb = mp->outskb;
@@ -1174,9 +1135,7 @@
 	struct capiminor *mp = tty->driver_data;
 	struct sk_buff *skb;
 
-#ifdef _DEBUG_TTYFUNCS
-	printk(KERN_DEBUG "capinc_tty_flush_chars\n");
-#endif
+	pr_debug("capinc_tty_flush_chars\n");
 
 	spin_lock_bh(&mp->outlock);
 	skb = mp->outskb;
@@ -1200,9 +1159,7 @@
 
 	room = CAPINC_MAX_SENDQUEUE-skb_queue_len(&mp->outqueue);
 	room *= CAPI_MAX_BLKSIZE;
-#ifdef _DEBUG_TTYFUNCS
-	printk(KERN_DEBUG "capinc_tty_write_room = %d\n", room);
-#endif
+	pr_debug("capinc_tty_write_room = %d\n", room);
 	return room;
 }
 
@@ -1210,12 +1167,10 @@
 {
 	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,
-			skb_queue_len(&mp->outqueue),
-			skb_queue_len(&mp->inqueue));
-#endif
+	pr_debug("capinc_tty_chars_in_buffer = %d nack=%d sq=%d rq=%d\n",
+		 mp->outbytes, mp->nack,
+		 skb_queue_len(&mp->outqueue),
+		 skb_queue_len(&mp->inqueue));
 	return mp->outbytes;
 }
 
@@ -1227,17 +1182,13 @@
 
 static void capinc_tty_set_termios(struct tty_struct *tty, struct ktermios * old)
 {
-#ifdef _DEBUG_TTYFUNCS
-	printk(KERN_DEBUG "capinc_tty_set_termios\n");
-#endif
+	pr_debug("capinc_tty_set_termios\n");
 }
 
 static void capinc_tty_throttle(struct tty_struct *tty)
 {
 	struct capiminor *mp = tty->driver_data;
-#ifdef _DEBUG_TTYFUNCS
-	printk(KERN_DEBUG "capinc_tty_throttle\n");
-#endif
+	pr_debug("capinc_tty_throttle\n");
 	mp->ttyinstop = 1;
 }
 
@@ -1245,9 +1196,7 @@
 {
 	struct capiminor *mp = tty->driver_data;
 
-#ifdef _DEBUG_TTYFUNCS
-	printk(KERN_DEBUG "capinc_tty_unthrottle\n");
-#endif
+	pr_debug("capinc_tty_unthrottle\n");
 	mp->ttyinstop = 0;
 	handle_minor_recv(mp);
 }
@@ -1256,9 +1205,7 @@
 {
 	struct capiminor *mp = tty->driver_data;
 
-#ifdef _DEBUG_TTYFUNCS
-	printk(KERN_DEBUG "capinc_tty_stop\n");
-#endif
+	pr_debug("capinc_tty_stop\n");
 	mp->ttyoutstop = 1;
 }
 
@@ -1266,9 +1213,7 @@
 {
 	struct capiminor *mp = tty->driver_data;
 
-#ifdef _DEBUG_TTYFUNCS
-	printk(KERN_DEBUG "capinc_tty_start\n");
-#endif
+	pr_debug("capinc_tty_start\n");
 	mp->ttyoutstop = 0;
 	handle_minor_send(mp);
 }
@@ -1277,39 +1222,29 @@
 {
 	struct capiminor *mp = tty->driver_data;
 
-#ifdef _DEBUG_TTYFUNCS
-	printk(KERN_DEBUG "capinc_tty_hangup\n");
-#endif
+	pr_debug("capinc_tty_hangup\n");
 	tty_port_hangup(&mp->port);
 }
 
 static int capinc_tty_break_ctl(struct tty_struct *tty, int state)
 {
-#ifdef _DEBUG_TTYFUNCS
-	printk(KERN_DEBUG "capinc_tty_break_ctl(%d)\n", state);
-#endif
+	pr_debug("capinc_tty_break_ctl(%d)\n", state);
 	return 0;
 }
 
 static void capinc_tty_flush_buffer(struct tty_struct *tty)
 {
-#ifdef _DEBUG_TTYFUNCS
-	printk(KERN_DEBUG "capinc_tty_flush_buffer\n");
-#endif
+	pr_debug("capinc_tty_flush_buffer\n");
 }
 
 static void capinc_tty_set_ldisc(struct tty_struct *tty)
 {
-#ifdef _DEBUG_TTYFUNCS
-	printk(KERN_DEBUG "capinc_tty_set_ldisc\n");
-#endif
+	pr_debug("capinc_tty_set_ldisc\n");
 }
 
 static void capinc_tty_send_xchar(struct tty_struct *tty, char ch)
 {
-#ifdef _DEBUG_TTYFUNCS
-	printk(KERN_DEBUG "capinc_tty_send_xchar(%d)\n", ch);
-#endif
+	pr_debug("capinc_tty_send_xchar(%d)\n", ch);
 }
 
 static const struct tty_operations capinc_ops = {
@@ -1514,10 +1449,8 @@
 
 	proc_init();
 
-#if defined(CONFIG_ISDN_CAPI_CAPIFS) || defined(CONFIG_ISDN_CAPI_CAPIFS_MODULE)
-        compileinfo = " (middleware+capifs)";
-#elif defined(CONFIG_ISDN_CAPI_MIDDLEWARE)
-        compileinfo = " (no capifs)";
+#ifdef CONFIG_ISDN_CAPI_MIDDLEWARE
+        compileinfo = " (middleware)";
 #else
         compileinfo = " (no middleware)";
 #endif
diff -druN linux-2.6.39-libre/drivers/isdn/capi/capifs.c linux-3.0-rc7-libre/drivers/isdn/capi/capifs.c
--- linux-2.6.39-libre/drivers/isdn/capi/capifs.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/isdn/capi/capifs.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,239 +0,0 @@
-/* $Id: capifs.c,v 1.1.2.3 2004/01/16 21:09:26 keil Exp $
- * 
- * Copyright 2000 by Carsten Paeth <calle@calle.de>
- *
- * Heavily based on devpts filesystem from H. Peter Anvin
- * 
- * This software may be used and distributed according to the terms
- * of the GNU General Public License, incorporated herein by reference.
- *
- */
-
-#include <linux/fs.h>
-#include <linux/mount.h>
-#include <linux/slab.h>
-#include <linux/namei.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/ctype.h>
-#include <linux/sched.h>	/* current */
-
-#include "capifs.h"
-
-MODULE_DESCRIPTION("CAPI4Linux: /dev/capi/ filesystem");
-MODULE_AUTHOR("Carsten Paeth");
-MODULE_LICENSE("GPL");
-
-/* ------------------------------------------------------------------ */
-
-#define CAPIFS_SUPER_MAGIC (('C'<<8)|'N')
-
-static struct vfsmount *capifs_mnt;
-static int capifs_mnt_count;
-
-static struct {
-	int setuid;
-	int setgid;
-	uid_t   uid;
-	gid_t   gid;
-	umode_t mode;
-} config = {.mode = 0600};
-
-/* ------------------------------------------------------------------ */
-
-static int capifs_remount(struct super_block *s, int *flags, char *data)
-{
-	int setuid = 0;
-	int setgid = 0;
-	uid_t uid = 0;
-	gid_t gid = 0;
-	umode_t mode = 0600;
-	char *this_char;
-	char *new_opt = kstrdup(data, GFP_KERNEL);
-
-	this_char = NULL;
-	while ((this_char = strsep(&data, ",")) != NULL) {
-		int n;
-		char dummy;
-		if (!*this_char)
-			continue;
-		if (sscanf(this_char, "uid=%i%c", &n, &dummy) == 1) {
-			setuid = 1;
-			uid = n;
-		} else if (sscanf(this_char, "gid=%i%c", &n, &dummy) == 1) {
-			setgid = 1;
-			gid = n;
-		} else if (sscanf(this_char, "mode=%o%c", &n, &dummy) == 1)
-			mode = n & ~S_IFMT;
-		else {
-			kfree(new_opt);
-			printk("capifs: called with bogus options\n");
-			return -EINVAL;
-		}
-	}
-
-	mutex_lock(&s->s_root->d_inode->i_mutex);
-
-	replace_mount_options(s, new_opt);
-	config.setuid  = setuid;
-	config.setgid  = setgid;
-	config.uid     = uid;
-	config.gid     = gid;
-	config.mode    = mode;
-
-	mutex_unlock(&s->s_root->d_inode->i_mutex);
-
-	return 0;
-}
-
-static const struct super_operations capifs_sops =
-{
-	.statfs		= simple_statfs,
-	.remount_fs	= capifs_remount,
-	.show_options	= generic_show_options,
-};
-
-
-static int
-capifs_fill_super(struct super_block *s, void *data, int silent)
-{
-	struct inode * inode;
-
-	s->s_blocksize = 1024;
-	s->s_blocksize_bits = 10;
-	s->s_magic = CAPIFS_SUPER_MAGIC;
-	s->s_op = &capifs_sops;
-	s->s_time_gran = 1;
-
-	inode = new_inode(s);
-	if (!inode)
-		goto fail;
-	inode->i_ino = 1;
-	inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
-	inode->i_mode = S_IFDIR | S_IRUGO | S_IXUGO | S_IWUSR;
-	inode->i_op = &simple_dir_inode_operations;
-	inode->i_fop = &simple_dir_operations;
-	inode->i_nlink = 2;
-
-	s->s_root = d_alloc_root(inode);
-	if (s->s_root)
-		return 0;
-	
-	printk("capifs: get root dentry failed\n");
-	iput(inode);
-fail:
-	return -ENOMEM;
-}
-
-static struct dentry *capifs_mount(struct file_system_type *fs_type,
-	int flags, const char *dev_name, void *data)
-{
-	return mount_single(fs_type, flags, data, capifs_fill_super);
-}
-
-static struct file_system_type capifs_fs_type = {
-	.owner		= THIS_MODULE,
-	.name		= "capifs",
-	.mount		= capifs_mount,
-	.kill_sb	= kill_anon_super,
-};
-
-static struct dentry *new_ncci(unsigned int number, dev_t device)
-{
-	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);
-
-	namelen = sprintf(name, "%d", number);
-	dentry = lookup_one_len(name, root, namelen);
-	if (IS_ERR(dentry)) {
-		dentry = NULL;
-		goto unlock_out;
-	}
-
-	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);
-
-	d_instantiate(dentry, inode);
-	dget(dentry);
-
-unlock_out:
-	mutex_unlock(&root->d_inode->i_mutex);
-
-	return dentry;
-}
-
-struct dentry *capifs_new_ncci(unsigned int number, dev_t device)
-{
-	struct dentry *dentry;
-
-	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;
-}
-
-void capifs_free_ncci(struct dentry *dentry)
-{
-	struct dentry *root = capifs_mnt->mnt_sb->s_root;
-	struct inode *inode;
-
-	if (!dentry)
-		return;
-
-	mutex_lock(&root->d_inode->i_mutex);
-
-	inode = dentry->d_inode;
-	if (inode) {
-		drop_nlink(inode);
-		d_delete(dentry);
-		dput(dentry);
-	}
-	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);
-}
-
-EXPORT_SYMBOL(capifs_new_ncci);
-EXPORT_SYMBOL(capifs_free_ncci);
-
-module_init(capifs_init);
-module_exit(capifs_exit);
diff -druN linux-2.6.39-libre/drivers/isdn/capi/capifs.h linux-3.0-rc7-libre/drivers/isdn/capi/capifs.h
--- linux-2.6.39-libre/drivers/isdn/capi/capifs.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/isdn/capi/capifs.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,28 +0,0 @@
-/* $Id: capifs.h,v 1.1.2.2 2004/01/16 21:09:26 keil Exp $
- * 
- * Copyright 2000 by Carsten Paeth <calle@calle.de>
- *
- * This software may be used and distributed according to the terms
- * of the GNU General Public License, incorporated herein by reference.
- *
- */
-
-#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 -druN linux-2.6.39-libre/drivers/isdn/capi/Kconfig linux-3.0-rc7-libre/drivers/isdn/capi/Kconfig
--- linux-2.6.39-libre/drivers/isdn/capi/Kconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/isdn/capi/Kconfig	2011-07-11 19:51:52.000000000 -0400
@@ -33,21 +33,6 @@
 	  standardized libcapi20 to access this functionality.  You should say
 	  Y/M here.
 
-config ISDN_CAPI_CAPIFS_BOOL
-	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
-
 config ISDN_CAPI_CAPIDRV
 	tristate "CAPI2.0 capidrv interface support"
 	depends on ISDN_I4L
diff -druN linux-2.6.39-libre/drivers/isdn/capi/Makefile linux-3.0-rc7-libre/drivers/isdn/capi/Makefile
--- linux-2.6.39-libre/drivers/isdn/capi/Makefile	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/isdn/capi/Makefile	2011-07-11 19:51:52.000000000 -0400
@@ -7,7 +7,6 @@
 obj-$(CONFIG_ISDN_CAPI)			+= kernelcapi.o
 obj-$(CONFIG_ISDN_CAPI_CAPI20)		+= capi.o 
 obj-$(CONFIG_ISDN_CAPI_CAPIDRV)		+= capidrv.o
-obj-$(CONFIG_ISDN_CAPI_CAPIFS)		+= capifs.o
 
 # Multipart objects.
 
diff -druN linux-2.6.39-libre/drivers/isdn/gigaset/bas-gigaset.c linux-3.0-rc7-libre/drivers/isdn/gigaset/bas-gigaset.c
--- linux-2.6.39-libre/drivers/isdn/gigaset/bas-gigaset.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/isdn/gigaset/bas-gigaset.c	2011-07-11 19:51:52.000000000 -0400
@@ -1157,7 +1157,6 @@
 	struct urb *urb;
 	int status;
 	struct usb_iso_packet_descriptor *ifd;
-	int offset;
 	unsigned long flags;
 	int i;
 	struct sk_buff *skb;
@@ -1225,7 +1224,6 @@
 			 *   successfully sent
 			 * - all following frames are not sent at all
 			 */
-			offset = done->limit;	/* default (no error) */
 			for (i = 0; i < BAS_NUMFRAMES; i++) {
 				ifd = &urb->iso_frame_desc[i];
 				if (ifd->status ||
@@ -1235,9 +1233,6 @@
 						 i, ifd->actual_length,
 						 ifd->length,
 						 get_usb_statmsg(ifd->status));
-					offset = (ifd->offset +
-						  ifd->actual_length)
-						 % BAS_OUTBUFSIZE;
 					break;
 				}
 			}
diff -druN linux-2.6.39-libre/drivers/isdn/gigaset/ev-layer.c linux-3.0-rc7-libre/drivers/isdn/gigaset/ev-layer.c
--- linux-2.6.39-libre/drivers/isdn/gigaset/ev-layer.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/isdn/gigaset/ev-layer.c	2011-07-11 19:51:52.000000000 -0400
@@ -390,12 +390,12 @@
  */
 static int cid_of_response(char *s)
 {
-	unsigned long cid;
+	int cid;
 	int rc;
 
 	if (s[-1] != ';')
 		return 0;	/* no CID separator */
-	rc = strict_strtoul(s, 10, &cid);
+	rc = kstrtoint(s, 10, &cid);
 	if (rc)
 		return 0;	/* CID not numeric */
 	if (cid < 1 || cid > 65535)
@@ -566,27 +566,19 @@
 		case RT_ZCAU:
 			event->parameter = -1;
 			if (curarg + 1 < params) {
-				unsigned long type, value;
-
-				i = strict_strtoul(argv[curarg++], 16, &type);
-				j = strict_strtoul(argv[curarg++], 16, &value);
+				u8 type, value;
 
-				if (i == 0 && type < 256 &&
-				    j == 0 && value < 256)
+				i = kstrtou8(argv[curarg++], 16, &type);
+				j = kstrtou8(argv[curarg++], 16, &value);
+				if (i == 0 && j == 0)
 					event->parameter = (type << 8) | value;
 			} else
 				curarg = params - 1;
 			break;
 		case RT_NUMBER:
-			event->parameter = -1;
-			if (curarg < params) {
-				unsigned long res;
-				int rc;
-
-				rc = strict_strtoul(argv[curarg++], 10, &res);
-				if (rc == 0)
-					event->parameter = res;
-			}
+			if (curarg >= params ||
+			    kstrtoint(argv[curarg++], 10, &event->parameter))
+				event->parameter = -1;
 			gig_dbg(DEBUG_EVENT, "parameter==%d", event->parameter);
 			break;
 		}
diff -druN linux-2.6.39-libre/drivers/isdn/gigaset/interface.c linux-3.0-rc7-libre/drivers/isdn/gigaset/interface.c
--- linux-2.6.39-libre/drivers/isdn/gigaset/interface.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/isdn/gigaset/interface.c	2011-07-11 19:51:52.000000000 -0400
@@ -156,8 +156,10 @@
 	if (!cs || !try_module_get(cs->driver->owner))
 		return -ENODEV;
 
-	if (mutex_lock_interruptible(&cs->mutex))
+	if (mutex_lock_interruptible(&cs->mutex)) {
+		module_put(cs->driver->owner);
 		return -ERESTARTSYS;
+	}
 	tty->driver_data = cs;
 
 	++cs->open_count;
diff -druN linux-2.6.39-libre/drivers/isdn/hardware/avm/avm_cs.c linux-3.0-rc7-libre/drivers/isdn/hardware/avm/avm_cs.c
--- linux-2.6.39-libre/drivers/isdn/hardware/avm/avm_cs.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/isdn/hardware/avm/avm_cs.c	2011-07-11 19:51:52.000000000 -0400
@@ -149,7 +149,7 @@
 } /* avmcs_release */
 
 
-static struct pcmcia_device_id avmcs_ids[] = {
+static const struct pcmcia_device_id avmcs_ids[] = {
 	PCMCIA_DEVICE_PROD_ID12("AVM", "ISDN-Controller B1", 0x95d42008, 0x845dc335),
 	PCMCIA_DEVICE_PROD_ID12("AVM", "Mobile ISDN-Controller M1", 0x95d42008, 0x81e10430),
 	PCMCIA_DEVICE_PROD_ID12("AVM", "Mobile ISDN-Controller M2", 0x95d42008, 0x18e8558a),
diff -druN linux-2.6.39-libre/drivers/isdn/hardware/eicon/debug.c linux-3.0-rc7-libre/drivers/isdn/hardware/eicon/debug.c
--- linux-2.6.39-libre/drivers/isdn/hardware/eicon/debug.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/isdn/hardware/eicon/debug.c	2011-07-11 19:51:52.000000000 -0400
@@ -861,7 +861,7 @@
 void diva_mnt_add_xdi_adapter (const DESCRIPTOR* d) {
   diva_os_spin_lock_magic_t old_irql, old_irql1;
   dword sec, usec, logical, serial, org_mask;
-  int id, best_id = 0, free_id = -1;
+  int id, free_id = -1;
   char tmp[128];
   diva_dbg_entry_head_t* pmsg = NULL;
   int len;
@@ -906,7 +906,6 @@
         and slot is still free - reuse it
         */
       free_id = id;
-      best_id = 1;
       break;
     }
   }
diff -druN linux-2.6.39-libre/drivers/isdn/hardware/eicon/divasfunc.c linux-3.0-rc7-libre/drivers/isdn/hardware/eicon/divasfunc.c
--- linux-2.6.39-libre/drivers/isdn/hardware/eicon/divasfunc.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/isdn/hardware/eicon/divasfunc.c	2011-07-11 19:51:52.000000000 -0400
@@ -113,9 +113,8 @@
 static void start_dbg(void)
 {
 	DbgRegister("DIVAS", DRIVERRELEASE_DIVAS, (debugmask) ? debugmask : DBG_DEFAULT);
-	DBG_LOG(("DIVA ISDNXDI BUILD (%s[%s]-%s-%s)",
-		 DIVA_BUILD, diva_xdi_common_code_build, __DATE__,
-		 __TIME__))
+	DBG_LOG(("DIVA ISDNXDI BUILD (%s[%s])",
+		 DIVA_BUILD, diva_xdi_common_code_build))
 }
 
 /*
diff -druN linux-2.6.39-libre/drivers/isdn/hardware/eicon/message.c linux-3.0-rc7-libre/drivers/isdn/hardware/eicon/message.c
--- linux-2.6.39-libre/drivers/isdn/hardware/eicon/message.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/isdn/hardware/eicon/message.c	2011-07-11 19:51:52.000000000 -0400
@@ -1198,7 +1198,6 @@
   word ch;
   word i;
   word Info;
-  word CIP;
   byte LinkLayer;
   API_PARSE * ai;
   API_PARSE * bp;
@@ -1340,7 +1339,6 @@
         add_s(plci,BC,&parms[6]);
         add_s(plci,LLC,&parms[7]);
         add_s(plci,HLC,&parms[8]);
-        CIP = GET_WORD(parms[0].info);
         if (a->Info_Mask[appl->Id-1] & 0x200)
         {
           /* early B3 connect (CIP mask bit 9) no release after a disc */
@@ -4830,7 +4828,6 @@
   dword x_Id;
   dword Id;
   dword rId;
-  word Number = 0;
   word i;
   word cip;
   dword cip_mask;
@@ -5106,7 +5103,7 @@
     }
   }
 
-  if(plci->appl) Number = plci->appl->Number++;
+  if(plci->appl) plci->appl->Number++;
 
   switch(plci->Sig.Ind) {
   /* Response to Get_Supported_Services request */
@@ -5894,7 +5891,6 @@
     break;
 
   case TEL_CTRL:
-    Number = 0;
     ie = multi_fac_parms[0]; /* inspect the facility hook indications */
     if(plci->State==ADVANCED_VOICE_SIG && ie[0]){
       switch (ie[1]&0x91) {
@@ -10119,14 +10115,12 @@
 
 static void dtmf_confirmation (dword Id, PLCI   *plci)
 {
-  word Info;
   word i;
     byte result[4];
 
   dbug (1, dprintf ("[%06lx] %s,%d: dtmf_confirmation",
     UnMapId (Id), (char   *)(FILE_), __LINE__));
 
-  Info = GOOD;
   result[0] = 2;
   PUT_WORD (&result[1], DTMF_SUCCESS);
   if (plci->dtmf_send_requests != 0)
@@ -11520,13 +11514,12 @@
 static void mixer_command (dword Id, PLCI   *plci, byte Rc)
 {
   DIVA_CAPI_ADAPTER   *a;
-  word i, internal_command, Info;
+  word i, internal_command;
 
   dbug (1, dprintf ("[%06lx] %s,%d: mixer_command %02x %04x %04x",
     UnMapId (Id), (char   *)(FILE_), __LINE__, Rc, plci->internal_command,
     plci->li_cmd));
 
-  Info = GOOD;
   a = plci->adapter;
   internal_command = plci->internal_command;
   plci->internal_command = 0;
@@ -11550,7 +11543,6 @@
         {
           dbug (1, dprintf ("[%06lx] %s,%d: Load mixer failed",
             UnMapId (Id), (char   *)(FILE_), __LINE__));
-          Info = _FACILITY_NOT_SUPPORTED;
           break;
         }
         if (plci->internal_command)
@@ -11592,7 +11584,6 @@
             } while ((plci->li_plci_b_write_pos != plci->li_plci_b_req_pos)
               && !(plci->li_plci_b_queue[i] & LI_PLCI_B_LAST_FLAG));
           }
-          Info = _FACILITY_NOT_SUPPORTED;
           break;
         }
         if (plci->internal_command)
@@ -11610,7 +11601,6 @@
         {
           dbug (1, dprintf ("[%06lx] %s,%d: Unload mixer failed",
             UnMapId (Id), (char   *)(FILE_), __LINE__));
-          Info = _FACILITY_NOT_SUPPORTED;
           break;
         }
         if (plci->internal_command)
@@ -12448,13 +12438,11 @@
 static void mixer_indication_coefs_set (dword Id, PLCI   *plci)
 {
   dword d;
-  DIVA_CAPI_ADAPTER   *a;
     byte result[12];
 
   dbug (1, dprintf ("[%06lx] %s,%d: mixer_indication_coefs_set",
     UnMapId (Id), (char   *)(FILE_), __LINE__));
 
-  a = plci->adapter;
   if (plci->li_plci_b_read_pos != plci->li_plci_b_req_pos)
   {
     do
@@ -14111,13 +14099,11 @@
 
 static void fax_connect_ack_command (dword Id, PLCI   *plci, byte Rc)
 {
-  word Info;
   word internal_command;
 
   dbug (1, dprintf ("[%06lx] %s,%d: fax_connect_ack_command %02x %04x",
     UnMapId (Id), (char   *)(FILE_), __LINE__, Rc, plci->internal_command));
 
-  Info = GOOD;
   internal_command = plci->internal_command;
   plci->internal_command = 0;
   switch (internal_command)
@@ -14160,13 +14146,11 @@
 
 static void fax_edata_ack_command (dword Id, PLCI   *plci, byte Rc)
 {
-  word Info;
   word internal_command;
 
   dbug (1, dprintf ("[%06lx] %s,%d: fax_edata_ack_command %02x %04x",
     UnMapId (Id), (char   *)(FILE_), __LINE__, Rc, plci->internal_command));
 
-  Info = GOOD;
   internal_command = plci->internal_command;
   plci->internal_command = 0;
   switch (internal_command)
@@ -14395,13 +14379,11 @@
 
 static void rtp_connect_b3_res_command (dword Id, PLCI   *plci, byte Rc)
 {
-  word Info;
   word internal_command;
 
   dbug (1, dprintf ("[%06lx] %s,%d: rtp_connect_b3_res_command %02x %04x",
     UnMapId (Id), (char   *)(FILE_), __LINE__, Rc, plci->internal_command));
 
-  Info = GOOD;
   internal_command = plci->internal_command;
   plci->internal_command = 0;
   switch (internal_command)
@@ -14423,7 +14405,6 @@
     {
       dbug (1, dprintf ("[%06lx] %s,%d: RTP setting connect resp info failed %02x",
         UnMapId (Id), (char   *)(FILE_), __LINE__, Rc));
-      Info = _WRONG_STATE;
       break;
     }
     if (plci_nl_busy (plci))
diff -druN linux-2.6.39-libre/drivers/isdn/hardware/mISDN/hfcpci.c linux-3.0-rc7-libre/drivers/isdn/hardware/mISDN/hfcpci.c
--- linux-2.6.39-libre/drivers/isdn/hardware/mISDN/hfcpci.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/isdn/hardware/mISDN/hfcpci.c	2011-07-11 19:51:52.000000000 -0400
@@ -405,7 +405,7 @@
     u_char *bdata, int count)
 {
 	u_char		*ptr, *ptr1, new_f2;
-	int		total, maxlen, new_z2;
+	int		maxlen, new_z2;
 	struct zt	*zp;
 
 	if ((bch->debug & DEBUG_HW_BCHANNEL) && !(bch->debug & DEBUG_HW_BFIFO))
@@ -431,7 +431,6 @@
 			printk(KERN_WARNING "HFCPCI: receive out of memory\n");
 			return;
 		}
-		total = count;
 		count -= 3;
 		ptr = skb_put(bch->rx_skb, count);
 
@@ -968,7 +967,6 @@
 ph_state_nt(struct dchannel *dch)
 {
 	struct hfc_pci	*hc = dch->hw;
-	u_char	val;
 
 	if (dch->debug)
 		printk(KERN_DEBUG "%s: NT newstate %x\n",
@@ -982,7 +980,7 @@
 			hc->hw.int_m1 &= ~HFCPCI_INTS_TIMER;
 			Write_hfc(hc, HFCPCI_INT_M1, hc->hw.int_m1);
 			/* Clear already pending ints */
-			val = Read_hfc(hc, HFCPCI_INT_S1);
+			(void) Read_hfc(hc, HFCPCI_INT_S1);
 			Write_hfc(hc, HFCPCI_STATES, 4 | HFCPCI_LOAD_STATE);
 			udelay(10);
 			Write_hfc(hc, HFCPCI_STATES, 4);
diff -druN linux-2.6.39-libre/drivers/isdn/hardware/mISDN/hfcsusb.c linux-3.0-rc7-libre/drivers/isdn/hardware/mISDN/hfcsusb.c
--- linux-2.6.39-libre/drivers/isdn/hardware/mISDN/hfcsusb.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/isdn/hardware/mISDN/hfcsusb.c	2011-07-11 19:51:52.000000000 -0400
@@ -118,14 +118,12 @@
 ctrl_complete(struct urb *urb)
 {
 	struct hfcsusb *hw = (struct hfcsusb *) urb->context;
-	struct ctrl_buf *buf;
 
 	if (debug & DBG_HFC_CALL_TRACE)
 		printk(KERN_DEBUG "%s: %s\n", hw->name, __func__);
 
 	urb->dev = hw->dev;
 	if (hw->ctrl_cnt) {
-		buf = &hw->ctrl_buff[hw->ctrl_out_idx];
 		hw->ctrl_cnt--;	/* decrement actual count */
 		if (++hw->ctrl_out_idx >= HFC_CTRL_BUFSIZE)
 			hw->ctrl_out_idx = 0;	/* pointer wrap */
@@ -285,6 +283,7 @@
 	_queue_data(&dch->dev.D, MPH_INFORMATION_IND, MISDN_ID_ANY,
 		sizeof(struct ph_info_dch) + dch->dev.nrbchan *
 		sizeof(struct ph_info_ch), phi, GFP_ATOMIC);
+	kfree(phi);
 }
 
 /*
@@ -1726,7 +1725,6 @@
 static int
 setup_hfcsusb(struct hfcsusb *hw)
 {
-	int err;
 	u_char b;
 
 	if (debug & DBG_HFC_CALL_TRACE)
@@ -1745,7 +1743,7 @@
 	}
 
 	/* first set the needed config, interface and alternate */
-	err = usb_set_interface(hw->dev, hw->if_used, hw->alt_used);
+	(void) usb_set_interface(hw->dev, hw->if_used, hw->alt_used);
 
 	hw->led_state = 0;
 
diff -druN linux-2.6.39-libre/drivers/isdn/hardware/mISDN/netjet.c linux-3.0-rc7-libre/drivers/isdn/hardware/mISDN/netjet.c
--- linux-2.6.39-libre/drivers/isdn/hardware/mISDN/netjet.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/isdn/hardware/mISDN/netjet.c	2011-07-11 19:51:52.000000000 -0400
@@ -1072,6 +1072,12 @@
 		return -ENODEV;
 	}
 
+	if (pdev->subsystem_vendor == 0xb100 &&
+	    pdev->subsystem_device == 0x0003 ) {
+		pr_notice("Netjet: Digium TDM400P not handled yet\n");
+		return -ENODEV;
+	}
+
 	card = kzalloc(sizeof(struct tiger_hw), GFP_ATOMIC);
 	if (!card) {
 		pr_info("No kmem for Netjet\n");
diff -druN linux-2.6.39-libre/drivers/isdn/hisax/arcofi.c linux-3.0-rc7-libre/drivers/isdn/hisax/arcofi.c
--- linux-2.6.39-libre/drivers/isdn/hisax/arcofi.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/isdn/hisax/arcofi.c	2011-07-11 19:51:52.000000000 -0400
@@ -30,8 +30,6 @@
 
 static void
 send_arcofi(struct IsdnCardState *cs) {
-	u_char val;
-	
 	add_arcofi_timer(cs);
 	cs->dc.isac.mon_txp = 0;
 	cs->dc.isac.mon_txc = cs->dc.isac.arcofi_list->len;
@@ -45,7 +43,7 @@
 	cs->dc.isac.mocr &= 0x0f;
 	cs->dc.isac.mocr |= 0xa0;
 	cs->writeisac(cs, ISAC_MOCR, cs->dc.isac.mocr);
-	val = cs->readisac(cs, ISAC_MOSR);
+	(void) cs->readisac(cs, ISAC_MOSR);
 	cs->writeisac(cs, ISAC_MOX1, cs->dc.isac.mon_tx[cs->dc.isac.mon_txp++]);
 	cs->dc.isac.mocr |= 0x10;
 	cs->writeisac(cs, ISAC_MOCR, cs->dc.isac.mocr);
diff -druN linux-2.6.39-libre/drivers/isdn/hisax/avma1_cs.c linux-3.0-rc7-libre/drivers/isdn/hisax/avma1_cs.c
--- linux-2.6.39-libre/drivers/isdn/hisax/avma1_cs.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/isdn/hisax/avma1_cs.c	2011-07-11 19:51:52.000000000 -0400
@@ -146,7 +146,7 @@
 	pcmcia_disable_device(link);
 } /* avma1cs_release */
 
-static struct pcmcia_device_id avma1cs_ids[] = {
+static const struct pcmcia_device_id avma1cs_ids[] = {
 	PCMCIA_DEVICE_PROD_ID12("AVM", "ISDN A", 0x95d42008, 0xadc9d4bb),
 	PCMCIA_DEVICE_PROD_ID12("ISDN", "CARD", 0x8d9761c8, 0x01c5aa7b),
 	PCMCIA_DEVICE_NULL
diff -druN linux-2.6.39-libre/drivers/isdn/hisax/elsa_cs.c linux-3.0-rc7-libre/drivers/isdn/hisax/elsa_cs.c
--- linux-2.6.39-libre/drivers/isdn/hisax/elsa_cs.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/isdn/hisax/elsa_cs.c	2011-07-11 19:51:52.000000000 -0400
@@ -129,12 +129,10 @@
 
 static int __devinit elsa_cs_config(struct pcmcia_device *link)
 {
-    local_info_t *dev;
     int i;
     IsdnCard_t icard;
 
     dev_dbg(&link->dev, "elsa_config(0x%p)\n", link);
-    dev = link->priv;
 
     link->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_SET_IO;
 
@@ -202,7 +200,7 @@
 	return 0;
 }
 
-static struct pcmcia_device_id elsa_ids[] = {
+static const struct pcmcia_device_id elsa_ids[] = {
 	PCMCIA_DEVICE_PROD_ID12("ELSA AG (Aachen, Germany)", "MicroLink ISDN/MC ", 0x983de2c4, 0x333ba257),
 	PCMCIA_DEVICE_PROD_ID12("ELSA GmbH, Aachen", "MicroLink ISDN/MC ", 0x639e5718, 0x333ba257),
 	PCMCIA_DEVICE_NULL
diff -druN linux-2.6.39-libre/drivers/isdn/hisax/elsa_ser.c linux-3.0-rc7-libre/drivers/isdn/hisax/elsa_ser.c
--- linux-2.6.39-libre/drivers/isdn/hisax/elsa_ser.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/isdn/hisax/elsa_ser.c	2011-07-11 19:51:52.000000000 -0400
@@ -109,11 +109,10 @@
 {
 	int	quot = 0, baud_base;
 	unsigned cval, fcr = 0;
-	int	bits;
 
 
 	/* byte size and parity */
-	cval = 0x03; bits = 10;
+	cval = 0x03;
 	/* Determine divisor based on baud rate */
 	baud_base = BASE_BAUD;
 	quot = baud_base / baud;
diff -druN linux-2.6.39-libre/drivers/isdn/hisax/hfc_usb.c linux-3.0-rc7-libre/drivers/isdn/hisax/hfc_usb.c
--- linux-2.6.39-libre/drivers/isdn/hisax/hfc_usb.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/isdn/hisax/hfc_usb.c	2011-07-11 19:51:52.000000000 -0400
@@ -258,11 +258,9 @@
 ctrl_complete(struct urb *urb)
 {
 	hfcusb_data *hfc = (hfcusb_data *) urb->context;
-	ctrl_buft *buf;
 
 	urb->dev = hfc->dev;
 	if (hfc->ctrl_cnt) {
-		buf = &hfc->ctrl_buff[hfc->ctrl_out_idx];
 		hfc->ctrl_cnt--;	/* decrement actual count */
 		if (++hfc->ctrl_out_idx >= HFC_CTRL_BUFSIZE)
 			hfc->ctrl_out_idx = 0;	/* pointer wrap */
@@ -1097,7 +1095,7 @@
 hfc_usb_init(hfcusb_data * hfc)
 {
 	usb_fifo *fifo;
-	int i, err;
+	int i;
 	u_char b;
 	struct hisax_b_if *p_b_if[2];
 
@@ -1112,7 +1110,7 @@
 	}
 
 	/* first set the needed config, interface and alternate */
-	err = usb_set_interface(hfc->dev, hfc->if_used, hfc->alt_used);
+	usb_set_interface(hfc->dev, hfc->if_used, hfc->alt_used);
 
 	/* do Chip reset */
 	write_usb(hfc, HFCUSB_CIRM, 8);
diff -druN linux-2.6.39-libre/drivers/isdn/hisax/ipacx.c linux-3.0-rc7-libre/drivers/isdn/hisax/ipacx.c
--- linux-2.6.39-libre/drivers/isdn/hisax/ipacx.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/isdn/hisax/ipacx.c	2011-07-11 19:51:52.000000000 -0400
@@ -96,7 +96,7 @@
 {
 	struct IsdnCardState *cs = (struct IsdnCardState *) st->l1.hardware;
 	struct sk_buff *skb = arg;
-  u_char cda1_cr, cda2_cr;
+	u_char cda1_cr;
 
 	switch (pr) {
 		case (PH_DATA |REQUEST):
@@ -163,7 +163,7 @@
       cs->writeisac(cs, IPACX_CDA_TSDP10, 0x80); // Timeslot 0 is B1
       cs->writeisac(cs, IPACX_CDA_TSDP11, 0x81); // Timeslot 0 is B1
       cda1_cr = cs->readisac(cs, IPACX_CDA1_CR);
-      cda2_cr = cs->readisac(cs, IPACX_CDA2_CR);
+      (void) cs->readisac(cs, IPACX_CDA2_CR);
 			if ((long)arg &1) { // loop B1
         cs->writeisac(cs, IPACX_CDA1_CR, cda1_cr |0x0a); 
       }
diff -druN linux-2.6.39-libre/drivers/isdn/hisax/jade.c linux-3.0-rc7-libre/drivers/isdn/hisax/jade.c
--- linux-2.6.39-libre/drivers/isdn/hisax/jade.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/isdn/hisax/jade.c	2011-07-11 19:51:52.000000000 -0400
@@ -23,10 +23,9 @@
 int
 JadeVersion(struct IsdnCardState *cs, char *s)
 {
-    int ver,i;
+    int ver;
     int to = 50;
     cs->BC_Write_Reg(cs, -1, 0x50, 0x19);
-    i=0;
     while (to) {
     	udelay(1);
 	ver = cs->BC_Read_Reg(cs, -1, 0x60);
diff -druN linux-2.6.39-libre/drivers/isdn/hisax/l3dss1.c linux-3.0-rc7-libre/drivers/isdn/hisax/l3dss1.c
--- linux-2.6.39-libre/drivers/isdn/hisax/l3dss1.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/isdn/hisax/l3dss1.c	2011-07-11 19:51:52.000000000 -0400
@@ -2943,7 +2943,7 @@
 static void
 dss1up(struct PStack *st, int pr, void *arg)
 {
-	int i, mt, cr, cause, callState;
+	int i, mt, cr, callState;
 	char *ptr;
 	u_char *p;
 	struct sk_buff *skb = arg;
@@ -3034,12 +3034,10 @@
 				return;
 			}
 		} else if (mt == MT_STATUS) {
-			cause = 0;
 			if ((ptr = findie(skb->data, skb->len, IE_CAUSE, 0)) != NULL) {
 				ptr++;
 				if (*ptr++ == 2)
 					ptr++;
-				cause = *ptr & 0x7f;
 			}
 			callState = 0;
 			if ((ptr = findie(skb->data, skb->len, IE_CALL_STATE, 0)) != NULL) {
diff -druN linux-2.6.39-libre/drivers/isdn/hisax/l3ni1.c linux-3.0-rc7-libre/drivers/isdn/hisax/l3ni1.c
--- linux-2.6.39-libre/drivers/isdn/hisax/l3ni1.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/isdn/hisax/l3ni1.c	2011-07-11 19:51:52.000000000 -0400
@@ -2883,7 +2883,7 @@
 static void
 ni1up(struct PStack *st, int pr, void *arg)
 {
-	int i, mt, cr, cause, callState;
+	int i, mt, cr, callState;
 	char *ptr;
 	u_char *p;
 	struct sk_buff *skb = arg;
@@ -2986,12 +2986,10 @@
 				return;
 			}
 		} else if (mt == MT_STATUS) {
-			cause = 0;
 			if ((ptr = findie(skb->data, skb->len, IE_CAUSE, 0)) != NULL) {
 				ptr++;
 				if (*ptr++ == 2)
 					ptr++;
-				cause = *ptr & 0x7f;
 			}
 			callState = 0;
 			if ((ptr = findie(skb->data, skb->len, IE_CALL_STATE, 0)) != NULL) {
diff -druN linux-2.6.39-libre/drivers/isdn/hisax/sedlbauer_cs.c linux-3.0-rc7-libre/drivers/isdn/hisax/sedlbauer_cs.c
--- linux-2.6.39-libre/drivers/isdn/hisax/sedlbauer_cs.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/isdn/hisax/sedlbauer_cs.c	2011-07-11 19:51:52.000000000 -0400
@@ -186,7 +186,7 @@
 }
 
 
-static struct pcmcia_device_id sedlbauer_ids[] = {
+static const struct pcmcia_device_id sedlbauer_ids[] = {
 	PCMCIA_DEVICE_PROD_ID123("SEDLBAUER", "speed star II", "V 3.1", 0x81fb79f5, 0xf3612e1d, 0x6b95c78a),
 	PCMCIA_DEVICE_PROD_ID123("SEDLBAUER", "ISDN-Adapter", "4D67", 0x81fb79f5, 0xe4e9bc12, 0x397b7e90),
 	PCMCIA_DEVICE_PROD_ID123("SEDLBAUER", "ISDN-Adapter", "4D98", 0x81fb79f5, 0xe4e9bc12, 0x2e5c7fce),
diff -druN linux-2.6.39-libre/drivers/isdn/hisax/st5481.h linux-3.0-rc7-libre/drivers/isdn/hisax/st5481.h
--- linux-2.6.39-libre/drivers/isdn/hisax/st5481.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/isdn/hisax/st5481.h	2011-07-11 19:51:52.000000000 -0400
@@ -377,7 +377,6 @@
 };
 
 struct st5481_adapter {
-	struct list_head list;
 	int number_of_leds;
 	struct usb_device *usb_dev;
 	struct hisax_d_if hisax_d_if;
diff -druN linux-2.6.39-libre/drivers/isdn/hisax/st5481_init.c linux-3.0-rc7-libre/drivers/isdn/hisax/st5481_init.c
--- linux-2.6.39-libre/drivers/isdn/hisax/st5481_init.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/isdn/hisax/st5481_init.c	2011-07-11 19:51:52.000000000 -0400
@@ -46,8 +46,6 @@
 #endif
 int st5481_debug;
 
-static LIST_HEAD(adapter_list);
-
 /* ======================================================================
  * registration/deregistration with the USB layer
  */
@@ -86,7 +84,6 @@
 		adapter->bcs[i].b_if.ifc.priv = &adapter->bcs[i];
 		adapter->bcs[i].b_if.ifc.l2l1 = st5481_b_l2l1;
 	}
-	list_add(&adapter->list, &adapter_list);
 
 	retval = st5481_setup_usb(adapter);
 	if (retval < 0)
@@ -125,6 +122,7 @@
  err_usb:
 	st5481_release_usb(adapter);
  err:
+	kfree(adapter);
 	return -EIO;
 }
 
@@ -142,8 +140,6 @@
 	if (!adapter)
 		return;
 	
-	list_del(&adapter->list);
-
 	st5481_stop(adapter);
 	st5481_release_b(&adapter->bcs[1]);
 	st5481_release_b(&adapter->bcs[0]);
diff -druN linux-2.6.39-libre/drivers/isdn/hisax/teles_cs.c linux-3.0-rc7-libre/drivers/isdn/hisax/teles_cs.c
--- linux-2.6.39-libre/drivers/isdn/hisax/teles_cs.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/isdn/hisax/teles_cs.c	2011-07-11 19:51:52.000000000 -0400
@@ -111,12 +111,10 @@
 
 static int __devinit teles_cs_config(struct pcmcia_device *link)
 {
-    local_info_t *dev;
     int i;
     IsdnCard_t icard;
 
     dev_dbg(&link->dev, "teles_config(0x%p)\n", link);
-    dev = link->priv;
 
     i = pcmcia_loop_config(link, teles_cs_configcheck, NULL);
     if (i != 0)
@@ -185,7 +183,7 @@
 }
 
 
-static struct pcmcia_device_id teles_ids[] = {
+static const struct pcmcia_device_id teles_ids[] = {
 	PCMCIA_DEVICE_PROD_ID12("TELES", "S0/PC", 0x67b50eae, 0xe9e70119),
 	PCMCIA_DEVICE_NULL,
 };
diff -druN linux-2.6.39-libre/drivers/isdn/hysdn/hysdn_proclog.c linux-3.0-rc7-libre/drivers/isdn/hysdn/hysdn_proclog.c
--- linux-2.6.39-libre/drivers/isdn/hysdn/hysdn_proclog.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/isdn/hysdn/hysdn_proclog.c	2011-07-11 19:51:52.000000000 -0400
@@ -155,7 +155,6 @@
 static ssize_t
 hysdn_log_write(struct file *file, const char __user *buf, size_t count, loff_t * off)
 {
-	unsigned long u = 0;
 	int rc;
 	unsigned char valbuf[128];
 	hysdn_card *card = file->private_data;
@@ -167,12 +166,10 @@
 
 	valbuf[count] = 0;	/* terminating 0 */
 
-	rc = strict_strtoul(valbuf, 0, &u);
-
-	if (rc == 0) {
-		card->debug_flags = u;	/* remember debug flags */
-		hysdn_addlog(card, "debug set to 0x%lx", card->debug_flags);
-	}
+	rc = kstrtoul(valbuf, 0, &card->debug_flags);
+	if (rc < 0)
+		return rc;
+	hysdn_addlog(card, "debug set to 0x%lx", card->debug_flags);
 	return (count);
 }				/* hysdn_log_write */
 
diff -druN linux-2.6.39-libre/drivers/isdn/i4l/isdn_common.c linux-3.0-rc7-libre/drivers/isdn/i4l/isdn_common.c
--- linux-2.6.39-libre/drivers/isdn/i4l/isdn_common.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/isdn/i4l/isdn_common.c	2011-07-11 19:51:52.000000000 -0400
@@ -399,13 +399,8 @@
 #include <linux/isdn/capicmd.h>
 
 static int
-isdn_capi_rec_hl_msg(capi_msg *cm) {
-	
-	int di;
-	int ch;
-	
-	di = (cm->adr.Controller & 0x7f) -1;
-	ch = isdn_dc2minor(di, (cm->adr.Controller>>8)& 0x7f);
+isdn_capi_rec_hl_msg(capi_msg *cm)
+{
 	switch(cm->Command) {
 		case CAPI_FACILITY:
 			/* in the moment only handled in tty */
@@ -1278,7 +1273,6 @@
 	uint minor = iminor(file->f_path.dentry->d_inode);
 	isdn_ctrl c;
 	int drvidx;
-	int chidx;
 	int ret;
 	int i;
 	char __user *p;
@@ -1340,7 +1334,6 @@
 		drvidx = isdn_minor2drv(minor);
 		if (drvidx < 0)
 			return -ENODEV;
-		chidx = isdn_minor2chan(minor);
 		if (!(dev->drv[drvidx]->flags & DRV_FLAG_RUNNING))
 			return -ENODEV;
 		return 0;
diff -druN linux-2.6.39-libre/drivers/isdn/i4l/isdn_net.c linux-3.0-rc7-libre/drivers/isdn/i4l/isdn_net.c
--- linux-2.6.39-libre/drivers/isdn/i4l/isdn_net.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/isdn/i4l/isdn_net.c	2011-07-11 19:51:52.000000000 -0400
@@ -1678,7 +1678,6 @@
 	u32 your_seq;
 	__be32 local;
 	__be32 *addr, *mask;
-	u16 unused;
 
 	if (skb->len < 14)
 		return;
@@ -1722,7 +1721,6 @@
 		lp->cisco_last_slarp_in = jiffies;
 		my_seq = be32_to_cpup((__be32 *)(p + 0));
 		your_seq = be32_to_cpup((__be32 *)(p + 4));
-		unused = be16_to_cpup((__be16 *)(p + 8));
 		p += 10;
 		lp->cisco_yourseq = my_seq;
 		lp->cisco_mineseen = your_seq;
diff -druN linux-2.6.39-libre/drivers/isdn/i4l/isdn_tty.c linux-3.0-rc7-libre/drivers/isdn/i4l/isdn_tty.c
--- linux-2.6.39-libre/drivers/isdn/i4l/isdn_tty.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/isdn/i4l/isdn_tty.c	2011-07-11 19:51:52.000000000 -0400
@@ -998,7 +998,6 @@
 {
 	uint cflag,
 	 cval,
-	 fcr,
 	 quot;
 	int i;
 
@@ -1037,7 +1036,6 @@
 		cval |= UART_LCR_PARITY;
 	if (!(cflag & PARODD))
 		cval |= UART_LCR_EPAR;
-	fcr = 0;
 
 	/* CTS flow control flag and modem status interrupts */
 	if (cflag & CRTSCTS) {
diff -druN linux-2.6.39-libre/drivers/isdn/mISDN/layer2.c linux-3.0-rc7-libre/drivers/isdn/mISDN/layer2.c
--- linux-2.6.39-libre/drivers/isdn/mISDN/layer2.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/isdn/mISDN/layer2.c	2011-07-11 19:51:52.000000000 -0400
@@ -1640,7 +1640,7 @@
 }
 
 static void
-l2_st14_persistant_da(struct FsmInst *fi, int event, void *arg)
+l2_st14_persistent_da(struct FsmInst *fi, int event, void *arg)
 {
 	struct layer2 *l2 = fi->userdata;
 	struct sk_buff *skb = arg;
@@ -1654,7 +1654,7 @@
 }
 
 static void
-l2_st5_persistant_da(struct FsmInst *fi, int event, void *arg)
+l2_st5_persistent_da(struct FsmInst *fi, int event, void *arg)
 {
 	struct layer2 *l2 = fi->userdata;
 	struct sk_buff *skb = arg;
@@ -1671,7 +1671,7 @@
 }
 
 static void
-l2_st6_persistant_da(struct FsmInst *fi, int event, void *arg)
+l2_st6_persistent_da(struct FsmInst *fi, int event, void *arg)
 {
 	struct layer2 *l2 = fi->userdata;
 	struct sk_buff *skb = arg;
@@ -1685,7 +1685,7 @@
 }
 
 static void
-l2_persistant_da(struct FsmInst *fi, int event, void *arg)
+l2_persistent_da(struct FsmInst *fi, int event, void *arg)
 {
 	struct layer2 *l2 = fi->userdata;
 	struct sk_buff *skb = arg;
@@ -1829,14 +1829,14 @@
 	{ST_L2_6, EV_L2_FRAME_ERROR, l2_frame_error},
 	{ST_L2_7, EV_L2_FRAME_ERROR, l2_frame_error_reest},
 	{ST_L2_8, EV_L2_FRAME_ERROR, l2_frame_error_reest},
-	{ST_L2_1, EV_L1_DEACTIVATE, l2_st14_persistant_da},
+	{ST_L2_1, EV_L1_DEACTIVATE, l2_st14_persistent_da},
 	{ST_L2_2, EV_L1_DEACTIVATE, l2_st24_tei_remove},
 	{ST_L2_3, EV_L1_DEACTIVATE, l2_st3_tei_remove},
-	{ST_L2_4, EV_L1_DEACTIVATE, l2_st14_persistant_da},
-	{ST_L2_5, EV_L1_DEACTIVATE, l2_st5_persistant_da},
-	{ST_L2_6, EV_L1_DEACTIVATE, l2_st6_persistant_da},
-	{ST_L2_7, EV_L1_DEACTIVATE, l2_persistant_da},
-	{ST_L2_8, EV_L1_DEACTIVATE, l2_persistant_da},
+	{ST_L2_4, EV_L1_DEACTIVATE, l2_st14_persistent_da},
+	{ST_L2_5, EV_L1_DEACTIVATE, l2_st5_persistent_da},
+	{ST_L2_6, EV_L1_DEACTIVATE, l2_st6_persistent_da},
+	{ST_L2_7, EV_L1_DEACTIVATE, l2_persistent_da},
+	{ST_L2_8, EV_L1_DEACTIVATE, l2_persistent_da},
 };
 
 static int
diff -druN linux-2.6.39-libre/drivers/isdn/mISDN/socket.c linux-3.0-rc7-libre/drivers/isdn/mISDN/socket.c
--- linux-2.6.39-libre/drivers/isdn/mISDN/socket.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/isdn/mISDN/socket.c	2011-07-11 19:51:52.000000000 -0400
@@ -457,6 +457,9 @@
 	if (get_user(len, optlen))
 		return -EFAULT;
 
+	if (len != sizeof(char))
+		return -EINVAL;
+
 	switch (optname) {
 	case MISDN_TIME_STAMP:
 		if (_pms(sk)->cmask & MISDN_TIME_STAMP)
diff -druN linux-2.6.39-libre/drivers/Kconfig linux-3.0-rc7-libre/drivers/Kconfig
--- linux-2.6.39-libre/drivers/Kconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/Kconfig	2011-07-11 19:51:52.000000000 -0400
@@ -54,6 +54,8 @@
 
 source "drivers/pps/Kconfig"
 
+source "drivers/ptp/Kconfig"
+
 source "drivers/gpio/Kconfig"
 
 source "drivers/w1/Kconfig"
@@ -68,6 +70,8 @@
 
 source "drivers/ssb/Kconfig"
 
+source "drivers/bcma/Kconfig"
+
 source "drivers/mfd/Kconfig"
 
 source "drivers/regulator/Kconfig"
@@ -119,4 +123,7 @@
 source "drivers/clk/Kconfig"
 
 source "drivers/hwspinlock/Kconfig"
+
+source "drivers/clocksource/Kconfig"
+
 endmenu
diff -druN linux-2.6.39-libre/drivers/leds/Kconfig linux-3.0-rc7-libre/drivers/leds/Kconfig
--- linux-2.6.39-libre/drivers/leds/Kconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/leds/Kconfig	2011-07-11 19:51:52.000000000 -0400
@@ -1,3 +1,10 @@
+config LEDS_GPIO_REGISTER
+	bool
+	help
+	  This option provides the function gpio_led_register_device.
+	  As this function is used by arch code it must not be compiled as a
+	  module.
+
 menuconfig NEW_LEDS
 	bool "LED Support"
 	help
@@ -7,15 +14,14 @@
 	  This is not related to standard keyboard LEDs which are controlled
 	  via the input system.
 
+if NEW_LEDS
+
 config LEDS_CLASS
 	bool "LED Class Support"
-	depends on NEW_LEDS
 	help
 	  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 NEW_LEDS
-
 comment "LED drivers"
 
 config LEDS_88PM860X
@@ -115,13 +121,6 @@
 	  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
-	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
@@ -162,6 +161,16 @@
 	  LED controller. It is generally only useful
 	  as a platform driver
 
+config LEDS_PCA9532_GPIO
+	bool "Enable GPIO support for PCA9532"
+	depends on LEDS_PCA9532
+	depends on GPIOLIB
+	help
+	  Allow unused pins on PCA9532 to be used as gpio.
+
+	  To use a pin as gpio pca9532_type in pca9532_platform data needs to
+	  set to PCA9532_TYPE_GPIO.
+
 config LEDS_GPIO
 	tristate "LED Support for GPIO connected LEDs"
 	depends on LEDS_CLASS
@@ -379,6 +388,17 @@
 	  and 5Big Network v2 boards. The LEDs are wired to a CPLD and are
 	  controlled through a GPIO extension bus.
 
+config LEDS_ASIC3
+	bool "LED support for the HTC ASIC3"
+	depends on LEDS_CLASS
+	depends on MFD_ASIC3
+	default y
+	help
+	  This option enables support for the LEDs on the HTC ASIC3. The HTC
+	  ASIC3 LED GPIOs are inputs, not outputs, thus the leds-gpio driver
+	  cannot be used. This driver supports hardware blinking with an on+off
+	  period from 62ms to 125s. Say Y to enable LEDs on the HP iPAQ hx4700.
+
 config LEDS_TRIGGERS
 	bool "LED Trigger support"
 	depends on LEDS_CLASS
diff -druN linux-2.6.39-libre/drivers/leds/led-class.c linux-3.0-rc7-libre/drivers/leds/led-class.c
--- linux-2.6.39-libre/drivers/leds/led-class.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/leds/led-class.c	2011-07-11 19:51:52.000000000 -0400
@@ -131,7 +131,8 @@
 	if (!led_cdev->blink_brightness)
 		led_cdev->blink_brightness = led_cdev->max_brightness;
 
-	if (delay_on == led_cdev->blink_delay_on &&
+	if (led_get_trigger_data(led_cdev) &&
+	    delay_on == led_cdev->blink_delay_on &&
 	    delay_off == led_cdev->blink_delay_off)
 		return;
 
diff -druN linux-2.6.39-libre/drivers/leds/leds-88pm860x.c linux-3.0-rc7-libre/drivers/leds/leds-88pm860x.c
--- linux-2.6.39-libre/drivers/leds/leds-88pm860x.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/leds/leds-88pm860x.c	2011-07-11 19:51:52.000000000 -0400
@@ -17,7 +17,6 @@
 #include <linux/leds.h>
 #include <linux/slab.h>
 #include <linux/workqueue.h>
-#include <linux/mfd/core.h>
 #include <linux/mfd/88pm860x.h>
 
 #define LED_PWM_SHIFT		(3)
@@ -171,7 +170,6 @@
 	struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent);
 	struct pm860x_led_pdata *pdata;
 	struct pm860x_led *data;
-	struct mfd_cell *cell;
 	struct resource *res;
 	int ret;
 
@@ -181,10 +179,7 @@
 		return -EINVAL;
 	}
 
-	cell = pdev->dev.platform_data;
-	if (cell == NULL)
-		return -ENODEV;
-	pdata = cell->mfd_data;
+	pdata = pdev->dev.platform_data;
 	if (pdata == NULL) {
 		dev_err(&pdev->dev, "No platform data!\n");
 		return -EINVAL;
diff -druN linux-2.6.39-libre/drivers/leds/leds-asic3.c linux-3.0-rc7-libre/drivers/leds/leds-asic3.c
--- linux-2.6.39-libre/drivers/leds/leds-asic3.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/leds/leds-asic3.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,165 @@
+/*
+ *  Copyright (C) 2011 Paul Parsons <lost.distance@yahoo.com>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 2 as
+ *  published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/leds.h>
+#include <linux/slab.h>
+
+#include <linux/mfd/asic3.h>
+#include <linux/mfd/core.h>
+
+/*
+ *	The HTC ASIC3 LED GPIOs are inputs, not outputs.
+ *	Hence we turn the LEDs on/off via the TimeBase register.
+ */
+
+/*
+ *	When TimeBase is 4 the clock resolution is about 32Hz.
+ *	This driver supports hardware blinking with an on+off
+ *	period from 62ms (2 clocks) to 125s (4000 clocks).
+ */
+#define MS_TO_CLK(ms)	DIV_ROUND_CLOSEST(((ms)*1024), 32000)
+#define CLK_TO_MS(clk)	(((clk)*32000)/1024)
+#define MAX_CLK		4000            /* Fits into 12-bit Time registers */
+#define MAX_MS		CLK_TO_MS(MAX_CLK)
+
+static const unsigned int led_n_base[ASIC3_NUM_LEDS] = {
+	[0] = ASIC3_LED_0_Base,
+	[1] = ASIC3_LED_1_Base,
+	[2] = ASIC3_LED_2_Base,
+};
+
+static void brightness_set(struct led_classdev *cdev,
+	enum led_brightness value)
+{
+	struct platform_device *pdev = to_platform_device(cdev->dev->parent);
+	const struct mfd_cell *cell = mfd_get_cell(pdev);
+	struct asic3 *asic = dev_get_drvdata(pdev->dev.parent);
+	u32 timebase;
+	unsigned int base;
+
+	timebase = (value == LED_OFF) ? 0 : (LED_EN|0x4);
+
+	base = led_n_base[cell->id];
+	asic3_write_register(asic, (base + ASIC3_LED_PeriodTime), 32);
+	asic3_write_register(asic, (base + ASIC3_LED_DutyTime), 32);
+	asic3_write_register(asic, (base + ASIC3_LED_AutoStopCount), 0);
+	asic3_write_register(asic, (base + ASIC3_LED_TimeBase), timebase);
+}
+
+static int blink_set(struct led_classdev *cdev,
+	unsigned long *delay_on,
+	unsigned long *delay_off)
+{
+	struct platform_device *pdev = to_platform_device(cdev->dev->parent);
+	const struct mfd_cell *cell = mfd_get_cell(pdev);
+	struct asic3 *asic = dev_get_drvdata(pdev->dev.parent);
+	u32 on;
+	u32 off;
+	unsigned int base;
+
+	if (*delay_on > MAX_MS || *delay_off > MAX_MS)
+		return -EINVAL;
+
+	if (*delay_on == 0 && *delay_off == 0) {
+		/* If both are zero then a sensible default should be chosen */
+		on = MS_TO_CLK(500);
+		off = MS_TO_CLK(500);
+	} else {
+		on = MS_TO_CLK(*delay_on);
+		off = MS_TO_CLK(*delay_off);
+		if ((on + off) > MAX_CLK)
+			return -EINVAL;
+	}
+
+	base = led_n_base[cell->id];
+	asic3_write_register(asic, (base + ASIC3_LED_PeriodTime), (on + off));
+	asic3_write_register(asic, (base + ASIC3_LED_DutyTime), on);
+	asic3_write_register(asic, (base + ASIC3_LED_AutoStopCount), 0);
+	asic3_write_register(asic, (base + ASIC3_LED_TimeBase), (LED_EN|0x4));
+
+	*delay_on = CLK_TO_MS(on);
+	*delay_off = CLK_TO_MS(off);
+
+	return 0;
+}
+
+static int __devinit asic3_led_probe(struct platform_device *pdev)
+{
+	struct asic3_led *led = pdev->dev.platform_data;
+	int ret;
+
+	ret = mfd_cell_enable(pdev);
+	if (ret < 0)
+		goto ret0;
+
+	led->cdev = kzalloc(sizeof(struct led_classdev), GFP_KERNEL);
+	if (!led->cdev) {
+		ret = -ENOMEM;
+		goto ret1;
+	}
+
+	led->cdev->name = led->name;
+	led->cdev->default_trigger = led->default_trigger;
+	led->cdev->brightness_set = brightness_set;
+	led->cdev->blink_set = blink_set;
+
+	ret = led_classdev_register(&pdev->dev, led->cdev);
+	if (ret < 0)
+		goto ret2;
+
+	return 0;
+
+ret2:
+	kfree(led->cdev);
+ret1:
+	(void) mfd_cell_disable(pdev);
+ret0:
+	return ret;
+}
+
+static int __devexit asic3_led_remove(struct platform_device *pdev)
+{
+	struct asic3_led *led = pdev->dev.platform_data;
+
+	led_classdev_unregister(led->cdev);
+
+	kfree(led->cdev);
+
+	return mfd_cell_disable(pdev);
+}
+
+static struct platform_driver asic3_led_driver = {
+	.probe		= asic3_led_probe,
+	.remove		= __devexit_p(asic3_led_remove),
+	.driver		= {
+		.name	= "leds-asic3",
+		.owner	= THIS_MODULE,
+	},
+};
+
+MODULE_ALIAS("platform:leds-asic3");
+
+static int __init asic3_led_init(void)
+{
+	return platform_driver_register(&asic3_led_driver);
+}
+
+static void __exit asic3_led_exit(void)
+{
+	platform_driver_unregister(&asic3_led_driver);
+}
+
+module_init(asic3_led_init);
+module_exit(asic3_led_exit);
+
+MODULE_AUTHOR("Paul Parsons <lost.distance@yahoo.com>");
+MODULE_DESCRIPTION("HTC ASIC3 LED driver");
+MODULE_LICENSE("GPL");
diff -druN linux-2.6.39-libre/drivers/leds/leds-gpio-register.c linux-3.0-rc7-libre/drivers/leds/leds-gpio-register.c
--- linux-2.6.39-libre/drivers/leds/leds-gpio-register.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/leds/leds-gpio-register.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2011 Pengutronix
+ * Uwe Kleine-Koenig <u.kleine-koenig@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/err.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/leds.h>
+
+/**
+ * gpio_led_register_device - register a gpio-led device
+ * @pdata: the platform data used for the new device
+ *
+ * Makes a copy of pdata and pdata->leds and registers a new leds-gpio device
+ * with the result. This allows to have pdata and pdata-leds in .init.rodata
+ * and so saves some bytes compared to a static struct platform_device with
+ * static platform data.
+ *
+ * Returns the registered device or an error pointer.
+ */
+struct platform_device *__init gpio_led_register_device(
+		int id, const struct gpio_led_platform_data *pdata)
+{
+	struct platform_device *ret;
+	struct gpio_led_platform_data _pdata = *pdata;
+
+	_pdata.leds = kmemdup(pdata->leds,
+			pdata->num_leds * sizeof(*pdata->leds), GFP_KERNEL);
+	if (!_pdata.leds)
+		return ERR_PTR(-ENOMEM);
+
+	ret = platform_device_register_resndata(NULL, "leds-gpio", id,
+			NULL, 0, &_pdata, sizeof(_pdata));
+	if (IS_ERR(ret))
+		kfree(_pdata.leds);
+
+	return ret;
+}
diff -druN linux-2.6.39-libre/drivers/leds/leds.h linux-3.0-rc7-libre/drivers/leds/leds.h
--- linux-2.6.39-libre/drivers/leds/leds.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/leds/leds.h	2011-07-11 19:51:52.000000000 -0400
@@ -40,10 +40,17 @@
 void led_trigger_set(struct led_classdev *led_cdev,
 			struct led_trigger *trigger);
 void led_trigger_remove(struct led_classdev *led_cdev);
+
+static inline void *led_get_trigger_data(struct led_classdev *led_cdev)
+{
+	return led_cdev->trigger_data;
+}
+
 #else
 #define led_trigger_set_default(x) do {} while (0)
 #define led_trigger_set(x, y) do {} while (0)
 #define led_trigger_remove(x) do {} while (0)
+#define led_get_trigger_data(x) (NULL)
 #endif
 
 ssize_t led_trigger_store(struct device *dev, struct device_attribute *attr,
diff -druN linux-2.6.39-libre/drivers/leds/leds-h1940.c linux-3.0-rc7-libre/drivers/leds/leds-h1940.c
--- linux-2.6.39-libre/drivers/leds/leds-h1940.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/leds/leds-h1940.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,170 +0,0 @@
-/*
- * drivers/leds/leds-h1940.c
- * Copyright (c) Arnaud Patard <arnaud.patard@rtp-net.org>
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License.  See the file COPYING in the main directory of this archive for
- * more details.
- *
- * H1940 leds driver
- *
- */
-
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <linux/delay.h>
-#include <linux/string.h>
-#include <linux/ctype.h>
-#include <linux/leds.h>
-#include <linux/gpio.h>
-
-#include <mach/regs-gpio.h>
-#include <mach/hardware.h>
-#include <mach/h1940-latch.h>
-
-/*
- * Green led.
- */
-static void h1940_greenled_set(struct led_classdev *led_dev,
-			       enum led_brightness value)
-{
-	switch (value) {
-	case LED_HALF:
-		h1940_latch_control(0, H1940_LATCH_LED_FLASH);
-		s3c2410_gpio_setpin(S3C2410_GPA7, 1);
-		break;
-	case LED_FULL:
-		h1940_latch_control(0, H1940_LATCH_LED_GREEN);
-		s3c2410_gpio_setpin(S3C2410_GPA7, 1);
-		break;
-	default:
-	case LED_OFF:
-		h1940_latch_control(H1940_LATCH_LED_FLASH, 0);
-		h1940_latch_control(H1940_LATCH_LED_GREEN, 0);
-		s3c2410_gpio_setpin(S3C2410_GPA7, 0);
-		break;
-	}
-}
-
-static struct led_classdev h1940_greenled = {
-	.name			= "h1940:green",
-	.brightness_set		= h1940_greenled_set,
-	.default_trigger	= "h1940-charger",
-};
-
-/*
- * Red led.
- */
-static void h1940_redled_set(struct led_classdev *led_dev,
-			     enum led_brightness value)
-{
-	switch (value) {
-	case LED_HALF:
-		h1940_latch_control(0, H1940_LATCH_LED_FLASH);
-		s3c2410_gpio_setpin(S3C2410_GPA1, 1);
-		break;
-	case LED_FULL:
-		h1940_latch_control(0, H1940_LATCH_LED_RED);
-		s3c2410_gpio_setpin(S3C2410_GPA1, 1);
-		break;
-	default:
-	case LED_OFF:
-		h1940_latch_control(H1940_LATCH_LED_FLASH, 0);
-		h1940_latch_control(H1940_LATCH_LED_RED, 0);
-		s3c2410_gpio_setpin(S3C2410_GPA1, 0);
-		break;
-	}
-}
-
-static struct led_classdev h1940_redled = {
-	.name			= "h1940:red",
-	.brightness_set		= h1940_redled_set,
-	.default_trigger	= "h1940-charger",
-};
-
-/*
- * Blue led.
- * (it can only be blue flashing led)
- */
-static void h1940_blueled_set(struct led_classdev *led_dev,
-			      enum led_brightness value)
-{
-	if (value) {
-		/* flashing Blue */
-		h1940_latch_control(0, H1940_LATCH_LED_FLASH);
-		s3c2410_gpio_setpin(S3C2410_GPA3, 1);
-	} else {
-		h1940_latch_control(H1940_LATCH_LED_FLASH, 0);
-		s3c2410_gpio_setpin(S3C2410_GPA3, 0);
-	}
-
-}
-
-static struct led_classdev h1940_blueled = {
-	.name			= "h1940:blue",
-	.brightness_set		= h1940_blueled_set,
-	.default_trigger	= "h1940-bluetooth",
-};
-
-static int __devinit h1940leds_probe(struct platform_device *pdev)
-{
-	int ret;
-
-	ret = led_classdev_register(&pdev->dev, &h1940_greenled);
-	if (ret)
-		goto err_green;
-
-	ret = led_classdev_register(&pdev->dev, &h1940_redled);
-	if (ret)
-		goto err_red;
-
-	ret = led_classdev_register(&pdev->dev, &h1940_blueled);
-	if (ret)
-		goto err_blue;
-
-	return 0;
-
-err_blue:
-	led_classdev_unregister(&h1940_redled);
-err_red:
-	led_classdev_unregister(&h1940_greenled);
-err_green:
-	return ret;
-}
-
-static int h1940leds_remove(struct platform_device *pdev)
-{
-	led_classdev_unregister(&h1940_greenled);
-	led_classdev_unregister(&h1940_redled);
-	led_classdev_unregister(&h1940_blueled);
-	return 0;
-}
-
-
-static struct platform_driver h1940leds_driver = {
-	.driver		= {
-		.name	= "h1940-leds",
-		.owner	= THIS_MODULE,
-	},
-	.probe		= h1940leds_probe,
-	.remove		= h1940leds_remove,
-};
-
-
-static int __init h1940leds_init(void)
-{
-	return platform_driver_register(&h1940leds_driver);
-}
-
-static void __exit h1940leds_exit(void)
-{
-	platform_driver_unregister(&h1940leds_driver);
-}
-
-module_init(h1940leds_init);
-module_exit(h1940leds_exit);
-
-MODULE_AUTHOR("Arnaud Patard <arnaud.patard@rtp-net.org>");
-MODULE_DESCRIPTION("LED driver for the iPAQ H1940");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:h1940-leds");
diff -druN linux-2.6.39-libre/drivers/leds/leds-lm3530.c linux-3.0-rc7-libre/drivers/leds/leds-lm3530.c
--- linux-2.6.39-libre/drivers/leds/leds-lm3530.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/leds/leds-lm3530.c	2011-07-11 19:51:52.000000000 -0400
@@ -17,6 +17,7 @@
 #include <linux/input.h>
 #include <linux/led-lm3530.h>
 #include <linux/types.h>
+#include <linux/regulator/consumer.h>
 
 #define LM3530_LED_DEV "lcd-backlight"
 #define LM3530_NAME "lm3530-led"
@@ -96,12 +97,18 @@
  * @client: i2c client
  * @pdata: LM3530 platform data
  * @mode: mode of operation - manual, ALS, PWM
+ * @regulator: regulator
+ * @brighness: previous brightness value
+ * @enable: regulator is enabled
  */
 struct lm3530_data {
 	struct led_classdev led_dev;
 	struct i2c_client *client;
 	struct lm3530_platform_data *pdata;
 	enum lm3530_mode mode;
+	struct regulator *regulator;
+	enum led_brightness brightness;
+	bool enable;
 };
 
 static const u8 lm3530_reg[LM3530_REG_MAX] = {
@@ -172,7 +179,10 @@
 	brt_ramp = (pltfm->brt_ramp_fall << LM3530_BRT_RAMP_FALL_SHIFT) |
 			(pltfm->brt_ramp_rise << LM3530_BRT_RAMP_RISE_SHIFT);
 
-	brightness = pltfm->brt_val;
+	if (drvdata->brightness)
+		brightness = drvdata->brightness;
+	else
+		brightness = drvdata->brightness = pltfm->brt_val;
 
 	reg_val[0] = gen_config;	/* LM3530_GEN_CONFIG */
 	reg_val[1] = als_config;	/* LM3530_ALS_CONFIG */
@@ -190,6 +200,16 @@
 	reg_val[13] = LM3530_DEF_ZT_3;	/* LM3530_ALS_Z3T_REG */
 	reg_val[14] = LM3530_DEF_ZT_4;	/* LM3530_ALS_Z4T_REG */
 
+	if (!drvdata->enable) {
+		ret = regulator_enable(drvdata->regulator);
+		if (ret) {
+			dev_err(&drvdata->client->dev,
+					"Enable regulator failed\n");
+			return ret;
+		}
+		drvdata->enable = true;
+	}
+
 	for (i = 0; i < LM3530_REG_MAX; i++) {
 		ret = i2c_smbus_write_byte_data(client,
 				lm3530_reg[i], reg_val[i]);
@@ -210,12 +230,31 @@
 	switch (drvdata->mode) {
 	case LM3530_BL_MODE_MANUAL:
 
+		if (!drvdata->enable) {
+			err = lm3530_init_registers(drvdata);
+			if (err) {
+				dev_err(&drvdata->client->dev,
+					"Register Init failed: %d\n", err);
+				break;
+			}
+		}
+
 		/* set the brightness in brightness control register*/
 		err = i2c_smbus_write_byte_data(drvdata->client,
 				LM3530_BRT_CTRL_REG, brt_val / 2);
 		if (err)
 			dev_err(&drvdata->client->dev,
 				"Unable to set brightness: %d\n", err);
+		else
+			drvdata->brightness = brt_val / 2;
+
+		if (brt_val == 0) {
+			err = regulator_disable(drvdata->regulator);
+			if (err)
+				dev_err(&drvdata->client->dev,
+					"Disable regulator failed\n");
+			drvdata->enable = false;
+		}
 		break;
 	case LM3530_BL_MODE_ALS:
 		break;
@@ -297,20 +336,31 @@
 	drvdata->mode = pdata->mode;
 	drvdata->client = client;
 	drvdata->pdata = pdata;
+	drvdata->brightness = LED_OFF;
+	drvdata->enable = false;
 	drvdata->led_dev.name = LM3530_LED_DEV;
 	drvdata->led_dev.brightness_set = lm3530_brightness_set;
 
 	i2c_set_clientdata(client, drvdata);
 
-	err = lm3530_init_registers(drvdata);
-	if (err < 0) {
-		dev_err(&client->dev, "Register Init failed: %d\n", err);
-		err = -ENODEV;
-		goto err_reg_init;
+	drvdata->regulator = regulator_get(&client->dev, "vin");
+	if (IS_ERR(drvdata->regulator)) {
+		dev_err(&client->dev, "regulator get failed\n");
+		err = PTR_ERR(drvdata->regulator);
+		drvdata->regulator = NULL;
+		goto err_regulator_get;
 	}
 
-	err = led_classdev_register((struct device *)
-				      &client->dev, &drvdata->led_dev);
+	if (drvdata->pdata->brt_val) {
+		err = lm3530_init_registers(drvdata);
+		if (err < 0) {
+			dev_err(&client->dev,
+				"Register Init failed: %d\n", err);
+			err = -ENODEV;
+			goto err_reg_init;
+		}
+	}
+	err = led_classdev_register(&client->dev, &drvdata->led_dev);
 	if (err < 0) {
 		dev_err(&client->dev, "Register led class failed: %d\n", err);
 		err = -ENODEV;
@@ -330,6 +380,9 @@
 	led_classdev_unregister(&drvdata->led_dev);
 err_class_register:
 err_reg_init:
+	regulator_put(drvdata->regulator);
+err_regulator_get:
+	i2c_set_clientdata(client, NULL);
 	kfree(drvdata);
 err_out:
 	return err;
@@ -340,6 +393,10 @@
 	struct lm3530_data *drvdata = i2c_get_clientdata(client);
 
 	device_remove_file(drvdata->led_dev.dev, &dev_attr_mode);
+
+	if (drvdata->enable)
+		regulator_disable(drvdata->regulator);
+	regulator_put(drvdata->regulator);
 	led_classdev_unregister(&drvdata->led_dev);
 	kfree(drvdata);
 	return 0;
diff -druN linux-2.6.39-libre/drivers/leds/leds-lp5521.c linux-3.0-rc7-libre/drivers/leds/leds-lp5521.c
--- linux-2.6.39-libre/drivers/leds/leds-lp5521.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/leds/leds-lp5521.c	2011-07-11 19:51:52.000000000 -0400
@@ -593,7 +593,7 @@
 				&lp5521_led_attribute_group);
 }
 
-static int __init lp5521_init_led(struct lp5521_led *led,
+static int __devinit lp5521_init_led(struct lp5521_led *led,
 				struct i2c_client *client,
 				int chan, struct lp5521_platform_data *pdata)
 {
@@ -637,7 +637,7 @@
 	return 0;
 }
 
-static int lp5521_probe(struct i2c_client *client,
+static int __devinit lp5521_probe(struct i2c_client *client,
 			const struct i2c_device_id *id)
 {
 	struct lp5521_chip		*chip;
diff -druN linux-2.6.39-libre/drivers/leds/leds-lp5523.c linux-3.0-rc7-libre/drivers/leds/leds-lp5523.c
--- linux-2.6.39-libre/drivers/leds/leds-lp5523.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/leds/leds-lp5523.c	2011-07-11 19:51:52.000000000 -0400
@@ -826,7 +826,7 @@
 	return 0;
 }
 
-static int __init lp5523_init_led(struct lp5523_led *led, struct device *dev,
+static int __devinit lp5523_init_led(struct lp5523_led *led, struct device *dev,
 			   int chan, struct lp5523_platform_data *pdata)
 {
 	char name[32];
@@ -872,7 +872,7 @@
 
 static struct i2c_driver lp5523_driver;
 
-static int lp5523_probe(struct i2c_client *client,
+static int __devinit lp5523_probe(struct i2c_client *client,
 			const struct i2c_device_id *id)
 {
 	struct lp5523_chip		*chip;
diff -druN linux-2.6.39-libre/drivers/leds/leds-mc13783.c linux-3.0-rc7-libre/drivers/leds/leds-mc13783.c
--- linux-2.6.39-libre/drivers/leds/leds-mc13783.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/leds/leds-mc13783.c	2011-07-11 19:51:52.000000000 -0400
@@ -22,7 +22,6 @@
 #include <linux/leds.h>
 #include <linux/workqueue.h>
 #include <linux/mfd/mc13783.h>
-#include <linux/mfd/core.h>
 #include <linux/slab.h>
 
 struct mc13783_led {
@@ -184,7 +183,7 @@
 
 static int __devinit mc13783_leds_prepare(struct platform_device *pdev)
 {
-	struct mc13783_leds_platform_data *pdata = mfd_get_data(pdev);
+	struct mc13783_leds_platform_data *pdata = dev_get_platdata(&pdev->dev);
 	struct mc13783 *dev = dev_get_drvdata(pdev->dev.parent);
 	int ret = 0;
 	int reg = 0;
@@ -235,7 +234,7 @@
 							MC13783_LED_Cx_PERIOD;
 
 	if (pdata->flags & MC13783_LED_TRIODE_TC3)
-		reg |= MC13783_LED_Cx_TRIODE_TC_BIT;;
+		reg |= MC13783_LED_Cx_TRIODE_TC_BIT;
 
 	ret = mc13783_reg_write(dev, MC13783_REG_LED_CONTROL_5, reg);
 	if (ret)
@@ -265,7 +264,7 @@
 
 static int __devinit mc13783_led_probe(struct platform_device *pdev)
 {
-	struct mc13783_leds_platform_data *pdata = mfd_get_data(pdev);
+	struct mc13783_leds_platform_data *pdata = dev_get_platdata(&pdev->dev);
 	struct mc13783_led_platform_data *led_cur;
 	struct mc13783_led *led, *led_dat;
 	int ret, i;
@@ -352,7 +351,7 @@
 
 static int __devexit mc13783_led_remove(struct platform_device *pdev)
 {
-	struct mc13783_leds_platform_data *pdata = mfd_get_data(pdev);
+	struct mc13783_leds_platform_data *pdata = dev_get_platdata(&pdev->dev);
 	struct mc13783_led *led = platform_get_drvdata(pdev);
 	struct mc13783 *dev = dev_get_drvdata(pdev->dev.parent);
 	int i;
diff -druN linux-2.6.39-libre/drivers/leds/leds-pca9532.c linux-3.0-rc7-libre/drivers/leds/leds-pca9532.c
--- linux-2.6.39-libre/drivers/leds/leds-pca9532.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/leds/leds-pca9532.c	2011-07-11 19:51:52.000000000 -0400
@@ -1,13 +1,14 @@
 /*
  * pca9532.c - 16-bit Led dimmer
  *
+ * Copyright (C) 2011 Jan Weitzel
  * Copyright (C) 2008 Riku Voipio
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation; version 2 of the License.
  *
- * Datasheet: http://www.nxp.com/acrobat/datasheets/PCA9532_3.pdf
+ * Datasheet: http://www.nxp.com/documents/data_sheet/PCA9532.pdf
  *
  */
 
@@ -19,21 +20,32 @@
 #include <linux/mutex.h>
 #include <linux/workqueue.h>
 #include <linux/leds-pca9532.h>
+#include <linux/gpio.h>
 
-#define PCA9532_REG_PSC(i) (0x2+(i)*2)
-#define PCA9532_REG_PWM(i) (0x3+(i)*2)
-#define PCA9532_REG_LS0  0x6
-#define LED_REG(led) ((led>>2)+PCA9532_REG_LS0)
-#define LED_NUM(led) (led & 0x3)
+/* m =  num_leds*/
+#define PCA9532_REG_INPUT(i)	((i) >> 3)
+#define PCA9532_REG_OFFSET(m)	((m) >> 4)
+#define PCA9532_REG_PSC(m, i)	(PCA9532_REG_OFFSET(m) + 0x1 + (i) * 2)
+#define PCA9532_REG_PWM(m, i)	(PCA9532_REG_OFFSET(m) + 0x2 + (i) * 2)
+#define LED_REG(m, led)		(PCA9532_REG_OFFSET(m) + 0x5 + (led >> 2))
+#define LED_NUM(led)		(led & 0x3)
 
 #define ldev_to_led(c)       container_of(c, struct pca9532_led, ldev)
 
+struct pca9532_chip_info {
+	u8	num_leds;
+};
+
 struct pca9532_data {
 	struct i2c_client *client;
 	struct pca9532_led leds[16];
 	struct mutex update_lock;
 	struct input_dev *idev;
 	struct work_struct work;
+#ifdef CONFIG_LEDS_PCA9532_GPIO
+	struct gpio_chip gpio;
+#endif
+	const struct pca9532_chip_info *chip_info;
 	u8 pwm[2];
 	u8 psc[2];
 };
@@ -42,16 +54,41 @@
 	const struct i2c_device_id *id);
 static int pca9532_remove(struct i2c_client *client);
 
+enum {
+	pca9530,
+	pca9531,
+	pca9532,
+	pca9533,
+};
+
 static const struct i2c_device_id pca9532_id[] = {
-	{ "pca9532", 0 },
+	{ "pca9530", pca9530 },
+	{ "pca9531", pca9531 },
+	{ "pca9532", pca9532 },
+	{ "pca9533", pca9533 },
 	{ }
 };
 
 MODULE_DEVICE_TABLE(i2c, pca9532_id);
 
+static const struct pca9532_chip_info pca9532_chip_info_tbl[] = {
+	[pca9530] = {
+		.num_leds = 2,
+	},
+	[pca9531] = {
+		.num_leds = 8,
+	},
+	[pca9532] = {
+		.num_leds = 16,
+	},
+	[pca9533] = {
+		.num_leds = 4,
+	},
+};
+
 static struct i2c_driver pca9532_driver = {
 	.driver = {
-		.name = "pca9532",
+		.name = "leds-pca953x",
 	},
 	.probe = pca9532_probe,
 	.remove = pca9532_remove,
@@ -68,7 +105,7 @@
 {
 	int a = 0, b = 0, i = 0;
 	struct pca9532_data *data = i2c_get_clientdata(client);
-	for (i = 0; i < 16; i++) {
+	for (i = 0; i < data->chip_info->num_leds; i++) {
 		if (data->leds[i].type == PCA9532_TYPE_LED &&
 			data->leds[i].state == PCA9532_PWM0+pwm) {
 				a++;
@@ -92,10 +129,12 @@
 static int pca9532_setpwm(struct i2c_client *client, int pwm)
 {
 	struct pca9532_data *data = i2c_get_clientdata(client);
+	u8 maxleds = data->chip_info->num_leds;
+
 	mutex_lock(&data->update_lock);
-	i2c_smbus_write_byte_data(client, PCA9532_REG_PWM(pwm),
+	i2c_smbus_write_byte_data(client, PCA9532_REG_PWM(maxleds, pwm),
 		data->pwm[pwm]);
-	i2c_smbus_write_byte_data(client, PCA9532_REG_PSC(pwm),
+	i2c_smbus_write_byte_data(client, PCA9532_REG_PSC(maxleds, pwm),
 		data->psc[pwm]);
 	mutex_unlock(&data->update_lock);
 	return 0;
@@ -106,15 +145,16 @@
 {
 	struct i2c_client *client = led->client;
 	struct pca9532_data *data = i2c_get_clientdata(client);
+	u8 maxleds = data->chip_info->num_leds;
 	char reg;
 
 	mutex_lock(&data->update_lock);
-	reg = i2c_smbus_read_byte_data(client, LED_REG(led->id));
+	reg = i2c_smbus_read_byte_data(client, LED_REG(maxleds, led->id));
 	/* zero led bits */
 	reg = reg & ~(0x3<<LED_NUM(led->id)*2);
 	/* set the new value */
 	reg = reg | (led->state << LED_NUM(led->id)*2);
-	i2c_smbus_write_byte_data(client, LED_REG(led->id), reg);
+	i2c_smbus_write_byte_data(client, LED_REG(maxleds, led->id), reg);
 	mutex_unlock(&data->update_lock);
 }
 
@@ -183,10 +223,12 @@
 
 static void pca9532_input_work(struct work_struct *work)
 {
-	struct pca9532_data *data;
-	data = container_of(work, struct pca9532_data, work);
+	struct pca9532_data *data =
+		container_of(work, struct pca9532_data, work);
+	u8 maxleds = data->chip_info->num_leds;
+
 	mutex_lock(&data->update_lock);
-	i2c_smbus_write_byte_data(data->client, PCA9532_REG_PWM(1),
+	i2c_smbus_write_byte_data(data->client, PCA9532_REG_PWM(maxleds, 1),
 		data->pwm[1]);
 	mutex_unlock(&data->update_lock);
 }
@@ -200,16 +242,68 @@
 	pca9532_setled(led);
 }
 
-static void pca9532_destroy_devices(struct pca9532_data *data, int n_devs)
+#ifdef CONFIG_LEDS_PCA9532_GPIO
+static int pca9532_gpio_request_pin(struct gpio_chip *gc, unsigned offset)
+{
+	struct pca9532_data *data = container_of(gc, struct pca9532_data, gpio);
+	struct pca9532_led *led = &data->leds[offset];
+
+	if (led->type == PCA9532_TYPE_GPIO)
+		return 0;
+
+	return -EBUSY;
+}
+
+static void pca9532_gpio_set_value(struct gpio_chip *gc, unsigned offset, int val)
+{
+	struct pca9532_data *data = container_of(gc, struct pca9532_data, gpio);
+	struct pca9532_led *led = &data->leds[offset];
+
+	if (val)
+		led->state = PCA9532_ON;
+	else
+		led->state = PCA9532_OFF;
+
+	pca9532_setled(led);
+}
+
+static int pca9532_gpio_get_value(struct gpio_chip *gc, unsigned offset)
+{
+	struct pca9532_data *data = container_of(gc, struct pca9532_data, gpio);
+	unsigned char reg;
+
+	reg = i2c_smbus_read_byte_data(data->client, PCA9532_REG_INPUT(offset));
+
+	return !!(reg & (1 << (offset % 8)));
+}
+
+static int pca9532_gpio_direction_input(struct gpio_chip *gc, unsigned offset)
+{
+	/* To use as input ensure pin is not driven */
+	pca9532_gpio_set_value(gc, offset, 0);
+
+	return 0;
+}
+
+static int pca9532_gpio_direction_output(struct gpio_chip *gc, unsigned offset, int val)
+{
+	pca9532_gpio_set_value(gc, offset, val);
+
+	return 0;
+}
+#endif /* CONFIG_LEDS_PCA9532_GPIO */
+
+static int pca9532_destroy_devices(struct pca9532_data *data, int n_devs)
 {
 	int i = n_devs;
 
 	if (!data)
-		return;
+		return -EINVAL;
 
 	while (--i >= 0) {
 		switch (data->leds[i].type) {
 		case PCA9532_TYPE_NONE:
+		case PCA9532_TYPE_GPIO:
 			break;
 		case PCA9532_TYPE_LED:
 			led_classdev_unregister(&data->leds[i].ldev);
@@ -224,23 +318,38 @@
 			break;
 		}
 	}
+
+#ifdef CONFIG_LEDS_PCA9532_GPIO
+	if (data->gpio.dev) {
+		int err = gpiochip_remove(&data->gpio);
+		if (err) {
+			dev_err(&data->client->dev, "%s failed, %d\n",
+						"gpiochip_remove()", err);
+			return err;
+		}
+	}
+#endif
+
+	return 0;
 }
 
 static int pca9532_configure(struct i2c_client *client,
 	struct pca9532_data *data, struct pca9532_platform_data *pdata)
 {
 	int i, err = 0;
+	int gpios = 0;
+	u8 maxleds = data->chip_info->num_leds;
 
 	for (i = 0; i < 2; i++)	{
 		data->pwm[i] = pdata->pwm[i];
 		data->psc[i] = pdata->psc[i];
-		i2c_smbus_write_byte_data(client, PCA9532_REG_PWM(i),
+		i2c_smbus_write_byte_data(client, PCA9532_REG_PWM(maxleds, i),
 			data->pwm[i]);
-		i2c_smbus_write_byte_data(client, PCA9532_REG_PSC(i),
+		i2c_smbus_write_byte_data(client, PCA9532_REG_PSC(maxleds, i),
 			data->psc[i]);
 	}
 
-	for (i = 0; i < 16; i++) {
+	for (i = 0; i < data->chip_info->num_leds; i++) {
 		struct pca9532_led *led = &data->leds[i];
 		struct pca9532_led *pled = &pdata->leds[i];
 		led->client = client;
@@ -249,6 +358,9 @@
 		switch (led->type) {
 		case PCA9532_TYPE_NONE:
 			break;
+		case PCA9532_TYPE_GPIO:
+			gpios++;
+			break;
 		case PCA9532_TYPE_LED:
 			led->state = pled->state;
 			led->name = pled->name;
@@ -297,6 +409,34 @@
 			break;
 		}
 	}
+
+#ifdef CONFIG_LEDS_PCA9532_GPIO
+	if (gpios) {
+		data->gpio.label = "gpio-pca9532";
+		data->gpio.direction_input = pca9532_gpio_direction_input;
+		data->gpio.direction_output = pca9532_gpio_direction_output;
+		data->gpio.set = pca9532_gpio_set_value;
+		data->gpio.get = pca9532_gpio_get_value;
+		data->gpio.request = pca9532_gpio_request_pin;
+		data->gpio.can_sleep = 1;
+		data->gpio.base = pdata->gpio_base;
+		data->gpio.ngpio = data->chip_info->num_leds;
+		data->gpio.dev = &client->dev;
+		data->gpio.owner = THIS_MODULE;
+
+		err = gpiochip_add(&data->gpio);
+		if (err) {
+			/* Use data->gpio.dev as a flag for freeing gpiochip */
+			data->gpio.dev = NULL;
+			dev_warn(&client->dev, "could not add gpiochip\n");
+		} else {
+			dev_info(&client->dev, "gpios %i...%i\n",
+				data->gpio.base, data->gpio.base +
+				data->gpio.ngpio - 1);
+		}
+	}
+#endif
+
 	return 0;
 
 exit:
@@ -322,6 +462,8 @@
 	if (!data)
 		return -ENOMEM;
 
+	data->chip_info = &pca9532_chip_info_tbl[id->driver_data];
+
 	dev_info(&client->dev, "setting platform data\n");
 	i2c_set_clientdata(client, data);
 	data->client = client;
@@ -337,7 +479,12 @@
 static int pca9532_remove(struct i2c_client *client)
 {
 	struct pca9532_data *data = i2c_get_clientdata(client);
-	pca9532_destroy_devices(data, 16);
+	int err;
+
+	err = pca9532_destroy_devices(data, data->chip_info->num_leds);
+	if (err)
+		return err;
+
 	kfree(data);
 	return 0;
 }
diff -druN linux-2.6.39-libre/drivers/leds/ledtrig-timer.c linux-3.0-rc7-libre/drivers/leds/ledtrig-timer.c
--- linux-2.6.39-libre/drivers/leds/ledtrig-timer.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/leds/ledtrig-timer.c	2011-07-11 19:51:52.000000000 -0400
@@ -91,6 +91,9 @@
 	if (rc)
 		goto err_out_delayon;
 
+	led_blink_set(led_cdev, &led_cdev->blink_delay_on,
+		      &led_cdev->blink_delay_off);
+
 	led_cdev->trigger_data = (void *)1;
 
 	return;
diff -druN linux-2.6.39-libre/drivers/leds/Makefile linux-3.0-rc7-libre/drivers/leds/Makefile
--- linux-2.6.39-libre/drivers/leds/Makefile	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/leds/Makefile	2011-07-11 19:51:52.000000000 -0400
@@ -17,11 +17,11 @@
 obj-$(CONFIG_LEDS_NET5501)		+= leds-net5501.o
 obj-$(CONFIG_LEDS_WRAP)			+= leds-wrap.o
 obj-$(CONFIG_LEDS_ALIX2)		+= leds-alix2.o
-obj-$(CONFIG_LEDS_H1940)		+= leds-h1940.o
 obj-$(CONFIG_LEDS_COBALT_QUBE)		+= leds-cobalt-qube.o
 obj-$(CONFIG_LEDS_COBALT_RAQ)		+= leds-cobalt-raq.o
 obj-$(CONFIG_LEDS_SUNFIRE)		+= leds-sunfire.o
 obj-$(CONFIG_LEDS_PCA9532)		+= leds-pca9532.o
+obj-$(CONFIG_LEDS_GPIO_REGISTER)	+= leds-gpio-register.o
 obj-$(CONFIG_LEDS_GPIO)			+= leds-gpio.o
 obj-$(CONFIG_LEDS_LP3944)		+= leds-lp3944.o
 obj-$(CONFIG_LEDS_LP5521)		+= leds-lp5521.o
@@ -42,6 +42,7 @@
 obj-$(CONFIG_LEDS_MC13783)		+= leds-mc13783.o
 obj-$(CONFIG_LEDS_NS2)			+= leds-ns2.o
 obj-$(CONFIG_LEDS_NETXBIG)		+= leds-netxbig.o
+obj-$(CONFIG_LEDS_ASIC3)		+= leds-asic3.o
 
 # LED SPI Drivers
 obj-$(CONFIG_LEDS_DAC124S085)		+= leds-dac124s085.o
diff -druN linux-2.6.39-libre/drivers/lguest/Kconfig linux-3.0-rc7-libre/drivers/lguest/Kconfig
--- linux-2.6.39-libre/drivers/lguest/Kconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/lguest/Kconfig	2011-07-11 19:51:52.000000000 -0400
@@ -5,8 +5,10 @@
 	---help---
 	  This is a very simple module which allows you to run
 	  multiple instances of the same Linux kernel, using the
-	  "lguest" command found in the Documentation/lguest directory.
+	  "lguest" command found in the Documentation/virtual/lguest
+	  directory.
+
 	  Note that "lguest" is pronounced to rhyme with "fell quest",
-	  not "rustyvisor".  See Documentation/lguest/lguest.txt.
+	  not "rustyvisor". See Documentation/virtual/lguest/lguest.txt.
 
 	  If unsure, say N.  If curious, say M.  If masochistic, say Y.
diff -druN linux-2.6.39-libre/drivers/lguest/Makefile linux-3.0-rc7-libre/drivers/lguest/Makefile
--- linux-2.6.39-libre/drivers/lguest/Makefile	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/lguest/Makefile	2011-07-11 19:51:52.000000000 -0400
@@ -18,7 +18,7 @@
 Beer:
 	@for f in Preparation Guest Drivers Launcher Host Switcher Mastery; do echo "{==- $$f -==}"; make -s $$f; done; echo "{==-==}"
 Preparation Preparation! Guest Drivers Launcher Host Switcher Mastery:
-	@sh ../../Documentation/lguest/extract $(PREFIX) `find ../../* -name '*.[chS]' -wholename '*lguest*'`
+	@sh ../../Documentation/virtual/lguest/extract $(PREFIX) `find ../../* -name '*.[chS]' -wholename '*lguest*'`
 Puppy:
 	@clear
 	@printf "      __  \n (___()'\`;\n /,    /\`\n \\\\\\\"--\\\\\\   \n"
diff -druN linux-2.6.39-libre/drivers/macintosh/therm_pm72.c linux-3.0-rc7-libre/drivers/macintosh/therm_pm72.c
--- linux-2.6.39-libre/drivers/macintosh/therm_pm72.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/macintosh/therm_pm72.c	2011-07-11 19:51:52.000000000 -0400
@@ -44,11 +44,11 @@
  * TODO:  - Check MPU structure version/signature
  *        - Add things like /sbin/overtemp for non-critical
  *          overtemp conditions so userland can take some policy
- *          decisions, like slewing down CPUs
+ *          decisions, like slowing down CPUs
  *	  - Deal with fan and i2c failures in a better way
  *	  - Maybe do a generic PID based on params used for
  *	    U3 and Drives ? Definitely need to factor code a bit
- *          bettter... also make sensor detection more robust using
+ *          better... also make sensor detection more robust using
  *          the device-tree to probe for them
  *        - Figure out how to get the slots consumption and set the
  *          slots fan accordingly
diff -druN linux-2.6.39-libre/drivers/macintosh/via-pmu.c linux-3.0-rc7-libre/drivers/macintosh/via-pmu.c
--- linux-2.6.39-libre/drivers/macintosh/via-pmu.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/macintosh/via-pmu.c	2011-07-11 19:51:52.000000000 -0400
@@ -40,7 +40,7 @@
 #include <linux/init.h>
 #include <linux/interrupt.h>
 #include <linux/device.h>
-#include <linux/sysdev.h>
+#include <linux/syscore_ops.h>
 #include <linux/freezer.h>
 #include <linux/syscalls.h>
 #include <linux/suspend.h>
@@ -2527,12 +2527,9 @@
 #if defined(CONFIG_SUSPEND) && defined(CONFIG_PPC32)
 int pmu_sys_suspended;
 
-static int pmu_sys_suspend(struct sys_device *sysdev, pm_message_t state)
+static int pmu_syscore_suspend(void)
 {
-	if (state.event != PM_EVENT_SUSPEND || pmu_sys_suspended)
-		return 0;
-
-	/* Suspend PMU event interrupts */\
+	/* Suspend PMU event interrupts */
 	pmu_suspend();
 	pmu_sys_suspended = 1;
 
@@ -2544,12 +2541,12 @@
 	return 0;
 }
 
-static int pmu_sys_resume(struct sys_device *sysdev)
+static void pmu_syscore_resume(void)
 {
 	struct adb_request req;
 
 	if (!pmu_sys_suspended)
-		return 0;
+		return;
 
 	/* Tell PMU we are ready */
 	pmu_request(&req, NULL, 2, PMU_SYSTEM_READY, 2);
@@ -2562,50 +2559,21 @@
 	/* Resume PMU event interrupts */
 	pmu_resume();
 	pmu_sys_suspended = 0;
-
-	return 0;
 }
 
-#endif /* CONFIG_SUSPEND && CONFIG_PPC32 */
-
-static struct sysdev_class pmu_sysclass = {
-	.name = "pmu",
-};
-
-static struct sys_device device_pmu = {
-	.cls		= &pmu_sysclass,
-};
-
-static struct sysdev_driver driver_pmu = {
-#if defined(CONFIG_SUSPEND) && defined(CONFIG_PPC32)
-	.suspend	= &pmu_sys_suspend,
-	.resume		= &pmu_sys_resume,
-#endif /* CONFIG_SUSPEND && CONFIG_PPC32 */
+static struct syscore_ops pmu_syscore_ops = {
+	.suspend = pmu_syscore_suspend,
+	.resume = pmu_syscore_resume,
 };
 
-static int __init init_pmu_sysfs(void)
+static int pmu_syscore_register(void)
 {
-	int rc;
+	register_syscore_ops(&pmu_syscore_ops);
 
-	rc = sysdev_class_register(&pmu_sysclass);
-	if (rc) {
-		printk(KERN_ERR "Failed registering PMU sys class\n");
-		return -ENODEV;
-	}
-	rc = sysdev_register(&device_pmu);
-	if (rc) {
-		printk(KERN_ERR "Failed registering PMU sys device\n");
-		return -ENODEV;
-	}
-	rc = sysdev_driver_register(&pmu_sysclass, &driver_pmu);
-	if (rc) {
-		printk(KERN_ERR "Failed registering PMU sys driver\n");
-		return -ENODEV;
-	}
 	return 0;
 }
-
-subsys_initcall(init_pmu_sysfs);
+subsys_initcall(pmu_syscore_register);
+#endif /* CONFIG_SUSPEND && CONFIG_PPC32 */
 
 EXPORT_SYMBOL(pmu_request);
 EXPORT_SYMBOL(pmu_queue_request);
diff -druN linux-2.6.39-libre/drivers/Makefile linux-3.0-rc7-libre/drivers/Makefile
--- linux-2.6.39-libre/drivers/Makefile	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/Makefile	2011-07-11 19:51:52.000000000 -0400
@@ -17,6 +17,9 @@
 # was used and do nothing if so
 obj-$(CONFIG_PNP)		+= pnp/
 obj-$(CONFIG_ARM_AMBA)		+= amba/
+# Many drivers will want to use DMA so this has to be made available
+# really early.
+obj-$(CONFIG_DMA_ENGINE)	+= dma/
 
 obj-$(CONFIG_VIRTIO)		+= virtio/
 obj-$(CONFIG_XEN)		+= xen/
@@ -64,11 +67,10 @@
 obj-$(CONFIG_PARIDE) 		+= block/paride/
 obj-$(CONFIG_TC)		+= tc/
 obj-$(CONFIG_UWB)		+= uwb/
-obj-$(CONFIG_USB_OTG_UTILS)	+= usb/otg/
+obj-$(CONFIG_USB_OTG_UTILS)	+= usb/
 obj-$(CONFIG_USB)		+= usb/
-obj-$(CONFIG_USB_MUSB_HDRC)	+= usb/musb/
 obj-$(CONFIG_PCI)		+= usb/
-obj-$(CONFIG_USB_GADGET)	+= usb/gadget/
+obj-$(CONFIG_USB_GADGET)	+= usb/
 obj-$(CONFIG_SERIO)		+= input/serio/
 obj-$(CONFIG_GAMEPORT)		+= input/gameport/
 obj-$(CONFIG_INPUT)		+= input/
@@ -76,6 +78,7 @@
 obj-$(CONFIG_RTC_LIB)		+= rtc/
 obj-y				+= i2c/ media/
 obj-$(CONFIG_PPS)		+= pps/
+obj-$(CONFIG_PTP_1588_CLOCK)	+= ptp/
 obj-$(CONFIG_W1)		+= w1/
 obj-$(CONFIG_POWER_SUPPLY)	+= power/
 obj-$(CONFIG_HWMON)		+= hwmon/
@@ -92,10 +95,9 @@
 obj-y				+= lguest/
 obj-$(CONFIG_CPU_FREQ)		+= cpufreq/
 obj-$(CONFIG_CPU_IDLE)		+= cpuidle/
-obj-$(CONFIG_DMA_ENGINE)	+= dma/
 obj-$(CONFIG_MMC)		+= mmc/
 obj-$(CONFIG_MEMSTICK)		+= memstick/
-obj-$(CONFIG_NEW_LEDS)		+= leds/
+obj-y				+= leds/
 obj-$(CONFIG_INFINIBAND)	+= infiniband/
 obj-$(CONFIG_SGI_SN)		+= sn/
 obj-y				+= firmware/
@@ -110,6 +112,7 @@
 obj-$(CONFIG_PPC_PS3)		+= ps3/
 obj-$(CONFIG_OF)		+= of/
 obj-$(CONFIG_SSB)		+= ssb/
+obj-$(CONFIG_BCMA)		+= bcma/
 obj-$(CONFIG_VHOST_NET)		+= vhost/
 obj-$(CONFIG_VLYNQ)		+= vlynq/
 obj-$(CONFIG_STAGING)		+= staging/
diff -druN linux-2.6.39-libre/drivers/md/bitmap.c linux-3.0-rc7-libre/drivers/md/bitmap.c
--- linux-2.6.39-libre/drivers/md/bitmap.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/md/bitmap.c	2011-07-11 19:51:52.000000000 -0400
@@ -493,11 +493,11 @@
 	spin_unlock_irqrestore(&bitmap->lock, flags);
 	sb = kmap_atomic(bitmap->sb_page, KM_USER0);
 	sb->events = cpu_to_le64(bitmap->mddev->events);
-	if (bitmap->mddev->events < bitmap->events_cleared) {
+	if (bitmap->mddev->events < bitmap->events_cleared)
 		/* rocking back to read-only */
 		bitmap->events_cleared = bitmap->mddev->events;
-		sb->events_cleared = cpu_to_le64(bitmap->events_cleared);
-	}
+	sb->events_cleared = cpu_to_le64(bitmap->events_cleared);
+	sb->state = cpu_to_le32(bitmap->flags);
 	/* Just in case these have been changed via sysfs: */
 	sb->daemon_sleep = cpu_to_le32(bitmap->mddev->bitmap_info.daemon_sleep/HZ);
 	sb->write_behind = cpu_to_le32(bitmap->mddev->bitmap_info.max_write_behind);
@@ -534,6 +534,82 @@
 	kunmap_atomic(sb, KM_USER0);
 }
 
+/*
+ * bitmap_new_disk_sb
+ * @bitmap
+ *
+ * This function is somewhat the reverse of bitmap_read_sb.  bitmap_read_sb
+ * reads and verifies the on-disk bitmap superblock and populates bitmap_info.
+ * This function verifies 'bitmap_info' and populates the on-disk bitmap
+ * structure, which is to be written to disk.
+ *
+ * Returns: 0 on success, -Exxx on error
+ */
+static int bitmap_new_disk_sb(struct bitmap *bitmap)
+{
+	bitmap_super_t *sb;
+	unsigned long chunksize, daemon_sleep, write_behind;
+	int err = -EINVAL;
+
+	bitmap->sb_page = alloc_page(GFP_KERNEL);
+	if (IS_ERR(bitmap->sb_page)) {
+		err = PTR_ERR(bitmap->sb_page);
+		bitmap->sb_page = NULL;
+		return err;
+	}
+	bitmap->sb_page->index = 0;
+
+	sb = kmap_atomic(bitmap->sb_page, KM_USER0);
+
+	sb->magic = cpu_to_le32(BITMAP_MAGIC);
+	sb->version = cpu_to_le32(BITMAP_MAJOR_HI);
+
+	chunksize = bitmap->mddev->bitmap_info.chunksize;
+	BUG_ON(!chunksize);
+	if (!is_power_of_2(chunksize)) {
+		kunmap_atomic(sb, KM_USER0);
+		printk(KERN_ERR "bitmap chunksize not a power of 2\n");
+		return -EINVAL;
+	}
+	sb->chunksize = cpu_to_le32(chunksize);
+
+	daemon_sleep = bitmap->mddev->bitmap_info.daemon_sleep;
+	if (!daemon_sleep ||
+	    (daemon_sleep < 1) || (daemon_sleep > MAX_SCHEDULE_TIMEOUT)) {
+		printk(KERN_INFO "Choosing daemon_sleep default (5 sec)\n");
+		daemon_sleep = 5 * HZ;
+	}
+	sb->daemon_sleep = cpu_to_le32(daemon_sleep);
+	bitmap->mddev->bitmap_info.daemon_sleep = daemon_sleep;
+
+	/*
+	 * FIXME: write_behind for RAID1.  If not specified, what
+	 * is a good choice?  We choose COUNTER_MAX / 2 arbitrarily.
+	 */
+	write_behind = bitmap->mddev->bitmap_info.max_write_behind;
+	if (write_behind > COUNTER_MAX)
+		write_behind = COUNTER_MAX / 2;
+	sb->write_behind = cpu_to_le32(write_behind);
+	bitmap->mddev->bitmap_info.max_write_behind = write_behind;
+
+	/* keep the array size field of the bitmap superblock up to date */
+	sb->sync_size = cpu_to_le64(bitmap->mddev->resync_max_sectors);
+
+	memcpy(sb->uuid, bitmap->mddev->uuid, 16);
+
+	bitmap->flags |= BITMAP_STALE;
+	sb->state |= cpu_to_le32(BITMAP_STALE);
+	bitmap->events_cleared = bitmap->mddev->events;
+	sb->events_cleared = cpu_to_le64(bitmap->mddev->events);
+
+	bitmap->flags |= BITMAP_HOSTENDIAN;
+	sb->version = cpu_to_le32(BITMAP_MAJOR_HOSTENDIAN);
+
+	kunmap_atomic(sb, KM_USER0);
+
+	return 0;
+}
+
 /* read the superblock from the bitmap file and initialize some bitmap fields */
 static int bitmap_read_sb(struct bitmap *bitmap)
 {
@@ -575,7 +651,7 @@
 		reason = "unrecognized superblock version";
 	else if (chunksize < 512)
 		reason = "bitmap chunksize too small";
-	else if ((1 << ffz(~chunksize)) != chunksize)
+	else if (!is_power_of_2(chunksize))
 		reason = "bitmap chunksize not a power of 2";
 	else if (daemon_sleep < 1 || daemon_sleep > MAX_SCHEDULE_TIMEOUT)
 		reason = "daemon sleep period out of range";
@@ -618,7 +694,7 @@
 	if (le32_to_cpu(sb->version) == BITMAP_MAJOR_HOSTENDIAN)
 		bitmap->flags |= BITMAP_HOSTENDIAN;
 	bitmap->events_cleared = le64_to_cpu(sb->events_cleared);
-	if (sb->state & cpu_to_le32(BITMAP_STALE))
+	if (bitmap->flags & BITMAP_STALE)
 		bitmap->events_cleared = bitmap->mddev->events;
 	err = 0;
 out:
@@ -652,9 +728,11 @@
 	switch (op) {
 	case MASK_SET:
 		sb->state |= cpu_to_le32(bits);
+		bitmap->flags |= bits;
 		break;
 	case MASK_UNSET:
 		sb->state &= cpu_to_le32(~bits);
+		bitmap->flags &= ~bits;
 		break;
 	default:
 		BUG();
@@ -1074,8 +1152,8 @@
 	}
 
 	printk(KERN_INFO "%s: bitmap initialized from disk: "
-		"read %lu/%lu pages, set %lu bits\n",
-		bmname(bitmap), bitmap->file_pages, num_pages, bit_cnt);
+	       "read %lu/%lu pages, set %lu of %lu bits\n",
+	       bmname(bitmap), bitmap->file_pages, num_pages, bit_cnt, chunks);
 
 	return 0;
 
@@ -1330,7 +1408,7 @@
 			return 0;
 		}
 
-		if (unlikely((*bmc & COUNTER_MAX) == COUNTER_MAX)) {
+		if (unlikely(COUNTER(*bmc) == COUNTER_MAX)) {
 			DEFINE_WAIT(__wait);
 			/* note that it is safe to do the prepare_to_wait
 			 * after the test as long as we do it before dropping
@@ -1402,10 +1480,10 @@
 			sysfs_notify_dirent_safe(bitmap->sysfs_can_clear);
 		}
 
-		if (!success && ! (*bmc & NEEDED_MASK))
+		if (!success && !NEEDED(*bmc))
 			*bmc |= NEEDED_MASK;
 
-		if ((*bmc & COUNTER_MAX) == COUNTER_MAX)
+		if (COUNTER(*bmc) == COUNTER_MAX)
 			wake_up(&bitmap->overflow_wait);
 
 		(*bmc)--;
@@ -1726,9 +1804,16 @@
 		vfs_fsync(file, 1);
 	}
 	/* read superblock from bitmap file (this sets mddev->bitmap_info.chunksize) */
-	if (!mddev->bitmap_info.external)
-		err = bitmap_read_sb(bitmap);
-	else {
+	if (!mddev->bitmap_info.external) {
+		/*
+		 * If 'MD_ARRAY_FIRST_USE' is set, then device-mapper is
+		 * instructing us to create a new on-disk bitmap instance.
+		 */
+		if (test_and_clear_bit(MD_ARRAY_FIRST_USE, &mddev->flags))
+			err = bitmap_new_disk_sb(bitmap);
+		else
+			err = bitmap_read_sb(bitmap);
+	} else {
 		err = 0;
 		if (mddev->bitmap_info.chunksize == 0 ||
 		    mddev->bitmap_info.daemon_sleep == 0)
@@ -1752,9 +1837,6 @@
 	bitmap->chunks = chunks;
 	bitmap->pages = pages;
 	bitmap->missing_pages = pages;
-	bitmap->counter_bits = COUNTER_BITS;
-
-	bitmap->syncchunk = ~0UL;
 
 #ifdef INJECT_FATAL_FAULT_1
 	bitmap->bp = NULL;
diff -druN linux-2.6.39-libre/drivers/md/bitmap.h linux-3.0-rc7-libre/drivers/md/bitmap.h
--- linux-2.6.39-libre/drivers/md/bitmap.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/md/bitmap.h	2011-07-11 19:51:52.000000000 -0400
@@ -85,7 +85,6 @@
 typedef __u16 bitmap_counter_t;
 #define COUNTER_BITS 16
 #define COUNTER_BIT_SHIFT 4
-#define COUNTER_BYTE_RATIO (COUNTER_BITS / 8)
 #define COUNTER_BYTE_SHIFT (COUNTER_BIT_SHIFT - 3)
 
 #define NEEDED_MASK ((bitmap_counter_t) (1 << (COUNTER_BITS - 1)))
@@ -196,19 +195,10 @@
 
 	mddev_t *mddev; /* the md device that the bitmap is for */
 
-	int counter_bits; /* how many bits per block counter */
-
 	/* bitmap chunksize -- how much data does each bit represent? */
 	unsigned long chunkshift; /* chunksize = 2^chunkshift (for bitops) */
 	unsigned long chunks; /* total number of data chunks for the array */
 
-	/* We hold a count on the chunk currently being synced, and drop
-	 * it when the last block is started.  If the resync is aborted
-	 * midway, we need to be able to drop that count, so we remember
-	 * the counted chunk..
-	 */
-	unsigned long syncchunk;
-
 	__u64	events_cleared;
 	int need_sync;
 
diff -druN linux-2.6.39-libre/drivers/md/dm-io.c linux-3.0-rc7-libre/drivers/md/dm-io.c
--- linux-2.6.39-libre/drivers/md/dm-io.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/md/dm-io.c	2011-07-11 19:51:52.000000000 -0400
@@ -19,6 +19,8 @@
 #define DM_MSG_PREFIX "io"
 
 #define DM_IO_MAX_REGIONS	BITS_PER_LONG
+#define MIN_IOS		16
+#define MIN_BIOS	16
 
 struct dm_io_client {
 	mempool_t *pool;
@@ -41,33 +43,21 @@
 static struct kmem_cache *_dm_io_cache;
 
 /*
- * io contexts are only dynamically allocated for asynchronous
- * io.  Since async io is likely to be the majority of io we'll
- * have the same number of io contexts as bios! (FIXME: must reduce this).
- */
-
-static unsigned int pages_to_ios(unsigned int pages)
-{
-	return 4 * pages;	/* too many ? */
-}
-
-/*
  * Create a client with mempool and bioset.
  */
-struct dm_io_client *dm_io_client_create(unsigned num_pages)
+struct dm_io_client *dm_io_client_create(void)
 {
-	unsigned ios = pages_to_ios(num_pages);
 	struct dm_io_client *client;
 
 	client = kmalloc(sizeof(*client), GFP_KERNEL);
 	if (!client)
 		return ERR_PTR(-ENOMEM);
 
-	client->pool = mempool_create_slab_pool(ios, _dm_io_cache);
+	client->pool = mempool_create_slab_pool(MIN_IOS, _dm_io_cache);
 	if (!client->pool)
 		goto bad;
 
-	client->bios = bioset_create(16, 0);
+	client->bios = bioset_create(MIN_BIOS, 0);
 	if (!client->bios)
 		goto bad;
 
@@ -81,13 +71,6 @@
 }
 EXPORT_SYMBOL(dm_io_client_create);
 
-int dm_io_client_resize(unsigned num_pages, struct dm_io_client *client)
-{
-	return mempool_resize(client->pool, pages_to_ios(num_pages),
-			      GFP_KERNEL);
-}
-EXPORT_SYMBOL(dm_io_client_resize);
-
 void dm_io_client_destroy(struct dm_io_client *client)
 {
 	mempool_destroy(client->pool);
diff -druN linux-2.6.39-libre/drivers/md/dm-kcopyd.c linux-3.0-rc7-libre/drivers/md/dm-kcopyd.c
--- linux-2.6.39-libre/drivers/md/dm-kcopyd.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/md/dm-kcopyd.c	2011-07-11 19:51:52.000000000 -0400
@@ -27,15 +27,19 @@
 
 #include "dm.h"
 
+#define SUB_JOB_SIZE	128
+#define SPLIT_COUNT	8
+#define MIN_JOBS	8
+#define RESERVE_PAGES	(DIV_ROUND_UP(SUB_JOB_SIZE << SECTOR_SHIFT, PAGE_SIZE))
+
 /*-----------------------------------------------------------------
  * Each kcopyd client has its own little pool of preallocated
  * pages for kcopyd io.
  *---------------------------------------------------------------*/
 struct dm_kcopyd_client {
-	spinlock_t lock;
 	struct page_list *pages;
-	unsigned int nr_pages;
-	unsigned int nr_free_pages;
+	unsigned nr_reserved_pages;
+	unsigned nr_free_pages;
 
 	struct dm_io_client *io_client;
 
@@ -67,15 +71,18 @@
 	queue_work(kc->kcopyd_wq, &kc->kcopyd_work);
 }
 
-static struct page_list *alloc_pl(void)
+/*
+ * Obtain one page for the use of kcopyd.
+ */
+static struct page_list *alloc_pl(gfp_t gfp)
 {
 	struct page_list *pl;
 
-	pl = kmalloc(sizeof(*pl), GFP_KERNEL);
+	pl = kmalloc(sizeof(*pl), gfp);
 	if (!pl)
 		return NULL;
 
-	pl->page = alloc_page(GFP_KERNEL);
+	pl->page = alloc_page(gfp);
 	if (!pl->page) {
 		kfree(pl);
 		return NULL;
@@ -90,41 +97,56 @@
 	kfree(pl);
 }
 
-static int kcopyd_get_pages(struct dm_kcopyd_client *kc,
-			    unsigned int nr, struct page_list **pages)
+/*
+ * Add the provided pages to a client's free page list, releasing
+ * back to the system any beyond the reserved_pages limit.
+ */
+static void kcopyd_put_pages(struct dm_kcopyd_client *kc, struct page_list *pl)
 {
-	struct page_list *pl;
-
-	spin_lock(&kc->lock);
-	if (kc->nr_free_pages < nr) {
-		spin_unlock(&kc->lock);
-		return -ENOMEM;
-	}
-
-	kc->nr_free_pages -= nr;
-	for (*pages = pl = kc->pages; --nr; pl = pl->next)
-		;
+	struct page_list *next;
 
-	kc->pages = pl->next;
-	pl->next = NULL;
+	do {
+		next = pl->next;
 
-	spin_unlock(&kc->lock);
+		if (kc->nr_free_pages >= kc->nr_reserved_pages)
+			free_pl(pl);
+		else {
+			pl->next = kc->pages;
+			kc->pages = pl;
+			kc->nr_free_pages++;
+		}
 
-	return 0;
+		pl = next;
+	} while (pl);
 }
 
-static void kcopyd_put_pages(struct dm_kcopyd_client *kc, struct page_list *pl)
+static int kcopyd_get_pages(struct dm_kcopyd_client *kc,
+			    unsigned int nr, struct page_list **pages)
 {
-	struct page_list *cursor;
+	struct page_list *pl;
 
-	spin_lock(&kc->lock);
-	for (cursor = pl; cursor->next; cursor = cursor->next)
-		kc->nr_free_pages++;
+	*pages = NULL;
 
-	kc->nr_free_pages++;
-	cursor->next = kc->pages;
-	kc->pages = pl;
-	spin_unlock(&kc->lock);
+	do {
+		pl = alloc_pl(__GFP_NOWARN | __GFP_NORETRY);
+		if (unlikely(!pl)) {
+			/* Use reserved pages */
+			pl = kc->pages;
+			if (unlikely(!pl))
+				goto out_of_memory;
+			kc->pages = pl->next;
+			kc->nr_free_pages--;
+		}
+		pl->next = *pages;
+		*pages = pl;
+	} while (--nr);
+
+	return 0;
+
+out_of_memory:
+	if (*pages)
+		kcopyd_put_pages(kc, *pages);
+	return -ENOMEM;
 }
 
 /*
@@ -141,13 +163,16 @@
 	}
 }
 
-static int client_alloc_pages(struct dm_kcopyd_client *kc, unsigned int nr)
+/*
+ * Allocate and reserve nr_pages for the use of a specific client.
+ */
+static int client_reserve_pages(struct dm_kcopyd_client *kc, unsigned nr_pages)
 {
-	unsigned int i;
+	unsigned i;
 	struct page_list *pl = NULL, *next;
 
-	for (i = 0; i < nr; i++) {
-		next = alloc_pl();
+	for (i = 0; i < nr_pages; i++) {
+		next = alloc_pl(GFP_KERNEL);
 		if (!next) {
 			if (pl)
 				drop_pages(pl);
@@ -157,17 +182,18 @@
 		pl = next;
 	}
 
+	kc->nr_reserved_pages += nr_pages;
 	kcopyd_put_pages(kc, pl);
-	kc->nr_pages += nr;
+
 	return 0;
 }
 
 static void client_free_pages(struct dm_kcopyd_client *kc)
 {
-	BUG_ON(kc->nr_free_pages != kc->nr_pages);
+	BUG_ON(kc->nr_free_pages != kc->nr_reserved_pages);
 	drop_pages(kc->pages);
 	kc->pages = NULL;
-	kc->nr_free_pages = kc->nr_pages = 0;
+	kc->nr_free_pages = kc->nr_reserved_pages = 0;
 }
 
 /*-----------------------------------------------------------------
@@ -216,16 +242,17 @@
 	struct mutex lock;
 	atomic_t sub_jobs;
 	sector_t progress;
-};
 
-/* FIXME: this should scale with the number of pages */
-#define MIN_JOBS 512
+	struct kcopyd_job *master_job;
+};
 
 static struct kmem_cache *_job_cache;
 
 int __init dm_kcopyd_init(void)
 {
-	_job_cache = KMEM_CACHE(kcopyd_job, 0);
+	_job_cache = kmem_cache_create("kcopyd_job",
+				sizeof(struct kcopyd_job) * (SPLIT_COUNT + 1),
+				__alignof__(struct kcopyd_job), 0, NULL);
 	if (!_job_cache)
 		return -ENOMEM;
 
@@ -299,7 +326,12 @@
 
 	if (job->pages)
 		kcopyd_put_pages(kc, job->pages);
-	mempool_free(job, kc->job_pool);
+	/*
+	 * If this is the master job, the sub jobs have already
+	 * completed so we can free everything.
+	 */
+	if (job->master_job == job)
+		mempool_free(job, kc->job_pool);
 	fn(read_err, write_err, context);
 
 	if (atomic_dec_and_test(&kc->nr_jobs))
@@ -460,14 +492,14 @@
 	wake(kc);
 }
 
-#define SUB_JOB_SIZE 128
 static void segment_complete(int read_err, unsigned long write_err,
 			     void *context)
 {
 	/* FIXME: tidy this function */
 	sector_t progress = 0;
 	sector_t count = 0;
-	struct kcopyd_job *job = (struct kcopyd_job *) context;
+	struct kcopyd_job *sub_job = (struct kcopyd_job *) context;
+	struct kcopyd_job *job = sub_job->master_job;
 	struct dm_kcopyd_client *kc = job->kc;
 
 	mutex_lock(&job->lock);
@@ -498,8 +530,6 @@
 
 	if (count) {
 		int i;
-		struct kcopyd_job *sub_job = mempool_alloc(kc->job_pool,
-							   GFP_NOIO);
 
 		*sub_job = *job;
 		sub_job->source.sector += progress;
@@ -511,7 +541,7 @@
 		}
 
 		sub_job->fn = segment_complete;
-		sub_job->context = job;
+		sub_job->context = sub_job;
 		dispatch_job(sub_job);
 
 	} else if (atomic_dec_and_test(&job->sub_jobs)) {
@@ -531,19 +561,19 @@
 }
 
 /*
- * Create some little jobs that will do the move between
- * them.
+ * Create some sub jobs to share the work between them.
  */
-#define SPLIT_COUNT 8
-static void split_job(struct kcopyd_job *job)
+static void split_job(struct kcopyd_job *master_job)
 {
 	int i;
 
-	atomic_inc(&job->kc->nr_jobs);
+	atomic_inc(&master_job->kc->nr_jobs);
 
-	atomic_set(&job->sub_jobs, SPLIT_COUNT);
-	for (i = 0; i < SPLIT_COUNT; i++)
-		segment_complete(0, 0u, job);
+	atomic_set(&master_job->sub_jobs, SPLIT_COUNT);
+	for (i = 0; i < SPLIT_COUNT; i++) {
+		master_job[i + 1].master_job = master_job;
+		segment_complete(0, 0u, &master_job[i + 1]);
+	}
 }
 
 int dm_kcopyd_copy(struct dm_kcopyd_client *kc, struct dm_io_region *from,
@@ -553,7 +583,8 @@
 	struct kcopyd_job *job;
 
 	/*
-	 * Allocate a new job.
+	 * Allocate an array of jobs consisting of one master job
+	 * followed by SPLIT_COUNT sub jobs.
 	 */
 	job = mempool_alloc(kc->job_pool, GFP_NOIO);
 
@@ -577,10 +608,10 @@
 
 	job->fn = fn;
 	job->context = context;
+	job->master_job = job;
 
-	if (job->source.count < SUB_JOB_SIZE)
+	if (job->source.count <= SUB_JOB_SIZE)
 		dispatch_job(job);
-
 	else {
 		mutex_init(&job->lock);
 		job->progress = 0;
@@ -606,17 +637,15 @@
 /*-----------------------------------------------------------------
  * Client setup
  *---------------------------------------------------------------*/
-int dm_kcopyd_client_create(unsigned int nr_pages,
-			    struct dm_kcopyd_client **result)
+struct dm_kcopyd_client *dm_kcopyd_client_create(void)
 {
 	int r = -ENOMEM;
 	struct dm_kcopyd_client *kc;
 
 	kc = kmalloc(sizeof(*kc), GFP_KERNEL);
 	if (!kc)
-		return -ENOMEM;
+		return ERR_PTR(-ENOMEM);
 
-	spin_lock_init(&kc->lock);
 	spin_lock_init(&kc->job_lock);
 	INIT_LIST_HEAD(&kc->complete_jobs);
 	INIT_LIST_HEAD(&kc->io_jobs);
@@ -633,12 +662,12 @@
 		goto bad_workqueue;
 
 	kc->pages = NULL;
-	kc->nr_pages = kc->nr_free_pages = 0;
-	r = client_alloc_pages(kc, nr_pages);
+	kc->nr_reserved_pages = kc->nr_free_pages = 0;
+	r = client_reserve_pages(kc, RESERVE_PAGES);
 	if (r)
 		goto bad_client_pages;
 
-	kc->io_client = dm_io_client_create(nr_pages);
+	kc->io_client = dm_io_client_create();
 	if (IS_ERR(kc->io_client)) {
 		r = PTR_ERR(kc->io_client);
 		goto bad_io_client;
@@ -647,8 +676,7 @@
 	init_waitqueue_head(&kc->destroyq);
 	atomic_set(&kc->nr_jobs, 0);
 
-	*result = kc;
-	return 0;
+	return kc;
 
 bad_io_client:
 	client_free_pages(kc);
@@ -659,7 +687,7 @@
 bad_slab:
 	kfree(kc);
 
-	return r;
+	return ERR_PTR(r);
 }
 EXPORT_SYMBOL(dm_kcopyd_client_create);
 
diff -druN linux-2.6.39-libre/drivers/md/dm-log.c linux-3.0-rc7-libre/drivers/md/dm-log.c
--- linux-2.6.39-libre/drivers/md/dm-log.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/md/dm-log.c	2011-07-11 19:51:52.000000000 -0400
@@ -449,8 +449,7 @@
 
 		lc->io_req.mem.type = DM_IO_VMA;
 		lc->io_req.notify.fn = NULL;
-		lc->io_req.client = dm_io_client_create(dm_div_up(buf_size,
-								   PAGE_SIZE));
+		lc->io_req.client = dm_io_client_create();
 		if (IS_ERR(lc->io_req.client)) {
 			r = PTR_ERR(lc->io_req.client);
 			DMWARN("couldn't allocate disk io client");
diff -druN linux-2.6.39-libre/drivers/md/dm-mpath.c linux-3.0-rc7-libre/drivers/md/dm-mpath.c
--- linux-2.6.39-libre/drivers/md/dm-mpath.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/md/dm-mpath.c	2011-07-11 19:51:52.000000000 -0400
@@ -1290,7 +1290,7 @@
 	if (!error && !clone->errors)
 		return 0;	/* I/O complete */
 
-	if (error == -EOPNOTSUPP || error == -EREMOTEIO)
+	if (error == -EOPNOTSUPP || error == -EREMOTEIO || error == -EILSEQ)
 		return error;
 
 	if (mpio->pgpath)
diff -druN linux-2.6.39-libre/drivers/md/dm-raid1.c linux-3.0-rc7-libre/drivers/md/dm-raid1.c
--- linux-2.6.39-libre/drivers/md/dm-raid1.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/md/dm-raid1.c	2011-07-11 19:51:52.000000000 -0400
@@ -22,8 +22,6 @@
 #define DM_MSG_PREFIX "raid1"
 
 #define MAX_RECOVERY 1	/* Maximum number of regions recovered in parallel. */
-#define DM_IO_PAGES 64
-#define DM_KCOPYD_PAGES 64
 
 #define DM_RAID1_HANDLE_ERRORS 0x01
 #define errors_handled(p)	((p)->features & DM_RAID1_HANDLE_ERRORS)
@@ -887,7 +885,7 @@
 		return NULL;
 	}
 
-	ms->io_client = dm_io_client_create(DM_IO_PAGES);
+	ms->io_client = dm_io_client_create();
 	if (IS_ERR(ms->io_client)) {
 		ti->error = "Error creating dm_io client";
 		mempool_destroy(ms->read_record_pool);
@@ -1117,9 +1115,11 @@
 		goto err_destroy_wq;
 	}
 
-	r = dm_kcopyd_client_create(DM_KCOPYD_PAGES, &ms->kcopyd_client);
-	if (r)
+	ms->kcopyd_client = dm_kcopyd_client_create();
+	if (IS_ERR(ms->kcopyd_client)) {
+		r = PTR_ERR(ms->kcopyd_client);
 		goto err_destroy_wq;
+	}
 
 	wakeup_mirrord(ms);
 	return 0;
diff -druN linux-2.6.39-libre/drivers/md/dm-snap.c linux-3.0-rc7-libre/drivers/md/dm-snap.c
--- linux-2.6.39-libre/drivers/md/dm-snap.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/md/dm-snap.c	2011-07-11 19:51:52.000000000 -0400
@@ -40,11 +40,6 @@
 #define SNAPSHOT_COPY_PRIORITY 2
 
 /*
- * Reserve 1MB for each snapshot initially (with minimum of 1 page).
- */
-#define SNAPSHOT_PAGES (((1UL << 20) >> PAGE_SHIFT) ? : 1)
-
-/*
  * The size of the mempool used to track chunks in use.
  */
 #define MIN_IOS 256
@@ -1116,8 +1111,9 @@
 		goto bad_hash_tables;
 	}
 
-	r = dm_kcopyd_client_create(SNAPSHOT_PAGES, &s->kcopyd_client);
-	if (r) {
+	s->kcopyd_client = dm_kcopyd_client_create();
+	if (IS_ERR(s->kcopyd_client)) {
+		r = PTR_ERR(s->kcopyd_client);
 		ti->error = "Could not create kcopyd client";
 		goto bad_kcopyd;
 	}
diff -druN linux-2.6.39-libre/drivers/md/dm-snap-persistent.c linux-3.0-rc7-libre/drivers/md/dm-snap-persistent.c
--- linux-2.6.39-libre/drivers/md/dm-snap-persistent.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/md/dm-snap-persistent.c	2011-07-11 19:51:52.000000000 -0400
@@ -154,11 +154,6 @@
 	struct workqueue_struct *metadata_wq;
 };
 
-static unsigned sectors_to_pages(unsigned sectors)
-{
-	return DIV_ROUND_UP(sectors, PAGE_SIZE >> 9);
-}
-
 static int alloc_area(struct pstore *ps)
 {
 	int r = -ENOMEM;
@@ -318,8 +313,7 @@
 		chunk_size_supplied = 0;
 	}
 
-	ps->io_client = dm_io_client_create(sectors_to_pages(ps->store->
-							     chunk_size));
+	ps->io_client = dm_io_client_create();
 	if (IS_ERR(ps->io_client))
 		return PTR_ERR(ps->io_client);
 
@@ -368,11 +362,6 @@
 		return r;
 	}
 
-	r = dm_io_client_resize(sectors_to_pages(ps->store->chunk_size),
-				ps->io_client);
-	if (r)
-		return r;
-
 	r = alloc_area(ps);
 	return r;
 
diff -druN linux-2.6.39-libre/drivers/md/dm-table.c linux-3.0-rc7-libre/drivers/md/dm-table.c
--- linux-2.6.39-libre/drivers/md/dm-table.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/md/dm-table.c	2011-07-11 19:51:52.000000000 -0400
@@ -362,6 +362,7 @@
 static int device_area_is_invalid(struct dm_target *ti, struct dm_dev *dev,
 				  sector_t start, sector_t len, void *data)
 {
+	struct request_queue *q;
 	struct queue_limits *limits = data;
 	struct block_device *bdev = dev->bdev;
 	sector_t dev_size =
@@ -370,6 +371,22 @@
 		limits->logical_block_size >> SECTOR_SHIFT;
 	char b[BDEVNAME_SIZE];
 
+	/*
+	 * Some devices exist without request functions,
+	 * such as loop devices not yet bound to backing files.
+	 * Forbid the use of such devices.
+	 */
+	q = bdev_get_queue(bdev);
+	if (!q || !q->make_request_fn) {
+		DMWARN("%s: %s is not yet initialised: "
+		       "start=%llu, len=%llu, dev_size=%llu",
+		       dm_device_name(ti->table->md), bdevname(bdev, b),
+		       (unsigned long long)start,
+		       (unsigned long long)len,
+		       (unsigned long long)dev_size);
+		return 1;
+	}
+
 	if (!dev_size)
 		return 0;
 
@@ -1346,7 +1363,8 @@
 		return 0;
 
 	/*
-	 * Ensure that at least one underlying device supports discards.
+	 * Unless any target used by the table set discards_supported,
+	 * require at least one underlying device to support discards.
 	 * t->devices includes internal dm devices such as mirror logs
 	 * so we need to use iterate_devices here, which targets
 	 * supporting discard must provide.
@@ -1354,6 +1372,9 @@
 	while (i < dm_table_get_num_targets(t)) {
 		ti = dm_table_get_target(t, i++);
 
+		if (ti->discards_supported)
+			return 1;
+
 		if (ti->type->iterate_devices &&
 		    ti->type->iterate_devices(ti, device_discard_capable, NULL))
 			return 1;
diff -druN linux-2.6.39-libre/drivers/md/md.c linux-3.0-rc7-libre/drivers/md/md.c
--- linux-2.6.39-libre/drivers/md/md.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/md/md.c	2011-07-11 19:51:52.000000000 -0400
@@ -351,6 +351,9 @@
 	mddev->suspended = 0;
 	wake_up(&mddev->sb_wait);
 	mddev->pers->quiesce(mddev, 0);
+
+	md_wakeup_thread(mddev->thread);
+	md_wakeup_thread(mddev->sync_thread); /* possibly kick off a reshape */
 }
 EXPORT_SYMBOL_GPL(mddev_resume);
 
@@ -1750,6 +1753,18 @@
 	},
 };
 
+static void sync_super(mddev_t *mddev, mdk_rdev_t *rdev)
+{
+	if (mddev->sync_super) {
+		mddev->sync_super(mddev, rdev);
+		return;
+	}
+
+	BUG_ON(mddev->major_version >= ARRAY_SIZE(super_types));
+
+	super_types[mddev->major_version].sync_super(mddev, rdev);
+}
+
 static int match_mddev_units(mddev_t *mddev1, mddev_t *mddev2)
 {
 	mdk_rdev_t *rdev, *rdev2;
@@ -1781,8 +1796,8 @@
 
 	if (list_empty(&mddev->disks))
 		return 0; /* nothing to do */
-	if (blk_get_integrity(mddev->gendisk))
-		return 0; /* already registered */
+	if (!mddev->gendisk || blk_get_integrity(mddev->gendisk))
+		return 0; /* shouldn't register, or already is */
 	list_for_each_entry(rdev, &mddev->disks, same_set) {
 		/* skip spares and non-functional disks */
 		if (test_bit(Faulty, &rdev->flags))
@@ -2168,8 +2183,7 @@
 			/* Don't update this superblock */
 			rdev->sb_loaded = 2;
 		} else {
-			super_types[mddev->major_version].
-				sync_super(mddev, rdev);
+			sync_super(mddev, rdev);
 			rdev->sb_loaded = 1;
 		}
 	}
@@ -2462,7 +2476,7 @@
 		if (rdev->raid_disk == -1)
 			return -EEXIST;
 		/* personality does all needed checks */
-		if (rdev->mddev->pers->hot_add_disk == NULL)
+		if (rdev->mddev->pers->hot_remove_disk == NULL)
 			return -EINVAL;
 		err = rdev->mddev->pers->
 			hot_remove_disk(rdev->mddev, rdev->raid_disk);
@@ -3324,7 +3338,7 @@
 	char *e;
 	unsigned long long n = simple_strtoull(buf, &e, 10);
 
-	if (mddev->pers)
+	if (mddev->pers && !test_bit(MD_RECOVERY_FROZEN, &mddev->recovery))
 		return -EBUSY;
 	if (cmd_match(buf, "none"))
 		n = MaxSector;
@@ -4347,13 +4361,19 @@
 	disk->fops = &md_fops;
 	disk->private_data = mddev;
 	disk->queue = mddev->queue;
+	blk_queue_flush(mddev->queue, REQ_FLUSH | REQ_FUA);
 	/* Allow extended partitions.  This makes the
 	 * 'mdp' device redundant, but we can't really
 	 * remove it now.
 	 */
 	disk->flags |= GENHD_FL_EXT_DEVT;
-	add_disk(disk);
 	mddev->gendisk = disk;
+	/* As soon as we call add_disk(), another thread could get
+	 * through to md_open, so make sure it doesn't get too far
+	 */
+	mutex_lock(&mddev->open_mutex);
+	add_disk(disk);
+
 	error = kobject_init_and_add(&mddev->kobj, &md_ktype,
 				     &disk_to_dev(disk)->kobj, "%s", "md");
 	if (error) {
@@ -4367,8 +4387,7 @@
 	if (mddev->kobj.sd &&
 	    sysfs_create_group(&mddev->kobj, &md_bitmap_group))
 		printk(KERN_DEBUG "pointless warning\n");
-
-	blk_queue_flush(mddev->queue, REQ_FLUSH | REQ_FUA);
+	mutex_unlock(&mddev->open_mutex);
  abort:
 	mutex_unlock(&disks_mutex);
 	if (!error && mddev->kobj.sd) {
@@ -4614,9 +4633,6 @@
 	if (mddev->flags)
 		md_update_sb(mddev, 0);
 
-	md_wakeup_thread(mddev->thread);
-	md_wakeup_thread(mddev->sync_thread); /* possibly kick off a reshape */
-
 	md_new_event(mddev);
 	sysfs_notify_dirent_safe(mddev->sysfs_state);
 	sysfs_notify_dirent_safe(mddev->sysfs_action);
@@ -4637,6 +4653,10 @@
 		bitmap_destroy(mddev);
 		goto out;
 	}
+
+	md_wakeup_thread(mddev->thread);
+	md_wakeup_thread(mddev->sync_thread); /* possibly kick off a reshape */
+
 	set_capacity(mddev->gendisk, mddev->array_sectors);
 	revalidate_disk(mddev->gendisk);
 	mddev->changed = 1;
@@ -5211,6 +5231,16 @@
 		} else
 			super_types[mddev->major_version].
 				validate_super(mddev, rdev);
+		if ((info->state & (1<<MD_DISK_SYNC)) &&
+		    (!test_bit(In_sync, &rdev->flags) ||
+		     rdev->raid_disk != info->raid_disk)) {
+			/* This was a hot-add request, but events doesn't
+			 * match, so reject it.
+			 */
+			export_rdev(rdev);
+			return -EINVAL;
+		}
+
 		if (test_bit(In_sync, &rdev->flags))
 			rdev->saved_raid_disk = rdev->raid_disk;
 		else
@@ -5244,6 +5274,8 @@
 		if (mddev->degraded)
 			set_bit(MD_RECOVERY_RECOVER, &mddev->recovery);
 		set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
+		if (!err)
+			md_new_event(mddev);
 		md_wakeup_thread(mddev->thread);
 		return err;
 	}
@@ -6851,8 +6883,8 @@
 	 * Tune reconstruction:
 	 */
 	window = 32*(PAGE_SIZE/512);
-	printk(KERN_INFO "md: using %dk window, over a total of %llu blocks.\n",
-		window/2,(unsigned long long) max_sectors/2);
+	printk(KERN_INFO "md: using %dk window, over a total of %lluk.\n",
+		window/2, (unsigned long long)max_sectors/2);
 
 	atomic_set(&mddev->recovery_active, 0);
 	last_check = 0;
@@ -7030,7 +7062,6 @@
 }
 EXPORT_SYMBOL_GPL(md_do_sync);
 
-
 static int remove_and_add_spares(mddev_t *mddev)
 {
 	mdk_rdev_t *rdev;
@@ -7057,6 +7088,7 @@
 		list_for_each_entry(rdev, &mddev->disks, same_set) {
 			if (rdev->raid_disk >= 0 &&
 			    !test_bit(In_sync, &rdev->flags) &&
+			    !test_bit(Faulty, &rdev->flags) &&
 			    !test_bit(Blocked, &rdev->flags))
 				spares++;
 			if (rdev->raid_disk < 0
@@ -7142,6 +7174,9 @@
  */
 void md_check_recovery(mddev_t *mddev)
 {
+	if (mddev->suspended)
+		return;
+
 	if (mddev->bitmap)
 		bitmap_daemon_work(mddev);
 
diff -druN linux-2.6.39-libre/drivers/md/md.h linux-3.0-rc7-libre/drivers/md/md.h
--- linux-2.6.39-libre/drivers/md/md.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/md/md.h	2011-07-11 19:51:52.000000000 -0400
@@ -124,6 +124,7 @@
 #define MD_CHANGE_DEVS	0	/* Some device status has changed */
 #define MD_CHANGE_CLEAN 1	/* transition to or from 'clean' */
 #define MD_CHANGE_PENDING 2	/* switch from 'clean' to 'active' in progress */
+#define MD_ARRAY_FIRST_USE 3    /* First use of array, needs initialization */
 
 	int				suspended;
 	atomic_t			active_io;
@@ -330,6 +331,7 @@
 	atomic_t flush_pending;
 	struct work_struct flush_work;
 	struct work_struct event_work;	/* used by dm to report failure event */
+	void (*sync_super)(mddev_t *mddev, mdk_rdev_t *rdev);
 };
 
 
diff -druN linux-2.6.39-libre/drivers/md/multipath.c linux-3.0-rc7-libre/drivers/md/multipath.c
--- linux-2.6.39-libre/drivers/md/multipath.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/md/multipath.c	2011-07-11 19:51:52.000000000 -0400
@@ -146,7 +146,7 @@
 	int i;
 	
 	seq_printf (seq, " [%d/%d] [", conf->raid_disks,
-						 conf->working_disks);
+		    conf->raid_disks - mddev->degraded);
 	for (i = 0; i < conf->raid_disks; i++)
 		seq_printf (seq, "%s",
 			       conf->multipaths[i].rdev && 
@@ -186,35 +186,36 @@
 static void multipath_error (mddev_t *mddev, mdk_rdev_t *rdev)
 {
 	multipath_conf_t *conf = mddev->private;
+	char b[BDEVNAME_SIZE];
 
-	if (conf->working_disks <= 1) {
+	if (conf->raid_disks - mddev->degraded <= 1) {
 		/*
 		 * Uh oh, we can do nothing if this is our last path, but
 		 * first check if this is a queued request for a device
 		 * which has just failed.
 		 */
 		printk(KERN_ALERT 
-			"multipath: only one IO path left and IO error.\n");
+		       "multipath: only one IO path left and IO error.\n");
 		/* leave it active... it's all we have */
-	} else {
-		/*
-		 * Mark disk as unusable
-		 */
-		if (!test_bit(Faulty, &rdev->flags)) {
-			char b[BDEVNAME_SIZE];
-			clear_bit(In_sync, &rdev->flags);
-			set_bit(Faulty, &rdev->flags);
-			set_bit(MD_CHANGE_DEVS, &mddev->flags);
-			conf->working_disks--;
-			mddev->degraded++;
-			printk(KERN_ALERT "multipath: IO failure on %s,"
-				" disabling IO path.\n"
-				"multipath: Operation continuing"
-				" on %d IO paths.\n",
-				bdevname (rdev->bdev,b),
-				conf->working_disks);
-		}
+		return;
+	}
+	/*
+	 * Mark disk as unusable
+	 */
+	if (test_and_clear_bit(In_sync, &rdev->flags)) {
+		unsigned long flags;
+		spin_lock_irqsave(&conf->device_lock, flags);
+		mddev->degraded++;
+		spin_unlock_irqrestore(&conf->device_lock, flags);
 	}
+	set_bit(Faulty, &rdev->flags);
+	set_bit(MD_CHANGE_DEVS, &mddev->flags);
+	printk(KERN_ALERT "multipath: IO failure on %s,"
+	       " disabling IO path.\n"
+	       "multipath: Operation continuing"
+	       " on %d IO paths.\n",
+	       bdevname(rdev->bdev, b),
+	       conf->raid_disks - mddev->degraded);
 }
 
 static void print_multipath_conf (multipath_conf_t *conf)
@@ -227,7 +228,7 @@
 		printk("(conf==NULL)\n");
 		return;
 	}
-	printk(" --- wd:%d rd:%d\n", conf->working_disks,
+	printk(" --- wd:%d rd:%d\n", conf->raid_disks - conf->mddev->degraded,
 			 conf->raid_disks);
 
 	for (i = 0; i < conf->raid_disks; i++) {
@@ -274,10 +275,11 @@
 							   PAGE_CACHE_SIZE - 1);
 			}
 
-			conf->working_disks++;
+			spin_lock_irq(&conf->device_lock);
 			mddev->degraded--;
 			rdev->raid_disk = path;
 			set_bit(In_sync, &rdev->flags);
+			spin_unlock_irq(&conf->device_lock);
 			rcu_assign_pointer(p->rdev, rdev);
 			err = 0;
 			md_integrity_add_rdev(rdev, mddev);
@@ -391,6 +393,7 @@
 	int disk_idx;
 	struct multipath_info *disk;
 	mdk_rdev_t *rdev;
+	int working_disks;
 
 	if (md_check_no_bitmap(mddev))
 		return -EINVAL;
@@ -424,7 +427,7 @@
 		goto out_free_conf;
 	}
 
-	conf->working_disks = 0;
+	working_disks = 0;
 	list_for_each_entry(rdev, &mddev->disks, same_set) {
 		disk_idx = rdev->raid_disk;
 		if (disk_idx < 0 ||
@@ -446,7 +449,7 @@
 		}
 
 		if (!test_bit(Faulty, &rdev->flags))
-			conf->working_disks++;
+			working_disks++;
 	}
 
 	conf->raid_disks = mddev->raid_disks;
@@ -454,12 +457,12 @@
 	spin_lock_init(&conf->device_lock);
 	INIT_LIST_HEAD(&conf->retry_list);
 
-	if (!conf->working_disks) {
+	if (!working_disks) {
 		printk(KERN_ERR "multipath: no operational IO paths for %s\n",
 			mdname(mddev));
 		goto out_free_conf;
 	}
-	mddev->degraded = conf->raid_disks - conf->working_disks;
+	mddev->degraded = conf->raid_disks - working_disks;
 
 	conf->pool = mempool_create_kmalloc_pool(NR_RESERVED_BUFS,
 						 sizeof(struct multipath_bh));
@@ -481,7 +484,8 @@
 
 	printk(KERN_INFO 
 		"multipath: array %s active with %d out of %d IO paths\n",
-		mdname(mddev), conf->working_disks, mddev->raid_disks);
+		mdname(mddev), conf->raid_disks - mddev->degraded,
+	       mddev->raid_disks);
 	/*
 	 * Ok, everything is just fine now
 	 */
diff -druN linux-2.6.39-libre/drivers/md/multipath.h linux-3.0-rc7-libre/drivers/md/multipath.h
--- linux-2.6.39-libre/drivers/md/multipath.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/md/multipath.h	2011-07-11 19:51:52.000000000 -0400
@@ -9,7 +9,6 @@
 	mddev_t			*mddev;
 	struct multipath_info	*multipaths;
 	int			raid_disks;
-	int			working_disks;
 	spinlock_t		device_lock;
 	struct list_head	retry_list;
 
diff -druN linux-2.6.39-libre/drivers/md/raid10.c linux-3.0-rc7-libre/drivers/md/raid10.c
--- linux-2.6.39-libre/drivers/md/raid10.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/md/raid10.c	2011-07-11 19:51:52.000000000 -0400
@@ -271,9 +271,10 @@
 		 */
 		set_bit(R10BIO_Uptodate, &r10_bio->state);
 		raid_end_bio_io(r10_bio);
+		rdev_dec_pending(conf->mirrors[dev].rdev, conf->mddev);
 	} else {
 		/*
-		 * oops, read error:
+		 * oops, read error - keep the refcount on the rdev
 		 */
 		char b[BDEVNAME_SIZE];
 		if (printk_ratelimit())
@@ -282,8 +283,6 @@
 			       bdevname(conf->mirrors[dev].rdev->bdev,b), (unsigned long long)r10_bio->sector);
 		reschedule_retry(r10_bio);
 	}
-
-	rdev_dec_pending(conf->mirrors[dev].rdev, conf->mddev);
 }
 
 static void raid10_end_write_request(struct bio *bio, int error)
@@ -488,13 +487,19 @@
 static int read_balance(conf_t *conf, r10bio_t *r10_bio)
 {
 	const sector_t this_sector = r10_bio->sector;
-	int disk, slot, nslot;
+	int disk, slot;
 	const int sectors = r10_bio->sectors;
-	sector_t new_distance, current_distance;
+	sector_t new_distance, best_dist;
 	mdk_rdev_t *rdev;
+	int do_balance;
+	int best_slot;
 
 	raid10_find_phys(conf, r10_bio);
 	rcu_read_lock();
+retry:
+	best_slot = -1;
+	best_dist = MaxSector;
+	do_balance = 1;
 	/*
 	 * Check if we can balance. We can balance on the whole
 	 * device if no resync is going on (recovery is ok), or below
@@ -502,86 +507,58 @@
 	 * above the resync window.
 	 */
 	if (conf->mddev->recovery_cp < MaxSector
-	    && (this_sector + sectors >= conf->next_resync)) {
-		/* make sure that disk is operational */
-		slot = 0;
-		disk = r10_bio->devs[slot].devnum;
-
-		while ((rdev = rcu_dereference(conf->mirrors[disk].rdev)) == NULL ||
-		       r10_bio->devs[slot].bio == IO_BLOCKED ||
-		       !test_bit(In_sync, &rdev->flags)) {
-			slot++;
-			if (slot == conf->copies) {
-				slot = 0;
-				disk = -1;
-				break;
-			}
-			disk = r10_bio->devs[slot].devnum;
-		}
-		goto rb_out;
-	}
-
+	    && (this_sector + sectors >= conf->next_resync))
+		do_balance = 0;
 
-	/* make sure the disk is operational */
-	slot = 0;
-	disk = r10_bio->devs[slot].devnum;
-	while ((rdev=rcu_dereference(conf->mirrors[disk].rdev)) == NULL ||
-	       r10_bio->devs[slot].bio == IO_BLOCKED ||
-	       !test_bit(In_sync, &rdev->flags)) {
-		slot ++;
-		if (slot == conf->copies) {
-			disk = -1;
-			goto rb_out;
-		}
+	for (slot = 0; slot < conf->copies ; slot++) {
+		if (r10_bio->devs[slot].bio == IO_BLOCKED)
+			continue;
 		disk = r10_bio->devs[slot].devnum;
-	}
-
-
-	current_distance = abs(r10_bio->devs[slot].addr -
-			       conf->mirrors[disk].head_position);
-
-	/* Find the disk whose head is closest,
-	 * or - for far > 1 - find the closest to partition beginning */
-
-	for (nslot = slot; nslot < conf->copies; nslot++) {
-		int ndisk = r10_bio->devs[nslot].devnum;
-
-
-		if ((rdev=rcu_dereference(conf->mirrors[ndisk].rdev)) == NULL ||
-		    r10_bio->devs[nslot].bio == IO_BLOCKED ||
-		    !test_bit(In_sync, &rdev->flags))
+		rdev = rcu_dereference(conf->mirrors[disk].rdev);
+		if (rdev == NULL)
+			continue;
+		if (!test_bit(In_sync, &rdev->flags))
 			continue;
 
+		if (!do_balance)
+			break;
+
 		/* This optimisation is debatable, and completely destroys
 		 * sequential read speed for 'far copies' arrays.  So only
 		 * keep it for 'near' arrays, and review those later.
 		 */
-		if (conf->near_copies > 1 && !atomic_read(&rdev->nr_pending)) {
-			disk = ndisk;
-			slot = nslot;
+		if (conf->near_copies > 1 && !atomic_read(&rdev->nr_pending))
 			break;
-		}
 
 		/* for far > 1 always use the lowest address */
 		if (conf->far_copies > 1)
-			new_distance = r10_bio->devs[nslot].addr;
+			new_distance = r10_bio->devs[slot].addr;
 		else
-			new_distance = abs(r10_bio->devs[nslot].addr -
-					   conf->mirrors[ndisk].head_position);
-		if (new_distance < current_distance) {
-			current_distance = new_distance;
-			disk = ndisk;
-			slot = nslot;
+			new_distance = abs(r10_bio->devs[slot].addr -
+					   conf->mirrors[disk].head_position);
+		if (new_distance < best_dist) {
+			best_dist = new_distance;
+			best_slot = slot;
 		}
 	}
+	if (slot == conf->copies)
+		slot = best_slot;
 
-rb_out:
-	r10_bio->read_slot = slot;
-/*	conf->next_seq_sect = this_sector + sectors;*/
-
-	if (disk >= 0 && (rdev=rcu_dereference(conf->mirrors[disk].rdev))!= NULL)
-		atomic_inc(&conf->mirrors[disk].rdev->nr_pending);
-	else
+	if (slot >= 0) {
+		disk = r10_bio->devs[slot].devnum;
+		rdev = rcu_dereference(conf->mirrors[disk].rdev);
+		if (!rdev)
+			goto retry;
+		atomic_inc(&rdev->nr_pending);
+		if (test_bit(Faulty, &rdev->flags)) {
+			/* Cannot risk returning a device that failed
+			 * before we inc'ed nr_pending
+			 */
+			rdev_dec_pending(rdev, conf->mddev);
+			goto retry;
+		}
+		r10_bio->read_slot = slot;
+	} else
 		disk = -1;
 	rcu_read_unlock();
 
@@ -1460,40 +1437,33 @@
 	int max_read_errors = atomic_read(&mddev->max_corr_read_errors);
 	int d = r10_bio->devs[r10_bio->read_slot].devnum;
 
-	rcu_read_lock();
-	rdev = rcu_dereference(conf->mirrors[d].rdev);
-	if (rdev) { /* If rdev is not NULL */
-		char b[BDEVNAME_SIZE];
-		int cur_read_error_count = 0;
+	/* still own a reference to this rdev, so it cannot
+	 * have been cleared recently.
+	 */
+	rdev = conf->mirrors[d].rdev;
 
-		bdevname(rdev->bdev, b);
+	if (test_bit(Faulty, &rdev->flags))
+		/* drive has already been failed, just ignore any
+		   more fix_read_error() attempts */
+		return;
 
-		if (test_bit(Faulty, &rdev->flags)) {
-			rcu_read_unlock();
-			/* drive has already been failed, just ignore any
-			   more fix_read_error() attempts */
-			return;
-		}
+	check_decay_read_errors(mddev, rdev);
+	atomic_inc(&rdev->read_errors);
+	if (atomic_read(&rdev->read_errors) > max_read_errors) {
+		char b[BDEVNAME_SIZE];
+		bdevname(rdev->bdev, b);
 
-		check_decay_read_errors(mddev, rdev);
-		atomic_inc(&rdev->read_errors);
-		cur_read_error_count = atomic_read(&rdev->read_errors);
-		if (cur_read_error_count > max_read_errors) {
-			rcu_read_unlock();
-			printk(KERN_NOTICE
-			       "md/raid10:%s: %s: Raid device exceeded "
-			       "read_error threshold "
-			       "[cur %d:max %d]\n",
-			       mdname(mddev),
-			       b, cur_read_error_count, max_read_errors);
-			printk(KERN_NOTICE
-			       "md/raid10:%s: %s: Failing raid "
-			       "device\n", mdname(mddev), b);
-			md_error(mddev, conf->mirrors[d].rdev);
-			return;
-		}
+		printk(KERN_NOTICE
+		       "md/raid10:%s: %s: Raid device exceeded "
+		       "read_error threshold [cur %d:max %d]\n",
+		       mdname(mddev), b,
+		       atomic_read(&rdev->read_errors), max_read_errors);
+		printk(KERN_NOTICE
+		       "md/raid10:%s: %s: Failing raid device\n",
+		       mdname(mddev), b);
+		md_error(mddev, conf->mirrors[d].rdev);
+		return;
 	}
-	rcu_read_unlock();
 
 	while(sectors) {
 		int s = sectors;
@@ -1562,8 +1532,8 @@
 					       "write failed"
 					       " (%d sectors at %llu on %s)\n",
 					       mdname(mddev), s,
-					       (unsigned long long)(sect+
-					       rdev->data_offset),
+					       (unsigned long long)(
+						       sect + rdev->data_offset),
 					       bdevname(rdev->bdev, b));
 					printk(KERN_NOTICE "md/raid10:%s: %s: failing "
 					       "drive\n",
@@ -1599,8 +1569,8 @@
 					       "corrected sectors"
 					       " (%d sectors at %llu on %s)\n",
 					       mdname(mddev), s,
-					       (unsigned long long)(sect+
-						    rdev->data_offset),
+					       (unsigned long long)(
+						       sect + rdev->data_offset),
 					       bdevname(rdev->bdev, b));
 					printk(KERN_NOTICE "md/raid10:%s: %s: failing drive\n",
 					       mdname(mddev),
@@ -1612,8 +1582,8 @@
 					       "md/raid10:%s: read error corrected"
 					       " (%d sectors at %llu on %s)\n",
 					       mdname(mddev), s,
-					       (unsigned long long)(sect+
-					            rdev->data_offset),
+					       (unsigned long long)(
+						       sect + rdev->data_offset),
 					       bdevname(rdev->bdev, b));
 				}
 
@@ -1663,7 +1633,8 @@
 		else if (test_bit(R10BIO_IsRecover, &r10_bio->state))
 			recovery_request_write(mddev, r10_bio);
 		else {
-			int mirror;
+			int slot = r10_bio->read_slot;
+			int mirror = r10_bio->devs[slot].devnum;
 			/* we got a read error. Maybe the drive is bad.  Maybe just
 			 * the block and we can fix it.
 			 * We freeze all other IO, and try reading the block from
@@ -1677,9 +1648,10 @@
 				fix_read_error(conf, mddev, r10_bio);
 				unfreeze_array(conf);
 			}
+			rdev_dec_pending(conf->mirrors[mirror].rdev, mddev);
 
-			bio = r10_bio->devs[r10_bio->read_slot].bio;
-			r10_bio->devs[r10_bio->read_slot].bio =
+			bio = r10_bio->devs[slot].bio;
+			r10_bio->devs[slot].bio =
 				mddev->ro ? IO_BLOCKED : NULL;
 			mirror = read_balance(conf, r10_bio);
 			if (mirror == -1) {
@@ -1693,6 +1665,7 @@
 			} else {
 				const unsigned long do_sync = (r10_bio->master_bio->bi_rw & REQ_SYNC);
 				bio_put(bio);
+				slot = r10_bio->read_slot;
 				rdev = conf->mirrors[mirror].rdev;
 				if (printk_ratelimit())
 					printk(KERN_ERR "md/raid10:%s: %s: redirecting sector %llu to"
@@ -1702,8 +1675,8 @@
 					       (unsigned long long)r10_bio->sector);
 				bio = bio_clone_mddev(r10_bio->master_bio,
 						      GFP_NOIO, mddev);
-				r10_bio->devs[r10_bio->read_slot].bio = bio;
-				bio->bi_sector = r10_bio->devs[r10_bio->read_slot].addr
+				r10_bio->devs[slot].bio = bio;
+				bio->bi_sector = r10_bio->devs[slot].addr
 					+ rdev->data_offset;
 				bio->bi_bdev = rdev->bdev;
 				bio->bi_rw = READ | do_sync;
@@ -1763,13 +1736,13 @@
  *
  */
 
-static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, int go_faster)
+static sector_t sync_request(mddev_t *mddev, sector_t sector_nr,
+			     int *skipped, int go_faster)
 {
 	conf_t *conf = mddev->private;
 	r10bio_t *r10_bio;
 	struct bio *biolist = NULL, *bio;
 	sector_t max_sector, nr_sectors;
-	int disk;
 	int i;
 	int max_sync;
 	sector_t sync_blocks;
@@ -1858,108 +1831,114 @@
 		int j, k;
 		r10_bio = NULL;
 
-		for (i=0 ; i<conf->raid_disks; i++)
-			if (conf->mirrors[i].rdev &&
-			    !test_bit(In_sync, &conf->mirrors[i].rdev->flags)) {
-				int still_degraded = 0;
-				/* want to reconstruct this device */
-				r10bio_t *rb2 = r10_bio;
-				sector_t sect = raid10_find_virt(conf, sector_nr, i);
-				int must_sync;
-				/* Unless we are doing a full sync, we only need
-				 * to recover the block if it is set in the bitmap
-				 */
-				must_sync = bitmap_start_sync(mddev->bitmap, sect,
-							      &sync_blocks, 1);
-				if (sync_blocks < max_sync)
-					max_sync = sync_blocks;
-				if (!must_sync &&
-				    !conf->fullsync) {
-					/* yep, skip the sync_blocks here, but don't assume
-					 * that there will never be anything to do here
-					 */
-					chunks_skipped = -1;
-					continue;
-				}
+		for (i=0 ; i<conf->raid_disks; i++) {
+			int still_degraded;
+			r10bio_t *rb2;
+			sector_t sect;
+			int must_sync;
 
-				r10_bio = mempool_alloc(conf->r10buf_pool, GFP_NOIO);
-				raise_barrier(conf, rb2 != NULL);
-				atomic_set(&r10_bio->remaining, 0);
+			if (conf->mirrors[i].rdev == NULL ||
+			    test_bit(In_sync, &conf->mirrors[i].rdev->flags)) 
+				continue;
 
-				r10_bio->master_bio = (struct bio*)rb2;
-				if (rb2)
-					atomic_inc(&rb2->remaining);
-				r10_bio->mddev = mddev;
-				set_bit(R10BIO_IsRecover, &r10_bio->state);
-				r10_bio->sector = sect;
+			still_degraded = 0;
+			/* want to reconstruct this device */
+			rb2 = r10_bio;
+			sect = raid10_find_virt(conf, sector_nr, i);
+			/* Unless we are doing a full sync, we only need
+			 * to recover the block if it is set in the bitmap
+			 */
+			must_sync = bitmap_start_sync(mddev->bitmap, sect,
+						      &sync_blocks, 1);
+			if (sync_blocks < max_sync)
+				max_sync = sync_blocks;
+			if (!must_sync &&
+			    !conf->fullsync) {
+				/* yep, skip the sync_blocks here, but don't assume
+				 * that there will never be anything to do here
+				 */
+				chunks_skipped = -1;
+				continue;
+			}
 
-				raid10_find_phys(conf, r10_bio);
+			r10_bio = mempool_alloc(conf->r10buf_pool, GFP_NOIO);
+			raise_barrier(conf, rb2 != NULL);
+			atomic_set(&r10_bio->remaining, 0);
 
-				/* Need to check if the array will still be
-				 * degraded
-				 */
-				for (j=0; j<conf->raid_disks; j++)
-					if (conf->mirrors[j].rdev == NULL ||
-					    test_bit(Faulty, &conf->mirrors[j].rdev->flags)) {
-						still_degraded = 1;
-						break;
-					}
+			r10_bio->master_bio = (struct bio*)rb2;
+			if (rb2)
+				atomic_inc(&rb2->remaining);
+			r10_bio->mddev = mddev;
+			set_bit(R10BIO_IsRecover, &r10_bio->state);
+			r10_bio->sector = sect;
 
-				must_sync = bitmap_start_sync(mddev->bitmap, sect,
-							      &sync_blocks, still_degraded);
+			raid10_find_phys(conf, r10_bio);
 
-				for (j=0; j<conf->copies;j++) {
-					int d = r10_bio->devs[j].devnum;
-					if (conf->mirrors[d].rdev &&
-					    test_bit(In_sync, &conf->mirrors[d].rdev->flags)) {
-						/* This is where we read from */
-						bio = r10_bio->devs[0].bio;
-						bio->bi_next = biolist;
-						biolist = bio;
-						bio->bi_private = r10_bio;
-						bio->bi_end_io = end_sync_read;
-						bio->bi_rw = READ;
-						bio->bi_sector = r10_bio->devs[j].addr +
-							conf->mirrors[d].rdev->data_offset;
-						bio->bi_bdev = conf->mirrors[d].rdev->bdev;
-						atomic_inc(&conf->mirrors[d].rdev->nr_pending);
-						atomic_inc(&r10_bio->remaining);
-						/* and we write to 'i' */
+			/* Need to check if the array will still be
+			 * degraded
+			 */
+			for (j=0; j<conf->raid_disks; j++)
+				if (conf->mirrors[j].rdev == NULL ||
+				    test_bit(Faulty, &conf->mirrors[j].rdev->flags)) {
+					still_degraded = 1;
+					break;
+				}
 
-						for (k=0; k<conf->copies; k++)
-							if (r10_bio->devs[k].devnum == i)
-								break;
-						BUG_ON(k == conf->copies);
-						bio = r10_bio->devs[1].bio;
-						bio->bi_next = biolist;
-						biolist = bio;
-						bio->bi_private = r10_bio;
-						bio->bi_end_io = end_sync_write;
-						bio->bi_rw = WRITE;
-						bio->bi_sector = r10_bio->devs[k].addr +
-							conf->mirrors[i].rdev->data_offset;
-						bio->bi_bdev = conf->mirrors[i].rdev->bdev;
+			must_sync = bitmap_start_sync(mddev->bitmap, sect,
+						      &sync_blocks, still_degraded);
 
-						r10_bio->devs[0].devnum = d;
-						r10_bio->devs[1].devnum = i;
+			for (j=0; j<conf->copies;j++) {
+				int d = r10_bio->devs[j].devnum;
+				if (!conf->mirrors[d].rdev ||
+				    !test_bit(In_sync, &conf->mirrors[d].rdev->flags))
+					continue;
+				/* This is where we read from */
+				bio = r10_bio->devs[0].bio;
+				bio->bi_next = biolist;
+				biolist = bio;
+				bio->bi_private = r10_bio;
+				bio->bi_end_io = end_sync_read;
+				bio->bi_rw = READ;
+				bio->bi_sector = r10_bio->devs[j].addr +
+					conf->mirrors[d].rdev->data_offset;
+				bio->bi_bdev = conf->mirrors[d].rdev->bdev;
+				atomic_inc(&conf->mirrors[d].rdev->nr_pending);
+				atomic_inc(&r10_bio->remaining);
+				/* and we write to 'i' */
 
+				for (k=0; k<conf->copies; k++)
+					if (r10_bio->devs[k].devnum == i)
 						break;
-					}
-				}
-				if (j == conf->copies) {
-					/* Cannot recover, so abort the recovery */
-					put_buf(r10_bio);
-					if (rb2)
-						atomic_dec(&rb2->remaining);
-					r10_bio = rb2;
-					if (!test_and_set_bit(MD_RECOVERY_INTR,
-							      &mddev->recovery))
-						printk(KERN_INFO "md/raid10:%s: insufficient "
-						       "working devices for recovery.\n",
-						       mdname(mddev));
-					break;
-				}
+				BUG_ON(k == conf->copies);
+				bio = r10_bio->devs[1].bio;
+				bio->bi_next = biolist;
+				biolist = bio;
+				bio->bi_private = r10_bio;
+				bio->bi_end_io = end_sync_write;
+				bio->bi_rw = WRITE;
+				bio->bi_sector = r10_bio->devs[k].addr +
+					conf->mirrors[i].rdev->data_offset;
+				bio->bi_bdev = conf->mirrors[i].rdev->bdev;
+
+				r10_bio->devs[0].devnum = d;
+				r10_bio->devs[1].devnum = i;
+
+				break;
+			}
+			if (j == conf->copies) {
+				/* Cannot recover, so abort the recovery */
+				put_buf(r10_bio);
+				if (rb2)
+					atomic_dec(&rb2->remaining);
+				r10_bio = rb2;
+				if (!test_and_set_bit(MD_RECOVERY_INTR,
+						      &mddev->recovery))
+					printk(KERN_INFO "md/raid10:%s: insufficient "
+					       "working devices for recovery.\n",
+					       mdname(mddev));
+				break;
 			}
+		}
 		if (biolist == NULL) {
 			while (r10_bio) {
 				r10bio_t *rb2 = r10_bio;
@@ -1977,7 +1956,8 @@
 
 		if (!bitmap_start_sync(mddev->bitmap, sector_nr,
 				       &sync_blocks, mddev->degraded) &&
-		    !conf->fullsync && !test_bit(MD_RECOVERY_REQUESTED, &mddev->recovery)) {
+		    !conf->fullsync && !test_bit(MD_RECOVERY_REQUESTED,
+						 &mddev->recovery)) {
 			/* We can skip this block */
 			*skipped = 1;
 			return sync_blocks + sectors_skipped;
@@ -2022,7 +2002,8 @@
 			for (i=0; i<conf->copies; i++) {
 				int d = r10_bio->devs[i].devnum;
 				if (r10_bio->devs[i].bio->bi_end_io)
-					rdev_dec_pending(conf->mirrors[d].rdev, mddev);
+					rdev_dec_pending(conf->mirrors[d].rdev,
+							 mddev);
 			}
 			put_buf(r10_bio);
 			biolist = NULL;
@@ -2047,26 +2028,27 @@
 	do {
 		struct page *page;
 		int len = PAGE_SIZE;
-		disk = 0;
 		if (sector_nr + (len>>9) > max_sector)
 			len = (max_sector - sector_nr) << 9;
 		if (len == 0)
 			break;
 		for (bio= biolist ; bio ; bio=bio->bi_next) {
+			struct bio *bio2;
 			page = bio->bi_io_vec[bio->bi_vcnt].bv_page;
-			if (bio_add_page(bio, page, len, 0) == 0) {
-				/* stop here */
-				struct bio *bio2;
-				bio->bi_io_vec[bio->bi_vcnt].bv_page = page;
-				for (bio2 = biolist; bio2 && bio2 != bio; bio2 = bio2->bi_next) {
-					/* remove last page from this bio */
-					bio2->bi_vcnt--;
-					bio2->bi_size -= len;
-					bio2->bi_flags &= ~(1<< BIO_SEG_VALID);
-				}
-				goto bio_full;
+			if (bio_add_page(bio, page, len, 0))
+				continue;
+
+			/* stop here */
+			bio->bi_io_vec[bio->bi_vcnt].bv_page = page;
+			for (bio2 = biolist;
+			     bio2 && bio2 != bio;
+			     bio2 = bio2->bi_next) {
+				/* remove last page from this bio */
+				bio2->bi_vcnt--;
+				bio2->bi_size -= len;
+				bio2->bi_flags &= ~(1<< BIO_SEG_VALID);
 			}
-			disk = i;
+			goto bio_full;
 		}
 		nr_sectors += len>>9;
 		sector_nr += len>>9;
diff -druN linux-2.6.39-libre/drivers/md/raid1.c linux-3.0-rc7-libre/drivers/md/raid1.c
--- linux-2.6.39-libre/drivers/md/raid1.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/md/raid1.c	2011-07-11 19:51:52.000000000 -0400
@@ -297,23 +297,24 @@
 	rdev_dec_pending(conf->mirrors[mirror].rdev, conf->mddev);
 }
 
-static void r1_bio_write_done(r1bio_t *r1_bio, int vcnt, struct bio_vec *bv,
-			      int behind)
+static void r1_bio_write_done(r1bio_t *r1_bio)
 {
 	if (atomic_dec_and_test(&r1_bio->remaining))
 	{
 		/* it really is the end of this request */
 		if (test_bit(R1BIO_BehindIO, &r1_bio->state)) {
 			/* free extra copy of the data pages */
-			int i = vcnt;
+			int i = r1_bio->behind_page_count;
 			while (i--)
-				safe_put_page(bv[i].bv_page);
+				safe_put_page(r1_bio->behind_pages[i]);
+			kfree(r1_bio->behind_pages);
+			r1_bio->behind_pages = NULL;
 		}
 		/* clear the bitmap if all writes complete successfully */
 		bitmap_endwrite(r1_bio->mddev->bitmap, r1_bio->sector,
 				r1_bio->sectors,
 				!test_bit(R1BIO_Degraded, &r1_bio->state),
-				behind);
+				test_bit(R1BIO_BehindIO, &r1_bio->state));
 		md_write_end(r1_bio->mddev);
 		raid_end_bio_io(r1_bio);
 	}
@@ -386,7 +387,7 @@
 	 * Let's see if all mirrored write operations have finished
 	 * already.
 	 */
-	r1_bio_write_done(r1_bio, bio->bi_vcnt, bio->bi_io_vec, behind);
+	r1_bio_write_done(r1_bio);
 
 	if (to_put)
 		bio_put(to_put);
@@ -411,10 +412,10 @@
 {
 	const sector_t this_sector = r1_bio->sector;
 	const int sectors = r1_bio->sectors;
-	int new_disk = -1;
 	int start_disk;
+	int best_disk;
 	int i;
-	sector_t new_distance, current_distance;
+	sector_t best_dist;
 	mdk_rdev_t *rdev;
 	int choose_first;
 
@@ -425,6 +426,8 @@
 	 * We take the first readable disk when above the resync window.
 	 */
  retry:
+	best_disk = -1;
+	best_dist = MaxSector;
 	if (conf->mddev->recovery_cp < MaxSector &&
 	    (this_sector + sectors >= conf->next_resync)) {
 		choose_first = 1;
@@ -434,8 +437,8 @@
 		start_disk = conf->last_used;
 	}
 
-	/* make sure the disk is operational */
 	for (i = 0 ; i < conf->raid_disks ; i++) {
+		sector_t dist;
 		int disk = start_disk + i;
 		if (disk >= conf->raid_disks)
 			disk -= conf->raid_disks;
@@ -443,60 +446,43 @@
 		rdev = rcu_dereference(conf->mirrors[disk].rdev);
 		if (r1_bio->bios[disk] == IO_BLOCKED
 		    || rdev == NULL
-		    || !test_bit(In_sync, &rdev->flags))
+		    || test_bit(Faulty, &rdev->flags))
 			continue;
-
-		new_disk = disk;
-		if (!test_bit(WriteMostly, &rdev->flags))
-			break;
-	}
-
-	if (new_disk < 0 || choose_first)
-		goto rb_out;
-
-	/*
-	 * Don't change to another disk for sequential reads:
-	 */
-	if (conf->next_seq_sect == this_sector)
-		goto rb_out;
-	if (this_sector == conf->mirrors[new_disk].head_position)
-		goto rb_out;
-
-	current_distance = abs(this_sector 
-			       - conf->mirrors[new_disk].head_position);
-
-	/* look for a better disk - i.e. head is closer */
-	start_disk = new_disk;
-	for (i = 1; i < conf->raid_disks; i++) {
-		int disk = start_disk + 1;
-		if (disk >= conf->raid_disks)
-			disk -= conf->raid_disks;
-
-		rdev = rcu_dereference(conf->mirrors[disk].rdev);
-		if (r1_bio->bios[disk] == IO_BLOCKED
-		    || rdev == NULL
-		    || !test_bit(In_sync, &rdev->flags)
-		    || test_bit(WriteMostly, &rdev->flags))
+		if (!test_bit(In_sync, &rdev->flags) &&
+		    rdev->recovery_offset < this_sector + sectors)
 			continue;
-
-		if (!atomic_read(&rdev->nr_pending)) {
-			new_disk = disk;
+		if (test_bit(WriteMostly, &rdev->flags)) {
+			/* Don't balance among write-mostly, just
+			 * use the first as a last resort */
+			if (best_disk < 0)
+				best_disk = disk;
+			continue;
+		}
+		/* This is a reasonable device to use.  It might
+		 * even be best.
+		 */
+		dist = abs(this_sector - conf->mirrors[disk].head_position);
+		if (choose_first
+		    /* Don't change to another disk for sequential reads */
+		    || conf->next_seq_sect == this_sector
+		    || dist == 0
+		    /* If device is idle, use it */
+		    || atomic_read(&rdev->nr_pending) == 0) {
+			best_disk = disk;
 			break;
 		}
-		new_distance = abs(this_sector - conf->mirrors[disk].head_position);
-		if (new_distance < current_distance) {
-			current_distance = new_distance;
-			new_disk = disk;
+		if (dist < best_dist) {
+			best_dist = dist;
+			best_disk = disk;
 		}
 	}
 
- rb_out:
-	if (new_disk >= 0) {
-		rdev = rcu_dereference(conf->mirrors[new_disk].rdev);
+	if (best_disk >= 0) {
+		rdev = rcu_dereference(conf->mirrors[best_disk].rdev);
 		if (!rdev)
 			goto retry;
 		atomic_inc(&rdev->nr_pending);
-		if (!test_bit(In_sync, &rdev->flags)) {
+		if (test_bit(Faulty, &rdev->flags)) {
 			/* cannot risk returning a device that failed
 			 * before we inc'ed nr_pending
 			 */
@@ -504,28 +490,26 @@
 			goto retry;
 		}
 		conf->next_seq_sect = this_sector + sectors;
-		conf->last_used = new_disk;
+		conf->last_used = best_disk;
 	}
 	rcu_read_unlock();
 
-	return new_disk;
+	return best_disk;
 }
 
-static int raid1_congested(void *data, int bits)
+int md_raid1_congested(mddev_t *mddev, int bits)
 {
-	mddev_t *mddev = data;
 	conf_t *conf = mddev->private;
 	int i, ret = 0;
 
-	if (mddev_congested(mddev, bits))
-		return 1;
-
 	rcu_read_lock();
 	for (i = 0; i < mddev->raid_disks; i++) {
 		mdk_rdev_t *rdev = rcu_dereference(conf->mirrors[i].rdev);
 		if (rdev && !test_bit(Faulty, &rdev->flags)) {
 			struct request_queue *q = bdev_get_queue(rdev->bdev);
 
+			BUG_ON(!q);
+
 			/* Note the '|| 1' - when read_balance prefers
 			 * non-congested targets, it can be removed
 			 */
@@ -538,7 +522,15 @@
 	rcu_read_unlock();
 	return ret;
 }
+EXPORT_SYMBOL_GPL(md_raid1_congested);
+
+static int raid1_congested(void *data, int bits)
+{
+	mddev_t *mddev = data;
 
+	return mddev_congested(mddev, bits) ||
+		md_raid1_congested(mddev, bits);
+}
 
 static void flush_pending_writes(conf_t *conf)
 {
@@ -675,37 +667,36 @@
 
 
 /* duplicate the data pages for behind I/O 
- * We return a list of bio_vec rather than just page pointers
- * as it makes freeing easier
  */
-static struct bio_vec *alloc_behind_pages(struct bio *bio)
+static void alloc_behind_pages(struct bio *bio, r1bio_t *r1_bio)
 {
 	int i;
 	struct bio_vec *bvec;
-	struct bio_vec *pages = kzalloc(bio->bi_vcnt * sizeof(struct bio_vec),
+	struct page **pages = kzalloc(bio->bi_vcnt * sizeof(struct page*),
 					GFP_NOIO);
 	if (unlikely(!pages))
-		goto do_sync_io;
+		return;
 
 	bio_for_each_segment(bvec, bio, i) {
-		pages[i].bv_page = alloc_page(GFP_NOIO);
-		if (unlikely(!pages[i].bv_page))
+		pages[i] = alloc_page(GFP_NOIO);
+		if (unlikely(!pages[i]))
 			goto do_sync_io;
-		memcpy(kmap(pages[i].bv_page) + bvec->bv_offset,
+		memcpy(kmap(pages[i]) + bvec->bv_offset,
 			kmap(bvec->bv_page) + bvec->bv_offset, bvec->bv_len);
-		kunmap(pages[i].bv_page);
+		kunmap(pages[i]);
 		kunmap(bvec->bv_page);
 	}
-
-	return pages;
+	r1_bio->behind_pages = pages;
+	r1_bio->behind_page_count = bio->bi_vcnt;
+	set_bit(R1BIO_BehindIO, &r1_bio->state);
+	return;
 
 do_sync_io:
-	if (pages)
-		for (i = 0; i < bio->bi_vcnt && pages[i].bv_page; i++)
-			put_page(pages[i].bv_page);
+	for (i = 0; i < bio->bi_vcnt; i++)
+		if (pages[i])
+			put_page(pages[i]);
 	kfree(pages);
 	PRINTK("%dB behind alloc failed, doing sync I/O\n", bio->bi_size);
-	return NULL;
 }
 
 static int make_request(mddev_t *mddev, struct bio * bio)
@@ -717,7 +708,6 @@
 	int i, targets = 0, disks;
 	struct bitmap *bitmap;
 	unsigned long flags;
-	struct bio_vec *behind_pages = NULL;
 	const int rw = bio_data_dir(bio);
 	const unsigned long do_sync = (bio->bi_rw & REQ_SYNC);
 	const unsigned long do_flush_fua = (bio->bi_rw & (REQ_FLUSH | REQ_FUA));
@@ -870,9 +860,8 @@
 	if (bitmap &&
 	    (atomic_read(&bitmap->behind_writes)
 	     < mddev->bitmap_info.max_write_behind) &&
-	    !waitqueue_active(&bitmap->behind_wait) &&
-	    (behind_pages = alloc_behind_pages(bio)) != NULL)
-		set_bit(R1BIO_BehindIO, &r1_bio->state);
+	    !waitqueue_active(&bitmap->behind_wait))
+		alloc_behind_pages(bio, r1_bio);
 
 	atomic_set(&r1_bio->remaining, 1);
 	atomic_set(&r1_bio->behind_remaining, 0);
@@ -893,7 +882,7 @@
 		mbio->bi_rw = WRITE | do_flush_fua | do_sync;
 		mbio->bi_private = r1_bio;
 
-		if (behind_pages) {
+		if (r1_bio->behind_pages) {
 			struct bio_vec *bvec;
 			int j;
 
@@ -905,7 +894,7 @@
 			 * them all
 			 */
 			__bio_for_each_segment(bvec, mbio, j, 0)
-				bvec->bv_page = behind_pages[j].bv_page;
+				bvec->bv_page = r1_bio->behind_pages[j];
 			if (test_bit(WriteMostly, &conf->mirrors[i].rdev->flags))
 				atomic_inc(&r1_bio->behind_remaining);
 		}
@@ -915,8 +904,7 @@
 		bio_list_add(&conf->pending_bio_list, mbio);
 		spin_unlock_irqrestore(&conf->device_lock, flags);
 	}
-	r1_bio_write_done(r1_bio, bio->bi_vcnt, behind_pages, behind_pages != NULL);
-	kfree(behind_pages); /* the behind pages are attached to the bios now */
+	r1_bio_write_done(r1_bio);
 
 	/* In case raid1d snuck in to freeze_array */
 	wake_up(&conf->wait_barrier);
@@ -1196,194 +1184,210 @@
 	}
 }
 
-static void sync_request_write(mddev_t *mddev, r1bio_t *r1_bio)
+static int fix_sync_read_error(r1bio_t *r1_bio)
 {
+	/* Try some synchronous reads of other devices to get
+	 * good data, much like with normal read errors.  Only
+	 * read into the pages we already have so we don't
+	 * need to re-issue the read request.
+	 * We don't need to freeze the array, because being in an
+	 * active sync request, there is no normal IO, and
+	 * no overlapping syncs.
+	 */
+	mddev_t *mddev = r1_bio->mddev;
 	conf_t *conf = mddev->private;
-	int i;
-	int disks = conf->raid_disks;
-	struct bio *bio, *wbio;
-
-	bio = r1_bio->bios[r1_bio->read_disk];
+	struct bio *bio = r1_bio->bios[r1_bio->read_disk];
+	sector_t sect = r1_bio->sector;
+	int sectors = r1_bio->sectors;
+	int idx = 0;
 
+	while(sectors) {
+		int s = sectors;
+		int d = r1_bio->read_disk;
+		int success = 0;
+		mdk_rdev_t *rdev;
+		int start;
 
-	if (test_bit(MD_RECOVERY_REQUESTED, &mddev->recovery)) {
-		/* We have read all readable devices.  If we haven't
-		 * got the block, then there is no hope left.
-		 * If we have, then we want to do a comparison
-		 * and skip the write if everything is the same.
-		 * If any blocks failed to read, then we need to
-		 * attempt an over-write
-		 */
-		int primary;
-		if (!test_bit(R1BIO_Uptodate, &r1_bio->state)) {
-			for (i=0; i<mddev->raid_disks; i++)
-				if (r1_bio->bios[i]->bi_end_io == end_sync_read)
-					md_error(mddev, conf->mirrors[i].rdev);
+		if (s > (PAGE_SIZE>>9))
+			s = PAGE_SIZE >> 9;
+		do {
+			if (r1_bio->bios[d]->bi_end_io == end_sync_read) {
+				/* No rcu protection needed here devices
+				 * can only be removed when no resync is
+				 * active, and resync is currently active
+				 */
+				rdev = conf->mirrors[d].rdev;
+				if (sync_page_io(rdev,
+						 sect,
+						 s<<9,
+						 bio->bi_io_vec[idx].bv_page,
+						 READ, false)) {
+					success = 1;
+					break;
+				}
+			}
+			d++;
+			if (d == conf->raid_disks)
+				d = 0;
+		} while (!success && d != r1_bio->read_disk);
 
-			md_done_sync(mddev, r1_bio->sectors, 1);
+		if (!success) {
+			char b[BDEVNAME_SIZE];
+			/* Cannot read from anywhere, array is toast */
+			md_error(mddev, conf->mirrors[r1_bio->read_disk].rdev);
+			printk(KERN_ALERT "md/raid1:%s: %s: unrecoverable I/O read error"
+			       " for block %llu\n",
+			       mdname(mddev),
+			       bdevname(bio->bi_bdev, b),
+			       (unsigned long long)r1_bio->sector);
+			md_done_sync(mddev, r1_bio->sectors, 0);
 			put_buf(r1_bio);
-			return;
+			return 0;
 		}
-		for (primary=0; primary<mddev->raid_disks; primary++)
-			if (r1_bio->bios[primary]->bi_end_io == end_sync_read &&
-			    test_bit(BIO_UPTODATE, &r1_bio->bios[primary]->bi_flags)) {
-				r1_bio->bios[primary]->bi_end_io = NULL;
-				rdev_dec_pending(conf->mirrors[primary].rdev, mddev);
-				break;
-			}
-		r1_bio->read_disk = primary;
-		for (i=0; i<mddev->raid_disks; i++)
-			if (r1_bio->bios[i]->bi_end_io == end_sync_read) {
-				int j;
-				int vcnt = r1_bio->sectors >> (PAGE_SHIFT- 9);
-				struct bio *pbio = r1_bio->bios[primary];
-				struct bio *sbio = r1_bio->bios[i];
-
-				if (test_bit(BIO_UPTODATE, &sbio->bi_flags)) {
-					for (j = vcnt; j-- ; ) {
-						struct page *p, *s;
-						p = pbio->bi_io_vec[j].bv_page;
-						s = sbio->bi_io_vec[j].bv_page;
-						if (memcmp(page_address(p),
-							   page_address(s),
-							   PAGE_SIZE))
-							break;
-					}
-				} else
-					j = 0;
-				if (j >= 0)
-					mddev->resync_mismatches += r1_bio->sectors;
-				if (j < 0 || (test_bit(MD_RECOVERY_CHECK, &mddev->recovery)
-					      && test_bit(BIO_UPTODATE, &sbio->bi_flags))) {
-					sbio->bi_end_io = NULL;
-					rdev_dec_pending(conf->mirrors[i].rdev, mddev);
-				} else {
-					/* fixup the bio for reuse */
-					int size;
-					sbio->bi_vcnt = vcnt;
-					sbio->bi_size = r1_bio->sectors << 9;
-					sbio->bi_idx = 0;
-					sbio->bi_phys_segments = 0;
-					sbio->bi_flags &= ~(BIO_POOL_MASK - 1);
-					sbio->bi_flags |= 1 << BIO_UPTODATE;
-					sbio->bi_next = NULL;
-					sbio->bi_sector = r1_bio->sector +
-						conf->mirrors[i].rdev->data_offset;
-					sbio->bi_bdev = conf->mirrors[i].rdev->bdev;
-					size = sbio->bi_size;
-					for (j = 0; j < vcnt ; j++) {
-						struct bio_vec *bi;
-						bi = &sbio->bi_io_vec[j];
-						bi->bv_offset = 0;
-						if (size > PAGE_SIZE)
-							bi->bv_len = PAGE_SIZE;
-						else
-							bi->bv_len = size;
-						size -= PAGE_SIZE;
-						memcpy(page_address(bi->bv_page),
-						       page_address(pbio->bi_io_vec[j].bv_page),
-						       PAGE_SIZE);
-					}
 
-				}
-			}
+		start = d;
+		/* write it back and re-read */
+		while (d != r1_bio->read_disk) {
+			if (d == 0)
+				d = conf->raid_disks;
+			d--;
+			if (r1_bio->bios[d]->bi_end_io != end_sync_read)
+				continue;
+			rdev = conf->mirrors[d].rdev;
+			if (sync_page_io(rdev,
+					 sect,
+					 s<<9,
+					 bio->bi_io_vec[idx].bv_page,
+					 WRITE, false) == 0) {
+				r1_bio->bios[d]->bi_end_io = NULL;
+				rdev_dec_pending(rdev, mddev);
+				md_error(mddev, rdev);
+			} else
+				atomic_add(s, &rdev->corrected_errors);
+		}
+		d = start;
+		while (d != r1_bio->read_disk) {
+			if (d == 0)
+				d = conf->raid_disks;
+			d--;
+			if (r1_bio->bios[d]->bi_end_io != end_sync_read)
+				continue;
+			rdev = conf->mirrors[d].rdev;
+			if (sync_page_io(rdev,
+					 sect,
+					 s<<9,
+					 bio->bi_io_vec[idx].bv_page,
+					 READ, false) == 0)
+				md_error(mddev, rdev);
+		}
+		sectors -= s;
+		sect += s;
+		idx ++;
 	}
-	if (!test_bit(R1BIO_Uptodate, &r1_bio->state)) {
-		/* ouch - failed to read all of that.
-		 * Try some synchronous reads of other devices to get
-		 * good data, much like with normal read errors.  Only
-		 * read into the pages we already have so we don't
-		 * need to re-issue the read request.
-		 * We don't need to freeze the array, because being in an
-		 * active sync request, there is no normal IO, and
-		 * no overlapping syncs.
-		 */
-		sector_t sect = r1_bio->sector;
-		int sectors = r1_bio->sectors;
-		int idx = 0;
+	set_bit(R1BIO_Uptodate, &r1_bio->state);
+	set_bit(BIO_UPTODATE, &bio->bi_flags);
+	return 1;
+}
 
-		while(sectors) {
-			int s = sectors;
-			int d = r1_bio->read_disk;
-			int success = 0;
-			mdk_rdev_t *rdev;
+static int process_checks(r1bio_t *r1_bio)
+{
+	/* We have read all readable devices.  If we haven't
+	 * got the block, then there is no hope left.
+	 * If we have, then we want to do a comparison
+	 * and skip the write if everything is the same.
+	 * If any blocks failed to read, then we need to
+	 * attempt an over-write
+	 */
+	mddev_t *mddev = r1_bio->mddev;
+	conf_t *conf = mddev->private;
+	int primary;
+	int i;
 
-			if (s > (PAGE_SIZE>>9))
-				s = PAGE_SIZE >> 9;
-			do {
-				if (r1_bio->bios[d]->bi_end_io == end_sync_read) {
-					/* No rcu protection needed here devices
-					 * can only be removed when no resync is
-					 * active, and resync is currently active
-					 */
-					rdev = conf->mirrors[d].rdev;
-					if (sync_page_io(rdev,
-							 sect,
-							 s<<9,
-							 bio->bi_io_vec[idx].bv_page,
-							 READ, false)) {
-						success = 1;
-						break;
-					}
-				}
-				d++;
-				if (d == conf->raid_disks)
-					d = 0;
-			} while (!success && d != r1_bio->read_disk);
+	for (primary = 0; primary < conf->raid_disks; primary++)
+		if (r1_bio->bios[primary]->bi_end_io == end_sync_read &&
+		    test_bit(BIO_UPTODATE, &r1_bio->bios[primary]->bi_flags)) {
+			r1_bio->bios[primary]->bi_end_io = NULL;
+			rdev_dec_pending(conf->mirrors[primary].rdev, mddev);
+			break;
+		}
+	r1_bio->read_disk = primary;
+	for (i = 0; i < conf->raid_disks; i++) {
+		int j;
+		int vcnt = r1_bio->sectors >> (PAGE_SHIFT- 9);
+		struct bio *pbio = r1_bio->bios[primary];
+		struct bio *sbio = r1_bio->bios[i];
+		int size;
 
-			if (success) {
-				int start = d;
-				/* write it back and re-read */
-				set_bit(R1BIO_Uptodate, &r1_bio->state);
-				while (d != r1_bio->read_disk) {
-					if (d == 0)
-						d = conf->raid_disks;
-					d--;
-					if (r1_bio->bios[d]->bi_end_io != end_sync_read)
-						continue;
-					rdev = conf->mirrors[d].rdev;
-					atomic_add(s, &rdev->corrected_errors);
-					if (sync_page_io(rdev,
-							 sect,
-							 s<<9,
-							 bio->bi_io_vec[idx].bv_page,
-							 WRITE, false) == 0)
-						md_error(mddev, rdev);
-				}
-				d = start;
-				while (d != r1_bio->read_disk) {
-					if (d == 0)
-						d = conf->raid_disks;
-					d--;
-					if (r1_bio->bios[d]->bi_end_io != end_sync_read)
-						continue;
-					rdev = conf->mirrors[d].rdev;
-					if (sync_page_io(rdev,
-							 sect,
-							 s<<9,
-							 bio->bi_io_vec[idx].bv_page,
-							 READ, false) == 0)
-						md_error(mddev, rdev);
-				}
-			} else {
-				char b[BDEVNAME_SIZE];
-				/* Cannot read from anywhere, array is toast */
-				md_error(mddev, conf->mirrors[r1_bio->read_disk].rdev);
-				printk(KERN_ALERT "md/raid1:%s: %s: unrecoverable I/O read error"
-				       " for block %llu\n",
-				       mdname(mddev),
-				       bdevname(bio->bi_bdev, b),
-				       (unsigned long long)r1_bio->sector);
-				md_done_sync(mddev, r1_bio->sectors, 0);
-				put_buf(r1_bio);
-				return;
+		if (r1_bio->bios[i]->bi_end_io != end_sync_read)
+			continue;
+
+		if (test_bit(BIO_UPTODATE, &sbio->bi_flags)) {
+			for (j = vcnt; j-- ; ) {
+				struct page *p, *s;
+				p = pbio->bi_io_vec[j].bv_page;
+				s = sbio->bi_io_vec[j].bv_page;
+				if (memcmp(page_address(p),
+					   page_address(s),
+					   PAGE_SIZE))
+					break;
 			}
-			sectors -= s;
-			sect += s;
-			idx ++;
+		} else
+			j = 0;
+		if (j >= 0)
+			mddev->resync_mismatches += r1_bio->sectors;
+		if (j < 0 || (test_bit(MD_RECOVERY_CHECK, &mddev->recovery)
+			      && test_bit(BIO_UPTODATE, &sbio->bi_flags))) {
+			/* No need to write to this device. */
+			sbio->bi_end_io = NULL;
+			rdev_dec_pending(conf->mirrors[i].rdev, mddev);
+			continue;
+		}
+		/* fixup the bio for reuse */
+		sbio->bi_vcnt = vcnt;
+		sbio->bi_size = r1_bio->sectors << 9;
+		sbio->bi_idx = 0;
+		sbio->bi_phys_segments = 0;
+		sbio->bi_flags &= ~(BIO_POOL_MASK - 1);
+		sbio->bi_flags |= 1 << BIO_UPTODATE;
+		sbio->bi_next = NULL;
+		sbio->bi_sector = r1_bio->sector +
+			conf->mirrors[i].rdev->data_offset;
+		sbio->bi_bdev = conf->mirrors[i].rdev->bdev;
+		size = sbio->bi_size;
+		for (j = 0; j < vcnt ; j++) {
+			struct bio_vec *bi;
+			bi = &sbio->bi_io_vec[j];
+			bi->bv_offset = 0;
+			if (size > PAGE_SIZE)
+				bi->bv_len = PAGE_SIZE;
+			else
+				bi->bv_len = size;
+			size -= PAGE_SIZE;
+			memcpy(page_address(bi->bv_page),
+			       page_address(pbio->bi_io_vec[j].bv_page),
+			       PAGE_SIZE);
 		}
 	}
+	return 0;
+}
+
+static void sync_request_write(mddev_t *mddev, r1bio_t *r1_bio)
+{
+	conf_t *conf = mddev->private;
+	int i;
+	int disks = conf->raid_disks;
+	struct bio *bio, *wbio;
+
+	bio = r1_bio->bios[r1_bio->read_disk];
+
+	if (!test_bit(R1BIO_Uptodate, &r1_bio->state))
+		/* ouch - failed to read all of that. */
+		if (!fix_sync_read_error(r1_bio))
+			return;
 
+	if (test_bit(MD_RECOVERY_REQUESTED, &mddev->recovery))
+		if (process_checks(r1_bio) < 0)
+			return;
 	/*
 	 * schedule writes
 	 */
@@ -1974,6 +1978,8 @@
 		return PTR_ERR(conf);
 
 	list_for_each_entry(rdev, &mddev->disks, same_set) {
+		if (!mddev->gendisk)
+			continue;
 		disk_stack_limits(mddev->gendisk, rdev->bdev,
 				  rdev->data_offset << 9);
 		/* as we don't honour merge_bvec_fn, we must never risk
@@ -2015,8 +2021,10 @@
 
 	md_set_array_sectors(mddev, raid1_size(mddev, 0, 0));
 
-	mddev->queue->backing_dev_info.congested_fn = raid1_congested;
-	mddev->queue->backing_dev_info.congested_data = mddev;
+	if (mddev->queue) {
+		mddev->queue->backing_dev_info.congested_fn = raid1_congested;
+		mddev->queue->backing_dev_info.congested_data = mddev;
+	}
 	return md_integrity_register(mddev);
 }
 
@@ -2063,7 +2071,7 @@
 	set_capacity(mddev->gendisk, mddev->array_sectors);
 	revalidate_disk(mddev->gendisk);
 	if (sectors > mddev->dev_sectors &&
-	    mddev->recovery_cp == MaxSector) {
+	    mddev->recovery_cp > mddev->dev_sectors) {
 		mddev->recovery_cp = mddev->dev_sectors;
 		set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
 	}
diff -druN linux-2.6.39-libre/drivers/md/raid1.h linux-3.0-rc7-libre/drivers/md/raid1.h
--- linux-2.6.39-libre/drivers/md/raid1.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/md/raid1.h	2011-07-11 19:51:52.000000000 -0400
@@ -94,7 +94,9 @@
 	int			read_disk;
 
 	struct list_head	retry_list;
-	struct bitmap_update	*bitmap_update;
+	/* Next two are only valid when R1BIO_BehindIO is set */
+	struct page		**behind_pages;
+	int			behind_page_count;
 	/*
 	 * if the IO is in WRITE direction, then multiple bios are used.
 	 * We choose the number when they are allocated.
@@ -124,4 +126,6 @@
  */
 #define	R1BIO_Returned 6
 
+extern int md_raid1_congested(mddev_t *mddev, int bits);
+
 #endif
diff -druN linux-2.6.39-libre/drivers/md/raid5.c linux-3.0-rc7-libre/drivers/md/raid5.c
--- linux-2.6.39-libre/drivers/md/raid5.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/md/raid5.c	2011-07-11 19:51:52.000000000 -0400
@@ -129,7 +129,7 @@
 
 static inline void raid5_set_bi_hw_segments(struct bio *bio, unsigned int cnt)
 {
-	bio->bi_phys_segments = raid5_bi_phys_segments(bio) || (cnt << 16);
+	bio->bi_phys_segments = raid5_bi_phys_segments(bio) | (cnt << 16);
 }
 
 /* Find first data disk in a raid6 stripe */
@@ -514,7 +514,7 @@
 		bi = &sh->dev[i].req;
 
 		bi->bi_rw = rw;
-		if (rw == WRITE)
+		if (rw & WRITE)
 			bi->bi_end_io = raid5_end_write_request;
 		else
 			bi->bi_end_io = raid5_end_read_request;
@@ -548,13 +548,13 @@
 			bi->bi_io_vec[0].bv_offset = 0;
 			bi->bi_size = STRIPE_SIZE;
 			bi->bi_next = NULL;
-			if (rw == WRITE &&
+			if ((rw & WRITE) &&
 			    test_bit(R5_ReWrite, &sh->dev[i].flags))
 				atomic_add(STRIPE_SECTORS,
 					&rdev->corrected_errors);
 			generic_make_request(bi);
 		} else {
-			if (rw == WRITE)
+			if (rw & WRITE)
 				set_bit(STRIPE_DEGRADED, &sh->state);
 			pr_debug("skip op %ld on disc %d for sector %llu\n",
 				bi->bi_rw, i, (unsigned long long)sh->sector);
@@ -585,7 +585,7 @@
 	init_async_submit(&submit, flags, tx, NULL, NULL, NULL);
 
 	bio_for_each_segment(bvl, bio, i) {
-		int len = bio_iovec_idx(bio, i)->bv_len;
+		int len = bvl->bv_len;
 		int clen;
 		int b_offset = 0;
 
@@ -601,8 +601,8 @@
 			clen = len;
 
 		if (clen > 0) {
-			b_offset += bio_iovec_idx(bio, i)->bv_offset;
-			bio_page = bio_iovec_idx(bio, i)->bv_page;
+			b_offset += bvl->bv_offset;
+			bio_page = bvl->bv_page;
 			if (frombio)
 				tx = async_memcpy(page, bio_page, page_offset,
 						  b_offset, clen, &submit);
@@ -1700,27 +1700,25 @@
 	raid5_conf_t *conf = mddev->private;
 	pr_debug("raid456: error called\n");
 
-	if (!test_bit(Faulty, &rdev->flags)) {
-		set_bit(MD_CHANGE_DEVS, &mddev->flags);
-		if (test_and_clear_bit(In_sync, &rdev->flags)) {
-			unsigned long flags;
-			spin_lock_irqsave(&conf->device_lock, flags);
-			mddev->degraded++;
-			spin_unlock_irqrestore(&conf->device_lock, flags);
-			/*
-			 * if recovery was running, make sure it aborts.
-			 */
-			set_bit(MD_RECOVERY_INTR, &mddev->recovery);
-		}
-		set_bit(Faulty, &rdev->flags);
-		printk(KERN_ALERT
-		       "md/raid:%s: Disk failure on %s, disabling device.\n"
-		       "md/raid:%s: Operation continuing on %d devices.\n",
-		       mdname(mddev),
-		       bdevname(rdev->bdev, b),
-		       mdname(mddev),
-		       conf->raid_disks - mddev->degraded);
+	if (test_and_clear_bit(In_sync, &rdev->flags)) {
+		unsigned long flags;
+		spin_lock_irqsave(&conf->device_lock, flags);
+		mddev->degraded++;
+		spin_unlock_irqrestore(&conf->device_lock, flags);
+		/*
+		 * if recovery was running, make sure it aborts.
+		 */
+		set_bit(MD_RECOVERY_INTR, &mddev->recovery);
 	}
+	set_bit(Faulty, &rdev->flags);
+	set_bit(MD_CHANGE_DEVS, &mddev->flags);
+	printk(KERN_ALERT
+	       "md/raid:%s: Disk failure on %s, disabling device.\n"
+	       "md/raid:%s: Operation continuing on %d devices.\n",
+	       mdname(mddev),
+	       bdevname(rdev->bdev, b),
+	       mdname(mddev),
+	       conf->raid_disks - mddev->degraded);
 }
 
 /*
@@ -3960,7 +3958,7 @@
 			/* spinlock is needed as reshape_progress may be
 			 * 64bit on a 32bit platform, and so it might be
 			 * possible to see a half-updated value
-			 * Ofcourse reshape_progress could change after
+			 * Of course reshape_progress could change after
 			 * the lock is dropped, so once we get a reference
 			 * to the stripe that we think it is, we will have
 			 * to check again.
@@ -4860,7 +4858,7 @@
 			printk(KERN_INFO "md/raid:%s: device %s operational as raid"
 			       " disk %d\n",
 			       mdname(mddev), bdevname(rdev->bdev, b), raid_disk);
-		} else
+		} else if (rdev->saved_raid_disk != raid_disk)
 			/* Cannot rely on bitmap to complete recovery */
 			conf->fullsync = 1;
 	}
@@ -5391,7 +5389,8 @@
 		return -EINVAL;
 	set_capacity(mddev->gendisk, mddev->array_sectors);
 	revalidate_disk(mddev->gendisk);
-	if (sectors > mddev->dev_sectors && mddev->recovery_cp == MaxSector) {
+	if (sectors > mddev->dev_sectors &&
+	    mddev->recovery_cp > mddev->dev_sectors) {
 		mddev->recovery_cp = mddev->dev_sectors;
 		set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
 	}
diff -druN linux-2.6.39-libre/drivers/media/common/saa7146_core.c linux-3.0-rc7-libre/drivers/media/common/saa7146_core.c
--- linux-2.6.39-libre/drivers/media/common/saa7146_core.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/common/saa7146_core.c	2011-07-11 19:51:52.000000000 -0400
@@ -378,12 +378,7 @@
 	dev->pci = pci;
 
 	/* get chip-revision; this is needed to enable bug-fixes */
-	err = pci_read_config_dword(pci, PCI_CLASS_REVISION, &dev->revision);
-	if (err < 0) {
-		ERR(("pci_read_config_dword() failed.\n"));
-		goto err_disable;
-	}
-	dev->revision &= 0xf;
+	dev->revision = pci->revision;
 
 	/* remap the memory from virtual to physical address */
 
diff -druN linux-2.6.39-libre/drivers/media/common/tuners/Kconfig linux-3.0-rc7-libre/drivers/media/common/tuners/Kconfig
--- linux-2.6.39-libre/drivers/media/common/tuners/Kconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/common/tuners/Kconfig	2011-07-11 19:51:52.000000000 -0400
@@ -186,4 +186,12 @@
 	default m if MEDIA_TUNER_CUSTOMISE
 	help
 	  NXP TDA18218 silicon tuner driver.
+
+config MEDIA_TUNER_TDA18212
+	tristate "NXP TDA18212 silicon tuner"
+	depends on VIDEO_MEDIA && I2C
+	default m if MEDIA_TUNER_CUSTOMISE
+	help
+	  NXP TDA18212 silicon tuner driver.
+
 endmenu
diff -druN linux-2.6.39-libre/drivers/media/common/tuners/Makefile linux-3.0-rc7-libre/drivers/media/common/tuners/Makefile
--- linux-2.6.39-libre/drivers/media/common/tuners/Makefile	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/common/tuners/Makefile	2011-07-11 19:51:52.000000000 -0400
@@ -25,6 +25,7 @@
 obj-$(CONFIG_MEDIA_TUNER_MC44S803) += mc44s803.o
 obj-$(CONFIG_MEDIA_TUNER_MAX2165) += max2165.o
 obj-$(CONFIG_MEDIA_TUNER_TDA18218) += tda18218.o
+obj-$(CONFIG_MEDIA_TUNER_TDA18212) += tda18212.o
 
 EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core
 EXTRA_CFLAGS += -Idrivers/media/dvb/frontends
diff -druN linux-2.6.39-libre/drivers/media/common/tuners/mxl5005s.c linux-3.0-rc7-libre/drivers/media/common/tuners/mxl5005s.c
--- linux-2.6.39-libre/drivers/media/common/tuners/mxl5005s.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/common/tuners/mxl5005s.c	2011-07-11 19:51:52.000000000 -0400
@@ -4024,6 +4024,8 @@
 			case BANDWIDTH_8_MHZ:
 				req_bw  = MXL5005S_BANDWIDTH_8MHZ;
 				break;
+			default:
+				return -EINVAL;
 			}
 		}
 
diff -druN linux-2.6.39-libre/drivers/media/common/tuners/tda18212.c linux-3.0-rc7-libre/drivers/media/common/tuners/tda18212.c
--- linux-2.6.39-libre/drivers/media/common/tuners/tda18212.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/media/common/tuners/tda18212.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,265 @@
+/*
+ * NXP TDA18212HN silicon tuner driver
+ *
+ * Copyright (C) 2011 Antti Palosaari <crope@iki.fi>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License along
+ *    with this program; if not, write to the Free Software Foundation, Inc.,
+ *    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include "tda18212_priv.h"
+
+static int debug;
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "Turn on/off debugging (default:off).");
+
+/* write multiple registers */
+static int tda18212_wr_regs(struct tda18212_priv *priv, u8 reg, u8 *val,
+	int len)
+{
+	int ret;
+	u8 buf[len+1];
+	struct i2c_msg msg[1] = {
+		{
+			.addr = priv->cfg->i2c_address,
+			.flags = 0,
+			.len = sizeof(buf),
+			.buf = buf,
+		}
+	};
+
+	buf[0] = reg;
+	memcpy(&buf[1], val, len);
+
+	ret = i2c_transfer(priv->i2c, msg, 1);
+	if (ret == 1) {
+		ret = 0;
+	} else {
+		warn("i2c wr failed ret:%d reg:%02x len:%d", ret, reg, len);
+		ret = -EREMOTEIO;
+	}
+	return ret;
+}
+
+/* read multiple registers */
+static int tda18212_rd_regs(struct tda18212_priv *priv, u8 reg, u8 *val,
+	int len)
+{
+	int ret;
+	u8 buf[len];
+	struct i2c_msg msg[2] = {
+		{
+			.addr = priv->cfg->i2c_address,
+			.flags = 0,
+			.len = 1,
+			.buf = &reg,
+		}, {
+			.addr = priv->cfg->i2c_address,
+			.flags = I2C_M_RD,
+			.len = sizeof(buf),
+			.buf = buf,
+		}
+	};
+
+	ret = i2c_transfer(priv->i2c, msg, 2);
+	if (ret == 2) {
+		memcpy(val, buf, len);
+		ret = 0;
+	} else {
+		warn("i2c rd failed ret:%d reg:%02x len:%d", ret, reg, len);
+		ret = -EREMOTEIO;
+	}
+
+	return ret;
+}
+
+/* write single register */
+static int tda18212_wr_reg(struct tda18212_priv *priv, u8 reg, u8 val)
+{
+	return tda18212_wr_regs(priv, reg, &val, 1);
+}
+
+/* read single register */
+static int tda18212_rd_reg(struct tda18212_priv *priv, u8 reg, u8 *val)
+{
+	return tda18212_rd_regs(priv, reg, val, 1);
+}
+
+#if 0 /* keep, useful when developing driver */
+static void tda18212_dump_regs(struct tda18212_priv *priv)
+{
+	int i;
+	u8 buf[256];
+
+	#define TDA18212_RD_LEN 32
+	for (i = 0; i < sizeof(buf); i += TDA18212_RD_LEN)
+		tda18212_rd_regs(priv, i, &buf[i], TDA18212_RD_LEN);
+
+	print_hex_dump(KERN_INFO, "", DUMP_PREFIX_OFFSET, 32, 1, buf,
+		sizeof(buf), true);
+
+	return;
+}
+#endif
+
+static int tda18212_set_params(struct dvb_frontend *fe,
+	struct dvb_frontend_parameters *p)
+{
+	struct tda18212_priv *priv = fe->tuner_priv;
+	struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+	int ret, i;
+	u32 if_khz;
+	u8 buf[9];
+	static const u8 bw_params[][3] = {
+		/*  0f    13    23 */
+		{ 0xb3, 0x20, 0x03 }, /* DVB-T 6 MHz */
+		{ 0xb3, 0x31, 0x01 }, /* DVB-T 7 MHz */
+		{ 0xb3, 0x22, 0x01 }, /* DVB-T 8 MHz */
+		{ 0x92, 0x53, 0x03 }, /* DVB-C */
+	};
+
+	dbg("%s: delsys=%d RF=%d BW=%d", __func__,
+		c->delivery_system, c->frequency, c->bandwidth_hz);
+
+	if (fe->ops.i2c_gate_ctrl)
+		fe->ops.i2c_gate_ctrl(fe, 1); /* open I2C-gate */
+
+	switch (c->delivery_system) {
+	case SYS_DVBT:
+		switch (c->bandwidth_hz) {
+		case 6000000:
+			if_khz = priv->cfg->if_dvbt_6;
+			i = 0;
+			break;
+		case 7000000:
+			if_khz = priv->cfg->if_dvbt_7;
+			i = 1;
+			break;
+		case 8000000:
+			if_khz = priv->cfg->if_dvbt_8;
+			i = 2;
+			break;
+		default:
+			ret = -EINVAL;
+			goto error;
+		}
+		break;
+	case SYS_DVBC_ANNEX_AC:
+		if_khz = priv->cfg->if_dvbc;
+		i = 3;
+		break;
+	default:
+		ret = -EINVAL;
+		goto error;
+	}
+
+	ret = tda18212_wr_reg(priv, 0x23, bw_params[i][2]);
+	if (ret)
+		goto error;
+
+	ret = tda18212_wr_reg(priv, 0x06, 0x00);
+	if (ret)
+		goto error;
+
+	ret = tda18212_wr_reg(priv, 0x0f, bw_params[i][0]);
+	if (ret)
+		goto error;
+
+	buf[0] = 0x02;
+	buf[1] = bw_params[i][1];
+	buf[2] = 0x03; /* default value */
+	buf[3] = if_khz / 50;
+	buf[4] = ((c->frequency / 1000) >> 16) & 0xff;
+	buf[5] = ((c->frequency / 1000) >>  8) & 0xff;
+	buf[6] = ((c->frequency / 1000) >>  0) & 0xff;
+	buf[7] = 0xc1;
+	buf[8] = 0x01;
+	ret = tda18212_wr_regs(priv, 0x12, buf, sizeof(buf));
+	if (ret)
+		goto error;
+
+exit:
+	if (fe->ops.i2c_gate_ctrl)
+		fe->ops.i2c_gate_ctrl(fe, 0); /* close I2C-gate */
+
+	return ret;
+
+error:
+	dbg("%s: failed:%d", __func__, ret);
+	goto exit;
+}
+
+static int tda18212_release(struct dvb_frontend *fe)
+{
+	kfree(fe->tuner_priv);
+	fe->tuner_priv = NULL;
+	return 0;
+}
+
+static const struct dvb_tuner_ops tda18212_tuner_ops = {
+	.info = {
+		.name           = "NXP TDA18212",
+
+		.frequency_min  =  48000000,
+		.frequency_max  = 864000000,
+		.frequency_step =      1000,
+	},
+
+	.release       = tda18212_release,
+
+	.set_params    = tda18212_set_params,
+};
+
+struct dvb_frontend *tda18212_attach(struct dvb_frontend *fe,
+	struct i2c_adapter *i2c, struct tda18212_config *cfg)
+{
+	struct tda18212_priv *priv = NULL;
+	int ret;
+	u8 val;
+
+	priv = kzalloc(sizeof(struct tda18212_priv), GFP_KERNEL);
+	if (priv == NULL)
+		return NULL;
+
+	priv->cfg = cfg;
+	priv->i2c = i2c;
+	fe->tuner_priv = priv;
+
+	if (fe->ops.i2c_gate_ctrl)
+		fe->ops.i2c_gate_ctrl(fe, 1); /* open I2C-gate */
+
+	/* check if the tuner is there */
+	ret = tda18212_rd_reg(priv, 0x00, &val);
+
+	if (fe->ops.i2c_gate_ctrl)
+		fe->ops.i2c_gate_ctrl(fe, 0); /* close I2C-gate */
+
+	dbg("%s: ret:%d chip ID:%02x", __func__, ret, val);
+	if (ret || val != 0xc7) {
+		kfree(priv);
+		return NULL;
+	}
+
+	info("NXP TDA18212HN successfully identified.");
+
+	memcpy(&fe->ops.tuner_ops, &tda18212_tuner_ops,
+		sizeof(struct dvb_tuner_ops));
+
+	return fe;
+}
+EXPORT_SYMBOL(tda18212_attach);
+
+MODULE_DESCRIPTION("NXP TDA18212HN silicon tuner driver");
+MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
+MODULE_LICENSE("GPL");
diff -druN linux-2.6.39-libre/drivers/media/common/tuners/tda18212.h linux-3.0-rc7-libre/drivers/media/common/tuners/tda18212.h
--- linux-2.6.39-libre/drivers/media/common/tuners/tda18212.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/media/common/tuners/tda18212.h	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,48 @@
+/*
+ * NXP TDA18212HN silicon tuner driver
+ *
+ * Copyright (C) 2011 Antti Palosaari <crope@iki.fi>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License along
+ *    with this program; if not, write to the Free Software Foundation, Inc.,
+ *    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef TDA18212_H
+#define TDA18212_H
+
+#include "dvb_frontend.h"
+
+struct tda18212_config {
+	u8 i2c_address;
+
+	u16 if_dvbt_6;
+	u16 if_dvbt_7;
+	u16 if_dvbt_8;
+	u16 if_dvbc;
+};
+
+#if defined(CONFIG_MEDIA_TUNER_TDA18212) || \
+	(defined(CONFIG_MEDIA_TUNER_TDA18212_MODULE) && defined(MODULE))
+extern struct dvb_frontend *tda18212_attach(struct dvb_frontend *fe,
+	struct i2c_adapter *i2c, struct tda18212_config *cfg);
+#else
+static inline struct dvb_frontend *tda18212_attach(struct dvb_frontend *fe,
+	struct i2c_adapter *i2c, struct tda18212_config *cfg)
+{
+	printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+	return NULL;
+}
+#endif
+
+#endif
diff -druN linux-2.6.39-libre/drivers/media/common/tuners/tda18212_priv.h linux-3.0-rc7-libre/drivers/media/common/tuners/tda18212_priv.h
--- linux-2.6.39-libre/drivers/media/common/tuners/tda18212_priv.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/media/common/tuners/tda18212_priv.h	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,44 @@
+/*
+ * NXP TDA18212HN silicon tuner driver
+ *
+ * Copyright (C) 2011 Antti Palosaari <crope@iki.fi>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License along
+ *    with this program; if not, write to the Free Software Foundation, Inc.,
+ *    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef TDA18212_PRIV_H
+#define TDA18212_PRIV_H
+
+#include "tda18212.h"
+
+#define LOG_PREFIX "tda18212"
+
+#undef dbg
+#define dbg(f, arg...) \
+	if (debug) \
+		printk(KERN_INFO   LOG_PREFIX": " f "\n" , ## arg)
+#undef err
+#define err(f, arg...)  printk(KERN_ERR     LOG_PREFIX": " f "\n" , ## arg)
+#undef info
+#define info(f, arg...) printk(KERN_INFO    LOG_PREFIX": " f "\n" , ## arg)
+#undef warn
+#define warn(f, arg...) printk(KERN_WARNING LOG_PREFIX": " f "\n" , ## arg)
+
+struct tda18212_priv {
+	struct tda18212_config *cfg;
+	struct i2c_adapter *i2c;
+};
+
+#endif
diff -druN linux-2.6.39-libre/drivers/media/common/tuners/tda18271-fe.c linux-3.0-rc7-libre/drivers/media/common/tuners/tda18271-fe.c
--- linux-2.6.39-libre/drivers/media/common/tuners/tda18271-fe.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/common/tuners/tda18271-fe.c	2011-07-11 19:51:52.000000000 -0400
@@ -976,6 +976,10 @@
 			tda_warn("bandwidth not set!\n");
 			return -EINVAL;
 		}
+	} else if (fe->ops.info.type == FE_QAM) {
+		/* DVB-C */
+		map = &std_map->qam_8;
+		bw = 8000000;
 	} else {
 		tda_warn("modulation type not supported!\n");
 		return -EINVAL;
diff -druN linux-2.6.39-libre/drivers/media/common/tuners/xc5000.c linux-3.0-rc7-libre/drivers/media/common/tuners/xc5000.c
--- linux-2.6.39-libre/drivers/media/common/tuners/xc5000.c	2011-05-19 02:08:18.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/common/tuners/xc5000.c	2011-07-21 06:50:36.000000000 -0400
@@ -628,6 +628,15 @@
 	dprintk(1, "*** Quality (0:<8dB, 7:>56dB) = %d\n", quality);
 }
 
+/*
+ * As defined on EN 300 429, the DVB-C roll-off factor is 0.15.
+ * So, the amount of the needed bandwith is given by:
+ * 	Bw = Symbol_rate * (1 + 0.15)
+ * As such, the maximum symbol rate supported by 6 MHz is given by:
+ *	max_symbol_rate = 6 MHz / 1.15 = 5217391 Bauds
+ */
+#define MAX_SYMBOL_RATE_6MHz	5217391
+
 static int xc5000_set_params(struct dvb_frontend *fe,
 	struct dvb_frontend_parameters *params)
 {
@@ -688,21 +697,32 @@
 		}
 		priv->rf_mode = XC_RF_MODE_AIR;
 	} else if (fe->ops.info.type == FE_QAM) {
-		dprintk(1, "%s() QAM\n", __func__);
 		switch (params->u.qam.modulation) {
+		case QAM_256:
+		case QAM_AUTO:
 		case QAM_16:
 		case QAM_32:
 		case QAM_64:
 		case QAM_128:
-		case QAM_256:
-		case QAM_AUTO:
 			dprintk(1, "%s() QAM modulation\n", __func__);
-			priv->bandwidth = BANDWIDTH_8_MHZ;
-			priv->video_standard = DTV7_8;
-			priv->freq_hz = params->frequency - 2750000;
 			priv->rf_mode = XC_RF_MODE_CABLE;
+			/*
+			 * Using a 8MHz bandwidth sometimes fail
+			 * with 6MHz-spaced channels, due to inter-carrier
+			 * interference. So, use DTV6 firmware
+			 */
+			if (params->u.qam.symbol_rate <= MAX_SYMBOL_RATE_6MHz) {
+				priv->bandwidth = BANDWIDTH_6_MHZ;
+				priv->video_standard = DTV6;
+				priv->freq_hz = params->frequency - 1750000;
+			} else {
+				priv->bandwidth = BANDWIDTH_8_MHZ;
+				priv->video_standard = DTV7_8;
+				priv->freq_hz = params->frequency - 2750000;
+			}
 			break;
 		default:
+			dprintk(1, "%s() Unsupported QAM type\n", __func__);
 			return -EINVAL;
 		}
 	} else {
diff -druN linux-2.6.39-libre/drivers/media/dvb/b2c2/flexcop-pci.c linux-3.0-rc7-libre/drivers/media/dvb/b2c2/flexcop-pci.c
--- linux-2.6.39-libre/drivers/media/dvb/b2c2/flexcop-pci.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/dvb/b2c2/flexcop-pci.c	2011-07-11 19:51:52.000000000 -0400
@@ -290,10 +290,8 @@
 static int flexcop_pci_init(struct flexcop_pci *fc_pci)
 {
 	int ret;
-	u8 card_rev;
 
-	pci_read_config_byte(fc_pci->pdev, PCI_CLASS_REVISION, &card_rev);
-	info("card revision %x", card_rev);
+	info("card revision %x", fc_pci->pdev->revision);
 
 	if ((ret = pci_enable_device(fc_pci->pdev)) != 0)
 		return ret;
diff -druN linux-2.6.39-libre/drivers/media/dvb/bt8xx/bt878.c linux-3.0-rc7-libre/drivers/media/dvb/bt8xx/bt878.c
--- linux-2.6.39-libre/drivers/media/dvb/bt8xx/bt878.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/dvb/bt8xx/bt878.c	2011-07-11 19:51:52.000000000 -0400
@@ -460,7 +460,7 @@
 		goto fail0;
 	}
 
-	pci_read_config_byte(dev, PCI_CLASS_REVISION, &bt->revision);
+	bt->revision = dev->revision;
 	pci_read_config_byte(dev, PCI_LATENCY_TIMER, &lat);
 
 
diff -druN linux-2.6.39-libre/drivers/media/dvb/dm1105/dm1105.c linux-3.0-rc7-libre/drivers/media/dvb/dm1105/dm1105.c
--- linux-2.6.39-libre/drivers/media/dvb/dm1105/dm1105.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/dvb/dm1105/dm1105.c	2011-07-11 19:51:52.000000000 -0400
@@ -20,6 +20,7 @@
  */
 
 #include <linux/i2c.h>
+#include <linux/i2c-algo-bit.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
@@ -49,11 +50,12 @@
 
 #define UNSET (-1U)
 
-#define DM1105_BOARD_NOAUTO		UNSET
-#define DM1105_BOARD_UNKNOWN		0
-#define DM1105_BOARD_DVBWORLD_2002	1
-#define DM1105_BOARD_DVBWORLD_2004	2
-#define DM1105_BOARD_AXESS_DM05		3
+#define DM1105_BOARD_NOAUTO			UNSET
+#define DM1105_BOARD_UNKNOWN			0
+#define DM1105_BOARD_DVBWORLD_2002		1
+#define DM1105_BOARD_DVBWORLD_2004		2
+#define DM1105_BOARD_AXESS_DM05			3
+#define DM1105_BOARD_UNBRANDED_I2C_ON_GPIO	4
 
 /* ----------------------------------------------- */
 /*
@@ -157,22 +159,38 @@
 #define DM1105_MAX				0x04
 
 #define DRIVER_NAME				"dm1105"
+#define DM1105_I2C_GPIO_NAME			"dm1105-gpio"
 
 #define DM1105_DMA_PACKETS			47
 #define DM1105_DMA_PACKET_LENGTH		(128*4)
 #define DM1105_DMA_BYTES			(128 * 4 * DM1105_DMA_PACKETS)
 
+/*  */
+#define GPIO08					(1 << 8)
+#define GPIO13					(1 << 13)
+#define GPIO14					(1 << 14)
+#define GPIO15					(1 << 15)
+#define GPIO16					(1 << 16)
+#define GPIO17					(1 << 17)
+#define GPIO_ALL				0x03ffff
+
 /* GPIO's for LNB power control */
-#define DM1105_LNB_MASK				0x00000000
-#define DM1105_LNB_OFF				0x00020000
-#define DM1105_LNB_13V				0x00010100
-#define DM1105_LNB_18V				0x00000100
+#define DM1105_LNB_MASK				(GPIO_ALL & ~(GPIO14 | GPIO13))
+#define DM1105_LNB_OFF				GPIO17
+#define DM1105_LNB_13V				(GPIO16 | GPIO08)
+#define DM1105_LNB_18V				GPIO08
 
 /* GPIO's for LNB power control for Axess DM05 */
-#define DM05_LNB_MASK				0x00000000
-#define DM05_LNB_OFF				0x00020000/* actually 13v */
-#define DM05_LNB_13V				0x00020000
-#define DM05_LNB_18V				0x00030000
+#define DM05_LNB_MASK				(GPIO_ALL & ~(GPIO14 | GPIO13))
+#define DM05_LNB_OFF				GPIO17/* actually 13v */
+#define DM05_LNB_13V				GPIO17
+#define DM05_LNB_18V				(GPIO17 | GPIO16)
+
+/* GPIO's for LNB power control for unbranded with I2C on GPIO */
+#define UNBR_LNB_MASK				(GPIO17 | GPIO16)
+#define UNBR_LNB_OFF				0
+#define UNBR_LNB_13V				GPIO17
+#define UNBR_LNB_18V				(GPIO17 | GPIO16)
 
 static unsigned int card[]  = {[0 ... 3] = UNSET };
 module_param_array(card,  int, NULL, 0444);
@@ -187,7 +205,11 @@
 DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
 
 struct dm1105_board {
-	char                    *name;
+	char	*name;
+	struct	{
+		u32	mask, off, v13, v18;
+	} lnb;
+	u32	gpio_scl, gpio_sda;
 };
 
 struct dm1105_subid {
@@ -199,15 +221,50 @@
 static const struct dm1105_board dm1105_boards[] = {
 	[DM1105_BOARD_UNKNOWN] = {
 		.name		= "UNKNOWN/GENERIC",
+		.lnb = {
+			.mask = DM1105_LNB_MASK,
+			.off = DM1105_LNB_OFF,
+			.v13 = DM1105_LNB_13V,
+			.v18 = DM1105_LNB_18V,
+		},
 	},
 	[DM1105_BOARD_DVBWORLD_2002] = {
 		.name		= "DVBWorld PCI 2002",
+		.lnb = {
+			.mask = DM1105_LNB_MASK,
+			.off = DM1105_LNB_OFF,
+			.v13 = DM1105_LNB_13V,
+			.v18 = DM1105_LNB_18V,
+		},
 	},
 	[DM1105_BOARD_DVBWORLD_2004] = {
 		.name		= "DVBWorld PCI 2004",
+		.lnb = {
+			.mask = DM1105_LNB_MASK,
+			.off = DM1105_LNB_OFF,
+			.v13 = DM1105_LNB_13V,
+			.v18 = DM1105_LNB_18V,
+		},
 	},
 	[DM1105_BOARD_AXESS_DM05] = {
 		.name		= "Axess/EasyTv DM05",
+		.lnb = {
+			.mask = DM05_LNB_MASK,
+			.off = DM05_LNB_OFF,
+			.v13 = DM05_LNB_13V,
+			.v18 = DM05_LNB_18V,
+		},
+	},
+	[DM1105_BOARD_UNBRANDED_I2C_ON_GPIO] = {
+		.name		= "Unbranded DM1105 with i2c on GPIOs",
+		.lnb = {
+			.mask = UNBR_LNB_MASK,
+			.off = UNBR_LNB_OFF,
+			.v13 = UNBR_LNB_13V,
+			.v18 = UNBR_LNB_18V,
+		},
+		.gpio_scl	= GPIO14,
+		.gpio_sda	= GPIO13,
 	},
 };
 
@@ -293,6 +350,8 @@
 
 	/* i2c */
 	struct i2c_adapter i2c_adap;
+	struct i2c_adapter i2c_bb_adap;
+	struct i2c_algo_bit_data i2c_bit;
 
 	/* irq */
 	struct work_struct work;
@@ -328,6 +387,103 @@
 #define dm_setl(reg, bit)	dm_andorl((reg), (bit), (bit))
 #define dm_clearl(reg, bit)	dm_andorl((reg), (bit), 0)
 
+/* The chip has 18 GPIOs. In HOST mode GPIO's used as 15 bit address lines,
+ so we can use only 3 GPIO's from GPIO15 to GPIO17.
+ Here I don't check whether HOST is enebled as it is not implemented yet.
+ */
+static void dm1105_gpio_set(struct dm1105_dev *dev, u32 mask)
+{
+	if (mask & 0xfffc0000)
+		printk(KERN_ERR "%s: Only 18 GPIO's are allowed\n", __func__);
+
+	if (mask & 0x0003ffff)
+		dm_setl(DM1105_GPIOVAL, mask & 0x0003ffff);
+
+}
+
+static void dm1105_gpio_clear(struct dm1105_dev *dev, u32 mask)
+{
+	if (mask & 0xfffc0000)
+		printk(KERN_ERR "%s: Only 18 GPIO's are allowed\n", __func__);
+
+	if (mask & 0x0003ffff)
+		dm_clearl(DM1105_GPIOVAL, mask & 0x0003ffff);
+
+}
+
+static void dm1105_gpio_andor(struct dm1105_dev *dev, u32 mask, u32 val)
+{
+	if (mask & 0xfffc0000)
+		printk(KERN_ERR "%s: Only 18 GPIO's are allowed\n", __func__);
+
+	if (mask & 0x0003ffff)
+		dm_andorl(DM1105_GPIOVAL, mask & 0x0003ffff, val);
+
+}
+
+static u32 dm1105_gpio_get(struct dm1105_dev *dev, u32 mask)
+{
+	if (mask & 0xfffc0000)
+		printk(KERN_ERR "%s: Only 18 GPIO's are allowed\n", __func__);
+
+	if (mask & 0x0003ffff)
+		return dm_readl(DM1105_GPIOVAL) & mask & 0x0003ffff;
+
+	return 0;
+}
+
+static void dm1105_gpio_enable(struct dm1105_dev *dev, u32 mask, int asoutput)
+{
+	if (mask & 0xfffc0000)
+		printk(KERN_ERR "%s: Only 18 GPIO's are allowed\n", __func__);
+
+	if ((mask & 0x0003ffff) && asoutput)
+		dm_clearl(DM1105_GPIOCTR, mask & 0x0003ffff);
+	else if ((mask & 0x0003ffff) && !asoutput)
+		dm_setl(DM1105_GPIOCTR, mask & 0x0003ffff);
+
+}
+
+static void dm1105_setline(struct dm1105_dev *dev, u32 line, int state)
+{
+	if (state)
+		dm1105_gpio_enable(dev, line, 0);
+	else {
+		dm1105_gpio_enable(dev, line, 1);
+		dm1105_gpio_clear(dev, line);
+	}
+}
+
+static void dm1105_setsda(void *data, int state)
+{
+	struct dm1105_dev *dev = data;
+
+	dm1105_setline(dev, dm1105_boards[dev->boardnr].gpio_sda, state);
+}
+
+static void dm1105_setscl(void *data, int state)
+{
+	struct dm1105_dev *dev = data;
+
+	dm1105_setline(dev, dm1105_boards[dev->boardnr].gpio_scl, state);
+}
+
+static int dm1105_getsda(void *data)
+{
+	struct dm1105_dev *dev = data;
+
+	return dm1105_gpio_get(dev, dm1105_boards[dev->boardnr].gpio_sda)
+									? 1 : 0;
+}
+
+static int dm1105_getscl(void *data)
+{
+	struct dm1105_dev *dev = data;
+
+	return dm1105_gpio_get(dev, dm1105_boards[dev->boardnr].gpio_scl)
+									? 1 : 0;
+}
+
 static int dm1105_i2c_xfer(struct i2c_adapter *i2c_adap,
 			    struct i2c_msg *msgs, int num)
 {
@@ -436,31 +592,20 @@
 static int dm1105_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
 {
 	struct dm1105_dev *dev = frontend_to_dm1105_dev(fe);
-	u32 lnb_mask, lnb_13v, lnb_18v, lnb_off;
-
-	switch (dev->boardnr) {
-	case DM1105_BOARD_AXESS_DM05:
-		lnb_mask = DM05_LNB_MASK;
-		lnb_off = DM05_LNB_OFF;
-		lnb_13v = DM05_LNB_13V;
-		lnb_18v = DM05_LNB_18V;
-		break;
-	case DM1105_BOARD_DVBWORLD_2002:
-	case DM1105_BOARD_DVBWORLD_2004:
-	default:
-		lnb_mask = DM1105_LNB_MASK;
-		lnb_off = DM1105_LNB_OFF;
-		lnb_13v = DM1105_LNB_13V;
-		lnb_18v = DM1105_LNB_18V;
-	}
 
-	dm_writel(DM1105_GPIOCTR, lnb_mask);
+	dm1105_gpio_enable(dev, dm1105_boards[dev->boardnr].lnb.mask, 1);
 	if (voltage == SEC_VOLTAGE_18)
-		dm_writel(DM1105_GPIOVAL, lnb_18v);
+		dm1105_gpio_andor(dev,
+				dm1105_boards[dev->boardnr].lnb.mask,
+				dm1105_boards[dev->boardnr].lnb.v18);
 	else if (voltage == SEC_VOLTAGE_13)
-		dm_writel(DM1105_GPIOVAL, lnb_13v);
+		dm1105_gpio_andor(dev,
+				dm1105_boards[dev->boardnr].lnb.mask,
+				dm1105_boards[dev->boardnr].lnb.v13);
 	else
-		dm_writel(DM1105_GPIOVAL, lnb_off);
+		dm1105_gpio_andor(dev,
+				dm1105_boards[dev->boardnr].lnb.mask,
+				dm1105_boards[dev->boardnr].lnb.off);
 
 	return 0;
 }
@@ -708,6 +853,38 @@
 	int ret;
 
 	switch (dev->boardnr) {
+	case DM1105_BOARD_UNBRANDED_I2C_ON_GPIO:
+		dm1105_gpio_enable(dev, GPIO15, 1);
+		dm1105_gpio_clear(dev, GPIO15);
+		msleep(100);
+		dm1105_gpio_set(dev, GPIO15);
+		msleep(200);
+		dev->fe = dvb_attach(
+			stv0299_attach, &sharp_z0194a_config,
+			&dev->i2c_bb_adap);
+		if (dev->fe) {
+			dev->fe->ops.set_voltage = dm1105_set_voltage;
+			dvb_attach(dvb_pll_attach, dev->fe, 0x60,
+					&dev->i2c_bb_adap, DVB_PLL_OPERA1);
+			break;
+		}
+
+		dev->fe = dvb_attach(
+			stv0288_attach, &earda_config,
+			&dev->i2c_bb_adap);
+		if (dev->fe) {
+			dev->fe->ops.set_voltage = dm1105_set_voltage;
+			dvb_attach(stb6000_attach, dev->fe, 0x61,
+					&dev->i2c_bb_adap);
+			break;
+		}
+
+		dev->fe = dvb_attach(
+			si21xx_attach, &serit_config,
+			&dev->i2c_bb_adap);
+		if (dev->fe)
+			dev->fe->ops.set_voltage = dm1105_set_voltage;
+		break;
 	case DM1105_BOARD_DVBWORLD_2004:
 		dev->fe = dvb_attach(
 			cx24116_attach, &serit_sp2633_config,
@@ -870,11 +1047,32 @@
 	if (ret < 0)
 		goto err_dm1105_hw_exit;
 
+	i2c_set_adapdata(&dev->i2c_bb_adap, dev);
+	strcpy(dev->i2c_bb_adap.name, DM1105_I2C_GPIO_NAME);
+	dev->i2c_bb_adap.owner = THIS_MODULE;
+	dev->i2c_bb_adap.dev.parent = &pdev->dev;
+	dev->i2c_bb_adap.algo_data = &dev->i2c_bit;
+	dev->i2c_bit.data = dev;
+	dev->i2c_bit.setsda = dm1105_setsda;
+	dev->i2c_bit.setscl = dm1105_setscl;
+	dev->i2c_bit.getsda = dm1105_getsda;
+	dev->i2c_bit.getscl = dm1105_getscl;
+	dev->i2c_bit.udelay = 10;
+	dev->i2c_bit.timeout = 10;
+
+	/* Raise SCL and SDA */
+	dm1105_setsda(dev, 1);
+	dm1105_setscl(dev, 1);
+
+	ret = i2c_bit_add_bus(&dev->i2c_bb_adap);
+	if (ret < 0)
+		goto err_i2c_del_adapter;
+
 	/* dvb */
 	ret = dvb_register_adapter(&dev->dvb_adapter, DRIVER_NAME,
 					THIS_MODULE, &pdev->dev, adapter_nr);
 	if (ret < 0)
-		goto err_i2c_del_adapter;
+		goto err_i2c_del_adapters;
 
 	dvb_adapter = &dev->dvb_adapter;
 
@@ -952,6 +1150,8 @@
 	dvb_dmx_release(dvbdemux);
 err_dvb_unregister_adapter:
 	dvb_unregister_adapter(dvb_adapter);
+err_i2c_del_adapters:
+	i2c_del_adapter(&dev->i2c_bb_adap);
 err_i2c_del_adapter:
 	i2c_del_adapter(&dev->i2c_adap);
 err_dm1105_hw_exit:
diff -druN linux-2.6.39-libre/drivers/media/dvb/dvb-core/dvb_demux.c linux-3.0-rc7-libre/drivers/media/dvb/dvb-core/dvb_demux.c
--- linux-2.6.39-libre/drivers/media/dvb/dvb-core/dvb_demux.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/dvb/dvb-core/dvb_demux.c	2011-07-11 19:51:52.000000000 -0400
@@ -478,97 +478,94 @@
 
 EXPORT_SYMBOL(dvb_dmx_swfilter_packets);
 
-void dvb_dmx_swfilter(struct dvb_demux *demux, const u8 *buf, size_t count)
+static inline int find_next_packet(const u8 *buf, int pos, size_t count,
+				   const int pktsize)
 {
-	int p = 0, i, j;
-
-	spin_lock(&demux->lock);
+	int start = pos, lost;
 
-	if (demux->tsbufp) {
-		i = demux->tsbufp;
-		j = 188 - i;
-		if (count < j) {
-			memcpy(&demux->tsbuf[i], buf, count);
-			demux->tsbufp += count;
-			goto bailout;
-		}
-		memcpy(&demux->tsbuf[i], buf, j);
-		if (demux->tsbuf[0] == 0x47)
-			dvb_dmx_swfilter_packet(demux, demux->tsbuf);
-		demux->tsbufp = 0;
-		p += j;
+	while (pos < count) {
+		if (buf[pos] == 0x47 ||
+		    (pktsize == 204 && buf[pos] == 0xB8))
+			break;
+		pos++;
 	}
 
-	while (p < count) {
-		if (buf[p] == 0x47) {
-			if (count - p >= 188) {
-				dvb_dmx_swfilter_packet(demux, &buf[p]);
-				p += 188;
-			} else {
-				i = count - p;
-				memcpy(demux->tsbuf, &buf[p], i);
-				demux->tsbufp = i;
-				goto bailout;
-			}
-		} else
-			p++;
+	lost = pos - start;
+	if (lost) {
+		/* This garbage is part of a valid packet? */
+		int backtrack = pos - pktsize;
+		if (backtrack >= 0 && (buf[backtrack] == 0x47 ||
+		    (pktsize == 204 && buf[backtrack] == 0xB8)))
+			return backtrack;
 	}
 
-bailout:
-	spin_unlock(&demux->lock);
+	return pos;
 }
 
-EXPORT_SYMBOL(dvb_dmx_swfilter);
-
-void dvb_dmx_swfilter_204(struct dvb_demux *demux, const u8 *buf, size_t count)
+/* Filter all pktsize= 188 or 204 sized packets and skip garbage. */
+static inline void _dvb_dmx_swfilter(struct dvb_demux *demux, const u8 *buf,
+		size_t count, const int pktsize)
 {
 	int p = 0, i, j;
-	u8 tmppack[188];
+	const u8 *q;
 
 	spin_lock(&demux->lock);
 
-	if (demux->tsbufp) {
+	if (demux->tsbufp) { /* tsbuf[0] is now 0x47. */
 		i = demux->tsbufp;
-		j = 204 - i;
+		j = pktsize - i;
 		if (count < j) {
 			memcpy(&demux->tsbuf[i], buf, count);
 			demux->tsbufp += count;
 			goto bailout;
 		}
 		memcpy(&demux->tsbuf[i], buf, j);
-		if ((demux->tsbuf[0] == 0x47) || (demux->tsbuf[0] == 0xB8)) {
-			memcpy(tmppack, demux->tsbuf, 188);
-			if (tmppack[0] == 0xB8)
-				tmppack[0] = 0x47;
-			dvb_dmx_swfilter_packet(demux, tmppack);
-		}
+		if (demux->tsbuf[0] == 0x47) /* double check */
+			dvb_dmx_swfilter_packet(demux, demux->tsbuf);
 		demux->tsbufp = 0;
 		p += j;
 	}
 
-	while (p < count) {
-		if ((buf[p] == 0x47) || (buf[p] == 0xB8)) {
-			if (count - p >= 204) {
-				memcpy(tmppack, &buf[p], 188);
-				if (tmppack[0] == 0xB8)
-					tmppack[0] = 0x47;
-				dvb_dmx_swfilter_packet(demux, tmppack);
-				p += 204;
-			} else {
-				i = count - p;
-				memcpy(demux->tsbuf, &buf[p], i);
-				demux->tsbufp = i;
-				goto bailout;
-			}
-		} else {
-			p++;
+	while (1) {
+		p = find_next_packet(buf, p, count, pktsize);
+		if (p >= count)
+			break;
+		if (count - p < pktsize)
+			break;
+
+		q = &buf[p];
+
+		if (pktsize == 204 && (*q == 0xB8)) {
+			memcpy(demux->tsbuf, q, 188);
+			demux->tsbuf[0] = 0x47;
+			q = demux->tsbuf;
 		}
+		dvb_dmx_swfilter_packet(demux, q);
+		p += pktsize;
+	}
+
+	i = count - p;
+	if (i) {
+		memcpy(demux->tsbuf, &buf[p], i);
+		demux->tsbufp = i;
+		if (pktsize == 204 && demux->tsbuf[0] == 0xB8)
+			demux->tsbuf[0] = 0x47;
 	}
 
 bailout:
 	spin_unlock(&demux->lock);
 }
 
+void dvb_dmx_swfilter(struct dvb_demux *demux, const u8 *buf, size_t count)
+{
+	_dvb_dmx_swfilter(demux, buf, count, 188);
+}
+EXPORT_SYMBOL(dvb_dmx_swfilter);
+
+void dvb_dmx_swfilter_204(struct dvb_demux *demux, const u8 *buf, size_t count)
+{
+	_dvb_dmx_swfilter(demux, buf, count, 204);
+}
 EXPORT_SYMBOL(dvb_dmx_swfilter_204);
 
 static struct dvb_demux_filter *dvb_dmx_filter_alloc(struct dvb_demux *demux)
diff -druN linux-2.6.39-libre/drivers/media/dvb/dvb-core/dvb_frontend.c linux-3.0-rc7-libre/drivers/media/dvb/dvb-core/dvb_frontend.c
--- linux-2.6.39-libre/drivers/media/dvb/dvb-core/dvb_frontend.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/dvb/dvb-core/dvb_frontend.c	2011-07-11 19:51:52.000000000 -0400
@@ -105,7 +105,8 @@
 
 	/* thread/frontend values */
 	struct dvb_device *dvbdev;
-	struct dvb_frontend_parameters parameters;
+	struct dvb_frontend_parameters parameters_in;
+	struct dvb_frontend_parameters parameters_out;
 	struct dvb_fe_events events;
 	struct semaphore sem;
 	struct list_head list_head;
@@ -160,12 +161,11 @@
 
 	e = &events->events[events->eventw];
 
-	memcpy (&e->parameters, &fepriv->parameters,
-		sizeof (struct dvb_frontend_parameters));
-
 	if (status & FE_HAS_LOCK)
 		if (fe->ops.get_frontend)
-			fe->ops.get_frontend(fe, &e->parameters);
+			fe->ops.get_frontend(fe, &fepriv->parameters_out);
+
+	e->parameters = fepriv->parameters_out;
 
 	events->eventw = wp;
 
@@ -277,12 +277,12 @@
 	int ready = 0;
 	int fe_set_err = 0;
 	struct dvb_frontend_private *fepriv = fe->frontend_priv;
-	int original_inversion = fepriv->parameters.inversion;
-	u32 original_frequency = fepriv->parameters.frequency;
+	int original_inversion = fepriv->parameters_in.inversion;
+	u32 original_frequency = fepriv->parameters_in.frequency;
 
 	/* are we using autoinversion? */
 	autoinversion = ((!(fe->ops.info.caps & FE_CAN_INVERSION_AUTO)) &&
-			 (fepriv->parameters.inversion == INVERSION_AUTO));
+			 (fepriv->parameters_in.inversion == INVERSION_AUTO));
 
 	/* setup parameters correctly */
 	while(!ready) {
@@ -348,18 +348,19 @@
 		fepriv->auto_step, fepriv->auto_sub_step, fepriv->started_auto_step);
 
 	/* set the frontend itself */
-	fepriv->parameters.frequency += fepriv->lnb_drift;
+	fepriv->parameters_in.frequency += fepriv->lnb_drift;
 	if (autoinversion)
-		fepriv->parameters.inversion = fepriv->inversion;
+		fepriv->parameters_in.inversion = fepriv->inversion;
 	if (fe->ops.set_frontend)
-		fe_set_err = fe->ops.set_frontend(fe, &fepriv->parameters);
+		fe_set_err = fe->ops.set_frontend(fe, &fepriv->parameters_in);
+	fepriv->parameters_out = fepriv->parameters_in;
 	if (fe_set_err < 0) {
 		fepriv->state = FESTATE_ERROR;
 		return fe_set_err;
 	}
 
-	fepriv->parameters.frequency = original_frequency;
-	fepriv->parameters.inversion = original_inversion;
+	fepriv->parameters_in.frequency = original_frequency;
+	fepriv->parameters_in.inversion = original_inversion;
 
 	fepriv->auto_sub_step++;
 	return 0;
@@ -383,7 +384,8 @@
 		if (fepriv->state & FESTATE_RETUNE) {
 			if (fe->ops.set_frontend)
 				retval = fe->ops.set_frontend(fe,
-							&fepriv->parameters);
+							&fepriv->parameters_in);
+			fepriv->parameters_out = fepriv->parameters_in;
 			if (retval < 0)
 				fepriv->state = FESTATE_ERROR;
 			else
@@ -413,8 +415,8 @@
 
 		/* if we're tuned, then we have determined the correct inversion */
 		if ((!(fe->ops.info.caps & FE_CAN_INVERSION_AUTO)) &&
-		    (fepriv->parameters.inversion == INVERSION_AUTO)) {
-			fepriv->parameters.inversion = fepriv->inversion;
+		    (fepriv->parameters_in.inversion == INVERSION_AUTO)) {
+			fepriv->parameters_in.inversion = fepriv->inversion;
 		}
 		return;
 	}
@@ -594,12 +596,14 @@
 
 				if (fepriv->state & FESTATE_RETUNE) {
 					dprintk("%s: Retune requested, FESTATE_RETUNE\n", __func__);
-					params = &fepriv->parameters;
+					params = &fepriv->parameters_in;
 					fepriv->state = FESTATE_TUNED;
 				}
 
 				if (fe->ops.tune)
 					fe->ops.tune(fe, params, fepriv->tune_mode_flags, &fepriv->delay, &s);
+				if (params)
+					fepriv->parameters_out = *params;
 
 				if (s != fepriv->status && !(fepriv->tune_mode_flags & FE_TUNE_MODE_ONESHOT)) {
 					dprintk("%s: state changed, adding current state\n", __func__);
@@ -612,11 +616,9 @@
 				dvb_frontend_swzigzag(fe);
 				break;
 			case DVBFE_ALGO_CUSTOM:
-				params = NULL; /* have we been asked to RETUNE ?	*/
 				dprintk("%s: Frontend ALGO = DVBFE_ALGO_CUSTOM, state=%d\n", __func__, fepriv->state);
 				if (fepriv->state & FESTATE_RETUNE) {
 					dprintk("%s: Retune requested, FESTAT_RETUNE\n", __func__);
-					params = &fepriv->parameters;
 					fepriv->state = FESTATE_TUNED;
 				}
 				/* Case where we are going to search for a carrier
@@ -625,7 +627,7 @@
 				 */
 				if (fepriv->algo_status & DVBFE_ALGO_SEARCH_AGAIN) {
 					if (fe->ops.search) {
-						fepriv->algo_status = fe->ops.search(fe, &fepriv->parameters);
+						fepriv->algo_status = fe->ops.search(fe, &fepriv->parameters_in);
 						/* We did do a search as was requested, the flags are
 						 * now unset as well and has the flags wrt to search.
 						 */
@@ -636,11 +638,12 @@
 				/* Track the carrier if the search was successful */
 				if (fepriv->algo_status == DVBFE_ALGO_SEARCH_SUCCESS) {
 					if (fe->ops.track)
-						fe->ops.track(fe, &fepriv->parameters);
+						fe->ops.track(fe, &fepriv->parameters_in);
 				} else {
 					fepriv->algo_status |= DVBFE_ALGO_SEARCH_AGAIN;
 					fepriv->delay = HZ / 2;
 				}
+				fepriv->parameters_out = fepriv->parameters_in;
 				fe->ops.read_status(fe, &s);
 				if (s != fepriv->status) {
 					dvb_frontend_add_event(fe, s); /* update event list */
@@ -860,34 +863,34 @@
 
 static int dvb_frontend_clear_cache(struct dvb_frontend *fe)
 {
+	struct dtv_frontend_properties *c = &fe->dtv_property_cache;
 	int i;
 
-	memset(&(fe->dtv_property_cache), 0,
-			sizeof(struct dtv_frontend_properties));
+	memset(c, 0, sizeof(struct dtv_frontend_properties));
 
-	fe->dtv_property_cache.state = DTV_CLEAR;
-	fe->dtv_property_cache.delivery_system = SYS_UNDEFINED;
-	fe->dtv_property_cache.inversion = INVERSION_AUTO;
-	fe->dtv_property_cache.fec_inner = FEC_AUTO;
-	fe->dtv_property_cache.transmission_mode = TRANSMISSION_MODE_AUTO;
-	fe->dtv_property_cache.bandwidth_hz = BANDWIDTH_AUTO;
-	fe->dtv_property_cache.guard_interval = GUARD_INTERVAL_AUTO;
-	fe->dtv_property_cache.hierarchy = HIERARCHY_AUTO;
-	fe->dtv_property_cache.symbol_rate = QAM_AUTO;
-	fe->dtv_property_cache.code_rate_HP = FEC_AUTO;
-	fe->dtv_property_cache.code_rate_LP = FEC_AUTO;
+	c->state = DTV_CLEAR;
+	c->delivery_system = SYS_UNDEFINED;
+	c->inversion = INVERSION_AUTO;
+	c->fec_inner = FEC_AUTO;
+	c->transmission_mode = TRANSMISSION_MODE_AUTO;
+	c->bandwidth_hz = BANDWIDTH_AUTO;
+	c->guard_interval = GUARD_INTERVAL_AUTO;
+	c->hierarchy = HIERARCHY_AUTO;
+	c->symbol_rate = QAM_AUTO;
+	c->code_rate_HP = FEC_AUTO;
+	c->code_rate_LP = FEC_AUTO;
 
-	fe->dtv_property_cache.isdbt_partial_reception = -1;
-	fe->dtv_property_cache.isdbt_sb_mode = -1;
-	fe->dtv_property_cache.isdbt_sb_subchannel = -1;
-	fe->dtv_property_cache.isdbt_sb_segment_idx = -1;
-	fe->dtv_property_cache.isdbt_sb_segment_count = -1;
-	fe->dtv_property_cache.isdbt_layer_enabled = 0x7;
+	c->isdbt_partial_reception = -1;
+	c->isdbt_sb_mode = -1;
+	c->isdbt_sb_subchannel = -1;
+	c->isdbt_sb_segment_idx = -1;
+	c->isdbt_sb_segment_count = -1;
+	c->isdbt_layer_enabled = 0x7;
 	for (i = 0; i < 3; i++) {
-		fe->dtv_property_cache.layer[i].fec = FEC_AUTO;
-		fe->dtv_property_cache.layer[i].modulation = QAM_AUTO;
-		fe->dtv_property_cache.layer[i].interleaving = -1;
-		fe->dtv_property_cache.layer[i].segment_count = -1;
+		c->layer[i].fec = FEC_AUTO;
+		c->layer[i].modulation = QAM_AUTO;
+		c->layer[i].interleaving = -1;
+		c->layer[i].segment_count = -1;
 	}
 
 	return 0;
@@ -1020,10 +1023,9 @@
  * it's being used for the legacy or new API, reducing code and complexity.
  */
 static void dtv_property_cache_sync(struct dvb_frontend *fe,
-				    struct dvb_frontend_parameters *p)
+				    struct dtv_frontend_properties *c,
+				    const struct dvb_frontend_parameters *p)
 {
-	struct dtv_frontend_properties *c = &fe->dtv_property_cache;
-
 	c->frequency = p->frequency;
 	c->inversion = p->inversion;
 
@@ -1074,9 +1076,9 @@
  */
 static void dtv_property_legacy_params_sync(struct dvb_frontend *fe)
 {
-	struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+	const struct dtv_frontend_properties *c = &fe->dtv_property_cache;
 	struct dvb_frontend_private *fepriv = fe->frontend_priv;
-	struct dvb_frontend_parameters *p = &fepriv->parameters;
+	struct dvb_frontend_parameters *p = &fepriv->parameters_in;
 
 	p->frequency = c->frequency;
 	p->inversion = c->inversion;
@@ -1086,14 +1088,12 @@
 		dprintk("%s() Preparing QPSK req\n", __func__);
 		p->u.qpsk.symbol_rate = c->symbol_rate;
 		p->u.qpsk.fec_inner = c->fec_inner;
-		c->delivery_system = SYS_DVBS;
 		break;
 	case FE_QAM:
 		dprintk("%s() Preparing QAM req\n", __func__);
 		p->u.qam.symbol_rate = c->symbol_rate;
 		p->u.qam.fec_inner = c->fec_inner;
 		p->u.qam.modulation = c->modulation;
-		c->delivery_system = SYS_DVBC_ANNEX_AC;
 		break;
 	case FE_OFDM:
 		dprintk("%s() Preparing OFDM req\n", __func__);
@@ -1111,15 +1111,10 @@
 		p->u.ofdm.transmission_mode = c->transmission_mode;
 		p->u.ofdm.guard_interval = c->guard_interval;
 		p->u.ofdm.hierarchy_information = c->hierarchy;
-		c->delivery_system = SYS_DVBT;
 		break;
 	case FE_ATSC:
 		dprintk("%s() Preparing VSB req\n", __func__);
 		p->u.vsb.modulation = c->modulation;
-		if ((c->modulation == VSB_8) || (c->modulation == VSB_16))
-			c->delivery_system = SYS_ATSC;
-		else
-			c->delivery_system = SYS_DVBC_ANNEX_B;
 		break;
 	}
 }
@@ -1129,9 +1124,9 @@
  */
 static void dtv_property_adv_params_sync(struct dvb_frontend *fe)
 {
-	struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+	const struct dtv_frontend_properties *c = &fe->dtv_property_cache;
 	struct dvb_frontend_private *fepriv = fe->frontend_priv;
-	struct dvb_frontend_parameters *p = &fepriv->parameters;
+	struct dvb_frontend_parameters *p = &fepriv->parameters_in;
 
 	p->frequency = c->frequency;
 	p->inversion = c->inversion;
@@ -1148,10 +1143,9 @@
 		break;
 	}
 
-	if(c->delivery_system == SYS_ISDBT) {
-		/* Fake out a generic DVB-T request so we pass validation in the ioctl */
-		p->frequency = c->frequency;
-		p->inversion = c->inversion;
+	/* Fake out a generic DVB-T request so we pass validation in the ioctl */
+	if ((c->delivery_system == SYS_ISDBT) ||
+	    (c->delivery_system == SYS_DVBT2)) {
 		p->u.ofdm.constellation = QAM_AUTO;
 		p->u.ofdm.code_rate_HP = FEC_AUTO;
 		p->u.ofdm.code_rate_LP = FEC_AUTO;
@@ -1171,7 +1165,7 @@
 
 static void dtv_property_cache_submit(struct dvb_frontend *fe)
 {
-	struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+	const struct dtv_frontend_properties *c = &fe->dtv_property_cache;
 
 	/* For legacy delivery systems we don't need the delivery_system to
 	 * be specified, but we populate the older structures from the cache
@@ -1204,133 +1198,149 @@
 				    struct dtv_property *tvp,
 				    struct file *file)
 {
-	int r = 0;
-
-	/* Allow the frontend to validate incoming properties */
-	if (fe->ops.get_property)
-		r = fe->ops.get_property(fe, tvp);
+	const struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+	struct dvb_frontend_private *fepriv = fe->frontend_priv;
+	struct dtv_frontend_properties cdetected;
+	int r;
 
-	if (r < 0)
-		return r;
+	/*
+	 * If the driver implements a get_frontend function, then convert
+	 * detected parameters to S2API properties.
+	 */
+	if (fe->ops.get_frontend) {
+		cdetected = *c;
+		dtv_property_cache_sync(fe, &cdetected, &fepriv->parameters_out);
+		c = &cdetected;
+	}
 
 	switch(tvp->cmd) {
 	case DTV_FREQUENCY:
-		tvp->u.data = fe->dtv_property_cache.frequency;
+		tvp->u.data = c->frequency;
 		break;
 	case DTV_MODULATION:
-		tvp->u.data = fe->dtv_property_cache.modulation;
+		tvp->u.data = c->modulation;
 		break;
 	case DTV_BANDWIDTH_HZ:
-		tvp->u.data = fe->dtv_property_cache.bandwidth_hz;
+		tvp->u.data = c->bandwidth_hz;
 		break;
 	case DTV_INVERSION:
-		tvp->u.data = fe->dtv_property_cache.inversion;
+		tvp->u.data = c->inversion;
 		break;
 	case DTV_SYMBOL_RATE:
-		tvp->u.data = fe->dtv_property_cache.symbol_rate;
+		tvp->u.data = c->symbol_rate;
 		break;
 	case DTV_INNER_FEC:
-		tvp->u.data = fe->dtv_property_cache.fec_inner;
+		tvp->u.data = c->fec_inner;
 		break;
 	case DTV_PILOT:
-		tvp->u.data = fe->dtv_property_cache.pilot;
+		tvp->u.data = c->pilot;
 		break;
 	case DTV_ROLLOFF:
-		tvp->u.data = fe->dtv_property_cache.rolloff;
+		tvp->u.data = c->rolloff;
 		break;
 	case DTV_DELIVERY_SYSTEM:
-		tvp->u.data = fe->dtv_property_cache.delivery_system;
+		tvp->u.data = c->delivery_system;
 		break;
 	case DTV_VOLTAGE:
-		tvp->u.data = fe->dtv_property_cache.voltage;
+		tvp->u.data = c->voltage;
 		break;
 	case DTV_TONE:
-		tvp->u.data = fe->dtv_property_cache.sectone;
+		tvp->u.data = c->sectone;
 		break;
 	case DTV_API_VERSION:
 		tvp->u.data = (DVB_API_VERSION << 8) | DVB_API_VERSION_MINOR;
 		break;
 	case DTV_CODE_RATE_HP:
-		tvp->u.data = fe->dtv_property_cache.code_rate_HP;
+		tvp->u.data = c->code_rate_HP;
 		break;
 	case DTV_CODE_RATE_LP:
-		tvp->u.data = fe->dtv_property_cache.code_rate_LP;
+		tvp->u.data = c->code_rate_LP;
 		break;
 	case DTV_GUARD_INTERVAL:
-		tvp->u.data = fe->dtv_property_cache.guard_interval;
+		tvp->u.data = c->guard_interval;
 		break;
 	case DTV_TRANSMISSION_MODE:
-		tvp->u.data = fe->dtv_property_cache.transmission_mode;
+		tvp->u.data = c->transmission_mode;
 		break;
 	case DTV_HIERARCHY:
-		tvp->u.data = fe->dtv_property_cache.hierarchy;
+		tvp->u.data = c->hierarchy;
 		break;
 
 	/* ISDB-T Support here */
 	case DTV_ISDBT_PARTIAL_RECEPTION:
-		tvp->u.data = fe->dtv_property_cache.isdbt_partial_reception;
+		tvp->u.data = c->isdbt_partial_reception;
 		break;
 	case DTV_ISDBT_SOUND_BROADCASTING:
-		tvp->u.data = fe->dtv_property_cache.isdbt_sb_mode;
+		tvp->u.data = c->isdbt_sb_mode;
 		break;
 	case DTV_ISDBT_SB_SUBCHANNEL_ID:
-		tvp->u.data = fe->dtv_property_cache.isdbt_sb_subchannel;
+		tvp->u.data = c->isdbt_sb_subchannel;
 		break;
 	case DTV_ISDBT_SB_SEGMENT_IDX:
-		tvp->u.data = fe->dtv_property_cache.isdbt_sb_segment_idx;
+		tvp->u.data = c->isdbt_sb_segment_idx;
 		break;
 	case DTV_ISDBT_SB_SEGMENT_COUNT:
-		tvp->u.data = fe->dtv_property_cache.isdbt_sb_segment_count;
+		tvp->u.data = c->isdbt_sb_segment_count;
 		break;
 	case DTV_ISDBT_LAYER_ENABLED:
-		tvp->u.data = fe->dtv_property_cache.isdbt_layer_enabled;
+		tvp->u.data = c->isdbt_layer_enabled;
 		break;
 	case DTV_ISDBT_LAYERA_FEC:
-		tvp->u.data = fe->dtv_property_cache.layer[0].fec;
+		tvp->u.data = c->layer[0].fec;
 		break;
 	case DTV_ISDBT_LAYERA_MODULATION:
-		tvp->u.data = fe->dtv_property_cache.layer[0].modulation;
+		tvp->u.data = c->layer[0].modulation;
 		break;
 	case DTV_ISDBT_LAYERA_SEGMENT_COUNT:
-		tvp->u.data = fe->dtv_property_cache.layer[0].segment_count;
+		tvp->u.data = c->layer[0].segment_count;
 		break;
 	case DTV_ISDBT_LAYERA_TIME_INTERLEAVING:
-		tvp->u.data = fe->dtv_property_cache.layer[0].interleaving;
+		tvp->u.data = c->layer[0].interleaving;
 		break;
 	case DTV_ISDBT_LAYERB_FEC:
-		tvp->u.data = fe->dtv_property_cache.layer[1].fec;
+		tvp->u.data = c->layer[1].fec;
 		break;
 	case DTV_ISDBT_LAYERB_MODULATION:
-		tvp->u.data = fe->dtv_property_cache.layer[1].modulation;
+		tvp->u.data = c->layer[1].modulation;
 		break;
 	case DTV_ISDBT_LAYERB_SEGMENT_COUNT:
-		tvp->u.data = fe->dtv_property_cache.layer[1].segment_count;
+		tvp->u.data = c->layer[1].segment_count;
 		break;
 	case DTV_ISDBT_LAYERB_TIME_INTERLEAVING:
-		tvp->u.data = fe->dtv_property_cache.layer[1].interleaving;
+		tvp->u.data = c->layer[1].interleaving;
 		break;
 	case DTV_ISDBT_LAYERC_FEC:
-		tvp->u.data = fe->dtv_property_cache.layer[2].fec;
+		tvp->u.data = c->layer[2].fec;
 		break;
 	case DTV_ISDBT_LAYERC_MODULATION:
-		tvp->u.data = fe->dtv_property_cache.layer[2].modulation;
+		tvp->u.data = c->layer[2].modulation;
 		break;
 	case DTV_ISDBT_LAYERC_SEGMENT_COUNT:
-		tvp->u.data = fe->dtv_property_cache.layer[2].segment_count;
+		tvp->u.data = c->layer[2].segment_count;
 		break;
 	case DTV_ISDBT_LAYERC_TIME_INTERLEAVING:
-		tvp->u.data = fe->dtv_property_cache.layer[2].interleaving;
+		tvp->u.data = c->layer[2].interleaving;
 		break;
 	case DTV_ISDBS_TS_ID:
-		tvp->u.data = fe->dtv_property_cache.isdbs_ts_id;
+		tvp->u.data = c->isdbs_ts_id;
+		break;
+	case DTV_DVBT2_PLP_ID:
+		tvp->u.data = c->dvbt2_plp_id;
 		break;
 	default:
-		r = -1;
+		return -EINVAL;
+	}
+
+	/* Allow the frontend to override outgoing properties */
+	if (fe->ops.get_property) {
+		r = fe->ops.get_property(fe, tvp);
+		if (r < 0)
+			return r;
 	}
 
 	dtv_property_dump(tvp);
 
-	return r;
+	return 0;
 }
 
 static int dtv_property_process_set(struct dvb_frontend *fe,
@@ -1338,15 +1348,16 @@
 				    struct file *file)
 {
 	int r = 0;
+	struct dtv_frontend_properties *c = &fe->dtv_property_cache;
 	struct dvb_frontend_private *fepriv = fe->frontend_priv;
 	dtv_property_dump(tvp);
 
 	/* Allow the frontend to validate incoming properties */
-	if (fe->ops.set_property)
+	if (fe->ops.set_property) {
 		r = fe->ops.set_property(fe, tvp);
-
-	if (r < 0)
-		return r;
+		if (r < 0)
+			return r;
+	}
 
 	switch(tvp->cmd) {
 	case DTV_CLEAR:
@@ -1361,126 +1372,129 @@
 		 * tunerequest so we can pass validation in the FE_SET_FRONTEND
 		 * ioctl.
 		 */
-		fe->dtv_property_cache.state = tvp->cmd;
+		c->state = tvp->cmd;
 		dprintk("%s() Finalised property cache\n", __func__);
 		dtv_property_cache_submit(fe);
 
-		r |= dvb_frontend_ioctl_legacy(file, FE_SET_FRONTEND,
-			&fepriv->parameters);
+		r = dvb_frontend_ioctl_legacy(file, FE_SET_FRONTEND,
+			&fepriv->parameters_in);
 		break;
 	case DTV_FREQUENCY:
-		fe->dtv_property_cache.frequency = tvp->u.data;
+		c->frequency = tvp->u.data;
 		break;
 	case DTV_MODULATION:
-		fe->dtv_property_cache.modulation = tvp->u.data;
+		c->modulation = tvp->u.data;
 		break;
 	case DTV_BANDWIDTH_HZ:
-		fe->dtv_property_cache.bandwidth_hz = tvp->u.data;
+		c->bandwidth_hz = tvp->u.data;
 		break;
 	case DTV_INVERSION:
-		fe->dtv_property_cache.inversion = tvp->u.data;
+		c->inversion = tvp->u.data;
 		break;
 	case DTV_SYMBOL_RATE:
-		fe->dtv_property_cache.symbol_rate = tvp->u.data;
+		c->symbol_rate = tvp->u.data;
 		break;
 	case DTV_INNER_FEC:
-		fe->dtv_property_cache.fec_inner = tvp->u.data;
+		c->fec_inner = tvp->u.data;
 		break;
 	case DTV_PILOT:
-		fe->dtv_property_cache.pilot = tvp->u.data;
+		c->pilot = tvp->u.data;
 		break;
 	case DTV_ROLLOFF:
-		fe->dtv_property_cache.rolloff = tvp->u.data;
+		c->rolloff = tvp->u.data;
 		break;
 	case DTV_DELIVERY_SYSTEM:
-		fe->dtv_property_cache.delivery_system = tvp->u.data;
+		c->delivery_system = tvp->u.data;
 		break;
 	case DTV_VOLTAGE:
-		fe->dtv_property_cache.voltage = tvp->u.data;
+		c->voltage = tvp->u.data;
 		r = dvb_frontend_ioctl_legacy(file, FE_SET_VOLTAGE,
-			(void *)fe->dtv_property_cache.voltage);
+			(void *)c->voltage);
 		break;
 	case DTV_TONE:
-		fe->dtv_property_cache.sectone = tvp->u.data;
+		c->sectone = tvp->u.data;
 		r = dvb_frontend_ioctl_legacy(file, FE_SET_TONE,
-			(void *)fe->dtv_property_cache.sectone);
+			(void *)c->sectone);
 		break;
 	case DTV_CODE_RATE_HP:
-		fe->dtv_property_cache.code_rate_HP = tvp->u.data;
+		c->code_rate_HP = tvp->u.data;
 		break;
 	case DTV_CODE_RATE_LP:
-		fe->dtv_property_cache.code_rate_LP = tvp->u.data;
+		c->code_rate_LP = tvp->u.data;
 		break;
 	case DTV_GUARD_INTERVAL:
-		fe->dtv_property_cache.guard_interval = tvp->u.data;
+		c->guard_interval = tvp->u.data;
 		break;
 	case DTV_TRANSMISSION_MODE:
-		fe->dtv_property_cache.transmission_mode = tvp->u.data;
+		c->transmission_mode = tvp->u.data;
 		break;
 	case DTV_HIERARCHY:
-		fe->dtv_property_cache.hierarchy = tvp->u.data;
+		c->hierarchy = tvp->u.data;
 		break;
 
 	/* ISDB-T Support here */
 	case DTV_ISDBT_PARTIAL_RECEPTION:
-		fe->dtv_property_cache.isdbt_partial_reception = tvp->u.data;
+		c->isdbt_partial_reception = tvp->u.data;
 		break;
 	case DTV_ISDBT_SOUND_BROADCASTING:
-		fe->dtv_property_cache.isdbt_sb_mode = tvp->u.data;
+		c->isdbt_sb_mode = tvp->u.data;
 		break;
 	case DTV_ISDBT_SB_SUBCHANNEL_ID:
-		fe->dtv_property_cache.isdbt_sb_subchannel = tvp->u.data;
+		c->isdbt_sb_subchannel = tvp->u.data;
 		break;
 	case DTV_ISDBT_SB_SEGMENT_IDX:
-		fe->dtv_property_cache.isdbt_sb_segment_idx = tvp->u.data;
+		c->isdbt_sb_segment_idx = tvp->u.data;
 		break;
 	case DTV_ISDBT_SB_SEGMENT_COUNT:
-		fe->dtv_property_cache.isdbt_sb_segment_count = tvp->u.data;
+		c->isdbt_sb_segment_count = tvp->u.data;
 		break;
 	case DTV_ISDBT_LAYER_ENABLED:
-		fe->dtv_property_cache.isdbt_layer_enabled = tvp->u.data;
+		c->isdbt_layer_enabled = tvp->u.data;
 		break;
 	case DTV_ISDBT_LAYERA_FEC:
-		fe->dtv_property_cache.layer[0].fec = tvp->u.data;
+		c->layer[0].fec = tvp->u.data;
 		break;
 	case DTV_ISDBT_LAYERA_MODULATION:
-		fe->dtv_property_cache.layer[0].modulation = tvp->u.data;
+		c->layer[0].modulation = tvp->u.data;
 		break;
 	case DTV_ISDBT_LAYERA_SEGMENT_COUNT:
-		fe->dtv_property_cache.layer[0].segment_count = tvp->u.data;
+		c->layer[0].segment_count = tvp->u.data;
 		break;
 	case DTV_ISDBT_LAYERA_TIME_INTERLEAVING:
-		fe->dtv_property_cache.layer[0].interleaving = tvp->u.data;
+		c->layer[0].interleaving = tvp->u.data;
 		break;
 	case DTV_ISDBT_LAYERB_FEC:
-		fe->dtv_property_cache.layer[1].fec = tvp->u.data;
+		c->layer[1].fec = tvp->u.data;
 		break;
 	case DTV_ISDBT_LAYERB_MODULATION:
-		fe->dtv_property_cache.layer[1].modulation = tvp->u.data;
+		c->layer[1].modulation = tvp->u.data;
 		break;
 	case DTV_ISDBT_LAYERB_SEGMENT_COUNT:
-		fe->dtv_property_cache.layer[1].segment_count = tvp->u.data;
+		c->layer[1].segment_count = tvp->u.data;
 		break;
 	case DTV_ISDBT_LAYERB_TIME_INTERLEAVING:
-		fe->dtv_property_cache.layer[1].interleaving = tvp->u.data;
+		c->layer[1].interleaving = tvp->u.data;
 		break;
 	case DTV_ISDBT_LAYERC_FEC:
-		fe->dtv_property_cache.layer[2].fec = tvp->u.data;
+		c->layer[2].fec = tvp->u.data;
 		break;
 	case DTV_ISDBT_LAYERC_MODULATION:
-		fe->dtv_property_cache.layer[2].modulation = tvp->u.data;
+		c->layer[2].modulation = tvp->u.data;
 		break;
 	case DTV_ISDBT_LAYERC_SEGMENT_COUNT:
-		fe->dtv_property_cache.layer[2].segment_count = tvp->u.data;
+		c->layer[2].segment_count = tvp->u.data;
 		break;
 	case DTV_ISDBT_LAYERC_TIME_INTERLEAVING:
-		fe->dtv_property_cache.layer[2].interleaving = tvp->u.data;
+		c->layer[2].interleaving = tvp->u.data;
 		break;
 	case DTV_ISDBS_TS_ID:
-		fe->dtv_property_cache.isdbs_ts_id = tvp->u.data;
+		c->isdbs_ts_id = tvp->u.data;
+		break;
+	case DTV_DVBT2_PLP_ID:
+		c->dvbt2_plp_id = tvp->u.data;
 		break;
 	default:
-		r = -1;
+		return -EINVAL;
 	}
 
 	return r;
@@ -1491,6 +1505,7 @@
 {
 	struct dvb_device *dvbdev = file->private_data;
 	struct dvb_frontend *fe = dvbdev->priv;
+	struct dtv_frontend_properties *c = &fe->dtv_property_cache;
 	struct dvb_frontend_private *fepriv = fe->frontend_priv;
 	int err = -EOPNOTSUPP;
 
@@ -1510,7 +1525,7 @@
 	if ((cmd == FE_SET_PROPERTY) || (cmd == FE_GET_PROPERTY))
 		err = dvb_frontend_ioctl_properties(file, cmd, parg);
 	else {
-		fe->dtv_property_cache.state = DTV_UNDEFINED;
+		c->state = DTV_UNDEFINED;
 		err = dvb_frontend_ioctl_legacy(file, cmd, parg);
 	}
 
@@ -1523,6 +1538,7 @@
 {
 	struct dvb_device *dvbdev = file->private_data;
 	struct dvb_frontend *fe = dvbdev->priv;
+	struct dtv_frontend_properties *c = &fe->dtv_property_cache;
 	int err = 0;
 
 	struct dtv_properties *tvps = NULL;
@@ -1554,11 +1570,13 @@
 		}
 
 		for (i = 0; i < tvps->num; i++) {
-			(tvp + i)->result = dtv_property_process_set(fe, tvp + i, file);
-			err |= (tvp + i)->result;
+			err = dtv_property_process_set(fe, tvp + i, file);
+			if (err < 0)
+				goto out;
+			(tvp + i)->result = err;
 		}
 
-		if(fe->dtv_property_cache.state == DTV_TUNE)
+		if (c->state == DTV_TUNE)
 			dprintk("%s() Property cache is full, tuning\n", __func__);
 
 	} else
@@ -1586,8 +1604,10 @@
 		}
 
 		for (i = 0; i < tvps->num; i++) {
-			(tvp + i)->result = dtv_property_process_get(fe, tvp + i, file);
-			err |= (tvp + i)->result;
+			err = dtv_property_process_get(fe, tvp + i, file);
+			if (err < 0)
+				goto out;
+			(tvp + i)->result = err;
 		}
 
 		if (copy_to_user(tvps->props, tvp, tvps->num * sizeof(struct dtv_property))) {
@@ -1787,10 +1807,11 @@
 		break;
 
 	case FE_SET_FRONTEND: {
+		struct dtv_frontend_properties *c = &fe->dtv_property_cache;
 		struct dvb_frontend_tune_settings fetunesettings;
 
-		if(fe->dtv_property_cache.state == DTV_TUNE) {
-			if (dvb_frontend_check_parameters(fe, &fepriv->parameters) < 0) {
+		if (c->state == DTV_TUNE) {
+			if (dvb_frontend_check_parameters(fe, &fepriv->parameters_in) < 0) {
 				err = -EINVAL;
 				break;
 			}
@@ -1800,9 +1821,9 @@
 				break;
 			}
 
-			memcpy (&fepriv->parameters, parg,
+			memcpy (&fepriv->parameters_in, parg,
 				sizeof (struct dvb_frontend_parameters));
-			dtv_property_cache_sync(fe, &fepriv->parameters);
+			dtv_property_cache_sync(fe, c, &fepriv->parameters_in);
 		}
 
 		memset(&fetunesettings, 0, sizeof(struct dvb_frontend_tune_settings));
@@ -1811,15 +1832,15 @@
 
 		/* force auto frequency inversion if requested */
 		if (dvb_force_auto_inversion) {
-			fepriv->parameters.inversion = INVERSION_AUTO;
+			fepriv->parameters_in.inversion = INVERSION_AUTO;
 			fetunesettings.parameters.inversion = INVERSION_AUTO;
 		}
 		if (fe->ops.info.type == FE_OFDM) {
 			/* without hierarchical coding code_rate_LP is irrelevant,
 			 * so we tolerate the otherwise invalid FEC_NONE setting */
-			if (fepriv->parameters.u.ofdm.hierarchy_information == HIERARCHY_NONE &&
-			    fepriv->parameters.u.ofdm.code_rate_LP == FEC_NONE)
-				fepriv->parameters.u.ofdm.code_rate_LP = FEC_AUTO;
+			if (fepriv->parameters_in.u.ofdm.hierarchy_information == HIERARCHY_NONE &&
+			    fepriv->parameters_in.u.ofdm.code_rate_LP == FEC_NONE)
+				fepriv->parameters_in.u.ofdm.code_rate_LP = FEC_AUTO;
 		}
 
 		/* get frontend-specific tuning settings */
@@ -1832,8 +1853,8 @@
 			switch(fe->ops.info.type) {
 			case FE_QPSK:
 				fepriv->min_delay = HZ/20;
-				fepriv->step_size = fepriv->parameters.u.qpsk.symbol_rate / 16000;
-				fepriv->max_drift = fepriv->parameters.u.qpsk.symbol_rate / 2000;
+				fepriv->step_size = fepriv->parameters_in.u.qpsk.symbol_rate / 16000;
+				fepriv->max_drift = fepriv->parameters_in.u.qpsk.symbol_rate / 2000;
 				break;
 
 			case FE_QAM:
@@ -1875,8 +1896,8 @@
 
 	case FE_GET_FRONTEND:
 		if (fe->ops.get_frontend) {
-			memcpy (parg, &fepriv->parameters, sizeof (struct dvb_frontend_parameters));
-			err = fe->ops.get_frontend(fe, (struct dvb_frontend_parameters*) parg);
+			err = fe->ops.get_frontend(fe, &fepriv->parameters_out);
+			memcpy(parg, &fepriv->parameters_out, sizeof(struct dvb_frontend_parameters));
 		}
 		break;
 
diff -druN linux-2.6.39-libre/drivers/media/dvb/dvb-core/dvb_frontend.h linux-3.0-rc7-libre/drivers/media/dvb/dvb-core/dvb_frontend.h
--- linux-2.6.39-libre/drivers/media/dvb/dvb-core/dvb_frontend.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/dvb/dvb-core/dvb_frontend.h	2011-07-11 19:51:52.000000000 -0400
@@ -358,6 +358,9 @@
 
 	/* ISDB-T specifics */
 	u32			isdbs_ts_id;
+
+	/* DVB-T2 specifics */
+	u32                     dvbt2_plp_id;
 };
 
 struct dvb_frontend {
diff -druN linux-2.6.39-libre/drivers/media/dvb/dvb-usb/a800.c linux-3.0-rc7-libre/drivers/media/dvb/dvb-usb/a800.c
--- linux-2.6.39-libre/drivers/media/dvb/dvb-usb/a800.c	2011-05-19 02:08:23.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/dvb/dvb-usb/a800.c	2011-07-21 06:50:41.000000000 -0400
@@ -78,17 +78,26 @@
 
 static int a800_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
 {
-	u8 key[5];
+	int ret;
+	u8 *key = kmalloc(5, GFP_KERNEL);
+	if (!key)
+		return -ENOMEM;
+
 	if (usb_control_msg(d->udev,usb_rcvctrlpipe(d->udev,0),
 				0x04, USB_TYPE_VENDOR | USB_DIR_IN, 0, 0, key, 5,
-				2000) != 5)
-		return -ENODEV;
+				2000) != 5) {
+		ret = -ENODEV;
+		goto out;
+	}
 
 	/* call the universal NEC remote processor, to find out the key's state and event */
 	dvb_usb_nec_rc_key_to_event(d,key,event,state);
 	if (key[0] != 0)
 		deb_rc("key: %x %x %x %x %x\n",key[0],key[1],key[2],key[3],key[4]);
-	return 0;
+	ret = 0;
+out:
+	kfree(key);
+	return ret;
 }
 
 /* USB Driver stuff */
diff -druN linux-2.6.39-libre/drivers/media/dvb/dvb-usb/anysee.c linux-3.0-rc7-libre/drivers/media/dvb/dvb-usb/anysee.c
--- linux-2.6.39-libre/drivers/media/dvb/dvb-usb/anysee.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/dvb/dvb-usb/anysee.c	2011-07-11 19:51:52.000000000 -0400
@@ -36,6 +36,11 @@
 #include "mt352.h"
 #include "mt352_priv.h"
 #include "zl10353.h"
+#include "tda18212.h"
+#include "cx24116.h"
+#include "stv0900.h"
+#include "stv6110.h"
+#include "isl6423.h"
 
 /* debug */
 static int dvb_usb_anysee_debug;
@@ -55,8 +60,6 @@
 	int act_len, ret;
 	u8 buf[64];
 
-	if (slen > sizeof(buf))
-		slen = sizeof(buf);
 	memcpy(&buf[0], sbuf, slen);
 	buf[60] = state->seq++;
 
@@ -105,6 +108,27 @@
 	return anysee_ctrl_msg(d, buf, sizeof(buf), NULL, 0);
 }
 
+/* write single register with mask */
+static int anysee_wr_reg_mask(struct dvb_usb_device *d, u16 reg, u8 val,
+	u8 mask)
+{
+	int ret;
+	u8 tmp;
+
+	/* no need for read if whole reg is written */
+	if (mask != 0xff) {
+		ret = anysee_read_reg(d, reg, &tmp);
+		if (ret)
+			return ret;
+
+		val &= mask;
+		tmp &= ~mask;
+		val |= tmp;
+	}
+
+	return anysee_write_reg(d, reg, val);
+}
+
 static int anysee_get_hw_info(struct dvb_usb_device *d, u8 *id)
 {
 	u8 buf[] = {CMD_GET_HW_INFO};
@@ -154,30 +178,37 @@
 {
 	struct dvb_usb_device *d = i2c_get_adapdata(adap);
 	int ret = 0, inc, i = 0;
+	u8 buf[52]; /* 4 + 48 (I2C WR USB command header + I2C WR max) */
 
 	if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
 		return -EAGAIN;
 
 	while (i < num) {
 		if (num > i + 1 && (msg[i+1].flags & I2C_M_RD)) {
-			u8 buf[6];
+			if (msg[i].len > 2 || msg[i+1].len > 60) {
+				ret = -EOPNOTSUPP;
+				break;
+			}
 			buf[0] = CMD_I2C_READ;
-			buf[1] = msg[i].addr + 1;
+			buf[1] = (msg[i].addr << 1) | 0x01;
 			buf[2] = msg[i].buf[0];
-			buf[3] = 0x00;
-			buf[4] = 0x00;
-			buf[5] = 0x01;
-			ret = anysee_ctrl_msg(d, buf, sizeof(buf), msg[i+1].buf,
+			buf[3] = msg[i].buf[1];
+			buf[4] = msg[i].len-1;
+			buf[5] = msg[i+1].len;
+			ret = anysee_ctrl_msg(d, buf, 6, msg[i+1].buf,
 				msg[i+1].len);
 			inc = 2;
 		} else {
-			u8 buf[4+msg[i].len];
+			if (msg[i].len > 48) {
+				ret = -EOPNOTSUPP;
+				break;
+			}
 			buf[0] = CMD_I2C_WRITE;
-			buf[1] = msg[i].addr;
+			buf[1] = (msg[i].addr << 1);
 			buf[2] = msg[i].len;
 			buf[3] = 0x01;
 			memcpy(&buf[4], msg[i].buf, msg[i].len);
-			ret = anysee_ctrl_msg(d, buf, sizeof(buf), NULL, 0);
+			ret = anysee_ctrl_msg(d, buf, 4 + msg[i].len, NULL, 0);
 			inc = 1;
 		}
 		if (ret)
@@ -224,7 +255,7 @@
 
 /* Callbacks for DVB USB */
 static struct tda10023_config anysee_tda10023_config = {
-	.demod_address = 0x1a,
+	.demod_address = (0x1a >> 1),
 	.invert = 0,
 	.xtal   = 16000000,
 	.pll_m  = 11,
@@ -235,143 +266,539 @@
 };
 
 static struct mt352_config anysee_mt352_config = {
-	.demod_address = 0x1e,
+	.demod_address = (0x1e >> 1),
 	.demod_init    = anysee_mt352_demod_init,
 };
 
 static struct zl10353_config anysee_zl10353_config = {
-	.demod_address = 0x1e,
+	.demod_address = (0x1e >> 1),
 	.parallel_ts = 1,
 };
 
+static struct zl10353_config anysee_zl10353_tda18212_config2 = {
+	.demod_address = (0x1e >> 1),
+	.parallel_ts = 1,
+	.disable_i2c_gate_ctrl = 1,
+	.no_tuner = 1,
+	.if2 = 41500,
+};
+
+static struct zl10353_config anysee_zl10353_tda18212_config = {
+	.demod_address = (0x18 >> 1),
+	.parallel_ts = 1,
+	.disable_i2c_gate_ctrl = 1,
+	.no_tuner = 1,
+	.if2 = 41500,
+};
+
+static struct tda10023_config anysee_tda10023_tda18212_config = {
+	.demod_address = (0x1a >> 1),
+	.xtal   = 16000000,
+	.pll_m  = 12,
+	.pll_p  = 3,
+	.pll_n  = 1,
+	.output_mode = TDA10023_OUTPUT_MODE_PARALLEL_C,
+	.deltaf = 0xba02,
+};
+
+static struct tda18212_config anysee_tda18212_config = {
+	.i2c_address = (0xc0 >> 1),
+	.if_dvbt_6 = 4150,
+	.if_dvbt_7 = 4150,
+	.if_dvbt_8 = 4150,
+	.if_dvbc = 5000,
+};
+
+static struct cx24116_config anysee_cx24116_config = {
+	.demod_address = (0xaa >> 1),
+	.mpg_clk_pos_pol = 0x00,
+	.i2c_wr_max = 48,
+};
+
+static struct stv0900_config anysee_stv0900_config = {
+	.demod_address = (0xd0 >> 1),
+	.demod_mode = 0,
+	.xtal = 8000000,
+	.clkmode = 3,
+	.diseqc_mode = 2,
+	.tun1_maddress = 0,
+	.tun1_adc = 1, /* 1 Vpp */
+	.path1_mode = 3,
+};
+
+static struct stv6110_config anysee_stv6110_config = {
+	.i2c_address = (0xc0 >> 1),
+	.mclk = 16000000,
+	.clk_div = 1,
+};
+
+static struct isl6423_config anysee_isl6423_config = {
+	.current_max = SEC_CURRENT_800m,
+	.curlim  = SEC_CURRENT_LIM_OFF,
+	.mod_extern = 1,
+	.addr = (0x10 >> 1),
+};
+
+/*
+ * New USB device strings: Mfr=1, Product=2, SerialNumber=0
+ * Manufacturer: AMT.CO.KR
+ *
+ * E30 VID=04b4 PID=861f HW=2 FW=2.1 Product=????????
+ * PCB: ?
+ * parts: DNOS404ZH102A(MT352, DTT7579(?))
+ *
+ * E30 VID=04b4 PID=861f HW=2 FW=2.1 Product=????????
+ * PCB: ?
+ * parts: DNOS404ZH103A(ZL10353, DTT7579(?))
+ *
+ * E30 Plus VID=04b4 PID=861f HW=6 FW=1.0 "anysee"
+ * PCB: 507CD (rev1.1)
+ * parts: DNOS404ZH103A(ZL10353, DTT7579(?)), CST56I01
+ * OEA=80 OEB=00 OEC=00 OED=ff OEF=fe
+ * IOA=4f IOB=ff IOC=00 IOD=06 IOF=01
+ * IOD[0] ZL10353 1=enabled
+ * IOA[7] TS 0=enabled
+ * tuner is not behind ZL10353 I2C-gate (no care if gate disabled or not)
+ *
+ * E30 C Plus VID=04b4 PID=861f HW=10 FW=1.0 "anysee-DC(LP)"
+ * PCB: 507DC (rev0.2)
+ * parts: TDA10023, DTOS403IH102B TM, CST56I01
+ * OEA=80 OEB=00 OEC=00 OED=ff OEF=fe
+ * IOA=4f IOB=ff IOC=00 IOD=26 IOF=01
+ * IOD[0] TDA10023 1=enabled
+ *
+ * E30 S2 Plus VID=04b4 PID=861f HW=11 FW=0.1 "anysee-S2(LP)"
+ * PCB: 507SI (rev2.1)
+ * parts: BS2N10WCC01(CX24116, CX24118), ISL6423, TDA8024
+ * OEA=80 OEB=00 OEC=ff OED=ff OEF=fe
+ * IOA=4d IOB=ff IOC=00 IOD=26 IOF=01
+ * IOD[0] CX24116 1=enabled
+ *
+ * E30 C Plus VID=1c73 PID=861f HW=15 FW=1.2 "anysee-FA(LP)"
+ * PCB: 507FA (rev0.4)
+ * parts: TDA10023, DTOS403IH102B TM, TDA8024
+ * OEA=80 OEB=00 OEC=ff OED=ff OEF=ff
+ * IOA=4d IOB=ff IOC=00 IOD=00 IOF=c0
+ * IOD[5] TDA10023 1=enabled
+ * IOE[0] tuner 1=enabled
+ *
+ * E30 Combo Plus VID=1c73 PID=861f HW=15 FW=1.2 "anysee-FA(LP)"
+ * PCB: 507FA (rev1.1)
+ * parts: ZL10353, TDA10023, DTOS403IH102B TM, TDA8024
+ * OEA=80 OEB=00 OEC=ff OED=ff OEF=ff
+ * IOA=4d IOB=ff IOC=00 IOD=00 IOF=c0
+ * DVB-C:
+ * IOD[5] TDA10023 1=enabled
+ * IOE[0] tuner 1=enabled
+ * DVB-T:
+ * IOD[0] ZL10353 1=enabled
+ * IOE[0] tuner 0=enabled
+ * tuner is behind ZL10353 I2C-gate
+ *
+ * E7 TC VID=1c73 PID=861f HW=18 FW=0.7 AMTCI=0.5 "anysee-E7TC(LP)"
+ * PCB: 508TC (rev0.6)
+ * parts: ZL10353, TDA10023, DNOD44CDH086A(TDA18212)
+ * OEA=80 OEB=00 OEC=03 OED=f7 OEF=ff
+ * IOA=4d IOB=00 IOC=cc IOD=48 IOF=e4
+ * IOA[7] TS 1=enabled
+ * IOE[4] TDA18212 1=enabled
+ * DVB-C:
+ * IOD[6] ZL10353 0=disabled
+ * IOD[5] TDA10023 1=enabled
+ * IOE[0] IF 1=enabled
+ * DVB-T:
+ * IOD[5] TDA10023 0=disabled
+ * IOD[6] ZL10353 1=enabled
+ * IOE[0] IF 0=enabled
+ *
+ * E7 S2 VID=1c73 PID=861f HW=19 FW=0.4 AMTCI=0.5 "anysee-E7S2(LP)"
+ * PCB: 508S2 (rev0.7)
+ * parts: DNBU10512IST(STV0903, STV6110), ISL6423
+ * OEA=80 OEB=00 OEC=03 OED=f7 OEF=ff
+ * IOA=4d IOB=00 IOC=c4 IOD=08 IOF=e4
+ * IOA[7] TS 1=enabled
+ * IOE[5] STV0903 1=enabled
+ *
+ */
+
 static int anysee_frontend_attach(struct dvb_usb_adapter *adap)
 {
 	int ret;
 	struct anysee_state *state = adap->dev->priv;
 	u8 hw_info[3];
-	u8 io_d; /* IO port D */
+	u8 tmp;
+	struct i2c_msg msg[2] = {
+		{
+			.addr = anysee_tda18212_config.i2c_address,
+			.flags = 0,
+			.len = 1,
+			.buf = "\x00",
+		}, {
+			.addr = anysee_tda18212_config.i2c_address,
+			.flags = I2C_M_RD,
+			.len = 1,
+			.buf = &tmp,
+		}
+	};
 
-	/* check which hardware we have
-	   We must do this call two times to get reliable values (hw bug). */
+	/* Check which hardware we have.
+	 * We must do this call two times to get reliable values (hw bug).
+	 */
 	ret = anysee_get_hw_info(adap->dev, hw_info);
 	if (ret)
-		return ret;
+		goto error;
+
 	ret = anysee_get_hw_info(adap->dev, hw_info);
 	if (ret)
-		return ret;
+		goto error;
 
 	/* Meaning of these info bytes are guessed. */
-	info("firmware version:%d.%d.%d hardware id:%d",
-		0, hw_info[1], hw_info[2], hw_info[0]);
+	info("firmware version:%d.%d hardware id:%d",
+		hw_info[1], hw_info[2], hw_info[0]);
 
-	ret = anysee_read_reg(adap->dev, 0xb0, &io_d); /* IO port D */
-	if (ret)
-		return ret;
-	deb_info("%s: IO port D:%02x\n", __func__, io_d);
+	state->hw = hw_info[0];
 
-	/* Select demod using trial and error method. */
+	switch (state->hw) {
+	case ANYSEE_HW_02: /* 2 */
+		/* E30 */
 
-	/* Try to attach demodulator in following order:
-	      model      demod     hw  firmware
-	   1. E30        MT352     02  0.2.1
-	   2. E30        ZL10353   02  0.2.1
-	   3. E30 Combo  ZL10353   0f  0.1.2    DVB-T/C combo
-	   4. E30 Plus   ZL10353   06  0.1.0
-	   5. E30C Plus  TDA10023  0a  0.1.0    rev 0.2
-	      E30C Plus  TDA10023  0f  0.1.2    rev 0.4
-	      E30 Combo  TDA10023  0f  0.1.2    DVB-T/C combo
-	*/
+		/* attach demod */
+		adap->fe = dvb_attach(mt352_attach, &anysee_mt352_config,
+			&adap->dev->i2c_adap);
+		if (adap->fe)
+			break;
 
-	/* Zarlink MT352 DVB-T demod inside of Samsung DNOS404ZH102A NIM */
-	adap->fe = dvb_attach(mt352_attach, &anysee_mt352_config,
-			      &adap->dev->i2c_adap);
-	if (adap->fe != NULL) {
-		state->tuner = DVB_PLL_THOMSON_DTT7579;
-		return 0;
-	}
+		/* attach demod */
+		adap->fe = dvb_attach(zl10353_attach, &anysee_zl10353_config,
+			&adap->dev->i2c_adap);
 
-	/* Zarlink ZL10353 DVB-T demod inside of Samsung DNOS404ZH103A NIM */
-	adap->fe = dvb_attach(zl10353_attach, &anysee_zl10353_config,
-			      &adap->dev->i2c_adap);
-	if (adap->fe != NULL) {
-		state->tuner = DVB_PLL_THOMSON_DTT7579;
-		return 0;
-	}
+		break;
+	case ANYSEE_HW_507CD: /* 6 */
+		/* E30 Plus */
 
-	/* for E30 Combo Plus DVB-T demodulator */
-	if (dvb_usb_anysee_delsys) {
-		ret = anysee_write_reg(adap->dev, 0xb0, 0x01);
+		/* enable DVB-T demod on IOD[0] */
+		ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (1 << 0), 0x01);
 		if (ret)
-			return ret;
+			goto error;
 
-		/* Zarlink ZL10353 DVB-T demod */
+		/* enable transport stream on IOA[7] */
+		ret = anysee_wr_reg_mask(adap->dev, REG_IOA, (0 << 7), 0x80);
+		if (ret)
+			goto error;
+
+		/* attach demod */
 		adap->fe = dvb_attach(zl10353_attach, &anysee_zl10353_config,
-				      &adap->dev->i2c_adap);
-		if (adap->fe != NULL) {
-			state->tuner = DVB_PLL_SAMSUNG_DTOS403IH102A;
-			return 0;
+			&adap->dev->i2c_adap);
+
+		break;
+	case ANYSEE_HW_507DC: /* 10 */
+		/* E30 C Plus */
+
+		/* enable DVB-C demod on IOD[0] */
+		ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (1 << 0), 0x01);
+		if (ret)
+			goto error;
+
+		/* attach demod */
+		adap->fe = dvb_attach(tda10023_attach, &anysee_tda10023_config,
+			&adap->dev->i2c_adap, 0x48);
+
+		break;
+	case ANYSEE_HW_507SI: /* 11 */
+		/* E30 S2 Plus */
+
+		/* enable DVB-S/S2 demod on IOD[0] */
+		ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (1 << 0), 0x01);
+		if (ret)
+			goto error;
+
+		/* attach demod */
+		adap->fe = dvb_attach(cx24116_attach, &anysee_cx24116_config,
+			&adap->dev->i2c_adap);
+
+		break;
+	case ANYSEE_HW_507FA: /* 15 */
+		/* E30 Combo Plus */
+		/* E30 C Plus */
+
+		/* enable tuner on IOE[4] */
+		ret = anysee_wr_reg_mask(adap->dev, REG_IOE, (1 << 4), 0x10);
+		if (ret)
+			goto error;
+
+		/* probe TDA18212 */
+		tmp = 0;
+		ret = i2c_transfer(&adap->dev->i2c_adap, msg, 2);
+		if (ret == 2 && tmp == 0xc7)
+			deb_info("%s: TDA18212 found\n", __func__);
+		else
+			tmp = 0;
+
+		/* disable tuner on IOE[4] */
+		ret = anysee_wr_reg_mask(adap->dev, REG_IOE, (0 << 4), 0x10);
+		if (ret)
+			goto error;
+
+		if (dvb_usb_anysee_delsys) {
+			/* disable DVB-C demod on IOD[5] */
+			ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (0 << 5),
+				0x20);
+			if (ret)
+				goto error;
+
+			/* enable DVB-T demod on IOD[0] */
+			ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (1 << 0),
+				0x01);
+			if (ret)
+				goto error;
+
+			/* attach demod */
+			if (tmp == 0xc7) {
+				/* TDA18212 config */
+				adap->fe = dvb_attach(zl10353_attach,
+					&anysee_zl10353_tda18212_config2,
+					&adap->dev->i2c_adap);
+			} else {
+				/* PLL config */
+				adap->fe = dvb_attach(zl10353_attach,
+					&anysee_zl10353_config,
+					&adap->dev->i2c_adap);
+			}
+		} else {
+			/* disable DVB-T demod on IOD[0] */
+			ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (0 << 0),
+				0x01);
+			if (ret)
+				goto error;
+
+			/* enable DVB-C demod on IOD[5] */
+			ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (1 << 5),
+				0x20);
+			if (ret)
+				goto error;
+
+			/* attach demod */
+			if (tmp == 0xc7) {
+				/* TDA18212 config */
+				adap->fe = dvb_attach(tda10023_attach,
+					&anysee_tda10023_tda18212_config,
+					&adap->dev->i2c_adap, 0x48);
+			} else {
+				/* PLL config */
+				adap->fe = dvb_attach(tda10023_attach,
+					&anysee_tda10023_config,
+					&adap->dev->i2c_adap, 0x48);
+			}
 		}
-	}
 
-	/* connect demod on IO port D for TDA10023 & ZL10353 */
-	ret = anysee_write_reg(adap->dev, 0xb0, 0x25);
-	if (ret)
-		return ret;
+		break;
+	case ANYSEE_HW_508TC: /* 18 */
+		/* E7 TC */
 
-	/* Zarlink ZL10353 DVB-T demod inside of Samsung DNOS404ZH103A NIM */
-	adap->fe = dvb_attach(zl10353_attach, &anysee_zl10353_config,
-			      &adap->dev->i2c_adap);
-	if (adap->fe != NULL) {
-		state->tuner = DVB_PLL_THOMSON_DTT7579;
-		return 0;
-	}
+		/* enable transport stream on IOA[7] */
+		ret = anysee_wr_reg_mask(adap->dev, REG_IOA, (1 << 7), 0x80);
+		if (ret)
+			goto error;
 
-	/* IO port E - E30C rev 0.4 board requires this */
-	ret = anysee_write_reg(adap->dev, 0xb1, 0xa7);
-	if (ret)
-		return ret;
+		if (dvb_usb_anysee_delsys) {
+			/* disable DVB-C demod on IOD[5] */
+			ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (0 << 5),
+				0x20);
+			if (ret)
+				goto error;
 
-	/* Philips TDA10023 DVB-C demod */
-	adap->fe = dvb_attach(tda10023_attach, &anysee_tda10023_config,
-			      &adap->dev->i2c_adap, 0x48);
-	if (adap->fe != NULL) {
-		state->tuner = DVB_PLL_SAMSUNG_DTOS403IH102A;
-		return 0;
-	}
+			/* enable DVB-T demod on IOD[6] */
+			ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (1 << 6),
+				0x40);
+			if (ret)
+				goto error;
 
-	/* return IO port D to init value for safe */
-	ret = anysee_write_reg(adap->dev, 0xb0, io_d);
-	if (ret)
-		return ret;
+			/* enable IF route on IOE[0] */
+			ret = anysee_wr_reg_mask(adap->dev, REG_IOE, (0 << 0),
+				0x01);
+			if (ret)
+				goto error;
 
-	err("Unknown Anysee version: %02x %02x %02x. "\
-	    "Please report the <linux-dvb@linuxtv.org>.",
-	    hw_info[0], hw_info[1], hw_info[2]);
+			/* attach demod */
+			adap->fe = dvb_attach(zl10353_attach,
+				&anysee_zl10353_tda18212_config,
+				&adap->dev->i2c_adap);
+		} else {
+			/* disable DVB-T demod on IOD[6] */
+			ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (0 << 6),
+				0x40);
+			if (ret)
+				goto error;
 
-	return -ENODEV;
+			/* enable DVB-C demod on IOD[5] */
+			ret = anysee_wr_reg_mask(adap->dev, REG_IOD, (1 << 5),
+				0x20);
+			if (ret)
+				goto error;
+
+			/* enable IF route on IOE[0] */
+			ret = anysee_wr_reg_mask(adap->dev, REG_IOE, (1 << 0),
+				0x01);
+			if (ret)
+				goto error;
+
+			/* attach demod */
+			adap->fe = dvb_attach(tda10023_attach,
+				&anysee_tda10023_tda18212_config,
+				&adap->dev->i2c_adap, 0x48);
+		}
+
+		break;
+	case ANYSEE_HW_508S2: /* 19 */
+		/* E7 S2 */
+
+		/* enable transport stream on IOA[7] */
+		ret = anysee_wr_reg_mask(adap->dev, REG_IOA, (1 << 7), 0x80);
+		if (ret)
+			goto error;
+
+		/* enable DVB-S/S2 demod on IOE[5] */
+		ret = anysee_wr_reg_mask(adap->dev, REG_IOE, (1 << 5), 0x20);
+		if (ret)
+			goto error;
+
+		/* attach demod */
+		adap->fe = dvb_attach(stv0900_attach, &anysee_stv0900_config,
+			&adap->dev->i2c_adap, 0);
+
+		break;
+	}
+
+	if (!adap->fe) {
+		/* we have no frontend :-( */
+		ret = -ENODEV;
+		err("Unsupported Anysee version. " \
+			"Please report the <linux-media@vger.kernel.org>.");
+	}
+error:
+	return ret;
 }
 
 static int anysee_tuner_attach(struct dvb_usb_adapter *adap)
 {
 	struct anysee_state *state = adap->dev->priv;
+	struct dvb_frontend *fe;
+	int ret;
 	deb_info("%s:\n", __func__);
 
-	switch (state->tuner) {
-	case DVB_PLL_THOMSON_DTT7579:
-		/* Thomson dtt7579 (not sure) PLL inside of:
-		   Samsung DNOS404ZH102A NIM
-		   Samsung DNOS404ZH103A NIM */
-		dvb_attach(dvb_pll_attach, adap->fe, 0x61,
-			   NULL, DVB_PLL_THOMSON_DTT7579);
+	switch (state->hw) {
+	case ANYSEE_HW_02: /* 2 */
+		/* E30 */
+
+		/* attach tuner */
+		fe = dvb_attach(dvb_pll_attach, adap->fe, (0xc2 >> 1),
+			NULL, DVB_PLL_THOMSON_DTT7579);
+
 		break;
-	case DVB_PLL_SAMSUNG_DTOS403IH102A:
-		/* Unknown PLL inside of Samsung DTOS403IH102A tuner module */
-		dvb_attach(dvb_pll_attach, adap->fe, 0xc0,
-			   &adap->dev->i2c_adap, DVB_PLL_SAMSUNG_DTOS403IH102A);
+	case ANYSEE_HW_507CD: /* 6 */
+		/* E30 Plus */
+
+		/* attach tuner */
+		fe = dvb_attach(dvb_pll_attach, adap->fe, (0xc2 >> 1),
+			&adap->dev->i2c_adap, DVB_PLL_THOMSON_DTT7579);
+
+		break;
+	case ANYSEE_HW_507DC: /* 10 */
+		/* E30 C Plus */
+
+		/* attach tuner */
+		fe = dvb_attach(dvb_pll_attach, adap->fe, (0xc0 >> 1),
+			&adap->dev->i2c_adap, DVB_PLL_SAMSUNG_DTOS403IH102A);
+
 		break;
+	case ANYSEE_HW_507SI: /* 11 */
+		/* E30 S2 Plus */
+
+		/* attach LNB controller */
+		fe = dvb_attach(isl6423_attach, adap->fe, &adap->dev->i2c_adap,
+			&anysee_isl6423_config);
+
+		break;
+	case ANYSEE_HW_507FA: /* 15 */
+		/* E30 Combo Plus */
+		/* E30 C Plus */
+
+		if (dvb_usb_anysee_delsys) {
+			/* enable DVB-T tuner on IOE[0] */
+			ret = anysee_wr_reg_mask(adap->dev, REG_IOE, (0 << 0),
+				0x01);
+			if (ret)
+				goto error;
+		} else {
+			/* enable DVB-C tuner on IOE[0] */
+			ret = anysee_wr_reg_mask(adap->dev, REG_IOE, (1 << 0),
+				0x01);
+			if (ret)
+				goto error;
+		}
+
+		/* Try first attach TDA18212 silicon tuner on IOE[4], if that
+		 * fails attach old simple PLL. */
+
+		/* enable tuner on IOE[4] */
+		ret = anysee_wr_reg_mask(adap->dev, REG_IOE, (1 << 4), 0x10);
+		if (ret)
+			goto error;
+
+		/* attach tuner */
+		fe = dvb_attach(tda18212_attach, adap->fe, &adap->dev->i2c_adap,
+			&anysee_tda18212_config);
+		if (fe)
+			break;
+
+		/* disable tuner on IOE[4] */
+		ret = anysee_wr_reg_mask(adap->dev, REG_IOE, (0 << 4), 0x10);
+		if (ret)
+			goto error;
+
+		/* attach tuner */
+		fe = dvb_attach(dvb_pll_attach, adap->fe, (0xc0 >> 1),
+			&adap->dev->i2c_adap, DVB_PLL_SAMSUNG_DTOS403IH102A);
+
+		break;
+	case ANYSEE_HW_508TC: /* 18 */
+		/* E7 TC */
+
+		/* enable tuner on IOE[4] */
+		ret = anysee_wr_reg_mask(adap->dev, REG_IOE, (1 << 4), 0x10);
+		if (ret)
+			goto error;
+
+		/* attach tuner */
+		fe = dvb_attach(tda18212_attach, adap->fe, &adap->dev->i2c_adap,
+			&anysee_tda18212_config);
+
+		break;
+	case ANYSEE_HW_508S2: /* 19 */
+		/* E7 S2 */
+
+		/* attach tuner */
+		fe = dvb_attach(stv6110_attach, adap->fe,
+			&anysee_stv6110_config, &adap->dev->i2c_adap);
+
+		if (fe) {
+			/* attach LNB controller */
+			fe = dvb_attach(isl6423_attach, adap->fe,
+				&adap->dev->i2c_adap, &anysee_isl6423_config);
+		}
+
+		break;
+	default:
+		fe = NULL;
 	}
 
-	return 0;
+	if (fe)
+		ret = 0;
+	else
+		ret = -ENODEV;
+
+error:
+	return ret;
 }
 
 static int anysee_rc_query(struct dvb_usb_device *d)
diff -druN linux-2.6.39-libre/drivers/media/dvb/dvb-usb/anysee.h linux-3.0-rc7-libre/drivers/media/dvb/dvb-usb/anysee.h
--- linux-2.6.39-libre/drivers/media/dvb/dvb-usb/anysee.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/dvb/dvb-usb/anysee.h	2011-07-11 19:51:52.000000000 -0400
@@ -57,10 +57,29 @@
 };
 
 struct anysee_state {
-	u8 tuner;
+	u8 hw; /* PCB ID */
 	u8 seq;
 };
 
+#define ANYSEE_HW_02     2 /* E30 */
+#define ANYSEE_HW_507CD  6 /* E30 Plus */
+#define ANYSEE_HW_507DC 10 /* E30 C Plus */
+#define ANYSEE_HW_507SI 11 /* E30 S2 Plus */
+#define ANYSEE_HW_507FA 15 /* E30 Combo Plus / E30 C Plus */
+#define ANYSEE_HW_508TC 18 /* E7 TC */
+#define ANYSEE_HW_508S2 19 /* E7 S2 */
+
+#define REG_IOA       0x80 /* Port A (bit addressable) */
+#define REG_IOB       0x90 /* Port B (bit addressable) */
+#define REG_IOC       0xa0 /* Port C (bit addressable) */
+#define REG_IOD       0xb0 /* Port D (bit addressable) */
+#define REG_IOE       0xb1 /* Port E (NOT bit addressable) */
+#define REG_OEA       0xb2 /* Port A Output Enable */
+#define REG_OEB       0xb3 /* Port B Output Enable */
+#define REG_OEC       0xb4 /* Port C Output Enable */
+#define REG_OED       0xb5 /* Port D Output Enable */
+#define REG_OEE       0xb6 /* Port E Output Enable */
+
 #endif
 
 /***************************************************************************
@@ -136,7 +155,7 @@
 ----------------------------------------------------------------------------
 |    04 | 0x00
 ----------------------------------------------------------------------------
-|    05 | 0x01
+|    05 | data length
 ----------------------------------------------------------------------------
 | 06-59 | don't care
 ----------------------------------------------------------------------------
diff -druN linux-2.6.39-libre/drivers/media/dvb/dvb-usb/au6610.c linux-3.0-rc7-libre/drivers/media/dvb/dvb-usb/au6610.c
--- linux-2.6.39-libre/drivers/media/dvb/dvb-usb/au6610.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/dvb/dvb-usb/au6610.c	2011-07-11 19:51:52.000000000 -0400
@@ -33,8 +33,16 @@
 {
 	int ret;
 	u16 index;
-	u8 usb_buf[6]; /* enough for all known requests,
-			  read returns 5 and write 6 bytes */
+	u8 *usb_buf;
+
+	/*
+	 * allocate enough for all known requests,
+	 * read returns 5 and write 6 bytes
+	 */
+	usb_buf = kmalloc(6, GFP_KERNEL);
+	if (!usb_buf)
+		return -ENOMEM;
+
 	switch (wlen) {
 	case 1:
 		index = wbuf[0] << 8;
@@ -45,14 +53,15 @@
 		break;
 	default:
 		warn("wlen = %x, aborting.", wlen);
-		return -EINVAL;
+		ret = -EINVAL;
+		goto error;
 	}
 
 	ret = usb_control_msg(d->udev, usb_rcvctrlpipe(d->udev, 0), operation,
 			      USB_TYPE_VENDOR|USB_DIR_IN, addr << 1, index,
-			      usb_buf, sizeof(usb_buf), AU6610_USB_TIMEOUT);
+			      usb_buf, 6, AU6610_USB_TIMEOUT);
 	if (ret < 0)
-		return ret;
+		goto error;
 
 	switch (operation) {
 	case AU6610_REQ_I2C_READ:
@@ -60,7 +69,8 @@
 		/* requested value is always 5th byte in buffer */
 		rbuf[0] = usb_buf[4];
 	}
-
+error:
+	kfree(usb_buf);
 	return ret;
 }
 
diff -druN linux-2.6.39-libre/drivers/media/dvb/dvb-usb/ce6230.c linux-3.0-rc7-libre/drivers/media/dvb/dvb-usb/ce6230.c
--- linux-2.6.39-libre/drivers/media/dvb/dvb-usb/ce6230.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/dvb/dvb-usb/ce6230.c	2011-07-11 19:51:52.000000000 -0400
@@ -39,7 +39,7 @@
 	u8 requesttype;
 	u16 value;
 	u16 index;
-	u8 buf[req->data_len];
+	u8 *buf;
 
 	request = req->cmd;
 	value = req->value;
@@ -62,6 +62,12 @@
 		goto error;
 	}
 
+	buf = kmalloc(req->data_len, GFP_KERNEL);
+	if (!buf) {
+		ret = -ENOMEM;
+		goto error;
+	}
+
 	if (requesttype == (USB_TYPE_VENDOR | USB_DIR_OUT)) {
 		/* write */
 		memcpy(buf, req->data, req->data_len);
@@ -74,7 +80,7 @@
 	msleep(1); /* avoid I2C errors */
 
 	ret = usb_control_msg(udev, pipe, request, requesttype, value, index,
-				buf, sizeof(buf), CE6230_USB_TIMEOUT);
+				buf, req->data_len, CE6230_USB_TIMEOUT);
 
 	ce6230_debug_dump(request, requesttype, value, index, buf,
 		req->data_len, deb_xfer);
@@ -88,6 +94,7 @@
 	if (!ret && requesttype == (USB_TYPE_VENDOR | USB_DIR_IN))
 		memcpy(req->data, buf, req->data_len);
 
+	kfree(buf);
 error:
 	return ret;
 }
diff -druN linux-2.6.39-libre/drivers/media/dvb/dvb-usb/dib0700_core.c linux-3.0-rc7-libre/drivers/media/dvb/dvb-usb/dib0700_core.c
--- linux-2.6.39-libre/drivers/media/dvb/dvb-usb/dib0700_core.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/dvb/dvb-usb/dib0700_core.c	2011-07-11 19:51:52.000000000 -0400
@@ -27,19 +27,25 @@
 int dib0700_get_version(struct dvb_usb_device *d, u32 *hwversion,
 			u32 *romversion, u32 *ramversion, u32 *fwtype)
 {
-	u8 b[16];
-	int ret = usb_control_msg(d->udev, usb_rcvctrlpipe(d->udev, 0),
+	struct dib0700_state *st = d->priv;
+	int ret;
+
+	ret = usb_control_msg(d->udev, usb_rcvctrlpipe(d->udev, 0),
 				  REQUEST_GET_VERSION,
 				  USB_TYPE_VENDOR | USB_DIR_IN, 0, 0,
-				  b, sizeof(b), USB_CTRL_GET_TIMEOUT);
+				  st->buf, 16, USB_CTRL_GET_TIMEOUT);
 	if (hwversion != NULL)
-		*hwversion  = (b[0] << 24)  | (b[1] << 16)  | (b[2] << 8)  | b[3];
+		*hwversion  = (st->buf[0] << 24)  | (st->buf[1] << 16)  |
+			(st->buf[2] << 8)  | st->buf[3];
 	if (romversion != NULL)
-		*romversion = (b[4] << 24)  | (b[5] << 16)  | (b[6] << 8)  | b[7];
+		*romversion = (st->buf[4] << 24)  | (st->buf[5] << 16)  |
+			(st->buf[6] << 8)  | st->buf[7];
 	if (ramversion != NULL)
-		*ramversion = (b[8] << 24)  | (b[9] << 16)  | (b[10] << 8) | b[11];
+		*ramversion = (st->buf[8] << 24)  | (st->buf[9] << 16)  |
+			(st->buf[10] << 8) | st->buf[11];
 	if (fwtype != NULL)
-		*fwtype     = (b[12] << 24) | (b[13] << 16) | (b[14] << 8) | b[15];
+		*fwtype     = (st->buf[12] << 24) | (st->buf[13] << 16) |
+			(st->buf[14] << 8) | st->buf[15];
 	return ret;
 }
 
@@ -101,24 +107,31 @@
 
 int dib0700_set_gpio(struct dvb_usb_device *d, enum dib07x0_gpios gpio, u8 gpio_dir, u8 gpio_val)
 {
-	u8 buf[3] = { REQUEST_SET_GPIO, gpio, ((gpio_dir & 0x01) << 7) | ((gpio_val & 0x01) << 6) };
-	return dib0700_ctrl_wr(d, buf, sizeof(buf));
+	struct dib0700_state *st = d->priv;
+	s16 ret;
+
+	st->buf[0] = REQUEST_SET_GPIO;
+	st->buf[1] = gpio;
+	st->buf[2] = ((gpio_dir & 0x01) << 7) | ((gpio_val & 0x01) << 6);
+
+	ret = dib0700_ctrl_wr(d, st->buf, 3);
+
+	return ret;
 }
 
 static int dib0700_set_usb_xfer_len(struct dvb_usb_device *d, u16 nb_ts_packets)
 {
 	struct dib0700_state *st = d->priv;
-	u8 b[3];
 	int ret;
 
 	if (st->fw_version >= 0x10201) {
-		b[0] = REQUEST_SET_USB_XFER_LEN;
-		b[1] = (nb_ts_packets >> 8) & 0xff;
-		b[2] = nb_ts_packets & 0xff;
+		st->buf[0] = REQUEST_SET_USB_XFER_LEN;
+		st->buf[1] = (nb_ts_packets >> 8) & 0xff;
+		st->buf[2] = nb_ts_packets & 0xff;
 
 		deb_info("set the USB xfer len to %i Ts packet\n", nb_ts_packets);
 
-		ret = dib0700_ctrl_wr(d, b, sizeof(b));
+		ret = dib0700_ctrl_wr(d, st->buf, 3);
 	} else {
 		deb_info("this firmware does not allow to change the USB xfer len\n");
 		ret = -EIO;
@@ -137,11 +150,11 @@
 	   properly support i2c read calls not preceded by a write */
 
 	struct dvb_usb_device *d = i2c_get_adapdata(adap);
+	struct dib0700_state *st = d->priv;
 	uint8_t bus_mode = 1;  /* 0=eeprom bus, 1=frontend bus */
 	uint8_t gen_mode = 0; /* 0=master i2c, 1=gpio i2c */
 	uint8_t en_start = 0;
 	uint8_t en_stop = 0;
-	uint8_t buf[255]; /* TBV: malloc ? */
 	int result, i;
 
 	/* Ensure nobody else hits the i2c bus while we're sending our
@@ -195,24 +208,24 @@
 
 		} else {
 			/* Write request */
-			buf[0] = REQUEST_NEW_I2C_WRITE;
-			buf[1] = msg[i].addr << 1;
-			buf[2] = (en_start << 7) | (en_stop << 6) |
+			st->buf[0] = REQUEST_NEW_I2C_WRITE;
+			st->buf[1] = msg[i].addr << 1;
+			st->buf[2] = (en_start << 7) | (en_stop << 6) |
 				(msg[i].len & 0x3F);
 			/* I2C ctrl + FE bus; */
-			buf[3] = ((gen_mode << 6) & 0xC0) |
+			st->buf[3] = ((gen_mode << 6) & 0xC0) |
 				 ((bus_mode << 4) & 0x30);
 			/* The Actual i2c payload */
-			memcpy(&buf[4], msg[i].buf, msg[i].len);
+			memcpy(&st->buf[4], msg[i].buf, msg[i].len);
 
 			deb_data(">>> ");
-			debug_dump(buf, msg[i].len + 4, deb_data);
+			debug_dump(st->buf, msg[i].len + 4, deb_data);
 
 			result = usb_control_msg(d->udev,
 						 usb_sndctrlpipe(d->udev, 0),
 						 REQUEST_NEW_I2C_WRITE,
 						 USB_TYPE_VENDOR | USB_DIR_OUT,
-						 0, 0, buf, msg[i].len + 4,
+						 0, 0, st->buf, msg[i].len + 4,
 						 USB_CTRL_GET_TIMEOUT);
 			if (result < 0) {
 				deb_info("i2c write error (status = %d)\n", result);
@@ -231,27 +244,29 @@
 				   struct i2c_msg *msg, int num)
 {
 	struct dvb_usb_device *d = i2c_get_adapdata(adap);
+	struct dib0700_state *st = d->priv;
 	int i,len;
-	u8 buf[255];
 
 	if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
 		return -EAGAIN;
 
 	for (i = 0; i < num; i++) {
 		/* fill in the address */
-		buf[1] = msg[i].addr << 1;
+		st->buf[1] = msg[i].addr << 1;
 		/* fill the buffer */
-		memcpy(&buf[2], msg[i].buf, msg[i].len);
+		memcpy(&st->buf[2], msg[i].buf, msg[i].len);
 
 		/* write/read request */
 		if (i+1 < num && (msg[i+1].flags & I2C_M_RD)) {
-			buf[0] = REQUEST_I2C_READ;
-			buf[1] |= 1;
+			st->buf[0] = REQUEST_I2C_READ;
+			st->buf[1] |= 1;
 
 			/* special thing in the current firmware: when length is zero the read-failed */
-			if ((len = dib0700_ctrl_rd(d, buf, msg[i].len + 2, msg[i+1].buf, msg[i+1].len)) <= 0) {
+			len = dib0700_ctrl_rd(d, st->buf, msg[i].len + 2,
+					msg[i+1].buf, msg[i+1].len);
+			if (len <= 0) {
 				deb_info("I2C read failed on address 0x%02x\n",
-					 msg[i].addr);
+						msg[i].addr);
 				break;
 			}
 
@@ -259,13 +274,13 @@
 
 			i++;
 		} else {
-			buf[0] = REQUEST_I2C_WRITE;
-			if (dib0700_ctrl_wr(d, buf, msg[i].len + 2) < 0)
+			st->buf[0] = REQUEST_I2C_WRITE;
+			if (dib0700_ctrl_wr(d, st->buf, msg[i].len + 2) < 0)
 				break;
 		}
 	}
-
 	mutex_unlock(&d->i2c_mutex);
+
 	return i;
 }
 
@@ -297,15 +312,23 @@
 int dib0700_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),
+	s16 ret;
+	u8 *b;
+
+	b = kmalloc(16, GFP_KERNEL);
+	if (!b)
+		return	-ENOMEM;
+
+
+	ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
 		REQUEST_GET_VERSION, USB_TYPE_VENDOR | USB_DIR_IN, 0, 0, b, 16, USB_CTRL_GET_TIMEOUT);
 
 	deb_info("FW GET_VERSION length: %d\n",ret);
 
 	*cold = ret <= 0;
-
 	deb_info("cold: %d\n", *cold);
+
+	kfree(b);
 	return 0;
 }
 
@@ -313,43 +336,50 @@
 	u8 pll_src, u8 pll_range, u8 clock_gpio3, u16 pll_prediv,
 	u16 pll_loopdiv, u16 free_div, u16 dsuScaler)
 {
-	u8 b[10];
-	b[0] = REQUEST_SET_CLOCK;
-	b[1] = (en_pll << 7) | (pll_src << 6) | (pll_range << 5) | (clock_gpio3 << 4);
-	b[2] = (pll_prediv >> 8)  & 0xff; // MSB
-	b[3] =  pll_prediv        & 0xff; // LSB
-	b[4] = (pll_loopdiv >> 8) & 0xff; // MSB
-	b[5] =  pll_loopdiv       & 0xff; // LSB
-	b[6] = (free_div >> 8)    & 0xff; // MSB
-	b[7] =  free_div          & 0xff; // LSB
-	b[8] = (dsuScaler >> 8)   & 0xff; // MSB
-	b[9] =  dsuScaler         & 0xff; // LSB
+	struct dib0700_state *st = d->priv;
+	s16 ret;
 
-	return dib0700_ctrl_wr(d, b, 10);
+	st->buf[0] = REQUEST_SET_CLOCK;
+	st->buf[1] = (en_pll << 7) | (pll_src << 6) |
+		(pll_range << 5) | (clock_gpio3 << 4);
+	st->buf[2] = (pll_prediv >> 8)  & 0xff; /* MSB */
+	st->buf[3] =  pll_prediv        & 0xff; /* LSB */
+	st->buf[4] = (pll_loopdiv >> 8) & 0xff; /* MSB */
+	st->buf[5] =  pll_loopdiv       & 0xff; /* LSB */
+	st->buf[6] = (free_div >> 8)    & 0xff; /* MSB */
+	st->buf[7] =  free_div          & 0xff; /* LSB */
+	st->buf[8] = (dsuScaler >> 8)   & 0xff; /* MSB */
+	st->buf[9] =  dsuScaler         & 0xff; /* LSB */
+
+	ret = dib0700_ctrl_wr(d, st->buf, 10);
+
+	return ret;
 }
 
 int dib0700_set_i2c_speed(struct dvb_usb_device *d, u16 scl_kHz)
 {
+	struct dib0700_state *st = d->priv;
 	u16 divider;
-	u8 b[8];
 
 	if (scl_kHz == 0)
 		return -EINVAL;
 
-	b[0] = REQUEST_SET_I2C_PARAM;
+	st->buf[0] = REQUEST_SET_I2C_PARAM;
 	divider = (u16) (30000 / scl_kHz);
-	b[2] = (u8) (divider >> 8);
-	b[3] = (u8) (divider & 0xff);
+	st->buf[1] = 0;
+	st->buf[2] = (u8) (divider >> 8);
+	st->buf[3] = (u8) (divider & 0xff);
 	divider = (u16) (72000 / scl_kHz);
-	b[4] = (u8) (divider >> 8);
-	b[5] = (u8) (divider & 0xff);
+	st->buf[4] = (u8) (divider >> 8);
+	st->buf[5] = (u8) (divider & 0xff);
 	divider = (u16) (72000 / scl_kHz); /* clock: 72MHz */
-	b[6] = (u8) (divider >> 8);
-	b[7] = (u8) (divider & 0xff);
+	st->buf[6] = (u8) (divider >> 8);
+	st->buf[7] = (u8) (divider & 0xff);
 
 	deb_info("setting I2C speed: %04x %04x %04x (%d kHz).",
-		(b[2] << 8) | (b[3]), (b[4] << 8) | b[5], (b[6] << 8) | b[7], scl_kHz);
-	return dib0700_ctrl_wr(d, b, 8);
+		(st->buf[2] << 8) | (st->buf[3]), (st->buf[4] << 8) |
+		st->buf[5], (st->buf[6] << 8) | st->buf[7], scl_kHz);
+	return dib0700_ctrl_wr(d, st->buf, 8);
 }
 
 
@@ -364,32 +394,45 @@
 
 static int dib0700_jumpram(struct usb_device *udev, u32 address)
 {
-	int ret, actlen;
-	u8 buf[8] = { REQUEST_JUMPRAM, 0, 0, 0,
-		(address >> 24) & 0xff,
-		(address >> 16) & 0xff,
-		(address >> 8)  & 0xff,
-		 address        & 0xff };
+	int ret = 0, actlen;
+	u8 *buf;
+
+	buf = kmalloc(8, GFP_KERNEL);
+	if (!buf)
+		return -ENOMEM;
+	buf[0] = REQUEST_JUMPRAM;
+	buf[1] = 0;
+	buf[2] = 0;
+	buf[3] = 0;
+	buf[4] = (address >> 24) & 0xff;
+	buf[5] = (address >> 16) & 0xff;
+	buf[6] = (address >> 8)  & 0xff;
+	buf[7] =  address        & 0xff;
 
 	if ((ret = usb_bulk_msg(udev, usb_sndbulkpipe(udev, 0x01),buf,8,&actlen,1000)) < 0) {
 		deb_fw("jumpram to 0x%x failed\n",address);
-		return ret;
+		goto out;
 	}
 	if (actlen != 8) {
 		deb_fw("jumpram to 0x%x failed\n",address);
-		return -EIO;
+		ret = -EIO;
+		goto out;
 	}
-	return 0;
+out:
+	kfree(buf);
+	return ret;
 }
 
 int dib0700_download_firmware(struct usb_device *udev, const struct firmware *fw)
 {
 	struct hexline hx;
 	int pos = 0, ret, act_len, i, adap_num;
-	u8 b[16];
+	u8 *buf;
 	u32 fw_version;
 
-	u8 buf[260];
+	buf = kmalloc(260, GFP_KERNEL);
+	if (!buf)
+		return -ENOMEM;
 
 	while ((ret = dvb_usb_get_hexline(fw, &hx, &pos)) > 0) {
 		deb_fwdata("writing to address 0x%08x (buffer: 0x%02x %02x)\n",
@@ -411,7 +454,7 @@
 
 		if (ret < 0) {
 			err("firmware download failed at %d with %d",pos,ret);
-			return ret;
+			goto out;
 		}
 	}
 
@@ -432,8 +475,8 @@
 	usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
 				  REQUEST_GET_VERSION,
 				  USB_TYPE_VENDOR | USB_DIR_IN, 0, 0,
-				  b, sizeof(b), USB_CTRL_GET_TIMEOUT);
-	fw_version = (b[8] << 24) | (b[9] << 16) | (b[10] << 8) | b[11];
+				  buf, 16, USB_CTRL_GET_TIMEOUT);
+	fw_version = (buf[8] << 24) | (buf[9] << 16) | (buf[10] << 8) | buf[11];
 
 	/* set the buffer size - DVB-USB is allocating URB buffers
 	 * only after the firwmare download was successful */
@@ -451,14 +494,14 @@
 			}
 		}
 	}
-
+out:
+	kfree(buf);
 	return ret;
 }
 
 int dib0700_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
 {
 	struct dib0700_state *st = adap->dev->priv;
-	u8 b[4];
 	int ret;
 
 	if ((onoff != 0) && (st->fw_version >= 0x10201)) {
@@ -472,15 +515,17 @@
 		}
 	}
 
-	b[0] = REQUEST_ENABLE_VIDEO;
-	b[1] = (onoff << 4) | 0x00; /* this bit gives a kind of command, rather than enabling something or not */
+	st->buf[0] = REQUEST_ENABLE_VIDEO;
+	/* this bit gives a kind of command,
+	 * rather than enabling something or not */
+	st->buf[1] = (onoff << 4) | 0x00;
 
 	if (st->disable_streaming_master_mode == 1)
-		b[2] = 0x00;
+		st->buf[2] = 0x00;
 	else
-		b[2] = 0x01 << 4; /* Master mode */
+		st->buf[2] = 0x01 << 4; /* Master mode */
 
-	b[3] = 0x00;
+	st->buf[3] = 0x00;
 
 	deb_info("modifying (%d) streaming state for %d\n", onoff, adap->id);
 
@@ -499,20 +544,23 @@
 			st->channel_state |=	1 << (3-adap->stream.props.endpoint);
 	}
 
-	b[2] |= st->channel_state;
+	st->buf[2] |= st->channel_state;
 
-	deb_info("data for streaming: %x %x\n", b[1], b[2]);
+	deb_info("data for streaming: %x %x\n", st->buf[1], st->buf[2]);
 
-	return dib0700_ctrl_wr(adap->dev, b, 4);
+	return dib0700_ctrl_wr(adap->dev, st->buf, 4);
 }
 
 int dib0700_change_protocol(struct rc_dev *rc, u64 rc_type)
 {
 	struct dvb_usb_device *d = rc->priv;
 	struct dib0700_state *st = d->priv;
-	u8 rc_setup[3] = { REQUEST_SET_RC, 0, 0 };
 	int new_proto, ret;
 
+	st->buf[0] = REQUEST_SET_RC;
+	st->buf[1] = 0;
+	st->buf[2] = 0;
+
 	/* Set the IR mode */
 	if (rc_type == RC_TYPE_RC5)
 		new_proto = 1;
@@ -526,9 +574,9 @@
 	} else
 		return -EINVAL;
 
-	rc_setup[1] = new_proto;
+	st->buf[1] = new_proto;
 
-	ret = dib0700_ctrl_wr(d, rc_setup, sizeof(rc_setup));
+	ret = dib0700_ctrl_wr(d, st->buf, 3);
 	if (ret < 0) {
 		err("ir protocol setup failed");
 		return ret;
@@ -561,7 +609,6 @@
 static void dib0700_rc_urb_completion(struct urb *purb)
 {
 	struct dvb_usb_device *d = purb->context;
-	struct dib0700_state *st;
 	struct dib0700_rc_response *poll_reply;
 	u32 uninitialized_var(keycode);
 	u8 toggle;
@@ -576,7 +623,6 @@
 		return;
 	}
 
-	st = d->priv;
 	poll_reply = purb->transfer_buffer;
 
 	if (purb->status < 0) {
diff -druN linux-2.6.39-libre/drivers/media/dvb/dvb-usb/dib0700_devices.c linux-3.0-rc7-libre/drivers/media/dvb/dvb-usb/dib0700_devices.c
--- linux-2.6.39-libre/drivers/media/dvb/dvb-usb/dib0700_devices.c	2011-05-19 02:08:38.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/dvb/dvb-usb/dib0700_devices.c	2011-07-21 06:50:57.000000000 -0400
@@ -2439,7 +2439,6 @@
 
 	dib0700_set_i2c_speed(adap->dev, 340);
 	adap->fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x90, &tfe7090pvr_dib7000p_config[0]);
-
 	if (adap->fe == NULL)
 		return -ENODEV;
 
@@ -2802,6 +2801,7 @@
 	{ USB_DEVICE(USB_VID_DIBCOM,    USB_PID_DIBCOM_NIM7090) },
 	{ USB_DEVICE(USB_VID_DIBCOM,    USB_PID_DIBCOM_TFE7090PVR) },
 	{ USB_DEVICE(USB_VID_TECHNISAT, USB_PID_TECHNISAT_AIRSTAR_TELESTICK_2) },
+/* 75 */{ USB_DEVICE(USB_VID_MEDION,    USB_PID_CREATIX_CTX1921) },
 	{ 0 }		/* Terminating entry */
 };
 MODULE_DEVICE_TABLE(usb, dib0700_usb_id_table);
@@ -3411,7 +3411,7 @@
 			},
 		},
 
-		.num_device_descs = 3,
+		.num_device_descs = 4,
 		.devices = {
 			{   "DiBcom STK7770P reference design",
 				{ &dib0700_usb_id_table[59], NULL },
@@ -3427,6 +3427,10 @@
 				{ &dib0700_usb_id_table[74], NULL },
 				{ NULL },
 			},
+			{   "Medion CTX1921 DVB-T USB",
+				{ &dib0700_usb_id_table[75], NULL },
+				{ NULL },
+			},
 		},
 
 		.rc.core = {
diff -druN linux-2.6.39-libre/drivers/media/dvb/dvb-usb/dib0700.h linux-3.0-rc7-libre/drivers/media/dvb/dvb-usb/dib0700.h
--- linux-2.6.39-libre/drivers/media/dvb/dvb-usb/dib0700.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/dvb/dvb-usb/dib0700.h	2011-07-11 19:51:52.000000000 -0400
@@ -46,8 +46,9 @@
 	u8 is_dib7000pc;
 	u8 fw_use_new_i2c_api;
 	u8 disable_streaming_master_mode;
-    u32 fw_version;
-    u32 nb_packet_buffer_size;
+	u32 fw_version;
+	u32 nb_packet_buffer_size;
+	u8 buf[255];
 };
 
 extern int dib0700_get_version(struct dvb_usb_device *d, u32 *hwversion,
diff -druN linux-2.6.39-libre/drivers/media/dvb/dvb-usb/dibusb-common.c linux-3.0-rc7-libre/drivers/media/dvb/dvb-usb/dibusb-common.c
--- linux-2.6.39-libre/drivers/media/dvb/dvb-usb/dibusb-common.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/dvb/dvb-usb/dibusb-common.c	2011-07-11 19:51:52.000000000 -0400
@@ -408,7 +408,7 @@
 
 	{ 0x8008, KEY_DVD },
 	{ 0x8009, KEY_AUDIO },
-	{ 0x800a, KEY_MEDIA },      /* Pictures */
+	{ 0x800a, KEY_IMAGES },      /* Pictures */
 	{ 0x800b, KEY_VIDEO },
 
 	{ 0x800c, KEY_BACK },
diff -druN linux-2.6.39-libre/drivers/media/dvb/dvb-usb/dvb-usb-dvb.c linux-3.0-rc7-libre/drivers/media/dvb/dvb-usb/dvb-usb-dvb.c
--- linux-2.6.39-libre/drivers/media/dvb/dvb-usb/dvb-usb-dvb.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/dvb/dvb-usb/dvb-usb-dvb.c	2011-07-11 19:51:52.000000000 -0400
@@ -12,7 +12,7 @@
 static int dvb_usb_ctrl_feed(struct dvb_demux_feed *dvbdmxfeed, int onoff)
 {
 	struct dvb_usb_adapter *adap = dvbdmxfeed->demux->priv;
-	int newfeedcount,ret;
+	int newfeedcount, ret;
 
 	if (adap == NULL)
 		return -ENODEV;
@@ -24,9 +24,13 @@
 		deb_ts("stop feeding\n");
 		usb_urb_kill(&adap->stream);
 
-		if (adap->props.streaming_ctrl != NULL)
-			if ((ret = adap->props.streaming_ctrl(adap,0)))
+		if (adap->props.streaming_ctrl != NULL) {
+			ret = adap->props.streaming_ctrl(adap, 0);
+			if (ret < 0) {
 				err("error while stopping stream.");
+				return ret;
+			}
+		}
 	}
 
 	adap->feedcount = newfeedcount;
@@ -49,17 +53,24 @@
 
 		deb_ts("controlling pid parser\n");
 		if (adap->props.caps & DVB_USB_ADAP_HAS_PID_FILTER &&
-			adap->props.caps & DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF &&
-			adap->props.pid_filter_ctrl != NULL)
-			if (adap->props.pid_filter_ctrl(adap,adap->pid_filtering) < 0)
+			adap->props.caps &
+			DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF &&
+			adap->props.pid_filter_ctrl != NULL) {
+			ret = adap->props.pid_filter_ctrl(adap,
+				adap->pid_filtering);
+			if (ret < 0) {
 				err("could not handle pid_parser");
-
+				return ret;
+			}
+		}
 		deb_ts("start feeding\n");
-		if (adap->props.streaming_ctrl != NULL)
-			if (adap->props.streaming_ctrl(adap,1)) {
+		if (adap->props.streaming_ctrl != NULL) {
+			ret = adap->props.streaming_ctrl(adap, 1);
+			if (ret < 0) {
 				err("error while enabling fifo.");
-				return -ENODEV;
+				return ret;
 			}
+		}
 
 	}
 	return 0;
diff -druN linux-2.6.39-libre/drivers/media/dvb/dvb-usb/dvb-usb-ids.h linux-3.0-rc7-libre/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
--- linux-2.6.39-libre/drivers/media/dvb/dvb-usb/dvb-usb-ids.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/dvb/dvb-usb/dvb-usb-ids.h	2011-07-11 19:51:52.000000000 -0400
@@ -91,6 +91,7 @@
 #define USB_PID_COMPRO_VIDEOMATE_U500_PC		0x1e80
 #define USB_PID_CONCEPTRONIC_CTVDIGRCU			0xe397
 #define USB_PID_CONEXANT_D680_DMB			0x86d6
+#define USB_PID_CREATIX_CTX1921				0x1921
 #define USB_PID_DIBCOM_HOOK_DEFAULT			0x0064
 #define USB_PID_DIBCOM_HOOK_DEFAULT_REENUM		0x0065
 #define USB_PID_DIBCOM_MOD3000_COLD			0x0bb8
diff -druN linux-2.6.39-libre/drivers/media/dvb/dvb-usb/dw2102.c linux-3.0-rc7-libre/drivers/media/dvb/dvb-usb/dw2102.c
--- linux-2.6.39-libre/drivers/media/dvb/dvb-usb/dw2102.c	2011-05-19 02:08:49.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/dvb/dvb-usb/dw2102.c	2011-07-21 06:51:10.000000000 -0400
@@ -121,12 +121,16 @@
 			u16 index, u8 * data, u16 len, int flags)
 {
 	int ret;
-	u8 u8buf[len];
-
+	u8 *u8buf;
 	unsigned int pipe = (flags == DW210X_READ_MSG) ?
 				usb_rcvctrlpipe(dev, 0) : usb_sndctrlpipe(dev, 0);
 	u8 request_type = (flags == DW210X_READ_MSG) ? USB_DIR_IN : USB_DIR_OUT;
 
+	u8buf = kmalloc(len, GFP_KERNEL);
+	if (!u8buf)
+		return -ENOMEM;
+
+
 	if (flags == DW210X_WRITE_MSG)
 		memcpy(u8buf, data, len);
 	ret = usb_control_msg(dev, pipe, request, request_type | USB_TYPE_VENDOR,
@@ -134,6 +138,8 @@
 
 	if (flags == DW210X_READ_MSG)
 		memcpy(data, u8buf, len);
+
+	kfree(u8buf);
 	return ret;
 }
 
@@ -1377,7 +1383,7 @@
 	{ 0x0f, KEY_BLUE },	/* bottom yellow button */
 	{ 0x14, KEY_AUDIO },	/* Snapshot */
 	{ 0x38, KEY_TV },	/* TV/Radio */
-	{ 0x0c, KEY_ESC }	/* upper Red buttton */
+	{ 0x0c, KEY_ESC }	/* upper Red button */
 };
 
 static struct rc_map_dvb_usb_table_table keys_tables[] = {
diff -druN linux-2.6.39-libre/drivers/media/dvb/dvb-usb/ec168.c linux-3.0-rc7-libre/drivers/media/dvb/dvb-usb/ec168.c
--- linux-2.6.39-libre/drivers/media/dvb/dvb-usb/ec168.c	2011-05-19 02:08:51.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/dvb/dvb-usb/ec168.c	2011-07-21 06:51:13.000000000 -0400
@@ -36,7 +36,9 @@
 	int ret;
 	unsigned int pipe;
 	u8 request, requesttype;
-	u8 buf[req->size];
+	u8 *buf;
+
+
 
 	switch (req->cmd) {
 	case DOWNLOAD_FIRMWARE:
@@ -72,6 +74,12 @@
 		goto error;
 	}
 
+	buf = kmalloc(req->size, GFP_KERNEL);
+	if (!buf) {
+		ret = -ENOMEM;
+		goto error;
+	}
+
 	if (requesttype == (USB_TYPE_VENDOR | USB_DIR_OUT)) {
 		/* write */
 		memcpy(buf, req->data, req->size);
@@ -84,13 +92,13 @@
 	msleep(1); /* avoid I2C errors */
 
 	ret = usb_control_msg(udev, pipe, request, requesttype, req->value,
-		req->index, buf, sizeof(buf), EC168_USB_TIMEOUT);
+		req->index, buf, req->size, EC168_USB_TIMEOUT);
 
 	ec168_debug_dump(request, requesttype, req->value, req->index, buf,
 		req->size, deb_xfer);
 
 	if (ret < 0)
-		goto error;
+		goto err_dealloc;
 	else
 		ret = 0;
 
@@ -98,7 +106,11 @@
 	if (!ret && requesttype == (USB_TYPE_VENDOR | USB_DIR_IN))
 		memcpy(req->data, buf, req->size);
 
+	kfree(buf);
 	return ret;
+
+err_dealloc:
+	kfree(buf);
 error:
 	deb_info("%s: failed:%d\n", __func__, ret);
 	return ret;
diff -druN linux-2.6.39-libre/drivers/media/dvb/dvb-usb/friio.c linux-3.0-rc7-libre/drivers/media/dvb/dvb-usb/friio.c
--- linux-2.6.39-libre/drivers/media/dvb/dvb-usb/friio.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/dvb/dvb-usb/friio.c	2011-07-11 19:51:52.000000000 -0400
@@ -142,17 +142,20 @@
 	return I2C_FUNC_I2C;
 }
 
-
 static int friio_ext_ctl(struct dvb_usb_adapter *adap,
 			 u32 sat_color, int lnb_on)
 {
 	int i;
 	int ret;
 	struct i2c_msg msg;
-	u8 buf[2];
+	u8 *buf;
 	u32 mask;
 	u8 lnb = (lnb_on) ? FRIIO_CTL_LNB : 0;
 
+	buf = kmalloc(2, GFP_KERNEL);
+	if (!buf)
+		return -ENOMEM;
+
 	msg.addr = 0x00;
 	msg.flags = 0;
 	msg.len = 2;
@@ -189,6 +192,7 @@
 	buf[1] |= FRIIO_CTL_CLK;
 	ret += gl861_i2c_xfer(&adap->dev->i2c_adap, &msg, 1);
 
+	kfree(buf);
 	return (ret == 70);
 }
 
@@ -219,11 +223,20 @@
 	int ret;
 	int i;
 	int retry = 0;
-	u8 rbuf[2];
-	u8 wbuf[3];
+	u8 *rbuf, *wbuf;
 
 	deb_info("%s called.\n", __func__);
 
+	wbuf = kmalloc(3, GFP_KERNEL);
+	if (!wbuf)
+		return -ENOMEM;
+
+	rbuf = kmalloc(2, GFP_KERNEL);
+	if (!rbuf) {
+		kfree(wbuf);
+		return -ENOMEM;
+	}
+
 	/* use gl861_i2c_msg instead of gl861_i2c_xfer(), */
 	/* because the i2c device is not set up yet. */
 	wbuf[0] = 0x11;
@@ -358,6 +371,8 @@
 	return 0;
 
 error:
+	kfree(wbuf);
+	kfree(rbuf);
 	deb_info("%s:ret == %d\n", __func__, ret);
 	return -EIO;
 }
diff -druN linux-2.6.39-libre/drivers/media/dvb/dvb-usb/Kconfig linux-3.0-rc7-libre/drivers/media/dvb/dvb-usb/Kconfig
--- linux-2.6.39-libre/drivers/media/dvb/dvb-usb/Kconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/dvb/dvb-usb/Kconfig	2011-07-11 19:51:52.000000000 -0400
@@ -292,6 +292,11 @@
 	select DVB_MT352 if !DVB_FE_CUSTOMISE
 	select DVB_ZL10353 if !DVB_FE_CUSTOMISE
 	select DVB_TDA10023 if !DVB_FE_CUSTOMISE
+	select MEDIA_TUNER_TDA18212 if !MEDIA_TUNER_CUSTOMISE
+	select DVB_CX24116 if !DVB_FE_CUSTOMISE
+	select DVB_STV0900 if !DVB_FE_CUSTOMISE
+	select DVB_STV6110 if !DVB_FE_CUSTOMISE
+	select DVB_ISL6423 if !DVB_FE_CUSTOMISE
 	help
 	  Say Y here to support the Anysee E30, Anysee E30 Plus or
 	  Anysee E30 C Plus DVB USB2.0 receiver.
diff -druN linux-2.6.39-libre/drivers/media/dvb/dvb-usb/lmedm04.c linux-3.0-rc7-libre/drivers/media/dvb/dvb-usb/lmedm04.c
--- linux-2.6.39-libre/drivers/media/dvb/dvb-usb/lmedm04.c	2011-05-19 02:08:55.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/dvb/dvb-usb/lmedm04.c	2011-07-21 06:51:19.000000000 -0400
@@ -62,8 +62,6 @@
  *	LME2510: SHARP:BS2F7HZ0194(MV0194) cannot cold reset and share system
  * with other tuners. After a cold reset streaming will not start.
  *
- *	PID functions have been removed from this driver version due to
- * problems with different firmware and application versions.
  */
 #define DVB_USB_LOG_PREFIX "LME2510(C)"
 #include <linux/usb.h>
@@ -104,6 +102,10 @@
 module_param_named(firmware, dvb_usb_lme2510_firmware, int, 0644);
 MODULE_PARM_DESC(firmware, "set default firmware 0=Sharp7395 1=LG");
 
+static int pid_filter;
+module_param_named(pid, pid_filter, int, 0644);
+MODULE_PARM_DESC(pid, "set default 0=on 1=off");
+
 
 DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
 
@@ -125,6 +127,7 @@
 	u8 i2c_tuner_gate_r;
 	u8 i2c_tuner_addr;
 	u8 stream_on;
+	u8 pid_size;
 	void *buffer;
 	struct urb *lme_urb;
 	void *usb_buffer;
@@ -167,14 +170,14 @@
 	}
 	buff = st->usb_buffer;
 
-	/* the read/write capped at 512 */
-	memcpy(buff, wbuf, (wlen > 512) ? 512 : wlen);
-
 	ret = mutex_lock_interruptible(&d->usb_mutex);
 
 	if (ret < 0)
 		return -EAGAIN;
 
+	/* the read/write capped at 512 */
+	memcpy(buff, wbuf, (wlen > 512) ? 512 : wlen);
+
 	ret |= usb_clear_halt(d->udev, usb_sndbulkpipe(d->udev, 0x01));
 
 	ret |= lme2510_bulk_write(d->udev, buff, wlen , 0x01);
@@ -204,16 +207,36 @@
 			rbuff, sizeof(rbuff));
 	return ret;
 }
-static int lme2510_remote_keypress(struct dvb_usb_adapter *adap, u32 keypress)
+
+static int lme2510_enable_pid(struct dvb_usb_device *d, u8 index, u16 pid_out)
 {
-	struct dvb_usb_device *d = adap->dev;
+	struct lme2510_state *st = d->priv;
+	static u8 pid_buff[] = LME_ZERO_PID;
+	static u8 rbuf[1];
+	u8 pid_no = index * 2;
+	u8 pid_len = pid_no + 2;
+	int ret = 0;
+	deb_info(1, "PID Setting Pid %04x", pid_out);
 
-	deb_info(1, "INT Key Keypress =%04x", keypress);
+	if (st->pid_size == 0)
+		ret |= lme2510_stream_restart(d);
 
-	if (keypress > 0)
-		rc_keydown(d->rc_dev, keypress, 0);
+	pid_buff[2] = pid_no;
+	pid_buff[3] = (u8)pid_out & 0xff;
+	pid_buff[4] = pid_no + 1;
+	pid_buff[5] = (u8)(pid_out >> 8);
 
-	return 0;
+	if (pid_len > st->pid_size)
+		st->pid_size = pid_len;
+	pid_buff[7] = 0x80 + st->pid_size;
+
+	ret |= lme2510_usb_talk(d, pid_buff ,
+		sizeof(pid_buff) , rbuf, sizeof(rbuf));
+
+	if (st->stream_on)
+		ret |= lme2510_stream_restart(d);
+
+	return ret;
 }
 
 static void lme2510_int_response(struct urb *lme_urb)
@@ -222,6 +245,7 @@
 	struct lme2510_state *st = adap->dev->priv;
 	static u8 *ibuf, *rbuf;
 	int i = 0, offset;
+	u32 key;
 
 	switch (lme_urb->status) {
 	case 0:
@@ -248,10 +272,16 @@
 
 		switch (ibuf[0]) {
 		case 0xaa:
-			debug_data_snipet(1, "INT Remote data snipet in", ibuf);
-			lme2510_remote_keypress(adap,
-				(u32)(ibuf[2] << 24) + (ibuf[3] << 16) +
-				(ibuf[4] << 8) + ibuf[5]);
+			debug_data_snipet(1, "INT Remote data snipet", ibuf);
+			if ((ibuf[4] + ibuf[5]) == 0xff) {
+				key = ibuf[5];
+				key += (ibuf[3] > 0)
+					? (ibuf[3] ^ 0xff) << 8 : 0;
+				key += (ibuf[2] ^ 0xff) << 16;
+				deb_info(1, "INT Key =%08x", key);
+				if (adap->dev->rc_dev != NULL)
+					rc_keydown(adap->dev->rc_dev, key, 0);
+			}
 			break;
 		case 0xbb:
 			switch (st->tuner_config) {
@@ -326,16 +356,68 @@
 	return 0;
 }
 
+static int lme2510_pid_filter_ctrl(struct dvb_usb_adapter *adap, int onoff)
+{
+	struct lme2510_state *st = adap->dev->priv;
+	static u8 clear_pid_reg[] = LME_CLEAR_PID;
+	static u8 rbuf[1];
+	int ret;
+
+	deb_info(1, "PID Clearing Filter");
+
+	ret = mutex_lock_interruptible(&adap->dev->i2c_mutex);
+	if (ret < 0)
+		return -EAGAIN;
+
+	if (!onoff)
+		ret |= lme2510_usb_talk(adap->dev, clear_pid_reg,
+			sizeof(clear_pid_reg), rbuf, sizeof(rbuf));
+
+	st->pid_size = 0;
+
+	mutex_unlock(&adap->dev->i2c_mutex);
+
+	return 0;
+}
+
+static int lme2510_pid_filter(struct dvb_usb_adapter *adap, int index, u16 pid,
+	int onoff)
+{
+	int ret = 0;
+
+	deb_info(3, "%s PID=%04x Index=%04x onoff=%02x", __func__,
+		pid, index, onoff);
+
+	if (onoff)
+		if (!pid_filter) {
+			ret = mutex_lock_interruptible(&adap->dev->i2c_mutex);
+			if (ret < 0)
+				return -EAGAIN;
+			ret |= lme2510_enable_pid(adap->dev, index, pid);
+			mutex_unlock(&adap->dev->i2c_mutex);
+	}
+
+
+	return ret;
+}
+
+
 static int lme2510_return_status(struct usb_device *dev)
 {
 	int ret = 0;
-	u8 data[10] = {0};
+	u8 *data;
+
+	data = kzalloc(10, GFP_KERNEL);
+	if (!data)
+		return -ENOMEM;
 
 	ret |= usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
 			0x06, 0x80, 0x0302, 0x00, data, 0x0006, 200);
 	info("Firmware Status: %x (%x)", ret , data[2]);
 
-	return (ret < 0) ? -ENODEV : data[2];
+	ret = (ret < 0) ? -ENODEV : data[2];
+	kfree(data);
+	return ret;
 }
 
 static int lme2510_msg(struct dvb_usb_device *d,
@@ -591,9 +673,10 @@
 	else {
 		deb_info(1, "STM Steam Off");
 		/* mutex is here only to avoid collision with I2C */
-		ret = mutex_lock_interruptible(&adap->dev->i2c_mutex);
+		if (mutex_lock_interruptible(&adap->dev->i2c_mutex) < 0)
+			return -EAGAIN;
 
-		ret |= lme2510_usb_talk(adap->dev, clear_reg_3,
+		ret = lme2510_usb_talk(adap->dev, clear_reg_3,
 				sizeof(clear_reg_3), rbuf, rlen);
 		st->stream_on = 0;
 		st->i2c_talk_onoff = 1;
@@ -604,45 +687,6 @@
 	return (ret < 0) ? -ENODEV : 0;
 }
 
-static int lme2510_int_service(struct dvb_usb_adapter *adap)
-{
-	struct dvb_usb_device *d = adap->dev;
-	struct rc_dev *rc;
-	int ret;
-
-	info("STA Configuring Remote");
-
-	rc = rc_allocate_device();
-	if (!rc)
-		return -ENOMEM;
-
-	usb_make_path(d->udev, d->rc_phys, sizeof(d->rc_phys));
-	strlcat(d->rc_phys, "/ir0", sizeof(d->rc_phys));
-
-	rc->input_name = "LME2510 Remote Control";
-	rc->input_phys = d->rc_phys;
-	rc->map_name = RC_MAP_LME2510;
-	rc->driver_name = "LME 2510";
-	usb_to_input_id(d->udev, &rc->input_id);
-
-	ret = rc_register_device(rc);
-	if (ret) {
-		rc_free_device(rc);
-		return ret;
-	}
-	d->rc_dev = rc;
-
-	/* Start the Interrupt */
-	ret = lme2510_int_read(adap);
-	if (ret < 0) {
-		rc_unregister_device(rc);
-		info("INT Unable to start Interrupt Service");
-		return -ENODEV;
-	}
-
-	return 0;
-}
-
 static u8 check_sum(u8 *p, u8 len)
 {
 	u8 sum = 0;
@@ -655,7 +699,7 @@
 					const struct firmware *fw)
 {
 	int ret = 0;
-	u8 data[512] = {0};
+	u8 *data;
 	u16 j, wlen, len_in, start, end;
 	u8 packet_size, dlen, i;
 	u8 *fw_data;
@@ -663,6 +707,11 @@
 	packet_size = 0x31;
 	len_in = 1;
 
+	data = kzalloc(512, GFP_KERNEL);
+	if (!data) {
+		info("FRM Could not start Firmware Download (Buffer allocation failed)");
+		return -ENOMEM;
+	}
 
 	info("FRM Starting Firmware Download");
 
@@ -678,15 +727,15 @@
 				data[0] = i | 0x80;
 				dlen = (u8)(end - j)-1;
 			}
-		data[1] = dlen;
-		memcpy(&data[2], fw_data, dlen+1);
-		wlen = (u8) dlen + 4;
-		data[wlen-1] = check_sum(fw_data, dlen+1);
-		deb_info(1, "Data S=%02x:E=%02x CS= %02x", data[3],
+			data[1] = dlen;
+			memcpy(&data[2], fw_data, dlen+1);
+			wlen = (u8) dlen + 4;
+			data[wlen-1] = check_sum(fw_data, dlen+1);
+			deb_info(1, "Data S=%02x:E=%02x CS= %02x", data[3],
 				data[dlen+2], data[dlen+3]);
-		ret |= lme2510_bulk_write(dev, data,  wlen, 1);
-		ret |= lme2510_bulk_read(dev, data, len_in , 1);
-		ret |= (data[0] == 0x88) ? 0 : -1;
+			ret |= lme2510_bulk_write(dev, data,  wlen, 1);
+			ret |= lme2510_bulk_read(dev, data, len_in , 1);
+			ret |= (data[0] == 0x88) ? 0 : -1;
 		}
 	}
 
@@ -706,7 +755,7 @@
 	else
 		info("FRM Firmware Download Completed - Resetting Device");
 
-
+	kfree(data);
 	return (ret < 0) ? -ENODEV : 0;
 }
 
@@ -739,7 +788,7 @@
 
 	cold_fw = !cold;
 
-	if (udev->descriptor.idProduct == 0x1122) {
+	if (le16_to_cpu(udev->descriptor.idProduct) == 0x1122) {
 		switch (dvb_usb_lme2510_firmware) {
 		default:
 			dvb_usb_lme2510_firmware = TUNER_S0194;
@@ -747,7 +796,7 @@
 			fw_lme = fw_s0194;
 			ret = reject_firmware(&fw, fw_lme, &udev->dev);
 			if (ret == 0) {
-				cold = 0;/*lme2510-s0194 cannot cold reset*/
+				cold = 0;
 				break;
 			}
 			dvb_usb_lme2510_firmware = TUNER_LG;
@@ -769,8 +818,10 @@
 		case TUNER_S7395:
 			fw_lme = fw_c_s7395;
 			ret = reject_firmware(&fw, fw_lme, &udev->dev);
-			if (ret == 0)
+			if (ret == 0) {
+				cold = 0;
 				break;
+			}
 			dvb_usb_lme2510_firmware = TUNER_LG;
 		case TUNER_LG:
 			fw_lme = fw_c_lg;
@@ -796,14 +847,14 @@
 		ret = lme2510_download_firmware(udev, fw);
 	}
 
+	release_firmware(fw);
+
 	if (cold) {
 		info("FRM Changing to %s firmware", fw_lme);
 		lme_coldreset(udev);
 		return -ENODEV;
 	}
 
-	release_firmware(fw);
-
 	return ret;
 }
 
@@ -959,8 +1010,11 @@
 
 
 end:	if (ret) {
-		kfree(adap->fe);
-		adap->fe = NULL;
+		if (adap->fe) {
+			dvb_frontend_detach(adap->fe);
+			adap->fe = NULL;
+		}
+		adap->dev->props.rc.core.rc_codes = NULL;
 		return -ENODEV;
 	}
 
@@ -1003,8 +1057,12 @@
 		return -ENODEV;
 	}
 
-	/* Start the Interrupt & Remote*/
-	ret = lme2510_int_service(adap);
+	/* Start the Interrupt*/
+	ret = lme2510_int_read(adap);
+	if (ret < 0) {
+		info("INT Unable to start Interrupt Service");
+		return -ENODEV;
+	}
 
 	return ret;
 }
@@ -1017,12 +1075,13 @@
 	static u8 rbuf[1];
 	int ret, len = 3, rlen = 1;
 
-	ret = mutex_lock_interruptible(&d->i2c_mutex);
+	if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
+		return -EAGAIN;
 
 	if (onoff)
-		ret |= lme2510_usb_talk(d, lnb_on, len, rbuf, rlen);
+		ret = lme2510_usb_talk(d, lnb_on, len, rbuf, rlen);
 	else
-		ret |= lme2510_usb_talk(d, lnb_off, len, rbuf, rlen);
+		ret = lme2510_usb_talk(d, lnb_off, len, rbuf, rlen);
 
 	st->i2c_talk_onoff = 1;
 
@@ -1086,7 +1145,13 @@
 	.num_adapters = 1,
 	.adapter = {
 		{
+			.caps = DVB_USB_ADAP_HAS_PID_FILTER|
+				DVB_USB_ADAP_NEED_PID_FILTERING|
+				DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
 			.streaming_ctrl   = lme2510_streaming_ctrl,
+			.pid_filter_count = 15,
+			.pid_filter = lme2510_pid_filter,
+			.pid_filter_ctrl  = lme2510_pid_filter_ctrl,
 			.frontend_attach  = dm04_lme2510_frontend_attach,
 			.tuner_attach = dm04_lme2510_tuner,
 			/* parameter for the MPEG2-data transfer */
@@ -1103,6 +1168,12 @@
 			}
 		}
 	},
+	.rc.core = {
+		.protocol	= RC_TYPE_NEC,
+		.module_name	= "LME2510 Remote Control",
+		.allowed_protos	= RC_TYPE_NEC,
+		.rc_codes	= RC_MAP_LME2510,
+	},
 	.power_ctrl       = lme2510_powerup,
 	.identify_state   = lme2510_identify_state,
 	.i2c_algo         = &lme2510_i2c_algo,
@@ -1122,7 +1193,13 @@
 	.num_adapters = 1,
 	.adapter = {
 		{
+			.caps = DVB_USB_ADAP_HAS_PID_FILTER|
+				DVB_USB_ADAP_NEED_PID_FILTERING|
+				DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
 			.streaming_ctrl   = lme2510_streaming_ctrl,
+			.pid_filter_count = 15,
+			.pid_filter = lme2510_pid_filter,
+			.pid_filter_ctrl  = lme2510_pid_filter_ctrl,
 			.frontend_attach  = dm04_lme2510_frontend_attach,
 			.tuner_attach = dm04_lme2510_tuner,
 			/* parameter for the MPEG2-data transfer */
@@ -1139,6 +1216,12 @@
 			}
 		}
 	},
+	.rc.core = {
+		.protocol	= RC_TYPE_NEC,
+		.module_name	= "LME2510 Remote Control",
+		.allowed_protos	= RC_TYPE_NEC,
+		.rc_codes	= RC_MAP_LME2510,
+	},
 	.power_ctrl       = lme2510_powerup,
 	.identify_state   = lme2510_identify_state,
 	.i2c_algo         = &lme2510_i2c_algo,
@@ -1151,7 +1234,7 @@
 	}
 };
 
-void *lme2510_exit_int(struct dvb_usb_device *d)
+static void *lme2510_exit_int(struct dvb_usb_device *d)
 {
 	struct lme2510_state *st = d->priv;
 	struct dvb_usb_adapter *adap = &d->adapter[0];
@@ -1162,23 +1245,25 @@
 		adap->feedcount = 0;
 	}
 
-	if (st->lme_urb != NULL) {
+	if (st->usb_buffer != NULL) {
 		st->i2c_talk_onoff = 1;
 		st->signal_lock = 0;
 		st->signal_level = 0;
 		st->signal_sn = 0;
 		buffer = st->usb_buffer;
+	}
+
+	if (st->lme_urb != NULL) {
 		usb_kill_urb(st->lme_urb);
 		usb_free_coherent(d->udev, 5000, st->buffer,
 				  st->lme_urb->transfer_dma);
 		info("Interrupt Service Stopped");
-		rc_unregister_device(d->rc_dev);
-		info("Remote Stopped");
 	}
+
 	return buffer;
 }
 
-void lme2510_exit(struct usb_interface *intf)
+static void lme2510_exit(struct usb_interface *intf)
 {
 	struct dvb_usb_device *d = usb_get_intfdata(intf);
 	void *usb_buffer;
@@ -1186,7 +1271,8 @@
 	if (d != NULL) {
 		usb_buffer = lme2510_exit_int(d);
 		dvb_usb_device_exit(intf);
-		kfree(usb_buffer);
+		if (usb_buffer != NULL)
+			kfree(usb_buffer);
 	}
 }
 
@@ -1220,5 +1306,5 @@
 
 MODULE_AUTHOR("Malcolm Priestley <tvboxspy@gmail.com>");
 MODULE_DESCRIPTION("LME2510(C) DVB-S USB2.0");
-MODULE_VERSION("1.80");
+MODULE_VERSION("1.88");
 MODULE_LICENSE("GPL");
diff -druN linux-2.6.39-libre/drivers/media/dvb/dvb-usb/lmedm04.h linux-3.0-rc7-libre/drivers/media/dvb/dvb-usb/lmedm04.h
--- linux-2.6.39-libre/drivers/media/dvb/dvb-usb/lmedm04.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/dvb/dvb-usb/lmedm04.h	2011-07-11 19:51:52.000000000 -0400
@@ -40,6 +40,7 @@
 */
 #define LME_ST_ON_W	{0x06, 0x00}
 #define LME_CLEAR_PID   {0x03, 0x02, 0x20, 0xa0}
+#define LME_ZERO_PID	{0x03, 0x06, 0x00, 0x00, 0x01, 0x00, 0x20, 0x9c}
 
 /*  LNB Voltage
  *  07 XX XX
@@ -108,14 +109,14 @@
 	0x3d, 0x30,
 	0x40, 0x63,
 	0x41, 0x04,
-	0x42, 0x60,
+	0x42, 0x20,
 	0x43, 0x00,
 	0x44, 0x00,
 	0x45, 0x00,
 	0x46, 0x00,
 	0x47, 0x00,
 	0x4a, 0x00,
-	0x50, 0x12,
+	0x50, 0x10,
 	0x51, 0x36,
 	0x52, 0x21,
 	0x53, 0x94,
diff -druN linux-2.6.39-libre/drivers/media/dvb/dvb-usb/m920x.c linux-3.0-rc7-libre/drivers/media/dvb/dvb-usb/m920x.c
--- linux-2.6.39-libre/drivers/media/dvb/dvb-usb/m920x.c	2011-05-19 02:08:57.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/dvb/dvb-usb/m920x.c	2011-07-21 06:51:22.000000000 -0400
@@ -134,13 +134,17 @@
 {
 	struct m920x_state *m = d->priv;
 	int i, ret = 0;
-	u8 rc_state[2];
+	u8 *rc_state;
+
+	rc_state = kmalloc(2, GFP_KERNEL);
+	if (!rc_state)
+		return -ENOMEM;
 
 	if ((ret = m920x_read(d->udev, M9206_CORE, 0x0, M9206_RC_STATE, rc_state, 1)) != 0)
-		goto unlock;
+		goto out;
 
 	if ((ret = m920x_read(d->udev, M9206_CORE, 0x0, M9206_RC_KEY, rc_state + 1, 1)) != 0)
-		goto unlock;
+		goto out;
 
 	for (i = 0; i < d->props.rc.legacy.rc_map_size; i++)
 		if (rc5_data(&d->props.rc.legacy.rc_map_table[i]) == rc_state[1]) {
@@ -149,7 +153,7 @@
 			switch(rc_state[0]) {
 			case 0x80:
 				*state = REMOTE_NO_KEY_PRESSED;
-				goto unlock;
+				goto out;
 
 			case 0x88: /* framing error or "invalid code" */
 			case 0x99:
@@ -157,7 +161,7 @@
 			case 0xd8:
 				*state = REMOTE_NO_KEY_PRESSED;
 				m->rep_count = 0;
-				goto unlock;
+				goto out;
 
 			case 0x93:
 			case 0x92:
@@ -165,7 +169,7 @@
 			case 0x82:
 				m->rep_count = 0;
 				*state = REMOTE_KEY_PRESSED;
-				goto unlock;
+				goto out;
 
 			case 0x91:
 			case 0x81: /* pinnacle PCTV310e */
@@ -174,12 +178,12 @@
 					*state = REMOTE_KEY_REPEAT;
 				else
 					*state = REMOTE_NO_KEY_PRESSED;
-				goto unlock;
+				goto out;
 
 			default:
 				deb("Unexpected rc state %02x\n", rc_state[0]);
 				*state = REMOTE_NO_KEY_PRESSED;
-				goto unlock;
+				goto out;
 			}
 		}
 
@@ -188,8 +192,8 @@
 
 	*state = REMOTE_NO_KEY_PRESSED;
 
- unlock:
-
+ out:
+	kfree(rc_state);
 	return ret;
 }
 
@@ -339,13 +343,19 @@
 static int m920x_firmware_download(struct usb_device *udev, const struct firmware *fw)
 {
 	u16 value, index, size;
-	u8 read[4], *buff;
+	u8 *read, *buff;
 	int i, pass, ret = 0;
 
 	buff = kmalloc(65536, GFP_KERNEL);
 	if (buff == NULL)
 		return -ENOMEM;
 
+	read = kmalloc(4, GFP_KERNEL);
+	if (!read) {
+		kfree(buff);
+		return -ENOMEM;
+	}
+
 	if ((ret = m920x_read(udev, M9206_FILTER, 0x0, 0x8000, read, 4)) != 0)
 		goto done;
 	deb("%x %x %x %x\n", read[0], read[1], read[2], read[3]);
@@ -396,6 +406,7 @@
 	deb("firmware uploaded!\n");
 
  done:
+	kfree(read);
 	kfree(buff);
 
 	return ret;
@@ -632,9 +643,9 @@
 	{ 0x16, KEY_POWER },
 	{ 0x17, KEY_FAVORITES },
 	{ 0x0f, KEY_TEXT },
-	{ 0x48, KEY_MEDIA },		/* preview */
+	{ 0x48, KEY_PROGRAM },		/* preview */
 	{ 0x1c, KEY_EPG },
-	{ 0x04, KEY_LIST },			/* record list */
+	{ 0x04, KEY_LIST },		/* record list */
 	{ 0x03, KEY_1 },
 	{ 0x01, KEY_2 },
 	{ 0x06, KEY_3 },
@@ -674,14 +685,14 @@
 	{ 0x0e, KEY_MUTE },
 /*	{ 0x49, KEY_LR },	*/		/* L/R */
 	{ 0x07, KEY_SLEEP },		/* Hibernate */
-	{ 0x08, KEY_MEDIA },		/* A/V */
-	{ 0x0e, KEY_MENU },			/* Recall */
+	{ 0x08, KEY_VIDEO },		/* 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 */
+	{ 0x18, KEY_RED },		/* Red */
+	{ 0x53, KEY_GREEN },		/* Green */
+	{ 0x5e, KEY_YELLOW },		/* Yellow */
+	{ 0x5f, KEY_BLUE },		/* Blue */
 };
 
 /* DVB USB Driver stuff */
diff -druN linux-2.6.39-libre/drivers/media/dvb/dvb-usb/nova-t-usb2.c linux-3.0-rc7-libre/drivers/media/dvb/dvb-usb/nova-t-usb2.c
--- linux-2.6.39-libre/drivers/media/dvb/dvb-usb/nova-t-usb2.c	2011-05-19 02:08:59.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/dvb/dvb-usb/nova-t-usb2.c	2011-07-21 06:51:24.000000000 -0400
@@ -47,7 +47,7 @@
 	{ 0x1e17, KEY_RIGHT },
 	{ 0x1e18, KEY_VIDEO },
 	{ 0x1e19, KEY_AUDIO },
-	{ 0x1e1a, KEY_MEDIA },
+	{ 0x1e1a, KEY_IMAGES },
 	{ 0x1e1b, KEY_EPG },
 	{ 0x1e1c, KEY_TV },
 	{ 0x1e1e, KEY_NEXT },
diff -druN linux-2.6.39-libre/drivers/media/dvb/dvb-usb/opera1.c linux-3.0-rc7-libre/drivers/media/dvb/dvb-usb/opera1.c
--- linux-2.6.39-libre/drivers/media/dvb/dvb-usb/opera1.c	2011-05-19 02:09:02.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/dvb/dvb-usb/opera1.c	2011-07-21 06:51:27.000000000 -0400
@@ -53,27 +53,36 @@
 			    u8 * data, u16 len, int flags)
 {
 	int ret;
-	u8 r;
-	u8 u8buf[len];
-
+	u8 tmp;
+	u8 *buf;
 	unsigned int pipe = (flags == OPERA_READ_MSG) ?
 		usb_rcvctrlpipe(dev,0) : usb_sndctrlpipe(dev, 0);
 	u8 request_type = (flags == OPERA_READ_MSG) ? USB_DIR_IN : USB_DIR_OUT;
 
+	buf = kmalloc(len, GFP_KERNEL);
+	if (!buf)
+		return -ENOMEM;
+
 	if (flags == OPERA_WRITE_MSG)
-		memcpy(u8buf, data, len);
-	ret =
-		usb_control_msg(dev, pipe, request, request_type | USB_TYPE_VENDOR,
-			value, 0x0, u8buf, len, 2000);
+		memcpy(buf, data, len);
+	ret = usb_control_msg(dev, pipe, request,
+			request_type | USB_TYPE_VENDOR, value, 0x0,
+			buf, len, 2000);
 
 	if (request == OPERA_TUNER_REQ) {
+		tmp = buf[0];
 		if (usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
-				OPERA_TUNER_REQ, USB_DIR_IN | USB_TYPE_VENDOR,
-				0x01, 0x0, &r, 1, 2000)<1 || r!=0x08)
-					return 0;
+			    OPERA_TUNER_REQ, USB_DIR_IN | USB_TYPE_VENDOR,
+			    0x01, 0x0, buf, 1, 2000) < 1 || buf[0] != 0x08) {
+			ret = 0;
+			goto out;
+		}
+		buf[0] = tmp;
 	}
 	if (flags == OPERA_READ_MSG)
-		memcpy(data, u8buf, len);
+		memcpy(data, buf, len);
+out:
+	kfree(buf);
 	return ret;
 }
 
@@ -189,7 +198,7 @@
 static u8 opera1_inittab[] = {
 	0x00, 0xa1,
 	0x01, 0x15,
-	0x02, 0x00,
+	0x02, 0x30,
 	0x03, 0x00,
 	0x04, 0x7d,
 	0x05, 0x05,
diff -druN linux-2.6.39-libre/drivers/media/dvb/dvb-usb/vp702x.c linux-3.0-rc7-libre/drivers/media/dvb/dvb-usb/vp702x.c
--- linux-2.6.39-libre/drivers/media/dvb/dvb-usb/vp702x.c	2011-05-19 02:09:12.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/dvb/dvb-usb/vp702x.c	2011-07-21 06:51:38.000000000 -0400
@@ -15,6 +15,7 @@
  * see Documentation/dvb/README.dvb-usb for more information
  */
 #include "vp702x.h"
+#include <linux/mutex.h>
 
 /* debug */
 int dvb_usb_vp702x_debug;
@@ -23,27 +24,23 @@
 
 DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
 
-struct vp702x_state {
+struct vp702x_adapter_state {
 	int pid_filter_count;
 	int pid_filter_can_bypass;
 	u8  pid_filter_state;
 };
 
-struct vp702x_device_state {
-	u8 power_state;
-};
-
-/* check for mutex FIXME */
-int vp702x_usb_in_op(struct dvb_usb_device *d, u8 req, u16 value, u16 index, u8 *b, int blen)
+static int vp702x_usb_in_op_unlocked(struct dvb_usb_device *d, u8 req,
+				     u16 value, u16 index, u8 *b, int blen)
 {
-	int ret = -1;
+	int ret;
 
-		ret = usb_control_msg(d->udev,
-			usb_rcvctrlpipe(d->udev,0),
-			req,
-			USB_TYPE_VENDOR | USB_DIR_IN,
-			value,index,b,blen,
-			2000);
+	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);
@@ -58,8 +55,20 @@
 	return ret;
 }
 
-static int vp702x_usb_out_op(struct dvb_usb_device *d, u8 req, u16 value,
-			     u16 index, u8 *b, int blen)
+int vp702x_usb_in_op(struct dvb_usb_device *d, u8 req, u16 value,
+			    u16 index, u8 *b, int blen)
+{
+	int ret;
+
+	mutex_lock(&d->usb_mutex);
+	ret = vp702x_usb_in_op_unlocked(d, req, value, index, b, blen);
+	mutex_unlock(&d->usb_mutex);
+
+	return ret;
+}
+
+int vp702x_usb_out_op_unlocked(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);
@@ -77,6 +86,18 @@
 		return 0;
 }
 
+int vp702x_usb_out_op(struct dvb_usb_device *d, u8 req, u16 value,
+			     u16 index, u8 *b, int blen)
+{
+	int ret;
+
+	mutex_lock(&d->usb_mutex);
+	ret = vp702x_usb_out_op_unlocked(d, req, value, index, b, blen);
+	mutex_unlock(&d->usb_mutex);
+
+	return ret;
+}
+
 int vp702x_usb_inout_op(struct dvb_usb_device *d, u8 *o, int olen, u8 *i, int ilen, int msec)
 {
 	int ret;
@@ -84,50 +105,93 @@
 	if ((ret = mutex_lock_interruptible(&d->usb_mutex)))
 		return ret;
 
-	ret = vp702x_usb_out_op(d,REQUEST_OUT,0,0,o,olen);
+	ret = vp702x_usb_out_op_unlocked(d, REQUEST_OUT, 0, 0, o, olen);
 	msleep(msec);
-	ret = vp702x_usb_in_op(d,REQUEST_IN,0,0,i,ilen);
+	ret = vp702x_usb_in_op_unlocked(d, REQUEST_IN, 0, 0, i, ilen);
 
 	mutex_unlock(&d->usb_mutex);
-
 	return ret;
 }
 
 static int vp702x_usb_inout_cmd(struct dvb_usb_device *d, u8 cmd, u8 *o,
 				int olen, u8 *i, int ilen, int msec)
 {
-	u8 bout[olen+2];
-	u8 bin[ilen+1];
+	struct vp702x_device_state *st = d->priv;
 	int ret = 0;
+	u8 *buf;
+	int buflen = max(olen + 2, ilen + 1);
 
-	bout[0] = 0x00;
-	bout[1] = cmd;
-	memcpy(&bout[2],o,olen);
+	ret = mutex_lock_interruptible(&st->buf_mutex);
+	if (ret < 0)
+		return ret;
 
-	ret = vp702x_usb_inout_op(d, bout, olen+2, bin, ilen+1,msec);
+	if (buflen > st->buf_len) {
+		buf = kmalloc(buflen, GFP_KERNEL);
+		if (!buf) {
+			mutex_unlock(&st->buf_mutex);
+			return -ENOMEM;
+		}
+		info("successfully reallocated a bigger buffer");
+		kfree(st->buf);
+		st->buf = buf;
+		st->buf_len = buflen;
+	} else {
+		buf = st->buf;
+	}
+
+	buf[0] = 0x00;
+	buf[1] = cmd;
+	memcpy(&buf[2], o, olen);
+
+	ret = vp702x_usb_inout_op(d, buf, olen+2, buf, ilen+1, msec);
 
 	if (ret == 0)
-		memcpy(i,&bin[1],ilen);
+		memcpy(i, &buf[1], ilen);
+	mutex_unlock(&st->buf_mutex);
 
 	return ret;
 }
 
 static int vp702x_set_pld_mode(struct dvb_usb_adapter *adap, u8 bypass)
 {
-	u8 buf[16] = { 0 };
-	return vp702x_usb_in_op(adap->dev, 0xe0, (bypass << 8) | 0x0e, 0, buf, 16);
+	int ret;
+	struct vp702x_device_state *st = adap->dev->priv;
+	u8 *buf;
+
+	mutex_lock(&st->buf_mutex);
+
+	buf = st->buf;
+	memset(buf, 0, 16);
+
+	ret = vp702x_usb_in_op(adap->dev, 0xe0, (bypass << 8) | 0x0e,
+			0, buf, 16);
+	mutex_unlock(&st->buf_mutex);
+	return ret;
 }
 
 static int vp702x_set_pld_state(struct dvb_usb_adapter *adap, u8 state)
 {
-	u8 buf[16] = { 0 };
-	return vp702x_usb_in_op(adap->dev, 0xe0, (state << 8) | 0x0f, 0, buf, 16);
+	int ret;
+	struct vp702x_device_state *st = adap->dev->priv;
+	u8 *buf;
+
+	mutex_lock(&st->buf_mutex);
+
+	buf = st->buf;
+	memset(buf, 0, 16);
+	ret = vp702x_usb_in_op(adap->dev, 0xe0, (state << 8) | 0x0f,
+			0, buf, 16);
+
+	mutex_unlock(&st->buf_mutex);
+
+	return ret;
 }
 
 static int vp702x_set_pid(struct dvb_usb_adapter *adap, u16 pid, u8 id, int onoff)
 {
-	struct vp702x_state *st = adap->priv;
-	u8 buf[16] = { 0 };
+	struct vp702x_adapter_state *st = adap->priv;
+	struct vp702x_device_state *dst = adap->dev->priv;
+	u8 *buf;
 
 	if (onoff)
 		st->pid_filter_state |=  (1 << id);
@@ -139,32 +203,45 @@
 	id = 0x10 + id*2;
 
 	vp702x_set_pld_state(adap, st->pid_filter_state);
+
+	mutex_lock(&dst->buf_mutex);
+
+	buf = dst->buf;
+	memset(buf, 0, 16);
 	vp702x_usb_in_op(adap->dev, 0xe0, (((pid >> 8) & 0xff) << 8) | (id), 0, buf, 16);
 	vp702x_usb_in_op(adap->dev, 0xe0, (((pid     ) & 0xff) << 8) | (id+1), 0, buf, 16);
+
+	mutex_unlock(&dst->buf_mutex);
+
 	return 0;
 }
 
 
 static int vp702x_init_pid_filter(struct dvb_usb_adapter *adap)
 {
-	struct vp702x_state *st = adap->priv;
+	struct vp702x_adapter_state *st = adap->priv;
+	struct vp702x_device_state *dst = adap->dev->priv;
 	int i;
-	u8 b[10] = { 0 };
+	u8 *b;
 
 	st->pid_filter_count = 8;
 	st->pid_filter_can_bypass = 1;
 	st->pid_filter_state = 0x00;
 
-	vp702x_set_pld_mode(adap, 1); // bypass
+	vp702x_set_pld_mode(adap, 1); /* bypass */
 
 	for (i = 0; i < st->pid_filter_count; i++)
 		vp702x_set_pid(adap, 0xffff, i, 1);
 
+	mutex_lock(&dst->buf_mutex);
+	b = dst->buf;
+	memset(b, 0, 10);
 	vp702x_usb_in_op(adap->dev, 0xb5, 3, 0, b, 10);
 	vp702x_usb_in_op(adap->dev, 0xb5, 0, 0, b, 10);
 	vp702x_usb_in_op(adap->dev, 0xb5, 1, 0, b, 10);
+	mutex_unlock(&dst->buf_mutex);
+	/*vp702x_set_pld_mode(d, 0); // filter */
 
-	//vp702x_set_pld_mode(d, 0); // filter
 	return 0;
 }
 
@@ -182,18 +259,23 @@
 /* remote control stuff (does not work with my box) */
 static int vp702x_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
 {
-	u8 key[10];
+	u8 *key;
 	int i;
 
 /* remove the following return to enabled remote querying */
 	return 0;
 
+	key = kmalloc(10, GFP_KERNEL);
+	if (!key)
+		return -ENOMEM;
+
 	vp702x_usb_in_op(d,READ_REMOTE_REQ,0,0,key,10);
 
 	deb_rc("remote query key: %x %d\n",key[1],key[1]);
 
 	if (key[1] == 0x44) {
 		*state = REMOTE_NO_KEY_PRESSED;
+		kfree(key);
 		return 0;
 	}
 
@@ -203,15 +285,23 @@
 			*event = rc_map_vp702x_table[i].keycode;
 			break;
 		}
+	kfree(key);
 	return 0;
 }
 
 
 static int vp702x_read_mac_addr(struct dvb_usb_device *d,u8 mac[6])
 {
-	u8 i;
+	u8 i, *buf;
+	struct vp702x_device_state *st = d->priv;
+
+	mutex_lock(&st->buf_mutex);
+	buf = st->buf;
 	for (i = 6; i < 12; i++)
-		vp702x_usb_in_op(d, READ_EEPROM_REQ, i, 1, &mac[i - 6], 1);
+		vp702x_usb_in_op(d, READ_EEPROM_REQ, i, 1, &buf[i - 6], 1);
+
+	memcpy(mac, buf, 6);
+	mutex_unlock(&st->buf_mutex);
 	return 0;
 }
 
@@ -221,7 +311,8 @@
 
 	vp702x_usb_out_op(adap->dev, SET_TUNER_POWER_REQ, 0, 7, NULL, 0);
 
-	if (vp702x_usb_inout_cmd(adap->dev, GET_SYSTEM_STRING, NULL, 0, buf, 10, 10))
+	if (vp702x_usb_inout_cmd(adap->dev, GET_SYSTEM_STRING, NULL, 0,
+				   buf, 10, 10))
 		return -EIO;
 
 	buf[9] = '\0';
@@ -240,8 +331,38 @@
 static int vp702x_usb_probe(struct usb_interface *intf,
 		const struct usb_device_id *id)
 {
-	return dvb_usb_device_init(intf, &vp702x_properties,
-				   THIS_MODULE, NULL, adapter_nr);
+	struct dvb_usb_device *d;
+	struct vp702x_device_state *st;
+	int ret;
+
+	ret = dvb_usb_device_init(intf, &vp702x_properties,
+				   THIS_MODULE, &d, adapter_nr);
+	if (ret)
+		goto out;
+
+	st = d->priv;
+	st->buf_len = 16;
+	st->buf = kmalloc(st->buf_len, GFP_KERNEL);
+	if (!st->buf) {
+		ret = -ENOMEM;
+		dvb_usb_device_exit(intf);
+		goto out;
+	}
+	mutex_init(&st->buf_mutex);
+
+out:
+	return ret;
+
+}
+
+static void vp702x_usb_disconnect(struct usb_interface *intf)
+{
+	struct dvb_usb_device *d = usb_get_intfdata(intf);
+	struct vp702x_device_state *st = d->priv;
+	mutex_lock(&st->buf_mutex);
+	kfree(st->buf);
+	mutex_unlock(&st->buf_mutex);
+	dvb_usb_device_exit(intf);
 }
 
 static struct usb_device_id vp702x_usb_table [] = {
@@ -278,7 +399,7 @@
 					}
 				}
 			},
-			.size_of_priv     = sizeof(struct vp702x_state),
+			.size_of_priv     = sizeof(struct vp702x_adapter_state),
 		}
 	},
 	.read_mac_address = vp702x_read_mac_addr,
@@ -307,9 +428,9 @@
 /* usb specific object needed to register this driver with the usb subsystem */
 static struct usb_driver vp702x_usb_driver = {
 	.name		= "dvb_usb_vp702x",
-	.probe 		= vp702x_usb_probe,
-	.disconnect = dvb_usb_device_exit,
-	.id_table 	= vp702x_usb_table,
+	.probe		= vp702x_usb_probe,
+	.disconnect	= vp702x_usb_disconnect,
+	.id_table	= vp702x_usb_table,
 };
 
 /* module stuff */
diff -druN linux-2.6.39-libre/drivers/media/dvb/dvb-usb/vp702x-fe.c linux-3.0-rc7-libre/drivers/media/dvb/dvb-usb/vp702x-fe.c
--- linux-2.6.39-libre/drivers/media/dvb/dvb-usb/vp702x-fe.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/dvb/dvb-usb/vp702x-fe.c	2011-07-11 19:51:52.000000000 -0400
@@ -41,14 +41,23 @@
 
 static int vp702x_fe_refresh_state(struct vp702x_fe_state *st)
 {
-	u8 buf[10];
-	if (time_after(jiffies,st->next_status_check)) {
-		vp702x_usb_in_op(st->d,READ_STATUS,0,0,buf,10);
+	struct vp702x_device_state *dst = st->d->priv;
+	u8 *buf;
 
+	if (time_after(jiffies, st->next_status_check)) {
+		mutex_lock(&dst->buf_mutex);
+		buf = dst->buf;
+
+		vp702x_usb_in_op(st->d, READ_STATUS, 0, 0, buf, 10);
 		st->lock = buf[4];
-		vp702x_usb_in_op(st->d,READ_TUNER_REG_REQ,0x11,0,&st->snr,1);
-		vp702x_usb_in_op(st->d,READ_TUNER_REG_REQ,0x15,0,&st->sig,1);
 
+		vp702x_usb_in_op(st->d, READ_TUNER_REG_REQ, 0x11, 0, buf, 1);
+		st->snr = buf[0];
+
+		vp702x_usb_in_op(st->d, READ_TUNER_REG_REQ, 0x15, 0, buf, 1);
+		st->sig = buf[0];
+
+		mutex_unlock(&dst->buf_mutex);
 		st->next_status_check = jiffies + (st->status_check_interval*HZ)/1000;
 	}
 	return 0;
@@ -130,11 +139,17 @@
 				  struct dvb_frontend_parameters *fep)
 {
 	struct vp702x_fe_state *st = fe->demodulator_priv;
+	struct vp702x_device_state *dst = st->d->priv;
 	u32 freq = fep->frequency/1000;
 	/*CalFrequency*/
 /*	u16 frequencyRef[16] = { 2, 4, 8, 16, 32, 64, 128, 256, 24, 5, 10, 20, 40, 80, 160, 320 }; */
 	u64 sr;
-	u8 cmd[8] = { 0 },ibuf[10];
+	u8 *cmd;
+
+	mutex_lock(&dst->buf_mutex);
+
+	cmd = dst->buf;
+	memset(cmd, 0, 10);
 
 	cmd[0] = (freq >> 8) & 0x7f;
 	cmd[1] =  freq       & 0xff;
@@ -170,13 +185,15 @@
 	st->status_check_interval = 250;
 	st->next_status_check = jiffies;
 
-	vp702x_usb_inout_op(st->d,cmd,8,ibuf,10,100);
+	vp702x_usb_inout_op(st->d, cmd, 8, cmd, 10, 100);
 
-	if (ibuf[2] == 0 && ibuf[3] == 0)
+	if (cmd[2] == 0 && cmd[3] == 0)
 		deb_fe("tuning failed.\n");
 	else
 		deb_fe("tuning succeeded.\n");
 
+	mutex_unlock(&dst->buf_mutex);
+
 	return 0;
 }
 
@@ -204,27 +221,32 @@
 static int vp702x_fe_send_diseqc_msg (struct dvb_frontend* fe,
 				    struct dvb_diseqc_master_cmd *m)
 {
+	u8 *cmd;
 	struct vp702x_fe_state *st = fe->demodulator_priv;
-	u8 cmd[8],ibuf[10];
-	memset(cmd,0,8);
+	struct vp702x_device_state *dst = st->d->priv;
 
 	deb_fe("%s\n",__func__);
 
 	if (m->msg_len > 4)
 		return -EINVAL;
 
+	mutex_lock(&dst->buf_mutex);
+
+	cmd = dst->buf;
 	cmd[1] = SET_DISEQC_CMD;
 	cmd[2] = m->msg_len;
 	memcpy(&cmd[3], m->msg, m->msg_len);
-	cmd[7] = vp702x_chksum(cmd,0,7);
+	cmd[7] = vp702x_chksum(cmd, 0, 7);
 
-	vp702x_usb_inout_op(st->d,cmd,8,ibuf,10,100);
+	vp702x_usb_inout_op(st->d, cmd, 8, cmd, 10, 100);
 
-	if (ibuf[2] == 0 && ibuf[3] == 0)
+	if (cmd[2] == 0 && cmd[3] == 0)
 		deb_fe("diseqc cmd failed.\n");
 	else
 		deb_fe("diseqc cmd succeeded.\n");
 
+	mutex_unlock(&dst->buf_mutex);
+
 	return 0;
 }
 
@@ -237,7 +259,9 @@
 static int vp702x_fe_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
 {
 	struct vp702x_fe_state *st = fe->demodulator_priv;
-	u8 ibuf[10];
+	struct vp702x_device_state *dst = st->d->priv;
+	u8 *buf;
+
 	deb_fe("%s\n",__func__);
 
 	st->tone_mode = tone;
@@ -247,14 +271,21 @@
 	else
 		st->lnb_buf[2] = 0x00;
 
-	st->lnb_buf[7] = vp702x_chksum(st->lnb_buf,0,7);
+	st->lnb_buf[7] = vp702x_chksum(st->lnb_buf, 0, 7);
 
-	vp702x_usb_inout_op(st->d,st->lnb_buf,8,ibuf,10,100);
-	if (ibuf[2] == 0 && ibuf[3] == 0)
+	mutex_lock(&dst->buf_mutex);
+
+	buf = dst->buf;
+	memcpy(buf, st->lnb_buf, 8);
+
+	vp702x_usb_inout_op(st->d, buf, 8, buf, 10, 100);
+	if (buf[2] == 0 && buf[3] == 0)
 		deb_fe("set_tone cmd failed.\n");
 	else
 		deb_fe("set_tone cmd succeeded.\n");
 
+	mutex_unlock(&dst->buf_mutex);
+
 	return 0;
 }
 
@@ -262,7 +293,8 @@
 		voltage)
 {
 	struct vp702x_fe_state *st = fe->demodulator_priv;
-	u8 ibuf[10];
+	struct vp702x_device_state *dst = st->d->priv;
+	u8 *buf;
 	deb_fe("%s\n",__func__);
 
 	st->voltage = voltage;
@@ -272,14 +304,20 @@
 	else
 		st->lnb_buf[4] = 0x00;
 
-	st->lnb_buf[7] = vp702x_chksum(st->lnb_buf,0,7);
+	st->lnb_buf[7] = vp702x_chksum(st->lnb_buf, 0, 7);
 
-	vp702x_usb_inout_op(st->d,st->lnb_buf,8,ibuf,10,100);
-	if (ibuf[2] == 0 && ibuf[3] == 0)
+	mutex_lock(&dst->buf_mutex);
+
+	buf = dst->buf;
+	memcpy(buf, st->lnb_buf, 8);
+
+	vp702x_usb_inout_op(st->d, buf, 8, buf, 10, 100);
+	if (buf[2] == 0 && buf[3] == 0)
 		deb_fe("set_voltage cmd failed.\n");
 	else
 		deb_fe("set_voltage cmd succeeded.\n");
 
+	mutex_unlock(&dst->buf_mutex);
 	return 0;
 }
 
diff -druN linux-2.6.39-libre/drivers/media/dvb/dvb-usb/vp702x.h linux-3.0-rc7-libre/drivers/media/dvb/dvb-usb/vp702x.h
--- linux-2.6.39-libre/drivers/media/dvb/dvb-usb/vp702x.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/dvb/dvb-usb/vp702x.h	2011-07-11 19:51:52.000000000 -0400
@@ -98,6 +98,13 @@
 #define RESET_TUNER		0xBE
 /* IN  i: 0, v: 0, no extra buffer */
 
+struct vp702x_device_state {
+	struct mutex buf_mutex;
+	int buf_len;
+	u8 *buf;
+};
+
+
 extern struct dvb_frontend * vp702x_fe_attach(struct dvb_usb_device *d);
 
 extern int vp702x_usb_inout_op(struct dvb_usb_device *d, u8 *o, int olen, u8 *i, int ilen, int msec);
diff -druN linux-2.6.39-libre/drivers/media/dvb/dvb-usb/vp7045.c linux-3.0-rc7-libre/drivers/media/dvb/dvb-usb/vp7045.c
--- linux-2.6.39-libre/drivers/media/dvb/dvb-usb/vp7045.c	2011-05-19 02:09:14.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/dvb/dvb-usb/vp7045.c	2011-07-21 06:51:40.000000000 -0400
@@ -28,9 +28,9 @@
 int vp7045_usb_op(struct dvb_usb_device *d, u8 cmd, u8 *out, int outlen, u8 *in, int inlen, int msec)
 {
 	int ret = 0;
-	u8 inbuf[12] = { 0 }, outbuf[20] = { 0 };
+	u8 *buf = d->priv;
 
-	outbuf[0] = cmd;
+	buf[0] = cmd;
 
 	if (outlen > 19)
 		outlen = 19;
@@ -38,19 +38,21 @@
 	if (inlen > 11)
 		inlen = 11;
 
+	ret = mutex_lock_interruptible(&d->usb_mutex);
+	if (ret)
+		return ret;
+
 	if (out != NULL && outlen > 0)
-		memcpy(&outbuf[1], out, outlen);
+		memcpy(&buf[1], out, outlen);
 
 	deb_xfer("out buffer: ");
-	debug_dump(outbuf,outlen+1,deb_xfer);
+	debug_dump(buf, outlen+1, deb_xfer);
 
-	if ((ret = mutex_lock_interruptible(&d->usb_mutex)))
-		return ret;
 
 	if (usb_control_msg(d->udev,
 			usb_sndctrlpipe(d->udev,0),
 			TH_COMMAND_OUT, USB_TYPE_VENDOR | USB_DIR_OUT, 0, 0,
-			outbuf, 20, 2000) != 20) {
+			buf, 20, 2000) != 20) {
 		err("USB control message 'out' went wrong.");
 		ret = -EIO;
 		goto unlock;
@@ -61,17 +63,17 @@
 	if (usb_control_msg(d->udev,
 			usb_rcvctrlpipe(d->udev,0),
 			TH_COMMAND_IN, USB_TYPE_VENDOR | USB_DIR_IN, 0, 0,
-			inbuf, 12, 2000) != 12) {
+			buf, 12, 2000) != 12) {
 		err("USB control message 'in' went wrong.");
 		ret = -EIO;
 		goto unlock;
 	}
 
 	deb_xfer("in buffer: ");
-	debug_dump(inbuf,12,deb_xfer);
+	debug_dump(buf, 12, deb_xfer);
 
 	if (in != NULL && inlen > 0)
-		memcpy(in,&inbuf[1],inlen);
+		memcpy(in, &buf[1], inlen);
 
 unlock:
 	mutex_unlock(&d->usb_mutex);
@@ -222,8 +224,26 @@
 static int vp7045_usb_probe(struct usb_interface *intf,
 		const struct usb_device_id *id)
 {
-	return dvb_usb_device_init(intf, &vp7045_properties,
-				   THIS_MODULE, NULL, adapter_nr);
+	struct dvb_usb_device *d;
+	int ret = dvb_usb_device_init(intf, &vp7045_properties,
+				   THIS_MODULE, &d, adapter_nr);
+	if (ret)
+		return ret;
+
+	d->priv = kmalloc(20, GFP_KERNEL);
+	if (!d->priv) {
+		dvb_usb_device_exit(intf);
+		return -ENOMEM;
+	}
+
+	return ret;
+}
+
+static void vp7045_usb_disconnect(struct usb_interface *intf)
+{
+	struct dvb_usb_device *d = usb_get_intfdata(intf);
+	kfree(d->priv);
+	dvb_usb_device_exit(intf);
 }
 
 static struct usb_device_id vp7045_usb_table [] = {
@@ -238,6 +258,7 @@
 static struct dvb_usb_device_properties vp7045_properties = {
 	.usb_ctrl = CYPRESS_FX2,
 	.firmware = "/*(DEBLOBBED)*/",
+	.size_of_priv = sizeof(u8 *),
 
 	.num_adapters = 1,
 	.adapter = {
@@ -284,7 +305,7 @@
 static struct usb_driver vp7045_usb_driver = {
 	.name		= "dvb_usb_vp7045",
 	.probe		= vp7045_usb_probe,
-	.disconnect = dvb_usb_device_exit,
+	.disconnect	= vp7045_usb_disconnect,
 	.id_table	= vp7045_usb_table,
 };
 
diff -druN linux-2.6.39-libre/drivers/media/dvb/firewire/firedtv-avc.c linux-3.0-rc7-libre/drivers/media/dvb/firewire/firedtv-avc.c
--- linux-2.6.39-libre/drivers/media/dvb/firewire/firedtv-avc.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/dvb/firewire/firedtv-avc.c	2011-07-11 19:51:52.000000000 -0400
@@ -1320,14 +1320,10 @@
 {
 	int ret;
 
-	mutex_lock(&fdtv->avc_mutex);
-
 	ret = fdtv_read(fdtv, addr, data);
 	if (ret < 0)
 		dev_err(fdtv->device, "CMP: read I/O error\n");
 
-	mutex_unlock(&fdtv->avc_mutex);
-
 	return ret;
 }
 
@@ -1335,18 +1331,9 @@
 {
 	int ret;
 
-	mutex_lock(&fdtv->avc_mutex);
-
-	/* data[] is stack-allocated and should not be DMA-mapped. */
-	memcpy(fdtv->avc_data, data, 8);
-
-	ret = fdtv_lock(fdtv, addr, fdtv->avc_data);
+	ret = fdtv_lock(fdtv, addr, 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 -druN linux-2.6.39-libre/drivers/media/dvb/firewire/firedtv-fw.c linux-3.0-rc7-libre/drivers/media/dvb/firewire/firedtv-fw.c
--- linux-2.6.39-libre/drivers/media/dvb/firewire/firedtv-fw.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/dvb/firewire/firedtv-fw.c	2011-07-11 19:51:52.000000000 -0400
@@ -125,6 +125,7 @@
 
 		i = (i + 1) & (N_PACKETS - 1);
 	}
+	fw_iso_context_queue_flush(ctx->context);
 	ctx->current_packet = i;
 }
 
diff -druN linux-2.6.39-libre/drivers/media/dvb/frontends/bsbe1-d01a.h linux-3.0-rc7-libre/drivers/media/dvb/frontends/bsbe1-d01a.h
--- linux-2.6.39-libre/drivers/media/dvb/frontends/bsbe1-d01a.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/media/dvb/frontends/bsbe1-d01a.h	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,146 @@
+/*
+ * bsbe1-d01a.h - ALPS BSBE1-D01A tuner support
+ *
+ * Copyright (C) 2011 Oliver Endriss <o.endriss@gmx.de>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
+ *
+ *
+ * the project's page is at http://www.linuxtv.org
+ */
+
+#ifndef BSBE1_D01A_H
+#define BSBE1_D01A_H
+
+#include "stb6000.h"
+#include "stv0288.h"
+
+static u8 stv0288_bsbe1_d01a_inittab[] = {
+	0x01, 0x15,
+	0x02, 0x20,
+	0x09, 0x0,
+	0x0a, 0x4,
+	0x0b, 0x0,
+	0x0c, 0x0,
+	0x0d, 0x0,
+	0x0e, 0xd4,
+	0x0f, 0x30,
+	0x11, 0x80,
+	0x12, 0x03,
+	0x13, 0x48,
+	0x14, 0x84,
+	0x15, 0x45,
+	0x16, 0xb7,
+	0x17, 0x9c,
+	0x18, 0x0,
+	0x19, 0xa6,
+	0x1a, 0x88,
+	0x1b, 0x8f,
+	0x1c, 0xf0,
+	0x20, 0x0b,
+	0x21, 0x54,
+	0x22, 0x0,
+	0x23, 0x0,
+	0x2b, 0xff,
+	0x2c, 0xf7,
+	0x30, 0x0,
+	0x31, 0x1e,
+	0x32, 0x14,
+	0x33, 0x0f,
+	0x34, 0x09,
+	0x35, 0x0c,
+	0x36, 0x05,
+	0x37, 0x2f,
+	0x38, 0x16,
+	0x39, 0xbd,
+	0x3a, 0x03,
+	0x3b, 0x13,
+	0x3c, 0x11,
+	0x3d, 0x30,
+	0x40, 0x63,
+	0x41, 0x04,
+	0x42, 0x60,
+	0x43, 0x00,
+	0x44, 0x00,
+	0x45, 0x00,
+	0x46, 0x00,
+	0x47, 0x00,
+	0x4a, 0x00,
+	0x50, 0x10,
+	0x51, 0x36,
+	0x52, 0x09,
+	0x53, 0x94,
+	0x54, 0x62,
+	0x55, 0x29,
+	0x56, 0x64,
+	0x57, 0x2b,
+	0x58, 0x54,
+	0x59, 0x86,
+	0x5a, 0x0,
+	0x5b, 0x9b,
+	0x5c, 0x08,
+	0x5d, 0x7f,
+	0x5e, 0x0,
+	0x5f, 0xff,
+	0x70, 0x0,
+	0x71, 0x0,
+	0x72, 0x0,
+	0x74, 0x0,
+	0x75, 0x0,
+	0x76, 0x0,
+	0x81, 0x0,
+	0x82, 0x3f,
+	0x83, 0x3f,
+	0x84, 0x0,
+	0x85, 0x0,
+	0x88, 0x0,
+	0x89, 0x0,
+	0x8a, 0x0,
+	0x8b, 0x0,
+	0x8c, 0x0,
+	0x90, 0x0,
+	0x91, 0x0,
+	0x92, 0x0,
+	0x93, 0x0,
+	0x94, 0x1c,
+	0x97, 0x0,
+	0xa0, 0x48,
+	0xa1, 0x0,
+	0xb0, 0xb8,
+	0xb1, 0x3a,
+	0xb2, 0x10,
+	0xb3, 0x82,
+	0xb4, 0x80,
+	0xb5, 0x82,
+	0xb6, 0x82,
+	0xb7, 0x82,
+	0xb8, 0x20,
+	0xb9, 0x0,
+	0xf0, 0x0,
+	0xf1, 0x0,
+	0xf2, 0xc0,
+	0xff, 0xff,
+};
+
+static struct stv0288_config stv0288_bsbe1_d01a_config = {
+	.demod_address = 0x68,
+	.min_delay_ms = 100,
+	.inittab = stv0288_bsbe1_d01a_inittab,
+};
+
+#endif
diff -druN linux-2.6.39-libre/drivers/media/dvb/frontends/bsru6.h linux-3.0-rc7-libre/drivers/media/dvb/frontends/bsru6.h
--- linux-2.6.39-libre/drivers/media/dvb/frontends/bsru6.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/dvb/frontends/bsru6.h	2011-07-11 19:51:52.000000000 -0400
@@ -27,7 +27,7 @@
 
 static u8 alps_bsru6_inittab[] = {
 	0x01, 0x15,
-	0x02, 0x00,
+	0x02, 0x30,
 	0x03, 0x00,
 	0x04, 0x7d,   /* F22FR = 0x7d, F22 = f_VCO / 128 / 0x7d = 22 kHz */
 	0x05, 0x35,   /* I2CT = 0, SCLT = 1, SDAT = 1 */
diff -druN linux-2.6.39-libre/drivers/media/dvb/frontends/cx24116.c linux-3.0-rc7-libre/drivers/media/dvb/frontends/cx24116.c
--- linux-2.6.39-libre/drivers/media/dvb/frontends/cx24116.c	2011-05-19 02:09:29.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/dvb/frontends/cx24116.c	2011-07-21 06:51:56.000000000 -0400
@@ -137,7 +137,7 @@
 /* SNR measurements */
 static int esno_snr;
 module_param(esno_snr, int, 0644);
-MODULE_PARM_DESC(debug, "SNR return units, 0=PERCENTAGE 0-100, "\
+MODULE_PARM_DESC(esno_snr, "SNR return units, 0=PERCENTAGE 0-100, "\
 	"1=ESNO(db * 10) (default:0)");
 
 enum cmds {
@@ -566,7 +566,7 @@
 {
 	struct cx24116_state *state = fe->demodulator_priv;
 	struct cx24116_cmd cmd;
-	int i, ret;
+	int i, ret, len, max, remaining;
 	unsigned char vers[4];
 
 	dprintk("%s\n", __func__);
@@ -603,8 +603,21 @@
 	cx24116_writereg(state, 0xF5, 0x00);
 	cx24116_writereg(state, 0xF6, 0x00);
 
-	/* write the entire firmware as one transaction */
-	cx24116_writeregN(state, 0xF7, fw->data, fw->size);
+	/* Split firmware to the max I2C write len and write.
+	 * Writes whole firmware as one write when i2c_wr_max is set to 0. */
+	if (state->config->i2c_wr_max)
+		max = state->config->i2c_wr_max;
+	else
+		max = INT_MAX; /* enough for 32k firmware */
+
+	for (remaining = fw->size; remaining > 0; remaining -= max - 1) {
+		len = remaining;
+		if (len > max - 1)
+			len = max - 1;
+
+		cx24116_writeregN(state, 0xF7, &fw->data[fw->size - remaining],
+			len);
+	}
 
 	cx24116_writereg(state, 0xF4, 0x10);
 	cx24116_writereg(state, 0xF0, 0x00);
diff -druN linux-2.6.39-libre/drivers/media/dvb/frontends/cx24116.h linux-3.0-rc7-libre/drivers/media/dvb/frontends/cx24116.h
--- linux-2.6.39-libre/drivers/media/dvb/frontends/cx24116.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/dvb/frontends/cx24116.h	2011-07-11 19:51:52.000000000 -0400
@@ -35,6 +35,9 @@
 
 	/* Need to set MPEG parameters */
 	u8 mpg_clk_pos_pol:0x02;
+
+	/* max bytes I2C provider can write at once */
+	u16 i2c_wr_max;
 };
 
 #if defined(CONFIG_DVB_CX24116) || \
diff -druN linux-2.6.39-libre/drivers/media/dvb/frontends/cxd2820r_c.c linux-3.0-rc7-libre/drivers/media/dvb/frontends/cxd2820r_c.c
--- linux-2.6.39-libre/drivers/media/dvb/frontends/cxd2820r_c.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/media/dvb/frontends/cxd2820r_c.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,338 @@
+/*
+ * Sony CXD2820R demodulator driver
+ *
+ * Copyright (C) 2010 Antti Palosaari <crope@iki.fi>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License along
+ *    with this program; if not, write to the Free Software Foundation, Inc.,
+ *    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+
+#include "cxd2820r_priv.h"
+
+int cxd2820r_set_frontend_c(struct dvb_frontend *fe,
+	struct dvb_frontend_parameters *params)
+{
+	struct cxd2820r_priv *priv = fe->demodulator_priv;
+	struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+	int ret, i;
+	u8 buf[2];
+	u16 if_ctl;
+	u64 num;
+	struct reg_val_mask tab[] = {
+		{ 0x00080, 0x01, 0xff },
+		{ 0x00081, 0x05, 0xff },
+		{ 0x00085, 0x07, 0xff },
+		{ 0x00088, 0x01, 0xff },
+
+		{ 0x00082, 0x20, 0x60 },
+		{ 0x1016a, 0x48, 0xff },
+		{ 0x100a5, 0x00, 0x01 },
+		{ 0x10020, 0x06, 0x07 },
+		{ 0x10059, 0x50, 0xff },
+		{ 0x10087, 0x0c, 0x3c },
+		{ 0x1008b, 0x07, 0xff },
+		{ 0x1001f, priv->cfg.if_agc_polarity << 7, 0x80 },
+		{ 0x10070, priv->cfg.ts_mode, 0xff },
+	};
+
+	dbg("%s: RF=%d SR=%d", __func__, c->frequency, c->symbol_rate);
+
+	/* update GPIOs */
+	ret = cxd2820r_gpio(fe);
+	if (ret)
+		goto error;
+
+	/* program tuner */
+	if (fe->ops.tuner_ops.set_params)
+		fe->ops.tuner_ops.set_params(fe, params);
+
+	if (priv->delivery_system !=  SYS_DVBC_ANNEX_AC) {
+		for (i = 0; i < ARRAY_SIZE(tab); i++) {
+			ret = cxd2820r_wr_reg_mask(priv, tab[i].reg,
+				tab[i].val, tab[i].mask);
+			if (ret)
+				goto error;
+		}
+	}
+
+	priv->delivery_system = SYS_DVBC_ANNEX_AC;
+	priv->ber_running = 0; /* tune stops BER counter */
+
+	num = priv->cfg.if_dvbc;
+	num *= 0x4000;
+	if_ctl = cxd2820r_div_u64_round_closest(num, 41000);
+	buf[0] = (if_ctl >> 8) & 0x3f;
+	buf[1] = (if_ctl >> 0) & 0xff;
+
+	ret = cxd2820r_wr_regs(priv, 0x10042, buf, 2);
+	if (ret)
+		goto error;
+
+	ret = cxd2820r_wr_reg(priv, 0x000ff, 0x08);
+	if (ret)
+		goto error;
+
+	ret = cxd2820r_wr_reg(priv, 0x000fe, 0x01);
+	if (ret)
+		goto error;
+
+	return ret;
+error:
+	dbg("%s: failed:%d", __func__, ret);
+	return ret;
+}
+
+int cxd2820r_get_frontend_c(struct dvb_frontend *fe,
+	struct dvb_frontend_parameters *p)
+{
+	struct cxd2820r_priv *priv = fe->demodulator_priv;
+	struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+	int ret;
+	u8 buf[2];
+
+	ret = cxd2820r_rd_regs(priv, 0x1001a, buf, 2);
+	if (ret)
+		goto error;
+
+	c->symbol_rate = 2500 * ((buf[0] & 0x0f) << 8 | buf[1]);
+
+	ret = cxd2820r_rd_reg(priv, 0x10019, &buf[0]);
+	if (ret)
+		goto error;
+
+	switch ((buf[0] >> 0) & 0x03) {
+	case 0:
+		c->modulation = QAM_16;
+		break;
+	case 1:
+		c->modulation = QAM_32;
+		break;
+	case 2:
+		c->modulation = QAM_64;
+		break;
+	case 3:
+		c->modulation = QAM_128;
+		break;
+	case 4:
+		c->modulation = QAM_256;
+		break;
+	}
+
+	switch ((buf[0] >> 7) & 0x01) {
+	case 0:
+		c->inversion = INVERSION_OFF;
+		break;
+	case 1:
+		c->inversion = INVERSION_ON;
+		break;
+	}
+
+	return ret;
+error:
+	dbg("%s: failed:%d", __func__, ret);
+	return ret;
+}
+
+int cxd2820r_read_ber_c(struct dvb_frontend *fe, u32 *ber)
+{
+	struct cxd2820r_priv *priv = fe->demodulator_priv;
+	int ret;
+	u8 buf[3], start_ber = 0;
+	*ber = 0;
+
+	if (priv->ber_running) {
+		ret = cxd2820r_rd_regs(priv, 0x10076, buf, sizeof(buf));
+		if (ret)
+			goto error;
+
+		if ((buf[2] >> 7) & 0x01 || (buf[2] >> 4) & 0x01) {
+			*ber = (buf[2] & 0x0f) << 16 | buf[1] << 8 | buf[0];
+			start_ber = 1;
+		}
+	} else {
+		priv->ber_running = 1;
+		start_ber = 1;
+	}
+
+	if (start_ber) {
+		/* (re)start BER */
+		ret = cxd2820r_wr_reg(priv, 0x10079, 0x01);
+		if (ret)
+			goto error;
+	}
+
+	return ret;
+error:
+	dbg("%s: failed:%d", __func__, ret);
+	return ret;
+}
+
+int cxd2820r_read_signal_strength_c(struct dvb_frontend *fe,
+	u16 *strength)
+{
+	struct cxd2820r_priv *priv = fe->demodulator_priv;
+	int ret;
+	u8 buf[2];
+	u16 tmp;
+
+	ret = cxd2820r_rd_regs(priv, 0x10049, buf, sizeof(buf));
+	if (ret)
+		goto error;
+
+	tmp = (buf[0] & 0x03) << 8 | buf[1];
+	tmp = (~tmp & 0x03ff);
+
+	if (tmp == 512)
+		/* ~no signal */
+		tmp = 0;
+	else if (tmp > 350)
+		tmp = 350;
+
+	/* scale value to 0x0000-0xffff */
+	*strength = tmp * 0xffff / (350-0);
+
+	return ret;
+error:
+	dbg("%s: failed:%d", __func__, ret);
+	return ret;
+}
+
+int cxd2820r_read_snr_c(struct dvb_frontend *fe, u16 *snr)
+{
+	struct cxd2820r_priv *priv = fe->demodulator_priv;
+	int ret;
+	u8 tmp;
+	unsigned int A, B;
+	/* report SNR in dB * 10 */
+
+	ret = cxd2820r_rd_reg(priv, 0x10019, &tmp);
+	if (ret)
+		goto error;
+
+	if (((tmp >> 0) & 0x03) % 2) {
+		A = 875;
+		B = 650;
+	} else {
+		A = 950;
+		B = 760;
+	}
+
+	ret = cxd2820r_rd_reg(priv, 0x1004d, &tmp);
+	if (ret)
+		goto error;
+
+	#define CXD2820R_LOG2_E_24 24204406 /* log2(e) << 24 */
+	if (tmp)
+		*snr = A * (intlog2(B / tmp) >> 5) / (CXD2820R_LOG2_E_24 >> 5)
+			/ 10;
+	else
+		*snr = 0;
+
+	return ret;
+error:
+	dbg("%s: failed:%d", __func__, ret);
+	return ret;
+}
+
+int cxd2820r_read_ucblocks_c(struct dvb_frontend *fe, u32 *ucblocks)
+{
+	*ucblocks = 0;
+	/* no way to read ? */
+	return 0;
+}
+
+int cxd2820r_read_status_c(struct dvb_frontend *fe, fe_status_t *status)
+{
+	struct cxd2820r_priv *priv = fe->demodulator_priv;
+	int ret;
+	u8 buf[2];
+	*status = 0;
+
+	ret = cxd2820r_rd_regs(priv, 0x10088, buf, sizeof(buf));
+	if (ret)
+		goto error;
+
+	if (((buf[0] >> 0) & 0x01) == 1) {
+		*status |= FE_HAS_SIGNAL | FE_HAS_CARRIER |
+			FE_HAS_VITERBI | FE_HAS_SYNC;
+
+		if (((buf[1] >> 3) & 0x01) == 1) {
+			*status |= FE_HAS_SIGNAL | FE_HAS_CARRIER |
+				FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK;
+		}
+	}
+
+	dbg("%s: lock=%02x %02x", __func__, buf[0], buf[1]);
+
+	return ret;
+error:
+	dbg("%s: failed:%d", __func__, ret);
+	return ret;
+}
+
+int cxd2820r_init_c(struct dvb_frontend *fe)
+{
+	struct cxd2820r_priv *priv = fe->demodulator_priv;
+	int ret;
+
+	ret = cxd2820r_wr_reg(priv, 0x00085, 0x07);
+	if (ret)
+		goto error;
+
+	return ret;
+error:
+	dbg("%s: failed:%d", __func__, ret);
+	return ret;
+}
+
+int cxd2820r_sleep_c(struct dvb_frontend *fe)
+{
+	struct cxd2820r_priv *priv = fe->demodulator_priv;
+	int ret, i;
+	struct reg_val_mask tab[] = {
+		{ 0x000ff, 0x1f, 0xff },
+		{ 0x00085, 0x00, 0xff },
+		{ 0x00088, 0x01, 0xff },
+		{ 0x00081, 0x00, 0xff },
+		{ 0x00080, 0x00, 0xff },
+	};
+
+	dbg("%s", __func__);
+
+	priv->delivery_system = SYS_UNDEFINED;
+
+	for (i = 0; i < ARRAY_SIZE(tab); i++) {
+		ret = cxd2820r_wr_reg_mask(priv, tab[i].reg, tab[i].val,
+			tab[i].mask);
+		if (ret)
+			goto error;
+	}
+
+	return ret;
+error:
+	dbg("%s: failed:%d", __func__, ret);
+	return ret;
+}
+
+int cxd2820r_get_tune_settings_c(struct dvb_frontend *fe,
+	struct dvb_frontend_tune_settings *s)
+{
+	s->min_delay_ms = 500;
+	s->step_size = 0; /* no zigzag */
+	s->max_drift = 0;
+
+	return 0;
+}
+
diff -druN linux-2.6.39-libre/drivers/media/dvb/frontends/cxd2820r_core.c linux-3.0-rc7-libre/drivers/media/dvb/frontends/cxd2820r_core.c
--- linux-2.6.39-libre/drivers/media/dvb/frontends/cxd2820r_core.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/media/dvb/frontends/cxd2820r_core.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,915 @@
+/*
+ * Sony CXD2820R demodulator driver
+ *
+ * Copyright (C) 2010 Antti Palosaari <crope@iki.fi>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License along
+ *    with this program; if not, write to the Free Software Foundation, Inc.,
+ *    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+
+#include "cxd2820r_priv.h"
+
+int cxd2820r_debug;
+module_param_named(debug, cxd2820r_debug, int, 0644);
+MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
+
+/* write multiple registers */
+static int cxd2820r_wr_regs_i2c(struct cxd2820r_priv *priv, u8 i2c, u8 reg,
+	u8 *val, int len)
+{
+	int ret;
+	u8 buf[len+1];
+	struct i2c_msg msg[1] = {
+		{
+			.addr = i2c,
+			.flags = 0,
+			.len = sizeof(buf),
+			.buf = buf,
+		}
+	};
+
+	buf[0] = reg;
+	memcpy(&buf[1], val, len);
+
+	ret = i2c_transfer(priv->i2c, msg, 1);
+	if (ret == 1) {
+		ret = 0;
+	} else {
+		warn("i2c wr failed ret:%d reg:%02x len:%d", ret, reg, len);
+		ret = -EREMOTEIO;
+	}
+	return ret;
+}
+
+/* read multiple registers */
+static int cxd2820r_rd_regs_i2c(struct cxd2820r_priv *priv, u8 i2c, u8 reg,
+	u8 *val, int len)
+{
+	int ret;
+	u8 buf[len];
+	struct i2c_msg msg[2] = {
+		{
+			.addr = i2c,
+			.flags = 0,
+			.len = 1,
+			.buf = &reg,
+		}, {
+			.addr = i2c,
+			.flags = I2C_M_RD,
+			.len = sizeof(buf),
+			.buf = buf,
+		}
+	};
+
+	ret = i2c_transfer(priv->i2c, msg, 2);
+	if (ret == 2) {
+		memcpy(val, buf, len);
+		ret = 0;
+	} else {
+		warn("i2c rd failed ret:%d reg:%02x len:%d", ret, reg, len);
+		ret = -EREMOTEIO;
+	}
+
+	return ret;
+}
+
+/* write multiple registers */
+int cxd2820r_wr_regs(struct cxd2820r_priv *priv, u32 reginfo, u8 *val,
+	int len)
+{
+	int ret;
+	u8 i2c_addr;
+	u8 reg = (reginfo >> 0) & 0xff;
+	u8 bank = (reginfo >> 8) & 0xff;
+	u8 i2c = (reginfo >> 16) & 0x01;
+
+	/* select I2C */
+	if (i2c)
+		i2c_addr = priv->cfg.i2c_address | (1 << 1); /* DVB-C */
+	else
+		i2c_addr = priv->cfg.i2c_address; /* DVB-T/T2 */
+
+	/* switch bank if needed */
+	if (bank != priv->bank[i2c]) {
+		ret = cxd2820r_wr_regs_i2c(priv, i2c_addr, 0x00, &bank, 1);
+		if (ret)
+			return ret;
+		priv->bank[i2c] = bank;
+	}
+	return cxd2820r_wr_regs_i2c(priv, i2c_addr, reg, val, len);
+}
+
+/* read multiple registers */
+int cxd2820r_rd_regs(struct cxd2820r_priv *priv, u32 reginfo, u8 *val,
+	int len)
+{
+	int ret;
+	u8 i2c_addr;
+	u8 reg = (reginfo >> 0) & 0xff;
+	u8 bank = (reginfo >> 8) & 0xff;
+	u8 i2c = (reginfo >> 16) & 0x01;
+
+	/* select I2C */
+	if (i2c)
+		i2c_addr = priv->cfg.i2c_address | (1 << 1); /* DVB-C */
+	else
+		i2c_addr = priv->cfg.i2c_address; /* DVB-T/T2 */
+
+	/* switch bank if needed */
+	if (bank != priv->bank[i2c]) {
+		ret = cxd2820r_wr_regs_i2c(priv, i2c_addr, 0x00, &bank, 1);
+		if (ret)
+			return ret;
+		priv->bank[i2c] = bank;
+	}
+	return cxd2820r_rd_regs_i2c(priv, i2c_addr, reg, val, len);
+}
+
+/* write single register */
+int cxd2820r_wr_reg(struct cxd2820r_priv *priv, u32 reg, u8 val)
+{
+	return cxd2820r_wr_regs(priv, reg, &val, 1);
+}
+
+/* read single register */
+int cxd2820r_rd_reg(struct cxd2820r_priv *priv, u32 reg, u8 *val)
+{
+	return cxd2820r_rd_regs(priv, reg, val, 1);
+}
+
+/* write single register with mask */
+int cxd2820r_wr_reg_mask(struct cxd2820r_priv *priv, u32 reg, u8 val,
+	u8 mask)
+{
+	int ret;
+	u8 tmp;
+
+	/* no need for read if whole reg is written */
+	if (mask != 0xff) {
+		ret = cxd2820r_rd_reg(priv, reg, &tmp);
+		if (ret)
+			return ret;
+
+		val &= mask;
+		tmp &= ~mask;
+		val |= tmp;
+	}
+
+	return cxd2820r_wr_reg(priv, reg, val);
+}
+
+int cxd2820r_gpio(struct dvb_frontend *fe)
+{
+	struct cxd2820r_priv *priv = fe->demodulator_priv;
+	int ret, i;
+	u8 *gpio, tmp0, tmp1;
+	dbg("%s: delsys=%d", __func__, fe->dtv_property_cache.delivery_system);
+
+	switch (fe->dtv_property_cache.delivery_system) {
+	case SYS_DVBT:
+		gpio = priv->cfg.gpio_dvbt;
+		break;
+	case SYS_DVBT2:
+		gpio = priv->cfg.gpio_dvbt2;
+		break;
+	case SYS_DVBC_ANNEX_AC:
+		gpio = priv->cfg.gpio_dvbc;
+		break;
+	default:
+		ret = -EINVAL;
+		goto error;
+	}
+
+	/* update GPIOs only when needed */
+	if (!memcmp(gpio, priv->gpio, sizeof(priv->gpio)))
+		return 0;
+
+	tmp0 = 0x00;
+	tmp1 = 0x00;
+	for (i = 0; i < sizeof(priv->gpio); i++) {
+		/* enable / disable */
+		if (gpio[i] & CXD2820R_GPIO_E)
+			tmp0 |= (2 << 6) >> (2 * i);
+		else
+			tmp0 |= (1 << 6) >> (2 * i);
+
+		/* input / output */
+		if (gpio[i] & CXD2820R_GPIO_I)
+			tmp1 |= (1 << (3 + i));
+		else
+			tmp1 |= (0 << (3 + i));
+
+		/* high / low */
+		if (gpio[i] & CXD2820R_GPIO_H)
+			tmp1 |= (1 << (0 + i));
+		else
+			tmp1 |= (0 << (0 + i));
+
+		dbg("%s: GPIO i=%d %02x %02x", __func__, i, tmp0, tmp1);
+	}
+
+	dbg("%s: wr gpio=%02x %02x", __func__, tmp0, tmp1);
+
+	/* write bits [7:2] */
+	ret = cxd2820r_wr_reg_mask(priv, 0x00089, tmp0, 0xfc);
+	if (ret)
+		goto error;
+
+	/* write bits [5:0] */
+	ret = cxd2820r_wr_reg_mask(priv, 0x0008e, tmp1, 0x3f);
+	if (ret)
+		goto error;
+
+	memcpy(priv->gpio, gpio, sizeof(priv->gpio));
+
+	return ret;
+error:
+	dbg("%s: failed:%d", __func__, ret);
+	return ret;
+}
+
+/* lock FE */
+static int cxd2820r_lock(struct cxd2820r_priv *priv, int active_fe)
+{
+	int ret = 0;
+	dbg("%s: active_fe=%d", __func__, active_fe);
+
+	mutex_lock(&priv->fe_lock);
+
+	/* -1=NONE, 0=DVB-T/T2, 1=DVB-C */
+	if (priv->active_fe == active_fe)
+		;
+	else if (priv->active_fe == -1)
+		priv->active_fe = active_fe;
+	else
+		ret = -EBUSY;
+
+	mutex_unlock(&priv->fe_lock);
+
+	return ret;
+}
+
+/* unlock FE */
+static void cxd2820r_unlock(struct cxd2820r_priv *priv, int active_fe)
+{
+	dbg("%s: active_fe=%d", __func__, active_fe);
+
+	mutex_lock(&priv->fe_lock);
+
+	/* -1=NONE, 0=DVB-T/T2, 1=DVB-C */
+	if (priv->active_fe == active_fe)
+		priv->active_fe = -1;
+
+	mutex_unlock(&priv->fe_lock);
+
+	return;
+}
+
+/* 64 bit div with round closest, like DIV_ROUND_CLOSEST but 64 bit */
+u32 cxd2820r_div_u64_round_closest(u64 dividend, u32 divisor)
+{
+	return div_u64(dividend + (divisor / 2), divisor);
+}
+
+static int cxd2820r_set_frontend(struct dvb_frontend *fe,
+	struct dvb_frontend_parameters *p)
+{
+	struct cxd2820r_priv *priv = fe->demodulator_priv;
+	struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+	int ret;
+	dbg("%s: delsys=%d", __func__, fe->dtv_property_cache.delivery_system);
+
+	if (fe->ops.info.type == FE_OFDM) {
+		/* DVB-T/T2 */
+		ret = cxd2820r_lock(priv, 0);
+		if (ret)
+			return ret;
+
+		switch (priv->delivery_system) {
+		case SYS_UNDEFINED:
+			if (c->delivery_system == SYS_DVBT) {
+				/* SLEEP => DVB-T */
+				ret = cxd2820r_set_frontend_t(fe, p);
+			} else {
+				/* SLEEP => DVB-T2 */
+				ret = cxd2820r_set_frontend_t2(fe, p);
+			}
+			break;
+		case SYS_DVBT:
+			if (c->delivery_system == SYS_DVBT) {
+				/* DVB-T => DVB-T */
+				ret = cxd2820r_set_frontend_t(fe, p);
+			} else if (c->delivery_system == SYS_DVBT2) {
+				/* DVB-T => DVB-T2 */
+				ret = cxd2820r_sleep_t(fe);
+				ret = cxd2820r_set_frontend_t2(fe, p);
+			}
+			break;
+		case SYS_DVBT2:
+			if (c->delivery_system == SYS_DVBT2) {
+				/* DVB-T2 => DVB-T2 */
+				ret = cxd2820r_set_frontend_t2(fe, p);
+			} else if (c->delivery_system == SYS_DVBT) {
+				/* DVB-T2 => DVB-T */
+				ret = cxd2820r_sleep_t2(fe);
+				ret = cxd2820r_set_frontend_t(fe, p);
+			}
+			break;
+		default:
+			dbg("%s: error state=%d", __func__,
+				priv->delivery_system);
+			ret = -EINVAL;
+		}
+	} else {
+		/* DVB-C */
+		ret = cxd2820r_lock(priv, 1);
+		if (ret)
+			return ret;
+
+		ret = cxd2820r_set_frontend_c(fe, p);
+	}
+
+	return ret;
+}
+
+static int cxd2820r_read_status(struct dvb_frontend *fe, fe_status_t *status)
+{
+	struct cxd2820r_priv *priv = fe->demodulator_priv;
+	int ret;
+	dbg("%s: delsys=%d", __func__, fe->dtv_property_cache.delivery_system);
+
+	if (fe->ops.info.type == FE_OFDM) {
+		/* DVB-T/T2 */
+		ret = cxd2820r_lock(priv, 0);
+		if (ret)
+			return ret;
+
+		switch (fe->dtv_property_cache.delivery_system) {
+		case SYS_DVBT:
+			ret = cxd2820r_read_status_t(fe, status);
+			break;
+		case SYS_DVBT2:
+			ret = cxd2820r_read_status_t2(fe, status);
+			break;
+		default:
+			ret = -EINVAL;
+		}
+	} else {
+		/* DVB-C */
+		ret = cxd2820r_lock(priv, 1);
+		if (ret)
+			return ret;
+
+		ret = cxd2820r_read_status_c(fe, status);
+	}
+
+	return ret;
+}
+
+static int cxd2820r_get_frontend(struct dvb_frontend *fe,
+	struct dvb_frontend_parameters *p)
+{
+	struct cxd2820r_priv *priv = fe->demodulator_priv;
+	int ret;
+	dbg("%s: delsys=%d", __func__, fe->dtv_property_cache.delivery_system);
+
+	if (fe->ops.info.type == FE_OFDM) {
+		/* DVB-T/T2 */
+		ret = cxd2820r_lock(priv, 0);
+		if (ret)
+			return ret;
+
+		switch (fe->dtv_property_cache.delivery_system) {
+		case SYS_DVBT:
+			ret = cxd2820r_get_frontend_t(fe, p);
+			break;
+		case SYS_DVBT2:
+			ret = cxd2820r_get_frontend_t2(fe, p);
+			break;
+		default:
+			ret = -EINVAL;
+		}
+	} else {
+		/* DVB-C */
+		ret = cxd2820r_lock(priv, 1);
+		if (ret)
+			return ret;
+
+		ret = cxd2820r_get_frontend_c(fe, p);
+	}
+
+	return ret;
+}
+
+static int cxd2820r_read_ber(struct dvb_frontend *fe, u32 *ber)
+{
+	struct cxd2820r_priv *priv = fe->demodulator_priv;
+	int ret;
+	dbg("%s: delsys=%d", __func__, fe->dtv_property_cache.delivery_system);
+
+	if (fe->ops.info.type == FE_OFDM) {
+		/* DVB-T/T2 */
+		ret = cxd2820r_lock(priv, 0);
+		if (ret)
+			return ret;
+
+		switch (fe->dtv_property_cache.delivery_system) {
+		case SYS_DVBT:
+			ret = cxd2820r_read_ber_t(fe, ber);
+			break;
+		case SYS_DVBT2:
+			ret = cxd2820r_read_ber_t2(fe, ber);
+			break;
+		default:
+			ret = -EINVAL;
+		}
+	} else {
+		/* DVB-C */
+		ret = cxd2820r_lock(priv, 1);
+		if (ret)
+			return ret;
+
+		ret = cxd2820r_read_ber_c(fe, ber);
+	}
+
+	return ret;
+}
+
+static int cxd2820r_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
+{
+	struct cxd2820r_priv *priv = fe->demodulator_priv;
+	int ret;
+	dbg("%s: delsys=%d", __func__, fe->dtv_property_cache.delivery_system);
+
+	if (fe->ops.info.type == FE_OFDM) {
+		/* DVB-T/T2 */
+		ret = cxd2820r_lock(priv, 0);
+		if (ret)
+			return ret;
+
+		switch (fe->dtv_property_cache.delivery_system) {
+		case SYS_DVBT:
+			ret = cxd2820r_read_signal_strength_t(fe, strength);
+			break;
+		case SYS_DVBT2:
+			ret = cxd2820r_read_signal_strength_t2(fe, strength);
+			break;
+		default:
+			ret = -EINVAL;
+		}
+	} else {
+		/* DVB-C */
+		ret = cxd2820r_lock(priv, 1);
+		if (ret)
+			return ret;
+
+		ret = cxd2820r_read_signal_strength_c(fe, strength);
+	}
+
+	return ret;
+}
+
+static int cxd2820r_read_snr(struct dvb_frontend *fe, u16 *snr)
+{
+	struct cxd2820r_priv *priv = fe->demodulator_priv;
+	int ret;
+	dbg("%s: delsys=%d", __func__, fe->dtv_property_cache.delivery_system);
+
+	if (fe->ops.info.type == FE_OFDM) {
+		/* DVB-T/T2 */
+		ret = cxd2820r_lock(priv, 0);
+		if (ret)
+			return ret;
+
+		switch (fe->dtv_property_cache.delivery_system) {
+		case SYS_DVBT:
+			ret = cxd2820r_read_snr_t(fe, snr);
+			break;
+		case SYS_DVBT2:
+			ret = cxd2820r_read_snr_t2(fe, snr);
+			break;
+		default:
+			ret = -EINVAL;
+		}
+	} else {
+		/* DVB-C */
+		ret = cxd2820r_lock(priv, 1);
+		if (ret)
+			return ret;
+
+		ret = cxd2820r_read_snr_c(fe, snr);
+	}
+
+	return ret;
+}
+
+static int cxd2820r_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
+{
+	struct cxd2820r_priv *priv = fe->demodulator_priv;
+	int ret;
+	dbg("%s: delsys=%d", __func__, fe->dtv_property_cache.delivery_system);
+
+	if (fe->ops.info.type == FE_OFDM) {
+		/* DVB-T/T2 */
+		ret = cxd2820r_lock(priv, 0);
+		if (ret)
+			return ret;
+
+		switch (fe->dtv_property_cache.delivery_system) {
+		case SYS_DVBT:
+			ret = cxd2820r_read_ucblocks_t(fe, ucblocks);
+			break;
+		case SYS_DVBT2:
+			ret = cxd2820r_read_ucblocks_t2(fe, ucblocks);
+			break;
+		default:
+			ret = -EINVAL;
+		}
+	} else {
+		/* DVB-C */
+		ret = cxd2820r_lock(priv, 1);
+		if (ret)
+			return ret;
+
+		ret = cxd2820r_read_ucblocks_c(fe, ucblocks);
+	}
+
+	return ret;
+}
+
+static int cxd2820r_init(struct dvb_frontend *fe)
+{
+	struct cxd2820r_priv *priv = fe->demodulator_priv;
+	int ret;
+	dbg("%s: delsys=%d", __func__, fe->dtv_property_cache.delivery_system);
+
+	priv->delivery_system = SYS_UNDEFINED;
+	/* delivery system is unknown at that (init) phase */
+
+	if (fe->ops.info.type == FE_OFDM) {
+		/* DVB-T/T2 */
+		ret = cxd2820r_lock(priv, 0);
+		if (ret)
+			return ret;
+
+		ret = cxd2820r_init_t(fe);
+	} else {
+		/* DVB-C */
+		ret = cxd2820r_lock(priv, 1);
+		if (ret)
+			return ret;
+
+		ret = cxd2820r_init_c(fe);
+	}
+
+	return ret;
+}
+
+static int cxd2820r_sleep(struct dvb_frontend *fe)
+{
+	struct cxd2820r_priv *priv = fe->demodulator_priv;
+	int ret;
+	dbg("%s: delsys=%d", __func__, fe->dtv_property_cache.delivery_system);
+
+	if (fe->ops.info.type == FE_OFDM) {
+		/* DVB-T/T2 */
+		ret = cxd2820r_lock(priv, 0);
+		if (ret)
+			return ret;
+
+		switch (fe->dtv_property_cache.delivery_system) {
+		case SYS_DVBT:
+			ret = cxd2820r_sleep_t(fe);
+			break;
+		case SYS_DVBT2:
+			ret = cxd2820r_sleep_t2(fe);
+			break;
+		default:
+			ret = -EINVAL;
+		}
+
+		cxd2820r_unlock(priv, 0);
+	} else {
+		/* DVB-C */
+		ret = cxd2820r_lock(priv, 1);
+		if (ret)
+			return ret;
+
+		ret = cxd2820r_sleep_c(fe);
+
+		cxd2820r_unlock(priv, 1);
+	}
+
+	return ret;
+}
+
+static int cxd2820r_get_tune_settings(struct dvb_frontend *fe,
+	struct dvb_frontend_tune_settings *s)
+{
+	struct cxd2820r_priv *priv = fe->demodulator_priv;
+	int ret;
+	dbg("%s: delsys=%d", __func__, fe->dtv_property_cache.delivery_system);
+
+	if (fe->ops.info.type == FE_OFDM) {
+		/* DVB-T/T2 */
+		ret = cxd2820r_lock(priv, 0);
+		if (ret)
+			return ret;
+
+		switch (fe->dtv_property_cache.delivery_system) {
+		case SYS_DVBT:
+			ret = cxd2820r_get_tune_settings_t(fe, s);
+			break;
+		case SYS_DVBT2:
+			ret = cxd2820r_get_tune_settings_t2(fe, s);
+			break;
+		default:
+			ret = -EINVAL;
+		}
+	} else {
+		/* DVB-C */
+		ret = cxd2820r_lock(priv, 1);
+		if (ret)
+			return ret;
+
+		ret = cxd2820r_get_tune_settings_c(fe, s);
+	}
+
+	return ret;
+}
+
+static enum dvbfe_search cxd2820r_search(struct dvb_frontend *fe,
+	struct dvb_frontend_parameters *p)
+{
+	struct cxd2820r_priv *priv = fe->demodulator_priv;
+	struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+	int ret, i;
+	fe_status_t status = 0;
+	dbg("%s: delsys=%d", __func__, fe->dtv_property_cache.delivery_system);
+
+	/* switch between DVB-T and DVB-T2 when tune fails */
+	if (priv->last_tune_failed) {
+		if (priv->delivery_system == SYS_DVBT)
+			c->delivery_system = SYS_DVBT2;
+		else
+			c->delivery_system = SYS_DVBT;
+	}
+
+	/* set frontend */
+	ret = cxd2820r_set_frontend(fe, p);
+	if (ret)
+		goto error;
+
+
+	/* frontend lock wait loop count */
+	switch (priv->delivery_system) {
+	case SYS_DVBT:
+		i = 20;
+		break;
+	case SYS_DVBT2:
+		i = 40;
+		break;
+	case SYS_UNDEFINED:
+	default:
+		i = 0;
+		break;
+	}
+
+	/* wait frontend lock */
+	for (; i > 0; i--) {
+		dbg("%s: LOOP=%d", __func__, i);
+		msleep(50);
+		ret = cxd2820r_read_status(fe, &status);
+		if (ret)
+			goto error;
+
+		if (status & FE_HAS_SIGNAL)
+			break;
+	}
+
+	/* check if we have a valid signal */
+	if (status) {
+		priv->last_tune_failed = 0;
+		return DVBFE_ALGO_SEARCH_SUCCESS;
+	} else {
+		priv->last_tune_failed = 1;
+		return DVBFE_ALGO_SEARCH_AGAIN;
+	}
+
+error:
+	dbg("%s: failed:%d", __func__, ret);
+	return DVBFE_ALGO_SEARCH_ERROR;
+}
+
+static int cxd2820r_get_frontend_algo(struct dvb_frontend *fe)
+{
+	return DVBFE_ALGO_CUSTOM;
+}
+
+static void cxd2820r_release(struct dvb_frontend *fe)
+{
+	struct cxd2820r_priv *priv = fe->demodulator_priv;
+	dbg("%s", __func__);
+
+	if (fe->ops.info.type == FE_OFDM) {
+		i2c_del_adapter(&priv->tuner_i2c_adapter);
+		kfree(priv);
+	}
+
+	return;
+}
+
+static u32 cxd2820r_tuner_i2c_func(struct i2c_adapter *adapter)
+{
+	return I2C_FUNC_I2C;
+}
+
+static int cxd2820r_tuner_i2c_xfer(struct i2c_adapter *i2c_adap,
+	struct i2c_msg msg[], int num)
+{
+	struct cxd2820r_priv *priv = i2c_get_adapdata(i2c_adap);
+	u8 obuf[msg[0].len + 2];
+	struct i2c_msg msg2[2] = {
+		{
+			.addr = priv->cfg.i2c_address,
+			.flags = 0,
+			.len = sizeof(obuf),
+			.buf = obuf,
+		}, {
+			.addr = priv->cfg.i2c_address,
+			.flags = I2C_M_RD,
+			.len = msg[1].len,
+			.buf = msg[1].buf,
+		}
+	};
+
+	obuf[0] = 0x09;
+	obuf[1] = (msg[0].addr << 1);
+	if (num == 2) { /* I2C read */
+		obuf[1] = (msg[0].addr << 1) | I2C_M_RD; /* I2C RD flag */
+		msg2[0].len = sizeof(obuf) - 1; /* maybe HW bug ? */
+	}
+	memcpy(&obuf[2], msg[0].buf, msg[0].len);
+
+	return i2c_transfer(priv->i2c, msg2, num);
+}
+
+static struct i2c_algorithm cxd2820r_tuner_i2c_algo = {
+	.master_xfer   = cxd2820r_tuner_i2c_xfer,
+	.functionality = cxd2820r_tuner_i2c_func,
+};
+
+struct i2c_adapter *cxd2820r_get_tuner_i2c_adapter(struct dvb_frontend *fe)
+{
+	struct cxd2820r_priv *priv = fe->demodulator_priv;
+	return &priv->tuner_i2c_adapter;
+}
+EXPORT_SYMBOL(cxd2820r_get_tuner_i2c_adapter);
+
+static struct dvb_frontend_ops cxd2820r_ops[2];
+
+struct dvb_frontend *cxd2820r_attach(const struct cxd2820r_config *cfg,
+	struct i2c_adapter *i2c, struct dvb_frontend *fe)
+{
+	int ret;
+	struct cxd2820r_priv *priv = NULL;
+	u8 tmp;
+
+	if (fe == NULL) {
+		/* FE0 */
+		/* allocate memory for the internal priv */
+		priv = kzalloc(sizeof(struct cxd2820r_priv), GFP_KERNEL);
+		if (priv == NULL)
+			goto error;
+
+		/* setup the priv */
+		priv->i2c = i2c;
+		memcpy(&priv->cfg, cfg, sizeof(struct cxd2820r_config));
+		mutex_init(&priv->fe_lock);
+
+		priv->active_fe = -1; /* NONE */
+
+		/* check if the demod is there */
+		priv->bank[0] = priv->bank[1] = 0xff;
+		ret = cxd2820r_rd_reg(priv, 0x000fd, &tmp);
+		dbg("%s: chip id=%02x", __func__, tmp);
+		if (ret || tmp != 0xe1)
+			goto error;
+
+		/* create frontends */
+		memcpy(&priv->fe[0].ops, &cxd2820r_ops[0],
+			sizeof(struct dvb_frontend_ops));
+		memcpy(&priv->fe[1].ops, &cxd2820r_ops[1],
+			sizeof(struct dvb_frontend_ops));
+
+		priv->fe[0].demodulator_priv = priv;
+		priv->fe[1].demodulator_priv = priv;
+
+		/* create tuner i2c adapter */
+		strlcpy(priv->tuner_i2c_adapter.name,
+			"CXD2820R tuner I2C adapter",
+			sizeof(priv->tuner_i2c_adapter.name));
+		priv->tuner_i2c_adapter.algo = &cxd2820r_tuner_i2c_algo;
+		priv->tuner_i2c_adapter.algo_data = NULL;
+		i2c_set_adapdata(&priv->tuner_i2c_adapter, priv);
+		if (i2c_add_adapter(&priv->tuner_i2c_adapter) < 0) {
+			err("tuner I2C bus could not be initialized");
+			goto error;
+		}
+
+		return &priv->fe[0];
+
+	} else {
+		/* FE1: FE0 given as pointer, just return FE1 we have
+		 * already created */
+		priv = fe->demodulator_priv;
+		return &priv->fe[1];
+	}
+
+error:
+	kfree(priv);
+	return NULL;
+}
+EXPORT_SYMBOL(cxd2820r_attach);
+
+static struct dvb_frontend_ops cxd2820r_ops[2] = {
+	{
+		/* DVB-T/T2 */
+		.info = {
+			.name = "Sony CXD2820R (DVB-T/T2)",
+			.type = FE_OFDM,
+			.caps =
+				FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 |
+				FE_CAN_FEC_3_4 | FE_CAN_FEC_5_6 |
+				FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
+				FE_CAN_QPSK | FE_CAN_QAM_16 |
+				FE_CAN_QAM_64 | FE_CAN_QAM_256 |
+				FE_CAN_QAM_AUTO |
+				FE_CAN_TRANSMISSION_MODE_AUTO |
+				FE_CAN_GUARD_INTERVAL_AUTO |
+				FE_CAN_HIERARCHY_AUTO |
+				FE_CAN_MUTE_TS |
+				FE_CAN_2G_MODULATION
+		},
+
+		.release = cxd2820r_release,
+		.init = cxd2820r_init,
+		.sleep = cxd2820r_sleep,
+
+		.get_tune_settings = cxd2820r_get_tune_settings,
+
+		.get_frontend = cxd2820r_get_frontend,
+
+		.get_frontend_algo = cxd2820r_get_frontend_algo,
+		.search = cxd2820r_search,
+
+		.read_status = cxd2820r_read_status,
+		.read_snr = cxd2820r_read_snr,
+		.read_ber = cxd2820r_read_ber,
+		.read_ucblocks = cxd2820r_read_ucblocks,
+		.read_signal_strength = cxd2820r_read_signal_strength,
+	},
+	{
+		/* DVB-C */
+		.info = {
+			.name = "Sony CXD2820R (DVB-C)",
+			.type = FE_QAM,
+			.caps =
+				FE_CAN_QAM_16 | FE_CAN_QAM_32 | FE_CAN_QAM_64 |
+				FE_CAN_QAM_128 | FE_CAN_QAM_256 |
+				FE_CAN_FEC_AUTO
+		},
+
+		.release = cxd2820r_release,
+		.init = cxd2820r_init,
+		.sleep = cxd2820r_sleep,
+
+		.get_tune_settings = cxd2820r_get_tune_settings,
+
+		.set_frontend = cxd2820r_set_frontend,
+		.get_frontend = cxd2820r_get_frontend,
+
+		.read_status = cxd2820r_read_status,
+		.read_snr = cxd2820r_read_snr,
+		.read_ber = cxd2820r_read_ber,
+		.read_ucblocks = cxd2820r_read_ucblocks,
+		.read_signal_strength = cxd2820r_read_signal_strength,
+	},
+};
+
+
+MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
+MODULE_DESCRIPTION("Sony CXD2820R demodulator driver");
+MODULE_LICENSE("GPL");
diff -druN linux-2.6.39-libre/drivers/media/dvb/frontends/cxd2820r.h linux-3.0-rc7-libre/drivers/media/dvb/frontends/cxd2820r.h
--- linux-2.6.39-libre/drivers/media/dvb/frontends/cxd2820r.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/media/dvb/frontends/cxd2820r.h	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,118 @@
+/*
+ * Sony CXD2820R demodulator driver
+ *
+ * Copyright (C) 2010 Antti Palosaari <crope@iki.fi>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License along
+ *    with this program; if not, write to the Free Software Foundation, Inc.,
+ *    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+
+#ifndef CXD2820R_H
+#define CXD2820R_H
+
+#include <linux/dvb/frontend.h>
+
+#define CXD2820R_GPIO_D (0 << 0) /* disable */
+#define CXD2820R_GPIO_E (1 << 0) /* enable */
+#define CXD2820R_GPIO_O (0 << 1) /* output */
+#define CXD2820R_GPIO_I (1 << 1) /* input */
+#define CXD2820R_GPIO_L (0 << 2) /* output low */
+#define CXD2820R_GPIO_H (1 << 2) /* output high */
+
+#define CXD2820R_TS_SERIAL        0x08
+#define CXD2820R_TS_SERIAL_MSB    0x28
+#define CXD2820R_TS_PARALLEL      0x30
+#define CXD2820R_TS_PARALLEL_MSB  0x70
+
+struct cxd2820r_config {
+	/* Demodulator I2C address.
+	 * Driver determines DVB-C slave I2C address automatically from master
+	 * address.
+	 * Default: none, must set
+	 * Values: 0x6c, 0x6d
+	 */
+	u8 i2c_address;
+
+	/* TS output mode.
+	 * Default: none, must set.
+	 * Values:
+	 */
+	u8 ts_mode;
+
+	/* IF AGC polarity.
+	 * Default: 0
+	 * Values: 0, 1
+	 */
+	int if_agc_polarity:1;
+
+	/* Spectrum inversion.
+	 * Default: 0
+	 * Values: 0, 1
+	 */
+	int spec_inv:1;
+
+	/* IFs for all used modes.
+	 * Default: none, must set
+	 * Values: <kHz>
+	 */
+	u16 if_dvbt_6;
+	u16 if_dvbt_7;
+	u16 if_dvbt_8;
+	u16 if_dvbt2_5;
+	u16 if_dvbt2_6;
+	u16 if_dvbt2_7;
+	u16 if_dvbt2_8;
+	u16 if_dvbc;
+
+	/* GPIOs for all used modes.
+	 * Default: none, disabled
+	 * Values: <see above>
+	 */
+	u8 gpio_dvbt[3];
+	u8 gpio_dvbt2[3];
+	u8 gpio_dvbc[3];
+};
+
+
+#if defined(CONFIG_DVB_CXD2820R) || \
+	(defined(CONFIG_DVB_CXD2820R_MODULE) && defined(MODULE))
+extern struct dvb_frontend *cxd2820r_attach(
+	const struct cxd2820r_config *config,
+	struct i2c_adapter *i2c,
+	struct dvb_frontend *fe
+);
+extern struct i2c_adapter *cxd2820r_get_tuner_i2c_adapter(
+	struct dvb_frontend *fe
+);
+#else
+static inline struct dvb_frontend *cxd2820r_attach(
+	const struct cxd2820r_config *config,
+	struct i2c_adapter *i2c,
+	struct dvb_frontend *fe
+)
+{
+	printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+	return NULL;
+}
+static inline struct i2c_adapter *cxd2820r_get_tuner_i2c_adapter(
+	struct dvb_frontend *fe
+)
+{
+	return NULL;
+}
+
+#endif
+
+#endif /* CXD2820R_H */
diff -druN linux-2.6.39-libre/drivers/media/dvb/frontends/cxd2820r_priv.h linux-3.0-rc7-libre/drivers/media/dvb/frontends/cxd2820r_priv.h
--- linux-2.6.39-libre/drivers/media/dvb/frontends/cxd2820r_priv.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/media/dvb/frontends/cxd2820r_priv.h	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,166 @@
+/*
+ * Sony CXD2820R demodulator driver
+ *
+ * Copyright (C) 2010 Antti Palosaari <crope@iki.fi>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License along
+ *    with this program; if not, write to the Free Software Foundation, Inc.,
+ *    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+
+#ifndef CXD2820R_PRIV_H
+#define CXD2820R_PRIV_H
+
+#include <linux/dvb/version.h>
+#include "dvb_frontend.h"
+#include "dvb_math.h"
+#include "cxd2820r.h"
+
+#define LOG_PREFIX "cxd2820r"
+
+#undef dbg
+#define dbg(f, arg...) \
+	if (cxd2820r_debug) \
+		printk(KERN_INFO   LOG_PREFIX": " f "\n" , ## arg)
+#undef err
+#define err(f, arg...)  printk(KERN_ERR     LOG_PREFIX": " f "\n" , ## arg)
+#undef info
+#define info(f, arg...) printk(KERN_INFO    LOG_PREFIX": " f "\n" , ## arg)
+#undef warn
+#define warn(f, arg...) printk(KERN_WARNING LOG_PREFIX": " f "\n" , ## arg)
+
+struct reg_val_mask {
+	u32 reg;
+	u8  val;
+	u8  mask;
+};
+
+struct cxd2820r_priv {
+	struct i2c_adapter *i2c;
+	struct dvb_frontend fe[2];
+	struct cxd2820r_config cfg;
+	struct i2c_adapter tuner_i2c_adapter;
+
+	struct mutex fe_lock; /* FE lock */
+	int active_fe:2; /* FE lock, -1=NONE, 0=DVB-T/T2, 1=DVB-C */
+
+	int ber_running:1;
+
+	u8 bank[2];
+	u8 gpio[3];
+
+	fe_delivery_system_t delivery_system;
+	int last_tune_failed:1; /* for switch between T and T2 tune */
+};
+
+/* cxd2820r_core.c */
+
+extern int cxd2820r_debug;
+
+int cxd2820r_gpio(struct dvb_frontend *fe);
+
+int cxd2820r_wr_reg_mask(struct cxd2820r_priv *priv, u32 reg, u8 val,
+	u8 mask);
+
+int cxd2820r_wr_regs(struct cxd2820r_priv *priv, u32 reginfo, u8 *val,
+	int len);
+
+u32 cxd2820r_div_u64_round_closest(u64 dividend, u32 divisor);
+
+int cxd2820r_wr_regs(struct cxd2820r_priv *priv, u32 reginfo, u8 *val,
+	int len);
+
+int cxd2820r_rd_regs(struct cxd2820r_priv *priv, u32 reginfo, u8 *val,
+	int len);
+
+int cxd2820r_wr_reg(struct cxd2820r_priv *priv, u32 reg, u8 val);
+
+int cxd2820r_rd_reg(struct cxd2820r_priv *priv, u32 reg, u8 *val);
+
+/* cxd2820r_c.c */
+
+int cxd2820r_get_frontend_c(struct dvb_frontend *fe,
+	struct dvb_frontend_parameters *p);
+
+int cxd2820r_set_frontend_c(struct dvb_frontend *fe,
+	struct dvb_frontend_parameters *params);
+
+int cxd2820r_read_status_c(struct dvb_frontend *fe, fe_status_t *status);
+
+int cxd2820r_read_ber_c(struct dvb_frontend *fe, u32 *ber);
+
+int cxd2820r_read_signal_strength_c(struct dvb_frontend *fe, u16 *strength);
+
+int cxd2820r_read_snr_c(struct dvb_frontend *fe, u16 *snr);
+
+int cxd2820r_read_ucblocks_c(struct dvb_frontend *fe, u32 *ucblocks);
+
+int cxd2820r_init_c(struct dvb_frontend *fe);
+
+int cxd2820r_sleep_c(struct dvb_frontend *fe);
+
+int cxd2820r_get_tune_settings_c(struct dvb_frontend *fe,
+	struct dvb_frontend_tune_settings *s);
+
+/* cxd2820r_t.c */
+
+int cxd2820r_get_frontend_t(struct dvb_frontend *fe,
+	struct dvb_frontend_parameters *p);
+
+int cxd2820r_set_frontend_t(struct dvb_frontend *fe,
+	struct dvb_frontend_parameters *params);
+
+int cxd2820r_read_status_t(struct dvb_frontend *fe, fe_status_t *status);
+
+int cxd2820r_read_ber_t(struct dvb_frontend *fe, u32 *ber);
+
+int cxd2820r_read_signal_strength_t(struct dvb_frontend *fe, u16 *strength);
+
+int cxd2820r_read_snr_t(struct dvb_frontend *fe, u16 *snr);
+
+int cxd2820r_read_ucblocks_t(struct dvb_frontend *fe, u32 *ucblocks);
+
+int cxd2820r_init_t(struct dvb_frontend *fe);
+
+int cxd2820r_sleep_t(struct dvb_frontend *fe);
+
+int cxd2820r_get_tune_settings_t(struct dvb_frontend *fe,
+	struct dvb_frontend_tune_settings *s);
+
+/* cxd2820r_t2.c */
+
+int cxd2820r_get_frontend_t2(struct dvb_frontend *fe,
+	struct dvb_frontend_parameters *p);
+
+int cxd2820r_set_frontend_t2(struct dvb_frontend *fe,
+	struct dvb_frontend_parameters *params);
+
+int cxd2820r_read_status_t2(struct dvb_frontend *fe, fe_status_t *status);
+
+int cxd2820r_read_ber_t2(struct dvb_frontend *fe, u32 *ber);
+
+int cxd2820r_read_signal_strength_t2(struct dvb_frontend *fe, u16 *strength);
+
+int cxd2820r_read_snr_t2(struct dvb_frontend *fe, u16 *snr);
+
+int cxd2820r_read_ucblocks_t2(struct dvb_frontend *fe, u32 *ucblocks);
+
+int cxd2820r_init_t2(struct dvb_frontend *fe);
+
+int cxd2820r_sleep_t2(struct dvb_frontend *fe);
+
+int cxd2820r_get_tune_settings_t2(struct dvb_frontend *fe,
+	struct dvb_frontend_tune_settings *s);
+
+#endif /* CXD2820R_PRIV_H */
diff -druN linux-2.6.39-libre/drivers/media/dvb/frontends/cxd2820r_t2.c linux-3.0-rc7-libre/drivers/media/dvb/frontends/cxd2820r_t2.c
--- linux-2.6.39-libre/drivers/media/dvb/frontends/cxd2820r_t2.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/media/dvb/frontends/cxd2820r_t2.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,423 @@
+/*
+ * Sony CXD2820R demodulator driver
+ *
+ * Copyright (C) 2010 Antti Palosaari <crope@iki.fi>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License along
+ *    with this program; if not, write to the Free Software Foundation, Inc.,
+ *    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+
+#include "cxd2820r_priv.h"
+
+int cxd2820r_set_frontend_t2(struct dvb_frontend *fe,
+	struct dvb_frontend_parameters *params)
+{
+	struct cxd2820r_priv *priv = fe->demodulator_priv;
+	struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+	int ret, i;
+	u32 if_khz, if_ctl;
+	u64 num;
+	u8 buf[3], bw_param;
+	u8 bw_params1[][5] = {
+		{ 0x1c, 0xb3, 0x33, 0x33, 0x33 }, /* 5 MHz */
+		{ 0x17, 0xea, 0xaa, 0xaa, 0xaa }, /* 6 MHz */
+		{ 0x14, 0x80, 0x00, 0x00, 0x00 }, /* 7 MHz */
+		{ 0x11, 0xf0, 0x00, 0x00, 0x00 }, /* 8 MHz */
+	};
+	struct reg_val_mask tab[] = {
+		{ 0x00080, 0x02, 0xff },
+		{ 0x00081, 0x20, 0xff },
+		{ 0x00085, 0x07, 0xff },
+		{ 0x00088, 0x01, 0xff },
+		{ 0x02069, 0x01, 0xff },
+
+		{ 0x0207f, 0x2a, 0xff },
+		{ 0x02082, 0x0a, 0xff },
+		{ 0x02083, 0x0a, 0xff },
+		{ 0x020cb, priv->cfg.if_agc_polarity << 6, 0x40 },
+		{ 0x02070, priv->cfg.ts_mode, 0xff },
+		{ 0x020b5, priv->cfg.spec_inv << 4, 0x10 },
+		{ 0x02567, 0x07, 0x0f },
+		{ 0x02569, 0x03, 0x03 },
+		{ 0x02595, 0x1a, 0xff },
+		{ 0x02596, 0x50, 0xff },
+		{ 0x02a8c, 0x00, 0xff },
+		{ 0x02a8d, 0x34, 0xff },
+		{ 0x02a45, 0x06, 0x07 },
+		{ 0x03f10, 0x0d, 0xff },
+		{ 0x03f11, 0x02, 0xff },
+		{ 0x03f12, 0x01, 0xff },
+		{ 0x03f23, 0x2c, 0xff },
+		{ 0x03f51, 0x13, 0xff },
+		{ 0x03f52, 0x01, 0xff },
+		{ 0x03f53, 0x00, 0xff },
+		{ 0x027e6, 0x14, 0xff },
+		{ 0x02786, 0x02, 0x07 },
+		{ 0x02787, 0x40, 0xe0 },
+		{ 0x027ef, 0x10, 0x18 },
+	};
+
+	dbg("%s: RF=%d BW=%d", __func__, c->frequency, c->bandwidth_hz);
+
+	/* update GPIOs */
+	ret = cxd2820r_gpio(fe);
+	if (ret)
+		goto error;
+
+	/* program tuner */
+	if (fe->ops.tuner_ops.set_params)
+		fe->ops.tuner_ops.set_params(fe, params);
+
+	if (priv->delivery_system != SYS_DVBT2) {
+		for (i = 0; i < ARRAY_SIZE(tab); i++) {
+			ret = cxd2820r_wr_reg_mask(priv, tab[i].reg,
+				tab[i].val, tab[i].mask);
+			if (ret)
+				goto error;
+		}
+	}
+
+	priv->delivery_system = SYS_DVBT2;
+
+	switch (c->bandwidth_hz) {
+	case 5000000:
+		if_khz = priv->cfg.if_dvbt2_5;
+		i = 0;
+		bw_param = 3;
+		break;
+	case 6000000:
+		if_khz = priv->cfg.if_dvbt2_6;
+		i = 1;
+		bw_param = 2;
+		break;
+	case 7000000:
+		if_khz = priv->cfg.if_dvbt2_7;
+		i = 2;
+		bw_param = 1;
+		break;
+	case 8000000:
+		if_khz = priv->cfg.if_dvbt2_8;
+		i = 3;
+		bw_param = 0;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	num = if_khz;
+	num *= 0x1000000;
+	if_ctl = cxd2820r_div_u64_round_closest(num, 41000);
+	buf[0] = ((if_ctl >> 16) & 0xff);
+	buf[1] = ((if_ctl >>  8) & 0xff);
+	buf[2] = ((if_ctl >>  0) & 0xff);
+
+	ret = cxd2820r_wr_regs(priv, 0x020b6, buf, 3);
+	if (ret)
+		goto error;
+
+	ret = cxd2820r_wr_regs(priv, 0x0209f, bw_params1[i], 5);
+	if (ret)
+		goto error;
+
+	ret = cxd2820r_wr_reg_mask(priv, 0x020d7, bw_param << 6, 0xc0);
+	if (ret)
+		goto error;
+
+	ret = cxd2820r_wr_reg(priv, 0x000ff, 0x08);
+	if (ret)
+		goto error;
+
+	ret = cxd2820r_wr_reg(priv, 0x000fe, 0x01);
+	if (ret)
+		goto error;
+
+	return ret;
+error:
+	dbg("%s: failed:%d", __func__, ret);
+	return ret;
+
+}
+
+int cxd2820r_get_frontend_t2(struct dvb_frontend *fe,
+	struct dvb_frontend_parameters *p)
+{
+	struct cxd2820r_priv *priv = fe->demodulator_priv;
+	struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+	int ret;
+	u8 buf[2];
+
+	ret = cxd2820r_rd_regs(priv, 0x0205c, buf, 2);
+	if (ret)
+		goto error;
+
+	switch ((buf[0] >> 0) & 0x07) {
+	case 0:
+		c->transmission_mode = TRANSMISSION_MODE_2K;
+		break;
+	case 1:
+		c->transmission_mode = TRANSMISSION_MODE_8K;
+		break;
+	case 2:
+		c->transmission_mode = TRANSMISSION_MODE_4K;
+		break;
+	case 3:
+		c->transmission_mode = TRANSMISSION_MODE_1K;
+		break;
+	case 4:
+		c->transmission_mode = TRANSMISSION_MODE_16K;
+		break;
+	case 5:
+		c->transmission_mode = TRANSMISSION_MODE_32K;
+		break;
+	}
+
+	switch ((buf[1] >> 4) & 0x07) {
+	case 0:
+		c->guard_interval = GUARD_INTERVAL_1_32;
+		break;
+	case 1:
+		c->guard_interval = GUARD_INTERVAL_1_16;
+		break;
+	case 2:
+		c->guard_interval = GUARD_INTERVAL_1_8;
+		break;
+	case 3:
+		c->guard_interval = GUARD_INTERVAL_1_4;
+		break;
+	case 4:
+		c->guard_interval = GUARD_INTERVAL_1_128;
+		break;
+	case 5:
+		c->guard_interval = GUARD_INTERVAL_19_128;
+		break;
+	case 6:
+		c->guard_interval = GUARD_INTERVAL_19_256;
+		break;
+	}
+
+	ret = cxd2820r_rd_regs(priv, 0x0225b, buf, 2);
+	if (ret)
+		goto error;
+
+	switch ((buf[0] >> 0) & 0x07) {
+	case 0:
+		c->fec_inner = FEC_1_2;
+		break;
+	case 1:
+		c->fec_inner = FEC_3_5;
+		break;
+	case 2:
+		c->fec_inner = FEC_2_3;
+		break;
+	case 3:
+		c->fec_inner = FEC_3_4;
+		break;
+	case 4:
+		c->fec_inner = FEC_4_5;
+		break;
+	case 5:
+		c->fec_inner = FEC_5_6;
+		break;
+	}
+
+	switch ((buf[1] >> 0) & 0x07) {
+	case 0:
+		c->modulation = QPSK;
+		break;
+	case 1:
+		c->modulation = QAM_16;
+		break;
+	case 2:
+		c->modulation = QAM_64;
+		break;
+	case 3:
+		c->modulation = QAM_256;
+		break;
+	}
+
+	ret = cxd2820r_rd_reg(priv, 0x020b5, &buf[0]);
+	if (ret)
+		goto error;
+
+	switch ((buf[0] >> 4) & 0x01) {
+	case 0:
+		c->inversion = INVERSION_OFF;
+		break;
+	case 1:
+		c->inversion = INVERSION_ON;
+		break;
+	}
+
+	return ret;
+error:
+	dbg("%s: failed:%d", __func__, ret);
+	return ret;
+}
+
+int cxd2820r_read_status_t2(struct dvb_frontend *fe, fe_status_t *status)
+{
+	struct cxd2820r_priv *priv = fe->demodulator_priv;
+	int ret;
+	u8 buf[1];
+	*status = 0;
+
+	ret = cxd2820r_rd_reg(priv, 0x02010 , &buf[0]);
+	if (ret)
+		goto error;
+
+	if ((buf[0] & 0x07) == 6) {
+		if (((buf[0] >> 5) & 0x01) == 1) {
+			*status |= FE_HAS_SIGNAL | FE_HAS_CARRIER |
+				FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK;
+		} else {
+			*status |= FE_HAS_SIGNAL | FE_HAS_CARRIER |
+				FE_HAS_VITERBI | FE_HAS_SYNC;
+		}
+	}
+
+	dbg("%s: lock=%02x", __func__, buf[0]);
+
+	return ret;
+error:
+	dbg("%s: failed:%d", __func__, ret);
+	return ret;
+}
+
+int cxd2820r_read_ber_t2(struct dvb_frontend *fe, u32 *ber)
+{
+	struct cxd2820r_priv *priv = fe->demodulator_priv;
+	int ret;
+	u8 buf[4];
+	unsigned int errbits;
+	*ber = 0;
+	/* FIXME: correct calculation */
+
+	ret = cxd2820r_rd_regs(priv, 0x02039, buf, sizeof(buf));
+	if (ret)
+		goto error;
+
+	if ((buf[0] >> 4) & 0x01) {
+		errbits = (buf[0] & 0x0f) << 24 | buf[1] << 16 |
+			buf[2] << 8 | buf[3];
+
+		if (errbits)
+			*ber = errbits * 64 / 16588800;
+	}
+
+	return ret;
+error:
+	dbg("%s: failed:%d", __func__, ret);
+	return ret;
+}
+
+int cxd2820r_read_signal_strength_t2(struct dvb_frontend *fe,
+	u16 *strength)
+{
+	struct cxd2820r_priv *priv = fe->demodulator_priv;
+	int ret;
+	u8 buf[2];
+	u16 tmp;
+
+	ret = cxd2820r_rd_regs(priv, 0x02026, buf, sizeof(buf));
+	if (ret)
+		goto error;
+
+	tmp = (buf[0] & 0x0f) << 8 | buf[1];
+	tmp = ~tmp & 0x0fff;
+
+	/* scale value to 0x0000-0xffff from 0x0000-0x0fff */
+	*strength = tmp * 0xffff / 0x0fff;
+
+	return ret;
+error:
+	dbg("%s: failed:%d", __func__, ret);
+	return ret;
+}
+
+int cxd2820r_read_snr_t2(struct dvb_frontend *fe, u16 *snr)
+{
+	struct cxd2820r_priv *priv = fe->demodulator_priv;
+	int ret;
+	u8 buf[2];
+	u16 tmp;
+	/* report SNR in dB * 10 */
+
+	ret = cxd2820r_rd_regs(priv, 0x02028, buf, sizeof(buf));
+	if (ret)
+		goto error;
+
+	tmp = (buf[0] & 0x0f) << 8 | buf[1];
+	#define CXD2820R_LOG10_8_24 15151336 /* log10(8) << 24 */
+	if (tmp)
+		*snr = (intlog10(tmp) - CXD2820R_LOG10_8_24) / ((1 << 24)
+			/ 100);
+	else
+		*snr = 0;
+
+	dbg("%s: dBx10=%d val=%04x", __func__, *snr, tmp);
+
+	return ret;
+error:
+	dbg("%s: failed:%d", __func__, ret);
+	return ret;
+}
+
+int cxd2820r_read_ucblocks_t2(struct dvb_frontend *fe, u32 *ucblocks)
+{
+	*ucblocks = 0;
+	/* no way to read ? */
+	return 0;
+}
+
+int cxd2820r_sleep_t2(struct dvb_frontend *fe)
+{
+	struct cxd2820r_priv *priv = fe->demodulator_priv;
+	int ret, i;
+	struct reg_val_mask tab[] = {
+		{ 0x000ff, 0x1f, 0xff },
+		{ 0x00085, 0x00, 0xff },
+		{ 0x00088, 0x01, 0xff },
+		{ 0x02069, 0x00, 0xff },
+		{ 0x00081, 0x00, 0xff },
+		{ 0x00080, 0x00, 0xff },
+	};
+
+	dbg("%s", __func__);
+
+	for (i = 0; i < ARRAY_SIZE(tab); i++) {
+		ret = cxd2820r_wr_reg_mask(priv, tab[i].reg, tab[i].val,
+			tab[i].mask);
+		if (ret)
+			goto error;
+	}
+
+	priv->delivery_system = SYS_UNDEFINED;
+
+	return ret;
+error:
+	dbg("%s: failed:%d", __func__, ret);
+	return ret;
+}
+
+int cxd2820r_get_tune_settings_t2(struct dvb_frontend *fe,
+	struct dvb_frontend_tune_settings *s)
+{
+	s->min_delay_ms = 1500;
+	s->step_size = fe->ops.info.frequency_stepsize * 2;
+	s->max_drift = (fe->ops.info.frequency_stepsize * 2) + 1;
+
+	return 0;
+}
+
diff -druN linux-2.6.39-libre/drivers/media/dvb/frontends/cxd2820r_t.c linux-3.0-rc7-libre/drivers/media/dvb/frontends/cxd2820r_t.c
--- linux-2.6.39-libre/drivers/media/dvb/frontends/cxd2820r_t.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/media/dvb/frontends/cxd2820r_t.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,449 @@
+/*
+ * Sony CXD2820R demodulator driver
+ *
+ * Copyright (C) 2010 Antti Palosaari <crope@iki.fi>
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License along
+ *    with this program; if not, write to the Free Software Foundation, Inc.,
+ *    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+
+#include "cxd2820r_priv.h"
+
+int cxd2820r_set_frontend_t(struct dvb_frontend *fe,
+	struct dvb_frontend_parameters *p)
+{
+	struct cxd2820r_priv *priv = fe->demodulator_priv;
+	struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+	int ret, i;
+	u32 if_khz, if_ctl;
+	u64 num;
+	u8 buf[3], bw_param;
+	u8 bw_params1[][5] = {
+		{ 0x17, 0xea, 0xaa, 0xaa, 0xaa }, /* 6 MHz */
+		{ 0x14, 0x80, 0x00, 0x00, 0x00 }, /* 7 MHz */
+		{ 0x11, 0xf0, 0x00, 0x00, 0x00 }, /* 8 MHz */
+	};
+	u8 bw_params2[][2] = {
+		{ 0x1f, 0xdc }, /* 6 MHz */
+		{ 0x12, 0xf8 }, /* 7 MHz */
+		{ 0x01, 0xe0 }, /* 8 MHz */
+	};
+	struct reg_val_mask tab[] = {
+		{ 0x00080, 0x00, 0xff },
+		{ 0x00081, 0x03, 0xff },
+		{ 0x00085, 0x07, 0xff },
+		{ 0x00088, 0x01, 0xff },
+
+		{ 0x00070, priv->cfg.ts_mode, 0xff },
+		{ 0x000cb, priv->cfg.if_agc_polarity << 6, 0x40 },
+		{ 0x000a5, 0x00, 0x01 },
+		{ 0x00082, 0x20, 0x60 },
+		{ 0x000c2, 0xc3, 0xff },
+		{ 0x0016a, 0x50, 0xff },
+		{ 0x00427, 0x41, 0xff },
+	};
+
+	dbg("%s: RF=%d BW=%d", __func__, c->frequency, c->bandwidth_hz);
+
+	/* update GPIOs */
+	ret = cxd2820r_gpio(fe);
+	if (ret)
+		goto error;
+
+	/* program tuner */
+	if (fe->ops.tuner_ops.set_params)
+		fe->ops.tuner_ops.set_params(fe, p);
+
+	if (priv->delivery_system != SYS_DVBT) {
+		for (i = 0; i < ARRAY_SIZE(tab); i++) {
+			ret = cxd2820r_wr_reg_mask(priv, tab[i].reg,
+				tab[i].val, tab[i].mask);
+			if (ret)
+				goto error;
+		}
+	}
+
+	priv->delivery_system = SYS_DVBT;
+	priv->ber_running = 0; /* tune stops BER counter */
+
+	switch (c->bandwidth_hz) {
+	case 6000000:
+		if_khz = priv->cfg.if_dvbt_6;
+		i = 0;
+		bw_param = 2;
+		break;
+	case 7000000:
+		if_khz = priv->cfg.if_dvbt_7;
+		i = 1;
+		bw_param = 1;
+		break;
+	case 8000000:
+		if_khz = priv->cfg.if_dvbt_8;
+		i = 2;
+		bw_param = 0;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	num = if_khz;
+	num *= 0x1000000;
+	if_ctl = cxd2820r_div_u64_round_closest(num, 41000);
+	buf[0] = ((if_ctl >> 16) & 0xff);
+	buf[1] = ((if_ctl >>  8) & 0xff);
+	buf[2] = ((if_ctl >>  0) & 0xff);
+
+	ret = cxd2820r_wr_regs(priv, 0x000b6, buf, 3);
+	if (ret)
+		goto error;
+
+	ret = cxd2820r_wr_regs(priv, 0x0009f, bw_params1[i], 5);
+	if (ret)
+		goto error;
+
+	ret = cxd2820r_wr_reg_mask(priv, 0x000d7, bw_param << 6, 0xc0);
+	if (ret)
+		goto error;
+
+	ret = cxd2820r_wr_regs(priv, 0x000d9, bw_params2[i], 2);
+	if (ret)
+		goto error;
+
+	ret = cxd2820r_wr_reg(priv, 0x000ff, 0x08);
+	if (ret)
+		goto error;
+
+	ret = cxd2820r_wr_reg(priv, 0x000fe, 0x01);
+	if (ret)
+		goto error;
+
+	return ret;
+error:
+	dbg("%s: failed:%d", __func__, ret);
+	return ret;
+}
+
+int cxd2820r_get_frontend_t(struct dvb_frontend *fe,
+	struct dvb_frontend_parameters *p)
+{
+	struct cxd2820r_priv *priv = fe->demodulator_priv;
+	struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+	int ret;
+	u8 buf[2];
+
+	ret = cxd2820r_rd_regs(priv, 0x0002f, buf, sizeof(buf));
+	if (ret)
+		goto error;
+
+	switch ((buf[0] >> 6) & 0x03) {
+	case 0:
+		c->modulation = QPSK;
+		break;
+	case 1:
+		c->modulation = QAM_16;
+		break;
+	case 2:
+		c->modulation = QAM_64;
+		break;
+	}
+
+	switch ((buf[1] >> 1) & 0x03) {
+	case 0:
+		c->transmission_mode = TRANSMISSION_MODE_2K;
+		break;
+	case 1:
+		c->transmission_mode = TRANSMISSION_MODE_8K;
+		break;
+	}
+
+	switch ((buf[1] >> 3) & 0x03) {
+	case 0:
+		c->guard_interval = GUARD_INTERVAL_1_32;
+		break;
+	case 1:
+		c->guard_interval = GUARD_INTERVAL_1_16;
+		break;
+	case 2:
+		c->guard_interval = GUARD_INTERVAL_1_8;
+		break;
+	case 3:
+		c->guard_interval = GUARD_INTERVAL_1_4;
+		break;
+	}
+
+	switch ((buf[0] >> 3) & 0x07) {
+	case 0:
+		c->hierarchy = HIERARCHY_NONE;
+		break;
+	case 1:
+		c->hierarchy = HIERARCHY_1;
+		break;
+	case 2:
+		c->hierarchy = HIERARCHY_2;
+		break;
+	case 3:
+		c->hierarchy = HIERARCHY_4;
+		break;
+	}
+
+	switch ((buf[0] >> 0) & 0x07) {
+	case 0:
+		c->code_rate_HP = FEC_1_2;
+		break;
+	case 1:
+		c->code_rate_HP = FEC_2_3;
+		break;
+	case 2:
+		c->code_rate_HP = FEC_3_4;
+		break;
+	case 3:
+		c->code_rate_HP = FEC_5_6;
+		break;
+	case 4:
+		c->code_rate_HP = FEC_7_8;
+		break;
+	}
+
+	switch ((buf[1] >> 5) & 0x07) {
+	case 0:
+		c->code_rate_LP = FEC_1_2;
+		break;
+	case 1:
+		c->code_rate_LP = FEC_2_3;
+		break;
+	case 2:
+		c->code_rate_LP = FEC_3_4;
+		break;
+	case 3:
+		c->code_rate_LP = FEC_5_6;
+		break;
+	case 4:
+		c->code_rate_LP = FEC_7_8;
+		break;
+	}
+
+	ret = cxd2820r_rd_reg(priv, 0x007c6, &buf[0]);
+	if (ret)
+		goto error;
+
+	switch ((buf[0] >> 0) & 0x01) {
+	case 0:
+		c->inversion = INVERSION_OFF;
+		break;
+	case 1:
+		c->inversion = INVERSION_ON;
+		break;
+	}
+
+	return ret;
+error:
+	dbg("%s: failed:%d", __func__, ret);
+	return ret;
+}
+
+int cxd2820r_read_ber_t(struct dvb_frontend *fe, u32 *ber)
+{
+	struct cxd2820r_priv *priv = fe->demodulator_priv;
+	int ret;
+	u8 buf[3], start_ber = 0;
+	*ber = 0;
+
+	if (priv->ber_running) {
+		ret = cxd2820r_rd_regs(priv, 0x00076, buf, sizeof(buf));
+		if (ret)
+			goto error;
+
+		if ((buf[2] >> 7) & 0x01 || (buf[2] >> 4) & 0x01) {
+			*ber = (buf[2] & 0x0f) << 16 | buf[1] << 8 | buf[0];
+			start_ber = 1;
+		}
+	} else {
+		priv->ber_running = 1;
+		start_ber = 1;
+	}
+
+	if (start_ber) {
+		/* (re)start BER */
+		ret = cxd2820r_wr_reg(priv, 0x00079, 0x01);
+		if (ret)
+			goto error;
+	}
+
+	return ret;
+error:
+	dbg("%s: failed:%d", __func__, ret);
+	return ret;
+}
+
+int cxd2820r_read_signal_strength_t(struct dvb_frontend *fe,
+	u16 *strength)
+{
+	struct cxd2820r_priv *priv = fe->demodulator_priv;
+	int ret;
+	u8 buf[2];
+	u16 tmp;
+
+	ret = cxd2820r_rd_regs(priv, 0x00026, buf, sizeof(buf));
+	if (ret)
+		goto error;
+
+	tmp = (buf[0] & 0x0f) << 8 | buf[1];
+	tmp = ~tmp & 0x0fff;
+
+	/* scale value to 0x0000-0xffff from 0x0000-0x0fff */
+	*strength = tmp * 0xffff / 0x0fff;
+
+	return ret;
+error:
+	dbg("%s: failed:%d", __func__, ret);
+	return ret;
+}
+
+int cxd2820r_read_snr_t(struct dvb_frontend *fe, u16 *snr)
+{
+	struct cxd2820r_priv *priv = fe->demodulator_priv;
+	int ret;
+	u8 buf[2];
+	u16 tmp;
+	/* report SNR in dB * 10 */
+
+	ret = cxd2820r_rd_regs(priv, 0x00028, buf, sizeof(buf));
+	if (ret)
+		goto error;
+
+	tmp = (buf[0] & 0x1f) << 8 | buf[1];
+	#define CXD2820R_LOG10_8_24 15151336 /* log10(8) << 24 */
+	if (tmp)
+		*snr = (intlog10(tmp) - CXD2820R_LOG10_8_24) / ((1 << 24)
+			/ 100);
+	else
+		*snr = 0;
+
+	dbg("%s: dBx10=%d val=%04x", __func__, *snr, tmp);
+
+	return ret;
+error:
+	dbg("%s: failed:%d", __func__, ret);
+	return ret;
+}
+
+int cxd2820r_read_ucblocks_t(struct dvb_frontend *fe, u32 *ucblocks)
+{
+	*ucblocks = 0;
+	/* no way to read ? */
+	return 0;
+}
+
+int cxd2820r_read_status_t(struct dvb_frontend *fe, fe_status_t *status)
+{
+	struct cxd2820r_priv *priv = fe->demodulator_priv;
+	int ret;
+	u8 buf[4];
+	*status = 0;
+
+	ret = cxd2820r_rd_reg(priv, 0x00010, &buf[0]);
+	if (ret)
+		goto error;
+
+	if ((buf[0] & 0x07) == 6) {
+		ret = cxd2820r_rd_reg(priv, 0x00073, &buf[1]);
+		if (ret)
+			goto error;
+
+		if (((buf[1] >> 3) & 0x01) == 1) {
+			*status |= FE_HAS_SIGNAL | FE_HAS_CARRIER |
+				FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK;
+		} else {
+			*status |= FE_HAS_SIGNAL | FE_HAS_CARRIER |
+				FE_HAS_VITERBI | FE_HAS_SYNC;
+		}
+	} else {
+		ret = cxd2820r_rd_reg(priv, 0x00014, &buf[2]);
+		if (ret)
+			goto error;
+
+		if ((buf[2] & 0x0f) >= 4) {
+			ret = cxd2820r_rd_reg(priv, 0x00a14, &buf[3]);
+			if (ret)
+				goto error;
+
+			if (((buf[3] >> 4) & 0x01) == 1)
+				*status |= FE_HAS_SIGNAL;
+		}
+	}
+
+	dbg("%s: lock=%02x %02x %02x %02x", __func__,
+		buf[0], buf[1], buf[2], buf[3]);
+
+	return ret;
+error:
+	dbg("%s: failed:%d", __func__, ret);
+	return ret;
+}
+
+int cxd2820r_init_t(struct dvb_frontend *fe)
+{
+	struct cxd2820r_priv *priv = fe->demodulator_priv;
+	int ret;
+
+	ret = cxd2820r_wr_reg(priv, 0x00085, 0x07);
+	if (ret)
+		goto error;
+
+	return ret;
+error:
+	dbg("%s: failed:%d", __func__, ret);
+	return ret;
+}
+
+int cxd2820r_sleep_t(struct dvb_frontend *fe)
+{
+	struct cxd2820r_priv *priv = fe->demodulator_priv;
+	int ret, i;
+	struct reg_val_mask tab[] = {
+		{ 0x000ff, 0x1f, 0xff },
+		{ 0x00085, 0x00, 0xff },
+		{ 0x00088, 0x01, 0xff },
+		{ 0x00081, 0x00, 0xff },
+		{ 0x00080, 0x00, 0xff },
+	};
+
+	dbg("%s", __func__);
+
+	priv->delivery_system = SYS_UNDEFINED;
+
+	for (i = 0; i < ARRAY_SIZE(tab); i++) {
+		ret = cxd2820r_wr_reg_mask(priv, tab[i].reg, tab[i].val,
+			tab[i].mask);
+		if (ret)
+			goto error;
+	}
+
+	return ret;
+error:
+	dbg("%s: failed:%d", __func__, ret);
+	return ret;
+}
+
+int cxd2820r_get_tune_settings_t(struct dvb_frontend *fe,
+	struct dvb_frontend_tune_settings *s)
+{
+	s->min_delay_ms = 500;
+	s->step_size = fe->ops.info.frequency_stepsize * 2;
+	s->max_drift = (fe->ops.info.frequency_stepsize * 2) + 1;
+
+	return 0;
+}
+
diff -druN linux-2.6.39-libre/drivers/media/dvb/frontends/dib0070.c linux-3.0-rc7-libre/drivers/media/dvb/frontends/dib0070.c
--- linux-2.6.39-libre/drivers/media/dvb/frontends/dib0070.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/dvb/frontends/dib0070.c	2011-07-11 19:51:52.000000000 -0400
@@ -73,27 +73,47 @@
 
     u8  wbd_gain_current;
 	u16 wbd_offset_3_3[2];
+
+	/* for the I2C transfer */
+	struct i2c_msg msg[2];
+	u8 i2c_write_buffer[3];
+	u8 i2c_read_buffer[2];
 };
 
 static uint16_t dib0070_read_reg(struct dib0070_state *state, u8 reg)
 {
-	u8 b[2];
-	struct i2c_msg msg[2] = {
-		{ .addr = state->cfg->i2c_address, .flags = 0,        .buf = &reg, .len = 1 },
-		{ .addr = state->cfg->i2c_address, .flags = I2C_M_RD, .buf = b,  .len = 2 },
-	};
-	if (i2c_transfer(state->i2c, msg, 2) != 2) {
+	state->i2c_write_buffer[0] = reg;
+
+	memset(state->msg, 0, 2 * sizeof(struct i2c_msg));
+	state->msg[0].addr = state->cfg->i2c_address;
+	state->msg[0].flags = 0;
+	state->msg[0].buf = state->i2c_write_buffer;
+	state->msg[0].len = 1;
+	state->msg[1].addr = state->cfg->i2c_address;
+	state->msg[1].flags = I2C_M_RD;
+	state->msg[1].buf = state->i2c_read_buffer;
+	state->msg[1].len = 2;
+
+	if (i2c_transfer(state->i2c, state->msg, 2) != 2) {
 		printk(KERN_WARNING "DiB0070 I2C read failed\n");
 		return 0;
 	}
-	return (b[0] << 8) | b[1];
+	return (state->i2c_read_buffer[0] << 8) | state->i2c_read_buffer[1];
 }
 
 static int dib0070_write_reg(struct dib0070_state *state, u8 reg, u16 val)
 {
-	u8 b[3] = { reg, val >> 8, val & 0xff };
-	struct i2c_msg msg = { .addr = state->cfg->i2c_address, .flags = 0, .buf = b, .len = 3 };
-	if (i2c_transfer(state->i2c, &msg, 1) != 1) {
+	state->i2c_write_buffer[0] = reg;
+	state->i2c_write_buffer[1] = val >> 8;
+	state->i2c_write_buffer[2] = val & 0xff;
+
+	memset(state->msg, 0, sizeof(struct i2c_msg));
+	state->msg[0].addr = state->cfg->i2c_address;
+	state->msg[0].flags = 0;
+	state->msg[0].buf = state->i2c_write_buffer;
+	state->msg[0].len = 3;
+
+	if (i2c_transfer(state->i2c, state->msg, 1) != 1) {
 		printk(KERN_WARNING "DiB0070 I2C write failed\n");
 		return -EREMOTEIO;
 	}
diff -druN linux-2.6.39-libre/drivers/media/dvb/frontends/dib0090.c linux-3.0-rc7-libre/drivers/media/dvb/frontends/dib0090.c
--- linux-2.6.39-libre/drivers/media/dvb/frontends/dib0090.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/dvb/frontends/dib0090.c	2011-07-11 19:51:52.000000000 -0400
@@ -191,6 +191,11 @@
 	u8 wbd_calibration_gain;
 	const struct dib0090_wbd_slope *current_wbd_table;
 	u16 wbdmux;
+
+	/* for the I2C transfer */
+	struct i2c_msg msg[2];
+	u8 i2c_write_buffer[3];
+	u8 i2c_read_buffer[2];
 };
 
 struct dib0090_fw_state {
@@ -198,27 +203,48 @@
 	struct dvb_frontend *fe;
 	struct dib0090_identity identity;
 	const struct dib0090_config *config;
+
+	/* for the I2C transfer */
+	struct i2c_msg msg;
+	u8 i2c_write_buffer[2];
+	u8 i2c_read_buffer[2];
 };
 
 static u16 dib0090_read_reg(struct dib0090_state *state, u8 reg)
 {
-	u8 b[2];
-	struct i2c_msg msg[2] = {
-		{.addr = state->config->i2c_address, .flags = 0, .buf = &reg, .len = 1},
-		{.addr = state->config->i2c_address, .flags = I2C_M_RD, .buf = b, .len = 2},
-	};
-	if (i2c_transfer(state->i2c, msg, 2) != 2) {
+	state->i2c_write_buffer[0] = reg;
+
+	memset(state->msg, 0, 2 * sizeof(struct i2c_msg));
+	state->msg[0].addr = state->config->i2c_address;
+	state->msg[0].flags = 0;
+	state->msg[0].buf = state->i2c_write_buffer;
+	state->msg[0].len = 1;
+	state->msg[1].addr = state->config->i2c_address;
+	state->msg[1].flags = I2C_M_RD;
+	state->msg[1].buf = state->i2c_read_buffer;
+	state->msg[1].len = 2;
+
+	if (i2c_transfer(state->i2c, state->msg, 2) != 2) {
 		printk(KERN_WARNING "DiB0090 I2C read failed\n");
 		return 0;
 	}
-	return (b[0] << 8) | b[1];
+
+	return (state->i2c_read_buffer[0] << 8) | state->i2c_read_buffer[1];
 }
 
 static int dib0090_write_reg(struct dib0090_state *state, u32 reg, u16 val)
 {
-	u8 b[3] = { reg & 0xff, val >> 8, val & 0xff };
-	struct i2c_msg msg = {.addr = state->config->i2c_address, .flags = 0, .buf = b, .len = 3 };
-	if (i2c_transfer(state->i2c, &msg, 1) != 1) {
+	state->i2c_write_buffer[0] = reg & 0xff;
+	state->i2c_write_buffer[1] = val >> 8;
+	state->i2c_write_buffer[2] = val & 0xff;
+
+	memset(state->msg, 0, sizeof(struct i2c_msg));
+	state->msg[0].addr = state->config->i2c_address;
+	state->msg[0].flags = 0;
+	state->msg[0].buf = state->i2c_write_buffer;
+	state->msg[0].len = 3;
+
+	if (i2c_transfer(state->i2c, state->msg, 1) != 1) {
 		printk(KERN_WARNING "DiB0090 I2C write failed\n");
 		return -EREMOTEIO;
 	}
@@ -227,20 +253,31 @@
 
 static u16 dib0090_fw_read_reg(struct dib0090_fw_state *state, u8 reg)
 {
-	u8 b[2];
-	struct i2c_msg msg = {.addr = reg, .flags = I2C_M_RD, .buf = b, .len = 2 };
-	if (i2c_transfer(state->i2c, &msg, 1) != 1) {
+	state->i2c_write_buffer[0] = reg;
+
+	memset(&state->msg, 0, sizeof(struct i2c_msg));
+	state->msg.addr = reg;
+	state->msg.flags = I2C_M_RD;
+	state->msg.buf = state->i2c_read_buffer;
+	state->msg.len = 2;
+	if (i2c_transfer(state->i2c, &state->msg, 1) != 1) {
 		printk(KERN_WARNING "DiB0090 I2C read failed\n");
 		return 0;
 	}
-	return (b[0] << 8) | b[1];
+	return (state->i2c_read_buffer[0] << 8) | state->i2c_read_buffer[1];
 }
 
 static int dib0090_fw_write_reg(struct dib0090_fw_state *state, u8 reg, u16 val)
 {
-	u8 b[2] = { val >> 8, val & 0xff };
-	struct i2c_msg msg = {.addr = reg, .flags = 0, .buf = b, .len = 2 };
-	if (i2c_transfer(state->i2c, &msg, 1) != 1) {
+	state->i2c_write_buffer[0] = val >> 8;
+	state->i2c_write_buffer[1] = val & 0xff;
+
+	memset(&state->msg, 0, sizeof(struct i2c_msg));
+	state->msg.addr = reg;
+	state->msg.flags = 0;
+	state->msg.buf = state->i2c_write_buffer;
+	state->msg.len = 2;
+	if (i2c_transfer(state->i2c, &state->msg, 1) != 1) {
 		printk(KERN_WARNING "DiB0090 I2C write failed\n");
 		return -EREMOTEIO;
 	}
diff -druN linux-2.6.39-libre/drivers/media/dvb/frontends/dib7000m.c linux-3.0-rc7-libre/drivers/media/dvb/frontends/dib7000m.c
--- linux-2.6.39-libre/drivers/media/dvb/frontends/dib7000m.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/dvb/frontends/dib7000m.c	2011-07-11 19:51:52.000000000 -0400
@@ -50,6 +50,11 @@
 	u16 revision;
 
 	u8 agc_state;
+
+	/* for the I2C transfer */
+	struct i2c_msg msg[2];
+	u8 i2c_write_buffer[4];
+	u8 i2c_read_buffer[2];
 };
 
 enum dib7000m_power_mode {
@@ -64,29 +69,39 @@
 
 static u16 dib7000m_read_word(struct dib7000m_state *state, u16 reg)
 {
-	u8 wb[2] = { (reg >> 8) | 0x80, reg & 0xff };
-	u8 rb[2];
-	struct i2c_msg msg[2] = {
-		{ .addr = state->i2c_addr >> 1, .flags = 0,        .buf = wb, .len = 2 },
-		{ .addr = state->i2c_addr >> 1, .flags = I2C_M_RD, .buf = rb, .len = 2 },
-	};
+	state->i2c_write_buffer[0] = (reg >> 8) | 0x80;
+	state->i2c_write_buffer[1] = reg & 0xff;
 
-	if (i2c_transfer(state->i2c_adap, msg, 2) != 2)
+	memset(state->msg, 0, 2 * sizeof(struct i2c_msg));
+	state->msg[0].addr = state->i2c_addr >> 1;
+	state->msg[0].flags = 0;
+	state->msg[0].buf = state->i2c_write_buffer;
+	state->msg[0].len = 2;
+	state->msg[1].addr = state->i2c_addr >> 1;
+	state->msg[1].flags = I2C_M_RD;
+	state->msg[1].buf = state->i2c_read_buffer;
+	state->msg[1].len = 2;
+
+	if (i2c_transfer(state->i2c_adap, state->msg, 2) != 2)
 		dprintk("i2c read error on %d",reg);
 
-	return (rb[0] << 8) | rb[1];
+	return (state->i2c_read_buffer[0] << 8) | state->i2c_read_buffer[1];
 }
 
 static int dib7000m_write_word(struct dib7000m_state *state, u16 reg, u16 val)
 {
-	u8 b[4] = {
-		(reg >> 8) & 0xff, reg & 0xff,
-		(val >> 8) & 0xff, val & 0xff,
-	};
-	struct i2c_msg msg = {
-		.addr = state->i2c_addr >> 1, .flags = 0, .buf = b, .len = 4
-	};
-	return i2c_transfer(state->i2c_adap, &msg, 1) != 1 ? -EREMOTEIO : 0;
+	state->i2c_write_buffer[0] = (reg >> 8) & 0xff;
+	state->i2c_write_buffer[1] = reg & 0xff;
+	state->i2c_write_buffer[2] = (val >> 8) & 0xff;
+	state->i2c_write_buffer[3] = val & 0xff;
+
+	memset(&state->msg[0], 0, sizeof(struct i2c_msg));
+	state->msg[0].addr = state->i2c_addr >> 1;
+	state->msg[0].flags = 0;
+	state->msg[0].buf = state->i2c_write_buffer;
+	state->msg[0].len = 4;
+
+	return i2c_transfer(state->i2c_adap, state->msg, 1) != 1 ? -EREMOTEIO : 0;
 }
 static void dib7000m_write_tab(struct dib7000m_state *state, u16 *buf)
 {
diff -druN linux-2.6.39-libre/drivers/media/dvb/frontends/dib7000p.c linux-3.0-rc7-libre/drivers/media/dvb/frontends/dib7000p.c
--- linux-2.6.39-libre/drivers/media/dvb/frontends/dib7000p.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/dvb/frontends/dib7000p.c	2011-07-11 19:51:52.000000000 -0400
@@ -63,6 +63,11 @@
 
 	u16 tuner_enable;
 	struct i2c_adapter dib7090_tuner_adap;
+
+	/* for the I2C transfer */
+	struct i2c_msg msg[2];
+	u8 i2c_write_buffer[4];
+	u8 i2c_read_buffer[2];
 };
 
 enum dib7000p_power_mode {
@@ -76,29 +81,39 @@
 
 static u16 dib7000p_read_word(struct dib7000p_state *state, u16 reg)
 {
-	u8 wb[2] = { reg >> 8, reg & 0xff };
-	u8 rb[2];
-	struct i2c_msg msg[2] = {
-		{.addr = state->i2c_addr >> 1, .flags = 0, .buf = wb, .len = 2},
-		{.addr = state->i2c_addr >> 1, .flags = I2C_M_RD, .buf = rb, .len = 2},
-	};
+	state->i2c_write_buffer[0] = reg >> 8;
+	state->i2c_write_buffer[1] = reg & 0xff;
 
-	if (i2c_transfer(state->i2c_adap, msg, 2) != 2)
+	memset(state->msg, 0, 2 * sizeof(struct i2c_msg));
+	state->msg[0].addr = state->i2c_addr >> 1;
+	state->msg[0].flags = 0;
+	state->msg[0].buf = state->i2c_write_buffer;
+	state->msg[0].len = 2;
+	state->msg[1].addr = state->i2c_addr >> 1;
+	state->msg[1].flags = I2C_M_RD;
+	state->msg[1].buf = state->i2c_read_buffer;
+	state->msg[1].len = 2;
+
+	if (i2c_transfer(state->i2c_adap, state->msg, 2) != 2)
 		dprintk("i2c read error on %d", reg);
 
-	return (rb[0] << 8) | rb[1];
+	return (state->i2c_read_buffer[0] << 8) | state->i2c_read_buffer[1];
 }
 
 static int dib7000p_write_word(struct dib7000p_state *state, u16 reg, u16 val)
 {
-	u8 b[4] = {
-		(reg >> 8) & 0xff, reg & 0xff,
-		(val >> 8) & 0xff, val & 0xff,
-	};
-	struct i2c_msg msg = {
-		.addr = state->i2c_addr >> 1, .flags = 0, .buf = b, .len = 4
-	};
-	return i2c_transfer(state->i2c_adap, &msg, 1) != 1 ? -EREMOTEIO : 0;
+	state->i2c_write_buffer[0] = (reg >> 8) & 0xff;
+	state->i2c_write_buffer[1] = reg & 0xff;
+	state->i2c_write_buffer[2] = (val >> 8) & 0xff;
+	state->i2c_write_buffer[3] = val & 0xff;
+
+	memset(&state->msg[0], 0, sizeof(struct i2c_msg));
+	state->msg[0].addr = state->i2c_addr >> 1;
+	state->msg[0].flags = 0;
+	state->msg[0].buf = state->i2c_write_buffer;
+	state->msg[0].len = 4;
+
+	return i2c_transfer(state->i2c_adap, state->msg, 1) != 1 ? -EREMOTEIO : 0;
 }
 
 static void dib7000p_write_tab(struct dib7000p_state *state, u16 * buf)
@@ -1550,11 +1565,24 @@
 
 int dib7000pc_detection(struct i2c_adapter *i2c_adap)
 {
-	u8 tx[2], rx[2];
+	u8 *tx, *rx;
 	struct i2c_msg msg[2] = {
-		{.addr = 18 >> 1, .flags = 0, .buf = tx, .len = 2},
-		{.addr = 18 >> 1, .flags = I2C_M_RD, .buf = rx, .len = 2},
+		{.addr = 18 >> 1, .flags = 0, .len = 2},
+		{.addr = 18 >> 1, .flags = I2C_M_RD, .len = 2},
 	};
+	int ret = 0;
+
+	tx = kzalloc(2*sizeof(u8), GFP_KERNEL);
+	if (!tx)
+		return -ENOMEM;
+	rx = kzalloc(2*sizeof(u8), GFP_KERNEL);
+	if (!rx) {
+		goto rx_memory_error;
+		ret = -ENOMEM;
+	}
+
+	msg[0].buf = tx;
+	msg[1].buf = rx;
 
 	tx[0] = 0x03;
 	tx[1] = 0x00;
@@ -1574,7 +1602,11 @@
 		}
 
 	dprintk("-D-  DiB7000PC not detected");
-	return 0;
+
+	kfree(rx);
+rx_memory_error:
+	kfree(tx);
+	return ret;
 }
 EXPORT_SYMBOL(dib7000pc_detection);
 
diff -druN linux-2.6.39-libre/drivers/media/dvb/frontends/dib8000.c linux-3.0-rc7-libre/drivers/media/dvb/frontends/dib8000.c
--- linux-2.6.39-libre/drivers/media/dvb/frontends/dib8000.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/dvb/frontends/dib8000.c	2011-07-11 19:51:52.000000000 -0400
@@ -35,6 +35,8 @@
 struct i2c_device {
 	struct i2c_adapter *adap;
 	u8 addr;
+	u8 *i2c_write_buffer;
+	u8 *i2c_read_buffer;
 };
 
 struct dib8000_state {
@@ -70,6 +72,11 @@
 	u32 status;
 
 	struct dvb_frontend *fe[MAX_NUMBER_OF_FRONTENDS];
+
+	/* for the I2C transfer */
+	struct i2c_msg msg[2];
+	u8 i2c_write_buffer[4];
+	u8 i2c_read_buffer[2];
 };
 
 enum dib8000_power_mode {
@@ -79,22 +86,41 @@
 
 static u16 dib8000_i2c_read16(struct i2c_device *i2c, u16 reg)
 {
-	u8 wb[2] = { reg >> 8, reg & 0xff };
-	u8 rb[2];
 	struct i2c_msg msg[2] = {
-		{.addr = i2c->addr >> 1,.flags = 0,.buf = wb,.len = 2},
-		{.addr = i2c->addr >> 1,.flags = I2C_M_RD,.buf = rb,.len = 2},
+		{.addr = i2c->addr >> 1, .flags = 0,
+			.buf = i2c->i2c_write_buffer, .len = 2},
+		{.addr = i2c->addr >> 1, .flags = I2C_M_RD,
+			.buf = i2c->i2c_read_buffer, .len = 2},
 	};
 
+	msg[0].buf[0] = reg >> 8;
+	msg[0].buf[1] = reg & 0xff;
+
 	if (i2c_transfer(i2c->adap, msg, 2) != 2)
 		dprintk("i2c read error on %d", reg);
 
-	return (rb[0] << 8) | rb[1];
+	return (msg[1].buf[0] << 8) | msg[1].buf[1];
 }
 
 static u16 dib8000_read_word(struct dib8000_state *state, u16 reg)
 {
-	return dib8000_i2c_read16(&state->i2c, reg);
+	state->i2c_write_buffer[0] = reg >> 8;
+	state->i2c_write_buffer[1] = reg & 0xff;
+
+	memset(state->msg, 0, 2 * sizeof(struct i2c_msg));
+	state->msg[0].addr = state->i2c.addr >> 1;
+	state->msg[0].flags = 0;
+	state->msg[0].buf = state->i2c_write_buffer;
+	state->msg[0].len = 2;
+	state->msg[1].addr = state->i2c.addr >> 1;
+	state->msg[1].flags = I2C_M_RD;
+	state->msg[1].buf = state->i2c_read_buffer;
+	state->msg[1].len = 2;
+
+	if (i2c_transfer(state->i2c.adap, state->msg, 2) != 2)
+		dprintk("i2c read error on %d", reg);
+
+	return (state->i2c_read_buffer[0] << 8) | state->i2c_read_buffer[1];
 }
 
 static u32 dib8000_read32(struct dib8000_state *state, u16 reg)
@@ -109,19 +135,34 @@
 
 static int dib8000_i2c_write16(struct i2c_device *i2c, u16 reg, u16 val)
 {
-	u8 b[4] = {
-		(reg >> 8) & 0xff, reg & 0xff,
-		(val >> 8) & 0xff, val & 0xff,
-	};
-	struct i2c_msg msg = {
-		.addr = i2c->addr >> 1,.flags = 0,.buf = b,.len = 4
-	};
-	return i2c_transfer(i2c->adap, &msg, 1) != 1 ? -EREMOTEIO : 0;
+	struct i2c_msg msg = {.addr = i2c->addr >> 1, .flags = 0,
+		.buf = i2c->i2c_write_buffer, .len = 4};
+	int ret = 0;
+
+	msg.buf[0] = (reg >> 8) & 0xff;
+	msg.buf[1] = reg & 0xff;
+	msg.buf[2] = (val >> 8) & 0xff;
+	msg.buf[3] = val & 0xff;
+
+	ret = i2c_transfer(i2c->adap, &msg, 1) != 1 ? -EREMOTEIO : 0;
+
+	return ret;
 }
 
 static int dib8000_write_word(struct dib8000_state *state, u16 reg, u16 val)
 {
-	return dib8000_i2c_write16(&state->i2c, reg, val);
+	state->i2c_write_buffer[0] = (reg >> 8) & 0xff;
+	state->i2c_write_buffer[1] = reg & 0xff;
+	state->i2c_write_buffer[2] = (val >> 8) & 0xff;
+	state->i2c_write_buffer[3] = val & 0xff;
+
+	memset(&state->msg[0], 0, sizeof(struct i2c_msg));
+	state->msg[0].addr = state->i2c.addr >> 1;
+	state->msg[0].flags = 0;
+	state->msg[0].buf = state->i2c_write_buffer;
+	state->msg[0].len = 4;
+
+	return i2c_transfer(state->i2c.adap, state->msg, 1) != 1 ? -EREMOTEIO : 0;
 }
 
 static const s16 coeff_2k_sb_1seg_dqpsk[8] = {
@@ -980,30 +1021,31 @@
 	dprintk("Updated timing frequency: %d (default: %d)", state->timf, state->timf_default);
 }
 
+static const u16 adc_target_16dB[11] = {
+	(1 << 13) - 825 - 117,
+	(1 << 13) - 837 - 117,
+	(1 << 13) - 811 - 117,
+	(1 << 13) - 766 - 117,
+	(1 << 13) - 737 - 117,
+	(1 << 13) - 693 - 117,
+	(1 << 13) - 648 - 117,
+	(1 << 13) - 619 - 117,
+	(1 << 13) - 575 - 117,
+	(1 << 13) - 531 - 117,
+	(1 << 13) - 501 - 117
+};
+static const u8 permu_seg[] = { 6, 5, 7, 4, 8, 3, 9, 2, 10, 1, 11, 0, 12 };
+
 static void dib8000_set_channel(struct dib8000_state *state, u8 seq, u8 autosearching)
 {
 	u16 mode, max_constellation, seg_diff_mask = 0, nbseg_diff = 0;
 	u8 guard, crate, constellation, timeI;
-	u8 permu_seg[] = { 6, 5, 7, 4, 8, 3, 9, 2, 10, 1, 11, 0, 12 };
 	u16 i, coeff[4], P_cfr_left_edge = 0, P_cfr_right_edge = 0, seg_mask13 = 0x1fff;	// All 13 segments enabled
 	const s16 *ncoeff = NULL, *ana_fe;
 	u16 tmcc_pow = 0;
 	u16 coff_pow = 0x2800;
 	u16 init_prbs = 0xfff;
 	u16 ana_gain = 0;
-	u16 adc_target_16dB[11] = {
-		(1 << 13) - 825 - 117,
-		(1 << 13) - 837 - 117,
-		(1 << 13) - 811 - 117,
-		(1 << 13) - 766 - 117,
-		(1 << 13) - 737 - 117,
-		(1 << 13) - 693 - 117,
-		(1 << 13) - 648 - 117,
-		(1 << 13) - 619 - 117,
-		(1 << 13) - 575 - 117,
-		(1 << 13) - 531 - 117,
-		(1 << 13) - 501 - 117
-	};
 
 	if (state->ber_monitored_layer != LAYER_ALL)
 		dib8000_write_word(state, 285, (dib8000_read_word(state, 285) & 0x60) | state->ber_monitored_layer);
@@ -2379,10 +2421,22 @@
 
 int dib8000_i2c_enumeration(struct i2c_adapter *host, int no_of_demods, u8 default_addr, u8 first_addr)
 {
-	int k = 0;
+	int k = 0, ret = 0;
 	u8 new_addr = 0;
 	struct i2c_device client = {.adap = host };
 
+	client.i2c_write_buffer = kzalloc(4 * sizeof(u8), GFP_KERNEL);
+	if (!client.i2c_write_buffer) {
+		dprintk("%s: not enough memory", __func__);
+		return -ENOMEM;
+	}
+	client.i2c_read_buffer = kzalloc(4 * sizeof(u8), GFP_KERNEL);
+	if (!client.i2c_read_buffer) {
+		dprintk("%s: not enough memory", __func__);
+		ret = -ENOMEM;
+		goto error_memory;
+	}
+
 	for (k = no_of_demods - 1; k >= 0; k--) {
 		/* designated i2c address */
 		new_addr = first_addr + (k << 1);
@@ -2394,7 +2448,8 @@
 			client.addr = default_addr;
 			if (dib8000_identify(&client) == 0) {
 				dprintk("#%d: not identified", k);
-				return -EINVAL;
+				ret  = -EINVAL;
+				goto error;
 			}
 		}
 
@@ -2420,7 +2475,12 @@
 		dib8000_i2c_write16(&client, 1286, 0);
 	}
 
-	return 0;
+error:
+	kfree(client.i2c_read_buffer);
+error_memory:
+	kfree(client.i2c_write_buffer);
+
+	return ret;
 }
 
 EXPORT_SYMBOL(dib8000_i2c_enumeration);
@@ -2519,6 +2579,8 @@
 	memcpy(&state->cfg, cfg, sizeof(struct dib8000_config));
 	state->i2c.adap = i2c_adap;
 	state->i2c.addr = i2c_addr;
+	state->i2c.i2c_write_buffer = state->i2c_write_buffer;
+	state->i2c.i2c_read_buffer = state->i2c_read_buffer;
 	state->gpio_val = cfg->gpio_val;
 	state->gpio_dir = cfg->gpio_dir;
 
diff -druN linux-2.6.39-libre/drivers/media/dvb/frontends/dib9000.c linux-3.0-rc7-libre/drivers/media/dvb/frontends/dib9000.c
--- linux-2.6.39-libre/drivers/media/dvb/frontends/dib9000.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/dvb/frontends/dib9000.c	2011-07-11 19:51:52.000000000 -0400
@@ -27,6 +27,8 @@
 struct i2c_device {
 	struct i2c_adapter *i2c_adap;
 	u8 i2c_addr;
+	u8 *i2c_read_buffer;
+	u8 *i2c_write_buffer;
 };
 
 /* lock */
@@ -92,11 +94,16 @@
 
 	struct dvb_frontend *fe[MAX_NUMBER_OF_FRONTENDS];
 	u16 component_bus_speed;
+
+	/* for the I2C transfer */
+	struct i2c_msg msg[2];
+	u8 i2c_write_buffer[255];
+	u8 i2c_read_buffer[255];
 };
 
-u32 fe_info[44] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+static const u32 fe_info[44] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0
+	0, 0, 0, 0, 0, 0, 0, 0
 };
 
 enum dib9000_power_mode {
@@ -217,25 +224,33 @@
 	u32 chunk_size = 126;
 	u32 l;
 	int ret;
-	u8 wb[2] = { reg >> 8, reg & 0xff };
-	struct i2c_msg msg[2] = {
-		{.addr = state->i2c.i2c_addr >> 1, .flags = 0, .buf = wb, .len = 2},
-		{.addr = state->i2c.i2c_addr >> 1, .flags = I2C_M_RD, .buf = b, .len = len},
-	};
 
 	if (state->platform.risc.fw_is_running && (reg < 1024))
 		return dib9000_risc_apb_access_read(state, reg, attribute, NULL, 0, b, len);
 
+	memset(state->msg, 0, 2 * sizeof(struct i2c_msg));
+	state->msg[0].addr = state->i2c.i2c_addr >> 1;
+	state->msg[0].flags = 0;
+	state->msg[0].buf = state->i2c_write_buffer;
+	state->msg[0].len = 2;
+	state->msg[1].addr = state->i2c.i2c_addr >> 1;
+	state->msg[1].flags = I2C_M_RD;
+	state->msg[1].buf = b;
+	state->msg[1].len = len;
+
+	state->i2c_write_buffer[0] = reg >> 8;
+	state->i2c_write_buffer[1] = reg & 0xff;
+
 	if (attribute & DATA_BUS_ACCESS_MODE_8BIT)
-		wb[0] |= (1 << 5);
+		state->i2c_write_buffer[0] |= (1 << 5);
 	if (attribute & DATA_BUS_ACCESS_MODE_NO_ADDRESS_INCREMENT)
-		wb[0] |= (1 << 4);
+		state->i2c_write_buffer[0] |= (1 << 4);
 
 	do {
 		l = len < chunk_size ? len : chunk_size;
-		msg[1].len = l;
-		msg[1].buf = b;
-		ret = i2c_transfer(state->i2c.i2c_adap, msg, 2) != 2 ? -EREMOTEIO : 0;
+		state->msg[1].len = l;
+		state->msg[1].buf = b;
+		ret = i2c_transfer(state->i2c.i2c_adap, state->msg, 2) != 2 ? -EREMOTEIO : 0;
 		if (ret != 0) {
 			dprintk("i2c read error on %d", reg);
 			return -EREMOTEIO;
@@ -253,50 +268,47 @@
 
 static u16 dib9000_i2c_read16(struct i2c_device *i2c, u16 reg)
 {
-	u8 b[2];
-	u8 wb[2] = { reg >> 8, reg & 0xff };
 	struct i2c_msg msg[2] = {
-		{.addr = i2c->i2c_addr >> 1, .flags = 0, .buf = wb, .len = 2},
-		{.addr = i2c->i2c_addr >> 1, .flags = I2C_M_RD, .buf = b, .len = 2},
+		{.addr = i2c->i2c_addr >> 1, .flags = 0,
+			.buf = i2c->i2c_write_buffer, .len = 2},
+		{.addr = i2c->i2c_addr >> 1, .flags = I2C_M_RD,
+			.buf = i2c->i2c_read_buffer, .len = 2},
 	};
 
+	i2c->i2c_write_buffer[0] = reg >> 8;
+	i2c->i2c_write_buffer[1] = reg & 0xff;
+
 	if (i2c_transfer(i2c->i2c_adap, msg, 2) != 2) {
 		dprintk("read register %x error", reg);
 		return 0;
 	}
 
-	return (b[0] << 8) | b[1];
+	return (i2c->i2c_read_buffer[0] << 8) | i2c->i2c_read_buffer[1];
 }
 
 static inline u16 dib9000_read_word(struct dib9000_state *state, u16 reg)
 {
-	u8 b[2];
-	if (dib9000_read16_attr(state, reg, b, 2, 0) != 0)
+	if (dib9000_read16_attr(state, reg, state->i2c_read_buffer, 2, 0) != 0)
 		return 0;
-	return (b[0] << 8 | b[1]);
+	return (state->i2c_read_buffer[0] << 8) | state->i2c_read_buffer[1];
 }
 
 static inline u16 dib9000_read_word_attr(struct dib9000_state *state, u16 reg, u16 attribute)
 {
-	u8 b[2];
-	if (dib9000_read16_attr(state, reg, b, 2, attribute) != 0)
+	if (dib9000_read16_attr(state, reg, state->i2c_read_buffer, 2,
+				attribute) != 0)
 		return 0;
-	return (b[0] << 8 | b[1]);
+	return (state->i2c_read_buffer[0] << 8) | state->i2c_read_buffer[1];
 }
 
 #define dib9000_read16_noinc_attr(state, reg, b, len, attribute) dib9000_read16_attr(state, reg, b, len, (attribute) | DATA_BUS_ACCESS_MODE_NO_ADDRESS_INCREMENT)
 
 static u16 dib9000_write16_attr(struct dib9000_state *state, u16 reg, const u8 * buf, u32 len, u16 attribute)
 {
-	u8 b[255];
 	u32 chunk_size = 126;
 	u32 l;
 	int ret;
 
-	struct i2c_msg msg = {
-		.addr = state->i2c.i2c_addr >> 1, .flags = 0, .buf = b, .len = len + 2
-	};
-
 	if (state->platform.risc.fw_is_running && (reg < 1024)) {
 		if (dib9000_risc_apb_access_write
 		    (state, reg, DATA_BUS_ACCESS_MODE_16BIT | DATA_BUS_ACCESS_MODE_NO_ADDRESS_INCREMENT | attribute, buf, len) != 0)
@@ -304,20 +316,26 @@
 		return 0;
 	}
 
-	b[0] = (reg >> 8) & 0xff;
-	b[1] = (reg) & 0xff;
+	memset(&state->msg[0], 0, sizeof(struct i2c_msg));
+	state->msg[0].addr = state->i2c.i2c_addr >> 1;
+	state->msg[0].flags = 0;
+	state->msg[0].buf = state->i2c_write_buffer;
+	state->msg[0].len = len + 2;
+
+	state->i2c_write_buffer[0] = (reg >> 8) & 0xff;
+	state->i2c_write_buffer[1] = (reg) & 0xff;
 
 	if (attribute & DATA_BUS_ACCESS_MODE_8BIT)
-		b[0] |= (1 << 5);
+		state->i2c_write_buffer[0] |= (1 << 5);
 	if (attribute & DATA_BUS_ACCESS_MODE_NO_ADDRESS_INCREMENT)
-		b[0] |= (1 << 4);
+		state->i2c_write_buffer[0] |= (1 << 4);
 
 	do {
 		l = len < chunk_size ? len : chunk_size;
-		msg.len = l + 2;
-		memcpy(&b[2], buf, l);
+		state->msg[0].len = l + 2;
+		memcpy(&state->i2c_write_buffer[2], buf, l);
 
-		ret = i2c_transfer(state->i2c.i2c_adap, &msg, 1) != 1 ? -EREMOTEIO : 0;
+		ret = i2c_transfer(state->i2c.i2c_adap, state->msg, 1) != 1 ? -EREMOTEIO : 0;
 
 		buf += l;
 		len -= l;
@@ -331,11 +349,16 @@
 
 static int dib9000_i2c_write16(struct i2c_device *i2c, u16 reg, u16 val)
 {
-	u8 b[4] = { (reg >> 8) & 0xff, reg & 0xff, (val >> 8) & 0xff, val & 0xff };
 	struct i2c_msg msg = {
-		.addr = i2c->i2c_addr >> 1, .flags = 0, .buf = b, .len = 4
+		.addr = i2c->i2c_addr >> 1, .flags = 0,
+		.buf = i2c->i2c_write_buffer, .len = 4
 	};
 
+	i2c->i2c_write_buffer[0] = (reg >> 8) & 0xff;
+	i2c->i2c_write_buffer[1] = reg & 0xff;
+	i2c->i2c_write_buffer[2] = (val >> 8) & 0xff;
+	i2c->i2c_write_buffer[3] = val & 0xff;
+
 	return i2c_transfer(i2c->i2c_adap, &msg, 1) != 1 ? -EREMOTEIO : 0;
 }
 
@@ -1015,8 +1038,8 @@
 		return 0;
 	dib9000_risc_mem_write(state, FE_MM_RW_SYNC, &i);
 	do {
-		dib9000_risc_mem_read(state, FE_MM_RW_SYNC, &i, 1);
-	} while (i && index_loop--);
+		dib9000_risc_mem_read(state, FE_MM_RW_SYNC, state->i2c_read_buffer, 1);
+	} while (state->i2c_read_buffer[0] && index_loop--);
 
 	if (index_loop > 0)
 		return 0;
@@ -1139,7 +1162,7 @@
 
 		s8 intlv_native;
 	};
-	struct dibDVBTChannel ch;
+	struct dibDVBTChannel *ch;
 	int ret = 0;
 
 	DibAcquireLock(&state->platform.risc.mem_mbx_lock);
@@ -1148,9 +1171,12 @@
 		ret = -EIO;
 	}
 
-	dib9000_risc_mem_read(state, FE_MM_R_CHANNEL_UNION, (u8 *) &ch, sizeof(struct dibDVBTChannel));
+	dib9000_risc_mem_read(state, FE_MM_R_CHANNEL_UNION,
+			state->i2c_read_buffer, sizeof(struct dibDVBTChannel));
+	ch = (struct dibDVBTChannel *)state->i2c_read_buffer;
 
-	switch (ch.spectrum_inversion & 0x7) {
+
+	switch (ch->spectrum_inversion & 0x7) {
 	case 1:
 		state->fe[0]->dtv_property_cache.inversion = INVERSION_ON;
 		break;
@@ -1162,7 +1188,7 @@
 		state->fe[0]->dtv_property_cache.inversion = INVERSION_AUTO;
 		break;
 	}
-	switch (ch.nfft) {
+	switch (ch->nfft) {
 	case 0:
 		state->fe[0]->dtv_property_cache.transmission_mode = TRANSMISSION_MODE_2K;
 		break;
@@ -1177,7 +1203,7 @@
 		state->fe[0]->dtv_property_cache.transmission_mode = TRANSMISSION_MODE_AUTO;
 		break;
 	}
-	switch (ch.guard) {
+	switch (ch->guard) {
 	case 0:
 		state->fe[0]->dtv_property_cache.guard_interval = GUARD_INTERVAL_1_32;
 		break;
@@ -1195,7 +1221,7 @@
 		state->fe[0]->dtv_property_cache.guard_interval = GUARD_INTERVAL_AUTO;
 		break;
 	}
-	switch (ch.constellation) {
+	switch (ch->constellation) {
 	case 2:
 		state->fe[0]->dtv_property_cache.modulation = QAM_64;
 		break;
@@ -1210,7 +1236,7 @@
 		state->fe[0]->dtv_property_cache.modulation = QAM_AUTO;
 		break;
 	}
-	switch (ch.hrch) {
+	switch (ch->hrch) {
 	case 0:
 		state->fe[0]->dtv_property_cache.hierarchy = HIERARCHY_NONE;
 		break;
@@ -1222,7 +1248,7 @@
 		state->fe[0]->dtv_property_cache.hierarchy = HIERARCHY_AUTO;
 		break;
 	}
-	switch (ch.code_rate_hp) {
+	switch (ch->code_rate_hp) {
 	case 1:
 		state->fe[0]->dtv_property_cache.code_rate_HP = FEC_1_2;
 		break;
@@ -1243,7 +1269,7 @@
 		state->fe[0]->dtv_property_cache.code_rate_HP = FEC_AUTO;
 		break;
 	}
-	switch (ch.code_rate_lp) {
+	switch (ch->code_rate_lp) {
 	case 1:
 		state->fe[0]->dtv_property_cache.code_rate_LP = FEC_1_2;
 		break;
@@ -1439,9 +1465,10 @@
 		break;
 	case CT_DEMOD_STEP_1:
 		if (search)
-			dib9000_risc_mem_read(state, FE_MM_R_CHANNEL_SEARCH_STATE, (u8 *) &i, 1);
+			dib9000_risc_mem_read(state, FE_MM_R_CHANNEL_SEARCH_STATE, state->i2c_read_buffer, 1);
 		else
-			dib9000_risc_mem_read(state, FE_MM_R_CHANNEL_TUNE_STATE, (u8 *) &i, 1);
+			dib9000_risc_mem_read(state, FE_MM_R_CHANNEL_TUNE_STATE, state->i2c_read_buffer, 1);
+		i = (s8)state->i2c_read_buffer[0];
 		switch (i) {	/* something happened */
 		case 0:
 			break;
@@ -2038,14 +2065,17 @@
 static int dib9000_read_ber(struct dvb_frontend *fe, u32 * ber)
 {
 	struct dib9000_state *state = fe->demodulator_priv;
-	u16 c[16];
+	u16 *c;
 
 	DibAcquireLock(&state->platform.risc.mem_mbx_lock);
 	if (dib9000_fw_memmbx_sync(state, FE_SYNC_CHANNEL) < 0)
 		return -EIO;
-	dib9000_risc_mem_read(state, FE_MM_R_FE_MONITOR, (u8 *) c, sizeof(c));
+	dib9000_risc_mem_read(state, FE_MM_R_FE_MONITOR,
+			state->i2c_read_buffer, 16 * 2);
 	DibReleaseLock(&state->platform.risc.mem_mbx_lock);
 
+	c = (u16 *)state->i2c_read_buffer;
+
 	*ber = c[10] << 16 | c[11];
 	return 0;
 }
@@ -2054,7 +2084,7 @@
 {
 	struct dib9000_state *state = fe->demodulator_priv;
 	u8 index_frontend;
-	u16 c[16];
+	u16 *c = (u16 *)state->i2c_read_buffer;
 	u16 val;
 
 	*strength = 0;
@@ -2069,7 +2099,7 @@
 	DibAcquireLock(&state->platform.risc.mem_mbx_lock);
 	if (dib9000_fw_memmbx_sync(state, FE_SYNC_CHANNEL) < 0)
 		return -EIO;
-	dib9000_risc_mem_read(state, FE_MM_R_FE_MONITOR, (u8 *) c, sizeof(c));
+	dib9000_risc_mem_read(state, FE_MM_R_FE_MONITOR, (u8 *) c, 16 * 2);
 	DibReleaseLock(&state->platform.risc.mem_mbx_lock);
 
 	val = 65535 - c[4];
@@ -2083,14 +2113,14 @@
 static u32 dib9000_get_snr(struct dvb_frontend *fe)
 {
 	struct dib9000_state *state = fe->demodulator_priv;
-	u16 c[16];
+	u16 *c = (u16 *)state->i2c_read_buffer;
 	u32 n, s, exp;
 	u16 val;
 
 	DibAcquireLock(&state->platform.risc.mem_mbx_lock);
 	if (dib9000_fw_memmbx_sync(state, FE_SYNC_CHANNEL) < 0)
 		return -EIO;
-	dib9000_risc_mem_read(state, FE_MM_R_FE_MONITOR, (u8 *) c, sizeof(c));
+	dib9000_risc_mem_read(state, FE_MM_R_FE_MONITOR, (u8 *) c, 16 * 2);
 	DibReleaseLock(&state->platform.risc.mem_mbx_lock);
 
 	val = c[7];
@@ -2137,12 +2167,12 @@
 static int dib9000_read_unc_blocks(struct dvb_frontend *fe, u32 * unc)
 {
 	struct dib9000_state *state = fe->demodulator_priv;
-	u16 c[16];
+	u16 *c = (u16 *)state->i2c_read_buffer;
 
 	DibAcquireLock(&state->platform.risc.mem_mbx_lock);
 	if (dib9000_fw_memmbx_sync(state, FE_SYNC_CHANNEL) < 0)
 		return -EIO;
-	dib9000_risc_mem_read(state, FE_MM_R_FE_MONITOR, (u8 *) c, sizeof(c));
+	dib9000_risc_mem_read(state, FE_MM_R_FE_MONITOR, (u8 *) c, 16 * 2);
 	DibReleaseLock(&state->platform.risc.mem_mbx_lock);
 
 	*unc = c[12];
@@ -2151,10 +2181,22 @@
 
 int dib9000_i2c_enumeration(struct i2c_adapter *i2c, int no_of_demods, u8 default_addr, u8 first_addr)
 {
-	int k = 0;
+	int k = 0, ret = 0;
 	u8 new_addr = 0;
 	struct i2c_device client = {.i2c_adap = i2c };
 
+	client.i2c_write_buffer = kzalloc(4 * sizeof(u8), GFP_KERNEL);
+	if (!client.i2c_write_buffer) {
+		dprintk("%s: not enough memory", __func__);
+		return -ENOMEM;
+	}
+	client.i2c_read_buffer = kzalloc(4 * sizeof(u8), GFP_KERNEL);
+	if (!client.i2c_read_buffer) {
+		dprintk("%s: not enough memory", __func__);
+		ret = -ENOMEM;
+		goto error_memory;
+	}
+
 	client.i2c_addr = default_addr + 16;
 	dib9000_i2c_write16(&client, 1796, 0x0);
 
@@ -2178,7 +2220,8 @@
 			client.i2c_addr = default_addr;
 			if (dib9000_identify(&client) == 0) {
 				dprintk("DiB9000 #%d: not identified", k);
-				return -EIO;
+				ret = -EIO;
+				goto error;
 			}
 		}
 
@@ -2196,7 +2239,12 @@
 		dib9000_i2c_write16(&client, 1795, 0);
 	}
 
-	return 0;
+error:
+	kfree(client.i2c_read_buffer);
+error_memory:
+	kfree(client.i2c_write_buffer);
+
+	return ret;
 }
 EXPORT_SYMBOL(dib9000_i2c_enumeration);
 
@@ -2255,12 +2303,16 @@
 	if (st == NULL)
 		return NULL;
 	fe = kzalloc(sizeof(struct dvb_frontend), GFP_KERNEL);
-	if (fe == NULL)
+	if (fe == NULL) {
+		kfree(st);
 		return NULL;
+	}
 
 	memcpy(&st->chip.d9.cfg, cfg, sizeof(struct dib9000_config));
 	st->i2c.i2c_adap = i2c_adap;
 	st->i2c.i2c_addr = i2c_addr;
+	st->i2c.i2c_write_buffer = st->i2c_write_buffer;
+	st->i2c.i2c_read_buffer = st->i2c_read_buffer;
 
 	st->gpio_dir = DIB9000_GPIO_DEFAULT_DIRECTIONS;
 	st->gpio_val = DIB9000_GPIO_DEFAULT_VALUES;
diff -druN linux-2.6.39-libre/drivers/media/dvb/frontends/dibx000_common.c linux-3.0-rc7-libre/drivers/media/dvb/frontends/dibx000_common.c
--- linux-2.6.39-libre/drivers/media/dvb/frontends/dibx000_common.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/dvb/frontends/dibx000_common.c	2011-07-11 19:51:52.000000000 -0400
@@ -10,30 +10,39 @@
 
 static int dibx000_write_word(struct dibx000_i2c_master *mst, u16 reg, u16 val)
 {
-	u8 b[4] = {
-		(reg >> 8) & 0xff, reg & 0xff,
-		(val >> 8) & 0xff, val & 0xff,
-	};
-	struct i2c_msg msg = {
-		.addr = mst->i2c_addr,.flags = 0,.buf = b,.len = 4
-	};
+	mst->i2c_write_buffer[0] = (reg >> 8) & 0xff;
+	mst->i2c_write_buffer[1] = reg & 0xff;
+	mst->i2c_write_buffer[2] = (val >> 8) & 0xff;
+	mst->i2c_write_buffer[3] = val & 0xff;
 
-	return i2c_transfer(mst->i2c_adap, &msg, 1) != 1 ? -EREMOTEIO : 0;
+	memset(mst->msg, 0, sizeof(struct i2c_msg));
+	mst->msg[0].addr = mst->i2c_addr;
+	mst->msg[0].flags = 0;
+	mst->msg[0].buf = mst->i2c_write_buffer;
+	mst->msg[0].len = 4;
+
+	return i2c_transfer(mst->i2c_adap, mst->msg, 1) != 1 ? -EREMOTEIO : 0;
 }
 
 static u16 dibx000_read_word(struct dibx000_i2c_master *mst, u16 reg)
 {
-	u8 wb[2] = { reg >> 8, reg & 0xff };
-	u8 rb[2];
-	struct i2c_msg msg[2] = {
-		{.addr = mst->i2c_addr, .flags = 0, .buf = wb, .len = 2},
-		{.addr = mst->i2c_addr, .flags = I2C_M_RD, .buf = rb, .len = 2},
-	};
+	mst->i2c_write_buffer[0] = reg >> 8;
+	mst->i2c_write_buffer[1] = reg & 0xff;
 
-	if (i2c_transfer(mst->i2c_adap, msg, 2) != 2)
+	memset(mst->msg, 0, 2 * sizeof(struct i2c_msg));
+	mst->msg[0].addr = mst->i2c_addr;
+	mst->msg[0].flags = 0;
+	mst->msg[0].buf = mst->i2c_write_buffer;
+	mst->msg[0].len = 2;
+	mst->msg[1].addr = mst->i2c_addr;
+	mst->msg[1].flags = I2C_M_RD;
+	mst->msg[1].buf = mst->i2c_read_buffer;
+	mst->msg[1].len = 2;
+
+	if (i2c_transfer(mst->i2c_adap, mst->msg, 2) != 2)
 		dprintk("i2c read error on %d", reg);
 
-	return (rb[0] << 8) | rb[1];
+	return (mst->i2c_read_buffer[0] << 8) | mst->i2c_read_buffer[1];
 }
 
 static int dibx000_is_i2c_done(struct dibx000_i2c_master *mst)
@@ -248,26 +257,32 @@
 					struct i2c_msg msg[], int num)
 {
 	struct dibx000_i2c_master *mst = i2c_get_adapdata(i2c_adap);
-	struct i2c_msg m[2 + num];
-	u8 tx_open[4], tx_close[4];
 
-	memset(m, 0, sizeof(struct i2c_msg) * (2 + num));
+	if (num > 32) {
+		dprintk("%s: too much I2C message to be transmitted (%i).\
+				Maximum is 32", __func__, num);
+		return -ENOMEM;
+	}
+
+	memset(mst->msg, 0, sizeof(struct i2c_msg) * (2 + num));
 
 	dibx000_i2c_select_interface(mst, DIBX000_I2C_INTERFACE_GPIO_6_7);
 
-	dibx000_i2c_gate_ctrl(mst, tx_open, msg[0].addr, 1);
-	m[0].addr = mst->i2c_addr;
-	m[0].buf = tx_open;
-	m[0].len = 4;
+	/* open the gate */
+	dibx000_i2c_gate_ctrl(mst, &mst->i2c_write_buffer[0], msg[0].addr, 1);
+	mst->msg[0].addr = mst->i2c_addr;
+	mst->msg[0].buf = &mst->i2c_write_buffer[0];
+	mst->msg[0].len = 4;
 
-	memcpy(&m[1], msg, sizeof(struct i2c_msg) * num);
+	memcpy(&mst->msg[1], msg, sizeof(struct i2c_msg) * num);
 
-	dibx000_i2c_gate_ctrl(mst, tx_close, 0, 0);
-	m[num + 1].addr = mst->i2c_addr;
-	m[num + 1].buf = tx_close;
-	m[num + 1].len = 4;
+	/* close the gate */
+	dibx000_i2c_gate_ctrl(mst, &mst->i2c_write_buffer[4], 0, 0);
+	mst->msg[num + 1].addr = mst->i2c_addr;
+	mst->msg[num + 1].buf = &mst->i2c_write_buffer[4];
+	mst->msg[num + 1].len = 4;
 
-	return i2c_transfer(mst->i2c_adap, m, 2 + num) == 2 + num ? num : -EIO;
+	return i2c_transfer(mst->i2c_adap, mst->msg, 2 + num) == 2 + num ? num : -EIO;
 }
 
 static struct i2c_algorithm dibx000_i2c_gated_gpio67_algo = {
@@ -279,26 +294,32 @@
 					struct i2c_msg msg[], int num)
 {
 	struct dibx000_i2c_master *mst = i2c_get_adapdata(i2c_adap);
-	struct i2c_msg m[2 + num];
-	u8 tx_open[4], tx_close[4];
 
-	memset(m, 0, sizeof(struct i2c_msg) * (2 + num));
+	if (num > 32) {
+		dprintk("%s: too much I2C message to be transmitted (%i).\
+				Maximum is 32", __func__, num);
+		return -ENOMEM;
+	}
+
+	memset(mst->msg, 0, sizeof(struct i2c_msg) * (2 + num));
 
 	dibx000_i2c_select_interface(mst, DIBX000_I2C_INTERFACE_TUNER);
 
-	dibx000_i2c_gate_ctrl(mst, tx_open, msg[0].addr, 1);
-	m[0].addr = mst->i2c_addr;
-	m[0].buf = tx_open;
-	m[0].len = 4;
+	/* open the gate */
+	dibx000_i2c_gate_ctrl(mst, &mst->i2c_write_buffer[0], msg[0].addr, 1);
+	mst->msg[0].addr = mst->i2c_addr;
+	mst->msg[0].buf = &mst->i2c_write_buffer[0];
+	mst->msg[0].len = 4;
 
-	memcpy(&m[1], msg, sizeof(struct i2c_msg) * num);
+	memcpy(&mst->msg[1], msg, sizeof(struct i2c_msg) * num);
 
-	dibx000_i2c_gate_ctrl(mst, tx_close, 0, 0);
-	m[num + 1].addr = mst->i2c_addr;
-	m[num + 1].buf = tx_close;
-	m[num + 1].len = 4;
+	/* close the gate */
+	dibx000_i2c_gate_ctrl(mst, &mst->i2c_write_buffer[4], 0, 0);
+	mst->msg[num + 1].addr = mst->i2c_addr;
+	mst->msg[num + 1].buf = &mst->i2c_write_buffer[4];
+	mst->msg[num + 1].len = 4;
 
-	return i2c_transfer(mst->i2c_adap, m, 2 + num) == 2 + num ? num : -EIO;
+	return i2c_transfer(mst->i2c_adap, mst->msg, 2 + num) == 2 + num ? num : -EIO;
 }
 
 static struct i2c_algorithm dibx000_i2c_gated_tuner_algo = {
diff -druN linux-2.6.39-libre/drivers/media/dvb/frontends/dibx000_common.h linux-3.0-rc7-libre/drivers/media/dvb/frontends/dibx000_common.h
--- linux-2.6.39-libre/drivers/media/dvb/frontends/dibx000_common.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/dvb/frontends/dibx000_common.h	2011-07-11 19:51:52.000000000 -0400
@@ -28,6 +28,11 @@
 	u8 i2c_addr;
 
 	u16 base_reg;
+
+	/* for the I2C transfer */
+	struct i2c_msg msg[34];
+	u8 i2c_write_buffer[8];
+	u8 i2c_read_buffer[2];
 };
 
 extern int dibx000_init_i2c_master(struct dibx000_i2c_master *mst,
diff -druN linux-2.6.39-libre/drivers/media/dvb/frontends/drx397xD.c linux-3.0-rc7-libre/drivers/media/dvb/frontends/drx397xD.c
--- linux-2.6.39-libre/drivers/media/dvb/frontends/drx397xD.c	2011-05-19 02:09:37.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/dvb/frontends/drx397xD.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,1511 +0,0 @@
-/*
- * Driver for Micronas drx397xD demodulator
- *
- * Copyright (C) 2007 Henk Vergonet <Henk.Vergonet@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, see <http://www.gnu.org/licenses/>.
- */
-
-#define DEBUG			/* uncomment if you want debugging output */
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/init.h>
-#include <linux/device.h>
-#include <linux/delay.h>
-#include <linux/string.h>
-#include <linux/firmware.h>
-#include <linux/slab.h>
-#include <asm/div64.h>
-
-#include "dvb_frontend.h"
-#include "drx397xD.h"
-
-static const char mod_name[] = "drx397xD";
-
-#define MAX_CLOCK_DRIFT		200	/* maximal 200 PPM allowed */
-
-#define F_SET_0D0h	1
-#define F_SET_0D4h	2
-
-enum fw_ix {
-#define _FW_ENTRY(a, b, c)	b
-#include "drx397xD_fw.h"
-};
-
-/* chip specifics */
-struct drx397xD_state {
-	struct i2c_adapter *i2c;
-	struct dvb_frontend frontend;
-	struct drx397xD_config config;
-	enum fw_ix chip_rev;
-	int flags;
-	u32 bandwidth_parm;	/* internal bandwidth conversions */
-	u32 f_osc;		/* w90: actual osc frequency [Hz] */
-};
-
-/* Firmware */
-static const char *blob_name[] = {
-#define _BLOB_ENTRY(a, b)		a
-#include "drx397xD_fw.h"
-};
-
-enum blob_ix {
-#define _BLOB_ENTRY(a, b)		b
-#include "drx397xD_fw.h"
-};
-
-static struct {
-	const char *name;
-	const struct firmware *file;
-	rwlock_t lock;
-	int refcnt;
-	const u8 *data[ARRAY_SIZE(blob_name)];
-} fw[] = {
-#define _FW_ENTRY(a, b, c)	{					\
-			.name	= a,					\
-			.file	= NULL,					\
-			.lock	= __RW_LOCK_UNLOCKED(fw[c].lock),	\
-			.refcnt = 0,					\
-			.data	= { }		}
-#include "drx397xD_fw.h"
-};
-
-/* use only with writer lock acquired */
-static void _drx_release_fw(struct drx397xD_state *s, enum fw_ix ix)
-{
-	memset(&fw[ix].data[0], 0, sizeof(fw[0].data));
-	if (fw[ix].file)
-		release_firmware(fw[ix].file);
-}
-
-static void drx_release_fw(struct drx397xD_state *s)
-{
-	enum fw_ix ix = s->chip_rev;
-
-	pr_debug("%s\n", __func__);
-
-	write_lock(&fw[ix].lock);
-	if (fw[ix].refcnt) {
-		fw[ix].refcnt--;
-		if (fw[ix].refcnt == 0)
-			_drx_release_fw(s, ix);
-	}
-	write_unlock(&fw[ix].lock);
-}
-
-static int drx_load_fw(struct drx397xD_state *s, enum fw_ix ix)
-{
-	const u8 *data;
-	size_t size, len;
-	int i = 0, j, rc = -EINVAL;
-
-	pr_debug("%s\n", __func__);
-
-	if (ix < 0 || ix >= ARRAY_SIZE(fw))
-		return -EINVAL;
-	s->chip_rev = ix;
-
-	write_lock(&fw[ix].lock);
-	if (fw[ix].file) {
-		rc = 0;
-		goto exit_ok;
-	}
-	memset(&fw[ix].data[0], 0, sizeof(fw[0].data));
-
-	rc = reject_firmware(&fw[ix].file, fw[ix].name, s->i2c->dev.parent);
-	if (rc != 0) {
-		printk(KERN_ERR "%s: Firmware \"%s\" not available\n",
-		       mod_name, fw[ix].name);
-		goto exit_err;
-	}
-
-	if (!fw[ix].file->data || fw[ix].file->size < 10)
-		goto exit_corrupt;
-
-	data = fw[ix].file->data;
-	size = fw[ix].file->size;
-
-	if (data[i++] != 2)	/* check firmware version */
-		goto exit_corrupt;
-
-	do {
-		switch (data[i++]) {
-		case 0x00:	/* bytecode */
-			if (i >= size)
-				break;
-			i += data[i];
-		case 0x01:	/* reset */
-		case 0x02:	/* sleep */
-			i++;
-			break;
-		case 0xfe:	/* name */
-			len = strnlen(&data[i], size - i);
-			if (i + len + 1 >= size)
-				goto exit_corrupt;
-			if (data[i + len + 1] != 0)
-				goto exit_corrupt;
-			for (j = 0; j < ARRAY_SIZE(blob_name); j++) {
-				if (strcmp(blob_name[j], &data[i]) == 0) {
-					fw[ix].data[j] = &data[i + len + 1];
-					pr_debug("Loading %s\n", blob_name[j]);
-				}
-			}
-			i += len + 1;
-			break;
-		case 0xff:	/* file terminator */
-			if (i == size) {
-				rc = 0;
-				goto exit_ok;
-			}
-		default:
-			goto exit_corrupt;
-		}
-	} while (i < size);
-
-exit_corrupt:
-	printk(KERN_ERR "%s: Firmware is corrupt\n", mod_name);
-exit_err:
-	_drx_release_fw(s, ix);
-	fw[ix].refcnt--;
-exit_ok:
-	fw[ix].refcnt++;
-	write_unlock(&fw[ix].lock);
-
-	return rc;
-}
-
-/* i2c bus IO */
-static int write_fw(struct drx397xD_state *s, enum blob_ix ix)
-{
-	const u8 *data;
-	int len, rc = 0, i = 0;
-	struct i2c_msg msg = {
-		.addr = s->config.demod_address,
-		.flags = 0
-	};
-
-	if (ix < 0 || ix >= ARRAY_SIZE(blob_name)) {
-		pr_debug("%s drx_fw_ix_t out of range\n", __func__);
-		return -EINVAL;
-	}
-	pr_debug("%s %s\n", __func__, blob_name[ix]);
-
-	read_lock(&fw[s->chip_rev].lock);
-	data = fw[s->chip_rev].data[ix];
-	if (!data) {
-		rc = -EINVAL;
-		goto exit_rc;
-	}
-
-	for (;;) {
-		switch (data[i++]) {
-		case 0:	/* bytecode */
-			len = data[i++];
-			msg.len = len;
-			msg.buf = (__u8 *) &data[i];
-			if (i2c_transfer(s->i2c, &msg, 1) != 1) {
-				rc = -EIO;
-				goto exit_rc;
-			}
-			i += len;
-			break;
-		case 1:	/* reset */
-		case 2:	/* sleep */
-			i++;
-			break;
-		default:
-			goto exit_rc;
-		}
-	}
-exit_rc:
-	read_unlock(&fw[s->chip_rev].lock);
-
-	return rc;
-}
-
-/* Function is not endian safe, use the RD16 wrapper below */
-static int _read16(struct drx397xD_state *s, __le32 i2c_adr)
-{
-	int rc;
-	u8 a[4];
-	__le16 v;
-	struct i2c_msg msg[2] = {
-		{
-			.addr = s->config.demod_address,
-			.flags = 0,
-			.buf = a,
-			.len = sizeof(a)
-		}, {
-			.addr = s->config.demod_address,
-			.flags = I2C_M_RD,
-			.buf = (u8 *)&v,
-			.len = sizeof(v)
-		}
-	};
-
-	*(__le32 *) a = i2c_adr;
-
-	rc = i2c_transfer(s->i2c, msg, 2);
-	if (rc != 2)
-		return -EIO;
-
-	return le16_to_cpu(v);
-}
-
-/* Function is not endian safe, use the WR16.. wrappers below */
-static int _write16(struct drx397xD_state *s, __le32 i2c_adr, __le16 val)
-{
-	u8 a[6];
-	int rc;
-	struct i2c_msg msg = {
-		.addr = s->config.demod_address,
-		.flags = 0,
-		.buf = a,
-		.len = sizeof(a)
-	};
-
-	*(__le32 *)a = i2c_adr;
-	*(__le16 *)&a[4] = val;
-
-	rc = i2c_transfer(s->i2c, &msg, 1);
-	if (rc != 1)
-		return -EIO;
-
-	return 0;
-}
-
-#define WR16(ss, adr, val) \
-		_write16(ss, I2C_ADR_C0(adr), cpu_to_le16(val))
-#define WR16_E0(ss, adr, val) \
-		_write16(ss, I2C_ADR_E0(adr), cpu_to_le16(val))
-#define RD16(ss, adr) \
-		_read16(ss, I2C_ADR_C0(adr))
-
-#define EXIT_RC(cmd)	\
-	if ((rc = (cmd)) < 0)	\
-		goto exit_rc
-
-/* Tuner callback */
-static int PLL_Set(struct drx397xD_state *s,
-		   struct dvb_frontend_parameters *fep, int *df_tuner)
-{
-	struct dvb_frontend *fe = &s->frontend;
-	u32 f_tuner, f = fep->frequency;
-	int rc;
-
-	pr_debug("%s\n", __func__);
-
-	if ((f > s->frontend.ops.tuner_ops.info.frequency_max) ||
-	    (f < s->frontend.ops.tuner_ops.info.frequency_min))
-		return -EINVAL;
-
-	*df_tuner = 0;
-	if (!s->frontend.ops.tuner_ops.set_params ||
-	    !s->frontend.ops.tuner_ops.get_frequency)
-		return -ENOSYS;
-
-	rc = s->frontend.ops.tuner_ops.set_params(fe, fep);
-	if (rc < 0)
-		return rc;
-
-	rc = s->frontend.ops.tuner_ops.get_frequency(fe, &f_tuner);
-	if (rc < 0)
-		return rc;
-
-	*df_tuner = f_tuner - f;
-	pr_debug("%s requested %d [Hz] tuner %d [Hz]\n", __func__, f,
-		 f_tuner);
-
-	return 0;
-}
-
-/* Demodulator helper functions */
-static int SC_WaitForReady(struct drx397xD_state *s)
-{
-	int cnt = 1000;
-	int rc;
-
-	pr_debug("%s\n", __func__);
-
-	while (cnt--) {
-		rc = RD16(s, 0x820043);
-		if (rc == 0)
-			return 0;
-	}
-
-	return -1;
-}
-
-static int SC_SendCommand(struct drx397xD_state *s, int cmd)
-{
-	int rc;
-
-	pr_debug("%s\n", __func__);
-
-	WR16(s, 0x820043, cmd);
-	SC_WaitForReady(s);
-	rc = RD16(s, 0x820042);
-	if ((rc & 0xffff) == 0xffff)
-		return -1;
-
-	return 0;
-}
-
-static int HI_Command(struct drx397xD_state *s, u16 cmd)
-{
-	int rc, cnt = 1000;
-
-	pr_debug("%s\n", __func__);
-
-	rc = WR16(s, 0x420032, cmd);
-	if (rc < 0)
-		return rc;
-
-	do {
-		rc = RD16(s, 0x420032);
-		if (rc == 0) {
-			rc = RD16(s, 0x420031);
-			return rc;
-		}
-		if (rc < 0)
-			return rc;
-	} while (--cnt);
-
-	return rc;
-}
-
-static int HI_CfgCommand(struct drx397xD_state *s)
-{
-
-	pr_debug("%s\n", __func__);
-
-	WR16(s, 0x420033, 0x3973);
-	WR16(s, 0x420034, s->config.w50);	/* code 4, log 4 */
-	WR16(s, 0x420035, s->config.w52);	/* code 15,  log 9 */
-	WR16(s, 0x420036, s->config.demod_address << 1);
-	WR16(s, 0x420037, s->config.w56);	/* code (set_i2c ??  initX 1 ), log 1 */
-	/* WR16(s, 0x420033, 0x3973); */
-	if ((s->config.w56 & 8) == 0)
-		return HI_Command(s, 3);
-
-	return WR16(s, 0x420032, 0x3);
-}
-
-static const u8 fastIncrDecLUT_15273[] = {
-	0x0e, 0x0f, 0x0f, 0x10, 0x11, 0x12, 0x12, 0x13, 0x14,
-	0x15, 0x16, 0x17, 0x18, 0x1a, 0x1b, 0x1c, 0x1d, 0x1f
-};
-
-static const u8 slowIncrDecLUT_15272[] = {
-	3, 4, 4, 5, 6
-};
-
-static int SetCfgIfAgc(struct drx397xD_state *s, struct drx397xD_CfgIfAgc *agc)
-{
-	u16 w06 = agc->w06;
-	u16 w08 = agc->w08;
-	u16 w0A = agc->w0A;
-	u16 w0C = agc->w0C;
-	int quot, rem, i, rc = -EINVAL;
-
-	pr_debug("%s\n", __func__);
-
-	if (agc->w04 > 0x3ff)
-		goto exit_rc;
-
-	if (agc->d00 == 1) {
-		EXIT_RC(RD16(s, 0x0c20010));
-		rc &= ~0x10;
-		EXIT_RC(WR16(s, 0x0c20010, rc));
-		return WR16(s, 0x0c20030, agc->w04 & 0x7ff);
-	}
-
-	if (agc->d00 != 0)
-		goto exit_rc;
-	if (w0A < w08)
-		goto exit_rc;
-	if (w0A > 0x3ff)
-		goto exit_rc;
-	if (w0C > 0x3ff)
-		goto exit_rc;
-	if (w06 > 0x3ff)
-		goto exit_rc;
-
-	EXIT_RC(RD16(s, 0x0c20010));
-	rc |= 0x10;
-	EXIT_RC(WR16(s, 0x0c20010, rc));
-
-	EXIT_RC(WR16(s, 0x0c20025, (w06 >> 1) & 0x1ff));
-	EXIT_RC(WR16(s, 0x0c20031, (w0A - w08) >> 1));
-	EXIT_RC(WR16(s, 0x0c20032, ((w0A + w08) >> 1) - 0x1ff));
-
-	quot = w0C / 113;
-	rem = w0C % 113;
-	if (quot <= 8) {
-		quot = 8 - quot;
-	} else {
-		quot = 0;
-		rem += 113;
-	}
-
-	EXIT_RC(WR16(s, 0x0c20024, quot));
-
-	i = fastIncrDecLUT_15273[rem / 8];
-	EXIT_RC(WR16(s, 0x0c2002d, i));
-	EXIT_RC(WR16(s, 0x0c2002e, i));
-
-	i = slowIncrDecLUT_15272[rem / 28];
-	EXIT_RC(WR16(s, 0x0c2002b, i));
-	rc = WR16(s, 0x0c2002c, i);
-exit_rc:
-	return rc;
-}
-
-static int SetCfgRfAgc(struct drx397xD_state *s, struct drx397xD_CfgRfAgc *agc)
-{
-	u16 w04 = agc->w04;
-	u16 w06 = agc->w06;
-	int rc = -1;
-
-	pr_debug("%s %d 0x%x 0x%x\n", __func__, agc->d00, w04, w06);
-
-	if (w04 > 0x3ff)
-		goto exit_rc;
-
-	switch (agc->d00) {
-	case 1:
-		if (w04 == 0x3ff)
-			w04 = 0x400;
-
-		EXIT_RC(WR16(s, 0x0c20036, w04));
-		s->config.w9C &= ~2;
-		EXIT_RC(WR16(s, 0x0c20015, s->config.w9C));
-		EXIT_RC(RD16(s, 0x0c20010));
-		rc &= 0xbfdf;
-		EXIT_RC(WR16(s, 0x0c20010, rc));
-		EXIT_RC(RD16(s, 0x0c20013));
-		rc &= ~2;
-		break;
-	case 0:
-		/* loc_8000659 */
-		s->config.w9C &= ~2;
-		EXIT_RC(WR16(s, 0x0c20015, s->config.w9C));
-		EXIT_RC(RD16(s, 0x0c20010));
-		rc &= 0xbfdf;
-		rc |= 0x4000;
-		EXIT_RC(WR16(s, 0x0c20010, rc));
-		EXIT_RC(WR16(s, 0x0c20051, (w06 >> 4) & 0x3f));
-		EXIT_RC(RD16(s, 0x0c20013));
-		rc &= ~2;
-		break;
-	default:
-		s->config.w9C |= 2;
-		EXIT_RC(WR16(s, 0x0c20015, s->config.w9C));
-		EXIT_RC(RD16(s, 0x0c20010));
-		rc &= 0xbfdf;
-		EXIT_RC(WR16(s, 0x0c20010, rc));
-
-		EXIT_RC(WR16(s, 0x0c20036, 0));
-
-		EXIT_RC(RD16(s, 0x0c20013));
-		rc |= 2;
-	}
-	rc = WR16(s, 0x0c20013, rc);
-
-exit_rc:
-	return rc;
-}
-
-static int GetLockStatus(struct drx397xD_state *s, int *lockstat)
-{
-	int rc;
-
-	*lockstat = 0;
-
-	rc = RD16(s, 0x082004b);
-	if (rc < 0)
-		return rc;
-
-	if (s->config.d60 != 2)
-		return 0;
-
-	if ((rc & 7) == 7)
-		*lockstat |= 1;
-	if ((rc & 3) == 3)
-		*lockstat |= 2;
-	if (rc & 1)
-		*lockstat |= 4;
-	return 0;
-}
-
-static int CorrectSysClockDeviation(struct drx397xD_state *s)
-{
-	int rc = -EINVAL;
-	int lockstat;
-	u32 clk, clk_limit;
-
-	pr_debug("%s\n", __func__);
-
-	if (s->config.d5C == 0) {
-		EXIT_RC(WR16(s, 0x08200e8, 0x010));
-		EXIT_RC(WR16(s, 0x08200e9, 0x113));
-		s->config.d5C = 1;
-		return rc;
-	}
-	if (s->config.d5C != 1)
-		goto exit_rc;
-
-	rc = RD16(s, 0x0820048);
-
-	rc = GetLockStatus(s, &lockstat);
-	if (rc < 0)
-		goto exit_rc;
-	if ((lockstat & 1) == 0)
-		goto exit_rc;
-
-	EXIT_RC(WR16(s, 0x0420033, 0x200));
-	EXIT_RC(WR16(s, 0x0420034, 0xc5));
-	EXIT_RC(WR16(s, 0x0420035, 0x10));
-	EXIT_RC(WR16(s, 0x0420036, 0x1));
-	EXIT_RC(WR16(s, 0x0420037, 0xa));
-	EXIT_RC(HI_Command(s, 6));
-	EXIT_RC(RD16(s, 0x0420040));
-	clk = rc;
-	EXIT_RC(RD16(s, 0x0420041));
-	clk |= rc << 16;
-
-	if (clk <= 0x26ffff)
-		goto exit_rc;
-	if (clk > 0x610000)
-		goto exit_rc;
-
-	if (!s->bandwidth_parm)
-		return -EINVAL;
-
-	/* round & convert to Hz */
-	clk = ((u64) (clk + 0x800000) * s->bandwidth_parm + (1 << 20)) >> 21;
-	clk_limit = s->config.f_osc * MAX_CLOCK_DRIFT / 1000;
-
-	if (clk - s->config.f_osc * 1000 + clk_limit <= 2 * clk_limit) {
-		s->f_osc = clk;
-		pr_debug("%s: osc %d %d [Hz]\n", __func__,
-			 s->config.f_osc * 1000, clk - s->config.f_osc * 1000);
-	}
-	rc = WR16(s, 0x08200e8, 0);
-
-exit_rc:
-	return rc;
-}
-
-static int ConfigureMPEGOutput(struct drx397xD_state *s, int type)
-{
-	int rc, si, bp;
-
-	pr_debug("%s\n", __func__);
-
-	si = s->config.wA0;
-	if (s->config.w98 == 0) {
-		si |= 1;
-		bp = 0;
-	} else {
-		si &= ~1;
-		bp = 0x200;
-	}
-	if (s->config.w9A == 0)
-		si |= 0x80;
-	else
-		si &= ~0x80;
-
-	EXIT_RC(WR16(s, 0x2150045, 0));
-	EXIT_RC(WR16(s, 0x2150010, si));
-	EXIT_RC(WR16(s, 0x2150011, bp));
-	rc = WR16(s, 0x2150012, (type == 0 ? 0xfff : 0));
-
-exit_rc:
-	return rc;
-}
-
-static int drx_tune(struct drx397xD_state *s,
-		    struct dvb_frontend_parameters *fep)
-{
-	u16 v22 = 0;
-	u16 v1C = 0;
-	u16 v1A = 0;
-	u16 v18 = 0;
-	u32 edi = 0, ebx = 0, ebp = 0, edx = 0;
-	u16 v20 = 0, v1E = 0, v16 = 0, v14 = 0, v12 = 0, v10 = 0, v0E = 0;
-
-	int rc, df_tuner = 0;
-	int a, b, c, d;
-	pr_debug("%s %d\n", __func__, s->config.d60);
-
-	if (s->config.d60 != 2)
-		goto set_tuner;
-	rc = CorrectSysClockDeviation(s);
-	if (rc < 0)
-		goto set_tuner;
-
-	s->config.d60 = 1;
-	rc = ConfigureMPEGOutput(s, 0);
-	if (rc < 0)
-		goto set_tuner;
-set_tuner:
-
-	rc = PLL_Set(s, fep, &df_tuner);
-	if (rc < 0) {
-		printk(KERN_ERR "Error in pll_set\n");
-		goto exit_rc;
-	}
-	msleep(200);
-
-	a = rc = RD16(s, 0x2150016);
-	if (rc < 0)
-		goto exit_rc;
-	b = rc = RD16(s, 0x2150010);
-	if (rc < 0)
-		goto exit_rc;
-	c = rc = RD16(s, 0x2150034);
-	if (rc < 0)
-		goto exit_rc;
-	d = rc = RD16(s, 0x2150035);
-	if (rc < 0)
-		goto exit_rc;
-	rc = WR16(s, 0x2150014, c);
-	rc = WR16(s, 0x2150015, d);
-	rc = WR16(s, 0x2150010, 0);
-	rc = WR16(s, 0x2150000, 2);
-	rc = WR16(s, 0x2150036, 0x0fff);
-	rc = WR16(s, 0x2150016, a);
-
-	rc = WR16(s, 0x2150010, 2);
-	rc = WR16(s, 0x2150007, 0);
-	rc = WR16(s, 0x2150000, 1);
-	rc = WR16(s, 0x2110000, 0);
-	rc = WR16(s, 0x0800000, 0);
-	rc = WR16(s, 0x2800000, 0);
-	rc = WR16(s, 0x2110010, 0x664);
-
-	rc = write_fw(s, DRXD_ResetECRAM);
-	rc = WR16(s, 0x2110000, 1);
-
-	rc = write_fw(s, DRXD_InitSC);
-	if (rc < 0)
-		goto exit_rc;
-
-	rc = SetCfgIfAgc(s, &s->config.ifagc);
-	if (rc < 0)
-		goto exit_rc;
-
-	rc = SetCfgRfAgc(s, &s->config.rfagc);
-	if (rc < 0)
-		goto exit_rc;
-
-	if (fep->u.ofdm.transmission_mode != TRANSMISSION_MODE_2K)
-		v22 = 1;
-	switch (fep->u.ofdm.transmission_mode) {
-	case TRANSMISSION_MODE_8K:
-		edi = 1;
-		if (s->chip_rev == DRXD_FW_B1)
-			break;
-
-		rc = WR16(s, 0x2010010, 0);
-		if (rc < 0)
-			break;
-		v1C = 0x63;
-		v1A = 0x53;
-		v18 = 0x43;
-		break;
-	default:
-		edi = 0;
-		if (s->chip_rev == DRXD_FW_B1)
-			break;
-
-		rc = WR16(s, 0x2010010, 1);
-		if (rc < 0)
-			break;
-
-		v1C = 0x61;
-		v1A = 0x47;
-		v18 = 0x41;
-	}
-
-	switch (fep->u.ofdm.guard_interval) {
-	case GUARD_INTERVAL_1_4:
-		edi |= 0x0c;
-		break;
-	case GUARD_INTERVAL_1_8:
-		edi |= 0x08;
-		break;
-	case GUARD_INTERVAL_1_16:
-		edi |= 0x04;
-		break;
-	case GUARD_INTERVAL_1_32:
-		break;
-	default:
-		v22 |= 2;
-	}
-
-	ebx = 0;
-	ebp = 0;
-	v20 = 0;
-	v1E = 0;
-	v16 = 0;
-	v14 = 0;
-	v12 = 0;
-	v10 = 0;
-	v0E = 0;
-
-	switch (fep->u.ofdm.hierarchy_information) {
-	case HIERARCHY_1:
-		edi |= 0x40;
-		if (s->chip_rev == DRXD_FW_B1)
-			break;
-		rc = WR16(s, 0x1c10047, 1);
-		if (rc < 0)
-			goto exit_rc;
-		rc = WR16(s, 0x2010012, 1);
-		if (rc < 0)
-			goto exit_rc;
-		ebx = 0x19f;
-		ebp = 0x1fb;
-		v20 = 0x0c0;
-		v1E = 0x195;
-		v16 = 0x1d6;
-		v14 = 0x1ef;
-		v12 = 4;
-		v10 = 5;
-		v0E = 5;
-		break;
-	case HIERARCHY_2:
-		edi |= 0x80;
-		if (s->chip_rev == DRXD_FW_B1)
-			break;
-		rc = WR16(s, 0x1c10047, 2);
-		if (rc < 0)
-			goto exit_rc;
-		rc = WR16(s, 0x2010012, 2);
-		if (rc < 0)
-			goto exit_rc;
-		ebx = 0x08f;
-		ebp = 0x12f;
-		v20 = 0x0c0;
-		v1E = 0x11e;
-		v16 = 0x1d6;
-		v14 = 0x15e;
-		v12 = 4;
-		v10 = 5;
-		v0E = 5;
-		break;
-	case HIERARCHY_4:
-		edi |= 0xc0;
-		if (s->chip_rev == DRXD_FW_B1)
-			break;
-		rc = WR16(s, 0x1c10047, 3);
-		if (rc < 0)
-			goto exit_rc;
-		rc = WR16(s, 0x2010012, 3);
-		if (rc < 0)
-			goto exit_rc;
-		ebx = 0x14d;
-		ebp = 0x197;
-		v20 = 0x0c0;
-		v1E = 0x1ce;
-		v16 = 0x1d6;
-		v14 = 0x11a;
-		v12 = 4;
-		v10 = 6;
-		v0E = 5;
-		break;
-	default:
-		v22 |= 8;
-		if (s->chip_rev == DRXD_FW_B1)
-			break;
-		rc = WR16(s, 0x1c10047, 0);
-		if (rc < 0)
-			goto exit_rc;
-		rc = WR16(s, 0x2010012, 0);
-		if (rc < 0)
-			goto exit_rc;
-				/* QPSK    QAM16  QAM64	*/
-		ebx = 0x19f;	/*                 62	*/
-		ebp = 0x1fb;	/*                 15	*/
-		v20 = 0x16a;	/*  62			*/
-		v1E = 0x195;	/*         62		*/
-		v16 = 0x1bb;	/*  15			*/
-		v14 = 0x1ef;	/*         15		*/
-		v12 = 5;	/*  16			*/
-		v10 = 5;	/*         16		*/
-		v0E = 5;	/*                 16	*/
-	}
-
-	switch (fep->u.ofdm.constellation) {
-	default:
-		v22 |= 4;
-	case QPSK:
-		if (s->chip_rev == DRXD_FW_B1)
-			break;
-
-		rc = WR16(s, 0x1c10046, 0);
-		if (rc < 0)
-			goto exit_rc;
-		rc = WR16(s, 0x2010011, 0);
-		if (rc < 0)
-			goto exit_rc;
-		rc = WR16(s, 0x201001a, 0x10);
-		if (rc < 0)
-			goto exit_rc;
-		rc = WR16(s, 0x201001b, 0);
-		if (rc < 0)
-			goto exit_rc;
-		rc = WR16(s, 0x201001c, 0);
-		if (rc < 0)
-			goto exit_rc;
-		rc = WR16(s, 0x1c10062, v20);
-		if (rc < 0)
-			goto exit_rc;
-		rc = WR16(s, 0x1c1002a, v1C);
-		if (rc < 0)
-			goto exit_rc;
-		rc = WR16(s, 0x1c10015, v16);
-		if (rc < 0)
-			goto exit_rc;
-		rc = WR16(s, 0x1c10016, v12);
-		if (rc < 0)
-			goto exit_rc;
-		break;
-	case QAM_16:
-		edi |= 0x10;
-		if (s->chip_rev == DRXD_FW_B1)
-			break;
-
-		rc = WR16(s, 0x1c10046, 1);
-		if (rc < 0)
-			goto exit_rc;
-		rc = WR16(s, 0x2010011, 1);
-		if (rc < 0)
-			goto exit_rc;
-		rc = WR16(s, 0x201001a, 0x10);
-		if (rc < 0)
-			goto exit_rc;
-		rc = WR16(s, 0x201001b, 4);
-		if (rc < 0)
-			goto exit_rc;
-		rc = WR16(s, 0x201001c, 0);
-		if (rc < 0)
-			goto exit_rc;
-		rc = WR16(s, 0x1c10062, v1E);
-		if (rc < 0)
-			goto exit_rc;
-		rc = WR16(s, 0x1c1002a, v1A);
-		if (rc < 0)
-			goto exit_rc;
-		rc = WR16(s, 0x1c10015, v14);
-		if (rc < 0)
-			goto exit_rc;
-		rc = WR16(s, 0x1c10016, v10);
-		if (rc < 0)
-			goto exit_rc;
-		break;
-	case QAM_64:
-		edi |= 0x20;
-		rc = WR16(s, 0x1c10046, 2);
-		if (rc < 0)
-			goto exit_rc;
-		rc = WR16(s, 0x2010011, 2);
-		if (rc < 0)
-			goto exit_rc;
-		rc = WR16(s, 0x201001a, 0x20);
-		if (rc < 0)
-			goto exit_rc;
-		rc = WR16(s, 0x201001b, 8);
-		if (rc < 0)
-			goto exit_rc;
-		rc = WR16(s, 0x201001c, 2);
-		if (rc < 0)
-			goto exit_rc;
-		rc = WR16(s, 0x1c10062, ebx);
-		if (rc < 0)
-			goto exit_rc;
-		rc = WR16(s, 0x1c1002a, v18);
-		if (rc < 0)
-			goto exit_rc;
-		rc = WR16(s, 0x1c10015, ebp);
-		if (rc < 0)
-			goto exit_rc;
-		rc = WR16(s, 0x1c10016, v0E);
-		if (rc < 0)
-			goto exit_rc;
-		break;
-	}
-
-	if (s->config.s20d24 == 1) {
-		rc = WR16(s, 0x2010013, 0);
-	} else {
-		rc = WR16(s, 0x2010013, 1);
-		edi |= 0x1000;
-	}
-
-	switch (fep->u.ofdm.code_rate_HP) {
-	default:
-		v22 |= 0x10;
-	case FEC_1_2:
-		if (s->chip_rev == DRXD_FW_B1)
-			break;
-		rc = WR16(s, 0x2090011, 0);
-		break;
-	case FEC_2_3:
-		edi |= 0x200;
-		if (s->chip_rev == DRXD_FW_B1)
-			break;
-		rc = WR16(s, 0x2090011, 1);
-		break;
-	case FEC_3_4:
-		edi |= 0x400;
-		if (s->chip_rev == DRXD_FW_B1)
-			break;
-		rc = WR16(s, 0x2090011, 2);
-		break;
-	case FEC_5_6:		/* 5 */
-		edi |= 0x600;
-		if (s->chip_rev == DRXD_FW_B1)
-			break;
-		rc = WR16(s, 0x2090011, 3);
-		break;
-	case FEC_7_8:		/* 7 */
-		edi |= 0x800;
-		if (s->chip_rev == DRXD_FW_B1)
-			break;
-		rc = WR16(s, 0x2090011, 4);
-		break;
-	};
-	if (rc < 0)
-		goto exit_rc;
-
-	switch (fep->u.ofdm.bandwidth) {
-	default:
-		rc = -EINVAL;
-		goto exit_rc;
-	case BANDWIDTH_8_MHZ:	/* 0 */
-	case BANDWIDTH_AUTO:
-		rc = WR16(s, 0x0c2003f, 0x32);
-		s->bandwidth_parm = ebx = 0x8b8249;
-		edx = 0;
-		break;
-	case BANDWIDTH_7_MHZ:
-		rc = WR16(s, 0x0c2003f, 0x3b);
-		s->bandwidth_parm = ebx = 0x7a1200;
-		edx = 0x4807;
-		break;
-	case BANDWIDTH_6_MHZ:
-		rc = WR16(s, 0x0c2003f, 0x47);
-		s->bandwidth_parm = ebx = 0x68a1b6;
-		edx = 0x0f07;
-		break;
-	};
-
-	if (rc < 0)
-		goto exit_rc;
-
-	rc = WR16(s, 0x08200ec, edx);
-	if (rc < 0)
-		goto exit_rc;
-
-	rc = RD16(s, 0x0820050);
-	if (rc < 0)
-		goto exit_rc;
-	rc = WR16(s, 0x0820050, rc);
-
-	{
-		/* Configure bandwidth specific factor */
-		ebx = div64_u64(((u64) (s->f_osc) << 21) + (ebx >> 1),
-				     (u64)ebx) - 0x800000;
-		EXIT_RC(WR16(s, 0x0c50010, ebx & 0xffff));
-		EXIT_RC(WR16(s, 0x0c50011, ebx >> 16));
-
-		/* drx397xD oscillator calibration */
-		ebx = div64_u64(((u64) (s->config.f_if + df_tuner) << 28) +
-				     (s->f_osc >> 1), (u64)s->f_osc);
-	}
-	ebx &= 0xfffffff;
-	if (fep->inversion == INVERSION_ON)
-		ebx = 0x10000000 - ebx;
-
-	EXIT_RC(WR16(s, 0x0c30010, ebx & 0xffff));
-	EXIT_RC(WR16(s, 0x0c30011, ebx >> 16));
-
-	EXIT_RC(WR16(s, 0x0800000, 1));
-	EXIT_RC(RD16(s, 0x0800000));
-
-
-	EXIT_RC(SC_WaitForReady(s));
-	EXIT_RC(WR16(s, 0x0820042, 0));
-	EXIT_RC(WR16(s, 0x0820041, v22));
-	EXIT_RC(WR16(s, 0x0820040, edi));
-	EXIT_RC(SC_SendCommand(s, 3));
-
-	rc = RD16(s, 0x0800000);
-
-	SC_WaitForReady(s);
-	WR16(s, 0x0820042, 0);
-	WR16(s, 0x0820041, 1);
-	WR16(s, 0x0820040, 1);
-	SC_SendCommand(s, 1);
-
-
-	rc = WR16(s, 0x2150000, 2);
-	rc = WR16(s, 0x2150016, a);
-	rc = WR16(s, 0x2150010, 4);
-	rc = WR16(s, 0x2150036, 0);
-	rc = WR16(s, 0x2150000, 1);
-	s->config.d60 = 2;
-
-exit_rc:
-	return rc;
-}
-
-/*******************************************************************************
- * DVB interface
- ******************************************************************************/
-
-static int drx397x_init(struct dvb_frontend *fe)
-{
-	struct drx397xD_state *s = fe->demodulator_priv;
-	int rc;
-
-	pr_debug("%s\n", __func__);
-
-	s->config.rfagc.d00 = 2;	/* 0x7c */
-	s->config.rfagc.w04 = 0;
-	s->config.rfagc.w06 = 0x3ff;
-
-	s->config.ifagc.d00 = 0;	/* 0x68 */
-	s->config.ifagc.w04 = 0;
-	s->config.ifagc.w06 = 140;
-	s->config.ifagc.w08 = 0;
-	s->config.ifagc.w0A = 0x3ff;
-	s->config.ifagc.w0C = 0x388;
-
-	/* for signal strength calculations */
-	s->config.ss76 = 820;
-	s->config.ss78 = 2200;
-	s->config.ss7A = 150;
-
-	/* HI_CfgCommand */
-	s->config.w50 = 4;
-	s->config.w52 = 9;
-
-	s->config.f_if = 42800000;	/* d14: intermediate frequency [Hz] */
-	s->config.f_osc = 48000;	/* s66 : oscillator frequency [kHz] */
-	s->config.w92 = 12000;
-
-	s->config.w9C = 0x000e;
-	s->config.w9E = 0x0000;
-
-	/* ConfigureMPEGOutput params */
-	s->config.wA0 = 4;
-	s->config.w98 = 1;
-	s->config.w9A = 1;
-
-	/* get chip revision */
-	rc = RD16(s, 0x2410019);
-	if (rc < 0)
-		return -ENODEV;
-
-	if (rc == 0) {
-		printk(KERN_INFO "%s: chip revision A2\n", mod_name);
-		rc = drx_load_fw(s, DRXD_FW_A2);
-	} else {
-
-		rc = (rc >> 12) - 3;
-		switch (rc) {
-		case 1:
-			s->flags |= F_SET_0D4h;
-		case 0:
-		case 4:
-			s->flags |= F_SET_0D0h;
-			break;
-		case 2:
-		case 5:
-			break;
-		case 3:
-			s->flags |= F_SET_0D4h;
-			break;
-		default:
-			return -ENODEV;
-		};
-		printk(KERN_INFO "%s: chip revision B1.%d\n", mod_name, rc);
-		rc = drx_load_fw(s, DRXD_FW_B1);
-	}
-	if (rc < 0)
-		goto error;
-
-	rc = WR16(s, 0x0420033, 0x3973);
-	if (rc < 0)
-		goto error;
-
-	rc = HI_Command(s, 2);
-
-	msleep(1);
-
-	if (s->chip_rev == DRXD_FW_A2) {
-		rc = WR16(s, 0x043012d, 0x47F);
-		if (rc < 0)
-			goto error;
-	}
-	rc = WR16_E0(s, 0x0400000, 0);
-	if (rc < 0)
-		goto error;
-
-	if (s->config.w92 > 20000 || s->config.w92 % 4000) {
-		printk(KERN_ERR "%s: invalid osc frequency\n", mod_name);
-		rc = -1;
-		goto error;
-	}
-
-	rc = WR16(s, 0x2410010, 1);
-	if (rc < 0)
-		goto error;
-	rc = WR16(s, 0x2410011, 0x15);
-	if (rc < 0)
-		goto error;
-	rc = WR16(s, 0x2410012, s->config.w92 / 4000);
-	if (rc < 0)
-		goto error;
-#ifdef ORIG_FW
-	rc = WR16(s, 0x2410015, 2);
-	if (rc < 0)
-		goto error;
-#endif
-	rc = WR16(s, 0x2410017, 0x3973);
-	if (rc < 0)
-		goto error;
-
-	s->f_osc = s->config.f_osc * 1000;	/* initial estimator */
-
-	s->config.w56 = 1;
-
-	rc = HI_CfgCommand(s);
-	if (rc < 0)
-		goto error;
-
-	rc = write_fw(s, DRXD_InitAtomicRead);
-	if (rc < 0)
-		goto error;
-
-	if (s->chip_rev == DRXD_FW_A2) {
-		rc = WR16(s, 0x2150013, 0);
-		if (rc < 0)
-			goto error;
-	}
-
-	rc = WR16_E0(s, 0x0400002, 0);
-	if (rc < 0)
-		goto error;
-	rc = WR16(s, 0x0400002, 0);
-	if (rc < 0)
-		goto error;
-
-	if (s->chip_rev == DRXD_FW_A2) {
-		rc = write_fw(s, DRXD_ResetCEFR);
-		if (rc < 0)
-			goto error;
-	}
-	rc = write_fw(s, DRXD_microcode);
-	if (rc < 0)
-		goto error;
-
-	s->config.w9C = 0x0e;
-	if (s->flags & F_SET_0D0h) {
-		s->config.w9C = 0;
-		rc = RD16(s, 0x0c20010);
-		if (rc < 0)
-			goto write_DRXD_InitFE_1;
-
-		rc &= ~0x1000;
-		rc = WR16(s, 0x0c20010, rc);
-		if (rc < 0)
-			goto write_DRXD_InitFE_1;
-
-		rc = RD16(s, 0x0c20011);
-		if (rc < 0)
-			goto write_DRXD_InitFE_1;
-
-		rc &= ~0x8;
-		rc = WR16(s, 0x0c20011, rc);
-		if (rc < 0)
-			goto write_DRXD_InitFE_1;
-
-		rc = WR16(s, 0x0c20012, 1);
-	}
-
-write_DRXD_InitFE_1:
-
-	rc = write_fw(s, DRXD_InitFE_1);
-	if (rc < 0)
-		goto error;
-
-	rc = 1;
-	if (s->chip_rev == DRXD_FW_B1) {
-		if (s->flags & F_SET_0D0h)
-			rc = 0;
-	} else {
-		if (s->flags & F_SET_0D0h)
-			rc = 4;
-	}
-
-	rc = WR16(s, 0x0C20012, rc);
-	if (rc < 0)
-		goto error;
-
-	rc = WR16(s, 0x0C20013, s->config.w9E);
-	if (rc < 0)
-		goto error;
-	rc = WR16(s, 0x0C20015, s->config.w9C);
-	if (rc < 0)
-		goto error;
-
-	rc = write_fw(s, DRXD_InitFE_2);
-	if (rc < 0)
-		goto error;
-	rc = write_fw(s, DRXD_InitFT);
-	if (rc < 0)
-		goto error;
-	rc = write_fw(s, DRXD_InitCP);
-	if (rc < 0)
-		goto error;
-	rc = write_fw(s, DRXD_InitCE);
-	if (rc < 0)
-		goto error;
-	rc = write_fw(s, DRXD_InitEQ);
-	if (rc < 0)
-		goto error;
-	rc = write_fw(s, DRXD_InitEC);
-	if (rc < 0)
-		goto error;
-	rc = write_fw(s, DRXD_InitSC);
-	if (rc < 0)
-		goto error;
-
-	rc = SetCfgIfAgc(s, &s->config.ifagc);
-	if (rc < 0)
-		goto error;
-
-	rc = SetCfgRfAgc(s, &s->config.rfagc);
-	if (rc < 0)
-		goto error;
-
-	rc = ConfigureMPEGOutput(s, 1);
-	rc = WR16(s, 0x08201fe, 0x0017);
-	rc = WR16(s, 0x08201ff, 0x0101);
-
-	s->config.d5C = 0;
-	s->config.d60 = 1;
-	s->config.d48 = 1;
-
-error:
-	return rc;
-}
-
-static int drx397x_get_frontend(struct dvb_frontend *fe,
-				struct dvb_frontend_parameters *params)
-{
-	return 0;
-}
-
-static int drx397x_set_frontend(struct dvb_frontend *fe,
-				struct dvb_frontend_parameters *params)
-{
-	struct drx397xD_state *s = fe->demodulator_priv;
-
-	s->config.s20d24 = 1;
-
-	return drx_tune(s, params);
-}
-
-static int drx397x_get_tune_settings(struct dvb_frontend *fe,
-				     struct dvb_frontend_tune_settings
-				     *fe_tune_settings)
-{
-	fe_tune_settings->min_delay_ms = 10000;
-	fe_tune_settings->step_size = 0;
-	fe_tune_settings->max_drift = 0;
-
-	return 0;
-}
-
-static int drx397x_read_status(struct dvb_frontend *fe, fe_status_t *status)
-{
-	struct drx397xD_state *s = fe->demodulator_priv;
-	int lockstat;
-
-	GetLockStatus(s, &lockstat);
-
-	*status = 0;
-	if (lockstat & 2) {
-		CorrectSysClockDeviation(s);
-		ConfigureMPEGOutput(s, 1);
-		*status = FE_HAS_LOCK | FE_HAS_SYNC | FE_HAS_VITERBI;
-	}
-	if (lockstat & 4)
-		*status |= FE_HAS_CARRIER | FE_HAS_SIGNAL;
-
-	return 0;
-}
-
-static int drx397x_read_ber(struct dvb_frontend *fe, unsigned int *ber)
-{
-	*ber = 0;
-
-	return 0;
-}
-
-static int drx397x_read_snr(struct dvb_frontend *fe, u16 *snr)
-{
-	*snr = 0;
-
-	return 0;
-}
-
-static int drx397x_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
-{
-	struct drx397xD_state *s = fe->demodulator_priv;
-	int rc;
-
-	if (s->config.ifagc.d00 == 2) {
-		*strength = 0xffff;
-		return 0;
-	}
-	rc = RD16(s, 0x0c20035);
-	if (rc < 0) {
-		*strength = 0;
-		return 0;
-	}
-	rc &= 0x3ff;
-	/* Signal strength is calculated using the following formula:
-	 *
-	 * a = 2200 * 150 / (2200 + 150);
-	 * a = a * 3300 /  (a + 820);
-	 * b = 2200 * 3300 / (2200 + 820);
-	 * c = (((b-a) * rc) >> 10  + a) << 4;
-	 * strength = ~c & 0xffff;
-	 *
-	 * The following does the same but with less rounding errors:
-	 */
-	*strength = ~(7720 + (rc * 30744 >> 10));
-
-	return 0;
-}
-
-static int drx397x_read_ucblocks(struct dvb_frontend *fe,
-				 unsigned int *ucblocks)
-{
-	*ucblocks = 0;
-
-	return 0;
-}
-
-static int drx397x_sleep(struct dvb_frontend *fe)
-{
-	return 0;
-}
-
-static void drx397x_release(struct dvb_frontend *fe)
-{
-	struct drx397xD_state *s = fe->demodulator_priv;
-	printk(KERN_INFO "%s: release demodulator\n", mod_name);
-	if (s) {
-		drx_release_fw(s);
-		kfree(s);
-	}
-
-}
-
-static struct dvb_frontend_ops drx397x_ops = {
-
-	.info = {
-		 .name			= "Micronas DRX397xD DVB-T Frontend",
-		 .type			= FE_OFDM,
-		 .frequency_min		= 47125000,
-		 .frequency_max		= 855250000,
-		 .frequency_stepsize	= 166667,
-		 .frequency_tolerance	= 0,
-		 .caps =				  /* 0x0C01B2EAE */
-			 FE_CAN_FEC_1_2			| /* = 0x2, */
-			 FE_CAN_FEC_2_3			| /* = 0x4, */
-			 FE_CAN_FEC_3_4			| /* = 0x8, */
-			 FE_CAN_FEC_5_6			| /* = 0x20, */
-			 FE_CAN_FEC_7_8			| /* = 0x80, */
-			 FE_CAN_FEC_AUTO		| /* = 0x200, */
-			 FE_CAN_QPSK			| /* = 0x400, */
-			 FE_CAN_QAM_16			| /* = 0x800, */
-			 FE_CAN_QAM_64			| /* = 0x2000, */
-			 FE_CAN_QAM_AUTO		| /* = 0x10000, */
-			 FE_CAN_TRANSMISSION_MODE_AUTO	| /* = 0x20000, */
-			 FE_CAN_GUARD_INTERVAL_AUTO	| /* = 0x80000, */
-			 FE_CAN_HIERARCHY_AUTO		| /* = 0x100000, */
-			 FE_CAN_RECOVER			| /* = 0x40000000, */
-			 FE_CAN_MUTE_TS			  /* = 0x80000000 */
-	 },
-
-	.release = drx397x_release,
-	.init = drx397x_init,
-	.sleep = drx397x_sleep,
-
-	.set_frontend = drx397x_set_frontend,
-	.get_tune_settings = drx397x_get_tune_settings,
-	.get_frontend = drx397x_get_frontend,
-
-	.read_status = drx397x_read_status,
-	.read_snr = drx397x_read_snr,
-	.read_signal_strength = drx397x_read_signal_strength,
-	.read_ber = drx397x_read_ber,
-	.read_ucblocks = drx397x_read_ucblocks,
-};
-
-struct dvb_frontend *drx397xD_attach(const struct drx397xD_config *config,
-				     struct i2c_adapter *i2c)
-{
-	struct drx397xD_state *state;
-
-	/* allocate memory for the internal state */
-	state = kzalloc(sizeof(struct drx397xD_state), GFP_KERNEL);
-	if (!state)
-		goto error;
-
-	/* setup the state */
-	state->i2c = i2c;
-	memcpy(&state->config, config, sizeof(struct drx397xD_config));
-
-	/* check if the demod is there */
-	if (RD16(state, 0x2410019) < 0)
-		goto error;
-
-	/* create dvb_frontend */
-	memcpy(&state->frontend.ops, &drx397x_ops,
-			sizeof(struct dvb_frontend_ops));
-	state->frontend.demodulator_priv = state;
-
-	return &state->frontend;
-error:
-	kfree(state);
-
-	return NULL;
-}
-EXPORT_SYMBOL(drx397xD_attach);
-
-MODULE_DESCRIPTION("Micronas DRX397xD DVB-T Frontend");
-MODULE_AUTHOR("Henk Vergonet");
-MODULE_LICENSE("GPL");
-
diff -druN linux-2.6.39-libre/drivers/media/dvb/frontends/drx397xD_fw.h linux-3.0-rc7-libre/drivers/media/dvb/frontends/drx397xD_fw.h
--- linux-2.6.39-libre/drivers/media/dvb/frontends/drx397xD_fw.h	2011-05-19 02:09:39.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/dvb/frontends/drx397xD_fw.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,40 +0,0 @@
-/*
- * Firmware definitions for Micronas drx397xD
- *
- * Copyright (C) 2007 Henk Vergonet <Henk.Vergonet@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, see <http://www.gnu.org/licenses/>.
- */
-
-#ifdef _FW_ENTRY
-	_FW_ENTRY("/*(DEBLOBBED)*/",	DRXD_FW_A2 = 0,	DRXD_FW_A2	),
-	_FW_ENTRY("/*(DEBLOBBED)*/",	DRXD_FW_B1,	DRXD_FW_B1	),
-#undef _FW_ENTRY
-#endif /* _FW_ENTRY */
-
-#ifdef _BLOB_ENTRY
-	_BLOB_ENTRY("InitAtomicRead",	DRXD_InitAtomicRead = 0	),
-	_BLOB_ENTRY("InitCE",		DRXD_InitCE		),
-	_BLOB_ENTRY("InitCP",		DRXD_InitCP		),
-	_BLOB_ENTRY("InitEC",		DRXD_InitEC		),
-	_BLOB_ENTRY("InitEQ",		DRXD_InitEQ		),
-	_BLOB_ENTRY("InitFE_1",		DRXD_InitFE_1		),
-	_BLOB_ENTRY("InitFE_2",		DRXD_InitFE_2		),
-	_BLOB_ENTRY("InitFT",		DRXD_InitFT		),
-	_BLOB_ENTRY("InitSC",		DRXD_InitSC		),
-	_BLOB_ENTRY("ResetCEFR",	DRXD_ResetCEFR		),
-	_BLOB_ENTRY("ResetECRAM",	DRXD_ResetECRAM		),
-	_BLOB_ENTRY("microcode",	DRXD_microcode		),
-#undef _BLOB_ENTRY
-#endif /* _BLOB_ENTRY */
diff -druN linux-2.6.39-libre/drivers/media/dvb/frontends/drx397xD.h linux-3.0-rc7-libre/drivers/media/dvb/frontends/drx397xD.h
--- linux-2.6.39-libre/drivers/media/dvb/frontends/drx397xD.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/dvb/frontends/drx397xD.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,130 +0,0 @@
-/*
- *  Driver for Micronas DVB-T drx397xD demodulator
- *
- *  Copyright (C) 2007 Henk vergonet <Henk.Vergonet@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 _DRX397XD_H_INCLUDED
-#define _DRX397XD_H_INCLUDED
-
-#include <linux/dvb/frontend.h>
-
-#define DRX_F_STEPSIZE	166667
-#define DRX_F_OFFSET	36000000
-
-#define I2C_ADR_C0(x) \
-(	cpu_to_le32( \
-		(u32)( \
-			(((u32)(x) & (u32)0x000000ffUL)      ) | \
-			(((u32)(x) & (u32)0x0000ff00UL) << 16) | \
-			(((u32)(x) & (u32)0x0fff0000UL) >>  8) | \
-			 (	     (u32)0x00c00000UL)          \
-		      )) \
-)
-
-#define I2C_ADR_E0(x) \
-(	cpu_to_le32( \
-		(u32)( \
-			(((u32)(x) & (u32)0x000000ffUL)      ) | \
-			(((u32)(x) & (u32)0x0000ff00UL) << 16) | \
-			(((u32)(x) & (u32)0x0fff0000UL) >>  8) | \
-			 (	     (u32)0x00e00000UL)          \
-		      )) \
-)
-
-struct drx397xD_CfgRfAgc	/* 0x7c */
-{
-	int d00;	/* 2 */
-	u16 w04;
-	u16 w06;
-};
-
-struct drx397xD_CfgIfAgc	/* 0x68 */
-{
-	int d00;	/* 0 */
-	u16 w04;	/* 0 */
-	u16 w06;
-	u16 w08;
-	u16 w0A;
-	u16 w0C;
-};
-
-struct drx397xD_s20 {
-	int d04;
-	u32 d18;
-	u32 d1C;
-	u32 d20;
-	u32 d14;
-	u32 d24;
-	u32 d0C;
-	u32 d08;
-};
-
-struct drx397xD_config
-{
-	/* demodulator's I2C address */
-	u8	demod_address;		/* 0x0f */
-
-	struct drx397xD_CfgIfAgc  ifagc;  /* 0x68 */
-	struct drx397xD_CfgRfAgc  rfagc;  /* 0x7c */
-	u32	s20d24;
-
-	/* HI_CfgCommand parameters */
-	u16	w50, w52, /* w54, */ w56;
-
-	int	d5C;
-	int	d60;
-	int	d48;
-	int	d28;
-
-	u32	f_if;	/* d14: intermediate frequency [Hz]		*/
-			/*	36000000 on Cinergy 2400i DT		*/
-			/*	42800000 on Pinnacle Hybrid PRO 330e	*/
-
-	u16	f_osc;	/* s66: 48000 oscillator frequency [kHz]	*/
-
-	u16	w92;	/* 20000 */
-
-	u16	wA0;
-	u16	w98;
-	u16	w9A;
-
-	u16	w9C;	/* 0xe0 */
-	u16	w9E;	/* 0x00 */
-
-	/* used for signal strength calculations in
-	   drx397x_read_signal_strength
-	*/
-	u16	ss78;	// 2200
-	u16	ss7A;	// 150
-	u16	ss76;	// 820
-};
-
-#if defined(CONFIG_DVB_DRX397XD) || (defined(CONFIG_DVB_DRX397XD_MODULE) && defined(MODULE))
-extern struct dvb_frontend* drx397xD_attach(const struct drx397xD_config *config,
-					   struct i2c_adapter *i2c);
-#else
-static inline struct dvb_frontend* drx397xD_attach(const struct drx397xD_config *config,
-					   struct i2c_adapter *i2c)
-{
-	printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
-	return NULL;
-}
-#endif /* CONFIG_DVB_DRX397XD */
-
-#endif /* _DRX397XD_H_INCLUDED */
diff -druN linux-2.6.39-libre/drivers/media/dvb/frontends/drxd_firm.c linux-3.0-rc7-libre/drivers/media/dvb/frontends/drxd_firm.c
--- linux-2.6.39-libre/drivers/media/dvb/frontends/drxd_firm.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/media/dvb/frontends/drxd_firm.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,929 @@
+/*
+ * drxd_firm.c : DRXD firmware tables
+ *
+ * Copyright (C) 2006-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
+ */
+
+/* TODO: generate this file with a script from a settings file */
+
+/* Contains A2 firmware version: 1.4.2
+ * Contains B1 firmware version: 3.3.33
+ * Contains settings from driver 1.4.23
+*/
+
+#include "drxd_firm.h"
+
+#define ADDRESS(x)     ((x) & 0xFF), (((x)>>8) & 0xFF), (((x)>>16) & 0xFF), (((x)>>24) & 0xFF)
+#define LENGTH(x)      ((x) & 0xFF), (((x)>>8) & 0xFF)
+
+/* Is written via block write, must be little endian */
+#define DATA16(x)      ((x) & 0xFF), (((x)>>8) & 0xFF)
+
+#define WRBLOCK(a, l) ADDRESS(a), LENGTH(l)
+#define WR16(a, d) ADDRESS(a), LENGTH(1), DATA16(d)
+
+#define END_OF_TABLE      0xFF, 0xFF, 0xFF, 0xFF
+
+/* HI firmware patches */
+
+#define HI_TR_FUNC_ADDR HI_IF_RAM_USR_BEGIN__A
+#define HI_TR_FUNC_SIZE 9	/* size of this function in instruction words */
+
+u8 DRXD_InitAtomicRead[] = {
+	WRBLOCK(HI_TR_FUNC_ADDR, HI_TR_FUNC_SIZE),
+	0x26, 0x00,		/* 0         -> ring.rdy;           */
+	0x60, 0x04,		/* r0rami.dt -> ring.xba;           */
+	0x61, 0x04,		/* r0rami.dt -> ring.xad;           */
+	0xE3, 0x07,		/* HI_RA_RAM_USR_BEGIN -> ring.iad; */
+	0x40, 0x00,		/* (long immediate)                 */
+	0x64, 0x04,		/* r0rami.dt -> ring.len;           */
+	0x65, 0x04,		/* r0rami.dt -> ring.ctl;           */
+	0x26, 0x00,		/* 0         -> ring.rdy;           */
+	0x38, 0x00,		/* 0         -> jumps.ad;           */
+	END_OF_TABLE
+};
+
+/* Pins D0 and D1 of the parallel MPEG output can be used
+   to set the I2C address of a device. */
+
+#define HI_RST_FUNC_ADDR (HI_IF_RAM_USR_BEGIN__A + HI_TR_FUNC_SIZE)
+#define HI_RST_FUNC_SIZE 54	/* size of this function in instruction words */
+
+/* D0 Version */
+u8 DRXD_HiI2cPatch_1[] = {
+	WRBLOCK(HI_RST_FUNC_ADDR, HI_RST_FUNC_SIZE),
+	0xC8, 0x07, 0x01, 0x00,	/* MASK      -> reg0.dt;                        */
+	0xE0, 0x07, 0x15, 0x02,	/* (EC__BLK << 6) + EC_OC_REG__BNK -> ring.xba; */
+	0xE1, 0x07, 0x12, 0x00,	/* EC_OC_REG_OC_MPG_SIO__A -> ring.xad;         */
+	0xA2, 0x00,		/* M_BNK_ID_DAT -> ring.iba;                    */
+	0x23, 0x00,		/* &data     -> ring.iad;                       */
+	0x24, 0x00,		/* 0         -> ring.len;                       */
+	0xA5, 0x02,		/* M_RC_CTR_SWAP | M_RC_CTR_READ -> ring.ctl;   */
+	0x26, 0x00,		/* 0         -> ring.rdy;                       */
+	0x42, 0x00,		/* &data+1   -> w0ram.ad;                       */
+	0xC0, 0x07, 0xFF, 0x0F,	/* -1        -> w0ram.dt;                       */
+	0x63, 0x00,		/* &data+1   -> ring.iad;                       */
+	0x65, 0x02,		/* M_RC_CTR_SWAP | M_RC_CTR_WRITE -> ring.ctl;  */
+	0x26, 0x00,		/* 0         -> ring.rdy;                       */
+	0xE1, 0x07, 0x38, 0x00,	/* EC_OC_REG_OCR_MPG_USR_DAT__A -> ring.xad;    */
+	0xA5, 0x02,		/* M_RC_CTR_SWAP | M_RC_CTR_READ -> ring.ctl;   */
+	0x26, 0x00,		/* 0         -> ring.rdy;                       */
+	0xE1, 0x07, 0x12, 0x00,	/* EC_OC_REG_OC_MPG_SIO__A -> ring.xad;         */
+	0x23, 0x00,		/* &data     -> ring.iad;                       */
+	0x65, 0x02,		/* M_RC_CTR_SWAP | M_RC_CTR_WRITE -> ring.ctl;  */
+	0x26, 0x00,		/* 0         -> ring.rdy;                       */
+	0x42, 0x00,		/* &data+1   -> w0ram.ad;                       */
+	0x0F, 0x04,		/* r0ram.dt  -> and.op;                         */
+	0x1C, 0x06,		/* reg0.dt   -> and.tr;                         */
+	0xCF, 0x04,		/* and.rs    -> add.op;                         */
+	0xD0, 0x07, 0x70, 0x00,	/* DEF_DEV_ID -> add.tr;                        */
+	0xD0, 0x04,		/* add.rs    -> add.tr;                         */
+	0xC8, 0x04,		/* add.rs    -> reg0.dt;                        */
+	0x60, 0x00,		/* reg0.dt   -> w0ram.dt;                       */
+	0xC2, 0x07, 0x10, 0x00,	/* SLV0_BASE -> w0rami.ad;                      */
+	0x01, 0x00,		/* 0         -> w0rami.dt;                      */
+	0x01, 0x06,		/* reg0.dt   -> w0rami.dt;                      */
+	0xC2, 0x07, 0x20, 0x00,	/* SLV1_BASE -> w0rami.ad;                      */
+	0x01, 0x00,		/* 0         -> w0rami.dt;                      */
+	0x01, 0x06,		/* reg0.dt   -> w0rami.dt;                      */
+	0xC2, 0x07, 0x30, 0x00,	/* CMD_BASE  -> w0rami.ad;                      */
+	0x01, 0x00,		/* 0         -> w0rami.dt;                      */
+	0x01, 0x00,		/* 0         -> w0rami.dt;                      */
+	0x01, 0x00,		/* 0         -> w0rami.dt;                      */
+	0x68, 0x00,		/* M_IC_SEL_PT1 -> i2c.sel;                     */
+	0x29, 0x00,		/* M_IC_CMD_RESET -> i2c.cmd;                   */
+	0x28, 0x00,		/* M_IC_SEL_PT0 -> i2c.sel;                     */
+	0x29, 0x00,		/* M_IC_CMD_RESET -> i2c.cmd;                   */
+	0xF8, 0x07, 0x2F, 0x00,	/* 0x2F      -> jumps.ad;                       */
+
+	WR16((B_HI_IF_RAM_TRP_BPT0__AX + ((2 * 0) + 1)),
+	     (u16) (HI_RST_FUNC_ADDR & 0x3FF)),
+	WR16((B_HI_IF_RAM_TRP_BPT0__AX + ((2 * 1) + 1)),
+	     (u16) (HI_RST_FUNC_ADDR & 0x3FF)),
+	WR16((B_HI_IF_RAM_TRP_BPT0__AX + ((2 * 2) + 1)),
+	     (u16) (HI_RST_FUNC_ADDR & 0x3FF)),
+	WR16((B_HI_IF_RAM_TRP_BPT0__AX + ((2 * 3) + 1)),
+	     (u16) (HI_RST_FUNC_ADDR & 0x3FF)),
+
+	/* Force quick and dirty reset */
+	WR16(B_HI_CT_REG_COMM_STATE__A, 0),
+	END_OF_TABLE
+};
+
+/* D0,D1 Version */
+u8 DRXD_HiI2cPatch_3[] = {
+	WRBLOCK(HI_RST_FUNC_ADDR, HI_RST_FUNC_SIZE),
+	0xC8, 0x07, 0x03, 0x00,	/* MASK      -> reg0.dt;                        */
+	0xE0, 0x07, 0x15, 0x02,	/* (EC__BLK << 6) + EC_OC_REG__BNK -> ring.xba; */
+	0xE1, 0x07, 0x12, 0x00,	/* EC_OC_REG_OC_MPG_SIO__A -> ring.xad;         */
+	0xA2, 0x00,		/* M_BNK_ID_DAT -> ring.iba;                    */
+	0x23, 0x00,		/* &data     -> ring.iad;                       */
+	0x24, 0x00,		/* 0         -> ring.len;                       */
+	0xA5, 0x02,		/* M_RC_CTR_SWAP | M_RC_CTR_READ -> ring.ctl;   */
+	0x26, 0x00,		/* 0         -> ring.rdy;                       */
+	0x42, 0x00,		/* &data+1   -> w0ram.ad;                       */
+	0xC0, 0x07, 0xFF, 0x0F,	/* -1        -> w0ram.dt;                       */
+	0x63, 0x00,		/* &data+1   -> ring.iad;                       */
+	0x65, 0x02,		/* M_RC_CTR_SWAP | M_RC_CTR_WRITE -> ring.ctl;  */
+	0x26, 0x00,		/* 0         -> ring.rdy;                       */
+	0xE1, 0x07, 0x38, 0x00,	/* EC_OC_REG_OCR_MPG_USR_DAT__A -> ring.xad;    */
+	0xA5, 0x02,		/* M_RC_CTR_SWAP | M_RC_CTR_READ -> ring.ctl;   */
+	0x26, 0x00,		/* 0         -> ring.rdy;                       */
+	0xE1, 0x07, 0x12, 0x00,	/* EC_OC_REG_OC_MPG_SIO__A -> ring.xad;         */
+	0x23, 0x00,		/* &data     -> ring.iad;                       */
+	0x65, 0x02,		/* M_RC_CTR_SWAP | M_RC_CTR_WRITE -> ring.ctl;  */
+	0x26, 0x00,		/* 0         -> ring.rdy;                       */
+	0x42, 0x00,		/* &data+1   -> w0ram.ad;                       */
+	0x0F, 0x04,		/* r0ram.dt  -> and.op;                         */
+	0x1C, 0x06,		/* reg0.dt   -> and.tr;                         */
+	0xCF, 0x04,		/* and.rs    -> add.op;                         */
+	0xD0, 0x07, 0x70, 0x00,	/* DEF_DEV_ID -> add.tr;                        */
+	0xD0, 0x04,		/* add.rs    -> add.tr;                         */
+	0xC8, 0x04,		/* add.rs    -> reg0.dt;                        */
+	0x60, 0x00,		/* reg0.dt   -> w0ram.dt;                       */
+	0xC2, 0x07, 0x10, 0x00,	/* SLV0_BASE -> w0rami.ad;                      */
+	0x01, 0x00,		/* 0         -> w0rami.dt;                      */
+	0x01, 0x06,		/* reg0.dt   -> w0rami.dt;                      */
+	0xC2, 0x07, 0x20, 0x00,	/* SLV1_BASE -> w0rami.ad;                      */
+	0x01, 0x00,		/* 0         -> w0rami.dt;                      */
+	0x01, 0x06,		/* reg0.dt   -> w0rami.dt;                      */
+	0xC2, 0x07, 0x30, 0x00,	/* CMD_BASE  -> w0rami.ad;                      */
+	0x01, 0x00,		/* 0         -> w0rami.dt;                      */
+	0x01, 0x00,		/* 0         -> w0rami.dt;                      */
+	0x01, 0x00,		/* 0         -> w0rami.dt;                      */
+	0x68, 0x00,		/* M_IC_SEL_PT1 -> i2c.sel;                     */
+	0x29, 0x00,		/* M_IC_CMD_RESET -> i2c.cmd;                   */
+	0x28, 0x00,		/* M_IC_SEL_PT0 -> i2c.sel;                     */
+	0x29, 0x00,		/* M_IC_CMD_RESET -> i2c.cmd;                   */
+	0xF8, 0x07, 0x2F, 0x00,	/* 0x2F      -> jumps.ad;                       */
+
+	WR16((B_HI_IF_RAM_TRP_BPT0__AX + ((2 * 0) + 1)),
+	     (u16) (HI_RST_FUNC_ADDR & 0x3FF)),
+	WR16((B_HI_IF_RAM_TRP_BPT0__AX + ((2 * 1) + 1)),
+	     (u16) (HI_RST_FUNC_ADDR & 0x3FF)),
+	WR16((B_HI_IF_RAM_TRP_BPT0__AX + ((2 * 2) + 1)),
+	     (u16) (HI_RST_FUNC_ADDR & 0x3FF)),
+	WR16((B_HI_IF_RAM_TRP_BPT0__AX + ((2 * 3) + 1)),
+	     (u16) (HI_RST_FUNC_ADDR & 0x3FF)),
+
+	/* Force quick and dirty reset */
+	WR16(B_HI_CT_REG_COMM_STATE__A, 0),
+	END_OF_TABLE
+};
+
+u8 DRXD_ResetCEFR[] = {
+	WRBLOCK(CE_REG_FR_TREAL00__A, 57),
+	0x52, 0x00,		/* CE_REG_FR_TREAL00__A */
+	0x00, 0x00,		/* CE_REG_FR_TIMAG00__A */
+	0x52, 0x00,		/* CE_REG_FR_TREAL01__A */
+	0x00, 0x00,		/* CE_REG_FR_TIMAG01__A */
+	0x52, 0x00,		/* CE_REG_FR_TREAL02__A */
+	0x00, 0x00,		/* CE_REG_FR_TIMAG02__A */
+	0x52, 0x00,		/* CE_REG_FR_TREAL03__A */
+	0x00, 0x00,		/* CE_REG_FR_TIMAG03__A */
+	0x52, 0x00,		/* CE_REG_FR_TREAL04__A */
+	0x00, 0x00,		/* CE_REG_FR_TIMAG04__A */
+	0x52, 0x00,		/* CE_REG_FR_TREAL05__A */
+	0x00, 0x00,		/* CE_REG_FR_TIMAG05__A */
+	0x52, 0x00,		/* CE_REG_FR_TREAL06__A */
+	0x00, 0x00,		/* CE_REG_FR_TIMAG06__A */
+	0x52, 0x00,		/* CE_REG_FR_TREAL07__A */
+	0x00, 0x00,		/* CE_REG_FR_TIMAG07__A */
+	0x52, 0x00,		/* CE_REG_FR_TREAL08__A */
+	0x00, 0x00,		/* CE_REG_FR_TIMAG08__A */
+	0x52, 0x00,		/* CE_REG_FR_TREAL09__A */
+	0x00, 0x00,		/* CE_REG_FR_TIMAG09__A */
+	0x52, 0x00,		/* CE_REG_FR_TREAL10__A */
+	0x00, 0x00,		/* CE_REG_FR_TIMAG10__A */
+	0x52, 0x00,		/* CE_REG_FR_TREAL11__A */
+	0x00, 0x00,		/* CE_REG_FR_TIMAG11__A */
+
+	0x52, 0x00,		/* CE_REG_FR_MID_TAP__A */
+
+	0x0B, 0x00,		/* CE_REG_FR_SQS_G00__A */
+	0x0B, 0x00,		/* CE_REG_FR_SQS_G01__A */
+	0x0B, 0x00,		/* CE_REG_FR_SQS_G02__A */
+	0x0B, 0x00,		/* CE_REG_FR_SQS_G03__A */
+	0x0B, 0x00,		/* CE_REG_FR_SQS_G04__A */
+	0x0B, 0x00,		/* CE_REG_FR_SQS_G05__A */
+	0x0B, 0x00,		/* CE_REG_FR_SQS_G06__A */
+	0x0B, 0x00,		/* CE_REG_FR_SQS_G07__A */
+	0x0B, 0x00,		/* CE_REG_FR_SQS_G08__A */
+	0x0B, 0x00,		/* CE_REG_FR_SQS_G09__A */
+	0x0B, 0x00,		/* CE_REG_FR_SQS_G10__A */
+	0x0B, 0x00,		/* CE_REG_FR_SQS_G11__A */
+	0x0B, 0x00,		/* CE_REG_FR_SQS_G12__A */
+
+	0xFF, 0x01,		/* CE_REG_FR_RIO_G00__A */
+	0x90, 0x01,		/* CE_REG_FR_RIO_G01__A */
+	0x0B, 0x01,		/* CE_REG_FR_RIO_G02__A */
+	0xC8, 0x00,		/* CE_REG_FR_RIO_G03__A */
+	0xA0, 0x00,		/* CE_REG_FR_RIO_G04__A */
+	0x85, 0x00,		/* CE_REG_FR_RIO_G05__A */
+	0x72, 0x00,		/* CE_REG_FR_RIO_G06__A */
+	0x64, 0x00,		/* CE_REG_FR_RIO_G07__A */
+	0x59, 0x00,		/* CE_REG_FR_RIO_G08__A */
+	0x50, 0x00,		/* CE_REG_FR_RIO_G09__A */
+	0x49, 0x00,		/* CE_REG_FR_RIO_G10__A */
+
+	0x10, 0x00,		/* CE_REG_FR_MODE__A     */
+	0x78, 0x00,		/* CE_REG_FR_SQS_TRH__A  */
+	0x00, 0x00,		/* CE_REG_FR_RIO_GAIN__A */
+	0x00, 0x02,		/* CE_REG_FR_BYPASS__A   */
+	0x0D, 0x00,		/* CE_REG_FR_PM_SET__A   */
+	0x07, 0x00,		/* CE_REG_FR_ERR_SH__A   */
+	0x04, 0x00,		/* CE_REG_FR_MAN_SH__A   */
+	0x06, 0x00,		/* CE_REG_FR_TAP_SH__A   */
+
+	END_OF_TABLE
+};
+
+u8 DRXD_InitFEA2_1[] = {
+	WRBLOCK(FE_AD_REG_PD__A, 3),
+	0x00, 0x00,		/* FE_AD_REG_PD__A          */
+	0x01, 0x00,		/* FE_AD_REG_INVEXT__A      */
+	0x00, 0x00,		/* FE_AD_REG_CLKNEG__A      */
+
+	WRBLOCK(FE_AG_REG_DCE_AUR_CNT__A, 2),
+	0x10, 0x00,		/* FE_AG_REG_DCE_AUR_CNT__A */
+	0x10, 0x00,		/* FE_AG_REG_DCE_RUR_CNT__A */
+
+	WRBLOCK(FE_AG_REG_ACE_AUR_CNT__A, 2),
+	0x0E, 0x00,		/* FE_AG_REG_ACE_AUR_CNT__A */
+	0x00, 0x00,		/* FE_AG_REG_ACE_RUR_CNT__A */
+
+	WRBLOCK(FE_AG_REG_EGC_FLA_RGN__A, 5),
+	0x04, 0x00,		/* FE_AG_REG_EGC_FLA_RGN__A */
+	0x1F, 0x00,		/* FE_AG_REG_EGC_SLO_RGN__A */
+	0x00, 0x00,		/* FE_AG_REG_EGC_JMP_PSN__A */
+	0x00, 0x00,		/* FE_AG_REG_EGC_FLA_INC__A */
+	0x00, 0x00,		/* FE_AG_REG_EGC_FLA_DEC__A */
+
+	WRBLOCK(FE_AG_REG_GC1_AGC_MAX__A, 2),
+	0xFF, 0x01,		/* FE_AG_REG_GC1_AGC_MAX__A */
+	0x00, 0xFE,		/* FE_AG_REG_GC1_AGC_MIN__A */
+
+	WRBLOCK(FE_AG_REG_IND_WIN__A, 29),
+	0x00, 0x00,		/* FE_AG_REG_IND_WIN__A     */
+	0x05, 0x00,		/* FE_AG_REG_IND_THD_LOL__A */
+	0x0F, 0x00,		/* FE_AG_REG_IND_THD_HIL__A */
+	0x00, 0x00,		/* FE_AG_REG_IND_DEL__A     don't care */
+	0x1E, 0x00,		/* FE_AG_REG_IND_PD1_WRI__A */
+	0x0C, 0x00,		/* FE_AG_REG_PDA_AUR_CNT__A */
+	0x00, 0x00,		/* FE_AG_REG_PDA_RUR_CNT__A */
+	0x00, 0x00,		/* FE_AG_REG_PDA_AVE_DAT__A don't care  */
+	0x00, 0x00,		/* FE_AG_REG_PDC_RUR_CNT__A */
+	0x01, 0x00,		/* FE_AG_REG_PDC_SET_LVL__A */
+	0x02, 0x00,		/* FE_AG_REG_PDC_FLA_RGN__A */
+	0x00, 0x00,		/* FE_AG_REG_PDC_JMP_PSN__A don't care  */
+	0xFF, 0xFF,		/* FE_AG_REG_PDC_FLA_STP__A */
+	0xFF, 0xFF,		/* FE_AG_REG_PDC_SLO_STP__A */
+	0x00, 0x1F,		/* FE_AG_REG_PDC_PD2_WRI__A don't care  */
+	0x00, 0x00,		/* FE_AG_REG_PDC_MAP_DAT__A don't care  */
+	0x02, 0x00,		/* FE_AG_REG_PDC_MAX__A     */
+	0x0C, 0x00,		/* FE_AG_REG_TGA_AUR_CNT__A */
+	0x00, 0x00,		/* FE_AG_REG_TGA_RUR_CNT__A */
+	0x00, 0x00,		/* FE_AG_REG_TGA_AVE_DAT__A don't care  */
+	0x00, 0x00,		/* FE_AG_REG_TGC_RUR_CNT__A */
+	0x22, 0x00,		/* FE_AG_REG_TGC_SET_LVL__A */
+	0x15, 0x00,		/* FE_AG_REG_TGC_FLA_RGN__A */
+	0x00, 0x00,		/* FE_AG_REG_TGC_JMP_PSN__A don't care  */
+	0x01, 0x00,		/* FE_AG_REG_TGC_FLA_STP__A */
+	0x0A, 0x00,		/* FE_AG_REG_TGC_SLO_STP__A */
+	0x00, 0x00,		/* FE_AG_REG_TGC_MAP_DAT__A don't care  */
+	0x10, 0x00,		/* FE_AG_REG_FGA_AUR_CNT__A */
+	0x10, 0x00,		/* FE_AG_REG_FGA_RUR_CNT__A */
+
+	WRBLOCK(FE_AG_REG_BGC_FGC_WRI__A, 2),
+	0x00, 0x00,		/* FE_AG_REG_BGC_FGC_WRI__A */
+	0x00, 0x00,		/* FE_AG_REG_BGC_CGC_WRI__A */
+
+	WRBLOCK(FE_FD_REG_SCL__A, 3),
+	0x05, 0x00,		/* FE_FD_REG_SCL__A         */
+	0x03, 0x00,		/* FE_FD_REG_MAX_LEV__A     */
+	0x05, 0x00,		/* FE_FD_REG_NR__A          */
+
+	WRBLOCK(FE_CF_REG_SCL__A, 5),
+	0x16, 0x00,		/* FE_CF_REG_SCL__A         */
+	0x04, 0x00,		/* FE_CF_REG_MAX_LEV__A     */
+	0x06, 0x00,		/* FE_CF_REG_NR__A          */
+	0x00, 0x00,		/* FE_CF_REG_IMP_VAL__A     */
+	0x01, 0x00,		/* FE_CF_REG_MEAS_VAL__A    */
+
+	WRBLOCK(FE_CU_REG_FRM_CNT_RST__A, 2),
+	0x00, 0x08,		/* FE_CU_REG_FRM_CNT_RST__A */
+	0x00, 0x00,		/* FE_CU_REG_FRM_CNT_STR__A */
+
+	END_OF_TABLE
+};
+
+   /* with PGA */
+/*   WR16COND( DRXD_WITH_PGA, FE_AG_REG_AG_PGA_MODE__A   , 0x0004), */
+   /* without PGA */
+/*   WR16COND( DRXD_WITHOUT_PGA, FE_AG_REG_AG_PGA_MODE__A   , 0x0001), */
+/*   WR16(FE_AG_REG_AG_AGC_SIO__A,  (extAttr -> FeAgRegAgAgcSio), 0x0000 );*/
+/*   WR16(FE_AG_REG_AG_PWD__A        ,(extAttr -> FeAgRegAgPwd), 0x0000 );*/
+
+u8 DRXD_InitFEA2_2[] = {
+	WR16(FE_AG_REG_CDR_RUR_CNT__A, 0x0010),
+	WR16(FE_AG_REG_FGM_WRI__A, 48),
+	/* Activate measurement, activate scale */
+	WR16(FE_FD_REG_MEAS_VAL__A, 0x0001),
+
+	WR16(FE_CU_REG_COMM_EXEC__A, 0x0001),
+	WR16(FE_CF_REG_COMM_EXEC__A, 0x0001),
+	WR16(FE_IF_REG_COMM_EXEC__A, 0x0001),
+	WR16(FE_FD_REG_COMM_EXEC__A, 0x0001),
+	WR16(FE_FS_REG_COMM_EXEC__A, 0x0001),
+	WR16(FE_AD_REG_COMM_EXEC__A, 0x0001),
+	WR16(FE_AG_REG_COMM_EXEC__A, 0x0001),
+	WR16(FE_AG_REG_AG_MODE_LOP__A, 0x895E),
+
+	END_OF_TABLE
+};
+
+u8 DRXD_InitFEB1_1[] = {
+	WR16(B_FE_AD_REG_PD__A, 0x0000),
+	WR16(B_FE_AD_REG_CLKNEG__A, 0x0000),
+	WR16(B_FE_AG_REG_BGC_FGC_WRI__A, 0x0000),
+	WR16(B_FE_AG_REG_BGC_CGC_WRI__A, 0x0000),
+	WR16(B_FE_AG_REG_AG_MODE_LOP__A, 0x000a),
+	WR16(B_FE_AG_REG_IND_PD1_WRI__A, 35),
+	WR16(B_FE_AG_REG_IND_WIN__A, 0),
+	WR16(B_FE_AG_REG_IND_THD_LOL__A, 8),
+	WR16(B_FE_AG_REG_IND_THD_HIL__A, 8),
+	WR16(B_FE_CF_REG_IMP_VAL__A, 1),
+	WR16(B_FE_AG_REG_EGC_FLA_RGN__A, 7),
+	END_OF_TABLE
+};
+
+	/* with PGA */
+/*      WR16(B_FE_AG_REG_AG_PGA_MODE__A   , 0x0000, 0x0000); */
+       /* without PGA */
+/*      WR16(B_FE_AG_REG_AG_PGA_MODE__A   ,
+	     B_FE_AG_REG_AG_PGA_MODE_PFN_PCN_AFY_REN, 0x0000);*/
+									     /*   WR16(B_FE_AG_REG_AG_AGC_SIO__A,(extAttr -> FeAgRegAgAgcSio), 0x0000 );*//*added HS 23-05-2005 */
+/*   WR16(B_FE_AG_REG_AG_PWD__A    ,(extAttr -> FeAgRegAgPwd), 0x0000 );*/
+
+u8 DRXD_InitFEB1_2[] = {
+	WR16(B_FE_COMM_EXEC__A, 0x0001),
+
+	/* RF-AGC setup */
+	WR16(B_FE_AG_REG_PDA_AUR_CNT__A, 0x0C),
+	WR16(B_FE_AG_REG_PDC_SET_LVL__A, 0x01),
+	WR16(B_FE_AG_REG_PDC_FLA_RGN__A, 0x02),
+	WR16(B_FE_AG_REG_PDC_FLA_STP__A, 0xFFFF),
+	WR16(B_FE_AG_REG_PDC_SLO_STP__A, 0xFFFF),
+	WR16(B_FE_AG_REG_PDC_MAX__A, 0x02),
+	WR16(B_FE_AG_REG_TGA_AUR_CNT__A, 0x0C),
+	WR16(B_FE_AG_REG_TGC_SET_LVL__A, 0x22),
+	WR16(B_FE_AG_REG_TGC_FLA_RGN__A, 0x15),
+	WR16(B_FE_AG_REG_TGC_FLA_STP__A, 0x01),
+	WR16(B_FE_AG_REG_TGC_SLO_STP__A, 0x0A),
+
+	WR16(B_FE_CU_REG_DIV_NFC_CLP__A, 0),
+	WR16(B_FE_CU_REG_CTR_NFC_OCR__A, 25000),
+	WR16(B_FE_CU_REG_CTR_NFC_ICR__A, 1),
+	END_OF_TABLE
+};
+
+u8 DRXD_InitCPA2[] = {
+	WRBLOCK(CP_REG_BR_SPL_OFFSET__A, 2),
+	0x07, 0x00,		/* CP_REG_BR_SPL_OFFSET__A  */
+	0x0A, 0x00,		/* CP_REG_BR_STR_DEL__A     */
+
+	WRBLOCK(CP_REG_RT_ANG_INC0__A, 4),
+	0x00, 0x00,		/* CP_REG_RT_ANG_INC0__A    */
+	0x00, 0x00,		/* CP_REG_RT_ANG_INC1__A    */
+	0x03, 0x00,		/* CP_REG_RT_DETECT_ENA__A  */
+	0x03, 0x00,		/* CP_REG_RT_DETECT_TRH__A  */
+
+	WRBLOCK(CP_REG_AC_NEXP_OFFS__A, 5),
+	0x32, 0x00,		/* CP_REG_AC_NEXP_OFFS__A   */
+	0x62, 0x00,		/* CP_REG_AC_AVER_POW__A    */
+	0x82, 0x00,		/* CP_REG_AC_MAX_POW__A     */
+	0x26, 0x00,		/* CP_REG_AC_WEIGHT_MAN__A  */
+	0x0F, 0x00,		/* CP_REG_AC_WEIGHT_EXP__A  */
+
+	WRBLOCK(CP_REG_AC_AMP_MODE__A, 2),
+	0x02, 0x00,		/* CP_REG_AC_AMP_MODE__A    */
+	0x01, 0x00,		/* CP_REG_AC_AMP_FIX__A     */
+
+	WR16(CP_REG_INTERVAL__A, 0x0005),
+	WR16(CP_REG_RT_EXP_MARG__A, 0x0004),
+	WR16(CP_REG_AC_ANG_MODE__A, 0x0003),
+
+	WR16(CP_REG_COMM_EXEC__A, 0x0001),
+	END_OF_TABLE
+};
+
+u8 DRXD_InitCPB1[] = {
+	WR16(B_CP_REG_BR_SPL_OFFSET__A, 0x0008),
+	WR16(B_CP_COMM_EXEC__A, 0x0001),
+	END_OF_TABLE
+};
+
+u8 DRXD_InitCEA2[] = {
+	WRBLOCK(CE_REG_AVG_POW__A, 4),
+	0x62, 0x00,		/* CE_REG_AVG_POW__A        */
+	0x78, 0x00,		/* CE_REG_MAX_POW__A        */
+	0x62, 0x00,		/* CE_REG_ATT__A            */
+	0x17, 0x00,		/* CE_REG_NRED__A           */
+
+	WRBLOCK(CE_REG_NE_ERR_SELECT__A, 2),
+	0x07, 0x00,		/* CE_REG_NE_ERR_SELECT__A  */
+	0xEB, 0xFF,		/* CE_REG_NE_TD_CAL__A      */
+
+	WRBLOCK(CE_REG_NE_MIXAVG__A, 2),
+	0x06, 0x00,		/* CE_REG_NE_MIXAVG__A      */
+	0x00, 0x00,		/* CE_REG_NE_NUPD_OFS__A    */
+
+	WRBLOCK(CE_REG_PE_NEXP_OFFS__A, 2),
+	0x00, 0x00,		/* CE_REG_PE_NEXP_OFFS__A   */
+	0x00, 0x00,		/* CE_REG_PE_TIMESHIFT__A   */
+
+	WRBLOCK(CE_REG_TP_A0_TAP_NEW__A, 3),
+	0x00, 0x01,		/* CE_REG_TP_A0_TAP_NEW__A       */
+	0x01, 0x00,		/* CE_REG_TP_A0_TAP_NEW_VALID__A */
+	0x0E, 0x00,		/* CE_REG_TP_A0_MU_LMS_STEP__A   */
+
+	WRBLOCK(CE_REG_TP_A1_TAP_NEW__A, 3),
+	0x00, 0x00,		/* CE_REG_TP_A1_TAP_NEW__A        */
+	0x01, 0x00,		/* CE_REG_TP_A1_TAP_NEW_VALID__A  */
+	0x0A, 0x00,		/* CE_REG_TP_A1_MU_LMS_STEP__A    */
+
+	WRBLOCK(CE_REG_FI_SHT_INCR__A, 2),
+	0x12, 0x00,		/* CE_REG_FI_SHT_INCR__A          */
+	0x0C, 0x00,		/* CE_REG_FI_EXP_NORM__A          */
+
+	WRBLOCK(CE_REG_IR_INPUTSEL__A, 3),
+	0x00, 0x00,		/* CE_REG_IR_INPUTSEL__A          */
+	0x00, 0x00,		/* CE_REG_IR_STARTPOS__A          */
+	0xFF, 0x00,		/* CE_REG_IR_NEXP_THRES__A        */
+
+	WR16(CE_REG_TI_NEXP_OFFS__A, 0x0000),
+
+	END_OF_TABLE
+};
+
+u8 DRXD_InitCEB1[] = {
+	WR16(B_CE_REG_TI_PHN_ENABLE__A, 0x0001),
+	WR16(B_CE_REG_FR_PM_SET__A, 0x000D),
+
+	END_OF_TABLE
+};
+
+u8 DRXD_InitEQA2[] = {
+	WRBLOCK(EQ_REG_OT_QNT_THRES0__A, 4),
+	0x1E, 0x00,		/* EQ_REG_OT_QNT_THRES0__A        */
+	0x1F, 0x00,		/* EQ_REG_OT_QNT_THRES1__A        */
+	0x06, 0x00,		/* EQ_REG_OT_CSI_STEP__A          */
+	0x02, 0x00,		/* EQ_REG_OT_CSI_OFFSET__A        */
+
+	WR16(EQ_REG_TD_REQ_SMB_CNT__A, 0x0200),
+	WR16(EQ_REG_IS_CLIP_EXP__A, 0x001F),
+	WR16(EQ_REG_SN_OFFSET__A, (u16) (-7)),
+	WR16(EQ_REG_RC_SEL_CAR__A, 0x0002),
+	WR16(EQ_REG_COMM_EXEC__A, 0x0001),
+	END_OF_TABLE
+};
+
+u8 DRXD_InitEQB1[] = {
+	WR16(B_EQ_REG_COMM_EXEC__A, 0x0001),
+	END_OF_TABLE
+};
+
+u8 DRXD_ResetECRAM[] = {
+	/* Reset packet sync bytes in EC_VD ram */
+	WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (0 * 17), 0x0000),
+	WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (1 * 17), 0x0000),
+	WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (2 * 17), 0x0000),
+	WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (3 * 17), 0x0000),
+	WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (4 * 17), 0x0000),
+	WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (5 * 17), 0x0000),
+	WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (6 * 17), 0x0000),
+	WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (7 * 17), 0x0000),
+	WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (8 * 17), 0x0000),
+	WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (9 * 17), 0x0000),
+	WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (10 * 17), 0x0000),
+
+	/* Reset packet sync bytes in EC_RS ram */
+	WR16(EC_RS_EC_RAM__A, 0x0000),
+	WR16(EC_RS_EC_RAM__A + 204, 0x0000),
+	END_OF_TABLE
+};
+
+u8 DRXD_InitECA2[] = {
+	WRBLOCK(EC_SB_REG_CSI_HI__A, 6),
+	0x1F, 0x00,		/* EC_SB_REG_CSI_HI__A            */
+	0x1E, 0x00,		/* EC_SB_REG_CSI_LO__A            */
+	0x01, 0x00,		/* EC_SB_REG_SMB_TGL__A           */
+	0x7F, 0x00,		/* EC_SB_REG_SNR_HI__A            */
+	0x7F, 0x00,		/* EC_SB_REG_SNR_MID__A           */
+	0x7F, 0x00,		/* EC_SB_REG_SNR_LO__A            */
+
+	WRBLOCK(EC_RS_REG_REQ_PCK_CNT__A, 2),
+	0x00, 0x10,		/* EC_RS_REG_REQ_PCK_CNT__A       */
+	DATA16(EC_RS_REG_VAL_PCK),	/* EC_RS_REG_VAL__A               */
+
+	WRBLOCK(EC_OC_REG_TMD_TOP_MODE__A, 5),
+	0x03, 0x00,		/* EC_OC_REG_TMD_TOP_MODE__A      */
+	0xF4, 0x01,		/* EC_OC_REG_TMD_TOP_CNT__A       */
+	0xC0, 0x03,		/* EC_OC_REG_TMD_HIL_MAR__A       */
+	0x40, 0x00,		/* EC_OC_REG_TMD_LOL_MAR__A       */
+	0x03, 0x00,		/* EC_OC_REG_TMD_CUR_CNT__A       */
+
+	WRBLOCK(EC_OC_REG_AVR_ASH_CNT__A, 2),
+	0x06, 0x00,		/* EC_OC_REG_AVR_ASH_CNT__A       */
+	0x02, 0x00,		/* EC_OC_REG_AVR_BSH_CNT__A       */
+
+	WRBLOCK(EC_OC_REG_RCN_MODE__A, 7),
+	0x07, 0x00,		/* EC_OC_REG_RCN_MODE__A          */
+	0x00, 0x00,		/* EC_OC_REG_RCN_CRA_LOP__A       */
+	0xc0, 0x00,		/* EC_OC_REG_RCN_CRA_HIP__A       */
+	0x00, 0x10,		/* EC_OC_REG_RCN_CST_LOP__A       */
+	0x00, 0x00,		/* EC_OC_REG_RCN_CST_HIP__A       */
+	0xFF, 0x01,		/* EC_OC_REG_RCN_SET_LVL__A       */
+	0x0D, 0x00,		/* EC_OC_REG_RCN_GAI_LVL__A       */
+
+	WRBLOCK(EC_OC_REG_RCN_CLP_LOP__A, 2),
+	0x00, 0x00,		/* EC_OC_REG_RCN_CLP_LOP__A       */
+	0xC0, 0x00,		/* EC_OC_REG_RCN_CLP_HIP__A       */
+
+	WR16(EC_SB_REG_CSI_OFS__A, 0x0001),
+	WR16(EC_VD_REG_FORCE__A, 0x0002),
+	WR16(EC_VD_REG_REQ_SMB_CNT__A, 0x0001),
+	WR16(EC_VD_REG_RLK_ENA__A, 0x0001),
+	WR16(EC_OD_REG_SYNC__A, 0x0664),
+	WR16(EC_OC_REG_OC_MON_SIO__A, 0x0000),
+	WR16(EC_OC_REG_SNC_ISC_LVL__A, 0x0D0C),
+	/* Output zero on monitorbus pads, power saving */
+	WR16(EC_OC_REG_OCR_MON_UOS__A,
+	     (EC_OC_REG_OCR_MON_UOS_DAT_0_ENABLE |
+	      EC_OC_REG_OCR_MON_UOS_DAT_1_ENABLE |
+	      EC_OC_REG_OCR_MON_UOS_DAT_2_ENABLE |
+	      EC_OC_REG_OCR_MON_UOS_DAT_3_ENABLE |
+	      EC_OC_REG_OCR_MON_UOS_DAT_4_ENABLE |
+	      EC_OC_REG_OCR_MON_UOS_DAT_5_ENABLE |
+	      EC_OC_REG_OCR_MON_UOS_DAT_6_ENABLE |
+	      EC_OC_REG_OCR_MON_UOS_DAT_7_ENABLE |
+	      EC_OC_REG_OCR_MON_UOS_DAT_8_ENABLE |
+	      EC_OC_REG_OCR_MON_UOS_DAT_9_ENABLE |
+	      EC_OC_REG_OCR_MON_UOS_VAL_ENABLE |
+	      EC_OC_REG_OCR_MON_UOS_CLK_ENABLE)),
+	WR16(EC_OC_REG_OCR_MON_WRI__A,
+	     EC_OC_REG_OCR_MON_WRI_INIT),
+
+/*   CHK_ERROR(ResetECRAM(demod)); */
+	/* Reset packet sync bytes in EC_VD ram */
+	WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (0 * 17), 0x0000),
+	WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (1 * 17), 0x0000),
+	WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (2 * 17), 0x0000),
+	WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (3 * 17), 0x0000),
+	WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (4 * 17), 0x0000),
+	WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (5 * 17), 0x0000),
+	WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (6 * 17), 0x0000),
+	WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (7 * 17), 0x0000),
+	WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (8 * 17), 0x0000),
+	WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (9 * 17), 0x0000),
+	WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (10 * 17), 0x0000),
+
+	/* Reset packet sync bytes in EC_RS ram */
+	WR16(EC_RS_EC_RAM__A, 0x0000),
+	WR16(EC_RS_EC_RAM__A + 204, 0x0000),
+
+	WR16(EC_SB_REG_COMM_EXEC__A, 0x0001),
+	WR16(EC_VD_REG_COMM_EXEC__A, 0x0001),
+	WR16(EC_OD_REG_COMM_EXEC__A, 0x0001),
+	WR16(EC_RS_REG_COMM_EXEC__A, 0x0001),
+	END_OF_TABLE
+};
+
+u8 DRXD_InitECB1[] = {
+	WR16(B_EC_SB_REG_CSI_OFS0__A, 0x0001),
+	WR16(B_EC_SB_REG_CSI_OFS1__A, 0x0001),
+	WR16(B_EC_SB_REG_CSI_OFS2__A, 0x0001),
+	WR16(B_EC_SB_REG_CSI_LO__A, 0x000c),
+	WR16(B_EC_SB_REG_CSI_HI__A, 0x0018),
+	WR16(B_EC_SB_REG_SNR_HI__A, 0x007f),
+	WR16(B_EC_SB_REG_SNR_MID__A, 0x007f),
+	WR16(B_EC_SB_REG_SNR_LO__A, 0x007f),
+
+	WR16(B_EC_OC_REG_DTO_CLKMODE__A, 0x0002),
+	WR16(B_EC_OC_REG_DTO_PER__A, 0x0006),
+	WR16(B_EC_OC_REG_DTO_BUR__A, 0x0001),
+	WR16(B_EC_OC_REG_RCR_CLKMODE__A, 0x0000),
+	WR16(B_EC_OC_REG_RCN_GAI_LVL__A, 0x000D),
+	WR16(B_EC_OC_REG_OC_MPG_SIO__A, 0x0000),
+
+	/* Needed because shadow registers do not have correct default value */
+	WR16(B_EC_OC_REG_RCN_CST_LOP__A, 0x1000),
+	WR16(B_EC_OC_REG_RCN_CST_HIP__A, 0x0000),
+	WR16(B_EC_OC_REG_RCN_CRA_LOP__A, 0x0000),
+	WR16(B_EC_OC_REG_RCN_CRA_HIP__A, 0x00C0),
+	WR16(B_EC_OC_REG_RCN_CLP_LOP__A, 0x0000),
+	WR16(B_EC_OC_REG_RCN_CLP_HIP__A, 0x00C0),
+	WR16(B_EC_OC_REG_DTO_INC_LOP__A, 0x0000),
+	WR16(B_EC_OC_REG_DTO_INC_HIP__A, 0x00C0),
+
+	WR16(B_EC_OD_REG_SYNC__A, 0x0664),
+	WR16(B_EC_RS_REG_REQ_PCK_CNT__A, 0x1000),
+
+/*   CHK_ERROR(ResetECRAM(demod)); */
+	/* Reset packet sync bytes in EC_VD ram */
+	WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (0 * 17), 0x0000),
+	WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (1 * 17), 0x0000),
+	WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (2 * 17), 0x0000),
+	WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (3 * 17), 0x0000),
+	WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (4 * 17), 0x0000),
+	WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (5 * 17), 0x0000),
+	WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (6 * 17), 0x0000),
+	WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (7 * 17), 0x0000),
+	WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (8 * 17), 0x0000),
+	WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (9 * 17), 0x0000),
+	WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (10 * 17), 0x0000),
+
+	/* Reset packet sync bytes in EC_RS ram */
+	WR16(EC_RS_EC_RAM__A, 0x0000),
+	WR16(EC_RS_EC_RAM__A + 204, 0x0000),
+
+	WR16(B_EC_SB_REG_COMM_EXEC__A, 0x0001),
+	WR16(B_EC_VD_REG_COMM_EXEC__A, 0x0001),
+	WR16(B_EC_OD_REG_COMM_EXEC__A, 0x0001),
+	WR16(B_EC_RS_REG_COMM_EXEC__A, 0x0001),
+	END_OF_TABLE
+};
+
+u8 DRXD_ResetECA2[] = {
+
+	WR16(EC_OC_REG_COMM_EXEC__A, 0x0000),
+	WR16(EC_OD_REG_COMM_EXEC__A, 0x0000),
+
+	WRBLOCK(EC_OC_REG_TMD_TOP_MODE__A, 5),
+	0x03, 0x00,		/* EC_OC_REG_TMD_TOP_MODE__A      */
+	0xF4, 0x01,		/* EC_OC_REG_TMD_TOP_CNT__A       */
+	0xC0, 0x03,		/* EC_OC_REG_TMD_HIL_MAR__A       */
+	0x40, 0x00,		/* EC_OC_REG_TMD_LOL_MAR__A       */
+	0x03, 0x00,		/* EC_OC_REG_TMD_CUR_CNT__A       */
+
+	WRBLOCK(EC_OC_REG_AVR_ASH_CNT__A, 2),
+	0x06, 0x00,		/* EC_OC_REG_AVR_ASH_CNT__A       */
+	0x02, 0x00,		/* EC_OC_REG_AVR_BSH_CNT__A       */
+
+	WRBLOCK(EC_OC_REG_RCN_MODE__A, 7),
+	0x07, 0x00,		/* EC_OC_REG_RCN_MODE__A          */
+	0x00, 0x00,		/* EC_OC_REG_RCN_CRA_LOP__A       */
+	0xc0, 0x00,		/* EC_OC_REG_RCN_CRA_HIP__A       */
+	0x00, 0x10,		/* EC_OC_REG_RCN_CST_LOP__A       */
+	0x00, 0x00,		/* EC_OC_REG_RCN_CST_HIP__A       */
+	0xFF, 0x01,		/* EC_OC_REG_RCN_SET_LVL__A       */
+	0x0D, 0x00,		/* EC_OC_REG_RCN_GAI_LVL__A       */
+
+	WRBLOCK(EC_OC_REG_RCN_CLP_LOP__A, 2),
+	0x00, 0x00,		/* EC_OC_REG_RCN_CLP_LOP__A       */
+	0xC0, 0x00,		/* EC_OC_REG_RCN_CLP_HIP__A       */
+
+	WR16(EC_OD_REG_SYNC__A, 0x0664),
+	WR16(EC_OC_REG_OC_MON_SIO__A, 0x0000),
+	WR16(EC_OC_REG_SNC_ISC_LVL__A, 0x0D0C),
+	/* Output zero on monitorbus pads, power saving */
+	WR16(EC_OC_REG_OCR_MON_UOS__A,
+	     (EC_OC_REG_OCR_MON_UOS_DAT_0_ENABLE |
+	      EC_OC_REG_OCR_MON_UOS_DAT_1_ENABLE |
+	      EC_OC_REG_OCR_MON_UOS_DAT_2_ENABLE |
+	      EC_OC_REG_OCR_MON_UOS_DAT_3_ENABLE |
+	      EC_OC_REG_OCR_MON_UOS_DAT_4_ENABLE |
+	      EC_OC_REG_OCR_MON_UOS_DAT_5_ENABLE |
+	      EC_OC_REG_OCR_MON_UOS_DAT_6_ENABLE |
+	      EC_OC_REG_OCR_MON_UOS_DAT_7_ENABLE |
+	      EC_OC_REG_OCR_MON_UOS_DAT_8_ENABLE |
+	      EC_OC_REG_OCR_MON_UOS_DAT_9_ENABLE |
+	      EC_OC_REG_OCR_MON_UOS_VAL_ENABLE |
+	      EC_OC_REG_OCR_MON_UOS_CLK_ENABLE)),
+	WR16(EC_OC_REG_OCR_MON_WRI__A,
+	     EC_OC_REG_OCR_MON_WRI_INIT),
+
+/*   CHK_ERROR(ResetECRAM(demod)); */
+	/* Reset packet sync bytes in EC_VD ram */
+	WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (0 * 17), 0x0000),
+	WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (1 * 17), 0x0000),
+	WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (2 * 17), 0x0000),
+	WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (3 * 17), 0x0000),
+	WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (4 * 17), 0x0000),
+	WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (5 * 17), 0x0000),
+	WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (6 * 17), 0x0000),
+	WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (7 * 17), 0x0000),
+	WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (8 * 17), 0x0000),
+	WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (9 * 17), 0x0000),
+	WR16(EC_OD_DEINT_RAM__A + 0x3b7 + (10 * 17), 0x0000),
+
+	/* Reset packet sync bytes in EC_RS ram */
+	WR16(EC_RS_EC_RAM__A, 0x0000),
+	WR16(EC_RS_EC_RAM__A + 204, 0x0000),
+
+	WR16(EC_OD_REG_COMM_EXEC__A, 0x0001),
+	END_OF_TABLE
+};
+
+u8 DRXD_InitSC[] = {
+	WR16(SC_COMM_EXEC__A, 0),
+	WR16(SC_COMM_STATE__A, 0),
+
+#ifdef COMPILE_FOR_QT
+	WR16(SC_RA_RAM_BE_OPT_DELAY__A, 0x100),
+#endif
+
+	/* SC is not started, this is done in SetChannels() */
+	END_OF_TABLE
+};
+
+/* Diversity settings */
+
+u8 DRXD_InitDiversityFront[] = {
+	/* Start demod ********* RF in , diversity out **************************** */
+	WR16(B_SC_RA_RAM_CONFIG__A, B_SC_RA_RAM_CONFIG_FR_ENABLE__M |
+	     B_SC_RA_RAM_CONFIG_FREQSCAN__M),
+
+	WR16(B_SC_RA_RAM_LC_ABS_2K__A, 0x7),
+	WR16(B_SC_RA_RAM_LC_ABS_8K__A, 0x7),
+	WR16(B_SC_RA_RAM_IR_COARSE_8K_LENGTH__A, IRLEN_COARSE_8K),
+	WR16(B_SC_RA_RAM_IR_COARSE_8K_FREQINC__A, 1 << (11 - IRLEN_COARSE_8K)),
+	WR16(B_SC_RA_RAM_IR_COARSE_8K_KAISINC__A, 1 << (17 - IRLEN_COARSE_8K)),
+	WR16(B_SC_RA_RAM_IR_FINE_8K_LENGTH__A, IRLEN_FINE_8K),
+	WR16(B_SC_RA_RAM_IR_FINE_8K_FREQINC__A, 1 << (11 - IRLEN_FINE_8K)),
+	WR16(B_SC_RA_RAM_IR_FINE_8K_KAISINC__A, 1 << (17 - IRLEN_FINE_8K)),
+
+	WR16(B_SC_RA_RAM_IR_COARSE_2K_LENGTH__A, IRLEN_COARSE_2K),
+	WR16(B_SC_RA_RAM_IR_COARSE_2K_FREQINC__A, 1 << (11 - IRLEN_COARSE_2K)),
+	WR16(B_SC_RA_RAM_IR_COARSE_2K_KAISINC__A, 1 << (17 - IRLEN_COARSE_2K)),
+	WR16(B_SC_RA_RAM_IR_FINE_2K_LENGTH__A, IRLEN_FINE_2K),
+	WR16(B_SC_RA_RAM_IR_FINE_2K_FREQINC__A, 1 << (11 - IRLEN_FINE_2K)),
+	WR16(B_SC_RA_RAM_IR_FINE_2K_KAISINC__A, 1 << (17 - IRLEN_FINE_2K)),
+
+	WR16(B_LC_RA_RAM_FILTER_CRMM_A__A, 7),
+	WR16(B_LC_RA_RAM_FILTER_CRMM_B__A, 4),
+	WR16(B_LC_RA_RAM_FILTER_SRMM_A__A, 7),
+	WR16(B_LC_RA_RAM_FILTER_SRMM_B__A, 4),
+	WR16(B_LC_RA_RAM_FILTER_SYM_SET__A, 500),
+
+	WR16(B_CC_REG_DIVERSITY__A, 0x0001),
+	WR16(B_EC_OC_REG_OC_MODE_HIP__A, 0x0010),
+	WR16(B_EQ_REG_RC_SEL_CAR__A, B_EQ_REG_RC_SEL_CAR_PASS_B_CE |
+	     B_EQ_REG_RC_SEL_CAR_LOCAL_B_CE | B_EQ_REG_RC_SEL_CAR_MEAS_B_CE),
+
+	/*    0x2a ), *//* CE to PASS mux */
+
+	END_OF_TABLE
+};
+
+u8 DRXD_InitDiversityEnd[] = {
+	/* End demod *********** combining RF in and diversity in, MPEG TS out **** */
+	/* disable near/far; switch on timing slave mode */
+	WR16(B_SC_RA_RAM_CONFIG__A, B_SC_RA_RAM_CONFIG_FR_ENABLE__M |
+	     B_SC_RA_RAM_CONFIG_FREQSCAN__M |
+	     B_SC_RA_RAM_CONFIG_DIV_ECHO_ENABLE__M |
+	     B_SC_RA_RAM_CONFIG_SLAVE__M |
+	     B_SC_RA_RAM_CONFIG_DIV_BLANK_ENABLE__M
+/* MV from CtrlDiversity */
+	    ),
+#ifdef DRXDDIV_SRMM_SLAVING
+	WR16(SC_RA_RAM_LC_ABS_2K__A, 0x3c7),
+	WR16(SC_RA_RAM_LC_ABS_8K__A, 0x3c7),
+#else
+	WR16(SC_RA_RAM_LC_ABS_2K__A, 0x7),
+	WR16(SC_RA_RAM_LC_ABS_8K__A, 0x7),
+#endif
+
+	WR16(B_SC_RA_RAM_IR_COARSE_8K_LENGTH__A, IRLEN_COARSE_8K),
+	WR16(B_SC_RA_RAM_IR_COARSE_8K_FREQINC__A, 1 << (11 - IRLEN_COARSE_8K)),
+	WR16(B_SC_RA_RAM_IR_COARSE_8K_KAISINC__A, 1 << (17 - IRLEN_COARSE_8K)),
+	WR16(B_SC_RA_RAM_IR_FINE_8K_LENGTH__A, IRLEN_FINE_8K),
+	WR16(B_SC_RA_RAM_IR_FINE_8K_FREQINC__A, 1 << (11 - IRLEN_FINE_8K)),
+	WR16(B_SC_RA_RAM_IR_FINE_8K_KAISINC__A, 1 << (17 - IRLEN_FINE_8K)),
+
+	WR16(B_SC_RA_RAM_IR_COARSE_2K_LENGTH__A, IRLEN_COARSE_2K),
+	WR16(B_SC_RA_RAM_IR_COARSE_2K_FREQINC__A, 1 << (11 - IRLEN_COARSE_2K)),
+	WR16(B_SC_RA_RAM_IR_COARSE_2K_KAISINC__A, 1 << (17 - IRLEN_COARSE_2K)),
+	WR16(B_SC_RA_RAM_IR_FINE_2K_LENGTH__A, IRLEN_FINE_2K),
+	WR16(B_SC_RA_RAM_IR_FINE_2K_FREQINC__A, 1 << (11 - IRLEN_FINE_2K)),
+	WR16(B_SC_RA_RAM_IR_FINE_2K_KAISINC__A, 1 << (17 - IRLEN_FINE_2K)),
+
+	WR16(B_LC_RA_RAM_FILTER_CRMM_A__A, 7),
+	WR16(B_LC_RA_RAM_FILTER_CRMM_B__A, 4),
+	WR16(B_LC_RA_RAM_FILTER_SRMM_A__A, 7),
+	WR16(B_LC_RA_RAM_FILTER_SRMM_B__A, 4),
+	WR16(B_LC_RA_RAM_FILTER_SYM_SET__A, 500),
+
+	WR16(B_CC_REG_DIVERSITY__A, 0x0001),
+	END_OF_TABLE
+};
+
+u8 DRXD_DisableDiversity[] = {
+	WR16(B_SC_RA_RAM_LC_ABS_2K__A, B_SC_RA_RAM_LC_ABS_2K__PRE),
+	WR16(B_SC_RA_RAM_LC_ABS_8K__A, B_SC_RA_RAM_LC_ABS_8K__PRE),
+	WR16(B_SC_RA_RAM_IR_COARSE_8K_LENGTH__A,
+	     B_SC_RA_RAM_IR_COARSE_8K_LENGTH__PRE),
+	WR16(B_SC_RA_RAM_IR_COARSE_8K_FREQINC__A,
+	     B_SC_RA_RAM_IR_COARSE_8K_FREQINC__PRE),
+	WR16(B_SC_RA_RAM_IR_COARSE_8K_KAISINC__A,
+	     B_SC_RA_RAM_IR_COARSE_8K_KAISINC__PRE),
+	WR16(B_SC_RA_RAM_IR_FINE_8K_LENGTH__A,
+	     B_SC_RA_RAM_IR_FINE_8K_LENGTH__PRE),
+	WR16(B_SC_RA_RAM_IR_FINE_8K_FREQINC__A,
+	     B_SC_RA_RAM_IR_FINE_8K_FREQINC__PRE),
+	WR16(B_SC_RA_RAM_IR_FINE_8K_KAISINC__A,
+	     B_SC_RA_RAM_IR_FINE_8K_KAISINC__PRE),
+
+	WR16(B_SC_RA_RAM_IR_COARSE_2K_LENGTH__A,
+	     B_SC_RA_RAM_IR_COARSE_2K_LENGTH__PRE),
+	WR16(B_SC_RA_RAM_IR_COARSE_2K_FREQINC__A,
+	     B_SC_RA_RAM_IR_COARSE_2K_FREQINC__PRE),
+	WR16(B_SC_RA_RAM_IR_COARSE_2K_KAISINC__A,
+	     B_SC_RA_RAM_IR_COARSE_2K_KAISINC__PRE),
+	WR16(B_SC_RA_RAM_IR_FINE_2K_LENGTH__A,
+	     B_SC_RA_RAM_IR_FINE_2K_LENGTH__PRE),
+	WR16(B_SC_RA_RAM_IR_FINE_2K_FREQINC__A,
+	     B_SC_RA_RAM_IR_FINE_2K_FREQINC__PRE),
+	WR16(B_SC_RA_RAM_IR_FINE_2K_KAISINC__A,
+	     B_SC_RA_RAM_IR_FINE_2K_KAISINC__PRE),
+
+	WR16(B_LC_RA_RAM_FILTER_CRMM_A__A, B_LC_RA_RAM_FILTER_CRMM_A__PRE),
+	WR16(B_LC_RA_RAM_FILTER_CRMM_B__A, B_LC_RA_RAM_FILTER_CRMM_B__PRE),
+	WR16(B_LC_RA_RAM_FILTER_SRMM_A__A, B_LC_RA_RAM_FILTER_SRMM_A__PRE),
+	WR16(B_LC_RA_RAM_FILTER_SRMM_B__A, B_LC_RA_RAM_FILTER_SRMM_B__PRE),
+	WR16(B_LC_RA_RAM_FILTER_SYM_SET__A, B_LC_RA_RAM_FILTER_SYM_SET__PRE),
+
+	WR16(B_CC_REG_DIVERSITY__A, 0x0000),
+	WR16(B_EQ_REG_RC_SEL_CAR__A, B_EQ_REG_RC_SEL_CAR_INIT),	/* combining disabled */
+
+	END_OF_TABLE
+};
+
+u8 DRXD_StartDiversityFront[] = {
+	/* Start demod, RF in and diversity out, no combining */
+	WR16(B_FE_CF_REG_IMP_VAL__A, 0x0),
+	WR16(B_FE_AD_REG_FDB_IN__A, 0x0),
+	WR16(B_FE_AD_REG_INVEXT__A, 0x0),
+	WR16(B_EQ_REG_COMM_MB__A, 0x12),	/* EQ to MB out */
+	WR16(B_EQ_REG_RC_SEL_CAR__A, B_EQ_REG_RC_SEL_CAR_PASS_B_CE |	/* CE to PASS mux */
+	     B_EQ_REG_RC_SEL_CAR_LOCAL_B_CE | B_EQ_REG_RC_SEL_CAR_MEAS_B_CE),
+
+	WR16(SC_RA_RAM_ECHO_SHIFT_LIM__A, 2),
+
+	END_OF_TABLE
+};
+
+u8 DRXD_StartDiversityEnd[] = {
+	/* End demod, combining RF in and diversity in, MPEG TS out */
+	WR16(B_FE_CF_REG_IMP_VAL__A, 0x0),	/* disable impulse noise cruncher */
+	WR16(B_FE_AD_REG_INVEXT__A, 0x0),	/* clock inversion (for sohard board) */
+	WR16(B_CP_REG_BR_STR_DEL__A, 10),	/* apperently no mb delay matching is best */
+
+	WR16(B_EQ_REG_RC_SEL_CAR__A, B_EQ_REG_RC_SEL_CAR_DIV_ON |	/* org = 0x81 combining enabled */
+	     B_EQ_REG_RC_SEL_CAR_MEAS_A_CC |
+	     B_EQ_REG_RC_SEL_CAR_PASS_A_CC | B_EQ_REG_RC_SEL_CAR_LOCAL_A_CC),
+
+	END_OF_TABLE
+};
+
+u8 DRXD_DiversityDelay8MHZ[] = {
+	WR16(B_SC_RA_RAM_DIVERSITY_DELAY_2K_32__A, 1150 - 50),
+	WR16(B_SC_RA_RAM_DIVERSITY_DELAY_2K_16__A, 1100 - 50),
+	WR16(B_SC_RA_RAM_DIVERSITY_DELAY_2K_8__A, 1000 - 50),
+	WR16(B_SC_RA_RAM_DIVERSITY_DELAY_2K_4__A, 800 - 50),
+	WR16(B_SC_RA_RAM_DIVERSITY_DELAY_8K_32__A, 5420 - 50),
+	WR16(B_SC_RA_RAM_DIVERSITY_DELAY_8K_16__A, 5200 - 50),
+	WR16(B_SC_RA_RAM_DIVERSITY_DELAY_8K_8__A, 4800 - 50),
+	WR16(B_SC_RA_RAM_DIVERSITY_DELAY_8K_4__A, 4000 - 50),
+	END_OF_TABLE
+};
+
+u8 DRXD_DiversityDelay6MHZ[] =	/* also used ok for 7 MHz */
+{
+	WR16(B_SC_RA_RAM_DIVERSITY_DELAY_2K_32__A, 1100 - 50),
+	WR16(B_SC_RA_RAM_DIVERSITY_DELAY_2K_16__A, 1000 - 50),
+	WR16(B_SC_RA_RAM_DIVERSITY_DELAY_2K_8__A, 900 - 50),
+	WR16(B_SC_RA_RAM_DIVERSITY_DELAY_2K_4__A, 600 - 50),
+	WR16(B_SC_RA_RAM_DIVERSITY_DELAY_8K_32__A, 5300 - 50),
+	WR16(B_SC_RA_RAM_DIVERSITY_DELAY_8K_16__A, 5000 - 50),
+	WR16(B_SC_RA_RAM_DIVERSITY_DELAY_8K_8__A, 4500 - 50),
+	WR16(B_SC_RA_RAM_DIVERSITY_DELAY_8K_4__A, 3500 - 50),
+	END_OF_TABLE
+};
diff -druN linux-2.6.39-libre/drivers/media/dvb/frontends/drxd_firm.h linux-3.0-rc7-libre/drivers/media/dvb/frontends/drxd_firm.h
--- linux-2.6.39-libre/drivers/media/dvb/frontends/drxd_firm.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/media/dvb/frontends/drxd_firm.h	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,115 @@
+/*
+ * drxd_firm.h
+ *
+ * Copyright (C) 2006-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 _DRXD_FIRM_H_
+#define _DRXD_FIRM_H_
+
+#include <linux/types.h>
+#include "drxd_map_firm.h"
+
+#define VERSION_MAJOR 1
+#define VERSION_MINOR 4
+#define VERSION_PATCH 23
+
+#define HI_TR_FUNC_ADDR HI_IF_RAM_USR_BEGIN__A
+
+#define DRXD_MAX_RETRIES (1000)
+#define HI_I2C_DELAY     84
+#define HI_I2C_BRIDGE_DELAY   750
+
+#define EQ_TD_TPS_PWR_UNKNOWN          0x00C0	/* Unknown configurations */
+#define EQ_TD_TPS_PWR_QPSK             0x016a
+#define EQ_TD_TPS_PWR_QAM16_ALPHAN     0x0195
+#define EQ_TD_TPS_PWR_QAM16_ALPHA1     0x0195
+#define EQ_TD_TPS_PWR_QAM16_ALPHA2     0x011E
+#define EQ_TD_TPS_PWR_QAM16_ALPHA4     0x01CE
+#define EQ_TD_TPS_PWR_QAM64_ALPHAN     0x019F
+#define EQ_TD_TPS_PWR_QAM64_ALPHA1     0x019F
+#define EQ_TD_TPS_PWR_QAM64_ALPHA2     0x00F8
+#define EQ_TD_TPS_PWR_QAM64_ALPHA4     0x014D
+
+#define DRXD_DEF_AG_PWD_CONSUMER 0x000E
+#define DRXD_DEF_AG_PWD_PRO 0x0000
+#define DRXD_DEF_AG_AGC_SIO 0x0000
+
+#define DRXD_FE_CTRL_MAX 1023
+
+#define DRXD_OSCDEV_DO_SCAN  (16)
+
+#define DRXD_OSCDEV_DONT_SCAN  (0)
+
+#define DRXD_OSCDEV_STEP  (275)
+
+#define DRXD_SCAN_TIMEOUT    (650)
+
+#define DRXD_BANDWIDTH_8MHZ_IN_HZ  (0x8B8249L)
+#define DRXD_BANDWIDTH_7MHZ_IN_HZ  (0x7A1200L)
+#define DRXD_BANDWIDTH_6MHZ_IN_HZ  (0x68A1B6L)
+
+#define IRLEN_COARSE_8K       (10)
+#define IRLEN_FINE_8K         (10)
+#define IRLEN_COARSE_2K       (7)
+#define IRLEN_FINE_2K         (9)
+#define DIFF_INVALID          (511)
+#define DIFF_TARGET           (4)
+#define DIFF_MARGIN           (1)
+
+extern u8 DRXD_InitAtomicRead[];
+extern u8 DRXD_HiI2cPatch_1[];
+extern u8 DRXD_HiI2cPatch_3[];
+
+extern u8 DRXD_InitSC[];
+
+extern u8 DRXD_ResetCEFR[];
+extern u8 DRXD_InitFEA2_1[];
+extern u8 DRXD_InitFEA2_2[];
+extern u8 DRXD_InitCPA2[];
+extern u8 DRXD_InitCEA2[];
+extern u8 DRXD_InitEQA2[];
+extern u8 DRXD_InitECA2[];
+extern u8 DRXD_ResetECA2[];
+extern u8 DRXD_ResetECRAM[];
+
+extern u8 DRXD_A2_microcode[];
+extern u32 DRXD_A2_microcode_length;
+
+extern u8 DRXD_InitFEB1_1[];
+extern u8 DRXD_InitFEB1_2[];
+extern u8 DRXD_InitCPB1[];
+extern u8 DRXD_InitCEB1[];
+extern u8 DRXD_InitEQB1[];
+extern u8 DRXD_InitECB1[];
+
+extern u8 DRXD_InitDiversityFront[];
+extern u8 DRXD_InitDiversityEnd[];
+extern u8 DRXD_DisableDiversity[];
+extern u8 DRXD_StartDiversityFront[];
+extern u8 DRXD_StartDiversityEnd[];
+
+extern u8 DRXD_DiversityDelay8MHZ[];
+extern u8 DRXD_DiversityDelay6MHZ[];
+
+extern u8 DRXD_B1_microcode[];
+extern u32 DRXD_B1_microcode_length;
+
+#endif
diff -druN linux-2.6.39-libre/drivers/media/dvb/frontends/drxd.h linux-3.0-rc7-libre/drivers/media/dvb/frontends/drxd.h
--- linux-2.6.39-libre/drivers/media/dvb/frontends/drxd.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/media/dvb/frontends/drxd.h	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,61 @@
+/*
+ * drxd.h: DRXD DVB-T demodulator 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 _DRXD_H_
+#define _DRXD_H_
+
+#include <linux/types.h>
+#include <linux/i2c.h>
+
+struct drxd_config {
+	u8 index;
+
+	u8 pll_address;
+	u8 pll_type;
+#define DRXD_PLL_NONE     0
+#define DRXD_PLL_DTT7520X 1
+#define DRXD_PLL_MT3X0823 2
+
+	u32 clock;
+	u8 insert_rs_byte;
+
+	u8 demod_address;
+	u8 demoda_address;
+	u8 demod_revision;
+
+	/* If the tuner is not behind an i2c gate, be sure to flip this bit
+	   or else the i2c bus could get wedged */
+	u8 disable_i2c_gate_ctrl;
+
+	u32 IF;
+	int (*pll_set) (void *priv, void *priv_params,
+			u8 pll_addr, u8 demoda_addr, s32 *off);
+	 s16(*osc_deviation) (void *priv, s16 dev, int flag);
+};
+
+extern
+struct dvb_frontend *drxd_attach(const struct drxd_config *config,
+				 void *priv, struct i2c_adapter *i2c,
+				 struct device *dev);
+extern int drxd_config_i2c(struct dvb_frontend *, int);
+#endif
diff -druN linux-2.6.39-libre/drivers/media/dvb/frontends/drxd_hard.c linux-3.0-rc7-libre/drivers/media/dvb/frontends/drxd_hard.c
--- linux-2.6.39-libre/drivers/media/dvb/frontends/drxd_hard.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/media/dvb/frontends/drxd_hard.c	2011-07-21 06:52:11.000000000 -0400
@@ -0,0 +1,3001 @@
+/*
+ * drxd_hard.c: DVB-T Demodulator Micronas DRX3975D-A2,DRX397xD-B1
+ *
+ * Copyright (C) 2003-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
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/firmware.h>
+#include <linux/i2c.h>
+#include <linux/version.h>
+#include <asm/div64.h>
+
+#include "dvb_frontend.h"
+#include "drxd.h"
+#include "drxd_firm.h"
+
+#define DRX_FW_FILENAME_A2 "/*(DEBLOBBED)*/"
+#define DRX_FW_FILENAME_B1 "/*(DEBLOBBED)*/"
+
+#define CHUNK_SIZE 48
+
+#define DRX_I2C_RMW           0x10
+#define DRX_I2C_BROADCAST     0x20
+#define DRX_I2C_CLEARCRC      0x80
+#define DRX_I2C_SINGLE_MASTER 0xC0
+#define DRX_I2C_MODEFLAGS     0xC0
+#define DRX_I2C_FLAGS         0xF0
+
+#ifndef SIZEOF_ARRAY
+#define SIZEOF_ARRAY(array) (sizeof((array))/sizeof((array)[0]))
+#endif
+
+#define DEFAULT_LOCK_TIMEOUT    1100
+
+#define DRX_CHANNEL_AUTO 0
+#define DRX_CHANNEL_HIGH 1
+#define DRX_CHANNEL_LOW  2
+
+#define DRX_LOCK_MPEG  1
+#define DRX_LOCK_FEC   2
+#define DRX_LOCK_DEMOD 4
+
+/****************************************************************************/
+
+enum CSCDState {
+	CSCD_INIT = 0,
+	CSCD_SET,
+	CSCD_SAVED
+};
+
+enum CDrxdState {
+	DRXD_UNINITIALIZED = 0,
+	DRXD_STOPPED,
+	DRXD_STARTED
+};
+
+enum AGC_CTRL_MODE {
+	AGC_CTRL_AUTO = 0,
+	AGC_CTRL_USER,
+	AGC_CTRL_OFF
+};
+
+enum OperationMode {
+	OM_Default,
+	OM_DVBT_Diversity_Front,
+	OM_DVBT_Diversity_End
+};
+
+struct SCfgAgc {
+	enum AGC_CTRL_MODE ctrlMode;
+	u16 outputLevel;	/* range [0, ... , 1023], 1/n of fullscale range */
+	u16 settleLevel;	/* range [0, ... , 1023], 1/n of fullscale range */
+	u16 minOutputLevel;	/* range [0, ... , 1023], 1/n of fullscale range */
+	u16 maxOutputLevel;	/* range [0, ... , 1023], 1/n of fullscale range */
+	u16 speed;		/* range [0, ... , 1023], 1/n of fullscale range */
+
+	u16 R1;
+	u16 R2;
+	u16 R3;
+};
+
+struct SNoiseCal {
+	int cpOpt;
+	u16 cpNexpOfs;
+	u16 tdCal2k;
+	u16 tdCal8k;
+};
+
+enum app_env {
+	APPENV_STATIC = 0,
+	APPENV_PORTABLE = 1,
+	APPENV_MOBILE = 2
+};
+
+enum EIFFilter {
+	IFFILTER_SAW = 0,
+	IFFILTER_DISCRETE = 1
+};
+
+struct drxd_state {
+	struct dvb_frontend frontend;
+	struct dvb_frontend_ops ops;
+	struct dvb_frontend_parameters param;
+
+	const struct firmware *fw;
+	struct device *dev;
+
+	struct i2c_adapter *i2c;
+	void *priv;
+	struct drxd_config config;
+
+	int i2c_access;
+	int init_done;
+	struct mutex mutex;
+
+	u8 chip_adr;
+	u16 hi_cfg_timing_div;
+	u16 hi_cfg_bridge_delay;
+	u16 hi_cfg_wakeup_key;
+	u16 hi_cfg_ctrl;
+
+	u16 intermediate_freq;
+	u16 osc_clock_freq;
+
+	enum CSCDState cscd_state;
+	enum CDrxdState drxd_state;
+
+	u16 sys_clock_freq;
+	s16 osc_clock_deviation;
+	u16 expected_sys_clock_freq;
+
+	u16 insert_rs_byte;
+	u16 enable_parallel;
+
+	int operation_mode;
+
+	struct SCfgAgc if_agc_cfg;
+	struct SCfgAgc rf_agc_cfg;
+
+	struct SNoiseCal noise_cal;
+
+	u32 fe_fs_add_incr;
+	u32 org_fe_fs_add_incr;
+	u16 current_fe_if_incr;
+
+	u16 m_FeAgRegAgPwd;
+	u16 m_FeAgRegAgAgcSio;
+
+	u16 m_EcOcRegOcModeLop;
+	u16 m_EcOcRegSncSncLvl;
+	u8 *m_InitAtomicRead;
+	u8 *m_HiI2cPatch;
+
+	u8 *m_ResetCEFR;
+	u8 *m_InitFE_1;
+	u8 *m_InitFE_2;
+	u8 *m_InitCP;
+	u8 *m_InitCE;
+	u8 *m_InitEQ;
+	u8 *m_InitSC;
+	u8 *m_InitEC;
+	u8 *m_ResetECRAM;
+	u8 *m_InitDiversityFront;
+	u8 *m_InitDiversityEnd;
+	u8 *m_DisableDiversity;
+	u8 *m_StartDiversityFront;
+	u8 *m_StartDiversityEnd;
+
+	u8 *m_DiversityDelay8MHZ;
+	u8 *m_DiversityDelay6MHZ;
+
+	u8 *microcode;
+	u32 microcode_length;
+
+	int type_A;
+	int PGA;
+	int diversity;
+	int tuner_mirrors;
+
+	enum app_env app_env_default;
+	enum app_env app_env_diversity;
+
+};
+
+/****************************************************************************/
+/* I2C **********************************************************************/
+/****************************************************************************/
+
+static int i2c_write(struct i2c_adapter *adap, u8 adr, u8 * data, int len)
+{
+	struct i2c_msg msg = {.addr = adr, .flags = 0, .buf = data, .len = len };
+
+	if (i2c_transfer(adap, &msg, 1) != 1)
+		return -1;
+	return 0;
+}
+
+static int i2c_read(struct i2c_adapter *adap,
+		    u8 adr, u8 *msg, int len, u8 *answ, int alen)
+{
+	struct i2c_msg msgs[2] = {
+		{
+			.addr = adr, .flags = 0,
+			.buf = msg, .len = len
+		}, {
+			.addr = adr, .flags = I2C_M_RD,
+			.buf = answ, .len = alen
+		}
+	};
+	if (i2c_transfer(adap, msgs, 2) != 2)
+		return -1;
+	return 0;
+}
+
+inline u32 MulDiv32(u32 a, u32 b, u32 c)
+{
+	u64 tmp64;
+
+	tmp64 = (u64)a * (u64)b;
+	do_div(tmp64, c);
+
+	return (u32) tmp64;
+}
+
+static int Read16(struct drxd_state *state, u32 reg, u16 *data, u8 flags)
+{
+	u8 adr = state->config.demod_address;
+	u8 mm1[4] = { reg & 0xff, (reg >> 16) & 0xff,
+		flags | ((reg >> 24) & 0xff), (reg >> 8) & 0xff
+	};
+	u8 mm2[2];
+	if (i2c_read(state->i2c, adr, mm1, 4, mm2, 2) < 0)
+		return -1;
+	if (data)
+		*data = mm2[0] | (mm2[1] << 8);
+	return mm2[0] | (mm2[1] << 8);
+}
+
+static int Read32(struct drxd_state *state, u32 reg, u32 *data, u8 flags)
+{
+	u8 adr = state->config.demod_address;
+	u8 mm1[4] = { reg & 0xff, (reg >> 16) & 0xff,
+		flags | ((reg >> 24) & 0xff), (reg >> 8) & 0xff
+	};
+	u8 mm2[4];
+
+	if (i2c_read(state->i2c, adr, mm1, 4, mm2, 4) < 0)
+		return -1;
+	if (data)
+		*data =
+		    mm2[0] | (mm2[1] << 8) | (mm2[2] << 16) | (mm2[3] << 24);
+	return 0;
+}
+
+static int Write16(struct drxd_state *state, u32 reg, u16 data, u8 flags)
+{
+	u8 adr = state->config.demod_address;
+	u8 mm[6] = { reg & 0xff, (reg >> 16) & 0xff,
+		flags | ((reg >> 24) & 0xff), (reg >> 8) & 0xff,
+		data & 0xff, (data >> 8) & 0xff
+	};
+
+	if (i2c_write(state->i2c, adr, mm, 6) < 0)
+		return -1;
+	return 0;
+}
+
+static int Write32(struct drxd_state *state, u32 reg, u32 data, u8 flags)
+{
+	u8 adr = state->config.demod_address;
+	u8 mm[8] = { reg & 0xff, (reg >> 16) & 0xff,
+		flags | ((reg >> 24) & 0xff), (reg >> 8) & 0xff,
+		data & 0xff, (data >> 8) & 0xff,
+		(data >> 16) & 0xff, (data >> 24) & 0xff
+	};
+
+	if (i2c_write(state->i2c, adr, mm, 8) < 0)
+		return -1;
+	return 0;
+}
+
+static int write_chunk(struct drxd_state *state,
+		       u32 reg, u8 *data, u32 len, u8 flags)
+{
+	u8 adr = state->config.demod_address;
+	u8 mm[CHUNK_SIZE + 4] = { reg & 0xff, (reg >> 16) & 0xff,
+		flags | ((reg >> 24) & 0xff), (reg >> 8) & 0xff
+	};
+	int i;
+
+	for (i = 0; i < len; i++)
+		mm[4 + i] = data[i];
+	if (i2c_write(state->i2c, adr, mm, 4 + len) < 0) {
+		printk(KERN_ERR "error in write_chunk\n");
+		return -1;
+	}
+	return 0;
+}
+
+static int WriteBlock(struct drxd_state *state,
+		      u32 Address, u16 BlockSize, u8 *pBlock, u8 Flags)
+{
+	while (BlockSize > 0) {
+		u16 Chunk = BlockSize > CHUNK_SIZE ? CHUNK_SIZE : BlockSize;
+
+		if (write_chunk(state, Address, pBlock, Chunk, Flags) < 0)
+			return -1;
+		pBlock += Chunk;
+		Address += (Chunk >> 1);
+		BlockSize -= Chunk;
+	}
+	return 0;
+}
+
+static int WriteTable(struct drxd_state *state, u8 * pTable)
+{
+	int status = 0;
+
+	if (pTable == NULL)
+		return 0;
+
+	while (!status) {
+		u16 Length;
+		u32 Address = pTable[0] | (pTable[1] << 8) |
+		    (pTable[2] << 16) | (pTable[3] << 24);
+
+		if (Address == 0xFFFFFFFF)
+			break;
+		pTable += sizeof(u32);
+
+		Length = pTable[0] | (pTable[1] << 8);
+		pTable += sizeof(u16);
+		if (!Length)
+			break;
+		status = WriteBlock(state, Address, Length * 2, pTable, 0);
+		pTable += (Length * 2);
+	}
+	return status;
+}
+
+/****************************************************************************/
+/****************************************************************************/
+/****************************************************************************/
+
+static int ResetCEFR(struct drxd_state *state)
+{
+	return WriteTable(state, state->m_ResetCEFR);
+}
+
+static int InitCP(struct drxd_state *state)
+{
+	return WriteTable(state, state->m_InitCP);
+}
+
+static int InitCE(struct drxd_state *state)
+{
+	int status;
+	enum app_env AppEnv = state->app_env_default;
+
+	do {
+		status = WriteTable(state, state->m_InitCE);
+		if (status < 0)
+			break;
+
+		if (state->operation_mode == OM_DVBT_Diversity_Front ||
+		    state->operation_mode == OM_DVBT_Diversity_End) {
+			AppEnv = state->app_env_diversity;
+		}
+		if (AppEnv == APPENV_STATIC) {
+			status = Write16(state, CE_REG_TAPSET__A, 0x0000, 0);
+			if (status < 0)
+				break;
+		} else if (AppEnv == APPENV_PORTABLE) {
+			status = Write16(state, CE_REG_TAPSET__A, 0x0001, 0);
+			if (status < 0)
+				break;
+		} else if (AppEnv == APPENV_MOBILE && state->type_A) {
+			status = Write16(state, CE_REG_TAPSET__A, 0x0002, 0);
+			if (status < 0)
+				break;
+		} else if (AppEnv == APPENV_MOBILE && !state->type_A) {
+			status = Write16(state, CE_REG_TAPSET__A, 0x0006, 0);
+			if (status < 0)
+				break;
+		}
+
+		/* start ce */
+		status = Write16(state, B_CE_REG_COMM_EXEC__A, 0x0001, 0);
+		if (status < 0)
+			break;
+	} while (0);
+	return status;
+}
+
+static int StopOC(struct drxd_state *state)
+{
+	int status = 0;
+	u16 ocSyncLvl = 0;
+	u16 ocModeLop = state->m_EcOcRegOcModeLop;
+	u16 dtoIncLop = 0;
+	u16 dtoIncHip = 0;
+
+	do {
+		/* Store output configuration */
+		status = Read16(state, EC_OC_REG_SNC_ISC_LVL__A, &ocSyncLvl, 0);
+		if (status < 0)
+			break;
+		/* CHK_ERROR(Read16(EC_OC_REG_OC_MODE_LOP__A, &ocModeLop)); */
+		state->m_EcOcRegSncSncLvl = ocSyncLvl;
+		/* m_EcOcRegOcModeLop = ocModeLop; */
+
+		/* Flush FIFO (byte-boundary) at fixed rate */
+		status = Read16(state, EC_OC_REG_RCN_MAP_LOP__A, &dtoIncLop, 0);
+		if (status < 0)
+			break;
+		status = Read16(state, EC_OC_REG_RCN_MAP_HIP__A, &dtoIncHip, 0);
+		if (status < 0)
+			break;
+		status = Write16(state, EC_OC_REG_DTO_INC_LOP__A, dtoIncLop, 0);
+		if (status < 0)
+			break;
+		status = Write16(state, EC_OC_REG_DTO_INC_HIP__A, dtoIncHip, 0);
+		if (status < 0)
+			break;
+		ocModeLop &= ~(EC_OC_REG_OC_MODE_LOP_DTO_CTR_SRC__M);
+		ocModeLop |= EC_OC_REG_OC_MODE_LOP_DTO_CTR_SRC_STATIC;
+		status = Write16(state, EC_OC_REG_OC_MODE_LOP__A, ocModeLop, 0);
+		if (status < 0)
+			break;
+		status = Write16(state, EC_OC_REG_COMM_EXEC__A, EC_OC_REG_COMM_EXEC_CTL_HOLD, 0);
+		if (status < 0)
+			break;
+
+		msleep(1);
+		/* Output pins to '0' */
+		status = Write16(state, EC_OC_REG_OCR_MPG_UOS__A, EC_OC_REG_OCR_MPG_UOS__M, 0);
+		if (status < 0)
+			break;
+
+		/* Force the OC out of sync */
+		ocSyncLvl &= ~(EC_OC_REG_SNC_ISC_LVL_OSC__M);
+		status = Write16(state, EC_OC_REG_SNC_ISC_LVL__A, ocSyncLvl, 0);
+		if (status < 0)
+			break;
+		ocModeLop &= ~(EC_OC_REG_OC_MODE_LOP_PAR_ENA__M);
+		ocModeLop |= EC_OC_REG_OC_MODE_LOP_PAR_ENA_ENABLE;
+		ocModeLop |= 0x2;	/* Magically-out-of-sync */
+		status = Write16(state, EC_OC_REG_OC_MODE_LOP__A, ocModeLop, 0);
+		if (status < 0)
+			break;
+		status = Write16(state, EC_OC_REG_COMM_INT_STA__A, 0x0, 0);
+		if (status < 0)
+			break;
+		status = Write16(state, EC_OC_REG_COMM_EXEC__A, EC_OC_REG_COMM_EXEC_CTL_ACTIVE, 0);
+		if (status < 0)
+			break;
+	} while (0);
+
+	return status;
+}
+
+static int StartOC(struct drxd_state *state)
+{
+	int status = 0;
+
+	do {
+		/* Stop OC */
+		status = Write16(state, EC_OC_REG_COMM_EXEC__A, EC_OC_REG_COMM_EXEC_CTL_HOLD, 0);
+		if (status < 0)
+			break;
+
+		/* Restore output configuration */
+		status = Write16(state, EC_OC_REG_SNC_ISC_LVL__A, state->m_EcOcRegSncSncLvl, 0);
+		if (status < 0)
+			break;
+		status = Write16(state, EC_OC_REG_OC_MODE_LOP__A, state->m_EcOcRegOcModeLop, 0);
+		if (status < 0)
+			break;
+
+		/* Output pins active again */
+		status = Write16(state, EC_OC_REG_OCR_MPG_UOS__A, EC_OC_REG_OCR_MPG_UOS_INIT, 0);
+		if (status < 0)
+			break;
+
+		/* Start OC */
+		status = Write16(state, EC_OC_REG_COMM_EXEC__A, EC_OC_REG_COMM_EXEC_CTL_ACTIVE, 0);
+		if (status < 0)
+			break;
+	} while (0);
+	return status;
+}
+
+static int InitEQ(struct drxd_state *state)
+{
+	return WriteTable(state, state->m_InitEQ);
+}
+
+static int InitEC(struct drxd_state *state)
+{
+	return WriteTable(state, state->m_InitEC);
+}
+
+static int InitSC(struct drxd_state *state)
+{
+	return WriteTable(state, state->m_InitSC);
+}
+
+static int InitAtomicRead(struct drxd_state *state)
+{
+	return WriteTable(state, state->m_InitAtomicRead);
+}
+
+static int CorrectSysClockDeviation(struct drxd_state *state);
+
+static int DRX_GetLockStatus(struct drxd_state *state, u32 * pLockStatus)
+{
+	u16 ScRaRamLock = 0;
+	const u16 mpeg_lock_mask = (SC_RA_RAM_LOCK_MPEG__M |
+				    SC_RA_RAM_LOCK_FEC__M |
+				    SC_RA_RAM_LOCK_DEMOD__M);
+	const u16 fec_lock_mask = (SC_RA_RAM_LOCK_FEC__M |
+				   SC_RA_RAM_LOCK_DEMOD__M);
+	const u16 demod_lock_mask = SC_RA_RAM_LOCK_DEMOD__M;
+
+	int status;
+
+	*pLockStatus = 0;
+
+	status = Read16(state, SC_RA_RAM_LOCK__A, &ScRaRamLock, 0x0000);
+	if (status < 0) {
+		printk(KERN_ERR "Can't read SC_RA_RAM_LOCK__A status = %08x\n", status);
+		return status;
+	}
+
+	if (state->drxd_state != DRXD_STARTED)
+		return 0;
+
+	if ((ScRaRamLock & mpeg_lock_mask) == mpeg_lock_mask) {
+		*pLockStatus |= DRX_LOCK_MPEG;
+		CorrectSysClockDeviation(state);
+	}
+
+	if ((ScRaRamLock & fec_lock_mask) == fec_lock_mask)
+		*pLockStatus |= DRX_LOCK_FEC;
+
+	if ((ScRaRamLock & demod_lock_mask) == demod_lock_mask)
+		*pLockStatus |= DRX_LOCK_DEMOD;
+	return 0;
+}
+
+/****************************************************************************/
+
+static int SetCfgIfAgc(struct drxd_state *state, struct SCfgAgc *cfg)
+{
+	int status;
+
+	if (cfg->outputLevel > DRXD_FE_CTRL_MAX)
+		return -1;
+
+	if (cfg->ctrlMode == AGC_CTRL_USER) {
+		do {
+			u16 FeAgRegPm1AgcWri;
+			u16 FeAgRegAgModeLop;
+
+			status = Read16(state, FE_AG_REG_AG_MODE_LOP__A, &FeAgRegAgModeLop, 0);
+			if (status < 0)
+				break;
+			FeAgRegAgModeLop &= (~FE_AG_REG_AG_MODE_LOP_MODE_4__M);
+			FeAgRegAgModeLop |= FE_AG_REG_AG_MODE_LOP_MODE_4_STATIC;
+			status = Write16(state, FE_AG_REG_AG_MODE_LOP__A, FeAgRegAgModeLop, 0);
+			if (status < 0)
+				break;
+
+			FeAgRegPm1AgcWri = (u16) (cfg->outputLevel &
+						  FE_AG_REG_PM1_AGC_WRI__M);
+			status = Write16(state, FE_AG_REG_PM1_AGC_WRI__A, FeAgRegPm1AgcWri, 0);
+			if (status < 0)
+				break;
+		} while (0);
+	} else if (cfg->ctrlMode == AGC_CTRL_AUTO) {
+		if (((cfg->maxOutputLevel) < (cfg->minOutputLevel)) ||
+		    ((cfg->maxOutputLevel) > DRXD_FE_CTRL_MAX) ||
+		    ((cfg->speed) > DRXD_FE_CTRL_MAX) ||
+		    ((cfg->settleLevel) > DRXD_FE_CTRL_MAX)
+		    )
+			return -1;
+		do {
+			u16 FeAgRegAgModeLop;
+			u16 FeAgRegEgcSetLvl;
+			u16 slope, offset;
+
+			/* == Mode == */
+
+			status = Read16(state, FE_AG_REG_AG_MODE_LOP__A, &FeAgRegAgModeLop, 0);
+			if (status < 0)
+				break;
+			FeAgRegAgModeLop &= (~FE_AG_REG_AG_MODE_LOP_MODE_4__M);
+			FeAgRegAgModeLop |=
+			    FE_AG_REG_AG_MODE_LOP_MODE_4_DYNAMIC;
+			status = Write16(state, FE_AG_REG_AG_MODE_LOP__A, FeAgRegAgModeLop, 0);
+			if (status < 0)
+				break;
+
+			/* == Settle level == */
+
+			FeAgRegEgcSetLvl = (u16) ((cfg->settleLevel >> 1) &
+						  FE_AG_REG_EGC_SET_LVL__M);
+			status = Write16(state, FE_AG_REG_EGC_SET_LVL__A, FeAgRegEgcSetLvl, 0);
+			if (status < 0)
+				break;
+
+			/* == Min/Max == */
+
+			slope = (u16) ((cfg->maxOutputLevel -
+					cfg->minOutputLevel) / 2);
+			offset = (u16) ((cfg->maxOutputLevel +
+					 cfg->minOutputLevel) / 2 - 511);
+
+			status = Write16(state, FE_AG_REG_GC1_AGC_RIC__A, slope, 0);
+			if (status < 0)
+				break;
+			status = Write16(state, FE_AG_REG_GC1_AGC_OFF__A, offset, 0);
+			if (status < 0)
+				break;
+
+			/* == Speed == */
+			{
+				const u16 maxRur = 8;
+				const u16 slowIncrDecLUT[] = { 3, 4, 4, 5, 6 };
+				const u16 fastIncrDecLUT[] = { 14, 15, 15, 16,
+					17, 18, 18, 19,
+					20, 21, 22, 23,
+					24, 26, 27, 28,
+					29, 31
+				};
+
+				u16 fineSteps = (DRXD_FE_CTRL_MAX + 1) /
+				    (maxRur + 1);
+				u16 fineSpeed = (u16) (cfg->speed -
+						       ((cfg->speed /
+							 fineSteps) *
+							fineSteps));
+				u16 invRurCount = (u16) (cfg->speed /
+							 fineSteps);
+				u16 rurCount;
+				if (invRurCount > maxRur) {
+					rurCount = 0;
+					fineSpeed += fineSteps;
+				} else {
+					rurCount = maxRur - invRurCount;
+				}
+
+				/*
+				   fastInc = default *
+				   (2^(fineSpeed/fineSteps))
+				   => range[default...2*default>
+				   slowInc = default *
+				   (2^(fineSpeed/fineSteps))
+				 */
+				{
+					u16 fastIncrDec =
+					    fastIncrDecLUT[fineSpeed /
+							   ((fineSteps /
+							     (14 + 1)) + 1)];
+					u16 slowIncrDec =
+					    slowIncrDecLUT[fineSpeed /
+							   (fineSteps /
+							    (3 + 1))];
+
+					status = Write16(state, FE_AG_REG_EGC_RUR_CNT__A, rurCount, 0);
+					if (status < 0)
+						break;
+					status = Write16(state, FE_AG_REG_EGC_FAS_INC__A, fastIncrDec, 0);
+					if (status < 0)
+						break;
+					status = Write16(state, FE_AG_REG_EGC_FAS_DEC__A, fastIncrDec, 0);
+					if (status < 0)
+						break;
+					status = Write16(state, FE_AG_REG_EGC_SLO_INC__A, slowIncrDec, 0);
+					if (status < 0)
+						break;
+					status = Write16(state, FE_AG_REG_EGC_SLO_DEC__A, slowIncrDec, 0);
+					if (status < 0)
+						break;
+				}
+			}
+		} while (0);
+
+	} else {
+		/* No OFF mode for IF control */
+		return -1;
+	}
+	return status;
+}
+
+static int SetCfgRfAgc(struct drxd_state *state, struct SCfgAgc *cfg)
+{
+	int status = 0;
+
+	if (cfg->outputLevel > DRXD_FE_CTRL_MAX)
+		return -1;
+
+	if (cfg->ctrlMode == AGC_CTRL_USER) {
+		do {
+			u16 AgModeLop = 0;
+			u16 level = (cfg->outputLevel);
+
+			if (level == DRXD_FE_CTRL_MAX)
+				level++;
+
+			status = Write16(state, FE_AG_REG_PM2_AGC_WRI__A, level, 0x0000);
+			if (status < 0)
+				break;
+
+			/*==== Mode ====*/
+
+			/* Powerdown PD2, WRI source */
+			state->m_FeAgRegAgPwd &= ~(FE_AG_REG_AG_PWD_PWD_PD2__M);
+			state->m_FeAgRegAgPwd |=
+			    FE_AG_REG_AG_PWD_PWD_PD2_DISABLE;
+			status = Write16(state, FE_AG_REG_AG_PWD__A, state->m_FeAgRegAgPwd, 0x0000);
+			if (status < 0)
+				break;
+
+			status = Read16(state, FE_AG_REG_AG_MODE_LOP__A, &AgModeLop, 0x0000);
+			if (status < 0)
+				break;
+			AgModeLop &= (~(FE_AG_REG_AG_MODE_LOP_MODE_5__M |
+					FE_AG_REG_AG_MODE_LOP_MODE_E__M));
+			AgModeLop |= (FE_AG_REG_AG_MODE_LOP_MODE_5_STATIC |
+				      FE_AG_REG_AG_MODE_LOP_MODE_E_STATIC);
+			status = Write16(state, FE_AG_REG_AG_MODE_LOP__A, AgModeLop, 0x0000);
+			if (status < 0)
+				break;
+
+			/* enable AGC2 pin */
+			{
+				u16 FeAgRegAgAgcSio = 0;
+				status = Read16(state, FE_AG_REG_AG_AGC_SIO__A, &FeAgRegAgAgcSio, 0x0000);
+				if (status < 0)
+					break;
+				FeAgRegAgAgcSio &=
+				    ~(FE_AG_REG_AG_AGC_SIO_AGC_SIO_2__M);
+				FeAgRegAgAgcSio |=
+				    FE_AG_REG_AG_AGC_SIO_AGC_SIO_2_OUTPUT;
+				status = Write16(state, FE_AG_REG_AG_AGC_SIO__A, FeAgRegAgAgcSio, 0x0000);
+				if (status < 0)
+					break;
+			}
+
+		} while (0);
+	} else if (cfg->ctrlMode == AGC_CTRL_AUTO) {
+		u16 AgModeLop = 0;
+
+		do {
+			u16 level;
+			/* Automatic control */
+			/* Powerup PD2, AGC2 as output, TGC source */
+			(state->m_FeAgRegAgPwd) &=
+			    ~(FE_AG_REG_AG_PWD_PWD_PD2__M);
+			(state->m_FeAgRegAgPwd) |=
+			    FE_AG_REG_AG_PWD_PWD_PD2_DISABLE;
+			status = Write16(state, FE_AG_REG_AG_PWD__A, (state->m_FeAgRegAgPwd), 0x0000);
+			if (status < 0)
+				break;
+
+			status = Read16(state, FE_AG_REG_AG_MODE_LOP__A, &AgModeLop, 0x0000);
+			if (status < 0)
+				break;
+			AgModeLop &= (~(FE_AG_REG_AG_MODE_LOP_MODE_5__M |
+					FE_AG_REG_AG_MODE_LOP_MODE_E__M));
+			AgModeLop |= (FE_AG_REG_AG_MODE_LOP_MODE_5_STATIC |
+				      FE_AG_REG_AG_MODE_LOP_MODE_E_DYNAMIC);
+			status = Write16(state, FE_AG_REG_AG_MODE_LOP__A, AgModeLop, 0x0000);
+			if (status < 0)
+				break;
+			/* Settle level */
+			level = (((cfg->settleLevel) >> 4) &
+				 FE_AG_REG_TGC_SET_LVL__M);
+			status = Write16(state, FE_AG_REG_TGC_SET_LVL__A, level, 0x0000);
+			if (status < 0)
+				break;
+
+			/* Min/max: don't care */
+
+			/* Speed: TODO */
+
+			/* enable AGC2 pin */
+			{
+				u16 FeAgRegAgAgcSio = 0;
+				status = Read16(state, FE_AG_REG_AG_AGC_SIO__A, &FeAgRegAgAgcSio, 0x0000);
+				if (status < 0)
+					break;
+				FeAgRegAgAgcSio &=
+				    ~(FE_AG_REG_AG_AGC_SIO_AGC_SIO_2__M);
+				FeAgRegAgAgcSio |=
+				    FE_AG_REG_AG_AGC_SIO_AGC_SIO_2_OUTPUT;
+				status = Write16(state, FE_AG_REG_AG_AGC_SIO__A, FeAgRegAgAgcSio, 0x0000);
+				if (status < 0)
+					break;
+			}
+
+		} while (0);
+	} else {
+		u16 AgModeLop = 0;
+
+		do {
+			/* No RF AGC control */
+			/* Powerdown PD2, AGC2 as output, WRI source */
+			(state->m_FeAgRegAgPwd) &=
+			    ~(FE_AG_REG_AG_PWD_PWD_PD2__M);
+			(state->m_FeAgRegAgPwd) |=
+			    FE_AG_REG_AG_PWD_PWD_PD2_ENABLE;
+			status = Write16(state, FE_AG_REG_AG_PWD__A, (state->m_FeAgRegAgPwd), 0x0000);
+			if (status < 0)
+				break;
+
+			status = Read16(state, FE_AG_REG_AG_MODE_LOP__A, &AgModeLop, 0x0000);
+			if (status < 0)
+				break;
+			AgModeLop &= (~(FE_AG_REG_AG_MODE_LOP_MODE_5__M |
+					FE_AG_REG_AG_MODE_LOP_MODE_E__M));
+			AgModeLop |= (FE_AG_REG_AG_MODE_LOP_MODE_5_STATIC |
+				      FE_AG_REG_AG_MODE_LOP_MODE_E_STATIC);
+			status = Write16(state, FE_AG_REG_AG_MODE_LOP__A, AgModeLop, 0x0000);
+			if (status < 0)
+				break;
+
+			/* set FeAgRegAgAgcSio AGC2 (RF) as input */
+			{
+				u16 FeAgRegAgAgcSio = 0;
+				status = Read16(state, FE_AG_REG_AG_AGC_SIO__A, &FeAgRegAgAgcSio, 0x0000);
+				if (status < 0)
+					break;
+				FeAgRegAgAgcSio &=
+				    ~(FE_AG_REG_AG_AGC_SIO_AGC_SIO_2__M);
+				FeAgRegAgAgcSio |=
+				    FE_AG_REG_AG_AGC_SIO_AGC_SIO_2_INPUT;
+				status = Write16(state, FE_AG_REG_AG_AGC_SIO__A, FeAgRegAgAgcSio, 0x0000);
+				if (status < 0)
+					break;
+			}
+		} while (0);
+	}
+	return status;
+}
+
+static int ReadIFAgc(struct drxd_state *state, u32 * pValue)
+{
+	int status = 0;
+
+	*pValue = 0;
+	if (state->if_agc_cfg.ctrlMode != AGC_CTRL_OFF) {
+		u16 Value;
+		status = Read16(state, FE_AG_REG_GC1_AGC_DAT__A, &Value, 0);
+		Value &= FE_AG_REG_GC1_AGC_DAT__M;
+		if (status >= 0) {
+			/*           3.3V
+			   |
+			   R1
+			   |
+			   Vin - R3 - * -- Vout
+			   |
+			   R2
+			   |
+			   GND
+			 */
+			u32 R1 = state->if_agc_cfg.R1;
+			u32 R2 = state->if_agc_cfg.R2;
+			u32 R3 = state->if_agc_cfg.R3;
+
+			u32 Vmax = (3300 * R2) / (R1 + R2);
+			u32 Rpar = (R2 * R3) / (R3 + R2);
+			u32 Vmin = (3300 * Rpar) / (R1 + Rpar);
+			u32 Vout = Vmin + ((Vmax - Vmin) * Value) / 1024;
+
+			*pValue = Vout;
+		}
+	}
+	return status;
+}
+
+static int load_firmware(struct drxd_state *state, const char *fw_name)
+{
+	const struct firmware *fw;
+
+	if (reject_firmware(&fw, fw_name, state->dev) < 0) {
+		printk(KERN_ERR "drxd: firmware load failure [%s]\n", fw_name);
+		return -EIO;
+	}
+
+	state->microcode = kzalloc(fw->size, GFP_KERNEL);
+	if (state->microcode == NULL) {
+		printk(KERN_ERR "drxd: firmware load failure: nomemory\n");
+		return -ENOMEM;
+	}
+
+	memcpy(state->microcode, fw->data, fw->size);
+	state->microcode_length = fw->size;
+	return 0;
+}
+
+static int DownloadMicrocode(struct drxd_state *state,
+			     const u8 *pMCImage, u32 Length)
+{
+	u8 *pSrc;
+	u16 Flags;
+	u32 Address;
+	u16 nBlocks;
+	u16 BlockSize;
+	u16 BlockCRC;
+	u32 offset = 0;
+	int i, status = 0;
+
+	pSrc = (u8 *) pMCImage;
+	Flags = (pSrc[0] << 8) | pSrc[1];
+	pSrc += sizeof(u16);
+	offset += sizeof(u16);
+	nBlocks = (pSrc[0] << 8) | pSrc[1];
+	pSrc += sizeof(u16);
+	offset += sizeof(u16);
+
+	for (i = 0; i < nBlocks; i++) {
+		Address = (pSrc[0] << 24) | (pSrc[1] << 16) |
+		    (pSrc[2] << 8) | pSrc[3];
+		pSrc += sizeof(u32);
+		offset += sizeof(u32);
+
+		BlockSize = ((pSrc[0] << 8) | pSrc[1]) * sizeof(u16);
+		pSrc += sizeof(u16);
+		offset += sizeof(u16);
+
+		Flags = (pSrc[0] << 8) | pSrc[1];
+		pSrc += sizeof(u16);
+		offset += sizeof(u16);
+
+		BlockCRC = (pSrc[0] << 8) | pSrc[1];
+		pSrc += sizeof(u16);
+		offset += sizeof(u16);
+
+		status = WriteBlock(state, Address, BlockSize,
+				    pSrc, DRX_I2C_CLEARCRC);
+		if (status < 0)
+			break;
+		pSrc += BlockSize;
+		offset += BlockSize;
+	}
+
+	return status;
+}
+
+static int HI_Command(struct drxd_state *state, u16 cmd, u16 * pResult)
+{
+	u32 nrRetries = 0;
+	u16 waitCmd;
+	int status;
+
+	status = Write16(state, HI_RA_RAM_SRV_CMD__A, cmd, 0);
+	if (status < 0)
+		return status;
+
+	do {
+		nrRetries += 1;
+		if (nrRetries > DRXD_MAX_RETRIES) {
+			status = -1;
+			break;
+		};
+		status = Read16(state, HI_RA_RAM_SRV_CMD__A, &waitCmd, 0);
+	} while (waitCmd != 0);
+
+	if (status >= 0)
+		status = Read16(state, HI_RA_RAM_SRV_RES__A, pResult, 0);
+	return status;
+}
+
+static int HI_CfgCommand(struct drxd_state *state)
+{
+	int status = 0;
+
+	mutex_lock(&state->mutex);
+	Write16(state, HI_RA_RAM_SRV_CFG_KEY__A, HI_RA_RAM_SRV_RST_KEY_ACT, 0);
+	Write16(state, HI_RA_RAM_SRV_CFG_DIV__A, state->hi_cfg_timing_div, 0);
+	Write16(state, HI_RA_RAM_SRV_CFG_BDL__A, state->hi_cfg_bridge_delay, 0);
+	Write16(state, HI_RA_RAM_SRV_CFG_WUP__A, state->hi_cfg_wakeup_key, 0);
+	Write16(state, HI_RA_RAM_SRV_CFG_ACT__A, state->hi_cfg_ctrl, 0);
+
+	Write16(state, HI_RA_RAM_SRV_CFG_KEY__A, HI_RA_RAM_SRV_RST_KEY_ACT, 0);
+
+	if ((state->hi_cfg_ctrl & HI_RA_RAM_SRV_CFG_ACT_PWD_EXE) ==
+	    HI_RA_RAM_SRV_CFG_ACT_PWD_EXE)
+		status = Write16(state, HI_RA_RAM_SRV_CMD__A,
+				 HI_RA_RAM_SRV_CMD_CONFIG, 0);
+	else
+		status = HI_Command(state, HI_RA_RAM_SRV_CMD_CONFIG, 0);
+	mutex_unlock(&state->mutex);
+	return status;
+}
+
+static int InitHI(struct drxd_state *state)
+{
+	state->hi_cfg_wakeup_key = (state->chip_adr);
+	/* port/bridge/power down ctrl */
+	state->hi_cfg_ctrl = HI_RA_RAM_SRV_CFG_ACT_SLV0_ON;
+	return HI_CfgCommand(state);
+}
+
+static int HI_ResetCommand(struct drxd_state *state)
+{
+	int status;
+
+	mutex_lock(&state->mutex);
+	status = Write16(state, HI_RA_RAM_SRV_RST_KEY__A,
+			 HI_RA_RAM_SRV_RST_KEY_ACT, 0);
+	if (status == 0)
+		status = HI_Command(state, HI_RA_RAM_SRV_CMD_RESET, 0);
+	mutex_unlock(&state->mutex);
+	msleep(1);
+	return status;
+}
+
+static int DRX_ConfigureI2CBridge(struct drxd_state *state, int bEnableBridge)
+{
+	state->hi_cfg_ctrl &= (~HI_RA_RAM_SRV_CFG_ACT_BRD__M);
+	if (bEnableBridge)
+		state->hi_cfg_ctrl |= HI_RA_RAM_SRV_CFG_ACT_BRD_ON;
+	else
+		state->hi_cfg_ctrl |= HI_RA_RAM_SRV_CFG_ACT_BRD_OFF;
+
+	return HI_CfgCommand(state);
+}
+
+#define HI_TR_WRITE      0x9
+#define HI_TR_READ       0xA
+#define HI_TR_READ_WRITE 0xB
+#define HI_TR_BROADCAST  0x4
+
+#if 0
+static int AtomicReadBlock(struct drxd_state *state,
+			   u32 Addr, u16 DataSize, u8 *pData, u8 Flags)
+{
+	int status;
+	int i = 0;
+
+	/* Parameter check */
+	if ((!pData) || ((DataSize & 1) != 0))
+		return -1;
+
+	mutex_lock(&state->mutex);
+
+	do {
+		/* Instruct HI to read n bytes */
+		/* TODO use proper names forthese egisters */
+		status = Write16(state, HI_RA_RAM_SRV_CFG_KEY__A, (HI_TR_FUNC_ADDR & 0xFFFF), 0);
+		if (status < 0)
+			break;
+		status = Write16(state, HI_RA_RAM_SRV_CFG_DIV__A, (u16) (Addr >> 16), 0);
+		if (status < 0)
+			break;
+		status = Write16(state, HI_RA_RAM_SRV_CFG_BDL__A, (u16) (Addr & 0xFFFF), 0);
+		if (status < 0)
+			break;
+		status = Write16(state, HI_RA_RAM_SRV_CFG_WUP__A, (u16) ((DataSize / 2) - 1), 0);
+		if (status < 0)
+			break;
+		status = Write16(state, HI_RA_RAM_SRV_CFG_ACT__A, HI_TR_READ, 0);
+		if (status < 0)
+			break;
+
+		status = HI_Command(state, HI_RA_RAM_SRV_CMD_EXECUTE, 0);
+		if (status < 0)
+			break;
+
+	} while (0);
+
+	if (status >= 0) {
+		for (i = 0; i < (DataSize / 2); i += 1) {
+			u16 word;
+
+			status = Read16(state, (HI_RA_RAM_USR_BEGIN__A + i),
+					&word, 0);
+			if (status < 0)
+				break;
+			pData[2 * i] = (u8) (word & 0xFF);
+			pData[(2 * i) + 1] = (u8) (word >> 8);
+		}
+	}
+	mutex_unlock(&state->mutex);
+	return status;
+}
+
+static int AtomicReadReg32(struct drxd_state *state,
+			   u32 Addr, u32 *pData, u8 Flags)
+{
+	u8 buf[sizeof(u32)];
+	int status;
+
+	if (!pData)
+		return -1;
+	status = AtomicReadBlock(state, Addr, sizeof(u32), buf, Flags);
+	*pData = (((u32) buf[0]) << 0) +
+	    (((u32) buf[1]) << 8) +
+	    (((u32) buf[2]) << 16) + (((u32) buf[3]) << 24);
+	return status;
+}
+#endif
+
+static int StopAllProcessors(struct drxd_state *state)
+{
+	return Write16(state, HI_COMM_EXEC__A,
+		       SC_COMM_EXEC_CTL_STOP, DRX_I2C_BROADCAST);
+}
+
+static int EnableAndResetMB(struct drxd_state *state)
+{
+	if (state->type_A) {
+		/* disable? monitor bus observe @ EC_OC */
+		Write16(state, EC_OC_REG_OC_MON_SIO__A, 0x0000, 0x0000);
+	}
+
+	/* do inverse broadcast, followed by explicit write to HI */
+	Write16(state, HI_COMM_MB__A, 0x0000, DRX_I2C_BROADCAST);
+	Write16(state, HI_COMM_MB__A, 0x0000, 0x0000);
+	return 0;
+}
+
+static int InitCC(struct drxd_state *state)
+{
+	if (state->osc_clock_freq == 0 ||
+	    state->osc_clock_freq > 20000 ||
+	    (state->osc_clock_freq % 4000) != 0) {
+		printk(KERN_ERR "invalid osc frequency %d\n", state->osc_clock_freq);
+		return -1;
+	}
+
+	Write16(state, CC_REG_OSC_MODE__A, CC_REG_OSC_MODE_M20, 0);
+	Write16(state, CC_REG_PLL_MODE__A, CC_REG_PLL_MODE_BYPASS_PLL |
+		CC_REG_PLL_MODE_PUMP_CUR_12, 0);
+	Write16(state, CC_REG_REF_DIVIDE__A, state->osc_clock_freq / 4000, 0);
+	Write16(state, CC_REG_PWD_MODE__A, CC_REG_PWD_MODE_DOWN_PLL, 0);
+	Write16(state, CC_REG_UPDATE__A, CC_REG_UPDATE_KEY, 0);
+
+	return 0;
+}
+
+static int ResetECOD(struct drxd_state *state)
+{
+	int status = 0;
+
+	if (state->type_A)
+		status = Write16(state, EC_OD_REG_SYNC__A, 0x0664, 0);
+	else
+		status = Write16(state, B_EC_OD_REG_SYNC__A, 0x0664, 0);
+
+	if (!(status < 0))
+		status = WriteTable(state, state->m_ResetECRAM);
+	if (!(status < 0))
+		status = Write16(state, EC_OD_REG_COMM_EXEC__A, 0x0001, 0);
+	return status;
+}
+
+/* Configure PGA switch */
+
+static int SetCfgPga(struct drxd_state *state, int pgaSwitch)
+{
+	int status;
+	u16 AgModeLop = 0;
+	u16 AgModeHip = 0;
+	do {
+		if (pgaSwitch) {
+			/* PGA on */
+			/* fine gain */
+			status = Read16(state, B_FE_AG_REG_AG_MODE_LOP__A, &AgModeLop, 0x0000);
+			if (status < 0)
+				break;
+			AgModeLop &= (~(B_FE_AG_REG_AG_MODE_LOP_MODE_C__M));
+			AgModeLop |= B_FE_AG_REG_AG_MODE_LOP_MODE_C_DYNAMIC;
+			status = Write16(state, B_FE_AG_REG_AG_MODE_LOP__A, AgModeLop, 0x0000);
+			if (status < 0)
+				break;
+
+			/* coarse gain */
+			status = Read16(state, B_FE_AG_REG_AG_MODE_HIP__A, &AgModeHip, 0x0000);
+			if (status < 0)
+				break;
+			AgModeHip &= (~(B_FE_AG_REG_AG_MODE_HIP_MODE_J__M));
+			AgModeHip |= B_FE_AG_REG_AG_MODE_HIP_MODE_J_DYNAMIC;
+			status = Write16(state, B_FE_AG_REG_AG_MODE_HIP__A, AgModeHip, 0x0000);
+			if (status < 0)
+				break;
+
+			/* enable fine and coarse gain, enable AAF,
+			   no ext resistor */
+			status = Write16(state, B_FE_AG_REG_AG_PGA_MODE__A, B_FE_AG_REG_AG_PGA_MODE_PFY_PCY_AFY_REN, 0x0000);
+			if (status < 0)
+				break;
+		} else {
+			/* PGA off, bypass */
+
+			/* fine gain */
+			status = Read16(state, B_FE_AG_REG_AG_MODE_LOP__A, &AgModeLop, 0x0000);
+			if (status < 0)
+				break;
+			AgModeLop &= (~(B_FE_AG_REG_AG_MODE_LOP_MODE_C__M));
+			AgModeLop |= B_FE_AG_REG_AG_MODE_LOP_MODE_C_STATIC;
+			status = Write16(state, B_FE_AG_REG_AG_MODE_LOP__A, AgModeLop, 0x0000);
+			if (status < 0)
+				break;
+
+			/* coarse gain */
+			status = Read16(state, B_FE_AG_REG_AG_MODE_HIP__A, &AgModeHip, 0x0000);
+			if (status < 0)
+				break;
+			AgModeHip &= (~(B_FE_AG_REG_AG_MODE_HIP_MODE_J__M));
+			AgModeHip |= B_FE_AG_REG_AG_MODE_HIP_MODE_J_STATIC;
+			status = Write16(state, B_FE_AG_REG_AG_MODE_HIP__A, AgModeHip, 0x0000);
+			if (status < 0)
+				break;
+
+			/* disable fine and coarse gain, enable AAF,
+			   no ext resistor */
+			status = Write16(state, B_FE_AG_REG_AG_PGA_MODE__A, B_FE_AG_REG_AG_PGA_MODE_PFN_PCN_AFY_REN, 0x0000);
+			if (status < 0)
+				break;
+		}
+	} while (0);
+	return status;
+}
+
+static int InitFE(struct drxd_state *state)
+{
+	int status;
+
+	do {
+		status = WriteTable(state, state->m_InitFE_1);
+		if (status < 0)
+			break;
+
+		if (state->type_A) {
+			status = Write16(state, FE_AG_REG_AG_PGA_MODE__A,
+					 FE_AG_REG_AG_PGA_MODE_PFN_PCN_AFY_REN,
+					 0);
+		} else {
+			if (state->PGA)
+				status = SetCfgPga(state, 0);
+			else
+				status =
+				    Write16(state, B_FE_AG_REG_AG_PGA_MODE__A,
+					    B_FE_AG_REG_AG_PGA_MODE_PFN_PCN_AFY_REN,
+					    0);
+		}
+
+		if (status < 0)
+			break;
+		status = Write16(state, FE_AG_REG_AG_AGC_SIO__A, state->m_FeAgRegAgAgcSio, 0x0000);
+		if (status < 0)
+			break;
+		status = Write16(state, FE_AG_REG_AG_PWD__A, state->m_FeAgRegAgPwd, 0x0000);
+		if (status < 0)
+			break;
+
+		status = WriteTable(state, state->m_InitFE_2);
+		if (status < 0)
+			break;
+
+	} while (0);
+
+	return status;
+}
+
+static int InitFT(struct drxd_state *state)
+{
+	/*
+	   norm OFFSET,  MB says =2 voor 8K en =3 voor 2K waarschijnlijk
+	   SC stuff
+	 */
+	return Write16(state, FT_REG_COMM_EXEC__A, 0x0001, 0x0000);
+}
+
+static int SC_WaitForReady(struct drxd_state *state)
+{
+	u16 curCmd;
+	int i;
+
+	for (i = 0; i < DRXD_MAX_RETRIES; i += 1) {
+		int status = Read16(state, SC_RA_RAM_CMD__A, &curCmd, 0);
+		if (status == 0 || curCmd == 0)
+			return status;
+	}
+	return -1;
+}
+
+static int SC_SendCommand(struct drxd_state *state, u16 cmd)
+{
+	int status = 0;
+	u16 errCode;
+
+	Write16(state, SC_RA_RAM_CMD__A, cmd, 0);
+	SC_WaitForReady(state);
+
+	Read16(state, SC_RA_RAM_CMD_ADDR__A, &errCode, 0);
+
+	if (errCode == 0xFFFF) {
+		printk(KERN_ERR "Command Error\n");
+		status = -1;
+	}
+
+	return status;
+}
+
+static int SC_ProcStartCommand(struct drxd_state *state,
+			       u16 subCmd, u16 param0, u16 param1)
+{
+	int status = 0;
+	u16 scExec;
+
+	mutex_lock(&state->mutex);
+	do {
+		Read16(state, SC_COMM_EXEC__A, &scExec, 0);
+		if (scExec != 1) {
+			status = -1;
+			break;
+		}
+		SC_WaitForReady(state);
+		Write16(state, SC_RA_RAM_CMD_ADDR__A, subCmd, 0);
+		Write16(state, SC_RA_RAM_PARAM1__A, param1, 0);
+		Write16(state, SC_RA_RAM_PARAM0__A, param0, 0);
+
+		SC_SendCommand(state, SC_RA_RAM_CMD_PROC_START);
+	} while (0);
+	mutex_unlock(&state->mutex);
+	return status;
+}
+
+static int SC_SetPrefParamCommand(struct drxd_state *state,
+				  u16 subCmd, u16 param0, u16 param1)
+{
+	int status;
+
+	mutex_lock(&state->mutex);
+	do {
+		status = SC_WaitForReady(state);
+		if (status < 0)
+			break;
+		status = Write16(state, SC_RA_RAM_CMD_ADDR__A, subCmd, 0);
+		if (status < 0)
+			break;
+		status = Write16(state, SC_RA_RAM_PARAM1__A, param1, 0);
+		if (status < 0)
+			break;
+		status = Write16(state, SC_RA_RAM_PARAM0__A, param0, 0);
+		if (status < 0)
+			break;
+
+		status = SC_SendCommand(state, SC_RA_RAM_CMD_SET_PREF_PARAM);
+		if (status < 0)
+			break;
+	} while (0);
+	mutex_unlock(&state->mutex);
+	return status;
+}
+
+#if 0
+static int SC_GetOpParamCommand(struct drxd_state *state, u16 * result)
+{
+	int status = 0;
+
+	mutex_lock(&state->mutex);
+	do {
+		status = SC_WaitForReady(state);
+		if (status < 0)
+			break;
+		status = SC_SendCommand(state, SC_RA_RAM_CMD_GET_OP_PARAM);
+		if (status < 0)
+			break;
+		status = Read16(state, SC_RA_RAM_PARAM0__A, result, 0);
+		if (status < 0)
+			break;
+	} while (0);
+	mutex_unlock(&state->mutex);
+	return status;
+}
+#endif
+
+static int ConfigureMPEGOutput(struct drxd_state *state, int bEnableOutput)
+{
+	int status;
+
+	do {
+		u16 EcOcRegIprInvMpg = 0;
+		u16 EcOcRegOcModeLop = 0;
+		u16 EcOcRegOcModeHip = 0;
+		u16 EcOcRegOcMpgSio = 0;
+
+		/*CHK_ERROR(Read16(state, EC_OC_REG_OC_MODE_LOP__A, &EcOcRegOcModeLop, 0)); */
+
+		if (state->operation_mode == OM_DVBT_Diversity_Front) {
+			if (bEnableOutput) {
+				EcOcRegOcModeHip |=
+				    B_EC_OC_REG_OC_MODE_HIP_MPG_BUS_SRC_MONITOR;
+			} else
+				EcOcRegOcMpgSio |= EC_OC_REG_OC_MPG_SIO__M;
+			EcOcRegOcModeLop |=
+			    EC_OC_REG_OC_MODE_LOP_PAR_ENA_DISABLE;
+		} else {
+			EcOcRegOcModeLop = state->m_EcOcRegOcModeLop;
+
+			if (bEnableOutput)
+				EcOcRegOcMpgSio &= (~(EC_OC_REG_OC_MPG_SIO__M));
+			else
+				EcOcRegOcMpgSio |= EC_OC_REG_OC_MPG_SIO__M;
+
+			/* Don't Insert RS Byte */
+			if (state->insert_rs_byte) {
+				EcOcRegOcModeLop &=
+				    (~(EC_OC_REG_OC_MODE_LOP_PAR_ENA__M));
+				EcOcRegOcModeHip &=
+				    (~EC_OC_REG_OC_MODE_HIP_MPG_PAR_VAL__M);
+				EcOcRegOcModeHip |=
+				    EC_OC_REG_OC_MODE_HIP_MPG_PAR_VAL_ENABLE;
+			} else {
+				EcOcRegOcModeLop |=
+				    EC_OC_REG_OC_MODE_LOP_PAR_ENA_DISABLE;
+				EcOcRegOcModeHip &=
+				    (~EC_OC_REG_OC_MODE_HIP_MPG_PAR_VAL__M);
+				EcOcRegOcModeHip |=
+				    EC_OC_REG_OC_MODE_HIP_MPG_PAR_VAL_DISABLE;
+			}
+
+			/* Mode = Parallel */
+			if (state->enable_parallel)
+				EcOcRegOcModeLop &=
+				    (~(EC_OC_REG_OC_MODE_LOP_MPG_TRM_MDE__M));
+			else
+				EcOcRegOcModeLop |=
+				    EC_OC_REG_OC_MODE_LOP_MPG_TRM_MDE_SERIAL;
+		}
+		/* Invert Data */
+		/* EcOcRegIprInvMpg |= 0x00FF; */
+		EcOcRegIprInvMpg &= (~(0x00FF));
+
+		/* Invert Error ( we don't use the pin ) */
+		/*  EcOcRegIprInvMpg |= 0x0100; */
+		EcOcRegIprInvMpg &= (~(0x0100));
+
+		/* Invert Start ( we don't use the pin ) */
+		/* EcOcRegIprInvMpg |= 0x0200; */
+		EcOcRegIprInvMpg &= (~(0x0200));
+
+		/* Invert Valid ( we don't use the pin ) */
+		/* EcOcRegIprInvMpg |= 0x0400; */
+		EcOcRegIprInvMpg &= (~(0x0400));
+
+		/* Invert Clock */
+		/* EcOcRegIprInvMpg |= 0x0800; */
+		EcOcRegIprInvMpg &= (~(0x0800));
+
+		/* EcOcRegOcModeLop =0x05; */
+		status = Write16(state, EC_OC_REG_IPR_INV_MPG__A, EcOcRegIprInvMpg, 0);
+		if (status < 0)
+			break;
+		status = Write16(state, EC_OC_REG_OC_MODE_LOP__A, EcOcRegOcModeLop, 0);
+		if (status < 0)
+			break;
+		status = Write16(state, EC_OC_REG_OC_MODE_HIP__A, EcOcRegOcModeHip, 0x0000);
+		if (status < 0)
+			break;
+		status = Write16(state, EC_OC_REG_OC_MPG_SIO__A, EcOcRegOcMpgSio, 0);
+		if (status < 0)
+			break;
+	} while (0);
+	return status;
+}
+
+static int SetDeviceTypeId(struct drxd_state *state)
+{
+	int status = 0;
+	u16 deviceId = 0;
+
+	do {
+		status = Read16(state, CC_REG_JTAGID_L__A, &deviceId, 0);
+		if (status < 0)
+			break;
+		/* TODO: why twice? */
+		status = Read16(state, CC_REG_JTAGID_L__A, &deviceId, 0);
+		if (status < 0)
+			break;
+		printk(KERN_INFO "drxd: deviceId = %04x\n", deviceId);
+
+		state->type_A = 0;
+		state->PGA = 0;
+		state->diversity = 0;
+		if (deviceId == 0) {	/* on A2 only 3975 available */
+			state->type_A = 1;
+			printk(KERN_INFO "DRX3975D-A2\n");
+		} else {
+			deviceId >>= 12;
+			printk(KERN_INFO "DRX397%dD-B1\n", deviceId);
+			switch (deviceId) {
+			case 4:
+				state->diversity = 1;
+			case 3:
+			case 7:
+				state->PGA = 1;
+				break;
+			case 6:
+				state->diversity = 1;
+			case 5:
+			case 8:
+				break;
+			default:
+				status = -1;
+				break;
+			}
+		}
+	} while (0);
+
+	if (status < 0)
+		return status;
+
+	/* Init Table selection */
+	state->m_InitAtomicRead = DRXD_InitAtomicRead;
+	state->m_InitSC = DRXD_InitSC;
+	state->m_ResetECRAM = DRXD_ResetECRAM;
+	if (state->type_A) {
+		state->m_ResetCEFR = DRXD_ResetCEFR;
+		state->m_InitFE_1 = DRXD_InitFEA2_1;
+		state->m_InitFE_2 = DRXD_InitFEA2_2;
+		state->m_InitCP = DRXD_InitCPA2;
+		state->m_InitCE = DRXD_InitCEA2;
+		state->m_InitEQ = DRXD_InitEQA2;
+		state->m_InitEC = DRXD_InitECA2;
+		if (load_firmware(state, DRX_FW_FILENAME_A2))
+			return -EIO;
+	} else {
+		state->m_ResetCEFR = NULL;
+		state->m_InitFE_1 = DRXD_InitFEB1_1;
+		state->m_InitFE_2 = DRXD_InitFEB1_2;
+		state->m_InitCP = DRXD_InitCPB1;
+		state->m_InitCE = DRXD_InitCEB1;
+		state->m_InitEQ = DRXD_InitEQB1;
+		state->m_InitEC = DRXD_InitECB1;
+		if (load_firmware(state, DRX_FW_FILENAME_B1))
+			return -EIO;
+	}
+	if (state->diversity) {
+		state->m_InitDiversityFront = DRXD_InitDiversityFront;
+		state->m_InitDiversityEnd = DRXD_InitDiversityEnd;
+		state->m_DisableDiversity = DRXD_DisableDiversity;
+		state->m_StartDiversityFront = DRXD_StartDiversityFront;
+		state->m_StartDiversityEnd = DRXD_StartDiversityEnd;
+		state->m_DiversityDelay8MHZ = DRXD_DiversityDelay8MHZ;
+		state->m_DiversityDelay6MHZ = DRXD_DiversityDelay6MHZ;
+	} else {
+		state->m_InitDiversityFront = NULL;
+		state->m_InitDiversityEnd = NULL;
+		state->m_DisableDiversity = NULL;
+		state->m_StartDiversityFront = NULL;
+		state->m_StartDiversityEnd = NULL;
+		state->m_DiversityDelay8MHZ = NULL;
+		state->m_DiversityDelay6MHZ = NULL;
+	}
+
+	return status;
+}
+
+static int CorrectSysClockDeviation(struct drxd_state *state)
+{
+	int status;
+	s32 incr = 0;
+	s32 nomincr = 0;
+	u32 bandwidth = 0;
+	u32 sysClockInHz = 0;
+	u32 sysClockFreq = 0;	/* in kHz */
+	s16 oscClockDeviation;
+	s16 Diff;
+
+	do {
+		/* Retrieve bandwidth and incr, sanity check */
+
+		/* These accesses should be AtomicReadReg32, but that
+		   causes trouble (at least for diversity */
+		status = Read32(state, LC_RA_RAM_IFINCR_NOM_L__A, ((u32 *) &nomincr), 0);
+		if (status < 0)
+			break;
+		status = Read32(state, FE_IF_REG_INCR0__A, (u32 *) &incr, 0);
+		if (status < 0)
+			break;
+
+		if (state->type_A) {
+			if ((nomincr - incr < -500) || (nomincr - incr > 500))
+				break;
+		} else {
+			if ((nomincr - incr < -2000) || (nomincr - incr > 2000))
+				break;
+		}
+
+		switch (state->param.u.ofdm.bandwidth) {
+		case BANDWIDTH_8_MHZ:
+			bandwidth = DRXD_BANDWIDTH_8MHZ_IN_HZ;
+			break;
+		case BANDWIDTH_7_MHZ:
+			bandwidth = DRXD_BANDWIDTH_7MHZ_IN_HZ;
+			break;
+		case BANDWIDTH_6_MHZ:
+			bandwidth = DRXD_BANDWIDTH_6MHZ_IN_HZ;
+			break;
+		default:
+			return -1;
+			break;
+		}
+
+		/* Compute new sysclock value
+		   sysClockFreq = (((incr + 2^23)*bandwidth)/2^21)/1000 */
+		incr += (1 << 23);
+		sysClockInHz = MulDiv32(incr, bandwidth, 1 << 21);
+		sysClockFreq = (u32) (sysClockInHz / 1000);
+		/* rounding */
+		if ((sysClockInHz % 1000) > 500)
+			sysClockFreq++;
+
+		/* Compute clock deviation in ppm */
+		oscClockDeviation = (u16) ((((s32) (sysClockFreq) -
+					     (s32)
+					     (state->expected_sys_clock_freq)) *
+					    1000000L) /
+					   (s32)
+					   (state->expected_sys_clock_freq));
+
+		Diff = oscClockDeviation - state->osc_clock_deviation;
+		/*printk(KERN_INFO "sysclockdiff=%d\n", Diff); */
+		if (Diff >= -200 && Diff <= 200) {
+			state->sys_clock_freq = (u16) sysClockFreq;
+			if (oscClockDeviation != state->osc_clock_deviation) {
+				if (state->config.osc_deviation) {
+					state->config.osc_deviation(state->priv,
+								    oscClockDeviation,
+								    1);
+					state->osc_clock_deviation =
+					    oscClockDeviation;
+				}
+			}
+			/* switch OFF SRMM scan in SC */
+			status = Write16(state, SC_RA_RAM_SAMPLE_RATE_COUNT__A, DRXD_OSCDEV_DONT_SCAN, 0);
+			if (status < 0)
+				break;
+			/* overrule FE_IF internal value for
+			   proper re-locking */
+			status = Write16(state, SC_RA_RAM_IF_SAVE__AX, state->current_fe_if_incr, 0);
+			if (status < 0)
+				break;
+			state->cscd_state = CSCD_SAVED;
+		}
+	} while (0);
+
+	return status;
+}
+
+static int DRX_Stop(struct drxd_state *state)
+{
+	int status;
+
+	if (state->drxd_state != DRXD_STARTED)
+		return 0;
+
+	do {
+		if (state->cscd_state != CSCD_SAVED) {
+			u32 lock;
+			status = DRX_GetLockStatus(state, &lock);
+			if (status < 0)
+				break;
+		}
+
+		status = StopOC(state);
+		if (status < 0)
+			break;
+
+		state->drxd_state = DRXD_STOPPED;
+
+		status = ConfigureMPEGOutput(state, 0);
+		if (status < 0)
+			break;
+
+		if (state->type_A) {
+			/* Stop relevant processors off the device */
+			status = Write16(state, EC_OD_REG_COMM_EXEC__A, 0x0000, 0x0000);
+			if (status < 0)
+				break;
+
+			status = Write16(state, SC_COMM_EXEC__A, SC_COMM_EXEC_CTL_STOP, 0);
+			if (status < 0)
+				break;
+			status = Write16(state, LC_COMM_EXEC__A, SC_COMM_EXEC_CTL_STOP, 0);
+			if (status < 0)
+				break;
+		} else {
+			/* Stop all processors except HI & CC & FE */
+			status = Write16(state, B_SC_COMM_EXEC__A, SC_COMM_EXEC_CTL_STOP, 0);
+			if (status < 0)
+				break;
+			status = Write16(state, B_LC_COMM_EXEC__A, SC_COMM_EXEC_CTL_STOP, 0);
+			if (status < 0)
+				break;
+			status = Write16(state, B_FT_COMM_EXEC__A, SC_COMM_EXEC_CTL_STOP, 0);
+			if (status < 0)
+				break;
+			status = Write16(state, B_CP_COMM_EXEC__A, SC_COMM_EXEC_CTL_STOP, 0);
+			if (status < 0)
+				break;
+			status = Write16(state, B_CE_COMM_EXEC__A, SC_COMM_EXEC_CTL_STOP, 0);
+			if (status < 0)
+				break;
+			status = Write16(state, B_EQ_COMM_EXEC__A, SC_COMM_EXEC_CTL_STOP, 0);
+			if (status < 0)
+				break;
+			status = Write16(state, EC_OD_REG_COMM_EXEC__A, 0x0000, 0);
+			if (status < 0)
+				break;
+		}
+
+	} while (0);
+	return status;
+}
+
+int SetOperationMode(struct drxd_state *state, int oMode)
+{
+	int status;
+
+	do {
+		if (state->drxd_state != DRXD_STOPPED) {
+			status = -1;
+			break;
+		}
+
+		if (oMode == state->operation_mode) {
+			status = 0;
+			break;
+		}
+
+		if (oMode != OM_Default && !state->diversity) {
+			status = -1;
+			break;
+		}
+
+		switch (oMode) {
+		case OM_DVBT_Diversity_Front:
+			status = WriteTable(state, state->m_InitDiversityFront);
+			break;
+		case OM_DVBT_Diversity_End:
+			status = WriteTable(state, state->m_InitDiversityEnd);
+			break;
+		case OM_Default:
+			/* We need to check how to
+			   get DRXD out of diversity */
+		default:
+			status = WriteTable(state, state->m_DisableDiversity);
+			break;
+		}
+	} while (0);
+
+	if (!status)
+		state->operation_mode = oMode;
+	return status;
+}
+
+static int StartDiversity(struct drxd_state *state)
+{
+	int status = 0;
+	u16 rcControl;
+
+	do {
+		if (state->operation_mode == OM_DVBT_Diversity_Front) {
+			status = WriteTable(state, state->m_StartDiversityFront);
+			if (status < 0)
+				break;
+		} else if (state->operation_mode == OM_DVBT_Diversity_End) {
+			status = WriteTable(state, state->m_StartDiversityEnd);
+			if (status < 0)
+				break;
+			if (state->param.u.ofdm.bandwidth == BANDWIDTH_8_MHZ) {
+				status = WriteTable(state, state->m_DiversityDelay8MHZ);
+				if (status < 0)
+					break;
+			} else {
+				status = WriteTable(state, state->m_DiversityDelay6MHZ);
+				if (status < 0)
+					break;
+			}
+
+			status = Read16(state, B_EQ_REG_RC_SEL_CAR__A, &rcControl, 0);
+			if (status < 0)
+				break;
+			rcControl &= ~(B_EQ_REG_RC_SEL_CAR_FFTMODE__M);
+			rcControl |= B_EQ_REG_RC_SEL_CAR_DIV_ON |
+			    /*  combining enabled */
+			    B_EQ_REG_RC_SEL_CAR_MEAS_A_CC |
+			    B_EQ_REG_RC_SEL_CAR_PASS_A_CC |
+			    B_EQ_REG_RC_SEL_CAR_LOCAL_A_CC;
+			status = Write16(state, B_EQ_REG_RC_SEL_CAR__A, rcControl, 0);
+			if (status < 0)
+				break;
+		}
+	} while (0);
+	return status;
+}
+
+static int SetFrequencyShift(struct drxd_state *state,
+			     u32 offsetFreq, int channelMirrored)
+{
+	int negativeShift = (state->tuner_mirrors == channelMirrored);
+
+	/* Handle all mirroring
+	 *
+	 * Note: ADC mirroring (aliasing) is implictly handled by limiting
+	 * feFsRegAddInc to 28 bits below
+	 * (if the result before masking is more than 28 bits, this means
+	 *  that the ADC is mirroring.
+	 * The masking is in fact the aliasing of the ADC)
+	 *
+	 */
+
+	/* Compute register value, unsigned computation */
+	state->fe_fs_add_incr = MulDiv32(state->intermediate_freq +
+					 offsetFreq,
+					 1 << 28, state->sys_clock_freq);
+	/* Remove integer part */
+	state->fe_fs_add_incr &= 0x0FFFFFFFL;
+	if (negativeShift)
+		state->fe_fs_add_incr = ((1 << 28) - state->fe_fs_add_incr);
+
+	/* Save the frequency shift without tunerOffset compensation
+	   for CtrlGetChannel. */
+	state->org_fe_fs_add_incr = MulDiv32(state->intermediate_freq,
+					     1 << 28, state->sys_clock_freq);
+	/* Remove integer part */
+	state->org_fe_fs_add_incr &= 0x0FFFFFFFL;
+	if (negativeShift)
+		state->org_fe_fs_add_incr = ((1L << 28) -
+					     state->org_fe_fs_add_incr);
+
+	return Write32(state, FE_FS_REG_ADD_INC_LOP__A,
+		       state->fe_fs_add_incr, 0);
+}
+
+static int SetCfgNoiseCalibration(struct drxd_state *state,
+				  struct SNoiseCal *noiseCal)
+{
+	u16 beOptEna;
+	int status = 0;
+
+	do {
+		status = Read16(state, SC_RA_RAM_BE_OPT_ENA__A, &beOptEna, 0);
+		if (status < 0)
+			break;
+		if (noiseCal->cpOpt) {
+			beOptEna |= (1 << SC_RA_RAM_BE_OPT_ENA_CP_OPT);
+		} else {
+			beOptEna &= ~(1 << SC_RA_RAM_BE_OPT_ENA_CP_OPT);
+			status = Write16(state, CP_REG_AC_NEXP_OFFS__A, noiseCal->cpNexpOfs, 0);
+			if (status < 0)
+				break;
+		}
+		status = Write16(state, SC_RA_RAM_BE_OPT_ENA__A, beOptEna, 0);
+		if (status < 0)
+			break;
+
+		if (!state->type_A) {
+			status = Write16(state, B_SC_RA_RAM_CO_TD_CAL_2K__A, noiseCal->tdCal2k, 0);
+			if (status < 0)
+				break;
+			status = Write16(state, B_SC_RA_RAM_CO_TD_CAL_8K__A, noiseCal->tdCal8k, 0);
+			if (status < 0)
+				break;
+		}
+	} while (0);
+
+	return status;
+}
+
+static int DRX_Start(struct drxd_state *state, s32 off)
+{
+	struct dvb_ofdm_parameters *p = &state->param.u.ofdm;
+	int status;
+
+	u16 transmissionParams = 0;
+	u16 operationMode = 0;
+	u16 qpskTdTpsPwr = 0;
+	u16 qam16TdTpsPwr = 0;
+	u16 qam64TdTpsPwr = 0;
+	u32 feIfIncr = 0;
+	u32 bandwidth = 0;
+	int mirrorFreqSpect;
+
+	u16 qpskSnCeGain = 0;
+	u16 qam16SnCeGain = 0;
+	u16 qam64SnCeGain = 0;
+	u16 qpskIsGainMan = 0;
+	u16 qam16IsGainMan = 0;
+	u16 qam64IsGainMan = 0;
+	u16 qpskIsGainExp = 0;
+	u16 qam16IsGainExp = 0;
+	u16 qam64IsGainExp = 0;
+	u16 bandwidthParam = 0;
+
+	if (off < 0)
+		off = (off - 500) / 1000;
+	else
+		off = (off + 500) / 1000;
+
+	do {
+		if (state->drxd_state != DRXD_STOPPED)
+			return -1;
+		status = ResetECOD(state);
+		if (status < 0)
+			break;
+		if (state->type_A) {
+			status = InitSC(state);
+			if (status < 0)
+				break;
+		} else {
+			status = InitFT(state);
+			if (status < 0)
+				break;
+			status = InitCP(state);
+			if (status < 0)
+				break;
+			status = InitCE(state);
+			if (status < 0)
+				break;
+			status = InitEQ(state);
+			if (status < 0)
+				break;
+			status = InitSC(state);
+			if (status < 0)
+				break;
+		}
+
+		/* Restore current IF & RF AGC settings */
+
+		status = SetCfgIfAgc(state, &state->if_agc_cfg);
+		if (status < 0)
+			break;
+		status = SetCfgRfAgc(state, &state->rf_agc_cfg);
+		if (status < 0)
+			break;
+
+		mirrorFreqSpect = (state->param.inversion == INVERSION_ON);
+
+		switch (p->transmission_mode) {
+		default:	/* Not set, detect it automatically */
+			operationMode |= SC_RA_RAM_OP_AUTO_MODE__M;
+			/* fall through , try first guess DRX_FFTMODE_8K */
+		case TRANSMISSION_MODE_8K:
+			transmissionParams |= SC_RA_RAM_OP_PARAM_MODE_8K;
+			if (state->type_A) {
+				status = Write16(state, EC_SB_REG_TR_MODE__A, EC_SB_REG_TR_MODE_8K, 0x0000);
+				if (status < 0)
+					break;
+				qpskSnCeGain = 99;
+				qam16SnCeGain = 83;
+				qam64SnCeGain = 67;
+			}
+			break;
+		case TRANSMISSION_MODE_2K:
+			transmissionParams |= SC_RA_RAM_OP_PARAM_MODE_2K;
+			if (state->type_A) {
+				status = Write16(state, EC_SB_REG_TR_MODE__A, EC_SB_REG_TR_MODE_2K, 0x0000);
+				if (status < 0)
+					break;
+				qpskSnCeGain = 97;
+				qam16SnCeGain = 71;
+				qam64SnCeGain = 65;
+			}
+			break;
+		}
+
+		switch (p->guard_interval) {
+		case GUARD_INTERVAL_1_4:
+			transmissionParams |= SC_RA_RAM_OP_PARAM_GUARD_4;
+			break;
+		case GUARD_INTERVAL_1_8:
+			transmissionParams |= SC_RA_RAM_OP_PARAM_GUARD_8;
+			break;
+		case GUARD_INTERVAL_1_16:
+			transmissionParams |= SC_RA_RAM_OP_PARAM_GUARD_16;
+			break;
+		case GUARD_INTERVAL_1_32:
+			transmissionParams |= SC_RA_RAM_OP_PARAM_GUARD_32;
+			break;
+		default:	/* Not set, detect it automatically */
+			operationMode |= SC_RA_RAM_OP_AUTO_GUARD__M;
+			/* try first guess 1/4 */
+			transmissionParams |= SC_RA_RAM_OP_PARAM_GUARD_4;
+			break;
+		}
+
+		switch (p->hierarchy_information) {
+		case HIERARCHY_1:
+			transmissionParams |= SC_RA_RAM_OP_PARAM_HIER_A1;
+			if (state->type_A) {
+				status = Write16(state, EQ_REG_OT_ALPHA__A, 0x0001, 0x0000);
+				if (status < 0)
+					break;
+				status = Write16(state, EC_SB_REG_ALPHA__A, 0x0001, 0x0000);
+				if (status < 0)
+					break;
+
+				qpskTdTpsPwr = EQ_TD_TPS_PWR_UNKNOWN;
+				qam16TdTpsPwr = EQ_TD_TPS_PWR_QAM16_ALPHA1;
+				qam64TdTpsPwr = EQ_TD_TPS_PWR_QAM64_ALPHA1;
+
+				qpskIsGainMan =
+				    SC_RA_RAM_EQ_IS_GAIN_UNKNOWN_MAN__PRE;
+				qam16IsGainMan =
+				    SC_RA_RAM_EQ_IS_GAIN_16QAM_MAN__PRE;
+				qam64IsGainMan =
+				    SC_RA_RAM_EQ_IS_GAIN_64QAM_MAN__PRE;
+
+				qpskIsGainExp =
+				    SC_RA_RAM_EQ_IS_GAIN_UNKNOWN_EXP__PRE;
+				qam16IsGainExp =
+				    SC_RA_RAM_EQ_IS_GAIN_16QAM_EXP__PRE;
+				qam64IsGainExp =
+				    SC_RA_RAM_EQ_IS_GAIN_64QAM_EXP__PRE;
+			}
+			break;
+
+		case HIERARCHY_2:
+			transmissionParams |= SC_RA_RAM_OP_PARAM_HIER_A2;
+			if (state->type_A) {
+				status = Write16(state, EQ_REG_OT_ALPHA__A, 0x0002, 0x0000);
+				if (status < 0)
+					break;
+				status = Write16(state, EC_SB_REG_ALPHA__A, 0x0002, 0x0000);
+				if (status < 0)
+					break;
+
+				qpskTdTpsPwr = EQ_TD_TPS_PWR_UNKNOWN;
+				qam16TdTpsPwr = EQ_TD_TPS_PWR_QAM16_ALPHA2;
+				qam64TdTpsPwr = EQ_TD_TPS_PWR_QAM64_ALPHA2;
+
+				qpskIsGainMan =
+				    SC_RA_RAM_EQ_IS_GAIN_UNKNOWN_MAN__PRE;
+				qam16IsGainMan =
+				    SC_RA_RAM_EQ_IS_GAIN_16QAM_A2_MAN__PRE;
+				qam64IsGainMan =
+				    SC_RA_RAM_EQ_IS_GAIN_64QAM_A2_MAN__PRE;
+
+				qpskIsGainExp =
+				    SC_RA_RAM_EQ_IS_GAIN_UNKNOWN_EXP__PRE;
+				qam16IsGainExp =
+				    SC_RA_RAM_EQ_IS_GAIN_16QAM_A2_EXP__PRE;
+				qam64IsGainExp =
+				    SC_RA_RAM_EQ_IS_GAIN_64QAM_A2_EXP__PRE;
+			}
+			break;
+		case HIERARCHY_4:
+			transmissionParams |= SC_RA_RAM_OP_PARAM_HIER_A4;
+			if (state->type_A) {
+				status = Write16(state, EQ_REG_OT_ALPHA__A, 0x0003, 0x0000);
+				if (status < 0)
+					break;
+				status = Write16(state, EC_SB_REG_ALPHA__A, 0x0003, 0x0000);
+				if (status < 0)
+					break;
+
+				qpskTdTpsPwr = EQ_TD_TPS_PWR_UNKNOWN;
+				qam16TdTpsPwr = EQ_TD_TPS_PWR_QAM16_ALPHA4;
+				qam64TdTpsPwr = EQ_TD_TPS_PWR_QAM64_ALPHA4;
+
+				qpskIsGainMan =
+				    SC_RA_RAM_EQ_IS_GAIN_UNKNOWN_MAN__PRE;
+				qam16IsGainMan =
+				    SC_RA_RAM_EQ_IS_GAIN_16QAM_A4_MAN__PRE;
+				qam64IsGainMan =
+				    SC_RA_RAM_EQ_IS_GAIN_64QAM_A4_MAN__PRE;
+
+				qpskIsGainExp =
+				    SC_RA_RAM_EQ_IS_GAIN_UNKNOWN_EXP__PRE;
+				qam16IsGainExp =
+				    SC_RA_RAM_EQ_IS_GAIN_16QAM_A4_EXP__PRE;
+				qam64IsGainExp =
+				    SC_RA_RAM_EQ_IS_GAIN_64QAM_A4_EXP__PRE;
+			}
+			break;
+		case HIERARCHY_AUTO:
+		default:
+			/* Not set, detect it automatically, start with none */
+			operationMode |= SC_RA_RAM_OP_AUTO_HIER__M;
+			transmissionParams |= SC_RA_RAM_OP_PARAM_HIER_NO;
+			if (state->type_A) {
+				status = Write16(state, EQ_REG_OT_ALPHA__A, 0x0000, 0x0000);
+				if (status < 0)
+					break;
+				status = Write16(state, EC_SB_REG_ALPHA__A, 0x0000, 0x0000);
+				if (status < 0)
+					break;
+
+				qpskTdTpsPwr = EQ_TD_TPS_PWR_QPSK;
+				qam16TdTpsPwr = EQ_TD_TPS_PWR_QAM16_ALPHAN;
+				qam64TdTpsPwr = EQ_TD_TPS_PWR_QAM64_ALPHAN;
+
+				qpskIsGainMan =
+				    SC_RA_RAM_EQ_IS_GAIN_QPSK_MAN__PRE;
+				qam16IsGainMan =
+				    SC_RA_RAM_EQ_IS_GAIN_16QAM_MAN__PRE;
+				qam64IsGainMan =
+				    SC_RA_RAM_EQ_IS_GAIN_64QAM_MAN__PRE;
+
+				qpskIsGainExp =
+				    SC_RA_RAM_EQ_IS_GAIN_QPSK_EXP__PRE;
+				qam16IsGainExp =
+				    SC_RA_RAM_EQ_IS_GAIN_16QAM_EXP__PRE;
+				qam64IsGainExp =
+				    SC_RA_RAM_EQ_IS_GAIN_64QAM_EXP__PRE;
+			}
+			break;
+		}
+		status = status;
+		if (status < 0)
+			break;
+
+		switch (p->constellation) {
+		default:
+			operationMode |= SC_RA_RAM_OP_AUTO_CONST__M;
+			/* fall through , try first guess
+			   DRX_CONSTELLATION_QAM64 */
+		case QAM_64:
+			transmissionParams |= SC_RA_RAM_OP_PARAM_CONST_QAM64;
+			if (state->type_A) {
+				status = Write16(state, EQ_REG_OT_CONST__A, 0x0002, 0x0000);
+				if (status < 0)
+					break;
+				status = Write16(state, EC_SB_REG_CONST__A, EC_SB_REG_CONST_64QAM, 0x0000);
+				if (status < 0)
+					break;
+				status = Write16(state, EC_SB_REG_SCALE_MSB__A, 0x0020, 0x0000);
+				if (status < 0)
+					break;
+				status = Write16(state, EC_SB_REG_SCALE_BIT2__A, 0x0008, 0x0000);
+				if (status < 0)
+					break;
+				status = Write16(state, EC_SB_REG_SCALE_LSB__A, 0x0002, 0x0000);
+				if (status < 0)
+					break;
+
+				status = Write16(state, EQ_REG_TD_TPS_PWR_OFS__A, qam64TdTpsPwr, 0x0000);
+				if (status < 0)
+					break;
+				status = Write16(state, EQ_REG_SN_CEGAIN__A, qam64SnCeGain, 0x0000);
+				if (status < 0)
+					break;
+				status = Write16(state, EQ_REG_IS_GAIN_MAN__A, qam64IsGainMan, 0x0000);
+				if (status < 0)
+					break;
+				status = Write16(state, EQ_REG_IS_GAIN_EXP__A, qam64IsGainExp, 0x0000);
+				if (status < 0)
+					break;
+			}
+			break;
+		case QPSK:
+			transmissionParams |= SC_RA_RAM_OP_PARAM_CONST_QPSK;
+			if (state->type_A) {
+				status = Write16(state, EQ_REG_OT_CONST__A, 0x0000, 0x0000);
+				if (status < 0)
+					break;
+				status = Write16(state, EC_SB_REG_CONST__A, EC_SB_REG_CONST_QPSK, 0x0000);
+				if (status < 0)
+					break;
+				status = Write16(state, EC_SB_REG_SCALE_MSB__A, 0x0010, 0x0000);
+				if (status < 0)
+					break;
+				status = Write16(state, EC_SB_REG_SCALE_BIT2__A, 0x0000, 0x0000);
+				if (status < 0)
+					break;
+				status = Write16(state, EC_SB_REG_SCALE_LSB__A, 0x0000, 0x0000);
+				if (status < 0)
+					break;
+
+				status = Write16(state, EQ_REG_TD_TPS_PWR_OFS__A, qpskTdTpsPwr, 0x0000);
+				if (status < 0)
+					break;
+				status = Write16(state, EQ_REG_SN_CEGAIN__A, qpskSnCeGain, 0x0000);
+				if (status < 0)
+					break;
+				status = Write16(state, EQ_REG_IS_GAIN_MAN__A, qpskIsGainMan, 0x0000);
+				if (status < 0)
+					break;
+				status = Write16(state, EQ_REG_IS_GAIN_EXP__A, qpskIsGainExp, 0x0000);
+				if (status < 0)
+					break;
+			}
+			break;
+
+		case QAM_16:
+			transmissionParams |= SC_RA_RAM_OP_PARAM_CONST_QAM16;
+			if (state->type_A) {
+				status = Write16(state, EQ_REG_OT_CONST__A, 0x0001, 0x0000);
+				if (status < 0)
+					break;
+				status = Write16(state, EC_SB_REG_CONST__A, EC_SB_REG_CONST_16QAM, 0x0000);
+				if (status < 0)
+					break;
+				status = Write16(state, EC_SB_REG_SCALE_MSB__A, 0x0010, 0x0000);
+				if (status < 0)
+					break;
+				status = Write16(state, EC_SB_REG_SCALE_BIT2__A, 0x0004, 0x0000);
+				if (status < 0)
+					break;
+				status = Write16(state, EC_SB_REG_SCALE_LSB__A, 0x0000, 0x0000);
+				if (status < 0)
+					break;
+
+				status = Write16(state, EQ_REG_TD_TPS_PWR_OFS__A, qam16TdTpsPwr, 0x0000);
+				if (status < 0)
+					break;
+				status = Write16(state, EQ_REG_SN_CEGAIN__A, qam16SnCeGain, 0x0000);
+				if (status < 0)
+					break;
+				status = Write16(state, EQ_REG_IS_GAIN_MAN__A, qam16IsGainMan, 0x0000);
+				if (status < 0)
+					break;
+				status = Write16(state, EQ_REG_IS_GAIN_EXP__A, qam16IsGainExp, 0x0000);
+				if (status < 0)
+					break;
+			}
+			break;
+
+		}
+		status = status;
+		if (status < 0)
+			break;
+
+		switch (DRX_CHANNEL_HIGH) {
+		default:
+		case DRX_CHANNEL_AUTO:
+		case DRX_CHANNEL_LOW:
+			transmissionParams |= SC_RA_RAM_OP_PARAM_PRIO_LO;
+			status = Write16(state, EC_SB_REG_PRIOR__A, EC_SB_REG_PRIOR_LO, 0x0000);
+			if (status < 0)
+				break;
+			break;
+		case DRX_CHANNEL_HIGH:
+			transmissionParams |= SC_RA_RAM_OP_PARAM_PRIO_HI;
+			status = Write16(state, EC_SB_REG_PRIOR__A, EC_SB_REG_PRIOR_HI, 0x0000);
+			if (status < 0)
+				break;
+			break;
+
+		}
+
+		switch (p->code_rate_HP) {
+		case FEC_1_2:
+			transmissionParams |= SC_RA_RAM_OP_PARAM_RATE_1_2;
+			if (state->type_A) {
+				status = Write16(state, EC_VD_REG_SET_CODERATE__A, EC_VD_REG_SET_CODERATE_C1_2, 0x0000);
+				if (status < 0)
+					break;
+			}
+			break;
+		default:
+			operationMode |= SC_RA_RAM_OP_AUTO_RATE__M;
+		case FEC_2_3:
+			transmissionParams |= SC_RA_RAM_OP_PARAM_RATE_2_3;
+			if (state->type_A) {
+				status = Write16(state, EC_VD_REG_SET_CODERATE__A, EC_VD_REG_SET_CODERATE_C2_3, 0x0000);
+				if (status < 0)
+					break;
+			}
+			break;
+		case FEC_3_4:
+			transmissionParams |= SC_RA_RAM_OP_PARAM_RATE_3_4;
+			if (state->type_A) {
+				status = Write16(state, EC_VD_REG_SET_CODERATE__A, EC_VD_REG_SET_CODERATE_C3_4, 0x0000);
+				if (status < 0)
+					break;
+			}
+			break;
+		case FEC_5_6:
+			transmissionParams |= SC_RA_RAM_OP_PARAM_RATE_5_6;
+			if (state->type_A) {
+				status = Write16(state, EC_VD_REG_SET_CODERATE__A, EC_VD_REG_SET_CODERATE_C5_6, 0x0000);
+				if (status < 0)
+					break;
+			}
+			break;
+		case FEC_7_8:
+			transmissionParams |= SC_RA_RAM_OP_PARAM_RATE_7_8;
+			if (state->type_A) {
+				status = Write16(state, EC_VD_REG_SET_CODERATE__A, EC_VD_REG_SET_CODERATE_C7_8, 0x0000);
+				if (status < 0)
+					break;
+			}
+			break;
+		}
+		status = status;
+		if (status < 0)
+			break;
+
+		/* First determine real bandwidth (Hz) */
+		/* Also set delay for impulse noise cruncher (only A2) */
+		/* Also set parameters for EC_OC fix, note
+		   EC_OC_REG_TMD_HIL_MAR is changed
+		   by SC for fix for some 8K,1/8 guard but is restored by
+		   InitEC and ResetEC
+		   functions */
+		switch (p->bandwidth) {
+		case BANDWIDTH_AUTO:
+		case BANDWIDTH_8_MHZ:
+			/* (64/7)*(8/8)*1000000 */
+			bandwidth = DRXD_BANDWIDTH_8MHZ_IN_HZ;
+
+			bandwidthParam = 0;
+			status = Write16(state,
+					 FE_AG_REG_IND_DEL__A, 50, 0x0000);
+			break;
+		case BANDWIDTH_7_MHZ:
+			/* (64/7)*(7/8)*1000000 */
+			bandwidth = DRXD_BANDWIDTH_7MHZ_IN_HZ;
+			bandwidthParam = 0x4807;	/*binary:0100 1000 0000 0111 */
+			status = Write16(state,
+					 FE_AG_REG_IND_DEL__A, 59, 0x0000);
+			break;
+		case BANDWIDTH_6_MHZ:
+			/* (64/7)*(6/8)*1000000 */
+			bandwidth = DRXD_BANDWIDTH_6MHZ_IN_HZ;
+			bandwidthParam = 0x0F07;	/*binary: 0000 1111 0000 0111 */
+			status = Write16(state,
+					 FE_AG_REG_IND_DEL__A, 71, 0x0000);
+			break;
+		default:
+			status = -EINVAL;
+		}
+		if (status < 0)
+			break;
+
+		status = Write16(state, SC_RA_RAM_BAND__A, bandwidthParam, 0x0000);
+		if (status < 0)
+			break;
+
+		{
+			u16 sc_config;
+			status = Read16(state, SC_RA_RAM_CONFIG__A, &sc_config, 0);
+			if (status < 0)
+				break;
+
+			/* enable SLAVE mode in 2k 1/32 to
+			   prevent timing change glitches */
+			if ((p->transmission_mode == TRANSMISSION_MODE_2K) &&
+			    (p->guard_interval == GUARD_INTERVAL_1_32)) {
+				/* enable slave */
+				sc_config |= SC_RA_RAM_CONFIG_SLAVE__M;
+			} else {
+				/* disable slave */
+				sc_config &= ~SC_RA_RAM_CONFIG_SLAVE__M;
+			}
+			status = Write16(state, SC_RA_RAM_CONFIG__A, sc_config, 0);
+			if (status < 0)
+				break;
+		}
+
+		status = SetCfgNoiseCalibration(state, &state->noise_cal);
+		if (status < 0)
+			break;
+
+		if (state->cscd_state == CSCD_INIT) {
+			/* switch on SRMM scan in SC */
+			status = Write16(state, SC_RA_RAM_SAMPLE_RATE_COUNT__A, DRXD_OSCDEV_DO_SCAN, 0x0000);
+			if (status < 0)
+				break;
+/*            CHK_ERROR(Write16(SC_RA_RAM_SAMPLE_RATE_STEP__A, DRXD_OSCDEV_STEP, 0x0000));*/
+			state->cscd_state = CSCD_SET;
+		}
+
+		/* Now compute FE_IF_REG_INCR */
+		/*((( SysFreq/BandWidth)/2)/2) -1) * 2^23) =>
+		   ((SysFreq / BandWidth) * (2^21) ) - (2^23) */
+		feIfIncr = MulDiv32(state->sys_clock_freq * 1000,
+				    (1ULL << 21), bandwidth) - (1 << 23);
+		status = Write16(state, FE_IF_REG_INCR0__A, (u16) (feIfIncr & FE_IF_REG_INCR0__M), 0x0000);
+		if (status < 0)
+			break;
+		status = Write16(state, FE_IF_REG_INCR1__A, (u16) ((feIfIncr >> FE_IF_REG_INCR0__W) & FE_IF_REG_INCR1__M), 0x0000);
+		if (status < 0)
+			break;
+		/* Bandwidth setting done */
+
+		/* Mirror & frequency offset */
+		SetFrequencyShift(state, off, mirrorFreqSpect);
+
+		/* Start SC, write channel settings to SC */
+
+		/* Enable SC after setting all other parameters */
+		status = Write16(state, SC_COMM_STATE__A, 0, 0x0000);
+		if (status < 0)
+			break;
+		status = Write16(state, SC_COMM_EXEC__A, 1, 0x0000);
+		if (status < 0)
+			break;
+
+		/* Write SC parameter registers, operation mode */
+#if 1
+		operationMode = (SC_RA_RAM_OP_AUTO_MODE__M |
+				 SC_RA_RAM_OP_AUTO_GUARD__M |
+				 SC_RA_RAM_OP_AUTO_CONST__M |
+				 SC_RA_RAM_OP_AUTO_HIER__M |
+				 SC_RA_RAM_OP_AUTO_RATE__M);
+#endif
+		status = SC_SetPrefParamCommand(state, 0x0000, transmissionParams, operationMode);
+		if (status < 0)
+			break;
+
+		/* Start correct processes to get in lock */
+		status = SC_ProcStartCommand(state, SC_RA_RAM_PROC_LOCKTRACK, SC_RA_RAM_SW_EVENT_RUN_NMASK__M, SC_RA_RAM_LOCKTRACK_MIN);
+		if (status < 0)
+			break;
+
+		status = StartOC(state);
+		if (status < 0)
+			break;
+
+		if (state->operation_mode != OM_Default) {
+			status = StartDiversity(state);
+			if (status < 0)
+				break;
+		}
+
+		state->drxd_state = DRXD_STARTED;
+	} while (0);
+
+	return status;
+}
+
+static int CDRXD(struct drxd_state *state, u32 IntermediateFrequency)
+{
+	u32 ulRfAgcOutputLevel = 0xffffffff;
+	u32 ulRfAgcSettleLevel = 528;	/* Optimum value for MT2060 */
+	u32 ulRfAgcMinLevel = 0;	/* Currently unused */
+	u32 ulRfAgcMaxLevel = DRXD_FE_CTRL_MAX;	/* Currently unused */
+	u32 ulRfAgcSpeed = 0;	/* Currently unused */
+	u32 ulRfAgcMode = 0;	/*2;   Off */
+	u32 ulRfAgcR1 = 820;
+	u32 ulRfAgcR2 = 2200;
+	u32 ulRfAgcR3 = 150;
+	u32 ulIfAgcMode = 0;	/* Auto */
+	u32 ulIfAgcOutputLevel = 0xffffffff;
+	u32 ulIfAgcSettleLevel = 0xffffffff;
+	u32 ulIfAgcMinLevel = 0xffffffff;
+	u32 ulIfAgcMaxLevel = 0xffffffff;
+	u32 ulIfAgcSpeed = 0xffffffff;
+	u32 ulIfAgcR1 = 820;
+	u32 ulIfAgcR2 = 2200;
+	u32 ulIfAgcR3 = 150;
+	u32 ulClock = state->config.clock;
+	u32 ulSerialMode = 0;
+	u32 ulEcOcRegOcModeLop = 4;	/* Dynamic DTO source */
+	u32 ulHiI2cDelay = HI_I2C_DELAY;
+	u32 ulHiI2cBridgeDelay = HI_I2C_BRIDGE_DELAY;
+	u32 ulHiI2cPatch = 0;
+	u32 ulEnvironment = APPENV_PORTABLE;
+	u32 ulEnvironmentDiversity = APPENV_MOBILE;
+	u32 ulIFFilter = IFFILTER_SAW;
+
+	state->if_agc_cfg.ctrlMode = AGC_CTRL_AUTO;
+	state->if_agc_cfg.outputLevel = 0;
+	state->if_agc_cfg.settleLevel = 140;
+	state->if_agc_cfg.minOutputLevel = 0;
+	state->if_agc_cfg.maxOutputLevel = 1023;
+	state->if_agc_cfg.speed = 904;
+
+	if (ulIfAgcMode == 1 && ulIfAgcOutputLevel <= DRXD_FE_CTRL_MAX) {
+		state->if_agc_cfg.ctrlMode = AGC_CTRL_USER;
+		state->if_agc_cfg.outputLevel = (u16) (ulIfAgcOutputLevel);
+	}
+
+	if (ulIfAgcMode == 0 &&
+	    ulIfAgcSettleLevel <= DRXD_FE_CTRL_MAX &&
+	    ulIfAgcMinLevel <= DRXD_FE_CTRL_MAX &&
+	    ulIfAgcMaxLevel <= DRXD_FE_CTRL_MAX &&
+	    ulIfAgcSpeed <= DRXD_FE_CTRL_MAX) {
+		state->if_agc_cfg.ctrlMode = AGC_CTRL_AUTO;
+		state->if_agc_cfg.settleLevel = (u16) (ulIfAgcSettleLevel);
+		state->if_agc_cfg.minOutputLevel = (u16) (ulIfAgcMinLevel);
+		state->if_agc_cfg.maxOutputLevel = (u16) (ulIfAgcMaxLevel);
+		state->if_agc_cfg.speed = (u16) (ulIfAgcSpeed);
+	}
+
+	state->if_agc_cfg.R1 = (u16) (ulIfAgcR1);
+	state->if_agc_cfg.R2 = (u16) (ulIfAgcR2);
+	state->if_agc_cfg.R3 = (u16) (ulIfAgcR3);
+
+	state->rf_agc_cfg.R1 = (u16) (ulRfAgcR1);
+	state->rf_agc_cfg.R2 = (u16) (ulRfAgcR2);
+	state->rf_agc_cfg.R3 = (u16) (ulRfAgcR3);
+
+	state->rf_agc_cfg.ctrlMode = AGC_CTRL_AUTO;
+	/* rest of the RFAgcCfg structure currently unused */
+	if (ulRfAgcMode == 1 && ulRfAgcOutputLevel <= DRXD_FE_CTRL_MAX) {
+		state->rf_agc_cfg.ctrlMode = AGC_CTRL_USER;
+		state->rf_agc_cfg.outputLevel = (u16) (ulRfAgcOutputLevel);
+	}
+
+	if (ulRfAgcMode == 0 &&
+	    ulRfAgcSettleLevel <= DRXD_FE_CTRL_MAX &&
+	    ulRfAgcMinLevel <= DRXD_FE_CTRL_MAX &&
+	    ulRfAgcMaxLevel <= DRXD_FE_CTRL_MAX &&
+	    ulRfAgcSpeed <= DRXD_FE_CTRL_MAX) {
+		state->rf_agc_cfg.ctrlMode = AGC_CTRL_AUTO;
+		state->rf_agc_cfg.settleLevel = (u16) (ulRfAgcSettleLevel);
+		state->rf_agc_cfg.minOutputLevel = (u16) (ulRfAgcMinLevel);
+		state->rf_agc_cfg.maxOutputLevel = (u16) (ulRfAgcMaxLevel);
+		state->rf_agc_cfg.speed = (u16) (ulRfAgcSpeed);
+	}
+
+	if (ulRfAgcMode == 2)
+		state->rf_agc_cfg.ctrlMode = AGC_CTRL_OFF;
+
+	if (ulEnvironment <= 2)
+		state->app_env_default = (enum app_env)
+		    (ulEnvironment);
+	if (ulEnvironmentDiversity <= 2)
+		state->app_env_diversity = (enum app_env)
+		    (ulEnvironmentDiversity);
+
+	if (ulIFFilter == IFFILTER_DISCRETE) {
+		/* discrete filter */
+		state->noise_cal.cpOpt = 0;
+		state->noise_cal.cpNexpOfs = 40;
+		state->noise_cal.tdCal2k = -40;
+		state->noise_cal.tdCal8k = -24;
+	} else {
+		/* SAW filter */
+		state->noise_cal.cpOpt = 1;
+		state->noise_cal.cpNexpOfs = 0;
+		state->noise_cal.tdCal2k = -21;
+		state->noise_cal.tdCal8k = -24;
+	}
+	state->m_EcOcRegOcModeLop = (u16) (ulEcOcRegOcModeLop);
+
+	state->chip_adr = (state->config.demod_address << 1) | 1;
+	switch (ulHiI2cPatch) {
+	case 1:
+		state->m_HiI2cPatch = DRXD_HiI2cPatch_1;
+		break;
+	case 3:
+		state->m_HiI2cPatch = DRXD_HiI2cPatch_3;
+		break;
+	default:
+		state->m_HiI2cPatch = NULL;
+	}
+
+	/* modify tuner and clock attributes */
+	state->intermediate_freq = (u16) (IntermediateFrequency / 1000);
+	/* expected system clock frequency in kHz */
+	state->expected_sys_clock_freq = 48000;
+	/* real system clock frequency in kHz */
+	state->sys_clock_freq = 48000;
+	state->osc_clock_freq = (u16) ulClock;
+	state->osc_clock_deviation = 0;
+	state->cscd_state = CSCD_INIT;
+	state->drxd_state = DRXD_UNINITIALIZED;
+
+	state->PGA = 0;
+	state->type_A = 0;
+	state->tuner_mirrors = 0;
+
+	/* modify MPEG output attributes */
+	state->insert_rs_byte = state->config.insert_rs_byte;
+	state->enable_parallel = (ulSerialMode != 1);
+
+	/* Timing div, 250ns/Psys */
+	/* Timing div, = ( delay (nano seconds) * sysclk (kHz) )/ 1000 */
+
+	state->hi_cfg_timing_div = (u16) ((state->sys_clock_freq / 1000) *
+					  ulHiI2cDelay) / 1000;
+	/* Bridge delay, uses oscilator clock */
+	/* Delay = ( delay (nano seconds) * oscclk (kHz) )/ 1000 */
+	state->hi_cfg_bridge_delay = (u16) ((state->osc_clock_freq / 1000) *
+					    ulHiI2cBridgeDelay) / 1000;
+
+	state->m_FeAgRegAgPwd = DRXD_DEF_AG_PWD_CONSUMER;
+	/* state->m_FeAgRegAgPwd = DRXD_DEF_AG_PWD_PRO; */
+	state->m_FeAgRegAgAgcSio = DRXD_DEF_AG_AGC_SIO;
+	return 0;
+}
+
+int DRXD_init(struct drxd_state *state, const u8 * fw, u32 fw_size)
+{
+	int status = 0;
+	u32 driverVersion;
+
+	if (state->init_done)
+		return 0;
+
+	CDRXD(state, state->config.IF ? state->config.IF : 36000000);
+
+	do {
+		state->operation_mode = OM_Default;
+
+		status = SetDeviceTypeId(state);
+		if (status < 0)
+			break;
+
+		/* Apply I2c address patch to B1 */
+		if (!state->type_A && state->m_HiI2cPatch != NULL)
+			status = WriteTable(state, state->m_HiI2cPatch);
+			if (status < 0)
+				break;
+
+		if (state->type_A) {
+			/* HI firmware patch for UIO readout,
+			   avoid clearing of result register */
+			status = Write16(state, 0x43012D, 0x047f, 0);
+			if (status < 0)
+				break;
+		}
+
+		status = HI_ResetCommand(state);
+		if (status < 0)
+			break;
+
+		status = StopAllProcessors(state);
+		if (status < 0)
+			break;
+		status = InitCC(state);
+		if (status < 0)
+			break;
+
+		state->osc_clock_deviation = 0;
+
+		if (state->config.osc_deviation)
+			state->osc_clock_deviation =
+			    state->config.osc_deviation(state->priv, 0, 0);
+		{
+			/* Handle clock deviation */
+			s32 devB;
+			s32 devA = (s32) (state->osc_clock_deviation) *
+			    (s32) (state->expected_sys_clock_freq);
+			/* deviation in kHz */
+			s32 deviation = (devA / (1000000L));
+			/* rounding, signed */
+			if (devA > 0)
+				devB = (2);
+			else
+				devB = (-2);
+			if ((devB * (devA % 1000000L) > 1000000L)) {
+				/* add +1 or -1 */
+				deviation += (devB / 2);
+			}
+
+			state->sys_clock_freq =
+			    (u16) ((state->expected_sys_clock_freq) +
+				   deviation);
+		}
+		status = InitHI(state);
+		if (status < 0)
+			break;
+		status = InitAtomicRead(state);
+		if (status < 0)
+			break;
+
+		status = EnableAndResetMB(state);
+		if (status < 0)
+			break;
+		if (state->type_A)
+			status = ResetCEFR(state);
+			if (status < 0)
+				break;
+
+		if (fw) {
+			status = DownloadMicrocode(state, fw, fw_size);
+			if (status < 0)
+				break;
+		} else {
+			status = DownloadMicrocode(state, state->microcode, state->microcode_length);
+			if (status < 0)
+				break;
+		}
+
+		if (state->PGA) {
+			state->m_FeAgRegAgPwd = DRXD_DEF_AG_PWD_PRO;
+			SetCfgPga(state, 0);	/* PGA = 0 dB */
+		} else {
+			state->m_FeAgRegAgPwd = DRXD_DEF_AG_PWD_CONSUMER;
+		}
+
+		state->m_FeAgRegAgAgcSio = DRXD_DEF_AG_AGC_SIO;
+
+		status = InitFE(state);
+		if (status < 0)
+			break;
+		status = InitFT(state);
+		if (status < 0)
+			break;
+		status = InitCP(state);
+		if (status < 0)
+			break;
+		status = InitCE(state);
+		if (status < 0)
+			break;
+		status = InitEQ(state);
+		if (status < 0)
+			break;
+		status = InitEC(state);
+		if (status < 0)
+			break;
+		status = InitSC(state);
+		if (status < 0)
+			break;
+
+		status = SetCfgIfAgc(state, &state->if_agc_cfg);
+		if (status < 0)
+			break;
+		status = SetCfgRfAgc(state, &state->rf_agc_cfg);
+		if (status < 0)
+			break;
+
+		state->cscd_state = CSCD_INIT;
+		status = Write16(state, SC_COMM_EXEC__A, SC_COMM_EXEC_CTL_STOP, 0);
+		if (status < 0)
+			break;
+		status = Write16(state, LC_COMM_EXEC__A, SC_COMM_EXEC_CTL_STOP, 0);
+		if (status < 0)
+			break;
+
+		driverVersion = (((VERSION_MAJOR / 10) << 4) +
+				 (VERSION_MAJOR % 10)) << 24;
+		driverVersion += (((VERSION_MINOR / 10) << 4) +
+				  (VERSION_MINOR % 10)) << 16;
+		driverVersion += ((VERSION_PATCH / 1000) << 12) +
+		    ((VERSION_PATCH / 100) << 8) +
+		    ((VERSION_PATCH / 10) << 4) + (VERSION_PATCH % 10);
+
+		status = Write32(state, SC_RA_RAM_DRIVER_VERSION__AX, driverVersion, 0);
+		if (status < 0)
+			break;
+
+		status = StopOC(state);
+		if (status < 0)
+			break;
+
+		state->drxd_state = DRXD_STOPPED;
+		state->init_done = 1;
+		status = 0;
+	} while (0);
+	return status;
+}
+
+int DRXD_status(struct drxd_state *state, u32 * pLockStatus)
+{
+	DRX_GetLockStatus(state, pLockStatus);
+
+	/*if (*pLockStatus&DRX_LOCK_MPEG) */
+	if (*pLockStatus & DRX_LOCK_FEC) {
+		ConfigureMPEGOutput(state, 1);
+		/* Get status again, in case we have MPEG lock now */
+		/*DRX_GetLockStatus(state, pLockStatus); */
+	}
+
+	return 0;
+}
+
+/****************************************************************************/
+/****************************************************************************/
+/****************************************************************************/
+
+static int drxd_read_signal_strength(struct dvb_frontend *fe, u16 * strength)
+{
+	struct drxd_state *state = fe->demodulator_priv;
+	u32 value;
+	int res;
+
+	res = ReadIFAgc(state, &value);
+	if (res < 0)
+		*strength = 0;
+	else
+		*strength = 0xffff - (value << 4);
+	return 0;
+}
+
+static int drxd_read_status(struct dvb_frontend *fe, fe_status_t * status)
+{
+	struct drxd_state *state = fe->demodulator_priv;
+	u32 lock;
+
+	DRXD_status(state, &lock);
+	*status = 0;
+	/* No MPEG lock in V255 firmware, bug ? */
+#if 1
+	if (lock & DRX_LOCK_MPEG)
+		*status |= FE_HAS_LOCK;
+#else
+	if (lock & DRX_LOCK_FEC)
+		*status |= FE_HAS_LOCK;
+#endif
+	if (lock & DRX_LOCK_FEC)
+		*status |= FE_HAS_VITERBI | FE_HAS_SYNC;
+	if (lock & DRX_LOCK_DEMOD)
+		*status |= FE_HAS_CARRIER | FE_HAS_SIGNAL;
+
+	return 0;
+}
+
+static int drxd_init(struct dvb_frontend *fe)
+{
+	struct drxd_state *state = fe->demodulator_priv;
+	int err = 0;
+
+/*(DEBLOBBED)*/
+	return DRXD_init(state, 0, 0);
+
+	err = DRXD_init(state, state->fw->data, state->fw->size);
+	release_firmware(state->fw);
+	return err;
+}
+
+int drxd_config_i2c(struct dvb_frontend *fe, int onoff)
+{
+	struct drxd_state *state = fe->demodulator_priv;
+
+	if (state->config.disable_i2c_gate_ctrl == 1)
+		return 0;
+
+	return DRX_ConfigureI2CBridge(state, onoff);
+}
+EXPORT_SYMBOL(drxd_config_i2c);
+
+static int drxd_get_tune_settings(struct dvb_frontend *fe,
+				  struct dvb_frontend_tune_settings *sets)
+{
+	sets->min_delay_ms = 10000;
+	sets->max_drift = 0;
+	sets->step_size = 0;
+	return 0;
+}
+
+static int drxd_read_ber(struct dvb_frontend *fe, u32 * ber)
+{
+	*ber = 0;
+	return 0;
+}
+
+static int drxd_read_snr(struct dvb_frontend *fe, u16 * snr)
+{
+	*snr = 0;
+	return 0;
+}
+
+static int drxd_read_ucblocks(struct dvb_frontend *fe, u32 * ucblocks)
+{
+	*ucblocks = 0;
+	return 0;
+}
+
+static int drxd_sleep(struct dvb_frontend *fe)
+{
+	struct drxd_state *state = fe->demodulator_priv;
+
+	ConfigureMPEGOutput(state, 0);
+	return 0;
+}
+
+static int drxd_get_frontend(struct dvb_frontend *fe,
+			     struct dvb_frontend_parameters *param)
+{
+	return 0;
+}
+
+static int drxd_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
+{
+	return drxd_config_i2c(fe, enable);
+}
+
+static int drxd_set_frontend(struct dvb_frontend *fe,
+			     struct dvb_frontend_parameters *param)
+{
+	struct drxd_state *state = fe->demodulator_priv;
+	s32 off = 0;
+
+	state->param = *param;
+	DRX_Stop(state);
+
+	if (fe->ops.tuner_ops.set_params) {
+		fe->ops.tuner_ops.set_params(fe, param);
+		if (fe->ops.i2c_gate_ctrl)
+			fe->ops.i2c_gate_ctrl(fe, 0);
+	}
+
+	/* FIXME: move PLL drivers */
+	if (state->config.pll_set &&
+	    state->config.pll_set(state->priv, param,
+				  state->config.pll_address,
+				  state->config.demoda_address, &off) < 0) {
+		printk(KERN_ERR "Error in pll_set\n");
+		return -1;
+	}
+
+	msleep(200);
+
+	return DRX_Start(state, off);
+}
+
+static void drxd_release(struct dvb_frontend *fe)
+{
+	struct drxd_state *state = fe->demodulator_priv;
+
+	kfree(state);
+}
+
+static struct dvb_frontend_ops drxd_ops = {
+
+	.info = {
+		 .name = "Micronas DRXD DVB-T",
+		 .type = FE_OFDM,
+		 .frequency_min = 47125000,
+		 .frequency_max = 855250000,
+		 .frequency_stepsize = 166667,
+		 .frequency_tolerance = 0,
+		 .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 |
+		 FE_CAN_FEC_3_4 | FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 |
+		 FE_CAN_FEC_AUTO |
+		 FE_CAN_QAM_16 | FE_CAN_QAM_64 |
+		 FE_CAN_QAM_AUTO |
+		 FE_CAN_TRANSMISSION_MODE_AUTO |
+		 FE_CAN_GUARD_INTERVAL_AUTO |
+		 FE_CAN_HIERARCHY_AUTO | FE_CAN_RECOVER | FE_CAN_MUTE_TS},
+
+	.release = drxd_release,
+	.init = drxd_init,
+	.sleep = drxd_sleep,
+	.i2c_gate_ctrl = drxd_i2c_gate_ctrl,
+
+	.set_frontend = drxd_set_frontend,
+	.get_frontend = drxd_get_frontend,
+	.get_tune_settings = drxd_get_tune_settings,
+
+	.read_status = drxd_read_status,
+	.read_ber = drxd_read_ber,
+	.read_signal_strength = drxd_read_signal_strength,
+	.read_snr = drxd_read_snr,
+	.read_ucblocks = drxd_read_ucblocks,
+};
+
+struct dvb_frontend *drxd_attach(const struct drxd_config *config,
+				 void *priv, struct i2c_adapter *i2c,
+				 struct device *dev)
+{
+	struct drxd_state *state = NULL;
+
+	state = kmalloc(sizeof(struct drxd_state), GFP_KERNEL);
+	if (!state)
+		return NULL;
+	memset(state, 0, sizeof(*state));
+
+	memcpy(&state->ops, &drxd_ops, sizeof(struct dvb_frontend_ops));
+	state->dev = dev;
+	state->config = *config;
+	state->i2c = i2c;
+	state->priv = priv;
+
+	mutex_init(&state->mutex);
+
+	if (Read16(state, 0, 0, 0) < 0)
+		goto error;
+
+	memcpy(&state->frontend.ops, &drxd_ops,
+	       sizeof(struct dvb_frontend_ops));
+	state->frontend.demodulator_priv = state;
+	ConfigureMPEGOutput(state, 0);
+	return &state->frontend;
+
+error:
+	printk(KERN_ERR "drxd: not found\n");
+	kfree(state);
+	return NULL;
+}
+EXPORT_SYMBOL(drxd_attach);
+
+MODULE_DESCRIPTION("DRXD driver");
+MODULE_AUTHOR("Micronas");
+MODULE_LICENSE("GPL");
diff -druN linux-2.6.39-libre/drivers/media/dvb/frontends/drxd_map_firm.h linux-3.0-rc7-libre/drivers/media/dvb/frontends/drxd_map_firm.h
--- linux-2.6.39-libre/drivers/media/dvb/frontends/drxd_map_firm.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/media/dvb/frontends/drxd_map_firm.h	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,1013 @@
+/*
+ * drx3973d_map_firm.h
+ *
+ * Copyright (C) 2006-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 __DRX3973D_MAP__H__
+#define __DRX3973D_MAP__H__
+
+/*
+ * Note: originally, this file contained 12000+ lines of data
+ * Probably a few lines for every firwmare assembler instruction. However,
+ * only a few defines were actually used. So, removed all uneeded lines.
+ * If ever needed, the other lines can be easily obtained via git history.
+ */
+
+#define HI_COMM_EXEC__A                                              0x400000
+#define HI_COMM_MB__A                                                0x400002
+#define HI_CT_REG_COMM_STATE__A                                      0x410001
+#define HI_RA_RAM_SRV_RES__A                                         0x420031
+#define HI_RA_RAM_SRV_CMD__A                                         0x420032
+#define   HI_RA_RAM_SRV_CMD_RESET                                    0x2
+#define   HI_RA_RAM_SRV_CMD_CONFIG                                   0x3
+#define   HI_RA_RAM_SRV_CMD_EXECUTE                                  0x6
+#define HI_RA_RAM_SRV_RST_KEY__A                                     0x420033
+#define   HI_RA_RAM_SRV_RST_KEY_ACT                                  0x3973
+#define HI_RA_RAM_SRV_CFG_KEY__A                                     0x420033
+#define HI_RA_RAM_SRV_CFG_DIV__A                                     0x420034
+#define HI_RA_RAM_SRV_CFG_BDL__A                                     0x420035
+#define HI_RA_RAM_SRV_CFG_WUP__A                                     0x420036
+#define HI_RA_RAM_SRV_CFG_ACT__A                                     0x420037
+#define     HI_RA_RAM_SRV_CFG_ACT_SLV0_ON                            0x1
+#define   HI_RA_RAM_SRV_CFG_ACT_BRD__M                               0x4
+#define     HI_RA_RAM_SRV_CFG_ACT_BRD_OFF                            0x0
+#define     HI_RA_RAM_SRV_CFG_ACT_BRD_ON                             0x4
+#define     HI_RA_RAM_SRV_CFG_ACT_PWD_EXE                            0x8
+#define HI_RA_RAM_USR_BEGIN__A                                       0x420040
+#define HI_IF_RAM_TRP_BPT0__AX                                       0x430000
+#define HI_IF_RAM_USR_BEGIN__A                                       0x430200
+#define SC_COMM_EXEC__A                                              0x800000
+#define     SC_COMM_EXEC_CTL_STOP                                    0x0
+#define SC_COMM_STATE__A                                             0x800001
+#define SC_RA_RAM_PARAM0__A                                          0x820040
+#define SC_RA_RAM_PARAM1__A                                          0x820041
+#define SC_RA_RAM_CMD_ADDR__A                                        0x820042
+#define SC_RA_RAM_CMD__A                                             0x820043
+#define   SC_RA_RAM_CMD_PROC_START                                   0x1
+#define   SC_RA_RAM_CMD_SET_PREF_PARAM                               0x3
+#define   SC_RA_RAM_CMD_GET_OP_PARAM                                 0x5
+#define   SC_RA_RAM_SW_EVENT_RUN_NMASK__M                            0x1
+#define   SC_RA_RAM_LOCKTRACK_MIN                                    0x1
+#define     SC_RA_RAM_OP_PARAM_MODE_2K                               0x0
+#define     SC_RA_RAM_OP_PARAM_MODE_8K                               0x1
+#define     SC_RA_RAM_OP_PARAM_GUARD_32                              0x0
+#define     SC_RA_RAM_OP_PARAM_GUARD_16                              0x4
+#define     SC_RA_RAM_OP_PARAM_GUARD_8                               0x8
+#define     SC_RA_RAM_OP_PARAM_GUARD_4                               0xC
+#define     SC_RA_RAM_OP_PARAM_CONST_QPSK                            0x0
+#define     SC_RA_RAM_OP_PARAM_CONST_QAM16                           0x10
+#define     SC_RA_RAM_OP_PARAM_CONST_QAM64                           0x20
+#define     SC_RA_RAM_OP_PARAM_HIER_NO                               0x0
+#define     SC_RA_RAM_OP_PARAM_HIER_A1                               0x40
+#define     SC_RA_RAM_OP_PARAM_HIER_A2                               0x80
+#define     SC_RA_RAM_OP_PARAM_HIER_A4                               0xC0
+#define     SC_RA_RAM_OP_PARAM_RATE_1_2                              0x0
+#define     SC_RA_RAM_OP_PARAM_RATE_2_3                              0x200
+#define     SC_RA_RAM_OP_PARAM_RATE_3_4                              0x400
+#define     SC_RA_RAM_OP_PARAM_RATE_5_6                              0x600
+#define     SC_RA_RAM_OP_PARAM_RATE_7_8                              0x800
+#define     SC_RA_RAM_OP_PARAM_PRIO_HI                               0x0
+#define     SC_RA_RAM_OP_PARAM_PRIO_LO                               0x1000
+#define   SC_RA_RAM_OP_AUTO_MODE__M                                  0x1
+#define   SC_RA_RAM_OP_AUTO_GUARD__M                                 0x2
+#define   SC_RA_RAM_OP_AUTO_CONST__M                                 0x4
+#define   SC_RA_RAM_OP_AUTO_HIER__M                                  0x8
+#define   SC_RA_RAM_OP_AUTO_RATE__M                                  0x10
+#define SC_RA_RAM_LOCK__A                                            0x82004B
+#define   SC_RA_RAM_LOCK_DEMOD__M                                    0x1
+#define   SC_RA_RAM_LOCK_FEC__M                                      0x2
+#define   SC_RA_RAM_LOCK_MPEG__M                                     0x4
+#define SC_RA_RAM_BE_OPT_ENA__A                                      0x82004C
+#define   SC_RA_RAM_BE_OPT_ENA_CP_OPT                                0x1
+#define SC_RA_RAM_BE_OPT_DELAY__A                                    0x82004D
+#define SC_RA_RAM_CONFIG__A                                          0x820050
+#define   SC_RA_RAM_CONFIG_FR_ENABLE__M                              0x4
+#define   SC_RA_RAM_CONFIG_FREQSCAN__M                               0x10
+#define   SC_RA_RAM_CONFIG_SLAVE__M                                  0x20
+#define SC_RA_RAM_IF_SAVE__AX                                        0x82008E
+#define SC_RA_RAM_IR_COARSE_2K_LENGTH__A                             0x8200D1
+#define SC_RA_RAM_IR_COARSE_2K_LENGTH__PRE                           0x9
+#define SC_RA_RAM_IR_COARSE_2K_FREQINC__A                            0x8200D2
+#define SC_RA_RAM_IR_COARSE_2K_FREQINC__PRE                          0x4
+#define SC_RA_RAM_IR_COARSE_2K_KAISINC__A                            0x8200D3
+#define SC_RA_RAM_IR_COARSE_2K_KAISINC__PRE                          0x100
+#define SC_RA_RAM_IR_COARSE_8K_LENGTH__A                             0x8200D4
+#define SC_RA_RAM_IR_COARSE_8K_LENGTH__PRE                           0x8
+#define SC_RA_RAM_IR_COARSE_8K_FREQINC__A                            0x8200D5
+#define SC_RA_RAM_IR_COARSE_8K_FREQINC__PRE                          0x8
+#define SC_RA_RAM_IR_COARSE_8K_KAISINC__A                            0x8200D6
+#define SC_RA_RAM_IR_COARSE_8K_KAISINC__PRE                          0x200
+#define SC_RA_RAM_IR_FINE_2K_LENGTH__A                               0x8200D7
+#define SC_RA_RAM_IR_FINE_2K_LENGTH__PRE                             0x9
+#define SC_RA_RAM_IR_FINE_2K_FREQINC__A                              0x8200D8
+#define SC_RA_RAM_IR_FINE_2K_FREQINC__PRE                            0x4
+#define SC_RA_RAM_IR_FINE_2K_KAISINC__A                              0x8200D9
+#define SC_RA_RAM_IR_FINE_2K_KAISINC__PRE                            0x100
+#define SC_RA_RAM_IR_FINE_8K_LENGTH__A                               0x8200DA
+#define SC_RA_RAM_IR_FINE_8K_LENGTH__PRE                             0xB
+#define SC_RA_RAM_IR_FINE_8K_FREQINC__A                              0x8200DB
+#define SC_RA_RAM_IR_FINE_8K_FREQINC__PRE                            0x1
+#define SC_RA_RAM_IR_FINE_8K_KAISINC__A                              0x8200DC
+#define SC_RA_RAM_IR_FINE_8K_KAISINC__PRE                            0x40
+#define SC_RA_RAM_ECHO_SHIFT_LIM__A                                  0x8200DD
+#define SC_RA_RAM_SAMPLE_RATE_COUNT__A                               0x8200E8
+#define SC_RA_RAM_SAMPLE_RATE_STEP__A                                0x8200E9
+#define SC_RA_RAM_BAND__A                                            0x8200EC
+#define SC_RA_RAM_LC_ABS_2K__A                                       0x8200F4
+#define SC_RA_RAM_LC_ABS_2K__PRE                                     0x1F
+#define SC_RA_RAM_LC_ABS_8K__A                                       0x8200F5
+#define SC_RA_RAM_LC_ABS_8K__PRE                                     0x1F
+#define SC_RA_RAM_EQ_IS_GAIN_UNKNOWN_MAN__PRE                        0x1D6
+#define SC_RA_RAM_EQ_IS_GAIN_UNKNOWN_EXP__PRE                        0x4
+#define SC_RA_RAM_EQ_IS_GAIN_QPSK_MAN__PRE                           0x1BB
+#define SC_RA_RAM_EQ_IS_GAIN_QPSK_EXP__PRE                           0x5
+#define SC_RA_RAM_EQ_IS_GAIN_16QAM_MAN__PRE                          0x1EF
+#define SC_RA_RAM_EQ_IS_GAIN_16QAM_EXP__PRE                          0x5
+#define SC_RA_RAM_EQ_IS_GAIN_16QAM_A2_MAN__PRE                       0x15E
+#define SC_RA_RAM_EQ_IS_GAIN_16QAM_A2_EXP__PRE                       0x5
+#define SC_RA_RAM_EQ_IS_GAIN_16QAM_A4_MAN__PRE                       0x11A
+#define SC_RA_RAM_EQ_IS_GAIN_16QAM_A4_EXP__PRE                       0x6
+#define SC_RA_RAM_EQ_IS_GAIN_64QAM_MAN__PRE                          0x1FB
+#define SC_RA_RAM_EQ_IS_GAIN_64QAM_EXP__PRE                          0x5
+#define SC_RA_RAM_EQ_IS_GAIN_64QAM_A2_MAN__PRE                       0x12F
+#define SC_RA_RAM_EQ_IS_GAIN_64QAM_A2_EXP__PRE                       0x5
+#define SC_RA_RAM_EQ_IS_GAIN_64QAM_A4_MAN__PRE                       0x197
+#define SC_RA_RAM_EQ_IS_GAIN_64QAM_A4_EXP__PRE                       0x5
+#define SC_RA_RAM_DRIVER_VERSION__AX                                 0x8201FE
+#define   SC_RA_RAM_PROC_LOCKTRACK                                   0x0
+#define FE_COMM_EXEC__A                                              0xC00000
+#define FE_AD_REG_COMM_EXEC__A                                       0xC10000
+#define FE_AD_REG_FDB_IN__A                                          0xC10012
+#define FE_AD_REG_PD__A                                              0xC10013
+#define FE_AD_REG_INVEXT__A                                          0xC10014
+#define FE_AD_REG_CLKNEG__A                                          0xC10015
+#define FE_AG_REG_COMM_EXEC__A                                       0xC20000
+#define FE_AG_REG_AG_MODE_LOP__A                                     0xC20010
+#define   FE_AG_REG_AG_MODE_LOP_MODE_4__M                            0x10
+#define     FE_AG_REG_AG_MODE_LOP_MODE_4_STATIC                      0x0
+#define     FE_AG_REG_AG_MODE_LOP_MODE_4_DYNAMIC                     0x10
+#define   FE_AG_REG_AG_MODE_LOP_MODE_5__M                            0x20
+#define     FE_AG_REG_AG_MODE_LOP_MODE_5_STATIC                      0x0
+#define   FE_AG_REG_AG_MODE_LOP_MODE_C__M                            0x1000
+#define     FE_AG_REG_AG_MODE_LOP_MODE_C_STATIC                      0x0
+#define     FE_AG_REG_AG_MODE_LOP_MODE_C_DYNAMIC                     0x1000
+#define   FE_AG_REG_AG_MODE_LOP_MODE_E__M                            0x4000
+#define     FE_AG_REG_AG_MODE_LOP_MODE_E_STATIC                      0x0
+#define     FE_AG_REG_AG_MODE_LOP_MODE_E_DYNAMIC                     0x4000
+#define FE_AG_REG_AG_MODE_HIP__A                                     0xC20011
+#define FE_AG_REG_AG_PGA_MODE__A                                     0xC20012
+#define   FE_AG_REG_AG_PGA_MODE_PFY_PCY_AFY_REN                      0x0
+#define   FE_AG_REG_AG_PGA_MODE_PFN_PCN_AFY_REN                      0x1
+#define FE_AG_REG_AG_AGC_SIO__A                                      0xC20013
+#define   FE_AG_REG_AG_AGC_SIO_AGC_SIO_2__M                          0x2
+#define     FE_AG_REG_AG_AGC_SIO_AGC_SIO_2_OUTPUT                    0x0
+#define     FE_AG_REG_AG_AGC_SIO_AGC_SIO_2_INPUT                     0x2
+#define FE_AG_REG_AG_PWD__A                                          0xC20015
+#define   FE_AG_REG_AG_PWD_PWD_PD2__M                                0x2
+#define     FE_AG_REG_AG_PWD_PWD_PD2_DISABLE                         0x0
+#define     FE_AG_REG_AG_PWD_PWD_PD2_ENABLE                          0x2
+#define FE_AG_REG_DCE_AUR_CNT__A                                     0xC20016
+#define FE_AG_REG_DCE_RUR_CNT__A                                     0xC20017
+#define FE_AG_REG_ACE_AUR_CNT__A                                     0xC2001A
+#define FE_AG_REG_ACE_RUR_CNT__A                                     0xC2001B
+#define FE_AG_REG_CDR_RUR_CNT__A                                     0xC20020
+#define FE_AG_REG_EGC_RUR_CNT__A                                     0xC20024
+#define FE_AG_REG_EGC_SET_LVL__A                                     0xC20025
+#define FE_AG_REG_EGC_SET_LVL__M                                     0x1FF
+#define FE_AG_REG_EGC_FLA_RGN__A                                     0xC20026
+#define FE_AG_REG_EGC_SLO_RGN__A                                     0xC20027
+#define FE_AG_REG_EGC_JMP_PSN__A                                     0xC20028
+#define FE_AG_REG_EGC_FLA_INC__A                                     0xC20029
+#define FE_AG_REG_EGC_FLA_DEC__A                                     0xC2002A
+#define FE_AG_REG_EGC_SLO_INC__A                                     0xC2002B
+#define FE_AG_REG_EGC_SLO_DEC__A                                     0xC2002C
+#define FE_AG_REG_EGC_FAS_INC__A                                     0xC2002D
+#define FE_AG_REG_EGC_FAS_DEC__A                                     0xC2002E
+#define FE_AG_REG_PM1_AGC_WRI__A                                     0xC20030
+#define FE_AG_REG_PM1_AGC_WRI__M                                     0x7FF
+#define FE_AG_REG_GC1_AGC_RIC__A                                     0xC20031
+#define FE_AG_REG_GC1_AGC_OFF__A                                     0xC20032
+#define FE_AG_REG_GC1_AGC_MAX__A                                     0xC20033
+#define FE_AG_REG_GC1_AGC_MIN__A                                     0xC20034
+#define FE_AG_REG_GC1_AGC_DAT__A                                     0xC20035
+#define FE_AG_REG_GC1_AGC_DAT__M                                     0x3FF
+#define FE_AG_REG_PM2_AGC_WRI__A                                     0xC20036
+#define FE_AG_REG_IND_WIN__A                                         0xC2003C
+#define FE_AG_REG_IND_THD_LOL__A                                     0xC2003D
+#define FE_AG_REG_IND_THD_HIL__A                                     0xC2003E
+#define FE_AG_REG_IND_DEL__A                                         0xC2003F
+#define FE_AG_REG_IND_PD1_WRI__A                                     0xC20040
+#define FE_AG_REG_PDA_AUR_CNT__A                                     0xC20041
+#define FE_AG_REG_PDA_RUR_CNT__A                                     0xC20042
+#define FE_AG_REG_PDA_AVE_DAT__A                                     0xC20043
+#define FE_AG_REG_PDC_RUR_CNT__A                                     0xC20044
+#define FE_AG_REG_PDC_SET_LVL__A                                     0xC20045
+#define FE_AG_REG_PDC_FLA_RGN__A                                     0xC20046
+#define FE_AG_REG_PDC_JMP_PSN__A                                     0xC20047
+#define FE_AG_REG_PDC_FLA_STP__A                                     0xC20048
+#define FE_AG_REG_PDC_SLO_STP__A                                     0xC20049
+#define FE_AG_REG_PDC_PD2_WRI__A                                     0xC2004A
+#define FE_AG_REG_PDC_MAP_DAT__A                                     0xC2004B
+#define FE_AG_REG_PDC_MAX__A                                         0xC2004C
+#define FE_AG_REG_TGA_AUR_CNT__A                                     0xC2004D
+#define FE_AG_REG_TGA_RUR_CNT__A                                     0xC2004E
+#define FE_AG_REG_TGA_AVE_DAT__A                                     0xC2004F
+#define FE_AG_REG_TGC_RUR_CNT__A                                     0xC20050
+#define FE_AG_REG_TGC_SET_LVL__A                                     0xC20051
+#define FE_AG_REG_TGC_SET_LVL__M                                     0x3F
+#define FE_AG_REG_TGC_FLA_RGN__A                                     0xC20052
+#define FE_AG_REG_TGC_JMP_PSN__A                                     0xC20053
+#define FE_AG_REG_TGC_FLA_STP__A                                     0xC20054
+#define FE_AG_REG_TGC_SLO_STP__A                                     0xC20055
+#define FE_AG_REG_TGC_MAP_DAT__A                                     0xC20056
+#define FE_AG_REG_FGA_AUR_CNT__A                                     0xC20057
+#define FE_AG_REG_FGA_RUR_CNT__A                                     0xC20058
+#define FE_AG_REG_FGM_WRI__A                                         0xC20061
+#define FE_AG_REG_BGC_FGC_WRI__A                                     0xC20068
+#define FE_AG_REG_BGC_CGC_WRI__A                                     0xC20069
+#define FE_FS_REG_COMM_EXEC__A                                       0xC30000
+#define FE_FS_REG_ADD_INC_LOP__A                                     0xC30010
+#define FE_FD_REG_COMM_EXEC__A                                       0xC40000
+#define FE_FD_REG_SCL__A                                             0xC40010
+#define FE_FD_REG_MAX_LEV__A                                         0xC40011
+#define FE_FD_REG_NR__A                                              0xC40012
+#define FE_FD_REG_MEAS_VAL__A                                        0xC40014
+#define FE_IF_REG_COMM_EXEC__A                                       0xC50000
+#define FE_IF_REG_INCR0__A                                           0xC50010
+#define FE_IF_REG_INCR0__W                                           16
+#define FE_IF_REG_INCR0__M                                           0xFFFF
+#define FE_IF_REG_INCR1__A                                           0xC50011
+#define FE_IF_REG_INCR1__M                                           0xFF
+#define FE_CF_REG_COMM_EXEC__A                                       0xC60000
+#define FE_CF_REG_SCL__A                                             0xC60010
+#define FE_CF_REG_MAX_LEV__A                                         0xC60011
+#define FE_CF_REG_NR__A                                              0xC60012
+#define FE_CF_REG_IMP_VAL__A                                         0xC60013
+#define FE_CF_REG_MEAS_VAL__A                                        0xC60014
+#define FE_CU_REG_COMM_EXEC__A                                       0xC70000
+#define FE_CU_REG_FRM_CNT_RST__A                                     0xC70011
+#define FE_CU_REG_FRM_CNT_STR__A                                     0xC70012
+#define FT_COMM_EXEC__A                                              0x1000000
+#define FT_REG_COMM_EXEC__A                                          0x1010000
+#define CP_COMM_EXEC__A                                              0x1400000
+#define CP_REG_COMM_EXEC__A                                          0x1410000
+#define CP_REG_INTERVAL__A                                           0x1410011
+#define CP_REG_BR_SPL_OFFSET__A                                      0x1410023
+#define CP_REG_BR_STR_DEL__A                                         0x1410024
+#define CP_REG_RT_ANG_INC0__A                                        0x1410030
+#define CP_REG_RT_ANG_INC1__A                                        0x1410031
+#define CP_REG_RT_DETECT_ENA__A                                      0x1410032
+#define CP_REG_RT_DETECT_TRH__A                                      0x1410033
+#define CP_REG_RT_EXP_MARG__A                                        0x141003E
+#define CP_REG_AC_NEXP_OFFS__A                                       0x1410040
+#define CP_REG_AC_AVER_POW__A                                        0x1410041
+#define CP_REG_AC_MAX_POW__A                                         0x1410042
+#define CP_REG_AC_WEIGHT_MAN__A                                      0x1410043
+#define CP_REG_AC_WEIGHT_EXP__A                                      0x1410044
+#define CP_REG_AC_AMP_MODE__A                                        0x1410047
+#define CP_REG_AC_AMP_FIX__A                                         0x1410048
+#define CP_REG_AC_ANG_MODE__A                                        0x141004A
+#define CE_COMM_EXEC__A                                              0x1800000
+#define CE_REG_COMM_EXEC__A                                          0x1810000
+#define CE_REG_TAPSET__A                                             0x1810011
+#define CE_REG_AVG_POW__A                                            0x1810012
+#define CE_REG_MAX_POW__A                                            0x1810013
+#define CE_REG_ATT__A                                                0x1810014
+#define CE_REG_NRED__A                                               0x1810015
+#define CE_REG_NE_ERR_SELECT__A                                      0x1810043
+#define CE_REG_NE_TD_CAL__A                                          0x1810044
+#define CE_REG_NE_MIXAVG__A                                          0x1810046
+#define CE_REG_NE_NUPD_OFS__A                                        0x1810047
+#define CE_REG_PE_NEXP_OFFS__A                                       0x1810050
+#define CE_REG_PE_TIMESHIFT__A                                       0x1810051
+#define CE_REG_TP_A0_TAP_NEW__A                                      0x1810064
+#define CE_REG_TP_A0_TAP_NEW_VALID__A                                0x1810065
+#define CE_REG_TP_A0_MU_LMS_STEP__A                                  0x1810066
+#define CE_REG_TP_A1_TAP_NEW__A                                      0x1810068
+#define CE_REG_TP_A1_TAP_NEW_VALID__A                                0x1810069
+#define CE_REG_TP_A1_MU_LMS_STEP__A                                  0x181006A
+#define CE_REG_TI_NEXP_OFFS__A                                       0x1810070
+#define CE_REG_FI_SHT_INCR__A                                        0x1810090
+#define CE_REG_FI_EXP_NORM__A                                        0x1810091
+#define CE_REG_IR_INPUTSEL__A                                        0x18100A0
+#define CE_REG_IR_STARTPOS__A                                        0x18100A1
+#define CE_REG_IR_NEXP_THRES__A                                      0x18100A2
+#define CE_REG_FR_TREAL00__A                                         0x1820010
+#define CE_REG_FR_TIMAG00__A                                         0x1820011
+#define CE_REG_FR_TREAL01__A                                         0x1820012
+#define CE_REG_FR_TIMAG01__A                                         0x1820013
+#define CE_REG_FR_TREAL02__A                                         0x1820014
+#define CE_REG_FR_TIMAG02__A                                         0x1820015
+#define CE_REG_FR_TREAL03__A                                         0x1820016
+#define CE_REG_FR_TIMAG03__A                                         0x1820017
+#define CE_REG_FR_TREAL04__A                                         0x1820018
+#define CE_REG_FR_TIMAG04__A                                         0x1820019
+#define CE_REG_FR_TREAL05__A                                         0x182001A
+#define CE_REG_FR_TIMAG05__A                                         0x182001B
+#define CE_REG_FR_TREAL06__A                                         0x182001C
+#define CE_REG_FR_TIMAG06__A                                         0x182001D
+#define CE_REG_FR_TREAL07__A                                         0x182001E
+#define CE_REG_FR_TIMAG07__A                                         0x182001F
+#define CE_REG_FR_TREAL08__A                                         0x1820020
+#define CE_REG_FR_TIMAG08__A                                         0x1820021
+#define CE_REG_FR_TREAL09__A                                         0x1820022
+#define CE_REG_FR_TIMAG09__A                                         0x1820023
+#define CE_REG_FR_TREAL10__A                                         0x1820024
+#define CE_REG_FR_TIMAG10__A                                         0x1820025
+#define CE_REG_FR_TREAL11__A                                         0x1820026
+#define CE_REG_FR_TIMAG11__A                                         0x1820027
+#define CE_REG_FR_MID_TAP__A                                         0x1820028
+#define CE_REG_FR_SQS_G00__A                                         0x1820029
+#define CE_REG_FR_SQS_G01__A                                         0x182002A
+#define CE_REG_FR_SQS_G02__A                                         0x182002B
+#define CE_REG_FR_SQS_G03__A                                         0x182002C
+#define CE_REG_FR_SQS_G04__A                                         0x182002D
+#define CE_REG_FR_SQS_G05__A                                         0x182002E
+#define CE_REG_FR_SQS_G06__A                                         0x182002F
+#define CE_REG_FR_SQS_G07__A                                         0x1820030
+#define CE_REG_FR_SQS_G08__A                                         0x1820031
+#define CE_REG_FR_SQS_G09__A                                         0x1820032
+#define CE_REG_FR_SQS_G10__A                                         0x1820033
+#define CE_REG_FR_SQS_G11__A                                         0x1820034
+#define CE_REG_FR_SQS_G12__A                                         0x1820035
+#define CE_REG_FR_RIO_G00__A                                         0x1820036
+#define CE_REG_FR_RIO_G01__A                                         0x1820037
+#define CE_REG_FR_RIO_G02__A                                         0x1820038
+#define CE_REG_FR_RIO_G03__A                                         0x1820039
+#define CE_REG_FR_RIO_G04__A                                         0x182003A
+#define CE_REG_FR_RIO_G05__A                                         0x182003B
+#define CE_REG_FR_RIO_G06__A                                         0x182003C
+#define CE_REG_FR_RIO_G07__A                                         0x182003D
+#define CE_REG_FR_RIO_G08__A                                         0x182003E
+#define CE_REG_FR_RIO_G09__A                                         0x182003F
+#define CE_REG_FR_RIO_G10__A                                         0x1820040
+#define CE_REG_FR_MODE__A                                            0x1820041
+#define CE_REG_FR_SQS_TRH__A                                         0x1820042
+#define CE_REG_FR_RIO_GAIN__A                                        0x1820043
+#define CE_REG_FR_BYPASS__A                                          0x1820044
+#define CE_REG_FR_PM_SET__A                                          0x1820045
+#define CE_REG_FR_ERR_SH__A                                          0x1820046
+#define CE_REG_FR_MAN_SH__A                                          0x1820047
+#define CE_REG_FR_TAP_SH__A                                          0x1820048
+#define EQ_COMM_EXEC__A                                              0x1C00000
+#define EQ_REG_COMM_EXEC__A                                          0x1C10000
+#define EQ_REG_COMM_MB__A                                            0x1C10002
+#define EQ_REG_IS_GAIN_MAN__A                                        0x1C10015
+#define EQ_REG_IS_GAIN_EXP__A                                        0x1C10016
+#define EQ_REG_IS_CLIP_EXP__A                                        0x1C10017
+#define EQ_REG_SN_CEGAIN__A                                          0x1C1002A
+#define EQ_REG_SN_OFFSET__A                                          0x1C1002B
+#define EQ_REG_RC_SEL_CAR__A                                         0x1C10032
+#define   EQ_REG_RC_SEL_CAR_INIT                                     0x0
+#define     EQ_REG_RC_SEL_CAR_DIV_ON                                 0x1
+#define     EQ_REG_RC_SEL_CAR_PASS_A_CC                              0x0
+#define     EQ_REG_RC_SEL_CAR_PASS_B_CE                              0x2
+#define     EQ_REG_RC_SEL_CAR_LOCAL_A_CC                             0x0
+#define     EQ_REG_RC_SEL_CAR_LOCAL_B_CE                             0x8
+#define     EQ_REG_RC_SEL_CAR_MEAS_A_CC                              0x0
+#define     EQ_REG_RC_SEL_CAR_MEAS_B_CE                              0x20
+#define EQ_REG_OT_CONST__A                                           0x1C10046
+#define EQ_REG_OT_ALPHA__A                                           0x1C10047
+#define EQ_REG_OT_QNT_THRES0__A                                      0x1C10048
+#define EQ_REG_OT_QNT_THRES1__A                                      0x1C10049
+#define EQ_REG_OT_CSI_STEP__A                                        0x1C1004A
+#define EQ_REG_OT_CSI_OFFSET__A                                      0x1C1004B
+#define EQ_REG_TD_REQ_SMB_CNT__A                                     0x1C10061
+#define EQ_REG_TD_TPS_PWR_OFS__A                                     0x1C10062
+#define EC_SB_REG_COMM_EXEC__A                                       0x2010000
+#define EC_SB_REG_TR_MODE__A                                         0x2010010
+#define   EC_SB_REG_TR_MODE_8K                                       0x0
+#define   EC_SB_REG_TR_MODE_2K                                       0x1
+#define EC_SB_REG_CONST__A                                           0x2010011
+#define   EC_SB_REG_CONST_QPSK                                       0x0
+#define   EC_SB_REG_CONST_16QAM                                      0x1
+#define   EC_SB_REG_CONST_64QAM                                      0x2
+#define EC_SB_REG_ALPHA__A                                           0x2010012
+#define EC_SB_REG_PRIOR__A                                           0x2010013
+#define   EC_SB_REG_PRIOR_HI                                         0x0
+#define   EC_SB_REG_PRIOR_LO                                         0x1
+#define EC_SB_REG_CSI_HI__A                                          0x2010014
+#define EC_SB_REG_CSI_LO__A                                          0x2010015
+#define EC_SB_REG_SMB_TGL__A                                         0x2010016
+#define EC_SB_REG_SNR_HI__A                                          0x2010017
+#define EC_SB_REG_SNR_MID__A                                         0x2010018
+#define EC_SB_REG_SNR_LO__A                                          0x2010019
+#define EC_SB_REG_SCALE_MSB__A                                       0x201001A
+#define EC_SB_REG_SCALE_BIT2__A                                      0x201001B
+#define EC_SB_REG_SCALE_LSB__A                                       0x201001C
+#define EC_SB_REG_CSI_OFS__A                                         0x201001D
+#define EC_VD_REG_COMM_EXEC__A                                       0x2090000
+#define EC_VD_REG_FORCE__A                                           0x2090010
+#define EC_VD_REG_SET_CODERATE__A                                    0x2090011
+#define   EC_VD_REG_SET_CODERATE_C1_2                                0x0
+#define   EC_VD_REG_SET_CODERATE_C2_3                                0x1
+#define   EC_VD_REG_SET_CODERATE_C3_4                                0x2
+#define   EC_VD_REG_SET_CODERATE_C5_6                                0x3
+#define   EC_VD_REG_SET_CODERATE_C7_8                                0x4
+#define EC_VD_REG_REQ_SMB_CNT__A                                     0x2090012
+#define EC_VD_REG_RLK_ENA__A                                         0x2090014
+#define EC_OD_REG_COMM_EXEC__A                                       0x2110000
+#define EC_OD_REG_SYNC__A                                            0x2110010
+#define EC_OD_DEINT_RAM__A                                           0x2120000
+#define EC_RS_REG_COMM_EXEC__A                                       0x2130000
+#define EC_RS_REG_REQ_PCK_CNT__A                                     0x2130010
+#define EC_RS_REG_VAL__A                                             0x2130011
+#define   EC_RS_REG_VAL_PCK                                          0x1
+#define EC_RS_EC_RAM__A                                              0x2140000
+#define EC_OC_REG_COMM_EXEC__A                                       0x2150000
+#define     EC_OC_REG_COMM_EXEC_CTL_ACTIVE                           0x1
+#define     EC_OC_REG_COMM_EXEC_CTL_HOLD                             0x2
+#define EC_OC_REG_COMM_INT_STA__A                                    0x2150007
+#define EC_OC_REG_OC_MODE_LOP__A                                     0x2150010
+#define   EC_OC_REG_OC_MODE_LOP_PAR_ENA__M                           0x1
+#define     EC_OC_REG_OC_MODE_LOP_PAR_ENA_ENABLE                     0x0
+#define     EC_OC_REG_OC_MODE_LOP_PAR_ENA_DISABLE                    0x1
+#define   EC_OC_REG_OC_MODE_LOP_DTO_CTR_SRC__M                       0x4
+#define     EC_OC_REG_OC_MODE_LOP_DTO_CTR_SRC_STATIC                 0x0
+#define   EC_OC_REG_OC_MODE_LOP_MPG_TRM_MDE__M                       0x80
+#define     EC_OC_REG_OC_MODE_LOP_MPG_TRM_MDE_SERIAL                 0x80
+#define EC_OC_REG_OC_MODE_HIP__A                                     0x2150011
+#define     EC_OC_REG_OC_MODE_HIP_MPG_BUS_SRC_MONITOR                0x10
+#define   EC_OC_REG_OC_MODE_HIP_MPG_PAR_VAL__M                       0x200
+#define     EC_OC_REG_OC_MODE_HIP_MPG_PAR_VAL_DISABLE                0x0
+#define     EC_OC_REG_OC_MODE_HIP_MPG_PAR_VAL_ENABLE                 0x200
+#define EC_OC_REG_OC_MPG_SIO__A                                      0x2150012
+#define EC_OC_REG_OC_MPG_SIO__M                                      0xFFF
+#define EC_OC_REG_OC_MON_SIO__A                                      0x2150013
+#define EC_OC_REG_DTO_INC_LOP__A                                     0x2150014
+#define EC_OC_REG_DTO_INC_HIP__A                                     0x2150015
+#define EC_OC_REG_SNC_ISC_LVL__A                                     0x2150016
+#define   EC_OC_REG_SNC_ISC_LVL_OSC__M                               0xF0
+#define EC_OC_REG_TMD_TOP_MODE__A                                    0x215001D
+#define EC_OC_REG_TMD_TOP_CNT__A                                     0x215001E
+#define EC_OC_REG_TMD_HIL_MAR__A                                     0x215001F
+#define EC_OC_REG_TMD_LOL_MAR__A                                     0x2150020
+#define EC_OC_REG_TMD_CUR_CNT__A                                     0x2150021
+#define EC_OC_REG_AVR_ASH_CNT__A                                     0x2150023
+#define EC_OC_REG_AVR_BSH_CNT__A                                     0x2150024
+#define EC_OC_REG_RCN_MODE__A                                        0x2150027
+#define EC_OC_REG_RCN_CRA_LOP__A                                     0x2150028
+#define EC_OC_REG_RCN_CRA_HIP__A                                     0x2150029
+#define EC_OC_REG_RCN_CST_LOP__A                                     0x215002A
+#define EC_OC_REG_RCN_CST_HIP__A                                     0x215002B
+#define EC_OC_REG_RCN_SET_LVL__A                                     0x215002C
+#define EC_OC_REG_RCN_GAI_LVL__A                                     0x215002D
+#define EC_OC_REG_RCN_CLP_LOP__A                                     0x2150032
+#define EC_OC_REG_RCN_CLP_HIP__A                                     0x2150033
+#define EC_OC_REG_RCN_MAP_LOP__A                                     0x2150034
+#define EC_OC_REG_RCN_MAP_HIP__A                                     0x2150035
+#define EC_OC_REG_OCR_MPG_UOS__A                                     0x2150036
+#define EC_OC_REG_OCR_MPG_UOS__M                                     0xFFF
+#define   EC_OC_REG_OCR_MPG_UOS_INIT                                 0x0
+#define EC_OC_REG_OCR_MPG_USR_DAT__A                                 0x2150038
+#define EC_OC_REG_OCR_MON_UOS__A                                     0x2150039
+#define     EC_OC_REG_OCR_MON_UOS_DAT_0_ENABLE                       0x1
+#define     EC_OC_REG_OCR_MON_UOS_DAT_1_ENABLE                       0x2
+#define     EC_OC_REG_OCR_MON_UOS_DAT_2_ENABLE                       0x4
+#define     EC_OC_REG_OCR_MON_UOS_DAT_3_ENABLE                       0x8
+#define     EC_OC_REG_OCR_MON_UOS_DAT_4_ENABLE                       0x10
+#define     EC_OC_REG_OCR_MON_UOS_DAT_5_ENABLE                       0x20
+#define     EC_OC_REG_OCR_MON_UOS_DAT_6_ENABLE                       0x40
+#define     EC_OC_REG_OCR_MON_UOS_DAT_7_ENABLE                       0x80
+#define     EC_OC_REG_OCR_MON_UOS_DAT_8_ENABLE                       0x100
+#define     EC_OC_REG_OCR_MON_UOS_DAT_9_ENABLE                       0x200
+#define     EC_OC_REG_OCR_MON_UOS_VAL_ENABLE                         0x400
+#define     EC_OC_REG_OCR_MON_UOS_CLK_ENABLE                         0x800
+#define EC_OC_REG_OCR_MON_WRI__A                                     0x215003A
+#define   EC_OC_REG_OCR_MON_WRI_INIT                                 0x0
+#define EC_OC_REG_IPR_INV_MPG__A                                     0x2150045
+#define CC_REG_OSC_MODE__A                                           0x2410010
+#define   CC_REG_OSC_MODE_M20                                        0x1
+#define CC_REG_PLL_MODE__A                                           0x2410011
+#define     CC_REG_PLL_MODE_BYPASS_PLL                               0x1
+#define     CC_REG_PLL_MODE_PUMP_CUR_12                              0x14
+#define CC_REG_REF_DIVIDE__A                                         0x2410012
+#define CC_REG_PWD_MODE__A                                           0x2410015
+#define   CC_REG_PWD_MODE_DOWN_PLL                                   0x2
+#define CC_REG_UPDATE__A                                             0x2410017
+#define   CC_REG_UPDATE_KEY                                          0x3973
+#define CC_REG_JTAGID_L__A                                           0x2410019
+#define LC_COMM_EXEC__A                                              0x2800000
+#define LC_RA_RAM_IFINCR_NOM_L__A                                    0x282000C
+#define LC_RA_RAM_FILTER_SYM_SET__A                                  0x282001A
+#define LC_RA_RAM_FILTER_SYM_SET__PRE                                0x3E8
+#define LC_RA_RAM_FILTER_CRMM_A__A                                   0x2820060
+#define LC_RA_RAM_FILTER_CRMM_A__PRE                                 0x4
+#define LC_RA_RAM_FILTER_CRMM_B__A                                   0x2820061
+#define LC_RA_RAM_FILTER_CRMM_B__PRE                                 0x1
+#define LC_RA_RAM_FILTER_SRMM_A__A                                   0x2820068
+#define LC_RA_RAM_FILTER_SRMM_A__PRE                                 0x4
+#define LC_RA_RAM_FILTER_SRMM_B__A                                   0x2820069
+#define LC_RA_RAM_FILTER_SRMM_B__PRE                                 0x1
+#define B_HI_COMM_EXEC__A                                            0x400000
+#define B_HI_COMM_MB__A                                              0x400002
+#define B_HI_CT_REG_COMM_STATE__A                                    0x410001
+#define B_HI_RA_RAM_SRV_RES__A                                       0x420031
+#define B_HI_RA_RAM_SRV_CMD__A                                       0x420032
+#define   B_HI_RA_RAM_SRV_CMD_RESET                                  0x2
+#define   B_HI_RA_RAM_SRV_CMD_CONFIG                                 0x3
+#define   B_HI_RA_RAM_SRV_CMD_EXECUTE                                0x6
+#define B_HI_RA_RAM_SRV_RST_KEY__A                                   0x420033
+#define   B_HI_RA_RAM_SRV_RST_KEY_ACT                                0x3973
+#define B_HI_RA_RAM_SRV_CFG_KEY__A                                   0x420033
+#define B_HI_RA_RAM_SRV_CFG_DIV__A                                   0x420034
+#define B_HI_RA_RAM_SRV_CFG_BDL__A                                   0x420035
+#define B_HI_RA_RAM_SRV_CFG_WUP__A                                   0x420036
+#define B_HI_RA_RAM_SRV_CFG_ACT__A                                   0x420037
+#define     B_HI_RA_RAM_SRV_CFG_ACT_SLV0_ON                          0x1
+#define   B_HI_RA_RAM_SRV_CFG_ACT_BRD__M                             0x4
+#define     B_HI_RA_RAM_SRV_CFG_ACT_BRD_OFF                          0x0
+#define     B_HI_RA_RAM_SRV_CFG_ACT_BRD_ON                           0x4
+#define     B_HI_RA_RAM_SRV_CFG_ACT_PWD_EXE                          0x8
+#define B_HI_RA_RAM_USR_BEGIN__A                                     0x420040
+#define B_HI_IF_RAM_TRP_BPT0__AX                                     0x430000
+#define B_HI_IF_RAM_USR_BEGIN__A                                     0x430200
+#define B_SC_COMM_EXEC__A                                            0x800000
+#define     B_SC_COMM_EXEC_CTL_STOP                                  0x0
+#define B_SC_COMM_STATE__A                                           0x800001
+#define B_SC_RA_RAM_PARAM0__A                                        0x820040
+#define B_SC_RA_RAM_PARAM1__A                                        0x820041
+#define B_SC_RA_RAM_CMD_ADDR__A                                      0x820042
+#define B_SC_RA_RAM_CMD__A                                           0x820043
+#define   B_SC_RA_RAM_CMD_PROC_START                                 0x1
+#define   B_SC_RA_RAM_CMD_SET_PREF_PARAM                             0x3
+#define   B_SC_RA_RAM_CMD_GET_OP_PARAM                               0x5
+#define   B_SC_RA_RAM_SW_EVENT_RUN_NMASK__M                          0x1
+#define   B_SC_RA_RAM_LOCKTRACK_MIN                                  0x1
+#define     B_SC_RA_RAM_OP_PARAM_MODE_2K                             0x0
+#define     B_SC_RA_RAM_OP_PARAM_MODE_8K                             0x1
+#define     B_SC_RA_RAM_OP_PARAM_GUARD_32                            0x0
+#define     B_SC_RA_RAM_OP_PARAM_GUARD_16                            0x4
+#define     B_SC_RA_RAM_OP_PARAM_GUARD_8                             0x8
+#define     B_SC_RA_RAM_OP_PARAM_GUARD_4                             0xC
+#define     B_SC_RA_RAM_OP_PARAM_CONST_QPSK                          0x0
+#define     B_SC_RA_RAM_OP_PARAM_CONST_QAM16                         0x10
+#define     B_SC_RA_RAM_OP_PARAM_CONST_QAM64                         0x20
+#define     B_SC_RA_RAM_OP_PARAM_HIER_NO                             0x0
+#define     B_SC_RA_RAM_OP_PARAM_HIER_A1                             0x40
+#define     B_SC_RA_RAM_OP_PARAM_HIER_A2                             0x80
+#define     B_SC_RA_RAM_OP_PARAM_HIER_A4                             0xC0
+#define     B_SC_RA_RAM_OP_PARAM_RATE_1_2                            0x0
+#define     B_SC_RA_RAM_OP_PARAM_RATE_2_3                            0x200
+#define     B_SC_RA_RAM_OP_PARAM_RATE_3_4                            0x400
+#define     B_SC_RA_RAM_OP_PARAM_RATE_5_6                            0x600
+#define     B_SC_RA_RAM_OP_PARAM_RATE_7_8                            0x800
+#define     B_SC_RA_RAM_OP_PARAM_PRIO_HI                             0x0
+#define     B_SC_RA_RAM_OP_PARAM_PRIO_LO                             0x1000
+#define   B_SC_RA_RAM_OP_AUTO_MODE__M                                0x1
+#define   B_SC_RA_RAM_OP_AUTO_GUARD__M                               0x2
+#define   B_SC_RA_RAM_OP_AUTO_CONST__M                               0x4
+#define   B_SC_RA_RAM_OP_AUTO_HIER__M                                0x8
+#define   B_SC_RA_RAM_OP_AUTO_RATE__M                                0x10
+#define B_SC_RA_RAM_LOCK__A                                          0x82004B
+#define   B_SC_RA_RAM_LOCK_DEMOD__M                                  0x1
+#define   B_SC_RA_RAM_LOCK_FEC__M                                    0x2
+#define   B_SC_RA_RAM_LOCK_MPEG__M                                   0x4
+#define B_SC_RA_RAM_BE_OPT_ENA__A                                    0x82004C
+#define   B_SC_RA_RAM_BE_OPT_ENA_CP_OPT                              0x1
+#define B_SC_RA_RAM_BE_OPT_DELAY__A                                  0x82004D
+#define B_SC_RA_RAM_CONFIG__A                                        0x820050
+#define   B_SC_RA_RAM_CONFIG_FR_ENABLE__M                            0x4
+#define   B_SC_RA_RAM_CONFIG_FREQSCAN__M                             0x10
+#define   B_SC_RA_RAM_CONFIG_SLAVE__M                                0x20
+#define   B_SC_RA_RAM_CONFIG_DIV_BLANK_ENABLE__M                     0x200
+#define   B_SC_RA_RAM_CONFIG_DIV_ECHO_ENABLE__M                      0x400
+#define B_SC_RA_RAM_CO_TD_CAL_2K__A                                  0x82005D
+#define B_SC_RA_RAM_CO_TD_CAL_8K__A                                  0x82005E
+#define B_SC_RA_RAM_IF_SAVE__AX                                      0x82008E
+#define B_SC_RA_RAM_DIVERSITY_DELAY_2K_32__A                         0x820098
+#define B_SC_RA_RAM_DIVERSITY_DELAY_2K_16__A                         0x820099
+#define B_SC_RA_RAM_DIVERSITY_DELAY_2K_8__A                          0x82009A
+#define B_SC_RA_RAM_DIVERSITY_DELAY_2K_4__A                          0x82009B
+#define B_SC_RA_RAM_DIVERSITY_DELAY_8K_32__A                         0x82009C
+#define B_SC_RA_RAM_DIVERSITY_DELAY_8K_16__A                         0x82009D
+#define B_SC_RA_RAM_DIVERSITY_DELAY_8K_8__A                          0x82009E
+#define B_SC_RA_RAM_DIVERSITY_DELAY_8K_4__A                          0x82009F
+#define B_SC_RA_RAM_IR_COARSE_2K_LENGTH__A                           0x8200D1
+#define B_SC_RA_RAM_IR_COARSE_2K_LENGTH__PRE                         0x9
+#define B_SC_RA_RAM_IR_COARSE_2K_FREQINC__A                          0x8200D2
+#define B_SC_RA_RAM_IR_COARSE_2K_FREQINC__PRE                        0x4
+#define B_SC_RA_RAM_IR_COARSE_2K_KAISINC__A                          0x8200D3
+#define B_SC_RA_RAM_IR_COARSE_2K_KAISINC__PRE                        0x100
+#define B_SC_RA_RAM_IR_COARSE_8K_LENGTH__A                           0x8200D4
+#define B_SC_RA_RAM_IR_COARSE_8K_LENGTH__PRE                         0x8
+#define B_SC_RA_RAM_IR_COARSE_8K_FREQINC__A                          0x8200D5
+#define B_SC_RA_RAM_IR_COARSE_8K_FREQINC__PRE                        0x8
+#define B_SC_RA_RAM_IR_COARSE_8K_KAISINC__A                          0x8200D6
+#define B_SC_RA_RAM_IR_COARSE_8K_KAISINC__PRE                        0x200
+#define B_SC_RA_RAM_IR_FINE_2K_LENGTH__A                             0x8200D7
+#define B_SC_RA_RAM_IR_FINE_2K_LENGTH__PRE                           0x9
+#define B_SC_RA_RAM_IR_FINE_2K_FREQINC__A                            0x8200D8
+#define B_SC_RA_RAM_IR_FINE_2K_FREQINC__PRE                          0x4
+#define B_SC_RA_RAM_IR_FINE_2K_KAISINC__A                            0x8200D9
+#define B_SC_RA_RAM_IR_FINE_2K_KAISINC__PRE                          0x100
+#define B_SC_RA_RAM_IR_FINE_8K_LENGTH__A                             0x8200DA
+#define B_SC_RA_RAM_IR_FINE_8K_LENGTH__PRE                           0xB
+#define B_SC_RA_RAM_IR_FINE_8K_FREQINC__A                            0x8200DB
+#define B_SC_RA_RAM_IR_FINE_8K_FREQINC__PRE                          0x1
+#define B_SC_RA_RAM_IR_FINE_8K_KAISINC__A                            0x8200DC
+#define B_SC_RA_RAM_IR_FINE_8K_KAISINC__PRE                          0x40
+#define B_SC_RA_RAM_ECHO_SHIFT_LIM__A                                0x8200DD
+#define B_SC_RA_RAM_SAMPLE_RATE_COUNT__A                             0x8200E8
+#define B_SC_RA_RAM_SAMPLE_RATE_STEP__A                              0x8200E9
+#define B_SC_RA_RAM_BAND__A                                          0x8200EC
+#define B_SC_RA_RAM_LC_ABS_2K__A                                     0x8200F4
+#define B_SC_RA_RAM_LC_ABS_2K__PRE                                   0x1F
+#define B_SC_RA_RAM_LC_ABS_8K__A                                     0x8200F5
+#define B_SC_RA_RAM_LC_ABS_8K__PRE                                   0x1F
+#define B_SC_RA_RAM_EQ_IS_GAIN_UNKNOWN_MAN__PRE                      0x100
+#define B_SC_RA_RAM_EQ_IS_GAIN_UNKNOWN_EXP__PRE                      0x4
+#define B_SC_RA_RAM_EQ_IS_GAIN_QPSK_MAN__PRE                         0x1E2
+#define B_SC_RA_RAM_EQ_IS_GAIN_QPSK_EXP__PRE                         0x4
+#define B_SC_RA_RAM_EQ_IS_GAIN_16QAM_MAN__PRE                        0x10D
+#define B_SC_RA_RAM_EQ_IS_GAIN_16QAM_EXP__PRE                        0x5
+#define B_SC_RA_RAM_EQ_IS_GAIN_16QAM_A2_MAN__PRE                     0x17D
+#define B_SC_RA_RAM_EQ_IS_GAIN_16QAM_A2_EXP__PRE                     0x4
+#define B_SC_RA_RAM_EQ_IS_GAIN_16QAM_A4_MAN__PRE                     0x133
+#define B_SC_RA_RAM_EQ_IS_GAIN_16QAM_A4_EXP__PRE                     0x5
+#define B_SC_RA_RAM_EQ_IS_GAIN_64QAM_MAN__PRE                        0x114
+#define B_SC_RA_RAM_EQ_IS_GAIN_64QAM_EXP__PRE                        0x5
+#define B_SC_RA_RAM_EQ_IS_GAIN_64QAM_A2_MAN__PRE                     0x14A
+#define B_SC_RA_RAM_EQ_IS_GAIN_64QAM_A2_EXP__PRE                     0x4
+#define B_SC_RA_RAM_EQ_IS_GAIN_64QAM_A4_MAN__PRE                     0x1BB
+#define B_SC_RA_RAM_EQ_IS_GAIN_64QAM_A4_EXP__PRE                     0x4
+#define B_SC_RA_RAM_DRIVER_VERSION__AX                               0x8201FE
+#define   B_SC_RA_RAM_PROC_LOCKTRACK                                 0x0
+#define B_FE_COMM_EXEC__A                                            0xC00000
+#define B_FE_AD_REG_COMM_EXEC__A                                     0xC10000
+#define B_FE_AD_REG_FDB_IN__A                                        0xC10012
+#define B_FE_AD_REG_PD__A                                            0xC10013
+#define B_FE_AD_REG_INVEXT__A                                        0xC10014
+#define B_FE_AD_REG_CLKNEG__A                                        0xC10015
+#define B_FE_AG_REG_COMM_EXEC__A                                     0xC20000
+#define B_FE_AG_REG_AG_MODE_LOP__A                                   0xC20010
+#define   B_FE_AG_REG_AG_MODE_LOP_MODE_4__M                          0x10
+#define     B_FE_AG_REG_AG_MODE_LOP_MODE_4_STATIC                    0x0
+#define     B_FE_AG_REG_AG_MODE_LOP_MODE_4_DYNAMIC                   0x10
+#define   B_FE_AG_REG_AG_MODE_LOP_MODE_5__M                          0x20
+#define     B_FE_AG_REG_AG_MODE_LOP_MODE_5_STATIC                    0x0
+#define   B_FE_AG_REG_AG_MODE_LOP_MODE_C__M                          0x1000
+#define     B_FE_AG_REG_AG_MODE_LOP_MODE_C_STATIC                    0x0
+#define     B_FE_AG_REG_AG_MODE_LOP_MODE_C_DYNAMIC                   0x1000
+#define   B_FE_AG_REG_AG_MODE_LOP_MODE_E__M                          0x4000
+#define     B_FE_AG_REG_AG_MODE_LOP_MODE_E_STATIC                    0x0
+#define     B_FE_AG_REG_AG_MODE_LOP_MODE_E_DYNAMIC                   0x4000
+#define B_FE_AG_REG_AG_MODE_HIP__A                                   0xC20011
+#define   B_FE_AG_REG_AG_MODE_HIP_MODE_J__M                          0x8
+#define     B_FE_AG_REG_AG_MODE_HIP_MODE_J_STATIC                    0x0
+#define     B_FE_AG_REG_AG_MODE_HIP_MODE_J_DYNAMIC                   0x8
+#define B_FE_AG_REG_AG_PGA_MODE__A                                   0xC20012
+#define   B_FE_AG_REG_AG_PGA_MODE_PFY_PCY_AFY_REN                    0x0
+#define   B_FE_AG_REG_AG_PGA_MODE_PFN_PCN_AFY_REN                    0x1
+#define B_FE_AG_REG_AG_AGC_SIO__A                                    0xC20013
+#define   B_FE_AG_REG_AG_AGC_SIO_AGC_SIO_2__M                        0x2
+#define     B_FE_AG_REG_AG_AGC_SIO_AGC_SIO_2_OUTPUT                  0x0
+#define     B_FE_AG_REG_AG_AGC_SIO_AGC_SIO_2_INPUT                   0x2
+#define B_FE_AG_REG_AG_PWD__A                                        0xC20015
+#define   B_FE_AG_REG_AG_PWD_PWD_PD2__M                              0x2
+#define     B_FE_AG_REG_AG_PWD_PWD_PD2_DISABLE                       0x0
+#define     B_FE_AG_REG_AG_PWD_PWD_PD2_ENABLE                        0x2
+#define B_FE_AG_REG_DCE_AUR_CNT__A                                   0xC20016
+#define B_FE_AG_REG_DCE_RUR_CNT__A                                   0xC20017
+#define B_FE_AG_REG_ACE_AUR_CNT__A                                   0xC2001A
+#define B_FE_AG_REG_ACE_RUR_CNT__A                                   0xC2001B
+#define B_FE_AG_REG_CDR_RUR_CNT__A                                   0xC20020
+#define B_FE_AG_REG_EGC_RUR_CNT__A                                   0xC20024
+#define B_FE_AG_REG_EGC_SET_LVL__A                                   0xC20025
+#define B_FE_AG_REG_EGC_SET_LVL__M                                   0x1FF
+#define B_FE_AG_REG_EGC_FLA_RGN__A                                   0xC20026
+#define B_FE_AG_REG_EGC_SLO_RGN__A                                   0xC20027
+#define B_FE_AG_REG_EGC_JMP_PSN__A                                   0xC20028
+#define B_FE_AG_REG_EGC_FLA_INC__A                                   0xC20029
+#define B_FE_AG_REG_EGC_FLA_DEC__A                                   0xC2002A
+#define B_FE_AG_REG_EGC_SLO_INC__A                                   0xC2002B
+#define B_FE_AG_REG_EGC_SLO_DEC__A                                   0xC2002C
+#define B_FE_AG_REG_EGC_FAS_INC__A                                   0xC2002D
+#define B_FE_AG_REG_EGC_FAS_DEC__A                                   0xC2002E
+#define B_FE_AG_REG_PM1_AGC_WRI__A                                   0xC20030
+#define B_FE_AG_REG_PM1_AGC_WRI__M                                   0x7FF
+#define B_FE_AG_REG_GC1_AGC_RIC__A                                   0xC20031
+#define B_FE_AG_REG_GC1_AGC_OFF__A                                   0xC20032
+#define B_FE_AG_REG_GC1_AGC_MAX__A                                   0xC20033
+#define B_FE_AG_REG_GC1_AGC_MIN__A                                   0xC20034
+#define B_FE_AG_REG_GC1_AGC_DAT__A                                   0xC20035
+#define B_FE_AG_REG_GC1_AGC_DAT__M                                   0x3FF
+#define B_FE_AG_REG_PM2_AGC_WRI__A                                   0xC20036
+#define B_FE_AG_REG_IND_WIN__A                                       0xC2003C
+#define B_FE_AG_REG_IND_THD_LOL__A                                   0xC2003D
+#define B_FE_AG_REG_IND_THD_HIL__A                                   0xC2003E
+#define B_FE_AG_REG_IND_DEL__A                                       0xC2003F
+#define B_FE_AG_REG_IND_PD1_WRI__A                                   0xC20040
+#define B_FE_AG_REG_PDA_AUR_CNT__A                                   0xC20041
+#define B_FE_AG_REG_PDA_RUR_CNT__A                                   0xC20042
+#define B_FE_AG_REG_PDA_AVE_DAT__A                                   0xC20043
+#define B_FE_AG_REG_PDC_RUR_CNT__A                                   0xC20044
+#define B_FE_AG_REG_PDC_SET_LVL__A                                   0xC20045
+#define B_FE_AG_REG_PDC_FLA_RGN__A                                   0xC20046
+#define B_FE_AG_REG_PDC_JMP_PSN__A                                   0xC20047
+#define B_FE_AG_REG_PDC_FLA_STP__A                                   0xC20048
+#define B_FE_AG_REG_PDC_SLO_STP__A                                   0xC20049
+#define B_FE_AG_REG_PDC_PD2_WRI__A                                   0xC2004A
+#define B_FE_AG_REG_PDC_MAP_DAT__A                                   0xC2004B
+#define B_FE_AG_REG_PDC_MAX__A                                       0xC2004C
+#define B_FE_AG_REG_TGA_AUR_CNT__A                                   0xC2004D
+#define B_FE_AG_REG_TGA_RUR_CNT__A                                   0xC2004E
+#define B_FE_AG_REG_TGA_AVE_DAT__A                                   0xC2004F
+#define B_FE_AG_REG_TGC_RUR_CNT__A                                   0xC20050
+#define B_FE_AG_REG_TGC_SET_LVL__A                                   0xC20051
+#define B_FE_AG_REG_TGC_SET_LVL__M                                   0x3F
+#define B_FE_AG_REG_TGC_FLA_RGN__A                                   0xC20052
+#define B_FE_AG_REG_TGC_JMP_PSN__A                                   0xC20053
+#define B_FE_AG_REG_TGC_FLA_STP__A                                   0xC20054
+#define B_FE_AG_REG_TGC_SLO_STP__A                                   0xC20055
+#define B_FE_AG_REG_TGC_MAP_DAT__A                                   0xC20056
+#define B_FE_AG_REG_FGM_WRI__A                                       0xC20061
+#define B_FE_AG_REG_BGC_FGC_WRI__A                                   0xC20068
+#define B_FE_AG_REG_BGC_CGC_WRI__A                                   0xC20069
+#define B_FE_FS_REG_COMM_EXEC__A                                     0xC30000
+#define B_FE_FS_REG_ADD_INC_LOP__A                                   0xC30010
+#define B_FE_FD_REG_COMM_EXEC__A                                     0xC40000
+#define B_FE_FD_REG_SCL__A                                           0xC40010
+#define B_FE_FD_REG_MAX_LEV__A                                       0xC40011
+#define B_FE_FD_REG_NR__A                                            0xC40012
+#define B_FE_FD_REG_MEAS_VAL__A                                      0xC40014
+#define B_FE_IF_REG_COMM_EXEC__A                                     0xC50000
+#define B_FE_IF_REG_INCR0__A                                         0xC50010
+#define B_FE_IF_REG_INCR0__W                                         16
+#define B_FE_IF_REG_INCR0__M                                         0xFFFF
+#define B_FE_IF_REG_INCR1__A                                         0xC50011
+#define B_FE_IF_REG_INCR1__M                                         0xFF
+#define B_FE_CF_REG_COMM_EXEC__A                                     0xC60000
+#define B_FE_CF_REG_SCL__A                                           0xC60010
+#define B_FE_CF_REG_MAX_LEV__A                                       0xC60011
+#define B_FE_CF_REG_NR__A                                            0xC60012
+#define B_FE_CF_REG_IMP_VAL__A                                       0xC60013
+#define B_FE_CF_REG_MEAS_VAL__A                                      0xC60014
+#define B_FE_CU_REG_COMM_EXEC__A                                     0xC70000
+#define B_FE_CU_REG_FRM_CNT_RST__A                                   0xC70011
+#define B_FE_CU_REG_FRM_CNT_STR__A                                   0xC70012
+#define B_FE_CU_REG_CTR_NFC_ICR__A                                   0xC70020
+#define B_FE_CU_REG_CTR_NFC_OCR__A                                   0xC70021
+#define B_FE_CU_REG_DIV_NFC_CLP__A                                   0xC70027
+#define B_FT_COMM_EXEC__A                                            0x1000000
+#define B_FT_REG_COMM_EXEC__A                                        0x1010000
+#define B_CP_COMM_EXEC__A                                            0x1400000
+#define B_CP_REG_COMM_EXEC__A                                        0x1410000
+#define B_CP_REG_INTERVAL__A                                         0x1410011
+#define B_CP_REG_BR_SPL_OFFSET__A                                    0x1410023
+#define B_CP_REG_BR_STR_DEL__A                                       0x1410024
+#define B_CP_REG_RT_ANG_INC0__A                                      0x1410030
+#define B_CP_REG_RT_ANG_INC1__A                                      0x1410031
+#define B_CP_REG_RT_DETECT_TRH__A                                    0x1410033
+#define B_CP_REG_AC_NEXP_OFFS__A                                     0x1410040
+#define B_CP_REG_AC_AVER_POW__A                                      0x1410041
+#define B_CP_REG_AC_MAX_POW__A                                       0x1410042
+#define B_CP_REG_AC_WEIGHT_MAN__A                                    0x1410043
+#define B_CP_REG_AC_WEIGHT_EXP__A                                    0x1410044
+#define B_CP_REG_AC_AMP_MODE__A                                      0x1410047
+#define B_CP_REG_AC_AMP_FIX__A                                       0x1410048
+#define B_CP_REG_AC_ANG_MODE__A                                      0x141004A
+#define B_CE_COMM_EXEC__A                                            0x1800000
+#define B_CE_REG_COMM_EXEC__A                                        0x1810000
+#define B_CE_REG_TAPSET__A                                           0x1810011
+#define B_CE_REG_AVG_POW__A                                          0x1810012
+#define B_CE_REG_MAX_POW__A                                          0x1810013
+#define B_CE_REG_ATT__A                                              0x1810014
+#define B_CE_REG_NRED__A                                             0x1810015
+#define B_CE_REG_NE_ERR_SELECT__A                                    0x1810043
+#define B_CE_REG_NE_TD_CAL__A                                        0x1810044
+#define B_CE_REG_NE_MIXAVG__A                                        0x1810046
+#define B_CE_REG_NE_NUPD_OFS__A                                      0x1810047
+#define B_CE_REG_PE_NEXP_OFFS__A                                     0x1810050
+#define B_CE_REG_PE_TIMESHIFT__A                                     0x1810051
+#define B_CE_REG_TP_A0_TAP_NEW__A                                    0x1810064
+#define B_CE_REG_TP_A0_TAP_NEW_VALID__A                              0x1810065
+#define B_CE_REG_TP_A0_MU_LMS_STEP__A                                0x1810066
+#define B_CE_REG_TP_A1_TAP_NEW__A                                    0x1810068
+#define B_CE_REG_TP_A1_TAP_NEW_VALID__A                              0x1810069
+#define B_CE_REG_TP_A1_MU_LMS_STEP__A                                0x181006A
+#define B_CE_REG_TI_PHN_ENABLE__A                                    0x1810073
+#define B_CE_REG_FI_SHT_INCR__A                                      0x1810090
+#define B_CE_REG_FI_EXP_NORM__A                                      0x1810091
+#define B_CE_REG_IR_INPUTSEL__A                                      0x18100A0
+#define B_CE_REG_IR_STARTPOS__A                                      0x18100A1
+#define B_CE_REG_IR_NEXP_THRES__A                                    0x18100A2
+#define B_CE_REG_FR_TREAL00__A                                       0x1820010
+#define B_CE_REG_FR_TIMAG00__A                                       0x1820011
+#define B_CE_REG_FR_TREAL01__A                                       0x1820012
+#define B_CE_REG_FR_TIMAG01__A                                       0x1820013
+#define B_CE_REG_FR_TREAL02__A                                       0x1820014
+#define B_CE_REG_FR_TIMAG02__A                                       0x1820015
+#define B_CE_REG_FR_TREAL03__A                                       0x1820016
+#define B_CE_REG_FR_TIMAG03__A                                       0x1820017
+#define B_CE_REG_FR_TREAL04__A                                       0x1820018
+#define B_CE_REG_FR_TIMAG04__A                                       0x1820019
+#define B_CE_REG_FR_TREAL05__A                                       0x182001A
+#define B_CE_REG_FR_TIMAG05__A                                       0x182001B
+#define B_CE_REG_FR_TREAL06__A                                       0x182001C
+#define B_CE_REG_FR_TIMAG06__A                                       0x182001D
+#define B_CE_REG_FR_TREAL07__A                                       0x182001E
+#define B_CE_REG_FR_TIMAG07__A                                       0x182001F
+#define B_CE_REG_FR_TREAL08__A                                       0x1820020
+#define B_CE_REG_FR_TIMAG08__A                                       0x1820021
+#define B_CE_REG_FR_TREAL09__A                                       0x1820022
+#define B_CE_REG_FR_TIMAG09__A                                       0x1820023
+#define B_CE_REG_FR_TREAL10__A                                       0x1820024
+#define B_CE_REG_FR_TIMAG10__A                                       0x1820025
+#define B_CE_REG_FR_TREAL11__A                                       0x1820026
+#define B_CE_REG_FR_TIMAG11__A                                       0x1820027
+#define B_CE_REG_FR_MID_TAP__A                                       0x1820028
+#define B_CE_REG_FR_SQS_G00__A                                       0x1820029
+#define B_CE_REG_FR_SQS_G01__A                                       0x182002A
+#define B_CE_REG_FR_SQS_G02__A                                       0x182002B
+#define B_CE_REG_FR_SQS_G03__A                                       0x182002C
+#define B_CE_REG_FR_SQS_G04__A                                       0x182002D
+#define B_CE_REG_FR_SQS_G05__A                                       0x182002E
+#define B_CE_REG_FR_SQS_G06__A                                       0x182002F
+#define B_CE_REG_FR_SQS_G07__A                                       0x1820030
+#define B_CE_REG_FR_SQS_G08__A                                       0x1820031
+#define B_CE_REG_FR_SQS_G09__A                                       0x1820032
+#define B_CE_REG_FR_SQS_G10__A                                       0x1820033
+#define B_CE_REG_FR_SQS_G11__A                                       0x1820034
+#define B_CE_REG_FR_SQS_G12__A                                       0x1820035
+#define B_CE_REG_FR_RIO_G00__A                                       0x1820036
+#define B_CE_REG_FR_RIO_G01__A                                       0x1820037
+#define B_CE_REG_FR_RIO_G02__A                                       0x1820038
+#define B_CE_REG_FR_RIO_G03__A                                       0x1820039
+#define B_CE_REG_FR_RIO_G04__A                                       0x182003A
+#define B_CE_REG_FR_RIO_G05__A                                       0x182003B
+#define B_CE_REG_FR_RIO_G06__A                                       0x182003C
+#define B_CE_REG_FR_RIO_G07__A                                       0x182003D
+#define B_CE_REG_FR_RIO_G08__A                                       0x182003E
+#define B_CE_REG_FR_RIO_G09__A                                       0x182003F
+#define B_CE_REG_FR_RIO_G10__A                                       0x1820040
+#define B_CE_REG_FR_MODE__A                                          0x1820041
+#define B_CE_REG_FR_SQS_TRH__A                                       0x1820042
+#define B_CE_REG_FR_RIO_GAIN__A                                      0x1820043
+#define B_CE_REG_FR_BYPASS__A                                        0x1820044
+#define B_CE_REG_FR_PM_SET__A                                        0x1820045
+#define B_CE_REG_FR_ERR_SH__A                                        0x1820046
+#define B_CE_REG_FR_MAN_SH__A                                        0x1820047
+#define B_CE_REG_FR_TAP_SH__A                                        0x1820048
+#define B_EQ_COMM_EXEC__A                                            0x1C00000
+#define B_EQ_REG_COMM_EXEC__A                                        0x1C10000
+#define B_EQ_REG_COMM_MB__A                                          0x1C10002
+#define B_EQ_REG_IS_GAIN_MAN__A                                      0x1C10015
+#define B_EQ_REG_IS_GAIN_EXP__A                                      0x1C10016
+#define B_EQ_REG_IS_CLIP_EXP__A                                      0x1C10017
+#define B_EQ_REG_SN_CEGAIN__A                                        0x1C1002A
+#define B_EQ_REG_SN_OFFSET__A                                        0x1C1002B
+#define B_EQ_REG_RC_SEL_CAR__A                                       0x1C10032
+#define   B_EQ_REG_RC_SEL_CAR_INIT                                   0x2
+#define     B_EQ_REG_RC_SEL_CAR_DIV_ON                               0x1
+#define     B_EQ_REG_RC_SEL_CAR_PASS_A_CC                            0x0
+#define     B_EQ_REG_RC_SEL_CAR_PASS_B_CE                            0x2
+#define     B_EQ_REG_RC_SEL_CAR_LOCAL_A_CC                           0x0
+#define     B_EQ_REG_RC_SEL_CAR_LOCAL_B_CE                           0x8
+#define     B_EQ_REG_RC_SEL_CAR_MEAS_A_CC                            0x0
+#define     B_EQ_REG_RC_SEL_CAR_MEAS_B_CE                            0x20
+#define   B_EQ_REG_RC_SEL_CAR_FFTMODE__M                             0x80
+#define B_EQ_REG_OT_CONST__A                                         0x1C10046
+#define B_EQ_REG_OT_ALPHA__A                                         0x1C10047
+#define B_EQ_REG_OT_QNT_THRES0__A                                    0x1C10048
+#define B_EQ_REG_OT_QNT_THRES1__A                                    0x1C10049
+#define B_EQ_REG_OT_CSI_STEP__A                                      0x1C1004A
+#define B_EQ_REG_OT_CSI_OFFSET__A                                    0x1C1004B
+#define B_EQ_REG_TD_REQ_SMB_CNT__A                                   0x1C10061
+#define B_EQ_REG_TD_TPS_PWR_OFS__A                                   0x1C10062
+#define B_EC_SB_REG_COMM_EXEC__A                                     0x2010000
+#define B_EC_SB_REG_TR_MODE__A                                       0x2010010
+#define   B_EC_SB_REG_TR_MODE_8K                                     0x0
+#define   B_EC_SB_REG_TR_MODE_2K                                     0x1
+#define B_EC_SB_REG_CONST__A                                         0x2010011
+#define   B_EC_SB_REG_CONST_QPSK                                     0x0
+#define   B_EC_SB_REG_CONST_16QAM                                    0x1
+#define   B_EC_SB_REG_CONST_64QAM                                    0x2
+#define B_EC_SB_REG_ALPHA__A                                         0x2010012
+#define B_EC_SB_REG_PRIOR__A                                         0x2010013
+#define   B_EC_SB_REG_PRIOR_HI                                       0x0
+#define   B_EC_SB_REG_PRIOR_LO                                       0x1
+#define B_EC_SB_REG_CSI_HI__A                                        0x2010014
+#define B_EC_SB_REG_CSI_LO__A                                        0x2010015
+#define B_EC_SB_REG_SMB_TGL__A                                       0x2010016
+#define B_EC_SB_REG_SNR_HI__A                                        0x2010017
+#define B_EC_SB_REG_SNR_MID__A                                       0x2010018
+#define B_EC_SB_REG_SNR_LO__A                                        0x2010019
+#define B_EC_SB_REG_SCALE_MSB__A                                     0x201001A
+#define B_EC_SB_REG_SCALE_BIT2__A                                    0x201001B
+#define B_EC_SB_REG_SCALE_LSB__A                                     0x201001C
+#define B_EC_SB_REG_CSI_OFS0__A                                      0x201001D
+#define B_EC_SB_REG_CSI_OFS1__A                                      0x201001E
+#define B_EC_SB_REG_CSI_OFS2__A                                      0x201001F
+#define B_EC_VD_REG_COMM_EXEC__A                                     0x2090000
+#define B_EC_VD_REG_FORCE__A                                         0x2090010
+#define B_EC_VD_REG_SET_CODERATE__A                                  0x2090011
+#define   B_EC_VD_REG_SET_CODERATE_C1_2                              0x0
+#define   B_EC_VD_REG_SET_CODERATE_C2_3                              0x1
+#define   B_EC_VD_REG_SET_CODERATE_C3_4                              0x2
+#define   B_EC_VD_REG_SET_CODERATE_C5_6                              0x3
+#define   B_EC_VD_REG_SET_CODERATE_C7_8                              0x4
+#define B_EC_VD_REG_REQ_SMB_CNT__A                                   0x2090012
+#define B_EC_VD_REG_RLK_ENA__A                                       0x2090014
+#define B_EC_OD_REG_COMM_EXEC__A                                     0x2110000
+#define B_EC_OD_REG_SYNC__A                                          0x2110664
+#define B_EC_OD_DEINT_RAM__A                                         0x2120000
+#define B_EC_RS_REG_COMM_EXEC__A                                     0x2130000
+#define B_EC_RS_REG_REQ_PCK_CNT__A                                   0x2130010
+#define B_EC_RS_REG_VAL__A                                           0x2130011
+#define   B_EC_RS_REG_VAL_PCK                                        0x1
+#define B_EC_RS_EC_RAM__A                                            0x2140000
+#define B_EC_OC_REG_COMM_EXEC__A                                     0x2150000
+#define     B_EC_OC_REG_COMM_EXEC_CTL_ACTIVE                         0x1
+#define     B_EC_OC_REG_COMM_EXEC_CTL_HOLD                           0x2
+#define B_EC_OC_REG_COMM_INT_STA__A                                  0x2150007
+#define B_EC_OC_REG_OC_MODE_LOP__A                                   0x2150010
+#define   B_EC_OC_REG_OC_MODE_LOP_PAR_ENA__M                         0x1
+#define     B_EC_OC_REG_OC_MODE_LOP_PAR_ENA_ENABLE                   0x0
+#define     B_EC_OC_REG_OC_MODE_LOP_PAR_ENA_DISABLE                  0x1
+#define   B_EC_OC_REG_OC_MODE_LOP_DTO_CTR_SRC__M                     0x4
+#define     B_EC_OC_REG_OC_MODE_LOP_DTO_CTR_SRC_STATIC               0x0
+#define   B_EC_OC_REG_OC_MODE_LOP_MPG_TRM_MDE__M                     0x80
+#define     B_EC_OC_REG_OC_MODE_LOP_MPG_TRM_MDE_SERIAL               0x80
+#define B_EC_OC_REG_OC_MODE_HIP__A                                   0x2150011
+#define     B_EC_OC_REG_OC_MODE_HIP_MPG_BUS_SRC_MONITOR              0x10
+#define   B_EC_OC_REG_OC_MODE_HIP_MPG_PAR_VAL__M                     0x200
+#define     B_EC_OC_REG_OC_MODE_HIP_MPG_PAR_VAL_DISABLE              0x0
+#define     B_EC_OC_REG_OC_MODE_HIP_MPG_PAR_VAL_ENABLE               0x200
+#define B_EC_OC_REG_OC_MPG_SIO__A                                    0x2150012
+#define B_EC_OC_REG_OC_MPG_SIO__M                                    0xFFF
+#define B_EC_OC_REG_DTO_INC_LOP__A                                   0x2150014
+#define B_EC_OC_REG_DTO_INC_HIP__A                                   0x2150015
+#define B_EC_OC_REG_SNC_ISC_LVL__A                                   0x2150016
+#define   B_EC_OC_REG_SNC_ISC_LVL_OSC__M                             0xF0
+#define B_EC_OC_REG_TMD_TOP_MODE__A                                  0x215001D
+#define B_EC_OC_REG_TMD_TOP_CNT__A                                   0x215001E
+#define B_EC_OC_REG_TMD_HIL_MAR__A                                   0x215001F
+#define B_EC_OC_REG_TMD_LOL_MAR__A                                   0x2150020
+#define B_EC_OC_REG_TMD_CUR_CNT__A                                   0x2150021
+#define B_EC_OC_REG_AVR_ASH_CNT__A                                   0x2150023
+#define B_EC_OC_REG_AVR_BSH_CNT__A                                   0x2150024
+#define B_EC_OC_REG_RCN_MODE__A                                      0x2150027
+#define B_EC_OC_REG_RCN_CRA_LOP__A                                   0x2150028
+#define B_EC_OC_REG_RCN_CRA_HIP__A                                   0x2150029
+#define B_EC_OC_REG_RCN_CST_LOP__A                                   0x215002A
+#define B_EC_OC_REG_RCN_CST_HIP__A                                   0x215002B
+#define B_EC_OC_REG_RCN_SET_LVL__A                                   0x215002C
+#define B_EC_OC_REG_RCN_GAI_LVL__A                                   0x215002D
+#define B_EC_OC_REG_RCN_CLP_LOP__A                                   0x2150032
+#define B_EC_OC_REG_RCN_CLP_HIP__A                                   0x2150033
+#define B_EC_OC_REG_RCN_MAP_LOP__A                                   0x2150034
+#define B_EC_OC_REG_RCN_MAP_HIP__A                                   0x2150035
+#define B_EC_OC_REG_OCR_MPG_UOS__A                                   0x2150036
+#define B_EC_OC_REG_OCR_MPG_UOS__M                                   0xFFF
+#define   B_EC_OC_REG_OCR_MPG_UOS_INIT                               0x0
+#define B_EC_OC_REG_OCR_MPG_USR_DAT__A                               0x2150038
+#define B_EC_OC_REG_IPR_INV_MPG__A                                   0x2150045
+#define B_EC_OC_REG_DTO_CLKMODE__A                                   0x2150047
+#define B_EC_OC_REG_DTO_PER__A                                       0x2150048
+#define B_EC_OC_REG_DTO_BUR__A                                       0x2150049
+#define B_EC_OC_REG_RCR_CLKMODE__A                                   0x215004A
+#define B_CC_REG_OSC_MODE__A                                         0x2410010
+#define   B_CC_REG_OSC_MODE_M20                                      0x1
+#define B_CC_REG_PLL_MODE__A                                         0x2410011
+#define     B_CC_REG_PLL_MODE_BYPASS_PLL                             0x1
+#define     B_CC_REG_PLL_MODE_PUMP_CUR_12                            0x14
+#define B_CC_REG_REF_DIVIDE__A                                       0x2410012
+#define B_CC_REG_PWD_MODE__A                                         0x2410015
+#define   B_CC_REG_PWD_MODE_DOWN_PLL                                 0x2
+#define B_CC_REG_UPDATE__A                                           0x2410017
+#define   B_CC_REG_UPDATE_KEY                                        0x3973
+#define B_CC_REG_JTAGID_L__A                                         0x2410019
+#define B_CC_REG_DIVERSITY__A                                        0x241001B
+#define B_LC_COMM_EXEC__A                                            0x2800000
+#define B_LC_RA_RAM_IFINCR_NOM_L__A                                  0x282000C
+#define B_LC_RA_RAM_FILTER_SYM_SET__A                                0x282001A
+#define B_LC_RA_RAM_FILTER_SYM_SET__PRE                              0x3E8
+#define B_LC_RA_RAM_FILTER_CRMM_A__A                                 0x2820060
+#define B_LC_RA_RAM_FILTER_CRMM_A__PRE                               0x4
+#define B_LC_RA_RAM_FILTER_CRMM_B__A                                 0x2820061
+#define B_LC_RA_RAM_FILTER_CRMM_B__PRE                               0x1
+#define B_LC_RA_RAM_FILTER_SRMM_A__A                                 0x2820068
+#define B_LC_RA_RAM_FILTER_SRMM_A__PRE                               0x4
+#define B_LC_RA_RAM_FILTER_SRMM_B__A                                 0x2820069
+#define B_LC_RA_RAM_FILTER_SRMM_B__PRE                               0x1
+
+#endif
diff -druN linux-2.6.39-libre/drivers/media/dvb/frontends/eds1547.h linux-3.0-rc7-libre/drivers/media/dvb/frontends/eds1547.h
--- linux-2.6.39-libre/drivers/media/dvb/frontends/eds1547.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/dvb/frontends/eds1547.h	2011-07-11 19:51:52.000000000 -0400
@@ -61,7 +61,7 @@
 	0x3d, 0x30,
 	0x40, 0x63,
 	0x41, 0x04,
-	0x42, 0x60,
+	0x42, 0x20,
 	0x43, 0x00,
 	0x44, 0x00,
 	0x45, 0x00,
diff -druN linux-2.6.39-libre/drivers/media/dvb/frontends/ix2505v.c linux-3.0-rc7-libre/drivers/media/dvb/frontends/ix2505v.c
--- linux-2.6.39-libre/drivers/media/dvb/frontends/ix2505v.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/dvb/frontends/ix2505v.c	2011-07-11 19:51:52.000000000 -0400
@@ -218,11 +218,13 @@
 		fe->ops.i2c_gate_ctrl(fe, 1);
 
 	len = sizeof(data);
-
 	ret |= ix2505v_write(state, data, len);
 
 	data[2] |= 0x4; /* set TM = 1 other bits same */
 
+	if (fe->ops.i2c_gate_ctrl)
+		fe->ops.i2c_gate_ctrl(fe, 1);
+
 	len = 1;
 	ret |= ix2505v_write(state, &data[2], len); /* write byte 4 only */
 
@@ -233,12 +235,12 @@
 
 	deb_info("Data 2=[%x%x]\n", data[2], data[3]);
 
+	if (fe->ops.i2c_gate_ctrl)
+		fe->ops.i2c_gate_ctrl(fe, 1);
+
 	len = 2;
 	ret |= ix2505v_write(state, &data[2], len); /* write byte 4 & 5 */
 
-	if (fe->ops.i2c_gate_ctrl)
-		fe->ops.i2c_gate_ctrl(fe, 0);
-
 	if (state->config->min_delay_ms)
 		msleep(state->config->min_delay_ms);
 
diff -druN linux-2.6.39-libre/drivers/media/dvb/frontends/Kconfig linux-3.0-rc7-libre/drivers/media/dvb/frontends/Kconfig
--- linux-2.6.39-libre/drivers/media/dvb/frontends/Kconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/dvb/frontends/Kconfig	2011-07-11 19:51:52.000000000 -0400
@@ -263,18 +263,16 @@
 	help
 	  A DVB-T tuner module. Say Y when you want to support this frontend.
 
-config DVB_DRX397XD
-	tristate "Micronas DRX3975D/DRX3977D based"
+config DVB_DRXD
+	tristate "Micronas DRXD driver"
 	depends on DVB_CORE && I2C
 	default m if DVB_FE_CUSTOMISE
 	help
 	  A DVB-T tuner module. Say Y when you want to support this frontend.
 
-	  TODO:
-	  This driver needs external firmware. Please use the command
-	  "<kerneldir>/Documentation/dvb/get_dvb_firmware drx397xD" to
-	  download/extract them, and then copy them to /usr/lib/hotplug/firmware
-	  or /lib/firmware (depending on configuration of firmware hotplug).
+	  Note: this driver was based on vendor driver reference code (released
+	  under the GPL) as opposed to the existing drx397xd driver, which
+	  was written via reverse engineering.
 
 config DVB_L64781
 	tristate "LSI L64781"
@@ -385,6 +383,13 @@
 	help
 	  A DVB-T/C tuner module. Say Y when you want to support this frontend.
 
+config DVB_CXD2820R
+	tristate "Sony CXD2820R"
+	depends on DVB_CORE && I2C
+	default m if DVB_FE_CUSTOMISE
+	help
+	  Say Y when you want to support this frontend.
+
 comment "DVB-C (cable) frontends"
 	depends on DVB_CORE
 
diff -druN linux-2.6.39-libre/drivers/media/dvb/frontends/Makefile linux-3.0-rc7-libre/drivers/media/dvb/frontends/Makefile
--- linux-2.6.39-libre/drivers/media/dvb/frontends/Makefile	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/dvb/frontends/Makefile	2011-07-11 19:51:52.000000000 -0400
@@ -8,6 +8,8 @@
 stb0899-objs = stb0899_drv.o stb0899_algo.o
 stv0900-objs = stv0900_core.o stv0900_sw.o
 au8522-objs = au8522_dig.o au8522_decoder.o
+drxd-objs = drxd_firm.o drxd_hard.o
+cxd2820r-objs = cxd2820r_core.o cxd2820r_c.o cxd2820r_t.o cxd2820r_t2.o
 
 obj-$(CONFIG_DVB_PLL) += dvb-pll.o
 obj-$(CONFIG_DVB_STV0299) += stv0299.o
@@ -36,7 +38,7 @@
 obj-$(CONFIG_DVB_ZL10039) += zl10039.o
 obj-$(CONFIG_DVB_ZL10353) += zl10353.o
 obj-$(CONFIG_DVB_CX22702) += cx22702.o
-obj-$(CONFIG_DVB_DRX397XD) += drx397xD.o
+obj-$(CONFIG_DVB_DRXD) += drxd.o
 obj-$(CONFIG_DVB_TDA10021) += tda10021.o
 obj-$(CONFIG_DVB_TDA10023) += tda10023.o
 obj-$(CONFIG_DVB_STV0297) += stv0297.o
@@ -85,3 +87,5 @@
 obj-$(CONFIG_DVB_MB86A20S) += mb86a20s.o
 obj-$(CONFIG_DVB_IX2505V) += ix2505v.o
 obj-$(CONFIG_DVB_STV0367) += stv0367.o
+obj-$(CONFIG_DVB_CXD2820R) += cxd2820r.o
+
diff -druN linux-2.6.39-libre/drivers/media/dvb/frontends/stb0899_algo.c linux-3.0-rc7-libre/drivers/media/dvb/frontends/stb0899_algo.c
--- linux-2.6.39-libre/drivers/media/dvb/frontends/stb0899_algo.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/dvb/frontends/stb0899_algo.c	2011-07-11 19:51:52.000000000 -0400
@@ -23,7 +23,7 @@
 #include "stb0899_priv.h"
 #include "stb0899_reg.h"
 
-inline u32 stb0899_do_div(u64 n, u32 d)
+static inline u32 stb0899_do_div(u64 n, u32 d)
 {
 	/* wrap do_div() for ease of use */
 
diff -druN linux-2.6.39-libre/drivers/media/dvb/frontends/stv0288.c linux-3.0-rc7-libre/drivers/media/dvb/frontends/stv0288.c
--- linux-2.6.39-libre/drivers/media/dvb/frontends/stv0288.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/dvb/frontends/stv0288.c	2011-07-11 19:51:52.000000000 -0400
@@ -253,7 +253,7 @@
 	0x3d, 0x30,
 	0x40, 0x63,
 	0x41, 0x04,
-	0x42, 0x60,
+	0x42, 0x20,
 	0x43, 0x00,
 	0x44, 0x00,
 	0x45, 0x00,
diff -druN linux-2.6.39-libre/drivers/media/dvb/frontends/stv0299.c linux-3.0-rc7-libre/drivers/media/dvb/frontends/stv0299.c
--- linux-2.6.39-libre/drivers/media/dvb/frontends/stv0299.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/dvb/frontends/stv0299.c	2011-07-11 19:51:52.000000000 -0400
@@ -64,6 +64,7 @@
 	fe_code_rate_t fec_inner;
 	int errmode;
 	u32 ucblocks;
+	u8 mcr_reg;
 };
 
 #define STATUS_BER 0
@@ -457,6 +458,9 @@
 
 	dprintk("stv0299: init chip\n");
 
+	stv0299_writeregI(state, 0x02, 0x30 | state->mcr_reg);
+	msleep(50);
+
 	for (i = 0; ; i += 2)  {
 		reg = state->config->inittab[i];
 		val = state->config->inittab[i+1];
@@ -464,6 +468,8 @@
 			break;
 		if (reg == 0x0c && state->config->op0_off)
 			val &= ~0x10;
+		if (reg == 0x2)
+			state->mcr_reg = val & 0xf;
 		stv0299_writeregI(state, reg, val);
 	}
 
@@ -618,7 +624,7 @@
 {
 	struct stv0299_state* state = fe->demodulator_priv;
 
-	stv0299_writeregI(state, 0x02, 0x80);
+	stv0299_writeregI(state, 0x02, 0xb0 | state->mcr_reg);
 	state->initialised = 0;
 
 	return 0;
@@ -680,7 +686,7 @@
 	state->errmode = STATUS_BER;
 
 	/* check if the demod is there */
-	stv0299_writeregI(state, 0x02, 0x34); /* standby off */
+	stv0299_writeregI(state, 0x02, 0x30); /* standby off */
 	msleep(200);
 	id = stv0299_readreg(state, 0x00);
 
diff -druN linux-2.6.39-libre/drivers/media/dvb/frontends/tda8261.c linux-3.0-rc7-libre/drivers/media/dvb/frontends/tda8261.c
--- linux-2.6.39-libre/drivers/media/dvb/frontends/tda8261.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/dvb/frontends/tda8261.c	2011-07-11 19:51:52.000000000 -0400
@@ -224,7 +224,6 @@
 }
 
 EXPORT_SYMBOL(tda8261_attach);
-MODULE_PARM_DESC(verbose, "Set verbosity level");
 
 MODULE_AUTHOR("Manu Abraham");
 MODULE_DESCRIPTION("TDA8261 8PSK/QPSK Tuner");
diff -druN linux-2.6.39-libre/drivers/media/dvb/frontends/z0194a.h linux-3.0-rc7-libre/drivers/media/dvb/frontends/z0194a.h
--- linux-2.6.39-libre/drivers/media/dvb/frontends/z0194a.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/dvb/frontends/z0194a.h	2011-07-11 19:51:52.000000000 -0400
@@ -42,7 +42,7 @@
 
 static u8 sharp_z0194a_inittab[] = {
 	0x01, 0x15,
-	0x02, 0x00,
+	0x02, 0x30,
 	0x03, 0x00,
 	0x04, 0x7d,   /* F22FR = 0x7d, F22 = f_VCO / 128 / 0x7d = 22 kHz */
 	0x05, 0x35,   /* I2CT = 0, SCLT = 1, SDAT = 1 */
diff -druN linux-2.6.39-libre/drivers/media/dvb/mantis/hopper_cards.c linux-3.0-rc7-libre/drivers/media/dvb/mantis/hopper_cards.c
--- linux-2.6.39-libre/drivers/media/dvb/mantis/hopper_cards.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/dvb/mantis/hopper_cards.c	2011-07-11 19:51:52.000000000 -0400
@@ -44,7 +44,7 @@
 
 static unsigned int verbose;
 module_param(verbose, int, 0644);
-MODULE_PARM_DESC(verbose, "verbose startup messages, default is 1 (yes)");
+MODULE_PARM_DESC(verbose, "verbose startup messages, default is 0 (no)");
 
 #define DRIVER_NAME	"Hopper"
 
diff -druN linux-2.6.39-libre/drivers/media/dvb/mantis/mantis_cards.c linux-3.0-rc7-libre/drivers/media/dvb/mantis/mantis_cards.c
--- linux-2.6.39-libre/drivers/media/dvb/mantis/mantis_cards.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/dvb/mantis/mantis_cards.c	2011-07-11 19:51:52.000000000 -0400
@@ -52,7 +52,7 @@
 
 static unsigned int verbose;
 module_param(verbose, int, 0644);
-MODULE_PARM_DESC(verbose, "verbose startup messages, default is 1 (yes)");
+MODULE_PARM_DESC(verbose, "verbose startup messages, default is 0 (no)");
 
 static int devs;
 
diff -druN linux-2.6.39-libre/drivers/media/dvb/mantis/mantis_pci.c linux-3.0-rc7-libre/drivers/media/dvb/mantis/mantis_pci.c
--- linux-2.6.39-libre/drivers/media/dvb/mantis/mantis_pci.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/dvb/mantis/mantis_pci.c	2011-07-11 19:51:52.000000000 -0400
@@ -48,7 +48,7 @@
 
 int __devinit mantis_pci_init(struct mantis_pci *mantis)
 {
-	u8 revision, latency;
+	u8 latency;
 	struct mantis_hwconfig *config	= mantis->hwconfig;
 	struct pci_dev *pdev		= mantis->pdev;
 	int err, ret = 0;
@@ -95,9 +95,8 @@
 	}
 
 	pci_read_config_byte(pdev, PCI_LATENCY_TIMER, &latency);
-	pci_read_config_byte(pdev, PCI_CLASS_REVISION, &revision);
 	mantis->latency = latency;
-	mantis->revision = revision;
+	mantis->revision = pdev->revision;
 
 	dprintk(MANTIS_ERROR, 0, "    Mantis Rev %d [%04x:%04x], ",
 		mantis->revision,
diff -druN linux-2.6.39-libre/drivers/media/dvb/mantis/mantis_vp1033.c linux-3.0-rc7-libre/drivers/media/dvb/mantis/mantis_vp1033.c
--- linux-2.6.39-libre/drivers/media/dvb/mantis/mantis_vp1033.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/dvb/mantis/mantis_vp1033.c	2011-07-11 19:51:52.000000000 -0400
@@ -37,7 +37,7 @@
 
 u8 lgtdqcs001f_inittab[] = {
 	0x01, 0x15,
-	0x02, 0x00,
+	0x02, 0x30,
 	0x03, 0x00,
 	0x04, 0x2a,
 	0x05, 0x85,
diff -druN linux-2.6.39-libre/drivers/media/dvb/pt1/pt1.c linux-3.0-rc7-libre/drivers/media/dvb/pt1/pt1.c
--- linux-2.6.39-libre/drivers/media/dvb/pt1/pt1.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/dvb/pt1/pt1.c	2011-07-11 19:51:52.000000000 -0400
@@ -1090,6 +1090,7 @@
 	i2c_adap->algo = &pt1_i2c_algo;
 	i2c_adap->algo_data = NULL;
 	i2c_adap->dev.parent = &pdev->dev;
+	strcpy(i2c_adap->name, DRIVER_NAME);
 	i2c_set_adapdata(i2c_adap, pt1);
 	ret = i2c_add_adapter(i2c_adap);
 	if (ret < 0)
@@ -1156,10 +1157,10 @@
 	pt1->power = 0;
 	pt1->reset = 1;
 	pt1_update_power(pt1);
-err_pt1_cleanup_adapters:
-	pt1_cleanup_adapters(pt1);
 err_i2c_del_adapter:
 	i2c_del_adapter(i2c_adap);
+err_pt1_cleanup_adapters:
+	pt1_cleanup_adapters(pt1);
 err_kfree:
 	pci_set_drvdata(pdev, NULL);
 	kfree(pt1);
diff -druN linux-2.6.39-libre/drivers/media/dvb/siano/smsusb.c linux-3.0-rc7-libre/drivers/media/dvb/siano/smsusb.c
--- linux-2.6.39-libre/drivers/media/dvb/siano/smsusb.c	2011-05-19 02:09:49.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/dvb/siano/smsusb.c	2011-07-21 06:52:20.000000000 -0400
@@ -297,9 +297,8 @@
 		if (dev->coredev)
 			smscore_unregister_device(dev->coredev);
 
-		kfree(dev);
-
 		sms_info("device %p destroyed", dev);
+		kfree(dev);
 	}
 
 	usb_set_intfdata(intf, NULL);
diff -druN linux-2.6.39-libre/drivers/media/dvb/ttpci/budget-ci.c linux-3.0-rc7-libre/drivers/media/dvb/ttpci/budget-ci.c
--- linux-2.6.39-libre/drivers/media/dvb/ttpci/budget-ci.c	2011-05-19 02:09:37.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/dvb/ttpci/budget-ci.c	2011-07-21 06:52:07.000000000 -0400
@@ -52,6 +52,7 @@
 #include "bsru6.h"
 #include "tda1002x.h"
 #include "tda827x.h"
+#include "bsbe1-d01a.h"
 
 #define MODULE_NAME "budget_ci"
 
@@ -224,6 +225,7 @@
 	case 0x1017:
 	case 0x1019:
 	case 0x101a:
+	case 0x101b:
 		/* for the Technotrend 1500 bundled remote */
 		dev->map_name = RC_MAP_TT_1500;
 		break;
@@ -1388,6 +1390,23 @@
 		}
 		break;
 
+	case 0x101b: /* TT S-1500B (BSBE1-D01A - STV0288/STB6000/LNBP21) */
+		budget_ci->budget.dvb_frontend = dvb_attach(stv0288_attach, &stv0288_bsbe1_d01a_config, &budget_ci->budget.i2c_adap);
+		if (budget_ci->budget.dvb_frontend) {
+			if (dvb_attach(stb6000_attach, budget_ci->budget.dvb_frontend, 0x63, &budget_ci->budget.i2c_adap)) {
+				if (!dvb_attach(lnbp21_attach, budget_ci->budget.dvb_frontend, &budget_ci->budget.i2c_adap, 0, 0)) {
+					printk(KERN_ERR "%s: No LNBP21 found!\n", __func__);
+					dvb_frontend_detach(budget_ci->budget.dvb_frontend);
+					budget_ci->budget.dvb_frontend = NULL;
+				}
+			} else {
+				printk(KERN_ERR "%s: No STB6000 found!\n", __func__);
+				dvb_frontend_detach(budget_ci->budget.dvb_frontend);
+				budget_ci->budget.dvb_frontend = NULL;
+			}
+		}
+		break;
+
 	case 0x1019:		// TT S2-3200 PCI
 		/*
 		 * NOTE! on some STB0899 versions, the internal PLL takes a longer time
@@ -1518,6 +1537,7 @@
 MAKE_BUDGET_INFO(ttbcci, "TT-Budget-C-CI PCI", BUDGET_TT);
 MAKE_BUDGET_INFO(ttc1501, "TT-Budget C-1501 PCI", BUDGET_TT);
 MAKE_BUDGET_INFO(tt3200, "TT-Budget S2-3200 PCI", BUDGET_TT);
+MAKE_BUDGET_INFO(ttbs1500b, "TT-Budget S-1500B PCI", BUDGET_TT);
 
 static struct pci_device_id pci_tbl[] = {
 	MAKE_EXTENSION_PCI(ttbci, 0x13c2, 0x100c),
@@ -1528,6 +1548,7 @@
 	MAKE_EXTENSION_PCI(ttbs2, 0x13c2, 0x1017),
 	MAKE_EXTENSION_PCI(ttc1501, 0x13c2, 0x101a),
 	MAKE_EXTENSION_PCI(tt3200, 0x13c2, 0x1019),
+	MAKE_EXTENSION_PCI(ttbs1500b, 0x13c2, 0x101b),
 	{
 	 .vendor = 0,
 	 }
diff -druN linux-2.6.39-libre/drivers/media/dvb/ttpci/Kconfig linux-3.0-rc7-libre/drivers/media/dvb/ttpci/Kconfig
--- linux-2.6.39-libre/drivers/media/dvb/ttpci/Kconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/dvb/ttpci/Kconfig	2011-07-11 19:51:52.000000000 -0400
@@ -95,6 +95,8 @@
 	select DVB_STB0899 if !DVB_FE_CUSTOMISE
 	select DVB_STB6100 if !DVB_FE_CUSTOMISE
 	select DVB_LNBP21 if !DVB_FE_CUSTOMISE
+	select DVB_STV0288 if !DVB_FE_CUSTOMISE
+	select DVB_STB6000 if !DVB_FE_CUSTOMISE
 	select DVB_TDA10023 if !DVB_FE_CUSTOMISE
 	select MEDIA_TUNER_TDA827X if !MEDIA_TUNER_CUSTOMISE
 	depends on RC_CORE
diff -druN linux-2.6.39-libre/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c linux-3.0-rc7-libre/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c
--- linux-2.6.39-libre/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c	2011-05-19 02:09:51.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c	2011-07-21 06:52:23.000000000 -0400
@@ -52,7 +52,7 @@
     my TTUSB, so let it undef'd unless you want to implement another
     frontend. never tested.
 
-  DEBUG:
+  debug:
     define it to > 3 for really hardcore debugging. you probably don't want
     this unless the device doesn't load at all. > 2 for bandwidth statistics.
 */
@@ -134,20 +134,19 @@
 /* ugly workaround ... don't know why it's necessary to read */
 /* all result codes. */
 
-#define DEBUG 0
 static int ttusb_cmd(struct ttusb *ttusb,
 	      const u8 * data, int len, int needresult)
 {
 	int actual_len;
 	int err;
-#if DEBUG >= 3
 	int i;
 
-	printk(">");
-	for (i = 0; i < len; ++i)
-		printk(" %02x", data[i]);
-	printk("\n");
-#endif
+	if (debug >= 3) {
+		printk(KERN_DEBUG ">");
+		for (i = 0; i < len; ++i)
+			printk(KERN_CONT " %02x", data[i]);
+		printk(KERN_CONT "\n");
+	}
 
 	if (mutex_lock_interruptible(&ttusb->semusb) < 0)
 		return -EAGAIN;
@@ -176,13 +175,15 @@
 		mutex_unlock(&ttusb->semusb);
 		return err;
 	}
-#if DEBUG >= 3
-	actual_len = ttusb->last_result[3] + 4;
-	printk("<");
-	for (i = 0; i < actual_len; ++i)
-		printk(" %02x", ttusb->last_result[i]);
-	printk("\n");
-#endif
+
+	if (debug >= 3) {
+		actual_len = ttusb->last_result[3] + 4;
+		printk(KERN_DEBUG "<");
+		for (i = 0; i < actual_len; ++i)
+			printk(KERN_CONT " %02x", ttusb->last_result[i]);
+		printk(KERN_CONT "\n");
+	}
+
 	if (!needresult)
 		mutex_unlock(&ttusb->semusb);
 	return 0;
@@ -636,16 +637,13 @@
 				++ttusb->mux_state;
 			else {
 				ttusb->mux_state = 0;
-#if DEBUG > 3
-				if (ttusb->insync)
-					printk("%02x ", data[-1]);
-#else
 				if (ttusb->insync) {
-					printk("%s: lost sync.\n",
+					dprintk("%s: %02x\n",
+						__func__, data[-1]);
+					printk(KERN_INFO "%s: lost sync.\n",
 					       __func__);
 					ttusb->insync = 0;
 				}
-#endif
 			}
 			break;
 		case 3:
@@ -744,6 +742,9 @@
 static void ttusb_iso_irq(struct urb *urb)
 {
 	struct ttusb *ttusb = urb->context;
+	struct usb_iso_packet_descriptor *d;
+	u8 *data;
+	int len, i;
 
 	if (!ttusb->iso_streaming)
 		return;
@@ -755,21 +756,14 @@
 #endif
 
 	if (!urb->status) {
-		int i;
 		for (i = 0; i < urb->number_of_packets; ++i) {
-			struct usb_iso_packet_descriptor *d;
-			u8 *data;
-			int len;
 			numpkt++;
 			if (time_after_eq(jiffies, lastj + HZ)) {
-#if DEBUG > 2
-				printk
-				    ("frames/s: %d (ts: %d, stuff %d, sec: %d, invalid: %d, all: %d)\n",
-				     numpkt * HZ / (jiffies - lastj),
-				     numts, numstuff, numsec, numinvalid,
-				     numts + numstuff + numsec +
-				     numinvalid);
-#endif
+				dprintk("frames/s: %lu (ts: %d, stuff %d, "
+					"sec: %d, invalid: %d, all: %d)\n",
+					numpkt * HZ / (jiffies - lastj),
+					numts, numstuff, numsec, numinvalid,
+					numts + numstuff + numsec + numinvalid);
 				numts = numstuff = numsec = numinvalid = 0;
 				lastj = jiffies;
 				numpkt = 0;
diff -druN linux-2.6.39-libre/drivers/media/media-devnode.c linux-3.0-rc7-libre/drivers/media/media-devnode.c
--- linux-2.6.39-libre/drivers/media/media-devnode.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/media-devnode.c	2011-07-11 19:51:52.000000000 -0400
@@ -213,14 +213,14 @@
 
 	/* Part 1: Find a free minor number */
 	mutex_lock(&media_devnode_lock);
-	minor = find_next_zero_bit(media_devnode_nums, 0, MEDIA_NUM_DEVICES);
+	minor = find_next_zero_bit(media_devnode_nums, MEDIA_NUM_DEVICES, 0);
 	if (minor == MEDIA_NUM_DEVICES) {
 		mutex_unlock(&media_devnode_lock);
 		printk(KERN_ERR "could not get a free minor\n");
 		return -ENFILE;
 	}
 
-	set_bit(mdev->minor, media_devnode_nums);
+	set_bit(minor, media_devnode_nums);
 	mutex_unlock(&media_devnode_lock);
 
 	mdev->minor = minor;
diff -druN linux-2.6.39-libre/drivers/media/radio/Kconfig linux-3.0-rc7-libre/drivers/media/radio/Kconfig
--- linux-2.6.39-libre/drivers/media/radio/Kconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/radio/Kconfig	2011-07-11 19:51:52.000000000 -0400
@@ -166,21 +166,6 @@
 	  To compile this driver as a module, choose M here: the
 	  module will be called radio-maxiradio.
 
-config RADIO_MAESTRO
-	tristate "Maestro on board radio"
-	depends on VIDEO_V4L2 && PCI
-	---help---
-	  Say Y here to directly support the on-board radio tuner on the
-	  Maestro 2 or 2E sound card.
-
-	  In order to control your radio card, you will need to use programs
-	  that are compatible with the Video For Linux API.  Information on
-	  this API and pointers to "v4l" programs may be found at
-	  <file:Documentation/video4linux/API.html>.
-
-	  To compile this driver as a module, choose M here: the
-	  module will be called radio-maestro.
-
 config RADIO_MIROPCM20
 	tristate "miroSOUND PCM20 radio"
 	depends on ISA && VIDEO_V4L2 && SND
diff -druN linux-2.6.39-libre/drivers/media/radio/Makefile linux-3.0-rc7-libre/drivers/media/radio/Makefile
--- linux-2.6.39-libre/drivers/media/radio/Makefile	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/radio/Makefile	2011-07-11 19:51:52.000000000 -0400
@@ -16,7 +16,6 @@
 obj-$(CONFIG_RADIO_TRUST) += radio-trust.o
 obj-$(CONFIG_I2C_SI4713) += si4713-i2c.o
 obj-$(CONFIG_RADIO_SI4713) += radio-si4713.o
-obj-$(CONFIG_RADIO_MAESTRO) += radio-maestro.o
 obj-$(CONFIG_RADIO_MIROPCM20) += radio-miropcm20.o
 obj-$(CONFIG_USB_DSBR) += dsbr100.o
 obj-$(CONFIG_RADIO_SI470X) += si470x/
diff -druN linux-2.6.39-libre/drivers/media/radio/radio-maestro.c linux-3.0-rc7-libre/drivers/media/radio/radio-maestro.c
--- linux-2.6.39-libre/drivers/media/radio/radio-maestro.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/radio/radio-maestro.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,452 +0,0 @@
-/* Maestro PCI sound card radio driver for Linux support
- * (c) 2000 A. Tlalka, atlka@pg.gda.pl
- * Notes on the hardware
- *
- *  + Frequency control is done digitally
- *  + No volume control - only mute/unmute - you have to use Aux line volume
- *  control on Maestro card to set the volume
- *  + Radio status (tuned/not_tuned and stereo/mono) is valid some time after
- *  frequency setting (>100ms) and only when the radio is unmuted.
- *  version 0.02
- *  + io port is automatically detected - only the first radio is used
- *  version 0.03
- *  + thread access locking additions
- *  version 0.04
- * + code improvements
- * + VIDEO_TUNER_LOW is permanent
- *
- * Converted to V4L2 API by Mauro Carvalho Chehab <mchehab@infradead.org>
- */
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/ioport.h>
-#include <linux/delay.h>
-#include <linux/version.h>      /* for KERNEL_VERSION MACRO     */
-#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>
-
-MODULE_AUTHOR("Adam Tlalka, atlka@pg.gda.pl");
-MODULE_DESCRIPTION("Radio driver for the Maestro PCI sound card radio.");
-MODULE_LICENSE("GPL");
-
-static int radio_nr = -1;
-module_param(radio_nr, int, 0);
-
-#define RADIO_VERSION KERNEL_VERSION(0, 0, 6)
-#define DRIVER_VERSION	"0.06"
-
-#define GPIO_DATA	0x60   /* port offset from ESS_IO_BASE */
-
-#define IO_MASK		4      /* mask      register offset from GPIO_DATA
-				bits 1=unmask write to given bit */
-#define IO_DIR		8      /* direction register offset from GPIO_DATA
-				bits 0/1=read/write direction */
-
-#define GPIO6		0x0040 /* mask bits for GPIO lines */
-#define GPIO7		0x0080
-#define GPIO8		0x0100
-#define GPIO9		0x0200
-
-#define STR_DATA	GPIO6  /* radio TEA5757 pins and GPIO bits */
-#define STR_CLK		GPIO7
-#define STR_WREN	GPIO8
-#define STR_MOST	GPIO9
-
-#define FREQ_LO		 50*16000
-#define FREQ_HI		150*16000
-
-#define FREQ_IF		171200 /* 10.7*16000   */
-#define FREQ_STEP	200    /* 12.5*16      */
-
-#define FREQ2BITS(x)	((((unsigned int)(x)+FREQ_IF+(FREQ_STEP<<1))\
-			/(FREQ_STEP<<2))<<2) /* (x==fmhz*16*1000) -> bits */
-
-#define BITS2FREQ(x)	((x) * FREQ_STEP - FREQ_IF)
-
-struct maestro {
-	struct v4l2_device v4l2_dev;
-	struct video_device vdev;
-	struct pci_dev *pdev;
-	struct mutex lock;
-
-	u16	io;	/* base of Maestro card radio io (GPIO_DATA)*/
-	u16	muted;	/* VIDEO_AUDIO_MUTE */
-	u16	stereo;	/* VIDEO_TUNER_STEREO_ON */
-	u16	tuned;	/* signal strength (0 or 0xffff) */
-};
-
-static inline struct maestro *to_maestro(struct v4l2_device *v4l2_dev)
-{
-	return container_of(v4l2_dev, struct maestro, v4l2_dev);
-}
-
-static u32 radio_bits_get(struct maestro *dev)
-{
-	u16 io = dev->io, l, rdata;
-	u32 data = 0;
-	u16 omask;
-
-	omask = inw(io + IO_MASK);
-	outw(~(STR_CLK | STR_WREN), io + IO_MASK);
-	outw(0, io);
-	udelay(16);
-
-	for (l = 24; l--;) {
-		outw(STR_CLK, io);		/* HI state */
-		udelay(2);
-		if (!l)
-			dev->tuned = inw(io) & STR_MOST ? 0 : 0xffff;
-		outw(0, io);			/* LO state */
-		udelay(2);
-		data <<= 1;			/* shift data */
-		rdata = inw(io);
-		if (!l)
-			dev->stereo = (rdata & STR_MOST) ?  0 : 1;
-		else if (rdata & STR_DATA)
-			data++;
-		udelay(2);
-	}
-
-	if (dev->muted)
-		outw(STR_WREN, io);
-
-	udelay(4);
-	outw(omask, io + IO_MASK);
-
-	return data & 0x3ffe;
-}
-
-static void radio_bits_set(struct maestro *dev, u32 data)
-{
-	u16 io = dev->io, l, bits;
-	u16 omask, odir;
-
-	omask = inw(io + IO_MASK);
-	odir = (inw(io + IO_DIR) & ~STR_DATA) | (STR_CLK | STR_WREN);
-	outw(odir | STR_DATA, io + IO_DIR);
-	outw(~(STR_DATA | STR_CLK | STR_WREN), io + IO_MASK);
-	udelay(16);
-	for (l = 25; l; l--) {
-		bits = ((data >> 18) & STR_DATA) | STR_WREN;
-		data <<= 1;			/* shift data */
-		outw(bits, io);			/* start strobe */
-		udelay(2);
-		outw(bits | STR_CLK, io);	/* HI level */
-		udelay(2);
-		outw(bits, io);			/* LO level */
-		udelay(4);
-	}
-
-	if (!dev->muted)
-		outw(0, io);
-
-	udelay(4);
-	outw(omask, io + IO_MASK);
-	outw(odir, io + IO_DIR);
-	msleep(125);
-}
-
-static int vidioc_querycap(struct file *file, void  *priv,
-					struct v4l2_capability *v)
-{
-	struct maestro *dev = video_drvdata(file);
-
-	strlcpy(v->driver, "radio-maestro", sizeof(v->driver));
-	strlcpy(v->card, "Maestro Radio", sizeof(v->card));
-	snprintf(v->bus_info, sizeof(v->bus_info), "PCI:%s", pci_name(dev->pdev));
-	v->version = RADIO_VERSION;
-	v->capabilities = V4L2_CAP_TUNER | V4L2_CAP_RADIO;
-	return 0;
-}
-
-static int vidioc_g_tuner(struct file *file, void *priv,
-					struct v4l2_tuner *v)
-{
-	struct maestro *dev = video_drvdata(file);
-
-	if (v->index > 0)
-		return -EINVAL;
-
-	mutex_lock(&dev->lock);
-	radio_bits_get(dev);
-
-	strlcpy(v->name, "FM", sizeof(v->name));
-	v->type = V4L2_TUNER_RADIO;
-	v->rangelow = FREQ_LO;
-	v->rangehigh = FREQ_HI;
-	v->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO;
-	v->capability = V4L2_TUNER_CAP_LOW;
-	if (dev->stereo)
-		v->audmode = V4L2_TUNER_MODE_STEREO;
-	else
-		v->audmode = V4L2_TUNER_MODE_MONO;
-	v->signal = dev->tuned;
-	mutex_unlock(&dev->lock);
-	return 0;
-}
-
-static int vidioc_s_tuner(struct file *file, void *priv,
-					struct v4l2_tuner *v)
-{
-	return v->index ? -EINVAL : 0;
-}
-
-static int vidioc_s_frequency(struct file *file, void *priv,
-					struct v4l2_frequency *f)
-{
-	struct maestro *dev = video_drvdata(file);
-
-	if (f->tuner != 0 || f->type != V4L2_TUNER_RADIO)
-		return -EINVAL;
-	if (f->frequency < FREQ_LO || f->frequency > FREQ_HI)
-		return -EINVAL;
-	mutex_lock(&dev->lock);
-	radio_bits_set(dev, FREQ2BITS(f->frequency));
-	mutex_unlock(&dev->lock);
-	return 0;
-}
-
-static int vidioc_g_frequency(struct file *file, void *priv,
-					struct v4l2_frequency *f)
-{
-	struct maestro *dev = video_drvdata(file);
-
-	if (f->tuner != 0)
-		return -EINVAL;
-	f->type = V4L2_TUNER_RADIO;
-	mutex_lock(&dev->lock);
-	f->frequency = BITS2FREQ(radio_bits_get(dev));
-	mutex_unlock(&dev->lock);
-	return 0;
-}
-
-static int vidioc_queryctrl(struct file *file, void *priv,
-					struct v4l2_queryctrl *qc)
-{
-	switch (qc->id) {
-	case V4L2_CID_AUDIO_MUTE:
-		return v4l2_ctrl_query_fill(qc, 0, 1, 1, 1);
-	}
-	return -EINVAL;
-}
-
-static int vidioc_g_ctrl(struct file *file, void *priv,
-					struct v4l2_control *ctrl)
-{
-	struct maestro *dev = video_drvdata(file);
-
-	switch (ctrl->id) {
-	case V4L2_CID_AUDIO_MUTE:
-		ctrl->value = dev->muted;
-		return 0;
-	}
-	return -EINVAL;
-}
-
-static int vidioc_s_ctrl(struct file *file, void *priv,
-					struct v4l2_control *ctrl)
-{
-	struct maestro *dev = video_drvdata(file);
-	u16 io = dev->io;
-	u16 omask;
-
-	switch (ctrl->id) {
-	case V4L2_CID_AUDIO_MUTE:
-		mutex_lock(&dev->lock);
-		omask = inw(io + IO_MASK);
-		outw(~STR_WREN, io + IO_MASK);
-		dev->muted = ctrl->value;
-		outw(dev->muted ? STR_WREN : 0, io);
-		udelay(4);
-		outw(omask, io + IO_MASK);
-		msleep(125);
-		mutex_unlock(&dev->lock);
-		return 0;
-	}
-	return -EINVAL;
-}
-
-static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i)
-{
-	*i = 0;
-	return 0;
-}
-
-static int vidioc_s_input(struct file *filp, void *priv, unsigned int i)
-{
-	return i ? -EINVAL : 0;
-}
-
-static int vidioc_g_audio(struct file *file, void *priv,
-					struct v4l2_audio *a)
-{
-	a->index = 0;
-	strlcpy(a->name, "Radio", sizeof(a->name));
-	a->capability = V4L2_AUDCAP_STEREO;
-	return 0;
-}
-
-static int vidioc_s_audio(struct file *file, void *priv,
-					struct v4l2_audio *a)
-{
-	return a->index ? -EINVAL : 0;
-}
-
-static const struct v4l2_file_operations maestro_fops = {
-	.owner		= THIS_MODULE,
-	.unlocked_ioctl	= video_ioctl2,
-};
-
-static const struct v4l2_ioctl_ops maestro_ioctl_ops = {
-	.vidioc_querycap    = vidioc_querycap,
-	.vidioc_g_tuner     = vidioc_g_tuner,
-	.vidioc_s_tuner     = vidioc_s_tuner,
-	.vidioc_g_audio     = vidioc_g_audio,
-	.vidioc_s_audio     = vidioc_s_audio,
-	.vidioc_g_input     = vidioc_g_input,
-	.vidioc_s_input     = vidioc_s_input,
-	.vidioc_g_frequency = vidioc_g_frequency,
-	.vidioc_s_frequency = vidioc_s_frequency,
-	.vidioc_queryctrl   = vidioc_queryctrl,
-	.vidioc_g_ctrl      = vidioc_g_ctrl,
-	.vidioc_s_ctrl      = vidioc_s_ctrl,
-};
-
-static u16 __devinit radio_power_on(struct maestro *dev)
-{
-	register u16 io = dev->io;
-	register u32 ofreq;
-	u16 omask, odir;
-
-	omask = inw(io + IO_MASK);
-	odir = (inw(io + IO_DIR) & ~STR_DATA) | (STR_CLK | STR_WREN);
-	outw(odir & ~STR_WREN, io + IO_DIR);
-	dev->muted = inw(io) & STR_WREN ? 0 : 1;
-	outw(odir, io + IO_DIR);
-	outw(~(STR_WREN | STR_CLK), io + IO_MASK);
-	outw(dev->muted ? 0 : STR_WREN, io);
-	udelay(16);
-	outw(omask, io + IO_MASK);
-	ofreq = radio_bits_get(dev);
-
-	if ((ofreq < FREQ2BITS(FREQ_LO)) || (ofreq > FREQ2BITS(FREQ_HI)))
-		ofreq = FREQ2BITS(FREQ_LO);
-	radio_bits_set(dev, ofreq);
-
-	return (ofreq == radio_bits_get(dev));
-}
-
-static int __devinit maestro_probe(struct pci_dev *pdev,
-	const struct pci_device_id *ent)
-{
-	struct maestro *dev;
-	struct v4l2_device *v4l2_dev;
-	int retval;
-
-	retval = pci_enable_device(pdev);
-	if (retval) {
-		dev_err(&pdev->dev, "enabling pci device failed!\n");
-		goto err;
-	}
-
-	retval = -ENOMEM;
-
-	dev = kzalloc(sizeof(*dev), GFP_KERNEL);
-	if (dev == NULL) {
-		dev_err(&pdev->dev, "not enough memory\n");
-		goto err;
-	}
-
-	v4l2_dev = &dev->v4l2_dev;
-	mutex_init(&dev->lock);
-	dev->pdev = pdev;
-
-	strlcpy(v4l2_dev->name, "maestro", sizeof(v4l2_dev->name));
-
-	retval = v4l2_device_register(&pdev->dev, v4l2_dev);
-	if (retval < 0) {
-		v4l2_err(v4l2_dev, "Could not register v4l2_device\n");
-		goto errfr;
-	}
-
-	dev->io = pci_resource_start(pdev, 0) + GPIO_DATA;
-
-	strlcpy(dev->vdev.name, v4l2_dev->name, sizeof(dev->vdev.name));
-	dev->vdev.v4l2_dev = v4l2_dev;
-	dev->vdev.fops = &maestro_fops;
-	dev->vdev.ioctl_ops = &maestro_ioctl_ops;
-	dev->vdev.release = video_device_release_empty;
-	video_set_drvdata(&dev->vdev, dev);
-
-	if (!radio_power_on(dev)) {
-		retval = -EIO;
-		goto errfr1;
-	}
-
-	retval = video_register_device(&dev->vdev, VFL_TYPE_RADIO, radio_nr);
-	if (retval) {
-		v4l2_err(v4l2_dev, "can't register video device!\n");
-		goto errfr1;
-	}
-
-	v4l2_info(v4l2_dev, "version " DRIVER_VERSION "\n");
-
-	return 0;
-errfr1:
-	v4l2_device_unregister(v4l2_dev);
-errfr:
-	kfree(dev);
-err:
-	return retval;
-
-}
-
-static void __devexit maestro_remove(struct pci_dev *pdev)
-{
-	struct v4l2_device *v4l2_dev = dev_get_drvdata(&pdev->dev);
-	struct maestro *dev = to_maestro(v4l2_dev);
-
-	video_unregister_device(&dev->vdev);
-	v4l2_device_unregister(&dev->v4l2_dev);
-}
-
-static struct pci_device_id maestro_r_pci_tbl[] = {
-	{ PCI_DEVICE(PCI_VENDOR_ID_ESS, PCI_DEVICE_ID_ESS_ESS1968),
-		.class = PCI_CLASS_MULTIMEDIA_AUDIO << 8,
-		.class_mask = 0xffff00 },
-	{ PCI_DEVICE(PCI_VENDOR_ID_ESS, PCI_DEVICE_ID_ESS_ESS1978),
-		.class = PCI_CLASS_MULTIMEDIA_AUDIO << 8,
-		.class_mask = 0xffff00 },
-	{ 0 }
-};
-MODULE_DEVICE_TABLE(pci, maestro_r_pci_tbl);
-
-static struct pci_driver maestro_r_driver = {
-	.name		= "maestro_radio",
-	.id_table	= maestro_r_pci_tbl,
-	.probe		= maestro_probe,
-	.remove		= __devexit_p(maestro_remove),
-};
-
-static int __init maestro_radio_init(void)
-{
-	int retval = pci_register_driver(&maestro_r_driver);
-
-	if (retval)
-		printk(KERN_ERR "error during registration pci driver\n");
-
-	return retval;
-}
-
-static void __exit maestro_radio_exit(void)
-{
-	pci_unregister_driver(&maestro_r_driver);
-}
-
-module_init(maestro_radio_init);
-module_exit(maestro_radio_exit);
diff -druN linux-2.6.39-libre/drivers/media/radio/radio-maxiradio.c linux-3.0-rc7-libre/drivers/media/radio/radio-maxiradio.c
--- linux-2.6.39-libre/drivers/media/radio/radio-maxiradio.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/radio/radio-maxiradio.c	2011-07-11 19:51:52.000000000 -0400
@@ -412,8 +412,7 @@
 		goto err_out_free_region;
 	}
 
-	v4l2_info(v4l2_dev, "version " DRIVER_VERSION
-			" time " __TIME__ "  " __DATE__ "\n");
+	v4l2_info(v4l2_dev, "version " DRIVER_VERSION "\n");
 
 	v4l2_info(v4l2_dev, "found Guillemot MAXI Radio device (io = 0x%x)\n",
 	       dev->io);
diff -druN linux-2.6.39-libre/drivers/media/radio/radio-timb.c linux-3.0-rc7-libre/drivers/media/radio/radio-timb.c
--- linux-2.6.39-libre/drivers/media/radio/radio-timb.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/radio/radio-timb.c	2011-07-11 19:51:52.000000000 -0400
@@ -21,7 +21,6 @@
 #include <media/v4l2-ioctl.h>
 #include <media/v4l2-device.h>
 #include <linux/platform_device.h>
-#include <linux/mfd/core.h>
 #include <linux/interrupt.h>
 #include <linux/slab.h>
 #include <linux/i2c.h>
@@ -149,7 +148,7 @@
 
 static int __devinit timbradio_probe(struct platform_device *pdev)
 {
-	struct timb_radio_platform_data *pdata = mfd_get_data(pdev);
+	struct timb_radio_platform_data *pdata = pdev->dev.platform_data;
 	struct timbradio *tr;
 	int err;
 
diff -druN linux-2.6.39-libre/drivers/media/radio/radio-wl1273.c linux-3.0-rc7-libre/drivers/media/radio/radio-wl1273.c
--- linux-2.6.39-libre/drivers/media/radio/radio-wl1273.c	2011-05-19 02:10:54.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/radio/radio-wl1273.c	2011-07-21 06:53:26.000000000 -0400
@@ -1382,7 +1382,7 @@
 
 	switch (ctrl->id) {
 	case  V4L2_CID_TUNE_ANTENNA_CAPACITOR:
-		ctrl->val = wl1273_fm_get_tx_ctune(radio);
+		ctrl->cur.val = wl1273_fm_get_tx_ctune(radio);
 		break;
 
 	default:
@@ -1990,7 +1990,7 @@
 
 static int __devinit wl1273_fm_radio_probe(struct platform_device *pdev)
 {
-	struct wl1273_core **core = mfd_get_data(pdev);
+	struct wl1273_core **core = pdev->dev.platform_data;
 	struct wl1273_device *radio;
 	struct v4l2_ctrl *ctrl;
 	int r = 0;
diff -druN linux-2.6.39-libre/drivers/media/radio/si470x/radio-si470x-common.c linux-3.0-rc7-libre/drivers/media/radio/si470x/radio-si470x-common.c
--- linux-2.6.39-libre/drivers/media/radio/si470x/radio-si470x-common.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/radio/si470x/radio-si470x-common.c	2011-07-11 19:51:52.000000000 -0400
@@ -174,15 +174,27 @@
 	if (retval < 0)
 		goto done;
 
-	/* wait till tune operation has completed */
-	timeout = jiffies + msecs_to_jiffies(tune_timeout);
-	do {
-		retval = si470x_get_register(radio, STATUSRSSI);
-		if (retval < 0)
-			goto stop;
-		timed_out = time_after(jiffies, timeout);
-	} while (((radio->registers[STATUSRSSI] & STATUSRSSI_STC) == 0) &&
-		(!timed_out));
+	/* currently I2C driver only uses interrupt way to tune */
+	if (radio->stci_enabled) {
+		INIT_COMPLETION(radio->completion);
+
+		/* wait till tune operation has completed */
+		retval = wait_for_completion_timeout(&radio->completion,
+				msecs_to_jiffies(tune_timeout));
+		if (!retval)
+			timed_out = true;
+	} else {
+		/* wait till tune operation has completed */
+		timeout = jiffies + msecs_to_jiffies(tune_timeout);
+		do {
+			retval = si470x_get_register(radio, STATUSRSSI);
+			if (retval < 0)
+				goto stop;
+			timed_out = time_after(jiffies, timeout);
+		} while (((radio->registers[STATUSRSSI] & STATUSRSSI_STC) == 0)
+				&& (!timed_out));
+	}
+
 	if ((radio->registers[STATUSRSSI] & STATUSRSSI_STC) == 0)
 		dev_warn(&radio->videodev->dev, "tune does not complete\n");
 	if (timed_out)
@@ -310,15 +322,27 @@
 	if (retval < 0)
 		goto done;
 
-	/* wait till seek operation has completed */
-	timeout = jiffies + msecs_to_jiffies(seek_timeout);
-	do {
-		retval = si470x_get_register(radio, STATUSRSSI);
-		if (retval < 0)
-			goto stop;
-		timed_out = time_after(jiffies, timeout);
-	} while (((radio->registers[STATUSRSSI] & STATUSRSSI_STC) == 0) &&
-		(!timed_out));
+	/* currently I2C driver only uses interrupt way to seek */
+	if (radio->stci_enabled) {
+		INIT_COMPLETION(radio->completion);
+
+		/* wait till seek operation has completed */
+		retval = wait_for_completion_timeout(&radio->completion,
+				msecs_to_jiffies(seek_timeout));
+		if (!retval)
+			timed_out = true;
+	} else {
+		/* wait till seek operation has completed */
+		timeout = jiffies + msecs_to_jiffies(seek_timeout);
+		do {
+			retval = si470x_get_register(radio, STATUSRSSI);
+			if (retval < 0)
+				goto stop;
+			timed_out = time_after(jiffies, timeout);
+		} while (((radio->registers[STATUSRSSI] & STATUSRSSI_STC) == 0)
+				&& (!timed_out));
+	}
+
 	if ((radio->registers[STATUSRSSI] & STATUSRSSI_STC) == 0)
 		dev_warn(&radio->videodev->dev, "seek does not complete\n");
 	if (radio->registers[STATUSRSSI] & STATUSRSSI_SF)
diff -druN linux-2.6.39-libre/drivers/media/radio/si470x/radio-si470x.h linux-3.0-rc7-libre/drivers/media/radio/si470x/radio-si470x.h
--- linux-2.6.39-libre/drivers/media/radio/si470x/radio-si470x.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/radio/si470x/radio-si470x.h	2011-07-11 19:51:52.000000000 -0400
@@ -158,6 +158,9 @@
 	unsigned int rd_index;
 	unsigned int wr_index;
 
+	struct completion completion;
+	bool stci_enabled;		/* Seek/Tune Complete Interrupt */
+
 #if defined(CONFIG_USB_SI470X) || defined(CONFIG_USB_SI470X_MODULE)
 	/* reference to USB and video device */
 	struct usb_device *usbdev;
@@ -179,7 +182,6 @@
 
 #if defined(CONFIG_I2C_SI470X) || defined(CONFIG_I2C_SI470X_MODULE)
 	struct i2c_client *client;
-	struct work_struct radio_work;
 #endif
 };
 
diff -druN linux-2.6.39-libre/drivers/media/radio/si470x/radio-si470x-i2c.c linux-3.0-rc7-libre/drivers/media/radio/si470x/radio-si470x-i2c.c
--- linux-2.6.39-libre/drivers/media/radio/si470x/radio-si470x-i2c.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/radio/si470x/radio-si470x-i2c.c	2011-07-11 19:51:52.000000000 -0400
@@ -197,8 +197,9 @@
 		if (retval < 0)
 			goto done;
 
-		/* enable RDS interrupt */
+		/* enable RDS / STC interrupt */
 		radio->registers[SYSCONFIG1] |= SYSCONFIG1_RDSIEN;
+		radio->registers[SYSCONFIG1] |= SYSCONFIG1_STCIEN;
 		radio->registers[SYSCONFIG1] &= ~SYSCONFIG1_GPIO2;
 		radio->registers[SYSCONFIG1] |= 0x1 << 2;
 		retval = si470x_set_register(radio, SYSCONFIG1);
@@ -261,12 +262,11 @@
  **************************************************************************/
 
 /*
- * si470x_i2c_interrupt_work - rds processing function
+ * si470x_i2c_interrupt - interrupt handler
  */
-static void si470x_i2c_interrupt_work(struct work_struct *work)
+static irqreturn_t si470x_i2c_interrupt(int irq, void *dev_id)
 {
-	struct si470x_device *radio = container_of(work,
-			struct si470x_device, radio_work);
+	struct si470x_device *radio = dev_id;
 	unsigned char regnr;
 	unsigned char blocknum;
 	unsigned short bler; /* rds block errors */
@@ -274,21 +274,29 @@
 	unsigned char tmpbuf[3];
 	int retval = 0;
 
+	/* check Seek/Tune Complete */
+	retval = si470x_get_register(radio, STATUSRSSI);
+	if (retval < 0)
+		goto end;
+
+	if (radio->registers[STATUSRSSI] & STATUSRSSI_STC)
+		complete(&radio->completion);
+
 	/* safety checks */
 	if ((radio->registers[SYSCONFIG1] & SYSCONFIG1_RDS) == 0)
-		return;
+		goto end;
 
 	/* Update RDS registers */
-	for (regnr = 0; regnr < RDS_REGISTER_NUM; regnr++) {
+	for (regnr = 1; regnr < RDS_REGISTER_NUM; regnr++) {
 		retval = si470x_get_register(radio, STATUSRSSI + regnr);
 		if (retval < 0)
-			return;
+			goto end;
 	}
 
 	/* get rds blocks */
 	if ((radio->registers[STATUSRSSI] & STATUSRSSI_RDSR) == 0)
 		/* No RDS group ready, better luck next time */
-		return;
+		goto end;
 
 	for (blocknum = 0; blocknum < 4; blocknum++) {
 		switch (blocknum) {
@@ -342,19 +350,8 @@
 
 	if (radio->wr_index != radio->rd_index)
 		wake_up_interruptible(&radio->read_queue);
-}
-
-
-/*
- * si470x_i2c_interrupt - interrupt handler
- */
-static irqreturn_t si470x_i2c_interrupt(int irq, void *dev_id)
-{
-	struct si470x_device *radio = dev_id;
-
-	if (!work_pending(&radio->radio_work))
-		schedule_work(&radio->radio_work);
 
+end:
 	return IRQ_HANDLED;
 }
 
@@ -376,7 +373,6 @@
 		goto err_initial;
 	}
 
-	INIT_WORK(&radio->radio_work, si470x_i2c_interrupt_work);
 	radio->users = 0;
 	radio->client = client;
 	mutex_init(&radio->lock);
@@ -441,7 +437,11 @@
 	radio->rd_index = 0;
 	init_waitqueue_head(&radio->read_queue);
 
-	retval = request_irq(client->irq, si470x_i2c_interrupt,
+	/* mark Seek/Tune Complete Interrupt enabled */
+	radio->stci_enabled = true;
+	init_completion(&radio->completion);
+
+	retval = request_threaded_irq(client->irq, NULL, si470x_i2c_interrupt,
 			IRQF_TRIGGER_FALLING, DRIVER_NAME, radio);
 	if (retval) {
 		dev_err(&client->dev, "Failed to register interrupt\n");
@@ -479,7 +479,6 @@
 	struct si470x_device *radio = i2c_get_clientdata(client);
 
 	free_irq(client->irq, radio);
-	cancel_work_sync(&radio->radio_work);
 	video_unregister_device(radio->videodev);
 	kfree(radio);
 
@@ -491,8 +490,9 @@
 /*
  * si470x_i2c_suspend - suspend the device
  */
-static int si470x_i2c_suspend(struct i2c_client *client, pm_message_t mesg)
+static int si470x_i2c_suspend(struct device *dev)
 {
+	struct i2c_client *client = to_i2c_client(dev);
 	struct si470x_device *radio = i2c_get_clientdata(client);
 
 	/* power down */
@@ -507,8 +507,9 @@
 /*
  * si470x_i2c_resume - resume the device
  */
-static int si470x_i2c_resume(struct i2c_client *client)
+static int si470x_i2c_resume(struct device *dev)
 {
+	struct i2c_client *client = to_i2c_client(dev);
 	struct si470x_device *radio = i2c_get_clientdata(client);
 
 	/* power up : need 110ms */
@@ -519,9 +520,8 @@
 
 	return 0;
 }
-#else
-#define si470x_i2c_suspend	NULL
-#define si470x_i2c_resume	NULL
+
+static SIMPLE_DEV_PM_OPS(si470x_i2c_pm, si470x_i2c_suspend, si470x_i2c_resume);
 #endif
 
 
@@ -532,11 +532,12 @@
 	.driver = {
 		.name		= "si470x",
 		.owner		= THIS_MODULE,
+#ifdef CONFIG_PM
+		.pm		= &si470x_i2c_pm,
+#endif
 	},
 	.probe			= si470x_i2c_probe,
 	.remove			= __devexit_p(si470x_i2c_remove),
-	.suspend		= si470x_i2c_suspend,
-	.resume			= si470x_i2c_resume,
 	.id_table		= si470x_i2c_id,
 };
 
diff -druN linux-2.6.39-libre/drivers/media/radio/wl128x/fmdrv.h linux-3.0-rc7-libre/drivers/media/radio/wl128x/fmdrv.h
--- linux-2.6.39-libre/drivers/media/radio/wl128x/fmdrv.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/radio/wl128x/fmdrv.h	2011-07-11 19:51:52.000000000 -0400
@@ -55,8 +55,6 @@
 #define FM_DRV_TX_TIMEOUT      (5*HZ)	/* 5 seconds */
 #define FM_DRV_RX_SEEK_TIMEOUT (20*HZ)	/* 20 seconds */
 
-#define NO_OF_ENTRIES_IN_ARRAY(array) (sizeof(array) / sizeof(array[0]))
-
 #define fmerr(format, ...) \
 	printk(KERN_ERR "fmdrv: " format, ## __VA_ARGS__)
 #define fmwarn(format, ...) \
diff -druN linux-2.6.39-libre/drivers/media/radio/wl128x/fmdrv_v4l2.c linux-3.0-rc7-libre/drivers/media/radio/wl128x/fmdrv_v4l2.c
--- linux-2.6.39-libre/drivers/media/radio/wl128x/fmdrv_v4l2.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/radio/wl128x/fmdrv_v4l2.c	2011-07-11 19:51:52.000000000 -0400
@@ -191,7 +191,7 @@
 
 	switch (ctrl->id) {
 	case  V4L2_CID_TUNE_ANTENNA_CAPACITOR:
-		ctrl->val = fm_tx_get_tune_cap_val(fmdev);
+		ctrl->cur.val = fm_tx_get_tune_cap_val(fmdev);
 		break;
 	default:
 		fmwarn("%s: Unknown IOCTL: %d\n", __func__, ctrl->id);
diff -druN linux-2.6.39-libre/drivers/media/rc/fintek-cir.c linux-3.0-rc7-libre/drivers/media/rc/fintek-cir.c
--- linux-2.6.39-libre/drivers/media/rc/fintek-cir.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/media/rc/fintek-cir.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,689 @@
+/*
+ * Driver for Feature Integration Technology Inc. (aka Fintek) LPC CIR
+ *
+ * Copyright (C) 2011 Jarod Wilson <jarod@redhat.com>
+ *
+ * Special thanks to Fintek for providing hardware and spec sheets.
+ * This driver is based upon the nuvoton, ite and ene drivers for
+ * similar hardware.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public 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/pnp.h>
+#include <linux/io.h>
+#include <linux/interrupt.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <media/rc-core.h>
+#include <linux/pci_ids.h>
+
+#include "fintek-cir.h"
+
+/* write val to config reg */
+static inline void fintek_cr_write(struct fintek_dev *fintek, u8 val, u8 reg)
+{
+	fit_dbg("%s: reg 0x%02x, val 0x%02x  (ip/dp: %02x/%02x)",
+		__func__, reg, val, fintek->cr_ip, fintek->cr_dp);
+	outb(reg, fintek->cr_ip);
+	outb(val, fintek->cr_dp);
+}
+
+/* read val from config reg */
+static inline u8 fintek_cr_read(struct fintek_dev *fintek, u8 reg)
+{
+	u8 val;
+
+	outb(reg, fintek->cr_ip);
+	val = inb(fintek->cr_dp);
+
+	fit_dbg("%s: reg 0x%02x, val 0x%02x  (ip/dp: %02x/%02x)",
+		__func__, reg, val, fintek->cr_ip, fintek->cr_dp);
+	return val;
+}
+
+/* update config register bit without changing other bits */
+static inline void fintek_set_reg_bit(struct fintek_dev *fintek, u8 val, u8 reg)
+{
+	u8 tmp = fintek_cr_read(fintek, reg) | val;
+	fintek_cr_write(fintek, tmp, reg);
+}
+
+/* clear config register bit without changing other bits */
+static inline void fintek_clear_reg_bit(struct fintek_dev *fintek, u8 val, u8 reg)
+{
+	u8 tmp = fintek_cr_read(fintek, reg) & ~val;
+	fintek_cr_write(fintek, tmp, reg);
+}
+
+/* enter config mode */
+static inline void fintek_config_mode_enable(struct fintek_dev *fintek)
+{
+	/* Enabling Config Mode explicitly requires writing 2x */
+	outb(CONFIG_REG_ENABLE, fintek->cr_ip);
+	outb(CONFIG_REG_ENABLE, fintek->cr_ip);
+}
+
+/* exit config mode */
+static inline void fintek_config_mode_disable(struct fintek_dev *fintek)
+{
+	outb(CONFIG_REG_DISABLE, fintek->cr_ip);
+}
+
+/*
+ * When you want to address a specific logical device, write its logical
+ * device number to GCR_LOGICAL_DEV_NO
+ */
+static inline void fintek_select_logical_dev(struct fintek_dev *fintek, u8 ldev)
+{
+	fintek_cr_write(fintek, ldev, GCR_LOGICAL_DEV_NO);
+}
+
+/* write val to cir config register */
+static inline void fintek_cir_reg_write(struct fintek_dev *fintek, u8 val, u8 offset)
+{
+	outb(val, fintek->cir_addr + offset);
+}
+
+/* read val from cir config register */
+static u8 fintek_cir_reg_read(struct fintek_dev *fintek, u8 offset)
+{
+	u8 val;
+
+	val = inb(fintek->cir_addr + offset);
+
+	return val;
+}
+
+#define pr_reg(text, ...) \
+	printk(KERN_INFO KBUILD_MODNAME ": " text, ## __VA_ARGS__)
+
+/* dump current cir register contents */
+static void cir_dump_regs(struct fintek_dev *fintek)
+{
+	fintek_config_mode_enable(fintek);
+	fintek_select_logical_dev(fintek, LOGICAL_DEV_CIR);
+
+	pr_reg("%s: Dump CIR logical device registers:\n", FINTEK_DRIVER_NAME);
+	pr_reg(" * CR CIR BASE ADDR: 0x%x\n",
+	       (fintek_cr_read(fintek, CIR_CR_BASE_ADDR_HI) << 8) |
+		fintek_cr_read(fintek, CIR_CR_BASE_ADDR_LO));
+	pr_reg(" * CR CIR IRQ NUM:   0x%x\n",
+	       fintek_cr_read(fintek, CIR_CR_IRQ_SEL));
+
+	fintek_config_mode_disable(fintek);
+
+	pr_reg("%s: Dump CIR registers:\n", FINTEK_DRIVER_NAME);
+	pr_reg(" * STATUS:     0x%x\n", fintek_cir_reg_read(fintek, CIR_STATUS));
+	pr_reg(" * CONTROL:    0x%x\n", fintek_cir_reg_read(fintek, CIR_CONTROL));
+	pr_reg(" * RX_DATA:    0x%x\n", fintek_cir_reg_read(fintek, CIR_RX_DATA));
+	pr_reg(" * TX_CONTROL: 0x%x\n", fintek_cir_reg_read(fintek, CIR_TX_CONTROL));
+	pr_reg(" * TX_DATA:    0x%x\n", fintek_cir_reg_read(fintek, CIR_TX_DATA));
+}
+
+/* detect hardware features */
+static int fintek_hw_detect(struct fintek_dev *fintek)
+{
+	unsigned long flags;
+	u8 chip_major, chip_minor;
+	u8 vendor_major, vendor_minor;
+	u8 portsel, ir_class;
+	u16 vendor;
+	int ret = 0;
+
+	fintek_config_mode_enable(fintek);
+
+	/* Check if we're using config port 0x4e or 0x2e */
+	portsel = fintek_cr_read(fintek, GCR_CONFIG_PORT_SEL);
+	if (portsel == 0xff) {
+		fit_pr(KERN_INFO, "first portsel read was bunk, trying alt");
+		fintek_config_mode_disable(fintek);
+		fintek->cr_ip = CR_INDEX_PORT2;
+		fintek->cr_dp = CR_DATA_PORT2;
+		fintek_config_mode_enable(fintek);
+		portsel = fintek_cr_read(fintek, GCR_CONFIG_PORT_SEL);
+	}
+	fit_dbg("portsel reg: 0x%02x", portsel);
+
+	ir_class = fintek_cir_reg_read(fintek, CIR_CR_CLASS);
+	fit_dbg("ir_class reg: 0x%02x", ir_class);
+
+	switch (ir_class) {
+	case CLASS_RX_2TX:
+	case CLASS_RX_1TX:
+		fintek->hw_tx_capable = true;
+		break;
+	case CLASS_RX_ONLY:
+	default:
+		fintek->hw_tx_capable = false;
+		break;
+	}
+
+	chip_major = fintek_cr_read(fintek, GCR_CHIP_ID_HI);
+	chip_minor = fintek_cr_read(fintek, GCR_CHIP_ID_LO);
+
+	vendor_major = fintek_cr_read(fintek, GCR_VENDOR_ID_HI);
+	vendor_minor = fintek_cr_read(fintek, GCR_VENDOR_ID_LO);
+	vendor = vendor_major << 8 | vendor_minor;
+
+	if (vendor != VENDOR_ID_FINTEK)
+		fit_pr(KERN_WARNING, "Unknown vendor ID: 0x%04x", vendor);
+	else
+		fit_dbg("Read Fintek vendor ID from chip");
+
+	fintek_config_mode_disable(fintek);
+
+	spin_lock_irqsave(&fintek->fintek_lock, flags);
+	fintek->chip_major  = chip_major;
+	fintek->chip_minor  = chip_minor;
+	fintek->chip_vendor = vendor;
+	spin_unlock_irqrestore(&fintek->fintek_lock, flags);
+
+	return ret;
+}
+
+static void fintek_cir_ldev_init(struct fintek_dev *fintek)
+{
+	/* Select CIR logical device and enable */
+	fintek_select_logical_dev(fintek, LOGICAL_DEV_CIR);
+	fintek_cr_write(fintek, LOGICAL_DEV_ENABLE, CIR_CR_DEV_EN);
+
+	/* Write allocated CIR address and IRQ information to hardware */
+	fintek_cr_write(fintek, fintek->cir_addr >> 8, CIR_CR_BASE_ADDR_HI);
+	fintek_cr_write(fintek, fintek->cir_addr & 0xff, CIR_CR_BASE_ADDR_LO);
+
+	fintek_cr_write(fintek, fintek->cir_irq, CIR_CR_IRQ_SEL);
+
+	fit_dbg("CIR initialized, base io address: 0x%lx, irq: %d (len: %d)",
+		fintek->cir_addr, fintek->cir_irq, fintek->cir_port_len);
+}
+
+/* enable CIR interrupts */
+static void fintek_enable_cir_irq(struct fintek_dev *fintek)
+{
+	fintek_cir_reg_write(fintek, CIR_STATUS_IRQ_EN, CIR_STATUS);
+}
+
+static void fintek_cir_regs_init(struct fintek_dev *fintek)
+{
+	/* clear any and all stray interrupts */
+	fintek_cir_reg_write(fintek, CIR_STATUS_IRQ_MASK, CIR_STATUS);
+
+	/* and finally, enable interrupts */
+	fintek_enable_cir_irq(fintek);
+}
+
+static void fintek_enable_wake(struct fintek_dev *fintek)
+{
+	fintek_config_mode_enable(fintek);
+	fintek_select_logical_dev(fintek, LOGICAL_DEV_ACPI);
+
+	/* Allow CIR PME's to wake system */
+	fintek_set_reg_bit(fintek, ACPI_WAKE_EN_CIR_BIT, LDEV_ACPI_WAKE_EN_REG);
+	/* Enable CIR PME's */
+	fintek_set_reg_bit(fintek, ACPI_PME_CIR_BIT, LDEV_ACPI_PME_EN_REG);
+	/* Clear CIR PME status register */
+	fintek_set_reg_bit(fintek, ACPI_PME_CIR_BIT, LDEV_ACPI_PME_CLR_REG);
+	/* Save state */
+	fintek_set_reg_bit(fintek, ACPI_STATE_CIR_BIT, LDEV_ACPI_STATE_REG);
+
+	fintek_config_mode_disable(fintek);
+}
+
+static int fintek_cmdsize(u8 cmd, u8 subcmd)
+{
+	int datasize = 0;
+
+	switch (cmd) {
+	case BUF_COMMAND_NULL:
+		if (subcmd == BUF_HW_CMD_HEADER)
+			datasize = 1;
+		break;
+	case BUF_HW_CMD_HEADER:
+		if (subcmd == BUF_CMD_G_REVISION)
+			datasize = 2;
+		break;
+	case BUF_COMMAND_HEADER:
+		switch (subcmd) {
+		case BUF_CMD_S_CARRIER:
+		case BUF_CMD_S_TIMEOUT:
+		case BUF_RSP_PULSE_COUNT:
+			datasize = 2;
+			break;
+		case BUF_CMD_SIG_END:
+		case BUF_CMD_S_TXMASK:
+		case BUF_CMD_S_RXSENSOR:
+			datasize = 1;
+			break;
+		}
+	}
+
+	return datasize;
+}
+
+/* process ir data stored in driver buffer */
+static void fintek_process_rx_ir_data(struct fintek_dev *fintek)
+{
+	DEFINE_IR_RAW_EVENT(rawir);
+	u8 sample;
+	int i;
+
+	for (i = 0; i < fintek->pkts; i++) {
+		sample = fintek->buf[i];
+		switch (fintek->parser_state) {
+		case CMD_HEADER:
+			fintek->cmd = sample;
+			if ((fintek->cmd == BUF_COMMAND_HEADER) ||
+			    ((fintek->cmd & BUF_COMMAND_MASK) !=
+			     BUF_PULSE_BIT)) {
+				fintek->parser_state = SUBCMD;
+				continue;
+			}
+			fintek->rem = (fintek->cmd & BUF_LEN_MASK);
+			fit_dbg("%s: rem: 0x%02x", __func__, fintek->rem);
+			if (fintek->rem)
+				fintek->parser_state = PARSE_IRDATA;
+			else
+				ir_raw_event_reset(fintek->rdev);
+			break;
+		case SUBCMD:
+			fintek->rem = fintek_cmdsize(fintek->cmd, sample);
+			fintek->parser_state = CMD_DATA;
+			break;
+		case CMD_DATA:
+			fintek->rem--;
+			break;
+		case PARSE_IRDATA:
+			fintek->rem--;
+			init_ir_raw_event(&rawir);
+			rawir.pulse = ((sample & BUF_PULSE_BIT) != 0);
+			rawir.duration = US_TO_NS((sample & BUF_SAMPLE_MASK)
+					  * CIR_SAMPLE_PERIOD);
+
+			fit_dbg("Storing %s with duration %d",
+				rawir.pulse ? "pulse" : "space",
+				rawir.duration);
+			ir_raw_event_store_with_filter(fintek->rdev, &rawir);
+			break;
+		}
+
+		if ((fintek->parser_state != CMD_HEADER) && !fintek->rem)
+			fintek->parser_state = CMD_HEADER;
+	}
+
+	fintek->pkts = 0;
+
+	fit_dbg("Calling ir_raw_event_handle");
+	ir_raw_event_handle(fintek->rdev);
+}
+
+/* copy data from hardware rx register into driver buffer */
+static void fintek_get_rx_ir_data(struct fintek_dev *fintek, u8 rx_irqs)
+{
+	unsigned long flags;
+	u8 sample, status;
+
+	spin_lock_irqsave(&fintek->fintek_lock, flags);
+
+	/*
+	 * We must read data from CIR_RX_DATA until the hardware IR buffer
+	 * is empty and clears the RX_TIMEOUT and/or RX_RECEIVE flags in
+	 * the CIR_STATUS register
+	 */
+	do {
+		sample = fintek_cir_reg_read(fintek, CIR_RX_DATA);
+		fit_dbg("%s: sample: 0x%02x", __func__, sample);
+
+		fintek->buf[fintek->pkts] = sample;
+		fintek->pkts++;
+
+		status = fintek_cir_reg_read(fintek, CIR_STATUS);
+		if (!(status & CIR_STATUS_IRQ_EN))
+			break;
+	} while (status & rx_irqs);
+
+	fintek_process_rx_ir_data(fintek);
+
+	spin_unlock_irqrestore(&fintek->fintek_lock, flags);
+}
+
+static void fintek_cir_log_irqs(u8 status)
+{
+	fit_pr(KERN_INFO, "IRQ 0x%02x:%s%s%s%s%s", status,
+		status & CIR_STATUS_IRQ_EN	? " IRQEN"	: "",
+		status & CIR_STATUS_TX_FINISH	? " TXF"	: "",
+		status & CIR_STATUS_TX_UNDERRUN	? " TXU"	: "",
+		status & CIR_STATUS_RX_TIMEOUT	? " RXTO"	: "",
+		status & CIR_STATUS_RX_RECEIVE	? " RXOK"	: "");
+}
+
+/* interrupt service routine for incoming and outgoing CIR data */
+static irqreturn_t fintek_cir_isr(int irq, void *data)
+{
+	struct fintek_dev *fintek = data;
+	u8 status, rx_irqs;
+
+	fit_dbg_verbose("%s firing", __func__);
+
+	fintek_config_mode_enable(fintek);
+	fintek_select_logical_dev(fintek, LOGICAL_DEV_CIR);
+	fintek_config_mode_disable(fintek);
+
+	/*
+	 * Get IR Status register contents. Write 1 to ack/clear
+	 *
+	 * bit: reg name    - description
+	 *   3: TX_FINISH   - TX is finished
+	 *   2: TX_UNDERRUN - TX underrun
+	 *   1: RX_TIMEOUT  - RX data timeout
+	 *   0: RX_RECEIVE  - RX data received
+	 */
+	status = fintek_cir_reg_read(fintek, CIR_STATUS);
+	if (!(status & CIR_STATUS_IRQ_MASK) || status == 0xff) {
+		fit_dbg_verbose("%s exiting, IRSTS 0x%02x", __func__, status);
+		fintek_cir_reg_write(fintek, CIR_STATUS_IRQ_MASK, CIR_STATUS);
+		return IRQ_RETVAL(IRQ_NONE);
+	}
+
+	if (debug)
+		fintek_cir_log_irqs(status);
+
+	rx_irqs = status & (CIR_STATUS_RX_RECEIVE | CIR_STATUS_RX_TIMEOUT);
+	if (rx_irqs)
+		fintek_get_rx_ir_data(fintek, rx_irqs);
+
+	/* ack/clear all irq flags we've got */
+	fintek_cir_reg_write(fintek, status, CIR_STATUS);
+
+	fit_dbg_verbose("%s done", __func__);
+	return IRQ_RETVAL(IRQ_HANDLED);
+}
+
+static void fintek_enable_cir(struct fintek_dev *fintek)
+{
+	/* set IRQ enabled */
+	fintek_cir_reg_write(fintek, CIR_STATUS_IRQ_EN, CIR_STATUS);
+
+	fintek_config_mode_enable(fintek);
+
+	/* enable the CIR logical device */
+	fintek_select_logical_dev(fintek, LOGICAL_DEV_CIR);
+	fintek_cr_write(fintek, LOGICAL_DEV_ENABLE, CIR_CR_DEV_EN);
+
+	fintek_config_mode_disable(fintek);
+
+	/* clear all pending interrupts */
+	fintek_cir_reg_write(fintek, CIR_STATUS_IRQ_MASK, CIR_STATUS);
+
+	/* enable interrupts */
+	fintek_enable_cir_irq(fintek);
+}
+
+static void fintek_disable_cir(struct fintek_dev *fintek)
+{
+	fintek_config_mode_enable(fintek);
+
+	/* disable the CIR logical device */
+	fintek_select_logical_dev(fintek, LOGICAL_DEV_CIR);
+	fintek_cr_write(fintek, LOGICAL_DEV_DISABLE, CIR_CR_DEV_EN);
+
+	fintek_config_mode_disable(fintek);
+}
+
+static int fintek_open(struct rc_dev *dev)
+{
+	struct fintek_dev *fintek = dev->priv;
+	unsigned long flags;
+
+	spin_lock_irqsave(&fintek->fintek_lock, flags);
+	fintek_enable_cir(fintek);
+	spin_unlock_irqrestore(&fintek->fintek_lock, flags);
+
+	return 0;
+}
+
+static void fintek_close(struct rc_dev *dev)
+{
+	struct fintek_dev *fintek = dev->priv;
+	unsigned long flags;
+
+	spin_lock_irqsave(&fintek->fintek_lock, flags);
+	fintek_disable_cir(fintek);
+	spin_unlock_irqrestore(&fintek->fintek_lock, flags);
+}
+
+/* Allocate memory, probe hardware, and initialize everything */
+static int fintek_probe(struct pnp_dev *pdev, const struct pnp_device_id *dev_id)
+{
+	struct fintek_dev *fintek;
+	struct rc_dev *rdev;
+	int ret = -ENOMEM;
+
+	fintek = kzalloc(sizeof(struct fintek_dev), GFP_KERNEL);
+	if (!fintek)
+		return ret;
+
+	/* input device for IR remote (and tx) */
+	rdev = rc_allocate_device();
+	if (!rdev)
+		goto failure;
+
+	ret = -ENODEV;
+	/* validate pnp resources */
+	if (!pnp_port_valid(pdev, 0)) {
+		dev_err(&pdev->dev, "IR PNP Port not valid!\n");
+		goto failure;
+	}
+
+	if (!pnp_irq_valid(pdev, 0)) {
+		dev_err(&pdev->dev, "IR PNP IRQ not valid!\n");
+		goto failure;
+	}
+
+	fintek->cir_addr = pnp_port_start(pdev, 0);
+	fintek->cir_irq  = pnp_irq(pdev, 0);
+	fintek->cir_port_len = pnp_port_len(pdev, 0);
+
+	fintek->cr_ip = CR_INDEX_PORT;
+	fintek->cr_dp = CR_DATA_PORT;
+
+	spin_lock_init(&fintek->fintek_lock);
+
+	ret = -EBUSY;
+	/* now claim resources */
+	if (!request_region(fintek->cir_addr,
+			    fintek->cir_port_len, FINTEK_DRIVER_NAME))
+		goto failure;
+
+	if (request_irq(fintek->cir_irq, fintek_cir_isr, IRQF_SHARED,
+			FINTEK_DRIVER_NAME, (void *)fintek))
+		goto failure;
+
+	pnp_set_drvdata(pdev, fintek);
+	fintek->pdev = pdev;
+
+	ret = fintek_hw_detect(fintek);
+	if (ret)
+		goto failure;
+
+	/* Initialize CIR & CIR Wake Logical Devices */
+	fintek_config_mode_enable(fintek);
+	fintek_cir_ldev_init(fintek);
+	fintek_config_mode_disable(fintek);
+
+	/* Initialize CIR & CIR Wake Config Registers */
+	fintek_cir_regs_init(fintek);
+
+	/* Set up the rc device */
+	rdev->priv = fintek;
+	rdev->driver_type = RC_DRIVER_IR_RAW;
+	rdev->allowed_protos = RC_TYPE_ALL;
+	rdev->open = fintek_open;
+	rdev->close = fintek_close;
+	rdev->input_name = FINTEK_DESCRIPTION;
+	rdev->input_phys = "fintek/cir0";
+	rdev->input_id.bustype = BUS_HOST;
+	rdev->input_id.vendor = VENDOR_ID_FINTEK;
+	rdev->input_id.product = fintek->chip_major;
+	rdev->input_id.version = fintek->chip_minor;
+	rdev->dev.parent = &pdev->dev;
+	rdev->driver_name = FINTEK_DRIVER_NAME;
+	rdev->map_name = RC_MAP_RC6_MCE;
+	rdev->timeout = US_TO_NS(1000);
+	/* rx resolution is hardwired to 50us atm, 1, 25, 100 also possible */
+	rdev->rx_resolution = US_TO_NS(CIR_SAMPLE_PERIOD);
+
+	ret = rc_register_device(rdev);
+	if (ret)
+		goto failure;
+
+	device_init_wakeup(&pdev->dev, true);
+	fintek->rdev = rdev;
+	fit_pr(KERN_NOTICE, "driver has been successfully loaded\n");
+	if (debug)
+		cir_dump_regs(fintek);
+
+	return 0;
+
+failure:
+	if (fintek->cir_irq)
+		free_irq(fintek->cir_irq, fintek);
+	if (fintek->cir_addr)
+		release_region(fintek->cir_addr, fintek->cir_port_len);
+
+	rc_free_device(rdev);
+	kfree(fintek);
+
+	return ret;
+}
+
+static void __devexit fintek_remove(struct pnp_dev *pdev)
+{
+	struct fintek_dev *fintek = pnp_get_drvdata(pdev);
+	unsigned long flags;
+
+	spin_lock_irqsave(&fintek->fintek_lock, flags);
+	/* disable CIR */
+	fintek_disable_cir(fintek);
+	fintek_cir_reg_write(fintek, CIR_STATUS_IRQ_MASK, CIR_STATUS);
+	/* enable CIR Wake (for IR power-on) */
+	fintek_enable_wake(fintek);
+	spin_unlock_irqrestore(&fintek->fintek_lock, flags);
+
+	/* free resources */
+	free_irq(fintek->cir_irq, fintek);
+	release_region(fintek->cir_addr, fintek->cir_port_len);
+
+	rc_unregister_device(fintek->rdev);
+
+	kfree(fintek);
+}
+
+static int fintek_suspend(struct pnp_dev *pdev, pm_message_t state)
+{
+	struct fintek_dev *fintek = pnp_get_drvdata(pdev);
+	unsigned long flags;
+
+	fit_dbg("%s called", __func__);
+
+	spin_lock_irqsave(&fintek->fintek_lock, flags);
+
+	/* disable all CIR interrupts */
+	fintek_cir_reg_write(fintek, CIR_STATUS_IRQ_MASK, CIR_STATUS);
+
+	spin_unlock_irqrestore(&fintek->fintek_lock, flags);
+
+	fintek_config_mode_enable(fintek);
+
+	/* disable cir logical dev */
+	fintek_select_logical_dev(fintek, LOGICAL_DEV_CIR);
+	fintek_cr_write(fintek, LOGICAL_DEV_DISABLE, CIR_CR_DEV_EN);
+
+	fintek_config_mode_disable(fintek);
+
+	/* make sure wake is enabled */
+	fintek_enable_wake(fintek);
+
+	return 0;
+}
+
+static int fintek_resume(struct pnp_dev *pdev)
+{
+	int ret = 0;
+	struct fintek_dev *fintek = pnp_get_drvdata(pdev);
+
+	fit_dbg("%s called", __func__);
+
+	/* open interrupt */
+	fintek_enable_cir_irq(fintek);
+
+	/* Enable CIR logical device */
+	fintek_config_mode_enable(fintek);
+	fintek_select_logical_dev(fintek, LOGICAL_DEV_CIR);
+	fintek_cr_write(fintek, LOGICAL_DEV_ENABLE, CIR_CR_DEV_EN);
+
+	fintek_config_mode_disable(fintek);
+
+	fintek_cir_regs_init(fintek);
+
+	return ret;
+}
+
+static void fintek_shutdown(struct pnp_dev *pdev)
+{
+	struct fintek_dev *fintek = pnp_get_drvdata(pdev);
+	fintek_enable_wake(fintek);
+}
+
+static const struct pnp_device_id fintek_ids[] = {
+	{ "FIT0002", 0 },   /* CIR */
+	{ "", 0 },
+};
+
+static struct pnp_driver fintek_driver = {
+	.name		= FINTEK_DRIVER_NAME,
+	.id_table	= fintek_ids,
+	.flags		= PNP_DRIVER_RES_DO_NOT_CHANGE,
+	.probe		= fintek_probe,
+	.remove		= __devexit_p(fintek_remove),
+	.suspend	= fintek_suspend,
+	.resume		= fintek_resume,
+	.shutdown	= fintek_shutdown,
+};
+
+int fintek_init(void)
+{
+	return pnp_register_driver(&fintek_driver);
+}
+
+void fintek_exit(void)
+{
+	pnp_unregister_driver(&fintek_driver);
+}
+
+module_param(debug, int, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(debug, "Enable debugging output");
+
+MODULE_DEVICE_TABLE(pnp, fintek_ids);
+MODULE_DESCRIPTION(FINTEK_DESCRIPTION " driver");
+
+MODULE_AUTHOR("Jarod Wilson <jarod@redhat.com>");
+MODULE_LICENSE("GPL");
+
+module_init(fintek_init);
+module_exit(fintek_exit);
diff -druN linux-2.6.39-libre/drivers/media/rc/fintek-cir.h linux-3.0-rc7-libre/drivers/media/rc/fintek-cir.h
--- linux-2.6.39-libre/drivers/media/rc/fintek-cir.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/media/rc/fintek-cir.h	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,243 @@
+/*
+ * Driver for Feature Integration Technology Inc. (aka Fintek) LPC CIR
+ *
+ * Copyright (C) 2011 Jarod Wilson <jarod@redhat.com>
+ *
+ * Special thanks to Fintek for providing hardware and spec sheets.
+ * This driver is based upon the nuvoton, ite and ene drivers for
+ * similar hardware.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public 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/spinlock.h>
+#include <linux/ioctl.h>
+
+/* platform driver name to register */
+#define FINTEK_DRIVER_NAME	"fintek-cir"
+#define FINTEK_DESCRIPTION	"Fintek LPC SuperIO Consumer IR Transceiver"
+#define VENDOR_ID_FINTEK	0x1934
+
+
+/* debugging module parameter */
+static int debug;
+
+#define fit_pr(level, text, ...) \
+	printk(level KBUILD_MODNAME ": " text, ## __VA_ARGS__)
+
+#define fit_dbg(text, ...) \
+	if (debug) \
+		printk(KERN_DEBUG \
+			KBUILD_MODNAME ": " text "\n" , ## __VA_ARGS__)
+
+#define fit_dbg_verbose(text, ...) \
+	if (debug > 1) \
+		printk(KERN_DEBUG \
+			KBUILD_MODNAME ": " text "\n" , ## __VA_ARGS__)
+
+#define fit_dbg_wake(text, ...) \
+	if (debug > 2) \
+		printk(KERN_DEBUG \
+			KBUILD_MODNAME ": " text "\n" , ## __VA_ARGS__)
+
+
+#define TX_BUF_LEN 256
+#define RX_BUF_LEN 32
+
+struct fintek_dev {
+	struct pnp_dev *pdev;
+	struct rc_dev *rdev;
+
+	spinlock_t fintek_lock;
+
+	/* for rx */
+	u8 buf[RX_BUF_LEN];
+	unsigned int pkts;
+
+	struct {
+		spinlock_t lock;
+		u8 buf[TX_BUF_LEN];
+		unsigned int buf_count;
+		unsigned int cur_buf_num;
+		wait_queue_head_t queue;
+	} tx;
+
+	/* Config register index/data port pair */
+	u8 cr_ip;
+	u8 cr_dp;
+
+	/* hardware I/O settings */
+	unsigned long cir_addr;
+	int cir_irq;
+	int cir_port_len;
+
+	/* hardware id */
+	u8 chip_major;
+	u8 chip_minor;
+	u16 chip_vendor;
+
+	/* hardware features */
+	bool hw_learning_capable;
+	bool hw_tx_capable;
+
+	/* rx settings */
+	bool learning_enabled;
+	bool carrier_detect_enabled;
+
+	enum {
+		CMD_HEADER = 0,
+		SUBCMD,
+		CMD_DATA,
+		PARSE_IRDATA,
+	} parser_state;
+
+	u8 cmd, rem;
+
+	/* carrier period = 1 / frequency */
+	u32 carrier;
+};
+
+/* buffer packet constants, largely identical to mceusb.c */
+#define BUF_PULSE_BIT		0x80
+#define BUF_LEN_MASK		0x1f
+#define BUF_SAMPLE_MASK		0x7f
+
+#define BUF_COMMAND_HEADER	0x9f
+#define BUF_COMMAND_MASK	0xe0
+#define BUF_COMMAND_NULL	0x00
+#define BUF_HW_CMD_HEADER	0xff
+#define BUF_CMD_G_REVISION	0x0b
+#define BUF_CMD_S_CARRIER	0x06
+#define BUF_CMD_S_TIMEOUT	0x0c
+#define BUF_CMD_SIG_END		0x01
+#define BUF_CMD_S_TXMASK	0x08
+#define BUF_CMD_S_RXSENSOR	0x14
+#define BUF_RSP_PULSE_COUNT	0x15
+
+#define CIR_SAMPLE_PERIOD	50
+
+/*
+ * Configuration Register:
+ *  Index Port
+ *  Data Port
+ */
+#define CR_INDEX_PORT		0x2e
+#define CR_DATA_PORT		0x2f
+
+/* Possible alternate values, depends on how the chip is wired */
+#define CR_INDEX_PORT2		0x4e
+#define CR_DATA_PORT2		0x4f
+
+/*
+ * GCR_CONFIG_PORT_SEL bit 4 specifies which Index Port value is
+ * active. 1 = 0x4e, 0 = 0x2e
+ */
+#define PORT_SEL_PORT_4E_EN	0x10
+
+/* Extended Function Mode enable/disable magic values */
+#define CONFIG_REG_ENABLE	0x87
+#define CONFIG_REG_DISABLE	0xaa
+
+/* Chip IDs found in CR_CHIP_ID_{HI,LO} */
+#define CHIP_ID_HIGH_F71809U	0x04
+#define CHIP_ID_LOW_F71809U	0x08
+
+/*
+ * Global control regs we need to care about:
+ *      Global Control                  def.
+ *      Register name           addr    val. */
+#define GCR_SOFTWARE_RESET	0x02 /* 0x00 */
+#define GCR_LOGICAL_DEV_NO	0x07 /* 0x00 */
+#define GCR_CHIP_ID_HI		0x20 /* 0x04 */
+#define GCR_CHIP_ID_LO		0x21 /* 0x08 */
+#define GCR_VENDOR_ID_HI	0x23 /* 0x19 */
+#define GCR_VENDOR_ID_LO	0x24 /* 0x34 */
+#define GCR_CONFIG_PORT_SEL	0x25 /* 0x01 */
+#define GCR_KBMOUSE_WAKEUP	0x27
+
+#define LOGICAL_DEV_DISABLE	0x00
+#define LOGICAL_DEV_ENABLE	0x01
+
+/* Logical device number of the CIR function */
+#define LOGICAL_DEV_CIR		0x05
+
+/* CIR Logical Device (LDN 0x08) config registers */
+#define CIR_CR_COMMAND_INDEX	0x04
+#define CIR_CR_IRCS		0x05 /* Before host writes command to IR, host
+					must set to 1. When host finshes write
+					command to IR, host must clear to 0. */
+#define CIR_CR_COMMAND_DATA	0x06 /* Host read or write comand data */
+#define CIR_CR_CLASS		0x07 /* 0xff = rx-only, 0x66 = rx + 2 tx,
+					0x33 = rx + 1 tx */
+#define CIR_CR_DEV_EN		0x30 /* bit0 = 1 enables CIR */
+#define CIR_CR_BASE_ADDR_HI	0x60 /* MSB of CIR IO base addr */
+#define CIR_CR_BASE_ADDR_LO	0x61 /* LSB of CIR IO base addr */
+#define CIR_CR_IRQ_SEL		0x70 /* bits3-0 store CIR IRQ */
+#define CIR_CR_PSOUT_STATUS	0xf1
+#define CIR_CR_WAKE_KEY3_ADDR	0xf8
+#define CIR_CR_WAKE_KEY3_CODE	0xf9
+#define CIR_CR_WAKE_KEY3_DC	0xfa
+#define CIR_CR_WAKE_CONTROL	0xfb
+#define CIR_CR_WAKE_KEY12_ADDR	0xfc
+#define CIR_CR_WAKE_KEY4_ADDR	0xfd
+#define CIR_CR_WAKE_KEY5_ADDR	0xfe
+
+#define CLASS_RX_ONLY		0xff
+#define CLASS_RX_2TX		0x66
+#define CLASS_RX_1TX		0x33
+
+/* CIR device registers */
+#define CIR_STATUS		0x00
+#define CIR_RX_DATA		0x01
+#define CIR_TX_CONTROL		0x02
+#define CIR_TX_DATA		0x03
+#define CIR_CONTROL		0x04
+
+/* Bits to enable CIR wake */
+#define LOGICAL_DEV_ACPI	0x01
+#define LDEV_ACPI_WAKE_EN_REG	0xe8
+#define ACPI_WAKE_EN_CIR_BIT	0x04
+
+#define LDEV_ACPI_PME_EN_REG	0xf0
+#define LDEV_ACPI_PME_CLR_REG	0xf1
+#define ACPI_PME_CIR_BIT	0x02
+
+#define LDEV_ACPI_STATE_REG	0xf4
+#define ACPI_STATE_CIR_BIT	0x20
+
+/*
+ * CIR status register (0x00):
+ *   7 - CIR_IRQ_EN (1 = enable CIR IRQ, 0 = disable)
+ *   3 - TX_FINISH (1 when TX finished, write 1 to clear)
+ *   2 - TX_UNDERRUN (1 on TX underrun, write 1 to clear)
+ *   1 - RX_TIMEOUT (1 on RX timeout, write 1 to clear)
+ *   0 - RX_RECEIVE (1 on RX receive, write 1 to clear)
+ */
+#define CIR_STATUS_IRQ_EN	0x80
+#define CIR_STATUS_TX_FINISH	0x08
+#define CIR_STATUS_TX_UNDERRUN	0x04
+#define CIR_STATUS_RX_TIMEOUT	0x02
+#define CIR_STATUS_RX_RECEIVE	0x01
+#define CIR_STATUS_IRQ_MASK	0x0f
+
+/*
+ * CIR TX control register (0x02):
+ *   7 - TX_START (1 to indicate TX start, auto-cleared when done)
+ *   6 - TX_END (1 to indicate TX data written to TX fifo)
+ */
+#define CIR_TX_CONTROL_TX_START	0x80
+#define CIR_TX_CONTROL_TX_END	0x40
+
diff -druN linux-2.6.39-libre/drivers/media/rc/imon.c linux-3.0-rc7-libre/drivers/media/rc/imon.c
--- linux-2.6.39-libre/drivers/media/rc/imon.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/rc/imon.c	2011-07-11 19:51:52.000000000 -0400
@@ -307,6 +307,14 @@
 	/* 0xffdc iMON MCE VFD */
 	{ 0x00010000ffffffeell, KEY_VOLUMEUP },
 	{ 0x01000000ffffffeell, KEY_VOLUMEDOWN },
+	{ 0x00000001ffffffeell, KEY_MUTE },
+	{ 0x0000000fffffffeell, KEY_MEDIA },
+	{ 0x00000012ffffffeell, KEY_UP },
+	{ 0x00000013ffffffeell, KEY_DOWN },
+	{ 0x00000014ffffffeell, KEY_LEFT },
+	{ 0x00000015ffffffeell, KEY_RIGHT },
+	{ 0x00000016ffffffeell, KEY_ENTER },
+	{ 0x00000017ffffffeell, KEY_ESC },
 	/* iMON Knob values */
 	{ 0x000100ffffffffeell, KEY_VOLUMEUP },
 	{ 0x010000ffffffffeell, KEY_VOLUMEDOWN },
@@ -443,16 +451,6 @@
 	} else {
 		ictx->display_isopen = false;
 		dev_dbg(ictx->dev, "display port closed\n");
-		if (!ictx->dev_present_intf0) {
-			/*
-			 * Device disconnected before close and IR port is not
-			 * open. If IR port is open, context will be deleted by
-			 * ir_close.
-			 */
-			mutex_unlock(&ictx->lock);
-			free_imon_context(ictx);
-			return retval;
-		}
 	}
 
 	mutex_unlock(&ictx->lock);
@@ -1492,7 +1490,6 @@
 	struct device *dev = ictx->dev;
 	unsigned long flags;
 	u32 kc;
-	bool norelease = false;
 	int i;
 	u64 scancode;
 	int press_type = 0;
@@ -1560,7 +1557,6 @@
 	     !(buf[1] & 0x1 || buf[1] >> 2 & 0x1))) {
 		len = 8;
 		imon_pad_to_keys(ictx, buf);
-		norelease = true;
 	}
 
 	if (debug) {
@@ -1594,16 +1590,16 @@
 	/* Only panel type events left to process now */
 	spin_lock_irqsave(&ictx->kc_lock, flags);
 
+	do_gettimeofday(&t);
 	/* KEY_MUTE repeats from knob need to be suppressed */
 	if (ictx->kc == KEY_MUTE && ictx->kc == ictx->last_keycode) {
-		do_gettimeofday(&t);
 		msec = tv2int(&t, &prev_time);
-		prev_time = t;
 		if (msec < ictx->idev->rep[REP_DELAY]) {
 			spin_unlock_irqrestore(&ictx->kc_lock, flags);
 			return;
 		}
 	}
+	prev_time = t;
 	kc = ictx->kc;
 
 	spin_unlock_irqrestore(&ictx->kc_lock, flags);
@@ -1615,7 +1611,9 @@
 	input_report_key(ictx->idev, kc, 0);
 	input_sync(ictx->idev);
 
+	spin_lock_irqsave(&ictx->kc_lock, flags);
 	ictx->last_keycode = kc;
+	spin_unlock_irqrestore(&ictx->kc_lock, flags);
 
 	return;
 
@@ -1752,6 +1750,8 @@
 		detected_display_type = IMON_DISPLAY_TYPE_VFD;
 		break;
 	/* iMON VFD, MCE IR */
+	case 0x46:
+	case 0x7e:
 	case 0x9e:
 		dev_info(ictx->dev, "0xffdc iMON VFD, MCE IR");
 		detected_display_type = IMON_DISPLAY_TYPE_VFD;
@@ -1767,6 +1767,9 @@
 		dev_info(ictx->dev, "Unknown 0xffdc device, "
 			 "defaulting to VFD and iMON IR");
 		detected_display_type = IMON_DISPLAY_TYPE_VFD;
+		/* We don't know which one it is, allow user to set the
+		 * RC6 one from userspace if OTHER wasn't correct. */
+		allowed_protos |= RC_TYPE_RC6;
 		break;
 	}
 
@@ -1982,7 +1985,7 @@
 	return touch;
 
 touch_register_failed:
-	input_free_device(ictx->touch);
+	input_free_device(touch);
 
 touch_alloc_failed:
 	return NULL;
@@ -2274,14 +2277,12 @@
 	struct usb_host_interface *iface_desc = NULL;
 	struct usb_interface *first_if;
 	struct device *dev = &interface->dev;
-	int ifnum, code_length, sysfs_err;
+	int ifnum, sysfs_err;
 	int ret = 0;
 	struct imon_context *ictx = NULL;
 	struct imon_context *first_if_ctx = NULL;
 	u16 vendor, product;
 
-	code_length = BUF_CHUNK_SIZE * 8;
-
 	usbdev     = usb_get_dev(interface_to_usbdev(interface));
 	iface_desc = interface->cur_altsetting;
 	ifnum      = iface_desc->desc.bInterfaceNumber;
@@ -2366,8 +2367,6 @@
 	dev = ictx->dev;
 	ifnum = interface->cur_altsetting->desc.bInterfaceNumber;
 
-	mutex_lock(&ictx->lock);
-
 	/*
 	 * sysfs_remove_group is safe to call even if sysfs_create_group
 	 * hasn't been called
@@ -2391,24 +2390,20 @@
 		if (ictx->display_supported) {
 			if (ictx->display_type == IMON_DISPLAY_TYPE_LCD)
 				usb_deregister_dev(interface, &imon_lcd_class);
-			else
+			else if (ictx->display_type == IMON_DISPLAY_TYPE_VFD)
 				usb_deregister_dev(interface, &imon_vfd_class);
 		}
 	} else {
 		ictx->dev_present_intf1 = false;
 		usb_kill_urb(ictx->rx_urb_intf1);
-		if (ictx->display_type == IMON_DISPLAY_TYPE_VGA)
+		if (ictx->display_type == IMON_DISPLAY_TYPE_VGA) {
 			input_unregister_device(ictx->touch);
+			del_timer_sync(&ictx->ttimer);
+		}
 	}
 
-	if (!ictx->dev_present_intf0 && !ictx->dev_present_intf1) {
-		if (ictx->display_type == IMON_DISPLAY_TYPE_VGA)
-			del_timer_sync(&ictx->ttimer);
-		mutex_unlock(&ictx->lock);
-		if (!ictx->display_isopen)
-			free_imon_context(ictx);
-	} else
-		mutex_unlock(&ictx->lock);
+	if (!ictx->dev_present_intf0 && !ictx->dev_present_intf1)
+		free_imon_context(ictx);
 
 	mutex_unlock(&driver_lock);
 
diff -druN linux-2.6.39-libre/drivers/media/rc/ir-raw.c linux-3.0-rc7-libre/drivers/media/rc/ir-raw.c
--- linux-2.6.39-libre/drivers/media/rc/ir-raw.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/rc/ir-raw.c	2011-07-11 19:51:52.000000000 -0400
@@ -114,18 +114,20 @@
 	s64			delta; /* ns */
 	DEFINE_IR_RAW_EVENT(ev);
 	int			rc = 0;
+	int			delay;
 
 	if (!dev->raw)
 		return -EINVAL;
 
 	now = ktime_get();
 	delta = ktime_to_ns(ktime_sub(now, dev->raw->last_event));
+	delay = MS_TO_NS(dev->input_dev->rep[REP_DELAY]);
 
 	/* Check for a long duration since last event or if we're
 	 * being called for the first time, note that delta can't
 	 * possibly be negative.
 	 */
-	if (delta > IR_MAX_DURATION || !dev->raw->last_type)
+	if (delta > delay || !dev->raw->last_type)
 		type |= IR_START_EVENT;
 	else
 		ev.duration = delta;
diff -druN linux-2.6.39-libre/drivers/media/rc/ite-cir.c linux-3.0-rc7-libre/drivers/media/rc/ite-cir.c
--- linux-2.6.39-libre/drivers/media/rc/ite-cir.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/rc/ite-cir.c	2011-07-11 19:51:52.000000000 -0400
@@ -1250,11 +1250,9 @@
 	ite_dbg("%s called", __func__);
 
 	/* clear out all interrupt enable flags */
-	it8709_wr(dev,
-			    it8709_rr(dev,
-				      IT85_C0IER) & ~(IT85_IEC | IT85_RFOIE |
-						      IT85_RDAIE |
-						      IT85_TLDLIE), IT85_C0IER);
+	it8709_wr(dev, it8709_rr(dev, IT85_C0IER) &
+			~(IT85_IEC | IT85_RFOIE | IT85_RDAIE | IT85_TLDLIE),
+		  IT85_C0IER);
 
 	/* disable the receiver */
 	it8709_disable_rx(dev);
@@ -1270,11 +1268,9 @@
 	ite_dbg("%s called", __func__);
 
 	/* disable all the interrupts */
-	it8709_wr(dev,
-			    it8709_rr(dev,
-				      IT85_C0IER) & ~(IT85_IEC | IT85_RFOIE |
-						      IT85_RDAIE |
-						      IT85_TLDLIE), IT85_C0IER);
+	it8709_wr(dev, it8709_rr(dev, IT85_C0IER) &
+			~(IT85_IEC | IT85_RFOIE | IT85_RDAIE | IT85_TLDLIE),
+		  IT85_C0IER);
 
 	/* program the baud rate divisor */
 	it8709_wr(dev, ITE_BAUDRATE_DIVISOR & 0xff, IT85_C0BDLR);
@@ -1282,28 +1278,22 @@
 			IT85_C0BDHR);
 
 	/* program the C0MSTCR register defaults */
-	it8709_wr(dev, (it8709_rr(dev, IT85_C0MSTCR) & ~(IT85_ILSEL |
-								   IT85_ILE
-								   | IT85_FIFOTL
-								   |
-								   IT85_FIFOCLR
-								   |
-								   IT85_RESET))
-			    | IT85_FIFOTL_DEFAULT, IT85_C0MSTCR);
+	it8709_wr(dev, (it8709_rr(dev, IT85_C0MSTCR) &
+			~(IT85_ILSEL | IT85_ILE | IT85_FIFOTL
+			  | IT85_FIFOCLR | IT85_RESET)) | IT85_FIFOTL_DEFAULT,
+		  IT85_C0MSTCR);
 
 	/* program the C0RCR register defaults */
-	it8709_wr(dev,
-			    (it8709_rr(dev, IT85_C0RCR) &
-			     ~(IT85_RXEN | IT85_RDWOS | IT85_RXEND
-			       | IT85_RXACT | IT85_RXDCR)) |
-			    ITE_RXDCR_DEFAULT, IT85_C0RCR);
+	it8709_wr(dev, (it8709_rr(dev, IT85_C0RCR) &
+			~(IT85_RXEN | IT85_RDWOS | IT85_RXEND | IT85_RXACT
+			  | IT85_RXDCR)) | ITE_RXDCR_DEFAULT,
+		  IT85_C0RCR);
 
 	/* program the C0TCR register defaults */
-	it8709_wr(dev, (it8709_rr(dev, IT85_C0TCR)
-				  &~(IT85_TXMPM | IT85_TXMPW))
-			    |IT85_TXRLE | IT85_TXENDF |
-			    IT85_TXMPM_DEFAULT |
-			    IT85_TXMPW_DEFAULT, IT85_C0TCR);
+	it8709_wr(dev, (it8709_rr(dev, IT85_C0TCR) & ~(IT85_TXMPM | IT85_TXMPW))
+			| IT85_TXRLE | IT85_TXENDF | IT85_TXMPM_DEFAULT
+			| IT85_TXMPW_DEFAULT,
+		  IT85_C0TCR);
 
 	/* program the carrier parameters */
 	ite_set_carrier_params(dev);
@@ -1357,6 +1347,7 @@
 	{	/* 0: ITE8704 */
 	       .model = "ITE8704 CIR transceiver",
 	       .io_region_size = IT87_IOREG_LENGTH,
+	       .io_rsrc_no = 0,
 	       .hw_tx_capable = true,
 	       .sample_period = (u32) (1000000000ULL / 115200),
 	       .tx_carrier_freq = 38000,
@@ -1381,6 +1372,7 @@
 	{	/* 1: ITE8713 */
 	       .model = "ITE8713 CIR transceiver",
 	       .io_region_size = IT87_IOREG_LENGTH,
+	       .io_rsrc_no = 0,
 	       .hw_tx_capable = true,
 	       .sample_period = (u32) (1000000000ULL / 115200),
 	       .tx_carrier_freq = 38000,
@@ -1405,6 +1397,7 @@
 	{	/* 2: ITE8708 */
 	       .model = "ITE8708 CIR transceiver",
 	       .io_region_size = IT8708_IOREG_LENGTH,
+	       .io_rsrc_no = 0,
 	       .hw_tx_capable = true,
 	       .sample_period = (u32) (1000000000ULL / 115200),
 	       .tx_carrier_freq = 38000,
@@ -1430,6 +1423,7 @@
 	{	/* 3: ITE8709 */
 	       .model = "ITE8709 CIR transceiver",
 	       .io_region_size = IT8709_IOREG_LENGTH,
+	       .io_rsrc_no = 2,
 	       .hw_tx_capable = true,
 	       .sample_period = (u32) (1000000000ULL / 115200),
 	       .tx_carrier_freq = 38000,
@@ -1471,6 +1465,7 @@
 	struct rc_dev *rdev = NULL;
 	int ret = -ENOMEM;
 	int model_no;
+	int io_rsrc_no;
 
 	ite_dbg("%s called", __func__);
 
@@ -1500,10 +1495,11 @@
 
 	/* get the description for the device */
 	dev_desc = &ite_dev_descs[model_no];
+	io_rsrc_no = dev_desc->io_rsrc_no;
 
 	/* validate pnp resources */
-	if (!pnp_port_valid(pdev, 0) ||
-	    pnp_port_len(pdev, 0) != dev_desc->io_region_size) {
+	if (!pnp_port_valid(pdev, io_rsrc_no) ||
+	    pnp_port_len(pdev, io_rsrc_no) != dev_desc->io_region_size) {
 		dev_err(&pdev->dev, "IR PNP Port not valid!\n");
 		goto failure;
 	}
@@ -1514,7 +1510,7 @@
 	}
 
 	/* store resource values */
-	itdev->cir_addr = pnp_port_start(pdev, 0);
+	itdev->cir_addr = pnp_port_start(pdev, io_rsrc_no);
 	itdev->cir_irq = pnp_irq(pdev, 0);
 
 	/* initialize spinlocks */
@@ -1660,6 +1656,9 @@
 
 	ite_dbg("%s called", __func__);
 
+	/* wait for any transmission to end */
+	wait_event_interruptible(dev->tx_ended, !dev->transmitting);
+
 	spin_lock_irqsave(&dev->lock, flags);
 
 	/* disable all interrupts */
@@ -1680,13 +1679,10 @@
 
 	spin_lock_irqsave(&dev->lock, flags);
 
-	if (dev->transmitting) {
-		/* wake up the transmitter */
-		wake_up_interruptible(&dev->tx_queue);
-	} else {
-		/* enable the receiver */
-		dev->params.enable_rx(dev);
-	}
+	/* reinitialize hardware config registers */
+	dev->params.init_hardware(dev);
+	/* enable the receiver */
+	dev->params.enable_rx(dev);
 
 	spin_unlock_irqrestore(&dev->lock, flags);
 
diff -druN linux-2.6.39-libre/drivers/media/rc/ite-cir.h linux-3.0-rc7-libre/drivers/media/rc/ite-cir.h
--- linux-2.6.39-libre/drivers/media/rc/ite-cir.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/rc/ite-cir.h	2011-07-11 19:51:52.000000000 -0400
@@ -57,6 +57,9 @@
 	/* size of the I/O region */
 	int io_region_size;
 
+	/* IR pnp I/O resource number */
+	int io_rsrc_no;
+
 	/* true if the hardware supports transmission */
 	bool hw_tx_capable;
 
diff -druN linux-2.6.39-libre/drivers/media/rc/Kconfig linux-3.0-rc7-libre/drivers/media/rc/Kconfig
--- linux-2.6.39-libre/drivers/media/rc/Kconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/rc/Kconfig	2011-07-11 19:51:52.000000000 -0400
@@ -148,6 +148,18 @@
 	   To compile this driver as a module, choose M here: the
 	   module will be called ite-cir.
 
+config IR_FINTEK
+	tristate "Fintek Consumer Infrared Transceiver"
+	depends on PNP
+	depends on RC_CORE
+	---help---
+	   Say Y here to enable support for integrated infrared receiver
+	   /transciever made by Fintek. This chip is found on assorted
+	   Jetway motherboards (and of course, possibly others).
+
+	   To compile this driver as a module, choose M here: the
+	   module will be called fintek-cir.
+
 config IR_NUVOTON
 	tristate "Nuvoton w836x7hg Consumer Infrared Transceiver"
 	depends on PNP
@@ -161,6 +173,17 @@
 	   To compile this driver as a module, choose M here: the
 	   module will be called nuvoton-cir.
 
+config IR_REDRAT3
+	tristate "RedRat3 IR Transceiver"
+	depends on USB_ARCH_HAS_HCD
+	depends on RC_CORE
+	select USB
+	---help---
+	   Say Y here if you want to use a RedRat3 Infrared Transceiver.
+
+	   To compile this driver as a module, choose M here: the
+	   module will be called redrat3.
+
 config IR_STREAMZAP
 	tristate "Streamzap PC Remote IR Receiver"
 	depends on USB_ARCH_HAS_HCD
diff -druN linux-2.6.39-libre/drivers/media/rc/keymaps/Makefile linux-3.0-rc7-libre/drivers/media/rc/keymaps/Makefile
--- linux-2.6.39-libre/drivers/media/rc/keymaps/Makefile	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/rc/keymaps/Makefile	2011-07-11 19:51:52.000000000 -0400
@@ -77,6 +77,7 @@
 			rc-terratec-slim.o \
 			rc-terratec-slim-2.o \
 			rc-tevii-nec.o \
+			rc-tivo.o \
 			rc-total-media-in-hand.o \
 			rc-trekstor.o \
 			rc-tt-1500.o \
diff -druN linux-2.6.39-libre/drivers/media/rc/keymaps/rc-avermedia-cardbus.c linux-3.0-rc7-libre/drivers/media/rc/keymaps/rc-avermedia-cardbus.c
--- linux-2.6.39-libre/drivers/media/rc/keymaps/rc-avermedia-cardbus.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/rc/keymaps/rc-avermedia-cardbus.c	2011-07-11 19:51:52.000000000 -0400
@@ -52,7 +52,7 @@
 	{ 0x28, KEY_SELECT },		/* Select */
 	{ 0x29, KEY_BLUE },		/* Blue/Picture */
 	{ 0x2a, KEY_BACKSPACE },	/* Back */
-	{ 0x2b, KEY_MEDIA },		/* PIP (Picture-in-picture) */
+	{ 0x2b, KEY_VIDEO },		/* PIP (Picture-in-picture) */
 	{ 0x2c, KEY_DOWN },
 	{ 0x2e, KEY_DOT },
 	{ 0x2f, KEY_TV },		/* Live TV */
diff -druN linux-2.6.39-libre/drivers/media/rc/keymaps/rc-imon-mce.c linux-3.0-rc7-libre/drivers/media/rc/keymaps/rc-imon-mce.c
--- linux-2.6.39-libre/drivers/media/rc/keymaps/rc-imon-mce.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/rc/keymaps/rc-imon-mce.c	2011-07-11 19:51:52.000000000 -0400
@@ -111,7 +111,7 @@
 	{ 0x800ff44d, KEY_TITLE },
 
 	{ 0x800ff40c, KEY_POWER },
-	{ 0x800ff40d, KEY_LEFTMETA }, /* Windows MCE button */
+	{ 0x800ff40d, KEY_MEDIA }, /* Windows MCE button */
 
 };
 
diff -druN linux-2.6.39-libre/drivers/media/rc/keymaps/rc-imon-pad.c linux-3.0-rc7-libre/drivers/media/rc/keymaps/rc-imon-pad.c
--- linux-2.6.39-libre/drivers/media/rc/keymaps/rc-imon-pad.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/rc/keymaps/rc-imon-pad.c	2011-07-11 19:51:52.000000000 -0400
@@ -87,7 +87,7 @@
 
 	{ 0x2b8515b7, KEY_VIDEO },
 	{ 0x299195b7, KEY_AUDIO },
-	{ 0x2ba115b7, KEY_CAMERA },
+	{ 0x2ba115b7, KEY_IMAGES },
 	{ 0x28a515b7, KEY_TV },
 	{ 0x29a395b7, KEY_DVD },
 	{ 0x29a295b7, KEY_DVD },
@@ -97,7 +97,7 @@
 	{ 0x2ba395b7, KEY_MENU },
 
 	{ 0x288515b7, KEY_BOOKMARKS },
-	{ 0x2ab715b7, KEY_MEDIA }, /* Thumbnail */
+	{ 0x2ab715b7, KEY_CAMERA }, /* Thumbnail */
 	{ 0x298595b7, KEY_SUBTITLE },
 	{ 0x2b8595b7, KEY_LANGUAGE },
 
@@ -125,7 +125,7 @@
 	{ 0x2b8195b7, KEY_CONTEXT_MENU }, /* Left Menu*/
 	{ 0x02000065, KEY_COMPOSE }, /* RightMenu */
 	{ 0x28b715b7, KEY_COMPOSE }, /* RightMenu */
-	{ 0x2ab195b7, KEY_LEFTMETA }, /* Go or MultiMon */
+	{ 0x2ab195b7, KEY_MEDIA }, /* Go or MultiMon */
 	{ 0x29b715b7, KEY_DASHBOARD }, /* AppLauncher */
 };
 
diff -druN linux-2.6.39-libre/drivers/media/rc/keymaps/rc-kworld-plus-tv-analog.c linux-3.0-rc7-libre/drivers/media/rc/keymaps/rc-kworld-plus-tv-analog.c
--- linux-2.6.39-libre/drivers/media/rc/keymaps/rc-kworld-plus-tv-analog.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/rc/keymaps/rc-kworld-plus-tv-analog.c	2011-07-11 19:51:52.000000000 -0400
@@ -17,7 +17,7 @@
  */
 
 static struct rc_map_table kworld_plus_tv_analog[] = {
-	{ 0x0c, KEY_LEFTMETA },		/* Kworld key */
+	{ 0x0c, KEY_MEDIA },		/* Kworld key */
 	{ 0x16, KEY_CLOSECD },		/* -> ) */
 	{ 0x1d, KEY_POWER2 },
 
diff -druN linux-2.6.39-libre/drivers/media/rc/keymaps/rc-lme2510.c linux-3.0-rc7-libre/drivers/media/rc/keymaps/rc-lme2510.c
--- linux-2.6.39-libre/drivers/media/rc/keymaps/rc-lme2510.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/rc/keymaps/rc-lme2510.c	2011-07-11 19:51:52.000000000 -0400
@@ -14,81 +14,81 @@
 
 static struct rc_map_table lme2510_rc[] = {
 	/* Type 1 - 26 buttons */
-	{ 0xef12ba45, KEY_0 },
-	{ 0xef12a05f, KEY_1 },
-	{ 0xef12af50, KEY_2 },
-	{ 0xef12a25d, KEY_3 },
-	{ 0xef12be41, KEY_4 },
-	{ 0xef12f50a, KEY_5 },
-	{ 0xef12bd42, KEY_6 },
-	{ 0xef12b847, KEY_7 },
-	{ 0xef12b649, KEY_8 },
-	{ 0xef12fa05, KEY_9 },
-	{ 0xef12bc43, KEY_POWER },
-	{ 0xef12b946, KEY_SUBTITLE },
-	{ 0xef12f906, KEY_PAUSE },
-	{ 0xef12fc03, KEY_MEDIA_REPEAT},
-	{ 0xef12fd02, KEY_PAUSE },
-	{ 0xef12a15e, KEY_VOLUMEUP },
-	{ 0xef12a35c, KEY_VOLUMEDOWN },
-	{ 0xef12f609, KEY_CHANNELUP },
-	{ 0xef12e51a, KEY_CHANNELDOWN },
-	{ 0xef12e11e, KEY_PLAY },
-	{ 0xef12e41b, KEY_ZOOM },
-	{ 0xef12a659, KEY_MUTE },
-	{ 0xef12a55a, KEY_TV },
-	{ 0xef12e718, KEY_RECORD },
-	{ 0xef12f807, KEY_EPG },
-	{ 0xef12fe01, KEY_STOP },
+	{ 0x10ed45, KEY_0 },
+	{ 0x10ed5f, KEY_1 },
+	{ 0x10ed50, KEY_2 },
+	{ 0x10ed5d, KEY_3 },
+	{ 0x10ed41, KEY_4 },
+	{ 0x10ed0a, KEY_5 },
+	{ 0x10ed42, KEY_6 },
+	{ 0x10ed47, KEY_7 },
+	{ 0x10ed49, KEY_8 },
+	{ 0x10ed05, KEY_9 },
+	{ 0x10ed43, KEY_POWER },
+	{ 0x10ed46, KEY_SUBTITLE },
+	{ 0x10ed06, KEY_PAUSE },
+	{ 0x10ed03, KEY_MEDIA_REPEAT},
+	{ 0x10ed02, KEY_PAUSE },
+	{ 0x10ed5e, KEY_VOLUMEUP },
+	{ 0x10ed5c, KEY_VOLUMEDOWN },
+	{ 0x10ed09, KEY_CHANNELUP },
+	{ 0x10ed1a, KEY_CHANNELDOWN },
+	{ 0x10ed1e, KEY_PLAY },
+	{ 0x10ed1b, KEY_ZOOM },
+	{ 0x10ed59, KEY_MUTE },
+	{ 0x10ed5a, KEY_TV },
+	{ 0x10ed18, KEY_RECORD },
+	{ 0x10ed07, KEY_EPG },
+	{ 0x10ed01, KEY_STOP },
 	/* Type 2 - 20 buttons */
-	{ 0xff40ea15, KEY_0 },
-	{ 0xff40f708, KEY_1 },
-	{ 0xff40f609, KEY_2 },
-	{ 0xff40f50a, KEY_3 },
-	{ 0xff40f30c, KEY_4 },
-	{ 0xff40f20d, KEY_5 },
-	{ 0xff40f10e, KEY_6 },
-	{ 0xff40ef10, KEY_7 },
-	{ 0xff40ee11, KEY_8 },
-	{ 0xff40ed12, KEY_9 },
-	{ 0xff40ff00, KEY_POWER },
-	{ 0xff40fb04, KEY_MEDIA_REPEAT}, /* Recall */
-	{ 0xff40e51a, KEY_PAUSE }, /* Timeshift */
-	{ 0xff40fd02, KEY_VOLUMEUP }, /* 2 x -/+ Keys not marked */
-	{ 0xff40f906, KEY_VOLUMEDOWN }, /* Volume defined as right hand*/
-	{ 0xff40fe01, KEY_CHANNELUP },
-	{ 0xff40fa05, KEY_CHANNELDOWN },
-	{ 0xff40eb14, KEY_ZOOM },
-	{ 0xff40e718, KEY_RECORD },
-	{ 0xff40e916, KEY_STOP },
+	{ 0xbf15, KEY_0 },
+	{ 0xbf08, KEY_1 },
+	{ 0xbf09, KEY_2 },
+	{ 0xbf0a, KEY_3 },
+	{ 0xbf0c, KEY_4 },
+	{ 0xbf0d, KEY_5 },
+	{ 0xbf0e, KEY_6 },
+	{ 0xbf10, KEY_7 },
+	{ 0xbf11, KEY_8 },
+	{ 0xbf12, KEY_9 },
+	{ 0xbf00, KEY_POWER },
+	{ 0xbf04, KEY_MEDIA_REPEAT}, /* Recall */
+	{ 0xbf1a, KEY_PAUSE }, /* Timeshift */
+	{ 0xbf02, KEY_VOLUMEUP }, /* 2 x -/+ Keys not marked */
+	{ 0xbf06, KEY_VOLUMEDOWN }, /* Volume defined as right hand*/
+	{ 0xbf01, KEY_CHANNELUP },
+	{ 0xbf05, KEY_CHANNELDOWN },
+	{ 0xbf14, KEY_ZOOM },
+	{ 0xbf18, KEY_RECORD },
+	{ 0xbf16, KEY_STOP },
 	/* Type 3 - 20 buttons */
-	{ 0xff00e31c, KEY_0 },
-	{ 0xff00f807, KEY_1 },
-	{ 0xff00ea15, KEY_2 },
-	{ 0xff00f609, KEY_3 },
-	{ 0xff00e916, KEY_4 },
-	{ 0xff00e619, KEY_5 },
-	{ 0xff00f20d, KEY_6 },
-	{ 0xff00f30c, KEY_7 },
-	{ 0xff00e718, KEY_8 },
-	{ 0xff00a15e, KEY_9 },
-	{ 0xff00ba45, KEY_POWER },
-	{ 0xff00bb44, KEY_MEDIA_REPEAT}, /* Recall */
-	{ 0xff00b54a, KEY_PAUSE }, /* Timeshift */
-	{ 0xff00b847, KEY_VOLUMEUP }, /* 2 x -/+ Keys not marked */
-	{ 0xff00bc43, KEY_VOLUMEDOWN }, /* Volume defined as right hand*/
-	{ 0xff00b946, KEY_CHANNELUP },
-	{ 0xff00bf40, KEY_CHANNELDOWN },
-	{ 0xff00f708, KEY_ZOOM },
-	{ 0xff00bd42, KEY_RECORD },
-	{ 0xff00a55a, KEY_STOP },
+	{ 0x1c, KEY_0 },
+	{ 0x07, KEY_1 },
+	{ 0x15, KEY_2 },
+	{ 0x09, KEY_3 },
+	{ 0x16, KEY_4 },
+	{ 0x19, KEY_5 },
+	{ 0x0d, KEY_6 },
+	{ 0x0c, KEY_7 },
+	{ 0x18, KEY_8 },
+	{ 0x5e, KEY_9 },
+	{ 0x45, KEY_POWER },
+	{ 0x44, KEY_MEDIA_REPEAT}, /* Recall */
+	{ 0x4a, KEY_PAUSE }, /* Timeshift */
+	{ 0x47, KEY_VOLUMEUP }, /* 2 x -/+ Keys not marked */
+	{ 0x43, KEY_VOLUMEDOWN }, /* Volume defined as right hand*/
+	{ 0x46, KEY_CHANNELUP },
+	{ 0x40, KEY_CHANNELDOWN },
+	{ 0x08, KEY_ZOOM },
+	{ 0x42, KEY_RECORD },
+	{ 0x5a, KEY_STOP },
 };
 
 static struct rc_map_list lme2510_map = {
 	.map = {
 		.scan    = lme2510_rc,
 		.size    = ARRAY_SIZE(lme2510_rc),
-		.rc_type = RC_TYPE_UNKNOWN,
+		.rc_type = RC_TYPE_NEC,
 		.name    = RC_MAP_LME2510,
 	}
 };
diff -druN linux-2.6.39-libre/drivers/media/rc/keymaps/rc-pinnacle-pctv-hd.c linux-3.0-rc7-libre/drivers/media/rc/keymaps/rc-pinnacle-pctv-hd.c
--- linux-2.6.39-libre/drivers/media/rc/keymaps/rc-pinnacle-pctv-hd.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/rc/keymaps/rc-pinnacle-pctv-hd.c	2011-07-11 19:51:52.000000000 -0400
@@ -15,43 +15,39 @@
 /* Pinnacle PCTV HD 800i mini remote */
 
 static struct rc_map_table pinnacle_pctv_hd[] = {
-
-	{ 0x0f, KEY_1 },
-	{ 0x15, KEY_2 },
-	{ 0x10, KEY_3 },
-	{ 0x18, KEY_4 },
-	{ 0x1b, KEY_5 },
-	{ 0x1e, KEY_6 },
-	{ 0x11, KEY_7 },
-	{ 0x21, KEY_8 },
-	{ 0x12, KEY_9 },
-	{ 0x27, KEY_0 },
-
-	{ 0x24, KEY_ZOOM },
-	{ 0x2a, KEY_SUBTITLE },
-
-	{ 0x00, KEY_MUTE },
-	{ 0x01, KEY_ENTER },	/* Pinnacle Logo */
-	{ 0x39, KEY_POWER },
-
-	{ 0x03, KEY_VOLUMEUP },
-	{ 0x09, KEY_VOLUMEDOWN },
-	{ 0x06, KEY_CHANNELUP },
-	{ 0x0c, KEY_CHANNELDOWN },
-
-	{ 0x2d, KEY_REWIND },
-	{ 0x30, KEY_PLAYPAUSE },
-	{ 0x33, KEY_FASTFORWARD },
-	{ 0x3c, KEY_STOP },
-	{ 0x36, KEY_RECORD },
-	{ 0x3f, KEY_EPG },	/* Labeled "?" */
+	/* Key codes for the tiny Pinnacle remote*/
+	{ 0x0700, KEY_MUTE },
+	{ 0x0701, KEY_MENU }, /* Pinnacle logo */
+	{ 0x0739, KEY_POWER },
+	{ 0x0703, KEY_VOLUMEUP },
+	{ 0x0709, KEY_VOLUMEDOWN },
+	{ 0x0706, KEY_CHANNELUP },
+	{ 0x070c, KEY_CHANNELDOWN },
+	{ 0x070f, KEY_1 },
+	{ 0x0715, KEY_2 },
+	{ 0x0710, KEY_3 },
+	{ 0x0718, KEY_4 },
+	{ 0x071b, KEY_5 },
+	{ 0x071e, KEY_6 },
+	{ 0x0711, KEY_7 },
+	{ 0x0721, KEY_8 },
+	{ 0x0712, KEY_9 },
+	{ 0x0727, KEY_0 },
+	{ 0x0724, KEY_ZOOM }, /* 'Square' key */
+	{ 0x072a, KEY_SUBTITLE },   /* 'T' key */
+	{ 0x072d, KEY_REWIND },
+	{ 0x0730, KEY_PLAYPAUSE },
+	{ 0x0733, KEY_FASTFORWARD },
+	{ 0x0736, KEY_RECORD },
+	{ 0x073c, KEY_STOP },
+	{ 0x073f, KEY_HELP }, /* '?' key */
 };
 
 static struct rc_map_list pinnacle_pctv_hd_map = {
 	.map = {
 		.scan    = pinnacle_pctv_hd,
 		.size    = ARRAY_SIZE(pinnacle_pctv_hd),
-		.rc_type = RC_TYPE_UNKNOWN,	/* Legacy IR type */
+		.rc_type = RC_TYPE_RC5,
 		.name    = RC_MAP_PINNACLE_PCTV_HD,
 	}
 };
diff -druN linux-2.6.39-libre/drivers/media/rc/keymaps/rc-rc6-mce.c linux-3.0-rc7-libre/drivers/media/rc/keymaps/rc-rc6-mce.c
--- linux-2.6.39-libre/drivers/media/rc/keymaps/rc-rc6-mce.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/rc/keymaps/rc-rc6-mce.c	2011-07-11 19:51:52.000000000 -0400
@@ -30,7 +30,7 @@
 	{ 0x800f040a, KEY_DELETE },
 	{ 0x800f040b, KEY_ENTER },
 	{ 0x800f040c, KEY_POWER },		/* PC Power */
-	{ 0x800f040d, KEY_LEFTMETA },		/* Windows MCE button */
+	{ 0x800f040d, KEY_MEDIA },		/* Windows MCE button */
 	{ 0x800f040e, KEY_MUTE },
 	{ 0x800f040f, KEY_INFO },
 
@@ -87,7 +87,7 @@
 
 	{ 0x800f0465, KEY_POWER2 },	/* TV Power */
 	{ 0x800f046e, KEY_PLAYPAUSE },
-	{ 0x800f046f, KEY_MEDIA },	/* Start media application (NEW) */
+	{ 0x800f046f, KEY_PLAYER },	/* Start media application (NEW) */
 
 	{ 0x800f0480, KEY_BRIGHTNESSDOWN },
 	{ 0x800f0481, KEY_PLAYPAUSE },
diff -druN linux-2.6.39-libre/drivers/media/rc/keymaps/rc-tivo.c linux-3.0-rc7-libre/drivers/media/rc/keymaps/rc-tivo.c
--- linux-2.6.39-libre/drivers/media/rc/keymaps/rc-tivo.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/media/rc/keymaps/rc-tivo.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,98 @@
+/* rc-tivo.c - Keytable for TiVo remotes
+ *
+ * Copyright (c) 2011 by Jarod Wilson <jarod@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 <media/rc-map.h>
+
+/*
+ * Initial mapping is for the TiVo remote included in the Nero LiquidTV bundle,
+ * which also ships with a TiVo-branded IR transceiver, supported by the mceusb
+ * driver. Note that the remote uses an NEC-ish protocol, but instead of having
+ * a command/not_command pair, it has a vendor ID of 0xa10c, but some keys, the
+ * NEC extended checksums do pass, so the table presently has the intended
+ * values and the checksum-passed versions for those keys.
+ */
+static struct rc_map_table tivo[] = {
+	{ 0xa10c900f, KEY_MEDIA },	/* TiVo Button */
+	{ 0xa10c0807, KEY_POWER2 },	/* TV Power */
+	{ 0xa10c8807, KEY_TV },		/* Live TV/Swap */
+	{ 0xa10c2c03, KEY_VIDEO_NEXT },	/* TV Input */
+	{ 0xa10cc807, KEY_INFO },
+	{ 0xa10cfa05, KEY_CYCLEWINDOWS }, /* Window */
+	{ 0x0085305f, KEY_CYCLEWINDOWS },
+	{ 0xa10c6c03, KEY_EPG },	/* Guide */
+
+	{ 0xa10c2807, KEY_UP },
+	{ 0xa10c6807, KEY_DOWN },
+	{ 0xa10ce807, KEY_LEFT },
+	{ 0xa10ca807, KEY_RIGHT },
+
+	{ 0xa10c1807, KEY_SCROLLDOWN },	/* Red Thumbs Down */
+	{ 0xa10c9807, KEY_SELECT },
+	{ 0xa10c5807, KEY_SCROLLUP },	/* Green Thumbs Up */
+
+	{ 0xa10c3807, KEY_VOLUMEUP },
+	{ 0xa10cb807, KEY_VOLUMEDOWN },
+	{ 0xa10cd807, KEY_MUTE },
+	{ 0xa10c040b, KEY_RECORD },
+	{ 0xa10c7807, KEY_CHANNELUP },
+	{ 0xa10cf807, KEY_CHANNELDOWN },
+	{ 0x0085301f, KEY_CHANNELDOWN },
+
+	{ 0xa10c840b, KEY_PLAY },
+	{ 0xa10cc40b, KEY_PAUSE },
+	{ 0xa10ca40b, KEY_SLOW },
+	{ 0xa10c440b, KEY_REWIND },
+	{ 0xa10c240b, KEY_FASTFORWARD },
+	{ 0xa10c640b, KEY_PREVIOUS },
+	{ 0xa10ce40b, KEY_NEXT },	/* ->| */
+
+	{ 0xa10c220d, KEY_ZOOM },	/* Aspect */
+	{ 0xa10c120d, KEY_STOP },
+	{ 0xa10c520d, KEY_DVD },	/* DVD Menu */
+
+	{ 0xa10c140b, KEY_NUMERIC_1 },
+	{ 0xa10c940b, KEY_NUMERIC_2 },
+	{ 0xa10c540b, KEY_NUMERIC_3 },
+	{ 0xa10cd40b, KEY_NUMERIC_4 },
+	{ 0xa10c340b, KEY_NUMERIC_5 },
+	{ 0xa10cb40b, KEY_NUMERIC_6 },
+	{ 0xa10c740b, KEY_NUMERIC_7 },
+	{ 0xa10cf40b, KEY_NUMERIC_8 },
+	{ 0x0085302f, KEY_NUMERIC_8 },
+	{ 0xa10c0c03, KEY_NUMERIC_9 },
+	{ 0xa10c8c03, KEY_NUMERIC_0 },
+	{ 0xa10ccc03, KEY_ENTER },
+	{ 0xa10c4c03, KEY_CLEAR },
+};
+
+static struct rc_map_list tivo_map = {
+	.map = {
+		.scan    = tivo,
+		.size    = ARRAY_SIZE(tivo),
+		.rc_type = RC_TYPE_NEC,
+		.name    = RC_MAP_TIVO,
+	}
+};
+
+static int __init init_rc_map_tivo(void)
+{
+	return rc_map_register(&tivo_map);
+}
+
+static void __exit exit_rc_map_tivo(void)
+{
+	rc_map_unregister(&tivo_map);
+}
+
+module_init(init_rc_map_tivo)
+module_exit(exit_rc_map_tivo)
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Jarod Wilson <jarod@redhat.com>");
diff -druN linux-2.6.39-libre/drivers/media/rc/keymaps/rc-winfast.c linux-3.0-rc7-libre/drivers/media/rc/keymaps/rc-winfast.c
--- linux-2.6.39-libre/drivers/media/rc/keymaps/rc-winfast.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/rc/keymaps/rc-winfast.c	2011-07-11 19:51:52.000000000 -0400
@@ -32,8 +32,8 @@
 	{ 0x02, KEY_TUNER },		/* TV/FM, not on Y0400052 */
 	{ 0x1e, KEY_VIDEO },		/* Video Source */
 	{ 0x16, KEY_INFO },		/* Display information */
-	{ 0x04, KEY_LEFT },
-	{ 0x08, KEY_RIGHT },
+	{ 0x04, KEY_RIGHT },
+	{ 0x08, KEY_LEFT },
 	{ 0x0c, KEY_UP },
 	{ 0x10, KEY_DOWN },
 	{ 0x03, KEY_ZOOM },		/* fullscreen */
diff -druN linux-2.6.39-libre/drivers/media/rc/lirc_dev.c linux-3.0-rc7-libre/drivers/media/rc/lirc_dev.c
--- linux-2.6.39-libre/drivers/media/rc/lirc_dev.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/rc/lirc_dev.c	2011-07-11 19:51:52.000000000 -0400
@@ -55,6 +55,8 @@
 	struct lirc_buffer *buf;
 	unsigned int chunk_size;
 
+	struct cdev *cdev;
+
 	struct task_struct *task;
 	long jiffies_to_wait;
 };
@@ -62,7 +64,6 @@
 static DEFINE_MUTEX(lirc_dev_lock);
 
 static struct irctl *irctls[MAX_IRCTL_DEVICES];
-static struct cdev cdevs[MAX_IRCTL_DEVICES];
 
 /* Only used for sysfs but defined to void otherwise */
 static struct class *lirc_class;
@@ -167,9 +168,13 @@
 
 static int lirc_cdev_add(struct irctl *ir)
 {
-	int retval;
+	int retval = -ENOMEM;
 	struct lirc_driver *d = &ir->d;
-	struct cdev *cdev = &cdevs[d->minor];
+	struct cdev *cdev;
+
+	cdev = kzalloc(sizeof(*cdev), GFP_KERNEL);
+	if (!cdev)
+		goto err_out;
 
 	if (d->fops) {
 		cdev_init(cdev, d->fops);
@@ -180,12 +185,20 @@
 	}
 	retval = kobject_set_name(&cdev->kobj, "lirc%d", d->minor);
 	if (retval)
-		return retval;
+		goto err_out;
 
 	retval = cdev_add(cdev, MKDEV(MAJOR(lirc_base_dev), d->minor), 1);
-	if (retval)
+	if (retval) {
 		kobject_put(&cdev->kobj);
+		goto err_out;
+	}
+
+	ir->cdev = cdev;
 
+	return 0;
+
+err_out:
+	kfree(cdev);
 	return retval;
 }
 
@@ -214,7 +227,7 @@
 	if (MAX_IRCTL_DEVICES <= d->minor) {
 		dev_err(d->dev, "lirc_dev: lirc_register_driver: "
 			"\"minor\" must be between 0 and %d (%d)!\n",
-			MAX_IRCTL_DEVICES-1, d->minor);
+			MAX_IRCTL_DEVICES - 1, d->minor);
 		err = -EBADRQC;
 		goto out;
 	}
@@ -369,7 +382,7 @@
 
 	if (minor < 0 || minor >= MAX_IRCTL_DEVICES) {
 		printk(KERN_ERR "lirc_dev: %s: minor (%d) must be between "
-		       "0 and %d!\n", __func__, minor, MAX_IRCTL_DEVICES-1);
+		       "0 and %d!\n", __func__, minor, MAX_IRCTL_DEVICES - 1);
 		return -EBADRQC;
 	}
 
@@ -380,7 +393,7 @@
 		return -ENOENT;
 	}
 
-	cdev = &cdevs[minor];
+	cdev = ir->cdev;
 
 	mutex_lock(&lirc_dev_lock);
 
@@ -410,6 +423,7 @@
 	} else {
 		lirc_irctl_cleanup(ir);
 		cdev_del(cdev);
+		kfree(cdev);
 		kfree(ir);
 		irctls[minor] = NULL;
 	}
@@ -453,7 +467,7 @@
 		goto error;
 	}
 
-	cdev = &cdevs[iminor(inode)];
+	cdev = ir->cdev;
 	if (try_module_get(cdev->owner)) {
 		ir->open++;
 		retval = ir->d.set_use_inc(ir->d.data);
@@ -484,13 +498,15 @@
 int lirc_dev_fop_close(struct inode *inode, struct file *file)
 {
 	struct irctl *ir = irctls[iminor(inode)];
-	struct cdev *cdev = &cdevs[iminor(inode)];
+	struct cdev *cdev;
 
 	if (!ir) {
 		printk(KERN_ERR "%s: called with invalid irctl\n", __func__);
 		return -EINVAL;
 	}
 
+	cdev = ir->cdev;
+
 	dev_dbg(ir->d.dev, LOGHEAD "close called\n", ir->d.name, ir->d.minor);
 
 	WARN_ON(mutex_lock_killable(&lirc_dev_lock));
@@ -503,6 +519,7 @@
 		lirc_irctl_cleanup(ir);
 		cdev_del(cdev);
 		irctls[ir->d.minor] = NULL;
+		kfree(cdev);
 		kfree(ir);
 	}
 
diff -druN linux-2.6.39-libre/drivers/media/rc/Makefile linux-3.0-rc7-libre/drivers/media/rc/Makefile
--- linux-2.6.39-libre/drivers/media/rc/Makefile	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/rc/Makefile	2011-07-11 19:51:52.000000000 -0400
@@ -16,8 +16,10 @@
 obj-$(CONFIG_IR_IMON) += imon.o
 obj-$(CONFIG_IR_ITE_CIR) += ite-cir.o
 obj-$(CONFIG_IR_MCEUSB) += mceusb.o
+obj-$(CONFIG_IR_FINTEK) += fintek-cir.o
 obj-$(CONFIG_IR_NUVOTON) += nuvoton-cir.o
 obj-$(CONFIG_IR_ENE) += ene_ir.o
+obj-$(CONFIG_IR_REDRAT3) += redrat3.o
 obj-$(CONFIG_IR_STREAMZAP) += streamzap.o
 obj-$(CONFIG_IR_WINBOND_CIR) += winbond-cir.o
 obj-$(CONFIG_RC_LOOPBACK) += rc-loopback.o
diff -druN linux-2.6.39-libre/drivers/media/rc/mceusb.c linux-3.0-rc7-libre/drivers/media/rc/mceusb.c
--- linux-2.6.39-libre/drivers/media/rc/mceusb.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/rc/mceusb.c	2011-07-11 19:51:52.000000000 -0400
@@ -108,6 +108,12 @@
 static int debug;
 #endif
 
+#define mce_dbg(dev, fmt, ...)					\
+	do {							\
+		if (debug)					\
+			dev_info(dev, fmt, ## __VA_ARGS__);	\
+	} while (0)
+
 /* general constants */
 #define SEND_FLAG_IN_PROGRESS	1
 #define SEND_FLAG_COMPLETE	2
@@ -149,6 +155,8 @@
 	POLARIS_EVK,
 	CX_HYBRID_TV,
 	MULTIFUNCTION,
+	TIVO_KIT,
+	MCE_GEN2_NO_TX,
 };
 
 struct mceusb_model {
@@ -172,6 +180,10 @@
 	[MCE_GEN2] = {
 		.mce_gen2 = 1,
 	},
+	[MCE_GEN2_NO_TX] = {
+		.mce_gen2 = 1,
+		.no_tx = 1,
+	},
 	[MCE_GEN2_TX_INV] = {
 		.mce_gen2 = 1,
 		.tx_mask_normal = 1,
@@ -197,6 +209,10 @@
 		.mce_gen2 = 1,
 		.ir_intfnum = 2,
 	},
+	[TIVO_KIT] = {
+		.mce_gen2 = 1,
+		.rc_map = RC_MAP_TIVO,
+	},
 };
 
 static struct usb_device_id mceusb_dev_table[] = {
@@ -236,6 +252,9 @@
 	  .driver_info = MCE_GEN2_TX_INV },
 	/* SMK eHome Infrared Transceiver */
 	{ USB_DEVICE(VENDOR_SMK, 0x0338) },
+	/* SMK/I-O Data GV-MC7/RCKIT Receiver */
+	{ USB_DEVICE(VENDOR_SMK, 0x0353),
+	  .driver_info = MCE_GEN2_NO_TX },
 	/* Tatung eHome Infrared Transceiver */
 	{ USB_DEVICE(VENDOR_TATUNG, 0x9150) },
 	/* Shuttle eHome Infrared Transceiver */
@@ -279,7 +298,8 @@
 	/* Formosa21 / eHome Infrared Receiver */
 	{ USB_DEVICE(VENDOR_FORMOSA, 0xe016) },
 	/* Formosa aim / Trust MCE Infrared Receiver */
-	{ USB_DEVICE(VENDOR_FORMOSA, 0xe017) },
+	{ USB_DEVICE(VENDOR_FORMOSA, 0xe017),
+	  .driver_info = MCE_GEN2_NO_TX },
 	/* Formosa Industrial Computing / Beanbag Emulation Device */
 	{ USB_DEVICE(VENDOR_FORMOSA, 0xe018) },
 	/* Formosa21 / eHome Infrared Receiver */
@@ -308,7 +328,8 @@
 	/* Northstar Systems, Inc. eHome Infrared Transceiver */
 	{ USB_DEVICE(VENDOR_NORTHSTAR, 0xe004) },
 	/* TiVo PC IR Receiver */
-	{ USB_DEVICE(VENDOR_TIVO, 0x2000) },
+	{ USB_DEVICE(VENDOR_TIVO, 0x2000),
+	  .driver_info = TIVO_KIT },
 	/* Conexant Hybrid TV "Shelby" Polaris SDK */
 	{ USB_DEVICE(VENDOR_CONEXANT, 0x58a1),
 	  .driver_info = POLARIS_EVK },
@@ -594,20 +615,22 @@
 	if (ir) {
 		len = urb->actual_length;
 
-		dev_dbg(ir->dev, "callback called (status=%d len=%d)\n",
+		mce_dbg(ir->dev, "callback called (status=%d len=%d)\n",
 			urb->status, len);
 
 		mceusb_dev_printdata(ir, urb->transfer_buffer, 0, len, true);
 	}
 
+	/* the transfer buffer and urb were allocated in mce_request_packet */
+	kfree(urb->transfer_buffer);
+	usb_free_urb(urb);
 }
 
 /* request incoming or send outgoing usb packet - used to initialize remote */
-static void mce_request_packet(struct mceusb_dev *ir,
-			       struct usb_endpoint_descriptor *ep,
-			       unsigned char *data, int size, int urb_type)
+static void mce_request_packet(struct mceusb_dev *ir, unsigned char *data,
+			       int size, int urb_type)
 {
-	int res;
+	int res, pipe;
 	struct urb *async_urb;
 	struct device *dev = ir->dev;
 	unsigned char *async_buf;
@@ -627,10 +650,11 @@
 		}
 
 		/* outbound data */
-		usb_fill_int_urb(async_urb, ir->usbdev,
-			usb_sndintpipe(ir->usbdev, ep->bEndpointAddress),
+		pipe = usb_sndintpipe(ir->usbdev,
+				      ir->usb_ep_out->bEndpointAddress);
+		usb_fill_int_urb(async_urb, ir->usbdev, pipe,
 			async_buf, size, (usb_complete_t)mce_async_callback,
-			ir, ep->bInterval);
+			ir, ir->usb_ep_out->bInterval);
 		memcpy(async_buf, data, size);
 
 	} else if (urb_type == MCEUSB_RX) {
@@ -643,27 +667,27 @@
 		return;
 	}
 
-	dev_dbg(dev, "receive request called (size=%#x)\n", size);
+	mce_dbg(dev, "receive request called (size=%#x)\n", size);
 
 	async_urb->transfer_buffer_length = size;
 	async_urb->dev = ir->usbdev;
 
 	res = usb_submit_urb(async_urb, GFP_ATOMIC);
 	if (res) {
-		dev_dbg(dev, "receive request FAILED! (res=%d)\n", res);
+		mce_dbg(dev, "receive request FAILED! (res=%d)\n", res);
 		return;
 	}
-	dev_dbg(dev, "receive request complete (res=%d)\n", res);
+	mce_dbg(dev, "receive request complete (res=%d)\n", res);
 }
 
 static void mce_async_out(struct mceusb_dev *ir, unsigned char *data, int size)
 {
-	mce_request_packet(ir, ir->usb_ep_out, data, size, MCEUSB_TX);
+	mce_request_packet(ir, data, size, MCEUSB_TX);
 }
 
-static void mce_sync_in(struct mceusb_dev *ir, unsigned char *data, int size)
+static void mce_flush_rx_buffer(struct mceusb_dev *ir, int size)
 {
-	mce_request_packet(ir, ir->usb_ep_in, data, size, MCEUSB_RX);
+	mce_request_packet(ir, NULL, size, MCEUSB_RX);
 }
 
 /* Send data out the IR blaster port(s) */
@@ -782,7 +806,7 @@
 			ir->carrier = carrier;
 			cmdbuf[2] = MCE_CMD_SIG_END;
 			cmdbuf[3] = MCE_IRDATA_TRAILER;
-			dev_dbg(ir->dev, "%s: disabling carrier "
+			mce_dbg(ir->dev, "%s: disabling carrier "
 				"modulation\n", __func__);
 			mce_async_out(ir, cmdbuf, sizeof(cmdbuf));
 			return carrier;
@@ -794,7 +818,7 @@
 				ir->carrier = carrier;
 				cmdbuf[2] = prescaler;
 				cmdbuf[3] = divisor;
-				dev_dbg(ir->dev, "%s: requesting %u HZ "
+				mce_dbg(ir->dev, "%s: requesting %u HZ "
 					"carrier\n", __func__, carrier);
 
 				/* Transmit new carrier to mce device */
@@ -867,7 +891,7 @@
 			rawir.duration = (ir->buf_in[i] & MCE_PULSE_MASK)
 					 * US_TO_NS(MCE_TIME_UNIT);
 
-			dev_dbg(ir->dev, "Storing %s with duration %d\n",
+			mce_dbg(ir->dev, "Storing %s with duration %d\n",
 				rawir.pulse ? "pulse" : "space",
 				rawir.duration);
 
@@ -899,7 +923,7 @@
 		if (ir->parser_state != CMD_HEADER && !ir->rem)
 			ir->parser_state = CMD_HEADER;
 	}
-	dev_dbg(ir->dev, "processed IR data, calling ir_raw_event_handle\n");
+	mce_dbg(ir->dev, "processed IR data, calling ir_raw_event_handle\n");
 	ir_raw_event_handle(ir->rc);
 }
 
@@ -921,7 +945,7 @@
 
 	if (ir->send_flags == RECV_FLAG_IN_PROGRESS) {
 		ir->send_flags = SEND_FLAG_COMPLETE;
-		dev_dbg(ir->dev, "setup answer received %d bytes\n",
+		mce_dbg(ir->dev, "setup answer received %d bytes\n",
 			buf_len);
 	}
 
@@ -939,7 +963,7 @@
 
 	case -EPIPE:
 	default:
-		dev_dbg(ir->dev, "Error: urb status = %d\n", urb->status);
+		mce_dbg(ir->dev, "Error: urb status = %d\n", urb->status);
 		break;
 	}
 
@@ -949,7 +973,6 @@
 static void mceusb_gen1_init(struct mceusb_dev *ir)
 {
 	int ret;
-	int maxp = ir->len_in;
 	struct device *dev = ir->dev;
 	char *data;
 
@@ -966,8 +989,8 @@
 	ret = usb_control_msg(ir->usbdev, usb_rcvctrlpipe(ir->usbdev, 0),
 			      USB_REQ_SET_ADDRESS, USB_TYPE_VENDOR, 0, 0,
 			      data, USB_CTRL_MSG_SZ, HZ * 3);
-	dev_dbg(dev, "%s - ret = %d\n", __func__, ret);
-	dev_dbg(dev, "%s - data[0] = %d, data[1] = %d\n",
+	mce_dbg(dev, "%s - ret = %d\n", __func__, ret);
+	mce_dbg(dev, "%s - data[0] = %d, data[1] = %d\n",
 		__func__, data[0], data[1]);
 
 	/* set feature: bit rate 38400 bps */
@@ -975,71 +998,56 @@
 			      USB_REQ_SET_FEATURE, USB_TYPE_VENDOR,
 			      0xc04e, 0x0000, NULL, 0, HZ * 3);
 
-	dev_dbg(dev, "%s - ret = %d\n", __func__, ret);
+	mce_dbg(dev, "%s - ret = %d\n", __func__, ret);
 
 	/* bRequest 4: set char length to 8 bits */
 	ret = usb_control_msg(ir->usbdev, usb_sndctrlpipe(ir->usbdev, 0),
 			      4, USB_TYPE_VENDOR,
 			      0x0808, 0x0000, NULL, 0, HZ * 3);
-	dev_dbg(dev, "%s - retB = %d\n", __func__, ret);
+	mce_dbg(dev, "%s - retB = %d\n", __func__, ret);
 
 	/* bRequest 2: set handshaking to use DTR/DSR */
 	ret = usb_control_msg(ir->usbdev, usb_sndctrlpipe(ir->usbdev, 0),
 			      2, USB_TYPE_VENDOR,
 			      0x0000, 0x0100, NULL, 0, HZ * 3);
-	dev_dbg(dev, "%s - retC = %d\n", __func__, ret);
+	mce_dbg(dev, "%s - retC = %d\n", __func__, ret);
 
 	/* device reset */
 	mce_async_out(ir, DEVICE_RESET, sizeof(DEVICE_RESET));
-	mce_sync_in(ir, NULL, maxp);
 
 	/* get hw/sw revision? */
 	mce_async_out(ir, GET_REVISION, sizeof(GET_REVISION));
-	mce_sync_in(ir, NULL, maxp);
 
 	kfree(data);
 };
 
 static void mceusb_gen2_init(struct mceusb_dev *ir)
 {
-	int maxp = ir->len_in;
-
 	/* device reset */
 	mce_async_out(ir, DEVICE_RESET, sizeof(DEVICE_RESET));
-	mce_sync_in(ir, NULL, maxp);
 
 	/* get hw/sw revision? */
 	mce_async_out(ir, GET_REVISION, sizeof(GET_REVISION));
-	mce_sync_in(ir, NULL, maxp);
 
 	/* unknown what the next two actually return... */
 	mce_async_out(ir, GET_UNKNOWN, sizeof(GET_UNKNOWN));
-	mce_sync_in(ir, NULL, maxp);
 	mce_async_out(ir, GET_UNKNOWN2, sizeof(GET_UNKNOWN2));
-	mce_sync_in(ir, NULL, maxp);
 }
 
 static void mceusb_get_parameters(struct mceusb_dev *ir)
 {
-	int maxp = ir->len_in;
-
 	/* get the carrier and frequency */
 	mce_async_out(ir, GET_CARRIER_FREQ, sizeof(GET_CARRIER_FREQ));
-	mce_sync_in(ir, NULL, maxp);
 
-	if (!ir->flags.no_tx) {
+	if (!ir->flags.no_tx)
 		/* get the transmitter bitmask */
 		mce_async_out(ir, GET_TX_BITMASK, sizeof(GET_TX_BITMASK));
-		mce_sync_in(ir, NULL, maxp);
-	}
 
 	/* get receiver timeout value */
 	mce_async_out(ir, GET_RX_TIMEOUT, sizeof(GET_RX_TIMEOUT));
-	mce_sync_in(ir, NULL, maxp);
 
 	/* get receiver sensor setting */
 	mce_async_out(ir, GET_RX_SENSOR, sizeof(GET_RX_SENSOR));
-	mce_sync_in(ir, NULL, maxp);
 }
 
 static struct rc_dev *mceusb_init_rc_dev(struct mceusb_dev *ir)
@@ -1110,7 +1118,7 @@
 	bool tx_mask_normal;
 	int ir_intfnum;
 
-	dev_dbg(&intf->dev, "%s called\n", __func__);
+	mce_dbg(&intf->dev, "%s called\n", __func__);
 
 	idesc  = intf->cur_altsetting;
 
@@ -1138,7 +1146,7 @@
 			ep_in = ep;
 			ep_in->bmAttributes = USB_ENDPOINT_XFER_INT;
 			ep_in->bInterval = 1;
-			dev_dbg(&intf->dev, "acceptable inbound endpoint "
+			mce_dbg(&intf->dev, "acceptable inbound endpoint "
 				"found\n");
 		}
 
@@ -1153,12 +1161,12 @@
 			ep_out = ep;
 			ep_out->bmAttributes = USB_ENDPOINT_XFER_INT;
 			ep_out->bInterval = 1;
-			dev_dbg(&intf->dev, "acceptable outbound endpoint "
+			mce_dbg(&intf->dev, "acceptable outbound endpoint "
 				"found\n");
 		}
 	}
 	if (ep_in == NULL) {
-		dev_dbg(&intf->dev, "inbound and/or endpoint not found\n");
+		mce_dbg(&intf->dev, "inbound and/or endpoint not found\n");
 		return -ENODEV;
 	}
 
@@ -1203,16 +1211,16 @@
 	if (!ir->rc)
 		goto rc_dev_fail;
 
-	/* flush buffers on the device */
-	mce_sync_in(ir, NULL, maxp);
-	mce_sync_in(ir, NULL, maxp);
-
 	/* wire up inbound data handler */
 	usb_fill_int_urb(ir->urb_in, dev, pipe, ir->buf_in,
 		maxp, (usb_complete_t) mceusb_dev_recv, ir, ep_in->bInterval);
 	ir->urb_in->transfer_dma = ir->dma_in;
 	ir->urb_in->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
 
+	/* flush buffers on the device */
+	mce_dbg(&intf->dev, "Flushing receive buffers\n");
+	mce_flush_rx_buffer(ir, maxp);
+
 	/* initialize device */
 	if (ir->flags.microsoft_gen1)
 		mceusb_gen1_init(ir);
diff -druN linux-2.6.39-libre/drivers/media/rc/nuvoton-cir.c linux-3.0-rc7-libre/drivers/media/rc/nuvoton-cir.c
--- linux-2.6.39-libre/drivers/media/rc/nuvoton-cir.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/rc/nuvoton-cir.c	2011-07-11 19:51:52.000000000 -0400
@@ -37,8 +37,6 @@
 
 #include "nuvoton-cir.h"
 
-static char *chip_id = "w836x7hg";
-
 /* write val to config reg */
 static inline void nvt_cr_write(struct nvt_dev *nvt, u8 val, u8 reg)
 {
@@ -233,6 +231,8 @@
 	unsigned long flags;
 	u8 chip_major, chip_minor;
 	int ret = 0;
+	char chip_id[12];
+	bool chip_unknown = false;
 
 	nvt_efm_enable(nvt);
 
@@ -246,15 +246,39 @@
 	}
 
 	chip_minor = nvt_cr_read(nvt, CR_CHIP_ID_LO);
-	nvt_dbg("%s: chip id: 0x%02x 0x%02x", chip_id, chip_major, chip_minor);
 
-	if (chip_major != CHIP_ID_HIGH ||
-	    (chip_minor != CHIP_ID_LOW && chip_minor != CHIP_ID_LOW2)) {
-		nvt_pr(KERN_ERR, "%s: unsupported chip, id: 0x%02x 0x%02x",
-		       chip_id, chip_major, chip_minor);
-		ret = -ENODEV;
+	/* these are the known working chip revisions... */
+	switch (chip_major) {
+	case CHIP_ID_HIGH_667:
+		strcpy(chip_id, "w83667hg\0");
+		if (chip_minor != CHIP_ID_LOW_667)
+			chip_unknown = true;
+		break;
+	case CHIP_ID_HIGH_677B:
+		strcpy(chip_id, "w83677hg\0");
+		if (chip_minor != CHIP_ID_LOW_677B2 &&
+		    chip_minor != CHIP_ID_LOW_677B3)
+			chip_unknown = true;
+		break;
+	case CHIP_ID_HIGH_677C:
+		strcpy(chip_id, "w83677hg-c\0");
+		if (chip_minor != CHIP_ID_LOW_677C)
+			chip_unknown = true;
+		break;
+	default:
+		strcpy(chip_id, "w836x7hg\0");
+		chip_unknown = true;
+		break;
 	}
 
+	/* warn, but still let the driver load, if we don't know this chip */
+	if (chip_unknown)
+		nvt_pr(KERN_WARNING, "%s: unknown chip, id: 0x%02x 0x%02x, "
+		       "it may not work...", chip_id, chip_major, chip_minor);
+	else
+		nvt_dbg("%s: chip id: 0x%02x 0x%02x",
+			chip_id, chip_major, chip_minor);
+
 	nvt_efm_disable(nvt);
 
 	spin_lock_irqsave(&nvt->nvt_lock, flags);
@@ -267,13 +291,23 @@
 
 static void nvt_cir_ldev_init(struct nvt_dev *nvt)
 {
-	u8 val;
+	u8 val, psreg, psmask, psval;
 
-	/* output pin selection (Pin95=CIRRX, Pin96=CIRTX1, WB enabled */
-	val = nvt_cr_read(nvt, CR_OUTPUT_PIN_SEL);
-	val &= OUTPUT_PIN_SEL_MASK;
-	val |= (OUTPUT_ENABLE_CIR | OUTPUT_ENABLE_CIRWB);
-	nvt_cr_write(nvt, val, CR_OUTPUT_PIN_SEL);
+	if (nvt->chip_major == CHIP_ID_HIGH_667) {
+		psreg = CR_MULTIFUNC_PIN_SEL;
+		psmask = MULTIFUNC_PIN_SEL_MASK;
+		psval = MULTIFUNC_ENABLE_CIR | MULTIFUNC_ENABLE_CIRWB;
+	} else {
+		psreg = CR_OUTPUT_PIN_SEL;
+		psmask = OUTPUT_PIN_SEL_MASK;
+		psval = OUTPUT_ENABLE_CIR | OUTPUT_ENABLE_CIRWB;
+	}
+
+	/* output pin selection: enable CIR, with WB sensor enabled */
+	val = nvt_cr_read(nvt, psreg);
+	val &= psmask;
+	val |= psval;
+	nvt_cr_write(nvt, val, psreg);
 
 	/* Select CIR logical device and enable */
 	nvt_select_logical_dev(nvt, LOGICAL_DEV_CIR);
@@ -640,7 +674,7 @@
 				rawir.pulse ? "pulse" : "space",
 				rawir.duration);
 
-			ir_raw_event_store(nvt->rdev, &rawir);
+			ir_raw_event_store_with_filter(nvt->rdev, &rawir);
 		}
 
 		/*
@@ -957,7 +991,6 @@
 	unsigned long flags;
 
 	spin_lock_irqsave(&nvt->nvt_lock, flags);
-	nvt->in_use = true;
 	nvt_enable_cir(nvt);
 	spin_unlock_irqrestore(&nvt->nvt_lock, flags);
 
@@ -970,7 +1003,6 @@
 	unsigned long flags;
 
 	spin_lock_irqsave(&nvt->nvt_lock, flags);
-	nvt->in_use = false;
 	nvt_disable_cir(nvt);
 	spin_unlock_irqrestore(&nvt->nvt_lock, flags);
 }
@@ -1070,18 +1102,20 @@
 	rdev->tx_ir = nvt_tx_ir;
 	rdev->s_tx_carrier = nvt_set_tx_carrier;
 	rdev->input_name = "Nuvoton w836x7hg Infrared Remote Transceiver";
+	rdev->input_phys = "nuvoton/cir0";
 	rdev->input_id.bustype = BUS_HOST;
 	rdev->input_id.vendor = PCI_VENDOR_ID_WINBOND2;
 	rdev->input_id.product = nvt->chip_major;
 	rdev->input_id.version = nvt->chip_minor;
+	rdev->dev.parent = &pdev->dev;
 	rdev->driver_name = NVT_DRIVER_NAME;
 	rdev->map_name = RC_MAP_RC6_MCE;
+	rdev->timeout = US_TO_NS(1000);
+	/* rx resolution is hardwired to 50us atm, 1, 25, 100 also possible */
+	rdev->rx_resolution = US_TO_NS(CIR_SAMPLE_PERIOD);
 #if 0
 	rdev->min_timeout = XYZ;
 	rdev->max_timeout = XYZ;
-	rdev->timeout = XYZ;
-	/* rx resolution is hardwired to 50us atm, 1, 25, 100 also possible */
-	rdev->rx_resolution = XYZ;
 	/* tx bits */
 	rdev->tx_resolution = XYZ;
 #endif
@@ -1090,8 +1124,7 @@
 	if (ret)
 		goto failure;
 
-	device_set_wakeup_capable(&pdev->dev, 1);
-	device_set_wakeup_enable(&pdev->dev, 1);
+	device_init_wakeup(&pdev->dev, true);
 	nvt->rdev = rdev;
 	nvt_pr(KERN_NOTICE, "driver has been successfully loaded\n");
 	if (debug) {
diff -druN linux-2.6.39-libre/drivers/media/rc/nuvoton-cir.h linux-3.0-rc7-libre/drivers/media/rc/nuvoton-cir.h
--- linux-2.6.39-libre/drivers/media/rc/nuvoton-cir.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/rc/nuvoton-cir.h	2011-07-11 19:51:52.000000000 -0400
@@ -70,7 +70,6 @@
 	struct ir_raw_event rawir;
 
 	spinlock_t nvt_lock;
-	bool in_use;
 
 	/* for rx */
 	u8 buf[RX_BUF_LEN];
@@ -330,9 +329,13 @@
 #define EFER_EFM_DISABLE	0xaa
 
 /* Chip IDs found in CR_CHIP_ID_{HI,LO} */
-#define CHIP_ID_HIGH		0xb4
-#define CHIP_ID_LOW		0x72
-#define CHIP_ID_LOW2		0x73
+#define CHIP_ID_HIGH_667	0xa5
+#define CHIP_ID_HIGH_677B	0xb4
+#define CHIP_ID_HIGH_677C	0xc3
+#define CHIP_ID_LOW_667		0x13
+#define CHIP_ID_LOW_677B2	0x72
+#define CHIP_ID_LOW_677B3	0x73
+#define CHIP_ID_LOW_677C	0x33
 
 /* Config regs we need to care about */
 #define CR_SOFTWARE_RESET	0x02
@@ -341,6 +344,7 @@
 #define CR_CHIP_ID_LO		0x21
 #define CR_DEV_POWER_DOWN	0x22 /* bit 2 is CIR power, default power on */
 #define CR_OUTPUT_PIN_SEL	0x27
+#define CR_MULTIFUNC_PIN_SEL	0x2c
 #define CR_LOGICAL_DEV_EN	0x30 /* valid for all logical devices */
 /* next three regs valid for both the CIR and CIR_WAKE logical devices */
 #define CR_CIR_BASE_ADDR_HI	0x60
@@ -364,10 +368,16 @@
 #define CIR_INTR_MOUSE_IRQ_BIT	0x80
 #define PME_INTR_CIR_PASS_BIT	0x08
 
+/* w83677hg CIR pin config */
 #define OUTPUT_PIN_SEL_MASK	0xbc
 #define OUTPUT_ENABLE_CIR	0x01 /* Pin95=CIRRX, Pin96=CIRTX1 */
 #define OUTPUT_ENABLE_CIRWB	0x40 /* enable wide-band sensor */
 
+/* w83667hg CIR pin config */
+#define MULTIFUNC_PIN_SEL_MASK	0x1f
+#define MULTIFUNC_ENABLE_CIR	0x80 /* Pin75=CIRRX, Pin76=CIRTX1 */
+#define MULTIFUNC_ENABLE_CIRWB	0x20 /* enable wide-band sensor */
+
 /* MCE CIR signal length, related on sample period */
 
 /* MCE CIR controller signal length: about 43ms
diff -druN linux-2.6.39-libre/drivers/media/rc/rc-loopback.c linux-3.0-rc7-libre/drivers/media/rc/rc-loopback.c
--- linux-2.6.39-libre/drivers/media/rc/rc-loopback.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/rc/rc-loopback.c	2011-07-11 19:51:52.000000000 -0400
@@ -146,6 +146,12 @@
 		if (rawir.duration)
 			ir_raw_event_store_with_filter(dev, &rawir);
 	}
+
+	/* Fake a silence long enough to cause us to go idle */
+	rawir.pulse = false;
+	rawir.duration = dev->timeout;
+	ir_raw_event_store_with_filter(dev, &rawir);
+
 	ir_raw_event_handle(dev);
 
 out:
diff -druN linux-2.6.39-libre/drivers/media/rc/rc-main.c linux-3.0-rc7-libre/drivers/media/rc/rc-main.c
--- linux-2.6.39-libre/drivers/media/rc/rc-main.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/rc/rc-main.c	2011-07-11 19:51:52.000000000 -0400
@@ -522,18 +522,20 @@
 /**
  * ir_do_keyup() - internal function to signal the release of a keypress
  * @dev:	the struct rc_dev descriptor of the device
+ * @sync:	whether or not to call input_sync
  *
  * This function is used internally to release a keypress, it must be
  * called with keylock held.
  */
-static void ir_do_keyup(struct rc_dev *dev)
+static void ir_do_keyup(struct rc_dev *dev, bool sync)
 {
 	if (!dev->keypressed)
 		return;
 
 	IR_dprintk(1, "keyup key 0x%04x\n", dev->last_keycode);
 	input_report_key(dev->input_dev, dev->last_keycode, 0);
-	input_sync(dev->input_dev);
+	if (sync)
+		input_sync(dev->input_dev);
 	dev->keypressed = false;
 }
 
@@ -549,7 +551,7 @@
 	unsigned long flags;
 
 	spin_lock_irqsave(&dev->keylock, flags);
-	ir_do_keyup(dev);
+	ir_do_keyup(dev, true);
 	spin_unlock_irqrestore(&dev->keylock, flags);
 }
 EXPORT_SYMBOL_GPL(rc_keyup);
@@ -578,7 +580,7 @@
 	 */
 	spin_lock_irqsave(&dev->keylock, flags);
 	if (time_is_before_eq_jiffies(dev->keyup_jiffies))
-		ir_do_keyup(dev);
+		ir_do_keyup(dev, true);
 	spin_unlock_irqrestore(&dev->keylock, flags);
 }
 
@@ -597,6 +599,7 @@
 	spin_lock_irqsave(&dev->keylock, flags);
 
 	input_event(dev->input_dev, EV_MSC, MSC_SCAN, dev->last_scancode);
+	input_sync(dev->input_dev);
 
 	if (!dev->keypressed)
 		goto out;
@@ -622,29 +625,28 @@
 static void ir_do_keydown(struct rc_dev *dev, int scancode,
 			  u32 keycode, u8 toggle)
 {
-	input_event(dev->input_dev, EV_MSC, MSC_SCAN, scancode);
+	bool new_event = !dev->keypressed ||
+			 dev->last_scancode != scancode ||
+			 dev->last_toggle != toggle;
 
-	/* Repeat event? */
-	if (dev->keypressed &&
-	    dev->last_scancode == scancode &&
-	    dev->last_toggle == toggle)
-		return;
+	if (new_event && dev->keypressed)
+		ir_do_keyup(dev, false);
 
-	/* Release old keypress */
-	ir_do_keyup(dev);
+	input_event(dev->input_dev, EV_MSC, MSC_SCAN, scancode);
 
-	dev->last_scancode = scancode;
-	dev->last_toggle = toggle;
-	dev->last_keycode = keycode;
+	if (new_event && keycode != KEY_RESERVED) {
+		/* Register a keypress */
+		dev->keypressed = true;
+		dev->last_scancode = scancode;
+		dev->last_toggle = toggle;
+		dev->last_keycode = keycode;
 
-	if (keycode == KEY_RESERVED)
-		return;
+		IR_dprintk(1, "%s: key down event, "
+			   "key 0x%04x, scancode 0x%04x\n",
+			   dev->input_name, keycode, scancode);
+		input_report_key(dev->input_dev, keycode, 1);
+	}
 
-	/* Register a keypress */
-	dev->keypressed = true;
-	IR_dprintk(1, "%s: key down event, key 0x%04x, scancode 0x%04x\n",
-		   dev->input_name, keycode, scancode);
-	input_report_key(dev->input_dev, dev->last_keycode, 1);
 	input_sync(dev->input_dev);
 }
 
@@ -749,6 +751,9 @@
  * it is trigged by reading /sys/class/rc/rc?/protocols.
  * It returns the protocol names of supported protocols.
  * Enabled protocols are printed in brackets.
+ *
+ * dev->lock is taken to guard against races between device
+ * registration, store_protocols and show_protocols.
  */
 static ssize_t show_protocols(struct device *device,
 			      struct device_attribute *mattr, char *buf)
@@ -762,6 +767,8 @@
 	if (!dev)
 		return -EINVAL;
 
+	mutex_lock(&dev->lock);
+
 	if (dev->driver_type == RC_DRIVER_SCANCODE) {
 		enabled = dev->rc_map.rc_type;
 		allowed = dev->allowed_protos;
@@ -784,6 +791,9 @@
 	if (tmp != buf)
 		tmp--;
 	*tmp = '\n';
+
+	mutex_unlock(&dev->lock);
+
 	return tmp + 1 - buf;
 }
 
@@ -802,6 +812,9 @@
  * Writing "none" will disable all protocols.
  * Returns -EINVAL if an invalid protocol combination or unknown protocol name
  * is used, otherwise @len.
+ *
+ * dev->lock is taken to guard against races between device
+ * registration, store_protocols and show_protocols.
  */
 static ssize_t store_protocols(struct device *device,
 			       struct device_attribute *mattr,
@@ -815,18 +828,22 @@
 	u64 mask;
 	int rc, i, count = 0;
 	unsigned long flags;
+	ssize_t ret;
 
 	/* Device is being removed */
 	if (!dev)
 		return -EINVAL;
 
+	mutex_lock(&dev->lock);
+
 	if (dev->driver_type == RC_DRIVER_SCANCODE)
 		type = dev->rc_map.rc_type;
 	else if (dev->raw)
 		type = dev->raw->enabled_protocols;
 	else {
 		IR_dprintk(1, "Protocol switching not supported\n");
-		return -EINVAL;
+		ret = -EINVAL;
+		goto out;
 	}
 
 	while ((tmp = strsep((char **) &data, " \n")) != NULL) {
@@ -860,7 +877,8 @@
 			}
 			if (i == ARRAY_SIZE(proto_names)) {
 				IR_dprintk(1, "Unknown protocol: '%s'\n", tmp);
-				return -EINVAL;
+				ret = -EINVAL;
+				goto out;
 			}
 			count++;
 		}
@@ -875,7 +893,8 @@
 
 	if (!count) {
 		IR_dprintk(1, "Protocol not specified\n");
-		return -EINVAL;
+		ret = -EINVAL;
+		goto out;
 	}
 
 	if (dev->change_protocol) {
@@ -883,7 +902,8 @@
 		if (rc < 0) {
 			IR_dprintk(1, "Error setting protocols to 0x%llx\n",
 				   (long long)type);
-			return -EINVAL;
+			ret = -EINVAL;
+			goto out;
 		}
 	}
 
@@ -898,7 +918,11 @@
 	IR_dprintk(1, "Current protocol(s): 0x%llx\n",
 		   (long long)type);
 
-	return len;
+	ret = len;
+
+out:
+	mutex_unlock(&dev->lock);
+	return ret;
 }
 
 static void rc_dev_release(struct device *device)
@@ -974,6 +998,7 @@
 
 	spin_lock_init(&dev->rc_map.lock);
 	spin_lock_init(&dev->keylock);
+	mutex_init(&dev->lock);
 	setup_timer(&dev->timer_keyup, ir_timer_keyup, (unsigned long)dev);
 
 	dev->dev.type = &rc_dev_type;
@@ -1019,12 +1044,21 @@
 	if (dev->close)
 		dev->input_dev->close = ir_close;
 
+	/*
+	 * Take the lock here, as the device sysfs node will appear
+	 * when device_add() is called, which may trigger an ir-keytable udev
+	 * rule, which will in turn call show_protocols and access either
+	 * dev->rc_map.rc_type or dev->raw->enabled_protocols before it has
+	 * been initialized.
+	 */
+	mutex_lock(&dev->lock);
+
 	dev->devno = (unsigned long)(atomic_inc_return(&devno) - 1);
 	dev_set_name(&dev->dev, "rc%ld", dev->devno);
 	dev_set_drvdata(&dev->dev, dev);
 	rc = device_add(&dev->dev);
 	if (rc)
-		return rc;
+		goto out_unlock;
 
 	rc = ir_setkeytable(dev, rc_map);
 	if (rc)
@@ -1046,6 +1080,13 @@
 	 */
 	dev->input_dev->rep[REP_DELAY] = 500;
 
+	/*
+	 * As a repeat event on protocols like RC-5 and NEC take as long as
+	 * 110/114ms, using 33ms as a repeat period is not the right thing
+	 * to do.
+	 */
+	dev->input_dev->rep[REP_PERIOD] = 125;
+
 	path = kobject_get_path(&dev->dev.kobj, GFP_KERNEL);
 	printk(KERN_INFO "%s: %s as %s\n",
 		dev_name(&dev->dev),
@@ -1058,6 +1099,7 @@
 		if (rc < 0)
 			goto out_input;
 	}
+	mutex_unlock(&dev->lock);
 
 	if (dev->change_protocol) {
 		rc = dev->change_protocol(dev, rc_map->rc_type);
@@ -1083,6 +1125,8 @@
 	ir_free_table(&dev->rc_map);
 out_dev:
 	device_del(&dev->dev);
+out_unlock:
+	mutex_unlock(&dev->lock);
 	return rc;
 }
 EXPORT_SYMBOL_GPL(rc_register_device);
diff -druN linux-2.6.39-libre/drivers/media/rc/redrat3.c linux-3.0-rc7-libre/drivers/media/rc/redrat3.c
--- linux-2.6.39-libre/drivers/media/rc/redrat3.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/media/rc/redrat3.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,1344 @@
+/*
+ * USB RedRat3 IR Transceiver rc-core driver
+ *
+ * Copyright (c) 2011 by Jarod Wilson <jarod@redhat.com>
+ *  based heavily on the work of Stephen Cox, with additional
+ *  help from RedRat Ltd.
+ *
+ * This driver began life based an an old version of the first-generation
+ * lirc_mceusb driver from the lirc 0.7.2 distribution. It was then
+ * significantly rewritten by Stephen Cox with the aid of RedRat Ltd's
+ * Chris Dodge.
+ *
+ * The driver was then ported to rc-core and significantly rewritten again,
+ * by Jarod, using the in-kernel mceusb driver as a guide, after an initial
+ * port effort was started by Stephen.
+ *
+ * TODO LIST:
+ * - fix lirc not showing repeats properly
+ * --
+ *
+ * The RedRat3 is a USB transceiver with both send & receive,
+ * with 2 separate sensors available for receive to enable
+ * both good long range reception for general use, and good
+ * short range reception when required for learning a signal.
+ *
+ * http://www.redrat.co.uk/
+ *
+ * It uses its own little protocol to communicate, the required
+ * parts of which are embedded within this driver.
+ * --
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#include <linux/device.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/usb.h>
+#include <linux/usb/input.h>
+#include <media/rc-core.h>
+
+/* Driver Information */
+#define DRIVER_VERSION "0.70"
+#define DRIVER_AUTHOR "Jarod Wilson <jarod@redhat.com>"
+#define DRIVER_AUTHOR2 "The Dweller, Stephen Cox"
+#define DRIVER_DESC "RedRat3 USB IR Transceiver Driver"
+#define DRIVER_NAME "redrat3"
+
+/* module parameters */
+#ifdef CONFIG_USB_DEBUG
+static int debug = 1;
+#else
+static int debug;
+#endif
+
+#define RR3_DEBUG_STANDARD		0x1
+#define RR3_DEBUG_FUNCTION_TRACE	0x2
+
+#define rr3_dbg(dev, fmt, ...)					\
+	do {							\
+		if (debug & RR3_DEBUG_STANDARD)			\
+			dev_info(dev, fmt, ## __VA_ARGS__);	\
+	} while (0)
+
+#define rr3_ftr(dev, fmt, ...)					\
+	do {							\
+		if (debug & RR3_DEBUG_FUNCTION_TRACE)		\
+			dev_info(dev, fmt, ## __VA_ARGS__);	\
+	} while (0)
+
+/* bulk data transfer types */
+#define RR3_ERROR		0x01
+#define RR3_MOD_SIGNAL_IN	0x20
+#define RR3_MOD_SIGNAL_OUT	0x21
+
+/* Get the RR firmware version */
+#define RR3_FW_VERSION		0xb1
+#define RR3_FW_VERSION_LEN	64
+/* Send encoded signal bulk-sent earlier*/
+#define RR3_TX_SEND_SIGNAL	0xb3
+#define RR3_SET_IR_PARAM	0xb7
+#define RR3_GET_IR_PARAM	0xb8
+/* Blink the red LED on the device */
+#define RR3_BLINK_LED		0xb9
+/* Read serial number of device */
+#define RR3_READ_SER_NO		0xba
+#define RR3_SER_NO_LEN		4
+/* Start capture with the RC receiver */
+#define RR3_RC_DET_ENABLE	0xbb
+/* Stop capture with the RC receiver */
+#define RR3_RC_DET_DISABLE	0xbc
+/* Return the status of RC detector capture */
+#define RR3_RC_DET_STATUS	0xbd
+/* Reset redrat */
+#define RR3_RESET		0xa0
+
+/* Max number of lengths in the signal. */
+#define RR3_IR_IO_MAX_LENGTHS	0x01
+/* Periods to measure mod. freq. */
+#define RR3_IR_IO_PERIODS_MF	0x02
+/* Size of memory for main signal data */
+#define RR3_IR_IO_SIG_MEM_SIZE	0x03
+/* Delta value when measuring lengths */
+#define RR3_IR_IO_LENGTH_FUZZ	0x04
+/* Timeout for end of signal detection */
+#define RR3_IR_IO_SIG_TIMEOUT	0x05
+/* Minumum value for pause recognition. */
+#define RR3_IR_IO_MIN_PAUSE	0x06
+
+/* Clock freq. of EZ-USB chip */
+#define RR3_CLK			24000000
+/* Clock periods per timer count */
+#define RR3_CLK_PER_COUNT	12
+/* (RR3_CLK / RR3_CLK_PER_COUNT) */
+#define RR3_CLK_CONV_FACTOR	2000000
+/* USB bulk-in IR data endpoint address */
+#define RR3_BULK_IN_EP_ADDR	0x82
+
+/* Raw Modulated signal data value offsets */
+#define RR3_PAUSE_OFFSET	0
+#define RR3_FREQ_COUNT_OFFSET	4
+#define RR3_NUM_PERIOD_OFFSET	6
+#define RR3_MAX_LENGTHS_OFFSET	8
+#define RR3_NUM_LENGTHS_OFFSET	9
+#define RR3_MAX_SIGS_OFFSET	10
+#define RR3_NUM_SIGS_OFFSET	12
+#define RR3_REPEATS_OFFSET	14
+
+/* Size of the fixed-length portion of the signal */
+#define RR3_HEADER_LENGTH	15
+#define RR3_DRIVER_MAXLENS	128
+#define RR3_MAX_SIG_SIZE	512
+#define RR3_MAX_BUF_SIZE	\
+	((2 * RR3_HEADER_LENGTH) + RR3_DRIVER_MAXLENS + RR3_MAX_SIG_SIZE)
+#define RR3_TIME_UNIT		50
+#define RR3_END_OF_SIGNAL	0x7f
+#define RR3_TX_HEADER_OFFSET	4
+#define RR3_TX_TRAILER_LEN	2
+#define RR3_RX_MIN_TIMEOUT	5
+#define RR3_RX_MAX_TIMEOUT	2000
+
+/* The 8051's CPUCS Register address */
+#define RR3_CPUCS_REG_ADDR	0x7f92
+
+#define USB_RR3USB_VENDOR_ID	0x112a
+#define USB_RR3USB_PRODUCT_ID	0x0001
+#define USB_RR3IIUSB_PRODUCT_ID	0x0005
+
+/* table of devices that work with this driver */
+static struct usb_device_id redrat3_dev_table[] = {
+	/* Original version of the RedRat3 */
+	{USB_DEVICE(USB_RR3USB_VENDOR_ID, USB_RR3USB_PRODUCT_ID)},
+	/* Second Version/release of the RedRat3 - RetRat3-II */
+	{USB_DEVICE(USB_RR3USB_VENDOR_ID, USB_RR3IIUSB_PRODUCT_ID)},
+	{}			/* Terminating entry */
+};
+
+/* Structure to hold all of our device specific stuff */
+struct redrat3_dev {
+	/* core device bits */
+	struct rc_dev *rc;
+	struct device *dev;
+
+	/* save off the usb device pointer */
+	struct usb_device *udev;
+
+	/* the receive endpoint */
+	struct usb_endpoint_descriptor *ep_in;
+	/* the buffer to receive data */
+	unsigned char *bulk_in_buf;
+	/* urb used to read ir data */
+	struct urb *read_urb;
+
+	/* the send endpoint */
+	struct usb_endpoint_descriptor *ep_out;
+	/* the buffer to send data */
+	unsigned char *bulk_out_buf;
+	/* the urb used to send data */
+	struct urb *write_urb;
+
+	/* usb dma */
+	dma_addr_t dma_in;
+	dma_addr_t dma_out;
+
+	/* true if write urb is busy */
+	bool write_busy;
+	/* wait for the write to finish */
+	struct completion write_finished;
+
+	/* locks this structure */
+	struct mutex lock;
+
+	/* rx signal timeout timer */
+	struct timer_list rx_timeout;
+
+	/* Is the device currently receiving? */
+	bool recv_in_progress;
+	/* is the detector enabled*/
+	bool det_enabled;
+	/* Is the device currently transmitting?*/
+	bool transmitting;
+
+	/* store for current packet */
+	char pbuf[RR3_MAX_BUF_SIZE];
+	u16 pktlen;
+	u16 pkttype;
+	u16 bytes_read;
+	/* indicate whether we are going to reprocess
+	 * the USB callback with a bigger buffer */
+	int buftoosmall;
+	char *datap;
+
+	u32 carrier;
+
+	char name[128];
+	char phys[64];
+};
+
+/* All incoming data buffers adhere to a very specific data format */
+struct redrat3_signal_header {
+	u16 length;	/* Length of data being transferred */
+	u16 transfer_type; /* Type of data transferred */
+	u32 pause;	/* Pause between main and repeat signals */
+	u16 mod_freq_count; /* Value of timer on mod. freq. measurement */
+	u16 no_periods;	/* No. of periods over which mod. freq. is measured */
+	u8 max_lengths;	/* Max no. of lengths (i.e. size of array) */
+	u8 no_lengths;	/* Actual no. of elements in lengths array */
+	u16 max_sig_size; /* Max no. of values in signal data array */
+	u16 sig_size;	/* Acuto no. of values in signal data array */
+	u8 no_repeats;	/* No. of repeats of repeat signal section */
+	/* Here forward is the lengths and signal data */
+};
+
+static void redrat3_dump_signal_header(struct redrat3_signal_header *header)
+{
+	pr_info("%s:\n", __func__);
+	pr_info(" * length: %u, transfer_type: 0x%02x\n",
+		header->length, header->transfer_type);
+	pr_info(" * pause: %u, freq_count: %u, no_periods: %u\n",
+		header->pause, header->mod_freq_count, header->no_periods);
+	pr_info(" * lengths: %u (max: %u)\n",
+		header->no_lengths, header->max_lengths);
+	pr_info(" * sig_size: %u (max: %u)\n",
+		header->sig_size, header->max_sig_size);
+	pr_info(" * repeats: %u\n", header->no_repeats);
+}
+
+static void redrat3_dump_signal_data(char *buffer, u16 len)
+{
+	int offset, i;
+	char *data_vals;
+
+	pr_info("%s:", __func__);
+
+	offset = RR3_TX_HEADER_OFFSET + RR3_HEADER_LENGTH
+		 + (RR3_DRIVER_MAXLENS * sizeof(u16));
+
+	/* read RR3_DRIVER_MAXLENS from ctrl msg */
+	data_vals = buffer + offset;
+
+	for (i = 0; i < len; i++) {
+		if (i % 10 == 0)
+			pr_cont("\n * ");
+		pr_cont("%02x ", *data_vals++);
+	}
+
+	pr_cont("\n");
+}
+
+/*
+ * redrat3_issue_async
+ *
+ *  Issues an async read to the ir data in port..
+ *  sets the callback to be redrat3_handle_async
+ */
+static void redrat3_issue_async(struct redrat3_dev *rr3)
+{
+	int res;
+
+	rr3_ftr(rr3->dev, "Entering %s\n", __func__);
+
+	if (!rr3->det_enabled) {
+		dev_warn(rr3->dev, "not issuing async read, "
+			 "detector not enabled\n");
+		return;
+	}
+
+	memset(rr3->bulk_in_buf, 0, rr3->ep_in->wMaxPacketSize);
+	res = usb_submit_urb(rr3->read_urb, GFP_ATOMIC);
+	if (res)
+		rr3_dbg(rr3->dev, "%s: receive request FAILED! "
+			"(res %d, len %d)\n", __func__, res,
+			rr3->read_urb->transfer_buffer_length);
+}
+
+static void redrat3_dump_fw_error(struct redrat3_dev *rr3, int code)
+{
+	if (!rr3->transmitting && (code != 0x40))
+		dev_info(rr3->dev, "fw error code 0x%02x: ", code);
+
+	switch (code) {
+	case 0x00:
+		pr_cont("No Error\n");
+		break;
+
+	/* Codes 0x20 through 0x2f are IR Firmware Errors */
+	case 0x20:
+		pr_cont("Initial signal pulse not long enough "
+			"to measure carrier frequency\n");
+		break;
+	case 0x21:
+		pr_cont("Not enough length values allocated for signal\n");
+		break;
+	case 0x22:
+		pr_cont("Not enough memory allocated for signal data\n");
+		break;
+	case 0x23:
+		pr_cont("Too many signal repeats\n");
+		break;
+	case 0x28:
+		pr_cont("Insufficient memory available for IR signal "
+			"data memory allocation\n");
+		break;
+	case 0x29:
+		pr_cont("Insufficient memory available "
+			"for IrDa signal data memory allocation\n");
+		break;
+
+	/* Codes 0x30 through 0x3f are USB Firmware Errors */
+	case 0x30:
+		pr_cont("Insufficient memory available for bulk "
+			"transfer structure\n");
+		break;
+
+	/*
+	 * Other error codes... These are primarily errors that can occur in
+	 * the control messages sent to the redrat
+	 */
+	case 0x40:
+		if (!rr3->transmitting)
+			pr_cont("Signal capture has been terminated\n");
+		break;
+	case 0x41:
+		pr_cont("Attempt to set/get and unknown signal I/O "
+			"algorithm parameter\n");
+		break;
+	case 0x42:
+		pr_cont("Signal capture already started\n");
+		break;
+
+	default:
+		pr_cont("Unknown Error\n");
+		break;
+	}
+}
+
+static u32 redrat3_val_to_mod_freq(struct redrat3_signal_header *ph)
+{
+	u32 mod_freq = 0;
+
+	if (ph->mod_freq_count != 0)
+		mod_freq = (RR3_CLK * ph->no_periods) /
+				(ph->mod_freq_count * RR3_CLK_PER_COUNT);
+
+	return mod_freq;
+}
+
+/* this function scales down the figures for the same result... */
+static u32 redrat3_len_to_us(u32 length)
+{
+	u32 biglen = length * 1000;
+	u32 divisor = (RR3_CLK_CONV_FACTOR) / 1000;
+	u32 result = (u32) (biglen / divisor);
+
+	/* don't allow zero lengths to go back, breaks lirc */
+	return result ? result : 1;
+}
+
+/*
+ * convert us back into redrat3 lengths
+ *
+ * length * 1000   length * 1000000
+ * ------------- = ---------------- = micro
+ * rr3clk / 1000       rr3clk
+
+ * 6 * 2       4 * 3        micro * rr3clk          micro * rr3clk / 1000
+ * ----- = 4   ----- = 6    -------------- = len    ---------------------
+ *   3           2             1000000                    1000
+ */
+static u32 redrat3_us_to_len(u32 microsec)
+{
+	u32 result;
+	u32 divisor;
+
+	microsec &= IR_MAX_DURATION;
+	divisor = (RR3_CLK_CONV_FACTOR / 1000);
+	result = (u32)(microsec * divisor) / 1000;
+
+	/* don't allow zero lengths to go back, breaks lirc */
+	return result ? result : 1;
+
+}
+
+/* timer callback to send long trailing space on receive timeout */
+static void redrat3_rx_timeout(unsigned long data)
+{
+	struct redrat3_dev *rr3 = (struct redrat3_dev *)data;
+	DEFINE_IR_RAW_EVENT(rawir);
+
+	rawir.pulse = false;
+	rawir.duration = rr3->rc->timeout;
+	rr3_dbg(rr3->dev, "storing trailing space with duration %d\n",
+		rawir.duration);
+	ir_raw_event_store_with_filter(rr3->rc, &rawir);
+
+	rr3_dbg(rr3->dev, "calling ir_raw_event_handle\n");
+	ir_raw_event_handle(rr3->rc);
+
+	rr3_dbg(rr3->dev, "calling ir_raw_event_reset\n");
+	ir_raw_event_reset(rr3->rc);
+}
+
+static void redrat3_process_ir_data(struct redrat3_dev *rr3)
+{
+	DEFINE_IR_RAW_EVENT(rawir);
+	struct redrat3_signal_header header;
+	struct device *dev;
+	int i;
+	unsigned long delay;
+	u32 mod_freq, single_len;
+	u16 *len_vals;
+	u8 *data_vals;
+	u32 tmp32;
+	u16 tmp16;
+	char *sig_data;
+
+	if (!rr3) {
+		pr_err("%s called with no context!\n", __func__);
+		return;
+	}
+
+	rr3_ftr(rr3->dev, "Entered %s\n", __func__);
+
+	dev = rr3->dev;
+	sig_data = rr3->pbuf;
+
+	header.length = rr3->pktlen;
+	header.transfer_type = rr3->pkttype;
+
+	/* Sanity check */
+	if (!(header.length >= RR3_HEADER_LENGTH))
+		dev_warn(dev, "read returned less than rr3 header len\n");
+
+	delay = usecs_to_jiffies(rr3->rc->timeout / 1000);
+	mod_timer(&rr3->rx_timeout, jiffies + delay);
+
+	memcpy(&tmp32, sig_data + RR3_PAUSE_OFFSET, sizeof(tmp32));
+	header.pause = be32_to_cpu(tmp32);
+
+	memcpy(&tmp16, sig_data + RR3_FREQ_COUNT_OFFSET, sizeof(tmp16));
+	header.mod_freq_count = be16_to_cpu(tmp16);
+
+	memcpy(&tmp16, sig_data + RR3_NUM_PERIOD_OFFSET, sizeof(tmp16));
+	header.no_periods = be16_to_cpu(tmp16);
+
+	header.max_lengths = sig_data[RR3_MAX_LENGTHS_OFFSET];
+	header.no_lengths = sig_data[RR3_NUM_LENGTHS_OFFSET];
+
+	memcpy(&tmp16, sig_data + RR3_MAX_SIGS_OFFSET, sizeof(tmp16));
+	header.max_sig_size = be16_to_cpu(tmp16);
+
+	memcpy(&tmp16, sig_data + RR3_NUM_SIGS_OFFSET, sizeof(tmp16));
+	header.sig_size = be16_to_cpu(tmp16);
+
+	header.no_repeats= sig_data[RR3_REPEATS_OFFSET];
+
+	if (debug) {
+		redrat3_dump_signal_header(&header);
+		redrat3_dump_signal_data(sig_data, header.sig_size);
+	}
+
+	mod_freq = redrat3_val_to_mod_freq(&header);
+	rr3_dbg(dev, "Got mod_freq of %u\n", mod_freq);
+
+	/* Here we pull out the 'length' values from the signal */
+	len_vals = (u16 *)(sig_data + RR3_HEADER_LENGTH);
+
+	data_vals = sig_data + RR3_HEADER_LENGTH +
+		    (header.max_lengths * sizeof(u16));
+
+	/* process each rr3 encoded byte into an int */
+	for (i = 0; i < header.sig_size; i++) {
+		u16 val = len_vals[data_vals[i]];
+		single_len = redrat3_len_to_us((u32)be16_to_cpu(val));
+
+		/* cap the value to IR_MAX_DURATION */
+		single_len &= IR_MAX_DURATION;
+
+		/* we should always get pulse/space/pulse/space samples */
+		if (i % 2)
+			rawir.pulse = false;
+		else
+			rawir.pulse = true;
+
+		rawir.duration = US_TO_NS(single_len);
+		rr3_dbg(dev, "storing %s with duration %d (i: %d)\n",
+			rawir.pulse ? "pulse" : "space", rawir.duration, i);
+		ir_raw_event_store_with_filter(rr3->rc, &rawir);
+	}
+
+	/* add a trailing space, if need be */
+	if (i % 2) {
+		rawir.pulse = false;
+		/* this duration is made up, and may not be ideal... */
+		rawir.duration = rr3->rc->timeout / 2;
+		rr3_dbg(dev, "storing trailing space with duration %d\n",
+			rawir.duration);
+		ir_raw_event_store_with_filter(rr3->rc, &rawir);
+	}
+
+	rr3_dbg(dev, "calling ir_raw_event_handle\n");
+	ir_raw_event_handle(rr3->rc);
+
+	return;
+}
+
+/* Util fn to send rr3 cmds */
+static u8 redrat3_send_cmd(int cmd, struct redrat3_dev *rr3)
+{
+	struct usb_device *udev;
+	u8 *data;
+	int res;
+
+	data = kzalloc(sizeof(u8), GFP_KERNEL);
+	if (!data)
+		return -ENOMEM;
+
+	udev = rr3->udev;
+	res = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), cmd,
+			      USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
+			      0x0000, 0x0000, data, sizeof(u8), HZ * 10);
+
+	if (res < 0) {
+		dev_err(rr3->dev, "%s: Error sending rr3 cmd res %d, data %d",
+			__func__, res, *data);
+		res = -EIO;
+	} else
+		res = (u8)data[0];
+
+	kfree(data);
+
+	return res;
+}
+
+/* Enables the long range detector and starts async receive */
+static int redrat3_enable_detector(struct redrat3_dev *rr3)
+{
+	struct device *dev = rr3->dev;
+	u8 ret;
+
+	rr3_ftr(dev, "Entering %s\n", __func__);
+
+	ret = redrat3_send_cmd(RR3_RC_DET_ENABLE, rr3);
+	if (ret != 0)
+		dev_dbg(dev, "%s: unexpected ret of %d\n",
+			__func__, ret);
+
+	ret = redrat3_send_cmd(RR3_RC_DET_STATUS, rr3);
+	if (ret != 1) {
+		dev_err(dev, "%s: detector status: %d, should be 1\n",
+			__func__, ret);
+		return -EIO;
+	}
+
+	rr3->det_enabled = true;
+	redrat3_issue_async(rr3);
+
+	return 0;
+}
+
+/* Disables the rr3 long range detector */
+static void redrat3_disable_detector(struct redrat3_dev *rr3)
+{
+	struct device *dev = rr3->dev;
+	u8 ret;
+
+	rr3_ftr(dev, "Entering %s\n", __func__);
+
+	ret = redrat3_send_cmd(RR3_RC_DET_DISABLE, rr3);
+	if (ret != 0)
+		dev_err(dev, "%s: failure!\n", __func__);
+
+	ret = redrat3_send_cmd(RR3_RC_DET_STATUS, rr3);
+	if (ret != 0)
+		dev_warn(dev, "%s: detector status: %d, should be 0\n",
+			 __func__, ret);
+
+	rr3->det_enabled = false;
+}
+
+static inline void redrat3_delete(struct redrat3_dev *rr3,
+				  struct usb_device *udev)
+{
+	rr3_ftr(rr3->dev, "%s cleaning up\n", __func__);
+	usb_kill_urb(rr3->read_urb);
+	usb_kill_urb(rr3->write_urb);
+
+	usb_free_urb(rr3->read_urb);
+	usb_free_urb(rr3->write_urb);
+
+	usb_free_coherent(udev, rr3->ep_in->wMaxPacketSize,
+			  rr3->bulk_in_buf, rr3->dma_in);
+	usb_free_coherent(udev, rr3->ep_out->wMaxPacketSize,
+			  rr3->bulk_out_buf, rr3->dma_out);
+
+	kfree(rr3);
+}
+
+static u32 redrat3_get_timeout(struct device *dev,
+			       struct rc_dev *rc, struct usb_device *udev)
+{
+	u32 *tmp;
+	u32 timeout = MS_TO_NS(150); /* a sane default, if things go haywire */
+	int len, ret, pipe;
+
+	len = sizeof(*tmp);
+	tmp = kzalloc(len, GFP_KERNEL);
+	if (!tmp) {
+		dev_warn(dev, "Memory allocation faillure\n");
+		return timeout;
+	}
+
+	pipe = usb_rcvctrlpipe(udev, 0);
+	ret = usb_control_msg(udev, pipe, RR3_GET_IR_PARAM,
+			      USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
+			      RR3_IR_IO_SIG_TIMEOUT, 0, tmp, len, HZ * 5);
+	if (ret != len) {
+		dev_warn(dev, "Failed to read timeout from hardware\n");
+		return timeout;
+	}
+
+	timeout = US_TO_NS(redrat3_len_to_us(be32_to_cpu(*tmp)));
+	if (timeout < rc->min_timeout)
+		timeout = rc->min_timeout;
+	else if (timeout > rc->max_timeout)
+		timeout = rc->max_timeout;
+
+	rr3_dbg(dev, "Got timeout of %d ms\n", timeout / (1000 * 1000));
+	return timeout;
+}
+
+static void redrat3_reset(struct redrat3_dev *rr3)
+{
+	struct usb_device *udev = rr3->udev;
+	struct device *dev = rr3->dev;
+	int rc, rxpipe, txpipe;
+	u8 *val;
+	int len = sizeof(u8);
+
+	rr3_ftr(dev, "Entering %s\n", __func__);
+
+	rxpipe = usb_rcvctrlpipe(udev, 0);
+	txpipe = usb_sndctrlpipe(udev, 0);
+
+	val = kzalloc(len, GFP_KERNEL);
+	if (!val) {
+		dev_err(dev, "Memory allocation failure\n");
+		return;
+	}
+
+	*val = 0x01;
+	rc = usb_control_msg(udev, rxpipe, RR3_RESET,
+			     USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
+			     RR3_CPUCS_REG_ADDR, 0, val, len, HZ * 25);
+	rr3_dbg(dev, "reset returned 0x%02x\n", rc);
+
+	*val = 5;
+	rc = usb_control_msg(udev, txpipe, RR3_SET_IR_PARAM,
+			     USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT,
+			     RR3_IR_IO_LENGTH_FUZZ, 0, val, len, HZ * 25);
+	rr3_dbg(dev, "set ir parm len fuzz %d rc 0x%02x\n", *val, rc);
+
+	*val = RR3_DRIVER_MAXLENS;
+	rc = usb_control_msg(udev, txpipe, RR3_SET_IR_PARAM,
+			     USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT,
+			     RR3_IR_IO_MAX_LENGTHS, 0, val, len, HZ * 25);
+	rr3_dbg(dev, "set ir parm max lens %d rc 0x%02x\n", *val, rc);
+
+	kfree(val);
+}
+
+static void redrat3_get_firmware_rev(struct redrat3_dev *rr3)
+{
+	int rc = 0;
+	char *buffer;
+
+	rr3_ftr(rr3->dev, "Entering %s\n", __func__);
+
+	buffer = kzalloc(sizeof(char) * (RR3_FW_VERSION_LEN + 1), GFP_KERNEL);
+	if (!buffer) {
+		dev_err(rr3->dev, "Memory allocation failure\n");
+		return;
+	}
+
+	rc = usb_control_msg(rr3->udev, usb_rcvctrlpipe(rr3->udev, 0),
+			     RR3_FW_VERSION,
+			     USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
+			     0, 0, buffer, RR3_FW_VERSION_LEN, HZ * 5);
+
+	if (rc >= 0)
+		dev_info(rr3->dev, "Firmware rev: %s", buffer);
+	else
+		dev_err(rr3->dev, "Problem fetching firmware ID\n");
+
+	kfree(buffer);
+	rr3_ftr(rr3->dev, "Exiting %s\n", __func__);
+}
+
+static void redrat3_read_packet_start(struct redrat3_dev *rr3, int len)
+{
+	u16 tx_error;
+	u16 hdrlen;
+
+	rr3_ftr(rr3->dev, "Entering %s\n", __func__);
+
+	/* grab the Length and type of transfer */
+	memcpy(&(rr3->pktlen), (unsigned char *) rr3->bulk_in_buf,
+	       sizeof(rr3->pktlen));
+	memcpy(&(rr3->pkttype), ((unsigned char *) rr3->bulk_in_buf +
+		sizeof(rr3->pktlen)),
+	       sizeof(rr3->pkttype));
+
+	/*data needs conversion to know what its real values are*/
+	rr3->pktlen = be16_to_cpu(rr3->pktlen);
+	rr3->pkttype = be16_to_cpu(rr3->pkttype);
+
+	switch (rr3->pkttype) {
+	case RR3_ERROR:
+		memcpy(&tx_error, ((unsigned char *)rr3->bulk_in_buf
+			+ (sizeof(rr3->pktlen) + sizeof(rr3->pkttype))),
+		       sizeof(tx_error));
+		tx_error = be16_to_cpu(tx_error);
+		redrat3_dump_fw_error(rr3, tx_error);
+		break;
+
+	case RR3_MOD_SIGNAL_IN:
+		hdrlen = sizeof(rr3->pktlen) + sizeof(rr3->pkttype);
+		rr3->bytes_read = len;
+		rr3->bytes_read -= hdrlen;
+		rr3->datap = &(rr3->pbuf[0]);
+
+		memcpy(rr3->datap, ((unsigned char *)rr3->bulk_in_buf + hdrlen),
+		       rr3->bytes_read);
+		rr3->datap += rr3->bytes_read;
+		rr3_dbg(rr3->dev, "bytes_read %d, pktlen %d\n",
+			rr3->bytes_read, rr3->pktlen);
+		break;
+
+	default:
+		rr3_dbg(rr3->dev, "ignoring packet with type 0x%02x, "
+			"len of %d, 0x%02x\n", rr3->pkttype, len, rr3->pktlen);
+		break;
+	}
+}
+
+static void redrat3_read_packet_continue(struct redrat3_dev *rr3, int len)
+{
+
+	rr3_ftr(rr3->dev, "Entering %s\n", __func__);
+
+	memcpy(rr3->datap, (unsigned char *)rr3->bulk_in_buf, len);
+	rr3->datap += len;
+
+	rr3->bytes_read += len;
+	rr3_dbg(rr3->dev, "bytes_read %d, pktlen %d\n",
+		rr3->bytes_read, rr3->pktlen);
+}
+
+/* gather IR data from incoming urb, process it when we have enough */
+static int redrat3_get_ir_data(struct redrat3_dev *rr3, int len)
+{
+	struct device *dev = rr3->dev;
+	int ret = 0;
+
+	rr3_ftr(dev, "Entering %s\n", __func__);
+
+	if (rr3->pktlen > RR3_MAX_BUF_SIZE) {
+		dev_err(rr3->dev, "error: packet larger than buffer\n");
+		ret = -EINVAL;
+		goto out;
+	}
+
+	if ((rr3->bytes_read == 0) &&
+	    (len >= (sizeof(rr3->pkttype) + sizeof(rr3->pktlen)))) {
+		redrat3_read_packet_start(rr3, len);
+	} else if (rr3->bytes_read != 0) {
+		redrat3_read_packet_continue(rr3, len);
+	} else if (rr3->bytes_read == 0) {
+		dev_err(dev, "error: no packet data read\n");
+		ret = -ENODATA;
+		goto out;
+	}
+
+	if (rr3->bytes_read > rr3->pktlen) {
+		dev_err(dev, "bytes_read (%d) greater than pktlen (%d)\n",
+			rr3->bytes_read, rr3->pktlen);
+		ret = -EINVAL;
+		goto out;
+	} else if (rr3->bytes_read < rr3->pktlen)
+		/* we're still accumulating data */
+		return 0;
+
+	/* if we get here, we've got IR data to decode */
+	if (rr3->pkttype == RR3_MOD_SIGNAL_IN)
+		redrat3_process_ir_data(rr3);
+	else
+		rr3_dbg(dev, "discarding non-signal data packet "
+			"(type 0x%02x)\n", rr3->pkttype);
+
+out:
+	rr3->bytes_read = 0;
+	rr3->pktlen = 0;
+	rr3->pkttype = 0;
+	return ret;
+}
+
+/* callback function from USB when async USB request has completed */
+static void redrat3_handle_async(struct urb *urb, struct pt_regs *regs)
+{
+	struct redrat3_dev *rr3;
+
+	if (!urb)
+		return;
+
+	rr3 = urb->context;
+	if (!rr3) {
+		pr_err("%s called with invalid context!\n", __func__);
+		usb_unlink_urb(urb);
+		return;
+	}
+
+	rr3_ftr(rr3->dev, "Entering %s\n", __func__);
+
+	if (!rr3->det_enabled) {
+		rr3_dbg(rr3->dev, "received a read callback but detector "
+			"disabled - ignoring\n");
+		return;
+	}
+
+	switch (urb->status) {
+	case 0:
+		redrat3_get_ir_data(rr3, urb->actual_length);
+		break;
+
+	case -ECONNRESET:
+	case -ENOENT:
+	case -ESHUTDOWN:
+		usb_unlink_urb(urb);
+		return;
+
+	case -EPIPE:
+	default:
+		dev_warn(rr3->dev, "Error: urb status = %d\n", urb->status);
+		rr3->bytes_read = 0;
+		rr3->pktlen = 0;
+		rr3->pkttype = 0;
+		break;
+	}
+
+	if (!rr3->transmitting)
+		redrat3_issue_async(rr3);
+	else
+		rr3_dbg(rr3->dev, "IR transmit in progress\n");
+}
+
+static void redrat3_write_bulk_callback(struct urb *urb, struct pt_regs *regs)
+{
+	struct redrat3_dev *rr3;
+	int len;
+
+	if (!urb)
+		return;
+
+	rr3 = urb->context;
+	if (rr3) {
+		len = urb->actual_length;
+		rr3_ftr(rr3->dev, "%s: called (status=%d len=%d)\n",
+			__func__, urb->status, len);
+	}
+}
+
+static u16 mod_freq_to_val(unsigned int mod_freq)
+{
+	int mult = 6000000;
+
+	/* Clk used in mod. freq. generation is CLK24/4. */
+	return (u16)(65536 - (mult / mod_freq));
+}
+
+static int redrat3_set_tx_carrier(struct rc_dev *dev, u32 carrier)
+{
+	struct redrat3_dev *rr3 = dev->priv;
+
+	rr3->carrier = carrier;
+
+	return carrier;
+}
+
+static int redrat3_transmit_ir(struct rc_dev *rcdev, int *txbuf, u32 n)
+{
+	struct redrat3_dev *rr3 = rcdev->priv;
+	struct device *dev = rr3->dev;
+	struct redrat3_signal_header header;
+	int i, j, count, ret, ret_len, offset;
+	int lencheck, cur_sample_len, pipe;
+	char *buffer = NULL, *sigdata = NULL;
+	int *sample_lens = NULL;
+	u32 tmpi;
+	u16 tmps;
+	u8 *datap;
+	u8 curlencheck = 0;
+	u16 *lengths_ptr;
+	int sendbuf_len;
+
+	rr3_ftr(dev, "Entering %s\n", __func__);
+
+	if (rr3->transmitting) {
+		dev_warn(dev, "%s: transmitter already in use\n", __func__);
+		return -EAGAIN;
+	}
+
+	count = n / sizeof(int);
+	if (count > (RR3_DRIVER_MAXLENS * 2))
+		return -EINVAL;
+
+	rr3->transmitting = true;
+
+	redrat3_disable_detector(rr3);
+
+	if (rr3->det_enabled) {
+		dev_err(dev, "%s: cannot tx while rx is enabled\n", __func__);
+		ret = -EIO;
+		goto out;
+	}
+
+	sample_lens = kzalloc(sizeof(int) * RR3_DRIVER_MAXLENS, GFP_KERNEL);
+	if (!sample_lens) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	for (i = 0; i < count; i++) {
+		for (lencheck = 0; lencheck < curlencheck; lencheck++) {
+			cur_sample_len = redrat3_us_to_len(txbuf[i]);
+			if (sample_lens[lencheck] == cur_sample_len)
+				break;
+		}
+		if (lencheck == curlencheck) {
+			cur_sample_len = redrat3_us_to_len(txbuf[i]);
+			rr3_dbg(dev, "txbuf[%d]=%u, pos %d, enc %u\n",
+				i, txbuf[i], curlencheck, cur_sample_len);
+			if (curlencheck < 255) {
+				/* now convert the value to a proper
+				 * rr3 value.. */
+				sample_lens[curlencheck] = cur_sample_len;
+				curlencheck++;
+			} else {
+				dev_err(dev, "signal too long\n");
+				ret = -EINVAL;
+				goto out;
+			}
+		}
+	}
+
+	sigdata = kzalloc((count + RR3_TX_TRAILER_LEN), GFP_KERNEL);
+	if (!sigdata) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	sigdata[count] = RR3_END_OF_SIGNAL;
+	sigdata[count + 1] = RR3_END_OF_SIGNAL;
+	for (i = 0; i < count; i++) {
+		for (j = 0; j < curlencheck; j++) {
+			if (sample_lens[j] == redrat3_us_to_len(txbuf[i]))
+				sigdata[i] = j;
+		}
+	}
+
+	offset = RR3_TX_HEADER_OFFSET;
+	sendbuf_len = RR3_HEADER_LENGTH + (sizeof(u16) * RR3_DRIVER_MAXLENS)
+			+ count + RR3_TX_TRAILER_LEN + offset;
+
+	buffer = kzalloc(sendbuf_len, GFP_KERNEL);
+	if (!buffer) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	/* fill in our packet header */
+	header.length = sendbuf_len - offset;
+	header.transfer_type = RR3_MOD_SIGNAL_OUT;
+	header.pause = redrat3_len_to_us(100);
+	header.mod_freq_count = mod_freq_to_val(rr3->carrier);
+	header.no_periods = 0; /* n/a to transmit */
+	header.max_lengths = RR3_DRIVER_MAXLENS;
+	header.no_lengths = curlencheck;
+	header.max_sig_size = RR3_MAX_SIG_SIZE;
+	header.sig_size = count + RR3_TX_TRAILER_LEN;
+	/* we currently rely on repeat handling in the IR encoding source */
+	header.no_repeats = 0;
+
+	tmps = cpu_to_be16(header.length);
+	memcpy(buffer, &tmps, 2);
+
+	tmps = cpu_to_be16(header.transfer_type);
+	memcpy(buffer + 2, &tmps, 2);
+
+	tmpi = cpu_to_be32(header.pause);
+	memcpy(buffer + offset, &tmpi, sizeof(tmpi));
+
+	tmps = cpu_to_be16(header.mod_freq_count);
+	memcpy(buffer + offset + RR3_FREQ_COUNT_OFFSET, &tmps, 2);
+
+	buffer[offset + RR3_NUM_LENGTHS_OFFSET] = header.no_lengths;
+
+	tmps = cpu_to_be16(header.sig_size);
+	memcpy(buffer + offset + RR3_NUM_SIGS_OFFSET, &tmps, 2);
+
+	buffer[offset + RR3_REPEATS_OFFSET] = header.no_repeats;
+
+	lengths_ptr = (u16 *)(buffer + offset + RR3_HEADER_LENGTH);
+	for (i = 0; i < curlencheck; ++i)
+		lengths_ptr[i] = cpu_to_be16(sample_lens[i]);
+
+	datap = (u8 *)(buffer + offset + RR3_HEADER_LENGTH +
+			    (sizeof(u16) * RR3_DRIVER_MAXLENS));
+	memcpy(datap, sigdata, (count + RR3_TX_TRAILER_LEN));
+
+	if (debug) {
+		redrat3_dump_signal_header(&header);
+		redrat3_dump_signal_data(buffer, header.sig_size);
+	}
+
+	pipe = usb_sndbulkpipe(rr3->udev, rr3->ep_out->bEndpointAddress);
+	tmps = usb_bulk_msg(rr3->udev, pipe, buffer,
+			    sendbuf_len, &ret_len, 10 * HZ);
+	rr3_dbg(dev, "sent %d bytes, (ret %d)\n", ret_len, tmps);
+
+	/* now tell the hardware to transmit what we sent it */
+	pipe = usb_rcvctrlpipe(rr3->udev, 0);
+	ret = usb_control_msg(rr3->udev, pipe, RR3_TX_SEND_SIGNAL,
+			      USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
+			      0, 0, buffer, 2, HZ * 10);
+
+	if (ret < 0)
+		dev_err(dev, "Error: control msg send failed, rc %d\n", ret);
+	else
+		ret = n;
+
+out:
+	kfree(sample_lens);
+	kfree(buffer);
+	kfree(sigdata);
+
+	rr3->transmitting = false;
+
+	redrat3_enable_detector(rr3);
+
+	return ret;
+}
+
+static struct rc_dev *redrat3_init_rc_dev(struct redrat3_dev *rr3)
+{
+	struct device *dev = rr3->dev;
+	struct rc_dev *rc;
+	int ret = -ENODEV;
+	u16 prod = le16_to_cpu(rr3->udev->descriptor.idProduct);
+
+	rc = rc_allocate_device();
+	if (!rc) {
+		dev_err(dev, "remote input dev allocation failed\n");
+		goto out;
+	}
+
+	snprintf(rr3->name, sizeof(rr3->name), "RedRat3%s "
+		 "Infrared Remote Transceiver (%04x:%04x)",
+		 prod == USB_RR3IIUSB_PRODUCT_ID ? "-II" : "",
+		 le16_to_cpu(rr3->udev->descriptor.idVendor), prod);
+
+	usb_make_path(rr3->udev, rr3->phys, sizeof(rr3->phys));
+
+	rc->input_name = rr3->name;
+	rc->input_phys = rr3->phys;
+	usb_to_input_id(rr3->udev, &rc->input_id);
+	rc->dev.parent = dev;
+	rc->priv = rr3;
+	rc->driver_type = RC_DRIVER_IR_RAW;
+	rc->allowed_protos = RC_TYPE_ALL;
+	rc->min_timeout = MS_TO_NS(RR3_RX_MIN_TIMEOUT);
+	rc->max_timeout = MS_TO_NS(RR3_RX_MAX_TIMEOUT);
+	rc->timeout = redrat3_get_timeout(dev, rc, rr3->udev);
+	rc->tx_ir = redrat3_transmit_ir;
+	rc->s_tx_carrier = redrat3_set_tx_carrier;
+	rc->driver_name = DRIVER_NAME;
+	rc->map_name = RC_MAP_HAUPPAUGE;
+
+	ret = rc_register_device(rc);
+	if (ret < 0) {
+		dev_err(dev, "remote dev registration failed\n");
+		goto out;
+	}
+
+	return rc;
+
+out:
+	rc_free_device(rc);
+	return NULL;
+}
+
+static int __devinit redrat3_dev_probe(struct usb_interface *intf,
+				       const struct usb_device_id *id)
+{
+	struct usb_device *udev = interface_to_usbdev(intf);
+	struct device *dev = &intf->dev;
+	struct usb_host_interface *uhi;
+	struct redrat3_dev *rr3;
+	struct usb_endpoint_descriptor *ep;
+	struct usb_endpoint_descriptor *ep_in = NULL;
+	struct usb_endpoint_descriptor *ep_out = NULL;
+	u8 addr, attrs;
+	int pipe, i;
+	int retval = -ENOMEM;
+
+	rr3_ftr(dev, "%s called\n", __func__);
+
+	uhi = intf->cur_altsetting;
+
+	/* find our bulk-in and bulk-out endpoints */
+	for (i = 0; i < uhi->desc.bNumEndpoints; ++i) {
+		ep = &uhi->endpoint[i].desc;
+		addr = ep->bEndpointAddress;
+		attrs = ep->bmAttributes;
+
+		if ((ep_in == NULL) &&
+		    ((addr & USB_ENDPOINT_DIR_MASK) == USB_DIR_IN) &&
+		    ((attrs & USB_ENDPOINT_XFERTYPE_MASK) ==
+		     USB_ENDPOINT_XFER_BULK)) {
+			rr3_dbg(dev, "found bulk-in endpoint at 0x%02x\n",
+				ep->bEndpointAddress);
+			/* data comes in on 0x82, 0x81 is for other data... */
+			if (ep->bEndpointAddress == RR3_BULK_IN_EP_ADDR)
+				ep_in = ep;
+		}
+
+		if ((ep_out == NULL) &&
+		    ((addr & USB_ENDPOINT_DIR_MASK) == USB_DIR_OUT) &&
+		    ((attrs & USB_ENDPOINT_XFERTYPE_MASK) ==
+		     USB_ENDPOINT_XFER_BULK)) {
+			rr3_dbg(dev, "found bulk-out endpoint at 0x%02x\n",
+				ep->bEndpointAddress);
+			ep_out = ep;
+		}
+	}
+
+	if (!ep_in || !ep_out) {
+		dev_err(dev, "Couldn't find both in and out endpoints\n");
+		retval = -ENODEV;
+		goto no_endpoints;
+	}
+
+	/* allocate memory for our device state and initialize it */
+	rr3 = kzalloc(sizeof(*rr3), GFP_KERNEL);
+	if (rr3 == NULL) {
+		dev_err(dev, "Memory allocation failure\n");
+		goto error;
+	}
+
+	rr3->dev = &intf->dev;
+
+	/* set up bulk-in endpoint */
+	rr3->read_urb = usb_alloc_urb(0, GFP_KERNEL);
+	if (!rr3->read_urb) {
+		dev_err(dev, "Read urb allocation failure\n");
+		goto error;
+	}
+
+	rr3->ep_in = ep_in;
+	rr3->bulk_in_buf = usb_alloc_coherent(udev, ep_in->wMaxPacketSize,
+					      GFP_ATOMIC, &rr3->dma_in);
+	if (!rr3->bulk_in_buf) {
+		dev_err(dev, "Read buffer allocation failure\n");
+		goto error;
+	}
+
+	pipe = usb_rcvbulkpipe(udev, ep_in->bEndpointAddress);
+	usb_fill_bulk_urb(rr3->read_urb, udev, pipe,
+			  rr3->bulk_in_buf, ep_in->wMaxPacketSize,
+			  (usb_complete_t)redrat3_handle_async, rr3);
+
+	/* set up bulk-out endpoint*/
+	rr3->write_urb = usb_alloc_urb(0, GFP_KERNEL);
+	if (!rr3->write_urb) {
+		dev_err(dev, "Write urb allocation failure\n");
+		goto error;
+	}
+
+	rr3->ep_out = ep_out;
+	rr3->bulk_out_buf = usb_alloc_coherent(udev, ep_out->wMaxPacketSize,
+					       GFP_ATOMIC, &rr3->dma_out);
+	if (!rr3->bulk_out_buf) {
+		dev_err(dev, "Write buffer allocation failure\n");
+		goto error;
+	}
+
+	pipe = usb_sndbulkpipe(udev, ep_out->bEndpointAddress);
+	usb_fill_bulk_urb(rr3->write_urb, udev, pipe,
+			  rr3->bulk_out_buf, ep_out->wMaxPacketSize,
+			  (usb_complete_t)redrat3_write_bulk_callback, rr3);
+
+	mutex_init(&rr3->lock);
+	rr3->udev = udev;
+
+	redrat3_reset(rr3);
+	redrat3_get_firmware_rev(rr3);
+
+	/* might be all we need to do? */
+	retval = redrat3_enable_detector(rr3);
+	if (retval < 0)
+		goto error;
+
+	/* default.. will get overridden by any sends with a freq defined */
+	rr3->carrier = 38000;
+
+	rr3->rc = redrat3_init_rc_dev(rr3);
+	if (!rr3->rc)
+		goto error;
+
+	setup_timer(&rr3->rx_timeout, redrat3_rx_timeout, (unsigned long)rr3);
+
+	/* we can register the device now, as it is ready */
+	usb_set_intfdata(intf, rr3);
+
+	rr3_ftr(dev, "Exiting %s\n", __func__);
+	return 0;
+
+error:
+	redrat3_delete(rr3, rr3->udev);
+
+no_endpoints:
+	dev_err(dev, "%s: retval = %x", __func__, retval);
+
+	return retval;
+}
+
+static void __devexit redrat3_dev_disconnect(struct usb_interface *intf)
+{
+	struct usb_device *udev = interface_to_usbdev(intf);
+	struct redrat3_dev *rr3 = usb_get_intfdata(intf);
+
+	rr3_ftr(&intf->dev, "Entering %s\n", __func__);
+
+	if (!rr3)
+		return;
+
+	redrat3_disable_detector(rr3);
+
+	usb_set_intfdata(intf, NULL);
+	rc_unregister_device(rr3->rc);
+	redrat3_delete(rr3, udev);
+
+	rr3_ftr(&intf->dev, "RedRat3 IR Transceiver now disconnected\n");
+}
+
+static int redrat3_dev_suspend(struct usb_interface *intf, pm_message_t message)
+{
+	struct redrat3_dev *rr3 = usb_get_intfdata(intf);
+	rr3_ftr(rr3->dev, "suspend\n");
+	usb_kill_urb(rr3->read_urb);
+	return 0;
+}
+
+static int redrat3_dev_resume(struct usb_interface *intf)
+{
+	struct redrat3_dev *rr3 = usb_get_intfdata(intf);
+	rr3_ftr(rr3->dev, "resume\n");
+	if (usb_submit_urb(rr3->read_urb, GFP_ATOMIC))
+		return -EIO;
+	return 0;
+}
+
+static struct usb_driver redrat3_dev_driver = {
+	.name		= DRIVER_NAME,
+	.probe		= redrat3_dev_probe,
+	.disconnect	= redrat3_dev_disconnect,
+	.suspend	= redrat3_dev_suspend,
+	.resume		= redrat3_dev_resume,
+	.reset_resume	= redrat3_dev_resume,
+	.id_table	= redrat3_dev_table
+};
+
+static int __init redrat3_dev_init(void)
+{
+	int ret;
+
+	ret = usb_register(&redrat3_dev_driver);
+	if (ret < 0)
+		pr_err(DRIVER_NAME
+		       ": usb register failed, result = %d\n", ret);
+
+	return ret;
+}
+
+static void __exit redrat3_dev_exit(void)
+{
+	usb_deregister(&redrat3_dev_driver);
+}
+
+module_init(redrat3_dev_init);
+module_exit(redrat3_dev_exit);
+
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_AUTHOR(DRIVER_AUTHOR2);
+MODULE_LICENSE("GPL");
+MODULE_DEVICE_TABLE(usb, redrat3_dev_table);
+
+module_param(debug, int, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(debug, "Enable module debug spew. 0 = no debugging (default) "
+		 "0x1 = standard debug messages, 0x2 = function tracing debug. "
+		 "Flag bits are addative (i.e., 0x3 for both debug types).");
diff -druN linux-2.6.39-libre/drivers/media/rc/winbond-cir.c linux-3.0-rc7-libre/drivers/media/rc/winbond-cir.c
--- linux-2.6.39-libre/drivers/media/rc/winbond-cir.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/rc/winbond-cir.c	2011-07-11 19:51:52.000000000 -0400
@@ -19,11 +19,12 @@
  *    o DSDT dumps
  *
  *  Supported features:
+ *    o IR Receive
+ *    o IR Transmit
  *    o Wake-On-CIR functionality
  *
  *  To do:
  *    o Learning
- *    o IR Transmit
  *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
@@ -50,6 +51,8 @@
 #include <linux/io.h>
 #include <linux/bitrev.h>
 #include <linux/slab.h>
+#include <linux/wait.h>
+#include <linux/sched.h>
 #include <media/rc-core.h>
 
 #define DRVNAME "winbond-cir"
@@ -118,14 +121,24 @@
 #define WBCIR_IRQ_NONE		0x00
 /* RX data bit for WBCIR_REG_SP3_IER and WBCIR_REG_SP3_EIR */
 #define WBCIR_IRQ_RX		0x01
+/* TX data low bit for WBCIR_REG_SP3_IER and WBCIR_REG_SP3_EIR */
+#define WBCIR_IRQ_TX_LOW	0x02
 /* Over/Under-flow bit for WBCIR_REG_SP3_IER and WBCIR_REG_SP3_EIR */
 #define WBCIR_IRQ_ERR		0x04
+/* TX data empty bit for WBCEIR_REG_SP3_IER and WBCIR_REG_SP3_EIR */
+#define WBCIR_IRQ_TX_EMPTY	0x20
 /* Led enable/disable bit for WBCIR_REG_ECEIR_CTS */
 #define WBCIR_LED_ENABLE	0x80
 /* RX data available bit for WBCIR_REG_SP3_LSR */
 #define WBCIR_RX_AVAIL		0x01
+/* RX data overrun error bit for WBCIR_REG_SP3_LSR */
+#define WBCIR_RX_OVERRUN	0x02
+/* TX End-Of-Transmission bit for WBCIR_REG_SP3_ASCR */
+#define WBCIR_TX_EOT		0x04
 /* RX disable bit for WBCIR_REG_SP3_ASCR */
 #define WBCIR_RX_DISABLE	0x20
+/* TX data underrun error bit for WBCIR_REG_SP3_ASCR */
+#define WBCIR_TX_UNDERRUN	0x40
 /* Extended mode enable bit for WBCIR_REG_SP3_EXCR1 */
 #define WBCIR_EXT_ENABLE	0x01
 /* Select compare register in WBCIR_REG_WCEIR_INDEX (bits 5 & 6) */
@@ -154,6 +167,21 @@
 	IR_PROTOCOL_RC6          = 0x2,
 };
 
+/* Possible states for IR reception */
+enum wbcir_rxstate {
+	WBCIR_RXSTATE_INACTIVE = 0,
+	WBCIR_RXSTATE_ACTIVE,
+	WBCIR_RXSTATE_ERROR
+};
+
+/* Possible states for IR transmission */
+enum wbcir_txstate {
+	WBCIR_TXSTATE_INACTIVE = 0,
+	WBCIR_TXSTATE_ACTIVE,
+	WBCIR_TXSTATE_DONE,
+	WBCIR_TXSTATE_ERROR
+};
+
 /* Misc */
 #define WBCIR_NAME	"Winbond CIR"
 #define WBCIR_ID_FAMILY          0xF1 /* Family ID for the WPCD376I	*/
@@ -166,22 +194,29 @@
 /* Per-device data */
 struct wbcir_data {
 	spinlock_t spinlock;
+	struct rc_dev *dev;
+	struct led_classdev led;
 
 	unsigned long wbase;        /* Wake-Up Baseaddr		*/
 	unsigned long ebase;        /* Enhanced Func. Baseaddr	*/
 	unsigned long sbase;        /* Serial Port Baseaddr	*/
 	unsigned int  irq;          /* Serial Port IRQ		*/
+	u8 irqmask;
 
-	struct rc_dev *dev;
-
+	/* RX state */
+	enum wbcir_rxstate rxstate;
 	struct led_trigger *rxtrigger;
-	struct led_trigger *txtrigger;
-	struct led_classdev led;
+	struct ir_raw_event rxev;
 
-	/* RX irdata state */
-	bool irdata_active;
-	bool irdata_error;
-	struct ir_raw_event ev;
+	/* TX state */
+	enum wbcir_txstate txstate;
+	struct led_trigger *txtrigger;
+	u32 txlen;
+	u32 txoff;
+	u32 *txbuf;
+	wait_queue_head_t txwaitq;
+	u8 txmask;
+	u32 txcarrier;
 };
 
 static enum wbcir_protocol protocol = IR_PROTOCOL_RC6;
@@ -193,6 +228,10 @@
 module_param(invert, bool, 0444);
 MODULE_PARM_DESC(invert, "Invert the signal from the IR receiver");
 
+static int txandrx; /* default = 0 */
+module_param(txandrx, bool, 0444);
+MODULE_PARM_DESC(invert, "Allow simultaneous TX and RX");
+
 static unsigned int wake_sc = 0x800F040C;
 module_param(wake_sc, uint, 0644);
 MODULE_PARM_DESC(wake_sc, "Scancode of the power-on IR command");
@@ -228,6 +267,17 @@
 	outb(bank, data->sbase + WBCIR_REG_SP3_BSR);
 }
 
+static inline void
+wbcir_set_irqmask(struct wbcir_data *data, u8 irqmask)
+{
+	if (data->irqmask == irqmask)
+		return;
+
+	wbcir_select_bank(data, WBCIR_BANK_0);
+	outb(irqmask, data->sbase + WBCIR_REG_SP3_IER);
+	data->irqmask = irqmask;
+}
+
 static enum led_brightness
 wbcir_led_brightness_get(struct led_classdev *led_cdev)
 {
@@ -279,97 +329,297 @@
  *
  *****************************************************************************/
 
+static void
+wbcir_idle_rx(struct rc_dev *dev, bool idle)
+{
+	struct wbcir_data *data = dev->priv;
+
+	if (!idle && data->rxstate == WBCIR_RXSTATE_INACTIVE) {
+		data->rxstate = WBCIR_RXSTATE_ACTIVE;
+		led_trigger_event(data->rxtrigger, LED_FULL);
+	}
+
+	if (idle && data->rxstate != WBCIR_RXSTATE_INACTIVE)
+		/* Tell hardware to go idle by setting RXINACTIVE */
+		outb(WBCIR_RX_DISABLE, data->sbase + WBCIR_REG_SP3_ASCR);
+}
+
+static void
+wbcir_irq_rx(struct wbcir_data *data, struct pnp_dev *device)
+{
+	u8 irdata;
+	DEFINE_IR_RAW_EVENT(rawir);
+
+	/* Since RXHDLEV is set, at least 8 bytes are in the FIFO */
+	while (inb(data->sbase + WBCIR_REG_SP3_LSR) & WBCIR_RX_AVAIL) {
+		irdata = inb(data->sbase + WBCIR_REG_SP3_RXDATA);
+		if (data->rxstate == WBCIR_RXSTATE_ERROR)
+			continue;
+		rawir.pulse = irdata & 0x80 ? false : true;
+		rawir.duration = US_TO_NS((irdata & 0x7F) * 10);
+		ir_raw_event_store_with_filter(data->dev, &rawir);
+	}
+
+	/* Check if we should go idle */
+	if (data->dev->idle) {
+		led_trigger_event(data->rxtrigger, LED_OFF);
+		data->rxstate = WBCIR_RXSTATE_INACTIVE;
+	}
+
+	ir_raw_event_handle(data->dev);
+}
+
+static void
+wbcir_irq_tx(struct wbcir_data *data)
+{
+	unsigned int space;
+	unsigned int used;
+	u8 bytes[16];
+	u8 byte;
+
+	if (!data->txbuf)
+		return;
+
+	switch (data->txstate) {
+	case WBCIR_TXSTATE_INACTIVE:
+		/* TX FIFO empty */
+		space = 16;
+		led_trigger_event(data->txtrigger, LED_FULL);
+		break;
+	case WBCIR_TXSTATE_ACTIVE:
+		/* TX FIFO low (3 bytes or less) */
+		space = 13;
+		break;
+	case WBCIR_TXSTATE_ERROR:
+		space = 0;
+		break;
+	default:
+		return;
+	}
+
+	/*
+	 * TX data is run-length coded in bytes: YXXXXXXX
+	 * Y = space (1) or pulse (0)
+	 * X = duration, encoded as (X + 1) * 10us (i.e 10 to 1280 us)
+	 */
+	for (used = 0; used < space && data->txoff != data->txlen; used++) {
+		if (data->txbuf[data->txoff] == 0) {
+			data->txoff++;
+			continue;
+		}
+		byte = min((u32)0x80, data->txbuf[data->txoff]);
+		data->txbuf[data->txoff] -= byte;
+		byte--;
+		byte |= (data->txoff % 2 ? 0x80 : 0x00); /* pulse/space */
+		bytes[used] = byte;
+	}
+
+	while (data->txbuf[data->txoff] == 0 && data->txoff != data->txlen)
+		data->txoff++;
+
+	if (used == 0) {
+		/* Finished */
+		if (data->txstate == WBCIR_TXSTATE_ERROR)
+			/* Clear TX underrun bit */
+			outb(WBCIR_TX_UNDERRUN, data->sbase + WBCIR_REG_SP3_ASCR);
+		else
+			data->txstate = WBCIR_TXSTATE_DONE;
+		wbcir_set_irqmask(data, WBCIR_IRQ_RX | WBCIR_IRQ_ERR);
+		led_trigger_event(data->txtrigger, LED_OFF);
+		wake_up(&data->txwaitq);
+	} else if (data->txoff == data->txlen) {
+		/* At the end of transmission, tell the hw before last byte */
+		outsb(data->sbase + WBCIR_REG_SP3_TXDATA, bytes, used - 1);
+		outb(WBCIR_TX_EOT, data->sbase + WBCIR_REG_SP3_ASCR);
+		outb(bytes[used - 1], data->sbase + WBCIR_REG_SP3_TXDATA);
+		wbcir_set_irqmask(data, WBCIR_IRQ_RX | WBCIR_IRQ_ERR |
+				  WBCIR_IRQ_TX_EMPTY);
+	} else {
+		/* More data to follow... */
+		outsb(data->sbase + WBCIR_REG_SP3_RXDATA, bytes, used);
+		if (data->txstate == WBCIR_TXSTATE_INACTIVE) {
+			wbcir_set_irqmask(data, WBCIR_IRQ_RX | WBCIR_IRQ_ERR |
+					  WBCIR_IRQ_TX_LOW);
+			data->txstate = WBCIR_TXSTATE_ACTIVE;
+		}
+	}
+}
+
 static irqreturn_t
 wbcir_irq_handler(int irqno, void *cookie)
 {
 	struct pnp_dev *device = cookie;
 	struct wbcir_data *data = pnp_get_drvdata(device);
 	unsigned long flags;
-	u8 irdata[8];
-	u8 disable = true;
 	u8 status;
-	int i;
 
 	spin_lock_irqsave(&data->spinlock, flags);
-
 	wbcir_select_bank(data, WBCIR_BANK_0);
-
 	status = inb(data->sbase + WBCIR_REG_SP3_EIR);
+	status &= data->irqmask;
 
-	if (!(status & (WBCIR_IRQ_RX | WBCIR_IRQ_ERR))) {
+	if (!status) {
 		spin_unlock_irqrestore(&data->spinlock, flags);
 		return IRQ_NONE;
 	}
 
-	/* Check for e.g. buffer overflow */
 	if (status & WBCIR_IRQ_ERR) {
-		data->irdata_error = true;
-		ir_raw_event_reset(data->dev);
-	}
-
-	if (!(status & WBCIR_IRQ_RX))
-		goto out;
+		/* RX overflow? (read clears bit) */
+		if (inb(data->sbase + WBCIR_REG_SP3_LSR) & WBCIR_RX_OVERRUN) {
+			data->rxstate = WBCIR_RXSTATE_ERROR;
+			ir_raw_event_reset(data->dev);
+		}
 
-	if (!data->irdata_active) {
-		data->irdata_active = true;
-		led_trigger_event(data->rxtrigger, LED_FULL);
+		/* TX underflow? */
+		if (inb(data->sbase + WBCIR_REG_SP3_ASCR) & WBCIR_TX_UNDERRUN)
+			data->txstate = WBCIR_TXSTATE_ERROR;
 	}
 
-	/* Since RXHDLEV is set, at least 8 bytes are in the FIFO */
-	insb(data->sbase + WBCIR_REG_SP3_RXDATA, &irdata[0], 8);
+	if (status & WBCIR_IRQ_RX)
+		wbcir_irq_rx(data, device);
 
-	for (i = 0; i < 8; i++) {
-		u8 pulse;
-		u32 duration;
+	if (status & (WBCIR_IRQ_TX_LOW | WBCIR_IRQ_TX_EMPTY))
+		wbcir_irq_tx(data);
 
-		if (irdata[i] != 0xFF && irdata[i] != 0x00)
-			disable = false;
+	spin_unlock_irqrestore(&data->spinlock, flags);
+	return IRQ_HANDLED;
+}
 
-		if (data->irdata_error)
-			continue;
+/*****************************************************************************
+ *
+ * RC-CORE INTERFACE FUNCTIONS
+ *
+ *****************************************************************************/
 
-		pulse = irdata[i] & 0x80 ? false : true;
-		duration = (irdata[i] & 0x7F) * 10000; /* ns */
+static int
+wbcir_txcarrier(struct rc_dev *dev, u32 carrier)
+{
+	struct wbcir_data *data = dev->priv;
+	unsigned long flags;
+	u8 val;
+	u32 freq;
 
-		if (data->ev.pulse != pulse) {
-			if (data->ev.duration != 0) {
-				ir_raw_event_store(data->dev, &data->ev);
-				data->ev.duration = 0;
-			}
+	freq = DIV_ROUND_CLOSEST(carrier, 1000);
+	if (freq < 30 || freq > 60)
+		return -EINVAL;
 
-			data->ev.pulse = pulse;
-		}
+	switch (freq) {
+	case 58:
+	case 59:
+	case 60:
+		val = freq - 58;
+		freq *= 1000;
+		break;
+	case 57:
+		val = freq - 27;
+		freq = 56900;
+		break;
+	default:
+		val = freq - 27;
+		freq *= 1000;
+		break;
+	}
 
-		data->ev.duration += duration;
+	spin_lock_irqsave(&data->spinlock, flags);
+	if (data->txstate != WBCIR_TXSTATE_INACTIVE) {
+		spin_unlock_irqrestore(&data->spinlock, flags);
+		return -EBUSY;
 	}
 
-	if (disable) {
-		if (data->ev.duration != 0 && !data->irdata_error) {
-			ir_raw_event_store(data->dev, &data->ev);
-			data->ev.duration = 0;
-		}
+	if (data->txcarrier != freq) {
+		wbcir_select_bank(data, WBCIR_BANK_7);
+		wbcir_set_bits(data->sbase + WBCIR_REG_SP3_IRTXMC, val, 0x1F);
+		data->txcarrier = freq;
+	}
 
-		/* Set RXINACTIVE */
-		outb(WBCIR_RX_DISABLE, data->sbase + WBCIR_REG_SP3_ASCR);
+	spin_unlock_irqrestore(&data->spinlock, flags);
+	return 0;
+}
 
-		/* Drain the FIFO */
-		while (inb(data->sbase + WBCIR_REG_SP3_LSR) & WBCIR_RX_AVAIL)
-			inb(data->sbase + WBCIR_REG_SP3_RXDATA);
+static int
+wbcir_txmask(struct rc_dev *dev, u32 mask)
+{
+	struct wbcir_data *data = dev->priv;
+	unsigned long flags;
+	u8 val;
 
-		ir_raw_event_reset(data->dev);
-		data->irdata_error = false;
-		data->irdata_active = false;
-		led_trigger_event(data->rxtrigger, LED_OFF);
+	/* Four outputs, only one output can be enabled at a time */
+	switch (mask) {
+	case 0x1:
+		val = 0x0;
+		break;
+	case 0x2:
+		val = 0x1;
+		break;
+	case 0x4:
+		val = 0x2;
+		break;
+	case 0x8:
+		val = 0x3;
+		break;
+	default:
+		return -EINVAL;
 	}
 
-	ir_raw_event_handle(data->dev);
+	spin_lock_irqsave(&data->spinlock, flags);
+	if (data->txstate != WBCIR_TXSTATE_INACTIVE) {
+		spin_unlock_irqrestore(&data->spinlock, flags);
+		return -EBUSY;
+	}
+
+	if (data->txmask != mask) {
+		wbcir_set_bits(data->ebase + WBCIR_REG_ECEIR_CTS, val, 0x0c);
+		data->txmask = mask;
+	}
 
-out:
 	spin_unlock_irqrestore(&data->spinlock, flags);
-	return IRQ_HANDLED;
+	return 0;
 }
 
+static int
+wbcir_tx(struct rc_dev *dev, int *buf, u32 bufsize)
+{
+	struct wbcir_data *data = dev->priv;
+	u32 count;
+	unsigned i;
+	unsigned long flags;
+
+	/* bufsize has been sanity checked by the caller */
+	count = bufsize / sizeof(int);
+
+	/* Not sure if this is possible, but better safe than sorry */
+	spin_lock_irqsave(&data->spinlock, flags);
+	if (data->txstate != WBCIR_TXSTATE_INACTIVE) {
+		spin_unlock_irqrestore(&data->spinlock, flags);
+		return -EBUSY;
+	}
+
+	/* Convert values to multiples of 10us */
+	for (i = 0; i < count; i++)
+		buf[i] = DIV_ROUND_CLOSEST(buf[i], 10);
+
+	/* Fill the TX fifo once, the irq handler will do the rest */
+	data->txbuf = buf;
+	data->txlen = count;
+	data->txoff = 0;
+	wbcir_irq_tx(data);
+
+	/* Wait for the TX to complete */
+	while (data->txstate == WBCIR_TXSTATE_ACTIVE) {
+		spin_unlock_irqrestore(&data->spinlock, flags);
+		wait_event(data->txwaitq, data->txstate != WBCIR_TXSTATE_ACTIVE);
+		spin_lock_irqsave(&data->spinlock, flags);
+	}
+
+	/* We're done */
+	if (data->txstate == WBCIR_TXSTATE_ERROR)
+		count = -EAGAIN;
+	data->txstate = WBCIR_TXSTATE_INACTIVE;
+	data->txbuf = NULL;
+	spin_unlock_irqrestore(&data->spinlock, flags);
 
+	return count;
+}
 
 /*****************************************************************************
  *
@@ -382,7 +632,7 @@
 {
 	struct device *dev = &device->dev;
 	struct wbcir_data *data = pnp_get_drvdata(device);
-	int do_wake = 1;
+	bool do_wake = true;
 	u8 match[11];
 	u8 mask[11];
 	u8 rc6_csl = 0;
@@ -392,14 +642,14 @@
 	memset(mask, 0, sizeof(mask));
 
 	if (wake_sc == INVALID_SCANCODE || !device_may_wakeup(dev)) {
-		do_wake = 0;
+		do_wake = false;
 		goto finish;
 	}
 
 	switch (protocol) {
 	case IR_PROTOCOL_RC5:
 		if (wake_sc > 0xFFF) {
-			do_wake = 0;
+			do_wake = false;
 			dev_err(dev, "RC5 - Invalid wake scancode\n");
 			break;
 		}
@@ -418,7 +668,7 @@
 
 	case IR_PROTOCOL_NEC:
 		if (wake_sc > 0xFFFFFF) {
-			do_wake = 0;
+			do_wake = false;
 			dev_err(dev, "NEC - Invalid wake scancode\n");
 			break;
 		}
@@ -440,7 +690,7 @@
 
 		if (wake_rc6mode == 0) {
 			if (wake_sc > 0xFFFF) {
-				do_wake = 0;
+				do_wake = false;
 				dev_err(dev, "RC6 - Invalid wake scancode\n");
 				break;
 			}
@@ -496,7 +746,7 @@
 			} else if (wake_sc <= 0x007FFFFF) {
 				rc6_csl = 60;
 			} else {
-				do_wake = 0;
+				do_wake = false;
 				dev_err(dev, "RC6 - Invalid wake scancode\n");
 				break;
 			}
@@ -508,14 +758,14 @@
 			mask[i++] = 0x0F;
 
 		} else {
-			do_wake = 0;
+			do_wake = false;
 			dev_err(dev, "RC6 - Invalid wake mode\n");
 		}
 
 		break;
 
 	default:
-		do_wake = 0;
+		do_wake = false;
 		break;
 	}
 
@@ -551,21 +801,18 @@
 		wbcir_set_bits(data->wbase + WBCIR_REG_WCEIR_CTL, 0x00, 0x01);
 	}
 
-	/* Disable interrupts */
-	wbcir_select_bank(data, WBCIR_BANK_0);
-	outb(WBCIR_IRQ_NONE, data->sbase + WBCIR_REG_SP3_IER);
-
-	/* Disable LED */
-	data->irdata_active = false;
-	led_trigger_event(data->rxtrigger, LED_OFF);
-
 	/*
 	 * 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.
 	 */
+	wbcir_set_irqmask(data, WBCIR_IRQ_NONE);
 	disable_irq(data->irq);
+
+	/* Disable LED */
+	led_trigger_event(data->rxtrigger, LED_OFF);
+	led_trigger_event(data->txtrigger, LED_OFF);
 }
 
 static int
@@ -581,8 +828,7 @@
 	u8 tmp;
 
 	/* Disable interrupts */
-	wbcir_select_bank(data, WBCIR_BANK_0);
-	outb(WBCIR_IRQ_NONE, data->sbase + WBCIR_REG_SP3_IER);
+	wbcir_set_irqmask(data, WBCIR_IRQ_NONE);
 
 	/* Set PROT_SEL, RX_INV, Clear CEIR_EN (needed for the led) */
 	tmp = protocol << 4;
@@ -606,10 +852,11 @@
 		outb(0x00, data->ebase + WBCIR_REG_ECEIR_CCTL);
 
 	/*
-	 * Clear IR LED, set SP3 clock to 24Mhz
+	 * Clear IR LED, set SP3 clock to 24Mhz, set TX mask to IRTX1,
 	 * set SP3_IRRX_SW to binary 01, helpfully not documented
 	 */
 	outb(0x10, data->ebase + WBCIR_REG_ECEIR_CTS);
+	data->txmask = 0x1;
 
 	/* Enable extended mode */
 	wbcir_select_bank(data, WBCIR_BANK_2);
@@ -657,18 +904,21 @@
 	wbcir_select_bank(data, WBCIR_BANK_4);
 	outb(0x00, data->sbase + WBCIR_REG_SP3_IRCR1);
 
-	/* Enable MSR interrupt, Clear AUX_IRX */
+	/* Disable MSR interrupt, clear AUX_IRX, mask RX during TX? */
 	wbcir_select_bank(data, WBCIR_BANK_5);
-	outb(0x00, data->sbase + WBCIR_REG_SP3_IRCR2);
+	outb(txandrx ? 0x03 : 0x02, 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 */
+	/* Set RX demodulation freq, not really used */
 	wbcir_select_bank(data, WBCIR_BANK_7);
 	outb(0xF2, data->sbase + WBCIR_REG_SP3_IRRXDC);
+
+	/* Set TX modulation, 36kHz, 7us pulse width */
 	outb(0x69, data->sbase + WBCIR_REG_SP3_IRTXMC);
+	data->txcarrier = 36000;
 
 	/* Set invert and pin direction */
 	if (invert)
@@ -683,16 +933,23 @@
 	/* Clear AUX status bits */
 	outb(0xE0, data->sbase + WBCIR_REG_SP3_ASCR);
 
-	/* Clear IR decoding state */
-	data->irdata_active = false;
-	led_trigger_event(data->rxtrigger, LED_OFF);
-	data->irdata_error = false;
-	data->ev.duration = 0;
+	/* Clear RX state */
+	data->rxstate = WBCIR_RXSTATE_INACTIVE;
+	data->rxev.duration = 0;
 	ir_raw_event_reset(data->dev);
 	ir_raw_event_handle(data->dev);
 
+	/*
+	 * Check TX state, if we did a suspend/resume cycle while TX was
+	 * active, we will have a process waiting in txwaitq.
+	 */
+	if (data->txstate == WBCIR_TXSTATE_ACTIVE) {
+		data->txstate = WBCIR_TXSTATE_ERROR;
+		wake_up(&data->txwaitq);
+	}
+
 	/* Enable interrupts */
-	outb(WBCIR_IRQ_RX | WBCIR_IRQ_ERR, data->sbase + WBCIR_REG_SP3_IER);
+	wbcir_set_irqmask(data, WBCIR_IRQ_RX | WBCIR_IRQ_ERR);
 }
 
 static int
@@ -729,6 +986,7 @@
 	pnp_set_drvdata(device, data);
 
 	spin_lock_init(&data->spinlock);
+	init_waitqueue_head(&data->txwaitq);
 	data->ebase = pnp_port_start(device, 0);
 	data->wbase = pnp_port_start(device, 1);
 	data->sbase = pnp_port_start(device, 2);
@@ -807,6 +1065,11 @@
 	data->dev->input_id.vendor = PCI_VENDOR_ID_WINBOND;
 	data->dev->input_id.product = WBCIR_ID_FAMILY;
 	data->dev->input_id.version = WBCIR_ID_CHIP;
+	data->dev->map_name = RC_MAP_RC6_MCE;
+	data->dev->s_idle = wbcir_idle_rx;
+	data->dev->s_tx_mask = wbcir_txmask;
+	data->dev->s_tx_carrier = wbcir_txcarrier;
+	data->dev->tx_ir = wbcir_tx;
 	data->dev->priv = data;
 	data->dev->dev.parent = &device->dev;
 
@@ -849,9 +1112,7 @@
 	struct wbcir_data *data = pnp_get_drvdata(device);
 
 	/* Disable interrupts */
-	wbcir_select_bank(data, WBCIR_BANK_0);
-	outb(WBCIR_IRQ_NONE, data->sbase + WBCIR_REG_SP3_IER);
-
+	wbcir_set_irqmask(data, WBCIR_IRQ_NONE);
 	free_irq(data->irq, device);
 
 	/* Clear status bits NEC_REP, BUFF, MSG_END, MATCH */
diff -druN linux-2.6.39-libre/drivers/media/video/bt8xx/bttv-driver.c linux-3.0-rc7-libre/drivers/media/video/bt8xx/bttv-driver.c
--- linux-2.6.39-libre/drivers/media/video/bt8xx/bttv-driver.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/video/bt8xx/bttv-driver.c	2011-07-11 19:51:52.000000000 -0400
@@ -3474,7 +3474,7 @@
 	if (0 != t->index)
 		return -EINVAL;
 
-	bttv_call_all(btv, tuner, g_tuner, t);
+	bttv_call_all(btv, tuner, s_tuner, t);
 	return 0;
 }
 
@@ -4303,7 +4303,7 @@
 		goto fail0;
 	}
 
-	pci_read_config_byte(dev, PCI_CLASS_REVISION, &btv->revision);
+	btv->revision = dev->revision;
 	pci_read_config_byte(dev, PCI_LATENCY_TIMER, &lat);
 	printk(KERN_INFO "bttv%d: Bt%d (rev %d) at %s, ",
 	       bttv_num,btv->id, btv->revision, pci_name(dev));
diff -druN linux-2.6.39-libre/drivers/media/video/cpia2/cpia2_v4l.c linux-3.0-rc7-libre/drivers/media/video/cpia2/cpia2_v4l.c
--- linux-2.6.39-libre/drivers/media/video/cpia2/cpia2_v4l.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/video/cpia2/cpia2_v4l.c	2011-07-11 19:51:52.000000000 -0400
@@ -438,7 +438,7 @@
 		strcat(vc->card, " (676/");
 		break;
 	default:
-		strcat(vc->card, " (???/");
+		strcat(vc->card, " (XXX/");
 		break;
 	}
 	switch (cam->params.version.sensor_flags) {
@@ -458,7 +458,7 @@
 		strcat(vc->card, "500)");
 		break;
 	default:
-		strcat(vc->card, "???)");
+		strcat(vc->card, "XXX)");
 		break;
 	}
 
@@ -1313,7 +1313,7 @@
 static int cpia2_s_priority(struct file *file, void *_fh, enum v4l2_priority prio)
 {
 	struct camera_data *cam = video_drvdata(file);
-	struct cpia2_fh *fh = fh;
+	struct cpia2_fh *fh = _fh;
 
 	if (cam->streaming && prio != fh->prio &&
 			fh->prio == V4L2_PRIORITY_RECORD)
diff -druN linux-2.6.39-libre/drivers/media/video/cx18/cx18-cards.c linux-3.0-rc7-libre/drivers/media/video/cx18/cx18-cards.c
--- linux-2.6.39-libre/drivers/media/video/cx18/cx18-cards.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/video/cx18/cx18-cards.c	2011-07-11 19:51:52.000000000 -0400
@@ -39,6 +39,16 @@
 	.tv    = { 0x61, 0x60, I2C_CLIENT_END },
 };
 
+/*
+ * usual i2c tuner addresses to probe with additional demod address for
+ * an NXP TDA8295 at 0x42 (N.B. it can possibly be at 0x4b or 0x4c too).
+ */
+static struct cx18_card_tuner_i2c cx18_i2c_nxp = {
+	.radio = { I2C_CLIENT_END },
+	.demod = { 0x42, 0x43, I2C_CLIENT_END },
+	.tv    = { 0x61, 0x60, I2C_CLIENT_END },
+};
+
 /* Please add new PCI IDs to: http://pci-ids.ucw.cz/
    This keeps the PCI ID database up to date. Note that the entries
    must be added under vendor 0x4444 (Conexant) as subsystem IDs.
@@ -131,15 +141,15 @@
 		.tune_lane = 0,
 		.initial_emrs = 0,
 	},
-	.gpio_init.initial_value = 0x3001,
-	.gpio_init.direction = 0x3001,
+	.gpio_init.initial_value = 0x3801,
+	.gpio_init.direction = 0x3801,
 	.gpio_i2c_slave_reset = {
-		.active_lo_mask = 0x3001,
+		.active_lo_mask = 0x3801,
 		.msecs_asserted = 10,
 		.msecs_recovery = 40,
 		.ir_reset_mask  = 0x0001,
 	},
-	.i2c = &cx18_i2c_std,
+	.i2c = &cx18_i2c_nxp,
 };
 
 static const struct cx18_card cx18_card_hvr1600_samsung = {
diff -druN linux-2.6.39-libre/drivers/media/video/cx18/cx18-cards.h linux-3.0-rc7-libre/drivers/media/video/cx18/cx18-cards.h
--- linux-2.6.39-libre/drivers/media/video/cx18/cx18-cards.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/video/cx18/cx18-cards.h	2011-07-11 19:51:52.000000000 -0400
@@ -109,7 +109,7 @@
 
 struct cx18_card_tuner_i2c {
 	unsigned short radio[2];/* radio tuner i2c address to probe */
-	unsigned short demod[2];/* demodulator i2c address to probe */
+	unsigned short demod[3];/* demodulator i2c address to probe */
 	unsigned short tv[4];	/* tv tuner i2c addresses to probe */
 };
 
diff -druN linux-2.6.39-libre/drivers/media/video/cx18/cx18-driver.c linux-3.0-rc7-libre/drivers/media/video/cx18/cx18-driver.c
--- linux-2.6.39-libre/drivers/media/video/cx18/cx18-driver.c	2011-05-19 02:08:16.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/video/cx18/cx18-driver.c	2011-07-21 06:50:33.000000000 -0400
@@ -423,7 +423,16 @@
 		return;
 
 	/* autodetect tuner standard */
-	if (tv.tuner_formats & V4L2_STD_PAL) {
+#define TVEEPROM_TUNER_FORMAT_ALL (V4L2_STD_B  | V4L2_STD_GH | \
+				   V4L2_STD_MN | \
+				   V4L2_STD_PAL_I | \
+				   V4L2_STD_SECAM_L | V4L2_STD_SECAM_LC | \
+				   V4L2_STD_DK)
+	if ((tv.tuner_formats & TVEEPROM_TUNER_FORMAT_ALL)
+					== TVEEPROM_TUNER_FORMAT_ALL) {
+		CX18_DEBUG_INFO("Worldwide tuner detected\n");
+		cx->std = V4L2_STD_ALL;
+	} else if (tv.tuner_formats & V4L2_STD_PAL) {
 		CX18_DEBUG_INFO("PAL tuner detected\n");
 		cx->std |= V4L2_STD_PAL_BG | V4L2_STD_PAL_H;
 	} else if (tv.tuner_formats & V4L2_STD_NTSC) {
@@ -818,7 +827,7 @@
 	cmd |= PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER;
 	pci_write_config_word(pci_dev, PCI_COMMAND, cmd);
 
-	pci_read_config_byte(pci_dev, PCI_CLASS_REVISION, &cx->card_rev);
+	cx->card_rev = pci_dev->revision;
 	pci_read_config_byte(pci_dev, PCI_LATENCY_TIMER, &pci_latency);
 
 	if (pci_latency < 64 && cx18_pci_latency) {
@@ -1001,7 +1010,15 @@
 	if (cx->card->hw_all & CX18_HW_TVEEPROM) {
 		/* Based on the model number the cardtype may be changed.
 		   The PCI IDs are not always reliable. */
+		const struct cx18_card *orig_card = cx->card;
 		cx18_process_eeprom(cx);
+
+		if (cx->card != orig_card) {
+			/* Changed the cardtype; re-reset the I2C chips */
+			cx18_gpio_init(cx);
+			cx18_call_hw(cx, CX18_HW_GPIO_RESET_CTRL,
+					core, reset, (u32) CX18_GPIO_RESET_I2C);
+		}
 	}
 	if (cx->card->comment)
 		CX18_INFO("%s", cx->card->comment);
@@ -1087,6 +1104,8 @@
 	/* The tuner is fixed to the standard. The other inputs (e.g. S-Video)
 	   are not. */
 	cx->tuner_std = cx->std;
+	if (cx->std == V4L2_STD_ALL)
+		cx->std = V4L2_STD_NTSC_M;
 
 	retval = cx18_streams_setup(cx);
 	if (retval) {
@@ -1133,6 +1152,7 @@
 	int fw_retry_count = 3;
 	struct v4l2_frequency vf;
 	struct cx18_open_id fh;
+	v4l2_std_id std;
 
 	fh.cx = cx;
 
@@ -1220,7 +1240,8 @@
 	/* Let the VIDIOC_S_STD ioctl do all the work, keeps the code
 	   in one place. */
 	cx->std++;		/* Force full standard initialization */
-	cx18_s_std(NULL, &fh, &cx->tuner_std);
+	std = (cx->tuner_std == V4L2_STD_ALL) ? V4L2_STD_NTSC_M : cx->tuner_std;
+	cx18_s_std(NULL, &fh, &std);
 	cx18_s_frequency(NULL, &fh, &vf);
 	return 0;
 }
diff -druN linux-2.6.39-libre/drivers/media/video/cx18/cx18-driver.h linux-3.0-rc7-libre/drivers/media/video/cx18/cx18-driver.h
--- linux-2.6.39-libre/drivers/media/video/cx18/cx18-driver.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/video/cx18/cx18-driver.h	2011-07-11 19:51:52.000000000 -0400
@@ -65,6 +65,10 @@
 #include "dvb_net.h"
 #include "dvbdev.h"
 
+/* Videobuf / YUV support */
+#include <media/videobuf-core.h>
+#include <media/videobuf-vmalloc.h>
+
 #ifndef CONFIG_PCI
 #  error "This driver requires kernel PCI support."
 #endif
@@ -403,6 +407,23 @@
 	struct cx18_queue q_idle;	/* idle - not in rotation */
 
 	struct work_struct out_work_order;
+
+	/* Videobuf for YUV video */
+	u32 pixelformat;
+	struct list_head vb_capture;    /* video capture queue */
+	spinlock_t vb_lock;
+	struct timer_list vb_timeout;
+
+	struct videobuf_queue vbuf_q;
+	spinlock_t vbuf_q_lock; /* Protect vbuf_q */
+	enum v4l2_buf_type vb_type;
+};
+
+struct cx18_videobuf_buffer {
+	/* Common video buffer sub-system struct */
+	struct videobuf_buffer vb;
+	v4l2_std_id tvnorm; /* selected tv norm */
+	u32 bytes_used;
 };
 
 struct cx18_open_id {
@@ -410,6 +431,10 @@
 	u32 open_id;
 	int type;
 	struct cx18 *cx;
+
+	struct videobuf_queue vbuf_q;
+	spinlock_t s_lock; /* Protect vbuf_q */
+	enum v4l2_buf_type vb_type;
 };
 
 static inline struct cx18_open_id *fh2id(struct v4l2_fh *fh)
diff -druN linux-2.6.39-libre/drivers/media/video/cx18/cx18-fileops.c linux-3.0-rc7-libre/drivers/media/video/cx18/cx18-fileops.c
--- linux-2.6.39-libre/drivers/media/video/cx18/cx18-fileops.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/video/cx18/cx18-fileops.c	2011-07-11 19:51:52.000000000 -0400
@@ -597,6 +597,13 @@
 	mutex_unlock(&cx->serialize_lock);
 	if (rc)
 		return rc;
+
+	if ((s->vb_type == V4L2_BUF_TYPE_VIDEO_CAPTURE) &&
+		(id->type == CX18_ENC_STREAM_TYPE_YUV)) {
+		return videobuf_read_stream(&s->vbuf_q, buf, count, pos, 0,
+			filp->f_flags & O_NONBLOCK);
+	}
+
 	return cx18_read_pos(s, buf, count, pos, filp->f_flags & O_NONBLOCK);
 }
 
@@ -622,6 +629,15 @@
 		CX18_DEBUG_FILE("Encoder poll started capture\n");
 	}
 
+	if ((s->vb_type == V4L2_BUF_TYPE_VIDEO_CAPTURE) &&
+		(id->type == CX18_ENC_STREAM_TYPE_YUV)) {
+		int videobuf_poll = videobuf_poll_stream(filp, &s->vbuf_q, wait);
+                if (eof && videobuf_poll == POLLERR)
+                        return POLLHUP;
+                else
+                        return videobuf_poll;
+	}
+
 	/* add stream's waitq to the poll list */
 	CX18_DEBUG_HI_FILE("Encoder poll\n");
 	poll_wait(filp, &s->waitq, wait);
@@ -633,6 +649,58 @@
 	return 0;
 }
 
+int cx18_v4l2_mmap(struct file *file, struct vm_area_struct *vma)
+{
+	struct cx18_open_id *id = file->private_data;
+	struct cx18 *cx = id->cx;
+	struct cx18_stream *s = &cx->streams[id->type];
+	int eof = test_bit(CX18_F_S_STREAMOFF, &s->s_flags);
+
+	if ((s->vb_type == V4L2_BUF_TYPE_VIDEO_CAPTURE) &&
+		(id->type == CX18_ENC_STREAM_TYPE_YUV)) {
+
+		/* Start a capture if there is none */
+		if (!eof && !test_bit(CX18_F_S_STREAMING, &s->s_flags)) {
+			int rc;
+
+			mutex_lock(&cx->serialize_lock);
+			rc = cx18_start_capture(id);
+			mutex_unlock(&cx->serialize_lock);
+			if (rc) {
+				CX18_DEBUG_INFO(
+					"Could not start capture for %s (%d)\n",
+					s->name, rc);
+				return -EINVAL;
+			}
+			CX18_DEBUG_FILE("Encoder mmap started capture\n");
+		}
+
+		return videobuf_mmap_mapper(&s->vbuf_q, vma);
+	}
+
+	return -EINVAL;
+}
+
+void cx18_vb_timeout(unsigned long data)
+{
+	struct cx18_stream *s = (struct cx18_stream *)data;
+	struct cx18_videobuf_buffer *buf;
+	unsigned long flags;
+
+	/* Return all of the buffers in error state, so the vbi/vid inode
+	 * can return from blocking.
+	 */
+	spin_lock_irqsave(&s->vb_lock, flags);
+	while (!list_empty(&s->vb_capture)) {
+		buf = list_entry(s->vb_capture.next,
+			struct cx18_videobuf_buffer, vb.queue);
+		list_del(&buf->vb.queue);
+		buf->vb.state = VIDEOBUF_ERROR;
+		wake_up(&buf->vb.done);
+	}
+	spin_unlock_irqrestore(&s->vb_lock, flags);
+}
+
 void cx18_stop_capture(struct cx18_open_id *id, int gop_end)
 {
 	struct cx18 *cx = id->cx;
@@ -716,6 +784,8 @@
 		cx18_release_stream(s);
 	} else {
 		cx18_stop_capture(id, 0);
+		if (id->type == CX18_ENC_STREAM_TYPE_YUV)
+			videobuf_mmap_free(&id->vbuf_q);
 	}
 	kfree(id);
 	mutex_unlock(&cx->serialize_lock);
diff -druN linux-2.6.39-libre/drivers/media/video/cx18/cx18-fileops.h linux-3.0-rc7-libre/drivers/media/video/cx18/cx18-fileops.h
--- linux-2.6.39-libre/drivers/media/video/cx18/cx18-fileops.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/video/cx18/cx18-fileops.h	2011-07-11 19:51:52.000000000 -0400
@@ -33,6 +33,8 @@
 void cx18_stop_capture(struct cx18_open_id *id, int gop_end);
 void cx18_mute(struct cx18 *cx);
 void cx18_unmute(struct cx18 *cx);
+int cx18_v4l2_mmap(struct file *file, struct vm_area_struct *vma);
+void cx18_vb_timeout(unsigned long data);
 
 /* Shared with cx18-alsa module */
 int cx18_claim_stream(struct cx18_open_id *id, int type);
diff -druN linux-2.6.39-libre/drivers/media/video/cx18/cx18-ioctl.c linux-3.0-rc7-libre/drivers/media/video/cx18/cx18-ioctl.c
--- linux-2.6.39-libre/drivers/media/video/cx18/cx18-ioctl.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/video/cx18/cx18-ioctl.c	2011-07-11 19:51:52.000000000 -0400
@@ -150,6 +150,7 @@
 {
 	struct cx18_open_id *id = fh2id(fh);
 	struct cx18 *cx = id->cx;
+	struct cx18_stream *s = &cx->streams[id->type];
 	struct v4l2_pix_format *pixfmt = &fmt->fmt.pix;
 
 	pixfmt->width = cx->cxhdl.width;
@@ -158,9 +159,13 @@
 	pixfmt->field = V4L2_FIELD_INTERLACED;
 	pixfmt->priv = 0;
 	if (id->type == CX18_ENC_STREAM_TYPE_YUV) {
-		pixfmt->pixelformat = V4L2_PIX_FMT_HM12;
-		/* YUV size is (Y=(h*720) + UV=(h*(720/2))) */
-		pixfmt->sizeimage = pixfmt->height * 720 * 3 / 2;
+		pixfmt->pixelformat = s->pixelformat;
+		/* HM12 YUV size is (Y=(h*720) + UV=(h*(720/2)))
+		   UYUV YUV size is (Y=(h*720) + UV=(h*(720))) */
+		if (s->pixelformat == V4L2_PIX_FMT_HM12)
+			pixfmt->sizeimage = pixfmt->height * 720 * 3 / 2;
+		else
+			pixfmt->sizeimage = pixfmt->height * 720 * 2;
 		pixfmt->bytesperline = 720;
 	} else {
 		pixfmt->pixelformat = V4L2_PIX_FMT_MPEG;
@@ -237,7 +242,6 @@
 	h = min(h, cx->is_50hz ? 576 : 480);
 	h = max(h, min_h);
 
-	cx18_g_fmt_vid_cap(file, fh, fmt);
 	fmt->fmt.pix.width = w;
 	fmt->fmt.pix.height = h;
 	return 0;
@@ -274,6 +278,7 @@
 	struct cx18_open_id *id = fh2id(fh);
 	struct cx18 *cx = id->cx;
 	struct v4l2_mbus_framefmt mbus_fmt;
+	struct cx18_stream *s = &cx->streams[id->type];
 	int ret;
 	int w, h;
 
@@ -283,12 +288,15 @@
 	w = fmt->fmt.pix.width;
 	h = fmt->fmt.pix.height;
 
-	if (cx->cxhdl.width == w && cx->cxhdl.height == h)
+	if (cx->cxhdl.width == w && cx->cxhdl.height == h &&
+	    s->pixelformat == fmt->fmt.pix.pixelformat)
 		return 0;
 
 	if (atomic_read(&cx->ana_capturing) > 0)
 		return -EBUSY;
 
+	s->pixelformat = fmt->fmt.pix.pixelformat;
+
 	mbus_fmt.width = cx->cxhdl.width = w;
 	mbus_fmt.height = cx->cxhdl.height = h;
 	mbus_fmt.code = V4L2_MBUS_FMT_FIXED;
@@ -540,16 +548,19 @@
 static int cx18_enum_fmt_vid_cap(struct file *file, void *fh,
 					struct v4l2_fmtdesc *fmt)
 {
-	static struct v4l2_fmtdesc formats[] = {
+	static const struct v4l2_fmtdesc formats[] = {
 		{ 0, V4L2_BUF_TYPE_VIDEO_CAPTURE, 0,
 		  "HM12 (YUV 4:1:1)", V4L2_PIX_FMT_HM12, { 0, 0, 0, 0 }
 		},
 		{ 1, V4L2_BUF_TYPE_VIDEO_CAPTURE, V4L2_FMT_FLAG_COMPRESSED,
 		  "MPEG", V4L2_PIX_FMT_MPEG, { 0, 0, 0, 0 }
-		}
+		},
+		{ 2, V4L2_BUF_TYPE_VIDEO_CAPTURE, 0,
+		  "UYVY 4:2:2", V4L2_PIX_FMT_UYVY, { 0, 0, 0, 0 }
+		},
 	};
 
-	if (fmt->index > 1)
+	if (fmt->index > ARRAY_SIZE(formats) - 1)
 		return -EINVAL;
 	*fmt = formats[fmt->index];
 	return 0;
@@ -684,14 +695,10 @@
 
 	cx18_call_all(cx, tuner, g_tuner, vt);
 
-	if (test_bit(CX18_F_I_RADIO_USER, &cx->i_flags)) {
+	if (vt->type == V4L2_TUNER_RADIO)
 		strlcpy(vt->name, "cx18 Radio Tuner", sizeof(vt->name));
-		vt->type = V4L2_TUNER_RADIO;
-	} else {
+	else
 		strlcpy(vt->name, "cx18 TV Tuner", sizeof(vt->name));
-		vt->type = V4L2_TUNER_ANALOG_TV;
-	}
-
 	return 0;
 }
 
@@ -863,6 +870,117 @@
 	return 0;
 }
 
+static struct videobuf_queue *cx18_vb_queue(struct cx18_open_id *id)
+{
+	struct videobuf_queue *q = NULL;
+	struct cx18 *cx = id->cx;
+	struct cx18_stream *s = &cx->streams[id->type];
+
+	switch (s->vb_type) {
+	case V4L2_BUF_TYPE_VIDEO_CAPTURE:
+		q = &s->vbuf_q;
+		break;
+	case V4L2_BUF_TYPE_VBI_CAPTURE:
+		break;
+	default:
+		break;
+	}
+	return q;
+}
+
+static int cx18_streamon(struct file *file, void *priv,
+	enum v4l2_buf_type type)
+{
+	struct cx18_open_id *id = file->private_data;
+	struct cx18 *cx = id->cx;
+	struct cx18_stream *s = &cx->streams[id->type];
+
+	/* Start the hardware only if we're the video device */
+	if ((s->vb_type != V4L2_BUF_TYPE_VIDEO_CAPTURE) &&
+		(s->vb_type != V4L2_BUF_TYPE_VBI_CAPTURE))
+		return -EINVAL;
+
+	if (id->type != CX18_ENC_STREAM_TYPE_YUV)
+		return -EINVAL;
+
+	/* Establish a buffer timeout */
+	mod_timer(&s->vb_timeout, msecs_to_jiffies(2000) + jiffies);
+
+	return videobuf_streamon(cx18_vb_queue(id));
+}
+
+static int cx18_streamoff(struct file *file, void *priv,
+	enum v4l2_buf_type type)
+{
+	struct cx18_open_id *id = file->private_data;
+	struct cx18 *cx = id->cx;
+	struct cx18_stream *s = &cx->streams[id->type];
+
+	/* Start the hardware only if we're the video device */
+	if ((s->vb_type != V4L2_BUF_TYPE_VIDEO_CAPTURE) &&
+		(s->vb_type != V4L2_BUF_TYPE_VBI_CAPTURE))
+		return -EINVAL;
+
+	if (id->type != CX18_ENC_STREAM_TYPE_YUV)
+		return -EINVAL;
+
+	return videobuf_streamoff(cx18_vb_queue(id));
+}
+
+static int cx18_reqbufs(struct file *file, void *priv,
+	struct v4l2_requestbuffers *rb)
+{
+	struct cx18_open_id *id = file->private_data;
+	struct cx18 *cx = id->cx;
+	struct cx18_stream *s = &cx->streams[id->type];
+
+	if ((s->vb_type != V4L2_BUF_TYPE_VIDEO_CAPTURE) &&
+		(s->vb_type != V4L2_BUF_TYPE_VBI_CAPTURE))
+		return -EINVAL;
+
+	return videobuf_reqbufs(cx18_vb_queue(id), rb);
+}
+
+static int cx18_querybuf(struct file *file, void *priv,
+	struct v4l2_buffer *b)
+{
+	struct cx18_open_id *id = file->private_data;
+	struct cx18 *cx = id->cx;
+	struct cx18_stream *s = &cx->streams[id->type];
+
+	if ((s->vb_type != V4L2_BUF_TYPE_VIDEO_CAPTURE) &&
+		(s->vb_type != V4L2_BUF_TYPE_VBI_CAPTURE))
+		return -EINVAL;
+
+	return videobuf_querybuf(cx18_vb_queue(id), b);
+}
+
+static int cx18_qbuf(struct file *file, void *priv, struct v4l2_buffer *b)
+{
+	struct cx18_open_id *id = file->private_data;
+	struct cx18 *cx = id->cx;
+	struct cx18_stream *s = &cx->streams[id->type];
+
+	if ((s->vb_type != V4L2_BUF_TYPE_VIDEO_CAPTURE) &&
+		(s->vb_type != V4L2_BUF_TYPE_VBI_CAPTURE))
+		return -EINVAL;
+
+	return videobuf_qbuf(cx18_vb_queue(id), b);
+}
+
+static int cx18_dqbuf(struct file *file, void *priv, struct v4l2_buffer *b)
+{
+	struct cx18_open_id *id = file->private_data;
+	struct cx18 *cx = id->cx;
+	struct cx18_stream *s = &cx->streams[id->type];
+
+	if ((s->vb_type != V4L2_BUF_TYPE_VIDEO_CAPTURE) &&
+		(s->vb_type != V4L2_BUF_TYPE_VBI_CAPTURE))
+		return -EINVAL;
+
+	return videobuf_dqbuf(cx18_vb_queue(id), b, file->f_flags & O_NONBLOCK);
+}
+
 static int cx18_encoder_cmd(struct file *file, void *fh,
 				struct v4l2_encoder_cmd *enc)
 {
@@ -1081,6 +1199,12 @@
 	.vidioc_s_register              = cx18_s_register,
 #endif
 	.vidioc_default                 = cx18_default,
+	.vidioc_streamon                = cx18_streamon,
+	.vidioc_streamoff               = cx18_streamoff,
+	.vidioc_reqbufs                 = cx18_reqbufs,
+	.vidioc_querybuf                = cx18_querybuf,
+	.vidioc_qbuf                    = cx18_qbuf,
+	.vidioc_dqbuf                   = cx18_dqbuf,
 };
 
 void cx18_set_funcs(struct video_device *vdev)
diff -druN linux-2.6.39-libre/drivers/media/video/cx18/cx18-mailbox.c linux-3.0-rc7-libre/drivers/media/video/cx18/cx18-mailbox.c
--- linux-2.6.39-libre/drivers/media/video/cx18/cx18-mailbox.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/video/cx18/cx18-mailbox.c	2011-07-11 19:51:52.000000000 -0400
@@ -81,6 +81,7 @@
 	API_ENTRY(CPU, CX18_CPU_SET_SLICED_VBI_PARAM,           0),
 	API_ENTRY(CPU, CX18_CPU_SET_USERDATA_PLACE_HOLDER,      0),
 	API_ENTRY(CPU, CX18_CPU_GET_ENC_PTS,                    0),
+	API_ENTRY(CPU, CX18_CPU_SET_VFC_PARAM,                  0),
 	API_ENTRY(CPU, CX18_CPU_DE_SET_MDL_ACK,			0),
 	API_ENTRY(CPU, CX18_CPU_DE_SET_MDL,			API_FAST),
 	API_ENTRY(CPU, CX18_CPU_DE_RELEASE_MDL,			API_SLOW),
@@ -158,6 +159,60 @@
 	}
 }
 
+static void cx18_mdl_send_to_videobuf(struct cx18_stream *s,
+	struct cx18_mdl *mdl)
+{
+	struct cx18_videobuf_buffer *vb_buf;
+	struct cx18_buffer *buf;
+	u8 *p;
+	u32 offset = 0;
+	int dispatch = 0;
+
+	if (mdl->bytesused == 0)
+		return;
+
+	/* Acquire a videobuf buffer, clone to and and release it */
+	spin_lock(&s->vb_lock);
+	if (list_empty(&s->vb_capture))
+		goto out;
+
+	vb_buf = list_first_entry(&s->vb_capture, struct cx18_videobuf_buffer,
+		vb.queue);
+
+	p = videobuf_to_vmalloc(&vb_buf->vb);
+	if (!p)
+		goto out;
+
+	offset = vb_buf->bytes_used;
+	list_for_each_entry(buf, &mdl->buf_list, list) {
+		if (buf->bytesused == 0)
+			break;
+
+		if ((offset + buf->bytesused) <= vb_buf->vb.bsize) {
+			memcpy(p + offset, buf->buf, buf->bytesused);
+			offset += buf->bytesused;
+			vb_buf->bytes_used += buf->bytesused;
+		}
+	}
+
+	/* If we've filled the buffer as per the callers res then dispatch it */
+	if (vb_buf->bytes_used >= (vb_buf->vb.width * vb_buf->vb.height * 2)) {
+		dispatch = 1;
+		vb_buf->bytes_used = 0;
+	}
+
+	if (dispatch) {
+		vb_buf->vb.ts = ktime_to_timeval(ktime_get());
+		list_del(&vb_buf->vb.queue);
+		vb_buf->vb.state = VIDEOBUF_DONE;
+		wake_up(&vb_buf->vb.done);
+	}
+
+	mod_timer(&s->vb_timeout, msecs_to_jiffies(2000) + jiffies);
+
+out:
+	spin_unlock(&s->vb_lock);
+}
 
 static void cx18_mdl_send_to_alsa(struct cx18 *cx, struct cx18_stream *s,
 				  struct cx18_mdl *mdl)
@@ -263,6 +318,9 @@
 			} else {
 				cx18_enqueue(s, mdl, &s->q_full);
 			}
+		} else if (s->type == CX18_ENC_STREAM_TYPE_YUV) {
+			cx18_mdl_send_to_videobuf(s, mdl);
+			cx18_enqueue(s, mdl, &s->q_free);
 		} else {
 			cx18_enqueue(s, mdl, &s->q_full);
 			if (s->type == CX18_ENC_STREAM_TYPE_IDX)
diff -druN linux-2.6.39-libre/drivers/media/video/cx18/cx18-streams.c linux-3.0-rc7-libre/drivers/media/video/cx18/cx18-streams.c
--- linux-2.6.39-libre/drivers/media/video/cx18/cx18-streams.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/video/cx18/cx18-streams.c	2011-07-11 19:51:52.000000000 -0400
@@ -44,6 +44,7 @@
 	.unlocked_ioctl = cx18_v4l2_ioctl,
 	.release = cx18_v4l2_close,
 	.poll = cx18_v4l2_enc_poll,
+	.mmap = cx18_v4l2_mmap,
 };
 
 /* offset from 0 to register ts v4l2 minors on */
@@ -97,6 +98,141 @@
 	},
 };
 
+
+void cx18_dma_free(struct videobuf_queue *q,
+	struct cx18_stream *s, struct cx18_videobuf_buffer *buf)
+{
+	videobuf_waiton(q, &buf->vb, 0, 0);
+	videobuf_vmalloc_free(&buf->vb);
+	buf->vb.state = VIDEOBUF_NEEDS_INIT;
+}
+
+static int cx18_prepare_buffer(struct videobuf_queue *q,
+	struct cx18_stream *s,
+	struct cx18_videobuf_buffer *buf,
+	u32 pixelformat,
+	unsigned int width, unsigned int height,
+	enum v4l2_field field)
+{
+        struct cx18 *cx = s->cx;
+	int rc = 0;
+
+	/* check settings */
+	buf->bytes_used = 0;
+
+	if ((width  < 48) || (height < 32))
+		return -EINVAL;
+
+	buf->vb.size = (width * height * 2);
+	if ((buf->vb.baddr != 0) && (buf->vb.bsize < buf->vb.size))
+		return -EINVAL;
+
+	/* alloc + fill struct (if changed) */
+	if (buf->vb.width != width || buf->vb.height != height ||
+	    buf->vb.field != field || s->pixelformat != pixelformat ||
+	    buf->tvnorm != cx->std) {
+
+		buf->vb.width  = width;
+		buf->vb.height = height;
+		buf->vb.field  = field;
+		buf->tvnorm    = cx->std;
+		s->pixelformat = pixelformat;
+
+		cx18_dma_free(q, s, buf);
+	}
+
+	if ((buf->vb.baddr != 0) && (buf->vb.bsize < buf->vb.size))
+		return -EINVAL;
+
+	if (buf->vb.field == 0)
+		buf->vb.field = V4L2_FIELD_INTERLACED;
+
+	if (VIDEOBUF_NEEDS_INIT == buf->vb.state) {
+		buf->vb.width  = width;
+		buf->vb.height = height;
+		buf->vb.field  = field;
+		buf->tvnorm    = cx->std;
+		s->pixelformat = pixelformat;
+
+		rc = videobuf_iolock(q, &buf->vb, NULL);
+		if (rc != 0)
+			goto fail;
+	}
+	buf->vb.state = VIDEOBUF_PREPARED;
+	return 0;
+
+fail:
+	cx18_dma_free(q, s, buf);
+	return rc;
+
+}
+
+/* VB_MIN_BUFSIZE is lcm(1440 * 480, 1440 * 576)
+   1440 is a single line of 4:2:2 YUV at 720 luma samples wide
+*/
+#define VB_MIN_BUFFERS 32
+#define VB_MIN_BUFSIZE 4147200
+
+static int buffer_setup(struct videobuf_queue *q,
+	unsigned int *count, unsigned int *size)
+{
+	struct cx18_stream *s = q->priv_data;
+	struct cx18 *cx = s->cx;
+
+	*size = 2 * cx->cxhdl.width * cx->cxhdl.height;
+	if (*count == 0)
+		*count = VB_MIN_BUFFERS;
+
+	while (*size * *count > VB_MIN_BUFFERS * VB_MIN_BUFSIZE)
+		(*count)--;
+
+	q->field = V4L2_FIELD_INTERLACED;
+	q->last = V4L2_FIELD_INTERLACED;
+
+	return 0;
+}
+
+static int buffer_prepare(struct videobuf_queue *q,
+	struct videobuf_buffer *vb,
+	enum v4l2_field field)
+{
+	struct cx18_videobuf_buffer *buf =
+		container_of(vb, struct cx18_videobuf_buffer, vb);
+	struct cx18_stream *s = q->priv_data;
+	struct cx18 *cx = s->cx;
+
+	return cx18_prepare_buffer(q, s, buf, s->pixelformat,
+		cx->cxhdl.width, cx->cxhdl.height, field);
+}
+
+static void buffer_release(struct videobuf_queue *q,
+	struct videobuf_buffer *vb)
+{
+	struct cx18_videobuf_buffer *buf =
+		container_of(vb, struct cx18_videobuf_buffer, vb);
+	struct cx18_stream *s = q->priv_data;
+
+	cx18_dma_free(q, s, buf);
+}
+
+static void buffer_queue(struct videobuf_queue *q, struct videobuf_buffer *vb)
+{
+	struct cx18_videobuf_buffer *buf =
+		container_of(vb, struct cx18_videobuf_buffer, vb);
+	struct cx18_stream *s = q->priv_data;
+
+	buf->vb.state = VIDEOBUF_QUEUED;
+
+	list_add_tail(&buf->vb.queue, &s->vb_capture);
+}
+
+static struct videobuf_queue_ops cx18_videobuf_qops = {
+	.buf_setup    = buffer_setup,
+	.buf_prepare  = buffer_prepare,
+	.buf_queue    = buffer_queue,
+	.buf_release  = buffer_release,
+};
+
 static void cx18_stream_init(struct cx18 *cx, int type)
 {
 	struct cx18_stream *s = &cx->streams[type];
@@ -132,6 +268,26 @@
 	cx18_queue_init(&s->q_idle);
 
 	INIT_WORK(&s->out_work_order, cx18_out_work_handler);
+
+	INIT_LIST_HEAD(&s->vb_capture);
+	s->vb_timeout.function = cx18_vb_timeout;
+	s->vb_timeout.data = (unsigned long)s;
+	init_timer(&s->vb_timeout);
+	spin_lock_init(&s->vb_lock);
+	if (type == CX18_ENC_STREAM_TYPE_YUV) {
+		spin_lock_init(&s->vbuf_q_lock);
+
+		s->vb_type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+		videobuf_queue_vmalloc_init(&s->vbuf_q, &cx18_videobuf_qops,
+			&cx->pci_dev->dev, &s->vbuf_q_lock,
+			V4L2_BUF_TYPE_VIDEO_CAPTURE,
+			V4L2_FIELD_INTERLACED,
+			sizeof(struct cx18_videobuf_buffer),
+			s, &cx->serialize_lock);
+
+		/* Assume the previous pixel default */
+		s->pixelformat = V4L2_PIX_FMT_HM12;
+	}
 }
 
 static int cx18_prep_dev(struct cx18 *cx, int type)
@@ -372,6 +528,9 @@
 		if (vdev == NULL)
 			continue;
 
+		if (type == CX18_ENC_STREAM_TYPE_YUV)
+			videobuf_mmap_free(&cx->streams[type].vbuf_q);
+
 		cx18_stream_free(&cx->streams[type]);
 
 		/* Unregister or release device */
@@ -581,7 +740,10 @@
 		 * Set the MDL size to the exact size needed for one frame.
 		 * Use enough buffers per MDL to cover the MDL size
 		 */
-		s->mdl_size = 720 * s->cx->cxhdl.height * 3 / 2;
+		if (s->pixelformat == V4L2_PIX_FMT_HM12)
+			s->mdl_size = 720 * s->cx->cxhdl.height * 3 / 2;
+		else
+			s->mdl_size = 720 * s->cx->cxhdl.height * 2;
 		s->bufs_per_mdl = s->mdl_size / s->buf_size;
 		if (s->mdl_size % s->buf_size)
 			s->bufs_per_mdl++;
@@ -729,6 +891,19 @@
 		    test_bit(CX18_F_I_RADIO_USER, &cx->i_flags))
 			cx18_vapi(cx, CX18_CPU_SET_VIDEO_MUTE, 2, s->handle,
 			  (v4l2_ctrl_g_ctrl(cx->cxhdl.video_mute_yuv) << 8) | 1);
+
+		/* Enable the Video Format Converter for UYVY 4:2:2 support,
+		 * rather than the default HM12 Macroblovk 4:2:0 support.
+		 */
+		if (captype == CAPTURE_CHANNEL_TYPE_YUV) {
+			if (s->pixelformat == V4L2_PIX_FMT_UYVY)
+				cx18_vapi(cx, CX18_CPU_SET_VFC_PARAM, 2,
+					s->handle, 1);
+			else
+				/* If in doubt, default to HM12 */
+				cx18_vapi(cx, CX18_CPU_SET_VFC_PARAM, 2,
+					s->handle, 0);
+		}
 	}
 
 	if (atomic_read(&cx->tot_capturing) == 0) {
diff -druN linux-2.6.39-libre/drivers/media/video/cx18/cx18-version.h linux-3.0-rc7-libre/drivers/media/video/cx18/cx18-version.h
--- linux-2.6.39-libre/drivers/media/video/cx18/cx18-version.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/video/cx18/cx18-version.h	2011-07-11 19:51:52.000000000 -0400
@@ -24,7 +24,7 @@
 
 #define CX18_DRIVER_NAME "cx18"
 #define CX18_DRIVER_VERSION_MAJOR 1
-#define CX18_DRIVER_VERSION_MINOR 4
+#define CX18_DRIVER_VERSION_MINOR 5
 #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 -druN linux-2.6.39-libre/drivers/media/video/cx18/cx23418.h linux-3.0-rc7-libre/drivers/media/video/cx18/cx23418.h
--- linux-2.6.39-libre/drivers/media/video/cx18/cx23418.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/video/cx18/cx23418.h	2011-07-11 19:51:52.000000000 -0400
@@ -342,6 +342,12 @@
    ReturnCode */
 #define CX18_CPU_GET_ENC_PTS			(CPU_CMD_MASK_CAPTURE | 0x0022)
 
+/* Description: Set VFC parameters
+   IN[0] - task handle
+   IN[1] - VFC enable flag, 1 - enable, 0 - disable
+*/
+#define CX18_CPU_SET_VFC_PARAM                  (CPU_CMD_MASK_CAPTURE | 0x0023)
+
 /* Below is the list of commands related to the data exchange */
 #define CPU_CMD_MASK_DE 			(CPU_CMD_MASK | 0x040000)
 
diff -druN linux-2.6.39-libre/drivers/media/video/cx18/Kconfig linux-3.0-rc7-libre/drivers/media/video/cx18/Kconfig
--- linux-2.6.39-libre/drivers/media/video/cx18/Kconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/video/cx18/Kconfig	2011-07-11 19:51:52.000000000 -0400
@@ -2,6 +2,7 @@
 	tristate "Conexant cx23418 MPEG encoder support"
 	depends on VIDEO_V4L2 && DVB_CORE && PCI && I2C && EXPERIMENTAL
 	select I2C_ALGOBIT
+	select VIDEOBUF_VMALLOC
 	depends on RC_CORE
 	select VIDEO_TUNER
 	select VIDEO_TVEEPROM
@@ -9,6 +10,9 @@
 	select VIDEO_CS5345
 	select DVB_S5H1409 if !DVB_FE_CUSTOMISE
 	select MEDIA_TUNER_MXL5005S if !MEDIA_TUNER_CUSTOMISE
+	select DVB_S5H1411 if !DVB_FE_CUSTOMISE
+	select MEDIA_TUNER_TDA18271 if !MEDIA_TUNER_CUSTOMISE
+	select MEDIA_TUNER_TDA8290 if !MEDIA_TUNER_CUSTOMISE
 	---help---
 	  This is a video4linux driver for Conexant cx23418 based
 	  PCI combo video recorder devices.
diff -druN linux-2.6.39-libre/drivers/media/video/cx231xx/cx231xx-avcore.c linux-3.0-rc7-libre/drivers/media/video/cx231xx/cx231xx-avcore.c
--- linux-2.6.39-libre/drivers/media/video/cx231xx/cx231xx-avcore.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/video/cx231xx/cx231xx-avcore.c	2011-07-11 19:51:52.000000000 -0400
@@ -1354,7 +1354,7 @@
 {
 	u8 value[4] = { 0, 0, 0, 0 };
 	int status = 0;
-	cx231xx_info("cx231xx_dump_SC_reg %s!\n", __TIME__);
+	cx231xx_info("cx231xx_dump_SC_reg!\n");
 
 	status = cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, BOARD_CFG_STAT,
 				 value, 4);
diff -druN linux-2.6.39-libre/drivers/media/video/cx231xx/cx231xx-cards.c linux-3.0-rc7-libre/drivers/media/video/cx231xx/cx231xx-cards.c
--- linux-2.6.39-libre/drivers/media/video/cx231xx/cx231xx-cards.c	2011-05-19 02:08:18.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/video/cx231xx/cx231xx-cards.c	2011-07-21 06:50:36.000000000 -0400
@@ -401,6 +401,44 @@
 			.gpio = NULL,
 		} },
 	},
+	[CX231XX_BOARD_KWORLD_UB430_USB_HYBRID] = {
+		.name = "Kworld UB430 USB Hybrid",
+		.tuner_type = TUNER_NXP_TDA18271,
+		.tuner_addr = 0x60,
+		.decoder = CX231XX_AVDECODER,
+		.output_mode = OUT_MODE_VIP11,
+		.demod_xfer_mode = 0,
+		.ctl_pin_status_mask = 0xFFFFFFC4,
+		.agc_analog_digital_select_gpio = 0x11,	/* According with PV cxPolaris.inf file */
+		.tuner_sif_gpio = -1,
+		.tuner_scl_gpio = -1,
+		.tuner_sda_gpio = -1,
+		.gpio_pin_status_mask = 0x4001000,
+		.tuner_i2c_master = 2,
+		.demod_i2c_master = 1,
+		.ir_i2c_master = 2,
+		.has_dvb = 1,
+		.demod_addr = 0x10,
+		.norm = V4L2_STD_PAL_M,
+		.input = {{
+			.type = CX231XX_VMUX_TELEVISION,
+			.vmux = CX231XX_VIN_3_1,
+			.amux = CX231XX_AMUX_VIDEO,
+			.gpio = NULL,
+		}, {
+			.type = CX231XX_VMUX_COMPOSITE1,
+			.vmux = CX231XX_VIN_2_1,
+			.amux = CX231XX_AMUX_LINE_IN,
+			.gpio = NULL,
+		}, {
+			.type = CX231XX_VMUX_SVIDEO,
+			.vmux = CX231XX_VIN_1_1 |
+				(CX231XX_VIN_1_2 << 8) |
+				CX25840_SVIDEO_ON,
+			.amux = CX231XX_AMUX_LINE_IN,
+			.gpio = NULL,
+		} },
+	},
 	[CX231XX_BOARD_PV_PLAYTV_USB_HYBRID] = {
 		.name = "Pixelview PlayTV USB Hybrid",
 		.tuner_type = TUNER_NXP_TDA18271,
@@ -469,6 +507,31 @@
 			}
 		},
 	},
+
+	[CX231XX_BOARD_ICONBIT_U100] = {
+		.name = "Iconbit Analog Stick U100 FM",
+		.tuner_type = TUNER_ABSENT,
+		.decoder = CX231XX_AVDECODER,
+		.output_mode = OUT_MODE_VIP11,
+		.demod_xfer_mode = 0,
+		.ctl_pin_status_mask = 0xFFFFFFC4,
+		.agc_analog_digital_select_gpio = 0x1C,
+		.gpio_pin_status_mask = 0x4001000,
+
+		.input = {{
+			.type = CX231XX_VMUX_COMPOSITE1,
+			.vmux = CX231XX_VIN_2_1,
+			.amux = CX231XX_AMUX_LINE_IN,
+			.gpio = NULL,
+		}, {
+			.type = CX231XX_VMUX_SVIDEO,
+			.vmux = CX231XX_VIN_1_1 |
+				(CX231XX_VIN_1_2 << 8) |
+				CX25840_SVIDEO_ON,
+			.amux = CX231XX_AMUX_LINE_IN,
+			.gpio = NULL,
+		} },
+	},
 };
 const unsigned int cx231xx_bcount = ARRAY_SIZE(cx231xx_boards);
 
@@ -500,6 +563,10 @@
 	 .driver_info = CX231XX_BOARD_PV_PLAYTV_USB_HYBRID},
 	{USB_DEVICE(USB_VID_PIXELVIEW, 0x5014),
 	 .driver_info = CX231XX_BOARD_PV_XCAPTURE_USB},
+	{USB_DEVICE(0x1b80, 0xe424),
+	 .driver_info = CX231XX_BOARD_KWORLD_UB430_USB_HYBRID},
+	{USB_DEVICE(0x1f4d, 0x0237),
+	 .driver_info = CX231XX_BOARD_ICONBIT_U100},
 	{},
 };
 
diff -druN linux-2.6.39-libre/drivers/media/video/cx231xx/cx231xx-dvb.c linux-3.0-rc7-libre/drivers/media/video/cx231xx/cx231xx-dvb.c
--- linux-2.6.39-libre/drivers/media/video/cx231xx/cx231xx-dvb.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/video/cx231xx/cx231xx-dvb.c	2011-07-11 19:51:52.000000000 -0400
@@ -704,6 +704,7 @@
 		break;
 
 	case CX231XX_BOARD_PV_PLAYTV_USB_HYBRID:
+	case CX231XX_BOARD_KWORLD_UB430_USB_HYBRID:
 
 		printk(KERN_INFO "%s: looking for demod on i2c bus: %d\n",
 		       __func__, i2c_adapter_id(&dev->i2c_bus[dev->board.tuner_i2c_master].i2c_adap));
diff -druN linux-2.6.39-libre/drivers/media/video/cx231xx/cx231xx.h linux-3.0-rc7-libre/drivers/media/video/cx231xx/cx231xx.h
--- linux-2.6.39-libre/drivers/media/video/cx231xx/cx231xx.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/video/cx231xx/cx231xx.h	2011-07-11 19:51:52.000000000 -0400
@@ -65,6 +65,8 @@
 #define CX231XX_BOARD_HAUPPAUGE_USBLIVE2 9
 #define CX231XX_BOARD_PV_PLAYTV_USB_HYBRID 10
 #define CX231XX_BOARD_PV_XCAPTURE_USB 11
+#define CX231XX_BOARD_KWORLD_UB430_USB_HYBRID 12
+#define CX231XX_BOARD_ICONBIT_U100 13
 
 /* Limits minimum and default number of buffers */
 #define CX231XX_MIN_BUF                 4
diff -druN linux-2.6.39-libre/drivers/media/video/cx23885/cx23885-cards.c linux-3.0-rc7-libre/drivers/media/video/cx23885/cx23885-cards.c
--- linux-2.6.39-libre/drivers/media/video/cx23885/cx23885-cards.c	2011-05-19 02:10:20.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/video/cx23885/cx23885-cards.c	2011-07-21 06:52:46.000000000 -0400
@@ -25,8 +25,8 @@
 #include <linux/delay.h>
 #include <media/cx25840.h>
 #include <linux/firmware.h>
-#include <staging/altera.h>
 
+#include "../../../staging/altera-stapl/altera.h"
 #include "cx23885.h"
 #include "tuner-xc2028.h"
 #include "netup-init.h"
@@ -1399,6 +1399,7 @@
 		else
 			altera_init(&netup_config, fw);
 
+		release_firmware(fw);
 		break;
 	}
 	}
diff -druN linux-2.6.39-libre/drivers/media/video/cx23885/cx23885-core.c linux-3.0-rc7-libre/drivers/media/video/cx23885/cx23885-core.c
--- linux-2.6.39-libre/drivers/media/video/cx23885/cx23885-core.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/video/cx23885/cx23885-core.c	2011-07-11 19:51:52.000000000 -0400
@@ -2045,7 +2045,7 @@
 	}
 
 	/* print pci info */
-	pci_read_config_byte(pci_dev, PCI_CLASS_REVISION, &dev->pci_rev);
+	dev->pci_rev = pci_dev->revision;
 	pci_read_config_byte(pci_dev, PCI_LATENCY_TIMER,  &dev->pci_lat);
 	printk(KERN_INFO "%s/0: found at %s, rev: %d, irq: %d, "
 	       "latency: %d, mmio: 0x%llx\n", dev->name,
diff -druN linux-2.6.39-libre/drivers/media/video/cx88/cx88-blackbird.c linux-3.0-rc7-libre/drivers/media/video/cx88/cx88-blackbird.c
--- linux-2.6.39-libre/drivers/media/video/cx88/cx88-blackbird.c	2011-05-19 02:10:22.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/video/cx88/cx88-blackbird.c	2011-07-21 06:52:49.000000000 -0400
@@ -1060,18 +1060,21 @@
 
 	/* Make sure we can acquire the hardware */
 	drv = cx8802_get_driver(dev, CX88_MPEG_BLACKBIRD);
-	if (drv) {
-		err = drv->request_acquire(drv);
-		if(err != 0) {
-			dprintk(1,"%s: Unable to acquire hardware, %d\n", __func__, err);
-			mutex_unlock(&dev->core->lock);
-			return err;
-		}
+	if (!drv) {
+		dprintk(1, "%s: blackbird driver is not loaded\n", __func__);
+		mutex_unlock(&dev->core->lock);
+		return -ENODEV;
 	}
 
-	if (!atomic_read(&dev->core->mpeg_users) && blackbird_initialize_codec(dev) < 0) {
-		if (drv)
-			drv->request_release(drv);
+	err = drv->request_acquire(drv);
+	if (err != 0) {
+		dprintk(1,"%s: Unable to acquire hardware, %d\n", __func__, err);
+		mutex_unlock(&dev->core->lock);
+		return err;
+	}
+
+	if (!dev->core->mpeg_users && blackbird_initialize_codec(dev) < 0) {
+		drv->request_release(drv);
 		mutex_unlock(&dev->core->lock);
 		return -EINVAL;
 	}
@@ -1080,8 +1083,7 @@
 	/* allocate + initialize per filehandle data */
 	fh = kzalloc(sizeof(*fh),GFP_KERNEL);
 	if (NULL == fh) {
-		if (drv)
-			drv->request_release(drv);
+		drv->request_release(drv);
 		mutex_unlock(&dev->core->lock);
 		return -ENOMEM;
 	}
@@ -1099,7 +1101,7 @@
 	cx88_set_scale(dev->core, dev->width, dev->height,
 			fh->mpegq.field);
 
-	atomic_inc(&dev->core->mpeg_users);
+	dev->core->mpeg_users++;
 	mutex_unlock(&dev->core->lock);
 	return 0;
 }
@@ -1110,7 +1112,9 @@
 	struct cx8802_dev *dev = fh->dev;
 	struct cx8802_driver *drv = NULL;
 
-	if (dev->mpeg_active && atomic_read(&dev->core->mpeg_users) == 1)
+	mutex_lock(&dev->core->lock);
+
+	if (dev->mpeg_active && dev->core->mpeg_users == 1)
 		blackbird_stop_codec(dev);
 
 	cx8802_cancel_buffers(fh->dev);
@@ -1119,17 +1123,18 @@
 
 	videobuf_mmap_free(&fh->mpegq);
 
-	mutex_lock(&dev->core->lock);
 	file->private_data = NULL;
 	kfree(fh);
-	mutex_unlock(&dev->core->lock);
 
 	/* Make sure we release the hardware */
 	drv = cx8802_get_driver(dev, CX88_MPEG_BLACKBIRD);
+	WARN_ON(!drv);
 	if (drv)
 		drv->request_release(drv);
 
-	atomic_dec(&dev->core->mpeg_users);
+	dev->core->mpeg_users--;
+
+	mutex_unlock(&dev->core->lock);
 
 	return 0;
 }
@@ -1334,11 +1339,9 @@
 	blackbird_register_video(dev);
 
 	/* initial device configuration: needed ? */
-	mutex_lock(&dev->core->lock);
 //	init_controls(core);
 	cx88_set_tvnorm(core,core->tvnorm);
 	cx88_video_mux(core,0);
-	mutex_unlock(&dev->core->lock);
 
 	return 0;
 
diff -druN linux-2.6.39-libre/drivers/media/video/cx88/cx88-dvb.c linux-3.0-rc7-libre/drivers/media/video/cx88/cx88-dvb.c
--- linux-2.6.39-libre/drivers/media/video/cx88/cx88-dvb.c	2011-05-19 02:08:16.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/video/cx88/cx88-dvb.c	2011-07-21 06:50:33.000000000 -0400
@@ -133,6 +133,7 @@
 		return -EINVAL;
 	}
 
+	mutex_lock(&dev->core->lock);
 	drv = cx8802_get_driver(dev, CX88_MPEG_DVB);
 	if (drv) {
 		if (acquire){
@@ -143,6 +144,7 @@
 			dev->frontends.active_fe_id = 0;
 		}
 	}
+	mutex_unlock(&dev->core->lock);
 
 	return ret;
 }
diff -druN linux-2.6.39-libre/drivers/media/video/cx88/cx88.h linux-3.0-rc7-libre/drivers/media/video/cx88/cx88.h
--- linux-2.6.39-libre/drivers/media/video/cx88/cx88.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/video/cx88/cx88.h	2011-07-11 19:51:52.000000000 -0400
@@ -389,8 +389,8 @@
 	struct mutex               lock;
 	/* various v4l controls */
 	u32                        freq;
-	atomic_t		   users;
-	atomic_t                   mpeg_users;
+	int                        users;
+	int                        mpeg_users;
 
 	/* cx88-video needs to access cx8802 for hybrid tuner pll access. */
 	struct cx8802_dev          *dvbdev;
@@ -505,6 +505,8 @@
 	int (*suspend)(struct pci_dev *pci_dev, pm_message_t state);
 	int (*resume)(struct pci_dev *pci_dev);
 
+	/* Callers to the following functions must hold core->lock */
+
 	/* MPEG 8802 -> mini driver - Driver probe and configuration */
 	int (*probe)(struct cx8802_driver *drv);
 	int (*remove)(struct cx8802_driver *drv);
@@ -561,8 +563,9 @@
 	/* for switching modulation types */
 	unsigned char              ts_gen_cntrl;
 
-	/* List of attached drivers */
+	/* List of attached drivers; must hold core->lock to access */
 	struct list_head	   drvlist;
+
 	struct work_struct	   request_module_wk;
 };
 
@@ -685,6 +688,8 @@
 
 int cx8802_register_driver(struct cx8802_driver *drv);
 int cx8802_unregister_driver(struct cx8802_driver *drv);
+
+/* Caller must hold core->lock */
 struct cx8802_driver * cx8802_get_driver(struct cx8802_dev *dev, enum cx88_board_type btype);
 
 /* ----------------------------------------------------------- */
diff -druN linux-2.6.39-libre/drivers/media/video/cx88/cx88-mpeg.c linux-3.0-rc7-libre/drivers/media/video/cx88/cx88-mpeg.c
--- linux-2.6.39-libre/drivers/media/video/cx88/cx88-mpeg.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/video/cx88/cx88-mpeg.c	2011-07-11 19:51:52.000000000 -0400
@@ -78,6 +78,7 @@
 
 
 static LIST_HEAD(cx8802_devlist);
+static DEFINE_MUTEX(cx8802_mutex);
 /* ------------------------------------------------------------------ */
 
 static int cx8802_start_dma(struct cx8802_dev    *dev,
@@ -474,7 +475,7 @@
 		return -EIO;
 	}
 
-	pci_read_config_byte(dev->pci, PCI_CLASS_REVISION, &dev->pci_rev);
+	dev->pci_rev = dev->pci->revision;
 	pci_read_config_byte(dev->pci, PCI_LATENCY_TIMER,  &dev->pci_lat);
 	printk(KERN_INFO "%s/2: found at %s, rev: %d, irq: %d, "
 	       "latency: %d, mmio: 0x%llx\n", dev->core->name,
@@ -624,13 +625,11 @@
 
 	if (drv->advise_acquire)
 	{
-		mutex_lock(&drv->core->lock);
 		core->active_ref++;
 		if (core->active_type_id == CX88_BOARD_NONE) {
 			core->active_type_id = drv->type_id;
 			drv->advise_acquire(drv);
 		}
-		mutex_unlock(&drv->core->lock);
 
 		mpeg_dbg(1,"%s() Post acquire GPIO=%x\n", __func__, cx_read(MO_GP0_IO));
 	}
@@ -643,14 +642,12 @@
 {
 	struct cx88_core *core = drv->core;
 
-	mutex_lock(&drv->core->lock);
 	if (drv->advise_release && --core->active_ref == 0)
 	{
 		drv->advise_release(drv);
 		core->active_type_id = CX88_BOARD_NONE;
 		mpeg_dbg(1,"%s() Post release GPIO=%x\n", __func__, cx_read(MO_GP0_IO));
 	}
-	mutex_unlock(&drv->core->lock);
 
 	return 0;
 }
@@ -693,6 +690,8 @@
 		return err;
 	}
 
+	mutex_lock(&cx8802_mutex);
+
 	list_for_each_entry(dev, &cx8802_devlist, devlist) {
 		printk(KERN_INFO
 		       "%s/2: subsystem: %04x:%04x, board: %s [card=%d]\n",
@@ -702,8 +701,10 @@
 
 		/* Bring up a new struct for each driver instance */
 		driver = kzalloc(sizeof(*drv),GFP_KERNEL);
-		if (driver == NULL)
-			return -ENOMEM;
+		if (driver == NULL) {
+			err = -ENOMEM;
+			goto out;
+		}
 
 		/* Snapshot of the driver registration data */
 		drv->core = dev->core;
@@ -713,21 +714,23 @@
 		drv->request_release = cx8802_request_release;
 		memcpy(driver, drv, sizeof(*driver));
 
+		mutex_lock(&drv->core->lock);
 		err = drv->probe(driver);
 		if (err == 0) {
 			i++;
-			mutex_lock(&drv->core->lock);
 			list_add_tail(&driver->drvlist, &dev->drvlist);
-			mutex_unlock(&drv->core->lock);
 		} else {
 			printk(KERN_ERR
 			       "%s/2: cx8802 probe failed, err = %d\n",
 			       dev->core->name, err);
 		}
-
+		mutex_unlock(&drv->core->lock);
 	}
 
-	return i ? 0 : -ENODEV;
+	err = i ? 0 : -ENODEV;
+out:
+	mutex_unlock(&cx8802_mutex);
+	return err;
 }
 
 int cx8802_unregister_driver(struct cx8802_driver *drv)
@@ -741,6 +744,8 @@
 	       drv->type_id == CX88_MPEG_DVB ? "dvb" : "blackbird",
 	       drv->hw_access == CX8802_DRVCTL_SHARED ? "shared" : "exclusive");
 
+	mutex_lock(&cx8802_mutex);
+
 	list_for_each_entry(dev, &cx8802_devlist, devlist) {
 		printk(KERN_INFO
 		       "%s/2: subsystem: %04x:%04x, board: %s [card=%d]\n",
@@ -748,6 +753,8 @@
 		       dev->pci->subsystem_device, dev->core->board.name,
 		       dev->core->boardnr);
 
+		mutex_lock(&dev->core->lock);
+
 		list_for_each_entry_safe(d, dtmp, &dev->drvlist, drvlist) {
 			/* only unregister the correct driver type */
 			if (d->type_id != drv->type_id)
@@ -755,17 +762,18 @@
 
 			err = d->remove(d);
 			if (err == 0) {
-				mutex_lock(&drv->core->lock);
 				list_del(&d->drvlist);
-				mutex_unlock(&drv->core->lock);
 				kfree(d);
 			} else
 				printk(KERN_ERR "%s/2: cx8802 driver remove "
 				       "failed (%d)\n", dev->core->name, err);
 		}
 
+		mutex_unlock(&dev->core->lock);
 	}
 
+	mutex_unlock(&cx8802_mutex);
+
 	return err;
 }
 
@@ -803,7 +811,9 @@
 		goto fail_free;
 
 	INIT_LIST_HEAD(&dev->drvlist);
+	mutex_lock(&cx8802_mutex);
 	list_add_tail(&dev->devlist,&cx8802_devlist);
+	mutex_unlock(&cx8802_mutex);
 
 	/* now autoload cx88-dvb or cx88-blackbird */
 	request_modules(dev);
@@ -827,6 +837,8 @@
 
 	flush_request_modules(dev);
 
+	mutex_lock(&dev->core->lock);
+
 	if (!list_empty(&dev->drvlist)) {
 		struct cx8802_driver *drv, *tmp;
 		int err;
@@ -838,9 +850,7 @@
 		list_for_each_entry_safe(drv, tmp, &dev->drvlist, drvlist) {
 			err = drv->remove(drv);
 			if (err == 0) {
-				mutex_lock(&drv->core->lock);
 				list_del(&drv->drvlist);
-				mutex_unlock(&drv->core->lock);
 			} else
 				printk(KERN_ERR "%s/2: cx8802 driver remove "
 				       "failed (%d)\n", dev->core->name, err);
@@ -848,6 +858,8 @@
 		}
 	}
 
+	mutex_unlock(&dev->core->lock);
+
 	/* Destroy any 8802 reference. */
 	dev->core->dvbdev = NULL;
 
diff -druN linux-2.6.39-libre/drivers/media/video/cx88/cx88-video.c linux-3.0-rc7-libre/drivers/media/video/cx88/cx88-video.c
--- linux-2.6.39-libre/drivers/media/video/cx88/cx88-video.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/video/cx88/cx88-video.c	2011-07-11 19:51:52.000000000 -0400
@@ -824,7 +824,7 @@
 		call_all(core, tuner, s_radio);
 	}
 
-	atomic_inc(&core->users);
+	core->users++;
 	mutex_unlock(&core->lock);
 
 	return 0;
@@ -922,7 +922,8 @@
 	file->private_data = NULL;
 	kfree(fh);
 
-	if(atomic_dec_and_test(&dev->core->users))
+	dev->core->users--;
+	if (!dev->core->users)
 		call_all(dev->core, core, s_power, 0);
 	mutex_unlock(&dev->core->lock);
 
@@ -1832,7 +1833,7 @@
 	dev->core = core;
 
 	/* print pci info */
-	pci_read_config_byte(pci_dev, PCI_CLASS_REVISION, &dev->pci_rev);
+	dev->pci_rev = pci_dev->revision;
 	pci_read_config_byte(pci_dev, PCI_LATENCY_TIMER,  &dev->pci_lat);
 	printk(KERN_INFO "%s/0: found at %s, rev: %d, irq: %d, "
 	       "latency: %d, mmio: 0x%llx\n", core->name,
diff -druN linux-2.6.39-libre/drivers/media/video/em28xx/em28xx-cards.c linux-3.0-rc7-libre/drivers/media/video/em28xx/em28xx-cards.c
--- linux-2.6.39-libre/drivers/media/video/em28xx/em28xx-cards.c	2011-05-19 02:08:16.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/video/em28xx/em28xx-cards.c	2011-07-21 06:50:33.000000000 -0400
@@ -100,6 +100,13 @@
 	{ -1,			-1,	-1,		-1},
 };
 
+/* Board Hauppauge WinTV HVR 900 (R2) digital */
+static struct em28xx_reg_seq hauppauge_wintv_hvr_900R2_digital[] = {
+	{EM28XX_R08_GPIO,	0x2e,	~EM_GPIO_4,	10},
+	{EM2880_R04_GPO,	0x0c,	0x0f,		10},
+	{ -1,			-1,	-1,		-1},
+};
+
 /* Boards - EM2880 MSI DIGIVOX AD and EM2880_BOARD_MSI_DIGIVOX_AD_II */
 static struct em28xx_reg_seq em2880_msi_digivox_ad_analog[] = {
 	{EM28XX_R08_GPIO,       0x69,   ~EM_GPIO_4,	 10},
@@ -282,6 +289,16 @@
 	{	-1,		-1,	-1,	-1},
 };
 
+/* 2013:024f PCTV Systems nanoStick T2 290e
+ * GPIO_6 - demod reset
+ * GPIO_7 - LED
+ */
+static struct em28xx_reg_seq pctv_290e[] = {
+	{EM2874_R80_GPIO,	0x00,	0xff,		80},
+	{EM2874_R80_GPIO,	0x40,	0xff,		80}, /* GPIO_6 = 1 */
+	{EM2874_R80_GPIO,	0xc0,	0xff,		80}, /* GPIO_7 = 1 */
+	{-1,			-1,	-1,		-1},
+};
 
 /*
  *  Board definitions
@@ -859,6 +876,8 @@
 		.tuner_type   = TUNER_XC2028,
 		.tuner_gpio   = default_tuner_gpio,
 		.mts_firmware = 1,
+		.has_dvb      = 1,
+		.dvb_gpio     = hauppauge_wintv_hvr_900R2_digital,
 		.ir_codes     = RC_MAP_HAUPPAUGE,
 		.decoder      = EM28XX_TVP5150,
 		.input        = { {
@@ -1448,12 +1467,14 @@
 			.gpio     = pinnacle_hybrid_pro_analog,
 		} },
 	},
-	[EM2882_BOARD_PINNACLE_HYBRID_PRO] = {
-		.name         = "Pinnacle Hybrid Pro (2)",
-		.valid        = EM28XX_BOARD_NOT_VALIDATED,
+	[EM2882_BOARD_PINNACLE_HYBRID_PRO_330E] = {
+		.name         = "Pinnacle Hybrid Pro (330e)",
 		.tuner_type   = TUNER_XC2028,
 		.tuner_gpio   = default_tuner_gpio,
 		.mts_firmware = 1,
+		.has_dvb      = 1,
+		.dvb_gpio     = hauppauge_wintv_hvr_900R2_digital,
+		.ir_codes     = RC_MAP_PINNACLE_PCTV_HD,
 		.decoder      = EM28XX_TVP5150,
 		.input        = { {
 			.type     = EM28XX_VMUX_TELEVISION,
@@ -1749,6 +1770,17 @@
 		.dvb_gpio   = kworld_a340_digital,
 		.tuner_gpio = default_tuner_gpio,
 	},
+	/* 2013:024f PCTV Systems nanoStick T2 290e.
+	 * Empia EM28174, Sony CXD2820R and NXP TDA18271HD/C2 */
+	[EM28174_BOARD_PCTV_290E] = {
+		.i2c_speed      = EM2874_I2C_SECONDARY_BUS_SELECT |
+			EM28XX_I2C_CLK_WAIT_ENABLE | EM28XX_I2C_FREQ_100_KHZ,
+		.xclk          = EM28XX_XCLK_FREQUENCY_12MHZ,
+		.name          = "PCTV Systems nanoStick T2 290e",
+		.tuner_type    = TUNER_ABSENT,
+		.tuner_gpio    = pctv_290e,
+		.has_dvb       = 1,
+	},
 };
 const unsigned int em28xx_bcount = ARRAY_SIZE(em28xx_boards);
 
@@ -1863,7 +1895,7 @@
 	{ USB_DEVICE(0x2304, 0x021a),
 			.driver_info = EM2820_BOARD_PINNACLE_DVC_90 },
 	{ USB_DEVICE(0x2304, 0x0226),
-			.driver_info = EM2882_BOARD_PINNACLE_HYBRID_PRO },
+			.driver_info = EM2882_BOARD_PINNACLE_HYBRID_PRO_330E },
 	{ USB_DEVICE(0x2304, 0x0227),
 			.driver_info = EM2880_BOARD_PINNACLE_PCTV_HD_PRO },
 	{ USB_DEVICE(0x0413, 0x6023),
@@ -1876,6 +1908,8 @@
 			.driver_info = EM2860_BOARD_GADMEI_UTV330 },
 	{ USB_DEVICE(0x1b80, 0xa340),
 			.driver_info = EM2870_BOARD_KWORLD_A340 },
+	{ USB_DEVICE(0x2013, 0x024f),
+			.driver_info = EM28174_BOARD_PCTV_290E },
 	{ },
 };
 MODULE_DEVICE_TABLE(usb, em28xx_id_table);
@@ -2229,7 +2263,7 @@
 		ctl->demod = XC3028_FE_ZARLINK456;
 		break;
 	case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900_R2:
-		/* djh - Not sure which demod we need here */
+	case EM2882_BOARD_PINNACLE_HYBRID_PRO_330E:
 		ctl->demod = XC3028_FE_DEFAULT;
 		break;
 	case EM2880_BOARD_AMD_ATI_TV_WONDER_HD_600:
@@ -2799,6 +2833,11 @@
 			dev->reg_gpio_num = EM2874_R80_GPIO;
 			dev->wait_after_write = 0;
 			break;
+		case CHIP_ID_EM28174:
+			em28xx_info("chip ID is em28174\n");
+			dev->reg_gpio_num = EM2874_R80_GPIO;
+			dev->wait_after_write = 0;
+			break;
 		case CHIP_ID_EM2883:
 			em28xx_info("chip ID is em2882/em2883\n");
 			dev->wait_after_write = 0;
diff -druN linux-2.6.39-libre/drivers/media/video/em28xx/em28xx-core.c linux-3.0-rc7-libre/drivers/media/video/em28xx/em28xx-core.c
--- linux-2.6.39-libre/drivers/media/video/em28xx/em28xx-core.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/video/em28xx/em28xx-core.c	2011-07-11 19:51:52.000000000 -0400
@@ -489,7 +489,8 @@
 	int vid1, vid2, feat, cfg;
 	u32 vid;
 
-	if (dev->chip_id == CHIP_ID_EM2870 || dev->chip_id == CHIP_ID_EM2874) {
+	if (dev->chip_id == CHIP_ID_EM2870 || dev->chip_id == CHIP_ID_EM2874
+		|| dev->chip_id == CHIP_ID_EM28174) {
 		/* Digital only device - don't load any alsa module */
 		dev->audio_mode.has_audio = 0;
 		dev->has_audio_class = 0;
@@ -614,7 +615,7 @@
 {
 	int rc;
 
-	if (dev->chip_id == CHIP_ID_EM2874) {
+	if (dev->chip_id == CHIP_ID_EM2874 || dev->chip_id == CHIP_ID_EM28174) {
 		/* The Transport Stream Enable Register moved in em2874 */
 		if (!start) {
 			rc = em28xx_write_reg_bits(dev, EM2874_R5F_TS_ENABLE,
@@ -1111,6 +1112,10 @@
 		/* FIXME - for now assume 564 like it was before, but the
 		   em2874 code should be added to return the proper value... */
 		packet_size = 564;
+	} else if (dev->chip_id == CHIP_ID_EM28174) {
+		/* FIXME same as em2874. 564 was enough for 22 Mbit DVB-T
+		   but too much for 44 Mbit DVB-C. */
+		packet_size = 752;
 	} else {
 		/* TS max packet size stored in bits 1-0 of R01 */
 		chip_cfg2 = em28xx_read_reg(dev, EM28XX_R01_CHIPCFG2);
diff -druN linux-2.6.39-libre/drivers/media/video/em28xx/em28xx-dvb.c linux-3.0-rc7-libre/drivers/media/video/em28xx/em28xx-dvb.c
--- linux-2.6.39-libre/drivers/media/video/em28xx/em28xx-dvb.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/video/em28xx/em28xx-dvb.c	2011-07-11 19:51:52.000000000 -0400
@@ -38,6 +38,8 @@
 #include "tda1002x.h"
 #include "tda18271.h"
 #include "s921.h"
+#include "drxd.h"
+#include "cxd2820r.h"
 
 MODULE_DESCRIPTION("driver for em28xx based DVB cards");
 MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@infradead.org>");
@@ -58,7 +60,7 @@
 #define EM28XX_DVB_MAX_PACKETS 64
 
 struct em28xx_dvb {
-	struct dvb_frontend        *frontend;
+	struct dvb_frontend        *fe[2];
 
 	/* feed count management */
 	struct mutex               lock;
@@ -285,12 +287,13 @@
 	.if2 = 45600,
 };
 
-#ifdef EM28XX_DRX397XD_SUPPORT
-/* [TODO] djh - not sure yet what the device config needs to contain */
-static struct drx397xD_config em28xx_drx397xD_with_xc3028 = {
-	.demod_address = (0xe0 >> 1),
+static struct drxd_config em28xx_drxd = {
+	.index = 0, .demod_address = 0x70, .demod_revision = 0xa2,
+	.demoda_address = 0x00, .pll_address = 0x00,
+	.pll_type = DRXD_PLL_NONE, .clock = 12000, .insert_rs_byte = 1,
+	.pll_set = NULL, .osc_deviation = NULL, .IF = 42800000,
+	.disable_i2c_gate_ctrl = 1,
 };
-#endif
 
 static int mt352_terratec_xs_init(struct dvb_frontend *fe)
 {
@@ -332,6 +335,26 @@
 	.invert = 1,
 };
 
+static struct cxd2820r_config em28xx_cxd2820r_config = {
+	.i2c_address = (0xd8 >> 1),
+	.ts_mode = CXD2820R_TS_SERIAL,
+	.if_dvbt_6  = 3300,
+	.if_dvbt_7  = 3500,
+	.if_dvbt_8  = 4000,
+	.if_dvbt2_6 = 3300,
+	.if_dvbt2_7 = 3500,
+	.if_dvbt2_8 = 4000,
+	.if_dvbc    = 5000,
+
+	/* enable LNA for DVB-T2 and DVB-C */
+	.gpio_dvbt2[0] = CXD2820R_GPIO_E | CXD2820R_GPIO_O | CXD2820R_GPIO_L,
+	.gpio_dvbc[0] = CXD2820R_GPIO_E | CXD2820R_GPIO_O | CXD2820R_GPIO_L,
+};
+
+static struct tda18271_config em28xx_cxd2820r_tda18271_config = {
+	.output_opt = TDA18271_OUTPUT_LT_OFF,
+};
+
 /* ------------------------------------------------------------------ */
 
 static int attach_xc3028(u8 addr, struct em28xx *dev)
@@ -343,17 +366,17 @@
 	cfg.i2c_adap  = &dev->i2c_adap;
 	cfg.i2c_addr  = addr;
 
-	if (!dev->dvb->frontend) {
+	if (!dev->dvb->fe[0]) {
 		em28xx_errdev("/2: dvb frontend not attached. "
 				"Can't attach xc3028\n");
 		return -EINVAL;
 	}
 
-	fe = dvb_attach(xc2028_attach, dev->dvb->frontend, &cfg);
+	fe = dvb_attach(xc2028_attach, dev->dvb->fe[0], &cfg);
 	if (!fe) {
 		em28xx_errdev("/2: xc3028 attach failed\n");
-		dvb_frontend_detach(dev->dvb->frontend);
-		dev->dvb->frontend = NULL;
+		dvb_frontend_detach(dev->dvb->fe[0]);
+		dev->dvb->fe[0] = NULL;
 		return -EINVAL;
 	}
 
@@ -383,16 +406,28 @@
 	}
 
 	/* Ensure all frontends negotiate bus access */
-	dvb->frontend->ops.ts_bus_ctrl = em28xx_dvb_bus_ctrl;
+	dvb->fe[0]->ops.ts_bus_ctrl = em28xx_dvb_bus_ctrl;
+	if (dvb->fe[1])
+		dvb->fe[1]->ops.ts_bus_ctrl = em28xx_dvb_bus_ctrl;
 
 	dvb->adapter.priv = dev;
 
 	/* register frontend */
-	result = dvb_register_frontend(&dvb->adapter, dvb->frontend);
+	result = dvb_register_frontend(&dvb->adapter, dvb->fe[0]);
 	if (result < 0) {
 		printk(KERN_WARNING "%s: dvb_register_frontend failed (errno = %d)\n",
 		       dev->name, result);
-		goto fail_frontend;
+		goto fail_frontend0;
+	}
+
+	/* register 2nd frontend */
+	if (dvb->fe[1]) {
+		result = dvb_register_frontend(&dvb->adapter, dvb->fe[1]);
+		if (result < 0) {
+			printk(KERN_WARNING "%s: 2nd dvb_register_frontend failed (errno = %d)\n",
+				dev->name, result);
+			goto fail_frontend1;
+		}
 	}
 
 	/* register demux stuff */
@@ -458,9 +493,14 @@
 fail_dmxdev:
 	dvb_dmx_release(&dvb->demux);
 fail_dmx:
-	dvb_unregister_frontend(dvb->frontend);
-fail_frontend:
-	dvb_frontend_detach(dvb->frontend);
+	if (dvb->fe[1])
+		dvb_unregister_frontend(dvb->fe[1]);
+	dvb_unregister_frontend(dvb->fe[0]);
+fail_frontend1:
+	if (dvb->fe[1])
+		dvb_frontend_detach(dvb->fe[1]);
+fail_frontend0:
+	dvb_frontend_detach(dvb->fe[0]);
 	dvb_unregister_adapter(&dvb->adapter);
 fail_adapter:
 	return result;
@@ -473,12 +513,15 @@
 	dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_hw);
 	dvb_dmxdev_release(&dvb->dmxdev);
 	dvb_dmx_release(&dvb->demux);
-	dvb_unregister_frontend(dvb->frontend);
-	dvb_frontend_detach(dvb->frontend);
+	if (dvb->fe[1])
+		dvb_unregister_frontend(dvb->fe[1]);
+	dvb_unregister_frontend(dvb->fe[0]);
+	if (dvb->fe[1])
+		dvb_frontend_detach(dvb->fe[1]);
+	dvb_frontend_detach(dvb->fe[0]);
 	dvb_unregister_adapter(&dvb->adapter);
 }
 
-
 static int dvb_init(struct em28xx *dev)
 {
 	int result = 0;
@@ -497,16 +540,17 @@
 		return -ENOMEM;
 	}
 	dev->dvb = dvb;
+	dvb->fe[0] = dvb->fe[1] = NULL;
 
 	mutex_lock(&dev->lock);
 	em28xx_set_mode(dev, EM28XX_DIGITAL_MODE);
 	/* init frontend */
 	switch (dev->model) {
 	case EM2874_LEADERSHIP_ISDBT:
-		dvb->frontend = dvb_attach(s921_attach,
+		dvb->fe[0] = dvb_attach(s921_attach,
 				&sharp_isdbt, &dev->i2c_adap);
 
-		if (!dvb->frontend) {
+		if (!dvb->fe[0]) {
 			result = -EINVAL;
 			goto out_free;
 		}
@@ -516,7 +560,7 @@
 	case EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950:
 	case EM2880_BOARD_PINNACLE_PCTV_HD_PRO:
 	case EM2880_BOARD_AMD_ATI_TV_WONDER_HD_600:
-		dvb->frontend = dvb_attach(lgdt330x_attach,
+		dvb->fe[0] = dvb_attach(lgdt330x_attach,
 					   &em2880_lgdt3303_dev,
 					   &dev->i2c_adap);
 		if (attach_xc3028(0x61, dev) < 0) {
@@ -525,7 +569,7 @@
 		}
 		break;
 	case EM2880_BOARD_KWORLD_DVB_310U:
-		dvb->frontend = dvb_attach(zl10353_attach,
+		dvb->fe[0] = dvb_attach(zl10353_attach,
 					   &em28xx_zl10353_with_xc3028,
 					   &dev->i2c_adap);
 		if (attach_xc3028(0x61, dev) < 0) {
@@ -536,7 +580,7 @@
 	case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900:
 	case EM2882_BOARD_TERRATEC_HYBRID_XS:
 	case EM2880_BOARD_EMPIRE_DUAL_TV:
-		dvb->frontend = dvb_attach(zl10353_attach,
+		dvb->fe[0] = dvb_attach(zl10353_attach,
 					   &em28xx_zl10353_xc3028_no_i2c_gate,
 					   &dev->i2c_adap);
 		if (attach_xc3028(0x61, dev) < 0) {
@@ -549,13 +593,13 @@
 	case EM2881_BOARD_PINNACLE_HYBRID_PRO:
 	case EM2882_BOARD_DIKOM_DK300:
 	case EM2882_BOARD_KWORLD_VS_DVBT:
-		dvb->frontend = dvb_attach(zl10353_attach,
+		dvb->fe[0] = dvb_attach(zl10353_attach,
 					   &em28xx_zl10353_xc3028_no_i2c_gate,
 					   &dev->i2c_adap);
-		if (dvb->frontend == NULL) {
+		if (dvb->fe[0] == NULL) {
 			/* This board could have either a zl10353 or a mt352.
 			   If the chip id isn't for zl10353, try mt352 */
-			dvb->frontend = dvb_attach(mt352_attach,
+			dvb->fe[0] = dvb_attach(mt352_attach,
 						   &terratec_xs_mt352_cfg,
 						   &dev->i2c_adap);
 		}
@@ -567,7 +611,7 @@
 		break;
 	case EM2883_BOARD_KWORLD_HYBRID_330U:
 	case EM2882_BOARD_EVGA_INDTUBE:
-		dvb->frontend = dvb_attach(s5h1409_attach,
+		dvb->fe[0] = dvb_attach(s5h1409_attach,
 					   &em28xx_s5h1409_with_xc3028,
 					   &dev->i2c_adap);
 		if (attach_xc3028(0x61, dev) < 0) {
@@ -576,11 +620,11 @@
 		}
 		break;
 	case EM2882_BOARD_KWORLD_ATSC_315U:
-		dvb->frontend = dvb_attach(lgdt330x_attach,
+		dvb->fe[0] = dvb_attach(lgdt330x_attach,
 					   &em2880_lgdt3303_dev,
 					   &dev->i2c_adap);
-		if (dvb->frontend != NULL) {
-			if (!dvb_attach(simple_tuner_attach, dvb->frontend,
+		if (dvb->fe[0] != NULL) {
+			if (!dvb_attach(simple_tuner_attach, dvb->fe[0],
 				&dev->i2c_adap, 0x61, TUNER_THOMSON_DTT761X)) {
 				result = -EINVAL;
 				goto out_free;
@@ -588,25 +632,21 @@
 		}
 		break;
 	case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900_R2:
-#ifdef EM28XX_DRX397XD_SUPPORT
-		/* We don't have the config structure properly populated, so
-		   this is commented out for now */
-		dvb->frontend = dvb_attach(drx397xD_attach,
-					   &em28xx_drx397xD_with_xc3028,
-					   &dev->i2c_adap);
+	case EM2882_BOARD_PINNACLE_HYBRID_PRO_330E:
+		dvb->fe[0] = dvb_attach(drxd_attach, &em28xx_drxd, NULL,
+					   &dev->i2c_adap, &dev->udev->dev);
 		if (attach_xc3028(0x61, dev) < 0) {
 			result = -EINVAL;
 			goto out_free;
 		}
 		break;
-#endif
 	case EM2870_BOARD_REDDO_DVB_C_USB_BOX:
 		/* Philips CU1216L NIM (Philips TDA10023 + Infineon TUA6034) */
-		dvb->frontend = dvb_attach(tda10023_attach,
+		dvb->fe[0] = dvb_attach(tda10023_attach,
 			&em28xx_tda10023_config,
 			&dev->i2c_adap, 0x48);
-		if (dvb->frontend) {
-			if (!dvb_attach(simple_tuner_attach, dvb->frontend,
+		if (dvb->fe[0]) {
+			if (!dvb_attach(simple_tuner_attach, dvb->fe[0],
 				&dev->i2c_adap, 0x60, TUNER_PHILIPS_CU1216L)) {
 				result = -EINVAL;
 				goto out_free;
@@ -614,25 +654,53 @@
 		}
 		break;
 	case EM2870_BOARD_KWORLD_A340:
-		dvb->frontend = dvb_attach(lgdt3305_attach,
+		dvb->fe[0] = dvb_attach(lgdt3305_attach,
 					   &em2870_lgdt3304_dev,
 					   &dev->i2c_adap);
-		if (dvb->frontend != NULL)
-			dvb_attach(tda18271_attach, dvb->frontend, 0x60,
+		if (dvb->fe[0] != NULL)
+			dvb_attach(tda18271_attach, dvb->fe[0], 0x60,
 				   &dev->i2c_adap, &kworld_a340_config);
 		break;
+	case EM28174_BOARD_PCTV_290E:
+		/* MFE
+		 * FE 0 = DVB-T/T2 + FE 1 = DVB-C, both sharing same tuner. */
+		/* FE 0 */
+		dvb->fe[0] = dvb_attach(cxd2820r_attach,
+			&em28xx_cxd2820r_config, &dev->i2c_adap, NULL);
+		if (dvb->fe[0]) {
+			struct i2c_adapter *i2c_tuner;
+			i2c_tuner = cxd2820r_get_tuner_i2c_adapter(dvb->fe[0]);
+			/* FE 0 attach tuner */
+			if (!dvb_attach(tda18271_attach, dvb->fe[0], 0x60,
+				i2c_tuner, &em28xx_cxd2820r_tda18271_config)) {
+				dvb_frontend_detach(dvb->fe[0]);
+				result = -EINVAL;
+				goto out_free;
+			}
+			/* FE 1. This dvb_attach() cannot fail. */
+			dvb->fe[1] = dvb_attach(cxd2820r_attach, NULL, NULL,
+				dvb->fe[0]);
+			dvb->fe[1]->id = 1;
+			/* FE 1 attach tuner */
+			if (!dvb_attach(tda18271_attach, dvb->fe[1], 0x60,
+				i2c_tuner, &em28xx_cxd2820r_tda18271_config)) {
+				dvb_frontend_detach(dvb->fe[1]);
+				/* leave FE 0 still active */
+			}
+		}
+		break;
 	default:
 		em28xx_errdev("/2: The frontend of your DVB/ATSC card"
 				" isn't supported yet\n");
 		break;
 	}
-	if (NULL == dvb->frontend) {
+	if (NULL == dvb->fe[0]) {
 		em28xx_errdev("/2: frontend initialization failed\n");
 		result = -EINVAL;
 		goto out_free;
 	}
 	/* define general-purpose callback pointer */
-	dvb->frontend->callback = em28xx_tuner_callback;
+	dvb->fe[0]->callback = em28xx_tuner_callback;
 
 	/* register everything */
 	result = register_dvb(dvb, THIS_MODULE, dev, &dev->udev->dev);
diff -druN linux-2.6.39-libre/drivers/media/video/em28xx/em28xx.h linux-3.0-rc7-libre/drivers/media/video/em28xx/em28xx.h
--- linux-2.6.39-libre/drivers/media/video/em28xx/em28xx.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/video/em28xx/em28xx.h	2011-07-11 19:51:52.000000000 -0400
@@ -97,7 +97,7 @@
 #define EM2881_BOARD_PINNACLE_HYBRID_PRO	  53
 #define EM2882_BOARD_KWORLD_VS_DVBT		  54
 #define EM2882_BOARD_TERRATEC_HYBRID_XS		  55
-#define EM2882_BOARD_PINNACLE_HYBRID_PRO	  56
+#define EM2882_BOARD_PINNACLE_HYBRID_PRO_330E	  56
 #define EM2883_BOARD_KWORLD_HYBRID_330U                  57
 #define EM2820_BOARD_COMPRO_VIDEOMATE_FORYOU	  58
 #define EM2883_BOARD_HAUPPAUGE_WINTV_HVR_850	  60
@@ -118,6 +118,7 @@
 #define EM2882_BOARD_DIKOM_DK300		  75
 #define EM2870_BOARD_KWORLD_A340		  76
 #define EM2874_LEADERSHIP_ISDBT			  77
+#define EM28174_BOARD_PCTV_290E                   78
 
 
 /* Limits minimum and default number of buffers */
diff -druN linux-2.6.39-libre/drivers/media/video/em28xx/em28xx-i2c.c linux-3.0-rc7-libre/drivers/media/video/em28xx/em28xx-i2c.c
--- linux-2.6.39-libre/drivers/media/video/em28xx/em28xx-i2c.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/video/em28xx/em28xx-i2c.c	2011-07-11 19:51:52.000000000 -0400
@@ -332,7 +332,7 @@
 	struct em28xx_eeprom *em_eeprom = (void *)eedata;
 	int i, err, size = len, block;
 
-	if (dev->chip_id == CHIP_ID_EM2874) {
+	if (dev->chip_id == CHIP_ID_EM2874 || dev->chip_id == CHIP_ID_EM28174) {
 		/* Empia switched to a 16-bit addressable eeprom in newer
 		   devices.  While we could certainly write a routine to read
 		   the eeprom, there is nothing of use in there that cannot be
diff -druN linux-2.6.39-libre/drivers/media/video/em28xx/em28xx-reg.h linux-3.0-rc7-libre/drivers/media/video/em28xx/em28xx-reg.h
--- linux-2.6.39-libre/drivers/media/video/em28xx/em28xx-reg.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/video/em28xx/em28xx-reg.h	2011-07-11 19:51:52.000000000 -0400
@@ -201,6 +201,7 @@
 	CHIP_ID_EM2870 = 35,
 	CHIP_ID_EM2883 = 36,
 	CHIP_ID_EM2874 = 65,
+	CHIP_ID_EM28174 = 113,
 };
 
 /*
diff -druN linux-2.6.39-libre/drivers/media/video/em28xx/Kconfig linux-3.0-rc7-libre/drivers/media/video/em28xx/Kconfig
--- linux-2.6.39-libre/drivers/media/video/em28xx/Kconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/video/em28xx/Kconfig	2011-07-11 19:51:52.000000000 -0400
@@ -38,6 +38,8 @@
 	select DVB_ZL10353 if !DVB_FE_CUSTOMISE
 	select DVB_TDA10023 if !DVB_FE_CUSTOMISE
 	select DVB_S921 if !DVB_FE_CUSTOMISE
+	select DVB_DRXD if !DVB_FE_CUSTOMISE
+	select DVB_CXD2820R if !DVB_FE_CUSTOMISE
 	select VIDEOBUF_DVB
 	---help---
 	  This adds support for DVB cards based on the
diff -druN linux-2.6.39-libre/drivers/media/video/fsl-viu.c linux-3.0-rc7-libre/drivers/media/video/fsl-viu.c
--- linux-2.6.39-libre/drivers/media/video/fsl-viu.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/video/fsl-viu.c	2011-07-11 19:51:52.000000000 -0400
@@ -766,7 +766,7 @@
 	out_be32(&vr->picture_count, reg_val.picture_count);
 }
 
-static int viu_start_preview(struct viu_dev *dev, struct viu_fh *fh)
+static int viu_setup_preview(struct viu_dev *dev, struct viu_fh *fh)
 {
 	int bpp;
 
@@ -805,11 +805,6 @@
 	/* setup the base address of the overlay buffer */
 	reg_val.field_base_addr = (u32)dev->ovbuf.base;
 
-	dev->ovenable = 1;
-	viu_activate_overlay(dev->vr);
-
-	/* start dma */
-	viu_start_dma(dev);
 	return 0;
 }
 
@@ -825,13 +820,11 @@
 	if (err)
 		return err;
 
-	mutex_lock(&dev->lock);
 	fh->win = f->fmt.win;
 
 	spin_lock_irqsave(&dev->slock, flags);
-	viu_start_preview(dev, fh);
+	viu_setup_preview(dev, fh);
 	spin_unlock_irqrestore(&dev->slock, flags);
-	mutex_unlock(&dev->lock);
 	return 0;
 }
 
@@ -841,6 +834,28 @@
 	return 0;
 }
 
+static int vidioc_overlay(struct file *file, void *priv, unsigned int on)
+{
+	struct viu_fh  *fh  = priv;
+	struct viu_dev *dev = (struct viu_dev *)fh->dev;
+	unsigned long  flags;
+
+	if (on) {
+		spin_lock_irqsave(&dev->slock, flags);
+		viu_activate_overlay(dev->vr);
+		dev->ovenable = 1;
+
+		/* start dma */
+		viu_start_dma(dev);
+		spin_unlock_irqrestore(&dev->slock, flags);
+	} else {
+		viu_stop_dma(dev);
+		dev->ovenable = 0;
+	}
+
+	return 0;
+}
+
 int vidioc_g_fbuf(struct file *file, void *priv, struct v4l2_framebuffer *arg)
 {
 	struct viu_fh  *fh = priv;
@@ -911,12 +926,16 @@
 static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
 {
 	struct viu_fh *fh = priv;
+	struct viu_dev *dev = fh->dev;
 
 	if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
 		return -EINVAL;
 	if (fh->type != i)
 		return -EINVAL;
 
+	if (dev->ovenable)
+		dev->ovenable = 0;
+
 	viu_start_dma(fh->dev);
 
 	return videobuf_streamon(&fh->vb_vidq);
@@ -1311,7 +1330,8 @@
 	videobuf_queue_dma_contig_init(&fh->vb_vidq, &viu_video_qops,
 				       dev->dev, &fh->vbq_lock,
 				       fh->type, V4L2_FIELD_INTERLACED,
-				       sizeof(struct viu_buf), fh, NULL);
+				       sizeof(struct viu_buf), fh,
+				       &fh->dev->lock);
 	return 0;
 }
 
@@ -1401,7 +1421,7 @@
 	.release	= viu_release,
 	.read		= viu_read,
 	.poll		= viu_poll,
-	.ioctl		= video_ioctl2, /* V4L2 ioctl handler */
+	.unlocked_ioctl	= video_ioctl2, /* V4L2 ioctl handler */
 	.mmap		= viu_mmap,
 };
 
@@ -1415,6 +1435,7 @@
 	.vidioc_g_fmt_vid_overlay = vidioc_g_fmt_overlay,
 	.vidioc_try_fmt_vid_overlay = vidioc_try_fmt_overlay,
 	.vidioc_s_fmt_vid_overlay = vidioc_s_fmt_overlay,
+	.vidioc_overlay	      = vidioc_overlay,
 	.vidioc_g_fbuf	      = vidioc_g_fbuf,
 	.vidioc_s_fbuf	      = vidioc_s_fbuf,
 	.vidioc_reqbufs       = vidioc_reqbufs,
@@ -1498,9 +1519,6 @@
 	INIT_LIST_HEAD(&viu_dev->vidq.active);
 	INIT_LIST_HEAD(&viu_dev->vidq.queued);
 
-	/* initialize locks */
-	mutex_init(&viu_dev->lock);
-
 	snprintf(viu_dev->v4l2_dev.name,
 		 sizeof(viu_dev->v4l2_dev.name), "%s", "VIU");
 	ret = v4l2_device_register(viu_dev->dev, &viu_dev->v4l2_dev);
@@ -1531,8 +1549,15 @@
 
 	viu_dev->vdev = vdev;
 
+	/* initialize locks */
+	mutex_init(&viu_dev->lock);
+	viu_dev->vdev->lock = &viu_dev->lock;
+	spin_lock_init(&viu_dev->slock);
+
 	video_set_drvdata(viu_dev->vdev, viu_dev);
 
+	mutex_lock(&viu_dev->lock);
+
 	ret = video_register_device(viu_dev->vdev, VFL_TYPE_GRABBER, -1);
 	if (ret < 0) {
 		video_device_release(viu_dev->vdev);
@@ -1559,6 +1584,8 @@
 		goto err_irq;
 	}
 
+	mutex_unlock(&viu_dev->lock);
+
 	dev_info(&op->dev, "Freescale VIU Video Capture Board\n");
 	return ret;
 
@@ -1568,6 +1595,7 @@
 err_clk:
 	video_unregister_device(viu_dev->vdev);
 err_vdev:
+	mutex_unlock(&viu_dev->lock);
 	i2c_put_adapter(ad);
 	v4l2_device_unregister(&viu_dev->v4l2_dev);
 err:
diff -druN linux-2.6.39-libre/drivers/media/video/gspca/coarse_expo_autogain.h linux-3.0-rc7-libre/drivers/media/video/gspca/coarse_expo_autogain.h
--- linux-2.6.39-libre/drivers/media/video/gspca/coarse_expo_autogain.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/video/gspca/coarse_expo_autogain.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,116 +0,0 @@
-/*
- * 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 -druN linux-2.6.39-libre/drivers/media/video/gspca/cpia1.c linux-3.0-rc7-libre/drivers/media/video/gspca/cpia1.c
--- linux-2.6.39-libre/drivers/media/video/gspca/cpia1.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/video/gspca/cpia1.c	2011-07-11 19:51:52.000000000 -0400
@@ -1262,7 +1262,7 @@
 static void monitor_exposure(struct gspca_dev *gspca_dev)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
-	u8 exp_acc, bcomp, gain, coarseL, cmd[8];
+	u8 exp_acc, bcomp, cmd[8];
 	int ret, light_exp, dark_exp, very_dark_exp;
 	int old_exposure, new_exposure, framerate;
 	int setfps = 0, setexp = 0, setflicker = 0;
@@ -1284,8 +1284,6 @@
 	}
 	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;
@@ -1772,9 +1770,7 @@
 /* this function is called at probe and resume time */
 static int sd_init(struct gspca_dev *gspca_dev)
 {
-#ifdef GSPCA_DEBUG
 	struct sd *sd = (struct sd *) gspca_dev;
-#endif
 	int ret;
 
 	/* Start / Stop the camera to make sure we are talking to
diff -druN linux-2.6.39-libre/drivers/media/video/gspca/gl860/gl860.c linux-3.0-rc7-libre/drivers/media/video/gspca/gl860/gl860.c
--- linux-2.6.39-libre/drivers/media/video/gspca/gl860/gl860.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/video/gspca/gl860/gl860.c	2011-07-11 19:51:52.000000000 -0400
@@ -499,21 +499,8 @@
 static int sd_probe(struct usb_interface *intf,
 				const struct usb_device_id *id)
 {
-	struct gspca_dev *gspca_dev;
-	s32 ret;
-
-	ret = gspca_dev_probe(intf, id,
+	return gspca_dev_probe(intf, id,
 			&sd_desc_mi1320, sizeof(struct sd), THIS_MODULE);
-
-	if (ret >= 0) {
-		gspca_dev = usb_get_intfdata(intf);
-
-		PDEBUG(D_PROBE,
-			"Camera is now controlling video device %s",
-			video_device_node_name(&gspca_dev->vdev));
-	}
-
-	return ret;
 }
 
 static void sd_disconnect(struct usb_interface *intf)
diff -druN linux-2.6.39-libre/drivers/media/video/gspca/gspca.c linux-3.0-rc7-libre/drivers/media/video/gspca/gspca.c
--- linux-2.6.39-libre/drivers/media/video/gspca/gspca.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/video/gspca/gspca.c	2011-07-11 19:51:52.000000000 -0400
@@ -55,7 +55,7 @@
 MODULE_DESCRIPTION("GSPCA USB Camera Driver");
 MODULE_LICENSE("GPL");
 
-#define DRIVER_VERSION_NUMBER	KERNEL_VERSION(2, 12, 0)
+#define DRIVER_VERSION_NUMBER	KERNEL_VERSION(2, 13, 0)
 
 #ifdef GSPCA_DEBUG
 int gspca_debug = D_ERR | D_PROBE;
@@ -2495,6 +2495,6 @@
 module_param_named(debug, gspca_debug, int, 0644);
 MODULE_PARM_DESC(debug,
 		"Debug (bit) 0x01:error 0x02:probe 0x04:config"
-		" 0x08:stream 0x10:frame 0x20:packet 0x40:USBin 0x80:USBout"
+		" 0x08:stream 0x10:frame 0x20:packet"
 		" 0x0100: v4l2");
 #endif
diff -druN linux-2.6.39-libre/drivers/media/video/gspca/gspca.h linux-3.0-rc7-libre/drivers/media/video/gspca/gspca.h
--- linux-2.6.39-libre/drivers/media/video/gspca/gspca.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/video/gspca/gspca.h	2011-07-11 19:51:52.000000000 -0400
@@ -9,7 +9,7 @@
 #include <linux/mutex.h>
 
 /* compilation option */
-#define GSPCA_DEBUG 1
+/*#define GSPCA_DEBUG 1*/
 
 #ifdef GSPCA_DEBUG
 /* GSPCA our debug messages */
@@ -25,8 +25,8 @@
 #define D_STREAM 0x08
 #define D_FRAM 0x10
 #define D_PACK 0x20
-#define D_USBI 0x40
-#define D_USBO 0x80
+#define D_USBI 0x00
+#define D_USBO 0x00
 #define D_V4L2 0x0100
 #else
 #define PDEBUG(level, fmt, args...)
diff -druN linux-2.6.39-libre/drivers/media/video/gspca/jeilinj.c linux-3.0-rc7-libre/drivers/media/video/gspca/jeilinj.c
--- linux-2.6.39-libre/drivers/media/video/gspca/jeilinj.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/video/gspca/jeilinj.c	2011-07-11 19:51:52.000000000 -0400
@@ -6,6 +6,9 @@
  *
  * Copyright (C) 2009 Theodore Kilgore
  *
+ * Sportscam DV15 support and control settings are
+ * Copyright (C) 2011 Patrice Chotard
+ *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation; either version 2 of the License, or
@@ -23,7 +26,6 @@
 
 #define MODULE_NAME "jeilinj"
 
-#include <linux/workqueue.h>
 #include <linux/slab.h>
 #include "gspca.h"
 #include "jpeg.h"
@@ -34,29 +36,51 @@
 
 /* Default timeouts, in ms */
 #define JEILINJ_CMD_TIMEOUT 500
+#define JEILINJ_CMD_DELAY 160
 #define JEILINJ_DATA_TIMEOUT 1000
 
 /* Maximum transfer size to use. */
 #define JEILINJ_MAX_TRANSFER 0x200
-
 #define FRAME_HEADER_LEN 0x10
+#define FRAME_START 0xFFFFFFFF
+
+enum {
+	SAKAR_57379,
+	SPORTSCAM_DV15,
+};
+
+#define CAMQUALITY_MIN 0	/* highest cam quality */
+#define CAMQUALITY_MAX 97	/* lowest cam quality  */
+
+enum e_ctrl {
+	LIGHTFREQ,
+	AUTOGAIN,
+	RED,
+	GREEN,
+	BLUE,
+	NCTRLS		/* number of controls */
+};
 
 /* Structure to hold all of our device specific stuff */
 struct sd {
 	struct gspca_dev gspca_dev;	/* !! must be the first item */
+	struct gspca_ctrl ctrls[NCTRLS];
+	int blocks_left;
 	const struct v4l2_pix_format *cap_mode;
 	/* Driver stuff */
-	struct work_struct work_struct;
-	struct workqueue_struct *work_thread;
+	u8 type;
 	u8 quality;				 /* image quality */
-	u8 jpegqual;				/* webcam quality */
+#define QUALITY_MIN 35
+#define QUALITY_MAX 85
+#define QUALITY_DEF 85
 	u8 jpeg_hdr[JPEG_HDR_SZ];
 };
 
-	struct jlj_command {
-		unsigned char instruction[2];
-		unsigned char ack_wanted;
-	};
+struct jlj_command {
+	unsigned char instruction[2];
+	unsigned char ack_wanted;
+	unsigned char delay;
+};
 
 /* AFAICT these cameras will only do 320x240. */
 static struct v4l2_pix_format jlj_mode[] = {
@@ -64,6 +88,11 @@
 		.bytesperline = 320,
 		.sizeimage = 320 * 240,
 		.colorspace = V4L2_COLORSPACE_JPEG,
+		.priv = 0},
+	{ 640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
+		.bytesperline = 640,
+		.sizeimage = 640 * 480,
+		.colorspace = V4L2_COLORSPACE_JPEG,
 		.priv = 0}
 };
 
@@ -73,178 +102,295 @@
  */
 
 /* All commands are two bytes only */
-static int jlj_write2(struct gspca_dev *gspca_dev, unsigned char *command)
+static void jlj_write2(struct gspca_dev *gspca_dev, unsigned char *command)
 {
 	int retval;
 
+	if (gspca_dev->usb_err < 0)
+		return;
 	memcpy(gspca_dev->usb_buf, command, 2);
 	retval = usb_bulk_msg(gspca_dev->dev,
 			usb_sndbulkpipe(gspca_dev->dev, 3),
 			gspca_dev->usb_buf, 2, NULL, 500);
-	if (retval < 0)
+	if (retval < 0) {
 		err("command write [%02x] error %d",
 				gspca_dev->usb_buf[0], retval);
-	return retval;
+		gspca_dev->usb_err = retval;
+	}
 }
 
 /* Responses are one byte only */
-static int jlj_read1(struct gspca_dev *gspca_dev, unsigned char response)
+static void jlj_read1(struct gspca_dev *gspca_dev, unsigned char response)
 {
 	int retval;
 
+	if (gspca_dev->usb_err < 0)
+		return;
 	retval = usb_bulk_msg(gspca_dev->dev,
 	usb_rcvbulkpipe(gspca_dev->dev, 0x84),
 				gspca_dev->usb_buf, 1, NULL, 500);
 	response = gspca_dev->usb_buf[0];
-	if (retval < 0)
+	if (retval < 0) {
 		err("read command [%02x] error %d",
 				gspca_dev->usb_buf[0], retval);
-	return retval;
+		gspca_dev->usb_err = retval;
+	}
 }
 
-static int jlj_start(struct gspca_dev *gspca_dev)
+static void setfreq(struct gspca_dev *gspca_dev)
 {
-	int i;
-	int retval = -1;
-	u8 response = 0xff;
-	struct jlj_command start_commands[] = {
-		{{0x71, 0x81}, 0},
-		{{0x70, 0x05}, 0},
-		{{0x95, 0x70}, 1},
-		{{0x71, 0x81}, 0},
-		{{0x70, 0x04}, 0},
-		{{0x95, 0x70}, 1},
-		{{0x71, 0x00}, 0},
-		{{0x70, 0x08}, 0},
-		{{0x95, 0x70}, 1},
-		{{0x94, 0x02}, 0},
-		{{0xde, 0x24}, 0},
-		{{0x94, 0x02}, 0},
-		{{0xdd, 0xf0}, 0},
-		{{0x94, 0x02}, 0},
-		{{0xe3, 0x2c}, 0},
-		{{0x94, 0x02}, 0},
-		{{0xe4, 0x00}, 0},
-		{{0x94, 0x02}, 0},
-		{{0xe5, 0x00}, 0},
-		{{0x94, 0x02}, 0},
-		{{0xe6, 0x2c}, 0},
-		{{0x94, 0x03}, 0},
-		{{0xaa, 0x00}, 0},
-		{{0x71, 0x1e}, 0},
-		{{0x70, 0x06}, 0},
-		{{0x71, 0x80}, 0},
-		{{0x70, 0x07}, 0}
+	struct sd *sd = (struct sd *) gspca_dev;
+	u8 freq_commands[][2] = {
+		{0x71, 0x80},
+		{0x70, 0x07}
 	};
-	for (i = 0; i < ARRAY_SIZE(start_commands); i++) {
-		retval = jlj_write2(gspca_dev, start_commands[i].instruction);
-		if (retval < 0)
-			return retval;
-		if (start_commands[i].ack_wanted)
-			retval = jlj_read1(gspca_dev, response);
-		if (retval < 0)
-			return retval;
-	}
-	PDEBUG(D_ERR, "jlj_start retval is %d", retval);
-	return retval;
+
+	freq_commands[0][1] |= (sd->ctrls[LIGHTFREQ].val >> 1);
+
+	jlj_write2(gspca_dev, freq_commands[0]);
+	jlj_write2(gspca_dev, freq_commands[1]);
 }
 
-static int jlj_stop(struct gspca_dev *gspca_dev)
+static void setcamquality(struct gspca_dev *gspca_dev)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+	u8 quality_commands[][2] = {
+		{0x71, 0x1E},
+		{0x70, 0x06}
+	};
+	u8 camquality;
+
+	/* adapt camera quality from jpeg quality */
+	camquality = ((QUALITY_MAX - sd->quality) * CAMQUALITY_MAX)
+		/ (QUALITY_MAX - QUALITY_MIN);
+	quality_commands[0][1] += camquality;
+
+	jlj_write2(gspca_dev, quality_commands[0]);
+	jlj_write2(gspca_dev, quality_commands[1]);
+}
+
+static void setautogain(struct gspca_dev *gspca_dev)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+	u8 autogain_commands[][2] = {
+		{0x94, 0x02},
+		{0xcf, 0x00}
+	};
+
+	autogain_commands[1][1] = (sd->ctrls[AUTOGAIN].val << 4);
+
+	jlj_write2(gspca_dev, autogain_commands[0]);
+	jlj_write2(gspca_dev, autogain_commands[1]);
+}
+
+static void setred(struct gspca_dev *gspca_dev)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+	u8 setred_commands[][2] = {
+		{0x94, 0x02},
+		{0xe6, 0x00}
+	};
+
+	setred_commands[1][1] = sd->ctrls[RED].val;
+
+	jlj_write2(gspca_dev, setred_commands[0]);
+	jlj_write2(gspca_dev, setred_commands[1]);
+}
+
+static void setgreen(struct gspca_dev *gspca_dev)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+	u8 setgreen_commands[][2] = {
+		{0x94, 0x02},
+		{0xe7, 0x00}
+	};
+
+	setgreen_commands[1][1] = sd->ctrls[GREEN].val;
+
+	jlj_write2(gspca_dev, setgreen_commands[0]);
+	jlj_write2(gspca_dev, setgreen_commands[1]);
+}
+
+static void setblue(struct gspca_dev *gspca_dev)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+	u8 setblue_commands[][2] = {
+		{0x94, 0x02},
+		{0xe9, 0x00}
+	};
+
+	setblue_commands[1][1] = sd->ctrls[BLUE].val;
+
+	jlj_write2(gspca_dev, setblue_commands[0]);
+	jlj_write2(gspca_dev, setblue_commands[1]);
+}
+
+static const struct ctrl sd_ctrls[NCTRLS] = {
+[LIGHTFREQ] = {
+	    {
+		.id      = V4L2_CID_POWER_LINE_FREQUENCY,
+		.type    = V4L2_CTRL_TYPE_MENU,
+		.name    = "Light frequency filter",
+		.minimum = V4L2_CID_POWER_LINE_FREQUENCY_DISABLED, /* 1 */
+		.maximum = V4L2_CID_POWER_LINE_FREQUENCY_60HZ, /* 2 */
+		.step    = 1,
+		.default_value = V4L2_CID_POWER_LINE_FREQUENCY_60HZ,
+	    },
+	    .set_control = setfreq
+	},
+[AUTOGAIN] = {
+	    {
+		.id = V4L2_CID_AUTOGAIN,
+		.type = V4L2_CTRL_TYPE_INTEGER,
+		.name = "Automatic Gain (and Exposure)",
+		.minimum = 0,
+		.maximum = 3,
+		.step = 1,
+#define AUTOGAIN_DEF 0
+		.default_value = AUTOGAIN_DEF,
+	   },
+	   .set_control = setautogain
+	},
+[RED] = {
+	    {
+		.id = V4L2_CID_RED_BALANCE,
+		.type = V4L2_CTRL_TYPE_INTEGER,
+		.name = "red balance",
+		.minimum = 0,
+		.maximum = 3,
+		.step = 1,
+#define RED_BALANCE_DEF 2
+		.default_value = RED_BALANCE_DEF,
+	   },
+	   .set_control = setred
+	},
+
+[GREEN]	= {
+	    {
+		.id = V4L2_CID_GAIN,
+		.type = V4L2_CTRL_TYPE_INTEGER,
+		.name = "green balance",
+		.minimum = 0,
+		.maximum = 3,
+		.step = 1,
+#define GREEN_BALANCE_DEF 2
+		.default_value = GREEN_BALANCE_DEF,
+	   },
+	   .set_control = setgreen
+	},
+[BLUE] = {
+	    {
+		.id = V4L2_CID_BLUE_BALANCE,
+		.type = V4L2_CTRL_TYPE_INTEGER,
+		.name = "blue balance",
+		.minimum = 0,
+		.maximum = 3,
+		.step = 1,
+#define BLUE_BALANCE_DEF 2
+		.default_value = BLUE_BALANCE_DEF,
+	   },
+	   .set_control = setblue
+	},
+};
+
+static int jlj_start(struct gspca_dev *gspca_dev)
 {
 	int i;
-	int retval;
-	struct jlj_command stop_commands[] = {
-		{{0x71, 0x00}, 0},
-		{{0x70, 0x09}, 0},
-		{{0x71, 0x80}, 0},
-		{{0x70, 0x05}, 0}
+	int start_commands_size;
+	u8 response = 0xff;
+	struct sd *sd = (struct sd *) gspca_dev;
+	struct jlj_command start_commands[] = {
+		{{0x71, 0x81}, 0, 0},
+		{{0x70, 0x05}, 0, JEILINJ_CMD_DELAY},
+		{{0x95, 0x70}, 1, 0},
+		{{0x71, 0x81 - gspca_dev->curr_mode}, 0, 0},
+		{{0x70, 0x04}, 0, JEILINJ_CMD_DELAY},
+		{{0x95, 0x70}, 1, 0},
+		{{0x71, 0x00}, 0, 0},   /* start streaming ??*/
+		{{0x70, 0x08}, 0, JEILINJ_CMD_DELAY},
+		{{0x95, 0x70}, 1, 0},
+#define SPORTSCAM_DV15_CMD_SIZE 9
+		{{0x94, 0x02}, 0, 0},
+		{{0xde, 0x24}, 0, 0},
+		{{0x94, 0x02}, 0, 0},
+		{{0xdd, 0xf0}, 0, 0},
+		{{0x94, 0x02}, 0, 0},
+		{{0xe3, 0x2c}, 0, 0},
+		{{0x94, 0x02}, 0, 0},
+		{{0xe4, 0x00}, 0, 0},
+		{{0x94, 0x02}, 0, 0},
+		{{0xe5, 0x00}, 0, 0},
+		{{0x94, 0x02}, 0, 0},
+		{{0xe6, 0x2c}, 0, 0},
+		{{0x94, 0x03}, 0, 0},
+		{{0xaa, 0x00}, 0, 0}
 	};
-	for (i = 0; i < ARRAY_SIZE(stop_commands); i++) {
-		retval = jlj_write2(gspca_dev, stop_commands[i].instruction);
-		if (retval < 0)
-			return retval;
+
+	sd->blocks_left = 0;
+	/* Under Windows, USB spy shows that only the 9 first start
+	 * commands are used for SPORTSCAM_DV15 webcam
+	 */
+	if (sd->type == SPORTSCAM_DV15)
+		start_commands_size = SPORTSCAM_DV15_CMD_SIZE;
+	else
+		start_commands_size = ARRAY_SIZE(start_commands);
+
+	for (i = 0; i < start_commands_size; i++) {
+		jlj_write2(gspca_dev, start_commands[i].instruction);
+		if (start_commands[i].delay)
+			msleep(start_commands[i].delay);
+		if (start_commands[i].ack_wanted)
+			jlj_read1(gspca_dev, response);
 	}
-	return retval;
+	setcamquality(gspca_dev);
+	msleep(2);
+	setfreq(gspca_dev);
+	if (gspca_dev->usb_err < 0)
+		PDEBUG(D_ERR, "Start streaming command failed");
+	return gspca_dev->usb_err;
 }
 
-/* This function is called as a workqueue function and runs whenever the camera
- * is streaming data. Because it is a workqueue function it is allowed to sleep
- * so we can use synchronous USB calls. To avoid possible collisions with other
- * threads attempting to use the camera's USB interface the gspca usb_lock is
- * used when performing the one USB control operation inside the workqueue,
- * which tells the camera to close the stream. In practice the only thing
- * which needs to be protected against is the usb_set_interface call that
- * gspca makes during stream_off. Otherwise the camera doesn't provide any
- * controls that the user could try to change.
- */
-
-static void jlj_dostream(struct work_struct *work)
+static void sd_pkt_scan(struct gspca_dev *gspca_dev,
+			u8 *data, int len)
 {
-	struct sd *dev = container_of(work, struct sd, work_struct);
-	struct gspca_dev *gspca_dev = &dev->gspca_dev;
-	int blocks_left; /* 0x200-sized blocks remaining in current frame. */
-	int act_len;
+	struct sd *sd = (struct sd *) gspca_dev;
 	int packet_type;
-	int ret;
-	u8 *buffer;
+	u32 header_marker;
 
-	buffer = kmalloc(JEILINJ_MAX_TRANSFER, GFP_KERNEL | GFP_DMA);
-	if (!buffer) {
-		err("Couldn't allocate USB buffer");
-		goto quit_stream;
+	PDEBUG(D_STREAM, "Got %d bytes out of %d for Block 0",
+			len, JEILINJ_MAX_TRANSFER);
+	if (len != JEILINJ_MAX_TRANSFER) {
+		PDEBUG(D_PACK, "bad length");
+		goto discard;
 	}
-	while (gspca_dev->present && gspca_dev->streaming) {
-		/*
-		 * Now request data block 0. Line 0 reports the size
-		 * to download, in blocks of size 0x200, and also tells the
-		 * "actual" data size, in bytes, which seems best to ignore.
-		 */
-		ret = usb_bulk_msg(gspca_dev->dev,
-				usb_rcvbulkpipe(gspca_dev->dev, 0x82),
-				buffer, JEILINJ_MAX_TRANSFER, &act_len,
-				JEILINJ_DATA_TIMEOUT);
-		PDEBUG(D_STREAM,
-			"Got %d bytes out of %d for Block 0",
-			act_len, JEILINJ_MAX_TRANSFER);
-		if (ret < 0 || act_len < FRAME_HEADER_LEN)
-			goto quit_stream;
-		blocks_left = buffer[0x0a] - 1;
-		PDEBUG(D_STREAM, "blocks_left = 0x%x", blocks_left);
-
+	/* check if it's start of frame */
+	header_marker = ((u32 *)data)[0];
+	if (header_marker == FRAME_START) {
+		sd->blocks_left = data[0x0a] - 1;
+		PDEBUG(D_STREAM, "blocks_left = 0x%x", sd->blocks_left);
 		/* Start a new frame, and add the JPEG header, first thing */
 		gspca_frame_add(gspca_dev, FIRST_PACKET,
-				dev->jpeg_hdr, JPEG_HDR_SZ);
+				sd->jpeg_hdr, JPEG_HDR_SZ);
 		/* Toss line 0 of data block 0, keep the rest. */
 		gspca_frame_add(gspca_dev, INTER_PACKET,
-				buffer + FRAME_HEADER_LEN,
+				data + FRAME_HEADER_LEN,
 				JEILINJ_MAX_TRANSFER - FRAME_HEADER_LEN);
-
-		while (blocks_left > 0) {
-			if (!gspca_dev->present)
-				goto quit_stream;
-			ret = usb_bulk_msg(gspca_dev->dev,
-				usb_rcvbulkpipe(gspca_dev->dev, 0x82),
-				buffer, JEILINJ_MAX_TRANSFER, &act_len,
-				JEILINJ_DATA_TIMEOUT);
-			if (ret < 0 || act_len < JEILINJ_MAX_TRANSFER)
-				goto quit_stream;
-			PDEBUG(D_STREAM,
-				"%d blocks remaining for frame", blocks_left);
-			blocks_left -= 1;
-			if (blocks_left == 0)
-				packet_type = LAST_PACKET;
-			else
-				packet_type = INTER_PACKET;
-			gspca_frame_add(gspca_dev, packet_type,
-					buffer, JEILINJ_MAX_TRANSFER);
-		}
-	}
-quit_stream:
-	mutex_lock(&gspca_dev->usb_lock);
-	if (gspca_dev->present)
-		jlj_stop(gspca_dev);
-	mutex_unlock(&gspca_dev->usb_lock);
-	kfree(buffer);
+	} else if (sd->blocks_left > 0) {
+		PDEBUG(D_STREAM, "%d blocks remaining for frame",
+				sd->blocks_left);
+		sd->blocks_left -= 1;
+		if (sd->blocks_left == 0)
+			packet_type = LAST_PACKET;
+		else
+			packet_type = INTER_PACKET;
+		gspca_frame_add(gspca_dev, packet_type,
+				data, JEILINJ_MAX_TRANSFER);
+	} else
+		goto discard;
+	return;
+discard:
+	/* Discard data until a new frame starts. */
+	gspca_dev->last_packet_type = DISCARD_PACKET;
 }
 
 /* This function is called at probe time just before sd_init */
@@ -254,78 +400,169 @@
 	struct cam *cam = &gspca_dev->cam;
 	struct sd *dev  = (struct sd *) gspca_dev;
 
-	dev->quality  = 85;
-	dev->jpegqual = 85;
+	dev->type = id->driver_info;
+	gspca_dev->cam.ctrls = dev->ctrls;
+	dev->quality = QUALITY_DEF;
+	dev->ctrls[LIGHTFREQ].def = V4L2_CID_POWER_LINE_FREQUENCY_60HZ;
+	dev->ctrls[RED].def = RED_BALANCE_DEF;
+	dev->ctrls[GREEN].def = GREEN_BALANCE_DEF;
+	dev->ctrls[BLUE].def = BLUE_BALANCE_DEF;
 	PDEBUG(D_PROBE,
 		"JEILINJ camera detected"
 		" (vid/pid 0x%04X:0x%04X)", id->idVendor, id->idProduct);
 	cam->cam_mode = jlj_mode;
-	cam->nmodes = 1;
+	cam->nmodes = ARRAY_SIZE(jlj_mode);
 	cam->bulk = 1;
-	/* We don't use the buffer gspca allocates so make it small. */
-	cam->bulk_size = 32;
-	INIT_WORK(&dev->work_struct, jlj_dostream);
+	cam->bulk_nurbs = 1;
+	cam->bulk_size = JEILINJ_MAX_TRANSFER;
 	return 0;
 }
 
-/* called on streamoff with alt==0 and on disconnect */
-/* the usb_lock is held at entry - restore on exit */
-static void sd_stop0(struct gspca_dev *gspca_dev)
+static void sd_stopN(struct gspca_dev *gspca_dev)
 {
-	struct sd *dev = (struct sd *) gspca_dev;
+	int i;
+	u8 *buf;
+	u8 stop_commands[][2] = {
+		{0x71, 0x00},
+		{0x70, 0x09},
+		{0x71, 0x80},
+		{0x70, 0x05}
+	};
 
-	/* wait for the work queue to terminate */
-	mutex_unlock(&gspca_dev->usb_lock);
-	/* This waits for jlj_dostream to finish */
-	destroy_workqueue(dev->work_thread);
-	dev->work_thread = NULL;
-	mutex_lock(&gspca_dev->usb_lock);
+	for (;;) {
+		/* get the image remaining blocks */
+		usb_bulk_msg(gspca_dev->dev,
+				gspca_dev->urb[0]->pipe,
+				gspca_dev->urb[0]->transfer_buffer,
+				JEILINJ_MAX_TRANSFER, NULL,
+				JEILINJ_DATA_TIMEOUT);
+
+		/* search for 0xff 0xd9  (EOF for JPEG) */
+		i = 0;
+		buf = gspca_dev->urb[0]->transfer_buffer;
+		while ((i < (JEILINJ_MAX_TRANSFER - 1)) &&
+			((buf[i] != 0xff) || (buf[i+1] != 0xd9)))
+			i++;
+
+		if (i != (JEILINJ_MAX_TRANSFER - 1))
+			/* last remaining block found */
+			break;
+		}
+
+	for (i = 0; i < ARRAY_SIZE(stop_commands); i++)
+		jlj_write2(gspca_dev, stop_commands[i]);
 }
 
 /* this function is called at probe and resume time */
 static int sd_init(struct gspca_dev *gspca_dev)
 {
-	return 0;
+	return gspca_dev->usb_err;
 }
 
 /* Set up for getting frames. */
 static int sd_start(struct gspca_dev *gspca_dev)
 {
 	struct sd *dev = (struct sd *) gspca_dev;
-	int ret;
 
 	/* create the JPEG header */
 	jpeg_define(dev->jpeg_hdr, gspca_dev->height, gspca_dev->width,
 			0x21);          /* JPEG 422 */
 	jpeg_set_qual(dev->jpeg_hdr, dev->quality);
-	PDEBUG(D_STREAM, "Start streaming at 320x240");
-	ret = jlj_start(gspca_dev);
-	if (ret < 0) {
-		PDEBUG(D_ERR, "Start streaming command failed");
-		return ret;
-	}
-	/* Start the workqueue function to do the streaming */
-	dev->work_thread = create_singlethread_workqueue(MODULE_NAME);
-	queue_work(dev->work_thread, &dev->work_struct);
-
-	return 0;
+	PDEBUG(D_STREAM, "Start streaming at %dx%d",
+		gspca_dev->height, gspca_dev->width);
+	jlj_start(gspca_dev);
+	return gspca_dev->usb_err;
 }
 
 /* Table of supported USB devices */
 static const struct usb_device_id device_table[] = {
-	{USB_DEVICE(0x0979, 0x0280)},
+	{USB_DEVICE(0x0979, 0x0280), .driver_info = SAKAR_57379},
+	{USB_DEVICE(0x0979, 0x0270), .driver_info = SPORTSCAM_DV15},
 	{}
 };
 
 MODULE_DEVICE_TABLE(usb, device_table);
 
+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, "disable");
+			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;
+}
+
+static int sd_set_jcomp(struct gspca_dev *gspca_dev,
+			struct v4l2_jpegcompression *jcomp)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	if (jcomp->quality < QUALITY_MIN)
+		sd->quality = QUALITY_MIN;
+	else if (jcomp->quality > QUALITY_MAX)
+		sd->quality = QUALITY_MAX;
+	else
+		sd->quality = jcomp->quality;
+	if (gspca_dev->streaming) {
+		jpeg_set_qual(sd->jpeg_hdr, sd->quality);
+		setcamquality(gspca_dev);
+	}
+	return 0;
+}
+
+static int sd_get_jcomp(struct gspca_dev *gspca_dev,
+			struct v4l2_jpegcompression *jcomp)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	memset(jcomp, 0, sizeof *jcomp);
+	jcomp->quality = sd->quality;
+	jcomp->jpeg_markers = V4L2_JPEG_MARKER_DHT
+			| V4L2_JPEG_MARKER_DQT;
+	return 0;
+}
+
+
 /* sub-driver description */
-static const struct sd_desc sd_desc = {
+static const struct sd_desc sd_desc_sakar_57379 = {
 	.name   = MODULE_NAME,
 	.config = sd_config,
 	.init   = sd_init,
 	.start  = sd_start,
-	.stop0  = sd_stop0,
+	.stopN  = sd_stopN,
+	.pkt_scan = sd_pkt_scan,
+};
+
+/* sub-driver description */
+static const struct sd_desc sd_desc_sportscam_dv15 = {
+	.name   = MODULE_NAME,
+	.config = sd_config,
+	.init   = sd_init,
+	.start  = sd_start,
+	.stopN  = sd_stopN,
+	.pkt_scan = sd_pkt_scan,
+	.ctrls = sd_ctrls,
+	.nctrls = ARRAY_SIZE(sd_ctrls),
+	.querymenu = sd_querymenu,
+	.get_jcomp = sd_get_jcomp,
+	.set_jcomp = sd_set_jcomp,
+};
+
+static const struct sd_desc *sd_desc[2] = {
+	&sd_desc_sakar_57379,
+	&sd_desc_sportscam_dv15
 };
 
 /* -- device connect -- */
@@ -333,7 +570,7 @@
 		const struct usb_device_id *id)
 {
 	return gspca_dev_probe(intf, id,
-			&sd_desc,
+			sd_desc[id->driver_info],
 			sizeof(struct sd),
 			THIS_MODULE);
 }
diff -druN linux-2.6.39-libre/drivers/media/video/gspca/Kconfig linux-3.0-rc7-libre/drivers/media/video/gspca/Kconfig
--- linux-2.6.39-libre/drivers/media/video/gspca/Kconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/video/gspca/Kconfig	2011-07-11 19:51:52.000000000 -0400
@@ -77,6 +77,15 @@
 	  To compile this driver as a module, choose M here: the
 	  module will be called gspca_jeilinj.
 
+config USB_GSPCA_KINECT
+	tristate "Kinect sensor device USB Camera Driver"
+	depends on VIDEO_V4L2 && USB_GSPCA
+	help
+	  Say Y here if you want support for the Microsoft Kinect sensor device.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called gspca_kinect.
+
 config USB_GSPCA_KONICA
 	tristate "Konica USB Camera V4L2 driver"
 	depends on VIDEO_V4L2 && USB_GSPCA
diff -druN linux-2.6.39-libre/drivers/media/video/gspca/kinect.c linux-3.0-rc7-libre/drivers/media/video/gspca/kinect.c
--- linux-2.6.39-libre/drivers/media/video/gspca/kinect.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/media/video/gspca/kinect.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,429 @@
+/*
+ * kinect sensor device camera, gspca driver
+ *
+ * Copyright (C) 2011  Antonio Ospite <ospite@studenti.unina.it>
+ *
+ * Based on the OpenKinect project and libfreenect
+ * http://openkinect.org/wiki/Init_Analysis
+ *
+ * Special thanks to Steven Toth and kernellabs.com for sponsoring a Kinect
+ * sensor device which I tested the driver on.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * 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 "kinect"
+
+#include "gspca.h"
+
+#define CTRL_TIMEOUT 500
+
+MODULE_AUTHOR("Antonio Ospite <ospite@studenti.unina.it>");
+MODULE_DESCRIPTION("GSPCA/Kinect Sensor Device USB Camera Driver");
+MODULE_LICENSE("GPL");
+
+#ifdef GSPCA_DEBUG
+int gspca_debug = D_ERR | D_PROBE | D_CONF | D_STREAM | D_FRAM | D_PACK |
+	D_USBI | D_USBO | D_V4L2;
+#endif
+
+struct pkt_hdr {
+	uint8_t magic[2];
+	uint8_t pad;
+	uint8_t flag;
+	uint8_t unk1;
+	uint8_t seq;
+	uint8_t unk2;
+	uint8_t unk3;
+	uint32_t timestamp;
+};
+
+struct cam_hdr {
+	uint8_t magic[2];
+	uint16_t len;
+	uint16_t cmd;
+	uint16_t tag;
+};
+
+/* specific webcam descriptor */
+struct sd {
+	struct gspca_dev gspca_dev; /* !! must be the first item */
+	uint16_t cam_tag;           /* a sequence number for packets */
+	uint8_t stream_flag;        /* to identify different stream types */
+	uint8_t obuf[0x400];        /* output buffer for control commands */
+	uint8_t ibuf[0x200];        /* input buffer for control commands */
+};
+
+/* V4L2 controls supported by the driver */
+/* controls prototypes here */
+
+static const struct ctrl sd_ctrls[] = {
+};
+
+#define MODE_640x480   0x0001
+#define MODE_640x488   0x0002
+#define MODE_1280x1024 0x0004
+
+#define FORMAT_BAYER   0x0010
+#define FORMAT_UYVY    0x0020
+#define FORMAT_Y10B    0x0040
+
+#define FPS_HIGH       0x0100
+
+static const struct v4l2_pix_format video_camera_mode[] = {
+	{640, 480, V4L2_PIX_FMT_SGRBG8, V4L2_FIELD_NONE,
+	 .bytesperline = 640,
+	 .sizeimage = 640 * 480,
+	 .colorspace = V4L2_COLORSPACE_SRGB,
+	 .priv = MODE_640x480 | FORMAT_BAYER | FPS_HIGH},
+	{640, 480, V4L2_PIX_FMT_UYVY, V4L2_FIELD_NONE,
+	 .bytesperline = 640 * 2,
+	 .sizeimage = 640 * 480 * 2,
+	 .colorspace = V4L2_COLORSPACE_SRGB,
+	 .priv = MODE_640x480 | FORMAT_UYVY},
+	{1280, 1024, V4L2_PIX_FMT_SGRBG8, V4L2_FIELD_NONE,
+	 .bytesperline = 1280,
+	 .sizeimage = 1280 * 1024,
+	 .colorspace = V4L2_COLORSPACE_SRGB,
+	 .priv = MODE_1280x1024 | FORMAT_BAYER},
+	{640, 488, V4L2_PIX_FMT_Y10BPACK, V4L2_FIELD_NONE,
+	 .bytesperline = 640 * 10 / 8,
+	 .sizeimage =  640 * 488 * 10 / 8,
+	 .colorspace = V4L2_COLORSPACE_SRGB,
+	 .priv = MODE_640x488 | FORMAT_Y10B | FPS_HIGH},
+	{1280, 1024, V4L2_PIX_FMT_Y10BPACK, V4L2_FIELD_NONE,
+	 .bytesperline = 1280 * 10 / 8,
+	 .sizeimage =  1280 * 1024 * 10 / 8,
+	 .colorspace = V4L2_COLORSPACE_SRGB,
+	 .priv = MODE_1280x1024 | FORMAT_Y10B},
+};
+
+static int kinect_write(struct usb_device *udev, uint8_t *data,
+			uint16_t wLength)
+{
+	return usb_control_msg(udev,
+			      usb_sndctrlpipe(udev, 0),
+			      0x00,
+			      USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+			      0, 0, data, wLength, CTRL_TIMEOUT);
+}
+
+static int kinect_read(struct usb_device *udev, uint8_t *data, uint16_t wLength)
+{
+	return usb_control_msg(udev,
+			      usb_rcvctrlpipe(udev, 0),
+			      0x00,
+			      USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+			      0, 0, data, wLength, CTRL_TIMEOUT);
+}
+
+static int send_cmd(struct gspca_dev *gspca_dev, uint16_t cmd, void *cmdbuf,
+		unsigned int cmd_len, void *replybuf, unsigned int reply_len)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+	struct usb_device *udev = gspca_dev->dev;
+	int res, actual_len;
+	uint8_t *obuf = sd->obuf;
+	uint8_t *ibuf = sd->ibuf;
+	struct cam_hdr *chdr = (void *)obuf;
+	struct cam_hdr *rhdr = (void *)ibuf;
+
+	if (cmd_len & 1 || cmd_len > (0x400 - sizeof(*chdr))) {
+		err("send_cmd: Invalid command length (0x%x)", cmd_len);
+		return -1;
+	}
+
+	chdr->magic[0] = 0x47;
+	chdr->magic[1] = 0x4d;
+	chdr->cmd = cpu_to_le16(cmd);
+	chdr->tag = cpu_to_le16(sd->cam_tag);
+	chdr->len = cpu_to_le16(cmd_len / 2);
+
+	memcpy(obuf+sizeof(*chdr), cmdbuf, cmd_len);
+
+	res = kinect_write(udev, obuf, cmd_len + sizeof(*chdr));
+	PDEBUG(D_USBO, "Control cmd=%04x tag=%04x len=%04x: %d", cmd,
+		sd->cam_tag, cmd_len, res);
+	if (res < 0) {
+		err("send_cmd: Output control transfer failed (%d)", res);
+		return res;
+	}
+
+	do {
+		actual_len = kinect_read(udev, ibuf, 0x200);
+	} while (actual_len == 0);
+	PDEBUG(D_USBO, "Control reply: %d", res);
+	if (actual_len < sizeof(*rhdr)) {
+		err("send_cmd: Input control transfer failed (%d)", res);
+		return res;
+	}
+	actual_len -= sizeof(*rhdr);
+
+	if (rhdr->magic[0] != 0x52 || rhdr->magic[1] != 0x42) {
+		err("send_cmd: Bad magic %02x %02x", rhdr->magic[0],
+			rhdr->magic[1]);
+		return -1;
+	}
+	if (rhdr->cmd != chdr->cmd) {
+		err("send_cmd: Bad cmd %02x != %02x", rhdr->cmd, chdr->cmd);
+		return -1;
+	}
+	if (rhdr->tag != chdr->tag) {
+		err("send_cmd: Bad tag %04x != %04x", rhdr->tag, chdr->tag);
+		return -1;
+	}
+	if (cpu_to_le16(rhdr->len) != (actual_len/2)) {
+		err("send_cmd: Bad len %04x != %04x",
+				cpu_to_le16(rhdr->len), (int)(actual_len/2));
+		return -1;
+	}
+
+	if (actual_len > reply_len) {
+		warn("send_cmd: Data buffer is %d bytes long, but got %d bytes",
+				reply_len, actual_len);
+		memcpy(replybuf, ibuf+sizeof(*rhdr), reply_len);
+	} else {
+		memcpy(replybuf, ibuf+sizeof(*rhdr), actual_len);
+	}
+
+	sd->cam_tag++;
+
+	return actual_len;
+}
+
+static int write_register(struct gspca_dev *gspca_dev, uint16_t reg,
+			uint16_t data)
+{
+	uint16_t reply[2];
+	uint16_t cmd[2];
+	int res;
+
+	cmd[0] = cpu_to_le16(reg);
+	cmd[1] = cpu_to_le16(data);
+
+	PDEBUG(D_USBO, "Write Reg 0x%04x <= 0x%02x", reg, data);
+	res = send_cmd(gspca_dev, 0x03, cmd, 4, reply, 4);
+	if (res < 0)
+		return res;
+	if (res != 2) {
+		warn("send_cmd returned %d [%04x %04x], 0000 expected",
+				res, reply[0], reply[1]);
+	}
+	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;
+
+	sd->cam_tag = 0;
+
+	/* Only video stream is supported for now,
+	 * which has stream flag = 0x80 */
+	sd->stream_flag = 0x80;
+
+	cam = &gspca_dev->cam;
+
+	cam->cam_mode = video_camera_mode;
+	cam->nmodes = ARRAY_SIZE(video_camera_mode);
+
+#if 0
+	/* Setting those values is not needed for video stream */
+	cam->npkt = 15;
+	gspca_dev->pkt_size = 960 * 2;
+#endif
+
+	return 0;
+}
+
+/* this function is called at probe and resume time */
+static int sd_init(struct gspca_dev *gspca_dev)
+{
+	PDEBUG(D_PROBE, "Kinect Camera device.");
+
+	return 0;
+}
+
+static int sd_start(struct gspca_dev *gspca_dev)
+{
+	int mode;
+	uint8_t fmt_reg, fmt_val;
+	uint8_t res_reg, res_val;
+	uint8_t fps_reg, fps_val;
+	uint8_t mode_val;
+
+	mode = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv;
+
+	if (mode & FORMAT_Y10B) {
+		fmt_reg = 0x19;
+		res_reg = 0x1a;
+		fps_reg = 0x1b;
+		mode_val = 0x03;
+	} else {
+		fmt_reg = 0x0c;
+		res_reg = 0x0d;
+		fps_reg = 0x0e;
+		mode_val = 0x01;
+	}
+
+	/* format */
+	if (mode & FORMAT_UYVY)
+		fmt_val = 0x05;
+	else
+		fmt_val = 0x00;
+
+	if (mode & MODE_1280x1024)
+		res_val = 0x02;
+	else
+		res_val = 0x01;
+
+	if (mode & FPS_HIGH)
+		fps_val = 0x1e;
+	else
+		fps_val = 0x0f;
+
+
+	/* turn off IR-reset function */
+	write_register(gspca_dev, 0x105, 0x00);
+
+	/* Reset video stream */
+	write_register(gspca_dev, 0x05, 0x00);
+
+	/* Due to some ridiculous condition in the firmware, we have to start
+	 * and stop the depth stream before the camera will hand us 1280x1024
+	 * IR.  This is a stupid workaround, but we've yet to find a better
+	 * solution.
+	 *
+	 * Thanks to Drew Fisher for figuring this out.
+	 */
+	if (mode & (FORMAT_Y10B | MODE_1280x1024)) {
+		write_register(gspca_dev, 0x13, 0x01);
+		write_register(gspca_dev, 0x14, 0x1e);
+		write_register(gspca_dev, 0x06, 0x02);
+		write_register(gspca_dev, 0x06, 0x00);
+	}
+
+	write_register(gspca_dev, fmt_reg, fmt_val);
+	write_register(gspca_dev, res_reg, res_val);
+	write_register(gspca_dev, fps_reg, fps_val);
+
+	/* Start video stream */
+	write_register(gspca_dev, 0x05, mode_val);
+
+	/* disable Hflip */
+	write_register(gspca_dev, 0x47, 0x00);
+
+	return 0;
+}
+
+static void sd_stopN(struct gspca_dev *gspca_dev)
+{
+	/* reset video stream */
+	write_register(gspca_dev, 0x05, 0x00);
+}
+
+static void sd_pkt_scan(struct gspca_dev *gspca_dev, u8 *__data, int len)
+{
+	struct sd *sd = (struct sd *) gspca_dev;
+
+	struct pkt_hdr *hdr = (void *)__data;
+	uint8_t *data = __data + sizeof(*hdr);
+	int datalen = len - sizeof(*hdr);
+
+	uint8_t sof = sd->stream_flag | 1;
+	uint8_t mof = sd->stream_flag | 2;
+	uint8_t eof = sd->stream_flag | 5;
+
+	if (len < 12)
+		return;
+
+	if (hdr->magic[0] != 'R' || hdr->magic[1] != 'B') {
+		warn("[Stream %02x] Invalid magic %02x%02x", sd->stream_flag,
+				hdr->magic[0], hdr->magic[1]);
+		return;
+	}
+
+	if (hdr->flag == sof)
+		gspca_frame_add(gspca_dev, FIRST_PACKET, data, datalen);
+
+	else if (hdr->flag == mof)
+		gspca_frame_add(gspca_dev, INTER_PACKET, data, datalen);
+
+	else if (hdr->flag == eof)
+		gspca_frame_add(gspca_dev, LAST_PACKET, data, datalen);
+
+	else
+		warn("Packet type not recognized...");
+}
+
+/* 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,
+	.get_streamparm = sd_get_streamparm,
+	.set_streamparm = sd_set_streamparm,
+	*/
+};
+
+/* -- module initialisation -- */
+static const struct usb_device_id device_table[] = {
+	{USB_DEVICE(0x045e, 0x02ae)},
+	{}
+};
+
+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)
+{
+	return usb_register(&sd_driver);
+}
+
+static void __exit sd_mod_exit(void)
+{
+	usb_deregister(&sd_driver);
+}
+
+module_init(sd_mod_init);
+module_exit(sd_mod_exit);
diff -druN linux-2.6.39-libre/drivers/media/video/gspca/Makefile linux-3.0-rc7-libre/drivers/media/video/gspca/Makefile
--- linux-2.6.39-libre/drivers/media/video/gspca/Makefile	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/video/gspca/Makefile	2011-07-11 19:51:52.000000000 -0400
@@ -5,6 +5,7 @@
 obj-$(CONFIG_USB_GSPCA_ETOMS)    += gspca_etoms.o
 obj-$(CONFIG_USB_GSPCA_FINEPIX)  += gspca_finepix.o
 obj-$(CONFIG_USB_GSPCA_JEILINJ)  += gspca_jeilinj.o
+obj-$(CONFIG_USB_GSPCA_KINECT)   += gspca_kinect.o
 obj-$(CONFIG_USB_GSPCA_KONICA)   += gspca_konica.o
 obj-$(CONFIG_USB_GSPCA_MARS)     += gspca_mars.o
 obj-$(CONFIG_USB_GSPCA_MR97310A) += gspca_mr97310a.o
@@ -46,6 +47,7 @@
 gspca_etoms-objs    := etoms.o
 gspca_finepix-objs  := finepix.o
 gspca_jeilinj-objs  := jeilinj.o
+gspca_kinect-objs   := kinect.o
 gspca_konica-objs   := konica.o
 gspca_mars-objs     := mars.o
 gspca_mr97310a-objs := mr97310a.o
diff -druN linux-2.6.39-libre/drivers/media/video/gspca/ov519.c linux-3.0-rc7-libre/drivers/media/video/gspca/ov519.c
--- linux-2.6.39-libre/drivers/media/video/gspca/ov519.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/video/gspca/ov519.c	2011-07-11 19:51:52.000000000 -0400
@@ -609,7 +609,7 @@
  * buffers, there are some pretty strict real time constraints for
  * isochronous transfer for larger frame sizes).
  */
-/*jfm: this value works well for 1600x1200, but not 800x600 - see isoc_init */
+/*jfm: this value does not work for 800x600 - see isoc_init */
 #define OVFX2_BULK_SIZE (13 * 4096)
 
 /* I2C registers */
@@ -3307,6 +3307,7 @@
 
 	gspca_dev->cam.ctrls = sd->ctrls;
 	sd->quality = QUALITY_DEF;
+	sd->frame_rate = 15;
 
 	return 0;
 }
@@ -3469,7 +3470,6 @@
 				ARRAY_SIZE(init_519_ov7660));
 		write_i2c_regvals(sd, norm_7660, ARRAY_SIZE(norm_7660));
 		sd->gspca_dev.curr_mode = 1;	/* 640x480 */
-		sd->frame_rate = 15;
 		ov519_set_mode(sd);
 		ov519_set_fr(sd);
 		sd->ctrls[COLORS].max = 4;	/* 0..4 */
@@ -3511,7 +3511,7 @@
 
 	switch (sd->bridge) {
 	case BRIDGE_OVFX2:
-		if (gspca_dev->width == 1600)
+		if (gspca_dev->width != 800)
 			gspca_dev->cam.bulk_size = OVFX2_BULK_SIZE;
 		else
 			gspca_dev->cam.bulk_size = 7 * 4096;
@@ -4478,7 +4478,7 @@
 	gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
 
 	/* A short read signals EOF */
-	if (len < OVFX2_BULK_SIZE) {
+	if (len < gspca_dev->cam.bulk_size) {
 		/* If the frame is short, and it is one of the first ones
 		   the sensor and bridge are still syncing, so drop it. */
 		if (sd->first_frame) {
diff -druN linux-2.6.39-libre/drivers/media/video/gspca/sonixj.c linux-3.0-rc7-libre/drivers/media/video/gspca/sonixj.c
--- linux-2.6.39-libre/drivers/media/video/gspca/sonixj.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/video/gspca/sonixj.c	2011-07-11 19:51:52.000000000 -0400
@@ -60,7 +60,7 @@
 
 	u32 pktsz;			/* (used by pkt_scan) */
 	u16 npkt;
-	u8 nchg;
+	s8 nchg;
 	s8 short_mark;
 
 	u8 quality;			/* image quality */
diff -druN linux-2.6.39-libre/drivers/media/video/gspca/spca508.c linux-3.0-rc7-libre/drivers/media/video/gspca/spca508.c
--- linux-2.6.39-libre/drivers/media/video/gspca/spca508.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/video/gspca/spca508.c	2011-07-11 19:51:52.000000000 -0400
@@ -1375,7 +1375,6 @@
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 	struct cam *cam;
-	int data1, data2;
 	const u16 (*init_data)[2];
 	static const u16 (*(init_data_tb[]))[2] = {
 		spca508_vista_init_data,	/* CreativeVista 0 */
@@ -1386,6 +1385,9 @@
 		spca508_init_data,		/* ViewQuestVQ110 5 */
 	};
 
+#ifdef GSPCA_DEBUG
+	int data1, data2;
+
 	/* Read from global register the USB product and vendor IDs, just to
 	 * prove that we can communicate with the device.  This works, which
 	 * confirms at we are communicating properly and that the device
@@ -1400,6 +1402,7 @@
 
 	data1 = reg_read(gspca_dev, 0x8621);
 	PDEBUG(D_PROBE, "Window 1 average luminance: %d", data1);
+#endif
 
 	cam = &gspca_dev->cam;
 	cam->cam_mode = sif_mode;
diff -druN linux-2.6.39-libre/drivers/media/video/gspca/stk014.c linux-3.0-rc7-libre/drivers/media/video/gspca/stk014.c
--- linux-2.6.39-libre/drivers/media/video/gspca/stk014.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/video/gspca/stk014.c	2011-07-11 19:51:52.000000000 -0400
@@ -436,17 +436,14 @@
 static int sd_querymenu(struct gspca_dev *gspca_dev,
 			struct v4l2_querymenu *menu)
 {
+	static const char *freq_nm[3] = {"NoFliker", "50 Hz", "60 Hz"};
+
 	switch (menu->id) {
 	case V4L2_CID_POWER_LINE_FREQUENCY:
-		switch (menu->index) {
-		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;
+		if ((unsigned) menu->index >= ARRAY_SIZE(freq_nm))
+			break;
+		strcpy((char *) menu->name, freq_nm[menu->index]);
+		return 0;
 	}
 	return -EINVAL;
 }
diff -druN linux-2.6.39-libre/drivers/media/video/gspca/stv06xx/stv06xx_hdcs.h linux-3.0-rc7-libre/drivers/media/video/gspca/stv06xx/stv06xx_hdcs.h
--- linux-2.6.39-libre/drivers/media/video/gspca/stv06xx/stv06xx_hdcs.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/video/gspca/stv06xx/stv06xx_hdcs.h	2011-07-11 19:51:52.000000000 -0400
@@ -125,7 +125,7 @@
 #define HDCS_SLEEP_MODE		(1 << 1)
 
 #define HDCS_DEFAULT_EXPOSURE	48
-#define HDCS_DEFAULT_GAIN	128
+#define HDCS_DEFAULT_GAIN	50
 
 static int hdcs_probe_1x00(struct sd *sd);
 static int hdcs_probe_1020(struct sd *sd);
diff -druN linux-2.6.39-libre/drivers/media/video/gspca/stv06xx/stv06xx_pb0100.c linux-3.0-rc7-libre/drivers/media/video/gspca/stv06xx/stv06xx_pb0100.c
--- linux-2.6.39-libre/drivers/media/video/gspca/stv06xx/stv06xx_pb0100.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/video/gspca/stv06xx/stv06xx_pb0100.c	2011-07-11 19:51:52.000000000 -0400
@@ -217,6 +217,8 @@
 
 	intf = usb_ifnum_to_if(sd->gspca_dev.dev, sd->gspca_dev.iface);
 	alt = usb_altnum_to_altsetting(intf, sd->gspca_dev.alt);
+	if (!alt)
+		return -ENODEV;
 	packet_size = le16_to_cpu(alt->endpoint[0].desc.wMaxPacketSize);
 
 	/* If we don't have enough bandwidth use a lower framerate */
diff -druN linux-2.6.39-libre/drivers/media/video/gspca/sunplus.c linux-3.0-rc7-libre/drivers/media/video/gspca/sunplus.c
--- linux-2.6.39-libre/drivers/media/video/gspca/sunplus.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/video/gspca/sunplus.c	2011-07-11 19:51:52.000000000 -0400
@@ -396,57 +396,6 @@
 		req, index, value);
 }
 
-/* read 1 byte */
-static u8 reg_r_1(struct gspca_dev *gspca_dev,
-			u16 value)	/* wValue */
-{
-	int ret;
-
-	if (gspca_dev->usb_err < 0)
-		return 0;
-	ret = usb_control_msg(gspca_dev->dev,
-			usb_rcvctrlpipe(gspca_dev->dev, 0),
-			0x20,			/* request */
-			USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
-			value,
-			0,			/* index */
-			gspca_dev->usb_buf, 1,
-			500);			/* timeout */
-	if (ret < 0) {
-		err("reg_r_1 err %d", ret);
-		gspca_dev->usb_err = ret;
-		return 0;
-	}
-	return gspca_dev->usb_buf[0];
-}
-
-/* read 1 or 2 bytes */
-static u16 reg_r_12(struct gspca_dev *gspca_dev,
-			u8 req,		/* bRequest */
-			u16 index,	/* wIndex */
-			u16 length)	/* wLength (1 or 2 only) */
-{
-	int ret;
-
-	if (gspca_dev->usb_err < 0)
-		return 0;
-	gspca_dev->usb_buf[1] = 0;
-	ret = usb_control_msg(gspca_dev->dev,
-			usb_rcvctrlpipe(gspca_dev->dev, 0),
-			req,
-			USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
-			0,		/* value */
-			index,
-			gspca_dev->usb_buf, length,
-			500);
-	if (ret < 0) {
-		err("reg_r_12 err %d", ret);
-		gspca_dev->usb_err = ret;
-		return 0;
-	}
-	return (gspca_dev->usb_buf[1] << 8) + gspca_dev->usb_buf[0];
-}
-
 static void write_vector(struct gspca_dev *gspca_dev,
 			const struct cmd *data, int ncmds)
 {
@@ -473,44 +422,46 @@
 static void spca504_acknowledged_command(struct gspca_dev *gspca_dev,
 			     u8 req, u16 idx, u16 val)
 {
-	u16 notdone;
-
 	reg_w_riv(gspca_dev, req, idx, val);
-	notdone = reg_r_12(gspca_dev, 0x01, 0x0001, 1);
+	reg_r(gspca_dev, 0x01, 0x0001, 1);
+	PDEBUG(D_FRAM, "before wait 0x%04x", gspca_dev->usb_buf[0]);
 	reg_w_riv(gspca_dev, req, idx, val);
 
-	PDEBUG(D_FRAM, "before wait 0x%04x", notdone);
-
 	msleep(200);
-	notdone = reg_r_12(gspca_dev, 0x01, 0x0001, 1);
-	PDEBUG(D_FRAM, "after wait 0x%04x", notdone);
+	reg_r(gspca_dev, 0x01, 0x0001, 1);
+	PDEBUG(D_FRAM, "after wait 0x%04x", gspca_dev->usb_buf[0]);
 }
 
+#ifdef GSPCA_DEBUG
 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);
+	for (i = 0; i < 6; i++) {
+		reg_r(gspca_dev, 0, i, 1);
+		info[i] = gspca_dev->usb_buf[0];
+	}
 	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]);
 }
+#endif
 
 static void spca504A_acknowledged_command(struct gspca_dev *gspca_dev,
 			u8 req,
-			u16 idx, u16 val, u16 endcode, u8 count)
+			u16 idx, u16 val, u8 endcode, u8 count)
 {
 	u16 status;
 
 	reg_w_riv(gspca_dev, req, idx, val);
-	status = reg_r_12(gspca_dev, 0x01, 0x0001, 1);
+	reg_r(gspca_dev, 0x01, 0x0001, 1);
 	if (gspca_dev->usb_err < 0)
 		return;
-	PDEBUG(D_FRAM, "Status 0x%04x Need 0x%04x", status, endcode);
+	PDEBUG(D_FRAM, "Status 0x%02x Need 0x%02x",
+			gspca_dev->usb_buf[0], endcode);
 	if (!count)
 		return;
 	count = 200;
@@ -518,7 +469,8 @@
 		msleep(10);
 		/* gsmart mini2 write a each wait setting 1 ms is enough */
 /*		reg_w_riv(gspca_dev, req, idx, val); */
-		status = reg_r_12(gspca_dev, 0x01, 0x0001, 1);
+		reg_r(gspca_dev, 0x01, 0x0001, 1);
+		status = gspca_dev->usb_buf[0];
 		if (status == endcode) {
 			PDEBUG(D_FRAM, "status 0x%04x after wait %d",
 				status, 200 - count);
@@ -555,17 +507,19 @@
 	}
 }
 
+#ifdef GSPCA_DEBUG
 static void spca50x_GetFirmware(struct gspca_dev *gspca_dev)
 {
 	u8 *data;
 
 	data = gspca_dev->usb_buf;
 	reg_r(gspca_dev, 0x20, 0, 5);
-	PDEBUG(D_STREAM, "FirmWare : %d %d %d %d %d ",
+	PDEBUG(D_STREAM, "FirmWare: %d %d %d %d %d",
 		data[0], data[1], data[2], data[3], data[4]);
 	reg_r(gspca_dev, 0x23, 0, 64);
 	reg_r(gspca_dev, 0x23, 1, 64);
 }
+#endif
 
 static void spca504B_SetSizeType(struct gspca_dev *gspca_dev)
 {
@@ -578,7 +532,9 @@
 		reg_w_riv(gspca_dev, 0x31, 0, 0);
 		spca504B_WaitCmdStatus(gspca_dev);
 		spca504B_PollingDataReady(gspca_dev);
+#ifdef GSPCA_DEBUG
 		spca50x_GetFirmware(gspca_dev);
+#endif
 		reg_w_1(gspca_dev, 0x24, 0, 8, 2);		/* type */
 		reg_r(gspca_dev, 0x24, 8, 1);
 
@@ -628,7 +584,8 @@
 	cnt = 256;
 	while (--cnt > 0) {
 		/* With this we get the status, when return 0 it's all ok */
-		if (reg_r_12(gspca_dev, 0x06, 0x00, 1) == 0)
+		reg_r(gspca_dev, 0x06, 0x00, 1);
+		if (gspca_dev->usb_buf[0] == 0)
 			return;
 		msleep(10);
 	}
@@ -772,10 +729,14 @@
 		/* fall thru */
 	case BRIDGE_SPCA533:
 		spca504B_PollingDataReady(gspca_dev);
+#ifdef GSPCA_DEBUG
 		spca50x_GetFirmware(gspca_dev);
+#endif
 		break;
 	case BRIDGE_SPCA536:
+#ifdef GSPCA_DEBUG
 		spca50x_GetFirmware(gspca_dev);
+#endif
 		reg_r(gspca_dev, 0x00, 0x5002, 1);
 		reg_w_1(gspca_dev, 0x24, 0, 0, 0);
 		reg_r(gspca_dev, 0x24, 0, 1);
@@ -801,7 +762,9 @@
 /*	case BRIDGE_SPCA504: */
 		PDEBUG(D_STREAM, "Opening SPCA504");
 		if (sd->subtype == AiptekMiniPenCam13) {
+#ifdef GSPCA_DEBUG
 			spca504_read_info(gspca_dev);
+#endif
 
 			/* Set AE AWB Banding Type 3-> 50Hz 2-> 60Hz */
 			spca504A_acknowledged_command(gspca_dev, 0x24,
@@ -873,7 +836,9 @@
 		break;
 	case BRIDGE_SPCA504:
 		if (sd->subtype == AiptekMiniPenCam13) {
+#ifdef GSPCA_DEBUG
 			spca504_read_info(gspca_dev);
+#endif
 
 			/* Set AE AWB Banding Type 3-> 50Hz 2-> 60Hz */
 			spca504A_acknowledged_command(gspca_dev, 0x24,
@@ -885,7 +850,9 @@
 							0, 0, 0x9d, 1);
 		} else {
 			spca504_acknowledged_command(gspca_dev, 0x24, 8, 3);
+#ifdef GSPCA_DEBUG
 			spca504_read_info(gspca_dev);
+#endif
 			spca504_acknowledged_command(gspca_dev, 0x24, 8, 3);
 			spca504_acknowledged_command(gspca_dev, 0x24, 0, 0);
 		}
diff -druN linux-2.6.39-libre/drivers/media/video/gspca/t613.c linux-3.0-rc7-libre/drivers/media/video/gspca/t613.c
--- linux-2.6.39-libre/drivers/media/video/gspca/t613.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/video/gspca/t613.c	2011-07-11 19:51:52.000000000 -0400
@@ -92,8 +92,6 @@
 static int sd_getmirror(struct gspca_dev *gspca_dev, __s32 *val);
 static int sd_seteffect(struct gspca_dev *gspca_dev, __s32 val);
 static int sd_geteffect(struct gspca_dev *gspca_dev, __s32 *val);
-static int sd_querymenu(struct gspca_dev *gspca_dev,
-			struct v4l2_querymenu *menu);
 
 static const struct ctrl sd_ctrls[] = {
 	{
@@ -1379,17 +1377,14 @@
 static int sd_querymenu(struct gspca_dev *gspca_dev,
 			struct v4l2_querymenu *menu)
 {
+	static const char *freq_nm[3] = {"NoFliker", "50 Hz", "60 Hz"};
+
 	switch (menu->id) {
 	case V4L2_CID_POWER_LINE_FREQUENCY:
-		switch (menu->index) {
-		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;
+		if ((unsigned) menu->index >= ARRAY_SIZE(freq_nm))
+			break;
+		strcpy((char *) menu->name, freq_nm[menu->index]);
+		return 0;
 	case V4L2_CID_EFFECTS:
 		if ((unsigned) menu->index < ARRAY_SIZE(effects_control)) {
 			strncpy((char *) menu->name,
diff -druN linux-2.6.39-libre/drivers/media/video/gspca/zc3xx.c linux-3.0-rc7-libre/drivers/media/video/gspca/zc3xx.c
--- linux-2.6.39-libre/drivers/media/video/gspca/zc3xx.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/video/gspca/zc3xx.c	2011-07-11 19:51:52.000000000 -0400
@@ -3065,15 +3065,10 @@
 	{0xaa, 0x55, 0x0010}, /* 00,55,10,aa */
 	{0xa0, 0xf0, 0x0199}, /* 01,99,F0,cc */
 	{0xa0, 0x80, 0x019a}, /* 01,9A,80,cc */
-	{0xaa, 0x03, 0x0003}, /* 00,03,03,aa */
-	{0xaa, 0x10, 0x00fc}, /* 00,10,fc,aa */
-	{0xaa, 0x36, 0x001d}, /* 00,36,1D,aa */
-	{0xaa, 0x37, 0x004c}, /* 00,37,4C,aa */
-	{0xaa, 0x3b, 0x001d}, /* 00,3B,1D,aa */
 	{}
 };
 
-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, 0x001d}, /* 00,36,1D,aa */
@@ -3082,15 +3077,10 @@
 	{0xaa, 0x3c, 0x004c}, /* 00,3C,4C,aa */
 	{0xaa, 0x3d, 0x001d}, /* 00,3D,1D,aa */
 	{0xaa, 0x3e, 0x004c}, /* 00,3E,4C,aa */
-	{0xaa, 0x03, 0x0003}, /* 00,03,03,aa */
-	{0xaa, 0x10, 0x00fc}, /* 00,10,fc,aa */
-	{0xaa, 0x36, 0x003a}, /* 00,36,3A,aa */
-	{0xaa, 0x37, 0x0098}, /* 00,37,98,aa */
-	{0xaa, 0x3b, 0x003a}, /* 00,3B,3A,aa */
 	{}
 };
 
-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, 0x003a}, /* 00,36,3A,aa */
@@ -3099,15 +3089,10 @@
 	{0xaa, 0x3c, 0x0098}, /* 00,3C,98,aa */
 	{0xaa, 0x3d, 0x003a}, /* 00,3D,3A,aa */
 	{0xaa, 0x3e, 0x0098}, /* 00,3E,98,aa */
-	{0xaa, 0x03, 0x0003}, /* 00,03,03,aa */
-	{0xaa, 0x10, 0x00fc}, /* 00,10,fc,aa */
-	{0xaa, 0x36, 0x0018}, /* 00,36,18,aa */
-	{0xaa, 0x37, 0x006a}, /* 00,37,6A,aa */
-	{0xaa, 0x3d, 0x0018}, /* 00,3D,18,aa */
 	{}
 };
 
-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, 0x0018}, /* 00,36,18,aa */
@@ -3116,15 +3101,10 @@
 	{0xaa, 0x3e, 0x006a}, /* 00,3E,6A,aa */
 	{0xaa, 0x3b, 0x0018}, /* 00,3B,18,aa */
 	{0xaa, 0x3c, 0x006a}, /* 00,3C,6A,aa */
-	{0xaa, 0x03, 0x0003}, /* 00,03,03,aa */
-	{0xaa, 0x10, 0x00fc}, /* 00,10,fc,aa */
-	{0xaa, 0x36, 0x0030}, /* 00,36,30,aa */
-	{0xaa, 0x37, 0x00d4}, /* 00,37,D4,aa */
-	{0xaa, 0x3d, 0x0030}, /* 00,3D,30,aa */
 	{}
 };
 
-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, 0x0030}, /* 00,36,30,aa */
@@ -3133,15 +3113,10 @@
 	{0xaa, 0x3e, 0x00d4}, /* 00,3E,D4,aa */
 	{0xaa, 0x3b, 0x0030}, /* 00,3B,30,aa */
 	{0xaa, 0x3c, 0x00d4}, /* 00,3C,D4,aa */
-	{0xaa, 0x03, 0x0003}, /* 00,03,03,aa */
-	{0xaa, 0x10, 0x00fc}, /* 00,10,fc,aa */
-	{0xaa, 0x36, 0x0018}, /* 00,36,18,aa */
-	{0xaa, 0x37, 0x006a}, /* 00,37,6A,aa */
-	{0xaa, 0x3d, 0x0018}, /* 00,3D,18,aa */
 	{}
 };
 
-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, 0x0018}, /* 00,36,18,aa */
@@ -3150,15 +3125,10 @@
 	{0xaa, 0x3e, 0x006a}, /* 00,3E,6A,aa */
 	{0xaa, 0x3b, 0x0018}, /* 00,3B,18,aa */
 	{0xaa, 0x3c, 0x006a}, /* 00,3C,6A,aa */
-	{0xaa, 0x03, 0x0003}, /* 00,03,03,aa */
-	{0xaa, 0x10, 0x00fc}, /* 00,10,fc,aa */
-	{0xaa, 0x36, 0x0030}, /* 00,36,30,aa */
-	{0xaa, 0x37, 0x00d4}, /* 00,37,D4,aa */
-	{0xaa, 0x3d, 0x0030}, /* 00,3D,30,aa */
 	{}
 };
 
-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, 0x0030}, /* 00,36,30,aa */
@@ -6296,7 +6266,6 @@
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 	int i;
-	u8 retbyte;
 	u16 retword;
 
 /*fixme: lack of 8b=b3 (11,12)-> 10, 8b=e0 (14,15,16)-> 12 found in gspcav1*/
@@ -6389,8 +6358,12 @@
 	retword |= i2c_read(gspca_dev, 0x01);		/* ID 1 */
 	PDEBUG(D_PROBE, "probe 3wr vga 2 0x%04x", retword);
 	if (retword == 0x2030) {
+#ifdef GSPCA_DEBUG
+		u8 retbyte;
+
 		retbyte = i2c_read(gspca_dev, 0x02);	/* revision number */
 		PDEBUG(D_PROBE, "sensor PO2030 rev 0x%02x", retbyte);
+#endif
 		send_unknown(gspca_dev, SENSOR_PO2030);
 		return retword;
 	}
diff -druN linux-2.6.39-libre/drivers/media/video/ivtv/ivtv-driver.c linux-3.0-rc7-libre/drivers/media/video/ivtv/ivtv-driver.c
--- linux-2.6.39-libre/drivers/media/video/ivtv/ivtv-driver.c	2011-05-19 02:08:16.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/video/ivtv/ivtv-driver.c	2011-07-21 06:50:33.000000000 -0400
@@ -810,7 +810,6 @@
 			  const struct pci_device_id *pci_id)
 {
 	u16 cmd;
-	u8 card_rev;
 	unsigned char pci_latency;
 
 	IVTV_DEBUG_INFO("Enabling pci device\n");
@@ -857,7 +856,6 @@
 	}
 	IVTV_DEBUG_INFO("Bus Mastering Enabled.\n");
 
-	pci_read_config_byte(pdev, PCI_CLASS_REVISION, &card_rev);
 	pci_read_config_byte(pdev, PCI_LATENCY_TIMER, &pci_latency);
 
 	if (pci_latency < 64 && ivtv_pci_latency) {
@@ -874,7 +872,7 @@
 
 	IVTV_DEBUG_INFO("%d (rev %d) at %02x:%02x.%x, "
 		   "irq: %d, latency: %d, memory: 0x%lx\n",
-		   pdev->device, card_rev, pdev->bus->number,
+		   pdev->device, pdev->revision, pdev->bus->number,
 		   PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn),
 		   pdev->irq, pci_latency, (unsigned long)itv->base_addr);
 
@@ -1330,6 +1328,8 @@
 	if (!itv->has_cx23415)
 		write_reg_sync(0x03, IVTV_REG_DMACONTROL);
 
+	ivtv_s_std_enc(itv, &itv->tuner_std);
+
 	/* Default interrupts enabled. For the PVR350 this includes the
 	   decoder VSYNC interrupt, which is always on. It is not only used
 	   during decoding but also by the OSD.
@@ -1338,12 +1338,10 @@
 	if (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT) {
 		ivtv_clear_irq_mask(itv, IVTV_IRQ_MASK_INIT | IVTV_IRQ_DEC_VSYNC);
 		ivtv_set_osd_alpha(itv);
-	}
-	else
+		ivtv_s_std_dec(itv, &itv->tuner_std);
+	} else {
 		ivtv_clear_irq_mask(itv, IVTV_IRQ_MASK_INIT);
-
-	/* For cards with video out, this call needs interrupts enabled */
-	ivtv_s_std(NULL, &fh, &itv->tuner_std);
+	}
 
 	/* Setup initial controls */
 	cx2341x_handler_setup(&itv->cxhdl);
diff -druN linux-2.6.39-libre/drivers/media/video/ivtv/ivtvfb.c linux-3.0-rc7-libre/drivers/media/video/ivtv/ivtvfb.c
--- linux-2.6.39-libre/drivers/media/video/ivtv/ivtvfb.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/video/ivtv/ivtvfb.c	2011-07-11 19:51:52.000000000 -0400
@@ -247,7 +247,7 @@
 
 static int ivtvfb_set_display_window(struct ivtv *itv, struct v4l2_rect *ivtv_window)
 {
-	int osd_height_limit = itv->is_50hz ? 576 : 480;
+	int osd_height_limit = itv->is_out_50hz ? 576 : 480;
 
 	/* Only fail if resolution too high, otherwise fudge the start coords. */
 	if ((ivtv_window->height > osd_height_limit) || (ivtv_window->width > IVTV_OSD_MAX_WIDTH))
@@ -471,9 +471,9 @@
 			vblank.flags = FB_VBLANK_HAVE_COUNT |FB_VBLANK_HAVE_VCOUNT |
 					FB_VBLANK_HAVE_VSYNC;
 			trace = read_reg(IVTV_REG_DEC_LINE_FIELD) >> 16;
-			if (itv->is_50hz && trace > 312)
+			if (itv->is_out_50hz && trace > 312)
 				trace -= 312;
-			else if (itv->is_60hz && trace > 262)
+			else if (itv->is_out_60hz && trace > 262)
 				trace -= 262;
 			if (trace == 1)
 				vblank.flags |= FB_VBLANK_VSYNCING;
@@ -656,7 +656,7 @@
 	IVTVFB_DEBUG_INFO("ivtvfb_check_var\n");
 
 	/* Set base references for mode calcs. */
-	if (itv->is_50hz) {
+	if (itv->is_out_50hz) {
 		pixclock = 84316;
 		hlimit = 776;
 		vlimit = 591;
@@ -784,12 +784,12 @@
 	   If the margins are too large, just center the screen
 	   (enforcing margins causes too many problems) */
 
-	if (var->left_margin + var->xres > IVTV_OSD_MAX_WIDTH + 1) {
+	if (var->left_margin + var->xres > IVTV_OSD_MAX_WIDTH + 1)
 		var->left_margin = 1 + ((IVTV_OSD_MAX_WIDTH - var->xres) / 2);
-	}
-	if (var->upper_margin + var->yres > (itv->is_50hz ? 577 : 481)) {
-		var->upper_margin = 1 + (((itv->is_50hz ? 576 : 480) - var->yres) / 2);
-	}
+
+	if (var->upper_margin + var->yres > (itv->is_out_50hz ? 577 : 481))
+		var->upper_margin = 1 + (((itv->is_out_50hz ? 576 : 480) -
+			var->yres) / 2);
 
 	/* Maintain overall 'size' for a constant refresh rate */
 	var->right_margin = hlimit - var->left_margin - var->xres;
@@ -836,7 +836,12 @@
 	u32 osd_pan_index;
 	struct ivtv *itv = (struct ivtv *) info->par;
 
-	osd_pan_index = (var->xoffset + (var->yoffset * var->xres_virtual))*var->bits_per_pixel/8;
+	if (var->yoffset + info->var.yres > info->var.yres_virtual ||
+	    var->xoffset + info->var.xres > info->var.xres_virtual)
+		return -EINVAL;
+
+	osd_pan_index = var->yoffset * info->fix.line_length
+		      + var->xoffset * info->var.bits_per_pixel / 8;
 	write_reg(osd_pan_index, 0x02A0C);
 
 	/* Pass this info back the yuv handler */
@@ -1003,19 +1008,21 @@
 	/* Hardware coords start at 0, user coords start at 1. */
 	osd_left--;
 
-	start_window.left = osd_left >= 0 ? osd_left : ((IVTV_OSD_MAX_WIDTH - start_window.width) / 2);
+	start_window.left = osd_left >= 0 ?
+		 osd_left : ((IVTV_OSD_MAX_WIDTH - start_window.width) / 2);
 
 	oi->display_byte_stride =
 			start_window.width * oi->bytes_per_pixel;
 
 	/* Vertical size & position */
 
-	max_height = itv->is_50hz ? 576 : 480;
+	max_height = itv->is_out_50hz ? 576 : 480;
 
 	if (osd_yres > max_height)
 		osd_yres = max_height;
 
-	start_window.height = osd_yres ? osd_yres : itv->is_50hz ? 480 : 400;
+	start_window.height = osd_yres ?
+		osd_yres : itv->is_out_50hz ? 480 : 400;
 
 	/* Check vertical start (osd_upper). */
 	if (osd_upper + start_window.height > max_height + 1) {
diff -druN linux-2.6.39-libre/drivers/media/video/ivtv/ivtv-firmware.c linux-3.0-rc7-libre/drivers/media/video/ivtv/ivtv-firmware.c
--- linux-2.6.39-libre/drivers/media/video/ivtv/ivtv-firmware.c	2011-05-19 02:10:24.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/video/ivtv/ivtv-firmware.c	2011-07-21 06:52:51.000000000 -0400
@@ -280,8 +280,6 @@
 {
 	int rc = 0;
 	v4l2_std_id std;
-	struct ivtv_open_id fh;
-	fh.itv = itv;
 
 	if (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)
 		/* Display test image during restart */
@@ -301,14 +299,19 @@
 	/* Allow settings to reload */
 	ivtv_mailbox_cache_invalidate(itv);
 
-	/* Restore video standard */
+	/* Restore encoder video standard */
 	std = itv->std;
 	itv->std = 0;
-	ivtv_s_std(NULL, &fh, &std);
+	ivtv_s_std_enc(itv, &std);
 
 	if (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT) {
 		ivtv_init_mpeg_decoder(itv);
 
+		/* Restore decoder video standard */
+		std = itv->std_out;
+		itv->std_out = 0;
+		ivtv_s_std_dec(itv, &std);
+
 		/* Restore framebuffer if active */
 		if (itv->ivtvfb_restore)
 			itv->ivtvfb_restore(itv);
diff -druN linux-2.6.39-libre/drivers/media/video/ivtv/ivtv-ioctl.c linux-3.0-rc7-libre/drivers/media/video/ivtv/ivtv-ioctl.c
--- linux-2.6.39-libre/drivers/media/video/ivtv/ivtv-ioctl.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/video/ivtv/ivtv-ioctl.c	2011-07-11 19:51:52.000000000 -0400
@@ -1071,28 +1071,8 @@
 	return 0;
 }
 
-int ivtv_s_std(struct file *file, void *fh, v4l2_std_id *std)
+void ivtv_s_std_enc(struct ivtv *itv, v4l2_std_id *std)
 {
-	DEFINE_WAIT(wait);
-	struct ivtv *itv = fh2id(fh)->itv;
-	struct yuv_playback_info *yi = &itv->yuv_info;
-	int f;
-
-	if ((*std & V4L2_STD_ALL) == 0)
-		return -EINVAL;
-
-	if (*std == itv->std)
-		return 0;
-
-	if (test_bit(IVTV_F_I_RADIO_USER, &itv->i_flags) ||
-	    atomic_read(&itv->capturing) > 0 ||
-	    atomic_read(&itv->decoding) > 0) {
-		/* Switching standard would turn off the radio or mess
-		   with already running streams, prevent that by
-		   returning EBUSY. */
-		return -EBUSY;
-	}
-
 	itv->std = *std;
 	itv->is_60hz = (*std & V4L2_STD_525_60) ? 1 : 0;
 	itv->is_50hz = !itv->is_60hz;
@@ -1106,48 +1086,79 @@
 	if (itv->hw_flags & IVTV_HW_CX25840)
 		itv->vbi.sliced_decoder_line_size = itv->is_60hz ? 272 : 284;
 
-	IVTV_DEBUG_INFO("Switching standard to %llx.\n", (unsigned long long)itv->std);
-
 	/* Tuner */
 	ivtv_call_all(itv, core, s_std, itv->std);
+}
 
-	if (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT) {
-		/* set display standard */
-		itv->std_out = *std;
-		itv->is_out_60hz = itv->is_60hz;
-		itv->is_out_50hz = itv->is_50hz;
-		ivtv_call_all(itv, video, s_std_output, itv->std_out);
+void ivtv_s_std_dec(struct ivtv *itv, v4l2_std_id *std)
+{
+	struct yuv_playback_info *yi = &itv->yuv_info;
+	DEFINE_WAIT(wait);
+	int f;
 
-		/*
-		 * The next firmware call is time sensitive. Time it to
-		 * avoid risk of a hard lock, by trying to ensure the call
-		 * happens within the first 100 lines of the top field.
-		 * Make 4 attempts to sync to the decoder before giving up.
-		 */
-		for (f = 0; f < 4; f++) {
-			prepare_to_wait(&itv->vsync_waitq, &wait,
-					TASK_UNINTERRUPTIBLE);
-			if ((read_reg(IVTV_REG_DEC_LINE_FIELD) >> 16) < 100)
-				break;
-			schedule_timeout(msecs_to_jiffies(25));
-		}
-		finish_wait(&itv->vsync_waitq, &wait);
+	/* set display standard */
+	itv->std_out = *std;
+	itv->is_out_60hz = (*std & V4L2_STD_525_60) ? 1 : 0;
+	itv->is_out_50hz = !itv->is_out_60hz;
+	ivtv_call_all(itv, video, s_std_output, itv->std_out);
 
-		if (f == 4)
-			IVTV_WARN("Mode change failed to sync to decoder\n");
+	/*
+	 * The next firmware call is time sensitive. Time it to
+	 * avoid risk of a hard lock, by trying to ensure the call
+	 * happens within the first 100 lines of the top field.
+	 * Make 4 attempts to sync to the decoder before giving up.
+	 */
+	for (f = 0; f < 4; f++) {
+		prepare_to_wait(&itv->vsync_waitq, &wait,
+				TASK_UNINTERRUPTIBLE);
+		if ((read_reg(IVTV_REG_DEC_LINE_FIELD) >> 16) < 100)
+			break;
+		schedule_timeout(msecs_to_jiffies(25));
+	}
+	finish_wait(&itv->vsync_waitq, &wait);
 
-		ivtv_vapi(itv, CX2341X_DEC_SET_STANDARD, 1, itv->is_out_50hz);
-		itv->main_rect.left = itv->main_rect.top = 0;
-		itv->main_rect.width = 720;
-		itv->main_rect.height = itv->cxhdl.height;
-		ivtv_vapi(itv, CX2341X_OSD_SET_FRAMEBUFFER_WINDOW, 4,
-			720, itv->main_rect.height, 0, 0);
-		yi->main_rect = itv->main_rect;
-		if (!itv->osd_info) {
-			yi->osd_full_w = 720;
-			yi->osd_full_h = itv->is_out_50hz ? 576 : 480;
-		}
+	if (f == 4)
+		IVTV_WARN("Mode change failed to sync to decoder\n");
+
+	ivtv_vapi(itv, CX2341X_DEC_SET_STANDARD, 1, itv->is_out_50hz);
+	itv->main_rect.left = 0;
+	itv->main_rect.top = 0;
+	itv->main_rect.width = 720;
+	itv->main_rect.height = itv->is_out_50hz ? 576 : 480;
+	ivtv_vapi(itv, CX2341X_OSD_SET_FRAMEBUFFER_WINDOW, 4,
+		720, itv->main_rect.height, 0, 0);
+	yi->main_rect = itv->main_rect;
+	if (!itv->osd_info) {
+		yi->osd_full_w = 720;
+		yi->osd_full_h = itv->is_out_50hz ? 576 : 480;
 	}
+}
+
+int ivtv_s_std(struct file *file, void *fh, v4l2_std_id *std)
+{
+	struct ivtv *itv = fh2id(fh)->itv;
+
+	if ((*std & V4L2_STD_ALL) == 0)
+		return -EINVAL;
+
+	if (*std == itv->std)
+		return 0;
+
+	if (test_bit(IVTV_F_I_RADIO_USER, &itv->i_flags) ||
+	    atomic_read(&itv->capturing) > 0 ||
+	    atomic_read(&itv->decoding) > 0) {
+		/* Switching standard would mess with already running
+		   streams, prevent that by returning EBUSY. */
+		return -EBUSY;
+	}
+
+	IVTV_DEBUG_INFO("Switching standard to %llx.\n",
+		(unsigned long long)itv->std);
+
+	ivtv_s_std_enc(itv, std);
+	if (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)
+		ivtv_s_std_dec(itv, std);
+
 	return 0;
 }
 
@@ -1173,14 +1184,10 @@
 
 	ivtv_call_all(itv, tuner, g_tuner, vt);
 
-	if (test_bit(IVTV_F_I_RADIO_USER, &itv->i_flags)) {
+	if (vt->type == V4L2_TUNER_RADIO)
 		strlcpy(vt->name, "ivtv Radio Tuner", sizeof(vt->name));
-		vt->type = V4L2_TUNER_RADIO;
-	} else {
+	else
 		strlcpy(vt->name, "ivtv TV Tuner", sizeof(vt->name));
-		vt->type = V4L2_TUNER_ANALOG_TV;
-	}
-
 	return 0;
 }
 
diff -druN linux-2.6.39-libre/drivers/media/video/ivtv/ivtv-ioctl.h linux-3.0-rc7-libre/drivers/media/video/ivtv/ivtv-ioctl.h
--- linux-2.6.39-libre/drivers/media/video/ivtv/ivtv-ioctl.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/video/ivtv/ivtv-ioctl.h	2011-07-11 19:51:52.000000000 -0400
@@ -27,7 +27,8 @@
 void ivtv_set_osd_alpha(struct ivtv *itv);
 int ivtv_set_speed(struct ivtv *itv, int speed);
 void ivtv_set_funcs(struct video_device *vdev);
-int ivtv_s_std(struct file *file, void *fh, v4l2_std_id *std);
+void ivtv_s_std_enc(struct ivtv *itv, v4l2_std_id *std);
+void ivtv_s_std_dec(struct ivtv *itv, v4l2_std_id *std);
 int ivtv_s_frequency(struct file *file, void *fh, struct v4l2_frequency *vf);
 int ivtv_s_input(struct file *file, void *fh, unsigned int inp);
 long ivtv_v4l2_ioctl(struct file *filp, unsigned int cmd, unsigned long arg);
diff -druN linux-2.6.39-libre/drivers/media/video/ivtv/ivtv-streams.c linux-3.0-rc7-libre/drivers/media/video/ivtv/ivtv-streams.c
--- linux-2.6.39-libre/drivers/media/video/ivtv/ivtv-streams.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/video/ivtv/ivtv-streams.c	2011-07-11 19:51:52.000000000 -0400
@@ -589,7 +589,7 @@
 		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(300, 0);
 		ivtv_vapi(itv, CX2341X_ENC_INITIALIZE_INPUT, 0);
 		v4l2_subdev_call(itv->sd_video, video, s_stream, 1);
 	}
@@ -834,7 +834,7 @@
 		}
 
 		/* Handle any pending interrupts */
-		ivtv_msleep_timeout(100, 1);
+		ivtv_msleep_timeout(100, 0);
 	}
 
 	atomic_dec(&itv->capturing);
diff -druN linux-2.6.39-libre/drivers/media/video/ivtv/ivtv-vbi.c linux-3.0-rc7-libre/drivers/media/video/ivtv/ivtv-vbi.c
--- linux-2.6.39-libre/drivers/media/video/ivtv/ivtv-vbi.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/video/ivtv/ivtv-vbi.c	2011-07-11 19:51:52.000000000 -0400
@@ -71,7 +71,7 @@
 	   Turning this signal on and off can confuse certain
 	   TVs. As far as I can tell there is no reason not to
 	   transmit this signal. */
-	if ((itv->std & V4L2_STD_625_50) && !enabled) {
+	if ((itv->std_out & V4L2_STD_625_50) && !enabled) {
 		enabled = 1;
 		mode = 0x08;  /* 4x3 full format */
 	}
diff -druN linux-2.6.39-libre/drivers/media/video/Kconfig linux-3.0-rc7-libre/drivers/media/video/Kconfig
--- linux-2.6.39-libre/drivers/media/video/Kconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/video/Kconfig	2011-07-11 19:51:52.000000000 -0400
@@ -128,10 +128,10 @@
 # Encoder / Decoder module configuration
 #
 
-menu "Encoders/decoders and other helper chips"
+menu "Encoders, decoders, sensors and other helper chips"
 	visible if !VIDEO_HELPER_CHIPS_AUTO
 
-comment "Audio decoders"
+comment "Audio decoders, processors and mixers"
 
 config VIDEO_TVAUDIO
 	tristate "Simple audio decoder chips"
@@ -210,15 +210,6 @@
 	  To compile this driver as a module, choose M here: the
 	  module will be called cs53l32a.
 
-config VIDEO_M52790
-	tristate "Mitsubishi M52790 A/V switch"
-	depends on VIDEO_V4L2 && I2C
-	---help---
-	 Support for the Mitsubishi M52790 A/V switch.
-
-	 To compile this driver as a module, choose M here: the
-	 module will be called m52790.
-
 config VIDEO_TLV320AIC23B
 	tristate "Texas Instruments TLV320AIC23B audio codec"
 	depends on VIDEO_V4L2 && I2C && EXPERIMENTAL
@@ -321,29 +312,6 @@
 	  To compile this driver as a module, choose M here: the
 	  module will be called ks0127.
 
-config VIDEO_OV7670
-	tristate "OmniVision OV7670 sensor support"
-	depends on I2C && VIDEO_V4L2
-	---help---
-	  This is a Video4Linux2 sensor-level driver for the OmniVision
-	  OV7670 VGA camera.  It currently only works with the M88ALP01
-	  controller.
-
-config VIDEO_MT9V011
-	tristate "Micron mt9v011 sensor support"
-	depends on I2C && VIDEO_V4L2
-	---help---
-	  This is a Video4Linux2 sensor-level driver for the Micron
-	  mt0v011 1.3 Mpixel camera.  It currently only works with the
-	  em28xx driver.
-
-config VIDEO_TCM825X
-	tristate "TCM825x camera sensor support"
-	depends on I2C && VIDEO_V4L2
-	---help---
-	  This is a driver for the Toshiba TCM825x VGA camera sensor.
-	  It is used for example in Nokia N800.
-
 config VIDEO_SAA7110
 	tristate "Philips SAA7110 video decoder"
 	depends on VIDEO_V4L2 && I2C
@@ -362,15 +330,6 @@
 	  To compile this driver as a module, choose M here: the
 	  module will be called saa7115.
 
-config VIDEO_SAA717X
-	tristate "Philips SAA7171/3/4 audio/video decoders"
-	depends on VIDEO_V4L2 && I2C
-	---help---
-	  Support for the Philips SAA7171/3/4 audio/video decoders.
-
-	  To compile this driver as a module, choose M here: the
-	  module will be called saa717x.
-
 config VIDEO_SAA7191
 	tristate "Philips SAA7191 video decoder"
 	depends on VIDEO_V4L2 && I2C
@@ -420,6 +379,15 @@
 
 comment "Video and audio decoders"
 
+config VIDEO_SAA717X
+	tristate "Philips SAA7171/3/4 audio/video decoders"
+	depends on VIDEO_V4L2 && I2C
+	---help---
+	  Support for the Philips SAA7171/3/4 audio/video decoders.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called saa717x.
+
 source "drivers/media/video/cx25840/Kconfig"
 
 comment "MPEG video encoders"
@@ -474,15 +442,6 @@
 	  To compile this driver as a module, choose M here: the
 	  module will be called adv7175.
 
-config VIDEO_THS7303
-	tristate "THS7303 Video Amplifier"
-	depends on I2C
-	help
-	  Support for TI THS7303 video amplifier
-
-	  To compile this driver as a module, choose M here: the
-	  module will be called ths7303.
-
 config VIDEO_ADV7343
 	tristate "ADV7343 video encoder"
 	depends on I2C
@@ -498,6 +457,38 @@
 	help
 	  Video output driver for AKM AK8813 and AK8814 TV encoders
 
+comment "Camera sensor devices"
+
+config VIDEO_OV7670
+	tristate "OmniVision OV7670 sensor support"
+	depends on I2C && VIDEO_V4L2
+	---help---
+	  This is a Video4Linux2 sensor-level driver for the OmniVision
+	  OV7670 VGA camera.  It currently only works with the M88ALP01
+	  controller.
+
+config VIDEO_MT9V011
+	tristate "Micron mt9v011 sensor support"
+	depends on I2C && VIDEO_V4L2
+	---help---
+	  This is a Video4Linux2 sensor-level driver for the Micron
+	  mt0v011 1.3 Mpixel camera.  It currently only works with the
+	  em28xx driver.
+
+config VIDEO_MT9V032
+	tristate "Micron MT9V032 sensor support"
+	depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
+	---help---
+	  This is a Video4Linux2 sensor-level driver for the Micron
+	  MT9V032 752x480 CMOS sensor.
+
+config VIDEO_TCM825X
+	tristate "TCM825x camera sensor support"
+	depends on I2C && VIDEO_V4L2
+	---help---
+	  This is a driver for the Toshiba TCM825x VGA camera sensor.
+	  It is used for example in Nokia N800.
+
 comment "Video improvement chips"
 
 config VIDEO_UPD64031A
@@ -523,6 +514,26 @@
 	  To compile this driver as a module, choose M here: the
 	  module will be called upd64083.
 
+comment "Miscelaneous helper chips"
+
+config VIDEO_THS7303
+	tristate "THS7303 Video Amplifier"
+	depends on I2C
+	help
+	  Support for TI THS7303 video amplifier
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called ths7303.
+
+config VIDEO_M52790
+	tristate "Mitsubishi M52790 A/V switch"
+	depends on VIDEO_V4L2 && I2C
+	---help---
+	 Support for the Mitsubishi M52790 A/V switch.
+
+	 To compile this driver as a module, choose M here: the
+	 module will be called m52790.
+
 endmenu # encoder / decoder chips
 
 config VIDEO_SH_VOU
@@ -676,13 +687,13 @@
 
 config VIDEO_TIMBERDALE
 	tristate "Support for timberdale Video In/LogiWIN"
-	depends on VIDEO_V4L2 && I2C
+	depends on VIDEO_V4L2 && I2C && DMADEVICES
 	select DMA_ENGINE
 	select TIMB_DMA
 	select VIDEO_ADV7180
 	select VIDEOBUF_DMA_CONTIG
 	---help---
-	Add support for the Video In peripherial of the timberdale FPGA.
+	  Add support for the Video In peripherial of the timberdale FPGA.
 
 source "drivers/media/video/cx88/Kconfig"
 
@@ -746,6 +757,8 @@
 	---help---
 	  This driver supports NOON010PC30 CIF camera from Siliconfile
 
+source "drivers/media/video/m5mols/Kconfig"
+
 config VIDEO_OMAP3
 	tristate "OMAP 3 Camera support (EXPERIMENTAL)"
 	select OMAP_IOMMU
@@ -916,7 +929,7 @@
 	  This is a v4l2 driver for the TI OMAP2 camera capture interface
 
 config VIDEO_MX2_HOSTSUPPORT
-        bool
+	bool
 
 config VIDEO_MX2
 	tristate "i.MX27/i.MX25 Camera Sensor Interface driver"
@@ -927,6 +940,26 @@
 	  This is a v4l2 driver for the i.MX27 and the i.MX25 Camera Sensor
 	  Interface
 
+config  VIDEO_SAMSUNG_S5P_FIMC
+	tristate "Samsung S5P and EXYNOS4 camera host interface driver"
+	depends on VIDEO_DEV && VIDEO_V4L2 && PLAT_S5P
+	select VIDEOBUF2_DMA_CONTIG
+	select V4L2_MEM2MEM_DEV
+	---help---
+	  This is a v4l2 driver for Samsung S5P and EXYNOS4 camera
+	  host interface and video postprocessor.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called s5p-fimc.
+
+config VIDEO_S5P_MIPI_CSIS
+	tristate "Samsung S5P and EXYNOS4 MIPI CSI receiver driver"
+	depends on VIDEO_V4L2 && PM_RUNTIME && PLAT_S5P && VIDEO_V4L2_SUBDEV_API
+	---help---
+	  This is a v4l2 driver for Samsung S5P/EXYNOS4 MIPI-CSI receiver.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called s5p-csis.
 
 #
 # USB Multimedia device configuration
@@ -983,7 +1016,7 @@
 	  Supported devices are typically found in some Asus laptops,
 	  with USB id 174f:a311 and 05e1:0501. Other Syntek cameras
 	  may be supported by the stk11xx driver, from which this is
-	  derived, see <http://sourceforge.net/projects/syntekdriver/> 
+	  derived, see <http://sourceforge.net/projects/syntekdriver/>
 
 	  To compile this driver as a module, choose M here: the
 	  module will be called stkwebcam.
@@ -1022,13 +1055,5 @@
 	  This is a virtual test device for the memory-to-memory driver
 	  framework.
 
-config  VIDEO_SAMSUNG_S5P_FIMC
-	tristate "Samsung S5P FIMC (video postprocessor) driver"
-	depends on VIDEO_DEV && VIDEO_V4L2 && PLAT_S5P
-	select VIDEOBUF2_DMA_CONTIG
-	select V4L2_MEM2MEM_DEV
-	help
-	  This is a v4l2 driver for the S5P camera interface
-	  (video postprocessor)
 
 endif # V4L_MEM2MEM_DRIVERS
diff -druN linux-2.6.39-libre/drivers/media/video/m5mols/Kconfig linux-3.0-rc7-libre/drivers/media/video/m5mols/Kconfig
--- linux-2.6.39-libre/drivers/media/video/m5mols/Kconfig	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/media/video/m5mols/Kconfig	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,5 @@
+config VIDEO_M5MOLS
+	tristate "Fujitsu M-5MOLS 8MP sensor support"
+	depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
+	---help---
+	  This driver supports Fujitsu M-5MOLS camera sensor with ISP
diff -druN linux-2.6.39-libre/drivers/media/video/m5mols/m5mols_capture.c linux-3.0-rc7-libre/drivers/media/video/m5mols/m5mols_capture.c
--- linux-2.6.39-libre/drivers/media/video/m5mols/m5mols_capture.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/media/video/m5mols/m5mols_capture.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,191 @@
+/*
+ * The Capture code for Fujitsu M-5MOLS ISP
+ *
+ * Copyright (C) 2011 Samsung Electronics Co., Ltd.
+ * Author: HeungJun Kim <riverful.kim@samsung.com>
+ *
+ * Copyright (C) 2009 Samsung Electronics Co., Ltd.
+ * Author: Dongsoo Nathaniel Kim <dongsoo45.kim@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/i2c.h>
+#include <linux/slab.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <linux/version.h>
+#include <linux/gpio.h>
+#include <linux/regulator/consumer.h>
+#include <linux/videodev2.h>
+#include <linux/version.h>
+#include <media/v4l2-ctrls.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-subdev.h>
+#include <media/m5mols.h>
+
+#include "m5mols.h"
+#include "m5mols_reg.h"
+
+static int m5mols_capture_error_handler(struct m5mols_info *info,
+					int timeout)
+{
+	int ret;
+
+	/* Disable all interrupts and clear relevant interrupt staus bits */
+	ret = m5mols_write(&info->sd, SYSTEM_INT_ENABLE,
+			   info->interrupt & ~(REG_INT_CAPTURE));
+	if (ret)
+		return ret;
+
+	if (timeout == 0)
+		return -ETIMEDOUT;
+
+	return 0;
+}
+/**
+ * m5mols_read_rational - I2C read of a rational number
+ *
+ * Read numerator and denominator from registers @addr_num and @addr_den
+ * respectively and return the division result in @val.
+ */
+static int m5mols_read_rational(struct v4l2_subdev *sd, u32 addr_num,
+				u32 addr_den, u32 *val)
+{
+	u32 num, den;
+
+	int ret = m5mols_read_u32(sd, addr_num, &num);
+	if (!ret)
+		ret = m5mols_read_u32(sd, addr_den, &den);
+	if (ret)
+		return ret;
+	*val = den == 0 ? 0 : num / den;
+	return ret;
+}
+
+/**
+ * m5mols_capture_info - Gather captured image information
+ *
+ * For now it gathers only EXIF information and file size.
+ */
+static int m5mols_capture_info(struct m5mols_info *info)
+{
+	struct m5mols_exif *exif = &info->cap.exif;
+	struct v4l2_subdev *sd = &info->sd;
+	int ret;
+
+	ret = m5mols_read_rational(sd, EXIF_INFO_EXPTIME_NU,
+				   EXIF_INFO_EXPTIME_DE, &exif->exposure_time);
+	if (ret)
+		return ret;
+	ret = m5mols_read_rational(sd, EXIF_INFO_TV_NU, EXIF_INFO_TV_DE,
+				   &exif->shutter_speed);
+	if (ret)
+		return ret;
+	ret = m5mols_read_rational(sd, EXIF_INFO_AV_NU, EXIF_INFO_AV_DE,
+				   &exif->aperture);
+	if (ret)
+		return ret;
+	ret = m5mols_read_rational(sd, EXIF_INFO_BV_NU, EXIF_INFO_BV_DE,
+				   &exif->brightness);
+	if (ret)
+		return ret;
+	ret = m5mols_read_rational(sd, EXIF_INFO_EBV_NU, EXIF_INFO_EBV_DE,
+				   &exif->exposure_bias);
+	if (ret)
+		return ret;
+
+	ret = m5mols_read_u16(sd, EXIF_INFO_ISO, &exif->iso_speed);
+	if (!ret)
+		ret = m5mols_read_u16(sd, EXIF_INFO_FLASH, &exif->flash);
+	if (!ret)
+		ret = m5mols_read_u16(sd, EXIF_INFO_SDR, &exif->sdr);
+	if (!ret)
+		ret = m5mols_read_u16(sd, EXIF_INFO_QVAL, &exif->qval);
+	if (ret)
+		return ret;
+
+	if (!ret)
+		ret = m5mols_read_u32(sd, CAPC_IMAGE_SIZE, &info->cap.main);
+	if (!ret)
+		ret = m5mols_read_u32(sd, CAPC_THUMB_SIZE, &info->cap.thumb);
+	if (!ret)
+		info->cap.total = info->cap.main + info->cap.thumb;
+
+	return ret;
+}
+
+int m5mols_start_capture(struct m5mols_info *info)
+{
+	struct v4l2_subdev *sd = &info->sd;
+	u8 resolution = info->resolution;
+	int timeout;
+	int ret;
+
+	/*
+	 * Preparing capture. Setting control & interrupt before entering
+	 * capture mode
+	 *
+	 * 1) change to MONITOR mode for operating control & interrupt
+	 * 2) set controls (considering v4l2_control value & lock 3A)
+	 * 3) set interrupt
+	 * 4) change to CAPTURE mode
+	 */
+	ret = m5mols_mode(info, REG_MONITOR);
+	if (!ret)
+		ret = m5mols_sync_controls(info);
+	if (!ret)
+		ret = m5mols_lock_3a(info, true);
+	if (!ret)
+		ret = m5mols_enable_interrupt(sd, REG_INT_CAPTURE);
+	if (!ret)
+		ret = m5mols_mode(info, REG_CAPTURE);
+	if (!ret) {
+		/* Wait for capture interrupt, after changing capture mode */
+		timeout = wait_event_interruptible_timeout(info->irq_waitq,
+					   test_bit(ST_CAPT_IRQ, &info->flags),
+					   msecs_to_jiffies(2000));
+		if (test_and_clear_bit(ST_CAPT_IRQ, &info->flags))
+			ret = m5mols_capture_error_handler(info, timeout);
+	}
+	if (!ret)
+		ret = m5mols_lock_3a(info, false);
+	if (ret)
+		return ret;
+	/*
+	 * Starting capture. Setting capture frame count and resolution and
+	 * the format(available format: JPEG, Bayer RAW, YUV).
+	 *
+	 * 1) select single or multi(enable to 25), format, size
+	 * 2) set interrupt
+	 * 3) start capture(for main image, now)
+	 * 4) get information
+	 * 5) notify file size to v4l2 device(e.g, to s5p-fimc v4l2 device)
+	 */
+	ret = m5mols_write(sd, CAPC_SEL_FRAME, 1);
+	if (!ret)
+		ret = m5mols_write(sd, CAPP_YUVOUT_MAIN, REG_JPEG);
+	if (!ret)
+		ret = m5mols_write(sd, CAPP_MAIN_IMAGE_SIZE, resolution);
+	if (!ret)
+		ret = m5mols_enable_interrupt(sd, REG_INT_CAPTURE);
+	if (!ret)
+		ret = m5mols_write(sd, CAPC_START, REG_CAP_START_MAIN);
+	if (!ret) {
+		/* Wait for the capture completion interrupt */
+		timeout = wait_event_interruptible_timeout(info->irq_waitq,
+					   test_bit(ST_CAPT_IRQ, &info->flags),
+					   msecs_to_jiffies(2000));
+		if (test_and_clear_bit(ST_CAPT_IRQ, &info->flags)) {
+			ret = m5mols_capture_info(info);
+			if (!ret)
+				v4l2_subdev_notify(sd, 0, &info->cap.total);
+		}
+	}
+
+	return m5mols_capture_error_handler(info, timeout);
+}
diff -druN linux-2.6.39-libre/drivers/media/video/m5mols/m5mols_controls.c linux-3.0-rc7-libre/drivers/media/video/m5mols/m5mols_controls.c
--- linux-2.6.39-libre/drivers/media/video/m5mols/m5mols_controls.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/media/video/m5mols/m5mols_controls.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,299 @@
+/*
+ * Controls for M-5MOLS 8M Pixel camera sensor with ISP
+ *
+ * Copyright (C) 2011 Samsung Electronics Co., Ltd.
+ * Author: HeungJun Kim <riverful.kim@samsung.com>
+ *
+ * Copyright (C) 2009 Samsung Electronics Co., Ltd.
+ * Author: Dongsoo Nathaniel Kim <dongsoo45.kim@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/i2c.h>
+#include <linux/delay.h>
+#include <linux/videodev2.h>
+#include <media/v4l2-ctrls.h>
+
+#include "m5mols.h"
+#include "m5mols_reg.h"
+
+static struct m5mols_scenemode m5mols_default_scenemode[] = {
+	[REG_SCENE_NORMAL] = {
+		REG_AE_CENTER, REG_AE_INDEX_00, REG_AWB_AUTO, 0,
+		REG_CHROMA_ON, 3, REG_EDGE_ON, 5,
+		REG_AF_NORMAL, REG_FD_OFF,
+		REG_MCC_NORMAL, REG_LIGHT_OFF, REG_FLASH_OFF,
+		5, REG_ISO_AUTO, REG_CAP_NONE, REG_WDR_OFF,
+	},
+	[REG_SCENE_PORTRAIT] = {
+		REG_AE_CENTER, REG_AE_INDEX_00, REG_AWB_AUTO, 0,
+		REG_CHROMA_ON, 3, REG_EDGE_ON, 4,
+		REG_AF_NORMAL, BIT_FD_EN | BIT_FD_DRAW_FACE_FRAME,
+		REG_MCC_OFF, REG_LIGHT_OFF, REG_FLASH_OFF,
+		6, REG_ISO_AUTO, REG_CAP_NONE, REG_WDR_OFF,
+	},
+	[REG_SCENE_LANDSCAPE] = {
+		REG_AE_ALL, REG_AE_INDEX_00, REG_AWB_AUTO, 0,
+		REG_CHROMA_ON, 4, REG_EDGE_ON, 6,
+		REG_AF_NORMAL, REG_FD_OFF,
+		REG_MCC_OFF, REG_LIGHT_OFF, REG_FLASH_OFF,
+		6, REG_ISO_AUTO, REG_CAP_NONE, REG_WDR_OFF,
+	},
+	[REG_SCENE_SPORTS] = {
+		REG_AE_CENTER, REG_AE_INDEX_00, REG_AWB_AUTO, 0,
+		REG_CHROMA_ON, 3, REG_EDGE_ON, 5,
+		REG_AF_NORMAL, REG_FD_OFF,
+		REG_MCC_OFF, REG_LIGHT_OFF, REG_FLASH_OFF,
+		6, REG_ISO_AUTO, REG_CAP_NONE, REG_WDR_OFF,
+	},
+	[REG_SCENE_PARTY_INDOOR] = {
+		REG_AE_CENTER, REG_AE_INDEX_00, REG_AWB_AUTO, 0,
+		REG_CHROMA_ON, 4, REG_EDGE_ON, 5,
+		REG_AF_NORMAL, REG_FD_OFF,
+		REG_MCC_OFF, REG_LIGHT_OFF, REG_FLASH_OFF,
+		6, REG_ISO_200, REG_CAP_NONE, REG_WDR_OFF,
+	},
+	[REG_SCENE_BEACH_SNOW] = {
+		REG_AE_CENTER, REG_AE_INDEX_10_POS, REG_AWB_AUTO, 0,
+		REG_CHROMA_ON, 4, REG_EDGE_ON, 5,
+		REG_AF_NORMAL, REG_FD_OFF,
+		REG_MCC_OFF, REG_LIGHT_OFF, REG_FLASH_OFF,
+		6, REG_ISO_50, REG_CAP_NONE, REG_WDR_OFF,
+	},
+	[REG_SCENE_SUNSET] = {
+		REG_AE_CENTER, REG_AE_INDEX_00, REG_AWB_PRESET,
+		REG_AWB_DAYLIGHT,
+		REG_CHROMA_ON, 3, REG_EDGE_ON, 5,
+		REG_AF_NORMAL, REG_FD_OFF,
+		REG_MCC_OFF, REG_LIGHT_OFF, REG_FLASH_OFF,
+		6, REG_ISO_AUTO, REG_CAP_NONE, REG_WDR_OFF,
+	},
+	[REG_SCENE_DAWN_DUSK] = {
+		REG_AE_CENTER, REG_AE_INDEX_00, REG_AWB_PRESET,
+		REG_AWB_FLUORESCENT_1,
+		REG_CHROMA_ON, 3, REG_EDGE_ON, 5,
+		REG_AF_NORMAL, REG_FD_OFF,
+		REG_MCC_OFF, REG_LIGHT_OFF, REG_FLASH_OFF,
+		6, REG_ISO_AUTO, REG_CAP_NONE, REG_WDR_OFF,
+	},
+	[REG_SCENE_FALL] = {
+		REG_AE_CENTER, REG_AE_INDEX_00, REG_AWB_AUTO, 0,
+		REG_CHROMA_ON, 5, REG_EDGE_ON, 5,
+		REG_AF_NORMAL, REG_FD_OFF,
+		REG_MCC_OFF, REG_LIGHT_OFF, REG_FLASH_OFF,
+		6, REG_ISO_AUTO, REG_CAP_NONE, REG_WDR_OFF,
+	},
+	[REG_SCENE_NIGHT] = {
+		REG_AE_CENTER, REG_AE_INDEX_00, REG_AWB_AUTO, 0,
+		REG_CHROMA_ON, 3, REG_EDGE_ON, 5,
+		REG_AF_NORMAL, REG_FD_OFF,
+		REG_MCC_OFF, REG_LIGHT_OFF, REG_FLASH_OFF,
+		6, REG_ISO_AUTO, REG_CAP_NONE, REG_WDR_OFF,
+	},
+	[REG_SCENE_AGAINST_LIGHT] = {
+		REG_AE_CENTER, REG_AE_INDEX_00, REG_AWB_AUTO, 0,
+		REG_CHROMA_ON, 3, REG_EDGE_ON, 5,
+		REG_AF_NORMAL, REG_FD_OFF,
+		REG_MCC_OFF, REG_LIGHT_OFF, REG_FLASH_OFF,
+		6, REG_ISO_AUTO, REG_CAP_NONE, REG_WDR_OFF,
+	},
+	[REG_SCENE_FIRE] = {
+		REG_AE_CENTER, REG_AE_INDEX_00, REG_AWB_AUTO, 0,
+		REG_CHROMA_ON, 3, REG_EDGE_ON, 5,
+		REG_AF_NORMAL, REG_FD_OFF,
+		REG_MCC_OFF, REG_LIGHT_OFF, REG_FLASH_OFF,
+		6, REG_ISO_50, REG_CAP_NONE, REG_WDR_OFF,
+	},
+	[REG_SCENE_TEXT] = {
+		REG_AE_CENTER, REG_AE_INDEX_00, REG_AWB_AUTO, 0,
+		REG_CHROMA_ON, 3, REG_EDGE_ON, 7,
+		REG_AF_MACRO, REG_FD_OFF,
+		REG_MCC_OFF, REG_LIGHT_OFF, REG_FLASH_OFF,
+		6, REG_ISO_AUTO, REG_CAP_ANTI_SHAKE, REG_WDR_ON,
+	},
+	[REG_SCENE_CANDLE] = {
+		REG_AE_CENTER, REG_AE_INDEX_00, REG_AWB_AUTO, 0,
+		REG_CHROMA_ON, 3, REG_EDGE_ON, 5,
+		REG_AF_NORMAL, REG_FD_OFF,
+		REG_MCC_OFF, REG_LIGHT_OFF, REG_FLASH_OFF,
+		6, REG_ISO_AUTO, REG_CAP_NONE, REG_WDR_OFF,
+	},
+};
+
+/**
+ * m5mols_do_scenemode() - Change current scenemode
+ * @mode:	Desired mode of the scenemode
+ *
+ * WARNING: The execution order is important. Do not change the order.
+ */
+int m5mols_do_scenemode(struct m5mols_info *info, u8 mode)
+{
+	struct v4l2_subdev *sd = &info->sd;
+	struct m5mols_scenemode scenemode = m5mols_default_scenemode[mode];
+	int ret;
+
+	if (mode > REG_SCENE_CANDLE)
+		return -EINVAL;
+
+	ret = m5mols_lock_3a(info, false);
+	if (!ret)
+		ret = m5mols_write(sd, AE_EV_PRESET_MONITOR, mode);
+	if (!ret)
+		ret = m5mols_write(sd, AE_EV_PRESET_CAPTURE, mode);
+	if (!ret)
+		ret = m5mols_write(sd, AE_MODE, scenemode.metering);
+	if (!ret)
+		ret = m5mols_write(sd, AE_INDEX, scenemode.ev_bias);
+	if (!ret)
+		ret = m5mols_write(sd, AWB_MODE, scenemode.wb_mode);
+	if (!ret)
+		ret = m5mols_write(sd, AWB_MANUAL, scenemode.wb_preset);
+	if (!ret)
+		ret = m5mols_write(sd, MON_CHROMA_EN, scenemode.chroma_en);
+	if (!ret)
+		ret = m5mols_write(sd, MON_CHROMA_LVL, scenemode.chroma_lvl);
+	if (!ret)
+		ret = m5mols_write(sd, MON_EDGE_EN, scenemode.edge_en);
+	if (!ret)
+		ret = m5mols_write(sd, MON_EDGE_LVL, scenemode.edge_lvl);
+	if (!ret && is_available_af(info))
+		ret = m5mols_write(sd, AF_MODE, scenemode.af_range);
+	if (!ret && is_available_af(info))
+		ret = m5mols_write(sd, FD_CTL, scenemode.fd_mode);
+	if (!ret)
+		ret = m5mols_write(sd, MON_TONE_CTL, scenemode.tone);
+	if (!ret)
+		ret = m5mols_write(sd, AE_ISO, scenemode.iso);
+	if (!ret)
+		ret = m5mols_mode(info, REG_CAPTURE);
+	if (!ret)
+		ret = m5mols_write(sd, CAPP_WDR_EN, scenemode.wdr);
+	if (!ret)
+		ret = m5mols_write(sd, CAPP_MCC_MODE, scenemode.mcc);
+	if (!ret)
+		ret = m5mols_write(sd, CAPP_LIGHT_CTRL, scenemode.light);
+	if (!ret)
+		ret = m5mols_write(sd, CAPP_FLASH_CTRL, scenemode.flash);
+	if (!ret)
+		ret = m5mols_write(sd, CAPC_MODE, scenemode.capt_mode);
+	if (!ret)
+		ret = m5mols_mode(info, REG_MONITOR);
+
+	return ret;
+}
+
+static int m5mols_lock_ae(struct m5mols_info *info, bool lock)
+{
+	int ret = 0;
+
+	if (info->lock_ae != lock)
+		ret = m5mols_write(&info->sd, AE_LOCK,
+				lock ? REG_AE_LOCK : REG_AE_UNLOCK);
+	if (!ret)
+		info->lock_ae = lock;
+
+	return ret;
+}
+
+static int m5mols_lock_awb(struct m5mols_info *info, bool lock)
+{
+	int ret = 0;
+
+	if (info->lock_awb != lock)
+		ret = m5mols_write(&info->sd, AWB_LOCK,
+				lock ? REG_AWB_LOCK : REG_AWB_UNLOCK);
+	if (!ret)
+		info->lock_awb = lock;
+
+	return ret;
+}
+
+/* m5mols_lock_3a() - Lock 3A(Auto Exposure, Auto Whitebalance, Auto Focus) */
+int m5mols_lock_3a(struct m5mols_info *info, bool lock)
+{
+	int ret;
+
+	ret = m5mols_lock_ae(info, lock);
+	if (!ret)
+		ret = m5mols_lock_awb(info, lock);
+	/* Don't need to handle unlocking AF */
+	if (!ret && is_available_af(info) && lock)
+		ret = m5mols_write(&info->sd, AF_EXECUTE, REG_AF_STOP);
+
+	return ret;
+}
+
+/* m5mols_set_ctrl() - The main s_ctrl function called by m5mols_set_ctrl() */
+int m5mols_set_ctrl(struct v4l2_ctrl *ctrl)
+{
+	struct v4l2_subdev *sd = to_sd(ctrl);
+	struct m5mols_info *info = to_m5mols(sd);
+	int ret;
+
+	switch (ctrl->id) {
+	case V4L2_CID_ZOOM_ABSOLUTE:
+		return m5mols_write(sd, MON_ZOOM, ctrl->val);
+
+	case V4L2_CID_EXPOSURE_AUTO:
+		ret = m5mols_lock_ae(info,
+			ctrl->val == V4L2_EXPOSURE_AUTO ? false : true);
+		if (!ret && ctrl->val == V4L2_EXPOSURE_AUTO)
+			ret = m5mols_write(sd, AE_MODE, REG_AE_ALL);
+		if (!ret && ctrl->val == V4L2_EXPOSURE_MANUAL) {
+			int val = info->exposure->val;
+			ret = m5mols_write(sd, AE_MODE, REG_AE_OFF);
+			if (!ret)
+				ret = m5mols_write(sd, AE_MAN_GAIN_MON, val);
+			if (!ret)
+				ret = m5mols_write(sd, AE_MAN_GAIN_CAP, val);
+		}
+		return ret;
+
+	case V4L2_CID_AUTO_WHITE_BALANCE:
+		ret = m5mols_lock_awb(info, ctrl->val ? false : true);
+		if (!ret)
+			ret = m5mols_write(sd, AWB_MODE, ctrl->val ?
+				REG_AWB_AUTO : REG_AWB_PRESET);
+		return ret;
+
+	case V4L2_CID_SATURATION:
+		ret = m5mols_write(sd, MON_CHROMA_LVL, ctrl->val);
+		if (!ret)
+			ret = m5mols_write(sd, MON_CHROMA_EN, REG_CHROMA_ON);
+		return ret;
+
+	case V4L2_CID_COLORFX:
+		/*
+		 * This control uses two kinds of registers: normal & color.
+		 * The normal effect belongs to category 1, while the color
+		 * one belongs to category 2.
+		 *
+		 * The normal effect uses one register: CAT1_EFFECT.
+		 * The color effect uses three registers:
+		 * CAT2_COLOR_EFFECT, CAT2_CFIXR, CAT2_CFIXB.
+		 */
+		ret = m5mols_write(sd, PARM_EFFECT,
+			ctrl->val == V4L2_COLORFX_NEGATIVE ? REG_EFFECT_NEGA :
+			ctrl->val == V4L2_COLORFX_EMBOSS ? REG_EFFECT_EMBOSS :
+			REG_EFFECT_OFF);
+		if (!ret)
+			ret = m5mols_write(sd, MON_EFFECT,
+				ctrl->val == V4L2_COLORFX_SEPIA ?
+				REG_COLOR_EFFECT_ON : REG_COLOR_EFFECT_OFF);
+		if (!ret)
+			ret = m5mols_write(sd, MON_CFIXR,
+				ctrl->val == V4L2_COLORFX_SEPIA ?
+				REG_CFIXR_SEPIA : 0);
+		if (!ret)
+			ret = m5mols_write(sd, MON_CFIXB,
+				ctrl->val == V4L2_COLORFX_SEPIA ?
+				REG_CFIXB_SEPIA : 0);
+		return ret;
+	}
+
+	return -EINVAL;
+}
diff -druN linux-2.6.39-libre/drivers/media/video/m5mols/m5mols_core.c linux-3.0-rc7-libre/drivers/media/video/m5mols/m5mols_core.c
--- linux-2.6.39-libre/drivers/media/video/m5mols/m5mols_core.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/media/video/m5mols/m5mols_core.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,1042 @@
+/*
+ * Driver for M-5MOLS 8M Pixel camera sensor with ISP
+ *
+ * Copyright (C) 2011 Samsung Electronics Co., Ltd.
+ * Author: HeungJun Kim <riverful.kim@samsung.com>
+ *
+ * Copyright (C) 2009 Samsung Electronics Co., Ltd.
+ * Author: Dongsoo Nathaniel Kim <dongsoo45.kim@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/i2c.h>
+#include <linux/slab.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <linux/version.h>
+#include <linux/gpio.h>
+#include <linux/regulator/consumer.h>
+#include <linux/videodev2.h>
+#include <media/v4l2-ctrls.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-subdev.h>
+#include <media/m5mols.h>
+
+#include "m5mols.h"
+#include "m5mols_reg.h"
+
+int m5mols_debug;
+module_param(m5mols_debug, int, 0644);
+
+#define MODULE_NAME		"M5MOLS"
+#define M5MOLS_I2C_CHECK_RETRY	500
+
+/* The regulator consumer names for external voltage regulators */
+static struct regulator_bulk_data supplies[] = {
+	{
+		.supply = "core",	/* ARM core power, 1.2V */
+	}, {
+		.supply	= "dig_18",	/* digital power 1, 1.8V */
+	}, {
+		.supply	= "d_sensor",	/* sensor power 1, 1.8V */
+	}, {
+		.supply	= "dig_28",	/* digital power 2, 2.8V */
+	}, {
+		.supply	= "a_sensor",	/* analog power */
+	}, {
+		.supply	= "dig_12",	/* digital power 3, 1.2V */
+	},
+};
+
+static struct v4l2_mbus_framefmt m5mols_default_ffmt[M5MOLS_RESTYPE_MAX] = {
+	[M5MOLS_RESTYPE_MONITOR] = {
+		.width		= 1920,
+		.height		= 1080,
+		.code		= V4L2_MBUS_FMT_VYUY8_2X8,
+		.field		= V4L2_FIELD_NONE,
+		.colorspace	= V4L2_COLORSPACE_JPEG,
+	},
+	[M5MOLS_RESTYPE_CAPTURE] = {
+		.width		= 1920,
+		.height		= 1080,
+		.code		= V4L2_MBUS_FMT_JPEG_1X8,
+		.field		= V4L2_FIELD_NONE,
+		.colorspace	= V4L2_COLORSPACE_JPEG,
+	},
+};
+#define SIZE_DEFAULT_FFMT	ARRAY_SIZE(m5mols_default_ffmt)
+
+static const struct m5mols_resolution m5mols_reg_res[] = {
+	{ 0x01, M5MOLS_RESTYPE_MONITOR, 128, 96 },	/* SUB-QCIF */
+	{ 0x03, M5MOLS_RESTYPE_MONITOR, 160, 120 },	/* QQVGA */
+	{ 0x05, M5MOLS_RESTYPE_MONITOR, 176, 144 },	/* QCIF */
+	{ 0x06, M5MOLS_RESTYPE_MONITOR, 176, 176 },
+	{ 0x08, M5MOLS_RESTYPE_MONITOR, 240, 320 },	/* QVGA */
+	{ 0x09, M5MOLS_RESTYPE_MONITOR, 320, 240 },	/* QVGA */
+	{ 0x0c, M5MOLS_RESTYPE_MONITOR, 240, 400 },	/* WQVGA */
+	{ 0x0d, M5MOLS_RESTYPE_MONITOR, 400, 240 },	/* WQVGA */
+	{ 0x0e, M5MOLS_RESTYPE_MONITOR, 352, 288 },	/* CIF */
+	{ 0x13, M5MOLS_RESTYPE_MONITOR, 480, 360 },
+	{ 0x15, M5MOLS_RESTYPE_MONITOR, 640, 360 },	/* qHD */
+	{ 0x17, M5MOLS_RESTYPE_MONITOR, 640, 480 },	/* VGA */
+	{ 0x18, M5MOLS_RESTYPE_MONITOR, 720, 480 },
+	{ 0x1a, M5MOLS_RESTYPE_MONITOR, 800, 480 },	/* WVGA */
+	{ 0x1f, M5MOLS_RESTYPE_MONITOR, 800, 600 },	/* SVGA */
+	{ 0x21, M5MOLS_RESTYPE_MONITOR, 1280, 720 },	/* HD */
+	{ 0x25, M5MOLS_RESTYPE_MONITOR, 1920, 1080 },	/* 1080p */
+	{ 0x29, M5MOLS_RESTYPE_MONITOR, 3264, 2448 },	/* 2.63fps 8M */
+	{ 0x39, M5MOLS_RESTYPE_MONITOR, 800, 602 },	/* AHS_MON debug */
+
+	{ 0x02, M5MOLS_RESTYPE_CAPTURE, 320, 240 },	/* QVGA */
+	{ 0x04, M5MOLS_RESTYPE_CAPTURE, 400, 240 },	/* WQVGA */
+	{ 0x07, M5MOLS_RESTYPE_CAPTURE, 480, 360 },
+	{ 0x08, M5MOLS_RESTYPE_CAPTURE, 640, 360 },	/* qHD */
+	{ 0x09, M5MOLS_RESTYPE_CAPTURE, 640, 480 },	/* VGA */
+	{ 0x0a, M5MOLS_RESTYPE_CAPTURE, 800, 480 },	/* WVGA */
+	{ 0x10, M5MOLS_RESTYPE_CAPTURE, 1280, 720 },	/* HD */
+	{ 0x14, M5MOLS_RESTYPE_CAPTURE, 1280, 960 },	/* 1M */
+	{ 0x17, M5MOLS_RESTYPE_CAPTURE, 1600, 1200 },	/* 2M */
+	{ 0x19, M5MOLS_RESTYPE_CAPTURE, 1920, 1080 },	/* Full-HD */
+	{ 0x1a, M5MOLS_RESTYPE_CAPTURE, 2048, 1152 },	/* 3Mega */
+	{ 0x1b, M5MOLS_RESTYPE_CAPTURE, 2048, 1536 },
+	{ 0x1c, M5MOLS_RESTYPE_CAPTURE, 2560, 1440 },	/* 4Mega */
+	{ 0x1d, M5MOLS_RESTYPE_CAPTURE, 2560, 1536 },
+	{ 0x1f, M5MOLS_RESTYPE_CAPTURE, 2560, 1920 },	/* 5Mega */
+	{ 0x21, M5MOLS_RESTYPE_CAPTURE, 3264, 1836 },	/* 6Mega */
+	{ 0x22, M5MOLS_RESTYPE_CAPTURE, 3264, 1960 },
+	{ 0x25, M5MOLS_RESTYPE_CAPTURE, 3264, 2448 },	/* 8Mega */
+};
+
+/**
+ * m5mols_swap_byte - an byte array to integer conversion function
+ * @size: size in bytes of I2C packet defined in the M-5MOLS datasheet
+ *
+ * Convert I2C data byte array with performing any required byte
+ * reordering to assure proper values for each data type, regardless
+ * of the architecture endianness.
+ */
+static u32 m5mols_swap_byte(u8 *data, u8 length)
+{
+	if (length == 1)
+		return *data;
+	else if (length == 2)
+		return be16_to_cpu(*((u16 *)data));
+	else
+		return be32_to_cpu(*((u32 *)data));
+}
+
+/**
+ * m5mols_read -  I2C read function
+ * @reg: combination of size, category and command for the I2C packet
+ * @size: desired size of I2C packet
+ * @val: read value
+ */
+static int m5mols_read(struct v4l2_subdev *sd, u32 size, u32 reg, u32 *val)
+{
+	struct i2c_client *client = v4l2_get_subdevdata(sd);
+	u8 rbuf[M5MOLS_I2C_MAX_SIZE + 1];
+	u8 category = I2C_CATEGORY(reg);
+	u8 cmd = I2C_COMMAND(reg);
+	struct i2c_msg msg[2];
+	u8 wbuf[5];
+	int ret;
+
+	if (!client->adapter)
+		return -ENODEV;
+
+	msg[0].addr = client->addr;
+	msg[0].flags = 0;
+	msg[0].len = 5;
+	msg[0].buf = wbuf;
+	wbuf[0] = 5;
+	wbuf[1] = M5MOLS_BYTE_READ;
+	wbuf[2] = category;
+	wbuf[3] = cmd;
+	wbuf[4] = size;
+
+	msg[1].addr = client->addr;
+	msg[1].flags = I2C_M_RD;
+	msg[1].len = size + 1;
+	msg[1].buf = rbuf;
+
+	/* minimum stabilization time */
+	usleep_range(200, 200);
+
+	ret = i2c_transfer(client->adapter, msg, 2);
+	if (ret < 0) {
+		v4l2_err(sd, "read failed: size:%d cat:%02x cmd:%02x. %d\n",
+			 size, category, cmd, ret);
+		return ret;
+	}
+
+	*val = m5mols_swap_byte(&rbuf[1], size);
+
+	return 0;
+}
+
+int m5mols_read_u8(struct v4l2_subdev *sd, u32 reg, u8 *val)
+{
+	u32 val_32;
+	int ret;
+
+	if (I2C_SIZE(reg) != 1) {
+		v4l2_err(sd, "Wrong data size\n");
+		return -EINVAL;
+	}
+
+	ret = m5mols_read(sd, I2C_SIZE(reg), reg, &val_32);
+	if (ret)
+		return ret;
+
+	*val = (u8)val_32;
+	return ret;
+}
+
+int m5mols_read_u16(struct v4l2_subdev *sd, u32 reg, u16 *val)
+{
+	u32 val_32;
+	int ret;
+
+	if (I2C_SIZE(reg) != 2) {
+		v4l2_err(sd, "Wrong data size\n");
+		return -EINVAL;
+	}
+
+	ret = m5mols_read(sd, I2C_SIZE(reg), reg, &val_32);
+	if (ret)
+		return ret;
+
+	*val = (u16)val_32;
+	return ret;
+}
+
+int m5mols_read_u32(struct v4l2_subdev *sd, u32 reg, u32 *val)
+{
+	if (I2C_SIZE(reg) != 4) {
+		v4l2_err(sd, "Wrong data size\n");
+		return -EINVAL;
+	}
+
+	return m5mols_read(sd, I2C_SIZE(reg), reg, val);
+}
+
+/**
+ * m5mols_write - I2C command write function
+ * @reg: combination of size, category and command for the I2C packet
+ * @val: value to write
+ */
+int m5mols_write(struct v4l2_subdev *sd, u32 reg, u32 val)
+{
+	struct i2c_client *client = v4l2_get_subdevdata(sd);
+	u8 wbuf[M5MOLS_I2C_MAX_SIZE + 4];
+	u8 category = I2C_CATEGORY(reg);
+	u8 cmd = I2C_COMMAND(reg);
+	u8 size	= I2C_SIZE(reg);
+	u32 *buf = (u32 *)&wbuf[4];
+	struct i2c_msg msg[1];
+	int ret;
+
+	if (!client->adapter)
+		return -ENODEV;
+
+	if (size != 1 && size != 2 && size != 4) {
+		v4l2_err(sd, "Wrong data size\n");
+		return -EINVAL;
+	}
+
+	msg->addr = client->addr;
+	msg->flags = 0;
+	msg->len = (u16)size + 4;
+	msg->buf = wbuf;
+	wbuf[0] = size + 4;
+	wbuf[1] = M5MOLS_BYTE_WRITE;
+	wbuf[2] = category;
+	wbuf[3] = cmd;
+
+	*buf = m5mols_swap_byte((u8 *)&val, size);
+
+	usleep_range(200, 200);
+
+	ret = i2c_transfer(client->adapter, msg, 1);
+	if (ret < 0) {
+		v4l2_err(sd, "write failed: size:%d cat:%02x cmd:%02x. %d\n",
+			size, category, cmd, ret);
+		return ret;
+	}
+
+	return 0;
+}
+
+int m5mols_busy(struct v4l2_subdev *sd, u8 category, u8 cmd, u8 mask)
+{
+	u8 busy;
+	int i;
+	int ret;
+
+	for (i = 0; i < M5MOLS_I2C_CHECK_RETRY; i++) {
+		ret = m5mols_read_u8(sd, I2C_REG(category, cmd, 1), &busy);
+		if (ret < 0)
+			return ret;
+		if ((busy & mask) == mask)
+			return 0;
+	}
+	return -EBUSY;
+}
+
+/**
+ * m5mols_enable_interrupt - Clear interrupt pending bits and unmask interrupts
+ *
+ * Before writing desired interrupt value the INT_FACTOR register should
+ * be read to clear pending interrupts.
+ */
+int m5mols_enable_interrupt(struct v4l2_subdev *sd, u8 reg)
+{
+	struct m5mols_info *info = to_m5mols(sd);
+	u8 mask = is_available_af(info) ? REG_INT_AF : 0;
+	u8 dummy;
+	int ret;
+
+	ret = m5mols_read_u8(sd, SYSTEM_INT_FACTOR, &dummy);
+	if (!ret)
+		ret = m5mols_write(sd, SYSTEM_INT_ENABLE, reg & ~mask);
+	return ret;
+}
+
+/**
+ * m5mols_reg_mode - Write the mode and check busy status
+ *
+ * It always accompanies a little delay changing the M-5MOLS mode, so it is
+ * needed checking current busy status to guarantee right mode.
+ */
+static int m5mols_reg_mode(struct v4l2_subdev *sd, u8 mode)
+{
+	int ret = m5mols_write(sd, SYSTEM_SYSMODE, mode);
+
+	return ret ? ret : m5mols_busy(sd, CAT_SYSTEM, CAT0_SYSMODE, mode);
+}
+
+/**
+ * m5mols_mode - manage the M-5MOLS's mode
+ * @mode: the required operation mode
+ *
+ * The commands of M-5MOLS are grouped into specific modes. Each functionality
+ * can be guaranteed only when the sensor is operating in mode which which
+ * a command belongs to.
+ */
+int m5mols_mode(struct m5mols_info *info, u8 mode)
+{
+	struct v4l2_subdev *sd = &info->sd;
+	int ret = -EINVAL;
+	u8 reg;
+
+	if (mode < REG_PARAMETER && mode > REG_CAPTURE)
+		return ret;
+
+	ret = m5mols_read_u8(sd, SYSTEM_SYSMODE, &reg);
+	if ((!ret && reg == mode) || ret)
+		return ret;
+
+	switch (reg) {
+	case REG_PARAMETER:
+		ret = m5mols_reg_mode(sd, REG_MONITOR);
+		if (!ret && mode == REG_MONITOR)
+			break;
+		if (!ret)
+			ret = m5mols_reg_mode(sd, REG_CAPTURE);
+		break;
+
+	case REG_MONITOR:
+		if (mode == REG_PARAMETER) {
+			ret = m5mols_reg_mode(sd, REG_PARAMETER);
+			break;
+		}
+
+		ret = m5mols_reg_mode(sd, REG_CAPTURE);
+		break;
+
+	case REG_CAPTURE:
+		ret = m5mols_reg_mode(sd, REG_MONITOR);
+		if (!ret && mode == REG_MONITOR)
+			break;
+		if (!ret)
+			ret = m5mols_reg_mode(sd, REG_PARAMETER);
+		break;
+
+	default:
+		v4l2_warn(sd, "Wrong mode: %d\n", mode);
+	}
+
+	if (!ret)
+		info->mode = mode;
+
+	return ret;
+}
+
+/**
+ * m5mols_get_version - retrieve full revisions information of M-5MOLS
+ *
+ * The version information includes revisions of hardware and firmware,
+ * AutoFocus alghorithm version and the version string.
+ */
+static int m5mols_get_version(struct v4l2_subdev *sd)
+{
+	struct m5mols_info *info = to_m5mols(sd);
+	struct m5mols_version *ver = &info->ver;
+	u8 *str = ver->str;
+	int i;
+	int ret;
+
+	ret = m5mols_read_u8(sd, SYSTEM_VER_CUSTOMER, &ver->customer);
+	if (!ret)
+		ret = m5mols_read_u8(sd, SYSTEM_VER_PROJECT, &ver->project);
+	if (!ret)
+		ret = m5mols_read_u16(sd, SYSTEM_VER_FIRMWARE, &ver->fw);
+	if (!ret)
+		ret = m5mols_read_u16(sd, SYSTEM_VER_HARDWARE, &ver->hw);
+	if (!ret)
+		ret = m5mols_read_u16(sd, SYSTEM_VER_PARAMETER, &ver->param);
+	if (!ret)
+		ret = m5mols_read_u16(sd, SYSTEM_VER_AWB, &ver->awb);
+	if (!ret)
+		ret = m5mols_read_u8(sd, AF_VERSION, &ver->af);
+	if (ret)
+		return ret;
+
+	for (i = 0; i < VERSION_STRING_SIZE; i++) {
+		ret = m5mols_read_u8(sd, SYSTEM_VER_STRING, &str[i]);
+		if (ret)
+			return ret;
+	}
+
+	ver->fw = be16_to_cpu(ver->fw);
+	ver->hw = be16_to_cpu(ver->hw);
+	ver->param = be16_to_cpu(ver->param);
+	ver->awb = be16_to_cpu(ver->awb);
+
+	v4l2_info(sd, "Manufacturer\t[%s]\n",
+			is_manufacturer(info, REG_SAMSUNG_ELECTRO) ?
+			"Samsung Electro-Machanics" :
+			is_manufacturer(info, REG_SAMSUNG_OPTICS) ?
+			"Samsung Fiber-Optics" :
+			is_manufacturer(info, REG_SAMSUNG_TECHWIN) ?
+			"Samsung Techwin" : "None");
+	v4l2_info(sd, "Customer/Project\t[0x%02x/0x%02x]\n",
+			info->ver.customer, info->ver.project);
+
+	if (!is_available_af(info))
+		v4l2_info(sd, "No support Auto Focus on this firmware\n");
+
+	return ret;
+}
+
+/**
+ * __find_restype - Lookup M-5MOLS resolution type according to pixel code
+ * @code: pixel code
+ */
+static enum m5mols_restype __find_restype(enum v4l2_mbus_pixelcode code)
+{
+	enum m5mols_restype type = M5MOLS_RESTYPE_MONITOR;
+
+	do {
+		if (code == m5mols_default_ffmt[type].code)
+			return type;
+	} while (type++ != SIZE_DEFAULT_FFMT);
+
+	return 0;
+}
+
+/**
+ * __find_resolution - Lookup preset and type of M-5MOLS's resolution
+ * @mf: pixel format to find/negotiate the resolution preset for
+ * @type: M-5MOLS resolution type
+ * @resolution:	M-5MOLS resolution preset register value
+ *
+ * Find nearest resolution matching resolution preset and adjust mf
+ * to supported values.
+ */
+static int __find_resolution(struct v4l2_subdev *sd,
+			     struct v4l2_mbus_framefmt *mf,
+			     enum m5mols_restype *type,
+			     u32 *resolution)
+{
+	const struct m5mols_resolution *fsize = &m5mols_reg_res[0];
+	const struct m5mols_resolution *match = NULL;
+	enum m5mols_restype stype = __find_restype(mf->code);
+	int i = ARRAY_SIZE(m5mols_reg_res);
+	unsigned int min_err = ~0;
+
+	while (i--) {
+		int err;
+		if (stype == fsize->type) {
+			err = abs(fsize->width - mf->width)
+				+ abs(fsize->height - mf->height);
+
+			if (err < min_err) {
+				min_err = err;
+				match = fsize;
+			}
+		}
+		fsize++;
+	}
+	if (match) {
+		mf->width  = match->width;
+		mf->height = match->height;
+		*resolution = match->reg;
+		*type = stype;
+		return 0;
+	}
+
+	return -EINVAL;
+}
+
+static struct v4l2_mbus_framefmt *__find_format(struct m5mols_info *info,
+				struct v4l2_subdev_fh *fh,
+				enum v4l2_subdev_format_whence which,
+				enum m5mols_restype type)
+{
+	if (which == V4L2_SUBDEV_FORMAT_TRY)
+		return fh ? v4l2_subdev_get_try_format(fh, 0) : NULL;
+
+	return &info->ffmt[type];
+}
+
+static int m5mols_get_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
+			  struct v4l2_subdev_format *fmt)
+{
+	struct m5mols_info *info = to_m5mols(sd);
+	struct v4l2_mbus_framefmt *format;
+
+	if (fmt->pad != 0)
+		return -EINVAL;
+
+	format = __find_format(info, fh, fmt->which, info->res_type);
+	if (!format)
+		return -EINVAL;
+
+	fmt->format = *format;
+	return 0;
+}
+
+static int m5mols_set_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
+			  struct v4l2_subdev_format *fmt)
+{
+	struct m5mols_info *info = to_m5mols(sd);
+	struct v4l2_mbus_framefmt *format = &fmt->format;
+	struct v4l2_mbus_framefmt *sfmt;
+	enum m5mols_restype type;
+	u32 resolution = 0;
+	int ret;
+
+	if (fmt->pad != 0)
+		return -EINVAL;
+
+	ret = __find_resolution(sd, format, &type, &resolution);
+	if (ret < 0)
+		return ret;
+
+	sfmt = __find_format(info, fh, fmt->which, type);
+	if (!sfmt)
+		return 0;
+
+	*sfmt		= m5mols_default_ffmt[type];
+	sfmt->width	= format->width;
+	sfmt->height	= format->height;
+
+	if (fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE) {
+		info->resolution = resolution;
+		info->code = format->code;
+		info->res_type = type;
+	}
+
+	return 0;
+}
+
+static int m5mols_enum_mbus_code(struct v4l2_subdev *sd,
+				 struct v4l2_subdev_fh *fh,
+				 struct v4l2_subdev_mbus_code_enum *code)
+{
+	if (!code || code->index >= SIZE_DEFAULT_FFMT)
+		return -EINVAL;
+
+	code->code = m5mols_default_ffmt[code->index].code;
+
+	return 0;
+}
+
+static struct v4l2_subdev_pad_ops m5mols_pad_ops = {
+	.enum_mbus_code	= m5mols_enum_mbus_code,
+	.get_fmt	= m5mols_get_fmt,
+	.set_fmt	= m5mols_set_fmt,
+};
+
+/**
+ * m5mols_sync_controls - Apply default scene mode and the current controls
+ *
+ * This is used only streaming for syncing between v4l2_ctrl framework and
+ * m5mols's controls. First, do the scenemode to the sensor, then call
+ * v4l2_ctrl_handler_setup. It can be same between some commands and
+ * the scenemode's in the default v4l2_ctrls. But, such commands of control
+ * should be prior to the scenemode's one.
+ */
+int m5mols_sync_controls(struct m5mols_info *info)
+{
+	int ret = -EINVAL;
+
+	if (!is_ctrl_synced(info)) {
+		ret = m5mols_do_scenemode(info, REG_SCENE_NORMAL);
+		if (ret)
+			return ret;
+
+		v4l2_ctrl_handler_setup(&info->handle);
+		info->ctrl_sync = true;
+	}
+
+	return ret;
+}
+
+/**
+ * m5mols_start_monitor - Start the monitor mode
+ *
+ * Before applying the controls setup the resolution and frame rate
+ * in PARAMETER mode, and then switch over to MONITOR mode.
+ */
+static int m5mols_start_monitor(struct m5mols_info *info)
+{
+	struct v4l2_subdev *sd = &info->sd;
+	int ret;
+
+	ret = m5mols_mode(info, REG_PARAMETER);
+	if (!ret)
+		ret = m5mols_write(sd, PARM_MON_SIZE, info->resolution);
+	if (!ret)
+		ret = m5mols_write(sd, PARM_MON_FPS, REG_FPS_30);
+	if (!ret)
+		ret = m5mols_mode(info, REG_MONITOR);
+	if (!ret)
+		ret = m5mols_sync_controls(info);
+
+	return ret;
+}
+
+static int m5mols_s_stream(struct v4l2_subdev *sd, int enable)
+{
+	struct m5mols_info *info = to_m5mols(sd);
+
+	if (enable) {
+		int ret = -EINVAL;
+
+		if (is_code(info->code, M5MOLS_RESTYPE_MONITOR))
+			ret = m5mols_start_monitor(info);
+		if (is_code(info->code, M5MOLS_RESTYPE_CAPTURE))
+			ret = m5mols_start_capture(info);
+
+		return ret;
+	}
+
+	return m5mols_mode(info, REG_PARAMETER);
+}
+
+static const struct v4l2_subdev_video_ops m5mols_video_ops = {
+	.s_stream	= m5mols_s_stream,
+};
+
+static int m5mols_s_ctrl(struct v4l2_ctrl *ctrl)
+{
+	struct v4l2_subdev *sd = to_sd(ctrl);
+	struct m5mols_info *info = to_m5mols(sd);
+	int ret;
+
+	info->mode_save = info->mode;
+
+	ret = m5mols_mode(info, REG_PARAMETER);
+	if (!ret)
+		ret = m5mols_set_ctrl(ctrl);
+	if (!ret)
+		ret = m5mols_mode(info, info->mode_save);
+
+	return ret;
+}
+
+static const struct v4l2_ctrl_ops m5mols_ctrl_ops = {
+	.s_ctrl	= m5mols_s_ctrl,
+};
+
+static int m5mols_sensor_power(struct m5mols_info *info, bool enable)
+{
+	struct v4l2_subdev *sd = &info->sd;
+	struct i2c_client *client = v4l2_get_subdevdata(sd);
+	const struct m5mols_platform_data *pdata = info->pdata;
+	int ret;
+
+	if (enable) {
+		if (is_powered(info))
+			return 0;
+
+		if (info->set_power) {
+			ret = info->set_power(&client->dev, 1);
+			if (ret)
+				return ret;
+		}
+
+		ret = regulator_bulk_enable(ARRAY_SIZE(supplies), supplies);
+		if (ret) {
+			info->set_power(&client->dev, 0);
+			return ret;
+		}
+
+		gpio_set_value(pdata->gpio_reset, !pdata->reset_polarity);
+		usleep_range(1000, 1000);
+		info->power = true;
+
+		return ret;
+	}
+
+	if (!is_powered(info))
+		return 0;
+
+	ret = regulator_bulk_disable(ARRAY_SIZE(supplies), supplies);
+	if (ret)
+		return ret;
+
+	if (info->set_power)
+		info->set_power(&client->dev, 0);
+
+	gpio_set_value(pdata->gpio_reset, pdata->reset_polarity);
+	usleep_range(1000, 1000);
+	info->power = false;
+
+	return ret;
+}
+
+/* m5mols_update_fw - optional firmware update routine */
+int __attribute__ ((weak)) m5mols_update_fw(struct v4l2_subdev *sd,
+		int (*set_power)(struct m5mols_info *, bool))
+{
+	return 0;
+}
+
+/**
+ * m5mols_sensor_armboot - Booting M-5MOLS internal ARM core.
+ *
+ * Booting internal ARM core makes the M-5MOLS is ready for getting commands
+ * with I2C. It's the first thing to be done after it powered up. It must wait
+ * at least 520ms recommended by M-5MOLS datasheet, after executing arm booting.
+ */
+static int m5mols_sensor_armboot(struct v4l2_subdev *sd)
+{
+	int ret;
+
+	ret = m5mols_write(sd, FLASH_CAM_START, REG_START_ARM_BOOT);
+	if (ret < 0)
+		return ret;
+
+	msleep(520);
+
+	ret = m5mols_get_version(sd);
+	if (!ret)
+		ret = m5mols_update_fw(sd, m5mols_sensor_power);
+	if (ret)
+		return ret;
+
+	v4l2_dbg(1, m5mols_debug, sd, "Success ARM Booting\n");
+
+	ret = m5mols_write(sd, PARM_INTERFACE, REG_INTERFACE_MIPI);
+	if (!ret)
+		ret = m5mols_enable_interrupt(sd, REG_INT_AF);
+
+	return ret;
+}
+
+static int m5mols_init_controls(struct m5mols_info *info)
+{
+	struct v4l2_subdev *sd = &info->sd;
+	u16 max_exposure;
+	u16 step_zoom;
+	int ret;
+
+	/* Determine value's range & step of controls for various FW version */
+	ret = m5mols_read_u16(sd, AE_MAX_GAIN_MON, &max_exposure);
+	if (!ret)
+		step_zoom = is_manufacturer(info, REG_SAMSUNG_OPTICS) ? 31 : 1;
+	if (ret)
+		return ret;
+
+	v4l2_ctrl_handler_init(&info->handle, 6);
+	info->autowb = v4l2_ctrl_new_std(&info->handle,
+			&m5mols_ctrl_ops, V4L2_CID_AUTO_WHITE_BALANCE,
+			0, 1, 1, 0);
+	info->saturation = v4l2_ctrl_new_std(&info->handle,
+			&m5mols_ctrl_ops, V4L2_CID_SATURATION,
+			1, 5, 1, 3);
+	info->zoom = v4l2_ctrl_new_std(&info->handle,
+			&m5mols_ctrl_ops, V4L2_CID_ZOOM_ABSOLUTE,
+			1, 70, step_zoom, 1);
+	info->exposure = v4l2_ctrl_new_std(&info->handle,
+			&m5mols_ctrl_ops, V4L2_CID_EXPOSURE,
+			0, max_exposure, 1, (int)max_exposure/2);
+	info->colorfx = v4l2_ctrl_new_std_menu(&info->handle,
+			&m5mols_ctrl_ops, V4L2_CID_COLORFX,
+			4, (1 << V4L2_COLORFX_BW), V4L2_COLORFX_NONE);
+	info->autoexposure = v4l2_ctrl_new_std_menu(&info->handle,
+			&m5mols_ctrl_ops, V4L2_CID_EXPOSURE_AUTO,
+			1, 0, V4L2_EXPOSURE_MANUAL);
+
+	sd->ctrl_handler = &info->handle;
+	if (info->handle.error) {
+		v4l2_err(sd, "Failed to initialize controls: %d\n", ret);
+		v4l2_ctrl_handler_free(&info->handle);
+		return info->handle.error;
+	}
+
+	v4l2_ctrl_cluster(2, &info->autoexposure);
+
+	return 0;
+}
+
+/**
+ * m5mols_s_power - Main sensor power control function
+ *
+ * To prevent breaking the lens when the sensor is powered off the Soft-Landing
+ * algorithm is called where available. The Soft-Landing algorithm availability
+ * dependends on the firmware provider.
+ */
+static int m5mols_s_power(struct v4l2_subdev *sd, int on)
+{
+	struct m5mols_info *info = to_m5mols(sd);
+	int ret;
+
+	if (on) {
+		ret = m5mols_sensor_power(info, true);
+		if (!ret)
+			ret = m5mols_sensor_armboot(sd);
+		if (!ret)
+			ret = m5mols_init_controls(info);
+		if (ret)
+			return ret;
+
+		info->ffmt[M5MOLS_RESTYPE_MONITOR] =
+			m5mols_default_ffmt[M5MOLS_RESTYPE_MONITOR];
+		info->ffmt[M5MOLS_RESTYPE_CAPTURE] =
+			m5mols_default_ffmt[M5MOLS_RESTYPE_CAPTURE];
+		return ret;
+	}
+
+	if (is_manufacturer(info, REG_SAMSUNG_TECHWIN)) {
+		ret = m5mols_mode(info, REG_MONITOR);
+		if (!ret)
+			ret = m5mols_write(sd, AF_EXECUTE, REG_AF_STOP);
+		if (!ret)
+			ret = m5mols_write(sd, AF_MODE, REG_AF_POWEROFF);
+		if (!ret)
+			ret = m5mols_busy(sd, CAT_SYSTEM, CAT0_STATUS,
+					REG_AF_IDLE);
+		if (!ret)
+			v4l2_info(sd, "Success soft-landing lens\n");
+	}
+
+	ret = m5mols_sensor_power(info, false);
+	if (!ret) {
+		v4l2_ctrl_handler_free(&info->handle);
+		info->ctrl_sync = false;
+	}
+
+	return ret;
+}
+
+static int m5mols_log_status(struct v4l2_subdev *sd)
+{
+	struct m5mols_info *info = to_m5mols(sd);
+
+	v4l2_ctrl_handler_log_status(&info->handle, sd->name);
+
+	return 0;
+}
+
+static const struct v4l2_subdev_core_ops m5mols_core_ops = {
+	.s_power	= m5mols_s_power,
+	.g_ctrl		= v4l2_subdev_g_ctrl,
+	.s_ctrl		= v4l2_subdev_s_ctrl,
+	.queryctrl	= v4l2_subdev_queryctrl,
+	.querymenu	= v4l2_subdev_querymenu,
+	.g_ext_ctrls	= v4l2_subdev_g_ext_ctrls,
+	.try_ext_ctrls	= v4l2_subdev_try_ext_ctrls,
+	.s_ext_ctrls	= v4l2_subdev_s_ext_ctrls,
+	.log_status	= m5mols_log_status,
+};
+
+static const struct v4l2_subdev_ops m5mols_ops = {
+	.core		= &m5mols_core_ops,
+	.pad		= &m5mols_pad_ops,
+	.video		= &m5mols_video_ops,
+};
+
+static void m5mols_irq_work(struct work_struct *work)
+{
+	struct m5mols_info *info =
+		container_of(work, struct m5mols_info, work_irq);
+	struct v4l2_subdev *sd = &info->sd;
+	u8 reg;
+	int ret;
+
+	if (!is_powered(info) ||
+			m5mols_read_u8(sd, SYSTEM_INT_FACTOR, &info->interrupt))
+		return;
+
+	switch (info->interrupt & REG_INT_MASK) {
+	case REG_INT_AF:
+		if (!is_available_af(info))
+			break;
+		ret = m5mols_read_u8(sd, AF_STATUS, &reg);
+		v4l2_dbg(2, m5mols_debug, sd, "AF %s\n",
+			 reg == REG_AF_FAIL ? "Failed" :
+			 reg == REG_AF_SUCCESS ? "Success" :
+			 reg == REG_AF_IDLE ? "Idle" : "Busy");
+		break;
+	case REG_INT_CAPTURE:
+		if (!test_and_set_bit(ST_CAPT_IRQ, &info->flags))
+			wake_up_interruptible(&info->irq_waitq);
+
+		v4l2_dbg(2, m5mols_debug, sd, "CAPTURE\n");
+		break;
+	default:
+		v4l2_dbg(2, m5mols_debug, sd, "Undefined: %02x\n", reg);
+		break;
+	};
+}
+
+static irqreturn_t m5mols_irq_handler(int irq, void *data)
+{
+	struct v4l2_subdev *sd = data;
+	struct m5mols_info *info = to_m5mols(sd);
+
+	schedule_work(&info->work_irq);
+
+	return IRQ_HANDLED;
+}
+
+static int __devinit m5mols_probe(struct i2c_client *client,
+				  const struct i2c_device_id *id)
+{
+	const struct m5mols_platform_data *pdata = client->dev.platform_data;
+	struct m5mols_info *info;
+	struct v4l2_subdev *sd;
+	int ret;
+
+	if (pdata == NULL) {
+		dev_err(&client->dev, "No platform data\n");
+		return -EINVAL;
+	}
+
+	if (!gpio_is_valid(pdata->gpio_reset)) {
+		dev_err(&client->dev, "No valid RESET GPIO specified\n");
+		return -EINVAL;
+	}
+
+	if (!pdata->irq) {
+		dev_err(&client->dev, "Interrupt not assigned\n");
+		return -EINVAL;
+	}
+
+	info = kzalloc(sizeof(struct m5mols_info), GFP_KERNEL);
+	if (!info)
+		return -ENOMEM;
+
+	info->pdata = pdata;
+	info->set_power	= pdata->set_power;
+
+	ret = gpio_request(pdata->gpio_reset, "M5MOLS_NRST");
+	if (ret) {
+		dev_err(&client->dev, "Failed to request gpio: %d\n", ret);
+		goto out_free;
+	}
+	gpio_direction_output(pdata->gpio_reset, pdata->reset_polarity);
+
+	ret = regulator_bulk_get(&client->dev, ARRAY_SIZE(supplies), supplies);
+	if (ret) {
+		dev_err(&client->dev, "Failed to get regulators: %d\n", ret);
+		goto out_gpio;
+	}
+
+	sd = &info->sd;
+	strlcpy(sd->name, MODULE_NAME, sizeof(sd->name));
+	v4l2_i2c_subdev_init(sd, client, &m5mols_ops);
+
+	info->pad.flags = MEDIA_PAD_FL_SOURCE;
+	ret = media_entity_init(&sd->entity, 1, &info->pad, 0);
+	if (ret < 0)
+		goto out_reg;
+	sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR;
+
+	init_waitqueue_head(&info->irq_waitq);
+	INIT_WORK(&info->work_irq, m5mols_irq_work);
+	ret = request_irq(pdata->irq, m5mols_irq_handler,
+			  IRQF_TRIGGER_RISING, MODULE_NAME, sd);
+	if (ret) {
+		dev_err(&client->dev, "Interrupt request failed: %d\n", ret);
+		goto out_me;
+	}
+	info->res_type = M5MOLS_RESTYPE_MONITOR;
+	return 0;
+out_me:
+	media_entity_cleanup(&sd->entity);
+out_reg:
+	regulator_bulk_free(ARRAY_SIZE(supplies), supplies);
+out_gpio:
+	gpio_free(pdata->gpio_reset);
+out_free:
+	kfree(info);
+	return ret;
+}
+
+static int __devexit m5mols_remove(struct i2c_client *client)
+{
+	struct v4l2_subdev *sd = i2c_get_clientdata(client);
+	struct m5mols_info *info = to_m5mols(sd);
+
+	v4l2_device_unregister_subdev(sd);
+	free_irq(info->pdata->irq, sd);
+
+	regulator_bulk_free(ARRAY_SIZE(supplies), supplies);
+	gpio_free(info->pdata->gpio_reset);
+	media_entity_cleanup(&sd->entity);
+	kfree(info);
+	return 0;
+}
+
+static const struct i2c_device_id m5mols_id[] = {
+	{ MODULE_NAME, 0 },
+	{ },
+};
+MODULE_DEVICE_TABLE(i2c, m5mols_id);
+
+static struct i2c_driver m5mols_i2c_driver = {
+	.driver = {
+		.name	= MODULE_NAME,
+	},
+	.probe		= m5mols_probe,
+	.remove		= __devexit_p(m5mols_remove),
+	.id_table	= m5mols_id,
+};
+
+static int __init m5mols_mod_init(void)
+{
+	return i2c_add_driver(&m5mols_i2c_driver);
+}
+
+static void __exit m5mols_mod_exit(void)
+{
+	i2c_del_driver(&m5mols_i2c_driver);
+}
+
+module_init(m5mols_mod_init);
+module_exit(m5mols_mod_exit);
+
+MODULE_AUTHOR("HeungJun Kim <riverful.kim@samsung.com>");
+MODULE_AUTHOR("Dongsoo Kim <dongsoo45.kim@samsung.com>");
+MODULE_DESCRIPTION("Fujitsu M-5MOLS 8M Pixel camera driver");
+MODULE_LICENSE("GPL");
diff -druN linux-2.6.39-libre/drivers/media/video/m5mols/m5mols.h linux-3.0-rc7-libre/drivers/media/video/m5mols/m5mols.h
--- linux-2.6.39-libre/drivers/media/video/m5mols/m5mols.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/media/video/m5mols/m5mols.h	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,297 @@
+/*
+ * Header for M-5MOLS 8M Pixel camera sensor with ISP
+ *
+ * Copyright (C) 2011 Samsung Electronics Co., Ltd.
+ * Author: HeungJun Kim <riverful.kim@samsung.com>
+ *
+ * Copyright (C) 2009 Samsung Electronics Co., Ltd.
+ * Author: Dongsoo Nathaniel Kim <dongsoo45.kim@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#ifndef M5MOLS_H
+#define M5MOLS_H
+
+#include <media/v4l2-subdev.h>
+#include "m5mols_reg.h"
+
+extern int m5mols_debug;
+
+#define to_m5mols(__sd)	container_of(__sd, struct m5mols_info, sd)
+
+#define to_sd(__ctrl) \
+	(&container_of(__ctrl->handler, struct m5mols_info, handle)->sd)
+
+enum m5mols_restype {
+	M5MOLS_RESTYPE_MONITOR,
+	M5MOLS_RESTYPE_CAPTURE,
+	M5MOLS_RESTYPE_MAX,
+};
+
+/**
+ * struct m5mols_resolution - structure for the resolution
+ * @type: resolution type according to the pixel code
+ * @width: width of the resolution
+ * @height: height of the resolution
+ * @reg: resolution preset register value
+ */
+struct m5mols_resolution {
+	u8 reg;
+	enum m5mols_restype type;
+	u16 width;
+	u16 height;
+};
+
+/**
+ * struct m5mols_exif - structure for the EXIF information of M-5MOLS
+ * @exposure_time: exposure time register value
+ * @shutter_speed: speed of the shutter register value
+ * @aperture: aperture register value
+ * @exposure_bias: it calls also EV bias
+ * @iso_speed: ISO register value
+ * @flash: status register value of the flash
+ * @sdr: status register value of the Subject Distance Range
+ * @qval: not written exact meaning in document
+ */
+struct m5mols_exif {
+	u32 exposure_time;
+	u32 shutter_speed;
+	u32 aperture;
+	u32 brightness;
+	u32 exposure_bias;
+	u16 iso_speed;
+	u16 flash;
+	u16 sdr;
+	u16 qval;
+};
+
+/**
+ * struct m5mols_capture - Structure for the capture capability
+ * @exif: EXIF information
+ * @main: size in bytes of the main image
+ * @thumb: size in bytes of the thumb image, if it was accompanied
+ * @total: total size in bytes of the produced image
+ */
+struct m5mols_capture {
+	struct m5mols_exif exif;
+	u32 main;
+	u32 thumb;
+	u32 total;
+};
+
+/**
+ * struct m5mols_scenemode - structure for the scenemode capability
+ * @metering: metering light register value
+ * @ev_bias: EV bias register value
+ * @wb_mode: mode which means the WhiteBalance is Auto or Manual
+ * @wb_preset: whitebalance preset register value in the Manual mode
+ * @chroma_en: register value whether the Chroma capability is enabled or not
+ * @chroma_lvl: chroma's level register value
+ * @edge_en: register value Whether the Edge capability is enabled or not
+ * @edge_lvl: edge's level register value
+ * @af_range: Auto Focus's range
+ * @fd_mode: Face Detection mode
+ * @mcc: Multi-axis Color Conversion which means emotion color
+ * @light: status of the Light
+ * @flash: status of the Flash
+ * @tone: Tone color which means Contrast
+ * @iso: ISO register value
+ * @capt_mode: Mode of the Image Stabilization while the camera capturing
+ * @wdr: Wide Dynamic Range register value
+ *
+ * The each value according to each scenemode is recommended in the documents.
+ */
+struct m5mols_scenemode {
+	u8 metering;
+	u8 ev_bias;
+	u8 wb_mode;
+	u8 wb_preset;
+	u8 chroma_en;
+	u8 chroma_lvl;
+	u8 edge_en;
+	u8 edge_lvl;
+	u8 af_range;
+	u8 fd_mode;
+	u8 mcc;
+	u8 light;
+	u8 flash;
+	u8 tone;
+	u8 iso;
+	u8 capt_mode;
+	u8 wdr;
+};
+
+/**
+ * struct m5mols_version - firmware version information
+ * @customer:	customer information
+ * @project:	version of project information according to customer
+ * @fw:		firmware revision
+ * @hw:		hardware revision
+ * @param:	version of the parameter
+ * @awb:	Auto WhiteBalance algorithm version
+ * @str:	information about manufacturer and packaging vendor
+ * @af:		Auto Focus version
+ *
+ * The register offset starts the customer version at 0x0, and it ends
+ * the awb version at 0x09. The customer, project information occupies 1 bytes
+ * each. And also the fw, hw, param, awb each requires 2 bytes. The str is
+ * unique string associated with firmware's version. It includes information
+ * about manufacturer and the vendor of the sensor's packaging. The least
+ * significant 2 bytes of the string indicate packaging manufacturer.
+ */
+#define VERSION_STRING_SIZE	22
+struct m5mols_version {
+	u8	customer;
+	u8	project;
+	u16	fw;
+	u16	hw;
+	u16	param;
+	u16	awb;
+	u8	str[VERSION_STRING_SIZE];
+	u8	af;
+};
+
+/**
+ * struct m5mols_info - M-5MOLS driver data structure
+ * @pdata: platform data
+ * @sd: v4l-subdev instance
+ * @pad: media pad
+ * @ffmt: current fmt according to resolution type
+ * @res_type: current resolution type
+ * @code: current code
+ * @irq_waitq: waitqueue for the capture
+ * @work_irq: workqueue for the IRQ
+ * @flags: state variable for the interrupt handler
+ * @handle: control handler
+ * @autoexposure: Auto Exposure control
+ * @exposure: Exposure control
+ * @autowb: Auto White Balance control
+ * @colorfx: Color effect control
+ * @saturation:	Saturation control
+ * @zoom: Zoom control
+ * @ver: information of the version
+ * @cap: the capture mode attributes
+ * @power: current sensor's power status
+ * @ctrl_sync: true means all controls of the sensor are initialized
+ * @int_capture: true means the capture interrupt is issued once
+ * @lock_ae: true means the Auto Exposure is locked
+ * @lock_awb: true means the Aut WhiteBalance is locked
+ * @resolution:	register value for current resolution
+ * @interrupt: register value for current interrupt status
+ * @mode: register value for current operation mode
+ * @mode_save: register value for current operation mode for saving
+ * @set_power: optional power callback to the board code
+ */
+struct m5mols_info {
+	const struct m5mols_platform_data *pdata;
+	struct v4l2_subdev sd;
+	struct media_pad pad;
+	struct v4l2_mbus_framefmt ffmt[M5MOLS_RESTYPE_MAX];
+	int res_type;
+	enum v4l2_mbus_pixelcode code;
+	wait_queue_head_t irq_waitq;
+	struct work_struct work_irq;
+	unsigned long flags;
+
+	struct v4l2_ctrl_handler handle;
+	/* Autoexposure/exposure control cluster */
+	struct {
+		struct v4l2_ctrl *autoexposure;
+		struct v4l2_ctrl *exposure;
+	};
+	struct v4l2_ctrl *autowb;
+	struct v4l2_ctrl *colorfx;
+	struct v4l2_ctrl *saturation;
+	struct v4l2_ctrl *zoom;
+
+	struct m5mols_version ver;
+	struct m5mols_capture cap;
+	bool power;
+	bool ctrl_sync;
+	bool lock_ae;
+	bool lock_awb;
+	u8 resolution;
+	u8 interrupt;
+	u8 mode;
+	u8 mode_save;
+	int (*set_power)(struct device *dev, int on);
+};
+
+#define ST_CAPT_IRQ 0
+
+#define is_powered(__info) (__info->power)
+#define is_ctrl_synced(__info) (__info->ctrl_sync)
+#define is_available_af(__info)	(__info->ver.af)
+#define is_code(__code, __type) (__code == m5mols_default_ffmt[__type].code)
+#define is_manufacturer(__info, __manufacturer)	\
+				(__info->ver.str[0] == __manufacturer[0] && \
+				 __info->ver.str[1] == __manufacturer[1])
+/*
+ * I2C operation of the M-5MOLS
+ *
+ * The I2C read operation of the M-5MOLS requires 2 messages. The first
+ * message sends the information about the command, command category, and total
+ * message size. The second message is used to retrieve the data specifed in
+ * the first message
+ *
+ *   1st message                                2nd message
+ *   +-------+---+----------+-----+-------+     +------+------+------+------+
+ *   | size1 | R | category | cmd | size2 |     | d[0] | d[1] | d[2] | d[3] |
+ *   +-------+---+----------+-----+-------+     +------+------+------+------+
+ *   - size1: message data size(5 in this case)
+ *   - size2: desired buffer size of the 2nd message
+ *   - d[0..3]: according to size2
+ *
+ * The I2C write operation needs just one message. The message includes
+ * category, command, total size, and desired data.
+ *
+ *   1st message
+ *   +-------+---+----------+-----+------+------+------+------+
+ *   | size1 | W | category | cmd | d[0] | d[1] | d[2] | d[3] |
+ *   +-------+---+----------+-----+------+------+------+------+
+ *   - d[0..3]: according to size1
+ */
+int m5mols_read_u8(struct v4l2_subdev *sd, u32 reg_comb, u8 *val);
+int m5mols_read_u16(struct v4l2_subdev *sd, u32 reg_comb, u16 *val);
+int m5mols_read_u32(struct v4l2_subdev *sd, u32 reg_comb, u32 *val);
+int m5mols_write(struct v4l2_subdev *sd, u32 reg_comb, u32 val);
+int m5mols_busy(struct v4l2_subdev *sd, u8 category, u8 cmd, u8 value);
+
+/*
+ * Mode operation of the M-5MOLS
+ *
+ * Changing the mode of the M-5MOLS is needed right executing order.
+ * There are three modes(PARAMETER, MONITOR, CAPTURE) which can be changed
+ * by user. There are various categories associated with each mode.
+ *
+ * +============================================================+
+ * | mode	| category					|
+ * +============================================================+
+ * | FLASH	| FLASH(only after Stand-by or Power-on)	|
+ * | SYSTEM	| SYSTEM(only after sensor arm-booting)		|
+ * | PARAMETER	| PARAMETER					|
+ * | MONITOR	| MONITOR(preview), Auto Focus, Face Detection	|
+ * | CAPTURE	| Single CAPTURE, Preview(recording)		|
+ * +============================================================+
+ *
+ * The available executing order between each modes are as follows:
+ *   PARAMETER <---> MONITOR <---> CAPTURE
+ */
+int m5mols_mode(struct m5mols_info *info, u8 mode);
+
+int m5mols_enable_interrupt(struct v4l2_subdev *sd, u8 reg);
+int m5mols_sync_controls(struct m5mols_info *info);
+int m5mols_start_capture(struct m5mols_info *info);
+int m5mols_do_scenemode(struct m5mols_info *info, u8 mode);
+int m5mols_lock_3a(struct m5mols_info *info, bool lock);
+int m5mols_set_ctrl(struct v4l2_ctrl *ctrl);
+
+/* The firmware function */
+int m5mols_update_fw(struct v4l2_subdev *sd,
+		     int (*set_power)(struct m5mols_info *, bool));
+
+#endif	/* M5MOLS_H */
diff -druN linux-2.6.39-libre/drivers/media/video/m5mols/m5mols_reg.h linux-3.0-rc7-libre/drivers/media/video/m5mols/m5mols_reg.h
--- linux-2.6.39-libre/drivers/media/video/m5mols/m5mols_reg.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/media/video/m5mols/m5mols_reg.h	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,410 @@
+/*
+ * Register map for M-5MOLS 8M Pixel camera sensor with ISP
+ *
+ * Copyright (C) 2011 Samsung Electronics Co., Ltd.
+ * Author: HeungJun Kim <riverful.kim@samsung.com>
+ *
+ * Copyright (C) 2009 Samsung Electronics Co., Ltd.
+ * Author: Dongsoo Nathaniel Kim <dongsoo45.kim@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#ifndef M5MOLS_REG_H
+#define M5MOLS_REG_H
+
+#define M5MOLS_I2C_MAX_SIZE	4
+#define M5MOLS_BYTE_READ	0x01
+#define M5MOLS_BYTE_WRITE	0x02
+
+#define I2C_CATEGORY(__cat)		((__cat >> 16) & 0xff)
+#define I2C_COMMAND(__comm)		((__comm >> 8) & 0xff)
+#define I2C_SIZE(__reg_s)		((__reg_s) & 0xff)
+#define I2C_REG(__cat, __cmd, __reg_s)	((__cat << 16) | (__cmd << 8) | __reg_s)
+
+/*
+ * Category section register
+ *
+ * The category means set including relevant command of M-5MOLS.
+ */
+#define CAT_SYSTEM		0x00
+#define CAT_PARAM		0x01
+#define CAT_MONITOR		0x02
+#define CAT_AE			0x03
+#define CAT_WB			0x06
+#define CAT_EXIF		0x07
+#define CAT_FD			0x09
+#define CAT_LENS		0x0a
+#define CAT_CAPT_PARM		0x0b
+#define CAT_CAPT_CTRL		0x0c
+#define CAT_FLASH		0x0f	/* related to FW, revisions, booting */
+
+/*
+ * Category 0 - SYSTEM mode
+ *
+ * The SYSTEM mode in the M-5MOLS means area available to handle with the whole
+ * & all-round system of sensor. It deals with version/interrupt/setting mode &
+ * even sensor's status. Especially, the M-5MOLS sensor with ISP varies by
+ * packaging & manufacturer, even the customer and project code. And the
+ * function details may vary among them. The version information helps to
+ * determine what methods shall be used in the driver.
+ *
+ * There is many registers between customer version address and awb one. For
+ * more specific contents, see definition if file m5mols.h.
+ */
+#define CAT0_VER_CUSTOMER	0x00	/* customer version */
+#define CAT0_VER_PROJECT	0x01	/* project version */
+#define CAT0_VER_FIRMWARE	0x02	/* Firmware version */
+#define CAT0_VER_HARDWARE	0x04	/* Hardware version */
+#define CAT0_VER_PARAMETER	0x06	/* Parameter version */
+#define CAT0_VER_AWB		0x08	/* Auto WB version */
+#define CAT0_VER_STRING		0x0a	/* string including M-5MOLS */
+#define CAT0_SYSMODE		0x0b	/* SYSTEM mode register */
+#define CAT0_STATUS		0x0c	/* SYSTEM mode status register */
+#define CAT0_INT_FACTOR		0x10	/* interrupt pending register */
+#define CAT0_INT_ENABLE		0x11	/* interrupt enable register */
+
+#define SYSTEM_VER_CUSTOMER	I2C_REG(CAT_SYSTEM, CAT0_VER_CUSTOMER, 1)
+#define SYSTEM_VER_PROJECT	I2C_REG(CAT_SYSTEM, CAT0_VER_PROJECT, 1)
+#define SYSTEM_VER_FIRMWARE	I2C_REG(CAT_SYSTEM, CAT0_VER_FIRMWARE, 2)
+#define SYSTEM_VER_HARDWARE	I2C_REG(CAT_SYSTEM, CAT0_VER_HARDWARE, 2)
+#define SYSTEM_VER_PARAMETER	I2C_REG(CAT_SYSTEM, CAT0_VER_PARAMETER, 2)
+#define SYSTEM_VER_AWB		I2C_REG(CAT_SYSTEM, CAT0_VER_AWB, 2)
+
+#define SYSTEM_SYSMODE		I2C_REG(CAT_SYSTEM, CAT0_SYSMODE, 1)
+#define REG_SYSINIT		0x00	/* SYSTEM mode */
+#define REG_PARAMETER		0x01	/* PARAMETER mode */
+#define REG_MONITOR		0x02	/* MONITOR mode */
+#define REG_CAPTURE		0x03	/* CAPTURE mode */
+
+#define SYSTEM_CMD(__cmd)	I2C_REG(CAT_SYSTEM, cmd, 1)
+#define SYSTEM_VER_STRING	I2C_REG(CAT_SYSTEM, CAT0_VER_STRING, 1)
+#define REG_SAMSUNG_ELECTRO	"SE"	/* Samsung Electro-Mechanics */
+#define REG_SAMSUNG_OPTICS	"OP"	/* Samsung Fiber-Optics */
+#define REG_SAMSUNG_TECHWIN	"TB"	/* Samsung Techwin */
+
+#define SYSTEM_INT_FACTOR	I2C_REG(CAT_SYSTEM, CAT0_INT_FACTOR, 1)
+#define SYSTEM_INT_ENABLE	I2C_REG(CAT_SYSTEM, CAT0_INT_ENABLE, 1)
+#define REG_INT_MODE		(1 << 0)
+#define REG_INT_AF		(1 << 1)
+#define REG_INT_ZOOM		(1 << 2)
+#define REG_INT_CAPTURE		(1 << 3)
+#define REG_INT_FRAMESYNC	(1 << 4)
+#define REG_INT_FD		(1 << 5)
+#define REG_INT_LENS_INIT	(1 << 6)
+#define REG_INT_SOUND		(1 << 7)
+#define REG_INT_MASK		0x0f
+
+/*
+ * category 1 - PARAMETER mode
+ *
+ * This category supports function of camera features of M-5MOLS. It means we
+ * can handle with preview(MONITOR) resolution size/frame per second/interface
+ * between the sensor and the Application Processor/even the image effect.
+ */
+#define CAT1_DATA_INTERFACE	0x00	/* interface between sensor and AP */
+#define CAT1_MONITOR_SIZE	0x01	/* resolution at the MONITOR mode */
+#define CAT1_MONITOR_FPS	0x02	/* frame per second at this mode */
+#define CAT1_EFFECT		0x0b	/* image effects */
+
+#define PARM_MON_SIZE		I2C_REG(CAT_PARAM, CAT1_MONITOR_SIZE, 1)
+
+#define PARM_MON_FPS		I2C_REG(CAT_PARAM, CAT1_MONITOR_FPS, 1)
+#define REG_FPS_30		0x02
+
+#define PARM_INTERFACE		I2C_REG(CAT_PARAM, CAT1_DATA_INTERFACE, 1)
+#define REG_INTERFACE_MIPI	0x02
+
+#define PARM_EFFECT		I2C_REG(CAT_PARAM, CAT1_EFFECT, 1)
+#define REG_EFFECT_OFF		0x00
+#define REG_EFFECT_NEGA		0x01
+#define REG_EFFECT_EMBOSS	0x06
+#define REG_EFFECT_OUTLINE	0x07
+#define REG_EFFECT_WATERCOLOR	0x08
+
+/*
+ * Category 2 - MONITOR mode
+ *
+ * The MONITOR mode is same as preview mode as we said. The M-5MOLS has another
+ * mode named "Preview", but this preview mode is used at the case specific
+ * vider-recording mode. This mmode supports only YUYV format. On the other
+ * hand, the JPEG & RAW formats is supports by CAPTURE mode. And, there are
+ * another options like zoom/color effect(different with effect in PARAMETER
+ * mode)/anti hand shaking algorithm.
+ */
+#define CAT2_ZOOM		0x01	/* set the zoom position & execute */
+#define CAT2_ZOOM_STEP		0x03	/* set the zoom step */
+#define CAT2_CFIXB		0x09	/* CB value for color effect */
+#define CAT2_CFIXR		0x0a	/* CR value for color effect */
+#define CAT2_COLOR_EFFECT	0x0b	/* set on/off of color effect */
+#define CAT2_CHROMA_LVL		0x0f	/* set chroma level */
+#define CAT2_CHROMA_EN		0x10	/* set on/off of choroma */
+#define CAT2_EDGE_LVL		0x11	/* set sharpness level */
+#define CAT2_EDGE_EN		0x12	/* set on/off sharpness */
+#define CAT2_TONE_CTL		0x25	/* set tone color(contrast) */
+
+#define MON_ZOOM		I2C_REG(CAT_MONITOR, CAT2_ZOOM, 1)
+
+#define MON_CFIXR		I2C_REG(CAT_MONITOR, CAT2_CFIXR, 1)
+#define MON_CFIXB		I2C_REG(CAT_MONITOR, CAT2_CFIXB, 1)
+#define REG_CFIXB_SEPIA		0xd8
+#define REG_CFIXR_SEPIA		0x18
+
+#define MON_EFFECT		I2C_REG(CAT_MONITOR, CAT2_COLOR_EFFECT, 1)
+#define REG_COLOR_EFFECT_OFF	0x00
+#define REG_COLOR_EFFECT_ON	0x01
+
+#define MON_CHROMA_EN		I2C_REG(CAT_MONITOR, CAT2_CHROMA_EN, 1)
+#define MON_CHROMA_LVL		I2C_REG(CAT_MONITOR, CAT2_CHROMA_LVL, 1)
+#define REG_CHROMA_OFF		0x00
+#define REG_CHROMA_ON		0x01
+
+#define MON_EDGE_EN		I2C_REG(CAT_MONITOR, CAT2_EDGE_EN, 1)
+#define MON_EDGE_LVL		I2C_REG(CAT_MONITOR, CAT2_EDGE_LVL, 1)
+#define REG_EDGE_OFF		0x00
+#define REG_EDGE_ON		0x01
+
+#define MON_TONE_CTL		I2C_REG(CAT_MONITOR, CAT2_TONE_CTL, 1)
+
+/*
+ * Category 3 - Auto Exposure
+ *
+ * The M-5MOLS exposure capbility is detailed as which is similar to digital
+ * camera. This category supports AE locking/various AE mode(range of exposure)
+ * /ISO/flickering/EV bias/shutter/meteoring, and anything else. And the
+ * maximum/minimum exposure gain value depending on M-5MOLS firmware, may be
+ * different. So, this category also provide getting the max/min values. And,
+ * each MONITOR and CAPTURE mode has each gain/shutter/max exposure values.
+ */
+#define CAT3_AE_LOCK		0x00	/* locking Auto exposure */
+#define CAT3_AE_MODE		0x01	/* set AE mode, mode means range */
+#define CAT3_ISO		0x05	/* set ISO */
+#define CAT3_EV_PRESET_MONITOR	0x0a	/* EV(scenemode) preset for MONITOR */
+#define CAT3_EV_PRESET_CAPTURE	0x0b	/* EV(scenemode) preset for CAPTURE */
+#define CAT3_MANUAL_GAIN_MON	0x12	/* meteoring value for the MONITOR */
+#define CAT3_MAX_GAIN_MON	0x1a	/* max gain value for the MONITOR */
+#define CAT3_MANUAL_GAIN_CAP	0x26	/* meteoring value for the CAPTURE */
+#define CAT3_AE_INDEX		0x38	/* AE index */
+
+#define AE_LOCK			I2C_REG(CAT_AE, CAT3_AE_LOCK, 1)
+#define REG_AE_UNLOCK		0x00
+#define REG_AE_LOCK		0x01
+
+#define AE_MODE			I2C_REG(CAT_AE, CAT3_AE_MODE, 1)
+#define REG_AE_OFF		0x00	/* AE off */
+#define REG_AE_ALL		0x01	/* calc AE in all block integral */
+#define REG_AE_CENTER		0x03	/* calc AE in center weighted */
+#define REG_AE_SPOT		0x06	/* calc AE in specific spot */
+
+#define AE_ISO			I2C_REG(CAT_AE, CAT3_ISO, 1)
+#define REG_ISO_AUTO		0x00
+#define REG_ISO_50		0x01
+#define REG_ISO_100		0x02
+#define REG_ISO_200		0x03
+#define REG_ISO_400		0x04
+#define REG_ISO_800		0x05
+
+#define AE_EV_PRESET_MONITOR	I2C_REG(CAT_AE, CAT3_EV_PRESET_MONITOR, 1)
+#define AE_EV_PRESET_CAPTURE	I2C_REG(CAT_AE, CAT3_EV_PRESET_CAPTURE, 1)
+#define REG_SCENE_NORMAL	0x00
+#define REG_SCENE_PORTRAIT	0x01
+#define REG_SCENE_LANDSCAPE	0x02
+#define REG_SCENE_SPORTS	0x03
+#define REG_SCENE_PARTY_INDOOR	0x04
+#define REG_SCENE_BEACH_SNOW	0x05
+#define REG_SCENE_SUNSET	0x06
+#define REG_SCENE_DAWN_DUSK	0x07
+#define REG_SCENE_FALL		0x08
+#define REG_SCENE_NIGHT		0x09
+#define REG_SCENE_AGAINST_LIGHT	0x0a
+#define REG_SCENE_FIRE		0x0b
+#define REG_SCENE_TEXT		0x0c
+#define REG_SCENE_CANDLE	0x0d
+
+#define AE_MAN_GAIN_MON		I2C_REG(CAT_AE, CAT3_MANUAL_GAIN_MON, 2)
+#define AE_MAX_GAIN_MON		I2C_REG(CAT_AE, CAT3_MAX_GAIN_MON, 2)
+#define AE_MAN_GAIN_CAP		I2C_REG(CAT_AE, CAT3_MANUAL_GAIN_CAP, 2)
+
+#define AE_INDEX		I2C_REG(CAT_AE, CAT3_AE_INDEX, 1)
+#define REG_AE_INDEX_20_NEG	0x00
+#define REG_AE_INDEX_15_NEG	0x01
+#define REG_AE_INDEX_10_NEG	0x02
+#define REG_AE_INDEX_05_NEG	0x03
+#define REG_AE_INDEX_00		0x04
+#define REG_AE_INDEX_05_POS	0x05
+#define REG_AE_INDEX_10_POS	0x06
+#define REG_AE_INDEX_15_POS	0x07
+#define REG_AE_INDEX_20_POS	0x08
+
+/*
+ * Category 6 - White Balance
+ *
+ * This category provide AWB locking/mode/preset/speed/gain bias, etc.
+ */
+#define CAT6_AWB_LOCK		0x00	/* locking Auto Whitebalance */
+#define CAT6_AWB_MODE		0x02	/* set Auto or Manual */
+#define CAT6_AWB_MANUAL		0x03	/* set Manual(preset) value */
+
+#define AWB_LOCK		I2C_REG(CAT_WB, CAT6_AWB_LOCK, 1)
+#define REG_AWB_UNLOCK		0x00
+#define REG_AWB_LOCK		0x01
+
+#define AWB_MODE		I2C_REG(CAT_WB, CAT6_AWB_MODE, 1)
+#define REG_AWB_AUTO		0x01	/* AWB off */
+#define REG_AWB_PRESET		0x02	/* AWB preset */
+
+#define AWB_MANUAL		I2C_REG(CAT_WB, CAT6_AWB_MANUAL, 1)
+#define REG_AWB_INCANDESCENT	0x01
+#define REG_AWB_FLUORESCENT_1	0x02
+#define REG_AWB_FLUORESCENT_2	0x03
+#define REG_AWB_DAYLIGHT	0x04
+#define REG_AWB_CLOUDY		0x05
+#define REG_AWB_SHADE		0x06
+#define REG_AWB_HORIZON		0x07
+#define REG_AWB_LEDLIGHT	0x09
+
+/*
+ * Category 7 - EXIF information
+ */
+#define CAT7_INFO_EXPTIME_NU	0x00
+#define CAT7_INFO_EXPTIME_DE	0x04
+#define CAT7_INFO_TV_NU		0x08
+#define CAT7_INFO_TV_DE		0x0c
+#define CAT7_INFO_AV_NU		0x10
+#define CAT7_INFO_AV_DE		0x14
+#define CAT7_INFO_BV_NU		0x18
+#define CAT7_INFO_BV_DE		0x1c
+#define CAT7_INFO_EBV_NU	0x20
+#define CAT7_INFO_EBV_DE	0x24
+#define CAT7_INFO_ISO		0x28
+#define CAT7_INFO_FLASH		0x2a
+#define CAT7_INFO_SDR		0x2c
+#define CAT7_INFO_QVAL		0x2e
+
+#define EXIF_INFO_EXPTIME_NU	I2C_REG(CAT_EXIF, CAT7_INFO_EXPTIME_NU, 4)
+#define EXIF_INFO_EXPTIME_DE	I2C_REG(CAT_EXIF, CAT7_INFO_EXPTIME_DE, 4)
+#define EXIF_INFO_TV_NU		I2C_REG(CAT_EXIF, CAT7_INFO_TV_NU, 4)
+#define EXIF_INFO_TV_DE		I2C_REG(CAT_EXIF, CAT7_INFO_TV_DE, 4)
+#define EXIF_INFO_AV_NU		I2C_REG(CAT_EXIF, CAT7_INFO_AV_NU, 4)
+#define EXIF_INFO_AV_DE		I2C_REG(CAT_EXIF, CAT7_INFO_AV_DE, 4)
+#define EXIF_INFO_BV_NU		I2C_REG(CAT_EXIF, CAT7_INFO_BV_NU, 4)
+#define EXIF_INFO_BV_DE		I2C_REG(CAT_EXIF, CAT7_INFO_BV_DE, 4)
+#define EXIF_INFO_EBV_NU	I2C_REG(CAT_EXIF, CAT7_INFO_EBV_NU, 4)
+#define EXIF_INFO_EBV_DE	I2C_REG(CAT_EXIF, CAT7_INFO_EBV_DE, 4)
+#define EXIF_INFO_ISO		I2C_REG(CAT_EXIF, CAT7_INFO_ISO, 2)
+#define EXIF_INFO_FLASH		I2C_REG(CAT_EXIF, CAT7_INFO_FLASH, 2)
+#define EXIF_INFO_SDR		I2C_REG(CAT_EXIF, CAT7_INFO_SDR, 2)
+#define EXIF_INFO_QVAL		I2C_REG(CAT_EXIF, CAT7_INFO_QVAL, 2)
+
+/*
+ * Category 9 - Face Detection
+ */
+#define CAT9_FD_CTL		0x00
+
+#define FD_CTL			I2C_REG(CAT_FD, CAT9_FD_CTL, 1)
+#define BIT_FD_EN		0
+#define BIT_FD_DRAW_FACE_FRAME	4
+#define BIT_FD_DRAW_SMILE_LVL	6
+#define REG_FD(shift)		(1 << shift)
+#define REG_FD_OFF		0x0
+
+/*
+ * Category A - Lens Parameter
+ */
+#define CATA_AF_MODE		0x01
+#define CATA_AF_EXECUTE		0x02
+#define CATA_AF_STATUS		0x03
+#define CATA_AF_VERSION		0x0a
+
+#define AF_MODE			I2C_REG(CAT_LENS, CATA_AF_MODE, 1)
+#define REG_AF_NORMAL		0x00	/* Normal AF, one time */
+#define REG_AF_MACRO		0x01	/* Macro AF, one time */
+#define REG_AF_POWEROFF		0x07
+
+#define AF_EXECUTE		I2C_REG(CAT_LENS, CATA_AF_EXECUTE, 1)
+#define REG_AF_STOP		0x00
+#define REG_AF_EXE_AUTO		0x01
+#define REG_AF_EXE_CAF		0x02
+
+#define AF_STATUS		I2C_REG(CAT_LENS, CATA_AF_STATUS, 1)
+#define REG_AF_FAIL		0x00
+#define REG_AF_SUCCESS		0x02
+#define REG_AF_IDLE		0x04
+#define REG_AF_BUSY		0x05
+
+#define AF_VERSION		I2C_REG(CAT_LENS, CATA_AF_VERSION, 1)
+
+/*
+ * Category B - CAPTURE Parameter
+ */
+#define CATB_YUVOUT_MAIN	0x00
+#define CATB_MAIN_IMAGE_SIZE	0x01
+#define CATB_MCC_MODE		0x1d
+#define CATB_WDR_EN		0x2c
+#define CATB_LIGHT_CTRL		0x40
+#define CATB_FLASH_CTRL		0x41
+
+#define CAPP_YUVOUT_MAIN	I2C_REG(CAT_CAPT_PARM, CATB_YUVOUT_MAIN, 1)
+#define REG_YUV422		0x00
+#define REG_BAYER10		0x05
+#define REG_BAYER8		0x06
+#define REG_JPEG		0x10
+
+#define CAPP_MAIN_IMAGE_SIZE	I2C_REG(CAT_CAPT_PARM, CATB_MAIN_IMAGE_SIZE, 1)
+
+#define CAPP_MCC_MODE		I2C_REG(CAT_CAPT_PARM, CATB_MCC_MODE, 1)
+#define REG_MCC_OFF		0x00
+#define REG_MCC_NORMAL		0x01
+
+#define CAPP_WDR_EN		I2C_REG(CAT_CAPT_PARM, CATB_WDR_EN, 1)
+#define REG_WDR_OFF		0x00
+#define REG_WDR_ON		0x01
+#define REG_WDR_AUTO		0x02
+
+#define CAPP_LIGHT_CTRL		I2C_REG(CAT_CAPT_PARM, CATB_LIGHT_CTRL, 1)
+#define REG_LIGHT_OFF		0x00
+#define REG_LIGHT_ON		0x01
+#define REG_LIGHT_AUTO		0x02
+
+#define CAPP_FLASH_CTRL		I2C_REG(CAT_CAPT_PARM, CATB_FLASH_CTRL, 1)
+#define REG_FLASH_OFF		0x00
+#define REG_FLASH_ON		0x01
+#define REG_FLASH_AUTO		0x02
+
+/*
+ * Category C - CAPTURE Control
+ */
+#define CATC_CAP_MODE		0x00
+#define CATC_CAP_SEL_FRAME	0x06	/* It determines Single or Multi */
+#define CATC_CAP_START		0x09
+#define CATC_CAP_IMAGE_SIZE	0x0d
+#define CATC_CAP_THUMB_SIZE	0x11
+
+#define CAPC_MODE		I2C_REG(CAT_CAPT_CTRL, CATC_CAP_MODE, 1)
+#define REG_CAP_NONE		0x00
+#define REG_CAP_ANTI_SHAKE	0x02
+
+#define CAPC_SEL_FRAME		I2C_REG(CAT_CAPT_CTRL, CATC_CAP_SEL_FRAME, 1)
+
+#define CAPC_START		I2C_REG(CAT_CAPT_CTRL, CATC_CAP_START, 1)
+#define REG_CAP_START_MAIN	0x01
+#define REG_CAP_START_THUMB	0x03
+
+#define CAPC_IMAGE_SIZE		I2C_REG(CAT_CAPT_CTRL, CATC_CAP_IMAGE_SIZE, 4)
+#define CAPC_THUMB_SIZE		I2C_REG(CAT_CAPT_CTRL, CATC_CAP_THUMB_SIZE, 4)
+
+/*
+ * Category F - Flash
+ *
+ * This mode provides functions about internal flash stuff and system startup.
+ */
+#define CATF_CAM_START		0x12	/* It starts internal ARM core booting
+					 * after power-up */
+
+#define FLASH_CAM_START		I2C_REG(CAT_FLASH, CATF_CAM_START, 1)
+#define REG_START_ARM_BOOT	0x01
+
+#endif	/* M5MOLS_REG_H */
diff -druN linux-2.6.39-libre/drivers/media/video/m5mols/Makefile linux-3.0-rc7-libre/drivers/media/video/m5mols/Makefile
--- linux-2.6.39-libre/drivers/media/video/m5mols/Makefile	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/media/video/m5mols/Makefile	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,3 @@
+m5mols-objs	:= m5mols_core.o m5mols_controls.o m5mols_capture.o
+
+obj-$(CONFIG_VIDEO_M5MOLS)		+= m5mols.o
diff -druN linux-2.6.39-libre/drivers/media/video/Makefile linux-3.0-rc7-libre/drivers/media/video/Makefile
--- linux-2.6.39-libre/drivers/media/video/Makefile	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/video/Makefile	2011-07-11 19:51:52.000000000 -0400
@@ -66,8 +66,10 @@
 obj-$(CONFIG_VIDEO_TCM825X) += tcm825x.o
 obj-$(CONFIG_VIDEO_TVEEPROM) += tveeprom.o
 obj-$(CONFIG_VIDEO_MT9V011) += mt9v011.o
+obj-$(CONFIG_VIDEO_MT9V032) += mt9v032.o
 obj-$(CONFIG_VIDEO_SR030PC30)	+= sr030pc30.o
 obj-$(CONFIG_VIDEO_NOON010PC30)	+= noon010pc30.o
+obj-$(CONFIG_VIDEO_M5MOLS)	+= m5mols/
 
 obj-$(CONFIG_SOC_CAMERA_IMX074)		+= imx074.o
 obj-$(CONFIG_SOC_CAMERA_MT9M001)	+= mt9m001.o
@@ -164,6 +166,7 @@
 obj-$(CONFIG_VIDEO_SH_MOBILE_CSI2)	+= sh_mobile_csi2.o
 obj-$(CONFIG_VIDEO_SH_MOBILE_CEU)	+= sh_mobile_ceu_camera.o
 obj-$(CONFIG_VIDEO_OMAP1)		+= omap1_camera.o
+
 obj-$(CONFIG_VIDEO_SAMSUNG_S5P_FIMC) 	+= s5p-fimc/
 
 obj-$(CONFIG_ARCH_DAVINCI)		+= davinci/
diff -druN linux-2.6.39-libre/drivers/media/video/msp3400-driver.c linux-3.0-rc7-libre/drivers/media/video/msp3400-driver.c
--- linux-2.6.39-libre/drivers/media/video/msp3400-driver.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/video/msp3400-driver.c	2011-07-11 19:51:52.000000000 -0400
@@ -96,7 +96,7 @@
 MODULE_PARM_DESC(stereo_threshold, "Sets signal threshold to activate stereo");
 MODULE_PARM_DESC(standard, "Specify audio standard: 32 = NTSC, 64 = radio, Default: Autodetect");
 MODULE_PARM_DESC(amsound, "Hardwire AM sound at 6.5Hz (France), FM can autoscan");
-MODULE_PARM_DESC(dolby, "Activates Dolby processsing");
+MODULE_PARM_DESC(dolby, "Activates Dolby processing");
 
 /* ---------------------------------------------------------------------- */
 
@@ -480,12 +480,14 @@
 	struct msp_state *state = to_state(sd);
 	struct i2c_client *client = v4l2_get_subdevdata(sd);
 
-	if (state->radio)
+	if (vt->type != V4L2_TUNER_ANALOG_TV)
 		return 0;
-	if (state->opmode == OPMODE_AUTOSELECT)
-		msp_detect_stereo(client);
-	vt->audmode    = state->audmode;
-	vt->rxsubchans = state->rxsubchans;
+	if (!state->radio) {
+		if (state->opmode == OPMODE_AUTOSELECT)
+			msp_detect_stereo(client);
+		vt->rxsubchans = state->rxsubchans;
+	}
+	vt->audmode = state->audmode;
 	vt->capability |= V4L2_TUNER_CAP_STEREO |
 		V4L2_TUNER_CAP_LANG1 | V4L2_TUNER_CAP_LANG2;
 	return 0;
diff -druN linux-2.6.39-libre/drivers/media/video/mt9m111.c linux-3.0-rc7-libre/drivers/media/video/mt9m111.c
--- linux-2.6.39-libre/drivers/media/video/mt9m111.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/video/mt9m111.c	2011-07-11 19:51:52.000000000 -0400
@@ -315,10 +315,20 @@
 static int mt9m111_setup_pixfmt(struct i2c_client *client, u16 outfmt)
 {
 	int ret;
+	u16 mask = MT9M111_OUTFMT_PROCESSED_BAYER | MT9M111_OUTFMT_RGB |
+		MT9M111_OUTFMT_BYPASS_IFP | MT9M111_OUTFMT_SWAP_RGB_EVEN |
+		MT9M111_OUTFMT_RGB565 | MT9M111_OUTFMT_RGB555 |
+		MT9M111_OUTFMT_SWAP_YCbCr_Cb_Cr |
+		MT9M111_OUTFMT_SWAP_YCbCr_C_Y;
 
-	ret = reg_write(OUTPUT_FORMAT_CTRL2_A, outfmt);
+	ret = reg_read(OUTPUT_FORMAT_CTRL2_A);
+	if (ret >= 0)
+		ret = reg_write(OUTPUT_FORMAT_CTRL2_A, (ret & ~mask) | outfmt);
 	if (!ret)
-		ret = reg_write(OUTPUT_FORMAT_CTRL2_B, outfmt);
+		ret = reg_read(OUTPUT_FORMAT_CTRL2_B);
+	if (ret >= 0)
+		ret = reg_write(OUTPUT_FORMAT_CTRL2_B, (ret & ~mask) | outfmt);
+
 	return ret;
 }
 
diff -druN linux-2.6.39-libre/drivers/media/video/mt9v022.c linux-3.0-rc7-libre/drivers/media/video/mt9v022.c
--- linux-2.6.39-libre/drivers/media/video/mt9v022.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/video/mt9v022.c	2011-07-11 19:51:52.000000000 -0400
@@ -228,7 +228,7 @@
 
 	flags = soc_camera_apply_sensor_flags(icl, flags);
 
-	if (flags & SOCAM_PCLK_SAMPLE_RISING)
+	if (flags & SOCAM_PCLK_SAMPLE_FALLING)
 		pixclk |= 0x10;
 
 	if (!(flags & SOCAM_HSYNC_ACTIVE_HIGH))
diff -druN linux-2.6.39-libre/drivers/media/video/mt9v032.c linux-3.0-rc7-libre/drivers/media/video/mt9v032.c
--- linux-2.6.39-libre/drivers/media/video/mt9v032.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/media/video/mt9v032.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,773 @@
+/*
+ * Driver for MT9V032 CMOS Image Sensor from Micron
+ *
+ * Copyright (C) 2010, Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+ *
+ * Based on the MT9M001 driver,
+ *
+ * Copyright (C) 2008, Guennadi Liakhovetski <kernel@pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/delay.h>
+#include <linux/i2c.h>
+#include <linux/log2.h>
+#include <linux/mutex.h>
+#include <linux/slab.h>
+#include <linux/videodev2.h>
+#include <linux/v4l2-mediabus.h>
+
+#include <media/mt9v032.h>
+#include <media/v4l2-ctrls.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-subdev.h>
+
+#define MT9V032_PIXEL_ARRAY_HEIGHT			492
+#define MT9V032_PIXEL_ARRAY_WIDTH			782
+
+#define MT9V032_CHIP_VERSION				0x00
+#define		MT9V032_CHIP_ID_REV1			0x1311
+#define		MT9V032_CHIP_ID_REV3			0x1313
+#define MT9V032_ROW_START				0x01
+#define		MT9V032_ROW_START_MIN			4
+#define		MT9V032_ROW_START_DEF			10
+#define		MT9V032_ROW_START_MAX			482
+#define MT9V032_COLUMN_START				0x02
+#define		MT9V032_COLUMN_START_MIN		1
+#define		MT9V032_COLUMN_START_DEF		2
+#define		MT9V032_COLUMN_START_MAX		752
+#define MT9V032_WINDOW_HEIGHT				0x03
+#define		MT9V032_WINDOW_HEIGHT_MIN		1
+#define		MT9V032_WINDOW_HEIGHT_DEF		480
+#define		MT9V032_WINDOW_HEIGHT_MAX		480
+#define MT9V032_WINDOW_WIDTH				0x04
+#define		MT9V032_WINDOW_WIDTH_MIN		1
+#define		MT9V032_WINDOW_WIDTH_DEF		752
+#define		MT9V032_WINDOW_WIDTH_MAX		752
+#define MT9V032_HORIZONTAL_BLANKING			0x05
+#define		MT9V032_HORIZONTAL_BLANKING_MIN		43
+#define		MT9V032_HORIZONTAL_BLANKING_MAX		1023
+#define MT9V032_VERTICAL_BLANKING			0x06
+#define		MT9V032_VERTICAL_BLANKING_MIN		4
+#define		MT9V032_VERTICAL_BLANKING_MAX		3000
+#define MT9V032_CHIP_CONTROL				0x07
+#define		MT9V032_CHIP_CONTROL_MASTER_MODE	(1 << 3)
+#define		MT9V032_CHIP_CONTROL_DOUT_ENABLE	(1 << 7)
+#define		MT9V032_CHIP_CONTROL_SEQUENTIAL		(1 << 8)
+#define MT9V032_SHUTTER_WIDTH1				0x08
+#define MT9V032_SHUTTER_WIDTH2				0x09
+#define MT9V032_SHUTTER_WIDTH_CONTROL			0x0a
+#define MT9V032_TOTAL_SHUTTER_WIDTH			0x0b
+#define		MT9V032_TOTAL_SHUTTER_WIDTH_MIN		1
+#define		MT9V032_TOTAL_SHUTTER_WIDTH_DEF		480
+#define		MT9V032_TOTAL_SHUTTER_WIDTH_MAX		32767
+#define MT9V032_RESET					0x0c
+#define MT9V032_READ_MODE				0x0d
+#define		MT9V032_READ_MODE_ROW_BIN_MASK		(3 << 0)
+#define		MT9V032_READ_MODE_ROW_BIN_SHIFT		0
+#define		MT9V032_READ_MODE_COLUMN_BIN_MASK	(3 << 2)
+#define		MT9V032_READ_MODE_COLUMN_BIN_SHIFT	2
+#define		MT9V032_READ_MODE_ROW_FLIP		(1 << 4)
+#define		MT9V032_READ_MODE_COLUMN_FLIP		(1 << 5)
+#define		MT9V032_READ_MODE_DARK_COLUMNS		(1 << 6)
+#define		MT9V032_READ_MODE_DARK_ROWS		(1 << 7)
+#define MT9V032_PIXEL_OPERATION_MODE			0x0f
+#define		MT9V032_PIXEL_OPERATION_MODE_COLOR	(1 << 2)
+#define		MT9V032_PIXEL_OPERATION_MODE_HDR	(1 << 6)
+#define MT9V032_ANALOG_GAIN				0x35
+#define		MT9V032_ANALOG_GAIN_MIN			16
+#define		MT9V032_ANALOG_GAIN_DEF			16
+#define		MT9V032_ANALOG_GAIN_MAX			64
+#define MT9V032_MAX_ANALOG_GAIN				0x36
+#define		MT9V032_MAX_ANALOG_GAIN_MAX		127
+#define MT9V032_FRAME_DARK_AVERAGE			0x42
+#define MT9V032_DARK_AVG_THRESH				0x46
+#define		MT9V032_DARK_AVG_LOW_THRESH_MASK	(255 << 0)
+#define		MT9V032_DARK_AVG_LOW_THRESH_SHIFT	0
+#define		MT9V032_DARK_AVG_HIGH_THRESH_MASK	(255 << 8)
+#define		MT9V032_DARK_AVG_HIGH_THRESH_SHIFT	8
+#define MT9V032_ROW_NOISE_CORR_CONTROL			0x70
+#define		MT9V032_ROW_NOISE_CORR_ENABLE		(1 << 5)
+#define		MT9V032_ROW_NOISE_CORR_USE_BLK_AVG	(1 << 7)
+#define MT9V032_PIXEL_CLOCK				0x74
+#define		MT9V032_PIXEL_CLOCK_INV_LINE		(1 << 0)
+#define		MT9V032_PIXEL_CLOCK_INV_FRAME		(1 << 1)
+#define		MT9V032_PIXEL_CLOCK_XOR_LINE		(1 << 2)
+#define		MT9V032_PIXEL_CLOCK_CONT_LINE		(1 << 3)
+#define		MT9V032_PIXEL_CLOCK_INV_PXL_CLK		(1 << 4)
+#define MT9V032_TEST_PATTERN				0x7f
+#define		MT9V032_TEST_PATTERN_DATA_MASK		(1023 << 0)
+#define		MT9V032_TEST_PATTERN_DATA_SHIFT		0
+#define		MT9V032_TEST_PATTERN_USE_DATA		(1 << 10)
+#define		MT9V032_TEST_PATTERN_GRAY_MASK		(3 << 11)
+#define		MT9V032_TEST_PATTERN_GRAY_NONE		(0 << 11)
+#define		MT9V032_TEST_PATTERN_GRAY_VERTICAL	(1 << 11)
+#define		MT9V032_TEST_PATTERN_GRAY_HORIZONTAL	(2 << 11)
+#define		MT9V032_TEST_PATTERN_GRAY_DIAGONAL	(3 << 11)
+#define		MT9V032_TEST_PATTERN_ENABLE		(1 << 13)
+#define		MT9V032_TEST_PATTERN_FLIP		(1 << 14)
+#define MT9V032_AEC_AGC_ENABLE				0xaf
+#define		MT9V032_AEC_ENABLE			(1 << 0)
+#define		MT9V032_AGC_ENABLE			(1 << 1)
+#define MT9V032_THERMAL_INFO				0xc1
+
+struct mt9v032 {
+	struct v4l2_subdev subdev;
+	struct media_pad pad;
+
+	struct v4l2_mbus_framefmt format;
+	struct v4l2_rect crop;
+
+	struct v4l2_ctrl_handler ctrls;
+
+	struct mutex power_lock;
+	int power_count;
+
+	struct mt9v032_platform_data *pdata;
+	u16 chip_control;
+	u16 aec_agc;
+};
+
+static struct mt9v032 *to_mt9v032(struct v4l2_subdev *sd)
+{
+	return container_of(sd, struct mt9v032, subdev);
+}
+
+static int mt9v032_read(struct i2c_client *client, const u8 reg)
+{
+	s32 data = i2c_smbus_read_word_data(client, reg);
+	dev_dbg(&client->dev, "%s: read 0x%04x from 0x%02x\n", __func__,
+		swab16(data), reg);
+	return data < 0 ? data : swab16(data);
+}
+
+static int mt9v032_write(struct i2c_client *client, const u8 reg,
+			 const u16 data)
+{
+	dev_dbg(&client->dev, "%s: writing 0x%04x to 0x%02x\n", __func__,
+		data, reg);
+	return i2c_smbus_write_word_data(client, reg, swab16(data));
+}
+
+static int mt9v032_set_chip_control(struct mt9v032 *mt9v032, u16 clear, u16 set)
+{
+	struct i2c_client *client = v4l2_get_subdevdata(&mt9v032->subdev);
+	u16 value = (mt9v032->chip_control & ~clear) | set;
+	int ret;
+
+	ret = mt9v032_write(client, MT9V032_CHIP_CONTROL, value);
+	if (ret < 0)
+		return ret;
+
+	mt9v032->chip_control = value;
+	return 0;
+}
+
+static int
+mt9v032_update_aec_agc(struct mt9v032 *mt9v032, u16 which, int enable)
+{
+	struct i2c_client *client = v4l2_get_subdevdata(&mt9v032->subdev);
+	u16 value = mt9v032->aec_agc;
+	int ret;
+
+	if (enable)
+		value |= which;
+	else
+		value &= ~which;
+
+	ret = mt9v032_write(client, MT9V032_AEC_AGC_ENABLE, value);
+	if (ret < 0)
+		return ret;
+
+	mt9v032->aec_agc = value;
+	return 0;
+}
+
+static int mt9v032_power_on(struct mt9v032 *mt9v032)
+{
+	struct i2c_client *client = v4l2_get_subdevdata(&mt9v032->subdev);
+	int ret;
+
+	if (mt9v032->pdata->set_clock) {
+		mt9v032->pdata->set_clock(&mt9v032->subdev, 25000000);
+		udelay(1);
+	}
+
+	/* Reset the chip and stop data read out */
+	ret = mt9v032_write(client, MT9V032_RESET, 1);
+	if (ret < 0)
+		return ret;
+
+	ret = mt9v032_write(client, MT9V032_RESET, 0);
+	if (ret < 0)
+		return ret;
+
+	return mt9v032_write(client, MT9V032_CHIP_CONTROL, 0);
+}
+
+static void mt9v032_power_off(struct mt9v032 *mt9v032)
+{
+	if (mt9v032->pdata->set_clock)
+		mt9v032->pdata->set_clock(&mt9v032->subdev, 0);
+}
+
+static int __mt9v032_set_power(struct mt9v032 *mt9v032, bool on)
+{
+	struct i2c_client *client = v4l2_get_subdevdata(&mt9v032->subdev);
+	int ret;
+
+	if (!on) {
+		mt9v032_power_off(mt9v032);
+		return 0;
+	}
+
+	ret = mt9v032_power_on(mt9v032);
+	if (ret < 0)
+		return ret;
+
+	/* Configure the pixel clock polarity */
+	if (mt9v032->pdata && mt9v032->pdata->clk_pol) {
+		ret = mt9v032_write(client, MT9V032_PIXEL_CLOCK,
+				MT9V032_PIXEL_CLOCK_INV_PXL_CLK);
+		if (ret < 0)
+			return ret;
+	}
+
+	/* Disable the noise correction algorithm and restore the controls. */
+	ret = mt9v032_write(client, MT9V032_ROW_NOISE_CORR_CONTROL, 0);
+	if (ret < 0)
+		return ret;
+
+	return v4l2_ctrl_handler_setup(&mt9v032->ctrls);
+}
+
+/* -----------------------------------------------------------------------------
+ * V4L2 subdev video operations
+ */
+
+static struct v4l2_mbus_framefmt *
+__mt9v032_get_pad_format(struct mt9v032 *mt9v032, struct v4l2_subdev_fh *fh,
+			 unsigned int pad, enum v4l2_subdev_format_whence which)
+{
+	switch (which) {
+	case V4L2_SUBDEV_FORMAT_TRY:
+		return v4l2_subdev_get_try_format(fh, pad);
+	case V4L2_SUBDEV_FORMAT_ACTIVE:
+		return &mt9v032->format;
+	default:
+		return NULL;
+	}
+}
+
+static struct v4l2_rect *
+__mt9v032_get_pad_crop(struct mt9v032 *mt9v032, struct v4l2_subdev_fh *fh,
+		       unsigned int pad, enum v4l2_subdev_format_whence which)
+{
+	switch (which) {
+	case V4L2_SUBDEV_FORMAT_TRY:
+		return v4l2_subdev_get_try_crop(fh, pad);
+	case V4L2_SUBDEV_FORMAT_ACTIVE:
+		return &mt9v032->crop;
+	default:
+		return NULL;
+	}
+}
+
+static int mt9v032_s_stream(struct v4l2_subdev *subdev, int enable)
+{
+	const u16 mode = MT9V032_CHIP_CONTROL_MASTER_MODE
+		       | MT9V032_CHIP_CONTROL_DOUT_ENABLE
+		       | MT9V032_CHIP_CONTROL_SEQUENTIAL;
+	struct i2c_client *client = v4l2_get_subdevdata(subdev);
+	struct mt9v032 *mt9v032 = to_mt9v032(subdev);
+	struct v4l2_mbus_framefmt *format = &mt9v032->format;
+	struct v4l2_rect *crop = &mt9v032->crop;
+	unsigned int hratio;
+	unsigned int vratio;
+	int ret;
+
+	if (!enable)
+		return mt9v032_set_chip_control(mt9v032, mode, 0);
+
+	/* Configure the window size and row/column bin */
+	hratio = DIV_ROUND_CLOSEST(crop->width, format->width);
+	vratio = DIV_ROUND_CLOSEST(crop->height, format->height);
+
+	ret = mt9v032_write(client, MT9V032_READ_MODE,
+		    (hratio - 1) << MT9V032_READ_MODE_ROW_BIN_SHIFT |
+		    (vratio - 1) << MT9V032_READ_MODE_COLUMN_BIN_SHIFT);
+	if (ret < 0)
+		return ret;
+
+	ret = mt9v032_write(client, MT9V032_COLUMN_START, crop->left);
+	if (ret < 0)
+		return ret;
+
+	ret = mt9v032_write(client, MT9V032_ROW_START, crop->top);
+	if (ret < 0)
+		return ret;
+
+	ret = mt9v032_write(client, MT9V032_WINDOW_WIDTH, crop->width);
+	if (ret < 0)
+		return ret;
+
+	ret = mt9v032_write(client, MT9V032_WINDOW_HEIGHT, crop->height);
+	if (ret < 0)
+		return ret;
+
+	ret = mt9v032_write(client, MT9V032_HORIZONTAL_BLANKING,
+			    max(43, 660 - crop->width));
+	if (ret < 0)
+		return ret;
+
+	/* Switch to master "normal" mode */
+	return mt9v032_set_chip_control(mt9v032, 0, mode);
+}
+
+static int mt9v032_enum_mbus_code(struct v4l2_subdev *subdev,
+				  struct v4l2_subdev_fh *fh,
+				  struct v4l2_subdev_mbus_code_enum *code)
+{
+	if (code->index > 0)
+		return -EINVAL;
+
+	code->code = V4L2_MBUS_FMT_SGRBG10_1X10;
+	return 0;
+}
+
+static int mt9v032_enum_frame_size(struct v4l2_subdev *subdev,
+				   struct v4l2_subdev_fh *fh,
+				   struct v4l2_subdev_frame_size_enum *fse)
+{
+	if (fse->index >= 8 || fse->code != V4L2_MBUS_FMT_SGRBG10_1X10)
+		return -EINVAL;
+
+	fse->min_width = MT9V032_WINDOW_WIDTH_DEF / fse->index;
+	fse->max_width = fse->min_width;
+	fse->min_height = MT9V032_WINDOW_HEIGHT_DEF / fse->index;
+	fse->max_height = fse->min_height;
+
+	return 0;
+}
+
+static int mt9v032_get_format(struct v4l2_subdev *subdev,
+			      struct v4l2_subdev_fh *fh,
+			      struct v4l2_subdev_format *format)
+{
+	struct mt9v032 *mt9v032 = to_mt9v032(subdev);
+
+	format->format = *__mt9v032_get_pad_format(mt9v032, fh, format->pad,
+						   format->which);
+	return 0;
+}
+
+static int mt9v032_set_format(struct v4l2_subdev *subdev,
+			      struct v4l2_subdev_fh *fh,
+			      struct v4l2_subdev_format *format)
+{
+	struct mt9v032 *mt9v032 = to_mt9v032(subdev);
+	struct v4l2_mbus_framefmt *__format;
+	struct v4l2_rect *__crop;
+	unsigned int width;
+	unsigned int height;
+	unsigned int hratio;
+	unsigned int vratio;
+
+	__crop = __mt9v032_get_pad_crop(mt9v032, fh, format->pad,
+					format->which);
+
+	/* Clamp the width and height to avoid dividing by zero. */
+	width = clamp_t(unsigned int, ALIGN(format->format.width, 2),
+			max(__crop->width / 8, MT9V032_WINDOW_WIDTH_MIN),
+			__crop->width);
+	height = clamp_t(unsigned int, ALIGN(format->format.height, 2),
+			 max(__crop->height / 8, MT9V032_WINDOW_HEIGHT_MIN),
+			 __crop->height);
+
+	hratio = DIV_ROUND_CLOSEST(__crop->width, width);
+	vratio = DIV_ROUND_CLOSEST(__crop->height, height);
+
+	__format = __mt9v032_get_pad_format(mt9v032, fh, format->pad,
+					    format->which);
+	__format->width = __crop->width / hratio;
+	__format->height = __crop->height / vratio;
+
+	format->format = *__format;
+
+	return 0;
+}
+
+static int mt9v032_get_crop(struct v4l2_subdev *subdev,
+			    struct v4l2_subdev_fh *fh,
+			    struct v4l2_subdev_crop *crop)
+{
+	struct mt9v032 *mt9v032 = to_mt9v032(subdev);
+
+	crop->rect = *__mt9v032_get_pad_crop(mt9v032, fh, crop->pad,
+					     crop->which);
+	return 0;
+}
+
+static int mt9v032_set_crop(struct v4l2_subdev *subdev,
+			    struct v4l2_subdev_fh *fh,
+			    struct v4l2_subdev_crop *crop)
+{
+	struct mt9v032 *mt9v032 = to_mt9v032(subdev);
+	struct v4l2_mbus_framefmt *__format;
+	struct v4l2_rect *__crop;
+	struct v4l2_rect rect;
+
+	/* Clamp the crop rectangle boundaries and align them to a multiple of 2
+	 * pixels.
+	 */
+	rect.left = clamp(ALIGN(crop->rect.left, 2),
+			  MT9V032_COLUMN_START_MIN,
+			  MT9V032_COLUMN_START_MAX);
+	rect.top = clamp(ALIGN(crop->rect.top, 2),
+			 MT9V032_ROW_START_MIN,
+			 MT9V032_ROW_START_MAX);
+	rect.width = clamp(ALIGN(crop->rect.width, 2),
+			   MT9V032_WINDOW_WIDTH_MIN,
+			   MT9V032_WINDOW_WIDTH_MAX);
+	rect.height = clamp(ALIGN(crop->rect.height, 2),
+			    MT9V032_WINDOW_HEIGHT_MIN,
+			    MT9V032_WINDOW_HEIGHT_MAX);
+
+	rect.width = min(rect.width, MT9V032_PIXEL_ARRAY_WIDTH - rect.left);
+	rect.height = min(rect.height, MT9V032_PIXEL_ARRAY_HEIGHT - rect.top);
+
+	__crop = __mt9v032_get_pad_crop(mt9v032, fh, crop->pad, crop->which);
+
+	if (rect.width != __crop->width || rect.height != __crop->height) {
+		/* Reset the output image size if the crop rectangle size has
+		 * been modified.
+		 */
+		__format = __mt9v032_get_pad_format(mt9v032, fh, crop->pad,
+						    crop->which);
+		__format->width = rect.width;
+		__format->height = rect.height;
+	}
+
+	*__crop = rect;
+	crop->rect = rect;
+
+	return 0;
+}
+
+/* -----------------------------------------------------------------------------
+ * V4L2 subdev control operations
+ */
+
+#define V4L2_CID_TEST_PATTERN		(V4L2_CID_USER_BASE | 0x1001)
+
+static int mt9v032_s_ctrl(struct v4l2_ctrl *ctrl)
+{
+	struct mt9v032 *mt9v032 =
+			container_of(ctrl->handler, struct mt9v032, ctrls);
+	struct i2c_client *client = v4l2_get_subdevdata(&mt9v032->subdev);
+	u16 data;
+
+	switch (ctrl->id) {
+	case V4L2_CID_AUTOGAIN:
+		return mt9v032_update_aec_agc(mt9v032, MT9V032_AGC_ENABLE,
+					      ctrl->val);
+
+	case V4L2_CID_GAIN:
+		return mt9v032_write(client, MT9V032_ANALOG_GAIN, ctrl->val);
+
+	case V4L2_CID_EXPOSURE_AUTO:
+		return mt9v032_update_aec_agc(mt9v032, MT9V032_AEC_ENABLE,
+					      ctrl->val);
+
+	case V4L2_CID_EXPOSURE:
+		return mt9v032_write(client, MT9V032_TOTAL_SHUTTER_WIDTH,
+				     ctrl->val);
+
+	case V4L2_CID_TEST_PATTERN:
+		switch (ctrl->val) {
+		case 0:
+			data = 0;
+			break;
+		case 1:
+			data = MT9V032_TEST_PATTERN_GRAY_VERTICAL
+			     | MT9V032_TEST_PATTERN_ENABLE;
+			break;
+		case 2:
+			data = MT9V032_TEST_PATTERN_GRAY_HORIZONTAL
+			     | MT9V032_TEST_PATTERN_ENABLE;
+			break;
+		case 3:
+			data = MT9V032_TEST_PATTERN_GRAY_DIAGONAL
+			     | MT9V032_TEST_PATTERN_ENABLE;
+			break;
+		default:
+			data = (ctrl->val << MT9V032_TEST_PATTERN_DATA_SHIFT)
+			     | MT9V032_TEST_PATTERN_USE_DATA
+			     | MT9V032_TEST_PATTERN_ENABLE
+			     | MT9V032_TEST_PATTERN_FLIP;
+			break;
+		}
+
+		return mt9v032_write(client, MT9V032_TEST_PATTERN, data);
+	}
+
+	return 0;
+}
+
+static struct v4l2_ctrl_ops mt9v032_ctrl_ops = {
+	.s_ctrl = mt9v032_s_ctrl,
+};
+
+static const struct v4l2_ctrl_config mt9v032_ctrls[] = {
+	{
+		.ops		= &mt9v032_ctrl_ops,
+		.id		= V4L2_CID_TEST_PATTERN,
+		.type		= V4L2_CTRL_TYPE_INTEGER,
+		.name		= "Test pattern",
+		.min		= 0,
+		.max		= 1023,
+		.step		= 1,
+		.def		= 0,
+		.flags		= 0,
+	}
+};
+
+/* -----------------------------------------------------------------------------
+ * V4L2 subdev core operations
+ */
+
+static int mt9v032_set_power(struct v4l2_subdev *subdev, int on)
+{
+	struct mt9v032 *mt9v032 = to_mt9v032(subdev);
+	int ret = 0;
+
+	mutex_lock(&mt9v032->power_lock);
+
+	/* If the power count is modified from 0 to != 0 or from != 0 to 0,
+	 * update the power state.
+	 */
+	if (mt9v032->power_count == !on) {
+		ret = __mt9v032_set_power(mt9v032, !!on);
+		if (ret < 0)
+			goto done;
+	}
+
+	/* Update the power count. */
+	mt9v032->power_count += on ? 1 : -1;
+	WARN_ON(mt9v032->power_count < 0);
+
+done:
+	mutex_unlock(&mt9v032->power_lock);
+	return ret;
+}
+
+/* -----------------------------------------------------------------------------
+ * V4L2 subdev internal operations
+ */
+
+static int mt9v032_registered(struct v4l2_subdev *subdev)
+{
+	struct i2c_client *client = v4l2_get_subdevdata(subdev);
+	struct mt9v032 *mt9v032 = to_mt9v032(subdev);
+	s32 data;
+	int ret;
+
+	dev_info(&client->dev, "Probing MT9V032 at address 0x%02x\n",
+			client->addr);
+
+	ret = mt9v032_power_on(mt9v032);
+	if (ret < 0) {
+		dev_err(&client->dev, "MT9V032 power up failed\n");
+		return ret;
+	}
+
+	/* Read and check the sensor version */
+	data = mt9v032_read(client, MT9V032_CHIP_VERSION);
+	if (data != MT9V032_CHIP_ID_REV1 && data != MT9V032_CHIP_ID_REV3) {
+		dev_err(&client->dev, "MT9V032 not detected, wrong version "
+				"0x%04x\n", data);
+		return -ENODEV;
+	}
+
+	mt9v032_power_off(mt9v032);
+
+	dev_info(&client->dev, "MT9V032 detected at address 0x%02x\n",
+			client->addr);
+
+	return ret;
+}
+
+static int mt9v032_open(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh)
+{
+	struct v4l2_mbus_framefmt *format;
+	struct v4l2_rect *crop;
+
+	crop = v4l2_subdev_get_try_crop(fh, 0);
+	crop->left = MT9V032_COLUMN_START_DEF;
+	crop->top = MT9V032_ROW_START_DEF;
+	crop->width = MT9V032_WINDOW_WIDTH_DEF;
+	crop->height = MT9V032_WINDOW_HEIGHT_DEF;
+
+	format = v4l2_subdev_get_try_format(fh, 0);
+	format->code = V4L2_MBUS_FMT_SGRBG10_1X10;
+	format->width = MT9V032_WINDOW_WIDTH_DEF;
+	format->height = MT9V032_WINDOW_HEIGHT_DEF;
+	format->field = V4L2_FIELD_NONE;
+	format->colorspace = V4L2_COLORSPACE_SRGB;
+
+	return mt9v032_set_power(subdev, 1);
+}
+
+static int mt9v032_close(struct v4l2_subdev *subdev, struct v4l2_subdev_fh *fh)
+{
+	return mt9v032_set_power(subdev, 0);
+}
+
+static struct v4l2_subdev_core_ops mt9v032_subdev_core_ops = {
+	.s_power	= mt9v032_set_power,
+};
+
+static struct v4l2_subdev_video_ops mt9v032_subdev_video_ops = {
+	.s_stream	= mt9v032_s_stream,
+};
+
+static struct v4l2_subdev_pad_ops mt9v032_subdev_pad_ops = {
+	.enum_mbus_code = mt9v032_enum_mbus_code,
+	.enum_frame_size = mt9v032_enum_frame_size,
+	.get_fmt = mt9v032_get_format,
+	.set_fmt = mt9v032_set_format,
+	.get_crop = mt9v032_get_crop,
+	.set_crop = mt9v032_set_crop,
+};
+
+static struct v4l2_subdev_ops mt9v032_subdev_ops = {
+	.core	= &mt9v032_subdev_core_ops,
+	.video	= &mt9v032_subdev_video_ops,
+	.pad	= &mt9v032_subdev_pad_ops,
+};
+
+static const struct v4l2_subdev_internal_ops mt9v032_subdev_internal_ops = {
+	.registered = mt9v032_registered,
+	.open = mt9v032_open,
+	.close = mt9v032_close,
+};
+
+/* -----------------------------------------------------------------------------
+ * Driver initialization and probing
+ */
+
+static int mt9v032_probe(struct i2c_client *client,
+		const struct i2c_device_id *did)
+{
+	struct mt9v032 *mt9v032;
+	unsigned int i;
+	int ret;
+
+	if (!i2c_check_functionality(client->adapter,
+				     I2C_FUNC_SMBUS_WORD_DATA)) {
+		dev_warn(&client->adapter->dev,
+			 "I2C-Adapter doesn't support I2C_FUNC_SMBUS_WORD\n");
+		return -EIO;
+	}
+
+	mt9v032 = kzalloc(sizeof(*mt9v032), GFP_KERNEL);
+	if (!mt9v032)
+		return -ENOMEM;
+
+	mutex_init(&mt9v032->power_lock);
+	mt9v032->pdata = client->dev.platform_data;
+
+	v4l2_ctrl_handler_init(&mt9v032->ctrls, ARRAY_SIZE(mt9v032_ctrls) + 4);
+
+	v4l2_ctrl_new_std(&mt9v032->ctrls, &mt9v032_ctrl_ops,
+			  V4L2_CID_AUTOGAIN, 0, 1, 1, 1);
+	v4l2_ctrl_new_std(&mt9v032->ctrls, &mt9v032_ctrl_ops,
+			  V4L2_CID_GAIN, MT9V032_ANALOG_GAIN_MIN,
+			  MT9V032_ANALOG_GAIN_MAX, 1, MT9V032_ANALOG_GAIN_DEF);
+	v4l2_ctrl_new_std_menu(&mt9v032->ctrls, &mt9v032_ctrl_ops,
+			       V4L2_CID_EXPOSURE_AUTO, V4L2_EXPOSURE_MANUAL, 0,
+			       V4L2_EXPOSURE_AUTO);
+	v4l2_ctrl_new_std(&mt9v032->ctrls, &mt9v032_ctrl_ops,
+			  V4L2_CID_EXPOSURE, MT9V032_TOTAL_SHUTTER_WIDTH_MIN,
+			  MT9V032_TOTAL_SHUTTER_WIDTH_MAX, 1,
+			  MT9V032_TOTAL_SHUTTER_WIDTH_DEF);
+
+	for (i = 0; i < ARRAY_SIZE(mt9v032_ctrls); ++i)
+		v4l2_ctrl_new_custom(&mt9v032->ctrls, &mt9v032_ctrls[i], NULL);
+
+	mt9v032->subdev.ctrl_handler = &mt9v032->ctrls;
+
+	if (mt9v032->ctrls.error)
+		printk(KERN_INFO "%s: control initialization error %d\n",
+		       __func__, mt9v032->ctrls.error);
+
+	mt9v032->crop.left = MT9V032_COLUMN_START_DEF;
+	mt9v032->crop.top = MT9V032_ROW_START_DEF;
+	mt9v032->crop.width = MT9V032_WINDOW_WIDTH_DEF;
+	mt9v032->crop.height = MT9V032_WINDOW_HEIGHT_DEF;
+
+	mt9v032->format.code = V4L2_MBUS_FMT_SGRBG10_1X10;
+	mt9v032->format.width = MT9V032_WINDOW_WIDTH_DEF;
+	mt9v032->format.height = MT9V032_WINDOW_HEIGHT_DEF;
+	mt9v032->format.field = V4L2_FIELD_NONE;
+	mt9v032->format.colorspace = V4L2_COLORSPACE_SRGB;
+
+	mt9v032->aec_agc = MT9V032_AEC_ENABLE | MT9V032_AGC_ENABLE;
+
+	v4l2_i2c_subdev_init(&mt9v032->subdev, client, &mt9v032_subdev_ops);
+	mt9v032->subdev.internal_ops = &mt9v032_subdev_internal_ops;
+	mt9v032->subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
+
+	mt9v032->pad.flags = MEDIA_PAD_FL_SOURCE;
+	ret = media_entity_init(&mt9v032->subdev.entity, 1, &mt9v032->pad, 0);
+	if (ret < 0)
+		kfree(mt9v032);
+
+	return ret;
+}
+
+static int mt9v032_remove(struct i2c_client *client)
+{
+	struct v4l2_subdev *subdev = i2c_get_clientdata(client);
+	struct mt9v032 *mt9v032 = to_mt9v032(subdev);
+
+	v4l2_device_unregister_subdev(subdev);
+	media_entity_cleanup(&subdev->entity);
+	kfree(mt9v032);
+	return 0;
+}
+
+static const struct i2c_device_id mt9v032_id[] = {
+	{ "mt9v032", 0 },
+	{ }
+};
+MODULE_DEVICE_TABLE(i2c, mt9v032_id);
+
+static struct i2c_driver mt9v032_driver = {
+	.driver = {
+		.name = "mt9v032",
+	},
+	.probe		= mt9v032_probe,
+	.remove		= mt9v032_remove,
+	.id_table	= mt9v032_id,
+};
+
+static int __init mt9v032_init(void)
+{
+	return i2c_add_driver(&mt9v032_driver);
+}
+
+static void __exit mt9v032_exit(void)
+{
+	i2c_del_driver(&mt9v032_driver);
+}
+
+module_init(mt9v032_init);
+module_exit(mt9v032_exit);
+
+MODULE_DESCRIPTION("Aptina MT9V032 Camera driver");
+MODULE_AUTHOR("Laurent Pinchart <laurent.pinchart@ideasonboard.com>");
+MODULE_LICENSE("GPL");
diff -druN linux-2.6.39-libre/drivers/media/video/mx1_camera.c linux-3.0-rc7-libre/drivers/media/video/mx1_camera.c
--- linux-2.6.39-libre/drivers/media/video/mx1_camera.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/video/mx1_camera.c	2011-07-11 19:51:52.000000000 -0400
@@ -444,12 +444,9 @@
 {
 	struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
 	struct mx1_camera_dev *pcdev = ici->priv;
-	int ret;
 
-	if (pcdev->icd) {
-		ret = -EBUSY;
-		goto ebusy;
-	}
+	if (pcdev->icd)
+		return -EBUSY;
 
 	dev_info(icd->dev.parent, "MX1 Camera driver attached to camera %d\n",
 		 icd->devnum);
@@ -458,8 +455,7 @@
 
 	pcdev->icd = icd;
 
-ebusy:
-	return ret;
+	return 0;
 }
 
 static void mx1_camera_remove_device(struct soc_camera_device *icd)
diff -druN linux-2.6.39-libre/drivers/media/video/mx3_camera.c linux-3.0-rc7-libre/drivers/media/video/mx3_camera.c
--- linux-2.6.39-libre/drivers/media/video/mx3_camera.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/video/mx3_camera.c	2011-07-11 19:51:52.000000000 -0400
@@ -400,6 +400,35 @@
 	return 0;
 }
 
+static int mx3_stop_streaming(struct vb2_queue *q)
+{
+	struct soc_camera_device *icd = soc_camera_from_vb2q(q);
+	struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
+	struct mx3_camera_dev *mx3_cam = ici->priv;
+	struct idmac_channel *ichan = mx3_cam->idmac_channel[0];
+	struct dma_chan *chan;
+	struct mx3_camera_buffer *buf, *tmp;
+	unsigned long flags;
+
+	if (ichan) {
+		chan = &ichan->dma_chan;
+		chan->device->device_control(chan, DMA_TERMINATE_ALL, 0);
+	}
+
+	spin_lock_irqsave(&mx3_cam->lock, flags);
+
+	mx3_cam->active = NULL;
+
+	list_for_each_entry_safe(buf, tmp, &mx3_cam->capture, queue) {
+		buf->state = CSI_BUF_NEEDS_INIT;
+		list_del_init(&buf->queue);
+	}
+
+	spin_unlock_irqrestore(&mx3_cam->lock, flags);
+
+	return 0;
+}
+
 static struct vb2_ops mx3_videobuf_ops = {
 	.queue_setup	= mx3_videobuf_setup,
 	.buf_prepare	= mx3_videobuf_prepare,
@@ -408,6 +437,7 @@
 	.buf_init	= mx3_videobuf_init,
 	.wait_prepare	= soc_camera_unlock,
 	.wait_finish	= soc_camera_lock,
+	.stop_streaming	= mx3_stop_streaming,
 };
 
 static int mx3_camera_init_videobuf(struct vb2_queue *q,
@@ -658,8 +688,8 @@
 
 	fmt = soc_mbus_get_fmtdesc(code);
 	if (!fmt) {
-		dev_err(icd->dev.parent,
-			"Invalid format code #%u: %d\n", idx, code);
+		dev_warn(icd->dev.parent,
+			 "Unsupported format code #%u: %d\n", idx, code);
 		return 0;
 	}
 
@@ -712,13 +742,9 @@
 
 static void configure_geometry(struct mx3_camera_dev *mx3_cam,
 			       unsigned int width, unsigned int height,
-			       enum v4l2_mbus_pixelcode code)
+			       const struct soc_mbus_pixelfmt *fmt)
 {
 	u32 ctrl, width_field, height_field;
-	const struct soc_mbus_pixelfmt *fmt;
-
-	fmt = soc_mbus_get_fmtdesc(code);
-	BUG_ON(!fmt);
 
 	if (fourcc_to_ipu_pix(fmt->fourcc) == IPU_PIX_FMT_GENERIC) {
 		/*
@@ -726,8 +752,10 @@
 		 * the width parameter count the number of samples to
 		 * capture to complete the whole image width.
 		 */
-		width *= soc_mbus_samples_per_pixel(fmt);
-		BUG_ON(width < 0);
+		unsigned int num, den;
+		int ret = soc_mbus_samples_per_pixel(fmt, &num, &den);
+		BUG_ON(ret < 0);
+		width = width * num / den;
 	}
 
 	/* Setup frame size - this cannot be changed on-the-fly... */
@@ -774,8 +802,8 @@
  */
 static inline void stride_align(__u32 *width)
 {
-	if (((*width + 7) &  ~7) < 4096)
-		*width = (*width + 7) &  ~7;
+	if (ALIGN(*width, 8) < 4096)
+		*width = ALIGN(*width, 8);
 	else
 		*width = *width &  ~7;
 }
@@ -801,11 +829,14 @@
 	if (ret < 0)
 		return ret;
 
-	/* The capture device might have changed its output  */
+	/* The capture device might have changed its output sizes */
 	ret = v4l2_subdev_call(sd, video, g_mbus_fmt, &mf);
 	if (ret < 0)
 		return ret;
 
+	if (mf.code != icd->current_fmt->code)
+		return -EINVAL;
+
 	if (mf.width & 7) {
 		/* Ouch! We can only handle 8-byte aligned width... */
 		stride_align(&mf.width);
@@ -815,7 +846,8 @@
 	}
 
 	if (mf.width != icd->user_width || mf.height != icd->user_height)
-		configure_geometry(mx3_cam, mf.width, mf.height, mf.code);
+		configure_geometry(mx3_cam, mf.width, mf.height,
+				   icd->current_fmt->host_fmt);
 
 	dev_dbg(icd->dev.parent, "Sensor cropped %dx%d\n",
 		mf.width, mf.height);
@@ -853,7 +885,7 @@
 	 * mxc_v4l2_s_fmt()
 	 */
 
-	configure_geometry(mx3_cam, pix->width, pix->height, xlate->code);
+	configure_geometry(mx3_cam, pix->width, pix->height, xlate->host_fmt);
 
 	mf.width	= pix->width;
 	mf.height	= pix->height;
diff -druN linux-2.6.39-libre/drivers/media/video/omap/omap_vout.c linux-3.0-rc7-libre/drivers/media/video/omap/omap_vout.c
--- linux-2.6.39-libre/drivers/media/video/omap/omap_vout.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/video/omap/omap_vout.c	2011-07-11 19:51:52.000000000 -0400
@@ -47,7 +47,7 @@
 #include <plat/dma.h>
 #include <plat/vram.h>
 #include <plat/vrfb.h>
-#include <plat/display.h>
+#include <video/omapdss.h>
 
 #include "omap_voutlib.h"
 #include "omap_voutdef.h"
@@ -982,6 +982,14 @@
 	startindex = (vout->vid == OMAP_VIDEO1) ?
 		video1_numbuffers : video2_numbuffers;
 
+	/* Check the size of the buffer */
+	if (*size > vout->buffer_size) {
+		v4l2_err(&vout->vid_dev->v4l2_dev,
+				"buffer allocation mismatch [%u] [%u]\n",
+				*size, vout->buffer_size);
+		return -ENOMEM;
+	}
+
 	for (i = startindex; i < *count; i++) {
 		vout->buffer_size = *size;
 
@@ -1228,6 +1236,14 @@
 				(vma->vm_pgoff << PAGE_SHIFT));
 		return -EINVAL;
 	}
+	/* Check the size of the buffer */
+	if (size > vout->buffer_size) {
+		v4l2_err(&vout->vid_dev->v4l2_dev,
+				"insufficient memory [%lu] [%u]\n",
+				size, vout->buffer_size);
+		return -ENOMEM;
+	}
+
 	q->bufs[i]->baddr = vma->vm_start;
 
 	vma->vm_flags |= VM_RESERVED;
@@ -2391,7 +2407,7 @@
 		/* Register the Video device with V4L2
 		 */
 		vfd = vout->vfd;
-		if (video_register_device(vfd, VFL_TYPE_GRABBER, k + 1) < 0) {
+		if (video_register_device(vfd, VFL_TYPE_GRABBER, -1) < 0) {
 			dev_err(&pdev->dev, ": Could not register "
 					"Video for Linux device\n");
 			vfd->minor = -1;
diff -druN linux-2.6.39-libre/drivers/media/video/omap/omap_voutdef.h linux-3.0-rc7-libre/drivers/media/video/omap/omap_voutdef.h
--- linux-2.6.39-libre/drivers/media/video/omap/omap_voutdef.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/video/omap/omap_voutdef.h	2011-07-11 19:51:52.000000000 -0400
@@ -11,7 +11,7 @@
 #ifndef OMAP_VOUTDEF_H
 #define OMAP_VOUTDEF_H
 
-#include <plat/display.h>
+#include <video/omapdss.h>
 
 #define YUYV_BPP        2
 #define RGB565_BPP      2
diff -druN linux-2.6.39-libre/drivers/media/video/omap/omap_voutlib.c linux-3.0-rc7-libre/drivers/media/video/omap/omap_voutlib.c
--- linux-2.6.39-libre/drivers/media/video/omap/omap_voutlib.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/video/omap/omap_voutlib.c	2011-07-11 19:51:52.000000000 -0400
@@ -193,7 +193,7 @@
 		return -EINVAL;
 
 	if (cpu_is_omap24xx()) {
-		if (crop->height != win->w.height) {
+		if (try_crop.height != win->w.height) {
 			/* If we're resizing vertically, we can't support a
 			 * crop width wider than 768 pixels.
 			 */
@@ -202,7 +202,7 @@
 		}
 	}
 	/* vertical resizing */
-	vresize = (1024 * crop->height) / win->w.height;
+	vresize = (1024 * try_crop.height) / win->w.height;
 	if (cpu_is_omap24xx() && (vresize > 2048))
 		vresize = 2048;
 	else if (cpu_is_omap34xx() && (vresize > 4096))
@@ -221,7 +221,7 @@
 			try_crop.height = 2;
 	}
 	/* horizontal resizing */
-	hresize = (1024 * crop->width) / win->w.width;
+	hresize = (1024 * try_crop.width) / win->w.width;
 	if (cpu_is_omap24xx() && (hresize > 2048))
 		hresize = 2048;
 	else if (cpu_is_omap34xx() && (hresize > 4096))
diff -druN linux-2.6.39-libre/drivers/media/video/omap1_camera.c linux-3.0-rc7-libre/drivers/media/video/omap1_camera.c
--- linux-2.6.39-libre/drivers/media/video/omap1_camera.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/video/omap1_camera.c	2011-07-11 19:51:52.000000000 -0400
@@ -990,63 +990,80 @@
 }
 
 /* Duplicate standard formats based on host capability of byte swapping */
-static const struct soc_mbus_pixelfmt omap1_cam_formats[] = {
-	[V4L2_MBUS_FMT_UYVY8_2X8] = {
+static const struct soc_mbus_lookup omap1_cam_formats[] = {
+{
+	.code = V4L2_MBUS_FMT_UYVY8_2X8,
+	.fmt = {
 		.fourcc			= V4L2_PIX_FMT_YUYV,
 		.name			= "YUYV",
 		.bits_per_sample	= 8,
 		.packing		= SOC_MBUS_PACKING_2X8_PADHI,
 		.order			= SOC_MBUS_ORDER_BE,
 	},
-	[V4L2_MBUS_FMT_VYUY8_2X8] = {
+}, {
+	.code = V4L2_MBUS_FMT_VYUY8_2X8,
+	.fmt = {
 		.fourcc			= V4L2_PIX_FMT_YVYU,
 		.name			= "YVYU",
 		.bits_per_sample	= 8,
 		.packing		= SOC_MBUS_PACKING_2X8_PADHI,
 		.order			= SOC_MBUS_ORDER_BE,
 	},
-	[V4L2_MBUS_FMT_YUYV8_2X8] = {
+}, {
+	.code = V4L2_MBUS_FMT_YUYV8_2X8,
+	.fmt = {
 		.fourcc			= V4L2_PIX_FMT_UYVY,
 		.name			= "UYVY",
 		.bits_per_sample	= 8,
 		.packing		= SOC_MBUS_PACKING_2X8_PADHI,
 		.order			= SOC_MBUS_ORDER_BE,
 	},
-	[V4L2_MBUS_FMT_YVYU8_2X8] = {
+}, {
+	.code = V4L2_MBUS_FMT_YVYU8_2X8,
+	.fmt = {
 		.fourcc			= V4L2_PIX_FMT_VYUY,
 		.name			= "VYUY",
 		.bits_per_sample	= 8,
 		.packing		= SOC_MBUS_PACKING_2X8_PADHI,
 		.order			= SOC_MBUS_ORDER_BE,
 	},
-	[V4L2_MBUS_FMT_RGB555_2X8_PADHI_BE] = {
+}, {
+	.code = V4L2_MBUS_FMT_RGB555_2X8_PADHI_BE,
+	.fmt = {
 		.fourcc			= V4L2_PIX_FMT_RGB555,
 		.name			= "RGB555",
 		.bits_per_sample	= 8,
 		.packing		= SOC_MBUS_PACKING_2X8_PADHI,
 		.order			= SOC_MBUS_ORDER_BE,
 	},
-	[V4L2_MBUS_FMT_RGB555_2X8_PADHI_LE] = {
+}, {
+	.code = V4L2_MBUS_FMT_RGB555_2X8_PADHI_LE,
+	.fmt = {
 		.fourcc			= V4L2_PIX_FMT_RGB555X,
 		.name			= "RGB555X",
 		.bits_per_sample	= 8,
 		.packing		= SOC_MBUS_PACKING_2X8_PADHI,
 		.order			= SOC_MBUS_ORDER_BE,
 	},
-	[V4L2_MBUS_FMT_RGB565_2X8_BE] = {
+}, {
+	.code = V4L2_MBUS_FMT_RGB565_2X8_BE,
+	.fmt = {
 		.fourcc			= V4L2_PIX_FMT_RGB565,
 		.name			= "RGB565",
 		.bits_per_sample	= 8,
 		.packing		= SOC_MBUS_PACKING_2X8_PADHI,
 		.order			= SOC_MBUS_ORDER_BE,
 	},
-	[V4L2_MBUS_FMT_RGB565_2X8_LE] = {
+}, {
+	.code = V4L2_MBUS_FMT_RGB565_2X8_LE,
+	.fmt = {
 		.fourcc			= V4L2_PIX_FMT_RGB565X,
 		.name			= "RGB565X",
 		.bits_per_sample	= 8,
 		.packing		= SOC_MBUS_PACKING_2X8_PADHI,
 		.order			= SOC_MBUS_ORDER_BE,
 	},
+},
 };
 
 static int omap1_cam_get_formats(struct soc_camera_device *icd,
@@ -1065,7 +1082,7 @@
 
 	fmt = soc_mbus_get_fmtdesc(code);
 	if (!fmt) {
-		dev_err(dev, "%s: invalid format code #%d: %d\n", __func__,
+		dev_warn(dev, "%s: unsupported format code #%d: %d\n", __func__,
 				idx, code);
 		return 0;
 	}
@@ -1085,12 +1102,14 @@
 	case V4L2_MBUS_FMT_RGB565_2X8_LE:
 		formats++;
 		if (xlate) {
-			xlate->host_fmt	= &omap1_cam_formats[code];
+			xlate->host_fmt	= soc_mbus_find_fmtdesc(code,
+						omap1_cam_formats,
+						ARRAY_SIZE(omap1_cam_formats));
 			xlate->code	= code;
 			xlate++;
 			dev_dbg(dev,
 				"%s: providing format %s as byte swapped code #%d\n",
-				__func__, omap1_cam_formats[code].name, code);
+				__func__, xlate->host_fmt->name, code);
 		}
 	default:
 		if (xlate)
diff -druN linux-2.6.39-libre/drivers/media/video/omap3isp/isp.c linux-3.0-rc7-libre/drivers/media/video/omap3isp/isp.c
--- linux-2.6.39-libre/drivers/media/video/omap3isp/isp.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/video/omap3isp/isp.c	2011-07-11 19:51:52.000000000 -0400
@@ -391,7 +391,7 @@
 	};
 	int i;
 
-	dev_dbg(isp->dev, "");
+	dev_dbg(isp->dev, "ISP IRQ: ");
 
 	for (i = 0; i < ARRAY_SIZE(name); i++) {
 		if ((1 << i) & irqstatus)
@@ -1748,7 +1748,7 @@
 		goto done;
 
 	/* Register external entities */
-	for (subdevs = pdata->subdevs; subdevs->subdevs; ++subdevs) {
+	for (subdevs = pdata->subdevs; subdevs && subdevs->subdevs; ++subdevs) {
 		struct v4l2_subdev *sensor;
 		struct media_entity *input;
 		unsigned int flags;
diff -druN linux-2.6.39-libre/drivers/media/video/pvrusb2/pvrusb2-hdw.c linux-3.0-rc7-libre/drivers/media/video/pvrusb2/pvrusb2-hdw.c
--- linux-2.6.39-libre/drivers/media/video/pvrusb2/pvrusb2-hdw.c	2011-05-19 02:10:24.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/video/pvrusb2/pvrusb2-hdw.c	2011-07-21 06:52:51.000000000 -0400
@@ -3046,6 +3046,8 @@
 	if (hdw->input_dirty || hdw->audiomode_dirty || hdw->force_dirty) {
 		struct v4l2_tuner vt;
 		memset(&vt, 0, sizeof(vt));
+		vt.type = (hdw->input_val == PVR2_CVAL_INPUT_RADIO) ?
+			V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
 		vt.audmode = hdw->audiomode_val;
 		v4l2_device_call_all(&hdw->v4l2_dev, 0, tuner, s_tuner, &vt);
 	}
@@ -5171,6 +5173,8 @@
 {
 	struct v4l2_tuner *vtp = &hdw->tuner_signal_info;
 	memset(vtp, 0, sizeof(*vtp));
+	vtp->type = (hdw->input_val == PVR2_CVAL_INPUT_RADIO) ?
+		V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
 	hdw->tuner_signal_stale = 0;
 	/* Note: There apparently is no replacement for VIDIOC_CROPCAP
 	   using v4l2-subdev - therefore we can't support that AT ALL right
diff -druN linux-2.6.39-libre/drivers/media/video/pvrusb2/pvrusb2-std.c linux-3.0-rc7-libre/drivers/media/video/pvrusb2/pvrusb2-std.c
--- linux-2.6.39-libre/drivers/media/video/pvrusb2/pvrusb2-std.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/video/pvrusb2/pvrusb2-std.c	2011-07-11 19:51:52.000000000 -0400
@@ -278,12 +278,10 @@
 	}
 };
 
-#define generic_standards_cnt ARRAY_SIZE(generic_standards)
-
 static struct v4l2_standard *match_std(v4l2_std_id id)
 {
 	unsigned int idx;
-	for (idx = 0; idx < generic_standards_cnt; idx++) {
+	for (idx = 0; idx < ARRAY_SIZE(generic_standards); idx++) {
 		if (generic_standards[idx].id & id) {
 			return generic_standards + idx;
 		}
@@ -370,7 +368,11 @@
 
 	stddefs = kzalloc(sizeof(struct v4l2_standard) * std_cnt,
 			  GFP_KERNEL);
-	for (idx = 0; idx < std_cnt; idx++) stddefs[idx].index = idx;
+	if (!stddefs)
+		return NULL;
+
+	for (idx = 0; idx < std_cnt; idx++)
+		stddefs[idx].index = idx;
 
 	idx = 0;
 
diff -druN linux-2.6.39-libre/drivers/media/video/pwc/pwc-ctrl.c linux-3.0-rc7-libre/drivers/media/video/pwc/pwc-ctrl.c
--- linux-2.6.39-libre/drivers/media/video/pwc/pwc-ctrl.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/video/pwc/pwc-ctrl.c	2011-07-11 19:51:52.000000000 -0400
@@ -1414,7 +1414,7 @@
 	{
 		ARG_DEF(struct pwc_probe, probe)
 
-		strcpy(ARGR(probe).name, pdev->vdev->name);
+		strcpy(ARGR(probe).name, pdev->vdev.name);
 		ARGR(probe).type = pdev->type;
 		ARG_OUT(probe)
 		break;
diff -druN linux-2.6.39-libre/drivers/media/video/pwc/pwc.h linux-3.0-rc7-libre/drivers/media/video/pwc/pwc.h
--- linux-2.6.39-libre/drivers/media/video/pwc/pwc.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/video/pwc/pwc.h	2011-07-11 19:51:52.000000000 -0400
@@ -162,9 +162,9 @@
 
 struct pwc_device
 {
-   struct video_device *vdev;
+	struct video_device vdev;
 
-   /* Pointer to our usb_device */
+   /* Pointer to our usb_device, may be NULL after unplug */
    struct usb_device *udev;
 
    int type;                    /* type of cam (645, 646, 675, 680, 690, 720, 730, 740, 750) */
diff -druN linux-2.6.39-libre/drivers/media/video/pwc/pwc-if.c linux-3.0-rc7-libre/drivers/media/video/pwc/pwc-if.c
--- linux-2.6.39-libre/drivers/media/video/pwc/pwc-if.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/video/pwc/pwc-if.c	2011-07-11 19:51:52.000000000 -0400
@@ -40,7 +40,7 @@
    Oh yes, convention: to disctinguish between all the various pointers to
    device-structures, I use these names for the pointer variables:
    udev: struct usb_device *
-   vdev: struct video_device *
+   vdev: struct video_device (member of pwc_dev)
    pdev: struct pwc_devive *
 */
 
@@ -152,6 +152,7 @@
 			  size_t count, loff_t *ppos);
 static unsigned int pwc_video_poll(struct file *file, poll_table *wait);
 static int  pwc_video_mmap(struct file *file, struct vm_area_struct *vma);
+static void pwc_video_release(struct video_device *vfd);
 
 static const struct v4l2_file_operations pwc_fops = {
 	.owner =	THIS_MODULE,
@@ -164,42 +165,12 @@
 };
 static struct video_device pwc_template = {
 	.name =		"Philips Webcam",	/* Filled in later */
-	.release =	video_device_release,
+	.release =	pwc_video_release,
 	.fops =         &pwc_fops,
+	.ioctl_ops =	&pwc_ioctl_ops,
 };
 
 /***************************************************************************/
-
-/* Okay, this is some magic that I worked out and the reasoning behind it...
-
-   The biggest problem with any USB device is of course: "what to do
-   when the user unplugs the device while it is in use by an application?"
-   We have several options:
-   1) Curse them with the 7 plagues when they do (requires divine intervention)
-   2) Tell them not to (won't work: they'll do it anyway)
-   3) Oops the kernel (this will have a negative effect on a user's uptime)
-   4) Do something sensible.
-
-   Of course, we go for option 4.
-
-   It happens that this device will be linked to two times, once from
-   usb_device and once from the video_device in their respective 'private'
-   pointers. This is done when the device is probed() and all initialization
-   succeeded. The pwc_device struct links back to both structures.
-
-   When a device is unplugged while in use it will be removed from the
-   list of known USB devices; I also de-register it as a V4L device, but
-   unfortunately I can't free the memory since the struct is still in use
-   by the file descriptor. This free-ing is then deferend until the first
-   opportunity. Crude, but it works.
-
-   A small 'advantage' is that if a user unplugs the cam and plugs it back
-   in, it should get assigned the same video device minor, but unfortunately
-   it's non-trivial to re-link the cam back to the video device... (that
-   would surely be magic! :))
-*/
-
-/***************************************************************************/
 /* Private functions */
 
 /* Here we want the physical address of the memory.
@@ -1016,16 +987,15 @@
 static DEVICE_ATTR(button, S_IRUGO | S_IWUSR, show_snapshot_button_status,
 		   NULL);
 
-static int pwc_create_sysfs_files(struct video_device *vdev)
+static int pwc_create_sysfs_files(struct pwc_device *pdev)
 {
-	struct pwc_device *pdev = video_get_drvdata(vdev);
 	int rc;
 
-	rc = device_create_file(&vdev->dev, &dev_attr_button);
+	rc = device_create_file(&pdev->vdev.dev, &dev_attr_button);
 	if (rc)
 		goto err;
 	if (pdev->features & FEATURE_MOTOR_PANTILT) {
-		rc = device_create_file(&vdev->dev, &dev_attr_pan_tilt);
+		rc = device_create_file(&pdev->vdev.dev, &dev_attr_pan_tilt);
 		if (rc)
 			goto err_button;
 	}
@@ -1033,19 +1003,17 @@
 	return 0;
 
 err_button:
-	device_remove_file(&vdev->dev, &dev_attr_button);
+	device_remove_file(&pdev->vdev.dev, &dev_attr_button);
 err:
 	PWC_ERROR("Could not create sysfs files.\n");
 	return rc;
 }
 
-static void pwc_remove_sysfs_files(struct video_device *vdev)
+static void pwc_remove_sysfs_files(struct pwc_device *pdev)
 {
-	struct pwc_device *pdev = video_get_drvdata(vdev);
-
 	if (pdev->features & FEATURE_MOTOR_PANTILT)
-		device_remove_file(&vdev->dev, &dev_attr_pan_tilt);
-	device_remove_file(&vdev->dev, &dev_attr_button);
+		device_remove_file(&pdev->vdev.dev, &dev_attr_pan_tilt);
+	device_remove_file(&pdev->vdev.dev, &dev_attr_button);
 }
 
 #ifdef CONFIG_USB_PWC_DEBUG
@@ -1106,7 +1074,7 @@
 		if (ret >= 0)
 		{
 			PWC_DEBUG_OPEN("This %s camera is equipped with a %s (%d).\n",
-					pdev->vdev->name,
+					pdev->vdev.name,
 					pwc_sensor_type_to_string(i), i);
 		}
 	}
@@ -1180,16 +1148,15 @@
 	return 0;
 }
 
-
-static void pwc_cleanup(struct pwc_device *pdev)
+static void pwc_video_release(struct video_device *vfd)
 {
-	pwc_remove_sysfs_files(pdev->vdev);
-	video_unregister_device(pdev->vdev);
+	struct pwc_device *pdev = container_of(vfd, struct pwc_device, vdev);
+	int hint;
 
-#ifdef CONFIG_USB_PWC_INPUT_EVDEV
-	if (pdev->button_dev)
-		input_unregister_device(pdev->button_dev);
-#endif
+	/* search device_hint[] table if we occupy a slot, by any chance */
+	for (hint = 0; hint < MAX_DEV_HINTS; hint++)
+		if (device_hint[hint].pdev == pdev)
+			device_hint[hint].pdev = NULL;
 
 	kfree(pdev);
 }
@@ -1199,7 +1166,7 @@
 {
 	struct video_device *vdev = file->private_data;
 	struct pwc_device *pdev;
-	int i, hint;
+	int i;
 
 	PWC_DEBUG_OPEN(">> video_close called(vdev = 0x%p).\n", vdev);
 
@@ -1234,12 +1201,6 @@
 		}
 		pdev->vopen--;
 		PWC_DEBUG_OPEN("<< video_close() vopen=%d\n", pdev->vopen);
-	} else {
-		pwc_cleanup(pdev);
-		/* search device_hint[] table if we occupy a slot, by any chance */
-		for (hint = 0; hint < MAX_DEV_HINTS; hint++)
-			if (device_hint[hint].pdev == pdev)
-				device_hint[hint].pdev = NULL;
 	}
 
 	return 0;
@@ -1715,19 +1676,12 @@
 	init_waitqueue_head(&pdev->frameq);
 	pdev->vcompression = pwc_preferred_compression;
 
-	/* Allocate video_device structure */
-	pdev->vdev = video_device_alloc();
-	if (!pdev->vdev) {
-		PWC_ERROR("Err, cannot allocate video_device struture. Failing probe.");
-		rc = -ENOMEM;
-		goto err_free_mem;
-	}
-	memcpy(pdev->vdev, &pwc_template, sizeof(pwc_template));
-	pdev->vdev->parent = &intf->dev;
-	pdev->vdev->lock = &pdev->modlock;
-	pdev->vdev->ioctl_ops = &pwc_ioctl_ops;
-	strcpy(pdev->vdev->name, name);
-	video_set_drvdata(pdev->vdev, pdev);
+	/* Init video_device structure */
+	memcpy(&pdev->vdev, &pwc_template, sizeof(pwc_template));
+	pdev->vdev.parent = &intf->dev;
+	pdev->vdev.lock = &pdev->modlock;
+	strcpy(pdev->vdev.name, name);
+	video_set_drvdata(&pdev->vdev, pdev);
 
 	pdev->release = le16_to_cpu(udev->descriptor.bcdDevice);
 	PWC_DEBUG_PROBE("Release: %04x\n", pdev->release);
@@ -1746,8 +1700,6 @@
 		}
 	}
 
-	pdev->vdev->release = video_device_release;
-
 	/* occupy slot */
 	if (hint < MAX_DEV_HINTS)
 		device_hint[hint].pdev = pdev;
@@ -1759,16 +1711,16 @@
 	pwc_set_leds(pdev, 0, 0);
 	pwc_camera_power(pdev, 0);
 
-	rc = video_register_device(pdev->vdev, VFL_TYPE_GRABBER, video_nr);
+	rc = video_register_device(&pdev->vdev, VFL_TYPE_GRABBER, video_nr);
 	if (rc < 0) {
 		PWC_ERROR("Failed to register as video device (%d).\n", rc);
-		goto err_video_release;
+		goto err_free_mem;
 	}
-	rc = pwc_create_sysfs_files(pdev->vdev);
+	rc = pwc_create_sysfs_files(pdev);
 	if (rc)
 		goto err_video_unreg;
 
-	PWC_INFO("Registered as %s.\n", video_device_node_name(pdev->vdev));
+	PWC_INFO("Registered as %s.\n", video_device_node_name(&pdev->vdev));
 
 #ifdef CONFIG_USB_PWC_INPUT_EVDEV
 	/* register webcam snapshot button input device */
@@ -1776,7 +1728,7 @@
 	if (!pdev->button_dev) {
 		PWC_ERROR("Err, insufficient memory for webcam snapshot button device.");
 		rc = -ENOMEM;
-		pwc_remove_sysfs_files(pdev->vdev);
+		pwc_remove_sysfs_files(pdev);
 		goto err_video_unreg;
 	}
 
@@ -1794,7 +1746,7 @@
 	if (rc) {
 		input_free_device(pdev->button_dev);
 		pdev->button_dev = NULL;
-		pwc_remove_sysfs_files(pdev->vdev);
+		pwc_remove_sysfs_files(pdev);
 		goto err_video_unreg;
 	}
 #endif
@@ -1804,10 +1756,7 @@
 err_video_unreg:
 	if (hint < MAX_DEV_HINTS)
 		device_hint[hint].pdev = NULL;
-	video_unregister_device(pdev->vdev);
-	pdev->vdev = NULL;	/* So we don't try to release it below */
-err_video_release:
-	video_device_release(pdev->vdev);
+	video_unregister_device(&pdev->vdev);
 err_free_mem:
 	kfree(pdev);
 	return rc;
@@ -1816,10 +1765,8 @@
 /* The user yanked out the cable... */
 static void usb_pwc_disconnect(struct usb_interface *intf)
 {
-	struct pwc_device *pdev;
-	int hint;
+	struct pwc_device *pdev  = usb_get_intfdata(intf);
 
-	pdev = usb_get_intfdata (intf);
 	mutex_lock(&pdev->modlock);
 	usb_set_intfdata (intf, NULL);
 	if (pdev == NULL) {
@@ -1836,30 +1783,25 @@
 	}
 
 	/* We got unplugged; this is signalled by an EPIPE error code */
-	if (pdev->vopen) {
-		PWC_INFO("Disconnected while webcam is in use!\n");
-		pdev->error_status = EPIPE;
-	}
+	pdev->error_status = EPIPE;
+	pdev->unplugged = 1;
 
 	/* Alert waiting processes */
 	wake_up_interruptible(&pdev->frameq);
-	/* Wait until device is closed */
-	if (pdev->vopen) {
-		pdev->unplugged = 1;
-		pwc_iso_stop(pdev);
-	} else {
-		/* Device is closed, so we can safely unregister it */
-		PWC_DEBUG_PROBE("Unregistering video device in disconnect().\n");
-		pwc_cleanup(pdev);
 
-disconnect_out:
-		/* search device_hint[] table if we occupy a slot, by any chance */
-		for (hint = 0; hint < MAX_DEV_HINTS; hint++)
-			if (device_hint[hint].pdev == pdev)
-				device_hint[hint].pdev = NULL;
-	}
+	/* No need to keep the urbs around after disconnection */
+	pwc_isoc_cleanup(pdev);
 
+disconnect_out:
 	mutex_unlock(&pdev->modlock);
+
+	pwc_remove_sysfs_files(pdev);
+	video_unregister_device(&pdev->vdev);
+
+#ifdef CONFIG_USB_PWC_INPUT_EVDEV
+	if (pdev->button_dev)
+		input_unregister_device(pdev->button_dev);
+#endif
 }
 
 
diff -druN linux-2.6.39-libre/drivers/media/video/pwc/pwc-v4l.c linux-3.0-rc7-libre/drivers/media/video/pwc/pwc-v4l.c
--- linux-2.6.39-libre/drivers/media/video/pwc/pwc-v4l.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/video/pwc/pwc-v4l.c	2011-07-11 19:51:52.000000000 -0400
@@ -379,8 +379,27 @@
 
 static int pwc_queryctrl(struct file *file, void *fh, struct v4l2_queryctrl *c)
 {
-	int i;
+	int i, idx;
+	u32 id;
 
+	id = c->id;
+	if (id & V4L2_CTRL_FLAG_NEXT_CTRL) {
+		id &= V4L2_CTRL_ID_MASK;
+		id++;
+		idx = -1;
+		for (i = 0; i < ARRAY_SIZE(pwc_controls); i++) {
+			if (pwc_controls[i].id < id)
+				continue;
+			if (idx >= 0
+			 && pwc_controls[i].id > pwc_controls[idx].id)
+				continue;
+			idx = i;
+		}
+		if (idx < 0)
+			return -EINVAL;
+		memcpy(c, &pwc_controls[idx], sizeof pwc_controls[0]);
+		return 0;
+	}
 	for (i = 0; i < sizeof(pwc_controls) / sizeof(struct v4l2_queryctrl); i++) {
 		if (pwc_controls[i].id == c->id) {
 			PWC_DEBUG_IOCTL("ioctl(VIDIOC_QUERYCTRL) found\n");
diff -druN linux-2.6.39-libre/drivers/media/video/pxa_camera.c linux-3.0-rc7-libre/drivers/media/video/pxa_camera.c
--- linux-2.6.39-libre/drivers/media/video/pxa_camera.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/video/pxa_camera.c	2011-07-11 19:51:52.000000000 -0400
@@ -1155,15 +1155,11 @@
 	struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
 	struct pxa_camera_dev *pcdev = ici->priv;
 	unsigned long bus_flags, camera_flags, common_flags;
-	const struct soc_mbus_pixelfmt *fmt;
 	int ret;
 	struct pxa_cam *cam = icd->host_priv;
 
-	fmt = soc_mbus_get_fmtdesc(icd->current_fmt->code);
-	if (!fmt)
-		return -EINVAL;
-
-	ret = test_platform_param(pcdev, fmt->bits_per_sample, &bus_flags);
+	ret = test_platform_param(pcdev, icd->current_fmt->host_fmt->bits_per_sample,
+				  &bus_flags);
 	if (ret < 0)
 		return ret;
 
diff -druN linux-2.6.39-libre/drivers/media/video/s2255drv.c linux-3.0-rc7-libre/drivers/media/video/s2255drv.c
--- linux-2.6.39-libre/drivers/media/video/s2255drv.c	2011-05-19 02:10:49.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/video/s2255drv.c	2011-07-21 06:53:20.000000000 -0400
@@ -394,12 +394,17 @@
 /* start video number */
 static int video_nr = -1;	/* /dev/videoN, -1 for autodetect */
 
+/* Enable jpeg capture. */
+static int jpeg_enable = 1;
+
 module_param(debug, int, 0644);
 MODULE_PARM_DESC(debug, "Debug level(0-100) default 0");
 module_param(vid_limit, int, 0644);
 MODULE_PARM_DESC(vid_limit, "video memory limit(Mb)");
 module_param(video_nr, int, 0644);
 MODULE_PARM_DESC(video_nr, "start video minor(-1 default autodetect)");
+module_param(jpeg_enable, int, 0644);
+MODULE_PARM_DESC(jpeg_enable, "Jpeg enable(1-on 0-off) default 1");
 
 /* USB device table */
 #define USB_SENSORAY_VID	0x1943
@@ -413,6 +418,7 @@
 #define BUFFER_TIMEOUT msecs_to_jiffies(400)
 
 /* image formats.  */
+/* JPEG formats must be defined last to support jpeg_enable parameter */
 static const struct s2255_fmt formats[] = {
 	{
 		.name = "4:2:2, planar, YUV422P",
@@ -429,13 +435,17 @@
 		.fourcc = V4L2_PIX_FMT_UYVY,
 		.depth = 16
 	}, {
+		.name = "8bpp GREY",
+		.fourcc = V4L2_PIX_FMT_GREY,
+		.depth = 8
+	}, {
 		.name = "JPG",
 		.fourcc = V4L2_PIX_FMT_JPEG,
 		.depth = 24
 	}, {
-		.name = "8bpp GREY",
-		.fourcc = V4L2_PIX_FMT_GREY,
-		.depth = 8
+		.name = "MJPG",
+		.fourcc = V4L2_PIX_FMT_MJPEG,
+		.depth = 24
 	}
 };
 
@@ -610,6 +620,9 @@
 	for (i = 0; i < ARRAY_SIZE(formats); i++) {
 		if (-1 == formats[i].fourcc)
 			continue;
+	if (!jpeg_enable && ((formats[i].fourcc == V4L2_PIX_FMT_JPEG) ||
+			     (formats[i].fourcc == V4L2_PIX_FMT_MJPEG)))
+	    continue;
 		if (formats[i].fourcc == fourcc)
 			return formats + i;
 	}
@@ -653,6 +666,7 @@
 			memcpy(vbuf, tmpbuf, buf->vb.width * buf->vb.height);
 			break;
 		case V4L2_PIX_FMT_JPEG:
+		case V4L2_PIX_FMT_MJPEG:
 			buf->vb.size = jpgsize;
 			memcpy(vbuf, tmpbuf, buf->vb.size);
 			break;
@@ -856,7 +870,9 @@
 
 	if (index >= ARRAY_SIZE(formats))
 		return -EINVAL;
-
+    if (!jpeg_enable && ((formats[index].fourcc == V4L2_PIX_FMT_JPEG) ||
+			 (formats[index].fourcc == V4L2_PIX_FMT_MJPEG)))
+	return -EINVAL;
 	dprintk(4, "name %s\n", formats[index].name);
 	strlcpy(f->description, formats[index].name, sizeof(f->description));
 	f->pixelformat = formats[index].fourcc;
@@ -1037,6 +1053,7 @@
 		mode.color |= COLOR_Y8;
 		break;
 	case V4L2_PIX_FMT_JPEG:
+	case V4L2_PIX_FMT_MJPEG:
 		mode.color &= ~MASK_COLOR;
 		mode.color |= COLOR_JPG;
 		mode.color |= (channel->jc.quality << 8);
@@ -2382,7 +2399,7 @@
 			  read_pipe_completion, pipe_info);
 
 	if (pipe_info->state != 0) {
-		if (usb_submit_urb(pipe_info->stream_urb, GFP_KERNEL)) {
+		if (usb_submit_urb(pipe_info->stream_urb, GFP_ATOMIC)) {
 			dev_err(&dev->udev->dev, "error submitting urb\n");
 		}
 	} else {
diff -druN linux-2.6.39-libre/drivers/media/video/s5p-fimc/fimc-capture.c linux-3.0-rc7-libre/drivers/media/video/s5p-fimc/fimc-capture.c
--- linux-2.6.39-libre/drivers/media/video/s5p-fimc/fimc-capture.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/video/s5p-fimc/fimc-capture.c	2011-07-11 19:51:52.000000000 -0400
@@ -1,7 +1,7 @@
 /*
- * Samsung S5P SoC series camera interface (camera capture) driver
+ * Samsung S5P/EXYNOS4 SoC series camera interface (camera capture) driver
  *
- * Copyright (c) 2010 Samsung Electronics Co., Ltd
+ * Copyright (C) 2010 - 2011 Samsung Electronics Co., Ltd.
  * Author: Sylwester Nawrocki, <s.nawrocki@samsung.com>
  *
  * This program is free software; you can redistribute it and/or modify
@@ -262,12 +262,7 @@
 {
 	if (!fr || plane >= fr->fmt->memplanes)
 		return 0;
-
-	dbg("%s: w: %d. h: %d. depth[%d]: %d",
-	    __func__, fr->width, fr->height, plane, fr->fmt->depth[plane]);
-
 	return fr->f_width * fr->f_height * fr->fmt->depth[plane] / 8;
-
 }
 
 static int queue_setup(struct vb2_queue *vq, unsigned int *num_buffers,
@@ -283,24 +278,14 @@
 
 	*num_planes = fmt->memplanes;
 
-	dbg("%s, buffer count=%d, plane count=%d",
-	    __func__, *num_buffers, *num_planes);
-
 	for (i = 0; i < fmt->memplanes; i++) {
 		sizes[i] = get_plane_size(&ctx->d_frame, i);
-		dbg("plane: %u, plane_size: %lu", i, sizes[i]);
 		allocators[i] = ctx->fimc_dev->alloc_ctx;
 	}
 
 	return 0;
 }
 
-static int buffer_init(struct vb2_buffer *vb)
-{
-	/* TODO: */
-	return 0;
-}
-
 static int buffer_prepare(struct vb2_buffer *vb)
 {
 	struct vb2_queue *vq = vb->vb2_queue;
@@ -380,7 +365,6 @@
 	.queue_setup		= queue_setup,
 	.buf_prepare		= buffer_prepare,
 	.buf_queue		= buffer_queue,
-	.buf_init		= buffer_init,
 	.wait_prepare		= fimc_unlock,
 	.wait_finish		= fimc_lock,
 	.start_streaming	= start_streaming,
@@ -903,6 +887,7 @@
 err_v4l2_reg:
 	v4l2_device_unregister(v4l2_dev);
 err_info:
+	kfree(ctx);
 	dev_err(&fimc->pdev->dev, "failed to install\n");
 	return ret;
 }
diff -druN linux-2.6.39-libre/drivers/media/video/s5p-fimc/fimc-core.c linux-3.0-rc7-libre/drivers/media/video/s5p-fimc/fimc-core.c
--- linux-2.6.39-libre/drivers/media/video/s5p-fimc/fimc-core.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/video/s5p-fimc/fimc-core.c	2011-07-11 19:51:52.000000000 -0400
@@ -1,9 +1,8 @@
 /*
- * S5P camera interface (video postprocessor) driver
- *
- * Copyright (c) 2010 Samsung Electronics Co., Ltd
+ * Samsung S5P/EXYNOS4 SoC series camera interface (video postprocessor) driver
  *
- * Sylwester Nawrocki, <s.nawrocki@samsung.com>
+ * Copyright (C) 2010-2011 Samsung Electronics Co., Ltd.
+ * Contact: Sylwester Nawrocki, <s.nawrocki@samsung.com>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published
@@ -42,7 +41,6 @@
 		.color		= S5P_FIMC_RGB565,
 		.memplanes	= 1,
 		.colplanes	= 1,
-		.mbus_code	= V4L2_MBUS_FMT_RGB565_2X8_BE,
 		.flags		= FMT_FLAGS_M2M,
 	}, {
 		.name		= "BGR666",
@@ -232,11 +230,7 @@
 			return 0;
 		}
 	}
-
 	*shift = 0, *ratio = 1;
-
-	dbg("s: %d, t: %d, shift: %d, ratio: %d",
-	    src, tar, *shift, *ratio);
 	return 0;
 }
 
@@ -268,10 +262,8 @@
 		err("invalid source size: %d x %d", sx, sy);
 		return -EINVAL;
 	}
-
 	sc->real_width = sx;
 	sc->real_height = sy;
-	dbg("sx= %d, sy= %d, tx= %d, ty= %d", sx, sy, tx, ty);
 
 	ret = fimc_get_scaler_factor(sx, tx, &sc->pre_hratio, &sc->hfactor);
 	if (ret)
@@ -711,22 +703,18 @@
 	f = ctx_get_frame(ctx, vq->type);
 	if (IS_ERR(f))
 		return PTR_ERR(f);
-
 	/*
 	 * Return number of non-contigous planes (plane buffers)
 	 * depending on the configured color format.
 	 */
-	if (f->fmt)
-		*num_planes = f->fmt->memplanes;
+	if (!f->fmt)
+		return -EINVAL;
 
+	*num_planes = f->fmt->memplanes;
 	for (i = 0; i < f->fmt->memplanes; i++) {
-		sizes[i] = (f->width * f->height * f->fmt->depth[i]) >> 3;
+		sizes[i] = (f->f_width * f->f_height * f->fmt->depth[i]) / 8;
 		allocators[i] = ctx->fimc_dev->alloc_ctx;
 	}
-
-	if (*num_buffers == 0)
-		*num_buffers = 1;
-
 	return 0;
 }
 
@@ -852,7 +840,7 @@
 
 	for (i = 0; i < ARRAY_SIZE(fimc_formats); ++i) {
 		fmt = &fimc_formats[i];
-		if (fmt->fourcc == f->fmt.pix.pixelformat &&
+		if (fmt->fourcc == f->fmt.pix_mp.pixelformat &&
 		   (fmt->flags & mask))
 			break;
 	}
diff -druN linux-2.6.39-libre/drivers/media/video/s5p-fimc/fimc-core.h linux-3.0-rc7-libre/drivers/media/video/s5p-fimc/fimc-core.h
--- linux-2.6.39-libre/drivers/media/video/s5p-fimc/fimc-core.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/video/s5p-fimc/fimc-core.h	2011-07-11 19:51:52.000000000 -0400
@@ -1,7 +1,5 @@
 /*
- * Copyright (c) 2010 Samsung Electronics
- *
- * Sylwester Nawrocki, <s.nawrocki@samsung.com>
+ * Copyright (C) 2010 - 2011 Samsung Electronics Co., Ltd.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
@@ -135,9 +133,10 @@
  * @name: format description
  * @fourcc: the fourcc code for this format, 0 if not applicable
  * @color: the corresponding fimc_color_fmt
- * @depth: per plane driver's private 'number of bits per pixel'
  * @memplanes: number of physically non-contiguous data planes
  * @colplanes: number of physically contiguous data planes
+ * @depth: per plane driver's private 'number of bits per pixel'
+ * @flags: flags indicating which operation mode format applies to
  */
 struct fimc_fmt {
 	enum v4l2_mbus_pixelcode mbus_code;
@@ -171,7 +170,7 @@
 };
 
 /**
- * struct fimc_effect - the configuration data for the "Arbitrary" image effect
+ * struct fimc_effect - color effect information
  * @type:	effect type
  * @pat_cb:	cr value when type is "arbitrary"
  * @pat_cr:	cr value when type is "arbitrary"
@@ -184,7 +183,6 @@
 
 /**
  * struct fimc_scaler - the configuration data for FIMC inetrnal scaler
- *
  * @scaleup_h:		flag indicating scaling up horizontally
  * @scaleup_v:		flag indicating scaling up vertically
  * @copy_mode:		flag indicating transparent DMA transfer (no scaling
@@ -220,7 +218,6 @@
 
 /**
  * struct fimc_addr - the FIMC physical address set for DMA
- *
  * @y:	 luminance plane physical address
  * @cb:	 Cb plane physical address
  * @cr:	 Cr plane physical address
@@ -234,6 +231,7 @@
 /**
  * struct fimc_vid_buffer - the driver's video buffer
  * @vb:    v4l videobuf buffer
+ * @list:  linked list structure for buffer queue
  * @paddr: precalculated physical address set
  * @index: buffer index for the output DMA engine
  */
@@ -254,11 +252,10 @@
  * @offs_v:	image vertical pixel offset
  * @width:	image pixel width
  * @height:	image pixel weight
- * @paddr:	image frame buffer physical addresses
- * @buf_cnt:	number of buffers depending on a color format
  * @payload:	image size in bytes (w x h x bpp)
- * @color:	color format
+ * @paddr:	image frame buffer physical addresses
  * @dma_offset:	DMA offset in bytes
+ * @fmt:	fimc color format pointer
  */
 struct fimc_frame {
 	u32	f_width;
@@ -390,21 +387,22 @@
 
 /**
  * struct fimc_dev - abstraction for FIMC entity
- *
  * @slock:	the spinlock protecting this data structure
  * @lock:	the mutex protecting this data structure
  * @pdev:	pointer to the FIMC platform device
  * @pdata:	pointer to the device platform data
+ * @variant:	the IP variant information
  * @id:		FIMC device index (0..FIMC_MAX_DEVS)
  * @num_clocks: the number of clocks managed by this device instance
- * @clock[]:	the clocks required for FIMC operation
+ * @clock:	clocks required for FIMC operation
  * @regs:	the mapped hardware registers
  * @regs_res:	the resource claimed for IO registers
- * @irq:	interrupt number of the FIMC subdevice
- * @irq_queue:
+ * @irq:	FIMC interrupt number
+ * @irq_queue:	interrupt handler waitqueue
  * @m2m:	memory-to-memory V4L2 device information
  * @vid_cap:	camera capture device information
  * @state:	flags used to synchronize m2m and capture mode operation
+ * @alloc_ctx:	videobuf2 memory allocator context
  */
 struct fimc_dev {
 	spinlock_t			slock;
@@ -427,8 +425,7 @@
 
 /**
  * fimc_ctx - the device context data
- *
- * @lock:		mutex protecting this data structure
+ * @slock:		spinlock protecting this data structure
  * @s_frame:		source frame properties
  * @d_frame:		destination frame properties
  * @out_order_1p:	output 1-plane YCBCR order
diff -druN linux-2.6.39-libre/drivers/media/video/s5p-fimc/Makefile linux-3.0-rc7-libre/drivers/media/video/s5p-fimc/Makefile
--- linux-2.6.39-libre/drivers/media/video/s5p-fimc/Makefile	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/video/s5p-fimc/Makefile	2011-07-11 19:51:52.000000000 -0400
@@ -1,3 +1,5 @@
+s5p-fimc-objs := fimc-core.o fimc-reg.o fimc-capture.o
+s5p-csis-objs := mipi-csis.o
 
-obj-$(CONFIG_VIDEO_SAMSUNG_S5P_FIMC) := s5p-fimc.o
-s5p-fimc-y := fimc-core.o fimc-reg.o fimc-capture.o
+obj-$(CONFIG_VIDEO_S5P_MIPI_CSIS)	+= s5p-csis.o
+obj-$(CONFIG_VIDEO_SAMSUNG_S5P_FIMC)	+= s5p-fimc.o
diff -druN linux-2.6.39-libre/drivers/media/video/s5p-fimc/mipi-csis.c linux-3.0-rc7-libre/drivers/media/video/s5p-fimc/mipi-csis.c
--- linux-2.6.39-libre/drivers/media/video/s5p-fimc/mipi-csis.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/media/video/s5p-fimc/mipi-csis.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,724 @@
+/*
+ * Samsung S5P/EXYNOS4 SoC series MIPI-CSI receiver driver
+ *
+ * Copyright (C) 2011 Samsung Electronics Co., Ltd.
+ * Contact: Sylwester Nawrocki, <s.nawrocki@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/errno.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/kernel.h>
+#include <linux/memory.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+#include <linux/regulator/consumer.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+#include <linux/videodev2.h>
+#include <media/v4l2-subdev.h>
+#include <plat/mipi_csis.h>
+#include "mipi-csis.h"
+
+static int debug;
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "Debug level (0-1)");
+
+/* Register map definition */
+
+/* CSIS global control */
+#define S5PCSIS_CTRL			0x00
+#define S5PCSIS_CTRL_DPDN_DEFAULT	(0 << 31)
+#define S5PCSIS_CTRL_DPDN_SWAP		(1 << 31)
+#define S5PCSIS_CTRL_ALIGN_32BIT	(1 << 20)
+#define S5PCSIS_CTRL_UPDATE_SHADOW	(1 << 16)
+#define S5PCSIS_CTRL_WCLK_EXTCLK	(1 << 8)
+#define S5PCSIS_CTRL_RESET		(1 << 4)
+#define S5PCSIS_CTRL_ENABLE		(1 << 0)
+
+/* D-PHY control */
+#define S5PCSIS_DPHYCTRL		0x04
+#define S5PCSIS_DPHYCTRL_HSS_MASK	(0x1f << 27)
+#define S5PCSIS_DPHYCTRL_ENABLE		(0x1f << 0)
+
+#define S5PCSIS_CONFIG			0x08
+#define S5PCSIS_CFG_FMT_YCBCR422_8BIT	(0x1e << 2)
+#define S5PCSIS_CFG_FMT_RAW8		(0x2a << 2)
+#define S5PCSIS_CFG_FMT_RAW10		(0x2b << 2)
+#define S5PCSIS_CFG_FMT_RAW12		(0x2c << 2)
+/* User defined formats, x = 1...4 */
+#define S5PCSIS_CFG_FMT_USER(x)		((0x30 + x - 1) << 2)
+#define S5PCSIS_CFG_FMT_MASK		(0x3f << 2)
+#define S5PCSIS_CFG_NR_LANE_MASK	3
+
+/* Interrupt mask. */
+#define S5PCSIS_INTMSK			0x10
+#define S5PCSIS_INTMSK_EN_ALL		0xf000003f
+#define S5PCSIS_INTSRC			0x14
+
+/* Pixel resolution */
+#define S5PCSIS_RESOL			0x2c
+#define CSIS_MAX_PIX_WIDTH		0xffff
+#define CSIS_MAX_PIX_HEIGHT		0xffff
+
+enum {
+	CSIS_CLK_MUX,
+	CSIS_CLK_GATE,
+};
+
+static char *csi_clock_name[] = {
+	[CSIS_CLK_MUX]  = "sclk_csis",
+	[CSIS_CLK_GATE] = "csis",
+};
+#define NUM_CSIS_CLOCKS	ARRAY_SIZE(csi_clock_name)
+
+enum {
+	ST_POWERED	= 1,
+	ST_STREAMING	= 2,
+	ST_SUSPENDED	= 4,
+};
+
+/**
+ * struct csis_state - the driver's internal state data structure
+ * @lock: mutex serializing the subdev and power management operations,
+ *        protecting @format and @flags members
+ * @pads: CSIS pads array
+ * @sd: v4l2_subdev associated with CSIS device instance
+ * @pdev: CSIS platform device
+ * @regs_res: requested I/O register memory resource
+ * @regs: mmaped I/O registers memory
+ * @clock: CSIS clocks
+ * @irq: requested s5p-mipi-csis irq number
+ * @flags: the state variable for power and streaming control
+ * @csis_fmt: current CSIS pixel format
+ * @format: common media bus format for the source and sink pad
+ */
+struct csis_state {
+	struct mutex lock;
+	struct media_pad pads[CSIS_PADS_NUM];
+	struct v4l2_subdev sd;
+	struct platform_device *pdev;
+	struct resource *regs_res;
+	void __iomem *regs;
+	struct clk *clock[NUM_CSIS_CLOCKS];
+	int irq;
+	struct regulator *supply;
+	u32 flags;
+	const struct csis_pix_format *csis_fmt;
+	struct v4l2_mbus_framefmt format;
+};
+
+/**
+ * struct csis_pix_format - CSIS pixel format description
+ * @pix_width_alignment: horizontal pixel alignment, width will be
+ *                       multiple of 2^pix_width_alignment
+ * @code: corresponding media bus code
+ * @fmt_reg: S5PCSIS_CONFIG register value
+ */
+struct csis_pix_format {
+	unsigned int pix_width_alignment;
+	enum v4l2_mbus_pixelcode code;
+	u32 fmt_reg;
+};
+
+static const struct csis_pix_format s5pcsis_formats[] = {
+	{
+		.code = V4L2_MBUS_FMT_VYUY8_2X8,
+		.fmt_reg = S5PCSIS_CFG_FMT_YCBCR422_8BIT,
+	}, {
+		.code = V4L2_MBUS_FMT_JPEG_1X8,
+		.fmt_reg = S5PCSIS_CFG_FMT_USER(1),
+	},
+};
+
+#define s5pcsis_write(__csis, __r, __v) writel(__v, __csis->regs + __r)
+#define s5pcsis_read(__csis, __r) readl(__csis->regs + __r)
+
+static struct csis_state *sd_to_csis_state(struct v4l2_subdev *sdev)
+{
+	return container_of(sdev, struct csis_state, sd);
+}
+
+static const struct csis_pix_format *find_csis_format(
+	struct v4l2_mbus_framefmt *mf)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(s5pcsis_formats); i++)
+		if (mf->code == s5pcsis_formats[i].code)
+			return &s5pcsis_formats[i];
+	return NULL;
+}
+
+static void s5pcsis_enable_interrupts(struct csis_state *state, bool on)
+{
+	u32 val = s5pcsis_read(state, S5PCSIS_INTMSK);
+
+	val = on ? val | S5PCSIS_INTMSK_EN_ALL :
+		   val & ~S5PCSIS_INTMSK_EN_ALL;
+	s5pcsis_write(state, S5PCSIS_INTMSK, val);
+}
+
+static void s5pcsis_reset(struct csis_state *state)
+{
+	u32 val = s5pcsis_read(state, S5PCSIS_CTRL);
+
+	s5pcsis_write(state, S5PCSIS_CTRL, val | S5PCSIS_CTRL_RESET);
+	udelay(10);
+}
+
+static void s5pcsis_system_enable(struct csis_state *state, int on)
+{
+	u32 val;
+
+	val = s5pcsis_read(state, S5PCSIS_CTRL);
+	if (on)
+		val |= S5PCSIS_CTRL_ENABLE;
+	else
+		val &= ~S5PCSIS_CTRL_ENABLE;
+	s5pcsis_write(state, S5PCSIS_CTRL, val);
+
+	val = s5pcsis_read(state, S5PCSIS_DPHYCTRL);
+	if (on)
+		val |= S5PCSIS_DPHYCTRL_ENABLE;
+	else
+		val &= ~S5PCSIS_DPHYCTRL_ENABLE;
+	s5pcsis_write(state, S5PCSIS_DPHYCTRL, val);
+}
+
+/* Called with the state.lock mutex held */
+static void __s5pcsis_set_format(struct csis_state *state)
+{
+	struct v4l2_mbus_framefmt *mf = &state->format;
+	u32 val;
+
+	v4l2_dbg(1, debug, &state->sd, "fmt: %d, %d x %d\n",
+		 mf->code, mf->width, mf->height);
+
+	/* Color format */
+	val = s5pcsis_read(state, S5PCSIS_CONFIG);
+	val = (val & ~S5PCSIS_CFG_FMT_MASK) | state->csis_fmt->fmt_reg;
+	s5pcsis_write(state, S5PCSIS_CONFIG, val);
+
+	/* Pixel resolution */
+	val = (mf->width << 16) | mf->height;
+	s5pcsis_write(state, S5PCSIS_RESOL, val);
+}
+
+static void s5pcsis_set_hsync_settle(struct csis_state *state, int settle)
+{
+	u32 val = s5pcsis_read(state, S5PCSIS_DPHYCTRL);
+
+	val = (val & ~S5PCSIS_DPHYCTRL_HSS_MASK) | (settle << 27);
+	s5pcsis_write(state, S5PCSIS_DPHYCTRL, val);
+}
+
+static void s5pcsis_set_params(struct csis_state *state)
+{
+	struct s5p_platform_mipi_csis *pdata = state->pdev->dev.platform_data;
+	u32 val;
+
+	val = s5pcsis_read(state, S5PCSIS_CONFIG);
+	val = (val & ~S5PCSIS_CFG_NR_LANE_MASK) | (pdata->lanes - 1);
+	s5pcsis_write(state, S5PCSIS_CONFIG, val);
+
+	__s5pcsis_set_format(state);
+	s5pcsis_set_hsync_settle(state, pdata->hs_settle);
+
+	val = s5pcsis_read(state, S5PCSIS_CTRL);
+	if (pdata->alignment == 32)
+		val |= S5PCSIS_CTRL_ALIGN_32BIT;
+	else /* 24-bits */
+		val &= ~S5PCSIS_CTRL_ALIGN_32BIT;
+	/* Not using external clock. */
+	val &= ~S5PCSIS_CTRL_WCLK_EXTCLK;
+	s5pcsis_write(state, S5PCSIS_CTRL, val);
+
+	/* Update the shadow register. */
+	val = s5pcsis_read(state, S5PCSIS_CTRL);
+	s5pcsis_write(state, S5PCSIS_CTRL, val | S5PCSIS_CTRL_UPDATE_SHADOW);
+}
+
+static void s5pcsis_clk_put(struct csis_state *state)
+{
+	int i;
+
+	for (i = 0; i < NUM_CSIS_CLOCKS; i++)
+		if (!IS_ERR_OR_NULL(state->clock[i]))
+			clk_put(state->clock[i]);
+}
+
+static int s5pcsis_clk_get(struct csis_state *state)
+{
+	struct device *dev = &state->pdev->dev;
+	int i;
+
+	for (i = 0; i < NUM_CSIS_CLOCKS; i++) {
+		state->clock[i] = clk_get(dev, csi_clock_name[i]);
+		if (IS_ERR(state->clock[i])) {
+			s5pcsis_clk_put(state);
+			dev_err(dev, "failed to get clock: %s\n",
+				csi_clock_name[i]);
+			return -ENXIO;
+		}
+	}
+	return 0;
+}
+
+static int s5pcsis_s_power(struct v4l2_subdev *sd, int on)
+{
+	struct csis_state *state = sd_to_csis_state(sd);
+	struct device *dev = &state->pdev->dev;
+
+	if (on)
+		return pm_runtime_get_sync(dev);
+
+	return pm_runtime_put_sync(dev);
+}
+
+static void s5pcsis_start_stream(struct csis_state *state)
+{
+	s5pcsis_reset(state);
+	s5pcsis_set_params(state);
+	s5pcsis_system_enable(state, true);
+	s5pcsis_enable_interrupts(state, true);
+}
+
+static void s5pcsis_stop_stream(struct csis_state *state)
+{
+	s5pcsis_enable_interrupts(state, false);
+	s5pcsis_system_enable(state, false);
+}
+
+/* v4l2_subdev operations */
+static int s5pcsis_s_stream(struct v4l2_subdev *sd, int enable)
+{
+	struct csis_state *state = sd_to_csis_state(sd);
+	int ret = 0;
+
+	v4l2_dbg(1, debug, sd, "%s: %d, state: 0x%x\n",
+		 __func__, enable, state->flags);
+
+	if (enable) {
+		ret = pm_runtime_get_sync(&state->pdev->dev);
+		if (ret && ret != 1)
+			return ret;
+	}
+	mutex_lock(&state->lock);
+	if (enable) {
+		if (state->flags & ST_SUSPENDED) {
+			ret = -EBUSY;
+			goto unlock;
+		}
+		s5pcsis_start_stream(state);
+		state->flags |= ST_STREAMING;
+	} else {
+		s5pcsis_stop_stream(state);
+		state->flags &= ~ST_STREAMING;
+	}
+unlock:
+	mutex_unlock(&state->lock);
+	if (!enable)
+		pm_runtime_put(&state->pdev->dev);
+
+	return ret == 1 ? 0 : ret;
+}
+
+static int s5pcsis_enum_mbus_code(struct v4l2_subdev *sd,
+				  struct v4l2_subdev_fh *fh,
+				  struct v4l2_subdev_mbus_code_enum *code)
+{
+	if (code->index >= ARRAY_SIZE(s5pcsis_formats))
+		return -EINVAL;
+
+	code->code = s5pcsis_formats[code->index].code;
+	return 0;
+}
+
+static struct csis_pix_format const *s5pcsis_try_format(
+	struct v4l2_mbus_framefmt *mf)
+{
+	struct csis_pix_format const *csis_fmt;
+
+	csis_fmt = find_csis_format(mf);
+	if (csis_fmt == NULL)
+		csis_fmt = &s5pcsis_formats[0];
+
+	mf->code = csis_fmt->code;
+	v4l_bound_align_image(&mf->width, 1, CSIS_MAX_PIX_WIDTH,
+			      csis_fmt->pix_width_alignment,
+			      &mf->height, 1, CSIS_MAX_PIX_HEIGHT, 1,
+			      0);
+	return csis_fmt;
+}
+
+static struct v4l2_mbus_framefmt *__s5pcsis_get_format(
+		struct csis_state *state, struct v4l2_subdev_fh *fh,
+		u32 pad, enum v4l2_subdev_format_whence which)
+{
+	if (which == V4L2_SUBDEV_FORMAT_TRY)
+		return fh ? v4l2_subdev_get_try_format(fh, pad) : NULL;
+
+	return &state->format;
+}
+
+static int s5pcsis_set_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
+			   struct v4l2_subdev_format *fmt)
+{
+	struct csis_state *state = sd_to_csis_state(sd);
+	struct csis_pix_format const *csis_fmt;
+	struct v4l2_mbus_framefmt *mf;
+
+	if (fmt->pad != CSIS_PAD_SOURCE && fmt->pad != CSIS_PAD_SINK)
+		return -EINVAL;
+
+	mf = __s5pcsis_get_format(state, fh, fmt->pad, fmt->which);
+
+	if (fmt->pad == CSIS_PAD_SOURCE) {
+		if (mf) {
+			mutex_lock(&state->lock);
+			fmt->format = *mf;
+			mutex_unlock(&state->lock);
+		}
+		return 0;
+	}
+	csis_fmt = s5pcsis_try_format(&fmt->format);
+	if (mf) {
+		mutex_lock(&state->lock);
+		*mf = fmt->format;
+		if (fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE)
+			state->csis_fmt = csis_fmt;
+		mutex_unlock(&state->lock);
+	}
+	return 0;
+}
+
+static int s5pcsis_get_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
+			   struct v4l2_subdev_format *fmt)
+{
+	struct csis_state *state = sd_to_csis_state(sd);
+	struct v4l2_mbus_framefmt *mf;
+
+	if (fmt->pad != CSIS_PAD_SOURCE && fmt->pad != CSIS_PAD_SINK)
+		return -EINVAL;
+
+	mf = __s5pcsis_get_format(state, fh, fmt->pad, fmt->which);
+	if (!mf)
+		return -EINVAL;
+
+	mutex_lock(&state->lock);
+	fmt->format = *mf;
+	mutex_unlock(&state->lock);
+	return 0;
+}
+
+static struct v4l2_subdev_core_ops s5pcsis_core_ops = {
+	.s_power = s5pcsis_s_power,
+};
+
+static struct v4l2_subdev_pad_ops s5pcsis_pad_ops = {
+	.enum_mbus_code = s5pcsis_enum_mbus_code,
+	.get_fmt = s5pcsis_get_fmt,
+	.set_fmt = s5pcsis_set_fmt,
+};
+
+static struct v4l2_subdev_video_ops s5pcsis_video_ops = {
+	.s_stream = s5pcsis_s_stream,
+};
+
+static struct v4l2_subdev_ops s5pcsis_subdev_ops = {
+	.core = &s5pcsis_core_ops,
+	.pad = &s5pcsis_pad_ops,
+	.video = &s5pcsis_video_ops,
+};
+
+static irqreturn_t s5pcsis_irq_handler(int irq, void *dev_id)
+{
+	struct csis_state *state = dev_id;
+	u32 val;
+
+	/* Just clear the interrupt pending bits. */
+	val = s5pcsis_read(state, S5PCSIS_INTSRC);
+	s5pcsis_write(state, S5PCSIS_INTSRC, val);
+
+	return IRQ_HANDLED;
+}
+
+static int __devinit s5pcsis_probe(struct platform_device *pdev)
+{
+	struct s5p_platform_mipi_csis *pdata;
+	struct resource *mem_res;
+	struct resource *regs_res;
+	struct csis_state *state;
+	int ret = -ENOMEM;
+
+	state = kzalloc(sizeof(*state), GFP_KERNEL);
+	if (!state)
+		return -ENOMEM;
+
+	mutex_init(&state->lock);
+	state->pdev = pdev;
+
+	pdata = pdev->dev.platform_data;
+	if (pdata == NULL || pdata->phy_enable == NULL) {
+		dev_err(&pdev->dev, "Platform data not fully specified\n");
+		goto e_free;
+	}
+
+	if ((pdev->id == 1 && pdata->lanes > CSIS1_MAX_LANES) ||
+	    pdata->lanes > CSIS0_MAX_LANES) {
+		ret = -EINVAL;
+		dev_err(&pdev->dev, "Unsupported number of data lanes: %d\n",
+			pdata->lanes);
+		goto e_free;
+	}
+
+	mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!mem_res) {
+		dev_err(&pdev->dev, "Failed to get IO memory region\n");
+		goto e_free;
+	}
+
+	regs_res = request_mem_region(mem_res->start, resource_size(mem_res),
+				      pdev->name);
+	if (!regs_res) {
+		dev_err(&pdev->dev, "Failed to request IO memory region\n");
+		goto e_free;
+	}
+	state->regs_res = regs_res;
+
+	state->regs = ioremap(mem_res->start, resource_size(mem_res));
+	if (!state->regs) {
+		dev_err(&pdev->dev, "Failed to remap IO region\n");
+		goto e_reqmem;
+	}
+
+	ret = s5pcsis_clk_get(state);
+	if (ret)
+		goto e_unmap;
+
+	clk_enable(state->clock[CSIS_CLK_MUX]);
+	if (pdata->clk_rate)
+		clk_set_rate(state->clock[CSIS_CLK_MUX], pdata->clk_rate);
+	else
+		dev_WARN(&pdev->dev, "No clock frequency specified!\n");
+
+	state->irq = platform_get_irq(pdev, 0);
+	if (state->irq < 0) {
+		ret = state->irq;
+		dev_err(&pdev->dev, "Failed to get irq\n");
+		goto e_clkput;
+	}
+
+	if (!pdata->fixed_phy_vdd) {
+		state->supply = regulator_get(&pdev->dev, "vdd");
+		if (IS_ERR(state->supply)) {
+			ret = PTR_ERR(state->supply);
+			state->supply = NULL;
+			goto e_clkput;
+		}
+	}
+
+	ret = request_irq(state->irq, s5pcsis_irq_handler, 0,
+			  dev_name(&pdev->dev), state);
+	if (ret) {
+		dev_err(&pdev->dev, "request_irq failed\n");
+		goto e_regput;
+	}
+
+	v4l2_subdev_init(&state->sd, &s5pcsis_subdev_ops);
+	state->sd.owner = THIS_MODULE;
+	strlcpy(state->sd.name, dev_name(&pdev->dev), sizeof(state->sd.name));
+	state->csis_fmt = &s5pcsis_formats[0];
+
+	state->pads[CSIS_PAD_SINK].flags = MEDIA_PAD_FL_SINK;
+	state->pads[CSIS_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE;
+	ret = media_entity_init(&state->sd.entity,
+				CSIS_PADS_NUM, state->pads, 0);
+	if (ret < 0)
+		goto e_irqfree;
+
+	/* This allows to retrieve the platform device id by the host driver */
+	v4l2_set_subdevdata(&state->sd, pdev);
+
+	/* .. and a pointer to the subdev. */
+	platform_set_drvdata(pdev, &state->sd);
+
+	state->flags = ST_SUSPENDED;
+	pm_runtime_enable(&pdev->dev);
+
+	return 0;
+
+e_irqfree:
+	free_irq(state->irq, state);
+e_regput:
+	if (state->supply)
+		regulator_put(state->supply);
+e_clkput:
+	clk_disable(state->clock[CSIS_CLK_MUX]);
+	s5pcsis_clk_put(state);
+e_unmap:
+	iounmap(state->regs);
+e_reqmem:
+	release_mem_region(regs_res->start, resource_size(regs_res));
+e_free:
+	kfree(state);
+	return ret;
+}
+
+static int s5pcsis_suspend(struct device *dev)
+{
+	struct s5p_platform_mipi_csis *pdata = dev->platform_data;
+	struct platform_device *pdev = to_platform_device(dev);
+	struct v4l2_subdev *sd = platform_get_drvdata(pdev);
+	struct csis_state *state = sd_to_csis_state(sd);
+	int ret = 0;
+
+	v4l2_dbg(1, debug, sd, "%s: flags: 0x%x\n",
+		 __func__, state->flags);
+
+	mutex_lock(&state->lock);
+	if (state->flags & ST_POWERED) {
+		s5pcsis_stop_stream(state);
+		ret = pdata->phy_enable(state->pdev, false);
+		if (ret)
+			goto unlock;
+		if (state->supply) {
+			ret = regulator_disable(state->supply);
+			if (ret)
+				goto unlock;
+		}
+		clk_disable(state->clock[CSIS_CLK_GATE]);
+		state->flags &= ~ST_POWERED;
+	}
+	state->flags |= ST_SUSPENDED;
+ unlock:
+	mutex_unlock(&state->lock);
+	return ret ? -EAGAIN : 0;
+}
+
+static int s5pcsis_resume(struct device *dev)
+{
+	struct s5p_platform_mipi_csis *pdata = dev->platform_data;
+	struct platform_device *pdev = to_platform_device(dev);
+	struct v4l2_subdev *sd = platform_get_drvdata(pdev);
+	struct csis_state *state = sd_to_csis_state(sd);
+	int ret = 0;
+
+	v4l2_dbg(1, debug, sd, "%s: flags: 0x%x\n",
+		 __func__, state->flags);
+
+	mutex_lock(&state->lock);
+	if (!(state->flags & ST_SUSPENDED))
+		goto unlock;
+
+	if (!(state->flags & ST_POWERED)) {
+		if (state->supply)
+			ret = regulator_enable(state->supply);
+		if (ret)
+			goto unlock;
+
+		ret = pdata->phy_enable(state->pdev, true);
+		if (!ret) {
+			state->flags |= ST_POWERED;
+		} else if (state->supply) {
+			regulator_disable(state->supply);
+			goto unlock;
+		}
+		clk_enable(state->clock[CSIS_CLK_GATE]);
+	}
+	if (state->flags & ST_STREAMING)
+		s5pcsis_start_stream(state);
+
+	state->flags &= ~ST_SUSPENDED;
+ unlock:
+	mutex_unlock(&state->lock);
+	return ret ? -EAGAIN : 0;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int s5pcsis_pm_suspend(struct device *dev)
+{
+	return s5pcsis_suspend(dev);
+}
+
+static int s5pcsis_pm_resume(struct device *dev)
+{
+	int ret;
+
+	ret = s5pcsis_resume(dev);
+
+	if (!ret) {
+		pm_runtime_disable(dev);
+		ret = pm_runtime_set_active(dev);
+		pm_runtime_enable(dev);
+	}
+
+	return ret;
+}
+#endif
+
+static int __devexit s5pcsis_remove(struct platform_device *pdev)
+{
+	struct v4l2_subdev *sd = platform_get_drvdata(pdev);
+	struct csis_state *state = sd_to_csis_state(sd);
+	struct resource *res = state->regs_res;
+
+	pm_runtime_disable(&pdev->dev);
+	s5pcsis_suspend(&pdev->dev);
+	clk_disable(state->clock[CSIS_CLK_MUX]);
+	pm_runtime_set_suspended(&pdev->dev);
+
+	s5pcsis_clk_put(state);
+	if (state->supply)
+		regulator_put(state->supply);
+
+	media_entity_cleanup(&state->sd.entity);
+	free_irq(state->irq, state);
+	iounmap(state->regs);
+	release_mem_region(res->start, resource_size(res));
+	kfree(state);
+
+	return 0;
+}
+
+static const struct dev_pm_ops s5pcsis_pm_ops = {
+	SET_RUNTIME_PM_OPS(s5pcsis_suspend, s5pcsis_resume, NULL)
+	SET_SYSTEM_SLEEP_PM_OPS(s5pcsis_pm_suspend, s5pcsis_pm_resume)
+};
+
+static struct platform_driver s5pcsis_driver = {
+	.probe		= s5pcsis_probe,
+	.remove		= __devexit_p(s5pcsis_remove),
+	.driver		= {
+		.name	= CSIS_DRIVER_NAME,
+		.owner	= THIS_MODULE,
+		.pm	= &s5pcsis_pm_ops,
+	},
+};
+
+static int __init s5pcsis_init(void)
+{
+	return platform_driver_probe(&s5pcsis_driver, s5pcsis_probe);
+}
+
+static void __exit s5pcsis_exit(void)
+{
+	platform_driver_unregister(&s5pcsis_driver);
+}
+
+module_init(s5pcsis_init);
+module_exit(s5pcsis_exit);
+
+MODULE_AUTHOR("Sylwester Nawrocki <s.nawrocki@samsung.com>");
+MODULE_DESCRIPTION("S5P/EXYNOS4 MIPI CSI receiver driver");
+MODULE_LICENSE("GPL");
diff -druN linux-2.6.39-libre/drivers/media/video/s5p-fimc/mipi-csis.h linux-3.0-rc7-libre/drivers/media/video/s5p-fimc/mipi-csis.h
--- linux-2.6.39-libre/drivers/media/video/s5p-fimc/mipi-csis.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/media/video/s5p-fimc/mipi-csis.h	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,22 @@
+/*
+ * Samsung S5P/EXYNOS4 SoC series MIPI-CSI receiver driver
+ *
+ * Copyright (C) 2011 Samsung Electronics Co., Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#ifndef S5P_MIPI_CSIS_H_
+#define S5P_MIPI_CSIS_H_
+
+#define CSIS_DRIVER_NAME	"s5p-mipi-csis"
+#define CSIS_MAX_ENTITIES	2
+#define CSIS0_MAX_LANES		4
+#define CSIS1_MAX_LANES		2
+
+#define CSIS_PAD_SINK		0
+#define CSIS_PAD_SOURCE		1
+#define CSIS_PADS_NUM		2
+
+#endif
diff -druN linux-2.6.39-libre/drivers/media/video/saa7134/saa7134-cards.c linux-3.0-rc7-libre/drivers/media/video/saa7134/saa7134-cards.c
--- linux-2.6.39-libre/drivers/media/video/saa7134/saa7134-cards.c	2011-05-19 02:08:16.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/video/saa7134/saa7134-cards.c	2011-07-21 06:50:33.000000000 -0400
@@ -5591,6 +5591,105 @@
 			.amux = TV,
 		},
 	},
+	[SAA7134_BOARD_MAGICPRO_PROHDTV_PRO2] = {
+		/* Timothy Lee <timothy.lee@siriushk.com> */
+		.name		= "MagicPro ProHDTV Pro2 DMB-TH/Hybrid",
+		.audio_clock	= 0x00187de7,
+		.tuner_type	= TUNER_PHILIPS_TDA8290,
+		.radio_type	= UNSET,
+		.tuner_config	= 3,
+		.tuner_addr	= ADDR_UNSET,
+		.radio_addr	= ADDR_UNSET,
+		.gpiomask	= 0x02050000,
+		.mpeg		= SAA7134_MPEG_DVB,
+		.ts_type	= SAA7134_MPEG_TS_PARALLEL,
+		.inputs		= { {
+			.name   = name_tv,
+			.vmux   = 1,
+			.amux   = TV,
+			.tv     = 1,
+			.gpio   = 0x00050000,
+		}, {
+			.name   = name_comp1,
+			.vmux   = 3,
+			.amux   = LINE1,
+			.gpio   = 0x00050000,
+		}, {
+			.name   = name_svideo,
+			.vmux   = 8,
+			.amux   = LINE1,
+			.gpio   = 0x00050000,
+		} },
+		.radio = {
+			.name   = name_radio,
+			.amux   = TV,
+			.gpio   = 0x00050000,
+		},
+		.mute = {
+			.name   = name_mute,
+			.vmux   = 0,
+			.amux   = TV,
+			.gpio   = 0x00050000,
+		},
+	},
+	[SAA7134_BOARD_BEHOLD_501] = {
+		/*       Beholder Intl. Ltd. 2010       */
+		/* Dmitry Belimov <d.belimov@gmail.com> */
+		.name           = "Beholder BeholdTV 501",
+		.audio_clock    = 0x00200000,
+		.tuner_type     = TUNER_ABSENT,
+		.radio_type     = UNSET,
+		.tuner_addr     = ADDR_UNSET,
+		.radio_addr     = ADDR_UNSET,
+		.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,
+		},
+	},
+	[SAA7134_BOARD_BEHOLD_503FM] = {
+		/*       Beholder Intl. Ltd. 2010       */
+		/* Dmitry Belimov <d.belimov@gmail.com> */
+		.name           = "Beholder BeholdTV 503 FM",
+		.audio_clock    = 0x00200000,
+		.tuner_type     = TUNER_ABSENT,
+		.radio_type     = UNSET,
+		.tuner_addr     = ADDR_UNSET,
+		.radio_addr     = ADDR_UNSET,
+		.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,
+		},
+	},
 
 };
 
@@ -6796,6 +6895,24 @@
 		.subdevice    = 0xc900,
 		.driver_data  = SAA7134_BOARD_VIDEOMATE_M1F,
 	}, {
+		.vendor       = PCI_VENDOR_ID_PHILIPS,
+		.device       = PCI_DEVICE_ID_PHILIPS_SAA7133,
+		.subvendor    = 0x5ace,
+		.subdevice    = 0x5030,
+		.driver_data  = SAA7134_BOARD_BEHOLD_503FM,
+	}, {
+		.vendor       = PCI_VENDOR_ID_PHILIPS,
+		.device       = PCI_DEVICE_ID_PHILIPS_SAA7130,
+		.subvendor    = 0x5ace,
+		.subdevice    = 0x5010,
+		.driver_data  = SAA7134_BOARD_BEHOLD_501,
+	}, {
+		.vendor       = PCI_VENDOR_ID_PHILIPS,
+		.device       = PCI_DEVICE_ID_PHILIPS_SAA7134,
+		.subvendor    = 0x17de,
+		.subdevice    = 0xd136,
+		.driver_data  = SAA7134_BOARD_MAGICPRO_PROHDTV_PRO2,
+	}, {
 		/* --- boards without eeprom + subsystem ID --- */
 		.vendor       = PCI_VENDOR_ID_PHILIPS,
 		.device       = PCI_DEVICE_ID_PHILIPS_SAA7134,
@@ -6988,6 +7105,7 @@
 		switch (dev->board) {
 		case SAA7134_BOARD_HAUPPAUGE_HVR1150:
 		case SAA7134_BOARD_HAUPPAUGE_HVR1120:
+		case SAA7134_BOARD_MAGICPRO_PROHDTV_PRO2:
 			ret = saa7134_tda18271_hvr11x0_toggle_agc(dev, arg);
 			break;
 		case SAA7134_BOARD_KWORLD_PCI_SBTVD_FULLSEG:
@@ -7014,6 +7132,7 @@
 	case SAA7134_BOARD_HAUPPAUGE_HVR1120:
 	case SAA7134_BOARD_AVERMEDIA_M733A:
 	case SAA7134_BOARD_KWORLD_PCI_SBTVD_FULLSEG:
+	case SAA7134_BOARD_MAGICPRO_PROHDTV_PRO2:
 		/* tda8290 + tda18271 */
 		ret = saa7134_tda8290_18271_callback(dev, command, arg);
 		break;
@@ -7264,6 +7383,7 @@
 		break;
 	case SAA7134_BOARD_HAUPPAUGE_HVR1150:
 	case SAA7134_BOARD_HAUPPAUGE_HVR1120:
+		dev->has_remote = SAA7134_REMOTE_GPIO;
 		/* GPIO 26 high for digital, low for analog */
 		saa7134_set_gpio(dev, 26, 0);
 		msleep(1);
@@ -7326,6 +7446,11 @@
 		saa7134_set_gpio(dev, 1, 1);
 		dev->has_remote = SAA7134_REMOTE_GPIO;
 		break;
+	case SAA7134_BOARD_MAGICPRO_PROHDTV_PRO2:
+		/* enable LGS-8G75 */
+		saa_andorl(SAA7134_GPIO_GPMODE0 >> 2,   0x0e050000, 0x0c050000);
+		saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0x0e050000, 0x0c050000);
+		break;
 	}
 	return 0;
 }
diff -druN linux-2.6.39-libre/drivers/media/video/saa7134/saa7134-core.c linux-3.0-rc7-libre/drivers/media/video/saa7134/saa7134-core.c
--- linux-2.6.39-libre/drivers/media/video/saa7134/saa7134-core.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/video/saa7134/saa7134-core.c	2011-07-11 19:51:52.000000000 -0400
@@ -927,7 +927,7 @@
 	}
 
 	/* print pci info */
-	pci_read_config_byte(pci_dev, PCI_CLASS_REVISION, &dev->pci_rev);
+	dev->pci_rev = pci_dev->revision;
 	pci_read_config_byte(pci_dev, PCI_LATENCY_TIMER,  &dev->pci_lat);
 	printk(KERN_INFO "%s: found at %s, rev: %d, irq: %d, "
 	       "latency: %d, mmio: 0x%llx\n", dev->name,
diff -druN linux-2.6.39-libre/drivers/media/video/saa7134/saa7134-dvb.c linux-3.0-rc7-libre/drivers/media/video/saa7134/saa7134-dvb.c
--- linux-2.6.39-libre/drivers/media/video/saa7134/saa7134-dvb.c	2011-05-19 02:10:37.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/video/saa7134/saa7134-dvb.c	2011-07-21 06:53:07.000000000 -0400
@@ -53,6 +53,7 @@
 #include "lgdt3305.h"
 #include "tda8290.h"
 #include "mb86a20s.h"
+#include "lgs8gxx.h"
 
 #include "zl10353.h"
 
@@ -1123,6 +1124,26 @@
 	.gate    = TDA18271_GATE_ANALOG,
 };
 
+static struct lgs8gxx_config prohdtv_pro2_lgs8g75_config = {
+	.prod = LGS8GXX_PROD_LGS8G75,
+	.demod_address = 0x1d,
+	.serial_ts = 0,
+	.ts_clk_pol = 1,
+	.ts_clk_gated = 0,
+	.if_clk_freq = 30400, /* 30.4 MHz */
+	.if_freq = 4000, /* 4.00 MHz */
+	.if_neg_center = 0,
+	.ext_adc = 0,
+	.adc_signed = 1,
+	.adc_vpp = 3, /* 2.0 Vpp */
+	.if_neg_edge = 1,
+};
+
+static struct tda18271_config prohdtv_pro2_tda18271_config = {
+	.gate = TDA18271_GATE_ANALOG,
+	.output_opt = TDA18271_OUTPUT_LT_OFF,
+};
+
 /* ==================================================================
  * Core code
  */
@@ -1674,6 +1695,19 @@
 
 		/* mb86a20s need to use the I2C gateway */
 		break;
+	case SAA7134_BOARD_MAGICPRO_PROHDTV_PRO2:
+		fe0->dvb.frontend = dvb_attach(lgs8gxx_attach,
+					       &prohdtv_pro2_lgs8g75_config,
+					       &dev->i2c_adap);
+		if (fe0->dvb.frontend != NULL) {
+			dvb_attach(tda829x_attach, fe0->dvb.frontend,
+				   &dev->i2c_adap, 0x4b,
+				   &tda829x_no_probe);
+			dvb_attach(tda18271_attach, fe0->dvb.frontend,
+				   0x60, &dev->i2c_adap,
+				   &prohdtv_pro2_tda18271_config);
+		}
+		break;
 	default:
 		wprintk("Huh? unknown DVB card?\n");
 		break;
diff -druN linux-2.6.39-libre/drivers/media/video/saa7134/saa7134.h linux-3.0-rc7-libre/drivers/media/video/saa7134/saa7134.h
--- linux-2.6.39-libre/drivers/media/video/saa7134/saa7134.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/video/saa7134/saa7134.h	2011-07-11 19:51:52.000000000 -0400
@@ -328,6 +328,9 @@
 #define SAA7134_BOARD_KWORLD_PCI_SBTVD_FULLSEG 182
 #define SAA7134_BOARD_VIDEOMATE_M1F         183
 #define SAA7134_BOARD_ENCORE_ENLTV_FM3      184
+#define SAA7134_BOARD_MAGICPRO_PROHDTV_PRO2 185
+#define SAA7134_BOARD_BEHOLD_501            186
+#define SAA7134_BOARD_BEHOLD_503FM          187
 
 #define SAA7134_MAXBOARDS 32
 #define SAA7134_INPUT_MAX 8
diff -druN linux-2.6.39-libre/drivers/media/video/saa7134/saa7134-input.c linux-3.0-rc7-libre/drivers/media/video/saa7134/saa7134-input.c
--- linux-2.6.39-libre/drivers/media/video/saa7134/saa7134-input.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/video/saa7134/saa7134-input.c	2011-07-11 19:51:52.000000000 -0400
@@ -756,6 +756,14 @@
 		mask_keycode = 0x0ff00;
 		mask_keyup   = 0x040000;
 		break;
+	case SAA7134_BOARD_HAUPPAUGE_HVR1150:
+	case SAA7134_BOARD_HAUPPAUGE_HVR1120:
+		ir_codes     = RC_MAP_HAUPPAUGE;
+		mask_keydown = 0x0040000;	/* Enable GPIO18 line on both edges */
+		mask_keyup   = 0x0040000;
+		mask_keycode = 0xffff;
+		raw_decode   = true;
+		break;
 	}
 	if (NULL == ir_codes) {
 		printk("%s: Oops: IR config error [card=%d]\n",
@@ -955,7 +963,7 @@
 	 * to work with other protocols.
 	 */
 	if (!ir->active) {
-		timeout = jiffies + jiffies_to_msecs(15);
+		timeout = jiffies + msecs_to_jiffies(15);
 		mod_timer(&ir->timer, timeout);
 		ir->active = true;
 	}
diff -druN linux-2.6.39-libre/drivers/media/video/saa7164/saa7164-core.c linux-3.0-rc7-libre/drivers/media/video/saa7164/saa7164-core.c
--- linux-2.6.39-libre/drivers/media/video/saa7164/saa7164-core.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/video/saa7164/saa7164-core.c	2011-07-11 19:51:52.000000000 -0400
@@ -1247,7 +1247,7 @@
 	}
 
 	/* print pci info */
-	pci_read_config_byte(pci_dev, PCI_CLASS_REVISION, &dev->pci_rev);
+	dev->pci_rev = pci_dev->revision;
 	pci_read_config_byte(pci_dev, PCI_LATENCY_TIMER,  &dev->pci_lat);
 	printk(KERN_INFO "%s/0: found at %s, rev: %d, irq: %d, "
 	       "latency: %d, mmio: 0x%llx\n", dev->name,
diff -druN linux-2.6.39-libre/drivers/media/video/saa7164/saa7164-encoder.c linux-3.0-rc7-libre/drivers/media/video/saa7164/saa7164-encoder.c
--- linux-2.6.39-libre/drivers/media/video/saa7164/saa7164-encoder.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/video/saa7164/saa7164-encoder.c	2011-07-11 19:51:52.000000000 -0400
@@ -177,7 +177,7 @@
 		}
 	}
 
-	/* Allocate some kenrel kernel buffers for copying
+	/* Allocate some kernel buffers for copying
 	 * to userpsace.
 	 */
 	len = params->numberoflines * params->pitch;
diff -druN linux-2.6.39-libre/drivers/media/video/saa7164/saa7164-vbi.c linux-3.0-rc7-libre/drivers/media/video/saa7164/saa7164-vbi.c
--- linux-2.6.39-libre/drivers/media/video/saa7164/saa7164-vbi.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/video/saa7164/saa7164-vbi.c	2011-07-11 19:51:52.000000000 -0400
@@ -148,7 +148,7 @@
 		}
 	}
 
-	/* Allocate some kenrel kernel buffers for copying
+	/* Allocate some kernel buffers for copying
 	 * to userpsace.
 	 */
 	len = params->numberoflines * params->pitch;
diff -druN linux-2.6.39-libre/drivers/media/video/sh_mobile_ceu_camera.c linux-3.0-rc7-libre/drivers/media/video/sh_mobile_ceu_camera.c
--- linux-2.6.39-libre/drivers/media/video/sh_mobile_ceu_camera.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/video/sh_mobile_ceu_camera.c	2011-07-11 19:51:52.000000000 -0400
@@ -17,6 +17,7 @@
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/io.h>
+#include <linux/completion.h>
 #include <linux/delay.h>
 #include <linux/dma-mapping.h>
 #include <linux/errno.h>
@@ -106,6 +107,7 @@
 	struct vb2_alloc_ctx *alloc_ctx;
 
 	struct sh_mobile_ceu_info *pdata;
+	struct completion complete;
 
 	u32 cflcr;
 
@@ -114,6 +116,7 @@
 
 	unsigned int image_mode:1;
 	unsigned int is_16bit:1;
+	unsigned int frozen:1;
 };
 
 struct sh_mobile_ceu_cam {
@@ -273,7 +276,8 @@
 	ceu_write(pcdev, CEIER, ceu_read(pcdev, CEIER) & ~CEU_CEIER_MASK);
 	status = ceu_read(pcdev, CETCR);
 	ceu_write(pcdev, CETCR, ~status & CEU_CETCR_MAGIC);
-	ceu_write(pcdev, CEIER, ceu_read(pcdev, CEIER) | CEU_CEIER_MASK);
+	if (!pcdev->frozen)
+		ceu_write(pcdev, CEIER, ceu_read(pcdev, CEIER) | CEU_CEIER_MASK);
 	ceu_write(pcdev, CAPCR, ceu_read(pcdev, CAPCR) & ~CEU_CAPCR_CTNCP);
 	ceu_write(pcdev, CETCR, CEU_CETCR_MAGIC ^ CEU_CETCR_IGRW);
 
@@ -287,6 +291,11 @@
 		ret = -EIO;
 	}
 
+	if (pcdev->frozen) {
+		complete(&pcdev->complete);
+		return ret;
+	}
+
 	if (!pcdev->active)
 		return ret;
 
@@ -378,12 +387,11 @@
 	struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
 	struct sh_mobile_ceu_dev *pcdev = ici->priv;
 	struct sh_mobile_ceu_buffer *buf = to_ceu_vb(vb);
-	unsigned long flags;
 
 	dev_dbg(icd->dev.parent, "%s (vb=0x%p) 0x%p %lu\n", __func__,
 		vb, vb2_plane_vaddr(vb, 0), vb2_get_plane_payload(vb, 0));
 
-	spin_lock_irqsave(&pcdev->lock, flags);
+	spin_lock_irq(&pcdev->lock);
 	list_add_tail(&buf->queue, &pcdev->capture);
 
 	if (!pcdev->active) {
@@ -395,7 +403,7 @@
 		pcdev->active = vb;
 		sh_mobile_ceu_capture(pcdev);
 	}
-	spin_unlock_irqrestore(&pcdev->lock, flags);
+	spin_unlock_irq(&pcdev->lock);
 }
 
 static void sh_mobile_ceu_videobuf_release(struct vb2_buffer *vb)
@@ -404,9 +412,8 @@
 	struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
 	struct sh_mobile_ceu_buffer *buf = to_ceu_vb(vb);
 	struct sh_mobile_ceu_dev *pcdev = ici->priv;
-	unsigned long flags;
 
-	spin_lock_irqsave(&pcdev->lock, flags);
+	spin_lock_irq(&pcdev->lock);
 
 	if (pcdev->active == vb) {
 		/* disable capture (release DMA buffer), reset */
@@ -417,7 +424,7 @@
 	/* Doesn't hurt also if the list is empty */
 	list_del_init(&buf->queue);
 
-	spin_unlock_irqrestore(&pcdev->lock, flags);
+	spin_unlock_irq(&pcdev->lock);
 }
 
 static int sh_mobile_ceu_videobuf_init(struct vb2_buffer *vb)
@@ -427,6 +434,25 @@
 	return 0;
 }
 
+static int sh_mobile_ceu_stop_streaming(struct vb2_queue *q)
+{
+	struct soc_camera_device *icd = container_of(q, struct soc_camera_device, vb2_vidq);
+	struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
+	struct sh_mobile_ceu_dev *pcdev = ici->priv;
+	struct list_head *buf_head, *tmp;
+
+	spin_lock_irq(&pcdev->lock);
+
+	pcdev->active = NULL;
+
+	list_for_each_safe(buf_head, tmp, &pcdev->capture)
+		list_del_init(buf_head);
+
+	spin_unlock_irq(&pcdev->lock);
+
+	return sh_mobile_ceu_soft_reset(pcdev);
+}
+
 static struct vb2_ops sh_mobile_ceu_videobuf_ops = {
 	.queue_setup	= sh_mobile_ceu_videobuf_setup,
 	.buf_prepare	= sh_mobile_ceu_videobuf_prepare,
@@ -435,6 +461,7 @@
 	.buf_init	= sh_mobile_ceu_videobuf_init,
 	.wait_prepare	= soc_camera_unlock,
 	.wait_finish	= soc_camera_lock,
+	.stop_streaming	= sh_mobile_ceu_stop_streaming,
 };
 
 static irqreturn_t sh_mobile_ceu_irq(int irq, void *data)
@@ -500,7 +527,6 @@
 {
 	struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
 	struct sh_mobile_ceu_dev *pcdev = ici->priv;
-	unsigned long flags;
 
 	BUG_ON(icd != pcdev->icd);
 
@@ -509,13 +535,13 @@
 	sh_mobile_ceu_soft_reset(pcdev);
 
 	/* make sure active buffer is canceled */
-	spin_lock_irqsave(&pcdev->lock, flags);
+	spin_lock_irq(&pcdev->lock);
 	if (pcdev->active) {
 		list_del_init(&to_ceu_vb(pcdev->active)->queue);
 		vb2_buffer_done(pcdev->active, VB2_BUF_STATE_ERROR);
 		pcdev->active = NULL;
 	}
-	spin_unlock_irqrestore(&pcdev->lock, flags);
+	spin_unlock_irq(&pcdev->lock);
 
 	pm_runtime_put_sync(ici->v4l2_dev.dev);
 
@@ -891,8 +917,8 @@
 
 	fmt = soc_mbus_get_fmtdesc(code);
 	if (!fmt) {
-		dev_err(dev, "Invalid format code #%u: %d\n", idx, code);
-		return -EINVAL;
+		dev_warn(dev, "unsupported format code #%u: %d\n", idx, code);
+		return 0;
 	}
 
 	if (!pcdev->pdata->csi2_dev) {
@@ -1330,7 +1356,7 @@
 /*
  * CEU can scale and crop, but we don't want to waste bandwidth and kill the
  * framerate by always requesting the maximum image from the client. See
- * Documentation/video4linux/sh_mobile_camera_ceu.txt for a description of
+ * Documentation/video4linux/sh_mobile_ceu_camera.txt for a description of
  * scaling and cropping algorithms and for the meaning of referenced here steps.
  */
 static int sh_mobile_ceu_set_crop(struct soc_camera_device *icd,
@@ -1377,10 +1403,6 @@
 	if (mf.width > 2560 || mf.height > 1920)
 		return -EINVAL;
 
-	/* Cache camera output window */
-	cam->width	= mf.width;
-	cam->height	= mf.height;
-
 	/* 4. Calculate camera scales */
 	scale_cam_h	= calc_generic_scale(cam_rect->width, mf.width);
 	scale_cam_v	= calc_generic_scale(cam_rect->height, mf.height);
@@ -1389,6 +1411,39 @@
 	interm_width	= scale_down(rect->width, scale_cam_h);
 	interm_height	= scale_down(rect->height, scale_cam_v);
 
+	if (interm_width < icd->user_width) {
+		u32 new_scale_h;
+
+		new_scale_h = calc_generic_scale(rect->width, icd->user_width);
+
+		mf.width = scale_down(cam_rect->width, new_scale_h);
+	}
+
+	if (interm_height < icd->user_height) {
+		u32 new_scale_v;
+
+		new_scale_v = calc_generic_scale(rect->height, icd->user_height);
+
+		mf.height = scale_down(cam_rect->height, new_scale_v);
+	}
+
+	if (interm_width < icd->user_width || interm_height < icd->user_height) {
+		ret = v4l2_device_call_until_err(sd->v4l2_dev, (int)icd, video,
+						 s_mbus_fmt, &mf);
+		if (ret < 0)
+			return ret;
+
+		dev_geo(dev, "New camera output %ux%u\n", mf.width, mf.height);
+		scale_cam_h	= calc_generic_scale(cam_rect->width, mf.width);
+		scale_cam_v	= calc_generic_scale(cam_rect->height, mf.height);
+		interm_width	= scale_down(rect->width, scale_cam_h);
+		interm_height	= scale_down(rect->height, scale_cam_v);
+	}
+
+	/* Cache camera output window */
+	cam->width	= mf.width;
+	cam->height	= mf.height;
+
 	if (pcdev->image_mode) {
 		out_width	= min(interm_width, icd->user_width);
 		out_height	= min(interm_height, icd->user_height);
@@ -1704,6 +1759,63 @@
 	return ret;
 }
 
+static int sh_mobile_ceu_set_livecrop(struct soc_camera_device *icd,
+				      struct v4l2_crop *a)
+{
+	struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
+	struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
+	struct sh_mobile_ceu_dev *pcdev = ici->priv;
+	u32 out_width = icd->user_width, out_height = icd->user_height;
+	int ret;
+
+	/* Freeze queue */
+	pcdev->frozen = 1;
+	/* Wait for frame */
+	ret = wait_for_completion_interruptible(&pcdev->complete);
+	/* Stop the client */
+	ret = v4l2_subdev_call(sd, video, s_stream, 0);
+	if (ret < 0)
+		dev_warn(icd->dev.parent,
+			 "Client failed to stop the stream: %d\n", ret);
+	else
+		/* Do the crop, if it fails, there's nothing more we can do */
+		sh_mobile_ceu_set_crop(icd, a);
+
+	dev_geo(icd->dev.parent, "Output after crop: %ux%u\n", icd->user_width, icd->user_height);
+
+	if (icd->user_width != out_width || icd->user_height != out_height) {
+		struct v4l2_format f = {
+			.type	= V4L2_BUF_TYPE_VIDEO_CAPTURE,
+			.fmt.pix	= {
+				.width		= out_width,
+				.height		= out_height,
+				.pixelformat	= icd->current_fmt->host_fmt->fourcc,
+				.field		= pcdev->field,
+				.colorspace	= icd->colorspace,
+			},
+		};
+		ret = sh_mobile_ceu_set_fmt(icd, &f);
+		if (!ret && (out_width != f.fmt.pix.width ||
+			     out_height != f.fmt.pix.height))
+			ret = -EINVAL;
+		if (!ret) {
+			icd->user_width		= out_width;
+			icd->user_height	= out_height;
+			ret = sh_mobile_ceu_set_bus_param(icd,
+					icd->current_fmt->host_fmt->fourcc);
+		}
+	}
+
+	/* Thaw the queue */
+	pcdev->frozen = 0;
+	spin_lock_irq(&pcdev->lock);
+	sh_mobile_ceu_capture(pcdev);
+	spin_unlock_irq(&pcdev->lock);
+	/* Start the client */
+	ret = v4l2_subdev_call(sd, video, s_stream, 1);
+	return ret;
+}
+
 static unsigned int sh_mobile_ceu_poll(struct file *file, poll_table *pt)
 {
 	struct soc_camera_device *icd = file->private_data;
@@ -1790,6 +1902,7 @@
 	.put_formats	= sh_mobile_ceu_put_formats,
 	.get_crop	= sh_mobile_ceu_get_crop,
 	.set_crop	= sh_mobile_ceu_set_crop,
+	.set_livecrop	= sh_mobile_ceu_set_livecrop,
 	.set_fmt	= sh_mobile_ceu_set_fmt,
 	.try_fmt	= sh_mobile_ceu_try_fmt,
 	.set_ctrl	= sh_mobile_ceu_set_ctrl,
@@ -1856,6 +1969,7 @@
 
 	INIT_LIST_HEAD(&pcdev->capture);
 	spin_lock_init(&pcdev->lock);
+	init_completion(&pcdev->complete);
 
 	pcdev->pdata = pdev->dev.platform_data;
 	if (!pcdev->pdata) {
diff -druN linux-2.6.39-libre/drivers/media/video/soc_camera.c linux-3.0-rc7-libre/drivers/media/video/soc_camera.c
--- linux-2.6.39-libre/drivers/media/video/soc_camera.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/video/soc_camera.c	2011-07-11 19:51:52.000000000 -0400
@@ -41,6 +41,11 @@
 #define DEFAULT_WIDTH	640
 #define DEFAULT_HEIGHT	480
 
+#define is_streaming(ici, icd)				\
+	(((ici)->ops->init_videobuf) ?			\
+	 (icd)->vb_vidq.streaming :			\
+	 vb2_is_streaming(&(icd)->vb2_vidq))
+
 static LIST_HEAD(hosts);
 static LIST_HEAD(devices);
 static DEFINE_MUTEX(list_lock);		/* Protects the list of hosts */
@@ -358,8 +363,6 @@
 	if (!icd->user_formats)
 		return -ENOMEM;
 
-	icd->num_user_formats = fmts;
-
 	dev_dbg(&icd->dev, "Found %d supported formats.\n", fmts);
 
 	/* Second pass - actually fill data formats */
@@ -367,9 +370,10 @@
 	for (i = 0; i < raw_fmts; i++)
 		if (!ici->ops->get_formats) {
 			v4l2_subdev_call(sd, video, enum_mbus_fmt, i, &code);
-			icd->user_formats[i].host_fmt =
+			icd->user_formats[fmts].host_fmt =
 				soc_mbus_get_fmtdesc(code);
-			icd->user_formats[i].code = code;
+			if (icd->user_formats[fmts].host_fmt)
+				icd->user_formats[fmts++].code = code;
 		} else {
 			ret = ici->ops->get_formats(icd, i,
 						    &icd->user_formats[fmts]);
@@ -378,12 +382,12 @@
 			fmts += ret;
 		}
 
+	icd->num_user_formats = fmts;
 	icd->current_fmt = &icd->user_formats[0];
 
 	return 0;
 
 egfmt:
-	icd->num_user_formats = 0;
 	vfree(icd->user_formats);
 	return ret;
 }
@@ -662,7 +666,7 @@
 	if (icd->streamer && icd->streamer != file)
 		return -EBUSY;
 
-	if (icd->vb_vidq.bufs[0]) {
+	if (is_streaming(to_soc_camera_host(icd->dev.parent), icd)) {
 		dev_err(&icd->dev, "S_FMT denied: queue initialised\n");
 		return -EBUSY;
 	}
@@ -903,14 +907,17 @@
 	if (ret < 0) {
 		dev_err(&icd->dev,
 			"S_CROP denied: getting current crop failed\n");
-	} else if (icd->vb_vidq.bufs[0] &&
-		   (a->c.width != current_crop.c.width ||
-		    a->c.height != current_crop.c.height)) {
+	} else if ((a->c.width == current_crop.c.width &&
+		    a->c.height == current_crop.c.height) ||
+		   !is_streaming(ici, icd)) {
+		/* same size or not streaming - use .set_crop() */
+		ret = ici->ops->set_crop(icd, a);
+	} else if (ici->ops->set_livecrop) {
+		ret = ici->ops->set_livecrop(icd, a);
+	} else {
 		dev_err(&icd->dev,
 			"S_CROP denied: queue initialised and sizes differ\n");
 		ret = -EBUSY;
-	} else {
-		ret = ici->ops->set_crop(icd, a);
 	}
 
 	return ret;
@@ -1505,7 +1512,7 @@
  */
 static int soc_camera_video_start(struct soc_camera_device *icd)
 {
-	struct device_type *type = icd->vdev->dev.type;
+	const struct device_type *type = icd->vdev->dev.type;
 	int ret;
 
 	if (!icd->dev.parent)
diff -druN linux-2.6.39-libre/drivers/media/video/soc_mediabus.c linux-3.0-rc7-libre/drivers/media/video/soc_mediabus.c
--- linux-2.6.39-libre/drivers/media/video/soc_mediabus.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/video/soc_mediabus.c	2011-07-11 19:51:52.000000000 -0400
@@ -15,132 +15,329 @@
 #include <media/v4l2-mediabus.h>
 #include <media/soc_mediabus.h>
 
-#define MBUS_IDX(f) (V4L2_MBUS_FMT_ ## f - V4L2_MBUS_FMT_FIXED - 1)
-
-static const struct soc_mbus_pixelfmt mbus_fmt[] = {
-	[MBUS_IDX(YUYV8_2X8)] = {
+static const struct soc_mbus_lookup mbus_fmt[] = {
+{
+	.code = V4L2_MBUS_FMT_YUYV8_2X8,
+	.fmt = {
 		.fourcc			= V4L2_PIX_FMT_YUYV,
 		.name			= "YUYV",
 		.bits_per_sample	= 8,
 		.packing		= SOC_MBUS_PACKING_2X8_PADHI,
 		.order			= SOC_MBUS_ORDER_LE,
 	},
-	[MBUS_IDX(YVYU8_2X8)] = {
+}, {
+	.code = V4L2_MBUS_FMT_YVYU8_2X8,
+	.fmt = {
 		.fourcc			= V4L2_PIX_FMT_YVYU,
 		.name			= "YVYU",
 		.bits_per_sample	= 8,
 		.packing		= SOC_MBUS_PACKING_2X8_PADHI,
 		.order			= SOC_MBUS_ORDER_LE,
 	},
-	[MBUS_IDX(UYVY8_2X8)] = {
+}, {
+	.code = V4L2_MBUS_FMT_UYVY8_2X8,
+	.fmt = {
 		.fourcc			= V4L2_PIX_FMT_UYVY,
 		.name			= "UYVY",
 		.bits_per_sample	= 8,
 		.packing		= SOC_MBUS_PACKING_2X8_PADHI,
 		.order			= SOC_MBUS_ORDER_LE,
 	},
-	[MBUS_IDX(VYUY8_2X8)] = {
+}, {
+	.code = V4L2_MBUS_FMT_VYUY8_2X8,
+	.fmt = {
 		.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)] = {
+}, {
+	.code = V4L2_MBUS_FMT_RGB555_2X8_PADHI_LE,
+	.fmt = {
 		.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)] = {
+}, {
+	.code = V4L2_MBUS_FMT_RGB555_2X8_PADHI_BE,
+	.fmt = {
 		.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)] = {
+}, {
+	.code = V4L2_MBUS_FMT_RGB565_2X8_LE,
+	.fmt = {
 		.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)] = {
+}, {
+	.code = V4L2_MBUS_FMT_RGB565_2X8_BE,
+	.fmt = {
 		.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)] = {
+}, {
+	.code = V4L2_MBUS_FMT_SBGGR8_1X8,
+	.fmt = {
 		.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)] = {
+}, {
+	.code = V4L2_MBUS_FMT_SBGGR10_1X10,
+	.fmt = {
 		.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(Y8_1X8)] = {
+}, {
+	.code = V4L2_MBUS_FMT_Y8_1X8,
+	.fmt = {
 		.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)] = {
+}, {
+	.code = V4L2_MBUS_FMT_Y10_1X10,
+	.fmt = {
 		.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)] = {
+}, {
+	.code = V4L2_MBUS_FMT_SBGGR10_2X8_PADHI_LE,
+	.fmt = {
 		.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)] = {
+}, {
+	.code = V4L2_MBUS_FMT_SBGGR10_2X8_PADLO_LE,
+	.fmt = {
 		.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)] = {
+}, {
+	.code = V4L2_MBUS_FMT_SBGGR10_2X8_PADHI_BE,
+	.fmt = {
 		.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)] = {
+}, {
+	.code = V4L2_MBUS_FMT_SBGGR10_2X8_PADLO_BE,
+	.fmt = {
 		.fourcc			= V4L2_PIX_FMT_SBGGR10,
 		.name			= "Bayer 10 BGGR",
 		.bits_per_sample	= 8,
 		.packing		= SOC_MBUS_PACKING_2X8_PADLO,
 		.order			= SOC_MBUS_ORDER_BE,
 	},
+}, {
+	.code = V4L2_MBUS_FMT_JPEG_1X8,
+	.fmt = {
+		.fourcc                 = V4L2_PIX_FMT_JPEG,
+		.name                   = "JPEG",
+		.bits_per_sample        = 8,
+		.packing                = SOC_MBUS_PACKING_VARIABLE,
+		.order                  = SOC_MBUS_ORDER_LE,
+	},
+}, {
+	.code = V4L2_MBUS_FMT_RGB444_2X8_PADHI_BE,
+	.fmt = {
+		.fourcc			= V4L2_PIX_FMT_RGB444,
+		.name			= "RGB444",
+		.bits_per_sample	= 8,
+		.packing		= SOC_MBUS_PACKING_2X8_PADHI,
+		.order			= SOC_MBUS_ORDER_BE,
+	},
+}, {
+	.code = V4L2_MBUS_FMT_YUYV8_1_5X8,
+	.fmt = {
+		.fourcc			= V4L2_PIX_FMT_YUV420,
+		.name			= "YUYV 4:2:0",
+		.bits_per_sample	= 8,
+		.packing		= SOC_MBUS_PACKING_1_5X8,
+		.order			= SOC_MBUS_ORDER_LE,
+	},
+}, {
+	.code = V4L2_MBUS_FMT_YVYU8_1_5X8,
+	.fmt = {
+		.fourcc			= V4L2_PIX_FMT_YVU420,
+		.name			= "YVYU 4:2:0",
+		.bits_per_sample	= 8,
+		.packing		= SOC_MBUS_PACKING_1_5X8,
+		.order			= SOC_MBUS_ORDER_LE,
+	},
+}, {
+	.code = V4L2_MBUS_FMT_UYVY8_1X16,
+	.fmt = {
+		.fourcc			= V4L2_PIX_FMT_UYVY,
+		.name			= "UYVY 16bit",
+		.bits_per_sample	= 16,
+		.packing		= SOC_MBUS_PACKING_EXTEND16,
+		.order			= SOC_MBUS_ORDER_LE,
+	},
+}, {
+	.code = V4L2_MBUS_FMT_VYUY8_1X16,
+	.fmt = {
+		.fourcc			= V4L2_PIX_FMT_VYUY,
+		.name			= "VYUY 16bit",
+		.bits_per_sample	= 16,
+		.packing		= SOC_MBUS_PACKING_EXTEND16,
+		.order			= SOC_MBUS_ORDER_LE,
+	},
+}, {
+	.code = V4L2_MBUS_FMT_YUYV8_1X16,
+	.fmt = {
+		.fourcc			= V4L2_PIX_FMT_YUYV,
+		.name			= "YUYV 16bit",
+		.bits_per_sample	= 16,
+		.packing		= SOC_MBUS_PACKING_EXTEND16,
+		.order			= SOC_MBUS_ORDER_LE,
+	},
+}, {
+	.code = V4L2_MBUS_FMT_YVYU8_1X16,
+	.fmt = {
+		.fourcc			= V4L2_PIX_FMT_YVYU,
+		.name			= "YVYU 16bit",
+		.bits_per_sample	= 16,
+		.packing		= SOC_MBUS_PACKING_EXTEND16,
+		.order			= SOC_MBUS_ORDER_LE,
+	},
+}, {
+	.code = V4L2_MBUS_FMT_SGRBG8_1X8,
+	.fmt = {
+		.fourcc			= V4L2_PIX_FMT_SGRBG8,
+		.name			= "Bayer 8 GRBG",
+		.bits_per_sample	= 8,
+		.packing		= SOC_MBUS_PACKING_NONE,
+		.order			= SOC_MBUS_ORDER_LE,
+	},
+}, {
+	.code = V4L2_MBUS_FMT_SGRBG10_DPCM8_1X8,
+	.fmt = {
+		.fourcc			= V4L2_PIX_FMT_SGRBG10DPCM8,
+		.name			= "Bayer 10 BGGR DPCM 8",
+		.bits_per_sample	= 8,
+		.packing		= SOC_MBUS_PACKING_NONE,
+		.order			= SOC_MBUS_ORDER_LE,
+	},
+}, {
+	.code = V4L2_MBUS_FMT_SGBRG10_1X10,
+	.fmt = {
+		.fourcc			= V4L2_PIX_FMT_SGBRG10,
+		.name			= "Bayer 10 GBRG",
+		.bits_per_sample	= 10,
+		.packing		= SOC_MBUS_PACKING_EXTEND16,
+		.order			= SOC_MBUS_ORDER_LE,
+	},
+}, {
+	.code = V4L2_MBUS_FMT_SGRBG10_1X10,
+	.fmt = {
+		.fourcc			= V4L2_PIX_FMT_SGRBG10,
+		.name			= "Bayer 10 GRBG",
+		.bits_per_sample	= 10,
+		.packing		= SOC_MBUS_PACKING_EXTEND16,
+		.order			= SOC_MBUS_ORDER_LE,
+	},
+}, {
+	.code = V4L2_MBUS_FMT_SRGGB10_1X10,
+	.fmt = {
+		.fourcc			= V4L2_PIX_FMT_SRGGB10,
+		.name			= "Bayer 10 RGGB",
+		.bits_per_sample	= 10,
+		.packing		= SOC_MBUS_PACKING_EXTEND16,
+		.order			= SOC_MBUS_ORDER_LE,
+	},
+}, {
+	.code = V4L2_MBUS_FMT_SBGGR12_1X12,
+	.fmt = {
+		.fourcc			= V4L2_PIX_FMT_SBGGR12,
+		.name			= "Bayer 12 BGGR",
+		.bits_per_sample	= 12,
+		.packing		= SOC_MBUS_PACKING_EXTEND16,
+		.order			= SOC_MBUS_ORDER_LE,
+	},
+}, {
+	.code = V4L2_MBUS_FMT_SGBRG12_1X12,
+	.fmt = {
+		.fourcc			= V4L2_PIX_FMT_SGBRG12,
+		.name			= "Bayer 12 GBRG",
+		.bits_per_sample	= 12,
+		.packing		= SOC_MBUS_PACKING_EXTEND16,
+		.order			= SOC_MBUS_ORDER_LE,
+	},
+}, {
+	.code = V4L2_MBUS_FMT_SGRBG12_1X12,
+	.fmt = {
+		.fourcc			= V4L2_PIX_FMT_SGRBG12,
+		.name			= "Bayer 12 GRBG",
+		.bits_per_sample	= 12,
+		.packing		= SOC_MBUS_PACKING_EXTEND16,
+		.order			= SOC_MBUS_ORDER_LE,
+	},
+}, {
+	.code = V4L2_MBUS_FMT_SRGGB12_1X12,
+	.fmt = {
+		.fourcc			= V4L2_PIX_FMT_SRGGB12,
+		.name			= "Bayer 12 RGGB",
+		.bits_per_sample	= 12,
+		.packing		= SOC_MBUS_PACKING_EXTEND16,
+		.order			= SOC_MBUS_ORDER_LE,
+	},
+},
 };
 
-int soc_mbus_samples_per_pixel(const struct soc_mbus_pixelfmt *mf)
+int soc_mbus_samples_per_pixel(const struct soc_mbus_pixelfmt *mf,
+			unsigned int *numerator, unsigned int *denominator)
 {
 	switch (mf->packing) {
 	case SOC_MBUS_PACKING_NONE:
 	case SOC_MBUS_PACKING_EXTEND16:
-		return 1;
+		*numerator = 1;
+		*denominator = 1;
+		return 0;
 	case SOC_MBUS_PACKING_2X8_PADHI:
 	case SOC_MBUS_PACKING_2X8_PADLO:
-		return 2;
+		*numerator = 2;
+		*denominator = 1;
+		return 0;
+	case SOC_MBUS_PACKING_1_5X8:
+		*numerator = 3;
+		*denominator = 2;
+		return 0;
+	case SOC_MBUS_PACKING_VARIABLE:
+		*numerator = 0;
+		*denominator = 1;
+		return 0;
 	}
 	return -EINVAL;
 }
@@ -155,18 +352,34 @@
 	case SOC_MBUS_PACKING_2X8_PADLO:
 	case SOC_MBUS_PACKING_EXTEND16:
 		return width * 2;
+	case SOC_MBUS_PACKING_1_5X8:
+		return width * 3 / 2;
+	case SOC_MBUS_PACKING_VARIABLE:
+		return 0;
 	}
 	return -EINVAL;
 }
 EXPORT_SYMBOL(soc_mbus_bytes_per_line);
 
+const struct soc_mbus_pixelfmt *soc_mbus_find_fmtdesc(
+	enum v4l2_mbus_pixelcode code,
+	const struct soc_mbus_lookup *lookup,
+	int n)
+{
+	int i;
+
+	for (i = 0; i < n; i++)
+		if (lookup[i].code == code)
+			return &lookup[i].fmt;
+
+	return NULL;
+}
+EXPORT_SYMBOL(soc_mbus_find_fmtdesc);
+
 const struct soc_mbus_pixelfmt *soc_mbus_get_fmtdesc(
 	enum v4l2_mbus_pixelcode code)
 {
-	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;
+	return soc_mbus_find_fmtdesc(code, mbus_fmt, ARRAY_SIZE(mbus_fmt));
 }
 EXPORT_SYMBOL(soc_mbus_get_fmtdesc);
 
diff -druN linux-2.6.39-libre/drivers/media/video/timblogiw.c linux-3.0-rc7-libre/drivers/media/video/timblogiw.c
--- linux-2.6.39-libre/drivers/media/video/timblogiw.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/video/timblogiw.c	2011-07-11 19:51:52.000000000 -0400
@@ -24,7 +24,6 @@
 #include <linux/platform_device.h>
 #include <linux/slab.h>
 #include <linux/dmaengine.h>
-#include <linux/mfd/core.h>
 #include <linux/scatterlist.h>
 #include <linux/interrupt.h>
 #include <linux/list.h>
@@ -791,7 +790,7 @@
 {
 	int err;
 	struct timblogiw *lw = NULL;
-	struct timb_video_platform_data *pdata = mfd_get_data(pdev);
+	struct timb_video_platform_data *pdata = pdev->dev.platform_data;
 
 	if (!pdata) {
 		dev_err(&pdev->dev, "No platform data\n");
diff -druN linux-2.6.39-libre/drivers/media/video/tuner-core.c linux-3.0-rc7-libre/drivers/media/video/tuner-core.c
--- linux-2.6.39-libre/drivers/media/video/tuner-core.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/video/tuner-core.c	2011-07-11 19:51:52.000000000 -0400
@@ -724,19 +724,15 @@
 }
 
 /**
- * set_mode_freq - Switch tuner to other mode.
- * @client:	struct i2c_client pointer
+ * set_mode - Switch tuner to other mode.
  * @t:		a pointer to the module's internal struct_tuner
  * @mode:	enum v4l2_type (radio or TV)
- * @freq:	frequency to set (0 means to use the previous one)
  *
  * If tuner doesn't support the needed mode (radio or TV), prints a
  * debug message and returns -EINVAL, changing its state to standby.
- * Otherwise, changes the state and sets frequency to the last value, if
- * the tuner can sleep or if it supports both Radio and TV.
+ * Otherwise, changes the mode and returns 0.
  */
-static int set_mode_freq(struct i2c_client *client, struct tuner *t,
-			 enum v4l2_tuner_type mode, unsigned int freq)
+static int set_mode(struct tuner *t, enum v4l2_tuner_type mode)
 {
 	struct analog_demod_ops *analog_ops = &t->fe.ops.analog_ops;
 
@@ -752,17 +748,27 @@
 		t->mode = mode;
 		tuner_dbg("Changing to mode %d\n", mode);
 	}
+	return 0;
+}
+
+/**
+ * set_freq - Set the tuner to the desired frequency.
+ * @t:		a pointer to the module's internal struct_tuner
+ * @freq:	frequency to set (0 means to use the current frequency)
+ */
+static void set_freq(struct tuner *t, unsigned int freq)
+{
+	struct i2c_client *client = v4l2_get_subdevdata(&t->sd);
+
 	if (t->mode == V4L2_TUNER_RADIO) {
-		if (freq)
-			t->radio_freq = freq;
-		set_radio_freq(client, t->radio_freq);
+		if (!freq)
+			freq = t->radio_freq;
+		set_radio_freq(client, freq);
 	} else {
-		if (freq)
-			t->tv_freq = freq;
-		set_tv_freq(client, t->tv_freq);
+		if (!freq)
+			freq = t->tv_freq;
+		set_tv_freq(client, freq);
 	}
-
-	return 0;
 }
 
 /*
@@ -817,7 +823,8 @@
 /**
  * tuner_fixup_std - force a given video standard variant
  *
- * @t:	tuner internal struct
+ * @t: tuner internal struct
+ * @std:	TV standard
  *
  * A few devices or drivers have problem to detect some standard variations.
  * On other operational systems, the drivers generally have a per-country
@@ -827,57 +834,39 @@
  * to distinguish all video standard variations, a modprobe parameter can
  * be used to force a video standard match.
  */
-static int tuner_fixup_std(struct tuner *t)
+static v4l2_std_id tuner_fixup_std(struct tuner *t, v4l2_std_id std)
 {
-	if ((t->std & V4L2_STD_PAL) == V4L2_STD_PAL) {
+	if (pal[0] != '-' && (std & V4L2_STD_PAL) == V4L2_STD_PAL) {
 		switch (pal[0]) {
 		case '6':
-			tuner_dbg("insmod fixup: PAL => PAL-60\n");
-			t->std = V4L2_STD_PAL_60;
-			break;
+			return V4L2_STD_PAL_60;
 		case 'b':
 		case 'B':
 		case 'g':
 		case 'G':
-			tuner_dbg("insmod fixup: PAL => PAL-BG\n");
-			t->std = V4L2_STD_PAL_BG;
-			break;
+			return V4L2_STD_PAL_BG;
 		case 'i':
 		case 'I':
-			tuner_dbg("insmod fixup: PAL => PAL-I\n");
-			t->std = V4L2_STD_PAL_I;
-			break;
+			return V4L2_STD_PAL_I;
 		case 'd':
 		case 'D':
 		case 'k':
 		case 'K':
-			tuner_dbg("insmod fixup: PAL => PAL-DK\n");
-			t->std = V4L2_STD_PAL_DK;
-			break;
+			return V4L2_STD_PAL_DK;
 		case 'M':
 		case 'm':
-			tuner_dbg("insmod fixup: PAL => PAL-M\n");
-			t->std = V4L2_STD_PAL_M;
-			break;
+			return V4L2_STD_PAL_M;
 		case 'N':
 		case 'n':
-			if (pal[1] == 'c' || pal[1] == 'C') {
-				tuner_dbg("insmod fixup: PAL => PAL-Nc\n");
-				t->std = V4L2_STD_PAL_Nc;
-			} else {
-				tuner_dbg("insmod fixup: PAL => PAL-N\n");
-				t->std = V4L2_STD_PAL_N;
-			}
-			break;
-		case '-':
-			/* default parameter, do nothing */
-			break;
+			if (pal[1] == 'c' || pal[1] == 'C')
+				return V4L2_STD_PAL_Nc;
+			return V4L2_STD_PAL_N;
 		default:
 			tuner_warn("pal= argument not recognised\n");
 			break;
 		}
 	}
-	if ((t->std & V4L2_STD_SECAM) == V4L2_STD_SECAM) {
+	if (secam[0] != '-' && (std & V4L2_STD_SECAM) == V4L2_STD_SECAM) {
 		switch (secam[0]) {
 		case 'b':
 		case 'B':
@@ -885,63 +874,42 @@
 		case 'G':
 		case 'h':
 		case 'H':
-			tuner_dbg("insmod fixup: SECAM => SECAM-BGH\n");
-			t->std = V4L2_STD_SECAM_B |
-				 V4L2_STD_SECAM_G |
-				 V4L2_STD_SECAM_H;
-			break;
+			return V4L2_STD_SECAM_B |
+			       V4L2_STD_SECAM_G |
+			       V4L2_STD_SECAM_H;
 		case 'd':
 		case 'D':
 		case 'k':
 		case 'K':
-			tuner_dbg("insmod fixup: SECAM => SECAM-DK\n");
-			t->std = V4L2_STD_SECAM_DK;
-			break;
+			return V4L2_STD_SECAM_DK;
 		case 'l':
 		case 'L':
-			if ((secam[1] == 'C') || (secam[1] == 'c')) {
-				tuner_dbg("insmod fixup: SECAM => SECAM-L'\n");
-				t->std = V4L2_STD_SECAM_LC;
-			} else {
-				tuner_dbg("insmod fixup: SECAM => SECAM-L\n");
-				t->std = V4L2_STD_SECAM_L;
-			}
-			break;
-		case '-':
-			/* default parameter, do nothing */
-			break;
+			if ((secam[1] == 'C') || (secam[1] == 'c'))
+				return V4L2_STD_SECAM_LC;
+			return V4L2_STD_SECAM_L;
 		default:
 			tuner_warn("secam= argument not recognised\n");
 			break;
 		}
 	}
 
-	if ((t->std & V4L2_STD_NTSC) == V4L2_STD_NTSC) {
+	if (ntsc[0] != '-' && (std & V4L2_STD_NTSC) == V4L2_STD_NTSC) {
 		switch (ntsc[0]) {
 		case 'm':
 		case 'M':
-			tuner_dbg("insmod fixup: NTSC => NTSC-M\n");
-			t->std = V4L2_STD_NTSC_M;
-			break;
+			return V4L2_STD_NTSC_M;
 		case 'j':
 		case 'J':
-			tuner_dbg("insmod fixup: NTSC => NTSC_M_JP\n");
-			t->std = V4L2_STD_NTSC_M_JP;
-			break;
+			return V4L2_STD_NTSC_M_JP;
 		case 'k':
 		case 'K':
-			tuner_dbg("insmod fixup: NTSC => NTSC_M_KR\n");
-			t->std = V4L2_STD_NTSC_M_KR;
-			break;
-		case '-':
-			/* default parameter, do nothing */
-			break;
+			return V4L2_STD_NTSC_M_KR;
 		default:
 			tuner_info("ntsc= argument not recognised\n");
 			break;
 		}
 	}
-	return 0;
+	return std;
 }
 
 /*
@@ -1058,10 +1026,9 @@
 static int tuner_s_radio(struct v4l2_subdev *sd)
 {
 	struct tuner *t = to_tuner(sd);
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
 
-	if (set_mode_freq(client, t, V4L2_TUNER_RADIO, 0) == -EINVAL)
-		return 0;
+	if (set_mode(t, V4L2_TUNER_RADIO) == 0)
+		set_freq(t, 0);
 	return 0;
 }
 
@@ -1072,16 +1039,20 @@
 /**
  * tuner_s_power - controls the power state of the tuner
  * @sd: pointer to struct v4l2_subdev
- * @on: a zero value puts the tuner to sleep
+ * @on: a zero value puts the tuner to sleep, non-zero wakes it up
  */
 static int tuner_s_power(struct v4l2_subdev *sd, int on)
 {
 	struct tuner *t = to_tuner(sd);
 	struct analog_demod_ops *analog_ops = &t->fe.ops.analog_ops;
 
-	/* FIXME: Why this function don't wake the tuner if on != 0 ? */
-	if (on)
+	if (on) {
+		if (t->standby && set_mode(t, t->mode) == 0) {
+			tuner_dbg("Waking up tuner\n");
+			set_freq(t, 0);
+		}
 		return 0;
+	}
 
 	tuner_dbg("Putting tuner to sleep\n");
 	t->standby = true;
@@ -1093,28 +1064,36 @@
 static int tuner_s_std(struct v4l2_subdev *sd, v4l2_std_id std)
 {
 	struct tuner *t = to_tuner(sd);
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
 
-	if (set_mode_freq(client, t, V4L2_TUNER_ANALOG_TV, 0) == -EINVAL)
+	if (set_mode(t, V4L2_TUNER_ANALOG_TV))
 		return 0;
 
-	t->std = std;
-	tuner_fixup_std(t);
-
+	t->std = tuner_fixup_std(t, std);
+	if (t->std != std)
+		tuner_dbg("Fixup standard %llx to %llx\n", std, t->std);
+	set_freq(t, 0);
 	return 0;
 }
 
 static int tuner_s_frequency(struct v4l2_subdev *sd, struct v4l2_frequency *f)
 {
 	struct tuner *t = to_tuner(sd);
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
-
-	if (set_mode_freq(client, t, f->type, f->frequency) == -EINVAL)
-		return 0;
 
+	if (set_mode(t, f->type) == 0)
+		set_freq(t, f->frequency);
 	return 0;
 }
 
+/**
+ * tuner_g_frequency - Get the tuned frequency for the tuner
+ * @sd: pointer to struct v4l2_subdev
+ * @f: pointer to struct v4l2_frequency
+ *
+ * At return, the structure f will be filled with tuner frequency
+ * if the tuner matches the f->type.
+ * Note: f->type should be initialized before calling it.
+ * This is done by either video_ioctl2 or by the bridge driver.
+ */
 static int tuner_g_frequency(struct v4l2_subdev *sd, struct v4l2_frequency *f)
 {
 	struct tuner *t = to_tuner(sd);
@@ -1122,8 +1101,7 @@
 
 	if (check_mode(t, f->type) == -EINVAL)
 		return 0;
-	f->type = t->mode;
-	if (fe_tuner_ops->get_frequency && !t->standby) {
+	if (f->type == t->mode && fe_tuner_ops->get_frequency && !t->standby) {
 		u32 abs_freq;
 
 		fe_tuner_ops->get_frequency(&t->fe, &abs_freq);
@@ -1131,12 +1109,22 @@
 			DIV_ROUND_CLOSEST(abs_freq * 2, 125) :
 			DIV_ROUND_CLOSEST(abs_freq, 62500);
 	} else {
-		f->frequency = (V4L2_TUNER_RADIO == t->mode) ?
+		f->frequency = (V4L2_TUNER_RADIO == f->type) ?
 			t->radio_freq : t->tv_freq;
 	}
 	return 0;
 }
 
+/**
+ * tuner_g_tuner - Fill in tuner information
+ * @sd: pointer to struct v4l2_subdev
+ * @vt: pointer to struct v4l2_tuner
+ *
+ * At return, the structure vt will be filled with tuner information
+ * if the tuner matches vt->type.
+ * Note: vt->type should be initialized before calling it.
+ * This is done by either video_ioctl2 or by the bridge driver.
+ */
 static int tuner_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt)
 {
 	struct tuner *t = to_tuner(sd);
@@ -1145,48 +1133,58 @@
 
 	if (check_mode(t, vt->type) == -EINVAL)
 		return 0;
-	vt->type = t->mode;
-	if (analog_ops->get_afc)
+	if (vt->type == t->mode && analog_ops->get_afc)
 		vt->afc = analog_ops->get_afc(&t->fe);
-	if (t->mode == V4L2_TUNER_ANALOG_TV)
+	if (vt->type == V4L2_TUNER_ANALOG_TV)
 		vt->capability |= V4L2_TUNER_CAP_NORM;
-	if (t->mode != V4L2_TUNER_RADIO) {
+	if (vt->type != V4L2_TUNER_RADIO) {
 		vt->rangelow = tv_range[0] * 16;
 		vt->rangehigh = tv_range[1] * 16;
 		return 0;
 	}
 
 	/* radio mode */
-	vt->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO;
-	if (fe_tuner_ops->get_status) {
-		u32 tuner_status;
+	if (vt->type == t->mode) {
+		vt->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO;
+		if (fe_tuner_ops->get_status) {
+			u32 tuner_status;
 
-		fe_tuner_ops->get_status(&t->fe, &tuner_status);
-		vt->rxsubchans =
-			(tuner_status & TUNER_STATUS_STEREO) ?
-			V4L2_TUNER_SUB_STEREO :
-			V4L2_TUNER_SUB_MONO;
+			fe_tuner_ops->get_status(&t->fe, &tuner_status);
+			vt->rxsubchans =
+				(tuner_status & TUNER_STATUS_STEREO) ?
+				V4L2_TUNER_SUB_STEREO :
+				V4L2_TUNER_SUB_MONO;
+		}
+		if (analog_ops->has_signal)
+			vt->signal = analog_ops->has_signal(&t->fe);
+		vt->audmode = t->audmode;
 	}
-	if (analog_ops->has_signal)
-		vt->signal = analog_ops->has_signal(&t->fe);
 	vt->capability |= V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO;
-	vt->audmode = t->audmode;
 	vt->rangelow = radio_range[0] * 16000;
 	vt->rangehigh = radio_range[1] * 16000;
 
 	return 0;
 }
 
+/**
+ * tuner_s_tuner - Set the tuner's audio mode
+ * @sd: pointer to struct v4l2_subdev
+ * @vt: pointer to struct v4l2_tuner
+ *
+ * Sets the audio mode if the tuner matches vt->type.
+ * Note: vt->type should be initialized before calling it.
+ * This is done by either video_ioctl2 or by the bridge driver.
+ */
 static int tuner_s_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt)
 {
 	struct tuner *t = to_tuner(sd);
-	struct i2c_client *client = v4l2_get_subdevdata(sd);
 
-	if (set_mode_freq(client, t, vt->type, 0) == -EINVAL)
+	if (set_mode(t, vt->type))
 		return 0;
 
 	if (t->mode == V4L2_TUNER_RADIO)
 		t->audmode = vt->audmode;
+	set_freq(t, 0);
 
 	return 0;
 }
@@ -1221,7 +1219,8 @@
 	tuner_dbg("resume\n");
 
 	if (!t->standby)
-		set_mode_freq(c, t, t->type, 0);
+		if (set_mode(t, t->mode) == 0)
+			set_freq(t, 0);
 
 	return 0;
 }
diff -druN linux-2.6.39-libre/drivers/media/video/tveeprom.c linux-3.0-rc7-libre/drivers/media/video/tveeprom.c
--- linux-2.6.39-libre/drivers/media/video/tveeprom.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/video/tveeprom.c	2011-07-11 19:51:52.000000000 -0400
@@ -267,21 +267,27 @@
 	{ TUNER_ABSENT,                 "Xceive XC4000"},
 	{ TUNER_ABSENT,                 "Dibcom 7070"},
 	{ TUNER_PHILIPS_TDA8290,        "NXP 18271C2"},
-	{ TUNER_ABSENT,			"unknown"},
-	{ TUNER_ABSENT,			"unknown"},
-	{ TUNER_ABSENT,			"unknown"},
-	{ TUNER_ABSENT,			"unknown"},
+	{ TUNER_ABSENT,                 "Siano SMS1010"},
+	{ TUNER_ABSENT,                 "Siano SMS1150"},
+	{ TUNER_ABSENT,                 "MaxLinear 5007"},
+	{ TUNER_ABSENT,                 "TCL M09WPP_2P_E"},
 	/* 160-169 */
-	{ TUNER_ABSENT,			"unknown"},
-	{ TUNER_ABSENT,			"unknown"},
-	{ TUNER_ABSENT,			"unknown"},
-	{ TUNER_ABSENT,			"unknown"},
-	{ TUNER_ABSENT,			"unknown"},
-	{ TUNER_ABSENT,			"unknown"},
-	{ TUNER_ABSENT,			"unknown"},
-	{ TUNER_ABSENT,			"unknown"},
+	{ TUNER_ABSENT,                 "Siano SMS1180"},
+	{ TUNER_ABSENT,                 "Maxim_MAX2165"},
+	{ TUNER_ABSENT,                 "Siano SMS1140"},
+	{ TUNER_ABSENT,                 "Siano SMS1150 B1"},
+	{ TUNER_ABSENT,                 "MaxLinear 111"},
+	{ TUNER_ABSENT,                 "Dibcom 7770"},
+	{ TUNER_ABSENT,                 "Siano SMS1180VNS"},
+	{ TUNER_ABSENT,                 "Siano SMS1184"},
 	{ TUNER_PHILIPS_FQ1236_MK5,	"TCL M30WTP-4N-E"},
-	{ TUNER_ABSENT,			"unknown"},
+	{ TUNER_ABSENT,                 "TCL_M11WPP_2PN_E"},
+	/* 170-179 */
+	{ TUNER_ABSENT,                 "MaxLinear 301"},
+	{ TUNER_ABSENT,                 "Mirics MSi001"},
+	{ TUNER_ABSENT,                 "MaxLinear MxL241SF"},
+	{ TUNER_ABSENT,                 "Xceive XC5000C"},
+	{ TUNER_ABSENT,                 "Montage M68TS2020"},
 };
 
 /* Use V4L2_IDENT_AMBIGUOUS for those audio 'chips' that are
diff -druN linux-2.6.39-libre/drivers/media/video/usbvision/usbvision-cards.c linux-3.0-rc7-libre/drivers/media/video/usbvision/usbvision-cards.c
--- linux-2.6.39-libre/drivers/media/video/usbvision/usbvision-cards.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/video/usbvision/usbvision-cards.c	2011-07-11 19:51:52.000000000 -0400
@@ -1025,6 +1025,34 @@
 		.y_offset       = -1,
 		.model_string   = "Hauppauge WinTv-USB",
 	},
+	[MICROCAM_NTSC] = {
+		.interface      = -1,
+		.codec          = CODEC_WEBCAM,
+		.video_channels = 1,
+		.video_norm     = V4L2_STD_NTSC,
+		.audio_channels = 0,
+		.radio          = 0,
+		.vbi            = 0,
+		.tuner          = 0,
+		.tuner_type     = 0,
+		.x_offset       = 71,
+		.y_offset       = 15,
+		.model_string   = "Nogatech USB MicroCam NTSC (NV3000N)",
+	},
+	[MICROCAM_PAL] = {
+		.interface      = -1,
+		.codec          = CODEC_WEBCAM,
+		.video_channels = 1,
+		.video_norm     = V4L2_STD_PAL,
+		.audio_channels = 0,
+		.radio          = 0,
+		.vbi            = 0,
+		.tuner          = 0,
+		.tuner_type     = 0,
+		.x_offset       = 71,
+		.y_offset       = 18,
+		.model_string   = "Nogatech USB MicroCam PAL (NV3001P)",
+	},
 };
 const int usbvision_device_data_size = ARRAY_SIZE(usbvision_device_data);
 
@@ -1042,6 +1070,8 @@
 	{ USB_DEVICE(0x0573, 0x2d00), .driver_info = HPG_WINTV_LIVE_PAL_BG },
 	{ USB_DEVICE(0x0573, 0x2d01), .driver_info = HPG_WINTV_LIVE_PRO_NTSC_MN },
 	{ USB_DEVICE(0x0573, 0x2101), .driver_info = ZORAN_PMD_NOGATECH },
+	{ USB_DEVICE(0x0573, 0x3000), .driver_info = MICROCAM_NTSC },
+	{ USB_DEVICE(0x0573, 0x3001), .driver_info = MICROCAM_PAL },
 	{ USB_DEVICE(0x0573, 0x4100), .driver_info = NOGATECH_USB_TV_NTSC_FM },
 	{ USB_DEVICE(0x0573, 0x4110), .driver_info = PNY_USB_TV_NTSC_FM },
 	{ USB_DEVICE(0x0573, 0x4450), .driver_info = PV_PLAYTV_USB_PRO_PAL_FM },
@@ -1088,8 +1118,7 @@
 	{ USB_DEVICE(0x2304, 0x0110), .driver_info = PINNA_PCTV_USB_PAL_FM },
 	{ USB_DEVICE(0x2304, 0x0111), .driver_info = MIRO_PCTV_USB },
 	{ USB_DEVICE(0x2304, 0x0112), .driver_info = PINNA_PCTV_USB_NTSC_FM },
-	{ USB_DEVICE(0x2304, 0x0113),
-	  .driver_info = PINNA_PCTV_USB_NTSC_FM_V3 },
+	{ USB_DEVICE(0x2304, 0x0113), .driver_info = PINNA_PCTV_USB_NTSC_FM_V3 },
 	{ USB_DEVICE(0x2304, 0x0210), .driver_info = PINNA_PCTV_USB_PAL_FM_V2 },
 	{ USB_DEVICE(0x2304, 0x0212), .driver_info = PINNA_PCTV_USB_NTSC_FM_V2 },
 	{ USB_DEVICE(0x2304, 0x0214), .driver_info = PINNA_PCTV_USB_PAL_FM_V3 },
diff -druN linux-2.6.39-libre/drivers/media/video/usbvision/usbvision-cards.h linux-3.0-rc7-libre/drivers/media/video/usbvision/usbvision-cards.h
--- linux-2.6.39-libre/drivers/media/video/usbvision/usbvision-cards.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/video/usbvision/usbvision-cards.h	2011-07-11 19:51:52.000000000 -0400
@@ -63,5 +63,7 @@
 #define PINNA_PCTV_BUNGEE_PAL_FM                 62
 #define HPG_WINTV                                63
 #define PINNA_PCTV_USB_NTSC_FM_V3                64
+#define MICROCAM_NTSC                            65
+#define MICROCAM_PAL                             66
 
 extern const int usbvision_device_data_size;
diff -druN linux-2.6.39-libre/drivers/media/video/usbvision/usbvision-core.c linux-3.0-rc7-libre/drivers/media/video/usbvision/usbvision-core.c
--- linux-2.6.39-libre/drivers/media/video/usbvision/usbvision-core.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/video/usbvision/usbvision-core.c	2011-07-11 19:51:52.000000000 -0400
@@ -49,10 +49,6 @@
 module_param(core_debug, int, 0644);
 MODULE_PARM_DESC(core_debug, "enable debug messages [core]");
 
-static unsigned int force_testpattern;
-module_param(force_testpattern, int, 0644);
-MODULE_PARM_DESC(force_testpattern, "enable test pattern display [core]");
-
 static int adjust_compression = 1;	/* Set the compression to be adaptive */
 module_param(adjust_compression, int, 0444);
 MODULE_PARM_DESC(adjust_compression, " Set the ADPCM compression for the device.  Default: 1 (On)");
@@ -388,90 +384,6 @@
 }
 
 /*
- * usbvision_testpattern()
- *
- * Procedure forms a test pattern (yellow grid on blue background).
- *
- * Parameters:
- * fullframe:   if TRUE then entire frame is filled, otherwise the procedure
- *		continues from the current scanline.
- * pmode	0: fill the frame with solid blue color (like on VCR or TV)
- *		1: Draw a colored grid
- *
- */
-static void usbvision_testpattern(struct usb_usbvision *usbvision,
-				  int fullframe, int pmode)
-{
-	static const char proc[] = "usbvision_testpattern";
-	struct usbvision_frame *frame;
-	unsigned char *f;
-	int num_cell = 0;
-	int scan_length = 0;
-	static int num_pass;
-
-	if (usbvision == NULL) {
-		printk(KERN_ERR "%s: usbvision == NULL\n", proc);
-		return;
-	}
-	if (usbvision->cur_frame == NULL) {
-		printk(KERN_ERR "%s: usbvision->cur_frame is NULL.\n", proc);
-		return;
-	}
-
-	/* Grab the current frame */
-	frame = usbvision->cur_frame;
-
-	/* Optionally start at the beginning */
-	if (fullframe) {
-		frame->curline = 0;
-		frame->scanlength = 0;
-	}
-
-	/* Form every scan line */
-	for (; frame->curline < frame->frmheight; frame->curline++) {
-		int i;
-
-		f = frame->data + (usbvision->curwidth * 3 * frame->curline);
-		for (i = 0; i < usbvision->curwidth; i++) {
-			unsigned char cb = 0x80;
-			unsigned char cg = 0;
-			unsigned char cr = 0;
-
-			if (pmode == 1) {
-				if (frame->curline % 32 == 0)
-					cb = 0, cg = cr = 0xFF;
-				else if (i % 32 == 0) {
-					if (frame->curline % 32 == 1)
-						num_cell++;
-					cb = 0, cg = cr = 0xFF;
-				} else {
-					cb =
-					    ((num_cell * 7) +
-					     num_pass) & 0xFF;
-					cg =
-					    ((num_cell * 5) +
-					     num_pass * 2) & 0xFF;
-					cr =
-					    ((num_cell * 3) +
-					     num_pass * 3) & 0xFF;
-				}
-			} else {
-				/* Just the blue screen */
-			}
-
-			*f++ = cb;
-			*f++ = cg;
-			*f++ = cr;
-			scan_length += 3;
-		}
-	}
-
-	frame->grabstate = frame_state_done;
-	frame->scanlength += scan_length;
-	++num_pass;
-}
-
-/*
  * usbvision_decompress_alloc()
  *
  * allocates intermediate buffer for decompression
@@ -571,10 +483,6 @@
 	frame->scanstate = scan_state_lines;
 	frame->curline = 0;
 
-	if (force_testpattern) {
-		usbvision_testpattern(usbvision, 1, 1);
-		return parse_state_next_frame;
-	}
 	return parse_state_continue;
 }
 
@@ -1679,6 +1587,55 @@
 	return err_code;
 }
 
+/* configure webcam image sensor using the serial port */
+static int usbvision_init_webcam(struct usb_usbvision *usbvision)
+{
+	int rc;
+	int i;
+	static char init_values[38][3] = {
+		{ 0x04, 0x12, 0x08 }, { 0x05, 0xff, 0xc8 }, { 0x06, 0x18, 0x07 }, { 0x07, 0x90, 0x00 },
+		{ 0x09, 0x00, 0x00 }, { 0x0a, 0x00, 0x00 }, { 0x0b, 0x08, 0x00 }, { 0x0d, 0xcc, 0xcc },
+		{ 0x0e, 0x13, 0x14 }, { 0x10, 0x9b, 0x83 }, { 0x11, 0x5a, 0x3f }, { 0x12, 0xe4, 0x73 },
+		{ 0x13, 0x88, 0x84 }, { 0x14, 0x89, 0x80 }, { 0x15, 0x00, 0x20 }, { 0x16, 0x00, 0x00 },
+		{ 0x17, 0xff, 0xa0 }, { 0x18, 0x6b, 0x20 }, { 0x19, 0x22, 0x40 }, { 0x1a, 0x10, 0x07 },
+		{ 0x1b, 0x00, 0x47 }, { 0x1c, 0x03, 0xe0 }, { 0x1d, 0x00, 0x00 }, { 0x1e, 0x00, 0x00 },
+		{ 0x1f, 0x00, 0x00 }, { 0x20, 0x00, 0x00 }, { 0x21, 0x00, 0x00 }, { 0x22, 0x00, 0x00 },
+		{ 0x23, 0x00, 0x00 }, { 0x24, 0x00, 0x00 }, { 0x25, 0x00, 0x00 }, { 0x26, 0x00, 0x00 },
+		{ 0x27, 0x00, 0x00 }, { 0x28, 0x00, 0x00 }, { 0x29, 0x00, 0x00 }, { 0x08, 0x80, 0x60 },
+		{ 0x0f, 0x2d, 0x24 }, { 0x0c, 0x80, 0x80 }
+	};
+	char value[3];
+
+	/* the only difference between PAL and NTSC init_values */
+	if (usbvision_device_data[usbvision->dev_model].video_norm == V4L2_STD_NTSC)
+		init_values[4][1] = 0x34;
+
+	for (i = 0; i < sizeof(init_values) / 3; i++) {
+		usbvision_write_reg(usbvision, USBVISION_SER_MODE, USBVISION_SER_MODE_SOFT);
+		memcpy(value, init_values[i], 3);
+		rc = usb_control_msg(usbvision->dev,
+				     usb_sndctrlpipe(usbvision->dev, 1),
+				     USBVISION_OP_CODE,
+				     USB_DIR_OUT | USB_TYPE_VENDOR |
+				     USB_RECIP_ENDPOINT, 0,
+				     (__u16) USBVISION_SER_DAT1, value,
+				     3, HZ);
+		if (rc < 0)
+			return rc;
+		usbvision_write_reg(usbvision, USBVISION_SER_MODE, USBVISION_SER_MODE_SIO);
+		/* write 3 bytes to the serial port using SIO mode */
+		usbvision_write_reg(usbvision, USBVISION_SER_CONT, 3 | 0x10);
+		usbvision_write_reg(usbvision, USBVISION_IOPIN_REG, 0);
+		usbvision_write_reg(usbvision, USBVISION_SER_MODE, USBVISION_SER_MODE_SOFT);
+		usbvision_write_reg(usbvision, USBVISION_IOPIN_REG, USBVISION_IO_2);
+		usbvision_write_reg(usbvision, USBVISION_SER_MODE, USBVISION_SER_MODE_SOFT | USBVISION_CLK_OUT);
+		usbvision_write_reg(usbvision, USBVISION_SER_MODE, USBVISION_SER_MODE_SOFT | USBVISION_DAT_IO);
+		usbvision_write_reg(usbvision, USBVISION_SER_MODE, USBVISION_SER_MODE_SOFT | USBVISION_CLK_OUT | USBVISION_DAT_IO);
+	}
+
+	return 0;
+}
+
 /*
  * usbvision_set_video_format()
  *
@@ -1797,6 +1754,13 @@
 
 	frame_drop = FRAMERATE_MAX;	/* We can allow the maximum here, because dropping is controlled */
 
+	if (usbvision_device_data[usbvision->dev_model].codec == CODEC_WEBCAM) {
+		if (usbvision_device_data[usbvision->dev_model].video_norm == V4L2_STD_PAL)
+			frame_drop = 25;
+		else
+			frame_drop = 30;
+	}
+
 	/* frame_drop = 7; => frame_phase = 1, 5, 9, 13, 17, 21, 25, 0, 4, 8, ...
 		=> frame_skip = 4;
 		=> frame_rate = (7 + 1) * 25 / 32 = 200 / 32 = 6.25;
@@ -2046,6 +2010,12 @@
 		value[7] = 0x00;	/* 0x0010 -> 16 Input video v offset */
 	}
 
+	/* webcam is only 480 pixels wide, both PAL and NTSC version */
+	if (usbvision_device_data[usbvision->dev_model].codec == CODEC_WEBCAM) {
+		value[0] = 0xe0;
+		value[1] = 0x01;	/* 0x01E0 -> 480 Input video line length */
+	}
+
 	if (usbvision_device_data[usbvision->dev_model].x_offset >= 0) {
 		value[4] = usbvision_device_data[usbvision->dev_model].x_offset & 0xff;
 		value[5] = (usbvision_device_data[usbvision->dev_model].x_offset & 0x0300) >> 8;
@@ -2148,7 +2118,7 @@
 			     (__u16) USBVISION_DRM_PRM1, value, 8, HZ);
 
 	if (rc < 0) {
-		dev_err(&usbvision->dev->dev, "%sERROR=%d\n", __func__, rc);
+		dev_err(&usbvision->dev->dev, "%s: ERROR=%d\n", __func__, rc);
 		return rc;
 	}
 
@@ -2180,8 +2150,15 @@
 	usbvision_write_reg(usbvision, USBVISION_PWR_REG,
 			USBVISION_SSPND_EN | USBVISION_RES2);
 
+	if (usbvision_device_data[usbvision->dev_model].codec == CODEC_WEBCAM) {
+		usbvision_write_reg(usbvision, USBVISION_VIN_REG1,
+				USBVISION_16_422_SYNC | USBVISION_HVALID_PO);
+		usbvision_write_reg(usbvision, USBVISION_VIN_REG2,
+				USBVISION_NOHVALID | USBVISION_KEEP_BLANK);
+	}
 	usbvision_write_reg(usbvision, USBVISION_PWR_REG,
 			USBVISION_SSPND_EN | USBVISION_PWR_VID);
+	mdelay(10);
 	err_code = usbvision_write_reg(usbvision, USBVISION_PWR_REG,
 			USBVISION_SSPND_EN | USBVISION_PWR_VID | USBVISION_RES2);
 	if (err_code == 1)
@@ -2310,6 +2287,8 @@
 
 int usbvision_setup(struct usb_usbvision *usbvision, int format)
 {
+	if (usbvision_device_data[usbvision->dev_model].codec == CODEC_WEBCAM)
+		usbvision_init_webcam(usbvision);
 	usbvision_set_video_format(usbvision, format);
 	usbvision_set_dram_settings(usbvision);
 	usbvision_set_compress_params(usbvision);
diff -druN linux-2.6.39-libre/drivers/media/video/usbvision/usbvision.h linux-3.0-rc7-libre/drivers/media/video/usbvision/usbvision.h
--- linux-2.6.39-libre/drivers/media/video/usbvision/usbvision.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/video/usbvision/usbvision.h	2011-07-11 19:51:52.000000000 -0400
@@ -59,6 +59,11 @@
 	#define USBVISION_AUDIO_RADIO		2
 	#define USBVISION_AUDIO_MUTE		3
 #define USBVISION_SER_MODE		0x07
+	#define USBVISION_CLK_OUT		(1 << 0)
+	#define USBVISION_DAT_IO		(1 << 1)
+	#define USBVISION_SENS_OUT		(1 << 2)
+	#define USBVISION_SER_MODE_SOFT		(0 << 4)
+	#define USBVISION_SER_MODE_SIO		(1 << 4)
 #define USBVISION_SER_ADRS		0x08
 #define USBVISION_SER_CONT		0x09
 #define USBVISION_SER_DAT1		0x0A
@@ -328,6 +333,7 @@
 
 #define CODEC_SAA7113	7113
 #define CODEC_SAA7111	7111
+#define CODEC_WEBCAM	3000
 #define BRIDGE_NT1003	1003
 #define BRIDGE_NT1004	1004
 #define BRIDGE_NT1005   1005
diff -druN linux-2.6.39-libre/drivers/media/video/usbvision/usbvision-i2c.c linux-3.0-rc7-libre/drivers/media/video/usbvision/usbvision-i2c.c
--- linux-2.6.39-libre/drivers/media/video/usbvision/usbvision-i2c.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/video/usbvision/usbvision-i2c.c	2011-07-11 19:51:52.000000000 -0400
@@ -222,7 +222,7 @@
 	i2c_set_adapdata(&usbvision->i2c_adap, &usbvision->v4l2_dev);
 
 	if (usbvision_write_reg(usbvision, USBVISION_SER_MODE, USBVISION_IIC_LRNACK) < 0) {
-		printk(KERN_ERR "usbvision_register: can't write reg\n");
+		printk(KERN_ERR "usbvision_i2c_register: can't write reg\n");
 		return -EBUSY;
 	}
 
diff -druN linux-2.6.39-libre/drivers/media/video/usbvision/usbvision-video.c linux-3.0-rc7-libre/drivers/media/video/usbvision/usbvision-video.c
--- linux-2.6.39-libre/drivers/media/video/usbvision/usbvision-video.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/video/usbvision/usbvision-video.c	2011-07-11 19:51:52.000000000 -0400
@@ -70,8 +70,9 @@
 #include "usbvision.h"
 #include "usbvision-cards.h"
 
-#define DRIVER_AUTHOR "Joerg Heckenbach <joerg@heckenbach-aw.de>, \
-Dwaine Garden <DwaineGarden@rogers.com>"
+#define DRIVER_AUTHOR					\
+	"Joerg Heckenbach <joerg@heckenbach-aw.de>, "	\
+	"Dwaine Garden <DwaineGarden@rogers.com>"
 #define DRIVER_NAME "usbvision"
 #define DRIVER_ALIAS "USBVision"
 #define DRIVER_DESC "USBVision USB Video Device Driver for Linux"
@@ -1470,7 +1471,8 @@
 
 	/* This should be here to make i2c clients to be able to register */
 	/* first switch off audio */
-	usbvision_audio_off(usbvision);
+	if (usbvision_device_data[model].audio_channels > 0)
+		usbvision_audio_off(usbvision);
 	if (!power_on_at_open) {
 		/* and then power up the noisy tuner */
 		usbvision_power_on(usbvision);
diff -druN linux-2.6.39-libre/drivers/media/video/uvc/Makefile linux-3.0-rc7-libre/drivers/media/video/uvc/Makefile
--- linux-2.6.39-libre/drivers/media/video/uvc/Makefile	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/video/uvc/Makefile	2011-07-11 19:51:52.000000000 -0400
@@ -1,3 +1,6 @@
 uvcvideo-objs  := uvc_driver.o uvc_queue.o uvc_v4l2.o uvc_video.o uvc_ctrl.o \
 		  uvc_status.o uvc_isight.o
+ifeq ($(CONFIG_MEDIA_CONTROLLER),y)
+uvcvideo-objs  += uvc_entity.o
+endif
 obj-$(CONFIG_USB_VIDEO_CLASS) += uvcvideo.o
diff -druN linux-2.6.39-libre/drivers/media/video/uvc/uvc_ctrl.c linux-3.0-rc7-libre/drivers/media/video/uvc/uvc_ctrl.c
--- linux-2.6.39-libre/drivers/media/video/uvc/uvc_ctrl.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/video/uvc/uvc_ctrl.c	2011-07-11 19:51:52.000000000 -0400
@@ -42,281 +42,313 @@
 		.selector	= UVC_PU_BRIGHTNESS_CONTROL,
 		.index		= 0,
 		.size		= 2,
-		.flags		= UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE
-				| UVC_CONTROL_RESTORE,
+		.flags		= UVC_CTRL_FLAG_SET_CUR
+				| UVC_CTRL_FLAG_GET_RANGE
+				| UVC_CTRL_FLAG_RESTORE,
 	},
 	{
 		.entity		= UVC_GUID_UVC_PROCESSING,
 		.selector	= UVC_PU_CONTRAST_CONTROL,
 		.index		= 1,
 		.size		= 2,
-		.flags		= UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE
-				| UVC_CONTROL_RESTORE,
+		.flags		= UVC_CTRL_FLAG_SET_CUR
+				| UVC_CTRL_FLAG_GET_RANGE
+				| UVC_CTRL_FLAG_RESTORE,
 	},
 	{
 		.entity		= UVC_GUID_UVC_PROCESSING,
 		.selector	= UVC_PU_HUE_CONTROL,
 		.index		= 2,
 		.size		= 2,
-		.flags		= UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE
-				| UVC_CONTROL_RESTORE | UVC_CONTROL_AUTO_UPDATE,
+		.flags		= UVC_CTRL_FLAG_SET_CUR
+				| UVC_CTRL_FLAG_GET_RANGE
+				| UVC_CTRL_FLAG_RESTORE
+				| UVC_CTRL_FLAG_AUTO_UPDATE,
 	},
 	{
 		.entity		= UVC_GUID_UVC_PROCESSING,
 		.selector	= UVC_PU_SATURATION_CONTROL,
 		.index		= 3,
 		.size		= 2,
-		.flags		= UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE
-				| UVC_CONTROL_RESTORE,
+		.flags		= UVC_CTRL_FLAG_SET_CUR
+				| UVC_CTRL_FLAG_GET_RANGE
+				| UVC_CTRL_FLAG_RESTORE,
 	},
 	{
 		.entity		= UVC_GUID_UVC_PROCESSING,
 		.selector	= UVC_PU_SHARPNESS_CONTROL,
 		.index		= 4,
 		.size		= 2,
-		.flags		= UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE
-				| UVC_CONTROL_RESTORE,
+		.flags		= UVC_CTRL_FLAG_SET_CUR
+				| UVC_CTRL_FLAG_GET_RANGE
+				| UVC_CTRL_FLAG_RESTORE,
 	},
 	{
 		.entity		= UVC_GUID_UVC_PROCESSING,
 		.selector	= UVC_PU_GAMMA_CONTROL,
 		.index		= 5,
 		.size		= 2,
-		.flags		= UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE
-				| UVC_CONTROL_RESTORE,
+		.flags		= UVC_CTRL_FLAG_SET_CUR
+				| UVC_CTRL_FLAG_GET_RANGE
+				| UVC_CTRL_FLAG_RESTORE,
 	},
 	{
 		.entity		= UVC_GUID_UVC_PROCESSING,
 		.selector	= UVC_PU_WHITE_BALANCE_TEMPERATURE_CONTROL,
 		.index		= 6,
 		.size		= 2,
-		.flags		= UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE
-				| UVC_CONTROL_RESTORE | UVC_CONTROL_AUTO_UPDATE,
+		.flags		= UVC_CTRL_FLAG_SET_CUR
+				| UVC_CTRL_FLAG_GET_RANGE
+				| UVC_CTRL_FLAG_RESTORE
+				| UVC_CTRL_FLAG_AUTO_UPDATE,
 	},
 	{
 		.entity		= UVC_GUID_UVC_PROCESSING,
 		.selector	= UVC_PU_WHITE_BALANCE_COMPONENT_CONTROL,
 		.index		= 7,
 		.size		= 4,
-		.flags		= UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE
-				| UVC_CONTROL_RESTORE | UVC_CONTROL_AUTO_UPDATE,
+		.flags		= UVC_CTRL_FLAG_SET_CUR
+				| UVC_CTRL_FLAG_GET_RANGE
+				| UVC_CTRL_FLAG_RESTORE
+				| UVC_CTRL_FLAG_AUTO_UPDATE,
 	},
 	{
 		.entity		= UVC_GUID_UVC_PROCESSING,
 		.selector	= UVC_PU_BACKLIGHT_COMPENSATION_CONTROL,
 		.index		= 8,
 		.size		= 2,
-		.flags		= UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE
-				| UVC_CONTROL_RESTORE,
+		.flags		= UVC_CTRL_FLAG_SET_CUR
+				| UVC_CTRL_FLAG_GET_RANGE
+				| UVC_CTRL_FLAG_RESTORE,
 	},
 	{
 		.entity		= UVC_GUID_UVC_PROCESSING,
 		.selector	= UVC_PU_GAIN_CONTROL,
 		.index		= 9,
 		.size		= 2,
-		.flags		= UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE
-				| UVC_CONTROL_RESTORE,
+		.flags		= UVC_CTRL_FLAG_SET_CUR
+				| UVC_CTRL_FLAG_GET_RANGE
+				| UVC_CTRL_FLAG_RESTORE,
 	},
 	{
 		.entity		= UVC_GUID_UVC_PROCESSING,
 		.selector	= UVC_PU_POWER_LINE_FREQUENCY_CONTROL,
 		.index		= 10,
 		.size		= 1,
-		.flags		= UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_CUR
-				| UVC_CONTROL_GET_DEF | UVC_CONTROL_RESTORE,
+		.flags		= UVC_CTRL_FLAG_SET_CUR | UVC_CTRL_FLAG_GET_CUR
+				| UVC_CTRL_FLAG_GET_DEF | UVC_CTRL_FLAG_RESTORE,
 	},
 	{
 		.entity		= UVC_GUID_UVC_PROCESSING,
 		.selector	= UVC_PU_HUE_AUTO_CONTROL,
 		.index		= 11,
 		.size		= 1,
-		.flags		= UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_CUR
-				| UVC_CONTROL_GET_DEF | UVC_CONTROL_RESTORE,
+		.flags		= UVC_CTRL_FLAG_SET_CUR | UVC_CTRL_FLAG_GET_CUR
+				| UVC_CTRL_FLAG_GET_DEF | UVC_CTRL_FLAG_RESTORE,
 	},
 	{
 		.entity		= UVC_GUID_UVC_PROCESSING,
 		.selector	= UVC_PU_WHITE_BALANCE_TEMPERATURE_AUTO_CONTROL,
 		.index		= 12,
 		.size		= 1,
-		.flags		= UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_CUR
-				| UVC_CONTROL_GET_DEF | UVC_CONTROL_RESTORE,
+		.flags		= UVC_CTRL_FLAG_SET_CUR | UVC_CTRL_FLAG_GET_CUR
+				| UVC_CTRL_FLAG_GET_DEF | UVC_CTRL_FLAG_RESTORE,
 	},
 	{
 		.entity		= UVC_GUID_UVC_PROCESSING,
 		.selector	= UVC_PU_WHITE_BALANCE_COMPONENT_AUTO_CONTROL,
 		.index		= 13,
 		.size		= 1,
-		.flags		= UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_CUR
-				| UVC_CONTROL_GET_DEF | UVC_CONTROL_RESTORE,
+		.flags		= UVC_CTRL_FLAG_SET_CUR | UVC_CTRL_FLAG_GET_CUR
+				| UVC_CTRL_FLAG_GET_DEF | UVC_CTRL_FLAG_RESTORE,
 	},
 	{
 		.entity		= UVC_GUID_UVC_PROCESSING,
 		.selector	= UVC_PU_DIGITAL_MULTIPLIER_CONTROL,
 		.index		= 14,
 		.size		= 2,
-		.flags		= UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE
-				| UVC_CONTROL_RESTORE,
+		.flags		= UVC_CTRL_FLAG_SET_CUR
+				| UVC_CTRL_FLAG_GET_RANGE
+				| UVC_CTRL_FLAG_RESTORE,
 	},
 	{
 		.entity		= UVC_GUID_UVC_PROCESSING,
 		.selector	= UVC_PU_DIGITAL_MULTIPLIER_LIMIT_CONTROL,
 		.index		= 15,
 		.size		= 2,
-		.flags		= UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE
-				| UVC_CONTROL_RESTORE,
+		.flags		= UVC_CTRL_FLAG_SET_CUR
+				| UVC_CTRL_FLAG_GET_RANGE
+				| UVC_CTRL_FLAG_RESTORE,
 	},
 	{
 		.entity		= UVC_GUID_UVC_PROCESSING,
 		.selector	= UVC_PU_ANALOG_VIDEO_STANDARD_CONTROL,
 		.index		= 16,
 		.size		= 1,
-		.flags		= UVC_CONTROL_GET_CUR,
+		.flags		= UVC_CTRL_FLAG_GET_CUR,
 	},
 	{
 		.entity		= UVC_GUID_UVC_PROCESSING,
 		.selector	= UVC_PU_ANALOG_LOCK_STATUS_CONTROL,
 		.index		= 17,
 		.size		= 1,
-		.flags		= UVC_CONTROL_GET_CUR,
+		.flags		= UVC_CTRL_FLAG_GET_CUR,
 	},
 	{
 		.entity		= UVC_GUID_UVC_CAMERA,
 		.selector	= UVC_CT_SCANNING_MODE_CONTROL,
 		.index		= 0,
 		.size		= 1,
-		.flags		= UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_CUR
-				| UVC_CONTROL_RESTORE,
+		.flags		= UVC_CTRL_FLAG_SET_CUR | UVC_CTRL_FLAG_GET_CUR
+				| UVC_CTRL_FLAG_RESTORE,
 	},
 	{
 		.entity		= UVC_GUID_UVC_CAMERA,
 		.selector	= UVC_CT_AE_MODE_CONTROL,
 		.index		= 1,
 		.size		= 1,
-		.flags		= UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_CUR
-				| UVC_CONTROL_GET_DEF | UVC_CONTROL_GET_RES
-				| UVC_CONTROL_RESTORE,
+		.flags		= UVC_CTRL_FLAG_SET_CUR | UVC_CTRL_FLAG_GET_CUR
+				| UVC_CTRL_FLAG_GET_DEF | UVC_CTRL_FLAG_GET_RES
+				| UVC_CTRL_FLAG_RESTORE,
 	},
 	{
 		.entity		= UVC_GUID_UVC_CAMERA,
 		.selector	= UVC_CT_AE_PRIORITY_CONTROL,
 		.index		= 2,
 		.size		= 1,
-		.flags		= UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_CUR
-				| UVC_CONTROL_RESTORE,
+		.flags		= UVC_CTRL_FLAG_SET_CUR | UVC_CTRL_FLAG_GET_CUR
+				| UVC_CTRL_FLAG_RESTORE,
 	},
 	{
 		.entity		= UVC_GUID_UVC_CAMERA,
 		.selector	= UVC_CT_EXPOSURE_TIME_ABSOLUTE_CONTROL,
 		.index		= 3,
 		.size		= 4,
-		.flags		= UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE
-				| UVC_CONTROL_RESTORE,
+		.flags		= UVC_CTRL_FLAG_SET_CUR
+				| UVC_CTRL_FLAG_GET_RANGE
+				| UVC_CTRL_FLAG_RESTORE,
 	},
 	{
 		.entity		= UVC_GUID_UVC_CAMERA,
 		.selector	= UVC_CT_EXPOSURE_TIME_RELATIVE_CONTROL,
 		.index		= 4,
 		.size		= 1,
-		.flags		= UVC_CONTROL_SET_CUR | UVC_CONTROL_RESTORE,
+		.flags		= UVC_CTRL_FLAG_SET_CUR | UVC_CTRL_FLAG_RESTORE,
 	},
 	{
 		.entity		= UVC_GUID_UVC_CAMERA,
 		.selector	= UVC_CT_FOCUS_ABSOLUTE_CONTROL,
 		.index		= 5,
 		.size		= 2,
-		.flags		= UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE
-				| UVC_CONTROL_RESTORE | UVC_CONTROL_AUTO_UPDATE,
+		.flags		= UVC_CTRL_FLAG_SET_CUR
+				| UVC_CTRL_FLAG_GET_RANGE
+				| UVC_CTRL_FLAG_RESTORE
+				| UVC_CTRL_FLAG_AUTO_UPDATE,
 	},
 	{
 		.entity		= UVC_GUID_UVC_CAMERA,
 		.selector	= UVC_CT_FOCUS_RELATIVE_CONTROL,
 		.index		= 6,
 		.size		= 2,
-		.flags		= UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_MIN
-				| UVC_CONTROL_GET_MAX | UVC_CONTROL_GET_RES
-				| UVC_CONTROL_GET_DEF | UVC_CONTROL_AUTO_UPDATE,
+		.flags		= UVC_CTRL_FLAG_SET_CUR | UVC_CTRL_FLAG_GET_MIN
+				| UVC_CTRL_FLAG_GET_MAX | UVC_CTRL_FLAG_GET_RES
+				| UVC_CTRL_FLAG_GET_DEF
+				| UVC_CTRL_FLAG_AUTO_UPDATE,
 	},
 	{
 		.entity		= UVC_GUID_UVC_CAMERA,
 		.selector	= UVC_CT_IRIS_ABSOLUTE_CONTROL,
 		.index		= 7,
 		.size		= 2,
-		.flags		= UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE
-				| UVC_CONTROL_RESTORE | UVC_CONTROL_AUTO_UPDATE,
+		.flags		= UVC_CTRL_FLAG_SET_CUR
+				| UVC_CTRL_FLAG_GET_RANGE
+				| UVC_CTRL_FLAG_RESTORE
+				| UVC_CTRL_FLAG_AUTO_UPDATE,
 	},
 	{
 		.entity		= UVC_GUID_UVC_CAMERA,
 		.selector	= UVC_CT_IRIS_RELATIVE_CONTROL,
 		.index		= 8,
 		.size		= 1,
-		.flags		= UVC_CONTROL_SET_CUR | UVC_CONTROL_AUTO_UPDATE,
+		.flags		= UVC_CTRL_FLAG_SET_CUR
+				| UVC_CTRL_FLAG_AUTO_UPDATE,
 	},
 	{
 		.entity		= UVC_GUID_UVC_CAMERA,
 		.selector	= UVC_CT_ZOOM_ABSOLUTE_CONTROL,
 		.index		= 9,
 		.size		= 2,
-		.flags		= UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE
-				| UVC_CONTROL_RESTORE | UVC_CONTROL_AUTO_UPDATE,
+		.flags		= UVC_CTRL_FLAG_SET_CUR
+				| UVC_CTRL_FLAG_GET_RANGE
+				| UVC_CTRL_FLAG_RESTORE
+				| UVC_CTRL_FLAG_AUTO_UPDATE,
 	},
 	{
 		.entity		= UVC_GUID_UVC_CAMERA,
 		.selector	= UVC_CT_ZOOM_RELATIVE_CONTROL,
 		.index		= 10,
 		.size		= 3,
-		.flags		= UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_MIN
-				| UVC_CONTROL_GET_MAX | UVC_CONTROL_GET_RES
-				| UVC_CONTROL_GET_DEF | UVC_CONTROL_AUTO_UPDATE,
+		.flags		= UVC_CTRL_FLAG_SET_CUR | UVC_CTRL_FLAG_GET_MIN
+				| UVC_CTRL_FLAG_GET_MAX | UVC_CTRL_FLAG_GET_RES
+				| UVC_CTRL_FLAG_GET_DEF
+				| UVC_CTRL_FLAG_AUTO_UPDATE,
 	},
 	{
 		.entity		= UVC_GUID_UVC_CAMERA,
 		.selector	= UVC_CT_PANTILT_ABSOLUTE_CONTROL,
 		.index		= 11,
 		.size		= 8,
-		.flags		= UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE
-				| UVC_CONTROL_RESTORE | UVC_CONTROL_AUTO_UPDATE,
+		.flags		= UVC_CTRL_FLAG_SET_CUR
+				| UVC_CTRL_FLAG_GET_RANGE
+				| UVC_CTRL_FLAG_RESTORE
+				| UVC_CTRL_FLAG_AUTO_UPDATE,
 	},
 	{
 		.entity		= UVC_GUID_UVC_CAMERA,
 		.selector	= UVC_CT_PANTILT_RELATIVE_CONTROL,
 		.index		= 12,
 		.size		= 4,
-		.flags		= UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_MIN
-				| UVC_CONTROL_GET_MAX | UVC_CONTROL_GET_RES
-				| UVC_CONTROL_GET_DEF | UVC_CONTROL_AUTO_UPDATE,
+		.flags		= UVC_CTRL_FLAG_SET_CUR | UVC_CTRL_FLAG_GET_MIN
+				| UVC_CTRL_FLAG_GET_MAX | UVC_CTRL_FLAG_GET_RES
+				| UVC_CTRL_FLAG_GET_DEF
+				| UVC_CTRL_FLAG_AUTO_UPDATE,
 	},
 	{
 		.entity		= UVC_GUID_UVC_CAMERA,
 		.selector	= UVC_CT_ROLL_ABSOLUTE_CONTROL,
 		.index		= 13,
 		.size		= 2,
-		.flags		= UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE
-				| UVC_CONTROL_RESTORE | UVC_CONTROL_AUTO_UPDATE,
+		.flags		= UVC_CTRL_FLAG_SET_CUR
+				| UVC_CTRL_FLAG_GET_RANGE
+				| UVC_CTRL_FLAG_RESTORE
+				| UVC_CTRL_FLAG_AUTO_UPDATE,
 	},
 	{
 		.entity		= UVC_GUID_UVC_CAMERA,
 		.selector	= UVC_CT_ROLL_RELATIVE_CONTROL,
 		.index		= 14,
 		.size		= 2,
-		.flags		= UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_MIN
-				| UVC_CONTROL_GET_MAX | UVC_CONTROL_GET_RES
-				| UVC_CONTROL_GET_DEF | UVC_CONTROL_AUTO_UPDATE,
+		.flags		= UVC_CTRL_FLAG_SET_CUR | UVC_CTRL_FLAG_GET_MIN
+				| UVC_CTRL_FLAG_GET_MAX | UVC_CTRL_FLAG_GET_RES
+				| UVC_CTRL_FLAG_GET_DEF
+				| UVC_CTRL_FLAG_AUTO_UPDATE,
 	},
 	{
 		.entity		= UVC_GUID_UVC_CAMERA,
 		.selector	= UVC_CT_FOCUS_AUTO_CONTROL,
 		.index		= 17,
 		.size		= 1,
-		.flags		= UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_CUR
-				| UVC_CONTROL_GET_DEF | UVC_CONTROL_RESTORE,
+		.flags		= UVC_CTRL_FLAG_SET_CUR | UVC_CTRL_FLAG_GET_CUR
+				| UVC_CTRL_FLAG_GET_DEF | UVC_CTRL_FLAG_RESTORE,
 	},
 	{
 		.entity		= UVC_GUID_UVC_CAMERA,
 		.selector	= UVC_CT_PRIVACY_CONTROL,
 		.index		= 18,
 		.size		= 1,
-		.flags		= UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_CUR
-				| UVC_CONTROL_RESTORE | UVC_CONTROL_AUTO_UPDATE,
+		.flags		= UVC_CTRL_FLAG_SET_CUR | UVC_CTRL_FLAG_GET_CUR
+				| UVC_CTRL_FLAG_RESTORE
+				| UVC_CTRL_FLAG_AUTO_UPDATE,
 	},
 };
 
@@ -816,7 +848,7 @@
 {
 	int ret;
 
-	if (ctrl->info.flags & UVC_CONTROL_GET_DEF) {
+	if (ctrl->info.flags & UVC_CTRL_FLAG_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),
@@ -825,7 +857,7 @@
 			return ret;
 	}
 
-	if (ctrl->info.flags & UVC_CONTROL_GET_MIN) {
+	if (ctrl->info.flags & UVC_CTRL_FLAG_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),
@@ -833,7 +865,7 @@
 		if (ret < 0)
 			return ret;
 	}
-	if (ctrl->info.flags & UVC_CONTROL_GET_MAX) {
+	if (ctrl->info.flags & UVC_CTRL_FLAG_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),
@@ -841,7 +873,7 @@
 		if (ret < 0)
 			return ret;
 	}
-	if (ctrl->info.flags & UVC_CONTROL_GET_RES) {
+	if (ctrl->info.flags & UVC_CTRL_FLAG_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),
@@ -879,9 +911,9 @@
 	strlcpy(v4l2_ctrl->name, mapping->name, sizeof v4l2_ctrl->name);
 	v4l2_ctrl->flags = 0;
 
-	if (!(ctrl->info.flags & UVC_CONTROL_GET_CUR))
+	if (!(ctrl->info.flags & UVC_CTRL_FLAG_GET_CUR))
 		v4l2_ctrl->flags |= V4L2_CTRL_FLAG_WRITE_ONLY;
-	if (!(ctrl->info.flags & UVC_CONTROL_SET_CUR))
+	if (!(ctrl->info.flags & UVC_CTRL_FLAG_SET_CUR))
 		v4l2_ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY;
 
 	if (!ctrl->cached) {
@@ -890,7 +922,7 @@
 			goto done;
 	}
 
-	if (ctrl->info.flags & UVC_CONTROL_GET_DEF) {
+	if (ctrl->info.flags & UVC_CTRL_FLAG_GET_DEF) {
 		v4l2_ctrl->default_value = mapping->get(mapping, UVC_GET_DEF,
 				uvc_ctrl_data(ctrl, UVC_CTRL_DATA_DEF));
 	}
@@ -927,15 +959,15 @@
 		break;
 	}
 
-	if (ctrl->info.flags & UVC_CONTROL_GET_MIN)
+	if (ctrl->info.flags & UVC_CTRL_FLAG_GET_MIN)
 		v4l2_ctrl->minimum = mapping->get(mapping, UVC_GET_MIN,
 				     uvc_ctrl_data(ctrl, UVC_CTRL_DATA_MIN));
 
-	if (ctrl->info.flags & UVC_CONTROL_GET_MAX)
+	if (ctrl->info.flags & UVC_CTRL_FLAG_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)
+	if (ctrl->info.flags & UVC_CTRL_FLAG_GET_RES)
 		v4l2_ctrl->step = mapping->get(mapping, UVC_GET_RES,
 				  uvc_ctrl_data(ctrl, UVC_CTRL_DATA_RES));
 
@@ -983,6 +1015,24 @@
 	}
 
 	menu_info = &mapping->menu_info[query_menu->index];
+
+	if (ctrl->info.flags & UVC_CTRL_FLAG_GET_RES) {
+		s32 bitmap;
+
+		if (!ctrl->cached) {
+			ret = uvc_ctrl_populate_cache(chain, ctrl);
+			if (ret < 0)
+				goto done;
+		}
+
+		bitmap = mapping->get(mapping, UVC_GET_RES,
+				      uvc_ctrl_data(ctrl, UVC_CTRL_DATA_RES));
+		if (!(bitmap & menu_info->value)) {
+			ret = -EINVAL;
+			goto done;
+		}
+	}
+
 	strlcpy(query_menu->name, menu_info->name, sizeof query_menu->name);
 
 done:
@@ -1039,7 +1089,7 @@
 		 * marked as loaded in uvc_ctrl_get/uvc_ctrl_set to prevent
 		 * uvc_ctrl_get from using the cached value.
 		 */
-		if (ctrl->info.flags & UVC_CONTROL_AUTO_UPDATE)
+		if (ctrl->info.flags & UVC_CTRL_FLAG_AUTO_UPDATE)
 			ctrl->loaded = 0;
 
 		if (!ctrl->dirty)
@@ -1094,7 +1144,7 @@
 	int ret;
 
 	ctrl = uvc_find_control(chain, xctrl->id, &mapping);
-	if (ctrl == NULL || (ctrl->info.flags & UVC_CONTROL_GET_CUR) == 0)
+	if (ctrl == NULL || (ctrl->info.flags & UVC_CTRL_FLAG_GET_CUR) == 0)
 		return -EINVAL;
 
 	if (!ctrl->loaded) {
@@ -1136,7 +1186,7 @@
 	int ret;
 
 	ctrl = uvc_find_control(chain, xctrl->id, &mapping);
-	if (ctrl == NULL || (ctrl->info.flags & UVC_CONTROL_SET_CUR) == 0)
+	if (ctrl == NULL || (ctrl->info.flags & UVC_CTRL_FLAG_SET_CUR) == 0)
 		return -EINVAL;
 
 	/* Clamp out of range values. */
@@ -1171,6 +1221,23 @@
 		if (xctrl->value < 0 || xctrl->value >= mapping->menu_count)
 			return -ERANGE;
 		value = mapping->menu_info[xctrl->value].value;
+
+		/* Valid menu indices are reported by the GET_RES request for
+		 * UVC controls that support it.
+		 */
+		if (ctrl->info.flags & UVC_CTRL_FLAG_GET_RES) {
+			if (!ctrl->cached) {
+				ret = uvc_ctrl_populate_cache(chain, ctrl);
+				if (ret < 0)
+					return ret;
+			}
+
+			step = mapping->get(mapping, UVC_GET_RES,
+					uvc_ctrl_data(ctrl, UVC_CTRL_DATA_RES));
+			if (!(step & value))
+				return -ERANGE;
+		}
+
 		break;
 
 	default:
@@ -1183,7 +1250,7 @@
 	 * operation.
 	 */
 	if (!ctrl->loaded && (ctrl->info.size * 8) != mapping->size) {
-		if ((ctrl->info.flags & UVC_CONTROL_GET_CUR) == 0) {
+		if ((ctrl->info.flags & UVC_CTRL_FLAG_GET_CUR) == 0) {
 			memset(uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT),
 				0, ctrl->info.size);
 		} else {
@@ -1230,17 +1297,17 @@
 
 	static const struct uvc_ctrl_fixup fixups[] = {
 		{ { USB_DEVICE(0x046d, 0x08c2) }, 9, 1,
-			UVC_CONTROL_GET_MIN | UVC_CONTROL_GET_MAX |
-			UVC_CONTROL_GET_DEF | UVC_CONTROL_SET_CUR |
-			UVC_CONTROL_AUTO_UPDATE },
+			UVC_CTRL_FLAG_GET_MIN | UVC_CTRL_FLAG_GET_MAX |
+			UVC_CTRL_FLAG_GET_DEF | UVC_CTRL_FLAG_SET_CUR |
+			UVC_CTRL_FLAG_AUTO_UPDATE },
 		{ { USB_DEVICE(0x046d, 0x08cc) }, 9, 1,
-			UVC_CONTROL_GET_MIN | UVC_CONTROL_GET_MAX |
-			UVC_CONTROL_GET_DEF | UVC_CONTROL_SET_CUR |
-			UVC_CONTROL_AUTO_UPDATE },
+			UVC_CTRL_FLAG_GET_MIN | UVC_CTRL_FLAG_GET_MAX |
+			UVC_CTRL_FLAG_GET_DEF | UVC_CTRL_FLAG_SET_CUR |
+			UVC_CTRL_FLAG_AUTO_UPDATE },
 		{ { USB_DEVICE(0x046d, 0x0994) }, 9, 1,
-			UVC_CONTROL_GET_MIN | UVC_CONTROL_GET_MAX |
-			UVC_CONTROL_GET_DEF | UVC_CONTROL_SET_CUR |
-			UVC_CONTROL_AUTO_UPDATE },
+			UVC_CTRL_FLAG_GET_MIN | UVC_CTRL_FLAG_GET_MAX |
+			UVC_CTRL_FLAG_GET_DEF | UVC_CTRL_FLAG_SET_CUR |
+			UVC_CTRL_FLAG_AUTO_UPDATE },
 	};
 
 	unsigned int i;
@@ -1297,21 +1364,23 @@
 		goto done;
 	}
 
-	info->flags = UVC_CONTROL_GET_MIN | UVC_CONTROL_GET_MAX
-		    | UVC_CONTROL_GET_RES | UVC_CONTROL_GET_DEF
-		    | (data[0] & UVC_CONTROL_CAP_GET ? UVC_CONTROL_GET_CUR : 0)
-		    | (data[0] & UVC_CONTROL_CAP_SET ? UVC_CONTROL_SET_CUR : 0)
+	info->flags = UVC_CTRL_FLAG_GET_MIN | UVC_CTRL_FLAG_GET_MAX
+		    | UVC_CTRL_FLAG_GET_RES | UVC_CTRL_FLAG_GET_DEF
+		    | (data[0] & UVC_CONTROL_CAP_GET ?
+		       UVC_CTRL_FLAG_GET_CUR : 0)
+		    | (data[0] & UVC_CONTROL_CAP_SET ?
+		       UVC_CTRL_FLAG_SET_CUR : 0)
 		    | (data[0] & UVC_CONTROL_CAP_AUTOUPDATE ?
-		       UVC_CONTROL_AUTO_UPDATE : 0);
+		       UVC_CTRL_FLAG_AUTO_UPDATE : 0);
 
 	uvc_ctrl_fixup_xu_info(dev, ctrl, info);
 
 	uvc_trace(UVC_TRACE_CONTROL, "XU control %pUl/%u queried: len %u, "
 		  "flags { get %u set %u auto %u }.\n",
 		  info->entity, info->selector, info->size,
-		  (info->flags & UVC_CONTROL_GET_CUR) ? 1 : 0,
-		  (info->flags & UVC_CONTROL_SET_CUR) ? 1 : 0,
-		  (info->flags & UVC_CONTROL_AUTO_UPDATE) ? 1 : 0);
+		  (info->flags & UVC_CTRL_FLAG_GET_CUR) ? 1 : 0,
+		  (info->flags & UVC_CTRL_FLAG_SET_CUR) ? 1 : 0,
+		  (info->flags & UVC_CTRL_FLAG_AUTO_UPDATE) ? 1 : 0);
 
 done:
 	kfree(data);
@@ -1344,32 +1413,33 @@
 }
 
 int uvc_xu_ctrl_query(struct uvc_video_chain *chain,
-	struct uvc_xu_control *xctrl, int set)
+	struct uvc_xu_control_query *xqry)
 {
 	struct uvc_entity *entity;
-	struct uvc_control *ctrl = NULL;
+	struct uvc_control *ctrl;
 	unsigned int i, found = 0;
-	int restore = 0;
-	__u8 *data;
+	__u32 reqflags;
+	__u16 size;
+	__u8 *data = NULL;
 	int ret;
 
 	/* Find the extension unit. */
 	list_for_each_entry(entity, &chain->entities, chain) {
 		if (UVC_ENTITY_TYPE(entity) == UVC_VC_EXTENSION_UNIT &&
-		    entity->id == xctrl->unit)
+		    entity->id == xqry->unit)
 			break;
 	}
 
-	if (entity->id != xctrl->unit) {
+	if (entity->id != xqry->unit) {
 		uvc_trace(UVC_TRACE_CONTROL, "Extension unit %u not found.\n",
-			xctrl->unit);
-		return -EINVAL;
+			xqry->unit);
+		return -ENOENT;
 	}
 
 	/* Find the control and perform delayed initialization if needed. */
 	for (i = 0; i < entity->ncontrols; ++i) {
 		ctrl = &entity->controls[i];
-		if (ctrl->index == xctrl->selector - 1) {
+		if (ctrl->index == xqry->selector - 1) {
 			found = 1;
 			break;
 		}
@@ -1377,8 +1447,8 @@
 
 	if (!found) {
 		uvc_trace(UVC_TRACE_CONTROL, "Control %pUl/%u not found.\n",
-			entity->extension.guidExtensionCode, xctrl->selector);
-		return -EINVAL;
+			entity->extension.guidExtensionCode, xqry->selector);
+		return -ENOENT;
 	}
 
 	if (mutex_lock_interruptible(&chain->ctrl_mutex))
@@ -1390,43 +1460,72 @@
 		goto done;
 	}
 
-	/* Validate control data size. */
-	if (ctrl->info.size != xctrl->size) {
+	/* Validate the required buffer size and flags for the request */
+	reqflags = 0;
+	size = ctrl->info.size;
+
+	switch (xqry->query) {
+	case UVC_GET_CUR:
+		reqflags = UVC_CTRL_FLAG_GET_CUR;
+		break;
+	case UVC_GET_MIN:
+		reqflags = UVC_CTRL_FLAG_GET_MIN;
+		break;
+	case UVC_GET_MAX:
+		reqflags = UVC_CTRL_FLAG_GET_MAX;
+		break;
+	case UVC_GET_DEF:
+		reqflags = UVC_CTRL_FLAG_GET_DEF;
+		break;
+	case UVC_GET_RES:
+		reqflags = UVC_CTRL_FLAG_GET_RES;
+		break;
+	case UVC_SET_CUR:
+		reqflags = UVC_CTRL_FLAG_SET_CUR;
+		break;
+	case UVC_GET_LEN:
+		size = 2;
+		break;
+	case UVC_GET_INFO:
+		size = 1;
+		break;
+	default:
 		ret = -EINVAL;
 		goto done;
 	}
 
-	if ((set && !(ctrl->info.flags & UVC_CONTROL_SET_CUR)) ||
-	    (!set && !(ctrl->info.flags & UVC_CONTROL_GET_CUR))) {
-		ret = -EINVAL;
+	if (size != xqry->size) {
+		ret = -ENOBUFS;
 		goto done;
 	}
 
-	memcpy(uvc_ctrl_data(ctrl, UVC_CTRL_DATA_BACKUP),
-	       uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT),
-	       ctrl->info.size);
-	data = uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT);
-	restore = set;
+	if (reqflags && !(ctrl->info.flags & reqflags)) {
+		ret = -EBADRQC;
+		goto done;
+	}
 
-	if (set && copy_from_user(data, xctrl->data, xctrl->size)) {
+	data = kmalloc(size, GFP_KERNEL);
+	if (data == NULL) {
+		ret = -ENOMEM;
+		goto done;
+	}
+
+	if (xqry->query == UVC_SET_CUR &&
+	    copy_from_user(data, xqry->data, size)) {
 		ret = -EFAULT;
 		goto done;
 	}
 
-	ret = uvc_query_ctrl(chain->dev, set ? UVC_SET_CUR : UVC_GET_CUR,
-			     xctrl->unit, chain->dev->intfnum, xctrl->selector,
-			     data, xctrl->size);
+	ret = uvc_query_ctrl(chain->dev, xqry->query, xqry->unit,
+			     chain->dev->intfnum, xqry->selector, data, size);
 	if (ret < 0)
 		goto done;
 
-	if (!set && copy_to_user(xctrl->data, data, xctrl->size))
+	if (xqry->query != UVC_SET_CUR &&
+	    copy_to_user(xqry->data, data, size))
 		ret = -EFAULT;
 done:
-	if (ret && restore)
-		memcpy(uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT),
-		       uvc_ctrl_data(ctrl, UVC_CTRL_DATA_BACKUP),
-		       xctrl->size);
-
+	kfree(data);
 	mutex_unlock(&chain->ctrl_mutex);
 	return ret;
 }
@@ -1458,7 +1557,7 @@
 			ctrl = &entity->controls[i];
 
 			if (!ctrl->initialized || !ctrl->modified ||
-			    (ctrl->info.flags & UVC_CONTROL_RESTORE) == 0)
+			    (ctrl->info.flags & UVC_CTRL_FLAG_RESTORE) == 0)
 				continue;
 
 			printk(KERN_INFO "restoring control %pUl/%u/%u\n",
diff -druN linux-2.6.39-libre/drivers/media/video/uvc/uvc_driver.c linux-3.0-rc7-libre/drivers/media/video/uvc/uvc_driver.c
--- linux-2.6.39-libre/drivers/media/video/uvc/uvc_driver.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/video/uvc/uvc_driver.c	2011-07-11 19:51:52.000000000 -0400
@@ -84,6 +84,11 @@
 		.fcc		= V4L2_PIX_FMT_YUV420,
 	},
 	{
+		.name		= "YUV 4:2:0 (M420)",
+		.guid		= UVC_GUID_FORMAT_M420,
+		.fcc		= V4L2_PIX_FMT_M420,
+	},
+	{
 		.name		= "YUV 4:2:2 (UYVY)",
 		.guid		= UVC_GUID_FORMAT_UYVY,
 		.fcc		= V4L2_PIX_FMT_UYVY,
@@ -103,6 +108,11 @@
 		.guid		= UVC_GUID_FORMAT_BY8,
 		.fcc		= V4L2_PIX_FMT_SBGGR8,
 	},
+	{
+		.name		= "RGB565",
+		.guid		= UVC_GUID_FORMAT_RGBP,
+		.fcc		= V4L2_PIX_FMT_RGB565,
+	},
 };
 
 /* ------------------------------------------------------------------------
@@ -238,7 +248,7 @@
  * Terminal and unit management
  */
 
-static struct uvc_entity *uvc_entity_by_id(struct uvc_device *dev, int id)
+struct uvc_entity *uvc_entity_by_id(struct uvc_device *dev, int id)
 {
 	struct uvc_entity *entity;
 
@@ -785,9 +795,12 @@
 	struct uvc_entity *entity;
 	unsigned int num_inputs;
 	unsigned int size;
+	unsigned int i;
 
+	extra_size = ALIGN(extra_size, sizeof(*entity->pads));
 	num_inputs = (type & UVC_TERM_OUTPUT) ? num_pads : num_pads - 1;
-	size = sizeof(*entity) + extra_size + num_inputs;
+	size = sizeof(*entity) + extra_size + sizeof(*entity->pads) * num_pads
+	     + num_inputs;
 	entity = kzalloc(size, GFP_KERNEL);
 	if (entity == NULL)
 		return NULL;
@@ -795,8 +808,17 @@
 	entity->id = id;
 	entity->type = type;
 
+	entity->num_links = 0;
+	entity->num_pads = num_pads;
+	entity->pads = ((void *)(entity + 1)) + extra_size;
+
+	for (i = 0; i < num_inputs; ++i)
+		entity->pads[i].flags = MEDIA_PAD_FL_SINK;
+	if (!UVC_ENTITY_IS_OTERM(entity))
+		entity->pads[num_pads-1].flags = MEDIA_PAD_FL_SOURCE;
+
 	entity->bNrInPins = num_inputs;
-	entity->baSourceID = ((__u8 *)entity) + sizeof(*entity) + extra_size;
+	entity->baSourceID = (__u8 *)(&entity->pads[num_pads]);
 
 	return entity;
 }
@@ -1575,6 +1597,13 @@
 	uvc_status_cleanup(dev);
 	uvc_ctrl_cleanup_device(dev);
 
+	if (dev->vdev.dev)
+		v4l2_device_unregister(&dev->vdev);
+#ifdef CONFIG_MEDIA_CONTROLLER
+	if (media_devnode_is_registered(&dev->mdev.devnode))
+		media_device_unregister(&dev->mdev);
+#endif
+
 	list_for_each_safe(p, n, &dev->chains) {
 		struct uvc_video_chain *chain;
 		chain = list_entry(p, struct uvc_video_chain, list);
@@ -1584,6 +1613,13 @@
 	list_for_each_safe(p, n, &dev->entities) {
 		struct uvc_entity *entity;
 		entity = list_entry(p, struct uvc_entity, list);
+#ifdef CONFIG_MEDIA_CONTROLLER
+		uvc_mc_cleanup_entity(entity);
+#endif
+		if (entity->vdev) {
+			video_device_release(entity->vdev);
+			entity->vdev = NULL;
+		}
 		kfree(entity);
 	}
 
@@ -1606,8 +1642,6 @@
 	struct uvc_streaming *stream = video_get_drvdata(vdev);
 	struct uvc_device *dev = stream->dev;
 
-	video_device_release(vdev);
-
 	/* Decrement the registered streams count and delete the device when it
 	 * reaches zero.
 	 */
@@ -1672,7 +1706,7 @@
 	 * unregistered before the reference is released, so we don't need to
 	 * get another one.
 	 */
-	vdev->parent = &dev->intf->dev;
+	vdev->v4l2_dev = &dev->vdev;
 	vdev->fops = &uvc_fops;
 	vdev->release = uvc_release;
 	strlcpy(vdev->name, dev->name, sizeof vdev->name);
@@ -1721,6 +1755,8 @@
 		ret = uvc_register_video(dev, stream);
 		if (ret < 0)
 			return ret;
+
+		term->vdev = stream->vdev;
 	}
 
 	return 0;
@@ -1735,6 +1771,14 @@
 		ret = uvc_register_terms(dev, chain);
 		if (ret < 0)
 			return ret;
+
+#ifdef CONFIG_MEDIA_CONTROLLER
+		ret = uvc_mc_register_entities(chain);
+		if (ret < 0) {
+			uvc_printk(KERN_INFO, "Failed to register entites "
+				"(%d).\n", ret);
+		}
+#endif
 	}
 
 	return 0;
@@ -1804,6 +1848,24 @@
 			"linux-uvc-devel mailing list.\n");
 	}
 
+	/* Register the media and V4L2 devices. */
+#ifdef CONFIG_MEDIA_CONTROLLER
+	dev->mdev.dev = &intf->dev;
+	strlcpy(dev->mdev.model, dev->name, sizeof(dev->mdev.model));
+	if (udev->serial)
+		strlcpy(dev->mdev.serial, udev->serial,
+			sizeof(dev->mdev.serial));
+	strcpy(dev->mdev.bus_info, udev->devpath);
+	dev->mdev.hw_revision = le16_to_cpu(udev->descriptor.bcdDevice);
+	dev->mdev.driver_version = DRIVER_VERSION_NUMBER;
+	if (media_device_register(&dev->mdev) < 0)
+		goto error;
+
+	dev->vdev.mdev = &dev->mdev;
+#endif
+	if (v4l2_device_register(&intf->dev, &dev->vdev) < 0)
+		goto error;
+
 	/* Initialize controls. */
 	if (uvc_ctrl_init_device(dev) < 0)
 		goto error;
@@ -1812,7 +1874,7 @@
 	if (uvc_scan_device(dev) < 0)
 		goto error;
 
-	/* Register video devices. */
+	/* Register video device nodes. */
 	if (uvc_register_chains(dev) < 0)
 		goto error;
 
@@ -2077,6 +2139,15 @@
 	  .bInterfaceSubClass	= 1,
 	  .bInterfaceProtocol	= 0,
 	  .driver_info		= UVC_QUIRK_STREAM_NO_FID },
+	/* Hercules Classic Silver */
+	{ .match_flags		= USB_DEVICE_ID_MATCH_DEVICE
+				| USB_DEVICE_ID_MATCH_INT_INFO,
+	  .idVendor		= 0x06f8,
+	  .idProduct		= 0x300c,
+	  .bInterfaceClass	= USB_CLASS_VIDEO,
+	  .bInterfaceSubClass	= 1,
+	  .bInterfaceProtocol	= 0,
+	  .driver_info		= UVC_QUIRK_FIX_BANDWIDTH },
 	/* ViMicro Vega */
 	{ .match_flags		= USB_DEVICE_ID_MATCH_DEVICE
 				| USB_DEVICE_ID_MATCH_INT_INFO,
@@ -2123,6 +2194,15 @@
 	  .bInterfaceSubClass	= 1,
 	  .bInterfaceProtocol	= 0,
 	  .driver_info		= UVC_QUIRK_STREAM_NO_FID },
+	/* JMicron USB2.0 XGA WebCam */
+	{ .match_flags		= USB_DEVICE_ID_MATCH_DEVICE
+				| USB_DEVICE_ID_MATCH_INT_INFO,
+	  .idVendor		= 0x152d,
+	  .idProduct		= 0x0310,
+	  .bInterfaceClass	= USB_CLASS_VIDEO,
+	  .bInterfaceSubClass	= 1,
+	  .bInterfaceProtocol	= 0,
+	  .driver_info		= UVC_QUIRK_PROBE_MINMAX },
 	/* Syntek (HP Spartan) */
 	{ .match_flags		= USB_DEVICE_ID_MATCH_DEVICE
 				| USB_DEVICE_ID_MATCH_INT_INFO,
diff -druN linux-2.6.39-libre/drivers/media/video/uvc/uvc_entity.c linux-3.0-rc7-libre/drivers/media/video/uvc/uvc_entity.c
--- linux-2.6.39-libre/drivers/media/video/uvc/uvc_entity.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/media/video/uvc/uvc_entity.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,126 @@
+/*
+ *      uvc_entity.c  --  USB Video Class driver
+ *
+ *      Copyright (C) 2005-2011
+ *          Laurent Pinchart (laurent.pinchart@ideasonboard.com)
+ *
+ *      This program is free software; you can redistribute it and/or modify
+ *      it under the terms of the GNU General Public License as published by
+ *      the Free Software Foundation; either version 2 of the License, or
+ *      (at your option) any later version.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/videodev2.h>
+
+#include <media/v4l2-common.h>
+
+#include "uvcvideo.h"
+
+/* ------------------------------------------------------------------------
+ * Video subdevices registration and unregistration
+ */
+
+static int uvc_mc_register_entity(struct uvc_video_chain *chain,
+	struct uvc_entity *entity)
+{
+	const u32 flags = MEDIA_LNK_FL_ENABLED | MEDIA_LNK_FL_IMMUTABLE;
+	struct media_entity *sink;
+	unsigned int i;
+	int ret;
+
+	sink = (UVC_ENTITY_TYPE(entity) == UVC_TT_STREAMING)
+	     ? (entity->vdev ? &entity->vdev->entity : NULL)
+	     : &entity->subdev.entity;
+	if (sink == NULL)
+		return 0;
+
+	for (i = 0; i < entity->num_pads; ++i) {
+		struct media_entity *source;
+		struct uvc_entity *remote;
+		u8 remote_pad;
+
+		if (!(entity->pads[i].flags & MEDIA_PAD_FL_SINK))
+			continue;
+
+		remote = uvc_entity_by_id(chain->dev, entity->baSourceID[i]);
+		if (remote == NULL)
+			return -EINVAL;
+
+		source = (UVC_ENTITY_TYPE(remote) != UVC_TT_STREAMING)
+		       ? (remote->vdev ? &remote->vdev->entity : NULL)
+		       : &remote->subdev.entity;
+		if (source == NULL)
+			continue;
+
+		remote_pad = remote->num_pads - 1;
+		ret = media_entity_create_link(source, remote_pad,
+					       sink, i, flags);
+		if (ret < 0)
+			return ret;
+	}
+
+	if (UVC_ENTITY_TYPE(entity) == UVC_TT_STREAMING)
+		return 0;
+
+	return v4l2_device_register_subdev(&chain->dev->vdev, &entity->subdev);
+}
+
+static struct v4l2_subdev_ops uvc_subdev_ops = {
+};
+
+void uvc_mc_cleanup_entity(struct uvc_entity *entity)
+{
+	if (UVC_ENTITY_TYPE(entity) != UVC_TT_STREAMING)
+		media_entity_cleanup(&entity->subdev.entity);
+	else if (entity->vdev != NULL)
+		media_entity_cleanup(&entity->vdev->entity);
+}
+
+static int uvc_mc_init_entity(struct uvc_entity *entity)
+{
+	int ret;
+
+	if (UVC_ENTITY_TYPE(entity) != UVC_TT_STREAMING) {
+		v4l2_subdev_init(&entity->subdev, &uvc_subdev_ops);
+		strlcpy(entity->subdev.name, entity->name,
+			sizeof(entity->subdev.name));
+
+		ret = media_entity_init(&entity->subdev.entity,
+					entity->num_pads, entity->pads, 0);
+	} else if (entity->vdev != NULL) {
+		ret = media_entity_init(&entity->vdev->entity,
+					entity->num_pads, entity->pads, 0);
+	} else
+		ret = 0;
+
+	return ret;
+}
+
+int uvc_mc_register_entities(struct uvc_video_chain *chain)
+{
+	struct uvc_entity *entity;
+	int ret;
+
+	list_for_each_entry(entity, &chain->entities, chain) {
+		ret = uvc_mc_init_entity(entity);
+		if (ret < 0) {
+			uvc_printk(KERN_INFO, "Failed to initialize entity for "
+				   "entity %u\n", entity->id);
+			return ret;
+		}
+	}
+
+	list_for_each_entry(entity, &chain->entities, chain) {
+		ret = uvc_mc_register_entity(chain, entity);
+		if (ret < 0) {
+			uvc_printk(KERN_INFO, "Failed to register entity for "
+				   "entity %u\n", entity->id);
+			return ret;
+		}
+	}
+
+	return 0;
+}
diff -druN linux-2.6.39-libre/drivers/media/video/uvc/uvc_queue.c linux-3.0-rc7-libre/drivers/media/video/uvc/uvc_queue.c
--- linux-2.6.39-libre/drivers/media/video/uvc/uvc_queue.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/video/uvc/uvc_queue.c	2011-07-11 19:51:52.000000000 -0400
@@ -104,6 +104,8 @@
 	}
 
 	if (queue->count) {
+		uvc_queue_cancel(queue, 0);
+		INIT_LIST_HEAD(&queue->mainqueue);
 		vfree(queue->mem);
 		queue->count = 0;
 	}
@@ -424,7 +426,7 @@
 			break;
 	}
 
-	if (i == queue->count || size != queue->buf_size) {
+	if (i == queue->count || PAGE_ALIGN(size) != queue->buf_size) {
 		ret = -EINVAL;
 		goto done;
 	}
@@ -436,6 +438,7 @@
 	vma->vm_flags |= VM_IO;
 
 	addr = (unsigned long)queue->mem + buffer->buf.m.offset;
+#ifdef CONFIG_MMU
 	while (size > 0) {
 		page = vmalloc_to_page((void *)addr);
 		if ((ret = vm_insert_page(vma, start, page)) < 0)
@@ -445,6 +448,7 @@
 		addr += PAGE_SIZE;
 		size -= PAGE_SIZE;
 	}
+#endif
 
 	vma->vm_ops = &uvc_vm_ops;
 	vma->vm_private_data = buffer;
@@ -488,6 +492,36 @@
 	return mask;
 }
 
+#ifndef CONFIG_MMU
+/*
+ * Get unmapped area.
+ *
+ * NO-MMU arch need this function to make mmap() work correctly.
+ */
+unsigned long uvc_queue_get_unmapped_area(struct uvc_video_queue *queue,
+		unsigned long pgoff)
+{
+	struct uvc_buffer *buffer;
+	unsigned int i;
+	unsigned long ret;
+
+	mutex_lock(&queue->mutex);
+	for (i = 0; i < queue->count; ++i) {
+		buffer = &queue->buffer[i];
+		if ((buffer->buf.m.offset >> PAGE_SHIFT) == pgoff)
+			break;
+	}
+	if (i == queue->count) {
+		ret = -EINVAL;
+		goto done;
+	}
+	ret = (unsigned long)queue->mem + buffer->buf.m.offset;
+done:
+	mutex_unlock(&queue->mutex);
+	return ret;
+}
+#endif
+
 /*
  * Enable or disable the video buffers queue.
  *
diff -druN linux-2.6.39-libre/drivers/media/video/uvc/uvc_v4l2.c linux-3.0-rc7-libre/drivers/media/video/uvc/uvc_v4l2.c
--- linux-2.6.39-libre/drivers/media/video/uvc/uvc_v4l2.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/video/uvc/uvc_v4l2.c	2011-07-11 19:51:52.000000000 -0400
@@ -538,6 +538,20 @@
 	return 0;
 }
 
+static void uvc_v4l2_ioctl_warn(void)
+{
+	static int warned;
+
+	if (warned)
+		return;
+
+	uvc_printk(KERN_INFO, "Deprecated UVCIOC_CTRL_{ADD,MAP_OLD,GET,SET} "
+		   "ioctls will be removed in 2.6.42.\n");
+	uvc_printk(KERN_INFO, "See http://www.ideasonboard.org/uvc/upgrade/ "
+		   "for upgrade instructions.\n");
+	warned = 1;
+}
+
 static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
 {
 	struct video_device *vdev = video_devdata(file);
@@ -1018,21 +1032,40 @@
 		uvc_trace(UVC_TRACE_IOCTL, "Unsupported ioctl 0x%08x\n", cmd);
 		return -EINVAL;
 
-	/* Dynamic controls. */
-	case UVCIOC_CTRL_ADD:
-		/* Legacy ioctl, kept for API compatibility reasons */
+	/* Dynamic controls. UVCIOC_CTRL_ADD, UVCIOC_CTRL_MAP_OLD,
+	 * UVCIOC_CTRL_GET and UVCIOC_CTRL_SET are deprecated and scheduled for
+	 * removal in 2.6.42.
+	 */
+	case __UVCIOC_CTRL_ADD:
+		uvc_v4l2_ioctl_warn();
 		return -EEXIST;
 
-	case UVCIOC_CTRL_MAP_OLD:
+	case __UVCIOC_CTRL_MAP_OLD:
+		uvc_v4l2_ioctl_warn();
+	case __UVCIOC_CTRL_MAP:
 	case UVCIOC_CTRL_MAP:
 		return uvc_ioctl_ctrl_map(chain, arg,
-					  cmd == UVCIOC_CTRL_MAP_OLD);
+					  cmd == __UVCIOC_CTRL_MAP_OLD);
 
-	case UVCIOC_CTRL_GET:
-		return uvc_xu_ctrl_query(chain, arg, 0);
+	case __UVCIOC_CTRL_GET:
+	case __UVCIOC_CTRL_SET:
+	{
+		struct uvc_xu_control *xctrl = arg;
+		struct uvc_xu_control_query xqry = {
+			.unit		= xctrl->unit,
+			.selector	= xctrl->selector,
+			.query		= cmd == __UVCIOC_CTRL_GET
+					? UVC_GET_CUR : UVC_SET_CUR,
+			.size		= xctrl->size,
+			.data		= xctrl->data,
+		};
 
-	case UVCIOC_CTRL_SET:
-		return uvc_xu_ctrl_query(chain, arg, 1);
+		uvc_v4l2_ioctl_warn();
+		return uvc_xu_ctrl_query(chain, &xqry);
+	}
+
+	case UVCIOC_CTRL_QUERY:
+		return uvc_xu_ctrl_query(chain, arg);
 
 	default:
 		uvc_trace(UVC_TRACE_IOCTL, "Unknown ioctl 0x%08x\n", cmd);
@@ -1081,6 +1114,20 @@
 	return uvc_queue_poll(&stream->queue, file, wait);
 }
 
+#ifndef CONFIG_MMU
+static unsigned long uvc_v4l2_get_unmapped_area(struct file *file,
+		unsigned long addr, unsigned long len, unsigned long pgoff,
+		unsigned long flags)
+{
+	struct uvc_fh *handle = file->private_data;
+	struct uvc_streaming *stream = handle->stream;
+
+	uvc_trace(UVC_TRACE_CALLS, "uvc_v4l2_get_unmapped_area\n");
+
+	return uvc_queue_get_unmapped_area(&stream->queue, pgoff);
+}
+#endif
+
 const struct v4l2_file_operations uvc_fops = {
 	.owner		= THIS_MODULE,
 	.open		= uvc_v4l2_open,
@@ -1089,5 +1136,8 @@
 	.read		= uvc_v4l2_read,
 	.mmap		= uvc_v4l2_mmap,
 	.poll		= uvc_v4l2_poll,
+#ifndef CONFIG_MMU
+	.get_unmapped_area = uvc_v4l2_get_unmapped_area,
+#endif
 };
 
diff -druN linux-2.6.39-libre/drivers/media/video/uvc/uvc_video.c linux-3.0-rc7-libre/drivers/media/video/uvc/uvc_video.c
--- linux-2.6.39-libre/drivers/media/video/uvc/uvc_video.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/video/uvc/uvc_video.c	2011-07-11 19:51:52.000000000 -0400
@@ -1255,8 +1255,10 @@
 
 	/* Commit the streaming parameters. */
 	ret = uvc_commit_video(stream, &stream->ctrl);
-	if (ret < 0)
+	if (ret < 0) {
+		uvc_queue_enable(&stream->queue, 0);
 		return ret;
+	}
 
 	return uvc_init_video(stream, GFP_KERNEL);
 }
diff -druN linux-2.6.39-libre/drivers/media/video/uvc/uvcvideo.h linux-3.0-rc7-libre/drivers/media/video/uvc/uvcvideo.h
--- linux-2.6.39-libre/drivers/media/video/uvc/uvcvideo.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/video/uvc/uvcvideo.h	2011-07-11 19:51:52.000000000 -0400
@@ -4,6 +4,14 @@
 #include <linux/kernel.h>
 #include <linux/videodev2.h>
 
+#ifndef __KERNEL__
+/*
+ * This header provides binary compatibility with applications using the private
+ * uvcvideo API. This API is deprecated and will be removed in 2.6.42.
+ * Applications should be recompiled against the public linux/uvcvideo.h header.
+ */
+#warn "The uvcvideo.h header is deprecated, use linux/uvcvideo.h instead."
+
 /*
  * Dynamic controls
  */
@@ -23,32 +31,18 @@
 #define UVC_CONTROL_GET_MAX	(1 << 3)
 #define UVC_CONTROL_GET_RES	(1 << 4)
 #define UVC_CONTROL_GET_DEF	(1 << 5)
-/* Control should be saved at suspend and restored at resume. */
 #define UVC_CONTROL_RESTORE	(1 << 6)
-/* Control can be updated by the camera. */
 #define UVC_CONTROL_AUTO_UPDATE	(1 << 7)
 
 #define UVC_CONTROL_GET_RANGE	(UVC_CONTROL_GET_CUR | UVC_CONTROL_GET_MIN | \
 				 UVC_CONTROL_GET_MAX | UVC_CONTROL_GET_RES | \
 				 UVC_CONTROL_GET_DEF)
 
-struct uvc_xu_control_info {
-	__u8 entity[16];
-	__u8 index;
-	__u8 selector;
-	__u16 size;
-	__u32 flags;
-};
-
 struct uvc_menu_info {
 	__u32 value;
 	__u8 name[32];
 };
 
-struct uvc_xu_control_mapping_old {
-	__u8 reserved[64];
-};
-
 struct uvc_xu_control_mapping {
 	__u32 id;
 	__u8 name[32];
@@ -57,7 +51,7 @@
 
 	__u8 size;
 	__u8 offset;
-	enum v4l2_ctrl_type v4l2_type;
+	__u32 v4l2_type;
 	__u32 data_type;
 
 	struct uvc_menu_info __user *menu_info;
@@ -66,6 +60,20 @@
 	__u32 reserved[4];
 };
 
+#endif
+
+struct uvc_xu_control_info {
+	__u8 entity[16];
+	__u8 index;
+	__u8 selector;
+	__u16 size;
+	__u32 flags;
+};
+
+struct uvc_xu_control_mapping_old {
+	__u8 reserved[64];
+};
+
 struct uvc_xu_control {
 	__u8 unit;
 	__u8 selector;
@@ -73,16 +81,28 @@
 	__u8 __user *data;
 };
 
+#ifndef __KERNEL__
 #define UVCIOC_CTRL_ADD		_IOW('U', 1, struct uvc_xu_control_info)
 #define UVCIOC_CTRL_MAP_OLD	_IOWR('U', 2, struct uvc_xu_control_mapping_old)
 #define UVCIOC_CTRL_MAP		_IOWR('U', 2, struct uvc_xu_control_mapping)
 #define UVCIOC_CTRL_GET		_IOWR('U', 3, struct uvc_xu_control)
 #define UVCIOC_CTRL_SET		_IOW('U', 4, struct uvc_xu_control)
+#else
+#define __UVCIOC_CTRL_ADD	_IOW('U', 1, struct uvc_xu_control_info)
+#define __UVCIOC_CTRL_MAP_OLD	_IOWR('U', 2, struct uvc_xu_control_mapping_old)
+#define __UVCIOC_CTRL_MAP	_IOWR('U', 2, struct uvc_xu_control_mapping)
+#define __UVCIOC_CTRL_GET	_IOWR('U', 3, struct uvc_xu_control)
+#define __UVCIOC_CTRL_SET	_IOW('U', 4, struct uvc_xu_control)
+#endif
 
 #ifdef __KERNEL__
 
 #include <linux/poll.h>
+#include <linux/usb.h>
 #include <linux/usb/video.h>
+#include <linux/uvcvideo.h>
+#include <media/media-device.h>
+#include <media/v4l2-device.h>
 
 /* --------------------------------------------------------------------------
  * UVC constants
@@ -152,13 +172,19 @@
 #define UVC_GUID_FORMAT_BY8 \
 	{ 'B',  'Y',  '8',  ' ', 0x00, 0x00, 0x10, 0x00, \
 	 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}
+#define UVC_GUID_FORMAT_RGBP \
+	{ 'R',  'G',  'B',  'P', 0x00, 0x00, 0x10, 0x00, \
+	 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}
+#define UVC_GUID_FORMAT_M420 \
+	{ 'M',  '4',  '2',  '0', 0x00, 0x00, 0x10, 0x00, \
+	 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}
 
 /* ------------------------------------------------------------------------
  * Driver specific constants.
  */
 
-#define DRIVER_VERSION_NUMBER	KERNEL_VERSION(1, 0, 0)
-#define DRIVER_VERSION		"v1.0.0"
+#define DRIVER_VERSION_NUMBER	KERNEL_VERSION(1, 1, 0)
+#define DRIVER_VERSION		"v1.1.0"
 
 /* Number of isochronous URBs. */
 #define UVC_URBS		5
@@ -278,6 +304,13 @@
 	__u16 type;
 	char name[64];
 
+	/* Media controller-related fields. */
+	struct video_device *vdev;
+	struct v4l2_subdev subdev;
+	unsigned int num_pads;
+	unsigned int num_links;
+	struct media_pad *pads;
+
 	union {
 		struct {
 			__u16 wObjectiveFocalLengthMin;
@@ -481,6 +514,10 @@
 	atomic_t nmappings;
 
 	/* Video control interface */
+#ifdef CONFIG_MEDIA_CONTROLLER
+	struct media_device mdev;
+#endif
+	struct v4l2_device vdev;
 	__u16 uvc_version;
 	__u32 clock_frequency;
 
@@ -560,6 +597,8 @@
 /* Core driver */
 extern struct uvc_driver uvc_driver;
 
+extern struct uvc_entity *uvc_entity_by_id(struct uvc_device *dev, int id);
+
 /* Video buffers queue management. */
 extern void uvc_queue_init(struct uvc_video_queue *queue,
 		enum v4l2_buf_type type, int drop_corrupted);
@@ -580,6 +619,10 @@
 		struct vm_area_struct *vma);
 extern unsigned int uvc_queue_poll(struct uvc_video_queue *queue,
 		struct file *file, poll_table *wait);
+#ifndef CONFIG_MMU
+extern unsigned long uvc_queue_get_unmapped_area(struct uvc_video_queue *queue,
+		unsigned long pgoff);
+#endif
 extern int uvc_queue_allocated(struct uvc_video_queue *queue);
 static inline int uvc_queue_streaming(struct uvc_video_queue *queue)
 {
@@ -589,6 +632,10 @@
 /* V4L2 interface */
 extern const struct v4l2_file_operations uvc_fops;
 
+/* Media controller */
+extern int uvc_mc_register_entities(struct uvc_video_chain *chain);
+extern void uvc_mc_cleanup_entity(struct uvc_entity *entity);
+
 /* Video */
 extern int uvc_video_init(struct uvc_streaming *stream);
 extern int uvc_video_suspend(struct uvc_streaming *stream);
@@ -638,7 +685,7 @@
 		struct v4l2_ext_control *xctrl);
 
 extern int uvc_xu_ctrl_query(struct uvc_video_chain *chain,
-		struct uvc_xu_control *ctrl, int set);
+		struct uvc_xu_control_query *xqry);
 
 /* Utility functions */
 extern void uvc_simplify_fraction(uint32_t *numerator, uint32_t *denominator,
@@ -655,4 +702,3 @@
 #endif /* __KERNEL__ */
 
 #endif
-
diff -druN linux-2.6.39-libre/drivers/media/video/v4l2-dev.c linux-3.0-rc7-libre/drivers/media/video/v4l2-dev.c
--- linux-2.6.39-libre/drivers/media/video/v4l2-dev.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/video/v4l2-dev.c	2011-07-11 19:51:52.000000000 -0400
@@ -167,6 +167,12 @@
 
 	mutex_unlock(&videodev_lock);
 
+#if defined(CONFIG_MEDIA_CONTROLLER)
+	if (vdev->v4l2_dev && vdev->v4l2_dev->mdev &&
+	    vdev->vfl_type != VFL_TYPE_SUBDEV)
+		media_device_unregister_entity(&vdev->entity);
+#endif
+
 	/* Release video_device and perform other
 	   cleanups as needed. */
 	vdev->release(vdev);
@@ -352,6 +358,23 @@
 	return ret;
 }
 
+#ifdef CONFIG_MMU
+#define v4l2_get_unmapped_area NULL
+#else
+static unsigned long v4l2_get_unmapped_area(struct file *filp,
+		unsigned long addr, unsigned long len, unsigned long pgoff,
+		unsigned long flags)
+{
+	struct video_device *vdev = video_devdata(filp);
+
+	if (!vdev->fops->get_unmapped_area)
+		return -ENOSYS;
+	if (!video_is_registered(vdev))
+		return -ENODEV;
+	return vdev->fops->get_unmapped_area(filp, addr, len, pgoff, flags);
+}
+#endif
+
 static int v4l2_mmap(struct file *filp, struct vm_area_struct *vm)
 {
 	struct video_device *vdev = video_devdata(filp);
@@ -372,9 +395,6 @@
 static int v4l2_open(struct inode *inode, struct file *filp)
 {
 	struct video_device *vdev;
-#if defined(CONFIG_MEDIA_CONTROLLER)
-	struct media_entity *entity = NULL;
-#endif
 	int ret = 0;
 
 	/* Check if the video device is available */
@@ -388,17 +408,6 @@
 	/* and increase the device refcount */
 	video_get(vdev);
 	mutex_unlock(&videodev_lock);
-#if defined(CONFIG_MEDIA_CONTROLLER)
-	if (vdev->v4l2_dev && vdev->v4l2_dev->mdev &&
-	    vdev->vfl_type != VFL_TYPE_SUBDEV) {
-		entity = media_entity_get(&vdev->entity);
-		if (!entity) {
-			ret = -EBUSY;
-			video_put(vdev);
-			return ret;
-		}
-	}
-#endif
 	if (vdev->fops->open) {
 		if (vdev->lock && mutex_lock_interruptible(vdev->lock)) {
 			ret = -ERESTARTSYS;
@@ -414,14 +423,8 @@
 
 err:
 	/* decrease the refcount in case of an error */
-	if (ret) {
-#if defined(CONFIG_MEDIA_CONTROLLER)
-		if (vdev->v4l2_dev && vdev->v4l2_dev->mdev &&
-		    vdev->vfl_type != VFL_TYPE_SUBDEV)
-			media_entity_put(entity);
-#endif
+	if (ret)
 		video_put(vdev);
-	}
 	return ret;
 }
 
@@ -438,11 +441,6 @@
 		if (vdev->lock)
 			mutex_unlock(vdev->lock);
 	}
-#if defined(CONFIG_MEDIA_CONTROLLER)
-	if (vdev->v4l2_dev && vdev->v4l2_dev->mdev &&
-	    vdev->vfl_type != VFL_TYPE_SUBDEV)
-		media_entity_put(&vdev->entity);
-#endif
 	/* decrease the refcount unconditionally since the release()
 	   return value is ignored. */
 	video_put(vdev);
@@ -454,6 +452,7 @@
 	.read = v4l2_read,
 	.write = v4l2_write,
 	.open = v4l2_open,
+	.get_unmapped_area = v4l2_get_unmapped_area,
 	.mmap = v4l2_mmap,
 	.unlocked_ioctl = v4l2_ioctl,
 #ifdef CONFIG_COMPAT
@@ -736,12 +735,6 @@
 	if (!vdev || !video_is_registered(vdev))
 		return;
 
-#if defined(CONFIG_MEDIA_CONTROLLER)
-	if (vdev->v4l2_dev && vdev->v4l2_dev->mdev &&
-	    vdev->vfl_type != VFL_TYPE_SUBDEV)
-		media_device_unregister_entity(&vdev->entity);
-#endif
-
 	mutex_lock(&videodev_lock);
 	/* This must be in a critical section to prevent a race with v4l2_open.
 	 * Once this bit has been cleared video_get may never be called again.
diff -druN linux-2.6.39-libre/drivers/media/video/v4l2-ioctl.c linux-3.0-rc7-libre/drivers/media/video/v4l2-ioctl.c
--- linux-2.6.39-libre/drivers/media/video/v4l2-ioctl.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/video/v4l2-ioctl.c	2011-07-11 19:51:52.000000000 -0400
@@ -1822,6 +1822,8 @@
 		if (!ops->vidioc_g_tuner)
 			break;
 
+		p->type = (vfd->vfl_type == VFL_TYPE_RADIO) ?
+			V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
 		ret = ops->vidioc_g_tuner(file, fh, p);
 		if (!ret)
 			dbgarg(cmd, "index=%d, name=%s, type=%d, "
@@ -1840,6 +1842,8 @@
 
 		if (!ops->vidioc_s_tuner)
 			break;
+		p->type = (vfd->vfl_type == VFL_TYPE_RADIO) ?
+			V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
 		dbgarg(cmd, "index=%d, name=%s, type=%d, "
 				"capability=0x%x, rangelow=%d, "
 				"rangehigh=%d, signal=%d, afc=%d, "
@@ -1858,6 +1862,8 @@
 		if (!ops->vidioc_g_frequency)
 			break;
 
+		p->type = (vfd->vfl_type == VFL_TYPE_RADIO) ?
+			V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
 		ret = ops->vidioc_g_frequency(file, fh, p);
 		if (!ret)
 			dbgarg(cmd, "tuner=%d, type=%d, frequency=%d\n",
@@ -1940,13 +1946,19 @@
 	case VIDIOC_S_HW_FREQ_SEEK:
 	{
 		struct v4l2_hw_freq_seek *p = arg;
+		enum v4l2_tuner_type type;
 
 		if (!ops->vidioc_s_hw_freq_seek)
 			break;
+		type = (vfd->vfl_type == VFL_TYPE_RADIO) ?
+			V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
 		dbgarg(cmd,
-			"tuner=%d, type=%d, seek_upward=%d, wrap_around=%d\n",
-			p->tuner, p->type, p->seek_upward, p->wrap_around);
-		ret = ops->vidioc_s_hw_freq_seek(file, fh, p);
+			"tuner=%u, type=%u, seek_upward=%u, wrap_around=%u, spacing=%u\n",
+			p->tuner, p->type, p->seek_upward, p->wrap_around, p->spacing);
+		if (p->type != type)
+			ret = -EINVAL;
+		else
+			ret = ops->vidioc_s_hw_freq_seek(file, fh, p);
 		break;
 	}
 	case VIDIOC_ENUM_FRAMESIZES:
diff -druN linux-2.6.39-libre/drivers/media/video/via-camera.c linux-3.0-rc7-libre/drivers/media/video/via-camera.c
--- linux-2.6.39-libre/drivers/media/video/via-camera.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/video/via-camera.c	2011-07-11 19:51:52.000000000 -0400
@@ -29,6 +29,7 @@
 
 #include "via-camera.h"
 
+MODULE_ALIAS("platform:viafb-camera");
 MODULE_AUTHOR("Jonathan Corbet <corbet@lwn.net>");
 MODULE_DESCRIPTION("VIA framebuffer-based camera controller driver");
 MODULE_LICENSE("GPL");
diff -druN linux-2.6.39-libre/drivers/media/video/videobuf2-core.c linux-3.0-rc7-libre/drivers/media/video/videobuf2-core.c
--- linux-2.6.39-libre/drivers/media/video/videobuf2-core.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/video/videobuf2-core.c	2011-07-11 19:51:52.000000000 -0400
@@ -492,13 +492,6 @@
 		return -EINVAL;
 	}
 
-	/*
-	 * If the same number of buffers and memory access method is requested
-	 * then return immediately.
-	 */
-	if (q->memory == req->memory && req->count == q->num_buffers)
-		return 0;
-
 	if (req->count == 0 || q->num_buffers != 0 || q->memory != req->memory) {
 		/*
 		 * We already have buffers allocated, so first check if they
@@ -539,9 +532,9 @@
 	/* Finally, allocate buffers and video memory */
 	ret = __vb2_queue_alloc(q, req->memory, num_buffers, num_planes,
 				plane_sizes);
-	if (ret < 0) {
-		dprintk(1, "Memory allocation failed with error: %d\n", ret);
-		return ret;
+	if (ret == 0) {
+		dprintk(1, "Memory allocation failed\n");
+		return -ENOMEM;
 	}
 
 	/*
@@ -1196,6 +1189,7 @@
 	 * has not already dequeued before initiating cancel.
 	 */
 	INIT_LIST_HEAD(&q->done_list);
+	atomic_set(&q->queued_count, 0);
 	wake_up_all(&q->done_wq);
 
 	/*
diff -druN linux-2.6.39-libre/drivers/media/video/videobuf2-dma-sg.c linux-3.0-rc7-libre/drivers/media/video/videobuf2-dma-sg.c
--- linux-2.6.39-libre/drivers/media/video/videobuf2-dma-sg.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/video/videobuf2-dma-sg.c	2011-07-11 19:51:52.000000000 -0400
@@ -62,7 +62,7 @@
 		goto fail_pages_array_alloc;
 
 	for (i = 0; i < buf->sg_desc.num_pages; ++i) {
-		buf->pages[i] = alloc_page(GFP_KERNEL | __GFP_ZERO);
+		buf->pages[i] = alloc_page(GFP_KERNEL | __GFP_ZERO | __GFP_NOWARN);
 		if (NULL == buf->pages[i])
 			goto fail_pages_alloc;
 		sg_set_page(&buf->sg_desc.sglist[i],
diff -druN linux-2.6.39-libre/drivers/media/video/zoran/zoran_card.c linux-3.0-rc7-libre/drivers/media/video/zoran/zoran_card.c
--- linux-2.6.39-libre/drivers/media/video/zoran/zoran_card.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/media/video/zoran/zoran_card.c	2011-07-11 19:51:52.000000000 -0400
@@ -64,14 +64,6 @@
 module_param_array(card, int, NULL, 0444);
 MODULE_PARM_DESC(card, "Card type");
 
-static int encoder[BUZ_MAX] = { [0 ... (BUZ_MAX-1)] = -1 };
-module_param_array(encoder, int, NULL, 0444);
-MODULE_PARM_DESC(encoder, "Video encoder chip");
-
-static int decoder[BUZ_MAX] = { [0 ... (BUZ_MAX-1)] = -1 };
-module_param_array(decoder, int, NULL, 0444);
-MODULE_PARM_DESC(decoder, "Video decoder chip");
-
 /*
    The video mem address of the video card.
    The driver has a little database for some videocards
@@ -1230,7 +1222,7 @@
 	mutex_init(&zr->other_lock);
 	if (pci_enable_device(pdev))
 		goto zr_unreg;
-	pci_read_config_byte(zr->pci_dev, PCI_CLASS_REVISION, &zr->revision);
+	zr->revision = zr->pci_dev->revision;
 
 	dprintk(1,
 		KERN_INFO
diff -druN linux-2.6.39-libre/drivers/message/fusion/mptbase.c linux-3.0-rc7-libre/drivers/message/fusion/mptbase.c
--- linux-2.6.39-libre/drivers/message/fusion/mptbase.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/message/fusion/mptbase.c	2011-07-11 19:51:52.000000000 -0400
@@ -83,19 +83,18 @@
 
 static int mpt_msi_enable_spi;
 module_param(mpt_msi_enable_spi, int, 0);
-MODULE_PARM_DESC(mpt_msi_enable_spi, " Enable MSI Support for SPI \
-		controllers (default=0)");
+MODULE_PARM_DESC(mpt_msi_enable_spi,
+		 " Enable MSI Support for SPI controllers (default=0)");
 
 static int mpt_msi_enable_fc;
 module_param(mpt_msi_enable_fc, int, 0);
-MODULE_PARM_DESC(mpt_msi_enable_fc, " Enable MSI Support for FC \
-		controllers (default=0)");
+MODULE_PARM_DESC(mpt_msi_enable_fc,
+		 " Enable MSI Support for FC controllers (default=0)");
 
 static int mpt_msi_enable_sas;
 module_param(mpt_msi_enable_sas, int, 0);
-MODULE_PARM_DESC(mpt_msi_enable_sas, " Enable MSI Support for SAS \
-		controllers (default=0)");
-
+MODULE_PARM_DESC(mpt_msi_enable_sas,
+		 " Enable MSI Support for SAS controllers (default=0)");
 
 static int mpt_channel_mapping;
 module_param(mpt_channel_mapping, int, 0);
@@ -105,15 +104,14 @@
 static int mpt_set_debug_level(const char *val, struct kernel_param *kp);
 module_param_call(mpt_debug_level, mpt_set_debug_level, param_get_int,
 		  &mpt_debug_level, 0600);
-MODULE_PARM_DESC(mpt_debug_level, " debug level - refer to mptdebug.h \
-	- (default=0)");
+MODULE_PARM_DESC(mpt_debug_level,
+		 " debug level - refer to mptdebug.h - (default=0)");
 
 int mpt_fwfault_debug;
 EXPORT_SYMBOL(mpt_fwfault_debug);
 module_param(mpt_fwfault_debug, int, 0600);
-MODULE_PARM_DESC(mpt_fwfault_debug, "Enable detection of Firmware fault"
-	" and halt Firmware on fault - (default=0)");
-
+MODULE_PARM_DESC(mpt_fwfault_debug,
+		 "Enable detection of Firmware fault and halt Firmware on fault - (default=0)");
 
 static char	MptCallbacksName[MPT_MAX_PROTOCOL_DRIVERS][50];
 
diff -druN linux-2.6.39-libre/drivers/message/fusion/mptbase.h linux-3.0-rc7-libre/drivers/message/fusion/mptbase.h
--- linux-2.6.39-libre/drivers/message/fusion/mptbase.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/message/fusion/mptbase.h	2011-07-11 19:51:52.000000000 -0400
@@ -76,8 +76,8 @@
 #define COPYRIGHT	"Copyright (c) 1999-2008 " MODULEAUTHOR
 #endif
 
-#define MPT_LINUX_VERSION_COMMON	"3.04.18"
-#define MPT_LINUX_PACKAGE_NAME		"@(#)mptlinux-3.04.18"
+#define MPT_LINUX_VERSION_COMMON	"3.04.19"
+#define MPT_LINUX_PACKAGE_NAME		"@(#)mptlinux-3.04.19"
 #define WHAT_MAGIC_STRING		"@" "(" "#" ")"
 
 #define show_mptmod_ver(s,ver)  \
diff -druN linux-2.6.39-libre/drivers/message/fusion/mptsas.c linux-3.0-rc7-libre/drivers/message/fusion/mptsas.c
--- linux-2.6.39-libre/drivers/message/fusion/mptsas.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/message/fusion/mptsas.c	2011-07-11 19:51:52.000000000 -0400
@@ -5012,7 +5012,6 @@
 			(ioc_stat & MPI_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE)) {
 			VirtTarget *vtarget = NULL;
 			u8		id, channel;
-			u32	 log_info = le32_to_cpu(reply->IOCLogInfo);
 
 			id = sas_event_data->TargetID;
 			channel = sas_event_data->Bus;
@@ -5023,7 +5022,8 @@
 				    "LogInfo (0x%x) available for "
 				   "INTERNAL_DEVICE_RESET"
 				   "fw_id %d fw_channel %d\n", ioc->name,
-				   log_info, id, channel));
+				   le32_to_cpu(reply->IOCLogInfo),
+				   id, channel));
 				if (vtarget->raidVolume) {
 					devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT
 					"Skipping Raid Volume for inDMD\n",
diff -druN linux-2.6.39-libre/drivers/message/fusion/mptscsih.c linux-3.0-rc7-libre/drivers/message/fusion/mptscsih.c
--- linux-2.6.39-libre/drivers/message/fusion/mptscsih.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/message/fusion/mptscsih.c	2011-07-11 19:51:52.000000000 -0400
@@ -1415,11 +1415,8 @@
 	dmfprintk(ioc, printk(MYIOC_s_DEBUG_FMT "qcmd: SCpnt=%p, done()=%p\n",
 		ioc->name, SCpnt, done));
 
-	if (ioc->taskmgmt_quiesce_io) {
-		dtmprintk(ioc, printk(MYIOC_s_WARN_FMT "qcmd: SCpnt=%p timeout + 60HZ\n",
-			ioc->name, SCpnt));
+	if (ioc->taskmgmt_quiesce_io)
 		return SCSI_MLQUEUE_HOST_BUSY;
-	}
 
 	/*
 	 *  Put together a MPT SCSI request...
@@ -1773,7 +1770,6 @@
 	int		 scpnt_idx;
 	int		 retval;
 	VirtDevice	 *vdevice;
-	ulong	 	 sn = SCpnt->serial_number;
 	MPT_ADAPTER	*ioc;
 
 	/* If we can't locate our host adapter structure, return FAILED status.
@@ -1859,8 +1855,7 @@
 			 vdevice->vtarget->id, vdevice->lun,
 			 ctx2abort, mptscsih_get_tm_timeout(ioc));
 
-	if (SCPNT_TO_LOOKUP_IDX(ioc, SCpnt) == scpnt_idx &&
-	    SCpnt->serial_number == sn) {
+	if (SCPNT_TO_LOOKUP_IDX(ioc, SCpnt) == scpnt_idx) {
 		dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
 		    "task abort: command still in active list! (sc=%p)\n",
 		    ioc->name, SCpnt));
@@ -1873,9 +1868,9 @@
 	}
 
  out:
-	printk(MYIOC_s_INFO_FMT "task abort: %s (rv=%04x) (sc=%p) (sn=%ld)\n",
+	printk(MYIOC_s_INFO_FMT "task abort: %s (rv=%04x) (sc=%p)\n",
 	    ioc->name, ((retval == SUCCESS) ? "SUCCESS" : "FAILED"), retval,
-	    SCpnt, SCpnt->serial_number);
+	    SCpnt);
 
 	return retval;
 }
diff -druN linux-2.6.39-libre/drivers/message/fusion/mptspi.c linux-3.0-rc7-libre/drivers/message/fusion/mptspi.c
--- linux-2.6.39-libre/drivers/message/fusion/mptspi.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/message/fusion/mptspi.c	2011-07-11 19:51:52.000000000 -0400
@@ -867,6 +867,10 @@
 	struct _x_config_parms cfg;
 	struct _CONFIG_PAGE_HEADER hdr;
 	int err = -EBUSY;
+	u32 nego_parms;
+	u32 period;
+	struct scsi_device *sdev;
+	int i;
 
 	/* don't allow updating nego parameters on RAID devices */
 	if (starget->channel == 0 &&
@@ -904,6 +908,24 @@
 	pg1->Header.PageNumber = hdr.PageNumber;
 	pg1->Header.PageType = hdr.PageType;
 
+	nego_parms = le32_to_cpu(pg1->RequestedParameters);
+	period = (nego_parms & MPI_SCSIDEVPAGE1_RP_MIN_SYNC_PERIOD_MASK) >>
+		MPI_SCSIDEVPAGE1_RP_SHIFT_MIN_SYNC_PERIOD;
+	if (period == 8) {
+		/* Turn on inline data padding for TAPE when running U320 */
+		for (i = 0 ; i < 16; i++) {
+			sdev = scsi_device_lookup_by_target(starget, i);
+			if (sdev && sdev->type == TYPE_TAPE) {
+				sdev_printk(KERN_DEBUG, sdev, MYIOC_s_FMT
+					    "IDP:ON\n", ioc->name);
+				nego_parms |= MPI_SCSIDEVPAGE1_RP_IDP;
+				pg1->RequestedParameters =
+				    cpu_to_le32(nego_parms);
+				break;
+			}
+		}
+	}
+
 	mptspi_print_write_nego(hd, starget, le32_to_cpu(pg1->RequestedParameters));
 
 	if (mpt_config(ioc, &cfg)) {
diff -druN linux-2.6.39-libre/drivers/message/i2o/i2o_scsi.c linux-3.0-rc7-libre/drivers/message/i2o/i2o_scsi.c
--- linux-2.6.39-libre/drivers/message/i2o/i2o_scsi.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/message/i2o/i2o_scsi.c	2011-07-11 19:51:52.000000000 -0400
@@ -361,7 +361,7 @@
 	 */
 	error = le32_to_cpu(msg->body[0]);
 
-	osm_debug("Completed %ld\n", cmd->serial_number);
+	osm_debug("Completed %0x%p\n", cmd);
 
 	cmd->result = error & 0xff;
 	/*
@@ -678,7 +678,7 @@
 	/* Queue the message */
 	i2o_msg_post(c, msg);
 
-	osm_debug("Issued %ld\n", SCpnt->serial_number);
+	osm_debug("Issued %0x%p\n", SCpnt);
 
 	return 0;
 
diff -druN linux-2.6.39-libre/drivers/message/i2o/README.ioctl linux-3.0-rc7-libre/drivers/message/i2o/README.ioctl
--- linux-2.6.39-libre/drivers/message/i2o/README.ioctl	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/message/i2o/README.ioctl	2011-07-11 19:51:52.000000000 -0400
@@ -110,7 +110,7 @@
       ENOBUFS     Buffer not large enough.  If this occurs, the required
                   buffer length is written into *(lct->reslen)
 
-VI. Settting Parameters
+VI. Setting Parameters
    
    SYNOPSIS 
  
diff -druN linux-2.6.39-libre/drivers/mfd/88pm860x-core.c linux-3.0-rc7-libre/drivers/mfd/88pm860x-core.c
--- linux-2.6.39-libre/drivers/mfd/88pm860x-core.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mfd/88pm860x-core.c	2011-07-11 19:51:52.000000000 -0400
@@ -21,13 +21,13 @@
 
 #define INT_STATUS_NUM			3
 
-static struct resource bk_resources[] __initdata = {
+static struct resource bk_resources[] __devinitdata = {
 	{PM8606_BACKLIGHT1, PM8606_BACKLIGHT1, "backlight-0", IORESOURCE_IO,},
 	{PM8606_BACKLIGHT2, PM8606_BACKLIGHT2, "backlight-1", IORESOURCE_IO,},
 	{PM8606_BACKLIGHT3, PM8606_BACKLIGHT3, "backlight-2", IORESOURCE_IO,},
 };
 
-static struct resource led_resources[] __initdata = {
+static struct resource led_resources[] __devinitdata = {
 	{PM8606_LED1_RED,   PM8606_LED1_RED,   "led0-red",   IORESOURCE_IO,},
 	{PM8606_LED1_GREEN, PM8606_LED1_GREEN, "led0-green", IORESOURCE_IO,},
 	{PM8606_LED1_BLUE,  PM8606_LED1_BLUE,  "led0-blue",  IORESOURCE_IO,},
@@ -36,7 +36,7 @@
 	{PM8606_LED2_BLUE,  PM8606_LED2_BLUE,  "led1-blue",  IORESOURCE_IO,},
 };
 
-static struct resource regulator_resources[] __initdata = {
+static struct resource regulator_resources[] __devinitdata = {
 	{PM8607_ID_BUCK1, PM8607_ID_BUCK1, "buck-1", IORESOURCE_IO,},
 	{PM8607_ID_BUCK2, PM8607_ID_BUCK2, "buck-2", IORESOURCE_IO,},
 	{PM8607_ID_BUCK3, PM8607_ID_BUCK3, "buck-3", IORESOURCE_IO,},
@@ -57,15 +57,15 @@
 	{PM8607_ID_LDO15, PM8607_ID_LDO15, "ldo-15", IORESOURCE_IO,},
 };
 
-static struct resource touch_resources[] __initdata = {
+static struct resource touch_resources[] __devinitdata = {
 	{PM8607_IRQ_PEN, PM8607_IRQ_PEN, "touch", IORESOURCE_IRQ,},
 };
 
-static struct resource onkey_resources[] __initdata = {
+static struct resource onkey_resources[] __devinitdata = {
 	{PM8607_IRQ_ONKEY, PM8607_IRQ_ONKEY, "onkey", IORESOURCE_IRQ,},
 };
 
-static struct resource codec_resources[] __initdata = {
+static struct resource codec_resources[] __devinitdata = {
 	/* Headset microphone insertion or removal */
 	{PM8607_IRQ_MICIN,   PM8607_IRQ_MICIN,   "micin",   IORESOURCE_IRQ,},
 	/* Hook-switch press or release */
@@ -76,12 +76,12 @@
 	{PM8607_IRQ_AUDIO_SHORT, PM8607_IRQ_AUDIO_SHORT, "audio-short", IORESOURCE_IRQ,},
 };
 
-static struct resource battery_resources[] __initdata = {
+static struct resource battery_resources[] __devinitdata = {
 	{PM8607_IRQ_CC,  PM8607_IRQ_CC,  "columb counter", IORESOURCE_IRQ,},
 	{PM8607_IRQ_BAT, PM8607_IRQ_BAT, "battery",        IORESOURCE_IRQ,},
 };
 
-static struct resource charger_resources[] __initdata = {
+static struct resource charger_resources[] __devinitdata = {
 	{PM8607_IRQ_CHG,  PM8607_IRQ_CHG,  "charger detect",  IORESOURCE_IRQ,},
 	{PM8607_IRQ_CHG_DONE,  PM8607_IRQ_CHG_DONE,  "charging done",       IORESOURCE_IRQ,},
 	{PM8607_IRQ_CHG_FAULT, PM8607_IRQ_CHG_FAULT, "charging timeout",    IORESOURCE_IRQ,},
@@ -90,13 +90,17 @@
 	{PM8607_IRQ_VCHG, PM8607_IRQ_VCHG, "vchg voltage",    IORESOURCE_IRQ,},
 };
 
-static struct mfd_cell bk_devs[] __initdata = {
+static struct resource rtc_resources[] __devinitdata = {
+	{PM8607_IRQ_RTC, PM8607_IRQ_RTC, "rtc", IORESOURCE_IRQ,},
+};
+
+static struct mfd_cell bk_devs[] = {
 	{"88pm860x-backlight", 0,},
 	{"88pm860x-backlight", 1,},
 	{"88pm860x-backlight", 2,},
 };
 
-static struct mfd_cell led_devs[] __initdata = {
+static struct mfd_cell led_devs[] = {
 	{"88pm860x-led", 0,},
 	{"88pm860x-led", 1,},
 	{"88pm860x-led", 2,},
@@ -105,7 +109,7 @@
 	{"88pm860x-led", 5,},
 };
 
-static struct mfd_cell regulator_devs[] __initdata = {
+static struct mfd_cell regulator_devs[] = {
 	{"88pm860x-regulator", 0,},
 	{"88pm860x-regulator", 1,},
 	{"88pm860x-regulator", 2,},
@@ -126,15 +130,15 @@
 	{"88pm860x-regulator", 17,},
 };
 
-static struct mfd_cell touch_devs[] __initdata = {
+static struct mfd_cell touch_devs[] = {
 	{"88pm860x-touch", -1,},
 };
 
-static struct mfd_cell onkey_devs[] __initdata = {
+static struct mfd_cell onkey_devs[] = {
 	{"88pm860x-onkey", -1,},
 };
 
-static struct mfd_cell codec_devs[] __initdata = {
+static struct mfd_cell codec_devs[] = {
 	{"88pm860x-codec", -1,},
 };
 
@@ -143,11 +147,10 @@
 	{"88pm860x-charger", -1,},
 };
 
-static struct pm860x_backlight_pdata bk_pdata[ARRAY_SIZE(bk_devs)];
-static struct pm860x_led_pdata led_pdata[ARRAY_SIZE(led_devs)];
-static struct regulator_init_data regulator_pdata[ARRAY_SIZE(regulator_devs)];
-static struct pm860x_touch_pdata touch_pdata;
-static struct pm860x_power_pdata power_pdata;
+static struct mfd_cell rtc_devs[] = {
+	{"88pm860x-rtc", -1,},
+};
+
 
 struct pm860x_irq_data {
 	int	reg;
@@ -501,7 +504,6 @@
 }
 
 static void __devinit device_bk_init(struct pm860x_chip *chip,
-				     struct i2c_client *i2c,
 				     struct pm860x_platform_data *pdata)
 {
 	int ret;
@@ -514,13 +516,12 @@
 		pdata->num_backlights = ARRAY_SIZE(bk_devs);
 
 	for (i = 0; i < pdata->num_backlights; i++) {
-		memcpy(&bk_pdata[i], &pdata->backlight[i],
-			sizeof(struct pm860x_backlight_pdata));
-		bk_devs[i].mfd_data = &bk_pdata[i];
+		bk_devs[i].platform_data = &pdata->backlight[i];
+		bk_devs[i].pdata_size = sizeof(struct pm860x_backlight_pdata);
 
 		for (j = 0; j < ARRAY_SIZE(bk_devs); j++) {
 			id = bk_resources[j].start;
-			if (bk_pdata[i].flags != id)
+			if (pdata->backlight[i].flags != id)
 				continue;
 
 			bk_devs[i].num_resources = 1;
@@ -538,7 +539,6 @@
 }
 
 static void __devinit device_led_init(struct pm860x_chip *chip,
-				      struct i2c_client *i2c,
 				      struct pm860x_platform_data *pdata)
 {
 	int ret;
@@ -551,13 +551,12 @@
 		pdata->num_leds = ARRAY_SIZE(led_devs);
 
 	for (i = 0; i < pdata->num_leds; i++) {
-		memcpy(&led_pdata[i], &pdata->led[i],
-			sizeof(struct pm860x_led_pdata));
-		led_devs[i].mfd_data = &led_pdata[i];
+		led_devs[i].platform_data = &pdata->led[i];
+		led_devs[i].pdata_size = sizeof(struct pm860x_led_pdata);
 
 		for (j = 0; j < ARRAY_SIZE(led_devs); j++) {
 			id = led_resources[j].start;
-			if (led_pdata[i].flags != id)
+			if (pdata->led[i].flags != id)
 				continue;
 
 			led_devs[i].num_resources = 1;
@@ -575,12 +574,11 @@
 }
 
 static void __devinit device_regulator_init(struct pm860x_chip *chip,
-					    struct i2c_client *i2c,
 					    struct pm860x_platform_data *pdata)
 {
 	struct regulator_init_data *initdata;
 	int ret;
-	int i, j;
+	int i, seq;
 
 	if ((pdata == NULL) || (pdata->regulator == NULL))
 		return;
@@ -588,41 +586,21 @@
 	if (pdata->num_regulators > ARRAY_SIZE(regulator_devs))
 		pdata->num_regulators = ARRAY_SIZE(regulator_devs);
 
-	for (i = 0, j = -1; i < pdata->num_regulators; i++) {
+	for (i = 0, seq = -1; i < pdata->num_regulators; i++) {
 		initdata = &pdata->regulator[i];
-		if (strstr(initdata->constraints.name, "BUCK")) {
-			sscanf(initdata->constraints.name, "BUCK%d", &j);
-			/* BUCK1 ~ BUCK3 */
-			if ((j < 1) || (j > 3)) {
-				dev_err(chip->dev, "Failed to add constraint "
-					"(%s)\n", initdata->constraints.name);
-				goto out;
-			}
-			j = (j - 1) + PM8607_ID_BUCK1;
-		}
-		if (strstr(initdata->constraints.name, "LDO")) {
-			sscanf(initdata->constraints.name, "LDO%d", &j);
-			/* LDO1 ~ LDO15 */
-			if ((j < 1) || (j > 15)) {
-				dev_err(chip->dev, "Failed to add constraint "
-					"(%s)\n", initdata->constraints.name);
-				goto out;
-			}
-			j = (j - 1) + PM8607_ID_LDO1;
-		}
-		if (j == -1) {
-			dev_err(chip->dev, "Failed to add constraint (%s)\n",
-				initdata->constraints.name);
+		seq = *(unsigned int *)initdata->driver_data;
+		if ((seq < 0) || (seq > PM8607_ID_RG_MAX)) {
+			dev_err(chip->dev, "Wrong ID(%d) on regulator(%s)\n",
+				seq, initdata->constraints.name);
 			goto out;
 		}
-		memcpy(&regulator_pdata[i], &pdata->regulator[i],
-			sizeof(struct regulator_init_data));
-		regulator_devs[i].mfd_data = &regulator_pdata[i];
+		regulator_devs[i].platform_data = &pdata->regulator[i];
+		regulator_devs[i].pdata_size = sizeof(struct regulator_init_data);
 		regulator_devs[i].num_resources = 1;
-		regulator_devs[i].resources = &regulator_resources[j];
+		regulator_devs[i].resources = &regulator_resources[seq];
 
 		ret = mfd_add_devices(chip->dev, 0, &regulator_devs[i], 1,
-				      &regulator_resources[j], 0);
+				      &regulator_resources[seq], 0);
 		if (ret < 0) {
 			dev_err(chip->dev, "Failed to add regulator subdev\n");
 			goto out;
@@ -632,17 +610,35 @@
 	return;
 }
 
+static void __devinit device_rtc_init(struct pm860x_chip *chip,
+				      struct pm860x_platform_data *pdata)
+{
+	int ret;
+
+	if ((pdata == NULL))
+		return;
+
+	rtc_devs[0].platform_data = pdata->rtc;
+	rtc_devs[0].pdata_size = sizeof(struct pm860x_rtc_pdata);
+	rtc_devs[0].num_resources = ARRAY_SIZE(rtc_resources);
+	rtc_devs[0].resources = &rtc_resources[0];
+	ret = mfd_add_devices(chip->dev, 0, &rtc_devs[0],
+			      ARRAY_SIZE(rtc_devs), &rtc_resources[0],
+			      chip->irq_base);
+	if (ret < 0)
+		dev_err(chip->dev, "Failed to add rtc subdev\n");
+}
+
 static void __devinit device_touch_init(struct pm860x_chip *chip,
-					struct i2c_client *i2c,
 					struct pm860x_platform_data *pdata)
 {
 	int ret;
 
-	if ((pdata == NULL) || (pdata->touch == NULL))
+	if (pdata == NULL)
 		return;
 
-	memcpy(&touch_pdata, pdata->touch, sizeof(struct pm860x_touch_pdata));
-	touch_devs[0].mfd_data = &touch_pdata;
+	touch_devs[0].platform_data = pdata->touch;
+	touch_devs[0].pdata_size = sizeof(struct pm860x_touch_pdata);
 	touch_devs[0].num_resources = ARRAY_SIZE(touch_resources);
 	touch_devs[0].resources = &touch_resources[0];
 	ret = mfd_add_devices(chip->dev, 0, &touch_devs[0],
@@ -653,16 +649,15 @@
 }
 
 static void __devinit device_power_init(struct pm860x_chip *chip,
-					struct i2c_client *i2c,
 					struct pm860x_platform_data *pdata)
 {
 	int ret;
 
-	if ((pdata == NULL) || (pdata->power == NULL))
+	if (pdata == NULL)
 		return;
 
-	memcpy(&power_pdata, pdata->power, sizeof(struct pm860x_power_pdata));
-	power_devs[0].mfd_data = &power_pdata;
+	power_devs[0].platform_data = pdata->power;
+	power_devs[0].pdata_size = sizeof(struct pm860x_power_pdata);
 	power_devs[0].num_resources = ARRAY_SIZE(battery_resources);
 	power_devs[0].resources = &battery_resources[0],
 	ret = mfd_add_devices(chip->dev, 0, &power_devs[0], 1,
@@ -670,7 +665,8 @@
 	if (ret < 0)
 		dev_err(chip->dev, "Failed to add battery subdev\n");
 
-	power_devs[1].mfd_data = &power_pdata;
+	power_devs[1].platform_data = pdata->power;
+	power_devs[1].pdata_size = sizeof(struct pm860x_power_pdata);
 	power_devs[1].num_resources = ARRAY_SIZE(charger_resources);
 	power_devs[1].resources = &charger_resources[0],
 	ret = mfd_add_devices(chip->dev, 0, &power_devs[1], 1,
@@ -680,7 +676,6 @@
 }
 
 static void __devinit device_onkey_init(struct pm860x_chip *chip,
-					struct i2c_client *i2c,
 					struct pm860x_platform_data *pdata)
 {
 	int ret;
@@ -695,7 +690,6 @@
 }
 
 static void __devinit device_codec_init(struct pm860x_chip *chip,
-					struct i2c_client *i2c,
 					struct pm860x_platform_data *pdata)
 {
 	int ret;
@@ -763,11 +757,12 @@
 	if (ret < 0)
 		goto out;
 
-	device_regulator_init(chip, i2c, pdata);
-	device_onkey_init(chip, i2c, pdata);
-	device_touch_init(chip, i2c, pdata);
-	device_power_init(chip, i2c, pdata);
-	device_codec_init(chip, i2c, pdata);
+	device_regulator_init(chip, pdata);
+	device_rtc_init(chip, pdata);
+	device_onkey_init(chip, pdata);
+	device_touch_init(chip, pdata);
+	device_power_init(chip, pdata);
+	device_codec_init(chip, pdata);
 out:
 	return;
 }
@@ -779,8 +774,8 @@
 
 	switch (chip->id) {
 	case CHIP_PM8606:
-		device_bk_init(chip, chip->client, pdata);
-		device_led_init(chip, chip->client, pdata);
+		device_bk_init(chip, pdata);
+		device_led_init(chip, pdata);
 		break;
 	case CHIP_PM8607:
 		device_8607_init(chip, chip->client, pdata);
@@ -790,8 +785,8 @@
 	if (chip->companion) {
 		switch (chip->id) {
 		case CHIP_PM8607:
-			device_bk_init(chip, chip->companion, pdata);
-			device_led_init(chip, chip->companion, pdata);
+			device_bk_init(chip, pdata);
+			device_led_init(chip, pdata);
 			break;
 		case CHIP_PM8606:
 			device_8607_init(chip, chip->companion, pdata);
diff -druN linux-2.6.39-libre/drivers/mfd/ab3100-core.c linux-3.0-rc7-libre/drivers/mfd/ab3100-core.c
--- linux-2.6.39-libre/drivers/mfd/ab3100-core.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mfd/ab3100-core.c	2011-07-11 19:51:52.000000000 -0400
@@ -949,8 +949,10 @@
 		goto exit_no_ops;
 
 	/* Set up and register the platform devices. */
-	for (i = 0; i < ARRAY_SIZE(ab3100_devs); i++)
-		ab3100_devs[i].mfd_data = ab3100_plf_data;
+	for (i = 0; i < ARRAY_SIZE(ab3100_devs); i++) {
+		ab3100_devs[i].platform_data = ab3100_plf_data;
+		ab3100_devs[i].pdata_size = sizeof(struct ab3100_platform_data);
+	}
 
 	err = mfd_add_devices(&client->dev, 0, ab3100_devs,
 		ARRAY_SIZE(ab3100_devs), NULL, 0);
diff -druN linux-2.6.39-libre/drivers/mfd/ab3550-core.c linux-3.0-rc7-libre/drivers/mfd/ab3550-core.c
--- linux-2.6.39-libre/drivers/mfd/ab3550-core.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mfd/ab3550-core.c	2011-07-11 19:51:52.000000000 -0400
@@ -1320,8 +1320,10 @@
 		goto exit_no_ops;
 
 	/* Set up and register the platform devices. */
-	for (i = 0; i < AB3550_NUM_DEVICES; i++)
-		ab3550_devs[i].mfd_data = ab3550_plf_data->dev_data[i];
+	for (i = 0; i < AB3550_NUM_DEVICES; i++) {
+		ab3550_devs[i].platform_data = ab3550_plf_data->dev_data[i];
+		ab3550_devs[i].pdata_size = ab3550_plf_data->dev_data_sz[i];
+	}
 
 	err = mfd_add_devices(&client->dev, 0, ab3550_devs,
 		ARRAY_SIZE(ab3550_devs), NULL,
diff -druN linux-2.6.39-libre/drivers/mfd/ab8500-core.c linux-3.0-rc7-libre/drivers/mfd/ab8500-core.c
--- linux-2.6.39-libre/drivers/mfd/ab8500-core.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mfd/ab8500-core.c	2011-07-11 19:51:52.000000000 -0400
@@ -254,8 +254,9 @@
 		if (new == old)
 			continue;
 
-		/* Interrupt register 12 does'nt exist prior to version 0x20 */
-		if (ab8500_irq_regoffset[i] == 11 && ab8500->chip_id < 0x20)
+		/* Interrupt register 12 doesn't exist prior to version 2.0 */
+		if (ab8500_irq_regoffset[i] == 11 &&
+			ab8500->chip_id < AB8500_CUT2P0)
 			continue;
 
 		ab8500->oldmask[i] = new;
@@ -307,8 +308,8 @@
 		int status;
 		u8 value;
 
-		/* Interrupt register 12 does'nt exist prior to version 0x20 */
-		if (regoffset == 11 && ab8500->chip_id < 0x20)
+		/* Interrupt register 12 doesn't exist prior to version 2.0 */
+		if (regoffset == 11 && ab8500->chip_id < AB8500_CUT2P0)
 			continue;
 
 		status = get_register_interruptible(ab8500, AB8500_INTERRUPT,
@@ -724,17 +725,15 @@
 	if (ret < 0)
 		return ret;
 
-	/*
-	 * 0x0 - Early Drop
-	 * 0x10 - Cut 1.0
-	 * 0x11 - Cut 1.1
-	 * 0x20 - Cut 2.0
-	 * 0x30 - Cut 3.0
-	 */
-	if (value == 0x0 || value == 0x10 || value == 0x11 || value == 0x20 ||
-		value == 0x30) {
+	switch (value) {
+	case AB8500_CUTEARLY:
+	case AB8500_CUT1P0:
+	case AB8500_CUT1P1:
+	case AB8500_CUT2P0:
+	case AB8500_CUT3P0:
 		dev_info(ab8500->dev, "detected chip, revision: %#x\n", value);
-	} else {
+		break;
+	default:
 		dev_err(ab8500->dev, "unknown chip, revision: %#x\n", value);
 		return -EINVAL;
 	}
@@ -763,8 +762,9 @@
 
 	/* Clear and mask all interrupts */
 	for (i = 0; i < AB8500_NUM_IRQ_REGS; i++) {
-		/* Interrupt register 12 does'nt exist prior to version 0x20 */
-		if (ab8500_irq_regoffset[i] == 11 && ab8500->chip_id < 0x20)
+		/* Interrupt register 12 doesn't exist prior to version 2.0 */
+		if (ab8500_irq_regoffset[i] == 11 &&
+			ab8500->chip_id < AB8500_CUT2P0)
 			continue;
 
 		get_register_interruptible(ab8500, AB8500_INTERRUPT,
diff -druN linux-2.6.39-libre/drivers/mfd/ab8500-gpadc.c linux-3.0-rc7-libre/drivers/mfd/ab8500-gpadc.c
--- linux-2.6.39-libre/drivers/mfd/ab8500-gpadc.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mfd/ab8500-gpadc.c	2011-07-11 19:51:52.000000000 -0400
@@ -57,6 +57,7 @@
 #define SW_AVG_16			0x60
 #define ADC_SW_CONV			0x04
 #define EN_ICHAR			0x80
+#define BTEMP_PULL_UP			0x08
 #define EN_BUF				0x40
 #define DIS_ZERO			0x00
 #define GPADC_BUSY			0x01
@@ -101,6 +102,7 @@
 
 /**
  * struct ab8500_gpadc - AB8500 GPADC device information
+ * @chip_id			ABB chip id
  * @dev:			pointer to the struct device
  * @node:			a list of AB8500 GPADCs, hence prepared for
 				reentrance
@@ -112,6 +114,7 @@
  * @cal_data			array of ADC calibration data structs
  */
 struct ab8500_gpadc {
+	u8 chip_id;
 	struct device *dev;
 	struct list_head node;
 	struct completion ab8500_gpadc_complete;
@@ -274,6 +277,7 @@
 		dev_err(gpadc->dev, "gpadc_conversion: enable gpadc failed\n");
 		goto out;
 	}
+
 	/* Select the input source and set average samples to 16 */
 	ret = abx500_set_register_interruptible(gpadc->dev, AB8500_GPADC,
 		AB8500_GPADC_CTRL2_REG, (input | SW_AVG_16));
@@ -282,9 +286,11 @@
 			"gpadc_conversion: set avg samples failed\n");
 		goto out;
 	}
+
 	/*
 	 * Enable ADC, buffering, select rising edge and enable ADC path
-	 * charging current sense if it needed
+	 * charging current sense if it needed, ABB 3.0 needs some special
+	 * treatment too.
 	 */
 	switch (input) {
 	case MAIN_CHARGER_C:
@@ -294,6 +300,23 @@
 			EN_BUF | EN_ICHAR,
 			EN_BUF | EN_ICHAR);
 		break;
+	case BTEMP_BALL:
+		if (gpadc->chip_id >= AB8500_CUT3P0) {
+			/* Turn on btemp pull-up on ABB 3.0 */
+			ret = abx500_mask_and_set_register_interruptible(
+				gpadc->dev,
+				AB8500_GPADC, AB8500_GPADC_CTRL1_REG,
+				EN_BUF | BTEMP_PULL_UP,
+				EN_BUF | BTEMP_PULL_UP);
+
+		 /*
+		  * Delay might be needed for ABB8500 cut 3.0, if not, remove
+		  * when hardware will be availible
+		  */
+			msleep(1);
+			break;
+		}
+		/* Intentional fallthrough */
 	default:
 		ret = abx500_mask_and_set_register_interruptible(gpadc->dev,
 			AB8500_GPADC, AB8500_GPADC_CTRL1_REG, EN_BUF, EN_BUF);
@@ -304,6 +327,7 @@
 			"gpadc_conversion: select falling edge failed\n");
 		goto out;
 	}
+
 	ret = abx500_mask_and_set_register_interruptible(gpadc->dev,
 		AB8500_GPADC, AB8500_GPADC_CTRL1_REG, ADC_SW_CONV, ADC_SW_CONV);
 	if (ret < 0) {
@@ -552,6 +576,14 @@
 		goto fail;
 	}
 
+	/* Get Chip ID of the ABB ASIC  */
+	ret = abx500_get_chip_id(gpadc->dev);
+	if (ret < 0) {
+		dev_err(gpadc->dev, "failed to get chip ID\n");
+		goto fail_irq;
+	}
+	gpadc->chip_id = (u8) ret;
+
 	/* VTVout LDO used to power up ab8500-GPADC */
 	gpadc->regu = regulator_get(&pdev->dev, "vddadc");
 	if (IS_ERR(gpadc->regu)) {
diff -druN linux-2.6.39-libre/drivers/mfd/ab8500-i2c.c linux-3.0-rc7-libre/drivers/mfd/ab8500-i2c.c
--- linux-2.6.39-libre/drivers/mfd/ab8500-i2c.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mfd/ab8500-i2c.c	2011-07-11 19:51:52.000000000 -0400
@@ -11,8 +11,7 @@
 #include <linux/module.h>
 #include <linux/platform_device.h>
 #include <linux/mfd/ab8500.h>
-
-#include <mach/prcmu.h>
+#include <linux/mfd/db8500-prcmu.h>
 
 static int ab8500_i2c_write(struct ab8500 *ab8500, u16 addr, u8 data)
 {
diff -druN linux-2.6.39-libre/drivers/mfd/asic3.c linux-3.0-rc7-libre/drivers/mfd/asic3.c
--- linux-2.6.39-libre/drivers/mfd/asic3.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mfd/asic3.c	2011-07-11 19:51:52.000000000 -0400
@@ -88,19 +88,19 @@
 
 static int asic3_gpio_get(struct gpio_chip *chip, unsigned offset);
 
-static inline void asic3_write_register(struct asic3 *asic,
-				 unsigned int reg, u32 value)
+void asic3_write_register(struct asic3 *asic, unsigned int reg, u32 value)
 {
 	iowrite16(value, asic->mapping +
 		  (reg >> asic->bus_shift));
 }
+EXPORT_SYMBOL_GPL(asic3_write_register);
 
-static inline u32 asic3_read_register(struct asic3 *asic,
-			       unsigned int reg)
+u32 asic3_read_register(struct asic3 *asic, unsigned int reg)
 {
 	return ioread16(asic->mapping +
 			(reg >> asic->bus_shift));
 }
+EXPORT_SYMBOL_GPL(asic3_read_register);
 
 static void asic3_set_register(struct asic3 *asic, u32 reg, u32 bits, bool set)
 {
@@ -619,6 +619,7 @@
 /* MFD cells (SPI, PWM, LED, DS1WM, MMC) */
 static struct ds1wm_driver_data ds1wm_pdata = {
 	.active_high = 1,
+	.reset_recover_delay = 1,
 };
 
 static struct resource ds1wm_resources[] = {
@@ -676,7 +677,8 @@
 	.name          = "ds1wm",
 	.enable        = ds1wm_enable,
 	.disable       = ds1wm_disable,
-	.mfd_data      = &ds1wm_pdata,
+	.platform_data = &ds1wm_pdata,
+	.pdata_size    = sizeof(ds1wm_pdata),
 	.num_resources = ARRAY_SIZE(ds1wm_resources),
 	.resources     = ds1wm_resources,
 };
@@ -777,12 +779,61 @@
 	.name          = "tmio-mmc",
 	.enable        = asic3_mmc_enable,
 	.disable       = asic3_mmc_disable,
-	.mfd_data      = &asic3_mmc_data,
+	.platform_data = &asic3_mmc_data,
+	.pdata_size    = sizeof(asic3_mmc_data),
 	.num_resources = ARRAY_SIZE(asic3_mmc_resources),
 	.resources     = asic3_mmc_resources,
 };
 
+static const int clock_ledn[ASIC3_NUM_LEDS] = {
+	[0] = ASIC3_CLOCK_LED0,
+	[1] = ASIC3_CLOCK_LED1,
+	[2] = ASIC3_CLOCK_LED2,
+};
+
+static int asic3_leds_enable(struct platform_device *pdev)
+{
+	const struct mfd_cell *cell = mfd_get_cell(pdev);
+	struct asic3 *asic = dev_get_drvdata(pdev->dev.parent);
+
+	asic3_clk_enable(asic, &asic->clocks[clock_ledn[cell->id]]);
+
+	return 0;
+}
+
+static int asic3_leds_disable(struct platform_device *pdev)
+{
+	const struct mfd_cell *cell = mfd_get_cell(pdev);
+	struct asic3 *asic = dev_get_drvdata(pdev->dev.parent);
+
+	asic3_clk_disable(asic, &asic->clocks[clock_ledn[cell->id]]);
+
+	return 0;
+}
+
+static struct mfd_cell asic3_cell_leds[ASIC3_NUM_LEDS] = {
+	[0] = {
+		.name          = "leds-asic3",
+		.id            = 0,
+		.enable        = asic3_leds_enable,
+		.disable       = asic3_leds_disable,
+	},
+	[1] = {
+		.name          = "leds-asic3",
+		.id            = 1,
+		.enable        = asic3_leds_enable,
+		.disable       = asic3_leds_disable,
+	},
+	[2] = {
+		.name          = "leds-asic3",
+		.id            = 2,
+		.enable        = asic3_leds_enable,
+		.disable       = asic3_leds_disable,
+	},
+};
+
 static int __init asic3_mfd_probe(struct platform_device *pdev,
+				  struct asic3_platform_data *pdata,
 				  struct resource *mem)
 {
 	struct asic3 *asic = platform_get_drvdata(pdev);
@@ -806,7 +857,8 @@
 
 	/* MMC */
 	asic->tmio_cnf = ioremap((ASIC3_SD_CONFIG_BASE >> asic->bus_shift) +
-				 mem_sdio->start, 0x400 >> asic->bus_shift);
+				 mem_sdio->start,
+				 ASIC3_SD_CONFIG_SIZE >> asic->bus_shift);
 	if (!asic->tmio_cnf) {
 		ret = -ENOMEM;
 		dev_dbg(asic->dev, "Couldn't ioremap SD_CONFIG\n");
@@ -820,9 +872,23 @@
 	if (ret < 0)
 		goto out;
 
-	if (mem_sdio && (irq >= 0))
+	if (mem_sdio && (irq >= 0)) {
 		ret = mfd_add_devices(&pdev->dev, pdev->id,
 			&asic3_cell_mmc, 1, mem_sdio, irq);
+		if (ret < 0)
+			goto out;
+	}
+
+	if (pdata->leds) {
+		int i;
+
+		for (i = 0; i < ASIC3_NUM_LEDS; ++i) {
+			asic3_cell_leds[i].platform_data = &pdata->leds[i];
+			asic3_cell_leds[i].pdata_size = sizeof(pdata->leds[i]);
+		}
+		ret = mfd_add_devices(&pdev->dev, 0,
+			asic3_cell_leds, ASIC3_NUM_LEDS, NULL, 0);
+	}
 
  out:
 	return ret;
@@ -903,7 +969,7 @@
 	 */
 	memcpy(asic->clocks, asic3_clk_init, sizeof(asic3_clk_init));
 
-	asic3_mfd_probe(pdev, mem);
+	asic3_mfd_probe(pdev, pdata, mem);
 
 	dev_info(asic->dev, "ASIC3 Core driver\n");
 
diff -druN linux-2.6.39-libre/drivers/mfd/davinci_voicecodec.c linux-3.0-rc7-libre/drivers/mfd/davinci_voicecodec.c
--- linux-2.6.39-libre/drivers/mfd/davinci_voicecodec.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mfd/davinci_voicecodec.c	2011-07-11 19:51:52.000000000 -0400
@@ -119,12 +119,14 @@
 	/* Voice codec interface client */
 	cell = &davinci_vc->cells[DAVINCI_VC_VCIF_CELL];
 	cell->name = "davinci-vcif";
-	cell->mfd_data = davinci_vc;
+	cell->platform_data = davinci_vc;
+	cell->pdata_size = sizeof(*davinci_vc);
 
 	/* Voice codec CQ93VC client */
 	cell = &davinci_vc->cells[DAVINCI_VC_CQ93VC_CELL];
 	cell->name = "cq93vc-codec";
-	cell->mfd_data = davinci_vc;
+	cell->platform_data = davinci_vc;
+	cell->pdata_size = sizeof(*davinci_vc);
 
 	ret = mfd_add_devices(&pdev->dev, pdev->id, davinci_vc->cells,
 			      DAVINCI_VC_CELLS, NULL, 0);
diff -druN linux-2.6.39-libre/drivers/mfd/db5500-prcmu.c linux-3.0-rc7-libre/drivers/mfd/db5500-prcmu.c
--- linux-2.6.39-libre/drivers/mfd/db5500-prcmu.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/mfd/db5500-prcmu.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,448 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2010
+ *
+ * License Terms: GNU General Public License v2
+ * Author: Mattias Nilsson <mattias.i.nilsson@stericsson.com>
+ *
+ * U5500 PRCM Unit interface driver
+ */
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/delay.h>
+#include <linux/errno.h>
+#include <linux/err.h>
+#include <linux/spinlock.h>
+#include <linux/io.h>
+#include <linux/slab.h>
+#include <linux/mutex.h>
+#include <linux/completion.h>
+#include <linux/irq.h>
+#include <linux/jiffies.h>
+#include <linux/bitops.h>
+#include <linux/interrupt.h>
+#include <linux/mfd/db5500-prcmu.h>
+#include <mach/hardware.h>
+#include <mach/irqs.h>
+#include <mach/db5500-regs.h>
+#include "db5500-prcmu-regs.h"
+
+#define _PRCM_MB_HEADER (tcdm_base + 0xFE8)
+#define PRCM_REQ_MB0_HEADER (_PRCM_MB_HEADER + 0x0)
+#define PRCM_REQ_MB1_HEADER (_PRCM_MB_HEADER + 0x1)
+#define PRCM_REQ_MB2_HEADER (_PRCM_MB_HEADER + 0x2)
+#define PRCM_REQ_MB3_HEADER (_PRCM_MB_HEADER + 0x3)
+#define PRCM_REQ_MB4_HEADER (_PRCM_MB_HEADER + 0x4)
+#define PRCM_REQ_MB5_HEADER (_PRCM_MB_HEADER + 0x5)
+#define PRCM_REQ_MB6_HEADER (_PRCM_MB_HEADER + 0x6)
+#define PRCM_REQ_MB7_HEADER (_PRCM_MB_HEADER + 0x7)
+#define PRCM_ACK_MB0_HEADER (_PRCM_MB_HEADER + 0x8)
+#define PRCM_ACK_MB1_HEADER (_PRCM_MB_HEADER + 0x9)
+#define PRCM_ACK_MB2_HEADER (_PRCM_MB_HEADER + 0xa)
+#define PRCM_ACK_MB3_HEADER (_PRCM_MB_HEADER + 0xb)
+#define PRCM_ACK_MB4_HEADER (_PRCM_MB_HEADER + 0xc)
+#define PRCM_ACK_MB5_HEADER (_PRCM_MB_HEADER + 0xd)
+#define PRCM_ACK_MB6_HEADER (_PRCM_MB_HEADER + 0xe)
+#define PRCM_ACK_MB7_HEADER (_PRCM_MB_HEADER + 0xf)
+
+/* Req Mailboxes */
+#define PRCM_REQ_MB0 (tcdm_base + 0xFD8)
+#define PRCM_REQ_MB1 (tcdm_base + 0xFCC)
+#define PRCM_REQ_MB2 (tcdm_base + 0xFC4)
+#define PRCM_REQ_MB3 (tcdm_base + 0xFC0)
+#define PRCM_REQ_MB4 (tcdm_base + 0xF98)
+#define PRCM_REQ_MB5 (tcdm_base + 0xF90)
+#define PRCM_REQ_MB6 (tcdm_base + 0xF8C)
+#define PRCM_REQ_MB7 (tcdm_base + 0xF84)
+
+/* Ack Mailboxes */
+#define PRCM_ACK_MB0 (tcdm_base + 0xF38)
+#define PRCM_ACK_MB1 (tcdm_base + 0xF30)
+#define PRCM_ACK_MB2 (tcdm_base + 0xF24)
+#define PRCM_ACK_MB3 (tcdm_base + 0xF20)
+#define PRCM_ACK_MB4 (tcdm_base + 0xF1C)
+#define PRCM_ACK_MB5 (tcdm_base + 0xF14)
+#define PRCM_ACK_MB6 (tcdm_base + 0xF0C)
+#define PRCM_ACK_MB7 (tcdm_base + 0xF08)
+
+enum mb_return_code {
+	RC_SUCCESS,
+	RC_FAIL,
+};
+
+/* Mailbox 0 headers. */
+enum mb0_header {
+	/* request */
+	RMB0H_PWR_STATE_TRANS = 1,
+	RMB0H_WAKE_UP_CFG,
+	RMB0H_RD_WAKE_UP_ACK,
+	/* acknowledge */
+	AMB0H_WAKE_UP = 1,
+};
+
+/* Mailbox 5 headers. */
+enum mb5_header {
+	MB5H_I2C_WRITE = 1,
+	MB5H_I2C_READ,
+};
+
+/* Request mailbox 5 fields. */
+#define PRCM_REQ_MB5_I2C_SLAVE (PRCM_REQ_MB5 + 0)
+#define PRCM_REQ_MB5_I2C_REG (PRCM_REQ_MB5 + 1)
+#define PRCM_REQ_MB5_I2C_SIZE (PRCM_REQ_MB5 + 2)
+#define PRCM_REQ_MB5_I2C_DATA (PRCM_REQ_MB5 + 4)
+
+/* Acknowledge mailbox 5 fields. */
+#define PRCM_ACK_MB5_RETURN_CODE (PRCM_ACK_MB5 + 0)
+#define PRCM_ACK_MB5_I2C_DATA (PRCM_ACK_MB5 + 4)
+
+#define NUM_MB 8
+#define MBOX_BIT BIT
+#define ALL_MBOX_BITS (MBOX_BIT(NUM_MB) - 1)
+
+/*
+* Used by MCDE to setup all necessary PRCMU registers
+*/
+#define PRCMU_RESET_DSIPLL			0x00004000
+#define PRCMU_UNCLAMP_DSIPLL			0x00400800
+
+/* HDMI CLK MGT PLLSW=001 (PLLSOC0), PLLDIV=0x8, = 50 Mhz*/
+#define PRCMU_DSI_CLOCK_SETTING			0x00000128
+/* TVCLK_MGT PLLSW=001 (PLLSOC0) PLLDIV=0x13, = 19.05 MHZ */
+#define PRCMU_DSI_LP_CLOCK_SETTING		0x00000135
+#define PRCMU_PLLDSI_FREQ_SETTING		0x0004013C
+#define PRCMU_DSI_PLLOUT_SEL_SETTING		0x00000002
+#define PRCMU_ENABLE_ESCAPE_CLOCK_DIV		0x03000101
+#define PRCMU_DISABLE_ESCAPE_CLOCK_DIV		0x00000101
+
+#define PRCMU_ENABLE_PLLDSI			0x00000001
+#define PRCMU_DISABLE_PLLDSI			0x00000000
+
+#define PRCMU_DSI_RESET_SW			0x00000003
+
+#define PRCMU_PLLDSI_LOCKP_LOCKED		0x3
+
+/*
+ * mb0_transfer - state needed for mailbox 0 communication.
+ * @lock:		The transaction lock.
+ */
+static struct {
+	spinlock_t lock;
+} mb0_transfer;
+
+/*
+ * mb5_transfer - state needed for mailbox 5 communication.
+ * @lock:	The transaction lock.
+ * @work:	The transaction completion structure.
+ * @ack:	Reply ("acknowledge") data.
+ */
+static struct {
+	struct mutex lock;
+	struct completion work;
+	struct {
+		u8 header;
+		u8 status;
+		u8 value[4];
+	} ack;
+} mb5_transfer;
+
+/* PRCMU TCDM base IO address. */
+static __iomem void *tcdm_base;
+
+/**
+ * db5500_prcmu_abb_read() - Read register value(s) from the ABB.
+ * @slave:	The I2C slave address.
+ * @reg:	The (start) register address.
+ * @value:	The read out value(s).
+ * @size:	The number of registers to read.
+ *
+ * Reads register value(s) from the ABB.
+ * @size has to be <= 4.
+ */
+int db5500_prcmu_abb_read(u8 slave, u8 reg, u8 *value, u8 size)
+{
+	int r;
+
+	if ((size < 1) || (4 < size))
+		return -EINVAL;
+
+	mutex_lock(&mb5_transfer.lock);
+
+	while (readl(PRCM_MBOX_CPU_VAL) & MBOX_BIT(5))
+		cpu_relax();
+	writeb(slave, PRCM_REQ_MB5_I2C_SLAVE);
+	writeb(reg, PRCM_REQ_MB5_I2C_REG);
+	writeb(size, PRCM_REQ_MB5_I2C_SIZE);
+	writeb(MB5H_I2C_READ, PRCM_REQ_MB5_HEADER);
+
+	writel(MBOX_BIT(5), PRCM_MBOX_CPU_SET);
+	wait_for_completion(&mb5_transfer.work);
+
+	r = 0;
+	if ((mb5_transfer.ack.header == MB5H_I2C_READ) &&
+		(mb5_transfer.ack.status == RC_SUCCESS))
+		memcpy(value, mb5_transfer.ack.value, (size_t)size);
+	else
+		r = -EIO;
+
+	mutex_unlock(&mb5_transfer.lock);
+
+	return r;
+}
+
+/**
+ * db5500_prcmu_abb_write() - Write register value(s) to the ABB.
+ * @slave:	The I2C slave address.
+ * @reg:	The (start) register address.
+ * @value:	The value(s) to write.
+ * @size:	The number of registers to write.
+ *
+ * Writes register value(s) to the ABB.
+ * @size has to be <= 4.
+ */
+int db5500_prcmu_abb_write(u8 slave, u8 reg, u8 *value, u8 size)
+{
+	int r;
+
+	if ((size < 1) || (4 < size))
+		return -EINVAL;
+
+	mutex_lock(&mb5_transfer.lock);
+
+	while (readl(PRCM_MBOX_CPU_VAL) & MBOX_BIT(5))
+		cpu_relax();
+	writeb(slave, PRCM_REQ_MB5_I2C_SLAVE);
+	writeb(reg, PRCM_REQ_MB5_I2C_REG);
+	writeb(size, PRCM_REQ_MB5_I2C_SIZE);
+	memcpy_toio(PRCM_REQ_MB5_I2C_DATA, value, size);
+	writeb(MB5H_I2C_WRITE, PRCM_REQ_MB5_HEADER);
+
+	writel(MBOX_BIT(5), PRCM_MBOX_CPU_SET);
+	wait_for_completion(&mb5_transfer.work);
+
+	if ((mb5_transfer.ack.header == MB5H_I2C_WRITE) &&
+		(mb5_transfer.ack.status == RC_SUCCESS))
+		r = 0;
+	else
+		r = -EIO;
+
+	mutex_unlock(&mb5_transfer.lock);
+
+	return r;
+}
+
+int db5500_prcmu_enable_dsipll(void)
+{
+	int i;
+
+	/* Enable DSIPLL_RESETN resets */
+	writel(PRCMU_RESET_DSIPLL, PRCM_APE_RESETN_CLR);
+	/* Unclamp DSIPLL in/out */
+	writel(PRCMU_UNCLAMP_DSIPLL, PRCM_MMIP_LS_CLAMP_CLR);
+	/* Set DSI PLL FREQ */
+	writel(PRCMU_PLLDSI_FREQ_SETTING, PRCM_PLLDSI_FREQ);
+	writel(PRCMU_DSI_PLLOUT_SEL_SETTING,
+		PRCM_DSI_PLLOUT_SEL);
+	/* Enable Escape clocks */
+	writel(PRCMU_ENABLE_ESCAPE_CLOCK_DIV, PRCM_DSITVCLK_DIV);
+
+	/* Start DSI PLL */
+	writel(PRCMU_ENABLE_PLLDSI, PRCM_PLLDSI_ENABLE);
+	/* Reset DSI PLL */
+	writel(PRCMU_DSI_RESET_SW, PRCM_DSI_SW_RESET);
+	for (i = 0; i < 10; i++) {
+		if ((readl(PRCM_PLLDSI_LOCKP) &
+			PRCMU_PLLDSI_LOCKP_LOCKED) == PRCMU_PLLDSI_LOCKP_LOCKED)
+			break;
+		udelay(100);
+	}
+	/* Release DSIPLL_RESETN */
+	writel(PRCMU_RESET_DSIPLL, PRCM_APE_RESETN_SET);
+	return 0;
+}
+
+int db5500_prcmu_disable_dsipll(void)
+{
+	/* Disable dsi pll */
+	writel(PRCMU_DISABLE_PLLDSI, PRCM_PLLDSI_ENABLE);
+	/* Disable  escapeclock */
+	writel(PRCMU_DISABLE_ESCAPE_CLOCK_DIV, PRCM_DSITVCLK_DIV);
+	return 0;
+}
+
+int db5500_prcmu_set_display_clocks(void)
+{
+	/* HDMI and TVCLK Should be handled somewhere else */
+	/* PLLDIV=8, PLLSW=2, CLKEN=1 */
+	writel(PRCMU_DSI_CLOCK_SETTING, PRCM_HDMICLK_MGT);
+	/* PLLDIV=14, PLLSW=2, CLKEN=1 */
+	writel(PRCMU_DSI_LP_CLOCK_SETTING, PRCM_TVCLK_MGT);
+	return 0;
+}
+
+static void ack_dbb_wakeup(void)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&mb0_transfer.lock, flags);
+
+	while (readl(PRCM_MBOX_CPU_VAL) & MBOX_BIT(0))
+		cpu_relax();
+
+	writeb(RMB0H_RD_WAKE_UP_ACK, PRCM_REQ_MB0_HEADER);
+	writel(MBOX_BIT(0), PRCM_MBOX_CPU_SET);
+
+	spin_unlock_irqrestore(&mb0_transfer.lock, flags);
+}
+
+static inline void print_unknown_header_warning(u8 n, u8 header)
+{
+	pr_warning("prcmu: Unknown message header (%d) in mailbox %d.\n",
+		header, n);
+}
+
+static bool read_mailbox_0(void)
+{
+	bool r;
+	u8 header;
+
+	header = readb(PRCM_ACK_MB0_HEADER);
+	switch (header) {
+	case AMB0H_WAKE_UP:
+		r = true;
+		break;
+	default:
+		print_unknown_header_warning(0, header);
+		r = false;
+		break;
+	}
+	writel(MBOX_BIT(0), PRCM_ARM_IT1_CLEAR);
+	return r;
+}
+
+static bool read_mailbox_1(void)
+{
+	writel(MBOX_BIT(1), PRCM_ARM_IT1_CLEAR);
+	return false;
+}
+
+static bool read_mailbox_2(void)
+{
+	writel(MBOX_BIT(2), PRCM_ARM_IT1_CLEAR);
+	return false;
+}
+
+static bool read_mailbox_3(void)
+{
+	writel(MBOX_BIT(3), PRCM_ARM_IT1_CLEAR);
+	return false;
+}
+
+static bool read_mailbox_4(void)
+{
+	writel(MBOX_BIT(4), PRCM_ARM_IT1_CLEAR);
+	return false;
+}
+
+static bool read_mailbox_5(void)
+{
+	u8 header;
+
+	header = readb(PRCM_ACK_MB5_HEADER);
+	switch (header) {
+	case MB5H_I2C_READ:
+		memcpy_fromio(mb5_transfer.ack.value, PRCM_ACK_MB5_I2C_DATA, 4);
+	case MB5H_I2C_WRITE:
+		mb5_transfer.ack.header = header;
+		mb5_transfer.ack.status = readb(PRCM_ACK_MB5_RETURN_CODE);
+		complete(&mb5_transfer.work);
+		break;
+	default:
+		print_unknown_header_warning(5, header);
+		break;
+	}
+	writel(MBOX_BIT(5), PRCM_ARM_IT1_CLEAR);
+	return false;
+}
+
+static bool read_mailbox_6(void)
+{
+	writel(MBOX_BIT(6), PRCM_ARM_IT1_CLEAR);
+	return false;
+}
+
+static bool read_mailbox_7(void)
+{
+	writel(MBOX_BIT(7), PRCM_ARM_IT1_CLEAR);
+	return false;
+}
+
+static bool (* const read_mailbox[NUM_MB])(void) = {
+	read_mailbox_0,
+	read_mailbox_1,
+	read_mailbox_2,
+	read_mailbox_3,
+	read_mailbox_4,
+	read_mailbox_5,
+	read_mailbox_6,
+	read_mailbox_7
+};
+
+static irqreturn_t prcmu_irq_handler(int irq, void *data)
+{
+	u32 bits;
+	u8 n;
+	irqreturn_t r;
+
+	bits = (readl(PRCM_ARM_IT1_VAL) & ALL_MBOX_BITS);
+	if (unlikely(!bits))
+		return IRQ_NONE;
+
+	r = IRQ_HANDLED;
+	for (n = 0; bits; n++) {
+		if (bits & MBOX_BIT(n)) {
+			bits -= MBOX_BIT(n);
+			if (read_mailbox[n]())
+				r = IRQ_WAKE_THREAD;
+		}
+	}
+	return r;
+}
+
+static irqreturn_t prcmu_irq_thread_fn(int irq, void *data)
+{
+	ack_dbb_wakeup();
+	return IRQ_HANDLED;
+}
+
+void __init db5500_prcmu_early_init(void)
+{
+	tcdm_base = __io_address(U5500_PRCMU_TCDM_BASE);
+	spin_lock_init(&mb0_transfer.lock);
+	mutex_init(&mb5_transfer.lock);
+	init_completion(&mb5_transfer.work);
+}
+
+/**
+ * prcmu_fw_init - arch init call for the Linux PRCMU fw init logic
+ *
+ */
+int __init db5500_prcmu_init(void)
+{
+	int r = 0;
+
+	if (ux500_is_svp() || !cpu_is_u5500())
+		return -ENODEV;
+
+	/* Clean up the mailbox interrupts after pre-kernel code. */
+	writel(ALL_MBOX_BITS, PRCM_ARM_IT1_CLEAR);
+
+	r = request_threaded_irq(IRQ_DB5500_PRCMU1, prcmu_irq_handler,
+		prcmu_irq_thread_fn, 0, "prcmu", NULL);
+	if (r < 0) {
+		pr_err("prcmu: Failed to allocate IRQ_DB5500_PRCMU1.\n");
+		return -EBUSY;
+	}
+	return 0;
+}
+
+arch_initcall(db5500_prcmu_init);
diff -druN linux-2.6.39-libre/drivers/mfd/db5500-prcmu-regs.h linux-3.0-rc7-libre/drivers/mfd/db5500-prcmu-regs.h
--- linux-2.6.39-libre/drivers/mfd/db5500-prcmu-regs.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/mfd/db5500-prcmu-regs.h	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,115 @@
+/*
+ * Copyright (C) STMicroelectronics 2009
+ * Copyright (C) ST-Ericsson SA 2010
+ *
+ * Author: Kumar Sanghvi <kumar.sanghvi@stericsson.com>
+ * Author: Sundar Iyer <sundar.iyer@stericsson.com>
+ *
+ * License Terms: GNU General Public License v2
+ *
+ * PRCM Unit registers
+ */
+
+#ifndef __MACH_PRCMU_REGS_H
+#define __MACH_PRCMU_REGS_H
+
+#include <mach/hardware.h>
+
+#define PRCM_ARM_PLLDIVPS	(_PRCMU_BASE + 0x118)
+#define PRCM_ARM_PLLDIVPS_ARM_BRM_RATE		0x3f
+#define PRCM_ARM_PLLDIVPS_MAX_MASK		0xf
+
+#define PRCM_PLLARM_LOCKP       (_PRCMU_BASE + 0x0a8)
+#define PRCM_PLLARM_LOCKP_PRCM_PLLARM_LOCKP3	0x2
+
+#define PRCM_ARM_CHGCLKREQ	(_PRCMU_BASE + 0x114)
+#define PRCM_ARM_CHGCLKREQ_PRCM_ARM_CHGCLKREQ	0x1
+
+#define PRCM_PLLARM_ENABLE	(_PRCMU_BASE + 0x98)
+#define PRCM_PLLARM_ENABLE_PRCM_PLLARM_ENABLE	0x1
+#define PRCM_PLLARM_ENABLE_PRCM_PLLARM_COUNTON	0x100
+
+#define PRCM_ARMCLKFIX_MGT	(_PRCMU_BASE + 0x0)
+#define PRCM_A9_RESETN_CLR	(_PRCMU_BASE + 0x1f4)
+#define PRCM_A9_RESETN_SET	(_PRCMU_BASE + 0x1f0)
+#define PRCM_ARM_LS_CLAMP	(_PRCMU_BASE + 0x30c)
+#define PRCM_SRAM_A9		(_PRCMU_BASE + 0x308)
+
+/* ARM WFI Standby signal register */
+#define PRCM_ARM_WFI_STANDBY    (_PRCMU_BASE + 0x130)
+#define PRCM_IOCR		(_PRCMU_BASE + 0x310)
+#define PRCM_IOCR_IOFORCE			0x1
+
+/* CPU mailbox registers */
+#define PRCM_MBOX_CPU_VAL	(_PRCMU_BASE + 0x0fc)
+#define PRCM_MBOX_CPU_SET	(_PRCMU_BASE + 0x100)
+#define PRCM_MBOX_CPU_CLR	(_PRCMU_BASE + 0x104)
+
+/* Dual A9 core interrupt management unit registers */
+#define PRCM_A9_MASK_REQ	(_PRCMU_BASE + 0x328)
+#define PRCM_A9_MASK_REQ_PRCM_A9_MASK_REQ	0x1
+
+#define PRCM_A9_MASK_ACK	(_PRCMU_BASE + 0x32c)
+#define PRCM_ARMITMSK31TO0	(_PRCMU_BASE + 0x11c)
+#define PRCM_ARMITMSK63TO32	(_PRCMU_BASE + 0x120)
+#define PRCM_ARMITMSK95TO64	(_PRCMU_BASE + 0x124)
+#define PRCM_ARMITMSK127TO96	(_PRCMU_BASE + 0x128)
+#define PRCM_POWER_STATE_VAL	(_PRCMU_BASE + 0x25C)
+#define PRCM_ARMITVAL31TO0	(_PRCMU_BASE + 0x260)
+#define PRCM_ARMITVAL63TO32	(_PRCMU_BASE + 0x264)
+#define PRCM_ARMITVAL95TO64	(_PRCMU_BASE + 0x268)
+#define PRCM_ARMITVAL127TO96	(_PRCMU_BASE + 0x26C)
+
+#define PRCM_HOSTACCESS_REQ	(_PRCMU_BASE + 0x334)
+#define ARM_WAKEUP_MODEM	0x1
+
+#define PRCM_ARM_IT1_CLEAR	(_PRCMU_BASE + 0x48C)
+#define PRCM_ARM_IT1_VAL	(_PRCMU_BASE + 0x494)
+#define PRCM_HOLD_EVT		(_PRCMU_BASE + 0x174)
+
+#define PRCM_ITSTATUS0		(_PRCMU_BASE + 0x148)
+#define PRCM_ITSTATUS1		(_PRCMU_BASE + 0x150)
+#define PRCM_ITSTATUS2		(_PRCMU_BASE + 0x158)
+#define PRCM_ITSTATUS3		(_PRCMU_BASE + 0x160)
+#define PRCM_ITSTATUS4		(_PRCMU_BASE + 0x168)
+#define PRCM_ITSTATUS5		(_PRCMU_BASE + 0x484)
+#define PRCM_ITCLEAR5		(_PRCMU_BASE + 0x488)
+#define PRCM_ARMIT_MASKXP70_IT	(_PRCMU_BASE + 0x1018)
+
+/* System reset register */
+#define PRCM_APE_SOFTRST	(_PRCMU_BASE + 0x228)
+
+/* Level shifter and clamp control registers */
+#define PRCM_MMIP_LS_CLAMP_SET     (_PRCMU_BASE + 0x420)
+#define PRCM_MMIP_LS_CLAMP_CLR     (_PRCMU_BASE + 0x424)
+
+/* PRCMU clock/PLL/reset registers */
+#define PRCM_PLLDSI_FREQ           (_PRCMU_BASE + 0x500)
+#define PRCM_PLLDSI_ENABLE         (_PRCMU_BASE + 0x504)
+#define PRCM_PLLDSI_LOCKP          (_PRCMU_BASE + 0x508)
+#define PRCM_LCDCLK_MGT            (_PRCMU_BASE + 0x044)
+#define PRCM_MCDECLK_MGT           (_PRCMU_BASE + 0x064)
+#define PRCM_HDMICLK_MGT           (_PRCMU_BASE + 0x058)
+#define PRCM_TVCLK_MGT             (_PRCMU_BASE + 0x07c)
+#define PRCM_DSI_PLLOUT_SEL        (_PRCMU_BASE + 0x530)
+#define PRCM_DSITVCLK_DIV          (_PRCMU_BASE + 0x52C)
+#define PRCM_PLLDSI_LOCKP          (_PRCMU_BASE + 0x508)
+#define PRCM_APE_RESETN_SET        (_PRCMU_BASE + 0x1E4)
+#define PRCM_APE_RESETN_CLR        (_PRCMU_BASE + 0x1E8)
+#define PRCM_CLKOCR		   (_PRCMU_BASE + 0x1CC)
+
+/* ePOD and memory power signal control registers */
+#define PRCM_EPOD_C_SET            (_PRCMU_BASE + 0x410)
+#define PRCM_SRAM_LS_SLEEP         (_PRCMU_BASE + 0x304)
+
+/* Debug power control unit registers */
+#define PRCM_POWER_STATE_SET       (_PRCMU_BASE + 0x254)
+
+/* Miscellaneous unit registers */
+#define PRCM_DSI_SW_RESET          (_PRCMU_BASE + 0x324)
+#define PRCM_GPIOCR                (_PRCMU_BASE + 0x138)
+#define PRCM_GPIOCR_DBG_STM_MOD_CMD1            0x800
+#define PRCM_GPIOCR_DBG_UARTMOD_CMD0            0x1
+
+
+#endif /* __MACH_PRCMU__REGS_H */
diff -druN linux-2.6.39-libre/drivers/mfd/db8500-prcmu.c linux-3.0-rc7-libre/drivers/mfd/db8500-prcmu.c
--- linux-2.6.39-libre/drivers/mfd/db8500-prcmu.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/mfd/db8500-prcmu.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,2070 @@
+/*
+ * Copyright (C) STMicroelectronics 2009
+ * Copyright (C) ST-Ericsson SA 2010
+ *
+ * License Terms: GNU General Public License v2
+ * Author: Kumar Sanghvi <kumar.sanghvi@stericsson.com>
+ * Author: Sundar Iyer <sundar.iyer@stericsson.com>
+ * Author: Mattias Nilsson <mattias.i.nilsson@stericsson.com>
+ *
+ * U8500 PRCM Unit interface driver
+ *
+ */
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/delay.h>
+#include <linux/errno.h>
+#include <linux/err.h>
+#include <linux/spinlock.h>
+#include <linux/io.h>
+#include <linux/slab.h>
+#include <linux/mutex.h>
+#include <linux/completion.h>
+#include <linux/irq.h>
+#include <linux/jiffies.h>
+#include <linux/bitops.h>
+#include <linux/fs.h>
+#include <linux/platform_device.h>
+#include <linux/uaccess.h>
+#include <linux/mfd/core.h>
+#include <linux/mfd/db8500-prcmu.h>
+#include <linux/regulator/db8500-prcmu.h>
+#include <linux/regulator/machine.h>
+#include <mach/hardware.h>
+#include <mach/irqs.h>
+#include <mach/db8500-regs.h>
+#include <mach/id.h>
+#include "db8500-prcmu-regs.h"
+
+/* Offset for the firmware version within the TCPM */
+#define PRCMU_FW_VERSION_OFFSET 0xA4
+
+/* PRCMU project numbers, defined by PRCMU FW */
+#define PRCMU_PROJECT_ID_8500V1_0 1
+#define PRCMU_PROJECT_ID_8500V2_0 2
+#define PRCMU_PROJECT_ID_8400V2_0 3
+
+/* Index of different voltages to be used when accessing AVSData */
+#define PRCM_AVS_BASE		0x2FC
+#define PRCM_AVS_VBB_RET	(PRCM_AVS_BASE + 0x0)
+#define PRCM_AVS_VBB_MAX_OPP	(PRCM_AVS_BASE + 0x1)
+#define PRCM_AVS_VBB_100_OPP	(PRCM_AVS_BASE + 0x2)
+#define PRCM_AVS_VBB_50_OPP	(PRCM_AVS_BASE + 0x3)
+#define PRCM_AVS_VARM_MAX_OPP	(PRCM_AVS_BASE + 0x4)
+#define PRCM_AVS_VARM_100_OPP	(PRCM_AVS_BASE + 0x5)
+#define PRCM_AVS_VARM_50_OPP	(PRCM_AVS_BASE + 0x6)
+#define PRCM_AVS_VARM_RET	(PRCM_AVS_BASE + 0x7)
+#define PRCM_AVS_VAPE_100_OPP	(PRCM_AVS_BASE + 0x8)
+#define PRCM_AVS_VAPE_50_OPP	(PRCM_AVS_BASE + 0x9)
+#define PRCM_AVS_VMOD_100_OPP	(PRCM_AVS_BASE + 0xA)
+#define PRCM_AVS_VMOD_50_OPP	(PRCM_AVS_BASE + 0xB)
+#define PRCM_AVS_VSAFE		(PRCM_AVS_BASE + 0xC)
+
+#define PRCM_AVS_VOLTAGE		0
+#define PRCM_AVS_VOLTAGE_MASK		0x3f
+#define PRCM_AVS_ISSLOWSTARTUP		6
+#define PRCM_AVS_ISSLOWSTARTUP_MASK	(1 << PRCM_AVS_ISSLOWSTARTUP)
+#define PRCM_AVS_ISMODEENABLE		7
+#define PRCM_AVS_ISMODEENABLE_MASK	(1 << PRCM_AVS_ISMODEENABLE)
+
+#define PRCM_BOOT_STATUS	0xFFF
+#define PRCM_ROMCODE_A2P	0xFFE
+#define PRCM_ROMCODE_P2A	0xFFD
+#define PRCM_XP70_CUR_PWR_STATE 0xFFC      /* 4 BYTES */
+
+#define PRCM_SW_RST_REASON 0xFF8 /* 2 bytes */
+
+#define _PRCM_MBOX_HEADER		0xFE8 /* 16 bytes */
+#define PRCM_MBOX_HEADER_REQ_MB0	(_PRCM_MBOX_HEADER + 0x0)
+#define PRCM_MBOX_HEADER_REQ_MB1	(_PRCM_MBOX_HEADER + 0x1)
+#define PRCM_MBOX_HEADER_REQ_MB2	(_PRCM_MBOX_HEADER + 0x2)
+#define PRCM_MBOX_HEADER_REQ_MB3	(_PRCM_MBOX_HEADER + 0x3)
+#define PRCM_MBOX_HEADER_REQ_MB4	(_PRCM_MBOX_HEADER + 0x4)
+#define PRCM_MBOX_HEADER_REQ_MB5	(_PRCM_MBOX_HEADER + 0x5)
+#define PRCM_MBOX_HEADER_ACK_MB0	(_PRCM_MBOX_HEADER + 0x8)
+
+/* Req Mailboxes */
+#define PRCM_REQ_MB0 0xFDC /* 12 bytes  */
+#define PRCM_REQ_MB1 0xFD0 /* 12 bytes  */
+#define PRCM_REQ_MB2 0xFC0 /* 16 bytes  */
+#define PRCM_REQ_MB3 0xE4C /* 372 bytes  */
+#define PRCM_REQ_MB4 0xE48 /* 4 bytes  */
+#define PRCM_REQ_MB5 0xE44 /* 4 bytes  */
+
+/* Ack Mailboxes */
+#define PRCM_ACK_MB0 0xE08 /* 52 bytes  */
+#define PRCM_ACK_MB1 0xE04 /* 4 bytes */
+#define PRCM_ACK_MB2 0xE00 /* 4 bytes */
+#define PRCM_ACK_MB3 0xDFC /* 4 bytes */
+#define PRCM_ACK_MB4 0xDF8 /* 4 bytes */
+#define PRCM_ACK_MB5 0xDF4 /* 4 bytes */
+
+/* Mailbox 0 headers */
+#define MB0H_POWER_STATE_TRANS		0
+#define MB0H_CONFIG_WAKEUPS_EXE		1
+#define MB0H_READ_WAKEUP_ACK		3
+#define MB0H_CONFIG_WAKEUPS_SLEEP	4
+
+#define MB0H_WAKEUP_EXE 2
+#define MB0H_WAKEUP_SLEEP 5
+
+/* Mailbox 0 REQs */
+#define PRCM_REQ_MB0_AP_POWER_STATE	(PRCM_REQ_MB0 + 0x0)
+#define PRCM_REQ_MB0_AP_PLL_STATE	(PRCM_REQ_MB0 + 0x1)
+#define PRCM_REQ_MB0_ULP_CLOCK_STATE	(PRCM_REQ_MB0 + 0x2)
+#define PRCM_REQ_MB0_DO_NOT_WFI		(PRCM_REQ_MB0 + 0x3)
+#define PRCM_REQ_MB0_WAKEUP_8500	(PRCM_REQ_MB0 + 0x4)
+#define PRCM_REQ_MB0_WAKEUP_4500	(PRCM_REQ_MB0 + 0x8)
+
+/* Mailbox 0 ACKs */
+#define PRCM_ACK_MB0_AP_PWRSTTR_STATUS	(PRCM_ACK_MB0 + 0x0)
+#define PRCM_ACK_MB0_READ_POINTER	(PRCM_ACK_MB0 + 0x1)
+#define PRCM_ACK_MB0_WAKEUP_0_8500	(PRCM_ACK_MB0 + 0x4)
+#define PRCM_ACK_MB0_WAKEUP_0_4500	(PRCM_ACK_MB0 + 0x8)
+#define PRCM_ACK_MB0_WAKEUP_1_8500	(PRCM_ACK_MB0 + 0x1C)
+#define PRCM_ACK_MB0_WAKEUP_1_4500	(PRCM_ACK_MB0 + 0x20)
+#define PRCM_ACK_MB0_EVENT_4500_NUMBERS	20
+
+/* Mailbox 1 headers */
+#define MB1H_ARM_APE_OPP 0x0
+#define MB1H_RESET_MODEM 0x2
+#define MB1H_REQUEST_APE_OPP_100_VOLT 0x3
+#define MB1H_RELEASE_APE_OPP_100_VOLT 0x4
+#define MB1H_RELEASE_USB_WAKEUP 0x5
+
+/* Mailbox 1 Requests */
+#define PRCM_REQ_MB1_ARM_OPP			(PRCM_REQ_MB1 + 0x0)
+#define PRCM_REQ_MB1_APE_OPP			(PRCM_REQ_MB1 + 0x1)
+#define PRCM_REQ_MB1_APE_OPP_100_RESTORE	(PRCM_REQ_MB1 + 0x4)
+#define PRCM_REQ_MB1_ARM_OPP_100_RESTORE	(PRCM_REQ_MB1 + 0x8)
+
+/* Mailbox 1 ACKs */
+#define PRCM_ACK_MB1_CURRENT_ARM_OPP	(PRCM_ACK_MB1 + 0x0)
+#define PRCM_ACK_MB1_CURRENT_APE_OPP	(PRCM_ACK_MB1 + 0x1)
+#define PRCM_ACK_MB1_APE_VOLTAGE_STATUS	(PRCM_ACK_MB1 + 0x2)
+#define PRCM_ACK_MB1_DVFS_STATUS	(PRCM_ACK_MB1 + 0x3)
+
+/* Mailbox 2 headers */
+#define MB2H_DPS	0x0
+#define MB2H_AUTO_PWR	0x1
+
+/* Mailbox 2 REQs */
+#define PRCM_REQ_MB2_SVA_MMDSP		(PRCM_REQ_MB2 + 0x0)
+#define PRCM_REQ_MB2_SVA_PIPE		(PRCM_REQ_MB2 + 0x1)
+#define PRCM_REQ_MB2_SIA_MMDSP		(PRCM_REQ_MB2 + 0x2)
+#define PRCM_REQ_MB2_SIA_PIPE		(PRCM_REQ_MB2 + 0x3)
+#define PRCM_REQ_MB2_SGA		(PRCM_REQ_MB2 + 0x4)
+#define PRCM_REQ_MB2_B2R2_MCDE		(PRCM_REQ_MB2 + 0x5)
+#define PRCM_REQ_MB2_ESRAM12		(PRCM_REQ_MB2 + 0x6)
+#define PRCM_REQ_MB2_ESRAM34		(PRCM_REQ_MB2 + 0x7)
+#define PRCM_REQ_MB2_AUTO_PM_SLEEP	(PRCM_REQ_MB2 + 0x8)
+#define PRCM_REQ_MB2_AUTO_PM_IDLE	(PRCM_REQ_MB2 + 0xC)
+
+/* Mailbox 2 ACKs */
+#define PRCM_ACK_MB2_DPS_STATUS (PRCM_ACK_MB2 + 0x0)
+#define HWACC_PWR_ST_OK 0xFE
+
+/* Mailbox 3 headers */
+#define MB3H_ANC	0x0
+#define MB3H_SIDETONE	0x1
+#define MB3H_SYSCLK	0xE
+
+/* Mailbox 3 Requests */
+#define PRCM_REQ_MB3_ANC_FIR_COEFF	(PRCM_REQ_MB3 + 0x0)
+#define PRCM_REQ_MB3_ANC_IIR_COEFF	(PRCM_REQ_MB3 + 0x20)
+#define PRCM_REQ_MB3_ANC_SHIFTER	(PRCM_REQ_MB3 + 0x60)
+#define PRCM_REQ_MB3_ANC_WARP		(PRCM_REQ_MB3 + 0x64)
+#define PRCM_REQ_MB3_SIDETONE_FIR_GAIN	(PRCM_REQ_MB3 + 0x68)
+#define PRCM_REQ_MB3_SIDETONE_FIR_COEFF	(PRCM_REQ_MB3 + 0x6C)
+#define PRCM_REQ_MB3_SYSCLK_MGT		(PRCM_REQ_MB3 + 0x16C)
+
+/* Mailbox 4 headers */
+#define MB4H_DDR_INIT	0x0
+#define MB4H_MEM_ST	0x1
+#define MB4H_HOTDOG	0x12
+#define MB4H_HOTMON	0x13
+#define MB4H_HOT_PERIOD	0x14
+
+/* Mailbox 4 Requests */
+#define PRCM_REQ_MB4_DDR_ST_AP_SLEEP_IDLE	(PRCM_REQ_MB4 + 0x0)
+#define PRCM_REQ_MB4_DDR_ST_AP_DEEP_IDLE	(PRCM_REQ_MB4 + 0x1)
+#define PRCM_REQ_MB4_ESRAM0_ST			(PRCM_REQ_MB4 + 0x3)
+#define PRCM_REQ_MB4_HOTDOG_THRESHOLD		(PRCM_REQ_MB4 + 0x0)
+#define PRCM_REQ_MB4_HOTMON_LOW			(PRCM_REQ_MB4 + 0x0)
+#define PRCM_REQ_MB4_HOTMON_HIGH		(PRCM_REQ_MB4 + 0x1)
+#define PRCM_REQ_MB4_HOTMON_CONFIG		(PRCM_REQ_MB4 + 0x2)
+#define PRCM_REQ_MB4_HOT_PERIOD			(PRCM_REQ_MB4 + 0x0)
+#define HOTMON_CONFIG_LOW			BIT(0)
+#define HOTMON_CONFIG_HIGH			BIT(1)
+
+/* Mailbox 5 Requests */
+#define PRCM_REQ_MB5_I2C_SLAVE_OP	(PRCM_REQ_MB5 + 0x0)
+#define PRCM_REQ_MB5_I2C_HW_BITS	(PRCM_REQ_MB5 + 0x1)
+#define PRCM_REQ_MB5_I2C_REG		(PRCM_REQ_MB5 + 0x2)
+#define PRCM_REQ_MB5_I2C_VAL		(PRCM_REQ_MB5 + 0x3)
+#define PRCMU_I2C_WRITE(slave) \
+	(((slave) << 1) | (cpu_is_u8500v2() ? BIT(6) : 0))
+#define PRCMU_I2C_READ(slave) \
+	(((slave) << 1) | BIT(0) | (cpu_is_u8500v2() ? BIT(6) : 0))
+#define PRCMU_I2C_STOP_EN		BIT(3)
+
+/* Mailbox 5 ACKs */
+#define PRCM_ACK_MB5_I2C_STATUS	(PRCM_ACK_MB5 + 0x1)
+#define PRCM_ACK_MB5_I2C_VAL	(PRCM_ACK_MB5 + 0x3)
+#define I2C_WR_OK 0x1
+#define I2C_RD_OK 0x2
+
+#define NUM_MB 8
+#define MBOX_BIT BIT
+#define ALL_MBOX_BITS (MBOX_BIT(NUM_MB) - 1)
+
+/*
+ * Wakeups/IRQs
+ */
+
+#define WAKEUP_BIT_RTC BIT(0)
+#define WAKEUP_BIT_RTT0 BIT(1)
+#define WAKEUP_BIT_RTT1 BIT(2)
+#define WAKEUP_BIT_HSI0 BIT(3)
+#define WAKEUP_BIT_HSI1 BIT(4)
+#define WAKEUP_BIT_CA_WAKE BIT(5)
+#define WAKEUP_BIT_USB BIT(6)
+#define WAKEUP_BIT_ABB BIT(7)
+#define WAKEUP_BIT_ABB_FIFO BIT(8)
+#define WAKEUP_BIT_SYSCLK_OK BIT(9)
+#define WAKEUP_BIT_CA_SLEEP BIT(10)
+#define WAKEUP_BIT_AC_WAKE_ACK BIT(11)
+#define WAKEUP_BIT_SIDE_TONE_OK BIT(12)
+#define WAKEUP_BIT_ANC_OK BIT(13)
+#define WAKEUP_BIT_SW_ERROR BIT(14)
+#define WAKEUP_BIT_AC_SLEEP_ACK BIT(15)
+#define WAKEUP_BIT_ARM BIT(17)
+#define WAKEUP_BIT_HOTMON_LOW BIT(18)
+#define WAKEUP_BIT_HOTMON_HIGH BIT(19)
+#define WAKEUP_BIT_MODEM_SW_RESET_REQ BIT(20)
+#define WAKEUP_BIT_GPIO0 BIT(23)
+#define WAKEUP_BIT_GPIO1 BIT(24)
+#define WAKEUP_BIT_GPIO2 BIT(25)
+#define WAKEUP_BIT_GPIO3 BIT(26)
+#define WAKEUP_BIT_GPIO4 BIT(27)
+#define WAKEUP_BIT_GPIO5 BIT(28)
+#define WAKEUP_BIT_GPIO6 BIT(29)
+#define WAKEUP_BIT_GPIO7 BIT(30)
+#define WAKEUP_BIT_GPIO8 BIT(31)
+
+/*
+ * This vector maps irq numbers to the bits in the bit field used in
+ * communication with the PRCMU firmware.
+ *
+ * The reason for having this is to keep the irq numbers contiguous even though
+ * the bits in the bit field are not. (The bits also have a tendency to move
+ * around, to further complicate matters.)
+ */
+#define IRQ_INDEX(_name) ((IRQ_PRCMU_##_name) - IRQ_PRCMU_BASE)
+#define IRQ_ENTRY(_name)[IRQ_INDEX(_name)] = (WAKEUP_BIT_##_name)
+static u32 prcmu_irq_bit[NUM_PRCMU_WAKEUPS] = {
+	IRQ_ENTRY(RTC),
+	IRQ_ENTRY(RTT0),
+	IRQ_ENTRY(RTT1),
+	IRQ_ENTRY(HSI0),
+	IRQ_ENTRY(HSI1),
+	IRQ_ENTRY(CA_WAKE),
+	IRQ_ENTRY(USB),
+	IRQ_ENTRY(ABB),
+	IRQ_ENTRY(ABB_FIFO),
+	IRQ_ENTRY(CA_SLEEP),
+	IRQ_ENTRY(ARM),
+	IRQ_ENTRY(HOTMON_LOW),
+	IRQ_ENTRY(HOTMON_HIGH),
+	IRQ_ENTRY(MODEM_SW_RESET_REQ),
+	IRQ_ENTRY(GPIO0),
+	IRQ_ENTRY(GPIO1),
+	IRQ_ENTRY(GPIO2),
+	IRQ_ENTRY(GPIO3),
+	IRQ_ENTRY(GPIO4),
+	IRQ_ENTRY(GPIO5),
+	IRQ_ENTRY(GPIO6),
+	IRQ_ENTRY(GPIO7),
+	IRQ_ENTRY(GPIO8)
+};
+
+#define VALID_WAKEUPS (BIT(NUM_PRCMU_WAKEUP_INDICES) - 1)
+#define WAKEUP_ENTRY(_name)[PRCMU_WAKEUP_INDEX_##_name] = (WAKEUP_BIT_##_name)
+static u32 prcmu_wakeup_bit[NUM_PRCMU_WAKEUP_INDICES] = {
+	WAKEUP_ENTRY(RTC),
+	WAKEUP_ENTRY(RTT0),
+	WAKEUP_ENTRY(RTT1),
+	WAKEUP_ENTRY(HSI0),
+	WAKEUP_ENTRY(HSI1),
+	WAKEUP_ENTRY(USB),
+	WAKEUP_ENTRY(ABB),
+	WAKEUP_ENTRY(ABB_FIFO),
+	WAKEUP_ENTRY(ARM)
+};
+
+/*
+ * mb0_transfer - state needed for mailbox 0 communication.
+ * @lock:		The transaction lock.
+ * @dbb_events_lock:	A lock used to handle concurrent access to (parts of)
+ *			the request data.
+ * @mask_work:		Work structure used for (un)masking wakeup interrupts.
+ * @req:		Request data that need to persist between requests.
+ */
+static struct {
+	spinlock_t lock;
+	spinlock_t dbb_irqs_lock;
+	struct work_struct mask_work;
+	struct mutex ac_wake_lock;
+	struct completion ac_wake_work;
+	struct {
+		u32 dbb_irqs;
+		u32 dbb_wakeups;
+		u32 abb_events;
+	} req;
+} mb0_transfer;
+
+/*
+ * mb1_transfer - state needed for mailbox 1 communication.
+ * @lock:	The transaction lock.
+ * @work:	The transaction completion structure.
+ * @ack:	Reply ("acknowledge") data.
+ */
+static struct {
+	struct mutex lock;
+	struct completion work;
+	struct {
+		u8 header;
+		u8 arm_opp;
+		u8 ape_opp;
+		u8 ape_voltage_status;
+	} ack;
+} mb1_transfer;
+
+/*
+ * mb2_transfer - state needed for mailbox 2 communication.
+ * @lock:            The transaction lock.
+ * @work:            The transaction completion structure.
+ * @auto_pm_lock:    The autonomous power management configuration lock.
+ * @auto_pm_enabled: A flag indicating whether autonomous PM is enabled.
+ * @req:             Request data that need to persist between requests.
+ * @ack:             Reply ("acknowledge") data.
+ */
+static struct {
+	struct mutex lock;
+	struct completion work;
+	spinlock_t auto_pm_lock;
+	bool auto_pm_enabled;
+	struct {
+		u8 status;
+	} ack;
+} mb2_transfer;
+
+/*
+ * mb3_transfer - state needed for mailbox 3 communication.
+ * @lock:		The request lock.
+ * @sysclk_lock:	A lock used to handle concurrent sysclk requests.
+ * @sysclk_work:	Work structure used for sysclk requests.
+ */
+static struct {
+	spinlock_t lock;
+	struct mutex sysclk_lock;
+	struct completion sysclk_work;
+} mb3_transfer;
+
+/*
+ * mb4_transfer - state needed for mailbox 4 communication.
+ * @lock:	The transaction lock.
+ * @work:	The transaction completion structure.
+ */
+static struct {
+	struct mutex lock;
+	struct completion work;
+} mb4_transfer;
+
+/*
+ * mb5_transfer - state needed for mailbox 5 communication.
+ * @lock:	The transaction lock.
+ * @work:	The transaction completion structure.
+ * @ack:	Reply ("acknowledge") data.
+ */
+static struct {
+	struct mutex lock;
+	struct completion work;
+	struct {
+		u8 status;
+		u8 value;
+	} ack;
+} mb5_transfer;
+
+static atomic_t ac_wake_req_state = ATOMIC_INIT(0);
+
+/* Spinlocks */
+static DEFINE_SPINLOCK(clkout_lock);
+static DEFINE_SPINLOCK(gpiocr_lock);
+
+/* Global var to runtime determine TCDM base for v2 or v1 */
+static __iomem void *tcdm_base;
+
+struct clk_mgt {
+	unsigned int offset;
+	u32 pllsw;
+};
+
+static DEFINE_SPINLOCK(clk_mgt_lock);
+
+#define CLK_MGT_ENTRY(_name)[PRCMU_##_name] = { (PRCM_##_name##_MGT), 0 }
+struct clk_mgt clk_mgt[PRCMU_NUM_REG_CLOCKS] = {
+	CLK_MGT_ENTRY(SGACLK),
+	CLK_MGT_ENTRY(UARTCLK),
+	CLK_MGT_ENTRY(MSP02CLK),
+	CLK_MGT_ENTRY(MSP1CLK),
+	CLK_MGT_ENTRY(I2CCLK),
+	CLK_MGT_ENTRY(SDMMCCLK),
+	CLK_MGT_ENTRY(SLIMCLK),
+	CLK_MGT_ENTRY(PER1CLK),
+	CLK_MGT_ENTRY(PER2CLK),
+	CLK_MGT_ENTRY(PER3CLK),
+	CLK_MGT_ENTRY(PER5CLK),
+	CLK_MGT_ENTRY(PER6CLK),
+	CLK_MGT_ENTRY(PER7CLK),
+	CLK_MGT_ENTRY(LCDCLK),
+	CLK_MGT_ENTRY(BMLCLK),
+	CLK_MGT_ENTRY(HSITXCLK),
+	CLK_MGT_ENTRY(HSIRXCLK),
+	CLK_MGT_ENTRY(HDMICLK),
+	CLK_MGT_ENTRY(APEATCLK),
+	CLK_MGT_ENTRY(APETRACECLK),
+	CLK_MGT_ENTRY(MCDECLK),
+	CLK_MGT_ENTRY(IPI2CCLK),
+	CLK_MGT_ENTRY(DSIALTCLK),
+	CLK_MGT_ENTRY(DMACLK),
+	CLK_MGT_ENTRY(B2R2CLK),
+	CLK_MGT_ENTRY(TVCLK),
+	CLK_MGT_ENTRY(SSPCLK),
+	CLK_MGT_ENTRY(RNGCLK),
+	CLK_MGT_ENTRY(UICCCLK),
+};
+
+/*
+* Used by MCDE to setup all necessary PRCMU registers
+*/
+#define PRCMU_RESET_DSIPLL		0x00004000
+#define PRCMU_UNCLAMP_DSIPLL		0x00400800
+
+#define PRCMU_CLK_PLL_DIV_SHIFT		0
+#define PRCMU_CLK_PLL_SW_SHIFT		5
+#define PRCMU_CLK_38			(1 << 9)
+#define PRCMU_CLK_38_SRC		(1 << 10)
+#define PRCMU_CLK_38_DIV		(1 << 11)
+
+/* PLLDIV=12, PLLSW=4 (PLLDDR) */
+#define PRCMU_DSI_CLOCK_SETTING		0x0000008C
+
+/* PLLDIV=8, PLLSW=4 (PLLDDR) */
+#define PRCMU_DSI_CLOCK_SETTING_U8400	0x00000088
+
+/* DPI 50000000 Hz */
+#define PRCMU_DPI_CLOCK_SETTING		((1 << PRCMU_CLK_PLL_SW_SHIFT) | \
+					  (16 << PRCMU_CLK_PLL_DIV_SHIFT))
+#define PRCMU_DSI_LP_CLOCK_SETTING	0x00000E00
+
+/* D=101, N=1, R=4, SELDIV2=0 */
+#define PRCMU_PLLDSI_FREQ_SETTING	0x00040165
+
+/* D=70, N=1, R=3, SELDIV2=0 */
+#define PRCMU_PLLDSI_FREQ_SETTING_U8400	0x00030146
+
+#define PRCMU_ENABLE_PLLDSI		0x00000001
+#define PRCMU_DISABLE_PLLDSI		0x00000000
+#define PRCMU_RELEASE_RESET_DSS		0x0000400C
+#define PRCMU_DSI_PLLOUT_SEL_SETTING	0x00000202
+/* ESC clk, div0=1, div1=1, div2=3 */
+#define PRCMU_ENABLE_ESCAPE_CLOCK_DIV	0x07030101
+#define PRCMU_DISABLE_ESCAPE_CLOCK_DIV	0x00030101
+#define PRCMU_DSI_RESET_SW		0x00000007
+
+#define PRCMU_PLLDSI_LOCKP_LOCKED	0x3
+
+static struct {
+	u8 project_number;
+	u8 api_version;
+	u8 func_version;
+	u8 errata;
+} prcmu_version;
+
+
+int prcmu_enable_dsipll(void)
+{
+	int i;
+	unsigned int plldsifreq;
+
+	/* Clear DSIPLL_RESETN */
+	writel(PRCMU_RESET_DSIPLL, (_PRCMU_BASE + PRCM_APE_RESETN_CLR));
+	/* Unclamp DSIPLL in/out */
+	writel(PRCMU_UNCLAMP_DSIPLL, (_PRCMU_BASE + PRCM_MMIP_LS_CLAMP_CLR));
+
+	if (prcmu_is_u8400())
+		plldsifreq = PRCMU_PLLDSI_FREQ_SETTING_U8400;
+	else
+		plldsifreq = PRCMU_PLLDSI_FREQ_SETTING;
+	/* Set DSI PLL FREQ */
+	writel(plldsifreq, (_PRCMU_BASE + PRCM_PLLDSI_FREQ));
+	writel(PRCMU_DSI_PLLOUT_SEL_SETTING,
+		(_PRCMU_BASE + PRCM_DSI_PLLOUT_SEL));
+	/* Enable Escape clocks */
+	writel(PRCMU_ENABLE_ESCAPE_CLOCK_DIV,
+					(_PRCMU_BASE + PRCM_DSITVCLK_DIV));
+
+	/* Start DSI PLL */
+	writel(PRCMU_ENABLE_PLLDSI, (_PRCMU_BASE + PRCM_PLLDSI_ENABLE));
+	/* Reset DSI PLL */
+	writel(PRCMU_DSI_RESET_SW, (_PRCMU_BASE + PRCM_DSI_SW_RESET));
+	for (i = 0; i < 10; i++) {
+		if ((readl(_PRCMU_BASE + PRCM_PLLDSI_LOCKP) &
+			PRCMU_PLLDSI_LOCKP_LOCKED)
+					== PRCMU_PLLDSI_LOCKP_LOCKED)
+			break;
+		udelay(100);
+	}
+	/* Set DSIPLL_RESETN */
+	writel(PRCMU_RESET_DSIPLL, (_PRCMU_BASE + PRCM_APE_RESETN_SET));
+	return 0;
+}
+
+int prcmu_disable_dsipll(void)
+{
+	/* Disable dsi pll */
+	writel(PRCMU_DISABLE_PLLDSI, (_PRCMU_BASE + PRCM_PLLDSI_ENABLE));
+	/* Disable  escapeclock */
+	writel(PRCMU_DISABLE_ESCAPE_CLOCK_DIV,
+					(_PRCMU_BASE + PRCM_DSITVCLK_DIV));
+	return 0;
+}
+
+int prcmu_set_display_clocks(void)
+{
+	unsigned long flags;
+	unsigned int dsiclk;
+
+	if (prcmu_is_u8400())
+		dsiclk = PRCMU_DSI_CLOCK_SETTING_U8400;
+	else
+		dsiclk = PRCMU_DSI_CLOCK_SETTING;
+
+	spin_lock_irqsave(&clk_mgt_lock, flags);
+
+	/* Grab the HW semaphore. */
+	while ((readl(_PRCMU_BASE + PRCM_SEM) & PRCM_SEM_PRCM_SEM) != 0)
+		cpu_relax();
+
+	writel(dsiclk, (_PRCMU_BASE + PRCM_HDMICLK_MGT));
+	writel(PRCMU_DSI_LP_CLOCK_SETTING, (_PRCMU_BASE + PRCM_TVCLK_MGT));
+	writel(PRCMU_DPI_CLOCK_SETTING, (_PRCMU_BASE + PRCM_LCDCLK_MGT));
+
+	/* Release the HW semaphore. */
+	writel(0, (_PRCMU_BASE + PRCM_SEM));
+
+	spin_unlock_irqrestore(&clk_mgt_lock, flags);
+
+	return 0;
+}
+
+/**
+ * prcmu_enable_spi2 - Enables pin muxing for SPI2 on OtherAlternateC1.
+ */
+void prcmu_enable_spi2(void)
+{
+	u32 reg;
+	unsigned long flags;
+
+	spin_lock_irqsave(&gpiocr_lock, flags);
+	reg = readl(_PRCMU_BASE + PRCM_GPIOCR);
+	writel(reg | PRCM_GPIOCR_SPI2_SELECT, _PRCMU_BASE + PRCM_GPIOCR);
+	spin_unlock_irqrestore(&gpiocr_lock, flags);
+}
+
+/**
+ * prcmu_disable_spi2 - Disables pin muxing for SPI2 on OtherAlternateC1.
+ */
+void prcmu_disable_spi2(void)
+{
+	u32 reg;
+	unsigned long flags;
+
+	spin_lock_irqsave(&gpiocr_lock, flags);
+	reg = readl(_PRCMU_BASE + PRCM_GPIOCR);
+	writel(reg & ~PRCM_GPIOCR_SPI2_SELECT, _PRCMU_BASE + PRCM_GPIOCR);
+	spin_unlock_irqrestore(&gpiocr_lock, flags);
+}
+
+bool prcmu_has_arm_maxopp(void)
+{
+	return (readb(tcdm_base + PRCM_AVS_VARM_MAX_OPP) &
+		PRCM_AVS_ISMODEENABLE_MASK) == PRCM_AVS_ISMODEENABLE_MASK;
+}
+
+bool prcmu_is_u8400(void)
+{
+	return prcmu_version.project_number == PRCMU_PROJECT_ID_8400V2_0;
+}
+
+/**
+ * prcmu_get_boot_status - PRCMU boot status checking
+ * Returns: the current PRCMU boot status
+ */
+int prcmu_get_boot_status(void)
+{
+	return readb(tcdm_base + PRCM_BOOT_STATUS);
+}
+
+/**
+ * prcmu_set_rc_a2p - This function is used to run few power state sequences
+ * @val: Value to be set, i.e. transition requested
+ * Returns: 0 on success, -EINVAL on invalid argument
+ *
+ * This function is used to run the following power state sequences -
+ * any state to ApReset,  ApDeepSleep to ApExecute, ApExecute to ApDeepSleep
+ */
+int prcmu_set_rc_a2p(enum romcode_write val)
+{
+	if (val < RDY_2_DS || val > RDY_2_XP70_RST)
+		return -EINVAL;
+	writeb(val, (tcdm_base + PRCM_ROMCODE_A2P));
+	return 0;
+}
+
+/**
+ * prcmu_get_rc_p2a - This function is used to get power state sequences
+ * Returns: the power transition that has last happened
+ *
+ * This function can return the following transitions-
+ * any state to ApReset,  ApDeepSleep to ApExecute, ApExecute to ApDeepSleep
+ */
+enum romcode_read prcmu_get_rc_p2a(void)
+{
+	return readb(tcdm_base + PRCM_ROMCODE_P2A);
+}
+
+/**
+ * prcmu_get_current_mode - Return the current XP70 power mode
+ * Returns: Returns the current AP(ARM) power mode: init,
+ * apBoot, apExecute, apDeepSleep, apSleep, apIdle, apReset
+ */
+enum ap_pwrst prcmu_get_xp70_current_state(void)
+{
+	return readb(tcdm_base + PRCM_XP70_CUR_PWR_STATE);
+}
+
+/**
+ * prcmu_config_clkout - Configure one of the programmable clock outputs.
+ * @clkout:	The CLKOUT number (0 or 1).
+ * @source:	The clock to be used (one of the PRCMU_CLKSRC_*).
+ * @div:	The divider to be applied.
+ *
+ * Configures one of the programmable clock outputs (CLKOUTs).
+ * @div should be in the range [1,63] to request a configuration, or 0 to
+ * inform that the configuration is no longer requested.
+ */
+int prcmu_config_clkout(u8 clkout, u8 source, u8 div)
+{
+	static int requests[2];
+	int r = 0;
+	unsigned long flags;
+	u32 val;
+	u32 bits;
+	u32 mask;
+	u32 div_mask;
+
+	BUG_ON(clkout > 1);
+	BUG_ON(div > 63);
+	BUG_ON((clkout == 0) && (source > PRCMU_CLKSRC_CLK009));
+
+	if (!div && !requests[clkout])
+		return -EINVAL;
+
+	switch (clkout) {
+	case 0:
+		div_mask = PRCM_CLKOCR_CLKODIV0_MASK;
+		mask = (PRCM_CLKOCR_CLKODIV0_MASK | PRCM_CLKOCR_CLKOSEL0_MASK);
+		bits = ((source << PRCM_CLKOCR_CLKOSEL0_SHIFT) |
+			(div << PRCM_CLKOCR_CLKODIV0_SHIFT));
+		break;
+	case 1:
+		div_mask = PRCM_CLKOCR_CLKODIV1_MASK;
+		mask = (PRCM_CLKOCR_CLKODIV1_MASK | PRCM_CLKOCR_CLKOSEL1_MASK |
+			PRCM_CLKOCR_CLK1TYPE);
+		bits = ((source << PRCM_CLKOCR_CLKOSEL1_SHIFT) |
+			(div << PRCM_CLKOCR_CLKODIV1_SHIFT));
+		break;
+	}
+	bits &= mask;
+
+	spin_lock_irqsave(&clkout_lock, flags);
+
+	val = readl(_PRCMU_BASE + PRCM_CLKOCR);
+	if (val & div_mask) {
+		if (div) {
+			if ((val & mask) != bits) {
+				r = -EBUSY;
+				goto unlock_and_return;
+			}
+		} else {
+			if ((val & mask & ~div_mask) != bits) {
+				r = -EINVAL;
+				goto unlock_and_return;
+			}
+		}
+	}
+	writel((bits | (val & ~mask)), (_PRCMU_BASE + PRCM_CLKOCR));
+	requests[clkout] += (div ? 1 : -1);
+
+unlock_and_return:
+	spin_unlock_irqrestore(&clkout_lock, flags);
+
+	return r;
+}
+
+int prcmu_set_power_state(u8 state, bool keep_ulp_clk, bool keep_ap_pll)
+{
+	unsigned long flags;
+
+	BUG_ON((state < PRCMU_AP_SLEEP) || (PRCMU_AP_DEEP_IDLE < state));
+
+	spin_lock_irqsave(&mb0_transfer.lock, flags);
+
+	while (readl(_PRCMU_BASE + PRCM_MBOX_CPU_VAL) & MBOX_BIT(0))
+		cpu_relax();
+
+	writeb(MB0H_POWER_STATE_TRANS, (tcdm_base + PRCM_MBOX_HEADER_REQ_MB0));
+	writeb(state, (tcdm_base + PRCM_REQ_MB0_AP_POWER_STATE));
+	writeb((keep_ap_pll ? 1 : 0), (tcdm_base + PRCM_REQ_MB0_AP_PLL_STATE));
+	writeb((keep_ulp_clk ? 1 : 0),
+		(tcdm_base + PRCM_REQ_MB0_ULP_CLOCK_STATE));
+	writeb(0, (tcdm_base + PRCM_REQ_MB0_DO_NOT_WFI));
+	writel(MBOX_BIT(0), (_PRCMU_BASE + PRCM_MBOX_CPU_SET));
+
+	spin_unlock_irqrestore(&mb0_transfer.lock, flags);
+
+	return 0;
+}
+
+/* This function should only be called while mb0_transfer.lock is held. */
+static void config_wakeups(void)
+{
+	const u8 header[2] = {
+		MB0H_CONFIG_WAKEUPS_EXE,
+		MB0H_CONFIG_WAKEUPS_SLEEP
+	};
+	static u32 last_dbb_events;
+	static u32 last_abb_events;
+	u32 dbb_events;
+	u32 abb_events;
+	unsigned int i;
+
+	dbb_events = mb0_transfer.req.dbb_irqs | mb0_transfer.req.dbb_wakeups;
+	dbb_events |= (WAKEUP_BIT_AC_WAKE_ACK | WAKEUP_BIT_AC_SLEEP_ACK);
+
+	abb_events = mb0_transfer.req.abb_events;
+
+	if ((dbb_events == last_dbb_events) && (abb_events == last_abb_events))
+		return;
+
+	for (i = 0; i < 2; i++) {
+		while (readl(_PRCMU_BASE + PRCM_MBOX_CPU_VAL) & MBOX_BIT(0))
+			cpu_relax();
+		writel(dbb_events, (tcdm_base + PRCM_REQ_MB0_WAKEUP_8500));
+		writel(abb_events, (tcdm_base + PRCM_REQ_MB0_WAKEUP_4500));
+		writeb(header[i], (tcdm_base + PRCM_MBOX_HEADER_REQ_MB0));
+		writel(MBOX_BIT(0), (_PRCMU_BASE + PRCM_MBOX_CPU_SET));
+	}
+	last_dbb_events = dbb_events;
+	last_abb_events = abb_events;
+}
+
+void prcmu_enable_wakeups(u32 wakeups)
+{
+	unsigned long flags;
+	u32 bits;
+	int i;
+
+	BUG_ON(wakeups != (wakeups & VALID_WAKEUPS));
+
+	for (i = 0, bits = 0; i < NUM_PRCMU_WAKEUP_INDICES; i++) {
+		if (wakeups & BIT(i))
+			bits |= prcmu_wakeup_bit[i];
+	}
+
+	spin_lock_irqsave(&mb0_transfer.lock, flags);
+
+	mb0_transfer.req.dbb_wakeups = bits;
+	config_wakeups();
+
+	spin_unlock_irqrestore(&mb0_transfer.lock, flags);
+}
+
+void prcmu_config_abb_event_readout(u32 abb_events)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&mb0_transfer.lock, flags);
+
+	mb0_transfer.req.abb_events = abb_events;
+	config_wakeups();
+
+	spin_unlock_irqrestore(&mb0_transfer.lock, flags);
+}
+
+void prcmu_get_abb_event_buffer(void __iomem **buf)
+{
+	if (readb(tcdm_base + PRCM_ACK_MB0_READ_POINTER) & 1)
+		*buf = (tcdm_base + PRCM_ACK_MB0_WAKEUP_1_4500);
+	else
+		*buf = (tcdm_base + PRCM_ACK_MB0_WAKEUP_0_4500);
+}
+
+/**
+ * prcmu_set_arm_opp - set the appropriate ARM OPP
+ * @opp: The new ARM operating point to which transition is to be made
+ * Returns: 0 on success, non-zero on failure
+ *
+ * This function sets the the operating point of the ARM.
+ */
+int prcmu_set_arm_opp(u8 opp)
+{
+	int r;
+
+	if (opp < ARM_NO_CHANGE || opp > ARM_EXTCLK)
+		return -EINVAL;
+
+	r = 0;
+
+	mutex_lock(&mb1_transfer.lock);
+
+	while (readl(_PRCMU_BASE + PRCM_MBOX_CPU_VAL) & MBOX_BIT(1))
+		cpu_relax();
+
+	writeb(MB1H_ARM_APE_OPP, (tcdm_base + PRCM_MBOX_HEADER_REQ_MB1));
+	writeb(opp, (tcdm_base + PRCM_REQ_MB1_ARM_OPP));
+	writeb(APE_NO_CHANGE, (tcdm_base + PRCM_REQ_MB1_APE_OPP));
+
+	writel(MBOX_BIT(1), (_PRCMU_BASE + PRCM_MBOX_CPU_SET));
+	wait_for_completion(&mb1_transfer.work);
+
+	if ((mb1_transfer.ack.header != MB1H_ARM_APE_OPP) ||
+		(mb1_transfer.ack.arm_opp != opp))
+		r = -EIO;
+
+	mutex_unlock(&mb1_transfer.lock);
+
+	return r;
+}
+
+/**
+ * prcmu_get_arm_opp - get the current ARM OPP
+ *
+ * Returns: the current ARM OPP
+ */
+int prcmu_get_arm_opp(void)
+{
+	return readb(tcdm_base + PRCM_ACK_MB1_CURRENT_ARM_OPP);
+}
+
+/**
+ * prcmu_get_ddr_opp - get the current DDR OPP
+ *
+ * Returns: the current DDR OPP
+ */
+int prcmu_get_ddr_opp(void)
+{
+	return readb(_PRCMU_BASE + PRCM_DDR_SUBSYS_APE_MINBW);
+}
+
+/**
+ * set_ddr_opp - set the appropriate DDR OPP
+ * @opp: The new DDR operating point to which transition is to be made
+ * Returns: 0 on success, non-zero on failure
+ *
+ * This function sets the operating point of the DDR.
+ */
+int prcmu_set_ddr_opp(u8 opp)
+{
+	if (opp < DDR_100_OPP || opp > DDR_25_OPP)
+		return -EINVAL;
+	/* Changing the DDR OPP can hang the hardware pre-v21 */
+	if (cpu_is_u8500v20_or_later() && !cpu_is_u8500v20())
+		writeb(opp, (_PRCMU_BASE + PRCM_DDR_SUBSYS_APE_MINBW));
+
+	return 0;
+}
+/**
+ * set_ape_opp - set the appropriate APE OPP
+ * @opp: The new APE operating point to which transition is to be made
+ * Returns: 0 on success, non-zero on failure
+ *
+ * This function sets the operating point of the APE.
+ */
+int prcmu_set_ape_opp(u8 opp)
+{
+	int r = 0;
+
+	mutex_lock(&mb1_transfer.lock);
+
+	while (readl(_PRCMU_BASE + PRCM_MBOX_CPU_VAL) & MBOX_BIT(1))
+		cpu_relax();
+
+	writeb(MB1H_ARM_APE_OPP, (tcdm_base + PRCM_MBOX_HEADER_REQ_MB1));
+	writeb(ARM_NO_CHANGE, (tcdm_base + PRCM_REQ_MB1_ARM_OPP));
+	writeb(opp, (tcdm_base + PRCM_REQ_MB1_APE_OPP));
+
+	writel(MBOX_BIT(1), (_PRCMU_BASE + PRCM_MBOX_CPU_SET));
+	wait_for_completion(&mb1_transfer.work);
+
+	if ((mb1_transfer.ack.header != MB1H_ARM_APE_OPP) ||
+		(mb1_transfer.ack.ape_opp != opp))
+		r = -EIO;
+
+	mutex_unlock(&mb1_transfer.lock);
+
+	return r;
+}
+
+/**
+ * prcmu_get_ape_opp - get the current APE OPP
+ *
+ * Returns: the current APE OPP
+ */
+int prcmu_get_ape_opp(void)
+{
+	return readb(tcdm_base + PRCM_ACK_MB1_CURRENT_APE_OPP);
+}
+
+/**
+ * prcmu_request_ape_opp_100_voltage - Request APE OPP 100% voltage
+ * @enable: true to request the higher voltage, false to drop a request.
+ *
+ * Calls to this function to enable and disable requests must be balanced.
+ */
+int prcmu_request_ape_opp_100_voltage(bool enable)
+{
+	int r = 0;
+	u8 header;
+	static unsigned int requests;
+
+	mutex_lock(&mb1_transfer.lock);
+
+	if (enable) {
+		if (0 != requests++)
+			goto unlock_and_return;
+		header = MB1H_REQUEST_APE_OPP_100_VOLT;
+	} else {
+		if (requests == 0) {
+			r = -EIO;
+			goto unlock_and_return;
+		} else if (1 != requests--) {
+			goto unlock_and_return;
+		}
+		header = MB1H_RELEASE_APE_OPP_100_VOLT;
+	}
+
+	while (readl(_PRCMU_BASE + PRCM_MBOX_CPU_VAL) & MBOX_BIT(1))
+		cpu_relax();
+
+	writeb(header, (tcdm_base + PRCM_MBOX_HEADER_REQ_MB1));
+
+	writel(MBOX_BIT(1), (_PRCMU_BASE + PRCM_MBOX_CPU_SET));
+	wait_for_completion(&mb1_transfer.work);
+
+	if ((mb1_transfer.ack.header != header) ||
+		((mb1_transfer.ack.ape_voltage_status & BIT(0)) != 0))
+		r = -EIO;
+
+unlock_and_return:
+	mutex_unlock(&mb1_transfer.lock);
+
+	return r;
+}
+
+/**
+ * prcmu_release_usb_wakeup_state - release the state required by a USB wakeup
+ *
+ * This function releases the power state requirements of a USB wakeup.
+ */
+int prcmu_release_usb_wakeup_state(void)
+{
+	int r = 0;
+
+	mutex_lock(&mb1_transfer.lock);
+
+	while (readl(_PRCMU_BASE + PRCM_MBOX_CPU_VAL) & MBOX_BIT(1))
+		cpu_relax();
+
+	writeb(MB1H_RELEASE_USB_WAKEUP,
+		(tcdm_base + PRCM_MBOX_HEADER_REQ_MB1));
+
+	writel(MBOX_BIT(1), (_PRCMU_BASE + PRCM_MBOX_CPU_SET));
+	wait_for_completion(&mb1_transfer.work);
+
+	if ((mb1_transfer.ack.header != MB1H_RELEASE_USB_WAKEUP) ||
+		((mb1_transfer.ack.ape_voltage_status & BIT(0)) != 0))
+		r = -EIO;
+
+	mutex_unlock(&mb1_transfer.lock);
+
+	return r;
+}
+
+/**
+ * prcmu_set_epod - set the state of a EPOD (power domain)
+ * @epod_id: The EPOD to set
+ * @epod_state: The new EPOD state
+ *
+ * This function sets the state of a EPOD (power domain). It may not be called
+ * from interrupt context.
+ */
+int prcmu_set_epod(u16 epod_id, u8 epod_state)
+{
+	int r = 0;
+	bool ram_retention = false;
+	int i;
+
+	/* check argument */
+	BUG_ON(epod_id >= NUM_EPOD_ID);
+
+	/* set flag if retention is possible */
+	switch (epod_id) {
+	case EPOD_ID_SVAMMDSP:
+	case EPOD_ID_SIAMMDSP:
+	case EPOD_ID_ESRAM12:
+	case EPOD_ID_ESRAM34:
+		ram_retention = true;
+		break;
+	}
+
+	/* check argument */
+	BUG_ON(epod_state > EPOD_STATE_ON);
+	BUG_ON(epod_state == EPOD_STATE_RAMRET && !ram_retention);
+
+	/* get lock */
+	mutex_lock(&mb2_transfer.lock);
+
+	/* wait for mailbox */
+	while (readl(_PRCMU_BASE + PRCM_MBOX_CPU_VAL) & MBOX_BIT(2))
+		cpu_relax();
+
+	/* fill in mailbox */
+	for (i = 0; i < NUM_EPOD_ID; i++)
+		writeb(EPOD_STATE_NO_CHANGE, (tcdm_base + PRCM_REQ_MB2 + i));
+	writeb(epod_state, (tcdm_base + PRCM_REQ_MB2 + epod_id));
+
+	writeb(MB2H_DPS, (tcdm_base + PRCM_MBOX_HEADER_REQ_MB2));
+
+	writel(MBOX_BIT(2), (_PRCMU_BASE + PRCM_MBOX_CPU_SET));
+
+	/*
+	 * The current firmware version does not handle errors correctly,
+	 * and we cannot recover if there is an error.
+	 * This is expected to change when the firmware is updated.
+	 */
+	if (!wait_for_completion_timeout(&mb2_transfer.work,
+			msecs_to_jiffies(20000))) {
+		pr_err("prcmu: %s timed out (20 s) waiting for a reply.\n",
+			__func__);
+		r = -EIO;
+		goto unlock_and_return;
+	}
+
+	if (mb2_transfer.ack.status != HWACC_PWR_ST_OK)
+		r = -EIO;
+
+unlock_and_return:
+	mutex_unlock(&mb2_transfer.lock);
+	return r;
+}
+
+/**
+ * prcmu_configure_auto_pm - Configure autonomous power management.
+ * @sleep: Configuration for ApSleep.
+ * @idle:  Configuration for ApIdle.
+ */
+void prcmu_configure_auto_pm(struct prcmu_auto_pm_config *sleep,
+	struct prcmu_auto_pm_config *idle)
+{
+	u32 sleep_cfg;
+	u32 idle_cfg;
+	unsigned long flags;
+
+	BUG_ON((sleep == NULL) || (idle == NULL));
+
+	sleep_cfg = (sleep->sva_auto_pm_enable & 0xF);
+	sleep_cfg = ((sleep_cfg << 4) | (sleep->sia_auto_pm_enable & 0xF));
+	sleep_cfg = ((sleep_cfg << 8) | (sleep->sva_power_on & 0xFF));
+	sleep_cfg = ((sleep_cfg << 8) | (sleep->sia_power_on & 0xFF));
+	sleep_cfg = ((sleep_cfg << 4) | (sleep->sva_policy & 0xF));
+	sleep_cfg = ((sleep_cfg << 4) | (sleep->sia_policy & 0xF));
+
+	idle_cfg = (idle->sva_auto_pm_enable & 0xF);
+	idle_cfg = ((idle_cfg << 4) | (idle->sia_auto_pm_enable & 0xF));
+	idle_cfg = ((idle_cfg << 8) | (idle->sva_power_on & 0xFF));
+	idle_cfg = ((idle_cfg << 8) | (idle->sia_power_on & 0xFF));
+	idle_cfg = ((idle_cfg << 4) | (idle->sva_policy & 0xF));
+	idle_cfg = ((idle_cfg << 4) | (idle->sia_policy & 0xF));
+
+	spin_lock_irqsave(&mb2_transfer.auto_pm_lock, flags);
+
+	/*
+	 * The autonomous power management configuration is done through
+	 * fields in mailbox 2, but these fields are only used as shared
+	 * variables - i.e. there is no need to send a message.
+	 */
+	writel(sleep_cfg, (tcdm_base + PRCM_REQ_MB2_AUTO_PM_SLEEP));
+	writel(idle_cfg, (tcdm_base + PRCM_REQ_MB2_AUTO_PM_IDLE));
+
+	mb2_transfer.auto_pm_enabled =
+		((sleep->sva_auto_pm_enable == PRCMU_AUTO_PM_ON) ||
+		 (sleep->sia_auto_pm_enable == PRCMU_AUTO_PM_ON) ||
+		 (idle->sva_auto_pm_enable == PRCMU_AUTO_PM_ON) ||
+		 (idle->sia_auto_pm_enable == PRCMU_AUTO_PM_ON));
+
+	spin_unlock_irqrestore(&mb2_transfer.auto_pm_lock, flags);
+}
+EXPORT_SYMBOL(prcmu_configure_auto_pm);
+
+bool prcmu_is_auto_pm_enabled(void)
+{
+	return mb2_transfer.auto_pm_enabled;
+}
+
+static int request_sysclk(bool enable)
+{
+	int r;
+	unsigned long flags;
+
+	r = 0;
+
+	mutex_lock(&mb3_transfer.sysclk_lock);
+
+	spin_lock_irqsave(&mb3_transfer.lock, flags);
+
+	while (readl(_PRCMU_BASE + PRCM_MBOX_CPU_VAL) & MBOX_BIT(3))
+		cpu_relax();
+
+	writeb((enable ? ON : OFF), (tcdm_base + PRCM_REQ_MB3_SYSCLK_MGT));
+
+	writeb(MB3H_SYSCLK, (tcdm_base + PRCM_MBOX_HEADER_REQ_MB3));
+	writel(MBOX_BIT(3), (_PRCMU_BASE + PRCM_MBOX_CPU_SET));
+
+	spin_unlock_irqrestore(&mb3_transfer.lock, flags);
+
+	/*
+	 * The firmware only sends an ACK if we want to enable the
+	 * SysClk, and it succeeds.
+	 */
+	if (enable && !wait_for_completion_timeout(&mb3_transfer.sysclk_work,
+			msecs_to_jiffies(20000))) {
+		pr_err("prcmu: %s timed out (20 s) waiting for a reply.\n",
+			__func__);
+		r = -EIO;
+	}
+
+	mutex_unlock(&mb3_transfer.sysclk_lock);
+
+	return r;
+}
+
+static int request_timclk(bool enable)
+{
+	u32 val = (PRCM_TCR_DOZE_MODE | PRCM_TCR_TENSEL_MASK);
+
+	if (!enable)
+		val |= PRCM_TCR_STOP_TIMERS;
+	writel(val, (_PRCMU_BASE + PRCM_TCR));
+
+	return 0;
+}
+
+static int request_reg_clock(u8 clock, bool enable)
+{
+	u32 val;
+	unsigned long flags;
+
+	spin_lock_irqsave(&clk_mgt_lock, flags);
+
+	/* Grab the HW semaphore. */
+	while ((readl(_PRCMU_BASE + PRCM_SEM) & PRCM_SEM_PRCM_SEM) != 0)
+		cpu_relax();
+
+	val = readl(_PRCMU_BASE + clk_mgt[clock].offset);
+	if (enable) {
+		val |= (PRCM_CLK_MGT_CLKEN | clk_mgt[clock].pllsw);
+	} else {
+		clk_mgt[clock].pllsw = (val & PRCM_CLK_MGT_CLKPLLSW_MASK);
+		val &= ~(PRCM_CLK_MGT_CLKEN | PRCM_CLK_MGT_CLKPLLSW_MASK);
+	}
+	writel(val, (_PRCMU_BASE + clk_mgt[clock].offset));
+
+	/* Release the HW semaphore. */
+	writel(0, (_PRCMU_BASE + PRCM_SEM));
+
+	spin_unlock_irqrestore(&clk_mgt_lock, flags);
+
+	return 0;
+}
+
+/**
+ * prcmu_request_clock() - Request for a clock to be enabled or disabled.
+ * @clock:      The clock for which the request is made.
+ * @enable:     Whether the clock should be enabled (true) or disabled (false).
+ *
+ * This function should only be used by the clock implementation.
+ * Do not use it from any other place!
+ */
+int prcmu_request_clock(u8 clock, bool enable)
+{
+	if (clock < PRCMU_NUM_REG_CLOCKS)
+		return request_reg_clock(clock, enable);
+	else if (clock == PRCMU_TIMCLK)
+		return request_timclk(enable);
+	else if (clock == PRCMU_SYSCLK)
+		return request_sysclk(enable);
+	else
+		return -EINVAL;
+}
+
+int prcmu_config_esram0_deep_sleep(u8 state)
+{
+	if ((state > ESRAM0_DEEP_SLEEP_STATE_RET) ||
+	    (state < ESRAM0_DEEP_SLEEP_STATE_OFF))
+		return -EINVAL;
+
+	mutex_lock(&mb4_transfer.lock);
+
+	while (readl(_PRCMU_BASE + PRCM_MBOX_CPU_VAL) & MBOX_BIT(4))
+		cpu_relax();
+
+	writeb(MB4H_MEM_ST, (tcdm_base + PRCM_MBOX_HEADER_REQ_MB4));
+	writeb(((DDR_PWR_STATE_OFFHIGHLAT << 4) | DDR_PWR_STATE_ON),
+	       (tcdm_base + PRCM_REQ_MB4_DDR_ST_AP_SLEEP_IDLE));
+	writeb(DDR_PWR_STATE_ON,
+	       (tcdm_base + PRCM_REQ_MB4_DDR_ST_AP_DEEP_IDLE));
+	writeb(state, (tcdm_base + PRCM_REQ_MB4_ESRAM0_ST));
+
+	writel(MBOX_BIT(4), (_PRCMU_BASE + PRCM_MBOX_CPU_SET));
+	wait_for_completion(&mb4_transfer.work);
+
+	mutex_unlock(&mb4_transfer.lock);
+
+	return 0;
+}
+
+int prcmu_config_hotdog(u8 threshold)
+{
+	mutex_lock(&mb4_transfer.lock);
+
+	while (readl(_PRCMU_BASE + PRCM_MBOX_CPU_VAL) & MBOX_BIT(4))
+		cpu_relax();
+
+	writeb(threshold, (tcdm_base + PRCM_REQ_MB4_HOTDOG_THRESHOLD));
+	writeb(MB4H_HOTDOG, (tcdm_base + PRCM_MBOX_HEADER_REQ_MB4));
+
+	writel(MBOX_BIT(4), (_PRCMU_BASE + PRCM_MBOX_CPU_SET));
+	wait_for_completion(&mb4_transfer.work);
+
+	mutex_unlock(&mb4_transfer.lock);
+
+	return 0;
+}
+
+int prcmu_config_hotmon(u8 low, u8 high)
+{
+	mutex_lock(&mb4_transfer.lock);
+
+	while (readl(_PRCMU_BASE + PRCM_MBOX_CPU_VAL) & MBOX_BIT(4))
+		cpu_relax();
+
+	writeb(low, (tcdm_base + PRCM_REQ_MB4_HOTMON_LOW));
+	writeb(high, (tcdm_base + PRCM_REQ_MB4_HOTMON_HIGH));
+	writeb((HOTMON_CONFIG_LOW | HOTMON_CONFIG_HIGH),
+		(tcdm_base + PRCM_REQ_MB4_HOTMON_CONFIG));
+	writeb(MB4H_HOTMON, (tcdm_base + PRCM_MBOX_HEADER_REQ_MB4));
+
+	writel(MBOX_BIT(4), (_PRCMU_BASE + PRCM_MBOX_CPU_SET));
+	wait_for_completion(&mb4_transfer.work);
+
+	mutex_unlock(&mb4_transfer.lock);
+
+	return 0;
+}
+
+static int config_hot_period(u16 val)
+{
+	mutex_lock(&mb4_transfer.lock);
+
+	while (readl(_PRCMU_BASE + PRCM_MBOX_CPU_VAL) & MBOX_BIT(4))
+		cpu_relax();
+
+	writew(val, (tcdm_base + PRCM_REQ_MB4_HOT_PERIOD));
+	writeb(MB4H_HOT_PERIOD, (tcdm_base + PRCM_MBOX_HEADER_REQ_MB4));
+
+	writel(MBOX_BIT(4), (_PRCMU_BASE + PRCM_MBOX_CPU_SET));
+	wait_for_completion(&mb4_transfer.work);
+
+	mutex_unlock(&mb4_transfer.lock);
+
+	return 0;
+}
+
+int prcmu_start_temp_sense(u16 cycles32k)
+{
+	if (cycles32k == 0xFFFF)
+		return -EINVAL;
+
+	return config_hot_period(cycles32k);
+}
+
+int prcmu_stop_temp_sense(void)
+{
+	return config_hot_period(0xFFFF);
+}
+
+/**
+ * prcmu_set_clock_divider() - Configure the clock divider.
+ * @clock:	The clock for which the request is made.
+ * @divider:	The clock divider. (< 32)
+ *
+ * This function should only be used by the clock implementation.
+ * Do not use it from any other place!
+ */
+int prcmu_set_clock_divider(u8 clock, u8 divider)
+{
+	u32 val;
+	unsigned long flags;
+
+	if ((clock >= PRCMU_NUM_REG_CLOCKS) || (divider < 1) || (31 < divider))
+		return -EINVAL;
+
+	spin_lock_irqsave(&clk_mgt_lock, flags);
+
+	/* Grab the HW semaphore. */
+	while ((readl(_PRCMU_BASE + PRCM_SEM) & PRCM_SEM_PRCM_SEM) != 0)
+		cpu_relax();
+
+	val = readl(_PRCMU_BASE + clk_mgt[clock].offset);
+	val &= ~(PRCM_CLK_MGT_CLKPLLDIV_MASK);
+	val |= (u32)divider;
+	writel(val, (_PRCMU_BASE + clk_mgt[clock].offset));
+
+	/* Release the HW semaphore. */
+	writel(0, (_PRCMU_BASE + PRCM_SEM));
+
+	spin_unlock_irqrestore(&clk_mgt_lock, flags);
+
+	return 0;
+}
+
+/**
+ * prcmu_abb_read() - Read register value(s) from the ABB.
+ * @slave:	The I2C slave address.
+ * @reg:	The (start) register address.
+ * @value:	The read out value(s).
+ * @size:	The number of registers to read.
+ *
+ * Reads register value(s) from the ABB.
+ * @size has to be 1 for the current firmware version.
+ */
+int prcmu_abb_read(u8 slave, u8 reg, u8 *value, u8 size)
+{
+	int r;
+
+	if (size != 1)
+		return -EINVAL;
+
+	mutex_lock(&mb5_transfer.lock);
+
+	while (readl(_PRCMU_BASE + PRCM_MBOX_CPU_VAL) & MBOX_BIT(5))
+		cpu_relax();
+
+	writeb(PRCMU_I2C_READ(slave), (tcdm_base + PRCM_REQ_MB5_I2C_SLAVE_OP));
+	writeb(PRCMU_I2C_STOP_EN, (tcdm_base + PRCM_REQ_MB5_I2C_HW_BITS));
+	writeb(reg, (tcdm_base + PRCM_REQ_MB5_I2C_REG));
+	writeb(0, (tcdm_base + PRCM_REQ_MB5_I2C_VAL));
+
+	writel(MBOX_BIT(5), (_PRCMU_BASE + PRCM_MBOX_CPU_SET));
+
+	if (!wait_for_completion_timeout(&mb5_transfer.work,
+				msecs_to_jiffies(20000))) {
+		pr_err("prcmu: %s timed out (20 s) waiting for a reply.\n",
+			__func__);
+		r = -EIO;
+	} else {
+		r = ((mb5_transfer.ack.status == I2C_RD_OK) ? 0 : -EIO);
+	}
+
+	if (!r)
+		*value = mb5_transfer.ack.value;
+
+	mutex_unlock(&mb5_transfer.lock);
+
+	return r;
+}
+
+/**
+ * prcmu_abb_write() - Write register value(s) to the ABB.
+ * @slave:	The I2C slave address.
+ * @reg:	The (start) register address.
+ * @value:	The value(s) to write.
+ * @size:	The number of registers to write.
+ *
+ * Reads register value(s) from the ABB.
+ * @size has to be 1 for the current firmware version.
+ */
+int prcmu_abb_write(u8 slave, u8 reg, u8 *value, u8 size)
+{
+	int r;
+
+	if (size != 1)
+		return -EINVAL;
+
+	mutex_lock(&mb5_transfer.lock);
+
+	while (readl(_PRCMU_BASE + PRCM_MBOX_CPU_VAL) & MBOX_BIT(5))
+		cpu_relax();
+
+	writeb(PRCMU_I2C_WRITE(slave), (tcdm_base + PRCM_REQ_MB5_I2C_SLAVE_OP));
+	writeb(PRCMU_I2C_STOP_EN, (tcdm_base + PRCM_REQ_MB5_I2C_HW_BITS));
+	writeb(reg, (tcdm_base + PRCM_REQ_MB5_I2C_REG));
+	writeb(*value, (tcdm_base + PRCM_REQ_MB5_I2C_VAL));
+
+	writel(MBOX_BIT(5), (_PRCMU_BASE + PRCM_MBOX_CPU_SET));
+
+	if (!wait_for_completion_timeout(&mb5_transfer.work,
+				msecs_to_jiffies(20000))) {
+		pr_err("prcmu: %s timed out (20 s) waiting for a reply.\n",
+			__func__);
+		r = -EIO;
+	} else {
+		r = ((mb5_transfer.ack.status == I2C_WR_OK) ? 0 : -EIO);
+	}
+
+	mutex_unlock(&mb5_transfer.lock);
+
+	return r;
+}
+
+/**
+ * prcmu_ac_wake_req - should be called whenever ARM wants to wakeup Modem
+ */
+void prcmu_ac_wake_req(void)
+{
+	u32 val;
+
+	mutex_lock(&mb0_transfer.ac_wake_lock);
+
+	val = readl(_PRCMU_BASE + PRCM_HOSTACCESS_REQ);
+	if (val & PRCM_HOSTACCESS_REQ_HOSTACCESS_REQ)
+		goto unlock_and_return;
+
+	atomic_set(&ac_wake_req_state, 1);
+
+	writel((val | PRCM_HOSTACCESS_REQ_HOSTACCESS_REQ),
+		(_PRCMU_BASE + PRCM_HOSTACCESS_REQ));
+
+	if (!wait_for_completion_timeout(&mb0_transfer.ac_wake_work,
+			msecs_to_jiffies(20000))) {
+		pr_err("prcmu: %s timed out (20 s) waiting for a reply.\n",
+			__func__);
+	}
+
+unlock_and_return:
+	mutex_unlock(&mb0_transfer.ac_wake_lock);
+}
+
+/**
+ * prcmu_ac_sleep_req - called when ARM no longer needs to talk to modem
+ */
+void prcmu_ac_sleep_req()
+{
+	u32 val;
+
+	mutex_lock(&mb0_transfer.ac_wake_lock);
+
+	val = readl(_PRCMU_BASE + PRCM_HOSTACCESS_REQ);
+	if (!(val & PRCM_HOSTACCESS_REQ_HOSTACCESS_REQ))
+		goto unlock_and_return;
+
+	writel((val & ~PRCM_HOSTACCESS_REQ_HOSTACCESS_REQ),
+		(_PRCMU_BASE + PRCM_HOSTACCESS_REQ));
+
+	if (!wait_for_completion_timeout(&mb0_transfer.ac_wake_work,
+			msecs_to_jiffies(20000))) {
+		pr_err("prcmu: %s timed out (20 s) waiting for a reply.\n",
+			__func__);
+	}
+
+	atomic_set(&ac_wake_req_state, 0);
+
+unlock_and_return:
+	mutex_unlock(&mb0_transfer.ac_wake_lock);
+}
+
+bool prcmu_is_ac_wake_requested(void)
+{
+	return (atomic_read(&ac_wake_req_state) != 0);
+}
+
+/**
+ * prcmu_system_reset - System reset
+ *
+ * Saves the reset reason code and then sets the APE_SOFRST register which
+ * fires interrupt to fw
+ */
+void prcmu_system_reset(u16 reset_code)
+{
+	writew(reset_code, (tcdm_base + PRCM_SW_RST_REASON));
+	writel(1, (_PRCMU_BASE + PRCM_APE_SOFTRST));
+}
+
+/**
+ * prcmu_reset_modem - ask the PRCMU to reset modem
+ */
+void prcmu_modem_reset(void)
+{
+	mutex_lock(&mb1_transfer.lock);
+
+	while (readl(_PRCMU_BASE + PRCM_MBOX_CPU_VAL) & MBOX_BIT(1))
+		cpu_relax();
+
+	writeb(MB1H_RESET_MODEM, (tcdm_base + PRCM_MBOX_HEADER_REQ_MB1));
+	writel(MBOX_BIT(1), (_PRCMU_BASE + PRCM_MBOX_CPU_SET));
+	wait_for_completion(&mb1_transfer.work);
+
+	/*
+	 * No need to check return from PRCMU as modem should go in reset state
+	 * This state is already managed by upper layer
+	 */
+
+	mutex_unlock(&mb1_transfer.lock);
+}
+
+static void ack_dbb_wakeup(void)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&mb0_transfer.lock, flags);
+
+	while (readl(_PRCMU_BASE + PRCM_MBOX_CPU_VAL) & MBOX_BIT(0))
+		cpu_relax();
+
+	writeb(MB0H_READ_WAKEUP_ACK, (tcdm_base + PRCM_MBOX_HEADER_REQ_MB0));
+	writel(MBOX_BIT(0), (_PRCMU_BASE + PRCM_MBOX_CPU_SET));
+
+	spin_unlock_irqrestore(&mb0_transfer.lock, flags);
+}
+
+static inline void print_unknown_header_warning(u8 n, u8 header)
+{
+	pr_warning("prcmu: Unknown message header (%d) in mailbox %d.\n",
+		header, n);
+}
+
+static bool read_mailbox_0(void)
+{
+	bool r;
+	u32 ev;
+	unsigned int n;
+	u8 header;
+
+	header = readb(tcdm_base + PRCM_MBOX_HEADER_ACK_MB0);
+	switch (header) {
+	case MB0H_WAKEUP_EXE:
+	case MB0H_WAKEUP_SLEEP:
+		if (readb(tcdm_base + PRCM_ACK_MB0_READ_POINTER) & 1)
+			ev = readl(tcdm_base + PRCM_ACK_MB0_WAKEUP_1_8500);
+		else
+			ev = readl(tcdm_base + PRCM_ACK_MB0_WAKEUP_0_8500);
+
+		if (ev & (WAKEUP_BIT_AC_WAKE_ACK | WAKEUP_BIT_AC_SLEEP_ACK))
+			complete(&mb0_transfer.ac_wake_work);
+		if (ev & WAKEUP_BIT_SYSCLK_OK)
+			complete(&mb3_transfer.sysclk_work);
+
+		ev &= mb0_transfer.req.dbb_irqs;
+
+		for (n = 0; n < NUM_PRCMU_WAKEUPS; n++) {
+			if (ev & prcmu_irq_bit[n])
+				generic_handle_irq(IRQ_PRCMU_BASE + n);
+		}
+		r = true;
+		break;
+	default:
+		print_unknown_header_warning(0, header);
+		r = false;
+		break;
+	}
+	writel(MBOX_BIT(0), (_PRCMU_BASE + PRCM_ARM_IT1_CLR));
+	return r;
+}
+
+static bool read_mailbox_1(void)
+{
+	mb1_transfer.ack.header = readb(tcdm_base + PRCM_MBOX_HEADER_REQ_MB1);
+	mb1_transfer.ack.arm_opp = readb(tcdm_base +
+		PRCM_ACK_MB1_CURRENT_ARM_OPP);
+	mb1_transfer.ack.ape_opp = readb(tcdm_base +
+		PRCM_ACK_MB1_CURRENT_APE_OPP);
+	mb1_transfer.ack.ape_voltage_status = readb(tcdm_base +
+		PRCM_ACK_MB1_APE_VOLTAGE_STATUS);
+	writel(MBOX_BIT(1), (_PRCMU_BASE + PRCM_ARM_IT1_CLR));
+	complete(&mb1_transfer.work);
+	return false;
+}
+
+static bool read_mailbox_2(void)
+{
+	mb2_transfer.ack.status = readb(tcdm_base + PRCM_ACK_MB2_DPS_STATUS);
+	writel(MBOX_BIT(2), (_PRCMU_BASE + PRCM_ARM_IT1_CLR));
+	complete(&mb2_transfer.work);
+	return false;
+}
+
+static bool read_mailbox_3(void)
+{
+	writel(MBOX_BIT(3), (_PRCMU_BASE + PRCM_ARM_IT1_CLR));
+	return false;
+}
+
+static bool read_mailbox_4(void)
+{
+	u8 header;
+	bool do_complete = true;
+
+	header = readb(tcdm_base + PRCM_MBOX_HEADER_REQ_MB4);
+	switch (header) {
+	case MB4H_MEM_ST:
+	case MB4H_HOTDOG:
+	case MB4H_HOTMON:
+	case MB4H_HOT_PERIOD:
+		break;
+	default:
+		print_unknown_header_warning(4, header);
+		do_complete = false;
+		break;
+	}
+
+	writel(MBOX_BIT(4), (_PRCMU_BASE + PRCM_ARM_IT1_CLR));
+
+	if (do_complete)
+		complete(&mb4_transfer.work);
+
+	return false;
+}
+
+static bool read_mailbox_5(void)
+{
+	mb5_transfer.ack.status = readb(tcdm_base + PRCM_ACK_MB5_I2C_STATUS);
+	mb5_transfer.ack.value = readb(tcdm_base + PRCM_ACK_MB5_I2C_VAL);
+	writel(MBOX_BIT(5), (_PRCMU_BASE + PRCM_ARM_IT1_CLR));
+	complete(&mb5_transfer.work);
+	return false;
+}
+
+static bool read_mailbox_6(void)
+{
+	writel(MBOX_BIT(6), (_PRCMU_BASE + PRCM_ARM_IT1_CLR));
+	return false;
+}
+
+static bool read_mailbox_7(void)
+{
+	writel(MBOX_BIT(7), (_PRCMU_BASE + PRCM_ARM_IT1_CLR));
+	return false;
+}
+
+static bool (* const read_mailbox[NUM_MB])(void) = {
+	read_mailbox_0,
+	read_mailbox_1,
+	read_mailbox_2,
+	read_mailbox_3,
+	read_mailbox_4,
+	read_mailbox_5,
+	read_mailbox_6,
+	read_mailbox_7
+};
+
+static irqreturn_t prcmu_irq_handler(int irq, void *data)
+{
+	u32 bits;
+	u8 n;
+	irqreturn_t r;
+
+	bits = (readl(_PRCMU_BASE + PRCM_ARM_IT1_VAL) & ALL_MBOX_BITS);
+	if (unlikely(!bits))
+		return IRQ_NONE;
+
+	r = IRQ_HANDLED;
+	for (n = 0; bits; n++) {
+		if (bits & MBOX_BIT(n)) {
+			bits -= MBOX_BIT(n);
+			if (read_mailbox[n]())
+				r = IRQ_WAKE_THREAD;
+		}
+	}
+	return r;
+}
+
+static irqreturn_t prcmu_irq_thread_fn(int irq, void *data)
+{
+	ack_dbb_wakeup();
+	return IRQ_HANDLED;
+}
+
+static void prcmu_mask_work(struct work_struct *work)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&mb0_transfer.lock, flags);
+
+	config_wakeups();
+
+	spin_unlock_irqrestore(&mb0_transfer.lock, flags);
+}
+
+static void prcmu_irq_mask(struct irq_data *d)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&mb0_transfer.dbb_irqs_lock, flags);
+
+	mb0_transfer.req.dbb_irqs &= ~prcmu_irq_bit[d->irq - IRQ_PRCMU_BASE];
+
+	spin_unlock_irqrestore(&mb0_transfer.dbb_irqs_lock, flags);
+
+	if (d->irq != IRQ_PRCMU_CA_SLEEP)
+		schedule_work(&mb0_transfer.mask_work);
+}
+
+static void prcmu_irq_unmask(struct irq_data *d)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&mb0_transfer.dbb_irqs_lock, flags);
+
+	mb0_transfer.req.dbb_irqs |= prcmu_irq_bit[d->irq - IRQ_PRCMU_BASE];
+
+	spin_unlock_irqrestore(&mb0_transfer.dbb_irqs_lock, flags);
+
+	if (d->irq != IRQ_PRCMU_CA_SLEEP)
+		schedule_work(&mb0_transfer.mask_work);
+}
+
+static void noop(struct irq_data *d)
+{
+}
+
+static struct irq_chip prcmu_irq_chip = {
+	.name		= "prcmu",
+	.irq_disable	= prcmu_irq_mask,
+	.irq_ack	= noop,
+	.irq_mask	= prcmu_irq_mask,
+	.irq_unmask	= prcmu_irq_unmask,
+};
+
+void __init prcmu_early_init(void)
+{
+	unsigned int i;
+
+	if (cpu_is_u8500v1()) {
+		tcdm_base = __io_address(U8500_PRCMU_TCDM_BASE_V1);
+	} else if (cpu_is_u8500v2()) {
+		void *tcpm_base = ioremap_nocache(U8500_PRCMU_TCPM_BASE, SZ_4K);
+
+		if (tcpm_base != NULL) {
+			int version;
+			version = readl(tcpm_base + PRCMU_FW_VERSION_OFFSET);
+			prcmu_version.project_number = version & 0xFF;
+			prcmu_version.api_version = (version >> 8) & 0xFF;
+			prcmu_version.func_version = (version >> 16) & 0xFF;
+			prcmu_version.errata = (version >> 24) & 0xFF;
+			pr_info("PRCMU firmware version %d.%d.%d\n",
+				(version >> 8) & 0xFF, (version >> 16) & 0xFF,
+				(version >> 24) & 0xFF);
+			iounmap(tcpm_base);
+		}
+
+		tcdm_base = __io_address(U8500_PRCMU_TCDM_BASE);
+	} else {
+		pr_err("prcmu: Unsupported chip version\n");
+		BUG();
+	}
+
+	spin_lock_init(&mb0_transfer.lock);
+	spin_lock_init(&mb0_transfer.dbb_irqs_lock);
+	mutex_init(&mb0_transfer.ac_wake_lock);
+	init_completion(&mb0_transfer.ac_wake_work);
+	mutex_init(&mb1_transfer.lock);
+	init_completion(&mb1_transfer.work);
+	mutex_init(&mb2_transfer.lock);
+	init_completion(&mb2_transfer.work);
+	spin_lock_init(&mb2_transfer.auto_pm_lock);
+	spin_lock_init(&mb3_transfer.lock);
+	mutex_init(&mb3_transfer.sysclk_lock);
+	init_completion(&mb3_transfer.sysclk_work);
+	mutex_init(&mb4_transfer.lock);
+	init_completion(&mb4_transfer.work);
+	mutex_init(&mb5_transfer.lock);
+	init_completion(&mb5_transfer.work);
+
+	INIT_WORK(&mb0_transfer.mask_work, prcmu_mask_work);
+
+	/* Initalize irqs. */
+	for (i = 0; i < NUM_PRCMU_WAKEUPS; i++) {
+		unsigned int irq;
+
+		irq = IRQ_PRCMU_BASE + i;
+		irq_set_chip_and_handler(irq, &prcmu_irq_chip,
+					 handle_simple_irq);
+		set_irq_flags(irq, IRQF_VALID);
+	}
+}
+
+/*
+ * Power domain switches (ePODs) modeled as regulators for the DB8500 SoC
+ */
+static struct regulator_consumer_supply db8500_vape_consumers[] = {
+	REGULATOR_SUPPLY("v-ape", NULL),
+	REGULATOR_SUPPLY("v-i2c", "nmk-i2c.0"),
+	REGULATOR_SUPPLY("v-i2c", "nmk-i2c.1"),
+	REGULATOR_SUPPLY("v-i2c", "nmk-i2c.2"),
+	REGULATOR_SUPPLY("v-i2c", "nmk-i2c.3"),
+	/* "v-mmc" changed to "vcore" in the mainline kernel */
+	REGULATOR_SUPPLY("vcore", "sdi0"),
+	REGULATOR_SUPPLY("vcore", "sdi1"),
+	REGULATOR_SUPPLY("vcore", "sdi2"),
+	REGULATOR_SUPPLY("vcore", "sdi3"),
+	REGULATOR_SUPPLY("vcore", "sdi4"),
+	REGULATOR_SUPPLY("v-dma", "dma40.0"),
+	REGULATOR_SUPPLY("v-ape", "ab8500-usb.0"),
+	/* "v-uart" changed to "vcore" in the mainline kernel */
+	REGULATOR_SUPPLY("vcore", "uart0"),
+	REGULATOR_SUPPLY("vcore", "uart1"),
+	REGULATOR_SUPPLY("vcore", "uart2"),
+	REGULATOR_SUPPLY("v-ape", "nmk-ske-keypad.0"),
+};
+
+static struct regulator_consumer_supply db8500_vsmps2_consumers[] = {
+	/* CG2900 and CW1200 power to off-chip peripherals */
+	REGULATOR_SUPPLY("gbf_1v8", "cg2900-uart.0"),
+	REGULATOR_SUPPLY("wlan_1v8", "cw1200.0"),
+	REGULATOR_SUPPLY("musb_1v8", "ab8500-usb.0"),
+	/* AV8100 regulator */
+	REGULATOR_SUPPLY("hdmi_1v8", "0-0070"),
+};
+
+static struct regulator_consumer_supply db8500_b2r2_mcde_consumers[] = {
+	REGULATOR_SUPPLY("vsupply", "b2r2.0"),
+	REGULATOR_SUPPLY("vsupply", "mcde.0"),
+};
+
+static struct regulator_init_data db8500_regulators[DB8500_NUM_REGULATORS] = {
+	[DB8500_REGULATOR_VAPE] = {
+		.constraints = {
+			.name = "db8500-vape",
+			.valid_ops_mask = REGULATOR_CHANGE_STATUS,
+		},
+		.consumer_supplies = db8500_vape_consumers,
+		.num_consumer_supplies = ARRAY_SIZE(db8500_vape_consumers),
+	},
+	[DB8500_REGULATOR_VARM] = {
+		.constraints = {
+			.name = "db8500-varm",
+			.valid_ops_mask = REGULATOR_CHANGE_STATUS,
+		},
+	},
+	[DB8500_REGULATOR_VMODEM] = {
+		.constraints = {
+			.name = "db8500-vmodem",
+			.valid_ops_mask = REGULATOR_CHANGE_STATUS,
+		},
+	},
+	[DB8500_REGULATOR_VPLL] = {
+		.constraints = {
+			.name = "db8500-vpll",
+			.valid_ops_mask = REGULATOR_CHANGE_STATUS,
+		},
+	},
+	[DB8500_REGULATOR_VSMPS1] = {
+		.constraints = {
+			.name = "db8500-vsmps1",
+			.valid_ops_mask = REGULATOR_CHANGE_STATUS,
+		},
+	},
+	[DB8500_REGULATOR_VSMPS2] = {
+		.constraints = {
+			.name = "db8500-vsmps2",
+			.valid_ops_mask = REGULATOR_CHANGE_STATUS,
+		},
+		.consumer_supplies = db8500_vsmps2_consumers,
+		.num_consumer_supplies = ARRAY_SIZE(db8500_vsmps2_consumers),
+	},
+	[DB8500_REGULATOR_VSMPS3] = {
+		.constraints = {
+			.name = "db8500-vsmps3",
+			.valid_ops_mask = REGULATOR_CHANGE_STATUS,
+		},
+	},
+	[DB8500_REGULATOR_VRF1] = {
+		.constraints = {
+			.name = "db8500-vrf1",
+			.valid_ops_mask = REGULATOR_CHANGE_STATUS,
+		},
+	},
+	[DB8500_REGULATOR_SWITCH_SVAMMDSP] = {
+		.supply_regulator = "db8500-vape",
+		.constraints = {
+			.name = "db8500-sva-mmdsp",
+			.valid_ops_mask = REGULATOR_CHANGE_STATUS,
+		},
+	},
+	[DB8500_REGULATOR_SWITCH_SVAMMDSPRET] = {
+		.constraints = {
+			/* "ret" means "retention" */
+			.name = "db8500-sva-mmdsp-ret",
+			.valid_ops_mask = REGULATOR_CHANGE_STATUS,
+		},
+	},
+	[DB8500_REGULATOR_SWITCH_SVAPIPE] = {
+		.supply_regulator = "db8500-vape",
+		.constraints = {
+			.name = "db8500-sva-pipe",
+			.valid_ops_mask = REGULATOR_CHANGE_STATUS,
+		},
+	},
+	[DB8500_REGULATOR_SWITCH_SIAMMDSP] = {
+		.supply_regulator = "db8500-vape",
+		.constraints = {
+			.name = "db8500-sia-mmdsp",
+			.valid_ops_mask = REGULATOR_CHANGE_STATUS,
+		},
+	},
+	[DB8500_REGULATOR_SWITCH_SIAMMDSPRET] = {
+		.constraints = {
+			.name = "db8500-sia-mmdsp-ret",
+			.valid_ops_mask = REGULATOR_CHANGE_STATUS,
+		},
+	},
+	[DB8500_REGULATOR_SWITCH_SIAPIPE] = {
+		.supply_regulator = "db8500-vape",
+		.constraints = {
+			.name = "db8500-sia-pipe",
+			.valid_ops_mask = REGULATOR_CHANGE_STATUS,
+		},
+	},
+	[DB8500_REGULATOR_SWITCH_SGA] = {
+		.supply_regulator = "db8500-vape",
+		.constraints = {
+			.name = "db8500-sga",
+			.valid_ops_mask = REGULATOR_CHANGE_STATUS,
+		},
+	},
+	[DB8500_REGULATOR_SWITCH_B2R2_MCDE] = {
+		.supply_regulator = "db8500-vape",
+		.constraints = {
+			.name = "db8500-b2r2-mcde",
+			.valid_ops_mask = REGULATOR_CHANGE_STATUS,
+		},
+		.consumer_supplies = db8500_b2r2_mcde_consumers,
+		.num_consumer_supplies = ARRAY_SIZE(db8500_b2r2_mcde_consumers),
+	},
+	[DB8500_REGULATOR_SWITCH_ESRAM12] = {
+		.supply_regulator = "db8500-vape",
+		.constraints = {
+			.name = "db8500-esram12",
+			.valid_ops_mask = REGULATOR_CHANGE_STATUS,
+		},
+	},
+	[DB8500_REGULATOR_SWITCH_ESRAM12RET] = {
+		.constraints = {
+			.name = "db8500-esram12-ret",
+			.valid_ops_mask = REGULATOR_CHANGE_STATUS,
+		},
+	},
+	[DB8500_REGULATOR_SWITCH_ESRAM34] = {
+		.supply_regulator = "db8500-vape",
+		.constraints = {
+			.name = "db8500-esram34",
+			.valid_ops_mask = REGULATOR_CHANGE_STATUS,
+		},
+	},
+	[DB8500_REGULATOR_SWITCH_ESRAM34RET] = {
+		.constraints = {
+			.name = "db8500-esram34-ret",
+			.valid_ops_mask = REGULATOR_CHANGE_STATUS,
+		},
+	},
+};
+
+static struct mfd_cell db8500_prcmu_devs[] = {
+	{
+		.name = "db8500-prcmu-regulators",
+		.platform_data = &db8500_regulators,
+		.pdata_size = sizeof(db8500_regulators),
+	},
+	{
+		.name = "cpufreq-u8500",
+	},
+};
+
+/**
+ * prcmu_fw_init - arch init call for the Linux PRCMU fw init logic
+ *
+ */
+static int __init db8500_prcmu_probe(struct platform_device *pdev)
+{
+	int err = 0;
+
+	if (ux500_is_svp())
+		return -ENODEV;
+
+	/* Clean up the mailbox interrupts after pre-kernel code. */
+	writel(ALL_MBOX_BITS, (_PRCMU_BASE + PRCM_ARM_IT1_CLR));
+
+	err = request_threaded_irq(IRQ_DB8500_PRCMU1, prcmu_irq_handler,
+		prcmu_irq_thread_fn, IRQF_NO_SUSPEND, "prcmu", NULL);
+	if (err < 0) {
+		pr_err("prcmu: Failed to allocate IRQ_DB8500_PRCMU1.\n");
+		err = -EBUSY;
+		goto no_irq_return;
+	}
+
+	if (cpu_is_u8500v20_or_later())
+		prcmu_config_esram0_deep_sleep(ESRAM0_DEEP_SLEEP_STATE_RET);
+
+	err = mfd_add_devices(&pdev->dev, 0, db8500_prcmu_devs,
+			      ARRAY_SIZE(db8500_prcmu_devs), NULL,
+			      0);
+
+	if (err)
+		pr_err("prcmu: Failed to add subdevices\n");
+	else
+		pr_info("DB8500 PRCMU initialized\n");
+
+no_irq_return:
+	return err;
+}
+
+static struct platform_driver db8500_prcmu_driver = {
+	.driver = {
+		.name = "db8500-prcmu",
+		.owner = THIS_MODULE,
+	},
+};
+
+static int __init db8500_prcmu_init(void)
+{
+	return platform_driver_probe(&db8500_prcmu_driver, db8500_prcmu_probe);
+}
+
+arch_initcall(db8500_prcmu_init);
+
+MODULE_AUTHOR("Mattias Nilsson <mattias.i.nilsson@stericsson.com>");
+MODULE_DESCRIPTION("DB8500 PRCM Unit driver");
+MODULE_LICENSE("GPL v2");
diff -druN linux-2.6.39-libre/drivers/mfd/db8500-prcmu-regs.h linux-3.0-rc7-libre/drivers/mfd/db8500-prcmu-regs.h
--- linux-2.6.39-libre/drivers/mfd/db8500-prcmu-regs.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/mfd/db8500-prcmu-regs.h	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,166 @@
+/*
+ * Copyright (C) STMicroelectronics 2009
+ * Copyright (C) ST-Ericsson SA 2010
+ *
+ * Author: Kumar Sanghvi <kumar.sanghvi@stericsson.com>
+ * Author: Sundar Iyer <sundar.iyer@stericsson.com>
+ *
+ * License Terms: GNU General Public License v2
+ *
+ * PRCM Unit registers
+ */
+#ifndef __DB8500_PRCMU_REGS_H
+#define __DB8500_PRCMU_REGS_H
+
+#include <linux/bitops.h>
+#include <mach/hardware.h>
+
+#define BITS(_start, _end) ((BIT(_end) - BIT(_start)) + BIT(_end))
+
+#define PRCM_ARM_PLLDIVPS 0x118
+#define PRCM_ARM_PLLDIVPS_ARM_BRM_RATE	BITS(0, 5)
+#define PRCM_ARM_PLLDIVPS_MAX_MASK	0xF
+
+#define PRCM_PLLARM_LOCKP 0x0A8
+#define PRCM_PLLARM_LOCKP_PRCM_PLLARM_LOCKP3 BIT(1)
+
+#define PRCM_ARM_CHGCLKREQ 0x114
+#define PRCM_ARM_CHGCLKREQ_PRCM_ARM_CHGCLKREQ BIT(0)
+
+#define PRCM_PLLARM_ENABLE 0x98
+#define PRCM_PLLARM_ENABLE_PRCM_PLLARM_ENABLE	BIT(0)
+#define PRCM_PLLARM_ENABLE_PRCM_PLLARM_COUNTON	BIT(8)
+
+#define PRCM_ARMCLKFIX_MGT	0x0
+#define PRCM_A9_RESETN_CLR	0x1f4
+#define PRCM_A9_RESETN_SET	0x1f0
+#define PRCM_ARM_LS_CLAMP	0x30C
+#define PRCM_SRAM_A9		0x308
+
+/* ARM WFI Standby signal register */
+#define PRCM_ARM_WFI_STANDBY	0x130
+#define PRCM_IOCR		0x310
+#define PRCM_IOCR_IOFORCE BIT(0)
+
+/* CPU mailbox registers */
+#define PRCM_MBOX_CPU_VAL 0x0FC
+#define PRCM_MBOX_CPU_SET 0x100
+
+/* Dual A9 core interrupt management unit registers */
+#define PRCM_A9_MASK_REQ 0x328
+#define PRCM_A9_MASK_REQ_PRCM_A9_MASK_REQ BIT(0)
+
+#define PRCM_A9_MASK_ACK	0x32C
+#define PRCM_ARMITMSK31TO0	0x11C
+#define PRCM_ARMITMSK63TO32	0x120
+#define PRCM_ARMITMSK95TO64	0x124
+#define PRCM_ARMITMSK127TO96	0x128
+#define PRCM_POWER_STATE_VAL	0x25C
+#define PRCM_ARMITVAL31TO0	0x260
+#define PRCM_ARMITVAL63TO32	0x264
+#define PRCM_ARMITVAL95TO64	0x268
+#define PRCM_ARMITVAL127TO96	0x26C
+
+#define PRCM_HOSTACCESS_REQ 0x334
+#define PRCM_HOSTACCESS_REQ_HOSTACCESS_REQ BIT(0)
+
+#define PRCM_ARM_IT1_CLR 0x48C
+#define PRCM_ARM_IT1_VAL 0x494
+
+#define PRCM_ITSTATUS0		0x148
+#define PRCM_ITSTATUS1		0x150
+#define PRCM_ITSTATUS2		0x158
+#define PRCM_ITSTATUS3		0x160
+#define PRCM_ITSTATUS4		0x168
+#define PRCM_ITSTATUS5		0x484
+#define PRCM_ITCLEAR5		0x488
+#define PRCM_ARMIT_MASKXP70_IT	0x1018
+
+/* System reset register */
+#define PRCM_APE_SOFTRST 0x228
+
+/* Level shifter and clamp control registers */
+#define PRCM_MMIP_LS_CLAMP_SET 0x420
+#define PRCM_MMIP_LS_CLAMP_CLR 0x424
+
+/* PRCMU HW semaphore */
+#define PRCM_SEM 0x400
+#define PRCM_SEM_PRCM_SEM BIT(0)
+
+/* PRCMU clock/PLL/reset registers */
+#define PRCM_PLLDSI_FREQ	0x500
+#define PRCM_PLLDSI_ENABLE	0x504
+#define PRCM_PLLDSI_LOCKP	0x508
+#define PRCM_DSI_PLLOUT_SEL	0x530
+#define PRCM_DSITVCLK_DIV	0x52C
+#define PRCM_APE_RESETN_SET	0x1E4
+#define PRCM_APE_RESETN_CLR	0x1E8
+
+#define PRCM_TCR		0x1C8
+#define PRCM_TCR_TENSEL_MASK	BITS(0, 7)
+#define PRCM_TCR_STOP_TIMERS	BIT(16)
+#define PRCM_TCR_DOZE_MODE	BIT(17)
+
+#define PRCM_CLKOCR			0x1CC
+#define PRCM_CLKOCR_CLKODIV0_SHIFT	0
+#define PRCM_CLKOCR_CLKODIV0_MASK	BITS(0, 5)
+#define PRCM_CLKOCR_CLKOSEL0_SHIFT	6
+#define PRCM_CLKOCR_CLKOSEL0_MASK	BITS(6, 8)
+#define PRCM_CLKOCR_CLKODIV1_SHIFT	16
+#define PRCM_CLKOCR_CLKODIV1_MASK	BITS(16, 21)
+#define PRCM_CLKOCR_CLKOSEL1_SHIFT	22
+#define PRCM_CLKOCR_CLKOSEL1_MASK	BITS(22, 24)
+#define PRCM_CLKOCR_CLK1TYPE		BIT(28)
+
+#define PRCM_SGACLK_MGT		0x014
+#define PRCM_UARTCLK_MGT	0x018
+#define PRCM_MSP02CLK_MGT	0x01C
+#define PRCM_MSP1CLK_MGT	0x288
+#define PRCM_I2CCLK_MGT		0x020
+#define PRCM_SDMMCCLK_MGT	0x024
+#define PRCM_SLIMCLK_MGT	0x028
+#define PRCM_PER1CLK_MGT	0x02C
+#define PRCM_PER2CLK_MGT	0x030
+#define PRCM_PER3CLK_MGT	0x034
+#define PRCM_PER5CLK_MGT	0x038
+#define PRCM_PER6CLK_MGT	0x03C
+#define PRCM_PER7CLK_MGT	0x040
+#define PRCM_LCDCLK_MGT		0x044
+#define PRCM_BMLCLK_MGT		0x04C
+#define PRCM_HSITXCLK_MGT	0x050
+#define PRCM_HSIRXCLK_MGT	0x054
+#define PRCM_HDMICLK_MGT	0x058
+#define PRCM_APEATCLK_MGT	0x05C
+#define PRCM_APETRACECLK_MGT	0x060
+#define PRCM_MCDECLK_MGT	0x064
+#define PRCM_IPI2CCLK_MGT	0x068
+#define PRCM_DSIALTCLK_MGT	0x06C
+#define PRCM_DMACLK_MGT		0x074
+#define PRCM_B2R2CLK_MGT	0x078
+#define PRCM_TVCLK_MGT		0x07C
+#define PRCM_UNIPROCLK_MGT	0x278
+#define PRCM_SSPCLK_MGT		0x280
+#define PRCM_RNGCLK_MGT		0x284
+#define PRCM_UICCCLK_MGT	0x27C
+
+#define PRCM_CLK_MGT_CLKPLLDIV_MASK	BITS(0, 4)
+#define PRCM_CLK_MGT_CLKPLLSW_MASK	BITS(5, 7)
+#define PRCM_CLK_MGT_CLKEN		BIT(8)
+
+/* ePOD and memory power signal control registers */
+#define PRCM_EPOD_C_SET		0x410
+#define PRCM_SRAM_LS_SLEEP	0x304
+
+/* Debug power control unit registers */
+#define PRCM_POWER_STATE_SET 0x254
+
+/* Miscellaneous unit registers */
+#define PRCM_DSI_SW_RESET 0x324
+#define PRCM_GPIOCR		0x138
+
+/* GPIOCR register */
+#define PRCM_GPIOCR_SPI2_SELECT BIT(23)
+
+#define PRCM_DDR_SUBSYS_APE_MINBW  0x438
+
+#endif /* __DB8500_PRCMU_REGS_H */
diff -druN linux-2.6.39-libre/drivers/mfd/htc-pasic3.c linux-3.0-rc7-libre/drivers/mfd/htc-pasic3.c
--- linux-2.6.39-libre/drivers/mfd/htc-pasic3.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mfd/htc-pasic3.c	2011-07-11 19:51:52.000000000 -0400
@@ -99,6 +99,7 @@
 
 static struct ds1wm_driver_data ds1wm_pdata = {
 	.active_high = 0,
+	.reset_recover_delay = 1,
 };
 
 static struct resource ds1wm_resources[] __initdata = {
@@ -117,7 +118,8 @@
 	.name          = "ds1wm",
 	.enable        = ds1wm_enable,
 	.disable       = ds1wm_disable,
-	.mfd_data      = &ds1wm_pdata,
+	.platform_data = &ds1wm_pdata,
+	.pdata_size    = sizeof(ds1wm_pdata),
 	.num_resources = 2,
 	.resources     = ds1wm_resources,
 };
@@ -172,6 +174,8 @@
 	}
 
 	if (pdata && pdata->led_pdata) {
+		led_cell.platform_data = pdata->led_pdata;
+		led_cell.pdata_size = sizeof(struct pasic3_leds_machinfo);
 		ret = mfd_add_devices(&pdev->dev, pdev->id, &led_cell, 1, r, 0);
 		if (ret < 0)
 			dev_warn(dev, "failed to register LED device\n");
diff -druN linux-2.6.39-libre/drivers/mfd/janz-cmodio.c linux-3.0-rc7-libre/drivers/mfd/janz-cmodio.c
--- linux-2.6.39-libre/drivers/mfd/janz-cmodio.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mfd/janz-cmodio.c	2011-07-11 19:51:52.000000000 -0400
@@ -86,7 +86,8 @@
 
 	/* Add platform data */
 	pdata->modno = modno;
-	cell->mfd_data = pdata;
+	cell->platform_data = pdata;
+	cell->pdata_size = sizeof(*pdata);
 
 	/* MODULbus registers -- PCI BAR3 is big-endian MODULbus access */
 	res->flags = IORESOURCE_MEM;
diff -druN linux-2.6.39-libre/drivers/mfd/Kconfig linux-3.0-rc7-libre/drivers/mfd/Kconfig
--- linux-2.6.39-libre/drivers/mfd/Kconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mfd/Kconfig	2011-07-11 19:51:52.000000000 -0400
@@ -157,6 +157,20 @@
 	  This driver can also be built as a module.  If so, the module
 	  will be called tps6507x.
 
+config MFD_TPS6586X
+	bool "TPS6586x Power Management chips"
+	depends on I2C=y && GPIOLIB && GENERIC_HARDIRQS
+	select MFD_CORE
+	help
+	  If you say yes here you get support for the TPS6586X series of
+	  Power Management chips.
+	  This driver provides common support for accessing the device,
+	  additional drivers must be enabled in order to use the
+	  functionality of the device.
+
+	  This driver can also be built as a module.  If so, the module
+	  will be called tps6586x.
+
 config MENELAUS
 	bool "Texas Instruments TWL92330/Menelaus PM chip"
 	depends on I2C=y && ARCH_OMAP2
@@ -455,6 +469,20 @@
 	  facilities, and registers devices for the various functions
 	  so that function-specific drivers can bind to them.
 
+config PCF50633_ADC
+	tristate "Support for NXP PCF50633 ADC"
+	depends on MFD_PCF50633
+	help
+	 Say yes here if you want to include support for ADC in the
+	 NXP PCF50633 chip.
+
+config PCF50633_GPIO
+	tristate "Support for NXP PCF50633 GPIO"
+	depends on MFD_PCF50633
+	help
+	 Say yes here if you want to include support GPIO for pins on
+	 the PCF50633 chip.
+
 config MFD_MC13783
 	tristate
 
@@ -470,20 +498,6 @@
 	  additional drivers must be enabled in order to use the
 	  functionality of the device.
 
-config PCF50633_ADC
-	tristate "Support for NXP PCF50633 ADC"
-	depends on MFD_PCF50633
-	help
-	 Say yes here if you want to include support for ADC in the
-	 NXP PCF50633 chip.
-
-config PCF50633_GPIO
-	tristate "Support for NXP PCF50633 GPIO"
-	depends on MFD_PCF50633
-	help
-	 Say yes here if you want to include support GPIO for pins on
-	 the PCF50633 chip.
-
 config ABX500_CORE
 	bool "ST-Ericsson ABX500 Mixed Signal Circuit register functions"
 	default y if ARCH_U300 || ARCH_U8500
@@ -538,7 +552,7 @@
 
 config AB8500_I2C_CORE
 	bool "AB8500 register access via PRCMU I2C"
-	depends on AB8500_CORE && UX500_SOC_DB8500
+	depends on AB8500_CORE && MFD_DB8500_PRCMU
 	default y
 	help
 	  This enables register access to the AB8500 chip via PRCMU I2C.
@@ -575,6 +589,26 @@
 	  LEDs, vibrator, system power and temperature, power management
 	  and ALSA sound.
 
+config MFD_DB8500_PRCMU
+	bool "ST-Ericsson DB8500 Power Reset Control Management Unit"
+	depends on UX500_SOC_DB8500
+	select MFD_CORE
+	help
+	  Select this option to enable support for the DB8500 Power Reset
+	  and Control Management Unit. This is basically an autonomous
+	  system controller running an XP70 microprocessor, which is accessed
+	  through a register map.
+
+config MFD_DB5500_PRCMU
+	bool "ST-Ericsson DB5500 Power Reset Control Management Unit"
+	depends on UX500_SOC_DB5500
+	select MFD_CORE
+	help
+	  Select this option to enable support for the DB5500 Power Reset
+	  and Control Management Unit. This is basically an autonomous
+	  system controller running an XP70 microprocessor, which is accessed
+	  through a register map.
+
 config MFD_CS5535
 	tristate "Support for CS5535 and CS5536 southbridge core functions"
 	select MFD_CORE
@@ -629,20 +663,6 @@
 	  Say yes here if you want support for the ADC unit in the JZ4740 SoC.
 	  This driver is necessary for jz4740-battery and jz4740-hwmon driver.
 
-config MFD_TPS6586X
-	bool "TPS6586x Power Management chips"
-	depends on I2C=y && GPIOLIB && GENERIC_HARDIRQS
-	select MFD_CORE
-	help
-	  If you say yes here you get support for the TPS6586X series of
-	  Power Management chips.
-	  This driver provides common support for accessing the device,
-	  additional drivers must be enabled in order to use the
-	  functionality of the device.
-
-	  This driver can also be built as a module.  If so, the module
-	  will be called tps6586x.
-
 config MFD_VX855
 	tristate "Support for VIA VX855/VX875 integrated south bridge"
 	depends on PCI
@@ -671,6 +691,46 @@
 	  This MFD driver does the required setup functionalities for
 	  OMAP USB Host drivers.
 
+config MFD_PM8XXX
+	tristate
+
+config MFD_PM8921_CORE
+	tristate "Qualcomm PM8921 PMIC chip"
+	depends on MSM_SSBI
+	select MFD_CORE
+	select MFD_PM8XXX
+	help
+	  If you say yes to this option, support will be included for the
+	  built-in PM8921 PMIC chip.
+
+	  This is required if your board has a PM8921 and uses its features,
+	  such as: MPPs, GPIOs, regulators, interrupts, and PWM.
+
+	  Say M here if you want to include support for PM8921 chip as a module.
+	  This will build a module called "pm8921-core".
+
+config MFD_PM8XXX_IRQ
+	bool "Support for Qualcomm PM8xxx IRQ features"
+	depends on MFD_PM8XXX
+	default y if MFD_PM8XXX
+	help
+	  This is the IRQ driver for Qualcomm PM 8xxx PMIC chips.
+
+	  This is required to use certain other PM 8xxx features, such as GPIO
+	  and MPP.
+
+config MFD_TPS65910
+	bool "TPS65910 Power Management chip"
+	depends on I2C=y && GPIOLIB
+	select MFD_CORE
+	select GPIO_TPS65910
+	help
+	  if you say yes here you get support for the TPS65910 series of
+	  Power Management chips.
+
+config TPS65911_COMPARATOR
+	tristate
+
 endif # MFD_SUPPORT
 
 menu "Multimedia Capabilities Port drivers"
diff -druN linux-2.6.39-libre/drivers/mfd/Makefile linux-3.0-rc7-libre/drivers/mfd/Makefile
--- linux-2.6.39-libre/drivers/mfd/Makefile	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mfd/Makefile	2011-07-11 19:51:52.000000000 -0400
@@ -74,9 +74,12 @@
 obj-$(CONFIG_AB3100_OTP)	+= ab3100-otp.o
 obj-$(CONFIG_AB3550_CORE)	+= ab3550-core.o
 obj-$(CONFIG_AB8500_CORE)	+= ab8500-core.o ab8500-sysctrl.o
-obj-$(CONFIG_AB8500_I2C_CORE)	+= ab8500-i2c.o
 obj-$(CONFIG_AB8500_DEBUG)	+= ab8500-debugfs.o
 obj-$(CONFIG_AB8500_GPADC)	+= ab8500-gpadc.o
+obj-$(CONFIG_MFD_DB8500_PRCMU)	+= db8500-prcmu.o
+# ab8500-i2c need to come after db8500-prcmu (which provides the channel)
+obj-$(CONFIG_AB8500_I2C_CORE)	+= ab8500-i2c.o
+obj-$(CONFIG_MFD_DB5500_PRCMU)	+= db5500-prcmu.o
 obj-$(CONFIG_MFD_TIMBERDALE)    += timberdale.o
 obj-$(CONFIG_PMIC_ADP5520)	+= adp5520.o
 obj-$(CONFIG_LPC_SCH)		+= lpc_sch.o
@@ -88,3 +91,7 @@
 obj-$(CONFIG_MFD_WL1273_CORE)	+= wl1273-core.o
 obj-$(CONFIG_MFD_CS5535)	+= cs5535-mfd.o
 obj-$(CONFIG_MFD_OMAP_USB_HOST)	+= omap-usb-host.o
+obj-$(CONFIG_MFD_PM8921_CORE) 	+= pm8921-core.o
+obj-$(CONFIG_MFD_PM8XXX_IRQ) 	+= pm8xxx-irq.o
+obj-$(CONFIG_MFD_TPS65910)	+= tps65910.o tps65910-irq.o
+obj-$(CONFIG_TPS65911_COMPARATOR)	+= tps65911-comparator.o
diff -druN linux-2.6.39-libre/drivers/mfd/max8925-core.c linux-3.0-rc7-libre/drivers/mfd/max8925-core.c
--- linux-2.6.39-libre/drivers/mfd/max8925-core.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mfd/max8925-core.c	2011-07-11 19:51:52.000000000 -0400
@@ -627,7 +627,7 @@
 		goto out_dev;
 	}
 
-	if (pdata && pdata->regulator[0]) {
+	if (pdata) {
 		ret = mfd_add_devices(chip->dev, 0, &regulator_devs[0],
 				      ARRAY_SIZE(regulator_devs),
 				      &regulator_resources[0], 0);
diff -druN linux-2.6.39-libre/drivers/mfd/mc13xxx-core.c linux-3.0-rc7-libre/drivers/mfd/mc13xxx-core.c
--- linux-2.6.39-libre/drivers/mfd/mc13xxx-core.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mfd/mc13xxx-core.c	2011-07-11 19:51:52.000000000 -0400
@@ -683,13 +683,14 @@
 EXPORT_SYMBOL_GPL(mc13783_adc_do_conversion);
 
 static int mc13xxx_add_subdevice_pdata(struct mc13xxx *mc13xxx,
-		const char *format, void *pdata)
+		const char *format, void *pdata, size_t pdata_size)
 {
 	char buf[30];
 	const char *name = mc13xxx_get_chipname(mc13xxx);
 
 	struct mfd_cell cell = {
-		.mfd_data = pdata,
+		.platform_data = pdata,
+		.pdata_size = pdata_size,
 	};
 
 	/* there is no asnprintf in the kernel :-( */
@@ -705,7 +706,7 @@
 
 static int mc13xxx_add_subdevice(struct mc13xxx *mc13xxx, const char *format)
 {
-	return mc13xxx_add_subdevice_pdata(mc13xxx, format, NULL);
+	return mc13xxx_add_subdevice_pdata(mc13xxx, format, NULL, 0);
 }
 
 static int mc13xxx_probe(struct spi_device *spi)
@@ -764,7 +765,7 @@
 
 	if (pdata->flags & MC13XXX_USE_REGULATOR) {
 		mc13xxx_add_subdevice_pdata(mc13xxx, "%s-regulator",
-				&pdata->regulators);
+				&pdata->regulators, sizeof(pdata->regulators));
 	}
 
 	if (pdata->flags & MC13XXX_USE_RTC)
@@ -774,7 +775,8 @@
 		mc13xxx_add_subdevice(mc13xxx, "%s-ts");
 
 	if (pdata->flags & MC13XXX_USE_LED)
-		mc13xxx_add_subdevice_pdata(mc13xxx, "%s-led", pdata->leds);
+		mc13xxx_add_subdevice_pdata(mc13xxx, "%s-led",
+				pdata->leds, sizeof(*pdata->leds));
 
 	return 0;
 }
diff -druN linux-2.6.39-libre/drivers/mfd/mfd-core.c linux-3.0-rc7-libre/drivers/mfd/mfd-core.c
--- linux-2.6.39-libre/drivers/mfd/mfd-core.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mfd/mfd-core.c	2011-07-11 19:51:52.000000000 -0400
@@ -88,6 +88,13 @@
 
 	pdev->dev.parent = parent;
 
+	if (cell->pdata_size) {
+		ret = platform_device_add_data(pdev,
+					cell->platform_data, cell->pdata_size);
+		if (ret)
+			goto fail_res;
+	}
+
 	ret = mfd_platform_add_cell(pdev, cell);
 	if (ret)
 		goto fail_res;
diff -druN linux-2.6.39-libre/drivers/mfd/omap-usb-host.c linux-3.0-rc7-libre/drivers/mfd/omap-usb-host.c
--- linux-2.6.39-libre/drivers/mfd/omap-usb-host.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mfd/omap-usb-host.c	2011-07-11 19:51:52.000000000 -0400
@@ -281,6 +281,7 @@
 
 	if (!ehci) {
 		dev_err(dev, "omap_usbhs_alloc_child failed\n");
+		ret = -ENOMEM;
 		goto err_end;
 	}
 
@@ -304,13 +305,14 @@
 		sizeof(*ohci_data), dev);
 	if (!ohci) {
 		dev_err(dev, "omap_usbhs_alloc_child failed\n");
+		ret = -ENOMEM;
 		goto err_ehci;
 	}
 
 	return 0;
 
 err_ehci:
-	platform_device_put(ehci);
+	platform_device_unregister(ehci);
 
 err_end:
 	return ret;
@@ -994,22 +996,33 @@
 			dev_dbg(dev, "operation timed out\n");
 	}
 
-	if (pdata->ehci_data->phy_reset) {
-		if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[0]))
-			gpio_free(pdata->ehci_data->reset_gpio_port[0]);
-
-		if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[1]))
-			gpio_free(pdata->ehci_data->reset_gpio_port[1]);
+	if (is_omap_usbhs_rev2(omap)) {
+		if (is_ehci_tll_mode(pdata->port_mode[0]))
+			clk_enable(omap->usbtll_p1_fck);
+		if (is_ehci_tll_mode(pdata->port_mode[1]))
+			clk_enable(omap->usbtll_p2_fck);
+		clk_disable(omap->utmi_p2_fck);
+		clk_disable(omap->utmi_p1_fck);
 	}
 
-	clk_disable(omap->utmi_p2_fck);
-	clk_disable(omap->utmi_p1_fck);
 	clk_disable(omap->usbtll_ick);
 	clk_disable(omap->usbtll_fck);
 	clk_disable(omap->usbhost_fs_fck);
 	clk_disable(omap->usbhost_hs_fck);
 	clk_disable(omap->usbhost_ick);
 
+	/* The gpio_free migh sleep; so unlock the spinlock */
+	spin_unlock_irqrestore(&omap->lock, flags);
+
+	if (pdata->ehci_data->phy_reset) {
+		if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[0]))
+			gpio_free(pdata->ehci_data->reset_gpio_port[0]);
+
+		if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[1]))
+			gpio_free(pdata->ehci_data->reset_gpio_port[1]);
+	}
+	return;
+
 end_disble:
 	spin_unlock_irqrestore(&omap->lock, flags);
 }
diff -druN linux-2.6.39-libre/drivers/mfd/pm8921-core.c linux-3.0-rc7-libre/drivers/mfd/pm8921-core.c
--- linux-2.6.39-libre/drivers/mfd/pm8921-core.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/mfd/pm8921-core.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,212 @@
+/*
+ * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#define pr_fmt(fmt) "%s: " fmt, __func__
+
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/err.h>
+#include <linux/msm_ssbi.h>
+#include <linux/mfd/core.h>
+#include <linux/mfd/pm8xxx/pm8921.h>
+#include <linux/mfd/pm8xxx/core.h>
+
+#define REG_HWREV		0x002  /* PMIC4 revision */
+#define REG_HWREV_2		0x0E8  /* PMIC4 revision 2 */
+
+struct pm8921 {
+	struct device			*dev;
+	struct pm_irq_chip		*irq_chip;
+};
+
+static int pm8921_readb(const struct device *dev, u16 addr, u8 *val)
+{
+	const struct pm8xxx_drvdata *pm8921_drvdata = dev_get_drvdata(dev);
+	const struct pm8921 *pmic = pm8921_drvdata->pm_chip_data;
+
+	return msm_ssbi_read(pmic->dev->parent, addr, val, 1);
+}
+
+static int pm8921_writeb(const struct device *dev, u16 addr, u8 val)
+{
+	const struct pm8xxx_drvdata *pm8921_drvdata = dev_get_drvdata(dev);
+	const struct pm8921 *pmic = pm8921_drvdata->pm_chip_data;
+
+	return msm_ssbi_write(pmic->dev->parent, addr, &val, 1);
+}
+
+static int pm8921_read_buf(const struct device *dev, u16 addr, u8 *buf,
+									int cnt)
+{
+	const struct pm8xxx_drvdata *pm8921_drvdata = dev_get_drvdata(dev);
+	const struct pm8921 *pmic = pm8921_drvdata->pm_chip_data;
+
+	return msm_ssbi_read(pmic->dev->parent, addr, buf, cnt);
+}
+
+static int pm8921_write_buf(const struct device *dev, u16 addr, u8 *buf,
+									int cnt)
+{
+	const struct pm8xxx_drvdata *pm8921_drvdata = dev_get_drvdata(dev);
+	const struct pm8921 *pmic = pm8921_drvdata->pm_chip_data;
+
+	return msm_ssbi_write(pmic->dev->parent, addr, buf, cnt);
+}
+
+static int pm8921_read_irq_stat(const struct device *dev, int irq)
+{
+	const struct pm8xxx_drvdata *pm8921_drvdata = dev_get_drvdata(dev);
+	const struct pm8921 *pmic = pm8921_drvdata->pm_chip_data;
+
+	return pm8xxx_get_irq_stat(pmic->irq_chip, irq);
+}
+
+static struct pm8xxx_drvdata pm8921_drvdata = {
+	.pmic_readb		= pm8921_readb,
+	.pmic_writeb		= pm8921_writeb,
+	.pmic_read_buf		= pm8921_read_buf,
+	.pmic_write_buf		= pm8921_write_buf,
+	.pmic_read_irq_stat	= pm8921_read_irq_stat,
+};
+
+static int __devinit pm8921_add_subdevices(const struct pm8921_platform_data
+					   *pdata,
+					   struct pm8921 *pmic,
+					   u32 rev)
+{
+	int ret = 0, irq_base = 0;
+	struct pm_irq_chip *irq_chip;
+
+	if (pdata->irq_pdata) {
+		pdata->irq_pdata->irq_cdata.nirqs = PM8921_NR_IRQS;
+		pdata->irq_pdata->irq_cdata.rev = rev;
+		irq_base = pdata->irq_pdata->irq_base;
+		irq_chip = pm8xxx_irq_init(pmic->dev, pdata->irq_pdata);
+
+		if (IS_ERR(irq_chip)) {
+			pr_err("Failed to init interrupts ret=%ld\n",
+					PTR_ERR(irq_chip));
+			return PTR_ERR(irq_chip);
+		}
+		pmic->irq_chip = irq_chip;
+	}
+	return ret;
+}
+
+static int __devinit pm8921_probe(struct platform_device *pdev)
+{
+	const struct pm8921_platform_data *pdata = pdev->dev.platform_data;
+	struct pm8921 *pmic;
+	int rc;
+	u8 val;
+	u32 rev;
+
+	if (!pdata) {
+		pr_err("missing platform data\n");
+		return -EINVAL;
+	}
+
+	pmic = kzalloc(sizeof(struct pm8921), GFP_KERNEL);
+	if (!pmic) {
+		pr_err("Cannot alloc pm8921 struct\n");
+		return -ENOMEM;
+	}
+
+	/* Read PMIC chip revision */
+	rc = msm_ssbi_read(pdev->dev.parent, REG_HWREV, &val, sizeof(val));
+	if (rc) {
+		pr_err("Failed to read hw rev reg %d:rc=%d\n", REG_HWREV, rc);
+		goto err_read_rev;
+	}
+	pr_info("PMIC revision 1: %02X\n", val);
+	rev = val;
+
+	/* Read PMIC chip revision 2 */
+	rc = msm_ssbi_read(pdev->dev.parent, REG_HWREV_2, &val, sizeof(val));
+	if (rc) {
+		pr_err("Failed to read hw rev 2 reg %d:rc=%d\n",
+			REG_HWREV_2, rc);
+		goto err_read_rev;
+	}
+	pr_info("PMIC revision 2: %02X\n", val);
+	rev |= val << BITS_PER_BYTE;
+
+	pmic->dev = &pdev->dev;
+	pm8921_drvdata.pm_chip_data = pmic;
+	platform_set_drvdata(pdev, &pm8921_drvdata);
+
+	rc = pm8921_add_subdevices(pdata, pmic, rev);
+	if (rc) {
+		pr_err("Cannot add subdevices rc=%d\n", rc);
+		goto err;
+	}
+
+	/* gpio might not work if no irq device is found */
+	WARN_ON(pmic->irq_chip == NULL);
+
+	return 0;
+
+err:
+	mfd_remove_devices(pmic->dev);
+	platform_set_drvdata(pdev, NULL);
+err_read_rev:
+	kfree(pmic);
+	return rc;
+}
+
+static int __devexit pm8921_remove(struct platform_device *pdev)
+{
+	struct pm8xxx_drvdata *drvdata;
+	struct pm8921 *pmic = NULL;
+
+	drvdata = platform_get_drvdata(pdev);
+	if (drvdata)
+		pmic = drvdata->pm_chip_data;
+	if (pmic)
+		mfd_remove_devices(pmic->dev);
+	if (pmic->irq_chip) {
+		pm8xxx_irq_exit(pmic->irq_chip);
+		pmic->irq_chip = NULL;
+	}
+	platform_set_drvdata(pdev, NULL);
+	kfree(pmic);
+
+	return 0;
+}
+
+static struct platform_driver pm8921_driver = {
+	.probe		= pm8921_probe,
+	.remove		= __devexit_p(pm8921_remove),
+	.driver		= {
+		.name	= "pm8921-core",
+		.owner	= THIS_MODULE,
+	},
+};
+
+static int __init pm8921_init(void)
+{
+	return platform_driver_register(&pm8921_driver);
+}
+subsys_initcall(pm8921_init);
+
+static void __exit pm8921_exit(void)
+{
+	platform_driver_unregister(&pm8921_driver);
+}
+module_exit(pm8921_exit);
+
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("PMIC 8921 core driver");
+MODULE_VERSION("1.0");
+MODULE_ALIAS("platform:pm8921-core");
diff -druN linux-2.6.39-libre/drivers/mfd/pm8xxx-irq.c linux-3.0-rc7-libre/drivers/mfd/pm8xxx-irq.c
--- linux-2.6.39-libre/drivers/mfd/pm8xxx-irq.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/mfd/pm8xxx-irq.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,371 @@
+/*
+ * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#define pr_fmt(fmt)	"%s: " fmt, __func__
+
+#include <linux/err.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/kernel.h>
+#include <linux/mfd/pm8xxx/core.h>
+#include <linux/mfd/pm8xxx/irq.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+
+/* PMIC8xxx IRQ */
+
+#define	SSBI_REG_ADDR_IRQ_BASE		0x1BB
+
+#define	SSBI_REG_ADDR_IRQ_ROOT		(SSBI_REG_ADDR_IRQ_BASE + 0)
+#define	SSBI_REG_ADDR_IRQ_M_STATUS1	(SSBI_REG_ADDR_IRQ_BASE + 1)
+#define	SSBI_REG_ADDR_IRQ_M_STATUS2	(SSBI_REG_ADDR_IRQ_BASE + 2)
+#define	SSBI_REG_ADDR_IRQ_M_STATUS3	(SSBI_REG_ADDR_IRQ_BASE + 3)
+#define	SSBI_REG_ADDR_IRQ_M_STATUS4	(SSBI_REG_ADDR_IRQ_BASE + 4)
+#define	SSBI_REG_ADDR_IRQ_BLK_SEL	(SSBI_REG_ADDR_IRQ_BASE + 5)
+#define	SSBI_REG_ADDR_IRQ_IT_STATUS	(SSBI_REG_ADDR_IRQ_BASE + 6)
+#define	SSBI_REG_ADDR_IRQ_CONFIG	(SSBI_REG_ADDR_IRQ_BASE + 7)
+#define	SSBI_REG_ADDR_IRQ_RT_STATUS	(SSBI_REG_ADDR_IRQ_BASE + 8)
+
+#define	PM_IRQF_LVL_SEL			0x01	/* level select */
+#define	PM_IRQF_MASK_FE			0x02	/* mask falling edge */
+#define	PM_IRQF_MASK_RE			0x04	/* mask rising edge */
+#define	PM_IRQF_CLR			0x08	/* clear interrupt */
+#define	PM_IRQF_BITS_MASK		0x70
+#define	PM_IRQF_BITS_SHIFT		4
+#define	PM_IRQF_WRITE			0x80
+
+#define	PM_IRQF_MASK_ALL		(PM_IRQF_MASK_FE | \
+					PM_IRQF_MASK_RE)
+
+struct pm_irq_chip {
+	struct device		*dev;
+	spinlock_t		pm_irq_lock;
+	unsigned int		devirq;
+	unsigned int		irq_base;
+	unsigned int		num_irqs;
+	unsigned int		num_blocks;
+	unsigned int		num_masters;
+	u8			config[0];
+};
+
+static int pm8xxx_read_root_irq(const struct pm_irq_chip *chip, u8 *rp)
+{
+	return pm8xxx_readb(chip->dev, SSBI_REG_ADDR_IRQ_ROOT, rp);
+}
+
+static int pm8xxx_read_master_irq(const struct pm_irq_chip *chip, u8 m, u8 *bp)
+{
+	return pm8xxx_readb(chip->dev,
+			SSBI_REG_ADDR_IRQ_M_STATUS1 + m, bp);
+}
+
+static int pm8xxx_read_block_irq(struct pm_irq_chip *chip, u8 bp, u8 *ip)
+{
+	int	rc;
+
+	spin_lock(&chip->pm_irq_lock);
+	rc = pm8xxx_writeb(chip->dev, SSBI_REG_ADDR_IRQ_BLK_SEL, bp);
+	if (rc) {
+		pr_err("Failed Selecting Block %d rc=%d\n", bp, rc);
+		goto bail;
+	}
+
+	rc = pm8xxx_readb(chip->dev, SSBI_REG_ADDR_IRQ_IT_STATUS, ip);
+	if (rc)
+		pr_err("Failed Reading Status rc=%d\n", rc);
+bail:
+	spin_unlock(&chip->pm_irq_lock);
+	return rc;
+}
+
+static int pm8xxx_config_irq(struct pm_irq_chip *chip, u8 bp, u8 cp)
+{
+	int	rc;
+
+	spin_lock(&chip->pm_irq_lock);
+	rc = pm8xxx_writeb(chip->dev, SSBI_REG_ADDR_IRQ_BLK_SEL, bp);
+	if (rc) {
+		pr_err("Failed Selecting Block %d rc=%d\n", bp, rc);
+		goto bail;
+	}
+
+	cp |= PM_IRQF_WRITE;
+	rc = pm8xxx_writeb(chip->dev, SSBI_REG_ADDR_IRQ_CONFIG, cp);
+	if (rc)
+		pr_err("Failed Configuring IRQ rc=%d\n", rc);
+bail:
+	spin_unlock(&chip->pm_irq_lock);
+	return rc;
+}
+
+static int pm8xxx_irq_block_handler(struct pm_irq_chip *chip, int block)
+{
+	int pmirq, irq, i, ret = 0;
+	u8 bits;
+
+	ret = pm8xxx_read_block_irq(chip, block, &bits);
+	if (ret) {
+		pr_err("Failed reading %d block ret=%d", block, ret);
+		return ret;
+	}
+	if (!bits) {
+		pr_err("block bit set in master but no irqs: %d", block);
+		return 0;
+	}
+
+	/* Check IRQ bits */
+	for (i = 0; i < 8; i++) {
+		if (bits & (1 << i)) {
+			pmirq = block * 8 + i;
+			irq = pmirq + chip->irq_base;
+			generic_handle_irq(irq);
+		}
+	}
+	return 0;
+}
+
+static int pm8xxx_irq_master_handler(struct pm_irq_chip *chip, int master)
+{
+	u8 blockbits;
+	int block_number, i, ret = 0;
+
+	ret = pm8xxx_read_master_irq(chip, master, &blockbits);
+	if (ret) {
+		pr_err("Failed to read master %d ret=%d\n", master, ret);
+		return ret;
+	}
+	if (!blockbits) {
+		pr_err("master bit set in root but no blocks: %d", master);
+		return 0;
+	}
+
+	for (i = 0; i < 8; i++)
+		if (blockbits & (1 << i)) {
+			block_number = master * 8 + i;	/* block # */
+			ret |= pm8xxx_irq_block_handler(chip, block_number);
+		}
+	return ret;
+}
+
+static void pm8xxx_irq_handler(unsigned int irq, struct irq_desc *desc)
+{
+	struct pm_irq_chip *chip = irq_desc_get_handler_data(desc);
+	struct irq_chip *irq_chip = irq_desc_get_chip(desc);
+	u8	root;
+	int	i, ret, masters = 0;
+
+	ret = pm8xxx_read_root_irq(chip, &root);
+	if (ret) {
+		pr_err("Can't read root status ret=%d\n", ret);
+		return;
+	}
+
+	/* on pm8xxx series masters start from bit 1 of the root */
+	masters = root >> 1;
+
+	/* Read allowed masters for blocks. */
+	for (i = 0; i < chip->num_masters; i++)
+		if (masters & (1 << i))
+			pm8xxx_irq_master_handler(chip, i);
+
+	irq_chip->irq_ack(&desc->irq_data);
+}
+
+static void pm8xxx_irq_mask_ack(struct irq_data *d)
+{
+	struct pm_irq_chip *chip = irq_data_get_irq_chip_data(d);
+	unsigned int pmirq = d->irq - chip->irq_base;
+	int	master, irq_bit;
+	u8	block, config;
+
+	block = pmirq / 8;
+	master = block / 8;
+	irq_bit = pmirq % 8;
+
+	config = chip->config[pmirq] | PM_IRQF_MASK_ALL | PM_IRQF_CLR;
+	pm8xxx_config_irq(chip, block, config);
+}
+
+static void pm8xxx_irq_unmask(struct irq_data *d)
+{
+	struct pm_irq_chip *chip = irq_data_get_irq_chip_data(d);
+	unsigned int pmirq = d->irq - chip->irq_base;
+	int	master, irq_bit;
+	u8	block, config;
+
+	block = pmirq / 8;
+	master = block / 8;
+	irq_bit = pmirq % 8;
+
+	config = chip->config[pmirq];
+	pm8xxx_config_irq(chip, block, config);
+}
+
+static int pm8xxx_irq_set_type(struct irq_data *d, unsigned int flow_type)
+{
+	struct pm_irq_chip *chip = irq_data_get_irq_chip_data(d);
+	unsigned int pmirq = d->irq - chip->irq_base;
+	int master, irq_bit;
+	u8 block, config;
+
+	block = pmirq / 8;
+	master = block / 8;
+	irq_bit  = pmirq % 8;
+
+	chip->config[pmirq] = (irq_bit << PM_IRQF_BITS_SHIFT)
+							| PM_IRQF_MASK_ALL;
+	if (flow_type & (IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING)) {
+		if (flow_type & IRQF_TRIGGER_RISING)
+			chip->config[pmirq] &= ~PM_IRQF_MASK_RE;
+		if (flow_type & IRQF_TRIGGER_FALLING)
+			chip->config[pmirq] &= ~PM_IRQF_MASK_FE;
+	} else {
+		chip->config[pmirq] |= PM_IRQF_LVL_SEL;
+
+		if (flow_type & IRQF_TRIGGER_HIGH)
+			chip->config[pmirq] &= ~PM_IRQF_MASK_RE;
+		else
+			chip->config[pmirq] &= ~PM_IRQF_MASK_FE;
+	}
+
+	config = chip->config[pmirq] | PM_IRQF_CLR;
+	return pm8xxx_config_irq(chip, block, config);
+}
+
+static int pm8xxx_irq_set_wake(struct irq_data *d, unsigned int on)
+{
+	return 0;
+}
+
+static struct irq_chip pm8xxx_irq_chip = {
+	.name		= "pm8xxx",
+	.irq_mask_ack	= pm8xxx_irq_mask_ack,
+	.irq_unmask	= pm8xxx_irq_unmask,
+	.irq_set_type	= pm8xxx_irq_set_type,
+	.irq_set_wake	= pm8xxx_irq_set_wake,
+	.flags		= IRQCHIP_MASK_ON_SUSPEND,
+};
+
+/**
+ * pm8xxx_get_irq_stat - get the status of the irq line
+ * @chip: pointer to identify a pmic irq controller
+ * @irq: the irq number
+ *
+ * The pm8xxx gpio and mpp rely on the interrupt block to read
+ * the values on their pins. This function is to facilitate reading
+ * the status of a gpio or an mpp line. The caller has to convert the
+ * gpio number to irq number.
+ *
+ * RETURNS:
+ * an int indicating the value read on that line
+ */
+int pm8xxx_get_irq_stat(struct pm_irq_chip *chip, int irq)
+{
+	int pmirq, rc;
+	u8  block, bits, bit;
+	unsigned long flags;
+
+	if (chip == NULL || irq < chip->irq_base ||
+			irq >= chip->irq_base + chip->num_irqs)
+		return -EINVAL;
+
+	pmirq = irq - chip->irq_base;
+
+	block = pmirq / 8;
+	bit = pmirq % 8;
+
+	spin_lock_irqsave(&chip->pm_irq_lock, flags);
+
+	rc = pm8xxx_writeb(chip->dev, SSBI_REG_ADDR_IRQ_BLK_SEL, block);
+	if (rc) {
+		pr_err("Failed Selecting block irq=%d pmirq=%d blk=%d rc=%d\n",
+			irq, pmirq, block, rc);
+		goto bail_out;
+	}
+
+	rc = pm8xxx_readb(chip->dev, SSBI_REG_ADDR_IRQ_RT_STATUS, &bits);
+	if (rc) {
+		pr_err("Failed Configuring irq=%d pmirq=%d blk=%d rc=%d\n",
+			irq, pmirq, block, rc);
+		goto bail_out;
+	}
+
+	rc = (bits & (1 << bit)) ? 1 : 0;
+
+bail_out:
+	spin_unlock_irqrestore(&chip->pm_irq_lock, flags);
+
+	return rc;
+}
+EXPORT_SYMBOL_GPL(pm8xxx_get_irq_stat);
+
+struct pm_irq_chip *  __devinit pm8xxx_irq_init(struct device *dev,
+				const struct pm8xxx_irq_platform_data *pdata)
+{
+	struct pm_irq_chip  *chip;
+	int devirq, rc;
+	unsigned int pmirq;
+
+	if (!pdata) {
+		pr_err("No platform data\n");
+		return ERR_PTR(-EINVAL);
+	}
+
+	devirq = pdata->devirq;
+	if (devirq < 0) {
+		pr_err("missing devirq\n");
+		rc = devirq;
+		return ERR_PTR(-EINVAL);
+	}
+
+	chip = kzalloc(sizeof(struct pm_irq_chip)
+			+ sizeof(u8) * pdata->irq_cdata.nirqs, GFP_KERNEL);
+	if (!chip) {
+		pr_err("Cannot alloc pm_irq_chip struct\n");
+		return ERR_PTR(-EINVAL);
+	}
+
+	chip->dev = dev;
+	chip->devirq = devirq;
+	chip->irq_base = pdata->irq_base;
+	chip->num_irqs = pdata->irq_cdata.nirqs;
+	chip->num_blocks = DIV_ROUND_UP(chip->num_irqs, 8);
+	chip->num_masters = DIV_ROUND_UP(chip->num_blocks, 8);
+	spin_lock_init(&chip->pm_irq_lock);
+
+	for (pmirq = 0; pmirq < chip->num_irqs; pmirq++) {
+		irq_set_chip_and_handler(chip->irq_base + pmirq,
+				&pm8xxx_irq_chip,
+				handle_level_irq);
+		irq_set_chip_data(chip->irq_base + pmirq, chip);
+#ifdef CONFIG_ARM
+		set_irq_flags(chip->irq_base + pmirq, IRQF_VALID);
+#else
+		irq_set_noprobe(chip->irq_base + pmirq);
+#endif
+	}
+
+	irq_set_irq_type(devirq, pdata->irq_trigger_flag);
+	irq_set_handler_data(devirq, chip);
+	irq_set_chained_handler(devirq, pm8xxx_irq_handler);
+	set_irq_wake(devirq, 1);
+
+	return chip;
+}
+
+int __devexit pm8xxx_irq_exit(struct pm_irq_chip *chip)
+{
+	irq_set_chained_handler(chip->devirq, NULL);
+	kfree(chip);
+	return 0;
+}
diff -druN linux-2.6.39-libre/drivers/mfd/rdc321x-southbridge.c linux-3.0-rc7-libre/drivers/mfd/rdc321x-southbridge.c
--- linux-2.6.39-libre/drivers/mfd/rdc321x-southbridge.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mfd/rdc321x-southbridge.c	2011-07-11 19:51:52.000000000 -0400
@@ -61,12 +61,14 @@
 		.name		= "rdc321x-wdt",
 		.resources	= rdc321x_wdt_resource,
 		.num_resources	= ARRAY_SIZE(rdc321x_wdt_resource),
-		.mfd_data	= &rdc321x_wdt_pdata,
+		.platform_data	= &rdc321x_wdt_pdata,
+		.pdata_size	= sizeof(rdc321x_wdt_pdata),
 	}, {
 		.name		= "rdc321x-gpio",
 		.resources	= rdc321x_gpio_resources,
 		.num_resources	= ARRAY_SIZE(rdc321x_gpio_resources),
-		.mfd_data	= &rdc321x_gpio_pdata,
+		.platform_data	= &rdc321x_gpio_pdata,
+		.pdata_size	= sizeof(rdc321x_gpio_pdata),
 	},
 };
 
diff -druN linux-2.6.39-libre/drivers/mfd/t7l66xb.c linux-3.0-rc7-libre/drivers/mfd/t7l66xb.c
--- linux-2.6.39-libre/drivers/mfd/t7l66xb.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mfd/t7l66xb.c	2011-07-11 19:51:52.000000000 -0400
@@ -170,7 +170,8 @@
 		.name = "tmio-mmc",
 		.enable = t7l66xb_mmc_enable,
 		.disable = t7l66xb_mmc_disable,
-		.mfd_data = &t7166xb_mmc_data,
+		.platform_data = &t7166xb_mmc_data,
+		.pdata_size    = sizeof(t7166xb_mmc_data),
 		.num_resources = ARRAY_SIZE(t7l66xb_mmc_resources),
 		.resources = t7l66xb_mmc_resources,
 	},
@@ -382,7 +383,8 @@
 
 	t7l66xb_attach_irq(dev);
 
-	t7l66xb_cells[T7L66XB_CELL_NAND].mfd_data = pdata->nand_data;
+	t7l66xb_cells[T7L66XB_CELL_NAND].platform_data = pdata->nand_data;
+	t7l66xb_cells[T7L66XB_CELL_NAND].pdata_size = sizeof(*pdata->nand_data);
 
 	ret = mfd_add_devices(&dev->dev, dev->id,
 			      t7l66xb_cells, ARRAY_SIZE(t7l66xb_cells),
diff -druN linux-2.6.39-libre/drivers/mfd/tc6387xb.c linux-3.0-rc7-libre/drivers/mfd/tc6387xb.c
--- linux-2.6.39-libre/drivers/mfd/tc6387xb.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mfd/tc6387xb.c	2011-07-11 19:51:52.000000000 -0400
@@ -131,7 +131,8 @@
 		.name = "tmio-mmc",
 		.enable = tc6387xb_mmc_enable,
 		.disable = tc6387xb_mmc_disable,
-		.mfd_data = &tc6387xb_mmc_data,
+		.platform_data = &tc6387xb_mmc_data,
+		.pdata_size    = sizeof(tc6387xb_mmc_data),
 		.num_resources = ARRAY_SIZE(tc6387xb_mmc_resources),
 		.resources = tc6387xb_mmc_resources,
 	},
diff -druN linux-2.6.39-libre/drivers/mfd/tc6393xb.c linux-3.0-rc7-libre/drivers/mfd/tc6393xb.c
--- linux-2.6.39-libre/drivers/mfd/tc6393xb.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mfd/tc6393xb.c	2011-07-11 19:51:52.000000000 -0400
@@ -393,7 +393,8 @@
 		.name = "tmio-mmc",
 		.enable = tc6393xb_mmc_enable,
 		.resume = tc6393xb_mmc_resume,
-		.mfd_data = &tc6393xb_mmc_data,
+		.platform_data = &tc6393xb_mmc_data,
+		.pdata_size    = sizeof(tc6393xb_mmc_data),
 		.num_resources = ARRAY_SIZE(tc6393xb_mmc_resources),
 		.resources = tc6393xb_mmc_resources,
 	},
@@ -692,8 +693,11 @@
 			goto err_setup;
 	}
 
-	tc6393xb_cells[TC6393XB_CELL_NAND].mfd_data = tcpd->nand_data;
-	tc6393xb_cells[TC6393XB_CELL_FB].mfd_data = tcpd->fb_data;
+	tc6393xb_cells[TC6393XB_CELL_NAND].platform_data = tcpd->nand_data;
+	tc6393xb_cells[TC6393XB_CELL_NAND].pdata_size =
+						sizeof(*tcpd->nand_data);
+	tc6393xb_cells[TC6393XB_CELL_FB].platform_data = tcpd->fb_data;
+	tc6393xb_cells[TC6393XB_CELL_FB].pdata_size = sizeof(*tcpd->fb_data);
 
 	ret = mfd_add_devices(&dev->dev, dev->id,
 			tc6393xb_cells, ARRAY_SIZE(tc6393xb_cells),
diff -druN linux-2.6.39-libre/drivers/mfd/timberdale.c linux-3.0-rc7-libre/drivers/mfd/timberdale.c
--- linux-2.6.39-libre/drivers/mfd/timberdale.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mfd/timberdale.c	2011-07-11 19:51:52.000000000 -0400
@@ -384,7 +384,8 @@
 		.name = "timb-dma",
 		.num_resources = ARRAY_SIZE(timberdale_dma_resources),
 		.resources = timberdale_dma_resources,
-		.mfd_data = &timb_dma_platform_data,
+		.platform_data = &timb_dma_platform_data,
+		.pdata_size = sizeof(timb_dma_platform_data),
 	},
 	{
 		.name = "timb-uart",
@@ -395,37 +396,43 @@
 		.name = "xiic-i2c",
 		.num_resources = ARRAY_SIZE(timberdale_xiic_resources),
 		.resources = timberdale_xiic_resources,
-		.mfd_data = &timberdale_xiic_platform_data,
+		.platform_data = &timberdale_xiic_platform_data,
+		.pdata_size = sizeof(timberdale_xiic_platform_data),
 	},
 	{
 		.name = "timb-gpio",
 		.num_resources = ARRAY_SIZE(timberdale_gpio_resources),
 		.resources = timberdale_gpio_resources,
-		.mfd_data = &timberdale_gpio_platform_data,
+		.platform_data = &timberdale_gpio_platform_data,
+		.pdata_size = sizeof(timberdale_gpio_platform_data),
 	},
 	{
 		.name = "timb-video",
 		.num_resources = ARRAY_SIZE(timberdale_video_resources),
 		.resources = timberdale_video_resources,
-		.mfd_data = &timberdale_video_platform_data,
+		.platform_data = &timberdale_video_platform_data,
+		.pdata_size = sizeof(timberdale_video_platform_data),
 	},
 	{
 		.name = "timb-radio",
 		.num_resources = ARRAY_SIZE(timberdale_radio_resources),
 		.resources = timberdale_radio_resources,
-		.mfd_data = &timberdale_radio_platform_data,
+		.platform_data = &timberdale_radio_platform_data,
+		.pdata_size = sizeof(timberdale_radio_platform_data),
 	},
 	{
 		.name = "xilinx_spi",
 		.num_resources = ARRAY_SIZE(timberdale_spi_resources),
 		.resources = timberdale_spi_resources,
-		.mfd_data = &timberdale_xspi_platform_data,
+		.platform_data = &timberdale_xspi_platform_data,
+		.pdata_size = sizeof(timberdale_xspi_platform_data),
 	},
 	{
 		.name = "ks8842",
 		.num_resources = ARRAY_SIZE(timberdale_eth_resources),
 		.resources = timberdale_eth_resources,
-		.mfd_data = &timberdale_ks8842_platform_data,
+		.platform_data = &timberdale_ks8842_platform_data,
+		.pdata_size = sizeof(timberdale_ks8842_platform_data),
 	},
 };
 
@@ -434,7 +441,8 @@
 		.name = "timb-dma",
 		.num_resources = ARRAY_SIZE(timberdale_dma_resources),
 		.resources = timberdale_dma_resources,
-		.mfd_data = &timb_dma_platform_data,
+		.platform_data = &timb_dma_platform_data,
+		.pdata_size = sizeof(timb_dma_platform_data),
 	},
 	{
 		.name = "timb-uart",
@@ -450,13 +458,15 @@
 		.name = "xiic-i2c",
 		.num_resources = ARRAY_SIZE(timberdale_xiic_resources),
 		.resources = timberdale_xiic_resources,
-		.mfd_data = &timberdale_xiic_platform_data,
+		.platform_data = &timberdale_xiic_platform_data,
+		.pdata_size = sizeof(timberdale_xiic_platform_data),
 	},
 	{
 		.name = "timb-gpio",
 		.num_resources = ARRAY_SIZE(timberdale_gpio_resources),
 		.resources = timberdale_gpio_resources,
-		.mfd_data = &timberdale_gpio_platform_data,
+		.platform_data = &timberdale_gpio_platform_data,
+		.pdata_size = sizeof(timberdale_gpio_platform_data),
 	},
 	{
 		.name = "timb-mlogicore",
@@ -467,25 +477,29 @@
 		.name = "timb-video",
 		.num_resources = ARRAY_SIZE(timberdale_video_resources),
 		.resources = timberdale_video_resources,
-		.mfd_data = &timberdale_video_platform_data,
+		.platform_data = &timberdale_video_platform_data,
+		.pdata_size = sizeof(timberdale_video_platform_data),
 	},
 	{
 		.name = "timb-radio",
 		.num_resources = ARRAY_SIZE(timberdale_radio_resources),
 		.resources = timberdale_radio_resources,
-		.mfd_data = &timberdale_radio_platform_data,
+		.platform_data = &timberdale_radio_platform_data,
+		.pdata_size = sizeof(timberdale_radio_platform_data),
 	},
 	{
 		.name = "xilinx_spi",
 		.num_resources = ARRAY_SIZE(timberdale_spi_resources),
 		.resources = timberdale_spi_resources,
-		.mfd_data = &timberdale_xspi_platform_data,
+		.platform_data = &timberdale_xspi_platform_data,
+		.pdata_size = sizeof(timberdale_xspi_platform_data),
 	},
 	{
 		.name = "ks8842",
 		.num_resources = ARRAY_SIZE(timberdale_eth_resources),
 		.resources = timberdale_eth_resources,
-		.mfd_data = &timberdale_ks8842_platform_data,
+		.platform_data = &timberdale_ks8842_platform_data,
+		.pdata_size = sizeof(timberdale_ks8842_platform_data),
 	},
 };
 
@@ -494,7 +508,8 @@
 		.name = "timb-dma",
 		.num_resources = ARRAY_SIZE(timberdale_dma_resources),
 		.resources = timberdale_dma_resources,
-		.mfd_data = &timb_dma_platform_data,
+		.platform_data = &timb_dma_platform_data,
+		.pdata_size = sizeof(timb_dma_platform_data),
 	},
 	{
 		.name = "timb-uart",
@@ -505,31 +520,36 @@
 		.name = "xiic-i2c",
 		.num_resources = ARRAY_SIZE(timberdale_xiic_resources),
 		.resources = timberdale_xiic_resources,
-		.mfd_data = &timberdale_xiic_platform_data,
+		.platform_data = &timberdale_xiic_platform_data,
+		.pdata_size = sizeof(timberdale_xiic_platform_data),
 	},
 	{
 		.name = "timb-gpio",
 		.num_resources = ARRAY_SIZE(timberdale_gpio_resources),
 		.resources = timberdale_gpio_resources,
-		.mfd_data = &timberdale_gpio_platform_data,
+		.platform_data = &timberdale_gpio_platform_data,
+		.pdata_size = sizeof(timberdale_gpio_platform_data),
 	},
 	{
 		.name = "timb-video",
 		.num_resources = ARRAY_SIZE(timberdale_video_resources),
 		.resources = timberdale_video_resources,
-		.mfd_data = &timberdale_video_platform_data,
+		.platform_data = &timberdale_video_platform_data,
+		.pdata_size = sizeof(timberdale_video_platform_data),
 	},
 	{
 		.name = "timb-radio",
 		.num_resources = ARRAY_SIZE(timberdale_radio_resources),
 		.resources = timberdale_radio_resources,
-		.mfd_data = &timberdale_radio_platform_data,
+		.platform_data = &timberdale_radio_platform_data,
+		.pdata_size = sizeof(timberdale_radio_platform_data),
 	},
 	{
 		.name = "xilinx_spi",
 		.num_resources = ARRAY_SIZE(timberdale_spi_resources),
 		.resources = timberdale_spi_resources,
-		.mfd_data = &timberdale_xspi_platform_data,
+		.platform_data = &timberdale_xspi_platform_data,
+		.pdata_size = sizeof(timberdale_xspi_platform_data),
 	},
 };
 
@@ -538,7 +558,8 @@
 		.name = "timb-dma",
 		.num_resources = ARRAY_SIZE(timberdale_dma_resources),
 		.resources = timberdale_dma_resources,
-		.mfd_data = &timb_dma_platform_data,
+		.platform_data = &timb_dma_platform_data,
+		.pdata_size = sizeof(timb_dma_platform_data),
 	},
 	{
 		.name = "timb-uart",
@@ -549,37 +570,43 @@
 		.name = "ocores-i2c",
 		.num_resources = ARRAY_SIZE(timberdale_ocores_resources),
 		.resources = timberdale_ocores_resources,
-		.mfd_data = &timberdale_ocores_platform_data,
+		.platform_data = &timberdale_ocores_platform_data,
+		.pdata_size = sizeof(timberdale_ocores_platform_data),
 	},
 	{
 		.name = "timb-gpio",
 		.num_resources = ARRAY_SIZE(timberdale_gpio_resources),
 		.resources = timberdale_gpio_resources,
-		.mfd_data = &timberdale_gpio_platform_data,
+		.platform_data = &timberdale_gpio_platform_data,
+		.pdata_size = sizeof(timberdale_gpio_platform_data),
 	},
 	{
 		.name = "timb-video",
 		.num_resources = ARRAY_SIZE(timberdale_video_resources),
 		.resources = timberdale_video_resources,
-		.mfd_data = &timberdale_video_platform_data,
+		.platform_data = &timberdale_video_platform_data,
+		.pdata_size = sizeof(timberdale_video_platform_data),
 	},
 	{
 		.name = "timb-radio",
 		.num_resources = ARRAY_SIZE(timberdale_radio_resources),
 		.resources = timberdale_radio_resources,
-		.mfd_data = &timberdale_radio_platform_data,
+		.platform_data = &timberdale_radio_platform_data,
+		.pdata_size = sizeof(timberdale_radio_platform_data),
 	},
 	{
 		.name = "xilinx_spi",
 		.num_resources = ARRAY_SIZE(timberdale_spi_resources),
 		.resources = timberdale_spi_resources,
-		.mfd_data = &timberdale_xspi_platform_data,
+		.platform_data = &timberdale_xspi_platform_data,
+		.pdata_size = sizeof(timberdale_xspi_platform_data),
 	},
 	{
 		.name = "ks8842",
 		.num_resources = ARRAY_SIZE(timberdale_eth_resources),
 		.resources = timberdale_eth_resources,
-		.mfd_data = &timberdale_ks8842_platform_data,
+		.platform_data = &timberdale_ks8842_platform_data,
+		.pdata_size = sizeof(timberdale_ks8842_platform_data),
 	},
 };
 
diff -druN linux-2.6.39-libre/drivers/mfd/tps6105x.c linux-3.0-rc7-libre/drivers/mfd/tps6105x.c
--- linux-2.6.39-libre/drivers/mfd/tps6105x.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mfd/tps6105x.c	2011-07-11 19:51:52.000000000 -0400
@@ -183,7 +183,8 @@
 	/* Set up and register the platform devices. */
 	for (i = 0; i < ARRAY_SIZE(tps6105x_cells); i++) {
 		/* One state holder for all drivers, this is simple */
-		tps6105x_cells[i].mfd_data = tps6105x;
+		tps6105x_cells[i].platform_data = tps6105x;
+		tps6105x_cells[i].pdata_size = sizeof(*tps6105x);
 	}
 
 	ret = mfd_add_devices(&client->dev, 0, tps6105x_cells,
diff -druN linux-2.6.39-libre/drivers/mfd/tps6586x.c linux-3.0-rc7-libre/drivers/mfd/tps6586x.c
--- linux-2.6.39-libre/drivers/mfd/tps6586x.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mfd/tps6586x.c	2011-07-11 19:51:52.000000000 -0400
@@ -270,8 +270,8 @@
 {
 	struct tps6586x *tps6586x = container_of(chip, struct tps6586x, gpio);
 
-	__tps6586x_write(tps6586x->client, TPS6586X_GPIOSET2,
-			 value << offset);
+	tps6586x_update(tps6586x->dev, TPS6586X_GPIOSET2,
+			value << offset, 1 << offset);
 }
 
 static int tps6586x_gpio_output(struct gpio_chip *gc, unsigned offset,
diff -druN linux-2.6.39-libre/drivers/mfd/tps65910.c linux-3.0-rc7-libre/drivers/mfd/tps65910.c
--- linux-2.6.39-libre/drivers/mfd/tps65910.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/mfd/tps65910.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,229 @@
+/*
+ * tps65910.c  --  TI TPS6591x
+ *
+ * Copyright 2010 Texas Instruments Inc.
+ *
+ * Author: Graeme Gregory <gg@slimlogic.co.uk>
+ * Author: Jorge Eduardo Candelaria <jedu@slimlogic.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.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/i2c.h>
+#include <linux/gpio.h>
+#include <linux/mfd/core.h>
+#include <linux/mfd/tps65910.h>
+
+static struct mfd_cell tps65910s[] = {
+	{
+		.name = "tps65910-pmic",
+	},
+	{
+		.name = "tps65910-rtc",
+	},
+	{
+		.name = "tps65910-power",
+	},
+};
+
+
+static int tps65910_i2c_read(struct tps65910 *tps65910, u8 reg,
+				  int bytes, void *dest)
+{
+	struct i2c_client *i2c = tps65910->i2c_client;
+	struct i2c_msg xfer[2];
+	int ret;
+
+	/* Write register */
+	xfer[0].addr = i2c->addr;
+	xfer[0].flags = 0;
+	xfer[0].len = 1;
+	xfer[0].buf = &reg;
+
+	/* Read data */
+	xfer[1].addr = i2c->addr;
+	xfer[1].flags = I2C_M_RD;
+	xfer[1].len = bytes;
+	xfer[1].buf = dest;
+
+	ret = i2c_transfer(i2c->adapter, xfer, 2);
+	if (ret == 2)
+		ret = 0;
+	else if (ret >= 0)
+		ret = -EIO;
+
+	return ret;
+}
+
+static int tps65910_i2c_write(struct tps65910 *tps65910, u8 reg,
+				   int bytes, void *src)
+{
+	struct i2c_client *i2c = tps65910->i2c_client;
+	/* we add 1 byte for device register */
+	u8 msg[TPS65910_MAX_REGISTER + 1];
+	int ret;
+
+	if (bytes > TPS65910_MAX_REGISTER)
+		return -EINVAL;
+
+	msg[0] = reg;
+	memcpy(&msg[1], src, bytes);
+
+	ret = i2c_master_send(i2c, msg, bytes + 1);
+	if (ret < 0)
+		return ret;
+	if (ret != bytes + 1)
+		return -EIO;
+	return 0;
+}
+
+int tps65910_set_bits(struct tps65910 *tps65910, u8 reg, u8 mask)
+{
+	u8 data;
+	int err;
+
+	mutex_lock(&tps65910->io_mutex);
+	err = tps65910_i2c_read(tps65910, reg, 1, &data);
+	if (err) {
+		dev_err(tps65910->dev, "read from reg %x failed\n", reg);
+		goto out;
+	}
+
+	data |= mask;
+	err = tps65910_i2c_write(tps65910, reg, 1, &data);
+	if (err)
+		dev_err(tps65910->dev, "write to reg %x failed\n", reg);
+
+out:
+	mutex_unlock(&tps65910->io_mutex);
+	return err;
+}
+EXPORT_SYMBOL_GPL(tps65910_set_bits);
+
+int tps65910_clear_bits(struct tps65910 *tps65910, u8 reg, u8 mask)
+{
+	u8 data;
+	int err;
+
+	mutex_lock(&tps65910->io_mutex);
+	err = tps65910_i2c_read(tps65910, reg, 1, &data);
+	if (err) {
+		dev_err(tps65910->dev, "read from reg %x failed\n", reg);
+		goto out;
+	}
+
+	data &= mask;
+	err = tps65910_i2c_write(tps65910, reg, 1, &data);
+	if (err)
+		dev_err(tps65910->dev, "write to reg %x failed\n", reg);
+
+out:
+	mutex_unlock(&tps65910->io_mutex);
+	return err;
+}
+EXPORT_SYMBOL_GPL(tps65910_clear_bits);
+
+static int tps65910_i2c_probe(struct i2c_client *i2c,
+			    const struct i2c_device_id *id)
+{
+	struct tps65910 *tps65910;
+	struct tps65910_board *pmic_plat_data;
+	struct tps65910_platform_data *init_data;
+	int ret = 0;
+
+	pmic_plat_data = dev_get_platdata(&i2c->dev);
+	if (!pmic_plat_data)
+		return -EINVAL;
+
+	init_data = kzalloc(sizeof(struct tps65910_platform_data), GFP_KERNEL);
+	if (init_data == NULL)
+		return -ENOMEM;
+
+	init_data->irq = pmic_plat_data->irq;
+	init_data->irq_base = pmic_plat_data->irq;
+
+	tps65910 = kzalloc(sizeof(struct tps65910), GFP_KERNEL);
+	if (tps65910 == NULL)
+		return -ENOMEM;
+
+	i2c_set_clientdata(i2c, tps65910);
+	tps65910->dev = &i2c->dev;
+	tps65910->i2c_client = i2c;
+	tps65910->id = id->driver_data;
+	tps65910->read = tps65910_i2c_read;
+	tps65910->write = tps65910_i2c_write;
+	mutex_init(&tps65910->io_mutex);
+
+	ret = mfd_add_devices(tps65910->dev, -1,
+			      tps65910s, ARRAY_SIZE(tps65910s),
+			      NULL, 0);
+	if (ret < 0)
+		goto err;
+
+	tps65910_gpio_init(tps65910, pmic_plat_data->gpio_base);
+
+	ret = tps65910_irq_init(tps65910, init_data->irq, init_data);
+	if (ret < 0)
+		goto err;
+
+	return ret;
+
+err:
+	mfd_remove_devices(tps65910->dev);
+	kfree(tps65910);
+	return ret;
+}
+
+static int tps65910_i2c_remove(struct i2c_client *i2c)
+{
+	struct tps65910 *tps65910 = i2c_get_clientdata(i2c);
+
+	mfd_remove_devices(tps65910->dev);
+	kfree(tps65910);
+
+	return 0;
+}
+
+static const struct i2c_device_id tps65910_i2c_id[] = {
+       { "tps65910", TPS65910 },
+       { "tps65911", TPS65911 },
+       { }
+};
+MODULE_DEVICE_TABLE(i2c, tps65910_i2c_id);
+
+
+static struct i2c_driver tps65910_i2c_driver = {
+	.driver = {
+		   .name = "tps65910",
+		   .owner = THIS_MODULE,
+	},
+	.probe = tps65910_i2c_probe,
+	.remove = tps65910_i2c_remove,
+	.id_table = tps65910_i2c_id,
+};
+
+static int __init tps65910_i2c_init(void)
+{
+	return i2c_add_driver(&tps65910_i2c_driver);
+}
+/* init early so consumer devices can complete system boot */
+subsys_initcall(tps65910_i2c_init);
+
+static void __exit tps65910_i2c_exit(void)
+{
+	i2c_del_driver(&tps65910_i2c_driver);
+}
+module_exit(tps65910_i2c_exit);
+
+MODULE_AUTHOR("Graeme Gregory <gg@slimlogic.co.uk>");
+MODULE_AUTHOR("Jorge Eduardo Candelaria <jedu@slimlogic.co.uk>");
+MODULE_DESCRIPTION("TPS6591x chip family multi-function driver");
+MODULE_LICENSE("GPL");
diff -druN linux-2.6.39-libre/drivers/mfd/tps65910-irq.c linux-3.0-rc7-libre/drivers/mfd/tps65910-irq.c
--- linux-2.6.39-libre/drivers/mfd/tps65910-irq.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/mfd/tps65910-irq.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,218 @@
+/*
+ * tps65910-irq.c  --  TI TPS6591x
+ *
+ * Copyright 2010 Texas Instruments Inc.
+ *
+ * Author: Graeme Gregory <gg@slimlogic.co.uk>
+ * Author: Jorge Eduardo Candelaria <jedu@slimlogic.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.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/bug.h>
+#include <linux/device.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/gpio.h>
+#include <linux/mfd/tps65910.h>
+
+static inline int irq_to_tps65910_irq(struct tps65910 *tps65910,
+							int irq)
+{
+	return (irq - tps65910->irq_base);
+}
+
+/*
+ * This is a threaded IRQ handler so can access I2C/SPI.  Since all
+ * interrupts are clear on read the IRQ line will be reasserted and
+ * the physical IRQ will be handled again if another interrupt is
+ * asserted while we run - in the normal course of events this is a
+ * rare occurrence so we save I2C/SPI reads.  We're also assuming that
+ * it's rare to get lots of interrupts firing simultaneously so try to
+ * minimise I/O.
+ */
+static irqreturn_t tps65910_irq(int irq, void *irq_data)
+{
+	struct tps65910 *tps65910 = irq_data;
+	u32 irq_sts;
+	u32 irq_mask;
+	u8 reg;
+	int i;
+
+	tps65910->read(tps65910, TPS65910_INT_STS, 1, &reg);
+	irq_sts = reg;
+	tps65910->read(tps65910, TPS65910_INT_STS2, 1, &reg);
+	irq_sts |= reg << 8;
+	switch (tps65910_chip_id(tps65910)) {
+	case TPS65911:
+		tps65910->read(tps65910, TPS65910_INT_STS3, 1, &reg);
+		irq_sts |= reg << 16;
+	}
+
+	tps65910->read(tps65910, TPS65910_INT_MSK, 1, &reg);
+	irq_mask = reg;
+	tps65910->read(tps65910, TPS65910_INT_MSK2, 1, &reg);
+	irq_mask |= reg << 8;
+	switch (tps65910_chip_id(tps65910)) {
+	case TPS65911:
+		tps65910->read(tps65910, TPS65910_INT_MSK3, 1, &reg);
+		irq_mask |= reg << 16;
+	}
+
+	irq_sts &= ~irq_mask;
+
+	if (!irq_sts)
+		return IRQ_NONE;
+
+	for (i = 0; i < tps65910->irq_num; i++) {
+
+		if (!(irq_sts & (1 << i)))
+			continue;
+
+		handle_nested_irq(tps65910->irq_base + i);
+	}
+
+	/* Write the STS register back to clear IRQs we handled */
+	reg = irq_sts & 0xFF;
+	irq_sts >>= 8;
+	tps65910->write(tps65910, TPS65910_INT_STS, 1, &reg);
+	reg = irq_sts & 0xFF;
+	tps65910->write(tps65910, TPS65910_INT_STS2, 1, &reg);
+	switch (tps65910_chip_id(tps65910)) {
+	case TPS65911:
+		reg = irq_sts >> 8;
+		tps65910->write(tps65910, TPS65910_INT_STS3, 1, &reg);
+	}
+
+	return IRQ_HANDLED;
+}
+
+static void tps65910_irq_lock(struct irq_data *data)
+{
+	struct tps65910 *tps65910 = irq_data_get_irq_chip_data(data);
+
+	mutex_lock(&tps65910->irq_lock);
+}
+
+static void tps65910_irq_sync_unlock(struct irq_data *data)
+{
+	struct tps65910 *tps65910 = irq_data_get_irq_chip_data(data);
+	u32 reg_mask;
+	u8 reg;
+
+	tps65910->read(tps65910, TPS65910_INT_MSK, 1, &reg);
+	reg_mask = reg;
+	tps65910->read(tps65910, TPS65910_INT_MSK2, 1, &reg);
+	reg_mask |= reg << 8;
+	switch (tps65910_chip_id(tps65910)) {
+	case TPS65911:
+		tps65910->read(tps65910, TPS65910_INT_MSK3, 1, &reg);
+		reg_mask |= reg << 16;
+	}
+
+	if (tps65910->irq_mask != reg_mask) {
+		reg = tps65910->irq_mask & 0xFF;
+		tps65910->write(tps65910, TPS65910_INT_MSK, 1, &reg);
+		reg = tps65910->irq_mask >> 8 & 0xFF;
+		tps65910->write(tps65910, TPS65910_INT_MSK2, 1, &reg);
+		switch (tps65910_chip_id(tps65910)) {
+		case TPS65911:
+			reg = tps65910->irq_mask >> 16;
+			tps65910->write(tps65910, TPS65910_INT_MSK3, 1, &reg);
+		}
+	}
+	mutex_unlock(&tps65910->irq_lock);
+}
+
+static void tps65910_irq_enable(struct irq_data *data)
+{
+	struct tps65910 *tps65910 = irq_data_get_irq_chip_data(data);
+
+	tps65910->irq_mask &= ~( 1 << irq_to_tps65910_irq(tps65910, data->irq));
+}
+
+static void tps65910_irq_disable(struct irq_data *data)
+{
+	struct tps65910 *tps65910 = irq_data_get_irq_chip_data(data);
+
+	tps65910->irq_mask |= ( 1 << irq_to_tps65910_irq(tps65910, data->irq));
+}
+
+static struct irq_chip tps65910_irq_chip = {
+	.name = "tps65910",
+	.irq_bus_lock = tps65910_irq_lock,
+	.irq_bus_sync_unlock = tps65910_irq_sync_unlock,
+	.irq_disable = tps65910_irq_disable,
+	.irq_enable = tps65910_irq_enable,
+};
+
+int tps65910_irq_init(struct tps65910 *tps65910, int irq,
+		    struct tps65910_platform_data *pdata)
+{
+	int ret, cur_irq;
+	int flags = IRQF_ONESHOT;
+
+	if (!irq) {
+		dev_warn(tps65910->dev, "No interrupt support, no core IRQ\n");
+		return -EINVAL;
+	}
+
+	if (!pdata || !pdata->irq_base) {
+		dev_warn(tps65910->dev, "No interrupt support, no IRQ base\n");
+		return -EINVAL;
+	}
+
+	tps65910->irq_mask = 0xFFFFFF;
+
+	mutex_init(&tps65910->irq_lock);
+	tps65910->chip_irq = irq;
+	tps65910->irq_base = pdata->irq_base;
+
+	switch (tps65910_chip_id(tps65910)) {
+	case TPS65910:
+		tps65910->irq_num = TPS65910_NUM_IRQ;
+	case TPS65911:
+		tps65910->irq_num = TPS65911_NUM_IRQ;
+	}
+
+	/* Register with genirq */
+	for (cur_irq = tps65910->irq_base;
+	     cur_irq < tps65910->irq_num + tps65910->irq_base;
+	     cur_irq++) {
+		irq_set_chip_data(cur_irq, tps65910);
+		irq_set_chip_and_handler(cur_irq, &tps65910_irq_chip,
+					 handle_edge_irq);
+		irq_set_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
+		irq_set_noprobe(cur_irq);
+#endif
+	}
+
+	ret = request_threaded_irq(irq, NULL, tps65910_irq, flags,
+				   "tps65910", tps65910);
+
+	irq_set_irq_type(irq, IRQ_TYPE_LEVEL_LOW);
+
+	if (ret != 0)
+		dev_err(tps65910->dev, "Failed to request IRQ: %d\n", ret);
+
+	return ret;
+}
+
+int tps65910_irq_exit(struct tps65910 *tps65910)
+{
+	free_irq(tps65910->chip_irq, tps65910);
+	return 0;
+}
diff -druN linux-2.6.39-libre/drivers/mfd/tps65911-comparator.c linux-3.0-rc7-libre/drivers/mfd/tps65911-comparator.c
--- linux-2.6.39-libre/drivers/mfd/tps65911-comparator.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/mfd/tps65911-comparator.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,188 @@
+/*
+ * tps65910.c  --  TI TPS6591x
+ *
+ * Copyright 2010 Texas Instruments Inc.
+ *
+ * Author: Jorge Eduardo Candelaria <jedu@slimlogic.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.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/err.h>
+#include <linux/platform_device.h>
+#include <linux/debugfs.h>
+#include <linux/gpio.h>
+#include <linux/mfd/tps65910.h>
+
+#define COMP					0
+#define COMP1					1
+#define COMP2					2
+
+/* Comparator 1 voltage selection table in milivolts */
+static const u16 COMP_VSEL_TABLE[] = {
+	0, 2500, 2500, 2500, 2500, 2550, 2600, 2650,
+	2700, 2750, 2800, 2850, 2900, 2950, 3000, 3050,
+	3100, 3150, 3200, 3250, 3300, 3350, 3400, 3450,
+	3500,
+};
+
+struct comparator {
+	const char *name;
+	int reg;
+	int uV_max;
+	const u16 *vsel_table;
+};
+
+static struct comparator tps_comparators[] = {
+	{
+		.name = "COMP1",
+		.reg = TPS65911_VMBCH,
+		.uV_max = 3500,
+		.vsel_table = COMP_VSEL_TABLE,
+	},
+	{
+		.name = "COMP2",
+		.reg = TPS65911_VMBCH2,
+		.uV_max = 3500,
+		.vsel_table = COMP_VSEL_TABLE,
+	},
+};
+
+static int comp_threshold_set(struct tps65910 *tps65910, int id, int voltage)
+{
+	struct comparator tps_comp = tps_comparators[id];
+	int curr_voltage = 0;
+	int ret;
+	u8 index = 0, val;
+
+	if (id == COMP)
+		return 0;
+
+	while (curr_voltage < tps_comp.uV_max) {
+		curr_voltage = tps_comp.vsel_table[index];
+		if (curr_voltage >= voltage)
+			break;
+		else if (curr_voltage < voltage)
+			index ++;
+	}
+
+	if (curr_voltage > tps_comp.uV_max)
+		return -EINVAL;
+
+	val = index << 1;
+	ret = tps65910->write(tps65910, tps_comp.reg, 1, &val);
+
+	return ret;
+}
+
+static int comp_threshold_get(struct tps65910 *tps65910, int id)
+{
+	struct comparator tps_comp = tps_comparators[id];
+	int ret;
+	u8 val;
+
+	if (id == COMP)
+		return 0;
+
+	ret = tps65910->read(tps65910, tps_comp.reg, 1, &val);
+	if (ret < 0)
+		return ret;
+
+	val >>= 1;
+	return tps_comp.vsel_table[val];
+}
+
+static ssize_t comp_threshold_show(struct device *dev,
+				struct device_attribute *attr, char *buf)
+{
+	struct tps65910 *tps65910 = dev_get_drvdata(dev->parent);
+	struct attribute comp_attr = attr->attr;
+	int id, uVolt;
+
+	if (!strcmp(comp_attr.name, "comp1_threshold"))
+		id = COMP1;
+	else if (!strcmp(comp_attr.name, "comp2_threshold"))
+		id = COMP2;
+	else
+		return -EINVAL;
+
+	uVolt = comp_threshold_get(tps65910, id);
+
+	return sprintf(buf, "%d\n", uVolt);
+}
+
+static DEVICE_ATTR(comp1_threshold, S_IRUGO, comp_threshold_show, NULL);
+static DEVICE_ATTR(comp2_threshold, S_IRUGO, comp_threshold_show, NULL);
+
+static __devinit int tps65911_comparator_probe(struct platform_device *pdev)
+{
+	struct tps65910 *tps65910 = dev_get_drvdata(pdev->dev.parent);
+	struct tps65910_board *pdata = dev_get_platdata(tps65910->dev);
+	int ret;
+
+	ret = comp_threshold_set(tps65910, COMP1,  pdata->vmbch_threshold);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "cannot set COMP1 threshold\n");
+		return ret;
+	}
+
+	ret = comp_threshold_set(tps65910, COMP2, pdata->vmbch2_threshold);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "cannot set COMP2 theshold\n");
+		return ret;
+	}
+
+	/* Create sysfs entry */
+	ret = device_create_file(&pdev->dev, &dev_attr_comp1_threshold);
+	if (ret < 0)
+		dev_err(&pdev->dev, "failed to add COMP1 sysfs file\n");
+
+	ret = device_create_file(&pdev->dev, &dev_attr_comp2_threshold);
+	if (ret < 0)
+		dev_err(&pdev->dev, "failed to add COMP2 sysfs file\n");
+
+	return ret;
+}
+
+static __devexit int tps65911_comparator_remove(struct platform_device *pdev)
+{
+	struct tps65910 *tps65910;
+
+	tps65910 = dev_get_drvdata(pdev->dev.parent);
+
+	return 0;
+}
+
+static struct platform_driver tps65911_comparator_driver = {
+	.driver = {
+		.name = "tps65911-comparator",
+		.owner = THIS_MODULE,
+	},
+	.probe = tps65911_comparator_probe,
+	.remove = __devexit_p(tps65911_comparator_remove),
+};
+
+static int __init tps65911_comparator_init(void)
+{
+	return platform_driver_register(&tps65911_comparator_driver);
+}
+subsys_initcall(tps65911_comparator_init);
+
+static void __exit tps65911_comparator_exit(void)
+{
+	platform_driver_unregister(&tps65911_comparator_driver);
+}
+module_exit(tps65911_comparator_exit);
+
+MODULE_AUTHOR("Jorge Eduardo Candelaria <jedu@slimlogic.co.uk>");
+MODULE_DESCRIPTION("TPS65911 comparator driver");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:tps65911-comparator");
diff -druN linux-2.6.39-libre/drivers/mfd/twl4030-codec.c linux-3.0-rc7-libre/drivers/mfd/twl4030-codec.c
--- linux-2.6.39-libre/drivers/mfd/twl4030-codec.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mfd/twl4030-codec.c	2011-07-11 19:51:52.000000000 -0400
@@ -1,7 +1,7 @@
 /*
  * MFD driver for twl4030 codec submodule
  *
- * Author:	Peter Ujfalusi <peter.ujfalusi@nokia.com>
+ * Author: Peter Ujfalusi <peter.ujfalusi@ti.com>
  *
  * Copyright:   (C) 2009 Nokia Corporation
  *
@@ -208,13 +208,15 @@
 	if (pdata->audio) {
 		cell = &codec->cells[childs];
 		cell->name = "twl4030-codec";
-		cell->mfd_data = pdata->audio;
+		cell->platform_data = pdata->audio;
+		cell->pdata_size = sizeof(*pdata->audio);
 		childs++;
 	}
 	if (pdata->vibra) {
 		cell = &codec->cells[childs];
 		cell->name = "twl4030-vibra";
-		cell->mfd_data = pdata->vibra;
+		cell->platform_data = pdata->vibra;
+		cell->pdata_size = sizeof(*pdata->vibra);
 		childs++;
 	}
 
@@ -270,6 +272,6 @@
 }
 module_exit(twl4030_codec_exit);
 
-MODULE_AUTHOR("Peter Ujfalusi <peter.ujfalusi@nokia.com>");
+MODULE_AUTHOR("Peter Ujfalusi <peter.ujfalusi@ti.com>");
 MODULE_LICENSE("GPL");
 
diff -druN linux-2.6.39-libre/drivers/mfd/twl4030-power.c linux-3.0-rc7-libre/drivers/mfd/twl4030-power.c
--- linux-2.6.39-libre/drivers/mfd/twl4030-power.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mfd/twl4030-power.c	2011-07-11 19:51:52.000000000 -0400
@@ -120,7 +120,7 @@
 	[RES_HFCLKOUT]	= 0x8b,
 	[RES_32KCLKOUT]	= 0x8e,
 	[RES_RESET]	= 0x91,
-	[RES_Main_Ref]	= 0x94,
+	[RES_MAIN_REF]	= 0x94,
 };
 
 static int __init twl4030_write_script_byte(u8 address, u8 byte)
@@ -448,7 +448,7 @@
 			goto out;
 	}
 	if (tscript->flags & TWL4030_SLEEP_SCRIPT) {
-		if (order)
+		if (!order)
 			pr_warning("TWL4030: Bad order of scripts (sleep "\
 					"script before wakeup) Leads to boot"\
 					"failure on some boards\n");
@@ -485,9 +485,9 @@
 			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);
+		if (err)
 			return err;
 	}
 	if (flags & TWL4030_WAKEUP3_SCRIPT) {
diff -druN linux-2.6.39-libre/drivers/mfd/twl6030-irq.c linux-3.0-rc7-libre/drivers/mfd/twl6030-irq.c
--- linux-2.6.39-libre/drivers/mfd/twl6030-irq.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mfd/twl6030-irq.c	2011-07-11 19:51:52.000000000 -0400
@@ -76,8 +76,8 @@
 	USBOTG_INTR_OFFSET,	/* Bit 18	ID			*/
 	USB_PRES_INTR_OFFSET,	/* Bit 19	VBUS			*/
 	CHARGER_INTR_OFFSET,	/* Bit 20	CHRG_CTRL		*/
-	CHARGER_INTR_OFFSET,	/* Bit 21	EXT_CHRG		*/
-	CHARGER_INTR_OFFSET,	/* Bit 22	INT_CHRG		*/
+	CHARGERFAULT_INTR_OFFSET,	/* Bit 21	EXT_CHRG	*/
+	CHARGERFAULT_INTR_OFFSET,	/* Bit 22	INT_CHRG	*/
 	RSV_INTR_OFFSET,	/* Bit 23	Reserved		*/
 };
 /*----------------------------------------------------------------------*/
diff -druN linux-2.6.39-libre/drivers/mfd/twl-core.c linux-3.0-rc7-libre/drivers/mfd/twl-core.c
--- linux-2.6.39-libre/drivers/mfd/twl-core.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mfd/twl-core.c	2011-07-11 19:51:52.000000000 -0400
@@ -198,6 +198,7 @@
 #define TWL6030_BASEADD_GASGAUGE	0x00C0
 #define TWL6030_BASEADD_PIH		0x00D0
 #define TWL6030_BASEADD_CHARGER		0x00E0
+#define TWL6025_BASEADD_CHARGER		0x00DA
 
 /* subchip/slave 2 0x4A - DFT */
 #define TWL6030_BASEADD_DIEID		0x00C0
@@ -229,6 +230,9 @@
 /* is driver active, bound to a chip? */
 static bool inuse;
 
+/* TWL IDCODE Register value */
+static u32 twl_idcode;
+
 static unsigned int twl_id;
 unsigned int twl_rev(void)
 {
@@ -328,6 +332,7 @@
 
 	{ SUB_CHIP_ID0, TWL6030_BASEADD_RTC },
 	{ SUB_CHIP_ID0, TWL6030_BASEADD_MEM },
+	{ SUB_CHIP_ID1, TWL6025_BASEADD_CHARGER },
 };
 
 /*----------------------------------------------------------------------*/
@@ -487,6 +492,58 @@
 
 /*----------------------------------------------------------------------*/
 
+/**
+ * twl_read_idcode_register - API to read the IDCODE register.
+ *
+ * Unlocks the IDCODE register and read the 32 bit value.
+ */
+static int twl_read_idcode_register(void)
+{
+	int err;
+
+	err = twl_i2c_write_u8(TWL4030_MODULE_INTBR, TWL_EEPROM_R_UNLOCK,
+						REG_UNLOCK_TEST_REG);
+	if (err) {
+		pr_err("TWL4030 Unable to unlock IDCODE registers -%d\n", err);
+		goto fail;
+	}
+
+	err = twl_i2c_read(TWL4030_MODULE_INTBR, (u8 *)(&twl_idcode),
+						REG_IDCODE_7_0, 4);
+	if (err) {
+		pr_err("TWL4030: unable to read IDCODE -%d\n", err);
+		goto fail;
+	}
+
+	err = twl_i2c_write_u8(TWL4030_MODULE_INTBR, 0x0, REG_UNLOCK_TEST_REG);
+	if (err)
+		pr_err("TWL4030 Unable to relock IDCODE registers -%d\n", err);
+fail:
+	return err;
+}
+
+/**
+ * twl_get_type - API to get TWL Si type.
+ *
+ * Api to get the TWL Si type from IDCODE value.
+ */
+int twl_get_type(void)
+{
+	return TWL_SIL_TYPE(twl_idcode);
+}
+EXPORT_SYMBOL_GPL(twl_get_type);
+
+/**
+ * twl_get_version - API to get TWL Si version.
+ *
+ * Api to get the TWL Si version from IDCODE value.
+ */
+int twl_get_version(void)
+{
+	return TWL_SIL_REV(twl_idcode);
+}
+EXPORT_SYMBOL_GPL(twl_get_version);
+
 static struct device *
 add_numbered_child(unsigned chip, const char *name, int num,
 		void *pdata, unsigned pdata_len,
@@ -549,7 +606,7 @@
 static struct device *
 add_regulator_linked(int num, struct regulator_init_data *pdata,
 		struct regulator_consumer_supply *consumers,
-		unsigned num_consumers)
+		unsigned num_consumers, unsigned long features)
 {
 	unsigned sub_chip_id;
 	/* regulator framework demands init_data ... */
@@ -561,6 +618,8 @@
 		pdata->num_consumer_supplies = num_consumers;
 	}
 
+	pdata->driver_data = (void *)features;
+
 	/* NOTE:  we currently ignore regulator IRQs, e.g. for short circuits */
 	sub_chip_id = twl_map[TWL_MODULE_PM_MASTER].sid;
 	return add_numbered_child(sub_chip_id, "twl_reg", num,
@@ -568,9 +627,10 @@
 }
 
 static struct device *
-add_regulator(int num, struct regulator_init_data *pdata)
+add_regulator(int num, struct regulator_init_data *pdata,
+		unsigned long features)
 {
-	return add_regulator_linked(num, pdata, NULL, 0);
+	return add_regulator_linked(num, pdata, NULL, 0, features);
 }
 
 /*
@@ -650,17 +710,20 @@
 			};
 
 			child = add_regulator_linked(TWL4030_REG_VUSB1V5,
-						      &usb_fixed, &usb1v5, 1);
+						      &usb_fixed, &usb1v5, 1,
+						      features);
 			if (IS_ERR(child))
 				return PTR_ERR(child);
 
 			child = add_regulator_linked(TWL4030_REG_VUSB1V8,
-						      &usb_fixed, &usb1v8, 1);
+						      &usb_fixed, &usb1v8, 1,
+						      features);
 			if (IS_ERR(child))
 				return PTR_ERR(child);
 
 			child = add_regulator_linked(TWL4030_REG_VUSB3V1,
-						      &usb_fixed, &usb3v1, 1);
+						      &usb_fixed, &usb3v1, 1,
+						      features);
 			if (IS_ERR(child))
 				return PTR_ERR(child);
 
@@ -685,9 +748,8 @@
 	}
 	if (twl_has_usb() && pdata->usb && twl_class_is_6030()) {
 
-		static struct regulator_consumer_supply usb3v3 = {
-			.supply =	"vusb",
-		};
+		static struct regulator_consumer_supply usb3v3;
+		int regulator;
 
 		if (twl_has_regulator()) {
 			/* this is a template that gets copied */
@@ -700,12 +762,22 @@
 					| REGULATOR_CHANGE_STATUS,
 			};
 
-			child = add_regulator_linked(TWL6030_REG_VUSB,
-						      &usb_fixed, &usb3v3, 1);
+			if (features & TWL6025_SUBCLASS) {
+				usb3v3.supply =	"ldousb";
+				regulator = TWL6025_REG_LDOUSB;
+			} else {
+				usb3v3.supply = "vusb";
+				regulator = TWL6030_REG_VUSB;
+			}
+			child = add_regulator_linked(regulator, &usb_fixed,
+							&usb3v3, 1,
+							features);
 			if (IS_ERR(child))
 				return PTR_ERR(child);
 		}
 
+		pdata->usb->features = features;
+
 		child = add_child(0, "twl6030_usb",
 			pdata->usb, sizeof(*pdata->usb),
 			true,
@@ -718,7 +790,16 @@
 		/* we need to connect regulators to this transceiver */
 		if (twl_has_regulator() && child)
 			usb3v3.dev = child;
+	} else if (twl_has_regulator() && twl_class_is_6030()) {
+		if (features & TWL6025_SUBCLASS)
+			child = add_regulator(TWL6025_REG_LDOUSB,
+						pdata->ldousb, features);
+		else
+			child = add_regulator(TWL6030_REG_VUSB,
+						pdata->vusb, features);
 
+			if (IS_ERR(child))
+					return PTR_ERR(child);
 	}
 
 	if (twl_has_watchdog() && twl_class_is_4030()) {
@@ -755,46 +836,55 @@
 
 	/* twl4030 regulators */
 	if (twl_has_regulator() && twl_class_is_4030()) {
-		child = add_regulator(TWL4030_REG_VPLL1, pdata->vpll1);
+		child = add_regulator(TWL4030_REG_VPLL1, pdata->vpll1,
+					features);
 		if (IS_ERR(child))
 			return PTR_ERR(child);
 
-		child = add_regulator(TWL4030_REG_VIO, pdata->vio);
+		child = add_regulator(TWL4030_REG_VIO, pdata->vio,
+					features);
 		if (IS_ERR(child))
 			return PTR_ERR(child);
 
-		child = add_regulator(TWL4030_REG_VDD1, pdata->vdd1);
+		child = add_regulator(TWL4030_REG_VDD1, pdata->vdd1,
+					features);
 		if (IS_ERR(child))
 			return PTR_ERR(child);
 
-		child = add_regulator(TWL4030_REG_VDD2, pdata->vdd2);
+		child = add_regulator(TWL4030_REG_VDD2, pdata->vdd2,
+					features);
 		if (IS_ERR(child))
 			return PTR_ERR(child);
 
-		child = add_regulator(TWL4030_REG_VMMC1, pdata->vmmc1);
+		child = add_regulator(TWL4030_REG_VMMC1, pdata->vmmc1,
+					features);
 		if (IS_ERR(child))
 			return PTR_ERR(child);
 
-		child = add_regulator(TWL4030_REG_VDAC, pdata->vdac);
+		child = add_regulator(TWL4030_REG_VDAC, pdata->vdac,
+					features);
 		if (IS_ERR(child))
 			return PTR_ERR(child);
 
 		child = add_regulator((features & TWL4030_VAUX2)
 					? TWL4030_REG_VAUX2_4030
 					: TWL4030_REG_VAUX2,
-				pdata->vaux2);
+				pdata->vaux2, features);
 		if (IS_ERR(child))
 			return PTR_ERR(child);
 
-		child = add_regulator(TWL4030_REG_VINTANA1, pdata->vintana1);
+		child = add_regulator(TWL4030_REG_VINTANA1, pdata->vintana1,
+					features);
 		if (IS_ERR(child))
 			return PTR_ERR(child);
 
-		child = add_regulator(TWL4030_REG_VINTANA2, pdata->vintana2);
+		child = add_regulator(TWL4030_REG_VINTANA2, pdata->vintana2,
+					features);
 		if (IS_ERR(child))
 			return PTR_ERR(child);
 
-		child = add_regulator(TWL4030_REG_VINTDIG, pdata->vintdig);
+		child = add_regulator(TWL4030_REG_VINTDIG, pdata->vintdig,
+					features);
 		if (IS_ERR(child))
 			return PTR_ERR(child);
 	}
@@ -802,72 +892,152 @@
 	/* maybe add LDOs that are omitted on cost-reduced parts */
 	if (twl_has_regulator() && !(features & TPS_SUBSET)
 	  && twl_class_is_4030()) {
-		child = add_regulator(TWL4030_REG_VPLL2, pdata->vpll2);
+		child = add_regulator(TWL4030_REG_VPLL2, pdata->vpll2,
+					features);
 		if (IS_ERR(child))
 			return PTR_ERR(child);
 
-		child = add_regulator(TWL4030_REG_VMMC2, pdata->vmmc2);
+		child = add_regulator(TWL4030_REG_VMMC2, pdata->vmmc2,
+					features);
 		if (IS_ERR(child))
 			return PTR_ERR(child);
 
-		child = add_regulator(TWL4030_REG_VSIM, pdata->vsim);
+		child = add_regulator(TWL4030_REG_VSIM, pdata->vsim,
+					features);
 		if (IS_ERR(child))
 			return PTR_ERR(child);
 
-		child = add_regulator(TWL4030_REG_VAUX1, pdata->vaux1);
+		child = add_regulator(TWL4030_REG_VAUX1, pdata->vaux1,
+					features);
 		if (IS_ERR(child))
 			return PTR_ERR(child);
 
-		child = add_regulator(TWL4030_REG_VAUX3, pdata->vaux3);
+		child = add_regulator(TWL4030_REG_VAUX3, pdata->vaux3,
+					features);
 		if (IS_ERR(child))
 			return PTR_ERR(child);
 
-		child = add_regulator(TWL4030_REG_VAUX4, pdata->vaux4);
+		child = add_regulator(TWL4030_REG_VAUX4, pdata->vaux4,
+					features);
 		if (IS_ERR(child))
 			return PTR_ERR(child);
 	}
 
 	/* twl6030 regulators */
+	if (twl_has_regulator() && twl_class_is_6030() &&
+			!(features & TWL6025_SUBCLASS)) {
+		child = add_regulator(TWL6030_REG_VMMC, pdata->vmmc,
+					features);
+		if (IS_ERR(child))
+			return PTR_ERR(child);
+
+		child = add_regulator(TWL6030_REG_VPP, pdata->vpp,
+					features);
+		if (IS_ERR(child))
+			return PTR_ERR(child);
+
+		child = add_regulator(TWL6030_REG_VUSIM, pdata->vusim,
+					features);
+		if (IS_ERR(child))
+			return PTR_ERR(child);
+
+		child = add_regulator(TWL6030_REG_VCXIO, pdata->vcxio,
+					features);
+		if (IS_ERR(child))
+			return PTR_ERR(child);
+
+		child = add_regulator(TWL6030_REG_VDAC, pdata->vdac,
+					features);
+		if (IS_ERR(child))
+			return PTR_ERR(child);
+
+		child = add_regulator(TWL6030_REG_VAUX1_6030, pdata->vaux1,
+					features);
+		if (IS_ERR(child))
+			return PTR_ERR(child);
+
+		child = add_regulator(TWL6030_REG_VAUX2_6030, pdata->vaux2,
+					features);
+		if (IS_ERR(child))
+			return PTR_ERR(child);
+
+		child = add_regulator(TWL6030_REG_VAUX3_6030, pdata->vaux3,
+					features);
+		if (IS_ERR(child))
+			return PTR_ERR(child);
+
+		child = add_regulator(TWL6030_REG_CLK32KG, pdata->clk32kg,
+					features);
+		if (IS_ERR(child))
+			return PTR_ERR(child);
+	}
+
+	/* 6030 and 6025 share this regulator */
 	if (twl_has_regulator() && twl_class_is_6030()) {
-		child = add_regulator(TWL6030_REG_VMMC, pdata->vmmc);
+		child = add_regulator(TWL6030_REG_VANA, pdata->vana,
+					features);
 		if (IS_ERR(child))
 			return PTR_ERR(child);
+	}
 
-		child = add_regulator(TWL6030_REG_VPP, pdata->vpp);
+	/* twl6025 regulators */
+	if (twl_has_regulator() && twl_class_is_6030() &&
+			(features & TWL6025_SUBCLASS)) {
+		child = add_regulator(TWL6025_REG_LDO5, pdata->ldo5,
+					features);
 		if (IS_ERR(child))
 			return PTR_ERR(child);
 
-		child = add_regulator(TWL6030_REG_VUSIM, pdata->vusim);
+		child = add_regulator(TWL6025_REG_LDO1, pdata->ldo1,
+					features);
 		if (IS_ERR(child))
 			return PTR_ERR(child);
 
-		child = add_regulator(TWL6030_REG_VANA, pdata->vana);
+		child = add_regulator(TWL6025_REG_LDO7, pdata->ldo7,
+					features);
 		if (IS_ERR(child))
 			return PTR_ERR(child);
 
-		child = add_regulator(TWL6030_REG_VCXIO, pdata->vcxio);
+		child = add_regulator(TWL6025_REG_LDO6, pdata->ldo6,
+					features);
 		if (IS_ERR(child))
 			return PTR_ERR(child);
 
-		child = add_regulator(TWL6030_REG_VDAC, pdata->vdac);
+		child = add_regulator(TWL6025_REG_LDOLN, pdata->ldoln,
+					features);
 		if (IS_ERR(child))
 			return PTR_ERR(child);
 
-		child = add_regulator(TWL6030_REG_VAUX1_6030, pdata->vaux1);
+		child = add_regulator(TWL6025_REG_LDO2, pdata->ldo2,
+					features);
 		if (IS_ERR(child))
 			return PTR_ERR(child);
 
-		child = add_regulator(TWL6030_REG_VAUX2_6030, pdata->vaux2);
+		child = add_regulator(TWL6025_REG_LDO4, pdata->ldo4,
+					features);
 		if (IS_ERR(child))
 			return PTR_ERR(child);
 
-		child = add_regulator(TWL6030_REG_VAUX3_6030, pdata->vaux3);
+		child = add_regulator(TWL6025_REG_LDO3, pdata->ldo3,
+					features);
 		if (IS_ERR(child))
 			return PTR_ERR(child);
 
-		child = add_regulator(TWL6030_REG_CLK32KG, pdata->clk32kg);
+		child = add_regulator(TWL6025_REG_SMPS3, pdata->smps3,
+					features);
 		if (IS_ERR(child))
 			return PTR_ERR(child);
+
+		child = add_regulator(TWL6025_REG_SMPS4, pdata->smps4,
+					features);
+		if (IS_ERR(child))
+			return PTR_ERR(child);
+
+		child = add_regulator(TWL6025_REG_VIO, pdata->vio6025,
+					features);
+		if (IS_ERR(child))
+			return PTR_ERR(child);
+
 	}
 
 	if (twl_has_bci() && pdata->bci &&
@@ -1014,6 +1184,7 @@
 	unsigned			i;
 	struct twl4030_platform_data	*pdata = client->dev.platform_data;
 	u8 temp;
+	int ret = 0;
 
 	if (!pdata) {
 		dev_dbg(&client->dev, "no platform data?\n");
@@ -1060,6 +1231,12 @@
 	/* setup clock framework */
 	clocks_init(&client->dev, pdata->clock);
 
+	/* read TWL IDCODE Register */
+	if (twl_id == TWL4030_CLASS_ID) {
+		ret = twl_read_idcode_register();
+		WARN(ret < 0, "Error: reading twl_idcode register value\n");
+	}
+
 	/* load power event scripts */
 	if (twl_has_power() && pdata->power)
 		twl4030_power_init(pdata->power);
@@ -1108,6 +1285,7 @@
 	{ "tps65930", TPS_SUBSET },	/* fewer LDOs and DACs; no charger */
 	{ "tps65920", TPS_SUBSET },	/* fewer LDOs; no codec or charger */
 	{ "twl6030", TWL6030_CLASS },	/* "Phoenix power chip" */
+	{ "twl6025", TWL6030_CLASS | TWL6025_SUBCLASS }, /* "Phoenix lite" */
 	{ /* end of list */ },
 };
 MODULE_DEVICE_TABLE(i2c, twl_ids);
diff -druN linux-2.6.39-libre/drivers/mfd/wl1273-core.c linux-3.0-rc7-libre/drivers/mfd/wl1273-core.c
--- linux-2.6.39-libre/drivers/mfd/wl1273-core.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mfd/wl1273-core.c	2011-07-11 19:51:52.000000000 -0400
@@ -153,7 +153,6 @@
  */
 static int wl1273_fm_set_volume(struct wl1273_core *core, unsigned int volume)
 {
-	u16 val;
 	int r;
 
 	if (volume > WL1273_MAX_VOLUME)
@@ -217,7 +216,8 @@
 
 	cell = &core->cells[children];
 	cell->name = "wl1273_fm_radio";
-	cell->mfd_data = &core;
+	cell->platform_data = &core;
+	cell->pdata_size = sizeof(core);
 	children++;
 
 	core->read = wl1273_fm_read_reg;
@@ -231,7 +231,8 @@
 
 		dev_dbg(&client->dev, "%s: Have codec.\n", __func__);
 		cell->name = "wl1273-codec";
-		cell->mfd_data = &core;
+		cell->platform_data = &core;
+		cell->pdata_size = sizeof(core);
 		children++;
 	}
 
diff -druN linux-2.6.39-libre/drivers/mfd/wm831x-core.c linux-3.0-rc7-libre/drivers/mfd/wm831x-core.c
--- linux-2.6.39-libre/drivers/mfd/wm831x-core.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mfd/wm831x-core.c	2011-07-11 19:51:52.000000000 -0400
@@ -1442,7 +1442,7 @@
 	struct wm831x_pdata *pdata = wm831x->dev->platform_data;
 	int rev;
 	enum wm831x_parent parent;
-	int ret;
+	int ret, i;
 
 	mutex_init(&wm831x->io_lock);
 	mutex_init(&wm831x->key_lock);
@@ -1581,6 +1581,17 @@
 		}
 	}
 
+	if (pdata) {
+		for (i = 0; i < ARRAY_SIZE(pdata->gpio_defaults); i++) {
+			if (!pdata->gpio_defaults[i])
+				continue;
+
+			wm831x_reg_write(wm831x,
+					 WM831X_GPIO1_CONTROL + i,
+					 pdata->gpio_defaults[i] & 0xffff);
+		}
+	}
+
 	ret = wm831x_irq_init(wm831x, irq);
 	if (ret != 0)
 		goto err;
diff -druN linux-2.6.39-libre/drivers/mfd/wm831x-irq.c linux-3.0-rc7-libre/drivers/mfd/wm831x-irq.c
--- linux-2.6.39-libre/drivers/mfd/wm831x-irq.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mfd/wm831x-irq.c	2011-07-11 19:51:52.000000000 -0400
@@ -515,12 +515,6 @@
 				 0xffff);
 	}
 
-	if (!irq) {
-		dev_warn(wm831x->dev,
-			 "No interrupt specified - functionality limited\n");
-		return 0;
-	}
-
 	if (!pdata || !pdata->irq_base) {
 		dev_err(wm831x->dev,
 			"No interrupt base specified, no interrupts\n");
@@ -567,15 +561,22 @@
 #endif
 	}
 
-	ret = request_threaded_irq(irq, NULL, wm831x_irq_thread,
-				   IRQF_TRIGGER_LOW | IRQF_ONESHOT,
-				   "wm831x", wm831x);
-	if (ret != 0) {
-		dev_err(wm831x->dev, "Failed to request IRQ %d: %d\n",
-			irq, ret);
-		return ret;
+	if (irq) {
+		ret = request_threaded_irq(irq, NULL, wm831x_irq_thread,
+					   IRQF_TRIGGER_LOW | IRQF_ONESHOT,
+					   "wm831x", wm831x);
+		if (ret != 0) {
+			dev_err(wm831x->dev, "Failed to request IRQ %d: %d\n",
+				irq, ret);
+			return ret;
+		}
+	} else {
+		dev_warn(wm831x->dev,
+			 "No interrupt specified - functionality limited\n");
 	}
 
+
+
 	/* Enable top level interrupts, we mask at secondary level */
 	wm831x_reg_write(wm831x, WM831X_SYSTEM_INTERRUPTS_MASK, 0);
 
diff -druN linux-2.6.39-libre/drivers/mfd/wm8400-core.c linux-3.0-rc7-libre/drivers/mfd/wm8400-core.c
--- linux-2.6.39-libre/drivers/mfd/wm8400-core.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mfd/wm8400-core.c	2011-07-11 19:51:52.000000000 -0400
@@ -245,7 +245,8 @@
 {
 	struct mfd_cell cell = {
 		.name = "wm8400-codec",
-		.mfd_data = wm8400,
+		.platform_data = wm8400,
+		.pdata_size = sizeof(*wm8400),
 	};
 
 	return mfd_add_devices(wm8400->dev, -1, &cell, 1, NULL, 0);
diff -druN linux-2.6.39-libre/drivers/misc/apds990x.c linux-3.0-rc7-libre/drivers/misc/apds990x.c
--- linux-2.6.39-libre/drivers/misc/apds990x.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/misc/apds990x.c	2011-07-11 19:51:52.000000000 -0400
@@ -609,6 +609,7 @@
 	return ret;
 }
 
+#if defined(CONFIG_PM) || defined(CONFIG_PM_RUNTIME)
 static int apds990x_chip_on(struct apds990x_chip *chip)
 {
 	int err	 = regulator_bulk_enable(ARRAY_SIZE(chip->regs),
@@ -624,6 +625,7 @@
 	apds990x_mode_on(chip);
 	return 0;
 }
+#endif
 
 static int apds990x_chip_off(struct apds990x_chip *chip)
 {
diff -druN linux-2.6.39-libre/drivers/misc/bh1780gli.c linux-3.0-rc7-libre/drivers/misc/bh1780gli.c
--- linux-2.6.39-libre/drivers/misc/bh1780gli.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/misc/bh1780gli.c	2011-07-11 19:51:52.000000000 -0400
@@ -49,8 +49,8 @@
 	int ret = i2c_smbus_write_byte_data(ddata->client, reg, val);
 	if (ret < 0)
 		dev_err(&ddata->client->dev,
-			"i2c_smbus_write_byte_data failed error %d\
-			Register (%s)\n", ret, msg);
+			"i2c_smbus_write_byte_data failed error %d Register (%s)\n",
+			ret, msg);
 	return ret;
 }
 
@@ -59,8 +59,8 @@
 	int ret = i2c_smbus_read_byte_data(ddata->client, reg);
 	if (ret < 0)
 		dev_err(&ddata->client->dev,
-			"i2c_smbus_read_byte_data failed error %d\
-			 Register (%s)\n", ret, msg);
+			"i2c_smbus_read_byte_data failed error %d Register (%s)\n",
+			ret, msg);
 	return ret;
 }
 
diff -druN linux-2.6.39-libre/drivers/misc/carma/carma-fpga.c linux-3.0-rc7-libre/drivers/misc/carma/carma-fpga.c
--- linux-2.6.39-libre/drivers/misc/carma/carma-fpga.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/misc/carma/carma-fpga.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,1433 @@
+/*
+ * CARMA DATA-FPGA Access Driver
+ *
+ * Copyright (c) 2009-2011 Ira W. Snyder <iws@ovro.caltech.edu>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+/*
+ * FPGA Memory Dump Format
+ *
+ * FPGA #0 control registers (32 x 32-bit words)
+ * FPGA #1 control registers (32 x 32-bit words)
+ * FPGA #2 control registers (32 x 32-bit words)
+ * FPGA #3 control registers (32 x 32-bit words)
+ * SYSFPGA control registers (32 x 32-bit words)
+ * FPGA #0 correlation array (NUM_CORL0 correlation blocks)
+ * FPGA #1 correlation array (NUM_CORL1 correlation blocks)
+ * FPGA #2 correlation array (NUM_CORL2 correlation blocks)
+ * FPGA #3 correlation array (NUM_CORL3 correlation blocks)
+ *
+ * Each correlation array consists of:
+ *
+ * Correlation Data      (2 x NUM_LAGSn x 32-bit words)
+ * Pipeline Metadata     (2 x NUM_METAn x 32-bit words)
+ * Quantization Counters (2 x NUM_QCNTn x 32-bit words)
+ *
+ * The NUM_CORLn, NUM_LAGSn, NUM_METAn, and NUM_QCNTn values come from
+ * the FPGA configuration registers. They do not change once the FPGA's
+ * have been programmed, they only change on re-programming.
+ */
+
+/*
+ * Basic Description:
+ *
+ * This driver is used to capture correlation spectra off of the four data
+ * processing FPGAs. The FPGAs are often reprogrammed at runtime, therefore
+ * this driver supports dynamic enable/disable of capture while the device
+ * remains open.
+ *
+ * The nominal capture rate is 64Hz (every 15.625ms). To facilitate this fast
+ * capture rate, all buffers are pre-allocated to avoid any potentially long
+ * running memory allocations while capturing.
+ *
+ * There are two lists and one pointer which are used to keep track of the
+ * different states of data buffers.
+ *
+ * 1) free list
+ * This list holds all empty data buffers which are ready to receive data.
+ *
+ * 2) inflight pointer
+ * This pointer holds the currently inflight data buffer. This buffer is having
+ * data copied into it by the DMA engine.
+ *
+ * 3) used list
+ * This list holds data buffers which have been filled, and are waiting to be
+ * read by userspace.
+ *
+ * All buffers start life on the free list, then move successively to the
+ * inflight pointer, and then to the used list. After they have been read by
+ * userspace, they are moved back to the free list. The cycle repeats as long
+ * as necessary.
+ *
+ * It should be noted that all buffers are mapped and ready for DMA when they
+ * are on any of the three lists. They are only unmapped when they are in the
+ * process of being read by userspace.
+ */
+
+/*
+ * Notes on the IRQ masking scheme:
+ *
+ * The IRQ masking scheme here is different than most other hardware. The only
+ * way for the DATA-FPGAs to detect if the kernel has taken too long to copy
+ * the data is if the status registers are not cleared before the next
+ * correlation data dump is ready.
+ *
+ * The interrupt line is connected to the status registers, such that when they
+ * are cleared, the interrupt is de-asserted. Therein lies our problem. We need
+ * to schedule a long-running DMA operation and return from the interrupt
+ * handler quickly, but we cannot clear the status registers.
+ *
+ * To handle this, the system controller FPGA has the capability to connect the
+ * interrupt line to a user-controlled GPIO pin. This pin is driven high
+ * (unasserted) and left that way. To mask the interrupt, we change the
+ * interrupt source to the GPIO pin. Tada, we hid the interrupt. :)
+ */
+
+#include <linux/of_platform.h>
+#include <linux/dma-mapping.h>
+#include <linux/miscdevice.h>
+#include <linux/interrupt.h>
+#include <linux/dmaengine.h>
+#include <linux/seq_file.h>
+#include <linux/highmem.h>
+#include <linux/debugfs.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/poll.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/kref.h>
+#include <linux/io.h>
+
+#include <media/videobuf-dma-sg.h>
+
+/* system controller registers */
+#define SYS_IRQ_SOURCE_CTL	0x24
+#define SYS_IRQ_OUTPUT_EN	0x28
+#define SYS_IRQ_OUTPUT_DATA	0x2C
+#define SYS_IRQ_INPUT_DATA	0x30
+#define SYS_FPGA_CONFIG_STATUS	0x44
+
+/* GPIO IRQ line assignment */
+#define IRQ_CORL_DONE		0x10
+
+/* FPGA registers */
+#define MMAP_REG_VERSION	0x00
+#define MMAP_REG_CORL_CONF1	0x08
+#define MMAP_REG_CORL_CONF2	0x0C
+#define MMAP_REG_STATUS		0x48
+
+#define SYS_FPGA_BLOCK		0xF0000000
+
+#define DATA_FPGA_START		0x400000
+#define DATA_FPGA_SIZE		0x80000
+
+static const char drv_name[] = "carma-fpga";
+
+#define NUM_FPGA	4
+
+#define MIN_DATA_BUFS	8
+#define MAX_DATA_BUFS	64
+
+struct fpga_info {
+	unsigned int num_lag_ram;
+	unsigned int blk_size;
+};
+
+struct data_buf {
+	struct list_head entry;
+	struct videobuf_dmabuf vb;
+	size_t size;
+};
+
+struct fpga_device {
+	/* character device */
+	struct miscdevice miscdev;
+	struct device *dev;
+	struct mutex mutex;
+
+	/* reference count */
+	struct kref ref;
+
+	/* FPGA registers and information */
+	struct fpga_info info[NUM_FPGA];
+	void __iomem *regs;
+	int irq;
+
+	/* FPGA Physical Address/Size Information */
+	resource_size_t phys_addr;
+	size_t phys_size;
+
+	/* DMA structures */
+	struct sg_table corl_table;
+	unsigned int corl_nents;
+	struct dma_chan *chan;
+
+	/* Protection for all members below */
+	spinlock_t lock;
+
+	/* Device enable/disable flag */
+	bool enabled;
+
+	/* Correlation data buffers */
+	wait_queue_head_t wait;
+	struct list_head free;
+	struct list_head used;
+	struct data_buf *inflight;
+
+	/* Information about data buffers */
+	unsigned int num_dropped;
+	unsigned int num_buffers;
+	size_t bufsize;
+	struct dentry *dbg_entry;
+};
+
+struct fpga_reader {
+	struct fpga_device *priv;
+	struct data_buf *buf;
+	off_t buf_start;
+};
+
+static void fpga_device_release(struct kref *ref)
+{
+	struct fpga_device *priv = container_of(ref, struct fpga_device, ref);
+
+	/* the last reader has exited, cleanup the last bits */
+	mutex_destroy(&priv->mutex);
+	kfree(priv);
+}
+
+/*
+ * Data Buffer Allocation Helpers
+ */
+
+/**
+ * data_free_buffer() - free a single data buffer and all allocated memory
+ * @buf: the buffer to free
+ *
+ * This will free all of the pages allocated to the given data buffer, and
+ * then free the structure itself
+ */
+static void data_free_buffer(struct data_buf *buf)
+{
+	/* It is ok to free a NULL buffer */
+	if (!buf)
+		return;
+
+	/* free all memory */
+	videobuf_dma_free(&buf->vb);
+	kfree(buf);
+}
+
+/**
+ * data_alloc_buffer() - allocate and fill a data buffer with pages
+ * @bytes: the number of bytes required
+ *
+ * This allocates all space needed for a data buffer. It must be mapped before
+ * use in a DMA transaction using videobuf_dma_map().
+ *
+ * Returns NULL on failure
+ */
+static struct data_buf *data_alloc_buffer(const size_t bytes)
+{
+	unsigned int nr_pages;
+	struct data_buf *buf;
+	int ret;
+
+	/* calculate the number of pages necessary */
+	nr_pages = DIV_ROUND_UP(bytes, PAGE_SIZE);
+
+	/* allocate the buffer structure */
+	buf = kzalloc(sizeof(*buf), GFP_KERNEL);
+	if (!buf)
+		goto out_return;
+
+	/* initialize internal fields */
+	INIT_LIST_HEAD(&buf->entry);
+	buf->size = bytes;
+
+	/* allocate the videobuf */
+	videobuf_dma_init(&buf->vb);
+	ret = videobuf_dma_init_kernel(&buf->vb, DMA_FROM_DEVICE, nr_pages);
+	if (ret)
+		goto out_free_buf;
+
+	return buf;
+
+out_free_buf:
+	kfree(buf);
+out_return:
+	return NULL;
+}
+
+/**
+ * data_free_buffers() - free all allocated buffers
+ * @priv: the driver's private data structure
+ *
+ * Free all buffers allocated by the driver (except those currently in the
+ * process of being read by userspace).
+ *
+ * LOCKING: must hold dev->mutex
+ * CONTEXT: user
+ */
+static void data_free_buffers(struct fpga_device *priv)
+{
+	struct data_buf *buf, *tmp;
+
+	/* the device should be stopped, no DMA in progress */
+	BUG_ON(priv->inflight != NULL);
+
+	list_for_each_entry_safe(buf, tmp, &priv->free, entry) {
+		list_del_init(&buf->entry);
+		videobuf_dma_unmap(priv->dev, &buf->vb);
+		data_free_buffer(buf);
+	}
+
+	list_for_each_entry_safe(buf, tmp, &priv->used, entry) {
+		list_del_init(&buf->entry);
+		videobuf_dma_unmap(priv->dev, &buf->vb);
+		data_free_buffer(buf);
+	}
+
+	priv->num_buffers = 0;
+	priv->bufsize = 0;
+}
+
+/**
+ * data_alloc_buffers() - allocate 1 seconds worth of data buffers
+ * @priv: the driver's private data structure
+ *
+ * Allocate enough buffers for a whole second worth of data
+ *
+ * This routine will attempt to degrade nicely by succeeding even if a full
+ * second worth of data buffers could not be allocated, as long as a minimum
+ * number were allocated. In this case, it will print a message to the kernel
+ * log.
+ *
+ * The device must not be modifying any lists when this is called.
+ *
+ * CONTEXT: user
+ * LOCKING: must hold dev->mutex
+ *
+ * Returns 0 on success, -ERRNO otherwise
+ */
+static int data_alloc_buffers(struct fpga_device *priv)
+{
+	struct data_buf *buf;
+	int i, ret;
+
+	for (i = 0; i < MAX_DATA_BUFS; i++) {
+
+		/* allocate a buffer */
+		buf = data_alloc_buffer(priv->bufsize);
+		if (!buf)
+			break;
+
+		/* map it for DMA */
+		ret = videobuf_dma_map(priv->dev, &buf->vb);
+		if (ret) {
+			data_free_buffer(buf);
+			break;
+		}
+
+		/* add it to the list of free buffers */
+		list_add_tail(&buf->entry, &priv->free);
+		priv->num_buffers++;
+	}
+
+	/* Make sure we allocated the minimum required number of buffers */
+	if (priv->num_buffers < MIN_DATA_BUFS) {
+		dev_err(priv->dev, "Unable to allocate enough data buffers\n");
+		data_free_buffers(priv);
+		return -ENOMEM;
+	}
+
+	/* Warn if we are running in a degraded state, but do not fail */
+	if (priv->num_buffers < MAX_DATA_BUFS) {
+		dev_warn(priv->dev,
+			 "Unable to allocate %d buffers, using %d buffers instead\n",
+			 MAX_DATA_BUFS, i);
+	}
+
+	return 0;
+}
+
+/*
+ * DMA Operations Helpers
+ */
+
+/**
+ * fpga_start_addr() - get the physical address a DATA-FPGA
+ * @priv: the driver's private data structure
+ * @fpga: the DATA-FPGA number (zero based)
+ */
+static dma_addr_t fpga_start_addr(struct fpga_device *priv, unsigned int fpga)
+{
+	return priv->phys_addr + 0x400000 + (0x80000 * fpga);
+}
+
+/**
+ * fpga_block_addr() - get the physical address of a correlation data block
+ * @priv: the driver's private data structure
+ * @fpga: the DATA-FPGA number (zero based)
+ * @blknum: the correlation block number (zero based)
+ */
+static dma_addr_t fpga_block_addr(struct fpga_device *priv, unsigned int fpga,
+				  unsigned int blknum)
+{
+	return fpga_start_addr(priv, fpga) + (0x10000 * (1 + blknum));
+}
+
+#define REG_BLOCK_SIZE	(32 * 4)
+
+/**
+ * data_setup_corl_table() - create the scatterlist for correlation dumps
+ * @priv: the driver's private data structure
+ *
+ * Create the scatterlist for transferring a correlation dump from the
+ * DATA FPGAs. This structure will be reused for each buffer than needs
+ * to be filled with correlation data.
+ *
+ * Returns 0 on success, -ERRNO otherwise
+ */
+static int data_setup_corl_table(struct fpga_device *priv)
+{
+	struct sg_table *table = &priv->corl_table;
+	struct scatterlist *sg;
+	struct fpga_info *info;
+	int i, j, ret;
+
+	/* Calculate the number of entries needed */
+	priv->corl_nents = (1 + NUM_FPGA) * REG_BLOCK_SIZE;
+	for (i = 0; i < NUM_FPGA; i++)
+		priv->corl_nents += priv->info[i].num_lag_ram;
+
+	/* Allocate the scatterlist table */
+	ret = sg_alloc_table(table, priv->corl_nents, GFP_KERNEL);
+	if (ret) {
+		dev_err(priv->dev, "unable to allocate DMA table\n");
+		return ret;
+	}
+
+	/* Add the DATA FPGA registers to the scatterlist */
+	sg = table->sgl;
+	for (i = 0; i < NUM_FPGA; i++) {
+		sg_dma_address(sg) = fpga_start_addr(priv, i);
+		sg_dma_len(sg) = REG_BLOCK_SIZE;
+		sg = sg_next(sg);
+	}
+
+	/* Add the SYS-FPGA registers to the scatterlist */
+	sg_dma_address(sg) = SYS_FPGA_BLOCK;
+	sg_dma_len(sg) = REG_BLOCK_SIZE;
+	sg = sg_next(sg);
+
+	/* Add the FPGA correlation data blocks to the scatterlist */
+	for (i = 0; i < NUM_FPGA; i++) {
+		info = &priv->info[i];
+		for (j = 0; j < info->num_lag_ram; j++) {
+			sg_dma_address(sg) = fpga_block_addr(priv, i, j);
+			sg_dma_len(sg) = info->blk_size;
+			sg = sg_next(sg);
+		}
+	}
+
+	/*
+	 * All physical addresses and lengths are present in the structure
+	 * now. It can be reused for every FPGA DATA interrupt
+	 */
+	return 0;
+}
+
+/*
+ * FPGA Register Access Helpers
+ */
+
+static void fpga_write_reg(struct fpga_device *priv, unsigned int fpga,
+			   unsigned int reg, u32 val)
+{
+	const int fpga_start = DATA_FPGA_START + (fpga * DATA_FPGA_SIZE);
+	iowrite32be(val, priv->regs + fpga_start + reg);
+}
+
+static u32 fpga_read_reg(struct fpga_device *priv, unsigned int fpga,
+			 unsigned int reg)
+{
+	const int fpga_start = DATA_FPGA_START + (fpga * DATA_FPGA_SIZE);
+	return ioread32be(priv->regs + fpga_start + reg);
+}
+
+/**
+ * data_calculate_bufsize() - calculate the data buffer size required
+ * @priv: the driver's private data structure
+ *
+ * Calculate the total buffer size needed to hold a single block
+ * of correlation data
+ *
+ * CONTEXT: user
+ *
+ * Returns 0 on success, -ERRNO otherwise
+ */
+static int data_calculate_bufsize(struct fpga_device *priv)
+{
+	u32 num_corl, num_lags, num_meta, num_qcnt, num_pack;
+	u32 conf1, conf2, version;
+	u32 num_lag_ram, blk_size;
+	int i;
+
+	/* Each buffer starts with the 5 FPGA register areas */
+	priv->bufsize = (1 + NUM_FPGA) * REG_BLOCK_SIZE;
+
+	/* Read and store the configuration data for each FPGA */
+	for (i = 0; i < NUM_FPGA; i++) {
+		version = fpga_read_reg(priv, i, MMAP_REG_VERSION);
+		conf1 = fpga_read_reg(priv, i, MMAP_REG_CORL_CONF1);
+		conf2 = fpga_read_reg(priv, i, MMAP_REG_CORL_CONF2);
+
+		/* minor version 2 and later */
+		if ((version & 0x000000FF) >= 2) {
+			num_corl = (conf1 & 0x000000F0) >> 4;
+			num_pack = (conf1 & 0x00000F00) >> 8;
+			num_lags = (conf1 & 0x00FFF000) >> 12;
+			num_meta = (conf1 & 0x7F000000) >> 24;
+			num_qcnt = (conf2 & 0x00000FFF) >> 0;
+		} else {
+			num_corl = (conf1 & 0x000000F0) >> 4;
+			num_pack = 1; /* implied */
+			num_lags = (conf1 & 0x000FFF00) >> 8;
+			num_meta = (conf1 & 0x7FF00000) >> 20;
+			num_qcnt = (conf2 & 0x00000FFF) >> 0;
+		}
+
+		num_lag_ram = (num_corl + num_pack - 1) / num_pack;
+		blk_size = ((num_pack * num_lags) + num_meta + num_qcnt) * 8;
+
+		priv->info[i].num_lag_ram = num_lag_ram;
+		priv->info[i].blk_size = blk_size;
+		priv->bufsize += num_lag_ram * blk_size;
+
+		dev_dbg(priv->dev, "FPGA %d NUM_CORL: %d\n", i, num_corl);
+		dev_dbg(priv->dev, "FPGA %d NUM_PACK: %d\n", i, num_pack);
+		dev_dbg(priv->dev, "FPGA %d NUM_LAGS: %d\n", i, num_lags);
+		dev_dbg(priv->dev, "FPGA %d NUM_META: %d\n", i, num_meta);
+		dev_dbg(priv->dev, "FPGA %d NUM_QCNT: %d\n", i, num_qcnt);
+		dev_dbg(priv->dev, "FPGA %d BLK_SIZE: %d\n", i, blk_size);
+	}
+
+	dev_dbg(priv->dev, "TOTAL BUFFER SIZE: %zu bytes\n", priv->bufsize);
+	return 0;
+}
+
+/*
+ * Interrupt Handling
+ */
+
+/**
+ * data_disable_interrupts() - stop the device from generating interrupts
+ * @priv: the driver's private data structure
+ *
+ * Hide interrupts by switching to GPIO interrupt source
+ *
+ * LOCKING: must hold dev->lock
+ */
+static void data_disable_interrupts(struct fpga_device *priv)
+{
+	/* hide the interrupt by switching the IRQ driver to GPIO */
+	iowrite32be(0x2F, priv->regs + SYS_IRQ_SOURCE_CTL);
+}
+
+/**
+ * data_enable_interrupts() - allow the device to generate interrupts
+ * @priv: the driver's private data structure
+ *
+ * Unhide interrupts by switching to the FPGA interrupt source. At the
+ * same time, clear the DATA-FPGA status registers.
+ *
+ * LOCKING: must hold dev->lock
+ */
+static void data_enable_interrupts(struct fpga_device *priv)
+{
+	/* clear the actual FPGA corl_done interrupt */
+	fpga_write_reg(priv, 0, MMAP_REG_STATUS, 0x0);
+	fpga_write_reg(priv, 1, MMAP_REG_STATUS, 0x0);
+	fpga_write_reg(priv, 2, MMAP_REG_STATUS, 0x0);
+	fpga_write_reg(priv, 3, MMAP_REG_STATUS, 0x0);
+
+	/* flush the writes */
+	fpga_read_reg(priv, 0, MMAP_REG_STATUS);
+
+	/* switch back to the external interrupt source */
+	iowrite32be(0x3F, priv->regs + SYS_IRQ_SOURCE_CTL);
+}
+
+/**
+ * data_dma_cb() - DMAEngine callback for DMA completion
+ * @data: the driver's private data structure
+ *
+ * Complete a DMA transfer from the DATA-FPGA's
+ *
+ * This is called via the DMA callback mechanism, and will handle moving the
+ * completed DMA transaction to the used list, and then wake any processes
+ * waiting for new data
+ *
+ * CONTEXT: any, softirq expected
+ */
+static void data_dma_cb(void *data)
+{
+	struct fpga_device *priv = data;
+	unsigned long flags;
+
+	spin_lock_irqsave(&priv->lock, flags);
+
+	/* If there is no inflight buffer, we've got a bug */
+	BUG_ON(priv->inflight == NULL);
+
+	/* Move the inflight buffer onto the used list */
+	list_move_tail(&priv->inflight->entry, &priv->used);
+	priv->inflight = NULL;
+
+	/* clear the FPGA status and re-enable interrupts */
+	data_enable_interrupts(priv);
+
+	spin_unlock_irqrestore(&priv->lock, flags);
+
+	/*
+	 * We've changed both the inflight and used lists, so we need
+	 * to wake up any processes that are blocking for those events
+	 */
+	wake_up(&priv->wait);
+}
+
+/**
+ * data_submit_dma() - prepare and submit the required DMA to fill a buffer
+ * @priv: the driver's private data structure
+ * @buf: the data buffer
+ *
+ * Prepare and submit the necessary DMA transactions to fill a correlation
+ * data buffer.
+ *
+ * LOCKING: must hold dev->lock
+ * CONTEXT: hardirq only
+ *
+ * Returns 0 on success, -ERRNO otherwise
+ */
+static int data_submit_dma(struct fpga_device *priv, struct data_buf *buf)
+{
+	struct scatterlist *dst_sg, *src_sg;
+	unsigned int dst_nents, src_nents;
+	struct dma_chan *chan = priv->chan;
+	struct dma_async_tx_descriptor *tx;
+	dma_cookie_t cookie;
+	dma_addr_t dst, src;
+
+	dst_sg = buf->vb.sglist;
+	dst_nents = buf->vb.sglen;
+
+	src_sg = priv->corl_table.sgl;
+	src_nents = priv->corl_nents;
+
+	/*
+	 * All buffers passed to this function should be ready and mapped
+	 * for DMA already. Therefore, we don't need to do anything except
+	 * submit it to the Freescale DMA Engine for processing
+	 */
+
+	/* setup the scatterlist to scatterlist transfer */
+	tx = chan->device->device_prep_dma_sg(chan,
+					      dst_sg, dst_nents,
+					      src_sg, src_nents,
+					      0);
+	if (!tx) {
+		dev_err(priv->dev, "unable to prep scatterlist DMA\n");
+		return -ENOMEM;
+	}
+
+	/* submit the transaction to the DMA controller */
+	cookie = tx->tx_submit(tx);
+	if (dma_submit_error(cookie)) {
+		dev_err(priv->dev, "unable to submit scatterlist DMA\n");
+		return -ENOMEM;
+	}
+
+	/* Prepare the re-read of the SYS-FPGA block */
+	dst = sg_dma_address(dst_sg) + (NUM_FPGA * REG_BLOCK_SIZE);
+	src = SYS_FPGA_BLOCK;
+	tx = chan->device->device_prep_dma_memcpy(chan, dst, src,
+						  REG_BLOCK_SIZE,
+						  DMA_PREP_INTERRUPT);
+	if (!tx) {
+		dev_err(priv->dev, "unable to prep SYS-FPGA DMA\n");
+		return -ENOMEM;
+	}
+
+	/* Setup the callback */
+	tx->callback = data_dma_cb;
+	tx->callback_param = priv;
+
+	/* submit the transaction to the DMA controller */
+	cookie = tx->tx_submit(tx);
+	if (dma_submit_error(cookie)) {
+		dev_err(priv->dev, "unable to submit SYS-FPGA DMA\n");
+		return -ENOMEM;
+	}
+
+	return 0;
+}
+
+#define CORL_DONE	0x1
+#define CORL_ERR	0x2
+
+static irqreturn_t data_irq(int irq, void *dev_id)
+{
+	struct fpga_device *priv = dev_id;
+	bool submitted = false;
+	struct data_buf *buf;
+	u32 status;
+	int i;
+
+	/* detect spurious interrupts via FPGA status */
+	for (i = 0; i < 4; i++) {
+		status = fpga_read_reg(priv, i, MMAP_REG_STATUS);
+		if (!(status & (CORL_DONE | CORL_ERR))) {
+			dev_err(priv->dev, "spurious irq detected (FPGA)\n");
+			return IRQ_NONE;
+		}
+	}
+
+	/* detect spurious interrupts via raw IRQ pin readback */
+	status = ioread32be(priv->regs + SYS_IRQ_INPUT_DATA);
+	if (status & IRQ_CORL_DONE) {
+		dev_err(priv->dev, "spurious irq detected (IRQ)\n");
+		return IRQ_NONE;
+	}
+
+	spin_lock(&priv->lock);
+
+	/* hide the interrupt by switching the IRQ driver to GPIO */
+	data_disable_interrupts(priv);
+
+	/* If there are no free buffers, drop this data */
+	if (list_empty(&priv->free)) {
+		priv->num_dropped++;
+		goto out;
+	}
+
+	buf = list_first_entry(&priv->free, struct data_buf, entry);
+	list_del_init(&buf->entry);
+	BUG_ON(buf->size != priv->bufsize);
+
+	/* Submit a DMA transfer to get the correlation data */
+	if (data_submit_dma(priv, buf)) {
+		dev_err(priv->dev, "Unable to setup DMA transfer\n");
+		list_move_tail(&buf->entry, &priv->free);
+		goto out;
+	}
+
+	/* Save the buffer for the DMA callback */
+	priv->inflight = buf;
+	submitted = true;
+
+	/* Start the DMA Engine */
+	dma_async_memcpy_issue_pending(priv->chan);
+
+out:
+	/* If no DMA was submitted, re-enable interrupts */
+	if (!submitted)
+		data_enable_interrupts(priv);
+
+	spin_unlock(&priv->lock);
+	return IRQ_HANDLED;
+}
+
+/*
+ * Realtime Device Enable Helpers
+ */
+
+/**
+ * data_device_enable() - enable the device for buffered dumping
+ * @priv: the driver's private data structure
+ *
+ * Enable the device for buffered dumping. Allocates buffers and hooks up
+ * the interrupt handler. When this finishes, data will come pouring in.
+ *
+ * LOCKING: must hold dev->mutex
+ * CONTEXT: user context only
+ *
+ * Returns 0 on success, -ERRNO otherwise
+ */
+static int data_device_enable(struct fpga_device *priv)
+{
+	u32 val;
+	int ret;
+
+	/* multiple enables are safe: they do nothing */
+	if (priv->enabled)
+		return 0;
+
+	/* check that the FPGAs are programmed */
+	val = ioread32be(priv->regs + SYS_FPGA_CONFIG_STATUS);
+	if (!(val & (1 << 18))) {
+		dev_err(priv->dev, "DATA-FPGAs are not enabled\n");
+		return -ENODATA;
+	}
+
+	/* read the FPGAs to calculate the buffer size */
+	ret = data_calculate_bufsize(priv);
+	if (ret) {
+		dev_err(priv->dev, "unable to calculate buffer size\n");
+		goto out_error;
+	}
+
+	/* allocate the correlation data buffers */
+	ret = data_alloc_buffers(priv);
+	if (ret) {
+		dev_err(priv->dev, "unable to allocate buffers\n");
+		goto out_error;
+	}
+
+	/* setup the source scatterlist for dumping correlation data */
+	ret = data_setup_corl_table(priv);
+	if (ret) {
+		dev_err(priv->dev, "unable to setup correlation DMA table\n");
+		goto out_error;
+	}
+
+	/* hookup the irq handler */
+	ret = request_irq(priv->irq, data_irq, IRQF_SHARED, drv_name, priv);
+	if (ret) {
+		dev_err(priv->dev, "unable to request IRQ handler\n");
+		goto out_error;
+	}
+
+	/* switch to the external FPGA IRQ line */
+	data_enable_interrupts(priv);
+
+	/* success, we're enabled */
+	priv->enabled = true;
+	return 0;
+
+out_error:
+	sg_free_table(&priv->corl_table);
+	priv->corl_nents = 0;
+
+	data_free_buffers(priv);
+	return ret;
+}
+
+/**
+ * data_device_disable() - disable the device for buffered dumping
+ * @priv: the driver's private data structure
+ *
+ * Disable the device for buffered dumping. Stops new DMA transactions from
+ * being generated, waits for all outstanding DMA to complete, and then frees
+ * all buffers.
+ *
+ * LOCKING: must hold dev->mutex
+ * CONTEXT: user only
+ *
+ * Returns 0 on success, -ERRNO otherwise
+ */
+static int data_device_disable(struct fpga_device *priv)
+{
+	int ret;
+
+	/* allow multiple disable */
+	if (!priv->enabled)
+		return 0;
+
+	/* switch to the internal GPIO IRQ line */
+	data_disable_interrupts(priv);
+
+	/* unhook the irq handler */
+	free_irq(priv->irq, priv);
+
+	/*
+	 * wait for all outstanding DMA to complete
+	 *
+	 * Device interrupts are disabled, therefore another buffer cannot
+	 * be marked inflight.
+	 */
+	ret = wait_event_interruptible(priv->wait, priv->inflight == NULL);
+	if (ret)
+		return ret;
+
+	/* free the correlation table */
+	sg_free_table(&priv->corl_table);
+	priv->corl_nents = 0;
+
+	/*
+	 * We are taking the spinlock not to protect priv->enabled, but instead
+	 * to make sure that there are no readers in the process of altering
+	 * the free or used lists while we are setting this flag.
+	 */
+	spin_lock_irq(&priv->lock);
+	priv->enabled = false;
+	spin_unlock_irq(&priv->lock);
+
+	/* free all buffers: the free and used lists are not being changed */
+	data_free_buffers(priv);
+	return 0;
+}
+
+/*
+ * DEBUGFS Interface
+ */
+#ifdef CONFIG_DEBUG_FS
+
+/*
+ * Count the number of entries in the given list
+ */
+static unsigned int list_num_entries(struct list_head *list)
+{
+	struct list_head *entry;
+	unsigned int ret = 0;
+
+	list_for_each(entry, list)
+		ret++;
+
+	return ret;
+}
+
+static int data_debug_show(struct seq_file *f, void *offset)
+{
+	struct fpga_device *priv = f->private;
+	int ret;
+
+	/*
+	 * Lock the mutex first, so that we get an accurate value for enable
+	 * Lock the spinlock next, to get accurate list counts
+	 */
+	ret = mutex_lock_interruptible(&priv->mutex);
+	if (ret)
+		return ret;
+
+	spin_lock_irq(&priv->lock);
+
+	seq_printf(f, "enabled: %d\n", priv->enabled);
+	seq_printf(f, "bufsize: %d\n", priv->bufsize);
+	seq_printf(f, "num_buffers: %d\n", priv->num_buffers);
+	seq_printf(f, "num_free: %d\n", list_num_entries(&priv->free));
+	seq_printf(f, "inflight: %d\n", priv->inflight != NULL);
+	seq_printf(f, "num_used: %d\n", list_num_entries(&priv->used));
+	seq_printf(f, "num_dropped: %d\n", priv->num_dropped);
+
+	spin_unlock_irq(&priv->lock);
+	mutex_unlock(&priv->mutex);
+	return 0;
+}
+
+static int data_debug_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, data_debug_show, inode->i_private);
+}
+
+static const struct file_operations data_debug_fops = {
+	.owner		= THIS_MODULE,
+	.open		= data_debug_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
+static int data_debugfs_init(struct fpga_device *priv)
+{
+	priv->dbg_entry = debugfs_create_file(drv_name, S_IRUGO, NULL, priv,
+					      &data_debug_fops);
+	if (IS_ERR(priv->dbg_entry))
+		return PTR_ERR(priv->dbg_entry);
+
+	return 0;
+}
+
+static void data_debugfs_exit(struct fpga_device *priv)
+{
+	debugfs_remove(priv->dbg_entry);
+}
+
+#else
+
+static inline int data_debugfs_init(struct fpga_device *priv)
+{
+	return 0;
+}
+
+static inline void data_debugfs_exit(struct fpga_device *priv)
+{
+}
+
+#endif	/* CONFIG_DEBUG_FS */
+
+/*
+ * SYSFS Attributes
+ */
+
+static ssize_t data_en_show(struct device *dev, struct device_attribute *attr,
+			    char *buf)
+{
+	struct fpga_device *priv = dev_get_drvdata(dev);
+	return snprintf(buf, PAGE_SIZE, "%u\n", priv->enabled);
+}
+
+static ssize_t data_en_set(struct device *dev, struct device_attribute *attr,
+			   const char *buf, size_t count)
+{
+	struct fpga_device *priv = dev_get_drvdata(dev);
+	unsigned long enable;
+	int ret;
+
+	ret = strict_strtoul(buf, 0, &enable);
+	if (ret) {
+		dev_err(priv->dev, "unable to parse enable input\n");
+		return -EINVAL;
+	}
+
+	ret = mutex_lock_interruptible(&priv->mutex);
+	if (ret)
+		return ret;
+
+	if (enable)
+		ret = data_device_enable(priv);
+	else
+		ret = data_device_disable(priv);
+
+	if (ret) {
+		dev_err(priv->dev, "device %s failed\n",
+			enable ? "enable" : "disable");
+		count = ret;
+		goto out_unlock;
+	}
+
+out_unlock:
+	mutex_unlock(&priv->mutex);
+	return count;
+}
+
+static DEVICE_ATTR(enable, S_IWUSR | S_IRUGO, data_en_show, data_en_set);
+
+static struct attribute *data_sysfs_attrs[] = {
+	&dev_attr_enable.attr,
+	NULL,
+};
+
+static const struct attribute_group rt_sysfs_attr_group = {
+	.attrs = data_sysfs_attrs,
+};
+
+/*
+ * FPGA Realtime Data Character Device
+ */
+
+static int data_open(struct inode *inode, struct file *filp)
+{
+	/*
+	 * The miscdevice layer puts our struct miscdevice into the
+	 * filp->private_data field. We use this to find our private
+	 * data and then overwrite it with our own private structure.
+	 */
+	struct fpga_device *priv = container_of(filp->private_data,
+						struct fpga_device, miscdev);
+	struct fpga_reader *reader;
+	int ret;
+
+	/* allocate private data */
+	reader = kzalloc(sizeof(*reader), GFP_KERNEL);
+	if (!reader)
+		return -ENOMEM;
+
+	reader->priv = priv;
+	reader->buf = NULL;
+
+	filp->private_data = reader;
+	ret = nonseekable_open(inode, filp);
+	if (ret) {
+		dev_err(priv->dev, "nonseekable-open failed\n");
+		kfree(reader);
+		return ret;
+	}
+
+	/*
+	 * success, increase the reference count of the private data structure
+	 * so that it doesn't disappear if the device is unbound
+	 */
+	kref_get(&priv->ref);
+	return 0;
+}
+
+static int data_release(struct inode *inode, struct file *filp)
+{
+	struct fpga_reader *reader = filp->private_data;
+	struct fpga_device *priv = reader->priv;
+
+	/* free the per-reader structure */
+	data_free_buffer(reader->buf);
+	kfree(reader);
+	filp->private_data = NULL;
+
+	/* decrement our reference count to the private data */
+	kref_put(&priv->ref, fpga_device_release);
+	return 0;
+}
+
+static ssize_t data_read(struct file *filp, char __user *ubuf, size_t count,
+			 loff_t *f_pos)
+{
+	struct fpga_reader *reader = filp->private_data;
+	struct fpga_device *priv = reader->priv;
+	struct list_head *used = &priv->used;
+	struct data_buf *dbuf;
+	size_t avail;
+	void *data;
+	int ret;
+
+	/* check if we already have a partial buffer */
+	if (reader->buf) {
+		dbuf = reader->buf;
+		goto have_buffer;
+	}
+
+	spin_lock_irq(&priv->lock);
+
+	/* Block until there is at least one buffer on the used list */
+	while (list_empty(used)) {
+		spin_unlock_irq(&priv->lock);
+
+		if (filp->f_flags & O_NONBLOCK)
+			return -EAGAIN;
+
+		ret = wait_event_interruptible(priv->wait, !list_empty(used));
+		if (ret)
+			return ret;
+
+		spin_lock_irq(&priv->lock);
+	}
+
+	/* Grab the first buffer off of the used list */
+	dbuf = list_first_entry(used, struct data_buf, entry);
+	list_del_init(&dbuf->entry);
+
+	spin_unlock_irq(&priv->lock);
+
+	/* Buffers are always mapped: unmap it */
+	videobuf_dma_unmap(priv->dev, &dbuf->vb);
+
+	/* save the buffer for later */
+	reader->buf = dbuf;
+	reader->buf_start = 0;
+
+have_buffer:
+	/* Get the number of bytes available */
+	avail = dbuf->size - reader->buf_start;
+	data = dbuf->vb.vaddr + reader->buf_start;
+
+	/* Get the number of bytes we can transfer */
+	count = min(count, avail);
+
+	/* Copy the data to the userspace buffer */
+	if (copy_to_user(ubuf, data, count))
+		return -EFAULT;
+
+	/* Update the amount of available space */
+	avail -= count;
+
+	/*
+	 * If there is still some data available, save the buffer for the
+	 * next userspace call to read() and return
+	 */
+	if (avail > 0) {
+		reader->buf_start += count;
+		reader->buf = dbuf;
+		return count;
+	}
+
+	/*
+	 * Get the buffer ready to be reused for DMA
+	 *
+	 * If it fails, we pretend that the read never happed and return
+	 * -EFAULT to userspace. The read will be retried.
+	 */
+	ret = videobuf_dma_map(priv->dev, &dbuf->vb);
+	if (ret) {
+		dev_err(priv->dev, "unable to remap buffer for DMA\n");
+		return -EFAULT;
+	}
+
+	/* Lock against concurrent enable/disable */
+	spin_lock_irq(&priv->lock);
+
+	/* the reader is finished with this buffer */
+	reader->buf = NULL;
+
+	/*
+	 * One of two things has happened, the device is disabled, or the
+	 * device has been reconfigured underneath us. In either case, we
+	 * should just throw away the buffer.
+	 */
+	if (!priv->enabled || dbuf->size != priv->bufsize) {
+		videobuf_dma_unmap(priv->dev, &dbuf->vb);
+		data_free_buffer(dbuf);
+		goto out_unlock;
+	}
+
+	/* The buffer is safe to reuse, so add it back to the free list */
+	list_add_tail(&dbuf->entry, &priv->free);
+
+out_unlock:
+	spin_unlock_irq(&priv->lock);
+	return count;
+}
+
+static unsigned int data_poll(struct file *filp, struct poll_table_struct *tbl)
+{
+	struct fpga_reader *reader = filp->private_data;
+	struct fpga_device *priv = reader->priv;
+	unsigned int mask = 0;
+
+	poll_wait(filp, &priv->wait, tbl);
+
+	if (!list_empty(&priv->used))
+		mask |= POLLIN | POLLRDNORM;
+
+	return mask;
+}
+
+static int data_mmap(struct file *filp, struct vm_area_struct *vma)
+{
+	struct fpga_reader *reader = filp->private_data;
+	struct fpga_device *priv = reader->priv;
+	unsigned long offset, vsize, psize, addr;
+
+	/* VMA properties */
+	offset = vma->vm_pgoff << PAGE_SHIFT;
+	vsize = vma->vm_end - vma->vm_start;
+	psize = priv->phys_size - offset;
+	addr = (priv->phys_addr + offset) >> PAGE_SHIFT;
+
+	/* Check against the FPGA region's physical memory size */
+	if (vsize > psize) {
+		dev_err(priv->dev, "requested mmap mapping too large\n");
+		return -EINVAL;
+	}
+
+	/* IO memory (stop cacheing) */
+	vma->vm_flags |= VM_IO | VM_RESERVED;
+	vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+
+	return io_remap_pfn_range(vma, vma->vm_start, addr, vsize,
+				  vma->vm_page_prot);
+}
+
+static const struct file_operations data_fops = {
+	.owner		= THIS_MODULE,
+	.open		= data_open,
+	.release	= data_release,
+	.read		= data_read,
+	.poll		= data_poll,
+	.mmap		= data_mmap,
+	.llseek		= no_llseek,
+};
+
+/*
+ * OpenFirmware Device Subsystem
+ */
+
+static bool dma_filter(struct dma_chan *chan, void *data)
+{
+	/*
+	 * DMA Channel #0 is used for the FPGA Programmer, so ignore it
+	 *
+	 * This probably won't survive an unload/load cycle of the Freescale
+	 * DMAEngine driver, but that won't be a problem
+	 */
+	if (chan->chan_id == 0 && chan->device->dev_id == 0)
+		return false;
+
+	return true;
+}
+
+static int data_of_probe(struct platform_device *op,
+			 const struct of_device_id *match)
+{
+	struct device_node *of_node = op->dev.of_node;
+	struct device *this_device;
+	struct fpga_device *priv;
+	struct resource res;
+	dma_cap_mask_t mask;
+	int ret;
+
+	/* Allocate private data */
+	priv = kzalloc(sizeof(*priv), GFP_KERNEL);
+	if (!priv) {
+		dev_err(&op->dev, "Unable to allocate device private data\n");
+		ret = -ENOMEM;
+		goto out_return;
+	}
+
+	dev_set_drvdata(&op->dev, priv);
+	priv->dev = &op->dev;
+	kref_init(&priv->ref);
+	mutex_init(&priv->mutex);
+
+	dev_set_drvdata(priv->dev, priv);
+	spin_lock_init(&priv->lock);
+	INIT_LIST_HEAD(&priv->free);
+	INIT_LIST_HEAD(&priv->used);
+	init_waitqueue_head(&priv->wait);
+
+	/* Setup the misc device */
+	priv->miscdev.minor = MISC_DYNAMIC_MINOR;
+	priv->miscdev.name = drv_name;
+	priv->miscdev.fops = &data_fops;
+
+	/* Get the physical address of the FPGA registers */
+	ret = of_address_to_resource(of_node, 0, &res);
+	if (ret) {
+		dev_err(&op->dev, "Unable to find FPGA physical address\n");
+		ret = -ENODEV;
+		goto out_free_priv;
+	}
+
+	priv->phys_addr = res.start;
+	priv->phys_size = resource_size(&res);
+
+	/* ioremap the registers for use */
+	priv->regs = of_iomap(of_node, 0);
+	if (!priv->regs) {
+		dev_err(&op->dev, "Unable to ioremap registers\n");
+		ret = -ENOMEM;
+		goto out_free_priv;
+	}
+
+	dma_cap_zero(mask);
+	dma_cap_set(DMA_MEMCPY, mask);
+	dma_cap_set(DMA_INTERRUPT, mask);
+	dma_cap_set(DMA_SLAVE, mask);
+	dma_cap_set(DMA_SG, mask);
+
+	/* Request a DMA channel */
+	priv->chan = dma_request_channel(mask, dma_filter, NULL);
+	if (!priv->chan) {
+		dev_err(&op->dev, "Unable to request DMA channel\n");
+		ret = -ENODEV;
+		goto out_unmap_regs;
+	}
+
+	/* Find the correct IRQ number */
+	priv->irq = irq_of_parse_and_map(of_node, 0);
+	if (priv->irq == NO_IRQ) {
+		dev_err(&op->dev, "Unable to find IRQ line\n");
+		ret = -ENODEV;
+		goto out_release_dma;
+	}
+
+	/* Drive the GPIO for FPGA IRQ high (no interrupt) */
+	iowrite32be(IRQ_CORL_DONE, priv->regs + SYS_IRQ_OUTPUT_DATA);
+
+	/* Register the miscdevice */
+	ret = misc_register(&priv->miscdev);
+	if (ret) {
+		dev_err(&op->dev, "Unable to register miscdevice\n");
+		goto out_irq_dispose_mapping;
+	}
+
+	/* Create the debugfs files */
+	ret = data_debugfs_init(priv);
+	if (ret) {
+		dev_err(&op->dev, "Unable to create debugfs files\n");
+		goto out_misc_deregister;
+	}
+
+	/* Create the sysfs files */
+	this_device = priv->miscdev.this_device;
+	dev_set_drvdata(this_device, priv);
+	ret = sysfs_create_group(&this_device->kobj, &rt_sysfs_attr_group);
+	if (ret) {
+		dev_err(&op->dev, "Unable to create sysfs files\n");
+		goto out_data_debugfs_exit;
+	}
+
+	dev_info(&op->dev, "CARMA FPGA Realtime Data Driver Loaded\n");
+	return 0;
+
+out_data_debugfs_exit:
+	data_debugfs_exit(priv);
+out_misc_deregister:
+	misc_deregister(&priv->miscdev);
+out_irq_dispose_mapping:
+	irq_dispose_mapping(priv->irq);
+out_release_dma:
+	dma_release_channel(priv->chan);
+out_unmap_regs:
+	iounmap(priv->regs);
+out_free_priv:
+	kref_put(&priv->ref, fpga_device_release);
+out_return:
+	return ret;
+}
+
+static int data_of_remove(struct platform_device *op)
+{
+	struct fpga_device *priv = dev_get_drvdata(&op->dev);
+	struct device *this_device = priv->miscdev.this_device;
+
+	/* remove all sysfs files, now the device cannot be re-enabled */
+	sysfs_remove_group(&this_device->kobj, &rt_sysfs_attr_group);
+
+	/* remove all debugfs files */
+	data_debugfs_exit(priv);
+
+	/* disable the device from generating data */
+	data_device_disable(priv);
+
+	/* remove the character device to stop new readers from appearing */
+	misc_deregister(&priv->miscdev);
+
+	/* cleanup everything not needed by readers */
+	irq_dispose_mapping(priv->irq);
+	dma_release_channel(priv->chan);
+	iounmap(priv->regs);
+
+	/* release our reference */
+	kref_put(&priv->ref, fpga_device_release);
+	return 0;
+}
+
+static struct of_device_id data_of_match[] = {
+	{ .compatible = "carma,carma-fpga", },
+	{},
+};
+
+static struct of_platform_driver data_of_driver = {
+	.probe		= data_of_probe,
+	.remove		= data_of_remove,
+	.driver		= {
+		.name		= drv_name,
+		.of_match_table	= data_of_match,
+		.owner		= THIS_MODULE,
+	},
+};
+
+/*
+ * Module Init / Exit
+ */
+
+static int __init data_init(void)
+{
+	return of_register_platform_driver(&data_of_driver);
+}
+
+static void __exit data_exit(void)
+{
+	of_unregister_platform_driver(&data_of_driver);
+}
+
+MODULE_AUTHOR("Ira W. Snyder <iws@ovro.caltech.edu>");
+MODULE_DESCRIPTION("CARMA DATA-FPGA Access Driver");
+MODULE_LICENSE("GPL");
+
+module_init(data_init);
+module_exit(data_exit);
diff -druN linux-2.6.39-libre/drivers/misc/carma/carma-fpga-program.c linux-3.0-rc7-libre/drivers/misc/carma/carma-fpga-program.c
--- linux-2.6.39-libre/drivers/misc/carma/carma-fpga-program.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/misc/carma/carma-fpga-program.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,1141 @@
+/*
+ * CARMA Board DATA-FPGA Programmer
+ *
+ * Copyright (c) 2009-2011 Ira W. Snyder <iws@ovro.caltech.edu>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/dma-mapping.h>
+#include <linux/of_platform.h>
+#include <linux/completion.h>
+#include <linux/miscdevice.h>
+#include <linux/dmaengine.h>
+#include <linux/interrupt.h>
+#include <linux/highmem.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/leds.h>
+#include <linux/slab.h>
+#include <linux/kref.h>
+#include <linux/fs.h>
+#include <linux/io.h>
+
+#include <media/videobuf-dma-sg.h>
+
+/* MPC8349EMDS specific get_immrbase() */
+#include <sysdev/fsl_soc.h>
+
+static const char drv_name[] = "carma-fpga-program";
+
+/*
+ * Firmware images are always this exact size
+ *
+ * 12849552 bytes for a CARMA Digitizer Board (EP2S90 FPGAs)
+ * 18662880 bytes for a CARMA Correlator Board (EP2S130 FPGAs)
+ */
+#define FW_SIZE_EP2S90		12849552
+#define FW_SIZE_EP2S130		18662880
+
+struct fpga_dev {
+	struct miscdevice miscdev;
+
+	/* Reference count */
+	struct kref ref;
+
+	/* Device Registers */
+	struct device *dev;
+	void __iomem *regs;
+	void __iomem *immr;
+
+	/* Freescale DMA Device */
+	struct dma_chan *chan;
+
+	/* Interrupts */
+	int irq, status;
+	struct completion completion;
+
+	/* FPGA Bitfile */
+	struct mutex lock;
+
+	struct videobuf_dmabuf vb;
+	bool vb_allocated;
+
+	/* max size and written bytes */
+	size_t fw_size;
+	size_t bytes;
+};
+
+/*
+ * FPGA Bitfile Helpers
+ */
+
+/**
+ * fpga_drop_firmware_data() - drop the bitfile image from memory
+ * @priv: the driver's private data structure
+ *
+ * LOCKING: must hold priv->lock
+ */
+static void fpga_drop_firmware_data(struct fpga_dev *priv)
+{
+	videobuf_dma_free(&priv->vb);
+	priv->vb_allocated = false;
+	priv->bytes = 0;
+}
+
+/*
+ * Private Data Reference Count
+ */
+
+static void fpga_dev_remove(struct kref *ref)
+{
+	struct fpga_dev *priv = container_of(ref, struct fpga_dev, ref);
+
+	/* free any firmware image that was not programmed */
+	fpga_drop_firmware_data(priv);
+
+	mutex_destroy(&priv->lock);
+	kfree(priv);
+}
+
+/*
+ * LED Trigger (could be a seperate module)
+ */
+
+/*
+ * NOTE: this whole thing does have the problem that whenever the led's are
+ * NOTE: first set to use the fpga trigger, they could be in the wrong state
+ */
+
+DEFINE_LED_TRIGGER(ledtrig_fpga);
+
+static void ledtrig_fpga_programmed(bool enabled)
+{
+	if (enabled)
+		led_trigger_event(ledtrig_fpga, LED_FULL);
+	else
+		led_trigger_event(ledtrig_fpga, LED_OFF);
+}
+
+/*
+ * FPGA Register Helpers
+ */
+
+/* Register Definitions */
+#define FPGA_CONFIG_CONTROL		0x40
+#define FPGA_CONFIG_STATUS		0x44
+#define FPGA_CONFIG_FIFO_SIZE		0x48
+#define FPGA_CONFIG_FIFO_USED		0x4C
+#define FPGA_CONFIG_TOTAL_BYTE_COUNT	0x50
+#define FPGA_CONFIG_CUR_BYTE_COUNT	0x54
+
+#define FPGA_FIFO_ADDRESS		0x3000
+
+static int fpga_fifo_size(void __iomem *regs)
+{
+	return ioread32be(regs + FPGA_CONFIG_FIFO_SIZE);
+}
+
+#define CFG_STATUS_ERR_MASK	0xfffe
+
+static int fpga_config_error(void __iomem *regs)
+{
+	return ioread32be(regs + FPGA_CONFIG_STATUS) & CFG_STATUS_ERR_MASK;
+}
+
+static int fpga_fifo_empty(void __iomem *regs)
+{
+	return ioread32be(regs + FPGA_CONFIG_FIFO_USED) == 0;
+}
+
+static void fpga_fifo_write(void __iomem *regs, u32 val)
+{
+	iowrite32be(val, regs + FPGA_FIFO_ADDRESS);
+}
+
+static void fpga_set_byte_count(void __iomem *regs, u32 count)
+{
+	iowrite32be(count, regs + FPGA_CONFIG_TOTAL_BYTE_COUNT);
+}
+
+#define CFG_CTL_ENABLE	(1 << 0)
+#define CFG_CTL_RESET	(1 << 1)
+#define CFG_CTL_DMA	(1 << 2)
+
+static void fpga_programmer_enable(struct fpga_dev *priv, bool dma)
+{
+	u32 val;
+
+	val = (dma) ? (CFG_CTL_ENABLE | CFG_CTL_DMA) : CFG_CTL_ENABLE;
+	iowrite32be(val, priv->regs + FPGA_CONFIG_CONTROL);
+}
+
+static void fpga_programmer_disable(struct fpga_dev *priv)
+{
+	iowrite32be(0x0, priv->regs + FPGA_CONFIG_CONTROL);
+}
+
+static void fpga_dump_registers(struct fpga_dev *priv)
+{
+	u32 control, status, size, used, total, curr;
+
+	/* good status: do nothing */
+	if (priv->status == 0)
+		return;
+
+	/* Dump all status registers */
+	control = ioread32be(priv->regs + FPGA_CONFIG_CONTROL);
+	status = ioread32be(priv->regs + FPGA_CONFIG_STATUS);
+	size = ioread32be(priv->regs + FPGA_CONFIG_FIFO_SIZE);
+	used = ioread32be(priv->regs + FPGA_CONFIG_FIFO_USED);
+	total = ioread32be(priv->regs + FPGA_CONFIG_TOTAL_BYTE_COUNT);
+	curr = ioread32be(priv->regs + FPGA_CONFIG_CUR_BYTE_COUNT);
+
+	dev_err(priv->dev, "Configuration failed, dumping status registers\n");
+	dev_err(priv->dev, "Control:    0x%.8x\n", control);
+	dev_err(priv->dev, "Status:     0x%.8x\n", status);
+	dev_err(priv->dev, "FIFO Size:  0x%.8x\n", size);
+	dev_err(priv->dev, "FIFO Used:  0x%.8x\n", used);
+	dev_err(priv->dev, "FIFO Total: 0x%.8x\n", total);
+	dev_err(priv->dev, "FIFO Curr:  0x%.8x\n", curr);
+}
+
+/*
+ * FPGA Power Supply Code
+ */
+
+#define CTL_PWR_CONTROL		0x2006
+#define CTL_PWR_STATUS		0x200A
+#define CTL_PWR_FAIL		0x200B
+
+#define PWR_CONTROL_ENABLE	0x01
+
+#define PWR_STATUS_ERROR_MASK	0x10
+#define PWR_STATUS_GOOD		0x0f
+
+/*
+ * Determine if the FPGA power is good for all supplies
+ */
+static bool fpga_power_good(struct fpga_dev *priv)
+{
+	u8 val;
+
+	val = ioread8(priv->regs + CTL_PWR_STATUS);
+	if (val & PWR_STATUS_ERROR_MASK)
+		return false;
+
+	return val == PWR_STATUS_GOOD;
+}
+
+/*
+ * Disable the FPGA power supplies
+ */
+static void fpga_disable_power_supplies(struct fpga_dev *priv)
+{
+	unsigned long start;
+	u8 val;
+
+	iowrite8(0x0, priv->regs + CTL_PWR_CONTROL);
+
+	/*
+	 * Wait 500ms for the power rails to discharge
+	 *
+	 * Without this delay, the CTL-CPLD state machine can get into a
+	 * state where it is waiting for the power-goods to assert, but they
+	 * never do. This only happens when enabling and disabling the
+	 * power sequencer very rapidly.
+	 *
+	 * The loop below will also wait for the power goods to de-assert,
+	 * but testing has shown that they are always disabled by the time
+	 * the sleep completes. However, omitting the sleep and only waiting
+	 * for the power-goods to de-assert was not sufficient to ensure
+	 * that the power sequencer would not wedge itself.
+	 */
+	msleep(500);
+
+	start = jiffies;
+	while (time_before(jiffies, start + HZ)) {
+		val = ioread8(priv->regs + CTL_PWR_STATUS);
+		if (!(val & PWR_STATUS_GOOD))
+			break;
+
+		usleep_range(5000, 10000);
+	}
+
+	val = ioread8(priv->regs + CTL_PWR_STATUS);
+	if (val & PWR_STATUS_GOOD) {
+		dev_err(priv->dev, "power disable failed: "
+				   "power goods: status 0x%.2x\n", val);
+	}
+
+	if (val & PWR_STATUS_ERROR_MASK) {
+		dev_err(priv->dev, "power disable failed: "
+				   "alarm bit set: status 0x%.2x\n", val);
+	}
+}
+
+/**
+ * fpga_enable_power_supplies() - enable the DATA-FPGA power supplies
+ * @priv: the driver's private data structure
+ *
+ * Enable the DATA-FPGA power supplies, waiting up to 1 second for
+ * them to enable successfully.
+ *
+ * Returns 0 on success, -ERRNO otherwise
+ */
+static int fpga_enable_power_supplies(struct fpga_dev *priv)
+{
+	unsigned long start = jiffies;
+
+	if (fpga_power_good(priv)) {
+		dev_dbg(priv->dev, "power was already good\n");
+		return 0;
+	}
+
+	iowrite8(PWR_CONTROL_ENABLE, priv->regs + CTL_PWR_CONTROL);
+	while (time_before(jiffies, start + HZ)) {
+		if (fpga_power_good(priv))
+			return 0;
+
+		usleep_range(5000, 10000);
+	}
+
+	return fpga_power_good(priv) ? 0 : -ETIMEDOUT;
+}
+
+/*
+ * Determine if the FPGA power supplies are all enabled
+ */
+static bool fpga_power_enabled(struct fpga_dev *priv)
+{
+	u8 val;
+
+	val = ioread8(priv->regs + CTL_PWR_CONTROL);
+	if (val & PWR_CONTROL_ENABLE)
+		return true;
+
+	return false;
+}
+
+/*
+ * Determine if the FPGA's are programmed and running correctly
+ */
+static bool fpga_running(struct fpga_dev *priv)
+{
+	if (!fpga_power_good(priv))
+		return false;
+
+	/* Check the config done bit */
+	return ioread32be(priv->regs + FPGA_CONFIG_STATUS) & (1 << 18);
+}
+
+/*
+ * FPGA Programming Code
+ */
+
+/**
+ * fpga_program_block() - put a block of data into the programmer's FIFO
+ * @priv: the driver's private data structure
+ * @buf: the data to program
+ * @count: the length of data to program (must be a multiple of 4 bytes)
+ *
+ * Returns 0 on success, -ERRNO otherwise
+ */
+static int fpga_program_block(struct fpga_dev *priv, void *buf, size_t count)
+{
+	u32 *data = buf;
+	int size = fpga_fifo_size(priv->regs);
+	int i, len;
+	unsigned long timeout;
+
+	/* enforce correct data length for the FIFO */
+	BUG_ON(count % 4 != 0);
+
+	while (count > 0) {
+
+		/* Get the size of the block to write (maximum is FIFO_SIZE) */
+		len = min_t(size_t, count, size);
+		timeout = jiffies + HZ / 4;
+
+		/* Write the block */
+		for (i = 0; i < len / 4; i++)
+			fpga_fifo_write(priv->regs, data[i]);
+
+		/* Update the amounts left */
+		count -= len;
+		data += len / 4;
+
+		/* Wait for the fifo to empty */
+		while (true) {
+
+			if (fpga_fifo_empty(priv->regs)) {
+				break;
+			} else {
+				dev_dbg(priv->dev, "Fifo not empty\n");
+				cpu_relax();
+			}
+
+			if (fpga_config_error(priv->regs)) {
+				dev_err(priv->dev, "Error detected\n");
+				return -EIO;
+			}
+
+			if (time_after(jiffies, timeout)) {
+				dev_err(priv->dev, "Fifo drain timeout\n");
+				return -ETIMEDOUT;
+			}
+
+			usleep_range(5000, 10000);
+		}
+	}
+
+	return 0;
+}
+
+/**
+ * fpga_program_cpu() - program the DATA-FPGA's using the CPU
+ * @priv: the driver's private data structure
+ *
+ * This is useful when the DMA programming method fails. It is possible to
+ * wedge the Freescale DMA controller such that the DMA programming method
+ * always fails. This method has always succeeded.
+ *
+ * Returns 0 on success, -ERRNO otherwise
+ */
+static noinline int fpga_program_cpu(struct fpga_dev *priv)
+{
+	int ret;
+
+	/* Disable the programmer */
+	fpga_programmer_disable(priv);
+
+	/* Set the total byte count */
+	fpga_set_byte_count(priv->regs, priv->bytes);
+	dev_dbg(priv->dev, "total byte count %u bytes\n", priv->bytes);
+
+	/* Enable the controller for programming */
+	fpga_programmer_enable(priv, false);
+	dev_dbg(priv->dev, "enabled the controller\n");
+
+	/* Write each chunk of the FPGA bitfile to FPGA programmer */
+	ret = fpga_program_block(priv, priv->vb.vaddr, priv->bytes);
+	if (ret)
+		goto out_disable_controller;
+
+	/* Wait for the interrupt handler to signal that programming finished */
+	ret = wait_for_completion_timeout(&priv->completion, 2 * HZ);
+	if (!ret) {
+		dev_err(priv->dev, "Timed out waiting for completion\n");
+		ret = -ETIMEDOUT;
+		goto out_disable_controller;
+	}
+
+	/* Retrieve the status from the interrupt handler */
+	ret = priv->status;
+
+out_disable_controller:
+	fpga_programmer_disable(priv);
+	return ret;
+}
+
+#define FIFO_DMA_ADDRESS	0xf0003000
+#define FIFO_MAX_LEN		4096
+
+/**
+ * fpga_program_dma() - program the DATA-FPGA's using the DMA engine
+ * @priv: the driver's private data structure
+ *
+ * Program the DATA-FPGA's using the Freescale DMA engine. This requires that
+ * the engine is programmed such that the hardware DMA request lines can
+ * control the entire DMA transaction. The system controller FPGA then
+ * completely offloads the programming from the CPU.
+ *
+ * Returns 0 on success, -ERRNO otherwise
+ */
+static noinline int fpga_program_dma(struct fpga_dev *priv)
+{
+	struct videobuf_dmabuf *vb = &priv->vb;
+	struct dma_chan *chan = priv->chan;
+	struct dma_async_tx_descriptor *tx;
+	size_t num_pages, len, avail = 0;
+	struct dma_slave_config config;
+	struct scatterlist *sg;
+	struct sg_table table;
+	dma_cookie_t cookie;
+	int ret, i;
+
+	/* Disable the programmer */
+	fpga_programmer_disable(priv);
+
+	/* Allocate a scatterlist for the DMA destination */
+	num_pages = DIV_ROUND_UP(priv->bytes, FIFO_MAX_LEN);
+	ret = sg_alloc_table(&table, num_pages, GFP_KERNEL);
+	if (ret) {
+		dev_err(priv->dev, "Unable to allocate dst scatterlist\n");
+		ret = -ENOMEM;
+		goto out_return;
+	}
+
+	/*
+	 * This is an ugly hack
+	 *
+	 * We fill in a scatterlist as if it were mapped for DMA. This is
+	 * necessary because there exists no better structure for this
+	 * inside the kernel code.
+	 *
+	 * As an added bonus, we can use the DMAEngine API for all of this,
+	 * rather than inventing another extremely similar API.
+	 */
+	avail = priv->bytes;
+	for_each_sg(table.sgl, sg, num_pages, i) {
+		len = min_t(size_t, avail, FIFO_MAX_LEN);
+		sg_dma_address(sg) = FIFO_DMA_ADDRESS;
+		sg_dma_len(sg) = len;
+
+		avail -= len;
+	}
+
+	/* Map the buffer for DMA */
+	ret = videobuf_dma_map(priv->dev, &priv->vb);
+	if (ret) {
+		dev_err(priv->dev, "Unable to map buffer for DMA\n");
+		goto out_free_table;
+	}
+
+	/*
+	 * Configure the DMA channel to transfer FIFO_SIZE / 2 bytes per
+	 * transaction, and then put it under external control
+	 */
+	memset(&config, 0, sizeof(config));
+	config.direction = DMA_TO_DEVICE;
+	config.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
+	config.dst_maxburst = fpga_fifo_size(priv->regs) / 2 / 4;
+	ret = chan->device->device_control(chan, DMA_SLAVE_CONFIG,
+					   (unsigned long)&config);
+	if (ret) {
+		dev_err(priv->dev, "DMA slave configuration failed\n");
+		goto out_dma_unmap;
+	}
+
+	ret = chan->device->device_control(chan, FSLDMA_EXTERNAL_START, 1);
+	if (ret) {
+		dev_err(priv->dev, "DMA external control setup failed\n");
+		goto out_dma_unmap;
+	}
+
+	/* setup and submit the DMA transaction */
+	tx = chan->device->device_prep_dma_sg(chan,
+					      table.sgl, num_pages,
+					      vb->sglist, vb->sglen, 0);
+	if (!tx) {
+		dev_err(priv->dev, "Unable to prep DMA transaction\n");
+		ret = -ENOMEM;
+		goto out_dma_unmap;
+	}
+
+	cookie = tx->tx_submit(tx);
+	if (dma_submit_error(cookie)) {
+		dev_err(priv->dev, "Unable to submit DMA transaction\n");
+		ret = -ENOMEM;
+		goto out_dma_unmap;
+	}
+
+	dma_async_memcpy_issue_pending(chan);
+
+	/* Set the total byte count */
+	fpga_set_byte_count(priv->regs, priv->bytes);
+	dev_dbg(priv->dev, "total byte count %u bytes\n", priv->bytes);
+
+	/* Enable the controller for DMA programming */
+	fpga_programmer_enable(priv, true);
+	dev_dbg(priv->dev, "enabled the controller\n");
+
+	/* Wait for the interrupt handler to signal that programming finished */
+	ret = wait_for_completion_timeout(&priv->completion, 2 * HZ);
+	if (!ret) {
+		dev_err(priv->dev, "Timed out waiting for completion\n");
+		ret = -ETIMEDOUT;
+		goto out_disable_controller;
+	}
+
+	/* Retrieve the status from the interrupt handler */
+	ret = priv->status;
+
+out_disable_controller:
+	fpga_programmer_disable(priv);
+out_dma_unmap:
+	videobuf_dma_unmap(priv->dev, vb);
+out_free_table:
+	sg_free_table(&table);
+out_return:
+	return ret;
+}
+
+/*
+ * Interrupt Handling
+ */
+
+static irqreturn_t fpga_irq(int irq, void *dev_id)
+{
+	struct fpga_dev *priv = dev_id;
+
+	/* Save the status */
+	priv->status = fpga_config_error(priv->regs) ? -EIO : 0;
+	dev_dbg(priv->dev, "INTERRUPT status %d\n", priv->status);
+	fpga_dump_registers(priv);
+
+	/* Disabling the programmer clears the interrupt */
+	fpga_programmer_disable(priv);
+
+	/* Notify any waiters */
+	complete(&priv->completion);
+
+	return IRQ_HANDLED;
+}
+
+/*
+ * SYSFS Helpers
+ */
+
+/**
+ * fpga_do_stop() - deconfigure (reset) the DATA-FPGA's
+ * @priv: the driver's private data structure
+ *
+ * LOCKING: must hold priv->lock
+ */
+static int fpga_do_stop(struct fpga_dev *priv)
+{
+	u32 val;
+
+	/* Set the led to unprogrammed */
+	ledtrig_fpga_programmed(false);
+
+	/* Pulse the config line to reset the FPGA's */
+	val = CFG_CTL_ENABLE | CFG_CTL_RESET;
+	iowrite32be(val, priv->regs + FPGA_CONFIG_CONTROL);
+	iowrite32be(0x0, priv->regs + FPGA_CONFIG_CONTROL);
+
+	return 0;
+}
+
+static noinline int fpga_do_program(struct fpga_dev *priv)
+{
+	int ret;
+
+	if (priv->bytes != priv->fw_size) {
+		dev_err(priv->dev, "Incorrect bitfile size: got %zu bytes, "
+				   "should be %zu bytes\n",
+				   priv->bytes, priv->fw_size);
+		return -EINVAL;
+	}
+
+	if (!fpga_power_enabled(priv)) {
+		dev_err(priv->dev, "Power not enabled\n");
+		return -EINVAL;
+	}
+
+	if (!fpga_power_good(priv)) {
+		dev_err(priv->dev, "Power not good\n");
+		return -EINVAL;
+	}
+
+	/* Set the LED to unprogrammed */
+	ledtrig_fpga_programmed(false);
+
+	/* Try to program the FPGA's using DMA */
+	ret = fpga_program_dma(priv);
+
+	/* If DMA failed or doesn't exist, try with CPU */
+	if (ret) {
+		dev_warn(priv->dev, "Falling back to CPU programming\n");
+		ret = fpga_program_cpu(priv);
+	}
+
+	if (ret) {
+		dev_err(priv->dev, "Unable to program FPGA's\n");
+		return ret;
+	}
+
+	/* Drop the firmware bitfile from memory */
+	fpga_drop_firmware_data(priv);
+
+	dev_dbg(priv->dev, "FPGA programming successful\n");
+	ledtrig_fpga_programmed(true);
+
+	return 0;
+}
+
+/*
+ * File Operations
+ */
+
+static int fpga_open(struct inode *inode, struct file *filp)
+{
+	/*
+	 * The miscdevice layer puts our struct miscdevice into the
+	 * filp->private_data field. We use this to find our private
+	 * data and then overwrite it with our own private structure.
+	 */
+	struct fpga_dev *priv = container_of(filp->private_data,
+					     struct fpga_dev, miscdev);
+	unsigned int nr_pages;
+	int ret;
+
+	/* We only allow one process at a time */
+	ret = mutex_lock_interruptible(&priv->lock);
+	if (ret)
+		return ret;
+
+	filp->private_data = priv;
+	kref_get(&priv->ref);
+
+	/* Truncation: drop any existing data */
+	if (filp->f_flags & O_TRUNC)
+		priv->bytes = 0;
+
+	/* Check if we have already allocated a buffer */
+	if (priv->vb_allocated)
+		return 0;
+
+	/* Allocate a buffer to hold enough data for the bitfile */
+	nr_pages = DIV_ROUND_UP(priv->fw_size, PAGE_SIZE);
+	ret = videobuf_dma_init_kernel(&priv->vb, DMA_TO_DEVICE, nr_pages);
+	if (ret) {
+		dev_err(priv->dev, "unable to allocate data buffer\n");
+		mutex_unlock(&priv->lock);
+		kref_put(&priv->ref, fpga_dev_remove);
+		return ret;
+	}
+
+	priv->vb_allocated = true;
+	return 0;
+}
+
+static int fpga_release(struct inode *inode, struct file *filp)
+{
+	struct fpga_dev *priv = filp->private_data;
+
+	mutex_unlock(&priv->lock);
+	kref_put(&priv->ref, fpga_dev_remove);
+	return 0;
+}
+
+static ssize_t fpga_write(struct file *filp, const char __user *buf,
+			  size_t count, loff_t *f_pos)
+{
+	struct fpga_dev *priv = filp->private_data;
+
+	/* FPGA bitfiles have an exact size: disallow anything else */
+	if (priv->bytes >= priv->fw_size)
+		return -ENOSPC;
+
+	count = min_t(size_t, priv->fw_size - priv->bytes, count);
+	if (copy_from_user(priv->vb.vaddr + priv->bytes, buf, count))
+		return -EFAULT;
+
+	priv->bytes += count;
+	return count;
+}
+
+static ssize_t fpga_read(struct file *filp, char __user *buf, size_t count,
+			 loff_t *f_pos)
+{
+	struct fpga_dev *priv = filp->private_data;
+
+	count = min_t(size_t, priv->bytes - *f_pos, count);
+	if (copy_to_user(buf, priv->vb.vaddr + *f_pos, count))
+		return -EFAULT;
+
+	*f_pos += count;
+	return count;
+}
+
+static loff_t fpga_llseek(struct file *filp, loff_t offset, int origin)
+{
+	struct fpga_dev *priv = filp->private_data;
+	loff_t newpos;
+
+	/* only read-only opens are allowed to seek */
+	if ((filp->f_flags & O_ACCMODE) != O_RDONLY)
+		return -EINVAL;
+
+	switch (origin) {
+	case SEEK_SET: /* seek relative to the beginning of the file */
+		newpos = offset;
+		break;
+	case SEEK_CUR: /* seek relative to current position in the file */
+		newpos = filp->f_pos + offset;
+		break;
+	case SEEK_END: /* seek relative to the end of the file */
+		newpos = priv->fw_size - offset;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	/* check for sanity */
+	if (newpos > priv->fw_size)
+		return -EINVAL;
+
+	filp->f_pos = newpos;
+	return newpos;
+}
+
+static const struct file_operations fpga_fops = {
+	.open		= fpga_open,
+	.release	= fpga_release,
+	.write		= fpga_write,
+	.read		= fpga_read,
+	.llseek		= fpga_llseek,
+};
+
+/*
+ * Device Attributes
+ */
+
+static ssize_t pfail_show(struct device *dev, struct device_attribute *attr,
+			  char *buf)
+{
+	struct fpga_dev *priv = dev_get_drvdata(dev);
+	u8 val;
+
+	val = ioread8(priv->regs + CTL_PWR_FAIL);
+	return snprintf(buf, PAGE_SIZE, "0x%.2x\n", val);
+}
+
+static ssize_t pgood_show(struct device *dev, struct device_attribute *attr,
+			  char *buf)
+{
+	struct fpga_dev *priv = dev_get_drvdata(dev);
+	return snprintf(buf, PAGE_SIZE, "%d\n", fpga_power_good(priv));
+}
+
+static ssize_t penable_show(struct device *dev, struct device_attribute *attr,
+			    char *buf)
+{
+	struct fpga_dev *priv = dev_get_drvdata(dev);
+	return snprintf(buf, PAGE_SIZE, "%d\n", fpga_power_enabled(priv));
+}
+
+static ssize_t penable_store(struct device *dev, struct device_attribute *attr,
+			     const char *buf, size_t count)
+{
+	struct fpga_dev *priv = dev_get_drvdata(dev);
+	unsigned long val;
+	int ret;
+
+	if (strict_strtoul(buf, 0, &val))
+		return -EINVAL;
+
+	if (val) {
+		ret = fpga_enable_power_supplies(priv);
+		if (ret)
+			return ret;
+	} else {
+		fpga_do_stop(priv);
+		fpga_disable_power_supplies(priv);
+	}
+
+	return count;
+}
+
+static ssize_t program_show(struct device *dev, struct device_attribute *attr,
+			    char *buf)
+{
+	struct fpga_dev *priv = dev_get_drvdata(dev);
+	return snprintf(buf, PAGE_SIZE, "%d\n", fpga_running(priv));
+}
+
+static ssize_t program_store(struct device *dev, struct device_attribute *attr,
+			     const char *buf, size_t count)
+{
+	struct fpga_dev *priv = dev_get_drvdata(dev);
+	unsigned long val;
+	int ret;
+
+	if (strict_strtoul(buf, 0, &val))
+		return -EINVAL;
+
+	/* We can't have an image writer and be programming simultaneously */
+	if (mutex_lock_interruptible(&priv->lock))
+		return -ERESTARTSYS;
+
+	/* Program or Reset the FPGA's */
+	ret = val ? fpga_do_program(priv) : fpga_do_stop(priv);
+	if (ret)
+		goto out_unlock;
+
+	/* Success */
+	ret = count;
+
+out_unlock:
+	mutex_unlock(&priv->lock);
+	return ret;
+}
+
+static DEVICE_ATTR(power_fail, S_IRUGO, pfail_show, NULL);
+static DEVICE_ATTR(power_good, S_IRUGO, pgood_show, NULL);
+static DEVICE_ATTR(power_enable, S_IRUGO | S_IWUSR,
+		   penable_show, penable_store);
+
+static DEVICE_ATTR(program, S_IRUGO | S_IWUSR,
+		   program_show, program_store);
+
+static struct attribute *fpga_attributes[] = {
+	&dev_attr_power_fail.attr,
+	&dev_attr_power_good.attr,
+	&dev_attr_power_enable.attr,
+	&dev_attr_program.attr,
+	NULL,
+};
+
+static const struct attribute_group fpga_attr_group = {
+	.attrs = fpga_attributes,
+};
+
+/*
+ * OpenFirmware Device Subsystem
+ */
+
+#define SYS_REG_VERSION		0x00
+#define SYS_REG_GEOGRAPHIC	0x10
+
+static bool dma_filter(struct dma_chan *chan, void *data)
+{
+	/*
+	 * DMA Channel #0 is the only acceptable device
+	 *
+	 * This probably won't survive an unload/load cycle of the Freescale
+	 * DMAEngine driver, but that won't be a problem
+	 */
+	return chan->chan_id == 0 && chan->device->dev_id == 0;
+}
+
+static int fpga_of_remove(struct platform_device *op)
+{
+	struct fpga_dev *priv = dev_get_drvdata(&op->dev);
+	struct device *this_device = priv->miscdev.this_device;
+
+	sysfs_remove_group(&this_device->kobj, &fpga_attr_group);
+	misc_deregister(&priv->miscdev);
+
+	free_irq(priv->irq, priv);
+	irq_dispose_mapping(priv->irq);
+
+	/* make sure the power supplies are off */
+	fpga_disable_power_supplies(priv);
+
+	/* unmap registers */
+	iounmap(priv->immr);
+	iounmap(priv->regs);
+
+	dma_release_channel(priv->chan);
+
+	/* drop our reference to the private data structure */
+	kref_put(&priv->ref, fpga_dev_remove);
+	return 0;
+}
+
+/* CTL-CPLD Version Register */
+#define CTL_CPLD_VERSION	0x2000
+
+static int fpga_of_probe(struct platform_device *op,
+			 const struct of_device_id *match)
+{
+	struct device_node *of_node = op->dev.of_node;
+	struct device *this_device;
+	struct fpga_dev *priv;
+	dma_cap_mask_t mask;
+	u32 ver;
+	int ret;
+
+	/* Allocate private data */
+	priv = kzalloc(sizeof(*priv), GFP_KERNEL);
+	if (!priv) {
+		dev_err(&op->dev, "Unable to allocate private data\n");
+		ret = -ENOMEM;
+		goto out_return;
+	}
+
+	/* Setup the miscdevice */
+	priv->miscdev.minor = MISC_DYNAMIC_MINOR;
+	priv->miscdev.name = drv_name;
+	priv->miscdev.fops = &fpga_fops;
+
+	kref_init(&priv->ref);
+
+	dev_set_drvdata(&op->dev, priv);
+	priv->dev = &op->dev;
+	mutex_init(&priv->lock);
+	init_completion(&priv->completion);
+	videobuf_dma_init(&priv->vb);
+
+	dev_set_drvdata(priv->dev, priv);
+	dma_cap_zero(mask);
+	dma_cap_set(DMA_MEMCPY, mask);
+	dma_cap_set(DMA_INTERRUPT, mask);
+	dma_cap_set(DMA_SLAVE, mask);
+	dma_cap_set(DMA_SG, mask);
+
+	/* Get control of DMA channel #0 */
+	priv->chan = dma_request_channel(mask, dma_filter, NULL);
+	if (!priv->chan) {
+		dev_err(&op->dev, "Unable to acquire DMA channel #0\n");
+		ret = -ENODEV;
+		goto out_free_priv;
+	}
+
+	/* Remap the registers for use */
+	priv->regs = of_iomap(of_node, 0);
+	if (!priv->regs) {
+		dev_err(&op->dev, "Unable to ioremap registers\n");
+		ret = -ENOMEM;
+		goto out_dma_release_channel;
+	}
+
+	/* Remap the IMMR for use */
+	priv->immr = ioremap(get_immrbase(), 0x100000);
+	if (!priv->immr) {
+		dev_err(&op->dev, "Unable to ioremap IMMR\n");
+		ret = -ENOMEM;
+		goto out_unmap_regs;
+	}
+
+	/*
+	 * Check that external DMA is configured
+	 *
+	 * U-Boot does this for us, but we should check it and bail out if
+	 * there is a problem. Failing to have this register setup correctly
+	 * will cause the DMA controller to transfer a single cacheline
+	 * worth of data, then wedge itself.
+	 */
+	if ((ioread32be(priv->immr + 0x114) & 0xE00) != 0xE00) {
+		dev_err(&op->dev, "External DMA control not configured\n");
+		ret = -ENODEV;
+		goto out_unmap_immr;
+	}
+
+	/*
+	 * Check the CTL-CPLD version
+	 *
+	 * This driver uses the CTL-CPLD DATA-FPGA power sequencer, and we
+	 * don't want to run on any version of the CTL-CPLD that does not use
+	 * a compatible register layout.
+	 *
+	 * v2: changed register layout, added power sequencer
+	 * v3: added glitch filter on the i2c overcurrent/overtemp outputs
+	 */
+	ver = ioread8(priv->regs + CTL_CPLD_VERSION);
+	if (ver != 0x02 && ver != 0x03) {
+		dev_err(&op->dev, "CTL-CPLD is not version 0x02 or 0x03!\n");
+		ret = -ENODEV;
+		goto out_unmap_immr;
+	}
+
+	/* Set the exact size that the firmware image should be */
+	ver = ioread32be(priv->regs + SYS_REG_VERSION);
+	priv->fw_size = (ver & (1 << 18)) ? FW_SIZE_EP2S130 : FW_SIZE_EP2S90;
+
+	/* Find the correct IRQ number */
+	priv->irq = irq_of_parse_and_map(of_node, 0);
+	if (priv->irq == NO_IRQ) {
+		dev_err(&op->dev, "Unable to find IRQ line\n");
+		ret = -ENODEV;
+		goto out_unmap_immr;
+	}
+
+	/* Request the IRQ */
+	ret = request_irq(priv->irq, fpga_irq, IRQF_SHARED, drv_name, priv);
+	if (ret) {
+		dev_err(&op->dev, "Unable to request IRQ %d\n", priv->irq);
+		ret = -ENODEV;
+		goto out_irq_dispose_mapping;
+	}
+
+	/* Reset and stop the FPGA's, just in case */
+	fpga_do_stop(priv);
+
+	/* Register the miscdevice */
+	ret = misc_register(&priv->miscdev);
+	if (ret) {
+		dev_err(&op->dev, "Unable to register miscdevice\n");
+		goto out_free_irq;
+	}
+
+	/* Create the sysfs files */
+	this_device = priv->miscdev.this_device;
+	dev_set_drvdata(this_device, priv);
+	ret = sysfs_create_group(&this_device->kobj, &fpga_attr_group);
+	if (ret) {
+		dev_err(&op->dev, "Unable to create sysfs files\n");
+		goto out_misc_deregister;
+	}
+
+	dev_info(priv->dev, "CARMA FPGA Programmer: %s rev%s with %s FPGAs\n",
+			(ver & (1 << 17)) ? "Correlator" : "Digitizer",
+			(ver & (1 << 16)) ? "B" : "A",
+			(ver & (1 << 18)) ? "EP2S130" : "EP2S90");
+
+	return 0;
+
+out_misc_deregister:
+	misc_deregister(&priv->miscdev);
+out_free_irq:
+	free_irq(priv->irq, priv);
+out_irq_dispose_mapping:
+	irq_dispose_mapping(priv->irq);
+out_unmap_immr:
+	iounmap(priv->immr);
+out_unmap_regs:
+	iounmap(priv->regs);
+out_dma_release_channel:
+	dma_release_channel(priv->chan);
+out_free_priv:
+	kref_put(&priv->ref, fpga_dev_remove);
+out_return:
+	return ret;
+}
+
+static struct of_device_id fpga_of_match[] = {
+	{ .compatible = "carma,fpga-programmer", },
+	{},
+};
+
+static struct of_platform_driver fpga_of_driver = {
+	.probe		= fpga_of_probe,
+	.remove		= fpga_of_remove,
+	.driver		= {
+		.name		= drv_name,
+		.of_match_table	= fpga_of_match,
+		.owner		= THIS_MODULE,
+	},
+};
+
+/*
+ * Module Init / Exit
+ */
+
+static int __init fpga_init(void)
+{
+	led_trigger_register_simple("fpga", &ledtrig_fpga);
+	return of_register_platform_driver(&fpga_of_driver);
+}
+
+static void __exit fpga_exit(void)
+{
+	of_unregister_platform_driver(&fpga_of_driver);
+	led_trigger_unregister_simple(ledtrig_fpga);
+}
+
+MODULE_AUTHOR("Ira W. Snyder <iws@ovro.caltech.edu>");
+MODULE_DESCRIPTION("CARMA Board DATA-FPGA Programmer");
+MODULE_LICENSE("GPL");
+
+module_init(fpga_init);
+module_exit(fpga_exit);
diff -druN linux-2.6.39-libre/drivers/misc/carma/Kconfig linux-3.0-rc7-libre/drivers/misc/carma/Kconfig
--- linux-2.6.39-libre/drivers/misc/carma/Kconfig	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/misc/carma/Kconfig	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,17 @@
+config CARMA_FPGA
+	tristate "CARMA DATA-FPGA Access Driver"
+	depends on FSL_SOC && PPC_83xx && MEDIA_SUPPORT && HAS_DMA && FSL_DMA
+	select VIDEOBUF_DMA_SG
+	default n
+	help
+	  Say Y here to include support for communicating with the data
+	  processing FPGAs on the OVRO CARMA board.
+
+config CARMA_FPGA_PROGRAM
+	tristate "CARMA DATA-FPGA Programmer"
+	depends on FSL_SOC && PPC_83xx && MEDIA_SUPPORT && HAS_DMA && FSL_DMA
+	select VIDEOBUF_DMA_SG
+	default n
+	help
+	  Say Y here to include support for programming the data processing
+	  FPGAs on the OVRO CARMA board.
diff -druN linux-2.6.39-libre/drivers/misc/carma/Makefile linux-3.0-rc7-libre/drivers/misc/carma/Makefile
--- linux-2.6.39-libre/drivers/misc/carma/Makefile	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/misc/carma/Makefile	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,2 @@
+obj-$(CONFIG_CARMA_FPGA)		+= carma-fpga.o
+obj-$(CONFIG_CARMA_FPGA_PROGRAM)	+= carma-fpga-program.o
diff -druN linux-2.6.39-libre/drivers/misc/cb710/sgbuf2.c linux-3.0-rc7-libre/drivers/misc/cb710/sgbuf2.c
--- linux-2.6.39-libre/drivers/misc/cb710/sgbuf2.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/misc/cb710/sgbuf2.c	2011-07-11 19:51:52.000000000 -0400
@@ -47,7 +47,7 @@
 
 static inline bool needs_unaligned_copy(const void *ptr)
 {
-#ifdef HAVE_EFFICIENT_UNALIGNED_ACCESS
+#ifdef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS
 	return false;
 #else
 	return ((ptr - NULL) & 3) != 0;
diff -druN linux-2.6.39-libre/drivers/misc/cs5535-mfgpt.c linux-3.0-rc7-libre/drivers/misc/cs5535-mfgpt.c
--- linux-2.6.39-libre/drivers/misc/cs5535-mfgpt.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/misc/cs5535-mfgpt.c	2011-07-11 19:51:52.000000000 -0400
@@ -174,7 +174,7 @@
 		timer_nr = t < max ? (int) t : -1;
 	} else {
 		/* check if the requested timer's available */
-		if (test_bit(timer_nr, mfgpt->avail))
+		if (!test_bit(timer_nr, mfgpt->avail))
 			timer_nr = -1;
 	}
 
@@ -329,7 +329,7 @@
 	return err;
 }
 
-static struct platform_driver cs5535_mfgpt_drv = {
+static struct platform_driver cs5535_mfgpt_driver = {
 	.driver = {
 		.name = DRV_NAME,
 		.owner = THIS_MODULE,
@@ -340,7 +340,7 @@
 
 static int __init cs5535_mfgpt_init(void)
 {
-	return platform_driver_register(&cs5535_mfgpt_drv);
+	return platform_driver_register(&cs5535_mfgpt_driver);
 }
 
 module_init(cs5535_mfgpt_init);
diff -druN linux-2.6.39-libre/drivers/misc/ibmasm/ibmasmfs.c linux-3.0-rc7-libre/drivers/misc/ibmasm/ibmasmfs.c
--- linux-2.6.39-libre/drivers/misc/ibmasm/ibmasmfs.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/misc/ibmasm/ibmasmfs.c	2011-07-11 19:51:52.000000000 -0400
@@ -29,7 +29,7 @@
 
 /*
  * The IBMASM file virtual filesystem. It creates the following hierarchy
- * dymamically when mounted from user space:
+ * dynamically when mounted from user space:
  *
  *    /ibmasm
  *    |-- 0
diff -druN linux-2.6.39-libre/drivers/misc/ioc4.c linux-3.0-rc7-libre/drivers/misc/ioc4.c
--- linux-2.6.39-libre/drivers/misc/ioc4.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/misc/ioc4.c	2011-07-11 19:51:52.000000000 -0400
@@ -270,7 +270,7 @@
 	return IOC4_VARIANT_PCI_RT;
 }
 
-static void __devinit
+static void
 ioc4_load_modules(struct work_struct *work)
 {
 	request_module("sgiioc4");
diff -druN linux-2.6.39-libre/drivers/misc/Kconfig linux-3.0-rc7-libre/drivers/misc/Kconfig
--- linux-2.6.39-libre/drivers/misc/Kconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/misc/Kconfig	2011-07-11 19:51:52.000000000 -0400
@@ -144,6 +144,19 @@
 	  If you choose to build module, its name will be phantom. If unsure,
 	  say N here.
 
+config INTEL_MID_PTI
+	tristate "Parallel Trace Interface for MIPI P1149.7 cJTAG standard"
+	default n
+	help
+	  The PTI (Parallel Trace Interface) driver directs
+	  trace data routed from various parts in the system out
+	  through an Intel Penwell PTI port and out of the mobile
+	  device for analysis with a debugging tool (Lauterbach or Fido).
+
+	  You should select this driver if the target kernel is meant for
+	  an Intel Atom (non-netbook) mobile device containing a MIPI
+	  P1149.7 standard implementation.
+
 config SGI_IOC4
 	tristate "SGI IOC4 Base IO support"
 	depends on PCI
@@ -459,7 +472,7 @@
 	  module will be called bmp085.
 
 config PCH_PHUB
-	tristate "PCH Packet Hub of Intel Topcliff / OKI SEMICONDUCTOR ML7213"
+	tristate "Intel EG20T PCH / OKI SEMICONDUCTOR IOH(ML7213/ML7223) PHUB"
 	depends on PCI
 	help
 	  This driver is for PCH(Platform controller Hub) PHUB(Packet Hub) of
@@ -467,10 +480,12 @@
 	  processor. The Topcliff has MAC address and Option ROM data in SROM.
 	  This driver can access MAC address and Option ROM data in SROM.
 
-	  This driver also can be used for OKI SEMICONDUCTOR's ML7213 which is
-	  for IVI(In-Vehicle Infotainment) use.
-	  ML7213 is companion chip for Intel Atom E6xx series.
-	  ML7213 is completely compatible for Intel EG20T PCH.
+	  This driver also can be used for OKI SEMICONDUCTOR IOH(Input/
+	  Output Hub), ML7213 and ML7223.
+	  ML7213 IOH is for IVI(In-Vehicle Infotainment) use and ML7223 IOH is
+	  for MP(Media Phone) use.
+	  ML7213/ML7223 is companion chip for Intel Atom E6xx series.
+	  ML7213/ML7223 is completely compatible for Intel EG20T PCH.
 
 	  To compile this driver as a module, choose M here: the module will
 	  be called pch_phub.
@@ -481,5 +496,6 @@
 source "drivers/misc/iwmc3200top/Kconfig"
 source "drivers/misc/ti-st/Kconfig"
 source "drivers/misc/lis3lv02d/Kconfig"
+source "drivers/misc/carma/Kconfig"
 
 endif # MISC_DEVICES
diff -druN linux-2.6.39-libre/drivers/misc/kgdbts.c linux-3.0-rc7-libre/drivers/misc/kgdbts.c
--- linux-2.6.39-libre/drivers/misc/kgdbts.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/misc/kgdbts.c	2011-07-11 19:51:52.000000000 -0400
@@ -285,32 +285,28 @@
 static int check_and_rewind_pc(char *put_str, char *arg)
 {
 	unsigned long addr = lookup_addr(arg);
+	unsigned long ip;
 	int offset = 0;
 
 	kgdb_hex2mem(&put_str[1], (char *)kgdbts_gdb_regs,
 		 NUMREGBYTES);
 	gdb_regs_to_pt_regs(kgdbts_gdb_regs, &kgdbts_regs);
-	v2printk("Stopped at IP: %lx\n", instruction_pointer(&kgdbts_regs));
-#ifdef CONFIG_X86
-	/* 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;
+	ip = instruction_pointer(&kgdbts_regs);
+	v2printk("Stopped at IP: %lx\n", ip);
+#ifdef GDB_ADJUSTS_BREAK_OFFSET
+	/* On some arches, a breakpoint stop requires it to be decremented */
+	if (addr + BREAK_INSTR_SIZE == ip)
+		offset = -BREAK_INSTR_SIZE;
 #endif
-	if (strcmp(arg, "silent") &&
-		instruction_pointer(&kgdbts_regs) + offset != addr) {
+	if (strcmp(arg, "silent") && ip + offset != addr) {
 		eprintk("kgdbts: BP mismatch %lx expected %lx\n",
-			   instruction_pointer(&kgdbts_regs) + offset, addr);
+			   ip + offset, addr);
 		return 1;
 	}
-#ifdef CONFIG_X86
-	/* On x86 adjust the instruction pointer if needed */
-	kgdbts_regs.ip += offset;
-#elif defined(CONFIG_SUPERH)
-	kgdbts_regs.pc += offset;
+	/* Readjust the instruction pointer if needed */
+	ip += offset;
+#ifdef GDB_ADJUSTS_BREAK_OFFSET
+	instruction_pointer_set(&kgdbts_regs, ip);
 #endif
 	return 0;
 }
diff -druN linux-2.6.39-libre/drivers/misc/lkdtm.c linux-3.0-rc7-libre/drivers/misc/lkdtm.c
--- linux-2.6.39-libre/drivers/misc/lkdtm.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/misc/lkdtm.c	2011-07-11 19:51:52.000000000 -0400
@@ -120,6 +120,7 @@
 static enum cname cpoint = CN_INVALID;
 static enum ctype cptype = CT_NONE;
 static int count = DEFAULT_COUNT;
+static DEFINE_SPINLOCK(count_lock);
 
 module_param(recur_count, int, 0644);
 MODULE_PARM_DESC(recur_count, " Recursion level for the stack overflow test, "\
@@ -230,11 +231,14 @@
 static int lkdtm_parse_commandline(void)
 {
 	int i;
+	unsigned long flags;
 
 	if (cpoint_count < 1 || recur_count < 1)
 		return -EINVAL;
 
+	spin_lock_irqsave(&count_lock, flags);
 	count = cpoint_count;
+	spin_unlock_irqrestore(&count_lock, flags);
 
 	/* No special parameters */
 	if (!cpoint_type && !cpoint_name)
@@ -349,6 +353,9 @@
 
 static void lkdtm_handler(void)
 {
+	unsigned long flags;
+
+	spin_lock_irqsave(&count_lock, flags);
 	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);
@@ -357,6 +364,7 @@
 		lkdtm_do_action(cptype);
 		count = cpoint_count;
 	}
+	spin_unlock_irqrestore(&count_lock, flags);
 }
 
 static int lkdtm_register_cpoint(enum cname which)
diff -druN linux-2.6.39-libre/drivers/misc/Makefile linux-3.0-rc7-libre/drivers/misc/Makefile
--- linux-2.6.39-libre/drivers/misc/Makefile	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/misc/Makefile	2011-07-11 19:51:52.000000000 -0400
@@ -6,6 +6,7 @@
 obj-$(CONFIG_AD525X_DPOT)	+= ad525x_dpot.o
 obj-$(CONFIG_AD525X_DPOT_I2C)	+= ad525x_dpot-i2c.o
 obj-$(CONFIG_AD525X_DPOT_SPI)	+= ad525x_dpot-spi.o
+0bj-$(CONFIG_INTEL_MID_PTI)	+= pti.o
 obj-$(CONFIG_ATMEL_PWM)		+= atmel_pwm.o
 obj-$(CONFIG_ATMEL_SSC)		+= atmel-ssc.o
 obj-$(CONFIG_ATMEL_TCLIB)	+= atmel_tclib.o
@@ -44,3 +45,4 @@
 obj-y				+= ti-st/
 obj-$(CONFIG_AB8500_PWM)	+= ab8500-pwm.o
 obj-y				+= lis3lv02d/
+obj-y				+= carma/
diff -druN linux-2.6.39-libre/drivers/misc/pch_phub.c linux-3.0-rc7-libre/drivers/misc/pch_phub.c
--- linux-2.6.39-libre/drivers/misc/pch_phub.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/misc/pch_phub.c	2011-07-11 19:51:52.000000000 -0400
@@ -34,12 +34,18 @@
 #define PHUB_TIMEOUT 0x05		/* Time out value for Status Register */
 #define PCH_PHUB_ROM_WRITE_ENABLE 0x01	/* Enabling for writing ROM */
 #define PCH_PHUB_ROM_WRITE_DISABLE 0x00	/* Disabling for writing ROM */
-#define PCH_PHUB_MAC_START_ADDR 0x20C  /* MAC data area start address offset */
-#define PCH_PHUB_ROM_START_ADDR_EG20T 0x14 /* ROM data area start address offset
+#define PCH_PHUB_MAC_START_ADDR_EG20T 0x14  /* MAC data area start address
+					       offset */
+#define PCH_PHUB_MAC_START_ADDR_ML7223 0x20C  /* MAC data area start address
+						 offset */
+#define PCH_PHUB_ROM_START_ADDR_EG20T 0x80 /* ROM data area start address offset
 					      (Intel EG20T PCH)*/
 #define PCH_PHUB_ROM_START_ADDR_ML7213 0x400 /* ROM data area start address
 						offset(OKI SEMICONDUCTOR ML7213)
 					      */
+#define PCH_PHUB_ROM_START_ADDR_ML7223 0x400 /* ROM data area start address
+						offset(OKI SEMICONDUCTOR ML7223)
+					      */
 
 /* MAX number of INT_REDUCE_CONTROL registers */
 #define MAX_NUM_INT_REDUCE_CONTROL_REG 128
@@ -63,6 +69,10 @@
 #define PCI_VENDOR_ID_ROHM			0x10db
 #define PCI_DEVICE_ID_ROHM_ML7213_PHUB		0x801A
 
+/* Macros for ML7223 */
+#define PCI_DEVICE_ID_ROHM_ML7223_mPHUB	0x8012 /* for Bus-m */
+#define PCI_DEVICE_ID_ROHM_ML7223_nPHUB	0x8002 /* for Bus-n */
+
 /* SROM ACCESS Macro */
 #define PCH_WORD_ADDR_MASK (~((1 << 2) - 1))
 
@@ -100,6 +110,9 @@
  * @clkcfg_reg:				CLK CFG register val
  * @pch_phub_base_address:		Register base address
  * @pch_phub_extrom_base_address:	external rom base address
+ * @pch_mac_start_address:		MAC address area start address
+ * @pch_opt_rom_start_address:		Option ROM start address
+ * @ioh_type:				Save IOH type
  */
 struct pch_phub_reg {
 	u32 phub_id_reg;
@@ -117,6 +130,9 @@
 	u32 clkcfg_reg;
 	void __iomem *pch_phub_base_address;
 	void __iomem *pch_phub_extrom_base_address;
+	u32 pch_mac_start_address;
+	u32 pch_opt_rom_start_address;
+	int ioh_type;
 };
 
 /* SROM SPEC for MAC address assignment offset */
@@ -319,7 +335,7 @@
 {
 	unsigned int mem_addr;
 
-	mem_addr = PCH_PHUB_ROM_START_ADDR_EG20T +
+	mem_addr = chip->pch_mac_start_address +
 			pch_phub_mac_offset[offset_address];
 
 	pch_phub_read_serial_rom(chip, mem_addr, data);
@@ -336,7 +352,7 @@
 	int retval;
 	unsigned int mem_addr;
 
-	mem_addr = PCH_PHUB_ROM_START_ADDR_EG20T +
+	mem_addr = chip->pch_mac_start_address +
 			pch_phub_mac_offset[offset_address];
 
 	retval = pch_phub_write_serial_rom(chip, mem_addr, data);
@@ -384,6 +400,48 @@
 	return retval;
 }
 
+/* pch_phub_gbe_serial_rom_conf_mp - makes SerialROM header format configuration
+ * for Gigabit Ethernet MAC address
+ */
+static int pch_phub_gbe_serial_rom_conf_mp(struct pch_phub_reg *chip)
+{
+	int retval;
+	u32 offset_addr;
+
+	offset_addr = 0x200;
+	retval = pch_phub_write_serial_rom(chip, 0x03 + offset_addr, 0xbc);
+	retval |= pch_phub_write_serial_rom(chip, 0x02 + offset_addr, 0x00);
+	retval |= pch_phub_write_serial_rom(chip, 0x01 + offset_addr, 0x40);
+	retval |= pch_phub_write_serial_rom(chip, 0x00 + offset_addr, 0x02);
+
+	retval |= pch_phub_write_serial_rom(chip, 0x07 + offset_addr, 0x00);
+	retval |= pch_phub_write_serial_rom(chip, 0x06 + offset_addr, 0x00);
+	retval |= pch_phub_write_serial_rom(chip, 0x05 + offset_addr, 0x00);
+	retval |= pch_phub_write_serial_rom(chip, 0x04 + offset_addr, 0x80);
+
+	retval |= pch_phub_write_serial_rom(chip, 0x0b + offset_addr, 0xbc);
+	retval |= pch_phub_write_serial_rom(chip, 0x0a + offset_addr, 0x00);
+	retval |= pch_phub_write_serial_rom(chip, 0x09 + offset_addr, 0x40);
+	retval |= pch_phub_write_serial_rom(chip, 0x08 + offset_addr, 0x18);
+
+	retval |= pch_phub_write_serial_rom(chip, 0x13 + offset_addr, 0xbc);
+	retval |= pch_phub_write_serial_rom(chip, 0x12 + offset_addr, 0x00);
+	retval |= pch_phub_write_serial_rom(chip, 0x11 + offset_addr, 0x40);
+	retval |= pch_phub_write_serial_rom(chip, 0x10 + offset_addr, 0x19);
+
+	retval |= pch_phub_write_serial_rom(chip, 0x1b + offset_addr, 0xbc);
+	retval |= pch_phub_write_serial_rom(chip, 0x1a + offset_addr, 0x00);
+	retval |= pch_phub_write_serial_rom(chip, 0x19 + offset_addr, 0x40);
+	retval |= pch_phub_write_serial_rom(chip, 0x18 + offset_addr, 0x3a);
+
+	retval |= pch_phub_write_serial_rom(chip, 0x1f + offset_addr, 0x01);
+	retval |= pch_phub_write_serial_rom(chip, 0x1e + offset_addr, 0x00);
+	retval |= pch_phub_write_serial_rom(chip, 0x1d + offset_addr, 0x00);
+	retval |= pch_phub_write_serial_rom(chip, 0x1c + offset_addr, 0x00);
+
+	return retval;
+}
+
 /**
  * pch_phub_read_gbe_mac_addr() - Read Gigabit Ethernet MAC address
  * @offset_address:	Gigabit Ethernet MAC address offset value.
@@ -406,7 +464,10 @@
 	int retval;
 	int i;
 
-	retval = pch_phub_gbe_serial_rom_conf(chip);
+	if (chip->ioh_type == 1) /* EG20T */
+		retval = pch_phub_gbe_serial_rom_conf(chip);
+	else	/* ML7223 */
+		retval = pch_phub_gbe_serial_rom_conf_mp(chip);
 	if (retval)
 		return retval;
 
@@ -441,12 +502,16 @@
 	}
 
 	/* Get Rom signature */
-	pch_phub_read_serial_rom(chip, 0x80, (unsigned char *)&rom_signature);
+	pch_phub_read_serial_rom(chip, chip->pch_opt_rom_start_address,
+				(unsigned char *)&rom_signature);
 	rom_signature &= 0xff;
-	pch_phub_read_serial_rom(chip, 0x81, (unsigned char *)&tmp);
+	pch_phub_read_serial_rom(chip, chip->pch_opt_rom_start_address + 1,
+				(unsigned char *)&tmp);
 	rom_signature |= (tmp & 0xff) << 8;
 	if (rom_signature == 0xAA55) {
-		pch_phub_read_serial_rom(chip, 0x82, &rom_length);
+		pch_phub_read_serial_rom(chip,
+					 chip->pch_opt_rom_start_address + 2,
+					 &rom_length);
 		orom_size = rom_length * 512;
 		if (orom_size < off) {
 			addr_offset = 0;
@@ -458,8 +523,9 @@
 		}
 
 		for (addr_offset = 0; addr_offset < count; addr_offset++) {
-			pch_phub_read_serial_rom(chip, 0x80 + addr_offset + off,
-							 &buf[addr_offset]);
+			pch_phub_read_serial_rom(chip,
+			    chip->pch_opt_rom_start_address + addr_offset + off,
+			    &buf[addr_offset]);
 		}
 	} else {
 		err = -ENODATA;
@@ -502,8 +568,9 @@
 		if (PCH_PHUB_OROM_SIZE < off + addr_offset)
 			goto return_ok;
 
-		ret = pch_phub_write_serial_rom(chip, 0x80 + addr_offset + off,
-						       buf[addr_offset]);
+		ret = pch_phub_write_serial_rom(chip,
+			    chip->pch_opt_rom_start_address + addr_offset + off,
+			    buf[addr_offset]);
 		if (ret) {
 			err = ret;
 			goto return_err;
@@ -603,19 +670,22 @@
 	dev_dbg(&pdev->dev, "%s : pci_iomap SUCCESS and value "
 		"in pch_phub_base_address variable is %p\n", __func__,
 		chip->pch_phub_base_address);
-	chip->pch_phub_extrom_base_address = pci_map_rom(pdev, &rom_size);
 
-	if (chip->pch_phub_extrom_base_address == 0) {
-		dev_err(&pdev->dev, "%s : pci_map_rom FAILED", __func__);
-		ret = -ENOMEM;
-		goto err_pci_map;
+	if (id->driver_data != 3) {
+		chip->pch_phub_extrom_base_address =\
+						   pci_map_rom(pdev, &rom_size);
+		if (chip->pch_phub_extrom_base_address == 0) {
+			dev_err(&pdev->dev, "%s: pci_map_rom FAILED", __func__);
+			ret = -ENOMEM;
+			goto err_pci_map;
+		}
+		dev_dbg(&pdev->dev, "%s : "
+			"pci_map_rom SUCCESS and value in "
+			"pch_phub_extrom_base_address variable is %p\n",
+			__func__, chip->pch_phub_extrom_base_address);
 	}
-	dev_dbg(&pdev->dev, "%s : "
-		"pci_map_rom SUCCESS and value in "
-		"pch_phub_extrom_base_address variable is %p\n", __func__,
-		chip->pch_phub_extrom_base_address);
 
-	if (id->driver_data == 1) {
+	if (id->driver_data == 1) { /* EG20T PCH */
 		retval = sysfs_create_file(&pdev->dev.kobj,
 					   &dev_attr_pch_mac.attr);
 		if (retval)
@@ -642,7 +712,9 @@
 		iowrite32(0x000affaa, chip->pch_phub_base_address + 0x14);
 		/* set the interrupt delay value */
 		iowrite32(0x25, chip->pch_phub_base_address + 0x44);
-	} else if (id->driver_data == 2) {
+		chip->pch_opt_rom_start_address = PCH_PHUB_ROM_START_ADDR_EG20T;
+		chip->pch_mac_start_address = PCH_PHUB_MAC_START_ADDR_EG20T;
+	} else if (id->driver_data == 2) { /* ML7213 IOH */
 		retval = sysfs_create_bin_file(&pdev->dev.kobj, &pch_bin_attr);
 		if (retval)
 			goto err_sysfs_create;
@@ -653,7 +725,38 @@
 		 * Device8(USB OHCI #0/ USB EHCI #0):a
 		 */
 		iowrite32(0x000affa0, chip->pch_phub_base_address + 0x14);
+		chip->pch_opt_rom_start_address =\
+						 PCH_PHUB_ROM_START_ADDR_ML7213;
+	} else if (id->driver_data == 3) { /* ML7223 IOH Bus-m*/
+		/* set the prefech value
+		 * Device8(GbE)
+		 */
+		iowrite32(0x000a0000, chip->pch_phub_base_address + 0x14);
+		chip->pch_opt_rom_start_address =\
+						 PCH_PHUB_ROM_START_ADDR_ML7223;
+		chip->pch_mac_start_address = PCH_PHUB_MAC_START_ADDR_ML7223;
+	} else if (id->driver_data == 4) { /* ML7223 IOH Bus-n*/
+		retval = sysfs_create_file(&pdev->dev.kobj,
+					   &dev_attr_pch_mac.attr);
+		if (retval)
+			goto err_sysfs_create;
+		retval = sysfs_create_bin_file(&pdev->dev.kobj, &pch_bin_attr);
+		if (retval)
+			goto exit_bin_attr;
+		/* set the prefech value
+		 * Device2(USB OHCI #0,1,2,3/ USB EHCI #0):a
+		 * Device4(SDIO #0,1):f
+		 * Device6(SATA 2):f
+		 */
+		iowrite32(0x0000ffa0, chip->pch_phub_base_address + 0x14);
+		/* set the interrupt delay value */
+		iowrite32(0x25, chip->pch_phub_base_address + 0x140);
+		chip->pch_opt_rom_start_address =\
+						 PCH_PHUB_ROM_START_ADDR_ML7223;
+		chip->pch_mac_start_address = PCH_PHUB_MAC_START_ADDR_ML7223;
 	}
+
+	chip->ioh_type = id->driver_data;
 	pci_set_drvdata(pdev, chip);
 
 	return 0;
@@ -733,6 +836,8 @@
 static struct pci_device_id pch_phub_pcidev_id[] = {
 	{ PCI_VDEVICE(INTEL, PCI_DEVICE_ID_PCH1_PHUB),       1,  },
 	{ PCI_VDEVICE(ROHM, PCI_DEVICE_ID_ROHM_ML7213_PHUB), 2,  },
+	{ PCI_VDEVICE(ROHM, PCI_DEVICE_ID_ROHM_ML7223_mPHUB), 3,  },
+	{ PCI_VDEVICE(ROHM, PCI_DEVICE_ID_ROHM_ML7223_nPHUB), 4,  },
 	{ }
 };
 MODULE_DEVICE_TABLE(pci, pch_phub_pcidev_id);
@@ -759,5 +864,5 @@
 module_init(pch_phub_pci_init);
 module_exit(pch_phub_pci_exit);
 
-MODULE_DESCRIPTION("PCH Packet Hub PCI Driver");
+MODULE_DESCRIPTION("Intel EG20T PCH/OKI SEMICONDUCTOR IOH(ML7213/ML7223) PHUB");
 MODULE_LICENSE("GPL");
diff -druN linux-2.6.39-libre/drivers/misc/pti.c linux-3.0-rc7-libre/drivers/misc/pti.c
--- linux-2.6.39-libre/drivers/misc/pti.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/misc/pti.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,983 @@
+/*
+ *  pti.c - PTI driver for cJTAG data extration
+ *
+ *  Copyright (C) Intel 2010
+ *
+ * This program is free software; you can 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.
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ * The PTI (Parallel Trace Interface) driver directs trace data routed from
+ * various parts in the system out through the Intel Penwell PTI port and
+ * out of the mobile device for analysis with a debugging tool
+ * (Lauterbach, Fido). This is part of a solution for the MIPI P1149.7,
+ * compact JTAG, standard.
+ */
+
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/console.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/tty.h>
+#include <linux/tty_driver.h>
+#include <linux/pci.h>
+#include <linux/mutex.h>
+#include <linux/miscdevice.h>
+#include <linux/pti.h>
+
+#define DRIVERNAME		"pti"
+#define PCINAME			"pciPTI"
+#define TTYNAME			"ttyPTI"
+#define CHARNAME		"pti"
+#define PTITTY_MINOR_START	0
+#define PTITTY_MINOR_NUM	2
+#define MAX_APP_IDS		16   /* 128 channel ids / u8 bit size */
+#define MAX_OS_IDS		16   /* 128 channel ids / u8 bit size */
+#define MAX_MODEM_IDS		16   /* 128 channel ids / u8 bit size */
+#define MODEM_BASE_ID		71   /* modem master ID address    */
+#define CONTROL_ID		72   /* control master ID address  */
+#define CONSOLE_ID		73   /* console master ID address  */
+#define OS_BASE_ID		74   /* base OS master ID address  */
+#define APP_BASE_ID		80   /* base App master ID address */
+#define CONTROL_FRAME_LEN	32   /* PTI control frame maximum size */
+#define USER_COPY_SIZE		8192 /* 8Kb buffer for user space copy */
+#define APERTURE_14		0x3800000 /* offset to first OS write addr */
+#define APERTURE_LEN		0x400000  /* address length */
+
+struct pti_tty {
+	struct pti_masterchannel *mc;
+};
+
+struct pti_dev {
+	struct tty_port port;
+	unsigned long pti_addr;
+	unsigned long aperture_base;
+	void __iomem *pti_ioaddr;
+	u8 ia_app[MAX_APP_IDS];
+	u8 ia_os[MAX_OS_IDS];
+	u8 ia_modem[MAX_MODEM_IDS];
+};
+
+/*
+ * This protects access to ia_app, ia_os, and ia_modem,
+ * which keeps track of channels allocated in
+ * an aperture write id.
+ */
+static DEFINE_MUTEX(alloclock);
+
+static struct pci_device_id pci_ids[] __devinitconst = {
+		{PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x82B)},
+		{0}
+};
+
+static struct tty_driver *pti_tty_driver;
+static struct pti_dev *drv_data;
+
+static unsigned int pti_console_channel;
+static unsigned int pti_control_channel;
+
+/**
+ *  pti_write_to_aperture()- The private write function to PTI HW.
+ *
+ *  @mc: The 'aperture'. It's part of a write address that holds
+ *       a master and channel ID.
+ *  @buf: Data being written to the HW that will ultimately be seen
+ *        in a debugging tool (Fido, Lauterbach).
+ *  @len: Size of buffer.
+ *
+ *  Since each aperture is specified by a unique
+ *  master/channel ID, no two processes will be writing
+ *  to the same aperture at the same time so no lock is required. The
+ *  PTI-Output agent will send these out in the order that they arrived, and
+ *  thus, it will intermix these messages. The debug tool can then later
+ *  regroup the appropriate message segments together reconstituting each
+ *  message.
+ */
+static void pti_write_to_aperture(struct pti_masterchannel *mc,
+				  u8 *buf,
+				  int len)
+{
+	int dwordcnt;
+	int final;
+	int i;
+	u32 ptiword;
+	u32 __iomem *aperture;
+	u8 *p = buf;
+
+	/*
+	 * calculate the aperture offset from the base using the master and
+	 * channel id's.
+	 */
+	aperture = drv_data->pti_ioaddr + (mc->master << 15)
+		+ (mc->channel << 8);
+
+	dwordcnt = len >> 2;
+	final = len - (dwordcnt << 2);	    /* final = trailing bytes    */
+	if (final == 0 && dwordcnt != 0) {  /* always need a final dword */
+		final += 4;
+		dwordcnt--;
+	}
+
+	for (i = 0; i < dwordcnt; i++) {
+		ptiword = be32_to_cpu(*(u32 *)p);
+		p += 4;
+		iowrite32(ptiword, aperture);
+	}
+
+	aperture += PTI_LASTDWORD_DTS;	/* adding DTS signals that is EOM */
+
+	ptiword = 0;
+	for (i = 0; i < final; i++)
+		ptiword |= *p++ << (24-(8*i));
+
+	iowrite32(ptiword, aperture);
+	return;
+}
+
+/**
+ *  pti_control_frame_built_and_sent()- control frame build and send function.
+ *
+ *  @mc: The master / channel structure on which the function
+ *       built a control frame.
+ *
+ *  To be able to post process the PTI contents on host side, a control frame
+ *  is added before sending any PTI content. So the host side knows on
+ *  each PTI frame the name of the thread using a dedicated master / channel.
+ *  The thread name is retrieved from the 'current' global variable.
+ *  This function builds this frame and sends it to a master ID CONTROL_ID.
+ *  The overhead is only 32 bytes since the driver only writes to HW
+ *  in 32 byte chunks.
+ */
+
+static void pti_control_frame_built_and_sent(struct pti_masterchannel *mc)
+{
+	struct pti_masterchannel mccontrol = {.master = CONTROL_ID,
+					      .channel = 0};
+	const char *control_format = "%3d %3d %s";
+	u8 control_frame[CONTROL_FRAME_LEN];
+
+	/*
+	 * Since we access the comm member in current's task_struct,
+	 * we only need to be as large as what 'comm' in that
+	 * structure is.
+	 */
+	char comm[TASK_COMM_LEN];
+
+	if (!in_interrupt())
+		get_task_comm(comm, current);
+	else
+		strncpy(comm, "Interrupt", TASK_COMM_LEN);
+
+	/* Absolutely ensure our buffer is zero terminated. */
+	comm[TASK_COMM_LEN-1] = 0;
+
+	mccontrol.channel = pti_control_channel;
+	pti_control_channel = (pti_control_channel + 1) & 0x7f;
+
+	snprintf(control_frame, CONTROL_FRAME_LEN, control_format, mc->master,
+		mc->channel, comm);
+	pti_write_to_aperture(&mccontrol, control_frame, strlen(control_frame));
+}
+
+/**
+ *  pti_write_full_frame_to_aperture()- high level function to
+ *					write to PTI.
+ *
+ *  @mc:  The 'aperture'. It's part of a write address that holds
+ *        a master and channel ID.
+ *  @buf: Data being written to the HW that will ultimately be seen
+ *        in a debugging tool (Fido, Lauterbach).
+ *  @len: Size of buffer.
+ *
+ *  All threads sending data (either console, user space application, ...)
+ *  are calling the high level function to write to PTI meaning that it is
+ *  possible to add a control frame before sending the content.
+ */
+static void pti_write_full_frame_to_aperture(struct pti_masterchannel *mc,
+						const unsigned char *buf,
+						int len)
+{
+	pti_control_frame_built_and_sent(mc);
+	pti_write_to_aperture(mc, (u8 *)buf, len);
+}
+
+/**
+ * get_id()- Allocate a master and channel ID.
+ *
+ * @id_array: an array of bits representing what channel
+ *            id's are allocated for writing.
+ * @max_ids:  The max amount of available write IDs to use.
+ * @base_id:  The starting SW channel ID, based on the Intel
+ *            PTI arch.
+ *
+ * Returns:
+ *	pti_masterchannel struct with master, channel ID address
+ *	0 for error
+ *
+ * Each bit in the arrays ia_app and ia_os correspond to a master and
+ * channel id. The bit is one if the id is taken and 0 if free. For
+ * every master there are 128 channel id's.
+ */
+static struct pti_masterchannel *get_id(u8 *id_array, int max_ids, int base_id)
+{
+	struct pti_masterchannel *mc;
+	int i, j, mask;
+
+	mc = kmalloc(sizeof(struct pti_masterchannel), GFP_KERNEL);
+	if (mc == NULL)
+		return NULL;
+
+	/* look for a byte with a free bit */
+	for (i = 0; i < max_ids; i++)
+		if (id_array[i] != 0xff)
+			break;
+	if (i == max_ids) {
+		kfree(mc);
+		return NULL;
+	}
+	/* find the bit in the 128 possible channel opportunities */
+	mask = 0x80;
+	for (j = 0; j < 8; j++) {
+		if ((id_array[i] & mask) == 0)
+			break;
+		mask >>= 1;
+	}
+
+	/* grab it */
+	id_array[i] |= mask;
+	mc->master  = base_id;
+	mc->channel = ((i & 0xf)<<3) + j;
+	/* write new master Id / channel Id allocation to channel control */
+	pti_control_frame_built_and_sent(mc);
+	return mc;
+}
+
+/*
+ * The following three functions:
+ * pti_request_mastercahannel(), mipi_release_masterchannel()
+ * and pti_writedata() are an API for other kernel drivers to
+ * access PTI.
+ */
+
+/**
+ * pti_request_masterchannel()- Kernel API function used to allocate
+ *				a master, channel ID address
+ *				to write to PTI HW.
+ *
+ * @type: 0- request Application  master, channel aperture ID write address.
+ *        1- request OS master, channel aperture ID write
+ *           address.
+ *        2- request Modem master, channel aperture ID
+ *           write address.
+ *        Other values, error.
+ *
+ * Returns:
+ *	pti_masterchannel struct
+ *	0 for error
+ */
+struct pti_masterchannel *pti_request_masterchannel(u8 type)
+{
+	struct pti_masterchannel *mc;
+
+	mutex_lock(&alloclock);
+
+	switch (type) {
+
+	case 0:
+		mc = get_id(drv_data->ia_app, MAX_APP_IDS, APP_BASE_ID);
+		break;
+
+	case 1:
+		mc = get_id(drv_data->ia_os, MAX_OS_IDS, OS_BASE_ID);
+		break;
+
+	case 2:
+		mc = get_id(drv_data->ia_modem, MAX_MODEM_IDS, MODEM_BASE_ID);
+		break;
+	default:
+		mc = NULL;
+	}
+
+	mutex_unlock(&alloclock);
+	return mc;
+}
+EXPORT_SYMBOL_GPL(pti_request_masterchannel);
+
+/**
+ * pti_release_masterchannel()- Kernel API function used to release
+ *				a master, channel ID address
+ *				used to write to PTI HW.
+ *
+ * @mc: master, channel apeture ID address to be released.  This
+ *      will de-allocate the structure via kfree().
+ */
+void pti_release_masterchannel(struct pti_masterchannel *mc)
+{
+	u8 master, channel, i;
+
+	mutex_lock(&alloclock);
+
+	if (mc) {
+		master = mc->master;
+		channel = mc->channel;
+
+		if (master == APP_BASE_ID) {
+			i = channel >> 3;
+			drv_data->ia_app[i] &=  ~(0x80>>(channel & 0x7));
+		} else if (master == OS_BASE_ID) {
+			i = channel >> 3;
+			drv_data->ia_os[i] &= ~(0x80>>(channel & 0x7));
+		} else {
+			i = channel >> 3;
+			drv_data->ia_modem[i] &= ~(0x80>>(channel & 0x7));
+		}
+
+		kfree(mc);
+	}
+
+	mutex_unlock(&alloclock);
+}
+EXPORT_SYMBOL_GPL(pti_release_masterchannel);
+
+/**
+ * pti_writedata()- Kernel API function used to write trace
+ *                  debugging data to PTI HW.
+ *
+ * @mc:    Master, channel aperture ID address to write to.
+ *         Null value will return with no write occurring.
+ * @buf:   Trace debuging data to write to the PTI HW.
+ *         Null value will return with no write occurring.
+ * @count: Size of buf. Value of 0 or a negative number will
+ *         return with no write occuring.
+ */
+void pti_writedata(struct pti_masterchannel *mc, u8 *buf, int count)
+{
+	/*
+	 * since this function is exported, this is treated like an
+	 * API function, thus, all parameters should
+	 * be checked for validity.
+	 */
+	if ((mc != NULL) && (buf != NULL) && (count > 0))
+		pti_write_to_aperture(mc, buf, count);
+	return;
+}
+EXPORT_SYMBOL_GPL(pti_writedata);
+
+/**
+ * pti_pci_remove()- Driver exit method to remove PTI from
+ *		   PCI bus.
+ * @pdev: variable containing pci info of PTI.
+ */
+static void __devexit pti_pci_remove(struct pci_dev *pdev)
+{
+	struct pti_dev *drv_data;
+
+	drv_data = pci_get_drvdata(pdev);
+	if (drv_data != NULL) {
+		pci_iounmap(pdev, drv_data->pti_ioaddr);
+		pci_set_drvdata(pdev, NULL);
+		kfree(drv_data);
+		pci_release_region(pdev, 1);
+		pci_disable_device(pdev);
+	}
+}
+
+/*
+ * for the tty_driver_*() basic function descriptions, see tty_driver.h.
+ * Specific header comments made for PTI-related specifics.
+ */
+
+/**
+ * pti_tty_driver_open()- Open an Application master, channel aperture
+ * ID to the PTI device via tty device.
+ *
+ * @tty: tty interface.
+ * @filp: filp interface pased to tty_port_open() call.
+ *
+ * Returns:
+ *	int, 0 for success
+ *	otherwise, fail value
+ *
+ * The main purpose of using the tty device interface is for
+ * each tty port to have a unique PTI write aperture.  In an
+ * example use case, ttyPTI0 gets syslogd and an APP aperture
+ * ID and ttyPTI1 is where the n_tracesink ldisc hooks to route
+ * modem messages into PTI.  Modem trace data does not have to
+ * go to ttyPTI1, but ttyPTI0 and ttyPTI1 do need to be distinct
+ * master IDs.  These messages go through the PTI HW and out of
+ * the handheld platform and to the Fido/Lauterbach device.
+ */
+static int pti_tty_driver_open(struct tty_struct *tty, struct file *filp)
+{
+	/*
+	 * we actually want to allocate a new channel per open, per
+	 * system arch.  HW gives more than plenty channels for a single
+	 * system task to have its own channel to write trace data. This
+	 * also removes a locking requirement for the actual write
+	 * procedure.
+	 */
+	return tty_port_open(&drv_data->port, tty, filp);
+}
+
+/**
+ * pti_tty_driver_close()- close tty device and release Application
+ * master, channel aperture ID to the PTI device via tty device.
+ *
+ * @tty: tty interface.
+ * @filp: filp interface pased to tty_port_close() call.
+ *
+ * The main purpose of using the tty device interface is to route
+ * syslog daemon messages to the PTI HW and out of the handheld platform
+ * and to the Fido/Lauterbach device.
+ */
+static void pti_tty_driver_close(struct tty_struct *tty, struct file *filp)
+{
+	tty_port_close(&drv_data->port, tty, filp);
+}
+
+/**
+ * pti_tty_intstall()- Used to set up specific master-channels
+ *		       to tty ports for organizational purposes when
+ *		       tracing viewed from debuging tools.
+ *
+ * @driver: tty driver information.
+ * @tty: tty struct containing pti information.
+ *
+ * Returns:
+ *	0 for success
+ *	otherwise, error
+ */
+static int pti_tty_install(struct tty_driver *driver, struct tty_struct *tty)
+{
+	int idx = tty->index;
+	struct pti_tty *pti_tty_data;
+	int ret = tty_init_termios(tty);
+
+	if (ret == 0) {
+		tty_driver_kref_get(driver);
+		tty->count++;
+		driver->ttys[idx] = tty;
+
+		pti_tty_data = kmalloc(sizeof(struct pti_tty), GFP_KERNEL);
+		if (pti_tty_data == NULL)
+			return -ENOMEM;
+
+		if (idx == PTITTY_MINOR_START)
+			pti_tty_data->mc = pti_request_masterchannel(0);
+		else
+			pti_tty_data->mc = pti_request_masterchannel(2);
+
+		if (pti_tty_data->mc == NULL) {
+			kfree(pti_tty_data);
+			return -ENXIO;
+		}
+		tty->driver_data = pti_tty_data;
+	}
+
+	return ret;
+}
+
+/**
+ * pti_tty_cleanup()- Used to de-allocate master-channel resources
+ *		      tied to tty's of this driver.
+ *
+ * @tty: tty struct containing pti information.
+ */
+static void pti_tty_cleanup(struct tty_struct *tty)
+{
+	struct pti_tty *pti_tty_data = tty->driver_data;
+	if (pti_tty_data == NULL)
+		return;
+	pti_release_masterchannel(pti_tty_data->mc);
+	kfree(pti_tty_data);
+	tty->driver_data = NULL;
+}
+
+/**
+ * pti_tty_driver_write()-  Write trace debugging data through the char
+ * interface to the PTI HW.  Part of the misc device implementation.
+ *
+ * @filp: Contains private data which is used to obtain
+ *        master, channel write ID.
+ * @data: trace data to be written.
+ * @len:  # of byte to write.
+ *
+ * Returns:
+ *	int, # of bytes written
+ *	otherwise, error
+ */
+static int pti_tty_driver_write(struct tty_struct *tty,
+	const unsigned char *buf, int len)
+{
+	struct pti_tty *pti_tty_data = tty->driver_data;
+	if ((pti_tty_data != NULL) && (pti_tty_data->mc != NULL)) {
+		pti_write_to_aperture(pti_tty_data->mc, (u8 *)buf, len);
+		return len;
+	}
+	/*
+	 * we can't write to the pti hardware if the private driver_data
+	 * and the mc address is not there.
+	 */
+	else
+		return -EFAULT;
+}
+
+/**
+ * pti_tty_write_room()- Always returns 2048.
+ *
+ * @tty: contains tty info of the pti driver.
+ */
+static int pti_tty_write_room(struct tty_struct *tty)
+{
+	return 2048;
+}
+
+/**
+ * pti_char_open()- Open an Application master, channel aperture
+ * ID to the PTI device. Part of the misc device implementation.
+ *
+ * @inode: not used.
+ * @filp:  Output- will have a masterchannel struct set containing
+ *                 the allocated application PTI aperture write address.
+ *
+ * Returns:
+ *	int, 0 for success
+ *	otherwise, a fail value
+ */
+static int pti_char_open(struct inode *inode, struct file *filp)
+{
+	struct pti_masterchannel *mc;
+
+	/*
+	 * We really do want to fail immediately if
+	 * pti_request_masterchannel() fails,
+	 * before assigning the value to filp->private_data.
+	 * Slightly easier to debug if this driver needs debugging.
+	 */
+	mc = pti_request_masterchannel(0);
+	if (mc == NULL)
+		return -ENOMEM;
+	filp->private_data = mc;
+	return 0;
+}
+
+/**
+ * pti_char_release()-  Close a char channel to the PTI device. Part
+ * of the misc device implementation.
+ *
+ * @inode: Not used in this implementaiton.
+ * @filp:  Contains private_data that contains the master, channel
+ *         ID to be released by the PTI device.
+ *
+ * Returns:
+ *	always 0
+ */
+static int pti_char_release(struct inode *inode, struct file *filp)
+{
+	pti_release_masterchannel(filp->private_data);
+	filp->private_data = NULL;
+	return 0;
+}
+
+/**
+ * pti_char_write()-  Write trace debugging data through the char
+ * interface to the PTI HW.  Part of the misc device implementation.
+ *
+ * @filp:  Contains private data which is used to obtain
+ *         master, channel write ID.
+ * @data:  trace data to be written.
+ * @len:   # of byte to write.
+ * @ppose: Not used in this function implementation.
+ *
+ * Returns:
+ *	int, # of bytes written
+ *	otherwise, error value
+ *
+ * Notes: From side discussions with Alan Cox and experimenting
+ * with PTI debug HW like Nokia's Fido box and Lauterbach
+ * devices, 8192 byte write buffer used by USER_COPY_SIZE was
+ * deemed an appropriate size for this type of usage with
+ * debugging HW.
+ */
+static ssize_t pti_char_write(struct file *filp, const char __user *data,
+			      size_t len, loff_t *ppose)
+{
+	struct pti_masterchannel *mc;
+	void *kbuf;
+	const char __user *tmp;
+	size_t size = USER_COPY_SIZE;
+	size_t n = 0;
+
+	tmp = data;
+	mc = filp->private_data;
+
+	kbuf = kmalloc(size, GFP_KERNEL);
+	if (kbuf == NULL)  {
+		pr_err("%s(%d): buf allocation failed\n",
+			__func__, __LINE__);
+		return -ENOMEM;
+	}
+
+	do {
+		if (len - n > USER_COPY_SIZE)
+			size = USER_COPY_SIZE;
+		else
+			size = len - n;
+
+		if (copy_from_user(kbuf, tmp, size)) {
+			kfree(kbuf);
+			return n ? n : -EFAULT;
+		}
+
+		pti_write_to_aperture(mc, kbuf, size);
+		n  += size;
+		tmp += size;
+
+	} while (len > n);
+
+	kfree(kbuf);
+	return len;
+}
+
+static const struct tty_operations pti_tty_driver_ops = {
+	.open		= pti_tty_driver_open,
+	.close		= pti_tty_driver_close,
+	.write		= pti_tty_driver_write,
+	.write_room	= pti_tty_write_room,
+	.install	= pti_tty_install,
+	.cleanup	= pti_tty_cleanup
+};
+
+static const struct file_operations pti_char_driver_ops = {
+	.owner		= THIS_MODULE,
+	.write		= pti_char_write,
+	.open		= pti_char_open,
+	.release	= pti_char_release,
+};
+
+static struct miscdevice pti_char_driver = {
+	.minor		= MISC_DYNAMIC_MINOR,
+	.name		= CHARNAME,
+	.fops		= &pti_char_driver_ops
+};
+
+/**
+ * pti_console_write()-  Write to the console that has been acquired.
+ *
+ * @c:   Not used in this implementaiton.
+ * @buf: Data to be written.
+ * @len: Length of buf.
+ */
+static void pti_console_write(struct console *c, const char *buf, unsigned len)
+{
+	static struct pti_masterchannel mc = {.master  = CONSOLE_ID,
+					      .channel = 0};
+
+	mc.channel = pti_console_channel;
+	pti_console_channel = (pti_console_channel + 1) & 0x7f;
+
+	pti_write_full_frame_to_aperture(&mc, buf, len);
+}
+
+/**
+ * pti_console_device()-  Return the driver tty structure and set the
+ *			  associated index implementation.
+ *
+ * @c:     Console device of the driver.
+ * @index: index associated with c.
+ *
+ * Returns:
+ *	always value of pti_tty_driver structure when this function
+ *	is called.
+ */
+static struct tty_driver *pti_console_device(struct console *c, int *index)
+{
+	*index = c->index;
+	return pti_tty_driver;
+}
+
+/**
+ * pti_console_setup()-  Initialize console variables used by the driver.
+ *
+ * @c:     Not used.
+ * @opts:  Not used.
+ *
+ * Returns:
+ *	always 0.
+ */
+static int pti_console_setup(struct console *c, char *opts)
+{
+	pti_console_channel = 0;
+	pti_control_channel = 0;
+	return 0;
+}
+
+/*
+ * pti_console struct, used to capture OS printk()'s and shift
+ * out to the PTI device for debugging.  This cannot be
+ * enabled upon boot because of the possibility of eating
+ * any serial console printk's (race condition discovered).
+ * The console should be enabled upon when the tty port is
+ * used for the first time.  Since the primary purpose for
+ * the tty port is to hook up syslog to it, the tty port
+ * will be open for a really long time.
+ */
+static struct console pti_console = {
+	.name		= TTYNAME,
+	.write		= pti_console_write,
+	.device		= pti_console_device,
+	.setup		= pti_console_setup,
+	.flags		= CON_PRINTBUFFER,
+	.index		= 0,
+};
+
+/**
+ * pti_port_activate()- Used to start/initialize any items upon
+ * first opening of tty_port().
+ *
+ * @port- The tty port number of the PTI device.
+ * @tty-  The tty struct associated with this device.
+ *
+ * Returns:
+ *	always returns 0
+ *
+ * Notes: The primary purpose of the PTI tty port 0 is to hook
+ * the syslog daemon to it; thus this port will be open for a
+ * very long time.
+ */
+static int pti_port_activate(struct tty_port *port, struct tty_struct *tty)
+{
+	if (port->tty->index == PTITTY_MINOR_START)
+		console_start(&pti_console);
+	return 0;
+}
+
+/**
+ * pti_port_shutdown()- Used to stop/shutdown any items upon the
+ * last tty port close.
+ *
+ * @port- The tty port number of the PTI device.
+ *
+ * Notes: The primary purpose of the PTI tty port 0 is to hook
+ * the syslog daemon to it; thus this port will be open for a
+ * very long time.
+ */
+static void pti_port_shutdown(struct tty_port *port)
+{
+	if (port->tty->index == PTITTY_MINOR_START)
+		console_stop(&pti_console);
+}
+
+static const struct tty_port_operations tty_port_ops = {
+	.activate = pti_port_activate,
+	.shutdown = pti_port_shutdown,
+};
+
+/*
+ * Note the _probe() call sets everything up and ties the char and tty
+ * to successfully detecting the PTI device on the pci bus.
+ */
+
+/**
+ * pti_pci_probe()- Used to detect pti on the pci bus and set
+ *		    things up in the driver.
+ *
+ * @pdev- pci_dev struct values for pti.
+ * @ent-  pci_device_id struct for pti driver.
+ *
+ * Returns:
+ *	0 for success
+ *	otherwise, error
+ */
+static int __devinit pti_pci_probe(struct pci_dev *pdev,
+		const struct pci_device_id *ent)
+{
+	int retval = -EINVAL;
+	int pci_bar = 1;
+
+	dev_dbg(&pdev->dev, "%s %s(%d): PTI PCI ID %04x:%04x\n", __FILE__,
+			__func__, __LINE__, pdev->vendor, pdev->device);
+
+	retval = misc_register(&pti_char_driver);
+	if (retval) {
+		pr_err("%s(%d): CHAR registration failed of pti driver\n",
+			__func__, __LINE__);
+		pr_err("%s(%d): Error value returned: %d\n",
+			__func__, __LINE__, retval);
+		return retval;
+	}
+
+	retval = pci_enable_device(pdev);
+	if (retval != 0) {
+		dev_err(&pdev->dev,
+			"%s: pci_enable_device() returned error %d\n",
+			__func__, retval);
+		return retval;
+	}
+
+	drv_data = kzalloc(sizeof(*drv_data), GFP_KERNEL);
+
+	if (drv_data == NULL) {
+		retval = -ENOMEM;
+		dev_err(&pdev->dev,
+			"%s(%d): kmalloc() returned NULL memory.\n",
+			__func__, __LINE__);
+		return retval;
+	}
+	drv_data->pti_addr = pci_resource_start(pdev, pci_bar);
+
+	retval = pci_request_region(pdev, pci_bar, dev_name(&pdev->dev));
+	if (retval != 0) {
+		dev_err(&pdev->dev,
+			"%s(%d): pci_request_region() returned error %d\n",
+			__func__, __LINE__, retval);
+		kfree(drv_data);
+		return retval;
+	}
+	drv_data->aperture_base = drv_data->pti_addr+APERTURE_14;
+	drv_data->pti_ioaddr =
+		ioremap_nocache((u32)drv_data->aperture_base,
+		APERTURE_LEN);
+	if (!drv_data->pti_ioaddr) {
+		pci_release_region(pdev, pci_bar);
+		retval = -ENOMEM;
+		kfree(drv_data);
+		return retval;
+	}
+
+	pci_set_drvdata(pdev, drv_data);
+
+	tty_port_init(&drv_data->port);
+	drv_data->port.ops = &tty_port_ops;
+
+	tty_register_device(pti_tty_driver, 0, &pdev->dev);
+	tty_register_device(pti_tty_driver, 1, &pdev->dev);
+
+	register_console(&pti_console);
+
+	return retval;
+}
+
+static struct pci_driver pti_pci_driver = {
+	.name		= PCINAME,
+	.id_table	= pci_ids,
+	.probe		= pti_pci_probe,
+	.remove		= pti_pci_remove,
+};
+
+/**
+ *
+ * pti_init()- Overall entry/init call to the pti driver.
+ *             It starts the registration process with the kernel.
+ *
+ * Returns:
+ *	int __init, 0 for success
+ *	otherwise value is an error
+ *
+ */
+static int __init pti_init(void)
+{
+	int retval = -EINVAL;
+
+	/* First register module as tty device */
+
+	pti_tty_driver = alloc_tty_driver(1);
+	if (pti_tty_driver == NULL) {
+		pr_err("%s(%d): Memory allocation failed for ptiTTY driver\n",
+			__func__, __LINE__);
+		return -ENOMEM;
+	}
+
+	pti_tty_driver->owner			= THIS_MODULE;
+	pti_tty_driver->magic			= TTY_DRIVER_MAGIC;
+	pti_tty_driver->driver_name		= DRIVERNAME;
+	pti_tty_driver->name			= TTYNAME;
+	pti_tty_driver->major			= 0;
+	pti_tty_driver->minor_start		= PTITTY_MINOR_START;
+	pti_tty_driver->minor_num		= PTITTY_MINOR_NUM;
+	pti_tty_driver->num			= PTITTY_MINOR_NUM;
+	pti_tty_driver->type			= TTY_DRIVER_TYPE_SYSTEM;
+	pti_tty_driver->subtype			= SYSTEM_TYPE_SYSCONS;
+	pti_tty_driver->flags			= TTY_DRIVER_REAL_RAW |
+						  TTY_DRIVER_DYNAMIC_DEV;
+	pti_tty_driver->init_termios		= tty_std_termios;
+
+	tty_set_operations(pti_tty_driver, &pti_tty_driver_ops);
+
+	retval = tty_register_driver(pti_tty_driver);
+	if (retval) {
+		pr_err("%s(%d): TTY registration failed of pti driver\n",
+			__func__, __LINE__);
+		pr_err("%s(%d): Error value returned: %d\n",
+			__func__, __LINE__, retval);
+
+		pti_tty_driver = NULL;
+		return retval;
+	}
+
+	retval = pci_register_driver(&pti_pci_driver);
+
+	if (retval) {
+		pr_err("%s(%d): PCI registration failed of pti driver\n",
+			__func__, __LINE__);
+		pr_err("%s(%d): Error value returned: %d\n",
+			__func__, __LINE__, retval);
+
+		tty_unregister_driver(pti_tty_driver);
+		pr_err("%s(%d): Unregistering TTY part of pti driver\n",
+			__func__, __LINE__);
+		pti_tty_driver = NULL;
+		return retval;
+	}
+
+	return retval;
+}
+
+/**
+ * pti_exit()- Unregisters this module as a tty and pci driver.
+ */
+static void __exit pti_exit(void)
+{
+	int retval;
+
+	tty_unregister_device(pti_tty_driver, 0);
+	tty_unregister_device(pti_tty_driver, 1);
+
+	retval = tty_unregister_driver(pti_tty_driver);
+	if (retval) {
+		pr_err("%s(%d): TTY unregistration failed of pti driver\n",
+			__func__, __LINE__);
+		pr_err("%s(%d): Error value returned: %d\n",
+			__func__, __LINE__, retval);
+	}
+
+	pci_unregister_driver(&pti_pci_driver);
+
+	retval = misc_deregister(&pti_char_driver);
+	if (retval) {
+		pr_err("%s(%d): CHAR unregistration failed of pti driver\n",
+			__func__, __LINE__);
+		pr_err("%s(%d): Error value returned: %d\n",
+			__func__, __LINE__, retval);
+	}
+
+	unregister_console(&pti_console);
+	return;
+}
+
+module_init(pti_init);
+module_exit(pti_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Ken Mills, Jay Freyensee");
+MODULE_DESCRIPTION("PTI Driver");
+
diff -druN linux-2.6.39-libre/drivers/misc/sgi-gru/grufault.c linux-3.0-rc7-libre/drivers/misc/sgi-gru/grufault.c
--- linux-2.6.39-libre/drivers/misc/sgi-gru/grufault.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/misc/sgi-gru/grufault.c	2011-07-11 19:51:52.000000000 -0400
@@ -33,6 +33,7 @@
 #include <linux/io.h>
 #include <linux/uaccess.h>
 #include <linux/security.h>
+#include <linux/prefetch.h>
 #include <asm/pgtable.h>
 #include "gru.h"
 #include "grutables.h"
diff -druN linux-2.6.39-libre/drivers/misc/sgi-gru/grumain.c linux-3.0-rc7-libre/drivers/misc/sgi-gru/grumain.c
--- linux-2.6.39-libre/drivers/misc/sgi-gru/grumain.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/misc/sgi-gru/grumain.c	2011-07-11 19:51:52.000000000 -0400
@@ -28,6 +28,7 @@
 #include <linux/device.h>
 #include <linux/list.h>
 #include <linux/err.h>
+#include <linux/prefetch.h>
 #include <asm/uv/uv_hub.h>
 #include "gru.h"
 #include "grutables.h"
diff -druN linux-2.6.39-libre/drivers/misc/sgi-xp/xpnet.c linux-3.0-rc7-libre/drivers/misc/sgi-xp/xpnet.c
--- linux-2.6.39-libre/drivers/misc/sgi-xp/xpnet.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/misc/sgi-xp/xpnet.c	2011-07-11 19:51:52.000000000 -0400
@@ -495,14 +495,14 @@
 		}
 	}
 
+	dev->stats.tx_packets++;
+	dev->stats.tx_bytes += skb->len;
+
 	if (atomic_dec_return(&queued_msg->use_count) == 0) {
 		dev_kfree_skb(skb);
 		kfree(queued_msg);
 	}
 
-	dev->stats.tx_packets++;
-	dev->stats.tx_bytes += skb->len;
-
 	return NETDEV_TX_OK;
 }
 
diff -druN linux-2.6.39-libre/drivers/misc/spear13xx_pcie_gadget.c linux-3.0-rc7-libre/drivers/misc/spear13xx_pcie_gadget.c
--- linux-2.6.39-libre/drivers/misc/spear13xx_pcie_gadget.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/misc/spear13xx_pcie_gadget.c	2011-07-11 19:51:52.000000000 -0400
@@ -787,8 +787,8 @@
 
 	status = request_irq(irq, spear_pcie_gadget_irq, 0, pdev->name, NULL);
 	if (status) {
-		dev_err(&pdev->dev, "pcie gadget interrupt IRQ%d already \
-				claimed\n", irq);
+		dev_err(&pdev->dev,
+			"pcie gadget interrupt IRQ%d already claimed\n", irq);
 		goto err_iounmap;
 	}
 
@@ -845,7 +845,7 @@
 err_iounmap_app:
 	iounmap(config->va_app_base);
 err_kzalloc:
-	kfree(config);
+	kfree(target);
 err_rel_res:
 	release_mem_region(res1->start, resource_size(res1));
 err_rel_res0:
diff -druN linux-2.6.39-libre/drivers/misc/ti-st/Kconfig linux-3.0-rc7-libre/drivers/misc/ti-st/Kconfig
--- linux-2.6.39-libre/drivers/misc/ti-st/Kconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/misc/ti-st/Kconfig	2011-07-11 19:51:52.000000000 -0400
@@ -5,7 +5,7 @@
 menu "Texas Instruments shared transport line discipline"
 config TI_ST
 	tristate "Shared transport core driver"
-	depends on RFKILL
+	depends on NET && GPIOLIB
 	select FW_LOADER
 	help
 	  This enables the shared transport core driver for TI
diff -druN linux-2.6.39-libre/drivers/misc/ti-st/st_core.c linux-3.0-rc7-libre/drivers/misc/ti-st/st_core.c
--- linux-2.6.39-libre/drivers/misc/ti-st/st_core.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/misc/ti-st/st_core.c	2011-07-11 19:51:52.000000000 -0400
@@ -43,13 +43,15 @@
 	pr_info("%s: id %d\n", __func__, new_proto->chnl_id);
 	/* list now has the channel id as index itself */
 	st_gdata->list[new_proto->chnl_id] = new_proto;
+	st_gdata->is_registered[new_proto->chnl_id] = true;
 }
 
 static void remove_channel_from_table(struct st_data_s *st_gdata,
 		struct st_proto_s *proto)
 {
 	pr_info("%s: id %d\n", __func__, proto->chnl_id);
-	st_gdata->list[proto->chnl_id] = NULL;
+/*	st_gdata->list[proto->chnl_id] = NULL; */
+	st_gdata->is_registered[proto->chnl_id] = false;
 }
 
 /*
@@ -104,7 +106,7 @@
 
 	if (unlikely
 	    (st_gdata == NULL || st_gdata->rx_skb == NULL
-	     || st_gdata->list[chnl_id] == NULL)) {
+	     || st_gdata->is_registered[chnl_id] == false)) {
 		pr_err("chnl_id %d not registered, no data to send?",
 			   chnl_id);
 		kfree_skb(st_gdata->rx_skb);
@@ -141,14 +143,15 @@
 	unsigned char i = 0;
 	pr_info(" %s ", __func__);
 	for (i = 0; i < ST_MAX_CHANNELS; i++) {
-		if (likely(st_gdata != NULL && st_gdata->list[i] != NULL &&
-			   st_gdata->list[i]->reg_complete_cb != NULL)) {
+		if (likely(st_gdata != NULL &&
+			st_gdata->is_registered[i] == true &&
+				st_gdata->list[i]->reg_complete_cb != NULL)) {
 			st_gdata->list[i]->reg_complete_cb
 				(st_gdata->list[i]->priv_data, err);
 			pr_info("protocol %d's cb sent %d\n", i, err);
 			if (err) { /* cleanup registered protocol */
 				st_gdata->protos_registered--;
-				st_gdata->list[i] = NULL;
+				st_gdata->is_registered[i] = false;
 			}
 		}
 	}
@@ -475,9 +478,9 @@
 {
 	seq_printf(buf, "[%d]\nBT=%c\nFM=%c\nGPS=%c\n",
 			st_gdata->protos_registered,
-			st_gdata->list[0x04] != NULL ? 'R' : 'U',
-			st_gdata->list[0x08] != NULL ? 'R' : 'U',
-			st_gdata->list[0x09] != NULL ? 'R' : 'U');
+			st_gdata->is_registered[0x04] == true ? 'R' : 'U',
+			st_gdata->is_registered[0x08] == true ? 'R' : 'U',
+			st_gdata->is_registered[0x09] == true ? 'R' : 'U');
 }
 
 /********************************************************************/
@@ -504,7 +507,7 @@
 		return -EPROTONOSUPPORT;
 	}
 
-	if (st_gdata->list[new_proto->chnl_id] != NULL) {
+	if (st_gdata->is_registered[new_proto->chnl_id] == true) {
 		pr_err("chnl_id %d already registered", new_proto->chnl_id);
 		return -EALREADY;
 	}
@@ -563,7 +566,7 @@
 		/* check for already registered once more,
 		 * since the above check is old
 		 */
-		if (st_gdata->list[new_proto->chnl_id] != NULL) {
+		if (st_gdata->is_registered[new_proto->chnl_id] == true) {
 			pr_err(" proto %d already registered ",
 				   new_proto->chnl_id);
 			return -EALREADY;
@@ -602,7 +605,7 @@
 	pr_debug("%s: %d ", __func__, proto->chnl_id);
 
 	st_kim_ref(&st_gdata, 0);
-	if (proto->chnl_id >= ST_MAX_CHANNELS) {
+	if (!st_gdata || proto->chnl_id >= ST_MAX_CHANNELS) {
 		pr_err(" chnl_id %d not supported", proto->chnl_id);
 		return -EPROTONOSUPPORT;
 	}
diff -druN linux-2.6.39-libre/drivers/misc/ti-st/st_kim.c linux-3.0-rc7-libre/drivers/misc/ti-st/st_kim.c
--- linux-2.6.39-libre/drivers/misc/ti-st/st_kim.c	2011-05-19 02:16:44.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/misc/ti-st/st_kim.c	2011-07-21 06:58:45.000000000 -0400
@@ -30,6 +30,7 @@
 #include <linux/debugfs.h>
 #include <linux/seq_file.h>
 #include <linux/sched.h>
+#include <linux/sysfs.h>
 #include <linux/tty.h>
 
 #include <linux/skbuff.h>
@@ -244,9 +245,9 @@
 		pr_err("invalid action after change remote baud command");
 	} else {
 		*ptr = *ptr + sizeof(struct bts_action) +
-			((struct bts_action *)nxt_action)->size;
+			((struct bts_action *)cur_action)->size;
 		*len = *len - (sizeof(struct bts_action) +
-				((struct bts_action *)nxt_action)->size);
+				((struct bts_action *)cur_action)->size);
 		/* warn user on not commenting these in firmware */
 		pr_warn("skipping the wait event of change remote baud");
 	}
@@ -603,6 +604,10 @@
 	struct kim_data_s	*kim_gdata;
 	/* get kim_gdata reference from platform device */
 	pdev = st_get_plat_device(id);
+	if (!pdev) {
+		*core_data = NULL;
+		return;
+	}
 	kim_gdata = dev_get_drvdata(&pdev->dev);
 	*core_data = kim_gdata->core_data;
 }
diff -druN linux-2.6.39-libre/drivers/mmc/card/block.c linux-3.0-rc7-libre/drivers/mmc/card/block.c
--- linux-2.6.39-libre/drivers/mmc/card/block.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mmc/card/block.c	2011-07-11 19:51:52.000000000 -0400
@@ -31,7 +31,11 @@
 #include <linux/mutex.h>
 #include <linux/scatterlist.h>
 #include <linux/string_helpers.h>
+#include <linux/delay.h>
+#include <linux/capability.h>
+#include <linux/compat.h>
 
+#include <linux/mmc/ioctl.h>
 #include <linux/mmc/card.h>
 #include <linux/mmc/host.h>
 #include <linux/mmc/mmc.h>
@@ -48,6 +52,13 @@
 #endif
 #define MODULE_PARAM_PREFIX "mmcblk."
 
+#define INAND_CMD38_ARG_EXT_CSD  113
+#define INAND_CMD38_ARG_ERASE    0x00
+#define INAND_CMD38_ARG_TRIM     0x01
+#define INAND_CMD38_ARG_SECERASE 0x80
+#define INAND_CMD38_ARG_SECTRIM1 0x81
+#define INAND_CMD38_ARG_SECTRIM2 0x88
+
 static DEFINE_MUTEX(block_mutex);
 
 /*
@@ -64,6 +75,7 @@
 
 /* 256 minors, so at most 256 separate devices */
 static DECLARE_BITMAP(dev_use, 256);
+static DECLARE_BITMAP(name_use, 256);
 
 /*
  * There is one mmc_blk_data per slot.
@@ -72,9 +84,24 @@
 	spinlock_t	lock;
 	struct gendisk	*disk;
 	struct mmc_queue queue;
+	struct list_head part;
+
+	unsigned int	flags;
+#define MMC_BLK_CMD23	(1 << 0)	/* Can do SET_BLOCK_COUNT for multiblock */
+#define MMC_BLK_REL_WR	(1 << 1)	/* MMC Reliable write support */
 
 	unsigned int	usage;
 	unsigned int	read_only;
+	unsigned int	part_type;
+	unsigned int	name_idx;
+
+	/*
+	 * Only set in main mmc_blk_data associated
+	 * with mmc_card with mmc_set_drvdata, and keeps
+	 * track of the current selected device partition.
+	 */
+	unsigned int	part_curr;
+	struct device_attribute force_ro;
 };
 
 static DEFINE_MUTEX(open_lock);
@@ -97,17 +124,22 @@
 	return md;
 }
 
+static inline int mmc_get_devidx(struct gendisk *disk)
+{
+	int devmaj = MAJOR(disk_devt(disk));
+	int devidx = MINOR(disk_devt(disk)) / perdev_minors;
+
+	if (!devmaj)
+		devidx = disk->first_minor / perdev_minors;
+	return devidx;
+}
+
 static void mmc_blk_put(struct mmc_blk_data *md)
 {
 	mutex_lock(&open_lock);
 	md->usage--;
 	if (md->usage == 0) {
-		int devmaj = MAJOR(disk_devt(md->disk));
-		int devidx = MINOR(disk_devt(md->disk)) / perdev_minors;
-
-		if (!devmaj)
-			devidx = md->disk->first_minor / perdev_minors;
-
+		int devidx = mmc_get_devidx(md->disk);
 		blk_cleanup_queue(md->queue.queue);
 
 		__clear_bit(devidx, dev_use);
@@ -118,6 +150,38 @@
 	mutex_unlock(&open_lock);
 }
 
+static ssize_t force_ro_show(struct device *dev, struct device_attribute *attr,
+			     char *buf)
+{
+	int ret;
+	struct mmc_blk_data *md = mmc_blk_get(dev_to_disk(dev));
+
+	ret = snprintf(buf, PAGE_SIZE, "%d",
+		       get_disk_ro(dev_to_disk(dev)) ^
+		       md->read_only);
+	mmc_blk_put(md);
+	return ret;
+}
+
+static ssize_t force_ro_store(struct device *dev, struct device_attribute *attr,
+			      const char *buf, size_t count)
+{
+	int ret;
+	char *end;
+	struct mmc_blk_data *md = mmc_blk_get(dev_to_disk(dev));
+	unsigned long set = simple_strtoul(buf, &end, 0);
+	if (end == buf) {
+		ret = -EINVAL;
+		goto out;
+	}
+
+	set_disk_ro(dev_to_disk(dev), set || md->read_only);
+	ret = count;
+out:
+	mmc_blk_put(md);
+	return ret;
+}
+
 static int mmc_blk_open(struct block_device *bdev, fmode_t mode)
 {
 	struct mmc_blk_data *md = mmc_blk_get(bdev->bd_disk);
@@ -158,35 +222,255 @@
 	return 0;
 }
 
+struct mmc_blk_ioc_data {
+	struct mmc_ioc_cmd ic;
+	unsigned char *buf;
+	u64 buf_bytes;
+};
+
+static struct mmc_blk_ioc_data *mmc_blk_ioctl_copy_from_user(
+	struct mmc_ioc_cmd __user *user)
+{
+	struct mmc_blk_ioc_data *idata;
+	int err;
+
+	idata = kzalloc(sizeof(*idata), GFP_KERNEL);
+	if (!idata) {
+		err = -ENOMEM;
+		goto out;
+	}
+
+	if (copy_from_user(&idata->ic, user, sizeof(idata->ic))) {
+		err = -EFAULT;
+		goto idata_err;
+	}
+
+	idata->buf_bytes = (u64) idata->ic.blksz * idata->ic.blocks;
+	if (idata->buf_bytes > MMC_IOC_MAX_BYTES) {
+		err = -EOVERFLOW;
+		goto idata_err;
+	}
+
+	idata->buf = kzalloc(idata->buf_bytes, GFP_KERNEL);
+	if (!idata->buf) {
+		err = -ENOMEM;
+		goto idata_err;
+	}
+
+	if (copy_from_user(idata->buf, (void __user *)(unsigned long)
+					idata->ic.data_ptr, idata->buf_bytes)) {
+		err = -EFAULT;
+		goto copy_err;
+	}
+
+	return idata;
+
+copy_err:
+	kfree(idata->buf);
+idata_err:
+	kfree(idata);
+out:
+	return ERR_PTR(err);
+}
+
+static int mmc_blk_ioctl_cmd(struct block_device *bdev,
+	struct mmc_ioc_cmd __user *ic_ptr)
+{
+	struct mmc_blk_ioc_data *idata;
+	struct mmc_blk_data *md;
+	struct mmc_card *card;
+	struct mmc_command cmd = {0};
+	struct mmc_data data = {0};
+	struct mmc_request mrq = {0};
+	struct scatterlist sg;
+	int err;
+
+	/*
+	 * The caller must have CAP_SYS_RAWIO, and must be calling this on the
+	 * whole block device, not on a partition.  This prevents overspray
+	 * between sibling partitions.
+	 */
+	if ((!capable(CAP_SYS_RAWIO)) || (bdev != bdev->bd_contains))
+		return -EPERM;
+
+	idata = mmc_blk_ioctl_copy_from_user(ic_ptr);
+	if (IS_ERR(idata))
+		return PTR_ERR(idata);
+
+	cmd.opcode = idata->ic.opcode;
+	cmd.arg = idata->ic.arg;
+	cmd.flags = idata->ic.flags;
+
+	data.sg = &sg;
+	data.sg_len = 1;
+	data.blksz = idata->ic.blksz;
+	data.blocks = idata->ic.blocks;
+
+	sg_init_one(data.sg, idata->buf, idata->buf_bytes);
+
+	if (idata->ic.write_flag)
+		data.flags = MMC_DATA_WRITE;
+	else
+		data.flags = MMC_DATA_READ;
+
+	mrq.cmd = &cmd;
+	mrq.data = &data;
+
+	md = mmc_blk_get(bdev->bd_disk);
+	if (!md) {
+		err = -EINVAL;
+		goto cmd_done;
+	}
+
+	card = md->queue.card;
+	if (IS_ERR(card)) {
+		err = PTR_ERR(card);
+		goto cmd_done;
+	}
+
+	mmc_claim_host(card->host);
+
+	if (idata->ic.is_acmd) {
+		err = mmc_app_cmd(card->host, card);
+		if (err)
+			goto cmd_rel_host;
+	}
+
+	/* data.flags must already be set before doing this. */
+	mmc_set_data_timeout(&data, card);
+	/* Allow overriding the timeout_ns for empirical tuning. */
+	if (idata->ic.data_timeout_ns)
+		data.timeout_ns = idata->ic.data_timeout_ns;
+
+	if ((cmd.flags & MMC_RSP_R1B) == MMC_RSP_R1B) {
+		/*
+		 * Pretend this is a data transfer and rely on the host driver
+		 * to compute timeout.  When all host drivers support
+		 * cmd.cmd_timeout for R1B, this can be changed to:
+		 *
+		 *     mrq.data = NULL;
+		 *     cmd.cmd_timeout = idata->ic.cmd_timeout_ms;
+		 */
+		data.timeout_ns = idata->ic.cmd_timeout_ms * 1000000;
+	}
+
+	mmc_wait_for_req(card->host, &mrq);
+
+	if (cmd.error) {
+		dev_err(mmc_dev(card->host), "%s: cmd error %d\n",
+						__func__, cmd.error);
+		err = cmd.error;
+		goto cmd_rel_host;
+	}
+	if (data.error) {
+		dev_err(mmc_dev(card->host), "%s: data error %d\n",
+						__func__, data.error);
+		err = data.error;
+		goto cmd_rel_host;
+	}
+
+	/*
+	 * According to the SD specs, some commands require a delay after
+	 * issuing the command.
+	 */
+	if (idata->ic.postsleep_min_us)
+		usleep_range(idata->ic.postsleep_min_us, idata->ic.postsleep_max_us);
+
+	if (copy_to_user(&(ic_ptr->response), cmd.resp, sizeof(cmd.resp))) {
+		err = -EFAULT;
+		goto cmd_rel_host;
+	}
+
+	if (!idata->ic.write_flag) {
+		if (copy_to_user((void __user *)(unsigned long) idata->ic.data_ptr,
+						idata->buf, idata->buf_bytes)) {
+			err = -EFAULT;
+			goto cmd_rel_host;
+		}
+	}
+
+cmd_rel_host:
+	mmc_release_host(card->host);
+
+cmd_done:
+	mmc_blk_put(md);
+	kfree(idata->buf);
+	kfree(idata);
+	return err;
+}
+
+static int mmc_blk_ioctl(struct block_device *bdev, fmode_t mode,
+	unsigned int cmd, unsigned long arg)
+{
+	int ret = -EINVAL;
+	if (cmd == MMC_IOC_CMD)
+		ret = mmc_blk_ioctl_cmd(bdev, (struct mmc_ioc_cmd __user *)arg);
+	return ret;
+}
+
+#ifdef CONFIG_COMPAT
+static int mmc_blk_compat_ioctl(struct block_device *bdev, fmode_t mode,
+	unsigned int cmd, unsigned long arg)
+{
+	return mmc_blk_ioctl(bdev, mode, cmd, (unsigned long) compat_ptr(arg));
+}
+#endif
+
 static const struct block_device_operations mmc_bdops = {
 	.open			= mmc_blk_open,
 	.release		= mmc_blk_release,
 	.getgeo			= mmc_blk_getgeo,
 	.owner			= THIS_MODULE,
+	.ioctl			= mmc_blk_ioctl,
+#ifdef CONFIG_COMPAT
+	.compat_ioctl		= mmc_blk_compat_ioctl,
+#endif
 };
 
 struct mmc_blk_request {
 	struct mmc_request	mrq;
+	struct mmc_command	sbc;
 	struct mmc_command	cmd;
 	struct mmc_command	stop;
 	struct mmc_data		data;
 };
 
+static inline int mmc_blk_part_switch(struct mmc_card *card,
+				      struct mmc_blk_data *md)
+{
+	int ret;
+	struct mmc_blk_data *main_md = mmc_get_drvdata(card);
+	if (main_md->part_curr == md->part_type)
+		return 0;
+
+	if (mmc_card_mmc(card)) {
+		card->ext_csd.part_config &= ~EXT_CSD_PART_CONFIG_ACC_MASK;
+		card->ext_csd.part_config |= md->part_type;
+
+		ret = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
+				 EXT_CSD_PART_CONFIG, card->ext_csd.part_config,
+				 card->ext_csd.part_time);
+		if (ret)
+			return ret;
+}
+
+	main_md->part_curr = md->part_type;
+	return 0;
+}
+
 static u32 mmc_sd_num_wr_blocks(struct mmc_card *card)
 {
 	int err;
 	u32 result;
 	__be32 *blocks;
 
-	struct mmc_request mrq;
-	struct mmc_command cmd;
-	struct mmc_data data;
+	struct mmc_request mrq = {0};
+	struct mmc_command cmd = {0};
+	struct mmc_data data = {0};
 	unsigned int timeout_us;
 
 	struct scatterlist sg;
 
-	memset(&cmd, 0, sizeof(struct mmc_command));
-
 	cmd.opcode = MMC_APP_CMD;
 	cmd.arg = card->rca << 16;
 	cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_AC;
@@ -203,8 +487,6 @@
 	cmd.arg = 0;
 	cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_ADTC;
 
-	memset(&data, 0, sizeof(struct mmc_data));
-
 	data.timeout_ns = card->csd.tacc_ns * 100;
 	data.timeout_clks = card->csd.tacc_clks * 100;
 
@@ -223,8 +505,6 @@
 	data.sg = &sg;
 	data.sg_len = 1;
 
-	memset(&mrq, 0, sizeof(struct mmc_request));
-
 	mrq.cmd = &cmd;
 	mrq.data = &data;
 
@@ -247,10 +527,9 @@
 
 static u32 get_card_status(struct mmc_card *card, struct request *req)
 {
-	struct mmc_command cmd;
+	struct mmc_command cmd = {0};
 	int err;
 
-	memset(&cmd, 0, sizeof(struct mmc_command));
 	cmd.opcode = MMC_SEND_STATUS;
 	if (!mmc_host_is_spi(card->host))
 		cmd.arg = card->rca << 16;
@@ -269,8 +548,6 @@
 	unsigned int from, nr, arg;
 	int err = 0;
 
-	mmc_claim_host(card->host);
-
 	if (!mmc_can_erase(card)) {
 		err = -EOPNOTSUPP;
 		goto out;
@@ -284,14 +561,22 @@
 	else
 		arg = MMC_ERASE_ARG;
 
+	if (card->quirks & MMC_QUIRK_INAND_CMD38) {
+		err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
+				 INAND_CMD38_ARG_EXT_CSD,
+				 arg == MMC_TRIM_ARG ?
+				 INAND_CMD38_ARG_TRIM :
+				 INAND_CMD38_ARG_ERASE,
+				 0);
+		if (err)
+			goto out;
+	}
 	err = mmc_erase(card, from, nr, arg);
 out:
 	spin_lock_irq(&md->lock);
 	__blk_end_request(req, err, blk_rq_bytes(req));
 	spin_unlock_irq(&md->lock);
 
-	mmc_release_host(card->host);
-
 	return err ? 0 : 1;
 }
 
@@ -303,8 +588,6 @@
 	unsigned int from, nr, arg;
 	int err = 0;
 
-	mmc_claim_host(card->host);
-
 	if (!mmc_can_secure_erase_trim(card)) {
 		err = -EOPNOTSUPP;
 		goto out;
@@ -318,19 +601,74 @@
 	else
 		arg = MMC_SECURE_ERASE_ARG;
 
+	if (card->quirks & MMC_QUIRK_INAND_CMD38) {
+		err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
+				 INAND_CMD38_ARG_EXT_CSD,
+				 arg == MMC_SECURE_TRIM1_ARG ?
+				 INAND_CMD38_ARG_SECTRIM1 :
+				 INAND_CMD38_ARG_SECERASE,
+				 0);
+		if (err)
+			goto out;
+	}
 	err = mmc_erase(card, from, nr, arg);
-	if (!err && arg == MMC_SECURE_TRIM1_ARG)
+	if (!err && arg == MMC_SECURE_TRIM1_ARG) {
+		if (card->quirks & MMC_QUIRK_INAND_CMD38) {
+			err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
+					 INAND_CMD38_ARG_EXT_CSD,
+					 INAND_CMD38_ARG_SECTRIM2,
+					 0);
+			if (err)
+				goto out;
+		}
 		err = mmc_erase(card, from, nr, MMC_SECURE_TRIM2_ARG);
+	}
 out:
 	spin_lock_irq(&md->lock);
 	__blk_end_request(req, err, blk_rq_bytes(req));
 	spin_unlock_irq(&md->lock);
 
-	mmc_release_host(card->host);
-
 	return err ? 0 : 1;
 }
 
+static int mmc_blk_issue_flush(struct mmc_queue *mq, struct request *req)
+{
+	struct mmc_blk_data *md = mq->data;
+
+	/*
+	 * No-op, only service this because we need REQ_FUA for reliable
+	 * writes.
+	 */
+	spin_lock_irq(&md->lock);
+	__blk_end_request_all(req, 0);
+	spin_unlock_irq(&md->lock);
+
+	return 1;
+}
+
+/*
+ * Reformat current write as a reliable write, supporting
+ * both legacy and the enhanced reliable write MMC cards.
+ * In each transfer we'll handle only as much as a single
+ * reliable write can handle, thus finish the request in
+ * partial completions.
+ */
+static inline void mmc_apply_rel_rw(struct mmc_blk_request *brq,
+				    struct mmc_card *card,
+				    struct request *req)
+{
+	if (!(card->ext_csd.rel_param & EXT_CSD_WR_REL_PARAM_EN)) {
+		/* Legacy mode imposes restrictions on transfers. */
+		if (!IS_ALIGNED(brq->cmd.arg, card->ext_csd.rel_sectors))
+			brq->data.blocks = 1;
+
+		if (brq->data.blocks > card->ext_csd.rel_sectors)
+			brq->data.blocks = card->ext_csd.rel_sectors;
+		else if (brq->data.blocks < card->ext_csd.rel_sectors)
+			brq->data.blocks = 1;
+	}
+}
+
 static int mmc_blk_issue_rw_rq(struct mmc_queue *mq, struct request *req)
 {
 	struct mmc_blk_data *md = mq->data;
@@ -338,10 +676,17 @@
 	struct mmc_blk_request brq;
 	int ret = 1, disable_multi = 0;
 
-	mmc_claim_host(card->host);
+	/*
+	 * Reliable writes are used to implement Forced Unit Access and
+	 * REQ_META accesses, and are supported only on MMCs.
+	 */
+	bool do_rel_wr = ((req->cmd_flags & REQ_FUA) ||
+			  (req->cmd_flags & REQ_META)) &&
+		(rq_data_dir(req) == WRITE) &&
+		(md->flags & MMC_BLK_REL_WR);
 
 	do {
-		struct mmc_command cmd;
+		struct mmc_command cmd = {0};
 		u32 readcmd, writecmd, status = 0;
 
 		memset(&brq, 0, sizeof(struct mmc_blk_request));
@@ -374,12 +719,12 @@
 		if (disable_multi && brq.data.blocks > 1)
 			brq.data.blocks = 1;
 
-		if (brq.data.blocks > 1) {
+		if (brq.data.blocks > 1 || do_rel_wr) {
 			/* SPI multiblock writes terminate using a special
 			 * token, not a STOP_TRANSMISSION request.
 			 */
-			if (!mmc_host_is_spi(card->host)
-					|| rq_data_dir(req) == READ)
+			if (!mmc_host_is_spi(card->host) ||
+			    rq_data_dir(req) == READ)
 				brq.mrq.stop = &brq.stop;
 			readcmd = MMC_READ_MULTIPLE_BLOCK;
 			writecmd = MMC_WRITE_MULTIPLE_BLOCK;
@@ -396,6 +741,38 @@
 			brq.data.flags |= MMC_DATA_WRITE;
 		}
 
+		if (do_rel_wr)
+			mmc_apply_rel_rw(&brq, card, req);
+
+		/*
+		 * Pre-defined multi-block transfers are preferable to
+		 * open ended-ones (and necessary for reliable writes).
+		 * However, it is not sufficient to just send CMD23,
+		 * and avoid the final CMD12, as on an error condition
+		 * CMD12 (stop) needs to be sent anyway. This, coupled
+		 * with Auto-CMD23 enhancements provided by some
+		 * hosts, means that the complexity of dealing
+		 * with this is best left to the host. If CMD23 is
+		 * supported by card and host, we'll fill sbc in and let
+		 * the host deal with handling it correctly. This means
+		 * that for hosts that don't expose MMC_CAP_CMD23, no
+		 * change of behavior will be observed.
+		 *
+		 * N.B: Some MMC cards experience perf degradation.
+		 * We'll avoid using CMD23-bounded multiblock writes for
+		 * these, while retaining features like reliable writes.
+		 */
+
+		if ((md->flags & MMC_BLK_CMD23) &&
+		    mmc_op_multi(brq.cmd.opcode) &&
+		    (do_rel_wr || !(card->quirks & MMC_QUIRK_BLK_NO_CMD23))) {
+			brq.sbc.opcode = MMC_SET_BLOCK_COUNT;
+			brq.sbc.arg = brq.data.blocks |
+				(do_rel_wr ? (1 << 31) : 0);
+			brq.sbc.flags = MMC_RSP_R1 | MMC_CMD_AC;
+			brq.mrq.sbc = &brq.sbc;
+		}
+
 		mmc_set_data_timeout(&brq.data, card);
 
 		brq.data.sg = mq->sg;
@@ -431,7 +808,8 @@
 		 * until later as we need to wait for the card to leave
 		 * programming mode even when things go wrong.
 		 */
-		if (brq.cmd.error || brq.data.error || brq.stop.error) {
+		if (brq.sbc.error || brq.cmd.error ||
+		    brq.data.error || brq.stop.error) {
 			if (brq.data.blocks > 1 && rq_data_dir(req) == READ) {
 				/* Redo read one sector at a time */
 				printk(KERN_WARNING "%s: retrying using single "
@@ -442,6 +820,13 @@
 			status = get_card_status(card, req);
 		}
 
+		if (brq.sbc.error) {
+			printk(KERN_ERR "%s: error %d sending SET_BLOCK_COUNT "
+			       "command, response %#x, card status %#x\n",
+			       req->rq_disk->disk_name, brq.sbc.error,
+			       brq.sbc.resp[0], status);
+		}
+
 		if (brq.cmd.error) {
 			printk(KERN_ERR "%s: error %d sending read/write "
 			       "command, response %#x, card status %#x\n",
@@ -520,8 +905,6 @@
 		spin_unlock_irq(&md->lock);
 	} while (ret);
 
-	mmc_release_host(card->host);
-
 	return 1;
 
  cmd_err:
@@ -548,8 +931,6 @@
 		spin_unlock_irq(&md->lock);
 	}
 
-	mmc_release_host(card->host);
-
 	spin_lock_irq(&md->lock);
 	while (ret)
 		ret = __blk_end_request(req, -EIO, blk_rq_cur_bytes(req));
@@ -560,14 +941,31 @@
 
 static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req)
 {
+	int ret;
+	struct mmc_blk_data *md = mq->data;
+	struct mmc_card *card = md->queue.card;
+
+	mmc_claim_host(card->host);
+	ret = mmc_blk_part_switch(card, md);
+	if (ret) {
+		ret = 0;
+		goto out;
+	}
+
 	if (req->cmd_flags & REQ_DISCARD) {
 		if (req->cmd_flags & REQ_SECURE)
-			return mmc_blk_issue_secdiscard_rq(mq, req);
+			ret = mmc_blk_issue_secdiscard_rq(mq, req);
 		else
-			return mmc_blk_issue_discard_rq(mq, req);
+			ret = mmc_blk_issue_discard_rq(mq, req);
+	} else if (req->cmd_flags & REQ_FLUSH) {
+		ret = mmc_blk_issue_flush(mq, req);
 	} else {
-		return mmc_blk_issue_rw_rq(mq, req);
+		ret = mmc_blk_issue_rw_rq(mq, req);
 	}
+
+out:
+	mmc_release_host(card->host);
+	return ret;
 }
 
 static inline int mmc_blk_readonly(struct mmc_card *card)
@@ -576,7 +974,11 @@
 	       !(card->csd.cmdclass & CCC_BLOCK_WRITE);
 }
 
-static struct mmc_blk_data *mmc_blk_alloc(struct mmc_card *card)
+static struct mmc_blk_data *mmc_blk_alloc_req(struct mmc_card *card,
+					      struct device *parent,
+					      sector_t size,
+					      bool default_ro,
+					      const char *subname)
 {
 	struct mmc_blk_data *md;
 	int devidx, ret;
@@ -592,6 +994,19 @@
 		goto out;
 	}
 
+	/*
+	 * !subname implies we are creating main mmc_blk_data that will be
+	 * associated with mmc_card with mmc_set_drvdata. Due to device
+	 * partitions, devidx will not coincide with a per-physical card
+	 * index anymore so we keep track of a name index.
+	 */
+	if (!subname) {
+		md->name_idx = find_first_zero_bit(name_use, max_devices);
+		__set_bit(md->name_idx, name_use);
+	}
+	else
+		md->name_idx = ((struct mmc_blk_data *)
+				dev_to_disk(parent)->private_data)->name_idx;
 
 	/*
 	 * Set the read-only status based on the supported commands
@@ -606,9 +1021,10 @@
 	}
 
 	spin_lock_init(&md->lock);
+	INIT_LIST_HEAD(&md->part);
 	md->usage = 1;
 
-	ret = mmc_init_queue(&md->queue, card, &md->lock);
+	ret = mmc_init_queue(&md->queue, card, &md->lock, subname);
 	if (ret)
 		goto err_putdisk;
 
@@ -620,8 +1036,8 @@
 	md->disk->fops = &mmc_bdops;
 	md->disk->private_data = md;
 	md->disk->queue = md->queue.queue;
-	md->disk->driverfs_dev = &card->dev;
-	set_disk_ro(md->disk, md->read_only);
+	md->disk->driverfs_dev = parent;
+	set_disk_ro(md->disk, md->read_only || default_ro);
 
 	/*
 	 * As discussed on lkml, GENHD_FL_REMOVABLE should:
@@ -636,32 +1052,107 @@
 	 */
 
 	snprintf(md->disk->disk_name, sizeof(md->disk->disk_name),
-		"mmcblk%d", devidx);
+		 "mmcblk%d%s", md->name_idx, subname ? subname : "");
 
 	blk_queue_logical_block_size(md->queue.queue, 512);
+	set_capacity(md->disk, size);
+
+	if (mmc_host_cmd23(card->host)) {
+		if (mmc_card_mmc(card) ||
+		    (mmc_card_sd(card) &&
+		     card->scr.cmds & SD_SCR_CMD23_SUPPORT))
+			md->flags |= MMC_BLK_CMD23;
+	}
+
+	if (mmc_card_mmc(card) &&
+	    md->flags & MMC_BLK_CMD23 &&
+	    ((card->ext_csd.rel_param & EXT_CSD_WR_REL_PARAM_EN) ||
+	     card->ext_csd.rel_sectors)) {
+		md->flags |= MMC_BLK_REL_WR;
+		blk_queue_flush(md->queue.queue, REQ_FLUSH | REQ_FUA);
+	}
+
+	return md;
+
+ err_putdisk:
+	put_disk(md->disk);
+ err_kfree:
+	kfree(md);
+ out:
+	return ERR_PTR(ret);
+}
+
+static struct mmc_blk_data *mmc_blk_alloc(struct mmc_card *card)
+{
+	sector_t size;
+	struct mmc_blk_data *md;
 
 	if (!mmc_card_sd(card) && mmc_card_blockaddr(card)) {
 		/*
 		 * The EXT_CSD sector count is in number or 512 byte
 		 * sectors.
 		 */
-		set_capacity(md->disk, card->ext_csd.sectors);
+		size = card->ext_csd.sectors;
 	} else {
 		/*
 		 * The CSD capacity field is in units of read_blkbits.
 		 * set_capacity takes units of 512 bytes.
 		 */
-		set_capacity(md->disk,
-			card->csd.capacity << (card->csd.read_blkbits - 9));
+		size = card->csd.capacity << (card->csd.read_blkbits - 9);
 	}
+
+	md = mmc_blk_alloc_req(card, &card->dev, size, false, NULL);
 	return md;
+}
 
- err_putdisk:
-	put_disk(md->disk);
- err_kfree:
-	kfree(md);
- out:
-	return ERR_PTR(ret);
+static int mmc_blk_alloc_part(struct mmc_card *card,
+			      struct mmc_blk_data *md,
+			      unsigned int part_type,
+			      sector_t size,
+			      bool default_ro,
+			      const char *subname)
+{
+	char cap_str[10];
+	struct mmc_blk_data *part_md;
+
+	part_md = mmc_blk_alloc_req(card, disk_to_dev(md->disk), size, default_ro,
+				    subname);
+	if (IS_ERR(part_md))
+		return PTR_ERR(part_md);
+	part_md->part_type = part_type;
+	list_add(&part_md->part, &md->part);
+
+	string_get_size((u64)get_capacity(part_md->disk) << 9, STRING_UNITS_2,
+			cap_str, sizeof(cap_str));
+	printk(KERN_INFO "%s: %s %s partition %u %s\n",
+	       part_md->disk->disk_name, mmc_card_id(card),
+	       mmc_card_name(card), part_md->part_type, cap_str);
+	return 0;
+}
+
+static int mmc_blk_alloc_parts(struct mmc_card *card, struct mmc_blk_data *md)
+{
+	int ret = 0;
+
+	if (!mmc_card_mmc(card))
+		return 0;
+
+	if (card->ext_csd.boot_size) {
+		ret = mmc_blk_alloc_part(card, md, EXT_CSD_PART_CONFIG_ACC_BOOT0,
+					 card->ext_csd.boot_size >> 9,
+					 true,
+					 "boot0");
+		if (ret)
+			return ret;
+		ret = mmc_blk_alloc_part(card, md, EXT_CSD_PART_CONFIG_ACC_BOOT1,
+					 card->ext_csd.boot_size >> 9,
+					 true,
+					 "boot1");
+		if (ret)
+			return ret;
+	}
+
+	return ret;
 }
 
 static int
@@ -682,9 +1173,81 @@
 	return 0;
 }
 
+static void mmc_blk_remove_req(struct mmc_blk_data *md)
+{
+	if (md) {
+		if (md->disk->flags & GENHD_FL_UP) {
+			device_remove_file(disk_to_dev(md->disk), &md->force_ro);
+
+			/* Stop new requests from getting into the queue */
+			del_gendisk(md->disk);
+		}
+
+		/* Then flush out any already in there */
+		mmc_cleanup_queue(&md->queue);
+		mmc_blk_put(md);
+	}
+}
+
+static void mmc_blk_remove_parts(struct mmc_card *card,
+				 struct mmc_blk_data *md)
+{
+	struct list_head *pos, *q;
+	struct mmc_blk_data *part_md;
+
+	__clear_bit(md->name_idx, name_use);
+	list_for_each_safe(pos, q, &md->part) {
+		part_md = list_entry(pos, struct mmc_blk_data, part);
+		list_del(pos);
+		mmc_blk_remove_req(part_md);
+	}
+}
+
+static int mmc_add_disk(struct mmc_blk_data *md)
+{
+	int ret;
+
+	add_disk(md->disk);
+	md->force_ro.show = force_ro_show;
+	md->force_ro.store = force_ro_store;
+	sysfs_attr_init(&md->force_ro.attr);
+	md->force_ro.attr.name = "force_ro";
+	md->force_ro.attr.mode = S_IRUGO | S_IWUSR;
+	ret = device_create_file(disk_to_dev(md->disk), &md->force_ro);
+	if (ret)
+		del_gendisk(md->disk);
+
+	return ret;
+}
+
+static const struct mmc_fixup blk_fixups[] =
+{
+	MMC_FIXUP("SEM02G", 0x2, 0x100, add_quirk, MMC_QUIRK_INAND_CMD38),
+	MMC_FIXUP("SEM04G", 0x2, 0x100, add_quirk, MMC_QUIRK_INAND_CMD38),
+	MMC_FIXUP("SEM08G", 0x2, 0x100, add_quirk, MMC_QUIRK_INAND_CMD38),
+	MMC_FIXUP("SEM16G", 0x2, 0x100, add_quirk, MMC_QUIRK_INAND_CMD38),
+	MMC_FIXUP("SEM32G", 0x2, 0x100, add_quirk, MMC_QUIRK_INAND_CMD38),
+
+	/*
+	 * Some MMC cards experience performance degradation with CMD23
+	 * instead of CMD12-bounded multiblock transfers. For now we'll
+	 * black list what's bad...
+	 * - Certain Toshiba cards.
+	 *
+	 * N.B. This doesn't affect SD cards.
+	 */
+	MMC_FIXUP("MMC08G", 0x11, CID_OEMID_ANY, add_quirk_mmc,
+		  MMC_QUIRK_BLK_NO_CMD23),
+	MMC_FIXUP("MMC16G", 0x11, CID_OEMID_ANY, add_quirk_mmc,
+		  MMC_QUIRK_BLK_NO_CMD23),
+	MMC_FIXUP("MMC32G", 0x11, CID_OEMID_ANY, add_quirk_mmc,
+		  MMC_QUIRK_BLK_NO_CMD23),
+	END_FIXUP
+};
+
 static int mmc_blk_probe(struct mmc_card *card)
 {
-	struct mmc_blk_data *md;
+	struct mmc_blk_data *md, *part_md;
 	int err;
 	char cap_str[10];
 
@@ -708,14 +1271,24 @@
 		md->disk->disk_name, mmc_card_id(card), mmc_card_name(card),
 		cap_str, md->read_only ? "(ro)" : "");
 
+	if (mmc_blk_alloc_parts(card, md))
+		goto out;
+
 	mmc_set_drvdata(card, md);
-	add_disk(md->disk);
+	mmc_fixup_device(card, blk_fixups);
+
+	if (mmc_add_disk(md))
+		goto out;
+
+	list_for_each_entry(part_md, &md->part, part) {
+		if (mmc_add_disk(part_md))
+			goto out;
+	}
 	return 0;
 
  out:
-	mmc_cleanup_queue(&md->queue);
-	mmc_blk_put(md);
-
+	mmc_blk_remove_parts(card, md);
+	mmc_blk_remove_req(md);
 	return err;
 }
 
@@ -723,36 +1296,46 @@
 {
 	struct mmc_blk_data *md = mmc_get_drvdata(card);
 
-	if (md) {
-		/* Stop new requests from getting into the queue */
-		del_gendisk(md->disk);
-
-		/* Then flush out any already in there */
-		mmc_cleanup_queue(&md->queue);
-
-		mmc_blk_put(md);
-	}
+	mmc_blk_remove_parts(card, md);
+	mmc_claim_host(card->host);
+	mmc_blk_part_switch(card, md);
+	mmc_release_host(card->host);
+	mmc_blk_remove_req(md);
 	mmc_set_drvdata(card, NULL);
 }
 
 #ifdef CONFIG_PM
 static int mmc_blk_suspend(struct mmc_card *card, pm_message_t state)
 {
+	struct mmc_blk_data *part_md;
 	struct mmc_blk_data *md = mmc_get_drvdata(card);
 
 	if (md) {
 		mmc_queue_suspend(&md->queue);
+		list_for_each_entry(part_md, &md->part, part) {
+			mmc_queue_suspend(&part_md->queue);
+		}
 	}
 	return 0;
 }
 
 static int mmc_blk_resume(struct mmc_card *card)
 {
+	struct mmc_blk_data *part_md;
 	struct mmc_blk_data *md = mmc_get_drvdata(card);
 
 	if (md) {
 		mmc_blk_set_blksize(md, card);
+
+		/*
+		 * Resume involves the card going into idle state,
+		 * so current partition is always the main one.
+		 */
+		md->part_curr = md->part_type;
 		mmc_queue_resume(&md->queue);
+		list_for_each_entry(part_md, &md->part, part) {
+			mmc_queue_resume(&part_md->queue);
+		}
 	}
 	return 0;
 }
diff -druN linux-2.6.39-libre/drivers/mmc/card/mmc_test.c linux-3.0-rc7-libre/drivers/mmc/card/mmc_test.c
--- linux-2.6.39-libre/drivers/mmc/card/mmc_test.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mmc/card/mmc_test.c	2011-07-11 19:51:52.000000000 -0400
@@ -212,7 +212,7 @@
 static int mmc_test_wait_busy(struct mmc_test_card *test)
 {
 	int ret, busy;
-	struct mmc_command cmd;
+	struct mmc_command cmd = {0};
 
 	busy = 0;
 	do {
@@ -246,18 +246,13 @@
 {
 	int ret;
 
-	struct mmc_request mrq;
-	struct mmc_command cmd;
-	struct mmc_command stop;
-	struct mmc_data data;
+	struct mmc_request mrq = {0};
+	struct mmc_command cmd = {0};
+	struct mmc_command stop = {0};
+	struct mmc_data data = {0};
 
 	struct scatterlist sg;
 
-	memset(&mrq, 0, sizeof(struct mmc_request));
-	memset(&cmd, 0, sizeof(struct mmc_command));
-	memset(&data, 0, sizeof(struct mmc_data));
-	memset(&stop, 0, sizeof(struct mmc_command));
-
 	mrq.cmd = &cmd;
 	mrq.data = &data;
 	mrq.stop = &stop;
@@ -731,15 +726,10 @@
 	struct scatterlist *sg, unsigned sg_len, unsigned dev_addr,
 	unsigned blocks, unsigned blksz, int write)
 {
-	struct mmc_request mrq;
-	struct mmc_command cmd;
-	struct mmc_command stop;
-	struct mmc_data data;
-
-	memset(&mrq, 0, sizeof(struct mmc_request));
-	memset(&cmd, 0, sizeof(struct mmc_command));
-	memset(&data, 0, sizeof(struct mmc_data));
-	memset(&stop, 0, sizeof(struct mmc_command));
+	struct mmc_request mrq = {0};
+	struct mmc_command cmd = {0};
+	struct mmc_command stop = {0};
+	struct mmc_data data = {0};
 
 	mrq.cmd = &cmd;
 	mrq.data = &data;
@@ -761,18 +751,13 @@
 static int mmc_test_broken_transfer(struct mmc_test_card *test,
 	unsigned blocks, unsigned blksz, int write)
 {
-	struct mmc_request mrq;
-	struct mmc_command cmd;
-	struct mmc_command stop;
-	struct mmc_data data;
+	struct mmc_request mrq = {0};
+	struct mmc_command cmd = {0};
+	struct mmc_command stop = {0};
+	struct mmc_data data = {0};
 
 	struct scatterlist sg;
 
-	memset(&mrq, 0, sizeof(struct mmc_request));
-	memset(&cmd, 0, sizeof(struct mmc_command));
-	memset(&data, 0, sizeof(struct mmc_data));
-	memset(&stop, 0, sizeof(struct mmc_command));
-
 	mrq.cmd = &cmd;
 	mrq.data = &data;
 	mrq.stop = &stop;
@@ -1401,8 +1386,9 @@
  */
 static int mmc_test_area_fill(struct mmc_test_card *test)
 {
-	return mmc_test_area_io(test, test->area.max_tfr, test->area.dev_addr,
-				1, 0, 0);
+	struct mmc_test_area *t = &test->area;
+
+	return mmc_test_area_io(test, t->max_tfr, t->dev_addr, 1, 0, 0);
 }
 
 /*
@@ -1415,7 +1401,7 @@
 	if (!mmc_can_erase(test->card))
 		return 0;
 
-	return mmc_erase(test->card, t->dev_addr, test->area.max_sz >> 9,
+	return mmc_erase(test->card, t->dev_addr, t->max_sz >> 9,
 			 MMC_ERASE_ARG);
 }
 
@@ -1542,8 +1528,10 @@
 static int mmc_test_best_performance(struct mmc_test_card *test, int write,
 				     int max_scatter)
 {
-	return mmc_test_area_io(test, test->area.max_tfr, test->area.dev_addr,
-				write, max_scatter, 1);
+	struct mmc_test_area *t = &test->area;
+
+	return mmc_test_area_io(test, t->max_tfr, t->dev_addr, write,
+				max_scatter, 1);
 }
 
 /*
@@ -1583,18 +1571,19 @@
  */
 static int mmc_test_profile_read_perf(struct mmc_test_card *test)
 {
+	struct mmc_test_area *t = &test->area;
 	unsigned long sz;
 	unsigned int dev_addr;
 	int ret;
 
-	for (sz = 512; sz < test->area.max_tfr; sz <<= 1) {
-		dev_addr = test->area.dev_addr + (sz >> 9);
+	for (sz = 512; sz < t->max_tfr; sz <<= 1) {
+		dev_addr = t->dev_addr + (sz >> 9);
 		ret = mmc_test_area_io(test, sz, dev_addr, 0, 0, 1);
 		if (ret)
 			return ret;
 	}
-	sz = test->area.max_tfr;
-	dev_addr = test->area.dev_addr;
+	sz = t->max_tfr;
+	dev_addr = t->dev_addr;
 	return mmc_test_area_io(test, sz, dev_addr, 0, 0, 1);
 }
 
@@ -1603,6 +1592,7 @@
  */
 static int mmc_test_profile_write_perf(struct mmc_test_card *test)
 {
+	struct mmc_test_area *t = &test->area;
 	unsigned long sz;
 	unsigned int dev_addr;
 	int ret;
@@ -1610,8 +1600,8 @@
 	ret = mmc_test_area_erase(test);
 	if (ret)
 		return ret;
-	for (sz = 512; sz < test->area.max_tfr; sz <<= 1) {
-		dev_addr = test->area.dev_addr + (sz >> 9);
+	for (sz = 512; sz < t->max_tfr; sz <<= 1) {
+		dev_addr = t->dev_addr + (sz >> 9);
 		ret = mmc_test_area_io(test, sz, dev_addr, 1, 0, 1);
 		if (ret)
 			return ret;
@@ -1619,8 +1609,8 @@
 	ret = mmc_test_area_erase(test);
 	if (ret)
 		return ret;
-	sz = test->area.max_tfr;
-	dev_addr = test->area.dev_addr;
+	sz = t->max_tfr;
+	dev_addr = t->dev_addr;
 	return mmc_test_area_io(test, sz, dev_addr, 1, 0, 1);
 }
 
@@ -1629,6 +1619,7 @@
  */
 static int mmc_test_profile_trim_perf(struct mmc_test_card *test)
 {
+	struct mmc_test_area *t = &test->area;
 	unsigned long sz;
 	unsigned int dev_addr;
 	struct timespec ts1, ts2;
@@ -1640,8 +1631,8 @@
 	if (!mmc_can_erase(test->card))
 		return RESULT_UNSUP_HOST;
 
-	for (sz = 512; sz < test->area.max_sz; sz <<= 1) {
-		dev_addr = test->area.dev_addr + (sz >> 9);
+	for (sz = 512; sz < t->max_sz; sz <<= 1) {
+		dev_addr = t->dev_addr + (sz >> 9);
 		getnstimeofday(&ts1);
 		ret = mmc_erase(test->card, dev_addr, sz >> 9, MMC_TRIM_ARG);
 		if (ret)
@@ -1649,7 +1640,7 @@
 		getnstimeofday(&ts2);
 		mmc_test_print_rate(test, sz, &ts1, &ts2);
 	}
-	dev_addr = test->area.dev_addr;
+	dev_addr = t->dev_addr;
 	getnstimeofday(&ts1);
 	ret = mmc_erase(test->card, dev_addr, sz >> 9, MMC_TRIM_ARG);
 	if (ret)
@@ -1661,12 +1652,13 @@
 
 static int mmc_test_seq_read_perf(struct mmc_test_card *test, unsigned long sz)
 {
+	struct mmc_test_area *t = &test->area;
 	unsigned int dev_addr, i, cnt;
 	struct timespec ts1, ts2;
 	int ret;
 
-	cnt = test->area.max_sz / sz;
-	dev_addr = test->area.dev_addr;
+	cnt = t->max_sz / sz;
+	dev_addr = t->dev_addr;
 	getnstimeofday(&ts1);
 	for (i = 0; i < cnt; i++) {
 		ret = mmc_test_area_io(test, sz, dev_addr, 0, 0, 0);
@@ -1684,20 +1676,22 @@
  */
 static int mmc_test_profile_seq_read_perf(struct mmc_test_card *test)
 {
+	struct mmc_test_area *t = &test->area;
 	unsigned long sz;
 	int ret;
 
-	for (sz = 512; sz < test->area.max_tfr; sz <<= 1) {
+	for (sz = 512; sz < t->max_tfr; sz <<= 1) {
 		ret = mmc_test_seq_read_perf(test, sz);
 		if (ret)
 			return ret;
 	}
-	sz = test->area.max_tfr;
+	sz = t->max_tfr;
 	return mmc_test_seq_read_perf(test, sz);
 }
 
 static int mmc_test_seq_write_perf(struct mmc_test_card *test, unsigned long sz)
 {
+	struct mmc_test_area *t = &test->area;
 	unsigned int dev_addr, i, cnt;
 	struct timespec ts1, ts2;
 	int ret;
@@ -1705,8 +1699,8 @@
 	ret = mmc_test_area_erase(test);
 	if (ret)
 		return ret;
-	cnt = test->area.max_sz / sz;
-	dev_addr = test->area.dev_addr;
+	cnt = t->max_sz / sz;
+	dev_addr = t->dev_addr;
 	getnstimeofday(&ts1);
 	for (i = 0; i < cnt; i++) {
 		ret = mmc_test_area_io(test, sz, dev_addr, 1, 0, 0);
@@ -1724,15 +1718,16 @@
  */
 static int mmc_test_profile_seq_write_perf(struct mmc_test_card *test)
 {
+	struct mmc_test_area *t = &test->area;
 	unsigned long sz;
 	int ret;
 
-	for (sz = 512; sz < test->area.max_tfr; sz <<= 1) {
+	for (sz = 512; sz < t->max_tfr; sz <<= 1) {
 		ret = mmc_test_seq_write_perf(test, sz);
 		if (ret)
 			return ret;
 	}
-	sz = test->area.max_tfr;
+	sz = t->max_tfr;
 	return mmc_test_seq_write_perf(test, sz);
 }
 
@@ -1741,6 +1736,7 @@
  */
 static int mmc_test_profile_seq_trim_perf(struct mmc_test_card *test)
 {
+	struct mmc_test_area *t = &test->area;
 	unsigned long sz;
 	unsigned int dev_addr, i, cnt;
 	struct timespec ts1, ts2;
@@ -1752,15 +1748,15 @@
 	if (!mmc_can_erase(test->card))
 		return RESULT_UNSUP_HOST;
 
-	for (sz = 512; sz <= test->area.max_sz; sz <<= 1) {
+	for (sz = 512; sz <= t->max_sz; sz <<= 1) {
 		ret = mmc_test_area_erase(test);
 		if (ret)
 			return ret;
 		ret = mmc_test_area_fill(test);
 		if (ret)
 			return ret;
-		cnt = test->area.max_sz / sz;
-		dev_addr = test->area.dev_addr;
+		cnt = t->max_sz / sz;
+		dev_addr = t->dev_addr;
 		getnstimeofday(&ts1);
 		for (i = 0; i < cnt; i++) {
 			ret = mmc_erase(test->card, dev_addr, sz >> 9,
@@ -1823,11 +1819,12 @@
 
 static int mmc_test_random_perf(struct mmc_test_card *test, int write)
 {
+	struct mmc_test_area *t = &test->area;
 	unsigned int next;
 	unsigned long sz;
 	int ret;
 
-	for (sz = 512; sz < test->area.max_tfr; sz <<= 1) {
+	for (sz = 512; sz < t->max_tfr; sz <<= 1) {
 		/*
 		 * When writing, try to get more consistent results by running
 		 * the test twice with exactly the same I/O but outputting the
@@ -1844,7 +1841,7 @@
 		if (ret)
 			return ret;
 	}
-	sz = test->area.max_tfr;
+	sz = t->max_tfr;
 	if (write) {
 		next = rnd_next;
 		ret = mmc_test_rnd_perf(test, write, 0, sz);
@@ -1874,17 +1871,18 @@
 static int mmc_test_seq_perf(struct mmc_test_card *test, int write,
 			     unsigned int tot_sz, int max_scatter)
 {
+	struct mmc_test_area *t = &test->area;
 	unsigned int dev_addr, i, cnt, sz, ssz;
 	struct timespec ts1, ts2;
 	int ret;
 
-	sz = test->area.max_tfr;
+	sz = t->max_tfr;
+
 	/*
 	 * In the case of a maximally scattered transfer, the maximum transfer
 	 * size is further limited by using PAGE_SIZE segments.
 	 */
 	if (max_scatter) {
-		struct mmc_test_area *t = &test->area;
 		unsigned long max_tfr;
 
 		if (t->max_seg_sz >= PAGE_SIZE)
diff -druN linux-2.6.39-libre/drivers/mmc/card/queue.c linux-3.0-rc7-libre/drivers/mmc/card/queue.c
--- linux-2.6.39-libre/drivers/mmc/card/queue.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mmc/card/queue.c	2011-07-11 19:51:52.000000000 -0400
@@ -106,10 +106,12 @@
  * @mq: mmc queue
  * @card: mmc card to attach this queue
  * @lock: queue lock
+ * @subname: partition subname
  *
  * Initialise a MMC card request queue.
  */
-int mmc_init_queue(struct mmc_queue *mq, struct mmc_card *card, spinlock_t *lock)
+int mmc_init_queue(struct mmc_queue *mq, struct mmc_card *card,
+		   spinlock_t *lock, const char *subname)
 {
 	struct mmc_host *host = card->host;
 	u64 limit = BLK_BOUNCE_HIGH;
@@ -133,12 +135,7 @@
 		mq->queue->limits.max_discard_sectors = UINT_MAX;
 		if (card->erased_byte == 0)
 			mq->queue->limits.discard_zeroes_data = 1;
-		if (!mmc_can_trim(card) && is_power_of_2(card->erase_size)) {
-			mq->queue->limits.discard_granularity =
-							card->erase_size << 9;
-			mq->queue->limits.discard_alignment =
-							card->erase_size << 9;
-		}
+		mq->queue->limits.discard_granularity = card->pref_erase << 9;
 		if (mmc_can_secure_erase_trim(card))
 			queue_flag_set_unlocked(QUEUE_FLAG_SECDISCARD,
 						mq->queue);
@@ -209,8 +206,8 @@
 
 	sema_init(&mq->thread_sem, 1);
 
-	mq->thread = kthread_run(mmc_queue_thread, mq, "mmcqd/%d",
-		host->index);
+	mq->thread = kthread_run(mmc_queue_thread, mq, "mmcqd/%d%s",
+		host->index, subname ? subname : "");
 
 	if (IS_ERR(mq->thread)) {
 		ret = PTR_ERR(mq->thread);
@@ -343,18 +340,14 @@
  */
 void mmc_queue_bounce_pre(struct mmc_queue *mq)
 {
-	unsigned long flags;
-
 	if (!mq->bounce_buf)
 		return;
 
 	if (rq_data_dir(mq->req) != WRITE)
 		return;
 
-	local_irq_save(flags);
 	sg_copy_to_buffer(mq->bounce_sg, mq->bounce_sg_len,
 		mq->bounce_buf, mq->sg[0].length);
-	local_irq_restore(flags);
 }
 
 /*
@@ -363,17 +356,13 @@
  */
 void mmc_queue_bounce_post(struct mmc_queue *mq)
 {
-	unsigned long flags;
-
 	if (!mq->bounce_buf)
 		return;
 
 	if (rq_data_dir(mq->req) != READ)
 		return;
 
-	local_irq_save(flags);
 	sg_copy_from_buffer(mq->bounce_sg, mq->bounce_sg_len,
 		mq->bounce_buf, mq->sg[0].length);
-	local_irq_restore(flags);
 }
 
diff -druN linux-2.6.39-libre/drivers/mmc/card/queue.h linux-3.0-rc7-libre/drivers/mmc/card/queue.h
--- linux-2.6.39-libre/drivers/mmc/card/queue.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mmc/card/queue.h	2011-07-11 19:51:52.000000000 -0400
@@ -19,7 +19,8 @@
 	unsigned int		bounce_sg_len;
 };
 
-extern int mmc_init_queue(struct mmc_queue *, struct mmc_card *, spinlock_t *);
+extern int mmc_init_queue(struct mmc_queue *, struct mmc_card *, spinlock_t *,
+			  const char *);
 extern void mmc_cleanup_queue(struct mmc_queue *);
 extern void mmc_queue_suspend(struct mmc_queue *);
 extern void mmc_queue_resume(struct mmc_queue *);
diff -druN linux-2.6.39-libre/drivers/mmc/core/bus.c linux-3.0-rc7-libre/drivers/mmc/core/bus.c
--- linux-2.6.39-libre/drivers/mmc/core/bus.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mmc/core/bus.c	2011-07-11 19:51:52.000000000 -0400
@@ -274,8 +274,12 @@
 		break;
 	case MMC_TYPE_SD:
 		type = "SD";
-		if (mmc_card_blockaddr(card))
-			type = "SDHC";
+		if (mmc_card_blockaddr(card)) {
+			if (mmc_card_ext_capacity(card))
+				type = "SDXC";
+			else
+				type = "SDHC";
+		}
 		break;
 	case MMC_TYPE_SDIO:
 		type = "SDIO";
@@ -299,7 +303,8 @@
 	} else {
 		printk(KERN_INFO "%s: new %s%s%s card at address %04x\n",
 			mmc_hostname(card->host),
-			mmc_card_highspeed(card) ? "high speed " : "",
+			mmc_sd_card_uhs(card) ? "ultra high speed " :
+			(mmc_card_highspeed(card) ? "high speed " : ""),
 			mmc_card_ddr_mode(card) ? "DDR " : "",
 			type, card->rca);
 	}
diff -druN linux-2.6.39-libre/drivers/mmc/core/core.c linux-3.0-rc7-libre/drivers/mmc/core/core.c
--- linux-2.6.39-libre/drivers/mmc/core/core.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mmc/core/core.c	2011-07-11 19:51:52.000000000 -0400
@@ -236,12 +236,10 @@
  */
 int mmc_wait_for_cmd(struct mmc_host *host, struct mmc_command *cmd, int retries)
 {
-	struct mmc_request mrq;
+	struct mmc_request mrq = {0};
 
 	WARN_ON(!host->claimed);
 
-	memset(&mrq, 0, sizeof(struct mmc_request));
-
 	memset(cmd->resp, 0, sizeof(cmd->resp));
 	cmd->retries = retries;
 
@@ -720,22 +718,12 @@
 }
 
 /*
- * Change data bus width and DDR mode of a host.
- */
-void mmc_set_bus_width_ddr(struct mmc_host *host, unsigned int width,
-			   unsigned int ddr)
-{
-	host->ios.bus_width = width;
-	host->ios.ddr = ddr;
-	mmc_set_ios(host);
-}
-
-/*
  * Change data bus width of a host.
  */
 void mmc_set_bus_width(struct mmc_host *host, unsigned int width)
 {
-	mmc_set_bus_width_ddr(host, width, MMC_SDR_MODE);
+	host->ios.bus_width = width;
+	mmc_set_ios(host);
 }
 
 /**
@@ -944,6 +932,38 @@
 	return ocr;
 }
 
+int mmc_set_signal_voltage(struct mmc_host *host, int signal_voltage, bool cmd11)
+{
+	struct mmc_command cmd = {0};
+	int err = 0;
+
+	BUG_ON(!host);
+
+	/*
+	 * Send CMD11 only if the request is to switch the card to
+	 * 1.8V signalling.
+	 */
+	if ((signal_voltage != MMC_SIGNAL_VOLTAGE_330) && cmd11) {
+		cmd.opcode = SD_SWITCH_VOLTAGE;
+		cmd.arg = 0;
+		cmd.flags = MMC_RSP_R1 | MMC_CMD_AC;
+
+		err = mmc_wait_for_cmd(host, &cmd, 0);
+		if (err)
+			return err;
+
+		if (!mmc_host_is_spi(host) && (cmd.resp[0] & R1_ERROR))
+			return -EIO;
+	}
+
+	host->ios.signal_voltage = signal_voltage;
+
+	if (host->ops->start_signal_voltage_switch)
+		err = host->ops->start_signal_voltage_switch(host, &host->ios);
+
+	return err;
+}
+
 /*
  * Select timing parameters for host.
  */
@@ -954,6 +974,15 @@
 }
 
 /*
+ * Select appropriate driver type for host.
+ */
+void mmc_set_driver_type(struct mmc_host *host, unsigned int drv_type)
+{
+	host->ios.drv_type = drv_type;
+	mmc_set_ios(host);
+}
+
+/*
  * Apply power to the MMC stack.  This is a two-stage process.
  * First, we enable power to the card without the clock running.
  * We then wait a bit for the power to stabilise.  Finally,
@@ -1187,9 +1216,8 @@
 	}
 }
 
-static void mmc_set_mmc_erase_timeout(struct mmc_card *card,
-				      struct mmc_command *cmd,
-				      unsigned int arg, unsigned int qty)
+static unsigned int mmc_mmc_erase_timeout(struct mmc_card *card,
+				          unsigned int arg, unsigned int qty)
 {
 	unsigned int erase_timeout;
 
@@ -1217,7 +1245,7 @@
 		 */
 		timeout_clks <<= 1;
 		timeout_us += (timeout_clks * 1000) /
-			      (card->host->ios.clock / 1000);
+			      (mmc_host_clk_rate(card->host) / 1000);
 
 		erase_timeout = timeout_us / 1000;
 
@@ -1246,44 +1274,48 @@
 	if (mmc_host_is_spi(card->host) && erase_timeout < 1000)
 		erase_timeout = 1000;
 
-	cmd->erase_timeout = erase_timeout;
+	return erase_timeout;
 }
 
-static void mmc_set_sd_erase_timeout(struct mmc_card *card,
-				     struct mmc_command *cmd, unsigned int arg,
-				     unsigned int qty)
+static unsigned int mmc_sd_erase_timeout(struct mmc_card *card,
+					 unsigned int arg,
+					 unsigned int qty)
 {
+	unsigned int erase_timeout;
+
 	if (card->ssr.erase_timeout) {
 		/* Erase timeout specified in SD Status Register (SSR) */
-		cmd->erase_timeout = card->ssr.erase_timeout * qty +
-				     card->ssr.erase_offset;
+		erase_timeout = card->ssr.erase_timeout * qty +
+				card->ssr.erase_offset;
 	} else {
 		/*
 		 * Erase timeout not specified in SD Status Register (SSR) so
 		 * use 250ms per write block.
 		 */
-		cmd->erase_timeout = 250 * qty;
+		erase_timeout = 250 * qty;
 	}
 
 	/* Must not be less than 1 second */
-	if (cmd->erase_timeout < 1000)
-		cmd->erase_timeout = 1000;
+	if (erase_timeout < 1000)
+		erase_timeout = 1000;
+
+	return erase_timeout;
 }
 
-static void mmc_set_erase_timeout(struct mmc_card *card,
-				  struct mmc_command *cmd, unsigned int arg,
-				  unsigned int qty)
+static unsigned int mmc_erase_timeout(struct mmc_card *card,
+				      unsigned int arg,
+				      unsigned int qty)
 {
 	if (mmc_card_sd(card))
-		mmc_set_sd_erase_timeout(card, cmd, arg, qty);
+		return mmc_sd_erase_timeout(card, arg, qty);
 	else
-		mmc_set_mmc_erase_timeout(card, cmd, arg, qty);
+		return mmc_mmc_erase_timeout(card, arg, qty);
 }
 
 static int mmc_do_erase(struct mmc_card *card, unsigned int from,
 			unsigned int to, unsigned int arg)
 {
-	struct mmc_command cmd;
+	struct mmc_command cmd = {0};
 	unsigned int qty = 0;
 	int err;
 
@@ -1317,7 +1349,6 @@
 		to <<= 9;
 	}
 
-	memset(&cmd, 0, sizeof(struct mmc_command));
 	if (mmc_card_sd(card))
 		cmd.opcode = SD_ERASE_WR_BLK_START;
 	else
@@ -1351,7 +1382,7 @@
 	cmd.opcode = MMC_ERASE;
 	cmd.arg = arg;
 	cmd.flags = MMC_RSP_SPI_R1B | MMC_RSP_R1B | MMC_CMD_AC;
-	mmc_set_erase_timeout(card, &cmd, arg, qty);
+	cmd.cmd_timeout_ms = mmc_erase_timeout(card, arg, qty);
 	err = mmc_wait_for_cmd(card->host, &cmd, 0);
 	if (err) {
 		printk(KERN_ERR "mmc_erase: erase error %d, status %#x\n",
@@ -1487,12 +1518,11 @@
 
 int mmc_set_blocklen(struct mmc_card *card, unsigned int blocklen)
 {
-	struct mmc_command cmd;
+	struct mmc_command cmd = {0};
 
 	if (mmc_card_blockaddr(card) || mmc_card_ddr_mode(card))
 		return 0;
 
-	memset(&cmd, 0, sizeof(struct mmc_command));
 	cmd.opcode = MMC_SET_BLOCKLEN;
 	cmd.arg = blocklen;
 	cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_AC;
@@ -1578,7 +1608,7 @@
 	for (i = 0; i < ARRAY_SIZE(freqs); i++) {
 		if (!mmc_rescan_try_freq(host, max(freqs[i], host->f_min)))
 			break;
-		if (freqs[i] < host->f_min)
+		if (freqs[i] <= host->f_min)
 			break;
 	}
 	mmc_release_host(host);
@@ -1746,7 +1776,7 @@
 	}
 	mmc_bus_put(host);
 
-	if (!err && !(host->pm_flags & MMC_PM_KEEP_POWER))
+	if (!err && !mmc_card_keep_power(host))
 		mmc_power_off(host);
 
 	return err;
@@ -1764,7 +1794,7 @@
 
 	mmc_bus_get(host);
 	if (host->bus_ops && !host->bus_dead) {
-		if (!(host->pm_flags & MMC_PM_KEEP_POWER)) {
+		if (!mmc_card_keep_power(host)) {
 			mmc_power_up(host);
 			mmc_select_voltage(host, host->ocr);
 			/*
@@ -1789,6 +1819,7 @@
 			err = 0;
 		}
 	}
+	host->pm_flags &= ~MMC_PM_KEEP_POWER;
 	mmc_bus_put(host);
 
 	return err;
diff -druN linux-2.6.39-libre/drivers/mmc/core/core.h linux-3.0-rc7-libre/drivers/mmc/core/core.h
--- linux-2.6.39-libre/drivers/mmc/core/core.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mmc/core/core.h	2011-07-11 19:51:52.000000000 -0400
@@ -38,10 +38,11 @@
 void mmc_set_ungated(struct mmc_host *host);
 void mmc_set_bus_mode(struct mmc_host *host, unsigned int mode);
 void mmc_set_bus_width(struct mmc_host *host, unsigned int width);
-void mmc_set_bus_width_ddr(struct mmc_host *host, unsigned int width,
-			   unsigned int ddr);
 u32 mmc_select_voltage(struct mmc_host *host, u32 ocr);
+int mmc_set_signal_voltage(struct mmc_host *host, int signal_voltage,
+			   bool cmd11);
 void mmc_set_timing(struct mmc_host *host, unsigned int timing);
+void mmc_set_driver_type(struct mmc_host *host, unsigned int drv_type);
 
 static inline void mmc_delay(unsigned int ms)
 {
@@ -61,8 +62,6 @@
 int mmc_attach_sd(struct mmc_host *host);
 int mmc_attach_sdio(struct mmc_host *host);
 
-void mmc_fixup_device(struct mmc_card *card);
-
 /* Module parameters */
 extern int use_spi_crc;
 
diff -druN linux-2.6.39-libre/drivers/mmc/core/host.c linux-3.0-rc7-libre/drivers/mmc/core/host.c
--- linux-2.6.39-libre/drivers/mmc/core/host.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mmc/core/host.c	2011-07-11 19:51:52.000000000 -0400
@@ -325,12 +325,12 @@
 	WARN_ON((host->caps & MMC_CAP_SDIO_IRQ) &&
 		!host->ops->enable_sdio_irq);
 
-	led_trigger_register_simple(dev_name(&host->class_dev), &host->led);
-
 	err = device_add(&host->class_dev);
 	if (err)
 		return err;
 
+	led_trigger_register_simple(dev_name(&host->class_dev), &host->led);
+
 #ifdef CONFIG_DEBUG_FS
 	mmc_add_host_debugfs(host);
 #endif
diff -druN linux-2.6.39-libre/drivers/mmc/core/mmc.c linux-3.0-rc7-libre/drivers/mmc/core/mmc.c
--- linux-2.6.39-libre/drivers/mmc/core/mmc.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mmc/core/mmc.c	2011-07-11 19:51:52.000000000 -0400
@@ -20,6 +20,7 @@
 #include "core.h"
 #include "bus.h"
 #include "mmc_ops.h"
+#include "sd_ops.h"
 
 static const unsigned int tran_exp[] = {
 	10000,		100000,		1000000,	10000000,
@@ -173,14 +174,17 @@
 }
 
 /*
- * Read and decode extended CSD.
+ * Read extended CSD.
  */
-static int mmc_read_ext_csd(struct mmc_card *card)
+static int mmc_get_ext_csd(struct mmc_card *card, u8 **new_ext_csd)
 {
 	int err;
 	u8 *ext_csd;
 
 	BUG_ON(!card);
+	BUG_ON(!new_ext_csd);
+
+	*new_ext_csd = NULL;
 
 	if (card->csd.mmca_vsn < CSD_SPEC_VER_4)
 		return 0;
@@ -198,12 +202,15 @@
 
 	err = mmc_send_ext_csd(card, ext_csd);
 	if (err) {
+		kfree(ext_csd);
+		*new_ext_csd = NULL;
+
 		/* If the host or the card can't do the switch,
 		 * fail more gracefully. */
 		if ((err != -EINVAL)
 		 && (err != -ENOSYS)
 		 && (err != -EFAULT))
-			goto out;
+			return err;
 
 		/*
 		 * High capacity cards should have this "magic" size
@@ -221,9 +228,23 @@
 				mmc_hostname(card->host));
 			err = 0;
 		}
+	} else
+		*new_ext_csd = ext_csd;
 
-		goto out;
-	}
+	return err;
+}
+
+/*
+ * Decode extended CSD.
+ */
+static int mmc_read_ext_csd(struct mmc_card *card, u8 *ext_csd)
+{
+	int err = 0;
+
+	BUG_ON(!card);
+
+	if (!ext_csd)
+		return 0;
 
 	/* Version is coded in the CSD_STRUCTURE byte in the EXT_CSD register */
 	if (card->csd.structure == 3) {
@@ -288,6 +309,10 @@
 
 	if (card->ext_csd.rev >= 3) {
 		u8 sa_shift = ext_csd[EXT_CSD_S_A_TIMEOUT];
+		card->ext_csd.part_config = ext_csd[EXT_CSD_PART_CONFIG];
+
+		/* EXT_CSD value is in units of 10ms, but we store in ms */
+		card->ext_csd.part_time = 10 * ext_csd[EXT_CSD_PART_SWITCH_TIME];
 
 		/* Sleep / awake timeout in 100ns units */
 		if (sa_shift > 0 && sa_shift <= 0x17)
@@ -299,6 +324,14 @@
 			ext_csd[EXT_CSD_ERASE_TIMEOUT_MULT];
 		card->ext_csd.hc_erase_size =
 			ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE] << 10;
+
+		card->ext_csd.rel_sectors = ext_csd[EXT_CSD_REL_WR_SEC_C];
+
+		/*
+		 * There are two boot regions of equal size, defined in
+		 * multiples of 128K.
+		 */
+		card->ext_csd.boot_size = ext_csd[EXT_CSD_BOOT_MULT] << 17;
 	}
 
 	if (card->ext_csd.rev >= 4) {
@@ -350,14 +383,78 @@
 			ext_csd[EXT_CSD_TRIM_MULT];
 	}
 
+	if (card->ext_csd.rev >= 5)
+		card->ext_csd.rel_param = ext_csd[EXT_CSD_WR_REL_PARAM];
+
 	if (ext_csd[EXT_CSD_ERASED_MEM_CONT])
 		card->erased_byte = 0xFF;
 	else
 		card->erased_byte = 0x0;
 
 out:
+	return err;
+}
+
+static inline void mmc_free_ext_csd(u8 *ext_csd)
+{
 	kfree(ext_csd);
+}
+
+
+static int mmc_compare_ext_csds(struct mmc_card *card, u8 *ext_csd,
+			unsigned bus_width)
+{
+	u8 *bw_ext_csd;
+	int err;
+
+	err = mmc_get_ext_csd(card, &bw_ext_csd);
+	if (err)
+		return err;
+
+	if ((ext_csd == NULL || bw_ext_csd == NULL)) {
+		if (bus_width != MMC_BUS_WIDTH_1)
+			err = -EINVAL;
+		goto out;
+	}
+
+	if (bus_width == MMC_BUS_WIDTH_1)
+		goto out;
+
+	/* only compare read only fields */
+	err = (!(ext_csd[EXT_CSD_PARTITION_SUPPORT] ==
+			bw_ext_csd[EXT_CSD_PARTITION_SUPPORT]) &&
+		(ext_csd[EXT_CSD_ERASED_MEM_CONT] ==
+			bw_ext_csd[EXT_CSD_ERASED_MEM_CONT]) &&
+		(ext_csd[EXT_CSD_REV] ==
+			bw_ext_csd[EXT_CSD_REV]) &&
+		(ext_csd[EXT_CSD_STRUCTURE] ==
+			bw_ext_csd[EXT_CSD_STRUCTURE]) &&
+		(ext_csd[EXT_CSD_CARD_TYPE] ==
+			bw_ext_csd[EXT_CSD_CARD_TYPE]) &&
+		(ext_csd[EXT_CSD_S_A_TIMEOUT] ==
+			bw_ext_csd[EXT_CSD_S_A_TIMEOUT]) &&
+		(ext_csd[EXT_CSD_HC_WP_GRP_SIZE] ==
+			bw_ext_csd[EXT_CSD_HC_WP_GRP_SIZE]) &&
+		(ext_csd[EXT_CSD_ERASE_TIMEOUT_MULT] ==
+			bw_ext_csd[EXT_CSD_ERASE_TIMEOUT_MULT]) &&
+		(ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE] ==
+			bw_ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE]) &&
+		(ext_csd[EXT_CSD_SEC_TRIM_MULT] ==
+			bw_ext_csd[EXT_CSD_SEC_TRIM_MULT]) &&
+		(ext_csd[EXT_CSD_SEC_ERASE_MULT] ==
+			bw_ext_csd[EXT_CSD_SEC_ERASE_MULT]) &&
+		(ext_csd[EXT_CSD_SEC_FEATURE_SUPPORT] ==
+			bw_ext_csd[EXT_CSD_SEC_FEATURE_SUPPORT]) &&
+		(ext_csd[EXT_CSD_TRIM_MULT] ==
+			bw_ext_csd[EXT_CSD_TRIM_MULT]) &&
+		memcmp(&ext_csd[EXT_CSD_SEC_CNT],
+		       &bw_ext_csd[EXT_CSD_SEC_CNT],
+		       4) != 0);
+	if (err)
+		err = -EINVAL;
 
+out:
+	mmc_free_ext_csd(bw_ext_csd);
 	return err;
 }
 
@@ -422,6 +519,7 @@
 	u32 cid[4];
 	unsigned int max_dtr;
 	u32 rocr;
+	u8 *ext_csd = NULL;
 
 	BUG_ON(!host);
 	WARN_ON(!host->claimed);
@@ -520,7 +618,11 @@
 		/*
 		 * Fetch and process extended CSD.
 		 */
-		err = mmc_read_ext_csd(card);
+
+		err = mmc_get_ext_csd(card, &ext_csd);
+		if (err)
+			goto free_card;
+		err = mmc_read_ext_csd(card, ext_csd);
 		if (err)
 			goto free_card;
 
@@ -542,7 +644,7 @@
 	 */
 	if (card->ext_csd.enhanced_area_en) {
 		err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
-				EXT_CSD_ERASE_GROUP_DEF, 1);
+				 EXT_CSD_ERASE_GROUP_DEF, 1, 0);
 
 		if (err && err != -EBADMSG)
 			goto free_card;
@@ -568,12 +670,24 @@
 	}
 
 	/*
+	 * Ensure eMMC user default partition is enabled
+	 */
+	if (card->ext_csd.part_config & EXT_CSD_PART_CONFIG_ACC_MASK) {
+		card->ext_csd.part_config &= ~EXT_CSD_PART_CONFIG_ACC_MASK;
+		err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_PART_CONFIG,
+				 card->ext_csd.part_config,
+				 card->ext_csd.part_time);
+		if (err && err != -EBADMSG)
+			goto free_card;
+	}
+
+	/*
 	 * Activate high speed (if supported)
 	 */
 	if ((card->ext_csd.hs_max_dtr != 0) &&
 		(host->caps & MMC_CAP_MMC_HIGHSPEED)) {
 		err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
-			EXT_CSD_HS_TIMING, 1);
+				 EXT_CSD_HS_TIMING, 1, 0);
 		if (err && err != -EBADMSG)
 			goto free_card;
 
@@ -606,10 +720,14 @@
 	 */
 	if (mmc_card_highspeed(card)) {
 		if ((card->ext_csd.card_type & EXT_CSD_CARD_TYPE_DDR_1_8V)
-			&& (host->caps & (MMC_CAP_1_8V_DDR)))
+			&& ((host->caps & (MMC_CAP_1_8V_DDR |
+			     MMC_CAP_UHS_DDR50))
+				== (MMC_CAP_1_8V_DDR | MMC_CAP_UHS_DDR50)))
 				ddr = MMC_1_8V_DDR_MODE;
 		else if ((card->ext_csd.card_type & EXT_CSD_CARD_TYPE_DDR_1_2V)
-			&& (host->caps & (MMC_CAP_1_2V_DDR)))
+			&& ((host->caps & (MMC_CAP_1_2V_DDR |
+			     MMC_CAP_UHS_DDR50))
+				== (MMC_CAP_1_2V_DDR | MMC_CAP_UHS_DDR50)))
 				ddr = MMC_1_2V_DDR_MODE;
 	}
 
@@ -640,18 +758,22 @@
 				ddr = 0; /* no DDR for 1-bit width */
 			err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
 					 EXT_CSD_BUS_WIDTH,
-					 ext_csd_bits[idx][0]);
+					 ext_csd_bits[idx][0],
+					 0);
 			if (!err) {
-				mmc_set_bus_width_ddr(card->host,
-						      bus_width, MMC_SDR_MODE);
+				mmc_set_bus_width(card->host, bus_width);
+
 				/*
 				 * If controller can't handle bus width test,
-				 * use the highest bus width to maintain
-				 * compatibility with previous MMC behavior.
+				 * compare ext_csd previously read in 1 bit mode
+				 * against ext_csd at new bus width
 				 */
 				if (!(host->caps & MMC_CAP_BUS_WIDTH_TEST))
-					break;
-				err = mmc_bus_test(card, bus_width);
+					err = mmc_compare_ext_csds(card,
+						ext_csd,
+						bus_width);
+				else
+					err = mmc_bus_test(card, bus_width);
 				if (!err)
 					break;
 			}
@@ -659,8 +781,9 @@
 
 		if (!err && ddr) {
 			err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
-					EXT_CSD_BUS_WIDTH,
-					ext_csd_bits[idx][1]);
+					 EXT_CSD_BUS_WIDTH,
+					 ext_csd_bits[idx][1],
+					 0);
 		}
 		if (err) {
 			printk(KERN_WARNING "%s: switch to bus width %d ddr %d "
@@ -668,20 +791,43 @@
 				1 << bus_width, ddr);
 			goto free_card;
 		} else if (ddr) {
+			/*
+			 * eMMC cards can support 3.3V to 1.2V i/o (vccq)
+			 * signaling.
+			 *
+			 * EXT_CSD_CARD_TYPE_DDR_1_8V means 3.3V or 1.8V vccq.
+			 *
+			 * 1.8V vccq at 3.3V core voltage (vcc) is not required
+			 * in the JEDEC spec for DDR.
+			 *
+			 * Do not force change in vccq since we are obviously
+			 * working and no change to vccq is needed.
+			 *
+			 * WARNING: eMMC rules are NOT the same as SD DDR
+			 */
+			if (ddr == EXT_CSD_CARD_TYPE_DDR_1_2V) {
+				err = mmc_set_signal_voltage(host,
+					MMC_SIGNAL_VOLTAGE_120, 0);
+				if (err)
+					goto err;
+			}
 			mmc_card_set_ddr_mode(card);
-			mmc_set_bus_width_ddr(card->host, bus_width, ddr);
+			mmc_set_timing(card->host, MMC_TIMING_UHS_DDR50);
+			mmc_set_bus_width(card->host, bus_width);
 		}
 	}
 
 	if (!oldcard)
 		host->card = card;
 
+	mmc_free_ext_csd(ext_csd);
 	return 0;
 
 free_card:
 	if (!oldcard)
 		mmc_remove_card(card);
 err:
+	mmc_free_ext_csd(ext_csd);
 
 	return err;
 }
diff -druN linux-2.6.39-libre/drivers/mmc/core/mmc_ops.c linux-3.0-rc7-libre/drivers/mmc/core/mmc_ops.c
--- linux-2.6.39-libre/drivers/mmc/core/mmc_ops.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mmc/core/mmc_ops.c	2011-07-11 19:51:52.000000000 -0400
@@ -23,12 +23,10 @@
 static int _mmc_select_card(struct mmc_host *host, struct mmc_card *card)
 {
 	int err;
-	struct mmc_command cmd;
+	struct mmc_command cmd = {0};
 
 	BUG_ON(!host);
 
-	memset(&cmd, 0, sizeof(struct mmc_command));
-
 	cmd.opcode = MMC_SELECT_CARD;
 
 	if (card) {
@@ -60,15 +58,13 @@
 
 int mmc_card_sleepawake(struct mmc_host *host, int sleep)
 {
-	struct mmc_command cmd;
+	struct mmc_command cmd = {0};
 	struct mmc_card *card = host->card;
 	int err;
 
 	if (sleep)
 		mmc_deselect_cards(host);
 
-	memset(&cmd, 0, sizeof(struct mmc_command));
-
 	cmd.opcode = MMC_SLEEP_AWAKE;
 	cmd.arg = card->rca << 16;
 	if (sleep)
@@ -97,7 +93,7 @@
 int mmc_go_idle(struct mmc_host *host)
 {
 	int err;
-	struct mmc_command cmd;
+	struct mmc_command cmd = {0};
 
 	/*
 	 * Non-SPI hosts need to prevent chipselect going active during
@@ -113,8 +109,6 @@
 		mmc_delay(1);
 	}
 
-	memset(&cmd, 0, sizeof(struct mmc_command));
-
 	cmd.opcode = MMC_GO_IDLE_STATE;
 	cmd.arg = 0;
 	cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_NONE | MMC_CMD_BC;
@@ -135,13 +129,11 @@
 
 int mmc_send_op_cond(struct mmc_host *host, u32 ocr, u32 *rocr)
 {
-	struct mmc_command cmd;
+	struct mmc_command cmd = {0};
 	int i, err = 0;
 
 	BUG_ON(!host);
 
-	memset(&cmd, 0, sizeof(struct mmc_command));
-
 	cmd.opcode = MMC_SEND_OP_COND;
 	cmd.arg = mmc_host_is_spi(host) ? 0 : ocr;
 	cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R3 | MMC_CMD_BCR;
@@ -178,13 +170,11 @@
 int mmc_all_send_cid(struct mmc_host *host, u32 *cid)
 {
 	int err;
-	struct mmc_command cmd;
+	struct mmc_command cmd = {0};
 
 	BUG_ON(!host);
 	BUG_ON(!cid);
 
-	memset(&cmd, 0, sizeof(struct mmc_command));
-
 	cmd.opcode = MMC_ALL_SEND_CID;
 	cmd.arg = 0;
 	cmd.flags = MMC_RSP_R2 | MMC_CMD_BCR;
@@ -201,13 +191,11 @@
 int mmc_set_relative_addr(struct mmc_card *card)
 {
 	int err;
-	struct mmc_command cmd;
+	struct mmc_command cmd = {0};
 
 	BUG_ON(!card);
 	BUG_ON(!card->host);
 
-	memset(&cmd, 0, sizeof(struct mmc_command));
-
 	cmd.opcode = MMC_SET_RELATIVE_ADDR;
 	cmd.arg = card->rca << 16;
 	cmd.flags = MMC_RSP_R1 | MMC_CMD_AC;
@@ -223,13 +211,11 @@
 mmc_send_cxd_native(struct mmc_host *host, u32 arg, u32 *cxd, int opcode)
 {
 	int err;
-	struct mmc_command cmd;
+	struct mmc_command cmd = {0};
 
 	BUG_ON(!host);
 	BUG_ON(!cxd);
 
-	memset(&cmd, 0, sizeof(struct mmc_command));
-
 	cmd.opcode = opcode;
 	cmd.arg = arg;
 	cmd.flags = MMC_RSP_R2 | MMC_CMD_AC;
@@ -247,9 +233,9 @@
 mmc_send_cxd_data(struct mmc_card *card, struct mmc_host *host,
 		u32 opcode, void *buf, unsigned len)
 {
-	struct mmc_request mrq;
-	struct mmc_command cmd;
-	struct mmc_data data;
+	struct mmc_request mrq = {0};
+	struct mmc_command cmd = {0};
+	struct mmc_data data = {0};
 	struct scatterlist sg;
 	void *data_buf;
 
@@ -260,10 +246,6 @@
 	if (data_buf == NULL)
 		return -ENOMEM;
 
-	memset(&mrq, 0, sizeof(struct mmc_request));
-	memset(&cmd, 0, sizeof(struct mmc_command));
-	memset(&data, 0, sizeof(struct mmc_data));
-
 	mrq.cmd = &cmd;
 	mrq.data = &data;
 
@@ -355,11 +337,9 @@
 
 int mmc_spi_read_ocr(struct mmc_host *host, int highcap, u32 *ocrp)
 {
-	struct mmc_command cmd;
+	struct mmc_command cmd = {0};
 	int err;
 
-	memset(&cmd, 0, sizeof(struct mmc_command));
-
 	cmd.opcode = MMC_SPI_READ_OCR;
 	cmd.arg = highcap ? (1 << 30) : 0;
 	cmd.flags = MMC_RSP_SPI_R3;
@@ -372,11 +352,9 @@
 
 int mmc_spi_set_crc(struct mmc_host *host, int use_crc)
 {
-	struct mmc_command cmd;
+	struct mmc_command cmd = {0};
 	int err;
 
-	memset(&cmd, 0, sizeof(struct mmc_command));
-
 	cmd.opcode = MMC_SPI_CRC_ON_OFF;
 	cmd.flags = MMC_RSP_SPI_R1;
 	cmd.arg = use_crc;
@@ -387,23 +365,34 @@
 	return err;
 }
 
-int mmc_switch(struct mmc_card *card, u8 set, u8 index, u8 value)
+/**
+ *	mmc_switch - modify EXT_CSD register
+ *	@card: the MMC card associated with the data transfer
+ *	@set: cmd set values
+ *	@index: EXT_CSD register index
+ *	@value: value to program into EXT_CSD register
+ *	@timeout_ms: timeout (ms) for operation performed by register write,
+ *                   timeout of zero implies maximum possible timeout
+ *
+ *	Modifies the EXT_CSD register for selected card.
+ */
+int mmc_switch(struct mmc_card *card, u8 set, u8 index, u8 value,
+	       unsigned int timeout_ms)
 {
 	int err;
-	struct mmc_command cmd;
+	struct mmc_command cmd = {0};
 	u32 status;
 
 	BUG_ON(!card);
 	BUG_ON(!card->host);
 
-	memset(&cmd, 0, sizeof(struct mmc_command));
-
 	cmd.opcode = MMC_SWITCH;
 	cmd.arg = (MMC_SWITCH_MODE_WRITE_BYTE << 24) |
 		  (index << 16) |
 		  (value << 8) |
 		  set;
 	cmd.flags = MMC_RSP_SPI_R1B | MMC_RSP_R1B | MMC_CMD_AC;
+	cmd.cmd_timeout_ms = timeout_ms;
 
 	err = mmc_wait_for_cmd(card->host, &cmd, MMC_CMD_RETRIES);
 	if (err)
@@ -433,17 +422,16 @@
 
 	return 0;
 }
+EXPORT_SYMBOL_GPL(mmc_switch);
 
 int mmc_send_status(struct mmc_card *card, u32 *status)
 {
 	int err;
-	struct mmc_command cmd;
+	struct mmc_command cmd = {0};
 
 	BUG_ON(!card);
 	BUG_ON(!card->host);
 
-	memset(&cmd, 0, sizeof(struct mmc_command));
-
 	cmd.opcode = MMC_SEND_STATUS;
 	if (!mmc_host_is_spi(card->host))
 		cmd.arg = card->rca << 16;
@@ -466,9 +454,9 @@
 mmc_send_bus_test(struct mmc_card *card, struct mmc_host *host, u8 opcode,
 		  u8 len)
 {
-	struct mmc_request mrq;
-	struct mmc_command cmd;
-	struct mmc_data data;
+	struct mmc_request mrq = {0};
+	struct mmc_command cmd = {0};
+	struct mmc_data data = {0};
 	struct scatterlist sg;
 	u8 *data_buf;
 	u8 *test_buf;
@@ -497,10 +485,6 @@
 	if (opcode == MMC_BUS_TEST_W)
 		memcpy(data_buf, test_buf, len);
 
-	memset(&mrq, 0, sizeof(struct mmc_request));
-	memset(&cmd, 0, sizeof(struct mmc_command));
-	memset(&data, 0, sizeof(struct mmc_data));
-
 	mrq.cmd = &cmd;
 	mrq.data = &data;
 	cmd.opcode = opcode;
diff -druN linux-2.6.39-libre/drivers/mmc/core/mmc_ops.h linux-3.0-rc7-libre/drivers/mmc/core/mmc_ops.h
--- linux-2.6.39-libre/drivers/mmc/core/mmc_ops.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mmc/core/mmc_ops.h	2011-07-11 19:51:52.000000000 -0400
@@ -20,7 +20,6 @@
 int mmc_set_relative_addr(struct mmc_card *card);
 int mmc_send_csd(struct mmc_card *card, u32 *csd);
 int mmc_send_ext_csd(struct mmc_card *card, u8 *ext_csd);
-int mmc_switch(struct mmc_card *card, u8 set, u8 index, u8 value);
 int mmc_send_status(struct mmc_card *card, u32 *status);
 int mmc_send_cid(struct mmc_host *host, u32 *cid);
 int mmc_spi_read_ocr(struct mmc_host *host, int highcap, u32 *ocrp);
diff -druN linux-2.6.39-libre/drivers/mmc/core/quirks.c linux-3.0-rc7-libre/drivers/mmc/core/quirks.c
--- linux-2.6.39-libre/drivers/mmc/core/quirks.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mmc/core/quirks.c	2011-07-11 19:51:52.000000000 -0400
@@ -1,7 +1,8 @@
 /*
- *  This file contains work-arounds for many known sdio hardware
- *  bugs.
+ *  This file contains work-arounds for many known SD/MMC
+ *  and SDIO hardware bugs.
  *
+ *  Copyright (c) 2011 Andrei Warkentin <andreiw@motorola.com>
  *  Copyright (c) 2011 Pierre Tardy <tardyp@gmail.com>
  *  Inspired from pci fixup code:
  *  Copyright (c) 1999 Martin Mares <mj@ucw.cz>
@@ -11,34 +12,14 @@
 #include <linux/types.h>
 #include <linux/kernel.h>
 #include <linux/mmc/card.h>
-#include <linux/mod_devicetable.h>
 
-/*
- *  The world is not perfect and supplies us with broken mmc/sdio devices.
- *  For at least a part of these bugs we need a work-around
- */
-
-struct mmc_fixup {
-	u16 vendor, device;	/* You can use SDIO_ANY_ID here of course */
-	void (*vendor_fixup)(struct mmc_card *card, int data);
-	int data;
-};
-
-/*
- * This hook just adds a quirk unconditionnally
- */
-static void __maybe_unused add_quirk(struct mmc_card *card, int data)
-{
-	card->quirks |= data;
-}
+#ifndef SDIO_VENDOR_ID_TI
+#define SDIO_VENDOR_ID_TI		0x0097
+#endif
 
-/*
- * This hook just removes a quirk unconditionnally
- */
-static void __maybe_unused remove_quirk(struct mmc_card *card, int data)
-{
-	card->quirks &= ~data;
-}
+#ifndef SDIO_DEVICE_ID_TI_WL1271
+#define SDIO_DEVICE_ID_TI_WL1271	0x4076
+#endif
 
 /*
  * This hook just adds a quirk for all sdio devices
@@ -49,33 +30,47 @@
 		card->quirks |= data;
 }
 
-#ifndef SDIO_VENDOR_ID_TI
-#define SDIO_VENDOR_ID_TI		0x0097
-#endif
-
-#ifndef SDIO_DEVICE_ID_TI_WL1271
-#define SDIO_DEVICE_ID_TI_WL1271	0x4076
-#endif
-
 static const struct mmc_fixup mmc_fixup_methods[] = {
 	/* by default sdio devices are considered CLK_GATING broken */
 	/* good cards will be whitelisted as they are tested */
-	{ SDIO_ANY_ID, SDIO_ANY_ID,
-		add_quirk_for_sdio_devices, MMC_QUIRK_BROKEN_CLK_GATING },
-	{ SDIO_VENDOR_ID_TI, SDIO_DEVICE_ID_TI_WL1271,
-		remove_quirk, MMC_QUIRK_BROKEN_CLK_GATING },
-	{ 0 }
+	SDIO_FIXUP(SDIO_ANY_ID, SDIO_ANY_ID,
+		   add_quirk_for_sdio_devices,
+		   MMC_QUIRK_BROKEN_CLK_GATING),
+
+	SDIO_FIXUP(SDIO_VENDOR_ID_TI, SDIO_DEVICE_ID_TI_WL1271,
+		   remove_quirk, MMC_QUIRK_BROKEN_CLK_GATING),
+
+	SDIO_FIXUP(SDIO_VENDOR_ID_TI, SDIO_DEVICE_ID_TI_WL1271,
+		   add_quirk, MMC_QUIRK_NONSTD_FUNC_IF),
+
+	SDIO_FIXUP(SDIO_VENDOR_ID_TI, SDIO_DEVICE_ID_TI_WL1271,
+		   add_quirk, MMC_QUIRK_DISABLE_CD),
+
+	END_FIXUP
 };
 
-void mmc_fixup_device(struct mmc_card *card)
+void mmc_fixup_device(struct mmc_card *card, const struct mmc_fixup *table)
 {
 	const struct mmc_fixup *f;
+	u64 rev = cid_rev_card(card);
 
-	for (f = mmc_fixup_methods; f->vendor_fixup; f++) {
-		if ((f->vendor == card->cis.vendor
-		     || f->vendor == (u16) SDIO_ANY_ID) &&
-		    (f->device == card->cis.device
-		     || f->device == (u16) SDIO_ANY_ID)) {
+	/* Non-core specific workarounds. */
+	if (!table)
+		table = mmc_fixup_methods;
+
+	for (f = table; f->vendor_fixup; f++) {
+		if ((f->manfid == CID_MANFID_ANY ||
+		     f->manfid == card->cid.manfid) &&
+		    (f->oemid == CID_OEMID_ANY ||
+		     f->oemid == card->cid.oemid) &&
+		    (f->name == CID_NAME_ANY ||
+		     !strncmp(f->name, card->cid.prod_name,
+			      sizeof(card->cid.prod_name))) &&
+		    (f->cis_vendor == card->cis.vendor ||
+		     f->cis_vendor == (u16) SDIO_ANY_ID) &&
+		    (f->cis_device == card->cis.device ||
+		     f->cis_device == (u16) SDIO_ANY_ID) &&
+		    rev >= f->rev_start && rev <= f->rev_end) {
 			dev_dbg(&card->dev, "calling %pF\n", f->vendor_fixup);
 			f->vendor_fixup(card, f->data);
 		}
diff -druN linux-2.6.39-libre/drivers/mmc/core/sd.c linux-3.0-rc7-libre/drivers/mmc/core/sd.c
--- linux-2.6.39-libre/drivers/mmc/core/sd.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mmc/core/sd.c	2011-07-11 19:51:52.000000000 -0400
@@ -130,7 +130,7 @@
 		break;
 	case 1:
 		/*
-		 * This is a block-addressed SDHC card. Most
+		 * This is a block-addressed SDHC or SDXC card. Most
 		 * interesting fields are unused and have fixed
 		 * values. To avoid getting tripped by buggy cards,
 		 * we assume those fixed values ourselves.
@@ -144,6 +144,11 @@
 		e = UNSTUFF_BITS(resp, 96, 3);
 		csd->max_dtr	  = tran_exp[e] * tran_mant[m];
 		csd->cmdclass	  = UNSTUFF_BITS(resp, 84, 12);
+		csd->c_size	  = UNSTUFF_BITS(resp, 48, 22);
+
+		/* SDXC cards have a minimum C_SIZE of 0x00FFFF */
+		if (csd->c_size >= 0xFFFF)
+			mmc_card_set_ext_capacity(card);
 
 		m = UNSTUFF_BITS(resp, 48, 22);
 		csd->capacity     = (1 + m) << 10;
@@ -189,12 +194,17 @@
 
 	scr->sda_vsn = UNSTUFF_BITS(resp, 56, 4);
 	scr->bus_widths = UNSTUFF_BITS(resp, 48, 4);
+	if (scr->sda_vsn == SCR_SPEC_VER_2)
+		/* Check if Physical Layer Spec v3.0 is supported */
+		scr->sda_spec3 = UNSTUFF_BITS(resp, 47, 1);
 
 	if (UNSTUFF_BITS(resp, 55, 1))
 		card->erased_byte = 0xFF;
 	else
 		card->erased_byte = 0x0;
 
+	if (scr->sda_spec3)
+		scr->cmds = UNSTUFF_BITS(resp, 32, 2);
 	return 0;
 }
 
@@ -274,29 +284,74 @@
 	status = kmalloc(64, GFP_KERNEL);
 	if (!status) {
 		printk(KERN_ERR "%s: could not allocate a buffer for "
-			"switch capabilities.\n", mmc_hostname(card->host));
+			"switch capabilities.\n",
+			mmc_hostname(card->host));
 		return -ENOMEM;
 	}
 
+	/* Find out the supported Bus Speed Modes. */
 	err = mmc_sd_switch(card, 0, 0, 1, status);
 	if (err) {
-		/* If the host or the card can't do the switch,
-		 * fail more gracefully. */
-		if ((err != -EINVAL)
-		 && (err != -ENOSYS)
-		 && (err != -EFAULT))
+		/*
+		 * If the host or the card can't do the switch,
+		 * fail more gracefully.
+		 */
+		if (err != -EINVAL && err != -ENOSYS && err != -EFAULT)
 			goto out;
 
-		printk(KERN_WARNING "%s: problem reading switch "
-			"capabilities, performance might suffer.\n",
+		printk(KERN_WARNING "%s: problem reading Bus Speed modes.\n",
 			mmc_hostname(card->host));
 		err = 0;
 
 		goto out;
 	}
 
-	if (status[13] & 0x02)
-		card->sw_caps.hs_max_dtr = 50000000;
+	if (card->scr.sda_spec3) {
+		card->sw_caps.sd3_bus_mode = status[13];
+
+		/* Find out Driver Strengths supported by the card */
+		err = mmc_sd_switch(card, 0, 2, 1, status);
+		if (err) {
+			/*
+			 * If the host or the card can't do the switch,
+			 * fail more gracefully.
+			 */
+			if (err != -EINVAL && err != -ENOSYS && err != -EFAULT)
+				goto out;
+
+			printk(KERN_WARNING "%s: problem reading "
+				"Driver Strength.\n",
+				mmc_hostname(card->host));
+			err = 0;
+
+			goto out;
+		}
+
+		card->sw_caps.sd3_drv_type = status[9];
+
+		/* Find out Current Limits supported by the card */
+		err = mmc_sd_switch(card, 0, 3, 1, status);
+		if (err) {
+			/*
+			 * If the host or the card can't do the switch,
+			 * fail more gracefully.
+			 */
+			if (err != -EINVAL && err != -ENOSYS && err != -EFAULT)
+				goto out;
+
+			printk(KERN_WARNING "%s: problem reading "
+				"Current Limit.\n",
+				mmc_hostname(card->host));
+			err = 0;
+
+			goto out;
+		}
+
+		card->sw_caps.sd3_curr_limit = status[7];
+	} else {
+		if (status[13] & 0x02)
+			card->sw_caps.hs_max_dtr = 50000000;
+	}
 
 out:
 	kfree(status);
@@ -352,6 +407,232 @@
 	return err;
 }
 
+static int sd_select_driver_type(struct mmc_card *card, u8 *status)
+{
+	int host_drv_type = 0, card_drv_type = 0;
+	int err;
+
+	/*
+	 * If the host doesn't support any of the Driver Types A,C or D,
+	 * default Driver Type B is used.
+	 */
+	if (!(card->host->caps & (MMC_CAP_DRIVER_TYPE_A | MMC_CAP_DRIVER_TYPE_C
+	    | MMC_CAP_DRIVER_TYPE_D)))
+		return 0;
+
+	if (card->host->caps & MMC_CAP_DRIVER_TYPE_A) {
+		host_drv_type = MMC_SET_DRIVER_TYPE_A;
+		if (card->sw_caps.sd3_drv_type & SD_DRIVER_TYPE_A)
+			card_drv_type = MMC_SET_DRIVER_TYPE_A;
+		else if (card->sw_caps.sd3_drv_type & SD_DRIVER_TYPE_B)
+			card_drv_type = MMC_SET_DRIVER_TYPE_B;
+		else if (card->sw_caps.sd3_drv_type & SD_DRIVER_TYPE_C)
+			card_drv_type = MMC_SET_DRIVER_TYPE_C;
+	} else if (card->host->caps & MMC_CAP_DRIVER_TYPE_C) {
+		host_drv_type = MMC_SET_DRIVER_TYPE_C;
+		if (card->sw_caps.sd3_drv_type & SD_DRIVER_TYPE_C)
+			card_drv_type = MMC_SET_DRIVER_TYPE_C;
+	} else if (!(card->host->caps & MMC_CAP_DRIVER_TYPE_D)) {
+		/*
+		 * If we are here, that means only the default driver type
+		 * B is supported by the host.
+		 */
+		host_drv_type = MMC_SET_DRIVER_TYPE_B;
+		if (card->sw_caps.sd3_drv_type & SD_DRIVER_TYPE_B)
+			card_drv_type = MMC_SET_DRIVER_TYPE_B;
+		else if (card->sw_caps.sd3_drv_type & SD_DRIVER_TYPE_C)
+			card_drv_type = MMC_SET_DRIVER_TYPE_C;
+	}
+
+	err = mmc_sd_switch(card, 1, 2, card_drv_type, status);
+	if (err)
+		return err;
+
+	if ((status[15] & 0xF) != card_drv_type) {
+		printk(KERN_WARNING "%s: Problem setting driver strength!\n",
+			mmc_hostname(card->host));
+		return 0;
+	}
+
+	mmc_set_driver_type(card->host, host_drv_type);
+
+	return 0;
+}
+
+static int sd_set_bus_speed_mode(struct mmc_card *card, u8 *status)
+{
+	unsigned int bus_speed = 0, timing = 0;
+	int err;
+
+	/*
+	 * If the host doesn't support any of the UHS-I modes, fallback on
+	 * default speed.
+	 */
+	if (!(card->host->caps & (MMC_CAP_UHS_SDR12 | MMC_CAP_UHS_SDR25 |
+	    MMC_CAP_UHS_SDR50 | MMC_CAP_UHS_SDR104 | MMC_CAP_UHS_DDR50)))
+		return 0;
+
+	if ((card->host->caps & MMC_CAP_UHS_SDR104) &&
+	    (card->sw_caps.sd3_bus_mode & SD_MODE_UHS_SDR104)) {
+			bus_speed = UHS_SDR104_BUS_SPEED;
+			timing = MMC_TIMING_UHS_SDR104;
+			card->sw_caps.uhs_max_dtr = UHS_SDR104_MAX_DTR;
+	} else if ((card->host->caps & MMC_CAP_UHS_DDR50) &&
+		   (card->sw_caps.sd3_bus_mode & SD_MODE_UHS_DDR50)) {
+			bus_speed = UHS_DDR50_BUS_SPEED;
+			timing = MMC_TIMING_UHS_DDR50;
+			card->sw_caps.uhs_max_dtr = UHS_DDR50_MAX_DTR;
+	} else if ((card->host->caps & (MMC_CAP_UHS_SDR104 |
+		    MMC_CAP_UHS_SDR50)) && (card->sw_caps.sd3_bus_mode &
+		    SD_MODE_UHS_SDR50)) {
+			bus_speed = UHS_SDR50_BUS_SPEED;
+			timing = MMC_TIMING_UHS_SDR50;
+			card->sw_caps.uhs_max_dtr = UHS_SDR50_MAX_DTR;
+	} else if ((card->host->caps & (MMC_CAP_UHS_SDR104 |
+		    MMC_CAP_UHS_SDR50 | MMC_CAP_UHS_SDR25)) &&
+		   (card->sw_caps.sd3_bus_mode & SD_MODE_UHS_SDR25)) {
+			bus_speed = UHS_SDR25_BUS_SPEED;
+			timing = MMC_TIMING_UHS_SDR25;
+			card->sw_caps.uhs_max_dtr = UHS_SDR25_MAX_DTR;
+	} else if ((card->host->caps & (MMC_CAP_UHS_SDR104 |
+		    MMC_CAP_UHS_SDR50 | MMC_CAP_UHS_SDR25 |
+		    MMC_CAP_UHS_SDR12)) && (card->sw_caps.sd3_bus_mode &
+		    SD_MODE_UHS_SDR12)) {
+			bus_speed = UHS_SDR12_BUS_SPEED;
+			timing = MMC_TIMING_UHS_SDR12;
+			card->sw_caps.uhs_max_dtr = UHS_SDR12_MAX_DTR;
+	}
+
+	card->sd_bus_speed = bus_speed;
+	err = mmc_sd_switch(card, 1, 0, bus_speed, status);
+	if (err)
+		return err;
+
+	if ((status[16] & 0xF) != bus_speed)
+		printk(KERN_WARNING "%s: Problem setting bus speed mode!\n",
+			mmc_hostname(card->host));
+	else {
+		mmc_set_timing(card->host, timing);
+		mmc_set_clock(card->host, card->sw_caps.uhs_max_dtr);
+	}
+
+	return 0;
+}
+
+static int sd_set_current_limit(struct mmc_card *card, u8 *status)
+{
+	int current_limit = 0;
+	int err;
+
+	/*
+	 * Current limit switch is only defined for SDR50, SDR104, and DDR50
+	 * bus speed modes. For other bus speed modes, we set the default
+	 * current limit of 200mA.
+	 */
+	if ((card->sd_bus_speed == UHS_SDR50_BUS_SPEED) ||
+	    (card->sd_bus_speed == UHS_SDR104_BUS_SPEED) ||
+	    (card->sd_bus_speed == UHS_DDR50_BUS_SPEED)) {
+		if (card->host->caps & MMC_CAP_MAX_CURRENT_800) {
+			if (card->sw_caps.sd3_curr_limit & SD_MAX_CURRENT_800)
+				current_limit = SD_SET_CURRENT_LIMIT_800;
+			else if (card->sw_caps.sd3_curr_limit &
+					SD_MAX_CURRENT_600)
+				current_limit = SD_SET_CURRENT_LIMIT_600;
+			else if (card->sw_caps.sd3_curr_limit &
+					SD_MAX_CURRENT_400)
+				current_limit = SD_SET_CURRENT_LIMIT_400;
+			else if (card->sw_caps.sd3_curr_limit &
+					SD_MAX_CURRENT_200)
+				current_limit = SD_SET_CURRENT_LIMIT_200;
+		} else if (card->host->caps & MMC_CAP_MAX_CURRENT_600) {
+			if (card->sw_caps.sd3_curr_limit & SD_MAX_CURRENT_600)
+				current_limit = SD_SET_CURRENT_LIMIT_600;
+			else if (card->sw_caps.sd3_curr_limit &
+					SD_MAX_CURRENT_400)
+				current_limit = SD_SET_CURRENT_LIMIT_400;
+			else if (card->sw_caps.sd3_curr_limit &
+					SD_MAX_CURRENT_200)
+				current_limit = SD_SET_CURRENT_LIMIT_200;
+		} else if (card->host->caps & MMC_CAP_MAX_CURRENT_400) {
+			if (card->sw_caps.sd3_curr_limit & SD_MAX_CURRENT_400)
+				current_limit = SD_SET_CURRENT_LIMIT_400;
+			else if (card->sw_caps.sd3_curr_limit &
+					SD_MAX_CURRENT_200)
+				current_limit = SD_SET_CURRENT_LIMIT_200;
+		} else if (card->host->caps & MMC_CAP_MAX_CURRENT_200) {
+			if (card->sw_caps.sd3_curr_limit & SD_MAX_CURRENT_200)
+				current_limit = SD_SET_CURRENT_LIMIT_200;
+		}
+	} else
+		current_limit = SD_SET_CURRENT_LIMIT_200;
+
+	err = mmc_sd_switch(card, 1, 3, current_limit, status);
+	if (err)
+		return err;
+
+	if (((status[15] >> 4) & 0x0F) != current_limit)
+		printk(KERN_WARNING "%s: Problem setting current limit!\n",
+			mmc_hostname(card->host));
+
+	return 0;
+}
+
+/*
+ * UHS-I specific initialization procedure
+ */
+static int mmc_sd_init_uhs_card(struct mmc_card *card)
+{
+	int err;
+	u8 *status;
+
+	if (!card->scr.sda_spec3)
+		return 0;
+
+	if (!(card->csd.cmdclass & CCC_SWITCH))
+		return 0;
+
+	status = kmalloc(64, GFP_KERNEL);
+	if (!status) {
+		printk(KERN_ERR "%s: could not allocate a buffer for "
+			"switch capabilities.\n", mmc_hostname(card->host));
+		return -ENOMEM;
+	}
+
+	/* Set 4-bit bus width */
+	if ((card->host->caps & MMC_CAP_4_BIT_DATA) &&
+	    (card->scr.bus_widths & SD_SCR_BUS_WIDTH_4)) {
+		err = mmc_app_set_bus_width(card, MMC_BUS_WIDTH_4);
+		if (err)
+			goto out;
+
+		mmc_set_bus_width(card->host, MMC_BUS_WIDTH_4);
+	}
+
+	/* Set the driver strength for the card */
+	err = sd_select_driver_type(card, status);
+	if (err)
+		goto out;
+
+	/* Set bus speed mode of the card */
+	err = sd_set_bus_speed_mode(card, status);
+	if (err)
+		goto out;
+
+	/* Set current limit for the card */
+	err = sd_set_current_limit(card, status);
+	if (err)
+		goto out;
+
+	/* SPI mode doesn't define CMD19 */
+	if (!mmc_host_is_spi(card->host) && card->host->ops->execute_tuning)
+		err = card->host->ops->execute_tuning(card->host);
+
+out:
+	kfree(status);
+
+	return err;
+}
+
 MMC_DEV_ATTR(cid, "%08x%08x%08x%08x\n", card->raw_cid[0], card->raw_cid[1],
 	card->raw_cid[2], card->raw_cid[3]);
 MMC_DEV_ATTR(csd, "%08x%08x%08x%08x\n", card->raw_csd[0], card->raw_csd[1],
@@ -400,7 +681,7 @@
 /*
  * Fetch CID from card.
  */
-int mmc_sd_get_cid(struct mmc_host *host, u32 ocr, u32 *cid)
+int mmc_sd_get_cid(struct mmc_host *host, u32 ocr, u32 *cid, u32 *rocr)
 {
 	int err;
 
@@ -420,12 +701,39 @@
 	 */
 	err = mmc_send_if_cond(host, ocr);
 	if (!err)
-		ocr |= 1 << 30;
+		ocr |= SD_OCR_CCS;
 
-	err = mmc_send_app_op_cond(host, ocr, NULL);
+	/*
+	 * If the host supports one of UHS-I modes, request the card
+	 * to switch to 1.8V signaling level.
+	 */
+	if (host->caps & (MMC_CAP_UHS_SDR12 | MMC_CAP_UHS_SDR25 |
+	    MMC_CAP_UHS_SDR50 | MMC_CAP_UHS_SDR104 | MMC_CAP_UHS_DDR50))
+		ocr |= SD_OCR_S18R;
+
+	/* If the host can supply more than 150mA, XPC should be set to 1. */
+	if (host->caps & (MMC_CAP_SET_XPC_330 | MMC_CAP_SET_XPC_300 |
+	    MMC_CAP_SET_XPC_180))
+		ocr |= SD_OCR_XPC;
+
+try_again:
+	err = mmc_send_app_op_cond(host, ocr, rocr);
 	if (err)
 		return err;
 
+	/*
+	 * In case CCS and S18A in the response is set, start Signal Voltage
+	 * Switch procedure. SPI mode doesn't support CMD11.
+	 */
+	if (!mmc_host_is_spi(host) && rocr &&
+	   ((*rocr & 0x41000000) == 0x41000000)) {
+		err = mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_180, true);
+		if (err) {
+			ocr &= ~SD_OCR_S18R;
+			goto try_again;
+		}
+	}
+
 	if (mmc_host_is_spi(host))
 		err = mmc_send_cid(host, cid);
 	else
@@ -553,11 +861,12 @@
 	struct mmc_card *card;
 	int err;
 	u32 cid[4];
+	u32 rocr = 0;
 
 	BUG_ON(!host);
 	WARN_ON(!host->claimed);
 
-	err = mmc_sd_get_cid(host, ocr, cid);
+	err = mmc_sd_get_cid(host, ocr, cid, &rocr);
 	if (err)
 		return err;
 
@@ -610,30 +919,47 @@
 	if (err)
 		goto free_card;
 
-	/*
-	 * Attempt to change to high-speed (if supported)
-	 */
-	err = mmc_sd_switch_hs(card);
-	if (err > 0)
-		mmc_sd_go_highspeed(card);
-	else if (err)
-		goto free_card;
+	/* Initialization sequence for UHS-I cards */
+	if (rocr & SD_ROCR_S18A) {
+		err = mmc_sd_init_uhs_card(card);
+		if (err)
+			goto free_card;
 
-	/*
-	 * Set bus speed.
-	 */
-	mmc_set_clock(host, mmc_sd_get_max_clock(card));
+		/* Card is an ultra-high-speed card */
+		mmc_sd_card_set_uhs(card);
 
-	/*
-	 * Switch to wider bus (if supported).
-	 */
-	if ((host->caps & MMC_CAP_4_BIT_DATA) &&
-		(card->scr.bus_widths & SD_SCR_BUS_WIDTH_4)) {
-		err = mmc_app_set_bus_width(card, MMC_BUS_WIDTH_4);
-		if (err)
+		/*
+		 * Since initialization is now complete, enable preset
+		 * value registers for UHS-I cards.
+		 */
+		if (host->ops->enable_preset_value)
+			host->ops->enable_preset_value(host, true);
+	} else {
+		/*
+		 * Attempt to change to high-speed (if supported)
+		 */
+		err = mmc_sd_switch_hs(card);
+		if (err > 0)
+			mmc_sd_go_highspeed(card);
+		else if (err)
 			goto free_card;
 
-		mmc_set_bus_width(host, MMC_BUS_WIDTH_4);
+		/*
+		 * Set bus speed.
+		 */
+		mmc_set_clock(host, mmc_sd_get_max_clock(card));
+
+		/*
+		 * Switch to wider bus (if supported).
+		 */
+		if ((host->caps & MMC_CAP_4_BIT_DATA) &&
+			(card->scr.bus_widths & SD_SCR_BUS_WIDTH_4)) {
+			err = mmc_app_set_bus_width(card, MMC_BUS_WIDTH_4);
+			if (err)
+				goto free_card;
+
+			mmc_set_bus_width(host, MMC_BUS_WIDTH_4);
+		}
 	}
 
 	host->card = card;
@@ -773,6 +1099,15 @@
 	BUG_ON(!host);
 	WARN_ON(!host->claimed);
 
+	/* Make sure we are at 3.3V signalling voltage */
+	err = mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_330, false);
+	if (err)
+		return err;
+
+	/* Disable preset value enable if already set since last time */
+	if (host->ops->enable_preset_value)
+		host->ops->enable_preset_value(host, false);
+
 	err = mmc_send_app_op_cond(host, 0, &ocr);
 	if (err)
 		return err;
diff -druN linux-2.6.39-libre/drivers/mmc/core/sd.h linux-3.0-rc7-libre/drivers/mmc/core/sd.h
--- linux-2.6.39-libre/drivers/mmc/core/sd.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mmc/core/sd.h	2011-07-11 19:51:52.000000000 -0400
@@ -5,7 +5,7 @@
 
 extern struct device_type sd_type;
 
-int mmc_sd_get_cid(struct mmc_host *host, u32 ocr, u32 *cid);
+int mmc_sd_get_cid(struct mmc_host *host, u32 ocr, u32 *cid, u32 *rocr);
 int mmc_sd_get_csd(struct mmc_host *host, struct mmc_card *card);
 void mmc_decode_cid(struct mmc_card *card);
 int mmc_sd_setup_card(struct mmc_host *host, struct mmc_card *card,
diff -druN linux-2.6.39-libre/drivers/mmc/core/sdio_bus.c linux-3.0-rc7-libre/drivers/mmc/core/sdio_bus.c
--- linux-2.6.39-libre/drivers/mmc/core/sdio_bus.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mmc/core/sdio_bus.c	2011-07-11 19:51:52.000000000 -0400
@@ -189,7 +189,7 @@
 
 	/* Then undo the runtime PM settings in sdio_bus_probe() */
 	if (func->card->host->caps & MMC_CAP_POWER_OFF_CARD)
-		pm_runtime_put_noidle(dev);
+		pm_runtime_put_sync(dev);
 
 out:
 	return ret;
diff -druN linux-2.6.39-libre/drivers/mmc/core/sdio.c linux-3.0-rc7-libre/drivers/mmc/core/sdio.c
--- linux-2.6.39-libre/drivers/mmc/core/sdio.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mmc/core/sdio.c	2011-07-11 19:51:52.000000000 -0400
@@ -16,6 +16,7 @@
 #include <linux/mmc/card.h>
 #include <linux/mmc/sdio.h>
 #include <linux/mmc/sdio_func.h>
+#include <linux/mmc/sdio_ids.h>
 
 #include "core.h"
 #include "bus.h"
@@ -31,6 +32,11 @@
 	int ret;
 	unsigned char data;
 
+	if (mmc_card_nonstd_func_interface(func->card)) {
+		func->class = SDIO_CLASS_NONE;
+		return 0;
+	}
+
 	ret = mmc_io_rw_direct(func->card, 0, 0,
 		SDIO_FBR_BASE(func->num) + SDIO_FBR_STD_IF, 0, &data);
 	if (ret)
@@ -181,7 +187,7 @@
 	int ret;
 	u8 ctrl;
 
-	if (!card->cccr.disable_cd)
+	if (!mmc_card_disable_cd(card))
 		return 0;
 
 	ret = mmc_io_rw_direct(card, 0, 0, SDIO_CCCR_IF, 0, &ctrl);
@@ -363,8 +369,8 @@
 		goto err;
 	}
 
-	if (ocr & R4_MEMORY_PRESENT
-	    && mmc_sd_get_cid(host, host->ocr & ocr, card->raw_cid) == 0) {
+	if ((ocr & R4_MEMORY_PRESENT) &&
+	    mmc_sd_get_cid(host, host->ocr & ocr, card->raw_cid, NULL) == 0) {
 		card->type = MMC_TYPE_SD_COMBO;
 
 		if (oldcard && (oldcard->type != MMC_TYPE_SD_COMBO ||
@@ -466,7 +472,7 @@
 
 		card = oldcard;
 	}
-	mmc_fixup_device(card);
+	mmc_fixup_device(card, NULL);
 
 	if (card->type == MMC_TYPE_SD_COMBO) {
 		err = mmc_sd_setup_card(host, card, oldcard != NULL);
@@ -625,7 +631,7 @@
 		}
 	}
 
-	if (!err && host->pm_flags & MMC_PM_KEEP_POWER) {
+	if (!err && mmc_card_keep_power(host) && mmc_card_wake_sdio_irq(host)) {
 		mmc_claim_host(host);
 		sdio_disable_wide(host->card);
 		mmc_release_host(host);
@@ -645,10 +651,10 @@
 	mmc_claim_host(host);
 
 	/* No need to reinitialize powered-resumed nonremovable cards */
-	if (mmc_card_is_removable(host) || !mmc_card_is_powered_resumed(host))
+	if (mmc_card_is_removable(host) || !mmc_card_keep_power(host))
 		err = mmc_sdio_init_card(host, host->ocr, host->card,
-				 (host->pm_flags & MMC_PM_KEEP_POWER));
-	else if (mmc_card_is_powered_resumed(host)) {
+					mmc_card_keep_power(host));
+	else if (mmc_card_keep_power(host) && mmc_card_wake_sdio_irq(host)) {
 		/* We may have switched to 1-bit mode during suspend */
 		err = sdio_enable_4bit_bus(host->card);
 		if (err > 0) {
@@ -685,15 +691,54 @@
 static int mmc_sdio_power_restore(struct mmc_host *host)
 {
 	int ret;
+	u32 ocr;
 
 	BUG_ON(!host);
 	BUG_ON(!host->card);
 
 	mmc_claim_host(host);
+
+	/*
+	 * Reset the card by performing the same steps that are taken by
+	 * mmc_rescan_try_freq() and mmc_attach_sdio() during a "normal" probe.
+	 *
+	 * sdio_reset() is technically not needed. Having just powered up the
+	 * hardware, it should already be in reset state. However, some
+	 * platforms (such as SD8686 on OLPC) do not instantly cut power,
+	 * meaning that a reset is required when restoring power soon after
+	 * powering off. It is harmless in other cases.
+	 *
+	 * The CMD5 reset (mmc_send_io_op_cond()), according to the SDIO spec,
+	 * is not necessary for non-removable cards. However, it is required
+	 * for OLPC SD8686 (which expects a [CMD5,5,3,7] init sequence), and
+	 * harmless in other situations.
+	 *
+	 * With these steps taken, mmc_select_voltage() is also required to
+	 * restore the correct voltage setting of the card.
+	 */
+	sdio_reset(host);
+	mmc_go_idle(host);
+	mmc_send_if_cond(host, host->ocr_avail);
+
+	ret = mmc_send_io_op_cond(host, 0, &ocr);
+	if (ret)
+		goto out;
+
+	if (host->ocr_avail_sdio)
+		host->ocr_avail = host->ocr_avail_sdio;
+
+	host->ocr = mmc_select_voltage(host, ocr & ~0x7F);
+	if (!host->ocr) {
+		ret = -EINVAL;
+		goto out;
+	}
+
 	ret = mmc_sdio_init_card(host, host->ocr, host->card,
-			(host->pm_flags & MMC_PM_KEEP_POWER));
+				mmc_card_keep_power(host));
 	if (!ret && host->sdio_irqs)
 		mmc_signal_sdio_irq(host);
+
+out:
 	mmc_release_host(host);
 
 	return ret;
diff -druN linux-2.6.39-libre/drivers/mmc/core/sdio_irq.c linux-3.0-rc7-libre/drivers/mmc/core/sdio_irq.c
--- linux-2.6.39-libre/drivers/mmc/core/sdio_irq.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mmc/core/sdio_irq.c	2011-07-11 19:51:52.000000000 -0400
@@ -31,6 +31,17 @@
 {
 	int i, ret, count;
 	unsigned char pending;
+	struct sdio_func *func;
+
+	/*
+	 * Optimization, if there is only 1 function interrupt registered
+	 * call irq handler directly
+	 */
+	func = card->sdio_single_irq;
+	if (func) {
+		func->irq_handler(func);
+		return 1;
+	}
 
 	ret = mmc_io_rw_direct(card, 0, 0, SDIO_CCCR_INTx, 0, &pending);
 	if (ret) {
@@ -42,7 +53,7 @@
 	count = 0;
 	for (i = 1; i <= 7; i++) {
 		if (pending & (1 << i)) {
-			struct sdio_func *func = card->sdio_func[i - 1];
+			func = card->sdio_func[i - 1];
 			if (!func) {
 				printk(KERN_WARNING "%s: pending IRQ for "
 					"non-existent function\n",
@@ -186,6 +197,24 @@
 	return 0;
 }
 
+/* If there is only 1 function registered set sdio_single_irq */
+static void sdio_single_irq_set(struct mmc_card *card)
+{
+	struct sdio_func *func;
+	int i;
+
+	card->sdio_single_irq = NULL;
+	if ((card->host->caps & MMC_CAP_SDIO_IRQ) &&
+	    card->host->sdio_irqs == 1)
+		for (i = 0; i < card->sdio_funcs; i++) {
+		       func = card->sdio_func[i];
+		       if (func && func->irq_handler) {
+			       card->sdio_single_irq = func;
+			       break;
+		       }
+	       }
+}
+
 /**
  *	sdio_claim_irq - claim the IRQ for a SDIO function
  *	@func: SDIO function
@@ -227,6 +256,7 @@
 	ret = sdio_card_irq_get(func->card);
 	if (ret)
 		func->irq_handler = NULL;
+	sdio_single_irq_set(func->card);
 
 	return ret;
 }
@@ -251,6 +281,7 @@
 	if (func->irq_handler) {
 		func->irq_handler = NULL;
 		sdio_card_irq_put(func->card);
+		sdio_single_irq_set(func->card);
 	}
 
 	ret = mmc_io_rw_direct(func->card, 0, 0, SDIO_CCCR_IENx, 0, &reg);
diff -druN linux-2.6.39-libre/drivers/mmc/core/sdio_ops.c linux-3.0-rc7-libre/drivers/mmc/core/sdio_ops.c
--- linux-2.6.39-libre/drivers/mmc/core/sdio_ops.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mmc/core/sdio_ops.c	2011-07-11 19:51:52.000000000 -0400
@@ -21,13 +21,11 @@
 
 int mmc_send_io_op_cond(struct mmc_host *host, u32 ocr, u32 *rocr)
 {
-	struct mmc_command cmd;
+	struct mmc_command cmd = {0};
 	int i, err = 0;
 
 	BUG_ON(!host);
 
-	memset(&cmd, 0, sizeof(struct mmc_command));
-
 	cmd.opcode = SD_IO_SEND_OP_COND;
 	cmd.arg = ocr;
 	cmd.flags = MMC_RSP_SPI_R4 | MMC_RSP_R4 | MMC_CMD_BCR;
@@ -70,7 +68,7 @@
 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;
+	struct mmc_command cmd = {0};
 	int err;
 
 	BUG_ON(!host);
@@ -80,8 +78,6 @@
 	if (addr & ~0x1FFFF)
 		return -EINVAL;
 
-	memset(&cmd, 0, sizeof(struct mmc_command));
-
 	cmd.opcode = SD_IO_RW_DIRECT;
 	cmd.arg = write ? 0x80000000 : 0x00000000;
 	cmd.arg |= fn << 28;
@@ -125,9 +121,9 @@
 int mmc_io_rw_extended(struct mmc_card *card, int write, unsigned fn,
 	unsigned addr, int incr_addr, u8 *buf, unsigned blocks, unsigned blksz)
 {
-	struct mmc_request mrq;
-	struct mmc_command cmd;
-	struct mmc_data data;
+	struct mmc_request mrq = {0};
+	struct mmc_command cmd = {0};
+	struct mmc_data data = {0};
 	struct scatterlist sg;
 
 	BUG_ON(!card);
@@ -140,10 +136,6 @@
 	if (addr & ~0x1FFFF)
 		return -EINVAL;
 
-	memset(&mrq, 0, sizeof(struct mmc_request));
-	memset(&cmd, 0, sizeof(struct mmc_command));
-	memset(&data, 0, sizeof(struct mmc_data));
-
 	mrq.cmd = &cmd;
 	mrq.data = &data;
 
diff -druN linux-2.6.39-libre/drivers/mmc/core/sd_ops.c linux-3.0-rc7-libre/drivers/mmc/core/sd_ops.c
--- linux-2.6.39-libre/drivers/mmc/core/sd_ops.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mmc/core/sd_ops.c	2011-07-11 19:51:52.000000000 -0400
@@ -21,10 +21,10 @@
 #include "core.h"
 #include "sd_ops.h"
 
-static int mmc_app_cmd(struct mmc_host *host, struct mmc_card *card)
+int mmc_app_cmd(struct mmc_host *host, struct mmc_card *card)
 {
 	int err;
-	struct mmc_command cmd;
+	struct mmc_command cmd = {0};
 
 	BUG_ON(!host);
 	BUG_ON(card && (card->host != host));
@@ -49,6 +49,7 @@
 
 	return 0;
 }
+EXPORT_SYMBOL_GPL(mmc_app_cmd);
 
 /**
  *	mmc_wait_for_app_cmd - start an application command and wait for
@@ -66,7 +67,7 @@
 int mmc_wait_for_app_cmd(struct mmc_host *host, struct mmc_card *card,
 	struct mmc_command *cmd, int retries)
 {
-	struct mmc_request mrq;
+	struct mmc_request mrq = {0};
 
 	int i, err;
 
@@ -119,13 +120,11 @@
 int mmc_app_set_bus_width(struct mmc_card *card, int width)
 {
 	int err;
-	struct mmc_command cmd;
+	struct mmc_command cmd = {0};
 
 	BUG_ON(!card);
 	BUG_ON(!card->host);
 
-	memset(&cmd, 0, sizeof(struct mmc_command));
-
 	cmd.opcode = SD_APP_SET_BUS_WIDTH;
 	cmd.flags = MMC_RSP_R1 | MMC_CMD_AC;
 
@@ -149,13 +148,11 @@
 
 int mmc_send_app_op_cond(struct mmc_host *host, u32 ocr, u32 *rocr)
 {
-	struct mmc_command cmd;
+	struct mmc_command cmd = {0};
 	int i, err = 0;
 
 	BUG_ON(!host);
 
-	memset(&cmd, 0, sizeof(struct mmc_command));
-
 	cmd.opcode = SD_APP_OP_COND;
 	if (mmc_host_is_spi(host))
 		cmd.arg = ocr & (1 << 30); /* SPI only defines one bit */
@@ -194,7 +191,7 @@
 
 int mmc_send_if_cond(struct mmc_host *host, u32 ocr)
 {
-	struct mmc_command cmd;
+	struct mmc_command cmd = {0};
 	int err;
 	static const u8 test_pattern = 0xAA;
 	u8 result_pattern;
@@ -226,13 +223,11 @@
 int mmc_send_relative_addr(struct mmc_host *host, unsigned int *rca)
 {
 	int err;
-	struct mmc_command cmd;
+	struct mmc_command cmd = {0};
 
 	BUG_ON(!host);
 	BUG_ON(!rca);
 
-	memset(&cmd, 0, sizeof(struct mmc_command));
-
 	cmd.opcode = SD_SEND_RELATIVE_ADDR;
 	cmd.arg = 0;
 	cmd.flags = MMC_RSP_R6 | MMC_CMD_BCR;
@@ -249,9 +244,9 @@
 int mmc_app_send_scr(struct mmc_card *card, u32 *scr)
 {
 	int err;
-	struct mmc_request mrq;
-	struct mmc_command cmd;
-	struct mmc_data data;
+	struct mmc_request mrq = {0};
+	struct mmc_command cmd = {0};
+	struct mmc_data data = {0};
 	struct scatterlist sg;
 	void *data_buf;
 
@@ -272,10 +267,6 @@
 	if (data_buf == NULL)
 		return -ENOMEM;
 
-	memset(&mrq, 0, sizeof(struct mmc_request));
-	memset(&cmd, 0, sizeof(struct mmc_command));
-	memset(&data, 0, sizeof(struct mmc_data));
-
 	mrq.cmd = &cmd;
 	mrq.data = &data;
 
@@ -312,9 +303,9 @@
 int mmc_sd_switch(struct mmc_card *card, int mode, int group,
 	u8 value, u8 *resp)
 {
-	struct mmc_request mrq;
-	struct mmc_command cmd;
-	struct mmc_data data;
+	struct mmc_request mrq = {0};
+	struct mmc_command cmd = {0};
+	struct mmc_data data = {0};
 	struct scatterlist sg;
 
 	BUG_ON(!card);
@@ -325,10 +316,6 @@
 	mode = !!mode;
 	value &= 0xF;
 
-	memset(&mrq, 0, sizeof(struct mmc_request));
-	memset(&cmd, 0, sizeof(struct mmc_command));
-	memset(&data, 0, sizeof(struct mmc_data));
-
 	mrq.cmd = &cmd;
 	mrq.data = &data;
 
@@ -361,9 +348,9 @@
 int mmc_app_sd_status(struct mmc_card *card, void *ssr)
 {
 	int err;
-	struct mmc_request mrq;
-	struct mmc_command cmd;
-	struct mmc_data data;
+	struct mmc_request mrq = {0};
+	struct mmc_command cmd = {0};
+	struct mmc_data data = {0};
 	struct scatterlist sg;
 
 	BUG_ON(!card);
@@ -376,10 +363,6 @@
 	if (err)
 		return err;
 
-	memset(&mrq, 0, sizeof(struct mmc_request));
-	memset(&cmd, 0, sizeof(struct mmc_command));
-	memset(&data, 0, sizeof(struct mmc_data));
-
 	mrq.cmd = &cmd;
 	mrq.data = &data;
 
diff -druN linux-2.6.39-libre/drivers/mmc/host/atmel-mci.c linux-3.0-rc7-libre/drivers/mmc/host/atmel-mci.c
--- linux-2.6.39-libre/drivers/mmc/host/atmel-mci.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mmc/host/atmel-mci.c	2011-07-11 19:51:52.000000000 -0400
@@ -1899,5 +1899,5 @@
 module_exit(atmci_exit);
 
 MODULE_DESCRIPTION("Atmel Multimedia Card Interface driver");
-MODULE_AUTHOR("Haavard Skinnemoen <haavard.skinnemoen@atmel.com>");
+MODULE_AUTHOR("Haavard Skinnemoen (Atmel)");
 MODULE_LICENSE("GPL v2");
diff -druN linux-2.6.39-libre/drivers/mmc/host/dw_mmc.c linux-3.0-rc7-libre/drivers/mmc/host/dw_mmc.c
--- linux-2.6.39-libre/drivers/mmc/host/dw_mmc.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mmc/host/dw_mmc.c	2011-07-11 19:51:52.000000000 -0400
@@ -1769,9 +1769,6 @@
 	int i, ret;
 	struct dw_mci *host = platform_get_drvdata(pdev);
 
-	if (host->vmmc)
-		regulator_enable(host->vmmc);
-
 	for (i = 0; i < host->num_slots; i++) {
 		struct dw_mci_slot *slot = host->slot[i];
 		if (!slot)
@@ -1798,6 +1795,9 @@
 	int i, ret;
 	struct dw_mci *host = platform_get_drvdata(pdev);
 
+	if (host->vmmc)
+		regulator_enable(host->vmmc);
+
 	if (host->dma_ops->init)
 		host->dma_ops->init(host);
 
diff -druN linux-2.6.39-libre/drivers/mmc/host/Kconfig linux-3.0-rc7-libre/drivers/mmc/host/Kconfig
--- linux-2.6.39-libre/drivers/mmc/host/Kconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mmc/host/Kconfig	2011-07-21 06:59:26.000000000 -0400
@@ -154,7 +154,7 @@
 	  If unsure, say N.
 
 config MMC_SDHCI_TEGRA
-	tristate "SDHCI platform support for the Tegra SD/MMC Controller"
+	bool "SDHCI platform support for the Tegra SD/MMC Controller"
 	depends on MMC_SDHCI_PLTFM && ARCH_TEGRA
 	select MMC_SDHCI_IO_ACCESSORS
 	help
@@ -535,6 +535,31 @@
 	  If you have a board based on such a SoC and with a SD/MMC slot,
 	  say Y or M here.
 
+config MMC_VUB300
+	tristate "VUB300 USB to SDIO/SD/MMC Host Controller support"
+	depends on USB
+	help
+	  This selects support for Elan Digital Systems' VUB300 chip.
+
+	  The VUB300 is a USB-SDIO Host Controller Interface chip
+	  that enables the host computer to use SDIO/SD/MMC cards
+	  via a USB 2.0 or USB 1.1 host.
+
+	  The VUB300 chip will be found in both physically separate
+	  USB to SDIO/SD/MMC adapters and embedded on some motherboards.
+
+	  The VUB300 chip supports SD and MMC memory cards in addition
+	  to single and multifunction SDIO cards.
+
+	  /*(DEBLOBBED)*/
+
+	  To compile this mmc host controller driver as a module,
+	  choose M here: the module will be called vub300.
+
+	  If you have a computer with an embedded VUB300 chip
+	  or if you intend connecting a USB adapter based on a
+	  VUB300 chip say Y or M here.
+
 config MMC_USHC
 	tristate "USB SD Host Controller (USHC) support"
 	depends on USB
diff -druN linux-2.6.39-libre/drivers/mmc/host/Makefile linux-3.0-rc7-libre/drivers/mmc/host/Makefile
--- linux-2.6.39-libre/drivers/mmc/host/Makefile	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mmc/host/Makefile	2011-07-11 19:51:52.000000000 -0400
@@ -41,6 +41,7 @@
 obj-$(CONFIG_MMC_DW)		+= dw_mmc.o
 obj-$(CONFIG_MMC_SH_MMCIF)	+= sh_mmcif.o
 obj-$(CONFIG_MMC_JZ4740)	+= jz4740_mmc.o
+obj-$(CONFIG_MMC_VUB300)	+= vub300.o
 obj-$(CONFIG_MMC_USHC)		+= ushc.o
 
 obj-$(CONFIG_MMC_SDHCI_PLTFM)			+= sdhci-platform.o
diff -druN linux-2.6.39-libre/drivers/mmc/host/mmci.c linux-3.0-rc7-libre/drivers/mmc/host/mmci.c
--- linux-2.6.39-libre/drivers/mmc/host/mmci.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mmc/host/mmci.c	2011-07-11 19:51:52.000000000 -0400
@@ -51,6 +51,7 @@
  *		  is asserted (likewise for RX)
  * @sdio: variant supports SDIO
  * @st_clkdiv: true if using a ST-specific clock divider algorithm
+ * @blksz_datactrl16: true if Block size is at b16..b30 position in datactrl register
  */
 struct variant_data {
 	unsigned int		clkreg;
@@ -60,6 +61,7 @@
 	unsigned int		fifohalfsize;
 	bool			sdio;
 	bool			st_clkdiv;
+	bool			blksz_datactrl16;
 };
 
 static struct variant_data variant_arm = {
@@ -77,7 +79,7 @@
 static struct variant_data variant_u300 = {
 	.fifosize		= 16 * 4,
 	.fifohalfsize		= 8 * 4,
-	.clkreg_enable		= 1 << 13, /* HWFCEN */
+	.clkreg_enable		= MCI_ST_U300_HWFCEN,
 	.datalength_bits	= 16,
 	.sdio			= true,
 };
@@ -86,12 +88,23 @@
 	.fifosize		= 30 * 4,
 	.fifohalfsize		= 8 * 4,
 	.clkreg			= MCI_CLK_ENABLE,
-	.clkreg_enable		= 1 << 14, /* HWFCEN */
+	.clkreg_enable		= MCI_ST_UX500_HWFCEN,
 	.datalength_bits	= 24,
 	.sdio			= true,
 	.st_clkdiv		= true,
 };
 
+static struct variant_data variant_ux500v2 = {
+	.fifosize		= 30 * 4,
+	.fifohalfsize		= 8 * 4,
+	.clkreg			= MCI_CLK_ENABLE,
+	.clkreg_enable		= MCI_ST_UX500_HWFCEN,
+	.datalength_bits	= 24,
+	.sdio			= true,
+	.st_clkdiv		= true,
+	.blksz_datactrl16	= true,
+};
+
 /*
  * This must be called with host->lock held
  */
@@ -103,6 +116,8 @@
 	if (desired) {
 		if (desired >= host->mclk) {
 			clk = MCI_CLK_BYPASS;
+			if (variant->st_clkdiv)
+				clk |= MCI_ST_UX500_NEG_EDGE;
 			host->cclk = host->mclk;
 		} else if (variant->st_clkdiv) {
 			/*
@@ -463,7 +478,10 @@
 	blksz_bits = ffs(data->blksz) - 1;
 	BUG_ON(1 << blksz_bits != data->blksz);
 
-	datactrl = MCI_DPSM_ENABLE | blksz_bits << 4;
+	if (variant->blksz_datactrl16)
+		datactrl = MCI_DPSM_ENABLE | (data->blksz << 16);
+	else
+		datactrl = MCI_DPSM_ENABLE | blksz_bits << 4;
 
 	if (data->flags & MMC_DATA_READ)
 		datactrl |= MCI_DPSM_DIRECTION;
@@ -564,6 +582,8 @@
 			data->error = -EILSEQ;
 		} else if (status & MCI_DATATIMEOUT) {
 			data->error = -ETIMEDOUT;
+		} else if (status & MCI_STARTBITERR) {
+			data->error = -ECOMM;
 		} else if (status & MCI_TXUNDERRUN) {
 			data->error = -EIO;
 		} else if (status & MCI_RXOVERRUN) {
@@ -1126,9 +1146,17 @@
 		else if (ret != -ENOSYS)
 			goto err_gpio_cd;
 
+		/*
+		 * A gpio pin that will detect cards when inserted and removed
+		 * will most likely want to trigger on the edges if it is
+		 * 0 when ejected and 1 when inserted (or mutatis mutandis
+		 * for the inverted case) so we request triggers on both
+		 * edges.
+		 */
 		ret = request_any_context_irq(gpio_to_irq(plat->gpio_cd),
-					      mmci_cd_irq, 0,
-					      DRIVER_NAME " (cd)", host);
+				mmci_cd_irq,
+				IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
+				DRIVER_NAME " (cd)", host);
 		if (ret >= 0)
 			host->gpio_cd_irq = gpio_to_irq(plat->gpio_cd);
 	}
@@ -1309,9 +1337,14 @@
 	},
 	{
 		.id     = 0x00480180,
-		.mask   = 0x00ffffff,
+		.mask   = 0xf0ffffff,
 		.data	= &variant_ux500,
 	},
+	{
+		.id     = 0x10480180,
+		.mask   = 0xf0ffffff,
+		.data	= &variant_ux500v2,
+	},
 	{ 0, 0 },
 };
 
diff -druN linux-2.6.39-libre/drivers/mmc/host/mmci.h linux-3.0-rc7-libre/drivers/mmc/host/mmci.h
--- linux-2.6.39-libre/drivers/mmc/host/mmci.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mmc/host/mmci.h	2011-07-11 19:51:52.000000000 -0400
@@ -11,23 +11,33 @@
 #define MCI_PWR_OFF		0x00
 #define MCI_PWR_UP		0x02
 #define MCI_PWR_ON		0x03
-#define MCI_DATA2DIREN		(1 << 2)
-#define MCI_CMDDIREN		(1 << 3)
-#define MCI_DATA0DIREN		(1 << 4)
-#define MCI_DATA31DIREN		(1 << 5)
 #define MCI_OD			(1 << 6)
 #define MCI_ROD			(1 << 7)
-/* The ST Micro version does not have ROD */
-#define MCI_FBCLKEN		(1 << 7)
-#define MCI_DATA74DIREN		(1 << 8)
+/*
+ * The ST Micro version does not have ROD and reuse the voltage registers
+ * for direction settings
+ */
+#define MCI_ST_DATA2DIREN	(1 << 2)
+#define MCI_ST_CMDDIREN		(1 << 3)
+#define MCI_ST_DATA0DIREN	(1 << 4)
+#define MCI_ST_DATA31DIREN	(1 << 5)
+#define MCI_ST_FBCLKEN		(1 << 7)
+#define MCI_ST_DATA74DIREN	(1 << 8)
 
 #define MMCICLOCK		0x004
 #define MCI_CLK_ENABLE		(1 << 8)
 #define MCI_CLK_PWRSAVE		(1 << 9)
 #define MCI_CLK_BYPASS		(1 << 10)
 #define MCI_4BIT_BUS		(1 << 11)
-/* 8bit wide buses supported in ST Micro versions */
+/*
+ * 8bit wide buses, hardware flow contronl, negative edges and clock inversion
+ * supported in ST Micro U300 and Ux500 versions
+ */
 #define MCI_ST_8BIT_BUS		(1 << 12)
+#define MCI_ST_U300_HWFCEN	(1 << 13)
+#define MCI_ST_UX500_NEG_EDGE	(1 << 13)
+#define MCI_ST_UX500_HWFCEN	(1 << 14)
+#define MCI_ST_UX500_CLK_INV	(1 << 15)
 
 #define MMCIARGUMENT		0x008
 #define MMCICOMMAND		0x00c
@@ -76,6 +86,7 @@
 #define MCI_CMDRESPEND		(1 << 6)
 #define MCI_CMDSENT		(1 << 7)
 #define MCI_DATAEND		(1 << 8)
+#define MCI_STARTBITERR		(1 << 9)
 #define MCI_DATABLOCKEND	(1 << 10)
 #define MCI_CMDACTIVE		(1 << 11)
 #define MCI_TXACTIVE		(1 << 12)
@@ -88,8 +99,9 @@
 #define MCI_RXFIFOEMPTY		(1 << 19)
 #define MCI_TXDATAAVLBL		(1 << 20)
 #define MCI_RXDATAAVLBL		(1 << 21)
-#define MCI_SDIOIT		(1 << 22)
-#define MCI_CEATAEND		(1 << 23)
+/* Extended status bits for the ST Micro variants */
+#define MCI_ST_SDIOIT		(1 << 22)
+#define MCI_ST_CEATAEND		(1 << 23)
 
 #define MMCICLEAR		0x038
 #define MCI_CMDCRCFAILCLR	(1 << 0)
@@ -101,9 +113,11 @@
 #define MCI_CMDRESPENDCLR	(1 << 6)
 #define MCI_CMDSENTCLR		(1 << 7)
 #define MCI_DATAENDCLR		(1 << 8)
+#define MCI_STARTBITERRCLR	(1 << 9)
 #define MCI_DATABLOCKENDCLR	(1 << 10)
-#define MCI_SDIOITC		(1 << 22)
-#define MCI_CEATAENDC		(1 << 23)
+/* Extended status bits for the ST Micro variants */
+#define MCI_ST_SDIOITC		(1 << 22)
+#define MCI_ST_CEATAENDC	(1 << 23)
 
 #define MMCIMASK0		0x03c
 #define MCI_CMDCRCFAILMASK	(1 << 0)
@@ -115,6 +129,7 @@
 #define MCI_CMDRESPENDMASK	(1 << 6)
 #define MCI_CMDSENTMASK		(1 << 7)
 #define MCI_DATAENDMASK		(1 << 8)
+#define MCI_STARTBITERRMASK	(1 << 9)
 #define MCI_DATABLOCKENDMASK	(1 << 10)
 #define MCI_CMDACTIVEMASK	(1 << 11)
 #define MCI_TXACTIVEMASK	(1 << 12)
@@ -127,8 +142,9 @@
 #define MCI_RXFIFOEMPTYMASK	(1 << 19)
 #define MCI_TXDATAAVLBLMASK	(1 << 20)
 #define MCI_RXDATAAVLBLMASK	(1 << 21)
-#define MCI_SDIOITMASK		(1 << 22)
-#define MCI_CEATAENDMASK	(1 << 23)
+/* Extended status bits for the ST Micro variants */
+#define MCI_ST_SDIOITMASK	(1 << 22)
+#define MCI_ST_CEATAENDMASK	(1 << 23)
 
 #define MMCIMASK1		0x040
 #define MMCIFIFOCNT		0x048
@@ -137,7 +153,7 @@
 #define MCI_IRQENABLE	\
 	(MCI_CMDCRCFAILMASK|MCI_DATACRCFAILMASK|MCI_CMDTIMEOUTMASK|	\
 	MCI_DATATIMEOUTMASK|MCI_TXUNDERRUNMASK|MCI_RXOVERRUNMASK|	\
-	MCI_CMDRESPENDMASK|MCI_CMDSENTMASK)
+	MCI_CMDRESPENDMASK|MCI_CMDSENTMASK|MCI_STARTBITERRMASK)
 
 /* These interrupts are directed to IRQ1 when two IRQ lines are available */
 #define MCI_IRQ1MASK \
diff -druN linux-2.6.39-libre/drivers/mmc/host/of_mmc_spi.c linux-3.0-rc7-libre/drivers/mmc/host/of_mmc_spi.c
--- linux-2.6.39-libre/drivers/mmc/host/of_mmc_spi.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mmc/host/of_mmc_spi.c	2011-07-11 19:51:52.000000000 -0400
@@ -25,6 +25,11 @@
 #include <linux/mmc/core.h>
 #include <linux/mmc/host.h>
 
+/* For archs that don't support NO_IRQ (such as mips), provide a dummy value */
+#ifndef NO_IRQ
+#define NO_IRQ 0
+#endif
+
 MODULE_LICENSE("GPL");
 
 enum {
diff -druN linux-2.6.39-libre/drivers/mmc/host/omap_hsmmc.c linux-3.0-rc7-libre/drivers/mmc/host/omap_hsmmc.c
--- linux-2.6.39-libre/drivers/mmc/host/omap_hsmmc.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mmc/host/omap_hsmmc.c	2011-07-11 19:51:52.000000000 -0400
@@ -429,12 +429,14 @@
 				return -EINVAL;
 			}
 		}
-		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;
 
+		/* For eMMC do not power off when not in sleep state */
+		if (mmc_slot(host).no_regulator_off_init)
+			return 0;
 		/*
 		* UGLY HACK:  workaround regulator framework bugs.
 		* When the bootloader leaves a supply active, it's
@@ -959,7 +961,8 @@
 	spin_unlock(&host->irq_lock);
 
 	if (host->use_dma && dma_ch != -1) {
-		dma_unmap_sg(mmc_dev(host->mmc), host->data->sg, host->dma_len,
+		dma_unmap_sg(mmc_dev(host->mmc), host->data->sg,
+			host->data->sg_len,
 			omap_hsmmc_get_dma_dir(host, host->data));
 		omap_free_dma(dma_ch);
 	}
@@ -1343,7 +1346,7 @@
 		return;
 	}
 
-	dma_unmap_sg(mmc_dev(host->mmc), data->sg, host->dma_len,
+	dma_unmap_sg(mmc_dev(host->mmc), data->sg, data->sg_len,
 		omap_hsmmc_get_dma_dir(host, data));
 
 	req_in_progress = host->req_in_progress;
diff -druN linux-2.6.39-libre/drivers/mmc/host/sdhci.c linux-3.0-rc7-libre/drivers/mmc/host/sdhci.c
--- linux-2.6.39-libre/drivers/mmc/host/sdhci.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mmc/host/sdhci.c	2011-07-11 19:51:52.000000000 -0400
@@ -38,13 +38,16 @@
 #define SDHCI_USE_LEDS_CLASS
 #endif
 
+#define MAX_TUNING_LOOP 40
+
 static unsigned int debug_quirks = 0;
 
-static void sdhci_prepare_data(struct sdhci_host *, struct mmc_data *);
 static void sdhci_finish_data(struct sdhci_host *);
 
 static void sdhci_send_command(struct sdhci_host *, struct mmc_command *);
 static void sdhci_finish_command(struct sdhci_host *);
+static int sdhci_execute_tuning(struct mmc_host *mmc);
+static void sdhci_tuning_timer(unsigned long data);
 
 static void sdhci_dumpregs(struct sdhci_host *host)
 {
@@ -84,6 +87,8 @@
 	printk(KERN_DEBUG DRIVER_NAME ": Cmd:      0x%08x | Max curr: 0x%08x\n",
 		sdhci_readw(host, SDHCI_COMMAND),
 		sdhci_readl(host, SDHCI_MAX_CURRENT));
+	printk(KERN_DEBUG DRIVER_NAME ": Host ctl2: 0x%08x\n",
+		sdhci_readw(host, SDHCI_HOST_CONTROL2));
 
 	if (host->flags & SDHCI_USE_ADMA)
 		printk(KERN_DEBUG DRIVER_NAME ": ADMA Err: 0x%08x | ADMA Ptr: 0x%08x\n",
@@ -157,6 +162,9 @@
 	if (host->quirks & SDHCI_QUIRK_RESTORE_IRQS_AFTER_RESET)
 		ier = sdhci_readl(host, SDHCI_INT_ENABLE);
 
+	if (host->ops->platform_reset_enter)
+		host->ops->platform_reset_enter(host, mask);
+
 	sdhci_writeb(host, mask, SDHCI_SOFTWARE_RESET);
 
 	if (mask & SDHCI_RESET_ALL)
@@ -177,6 +185,9 @@
 		mdelay(1);
 	}
 
+	if (host->ops->platform_reset_exit)
+		host->ops->platform_reset_exit(host, mask);
+
 	if (host->quirks & SDHCI_QUIRK_RESTORE_IRQS_AFTER_RESET)
 		sdhci_clear_set_irqs(host, SDHCI_INT_ALL_MASK, ier);
 }
@@ -591,9 +602,10 @@
 		data->sg_len, direction);
 }
 
-static u8 sdhci_calc_timeout(struct sdhci_host *host, struct mmc_data *data)
+static u8 sdhci_calc_timeout(struct sdhci_host *host, struct mmc_command *cmd)
 {
 	u8 count;
+	struct mmc_data *data = cmd->data;
 	unsigned target_timeout, current_timeout;
 
 	/*
@@ -605,9 +617,16 @@
 	if (host->quirks & SDHCI_QUIRK_BROKEN_TIMEOUT_VAL)
 		return 0xE;
 
+	/* Unspecified timeout, assume max */
+	if (!data && !cmd->cmd_timeout_ms)
+		return 0xE;
+
 	/* timeout in us */
-	target_timeout = data->timeout_ns / 1000 +
-		data->timeout_clks / host->clock;
+	if (!data)
+		target_timeout = cmd->cmd_timeout_ms * 1000;
+	else
+		target_timeout = data->timeout_ns / 1000 +
+			data->timeout_clks / host->clock;
 
 	if (host->quirks & SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK)
 		host->timeout_clk = host->clock / 1000;
@@ -622,6 +641,7 @@
 	 *     =>
 	 *     (1) / (2) > 2^6
 	 */
+	BUG_ON(!host->timeout_clk);
 	count = 0;
 	current_timeout = (1 << 13) * 1000 / host->timeout_clk;
 	while (current_timeout < target_timeout) {
@@ -632,8 +652,8 @@
 	}
 
 	if (count >= 0xF) {
-		printk(KERN_WARNING "%s: Too large timeout requested!\n",
-			mmc_hostname(host->mmc));
+		printk(KERN_WARNING "%s: Too large timeout requested for CMD%d!\n",
+		       mmc_hostname(host->mmc), cmd->opcode);
 		count = 0xE;
 	}
 
@@ -651,15 +671,21 @@
 		sdhci_clear_set_irqs(host, dma_irqs, pio_irqs);
 }
 
-static void sdhci_prepare_data(struct sdhci_host *host, struct mmc_data *data)
+static void sdhci_prepare_data(struct sdhci_host *host, struct mmc_command *cmd)
 {
 	u8 count;
 	u8 ctrl;
+	struct mmc_data *data = cmd->data;
 	int ret;
 
 	WARN_ON(host->data);
 
-	if (data == NULL)
+	if (data || (cmd->flags & MMC_RSP_BUSY)) {
+		count = sdhci_calc_timeout(host, cmd);
+		sdhci_writeb(host, count, SDHCI_TIMEOUT_CONTROL);
+	}
+
+	if (!data)
 		return;
 
 	/* Sanity checks */
@@ -669,9 +695,7 @@
 
 	host->data = data;
 	host->data_early = 0;
-
-	count = sdhci_calc_timeout(host, data);
-	sdhci_writeb(host, count, SDHCI_TIMEOUT_CONTROL);
+	host->data->bytes_xfered = 0;
 
 	if (host->flags & (SDHCI_USE_SDMA | SDHCI_USE_ADMA))
 		host->flags |= SDHCI_REQ_USE_DMA;
@@ -807,15 +831,17 @@
 
 	sdhci_set_transfer_irqs(host);
 
-	/* We do not handle DMA boundaries, so set it to max (512 KiB) */
-	sdhci_writew(host, SDHCI_MAKE_BLKSZ(7, data->blksz), SDHCI_BLOCK_SIZE);
+	/* Set the DMA boundary value and block size */
+	sdhci_writew(host, SDHCI_MAKE_BLKSZ(SDHCI_DEFAULT_BOUNDARY_ARG,
+		data->blksz), SDHCI_BLOCK_SIZE);
 	sdhci_writew(host, data->blocks, SDHCI_BLOCK_COUNT);
 }
 
 static void sdhci_set_transfer_mode(struct sdhci_host *host,
-	struct mmc_data *data)
+	struct mmc_command *cmd)
 {
 	u16 mode;
+	struct mmc_data *data = cmd->data;
 
 	if (data == NULL)
 		return;
@@ -823,12 +849,20 @@
 	WARN_ON(!host->data);
 
 	mode = SDHCI_TRNS_BLK_CNT_EN;
-	if (data->blocks > 1) {
-		if (host->quirks & SDHCI_QUIRK_MULTIBLOCK_READ_ACMD12)
-			mode |= SDHCI_TRNS_MULTI | SDHCI_TRNS_ACMD12;
-		else
-			mode |= SDHCI_TRNS_MULTI;
+	if (mmc_op_multi(cmd->opcode) || data->blocks > 1) {
+		mode |= SDHCI_TRNS_MULTI;
+		/*
+		 * If we are sending CMD23, CMD12 never gets sent
+		 * on successful completion (so no Auto-CMD12).
+		 */
+		if (!host->mrq->sbc && (host->flags & SDHCI_AUTO_CMD12))
+			mode |= SDHCI_TRNS_AUTO_CMD12;
+		else if (host->mrq->sbc && (host->flags & SDHCI_AUTO_CMD23)) {
+			mode |= SDHCI_TRNS_AUTO_CMD23;
+			sdhci_writel(host, host->mrq->sbc->arg, SDHCI_ARGUMENT2);
+		}
 	}
+
 	if (data->flags & MMC_DATA_READ)
 		mode |= SDHCI_TRNS_READ;
 	if (host->flags & SDHCI_REQ_USE_DMA)
@@ -868,7 +902,15 @@
 	else
 		data->bytes_xfered = data->blksz * data->blocks;
 
-	if (data->stop) {
+	/*
+	 * Need to send CMD12 if -
+	 * a) open-ended multiblock transfer (no CMD23)
+	 * b) error in multiblock transfer
+	 */
+	if (data->stop &&
+	    (data->error ||
+	     !host->mrq->sbc)) {
+
 		/*
 		 * The controller needs a reset of internal state machines
 		 * upon error conditions.
@@ -920,11 +962,11 @@
 
 	host->cmd = cmd;
 
-	sdhci_prepare_data(host, cmd->data);
+	sdhci_prepare_data(host, cmd);
 
 	sdhci_writel(host, cmd->arg, SDHCI_ARGUMENT);
 
-	sdhci_set_transfer_mode(host, cmd->data);
+	sdhci_set_transfer_mode(host, cmd);
 
 	if ((cmd->flags & MMC_RSP_136) && (cmd->flags & MMC_RSP_BUSY)) {
 		printk(KERN_ERR "%s: Unsupported response type!\n",
@@ -947,7 +989,9 @@
 		flags |= SDHCI_CMD_CRC;
 	if (cmd->flags & MMC_RSP_OPCODE)
 		flags |= SDHCI_CMD_INDEX;
-	if (cmd->data)
+
+	/* CMD19 is special in that the Data Present Select should be set */
+	if (cmd->data || (cmd->opcode == MMC_SEND_TUNING_BLOCK))
 		flags |= SDHCI_CMD_DATA;
 
 	sdhci_writew(host, SDHCI_MAKE_CMD(cmd->opcode, flags), SDHCI_COMMAND);
@@ -977,19 +1021,27 @@
 
 	host->cmd->error = 0;
 
-	if (host->data && host->data_early)
-		sdhci_finish_data(host);
+	/* Finished CMD23, now send actual command. */
+	if (host->cmd == host->mrq->sbc) {
+		host->cmd = NULL;
+		sdhci_send_command(host, host->mrq->cmd);
+	} else {
 
-	if (!host->cmd->data)
-		tasklet_schedule(&host->finish_tasklet);
+		/* Processed actual command. */
+		if (host->data && host->data_early)
+			sdhci_finish_data(host);
 
-	host->cmd = NULL;
+		if (!host->cmd->data)
+			tasklet_schedule(&host->finish_tasklet);
+
+		host->cmd = NULL;
+	}
 }
 
 static void sdhci_set_clock(struct sdhci_host *host, unsigned int clock)
 {
-	int div;
-	u16 clk;
+	int div = 0; /* Initialized for compiler warning */
+	u16 clk = 0;
 	unsigned long timeout;
 
 	if (clock == host->clock)
@@ -1007,14 +1059,45 @@
 		goto out;
 
 	if (host->version >= SDHCI_SPEC_300) {
-		/* Version 3.00 divisors must be a multiple of 2. */
-		if (host->max_clk <= clock)
-			div = 1;
-		else {
-			for (div = 2; div < SDHCI_MAX_DIV_SPEC_300; div += 2) {
-				if ((host->max_clk / div) <= clock)
-					break;
+		/*
+		 * Check if the Host Controller supports Programmable Clock
+		 * Mode.
+		 */
+		if (host->clk_mul) {
+			u16 ctrl;
+
+			/*
+			 * We need to figure out whether the Host Driver needs
+			 * to select Programmable Clock Mode, or the value can
+			 * be set automatically by the Host Controller based on
+			 * the Preset Value registers.
+			 */
+			ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2);
+			if (!(ctrl & SDHCI_CTRL_PRESET_VAL_ENABLE)) {
+				for (div = 1; div <= 1024; div++) {
+					if (((host->max_clk * host->clk_mul) /
+					      div) <= clock)
+						break;
+				}
+				/*
+				 * Set Programmable Clock Mode in the Clock
+				 * Control register.
+				 */
+				clk = SDHCI_PROG_CLOCK_MODE;
+				div--;
 			}
+		} else {
+			/* Version 3.00 divisors must be a multiple of 2. */
+			if (host->max_clk <= clock)
+				div = 1;
+			else {
+				for (div = 2; div < SDHCI_MAX_DIV_SPEC_300;
+				     div += 2) {
+					if ((host->max_clk / div) <= clock)
+						break;
+				}
+			}
+			div >>= 1;
 		}
 	} else {
 		/* Version 2.00 divisors must be a power of 2. */
@@ -1022,10 +1105,10 @@
 			if ((host->max_clk / div) <= clock)
 				break;
 		}
+		div >>= 1;
 	}
-	div >>= 1;
 
-	clk = (div & SDHCI_DIV_MASK) << SDHCI_DIVIDER_SHIFT;
+	clk |= (div & SDHCI_DIV_MASK) << SDHCI_DIVIDER_SHIFT;
 	clk |= ((div & SDHCI_DIV_HI_MASK) >> SDHCI_DIV_MASK_LEN)
 		<< SDHCI_DIVIDER_HI_SHIFT;
 	clk |= SDHCI_CLOCK_INT_EN;
@@ -1131,7 +1214,12 @@
 #ifndef SDHCI_USE_LEDS_CLASS
 	sdhci_activate_led(host);
 #endif
-	if (host->quirks & SDHCI_QUIRK_MULTIBLOCK_READ_ACMD12) {
+
+	/*
+	 * Ensure we don't send the STOP for non-SET_BLOCK_COUNTED
+	 * requests if Auto-CMD12 is enabled.
+	 */
+	if (!mrq->sbc && (host->flags & SDHCI_AUTO_CMD12)) {
 		if (mrq->stop) {
 			mrq->data->stop = NULL;
 			mrq->stop = NULL;
@@ -1150,8 +1238,30 @@
 	if (!present || host->flags & SDHCI_DEVICE_DEAD) {
 		host->mrq->cmd->error = -ENOMEDIUM;
 		tasklet_schedule(&host->finish_tasklet);
-	} else
-		sdhci_send_command(host, mrq->cmd);
+	} else {
+		u32 present_state;
+
+		present_state = sdhci_readl(host, SDHCI_PRESENT_STATE);
+		/*
+		 * Check if the re-tuning timer has already expired and there
+		 * is no on-going data transfer. If so, we need to execute
+		 * tuning procedure before sending command.
+		 */
+		if ((host->flags & SDHCI_NEEDS_RETUNING) &&
+		    !(present_state & (SDHCI_DOING_WRITE | SDHCI_DOING_READ))) {
+			spin_unlock_irqrestore(&host->lock, flags);
+			sdhci_execute_tuning(mmc);
+			spin_lock_irqsave(&host->lock, flags);
+
+			/* Restore original mmc_request structure */
+			host->mrq = mrq;
+		}
+
+		if (mrq->sbc && !(host->flags & SDHCI_AUTO_CMD23))
+			sdhci_send_command(host, mrq->sbc);
+		else
+			sdhci_send_command(host, mrq->cmd);
+	}
 
 	mmiowb();
 	spin_unlock_irqrestore(&host->lock, flags);
@@ -1222,7 +1332,84 @@
 	else
 		ctrl &= ~SDHCI_CTRL_HISPD;
 
-	sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL);
+	if (host->version >= SDHCI_SPEC_300) {
+		u16 clk, ctrl_2;
+		unsigned int clock;
+
+		/* In case of UHS-I modes, set High Speed Enable */
+		if ((ios->timing == MMC_TIMING_UHS_SDR50) ||
+		    (ios->timing == MMC_TIMING_UHS_SDR104) ||
+		    (ios->timing == MMC_TIMING_UHS_DDR50) ||
+		    (ios->timing == MMC_TIMING_UHS_SDR25) ||
+		    (ios->timing == MMC_TIMING_UHS_SDR12))
+			ctrl |= SDHCI_CTRL_HISPD;
+
+		ctrl_2 = sdhci_readw(host, SDHCI_HOST_CONTROL2);
+		if (!(ctrl_2 & SDHCI_CTRL_PRESET_VAL_ENABLE)) {
+			sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL);
+			/*
+			 * We only need to set Driver Strength if the
+			 * preset value enable is not set.
+			 */
+			ctrl_2 &= ~SDHCI_CTRL_DRV_TYPE_MASK;
+			if (ios->drv_type == MMC_SET_DRIVER_TYPE_A)
+				ctrl_2 |= SDHCI_CTRL_DRV_TYPE_A;
+			else if (ios->drv_type == MMC_SET_DRIVER_TYPE_C)
+				ctrl_2 |= SDHCI_CTRL_DRV_TYPE_C;
+
+			sdhci_writew(host, ctrl_2, SDHCI_HOST_CONTROL2);
+		} else {
+			/*
+			 * According to SDHC Spec v3.00, if the Preset Value
+			 * Enable in the Host Control 2 register is set, we
+			 * need to reset SD Clock Enable before changing High
+			 * Speed Enable to avoid generating clock gliches.
+			 */
+
+			/* Reset SD Clock Enable */
+			clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL);
+			clk &= ~SDHCI_CLOCK_CARD_EN;
+			sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL);
+
+			sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL);
+
+			/* Re-enable SD Clock */
+			clock = host->clock;
+			host->clock = 0;
+			sdhci_set_clock(host, clock);
+		}
+
+
+		/* Reset SD Clock Enable */
+		clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL);
+		clk &= ~SDHCI_CLOCK_CARD_EN;
+		sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL);
+
+		if (host->ops->set_uhs_signaling)
+			host->ops->set_uhs_signaling(host, ios->timing);
+		else {
+			ctrl_2 = sdhci_readw(host, SDHCI_HOST_CONTROL2);
+			/* Select Bus Speed Mode for host */
+			ctrl_2 &= ~SDHCI_CTRL_UHS_MASK;
+			if (ios->timing == MMC_TIMING_UHS_SDR12)
+				ctrl_2 |= SDHCI_CTRL_UHS_SDR12;
+			else if (ios->timing == MMC_TIMING_UHS_SDR25)
+				ctrl_2 |= SDHCI_CTRL_UHS_SDR25;
+			else if (ios->timing == MMC_TIMING_UHS_SDR50)
+				ctrl_2 |= SDHCI_CTRL_UHS_SDR50;
+			else if (ios->timing == MMC_TIMING_UHS_SDR104)
+				ctrl_2 |= SDHCI_CTRL_UHS_SDR104;
+			else if (ios->timing == MMC_TIMING_UHS_DDR50)
+				ctrl_2 |= SDHCI_CTRL_UHS_DDR50;
+			sdhci_writew(host, ctrl_2, SDHCI_HOST_CONTROL2);
+		}
+
+		/* Re-enable SD Clock */
+		clock = host->clock;
+		host->clock = 0;
+		sdhci_set_clock(host, clock);
+	} else
+		sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL);
 
 	/*
 	 * Some (ENE) controllers go apeshit on some ios operation,
@@ -1237,14 +1424,11 @@
 	spin_unlock_irqrestore(&host->lock, flags);
 }
 
-static int sdhci_get_ro(struct mmc_host *mmc)
+static int check_ro(struct sdhci_host *host)
 {
-	struct sdhci_host *host;
 	unsigned long flags;
 	int is_readonly;
 
-	host = mmc_priv(mmc);
-
 	spin_lock_irqsave(&host->lock, flags);
 
 	if (host->flags & SDHCI_DEVICE_DEAD)
@@ -1262,6 +1446,29 @@
 		!is_readonly : is_readonly;
 }
 
+#define SAMPLE_COUNT	5
+
+static int sdhci_get_ro(struct mmc_host *mmc)
+{
+	struct sdhci_host *host;
+	int i, ro_count;
+
+	host = mmc_priv(mmc);
+
+	if (!(host->quirks & SDHCI_QUIRK_UNSTABLE_RO_DETECT))
+		return check_ro(host);
+
+	ro_count = 0;
+	for (i = 0; i < SAMPLE_COUNT; i++) {
+		if (check_ro(host)) {
+			if (++ro_count > SAMPLE_COUNT / 2)
+				return 1;
+		}
+		msleep(30);
+	}
+	return 0;
+}
+
 static void sdhci_enable_sdio_irq(struct mmc_host *mmc, int enable)
 {
 	struct sdhci_host *host;
@@ -1284,11 +1491,322 @@
 	spin_unlock_irqrestore(&host->lock, flags);
 }
 
+static int sdhci_start_signal_voltage_switch(struct mmc_host *mmc,
+	struct mmc_ios *ios)
+{
+	struct sdhci_host *host;
+	u8 pwr;
+	u16 clk, ctrl;
+	u32 present_state;
+
+	host = mmc_priv(mmc);
+
+	/*
+	 * Signal Voltage Switching is only applicable for Host Controllers
+	 * v3.00 and above.
+	 */
+	if (host->version < SDHCI_SPEC_300)
+		return 0;
+
+	/*
+	 * We first check whether the request is to set signalling voltage
+	 * to 3.3V. If so, we change the voltage to 3.3V and return quickly.
+	 */
+	ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2);
+	if (ios->signal_voltage == MMC_SIGNAL_VOLTAGE_330) {
+		/* Set 1.8V Signal Enable in the Host Control2 register to 0 */
+		ctrl &= ~SDHCI_CTRL_VDD_180;
+		sdhci_writew(host, ctrl, SDHCI_HOST_CONTROL2);
+
+		/* Wait for 5ms */
+		usleep_range(5000, 5500);
+
+		/* 3.3V regulator output should be stable within 5 ms */
+		ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2);
+		if (!(ctrl & SDHCI_CTRL_VDD_180))
+			return 0;
+		else {
+			printk(KERN_INFO DRIVER_NAME ": Switching to 3.3V "
+				"signalling voltage failed\n");
+			return -EIO;
+		}
+	} else if (!(ctrl & SDHCI_CTRL_VDD_180) &&
+		  (ios->signal_voltage == MMC_SIGNAL_VOLTAGE_180)) {
+		/* Stop SDCLK */
+		clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL);
+		clk &= ~SDHCI_CLOCK_CARD_EN;
+		sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL);
+
+		/* Check whether DAT[3:0] is 0000 */
+		present_state = sdhci_readl(host, SDHCI_PRESENT_STATE);
+		if (!((present_state & SDHCI_DATA_LVL_MASK) >>
+		       SDHCI_DATA_LVL_SHIFT)) {
+			/*
+			 * Enable 1.8V Signal Enable in the Host Control2
+			 * register
+			 */
+			ctrl |= SDHCI_CTRL_VDD_180;
+			sdhci_writew(host, ctrl, SDHCI_HOST_CONTROL2);
+
+			/* Wait for 5ms */
+			usleep_range(5000, 5500);
+
+			ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2);
+			if (ctrl & SDHCI_CTRL_VDD_180) {
+				/* Provide SDCLK again and wait for 1ms*/
+				clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL);
+				clk |= SDHCI_CLOCK_CARD_EN;
+				sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL);
+				usleep_range(1000, 1500);
+
+				/*
+				 * If DAT[3:0] level is 1111b, then the card
+				 * was successfully switched to 1.8V signaling.
+				 */
+				present_state = sdhci_readl(host,
+							SDHCI_PRESENT_STATE);
+				if ((present_state & SDHCI_DATA_LVL_MASK) ==
+				     SDHCI_DATA_LVL_MASK)
+					return 0;
+			}
+		}
+
+		/*
+		 * If we are here, that means the switch to 1.8V signaling
+		 * failed. We power cycle the card, and retry initialization
+		 * sequence by setting S18R to 0.
+		 */
+		pwr = sdhci_readb(host, SDHCI_POWER_CONTROL);
+		pwr &= ~SDHCI_POWER_ON;
+		sdhci_writeb(host, pwr, SDHCI_POWER_CONTROL);
+
+		/* Wait for 1ms as per the spec */
+		usleep_range(1000, 1500);
+		pwr |= SDHCI_POWER_ON;
+		sdhci_writeb(host, pwr, SDHCI_POWER_CONTROL);
+
+		printk(KERN_INFO DRIVER_NAME ": Switching to 1.8V signalling "
+			"voltage failed, retrying with S18R set to 0\n");
+		return -EAGAIN;
+	} else
+		/* No signal voltage switch required */
+		return 0;
+}
+
+static int sdhci_execute_tuning(struct mmc_host *mmc)
+{
+	struct sdhci_host *host;
+	u16 ctrl;
+	u32 ier;
+	int tuning_loop_counter = MAX_TUNING_LOOP;
+	unsigned long timeout;
+	int err = 0;
+
+	host = mmc_priv(mmc);
+
+	disable_irq(host->irq);
+	spin_lock(&host->lock);
+
+	ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2);
+
+	/*
+	 * Host Controller needs tuning only in case of SDR104 mode
+	 * and for SDR50 mode when Use Tuning for SDR50 is set in
+	 * Capabilities register.
+	 */
+	if (((ctrl & SDHCI_CTRL_UHS_MASK) == SDHCI_CTRL_UHS_SDR104) ||
+	    (((ctrl & SDHCI_CTRL_UHS_MASK) == SDHCI_CTRL_UHS_SDR50) &&
+	    (host->flags & SDHCI_SDR50_NEEDS_TUNING)))
+		ctrl |= SDHCI_CTRL_EXEC_TUNING;
+	else {
+		spin_unlock(&host->lock);
+		enable_irq(host->irq);
+		return 0;
+	}
+
+	sdhci_writew(host, ctrl, SDHCI_HOST_CONTROL2);
+
+	/*
+	 * As per the Host Controller spec v3.00, tuning command
+	 * generates Buffer Read Ready interrupt, so enable that.
+	 *
+	 * Note: The spec clearly says that when tuning sequence
+	 * is being performed, the controller does not generate
+	 * interrupts other than Buffer Read Ready interrupt. But
+	 * to make sure we don't hit a controller bug, we _only_
+	 * enable Buffer Read Ready interrupt here.
+	 */
+	ier = sdhci_readl(host, SDHCI_INT_ENABLE);
+	sdhci_clear_set_irqs(host, ier, SDHCI_INT_DATA_AVAIL);
+
+	/*
+	 * Issue CMD19 repeatedly till Execute Tuning is set to 0 or the number
+	 * of loops reaches 40 times or a timeout of 150ms occurs.
+	 */
+	timeout = 150;
+	do {
+		struct mmc_command cmd = {0};
+		struct mmc_request mrq = {0};
+
+		if (!tuning_loop_counter && !timeout)
+			break;
+
+		cmd.opcode = MMC_SEND_TUNING_BLOCK;
+		cmd.arg = 0;
+		cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC;
+		cmd.retries = 0;
+		cmd.data = NULL;
+		cmd.error = 0;
+
+		mrq.cmd = &cmd;
+		host->mrq = &mrq;
+
+		/*
+		 * In response to CMD19, the card sends 64 bytes of tuning
+		 * block to the Host Controller. So we set the block size
+		 * to 64 here.
+		 */
+		sdhci_writew(host, SDHCI_MAKE_BLKSZ(7, 64), SDHCI_BLOCK_SIZE);
+
+		/*
+		 * The tuning block is sent by the card to the host controller.
+		 * So we set the TRNS_READ bit in the Transfer Mode register.
+		 * This also takes care of setting DMA Enable and Multi Block
+		 * Select in the same register to 0.
+		 */
+		sdhci_writew(host, SDHCI_TRNS_READ, SDHCI_TRANSFER_MODE);
+
+		sdhci_send_command(host, &cmd);
+
+		host->cmd = NULL;
+		host->mrq = NULL;
+
+		spin_unlock(&host->lock);
+		enable_irq(host->irq);
+
+		/* Wait for Buffer Read Ready interrupt */
+		wait_event_interruptible_timeout(host->buf_ready_int,
+					(host->tuning_done == 1),
+					msecs_to_jiffies(50));
+		disable_irq(host->irq);
+		spin_lock(&host->lock);
+
+		if (!host->tuning_done) {
+			printk(KERN_INFO DRIVER_NAME ": Timeout waiting for "
+				"Buffer Read Ready interrupt during tuning "
+				"procedure, falling back to fixed sampling "
+				"clock\n");
+			ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2);
+			ctrl &= ~SDHCI_CTRL_TUNED_CLK;
+			ctrl &= ~SDHCI_CTRL_EXEC_TUNING;
+			sdhci_writew(host, ctrl, SDHCI_HOST_CONTROL2);
+
+			err = -EIO;
+			goto out;
+		}
+
+		host->tuning_done = 0;
+
+		ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2);
+		tuning_loop_counter--;
+		timeout--;
+		mdelay(1);
+	} while (ctrl & SDHCI_CTRL_EXEC_TUNING);
+
+	/*
+	 * The Host Driver has exhausted the maximum number of loops allowed,
+	 * so use fixed sampling frequency.
+	 */
+	if (!tuning_loop_counter || !timeout) {
+		ctrl &= ~SDHCI_CTRL_TUNED_CLK;
+		sdhci_writew(host, ctrl, SDHCI_HOST_CONTROL2);
+	} else {
+		if (!(ctrl & SDHCI_CTRL_TUNED_CLK)) {
+			printk(KERN_INFO DRIVER_NAME ": Tuning procedure"
+				" failed, falling back to fixed sampling"
+				" clock\n");
+			err = -EIO;
+		}
+	}
+
+out:
+	/*
+	 * If this is the very first time we are here, we start the retuning
+	 * timer. Since only during the first time, SDHCI_NEEDS_RETUNING
+	 * flag won't be set, we check this condition before actually starting
+	 * the timer.
+	 */
+	if (!(host->flags & SDHCI_NEEDS_RETUNING) && host->tuning_count &&
+	    (host->tuning_mode == SDHCI_TUNING_MODE_1)) {
+		mod_timer(&host->tuning_timer, jiffies +
+			host->tuning_count * HZ);
+		/* Tuning mode 1 limits the maximum data length to 4MB */
+		mmc->max_blk_count = (4 * 1024 * 1024) / mmc->max_blk_size;
+	} else {
+		host->flags &= ~SDHCI_NEEDS_RETUNING;
+		/* Reload the new initial value for timer */
+		if (host->tuning_mode == SDHCI_TUNING_MODE_1)
+			mod_timer(&host->tuning_timer, jiffies +
+				host->tuning_count * HZ);
+	}
+
+	/*
+	 * In case tuning fails, host controllers which support re-tuning can
+	 * try tuning again at a later time, when the re-tuning timer expires.
+	 * So for these controllers, we return 0. Since there might be other
+	 * controllers who do not have this capability, we return error for
+	 * them.
+	 */
+	if (err && host->tuning_count &&
+	    host->tuning_mode == SDHCI_TUNING_MODE_1)
+		err = 0;
+
+	sdhci_clear_set_irqs(host, SDHCI_INT_DATA_AVAIL, ier);
+	spin_unlock(&host->lock);
+	enable_irq(host->irq);
+
+	return err;
+}
+
+static void sdhci_enable_preset_value(struct mmc_host *mmc, bool enable)
+{
+	struct sdhci_host *host;
+	u16 ctrl;
+	unsigned long flags;
+
+	host = mmc_priv(mmc);
+
+	/* Host Controller v3.00 defines preset value registers */
+	if (host->version < SDHCI_SPEC_300)
+		return;
+
+	spin_lock_irqsave(&host->lock, flags);
+
+	ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2);
+
+	/*
+	 * We only enable or disable Preset Value if they are not already
+	 * enabled or disabled respectively. Otherwise, we bail out.
+	 */
+	if (enable && !(ctrl & SDHCI_CTRL_PRESET_VAL_ENABLE)) {
+		ctrl |= SDHCI_CTRL_PRESET_VAL_ENABLE;
+		sdhci_writew(host, ctrl, SDHCI_HOST_CONTROL2);
+	} else if (!enable && (ctrl & SDHCI_CTRL_PRESET_VAL_ENABLE)) {
+		ctrl &= ~SDHCI_CTRL_PRESET_VAL_ENABLE;
+		sdhci_writew(host, ctrl, SDHCI_HOST_CONTROL2);
+	}
+
+	spin_unlock_irqrestore(&host->lock, flags);
+}
+
 static const struct mmc_host_ops sdhci_ops = {
 	.request	= sdhci_request,
 	.set_ios	= sdhci_set_ios,
 	.get_ro		= sdhci_get_ro,
 	.enable_sdio_irq = sdhci_enable_sdio_irq,
+	.start_signal_voltage_switch	= sdhci_start_signal_voltage_switch,
+	.execute_tuning			= sdhci_execute_tuning,
+	.enable_preset_value		= sdhci_enable_preset_value,
 };
 
 /*****************************************************************************\
@@ -1345,6 +1863,9 @@
 
 	del_timer(&host->timer);
 
+	if (host->version >= SDHCI_SPEC_300)
+		del_timer(&host->tuning_timer);
+
 	mrq = host->mrq;
 
 	/*
@@ -1418,6 +1939,20 @@
 	spin_unlock_irqrestore(&host->lock, flags);
 }
 
+static void sdhci_tuning_timer(unsigned long data)
+{
+	struct sdhci_host *host;
+	unsigned long flags;
+
+	host = (struct sdhci_host *)data;
+
+	spin_lock_irqsave(&host->lock, flags);
+
+	host->flags |= SDHCI_NEEDS_RETUNING;
+
+	spin_unlock_irqrestore(&host->lock, flags);
+}
+
 /*****************************************************************************\
  *                                                                           *
  * Interrupt handling                                                        *
@@ -1506,6 +2041,16 @@
 {
 	BUG_ON(intmask == 0);
 
+	/* CMD19 generates _only_ Buffer Read Ready interrupt */
+	if (intmask & SDHCI_INT_DATA_AVAIL) {
+		if (SDHCI_GET_CMD(sdhci_readw(host, SDHCI_COMMAND)) ==
+		    MMC_SEND_TUNING_BLOCK) {
+			host->tuning_done = 1;
+			wake_up(&host->buf_ready_int);
+			return;
+		}
+	}
+
 	if (!host->data) {
 		/*
 		 * The "data complete" interrupt is also used to
@@ -1551,10 +2096,28 @@
 		 * We currently don't do anything fancy with DMA
 		 * boundaries, but as we can't disable the feature
 		 * we need to at least restart the transfer.
+		 *
+		 * According to the spec sdhci_readl(host, SDHCI_DMA_ADDRESS)
+		 * should return a valid address to continue from, but as
+		 * some controllers are faulty, don't trust them.
 		 */
-		if (intmask & SDHCI_INT_DMA_END)
-			sdhci_writel(host, sdhci_readl(host, SDHCI_DMA_ADDRESS),
-				SDHCI_DMA_ADDRESS);
+		if (intmask & SDHCI_INT_DMA_END) {
+			u32 dmastart, dmanow;
+			dmastart = sg_dma_address(host->data->sg);
+			dmanow = dmastart + host->data->bytes_xfered;
+			/*
+			 * Force update to the next DMA block boundary.
+			 */
+			dmanow = (dmanow &
+				~(SDHCI_DEFAULT_BOUNDARY_SIZE - 1)) +
+				SDHCI_DEFAULT_BOUNDARY_SIZE;
+			host->data->bytes_xfered = dmanow - dmastart;
+			DBG("%s: DMA base 0x%08x, transferred 0x%06x bytes,"
+				" next 0x%08x\n",
+				mmc_hostname(host->mmc), dmastart,
+				host->data->bytes_xfered, dmanow);
+			sdhci_writel(host, dmanow, SDHCI_DMA_ADDRESS);
+		}
 
 		if (intmask & SDHCI_INT_DATA_END) {
 			if (host->cmd) {
@@ -1664,6 +2227,14 @@
 
 	sdhci_disable_card_detection(host);
 
+	/* Disable tuning since we are suspending */
+	if (host->version >= SDHCI_SPEC_300 && host->tuning_count &&
+	    host->tuning_mode == SDHCI_TUNING_MODE_1) {
+		host->flags &= ~SDHCI_NEEDS_RETUNING;
+		mod_timer(&host->tuning_timer, jiffies +
+			host->tuning_count * HZ);
+	}
+
 	ret = mmc_suspend_host(host->mmc);
 	if (ret)
 		return ret;
@@ -1705,6 +2276,11 @@
 	ret = mmc_resume_host(host->mmc);
 	sdhci_enable_card_detection(host);
 
+	/* Set the re-tuning expiration flag */
+	if ((host->version >= SDHCI_SPEC_300) && host->tuning_count &&
+	    (host->tuning_mode == SDHCI_TUNING_MODE_1))
+		host->flags |= SDHCI_NEEDS_RETUNING;
+
 	return ret;
 }
 
@@ -1751,7 +2327,9 @@
 int sdhci_add_host(struct sdhci_host *host)
 {
 	struct mmc_host *mmc;
-	unsigned int caps, ocr_avail;
+	u32 caps[2];
+	u32 max_current_caps;
+	unsigned int ocr_avail;
 	int ret;
 
 	WARN_ON(host == NULL);
@@ -1774,12 +2352,15 @@
 			host->version);
 	}
 
-	caps = (host->quirks & SDHCI_QUIRK_MISSING_CAPS) ? host->caps :
+	caps[0] = (host->quirks & SDHCI_QUIRK_MISSING_CAPS) ? host->caps :
 		sdhci_readl(host, SDHCI_CAPABILITIES);
 
+	caps[1] = (host->version >= SDHCI_SPEC_300) ?
+		sdhci_readl(host, SDHCI_CAPABILITIES_1) : 0;
+
 	if (host->quirks & SDHCI_QUIRK_FORCE_DMA)
 		host->flags |= SDHCI_USE_SDMA;
-	else if (!(caps & SDHCI_CAN_DO_SDMA))
+	else if (!(caps[0] & SDHCI_CAN_DO_SDMA))
 		DBG("Controller doesn't have SDMA capability\n");
 	else
 		host->flags |= SDHCI_USE_SDMA;
@@ -1790,7 +2371,8 @@
 		host->flags &= ~SDHCI_USE_SDMA;
 	}
 
-	if ((host->version >= SDHCI_SPEC_200) && (caps & SDHCI_CAN_DO_ADMA2))
+	if ((host->version >= SDHCI_SPEC_200) &&
+		(caps[0] & SDHCI_CAN_DO_ADMA2))
 		host->flags |= SDHCI_USE_ADMA;
 
 	if ((host->quirks & SDHCI_QUIRK_BROKEN_ADMA) &&
@@ -1840,10 +2422,10 @@
 	}
 
 	if (host->version >= SDHCI_SPEC_300)
-		host->max_clk = (caps & SDHCI_CLOCK_V3_BASE_MASK)
+		host->max_clk = (caps[0] & SDHCI_CLOCK_V3_BASE_MASK)
 			>> SDHCI_CLOCK_BASE_SHIFT;
 	else
-		host->max_clk = (caps & SDHCI_CLOCK_BASE_MASK)
+		host->max_clk = (caps[0] & SDHCI_CLOCK_BASE_MASK)
 			>> SDHCI_CLOCK_BASE_SHIFT;
 
 	host->max_clk *= 1000000;
@@ -1859,7 +2441,7 @@
 	}
 
 	host->timeout_clk =
-		(caps & SDHCI_TIMEOUT_CLK_MASK) >> SDHCI_TIMEOUT_CLK_SHIFT;
+		(caps[0] & SDHCI_TIMEOUT_CLK_MASK) >> SDHCI_TIMEOUT_CLK_SHIFT;
 	if (host->timeout_clk == 0) {
 		if (host->ops->get_timeout_clock) {
 			host->timeout_clk = host->ops->get_timeout_clock(host);
@@ -1871,22 +2453,55 @@
 			return -ENODEV;
 		}
 	}
-	if (caps & SDHCI_TIMEOUT_CLK_UNIT)
+	if (caps[0] & SDHCI_TIMEOUT_CLK_UNIT)
 		host->timeout_clk *= 1000;
 
 	/*
+	 * In case of Host Controller v3.00, find out whether clock
+	 * multiplier is supported.
+	 */
+	host->clk_mul = (caps[1] & SDHCI_CLOCK_MUL_MASK) >>
+			SDHCI_CLOCK_MUL_SHIFT;
+
+	/*
+	 * In case the value in Clock Multiplier is 0, then programmable
+	 * clock mode is not supported, otherwise the actual clock
+	 * multiplier is one more than the value of Clock Multiplier
+	 * in the Capabilities Register.
+	 */
+	if (host->clk_mul)
+		host->clk_mul += 1;
+
+	/*
 	 * Set host parameters.
 	 */
 	mmc->ops = &sdhci_ops;
+	mmc->f_max = host->max_clk;
 	if (host->ops->get_min_clock)
 		mmc->f_min = host->ops->get_min_clock(host);
-	else if (host->version >= SDHCI_SPEC_300)
-		mmc->f_min = host->max_clk / SDHCI_MAX_DIV_SPEC_300;
-	else
+	else if (host->version >= SDHCI_SPEC_300) {
+		if (host->clk_mul) {
+			mmc->f_min = (host->max_clk * host->clk_mul) / 1024;
+			mmc->f_max = host->max_clk * host->clk_mul;
+		} else
+			mmc->f_min = host->max_clk / SDHCI_MAX_DIV_SPEC_300;
+	} else
 		mmc->f_min = host->max_clk / SDHCI_MAX_DIV_SPEC_200;
 
-	mmc->f_max = host->max_clk;
-	mmc->caps |= MMC_CAP_SDIO_IRQ;
+	mmc->caps |= MMC_CAP_SDIO_IRQ | MMC_CAP_ERASE | MMC_CAP_CMD23;
+
+	if (host->quirks & SDHCI_QUIRK_MULTIBLOCK_READ_ACMD12)
+		host->flags |= SDHCI_AUTO_CMD12;
+
+	/* Auto-CMD23 stuff only works in ADMA or PIO. */
+	if ((host->version >= SDHCI_SPEC_300) &&
+	    ((host->flags & SDHCI_USE_ADMA) ||
+	     !(host->flags & SDHCI_USE_SDMA))) {
+		host->flags |= SDHCI_AUTO_CMD23;
+		DBG("%s: Auto-CMD23 available\n", mmc_hostname(mmc));
+	} else {
+		DBG("%s: Auto-CMD23 unavailable\n", mmc_hostname(mmc));
+	}
 
 	/*
 	 * A controller may support 8-bit width, but the board itself
@@ -1898,21 +2513,113 @@
 	if (!(host->quirks & SDHCI_QUIRK_FORCE_1_BIT_DATA))
 		mmc->caps |= MMC_CAP_4_BIT_DATA;
 
-	if (caps & SDHCI_CAN_DO_HISPD)
+	if (caps[0] & SDHCI_CAN_DO_HISPD)
 		mmc->caps |= MMC_CAP_SD_HIGHSPEED | MMC_CAP_MMC_HIGHSPEED;
 
 	if ((host->quirks & SDHCI_QUIRK_BROKEN_CARD_DETECTION) &&
 	    mmc_card_is_removable(mmc))
 		mmc->caps |= MMC_CAP_NEEDS_POLL;
 
+	/* UHS-I mode(s) supported by the host controller. */
+	if (host->version >= SDHCI_SPEC_300)
+		mmc->caps |= MMC_CAP_UHS_SDR12 | MMC_CAP_UHS_SDR25;
+
+	/* SDR104 supports also implies SDR50 support */
+	if (caps[1] & SDHCI_SUPPORT_SDR104)
+		mmc->caps |= MMC_CAP_UHS_SDR104 | MMC_CAP_UHS_SDR50;
+	else if (caps[1] & SDHCI_SUPPORT_SDR50)
+		mmc->caps |= MMC_CAP_UHS_SDR50;
+
+	if (caps[1] & SDHCI_SUPPORT_DDR50)
+		mmc->caps |= MMC_CAP_UHS_DDR50;
+
+	/* Does the host needs tuning for SDR50? */
+	if (caps[1] & SDHCI_USE_SDR50_TUNING)
+		host->flags |= SDHCI_SDR50_NEEDS_TUNING;
+
+	/* Driver Type(s) (A, C, D) supported by the host */
+	if (caps[1] & SDHCI_DRIVER_TYPE_A)
+		mmc->caps |= MMC_CAP_DRIVER_TYPE_A;
+	if (caps[1] & SDHCI_DRIVER_TYPE_C)
+		mmc->caps |= MMC_CAP_DRIVER_TYPE_C;
+	if (caps[1] & SDHCI_DRIVER_TYPE_D)
+		mmc->caps |= MMC_CAP_DRIVER_TYPE_D;
+
+	/* Initial value for re-tuning timer count */
+	host->tuning_count = (caps[1] & SDHCI_RETUNING_TIMER_COUNT_MASK) >>
+			      SDHCI_RETUNING_TIMER_COUNT_SHIFT;
+
+	/*
+	 * In case Re-tuning Timer is not disabled, the actual value of
+	 * re-tuning timer will be 2 ^ (n - 1).
+	 */
+	if (host->tuning_count)
+		host->tuning_count = 1 << (host->tuning_count - 1);
+
+	/* Re-tuning mode supported by the Host Controller */
+	host->tuning_mode = (caps[1] & SDHCI_RETUNING_MODE_MASK) >>
+			     SDHCI_RETUNING_MODE_SHIFT;
+
 	ocr_avail = 0;
-	if (caps & SDHCI_CAN_VDD_330)
+	/*
+	 * According to SD Host Controller spec v3.00, if the Host System
+	 * can afford more than 150mA, Host Driver should set XPC to 1. Also
+	 * the value is meaningful only if Voltage Support in the Capabilities
+	 * register is set. The actual current value is 4 times the register
+	 * value.
+	 */
+	max_current_caps = sdhci_readl(host, SDHCI_MAX_CURRENT);
+
+	if (caps[0] & SDHCI_CAN_VDD_330) {
+		int max_current_330;
+
 		ocr_avail |= MMC_VDD_32_33 | MMC_VDD_33_34;
-	if (caps & SDHCI_CAN_VDD_300)
+
+		max_current_330 = ((max_current_caps &
+				   SDHCI_MAX_CURRENT_330_MASK) >>
+				   SDHCI_MAX_CURRENT_330_SHIFT) *
+				   SDHCI_MAX_CURRENT_MULTIPLIER;
+
+		if (max_current_330 > 150)
+			mmc->caps |= MMC_CAP_SET_XPC_330;
+	}
+	if (caps[0] & SDHCI_CAN_VDD_300) {
+		int max_current_300;
+
 		ocr_avail |= MMC_VDD_29_30 | MMC_VDD_30_31;
-	if (caps & SDHCI_CAN_VDD_180)
+
+		max_current_300 = ((max_current_caps &
+				   SDHCI_MAX_CURRENT_300_MASK) >>
+				   SDHCI_MAX_CURRENT_300_SHIFT) *
+				   SDHCI_MAX_CURRENT_MULTIPLIER;
+
+		if (max_current_300 > 150)
+			mmc->caps |= MMC_CAP_SET_XPC_300;
+	}
+	if (caps[0] & SDHCI_CAN_VDD_180) {
+		int max_current_180;
+
 		ocr_avail |= MMC_VDD_165_195;
 
+		max_current_180 = ((max_current_caps &
+				   SDHCI_MAX_CURRENT_180_MASK) >>
+				   SDHCI_MAX_CURRENT_180_SHIFT) *
+				   SDHCI_MAX_CURRENT_MULTIPLIER;
+
+		if (max_current_180 > 150)
+			mmc->caps |= MMC_CAP_SET_XPC_180;
+
+		/* Maximum current capabilities of the host at 1.8V */
+		if (max_current_180 >= 800)
+			mmc->caps |= MMC_CAP_MAX_CURRENT_800;
+		else if (max_current_180 >= 600)
+			mmc->caps |= MMC_CAP_MAX_CURRENT_600;
+		else if (max_current_180 >= 400)
+			mmc->caps |= MMC_CAP_MAX_CURRENT_400;
+		else
+			mmc->caps |= MMC_CAP_MAX_CURRENT_200;
+	}
+
 	mmc->ocr_avail = ocr_avail;
 	mmc->ocr_avail_sdio = ocr_avail;
 	if (host->ocr_avail_sdio)
@@ -1972,7 +2679,7 @@
 	if (host->quirks & SDHCI_QUIRK_FORCE_BLK_SZ_2048) {
 		mmc->max_blk_size = 2;
 	} else {
-		mmc->max_blk_size = (caps & SDHCI_MAX_BLOCK_MASK) >>
+		mmc->max_blk_size = (caps[0] & SDHCI_MAX_BLOCK_MASK) >>
 				SDHCI_MAX_BLOCK_SHIFT;
 		if (mmc->max_blk_size >= 3) {
 			printk(KERN_WARNING "%s: Invalid maximum block size, "
@@ -1998,6 +2705,15 @@
 
 	setup_timer(&host->timer, sdhci_timeout_timer, (unsigned long)host);
 
+	if (host->version >= SDHCI_SPEC_300) {
+		init_waitqueue_head(&host->buf_ready_int);
+
+		/* Initialize re-tuning timer */
+		init_timer(&host->tuning_timer);
+		host->tuning_timer.data = (unsigned long)host;
+		host->tuning_timer.function = sdhci_tuning_timer;
+	}
+
 	ret = request_irq(host->irq, sdhci_irq, IRQF_SHARED,
 		mmc_hostname(mmc), host);
 	if (ret)
@@ -2091,6 +2807,8 @@
 	free_irq(host->irq, host);
 
 	del_timer_sync(&host->timer);
+	if (host->version >= SDHCI_SPEC_300)
+		del_timer_sync(&host->tuning_timer);
 
 	tasklet_kill(&host->card_tasklet);
 	tasklet_kill(&host->finish_tasklet);
diff -druN linux-2.6.39-libre/drivers/mmc/host/sdhci.h linux-3.0-rc7-libre/drivers/mmc/host/sdhci.h
--- linux-2.6.39-libre/drivers/mmc/host/sdhci.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mmc/host/sdhci.h	2011-07-11 19:51:52.000000000 -0400
@@ -25,6 +25,7 @@
  */
 
 #define SDHCI_DMA_ADDRESS	0x00
+#define SDHCI_ARGUMENT2		SDHCI_DMA_ADDRESS
 
 #define SDHCI_BLOCK_SIZE	0x04
 #define  SDHCI_MAKE_BLKSZ(dma, blksz) (((dma & 0x7) << 12) | (blksz & 0xFFF))
@@ -36,7 +37,8 @@
 #define SDHCI_TRANSFER_MODE	0x0C
 #define  SDHCI_TRNS_DMA		0x01
 #define  SDHCI_TRNS_BLK_CNT_EN	0x02
-#define  SDHCI_TRNS_ACMD12	0x04
+#define  SDHCI_TRNS_AUTO_CMD12	0x04
+#define  SDHCI_TRNS_AUTO_CMD23	0x08
 #define  SDHCI_TRNS_READ	0x10
 #define  SDHCI_TRNS_MULTI	0x20
 
@@ -68,8 +70,10 @@
 #define  SDHCI_DATA_AVAILABLE	0x00000800
 #define  SDHCI_CARD_PRESENT	0x00010000
 #define  SDHCI_WRITE_PROTECT	0x00080000
+#define  SDHCI_DATA_LVL_MASK	0x00F00000
+#define   SDHCI_DATA_LVL_SHIFT	20
 
-#define SDHCI_HOST_CONTROL 	0x28
+#define SDHCI_HOST_CONTROL	0x28
 #define  SDHCI_CTRL_LED		0x01
 #define  SDHCI_CTRL_4BITBUS	0x02
 #define  SDHCI_CTRL_HISPD	0x04
@@ -99,6 +103,7 @@
 #define  SDHCI_DIV_MASK	0xFF
 #define  SDHCI_DIV_MASK_LEN	8
 #define  SDHCI_DIV_HI_MASK	0x300
+#define  SDHCI_PROG_CLOCK_MODE	0x0020
 #define  SDHCI_CLOCK_CARD_EN	0x0004
 #define  SDHCI_CLOCK_INT_STABLE	0x0002
 #define  SDHCI_CLOCK_INT_EN	0x0001
@@ -146,7 +151,22 @@
 
 #define SDHCI_ACMD12_ERR	0x3C
 
-/* 3E-3F reserved */
+#define SDHCI_HOST_CONTROL2		0x3E
+#define  SDHCI_CTRL_UHS_MASK		0x0007
+#define   SDHCI_CTRL_UHS_SDR12		0x0000
+#define   SDHCI_CTRL_UHS_SDR25		0x0001
+#define   SDHCI_CTRL_UHS_SDR50		0x0002
+#define   SDHCI_CTRL_UHS_SDR104		0x0003
+#define   SDHCI_CTRL_UHS_DDR50		0x0004
+#define  SDHCI_CTRL_VDD_180		0x0008
+#define  SDHCI_CTRL_DRV_TYPE_MASK	0x0030
+#define   SDHCI_CTRL_DRV_TYPE_B		0x0000
+#define   SDHCI_CTRL_DRV_TYPE_A		0x0010
+#define   SDHCI_CTRL_DRV_TYPE_C		0x0020
+#define   SDHCI_CTRL_DRV_TYPE_D		0x0030
+#define  SDHCI_CTRL_EXEC_TUNING		0x0040
+#define  SDHCI_CTRL_TUNED_CLK		0x0080
+#define  SDHCI_CTRL_PRESET_VAL_ENABLE	0x8000
 
 #define SDHCI_CAPABILITIES	0x40
 #define  SDHCI_TIMEOUT_CLK_MASK	0x0000003F
@@ -167,9 +187,30 @@
 #define  SDHCI_CAN_VDD_180	0x04000000
 #define  SDHCI_CAN_64BIT	0x10000000
 
+#define  SDHCI_SUPPORT_SDR50	0x00000001
+#define  SDHCI_SUPPORT_SDR104	0x00000002
+#define  SDHCI_SUPPORT_DDR50	0x00000004
+#define  SDHCI_DRIVER_TYPE_A	0x00000010
+#define  SDHCI_DRIVER_TYPE_C	0x00000020
+#define  SDHCI_DRIVER_TYPE_D	0x00000040
+#define  SDHCI_RETUNING_TIMER_COUNT_MASK	0x00000F00
+#define  SDHCI_RETUNING_TIMER_COUNT_SHIFT	8
+#define  SDHCI_USE_SDR50_TUNING			0x00002000
+#define  SDHCI_RETUNING_MODE_MASK		0x0000C000
+#define  SDHCI_RETUNING_MODE_SHIFT		14
+#define  SDHCI_CLOCK_MUL_MASK	0x00FF0000
+#define  SDHCI_CLOCK_MUL_SHIFT	16
+
 #define SDHCI_CAPABILITIES_1	0x44
 
-#define SDHCI_MAX_CURRENT	0x48
+#define SDHCI_MAX_CURRENT		0x48
+#define  SDHCI_MAX_CURRENT_330_MASK	0x0000FF
+#define  SDHCI_MAX_CURRENT_330_SHIFT	0
+#define  SDHCI_MAX_CURRENT_300_MASK	0x00FF00
+#define  SDHCI_MAX_CURRENT_300_SHIFT	8
+#define  SDHCI_MAX_CURRENT_180_MASK	0xFF0000
+#define  SDHCI_MAX_CURRENT_180_SHIFT	16
+#define   SDHCI_MAX_CURRENT_MULTIPLIER	4
 
 /* 4C-4F reserved for more max current */
 
@@ -202,6 +243,12 @@
 #define SDHCI_MAX_DIV_SPEC_200	256
 #define SDHCI_MAX_DIV_SPEC_300	2046
 
+/*
+ * Host SDMA buffer boundary. Valid values from 4K to 512K in powers of 2.
+ */
+#define SDHCI_DEFAULT_BOUNDARY_SIZE  (512 * 1024)
+#define SDHCI_DEFAULT_BOUNDARY_ARG   (ilog2(SDHCI_DEFAULT_BOUNDARY_SIZE) - 12)
+
 struct sdhci_ops {
 #ifdef CONFIG_MMC_SDHCI_IO_ACCESSORS
 	u32		(*read_l)(struct sdhci_host *host, int reg);
@@ -223,6 +270,10 @@
 	void (*platform_send_init_74_clocks)(struct sdhci_host *host,
 					     u8 power_mode);
 	unsigned int    (*get_ro)(struct sdhci_host *host);
+	void	(*platform_reset_enter)(struct sdhci_host *host, u8 mask);
+	void	(*platform_reset_exit)(struct sdhci_host *host, u8 mask);
+	int	(*set_uhs_signaling)(struct sdhci_host *host, unsigned int uhs);
+
 };
 
 #ifdef CONFIG_MMC_SDHCI_IO_ACCESSORS
diff -druN linux-2.6.39-libre/drivers/mmc/host/sdhci-pci.c linux-3.0-rc7-libre/drivers/mmc/host/sdhci-pci.c
--- linux-2.6.39-libre/drivers/mmc/host/sdhci-pci.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mmc/host/sdhci-pci.c	2011-07-11 19:51:52.000000000 -0400
@@ -18,11 +18,9 @@
 #include <linux/dma-mapping.h>
 #include <linux/slab.h>
 #include <linux/device.h>
-
 #include <linux/mmc/host.h>
-
-#include <asm/scatterlist.h>
-#include <asm/io.h>
+#include <linux/scatterlist.h>
+#include <linux/io.h>
 
 #include "sdhci.h"
 
@@ -46,14 +44,14 @@
 struct sdhci_pci_fixes {
 	unsigned int		quirks;
 
-	int			(*probe)(struct sdhci_pci_chip*);
+	int			(*probe) (struct sdhci_pci_chip *);
 
-	int			(*probe_slot)(struct sdhci_pci_slot*);
-	void			(*remove_slot)(struct sdhci_pci_slot*, int);
+	int			(*probe_slot) (struct sdhci_pci_slot *);
+	void			(*remove_slot) (struct sdhci_pci_slot *, int);
 
-	int			(*suspend)(struct sdhci_pci_chip*,
+	int			(*suspend) (struct sdhci_pci_chip *,
 					pm_message_t);
-	int			(*resume)(struct sdhci_pci_chip*);
+	int			(*resume) (struct sdhci_pci_chip *);
 };
 
 struct sdhci_pci_slot {
@@ -329,6 +327,11 @@
 		return ret;
 	}
 
+	/* quirk for unsable RO-detection on JM388 chips */
+	if (chip->pdev->device == PCI_DEVICE_ID_JMICRON_JMB388_SD ||
+	    chip->pdev->device == PCI_DEVICE_ID_JMICRON_JMB388_ESD)
+		chip->quirks |= SDHCI_QUIRK_UNSTABLE_RO_DETECT;
+
 	return 0;
 }
 
@@ -402,7 +405,7 @@
 
 	if (chip->pdev->device == PCI_DEVICE_ID_JMICRON_JMB38X_MMC ||
 	    chip->pdev->device == PCI_DEVICE_ID_JMICRON_JMB388_ESD) {
-		for (i = 0;i < chip->num_slots;i++)
+		for (i = 0; i < chip->num_slots; i++)
 			jmicron_enable_mmc(chip->slots[i]->host, 0);
 	}
 
@@ -415,7 +418,7 @@
 
 	if (chip->pdev->device == PCI_DEVICE_ID_JMICRON_JMB38X_MMC ||
 	    chip->pdev->device == PCI_DEVICE_ID_JMICRON_JMB388_ESD) {
-		for (i = 0;i < chip->num_slots;i++)
+		for (i = 0; i < chip->num_slots; i++)
 			jmicron_enable_mmc(chip->slots[i]->host, 1);
 	}
 
@@ -798,7 +801,7 @@
 
 #ifdef CONFIG_PM
 
-static int sdhci_pci_suspend (struct pci_dev *pdev, pm_message_t state)
+static int sdhci_pci_suspend(struct pci_dev *pdev, pm_message_t state)
 {
 	struct sdhci_pci_chip *chip;
 	struct sdhci_pci_slot *slot;
@@ -810,7 +813,7 @@
 	if (!chip)
 		return 0;
 
-	for (i = 0;i < chip->num_slots;i++) {
+	for (i = 0; i < chip->num_slots; i++) {
 		slot = chip->slots[i];
 		if (!slot)
 			continue;
@@ -818,7 +821,7 @@
 		ret = sdhci_suspend_host(slot->host, state);
 
 		if (ret) {
-			for (i--;i >= 0;i--)
+			for (i--; i >= 0; i--)
 				sdhci_resume_host(chip->slots[i]->host);
 			return ret;
 		}
@@ -833,7 +836,7 @@
 	if (chip->fixes && chip->fixes->suspend) {
 		ret = chip->fixes->suspend(chip, state);
 		if (ret) {
-			for (i = chip->num_slots - 1;i >= 0;i--)
+			for (i = chip->num_slots - 1; i >= 0; i--)
 				sdhci_resume_host(chip->slots[i]->host);
 			return ret;
 		}
@@ -855,7 +858,7 @@
 	return 0;
 }
 
-static int sdhci_pci_resume (struct pci_dev *pdev)
+static int sdhci_pci_resume(struct pci_dev *pdev)
 {
 	struct sdhci_pci_chip *chip;
 	struct sdhci_pci_slot *slot;
@@ -877,7 +880,7 @@
 			return ret;
 	}
 
-	for (i = 0;i < chip->num_slots;i++) {
+	for (i = 0; i < chip->num_slots; i++) {
 		slot = chip->slots[i];
 		if (!slot)
 			continue;
@@ -1059,7 +1062,7 @@
 	}
 
 	chip->pdev = pdev;
-	chip->fixes = (const struct sdhci_pci_fixes*)ent->driver_data;
+	chip->fixes = (const struct sdhci_pci_fixes *)ent->driver_data;
 	if (chip->fixes)
 		chip->quirks = chip->fixes->quirks;
 	chip->num_slots = slots;
@@ -1074,10 +1077,10 @@
 
 	slots = chip->num_slots;	/* Quirk may have changed this */
 
-	for (i = 0;i < slots;i++) {
+	for (i = 0; i < slots; i++) {
 		slot = sdhci_pci_probe_slot(pdev, chip, first_bar + i);
 		if (IS_ERR(slot)) {
-			for (i--;i >= 0;i--)
+			for (i--; i >= 0; i--)
 				sdhci_pci_remove_slot(chip->slots[i]);
 			ret = PTR_ERR(slot);
 			goto free;
@@ -1105,7 +1108,7 @@
 	chip = pci_get_drvdata(pdev);
 
 	if (chip) {
-		for (i = 0;i < chip->num_slots; i++)
+		for (i = 0; i < chip->num_slots; i++)
 			sdhci_pci_remove_slot(chip->slots[i]);
 
 		pci_set_drvdata(pdev, NULL);
@@ -1116,9 +1119,9 @@
 }
 
 static struct pci_driver sdhci_driver = {
-	.name = 	"sdhci-pci",
+	.name =		"sdhci-pci",
 	.id_table =	pci_ids,
-	.probe = 	sdhci_pci_probe,
+	.probe =	sdhci_pci_probe,
 	.remove =	__devexit_p(sdhci_pci_remove),
 	.suspend =	sdhci_pci_suspend,
 	.resume	=	sdhci_pci_resume,
diff -druN linux-2.6.39-libre/drivers/mmc/host/sdhci-pxa.c linux-3.0-rc7-libre/drivers/mmc/host/sdhci-pxa.c
--- linux-2.6.39-libre/drivers/mmc/host/sdhci-pxa.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mmc/host/sdhci-pxa.c	2011-07-11 19:51:52.000000000 -0400
@@ -69,7 +69,45 @@
 	}
 }
 
+static int set_uhs_signaling(struct sdhci_host *host, unsigned int uhs)
+{
+	u16 ctrl_2;
+
+	/*
+	 * Set V18_EN -- UHS modes do not work without this.
+	 * does not change signaling voltage
+	 */
+	ctrl_2 = sdhci_readw(host, SDHCI_HOST_CONTROL2);
+
+	/* Select Bus Speed Mode for host */
+	ctrl_2 &= ~SDHCI_CTRL_UHS_MASK;
+	switch (uhs) {
+	case MMC_TIMING_UHS_SDR12:
+		ctrl_2 |= SDHCI_CTRL_UHS_SDR12;
+		break;
+	case MMC_TIMING_UHS_SDR25:
+		ctrl_2 |= SDHCI_CTRL_UHS_SDR25;
+		break;
+	case MMC_TIMING_UHS_SDR50:
+		ctrl_2 |= SDHCI_CTRL_UHS_SDR50 | SDHCI_CTRL_VDD_180;
+		break;
+	case MMC_TIMING_UHS_SDR104:
+		ctrl_2 |= SDHCI_CTRL_UHS_SDR104 | SDHCI_CTRL_VDD_180;
+		break;
+	case MMC_TIMING_UHS_DDR50:
+		ctrl_2 |= SDHCI_CTRL_UHS_DDR50 | SDHCI_CTRL_VDD_180;
+		break;
+	}
+
+	sdhci_writew(host, ctrl_2, SDHCI_HOST_CONTROL2);
+	pr_debug("%s:%s uhs = %d, ctrl_2 = %04X\n",
+		__func__, mmc_hostname(host->mmc), uhs, ctrl_2);
+
+	return 0;
+}
+
 static struct sdhci_ops sdhci_pxa_ops = {
+	.set_uhs_signaling = set_uhs_signaling,
 	.set_clock = set_clock,
 };
 
@@ -136,11 +174,19 @@
 	host->hw_name = "MMC";
 	host->ops = &sdhci_pxa_ops;
 	host->irq = irq;
-	host->quirks = SDHCI_QUIRK_BROKEN_ADMA | SDHCI_QUIRK_BROKEN_TIMEOUT_VAL;
+	host->quirks = SDHCI_QUIRK_BROKEN_ADMA
+		| SDHCI_QUIRK_BROKEN_TIMEOUT_VAL
+		| SDHCI_QUIRK_32BIT_DMA_ADDR
+		| SDHCI_QUIRK_32BIT_DMA_SIZE
+		| SDHCI_QUIRK_32BIT_ADMA_SIZE
+		| SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC;
 
 	if (pdata->quirks)
 		host->quirks |= pdata->quirks;
 
+	/* enable 1/8V DDR capable */
+	host->mmc->caps |= MMC_CAP_1_8V_DDR;
+
 	/* If slot design supports 8 bit data, indicate this to MMC. */
 	if (pdata->flags & PXA_FLAG_SD_8_BIT_CAPABLE_SLOT)
 		host->mmc->caps |= MMC_CAP_8_BIT_DATA;
diff -druN linux-2.6.39-libre/drivers/mmc/host/sdhci-tegra.c linux-3.0-rc7-libre/drivers/mmc/host/sdhci-tegra.c
--- linux-2.6.39-libre/drivers/mmc/host/sdhci-tegra.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mmc/host/sdhci-tegra.c	2011-07-11 19:51:52.000000000 -0400
@@ -184,6 +184,8 @@
 	clk_enable(clk);
 	pltfm_host->clk = clk;
 
+	host->mmc->pm_caps = plat->pm_flags;
+
 	if (plat->is_8bit)
 		host->mmc->caps |= MMC_CAP_8_BIT_DATA;
 
diff -druN linux-2.6.39-libre/drivers/mmc/host/sdricoh_cs.c linux-3.0-rc7-libre/drivers/mmc/host/sdricoh_cs.c
--- linux-2.6.39-libre/drivers/mmc/host/sdricoh_cs.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mmc/host/sdricoh_cs.c	2011-07-11 19:51:52.000000000 -0400
@@ -76,7 +76,7 @@
 #define BUSY_TIMEOUT      32767
 
 /* list of supported pcmcia devices */
-static struct pcmcia_device_id pcmcia_ids[] = {
+static const struct pcmcia_device_id pcmcia_ids[] = {
 	/* vendor and device strings followed by their crc32 hashes */
 	PCMCIA_DEVICE_PROD_ID12("RICOH", "Bay1Controller", 0xd9f522ed,
 				0xc3901202),
diff -druN linux-2.6.39-libre/drivers/mmc/host/sh_mmcif.c linux-3.0-rc7-libre/drivers/mmc/host/sh_mmcif.c
--- linux-2.6.39-libre/drivers/mmc/host/sh_mmcif.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mmc/host/sh_mmcif.c	2011-07-11 19:51:52.000000000 -0400
@@ -29,6 +29,8 @@
 #include <linux/mmc/sh_mmcif.h>
 #include <linux/pagemap.h>
 #include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+#include <linux/spinlock.h>
 
 #define DRIVER_NAME	"sh_mmcif"
 #define DRIVER_VERSION	"2010-04-28"
@@ -153,6 +155,12 @@
 #define CLKDEV_MMC_DATA		20000000 /* 20MHz */
 #define CLKDEV_INIT		400000   /* 400 KHz */
 
+enum mmcif_state {
+	STATE_IDLE,
+	STATE_REQUEST,
+	STATE_IOS,
+};
+
 struct sh_mmcif_host {
 	struct mmc_host *mmc;
 	struct mmc_data *data;
@@ -164,6 +172,9 @@
 	long timeout;
 	void __iomem *addr;
 	struct completion intr_wait;
+	enum mmcif_state state;
+	spinlock_t lock;
+	bool power;
 
 	/* DMA support */
 	struct dma_chan		*chan_rx;
@@ -798,17 +809,31 @@
 static void sh_mmcif_request(struct mmc_host *mmc, struct mmc_request *mrq)
 {
 	struct sh_mmcif_host *host = mmc_priv(mmc);
+	unsigned long flags;
+
+	spin_lock_irqsave(&host->lock, flags);
+	if (host->state != STATE_IDLE) {
+		spin_unlock_irqrestore(&host->lock, flags);
+		mrq->cmd->error = -EAGAIN;
+		mmc_request_done(mmc, mrq);
+		return;
+	}
+
+	host->state = STATE_REQUEST;
+	spin_unlock_irqrestore(&host->lock, flags);
 
 	switch (mrq->cmd->opcode) {
 	/* MMCIF does not support SD/SDIO command */
 	case SD_IO_SEND_OP_COND:
 	case MMC_APP_CMD:
+		host->state = STATE_IDLE;
 		mrq->cmd->error = -ETIMEDOUT;
 		mmc_request_done(mmc, mrq);
 		return;
 	case MMC_SEND_EXT_CSD: /* = SD_SEND_IF_COND (8) */
 		if (!mrq->data) {
 			/* send_if_cond cmd (not support) */
+			host->state = STATE_IDLE;
 			mrq->cmd->error = -ETIMEDOUT;
 			mmc_request_done(mmc, mrq);
 			return;
@@ -830,12 +855,9 @@
 	sh_mmcif_start_cmd(host, mrq, mrq->cmd);
 	host->data = NULL;
 
-	if (mrq->cmd->error != 0) {
-		mmc_request_done(mmc, mrq);
-		return;
-	}
-	if (mrq->stop)
+	if (!mrq->cmd->error && mrq->stop)
 		sh_mmcif_stop_cmd(host, mrq, mrq->stop);
+	host->state = STATE_IDLE;
 	mmc_request_done(mmc, mrq);
 }
 
@@ -843,15 +865,39 @@
 {
 	struct sh_mmcif_host *host = mmc_priv(mmc);
 	struct sh_mmcif_plat_data *p = host->pd->dev.platform_data;
+	unsigned long flags;
+
+	spin_lock_irqsave(&host->lock, flags);
+	if (host->state != STATE_IDLE) {
+		spin_unlock_irqrestore(&host->lock, flags);
+		return;
+	}
+
+	host->state = STATE_IOS;
+	spin_unlock_irqrestore(&host->lock, flags);
 
 	if (ios->power_mode == MMC_POWER_UP) {
 		if (p->set_pwr)
 			p->set_pwr(host->pd, ios->power_mode);
+		if (!host->power) {
+			/* See if we also get DMA */
+			sh_mmcif_request_dma(host, host->pd->dev.platform_data);
+			pm_runtime_get_sync(&host->pd->dev);
+			host->power = true;
+		}
 	} else if (ios->power_mode == MMC_POWER_OFF || !ios->clock) {
 		/* clock stop */
 		sh_mmcif_clock_control(host, 0);
-		if (ios->power_mode == MMC_POWER_OFF && p->down_pwr)
-			p->down_pwr(host->pd);
+		if (ios->power_mode == MMC_POWER_OFF) {
+			if (host->power) {
+				pm_runtime_put(&host->pd->dev);
+				sh_mmcif_release_dma(host);
+				host->power = false;
+			}
+			if (p->down_pwr)
+				p->down_pwr(host->pd);
+		}
+		host->state = STATE_IDLE;
 		return;
 	}
 
@@ -859,6 +905,7 @@
 		sh_mmcif_clock_control(host, ios->clock);
 
 	host->bus_width = ios->bus_width;
+	host->state = STATE_IDLE;
 }
 
 static int sh_mmcif_get_cd(struct mmc_host *mmc)
@@ -925,7 +972,7 @@
 		sh_mmcif_bitclr(host, MMCIF_CE_INT_MASK, state);
 		err = 1;
 	} else {
-		dev_dbg(&host->pd->dev, "Not support int\n");
+		dev_dbg(&host->pd->dev, "Unsupported interrupt: 0x%x\n", state);
 		sh_mmcif_writel(host->addr, MMCIF_CE_INT, ~state);
 		sh_mmcif_bitclr(host, MMCIF_CE_INT_MASK, state);
 		err = 1;
@@ -996,6 +1043,7 @@
 	host->pd = pdev;
 
 	init_completion(&host->intr_wait);
+	spin_lock_init(&host->lock);
 
 	mmc->ops = &sh_mmcif_ops;
 	mmc->f_max = host->clk;
@@ -1020,24 +1068,29 @@
 	sh_mmcif_sync_reset(host);
 	platform_set_drvdata(pdev, host);
 
-	/* See if we also get DMA */
-	sh_mmcif_request_dma(host, pd);
+	pm_runtime_enable(&pdev->dev);
+	host->power = false;
+
+	ret = pm_runtime_resume(&pdev->dev);
+	if (ret < 0)
+		goto clean_up2;
 
 	mmc_add_host(mmc);
 
+	sh_mmcif_writel(host->addr, MMCIF_CE_INT_MASK, MASK_ALL);
+
 	ret = request_irq(irq[0], sh_mmcif_intr, 0, "sh_mmc:error", host);
 	if (ret) {
 		dev_err(&pdev->dev, "request_irq error (sh_mmc:error)\n");
-		goto clean_up2;
+		goto clean_up3;
 	}
 	ret = request_irq(irq[1], sh_mmcif_intr, 0, "sh_mmc:int", host);
 	if (ret) {
 		free_irq(irq[0], host);
 		dev_err(&pdev->dev, "request_irq error (sh_mmc:int)\n");
-		goto clean_up2;
+		goto clean_up3;
 	}
 
-	sh_mmcif_writel(host->addr, MMCIF_CE_INT_MASK, MASK_ALL);
 	sh_mmcif_detect(host->mmc);
 
 	dev_info(&pdev->dev, "driver version %s\n", DRIVER_VERSION);
@@ -1045,7 +1098,11 @@
 		sh_mmcif_readl(host->addr, MMCIF_CE_VERSION) & 0x0000ffff);
 	return ret;
 
+clean_up3:
+	mmc_remove_host(mmc);
+	pm_runtime_suspend(&pdev->dev);
 clean_up2:
+	pm_runtime_disable(&pdev->dev);
 	clk_disable(host->hclk);
 clean_up1:
 	mmc_free_host(mmc);
@@ -1060,14 +1117,14 @@
 	struct sh_mmcif_host *host = platform_get_drvdata(pdev);
 	int irq[2];
 
+	pm_runtime_get_sync(&pdev->dev);
+
 	mmc_remove_host(host->mmc);
-	sh_mmcif_release_dma(host);
+	sh_mmcif_writel(host->addr, MMCIF_CE_INT_MASK, MASK_ALL);
 
 	if (host->addr)
 		iounmap(host->addr);
 
-	sh_mmcif_writel(host->addr, MMCIF_CE_INT_MASK, MASK_ALL);
-
 	irq[0] = platform_get_irq(pdev, 0);
 	irq[1] = platform_get_irq(pdev, 1);
 
@@ -1078,15 +1135,52 @@
 
 	clk_disable(host->hclk);
 	mmc_free_host(host->mmc);
+	pm_runtime_put_sync(&pdev->dev);
+	pm_runtime_disable(&pdev->dev);
 
 	return 0;
 }
 
+#ifdef CONFIG_PM
+static int sh_mmcif_suspend(struct device *dev)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct sh_mmcif_host *host = platform_get_drvdata(pdev);
+	int ret = mmc_suspend_host(host->mmc);
+
+	if (!ret) {
+		sh_mmcif_writel(host->addr, MMCIF_CE_INT_MASK, MASK_ALL);
+		clk_disable(host->hclk);
+	}
+
+	return ret;
+}
+
+static int sh_mmcif_resume(struct device *dev)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct sh_mmcif_host *host = platform_get_drvdata(pdev);
+
+	clk_enable(host->hclk);
+
+	return mmc_resume_host(host->mmc);
+}
+#else
+#define sh_mmcif_suspend	NULL
+#define sh_mmcif_resume		NULL
+#endif	/* CONFIG_PM */
+
+static const struct dev_pm_ops sh_mmcif_dev_pm_ops = {
+	.suspend = sh_mmcif_suspend,
+	.resume = sh_mmcif_resume,
+};
+
 static struct platform_driver sh_mmcif_driver = {
 	.probe		= sh_mmcif_probe,
 	.remove		= sh_mmcif_remove,
 	.driver		= {
 		.name	= DRIVER_NAME,
+		.pm	= &sh_mmcif_dev_pm_ops,
 	},
 };
 
diff -druN linux-2.6.39-libre/drivers/mmc/host/sh_mobile_sdhi.c linux-3.0-rc7-libre/drivers/mmc/host/sh_mobile_sdhi.c
--- linux-2.6.39-libre/drivers/mmc/host/sh_mobile_sdhi.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mmc/host/sh_mobile_sdhi.c	2011-07-11 19:51:52.000000000 -0400
@@ -62,7 +62,7 @@
 	struct sh_mobile_sdhi_info *p = pdev->dev.platform_data;
 	struct tmio_mmc_host *host;
 	char clk_name[8];
-	int ret;
+	int i, irq, ret;
 
 	priv = kzalloc(sizeof(struct sh_mobile_sdhi), GFP_KERNEL);
 	if (priv == NULL) {
@@ -71,6 +71,7 @@
 	}
 
 	mmc_data = &priv->mmc_data;
+	p->pdata = mmc_data;
 
 	snprintf(clk_name, sizeof(clk_name), "sdhi%d", pdev->id);
 	priv->clk = clk_get(&pdev->dev, clk_name);
@@ -91,7 +92,7 @@
 		mmc_data->ocr_mask = p->tmio_ocr_mask;
 		mmc_data->capabilities |= p->tmio_caps;
 
-		if (p->dma_slave_tx >= 0 && p->dma_slave_rx >= 0) {
+		if (p->dma_slave_tx > 0 && p->dma_slave_rx > 0) {
 			priv->param_tx.slave_id = p->dma_slave_tx;
 			priv->param_rx.slave_id = p->dma_slave_rx;
 			priv->dma_priv.chan_priv_tx = &priv->param_tx;
@@ -116,11 +117,36 @@
 	if (ret < 0)
 		goto eprobe;
 
-	pr_info("%s at 0x%08lx irq %d\n", mmc_hostname(host->mmc),
-		(unsigned long)host->ctl, host->irq);
+	for (i = 0; i < 3; i++) {
+		irq = platform_get_irq(pdev, i);
+		if (irq < 0) {
+			if (i) {
+				continue;
+			} else {
+				ret = irq;
+				goto eirq;
+			}
+		}
+		ret = request_irq(irq, tmio_mmc_irq, 0,
+				  dev_name(&pdev->dev), host);
+		if (ret) {
+			while (i--) {
+				irq = platform_get_irq(pdev, i);
+				if (irq >= 0)
+					free_irq(irq, host);
+			}
+			goto eirq;
+		}
+	}
+	dev_info(&pdev->dev, "%s base at 0x%08lx clock rate %u MHz\n",
+		 mmc_hostname(host->mmc), (unsigned long)
+		 (platform_get_resource(pdev,IORESOURCE_MEM, 0)->start),
+		 mmc_data->hclk / 1000000);
 
 	return ret;
 
+eirq:
+	tmio_mmc_host_remove(host);
 eprobe:
 	clk_disable(priv->clk);
 	clk_put(priv->clk);
@@ -134,8 +160,19 @@
 	struct mmc_host *mmc = platform_get_drvdata(pdev);
 	struct tmio_mmc_host *host = mmc_priv(mmc);
 	struct sh_mobile_sdhi *priv = container_of(host->pdata, struct sh_mobile_sdhi, mmc_data);
+	struct sh_mobile_sdhi_info *p = pdev->dev.platform_data;
+	int i, irq;
+
+	p->pdata = NULL;
 
 	tmio_mmc_host_remove(host);
+
+	for (i = 0; i < 3; i++) {
+		irq = platform_get_irq(pdev, i);
+		if (irq >= 0)
+			free_irq(irq, host);
+	}
+
 	clk_disable(priv->clk);
 	clk_put(priv->clk);
 	kfree(priv);
@@ -143,10 +180,18 @@
 	return 0;
 }
 
+static const struct dev_pm_ops tmio_mmc_dev_pm_ops = {
+	.suspend = tmio_mmc_host_suspend,
+	.resume = tmio_mmc_host_resume,
+	.runtime_suspend = tmio_mmc_host_runtime_suspend,
+	.runtime_resume = tmio_mmc_host_runtime_resume,
+};
+
 static struct platform_driver sh_mobile_sdhi_driver = {
 	.driver		= {
 		.name	= "sh_mobile_sdhi",
 		.owner	= THIS_MODULE,
+		.pm	= &tmio_mmc_dev_pm_ops,
 	},
 	.probe		= sh_mobile_sdhi_probe,
 	.remove		= __devexit_p(sh_mobile_sdhi_remove),
diff -druN linux-2.6.39-libre/drivers/mmc/host/tmio_mmc.c linux-3.0-rc7-libre/drivers/mmc/host/tmio_mmc.c
--- linux-2.6.39-libre/drivers/mmc/host/tmio_mmc.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mmc/host/tmio_mmc.c	2011-07-11 19:51:52.000000000 -0400
@@ -30,7 +30,7 @@
 	struct mmc_host *mmc = platform_get_drvdata(dev);
 	int ret;
 
-	ret = mmc_suspend_host(mmc);
+	ret = tmio_mmc_host_suspend(&dev->dev);
 
 	/* Tell MFD core it can disable us now.*/
 	if (!ret && cell->disable)
@@ -46,15 +46,12 @@
 	int ret = 0;
 
 	/* Tell the MFD core we are ready to be enabled */
-	if (cell->resume) {
+	if (cell->resume)
 		ret = cell->resume(dev);
-		if (ret)
-			goto out;
-	}
 
-	mmc_resume_host(mmc);
+	if (!ret)
+		ret = tmio_mmc_host_resume(&dev->dev);
 
-out:
 	return ret;
 }
 #else
@@ -67,15 +64,21 @@
 	const struct mfd_cell *cell = mfd_get_cell(pdev);
 	struct tmio_mmc_data *pdata;
 	struct tmio_mmc_host *host;
-	int ret = -EINVAL;
+	int ret = -EINVAL, irq;
 
 	if (pdev->num_resources != 2)
 		goto out;
 
-	pdata = mfd_get_data(pdev);
+	pdata = pdev->dev.platform_data;
 	if (!pdata || !pdata->hclk)
 		goto out;
 
+	irq = platform_get_irq(pdev, 0);
+	if (irq < 0) {
+		ret = irq;
+		goto out;
+	}
+
 	/* Tell the MFD core we are ready to be enabled */
 	if (cell->enable) {
 		ret = cell->enable(pdev);
@@ -87,11 +90,18 @@
 	if (ret)
 		goto cell_disable;
 
+	ret = request_irq(irq, tmio_mmc_irq, IRQF_DISABLED |
+			  IRQF_TRIGGER_FALLING, dev_name(&pdev->dev), host);
+	if (ret)
+		goto host_remove;
+
 	pr_info("%s at 0x%08lx irq %d\n", mmc_hostname(host->mmc),
-		(unsigned long)host->ctl, host->irq);
+		(unsigned long)host->ctl, irq);
 
 	return 0;
 
+host_remove:
+	tmio_mmc_host_remove(host);
 cell_disable:
 	if (cell->disable)
 		cell->disable(pdev);
@@ -107,7 +117,9 @@
 	platform_set_drvdata(pdev, NULL);
 
 	if (mmc) {
-		tmio_mmc_host_remove(mmc_priv(mmc));
+		struct tmio_mmc_host *host = mmc_priv(mmc);
+		free_irq(platform_get_irq(pdev, 0), host);
+		tmio_mmc_host_remove(host);
 		if (cell->disable)
 			cell->disable(pdev);
 	}
diff -druN linux-2.6.39-libre/drivers/mmc/host/tmio_mmc_dma.c linux-3.0-rc7-libre/drivers/mmc/host/tmio_mmc_dma.c
--- linux-2.6.39-libre/drivers/mmc/host/tmio_mmc_dma.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mmc/host/tmio_mmc_dma.c	2011-07-11 19:51:52.000000000 -0400
@@ -256,7 +256,10 @@
 void tmio_mmc_request_dma(struct tmio_mmc_host *host, struct tmio_mmc_data *pdata)
 {
 	/* We can only either use DMA for both Tx and Rx or not use it at all */
-	if (pdata->dma) {
+	if (!pdata->dma)
+		return;
+
+	if (!host->chan_tx && !host->chan_rx) {
 		dma_cap_mask_t mask;
 
 		dma_cap_zero(mask);
@@ -284,18 +287,18 @@
 
 		tasklet_init(&host->dma_complete, tmio_mmc_tasklet_fn, (unsigned long)host);
 		tasklet_init(&host->dma_issue, tmio_mmc_issue_tasklet_fn, (unsigned long)host);
+	}
 
-		tmio_mmc_enable_dma(host, true);
+	tmio_mmc_enable_dma(host, true);
+
+	return;
 
-		return;
 ebouncebuf:
-		dma_release_channel(host->chan_rx);
-		host->chan_rx = NULL;
+	dma_release_channel(host->chan_rx);
+	host->chan_rx = NULL;
 ereqrx:
-		dma_release_channel(host->chan_tx);
-		host->chan_tx = NULL;
-		return;
-	}
+	dma_release_channel(host->chan_tx);
+	host->chan_tx = NULL;
 }
 
 void tmio_mmc_release_dma(struct tmio_mmc_host *host)
diff -druN linux-2.6.39-libre/drivers/mmc/host/tmio_mmc.h linux-3.0-rc7-libre/drivers/mmc/host/tmio_mmc.h
--- linux-2.6.39-libre/drivers/mmc/host/tmio_mmc.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mmc/host/tmio_mmc.h	2011-07-11 19:51:52.000000000 -0400
@@ -19,6 +19,7 @@
 #include <linux/highmem.h>
 #include <linux/mmc/tmio.h>
 #include <linux/pagemap.h>
+#include <linux/spinlock.h>
 
 /* Definitions for values the CTRL_SDIO_STATUS register can take. */
 #define TMIO_SDIO_STAT_IOIRQ	0x0001
@@ -44,13 +45,14 @@
 	struct mmc_request      *mrq;
 	struct mmc_data         *data;
 	struct mmc_host         *mmc;
-	int                     irq;
 	unsigned int		sdio_irq_enabled;
 
 	/* Callbacks for clock / power control */
 	void (*set_pwr)(struct platform_device *host, int state);
 	void (*set_clk_div)(struct platform_device *host, int state);
 
+	int			pm_error;
+
 	/* pio related stuff */
 	struct scatterlist      *sg_ptr;
 	struct scatterlist      *sg_orig;
@@ -83,6 +85,7 @@
 
 void tmio_mmc_enable_mmc_irqs(struct tmio_mmc_host *host, u32 i);
 void tmio_mmc_disable_mmc_irqs(struct tmio_mmc_host *host, u32 i);
+irqreturn_t tmio_mmc_irq(int irq, void *devid);
 
 static inline char *tmio_mmc_kmap_atomic(struct scatterlist *sg,
 					 unsigned long *flags)
@@ -120,4 +123,15 @@
 }
 #endif
 
+#ifdef CONFIG_PM
+int tmio_mmc_host_suspend(struct device *dev);
+int tmio_mmc_host_resume(struct device *dev);
+#else
+#define tmio_mmc_host_suspend NULL
+#define tmio_mmc_host_resume NULL
+#endif
+
+int tmio_mmc_host_runtime_suspend(struct device *dev);
+int tmio_mmc_host_runtime_resume(struct device *dev);
+
 #endif
diff -druN linux-2.6.39-libre/drivers/mmc/host/tmio_mmc_pio.c linux-3.0-rc7-libre/drivers/mmc/host/tmio_mmc_pio.c
--- linux-2.6.39-libre/drivers/mmc/host/tmio_mmc_pio.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mmc/host/tmio_mmc_pio.c	2011-07-11 19:51:52.000000000 -0400
@@ -39,6 +39,7 @@
 #include <linux/module.h>
 #include <linux/pagemap.h>
 #include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
 #include <linux/scatterlist.h>
 #include <linux/workqueue.h>
 #include <linux/spinlock.h>
@@ -243,8 +244,12 @@
 	spin_lock_irqsave(&host->lock, flags);
 	mrq = host->mrq;
 
-	/* request already finished */
-	if (!mrq
+	/*
+	 * is request already finished? Since we use a non-blocking
+	 * cancel_delayed_work(), it can happen, that a .set_ios() call preempts
+	 * us, so, have to check for IS_ERR(host->mrq)
+	 */
+	if (IS_ERR_OR_NULL(mrq)
 	    || time_is_after_jiffies(host->last_req_ts +
 		msecs_to_jiffies(2000))) {
 		spin_unlock_irqrestore(&host->lock, flags);
@@ -264,16 +269,19 @@
 
 	host->cmd = NULL;
 	host->data = NULL;
-	host->mrq = NULL;
 	host->force_pio = false;
 
 	spin_unlock_irqrestore(&host->lock, flags);
 
 	tmio_mmc_reset(host);
 
+	/* Ready for new calls */
+	host->mrq = NULL;
+
 	mmc_request_done(host->mmc, mrq);
 }
 
+/* called with host->lock held, interrupts disabled */
 static void tmio_mmc_finish_request(struct tmio_mmc_host *host)
 {
 	struct mmc_request *mrq = host->mrq;
@@ -281,13 +289,15 @@
 	if (!mrq)
 		return;
 
-	host->mrq = NULL;
 	host->cmd = NULL;
 	host->data = NULL;
 	host->force_pio = false;
 
 	cancel_delayed_work(&host->delayed_reset_work);
 
+	host->mrq = NULL;
+
+	/* FIXME: mmc_request_done() can schedule! */
 	mmc_request_done(host->mmc, mrq);
 }
 
@@ -554,7 +564,7 @@
 	spin_unlock(&host->lock);
 }
 
-static irqreturn_t tmio_mmc_irq(int irq, void *devid)
+irqreturn_t tmio_mmc_irq(int irq, void *devid)
 {
 	struct tmio_mmc_host *host = devid;
 	struct tmio_mmc_data *pdata = host->pdata;
@@ -649,6 +659,7 @@
 out:
 	return IRQ_HANDLED;
 }
+EXPORT_SYMBOL(tmio_mmc_irq);
 
 static int tmio_mmc_start_data(struct tmio_mmc_host *host,
 	struct mmc_data *data)
@@ -685,15 +696,27 @@
 static void tmio_mmc_request(struct mmc_host *mmc, struct mmc_request *mrq)
 {
 	struct tmio_mmc_host *host = mmc_priv(mmc);
+	unsigned long flags;
 	int ret;
 
-	if (host->mrq)
+	spin_lock_irqsave(&host->lock, flags);
+
+	if (host->mrq) {
 		pr_debug("request not null\n");
+		if (IS_ERR(host->mrq)) {
+			spin_unlock_irqrestore(&host->lock, flags);
+			mrq->cmd->error = -EAGAIN;
+			mmc_request_done(mmc, mrq);
+			return;
+		}
+	}
 
 	host->last_req_ts = jiffies;
 	wmb();
 	host->mrq = mrq;
 
+	spin_unlock_irqrestore(&host->lock, flags);
+
 	if (mrq->data) {
 		ret = tmio_mmc_start_data(host, mrq->data);
 		if (ret)
@@ -708,8 +731,8 @@
 	}
 
 fail:
-	host->mrq = NULL;
 	host->force_pio = false;
+	host->mrq = NULL;
 	mrq->cmd->error = ret;
 	mmc_request_done(mmc, mrq);
 }
@@ -723,19 +746,54 @@
 static void tmio_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
 {
 	struct tmio_mmc_host *host = mmc_priv(mmc);
+	struct tmio_mmc_data *pdata = host->pdata;
+	unsigned long flags;
+
+	spin_lock_irqsave(&host->lock, flags);
+	if (host->mrq) {
+		if (IS_ERR(host->mrq)) {
+			dev_dbg(&host->pdev->dev,
+				"%s.%d: concurrent .set_ios(), clk %u, mode %u\n",
+				current->comm, task_pid_nr(current),
+				ios->clock, ios->power_mode);
+			host->mrq = ERR_PTR(-EINTR);
+		} else {
+			dev_dbg(&host->pdev->dev,
+				"%s.%d: CMD%u active since %lu, now %lu!\n",
+				current->comm, task_pid_nr(current),
+				host->mrq->cmd->opcode, host->last_req_ts, jiffies);
+		}
+		spin_unlock_irqrestore(&host->lock, flags);
+		return;
+	}
+
+	host->mrq = ERR_PTR(-EBUSY);
+
+	spin_unlock_irqrestore(&host->lock, flags);
 
 	if (ios->clock)
 		tmio_mmc_set_clock(host, ios->clock);
 
 	/* Power sequence - OFF -> UP -> ON */
 	if (ios->power_mode == MMC_POWER_UP) {
+		if ((pdata->flags & TMIO_MMC_HAS_COLD_CD) && !pdata->power) {
+			pm_runtime_get_sync(&host->pdev->dev);
+			pdata->power = true;
+		}
 		/* power up SD bus */
 		if (host->set_pwr)
 			host->set_pwr(host->pdev, 1);
 	} else if (ios->power_mode == MMC_POWER_OFF || !ios->clock) {
 		/* power down SD bus */
-		if (ios->power_mode == MMC_POWER_OFF && host->set_pwr)
-			host->set_pwr(host->pdev, 0);
+		if (ios->power_mode == MMC_POWER_OFF) {
+			if (host->set_pwr)
+				host->set_pwr(host->pdev, 0);
+			if ((pdata->flags & TMIO_MMC_HAS_COLD_CD) &&
+			    pdata->power) {
+				pdata->power = false;
+				pm_runtime_put(&host->pdev->dev);
+			}
+		}
 		tmio_mmc_clk_stop(host);
 	} else {
 		/* start bus clock */
@@ -753,6 +811,12 @@
 
 	/* Let things settle. delay taken from winCE driver */
 	udelay(140);
+	if (PTR_ERR(host->mrq) == -EINTR)
+		dev_dbg(&host->pdev->dev,
+			"%s.%d: IOS interrupted: clk %u, mode %u",
+			current->comm, task_pid_nr(current),
+			ios->clock, ios->power_mode);
+	host->mrq = NULL;
 }
 
 static int tmio_mmc_get_ro(struct mmc_host *mmc)
@@ -760,8 +824,8 @@
 	struct tmio_mmc_host *host = mmc_priv(mmc);
 	struct tmio_mmc_data *pdata = host->pdata;
 
-	return ((pdata->flags & TMIO_MMC_WRPROTECT_DISABLE) ||
-		!(sd_ctrl_read32(host, CTL_STATUS) & TMIO_STAT_WRPROTECT));
+	return !((pdata->flags & TMIO_MMC_WRPROTECT_DISABLE) ||
+		 (sd_ctrl_read32(host, CTL_STATUS) & TMIO_STAT_WRPROTECT));
 }
 
 static int tmio_mmc_get_cd(struct mmc_host *mmc)
@@ -801,6 +865,7 @@
 	if (!mmc)
 		return -ENOMEM;
 
+	pdata->dev = &pdev->dev;
 	_host = mmc_priv(mmc);
 	_host->pdata = pdata;
 	_host->mmc = mmc;
@@ -834,24 +899,19 @@
 	else
 		mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34;
 
-	tmio_mmc_clk_stop(_host);
-	tmio_mmc_reset(_host);
-
-	ret = platform_get_irq(pdev, 0);
+	pdata->power = false;
+	pm_runtime_enable(&pdev->dev);
+	ret = pm_runtime_resume(&pdev->dev);
 	if (ret < 0)
-		goto unmap_ctl;
+		goto pm_disable;
 
-	_host->irq = ret;
+	tmio_mmc_clk_stop(_host);
+	tmio_mmc_reset(_host);
 
 	tmio_mmc_disable_mmc_irqs(_host, TMIO_MASK_ALL);
 	if (pdata->flags & TMIO_MMC_SDIO_IRQ)
 		tmio_mmc_enable_sdio_irq(mmc, 0);
 
-	ret = request_irq(_host->irq, tmio_mmc_irq, IRQF_DISABLED |
-		IRQF_TRIGGER_FALLING, dev_name(&pdev->dev), _host);
-	if (ret)
-		goto unmap_ctl;
-
 	spin_lock_init(&_host->lock);
 
 	/* Init delayed work for request timeouts */
@@ -860,6 +920,10 @@
 	/* See if we also get DMA */
 	tmio_mmc_request_dma(_host, pdata);
 
+	/* We have to keep the device powered for its card detection to work */
+	if (!(pdata->flags & TMIO_MMC_HAS_COLD_CD))
+		pm_runtime_get_noresume(&pdev->dev);
+
 	mmc_add_host(mmc);
 
 	/* Unmask the IRQs we want to know about */
@@ -874,7 +938,8 @@
 
 	return 0;
 
-unmap_ctl:
+pm_disable:
+	pm_runtime_disable(&pdev->dev);
 	iounmap(_host->ctl);
 host_free:
 	mmc_free_host(mmc);
@@ -885,13 +950,88 @@
 
 void tmio_mmc_host_remove(struct tmio_mmc_host *host)
 {
+	struct platform_device *pdev = host->pdev;
+
+	/*
+	 * We don't have to manipulate pdata->power here: if there is a card in
+	 * the slot, the runtime PM is active and our .runtime_resume() will not
+	 * be run. If there is no card in the slot and the platform can suspend
+	 * the controller, the runtime PM is suspended and pdata->power == false,
+	 * so, our .runtime_resume() will not try to detect a card in the slot.
+	 */
+	if (host->pdata->flags & TMIO_MMC_HAS_COLD_CD)
+		pm_runtime_get_sync(&pdev->dev);
+
 	mmc_remove_host(host->mmc);
 	cancel_delayed_work_sync(&host->delayed_reset_work);
 	tmio_mmc_release_dma(host);
-	free_irq(host->irq, host);
+
+	pm_runtime_put_sync(&pdev->dev);
+	pm_runtime_disable(&pdev->dev);
+
 	iounmap(host->ctl);
 	mmc_free_host(host->mmc);
 }
 EXPORT_SYMBOL(tmio_mmc_host_remove);
 
+#ifdef CONFIG_PM
+int tmio_mmc_host_suspend(struct device *dev)
+{
+	struct mmc_host *mmc = dev_get_drvdata(dev);
+	struct tmio_mmc_host *host = mmc_priv(mmc);
+	int ret = mmc_suspend_host(mmc);
+
+	if (!ret)
+		tmio_mmc_disable_mmc_irqs(host, TMIO_MASK_ALL);
+
+	host->pm_error = pm_runtime_put_sync(dev);
+
+	return ret;
+}
+EXPORT_SYMBOL(tmio_mmc_host_suspend);
+
+int tmio_mmc_host_resume(struct device *dev)
+{
+	struct mmc_host *mmc = dev_get_drvdata(dev);
+	struct tmio_mmc_host *host = mmc_priv(mmc);
+
+	/* The MMC core will perform the complete set up */
+	host->pdata->power = false;
+
+	if (!host->pm_error)
+		pm_runtime_get_sync(dev);
+
+	tmio_mmc_reset(mmc_priv(mmc));
+	tmio_mmc_request_dma(host, host->pdata);
+
+	return mmc_resume_host(mmc);
+}
+EXPORT_SYMBOL(tmio_mmc_host_resume);
+
+#endif	/* CONFIG_PM */
+
+int tmio_mmc_host_runtime_suspend(struct device *dev)
+{
+	return 0;
+}
+EXPORT_SYMBOL(tmio_mmc_host_runtime_suspend);
+
+int tmio_mmc_host_runtime_resume(struct device *dev)
+{
+	struct mmc_host *mmc = dev_get_drvdata(dev);
+	struct tmio_mmc_host *host = mmc_priv(mmc);
+	struct tmio_mmc_data *pdata = host->pdata;
+
+	tmio_mmc_reset(host);
+
+	if (pdata->power) {
+		/* Only entered after a card-insert interrupt */
+		tmio_mmc_set_ios(mmc, &mmc->ios);
+		mmc_detect_change(mmc, msecs_to_jiffies(100));
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL(tmio_mmc_host_runtime_resume);
+
 MODULE_LICENSE("GPL v2");
diff -druN linux-2.6.39-libre/drivers/mmc/host/vub300.c linux-3.0-rc7-libre/drivers/mmc/host/vub300.c
--- linux-2.6.39-libre/drivers/mmc/host/vub300.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/mmc/host/vub300.c	2011-07-21 06:59:29.000000000 -0400
@@ -0,0 +1,2503 @@
+/*
+ * Remote VUB300 SDIO/SDmem Host Controller Driver
+ *
+ * Copyright (C) 2010 Elan Digital Systems Limited
+ *
+ * based on USB Skeleton driver - 2.2
+ *
+ * Copyright (C) 2001-2004 Greg Kroah-Hartman (greg@kroah.com)
+ *
+ * This program is free software; 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
+ *
+ * VUB300: is a USB 2.0 client device with a single SDIO/SDmem/MMC slot
+ *         Any SDIO/SDmem/MMC device plugged into the VUB300 will appear,
+ *         by virtue of this driver, to have been plugged into a local
+ *         SDIO host controller, similar to, say, a PCI Ricoh controller
+ *         This is because this kernel device driver is both a USB 2.0
+ *         client device driver AND an MMC host controller driver. Thus
+ *         if there is an existing driver for the inserted SDIO/SDmem/MMC
+ *         device then that driver will be used by the kernel to manage
+ *         the device in exactly the same fashion as if it had been
+ *         directly plugged into, say, a local pci bus Ricoh controller
+ *
+ * RANT: this driver was written using a display 128x48 - converting it
+ *       to a line width of 80 makes it very difficult to support. In
+ *       particular functions have been broken down into sub functions
+ *       and the original meaningful names have been shortened into
+ *       cryptic ones.
+ *       The problem is that executing a fragment of code subject to
+ *       two conditions means an indentation of 24, thus leaving only
+ *       56 characters for a C statement. And that is quite ridiculous!
+ *
+ * Data types: data passed to/from the VUB300 is fixed to a number of
+ *             bits and driver data fields reflect that limit by using
+ *             u8, u16, u32
+ */
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/kref.h>
+#include <linux/uaccess.h>
+#include <linux/usb.h>
+#include <linux/mutex.h>
+#include <linux/mmc/host.h>
+#include <linux/mmc/card.h>
+#include <linux/mmc/sdio_func.h>
+#include <linux/mmc/sdio_ids.h>
+#include <linux/workqueue.h>
+#include <linux/ctype.h>
+#include <linux/firmware.h>
+#include <linux/scatterlist.h>
+
+struct host_controller_info {
+	u8 info_size;
+	u16 firmware_version;
+	u8 number_of_ports;
+} __packed;
+
+#define FIRMWARE_BLOCK_BOUNDARY 1024
+struct sd_command_header {
+	u8 header_size;
+	u8 header_type;
+	u8 port_number;
+	u8 command_type; /* Bit7 - Rd/Wr */
+	u8 command_index;
+	u8 transfer_size[4]; /* ReadSize + ReadSize */
+	u8 response_type;
+	u8 arguments[4];
+	u8 block_count[2];
+	u8 block_size[2];
+	u8 block_boundary[2];
+	u8 reserved[44]; /* to pad out to 64 bytes */
+} __packed;
+
+struct sd_irqpoll_header {
+	u8 header_size;
+	u8 header_type;
+	u8 port_number;
+	u8 command_type; /* Bit7 - Rd/Wr */
+	u8 padding[16]; /* don't ask why !! */
+	u8 poll_timeout_msb;
+	u8 poll_timeout_lsb;
+	u8 reserved[42]; /* to pad out to 64 bytes */
+} __packed;
+
+struct sd_common_header {
+	u8 header_size;
+	u8 header_type;
+	u8 port_number;
+} __packed;
+
+struct sd_response_header {
+	u8 header_size;
+	u8 header_type;
+	u8 port_number;
+	u8 command_type;
+	u8 command_index;
+	u8 command_response[0];
+} __packed;
+
+struct sd_status_header {
+	u8 header_size;
+	u8 header_type;
+	u8 port_number;
+	u16 port_flags;
+	u32 sdio_clock;
+	u16 host_header_size;
+	u16 func_header_size;
+	u16 ctrl_header_size;
+} __packed;
+
+struct sd_error_header {
+	u8 header_size;
+	u8 header_type;
+	u8 port_number;
+	u8 error_code;
+} __packed;
+
+struct sd_interrupt_header {
+	u8 header_size;
+	u8 header_type;
+	u8 port_number;
+} __packed;
+
+struct offload_registers_access {
+	u8 command_byte[4];
+	u8 Respond_Byte[4];
+} __packed;
+
+#define INTERRUPT_REGISTER_ACCESSES 15
+struct sd_offloaded_interrupt {
+	u8 header_size;
+	u8 header_type;
+	u8 port_number;
+	struct offload_registers_access reg[INTERRUPT_REGISTER_ACCESSES];
+} __packed;
+
+struct sd_register_header {
+	u8 header_size;
+	u8 header_type;
+	u8 port_number;
+	u8 command_type;
+	u8 command_index;
+	u8 command_response[6];
+} __packed;
+
+#define PIGGYBACK_REGISTER_ACCESSES 14
+struct sd_offloaded_piggyback {
+	struct sd_register_header sdio;
+	struct offload_registers_access reg[PIGGYBACK_REGISTER_ACCESSES];
+} __packed;
+
+union sd_response {
+	struct sd_common_header common;
+	struct sd_status_header status;
+	struct sd_error_header error;
+	struct sd_interrupt_header interrupt;
+	struct sd_response_header response;
+	struct sd_offloaded_interrupt irq;
+	struct sd_offloaded_piggyback pig;
+} __packed;
+
+union sd_command {
+	struct sd_command_header head;
+	struct sd_irqpoll_header poll;
+} __packed;
+
+enum SD_RESPONSE_TYPE {
+	SDRT_UNSPECIFIED = 0,
+	SDRT_NONE,
+	SDRT_1,
+	SDRT_1B,
+	SDRT_2,
+	SDRT_3,
+	SDRT_4,
+	SDRT_5,
+	SDRT_5B,
+	SDRT_6,
+	SDRT_7,
+};
+
+#define RESPONSE_INTERRUPT			0x01
+#define RESPONSE_ERROR				0x02
+#define RESPONSE_STATUS				0x03
+#define RESPONSE_IRQ_DISABLED			0x05
+#define RESPONSE_IRQ_ENABLED			0x06
+#define RESPONSE_PIGGYBACKED			0x07
+#define RESPONSE_NO_INTERRUPT			0x08
+#define RESPONSE_PIG_DISABLED			0x09
+#define RESPONSE_PIG_ENABLED			0x0A
+#define SD_ERROR_1BIT_TIMEOUT			0x01
+#define SD_ERROR_4BIT_TIMEOUT			0x02
+#define SD_ERROR_1BIT_CRC_WRONG			0x03
+#define SD_ERROR_4BIT_CRC_WRONG			0x04
+#define SD_ERROR_1BIT_CRC_ERROR			0x05
+#define SD_ERROR_4BIT_CRC_ERROR			0x06
+#define SD_ERROR_NO_CMD_ENDBIT			0x07
+#define SD_ERROR_NO_1BIT_DATEND			0x08
+#define SD_ERROR_NO_4BIT_DATEND			0x09
+#define SD_ERROR_1BIT_UNEXPECTED_TIMEOUT	0x0A
+#define SD_ERROR_4BIT_UNEXPECTED_TIMEOUT	0x0B
+#define SD_ERROR_ILLEGAL_COMMAND		0x0C
+#define SD_ERROR_NO_DEVICE			0x0D
+#define SD_ERROR_TRANSFER_LENGTH		0x0E
+#define SD_ERROR_1BIT_DATA_TIMEOUT		0x0F
+#define SD_ERROR_4BIT_DATA_TIMEOUT		0x10
+#define SD_ERROR_ILLEGAL_STATE			0x11
+#define SD_ERROR_UNKNOWN_ERROR			0x12
+#define SD_ERROR_RESERVED_ERROR			0x13
+#define SD_ERROR_INVALID_FUNCTION		0x14
+#define SD_ERROR_OUT_OF_RANGE			0x15
+#define SD_ERROR_STAT_CMD			0x16
+#define SD_ERROR_STAT_DATA			0x17
+#define SD_ERROR_STAT_CMD_TIMEOUT		0x18
+#define SD_ERROR_SDCRDY_STUCK			0x19
+#define SD_ERROR_UNHANDLED			0x1A
+#define SD_ERROR_OVERRUN			0x1B
+#define SD_ERROR_PIO_TIMEOUT			0x1C
+
+#define FUN(c) (0x000007 & (c->arg>>28))
+#define REG(c) (0x01FFFF & (c->arg>>9))
+
+static int limit_speed_to_24_MHz;
+module_param(limit_speed_to_24_MHz, bool, 0644);
+MODULE_PARM_DESC(limit_speed_to_24_MHz, "Limit Max SDIO Clock Speed to 24 MHz");
+
+static int pad_input_to_usb_pkt;
+module_param(pad_input_to_usb_pkt, bool, 0644);
+MODULE_PARM_DESC(pad_input_to_usb_pkt,
+		 "Pad USB data input transfers to whole USB Packet");
+
+static int disable_offload_processing;
+module_param(disable_offload_processing, bool, 0644);
+MODULE_PARM_DESC(disable_offload_processing, "Disable Offload Processing");
+
+static int force_1_bit_data_xfers;
+module_param(force_1_bit_data_xfers, bool, 0644);
+MODULE_PARM_DESC(force_1_bit_data_xfers,
+		 "Force SDIO Data Transfers to 1-bit Mode");
+
+static int force_polling_for_irqs;
+module_param(force_polling_for_irqs, bool, 0644);
+MODULE_PARM_DESC(force_polling_for_irqs, "Force Polling for SDIO interrupts");
+
+static int firmware_irqpoll_timeout = 1024;
+module_param(firmware_irqpoll_timeout, int, 0644);
+MODULE_PARM_DESC(firmware_irqpoll_timeout, "VUB300 firmware irqpoll timeout");
+
+static int force_max_req_size = 128;
+module_param(force_max_req_size, int, 0644);
+MODULE_PARM_DESC(force_max_req_size, "set max request size in kBytes");
+
+#ifdef SMSC_DEVELOPMENT_BOARD
+static int firmware_rom_wait_states = 0x04;
+#else
+static int firmware_rom_wait_states = 0x1C;
+#endif
+
+module_param(firmware_rom_wait_states, bool, 0644);
+MODULE_PARM_DESC(firmware_rom_wait_states,
+		 "ROM wait states byte=RRRIIEEE (Reserved Internal External)");
+
+#define ELAN_VENDOR_ID		0x2201
+#define VUB300_VENDOR_ID	0x0424
+#define VUB300_PRODUCT_ID	0x012C
+static struct usb_device_id vub300_table[] = {
+	{USB_DEVICE(ELAN_VENDOR_ID, VUB300_PRODUCT_ID)},
+	{USB_DEVICE(VUB300_VENDOR_ID, VUB300_PRODUCT_ID)},
+	{} /* Terminating entry */
+};
+MODULE_DEVICE_TABLE(usb, vub300_table);
+
+static struct workqueue_struct *cmndworkqueue;
+static struct workqueue_struct *pollworkqueue;
+static struct workqueue_struct *deadworkqueue;
+
+static inline int interface_to_InterfaceNumber(struct usb_interface *interface)
+{
+	if (!interface)
+		return -1;
+	if (!interface->cur_altsetting)
+		return -1;
+	return interface->cur_altsetting->desc.bInterfaceNumber;
+}
+
+struct sdio_register {
+	unsigned func_num:3;
+	unsigned sdio_reg:17;
+	unsigned activate:1;
+	unsigned prepared:1;
+	unsigned regvalue:8;
+	unsigned response:8;
+	unsigned sparebit:26;
+};
+
+struct vub300_mmc_host {
+	struct usb_device *udev;
+	struct usb_interface *interface;
+	struct kref kref;
+	struct mutex cmd_mutex;
+	struct mutex irq_mutex;
+	char vub_name[3 + (9 * 8) + 4 + 1]; /* max of 7 sdio fn's */
+	u8 cmnd_out_ep; /* EndPoint for commands */
+	u8 cmnd_res_ep; /* EndPoint for responses */
+	u8 data_out_ep; /* EndPoint for out data */
+	u8 data_inp_ep; /* EndPoint for inp data */
+	bool card_powered;
+	bool card_present;
+	bool read_only;
+	bool large_usb_packets;
+	bool app_spec; /* ApplicationSpecific */
+	bool irq_enabled; /* by the MMC CORE */
+	bool irq_disabled; /* in the firmware */
+	unsigned bus_width:4;
+	u8 total_offload_count;
+	u8 dynamic_register_count;
+	u8 resp_len;
+	u32 datasize;
+	int errors;
+	int usb_transport_fail;
+	int usb_timed_out;
+	int irqs_queued;
+	struct sdio_register sdio_register[16];
+	struct offload_interrupt_function_register {
+#define MAXREGBITS 4
+#define MAXREGS (1<<MAXREGBITS)
+#define MAXREGMASK (MAXREGS-1)
+		u8 offload_count;
+		u32 offload_point;
+		struct offload_registers_access reg[MAXREGS];
+	} fn[8];
+	u16 fbs[8]; /* Function Block Size */
+	struct mmc_command *cmd;
+	struct mmc_request *req;
+	struct mmc_data *data;
+	struct mmc_host *mmc;
+	struct urb *urb;
+	struct urb *command_out_urb;
+	struct urb *command_res_urb;
+	struct completion command_complete;
+	struct completion irqpoll_complete;
+	union sd_command cmnd;
+	union sd_response resp;
+	struct timer_list sg_transfer_timer;
+	struct usb_sg_request sg_request;
+	struct timer_list inactivity_timer;
+	struct work_struct deadwork;
+	struct work_struct cmndwork;
+	struct delayed_work pollwork;
+	struct host_controller_info hc_info;
+	struct sd_status_header system_port_status;
+	u8 padded_buffer[64];
+};
+
+#define kref_to_vub300_mmc_host(d) container_of(d, struct vub300_mmc_host, kref)
+#define SET_TRANSFER_PSEUDOCODE		21
+#define SET_INTERRUPT_PSEUDOCODE	20
+#define SET_FAILURE_MODE		18
+#define SET_ROM_WAIT_STATES		16
+#define SET_IRQ_ENABLE			13
+#define SET_CLOCK_SPEED			11
+#define SET_FUNCTION_BLOCK_SIZE		9
+#define SET_SD_DATA_MODE		6
+#define SET_SD_POWER			4
+#define ENTER_DFU_MODE			3
+#define GET_HC_INF0			1
+#define GET_SYSTEM_PORT_STATUS		0
+
+static void vub300_delete(struct kref *kref)
+{				/* kref callback - softirq */
+	struct vub300_mmc_host *vub300 = kref_to_vub300_mmc_host(kref);
+	struct mmc_host *mmc = vub300->mmc;
+	usb_free_urb(vub300->command_out_urb);
+	vub300->command_out_urb = NULL;
+	usb_free_urb(vub300->command_res_urb);
+	vub300->command_res_urb = NULL;
+	usb_put_dev(vub300->udev);
+	mmc_free_host(mmc);
+	/*
+	 * and hence also frees vub300
+	 * which is contained at the end of struct mmc
+	 */
+}
+
+static void vub300_queue_cmnd_work(struct vub300_mmc_host *vub300)
+{
+	kref_get(&vub300->kref);
+	if (queue_work(cmndworkqueue, &vub300->cmndwork)) {
+		/*
+		 * then the cmndworkqueue was not previously
+		 * running and the above get ref is obvious
+		 * required and will be put when the thread
+		 * terminates by a specific call
+		 */
+	} else {
+		/*
+		 * the cmndworkqueue was already running from
+		 * a previous invocation and thus to keep the
+		 * kref counts correct we must undo the get
+		 */
+		kref_put(&vub300->kref, vub300_delete);
+	}
+}
+
+static void vub300_queue_poll_work(struct vub300_mmc_host *vub300, int delay)
+{
+	kref_get(&vub300->kref);
+	if (queue_delayed_work(pollworkqueue, &vub300->pollwork, delay)) {
+		/*
+		 * then the pollworkqueue was not previously
+		 * running and the above get ref is obvious
+		 * required and will be put when the thread
+		 * terminates by a specific call
+		 */
+	} else {
+		/*
+		 * the pollworkqueue was already running from
+		 * a previous invocation and thus to keep the
+		 * kref counts correct we must undo the get
+		 */
+		kref_put(&vub300->kref, vub300_delete);
+	}
+}
+
+static void vub300_queue_dead_work(struct vub300_mmc_host *vub300)
+{
+	kref_get(&vub300->kref);
+	if (queue_work(deadworkqueue, &vub300->deadwork)) {
+		/*
+		 * then the deadworkqueue was not previously
+		 * running and the above get ref is obvious
+		 * required and will be put when the thread
+		 * terminates by a specific call
+		 */
+	} else {
+		/*
+		 * the deadworkqueue was already running from
+		 * a previous invocation and thus to keep the
+		 * kref counts correct we must undo the get
+		 */
+		kref_put(&vub300->kref, vub300_delete);
+	}
+}
+
+static void irqpoll_res_completed(struct urb *urb)
+{				/* urb completion handler - hardirq */
+	struct vub300_mmc_host *vub300 = (struct vub300_mmc_host *)urb->context;
+	if (urb->status)
+		vub300->usb_transport_fail = urb->status;
+	complete(&vub300->irqpoll_complete);
+}
+
+static void irqpoll_out_completed(struct urb *urb)
+{				/* urb completion handler - hardirq */
+	struct vub300_mmc_host *vub300 = (struct vub300_mmc_host *)urb->context;
+	if (urb->status) {
+		vub300->usb_transport_fail = urb->status;
+		complete(&vub300->irqpoll_complete);
+		return;
+	} else {
+		int ret;
+		unsigned int pipe =
+			usb_rcvbulkpipe(vub300->udev, vub300->cmnd_res_ep);
+		usb_fill_bulk_urb(vub300->command_res_urb, vub300->udev, pipe,
+				  &vub300->resp, sizeof(vub300->resp),
+				  irqpoll_res_completed, vub300);
+		vub300->command_res_urb->actual_length = 0;
+		ret = usb_submit_urb(vub300->command_res_urb, GFP_ATOMIC);
+		if (ret) {
+			vub300->usb_transport_fail = ret;
+			complete(&vub300->irqpoll_complete);
+		}
+		return;
+	}
+}
+
+static void send_irqpoll(struct vub300_mmc_host *vub300)
+{
+	/* cmd_mutex is held by vub300_pollwork_thread */
+	int retval;
+	int timeout = 0xFFFF & (0x0001FFFF - firmware_irqpoll_timeout);
+	vub300->cmnd.poll.header_size = 22;
+	vub300->cmnd.poll.header_type = 1;
+	vub300->cmnd.poll.port_number = 0;
+	vub300->cmnd.poll.command_type = 2;
+	vub300->cmnd.poll.poll_timeout_lsb = 0xFF & (unsigned)timeout;
+	vub300->cmnd.poll.poll_timeout_msb = 0xFF & (unsigned)(timeout >> 8);
+	usb_fill_bulk_urb(vub300->command_out_urb, vub300->udev,
+			  usb_sndbulkpipe(vub300->udev, vub300->cmnd_out_ep)
+			  , &vub300->cmnd, sizeof(vub300->cmnd)
+			  , irqpoll_out_completed, vub300);
+	retval = usb_submit_urb(vub300->command_out_urb, GFP_KERNEL);
+	if (0 > retval) {
+		vub300->usb_transport_fail = retval;
+		vub300_queue_poll_work(vub300, 1);
+		complete(&vub300->irqpoll_complete);
+		return;
+	} else {
+		return;
+	}
+}
+
+static void new_system_port_status(struct vub300_mmc_host *vub300)
+{
+	int old_card_present = vub300->card_present;
+	int new_card_present =
+		(0x0001 & vub300->system_port_status.port_flags) ? 1 : 0;
+	vub300->read_only =
+		(0x0010 & vub300->system_port_status.port_flags) ? 1 : 0;
+	if (new_card_present && !old_card_present) {
+		dev_info(&vub300->udev->dev, "card just inserted\n");
+		vub300->card_present = 1;
+		vub300->bus_width = 0;
+		if (disable_offload_processing)
+			strncpy(vub300->vub_name, "EMPTY Processing Disabled",
+				sizeof(vub300->vub_name));
+		else
+			vub300->vub_name[0] = 0;
+		mmc_detect_change(vub300->mmc, 1);
+	} else if (!new_card_present && old_card_present) {
+		dev_info(&vub300->udev->dev, "card just ejected\n");
+		vub300->card_present = 0;
+		mmc_detect_change(vub300->mmc, 0);
+	} else {
+		/* no change */
+	}
+}
+
+static void __add_offloaded_reg_to_fifo(struct vub300_mmc_host *vub300,
+					struct offload_registers_access
+					*register_access, u8 func)
+{
+	u8 r = vub300->fn[func].offload_point + vub300->fn[func].offload_count;
+	memcpy(&vub300->fn[func].reg[MAXREGMASK & r], register_access,
+	       sizeof(struct offload_registers_access));
+	vub300->fn[func].offload_count += 1;
+	vub300->total_offload_count += 1;
+}
+
+static void add_offloaded_reg(struct vub300_mmc_host *vub300,
+			      struct offload_registers_access *register_access)
+{
+	u32 Register = ((0x03 & register_access->command_byte[0]) << 15)
+			| ((0xFF & register_access->command_byte[1]) << 7)
+			| ((0xFE & register_access->command_byte[2]) >> 1);
+	u8 func = ((0x70 & register_access->command_byte[0]) >> 4);
+	u8 regs = vub300->dynamic_register_count;
+	u8 i = 0;
+	while (0 < regs-- && 1 == vub300->sdio_register[i].activate) {
+		if (vub300->sdio_register[i].func_num == func &&
+		    vub300->sdio_register[i].sdio_reg == Register) {
+			if (vub300->sdio_register[i].prepared == 0)
+				vub300->sdio_register[i].prepared = 1;
+			vub300->sdio_register[i].response =
+				register_access->Respond_Byte[2];
+			vub300->sdio_register[i].regvalue =
+				register_access->Respond_Byte[3];
+			return;
+		} else {
+			i += 1;
+			continue;
+		}
+	};
+	__add_offloaded_reg_to_fifo(vub300, register_access, func);
+}
+
+static void check_vub300_port_status(struct vub300_mmc_host *vub300)
+{
+	/*
+	 * cmd_mutex is held by vub300_pollwork_thread,
+	 * vub300_deadwork_thread or vub300_cmndwork_thread
+	 */
+	int retval;
+	retval =
+		usb_control_msg(vub300->udev, usb_rcvctrlpipe(vub300->udev, 0),
+				GET_SYSTEM_PORT_STATUS,
+				USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+				0x0000, 0x0000, &vub300->system_port_status,
+				sizeof(vub300->system_port_status), HZ);
+	if (sizeof(vub300->system_port_status) == retval)
+		new_system_port_status(vub300);
+}
+
+static void __vub300_irqpoll_response(struct vub300_mmc_host *vub300)
+{
+	/* cmd_mutex is held by vub300_pollwork_thread */
+	if (vub300->command_res_urb->actual_length == 0)
+		return;
+
+	switch (vub300->resp.common.header_type) {
+	case RESPONSE_INTERRUPT:
+		mutex_lock(&vub300->irq_mutex);
+		if (vub300->irq_enabled)
+			mmc_signal_sdio_irq(vub300->mmc);
+		else
+			vub300->irqs_queued += 1;
+		vub300->irq_disabled = 1;
+		mutex_unlock(&vub300->irq_mutex);
+		break;
+	case RESPONSE_ERROR:
+		if (vub300->resp.error.error_code == SD_ERROR_NO_DEVICE)
+			check_vub300_port_status(vub300);
+		break;
+	case RESPONSE_STATUS:
+		vub300->system_port_status = vub300->resp.status;
+		new_system_port_status(vub300);
+		if (!vub300->card_present)
+			vub300_queue_poll_work(vub300, HZ / 5);
+		break;
+	case RESPONSE_IRQ_DISABLED:
+	{
+		int offloaded_data_length = vub300->resp.common.header_size - 3;
+		int register_count = offloaded_data_length >> 3;
+		int ri = 0;
+		while (register_count--) {
+			add_offloaded_reg(vub300, &vub300->resp.irq.reg[ri]);
+			ri += 1;
+		}
+		mutex_lock(&vub300->irq_mutex);
+		if (vub300->irq_enabled)
+			mmc_signal_sdio_irq(vub300->mmc);
+		else
+			vub300->irqs_queued += 1;
+		vub300->irq_disabled = 1;
+		mutex_unlock(&vub300->irq_mutex);
+		break;
+	}
+	case RESPONSE_IRQ_ENABLED:
+	{
+		int offloaded_data_length = vub300->resp.common.header_size - 3;
+		int register_count = offloaded_data_length >> 3;
+		int ri = 0;
+		while (register_count--) {
+			add_offloaded_reg(vub300, &vub300->resp.irq.reg[ri]);
+			ri += 1;
+		}
+		mutex_lock(&vub300->irq_mutex);
+		if (vub300->irq_enabled)
+			mmc_signal_sdio_irq(vub300->mmc);
+		else if (vub300->irqs_queued)
+			vub300->irqs_queued += 1;
+		else
+			vub300->irqs_queued += 1;
+		vub300->irq_disabled = 0;
+		mutex_unlock(&vub300->irq_mutex);
+		break;
+	}
+	case RESPONSE_NO_INTERRUPT:
+		vub300_queue_poll_work(vub300, 1);
+		break;
+	default:
+		break;
+	}
+}
+
+static void __do_poll(struct vub300_mmc_host *vub300)
+{
+	/* cmd_mutex is held by vub300_pollwork_thread */
+	long commretval;
+	mod_timer(&vub300->inactivity_timer, jiffies + HZ);
+	init_completion(&vub300->irqpoll_complete);
+	send_irqpoll(vub300);
+	commretval = wait_for_completion_timeout(&vub300->irqpoll_complete,
+						 msecs_to_jiffies(500));
+	if (vub300->usb_transport_fail) {
+		/* no need to do anything */
+	} else if (commretval == 0) {
+		vub300->usb_timed_out = 1;
+		usb_kill_urb(vub300->command_out_urb);
+		usb_kill_urb(vub300->command_res_urb);
+	} else if (commretval < 0) {
+		vub300_queue_poll_work(vub300, 1);
+	} else { /* commretval > 0 */
+		__vub300_irqpoll_response(vub300);
+	}
+}
+
+/* this thread runs only when the driver
+ * is trying to poll the device for an IRQ
+ */
+static void vub300_pollwork_thread(struct work_struct *work)
+{				/* NOT irq */
+	struct vub300_mmc_host *vub300 = container_of(work,
+			      struct vub300_mmc_host, pollwork.work);
+	if (!vub300->interface) {
+		kref_put(&vub300->kref, vub300_delete);
+		return;
+	}
+	mutex_lock(&vub300->cmd_mutex);
+	if (vub300->cmd) {
+		vub300_queue_poll_work(vub300, 1);
+	} else if (!vub300->card_present) {
+		/* no need to do anything */
+	} else { /* vub300->card_present */
+		mutex_lock(&vub300->irq_mutex);
+		if (!vub300->irq_enabled) {
+			mutex_unlock(&vub300->irq_mutex);
+		} else if (vub300->irqs_queued) {
+			vub300->irqs_queued -= 1;
+			mmc_signal_sdio_irq(vub300->mmc);
+			mod_timer(&vub300->inactivity_timer, jiffies + HZ);
+			mutex_unlock(&vub300->irq_mutex);
+		} else { /* NOT vub300->irqs_queued */
+			mutex_unlock(&vub300->irq_mutex);
+			__do_poll(vub300);
+		}
+	}
+	mutex_unlock(&vub300->cmd_mutex);
+	kref_put(&vub300->kref, vub300_delete);
+}
+
+static void vub300_deadwork_thread(struct work_struct *work)
+{				/* NOT irq */
+	struct vub300_mmc_host *vub300 =
+		container_of(work, struct vub300_mmc_host, deadwork);
+	if (!vub300->interface) {
+		kref_put(&vub300->kref, vub300_delete);
+		return;
+	}
+	mutex_lock(&vub300->cmd_mutex);
+	if (vub300->cmd) {
+		/*
+		 * a command got in as the inactivity
+		 * timer expired - so we just let the
+		 * processing of the command show if
+		 * the device is dead
+		 */
+	} else if (vub300->card_present) {
+		check_vub300_port_status(vub300);
+	} else if (vub300->mmc && vub300->mmc->card &&
+		   mmc_card_present(vub300->mmc->card)) {
+		/*
+		 * the MMC core must not have responded
+		 * to the previous indication - lets
+		 * hope that it eventually does so we
+		 * will just ignore this for now
+		 */
+	} else {
+		check_vub300_port_status(vub300);
+	}
+	mod_timer(&vub300->inactivity_timer, jiffies + HZ);
+	mutex_unlock(&vub300->cmd_mutex);
+	kref_put(&vub300->kref, vub300_delete);
+}
+
+static void vub300_inactivity_timer_expired(unsigned long data)
+{				/* softirq */
+	struct vub300_mmc_host *vub300 = (struct vub300_mmc_host *)data;
+	if (!vub300->interface) {
+		kref_put(&vub300->kref, vub300_delete);
+	} else if (vub300->cmd) {
+		mod_timer(&vub300->inactivity_timer, jiffies + HZ);
+	} else {
+		vub300_queue_dead_work(vub300);
+		mod_timer(&vub300->inactivity_timer, jiffies + HZ);
+	}
+}
+
+static int vub300_response_error(u8 error_code)
+{
+	switch (error_code) {
+	case SD_ERROR_PIO_TIMEOUT:
+	case SD_ERROR_1BIT_TIMEOUT:
+	case SD_ERROR_4BIT_TIMEOUT:
+		return -ETIMEDOUT;
+	case SD_ERROR_STAT_DATA:
+	case SD_ERROR_OVERRUN:
+	case SD_ERROR_STAT_CMD:
+	case SD_ERROR_STAT_CMD_TIMEOUT:
+	case SD_ERROR_SDCRDY_STUCK:
+	case SD_ERROR_UNHANDLED:
+	case SD_ERROR_1BIT_CRC_WRONG:
+	case SD_ERROR_4BIT_CRC_WRONG:
+	case SD_ERROR_1BIT_CRC_ERROR:
+	case SD_ERROR_4BIT_CRC_ERROR:
+	case SD_ERROR_NO_CMD_ENDBIT:
+	case SD_ERROR_NO_1BIT_DATEND:
+	case SD_ERROR_NO_4BIT_DATEND:
+	case SD_ERROR_1BIT_DATA_TIMEOUT:
+	case SD_ERROR_4BIT_DATA_TIMEOUT:
+	case SD_ERROR_1BIT_UNEXPECTED_TIMEOUT:
+	case SD_ERROR_4BIT_UNEXPECTED_TIMEOUT:
+		return -EILSEQ;
+	case 33:
+		return -EILSEQ;
+	case SD_ERROR_ILLEGAL_COMMAND:
+		return -EINVAL;
+	case SD_ERROR_NO_DEVICE:
+		return -ENOMEDIUM;
+	default:
+		return -ENODEV;
+	}
+}
+
+static void command_res_completed(struct urb *urb)
+{				/* urb completion handler - hardirq */
+	struct vub300_mmc_host *vub300 = (struct vub300_mmc_host *)urb->context;
+	if (urb->status) {
+		/* we have to let the initiator handle the error */
+	} else if (vub300->command_res_urb->actual_length == 0) {
+		/*
+		 * we have seen this happen once or twice and
+		 * we suspect a buggy USB host controller
+		 */
+	} else if (!vub300->data) {
+		/* this means that the command (typically CMD52) suceeded */
+	} else if (vub300->resp.common.header_type != 0x02) {
+		/*
+		 * this is an error response from the VUB300 chip
+		 * and we let the initiator handle it
+		 */
+	} else if (vub300->urb) {
+		vub300->cmd->error =
+			vub300_response_error(vub300->resp.error.error_code);
+		usb_unlink_urb(vub300->urb);
+	} else {
+		vub300->cmd->error =
+			vub300_response_error(vub300->resp.error.error_code);
+		usb_sg_cancel(&vub300->sg_request);
+	}
+	complete(&vub300->command_complete);	/* got_response_in */
+}
+
+static void command_out_completed(struct urb *urb)
+{				/* urb completion handler - hardirq */
+	struct vub300_mmc_host *vub300 = (struct vub300_mmc_host *)urb->context;
+	if (urb->status) {
+		complete(&vub300->command_complete);
+	} else {
+		int ret;
+		unsigned int pipe =
+			usb_rcvbulkpipe(vub300->udev, vub300->cmnd_res_ep);
+		usb_fill_bulk_urb(vub300->command_res_urb, vub300->udev, pipe,
+				  &vub300->resp, sizeof(vub300->resp),
+				  command_res_completed, vub300);
+		vub300->command_res_urb->actual_length = 0;
+		ret = usb_submit_urb(vub300->command_res_urb, GFP_ATOMIC);
+		if (ret == 0) {
+			/*
+			 * the urb completion handler will call
+			 * our completion handler
+			 */
+		} else {
+			/*
+			 * and thus we only call it directly
+			 * when it will not be called
+			 */
+			complete(&vub300->command_complete);
+		}
+	}
+}
+
+/*
+ * the STUFF bits are masked out for the comparisons
+ */
+static void snoop_block_size_and_bus_width(struct vub300_mmc_host *vub300,
+					   u32 cmd_arg)
+{
+	if ((0xFBFFFE00 & cmd_arg) == 0x80022200)
+		vub300->fbs[1] = (cmd_arg << 8) | (0x00FF & vub300->fbs[1]);
+	else if ((0xFBFFFE00 & cmd_arg) == 0x80022000)
+		vub300->fbs[1] = (0xFF & cmd_arg) | (0xFF00 & vub300->fbs[1]);
+	else if ((0xFBFFFE00 & cmd_arg) == 0x80042200)
+		vub300->fbs[2] = (cmd_arg << 8) | (0x00FF & vub300->fbs[2]);
+	else if ((0xFBFFFE00 & cmd_arg) == 0x80042000)
+		vub300->fbs[2] = (0xFF & cmd_arg) | (0xFF00 & vub300->fbs[2]);
+	else if ((0xFBFFFE00 & cmd_arg) == 0x80062200)
+		vub300->fbs[3] = (cmd_arg << 8) | (0x00FF & vub300->fbs[3]);
+	else if ((0xFBFFFE00 & cmd_arg) == 0x80062000)
+		vub300->fbs[3] = (0xFF & cmd_arg) | (0xFF00 & vub300->fbs[3]);
+	else if ((0xFBFFFE00 & cmd_arg) == 0x80082200)
+		vub300->fbs[4] = (cmd_arg << 8) | (0x00FF & vub300->fbs[4]);
+	else if ((0xFBFFFE00 & cmd_arg) == 0x80082000)
+		vub300->fbs[4] = (0xFF & cmd_arg) | (0xFF00 & vub300->fbs[4]);
+	else if ((0xFBFFFE00 & cmd_arg) == 0x800A2200)
+		vub300->fbs[5] = (cmd_arg << 8) | (0x00FF & vub300->fbs[5]);
+	else if ((0xFBFFFE00 & cmd_arg) == 0x800A2000)
+		vub300->fbs[5] = (0xFF & cmd_arg) | (0xFF00 & vub300->fbs[5]);
+	else if ((0xFBFFFE00 & cmd_arg) == 0x800C2200)
+		vub300->fbs[6] = (cmd_arg << 8) | (0x00FF & vub300->fbs[6]);
+	else if ((0xFBFFFE00 & cmd_arg) == 0x800C2000)
+		vub300->fbs[6] = (0xFF & cmd_arg) | (0xFF00 & vub300->fbs[6]);
+	else if ((0xFBFFFE00 & cmd_arg) == 0x800E2200)
+		vub300->fbs[7] = (cmd_arg << 8) | (0x00FF & vub300->fbs[7]);
+	else if ((0xFBFFFE00 & cmd_arg) == 0x800E2000)
+		vub300->fbs[7] = (0xFF & cmd_arg) | (0xFF00 & vub300->fbs[7]);
+	else if ((0xFBFFFE03 & cmd_arg) == 0x80000E00)
+		vub300->bus_width = 1;
+	else if ((0xFBFFFE03 & cmd_arg) == 0x80000E02)
+		vub300->bus_width = 4;
+}
+
+static void send_command(struct vub300_mmc_host *vub300)
+{
+	/* cmd_mutex is held by vub300_cmndwork_thread */
+	struct mmc_command *cmd = vub300->cmd;
+	struct mmc_data *data = vub300->data;
+	int retval;
+	int i;
+	u8 response_type;
+	if (vub300->app_spec) {
+		switch (cmd->opcode) {
+		case 6:
+			response_type = SDRT_1;
+			vub300->resp_len = 6;
+			if (0x00000000 == (0x00000003 & cmd->arg))
+				vub300->bus_width = 1;
+			else if (0x00000002 == (0x00000003 & cmd->arg))
+				vub300->bus_width = 4;
+			else
+				dev_err(&vub300->udev->dev,
+					"unexpected ACMD6 bus_width=%d\n",
+					0x00000003 & cmd->arg);
+			break;
+		case 13:
+			response_type = SDRT_1;
+			vub300->resp_len = 6;
+			break;
+		case 22:
+			response_type = SDRT_1;
+			vub300->resp_len = 6;
+			break;
+		case 23:
+			response_type = SDRT_1;
+			vub300->resp_len = 6;
+			break;
+		case 41:
+			response_type = SDRT_3;
+			vub300->resp_len = 6;
+			break;
+		case 42:
+			response_type = SDRT_1;
+			vub300->resp_len = 6;
+			break;
+		case 51:
+			response_type = SDRT_1;
+			vub300->resp_len = 6;
+			break;
+		case 55:
+			response_type = SDRT_1;
+			vub300->resp_len = 6;
+			break;
+		default:
+			vub300->resp_len = 0;
+			cmd->error = -EINVAL;
+			complete(&vub300->command_complete);
+			return;
+		}
+		vub300->app_spec = 0;
+	} else {
+		switch (cmd->opcode) {
+		case 0:
+			response_type = SDRT_NONE;
+			vub300->resp_len = 0;
+			break;
+		case 1:
+			response_type = SDRT_3;
+			vub300->resp_len = 6;
+			break;
+		case 2:
+			response_type = SDRT_2;
+			vub300->resp_len = 17;
+			break;
+		case 3:
+			response_type = SDRT_6;
+			vub300->resp_len = 6;
+			break;
+		case 4:
+			response_type = SDRT_NONE;
+			vub300->resp_len = 0;
+			break;
+		case 5:
+			response_type = SDRT_4;
+			vub300->resp_len = 6;
+			break;
+		case 6:
+			response_type = SDRT_1;
+			vub300->resp_len = 6;
+			break;
+		case 7:
+			response_type = SDRT_1B;
+			vub300->resp_len = 6;
+			break;
+		case 8:
+			response_type = SDRT_7;
+			vub300->resp_len = 6;
+			break;
+		case 9:
+			response_type = SDRT_2;
+			vub300->resp_len = 17;
+			break;
+		case 10:
+			response_type = SDRT_2;
+			vub300->resp_len = 17;
+			break;
+		case 12:
+			response_type = SDRT_1B;
+			vub300->resp_len = 6;
+			break;
+		case 13:
+			response_type = SDRT_1;
+			vub300->resp_len = 6;
+			break;
+		case 15:
+			response_type = SDRT_NONE;
+			vub300->resp_len = 0;
+			break;
+		case 16:
+			for (i = 0; i < ARRAY_SIZE(vub300->fbs); i++)
+				vub300->fbs[i] = 0xFFFF & cmd->arg;
+			response_type = SDRT_1;
+			vub300->resp_len = 6;
+			break;
+		case 17:
+		case 18:
+		case 24:
+		case 25:
+		case 27:
+			response_type = SDRT_1;
+			vub300->resp_len = 6;
+			break;
+		case 28:
+		case 29:
+			response_type = SDRT_1B;
+			vub300->resp_len = 6;
+			break;
+		case 30:
+		case 32:
+		case 33:
+			response_type = SDRT_1;
+			vub300->resp_len = 6;
+			break;
+		case 38:
+			response_type = SDRT_1B;
+			vub300->resp_len = 6;
+			break;
+		case 42:
+			response_type = SDRT_1;
+			vub300->resp_len = 6;
+			break;
+		case 52:
+			response_type = SDRT_5;
+			vub300->resp_len = 6;
+			snoop_block_size_and_bus_width(vub300, cmd->arg);
+			break;
+		case 53:
+			response_type = SDRT_5;
+			vub300->resp_len = 6;
+			break;
+		case 55:
+			response_type = SDRT_1;
+			vub300->resp_len = 6;
+			vub300->app_spec = 1;
+			break;
+		case 56:
+			response_type = SDRT_1;
+			vub300->resp_len = 6;
+			break;
+		default:
+			vub300->resp_len = 0;
+			cmd->error = -EINVAL;
+			complete(&vub300->command_complete);
+			return;
+		}
+	}
+	/*
+	 * it is a shame that we can not use "sizeof(struct sd_command_header)"
+	 * this is because the packet _must_ be padded to 64 bytes
+	 */
+	vub300->cmnd.head.header_size = 20;
+	vub300->cmnd.head.header_type = 0x00;
+	vub300->cmnd.head.port_number = 0; /* "0" means port 1 */
+	vub300->cmnd.head.command_type = 0x00; /* standard read command */
+	vub300->cmnd.head.response_type = response_type;
+	vub300->cmnd.head.command_index = cmd->opcode;
+	vub300->cmnd.head.arguments[0] = cmd->arg >> 24;
+	vub300->cmnd.head.arguments[1] = cmd->arg >> 16;
+	vub300->cmnd.head.arguments[2] = cmd->arg >> 8;
+	vub300->cmnd.head.arguments[3] = cmd->arg >> 0;
+	if (cmd->opcode == 52) {
+		int fn = 0x7 & (cmd->arg >> 28);
+		vub300->cmnd.head.block_count[0] = 0;
+		vub300->cmnd.head.block_count[1] = 0;
+		vub300->cmnd.head.block_size[0] = (vub300->fbs[fn] >> 8) & 0xFF;
+		vub300->cmnd.head.block_size[1] = (vub300->fbs[fn] >> 0) & 0xFF;
+		vub300->cmnd.head.command_type = 0x00;
+		vub300->cmnd.head.transfer_size[0] = 0;
+		vub300->cmnd.head.transfer_size[1] = 0;
+		vub300->cmnd.head.transfer_size[2] = 0;
+		vub300->cmnd.head.transfer_size[3] = 0;
+	} else if (!data) {
+		vub300->cmnd.head.block_count[0] = 0;
+		vub300->cmnd.head.block_count[1] = 0;
+		vub300->cmnd.head.block_size[0] = (vub300->fbs[0] >> 8) & 0xFF;
+		vub300->cmnd.head.block_size[1] = (vub300->fbs[0] >> 0) & 0xFF;
+		vub300->cmnd.head.command_type = 0x00;
+		vub300->cmnd.head.transfer_size[0] = 0;
+		vub300->cmnd.head.transfer_size[1] = 0;
+		vub300->cmnd.head.transfer_size[2] = 0;
+		vub300->cmnd.head.transfer_size[3] = 0;
+	} else if (cmd->opcode == 53) {
+		int fn = 0x7 & (cmd->arg >> 28);
+		if (0x08 & vub300->cmnd.head.arguments[0]) { /* BLOCK MODE */
+			vub300->cmnd.head.block_count[0] =
+				(data->blocks >> 8) & 0xFF;
+			vub300->cmnd.head.block_count[1] =
+				(data->blocks >> 0) & 0xFF;
+			vub300->cmnd.head.block_size[0] =
+				(data->blksz >> 8) & 0xFF;
+			vub300->cmnd.head.block_size[1] =
+				(data->blksz >> 0) & 0xFF;
+		} else {	/* BYTE MODE */
+			vub300->cmnd.head.block_count[0] = 0;
+			vub300->cmnd.head.block_count[1] = 0;
+			vub300->cmnd.head.block_size[0] =
+				(vub300->datasize >> 8) & 0xFF;
+			vub300->cmnd.head.block_size[1] =
+				(vub300->datasize >> 0) & 0xFF;
+		}
+		vub300->cmnd.head.command_type =
+			(MMC_DATA_READ & data->flags) ? 0x00 : 0x80;
+		vub300->cmnd.head.transfer_size[0] =
+			(vub300->datasize >> 24) & 0xFF;
+		vub300->cmnd.head.transfer_size[1] =
+			(vub300->datasize >> 16) & 0xFF;
+		vub300->cmnd.head.transfer_size[2] =
+			(vub300->datasize >> 8) & 0xFF;
+		vub300->cmnd.head.transfer_size[3] =
+			(vub300->datasize >> 0) & 0xFF;
+		if (vub300->datasize < vub300->fbs[fn]) {
+			vub300->cmnd.head.block_count[0] = 0;
+			vub300->cmnd.head.block_count[1] = 0;
+		}
+	} else {
+		vub300->cmnd.head.block_count[0] = (data->blocks >> 8) & 0xFF;
+		vub300->cmnd.head.block_count[1] = (data->blocks >> 0) & 0xFF;
+		vub300->cmnd.head.block_size[0] = (data->blksz >> 8) & 0xFF;
+		vub300->cmnd.head.block_size[1] = (data->blksz >> 0) & 0xFF;
+		vub300->cmnd.head.command_type =
+			(MMC_DATA_READ & data->flags) ? 0x00 : 0x80;
+		vub300->cmnd.head.transfer_size[0] =
+			(vub300->datasize >> 24) & 0xFF;
+		vub300->cmnd.head.transfer_size[1] =
+			(vub300->datasize >> 16) & 0xFF;
+		vub300->cmnd.head.transfer_size[2] =
+			(vub300->datasize >> 8) & 0xFF;
+		vub300->cmnd.head.transfer_size[3] =
+			(vub300->datasize >> 0) & 0xFF;
+		if (vub300->datasize < vub300->fbs[0]) {
+			vub300->cmnd.head.block_count[0] = 0;
+			vub300->cmnd.head.block_count[1] = 0;
+		}
+	}
+	if (vub300->cmnd.head.block_size[0] || vub300->cmnd.head.block_size[1]) {
+		u16 block_size = vub300->cmnd.head.block_size[1] |
+			(vub300->cmnd.head.block_size[0] << 8);
+		u16 block_boundary = FIRMWARE_BLOCK_BOUNDARY -
+			(FIRMWARE_BLOCK_BOUNDARY % block_size);
+		vub300->cmnd.head.block_boundary[0] =
+			(block_boundary >> 8) & 0xFF;
+		vub300->cmnd.head.block_boundary[1] =
+			(block_boundary >> 0) & 0xFF;
+	} else {
+		vub300->cmnd.head.block_boundary[0] = 0;
+		vub300->cmnd.head.block_boundary[1] = 0;
+	}
+	usb_fill_bulk_urb(vub300->command_out_urb, vub300->udev,
+			  usb_sndbulkpipe(vub300->udev, vub300->cmnd_out_ep),
+			  &vub300->cmnd, sizeof(vub300->cmnd),
+			  command_out_completed, vub300);
+	retval = usb_submit_urb(vub300->command_out_urb, GFP_KERNEL);
+	if (retval < 0) {
+		cmd->error = retval;
+		complete(&vub300->command_complete);
+		return;
+	} else {
+		return;
+	}
+}
+
+/*
+ * timer callback runs in atomic mode
+ *       so it cannot call usb_kill_urb()
+ */
+static void vub300_sg_timed_out(unsigned long data)
+{
+	struct vub300_mmc_host *vub300 = (struct vub300_mmc_host *)data;
+	vub300->usb_timed_out = 1;
+	usb_sg_cancel(&vub300->sg_request);
+	usb_unlink_urb(vub300->command_out_urb);
+	usb_unlink_urb(vub300->command_res_urb);
+}
+
+static u16 roundup_to_multiple_of_64(u16 number)
+{
+	return 0xFFC0 & (0x3F + number);
+}
+
+/*
+ * this is a separate function to solve the 80 column width restriction
+ */
+static void __download_offload_pseudocode(struct vub300_mmc_host *vub300,
+					  const struct firmware *fw)
+{
+	u8 register_count = 0;
+	u16 ts = 0;
+	u16 interrupt_size = 0;
+	const u8 *data = fw->data;
+	int size = fw->size;
+	u8 c;
+	dev_info(&vub300->udev->dev, "using %s for SDIO offload processing\n",
+		 vub300->vub_name);
+	do {
+		c = *data++;
+	} while (size-- && c); /* skip comment */
+	dev_info(&vub300->udev->dev, "using offload firmware %s %s\n", fw->data,
+		 vub300->vub_name);
+	if (size < 4) {
+		dev_err(&vub300->udev->dev,
+			"corrupt offload pseudocode in firmware %s\n",
+			vub300->vub_name);
+		strncpy(vub300->vub_name, "corrupt offload pseudocode",
+			sizeof(vub300->vub_name));
+		return;
+	}
+	interrupt_size += *data++;
+	size -= 1;
+	interrupt_size <<= 8;
+	interrupt_size += *data++;
+	size -= 1;
+	if (interrupt_size < size) {
+		u16 xfer_length = roundup_to_multiple_of_64(interrupt_size);
+		u8 *xfer_buffer = kmalloc(xfer_length, GFP_KERNEL);
+		if (xfer_buffer) {
+			int retval;
+			memcpy(xfer_buffer, data, interrupt_size);
+			memset(xfer_buffer + interrupt_size, 0,
+			       xfer_length - interrupt_size);
+			size -= interrupt_size;
+			data += interrupt_size;
+			retval =
+				usb_control_msg(vub300->udev,
+						usb_sndctrlpipe(vub300->udev, 0),
+						SET_INTERRUPT_PSEUDOCODE,
+						USB_DIR_OUT | USB_TYPE_VENDOR |
+						USB_RECIP_DEVICE, 0x0000, 0x0000,
+						xfer_buffer, xfer_length, HZ);
+			kfree(xfer_buffer);
+			if (retval < 0) {
+				strncpy(vub300->vub_name,
+					"SDIO pseudocode download failed",
+					sizeof(vub300->vub_name));
+				return;
+			}
+		} else {
+			dev_err(&vub300->udev->dev,
+				"not enough memory for xfer buffer to send"
+				" INTERRUPT_PSEUDOCODE for %s %s\n", fw->data,
+				vub300->vub_name);
+			strncpy(vub300->vub_name,
+				"SDIO interrupt pseudocode download failed",
+				sizeof(vub300->vub_name));
+			return;
+		}
+	} else {
+		dev_err(&vub300->udev->dev,
+			"corrupt interrupt pseudocode in firmware %s %s\n",
+			fw->data, vub300->vub_name);
+		strncpy(vub300->vub_name, "corrupt interrupt pseudocode",
+			sizeof(vub300->vub_name));
+		return;
+	}
+	ts += *data++;
+	size -= 1;
+	ts <<= 8;
+	ts += *data++;
+	size -= 1;
+	if (ts < size) {
+		u16 xfer_length = roundup_to_multiple_of_64(ts);
+		u8 *xfer_buffer = kmalloc(xfer_length, GFP_KERNEL);
+		if (xfer_buffer) {
+			int retval;
+			memcpy(xfer_buffer, data, ts);
+			memset(xfer_buffer + ts, 0,
+			       xfer_length - ts);
+			size -= ts;
+			data += ts;
+			retval =
+				usb_control_msg(vub300->udev,
+						usb_sndctrlpipe(vub300->udev, 0),
+						SET_TRANSFER_PSEUDOCODE,
+						USB_DIR_OUT | USB_TYPE_VENDOR |
+						USB_RECIP_DEVICE, 0x0000, 0x0000,
+						xfer_buffer, xfer_length, HZ);
+			kfree(xfer_buffer);
+			if (retval < 0) {
+				strncpy(vub300->vub_name,
+					"SDIO pseudocode download failed",
+					sizeof(vub300->vub_name));
+				return;
+			}
+		} else {
+			dev_err(&vub300->udev->dev,
+				"not enough memory for xfer buffer to send"
+				" TRANSFER_PSEUDOCODE for %s %s\n", fw->data,
+				vub300->vub_name);
+			strncpy(vub300->vub_name,
+				"SDIO transfer pseudocode download failed",
+				sizeof(vub300->vub_name));
+			return;
+		}
+	} else {
+		dev_err(&vub300->udev->dev,
+			"corrupt transfer pseudocode in firmware %s %s\n",
+			fw->data, vub300->vub_name);
+		strncpy(vub300->vub_name, "corrupt transfer pseudocode",
+			sizeof(vub300->vub_name));
+		return;
+	}
+	register_count += *data++;
+	size -= 1;
+	if (register_count * 4 == size) {
+		int I = vub300->dynamic_register_count = register_count;
+		int i = 0;
+		while (I--) {
+			unsigned int func_num = 0;
+			vub300->sdio_register[i].func_num = *data++;
+			size -= 1;
+			func_num += *data++;
+			size -= 1;
+			func_num <<= 8;
+			func_num += *data++;
+			size -= 1;
+			func_num <<= 8;
+			func_num += *data++;
+			size -= 1;
+			vub300->sdio_register[i].sdio_reg = func_num;
+			vub300->sdio_register[i].activate = 1;
+			vub300->sdio_register[i].prepared = 0;
+			i += 1;
+		}
+		dev_info(&vub300->udev->dev,
+			 "initialized %d dynamic pseudocode registers\n",
+			 vub300->dynamic_register_count);
+		return;
+	} else {
+		dev_err(&vub300->udev->dev,
+			"corrupt dynamic registers in firmware %s\n",
+			vub300->vub_name);
+		strncpy(vub300->vub_name, "corrupt dynamic registers",
+			sizeof(vub300->vub_name));
+		return;
+	}
+}
+
+/*
+ * if the binary containing the EMPTY PseudoCode can not be found
+ * vub300->vub_name is set anyway in order to prevent an automatic retry
+ */
+static void download_offload_pseudocode(struct vub300_mmc_host *vub300)
+{
+	struct mmc_card *card = vub300->mmc->card;
+	int sdio_funcs = card->sdio_funcs;
+	const struct firmware *fw = NULL;
+	int l = snprintf(vub300->vub_name, sizeof(vub300->vub_name),
+			 "/*(DEBLOBBED)*/", card->cis.vendor, card->cis.device);
+	int n = 0;
+	int retval;
+	for (n = 0; n < sdio_funcs; n++) {
+		struct sdio_func *sf = card->sdio_func[n];
+		l += snprintf(vub300->vub_name + l,
+			      sizeof(vub300->vub_name) - l, "_%04X%04X",
+			      sf->vendor, sf->device);
+	};
+	/*(DEBLOBBED)*/
+	dev_info(&vub300->udev->dev, "requesting offload firmware %s\n",
+		 vub300->vub_name);
+	retval = reject_firmware(&fw, vub300->vub_name, &card->dev);
+	if (retval < 0) {
+		strncpy(vub300->vub_name, "/*(DEBLOBBED)*/",
+			sizeof(vub300->vub_name));
+		retval = reject_firmware(&fw, vub300->vub_name, &card->dev);
+		if (retval < 0) {
+			strncpy(vub300->vub_name,
+				"no SDIO offload firmware found",
+				sizeof(vub300->vub_name));
+		} else {
+			__download_offload_pseudocode(vub300, fw);
+			release_firmware(fw);
+		}
+	} else {
+		__download_offload_pseudocode(vub300, fw);
+		release_firmware(fw);
+	}
+}
+
+static void vub300_usb_bulk_msg_completion(struct urb *urb)
+{				/* urb completion handler - hardirq */
+	complete((struct completion *)urb->context);
+}
+
+static int vub300_usb_bulk_msg(struct vub300_mmc_host *vub300,
+			       unsigned int pipe, void *data, int len,
+			       int *actual_length, int timeout_msecs)
+{
+	/* cmd_mutex is held by vub300_cmndwork_thread */
+	struct usb_device *usb_dev = vub300->udev;
+	struct completion done;
+	int retval;
+	vub300->urb = usb_alloc_urb(0, GFP_KERNEL);
+	if (!vub300->urb)
+		return -ENOMEM;
+	usb_fill_bulk_urb(vub300->urb, usb_dev, pipe, data, len,
+			  vub300_usb_bulk_msg_completion, NULL);
+	init_completion(&done);
+	vub300->urb->context = &done;
+	vub300->urb->actual_length = 0;
+	retval = usb_submit_urb(vub300->urb, GFP_KERNEL);
+	if (unlikely(retval))
+		goto out;
+	if (!wait_for_completion_timeout
+	    (&done, msecs_to_jiffies(timeout_msecs))) {
+		retval = -ETIMEDOUT;
+		usb_kill_urb(vub300->urb);
+	} else {
+		retval = vub300->urb->status;
+	}
+out:
+	*actual_length = vub300->urb->actual_length;
+	usb_free_urb(vub300->urb);
+	vub300->urb = NULL;
+	return retval;
+}
+
+static int __command_read_data(struct vub300_mmc_host *vub300,
+			       struct mmc_command *cmd, struct mmc_data *data)
+{
+	/* cmd_mutex is held by vub300_cmndwork_thread */
+	int linear_length = vub300->datasize;
+	int padded_length = vub300->large_usb_packets ?
+		((511 + linear_length) >> 9) << 9 :
+		((63 + linear_length) >> 6) << 6;
+	if ((padded_length == linear_length) || !pad_input_to_usb_pkt) {
+		int result;
+		unsigned pipe;
+		pipe = usb_rcvbulkpipe(vub300->udev, vub300->data_inp_ep);
+		result = usb_sg_init(&vub300->sg_request, vub300->udev,
+				     pipe, 0, data->sg,
+				     data->sg_len, 0, GFP_KERNEL);
+		if (result < 0) {
+			usb_unlink_urb(vub300->command_out_urb);
+			usb_unlink_urb(vub300->command_res_urb);
+			cmd->error = result;
+			data->bytes_xfered = 0;
+			return 0;
+		} else {
+			vub300->sg_transfer_timer.expires =
+				jiffies + msecs_to_jiffies(2000 +
+						  (linear_length / 16384));
+			add_timer(&vub300->sg_transfer_timer);
+			usb_sg_wait(&vub300->sg_request);
+			del_timer(&vub300->sg_transfer_timer);
+			if (vub300->sg_request.status < 0) {
+				cmd->error = vub300->sg_request.status;
+				data->bytes_xfered = 0;
+				return 0;
+			} else {
+				data->bytes_xfered = vub300->datasize;
+				return linear_length;
+			}
+		}
+	} else {
+		u8 *buf = kmalloc(padded_length, GFP_KERNEL);
+		if (buf) {
+			int result;
+			unsigned pipe = usb_rcvbulkpipe(vub300->udev,
+							vub300->data_inp_ep);
+			int actual_length = 0;
+			result = vub300_usb_bulk_msg(vub300, pipe, buf,
+					     padded_length, &actual_length,
+					     2000 + (padded_length / 16384));
+			if (result < 0) {
+				cmd->error = result;
+				data->bytes_xfered = 0;
+				kfree(buf);
+				return 0;
+			} else if (actual_length < linear_length) {
+				cmd->error = -EREMOTEIO;
+				data->bytes_xfered = 0;
+				kfree(buf);
+				return 0;
+			} else {
+				sg_copy_from_buffer(data->sg, data->sg_len, buf,
+						    linear_length);
+				kfree(buf);
+				data->bytes_xfered = vub300->datasize;
+				return linear_length;
+			}
+		} else {
+			cmd->error = -ENOMEM;
+			data->bytes_xfered = 0;
+			return 0;
+		}
+	}
+}
+
+static int __command_write_data(struct vub300_mmc_host *vub300,
+				struct mmc_command *cmd, struct mmc_data *data)
+{
+	/* cmd_mutex is held by vub300_cmndwork_thread */
+	unsigned pipe = usb_sndbulkpipe(vub300->udev, vub300->data_out_ep);
+	int linear_length = vub300->datasize;
+	int modulo_64_length = linear_length & 0x003F;
+	int modulo_512_length = linear_length & 0x01FF;
+	if (linear_length < 64) {
+		int result;
+		int actual_length;
+		sg_copy_to_buffer(data->sg, data->sg_len,
+				  vub300->padded_buffer,
+				  sizeof(vub300->padded_buffer));
+		memset(vub300->padded_buffer + linear_length, 0,
+		       sizeof(vub300->padded_buffer) - linear_length);
+		result = vub300_usb_bulk_msg(vub300, pipe, vub300->padded_buffer,
+					     sizeof(vub300->padded_buffer),
+					     &actual_length, 2000 +
+					     (sizeof(vub300->padded_buffer) /
+					      16384));
+		if (result < 0) {
+			cmd->error = result;
+			data->bytes_xfered = 0;
+		} else {
+			data->bytes_xfered = vub300->datasize;
+		}
+	} else if ((!vub300->large_usb_packets && (0 < modulo_64_length)) ||
+		    (vub300->large_usb_packets && (64 > modulo_512_length))
+		) {		/* don't you just love these work-rounds */
+		int padded_length = ((63 + linear_length) >> 6) << 6;
+		u8 *buf = kmalloc(padded_length, GFP_KERNEL);
+		if (buf) {
+			int result;
+			int actual_length;
+			sg_copy_to_buffer(data->sg, data->sg_len, buf,
+					  padded_length);
+			memset(buf + linear_length, 0,
+			       padded_length - linear_length);
+			result =
+				vub300_usb_bulk_msg(vub300, pipe, buf,
+						    padded_length, &actual_length,
+						    2000 + padded_length / 16384);
+			kfree(buf);
+			if (result < 0) {
+				cmd->error = result;
+				data->bytes_xfered = 0;
+			} else {
+				data->bytes_xfered = vub300->datasize;
+			}
+		} else {
+			cmd->error = -ENOMEM;
+			data->bytes_xfered = 0;
+		}
+	} else {		/* no data padding required */
+		int result;
+		unsigned char buf[64 * 4];
+		sg_copy_to_buffer(data->sg, data->sg_len, buf, sizeof(buf));
+		result = usb_sg_init(&vub300->sg_request, vub300->udev,
+				     pipe, 0, data->sg,
+				     data->sg_len, 0, GFP_KERNEL);
+		if (result < 0) {
+			usb_unlink_urb(vub300->command_out_urb);
+			usb_unlink_urb(vub300->command_res_urb);
+			cmd->error = result;
+			data->bytes_xfered = 0;
+		} else {
+			vub300->sg_transfer_timer.expires =
+				jiffies + msecs_to_jiffies(2000 +
+							   linear_length / 16384);
+			add_timer(&vub300->sg_transfer_timer);
+			usb_sg_wait(&vub300->sg_request);
+			if (cmd->error) {
+				data->bytes_xfered = 0;
+			} else {
+				del_timer(&vub300->sg_transfer_timer);
+				if (vub300->sg_request.status < 0) {
+					cmd->error = vub300->sg_request.status;
+					data->bytes_xfered = 0;
+				} else {
+					data->bytes_xfered = vub300->datasize;
+				}
+			}
+		}
+	}
+	return linear_length;
+}
+
+static void __vub300_command_response(struct vub300_mmc_host *vub300,
+				      struct mmc_command *cmd,
+				      struct mmc_data *data, int data_length)
+{
+	/* cmd_mutex is held by vub300_cmndwork_thread */
+	long respretval;
+	int msec_timeout = 1000 + data_length / 4;
+	respretval =
+		wait_for_completion_timeout(&vub300->command_complete,
+					    msecs_to_jiffies(msec_timeout));
+	if (respretval == 0) { /* TIMED OUT */
+		/* we don't know which of "out" and "res" if any failed */
+		int result;
+		vub300->usb_timed_out = 1;
+		usb_kill_urb(vub300->command_out_urb);
+		usb_kill_urb(vub300->command_res_urb);
+		cmd->error = -ETIMEDOUT;
+		result = usb_lock_device_for_reset(vub300->udev,
+						   vub300->interface);
+		if (result == 0) {
+			result = usb_reset_device(vub300->udev);
+			usb_unlock_device(vub300->udev);
+		}
+	} else if (respretval < 0) {
+		/* we don't know which of "out" and "res" if any failed */
+		usb_kill_urb(vub300->command_out_urb);
+		usb_kill_urb(vub300->command_res_urb);
+		cmd->error = respretval;
+	} else if (cmd->error) {
+		/*
+		 * the error occured sending the command
+		 * or recieving the response
+		 */
+	} else if (vub300->command_out_urb->status) {
+		vub300->usb_transport_fail = vub300->command_out_urb->status;
+		cmd->error = -EPROTO == vub300->command_out_urb->status ?
+			-ESHUTDOWN : vub300->command_out_urb->status;
+	} else if (vub300->command_res_urb->status) {
+		vub300->usb_transport_fail = vub300->command_res_urb->status;
+		cmd->error = -EPROTO == vub300->command_res_urb->status ?
+			-ESHUTDOWN : vub300->command_res_urb->status;
+	} else if (vub300->resp.common.header_type == 0x00) {
+		/*
+		 * the command completed successfully
+		 * and there was no piggybacked data
+		 */
+	} else if (vub300->resp.common.header_type == RESPONSE_ERROR) {
+		cmd->error =
+			vub300_response_error(vub300->resp.error.error_code);
+		if (vub300->data)
+			usb_sg_cancel(&vub300->sg_request);
+	} else if (vub300->resp.common.header_type == RESPONSE_PIGGYBACKED) {
+		int offloaded_data_length =
+			vub300->resp.common.header_size -
+			sizeof(struct sd_register_header);
+		int register_count = offloaded_data_length >> 3;
+		int ri = 0;
+		while (register_count--) {
+			add_offloaded_reg(vub300, &vub300->resp.pig.reg[ri]);
+			ri += 1;
+		}
+		vub300->resp.common.header_size =
+			sizeof(struct sd_register_header);
+		vub300->resp.common.header_type = 0x00;
+		cmd->error = 0;
+	} else if (vub300->resp.common.header_type == RESPONSE_PIG_DISABLED) {
+		int offloaded_data_length =
+			vub300->resp.common.header_size -
+			sizeof(struct sd_register_header);
+		int register_count = offloaded_data_length >> 3;
+		int ri = 0;
+		while (register_count--) {
+			add_offloaded_reg(vub300, &vub300->resp.pig.reg[ri]);
+			ri += 1;
+		}
+		mutex_lock(&vub300->irq_mutex);
+		if (vub300->irqs_queued) {
+			vub300->irqs_queued += 1;
+		} else if (vub300->irq_enabled) {
+			vub300->irqs_queued += 1;
+			vub300_queue_poll_work(vub300, 0);
+		} else {
+			vub300->irqs_queued += 1;
+		}
+		vub300->irq_disabled = 1;
+		mutex_unlock(&vub300->irq_mutex);
+		vub300->resp.common.header_size =
+			sizeof(struct sd_register_header);
+		vub300->resp.common.header_type = 0x00;
+		cmd->error = 0;
+	} else if (vub300->resp.common.header_type == RESPONSE_PIG_ENABLED) {
+		int offloaded_data_length =
+			vub300->resp.common.header_size -
+			sizeof(struct sd_register_header);
+		int register_count = offloaded_data_length >> 3;
+		int ri = 0;
+		while (register_count--) {
+			add_offloaded_reg(vub300, &vub300->resp.pig.reg[ri]);
+			ri += 1;
+		}
+		mutex_lock(&vub300->irq_mutex);
+		if (vub300->irqs_queued) {
+			vub300->irqs_queued += 1;
+		} else if (vub300->irq_enabled) {
+			vub300->irqs_queued += 1;
+			vub300_queue_poll_work(vub300, 0);
+		} else {
+			vub300->irqs_queued += 1;
+		}
+		vub300->irq_disabled = 0;
+		mutex_unlock(&vub300->irq_mutex);
+		vub300->resp.common.header_size =
+			sizeof(struct sd_register_header);
+		vub300->resp.common.header_type = 0x00;
+		cmd->error = 0;
+	} else {
+		cmd->error = -EINVAL;
+	}
+}
+
+static void construct_request_response(struct vub300_mmc_host *vub300,
+				       struct mmc_command *cmd)
+{
+	int resp_len = vub300->resp_len;
+	int less_cmd = (17 == resp_len) ? resp_len : resp_len - 1;
+	int bytes = 3 & less_cmd;
+	int words = less_cmd >> 2;
+	u8 *r = vub300->resp.response.command_response;
+	if (bytes == 3) {
+		cmd->resp[words] = (r[1 + (words << 2)] << 24)
+			| (r[2 + (words << 2)] << 16)
+			| (r[3 + (words << 2)] << 8);
+	} else if (bytes == 2) {
+		cmd->resp[words] = (r[1 + (words << 2)] << 24)
+			| (r[2 + (words << 2)] << 16);
+	} else if (bytes == 1) {
+		cmd->resp[words] = (r[1 + (words << 2)] << 24);
+	}
+	while (words-- > 0) {
+		cmd->resp[words] = (r[1 + (words << 2)] << 24)
+			| (r[2 + (words << 2)] << 16)
+			| (r[3 + (words << 2)] << 8)
+			| (r[4 + (words << 2)] << 0);
+	}
+	if ((cmd->opcode == 53) && (0x000000FF & cmd->resp[0]))
+		cmd->resp[0] &= 0xFFFFFF00;
+}
+
+/* this thread runs only when there is an upper level command req outstanding */
+static void vub300_cmndwork_thread(struct work_struct *work)
+{
+	struct vub300_mmc_host *vub300 =
+		container_of(work, struct vub300_mmc_host, cmndwork);
+	if (!vub300->interface) {
+		kref_put(&vub300->kref, vub300_delete);
+		return;
+	} else {
+		struct mmc_request *req = vub300->req;
+		struct mmc_command *cmd = vub300->cmd;
+		struct mmc_data *data = vub300->data;
+		int data_length;
+		mutex_lock(&vub300->cmd_mutex);
+		init_completion(&vub300->command_complete);
+		if (likely(vub300->vub_name[0]) || !vub300->mmc->card ||
+		    !mmc_card_present(vub300->mmc->card)) {
+			/*
+			 * the name of the EMPTY Pseudo firmware file
+			 * is used as a flag to indicate that the file
+			 * has been already downloaded to the VUB300 chip
+			 */
+		} else if (0 == vub300->mmc->card->sdio_funcs) {
+			strncpy(vub300->vub_name, "SD memory device",
+				sizeof(vub300->vub_name));
+		} else {
+			download_offload_pseudocode(vub300);
+		}
+		send_command(vub300);
+		if (!data)
+			data_length = 0;
+		else if (MMC_DATA_READ & data->flags)
+			data_length = __command_read_data(vub300, cmd, data);
+		else
+			data_length = __command_write_data(vub300, cmd, data);
+		__vub300_command_response(vub300, cmd, data, data_length);
+		vub300->req = NULL;
+		vub300->cmd = NULL;
+		vub300->data = NULL;
+		if (cmd->error) {
+			if (cmd->error == -ENOMEDIUM)
+				check_vub300_port_status(vub300);
+			mutex_unlock(&vub300->cmd_mutex);
+			mmc_request_done(vub300->mmc, req);
+			kref_put(&vub300->kref, vub300_delete);
+			return;
+		} else {
+			construct_request_response(vub300, cmd);
+			vub300->resp_len = 0;
+			mutex_unlock(&vub300->cmd_mutex);
+			kref_put(&vub300->kref, vub300_delete);
+			mmc_request_done(vub300->mmc, req);
+			return;
+		}
+	}
+}
+
+static int examine_cyclic_buffer(struct vub300_mmc_host *vub300,
+				 struct mmc_command *cmd, u8 Function)
+{
+	/* cmd_mutex is held by vub300_mmc_request */
+	u8 cmd0 = 0xFF & (cmd->arg >> 24);
+	u8 cmd1 = 0xFF & (cmd->arg >> 16);
+	u8 cmd2 = 0xFF & (cmd->arg >> 8);
+	u8 cmd3 = 0xFF & (cmd->arg >> 0);
+	int first = MAXREGMASK & vub300->fn[Function].offload_point;
+	struct offload_registers_access *rf = &vub300->fn[Function].reg[first];
+	if (cmd0 == rf->command_byte[0] &&
+	    cmd1 == rf->command_byte[1] &&
+	    cmd2 == rf->command_byte[2] &&
+	    cmd3 == rf->command_byte[3]) {
+		u8 checksum = 0x00;
+		cmd->resp[1] = checksum << 24;
+		cmd->resp[0] = (rf->Respond_Byte[0] << 24)
+			| (rf->Respond_Byte[1] << 16)
+			| (rf->Respond_Byte[2] << 8)
+			| (rf->Respond_Byte[3] << 0);
+		vub300->fn[Function].offload_point += 1;
+		vub300->fn[Function].offload_count -= 1;
+		vub300->total_offload_count -= 1;
+		return 1;
+	} else {
+		int delta = 1;	/* because it does not match the first one */
+		u8 register_count = vub300->fn[Function].offload_count - 1;
+		u32 register_point = vub300->fn[Function].offload_point + 1;
+		while (0 < register_count) {
+			int point = MAXREGMASK & register_point;
+			struct offload_registers_access *r =
+				&vub300->fn[Function].reg[point];
+			if (cmd0 == r->command_byte[0] &&
+			    cmd1 == r->command_byte[1] &&
+			    cmd2 == r->command_byte[2] &&
+			    cmd3 == r->command_byte[3]) {
+				u8 checksum = 0x00;
+				cmd->resp[1] = checksum << 24;
+				cmd->resp[0] = (r->Respond_Byte[0] << 24)
+					| (r->Respond_Byte[1] << 16)
+					| (r->Respond_Byte[2] << 8)
+					| (r->Respond_Byte[3] << 0);
+				vub300->fn[Function].offload_point += delta;
+				vub300->fn[Function].offload_count -= delta;
+				vub300->total_offload_count -= delta;
+				return 1;
+			} else {
+				register_point += 1;
+				register_count -= 1;
+				delta += 1;
+				continue;
+			}
+		}
+		return 0;
+	}
+}
+
+static int satisfy_request_from_offloaded_data(struct vub300_mmc_host *vub300,
+					       struct mmc_command *cmd)
+{
+	/* cmd_mutex is held by vub300_mmc_request */
+	u8 regs = vub300->dynamic_register_count;
+	u8 i = 0;
+	u8 func = FUN(cmd);
+	u32 reg = REG(cmd);
+	while (0 < regs--) {
+		if ((vub300->sdio_register[i].func_num == func) &&
+		    (vub300->sdio_register[i].sdio_reg == reg)) {
+			if (!vub300->sdio_register[i].prepared) {
+				return 0;
+			} else if ((0x80000000 & cmd->arg) == 0x80000000) {
+				/*
+				 * a write to a dynamic register
+				 * nullifies our offloaded value
+				 */
+				vub300->sdio_register[i].prepared = 0;
+				return 0;
+			} else {
+				u8 checksum = 0x00;
+				u8 rsp0 = 0x00;
+				u8 rsp1 = 0x00;
+				u8 rsp2 = vub300->sdio_register[i].response;
+				u8 rsp3 = vub300->sdio_register[i].regvalue;
+				vub300->sdio_register[i].prepared = 0;
+				cmd->resp[1] = checksum << 24;
+				cmd->resp[0] = (rsp0 << 24)
+					| (rsp1 << 16)
+					| (rsp2 << 8)
+					| (rsp3 << 0);
+				return 1;
+			}
+		} else {
+			i += 1;
+			continue;
+		}
+	};
+	if (vub300->total_offload_count == 0)
+		return 0;
+	else if (vub300->fn[func].offload_count == 0)
+		return 0;
+	else
+		return examine_cyclic_buffer(vub300, cmd, func);
+}
+
+static void vub300_mmc_request(struct mmc_host *mmc, struct mmc_request *req)
+{				/* NOT irq */
+	struct mmc_command *cmd = req->cmd;
+	struct vub300_mmc_host *vub300 = mmc_priv(mmc);
+	if (!vub300->interface) {
+		cmd->error = -ESHUTDOWN;
+		mmc_request_done(mmc, req);
+		return;
+	} else {
+		struct mmc_data *data = req->data;
+		if (!vub300->card_powered) {
+			cmd->error = -ENOMEDIUM;
+			mmc_request_done(mmc, req);
+			return;
+		}
+		if (!vub300->card_present) {
+			cmd->error = -ENOMEDIUM;
+			mmc_request_done(mmc, req);
+			return;
+		}
+		if (vub300->usb_transport_fail) {
+			cmd->error = vub300->usb_transport_fail;
+			mmc_request_done(mmc, req);
+			return;
+		}
+		if (!vub300->interface) {
+			cmd->error = -ENODEV;
+			mmc_request_done(mmc, req);
+			return;
+		}
+		kref_get(&vub300->kref);
+		mutex_lock(&vub300->cmd_mutex);
+		mod_timer(&vub300->inactivity_timer, jiffies + HZ);
+		/*
+		 * for performance we have to return immediately
+		 * if the requested data has been offloaded
+		 */
+		if (cmd->opcode == 52 &&
+		    satisfy_request_from_offloaded_data(vub300, cmd)) {
+			cmd->error = 0;
+			mutex_unlock(&vub300->cmd_mutex);
+			kref_put(&vub300->kref, vub300_delete);
+			mmc_request_done(mmc, req);
+			return;
+		} else {
+			vub300->cmd = cmd;
+			vub300->req = req;
+			vub300->data = data;
+			if (data)
+				vub300->datasize = data->blksz * data->blocks;
+			else
+				vub300->datasize = 0;
+			vub300_queue_cmnd_work(vub300);
+			mutex_unlock(&vub300->cmd_mutex);
+			kref_put(&vub300->kref, vub300_delete);
+			/*
+			 * the kernel lock diagnostics complain
+			 * if the cmd_mutex * is "passed on"
+			 * to the cmndwork thread,
+			 * so we must release it now
+			 * and re-acquire it in the cmndwork thread
+			 */
+		}
+	}
+}
+
+static void __set_clock_speed(struct vub300_mmc_host *vub300, u8 buf[8],
+			      struct mmc_ios *ios)
+{
+	int buf_array_size = 8; /* ARRAY_SIZE(buf) does not work !!! */
+	int retval;
+	u32 kHzClock;
+	if (ios->clock >= 48000000)
+		kHzClock = 48000;
+	else if (ios->clock >= 24000000)
+		kHzClock = 24000;
+	else if (ios->clock >= 20000000)
+		kHzClock = 20000;
+	else if (ios->clock >= 15000000)
+		kHzClock = 15000;
+	else if (ios->clock >= 200000)
+		kHzClock = 200;
+	else
+		kHzClock = 0;
+	{
+		int i;
+		u64 c = kHzClock;
+		for (i = 0; i < buf_array_size; i++) {
+			buf[i] = c;
+			c >>= 8;
+		}
+	}
+	retval =
+		usb_control_msg(vub300->udev, usb_sndctrlpipe(vub300->udev, 0),
+				SET_CLOCK_SPEED,
+				USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+				0x00, 0x00, buf, buf_array_size, HZ);
+	if (retval != 8) {
+		dev_err(&vub300->udev->dev, "SET_CLOCK_SPEED"
+			" %dkHz failed with retval=%d\n", kHzClock, retval);
+	} else {
+		dev_dbg(&vub300->udev->dev, "SET_CLOCK_SPEED"
+			" %dkHz\n", kHzClock);
+	}
+}
+
+static void vub300_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
+{				/* NOT irq */
+	struct vub300_mmc_host *vub300 = mmc_priv(mmc);
+	if (!vub300->interface)
+		return;
+	kref_get(&vub300->kref);
+	mutex_lock(&vub300->cmd_mutex);
+	if ((ios->power_mode == MMC_POWER_OFF) && vub300->card_powered) {
+		vub300->card_powered = 0;
+		usb_control_msg(vub300->udev, usb_sndctrlpipe(vub300->udev, 0),
+				SET_SD_POWER,
+				USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+				0x0000, 0x0000, NULL, 0, HZ);
+		/* must wait for the VUB300 u-proc to boot up */
+		msleep(600);
+	} else if ((ios->power_mode == MMC_POWER_UP) && !vub300->card_powered) {
+		usb_control_msg(vub300->udev, usb_sndctrlpipe(vub300->udev, 0),
+				SET_SD_POWER,
+				USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+				0x0001, 0x0000, NULL, 0, HZ);
+		msleep(600);
+		vub300->card_powered = 1;
+	} else if (ios->power_mode == MMC_POWER_ON) {
+		u8 *buf = kmalloc(8, GFP_KERNEL);
+		if (buf) {
+			__set_clock_speed(vub300, buf, ios);
+			kfree(buf);
+		}
+	} else {
+		/* this should mean no change of state */
+	}
+	mutex_unlock(&vub300->cmd_mutex);
+	kref_put(&vub300->kref, vub300_delete);
+}
+
+static int vub300_mmc_get_ro(struct mmc_host *mmc)
+{
+	struct vub300_mmc_host *vub300 = mmc_priv(mmc);
+	return vub300->read_only;
+}
+
+static void vub300_enable_sdio_irq(struct mmc_host *mmc, int enable)
+{				/* NOT irq */
+	struct vub300_mmc_host *vub300 = mmc_priv(mmc);
+	if (!vub300->interface)
+		return;
+	kref_get(&vub300->kref);
+	if (enable) {
+		mutex_lock(&vub300->irq_mutex);
+		if (vub300->irqs_queued) {
+			vub300->irqs_queued -= 1;
+			mmc_signal_sdio_irq(vub300->mmc);
+		} else if (vub300->irq_disabled) {
+			vub300->irq_disabled = 0;
+			vub300->irq_enabled = 1;
+			vub300_queue_poll_work(vub300, 0);
+		} else if (vub300->irq_enabled) {
+			/* this should not happen, so we will just ignore it */
+		} else {
+			vub300->irq_enabled = 1;
+			vub300_queue_poll_work(vub300, 0);
+		}
+		mutex_unlock(&vub300->irq_mutex);
+	} else {
+		vub300->irq_enabled = 0;
+	}
+	kref_put(&vub300->kref, vub300_delete);
+}
+
+void vub300_init_card(struct mmc_host *mmc, struct mmc_card *card)
+{				/* NOT irq */
+	struct vub300_mmc_host *vub300 = mmc_priv(mmc);
+	dev_info(&vub300->udev->dev, "NO host QUIRKS for this card\n");
+}
+
+static struct mmc_host_ops vub300_mmc_ops = {
+	.request = vub300_mmc_request,
+	.set_ios = vub300_mmc_set_ios,
+	.get_ro = vub300_mmc_get_ro,
+	.enable_sdio_irq = vub300_enable_sdio_irq,
+	.init_card = vub300_init_card,
+};
+
+static int vub300_probe(struct usb_interface *interface,
+			const struct usb_device_id *id)
+{				/* NOT irq */
+	struct vub300_mmc_host *vub300;
+	struct usb_host_interface *iface_desc;
+	struct usb_device *udev = usb_get_dev(interface_to_usbdev(interface));
+	int i;
+	int retval = -ENOMEM;
+	struct urb *command_out_urb;
+	struct urb *command_res_urb;
+	struct mmc_host *mmc;
+	char manufacturer[48];
+	char product[32];
+	char serial_number[32];
+	usb_string(udev, udev->descriptor.iManufacturer, manufacturer,
+		   sizeof(manufacturer));
+	usb_string(udev, udev->descriptor.iProduct, product, sizeof(product));
+	usb_string(udev, udev->descriptor.iSerialNumber, serial_number,
+		   sizeof(serial_number));
+	dev_info(&udev->dev, "probing VID:PID(%04X:%04X) %s %s %s\n",
+		 udev->descriptor.idVendor, udev->descriptor.idProduct,
+		 manufacturer, product, serial_number);
+	command_out_urb = usb_alloc_urb(0, GFP_KERNEL);
+	if (!command_out_urb) {
+		retval = -ENOMEM;
+		dev_err(&udev->dev, "not enough memory for command_out_urb\n");
+		goto error0;
+	}
+	command_res_urb = usb_alloc_urb(0, GFP_KERNEL);
+	if (!command_res_urb) {
+		retval = -ENOMEM;
+		dev_err(&udev->dev, "not enough memory for command_res_urb\n");
+		goto error1;
+	}
+	/* this also allocates memory for our VUB300 mmc host device */
+	mmc = mmc_alloc_host(sizeof(struct vub300_mmc_host), &udev->dev);
+	if (!mmc) {
+		retval = -ENOMEM;
+		dev_err(&udev->dev, "not enough memory for the mmc_host\n");
+		goto error4;
+	}
+	/* MMC core transfer sizes tunable parameters */
+	mmc->caps = 0;
+	if (!force_1_bit_data_xfers)
+		mmc->caps |= MMC_CAP_4_BIT_DATA;
+	if (!force_polling_for_irqs)
+		mmc->caps |= MMC_CAP_SDIO_IRQ;
+	mmc->caps &= ~MMC_CAP_NEEDS_POLL;
+	/*
+	 * MMC_CAP_NEEDS_POLL causes core.c:mmc_rescan() to poll
+	 * for devices which results in spurious CMD7's being
+	 * issued which stops some SDIO cards from working
+	 */
+	if (limit_speed_to_24_MHz) {
+		mmc->caps |= MMC_CAP_MMC_HIGHSPEED;
+		mmc->caps |= MMC_CAP_SD_HIGHSPEED;
+		mmc->f_max = 24000000;
+		dev_info(&udev->dev, "limiting SDIO speed to 24_MHz\n");
+	} else {
+		mmc->caps |= MMC_CAP_MMC_HIGHSPEED;
+		mmc->caps |= MMC_CAP_SD_HIGHSPEED;
+		mmc->f_max = 48000000;
+	}
+	mmc->f_min = 200000;
+	mmc->max_blk_count = 511;
+	mmc->max_blk_size = 512;
+	mmc->max_segs = 128;
+	if (force_max_req_size)
+		mmc->max_req_size = force_max_req_size * 1024;
+	else
+		mmc->max_req_size = 64 * 1024;
+	mmc->max_seg_size = mmc->max_req_size;
+	mmc->ocr_avail = 0;
+	mmc->ocr_avail |= MMC_VDD_165_195;
+	mmc->ocr_avail |= MMC_VDD_20_21;
+	mmc->ocr_avail |= MMC_VDD_21_22;
+	mmc->ocr_avail |= MMC_VDD_22_23;
+	mmc->ocr_avail |= MMC_VDD_23_24;
+	mmc->ocr_avail |= MMC_VDD_24_25;
+	mmc->ocr_avail |= MMC_VDD_25_26;
+	mmc->ocr_avail |= MMC_VDD_26_27;
+	mmc->ocr_avail |= MMC_VDD_27_28;
+	mmc->ocr_avail |= MMC_VDD_28_29;
+	mmc->ocr_avail |= MMC_VDD_29_30;
+	mmc->ocr_avail |= MMC_VDD_30_31;
+	mmc->ocr_avail |= MMC_VDD_31_32;
+	mmc->ocr_avail |= MMC_VDD_32_33;
+	mmc->ocr_avail |= MMC_VDD_33_34;
+	mmc->ocr_avail |= MMC_VDD_34_35;
+	mmc->ocr_avail |= MMC_VDD_35_36;
+	mmc->ops = &vub300_mmc_ops;
+	vub300 = mmc_priv(mmc);
+	vub300->mmc = mmc;
+	vub300->card_powered = 0;
+	vub300->bus_width = 0;
+	vub300->cmnd.head.block_size[0] = 0x00;
+	vub300->cmnd.head.block_size[1] = 0x00;
+	vub300->app_spec = 0;
+	mutex_init(&vub300->cmd_mutex);
+	mutex_init(&vub300->irq_mutex);
+	vub300->command_out_urb = command_out_urb;
+	vub300->command_res_urb = command_res_urb;
+	vub300->usb_timed_out = 0;
+	vub300->dynamic_register_count = 0;
+
+	for (i = 0; i < ARRAY_SIZE(vub300->fn); i++) {
+		vub300->fn[i].offload_point = 0;
+		vub300->fn[i].offload_count = 0;
+	}
+
+	vub300->total_offload_count = 0;
+	vub300->irq_enabled = 0;
+	vub300->irq_disabled = 0;
+	vub300->irqs_queued = 0;
+
+	for (i = 0; i < ARRAY_SIZE(vub300->sdio_register); i++)
+		vub300->sdio_register[i++].activate = 0;
+
+	vub300->udev = udev;
+	vub300->interface = interface;
+	vub300->cmnd_res_ep = 0;
+	vub300->cmnd_out_ep = 0;
+	vub300->data_inp_ep = 0;
+	vub300->data_out_ep = 0;
+
+	for (i = 0; i < ARRAY_SIZE(vub300->fbs); i++)
+		vub300->fbs[i] = 512;
+
+	/*
+	 *      set up the endpoint information
+	 *
+	 * use the first pair of bulk-in and bulk-out
+	 *     endpoints for Command/Response+Interrupt
+	 *
+	 * use the second pair of bulk-in and bulk-out
+	 *     endpoints for Data In/Out
+	 */
+	vub300->large_usb_packets = 0;
+	iface_desc = interface->cur_altsetting;
+	for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) {
+		struct usb_endpoint_descriptor *endpoint =
+			&iface_desc->endpoint[i].desc;
+		dev_info(&vub300->udev->dev,
+			 "vub300 testing %s EndPoint(%d) %02X\n",
+			 usb_endpoint_is_bulk_in(endpoint) ? "BULK IN" :
+			 usb_endpoint_is_bulk_out(endpoint) ? "BULK OUT" :
+			 "UNKNOWN", i, endpoint->bEndpointAddress);
+		if (endpoint->wMaxPacketSize > 64)
+			vub300->large_usb_packets = 1;
+		if (usb_endpoint_is_bulk_in(endpoint)) {
+			if (!vub300->cmnd_res_ep) {
+				vub300->cmnd_res_ep =
+					endpoint->bEndpointAddress;
+			} else if (!vub300->data_inp_ep) {
+				vub300->data_inp_ep =
+					endpoint->bEndpointAddress;
+			} else {
+				dev_warn(&vub300->udev->dev,
+					 "ignoring"
+					 " unexpected bulk_in endpoint");
+			}
+		} else if (usb_endpoint_is_bulk_out(endpoint)) {
+			if (!vub300->cmnd_out_ep) {
+				vub300->cmnd_out_ep =
+					endpoint->bEndpointAddress;
+			} else if (!vub300->data_out_ep) {
+				vub300->data_out_ep =
+					endpoint->bEndpointAddress;
+			} else {
+				dev_warn(&vub300->udev->dev,
+					 "ignoring"
+					 " unexpected bulk_out endpoint");
+			}
+		} else {
+			dev_warn(&vub300->udev->dev,
+				 "vub300 ignoring EndPoint(%d) %02X", i,
+				 endpoint->bEndpointAddress);
+		}
+	}
+	if (vub300->cmnd_res_ep && vub300->cmnd_out_ep &&
+	    vub300->data_inp_ep && vub300->data_out_ep) {
+		dev_info(&vub300->udev->dev,
+			 "vub300 %s packets"
+			 " using EndPoints %02X %02X %02X %02X\n",
+			 vub300->large_usb_packets ? "LARGE" : "SMALL",
+			 vub300->cmnd_out_ep, vub300->cmnd_res_ep,
+			 vub300->data_out_ep, vub300->data_inp_ep);
+		/* we have the expected EndPoints */
+	} else {
+		dev_err(&vub300->udev->dev,
+		    "Could not find two sets of bulk-in/out endpoint pairs\n");
+		retval = -EINVAL;
+		goto error5;
+	}
+	retval =
+		usb_control_msg(vub300->udev, usb_rcvctrlpipe(vub300->udev, 0),
+				GET_HC_INF0,
+				USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+				0x0000, 0x0000, &vub300->hc_info,
+				sizeof(vub300->hc_info), HZ);
+	if (retval < 0)
+		goto error5;
+	retval =
+		usb_control_msg(vub300->udev, usb_rcvctrlpipe(vub300->udev, 0),
+				SET_ROM_WAIT_STATES,
+				USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+				firmware_rom_wait_states, 0x0000, NULL, 0, HZ);
+	if (retval < 0)
+		goto error5;
+	dev_info(&vub300->udev->dev,
+		 "operating_mode = %s %s %d MHz %s %d byte USB packets\n",
+		 (mmc->caps & MMC_CAP_SDIO_IRQ) ? "IRQs" : "POLL",
+		 (mmc->caps & MMC_CAP_4_BIT_DATA) ? "4-bit" : "1-bit",
+		 mmc->f_max / 1000000,
+		 pad_input_to_usb_pkt ? "padding input data to" : "with",
+		 vub300->large_usb_packets ? 512 : 64);
+	retval =
+		usb_control_msg(vub300->udev, usb_rcvctrlpipe(vub300->udev, 0),
+				GET_SYSTEM_PORT_STATUS,
+				USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+				0x0000, 0x0000, &vub300->system_port_status,
+				sizeof(vub300->system_port_status), HZ);
+	if (retval < 0) {
+		goto error4;
+	} else if (sizeof(vub300->system_port_status) == retval) {
+		vub300->card_present =
+			(0x0001 & vub300->system_port_status.port_flags) ? 1 : 0;
+		vub300->read_only =
+			(0x0010 & vub300->system_port_status.port_flags) ? 1 : 0;
+	} else {
+		goto error4;
+	}
+	usb_set_intfdata(interface, vub300);
+	INIT_DELAYED_WORK(&vub300->pollwork, vub300_pollwork_thread);
+	INIT_WORK(&vub300->cmndwork, vub300_cmndwork_thread);
+	INIT_WORK(&vub300->deadwork, vub300_deadwork_thread);
+	kref_init(&vub300->kref);
+	init_timer(&vub300->sg_transfer_timer);
+	vub300->sg_transfer_timer.data = (unsigned long)vub300;
+	vub300->sg_transfer_timer.function = vub300_sg_timed_out;
+	kref_get(&vub300->kref);
+	init_timer(&vub300->inactivity_timer);
+	vub300->inactivity_timer.data = (unsigned long)vub300;
+	vub300->inactivity_timer.function = vub300_inactivity_timer_expired;
+	vub300->inactivity_timer.expires = jiffies + HZ;
+	add_timer(&vub300->inactivity_timer);
+	if (vub300->card_present)
+		dev_info(&vub300->udev->dev,
+			 "USB vub300 remote SDIO host controller[%d]"
+			 "connected with SD/SDIO card inserted\n",
+			 interface_to_InterfaceNumber(interface));
+	else
+		dev_info(&vub300->udev->dev,
+			 "USB vub300 remote SDIO host controller[%d]"
+			 "connected with no SD/SDIO card inserted\n",
+			 interface_to_InterfaceNumber(interface));
+	mmc_add_host(mmc);
+	return 0;
+error5:
+	mmc_free_host(mmc);
+	/*
+	 * and hence also frees vub300
+	 * which is contained at the end of struct mmc
+	 */
+error4:
+	usb_free_urb(command_out_urb);
+error1:
+	usb_free_urb(command_res_urb);
+error0:
+	return retval;
+}
+
+static void vub300_disconnect(struct usb_interface *interface)
+{				/* NOT irq */
+	struct vub300_mmc_host *vub300 = usb_get_intfdata(interface);
+	if (!vub300 || !vub300->mmc) {
+		return;
+	} else {
+		struct mmc_host *mmc = vub300->mmc;
+		if (!vub300->mmc) {
+			return;
+		} else {
+			int ifnum = interface_to_InterfaceNumber(interface);
+			usb_set_intfdata(interface, NULL);
+			/* prevent more I/O from starting */
+			vub300->interface = NULL;
+			kref_put(&vub300->kref, vub300_delete);
+			mmc_remove_host(mmc);
+			pr_info("USB vub300 remote SDIO host controller[%d]"
+				" now disconnected", ifnum);
+			return;
+		}
+	}
+}
+
+#ifdef CONFIG_PM
+static int vub300_suspend(struct usb_interface *intf, pm_message_t message)
+{
+	struct vub300_mmc_host *vub300 = usb_get_intfdata(intf);
+	if (!vub300 || !vub300->mmc) {
+		return 0;
+	} else {
+		struct mmc_host *mmc = vub300->mmc;
+		mmc_suspend_host(mmc);
+		return 0;
+	}
+}
+
+static int vub300_resume(struct usb_interface *intf)
+{
+	struct vub300_mmc_host *vub300 = usb_get_intfdata(intf);
+	if (!vub300 || !vub300->mmc) {
+		return 0;
+	} else {
+		struct mmc_host *mmc = vub300->mmc;
+		mmc_resume_host(mmc);
+		return 0;
+	}
+}
+#else
+#define vub300_suspend NULL
+#define vub300_resume NULL
+#endif
+static int vub300_pre_reset(struct usb_interface *intf)
+{				/* NOT irq */
+	struct vub300_mmc_host *vub300 = usb_get_intfdata(intf);
+	mutex_lock(&vub300->cmd_mutex);
+	return 0;
+}
+
+static int vub300_post_reset(struct usb_interface *intf)
+{				/* NOT irq */
+	struct vub300_mmc_host *vub300 = usb_get_intfdata(intf);
+	/* we are sure no URBs are active - no locking needed */
+	vub300->errors = -EPIPE;
+	mutex_unlock(&vub300->cmd_mutex);
+	return 0;
+}
+
+static struct usb_driver vub300_driver = {
+	.name = "vub300",
+	.probe = vub300_probe,
+	.disconnect = vub300_disconnect,
+	.suspend = vub300_suspend,
+	.resume = vub300_resume,
+	.pre_reset = vub300_pre_reset,
+	.post_reset = vub300_post_reset,
+	.id_table = vub300_table,
+	.supports_autosuspend = 1,
+};
+
+static int __init vub300_init(void)
+{				/* NOT irq */
+	int result;
+
+	pr_info("VUB300 Driver rom wait states = %02X irqpoll timeout = %04X",
+		firmware_rom_wait_states, 0x0FFFF & firmware_irqpoll_timeout);
+	cmndworkqueue = create_singlethread_workqueue("kvub300c");
+	if (!cmndworkqueue) {
+		pr_err("not enough memory for the REQUEST workqueue");
+		result = -ENOMEM;
+		goto out1;
+	}
+	pollworkqueue = create_singlethread_workqueue("kvub300p");
+	if (!pollworkqueue) {
+		pr_err("not enough memory for the IRQPOLL workqueue");
+		result = -ENOMEM;
+		goto out2;
+	}
+	deadworkqueue = create_singlethread_workqueue("kvub300d");
+	if (!deadworkqueue) {
+		pr_err("not enough memory for the EXPIRED workqueue");
+		result = -ENOMEM;
+		goto out3;
+	}
+	result = usb_register(&vub300_driver);
+	if (result) {
+		pr_err("usb_register failed. Error number %d", result);
+		goto out4;
+	}
+	return 0;
+out4:
+	destroy_workqueue(deadworkqueue);
+out3:
+	destroy_workqueue(pollworkqueue);
+out2:
+	destroy_workqueue(cmndworkqueue);
+out1:
+	return result;
+}
+
+static void __exit vub300_exit(void)
+{
+	usb_deregister(&vub300_driver);
+	flush_workqueue(cmndworkqueue);
+	flush_workqueue(pollworkqueue);
+	flush_workqueue(deadworkqueue);
+	destroy_workqueue(cmndworkqueue);
+	destroy_workqueue(pollworkqueue);
+	destroy_workqueue(deadworkqueue);
+}
+
+module_init(vub300_init);
+module_exit(vub300_exit);
+
+MODULE_AUTHOR("Tony Olech <tony.olech@elandigitalsystems.com>");
+MODULE_DESCRIPTION("VUB300 USB to SD/MMC/SDIO adapter driver");
+MODULE_LICENSE("GPL");
diff -druN linux-2.6.39-libre/drivers/mtd/chips/cfi_cmdset_0001.c linux-3.0-rc7-libre/drivers/mtd/chips/cfi_cmdset_0001.c
--- linux-2.6.39-libre/drivers/mtd/chips/cfi_cmdset_0001.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mtd/chips/cfi_cmdset_0001.c	2011-07-11 19:51:52.000000000 -0400
@@ -812,12 +812,9 @@
 			        break;
 
 			if (time_after(jiffies, timeo)) {
-				/* Urgh. Resume and pretend we weren't here.  */
-				map_write(map, CMD(0xd0), adr);
-				/* Make sure we're in 'read status' mode if it had finished */
-				map_write(map, CMD(0x70), adr);
-				chip->state = FL_ERASING;
-				chip->oldstate = FL_READY;
+				/* Urgh. Resume and pretend we weren't here.
+				 * Make sure we're in 'read status' mode if it had finished */
+				put_chip(map, chip, adr);
 				printk(KERN_ERR "%s: Chip not ready after erase "
 				       "suspended: status = 0x%lx\n", map->name, status.x[0]);
 				return -EIO;
@@ -997,7 +994,6 @@
 
 	switch(chip->oldstate) {
 	case FL_ERASING:
-		chip->state = chip->oldstate;
 		/* What if one interleaved chip has finished and the
 		   other hasn't? The old code would leave the finished
 		   one in READY mode. That's bad, and caused -EROFS
diff -druN linux-2.6.39-libre/drivers/mtd/chips/cfi_cmdset_0002.c linux-3.0-rc7-libre/drivers/mtd/chips/cfi_cmdset_0002.c
--- linux-2.6.39-libre/drivers/mtd/chips/cfi_cmdset_0002.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mtd/chips/cfi_cmdset_0002.c	2011-07-11 19:51:52.000000000 -0400
@@ -462,13 +462,14 @@
 			cfi_fixup_major_minor(cfi, extp);
 
 			/*
-			 * Valid primary extension versions are: 1.0, 1.1, 1.2, 1.3, 1.4
+			 * Valid primary extension versions are: 1.0, 1.1, 1.2, 1.3, 1.4, 1.5
 			 * see: http://cs.ozerki.net/zap/pub/axim-x5/docs/cfi_r20.pdf, page 19 
 			 *      http://www.spansion.com/Support/AppNotes/cfi_100_20011201.pdf
 			 *      http://www.spansion.com/Support/Datasheets/s29ws-p_00_a12_e.pdf
+			 *      http://www.spansion.com/Support/Datasheets/S29GL_128S_01GS_00_02_e.pdf
 			 */
 			if (extp->MajorVersion != '1' ||
-			    (extp->MajorVersion == '1' && (extp->MinorVersion < '0' || extp->MinorVersion > '4'))) {
+			    (extp->MajorVersion == '1' && (extp->MinorVersion < '0' || extp->MinorVersion > '5'))) {
 				printk(KERN_ERR "  Unknown Amd/Fujitsu Extended Query "
 				       "version %c.%c (%#02x/%#02x).\n",
 				       extp->MajorVersion, extp->MinorVersion,
@@ -710,9 +711,7 @@
 				 * there was an error (so leave the erase
 				 * routine to recover from it) or we trying to
 				 * use the erase-in-progress sector. */
-				map_write(map, cfi->sector_erase_cmd, chip->in_progress_block_addr);
-				chip->state = FL_ERASING;
-				chip->oldstate = FL_READY;
+				put_chip(map, chip, adr);
 				printk(KERN_ERR "MTD %s(): chip not ready after erase suspend\n", __func__);
 				return -EIO;
 			}
@@ -762,7 +761,6 @@
 
 	switch(chip->oldstate) {
 	case FL_ERASING:
-		chip->state = chip->oldstate;
 		map_write(map, cfi->sector_erase_cmd, chip->in_progress_block_addr);
 		chip->oldstate = FL_READY;
 		chip->state = FL_ERASING;
diff -druN linux-2.6.39-libre/drivers/mtd/chips/cfi_cmdset_0020.c linux-3.0-rc7-libre/drivers/mtd/chips/cfi_cmdset_0020.c
--- linux-2.6.39-libre/drivers/mtd/chips/cfi_cmdset_0020.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mtd/chips/cfi_cmdset_0020.c	2011-07-11 19:51:52.000000000 -0400
@@ -296,6 +296,7 @@
 				/* make sure we're in 'read status' mode */
 				map_write(map, CMD(0x70), cmd_addr);
 				chip->state = FL_ERASING;
+				wake_up(&chip->wq);
 				mutex_unlock(&chip->mutex);
 				printk(KERN_ERR "Chip not ready after erase "
 				       "suspended: status = 0x%lx\n", status.x[0]);
diff -druN linux-2.6.39-libre/drivers/mtd/devices/block2mtd.c linux-3.0-rc7-libre/drivers/mtd/devices/block2mtd.c
--- linux-2.6.39-libre/drivers/mtd/devices/block2mtd.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mtd/devices/block2mtd.c	2011-07-11 19:51:52.000000000 -0400
@@ -294,7 +294,7 @@
 	dev->mtd.priv = dev;
 	dev->mtd.owner = THIS_MODULE;
 
-	if (add_mtd_device(&dev->mtd)) {
+	if (mtd_device_register(&dev->mtd, NULL, 0)) {
 		/* Device didn't get added, so free the entry */
 		goto devinit_err;
 	}
@@ -465,7 +465,7 @@
 	list_for_each_safe(pos, next, &blkmtd_device_list) {
 		struct block2mtd_dev *dev = list_entry(pos, typeof(*dev), list);
 		block2mtd_sync(&dev->mtd);
-		del_mtd_device(&dev->mtd);
+		mtd_device_unregister(&dev->mtd);
 		INFO("mtd%d: [%s] removed", dev->mtd.index,
 				dev->mtd.name + strlen("block2mtd: "));
 		list_del(&dev->list);
diff -druN linux-2.6.39-libre/drivers/mtd/devices/doc2000.c linux-3.0-rc7-libre/drivers/mtd/devices/doc2000.c
--- linux-2.6.39-libre/drivers/mtd/devices/doc2000.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mtd/devices/doc2000.c	2011-07-11 19:51:52.000000000 -0400
@@ -597,7 +597,7 @@
 		doc2klist = mtd;
 		mtd->size = this->totlen;
 		mtd->erasesize = this->erasesize;
-		add_mtd_device(mtd);
+		mtd_device_register(mtd, NULL, 0);
 		return;
 	}
 }
@@ -1185,7 +1185,7 @@
 		this = mtd->priv;
 		doc2klist = this->nextdoc;
 
-		del_mtd_device(mtd);
+		mtd_device_unregister(mtd);
 
 		iounmap(this->virtadr);
 		kfree(this->chips);
diff -druN linux-2.6.39-libre/drivers/mtd/devices/doc2001.c linux-3.0-rc7-libre/drivers/mtd/devices/doc2001.c
--- linux-2.6.39-libre/drivers/mtd/devices/doc2001.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mtd/devices/doc2001.c	2011-07-11 19:51:52.000000000 -0400
@@ -376,7 +376,7 @@
 		this->nextdoc = docmillist;
 		docmillist = mtd;
 		mtd->size  = this->totlen;
-		add_mtd_device(mtd);
+		mtd_device_register(mtd, NULL, 0);
 		return;
 	}
 }
@@ -826,7 +826,7 @@
 		this = mtd->priv;
 		docmillist = this->nextdoc;
 
-		del_mtd_device(mtd);
+		mtd_device_unregister(mtd);
 
 		iounmap(this->virtadr);
 		kfree(this->chips);
diff -druN linux-2.6.39-libre/drivers/mtd/devices/doc2001plus.c linux-3.0-rc7-libre/drivers/mtd/devices/doc2001plus.c
--- linux-2.6.39-libre/drivers/mtd/devices/doc2001plus.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mtd/devices/doc2001plus.c	2011-07-11 19:51:52.000000000 -0400
@@ -499,7 +499,7 @@
 		docmilpluslist = mtd;
 		mtd->size  = this->totlen;
 		mtd->erasesize = this->erasesize;
-		add_mtd_device(mtd);
+		mtd_device_register(mtd, NULL, 0);
 		return;
 	}
 }
@@ -1091,7 +1091,7 @@
 		this = mtd->priv;
 		docmilpluslist = this->nextdoc;
 
-		del_mtd_device(mtd);
+		mtd_device_unregister(mtd);
 
 		iounmap(this->virtadr);
 		kfree(this->chips);
diff -druN linux-2.6.39-libre/drivers/mtd/devices/lart.c linux-3.0-rc7-libre/drivers/mtd/devices/lart.c
--- linux-2.6.39-libre/drivers/mtd/devices/lart.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mtd/devices/lart.c	2011-07-11 19:51:52.000000000 -0400
@@ -684,9 +684,10 @@
 #endif
 
 #ifndef HAVE_PARTITIONS
-   result = add_mtd_device (&mtd);
+   result = mtd_device_register(&mtd, NULL, 0);
 #else
-   result = add_mtd_partitions (&mtd,lart_partitions, ARRAY_SIZE(lart_partitions));
+   result = mtd_device_register(&mtd, lart_partitions,
+                                ARRAY_SIZE(lart_partitions));
 #endif
 
    return (result);
@@ -695,9 +696,9 @@
 static void __exit lart_flash_exit (void)
 {
 #ifndef HAVE_PARTITIONS
-   del_mtd_device (&mtd);
+   mtd_device_unregister(&mtd);
 #else
-   del_mtd_partitions (&mtd);
+   mtd_device_unregister(&mtd);
 #endif
 }
 
diff -druN linux-2.6.39-libre/drivers/mtd/devices/m25p80.c linux-3.0-rc7-libre/drivers/mtd/devices/m25p80.c
--- linux-2.6.39-libre/drivers/mtd/devices/m25p80.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mtd/devices/m25p80.c	2011-07-11 19:51:52.000000000 -0400
@@ -27,6 +27,7 @@
 #include <linux/sched.h>
 #include <linux/mod_devicetable.h>
 
+#include <linux/mtd/cfi.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/partitions.h>
 
@@ -55,6 +56,9 @@
 #define	OPCODE_EN4B		0xb7	/* Enter 4-byte mode */
 #define	OPCODE_EX4B		0xe9	/* Exit 4-byte mode */
 
+/* Used for Spansion flashes only. */
+#define	OPCODE_BRWR		0x17	/* Bank register write */
+
 /* Status Register bits. */
 #define	SR_WIP			1	/* Write in progress */
 #define	SR_WEL			2	/* Write enable latch */
@@ -76,6 +80,8 @@
 #define FAST_READ_DUMMY_BYTE 0
 #endif
 
+#define JEDEC_MFR(_jedec_id)	((_jedec_id) >> 16)
+
 /****************************************************************************/
 
 struct m25p {
@@ -158,11 +164,18 @@
 /*
  * Enable/disable 4-byte addressing mode.
  */
-static inline int set_4byte(struct m25p *flash, int enable)
+static inline int set_4byte(struct m25p *flash, u32 jedec_id, int enable)
 {
-	u8	code = enable ? OPCODE_EN4B : OPCODE_EX4B;
-
-	return spi_write_then_read(flash->spi, &code, 1, NULL, 0);
+	switch (JEDEC_MFR(jedec_id)) {
+	case CFI_MFR_MACRONIX:
+		flash->command[0] = enable ? OPCODE_EN4B : OPCODE_EX4B;
+		return spi_write(flash->spi, flash->command, 1);
+	default:
+		/* Spansion style */
+		flash->command[0] = OPCODE_BRWR;
+		flash->command[1] = enable << 7;
+		return spi_write(flash->spi, flash->command, 2);
+	}
 }
 
 /*
@@ -668,6 +681,7 @@
 	/* Macronix */
 	{ "mx25l4005a",  INFO(0xc22013, 0, 64 * 1024,   8, SECT_4K) },
 	{ "mx25l8005",   INFO(0xc22014, 0, 64 * 1024,  16, 0) },
+	{ "mx25l1606e",  INFO(0xc22015, 0, 64 * 1024,  32, SECT_4K) },
 	{ "mx25l3205d",  INFO(0xc22016, 0, 64 * 1024,  64, 0) },
 	{ "mx25l6405d",  INFO(0xc22017, 0, 64 * 1024, 128, 0) },
 	{ "mx25l12805d", INFO(0xc22018, 0, 64 * 1024, 256, 0) },
@@ -684,6 +698,10 @@
 	{ "s25sl032a",  INFO(0x010215,      0,  64 * 1024,  64, 0) },
 	{ "s25sl032p",  INFO(0x010215, 0x4d00,  64 * 1024,  64, SECT_4K) },
 	{ "s25sl064a",  INFO(0x010216,      0,  64 * 1024, 128, 0) },
+	{ "s25fl256s0", INFO(0x010219, 0x4d00, 256 * 1024, 128, 0) },
+	{ "s25fl256s1", INFO(0x010219, 0x4d01,  64 * 1024, 512, 0) },
+	{ "s25fl512s",  INFO(0x010220, 0x4d00, 256 * 1024, 256, 0) },
+	{ "s70fl01gs",  INFO(0x010221, 0x4d00, 256 * 1024, 256, 0) },
 	{ "s25sl12800", INFO(0x012018, 0x0300, 256 * 1024,  64, 0) },
 	{ "s25sl12801", INFO(0x012018, 0x0301,  64 * 1024, 256, 0) },
 	{ "s25fl129p0", INFO(0x012018, 0x4d00, 256 * 1024,  64, 0) },
@@ -729,7 +747,10 @@
 	{ "m25pe80", INFO(0x208014,  0, 64 * 1024, 16,       0) },
 	{ "m25pe16", INFO(0x208015,  0, 64 * 1024, 32, SECT_4K) },
 
-	{ "m25px64", INFO(0x207117,  0, 64 * 1024, 128, 0) },
+	{ "m25px32",    INFO(0x207116,  0, 64 * 1024, 64, SECT_4K) },
+	{ "m25px32-s0", INFO(0x207316,  0, 64 * 1024, 64, SECT_4K) },
+	{ "m25px32-s1", INFO(0x206316,  0, 64 * 1024, 64, SECT_4K) },
+	{ "m25px64",    INFO(0x207117,  0, 64 * 1024, 128, 0) },
 
 	/* Winbond -- w25x "blocks" are 64K, "sectors" are 4KiB */
 	{ "w25x10", INFO(0xef3011, 0, 64 * 1024,  2,  SECT_4K) },
@@ -804,6 +825,8 @@
 	struct m25p			*flash;
 	struct flash_info		*info;
 	unsigned			i;
+	struct mtd_partition		*parts = NULL;
+	int				nr_parts = 0;
 
 	/* Platform data helps sort out which chip type we have, as
 	 * well as how this board partitions it.  If we don't have
@@ -868,9 +891,9 @@
 	 * up with the software protection bits set
 	 */
 
-	if (info->jedec_id >> 16 == 0x1f ||
-	    info->jedec_id >> 16 == 0x89 ||
-	    info->jedec_id >> 16 == 0xbf) {
+	if (JEDEC_MFR(info->jedec_id) == CFI_MFR_ATMEL ||
+	    JEDEC_MFR(info->jedec_id) == CFI_MFR_INTEL ||
+	    JEDEC_MFR(info->jedec_id) == CFI_MFR_SST) {
 		write_enable(flash);
 		write_sr(flash, 0);
 	}
@@ -888,7 +911,7 @@
 	flash->mtd.read = m25p80_read;
 
 	/* sst flash chips use AAI word program */
-	if (info->jedec_id >> 16 == 0xbf)
+	if (JEDEC_MFR(info->jedec_id) == CFI_MFR_SST)
 		flash->mtd.write = sst_write;
 	else
 		flash->mtd.write = m25p80_write;
@@ -914,7 +937,7 @@
 		/* enable 4-byte addressing if the device exceeds 16MiB */
 		if (flash->mtd.size > 0x1000000) {
 			flash->addr_width = 4;
-			set_4byte(flash, 1);
+			set_4byte(flash, info->jedec_id, 1);
 		} else
 			flash->addr_width = 3;
 	}
@@ -945,48 +968,41 @@
 	/* partitions should match sector boundaries; and it may be good to
 	 * use readonly partitions for writeprotected sectors (BP2..BP0).
 	 */
-	if (mtd_has_partitions()) {
-		struct mtd_partition	*parts = NULL;
-		int			nr_parts = 0;
-
-		if (mtd_has_cmdlinepart()) {
-			static const char *part_probes[]
-					= { "cmdlinepart", NULL, };
+	if (mtd_has_cmdlinepart()) {
+		static const char *part_probes[]
+			= { "cmdlinepart", NULL, };
 
-			nr_parts = parse_mtd_partitions(&flash->mtd,
-					part_probes, &parts, 0);
-		}
+		nr_parts = parse_mtd_partitions(&flash->mtd,
+						part_probes, &parts, 0);
+	}
 
-		if (nr_parts <= 0 && data && data->parts) {
-			parts = data->parts;
-			nr_parts = data->nr_parts;
-		}
+	if (nr_parts <= 0 && data && data->parts) {
+		parts = data->parts;
+		nr_parts = data->nr_parts;
+	}
 
 #ifdef CONFIG_MTD_OF_PARTS
-		if (nr_parts <= 0 && spi->dev.of_node) {
-			nr_parts = of_mtd_parse_partitions(&spi->dev,
-					spi->dev.of_node, &parts);
-		}
+	if (nr_parts <= 0 && spi->dev.of_node) {
+		nr_parts = of_mtd_parse_partitions(&spi->dev,
+						   spi->dev.of_node, &parts);
+	}
 #endif
 
-		if (nr_parts > 0) {
-			for (i = 0; i < nr_parts; i++) {
-				DEBUG(MTD_DEBUG_LEVEL2, "partitions[%d] = "
-					"{.name = %s, .offset = 0x%llx, "
-						".size = 0x%llx (%lldKiB) }\n",
-					i, parts[i].name,
-					(long long)parts[i].offset,
-					(long long)parts[i].size,
-					(long long)(parts[i].size >> 10));
-			}
-			flash->partitioned = 1;
-			return add_mtd_partitions(&flash->mtd, parts, nr_parts);
+	if (nr_parts > 0) {
+		for (i = 0; i < nr_parts; i++) {
+			DEBUG(MTD_DEBUG_LEVEL2, "partitions[%d] = "
+			      "{.name = %s, .offset = 0x%llx, "
+			      ".size = 0x%llx (%lldKiB) }\n",
+			      i, parts[i].name,
+			      (long long)parts[i].offset,
+			      (long long)parts[i].size,
+			      (long long)(parts[i].size >> 10));
 		}
-	} else if (data && data->nr_parts)
-		dev_warn(&spi->dev, "ignoring %d default partitions on %s\n",
-				data->nr_parts, data->name);
+		flash->partitioned = 1;
+	}
 
-	return add_mtd_device(&flash->mtd) == 1 ? -ENODEV : 0;
+	return mtd_device_register(&flash->mtd, parts, nr_parts) == 1 ?
+		-ENODEV : 0;
 }
 
 
@@ -996,10 +1012,7 @@
 	int		status;
 
 	/* Clean up MTD stuff. */
-	if (mtd_has_partitions() && flash->partitioned)
-		status = del_mtd_partitions(&flash->mtd);
-	else
-		status = del_mtd_device(&flash->mtd);
+	status = mtd_device_unregister(&flash->mtd);
 	if (status == 0) {
 		kfree(flash->command);
 		kfree(flash);
diff -druN linux-2.6.39-libre/drivers/mtd/devices/ms02-nv.c linux-3.0-rc7-libre/drivers/mtd/devices/ms02-nv.c
--- linux-2.6.39-libre/drivers/mtd/devices/ms02-nv.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mtd/devices/ms02-nv.c	2011-07-11 19:51:52.000000000 -0400
@@ -220,7 +220,7 @@
 	mtd->writesize = 1;
 
 	ret = -EIO;
-	if (add_mtd_device(mtd)) {
+	if (mtd_device_register(mtd, NULL, 0)) {
 		printk(KERN_ERR
 			"ms02-nv: Unable to register MTD device, aborting!\n");
 		goto err_out_csr_res;
@@ -262,7 +262,7 @@
 
 	root_ms02nv_mtd = mp->next;
 
-	del_mtd_device(mtd);
+	mtd_device_unregister(mtd);
 
 	release_resource(mp->resource.csr);
 	kfree(mp->resource.csr);
diff -druN linux-2.6.39-libre/drivers/mtd/devices/mtd_dataflash.c linux-3.0-rc7-libre/drivers/mtd/devices/mtd_dataflash.c
--- linux-2.6.39-libre/drivers/mtd/devices/mtd_dataflash.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mtd/devices/mtd_dataflash.c	2011-07-11 19:51:52.000000000 -0400
@@ -637,6 +637,8 @@
 	struct flash_platform_data	*pdata = spi->dev.platform_data;
 	char				*otp_tag = "";
 	int				err = 0;
+	struct mtd_partition		*parts;
+	int				nr_parts = 0;
 
 	priv = kzalloc(sizeof *priv, GFP_KERNEL);
 	if (!priv)
@@ -675,33 +677,25 @@
 			pagesize, otp_tag);
 	dev_set_drvdata(&spi->dev, priv);
 
-	if (mtd_has_partitions()) {
-		struct mtd_partition	*parts;
-		int			nr_parts = 0;
-
-		if (mtd_has_cmdlinepart()) {
-			static const char *part_probes[]
-					= { "cmdlinepart", NULL, };
+	if (mtd_has_cmdlinepart()) {
+		static const char *part_probes[] = { "cmdlinepart", NULL, };
 
-			nr_parts = parse_mtd_partitions(device,
-					part_probes, &parts, 0);
-		}
+		nr_parts = parse_mtd_partitions(device, part_probes, &parts,
+						0);
+	}
 
-		if (nr_parts <= 0 && pdata && pdata->parts) {
-			parts = pdata->parts;
-			nr_parts = pdata->nr_parts;
-		}
+	if (nr_parts <= 0 && pdata && pdata->parts) {
+		parts = pdata->parts;
+		nr_parts = pdata->nr_parts;
+	}
 
-		if (nr_parts > 0) {
-			priv->partitioned = 1;
-			err = add_mtd_partitions(device, parts, nr_parts);
-			goto out;
-		}
-	} else if (pdata && pdata->nr_parts)
-		dev_warn(&spi->dev, "ignoring %d default partitions on %s\n",
-				pdata->nr_parts, device->name);
+	if (nr_parts > 0) {
+		priv->partitioned = 1;
+		err = mtd_device_register(device, parts, nr_parts);
+		goto out;
+	}
 
-	if (add_mtd_device(device) == 1)
+	if (mtd_device_register(device, NULL, 0) == 1)
 		err = -ENODEV;
 
 out:
@@ -939,10 +933,7 @@
 
 	DEBUG(MTD_DEBUG_LEVEL1, "%s: remove\n", dev_name(&spi->dev));
 
-	if (mtd_has_partitions() && flash->partitioned)
-		status = del_mtd_partitions(&flash->mtd);
-	else
-		status = del_mtd_device(&flash->mtd);
+	status = mtd_device_unregister(&flash->mtd);
 	if (status == 0) {
 		dev_set_drvdata(&spi->dev, NULL);
 		kfree(flash);
diff -druN linux-2.6.39-libre/drivers/mtd/devices/mtdram.c linux-3.0-rc7-libre/drivers/mtd/devices/mtdram.c
--- linux-2.6.39-libre/drivers/mtd/devices/mtdram.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mtd/devices/mtdram.c	2011-07-11 19:51:52.000000000 -0400
@@ -104,7 +104,7 @@
 static void __exit cleanup_mtdram(void)
 {
 	if (mtd_info) {
-		del_mtd_device(mtd_info);
+		mtd_device_unregister(mtd_info);
 		vfree(mtd_info->priv);
 		kfree(mtd_info);
 	}
@@ -133,9 +133,8 @@
 	mtd->read = ram_read;
 	mtd->write = ram_write;
 
-	if (add_mtd_device(mtd)) {
+	if (mtd_device_register(mtd, NULL, 0))
 		return -EIO;
-	}
 
 	return 0;
 }
diff -druN linux-2.6.39-libre/drivers/mtd/devices/phram.c linux-3.0-rc7-libre/drivers/mtd/devices/phram.c
--- linux-2.6.39-libre/drivers/mtd/devices/phram.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mtd/devices/phram.c	2011-07-11 19:51:52.000000000 -0400
@@ -115,7 +115,7 @@
 	struct phram_mtd_list *this, *safe;
 
 	list_for_each_entry_safe(this, safe, &phram_list, list) {
-		del_mtd_device(&this->mtd);
+		mtd_device_unregister(&this->mtd);
 		iounmap(this->mtd.priv);
 		kfree(this->mtd.name);
 		kfree(this);
@@ -153,7 +153,7 @@
 	new->mtd.writesize = 1;
 
 	ret = -EAGAIN;
-	if (add_mtd_device(&new->mtd)) {
+	if (mtd_device_register(&new->mtd, NULL, 0)) {
 		pr_err("Failed to register new device\n");
 		goto out2;
 	}
diff -druN linux-2.6.39-libre/drivers/mtd/devices/pmc551.c linux-3.0-rc7-libre/drivers/mtd/devices/pmc551.c
--- linux-2.6.39-libre/drivers/mtd/devices/pmc551.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mtd/devices/pmc551.c	2011-07-11 19:51:52.000000000 -0400
@@ -798,7 +798,7 @@
 		mtd->writesize = 1;
 		mtd->owner = THIS_MODULE;
 
-		if (add_mtd_device(mtd)) {
+		if (mtd_device_register(mtd, NULL, 0)) {
 			printk(KERN_NOTICE "pmc551: Failed to register new device\n");
 			pci_iounmap(PCI_Device, priv->start);
 			kfree(mtd->priv);
@@ -806,7 +806,7 @@
 			break;
 		}
 
-		/* Keep a reference as the add_mtd_device worked */
+		/* Keep a reference as the mtd_device_register worked */
 		pci_dev_get(PCI_Device);
 
 		printk(KERN_NOTICE "Registered pmc551 memory device.\n");
@@ -856,7 +856,7 @@
 		pci_dev_put(priv->dev);
 
 		kfree(mtd->priv);
-		del_mtd_device(mtd);
+		mtd_device_unregister(mtd);
 		kfree(mtd);
 		found++;
 	}
diff -druN linux-2.6.39-libre/drivers/mtd/devices/slram.c linux-3.0-rc7-libre/drivers/mtd/devices/slram.c
--- linux-2.6.39-libre/drivers/mtd/devices/slram.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mtd/devices/slram.c	2011-07-11 19:51:52.000000000 -0400
@@ -210,7 +210,7 @@
 	(*curmtd)->mtdinfo->erasesize = SLRAM_BLK_SZ;
 	(*curmtd)->mtdinfo->writesize = 1;
 
-	if (add_mtd_device((*curmtd)->mtdinfo))	{
+	if (mtd_device_register((*curmtd)->mtdinfo, NULL, 0))	{
 		E("slram: Failed to register new device\n");
 		iounmap(((slram_priv_t *)(*curmtd)->mtdinfo->priv)->start);
 		kfree((*curmtd)->mtdinfo->priv);
@@ -231,7 +231,7 @@
 
 	while (slram_mtdlist) {
 		nextitem = slram_mtdlist->next;
-		del_mtd_device(slram_mtdlist->mtdinfo);
+		mtd_device_unregister(slram_mtdlist->mtdinfo);
 		iounmap(((slram_priv_t *)slram_mtdlist->mtdinfo->priv)->start);
 		kfree(slram_mtdlist->mtdinfo->priv);
 		kfree(slram_mtdlist->mtdinfo);
diff -druN linux-2.6.39-libre/drivers/mtd/devices/sst25l.c linux-3.0-rc7-libre/drivers/mtd/devices/sst25l.c
--- linux-2.6.39-libre/drivers/mtd/devices/sst25l.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mtd/devices/sst25l.c	2011-07-11 19:51:52.000000000 -0400
@@ -66,7 +66,7 @@
 
 #define to_sst25l_flash(x) container_of(x, struct sst25l_flash, mtd)
 
-static struct flash_info __initdata sst25l_flash_info[] = {
+static struct flash_info __devinitdata sst25l_flash_info[] = {
 	{"sst25lf020a", 0xbf43, 256, 1024, 4096},
 	{"sst25lf040a",	0xbf44,	256, 2048, 4096},
 };
@@ -381,6 +381,8 @@
 	struct sst25l_flash *flash;
 	struct flash_platform_data *data;
 	int ret, i;
+	struct mtd_partition *parts = NULL;
+	int nr_parts = 0;
 
 	flash_info = sst25l_match_device(spi);
 	if (!flash_info)
@@ -420,46 +422,37 @@
 	      flash->mtd.erasesize, flash->mtd.erasesize / 1024,
 	      flash->mtd.numeraseregions);
 
-	if (mtd_has_partitions()) {
-		struct mtd_partition *parts = NULL;
-		int nr_parts = 0;
 
-		if (mtd_has_cmdlinepart()) {
-			static const char *part_probes[] =
-				{"cmdlinepart", NULL};
-
-			nr_parts = parse_mtd_partitions(&flash->mtd,
-							part_probes,
-							&parts, 0);
-		}
+	if (mtd_has_cmdlinepart()) {
+		static const char *part_probes[] = {"cmdlinepart", NULL};
 
-		if (nr_parts <= 0 && data && data->parts) {
-			parts = data->parts;
-			nr_parts = data->nr_parts;
-		}
+		nr_parts = parse_mtd_partitions(&flash->mtd,
+						part_probes,
+						&parts, 0);
+	}
 
-		if (nr_parts > 0) {
-			for (i = 0; i < nr_parts; i++) {
-				DEBUG(MTD_DEBUG_LEVEL2, "partitions[%d] = "
-				      "{.name = %s, .offset = 0x%llx, "
-				      ".size = 0x%llx (%lldKiB) }\n",
-				      i, parts[i].name,
-				      (long long)parts[i].offset,
-				      (long long)parts[i].size,
-				      (long long)(parts[i].size >> 10));
-			}
+	if (nr_parts <= 0 && data && data->parts) {
+		parts = data->parts;
+		nr_parts = data->nr_parts;
+	}
 
-			flash->partitioned = 1;
-			return add_mtd_partitions(&flash->mtd,
-						  parts, nr_parts);
+	if (nr_parts > 0) {
+		for (i = 0; i < nr_parts; i++) {
+			DEBUG(MTD_DEBUG_LEVEL2, "partitions[%d] = "
+			      "{.name = %s, .offset = 0x%llx, "
+			      ".size = 0x%llx (%lldKiB) }\n",
+			      i, parts[i].name,
+			      (long long)parts[i].offset,
+			      (long long)parts[i].size,
+			      (long long)(parts[i].size >> 10));
 		}
 
-	} else if (data && data->nr_parts) {
-		dev_warn(&spi->dev, "ignoring %d default partitions on %s\n",
-			 data->nr_parts, data->name);
+		flash->partitioned = 1;
+		return mtd_device_register(&flash->mtd, parts,
+					   nr_parts);
 	}
 
-	ret = add_mtd_device(&flash->mtd);
+	ret = mtd_device_register(&flash->mtd, NULL, 0);
 	if (ret == 1) {
 		kfree(flash);
 		dev_set_drvdata(&spi->dev, NULL);
@@ -469,15 +462,12 @@
 	return 0;
 }
 
-static int __exit sst25l_remove(struct spi_device *spi)
+static int __devexit sst25l_remove(struct spi_device *spi)
 {
 	struct sst25l_flash *flash = dev_get_drvdata(&spi->dev);
 	int ret;
 
-	if (mtd_has_partitions() && flash->partitioned)
-		ret = del_mtd_partitions(&flash->mtd);
-	else
-		ret = del_mtd_device(&flash->mtd);
+	ret = mtd_device_unregister(&flash->mtd);
 	if (ret == 0)
 		kfree(flash);
 	return ret;
@@ -490,7 +480,7 @@
 		.owner	= THIS_MODULE,
 	},
 	.probe		= sst25l_probe,
-	.remove		= __exit_p(sst25l_remove),
+	.remove		= __devexit_p(sst25l_remove),
 };
 
 static int __init sst25l_init(void)
diff -druN linux-2.6.39-libre/drivers/mtd/Kconfig linux-3.0-rc7-libre/drivers/mtd/Kconfig
--- linux-2.6.39-libre/drivers/mtd/Kconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mtd/Kconfig	2011-07-11 19:51:52.000000000 -0400
@@ -33,20 +33,6 @@
 	  should normally be compiled as kernel modules. The modules perform
 	  various checks and verifications when loaded.
 
-config MTD_PARTITIONS
-	bool "MTD partitioning support"
-	help
-	  If you have a device which needs to divide its flash chip(s) up
-	  into multiple 'partitions', each of which appears to the user as
-	  a separate MTD device, you require this option to be enabled. If
-	  unsure, say 'Y'.
-
-	  Note, however, that you don't need this option for the DiskOnChip
-	  devices. Partitioning on NFTL 'devices' is a different - that's the
-	  'normal' form of partitioning used on a block device.
-
-if MTD_PARTITIONS
-
 config MTD_REDBOOT_PARTS
 	tristate "RedBoot partition table parsing"
 	---help---
@@ -99,7 +85,7 @@
 
 config MTD_CMDLINE_PARTS
 	bool "Command line partition table parsing"
-	depends on MTD_PARTITIONS = "y" && MTD = "y"
+	depends on MTD = "y"
 	---help---
 	  Allow generic configuration of the MTD partition tables via the kernel
 	  command line. Multiple flash resources are supported for hardware where
@@ -148,8 +134,7 @@
 
 	  You will still need the parsing functions to be called by the driver
 	  for your particular device. It won't happen automatically. The
-	  'armflash' map driver (CONFIG_MTD_ARM_INTEGRATOR) does this, for
-	  example.
+	  'physmap' map driver (CONFIG_MTD_PHYSMAP) does this, for example.
 
 config MTD_OF_PARTS
 	def_bool y
@@ -164,8 +149,6 @@
 	---help---
 	  TI AR7 partitioning support
 
-endif # MTD_PARTITIONS
-
 comment "User Modules And Translation Layers"
 
 config MTD_CHAR
diff -druN linux-2.6.39-libre/drivers/mtd/lpddr/lpddr_cmds.c linux-3.0-rc7-libre/drivers/mtd/lpddr/lpddr_cmds.c
--- linux-2.6.39-libre/drivers/mtd/lpddr/lpddr_cmds.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mtd/lpddr/lpddr_cmds.c	2011-07-11 19:51:52.000000000 -0400
@@ -313,12 +313,7 @@
 		if (ret) {
 			/* Oops. something got wrong. */
 			/* Resume and pretend we weren't here.  */
-			map_write(map, CMD(LPDDR_RESUME),
-				map->pfow_base + PFOW_COMMAND_CODE);
-			map_write(map, CMD(LPDDR_START_EXECUTION),
-				map->pfow_base + PFOW_COMMAND_EXECUTE);
-			chip->state = FL_ERASING;
-			chip->oldstate = FL_READY;
+			put_chip(map, chip);
 			printk(KERN_ERR "%s: suspend operation failed."
 					"State may be wrong \n", map->name);
 			return -EIO;
@@ -383,7 +378,6 @@
 
 	switch (chip->oldstate) {
 	case FL_ERASING:
-		chip->state = chip->oldstate;
 		map_write(map, CMD(LPDDR_RESUME),
 				map->pfow_base + PFOW_COMMAND_CODE);
 		map_write(map, CMD(LPDDR_START_EXECUTION),
diff -druN linux-2.6.39-libre/drivers/mtd/Makefile linux-3.0-rc7-libre/drivers/mtd/Makefile
--- linux-2.6.39-libre/drivers/mtd/Makefile	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mtd/Makefile	2011-07-11 19:51:52.000000000 -0400
@@ -4,8 +4,7 @@
 
 # Core functionality.
 obj-$(CONFIG_MTD)		+= mtd.o
-mtd-y				:= mtdcore.o mtdsuper.o mtdconcat.o
-mtd-$(CONFIG_MTD_PARTITIONS)	+= mtdpart.o
+mtd-y				:= mtdcore.o mtdsuper.o mtdconcat.o mtdpart.o
 mtd-$(CONFIG_MTD_OF_PARTS)	+= ofpart.o
 
 obj-$(CONFIG_MTD_REDBOOT_PARTS) += redboot.o
diff -druN linux-2.6.39-libre/drivers/mtd/maps/amd76xrom.c linux-3.0-rc7-libre/drivers/mtd/maps/amd76xrom.c
--- linux-2.6.39-libre/drivers/mtd/maps/amd76xrom.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mtd/maps/amd76xrom.c	2011-07-11 19:51:52.000000000 -0400
@@ -82,7 +82,7 @@
 		if (map->rsrc.parent) {
 			release_resource(&map->rsrc);
 		}
-		del_mtd_device(map->mtd);
+		mtd_device_unregister(map->mtd);
 		map_destroy(map->mtd);
 		list_del(&map->list);
 		kfree(map);
@@ -262,7 +262,7 @@
 
 		/* Now that the mtd devices is complete claim and export it */
 		map->mtd->owner = THIS_MODULE;
-		if (add_mtd_device(map->mtd)) {
+		if (mtd_device_register(map->mtd, NULL, 0)) {
 			map_destroy(map->mtd);
 			map->mtd = NULL;
 			goto out;
diff -druN linux-2.6.39-libre/drivers/mtd/maps/autcpu12-nvram.c linux-3.0-rc7-libre/drivers/mtd/maps/autcpu12-nvram.c
--- linux-2.6.39-libre/drivers/mtd/maps/autcpu12-nvram.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mtd/maps/autcpu12-nvram.c	2011-07-11 19:51:52.000000000 -0400
@@ -88,7 +88,7 @@
 	sram_mtd->owner = THIS_MODULE;
 	sram_mtd->erasesize = 16;
 
-	if (add_mtd_device(sram_mtd)) {
+	if (mtd_device_register(sram_mtd, NULL, 0)) {
 		printk("NV-RAM device addition failed\n");
 		err = -ENOMEM;
 		goto out_probe;
@@ -111,7 +111,7 @@
 static void __exit cleanup_autcpu12_maps(void)
 {
 	if (sram_mtd) {
-		del_mtd_device(sram_mtd);
+		mtd_device_unregister(sram_mtd);
 		map_destroy(sram_mtd);
 		iounmap((void *)autcpu12_sram_map.virt);
 	}
diff -druN linux-2.6.39-libre/drivers/mtd/maps/bcm963xx-flash.c linux-3.0-rc7-libre/drivers/mtd/maps/bcm963xx-flash.c
--- linux-2.6.39-libre/drivers/mtd/maps/bcm963xx-flash.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mtd/maps/bcm963xx-flash.c	2011-07-11 19:51:52.000000000 -0400
@@ -224,8 +224,8 @@
 		goto err_probe;
 	}
 
-	return add_mtd_partitions(bcm963xx_mtd_info, parsed_parts,
-						parsed_nr_parts);
+	return mtd_device_register(bcm963xx_mtd_info, parsed_parts,
+				   parsed_nr_parts);
 
 err_probe:
 	iounmap(bcm963xx_map.virt);
@@ -235,7 +235,7 @@
 static int bcm963xx_remove(struct platform_device *pdev)
 {
 	if (bcm963xx_mtd_info) {
-		del_mtd_partitions(bcm963xx_mtd_info);
+		mtd_device_unregister(bcm963xx_mtd_info);
 		map_destroy(bcm963xx_mtd_info);
 	}
 
diff -druN linux-2.6.39-libre/drivers/mtd/maps/bfin-async-flash.c linux-3.0-rc7-libre/drivers/mtd/maps/bfin-async-flash.c
--- linux-2.6.39-libre/drivers/mtd/maps/bfin-async-flash.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mtd/maps/bfin-async-flash.c	2011-07-11 19:51:52.000000000 -0400
@@ -41,9 +41,7 @@
 	uint32_t flash_ambctl0, flash_ambctl1;
 	uint32_t save_ambctl0, save_ambctl1;
 	unsigned long irq_flags;
-#ifdef CONFIG_MTD_PARTITIONS
 	struct mtd_partition *parts;
-#endif
 };
 
 static void switch_to_flash(struct async_state *state)
@@ -124,9 +122,7 @@
 	switch_back(state);
 }
 
-#ifdef CONFIG_MTD_PARTITIONS
 static const char *part_probe_types[] = { "cmdlinepart", "RedBoot", NULL };
-#endif
 
 static int __devinit bfin_flash_probe(struct platform_device *pdev)
 {
@@ -169,22 +165,17 @@
 		return -ENXIO;
 	}
 
-#ifdef CONFIG_MTD_PARTITIONS
 	ret = parse_mtd_partitions(state->mtd, part_probe_types, &pdata->parts, 0);
 	if (ret > 0) {
 		pr_devinit(KERN_NOTICE DRIVER_NAME ": Using commandline partition definition\n");
-		add_mtd_partitions(state->mtd, pdata->parts, ret);
+		mtd_device_register(state->mtd, pdata->parts, ret);
 		state->parts = pdata->parts;
-
 	} else if (pdata->nr_parts) {
 		pr_devinit(KERN_NOTICE DRIVER_NAME ": Using board partition definition\n");
-		add_mtd_partitions(state->mtd, pdata->parts, pdata->nr_parts);
-
-	} else
-#endif
-	{
+		mtd_device_register(state->mtd, pdata->parts, pdata->nr_parts);
+	} else {
 		pr_devinit(KERN_NOTICE DRIVER_NAME ": no partition info available, registering whole flash at once\n");
-		add_mtd_device(state->mtd);
+		mtd_device_register(state->mtd, NULL, 0);
 	}
 
 	platform_set_drvdata(pdev, state);
@@ -196,10 +187,8 @@
 {
 	struct async_state *state = platform_get_drvdata(pdev);
 	gpio_free(state->enet_flash_pin);
-#ifdef CONFIG_MTD_PARTITIONS
-	del_mtd_partitions(state->mtd);
+	mtd_device_unregister(state->mtd);
 	kfree(state->parts);
-#endif
 	map_destroy(state->mtd);
 	kfree(state);
 	return 0;
diff -druN linux-2.6.39-libre/drivers/mtd/maps/cdb89712.c linux-3.0-rc7-libre/drivers/mtd/maps/cdb89712.c
--- linux-2.6.39-libre/drivers/mtd/maps/cdb89712.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mtd/maps/cdb89712.c	2011-07-11 19:51:52.000000000 -0400
@@ -75,7 +75,7 @@
 
 	flash_mtd->owner = THIS_MODULE;
 
-	if (add_mtd_device(flash_mtd)) {
+	if (mtd_device_register(flash_mtd, NULL, 0)) {
 		printk("FLASH device addition failed\n");
 		err = -ENOMEM;
 		goto out_probe;
@@ -141,7 +141,7 @@
 	sram_mtd->owner = THIS_MODULE;
 	sram_mtd->erasesize = 16;
 
-	if (add_mtd_device(sram_mtd)) {
+	if (mtd_device_register(sram_mtd, NULL, 0)) {
 		printk("SRAM device addition failed\n");
 		err = -ENOMEM;
 		goto out_probe;
@@ -209,7 +209,7 @@
 	bootrom_mtd->owner = THIS_MODULE;
 	bootrom_mtd->erasesize = 0x10000;
 
-	if (add_mtd_device(bootrom_mtd)) {
+	if (mtd_device_register(bootrom_mtd, NULL, 0)) {
 		printk("BootROM device addition failed\n");
 		err = -ENOMEM;
 		goto out_probe;
@@ -249,21 +249,21 @@
 static void __exit cleanup_cdb89712_maps(void)
 {
 	if (sram_mtd) {
-		del_mtd_device(sram_mtd);
+		mtd_device_unregister(sram_mtd);
 		map_destroy(sram_mtd);
 		iounmap((void *)cdb89712_sram_map.virt);
 		release_resource (&cdb89712_sram_resource);
 	}
 
 	if (flash_mtd) {
-		del_mtd_device(flash_mtd);
+		mtd_device_unregister(flash_mtd);
 		map_destroy(flash_mtd);
 		iounmap((void *)cdb89712_flash_map.virt);
 		release_resource (&cdb89712_flash_resource);
 	}
 
 	if (bootrom_mtd) {
-		del_mtd_device(bootrom_mtd);
+		mtd_device_unregister(bootrom_mtd);
 		map_destroy(bootrom_mtd);
 		iounmap((void *)cdb89712_bootrom_map.virt);
 		release_resource (&cdb89712_bootrom_resource);
diff -druN linux-2.6.39-libre/drivers/mtd/maps/ceiva.c linux-3.0-rc7-libre/drivers/mtd/maps/ceiva.c
--- linux-2.6.39-libre/drivers/mtd/maps/ceiva.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mtd/maps/ceiva.c	2011-07-11 19:51:52.000000000 -0400
@@ -224,7 +224,7 @@
 {
 	int i;
 
-	del_mtd_partitions(mtd);
+	mtd_device_unregister(mtd);
 
 	if (mtd != clps[0].mtd)
 		mtd_concat_destroy(mtd);
@@ -292,11 +292,11 @@
 	if (nr_parts == 0) {
 		printk(KERN_NOTICE "clps flash: no partition info "
 			"available, registering whole flash\n");
-		add_mtd_device(mtd);
+		mtd_device_register(mtd, NULL, 0);
 	} else {
 		printk(KERN_NOTICE "clps flash: using %s partition "
 			"definition\n", part_type);
-		add_mtd_partitions(mtd, parsed_parts, nr_parts);
+		mtd_device_register(mtd, parsed_parts, nr_parts);
 	}
 
 	/* Always succeeds. */
diff -druN linux-2.6.39-libre/drivers/mtd/maps/cfi_flagadm.c linux-3.0-rc7-libre/drivers/mtd/maps/cfi_flagadm.c
--- linux-2.6.39-libre/drivers/mtd/maps/cfi_flagadm.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mtd/maps/cfi_flagadm.c	2011-07-11 19:51:52.000000000 -0400
@@ -107,7 +107,7 @@
 	mymtd = do_map_probe("cfi_probe", &flagadm_map);
 	if (mymtd) {
 		mymtd->owner = THIS_MODULE;
-		add_mtd_partitions(mymtd, flagadm_parts, PARTITION_COUNT);
+		mtd_device_register(mymtd, flagadm_parts, PARTITION_COUNT);
 		printk(KERN_NOTICE "FlagaDM flash device initialized\n");
 		return 0;
 	}
@@ -119,7 +119,7 @@
 static void __exit cleanup_flagadm(void)
 {
 	if (mymtd) {
-		del_mtd_partitions(mymtd);
+		mtd_device_unregister(mymtd);
 		map_destroy(mymtd);
 	}
 	if (flagadm_map.virt) {
diff -druN linux-2.6.39-libre/drivers/mtd/maps/ck804xrom.c linux-3.0-rc7-libre/drivers/mtd/maps/ck804xrom.c
--- linux-2.6.39-libre/drivers/mtd/maps/ck804xrom.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mtd/maps/ck804xrom.c	2011-07-11 19:51:52.000000000 -0400
@@ -94,7 +94,7 @@
 		if (map->rsrc.parent)
 			release_resource(&map->rsrc);
 
-		del_mtd_device(map->mtd);
+		mtd_device_unregister(map->mtd);
 		map_destroy(map->mtd);
 		list_del(&map->list);
 		kfree(map);
@@ -291,7 +291,7 @@
 
 		/* Now that the mtd devices is complete claim and export it */
 		map->mtd->owner = THIS_MODULE;
-		if (add_mtd_device(map->mtd)) {
+		if (mtd_device_register(map->mtd, NULL, 0)) {
 			map_destroy(map->mtd);
 			map->mtd = NULL;
 			goto out;
diff -druN linux-2.6.39-libre/drivers/mtd/maps/dbox2-flash.c linux-3.0-rc7-libre/drivers/mtd/maps/dbox2-flash.c
--- linux-2.6.39-libre/drivers/mtd/maps/dbox2-flash.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mtd/maps/dbox2-flash.c	2011-07-11 19:51:52.000000000 -0400
@@ -93,7 +93,7 @@
 		mymtd->owner = THIS_MODULE;
 
                 /* Create MTD devices for each partition. */
-	        add_mtd_partitions(mymtd, partition_info, NUM_PARTITIONS);
+		mtd_device_register(mymtd, partition_info, NUM_PARTITIONS);
 
 		return 0;
 	}
@@ -105,7 +105,7 @@
 static void __exit cleanup_dbox2_flash(void)
 {
 	if (mymtd) {
-		del_mtd_partitions(mymtd);
+		mtd_device_unregister(mymtd);
 		map_destroy(mymtd);
 	}
 	if (dbox2_flash_map.virt) {
diff -druN linux-2.6.39-libre/drivers/mtd/maps/dc21285.c linux-3.0-rc7-libre/drivers/mtd/maps/dc21285.c
--- linux-2.6.39-libre/drivers/mtd/maps/dc21285.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mtd/maps/dc21285.c	2011-07-11 19:51:52.000000000 -0400
@@ -145,17 +145,13 @@
 
 
 /* Partition stuff */
-#ifdef CONFIG_MTD_PARTITIONS
 static struct mtd_partition *dc21285_parts;
 static const char *probes[] = { "RedBoot", "cmdlinepart", NULL };
-#endif
 
 static int __init init_dc21285(void)
 {
 
-#ifdef CONFIG_MTD_PARTITIONS
 	int nrparts;
-#endif
 
 	/* Determine bankwidth */
 	switch (*CSR_SA110_CNTL & (3<<14)) {
@@ -204,13 +200,8 @@
 
 	dc21285_mtd->owner = THIS_MODULE;
 
-#ifdef CONFIG_MTD_PARTITIONS
 	nrparts = parse_mtd_partitions(dc21285_mtd, probes, &dc21285_parts, 0);
-	if (nrparts > 0)
-		add_mtd_partitions(dc21285_mtd, dc21285_parts, nrparts);
-	else
-#endif
-		add_mtd_device(dc21285_mtd);
+	mtd_device_register(dc21285_mtd, dc21285_parts, nrparts);
 
 	if(machine_is_ebsa285()) {
 		/*
@@ -232,14 +223,9 @@
 
 static void __exit cleanup_dc21285(void)
 {
-#ifdef CONFIG_MTD_PARTITIONS
-	if (dc21285_parts) {
-		del_mtd_partitions(dc21285_mtd);
+	mtd_device_unregister(dc21285_mtd);
+	if (dc21285_parts)
 		kfree(dc21285_parts);
-	} else
-#endif
-		del_mtd_device(dc21285_mtd);
-
 	map_destroy(dc21285_mtd);
 	iounmap(dc21285_map.virt);
 }
diff -druN linux-2.6.39-libre/drivers/mtd/maps/dilnetpc.c linux-3.0-rc7-libre/drivers/mtd/maps/dilnetpc.c
--- linux-2.6.39-libre/drivers/mtd/maps/dilnetpc.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mtd/maps/dilnetpc.c	2011-07-11 19:51:52.000000000 -0400
@@ -450,7 +450,7 @@
 	partition_info[2].mtdp = &lowlvl_parts[1];
 	partition_info[3].mtdp = &lowlvl_parts[3];
 
-	add_mtd_partitions(mymtd, partition_info, NUM_PARTITIONS);
+	mtd_device_register(mymtd, partition_info, NUM_PARTITIONS);
 
 	/*
 	** now create a virtual MTD device by concatenating the for partitions
@@ -463,7 +463,8 @@
 		** we do not supply mtd pointers in higlvl_partition_info, so
 		** add_mtd_partitions() will register the devices.
 		*/
-		add_mtd_partitions(merged_mtd, higlvl_partition_info, NUM_HIGHLVL_PARTITIONS);
+		mtd_device_register(merged_mtd, higlvl_partition_info,
+				    NUM_HIGHLVL_PARTITIONS);
 	}
 
 	return 0;
@@ -472,12 +473,12 @@
 static void __exit cleanup_dnpc(void)
 {
 	if(merged_mtd) {
-		del_mtd_partitions(merged_mtd);
+		mtd_device_unregister(merged_mtd);
 		mtd_concat_destroy(merged_mtd);
 	}
 
 	if (mymtd) {
-		del_mtd_partitions(mymtd);
+		mtd_device_unregister(mymtd);
 		map_destroy(mymtd);
 	}
 	if (dnpc_map.virt) {
diff -druN linux-2.6.39-libre/drivers/mtd/maps/dmv182.c linux-3.0-rc7-libre/drivers/mtd/maps/dmv182.c
--- linux-2.6.39-libre/drivers/mtd/maps/dmv182.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mtd/maps/dmv182.c	2011-07-11 19:51:52.000000000 -0400
@@ -120,7 +120,7 @@
 		   this_mtd->size >> 20, FLASH_BASE_ADDR);
 
 	this_mtd->owner = THIS_MODULE;
-	add_mtd_partitions(this_mtd, partitions, num_parts);
+	mtd_device_register(this_mtd, partitions, num_parts);
 
 	return 0;
 }
@@ -129,7 +129,7 @@
 {
 	if (this_mtd)
 	{
-		del_mtd_partitions(this_mtd);
+		mtd_device_unregister(this_mtd);
 		map_destroy(this_mtd);
 	}
 
diff -druN linux-2.6.39-libre/drivers/mtd/maps/edb7312.c linux-3.0-rc7-libre/drivers/mtd/maps/edb7312.c
--- linux-2.6.39-libre/drivers/mtd/maps/edb7312.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mtd/maps/edb7312.c	2011-07-11 19:51:52.000000000 -0400
@@ -15,10 +15,7 @@
 #include <asm/io.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/map.h>
-
-#ifdef CONFIG_MTD_PARTITIONS
 #include <linux/mtd/partitions.h>
-#endif
 
 #define WINDOW_ADDR 0x00000000      /* physical properties of flash */
 #define WINDOW_SIZE 0x01000000
@@ -40,8 +37,6 @@
 	.phys = WINDOW_ADDR,
 };
 
-#ifdef CONFIG_MTD_PARTITIONS
-
 /*
  * MTD partitioning stuff
  */
@@ -66,8 +61,6 @@
 
 static const char *probes[] = { "RedBoot", "cmdlinepart", NULL };
 
-#endif
-
 static int                   mtd_parts_nb = 0;
 static struct mtd_partition *mtd_parts    = 0;
 
@@ -96,27 +89,24 @@
 	if (mymtd) {
 		mymtd->owner = THIS_MODULE;
 
-#ifdef CONFIG_MTD_PARTITIONS
 		mtd_parts_nb = parse_mtd_partitions(mymtd, probes, &mtd_parts, MTDID);
 		if (mtd_parts_nb > 0)
-		  part_type = "detected";
+			part_type = "detected";
 
-		if (mtd_parts_nb == 0)
-		{
+		if (mtd_parts_nb == 0) {
 			mtd_parts = static_partitions;
 			mtd_parts_nb = ARRAY_SIZE(static_partitions);
 			part_type = "static";
 		}
-#endif
-		add_mtd_device(mymtd);
+
 		if (mtd_parts_nb == 0)
-		  printk(KERN_NOTICE MSG_PREFIX "no partition info available\n");
+			printk(KERN_NOTICE MSG_PREFIX "no partition info available\n");
 		else
-		{
 			printk(KERN_NOTICE MSG_PREFIX
 			       "using %s partition definition\n", part_type);
-			add_mtd_partitions(mymtd, mtd_parts, mtd_parts_nb);
-		}
+		/* Register the whole device first. */
+		mtd_device_register(mymtd, NULL, 0);
+		mtd_device_register(mymtd, mtd_parts, mtd_parts_nb);
 		return 0;
 	}
 
@@ -127,7 +117,7 @@
 static void __exit cleanup_edb7312nor(void)
 {
 	if (mymtd) {
-		del_mtd_device(mymtd);
+		mtd_device_unregister(mymtd);
 		map_destroy(mymtd);
 	}
 	if (edb7312nor_map.virt) {
diff -druN linux-2.6.39-libre/drivers/mtd/maps/esb2rom.c linux-3.0-rc7-libre/drivers/mtd/maps/esb2rom.c
--- linux-2.6.39-libre/drivers/mtd/maps/esb2rom.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mtd/maps/esb2rom.c	2011-07-11 19:51:52.000000000 -0400
@@ -128,7 +128,7 @@
 	list_for_each_entry_safe(map, scratch, &window->maps, list) {
 		if (map->rsrc.parent)
 			release_resource(&map->rsrc);
-		del_mtd_device(map->mtd);
+		mtd_device_unregister(map->mtd);
 		map_destroy(map->mtd);
 		list_del(&map->list);
 		kfree(map);
@@ -352,7 +352,7 @@
 
 		/* Now that the mtd devices is complete claim and export it */
 		map->mtd->owner = THIS_MODULE;
-		if (add_mtd_device(map->mtd)) {
+		if (mtd_device_register(map->mtd, NULL, 0)) {
 			map_destroy(map->mtd);
 			map->mtd = NULL;
 			goto out;
diff -druN linux-2.6.39-libre/drivers/mtd/maps/fortunet.c linux-3.0-rc7-libre/drivers/mtd/maps/fortunet.c
--- linux-2.6.39-libre/drivers/mtd/maps/fortunet.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mtd/maps/fortunet.c	2011-07-11 19:51:52.000000000 -0400
@@ -243,8 +243,9 @@
 					&map_regions[ix].map_info);
 			}
 			map_regions[ix].mymtd->owner = THIS_MODULE;
-			add_mtd_partitions(map_regions[ix].mymtd,
-				map_regions[ix].parts,map_regions_parts[ix]);
+			mtd_device_register(map_regions[ix].mymtd,
+					    map_regions[ix].parts,
+					    map_regions_parts[ix]);
 		}
 	}
 	if(iy)
@@ -261,7 +262,7 @@
 		{
 			if( map_regions[ix].mymtd )
 			{
-				del_mtd_partitions( map_regions[ix].mymtd );
+				mtd_device_unregister(map_regions[ix].mymtd);
 				map_destroy( map_regions[ix].mymtd );
 			}
 			iounmap((void *)map_regions[ix].map_info.virt);
diff -druN linux-2.6.39-libre/drivers/mtd/maps/gpio-addr-flash.c linux-3.0-rc7-libre/drivers/mtd/maps/gpio-addr-flash.c
--- linux-2.6.39-libre/drivers/mtd/maps/gpio-addr-flash.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mtd/maps/gpio-addr-flash.c	2011-07-11 19:51:52.000000000 -0400
@@ -155,9 +155,7 @@
 	memcpy_toio(map->virt + (to % state->win_size), from, len);
 }
 
-#ifdef CONFIG_MTD_PARTITIONS
 static const char *part_probe_types[] = { "cmdlinepart", "RedBoot", NULL };
-#endif
 
 /**
  * gpio_flash_probe() - setup a mapping for a GPIO assisted flash
@@ -189,7 +187,7 @@
  */
 static int __devinit gpio_flash_probe(struct platform_device *pdev)
 {
-	int ret;
+	int nr_parts;
 	size_t i, arr_size;
 	struct physmap_flash_data *pdata;
 	struct resource *memory;
@@ -254,24 +252,21 @@
 		return -ENXIO;
 	}
 
-#ifdef CONFIG_MTD_PARTITIONS
-	ret = parse_mtd_partitions(state->mtd, part_probe_types, &pdata->parts, 0);
-	if (ret > 0) {
+	nr_parts = parse_mtd_partitions(state->mtd, part_probe_types,
+					&pdata->parts, 0);
+	if (nr_parts > 0) {
 		pr_devinit(KERN_NOTICE PFX "Using commandline partition definition\n");
-		add_mtd_partitions(state->mtd, pdata->parts, ret);
 		kfree(pdata->parts);
-
 	} else if (pdata->nr_parts) {
 		pr_devinit(KERN_NOTICE PFX "Using board partition definition\n");
-		add_mtd_partitions(state->mtd, pdata->parts, pdata->nr_parts);
-
-	} else
-#endif
-	{
+		nr_parts = pdata->nr_parts;
+	} else {
 		pr_devinit(KERN_NOTICE PFX "no partition info available, registering whole flash at once\n");
-		add_mtd_device(state->mtd);
+		nr_parts = 0;
 	}
 
+	mtd_device_register(state->mtd, pdata->parts, nr_parts);
+
 	return 0;
 }
 
@@ -282,9 +277,7 @@
 	do {
 		gpio_free(state->gpio_addrs[i]);
 	} while (++i < state->gpio_count);
-#ifdef CONFIG_MTD_PARTITIONS
-	del_mtd_partitions(state->mtd);
-#endif
+	mtd_device_unregister(state->mtd);
 	map_destroy(state->mtd);
 	kfree(state);
 	return 0;
diff -druN linux-2.6.39-libre/drivers/mtd/maps/h720x-flash.c linux-3.0-rc7-libre/drivers/mtd/maps/h720x-flash.c
--- linux-2.6.39-libre/drivers/mtd/maps/h720x-flash.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mtd/maps/h720x-flash.c	2011-07-11 19:51:52.000000000 -0400
@@ -92,18 +92,16 @@
 	if (mymtd) {
 		mymtd->owner = THIS_MODULE;
 
-#ifdef CONFIG_MTD_PARTITIONS
 		nr_mtd_parts = parse_mtd_partitions(mymtd, probes, &mtd_parts, 0);
 		if (nr_mtd_parts > 0)
 			part_type = "command line";
-#endif
 		if (nr_mtd_parts <= 0) {
 			mtd_parts = h720x_partitions;
 			nr_mtd_parts = NUM_PARTITIONS;
 			part_type = "builtin";
 		}
 		printk(KERN_INFO "Using %s partition table\n", part_type);
-		add_mtd_partitions(mymtd, mtd_parts, nr_mtd_parts);
+		mtd_device_register(mymtd, mtd_parts, nr_mtd_parts);
 		return 0;
 	}
 
@@ -118,7 +116,7 @@
 {
 
 	if (mymtd) {
-		del_mtd_partitions(mymtd);
+		mtd_device_unregister(mymtd);
 		map_destroy(mymtd);
 	}
 
diff -druN linux-2.6.39-libre/drivers/mtd/maps/ichxrom.c linux-3.0-rc7-libre/drivers/mtd/maps/ichxrom.c
--- linux-2.6.39-libre/drivers/mtd/maps/ichxrom.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mtd/maps/ichxrom.c	2011-07-11 19:51:52.000000000 -0400
@@ -67,7 +67,7 @@
 	list_for_each_entry_safe(map, scratch, &window->maps, list) {
 		if (map->rsrc.parent)
 			release_resource(&map->rsrc);
-		del_mtd_device(map->mtd);
+		mtd_device_unregister(map->mtd);
 		map_destroy(map->mtd);
 		list_del(&map->list);
 		kfree(map);
@@ -287,7 +287,7 @@
 
 		/* Now that the mtd devices is complete claim and export it */
 		map->mtd->owner = THIS_MODULE;
-		if (add_mtd_device(map->mtd)) {
+		if (mtd_device_register(map->mtd, NULL, 0)) {
 			map_destroy(map->mtd);
 			map->mtd = NULL;
 			goto out;
diff -druN linux-2.6.39-libre/drivers/mtd/maps/impa7.c linux-3.0-rc7-libre/drivers/mtd/maps/impa7.c
--- linux-2.6.39-libre/drivers/mtd/maps/impa7.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mtd/maps/impa7.c	2011-07-11 19:51:52.000000000 -0400
@@ -15,10 +15,7 @@
 #include <asm/io.h>
 #include <linux/mtd/mtd.h>
 #include <linux/mtd/map.h>
-
-#ifdef CONFIG_MTD_PARTITIONS
 #include <linux/mtd/partitions.h>
-#endif
 
 #define WINDOW_ADDR0 0x00000000      /* physical properties of flash */
 #define WINDOW_SIZE0 0x00800000
@@ -49,8 +46,6 @@
 	},
 };
 
-#ifdef CONFIG_MTD_PARTITIONS
-
 /*
  * MTD partitioning stuff
  */
@@ -66,8 +61,6 @@
 static int mtd_parts_nb[NUM_FLASHBANKS];
 static struct mtd_partition *mtd_parts[NUM_FLASHBANKS];
 
-#endif
-
 static const char *probes[] = { "cmdlinepart", NULL };
 
 static int __init init_impa7(void)
@@ -104,7 +97,6 @@
 		if (impa7_mtd[i]) {
 			impa7_mtd[i]->owner = THIS_MODULE;
 			devicesfound++;
-#ifdef CONFIG_MTD_PARTITIONS
 			mtd_parts_nb[i] = parse_mtd_partitions(impa7_mtd[i],
 							       probes,
 							       &mtd_parts[i],
@@ -120,12 +112,8 @@
 			printk(KERN_NOTICE MSG_PREFIX
 			       "using %s partition definition\n",
 			       part_type);
-			add_mtd_partitions(impa7_mtd[i],
-					   mtd_parts[i], mtd_parts_nb[i]);
-#else
-			add_mtd_device(impa7_mtd[i]);
-
-#endif
+			mtd_device_register(impa7_mtd[i],
+					    mtd_parts[i], mtd_parts_nb[i]);
 		}
 		else
 			iounmap((void *)impa7_map[i].virt);
@@ -138,11 +126,7 @@
 	int i;
 	for (i=0; i<NUM_FLASHBANKS; i++) {
 		if (impa7_mtd[i]) {
-#ifdef CONFIG_MTD_PARTITIONS
-			del_mtd_partitions(impa7_mtd[i]);
-#else
-			del_mtd_device(impa7_mtd[i]);
-#endif
+			mtd_device_unregister(impa7_mtd[i]);
 			map_destroy(impa7_mtd[i]);
 			iounmap((void *)impa7_map[i].virt);
 			impa7_map[i].virt = 0;
diff -druN linux-2.6.39-libre/drivers/mtd/maps/integrator-flash.c linux-3.0-rc7-libre/drivers/mtd/maps/integrator-flash.c
--- linux-2.6.39-libre/drivers/mtd/maps/integrator-flash.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mtd/maps/integrator-flash.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,309 +0,0 @@
-/*======================================================================
-
-    drivers/mtd/maps/integrator-flash.c: ARM Integrator flash map driver
-
-    Copyright (C) 2000 ARM Limited
-    Copyright (C) 2003 Deep Blue Solutions Ltd.
-
-   This program is free software; you can redistribute it and/or modify
-   it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2 of the License, or
-   (at your option) any later version.
-
-   This program is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-
-   This is access code for flashes using ARM's flash partitioning
-   standards.
-
-======================================================================*/
-
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/slab.h>
-#include <linux/ioport.h>
-#include <linux/platform_device.h>
-#include <linux/init.h>
-#include <linux/io.h>
-
-#include <linux/mtd/mtd.h>
-#include <linux/mtd/map.h>
-#include <linux/mtd/partitions.h>
-#include <linux/mtd/concat.h>
-
-#include <asm/mach/flash.h>
-#include <mach/hardware.h>
-#include <asm/system.h>
-
-struct armflash_subdev_info {
-	char			*name;
-	struct mtd_info		*mtd;
-	struct map_info		map;
-	struct flash_platform_data *plat;
-};
-
-struct armflash_info {
-	struct resource		*res;
-	struct mtd_partition	*parts;
-	struct mtd_info		*mtd;
-	int			nr_subdev;
-	struct armflash_subdev_info subdev[0];
-};
-
-static void armflash_set_vpp(struct map_info *map, int on)
-{
-	struct armflash_subdev_info *info =
-		container_of(map, struct armflash_subdev_info, map);
-
-	if (info->plat && info->plat->set_vpp)
-		info->plat->set_vpp(on);
-}
-
-static const char *probes[] = { "cmdlinepart", "RedBoot", "afs", NULL };
-
-static int armflash_subdev_probe(struct armflash_subdev_info *subdev,
-				 struct resource *res)
-{
-	struct flash_platform_data *plat = subdev->plat;
-	resource_size_t size = res->end - res->start + 1;
-	void __iomem *base;
-	int err = 0;
-
-	if (!request_mem_region(res->start, size, subdev->name)) {
-		err = -EBUSY;
-		goto out;
-	}
-
-	base = ioremap(res->start, size);
-	if (!base) {
-		err = -ENOMEM;
-		goto no_mem;
-	}
-
-	/*
-	 * look for CFI based flash parts fitted to this board
-	 */
-	subdev->map.size	= size;
-	subdev->map.bankwidth	= plat->width;
-	subdev->map.phys	= res->start;
-	subdev->map.virt	= base;
-	subdev->map.name	= subdev->name;
-	subdev->map.set_vpp	= armflash_set_vpp;
-
-	simple_map_init(&subdev->map);
-
-	/*
-	 * Also, the CFI layer automatically works out what size
-	 * of chips we have, and does the necessary identification
-	 * for us automatically.
-	 */
-	subdev->mtd = do_map_probe(plat->map_name, &subdev->map);
-	if (!subdev->mtd) {
-		err = -ENXIO;
-		goto no_device;
-	}
-
-	subdev->mtd->owner = THIS_MODULE;
-
-	/* Successful? */
-	if (err == 0)
-		return err;
-
-	if (subdev->mtd)
-		map_destroy(subdev->mtd);
- no_device:
-	iounmap(base);
- no_mem:
-	release_mem_region(res->start, size);
- out:
-	return err;
-}
-
-static void armflash_subdev_remove(struct armflash_subdev_info *subdev)
-{
-	if (subdev->mtd)
-		map_destroy(subdev->mtd);
-	if (subdev->map.virt)
-		iounmap(subdev->map.virt);
-	kfree(subdev->name);
-	subdev->name = NULL;
-	release_mem_region(subdev->map.phys, subdev->map.size);
-}
-
-static int armflash_probe(struct platform_device *dev)
-{
-	struct flash_platform_data *plat = dev->dev.platform_data;
-	unsigned int size;
-	struct armflash_info *info;
-	int i, nr, err;
-
-	/* Count the number of devices */
-	for (nr = 0; ; nr++)
-		if (!platform_get_resource(dev, IORESOURCE_MEM, nr))
-			break;
-	if (nr == 0) {
-		err = -ENODEV;
-		goto out;
-	}
-
-	size = sizeof(struct armflash_info) +
-		sizeof(struct armflash_subdev_info) * nr;
-	info = kzalloc(size, GFP_KERNEL);
-	if (!info) {
-		err = -ENOMEM;
-		goto out;
-	}
-
-	if (plat && plat->init) {
-		err = plat->init();
-		if (err)
-			goto no_resource;
-	}
-
-	for (i = 0; i < nr; i++) {
-		struct armflash_subdev_info *subdev = &info->subdev[i];
-		struct resource *res;
-
-		res = platform_get_resource(dev, IORESOURCE_MEM, i);
-		if (!res)
-			break;
-
-		if (nr == 1)
-			/* No MTD concatenation, just use the default name */
-			subdev->name = kstrdup(dev_name(&dev->dev), GFP_KERNEL);
-		else
-			subdev->name = kasprintf(GFP_KERNEL, "%s-%d",
-						 dev_name(&dev->dev), i);
-		if (!subdev->name) {
-			err = -ENOMEM;
-			break;
-		}
-		subdev->plat = plat;
-
-		err = armflash_subdev_probe(subdev, res);
-		if (err) {
-			kfree(subdev->name);
-			subdev->name = NULL;
-			break;
-		}
-	}
-	info->nr_subdev = i;
-
-	if (err)
-		goto subdev_err;
-
-	if (info->nr_subdev == 1)
-		info->mtd = info->subdev[0].mtd;
-	else if (info->nr_subdev > 1) {
-		struct mtd_info *cdev[info->nr_subdev];
-
-		/*
-		 * We detected multiple devices.  Concatenate them together.
-		 */
-		for (i = 0; i < info->nr_subdev; i++)
-			cdev[i] = info->subdev[i].mtd;
-
-		info->mtd = mtd_concat_create(cdev, info->nr_subdev,
-					      dev_name(&dev->dev));
-		if (info->mtd == NULL)
-			err = -ENXIO;
-	}
-
-	if (err < 0)
-		goto cleanup;
-
-	err = parse_mtd_partitions(info->mtd, probes, &info->parts, 0);
-	if (err > 0) {
-		err = add_mtd_partitions(info->mtd, info->parts, err);
-		if (err)
-			printk(KERN_ERR
-			       "mtd partition registration failed: %d\n", err);
-	}
-
-	if (err == 0) {
-		platform_set_drvdata(dev, info);
-		return err;
-	}
-
-	/*
-	 * We got an error, free all resources.
-	 */
- cleanup:
-	if (info->mtd) {
-		del_mtd_partitions(info->mtd);
-		if (info->mtd != info->subdev[0].mtd)
-			mtd_concat_destroy(info->mtd);
-	}
-	kfree(info->parts);
- subdev_err:
-	for (i = info->nr_subdev - 1; i >= 0; i--)
-		armflash_subdev_remove(&info->subdev[i]);
- no_resource:
-	if (plat && plat->exit)
-		plat->exit();
-	kfree(info);
- out:
-	return err;
-}
-
-static int armflash_remove(struct platform_device *dev)
-{
-	struct armflash_info *info = platform_get_drvdata(dev);
-	struct flash_platform_data *plat = dev->dev.platform_data;
-	int i;
-
-	platform_set_drvdata(dev, NULL);
-
-	if (info) {
-		if (info->mtd) {
-			del_mtd_partitions(info->mtd);
-			if (info->mtd != info->subdev[0].mtd)
-				mtd_concat_destroy(info->mtd);
-		}
-		kfree(info->parts);
-
-		for (i = info->nr_subdev - 1; i >= 0; i--)
-			armflash_subdev_remove(&info->subdev[i]);
-
-		if (plat && plat->exit)
-			plat->exit();
-
-		kfree(info);
-	}
-
-	return 0;
-}
-
-static struct platform_driver armflash_driver = {
-	.probe		= armflash_probe,
-	.remove		= armflash_remove,
-	.driver		= {
-		.name	= "armflash",
-		.owner	= THIS_MODULE,
-	},
-};
-
-static int __init armflash_init(void)
-{
-	return platform_driver_register(&armflash_driver);
-}
-
-static void __exit armflash_exit(void)
-{
-	platform_driver_unregister(&armflash_driver);
-}
-
-module_init(armflash_init);
-module_exit(armflash_exit);
-
-MODULE_AUTHOR("ARM Ltd");
-MODULE_DESCRIPTION("ARM Integrator CFI map driver");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:armflash");
diff -druN linux-2.6.39-libre/drivers/mtd/maps/intel_vr_nor.c linux-3.0-rc7-libre/drivers/mtd/maps/intel_vr_nor.c
--- linux-2.6.39-libre/drivers/mtd/maps/intel_vr_nor.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mtd/maps/intel_vr_nor.c	2011-07-11 19:51:52.000000000 -0400
@@ -66,33 +66,18 @@
 
 static void __devexit vr_nor_destroy_partitions(struct vr_nor_mtd *p)
 {
-	if (p->nr_parts > 0) {
-#if defined(CONFIG_MTD_PARTITIONS) || defined(CONFIG_MTD_PARTITIONS_MODULE)
-		del_mtd_partitions(p->info);
-#endif
-	} else
-		del_mtd_device(p->info);
+	mtd_device_unregister(p->info);
 }
 
 static int __devinit vr_nor_init_partitions(struct vr_nor_mtd *p)
 {
-	int err = 0;
-#if defined(CONFIG_MTD_PARTITIONS) || defined(CONFIG_MTD_PARTITIONS_MODULE)
 	struct mtd_partition *parts;
 	static const char *part_probes[] = { "cmdlinepart", NULL };
-#endif
 
 	/* register the flash bank */
-#if defined(CONFIG_MTD_PARTITIONS) || defined(CONFIG_MTD_PARTITIONS_MODULE)
 	/* partition the flash bank */
 	p->nr_parts = parse_mtd_partitions(p->info, part_probes, &parts, 0);
-	if (p->nr_parts > 0)
-		err = add_mtd_partitions(p->info, parts, p->nr_parts);
-#endif
-	if (p->nr_parts <= 0)
-		err = add_mtd_device(p->info);
-
-	return err;
+	return mtd_device_register(p->info, parts, p->nr_parts);
 }
 
 static void __devexit vr_nor_destroy_mtd_setup(struct vr_nor_mtd *p)
diff -druN linux-2.6.39-libre/drivers/mtd/maps/ixp2000.c linux-3.0-rc7-libre/drivers/mtd/maps/ixp2000.c
--- linux-2.6.39-libre/drivers/mtd/maps/ixp2000.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mtd/maps/ixp2000.c	2011-07-11 19:51:52.000000000 -0400
@@ -119,7 +119,7 @@
 		return 0;
 
 	if (info->mtd) {
-		del_mtd_partitions(info->mtd);
+		mtd_device_unregister(info->mtd);
 		map_destroy(info->mtd);
 	}
 	if (info->map.map_priv_1)
@@ -230,7 +230,7 @@
 
 	err = parse_mtd_partitions(info->mtd, probes, &info->partitions, 0);
 	if (err > 0) {
-		err = add_mtd_partitions(info->mtd, info->partitions, err);
+		err = mtd_device_register(info->mtd, info->partitions, err);
 		if(err)
 			dev_err(&dev->dev, "Could not parse partitions\n");
 	}
diff -druN linux-2.6.39-libre/drivers/mtd/maps/ixp4xx.c linux-3.0-rc7-libre/drivers/mtd/maps/ixp4xx.c
--- linux-2.6.39-libre/drivers/mtd/maps/ixp4xx.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mtd/maps/ixp4xx.c	2011-07-11 19:51:52.000000000 -0400
@@ -162,7 +162,7 @@
 		return 0;
 
 	if (info->mtd) {
-		del_mtd_partitions(info->mtd);
+		mtd_device_unregister(info->mtd);
 		map_destroy(info->mtd);
 	}
 	if (info->map.virt)
@@ -252,10 +252,8 @@
 	/* Use the fast version */
 	info->map.write = ixp4xx_write16;
 
-#ifdef CONFIG_MTD_PARTITIONS
 	nr_parts = parse_mtd_partitions(info->mtd, probes, &info->partitions,
 					dev->resource->start);
-#endif
 	if (nr_parts > 0) {
 		part_type = "dynamic";
 	} else {
@@ -263,18 +261,16 @@
 		nr_parts = plat->nr_parts;
 		part_type = "static";
 	}
-	if (nr_parts == 0) {
+	if (nr_parts == 0)
 		printk(KERN_NOTICE "IXP4xx flash: no partition info "
 			"available, registering whole flash\n");
-		err = add_mtd_device(info->mtd);
-	} else {
+	else
 		printk(KERN_NOTICE "IXP4xx flash: using %s partition "
 			"definition\n", part_type);
-		err = add_mtd_partitions(info->mtd, info->partitions, nr_parts);
 
-		if(err)
-			printk(KERN_ERR "Could not parse partitions\n");
-	}
+	err = mtd_device_register(info->mtd, info->partitions, nr_parts);
+	if (err)
+		printk(KERN_ERR "Could not parse partitions\n");
 
 	if (err)
 		goto Error;
diff -druN linux-2.6.39-libre/drivers/mtd/maps/Kconfig linux-3.0-rc7-libre/drivers/mtd/maps/Kconfig
--- linux-2.6.39-libre/drivers/mtd/maps/Kconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mtd/maps/Kconfig	2011-07-11 19:51:52.000000000 -0400
@@ -82,7 +82,6 @@
 config MTD_PMC_MSP_EVM
 	tristate "CFI Flash device mapped on PMC-Sierra MSP"
 	depends on PMC_MSP && MTD_CFI
-	select MTD_PARTITIONS
 	help
 	  This provides a 'mapping' driver which supports the way
 	  in which user-programmable flash chips are connected on the
@@ -122,7 +121,7 @@
 
 config MTD_NETSC520
 	tristate "CFI Flash device mapped on AMD NetSc520"
-	depends on X86 && MTD_CFI && MTD_PARTITIONS
+	depends on X86 && MTD_CFI
 	help
 	  This enables access routines for the flash chips on the AMD NetSc520
 	  demonstration board. If you have one of these boards and would like
@@ -131,7 +130,6 @@
 config MTD_TS5500
 	tristate "JEDEC Flash device mapped on Technologic Systems TS-5500"
 	depends on X86
-	select MTD_PARTITIONS
 	select MTD_JEDECPROBE
 	select MTD_CFI_AMDSTD
 	help
@@ -149,7 +147,7 @@
 
 config MTD_SBC_GXX
 	tristate "CFI Flash device mapped on Arcom SBC-GXx boards"
-	depends on X86 && MTD_CFI_INTELEXT && MTD_PARTITIONS && MTD_COMPLEX_MAPPINGS
+	depends on X86 && MTD_CFI_INTELEXT && MTD_COMPLEX_MAPPINGS
 	help
 	  This provides a driver for the on-board flash of Arcom Control
 	  Systems' SBC-GXn family of boards, formerly known as SBC-MediaGX.
@@ -161,7 +159,6 @@
 config MTD_PXA2XX
 	tristate "CFI Flash device mapped on Intel XScale PXA2xx based boards"
 	depends on (PXA25x || PXA27x) && MTD_CFI_INTELEXT
-	select MTD_PARTITIONS
 	help
 	  This provides a driver for the NOR flash attached to a PXA2xx chip.
 
@@ -185,7 +182,7 @@
 
 config MTD_SCx200_DOCFLASH
 	tristate "Flash device mapped with DOCCS on NatSemi SCx200"
-	depends on SCx200 && MTD_CFI && MTD_PARTITIONS
+	depends on SCx200 && MTD_CFI
 	help
 	  Enable support for a flash chip mapped using the DOCCS signal on a
 	  National Semiconductor SCx200 processor.
@@ -247,7 +244,7 @@
 
 config MTD_NETtel
 	tristate "CFI flash device on SnapGear/SecureEdge"
-	depends on X86 && MTD_PARTITIONS && MTD_JEDECPROBE
+	depends on X86 && MTD_JEDECPROBE
 	help
 	  Support for flash chips on NETtel/SecureEdge/SnapGear boards.
 
@@ -260,9 +257,16 @@
 	  Support for parsing CFE image tag and creating MTD partitions on
 	  Broadcom BCM63xx boards.
 
+config MTD_LANTIQ
+	tristate "Lantiq SoC NOR support"
+	depends on LANTIQ
+	select MTD_PARTITIONS
+	help
+	  Support for NOR flash attached to the Lantiq SoC's External Bus Unit.
+
 config MTD_DILNETPC
 	tristate "CFI Flash device mapped on DIL/Net PC"
-	depends on X86 && MTD_PARTITIONS && MTD_CFI_INTELEXT && BROKEN
+	depends on X86 && MTD_CFI_INTELEXT && BROKEN
 	help
 	  MTD map driver for SSV DIL/Net PC Boards "DNP" and "ADNP".
 	  For details, see <http://www.ssv-embedded.de/ssv/pc104/p169.htm>
@@ -348,7 +352,7 @@
 
 config MTD_SA1100
 	tristate "CFI Flash device mapped on StrongARM SA11x0"
-	depends on MTD_CFI && ARCH_SA1100 && MTD_PARTITIONS
+	depends on MTD_CFI && ARCH_SA1100
 	help
 	  This enables access to the flash chips on most platforms based on
 	  the SA1100 and SA1110, including the Assabet and the Compaq iPAQ.
@@ -382,7 +386,7 @@
 
 config MTD_FORTUNET
 	tristate "CFI Flash device mapped on the FortuNet board"
-	depends on MTD_CFI && MTD_PARTITIONS && SA1100_FORTUNET
+	depends on MTD_CFI && SA1100_FORTUNET
 	help
 	  This enables access to the Flash on the FortuNet board.  If you
 	  have such a board, say 'Y'.
@@ -454,7 +458,6 @@
 config MTD_BFIN_ASYNC
 	tristate "Blackfin BF533-STAMP Flash Chip Support"
 	depends on BFIN533_STAMP && MTD_CFI && MTD_COMPLEX_MAPPINGS
-	select MTD_PARTITIONS
 	default y
 	help
 	  Map driver which allows for simultaneous utilization of
@@ -466,7 +469,6 @@
 	tristate "GPIO-assisted Flash Chip Support"
 	depends on GENERIC_GPIO || GPIOLIB
 	depends on MTD_COMPLEX_MAPPINGS
-	select MTD_PARTITIONS
 	help
 	  Map driver which allows flashes to be partially physically addressed
 	  and assisted by GPIOs.
@@ -475,14 +477,13 @@
 
 config MTD_UCLINUX
 	bool "Generic uClinux RAM/ROM filesystem support"
-	depends on MTD_PARTITIONS && MTD_RAM=y && !MMU
+	depends on MTD_RAM=y && !MMU
 	help
 	  Map driver to support image based filesystems for uClinux.
 
 config MTD_WRSBC8260
 	tristate "Map driver for WindRiver PowerQUICC II MPC82xx board"
 	depends on (SBC82xx || SBC8560)
-	select MTD_PARTITIONS
 	select MTD_MAP_BANK_WIDTH_4
 	select MTD_MAP_BANK_WIDTH_1
 	select MTD_CFI_I1
@@ -495,7 +496,6 @@
 config MTD_DMV182
         tristate "Map driver for Dy-4 SVME/DMV-182 board."
         depends on DMV182
-        select MTD_PARTITIONS
 	select MTD_MAP_BANK_WIDTH_32
 	select MTD_CFI_I8
 	select MTD_CFI_AMDSTD
diff -druN linux-2.6.39-libre/drivers/mtd/maps/l440gx.c linux-3.0-rc7-libre/drivers/mtd/maps/l440gx.c
--- linux-2.6.39-libre/drivers/mtd/maps/l440gx.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mtd/maps/l440gx.c	2011-07-11 19:51:52.000000000 -0400
@@ -138,7 +138,7 @@
 	if (mymtd) {
 		mymtd->owner = THIS_MODULE;
 
-		add_mtd_device(mymtd);
+		mtd_device_register(mymtd, NULL, 0);
 		return 0;
 	}
 
@@ -148,7 +148,7 @@
 
 static void __exit cleanup_l440gx(void)
 {
-	del_mtd_device(mymtd);
+	mtd_device_unregister(mymtd);
 	map_destroy(mymtd);
 
 	iounmap(l440gx_map.virt);
diff -druN linux-2.6.39-libre/drivers/mtd/maps/lantiq-flash.c linux-3.0-rc7-libre/drivers/mtd/maps/lantiq-flash.c
--- linux-2.6.39-libre/drivers/mtd/maps/lantiq-flash.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/mtd/maps/lantiq-flash.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,251 @@
+/*
+ *  This program is free software; you can redistribute it and/or modify it
+ *  under the terms of the GNU General Public License version 2 as published
+ *  by the Free Software Foundation.
+ *
+ *  Copyright (C) 2004 Liu Peng Infineon IFAP DC COM CPE
+ *  Copyright (C) 2010 John Crispin <blogic@openwrt.org>
+ */
+
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/io.h>
+#include <linux/slab.h>
+#include <linux/init.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/map.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/cfi.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/physmap.h>
+
+#include <lantiq_soc.h>
+#include <lantiq_platform.h>
+
+/*
+ * The NOR flash is connected to the same external bus unit (EBU) as PCI.
+ * To make PCI work we need to enable the endianness swapping for the address
+ * written to the EBU. This endianness swapping works for PCI correctly but
+ * fails for attached NOR devices. To workaround this we need to use a complex
+ * map. The workaround involves swapping all addresses whilst probing the chip.
+ * Once probing is complete we stop swapping the addresses but swizzle the
+ * unlock addresses to ensure that access to the NOR device works correctly.
+ */
+
+enum {
+	LTQ_NOR_PROBING,
+	LTQ_NOR_NORMAL
+};
+
+struct ltq_mtd {
+	struct resource *res;
+	struct mtd_info *mtd;
+	struct map_info *map;
+};
+
+static char ltq_map_name[] = "ltq_nor";
+
+static map_word
+ltq_read16(struct map_info *map, unsigned long adr)
+{
+	unsigned long flags;
+	map_word temp;
+
+	if (map->map_priv_1 == LTQ_NOR_PROBING)
+		adr ^= 2;
+	spin_lock_irqsave(&ebu_lock, flags);
+	temp.x[0] = *(u16 *)(map->virt + adr);
+	spin_unlock_irqrestore(&ebu_lock, flags);
+	return temp;
+}
+
+static void
+ltq_write16(struct map_info *map, map_word d, unsigned long adr)
+{
+	unsigned long flags;
+
+	if (map->map_priv_1 == LTQ_NOR_PROBING)
+		adr ^= 2;
+	spin_lock_irqsave(&ebu_lock, flags);
+	*(u16 *)(map->virt + adr) = d.x[0];
+	spin_unlock_irqrestore(&ebu_lock, flags);
+}
+
+/*
+ * The following 2 functions copy data between iomem and a cached memory
+ * section. As memcpy() makes use of pre-fetching we cannot use it here.
+ * The normal alternative of using memcpy_{to,from}io also makes use of
+ * memcpy() on MIPS so it is not applicable either. We are therefore stuck
+ * with having to use our own loop.
+ */
+static void
+ltq_copy_from(struct map_info *map, void *to,
+	unsigned long from, ssize_t len)
+{
+	unsigned char *f = (unsigned char *)map->virt + from;
+	unsigned char *t = (unsigned char *)to;
+	unsigned long flags;
+
+	spin_lock_irqsave(&ebu_lock, flags);
+	while (len--)
+		*t++ = *f++;
+	spin_unlock_irqrestore(&ebu_lock, flags);
+}
+
+static void
+ltq_copy_to(struct map_info *map, unsigned long to,
+	const void *from, ssize_t len)
+{
+	unsigned char *f = (unsigned char *)from;
+	unsigned char *t = (unsigned char *)map->virt + to;
+	unsigned long flags;
+
+	spin_lock_irqsave(&ebu_lock, flags);
+	while (len--)
+		*t++ = *f++;
+	spin_unlock_irqrestore(&ebu_lock, flags);
+}
+
+static const char const *part_probe_types[] = { "cmdlinepart", NULL };
+
+static int __init
+ltq_mtd_probe(struct platform_device *pdev)
+{
+	struct physmap_flash_data *ltq_mtd_data = dev_get_platdata(&pdev->dev);
+	struct ltq_mtd *ltq_mtd;
+	struct mtd_partition *parts;
+	struct resource *res;
+	int nr_parts = 0;
+	struct cfi_private *cfi;
+	int err;
+
+	ltq_mtd = kzalloc(sizeof(struct ltq_mtd), GFP_KERNEL);
+	platform_set_drvdata(pdev, ltq_mtd);
+
+	ltq_mtd->res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!ltq_mtd->res) {
+		dev_err(&pdev->dev, "failed to get memory resource");
+		err = -ENOENT;
+		goto err_out;
+	}
+
+	res = devm_request_mem_region(&pdev->dev, ltq_mtd->res->start,
+		resource_size(ltq_mtd->res), dev_name(&pdev->dev));
+	if (!ltq_mtd->res) {
+		dev_err(&pdev->dev, "failed to request mem resource");
+		err = -EBUSY;
+		goto err_out;
+	}
+
+	ltq_mtd->map = kzalloc(sizeof(struct map_info), GFP_KERNEL);
+	ltq_mtd->map->phys = res->start;
+	ltq_mtd->map->size = resource_size(res);
+	ltq_mtd->map->virt = devm_ioremap_nocache(&pdev->dev,
+				ltq_mtd->map->phys, ltq_mtd->map->size);
+	if (!ltq_mtd->map->virt) {
+		dev_err(&pdev->dev, "failed to ioremap!\n");
+		err = -ENOMEM;
+		goto err_free;
+	}
+
+	ltq_mtd->map->name = ltq_map_name;
+	ltq_mtd->map->bankwidth = 2;
+	ltq_mtd->map->read = ltq_read16;
+	ltq_mtd->map->write = ltq_write16;
+	ltq_mtd->map->copy_from = ltq_copy_from;
+	ltq_mtd->map->copy_to = ltq_copy_to;
+
+	ltq_mtd->map->map_priv_1 = LTQ_NOR_PROBING;
+	ltq_mtd->mtd = do_map_probe("cfi_probe", ltq_mtd->map);
+	ltq_mtd->map->map_priv_1 = LTQ_NOR_NORMAL;
+
+	if (!ltq_mtd->mtd) {
+		dev_err(&pdev->dev, "probing failed\n");
+		err = -ENXIO;
+		goto err_unmap;
+	}
+
+	ltq_mtd->mtd->owner = THIS_MODULE;
+
+	cfi = ltq_mtd->map->fldrv_priv;
+	cfi->addr_unlock1 ^= 1;
+	cfi->addr_unlock2 ^= 1;
+
+	nr_parts = parse_mtd_partitions(ltq_mtd->mtd,
+				part_probe_types, &parts, 0);
+	if (nr_parts > 0) {
+		dev_info(&pdev->dev,
+			"using %d partitions from cmdline", nr_parts);
+	} else {
+		nr_parts = ltq_mtd_data->nr_parts;
+		parts = ltq_mtd_data->parts;
+	}
+
+	err = add_mtd_partitions(ltq_mtd->mtd, parts, nr_parts);
+	if (err) {
+		dev_err(&pdev->dev, "failed to add partitions\n");
+		goto err_destroy;
+	}
+
+	return 0;
+
+err_destroy:
+	map_destroy(ltq_mtd->mtd);
+err_unmap:
+	iounmap(ltq_mtd->map->virt);
+err_free:
+	kfree(ltq_mtd->map);
+err_out:
+	kfree(ltq_mtd);
+	return err;
+}
+
+static int __devexit
+ltq_mtd_remove(struct platform_device *pdev)
+{
+	struct ltq_mtd *ltq_mtd = platform_get_drvdata(pdev);
+
+	if (ltq_mtd) {
+		if (ltq_mtd->mtd) {
+			del_mtd_partitions(ltq_mtd->mtd);
+			map_destroy(ltq_mtd->mtd);
+		}
+		if (ltq_mtd->map->virt)
+			iounmap(ltq_mtd->map->virt);
+		kfree(ltq_mtd->map);
+		kfree(ltq_mtd);
+	}
+	return 0;
+}
+
+static struct platform_driver ltq_mtd_driver = {
+	.remove = __devexit_p(ltq_mtd_remove),
+	.driver = {
+		.name = "ltq_nor",
+		.owner = THIS_MODULE,
+	},
+};
+
+static int __init
+init_ltq_mtd(void)
+{
+	int ret = platform_driver_probe(&ltq_mtd_driver, ltq_mtd_probe);
+
+	if (ret)
+		pr_err("ltq_nor: error registering platform driver");
+	return ret;
+}
+
+static void __exit
+exit_ltq_mtd(void)
+{
+	platform_driver_unregister(&ltq_mtd_driver);
+}
+
+module_init(init_ltq_mtd);
+module_exit(exit_ltq_mtd);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("John Crispin <blogic@openwrt.org>");
+MODULE_DESCRIPTION("Lantiq SoC NOR");
diff -druN linux-2.6.39-libre/drivers/mtd/maps/latch-addr-flash.c linux-3.0-rc7-libre/drivers/mtd/maps/latch-addr-flash.c
--- linux-2.6.39-libre/drivers/mtd/maps/latch-addr-flash.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mtd/maps/latch-addr-flash.c	2011-07-11 19:51:52.000000000 -0400
@@ -112,18 +112,9 @@
 	latch_addr_data = dev->dev.platform_data;
 
 	if (info->mtd != NULL) {
-		if (mtd_has_partitions()) {
-			if (info->nr_parts) {
-				del_mtd_partitions(info->mtd);
-				kfree(info->parts);
-			} else if (latch_addr_data->nr_parts) {
-				del_mtd_partitions(info->mtd);
-			} else {
-				del_mtd_device(info->mtd);
-			}
-		} else {
-			del_mtd_device(info->mtd);
-		}
+		if (info->nr_parts)
+			kfree(info->parts);
+		mtd_device_unregister(info->mtd);
 		map_destroy(info->mtd);
 	}
 
@@ -215,23 +206,21 @@
 	}
 	info->mtd->owner = THIS_MODULE;
 
-	if (mtd_has_partitions()) {
-
-		err = parse_mtd_partitions(info->mtd,
-					   (const char **)part_probe_types,
-					   &info->parts, 0);
-		if (err > 0) {
-			add_mtd_partitions(info->mtd, info->parts, err);
-			return 0;
-		}
-		if (latch_addr_data->nr_parts) {
-			pr_notice("Using latch-addr-flash partition information\n");
-			add_mtd_partitions(info->mtd, latch_addr_data->parts,
-					latch_addr_data->nr_parts);
-			return 0;
-		}
+	err = parse_mtd_partitions(info->mtd, (const char **)part_probe_types,
+				   &info->parts, 0);
+	if (err > 0) {
+		mtd_device_register(info->mtd, info->parts, err);
+		return 0;
 	}
-	add_mtd_device(info->mtd);
+	if (latch_addr_data->nr_parts) {
+		pr_notice("Using latch-addr-flash partition information\n");
+		mtd_device_register(info->mtd,
+				    latch_addr_data->parts,
+				    latch_addr_data->nr_parts);
+		return 0;
+	}
+
+	mtd_device_register(info->mtd, NULL, 0);
 	return 0;
 
 iounmap:
diff -druN linux-2.6.39-libre/drivers/mtd/maps/Makefile linux-3.0-rc7-libre/drivers/mtd/maps/Makefile
--- linux-2.6.39-libre/drivers/mtd/maps/Makefile	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mtd/maps/Makefile	2011-07-11 19:51:52.000000000 -0400
@@ -8,7 +8,6 @@
 
 # Chip mappings
 obj-$(CONFIG_MTD_CDB89712)	+= cdb89712.o
-obj-$(CONFIG_MTD_ARM_INTEGRATOR)+= integrator-flash.o
 obj-$(CONFIG_MTD_CFI_FLAGADM)	+= cfi_flagadm.o
 obj-$(CONFIG_MTD_DC21285)	+= dc21285.o
 obj-$(CONFIG_MTD_DILNETPC)	+= dilnetpc.o
@@ -60,3 +59,4 @@
 obj-$(CONFIG_MTD_GPIO_ADDR)	+= gpio-addr-flash.o
 obj-$(CONFIG_MTD_BCM963XX)	+= bcm963xx-flash.o
 obj-$(CONFIG_MTD_LATCH_ADDR)	+= latch-addr-flash.o
+obj-$(CONFIG_MTD_LANTIQ)	+= lantiq-flash.o
diff -druN linux-2.6.39-libre/drivers/mtd/maps/mbx860.c linux-3.0-rc7-libre/drivers/mtd/maps/mbx860.c
--- linux-2.6.39-libre/drivers/mtd/maps/mbx860.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mtd/maps/mbx860.c	2011-07-11 19:51:52.000000000 -0400
@@ -69,8 +69,8 @@
 	mymtd = do_map_probe("jedec_probe", &mbx_map);
 	if (mymtd) {
 		mymtd->owner = THIS_MODULE;
-		add_mtd_device(mymtd);
-                add_mtd_partitions(mymtd, partition_info, NUM_PARTITIONS);
+		mtd_device_register(mymtd, NULL, 0);
+		mtd_device_register(mymtd, partition_info, NUM_PARTITIONS);
 		return 0;
 	}
 
@@ -81,7 +81,7 @@
 static void __exit cleanup_mbx(void)
 {
 	if (mymtd) {
-		del_mtd_device(mymtd);
+		mtd_device_unregister(mymtd);
 		map_destroy(mymtd);
 	}
 	if (mbx_map.virt) {
diff -druN linux-2.6.39-libre/drivers/mtd/maps/netsc520.c linux-3.0-rc7-libre/drivers/mtd/maps/netsc520.c
--- linux-2.6.39-libre/drivers/mtd/maps/netsc520.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mtd/maps/netsc520.c	2011-07-11 19:51:52.000000000 -0400
@@ -116,14 +116,14 @@
 	}
 
 	mymtd->owner = THIS_MODULE;
-	add_mtd_partitions( mymtd, partition_info, NUM_PARTITIONS );
+	mtd_device_register(mymtd, partition_info, NUM_PARTITIONS);
 	return 0;
 }
 
 static void __exit cleanup_netsc520(void)
 {
 	if (mymtd) {
-		del_mtd_partitions(mymtd);
+		mtd_device_unregister(mymtd);
 		map_destroy(mymtd);
 	}
 	if (netsc520_map.virt) {
diff -druN linux-2.6.39-libre/drivers/mtd/maps/nettel.c linux-3.0-rc7-libre/drivers/mtd/maps/nettel.c
--- linux-2.6.39-libre/drivers/mtd/maps/nettel.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mtd/maps/nettel.c	2011-07-11 19:51:52.000000000 -0400
@@ -383,13 +383,13 @@
 		/* No BIOS regions when AMD boot */
 		num_intel_partitions -= 2;
 	}
-	rc = add_mtd_partitions(intel_mtd, nettel_intel_partitions,
-		num_intel_partitions);
+	rc = mtd_device_register(intel_mtd, nettel_intel_partitions,
+				 num_intel_partitions);
 #endif
 
 	if (amd_mtd) {
-		rc = add_mtd_partitions(amd_mtd, nettel_amd_partitions,
-			num_amd_partitions);
+		rc = mtd_device_register(amd_mtd, nettel_amd_partitions,
+					 num_amd_partitions);
 	}
 
 #ifdef CONFIG_MTD_CFI_INTELEXT
@@ -419,7 +419,7 @@
 	unregister_reboot_notifier(&nettel_notifier_block);
 #endif
 	if (amd_mtd) {
-		del_mtd_partitions(amd_mtd);
+		mtd_device_unregister(amd_mtd);
 		map_destroy(amd_mtd);
 	}
 	if (nettel_mmcrp) {
@@ -432,7 +432,7 @@
 	}
 #ifdef CONFIG_MTD_CFI_INTELEXT
 	if (intel_mtd) {
-		del_mtd_partitions(intel_mtd);
+		mtd_device_unregister(intel_mtd);
 		map_destroy(intel_mtd);
 	}
 	if (nettel_intel_map.virt) {
diff -druN linux-2.6.39-libre/drivers/mtd/maps/octagon-5066.c linux-3.0-rc7-libre/drivers/mtd/maps/octagon-5066.c
--- linux-2.6.39-libre/drivers/mtd/maps/octagon-5066.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mtd/maps/octagon-5066.c	2011-07-11 19:51:52.000000000 -0400
@@ -175,7 +175,7 @@
 	int i;
 	for (i=0; i<2; i++) {
 		if (oct5066_mtd[i]) {
-			del_mtd_device(oct5066_mtd[i]);
+			mtd_device_unregister(oct5066_mtd[i]);
 			map_destroy(oct5066_mtd[i]);
 		}
 	}
@@ -220,7 +220,7 @@
 			oct5066_mtd[i] = do_map_probe("map_rom", &oct5066_map[i]);
 		if (oct5066_mtd[i]) {
 			oct5066_mtd[i]->owner = THIS_MODULE;
-			add_mtd_device(oct5066_mtd[i]);
+			mtd_device_register(oct5066_mtd[i], NULL, 0);
 		}
 	}
 
diff -druN linux-2.6.39-libre/drivers/mtd/maps/pci.c linux-3.0-rc7-libre/drivers/mtd/maps/pci.c
--- linux-2.6.39-libre/drivers/mtd/maps/pci.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mtd/maps/pci.c	2011-07-11 19:51:52.000000000 -0400
@@ -313,7 +313,7 @@
 		goto release;
 
 	mtd->owner = THIS_MODULE;
-	add_mtd_device(mtd);
+	mtd_device_register(mtd, NULL, 0);
 
 	pci_set_drvdata(dev, mtd);
 
@@ -336,7 +336,7 @@
 	struct mtd_info *mtd = pci_get_drvdata(dev);
 	struct map_pci_info *map = mtd->priv;
 
-	del_mtd_device(mtd);
+	mtd_device_unregister(mtd);
 	map_destroy(mtd);
 	map->exit(dev, map);
 	kfree(map);
diff -druN linux-2.6.39-libre/drivers/mtd/maps/pcmciamtd.c linux-3.0-rc7-libre/drivers/mtd/maps/pcmciamtd.c
--- linux-2.6.39-libre/drivers/mtd/maps/pcmciamtd.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mtd/maps/pcmciamtd.c	2011-07-11 19:51:52.000000000 -0400
@@ -630,7 +630,7 @@
 		dev->pcmcia_map.copy_to = pcmcia_copy_to;
 	}
 
-	if(add_mtd_device(mtd)) {
+	if (mtd_device_register(mtd, NULL, 0)) {
 		map_destroy(mtd);
 		dev->mtd_info = NULL;
 		dev_err(&dev->p_dev->dev,
@@ -669,7 +669,7 @@
 	DEBUG(3, "link=0x%p", link);
 
 	if(dev->mtd_info) {
-		del_mtd_device(dev->mtd_info);
+		mtd_device_unregister(dev->mtd_info);
 		dev_info(&dev->p_dev->dev, "mtd%d: Removing\n",
 			 dev->mtd_info->index);
 		map_destroy(dev->mtd_info);
@@ -694,7 +694,7 @@
 	return pcmciamtd_config(link);
 }
 
-static struct pcmcia_device_id pcmciamtd_ids[] = {
+static const struct pcmcia_device_id pcmciamtd_ids[] = {
 	PCMCIA_DEVICE_FUNC_ID(1),
 	PCMCIA_DEVICE_PROD_ID123("IO DATA", "PCS-2M", "2MB SRAM", 0x547e66dc, 0x1fed36cd, 0x36eadd21),
 	PCMCIA_DEVICE_PROD_ID12("IBM", "2MB SRAM", 0xb569a6e5, 0x36eadd21),
diff -druN linux-2.6.39-libre/drivers/mtd/maps/physmap.c linux-3.0-rc7-libre/drivers/mtd/maps/physmap.c
--- linux-2.6.39-libre/drivers/mtd/maps/physmap.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mtd/maps/physmap.c	2011-07-11 19:51:52.000000000 -0400
@@ -27,10 +27,8 @@
 	struct mtd_info		*mtd[MAX_RESOURCES];
 	struct mtd_info		*cmtd;
 	struct map_info		map[MAX_RESOURCES];
-#ifdef CONFIG_MTD_PARTITIONS
 	int			nr_parts;
 	struct mtd_partition	*parts;
-#endif
 };
 
 static int physmap_flash_remove(struct platform_device *dev)
@@ -47,18 +45,9 @@
 	physmap_data = dev->dev.platform_data;
 
 	if (info->cmtd) {
-#ifdef CONFIG_MTD_PARTITIONS
-		if (info->nr_parts || physmap_data->nr_parts) {
-			del_mtd_partitions(info->cmtd);
-
-			if (info->nr_parts)
-				kfree(info->parts);
-		} else {
-			del_mtd_device(info->cmtd);
-		}
-#else
-		del_mtd_device(info->cmtd);
-#endif
+		mtd_device_unregister(info->cmtd);
+		if (info->nr_parts)
+			kfree(info->parts);
 		if (info->cmtd != info->mtd[0])
 			mtd_concat_destroy(info->cmtd);
 	}
@@ -67,18 +56,33 @@
 		if (info->mtd[i] != NULL)
 			map_destroy(info->mtd[i]);
 	}
+
+	if (physmap_data->exit)
+		physmap_data->exit(dev);
+
 	return 0;
 }
 
+static void physmap_set_vpp(struct map_info *map, int state)
+{
+	struct platform_device *pdev;
+	struct physmap_flash_data *physmap_data;
+
+	pdev = (struct platform_device *)map->map_priv_1;
+	physmap_data = pdev->dev.platform_data;
+
+	if (physmap_data->set_vpp)
+		physmap_data->set_vpp(pdev, state);
+}
+
 static const char *rom_probe_types[] = {
 					"cfi_probe",
 					"jedec_probe",
 					"qinfo_probe",
 					"map_rom",
 					NULL };
-#ifdef CONFIG_MTD_PARTITIONS
-static const char *part_probe_types[] = { "cmdlinepart", "RedBoot", NULL };
-#endif
+static const char *part_probe_types[] = { "cmdlinepart", "RedBoot", "afs",
+					  NULL };
 
 static int physmap_flash_probe(struct platform_device *dev)
 {
@@ -100,6 +104,12 @@
 		goto err_out;
 	}
 
+	if (physmap_data->init) {
+		err = physmap_data->init(dev);
+		if (err)
+			goto err_out;
+	}
+
 	platform_set_drvdata(dev, info);
 
 	for (i = 0; i < dev->num_resources; i++) {
@@ -120,8 +130,9 @@
 		info->map[i].phys = dev->resource[i].start;
 		info->map[i].size = resource_size(&dev->resource[i]);
 		info->map[i].bankwidth = physmap_data->width;
-		info->map[i].set_vpp = physmap_data->set_vpp;
+		info->map[i].set_vpp = physmap_set_vpp;
 		info->map[i].pfow_base = physmap_data->pfow_base;
+		info->map[i].map_priv_1 = (unsigned long)dev;
 
 		info->map[i].virt = devm_ioremap(&dev->dev, info->map[i].phys,
 						 info->map[i].size);
@@ -164,24 +175,23 @@
 	if (err)
 		goto err_out;
 
-#ifdef CONFIG_MTD_PARTITIONS
 	err = parse_mtd_partitions(info->cmtd, part_probe_types,
-				&info->parts, 0);
+				   &info->parts, 0);
 	if (err > 0) {
-		add_mtd_partitions(info->cmtd, info->parts, err);
+		mtd_device_register(info->cmtd, info->parts, err);
 		info->nr_parts = err;
 		return 0;
 	}
 
 	if (physmap_data->nr_parts) {
 		printk(KERN_NOTICE "Using physmap partition information\n");
-		add_mtd_partitions(info->cmtd, physmap_data->parts,
-				   physmap_data->nr_parts);
+		mtd_device_register(info->cmtd, physmap_data->parts,
+				    physmap_data->nr_parts);
 		return 0;
 	}
-#endif
 
-	add_mtd_device(info->cmtd);
+	mtd_device_register(info->cmtd, NULL, 0);
+
 	return 0;
 
 err_out:
@@ -245,14 +255,12 @@
 	physmap_flash_data.set_vpp = set_vpp;
 }
 
-#ifdef CONFIG_MTD_PARTITIONS
 void physmap_set_partitions(struct mtd_partition *parts, int num_parts)
 {
 	physmap_flash_data.nr_parts = num_parts;
 	physmap_flash_data.parts = parts;
 }
 #endif
-#endif
 
 static int __init physmap_init(void)
 {
diff -druN linux-2.6.39-libre/drivers/mtd/maps/physmap_of.c linux-3.0-rc7-libre/drivers/mtd/maps/physmap_of.c
--- linux-2.6.39-libre/drivers/mtd/maps/physmap_of.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mtd/maps/physmap_of.c	2011-07-11 19:51:52.000000000 -0400
@@ -34,16 +34,12 @@
 
 struct of_flash {
 	struct mtd_info		*cmtd;
-#ifdef CONFIG_MTD_PARTITIONS
 	struct mtd_partition	*parts;
-#endif
 	int list_size; /* number of elements in of_flash_list */
 	struct of_flash_list	list[0];
 };
 
-#ifdef CONFIG_MTD_PARTITIONS
 #define OF_FLASH_PARTS(info)	((info)->parts)
-
 static int parse_obsolete_partitions(struct platform_device *dev,
 				     struct of_flash *info,
 				     struct device_node *dp)
@@ -89,10 +85,6 @@
 
 	return nr_parts;
 }
-#else /* MTD_PARTITIONS */
-#define	OF_FLASH_PARTS(info)		(0)
-#define parse_partitions(info, dev)	(0)
-#endif /* MTD_PARTITIONS */
 
 static int of_flash_remove(struct platform_device *dev)
 {
@@ -105,17 +97,14 @@
 	dev_set_drvdata(&dev->dev, NULL);
 
 	if (info->cmtd != info->list[0].mtd) {
-		del_mtd_device(info->cmtd);
+		mtd_device_unregister(info->cmtd);
 		mtd_concat_destroy(info->cmtd);
 	}
 
 	if (info->cmtd) {
-		if (OF_FLASH_PARTS(info)) {
-			del_mtd_partitions(info->cmtd);
+		if (OF_FLASH_PARTS(info))
 			kfree(OF_FLASH_PARTS(info));
-		} else {
-			del_mtd_device(info->cmtd);
-		}
+		mtd_device_unregister(info->cmtd);
 	}
 
 	for (i = 0; i < info->list_size; i++) {
@@ -172,7 +161,6 @@
 	}
 }
 
-#ifdef CONFIG_MTD_PARTITIONS
 /* When partitions are set we look for a linux,part-probe property which
    specifies the list of partition probers to use. If none is given then the
    default is use. These take precedence over other device tree
@@ -212,14 +200,11 @@
 	if (probes != part_probe_types_def)
 		kfree(probes);
 }
-#endif
 
 static struct of_device_id of_flash_match[];
 static int __devinit of_flash_probe(struct platform_device *dev)
 {
-#ifdef CONFIG_MTD_PARTITIONS
 	const char **part_probe_types;
-#endif
 	const struct of_device_id *match;
 	struct device_node *dp = dev->dev.of_node;
 	struct resource res;
@@ -346,7 +331,6 @@
 	if (err)
 		goto err_out;
 
-#ifdef CONFIG_MTD_PARTITIONS
 	part_probe_types = of_get_probes(dp);
 	err = parse_mtd_partitions(info->cmtd, part_probe_types,
 				   &info->parts, 0);
@@ -356,13 +340,11 @@
 	}
 	of_free_probes(part_probe_types);
 
-#ifdef CONFIG_MTD_OF_PARTS
 	if (err == 0) {
 		err = of_mtd_parse_partitions(&dev->dev, dp, &info->parts);
 		if (err < 0)
 			goto err_out;
 	}
-#endif
 
 	if (err == 0) {
 		err = parse_obsolete_partitions(dev, info, dp);
@@ -370,11 +352,7 @@
 			goto err_out;
 	}
 
-	if (err > 0)
-		add_mtd_partitions(info->cmtd, info->parts, err);
-	else
-#endif
-		add_mtd_device(info->cmtd);
+	mtd_device_register(info->cmtd, info->parts, err);
 
 	kfree(mtd_list);
 
diff -druN linux-2.6.39-libre/drivers/mtd/maps/pismo.c linux-3.0-rc7-libre/drivers/mtd/maps/pismo.c
--- linux-2.6.39-libre/drivers/mtd/maps/pismo.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mtd/maps/pismo.c	2011-07-11 19:51:52.000000000 -0400
@@ -50,39 +50,13 @@
 	struct platform_device	*dev[PISMO_NUM_CS];
 };
 
-/* FIXME: set_vpp could do with a better calling convention */
-static struct pismo_data *vpp_pismo;
-static DEFINE_MUTEX(pismo_mutex);
-
-static int pismo_setvpp_probe_fix(struct pismo_data *pismo)
-{
-	mutex_lock(&pismo_mutex);
-	if (vpp_pismo) {
-		mutex_unlock(&pismo_mutex);
-		kfree(pismo);
-		return -EBUSY;
-	}
-	vpp_pismo = pismo;
-	mutex_unlock(&pismo_mutex);
-	return 0;
-}
-
-static void pismo_setvpp_remove_fix(struct pismo_data *pismo)
-{
-	mutex_lock(&pismo_mutex);
-	if (vpp_pismo == pismo)
-		vpp_pismo = NULL;
-	mutex_unlock(&pismo_mutex);
-}
-
-static void pismo_set_vpp(struct map_info *map, int on)
+static void pismo_set_vpp(struct platform_device *pdev, int on)
 {
-	struct pismo_data *pismo = vpp_pismo;
+	struct i2c_client *client = to_i2c_client(pdev->dev.parent);
+	struct pismo_data *pismo = i2c_get_clientdata(client);
 
 	pismo->vpp(pismo->vpp_data, on);
 }
-/* end of hack */
-
 
 static unsigned int __devinit pismo_width_to_bytes(unsigned int width)
 {
@@ -231,9 +205,6 @@
 	for (i = 0; i < ARRAY_SIZE(pismo->dev); i++)
 		platform_device_unregister(pismo->dev[i]);
 
-	/* FIXME: set_vpp needs saner arguments */
-	pismo_setvpp_remove_fix(pismo);
-
 	kfree(pismo);
 
 	return 0;
@@ -257,11 +228,6 @@
 	if (!pismo)
 		return -ENOMEM;
 
-	/* FIXME: set_vpp needs saner arguments */
-	ret = pismo_setvpp_probe_fix(pismo);
-	if (ret)
-		return ret;
-
 	pismo->client = client;
 	if (pdata) {
 		pismo->vpp = pdata->set_vpp;
diff -druN linux-2.6.39-libre/drivers/mtd/maps/plat-ram.c linux-3.0-rc7-libre/drivers/mtd/maps/plat-ram.c
--- linux-2.6.39-libre/drivers/mtd/maps/plat-ram.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mtd/maps/plat-ram.c	2011-07-11 19:51:52.000000000 -0400
@@ -94,14 +94,11 @@
 		return 0;
 
 	if (info->mtd) {
-#ifdef CONFIG_MTD_PARTITIONS
+		mtd_device_unregister(info->mtd);
 		if (info->partitions) {
-			del_mtd_partitions(info->mtd);
 			if (info->free_partitions)
 				kfree(info->partitions);
 		}
-#endif
-		del_mtd_device(info->mtd);
 		map_destroy(info->mtd);
 	}
 
@@ -231,7 +228,6 @@
 	/* check to see if there are any available partitions, or wether
 	 * to add this device whole */
 
-#ifdef CONFIG_MTD_PARTITIONS
 	if (!pdata->nr_partitions) {
 		/* try to probe using the supplied probe type */
 		if (pdata->probes) {
@@ -239,24 +235,22 @@
 					   &info->partitions, 0);
 			info->free_partitions = 1;
 			if (err > 0)
-				err = add_mtd_partitions(info->mtd,
+				err = mtd_device_register(info->mtd,
 					info->partitions, err);
 		}
 	}
 	/* use the static mapping */
 	else
-		err = add_mtd_partitions(info->mtd, pdata->partitions,
-				pdata->nr_partitions);
-#endif /* CONFIG_MTD_PARTITIONS */
-
-	if (add_mtd_device(info->mtd)) {
-		dev_err(&pdev->dev, "add_mtd_device() failed\n");
-		err = -ENOMEM;
-	}
-
+		err = mtd_device_register(info->mtd, pdata->partitions,
+					  pdata->nr_partitions);
 	if (!err)
 		dev_info(&pdev->dev, "registered mtd device\n");
 
+	/* add the whole device. */
+	err = mtd_device_register(info->mtd, NULL, 0);
+	if (err)
+		dev_err(&pdev->dev, "failed to register the entire device\n");
+
 	return err;
 
  exit_free:
diff -druN linux-2.6.39-libre/drivers/mtd/maps/pmcmsp-flash.c linux-3.0-rc7-libre/drivers/mtd/maps/pmcmsp-flash.c
--- linux-2.6.39-libre/drivers/mtd/maps/pmcmsp-flash.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mtd/maps/pmcmsp-flash.c	2011-07-11 19:51:52.000000000 -0400
@@ -173,7 +173,7 @@
 		msp_flash[i] = do_map_probe("cfi_probe", &msp_maps[i]);
 		if (msp_flash[i]) {
 			msp_flash[i]->owner = THIS_MODULE;
-			add_mtd_partitions(msp_flash[i], msp_parts[i], pcnt);
+			mtd_device_register(msp_flash[i], msp_parts[i], pcnt);
 		} else {
 			printk(KERN_ERR "map probe failed for flash\n");
 			ret = -ENXIO;
@@ -188,7 +188,7 @@
 
 cleanup_loop:
 	while (i--) {
-		del_mtd_partitions(msp_flash[i]);
+		mtd_device_unregister(msp_flash[i]);
 		map_destroy(msp_flash[i]);
 		kfree(msp_maps[i].name);
 		iounmap(msp_maps[i].virt);
@@ -207,7 +207,7 @@
 	int i;
 
 	for (i = 0; i < fcnt; i++) {
-		del_mtd_partitions(msp_flash[i]);
+		mtd_device_unregister(msp_flash[i]);
 		map_destroy(msp_flash[i]);
 		iounmap((void *)msp_maps[i].virt);
 
diff -druN linux-2.6.39-libre/drivers/mtd/maps/pxa2xx-flash.c linux-3.0-rc7-libre/drivers/mtd/maps/pxa2xx-flash.c
--- linux-2.6.39-libre/drivers/mtd/maps/pxa2xx-flash.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mtd/maps/pxa2xx-flash.c	2011-07-11 19:51:52.000000000 -0400
@@ -104,23 +104,18 @@
 	}
 	info->mtd->owner = THIS_MODULE;
 
-#ifdef CONFIG_MTD_PARTITIONS
 	ret = parse_mtd_partitions(info->mtd, probes, &parts, 0);
 
 	if (ret > 0) {
 		info->nr_parts = ret;
 		info->parts = parts;
 	}
-#endif
 
-	if (info->nr_parts) {
-		add_mtd_partitions(info->mtd, info->parts,
-				   info->nr_parts);
-	} else {
+	if (!info->nr_parts)
 		printk("Registering %s as whole device\n",
 		       info->map.name);
-		add_mtd_device(info->mtd);
-	}
+
+	mtd_device_register(info->mtd, info->parts, info->nr_parts);
 
 	platform_set_drvdata(pdev, info);
 	return 0;
@@ -132,12 +127,7 @@
 
 	platform_set_drvdata(dev, NULL);
 
-#ifdef CONFIG_MTD_PARTITIONS
-	if (info->nr_parts)
-		del_mtd_partitions(info->mtd);
-	else
-#endif
-		del_mtd_device(info->mtd);
+	mtd_device_unregister(info->mtd);
 
 	map_destroy(info->mtd);
 	iounmap(info->map.virt);
diff -druN linux-2.6.39-libre/drivers/mtd/maps/rbtx4939-flash.c linux-3.0-rc7-libre/drivers/mtd/maps/rbtx4939-flash.c
--- linux-2.6.39-libre/drivers/mtd/maps/rbtx4939-flash.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mtd/maps/rbtx4939-flash.c	2011-07-11 19:51:52.000000000 -0400
@@ -25,10 +25,8 @@
 struct rbtx4939_flash_info {
 	struct mtd_info *mtd;
 	struct map_info map;
-#ifdef CONFIG_MTD_PARTITIONS
 	int nr_parts;
 	struct mtd_partition *parts;
-#endif
 };
 
 static int rbtx4939_flash_remove(struct platform_device *dev)
@@ -41,28 +39,18 @@
 	platform_set_drvdata(dev, NULL);
 
 	if (info->mtd) {
-#ifdef CONFIG_MTD_PARTITIONS
 		struct rbtx4939_flash_data *pdata = dev->dev.platform_data;
 
-		if (info->nr_parts) {
-			del_mtd_partitions(info->mtd);
+		if (info->nr_parts)
 			kfree(info->parts);
-		} else if (pdata->nr_parts)
-			del_mtd_partitions(info->mtd);
-		else
-			del_mtd_device(info->mtd);
-#else
-		del_mtd_device(info->mtd);
-#endif
+		mtd_device_unregister(info->mtd);
 		map_destroy(info->mtd);
 	}
 	return 0;
 }
 
 static const char *rom_probe_types[] = { "cfi_probe", "jedec_probe", NULL };
-#ifdef CONFIG_MTD_PARTITIONS
 static const char *part_probe_types[] = { "cmdlinepart", NULL };
-#endif
 
 static int rbtx4939_flash_probe(struct platform_device *dev)
 {
@@ -120,23 +108,21 @@
 	if (err)
 		goto err_out;
 
-#ifdef CONFIG_MTD_PARTITIONS
 	err = parse_mtd_partitions(info->mtd, part_probe_types,
 				&info->parts, 0);
 	if (err > 0) {
-		add_mtd_partitions(info->mtd, info->parts, err);
+		mtd_device_register(info->mtd, info->parts, err);
 		info->nr_parts = err;
 		return 0;
 	}
 
 	if (pdata->nr_parts) {
 		pr_notice("Using rbtx4939 partition information\n");
-		add_mtd_partitions(info->mtd, pdata->parts, pdata->nr_parts);
+		mtd_device_register(info->mtd, pdata->parts, pdata->nr_parts);
 		return 0;
 	}
-#endif
 
-	add_mtd_device(info->mtd);
+	mtd_device_register(info->mtd, NULL, 0);
 	return 0;
 
 err_out:
diff -druN linux-2.6.39-libre/drivers/mtd/maps/rpxlite.c linux-3.0-rc7-libre/drivers/mtd/maps/rpxlite.c
--- linux-2.6.39-libre/drivers/mtd/maps/rpxlite.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mtd/maps/rpxlite.c	2011-07-11 19:51:52.000000000 -0400
@@ -36,7 +36,7 @@
 	mymtd = do_map_probe("cfi_probe", &rpxlite_map);
 	if (mymtd) {
 		mymtd->owner = THIS_MODULE;
-		add_mtd_device(mymtd);
+		mtd_device_register(mymtd, NULL, 0);
 		return 0;
 	}
 
@@ -47,7 +47,7 @@
 static void __exit cleanup_rpxlite(void)
 {
 	if (mymtd) {
-		del_mtd_device(mymtd);
+		mtd_device_unregister(mymtd);
 		map_destroy(mymtd);
 	}
 	if (rpxlite_map.virt) {
diff -druN linux-2.6.39-libre/drivers/mtd/maps/sa1100-flash.c linux-3.0-rc7-libre/drivers/mtd/maps/sa1100-flash.c
--- linux-2.6.39-libre/drivers/mtd/maps/sa1100-flash.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mtd/maps/sa1100-flash.c	2011-07-11 19:51:52.000000000 -0400
@@ -226,12 +226,7 @@
 	int i;
 
 	if (info->mtd) {
-		if (info->nr_parts == 0)
-			del_mtd_device(info->mtd);
-#ifdef CONFIG_MTD_PARTITIONS
-		else
-			del_mtd_partitions(info->mtd);
-#endif
+		mtd_device_unregister(info->mtd);
 		if (info->mtd != info->subdev[0].mtd)
 			mtd_concat_destroy(info->mtd);
 	}
@@ -363,28 +358,24 @@
 	/*
 	 * Partition selection stuff.
 	 */
-#ifdef CONFIG_MTD_PARTITIONS
 	nr_parts = parse_mtd_partitions(info->mtd, part_probes, &parts, 0);
 	if (nr_parts > 0) {
 		info->parts = parts;
 		part_type = "dynamic";
-	} else
-#endif
-	{
+	} else {
 		parts = plat->parts;
 		nr_parts = plat->nr_parts;
 		part_type = "static";
 	}
 
-	if (nr_parts == 0) {
+	if (nr_parts == 0)
 		printk(KERN_NOTICE "SA1100 flash: no partition info "
 			"available, registering whole flash\n");
-		add_mtd_device(info->mtd);
-	} else {
+	else
 		printk(KERN_NOTICE "SA1100 flash: using %s partition "
 			"definition\n", part_type);
-		add_mtd_partitions(info->mtd, parts, nr_parts);
-	}
+
+	mtd_device_register(info->mtd, parts, nr_parts);
 
 	info->nr_parts = nr_parts;
 
diff -druN linux-2.6.39-libre/drivers/mtd/maps/sbc_gxx.c linux-3.0-rc7-libre/drivers/mtd/maps/sbc_gxx.c
--- linux-2.6.39-libre/drivers/mtd/maps/sbc_gxx.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mtd/maps/sbc_gxx.c	2011-07-11 19:51:52.000000000 -0400
@@ -182,7 +182,7 @@
 static void cleanup_sbc_gxx(void)
 {
 	if( all_mtd ) {
-		del_mtd_partitions( all_mtd );
+		mtd_device_unregister(all_mtd);
 		map_destroy( all_mtd );
 	}
 
@@ -223,7 +223,7 @@
 	all_mtd->owner = THIS_MODULE;
 
 	/* Create MTD devices for each partition. */
-	add_mtd_partitions(all_mtd, partition_info, NUM_PARTITIONS );
+	mtd_device_register(all_mtd, partition_info, NUM_PARTITIONS);
 
 	return 0;
 }
diff -druN linux-2.6.39-libre/drivers/mtd/maps/sc520cdp.c linux-3.0-rc7-libre/drivers/mtd/maps/sc520cdp.c
--- linux-2.6.39-libre/drivers/mtd/maps/sc520cdp.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mtd/maps/sc520cdp.c	2011-07-11 19:51:52.000000000 -0400
@@ -266,10 +266,10 @@
 		/* Combine the two flash banks into a single MTD device & register it: */
 		merged_mtd = mtd_concat_create(mymtd, 2, "SC520CDP Flash Banks #0 and #1");
 		if(merged_mtd)
-			add_mtd_device(merged_mtd);
+			mtd_device_register(merged_mtd, NULL, 0);
 	}
 	if(devices_found == 3) /* register the third (DIL-Flash) device */
-		add_mtd_device(mymtd[2]);
+		mtd_device_register(mymtd[2], NULL, 0);
 	return(devices_found ? 0 : -ENXIO);
 }
 
@@ -278,11 +278,11 @@
 	int i;
 
 	if (merged_mtd) {
-		del_mtd_device(merged_mtd);
+		mtd_device_unregister(merged_mtd);
 		mtd_concat_destroy(merged_mtd);
 	}
 	if (mymtd[2])
-		del_mtd_device(mymtd[2]);
+		mtd_device_unregister(mymtd[2]);
 
 	for (i = 0; i < NUM_FLASH_BANKS; i++) {
 		if (mymtd[i])
diff -druN linux-2.6.39-libre/drivers/mtd/maps/scb2_flash.c linux-3.0-rc7-libre/drivers/mtd/maps/scb2_flash.c
--- linux-2.6.39-libre/drivers/mtd/maps/scb2_flash.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mtd/maps/scb2_flash.c	2011-07-11 19:51:52.000000000 -0400
@@ -180,7 +180,7 @@
 
 	scb2_mtd->owner = THIS_MODULE;
 	if (scb2_fixup_mtd(scb2_mtd) < 0) {
-		del_mtd_device(scb2_mtd);
+		mtd_device_unregister(scb2_mtd);
 		map_destroy(scb2_mtd);
 		iounmap(scb2_ioaddr);
 		if (!region_fail)
@@ -192,7 +192,7 @@
 	       (unsigned long long)scb2_mtd->size,
 	       (unsigned long long)(SCB2_WINDOW - scb2_mtd->size));
 
-	add_mtd_device(scb2_mtd);
+	mtd_device_register(scb2_mtd, NULL, 0);
 
 	return 0;
 }
@@ -207,7 +207,7 @@
 	if (scb2_mtd->lock)
 		scb2_mtd->lock(scb2_mtd, 0, scb2_mtd->size);
 
-	del_mtd_device(scb2_mtd);
+	mtd_device_unregister(scb2_mtd);
 	map_destroy(scb2_mtd);
 
 	iounmap(scb2_ioaddr);
diff -druN linux-2.6.39-libre/drivers/mtd/maps/scx200_docflash.c linux-3.0-rc7-libre/drivers/mtd/maps/scx200_docflash.c
--- linux-2.6.39-libre/drivers/mtd/maps/scx200_docflash.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mtd/maps/scx200_docflash.c	2011-07-11 19:51:52.000000000 -0400
@@ -44,7 +44,6 @@
 
 static struct mtd_info *mymtd;
 
-#ifdef CONFIG_MTD_PARTITIONS
 static struct mtd_partition partition_info[] = {
 	{
 		.name   = "DOCCS Boot kernel",
@@ -68,8 +67,6 @@
 	},
 };
 #define NUM_PARTITIONS ARRAY_SIZE(partition_info)
-#endif
-
 
 static struct map_info scx200_docflash_map = {
 	.name      = "NatSemi SCx200 DOCCS Flash",
@@ -198,24 +195,17 @@
 
 	mymtd->owner = THIS_MODULE;
 
-#ifdef CONFIG_MTD_PARTITIONS
 	partition_info[3].offset = mymtd->size-partition_info[3].size;
 	partition_info[2].size = partition_info[3].offset-partition_info[2].offset;
-	add_mtd_partitions(mymtd, partition_info, NUM_PARTITIONS);
-#else
-	add_mtd_device(mymtd);
-#endif
+	mtd_device_register(mymtd, partition_info, NUM_PARTITIONS);
+
 	return 0;
 }
 
 static void __exit cleanup_scx200_docflash(void)
 {
 	if (mymtd) {
-#ifdef CONFIG_MTD_PARTITIONS
-		del_mtd_partitions(mymtd);
-#else
-		del_mtd_device(mymtd);
-#endif
+		mtd_device_unregister(mymtd);
 		map_destroy(mymtd);
 	}
 	if (scx200_docflash_map.virt) {
diff -druN linux-2.6.39-libre/drivers/mtd/maps/solutionengine.c linux-3.0-rc7-libre/drivers/mtd/maps/solutionengine.c
--- linux-2.6.39-libre/drivers/mtd/maps/solutionengine.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mtd/maps/solutionengine.c	2011-07-11 19:51:52.000000000 -0400
@@ -89,7 +89,7 @@
 	eprom_mtd = do_map_probe("map_rom", &soleng_eprom_map);
 	if (eprom_mtd) {
 		eprom_mtd->owner = THIS_MODULE;
-		add_mtd_device(eprom_mtd);
+		mtd_device_register(eprom_mtd, NULL, 0);
 	}
 
 	nr_parts = parse_mtd_partitions(flash_mtd, probes, &parsed_parts, 0);
@@ -104,9 +104,9 @@
 #endif /* CONFIG_MTD_SUPERH_RESERVE */
 
 	if (nr_parts > 0)
-		add_mtd_partitions(flash_mtd, parsed_parts, nr_parts);
+		mtd_device_register(flash_mtd, parsed_parts, nr_parts);
 	else
-		add_mtd_device(flash_mtd);
+		mtd_device_register(flash_mtd, NULL, 0);
 
 	return 0;
 }
@@ -114,14 +114,14 @@
 static void __exit cleanup_soleng_maps(void)
 {
 	if (eprom_mtd) {
-		del_mtd_device(eprom_mtd);
+		mtd_device_unregister(eprom_mtd);
 		map_destroy(eprom_mtd);
 	}
 
 	if (parsed_parts)
-		del_mtd_partitions(flash_mtd);
+		mtd_device_unregister(flash_mtd);
 	else
-		del_mtd_device(flash_mtd);
+		mtd_device_unregister(flash_mtd);
 	map_destroy(flash_mtd);
 }
 
diff -druN linux-2.6.39-libre/drivers/mtd/maps/sun_uflash.c linux-3.0-rc7-libre/drivers/mtd/maps/sun_uflash.c
--- linux-2.6.39-libre/drivers/mtd/maps/sun_uflash.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mtd/maps/sun_uflash.c	2011-07-11 19:51:52.000000000 -0400
@@ -101,7 +101,7 @@
 
 	up->mtd->owner = THIS_MODULE;
 
-	add_mtd_device(up->mtd);
+	mtd_device_register(up->mtd, NULL, 0);
 
 	dev_set_drvdata(&op->dev, up);
 
@@ -126,7 +126,7 @@
 	struct uflash_dev *up = dev_get_drvdata(&op->dev);
 
 	if (up->mtd) {
-		del_mtd_device(up->mtd);
+		mtd_device_unregister(up->mtd);
 		map_destroy(up->mtd);
 	}
 	if (up->map.virt) {
diff -druN linux-2.6.39-libre/drivers/mtd/maps/tqm8xxl.c linux-3.0-rc7-libre/drivers/mtd/maps/tqm8xxl.c
--- linux-2.6.39-libre/drivers/mtd/maps/tqm8xxl.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mtd/maps/tqm8xxl.c	2011-07-11 19:51:52.000000000 -0400
@@ -62,7 +62,6 @@
  * "struct map_desc *_io_desc" for the corresponding machine.
  */
 
-#ifdef CONFIG_MTD_PARTITIONS
 /* Currently, TQM8xxL has up to 8MiB flash */
 static unsigned long tqm8xxl_max_flash_size = 0x00800000;
 
@@ -107,7 +106,6 @@
 	  //.size = MTDPART_SIZ_FULL,
 	}
 };
-#endif
 
 static int __init init_tqm_mtd(void)
 {
@@ -188,7 +186,6 @@
 		goto error_mem;
 	}
 
-#ifdef CONFIG_MTD_PARTITIONS
 	/*
 	 * Select Static partition definitions
 	 */
@@ -201,21 +198,14 @@
 	part_banks[1].nums = ARRAY_SIZE(tqm8xxl_fs_partitions);
 
 	for(idx = 0; idx < num_banks ; idx++) {
-		if (part_banks[idx].nums == 0) {
+		if (part_banks[idx].nums == 0)
 			printk(KERN_NOTICE "TQM flash%d: no partition info available, registering whole flash at once\n", idx);
-			add_mtd_device(mtd_banks[idx]);
-		} else {
+		else
 			printk(KERN_NOTICE "TQM flash%d: Using %s partition definition\n",
 					idx, part_banks[idx].type);
-			add_mtd_partitions(mtd_banks[idx], part_banks[idx].mtd_part,
-								part_banks[idx].nums);
-		}
+		mtd_device_register(mtd_banks[idx], part_banks[idx].mtd_part,
+		part_banks[idx].nums);
 	}
-#else
-	printk(KERN_NOTICE "TQM flash: registering %d whole flash banks at once\n", num_banks);
-	for(idx = 0 ; idx < num_banks ; idx++)
-		add_mtd_device(mtd_banks[idx]);
-#endif
 	return 0;
 error_mem:
 	for(idx = 0 ; idx < FLASH_BANK_MAX ; idx++) {
@@ -237,7 +227,7 @@
 	for(idx = 0 ; idx < num_banks ; idx++) {
 		/* destroy mtd_info previously allocated */
 		if (mtd_banks[idx]) {
-			del_mtd_partitions(mtd_banks[idx]);
+			mtd_device_unregister(mtd_banks[idx]);
 			map_destroy(mtd_banks[idx]);
 		}
 		/* release map_info not used anymore */
diff -druN linux-2.6.39-libre/drivers/mtd/maps/ts5500_flash.c linux-3.0-rc7-libre/drivers/mtd/maps/ts5500_flash.c
--- linux-2.6.39-libre/drivers/mtd/maps/ts5500_flash.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mtd/maps/ts5500_flash.c	2011-07-11 19:51:52.000000000 -0400
@@ -89,7 +89,7 @@
 	}
 
 	mymtd->owner = THIS_MODULE;
-	add_mtd_partitions(mymtd, ts5500_partitions, NUM_PARTITIONS);
+	mtd_device_register(mymtd, ts5500_partitions, NUM_PARTITIONS);
 
 	return 0;
 
@@ -102,7 +102,7 @@
 static void __exit cleanup_ts5500_map(void)
 {
 	if (mymtd) {
-		del_mtd_partitions(mymtd);
+		mtd_device_unregister(mymtd);
 		map_destroy(mymtd);
 	}
 
diff -druN linux-2.6.39-libre/drivers/mtd/maps/tsunami_flash.c linux-3.0-rc7-libre/drivers/mtd/maps/tsunami_flash.c
--- linux-2.6.39-libre/drivers/mtd/maps/tsunami_flash.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mtd/maps/tsunami_flash.c	2011-07-11 19:51:52.000000000 -0400
@@ -76,7 +76,7 @@
 	struct mtd_info *mtd;
 	mtd = tsunami_flash_mtd;
 	if (mtd) {
-		del_mtd_device(mtd);
+		mtd_device_unregister(mtd);
 		map_destroy(mtd);
 	}
 	tsunami_flash_mtd = 0;
@@ -97,7 +97,7 @@
 	}
 	if (tsunami_flash_mtd) {
 		tsunami_flash_mtd->owner = THIS_MODULE;
-		add_mtd_device(tsunami_flash_mtd);
+		mtd_device_register(tsunami_flash_mtd, NULL, 0);
 		return 0;
 	}
 	return -ENXIO;
diff -druN linux-2.6.39-libre/drivers/mtd/maps/uclinux.c linux-3.0-rc7-libre/drivers/mtd/maps/uclinux.c
--- linux-2.6.39-libre/drivers/mtd/maps/uclinux.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mtd/maps/uclinux.c	2011-07-11 19:51:52.000000000 -0400
@@ -89,11 +89,7 @@
 	mtd->priv = mapp;
 
 	uclinux_ram_mtdinfo = mtd;
-#ifdef CONFIG_MTD_PARTITIONS
-	add_mtd_partitions(mtd, uclinux_romfs, NUM_PARTITIONS);
-#else
-	add_mtd_device(mtd);
-#endif
+	mtd_device_register(mtd, uclinux_romfs, NUM_PARTITIONS);
 
 	return(0);
 }
@@ -103,11 +99,7 @@
 static void __exit uclinux_mtd_cleanup(void)
 {
 	if (uclinux_ram_mtdinfo) {
-#ifdef CONFIG_MTD_PARTITIONS
-		del_mtd_partitions(uclinux_ram_mtdinfo);
-#else
-		del_mtd_device(uclinux_ram_mtdinfo);
-#endif
+		mtd_device_unregister(uclinux_ram_mtdinfo);
 		map_destroy(uclinux_ram_mtdinfo);
 		uclinux_ram_mtdinfo = NULL;
 	}
diff -druN linux-2.6.39-libre/drivers/mtd/maps/vmax301.c linux-3.0-rc7-libre/drivers/mtd/maps/vmax301.c
--- linux-2.6.39-libre/drivers/mtd/maps/vmax301.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mtd/maps/vmax301.c	2011-07-11 19:51:52.000000000 -0400
@@ -138,7 +138,7 @@
 
 	for (i=0; i<2; i++) {
 		if (vmax_mtd[i]) {
-			del_mtd_device(vmax_mtd[i]);
+			mtd_device_unregister(vmax_mtd[i]);
 			map_destroy(vmax_mtd[i]);
 		}
 	}
@@ -176,7 +176,7 @@
 			vmax_mtd[i] = do_map_probe("map_rom", &vmax_map[i]);
 		if (vmax_mtd[i]) {
 			vmax_mtd[i]->owner = THIS_MODULE;
-			add_mtd_device(vmax_mtd[i]);
+			mtd_device_register(vmax_mtd[i], NULL, 0);
 		}
 	}
 
diff -druN linux-2.6.39-libre/drivers/mtd/maps/vmu-flash.c linux-3.0-rc7-libre/drivers/mtd/maps/vmu-flash.c
--- linux-2.6.39-libre/drivers/mtd/maps/vmu-flash.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mtd/maps/vmu-flash.c	2011-07-11 19:51:52.000000000 -0400
@@ -563,7 +563,7 @@
 		goto fail_cache_create;
 	part_cur->pcache = pcache;
 
-	error = add_mtd_device(mtd_cur);
+	error = mtd_device_register(mtd_cur, NULL, 0);
 	if (error)
 		goto fail_mtd_register;
 
@@ -709,7 +709,7 @@
 	for (x = 0; x < card->partitions; x++) {
 		mpart = ((card->mtd)[x]).priv;
 		mpart->mdev = NULL;
-		del_mtd_device(&((card->mtd)[x]));
+		mtd_device_unregister(&((card->mtd)[x]));
 		kfree(((card->parts)[x]).name);
 	}
 	kfree(card->parts);
diff -druN linux-2.6.39-libre/drivers/mtd/maps/wr_sbc82xx_flash.c linux-3.0-rc7-libre/drivers/mtd/maps/wr_sbc82xx_flash.c
--- linux-2.6.39-libre/drivers/mtd/maps/wr_sbc82xx_flash.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mtd/maps/wr_sbc82xx_flash.c	2011-07-11 19:51:52.000000000 -0400
@@ -132,17 +132,20 @@
 		nr_parts = parse_mtd_partitions(sbcmtd[i], part_probes,
 						&sbcmtd_parts[i], 0);
 		if (nr_parts > 0) {
-			add_mtd_partitions (sbcmtd[i], sbcmtd_parts[i], nr_parts);
+			mtd_device_register(sbcmtd[i], sbcmtd_parts[i],
+					    nr_parts);
 			continue;
 		}
 
 		/* No partitioning detected. Use default */
 		if (i == 2) {
-			add_mtd_device(sbcmtd[i]);
+			mtd_device_register(sbcmtd[i], NULL, 0);
 		} else if (i == bigflash) {
-			add_mtd_partitions (sbcmtd[i], bigflash_parts, ARRAY_SIZE(bigflash_parts));
+			mtd_device_register(sbcmtd[i], bigflash_parts,
+					    ARRAY_SIZE(bigflash_parts));
 		} else {
-			add_mtd_partitions (sbcmtd[i], smallflash_parts, ARRAY_SIZE(smallflash_parts));
+			mtd_device_register(sbcmtd[i], smallflash_parts,
+					    ARRAY_SIZE(smallflash_parts));
 		}
 	}
 	return 0;
@@ -157,9 +160,9 @@
 			continue;
 
 		if (i<2 || sbcmtd_parts[i])
-			del_mtd_partitions(sbcmtd[i]);
+			mtd_device_unregister(sbcmtd[i]);
 		else
-			del_mtd_device(sbcmtd[i]);
+			mtd_device_unregister(sbcmtd[i]);
 
 		kfree(sbcmtd_parts[i]);
 		map_destroy(sbcmtd[i]);
diff -druN linux-2.6.39-libre/drivers/mtd/mtd_blkdevs.c linux-3.0-rc7-libre/drivers/mtd/mtd_blkdevs.c
--- linux-2.6.39-libre/drivers/mtd/mtd_blkdevs.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mtd/mtd_blkdevs.c	2011-07-11 19:51:52.000000000 -0400
@@ -221,15 +221,33 @@
 	kref_get(&dev->ref);
 	__module_get(dev->tr->owner);
 
-	if (dev->mtd) {
-		ret = dev->tr->open ? dev->tr->open(dev) : 0;
-		__get_mtd_device(dev->mtd);
+	if (!dev->mtd)
+		goto unlock;
+
+	if (dev->tr->open) {
+		ret = dev->tr->open(dev);
+		if (ret)
+			goto error_put;
 	}
 
+	ret = __get_mtd_device(dev->mtd);
+	if (ret)
+		goto error_release;
+
 unlock:
 	mutex_unlock(&dev->lock);
 	blktrans_dev_put(dev);
 	return ret;
+
+error_release:
+	if (dev->tr->release)
+		dev->tr->release(dev);
+error_put:
+	module_put(dev->tr->owner);
+	kref_put(&dev->ref, blktrans_dev_release);
+	mutex_unlock(&dev->lock);
+	blktrans_dev_put(dev);
+	return ret;
 }
 
 static int blktrans_release(struct gendisk *disk, fmode_t mode)
diff -druN linux-2.6.39-libre/drivers/mtd/mtdchar.c linux-3.0-rc7-libre/drivers/mtd/mtdchar.c
--- linux-2.6.39-libre/drivers/mtd/mtdchar.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mtd/mtdchar.c	2011-07-11 19:51:52.000000000 -0400
@@ -166,10 +166,23 @@
 	return 0;
 } /* mtd_close */
 
-/* FIXME: This _really_ needs to die. In 2.5, we should lock the
-   userspace buffer down and use it directly with readv/writev.
-*/
-#define MAX_KMALLOC_SIZE 0x20000
+/* Back in June 2001, dwmw2 wrote:
+ *
+ *   FIXME: This _really_ needs to die. In 2.5, we should lock the
+ *   userspace buffer down and use it directly with readv/writev.
+ *
+ * The implementation below, using mtd_kmalloc_up_to, mitigates
+ * allocation failures when the system is under low-memory situations
+ * or if memory is highly fragmented at the cost of reducing the
+ * performance of the requested transfer due to a smaller buffer size.
+ *
+ * A more complex but more memory-efficient implementation based on
+ * get_user_pages and iovecs to cover extents of those pages is a
+ * longer-term goal, as intimated by dwmw2 above. However, for the
+ * write case, this requires yet more complex head and tail transfer
+ * handling when those head and tail offsets and sizes are such that
+ * alignment requirements are not met in the NAND subdriver.
+ */
 
 static ssize_t mtd_read(struct file *file, char __user *buf, size_t count,loff_t *ppos)
 {
@@ -179,6 +192,7 @@
 	size_t total_retlen=0;
 	int ret=0;
 	int len;
+	size_t size = count;
 	char *kbuf;
 
 	DEBUG(MTD_DEBUG_LEVEL0,"MTD_read\n");
@@ -189,23 +203,12 @@
 	if (!count)
 		return 0;
 
-	/* FIXME: Use kiovec in 2.5 to lock down the user's buffers
-	   and pass them directly to the MTD functions */
-
-	if (count > MAX_KMALLOC_SIZE)
-		kbuf=kmalloc(MAX_KMALLOC_SIZE, GFP_KERNEL);
-	else
-		kbuf=kmalloc(count, GFP_KERNEL);
-
+	kbuf = mtd_kmalloc_up_to(mtd, &size);
 	if (!kbuf)
 		return -ENOMEM;
 
 	while (count) {
-
-		if (count > MAX_KMALLOC_SIZE)
-			len = MAX_KMALLOC_SIZE;
-		else
-			len = count;
+		len = min_t(size_t, count, size);
 
 		switch (mfi->mode) {
 		case MTD_MODE_OTP_FACTORY:
@@ -268,6 +271,7 @@
 {
 	struct mtd_file_info *mfi = file->private_data;
 	struct mtd_info *mtd = mfi->mtd;
+	size_t size = count;
 	char *kbuf;
 	size_t retlen;
 	size_t total_retlen=0;
@@ -285,20 +289,12 @@
 	if (!count)
 		return 0;
 
-	if (count > MAX_KMALLOC_SIZE)
-		kbuf=kmalloc(MAX_KMALLOC_SIZE, GFP_KERNEL);
-	else
-		kbuf=kmalloc(count, GFP_KERNEL);
-
+	kbuf = mtd_kmalloc_up_to(mtd, &size);
 	if (!kbuf)
 		return -ENOMEM;
 
 	while (count) {
-
-		if (count > MAX_KMALLOC_SIZE)
-			len = MAX_KMALLOC_SIZE;
-		else
-			len = count;
+		len = min_t(size_t, count, size);
 
 		if (copy_from_user(kbuf, buf, len)) {
 			kfree(kbuf);
@@ -512,7 +508,6 @@
 	return 0;
 }
 
-#ifdef CONFIG_MTD_PARTITIONS
 static int mtd_blkpg_ioctl(struct mtd_info *mtd,
 			   struct blkpg_ioctl_arg __user *arg)
 {
@@ -548,8 +543,6 @@
 		return -EINVAL;
 	}
 }
-#endif
-
 
 static int mtd_ioctl(struct file *file, u_int cmd, u_long arg)
 {
@@ -941,7 +934,6 @@
 		break;
 	}
 
-#ifdef CONFIG_MTD_PARTITIONS
 	case BLKPG:
 	{
 		ret = mtd_blkpg_ioctl(mtd,
@@ -955,7 +947,6 @@
 		ret = 0;
 		break;
 	}
-#endif
 
 	default:
 		ret = -ENOTTY;
diff -druN linux-2.6.39-libre/drivers/mtd/mtdconcat.c linux-3.0-rc7-libre/drivers/mtd/mtdconcat.c
--- linux-2.6.39-libre/drivers/mtd/mtdconcat.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mtd/mtdconcat.c	2011-07-11 19:51:52.000000000 -0400
@@ -319,7 +319,7 @@
 	if (!(mtd->flags & MTD_WRITEABLE))
 		return -EROFS;
 
-	ops->retlen = 0;
+	ops->retlen = ops->oobretlen = 0;
 
 	for (i = 0; i < concat->num_subdev; i++) {
 		struct mtd_info *subdev = concat->subdev[i];
@@ -334,7 +334,7 @@
 			devops.len = subdev->size - to;
 
 		err = subdev->write_oob(subdev, to, &devops);
-		ops->retlen += devops.retlen;
+		ops->retlen += devops.oobretlen;
 		if (err)
 			return err;
 
diff -druN linux-2.6.39-libre/drivers/mtd/mtdcore.c linux-3.0-rc7-libre/drivers/mtd/mtdcore.c
--- linux-2.6.39-libre/drivers/mtd/mtdcore.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mtd/mtdcore.c	2011-07-11 19:51:52.000000000 -0400
@@ -24,6 +24,7 @@
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/ptrace.h>
+#include <linux/seq_file.h>
 #include <linux/string.h>
 #include <linux/timer.h>
 #include <linux/major.h>
@@ -37,6 +38,7 @@
 #include <linux/gfp.h>
 
 #include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
 
 #include "mtdcore.h"
 /*
@@ -391,7 +393,7 @@
  *	if the requested device does not appear to be present in the list.
  */
 
-int del_mtd_device (struct mtd_info *mtd)
+int del_mtd_device(struct mtd_info *mtd)
 {
 	int ret;
 	struct mtd_notifier *not;
@@ -427,6 +429,50 @@
 }
 
 /**
+ * mtd_device_register - register an MTD device.
+ *
+ * @master: the MTD device to register
+ * @parts: the partitions to register - only valid if nr_parts > 0
+ * @nr_parts: the number of partitions in parts.  If zero then the full MTD
+ *            device is registered
+ *
+ * Register an MTD device with the system and optionally, a number of
+ * partitions.  If nr_parts is 0 then the whole device is registered, otherwise
+ * only the partitions are registered.  To register both the full device *and*
+ * the partitions, call mtd_device_register() twice, once with nr_parts == 0
+ * and once equal to the number of partitions.
+ */
+int mtd_device_register(struct mtd_info *master,
+			const struct mtd_partition *parts,
+			int nr_parts)
+{
+	return parts ? add_mtd_partitions(master, parts, nr_parts) :
+		add_mtd_device(master);
+}
+EXPORT_SYMBOL_GPL(mtd_device_register);
+
+/**
+ * mtd_device_unregister - unregister an existing MTD device.
+ *
+ * @master: the MTD device to unregister.  This will unregister both the master
+ *          and any partitions if registered.
+ */
+int mtd_device_unregister(struct mtd_info *master)
+{
+	int err;
+
+	err = del_mtd_partitions(master);
+	if (err)
+		return err;
+
+	if (!device_is_registered(&master->dev))
+		return 0;
+
+	return del_mtd_device(master);
+}
+EXPORT_SYMBOL_GPL(mtd_device_unregister);
+
+/**
  *	register_mtd_user - register a 'user' of MTD devices.
  *	@new: pointer to notifier info structure
  *
@@ -443,7 +489,7 @@
 
 	list_add(&new->list, &mtd_notifiers);
 
- 	__module_get(THIS_MODULE);
+	__module_get(THIS_MODULE);
 
 	mtd_for_each_device(mtd)
 		new->add(mtd);
@@ -532,7 +578,6 @@
 		return -ENODEV;
 
 	if (mtd->get_device) {
-
 		err = mtd->get_device(mtd);
 
 		if (err) {
@@ -570,21 +615,13 @@
 	if (!mtd)
 		goto out_unlock;
 
-	if (!try_module_get(mtd->owner))
+	err = __get_mtd_device(mtd);
+	if (err)
 		goto out_unlock;
 
-	if (mtd->get_device) {
-		err = mtd->get_device(mtd);
-		if (err)
-			goto out_put;
-	}
-
-	mtd->usecount++;
 	mutex_unlock(&mtd_table_mutex);
 	return mtd;
 
-out_put:
-	module_put(mtd->owner);
 out_unlock:
 	mutex_unlock(&mtd_table_mutex);
 	return ERR_PTR(err);
@@ -638,8 +675,54 @@
 	return ret;
 }
 
-EXPORT_SYMBOL_GPL(add_mtd_device);
-EXPORT_SYMBOL_GPL(del_mtd_device);
+/**
+ * mtd_kmalloc_up_to - allocate a contiguous buffer up to the specified size
+ * @size: A pointer to the ideal or maximum size of the allocation. Points
+ *        to the actual allocation size on success.
+ *
+ * This routine attempts to allocate a contiguous kernel buffer up to
+ * the specified size, backing off the size of the request exponentially
+ * until the request succeeds or until the allocation size falls below
+ * the system page size. This attempts to make sure it does not adversely
+ * impact system performance, so when allocating more than one page, we
+ * ask the memory allocator to avoid re-trying, swapping, writing back
+ * or performing I/O.
+ *
+ * Note, this function also makes sure that the allocated buffer is aligned to
+ * the MTD device's min. I/O unit, i.e. the "mtd->writesize" value.
+ *
+ * This is called, for example by mtd_{read,write} and jffs2_scan_medium,
+ * to handle smaller (i.e. degraded) buffer allocations under low- or
+ * fragmented-memory situations where such reduced allocations, from a
+ * requested ideal, are allowed.
+ *
+ * Returns a pointer to the allocated buffer on success; otherwise, NULL.
+ */
+void *mtd_kmalloc_up_to(const struct mtd_info *mtd, size_t *size)
+{
+	gfp_t flags = __GFP_NOWARN | __GFP_WAIT |
+		       __GFP_NORETRY | __GFP_NO_KSWAPD;
+	size_t min_alloc = max_t(size_t, mtd->writesize, PAGE_SIZE);
+	void *kbuf;
+
+	*size = min_t(size_t, *size, KMALLOC_MAX_SIZE);
+
+	while (*size > min_alloc) {
+		kbuf = kmalloc(*size, flags);
+		if (kbuf)
+			return kbuf;
+
+		*size >>= 1;
+		*size = ALIGN(*size, mtd->writesize);
+	}
+
+	/*
+	 * For the last resort allocation allow 'kmalloc()' to do all sorts of
+	 * things (write-back, dropping caches, etc) by using GFP_KERNEL.
+	 */
+	return kmalloc(*size, GFP_KERNEL);
+}
+
 EXPORT_SYMBOL_GPL(get_mtd_device);
 EXPORT_SYMBOL_GPL(get_mtd_device_nm);
 EXPORT_SYMBOL_GPL(__get_mtd_device);
@@ -648,6 +731,7 @@
 EXPORT_SYMBOL_GPL(register_mtd_user);
 EXPORT_SYMBOL_GPL(unregister_mtd_user);
 EXPORT_SYMBOL_GPL(default_mtd_writev);
+EXPORT_SYMBOL_GPL(mtd_kmalloc_up_to);
 
 #ifdef CONFIG_PROC_FS
 
@@ -656,44 +740,32 @@
 
 static struct proc_dir_entry *proc_mtd;
 
-static inline int mtd_proc_info(char *buf, struct mtd_info *this)
-{
-	return sprintf(buf, "mtd%d: %8.8llx %8.8x \"%s\"\n", this->index,
-		       (unsigned long long)this->size,
-		       this->erasesize, this->name);
-}
-
-static int mtd_read_proc (char *page, char **start, off_t off, int count,
-			  int *eof, void *data_unused)
+static int mtd_proc_show(struct seq_file *m, void *v)
 {
 	struct mtd_info *mtd;
-	int len, l;
-        off_t   begin = 0;
 
+	seq_puts(m, "dev:    size   erasesize  name\n");
 	mutex_lock(&mtd_table_mutex);
-
-	len = sprintf(page, "dev:    size   erasesize  name\n");
 	mtd_for_each_device(mtd) {
-		l = mtd_proc_info(page + len, mtd);
-                len += l;
-                if (len+begin > off+count)
-                        goto done;
-                if (len+begin < off) {
-                        begin += len;
-                        len = 0;
-                }
-        }
-
-        *eof = 1;
-
-done:
+		seq_printf(m, "mtd%d: %8.8llx %8.8x \"%s\"\n",
+			   mtd->index, (unsigned long long)mtd->size,
+			   mtd->erasesize, mtd->name);
+	}
 	mutex_unlock(&mtd_table_mutex);
-        if (off >= len+begin)
-                return 0;
-        *start = page + (off-begin);
-        return ((count < begin+len-off) ? count : begin+len-off);
+	return 0;
+}
+
+static int mtd_proc_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, mtd_proc_show, NULL);
 }
 
+static const struct file_operations mtd_proc_ops = {
+	.open		= mtd_proc_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
 #endif /* CONFIG_PROC_FS */
 
 /*====================================================================*/
@@ -734,8 +806,7 @@
 		goto err_bdi3;
 
 #ifdef CONFIG_PROC_FS
-	if ((proc_mtd = create_proc_entry( "mtd", 0, NULL )))
-		proc_mtd->read_proc = mtd_read_proc;
+	proc_mtd = proc_create("mtd", 0, NULL, &mtd_proc_ops);
 #endif /* CONFIG_PROC_FS */
 	return 0;
 
@@ -753,7 +824,7 @@
 static void __exit cleanup_mtd(void)
 {
 #ifdef CONFIG_PROC_FS
-        if (proc_mtd)
+	if (proc_mtd)
 		remove_proc_entry( "mtd", NULL);
 #endif /* CONFIG_PROC_FS */
 	class_unregister(&mtd_class);
diff -druN linux-2.6.39-libre/drivers/mtd/mtdcore.h linux-3.0-rc7-libre/drivers/mtd/mtdcore.h
--- linux-2.6.39-libre/drivers/mtd/mtdcore.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mtd/mtdcore.h	2011-07-11 19:51:52.000000000 -0400
@@ -10,6 +10,12 @@
 extern struct mutex mtd_table_mutex;
 extern struct mtd_info *__mtd_next_device(int i);
 
+extern int add_mtd_device(struct mtd_info *mtd);
+extern int del_mtd_device(struct mtd_info *mtd);
+extern int add_mtd_partitions(struct mtd_info *, const struct mtd_partition *,
+			      int);
+extern int del_mtd_partitions(struct mtd_info *);
+
 #define mtd_for_each_device(mtd)			\
 	for ((mtd) = __mtd_next_device(0);		\
 	     (mtd) != NULL;				\
diff -druN linux-2.6.39-libre/drivers/mtd/mtdpart.c linux-3.0-rc7-libre/drivers/mtd/mtdpart.c
--- linux-2.6.39-libre/drivers/mtd/mtdpart.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mtd/mtdpart.c	2011-07-11 19:51:52.000000000 -0400
@@ -31,6 +31,8 @@
 #include <linux/mtd/partitions.h>
 #include <linux/err.h>
 
+#include "mtdcore.h"
+
 /* Our partition linked list */
 static LIST_HEAD(mtd_partitions);
 static DEFINE_MUTEX(mtd_partitions_mutex);
@@ -376,7 +378,6 @@
 
 	return err;
 }
-EXPORT_SYMBOL(del_mtd_partitions);
 
 static struct mtd_part *allocate_partition(struct mtd_info *master,
 			const struct mtd_partition *part, int partno,
@@ -671,7 +672,6 @@
 
 	return 0;
 }
-EXPORT_SYMBOL(add_mtd_partitions);
 
 static DEFINE_SPINLOCK(part_parser_lock);
 static LIST_HEAD(part_parsers);
@@ -722,11 +722,8 @@
 		parser = get_partition_parser(*types);
 		if (!parser && !request_module("%s", *types))
 				parser = get_partition_parser(*types);
-		if (!parser) {
-			printk(KERN_NOTICE "%s partition parsing not available\n",
-			       *types);
+		if (!parser)
 			continue;
-		}
 		ret = (*parser->parse_fn)(master, pparts, origin);
 		if (ret > 0) {
 			printk(KERN_NOTICE "%d %s partitions found on MTD device %s\n",
diff -druN linux-2.6.39-libre/drivers/mtd/mtdswap.c linux-3.0-rc7-libre/drivers/mtd/mtdswap.c
--- linux-2.6.39-libre/drivers/mtd/mtdswap.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mtd/mtdswap.c	2011-07-11 19:51:52.000000000 -0400
@@ -1450,7 +1450,13 @@
 	}
 
 	oinfo = mtd->ecclayout;
-	if (!mtd->oobsize || !oinfo || oinfo->oobavail < MTDSWAP_OOBSIZE) {
+	if (!oinfo) {
+		printk(KERN_ERR "%s: mtd%d does not have OOB\n",
+			MTDSWAP_PREFIX, mtd->index);
+		return;
+	}
+
+	if (!mtd->oobsize || oinfo->oobavail < MTDSWAP_OOBSIZE) {
 		printk(KERN_ERR "%s: Not enough free bytes in OOB, "
 			"%d available, %zu needed.\n",
 			MTDSWAP_PREFIX, oinfo->oobavail, MTDSWAP_OOBSIZE);
diff -druN linux-2.6.39-libre/drivers/mtd/nand/alauda.c linux-3.0-rc7-libre/drivers/mtd/nand/alauda.c
--- linux-2.6.39-libre/drivers/mtd/nand/alauda.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mtd/nand/alauda.c	2011-07-11 19:51:52.000000000 -0400
@@ -120,7 +120,7 @@
 	struct alauda *al = container_of(kref, struct alauda, kref);
 
 	if (al->mtd) {
-		del_mtd_device(al->mtd);
+		mtd_device_unregister(al->mtd);
 		kfree(al->mtd);
 	}
 	usb_put_dev(al->dev);
@@ -592,7 +592,7 @@
 	mtd->priv = al;
 	mtd->owner = THIS_MODULE;
 
-	err = add_mtd_device(mtd);
+	err = mtd_device_register(mtd, NULL, 0);
 	if (err) {
 		err = -ENFILE;
 		goto error;
diff -druN linux-2.6.39-libre/drivers/mtd/nand/ams-delta.c linux-3.0-rc7-libre/drivers/mtd/nand/ams-delta.c
--- linux-2.6.39-libre/drivers/mtd/nand/ams-delta.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mtd/nand/ams-delta.c	2011-07-11 19:51:52.000000000 -0400
@@ -235,8 +235,8 @@
 	}
 
 	/* Register the partitions */
-	add_mtd_partitions(ams_delta_mtd, partition_info,
-			   ARRAY_SIZE(partition_info));
+	mtd_device_register(ams_delta_mtd, partition_info,
+			    ARRAY_SIZE(partition_info));
 
 	goto out;
 
diff -druN linux-2.6.39-libre/drivers/mtd/nand/atmel_nand.c linux-3.0-rc7-libre/drivers/mtd/nand/atmel_nand.c
--- linux-2.6.39-libre/drivers/mtd/nand/atmel_nand.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mtd/nand/atmel_nand.c	2011-07-11 19:51:52.000000000 -0400
@@ -30,6 +30,7 @@
 #include <linux/mtd/nand.h>
 #include <linux/mtd/partitions.h>
 
+#include <linux/dmaengine.h>
 #include <linux/gpio.h>
 #include <linux/io.h>
 
@@ -494,11 +495,8 @@
 	struct resource *regs;
 	struct resource *mem;
 	int res;
-
-#ifdef CONFIG_MTD_PARTITIONS
 	struct mtd_partition *partitions = NULL;
 	int num_partitions = 0;
-#endif
 
 	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	if (!mem) {
@@ -656,7 +654,6 @@
 		goto err_scan_tail;
 	}
 
-#ifdef CONFIG_MTD_PARTITIONS
 #ifdef CONFIG_MTD_CMDLINE_PARTS
 	mtd->name = "atmel_nand";
 	num_partitions = parse_mtd_partitions(mtd, part_probes,
@@ -672,17 +669,11 @@
 		goto err_no_partitions;
 	}
 
-	res = add_mtd_partitions(mtd, partitions, num_partitions);
-#else
-	res = add_mtd_device(mtd);
-#endif
-
+	res = mtd_device_register(mtd, partitions, num_partitions);
 	if (!res)
 		return res;
 
-#ifdef CONFIG_MTD_PARTITIONS
 err_no_partitions:
-#endif
 	nand_release(mtd);
 err_scan_tail:
 err_scan_ident:
diff -druN linux-2.6.39-libre/drivers/mtd/nand/au1550nd.c linux-3.0-rc7-libre/drivers/mtd/nand/au1550nd.c
--- linux-2.6.39-libre/drivers/mtd/nand/au1550nd.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mtd/nand/au1550nd.c	2011-07-11 19:51:52.000000000 -0400
@@ -10,6 +10,7 @@
  */
 
 #include <linux/slab.h>
+#include <linux/gpio.h>
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/interrupt.h>
@@ -470,7 +471,7 @@
 
 #ifdef CONFIG_MIPS_PB1550
 	/* set gpio206 high */
-	au_writel(au_readl(GPIO2_DIR) & ~(1 << 6), GPIO2_DIR);
+	gpio_direction_input(206);
 
 	boot_swapboot = (au_readl(MEM_STSTAT) & (0x7 << 1)) | ((bcsr_read(BCSR_STATUS) >> 6) & 0x1);
 
@@ -580,7 +581,8 @@
 	}
 
 	/* Register the partitions */
-	add_mtd_partitions(au1550_mtd, partition_info, ARRAY_SIZE(partition_info));
+	mtd_device_register(au1550_mtd, partition_info,
+			    ARRAY_SIZE(partition_info));
 
 	return 0;
 
diff -druN linux-2.6.39-libre/drivers/mtd/nand/autcpu12.c linux-3.0-rc7-libre/drivers/mtd/nand/autcpu12.c
--- linux-2.6.39-libre/drivers/mtd/nand/autcpu12.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mtd/nand/autcpu12.c	2011-07-11 19:51:52.000000000 -0400
@@ -185,20 +185,20 @@
 	/* Register the partitions */
 	switch (autcpu12_mtd->size) {
 		case SZ_16M:
-			add_mtd_partitions(autcpu12_mtd, partition_info16k,
-					   NUM_PARTITIONS16K);
+			mtd_device_register(autcpu12_mtd, partition_info16k,
+					    NUM_PARTITIONS16K);
 			break;
 		case SZ_32M:
-			add_mtd_partitions(autcpu12_mtd, partition_info32k,
-					   NUM_PARTITIONS32K);
+			mtd_device_register(autcpu12_mtd, partition_info32k,
+					    NUM_PARTITIONS32K);
 			break;
 		case SZ_64M:
-			add_mtd_partitions(autcpu12_mtd, partition_info64k,
-					   NUM_PARTITIONS64K);
+			mtd_device_register(autcpu12_mtd, partition_info64k,
+					    NUM_PARTITIONS64K);
 			break;
 		case SZ_128M:
-			add_mtd_partitions(autcpu12_mtd, partition_info128k,
-					   NUM_PARTITIONS128K);
+			mtd_device_register(autcpu12_mtd, partition_info128k,
+					    NUM_PARTITIONS128K);
 			break;
 		default:
 			printk("Unsupported SmartMedia device\n");
diff -druN linux-2.6.39-libre/drivers/mtd/nand/bcm_umi_nand.c linux-3.0-rc7-libre/drivers/mtd/nand/bcm_umi_nand.c
--- linux-2.6.39-libre/drivers/mtd/nand/bcm_umi_nand.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mtd/nand/bcm_umi_nand.c	2011-07-11 19:51:52.000000000 -0400
@@ -52,9 +52,7 @@
 static const __devinitconst char gBanner[] = KERN_INFO \
 	"BCM UMI MTD NAND Driver: 1.00\n";
 
-#ifdef CONFIG_MTD_PARTITIONS
 const char *part_probes[] = { "cmdlinepart", NULL };
-#endif
 
 #if NAND_ECC_BCH
 static uint8_t scan_ff_pattern[] = { 0xff };
@@ -509,7 +507,7 @@
 			kfree(board_mtd);
 			return -EIO;
 		}
-		add_mtd_partitions(board_mtd, partition_info, nr_partitions);
+		mtd_device_register(board_mtd, partition_info, nr_partitions);
 	}
 
 	/* Return happy */
diff -druN linux-2.6.39-libre/drivers/mtd/nand/bf5xx_nand.c linux-3.0-rc7-libre/drivers/mtd/nand/bf5xx_nand.c
--- linux-2.6.39-libre/drivers/mtd/nand/bf5xx_nand.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mtd/nand/bf5xx_nand.c	2011-07-11 19:51:52.000000000 -0400
@@ -659,15 +659,10 @@
 static int __devinit bf5xx_nand_add_partition(struct bf5xx_nand_info *info)
 {
 	struct mtd_info *mtd = &info->mtd;
-
-#ifdef CONFIG_MTD_PARTITIONS
 	struct mtd_partition *parts = info->platform->partitions;
 	int nr = info->platform->nr_partitions;
 
-	return add_mtd_partitions(mtd, parts, nr);
-#else
-	return add_mtd_device(mtd);
-#endif
+	return mtd_device_register(mtd, parts, nr);
 }
 
 static int __devexit bf5xx_nand_remove(struct platform_device *pdev)
diff -druN linux-2.6.39-libre/drivers/mtd/nand/cafe_nand.c linux-3.0-rc7-libre/drivers/mtd/nand/cafe_nand.c
--- linux-2.6.39-libre/drivers/mtd/nand/cafe_nand.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mtd/nand/cafe_nand.c	2011-07-11 19:51:52.000000000 -0400
@@ -90,9 +90,7 @@
 static int timing[3];
 module_param_array(timing, int, &numtimings, 0644);
 
-#ifdef CONFIG_MTD_PARTITIONS
 static const char *part_probes[] = { "cmdlinepart", "RedBoot", NULL };
-#endif
 
 /* Hrm. Why isn't this already conditional on something in the struct device? */
 #define cafe_dev_dbg(dev, args...) do { if (debug) dev_dbg(dev, ##args); } while(0)
@@ -632,10 +630,8 @@
 	struct cafe_priv *cafe;
 	uint32_t ctrl;
 	int err = 0;
-#ifdef CONFIG_MTD_PARTITIONS
 	struct mtd_partition *parts;
 	int nr_parts;
-#endif
 
 	/* Very old versions shared the same PCI ident for all three
 	   functions on the chip. Verify the class too... */
@@ -804,9 +800,8 @@
 	pci_set_drvdata(pdev, mtd);
 
 	/* We register the whole device first, separate from the partitions */
-	add_mtd_device(mtd);
+	mtd_device_register(mtd, NULL, 0);
 
-#ifdef CONFIG_MTD_PARTITIONS
 #ifdef CONFIG_MTD_CMDLINE_PARTS
 	mtd->name = "cafe_nand";
 #endif
@@ -814,9 +809,8 @@
 	if (nr_parts > 0) {
 		cafe->parts = parts;
 		dev_info(&cafe->pdev->dev, "%d partitions found\n", nr_parts);
-		add_mtd_partitions(mtd, parts, nr_parts);
+		mtd_device_register(mtd, parts, nr_parts);
 	}
-#endif
 	goto out;
 
  out_irq:
@@ -838,7 +832,6 @@
 	struct mtd_info *mtd = pci_get_drvdata(pdev);
 	struct cafe_priv *cafe = mtd->priv;
 
-	del_mtd_device(mtd);
 	/* Disable NAND IRQ in global IRQ mask register */
 	cafe_writel(cafe, ~1 & cafe_readl(cafe, GLOBAL_IRQ_MASK), GLOBAL_IRQ_MASK);
 	free_irq(pdev->irq, mtd);
diff -druN linux-2.6.39-libre/drivers/mtd/nand/cmx270_nand.c linux-3.0-rc7-libre/drivers/mtd/nand/cmx270_nand.c
--- linux-2.6.39-libre/drivers/mtd/nand/cmx270_nand.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mtd/nand/cmx270_nand.c	2011-07-11 19:51:52.000000000 -0400
@@ -238,7 +238,7 @@
 
 	/* Register the partitions */
 	pr_notice("Using %s partition definition\n", part_type);
-	ret = add_mtd_partitions(cmx270_nand_mtd, mtd_parts, mtd_parts_nb);
+	ret = mtd_device_register(cmx270_nand_mtd, mtd_parts, mtd_parts_nb);
 	if (ret)
 		goto err_scan;
 
diff -druN linux-2.6.39-libre/drivers/mtd/nand/cs553x_nand.c linux-3.0-rc7-libre/drivers/mtd/nand/cs553x_nand.c
--- linux-2.6.39-libre/drivers/mtd/nand/cs553x_nand.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mtd/nand/cs553x_nand.c	2011-07-11 19:51:52.000000000 -0400
@@ -277,22 +277,15 @@
 	return 0;
 }
 
-
-#ifdef CONFIG_MTD_PARTITIONS
 static const char *part_probes[] = { "cmdlinepart", NULL };
-#endif
-
 
 static int __init cs553x_init(void)
 {
 	int err = -ENXIO;
 	int i;
 	uint64_t val;
-
-#ifdef CONFIG_MTD_PARTITIONS
 	int mtd_parts_nb = 0;
 	struct mtd_partition *mtd_parts = NULL;
-#endif
 
 	/* If the CPU isn't a Geode GX or LX, abort */
 	if (!is_geode())
@@ -324,17 +317,11 @@
 		if (cs553x_mtd[i]) {
 
 			/* If any devices registered, return success. Else the last error. */
-#ifdef CONFIG_MTD_PARTITIONS
 			mtd_parts_nb = parse_mtd_partitions(cs553x_mtd[i], part_probes, &mtd_parts, 0);
-			if (mtd_parts_nb > 0) {
+			if (mtd_parts_nb > 0)
 				printk(KERN_NOTICE "Using command line partition definition\n");
-				add_mtd_partitions(cs553x_mtd[i], mtd_parts, mtd_parts_nb);
-			} else {
-				add_mtd_device(cs553x_mtd[i]);
-			}
-#else
-			add_mtd_device(cs553x_mtd[i]);
-#endif
+			mtd_device_register(cs553x_mtd[i], mtd_parts,
+					    mtd_parts_nb);
 			err = 0;
 		}
 	}
diff -druN linux-2.6.39-libre/drivers/mtd/nand/davinci_nand.c linux-3.0-rc7-libre/drivers/mtd/nand/davinci_nand.c
--- linux-2.6.39-libre/drivers/mtd/nand/davinci_nand.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mtd/nand/davinci_nand.c	2011-07-11 19:51:52.000000000 -0400
@@ -530,6 +530,8 @@
 	int				ret;
 	uint32_t			val;
 	nand_ecc_modes_t		ecc_mode;
+	struct mtd_partition		*mtd_parts = NULL;
+	int				mtd_parts_nb = 0;
 
 	/* insist on board-specific configuration */
 	if (!pdata)
@@ -749,41 +751,33 @@
 	if (ret < 0)
 		goto err_scan;
 
-	if (mtd_has_partitions()) {
-		struct mtd_partition	*mtd_parts = NULL;
-		int			mtd_parts_nb = 0;
-
-		if (mtd_has_cmdlinepart()) {
-			static const char *probes[] __initconst =
-				{ "cmdlinepart", NULL };
-
-			mtd_parts_nb = parse_mtd_partitions(&info->mtd, probes,
-							    &mtd_parts, 0);
-		}
+	if (mtd_has_cmdlinepart()) {
+		static const char *probes[] __initconst = {
+			"cmdlinepart", NULL
+		};
 
-		if (mtd_parts_nb <= 0) {
-			mtd_parts = pdata->parts;
-			mtd_parts_nb = pdata->nr_parts;
-		}
+		mtd_parts_nb = parse_mtd_partitions(&info->mtd, probes,
+						    &mtd_parts, 0);
+	}
 
-		/* Register any partitions */
-		if (mtd_parts_nb > 0) {
-			ret = add_mtd_partitions(&info->mtd,
-					mtd_parts, mtd_parts_nb);
-			if (ret == 0)
-				info->partitioned = true;
-		}
+	if (mtd_parts_nb <= 0) {
+		mtd_parts = pdata->parts;
+		mtd_parts_nb = pdata->nr_parts;
+	}
 
-	} else if (pdata->nr_parts) {
-		dev_warn(&pdev->dev, "ignoring %d default partitions on %s\n",
-				pdata->nr_parts, info->mtd.name);
+	/* Register any partitions */
+	if (mtd_parts_nb > 0) {
+		ret = mtd_device_register(&info->mtd, mtd_parts,
+					  mtd_parts_nb);
+		if (ret == 0)
+			info->partitioned = true;
 	}
 
 	/* If there's no partition info, just package the whole chip
 	 * as a single MTD device.
 	 */
 	if (!info->partitioned)
-		ret = add_mtd_device(&info->mtd) ? -ENODEV : 0;
+		ret = mtd_device_register(&info->mtd, NULL, 0) ? -ENODEV : 0;
 
 	if (ret < 0)
 		goto err_scan;
@@ -824,10 +818,7 @@
 	struct davinci_nand_info *info = platform_get_drvdata(pdev);
 	int status;
 
-	if (mtd_has_partitions() && info->partitioned)
-		status = del_mtd_partitions(&info->mtd);
-	else
-		status = del_mtd_device(&info->mtd);
+	status = mtd_device_unregister(&info->mtd);
 
 	spin_lock_irq(&davinci_nand_lock);
 	if (info->chip.ecc.mode == NAND_ECC_HW_SYNDROME)
diff -druN linux-2.6.39-libre/drivers/mtd/nand/denali.c linux-3.0-rc7-libre/drivers/mtd/nand/denali.c
--- linux-2.6.39-libre/drivers/mtd/nand/denali.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mtd/nand/denali.c	2011-07-11 19:51:52.000000000 -0400
@@ -19,6 +19,7 @@
 
 #include <linux/interrupt.h>
 #include <linux/delay.h>
+#include <linux/dma-mapping.h>
 #include <linux/wait.h>
 #include <linux/mutex.h>
 #include <linux/slab.h>
@@ -44,16 +45,16 @@
 
 /* We define a macro here that combines all interrupts this driver uses into
  * a single constant value, for convenience. */
-#define DENALI_IRQ_ALL	(INTR_STATUS0__DMA_CMD_COMP | \
-			INTR_STATUS0__ECC_TRANSACTION_DONE | \
-			INTR_STATUS0__ECC_ERR | \
-			INTR_STATUS0__PROGRAM_FAIL | \
-			INTR_STATUS0__LOAD_COMP | \
-			INTR_STATUS0__PROGRAM_COMP | \
-			INTR_STATUS0__TIME_OUT | \
-			INTR_STATUS0__ERASE_FAIL | \
-			INTR_STATUS0__RST_COMP | \
-			INTR_STATUS0__ERASE_COMP)
+#define DENALI_IRQ_ALL	(INTR_STATUS__DMA_CMD_COMP | \
+			INTR_STATUS__ECC_TRANSACTION_DONE | \
+			INTR_STATUS__ECC_ERR | \
+			INTR_STATUS__PROGRAM_FAIL | \
+			INTR_STATUS__LOAD_COMP | \
+			INTR_STATUS__PROGRAM_COMP | \
+			INTR_STATUS__TIME_OUT | \
+			INTR_STATUS__ERASE_FAIL | \
+			INTR_STATUS__RST_COMP | \
+			INTR_STATUS__ERASE_COMP)
 
 /* indicates whether or not the internal value for the flash bank is
  * valid or not */
@@ -95,30 +96,6 @@
 	{ /* end: all zeroes */ }
 };
 
-
-/* these are static lookup tables that give us easy access to
- * registers in the NAND controller.
- */
-static const uint32_t intr_status_addresses[4] = {INTR_STATUS0,
-						  INTR_STATUS1,
-						  INTR_STATUS2,
-						  INTR_STATUS3};
-
-static const uint32_t device_reset_banks[4] = {DEVICE_RESET__BANK0,
-							DEVICE_RESET__BANK1,
-							DEVICE_RESET__BANK2,
-							DEVICE_RESET__BANK3};
-
-static const uint32_t operation_timeout[4] = {INTR_STATUS0__TIME_OUT,
-							INTR_STATUS1__TIME_OUT,
-							INTR_STATUS2__TIME_OUT,
-							INTR_STATUS3__TIME_OUT};
-
-static const uint32_t reset_complete[4] = {INTR_STATUS0__RST_COMP,
-							INTR_STATUS1__RST_COMP,
-							INTR_STATUS2__RST_COMP,
-							INTR_STATUS3__RST_COMP};
-
 /* forward declarations */
 static void clear_interrupts(struct denali_nand_info *denali);
 static uint32_t wait_for_irq(struct denali_nand_info *denali,
@@ -180,19 +157,17 @@
 static void reset_bank(struct denali_nand_info *denali)
 {
 	uint32_t irq_status = 0;
-	uint32_t irq_mask = reset_complete[denali->flash_bank] |
-			    operation_timeout[denali->flash_bank];
-	int bank = 0;
+	uint32_t irq_mask = INTR_STATUS__RST_COMP |
+			    INTR_STATUS__TIME_OUT;
 
 	clear_interrupts(denali);
 
-	bank = device_reset_banks[denali->flash_bank];
-	iowrite32(bank, denali->flash_reg + DEVICE_RESET);
+	iowrite32(1 << denali->flash_bank, denali->flash_reg + DEVICE_RESET);
 
 	irq_status = wait_for_irq(denali, irq_mask);
 
-	if (irq_status & operation_timeout[denali->flash_bank])
-		dev_err(&denali->dev->dev, "reset bank failed.\n");
+	if (irq_status & INTR_STATUS__TIME_OUT)
+		dev_err(denali->dev, "reset bank failed.\n");
 }
 
 /* Reset the flash controller */
@@ -200,29 +175,28 @@
 {
 	uint32_t i;
 
-	dev_dbg(&denali->dev->dev, "%s, Line %d, Function: %s\n",
+	dev_dbg(denali->dev, "%s, Line %d, Function: %s\n",
 		       __FILE__, __LINE__, __func__);
 
-	for (i = 0 ; i < LLD_MAX_FLASH_BANKS; i++)
-		iowrite32(reset_complete[i] | operation_timeout[i],
-		denali->flash_reg + intr_status_addresses[i]);
+	for (i = 0 ; i < denali->max_banks; i++)
+		iowrite32(INTR_STATUS__RST_COMP | INTR_STATUS__TIME_OUT,
+		denali->flash_reg + INTR_STATUS(i));
 
-	for (i = 0 ; i < LLD_MAX_FLASH_BANKS; i++) {
-		iowrite32(device_reset_banks[i],
-				denali->flash_reg + DEVICE_RESET);
+	for (i = 0 ; i < denali->max_banks; i++) {
+		iowrite32(1 << i, denali->flash_reg + DEVICE_RESET);
 		while (!(ioread32(denali->flash_reg +
-				intr_status_addresses[i]) &
-			(reset_complete[i] | operation_timeout[i])))
+				INTR_STATUS(i)) &
+			(INTR_STATUS__RST_COMP | INTR_STATUS__TIME_OUT)))
 			cpu_relax();
-		if (ioread32(denali->flash_reg + intr_status_addresses[i]) &
-			operation_timeout[i])
-			dev_dbg(&denali->dev->dev,
+		if (ioread32(denali->flash_reg + INTR_STATUS(i)) &
+			INTR_STATUS__TIME_OUT)
+			dev_dbg(denali->dev,
 			"NAND Reset operation timed out on bank %d\n", i);
 	}
 
-	for (i = 0; i < LLD_MAX_FLASH_BANKS; i++)
-		iowrite32(reset_complete[i] | operation_timeout[i],
-			denali->flash_reg + intr_status_addresses[i]);
+	for (i = 0; i < denali->max_banks; i++)
+		iowrite32(INTR_STATUS__RST_COMP | INTR_STATUS__TIME_OUT,
+			denali->flash_reg + INTR_STATUS(i));
 
 	return PASS;
 }
@@ -254,7 +228,7 @@
 	uint16_t acc_clks;
 	uint16_t addr_2_data, re_2_we, re_2_re, we_2_re, cs_cnt;
 
-	dev_dbg(&denali->dev->dev, "%s, Line %d, Function: %s\n",
+	dev_dbg(denali->dev, "%s, Line %d, Function: %s\n",
 		       __FILE__, __LINE__, __func__);
 
 	en_lo = CEIL_DIV(Trp[mode], CLK_X);
@@ -291,7 +265,7 @@
 		acc_clks++;
 
 	if ((data_invalid - acc_clks * CLK_X) < 2)
-		dev_warn(&denali->dev->dev, "%s, Line %d: Warning!\n",
+		dev_warn(denali->dev, "%s, Line %d: Warning!\n",
 			__FILE__, __LINE__);
 
 	addr_2_data = CEIL_DIV(Tadl[mode], CLK_X);
@@ -419,7 +393,7 @@
 #endif
 		break;
 	default:
-		dev_warn(&denali->dev->dev,
+		dev_warn(denali->dev,
 			"Spectra: Unknown Hynix NAND (Device ID: 0x%x)."
 			"Will use default parameter values instead.\n",
 			device_id);
@@ -431,17 +405,17 @@
  */
 static void find_valid_banks(struct denali_nand_info *denali)
 {
-	uint32_t id[LLD_MAX_FLASH_BANKS];
+	uint32_t id[denali->max_banks];
 	int i;
 
 	denali->total_used_banks = 1;
-	for (i = 0; i < LLD_MAX_FLASH_BANKS; i++) {
+	for (i = 0; i < denali->max_banks; i++) {
 		index_addr(denali, (uint32_t)(MODE_11 | (i << 24) | 0), 0x90);
 		index_addr(denali, (uint32_t)(MODE_11 | (i << 24) | 1), 0);
 		index_addr_read_data(denali,
 				(uint32_t)(MODE_11 | (i << 24) | 2), &id[i]);
 
-		dev_dbg(&denali->dev->dev,
+		dev_dbg(denali->dev,
 			"Return 1st ID for bank[%d]: %x\n", i, id[i]);
 
 		if (i == 0) {
@@ -461,16 +435,27 @@
 		 * Multichip support is not enabled.
 		 */
 		if (denali->total_used_banks != 1) {
-			dev_err(&denali->dev->dev,
+			dev_err(denali->dev,
 					"Sorry, Intel CE4100 only supports "
 					"a single NAND device.\n");
 			BUG();
 		}
 	}
-	dev_dbg(&denali->dev->dev,
+	dev_dbg(denali->dev,
 		"denali->total_used_banks: %d\n", denali->total_used_banks);
 }
 
+/*
+ * Use the configuration feature register to determine the maximum number of
+ * banks that the hardware supports.
+ */
+static void detect_max_banks(struct denali_nand_info *denali)
+{
+	uint32_t features = ioread32(denali->flash_reg + FEATURES);
+
+	denali->max_banks = 2 << (features & FEATURES__N_BANKS);
+}
+
 static void detect_partition_feature(struct denali_nand_info *denali)
 {
 	/* For MRST platform, denali->fwblks represent the
@@ -480,15 +465,15 @@
 	 * blocks it can't touch.
 	 * */
 	if (ioread32(denali->flash_reg + FEATURES) & FEATURES__PARTITION) {
-		if ((ioread32(denali->flash_reg + PERM_SRC_ID_1) &
-			PERM_SRC_ID_1__SRCID) == SPECTRA_PARTITION_ID) {
+		if ((ioread32(denali->flash_reg + PERM_SRC_ID(1)) &
+			PERM_SRC_ID__SRCID) == SPECTRA_PARTITION_ID) {
 			denali->fwblks =
-			    ((ioread32(denali->flash_reg + MIN_MAX_BANK_1) &
-			      MIN_MAX_BANK_1__MIN_VALUE) *
+			    ((ioread32(denali->flash_reg + MIN_MAX_BANK(1)) &
+			      MIN_MAX_BANK__MIN_VALUE) *
 			     denali->blksperchip)
 			    +
-			    (ioread32(denali->flash_reg + MIN_BLK_ADDR_1) &
-			    MIN_BLK_ADDR_1__VALUE);
+			    (ioread32(denali->flash_reg + MIN_BLK_ADDR(1)) &
+			    MIN_BLK_ADDR__VALUE);
 		} else
 			denali->fwblks = SPECTRA_START_BLOCK;
 	} else
@@ -501,7 +486,7 @@
 	uint32_t id_bytes[5], addr;
 	uint8_t i, maf_id, device_id;
 
-	dev_dbg(&denali->dev->dev,
+	dev_dbg(denali->dev,
 			"%s, Line %d, Function: %s\n",
 			__FILE__, __LINE__, __func__);
 
@@ -530,7 +515,7 @@
 		get_hynix_nand_para(denali, device_id);
 	}
 
-	dev_info(&denali->dev->dev,
+	dev_info(denali->dev,
 			"Dump timing register values:"
 			"acc_clks: %d, re_2_we: %d, re_2_re: %d\n"
 			"we_2_re: %d, addr_2_data: %d, rdwr_en_lo_cnt: %d\n"
@@ -560,7 +545,7 @@
 static void denali_set_intr_modes(struct denali_nand_info *denali,
 					uint16_t INT_ENABLE)
 {
-	dev_dbg(&denali->dev->dev, "%s, Line %d, Function: %s\n",
+	dev_dbg(denali->dev, "%s, Line %d, Function: %s\n",
 		       __FILE__, __LINE__, __func__);
 
 	if (INT_ENABLE)
@@ -580,6 +565,7 @@
 static void denali_irq_init(struct denali_nand_info *denali)
 {
 	uint32_t int_mask = 0;
+	int i;
 
 	/* Disable global interrupts */
 	denali_set_intr_modes(denali, false);
@@ -587,10 +573,8 @@
 	int_mask = DENALI_IRQ_ALL;
 
 	/* Clear all status bits */
-	iowrite32(0xFFFF, denali->flash_reg + INTR_STATUS0);
-	iowrite32(0xFFFF, denali->flash_reg + INTR_STATUS1);
-	iowrite32(0xFFFF, denali->flash_reg + INTR_STATUS2);
-	iowrite32(0xFFFF, denali->flash_reg + INTR_STATUS3);
+	for (i = 0; i < denali->max_banks; ++i)
+		iowrite32(0xFFFF, denali->flash_reg + INTR_STATUS(i));
 
 	denali_irq_enable(denali, int_mask);
 }
@@ -604,10 +588,10 @@
 static void denali_irq_enable(struct denali_nand_info *denali,
 							uint32_t int_mask)
 {
-	iowrite32(int_mask, denali->flash_reg + INTR_EN0);
-	iowrite32(int_mask, denali->flash_reg + INTR_EN1);
-	iowrite32(int_mask, denali->flash_reg + INTR_EN2);
-	iowrite32(int_mask, denali->flash_reg + INTR_EN3);
+	int i;
+
+	for (i = 0; i < denali->max_banks; ++i)
+		iowrite32(int_mask, denali->flash_reg + INTR_EN(i));
 }
 
 /* This function only returns when an interrupt that this driver cares about
@@ -624,7 +608,7 @@
 {
 	uint32_t intr_status_reg = 0;
 
-	intr_status_reg = intr_status_addresses[denali->flash_bank];
+	intr_status_reg = INTR_STATUS(denali->flash_bank);
 
 	iowrite32(irq_mask, denali->flash_reg + intr_status_reg);
 }
@@ -645,7 +629,7 @@
 {
 	uint32_t intr_status_reg = 0;
 
-	intr_status_reg = intr_status_addresses[denali->flash_bank];
+	intr_status_reg = INTR_STATUS(denali->flash_bank);
 
 	return ioread32(denali->flash_reg + intr_status_reg);
 }
@@ -754,7 +738,7 @@
 		 irq_mask = 0;
 
 	if (op == DENALI_READ)
-		irq_mask = INTR_STATUS0__LOAD_COMP;
+		irq_mask = INTR_STATUS__LOAD_COMP;
 	else if (op == DENALI_WRITE)
 		irq_mask = 0;
 	else
@@ -800,7 +784,7 @@
 			irq_status = wait_for_irq(denali, irq_mask);
 
 			if (irq_status == 0) {
-				dev_err(&denali->dev->dev,
+				dev_err(denali->dev,
 						"cmd, page, addr on timeout "
 						"(0x%x, 0x%x, 0x%x)\n",
 						cmd, denali->page, addr);
@@ -861,8 +845,8 @@
 {
 	struct denali_nand_info *denali = mtd_to_denali(mtd);
 	uint32_t irq_status = 0;
-	uint32_t irq_mask = INTR_STATUS0__PROGRAM_COMP |
-						INTR_STATUS0__PROGRAM_FAIL;
+	uint32_t irq_mask = INTR_STATUS__PROGRAM_COMP |
+						INTR_STATUS__PROGRAM_FAIL;
 	int status = 0;
 
 	denali->page = page;
@@ -875,11 +859,11 @@
 		irq_status = wait_for_irq(denali, irq_mask);
 
 		if (irq_status == 0) {
-			dev_err(&denali->dev->dev, "OOB write failed\n");
+			dev_err(denali->dev, "OOB write failed\n");
 			status = -EIO;
 		}
 	} else {
-		dev_err(&denali->dev->dev, "unable to send pipeline command\n");
+		dev_err(denali->dev, "unable to send pipeline command\n");
 		status = -EIO;
 	}
 	return status;
@@ -889,7 +873,7 @@
 static void read_oob_data(struct mtd_info *mtd, uint8_t *buf, int page)
 {
 	struct denali_nand_info *denali = mtd_to_denali(mtd);
-	uint32_t irq_mask = INTR_STATUS0__LOAD_COMP,
+	uint32_t irq_mask = INTR_STATUS__LOAD_COMP,
 			 irq_status = 0, addr = 0x0, cmd = 0x0;
 
 	denali->page = page;
@@ -904,7 +888,7 @@
 		irq_status = wait_for_irq(denali, irq_mask);
 
 		if (irq_status == 0)
-			dev_err(&denali->dev->dev, "page on OOB timeout %d\n",
+			dev_err(denali->dev, "page on OOB timeout %d\n",
 					denali->page);
 
 		/* We set the device back to MAIN_ACCESS here as I observed
@@ -944,7 +928,7 @@
 {
 	bool check_erased_page = false;
 
-	if (irq_status & INTR_STATUS0__ECC_ERR) {
+	if (irq_status & INTR_STATUS__ECC_ERR) {
 		/* read the ECC errors. we'll ignore them for now */
 		uint32_t err_address = 0, err_correction_info = 0;
 		uint32_t err_byte = 0, err_sector = 0, err_device = 0;
@@ -995,7 +979,7 @@
 		 * for a while for this interrupt
 		 * */
 		while (!(read_interrupt_status(denali) &
-				INTR_STATUS0__ECC_TRANSACTION_DONE))
+				INTR_STATUS__ECC_TRANSACTION_DONE))
 			cpu_relax();
 		clear_interrupts(denali);
 		denali_set_intr_modes(denali, true);
@@ -1045,14 +1029,13 @@
 			const uint8_t *buf, bool raw_xfer)
 {
 	struct denali_nand_info *denali = mtd_to_denali(mtd);
-	struct pci_dev *pci_dev = denali->dev;
 
 	dma_addr_t addr = denali->buf.dma_buf;
 	size_t size = denali->mtd.writesize + denali->mtd.oobsize;
 
 	uint32_t irq_status = 0;
-	uint32_t irq_mask = INTR_STATUS0__DMA_CMD_COMP |
-						INTR_STATUS0__PROGRAM_FAIL;
+	uint32_t irq_mask = INTR_STATUS__DMA_CMD_COMP |
+						INTR_STATUS__PROGRAM_FAIL;
 
 	/* if it is a raw xfer, we want to disable ecc, and send
 	 * the spare area.
@@ -1071,7 +1054,7 @@
 			mtd->oobsize);
 	}
 
-	pci_dma_sync_single_for_device(pci_dev, addr, size, PCI_DMA_TODEVICE);
+	dma_sync_single_for_device(denali->dev, addr, size, DMA_TO_DEVICE);
 
 	clear_interrupts(denali);
 	denali_enable_dma(denali, true);
@@ -1082,16 +1065,16 @@
 	irq_status = wait_for_irq(denali, irq_mask);
 
 	if (irq_status == 0) {
-		dev_err(&denali->dev->dev,
+		dev_err(denali->dev,
 				"timeout on write_page (type = %d)\n",
 				raw_xfer);
 		denali->status =
-			(irq_status & INTR_STATUS0__PROGRAM_FAIL) ?
+			(irq_status & INTR_STATUS__PROGRAM_FAIL) ?
 			NAND_STATUS_FAIL : PASS;
 	}
 
 	denali_enable_dma(denali, false);
-	pci_dma_sync_single_for_cpu(pci_dev, addr, size, PCI_DMA_TODEVICE);
+	dma_sync_single_for_cpu(denali->dev, addr, size, DMA_TO_DEVICE);
 }
 
 /* NAND core entry points */
@@ -1139,18 +1122,17 @@
 			    uint8_t *buf, int page)
 {
 	struct denali_nand_info *denali = mtd_to_denali(mtd);
-	struct pci_dev *pci_dev = denali->dev;
 
 	dma_addr_t addr = denali->buf.dma_buf;
 	size_t size = denali->mtd.writesize + denali->mtd.oobsize;
 
 	uint32_t irq_status = 0;
-	uint32_t irq_mask = INTR_STATUS0__ECC_TRANSACTION_DONE |
-			    INTR_STATUS0__ECC_ERR;
+	uint32_t irq_mask = INTR_STATUS__ECC_TRANSACTION_DONE |
+			    INTR_STATUS__ECC_ERR;
 	bool check_erased_page = false;
 
 	if (page != denali->page) {
-		dev_err(&denali->dev->dev, "IN %s: page %d is not"
+		dev_err(denali->dev, "IN %s: page %d is not"
 				" equal to denali->page %d, investigate!!",
 				__func__, page, denali->page);
 		BUG();
@@ -1159,7 +1141,7 @@
 	setup_ecc_for_xfer(denali, true, false);
 
 	denali_enable_dma(denali, true);
-	pci_dma_sync_single_for_device(pci_dev, addr, size, PCI_DMA_FROMDEVICE);
+	dma_sync_single_for_device(denali->dev, addr, size, DMA_FROM_DEVICE);
 
 	clear_interrupts(denali);
 	denali_setup_dma(denali, DENALI_READ);
@@ -1167,7 +1149,7 @@
 	/* wait for operation to complete */
 	irq_status = wait_for_irq(denali, irq_mask);
 
-	pci_dma_sync_single_for_cpu(pci_dev, addr, size, PCI_DMA_FROMDEVICE);
+	dma_sync_single_for_cpu(denali->dev, addr, size, DMA_FROM_DEVICE);
 
 	memcpy(buf, denali->buf.buf, mtd->writesize);
 
@@ -1192,16 +1174,15 @@
 				uint8_t *buf, int page)
 {
 	struct denali_nand_info *denali = mtd_to_denali(mtd);
-	struct pci_dev *pci_dev = denali->dev;
 
 	dma_addr_t addr = denali->buf.dma_buf;
 	size_t size = denali->mtd.writesize + denali->mtd.oobsize;
 
 	uint32_t irq_status = 0;
-	uint32_t irq_mask = INTR_STATUS0__DMA_CMD_COMP;
+	uint32_t irq_mask = INTR_STATUS__DMA_CMD_COMP;
 
 	if (page != denali->page) {
-		dev_err(&denali->dev->dev, "IN %s: page %d is not"
+		dev_err(denali->dev, "IN %s: page %d is not"
 				" equal to denali->page %d, investigate!!",
 				__func__, page, denali->page);
 		BUG();
@@ -1210,7 +1191,7 @@
 	setup_ecc_for_xfer(denali, false, true);
 	denali_enable_dma(denali, true);
 
-	pci_dma_sync_single_for_device(pci_dev, addr, size, PCI_DMA_FROMDEVICE);
+	dma_sync_single_for_device(denali->dev, addr, size, DMA_FROM_DEVICE);
 
 	clear_interrupts(denali);
 	denali_setup_dma(denali, DENALI_READ);
@@ -1218,7 +1199,7 @@
 	/* wait for operation to complete */
 	irq_status = wait_for_irq(denali, irq_mask);
 
-	pci_dma_sync_single_for_cpu(pci_dev, addr, size, PCI_DMA_FROMDEVICE);
+	dma_sync_single_for_cpu(denali->dev, addr, size, DMA_FROM_DEVICE);
 
 	denali_enable_dma(denali, false);
 
@@ -1271,10 +1252,10 @@
 	index_addr(denali, (uint32_t)cmd, 0x1);
 
 	/* wait for erase to complete or failure to occur */
-	irq_status = wait_for_irq(denali, INTR_STATUS0__ERASE_COMP |
-					INTR_STATUS0__ERASE_FAIL);
+	irq_status = wait_for_irq(denali, INTR_STATUS__ERASE_COMP |
+					INTR_STATUS__ERASE_FAIL);
 
-	denali->status = (irq_status & INTR_STATUS0__ERASE_FAIL) ?
+	denali->status = (irq_status & INTR_STATUS__ERASE_FAIL) ?
 						NAND_STATUS_FAIL : PASS;
 }
 
@@ -1330,7 +1311,7 @@
 				uint8_t *ecc_code)
 {
 	struct denali_nand_info *denali = mtd_to_denali(mtd);
-	dev_err(&denali->dev->dev,
+	dev_err(denali->dev,
 			"denali_ecc_calculate called unexpectedly\n");
 	BUG();
 	return -EIO;
@@ -1340,7 +1321,7 @@
 				uint8_t *read_ecc, uint8_t *calc_ecc)
 {
 	struct denali_nand_info *denali = mtd_to_denali(mtd);
-	dev_err(&denali->dev->dev,
+	dev_err(denali->dev,
 			"denali_ecc_correct called unexpectedly\n");
 	BUG();
 	return -EIO;
@@ -1349,7 +1330,7 @@
 static void denali_ecc_hwctl(struct mtd_info *mtd, int mode)
 {
 	struct denali_nand_info *denali = mtd_to_denali(mtd);
-	dev_err(&denali->dev->dev,
+	dev_err(denali->dev,
 			"denali_ecc_hwctl called unexpectedly\n");
 	BUG();
 }
@@ -1375,6 +1356,7 @@
 	/* Should set value for these registers when init */
 	iowrite32(0, denali->flash_reg + TWO_ROW_ADDR_CYCLES);
 	iowrite32(1, denali->flash_reg + ECC_ENABLE);
+	detect_max_banks(denali);
 	denali_nand_timing_set(denali);
 	denali_irq_init(denali);
 }
@@ -1484,24 +1466,22 @@
 	}
 
 	/* Is 32-bit DMA supported? */
-	ret = pci_set_dma_mask(dev, DMA_BIT_MASK(32));
-
+	ret = dma_set_mask(&dev->dev, DMA_BIT_MASK(32));
 	if (ret) {
 		printk(KERN_ERR "Spectra: no usable DMA configuration\n");
 		goto failed_enable_dev;
 	}
-	denali->buf.dma_buf =
-		pci_map_single(dev, denali->buf.buf,
-						DENALI_BUF_SIZE,
-						PCI_DMA_BIDIRECTIONAL);
+	denali->buf.dma_buf = dma_map_single(&dev->dev, denali->buf.buf,
+					     DENALI_BUF_SIZE,
+					     DMA_BIDIRECTIONAL);
 
-	if (pci_dma_mapping_error(dev, denali->buf.dma_buf)) {
+	if (dma_mapping_error(&dev->dev, denali->buf.dma_buf)) {
 		dev_err(&dev->dev, "Spectra: failed to map DMA buffer\n");
 		goto failed_enable_dev;
 	}
 
 	pci_set_master(dev);
-	denali->dev = dev;
+	denali->dev = &dev->dev;
 	denali->mtd.dev.parent = &dev->dev;
 
 	ret = pci_request_regions(dev, DENALI_NAND_NAME);
@@ -1554,7 +1534,7 @@
 	/* scan for NAND devices attached to the controller
 	 * this is the first stage in a two step process to register
 	 * with the nand subsystem */
-	if (nand_scan_ident(&denali->mtd, LLD_MAX_FLASH_BANKS, NULL)) {
+	if (nand_scan_ident(&denali->mtd, denali->max_banks, NULL)) {
 		ret = -ENXIO;
 		goto failed_req_irq;
 	}
@@ -1664,7 +1644,7 @@
 		goto failed_req_irq;
 	}
 
-	ret = add_mtd_device(&denali->mtd);
+	ret = mtd_device_register(&denali->mtd, NULL, 0);
 	if (ret) {
 		dev_err(&dev->dev, "Spectra: Failed to register MTD: %d\n",
 				ret);
@@ -1681,8 +1661,8 @@
 failed_req_regions:
 	pci_release_regions(dev);
 failed_dma_map:
-	pci_unmap_single(dev, denali->buf.dma_buf, DENALI_BUF_SIZE,
-							PCI_DMA_BIDIRECTIONAL);
+	dma_unmap_single(&dev->dev, denali->buf.dma_buf, DENALI_BUF_SIZE,
+			 DMA_BIDIRECTIONAL);
 failed_enable_dev:
 	pci_disable_device(dev);
 failed_alloc_memery:
@@ -1696,7 +1676,7 @@
 	struct denali_nand_info *denali = pci_get_drvdata(dev);
 
 	nand_release(&denali->mtd);
-	del_mtd_device(&denali->mtd);
+	mtd_device_unregister(&denali->mtd);
 
 	denali_irq_cleanup(dev->irq, denali);
 
@@ -1704,8 +1684,8 @@
 	iounmap(denali->flash_mem);
 	pci_release_regions(dev);
 	pci_disable_device(dev);
-	pci_unmap_single(dev, denali->buf.dma_buf, DENALI_BUF_SIZE,
-							PCI_DMA_BIDIRECTIONAL);
+	dma_unmap_single(&dev->dev, denali->buf.dma_buf, DENALI_BUF_SIZE,
+			 DMA_BIDIRECTIONAL);
 	pci_set_drvdata(dev, NULL);
 	kfree(denali);
 }
@@ -1721,8 +1701,7 @@
 
 static int __devinit denali_init(void)
 {
-	printk(KERN_INFO "Spectra MTD driver built on %s @ %s\n",
-			__DATE__, __TIME__);
+	printk(KERN_INFO "Spectra MTD driver\n");
 	return pci_register_driver(&denali_pci_driver);
 }
 
diff -druN linux-2.6.39-libre/drivers/mtd/nand/denali.h linux-3.0-rc7-libre/drivers/mtd/nand/denali.h
--- linux-2.6.39-libre/drivers/mtd/nand/denali.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mtd/nand/denali.h	2011-07-11 19:51:52.000000000 -0400
@@ -211,185 +211,46 @@
 #define TRANSFER_MODE				0x400
 #define     TRANSFER_MODE__VALUE			0x0003
 
-#define INTR_STATUS0				0x410
-#define     INTR_STATUS0__ECC_TRANSACTION_DONE		0x0001
-#define     INTR_STATUS0__ECC_ERR			0x0002
-#define     INTR_STATUS0__DMA_CMD_COMP			0x0004
-#define     INTR_STATUS0__TIME_OUT			0x0008
-#define     INTR_STATUS0__PROGRAM_FAIL			0x0010
-#define     INTR_STATUS0__ERASE_FAIL			0x0020
-#define     INTR_STATUS0__LOAD_COMP			0x0040
-#define     INTR_STATUS0__PROGRAM_COMP			0x0080
-#define     INTR_STATUS0__ERASE_COMP			0x0100
-#define     INTR_STATUS0__PIPE_CPYBCK_CMD_COMP		0x0200
-#define     INTR_STATUS0__LOCKED_BLK			0x0400
-#define     INTR_STATUS0__UNSUP_CMD			0x0800
-#define     INTR_STATUS0__INT_ACT			0x1000
-#define     INTR_STATUS0__RST_COMP			0x2000
-#define     INTR_STATUS0__PIPE_CMD_ERR			0x4000
-#define     INTR_STATUS0__PAGE_XFER_INC			0x8000
-
-#define INTR_EN0					0x420
-#define     INTR_EN0__ECC_TRANSACTION_DONE		0x0001
-#define     INTR_EN0__ECC_ERR				0x0002
-#define     INTR_EN0__DMA_CMD_COMP			0x0004
-#define     INTR_EN0__TIME_OUT				0x0008
-#define     INTR_EN0__PROGRAM_FAIL			0x0010
-#define     INTR_EN0__ERASE_FAIL			0x0020
-#define     INTR_EN0__LOAD_COMP				0x0040
-#define     INTR_EN0__PROGRAM_COMP			0x0080
-#define     INTR_EN0__ERASE_COMP			0x0100
-#define     INTR_EN0__PIPE_CPYBCK_CMD_COMP		0x0200
-#define     INTR_EN0__LOCKED_BLK			0x0400
-#define     INTR_EN0__UNSUP_CMD				0x0800
-#define     INTR_EN0__INT_ACT				0x1000
-#define     INTR_EN0__RST_COMP				0x2000
-#define     INTR_EN0__PIPE_CMD_ERR			0x4000
-#define     INTR_EN0__PAGE_XFER_INC			0x8000
-
-#define PAGE_CNT0				0x430
-#define     PAGE_CNT0__VALUE				0x00ff
-
-#define ERR_PAGE_ADDR0				0x440
-#define     ERR_PAGE_ADDR0__VALUE			0xffff
-
-#define ERR_BLOCK_ADDR0				0x450
-#define     ERR_BLOCK_ADDR0__VALUE			0xffff
-
-#define INTR_STATUS1				0x460
-#define     INTR_STATUS1__ECC_TRANSACTION_DONE		0x0001
-#define     INTR_STATUS1__ECC_ERR			0x0002
-#define     INTR_STATUS1__DMA_CMD_COMP			0x0004
-#define     INTR_STATUS1__TIME_OUT			0x0008
-#define     INTR_STATUS1__PROGRAM_FAIL			0x0010
-#define     INTR_STATUS1__ERASE_FAIL			0x0020
-#define     INTR_STATUS1__LOAD_COMP			0x0040
-#define     INTR_STATUS1__PROGRAM_COMP			0x0080
-#define     INTR_STATUS1__ERASE_COMP			0x0100
-#define     INTR_STATUS1__PIPE_CPYBCK_CMD_COMP		0x0200
-#define     INTR_STATUS1__LOCKED_BLK			0x0400
-#define     INTR_STATUS1__UNSUP_CMD			0x0800
-#define     INTR_STATUS1__INT_ACT			0x1000
-#define     INTR_STATUS1__RST_COMP			0x2000
-#define     INTR_STATUS1__PIPE_CMD_ERR			0x4000
-#define     INTR_STATUS1__PAGE_XFER_INC			0x8000
-
-#define INTR_EN1					0x470
-#define     INTR_EN1__ECC_TRANSACTION_DONE		0x0001
-#define     INTR_EN1__ECC_ERR				0x0002
-#define     INTR_EN1__DMA_CMD_COMP			0x0004
-#define     INTR_EN1__TIME_OUT				0x0008
-#define     INTR_EN1__PROGRAM_FAIL			0x0010
-#define     INTR_EN1__ERASE_FAIL			0x0020
-#define     INTR_EN1__LOAD_COMP				0x0040
-#define     INTR_EN1__PROGRAM_COMP			0x0080
-#define     INTR_EN1__ERASE_COMP			0x0100
-#define     INTR_EN1__PIPE_CPYBCK_CMD_COMP		0x0200
-#define     INTR_EN1__LOCKED_BLK			0x0400
-#define     INTR_EN1__UNSUP_CMD				0x0800
-#define     INTR_EN1__INT_ACT				0x1000
-#define     INTR_EN1__RST_COMP				0x2000
-#define     INTR_EN1__PIPE_CMD_ERR			0x4000
-#define     INTR_EN1__PAGE_XFER_INC			0x8000
-
-#define PAGE_CNT1				0x480
-#define     PAGE_CNT1__VALUE				0x00ff
-
-#define ERR_PAGE_ADDR1				0x490
-#define     ERR_PAGE_ADDR1__VALUE			0xffff
-
-#define ERR_BLOCK_ADDR1				0x4a0
-#define     ERR_BLOCK_ADDR1__VALUE			0xffff
-
-#define INTR_STATUS2				0x4b0
-#define     INTR_STATUS2__ECC_TRANSACTION_DONE		0x0001
-#define     INTR_STATUS2__ECC_ERR			0x0002
-#define     INTR_STATUS2__DMA_CMD_COMP			0x0004
-#define     INTR_STATUS2__TIME_OUT			0x0008
-#define     INTR_STATUS2__PROGRAM_FAIL			0x0010
-#define     INTR_STATUS2__ERASE_FAIL			0x0020
-#define     INTR_STATUS2__LOAD_COMP			0x0040
-#define     INTR_STATUS2__PROGRAM_COMP			0x0080
-#define     INTR_STATUS2__ERASE_COMP			0x0100
-#define     INTR_STATUS2__PIPE_CPYBCK_CMD_COMP		0x0200
-#define     INTR_STATUS2__LOCKED_BLK			0x0400
-#define     INTR_STATUS2__UNSUP_CMD			0x0800
-#define     INTR_STATUS2__INT_ACT			0x1000
-#define     INTR_STATUS2__RST_COMP			0x2000
-#define     INTR_STATUS2__PIPE_CMD_ERR			0x4000
-#define     INTR_STATUS2__PAGE_XFER_INC			0x8000
-
-#define INTR_EN2					0x4c0
-#define     INTR_EN2__ECC_TRANSACTION_DONE		0x0001
-#define     INTR_EN2__ECC_ERR				0x0002
-#define     INTR_EN2__DMA_CMD_COMP			0x0004
-#define     INTR_EN2__TIME_OUT				0x0008
-#define     INTR_EN2__PROGRAM_FAIL			0x0010
-#define     INTR_EN2__ERASE_FAIL			0x0020
-#define     INTR_EN2__LOAD_COMP				0x0040
-#define     INTR_EN2__PROGRAM_COMP			0x0080
-#define     INTR_EN2__ERASE_COMP			0x0100
-#define     INTR_EN2__PIPE_CPYBCK_CMD_COMP		0x0200
-#define     INTR_EN2__LOCKED_BLK			0x0400
-#define     INTR_EN2__UNSUP_CMD				0x0800
-#define     INTR_EN2__INT_ACT				0x1000
-#define     INTR_EN2__RST_COMP				0x2000
-#define     INTR_EN2__PIPE_CMD_ERR			0x4000
-#define     INTR_EN2__PAGE_XFER_INC			0x8000
-
-#define PAGE_CNT2				0x4d0
-#define     PAGE_CNT2__VALUE				0x00ff
-
-#define ERR_PAGE_ADDR2				0x4e0
-#define     ERR_PAGE_ADDR2__VALUE			0xffff
-
-#define ERR_BLOCK_ADDR2				0x4f0
-#define     ERR_BLOCK_ADDR2__VALUE			0xffff
-
-#define INTR_STATUS3				0x500
-#define     INTR_STATUS3__ECC_TRANSACTION_DONE		0x0001
-#define     INTR_STATUS3__ECC_ERR			0x0002
-#define     INTR_STATUS3__DMA_CMD_COMP			0x0004
-#define     INTR_STATUS3__TIME_OUT			0x0008
-#define     INTR_STATUS3__PROGRAM_FAIL			0x0010
-#define     INTR_STATUS3__ERASE_FAIL			0x0020
-#define     INTR_STATUS3__LOAD_COMP			0x0040
-#define     INTR_STATUS3__PROGRAM_COMP			0x0080
-#define     INTR_STATUS3__ERASE_COMP			0x0100
-#define     INTR_STATUS3__PIPE_CPYBCK_CMD_COMP		0x0200
-#define     INTR_STATUS3__LOCKED_BLK			0x0400
-#define     INTR_STATUS3__UNSUP_CMD			0x0800
-#define     INTR_STATUS3__INT_ACT			0x1000
-#define     INTR_STATUS3__RST_COMP			0x2000
-#define     INTR_STATUS3__PIPE_CMD_ERR			0x4000
-#define     INTR_STATUS3__PAGE_XFER_INC			0x8000
-
-#define INTR_EN3					0x510
-#define     INTR_EN3__ECC_TRANSACTION_DONE		0x0001
-#define     INTR_EN3__ECC_ERR				0x0002
-#define     INTR_EN3__DMA_CMD_COMP			0x0004
-#define     INTR_EN3__TIME_OUT				0x0008
-#define     INTR_EN3__PROGRAM_FAIL			0x0010
-#define     INTR_EN3__ERASE_FAIL			0x0020
-#define     INTR_EN3__LOAD_COMP				0x0040
-#define     INTR_EN3__PROGRAM_COMP			0x0080
-#define     INTR_EN3__ERASE_COMP			0x0100
-#define     INTR_EN3__PIPE_CPYBCK_CMD_COMP		0x0200
-#define     INTR_EN3__LOCKED_BLK			0x0400
-#define     INTR_EN3__UNSUP_CMD				0x0800
-#define     INTR_EN3__INT_ACT				0x1000
-#define     INTR_EN3__RST_COMP				0x2000
-#define     INTR_EN3__PIPE_CMD_ERR			0x4000
-#define     INTR_EN3__PAGE_XFER_INC			0x8000
+#define INTR_STATUS(__bank)	(0x410 + ((__bank) * 0x50))
+#define INTR_EN(__bank)		(0x420 + ((__bank) * 0x50))
 
-#define PAGE_CNT3				0x520
-#define     PAGE_CNT3__VALUE				0x00ff
+#define     INTR_STATUS__ECC_TRANSACTION_DONE		0x0001
+#define     INTR_STATUS__ECC_ERR			0x0002
+#define     INTR_STATUS__DMA_CMD_COMP			0x0004
+#define     INTR_STATUS__TIME_OUT			0x0008
+#define     INTR_STATUS__PROGRAM_FAIL			0x0010
+#define     INTR_STATUS__ERASE_FAIL			0x0020
+#define     INTR_STATUS__LOAD_COMP			0x0040
+#define     INTR_STATUS__PROGRAM_COMP			0x0080
+#define     INTR_STATUS__ERASE_COMP			0x0100
+#define     INTR_STATUS__PIPE_CPYBCK_CMD_COMP		0x0200
+#define     INTR_STATUS__LOCKED_BLK			0x0400
+#define     INTR_STATUS__UNSUP_CMD			0x0800
+#define     INTR_STATUS__INT_ACT			0x1000
+#define     INTR_STATUS__RST_COMP			0x2000
+#define     INTR_STATUS__PIPE_CMD_ERR			0x4000
+#define     INTR_STATUS__PAGE_XFER_INC			0x8000
 
-#define ERR_PAGE_ADDR3				0x530
-#define     ERR_PAGE_ADDR3__VALUE			0xffff
+#define     INTR_EN__ECC_TRANSACTION_DONE		0x0001
+#define     INTR_EN__ECC_ERR				0x0002
+#define     INTR_EN__DMA_CMD_COMP			0x0004
+#define     INTR_EN__TIME_OUT				0x0008
+#define     INTR_EN__PROGRAM_FAIL			0x0010
+#define     INTR_EN__ERASE_FAIL				0x0020
+#define     INTR_EN__LOAD_COMP				0x0040
+#define     INTR_EN__PROGRAM_COMP			0x0080
+#define     INTR_EN__ERASE_COMP				0x0100
+#define     INTR_EN__PIPE_CPYBCK_CMD_COMP		0x0200
+#define     INTR_EN__LOCKED_BLK				0x0400
+#define     INTR_EN__UNSUP_CMD				0x0800
+#define     INTR_EN__INT_ACT				0x1000
+#define     INTR_EN__RST_COMP				0x2000
+#define     INTR_EN__PIPE_CMD_ERR			0x4000
+#define     INTR_EN__PAGE_XFER_INC			0x8000
 
-#define ERR_BLOCK_ADDR3				0x540
-#define     ERR_BLOCK_ADDR3__VALUE			0xffff
+#define PAGE_CNT(__bank)	(0x430 + ((__bank) * 0x50))
+#define ERR_PAGE_ADDR(__bank)	(0x440 + ((__bank) * 0x50))
+#define ERR_BLOCK_ADDR(__bank)	(0x450 + ((__bank) * 0x50))
 
 #define DATA_INTR				0x550
 #define     DATA_INTR__WRITE_SPACE_AV			0x0001
@@ -484,141 +345,23 @@
 #define     PTN_INTR_EN__ACCESS_ERROR_BANK3		0x0010
 #define     PTN_INTR_EN__REG_ACCESS_ERROR		0x0020
 
-#define PERM_SRC_ID_0				0x830
-#define     PERM_SRC_ID_0__SRCID			0x00ff
-#define     PERM_SRC_ID_0__DIRECT_ACCESS_ACTIVE		0x0800
-#define     PERM_SRC_ID_0__WRITE_ACTIVE			0x2000
-#define     PERM_SRC_ID_0__READ_ACTIVE			0x4000
-#define     PERM_SRC_ID_0__PARTITION_VALID		0x8000
-
-#define MIN_BLK_ADDR_0				0x840
-#define     MIN_BLK_ADDR_0__VALUE			0xffff
-
-#define MAX_BLK_ADDR_0				0x850
-#define     MAX_BLK_ADDR_0__VALUE			0xffff
-
-#define MIN_MAX_BANK_0				0x860
-#define     MIN_MAX_BANK_0__MIN_VALUE			0x0003
-#define     MIN_MAX_BANK_0__MAX_VALUE			0x000c
-
-#define PERM_SRC_ID_1				0x870
-#define     PERM_SRC_ID_1__SRCID			0x00ff
-#define     PERM_SRC_ID_1__DIRECT_ACCESS_ACTIVE		0x0800
-#define     PERM_SRC_ID_1__WRITE_ACTIVE			0x2000
-#define     PERM_SRC_ID_1__READ_ACTIVE			0x4000
-#define     PERM_SRC_ID_1__PARTITION_VALID		0x8000
-
-#define MIN_BLK_ADDR_1				0x880
-#define     MIN_BLK_ADDR_1__VALUE			0xffff
-
-#define MAX_BLK_ADDR_1				0x890
-#define     MAX_BLK_ADDR_1__VALUE			0xffff
-
-#define MIN_MAX_BANK_1				0x8a0
-#define     MIN_MAX_BANK_1__MIN_VALUE			0x0003
-#define     MIN_MAX_BANK_1__MAX_VALUE			0x000c
-
-#define PERM_SRC_ID_2				0x8b0
-#define     PERM_SRC_ID_2__SRCID			0x00ff
-#define     PERM_SRC_ID_2__DIRECT_ACCESS_ACTIVE		0x0800
-#define     PERM_SRC_ID_2__WRITE_ACTIVE			0x2000
-#define     PERM_SRC_ID_2__READ_ACTIVE			0x4000
-#define     PERM_SRC_ID_2__PARTITION_VALID		0x8000
-
-#define MIN_BLK_ADDR_2				0x8c0
-#define     MIN_BLK_ADDR_2__VALUE			0xffff
-
-#define MAX_BLK_ADDR_2				0x8d0
-#define     MAX_BLK_ADDR_2__VALUE			0xffff
-
-#define MIN_MAX_BANK_2				0x8e0
-#define     MIN_MAX_BANK_2__MIN_VALUE			0x0003
-#define     MIN_MAX_BANK_2__MAX_VALUE			0x000c
-
-#define PERM_SRC_ID_3				0x8f0
-#define     PERM_SRC_ID_3__SRCID			0x00ff
-#define     PERM_SRC_ID_3__DIRECT_ACCESS_ACTIVE		0x0800
-#define     PERM_SRC_ID_3__WRITE_ACTIVE			0x2000
-#define     PERM_SRC_ID_3__READ_ACTIVE			0x4000
-#define     PERM_SRC_ID_3__PARTITION_VALID		0x8000
-
-#define MIN_BLK_ADDR_3				0x900
-#define     MIN_BLK_ADDR_3__VALUE			0xffff
-
-#define MAX_BLK_ADDR_3				0x910
-#define     MAX_BLK_ADDR_3__VALUE			0xffff
-
-#define MIN_MAX_BANK_3				0x920
-#define     MIN_MAX_BANK_3__MIN_VALUE			0x0003
-#define     MIN_MAX_BANK_3__MAX_VALUE			0x000c
-
-#define PERM_SRC_ID_4				0x930
-#define     PERM_SRC_ID_4__SRCID			0x00ff
-#define     PERM_SRC_ID_4__DIRECT_ACCESS_ACTIVE		0x0800
-#define     PERM_SRC_ID_4__WRITE_ACTIVE			0x2000
-#define     PERM_SRC_ID_4__READ_ACTIVE			0x4000
-#define     PERM_SRC_ID_4__PARTITION_VALID		0x8000
-
-#define MIN_BLK_ADDR_4				0x940
-#define     MIN_BLK_ADDR_4__VALUE			0xffff
-
-#define MAX_BLK_ADDR_4				0x950
-#define     MAX_BLK_ADDR_4__VALUE			0xffff
-
-#define MIN_MAX_BANK_4				0x960
-#define     MIN_MAX_BANK_4__MIN_VALUE			0x0003
-#define     MIN_MAX_BANK_4__MAX_VALUE			0x000c
-
-#define PERM_SRC_ID_5				0x970
-#define     PERM_SRC_ID_5__SRCID			0x00ff
-#define     PERM_SRC_ID_5__DIRECT_ACCESS_ACTIVE		0x0800
-#define     PERM_SRC_ID_5__WRITE_ACTIVE			0x2000
-#define     PERM_SRC_ID_5__READ_ACTIVE			0x4000
-#define     PERM_SRC_ID_5__PARTITION_VALID		0x8000
-
-#define MIN_BLK_ADDR_5				0x980
-#define     MIN_BLK_ADDR_5__VALUE			0xffff
-
-#define MAX_BLK_ADDR_5				0x990
-#define     MAX_BLK_ADDR_5__VALUE			0xffff
-
-#define MIN_MAX_BANK_5				0x9a0
-#define     MIN_MAX_BANK_5__MIN_VALUE			0x0003
-#define     MIN_MAX_BANK_5__MAX_VALUE			0x000c
-
-#define PERM_SRC_ID_6				0x9b0
-#define     PERM_SRC_ID_6__SRCID			0x00ff
-#define     PERM_SRC_ID_6__DIRECT_ACCESS_ACTIVE		0x0800
-#define     PERM_SRC_ID_6__WRITE_ACTIVE			0x2000
-#define     PERM_SRC_ID_6__READ_ACTIVE			0x4000
-#define     PERM_SRC_ID_6__PARTITION_VALID		0x8000
-
-#define MIN_BLK_ADDR_6				0x9c0
-#define     MIN_BLK_ADDR_6__VALUE			0xffff
-
-#define MAX_BLK_ADDR_6				0x9d0
-#define     MAX_BLK_ADDR_6__VALUE			0xffff
-
-#define MIN_MAX_BANK_6				0x9e0
-#define     MIN_MAX_BANK_6__MIN_VALUE			0x0003
-#define     MIN_MAX_BANK_6__MAX_VALUE			0x000c
+#define PERM_SRC_ID(__bank)	(0x830 + ((__bank) * 0x40))
+#define     PERM_SRC_ID__SRCID				0x00ff
+#define     PERM_SRC_ID__DIRECT_ACCESS_ACTIVE		0x0800
+#define     PERM_SRC_ID__WRITE_ACTIVE			0x2000
+#define     PERM_SRC_ID__READ_ACTIVE			0x4000
+#define     PERM_SRC_ID__PARTITION_VALID		0x8000
 
-#define PERM_SRC_ID_7				0x9f0
-#define     PERM_SRC_ID_7__SRCID			0x00ff
-#define     PERM_SRC_ID_7__DIRECT_ACCESS_ACTIVE		0x0800
-#define     PERM_SRC_ID_7__WRITE_ACTIVE			0x2000
-#define     PERM_SRC_ID_7__READ_ACTIVE			0x4000
-#define     PERM_SRC_ID_7__PARTITION_VALID		0x8000
+#define MIN_BLK_ADDR(__bank)	(0x840 + ((__bank) * 0x40))
+#define     MIN_BLK_ADDR__VALUE				0xffff
 
-#define MIN_BLK_ADDR_7				0xa00
-#define     MIN_BLK_ADDR_7__VALUE			0xffff
+#define MAX_BLK_ADDR(__bank)	(0x850 + ((__bank) * 0x40))
+#define     MAX_BLK_ADDR__VALUE				0xffff
 
-#define MAX_BLK_ADDR_7				0xa10
-#define     MAX_BLK_ADDR_7__VALUE			0xffff
+#define MIN_MAX_BANK(__bank)	(0x860 + ((__bank) * 0x40))
+#define     MIN_MAX_BANK__MIN_VALUE			0x0003
+#define     MIN_MAX_BANK__MAX_VALUE			0x000c
 
-#define MIN_MAX_BANK_7				0xa20
-#define     MIN_MAX_BANK_7__MIN_VALUE			0x0003
-#define     MIN_MAX_BANK_7__MAX_VALUE			0x000c
 
 /* ffsdefs.h */
 #define CLEAR 0                 /*use this to clear a field instead of "fail"*/
@@ -711,7 +454,6 @@
 #define READ_WRITE_ENABLE_HIGH_COUNT    22
 
 #define ECC_SECTOR_SIZE     512
-#define LLD_MAX_FLASH_BANKS     4
 
 #define DENALI_BUF_SIZE		(NAND_MAX_PAGESIZE + NAND_MAX_OOBSIZE)
 
@@ -732,7 +474,7 @@
 	int status;
 	int platform;
 	struct nand_buf buf;
-	struct pci_dev *dev;
+	struct device *dev;
 	int total_used_banks;
 	uint32_t block;  /* stored for future use */
 	uint16_t page;
@@ -751,6 +493,7 @@
 	uint32_t totalblks;
 	uint32_t blksperchip;
 	uint32_t bbtskipbytes;
+	uint32_t max_banks;
 };
 
 #endif /*_LLD_NAND_*/
diff -druN linux-2.6.39-libre/drivers/mtd/nand/diskonchip.c linux-3.0-rc7-libre/drivers/mtd/nand/diskonchip.c
--- linux-2.6.39-libre/drivers/mtd/nand/diskonchip.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mtd/nand/diskonchip.c	2011-07-11 19:51:52.000000000 -0400
@@ -1360,11 +1360,9 @@
 	   At least as nand_bbt.c is currently written. */
 	if ((ret = nand_scan_bbt(mtd, NULL)))
 		return ret;
-	add_mtd_device(mtd);
-#ifdef CONFIG_MTD_PARTITIONS
+	mtd_device_register(mtd, NULL, 0);
 	if (!no_autopart)
-		add_mtd_partitions(mtd, parts, numparts);
-#endif
+		mtd_device_register(mtd, parts, numparts);
 	return 0;
 }
 
@@ -1419,11 +1417,9 @@
 	   autopartitioning, but I want to give it more thought. */
 	if (!numparts)
 		return -EIO;
-	add_mtd_device(mtd);
-#ifdef CONFIG_MTD_PARTITIONS
+	mtd_device_register(mtd, NULL, 0);
 	if (!no_autopart)
-		add_mtd_partitions(mtd, parts, numparts);
-#endif
+		mtd_device_register(mtd, parts, numparts);
 	return 0;
 }
 
@@ -1678,9 +1674,9 @@
 		/* DBB note: i believe nand_release is necessary here, as
 		   buffers may have been allocated in nand_base.  Check with
 		   Thomas. FIX ME! */
-		/* nand_release will call del_mtd_device, but we haven't yet
-		   added it.  This is handled without incident by
-		   del_mtd_device, as far as I can tell. */
+		/* nand_release will call mtd_device_unregister, but we
+		   haven't yet added it.  This is handled without incident by
+		   mtd_device_unregister, as far as I can tell. */
 		nand_release(mtd);
 		kfree(mtd);
 		goto fail;
diff -druN linux-2.6.39-libre/drivers/mtd/nand/edb7312.c linux-3.0-rc7-libre/drivers/mtd/nand/edb7312.c
--- linux-2.6.39-libre/drivers/mtd/nand/edb7312.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mtd/nand/edb7312.c	2011-07-11 19:51:52.000000000 -0400
@@ -55,7 +55,6 @@
 static void __iomem *ep7312_pxdr = (void __iomem *)EP7312_PXDR;
 static void __iomem *ep7312_pxddr = (void __iomem *)EP7312_PXDDR;
 
-#ifdef CONFIG_MTD_PARTITIONS
 /*
  * Define static partitions for flash device
  */
@@ -67,8 +66,6 @@
 
 #define NUM_PARTITIONS 1
 
-#endif
-
 /*
  *	hardware specific access to control-lines
  *
@@ -101,9 +98,7 @@
 	return 1;
 }
 
-#ifdef CONFIG_MTD_PARTITIONS
 const char *part_probes[] = { "cmdlinepart", NULL };
-#endif
 
 /*
  * Main initialization routine
@@ -162,14 +157,12 @@
 		kfree(ep7312_mtd);
 		return -ENXIO;
 	}
-#ifdef CONFIG_MTD_PARTITIONS
 	ep7312_mtd->name = "edb7312-nand";
 	mtd_parts_nb = parse_mtd_partitions(ep7312_mtd, part_probes, &mtd_parts, 0);
 	if (mtd_parts_nb > 0)
 		part_type = "command line";
 	else
 		mtd_parts_nb = 0;
-#endif
 	if (mtd_parts_nb == 0) {
 		mtd_parts = partition_info;
 		mtd_parts_nb = NUM_PARTITIONS;
@@ -178,7 +171,7 @@
 
 	/* Register the partitions */
 	printk(KERN_NOTICE "Using %s partition definition\n", part_type);
-	add_mtd_partitions(ep7312_mtd, mtd_parts, mtd_parts_nb);
+	mtd_device_register(ep7312_mtd, mtd_parts, mtd_parts_nb);
 
 	/* Return happy */
 	return 0;
diff -druN linux-2.6.39-libre/drivers/mtd/nand/fsl_elbc_nand.c linux-3.0-rc7-libre/drivers/mtd/nand/fsl_elbc_nand.c
--- linux-2.6.39-libre/drivers/mtd/nand/fsl_elbc_nand.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mtd/nand/fsl_elbc_nand.c	2011-07-11 19:51:52.000000000 -0400
@@ -339,9 +339,9 @@
 		                    (FIR_OP_UA  << FIR_OP1_SHIFT) |
 		                    (FIR_OP_RBW << FIR_OP2_SHIFT));
 		out_be32(&lbc->fcr, NAND_CMD_READID << FCR_CMD0_SHIFT);
-		/* 5 bytes for manuf, device and exts */
-		out_be32(&lbc->fbcr, 5);
-		elbc_fcm_ctrl->read_bytes = 5;
+		/* nand_get_flash_type() reads 8 bytes of entire ID string */
+		out_be32(&lbc->fbcr, 8);
+		elbc_fcm_ctrl->read_bytes = 8;
 		elbc_fcm_ctrl->use_mdr = 1;
 		elbc_fcm_ctrl->mdr = 0;
 
@@ -841,12 +841,9 @@
 	struct fsl_elbc_mtd *priv;
 	struct resource res;
 	struct fsl_elbc_fcm_ctrl *elbc_fcm_ctrl;
-
-#ifdef CONFIG_MTD_PARTITIONS
 	static const char *part_probe_types[]
 		= { "cmdlinepart", "RedBoot", NULL };
 	struct mtd_partition *parts;
-#endif
 	int ret;
 	int bank;
 	struct device *dev;
@@ -935,26 +932,19 @@
 	if (ret)
 		goto err;
 
-#ifdef CONFIG_MTD_PARTITIONS
 	/* First look for RedBoot table or partitions on the command
 	 * line, these take precedence over device tree information */
 	ret = parse_mtd_partitions(&priv->mtd, part_probe_types, &parts, 0);
 	if (ret < 0)
 		goto err;
 
-#ifdef CONFIG_MTD_OF_PARTS
 	if (ret == 0) {
 		ret = of_mtd_parse_partitions(priv->dev, node, &parts);
 		if (ret < 0)
 			goto err;
 	}
-#endif
 
-	if (ret > 0)
-		add_mtd_partitions(&priv->mtd, parts, ret);
-	else
-#endif
-		add_mtd_device(&priv->mtd);
+	mtd_device_register(&priv->mtd, parts, ret);
 
 	printk(KERN_INFO "eLBC NAND device at 0x%llx, bank %d\n",
 	       (unsigned long long)res.start, priv->bank);
diff -druN linux-2.6.39-libre/drivers/mtd/nand/fsl_upm.c linux-3.0-rc7-libre/drivers/mtd/nand/fsl_upm.c
--- linux-2.6.39-libre/drivers/mtd/nand/fsl_upm.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mtd/nand/fsl_upm.c	2011-07-11 19:51:52.000000000 -0400
@@ -33,10 +33,7 @@
 	struct mtd_info mtd;
 	struct nand_chip chip;
 	int last_ctrl;
-#ifdef CONFIG_MTD_PARTITIONS
 	struct mtd_partition *parts;
-#endif
-
 	struct fsl_upm upm;
 	uint8_t upm_addr_offset;
 	uint8_t upm_cmd_offset;
@@ -161,9 +158,7 @@
 {
 	int ret;
 	struct device_node *flash_np;
-#ifdef CONFIG_MTD_PARTITIONS
 	static const char *part_types[] = { "cmdlinepart", NULL, };
-#endif
 
 	fun->chip.IO_ADDR_R = fun->io_base;
 	fun->chip.IO_ADDR_W = fun->io_base;
@@ -197,7 +192,6 @@
 	if (ret)
 		goto err;
 
-#ifdef CONFIG_MTD_PARTITIONS
 	ret = parse_mtd_partitions(&fun->mtd, part_types, &fun->parts, 0);
 
 #ifdef CONFIG_MTD_OF_PARTS
@@ -207,11 +201,7 @@
 			goto err;
 	}
 #endif
-	if (ret > 0)
-		ret = add_mtd_partitions(&fun->mtd, fun->parts, ret);
-	else
-#endif
-		ret = add_mtd_device(&fun->mtd);
+	ret = mtd_device_register(&fun->mtd, fun->parts, ret);
 err:
 	of_node_put(flash_np);
 	return ret;
diff -druN linux-2.6.39-libre/drivers/mtd/nand/fsmc_nand.c linux-3.0-rc7-libre/drivers/mtd/nand/fsmc_nand.c
--- linux-2.6.39-libre/drivers/mtd/nand/fsmc_nand.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mtd/nand/fsmc_nand.c	2011-07-11 19:51:52.000000000 -0400
@@ -120,8 +120,6 @@
 	}
 };
 
-
-#ifdef CONFIG_MTD_PARTITIONS
 /*
  * Default partition tables to be used if the partition information not
  * provided through platform data.
@@ -182,7 +180,6 @@
 #ifdef CONFIG_MTD_CMDLINE_PARTS
 const char *part_probes[] = { "cmdlinepart", NULL };
 #endif
-#endif
 
 /**
  * struct fsmc_nand_data - structure for FSMC NAND device state
@@ -719,7 +716,6 @@
 	 * platform data,
 	 * default partition information present in driver.
 	 */
-#ifdef CONFIG_MTD_PARTITIONS
 #ifdef CONFIG_MTD_CMDLINE_PARTS
 	/*
 	 * Check if partition info passed via command line
@@ -777,19 +773,10 @@
 	}
 #endif
 
-	if (host->partitions) {
-		ret = add_mtd_partitions(&host->mtd, host->partitions,
-				host->nr_partitions);
-		if (ret)
-			goto err_probe;
-	}
-#else
-	dev_info(&pdev->dev, "Registering %s as whole device\n", mtd->name);
-	if (!add_mtd_device(mtd)) {
-		ret = -ENXIO;
+	ret = mtd_device_register(&host->mtd, host->partitions,
+				  host->nr_partitions);
+	if (ret)
 		goto err_probe;
-	}
-#endif
 
 	platform_set_drvdata(pdev, host);
 	dev_info(&pdev->dev, "FSMC NAND driver registration successful\n");
@@ -835,11 +822,7 @@
 	platform_set_drvdata(pdev, NULL);
 
 	if (host) {
-#ifdef CONFIG_MTD_PARTITIONS
-		del_mtd_partitions(&host->mtd);
-#else
-		del_mtd_device(&host->mtd);
-#endif
+		mtd_device_unregister(&host->mtd);
 		clk_disable(host->clk);
 		clk_put(host->clk);
 
diff -druN linux-2.6.39-libre/drivers/mtd/nand/gpio.c linux-3.0-rc7-libre/drivers/mtd/nand/gpio.c
--- linux-2.6.39-libre/drivers/mtd/nand/gpio.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mtd/nand/gpio.c	2011-07-11 19:51:52.000000000 -0400
@@ -316,8 +316,8 @@
 		gpiomtd->plat.adjust_parts(&gpiomtd->plat,
 					   gpiomtd->mtd_info.size);
 
-	add_mtd_partitions(&gpiomtd->mtd_info, gpiomtd->plat.parts,
-			   gpiomtd->plat.num_parts);
+	mtd_device_register(&gpiomtd->mtd_info, gpiomtd->plat.parts,
+			    gpiomtd->plat.num_parts);
 	platform_set_drvdata(dev, gpiomtd);
 
 	return 0;
diff -druN linux-2.6.39-libre/drivers/mtd/nand/h1910.c linux-3.0-rc7-libre/drivers/mtd/nand/h1910.c
--- linux-2.6.39-libre/drivers/mtd/nand/h1910.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mtd/nand/h1910.c	2011-07-11 19:51:52.000000000 -0400
@@ -38,7 +38,6 @@
  * Module stuff
  */
 
-#ifdef CONFIG_MTD_PARTITIONS
 /*
  * Define static partitions for flash device
  */
@@ -50,8 +49,6 @@
 
 #define NUM_PARTITIONS 1
 
-#endif
-
 /*
  *	hardware specific access to control-lines
  *
@@ -154,7 +151,7 @@
 
 	/* Register the partitions */
 	printk(KERN_NOTICE "Using %s partition definition\n", part_type);
-	add_mtd_partitions(h1910_nand_mtd, mtd_parts, mtd_parts_nb);
+	mtd_device_register(h1910_nand_mtd, mtd_parts, mtd_parts_nb);
 
 	/* Return happy */
 	return 0;
diff -druN linux-2.6.39-libre/drivers/mtd/nand/jz4740_nand.c linux-3.0-rc7-libre/drivers/mtd/nand/jz4740_nand.c
--- linux-2.6.39-libre/drivers/mtd/nand/jz4740_nand.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mtd/nand/jz4740_nand.c	2011-07-11 19:51:52.000000000 -0400
@@ -299,10 +299,8 @@
 	struct nand_chip *chip;
 	struct mtd_info *mtd;
 	struct jz_nand_platform_data *pdata = pdev->dev.platform_data;
-#ifdef CONFIG_MTD_PARTITIONS
 	struct mtd_partition *partition_info;
 	int num_partitions = 0;
-#endif
 
 	nand = kzalloc(sizeof(*nand), GFP_KERNEL);
 	if (!nand) {
@@ -375,7 +373,6 @@
 		goto err_gpio_free;
 	}
 
-#ifdef CONFIG_MTD_PARTITIONS
 #ifdef CONFIG_MTD_CMDLINE_PARTS
 	num_partitions = parse_mtd_partitions(mtd, part_probes,
 						&partition_info, 0);
@@ -384,12 +381,7 @@
 		num_partitions = pdata->num_partitions;
 		partition_info = pdata->partitions;
 	}
-
-	if (num_partitions > 0)
-		ret = add_mtd_partitions(mtd, partition_info, num_partitions);
-	else
-#endif
-	ret = add_mtd_device(mtd);
+	ret = mtd_device_register(mtd, partition_info, num_partitions);
 
 	if (ret) {
 		dev_err(&pdev->dev, "Failed to add mtd device\n");
diff -druN linux-2.6.39-libre/drivers/mtd/nand/Kconfig linux-3.0-rc7-libre/drivers/mtd/nand/Kconfig
--- linux-2.6.39-libre/drivers/mtd/nand/Kconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mtd/nand/Kconfig	2011-07-11 19:51:52.000000000 -0400
@@ -92,7 +92,7 @@
 
 config MTD_NAND_H1900
 	tristate "iPAQ H1900 flash"
-	depends on ARCH_PXA && MTD_PARTITIONS
+	depends on ARCH_PXA
 	help
 	  This enables the driver for the iPAQ h1900 flash.
 
@@ -419,7 +419,6 @@
 
 config MTD_NAND_NANDSIM
 	tristate "Support for NAND Flash Simulator"
-	depends on MTD_PARTITIONS
 	help
 	  The simulator may simulate various NAND flash chips for the
 	  MTD nand layer.
@@ -513,7 +512,7 @@
 
 config MTD_NAND_NUC900
 	tristate "Support for NAND on Nuvoton NUC9xx/w90p910 evaluation boards."
-	depends on ARCH_W90X900 && MTD_PARTITIONS
+	depends on ARCH_W90X900
 	help
 	  This enables the driver for the NAND Flash on evaluation board based
 	  on w90p910 / NUC9xx.
diff -druN linux-2.6.39-libre/drivers/mtd/nand/mpc5121_nfc.c linux-3.0-rc7-libre/drivers/mtd/nand/mpc5121_nfc.c
--- linux-2.6.39-libre/drivers/mtd/nand/mpc5121_nfc.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mtd/nand/mpc5121_nfc.c	2011-07-11 19:51:52.000000000 -0400
@@ -131,9 +131,7 @@
 
 static void mpc5121_nfc_done(struct mtd_info *mtd);
 
-#ifdef CONFIG_MTD_PARTITIONS
 static const char *mpc5121_nfc_pprobes[] = { "cmdlinepart", NULL };
-#endif
 
 /* Read NFC register */
 static inline u16 nfc_read(struct mtd_info *mtd, uint reg)
@@ -658,9 +656,7 @@
 	struct mpc5121_nfc_prv *prv;
 	struct resource res;
 	struct mtd_info *mtd;
-#ifdef CONFIG_MTD_PARTITIONS
 	struct mtd_partition *parts;
-#endif
 	struct nand_chip *chip;
 	unsigned long regs_paddr, regs_size;
 	const __be32 *chips_no;
@@ -841,7 +837,6 @@
 	dev_set_drvdata(dev, mtd);
 
 	/* Register device in MTD */
-#ifdef CONFIG_MTD_PARTITIONS
 	retval = parse_mtd_partitions(mtd, mpc5121_nfc_pprobes, &parts, 0);
 #ifdef CONFIG_MTD_OF_PARTS
 	if (retval == 0)
@@ -854,12 +849,7 @@
 		goto error;
 	}
 
-	if (retval > 0)
-		retval = add_mtd_partitions(mtd, parts, retval);
-	else
-#endif
-		retval = add_mtd_device(mtd);
-
+	retval = mtd_device_register(mtd, parts, retval);
 	if (retval) {
 		dev_err(dev, "Error adding MTD device!\n");
 		devm_free_irq(dev, prv->irq, mtd);
diff -druN linux-2.6.39-libre/drivers/mtd/nand/mxc_nand.c linux-3.0-rc7-libre/drivers/mtd/nand/mxc_nand.c
--- linux-2.6.39-libre/drivers/mtd/nand/mxc_nand.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mtd/nand/mxc_nand.c	2011-07-11 19:51:52.000000000 -0400
@@ -56,8 +56,14 @@
 #define NFC_V1_V2_WRPROT		(host->regs + 0x12)
 #define NFC_V1_UNLOCKSTART_BLKADDR	(host->regs + 0x14)
 #define NFC_V1_UNLOCKEND_BLKADDR	(host->regs + 0x16)
-#define NFC_V21_UNLOCKSTART_BLKADDR	(host->regs + 0x20)
-#define NFC_V21_UNLOCKEND_BLKADDR	(host->regs + 0x22)
+#define NFC_V21_UNLOCKSTART_BLKADDR0	(host->regs + 0x20)
+#define NFC_V21_UNLOCKSTART_BLKADDR1	(host->regs + 0x24)
+#define NFC_V21_UNLOCKSTART_BLKADDR2	(host->regs + 0x28)
+#define NFC_V21_UNLOCKSTART_BLKADDR3	(host->regs + 0x2c)
+#define NFC_V21_UNLOCKEND_BLKADDR0	(host->regs + 0x22)
+#define NFC_V21_UNLOCKEND_BLKADDR1	(host->regs + 0x26)
+#define NFC_V21_UNLOCKEND_BLKADDR2	(host->regs + 0x2a)
+#define NFC_V21_UNLOCKEND_BLKADDR3	(host->regs + 0x2e)
 #define NFC_V1_V2_NF_WRPRST		(host->regs + 0x18)
 #define NFC_V1_V2_CONFIG1		(host->regs + 0x1a)
 #define NFC_V1_V2_CONFIG2		(host->regs + 0x1c)
@@ -152,6 +158,7 @@
 	int			clk_act;
 	int			irq;
 	int			eccsize;
+	int			active_cs;
 
 	struct completion	op_completion;
 
@@ -236,9 +243,7 @@
 	}
 };
 
-#ifdef CONFIG_MTD_PARTITIONS
 static const char *part_probes[] = { "RedBoot", "cmdlinepart", NULL };
-#endif
 
 static irqreturn_t mxc_nfc_irq(int irq, void *dev_id)
 {
@@ -445,7 +450,7 @@
 	for (i = 0; i < bufs; i++) {
 
 		/* NANDFC buffer 0 is used for page read/write */
-		writew(i, NFC_V1_V2_BUF_ADDR);
+		writew((host->active_cs << 4) | i, NFC_V1_V2_BUF_ADDR);
 
 		writew(ops, NFC_V1_V2_CONFIG2);
 
@@ -470,7 +475,7 @@
 	struct nand_chip *this = &host->nand;
 
 	/* NANDFC buffer 0 is used for device ID output */
-	writew(0x0, NFC_V1_V2_BUF_ADDR);
+	writew(host->active_cs << 4, NFC_V1_V2_BUF_ADDR);
 
 	writew(NFC_ID, NFC_V1_V2_CONFIG2);
 
@@ -505,7 +510,7 @@
 	uint32_t store;
 	uint16_t ret;
 
-	writew(0x0, NFC_V1_V2_BUF_ADDR);
+	writew(host->active_cs << 4, NFC_V1_V2_BUF_ADDR);
 
 	/*
 	 * The device status is stored in main_area0. To
@@ -686,24 +691,24 @@
 	struct nand_chip *nand_chip = mtd->priv;
 	struct mxc_nand_host *host = nand_chip->priv;
 
-	switch (chip) {
-	case -1:
+	if (chip == -1) {
 		/* Disable the NFC clock */
 		if (host->clk_act) {
 			clk_disable(host->clk);
 			host->clk_act = 0;
 		}
-		break;
-	case 0:
+		return;
+	}
+
+	if (!host->clk_act) {
 		/* Enable the NFC clock */
-		if (!host->clk_act) {
-			clk_enable(host->clk);
-			host->clk_act = 1;
-		}
-		break;
+		clk_enable(host->clk);
+		host->clk_act = 1;
+	}
 
-	default:
-		break;
+	if (nfc_is_v21()) {
+		host->active_cs = chip;
+		writew(host->active_cs << 4, NFC_V1_V2_BUF_ADDR);
 	}
 }
 
@@ -834,8 +839,14 @@
 
 	/* Blocks to be unlocked */
 	if (nfc_is_v21()) {
-		writew(0x0, NFC_V21_UNLOCKSTART_BLKADDR);
-		writew(0xffff, NFC_V21_UNLOCKEND_BLKADDR);
+		writew(0x0, NFC_V21_UNLOCKSTART_BLKADDR0);
+		writew(0x0, NFC_V21_UNLOCKSTART_BLKADDR1);
+		writew(0x0, NFC_V21_UNLOCKSTART_BLKADDR2);
+		writew(0x0, NFC_V21_UNLOCKSTART_BLKADDR3);
+		writew(0xffff, NFC_V21_UNLOCKEND_BLKADDR0);
+		writew(0xffff, NFC_V21_UNLOCKEND_BLKADDR1);
+		writew(0xffff, NFC_V21_UNLOCKEND_BLKADDR2);
+		writew(0xffff, NFC_V21_UNLOCKEND_BLKADDR3);
 	} else if (nfc_is_v1()) {
 		writew(0x0, NFC_V1_UNLOCKSTART_BLKADDR);
 		writew(0x4000, NFC_V1_UNLOCKEND_BLKADDR);
@@ -1200,7 +1211,7 @@
 		irq_control_v1_v2(host, 1);
 
 	/* first scan to find the device and get the page size */
-	if (nand_scan_ident(mtd, 1, NULL)) {
+	if (nand_scan_ident(mtd, nfc_is_v21() ? 4 : 1, NULL)) {
 		err = -ENXIO;
 		goto escan;
 	}
@@ -1220,18 +1231,15 @@
 	}
 
 	/* Register the partitions */
-#ifdef CONFIG_MTD_PARTITIONS
 	nr_parts =
 	    parse_mtd_partitions(mtd, part_probes, &host->parts, 0);
 	if (nr_parts > 0)
-		add_mtd_partitions(mtd, host->parts, nr_parts);
+		mtd_device_register(mtd, host->parts, nr_parts);
 	else if (pdata->parts)
-		add_mtd_partitions(mtd, pdata->parts, pdata->nr_parts);
-	else
-#endif
-	{
+		mtd_device_register(mtd, pdata->parts, pdata->nr_parts);
+	else {
 		pr_info("Registering %s as whole device\n", mtd->name);
-		add_mtd_device(mtd);
+		mtd_device_register(mtd, NULL, 0);
 	}
 
 	platform_set_drvdata(pdev, host);
diff -druN linux-2.6.39-libre/drivers/mtd/nand/nand_base.c linux-3.0-rc7-libre/drivers/mtd/nand/nand_base.c
--- linux-2.6.39-libre/drivers/mtd/nand/nand_base.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mtd/nand/nand_base.c	2011-07-11 19:51:52.000000000 -0400
@@ -47,10 +47,7 @@
 #include <linux/bitops.h>
 #include <linux/leds.h>
 #include <linux/io.h>
-
-#ifdef CONFIG_MTD_PARTITIONS
 #include <linux/mtd/partitions.h>
-#endif
 
 /* Define default oob placement schemes for large and small page devices */
 static struct nand_ecclayout nand_oob_8 = {
@@ -976,9 +973,6 @@
 	ret = __nand_unlock(mtd, ofs, len, 0);
 
 out:
-	/* de-select the NAND device */
-	chip->select_chip(mtd, -1);
-
 	nand_release_device(mtd);
 
 	return ret;
@@ -1046,9 +1040,6 @@
 	ret = __nand_unlock(mtd, ofs, len, 0x1);
 
 out:
-	/* de-select the NAND device */
-	chip->select_chip(mtd, -1);
-
 	nand_release_device(mtd);
 
 	return ret;
@@ -3112,6 +3103,8 @@
 		chip->chip_shift += 32 - 1;
 	}
 
+	chip->badblockbits = 8;
+
 	/* Set the bad block position */
 	if (mtd->writesize > 512 || (busw & NAND_BUSWIDTH_16))
 		chip->badblockpos = NAND_LARGE_BADBLOCK_POS;
@@ -3539,12 +3532,7 @@
 	if (chip->ecc.mode == NAND_ECC_SOFT_BCH)
 		nand_bch_free((struct nand_bch_control *)chip->ecc.priv);
 
-#ifdef CONFIG_MTD_PARTITIONS
-	/* Deregister partitions */
-	del_mtd_partitions(mtd);
-#endif
-	/* Deregister the device */
-	del_mtd_device(mtd);
+	mtd_device_unregister(mtd);
 
 	/* Free bad block table memory */
 	kfree(chip->bbt);
diff -druN linux-2.6.39-libre/drivers/mtd/nand/nand_bbt.c linux-3.0-rc7-libre/drivers/mtd/nand/nand_bbt.c
--- linux-2.6.39-libre/drivers/mtd/nand/nand_bbt.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mtd/nand/nand_bbt.c	2011-07-11 19:51:52.000000000 -0400
@@ -1276,20 +1276,6 @@
  * while scanning a device for factory marked good / bad blocks. */
 static uint8_t scan_ff_pattern[] = { 0xff, 0xff };
 
-static struct nand_bbt_descr smallpage_flashbased = {
-	.options = NAND_BBT_SCAN2NDPAGE,
-	.offs = NAND_SMALL_BADBLOCK_POS,
-	.len = 1,
-	.pattern = scan_ff_pattern
-};
-
-static struct nand_bbt_descr largepage_flashbased = {
-	.options = NAND_BBT_SCAN2NDPAGE,
-	.offs = NAND_LARGE_BADBLOCK_POS,
-	.len = 2,
-	.pattern = scan_ff_pattern
-};
-
 static uint8_t scan_agand_pattern[] = { 0x1C, 0x71, 0xC7, 0x1C, 0x71, 0xC7 };
 
 static struct nand_bbt_descr agand_flashbased = {
@@ -1355,10 +1341,6 @@
  * this->badblock_pattern. Thus, this->badblock_pattern should be NULL when
  * passed to this function.
  *
- * TODO: Handle other flags, replace other static structs
- *        (e.g. handle NAND_BBT_FLASH for flash-based BBT,
- *             replace smallpage_flashbased)
- *
  */
 static int nand_create_default_bbt_descr(struct nand_chip *this)
 {
@@ -1422,15 +1404,14 @@
 				this->bbt_md = &bbt_mirror_descr;
 			}
 		}
-		if (!this->badblock_pattern) {
-			this->badblock_pattern = (mtd->writesize > 512) ? &largepage_flashbased : &smallpage_flashbased;
-		}
 	} else {
 		this->bbt_td = NULL;
 		this->bbt_md = NULL;
-		if (!this->badblock_pattern)
-			nand_create_default_bbt_descr(this);
 	}
+
+	if (!this->badblock_pattern)
+		nand_create_default_bbt_descr(this);
+
 	return nand_scan_bbt(mtd, this->badblock_pattern);
 }
 
diff -druN linux-2.6.39-libre/drivers/mtd/nand/nandsim.c linux-3.0-rc7-libre/drivers/mtd/nand/nandsim.c
--- linux-2.6.39-libre/drivers/mtd/nand/nandsim.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mtd/nand/nandsim.c	2011-07-11 19:51:52.000000000 -0400
@@ -2383,7 +2383,9 @@
 		goto err_exit;
 
 	/* Register NAND partitions */
-	if ((retval = add_mtd_partitions(nsmtd, &nand->partitions[0], nand->nbparts)) != 0)
+	retval = mtd_device_register(nsmtd, &nand->partitions[0],
+				     nand->nbparts);
+	if (retval != 0)
 		goto err_exit;
 
         return 0;
diff -druN linux-2.6.39-libre/drivers/mtd/nand/ndfc.c linux-3.0-rc7-libre/drivers/mtd/nand/ndfc.c
--- linux-2.6.39-libre/drivers/mtd/nand/ndfc.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mtd/nand/ndfc.c	2011-07-11 19:51:52.000000000 -0400
@@ -33,6 +33,7 @@
 #include <linux/of_platform.h>
 #include <asm/io.h>
 
+#define NDFC_MAX_CS    4
 
 struct ndfc_controller {
 	struct platform_device *ofdev;
@@ -41,17 +42,16 @@
 	struct nand_chip chip;
 	int chip_select;
 	struct nand_hw_control ndfc_control;
-#ifdef CONFIG_MTD_PARTITIONS
 	struct mtd_partition *parts;
-#endif
 };
 
-static struct ndfc_controller ndfc_ctrl;
+static struct ndfc_controller ndfc_ctrl[NDFC_MAX_CS];
 
 static void ndfc_select_chip(struct mtd_info *mtd, int chip)
 {
 	uint32_t ccr;
-	struct ndfc_controller *ndfc = &ndfc_ctrl;
+	struct nand_chip *nchip = mtd->priv;
+	struct ndfc_controller *ndfc = nchip->priv;
 
 	ccr = in_be32(ndfc->ndfcbase + NDFC_CCR);
 	if (chip >= 0) {
@@ -64,7 +64,8 @@
 
 static void ndfc_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl)
 {
-	struct ndfc_controller *ndfc = &ndfc_ctrl;
+	struct nand_chip *chip = mtd->priv;
+	struct ndfc_controller *ndfc = chip->priv;
 
 	if (cmd == NAND_CMD_NONE)
 		return;
@@ -77,7 +78,8 @@
 
 static int ndfc_ready(struct mtd_info *mtd)
 {
-	struct ndfc_controller *ndfc = &ndfc_ctrl;
+	struct nand_chip *chip = mtd->priv;
+	struct ndfc_controller *ndfc = chip->priv;
 
 	return in_be32(ndfc->ndfcbase + NDFC_STAT) & NDFC_STAT_IS_READY;
 }
@@ -85,7 +87,8 @@
 static void ndfc_enable_hwecc(struct mtd_info *mtd, int mode)
 {
 	uint32_t ccr;
-	struct ndfc_controller *ndfc = &ndfc_ctrl;
+	struct nand_chip *chip = mtd->priv;
+	struct ndfc_controller *ndfc = chip->priv;
 
 	ccr = in_be32(ndfc->ndfcbase + NDFC_CCR);
 	ccr |= NDFC_CCR_RESET_ECC;
@@ -96,7 +99,8 @@
 static int ndfc_calculate_ecc(struct mtd_info *mtd,
 			      const u_char *dat, u_char *ecc_code)
 {
-	struct ndfc_controller *ndfc = &ndfc_ctrl;
+	struct nand_chip *chip = mtd->priv;
+	struct ndfc_controller *ndfc = chip->priv;
 	uint32_t ecc;
 	uint8_t *p = (uint8_t *)&ecc;
 
@@ -119,7 +123,8 @@
  */
 static void ndfc_read_buf(struct mtd_info *mtd, uint8_t *buf, int len)
 {
-	struct ndfc_controller *ndfc = &ndfc_ctrl;
+	struct nand_chip *chip = mtd->priv;
+	struct ndfc_controller *ndfc = chip->priv;
 	uint32_t *p = (uint32_t *) buf;
 
 	for(;len > 0; len -= 4)
@@ -128,7 +133,8 @@
 
 static void ndfc_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len)
 {
-	struct ndfc_controller *ndfc = &ndfc_ctrl;
+	struct nand_chip *chip = mtd->priv;
+	struct ndfc_controller *ndfc = chip->priv;
 	uint32_t *p = (uint32_t *) buf;
 
 	for(;len > 0; len -= 4)
@@ -137,7 +143,8 @@
 
 static int ndfc_verify_buf(struct mtd_info *mtd, const uint8_t *buf, int len)
 {
-	struct ndfc_controller *ndfc = &ndfc_ctrl;
+	struct nand_chip *chip = mtd->priv;
+	struct ndfc_controller *ndfc = chip->priv;
 	uint32_t *p = (uint32_t *) buf;
 
 	for(;len > 0; len -= 4)
@@ -152,13 +159,11 @@
 static int ndfc_chip_init(struct ndfc_controller *ndfc,
 			  struct device_node *node)
 {
-#ifdef CONFIG_MTD_PARTITIONS
 #ifdef CONFIG_MTD_CMDLINE_PARTS
 	static const char *part_types[] = { "cmdlinepart", NULL };
 #else
 	static const char *part_types[] = { NULL };
 #endif
-#endif
 	struct device_node *flash_np;
 	struct nand_chip *chip = &ndfc->chip;
 	int ret;
@@ -179,6 +184,7 @@
 	chip->ecc.mode = NAND_ECC_HW;
 	chip->ecc.size = 256;
 	chip->ecc.bytes = 3;
+	chip->priv = ndfc;
 
 	ndfc->mtd.priv = chip;
 	ndfc->mtd.owner = THIS_MODULE;
@@ -198,25 +204,18 @@
 	if (ret)
 		goto err;
 
-#ifdef CONFIG_MTD_PARTITIONS
 	ret = parse_mtd_partitions(&ndfc->mtd, part_types, &ndfc->parts, 0);
 	if (ret < 0)
 		goto err;
 
-#ifdef CONFIG_MTD_OF_PARTS
 	if (ret == 0) {
 		ret = of_mtd_parse_partitions(&ndfc->ofdev->dev, flash_np,
 					      &ndfc->parts);
 		if (ret < 0)
 			goto err;
 	}
-#endif
 
-	if (ret > 0)
-		ret = add_mtd_partitions(&ndfc->mtd, ndfc->parts, ret);
-	else
-#endif
-		ret = add_mtd_device(&ndfc->mtd);
+	ret = mtd_device_register(&ndfc->mtd, ndfc->parts, ret);
 
 err:
 	of_node_put(flash_np);
@@ -227,15 +226,10 @@
 
 static int __devinit ndfc_probe(struct platform_device *ofdev)
 {
-	struct ndfc_controller *ndfc = &ndfc_ctrl;
+	struct ndfc_controller *ndfc;
 	const __be32 *reg;
 	u32 ccr;
-	int err, len;
-
-	spin_lock_init(&ndfc->ndfc_control.lock);
-	init_waitqueue_head(&ndfc->ndfc_control.wq);
-	ndfc->ofdev = ofdev;
-	dev_set_drvdata(&ofdev->dev, ndfc);
+	int err, len, cs;
 
 	/* Read the reg property to get the chip select */
 	reg = of_get_property(ofdev->dev.of_node, "reg", &len);
@@ -243,7 +237,20 @@
 		dev_err(&ofdev->dev, "unable read reg property (%d)\n", len);
 		return -ENOENT;
 	}
-	ndfc->chip_select = be32_to_cpu(reg[0]);
+
+	cs = be32_to_cpu(reg[0]);
+	if (cs >= NDFC_MAX_CS) {
+		dev_err(&ofdev->dev, "invalid CS number (%d)\n", cs);
+		return -EINVAL;
+	}
+
+	ndfc = &ndfc_ctrl[cs];
+	ndfc->chip_select = cs;
+
+	spin_lock_init(&ndfc->ndfc_control.lock);
+	init_waitqueue_head(&ndfc->ndfc_control.wq);
+	ndfc->ofdev = ofdev;
+	dev_set_drvdata(&ofdev->dev, ndfc);
 
 	ndfc->ndfcbase = of_iomap(ofdev->dev.of_node, 0);
 	if (!ndfc->ndfcbase) {
diff -druN linux-2.6.39-libre/drivers/mtd/nand/nomadik_nand.c linux-3.0-rc7-libre/drivers/mtd/nand/nomadik_nand.c
--- linux-2.6.39-libre/drivers/mtd/nand/nomadik_nand.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mtd/nand/nomadik_nand.c	2011-07-11 19:51:52.000000000 -0400
@@ -158,12 +158,7 @@
 		goto err_unmap;
 	}
 
-#ifdef CONFIG_MTD_PARTITIONS
-	add_mtd_partitions(&host->mtd, pdata->parts, pdata->nparts);
-#else
-	pr_info("Registering %s as whole device\n", mtd->name);
-	add_mtd_device(mtd);
-#endif
+	mtd_device_register(&host->mtd, pdata->parts, pdata->nparts);
 
 	platform_set_drvdata(pdev, host);
 	return 0;
diff -druN linux-2.6.39-libre/drivers/mtd/nand/nuc900_nand.c linux-3.0-rc7-libre/drivers/mtd/nand/nuc900_nand.c
--- linux-2.6.39-libre/drivers/mtd/nand/nuc900_nand.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mtd/nand/nuc900_nand.c	2011-07-11 19:51:52.000000000 -0400
@@ -321,8 +321,8 @@
 		goto fail3;
 	}
 
-	add_mtd_partitions(&(nuc900_nand->mtd), partitions,
-						ARRAY_SIZE(partitions));
+	mtd_device_register(&(nuc900_nand->mtd), partitions,
+			    ARRAY_SIZE(partitions));
 
 	platform_set_drvdata(pdev, nuc900_nand);
 
diff -druN linux-2.6.39-libre/drivers/mtd/nand/omap2.c linux-3.0-rc7-libre/drivers/mtd/nand/omap2.c
--- linux-2.6.39-libre/drivers/mtd/nand/omap2.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mtd/nand/omap2.c	2011-07-11 19:51:52.000000000 -0400
@@ -94,9 +94,7 @@
 #define P4e_s(a)	(TF(a & NAND_Ecc_P4e)		<< 0)
 #define P4o_s(a)	(TF(a & NAND_Ecc_P4o)		<< 1)
 
-#ifdef CONFIG_MTD_PARTITIONS
 static const char *part_probes[] = { "cmdlinepart", NULL };
-#endif
 
 /* oob info generated runtime depending on ecc algorithm and layout selected */
 static struct nand_ecclayout omap_oobinfo;
@@ -263,11 +261,10 @@
 	if (ret) {
 		/* PFPW engine is busy, use cpu copy method */
 		if (info->nand.options & NAND_BUSWIDTH_16)
-			omap_read_buf16(mtd, buf, len);
+			omap_read_buf16(mtd, (u_char *)p, len);
 		else
-			omap_read_buf8(mtd, buf, len);
+			omap_read_buf8(mtd, (u_char *)p, len);
 	} else {
-		p = (u32 *) buf;
 		do {
 			r_count = gpmc_read_status(GPMC_PREFETCH_FIFO_CNT);
 			r_count = r_count >> 2;
@@ -293,7 +290,7 @@
 						struct omap_nand_info, mtd);
 	uint32_t w_count = 0;
 	int i = 0, ret = 0;
-	u16 *p;
+	u16 *p = (u16 *)buf;
 	unsigned long tim, limit;
 
 	/* take care of subpage writes */
@@ -309,11 +306,10 @@
 	if (ret) {
 		/* PFPW engine is busy, use cpu copy method */
 		if (info->nand.options & NAND_BUSWIDTH_16)
-			omap_write_buf16(mtd, buf, len);
+			omap_write_buf16(mtd, (u_char *)p, len);
 		else
-			omap_write_buf8(mtd, buf, len);
+			omap_write_buf8(mtd, (u_char *)p, len);
 	} else {
-		p = (u16 *) buf;
 		while (len) {
 			w_count = gpmc_read_status(GPMC_PREFETCH_FIFO_CNT);
 			w_count = w_count >> 1;
@@ -1073,9 +1069,9 @@
 	/* DIP switches on some boards change between 8 and 16 bit
 	 * bus widths for flash.  Try the other width if the first try fails.
 	 */
-	if (nand_scan(&info->mtd, 1)) {
+	if (nand_scan_ident(&info->mtd, 1, NULL)) {
 		info->nand.options ^= NAND_BUSWIDTH_16;
-		if (nand_scan(&info->mtd, 1)) {
+		if (nand_scan_ident(&info->mtd, 1, NULL)) {
 			err = -ENXIO;
 			goto out_release_mem_region;
 		}
@@ -1101,15 +1097,19 @@
 		info->nand.ecc.layout = &omap_oobinfo;
 	}
 
-#ifdef CONFIG_MTD_PARTITIONS
+	/* second phase scan */
+	if (nand_scan_tail(&info->mtd)) {
+		err = -ENXIO;
+		goto out_release_mem_region;
+	}
+
 	err = parse_mtd_partitions(&info->mtd, part_probes, &info->parts, 0);
 	if (err > 0)
-		add_mtd_partitions(&info->mtd, info->parts, err);
+		mtd_device_register(&info->mtd, info->parts, err);
 	else if (pdata->parts)
-		add_mtd_partitions(&info->mtd, pdata->parts, pdata->nr_parts);
+		mtd_device_register(&info->mtd, pdata->parts, pdata->nr_parts);
 	else
-#endif
-		add_mtd_device(&info->mtd);
+		mtd_device_register(&info->mtd, NULL, 0);
 
 	platform_set_drvdata(pdev, &info->mtd);
 
diff -druN linux-2.6.39-libre/drivers/mtd/nand/orion_nand.c linux-3.0-rc7-libre/drivers/mtd/nand/orion_nand.c
--- linux-2.6.39-libre/drivers/mtd/nand/orion_nand.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mtd/nand/orion_nand.c	2011-07-11 19:51:52.000000000 -0400
@@ -21,9 +21,7 @@
 #include <mach/hardware.h>
 #include <plat/orion_nand.h>
 
-#ifdef CONFIG_MTD_CMDLINE_PARTS
 static const char *part_probes[] = { "cmdlinepart", NULL };
-#endif
 
 static void orion_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl)
 {
@@ -83,10 +81,8 @@
 	struct resource *res;
 	void __iomem *io_base;
 	int ret = 0;
-#ifdef CONFIG_MTD_PARTITIONS
 	struct mtd_partition *partitions = NULL;
 	int num_part = 0;
-#endif
 
 	nc = kzalloc(sizeof(struct nand_chip) + sizeof(struct mtd_info), GFP_KERNEL);
 	if (!nc) {
@@ -136,7 +132,6 @@
 		goto no_dev;
 	}
 
-#ifdef CONFIG_MTD_PARTITIONS
 #ifdef CONFIG_MTD_CMDLINE_PARTS
 	mtd->name = "orion_nand";
 	num_part = parse_mtd_partitions(mtd, part_probes, &partitions, 0);
@@ -147,14 +142,7 @@
 		partitions = board->parts;
 	}
 
-	if (partitions && num_part > 0)
-		ret = add_mtd_partitions(mtd, partitions, num_part);
-	else
-		ret = add_mtd_device(mtd);
-#else
-	ret = add_mtd_device(mtd);
-#endif
-
+	ret = mtd_device_register(mtd, partitions, num_part);
 	if (ret) {
 		nand_release(mtd);
 		goto no_dev;
diff -druN linux-2.6.39-libre/drivers/mtd/nand/pasemi_nand.c linux-3.0-rc7-libre/drivers/mtd/nand/pasemi_nand.c
--- linux-2.6.39-libre/drivers/mtd/nand/pasemi_nand.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mtd/nand/pasemi_nand.c	2011-07-11 19:51:52.000000000 -0400
@@ -163,7 +163,7 @@
 		goto out_lpc;
 	}
 
-	if (add_mtd_device(pasemi_nand_mtd)) {
+	if (mtd_device_register(pasemi_nand_mtd, NULL, 0)) {
 		printk(KERN_ERR "pasemi_nand: Unable to register MTD device\n");
 		err = -ENODEV;
 		goto out_lpc;
diff -druN linux-2.6.39-libre/drivers/mtd/nand/plat_nand.c linux-3.0-rc7-libre/drivers/mtd/nand/plat_nand.c
--- linux-2.6.39-libre/drivers/mtd/nand/plat_nand.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mtd/nand/plat_nand.c	2011-07-11 19:51:52.000000000 -0400
@@ -21,10 +21,8 @@
 	struct nand_chip	chip;
 	struct mtd_info		mtd;
 	void __iomem		*io_base;
-#ifdef CONFIG_MTD_PARTITIONS
 	int			nr_parts;
 	struct mtd_partition	*parts;
-#endif
 };
 
 /*
@@ -101,13 +99,12 @@
 		goto out;
 	}
 
-#ifdef CONFIG_MTD_PARTITIONS
 	if (pdata->chip.part_probe_types) {
 		err = parse_mtd_partitions(&data->mtd,
 					pdata->chip.part_probe_types,
 					&data->parts, 0);
 		if (err > 0) {
-			add_mtd_partitions(&data->mtd, data->parts, err);
+			mtd_device_register(&data->mtd, data->parts, err);
 			return 0;
 		}
 	}
@@ -115,11 +112,10 @@
 		pdata->chip.set_parts(data->mtd.size, &pdata->chip);
 	if (pdata->chip.partitions) {
 		data->parts = pdata->chip.partitions;
-		err = add_mtd_partitions(&data->mtd, data->parts,
+		err = mtd_device_register(&data->mtd, data->parts,
 			pdata->chip.nr_partitions);
 	} else
-#endif
-	err = add_mtd_device(&data->mtd);
+		err = mtd_device_register(&data->mtd, NULL, 0);
 
 	if (!err)
 		return err;
@@ -149,10 +145,8 @@
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 
 	nand_release(&data->mtd);
-#ifdef CONFIG_MTD_PARTITIONS
 	if (data->parts && data->parts != pdata->chip.partitions)
 		kfree(data->parts);
-#endif
 	if (pdata->ctrl.remove)
 		pdata->ctrl.remove(pdev);
 	iounmap(data->io_base);
diff -druN linux-2.6.39-libre/drivers/mtd/nand/ppchameleonevb.c linux-3.0-rc7-libre/drivers/mtd/nand/ppchameleonevb.c
--- linux-2.6.39-libre/drivers/mtd/nand/ppchameleonevb.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mtd/nand/ppchameleonevb.c	2011-07-11 19:51:52.000000000 -0400
@@ -73,7 +73,6 @@
 __setup("ppchameleonevb_fio_pbase=", ppchameleonevb_fio_pbase);
 #endif
 
-#ifdef CONFIG_MTD_PARTITIONS
 /*
  * Define static partitions for flash devices
  */
@@ -101,7 +100,6 @@
 #define NUM_PARTITIONS 1
 
 extern int parse_cmdline_partitions(struct mtd_info *master, struct mtd_partition **pparts, const char *mtd_id);
-#endif
 
 /*
  *	hardware specific access to control-lines
@@ -189,10 +187,8 @@
 }
 #endif
 
-#ifdef CONFIG_MTD_PARTITIONS
 const char *part_probes[] = { "cmdlinepart", NULL };
 const char *part_probes_evb[] = { "cmdlinepart", NULL };
-#endif
 
 /*
  * Main initialization routine
@@ -284,14 +280,13 @@
 		this->chip_delay = NAND_SMALL_DELAY_US;
 #endif
 
-#ifdef CONFIG_MTD_PARTITIONS
 	ppchameleon_mtd->name = "ppchameleon-nand";
 	mtd_parts_nb = parse_mtd_partitions(ppchameleon_mtd, part_probes, &mtd_parts, 0);
 	if (mtd_parts_nb > 0)
 		part_type = "command line";
 	else
 		mtd_parts_nb = 0;
-#endif
+
 	if (mtd_parts_nb == 0) {
 		if (ppchameleon_mtd->size == NAND_SMALL_SIZE)
 			mtd_parts = partition_info_me;
@@ -303,7 +298,7 @@
 
 	/* Register the partitions */
 	printk(KERN_NOTICE "Using %s partition definition\n", part_type);
-	add_mtd_partitions(ppchameleon_mtd, mtd_parts, mtd_parts_nb);
+	mtd_device_register(ppchameleon_mtd, mtd_parts, mtd_parts_nb);
 
  nand_evb_init:
 	/****************************
@@ -385,14 +380,14 @@
 			iounmap(ppchameleon_fio_base);
 		return -ENXIO;
 	}
-#ifdef CONFIG_MTD_PARTITIONS
+
 	ppchameleonevb_mtd->name = NAND_EVB_MTD_NAME;
 	mtd_parts_nb = parse_mtd_partitions(ppchameleonevb_mtd, part_probes_evb, &mtd_parts, 0);
 	if (mtd_parts_nb > 0)
 		part_type = "command line";
 	else
 		mtd_parts_nb = 0;
-#endif
+
 	if (mtd_parts_nb == 0) {
 		mtd_parts = partition_info_evb;
 		mtd_parts_nb = NUM_PARTITIONS;
@@ -401,7 +396,7 @@
 
 	/* Register the partitions */
 	printk(KERN_NOTICE "Using %s partition definition\n", part_type);
-	add_mtd_partitions(ppchameleonevb_mtd, mtd_parts, mtd_parts_nb);
+	mtd_device_register(ppchameleonevb_mtd, mtd_parts, mtd_parts_nb);
 
 	/* Return happy */
 	return 0;
diff -druN linux-2.6.39-libre/drivers/mtd/nand/pxa3xx_nand.c linux-3.0-rc7-libre/drivers/mtd/nand/pxa3xx_nand.c
--- linux-2.6.39-libre/drivers/mtd/nand/pxa3xx_nand.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mtd/nand/pxa3xx_nand.c	2011-07-11 19:51:52.000000000 -0400
@@ -1119,10 +1119,7 @@
 	clk_put(info->clk);
 
 	if (mtd) {
-		del_mtd_device(mtd);
-#ifdef CONFIG_MTD_PARTITIONS
-		del_mtd_partitions(mtd);
-#endif
+		mtd_device_unregister(mtd);
 		kfree(mtd);
 	}
 	return 0;
@@ -1149,7 +1146,6 @@
 		return -ENODEV;
 	}
 
-#ifdef CONFIG_MTD_PARTITIONS
 	if (mtd_has_cmdlinepart()) {
 		const char *probes[] = { "cmdlinepart", NULL };
 		struct mtd_partition *parts;
@@ -1158,13 +1154,10 @@
 		nr_parts = parse_mtd_partitions(info->mtd, probes, &parts, 0);
 
 		if (nr_parts)
-			return add_mtd_partitions(info->mtd, parts, nr_parts);
+			return mtd_device_register(info->mtd, parts, nr_parts);
 	}
 
-	return add_mtd_partitions(info->mtd, pdata->parts, pdata->nr_parts);
-#else
-	return 0;
-#endif
+	return mtd_device_register(info->mtd, pdata->parts, pdata->nr_parts);
 }
 
 #ifdef CONFIG_PM
diff -druN linux-2.6.39-libre/drivers/mtd/nand/rtc_from4.c linux-3.0-rc7-libre/drivers/mtd/nand/rtc_from4.c
--- linux-2.6.39-libre/drivers/mtd/nand/rtc_from4.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mtd/nand/rtc_from4.c	2011-07-11 19:51:52.000000000 -0400
@@ -580,7 +580,8 @@
 #endif
 
 	/* Register the partitions */
-	ret = add_mtd_partitions(rtc_from4_mtd, partition_info, NUM_PARTITIONS);
+	ret = mtd_device_register(rtc_from4_mtd, partition_info,
+				  NUM_PARTITIONS);
 	if (ret)
 		goto err_3;
 
diff -druN linux-2.6.39-libre/drivers/mtd/nand/s3c2410.c linux-3.0-rc7-libre/drivers/mtd/nand/s3c2410.c
--- linux-2.6.39-libre/drivers/mtd/nand/s3c2410.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mtd/nand/s3c2410.c	2011-07-11 19:51:52.000000000 -0400
@@ -55,7 +55,7 @@
 #endif
 
 #ifdef CONFIG_MTD_NAND_S3C2410_CLKSTOP
-static int clock_stop = 1;
+static const int clock_stop = 1;
 #else
 static const int clock_stop = 0;
 #endif
@@ -96,6 +96,12 @@
 	TYPE_S3C2440,
 };
 
+enum s3c_nand_clk_state {
+	CLOCK_DISABLE	= 0,
+	CLOCK_ENABLE,
+	CLOCK_SUSPEND,
+};
+
 /* overview of the s3c2410 nand state */
 
 /**
@@ -111,6 +117,7 @@
  * @mtd_count: The number of MTDs created from this controller.
  * @save_sel: The contents of @sel_reg to be saved over suspend.
  * @clk_rate: The clock rate from @clk.
+ * @clk_state: The current clock state.
  * @cpu_type: The exact type of this controller.
  */
 struct s3c2410_nand_info {
@@ -129,6 +136,7 @@
 	int				mtd_count;
 	unsigned long			save_sel;
 	unsigned long			clk_rate;
+	enum s3c_nand_clk_state		clk_state;
 
 	enum s3c_cpu_type		cpu_type;
 
@@ -159,11 +167,33 @@
 	return dev->dev.platform_data;
 }
 
-static inline int allow_clk_stop(struct s3c2410_nand_info *info)
+static inline int allow_clk_suspend(struct s3c2410_nand_info *info)
 {
 	return clock_stop;
 }
 
+/**
+ * s3c2410_nand_clk_set_state - Enable, disable or suspend NAND clock.
+ * @info: The controller instance.
+ * @new_state: State to which clock should be set.
+ */
+static void s3c2410_nand_clk_set_state(struct s3c2410_nand_info *info,
+		enum s3c_nand_clk_state new_state)
+{
+	if (!allow_clk_suspend(info) && new_state == CLOCK_SUSPEND)
+		return;
+
+	if (info->clk_state == CLOCK_ENABLE) {
+		if (new_state != CLOCK_ENABLE)
+			clk_disable(info->clk);
+	} else {
+		if (new_state == CLOCK_ENABLE)
+			clk_enable(info->clk);
+	}
+
+	info->clk_state = new_state;
+}
+
 /* timing calculations */
 
 #define NS_IN_KHZ 1000000
@@ -333,8 +363,8 @@
 	nmtd = this->priv;
 	info = nmtd->info;
 
-	if (chip != -1 && allow_clk_stop(info))
-		clk_enable(info->clk);
+	if (chip != -1)
+		s3c2410_nand_clk_set_state(info, CLOCK_ENABLE);
 
 	cur = readl(info->sel_reg);
 
@@ -356,8 +386,8 @@
 
 	writel(cur, info->sel_reg);
 
-	if (chip == -1 && allow_clk_stop(info))
-		clk_disable(info->clk);
+	if (chip == -1)
+		s3c2410_nand_clk_set_state(info, CLOCK_SUSPEND);
 }
 
 /* s3c2410_nand_hwcontrol
@@ -694,8 +724,7 @@
 	/* free the common resources */
 
 	if (info->clk != NULL && !IS_ERR(info->clk)) {
-		if (!allow_clk_stop(info))
-			clk_disable(info->clk);
+		s3c2410_nand_clk_set_state(info, CLOCK_DISABLE);
 		clk_put(info->clk);
 	}
 
@@ -715,7 +744,6 @@
 	return 0;
 }
 
-#ifdef CONFIG_MTD_PARTITIONS
 const char *part_probes[] = { "cmdlinepart", NULL };
 static int s3c2410_nand_add_partition(struct s3c2410_nand_info *info,
 				      struct s3c2410_nand_mtd *mtd,
@@ -725,7 +753,7 @@
 	int nr_part = 0;
 
 	if (set == NULL)
-		return add_mtd_device(&mtd->mtd);
+		return mtd_device_register(&mtd->mtd, NULL, 0);
 
 	mtd->mtd.name = set->name;
 	nr_part = parse_mtd_partitions(&mtd->mtd, part_probes, &part_info, 0);
@@ -735,19 +763,8 @@
 		part_info = set->partitions;
 	}
 
-	if (nr_part > 0 && part_info)
-		return add_mtd_partitions(&mtd->mtd, part_info, nr_part);
-
-	return add_mtd_device(&mtd->mtd);
-}
-#else
-static int s3c2410_nand_add_partition(struct s3c2410_nand_info *info,
-				      struct s3c2410_nand_mtd *mtd,
-				      struct s3c2410_nand_set *set)
-{
-	return add_mtd_device(&mtd->mtd);
+	return mtd_device_register(&mtd->mtd, part_info, nr_part);
 }
-#endif
 
 /**
  * s3c2410_nand_init_chip - initialise a single instance of an chip
@@ -947,7 +964,7 @@
 		goto exit_error;
 	}
 
-	clk_enable(info->clk);
+	s3c2410_nand_clk_set_state(info, CLOCK_ENABLE);
 
 	/* allocate and map the resource */
 
@@ -1026,9 +1043,9 @@
 		goto exit_error;
 	}
 
-	if (allow_clk_stop(info)) {
+	if (allow_clk_suspend(info)) {
 		dev_info(&pdev->dev, "clock idle support enabled\n");
-		clk_disable(info->clk);
+		s3c2410_nand_clk_set_state(info, CLOCK_SUSPEND);
 	}
 
 	pr_debug("initialised ok\n");
@@ -1059,8 +1076,7 @@
 
 		writel(info->save_sel | info->sel_bit, info->sel_reg);
 
-		if (!allow_clk_stop(info))
-			clk_disable(info->clk);
+		s3c2410_nand_clk_set_state(info, CLOCK_DISABLE);
 	}
 
 	return 0;
@@ -1072,7 +1088,7 @@
 	unsigned long sel;
 
 	if (info) {
-		clk_enable(info->clk);
+		s3c2410_nand_clk_set_state(info, CLOCK_ENABLE);
 		s3c2410_nand_inithw(info);
 
 		/* Restore the state of the nFCE line. */
@@ -1082,8 +1098,7 @@
 		sel |= info->save_sel & info->sel_bit;
 		writel(sel, info->sel_reg);
 
-		if (allow_clk_stop(info))
-			clk_disable(info->clk);
+		s3c2410_nand_clk_set_state(info, CLOCK_SUSPEND);
 	}
 
 	return 0;
diff -druN linux-2.6.39-libre/drivers/mtd/nand/sharpsl.c linux-3.0-rc7-libre/drivers/mtd/nand/sharpsl.c
--- linux-2.6.39-libre/drivers/mtd/nand/sharpsl.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mtd/nand/sharpsl.c	2011-07-11 19:51:52.000000000 -0400
@@ -103,9 +103,7 @@
 	return readb(sharpsl->io + ECCCNTR) != 0;
 }
 
-#ifdef CONFIG_MTD_PARTITIONS
 static const char *part_probes[] = { "cmdlinepart", NULL };
-#endif
 
 /*
  * Main initialization routine
@@ -113,10 +111,8 @@
 static int __devinit sharpsl_nand_probe(struct platform_device *pdev)
 {
 	struct nand_chip *this;
-#ifdef CONFIG_MTD_PARTITIONS
 	struct mtd_partition *sharpsl_partition_info;
 	int nr_partitions;
-#endif
 	struct resource *r;
 	int err = 0;
 	struct sharpsl_nand *sharpsl;
@@ -188,18 +184,14 @@
 
 	/* Register the partitions */
 	sharpsl->mtd.name = "sharpsl-nand";
-#ifdef CONFIG_MTD_PARTITIONS
 	nr_partitions = parse_mtd_partitions(&sharpsl->mtd, part_probes, &sharpsl_partition_info, 0);
 	if (nr_partitions <= 0) {
 		nr_partitions = data->nr_partitions;
 		sharpsl_partition_info = data->partitions;
 	}
 
-	if (nr_partitions > 0)
-		err = add_mtd_partitions(&sharpsl->mtd, sharpsl_partition_info, nr_partitions);
-	else
-#endif
-	err = add_mtd_device(&sharpsl->mtd);
+	err = mtd_device_register(&sharpsl->mtd, sharpsl_partition_info,
+				  nr_partitions);
 	if (err)
 		goto err_add;
 
diff -druN linux-2.6.39-libre/drivers/mtd/nand/sh_flctl.c linux-3.0-rc7-libre/drivers/mtd/nand/sh_flctl.c
--- linux-2.6.39-libre/drivers/mtd/nand/sh_flctl.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mtd/nand/sh_flctl.c	2011-07-11 19:51:52.000000000 -0400
@@ -867,7 +867,7 @@
 	if (ret)
 		goto err;
 
-	add_mtd_partitions(flctl_mtd, pdata->parts, pdata->nr_parts);
+	mtd_device_register(flctl_mtd, pdata->parts, pdata->nr_parts);
 
 	return 0;
 
diff -druN linux-2.6.39-libre/drivers/mtd/nand/sm_common.c linux-3.0-rc7-libre/drivers/mtd/nand/sm_common.c
--- linux-2.6.39-libre/drivers/mtd/nand/sm_common.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mtd/nand/sm_common.c	2011-07-11 19:51:52.000000000 -0400
@@ -139,7 +139,7 @@
 	if (ret)
 		return ret;
 
-	return add_mtd_device(mtd);
+	return mtd_device_register(mtd, NULL, 0);
 }
 EXPORT_SYMBOL_GPL(sm_register_device);
 
diff -druN linux-2.6.39-libre/drivers/mtd/nand/socrates_nand.c linux-3.0-rc7-libre/drivers/mtd/nand/socrates_nand.c
--- linux-2.6.39-libre/drivers/mtd/nand/socrates_nand.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mtd/nand/socrates_nand.c	2011-07-11 19:51:52.000000000 -0400
@@ -155,9 +155,7 @@
 	return 1;
 }
 
-#ifdef CONFIG_MTD_PARTITIONS
 static const char *part_probes[] = { "cmdlinepart", NULL };
-#endif
 
 /*
  * Probe for the NAND device.
@@ -168,11 +166,8 @@
 	struct mtd_info *mtd;
 	struct nand_chip *nand_chip;
 	int res;
-
-#ifdef CONFIG_MTD_PARTITIONS
 	struct mtd_partition *partitions = NULL;
 	int num_partitions = 0;
-#endif
 
 	/* Allocate memory for the device structure (and zero it) */
 	host = kzalloc(sizeof(struct socrates_nand_host), GFP_KERNEL);
@@ -230,7 +225,6 @@
 		goto out;
 	}
 
-#ifdef CONFIG_MTD_PARTITIONS
 #ifdef CONFIG_MTD_CMDLINE_PARTS
 	num_partitions = parse_mtd_partitions(mtd, part_probes,
 					      &partitions, 0);
@@ -240,7 +234,6 @@
 	}
 #endif
 
-#ifdef CONFIG_MTD_OF_PARTS
 	if (num_partitions == 0) {
 		num_partitions = of_mtd_parse_partitions(&ofdev->dev,
 							 ofdev->dev.of_node,
@@ -250,19 +243,12 @@
 			goto release;
 		}
 	}
-#endif
-	if (partitions && (num_partitions > 0))
-		res = add_mtd_partitions(mtd, partitions, num_partitions);
-	else
-#endif
-		res = add_mtd_device(mtd);
 
+	res = mtd_device_register(mtd, partitions, num_partitions);
 	if (!res)
 		return res;
 
-#ifdef CONFIG_MTD_PARTITIONS
 release:
-#endif
 	nand_release(mtd);
 
 out:
diff -druN linux-2.6.39-libre/drivers/mtd/nand/spia.c linux-3.0-rc7-libre/drivers/mtd/nand/spia.c
--- linux-2.6.39-libre/drivers/mtd/nand/spia.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mtd/nand/spia.c	2011-07-11 19:51:52.000000000 -0400
@@ -149,7 +149,7 @@
 	}
 
 	/* Register the partitions */
-	add_mtd_partitions(spia_mtd, partition_info, NUM_PARTITIONS);
+	mtd_device_register(spia_mtd, partition_info, NUM_PARTITIONS);
 
 	/* Return happy */
 	return 0;
diff -druN linux-2.6.39-libre/drivers/mtd/nand/tmio_nand.c linux-3.0-rc7-libre/drivers/mtd/nand/tmio_nand.c
--- linux-2.6.39-libre/drivers/mtd/nand/tmio_nand.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mtd/nand/tmio_nand.c	2011-07-11 19:51:52.000000000 -0400
@@ -372,7 +372,7 @@
 
 static int tmio_probe(struct platform_device *dev)
 {
-	struct tmio_nand_data *data = mfd_get_data(dev);
+	struct tmio_nand_data *data = dev->dev.platform_data;
 	struct resource *fcr = platform_get_resource(dev,
 			IORESOURCE_MEM, 0);
 	struct resource *ccr = platform_get_resource(dev,
@@ -381,10 +381,8 @@
 	struct tmio_nand *tmio;
 	struct mtd_info *mtd;
 	struct nand_chip *nand_chip;
-#ifdef CONFIG_MTD_PARTITIONS
 	struct mtd_partition *parts;
 	int nbparts = 0;
-#endif
 	int retval;
 
 	if (data == NULL)
@@ -463,7 +461,6 @@
 		goto err_scan;
 	}
 	/* Register the partitions */
-#ifdef CONFIG_MTD_PARTITIONS
 #ifdef CONFIG_MTD_CMDLINE_PARTS
 	nbparts = parse_mtd_partitions(mtd, part_probes, &parts, 0);
 #endif
@@ -472,12 +469,7 @@
 		nbparts = data->num_partitions;
 	}
 
-	if (nbparts)
-		retval = add_mtd_partitions(mtd, parts, nbparts);
-	else
-#endif
-	retval = add_mtd_device(mtd);
-
+	retval = mtd_device_register(mtd, parts, nbparts);
 	if (!retval)
 		return retval;
 
diff -druN linux-2.6.39-libre/drivers/mtd/nand/txx9ndfmc.c linux-3.0-rc7-libre/drivers/mtd/nand/txx9ndfmc.c
--- linux-2.6.39-libre/drivers/mtd/nand/txx9ndfmc.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mtd/nand/txx9ndfmc.c	2011-07-11 19:51:52.000000000 -0400
@@ -74,9 +74,7 @@
 	unsigned char hold;	/* in gbusclock */
 	unsigned char spw;	/* in gbusclock */
 	struct nand_hw_control hw_control;
-#ifdef CONFIG_MTD_PARTITIONS
 	struct mtd_partition *parts[MAX_TXX9NDFMC_DEV];
-#endif
 };
 
 static struct platform_device *mtd_to_platdev(struct mtd_info *mtd)
@@ -289,9 +287,7 @@
 static int __init txx9ndfmc_probe(struct platform_device *dev)
 {
 	struct txx9ndfmc_platform_data *plat = dev->dev.platform_data;
-#ifdef CONFIG_MTD_PARTITIONS
 	static const char *probes[] = { "cmdlinepart", NULL };
-#endif
 	int hold, spw;
 	int i;
 	struct txx9ndfmc_drvdata *drvdata;
@@ -337,9 +333,7 @@
 		struct txx9ndfmc_priv *txx9_priv;
 		struct nand_chip *chip;
 		struct mtd_info *mtd;
-#ifdef CONFIG_MTD_PARTITIONS
 		int nr_parts;
-#endif
 
 		if (!(plat->ch_mask & (1 << i)))
 			continue;
@@ -399,13 +393,9 @@
 		}
 		mtd->name = txx9_priv->mtdname;
 
-#ifdef CONFIG_MTD_PARTITIONS
 		nr_parts = parse_mtd_partitions(mtd, probes,
 						&drvdata->parts[i], 0);
-		if (nr_parts > 0)
-			add_mtd_partitions(mtd, drvdata->parts[i], nr_parts);
-#endif
-		add_mtd_device(mtd);
+		mtd_device_register(mtd, drvdata->parts[i], nr_parts);
 		drvdata->mtds[i] = mtd;
 	}
 
@@ -431,9 +421,7 @@
 		txx9_priv = chip->priv;
 
 		nand_release(mtd);
-#ifdef CONFIG_MTD_PARTITIONS
 		kfree(drvdata->parts[i]);
-#endif
 		kfree(txx9_priv->mtdname);
 		kfree(txx9_priv);
 	}
diff -druN linux-2.6.39-libre/drivers/mtd/onenand/generic.c linux-3.0-rc7-libre/drivers/mtd/onenand/generic.c
--- linux-2.6.39-libre/drivers/mtd/onenand/generic.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mtd/onenand/generic.c	2011-07-11 19:51:52.000000000 -0400
@@ -30,9 +30,7 @@
  */
 #define DRIVER_NAME	"onenand-flash"
 
-#ifdef CONFIG_MTD_PARTITIONS
 static const char *part_probes[] = { "cmdlinepart", NULL,  };
-#endif
 
 struct onenand_info {
 	struct mtd_info		mtd;
@@ -75,15 +73,13 @@
 		goto out_iounmap;
 	}
 
-#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);
+		mtd_device_register(&info->mtd, info->parts, err);
 	else if (err <= 0 && pdata && pdata->parts)
-		add_mtd_partitions(&info->mtd, pdata->parts, pdata->nr_parts);
+		mtd_device_register(&info->mtd, pdata->parts, pdata->nr_parts);
 	else
-#endif
-		err = add_mtd_device(&info->mtd);
+		err = mtd_device_register(&info->mtd, NULL, 0);
 
 	platform_set_drvdata(pdev, info);
 
@@ -108,11 +104,7 @@
 	platform_set_drvdata(pdev, NULL);
 
 	if (info) {
-		if (info->parts)
-			del_mtd_partitions(&info->mtd);
-		else
-			del_mtd_device(&info->mtd);
-
+		mtd_device_unregister(&info->mtd);
 		onenand_release(&info->mtd);
 		release_mem_region(res->start, size);
 		iounmap(info->onenand.base);
diff -druN linux-2.6.39-libre/drivers/mtd/onenand/Kconfig linux-3.0-rc7-libre/drivers/mtd/onenand/Kconfig
--- linux-2.6.39-libre/drivers/mtd/onenand/Kconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mtd/onenand/Kconfig	2011-07-11 19:51:52.000000000 -0400
@@ -1,7 +1,6 @@
 menuconfig MTD_ONENAND
 	tristate "OneNAND Device Support"
 	depends on MTD
-	select MTD_PARTITIONS
 	help
 	  This enables support for accessing all type of OneNAND flash
 	  devices. For further information see
diff -druN linux-2.6.39-libre/drivers/mtd/onenand/omap2.c linux-3.0-rc7-libre/drivers/mtd/onenand/omap2.c
--- linux-2.6.39-libre/drivers/mtd/onenand/omap2.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mtd/onenand/omap2.c	2011-07-11 19:51:52.000000000 -0400
@@ -67,9 +67,7 @@
 	struct regulator *regulator;
 };
 
-#ifdef CONFIG_MTD_PARTITIONS
 static const char *part_probes[] = { "cmdlinepart", NULL,  };
-#endif
 
 static void omap2_onenand_dma_cb(int lch, u16 ch_status, void *data)
 {
@@ -755,15 +753,13 @@
 	if ((r = onenand_scan(&c->mtd, 1)) < 0)
 		goto err_release_regulator;
 
-#ifdef CONFIG_MTD_PARTITIONS
 	r = parse_mtd_partitions(&c->mtd, part_probes, &c->parts, 0);
 	if (r > 0)
-		r = add_mtd_partitions(&c->mtd, c->parts, r);
+		r = mtd_device_register(&c->mtd, c->parts, r);
 	else if (pdata->parts != NULL)
-		r = add_mtd_partitions(&c->mtd, pdata->parts, pdata->nr_parts);
+		r = mtd_device_register(&c->mtd, pdata->parts, pdata->nr_parts);
 	else
-#endif
-		r = add_mtd_device(&c->mtd);
+		r = mtd_device_register(&c->mtd, NULL, 0);
 	if (r)
 		goto err_release_onenand;
 
diff -druN linux-2.6.39-libre/drivers/mtd/onenand/onenand_base.c linux-3.0-rc7-libre/drivers/mtd/onenand/onenand_base.c
--- linux-2.6.39-libre/drivers/mtd/onenand/onenand_base.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mtd/onenand/onenand_base.c	2011-07-11 19:51:52.000000000 -0400
@@ -65,11 +65,11 @@
 			"	   : 2 -> 1st Block lock"
 			"	   : 3 -> BOTH OTP Block and 1st Block lock");
 
-/**
- *  onenand_oob_128 - oob info for Flex-Onenand with 4KB page
- *  For now, we expose only 64 out of 80 ecc bytes
+/*
+ * flexonenand_oob_128 - oob info for Flex-Onenand with 4KB page
+ * For now, we expose only 64 out of 80 ecc bytes
  */
-static struct nand_ecclayout onenand_oob_128 = {
+static struct nand_ecclayout flexonenand_oob_128 = {
 	.eccbytes	= 64,
 	.eccpos		= {
 		6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
@@ -86,6 +86,35 @@
 	}
 };
 
+/*
+ * onenand_oob_128 - oob info for OneNAND with 4KB page
+ *
+ * Based on specification:
+ * 4Gb M-die OneNAND Flash (KFM4G16Q4M, KFN8G16Q4M). Rev. 1.3, Apr. 2010
+ *
+ * For eccpos we expose only 64 bytes out of 72 (see struct nand_ecclayout)
+ *
+ * oobfree uses the spare area fields marked as
+ * "Managed by internal ECC logic for Logical Sector Number area"
+ */
+static struct nand_ecclayout onenand_oob_128 = {
+	.eccbytes	= 64,
+	.eccpos		= {
+		7, 8, 9, 10, 11, 12, 13, 14, 15,
+		23, 24, 25, 26, 27, 28, 29, 30, 31,
+		39, 40, 41, 42, 43, 44, 45, 46, 47,
+		55, 56, 57, 58, 59, 60, 61, 62, 63,
+		71, 72, 73, 74, 75, 76, 77, 78, 79,
+		87, 88, 89, 90, 91, 92, 93, 94, 95,
+		103, 104, 105, 106, 107, 108, 109, 110, 111,
+		119
+	},
+	.oobfree	= {
+		{2, 3}, {18, 3}, {34, 3}, {50, 3},
+		{66, 3}, {82, 3}, {98, 3}, {114, 3}
+	}
+};
+
 /**
  * onenand_oob_64 - oob info for large (2KB) page
  */
@@ -2424,7 +2453,7 @@
 		len -= block_size;
 		addr += block_size;
 
-		if (addr == region_end) {
+		if (region && addr == region_end) {
 			if (!len)
 				break;
 			region++;
@@ -4018,8 +4047,13 @@
 	 */
 	switch (mtd->oobsize) {
 	case 128:
-		this->ecclayout = &onenand_oob_128;
-		mtd->subpage_sft = 0;
+		if (FLEXONENAND(this)) {
+			this->ecclayout = &flexonenand_oob_128;
+			mtd->subpage_sft = 0;
+		} else {
+			this->ecclayout = &onenand_oob_128;
+			mtd->subpage_sft = 2;
+		}
 		break;
 	case 64:
 		this->ecclayout = &onenand_oob_64;
@@ -4108,12 +4142,8 @@
 {
 	struct onenand_chip *this = mtd->priv;
 
-#ifdef CONFIG_MTD_PARTITIONS
 	/* Deregister partitions */
-	del_mtd_partitions (mtd);
-#endif
-	/* Deregister the device */
-	del_mtd_device (mtd);
+	mtd_device_unregister(mtd);
 
 	/* Free bad block table memory, if allocated */
 	if (this->bbm) {
diff -druN linux-2.6.39-libre/drivers/mtd/onenand/onenand_sim.c linux-3.0-rc7-libre/drivers/mtd/onenand/onenand_sim.c
--- linux-2.6.39-libre/drivers/mtd/onenand/onenand_sim.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mtd/onenand/onenand_sim.c	2011-07-11 19:51:52.000000000 -0400
@@ -539,7 +539,8 @@
 		return -ENXIO;
 	}
 
-	add_mtd_partitions(&info->mtd, info->parts, ARRAY_SIZE(os_partitions));
+	mtd_device_register(&info->mtd, info->parts,
+			    ARRAY_SIZE(os_partitions));
 
 	return 0;
 }
diff -druN linux-2.6.39-libre/drivers/mtd/onenand/samsung.c linux-3.0-rc7-libre/drivers/mtd/onenand/samsung.c
--- linux-2.6.39-libre/drivers/mtd/onenand/samsung.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mtd/onenand/samsung.c	2011-07-11 19:51:52.000000000 -0400
@@ -147,9 +147,7 @@
 	struct resource *dma_res;
 	unsigned long	phys_base;
 	struct completion	complete;
-#ifdef CONFIG_MTD_PARTITIONS
 	struct mtd_partition *parts;
-#endif
 };
 
 #define CMD_MAP_00(dev, addr)		(dev->cmd_map(MAP_00, ((addr) << 1)))
@@ -159,9 +157,7 @@
 
 static struct s3c_onenand *onenand;
 
-#ifdef CONFIG_MTD_PARTITIONS
 static const char *part_probes[] = { "cmdlinepart", NULL, };
-#endif
 
 static inline int s3c_read_reg(int offset)
 {
@@ -1021,15 +1017,13 @@
 	if (s3c_read_reg(MEM_CFG_OFFSET) & ONENAND_SYS_CFG1_SYNC_READ)
 		dev_info(&onenand->pdev->dev, "OneNAND Sync. Burst Read enabled\n");
 
-#ifdef CONFIG_MTD_PARTITIONS
 	err = parse_mtd_partitions(mtd, part_probes, &onenand->parts, 0);
 	if (err > 0)
-		add_mtd_partitions(mtd, onenand->parts, err);
+		mtd_device_register(mtd, onenand->parts, err);
 	else if (err <= 0 && pdata && pdata->parts)
-		add_mtd_partitions(mtd, pdata->parts, pdata->nr_parts);
+		mtd_device_register(mtd, pdata->parts, pdata->nr_parts);
 	else
-#endif
-		err = add_mtd_device(mtd);
+		err = mtd_device_register(mtd, NULL, 0);
 
 	platform_set_drvdata(pdev, mtd);
 
diff -druN linux-2.6.39-libre/drivers/mtd/ubi/cdev.c linux-3.0-rc7-libre/drivers/mtd/ubi/cdev.c
--- linux-2.6.39-libre/drivers/mtd/ubi/cdev.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mtd/ubi/cdev.c	2011-07-11 19:51:52.000000000 -0400
@@ -115,7 +115,7 @@
 		mode = UBI_READONLY;
 
 	dbg_gen("open device %d, volume %d, mode %d",
-	        ubi_num, vol_id, mode);
+		ubi_num, vol_id, mode);
 
 	desc = ubi_open_volume(ubi_num, vol_id, mode);
 	if (IS_ERR(desc))
@@ -158,7 +158,7 @@
 	loff_t new_offset;
 
 	if (vol->updating) {
-		 /* Update is in progress, seeking is prohibited */
+		/* Update is in progress, seeking is prohibited */
 		dbg_err("updating");
 		return -EBUSY;
 	}
@@ -561,18 +561,18 @@
 	}
 
 	/* Set volume property command */
-	case UBI_IOCSETPROP:
+	case UBI_IOCSETVOLPROP:
 	{
-		struct ubi_set_prop_req req;
+		struct ubi_set_vol_prop_req req;
 
 		err = copy_from_user(&req, argp,
-				sizeof(struct ubi_set_prop_req));
+				     sizeof(struct ubi_set_vol_prop_req));
 		if (err) {
 			err = -EFAULT;
 			break;
 		}
 		switch (req.property) {
-		case UBI_PROP_DIRECT_WRITE:
+		case UBI_VOL_PROP_DIRECT_WRITE:
 			mutex_lock(&ubi->device_mutex);
 			desc->vol->direct_writes = !!req.value;
 			mutex_unlock(&ubi->device_mutex);
@@ -1100,5 +1100,5 @@
 	.owner          = THIS_MODULE,
 	.unlocked_ioctl = ctrl_cdev_ioctl,
 	.compat_ioctl   = ctrl_cdev_compat_ioctl,
-	.llseek		= noop_llseek,
+	.llseek		= no_llseek,
 };
diff -druN linux-2.6.39-libre/drivers/mtd/ubi/debug.c linux-3.0-rc7-libre/drivers/mtd/ubi/debug.c
--- linux-2.6.39-libre/drivers/mtd/ubi/debug.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mtd/ubi/debug.c	2011-07-11 19:51:52.000000000 -0400
@@ -30,15 +30,12 @@
 #include <linux/module.h>
 #include <linux/moduleparam.h>
 
-unsigned int ubi_msg_flags;
 unsigned int ubi_chk_flags;
 unsigned int ubi_tst_flags;
 
-module_param_named(debug_msgs, ubi_msg_flags, uint, S_IRUGO | S_IWUSR);
 module_param_named(debug_chks, ubi_chk_flags, uint, S_IRUGO | S_IWUSR);
 module_param_named(debug_tsts, ubi_chk_flags, uint, S_IRUGO | S_IWUSR);
 
-MODULE_PARM_DESC(debug_msgs, "Debug message type flags");
 MODULE_PARM_DESC(debug_chks, "Debug check flags");
 MODULE_PARM_DESC(debug_tsts, "Debug special test flags");
 
@@ -75,15 +72,15 @@
 {
 	printk(KERN_DEBUG "Volume identifier header dump:\n");
 	printk(KERN_DEBUG "\tmagic     %08x\n", be32_to_cpu(vid_hdr->magic));
-	printk(KERN_DEBUG "\tversion   %d\n",   (int)vid_hdr->version);
-	printk(KERN_DEBUG "\tvol_type  %d\n",   (int)vid_hdr->vol_type);
-	printk(KERN_DEBUG "\tcopy_flag %d\n",   (int)vid_hdr->copy_flag);
-	printk(KERN_DEBUG "\tcompat    %d\n",   (int)vid_hdr->compat);
-	printk(KERN_DEBUG "\tvol_id    %d\n",   be32_to_cpu(vid_hdr->vol_id));
-	printk(KERN_DEBUG "\tlnum      %d\n",   be32_to_cpu(vid_hdr->lnum));
-	printk(KERN_DEBUG "\tdata_size %d\n",   be32_to_cpu(vid_hdr->data_size));
-	printk(KERN_DEBUG "\tused_ebs  %d\n",   be32_to_cpu(vid_hdr->used_ebs));
-	printk(KERN_DEBUG "\tdata_pad  %d\n",   be32_to_cpu(vid_hdr->data_pad));
+	printk(KERN_DEBUG "\tversion   %d\n",  (int)vid_hdr->version);
+	printk(KERN_DEBUG "\tvol_type  %d\n",  (int)vid_hdr->vol_type);
+	printk(KERN_DEBUG "\tcopy_flag %d\n",  (int)vid_hdr->copy_flag);
+	printk(KERN_DEBUG "\tcompat    %d\n",  (int)vid_hdr->compat);
+	printk(KERN_DEBUG "\tvol_id    %d\n",  be32_to_cpu(vid_hdr->vol_id));
+	printk(KERN_DEBUG "\tlnum      %d\n",  be32_to_cpu(vid_hdr->lnum));
+	printk(KERN_DEBUG "\tdata_size %d\n",  be32_to_cpu(vid_hdr->data_size));
+	printk(KERN_DEBUG "\tused_ebs  %d\n",  be32_to_cpu(vid_hdr->used_ebs));
+	printk(KERN_DEBUG "\tdata_pad  %d\n",  be32_to_cpu(vid_hdr->data_pad));
 	printk(KERN_DEBUG "\tsqnum     %llu\n",
 		(unsigned long long)be64_to_cpu(vid_hdr->sqnum));
 	printk(KERN_DEBUG "\thdr_crc   %08x\n", be32_to_cpu(vid_hdr->hdr_crc));
diff -druN linux-2.6.39-libre/drivers/mtd/ubi/debug.h linux-3.0-rc7-libre/drivers/mtd/ubi/debug.h
--- linux-2.6.39-libre/drivers/mtd/ubi/debug.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mtd/ubi/debug.h	2011-07-11 19:51:52.000000000 -0400
@@ -21,11 +21,17 @@
 #ifndef __UBI_DEBUG_H__
 #define __UBI_DEBUG_H__
 
+struct ubi_ec_hdr;
+struct ubi_vid_hdr;
+struct ubi_volume;
+struct ubi_vtbl_record;
+struct ubi_scan_volume;
+struct ubi_scan_leb;
+struct ubi_mkvol_req;
+
 #ifdef CONFIG_MTD_UBI_DEBUG
 #include <linux/random.h>
 
-#define dbg_err(fmt, ...) ubi_err(fmt, ##__VA_ARGS__)
-
 #define ubi_assert(expr)  do {                                               \
 	if (unlikely(!(expr))) {                                             \
 		printk(KERN_CRIT "UBI assert failed in %s at %u (pid %d)\n", \
@@ -34,24 +40,28 @@
 	}                                                                    \
 } while (0)
 
-#define dbg_msg(fmt, ...)                                    \
-	printk(KERN_DEBUG "UBI DBG (pid %d): %s: " fmt "\n", \
-	       current->pid, __func__, ##__VA_ARGS__)
-
-#define dbg_do_msg(typ, fmt, ...) do {                       \
-	if (ubi_msg_flags & typ)                             \
-		dbg_msg(fmt, ##__VA_ARGS__);                 \
-} while (0)
+#define dbg_err(fmt, ...) ubi_err(fmt, ##__VA_ARGS__)
 
 #define ubi_dbg_dump_stack() dump_stack()
 
-struct ubi_ec_hdr;
-struct ubi_vid_hdr;
-struct ubi_volume;
-struct ubi_vtbl_record;
-struct ubi_scan_volume;
-struct ubi_scan_leb;
-struct ubi_mkvol_req;
+#define ubi_dbg_print_hex_dump(l, ps, pt, r, g, b, len, a)  \
+		print_hex_dump(l, ps, pt, r, g, b, len, a)
+
+#define ubi_dbg_msg(type, fmt, ...) \
+	pr_debug("UBI DBG " type ": " fmt "\n", ##__VA_ARGS__)
+
+/* Just a debugging messages not related to any specific UBI subsystem */
+#define dbg_msg(fmt, ...) ubi_dbg_msg("msg", fmt, ##__VA_ARGS__)
+/* General debugging messages */
+#define dbg_gen(fmt, ...) ubi_dbg_msg("gen", fmt, ##__VA_ARGS__)
+/* Messages from the eraseblock association sub-system */
+#define dbg_eba(fmt, ...) ubi_dbg_msg("eba", fmt, ##__VA_ARGS__)
+/* Messages from the wear-leveling sub-system */
+#define dbg_wl(fmt, ...)  ubi_dbg_msg("wl", fmt, ##__VA_ARGS__)
+/* Messages from the input/output sub-system */
+#define dbg_io(fmt, ...)  ubi_dbg_msg("io", fmt, ##__VA_ARGS__)
+/* Initialization and build messages */
+#define dbg_bld(fmt, ...) ubi_dbg_msg("bld", fmt, ##__VA_ARGS__)
 
 void ubi_dbg_dump_ec_hdr(const struct ubi_ec_hdr *ec_hdr);
 void ubi_dbg_dump_vid_hdr(const struct ubi_vid_hdr *vid_hdr);
@@ -62,43 +72,6 @@
 void ubi_dbg_dump_mkvol_req(const struct ubi_mkvol_req *req);
 void ubi_dbg_dump_flash(struct ubi_device *ubi, int pnum, int offset, int len);
 
-extern unsigned int ubi_msg_flags;
-
-/*
- * Debugging message type flags (must match msg_type_names in debug.c).
- *
- * UBI_MSG_GEN: general messages
- * UBI_MSG_EBA: journal messages
- * UBI_MSG_WL: mount messages
- * UBI_MSG_IO: commit messages
- * UBI_MSG_BLD: LEB find messages
- */
-enum {
-	UBI_MSG_GEN  = 0x1,
-	UBI_MSG_EBA  = 0x2,
-	UBI_MSG_WL   = 0x4,
-	UBI_MSG_IO   = 0x8,
-	UBI_MSG_BLD  = 0x10,
-};
-
-#define ubi_dbg_print_hex_dump(l, ps, pt, r, g, b, len, a)  \
-		print_hex_dump(l, ps, pt, r, g, b, len, a)
-
-/* General debugging messages */
-#define dbg_gen(fmt, ...) dbg_do_msg(UBI_MSG_GEN, fmt, ##__VA_ARGS__)
-
-/* Messages from the eraseblock association sub-system */
-#define dbg_eba(fmt, ...) dbg_do_msg(UBI_MSG_EBA, fmt, ##__VA_ARGS__)
-
-/* Messages from the wear-leveling sub-system */
-#define dbg_wl(fmt, ...) dbg_do_msg(UBI_MSG_WL, fmt, ##__VA_ARGS__)
-
-/* Messages from the input/output sub-system */
-#define dbg_io(fmt, ...) dbg_do_msg(UBI_MSG_IO, fmt, ##__VA_ARGS__)
-
-/* Initialization and build messages */
-#define dbg_bld(fmt, ...) dbg_do_msg(UBI_MSG_BLD, fmt, ##__VA_ARGS__)
-
 extern unsigned int ubi_chk_flags;
 
 /*
@@ -184,31 +157,61 @@
 
 #else
 
-#define ubi_assert(expr)                 ({})
-#define dbg_err(fmt, ...)                ({})
-#define dbg_msg(fmt, ...)                ({})
-#define dbg_gen(fmt, ...)                ({})
-#define dbg_eba(fmt, ...)                ({})
-#define dbg_wl(fmt, ...)                 ({})
-#define dbg_io(fmt, ...)                 ({})
-#define dbg_bld(fmt, ...)                ({})
-#define ubi_dbg_dump_stack()             ({})
-#define ubi_dbg_dump_ec_hdr(ec_hdr)      ({})
-#define ubi_dbg_dump_vid_hdr(vid_hdr)    ({})
-#define ubi_dbg_dump_vol_info(vol)       ({})
-#define ubi_dbg_dump_vtbl_record(r, idx) ({})
-#define ubi_dbg_dump_sv(sv)              ({})
-#define ubi_dbg_dump_seb(seb, type)      ({})
-#define ubi_dbg_dump_mkvol_req(req)      ({})
-#define ubi_dbg_dump_flash(ubi, pnum, offset, len) ({})
-#define ubi_dbg_print_hex_dump(l, ps, pt, r, g, b, len, a)  ({})
+/* Use "if (0)" to make compiler check arguments even if debugging is off */
+#define ubi_assert(expr)  do {                                               \
+	if (0) {                                                             \
+		printk(KERN_CRIT "UBI assert failed in %s at %u (pid %d)\n", \
+		       __func__, __LINE__, current->pid);                    \
+	}                                                                    \
+} while (0)
 
-#define ubi_dbg_is_bgt_disabled()  0
-#define ubi_dbg_is_bitflip()       0
-#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
+#define dbg_err(fmt, ...) do {                                               \
+	if (0)                                                               \
+		ubi_err(fmt, ##__VA_ARGS__);                                 \
+} while (0)
+
+#define ubi_dbg_msg(fmt, ...) do {                                           \
+	if (0)                                                               \
+		pr_debug(fmt "\n", ##__VA_ARGS__);                           \
+} while (0)
+
+#define dbg_msg(fmt, ...)  ubi_dbg_msg(fmt, ##__VA_ARGS__)
+#define dbg_gen(fmt, ...)  ubi_dbg_msg(fmt, ##__VA_ARGS__)
+#define dbg_eba(fmt, ...)  ubi_dbg_msg(fmt, ##__VA_ARGS__)
+#define dbg_wl(fmt, ...)   ubi_dbg_msg(fmt, ##__VA_ARGS__)
+#define dbg_io(fmt, ...)   ubi_dbg_msg(fmt, ##__VA_ARGS__)
+#define dbg_bld(fmt, ...)  ubi_dbg_msg(fmt, ##__VA_ARGS__)
+
+static inline void ubi_dbg_dump_stack(void)                          { return; }
+static inline void
+ubi_dbg_dump_ec_hdr(const struct ubi_ec_hdr *ec_hdr)                 { return; }
+static inline void
+ubi_dbg_dump_vid_hdr(const struct ubi_vid_hdr *vid_hdr)              { return; }
+static inline void
+ubi_dbg_dump_vol_info(const struct ubi_volume *vol)                  { return; }
+static inline void
+ubi_dbg_dump_vtbl_record(const struct ubi_vtbl_record *r, int idx)   { return; }
+static inline void ubi_dbg_dump_sv(const struct ubi_scan_volume *sv) { return; }
+static inline void ubi_dbg_dump_seb(const struct ubi_scan_leb *seb,
+				    int type)                        { return; }
+static inline void
+ubi_dbg_dump_mkvol_req(const struct ubi_mkvol_req *req)              { return; }
+static inline void ubi_dbg_dump_flash(struct ubi_device *ubi,
+				      int pnum, int offset, int len) { return; }
+static inline void
+ubi_dbg_print_hex_dump(const char *l, const char *ps, int pt, int r,
+		       int g, const void *b, size_t len, bool a)     { return; }
+
+static inline int ubi_dbg_is_bgt_disabled(void)                    { return 0; }
+static inline int ubi_dbg_is_bitflip(void)                         { return 0; }
+static inline int ubi_dbg_is_write_failure(void)                   { return 0; }
+static inline int ubi_dbg_is_erase_failure(void)                   { return 0; }
+static inline int ubi_dbg_check_all_ff(struct ubi_device *ubi,
+				       int pnum, int offset,
+				       int len)                    { return 0; }
+static inline int ubi_dbg_check_write(struct ubi_device *ubi,
+				      const void *buf, int pnum,
+				      int offset, int len)         { return 0; }
 
 #endif /* !CONFIG_MTD_UBI_DEBUG */
 #endif /* !__UBI_DEBUG_H__ */
diff -druN linux-2.6.39-libre/drivers/mtd/ubi/gluebi.c linux-3.0-rc7-libre/drivers/mtd/ubi/gluebi.c
--- linux-2.6.39-libre/drivers/mtd/ubi/gluebi.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mtd/ubi/gluebi.c	2011-07-11 19:51:52.000000000 -0400
@@ -365,7 +365,7 @@
 			vi->vol_id);
 	mutex_unlock(&devices_mutex);
 
-	if (add_mtd_device(mtd)) {
+	if (mtd_device_register(mtd, NULL, 0)) {
 		err_msg("cannot add MTD device");
 		kfree(mtd->name);
 		kfree(gluebi);
@@ -407,7 +407,7 @@
 		return err;
 
 	mtd = &gluebi->mtd;
-	err = del_mtd_device(mtd);
+	err = mtd_device_unregister(mtd);
 	if (err) {
 		err_msg("cannot remove fake MTD device %d, UBI device %d, "
 			"volume %d, error %d", mtd->index, gluebi->ubi_num,
@@ -524,7 +524,7 @@
 		int err;
 		struct mtd_info *mtd = &gluebi->mtd;
 
-		err = del_mtd_device(mtd);
+		err = mtd_device_unregister(mtd);
 		if (err)
 			err_msg("error %d while removing gluebi MTD device %d, "
 				"UBI device %d, volume %d - ignoring", err,
diff -druN linux-2.6.39-libre/drivers/mtd/ubi/io.c linux-3.0-rc7-libre/drivers/mtd/ubi/io.c
--- linux-2.6.39-libre/drivers/mtd/ubi/io.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mtd/ubi/io.c	2011-07-11 19:51:52.000000000 -0400
@@ -189,8 +189,8 @@
 		}
 
 		if (retries++ < UBI_IO_RETRIES) {
-			dbg_io("error %d%s while reading %d bytes from PEB %d:%d,"
-			       " read only %zd bytes, retry",
+			dbg_io("error %d%s while reading %d bytes from PEB "
+			       "%d:%d, read only %zd bytes, retry",
 			       err, errstr, len, pnum, offset, read);
 			yield();
 			goto retry;
@@ -465,7 +465,7 @@
 	}
 
 	err = patt_count;
-	ubi_msg("PEB %d passed torture test, do not mark it a bad", pnum);
+	ubi_msg("PEB %d passed torture test, do not mark it as bad", pnum);
 
 out:
 	mutex_unlock(&ubi->buf_mutex);
diff -druN linux-2.6.39-libre/drivers/mtd/ubi/scan.c linux-3.0-rc7-libre/drivers/mtd/ubi/scan.c
--- linux-2.6.39-libre/drivers/mtd/ubi/scan.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mtd/ubi/scan.c	2011-07-11 19:51:52.000000000 -0400
@@ -1103,7 +1103,7 @@
 		 * otherwise, only print a warning.
 		 */
 		if (si->corr_peb_count >= max_corr) {
-			ubi_err("too many corrupted PEBs, refusing this device");
+			ubi_err("too many corrupted PEBs, refusing");
 			return -EINVAL;
 		}
 	}
diff -druN linux-2.6.39-libre/drivers/mtd/ubi/ubi.h linux-3.0-rc7-libre/drivers/mtd/ubi/ubi.h
--- linux-2.6.39-libre/drivers/mtd/ubi/ubi.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mtd/ubi/ubi.h	2011-07-11 19:51:52.000000000 -0400
@@ -341,8 +341,8 @@
  *      protected from the wear-leveling worker)
  * @pq_head: protection queue head
  * @wl_lock: protects the @used, @free, @pq, @pq_head, @lookuptbl, @move_from,
- * 	     @move_to, @move_to_put @erase_pending, @wl_scheduled, @works,
- * 	     @erroneous, and @erroneous_peb_count fields
+ *	     @move_to, @move_to_put @erase_pending, @wl_scheduled, @works,
+ *	     @erroneous, and @erroneous_peb_count fields
  * @move_mutex: serializes eraseblock moves
  * @work_sem: synchronizes the WL worker with use tasks
  * @wl_scheduled: non-zero if the wear-leveling was scheduled
diff -druN linux-2.6.39-libre/drivers/mtd/ubi/ubi-media.h linux-3.0-rc7-libre/drivers/mtd/ubi/ubi-media.h
--- linux-2.6.39-libre/drivers/mtd/ubi/ubi-media.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mtd/ubi/ubi-media.h	2011-07-11 19:51:52.000000000 -0400
@@ -164,7 +164,7 @@
 	__be32  image_seq;
 	__u8    padding2[32];
 	__be32  hdr_crc;
-} __attribute__ ((packed));
+} __packed;
 
 /**
  * struct ubi_vid_hdr - on-flash UBI volume identifier header.
@@ -292,7 +292,7 @@
 	__be64  sqnum;
 	__u8    padding3[12];
 	__be32  hdr_crc;
-} __attribute__ ((packed));
+} __packed;
 
 /* Internal UBI volumes count */
 #define UBI_INT_VOL_COUNT 1
@@ -373,6 +373,6 @@
 	__u8    flags;
 	__u8    padding[23];
 	__be32  crc;
-} __attribute__ ((packed));
+} __packed;
 
 #endif /* !__UBI_MEDIA_H__ */
diff -druN linux-2.6.39-libre/drivers/mtd/ubi/wl.c linux-3.0-rc7-libre/drivers/mtd/ubi/wl.c
--- linux-2.6.39-libre/drivers/mtd/ubi/wl.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/mtd/ubi/wl.c	2011-07-11 19:51:52.000000000 -0400
@@ -1570,7 +1570,8 @@
  * @ec: the erase counter to check
  *
  * This function returns zero if the erase counter of physical eraseblock @pnum
- * is equivalent to @ec, and a negative error code if not or 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)
 {
diff -druN linux-2.6.39-libre/drivers/net/3c503.c linux-3.0-rc7-libre/drivers/net/3c503.c
--- linux-2.6.39-libre/drivers/net/3c503.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/3c503.c	2011-07-11 19:51:52.000000000 -0400
@@ -412,7 +412,7 @@
 		outb_p(0x04 << ((*irqp == 9) ? 2 : *irqp), E33G_IDCFR);
 		outb_p(0x00, E33G_IDCFR);
 		msleep(1);
-		free_irq(*irqp, el2_probe_interrupt);
+		free_irq(*irqp, &seen);
 		if (!seen)
 			continue;
 
@@ -422,6 +422,7 @@
 			continue;
 		if (retval < 0)
 			goto err_disable;
+		break;
 	} while (*++irqp);
 
 	if (*irqp == 0) {
diff -druN linux-2.6.39-libre/drivers/net/3c509.c linux-3.0-rc7-libre/drivers/net/3c509.c
--- linux-2.6.39-libre/drivers/net/3c509.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/3c509.c	2011-07-11 19:51:52.000000000 -0400
@@ -1207,7 +1207,7 @@
 			ecmd->duplex = DUPLEX_FULL;
 	}
 
-	ecmd->speed = SPEED_10;
+	ethtool_cmd_speed_set(ecmd, SPEED_10);
 	EL3WINDOW(1);
 	return 0;
 }
diff -druN linux-2.6.39-libre/drivers/net/8139cp.c linux-3.0-rc7-libre/drivers/net/8139cp.c
--- linux-2.6.39-libre/drivers/net/8139cp.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/8139cp.c	2011-07-11 19:51:52.000000000 -0400
@@ -758,8 +758,7 @@
 
 	entry = cp->tx_head;
 	eor = (entry == (CP_TX_RING_SIZE - 1)) ? RingEnd : 0;
-	if (dev->features & NETIF_F_TSO)
-		mss = skb_shinfo(skb)->gso_size;
+	mss = skb_shinfo(skb)->gso_size;
 
 	if (skb_shinfo(skb)->nr_frags == 0) {
 		struct cp_desc *txd = &cp->tx_ring[entry];
@@ -1416,32 +1415,23 @@
 	cp->msg_enable = value;
 }
 
-static u32 cp_get_rx_csum(struct net_device *dev)
+static int cp_set_features(struct net_device *dev, u32 features)
 {
 	struct cp_private *cp = netdev_priv(dev);
-	return (cpr16(CpCmd) & RxChkSum) ? 1 : 0;
-}
+	unsigned long flags;
 
-static int cp_set_rx_csum(struct net_device *dev, u32 data)
-{
-	struct cp_private *cp = netdev_priv(dev);
-	u16 cmd = cp->cpcmd, newcmd;
+	if (!((dev->features ^ features) & NETIF_F_RXCSUM))
+		return 0;
 
-	newcmd = cmd;
+	spin_lock_irqsave(&cp->lock, flags);
 
-	if (data)
-		newcmd |= RxChkSum;
+	if (features & NETIF_F_RXCSUM)
+		cp->cpcmd |= RxChkSum;
 	else
-		newcmd &= ~RxChkSum;
-
-	if (newcmd != cmd) {
-		unsigned long flags;
+		cp->cpcmd &= ~RxChkSum;
 
-		spin_lock_irqsave(&cp->lock, flags);
-		cp->cpcmd = newcmd;
-		cpw16_f(CpCmd, newcmd);
-		spin_unlock_irqrestore(&cp->lock, flags);
-	}
+	cpw16_f(CpCmd, cp->cpcmd);
+	spin_unlock_irqrestore(&cp->lock, flags);
 
 	return 0;
 }
@@ -1554,11 +1544,6 @@
 	.get_link		= ethtool_op_get_link,
 	.get_msglevel		= cp_get_msglevel,
 	.set_msglevel		= cp_set_msglevel,
-	.get_rx_csum		= cp_get_rx_csum,
-	.set_rx_csum		= cp_set_rx_csum,
-	.set_tx_csum		= ethtool_op_set_tx_csum, /* local! */
-	.set_sg			= ethtool_op_set_sg,
-	.set_tso		= ethtool_op_set_tso,
 	.get_regs		= cp_get_regs,
 	.get_wol		= cp_get_wol,
 	.set_wol		= cp_set_wol,
@@ -1831,6 +1816,7 @@
 	.ndo_do_ioctl		= cp_ioctl,
 	.ndo_start_xmit		= cp_start_xmit,
 	.ndo_tx_timeout		= cp_tx_timeout,
+	.ndo_set_features	= cp_set_features,
 #if CP_VLAN_TAG_USED
 	.ndo_vlan_rx_register	= cp_vlan_rx_register,
 #endif
@@ -1934,6 +1920,9 @@
 	cp->cpcmd = (pci_using_dac ? PCIDAC : 0) |
 		    PCIMulRW | RxChkSum | CpRxOn | CpTxOn;
 
+	dev->features |= NETIF_F_RXCSUM;
+	dev->hw_features |= NETIF_F_RXCSUM;
+
 	regs = ioremap(pciaddr, CP_REGS_SIZE);
 	if (!regs) {
 		rc = -EIO;
@@ -1966,9 +1955,8 @@
 	if (pci_using_dac)
 		dev->features |= NETIF_F_HIGHDMA;
 
-#if 0 /* disabled by default until verified */
-	dev->features |= NETIF_F_TSO;
-#endif
+	/* disabled by default until verified */
+	dev->hw_features |= NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO;
 
 	dev->irq = pdev->irq;
 
diff -druN linux-2.6.39-libre/drivers/net/8139too.c linux-3.0-rc7-libre/drivers/net/8139too.c
--- linux-2.6.39-libre/drivers/net/8139too.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/8139too.c	2011-07-11 19:51:52.000000000 -0400
@@ -992,6 +992,7 @@
 	 * features
 	 */
 	dev->features |= NETIF_F_SG | NETIF_F_HW_CSUM | NETIF_F_HIGHDMA;
+	dev->vlan_features = dev->features;
 
 	dev->irq = pdev->irq;
 
diff -druN linux-2.6.39-libre/drivers/net/acenic.c linux-3.0-rc7-libre/drivers/net/acenic.c
--- linux-2.6.39-libre/drivers/net/acenic.c	2011-05-19 02:11:03.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/acenic.c	2011-07-21 06:53:34.000000000 -0400
@@ -68,6 +68,7 @@
 #include <linux/sockios.h>
 #include <linux/firmware.h>
 #include <linux/slab.h>
+#include <linux/prefetch.h>
 
 #if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
 #include <linux/if_vlan.h>
@@ -2658,15 +2659,15 @@
 
 	link = readl(&regs->GigLnkState);
 	if (link & LNK_1000MB)
-		ecmd->speed = SPEED_1000;
+		ethtool_cmd_speed_set(ecmd, SPEED_1000);
 	else {
 		link = readl(&regs->FastLnkState);
 		if (link & LNK_100MB)
-			ecmd->speed = SPEED_100;
+			ethtool_cmd_speed_set(ecmd, SPEED_100);
 		else if (link & LNK_10MB)
-			ecmd->speed = SPEED_10;
+			ethtool_cmd_speed_set(ecmd, SPEED_10);
 		else
-			ecmd->speed = 0;
+			ethtool_cmd_speed_set(ecmd, 0);
 	}
 	if (link & LNK_FULL_DUPLEX)
 		ecmd->duplex = DUPLEX_FULL;
@@ -2718,9 +2719,9 @@
 		link |= LNK_TX_FLOW_CTL_Y;
 	if (ecmd->autoneg == AUTONEG_ENABLE)
 		link |= LNK_NEGOTIATE;
-	if (ecmd->speed != speed) {
+	if (ethtool_cmd_speed(ecmd) != speed) {
 		link &= ~(LNK_1000MB | LNK_100MB | LNK_10MB);
-		switch (speed) {
+		switch (ethtool_cmd_speed(ecmd)) {
 		case SPEED_1000:
 			link |= LNK_1000MB;
 			break;
diff -druN linux-2.6.39-libre/drivers/net/arm/am79c961a.c linux-3.0-rc7-libre/drivers/net/arm/am79c961a.c
--- linux-2.6.39-libre/drivers/net/arm/am79c961a.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/arm/am79c961a.c	2011-07-11 19:51:52.000000000 -0400
@@ -50,7 +50,7 @@
 #ifdef __arm__
 static void write_rreg(u_long base, u_int reg, u_int val)
 {
-	__asm__(
+	asm volatile(
 	"str%?h	%1, [%2]	@ NET_RAP\n\t"
 	"str%?h	%0, [%2, #-4]	@ NET_RDP"
 	:
@@ -60,7 +60,7 @@
 static inline unsigned short read_rreg(u_long base_addr, u_int reg)
 {
 	unsigned short v;
-	__asm__(
+	asm volatile(
 	"str%?h	%1, [%2]	@ NET_RAP\n\t"
 	"ldr%?h	%0, [%2, #-4]	@ NET_RDP"
 	: "=r" (v)
@@ -70,7 +70,7 @@
 
 static inline void write_ireg(u_long base, u_int reg, u_int val)
 {
-	__asm__(
+	asm volatile(
 	"str%?h	%1, [%2]	@ NET_RAP\n\t"
 	"str%?h	%0, [%2, #8]	@ NET_IDP"
 	:
@@ -80,7 +80,7 @@
 static inline unsigned short read_ireg(u_long base_addr, u_int reg)
 {
 	u_short v;
-	__asm__(
+	asm volatile(
 	"str%?h	%1, [%2]	@ NAT_RAP\n\t"
 	"ldr%?h	%0, [%2, #8]	@ NET_IDP\n\t"
 	: "=r" (v)
@@ -91,47 +91,48 @@
 #define am_writeword(dev,off,val) __raw_writew(val, ISAMEM_BASE + ((off) << 1))
 #define am_readword(dev,off)      __raw_readw(ISAMEM_BASE + ((off) << 1))
 
-static inline void
+static void
 am_writebuffer(struct net_device *dev, u_int offset, unsigned char *buf, unsigned int length)
 {
 	offset = ISAMEM_BASE + (offset << 1);
 	length = (length + 1) & ~1;
 	if ((int)buf & 2) {
-		__asm__ __volatile__("str%?h	%2, [%0], #4"
+		asm volatile("str%?h	%2, [%0], #4"
 		 : "=&r" (offset) : "0" (offset), "r" (buf[0] | (buf[1] << 8)));
 		buf += 2;
 		length -= 2;
 	}
 	while (length > 8) {
-		unsigned int tmp, tmp2;
-		__asm__ __volatile__(
-			"ldm%?ia	%1!, {%2, %3}\n\t"
+		register unsigned int tmp asm("r2"), tmp2 asm("r3");
+		asm volatile(
+			"ldm%?ia	%0!, {%1, %2}"
+			: "+r" (buf), "=&r" (tmp), "=&r" (tmp2));
+		length -= 8;
+		asm volatile(
+			"str%?h	%1, [%0], #4\n\t"
+			"mov%?	%1, %1, lsr #16\n\t"
+			"str%?h	%1, [%0], #4\n\t"
 			"str%?h	%2, [%0], #4\n\t"
 			"mov%?	%2, %2, lsr #16\n\t"
-			"str%?h	%2, [%0], #4\n\t"
-			"str%?h	%3, [%0], #4\n\t"
-			"mov%?	%3, %3, lsr #16\n\t"
-			"str%?h	%3, [%0], #4"
-		: "=&r" (offset), "=&r" (buf), "=r" (tmp), "=r" (tmp2)
-		: "0" (offset), "1" (buf));
-		length -= 8;
+			"str%?h	%2, [%0], #4"
+		: "+r" (offset), "=&r" (tmp), "=&r" (tmp2));
 	}
 	while (length > 0) {
-		__asm__ __volatile__("str%?h	%2, [%0], #4"
+		asm volatile("str%?h	%2, [%0], #4"
 		 : "=&r" (offset) : "0" (offset), "r" (buf[0] | (buf[1] << 8)));
 		buf += 2;
 		length -= 2;
 	}
 }
 
-static inline void
+static void
 am_readbuffer(struct net_device *dev, u_int offset, unsigned char *buf, unsigned int length)
 {
 	offset = ISAMEM_BASE + (offset << 1);
 	length = (length + 1) & ~1;
 	if ((int)buf & 2) {
 		unsigned int tmp;
-		__asm__ __volatile__(
+		asm volatile(
 			"ldr%?h	%2, [%0], #4\n\t"
 			"str%?b	%2, [%1], #1\n\t"
 			"mov%?	%2, %2, lsr #8\n\t"
@@ -140,12 +141,12 @@
 		length -= 2;
 	}
 	while (length > 8) {
-		unsigned int tmp, tmp2, tmp3;
-		__asm__ __volatile__(
+		register unsigned int tmp asm("r2"), tmp2 asm("r3"), tmp3;
+		asm volatile(
 			"ldr%?h	%2, [%0], #4\n\t"
+			"ldr%?h	%4, [%0], #4\n\t"
 			"ldr%?h	%3, [%0], #4\n\t"
-			"orr%?	%2, %2, %3, lsl #16\n\t"
-			"ldr%?h	%3, [%0], #4\n\t"
+			"orr%?	%2, %2, %4, lsl #16\n\t"
 			"ldr%?h	%4, [%0], #4\n\t"
 			"orr%?	%3, %3, %4, lsl #16\n\t"
 			"stm%?ia	%1!, {%2, %3}"
@@ -155,7 +156,7 @@
 	}
 	while (length > 0) {
 		unsigned int tmp;
-		__asm__ __volatile__(
+		asm volatile(
 			"ldr%?h	%2, [%0], #4\n\t"
 			"str%?b	%2, [%1], #1\n\t"
 			"mov%?	%2, %2, lsr #8\n\t"
@@ -196,6 +197,42 @@
 	return errorcount;
 }
 
+static void am79c961_mc_hash(char *addr, u16 *hash)
+{
+	if (addr[0] & 0x01) {
+		int idx, bit;
+		u32 crc;
+
+		crc = ether_crc_le(ETH_ALEN, addr);
+
+		idx = crc >> 30;
+		bit = (crc >> 26) & 15;
+
+		hash[idx] |= 1 << bit;
+	}
+}
+
+static unsigned int am79c961_get_rx_mode(struct net_device *dev, u16 *hash)
+{
+	unsigned int mode = MODE_PORT_10BT;
+
+	if (dev->flags & IFF_PROMISC) {
+		mode |= MODE_PROMISC;
+		memset(hash, 0xff, 4 * sizeof(*hash));
+	} else if (dev->flags & IFF_ALLMULTI) {
+		memset(hash, 0xff, 4 * sizeof(*hash));
+	} else {
+		struct netdev_hw_addr *ha;
+
+		memset(hash, 0, 4 * sizeof(*hash));
+
+		netdev_for_each_mc_addr(ha, dev)
+			am79c961_mc_hash(ha->addr, hash);
+	}
+
+	return mode;
+}
+
 static void
 am79c961_init_for_open(struct net_device *dev)
 {
@@ -203,6 +240,7 @@
 	unsigned long flags;
 	unsigned char *p;
 	u_int hdr_addr, first_free_addr;
+	u16 multi_hash[4], mode = am79c961_get_rx_mode(dev, multi_hash);
 	int i;
 
 	/*
@@ -218,16 +256,12 @@
 	write_ireg (dev->base_addr, 2, 0x0000); /* MODE register selects media */
 
 	for (i = LADRL; i <= LADRH; i++)
-		write_rreg (dev->base_addr, i, 0);
+		write_rreg (dev->base_addr, i, multi_hash[i - LADRL]);
 
 	for (i = PADRL, p = dev->dev_addr; i <= PADRH; i++, p += 2)
 		write_rreg (dev->base_addr, i, p[0] | (p[1] << 8));
 
-	i = MODE_PORT_10BT;
-	if (dev->flags & IFF_PROMISC)
-		i |= MODE_PROMISC;
-
-	write_rreg (dev->base_addr, MODE, i);
+	write_rreg (dev->base_addr, MODE, mode);
 	write_rreg (dev->base_addr, POLLINT, 0);
 	write_rreg (dev->base_addr, SIZERXR, -RX_BUFFERS);
 	write_rreg (dev->base_addr, SIZETXR, -TX_BUFFERS);
@@ -340,21 +374,6 @@
 	return 0;
 }
 
-static void am79c961_mc_hash(char *addr, unsigned short *hash)
-{
-	if (addr[0] & 0x01) {
-		int idx, bit;
-		u32 crc;
-
-		crc = ether_crc_le(ETH_ALEN, addr);
-
-		idx = crc >> 30;
-		bit = (crc >> 26) & 15;
-
-		hash[idx] |= 1 << bit;
-	}
-}
-
 /*
  * Set or clear promiscuous/multicast mode filter for this adapter.
  */
@@ -362,24 +381,9 @@
 {
 	struct dev_priv *priv = netdev_priv(dev);
 	unsigned long flags;
-	unsigned short multi_hash[4], mode;
+	u16 multi_hash[4], mode = am79c961_get_rx_mode(dev, multi_hash);
 	int i, stopped;
 
-	mode = MODE_PORT_10BT;
-
-	if (dev->flags & IFF_PROMISC) {
-		mode |= MODE_PROMISC;
-	} else if (dev->flags & IFF_ALLMULTI) {
-		memset(multi_hash, 0xff, sizeof(multi_hash));
-	} else {
-		struct netdev_hw_addr *ha;
-
-		memset(multi_hash, 0x00, sizeof(multi_hash));
-
-		netdev_for_each_mc_addr(ha, dev)
-			am79c961_mc_hash(ha->addr, multi_hash);
-	}
-
 	spin_lock_irqsave(&priv->chip_lock, flags);
 
 	stopped = read_rreg(dev->base_addr, CSR0) & CSR0_STOP;
diff -druN linux-2.6.39-libre/drivers/net/arm/ep93xx_eth.c linux-3.0-rc7-libre/drivers/net/arm/ep93xx_eth.c
--- linux-2.6.39-libre/drivers/net/arm/ep93xx_eth.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/arm/ep93xx_eth.c	2011-07-11 19:51:52.000000000 -0400
@@ -283,10 +283,14 @@
 
 		skb = dev_alloc_skb(length + 2);
 		if (likely(skb != NULL)) {
+			struct ep93xx_rdesc *rxd = &ep->descs->rdesc[entry];
 			skb_reserve(skb, 2);
-			dma_sync_single_for_cpu(NULL, ep->descs->rdesc[entry].buf_addr,
+			dma_sync_single_for_cpu(dev->dev.parent, rxd->buf_addr,
 						length, DMA_FROM_DEVICE);
 			skb_copy_to_linear_data(skb, ep->rx_buf[entry], length);
+			dma_sync_single_for_device(dev->dev.parent,
+						   rxd->buf_addr, length,
+						   DMA_FROM_DEVICE);
 			skb_put(skb, length);
 			skb->protocol = eth_type_trans(skb, dev);
 
@@ -348,6 +352,7 @@
 static int ep93xx_xmit(struct sk_buff *skb, struct net_device *dev)
 {
 	struct ep93xx_priv *ep = netdev_priv(dev);
+	struct ep93xx_tdesc *txd;
 	int entry;
 
 	if (unlikely(skb->len > MAX_PKT_SIZE)) {
@@ -359,11 +364,14 @@
 	entry = ep->tx_pointer;
 	ep->tx_pointer = (ep->tx_pointer + 1) & (TX_QUEUE_ENTRIES - 1);
 
-	ep->descs->tdesc[entry].tdesc1 =
-		TDESC1_EOF | (entry << 16) | (skb->len & 0xfff);
+	txd = &ep->descs->tdesc[entry];
+
+	txd->tdesc1 = TDESC1_EOF | (entry << 16) | (skb->len & 0xfff);
+	dma_sync_single_for_cpu(dev->dev.parent, txd->buf_addr, skb->len,
+				DMA_TO_DEVICE);
 	skb_copy_and_csum_dev(skb, ep->tx_buf[entry]);
-	dma_sync_single_for_cpu(NULL, ep->descs->tdesc[entry].buf_addr,
-				skb->len, DMA_TO_DEVICE);
+	dma_sync_single_for_device(dev->dev.parent, txd->buf_addr, skb->len,
+				   DMA_TO_DEVICE);
 	dev_kfree_skb(skb);
 
 	spin_lock_irq(&ep->tx_pending_lock);
@@ -457,89 +465,80 @@
 
 static void ep93xx_free_buffers(struct ep93xx_priv *ep)
 {
+	struct device *dev = ep->dev->dev.parent;
 	int i;
 
-	for (i = 0; i < RX_QUEUE_ENTRIES; i += 2) {
+	for (i = 0; i < RX_QUEUE_ENTRIES; i++) {
 		dma_addr_t d;
 
 		d = ep->descs->rdesc[i].buf_addr;
 		if (d)
-			dma_unmap_single(NULL, d, PAGE_SIZE, DMA_FROM_DEVICE);
+			dma_unmap_single(dev, d, PKT_BUF_SIZE, DMA_FROM_DEVICE);
 
 		if (ep->rx_buf[i] != NULL)
-			free_page((unsigned long)ep->rx_buf[i]);
+			kfree(ep->rx_buf[i]);
 	}
 
-	for (i = 0; i < TX_QUEUE_ENTRIES; i += 2) {
+	for (i = 0; i < TX_QUEUE_ENTRIES; i++) {
 		dma_addr_t d;
 
 		d = ep->descs->tdesc[i].buf_addr;
 		if (d)
-			dma_unmap_single(NULL, d, PAGE_SIZE, DMA_TO_DEVICE);
+			dma_unmap_single(dev, d, PKT_BUF_SIZE, DMA_TO_DEVICE);
 
 		if (ep->tx_buf[i] != NULL)
-			free_page((unsigned long)ep->tx_buf[i]);
+			kfree(ep->tx_buf[i]);
 	}
 
-	dma_free_coherent(NULL, sizeof(struct ep93xx_descs), ep->descs,
+	dma_free_coherent(dev, sizeof(struct ep93xx_descs), ep->descs,
 							ep->descs_dma_addr);
 }
 
-/*
- * The hardware enforces a sub-2K maximum packet size, so we put
- * two buffers on every hardware page.
- */
 static int ep93xx_alloc_buffers(struct ep93xx_priv *ep)
 {
+	struct device *dev = ep->dev->dev.parent;
 	int i;
 
-	ep->descs = dma_alloc_coherent(NULL, sizeof(struct ep93xx_descs),
-				&ep->descs_dma_addr, GFP_KERNEL | GFP_DMA);
+	ep->descs = dma_alloc_coherent(dev, sizeof(struct ep93xx_descs),
+				&ep->descs_dma_addr, GFP_KERNEL);
 	if (ep->descs == NULL)
 		return 1;
 
-	for (i = 0; i < RX_QUEUE_ENTRIES; i += 2) {
-		void *page;
+	for (i = 0; i < RX_QUEUE_ENTRIES; i++) {
+		void *buf;
 		dma_addr_t d;
 
-		page = (void *)__get_free_page(GFP_KERNEL | GFP_DMA);
-		if (page == NULL)
+		buf = kmalloc(PKT_BUF_SIZE, GFP_KERNEL);
+		if (buf == NULL)
 			goto err;
 
-		d = dma_map_single(NULL, page, PAGE_SIZE, DMA_FROM_DEVICE);
-		if (dma_mapping_error(NULL, d)) {
-			free_page((unsigned long)page);
+		d = dma_map_single(dev, buf, PKT_BUF_SIZE, DMA_FROM_DEVICE);
+		if (dma_mapping_error(dev, d)) {
+			kfree(buf);
 			goto err;
 		}
 
-		ep->rx_buf[i] = page;
+		ep->rx_buf[i] = buf;
 		ep->descs->rdesc[i].buf_addr = d;
 		ep->descs->rdesc[i].rdesc1 = (i << 16) | PKT_BUF_SIZE;
-
-		ep->rx_buf[i + 1] = page + PKT_BUF_SIZE;
-		ep->descs->rdesc[i + 1].buf_addr = d + PKT_BUF_SIZE;
-		ep->descs->rdesc[i + 1].rdesc1 = ((i + 1) << 16) | PKT_BUF_SIZE;
 	}
 
-	for (i = 0; i < TX_QUEUE_ENTRIES; i += 2) {
-		void *page;
+	for (i = 0; i < TX_QUEUE_ENTRIES; i++) {
+		void *buf;
 		dma_addr_t d;
 
-		page = (void *)__get_free_page(GFP_KERNEL | GFP_DMA);
-		if (page == NULL)
+		buf = kmalloc(PKT_BUF_SIZE, GFP_KERNEL);
+		if (buf == NULL)
 			goto err;
 
-		d = dma_map_single(NULL, page, PAGE_SIZE, DMA_TO_DEVICE);
-		if (dma_mapping_error(NULL, d)) {
-			free_page((unsigned long)page);
+		d = dma_map_single(dev, buf, PKT_BUF_SIZE, DMA_TO_DEVICE);
+		if (dma_mapping_error(dev, d)) {
+			kfree(buf);
 			goto err;
 		}
 
-		ep->tx_buf[i] = page;
+		ep->tx_buf[i] = buf;
 		ep->descs->tdesc[i].buf_addr = d;
-
-		ep->tx_buf[i + 1] = page + PKT_BUF_SIZE;
-		ep->descs->tdesc[i + 1].buf_addr = d + PKT_BUF_SIZE;
 	}
 
 	return 0;
@@ -829,6 +828,7 @@
 	}
 	ep = netdev_priv(dev);
 	ep->dev = dev;
+	SET_NETDEV_DEV(dev, &pdev->dev);
 	netif_napi_add(dev, &ep->napi, ep93xx_poll, 64);
 
 	platform_set_drvdata(pdev, dev);
diff -druN linux-2.6.39-libre/drivers/net/arm/etherh.c linux-3.0-rc7-libre/drivers/net/arm/etherh.c
--- linux-2.6.39-libre/drivers/net/arm/etherh.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/arm/etherh.c	2011-07-11 19:51:52.000000000 -0400
@@ -591,10 +591,11 @@
 static int etherh_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
 {
 	cmd->supported	= etherh_priv(dev)->supported;
-	cmd->speed	= SPEED_10;
+	ethtool_cmd_speed_set(cmd, SPEED_10);
 	cmd->duplex	= DUPLEX_HALF;
 	cmd->port	= dev->if_port == IF_PORT_10BASET ? PORT_TP : PORT_BNC;
-	cmd->autoneg	= dev->flags & IFF_AUTOMEDIA ? AUTONEG_ENABLE : AUTONEG_DISABLE;
+	cmd->autoneg	= (dev->flags & IFF_AUTOMEDIA ?
+			   AUTONEG_ENABLE : AUTONEG_DISABLE);
 	return 0;
 }
 
diff -druN linux-2.6.39-libre/drivers/net/arm/ixp4xx_eth.c linux-3.0-rc7-libre/drivers/net/arm/ixp4xx_eth.c
--- linux-2.6.39-libre/drivers/net/arm/ixp4xx_eth.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/arm/ixp4xx_eth.c	2011-07-11 19:51:52.000000000 -0400
@@ -30,9 +30,12 @@
 #include <linux/etherdevice.h>
 #include <linux/io.h>
 #include <linux/kernel.h>
+#include <linux/net_tstamp.h>
 #include <linux/phy.h>
 #include <linux/platform_device.h>
+#include <linux/ptp_classify.h>
 #include <linux/slab.h>
+#include <mach/ixp46x_ts.h>
 #include <mach/npe.h>
 #include <mach/qmgr.h>
 
@@ -67,6 +70,10 @@
 #define RXFREE_QUEUE(port_id)	(NPE_ID(port_id) + 26)
 #define TXDONE_QUEUE		31
 
+#define PTP_SLAVE_MODE		1
+#define PTP_MASTER_MODE		2
+#define PORT2CHANNEL(p)		NPE_ID(p->id)
+
 /* TX Control Registers */
 #define TX_CNTRL0_TX_EN		0x01
 #define TX_CNTRL0_HALFDUPLEX	0x02
@@ -171,6 +178,8 @@
 	int id;			/* logical port ID */
 	int speed, duplex;
 	u8 firmware[4];
+	int hwts_tx_en;
+	int hwts_rx_en;
 };
 
 /* NPE message structure */
@@ -246,6 +255,172 @@
 static struct port *npe_port_tab[MAX_NPES];
 static struct dma_pool *dma_pool;
 
+static struct sock_filter ptp_filter[] = {
+	PTP_FILTER
+};
+
+static int ixp_ptp_match(struct sk_buff *skb, u16 uid_hi, u32 uid_lo, u16 seqid)
+{
+	u8 *data = skb->data;
+	unsigned int offset;
+	u16 *hi, *id;
+	u32 lo;
+
+	if (sk_run_filter(skb, ptp_filter) != PTP_CLASS_V1_IPV4)
+		return 0;
+
+	offset = ETH_HLEN + IPV4_HLEN(data) + UDP_HLEN;
+
+	if (skb->len < offset + OFF_PTP_SEQUENCE_ID + sizeof(seqid))
+		return 0;
+
+	hi = (u16 *)(data + offset + OFF_PTP_SOURCE_UUID);
+	id = (u16 *)(data + offset + OFF_PTP_SEQUENCE_ID);
+
+	memcpy(&lo, &hi[1], sizeof(lo));
+
+	return (uid_hi == ntohs(*hi) &&
+		uid_lo == ntohl(lo) &&
+		seqid  == ntohs(*id));
+}
+
+static void ixp_rx_timestamp(struct port *port, struct sk_buff *skb)
+{
+	struct skb_shared_hwtstamps *shhwtstamps;
+	struct ixp46x_ts_regs *regs;
+	u64 ns;
+	u32 ch, hi, lo, val;
+	u16 uid, seq;
+
+	if (!port->hwts_rx_en)
+		return;
+
+	ch = PORT2CHANNEL(port);
+
+	regs = (struct ixp46x_ts_regs __iomem *) IXP4XX_TIMESYNC_BASE_VIRT;
+
+	val = __raw_readl(&regs->channel[ch].ch_event);
+
+	if (!(val & RX_SNAPSHOT_LOCKED))
+		return;
+
+	lo = __raw_readl(&regs->channel[ch].src_uuid_lo);
+	hi = __raw_readl(&regs->channel[ch].src_uuid_hi);
+
+	uid = hi & 0xffff;
+	seq = (hi >> 16) & 0xffff;
+
+	if (!ixp_ptp_match(skb, htons(uid), htonl(lo), htons(seq)))
+		goto out;
+
+	lo = __raw_readl(&regs->channel[ch].rx_snap_lo);
+	hi = __raw_readl(&regs->channel[ch].rx_snap_hi);
+	ns = ((u64) hi) << 32;
+	ns |= lo;
+	ns <<= TICKS_NS_SHIFT;
+
+	shhwtstamps = skb_hwtstamps(skb);
+	memset(shhwtstamps, 0, sizeof(*shhwtstamps));
+	shhwtstamps->hwtstamp = ns_to_ktime(ns);
+out:
+	__raw_writel(RX_SNAPSHOT_LOCKED, &regs->channel[ch].ch_event);
+}
+
+static void ixp_tx_timestamp(struct port *port, struct sk_buff *skb)
+{
+	struct skb_shared_hwtstamps shhwtstamps;
+	struct ixp46x_ts_regs *regs;
+	struct skb_shared_info *shtx;
+	u64 ns;
+	u32 ch, cnt, hi, lo, val;
+
+	shtx = skb_shinfo(skb);
+	if (unlikely(shtx->tx_flags & SKBTX_HW_TSTAMP && port->hwts_tx_en))
+		shtx->tx_flags |= SKBTX_IN_PROGRESS;
+	else
+		return;
+
+	ch = PORT2CHANNEL(port);
+
+	regs = (struct ixp46x_ts_regs __iomem *) IXP4XX_TIMESYNC_BASE_VIRT;
+
+	/*
+	 * This really stinks, but we have to poll for the Tx time stamp.
+	 * Usually, the time stamp is ready after 4 to 6 microseconds.
+	 */
+	for (cnt = 0; cnt < 100; cnt++) {
+		val = __raw_readl(&regs->channel[ch].ch_event);
+		if (val & TX_SNAPSHOT_LOCKED)
+			break;
+		udelay(1);
+	}
+	if (!(val & TX_SNAPSHOT_LOCKED)) {
+		shtx->tx_flags &= ~SKBTX_IN_PROGRESS;
+		return;
+	}
+
+	lo = __raw_readl(&regs->channel[ch].tx_snap_lo);
+	hi = __raw_readl(&regs->channel[ch].tx_snap_hi);
+	ns = ((u64) hi) << 32;
+	ns |= lo;
+	ns <<= TICKS_NS_SHIFT;
+
+	memset(&shhwtstamps, 0, sizeof(shhwtstamps));
+	shhwtstamps.hwtstamp = ns_to_ktime(ns);
+	skb_tstamp_tx(skb, &shhwtstamps);
+
+	__raw_writel(TX_SNAPSHOT_LOCKED, &regs->channel[ch].ch_event);
+}
+
+static int hwtstamp_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
+{
+	struct hwtstamp_config cfg;
+	struct ixp46x_ts_regs *regs;
+	struct port *port = netdev_priv(netdev);
+	int ch;
+
+	if (copy_from_user(&cfg, ifr->ifr_data, sizeof(cfg)))
+		return -EFAULT;
+
+	if (cfg.flags) /* reserved for future extensions */
+		return -EINVAL;
+
+	ch = PORT2CHANNEL(port);
+	regs = (struct ixp46x_ts_regs __iomem *) IXP4XX_TIMESYNC_BASE_VIRT;
+
+	switch (cfg.tx_type) {
+	case HWTSTAMP_TX_OFF:
+		port->hwts_tx_en = 0;
+		break;
+	case HWTSTAMP_TX_ON:
+		port->hwts_tx_en = 1;
+		break;
+	default:
+		return -ERANGE;
+	}
+
+	switch (cfg.rx_filter) {
+	case HWTSTAMP_FILTER_NONE:
+		port->hwts_rx_en = 0;
+		break;
+	case HWTSTAMP_FILTER_PTP_V1_L4_SYNC:
+		port->hwts_rx_en = PTP_SLAVE_MODE;
+		__raw_writel(0, &regs->channel[ch].ch_control);
+		break;
+	case HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ:
+		port->hwts_rx_en = PTP_MASTER_MODE;
+		__raw_writel(MASTER_MODE, &regs->channel[ch].ch_control);
+		break;
+	default:
+		return -ERANGE;
+	}
+
+	/* Clear out any old time stamps. */
+	__raw_writel(TX_SNAPSHOT_LOCKED | RX_SNAPSHOT_LOCKED,
+		     &regs->channel[ch].ch_event);
+
+	return copy_to_user(ifr->ifr_data, &cfg, sizeof(cfg)) ? -EFAULT : 0;
+}
 
 static int ixp4xx_mdio_cmd(struct mii_bus *bus, int phy_id, int location,
 			   int write, u16 cmd)
@@ -573,6 +748,7 @@
 
 		debug_pkt(dev, "eth_poll", skb->data, skb->len);
 
+		ixp_rx_timestamp(port, skb);
 		skb->protocol = eth_type_trans(skb, dev);
 		dev->stats.rx_packets++;
 		dev->stats.rx_bytes += skb->len;
@@ -679,14 +855,12 @@
 		return NETDEV_TX_OK;
 	}
 	memcpy_swab32(mem, (u32 *)((int)skb->data & ~3), bytes / 4);
-	dev_kfree_skb(skb);
 #endif
 
 	phys = dma_map_single(&dev->dev, mem, bytes, DMA_TO_DEVICE);
 	if (dma_mapping_error(&dev->dev, phys)) {
-#ifdef __ARMEB__
 		dev_kfree_skb(skb);
-#else
+#ifndef __ARMEB__
 		kfree(mem);
 #endif
 		dev->stats.tx_dropped++;
@@ -728,6 +902,13 @@
 #if DEBUG_TX
 	printk(KERN_DEBUG "%s: eth_xmit end\n", dev->name);
 #endif
+
+	ixp_tx_timestamp(port, skb);
+	skb_tx_timestamp(skb);
+
+#ifndef __ARMEB__
+	dev_kfree_skb(skb);
+#endif
 	return NETDEV_TX_OK;
 }
 
@@ -783,6 +964,9 @@
 	if (!netif_running(dev))
 		return -EINVAL;
 
+	if (cpu_is_ixp46x() && cmd == SIOCSHWTSTAMP)
+		return hwtstamp_ioctl(dev, req, cmd);
+
 	return phy_mii_ioctl(port->phydev, req, cmd);
 }
 
@@ -1171,6 +1355,11 @@
 	char phy_id[MII_BUS_ID_SIZE + 3];
 	int err;
 
+	if (ptp_filter_init(ptp_filter, ARRAY_SIZE(ptp_filter))) {
+		pr_err("ixp4xx_eth: bad ptp filter\n");
+		return -EINVAL;
+	}
+
 	if (!(dev = alloc_etherdev(sizeof(struct port))))
 		return -ENOMEM;
 
diff -druN linux-2.6.39-libre/drivers/net/arm/ks8695net.c linux-3.0-rc7-libre/drivers/net/arm/ks8695net.c
--- linux-2.6.39-libre/drivers/net/arm/ks8695net.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/arm/ks8695net.c	2011-07-11 19:51:52.000000000 -0400
@@ -891,15 +891,16 @@
 			cmd->advertising |= ADVERTISED_Pause;
 		cmd->autoneg = AUTONEG_ENABLE;
 
-		cmd->speed = (ctrl & WMC_WSS) ? SPEED_100 : SPEED_10;
+		ethtool_cmd_speed_set(cmd,
+				      (ctrl & WMC_WSS) ? SPEED_100 : SPEED_10);
 		cmd->duplex = (ctrl & WMC_WDS) ?
 			DUPLEX_FULL : DUPLEX_HALF;
 	} else {
 		/* auto-negotiation is disabled */
 		cmd->autoneg = AUTONEG_DISABLE;
 
-		cmd->speed = (ctrl & WMC_WANF100) ?
-			SPEED_100 : SPEED_10;
+		ethtool_cmd_speed_set(cmd, ((ctrl & WMC_WANF100) ?
+					    SPEED_100 : SPEED_10));
 		cmd->duplex = (ctrl & WMC_WANFF) ?
 			DUPLEX_FULL : DUPLEX_HALF;
 	}
diff -druN linux-2.6.39-libre/drivers/net/atarilance.c linux-3.0-rc7-libre/drivers/net/atarilance.c
--- linux-2.6.39-libre/drivers/net/atarilance.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/atarilance.c	2011-07-11 19:51:52.000000000 -0400
@@ -554,7 +554,7 @@
 		memaddr == (unsigned short *)0xffe00000) {
 		/* PAMs card and Riebl on ST use level 5 autovector */
 		if (request_irq(IRQ_AUTO_5, lance_interrupt, IRQ_TYPE_PRIO,
-		            "PAM/Riebl-ST Ethernet", dev)) {
+		            "PAM,Riebl-ST Ethernet", dev)) {
 			printk( "Lance: request for irq %d failed\n", IRQ_AUTO_5 );
 			return 0;
 		}
diff -druN linux-2.6.39-libre/drivers/net/atl1c/atl1c_ethtool.c linux-3.0-rc7-libre/drivers/net/atl1c/atl1c_ethtool.c
--- linux-2.6.39-libre/drivers/net/atl1c/atl1c_ethtool.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/atl1c/atl1c_ethtool.c	2011-07-11 19:51:52.000000000 -0400
@@ -50,13 +50,13 @@
 	ecmd->transceiver = XCVR_INTERNAL;
 
 	if (adapter->link_speed != SPEED_0) {
-		ecmd->speed = adapter->link_speed;
+		ethtool_cmd_speed_set(ecmd, adapter->link_speed);
 		if (adapter->link_duplex == FULL_DUPLEX)
 			ecmd->duplex = DUPLEX_FULL;
 		else
 			ecmd->duplex = DUPLEX_HALF;
 	} else {
-		ecmd->speed = -1;
+		ethtool_cmd_speed_set(ecmd, -1);
 		ecmd->duplex = -1;
 	}
 
@@ -77,7 +77,8 @@
 	if (ecmd->autoneg == AUTONEG_ENABLE) {
 		autoneg_advertised = ADVERTISED_Autoneg;
 	} else {
-		if (ecmd->speed == SPEED_1000) {
+		u32 speed = ethtool_cmd_speed(ecmd);
+		if (speed == SPEED_1000) {
 			if (ecmd->duplex != DUPLEX_FULL) {
 				if (netif_msg_link(adapter))
 					dev_warn(&adapter->pdev->dev,
@@ -86,7 +87,7 @@
 				return -EINVAL;
 			}
 			autoneg_advertised = ADVERTISED_1000baseT_Full;
-		} else if (ecmd->speed == SPEED_100) {
+		} else if (speed == SPEED_100) {
 			if (ecmd->duplex == DUPLEX_FULL)
 				autoneg_advertised = ADVERTISED_100baseT_Full;
 			else
@@ -113,11 +114,6 @@
 	return 0;
 }
 
-static u32 atl1c_get_tx_csum(struct net_device *netdev)
-{
-	return (netdev->features & NETIF_F_HW_CSUM) != 0;
-}
-
 static u32 atl1c_get_msglevel(struct net_device *netdev)
 {
 	struct atl1c_adapter *adapter = netdev_priv(netdev);
@@ -307,9 +303,6 @@
 	.get_link               = ethtool_op_get_link,
 	.get_eeprom_len         = atl1c_get_eeprom_len,
 	.get_eeprom             = atl1c_get_eeprom,
-	.get_tx_csum            = atl1c_get_tx_csum,
-	.get_sg                 = ethtool_op_get_sg,
-	.set_sg                 = ethtool_op_set_sg,
 };
 
 void atl1c_set_ethtool_ops(struct net_device *netdev)
diff -druN linux-2.6.39-libre/drivers/net/atl1c/atl1c_main.c linux-3.0-rc7-libre/drivers/net/atl1c/atl1c_main.c
--- linux-2.6.39-libre/drivers/net/atl1c/atl1c_main.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/atl1c/atl1c_main.c	2011-07-11 19:51:52.000000000 -0400
@@ -480,6 +480,15 @@
 	adapter->rx_buffer_len = mtu > AT_RX_BUF_SIZE ?
 		roundup(mtu + ETH_HLEN + ETH_FCS_LEN + VLAN_HLEN, 8) : AT_RX_BUF_SIZE;
 }
+
+static u32 atl1c_fix_features(struct net_device *netdev, u32 features)
+{
+	if (netdev->mtu > MAX_TSO_FRAME_SIZE)
+		features &= ~(NETIF_F_TSO | NETIF_F_TSO6);
+
+	return features;
+}
+
 /*
  * atl1c_change_mtu - Change the Maximum Transfer Unit
  * @netdev: network interface device structure
@@ -506,14 +515,8 @@
 		netdev->mtu = new_mtu;
 		adapter->hw.max_frame_size = new_mtu;
 		atl1c_set_rxbufsize(adapter, netdev);
-		if (new_mtu > MAX_TSO_FRAME_SIZE) {
-			adapter->netdev->features &= ~NETIF_F_TSO;
-			adapter->netdev->features &= ~NETIF_F_TSO6;
-		} else {
-			adapter->netdev->features |= NETIF_F_TSO;
-			adapter->netdev->features |= NETIF_F_TSO6;
-		}
 		atl1c_down(adapter);
+		netdev_update_features(netdev);
 		atl1c_up(adapter);
 		clear_bit(__AT_RESETTING, &adapter->flags);
 		if (adapter->hw.ctrl_flags & ATL1C_FPGA_VERSION) {
@@ -1088,10 +1091,8 @@
 	u32 max_pay_load;
 	u16 tx_offload_thresh;
 	u32 txq_ctrl_data;
-	u32 extra_size = 0;     /* Jumbo frame threshold in QWORD unit */
 	u32 max_pay_load_data;
 
-	extra_size = ETH_HLEN + VLAN_HLEN + ETH_FCS_LEN;
 	tx_offload_thresh = MAX_TX_OFFLOAD_THRESH;
 	AT_WRITE_REG(hw, REG_TX_TSO_OFFLOAD_THRESH,
 		(tx_offload_thresh >> 3) & TX_TSO_OFFLOAD_THRESH_MASK);
@@ -2536,6 +2537,7 @@
 	return 0;
 }
 
+#ifdef CONFIG_PM_SLEEP
 static int atl1c_resume(struct device *dev)
 {
 	struct pci_dev *pdev = to_pci_dev(dev);
@@ -2562,6 +2564,7 @@
 
 	return 0;
 }
+#endif
 
 static void atl1c_shutdown(struct pci_dev *pdev)
 {
@@ -2581,6 +2584,7 @@
 	.ndo_set_mac_address 	= atl1c_set_mac_addr,
 	.ndo_set_multicast_list = atl1c_set_multi,
 	.ndo_change_mtu		= atl1c_change_mtu,
+	.ndo_fix_features	= atl1c_fix_features,
 	.ndo_do_ioctl		= atl1c_ioctl,
 	.ndo_tx_timeout		= atl1c_tx_timeout,
 	.ndo_get_stats		= atl1c_get_stats,
@@ -2601,12 +2605,13 @@
 	atl1c_set_ethtool_ops(netdev);
 
 	/* TODO: add when ready */
-	netdev->features =	NETIF_F_SG	   |
+	netdev->hw_features =	NETIF_F_SG	   |
 				NETIF_F_HW_CSUM	   |
 				NETIF_F_HW_VLAN_TX |
-				NETIF_F_HW_VLAN_RX |
 				NETIF_F_TSO	   |
 				NETIF_F_TSO6;
+	netdev->features =	netdev->hw_features |
+				NETIF_F_HW_VLAN_RX;
 	return 0;
 }
 
diff -druN linux-2.6.39-libre/drivers/net/atl1e/atl1e_ethtool.c linux-3.0-rc7-libre/drivers/net/atl1e/atl1e_ethtool.c
--- linux-2.6.39-libre/drivers/net/atl1e/atl1e_ethtool.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/atl1e/atl1e_ethtool.c	2011-07-11 19:51:52.000000000 -0400
@@ -51,13 +51,13 @@
 	ecmd->transceiver = XCVR_INTERNAL;
 
 	if (adapter->link_speed != SPEED_0) {
-		ecmd->speed = adapter->link_speed;
+		ethtool_cmd_speed_set(ecmd, adapter->link_speed);
 		if (adapter->link_duplex == FULL_DUPLEX)
 			ecmd->duplex = DUPLEX_FULL;
 		else
 			ecmd->duplex = DUPLEX_HALF;
 	} else {
-		ecmd->speed = -1;
+		ethtool_cmd_speed_set(ecmd, -1);
 		ecmd->duplex = -1;
 	}
 
@@ -382,9 +382,6 @@
 	.get_eeprom_len         = atl1e_get_eeprom_len,
 	.get_eeprom             = atl1e_get_eeprom,
 	.set_eeprom             = atl1e_set_eeprom,
-	.set_tx_csum            = ethtool_op_set_tx_hw_csum,
-	.set_sg                 = ethtool_op_set_sg,
-	.set_tso                = ethtool_op_set_tso,
 };
 
 void atl1e_set_ethtool_ops(struct net_device *netdev)
diff -druN linux-2.6.39-libre/drivers/net/atl1e/atl1e_main.c linux-3.0-rc7-libre/drivers/net/atl1e/atl1e_main.c
--- linux-2.6.39-libre/drivers/net/atl1e/atl1e_main.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/atl1e/atl1e_main.c	2011-07-11 19:51:52.000000000 -0400
@@ -691,10 +691,8 @@
 
 static void atl1e_init_ring_resources(struct atl1e_adapter *adapter)
 {
-	struct atl1e_tx_ring *tx_ring = NULL;
 	struct atl1e_rx_ring *rx_ring = NULL;
 
-	tx_ring = &adapter->tx_ring;
 	rx_ring = &adapter->rx_ring;
 
 	rx_ring->real_page_size = adapter->rx_ring.page_size
@@ -1927,11 +1925,7 @@
 	 * reschedule our watchdog timer */
 	set_bit(__AT_DOWN, &adapter->flags);
 
-#ifdef NETIF_F_LLTX
 	netif_stop_queue(netdev);
-#else
-	netif_tx_disable(netdev);
-#endif
 
 	/* reset MAC to disable all RX/TX */
 	atl1e_reset_hw(&adapter->hw);
@@ -2223,10 +2217,10 @@
 	netdev->watchdog_timeo = AT_TX_WATCHDOG;
 	atl1e_set_ethtool_ops(netdev);
 
-	netdev->features = NETIF_F_SG | NETIF_F_HW_CSUM |
-		NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
-	netdev->features |= NETIF_F_LLTX;
-	netdev->features |= NETIF_F_TSO;
+	netdev->hw_features = NETIF_F_SG | NETIF_F_HW_CSUM | NETIF_F_TSO |
+		NETIF_F_HW_VLAN_TX;
+	netdev->features = netdev->hw_features |
+		NETIF_F_HW_VLAN_RX | NETIF_F_LLTX;
 
 	return 0;
 }
diff -druN linux-2.6.39-libre/drivers/net/atlx/atl1.c linux-3.0-rc7-libre/drivers/net/atlx/atl1.c
--- linux-2.6.39-libre/drivers/net/atlx/atl1.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/atlx/atl1.c	2011-07-11 19:51:52.000000000 -0400
@@ -83,8 +83,9 @@
 #include "atl1.h"
 
 #define ATLX_DRIVER_VERSION "2.1.3"
-MODULE_AUTHOR("Xiong Huang <xiong.huang@atheros.com>, \
-Chris Snook <csnook@redhat.com>, Jay Cliburn <jcliburn@gmail.com>");
+MODULE_AUTHOR("Xiong Huang <xiong.huang@atheros.com>, "
+	      "Chris Snook <csnook@redhat.com>, "
+	      "Jay Cliburn <jcliburn@gmail.com>");
 MODULE_LICENSE("GPL");
 MODULE_VERSION(ATLX_DRIVER_VERSION);
 
@@ -2074,9 +2075,6 @@
 	cmb_tpd_next_to_clean = le16_to_cpu(adapter->cmb.cmb->tpd_cons_idx);
 
 	while (cmb_tpd_next_to_clean != sw_tpd_next_to_clean) {
-		struct tx_packet_desc *tpd;
-
-		tpd = ATL1_TPD_DESC(tpd_ring, sw_tpd_next_to_clean);
 		buffer_info = &tpd_ring->buffer_info[sw_tpd_next_to_clean];
 		if (buffer_info->dma) {
 			pci_unmap_page(adapter->pdev, buffer_info->dma,
@@ -2572,7 +2570,7 @@
 {
 	struct net_device *netdev = adapter->netdev;
 	int err;
-	int irq_flags = IRQF_SAMPLE_RANDOM;
+	int irq_flags = 0;
 
 	/* hardware has been reset, we need to reload some things */
 	atlx_set_multi(netdev);
@@ -2986,6 +2984,11 @@
 	netdev->features |= NETIF_F_SG;
 	netdev->features |= (NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX);
 
+	netdev->hw_features = NETIF_F_HW_CSUM | NETIF_F_SG | NETIF_F_TSO;
+
+	/* is this valid? see atl1_setup_mac_ctrl() */
+	netdev->features |= NETIF_F_RXCSUM;
+
 	/*
 	 * patch for some L1 of old version,
 	 * the final version of L1 may not need these
@@ -3229,13 +3232,13 @@
 	if (netif_carrier_ok(adapter->netdev)) {
 		u16 link_speed, link_duplex;
 		atl1_get_speed_and_duplex(hw, &link_speed, &link_duplex);
-		ecmd->speed = link_speed;
+		ethtool_cmd_speed_set(ecmd, link_speed);
 		if (link_duplex == FULL_DUPLEX)
 			ecmd->duplex = DUPLEX_FULL;
 		else
 			ecmd->duplex = DUPLEX_HALF;
 	} else {
-		ecmd->speed = -1;
+		ethtool_cmd_speed_set(ecmd, -1);
 		ecmd->duplex = -1;
 	}
 	if (hw->media_type == MEDIA_TYPE_AUTO_SENSOR ||
@@ -3266,7 +3269,8 @@
 	if (ecmd->autoneg == AUTONEG_ENABLE)
 		hw->media_type = MEDIA_TYPE_AUTO_SENSOR;
 	else {
-		if (ecmd->speed == SPEED_1000) {
+		u32 speed = ethtool_cmd_speed(ecmd);
+		if (speed == SPEED_1000) {
 			if (ecmd->duplex != DUPLEX_FULL) {
 				if (netif_msg_link(adapter))
 					dev_warn(&adapter->pdev->dev,
@@ -3275,7 +3279,7 @@
 				goto exit_sset;
 			}
 			hw->media_type = MEDIA_TYPE_1000M_FULL;
-		} else if (ecmd->speed == SPEED_100) {
+		} else if (speed == SPEED_100) {
 			if (ecmd->duplex == DUPLEX_FULL)
 				hw->media_type = MEDIA_TYPE_100M_FULL;
 			else
@@ -3595,12 +3599,6 @@
 	return 0;
 }
 
-/* FIXME: is this right? -- CHS */
-static u32 atl1_get_rx_csum(struct net_device *netdev)
-{
-	return 1;
-}
-
 static void atl1_get_strings(struct net_device *netdev, u32 stringset,
 	u8 *data)
 {
@@ -3668,13 +3666,9 @@
 	.set_ringparam		= atl1_set_ringparam,
 	.get_pauseparam		= atl1_get_pauseparam,
 	.set_pauseparam		= atl1_set_pauseparam,
-	.get_rx_csum		= atl1_get_rx_csum,
-	.set_tx_csum		= ethtool_op_set_tx_hw_csum,
 	.get_link		= ethtool_op_get_link,
-	.set_sg			= ethtool_op_set_sg,
 	.get_strings		= atl1_get_strings,
 	.nway_reset		= atl1_nway_reset,
 	.get_ethtool_stats	= atl1_get_ethtool_stats,
 	.get_sset_count		= atl1_get_sset_count,
-	.set_tso		= ethtool_op_set_tso,
 };
diff -druN linux-2.6.39-libre/drivers/net/atlx/atl2.c linux-3.0-rc7-libre/drivers/net/atlx/atl2.c
--- linux-2.6.39-libre/drivers/net/atlx/atl2.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/atlx/atl2.c	2011-07-11 19:51:52.000000000 -0400
@@ -1411,9 +1411,8 @@
 
 	err = -EIO;
 
-#ifdef NETIF_F_HW_VLAN_TX
+	netdev->hw_features = NETIF_F_SG;
 	netdev->features |= (NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX);
-#endif
 
 	/* Init PHY as early as possible due to power saving issue  */
 	atl2_phy_init(&adapter->hw);
@@ -1770,13 +1769,13 @@
 	ecmd->transceiver = XCVR_INTERNAL;
 
 	if (adapter->link_speed != SPEED_0) {
-		ecmd->speed = adapter->link_speed;
+		ethtool_cmd_speed_set(ecmd, adapter->link_speed);
 		if (adapter->link_duplex == FULL_DUPLEX)
 			ecmd->duplex = DUPLEX_FULL;
 		else
 			ecmd->duplex = DUPLEX_HALF;
 	} else {
-		ecmd->speed = -1;
+		ethtool_cmd_speed_set(ecmd, -1);
 		ecmd->duplex = -1;
 	}
 
@@ -1840,11 +1839,6 @@
 	return 0;
 }
 
-static u32 atl2_get_tx_csum(struct net_device *netdev)
-{
-	return (netdev->features & NETIF_F_HW_CSUM) != 0;
-}
-
 static u32 atl2_get_msglevel(struct net_device *netdev)
 {
 	return 0;
@@ -2112,12 +2106,6 @@
 	.get_eeprom_len		= atl2_get_eeprom_len,
 	.get_eeprom		= atl2_get_eeprom,
 	.set_eeprom		= atl2_set_eeprom,
-	.get_tx_csum		= atl2_get_tx_csum,
-	.get_sg			= ethtool_op_get_sg,
-	.set_sg			= ethtool_op_set_sg,
-#ifdef NETIF_F_TSO
-	.get_tso		= ethtool_op_get_tso,
-#endif
 };
 
 static void atl2_set_ethtool_ops(struct net_device *netdev)
diff -druN linux-2.6.39-libre/drivers/net/b44.c linux-3.0-rc7-libre/drivers/net/b44.c
--- linux-2.6.39-libre/drivers/net/b44.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/b44.c	2011-07-11 19:51:52.000000000 -0400
@@ -1807,8 +1807,8 @@
 	if (bp->flags & B44_FLAG_ADV_100FULL)
 		cmd->advertising |= ADVERTISED_100baseT_Full;
 	cmd->advertising |= ADVERTISED_Pause | ADVERTISED_Asym_Pause;
-	cmd->speed = (bp->flags & B44_FLAG_100_BASE_T) ?
-		SPEED_100 : SPEED_10;
+	ethtool_cmd_speed_set(cmd, ((bp->flags & B44_FLAG_100_BASE_T) ?
+				    SPEED_100 : SPEED_10));
 	cmd->duplex = (bp->flags & B44_FLAG_FULL_DUPLEX) ?
 		DUPLEX_FULL : DUPLEX_HALF;
 	cmd->port = 0;
@@ -1820,7 +1820,7 @@
 	if (cmd->autoneg == AUTONEG_ENABLE)
 		cmd->advertising |= ADVERTISED_Autoneg;
 	if (!netif_running(dev)){
-		cmd->speed = 0;
+		ethtool_cmd_speed_set(cmd, 0);
 		cmd->duplex = 0xff;
 	}
 	cmd->maxtxpkt = 0;
@@ -1831,6 +1831,7 @@
 static int b44_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
 {
 	struct b44 *bp = netdev_priv(dev);
+	u32 speed = ethtool_cmd_speed(cmd);
 
 	/* We do not support gigabit. */
 	if (cmd->autoneg == AUTONEG_ENABLE) {
@@ -1838,8 +1839,8 @@
 		    (ADVERTISED_1000baseT_Half |
 		     ADVERTISED_1000baseT_Full))
 			return -EINVAL;
-	} else if ((cmd->speed != SPEED_100 &&
-		    cmd->speed != SPEED_10) ||
+	} else if ((speed != SPEED_100 &&
+		    speed != SPEED_10) ||
 		   (cmd->duplex != DUPLEX_HALF &&
 		    cmd->duplex != DUPLEX_FULL)) {
 			return -EINVAL;
@@ -1873,7 +1874,7 @@
 	} else {
 		bp->flags |= B44_FLAG_FORCE_LINK;
 		bp->flags &= ~(B44_FLAG_100_BASE_T | B44_FLAG_FULL_DUPLEX);
-		if (cmd->speed == SPEED_100)
+		if (speed == SPEED_100)
 			bp->flags |= B44_FLAG_100_BASE_T;
 		if (cmd->duplex == DUPLEX_FULL)
 			bp->flags |= B44_FLAG_FULL_DUPLEX;
diff -druN linux-2.6.39-libre/drivers/net/bcm63xx_enet.c linux-3.0-rc7-libre/drivers/net/bcm63xx_enet.c
--- linux-2.6.39-libre/drivers/net/bcm63xx_enet.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/bcm63xx_enet.c	2011-07-11 19:51:52.000000000 -0400
@@ -839,8 +839,8 @@
 	if (ret)
 		goto out_phy_disconnect;
 
-	ret = request_irq(priv->irq_rx, bcm_enet_isr_dma,
-			  IRQF_SAMPLE_RANDOM | IRQF_DISABLED, dev->name, dev);
+	ret = request_irq(priv->irq_rx, bcm_enet_isr_dma, IRQF_DISABLED,
+			  dev->name, dev);
 	if (ret)
 		goto out_freeirq;
 
@@ -1346,7 +1346,8 @@
 		return phy_ethtool_gset(priv->phydev, cmd);
 	} else {
 		cmd->autoneg = 0;
-		cmd->speed = (priv->force_speed_100) ? SPEED_100 : SPEED_10;
+		ethtool_cmd_speed_set(cmd, ((priv->force_speed_100)
+					    ? SPEED_100 : SPEED_10));
 		cmd->duplex = (priv->force_duplex_full) ?
 			DUPLEX_FULL : DUPLEX_HALF;
 		cmd->supported = ADVERTISED_10baseT_Half  |
diff -druN linux-2.6.39-libre/drivers/net/benet/be_cmds.c linux-3.0-rc7-libre/drivers/net/benet/be_cmds.c
--- linux-2.6.39-libre/drivers/net/benet/be_cmds.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/benet/be_cmds.c	2011-07-11 19:51:52.000000000 -0400
@@ -71,18 +71,38 @@
 	compl_status = (compl->status >> CQE_STATUS_COMPL_SHIFT) &
 				CQE_STATUS_COMPL_MASK;
 
-	if ((compl->tag0 == OPCODE_COMMON_WRITE_FLASHROM) &&
+	if (((compl->tag0 == OPCODE_COMMON_WRITE_FLASHROM) ||
+		(compl->tag0 == OPCODE_COMMON_WRITE_OBJECT)) &&
 		(compl->tag1 == CMD_SUBSYSTEM_COMMON)) {
 		adapter->flash_status = compl_status;
 		complete(&adapter->flash_compl);
 	}
 
 	if (compl_status == MCC_STATUS_SUCCESS) {
-		if (compl->tag0 == OPCODE_ETH_GET_STATISTICS) {
-			struct be_cmd_resp_get_stats *resp =
-						adapter->stats_cmd.va;
-			be_dws_le_to_cpu(&resp->hw_stats,
-						sizeof(resp->hw_stats));
+		if (((compl->tag0 == OPCODE_ETH_GET_STATISTICS) ||
+			 (compl->tag0 == OPCODE_ETH_GET_PPORT_STATS)) &&
+			(compl->tag1 == CMD_SUBSYSTEM_ETH)) {
+			if (adapter->generation == BE_GEN3) {
+				if (lancer_chip(adapter)) {
+					struct lancer_cmd_resp_pport_stats
+						*resp = adapter->stats_cmd.va;
+					be_dws_le_to_cpu(&resp->pport_stats,
+						sizeof(resp->pport_stats));
+				} else {
+					struct be_cmd_resp_get_stats_v1 *resp =
+							adapter->stats_cmd.va;
+
+				be_dws_le_to_cpu(&resp->hw_stats,
+							sizeof(resp->hw_stats));
+				}
+			} else {
+				struct be_cmd_resp_get_stats_v0 *resp =
+							adapter->stats_cmd.va;
+
+				be_dws_le_to_cpu(&resp->hw_stats,
+							sizeof(resp->hw_stats));
+			}
+			be_parse_stats(adapter);
 			netdev_stats_update(adapter);
 			adapter->stats_cmd_sent = false;
 		}
@@ -292,12 +312,12 @@
 
 		if (msecs > 4000) {
 			dev_err(&adapter->pdev->dev, "mbox poll timed out\n");
-			be_detect_dump_ue(adapter);
+			if (!lancer_chip(adapter))
+				be_detect_dump_ue(adapter);
 			return -1;
 		}
 
-		set_current_state(TASK_INTERRUPTIBLE);
-		schedule_timeout(msecs_to_jiffies(1));
+		msleep(1);
 		msecs++;
 	} while (true);
 
@@ -374,23 +394,25 @@
 {
 	u16 stage;
 	int status, timeout = 0;
+	struct device *dev = &adapter->pdev->dev;
 
 	do {
 		status = be_POST_stage_get(adapter, &stage);
 		if (status) {
-			dev_err(&adapter->pdev->dev, "POST error; stage=0x%x\n",
-				stage);
+			dev_err(dev, "POST error; stage=0x%x\n", stage);
 			return -1;
 		} else if (stage != POST_STAGE_ARMFW_RDY) {
-			set_current_state(TASK_INTERRUPTIBLE);
-			schedule_timeout(2 * HZ);
+			if (msleep_interruptible(2000)) {
+				dev_err(dev, "Waiting for POST aborted\n");
+				return -EINTR;
+			}
 			timeout += 2;
 		} else {
 			return 0;
 		}
 	} while (timeout < 40);
 
-	dev_err(&adapter->pdev->dev, "POST timeout; stage=0x%x\n", stage);
+	dev_err(dev, "POST timeout; stage=0x%x\n", stage);
 	return -1;
 }
 
@@ -728,8 +750,6 @@
 	if (lancer_chip(adapter)) {
 		req->hdr.version = 2;
 		req->page_size = 1; /* 1 for 4K */
-		AMAP_SET_BITS(struct amap_cq_context_lancer, coalescwm, ctxt,
-								coalesce_wm);
 		AMAP_SET_BITS(struct amap_cq_context_lancer, nodelay, ctxt,
 								no_delay);
 		AMAP_SET_BITS(struct amap_cq_context_lancer, count, ctxt,
@@ -1074,7 +1094,7 @@
 int be_cmd_get_stats(struct be_adapter *adapter, struct be_dma_mem *nonemb_cmd)
 {
 	struct be_mcc_wrb *wrb;
-	struct be_cmd_req_get_stats *req;
+	struct be_cmd_req_hdr *hdr;
 	struct be_sge *sge;
 	int status = 0;
 
@@ -1088,14 +1108,62 @@
 		status = -EBUSY;
 		goto err;
 	}
-	req = nonemb_cmd->va;
+	hdr = nonemb_cmd->va;
 	sge = nonembedded_sgl(wrb);
 
-	be_wrb_hdr_prepare(wrb, sizeof(*req), false, 1,
+	be_wrb_hdr_prepare(wrb, nonemb_cmd->size, false, 1,
 			OPCODE_ETH_GET_STATISTICS);
 
+	be_cmd_hdr_prepare(hdr, CMD_SUBSYSTEM_ETH,
+		OPCODE_ETH_GET_STATISTICS, nonemb_cmd->size);
+
+	if (adapter->generation == BE_GEN3)
+		hdr->version = 1;
+
+	wrb->tag1 = CMD_SUBSYSTEM_ETH;
+	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);
+
+	be_mcc_notify(adapter);
+	adapter->stats_cmd_sent = true;
+
+err:
+	spin_unlock_bh(&adapter->mcc_lock);
+	return status;
+}
+
+/* Lancer Stats */
+int lancer_cmd_get_pport_stats(struct be_adapter *adapter,
+				struct be_dma_mem *nonemb_cmd)
+{
+
+	struct be_mcc_wrb *wrb;
+	struct lancer_cmd_req_pport_stats *req;
+	struct be_sge *sge;
+	int status = 0;
+
+	spin_lock_bh(&adapter->mcc_lock);
+
+	wrb = wrb_from_mccq(adapter);
+	if (!wrb) {
+		status = -EBUSY;
+		goto err;
+	}
+	req = nonemb_cmd->va;
+	sge = nonembedded_sgl(wrb);
+
+	be_wrb_hdr_prepare(wrb, nonemb_cmd->size, false, 1,
+			OPCODE_ETH_GET_PPORT_STATS);
+
 	be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ETH,
-		OPCODE_ETH_GET_STATISTICS, sizeof(*req));
+			OPCODE_ETH_GET_PPORT_STATS, nonemb_cmd->size);
+
+
+	req->cmd_params.params.pport_num = cpu_to_le16(adapter->port_num);
+	req->cmd_params.params.reset_stats = 0;
+
+	wrb->tag1 = CMD_SUBSYSTEM_ETH;
 	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);
@@ -1110,7 +1178,7 @@
 
 /* Uses synchronous mcc */
 int be_cmd_link_status_query(struct be_adapter *adapter,
-			bool *link_up, u8 *mac_speed, u16 *link_speed)
+			bool *link_up, u8 *mac_speed, u16 *link_speed, u32 dom)
 {
 	struct be_mcc_wrb *wrb;
 	struct be_cmd_req_link_status *req;
@@ -1186,6 +1254,116 @@
 	return status;
 }
 
+/* Uses synchronous mcc */
+int be_cmd_get_reg_len(struct be_adapter *adapter, u32 *log_size)
+{
+	struct be_mcc_wrb *wrb;
+	struct be_cmd_req_get_fat *req;
+	int status;
+
+	spin_lock_bh(&adapter->mcc_lock);
+
+	wrb = wrb_from_mccq(adapter);
+	if (!wrb) {
+		status = -EBUSY;
+		goto err;
+	}
+	req = embedded_payload(wrb);
+
+	be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0,
+			OPCODE_COMMON_MANAGE_FAT);
+
+	be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
+		OPCODE_COMMON_MANAGE_FAT, sizeof(*req));
+	req->fat_operation = cpu_to_le32(QUERY_FAT);
+	status = be_mcc_notify_wait(adapter);
+	if (!status) {
+		struct be_cmd_resp_get_fat *resp = embedded_payload(wrb);
+		if (log_size && resp->log_size)
+			*log_size = le32_to_cpu(resp->log_size) -
+					sizeof(u32);
+	}
+err:
+	spin_unlock_bh(&adapter->mcc_lock);
+	return status;
+}
+
+void be_cmd_get_regs(struct be_adapter *adapter, u32 buf_len, void *buf)
+{
+	struct be_dma_mem get_fat_cmd;
+	struct be_mcc_wrb *wrb;
+	struct be_cmd_req_get_fat *req;
+	struct be_sge *sge;
+	u32 offset = 0, total_size, buf_size,
+				log_offset = sizeof(u32), payload_len;
+	int status;
+
+	if (buf_len == 0)
+		return;
+
+	total_size = buf_len;
+
+	get_fat_cmd.size = sizeof(struct be_cmd_req_get_fat) + 60*1024;
+	get_fat_cmd.va = pci_alloc_consistent(adapter->pdev,
+			get_fat_cmd.size,
+			&get_fat_cmd.dma);
+	if (!get_fat_cmd.va) {
+		status = -ENOMEM;
+		dev_err(&adapter->pdev->dev,
+		"Memory allocation failure while retrieving FAT data\n");
+		return;
+	}
+
+	spin_lock_bh(&adapter->mcc_lock);
+
+	while (total_size) {
+		buf_size = min(total_size, (u32)60*1024);
+		total_size -= buf_size;
+
+		wrb = wrb_from_mccq(adapter);
+		if (!wrb) {
+			status = -EBUSY;
+			goto err;
+		}
+		req = get_fat_cmd.va;
+		sge = nonembedded_sgl(wrb);
+
+		payload_len = sizeof(struct be_cmd_req_get_fat) + buf_size;
+		be_wrb_hdr_prepare(wrb, payload_len, false, 1,
+				OPCODE_COMMON_MANAGE_FAT);
+
+		be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
+				OPCODE_COMMON_MANAGE_FAT, payload_len);
+
+		sge->pa_hi = cpu_to_le32(upper_32_bits(get_fat_cmd.dma));
+		sge->pa_lo = cpu_to_le32(get_fat_cmd.dma & 0xFFFFFFFF);
+		sge->len = cpu_to_le32(get_fat_cmd.size);
+
+		req->fat_operation = cpu_to_le32(RETRIEVE_FAT);
+		req->read_log_offset = cpu_to_le32(log_offset);
+		req->read_log_length = cpu_to_le32(buf_size);
+		req->data_buffer_size = cpu_to_le32(buf_size);
+
+		status = be_mcc_notify_wait(adapter);
+		if (!status) {
+			struct be_cmd_resp_get_fat *resp = get_fat_cmd.va;
+			memcpy(buf + offset,
+				resp->data_buffer,
+				resp->read_log_length);
+		} else {
+			dev_err(&adapter->pdev->dev, "FAT Table Retrieve error\n");
+			goto err;
+		}
+		offset += buf_size;
+		log_offset += buf_size;
+	}
+err:
+	pci_free_consistent(adapter->pdev, get_fat_cmd.size,
+			get_fat_cmd.va,
+			get_fat_cmd.dma);
+	spin_unlock_bh(&adapter->mcc_lock);
+}
+
 /* Uses Mbox */
 int be_cmd_get_fw_ver(struct be_adapter *adapter, char *fw_ver)
 {
@@ -1293,12 +1471,24 @@
 /* Uses MCC for this command as it may be called in BH context
  * Uses synchronous mcc
  */
-int be_cmd_promiscuous_config(struct be_adapter *adapter, u8 port_num, bool en)
+int be_cmd_promiscuous_config(struct be_adapter *adapter, bool en)
 {
 	struct be_mcc_wrb *wrb;
-	struct be_cmd_req_promiscuous_config *req;
+	struct be_cmd_req_rx_filter *req;
+	struct be_dma_mem promiscous_cmd;
+	struct be_sge *sge;
 	int status;
 
+	memset(&promiscous_cmd, 0, sizeof(struct be_dma_mem));
+	promiscous_cmd.size = sizeof(struct be_cmd_req_rx_filter);
+	promiscous_cmd.va = pci_alloc_consistent(adapter->pdev,
+				promiscous_cmd.size, &promiscous_cmd.dma);
+	if (!promiscous_cmd.va) {
+		dev_err(&adapter->pdev->dev,
+				"Memory allocation failure\n");
+		return -ENOMEM;
+	}
+
 	spin_lock_bh(&adapter->mcc_lock);
 
 	wrb = wrb_from_mccq(adapter);
@@ -1306,26 +1496,30 @@
 		status = -EBUSY;
 		goto err;
 	}
-	req = embedded_payload(wrb);
 
-	be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0, OPCODE_ETH_PROMISCUOUS);
+	req = promiscous_cmd.va;
+	sge = nonembedded_sgl(wrb);
 
-	be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ETH,
-		OPCODE_ETH_PROMISCUOUS, sizeof(*req));
+	be_wrb_hdr_prepare(wrb, sizeof(*req), false, 1,
+					OPCODE_COMMON_NTWK_RX_FILTER);
+	be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
+			OPCODE_COMMON_NTWK_RX_FILTER, sizeof(*req));
 
-	/* In FW versions X.102.149/X.101.487 and later,
-	 * the port setting associated only with the
-	 * issuing pci function will take effect
-	 */
-	if (port_num)
-		req->port1_promiscuous = en;
-	else
-		req->port0_promiscuous = en;
+	req->if_id = cpu_to_le32(adapter->if_handle);
+	req->if_flags_mask = cpu_to_le32(BE_IF_FLAGS_PROMISCUOUS);
+	if (en)
+		req->if_flags = cpu_to_le32(BE_IF_FLAGS_PROMISCUOUS);
+
+	sge->pa_hi = cpu_to_le32(upper_32_bits(promiscous_cmd.dma));
+	sge->pa_lo = cpu_to_le32(promiscous_cmd.dma & 0xFFFFFFFF);
+	sge->len = cpu_to_le32(promiscous_cmd.size);
 
 	status = be_mcc_notify_wait(adapter);
 
 err:
 	spin_unlock_bh(&adapter->mcc_lock);
+	pci_free_consistent(adapter->pdev, promiscous_cmd.size,
+			promiscous_cmd.va, promiscous_cmd.dma);
 	return status;
 }
 
@@ -1509,7 +1703,8 @@
 {
 	struct be_mcc_wrb *wrb;
 	struct be_cmd_req_rss_config *req;
-	u32 myhash[10];
+	u32 myhash[10] = {0x0123, 0x4567, 0x89AB, 0xCDEF, 0x01EF,
+			0x0123, 0x4567, 0x89AB, 0xCDEF, 0x01EF};
 	int status;
 
 	if (mutex_lock_interruptible(&adapter->mbox_lock))
@@ -1608,6 +1803,81 @@
 	return status;
 }
 
+int lancer_cmd_write_object(struct be_adapter *adapter, struct be_dma_mem *cmd,
+			u32 data_size, u32 data_offset, const char *obj_name,
+			u32 *data_written, u8 *addn_status)
+{
+	struct be_mcc_wrb *wrb;
+	struct lancer_cmd_req_write_object *req;
+	struct lancer_cmd_resp_write_object *resp;
+	void *ctxt = NULL;
+	int status;
+
+	spin_lock_bh(&adapter->mcc_lock);
+	adapter->flash_status = 0;
+
+	wrb = wrb_from_mccq(adapter);
+	if (!wrb) {
+		status = -EBUSY;
+		goto err_unlock;
+	}
+
+	req = embedded_payload(wrb);
+
+	be_wrb_hdr_prepare(wrb, sizeof(struct lancer_cmd_req_write_object),
+			true, 1, OPCODE_COMMON_WRITE_OBJECT);
+	wrb->tag1 = CMD_SUBSYSTEM_COMMON;
+
+	be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
+				OPCODE_COMMON_WRITE_OBJECT,
+				sizeof(struct lancer_cmd_req_write_object));
+
+	ctxt = &req->context;
+	AMAP_SET_BITS(struct amap_lancer_write_obj_context,
+			write_length, ctxt, data_size);
+
+	if (data_size == 0)
+		AMAP_SET_BITS(struct amap_lancer_write_obj_context,
+				eof, ctxt, 1);
+	else
+		AMAP_SET_BITS(struct amap_lancer_write_obj_context,
+				eof, ctxt, 0);
+
+	be_dws_cpu_to_le(ctxt, sizeof(req->context));
+	req->write_offset = cpu_to_le32(data_offset);
+	strcpy(req->object_name, obj_name);
+	req->descriptor_count = cpu_to_le32(1);
+	req->buf_len = cpu_to_le32(data_size);
+	req->addr_low = cpu_to_le32((cmd->dma +
+				sizeof(struct lancer_cmd_req_write_object))
+				& 0xFFFFFFFF);
+	req->addr_high = cpu_to_le32(upper_32_bits(cmd->dma +
+				sizeof(struct lancer_cmd_req_write_object)));
+
+	be_mcc_notify(adapter);
+	spin_unlock_bh(&adapter->mcc_lock);
+
+	if (!wait_for_completion_timeout(&adapter->flash_compl,
+			msecs_to_jiffies(12000)))
+		status = -1;
+	else
+		status = adapter->flash_status;
+
+	resp = embedded_payload(wrb);
+	if (!status) {
+		*data_written = le32_to_cpu(resp->actual_write_len);
+	} else {
+		*addn_status = resp->additional_status;
+		status = resp->status;
+	}
+
+	return status;
+
+err_unlock:
+	spin_unlock_bh(&adapter->mcc_lock);
+	return status;
+}
+
 int be_cmd_write_flashrom(struct be_adapter *adapter, struct be_dma_mem *cmd,
 			u32 flash_type, u32 flash_opcode, u32 buf_size)
 {
diff -druN linux-2.6.39-libre/drivers/net/benet/be_cmds.h linux-3.0-rc7-libre/drivers/net/benet/be_cmds.h
--- linux-2.6.39-libre/drivers/net/benet/be_cmds.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/benet/be_cmds.h	2011-07-11 19:51:52.000000000 -0400
@@ -186,12 +186,14 @@
 #define OPCODE_COMMON_NTWK_PMAC_ADD			59
 #define OPCODE_COMMON_NTWK_PMAC_DEL			60
 #define OPCODE_COMMON_FUNCTION_RESET			61
+#define OPCODE_COMMON_MANAGE_FAT			68
 #define OPCODE_COMMON_ENABLE_DISABLE_BEACON		69
 #define OPCODE_COMMON_GET_BEACON_STATE			70
 #define OPCODE_COMMON_READ_TRANSRECV_DATA		73
 #define OPCODE_COMMON_GET_PHY_DETAILS			102
 #define OPCODE_COMMON_SET_DRIVER_FUNCTION_CAP		103
 #define OPCODE_COMMON_GET_CNTL_ADDITIONAL_ATTRIBUTES	121
+#define OPCODE_COMMON_WRITE_OBJECT			172
 
 #define OPCODE_ETH_RSS_CONFIG				1
 #define OPCODE_ETH_ACPI_CONFIG				2
@@ -202,6 +204,7 @@
 #define OPCODE_ETH_TX_DESTROY           		9
 #define OPCODE_ETH_RX_DESTROY           		10
 #define OPCODE_ETH_ACPI_WOL_MAGIC_CONFIG		12
+#define OPCODE_ETH_GET_PPORT_STATS			18
 
 #define OPCODE_LOWLEVEL_HOST_DDR_DMA                    17
 #define OPCODE_LOWLEVEL_LOOPBACK_TEST                   18
@@ -380,6 +383,24 @@
 	u16 rsvd0;
 } __packed;
 
+struct be_cmd_req_get_fat {
+	struct be_cmd_req_hdr hdr;
+	u32 fat_operation;
+	u32 read_log_offset;
+	u32 read_log_length;
+	u32 data_buffer_size;
+	u32 data_buffer[1];
+} __packed;
+
+struct be_cmd_resp_get_fat {
+	struct be_cmd_resp_hdr hdr;
+	u32 log_size;
+	u32 read_log_length;
+	u32 rsvd[2];
+	u32 data_buffer[1];
+} __packed;
+
+
 /******************** Create MCCQ ***************************/
 /* Pseudo amap definition in which each bit of the actual structure is defined
  * as a byte: used to calculate offset/shift/mask of each field */
@@ -549,7 +570,7 @@
 };
 
 /*************** HW Stats Get **********************************/
-struct be_port_rxf_stats {
+struct be_port_rxf_stats_v0 {
 	u32 rx_bytes_lsd;	/* dword 0*/
 	u32 rx_bytes_msd;	/* dword 1*/
 	u32 rx_total_frames;	/* dword 2*/
@@ -618,8 +639,8 @@
 	u32 rx_input_fifo_overflow;	/* dword 65*/
 };
 
-struct be_rxf_stats {
-	struct be_port_rxf_stats port[2];
+struct be_rxf_stats_v0 {
+	struct be_port_rxf_stats_v0 port[2];
 	u32 rx_drops_no_pbuf;	/* dword 132*/
 	u32 rx_drops_no_txpb;	/* dword 133*/
 	u32 rx_drops_no_erx_descr;	/* dword 134*/
@@ -642,36 +663,227 @@
 	u32 rsvd1[6];
 };
 
-struct be_erx_stats {
+struct be_erx_stats_v0 {
 	u32 rx_drops_no_fragments[44];     /* dwordS 0 to 43*/
-	u32 debug_wdma_sent_hold;          /* dword 44*/
-	u32 debug_wdma_pbfree_sent_hold;   /* dword 45*/
-	u32 debug_wdma_zerobyte_pbfree_sent_hold; /* dword 46*/
-	u32 debug_pmem_pbuf_dealloc;       /* dword 47*/
+	u32 rsvd[4];
 };
 
 struct be_pmem_stats {
 	u32 eth_red_drops;
-	u32 rsvd[4];
+	u32 rsvd[5];
 };
 
-struct be_hw_stats {
-	struct be_rxf_stats rxf;
+struct be_hw_stats_v0 {
+	struct be_rxf_stats_v0 rxf;
 	u32 rsvd[48];
-	struct be_erx_stats erx;
+	struct be_erx_stats_v0 erx;
 	struct be_pmem_stats pmem;
 };
 
-struct be_cmd_req_get_stats {
+struct be_cmd_req_get_stats_v0 {
 	struct be_cmd_req_hdr hdr;
-	u8 rsvd[sizeof(struct be_hw_stats)];
+	u8 rsvd[sizeof(struct be_hw_stats_v0)];
 };
 
-struct be_cmd_resp_get_stats {
+struct be_cmd_resp_get_stats_v0 {
 	struct be_cmd_resp_hdr hdr;
-	struct be_hw_stats hw_stats;
+	struct be_hw_stats_v0 hw_stats;
 };
 
+#define make_64bit_val(hi_32, lo_32)	(((u64)hi_32<<32) | lo_32)
+struct lancer_cmd_pport_stats {
+	u32 tx_packets_lo;
+	u32 tx_packets_hi;
+	u32 tx_unicast_packets_lo;
+	u32 tx_unicast_packets_hi;
+	u32 tx_multicast_packets_lo;
+	u32 tx_multicast_packets_hi;
+	u32 tx_broadcast_packets_lo;
+	u32 tx_broadcast_packets_hi;
+	u32 tx_bytes_lo;
+	u32 tx_bytes_hi;
+	u32 tx_unicast_bytes_lo;
+	u32 tx_unicast_bytes_hi;
+	u32 tx_multicast_bytes_lo;
+	u32 tx_multicast_bytes_hi;
+	u32 tx_broadcast_bytes_lo;
+	u32 tx_broadcast_bytes_hi;
+	u32 tx_discards_lo;
+	u32 tx_discards_hi;
+	u32 tx_errors_lo;
+	u32 tx_errors_hi;
+	u32 tx_pause_frames_lo;
+	u32 tx_pause_frames_hi;
+	u32 tx_pause_on_frames_lo;
+	u32 tx_pause_on_frames_hi;
+	u32 tx_pause_off_frames_lo;
+	u32 tx_pause_off_frames_hi;
+	u32 tx_internal_mac_errors_lo;
+	u32 tx_internal_mac_errors_hi;
+	u32 tx_control_frames_lo;
+	u32 tx_control_frames_hi;
+	u32 tx_packets_64_bytes_lo;
+	u32 tx_packets_64_bytes_hi;
+	u32 tx_packets_65_to_127_bytes_lo;
+	u32 tx_packets_65_to_127_bytes_hi;
+	u32 tx_packets_128_to_255_bytes_lo;
+	u32 tx_packets_128_to_255_bytes_hi;
+	u32 tx_packets_256_to_511_bytes_lo;
+	u32 tx_packets_256_to_511_bytes_hi;
+	u32 tx_packets_512_to_1023_bytes_lo;
+	u32 tx_packets_512_to_1023_bytes_hi;
+	u32 tx_packets_1024_to_1518_bytes_lo;
+	u32 tx_packets_1024_to_1518_bytes_hi;
+	u32 tx_packets_1519_to_2047_bytes_lo;
+	u32 tx_packets_1519_to_2047_bytes_hi;
+	u32 tx_packets_2048_to_4095_bytes_lo;
+	u32 tx_packets_2048_to_4095_bytes_hi;
+	u32 tx_packets_4096_to_8191_bytes_lo;
+	u32 tx_packets_4096_to_8191_bytes_hi;
+	u32 tx_packets_8192_to_9216_bytes_lo;
+	u32 tx_packets_8192_to_9216_bytes_hi;
+	u32 tx_lso_packets_lo;
+	u32 tx_lso_packets_hi;
+	u32 rx_packets_lo;
+	u32 rx_packets_hi;
+	u32 rx_unicast_packets_lo;
+	u32 rx_unicast_packets_hi;
+	u32 rx_multicast_packets_lo;
+	u32 rx_multicast_packets_hi;
+	u32 rx_broadcast_packets_lo;
+	u32 rx_broadcast_packets_hi;
+	u32 rx_bytes_lo;
+	u32 rx_bytes_hi;
+	u32 rx_unicast_bytes_lo;
+	u32 rx_unicast_bytes_hi;
+	u32 rx_multicast_bytes_lo;
+	u32 rx_multicast_bytes_hi;
+	u32 rx_broadcast_bytes_lo;
+	u32 rx_broadcast_bytes_hi;
+	u32 rx_unknown_protos;
+	u32 rsvd_69; /* Word 69 is reserved */
+	u32 rx_discards_lo;
+	u32 rx_discards_hi;
+	u32 rx_errors_lo;
+	u32 rx_errors_hi;
+	u32 rx_crc_errors_lo;
+	u32 rx_crc_errors_hi;
+	u32 rx_alignment_errors_lo;
+	u32 rx_alignment_errors_hi;
+	u32 rx_symbol_errors_lo;
+	u32 rx_symbol_errors_hi;
+	u32 rx_pause_frames_lo;
+	u32 rx_pause_frames_hi;
+	u32 rx_pause_on_frames_lo;
+	u32 rx_pause_on_frames_hi;
+	u32 rx_pause_off_frames_lo;
+	u32 rx_pause_off_frames_hi;
+	u32 rx_frames_too_long_lo;
+	u32 rx_frames_too_long_hi;
+	u32 rx_internal_mac_errors_lo;
+	u32 rx_internal_mac_errors_hi;
+	u32 rx_undersize_packets;
+	u32 rx_oversize_packets;
+	u32 rx_fragment_packets;
+	u32 rx_jabbers;
+	u32 rx_control_frames_lo;
+	u32 rx_control_frames_hi;
+	u32 rx_control_frames_unknown_opcode_lo;
+	u32 rx_control_frames_unknown_opcode_hi;
+	u32 rx_in_range_errors;
+	u32 rx_out_of_range_errors;
+	u32 rx_address_match_errors;
+	u32 rx_vlan_mismatch_errors;
+	u32 rx_dropped_too_small;
+	u32 rx_dropped_too_short;
+	u32 rx_dropped_header_too_small;
+	u32 rx_dropped_invalid_tcp_length;
+	u32 rx_dropped_runt;
+	u32 rx_ip_checksum_errors;
+	u32 rx_tcp_checksum_errors;
+	u32 rx_udp_checksum_errors;
+	u32 rx_non_rss_packets;
+	u32 rsvd_111;
+	u32 rx_ipv4_packets_lo;
+	u32 rx_ipv4_packets_hi;
+	u32 rx_ipv6_packets_lo;
+	u32 rx_ipv6_packets_hi;
+	u32 rx_ipv4_bytes_lo;
+	u32 rx_ipv4_bytes_hi;
+	u32 rx_ipv6_bytes_lo;
+	u32 rx_ipv6_bytes_hi;
+	u32 rx_nic_packets_lo;
+	u32 rx_nic_packets_hi;
+	u32 rx_tcp_packets_lo;
+	u32 rx_tcp_packets_hi;
+	u32 rx_iscsi_packets_lo;
+	u32 rx_iscsi_packets_hi;
+	u32 rx_management_packets_lo;
+	u32 rx_management_packets_hi;
+	u32 rx_switched_unicast_packets_lo;
+	u32 rx_switched_unicast_packets_hi;
+	u32 rx_switched_multicast_packets_lo;
+	u32 rx_switched_multicast_packets_hi;
+	u32 rx_switched_broadcast_packets_lo;
+	u32 rx_switched_broadcast_packets_hi;
+	u32 num_forwards_lo;
+	u32 num_forwards_hi;
+	u32 rx_fifo_overflow;
+	u32 rx_input_fifo_overflow;
+	u32 rx_drops_too_many_frags_lo;
+	u32 rx_drops_too_many_frags_hi;
+	u32 rx_drops_invalid_queue;
+	u32 rsvd_141;
+	u32 rx_drops_mtu_lo;
+	u32 rx_drops_mtu_hi;
+	u32 rx_packets_64_bytes_lo;
+	u32 rx_packets_64_bytes_hi;
+	u32 rx_packets_65_to_127_bytes_lo;
+	u32 rx_packets_65_to_127_bytes_hi;
+	u32 rx_packets_128_to_255_bytes_lo;
+	u32 rx_packets_128_to_255_bytes_hi;
+	u32 rx_packets_256_to_511_bytes_lo;
+	u32 rx_packets_256_to_511_bytes_hi;
+	u32 rx_packets_512_to_1023_bytes_lo;
+	u32 rx_packets_512_to_1023_bytes_hi;
+	u32 rx_packets_1024_to_1518_bytes_lo;
+	u32 rx_packets_1024_to_1518_bytes_hi;
+	u32 rx_packets_1519_to_2047_bytes_lo;
+	u32 rx_packets_1519_to_2047_bytes_hi;
+	u32 rx_packets_2048_to_4095_bytes_lo;
+	u32 rx_packets_2048_to_4095_bytes_hi;
+	u32 rx_packets_4096_to_8191_bytes_lo;
+	u32 rx_packets_4096_to_8191_bytes_hi;
+	u32 rx_packets_8192_to_9216_bytes_lo;
+	u32 rx_packets_8192_to_9216_bytes_hi;
+};
+
+struct pport_stats_params {
+	u16 pport_num;
+	u8 rsvd;
+	u8 reset_stats;
+};
+
+struct lancer_cmd_req_pport_stats {
+	struct be_cmd_req_hdr hdr;
+	union {
+		struct pport_stats_params params;
+		u8 rsvd[sizeof(struct lancer_cmd_pport_stats)];
+	} cmd_params;
+};
+
+struct lancer_cmd_resp_pport_stats {
+	struct be_cmd_resp_hdr hdr;
+	struct lancer_cmd_pport_stats pport_stats;
+};
+
+static inline  struct lancer_cmd_pport_stats*
+	pport_stats_from_cmd(struct be_adapter *adapter)
+{
+	struct lancer_cmd_resp_pport_stats *cmd = adapter->stats_cmd.va;
+	return &cmd->pport_stats;
+}
+
 struct be_cmd_req_get_cntl_addnl_attribs {
 	struct be_cmd_req_hdr hdr;
 	u8 rsvd[8];
@@ -695,13 +907,6 @@
 	u16 normal_vlan[64];
 } __packed;
 
-struct be_cmd_req_promiscuous_config {
-	struct be_cmd_req_hdr hdr;
-	u8 port0_promiscuous;
-	u8 port1_promiscuous;
-	u16 rsvd0;
-} __packed;
-
 /******************** Multicast MAC Config *******************/
 #define BE_MAX_MC		64 /* set mcast promisc if > 64 */
 struct macaddr {
@@ -716,11 +921,18 @@
 	struct macaddr mac[BE_MAX_MC];
 } __packed;
 
-static inline struct be_hw_stats *
-hw_stats_from_cmd(struct be_cmd_resp_get_stats *cmd)
-{
-	return &cmd->hw_stats;
-}
+/******************* RX FILTER ******************************/
+struct be_cmd_req_rx_filter {
+	struct be_cmd_req_hdr hdr;
+	u32 global_flags_mask;
+	u32 global_flags;
+	u32 if_flags_mask;
+	u32 if_flags;
+	u32 if_id;
+	u32 multicast_num;
+	struct macaddr mac[BE_MAX_MC];
+};
+
 
 /******************** Link Status Query *******************/
 struct be_cmd_req_link_status {
@@ -920,6 +1132,36 @@
 	struct flashrom_params params;
 };
 
+/**************** Lancer Firmware Flash ************/
+struct amap_lancer_write_obj_context {
+	u8 write_length[24];
+	u8 reserved1[7];
+	u8 eof;
+} __packed;
+
+struct lancer_cmd_req_write_object {
+	struct be_cmd_req_hdr hdr;
+	u8 context[sizeof(struct amap_lancer_write_obj_context) / 8];
+	u32 write_offset;
+	u8 object_name[104];
+	u32 descriptor_count;
+	u32 buf_len;
+	u32 addr_low;
+	u32 addr_high;
+};
+
+struct lancer_cmd_resp_write_object {
+	u8 opcode;
+	u8 subsystem;
+	u8 rsvd1[2];
+	u8 status;
+	u8 additional_status;
+	u8 rsvd2[2];
+	u32 resp_len;
+	u32 actual_resp_len;
+	u32 actual_write_len;
+};
+
 /************************ WOL *******************************/
 struct be_cmd_req_acpi_wol_magic_config{
 	struct be_cmd_req_hdr hdr;
@@ -1061,6 +1303,151 @@
 	u8 rsvd[212];
 };
 
+/*************** HW Stats Get v1 **********************************/
+#define BE_TXP_SW_SZ			48
+struct be_port_rxf_stats_v1 {
+	u32 rsvd0[12];
+	u32 rx_crc_errors;
+	u32 rx_alignment_symbol_errors;
+	u32 rx_pause_frames;
+	u32 rx_priority_pause_frames;
+	u32 rx_control_frames;
+	u32 rx_in_range_errors;
+	u32 rx_out_range_errors;
+	u32 rx_frame_too_long;
+	u32 rx_address_match_errors;
+	u32 rx_dropped_too_small;
+	u32 rx_dropped_too_short;
+	u32 rx_dropped_header_too_small;
+	u32 rx_dropped_tcp_length;
+	u32 rx_dropped_runt;
+	u32 rsvd1[10];
+	u32 rx_ip_checksum_errs;
+	u32 rx_tcp_checksum_errs;
+	u32 rx_udp_checksum_errs;
+	u32 rsvd2[7];
+	u32 rx_switched_unicast_packets;
+	u32 rx_switched_multicast_packets;
+	u32 rx_switched_broadcast_packets;
+	u32 rsvd3[3];
+	u32 tx_pauseframes;
+	u32 tx_priority_pauseframes;
+	u32 tx_controlframes;
+	u32 rsvd4[10];
+	u32 rxpp_fifo_overflow_drop;
+	u32 rx_input_fifo_overflow_drop;
+	u32 pmem_fifo_overflow_drop;
+	u32 jabber_events;
+	u32 rsvd5[3];
+};
+
+
+struct be_rxf_stats_v1 {
+	struct be_port_rxf_stats_v1 port[4];
+	u32 rsvd0[2];
+	u32 rx_drops_no_pbuf;
+	u32 rx_drops_no_txpb;
+	u32 rx_drops_no_erx_descr;
+	u32 rx_drops_no_tpre_descr;
+	u32 rsvd1[6];
+	u32 rx_drops_too_many_frags;
+	u32 rx_drops_invalid_ring;
+	u32 forwarded_packets;
+	u32 rx_drops_mtu;
+	u32 rsvd2[14];
+};
+
+struct be_erx_stats_v1 {
+	u32 rx_drops_no_fragments[68];     /* dwordS 0 to 67*/
+	u32 rsvd[4];
+};
+
+struct be_hw_stats_v1 {
+	struct be_rxf_stats_v1 rxf;
+	u32 rsvd0[BE_TXP_SW_SZ];
+	struct be_erx_stats_v1 erx;
+	struct be_pmem_stats pmem;
+	u32 rsvd1[3];
+};
+
+struct be_cmd_req_get_stats_v1 {
+	struct be_cmd_req_hdr hdr;
+	u8 rsvd[sizeof(struct be_hw_stats_v1)];
+};
+
+struct be_cmd_resp_get_stats_v1 {
+	struct be_cmd_resp_hdr hdr;
+	struct be_hw_stats_v1 hw_stats;
+};
+
+static inline void *
+hw_stats_from_cmd(struct be_adapter *adapter)
+{
+	if (adapter->generation == BE_GEN3) {
+		struct be_cmd_resp_get_stats_v1 *cmd = adapter->stats_cmd.va;
+
+		return &cmd->hw_stats;
+	} else {
+		struct be_cmd_resp_get_stats_v0 *cmd = adapter->stats_cmd.va;
+
+		return &cmd->hw_stats;
+	}
+}
+
+static inline void *be_port_rxf_stats_from_cmd(struct be_adapter *adapter)
+{
+	if (adapter->generation == BE_GEN3) {
+		struct be_hw_stats_v1 *hw_stats = hw_stats_from_cmd(adapter);
+		struct be_rxf_stats_v1 *rxf_stats = &hw_stats->rxf;
+
+		return &rxf_stats->port[adapter->port_num];
+	} else {
+		struct be_hw_stats_v0 *hw_stats = hw_stats_from_cmd(adapter);
+		struct be_rxf_stats_v0 *rxf_stats = &hw_stats->rxf;
+
+		return &rxf_stats->port[adapter->port_num];
+	}
+}
+
+static inline void *be_rxf_stats_from_cmd(struct be_adapter *adapter)
+{
+	if (adapter->generation == BE_GEN3) {
+		struct be_hw_stats_v1 *hw_stats = hw_stats_from_cmd(adapter);
+
+		return &hw_stats->rxf;
+	} else {
+		struct be_hw_stats_v0 *hw_stats = hw_stats_from_cmd(adapter);
+
+		return &hw_stats->rxf;
+	}
+}
+
+static inline void *be_erx_stats_from_cmd(struct be_adapter *adapter)
+{
+	if (adapter->generation == BE_GEN3) {
+		struct be_hw_stats_v1 *hw_stats = hw_stats_from_cmd(adapter);
+
+		return &hw_stats->erx;
+	} else {
+		struct be_hw_stats_v0 *hw_stats = hw_stats_from_cmd(adapter);
+
+		return &hw_stats->erx;
+	}
+}
+
+static inline void *be_pmem_stats_from_cmd(struct be_adapter *adapter)
+{
+	if (adapter->generation == BE_GEN3) {
+		struct be_hw_stats_v1 *hw_stats = hw_stats_from_cmd(adapter);
+
+		return &hw_stats->pmem;
+	} else {
+		struct be_hw_stats_v0 *hw_stats = hw_stats_from_cmd(adapter);
+
+		return &hw_stats->pmem;
+	}
+}
+
 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,
@@ -1093,18 +1480,19 @@
 extern int be_cmd_q_destroy(struct be_adapter *adapter, struct be_queue_info *q,
 			int type);
 extern int be_cmd_link_status_query(struct be_adapter *adapter,
-			bool *link_up, u8 *mac_speed, u16 *link_speed);
+			bool *link_up, u8 *mac_speed, u16 *link_speed, u32 dom);
 extern int be_cmd_reset(struct be_adapter *adapter);
 extern int be_cmd_get_stats(struct be_adapter *adapter,
 			struct be_dma_mem *nonemb_cmd);
+extern int lancer_cmd_get_pport_stats(struct be_adapter *adapter,
+			struct be_dma_mem *nonemb_cmd);
 extern int be_cmd_get_fw_ver(struct be_adapter *adapter, char *fw_ver);
 
 extern int be_cmd_modify_eqd(struct be_adapter *adapter, u32 eq_id, u32 eqd);
 extern int be_cmd_vlan_config(struct be_adapter *adapter, u32 if_id,
 			u16 *vtag_array, u32 num, bool untagged,
 			bool promiscuous);
-extern int be_cmd_promiscuous_config(struct be_adapter *adapter,
-			u8 port_num, bool en);
+extern int be_cmd_promiscuous_config(struct be_adapter *adapter, bool en);
 extern int be_cmd_multicast_set(struct be_adapter *adapter, u32 if_id,
 			struct net_device *netdev, struct be_dma_mem *mem);
 extern int be_cmd_set_flow_control(struct be_adapter *adapter,
@@ -1124,6 +1512,11 @@
 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 lancer_cmd_write_object(struct be_adapter *adapter,
+				struct be_dma_mem *cmd,
+				u32 data_size, u32 data_offset,
+				const char *obj_name,
+				u32 *data_written, u8 *addn_status);
 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,
@@ -1148,4 +1541,6 @@
 extern int be_cmd_get_die_temperature(struct be_adapter *adapter);
 extern int be_cmd_get_cntl_attributes(struct be_adapter *adapter);
 extern int be_cmd_check_native_mode(struct be_adapter *adapter);
+extern int be_cmd_get_reg_len(struct be_adapter *adapter, u32 *log_size);
+extern void be_cmd_get_regs(struct be_adapter *adapter, u32 buf_len, void *buf);
 
diff -druN linux-2.6.39-libre/drivers/net/benet/be_ethtool.c linux-3.0-rc7-libre/drivers/net/benet/be_ethtool.c
--- linux-2.6.39-libre/drivers/net/benet/be_ethtool.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/benet/be_ethtool.c	2011-07-11 19:51:52.000000000 -0400
@@ -26,8 +26,8 @@
 	int offset;
 };
 
-enum {NETSTAT, PORTSTAT, MISCSTAT, DRVSTAT_TX, DRVSTAT_RX, ERXSTAT,
-			PMEMSTAT, DRVSTAT};
+enum {NETSTAT, DRVSTAT_TX, DRVSTAT_RX, ERXSTAT,
+			DRVSTAT};
 #define FIELDINFO(_struct, field) FIELD_SIZEOF(_struct, field), \
 					offsetof(_struct, field)
 #define NETSTAT_INFO(field) 	#field, NETSTAT,\
@@ -37,15 +37,8 @@
 					FIELDINFO(struct be_tx_stats, field)
 #define DRVSTAT_RX_INFO(field)	#field, DRVSTAT_RX,\
 					FIELDINFO(struct be_rx_stats, field)
-#define MISCSTAT_INFO(field) 	#field, MISCSTAT,\
-					FIELDINFO(struct be_rxf_stats, field)
-#define PORTSTAT_INFO(field) 	#field, PORTSTAT,\
-					FIELDINFO(struct be_port_rxf_stats, \
-						field)
-#define ERXSTAT_INFO(field) 	#field, ERXSTAT,\
-					FIELDINFO(struct be_erx_stats, field)
-#define PMEMSTAT_INFO(field) 	#field, PMEMSTAT,\
-					FIELDINFO(struct be_pmem_stats, field)
+#define ERXSTAT_INFO(field)	#field, ERXSTAT,\
+					FIELDINFO(struct be_erx_stats_v1, field)
 #define	DRVSTAT_INFO(field)	#field, DRVSTAT,\
 					FIELDINFO(struct be_drv_stats, \
 						field)
@@ -65,50 +58,41 @@
 	{DRVSTAT_TX_INFO(be_tx_stops)},
 	{DRVSTAT_TX_INFO(be_tx_events)},
 	{DRVSTAT_TX_INFO(be_tx_compl)},
-	{PORTSTAT_INFO(rx_unicast_frames)},
-	{PORTSTAT_INFO(rx_multicast_frames)},
-	{PORTSTAT_INFO(rx_broadcast_frames)},
-	{PORTSTAT_INFO(rx_crc_errors)},
-	{PORTSTAT_INFO(rx_alignment_symbol_errors)},
-	{PORTSTAT_INFO(rx_pause_frames)},
-	{PORTSTAT_INFO(rx_control_frames)},
-	{PORTSTAT_INFO(rx_in_range_errors)},
-	{PORTSTAT_INFO(rx_out_range_errors)},
-	{PORTSTAT_INFO(rx_frame_too_long)},
-	{PORTSTAT_INFO(rx_address_match_errors)},
-	{PORTSTAT_INFO(rx_vlan_mismatch)},
-	{PORTSTAT_INFO(rx_dropped_too_small)},
-	{PORTSTAT_INFO(rx_dropped_too_short)},
-	{PORTSTAT_INFO(rx_dropped_header_too_small)},
-	{PORTSTAT_INFO(rx_dropped_tcp_length)},
-	{PORTSTAT_INFO(rx_dropped_runt)},
-	{PORTSTAT_INFO(rx_fifo_overflow)},
-	{PORTSTAT_INFO(rx_input_fifo_overflow)},
-	{PORTSTAT_INFO(rx_ip_checksum_errs)},
-	{PORTSTAT_INFO(rx_tcp_checksum_errs)},
-	{PORTSTAT_INFO(rx_udp_checksum_errs)},
-	{PORTSTAT_INFO(rx_non_rss_packets)},
-	{PORTSTAT_INFO(rx_ipv4_packets)},
-	{PORTSTAT_INFO(rx_ipv6_packets)},
-	{PORTSTAT_INFO(rx_switched_unicast_packets)},
-	{PORTSTAT_INFO(rx_switched_multicast_packets)},
-	{PORTSTAT_INFO(rx_switched_broadcast_packets)},
-	{PORTSTAT_INFO(tx_unicastframes)},
-	{PORTSTAT_INFO(tx_multicastframes)},
-	{PORTSTAT_INFO(tx_broadcastframes)},
-	{PORTSTAT_INFO(tx_pauseframes)},
-	{PORTSTAT_INFO(tx_controlframes)},
-	{MISCSTAT_INFO(rx_drops_no_pbuf)},
-	{MISCSTAT_INFO(rx_drops_no_txpb)},
-	{MISCSTAT_INFO(rx_drops_no_erx_descr)},
-	{MISCSTAT_INFO(rx_drops_no_tpre_descr)},
-	{MISCSTAT_INFO(rx_drops_too_many_frags)},
-	{MISCSTAT_INFO(rx_drops_invalid_ring)},
-	{MISCSTAT_INFO(forwarded_packets)},
-	{MISCSTAT_INFO(rx_drops_mtu)},
-	{MISCSTAT_INFO(port0_jabber_events)},
-	{MISCSTAT_INFO(port1_jabber_events)},
-	{PMEMSTAT_INFO(eth_red_drops)},
+	{DRVSTAT_INFO(rx_crc_errors)},
+	{DRVSTAT_INFO(rx_alignment_symbol_errors)},
+	{DRVSTAT_INFO(rx_pause_frames)},
+	{DRVSTAT_INFO(rx_control_frames)},
+	{DRVSTAT_INFO(rx_in_range_errors)},
+	{DRVSTAT_INFO(rx_out_range_errors)},
+	{DRVSTAT_INFO(rx_frame_too_long)},
+	{DRVSTAT_INFO(rx_address_match_errors)},
+	{DRVSTAT_INFO(rx_dropped_too_small)},
+	{DRVSTAT_INFO(rx_dropped_too_short)},
+	{DRVSTAT_INFO(rx_dropped_header_too_small)},
+	{DRVSTAT_INFO(rx_dropped_tcp_length)},
+	{DRVSTAT_INFO(rx_dropped_runt)},
+	{DRVSTAT_INFO(rxpp_fifo_overflow_drop)},
+	{DRVSTAT_INFO(rx_input_fifo_overflow_drop)},
+	{DRVSTAT_INFO(rx_ip_checksum_errs)},
+	{DRVSTAT_INFO(rx_tcp_checksum_errs)},
+	{DRVSTAT_INFO(rx_udp_checksum_errs)},
+	{DRVSTAT_INFO(rx_switched_unicast_packets)},
+	{DRVSTAT_INFO(rx_switched_multicast_packets)},
+	{DRVSTAT_INFO(rx_switched_broadcast_packets)},
+	{DRVSTAT_INFO(tx_pauseframes)},
+	{DRVSTAT_INFO(tx_controlframes)},
+	{DRVSTAT_INFO(rx_priority_pause_frames)},
+	{DRVSTAT_INFO(pmem_fifo_overflow_drop)},
+	{DRVSTAT_INFO(jabber_events)},
+	{DRVSTAT_INFO(rx_drops_no_pbuf)},
+	{DRVSTAT_INFO(rx_drops_no_txpb)},
+	{DRVSTAT_INFO(rx_drops_no_erx_descr)},
+	{DRVSTAT_INFO(rx_drops_no_tpre_descr)},
+	{DRVSTAT_INFO(rx_drops_too_many_frags)},
+	{DRVSTAT_INFO(rx_drops_invalid_ring)},
+	{DRVSTAT_INFO(forwarded_packets)},
+	{DRVSTAT_INFO(rx_drops_mtu)},
+	{DRVSTAT_INFO(eth_red_drops)},
 	{DRVSTAT_INFO(be_on_die_temperature)}
 };
 #define ETHTOOL_STATS_NUM ARRAY_SIZE(et_stats)
@@ -156,6 +140,29 @@
 }
 
 static int
+be_get_reg_len(struct net_device *netdev)
+{
+	struct be_adapter *adapter = netdev_priv(netdev);
+	u32 log_size = 0;
+
+	if (be_physfn(adapter))
+		be_cmd_get_reg_len(adapter, &log_size);
+
+	return log_size;
+}
+
+static void
+be_get_regs(struct net_device *netdev, struct ethtool_regs *regs, void *buf)
+{
+	struct be_adapter *adapter = netdev_priv(netdev);
+
+	if (be_physfn(adapter)) {
+		memset(buf, 0, regs->len);
+		be_cmd_get_regs(adapter, regs->len, buf);
+	}
+}
+
+static int
 be_get_coalesce(struct net_device *netdev, struct ethtool_coalesce *coalesce)
 {
 	struct be_adapter *adapter = netdev_priv(netdev);
@@ -186,9 +193,9 @@
 	struct be_rx_obj *rxo;
 	struct be_eq_obj *rx_eq;
 	struct be_eq_obj *tx_eq = &adapter->tx_eq;
-	u32 tx_max, tx_min, tx_cur;
 	u32 rx_max, rx_min, rx_cur;
 	int status = 0, i;
+	u32 tx_cur;
 
 	if (coalesce->use_adaptive_tx_coalesce == 1)
 		return -EINVAL;
@@ -227,8 +234,6 @@
 		}
 	}
 
-	tx_max = coalesce->tx_coalesce_usecs_high;
-	tx_min = coalesce->tx_coalesce_usecs_low;
 	tx_cur = coalesce->tx_coalesce_usecs;
 
 	if (tx_cur > BE_MAX_EQD)
@@ -242,32 +247,11 @@
 	return 0;
 }
 
-static u32 be_get_rx_csum(struct net_device *netdev)
-{
-	struct be_adapter *adapter = netdev_priv(netdev);
-
-	return adapter->rx_csum;
-}
-
-static int be_set_rx_csum(struct net_device *netdev, uint32_t data)
-{
-	struct be_adapter *adapter = netdev_priv(netdev);
-
-	if (data)
-		adapter->rx_csum = true;
-	else
-		adapter->rx_csum = false;
-
-	return 0;
-}
-
 static void
 be_get_ethtool_stats(struct net_device *netdev,
 		struct ethtool_stats *stats, uint64_t *data)
 {
 	struct be_adapter *adapter = netdev_priv(netdev);
-	struct be_hw_stats *hw_stats = hw_stats_from_cmd(adapter->stats_cmd.va);
-	struct be_erx_stats *erx_stats = &hw_stats->erx;
 	struct be_rx_obj *rxo;
 	void *p = NULL;
 	int i, j;
@@ -280,15 +264,6 @@
 		case DRVSTAT_TX:
 			p = &adapter->tx_stats;
 			break;
-		case PORTSTAT:
-			p = &hw_stats->rxf.port[adapter->port_num];
-			break;
-		case MISCSTAT:
-			p = &hw_stats->rxf;
-			break;
-		case PMEMSTAT:
-			p = &hw_stats->pmem;
-			break;
 		case DRVSTAT:
 			p = &adapter->drv_stats;
 			break;
@@ -306,7 +281,8 @@
 				p = (u8 *)&rxo->stats + et_rx_stats[i].offset;
 				break;
 			case ERXSTAT:
-				p = (u32 *)erx_stats + rxo->q.id;
+				p = (u32 *)be_erx_stats_from_cmd(adapter) +
+								rxo->q.id;
 				break;
 			}
 			data[ETHTOOL_STATS_NUM + j * ETHTOOL_RXSTATS_NUM + i] =
@@ -374,19 +350,28 @@
 
 	if ((adapter->link_speed < 0) || (!(netdev->flags & IFF_UP))) {
 		status = be_cmd_link_status_query(adapter, &link_up,
-						&mac_speed, &link_speed);
+						&mac_speed, &link_speed, 0);
 
 		be_link_status_update(adapter, link_up);
 		/* link_speed is in units of 10 Mbps */
 		if (link_speed) {
-			ecmd->speed = link_speed*10;
+			ethtool_cmd_speed_set(ecmd, link_speed*10);
 		} else {
 			switch (mac_speed) {
+			case PHY_LINK_SPEED_10MBPS:
+				ethtool_cmd_speed_set(ecmd, SPEED_10);
+				break;
+			case PHY_LINK_SPEED_100MBPS:
+				ethtool_cmd_speed_set(ecmd, SPEED_100);
+				break;
 			case PHY_LINK_SPEED_1GBPS:
-				ecmd->speed = SPEED_1000;
+				ethtool_cmd_speed_set(ecmd, SPEED_1000);
 				break;
 			case PHY_LINK_SPEED_10GBPS:
-				ecmd->speed = SPEED_10000;
+				ethtool_cmd_speed_set(ecmd, SPEED_10000);
+				break;
+			case PHY_LINK_SPEED_ZERO:
+				ethtool_cmd_speed_set(ecmd, 0);
 				break;
 			}
 		}
@@ -429,14 +414,14 @@
 		}
 
 		/* Save for future use */
-		adapter->link_speed = ecmd->speed;
+		adapter->link_speed = ethtool_cmd_speed(ecmd);
 		adapter->port_type = ecmd->port;
 		adapter->transceiver = ecmd->transceiver;
 		adapter->autoneg = ecmd->autoneg;
 		dma_free_coherent(&adapter->pdev->dev, phy_cmd.size, phy_cmd.va,
 				  phy_cmd.dma);
 	} else {
-		ecmd->speed = adapter->link_speed;
+		ethtool_cmd_speed_set(ecmd, adapter->link_speed);
 		ecmd->port = adapter->port_type;
 		ecmd->transceiver = adapter->transceiver;
 		ecmd->autoneg = adapter->autoneg;
@@ -507,29 +492,33 @@
 }
 
 static int
-be_phys_id(struct net_device *netdev, u32 data)
+be_set_phys_id(struct net_device *netdev,
+	       enum ethtool_phys_id_state state)
 {
 	struct be_adapter *adapter = netdev_priv(netdev);
-	int status;
-	u32 cur;
-
-	be_cmd_get_beacon_state(adapter, adapter->hba_port_num, &cur);
 
-	if (cur == BEACON_STATE_ENABLED)
-		return 0;
+	switch (state) {
+	case ETHTOOL_ID_ACTIVE:
+		be_cmd_get_beacon_state(adapter, adapter->hba_port_num,
+					&adapter->beacon_state);
+		return 1;	/* cycle on/off once per second */
 
-	if (data < 2)
-		data = 2;
+	case ETHTOOL_ID_ON:
+		be_cmd_set_beacon_state(adapter, adapter->hba_port_num, 0, 0,
+					BEACON_STATE_ENABLED);
+		break;
 
-	status = be_cmd_set_beacon_state(adapter, adapter->hba_port_num, 0, 0,
-			BEACON_STATE_ENABLED);
-	set_current_state(TASK_INTERRUPTIBLE);
-	schedule_timeout(data*HZ);
+	case ETHTOOL_ID_OFF:
+		be_cmd_set_beacon_state(adapter, adapter->hba_port_num, 0, 0,
+					BEACON_STATE_DISABLED);
+		break;
 
-	status = be_cmd_set_beacon_state(adapter, adapter->hba_port_num, 0, 0,
-			BEACON_STATE_DISABLED);
+	case ETHTOOL_ID_INACTIVE:
+		be_cmd_set_beacon_state(adapter, adapter->hba_port_num, 0, 0,
+					adapter->beacon_state);
+	}
 
-	return status;
+	return 0;
 }
 
 static bool
@@ -646,7 +635,7 @@
 	}
 
 	if (be_cmd_link_status_query(adapter, &link_up, &mac_speed,
-				&qos_link_speed) != 0) {
+				&qos_link_speed, 0) != 0) {
 		test->flags |= ETH_TEST_FL_FAILED;
 		data[4] = -1;
 	} else if (!mac_speed) {
@@ -660,11 +649,9 @@
 {
 	struct be_adapter *adapter = netdev_priv(netdev);
 	char file_name[ETHTOOL_FLASH_MAX_FILENAME];
-	u32 region;
 
 	file_name[ETHTOOL_FLASH_MAX_FILENAME - 1] = 0;
 	strcpy(file_name, efl->data);
-	region = efl->region;
 
 	return be_load_fw(adapter, file_name);
 }
@@ -725,18 +712,12 @@
 	.get_ringparam = be_get_ringparam,
 	.get_pauseparam = be_get_pauseparam,
 	.set_pauseparam = be_set_pauseparam,
-	.get_rx_csum = be_get_rx_csum,
-	.set_rx_csum = be_set_rx_csum,
-	.get_tx_csum = ethtool_op_get_tx_csum,
-	.set_tx_csum = ethtool_op_set_tx_hw_csum,
-	.get_sg = ethtool_op_get_sg,
-	.set_sg = ethtool_op_set_sg,
-	.get_tso = ethtool_op_get_tso,
-	.set_tso = ethtool_op_set_tso,
 	.get_strings = be_get_stat_strings,
-	.phys_id = be_phys_id,
+	.set_phys_id = be_set_phys_id,
 	.get_sset_count = be_get_sset_count,
 	.get_ethtool_stats = be_get_ethtool_stats,
+	.get_regs_len = be_get_reg_len,
+	.get_regs = be_get_regs,
 	.flash_device = be_do_flash,
 	.self_test = be_self_test,
 };
diff -druN linux-2.6.39-libre/drivers/net/benet/be.h linux-3.0-rc7-libre/drivers/net/benet/be.h
--- linux-2.6.39-libre/drivers/net/benet/be.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/benet/be.h	2011-07-11 19:51:52.000000000 -0400
@@ -49,6 +49,7 @@
 #define OC_DEVICE_ID1		0x700	/* Device Id for BE2 cards */
 #define OC_DEVICE_ID2		0x710	/* Device Id for BE3 cards */
 #define OC_DEVICE_ID3		0xe220	/* Device id for Lancer cards */
+#define OC_DEVICE_ID4           0xe228   /* Device id for VF in Lancer */
 
 static inline char *nic_name(struct pci_dev *pdev)
 {
@@ -58,6 +59,7 @@
 	case OC_DEVICE_ID2:
 		return OC_NAME_BE;
 	case OC_DEVICE_ID3:
+	case OC_DEVICE_ID4:
 		return OC_NAME_LANCER;
 	case BE_DEVICE_ID2:
 		return BE3_NAME;
@@ -84,15 +86,14 @@
 #define MCC_CQ_LEN		256
 
 #define MAX_RSS_QS		4	/* BE limit is 4 queues/port */
-#define BE_MAX_MSIX_VECTORS	(MAX_RSS_QS + 1 + 1)/* RSS qs + 1 def Rx + Tx */
+#define MAX_RX_QS		(MAX_RSS_QS + 1) /* RSS qs + 1 def Rx */
+#define BE_MAX_MSIX_VECTORS	(MAX_RX_QS + 1)/* RX + TX */
 #define BE_NAPI_WEIGHT		64
 #define MAX_RX_POST 		BE_NAPI_WEIGHT /* Frags posted at a time */
 #define RX_FRAGS_REFILL_WM	(RX_Q_LEN - MAX_RX_POST)
 
 #define FW_VER_LEN		32
 
-#define BE_MAX_VF		32
-
 struct be_dma_mem {
 	void *va;
 	dma_addr_t dma;
@@ -245,6 +246,43 @@
 
 struct be_drv_stats {
 	u8 be_on_die_temperature;
+	u64 be_tx_events;
+	u64 eth_red_drops;
+	u64 rx_drops_no_pbuf;
+	u64 rx_drops_no_txpb;
+	u64 rx_drops_no_erx_descr;
+	u64 rx_drops_no_tpre_descr;
+	u64 rx_drops_too_many_frags;
+	u64 rx_drops_invalid_ring;
+	u64 forwarded_packets;
+	u64 rx_drops_mtu;
+	u64 rx_crc_errors;
+	u64 rx_alignment_symbol_errors;
+	u64 rx_pause_frames;
+	u64 rx_priority_pause_frames;
+	u64 rx_control_frames;
+	u64 rx_in_range_errors;
+	u64 rx_out_range_errors;
+	u64 rx_frame_too_long;
+	u64 rx_address_match_errors;
+	u64 rx_dropped_too_small;
+	u64 rx_dropped_too_short;
+	u64 rx_dropped_header_too_small;
+	u64 rx_dropped_tcp_length;
+	u64 rx_dropped_runt;
+	u64 rx_ip_checksum_errs;
+	u64 rx_tcp_checksum_errs;
+	u64 rx_udp_checksum_errs;
+	u64 rx_switched_unicast_packets;
+	u64 rx_switched_multicast_packets;
+	u64 rx_switched_broadcast_packets;
+	u64 tx_pauseframes;
+	u64 tx_priority_pauseframes;
+	u64 tx_controlframes;
+	u64 rxpp_fifo_overflow_drop;
+	u64 rx_input_fifo_overflow_drop;
+	u64 pmem_fifo_overflow_drop;
+	u64 jabber_events;
 };
 
 struct be_vf_cfg {
@@ -276,7 +314,7 @@
 	spinlock_t mcc_cq_lock;
 
 	struct msix_entry msix_entries[BE_MAX_MSIX_VECTORS];
-	bool msix_enabled;
+	u32 num_msix_vec;
 	bool isr_registered;
 
 	/* TX Rings */
@@ -287,7 +325,7 @@
 	u32 cache_line_break[8];
 
 	/* Rx rings */
-	struct be_rx_obj rx_obj[MAX_RSS_QS + 1]; /* one default non-rss Q */
+	struct be_rx_obj rx_obj[MAX_RX_QS];
 	u32 num_rx_qs;
 	u32 big_page_size;	/* Compounded page size shared by rx wrbs */
 
@@ -308,10 +346,10 @@
 	u16 work_counter;
 
 	/* Ethtool knobs and info */
-	bool rx_csum; 		/* BE card must perform rx-checksumming */
 	char fw_ver[FW_VER_LEN];
 	u32 if_handle;		/* Used to configure filtering */
 	u32 pmac_id;		/* MAC addr handle used by BE card */
+	u32 beacon_state;	/* for set_phys_id */
 
 	bool eeh_err;
 	bool link_up;
@@ -334,7 +372,7 @@
 
 	bool be3_native;
 	bool sriov_enabled;
-	struct be_vf_cfg vf_cfg[BE_MAX_VF];
+	struct be_vf_cfg *vf_cfg;
 	u8 is_virtfn;
 	u32 sli_family;
 	u8 hba_port_num;
@@ -347,10 +385,12 @@
 #define BE_GEN2 2
 #define BE_GEN3 3
 
-#define lancer_chip(adapter)		(adapter->pdev->device == OC_DEVICE_ID3)
+#define lancer_chip(adapter)	((adapter->pdev->device == OC_DEVICE_ID3) || \
+				 (adapter->pdev->device == OC_DEVICE_ID4))
 
 extern const struct ethtool_ops be_ethtool_ops;
 
+#define msix_enabled(adapter)		(adapter->num_msix_vec > 0)
 #define tx_stats(adapter)		(&adapter->tx_stats)
 #define rx_stats(rxo)			(&rxo->stats)
 
@@ -455,18 +495,10 @@
 
 static inline void be_check_sriov_fn_type(struct be_adapter *adapter)
 {
-	u8 data;
 	u32 sli_intf;
 
-	if (lancer_chip(adapter)) {
-		pci_read_config_dword(adapter->pdev, SLI_INTF_REG_OFFSET,
-								&sli_intf);
-		adapter->is_virtfn = (sli_intf & SLI_INTF_FT_MASK) ? 1 : 0;
-	} else {
-		pci_write_config_byte(adapter->pdev, 0xFE, 0xAA);
-		pci_read_config_byte(adapter->pdev, 0xFE, &data);
-		adapter->is_virtfn = (data != 0xAA);
-	}
+	pci_read_config_dword(adapter->pdev, SLI_INTF_REG_OFFSET, &sli_intf);
+	adapter->is_virtfn = (sli_intf & SLI_INTF_FT_MASK) ? 1 : 0;
 }
 
 static inline void be_vf_eth_addr_generate(struct be_adapter *adapter, u8 *mac)
@@ -482,9 +514,15 @@
 	memcpy(mac, adapter->netdev->dev_addr, 3);
 }
 
+static inline bool be_multi_rxq(const struct be_adapter *adapter)
+{
+	return adapter->num_rx_qs > 1;
+}
+
 extern void be_cq_notify(struct be_adapter *adapter, u16 qid, bool arm,
 		u16 num_popped);
 extern void be_link_status_update(struct be_adapter *adapter, bool link_up);
 extern void netdev_stats_update(struct be_adapter *adapter);
+extern void be_parse_stats(struct be_adapter *adapter);
 extern int be_load_fw(struct be_adapter *adapter, u8 *func);
 #endif				/* BE_H */
diff -druN linux-2.6.39-libre/drivers/net/benet/be_hw.h linux-3.0-rc7-libre/drivers/net/benet/be_hw.h
--- linux-2.6.39-libre/drivers/net/benet/be_hw.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/benet/be_hw.h	2011-07-11 19:51:52.000000000 -0400
@@ -155,6 +155,10 @@
 /********** SRIOV VF PCICFG OFFSET ********/
 #define SRIOV_VF_PCICFG_OFFSET		(4096)
 
+/********** FAT TABLE  ********/
+#define RETRIEVE_FAT	0
+#define QUERY_FAT	1
+
 /* Flashrom related descriptors */
 #define IMAGE_TYPE_FIRMWARE		160
 #define IMAGE_TYPE_BOOTCODE		224
diff -druN linux-2.6.39-libre/drivers/net/benet/be_main.c linux-3.0-rc7-libre/drivers/net/benet/be_main.c
--- linux-2.6.39-libre/drivers/net/benet/be_main.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/benet/be_main.c	2011-07-11 19:51:52.000000000 -0400
@@ -15,6 +15,7 @@
  * Costa Mesa, CA 92626
  */
 
+#include <linux/prefetch.h>
 #include "be.h"
 #include "be_cmds.h"
 #include <asm/div64.h>
@@ -42,6 +43,7 @@
 	{ PCI_DEVICE(BE_VENDOR_ID, OC_DEVICE_ID1) },
 	{ PCI_DEVICE(BE_VENDOR_ID, OC_DEVICE_ID2) },
 	{ PCI_DEVICE(EMULEX_VENDOR_ID, OC_DEVICE_ID3)},
+	{ PCI_DEVICE(EMULEX_VENDOR_ID, OC_DEVICE_ID4)},
 	{ 0 }
 };
 MODULE_DEVICE_TABLE(pci, be_dev_ids);
@@ -116,11 +118,6 @@
 	"Unknown"
 };
 
-static inline bool be_multi_rxq(struct be_adapter *adapter)
-{
-	return (adapter->num_rx_qs > 1);
-}
-
 static void be_queue_free(struct be_adapter *adapter, struct be_queue_info *q)
 {
 	struct be_dma_mem *mem = &q->dma_mem;
@@ -250,14 +247,185 @@
 	return status;
 }
 
+static void populate_be2_stats(struct be_adapter *adapter)
+{
+
+	struct be_drv_stats *drvs = &adapter->drv_stats;
+	struct be_pmem_stats *pmem_sts = be_pmem_stats_from_cmd(adapter);
+	struct be_port_rxf_stats_v0 *port_stats =
+		be_port_rxf_stats_from_cmd(adapter);
+	struct be_rxf_stats_v0 *rxf_stats =
+		be_rxf_stats_from_cmd(adapter);
+
+	drvs->rx_pause_frames = port_stats->rx_pause_frames;
+	drvs->rx_crc_errors = port_stats->rx_crc_errors;
+	drvs->rx_control_frames = port_stats->rx_control_frames;
+	drvs->rx_in_range_errors = port_stats->rx_in_range_errors;
+	drvs->rx_frame_too_long = port_stats->rx_frame_too_long;
+	drvs->rx_dropped_runt = port_stats->rx_dropped_runt;
+	drvs->rx_ip_checksum_errs = port_stats->rx_ip_checksum_errs;
+	drvs->rx_tcp_checksum_errs = port_stats->rx_tcp_checksum_errs;
+	drvs->rx_udp_checksum_errs = port_stats->rx_udp_checksum_errs;
+	drvs->rxpp_fifo_overflow_drop = port_stats->rx_fifo_overflow;
+	drvs->rx_dropped_tcp_length = port_stats->rx_dropped_tcp_length;
+	drvs->rx_dropped_too_small = port_stats->rx_dropped_too_small;
+	drvs->rx_dropped_too_short = port_stats->rx_dropped_too_short;
+	drvs->rx_out_range_errors = port_stats->rx_out_range_errors;
+	drvs->rx_input_fifo_overflow_drop =
+		port_stats->rx_input_fifo_overflow;
+	drvs->rx_dropped_header_too_small =
+		port_stats->rx_dropped_header_too_small;
+	drvs->rx_address_match_errors =
+		port_stats->rx_address_match_errors;
+	drvs->rx_alignment_symbol_errors =
+		port_stats->rx_alignment_symbol_errors;
+
+	drvs->tx_pauseframes = port_stats->tx_pauseframes;
+	drvs->tx_controlframes = port_stats->tx_controlframes;
+
+	if (adapter->port_num)
+		drvs->jabber_events =
+			rxf_stats->port1_jabber_events;
+	else
+		drvs->jabber_events =
+			rxf_stats->port0_jabber_events;
+	drvs->rx_drops_no_pbuf = rxf_stats->rx_drops_no_pbuf;
+	drvs->rx_drops_no_txpb = rxf_stats->rx_drops_no_txpb;
+	drvs->rx_drops_no_erx_descr = rxf_stats->rx_drops_no_erx_descr;
+	drvs->rx_drops_invalid_ring = rxf_stats->rx_drops_invalid_ring;
+	drvs->forwarded_packets = rxf_stats->forwarded_packets;
+	drvs->rx_drops_mtu = rxf_stats->rx_drops_mtu;
+	drvs->rx_drops_no_tpre_descr =
+		rxf_stats->rx_drops_no_tpre_descr;
+	drvs->rx_drops_too_many_frags =
+		rxf_stats->rx_drops_too_many_frags;
+	adapter->drv_stats.eth_red_drops = pmem_sts->eth_red_drops;
+}
+
+static void populate_be3_stats(struct be_adapter *adapter)
+{
+	struct be_drv_stats *drvs = &adapter->drv_stats;
+	struct be_pmem_stats *pmem_sts = be_pmem_stats_from_cmd(adapter);
+
+	struct be_rxf_stats_v1 *rxf_stats =
+		be_rxf_stats_from_cmd(adapter);
+	struct be_port_rxf_stats_v1 *port_stats =
+		be_port_rxf_stats_from_cmd(adapter);
+
+	drvs->rx_priority_pause_frames = 0;
+	drvs->pmem_fifo_overflow_drop = 0;
+	drvs->rx_pause_frames = port_stats->rx_pause_frames;
+	drvs->rx_crc_errors = port_stats->rx_crc_errors;
+	drvs->rx_control_frames = port_stats->rx_control_frames;
+	drvs->rx_in_range_errors = port_stats->rx_in_range_errors;
+	drvs->rx_frame_too_long = port_stats->rx_frame_too_long;
+	drvs->rx_dropped_runt = port_stats->rx_dropped_runt;
+	drvs->rx_ip_checksum_errs = port_stats->rx_ip_checksum_errs;
+	drvs->rx_tcp_checksum_errs = port_stats->rx_tcp_checksum_errs;
+	drvs->rx_udp_checksum_errs = port_stats->rx_udp_checksum_errs;
+	drvs->rx_dropped_tcp_length = port_stats->rx_dropped_tcp_length;
+	drvs->rx_dropped_too_small = port_stats->rx_dropped_too_small;
+	drvs->rx_dropped_too_short = port_stats->rx_dropped_too_short;
+	drvs->rx_out_range_errors = port_stats->rx_out_range_errors;
+	drvs->rx_dropped_header_too_small =
+		port_stats->rx_dropped_header_too_small;
+	drvs->rx_input_fifo_overflow_drop =
+		port_stats->rx_input_fifo_overflow_drop;
+	drvs->rx_address_match_errors =
+		port_stats->rx_address_match_errors;
+	drvs->rx_alignment_symbol_errors =
+		port_stats->rx_alignment_symbol_errors;
+	drvs->rxpp_fifo_overflow_drop =
+		port_stats->rxpp_fifo_overflow_drop;
+	drvs->tx_pauseframes = port_stats->tx_pauseframes;
+	drvs->tx_controlframes = port_stats->tx_controlframes;
+	drvs->jabber_events = port_stats->jabber_events;
+	drvs->rx_drops_no_pbuf = rxf_stats->rx_drops_no_pbuf;
+	drvs->rx_drops_no_txpb = rxf_stats->rx_drops_no_txpb;
+	drvs->rx_drops_no_erx_descr = rxf_stats->rx_drops_no_erx_descr;
+	drvs->rx_drops_invalid_ring = rxf_stats->rx_drops_invalid_ring;
+	drvs->forwarded_packets = rxf_stats->forwarded_packets;
+	drvs->rx_drops_mtu = rxf_stats->rx_drops_mtu;
+	drvs->rx_drops_no_tpre_descr =
+		rxf_stats->rx_drops_no_tpre_descr;
+	drvs->rx_drops_too_many_frags =
+		rxf_stats->rx_drops_too_many_frags;
+	adapter->drv_stats.eth_red_drops = pmem_sts->eth_red_drops;
+}
+
+static void populate_lancer_stats(struct be_adapter *adapter)
+{
+
+	struct be_drv_stats *drvs = &adapter->drv_stats;
+	struct lancer_cmd_pport_stats *pport_stats = pport_stats_from_cmd
+						(adapter);
+	drvs->rx_priority_pause_frames = 0;
+	drvs->pmem_fifo_overflow_drop = 0;
+	drvs->rx_pause_frames =
+		make_64bit_val(pport_stats->rx_pause_frames_lo,
+				 pport_stats->rx_pause_frames_hi);
+	drvs->rx_crc_errors = make_64bit_val(pport_stats->rx_crc_errors_hi,
+						pport_stats->rx_crc_errors_lo);
+	drvs->rx_control_frames =
+			make_64bit_val(pport_stats->rx_control_frames_hi,
+			pport_stats->rx_control_frames_lo);
+	drvs->rx_in_range_errors = pport_stats->rx_in_range_errors;
+	drvs->rx_frame_too_long =
+		make_64bit_val(pport_stats->rx_internal_mac_errors_hi,
+					pport_stats->rx_frames_too_long_lo);
+	drvs->rx_dropped_runt = pport_stats->rx_dropped_runt;
+	drvs->rx_ip_checksum_errs = pport_stats->rx_ip_checksum_errors;
+	drvs->rx_tcp_checksum_errs = pport_stats->rx_tcp_checksum_errors;
+	drvs->rx_udp_checksum_errs = pport_stats->rx_udp_checksum_errors;
+	drvs->rx_dropped_tcp_length =
+				pport_stats->rx_dropped_invalid_tcp_length;
+	drvs->rx_dropped_too_small = pport_stats->rx_dropped_too_small;
+	drvs->rx_dropped_too_short = pport_stats->rx_dropped_too_short;
+	drvs->rx_out_range_errors = pport_stats->rx_out_of_range_errors;
+	drvs->rx_dropped_header_too_small =
+				pport_stats->rx_dropped_header_too_small;
+	drvs->rx_input_fifo_overflow_drop = pport_stats->rx_fifo_overflow;
+	drvs->rx_address_match_errors = pport_stats->rx_address_match_errors;
+	drvs->rx_alignment_symbol_errors =
+		make_64bit_val(pport_stats->rx_symbol_errors_hi,
+				pport_stats->rx_symbol_errors_lo);
+	drvs->rxpp_fifo_overflow_drop = pport_stats->rx_fifo_overflow;
+	drvs->tx_pauseframes = make_64bit_val(pport_stats->tx_pause_frames_hi,
+					pport_stats->tx_pause_frames_lo);
+	drvs->tx_controlframes =
+		make_64bit_val(pport_stats->tx_control_frames_hi,
+				pport_stats->tx_control_frames_lo);
+	drvs->jabber_events = pport_stats->rx_jabbers;
+	drvs->rx_drops_no_pbuf = 0;
+	drvs->rx_drops_no_txpb = 0;
+	drvs->rx_drops_no_erx_descr = 0;
+	drvs->rx_drops_invalid_ring = pport_stats->rx_drops_invalid_queue;
+	drvs->forwarded_packets = make_64bit_val(pport_stats->num_forwards_hi,
+						pport_stats->num_forwards_lo);
+	drvs->rx_drops_mtu = make_64bit_val(pport_stats->rx_drops_mtu_hi,
+						pport_stats->rx_drops_mtu_lo);
+	drvs->rx_drops_no_tpre_descr = 0;
+	drvs->rx_drops_too_many_frags =
+		make_64bit_val(pport_stats->rx_drops_too_many_frags_hi,
+				pport_stats->rx_drops_too_many_frags_lo);
+}
+
+void be_parse_stats(struct be_adapter *adapter)
+{
+	if (adapter->generation == BE_GEN3) {
+		if (lancer_chip(adapter))
+			populate_lancer_stats(adapter);
+		 else
+			populate_be3_stats(adapter);
+	} else {
+		populate_be2_stats(adapter);
+	}
+}
+
 void netdev_stats_update(struct be_adapter *adapter)
 {
-	struct be_hw_stats *hw_stats = hw_stats_from_cmd(adapter->stats_cmd.va);
-	struct be_rxf_stats *rxf_stats = &hw_stats->rxf;
-	struct be_port_rxf_stats *port_stats =
-			&rxf_stats->port[adapter->port_num];
+	struct be_drv_stats *drvs = &adapter->drv_stats;
 	struct net_device_stats *dev_stats = &adapter->netdev->stats;
-	struct be_erx_stats *erx_stats = &hw_stats->erx;
 	struct be_rx_obj *rxo;
 	int i;
 
@@ -267,43 +435,54 @@
 		dev_stats->rx_bytes += rx_stats(rxo)->rx_bytes;
 		dev_stats->multicast += rx_stats(rxo)->rx_mcast_pkts;
 		/*  no space in linux buffers: best possible approximation */
-		dev_stats->rx_dropped +=
-			erx_stats->rx_drops_no_fragments[rxo->q.id];
+		if (adapter->generation == BE_GEN3) {
+			if (!(lancer_chip(adapter))) {
+				struct be_erx_stats_v1 *erx_stats =
+					be_erx_stats_from_cmd(adapter);
+				dev_stats->rx_dropped +=
+				erx_stats->rx_drops_no_fragments[rxo->q.id];
+			}
+		} else {
+			struct be_erx_stats_v0 *erx_stats =
+					be_erx_stats_from_cmd(adapter);
+			dev_stats->rx_dropped +=
+				erx_stats->rx_drops_no_fragments[rxo->q.id];
+		}
 	}
 
 	dev_stats->tx_packets = tx_stats(adapter)->be_tx_pkts;
 	dev_stats->tx_bytes = tx_stats(adapter)->be_tx_bytes;
 
 	/* bad pkts received */
-	dev_stats->rx_errors = port_stats->rx_crc_errors +
-		port_stats->rx_alignment_symbol_errors +
-		port_stats->rx_in_range_errors +
-		port_stats->rx_out_range_errors +
-		port_stats->rx_frame_too_long +
-		port_stats->rx_dropped_too_small +
-		port_stats->rx_dropped_too_short +
-		port_stats->rx_dropped_header_too_small +
-		port_stats->rx_dropped_tcp_length +
-		port_stats->rx_dropped_runt +
-		port_stats->rx_tcp_checksum_errs +
-		port_stats->rx_ip_checksum_errs +
-		port_stats->rx_udp_checksum_errs;
+	dev_stats->rx_errors = drvs->rx_crc_errors +
+		drvs->rx_alignment_symbol_errors +
+		drvs->rx_in_range_errors +
+		drvs->rx_out_range_errors +
+		drvs->rx_frame_too_long +
+		drvs->rx_dropped_too_small +
+		drvs->rx_dropped_too_short +
+		drvs->rx_dropped_header_too_small +
+		drvs->rx_dropped_tcp_length +
+		drvs->rx_dropped_runt +
+		drvs->rx_tcp_checksum_errs +
+		drvs->rx_ip_checksum_errs +
+		drvs->rx_udp_checksum_errs;
 
 	/* detailed rx errors */
-	dev_stats->rx_length_errors = port_stats->rx_in_range_errors +
-		port_stats->rx_out_range_errors +
-		port_stats->rx_frame_too_long;
+	dev_stats->rx_length_errors = drvs->rx_in_range_errors +
+		drvs->rx_out_range_errors +
+		drvs->rx_frame_too_long;
 
-	dev_stats->rx_crc_errors = port_stats->rx_crc_errors;
+	dev_stats->rx_crc_errors = drvs->rx_crc_errors;
 
 	/* frame alignment errors */
-	dev_stats->rx_frame_errors = port_stats->rx_alignment_symbol_errors;
+	dev_stats->rx_frame_errors = drvs->rx_alignment_symbol_errors;
 
 	/* receiver fifo overrun */
 	/* drops_no_pbuf is no per i/f, it's per BE card */
-	dev_stats->rx_fifo_errors = port_stats->rx_fifo_overflow +
-					port_stats->rx_input_fifo_overflow +
-					rxf_stats->rx_drops_no_pbuf;
+	dev_stats->rx_fifo_errors = drvs->rxpp_fifo_overflow_drop +
+				drvs->rx_input_fifo_overflow_drop +
+				drvs->rx_drops_no_pbuf;
 }
 
 void be_link_status_update(struct be_adapter *adapter, bool link_up)
@@ -703,7 +882,7 @@
 	struct be_adapter *adapter = netdev_priv(netdev);
 
 	if (netdev->flags & IFF_PROMISC) {
-		be_cmd_promiscuous_config(adapter, adapter->port_num, 1);
+		be_cmd_promiscuous_config(adapter, true);
 		adapter->promiscuous = true;
 		goto done;
 	}
@@ -711,7 +890,7 @@
 	/* BE was previously in promiscuous mode; disable it */
 	if (adapter->promiscuous) {
 		adapter->promiscuous = false;
-		be_cmd_promiscuous_config(adapter, adapter->port_num, 0);
+		be_cmd_promiscuous_config(adapter, false);
 	}
 
 	/* Enable multicast promisc if num configured exceeds what we support */
@@ -993,9 +1172,10 @@
 			struct be_rx_obj *rxo,
 			struct be_rx_compl_info *rxcp)
 {
+	struct net_device *netdev = adapter->netdev;
 	struct sk_buff *skb;
 
-	skb = netdev_alloc_skb_ip_align(adapter->netdev, BE_HDR_LEN);
+	skb = netdev_alloc_skb_ip_align(netdev, BE_HDR_LEN);
 	if (unlikely(!skb)) {
 		if (net_ratelimit())
 			dev_warn(&adapter->pdev->dev, "skb alloc failed\n");
@@ -1005,13 +1185,16 @@
 
 	skb_fill_rx_data(adapter, rxo, skb, rxcp);
 
-	if (likely(adapter->rx_csum && csum_passed(rxcp)))
+	if (likely((netdev->features & NETIF_F_RXCSUM) && csum_passed(rxcp)))
 		skb->ip_summed = CHECKSUM_UNNECESSARY;
 	else
 		skb_checksum_none_assert(skb);
 
 	skb->truesize = skb->len + sizeof(struct sk_buff);
-	skb->protocol = eth_type_trans(skb, adapter->netdev);
+	skb->protocol = eth_type_trans(skb, netdev);
+	if (adapter->netdev->features & NETIF_F_RXHASH)
+		skb->rxhash = rxcp->rss_hash;
+
 
 	if (unlikely(rxcp->vlanf)) {
 		if (!adapter->vlan_grp || adapter->vlans_added == 0) {
@@ -1073,6 +1256,8 @@
 	skb->data_len = rxcp->pkt_size;
 	skb->truesize += rxcp->pkt_size;
 	skb->ip_summed = CHECKSUM_UNNECESSARY;
+	if (adapter->netdev->features & NETIF_F_RXHASH)
+		skb->rxhash = rxcp->rss_hash;
 
 	if (likely(!rxcp->vlanf))
 		napi_gro_frags(&eq_obj->napi);
@@ -1103,9 +1288,14 @@
 		AMAP_GET_BITS(struct amap_eth_rx_compl_v1, numfrags, compl);
 	rxcp->pkt_type =
 		AMAP_GET_BITS(struct amap_eth_rx_compl_v1, cast_enc, compl);
-	rxcp->vtm = AMAP_GET_BITS(struct amap_eth_rx_compl_v1, vtm, compl);
-	rxcp->vlan_tag = AMAP_GET_BITS(struct amap_eth_rx_compl_v1, vlan_tag,
-					compl);
+	rxcp->rss_hash =
+		AMAP_GET_BITS(struct amap_eth_rx_compl_v1, rsshash, rxcp);
+	if (rxcp->vlanf) {
+		rxcp->vtm = AMAP_GET_BITS(struct amap_eth_rx_compl_v1, vtm,
+					  compl);
+		rxcp->vlan_tag = AMAP_GET_BITS(struct amap_eth_rx_compl_v1, vlan_tag,
+					       compl);
+	}
 }
 
 static void be_parse_rx_compl_v0(struct be_adapter *adapter,
@@ -1130,9 +1320,14 @@
 		AMAP_GET_BITS(struct amap_eth_rx_compl_v0, numfrags, compl);
 	rxcp->pkt_type =
 		AMAP_GET_BITS(struct amap_eth_rx_compl_v0, cast_enc, compl);
-	rxcp->vtm = AMAP_GET_BITS(struct amap_eth_rx_compl_v0, vtm, compl);
-	rxcp->vlan_tag = AMAP_GET_BITS(struct amap_eth_rx_compl_v0, vlan_tag,
-					compl);
+	rxcp->rss_hash =
+		AMAP_GET_BITS(struct amap_eth_rx_compl_v0, rsshash, rxcp);
+	if (rxcp->vlanf) {
+		rxcp->vtm = AMAP_GET_BITS(struct amap_eth_rx_compl_v0, vtm,
+					  compl);
+		rxcp->vlan_tag = AMAP_GET_BITS(struct amap_eth_rx_compl_v0, vlan_tag,
+					       compl);
+	}
 }
 
 static struct be_rx_compl_info *be_rx_compl_get(struct be_rx_obj *rxo)
@@ -1154,17 +1349,20 @@
 	else
 		be_parse_rx_compl_v0(adapter, compl, rxcp);
 
-	/* vlanf could be wrongly set in some cards. ignore if vtm is not set */
-	if ((adapter->function_mode & 0x400) && !rxcp->vtm)
-		rxcp->vlanf = 0;
+	if (rxcp->vlanf) {
+		/* vlanf could be wrongly set in some cards.
+		 * ignore if vtm is not set */
+		if ((adapter->function_mode & 0x400) && !rxcp->vtm)
+			rxcp->vlanf = 0;
 
-	if (!lancer_chip(adapter))
-		rxcp->vlan_tag = swab16(rxcp->vlan_tag);
+		if (!lancer_chip(adapter))
+			rxcp->vlan_tag = swab16(rxcp->vlan_tag);
 
-	if (((adapter->pvid & VLAN_VID_MASK) ==
-		(rxcp->vlan_tag & VLAN_VID_MASK)) &&
-		!adapter->vlan_tag[rxcp->vlan_tag])
-		rxcp->vlanf = 0;
+		if (((adapter->pvid & VLAN_VID_MASK) ==
+		     (rxcp->vlan_tag & VLAN_VID_MASK)) &&
+		    !adapter->vlan_tag[rxcp->vlan_tag])
+			rxcp->vlanf = 0;
+	}
 
 	/* As the compl has been parsed, reset it; we wont touch it again */
 	compl->dw[offsetof(struct amap_eth_rx_compl_v1, valid) / 32] = 0;
@@ -1261,7 +1459,7 @@
 	return txcp;
 }
 
-static void be_tx_compl_process(struct be_adapter *adapter, u16 last_index)
+static u16 be_tx_compl_process(struct be_adapter *adapter, u16 last_index)
 {
 	struct be_queue_info *txq = &adapter->tx_obj.q;
 	struct be_eth_wrb *wrb;
@@ -1288,9 +1486,8 @@
 		queue_tail_inc(txq);
 	} while (cur_index != last_index);
 
-	atomic_sub(num_wrbs, &txq->used);
-
 	kfree_skb(sent_skb);
+	return num_wrbs;
 }
 
 static inline struct be_eq_entry *event_get(struct be_eq_obj *eq_obj)
@@ -1373,7 +1570,7 @@
 	struct be_queue_info *tx_cq = &adapter->tx_obj.cq;
 	struct be_queue_info *txq = &adapter->tx_obj.q;
 	struct be_eth_tx_compl *txcp;
-	u16 end_idx, cmpl = 0, timeo = 0;
+	u16 end_idx, cmpl = 0, timeo = 0, num_wrbs = 0;
 	struct sk_buff **sent_skbs = adapter->tx_obj.sent_skb_list;
 	struct sk_buff *sent_skb;
 	bool dummy_wrb;
@@ -1383,12 +1580,14 @@
 		while ((txcp = be_tx_compl_get(tx_cq))) {
 			end_idx = AMAP_GET_BITS(struct amap_eth_tx_compl,
 					wrb_index, txcp);
-			be_tx_compl_process(adapter, end_idx);
+			num_wrbs += be_tx_compl_process(adapter, end_idx);
 			cmpl++;
 		}
 		if (cmpl) {
 			be_cq_notify(adapter, tx_cq->id, false, cmpl);
+			atomic_sub(num_wrbs, &txq->used);
 			cmpl = 0;
+			num_wrbs = 0;
 		}
 
 		if (atomic_read(&txq->used) == 0 || ++timeo > 200)
@@ -1408,7 +1607,8 @@
 		index_adv(&end_idx,
 			wrb_cnt_for_skb(adapter, sent_skb, &dummy_wrb) - 1,
 			txq->len);
-		be_tx_compl_process(adapter, end_idx);
+		num_wrbs = be_tx_compl_process(adapter, end_idx);
+		atomic_sub(num_wrbs, &txq->used);
 	}
 }
 
@@ -1573,12 +1773,31 @@
 	}
 }
 
+static u32 be_num_rxqs_want(struct be_adapter *adapter)
+{
+	if (multi_rxq && (adapter->function_caps & BE_FUNCTION_CAPS_RSS) &&
+		!adapter->sriov_enabled && !(adapter->function_mode & 0x400)) {
+		return 1 + MAX_RSS_QS; /* one default non-RSS queue */
+	} else {
+		dev_warn(&adapter->pdev->dev,
+			"No support for multiple RX queues\n");
+		return 1;
+	}
+}
+
 static int be_rx_queues_create(struct be_adapter *adapter)
 {
 	struct be_queue_info *eq, *q, *cq;
 	struct be_rx_obj *rxo;
 	int rc, i;
 
+	adapter->num_rx_qs = min(be_num_rxqs_want(adapter),
+				msix_enabled(adapter) ?
+					adapter->num_msix_vec - 1 : 1);
+	if (adapter->num_rx_qs != MAX_RX_QS)
+		dev_warn(&adapter->pdev->dev,
+			"Can create only %d RX queues", adapter->num_rx_qs);
+
 	adapter->big_page_size = (1 << get_order(rx_frag_size)) * PAGE_SIZE;
 	for_all_rx_queues(adapter, rxo, i) {
 		rxo->adapter = adapter;
@@ -1724,12 +1943,15 @@
 			break;
 
 		/* Ignore flush completions */
-		if (rxcp->num_rcvd) {
+		if (rxcp->num_rcvd && rxcp->pkt_size) {
 			if (do_gro(rxcp))
 				be_rx_compl_process_gro(adapter, rxo, rxcp);
 			else
 				be_rx_compl_process(adapter, rxo, rxcp);
+		} else if (rxcp->pkt_size == 0) {
+			be_rx_compl_discard(adapter, rxo, rxcp);
 		}
+
 		be_rx_stats_update(rxo, rxcp);
 	}
 
@@ -1760,12 +1982,12 @@
 	struct be_queue_info *tx_cq = &adapter->tx_obj.cq;
 	struct be_eth_tx_compl *txcp;
 	int tx_compl = 0, mcc_compl, status = 0;
-	u16 end_idx;
+	u16 end_idx, num_wrbs = 0;
 
 	while ((txcp = be_tx_compl_get(tx_cq))) {
 		end_idx = AMAP_GET_BITS(struct amap_eth_tx_compl,
 				wrb_index, txcp);
-		be_tx_compl_process(adapter, end_idx);
+		num_wrbs += be_tx_compl_process(adapter, end_idx);
 		tx_compl++;
 	}
 
@@ -1781,6 +2003,8 @@
 	if (tx_compl) {
 		be_cq_notify(adapter, adapter->tx_obj.cq.id, true, tx_compl);
 
+		atomic_sub(num_wrbs, &txq->used);
+
 		/* As Tx wrbs have been freed up, wake up netdev queue if
 		 * it was stopped due to lack of tx wrbs.
 		 */
@@ -1843,6 +2067,9 @@
 	struct be_rx_obj *rxo;
 	int i;
 
+	if (!adapter->ue_detected && !lancer_chip(adapter))
+		be_detect_dump_ue(adapter);
+
 	/* when interrupts are not yet enabled, just reap any pending
 	* mcc completions */
 	if (!netif_running(adapter->netdev)) {
@@ -1855,15 +2082,16 @@
 			be_cq_notify(adapter, mcc_obj->cq.id, false, mcc_compl);
 		}
 
-		if (!adapter->ue_detected && !lancer_chip(adapter))
-			be_detect_dump_ue(adapter);
-
 		goto reschedule;
 	}
 
-	if (!adapter->stats_cmd_sent)
-		be_cmd_get_stats(adapter, &adapter->stats_cmd);
-
+	if (!adapter->stats_cmd_sent) {
+		if (lancer_chip(adapter))
+			lancer_cmd_get_pport_stats(adapter,
+						&adapter->stats_cmd);
+		else
+			be_cmd_get_stats(adapter, &adapter->stats_cmd);
+	}
 	be_tx_rate_update(adapter);
 
 	for_all_rx_queues(adapter, rxo, i) {
@@ -1875,8 +2103,6 @@
 			be_post_rx_frags(rxo, GFP_KERNEL);
 		}
 	}
-	if (!adapter->ue_detected && !lancer_chip(adapter))
-		be_detect_dump_ue(adapter);
 
 reschedule:
 	adapter->work_counter++;
@@ -1885,51 +2111,35 @@
 
 static void be_msix_disable(struct be_adapter *adapter)
 {
-	if (adapter->msix_enabled) {
+	if (msix_enabled(adapter)) {
 		pci_disable_msix(adapter->pdev);
-		adapter->msix_enabled = false;
-	}
-}
-
-static int be_num_rxqs_get(struct be_adapter *adapter)
-{
-	if (multi_rxq && (adapter->function_caps & BE_FUNCTION_CAPS_RSS) &&
-		!adapter->sriov_enabled && !(adapter->function_mode & 0x400)) {
-		return 1 + MAX_RSS_QS; /* one default non-RSS queue */
-	} else {
-		dev_warn(&adapter->pdev->dev,
-			"No support for multiple RX queues\n");
-		return 1;
+		adapter->num_msix_vec = 0;
 	}
 }
 
 static void be_msix_enable(struct be_adapter *adapter)
 {
 #define BE_MIN_MSIX_VECTORS	(1 + 1) /* Rx + Tx */
-	int i, status;
+	int i, status, num_vec;
 
-	adapter->num_rx_qs = be_num_rxqs_get(adapter);
+	num_vec = be_num_rxqs_want(adapter) + 1;
 
-	for (i = 0; i < (adapter->num_rx_qs + 1); i++)
+	for (i = 0; i < num_vec; i++)
 		adapter->msix_entries[i].entry = i;
 
-	status = pci_enable_msix(adapter->pdev, adapter->msix_entries,
-			adapter->num_rx_qs + 1);
+	status = pci_enable_msix(adapter->pdev, adapter->msix_entries, num_vec);
 	if (status == 0) {
 		goto done;
 	} else if (status >= BE_MIN_MSIX_VECTORS) {
+		num_vec = status;
 		if (pci_enable_msix(adapter->pdev, adapter->msix_entries,
-				status) == 0) {
-			adapter->num_rx_qs = status - 1;
-			dev_warn(&adapter->pdev->dev,
-				"Could alloc only %d MSIx vectors. "
-				"Using %d RX Qs\n", status, adapter->num_rx_qs);
+				num_vec) == 0)
 			goto done;
-		}
 	}
 	return;
 done:
-	adapter->msix_enabled = true;
+	adapter->num_msix_vec = num_vec;
+	return;
 }
 
 static void be_sriov_enable(struct be_adapter *adapter)
@@ -1937,7 +2147,20 @@
 	be_check_sriov_fn_type(adapter);
 #ifdef CONFIG_PCI_IOV
 	if (be_physfn(adapter) && num_vfs) {
-		int status;
+		int status, pos;
+		u16 nvfs;
+
+		pos = pci_find_ext_capability(adapter->pdev,
+						PCI_EXT_CAP_ID_SRIOV);
+		pci_read_config_word(adapter->pdev,
+					pos + PCI_SRIOV_TOTAL_VF, &nvfs);
+
+		if (num_vfs > nvfs) {
+			dev_info(&adapter->pdev->dev,
+					"Device supports %d VFs and not %d\n",
+					nvfs, num_vfs);
+			num_vfs = nvfs;
+		}
 
 		status = pci_enable_sriov(adapter->pdev, num_vfs);
 		adapter->sriov_enabled = status ? false : true;
@@ -2010,8 +2233,7 @@
 err:
 	dev_warn(&adapter->pdev->dev,
 		"MSIX Request IRQ failed - err %d\n", status);
-	pci_disable_msix(adapter->pdev);
-	adapter->msix_enabled = false;
+	be_msix_disable(adapter);
 	return status;
 }
 
@@ -2020,7 +2242,7 @@
 	struct net_device *netdev = adapter->netdev;
 	int status;
 
-	if (adapter->msix_enabled) {
+	if (msix_enabled(adapter)) {
 		status = be_msix_register(adapter);
 		if (status == 0)
 			goto done;
@@ -2053,7 +2275,7 @@
 		return;
 
 	/* INTx */
-	if (!adapter->msix_enabled) {
+	if (!msix_enabled(adapter)) {
 		free_irq(netdev->irq, adapter);
 		goto done;
 	}
@@ -2095,7 +2317,7 @@
 			 be_cq_notify(adapter, rxo->cq.id, false, 0);
 	}
 
-	if (adapter->msix_enabled) {
+	if (msix_enabled(adapter)) {
 		vec = be_msix_vec_get(adapter, tx_eq);
 		synchronize_irq(vec);
 
@@ -2148,7 +2370,7 @@
 	be_async_mcc_enable(adapter);
 
 	status = be_cmd_link_status_query(adapter, &link_up, &mac_speed,
-			&link_speed);
+			&link_speed, 0);
 	if (status)
 		goto err;
 	be_link_status_update(adapter, link_up);
@@ -2268,7 +2490,7 @@
 				BE_IF_FLAGS_PASS_L3L4_ERRORS;
 		en_flags |= BE_IF_FLAGS_PASS_L3L4_ERRORS;
 
-		if (be_multi_rxq(adapter)) {
+		if (adapter->function_caps & BE_FUNCTION_CAPS_RSS) {
 			cap_flags |= BE_IF_FLAGS_RSS;
 			en_flags |= BE_IF_FLAGS_RSS;
 		}
@@ -2325,7 +2547,6 @@
 
 	return 0;
 
-	be_mcc_queues_destroy(adapter);
 rx_qs_destroy:
 	be_rx_queues_destroy(adapter);
 tx_qs_destroy:
@@ -2493,7 +2714,6 @@
 					"cmd to write to flash rom failed.\n");
 				return -1;
 			}
-			yield();
 		}
 	}
 	return 0;
@@ -2511,32 +2731,96 @@
 		return 0;
 }
 
-int be_load_fw(struct be_adapter *adapter, u8 *func)
+static int lancer_fw_download(struct be_adapter *adapter,
+				const struct firmware *fw)
 {
-	char fw_file[ETHTOOL_FLASH_MAX_FILENAME];
-	const struct firmware *fw;
-	struct flash_file_hdr_g2 *fhdr;
-	struct flash_file_hdr_g3 *fhdr3;
-	struct image_hdr *img_hdr_ptr = NULL;
+#define LANCER_FW_DOWNLOAD_CHUNK      (32 * 1024)
+#define LANCER_FW_DOWNLOAD_LOCATION   "/prg"
 	struct be_dma_mem flash_cmd;
-	int status, i = 0, num_imgs = 0;
-	const u8 *p;
+	const u8 *data_ptr = NULL;
+	u8 *dest_image_ptr = NULL;
+	size_t image_size = 0;
+	u32 chunk_size = 0;
+	u32 data_written = 0;
+	u32 offset = 0;
+	int status = 0;
+	u8 add_status = 0;
 
-	if (!netif_running(adapter->netdev)) {
+	if (!IS_ALIGNED(fw->size, sizeof(u32))) {
 		dev_err(&adapter->pdev->dev,
-			"Firmware load not allowed (interface is down)\n");
-		return -EPERM;
+			"FW Image not properly aligned. "
+			"Length must be 4 byte aligned.\n");
+		status = -EINVAL;
+		goto lancer_fw_exit;
 	}
 
-	strcpy(fw_file, func);
+	flash_cmd.size = sizeof(struct lancer_cmd_req_write_object)
+				+ LANCER_FW_DOWNLOAD_CHUNK;
+	flash_cmd.va = dma_alloc_coherent(&adapter->pdev->dev, flash_cmd.size,
+						&flash_cmd.dma, GFP_KERNEL);
+	if (!flash_cmd.va) {
+		status = -ENOMEM;
+		dev_err(&adapter->pdev->dev,
+			"Memory allocation failure while flashing\n");
+		goto lancer_fw_exit;
+	}
 
-	status = request_firmware(&fw, fw_file, &adapter->pdev->dev);
-	if (status)
-		goto fw_exit;
+	dest_image_ptr = flash_cmd.va +
+				sizeof(struct lancer_cmd_req_write_object);
+	image_size = fw->size;
+	data_ptr = fw->data;
+
+	while (image_size) {
+		chunk_size = min_t(u32, image_size, LANCER_FW_DOWNLOAD_CHUNK);
+
+		/* Copy the image chunk content. */
+		memcpy(dest_image_ptr, data_ptr, chunk_size);
+
+		status = lancer_cmd_write_object(adapter, &flash_cmd,
+				chunk_size, offset, LANCER_FW_DOWNLOAD_LOCATION,
+				&data_written, &add_status);
+
+		if (status)
+			break;
+
+		offset += data_written;
+		data_ptr += data_written;
+		image_size -= data_written;
+	}
+
+	if (!status) {
+		/* Commit the FW written */
+		status = lancer_cmd_write_object(adapter, &flash_cmd,
+					0, offset, LANCER_FW_DOWNLOAD_LOCATION,
+					&data_written, &add_status);
+	}
+
+	dma_free_coherent(&adapter->pdev->dev, flash_cmd.size, flash_cmd.va,
+				flash_cmd.dma);
+	if (status) {
+		dev_err(&adapter->pdev->dev,
+			"Firmware load error. "
+			"Status code: 0x%x Additional Status: 0x%x\n",
+			status, add_status);
+		goto lancer_fw_exit;
+	}
+
+	dev_info(&adapter->pdev->dev, "Firmware flashed successfully\n");
+lancer_fw_exit:
+	return status;
+}
+
+static int be_fw_download(struct be_adapter *adapter, const struct firmware* fw)
+{
+	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;
+	const u8 *p;
+	int status = 0, i = 0, num_imgs = 0;
 
 	p = fw->data;
 	fhdr = (struct flash_file_hdr_g2 *) p;
-	dev_info(&adapter->pdev->dev, "Flashing firmware file %s\n", fw_file);
 
 	flash_cmd.size = sizeof(struct be_cmd_write_flashrom) + 32*1024;
 	flash_cmd.va = dma_alloc_coherent(&adapter->pdev->dev, flash_cmd.size,
@@ -2545,7 +2829,7 @@
 		status = -ENOMEM;
 		dev_err(&adapter->pdev->dev,
 			"Memory allocation failure while flashing\n");
-		goto fw_exit;
+		goto be_fw_exit;
 	}
 
 	if ((adapter->generation == BE_GEN3) &&
@@ -2573,11 +2857,37 @@
 			  flash_cmd.dma);
 	if (status) {
 		dev_err(&adapter->pdev->dev, "Firmware load error\n");
-		goto fw_exit;
+		goto be_fw_exit;
 	}
 
 	dev_info(&adapter->pdev->dev, "Firmware flashed successfully\n");
 
+be_fw_exit:
+	return status;
+}
+
+int be_load_fw(struct be_adapter *adapter, u8 *fw_file)
+{
+	const struct firmware *fw;
+	int status;
+
+	if (!netif_running(adapter->netdev)) {
+		dev_err(&adapter->pdev->dev,
+			"Firmware load not allowed (interface is down)\n");
+		return -1;
+	}
+
+	status = request_firmware(&fw, fw_file, &adapter->pdev->dev);
+	if (status)
+		goto fw_exit;
+
+	dev_info(&adapter->pdev->dev, "Flashing firmware file %s\n", fw_file);
+
+	if (lancer_chip(adapter))
+		status = lancer_fw_download(adapter, fw);
+	else
+		status = be_fw_download(adapter, fw);
+
 fw_exit:
 	release_firmware(fw);
 	return status;
@@ -2606,10 +2916,14 @@
 	struct be_rx_obj *rxo;
 	int i;
 
-	netdev->features |= NETIF_F_SG | NETIF_F_HW_VLAN_RX | NETIF_F_TSO |
-		NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_FILTER |
-		NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
-		NETIF_F_GRO | NETIF_F_TSO6;
+	netdev->hw_features |= NETIF_F_SG | NETIF_F_TSO | NETIF_F_TSO6 |
+		NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | NETIF_F_RXCSUM |
+		NETIF_F_HW_VLAN_TX;
+	if (be_multi_rxq(adapter))
+		netdev->hw_features |= NETIF_F_RXHASH;
+
+	netdev->features |= netdev->hw_features |
+		NETIF_F_HW_VLAN_RX | NETIF_F_HW_VLAN_FILTER;
 
 	netdev->vlan_features |= NETIF_F_SG | NETIF_F_TSO |
 		NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;
@@ -2619,8 +2933,6 @@
 
 	netdev->flags |= IFF_MULTICAST;
 
-	adapter->rx_csum = true;
-
 	/* Default settings for Rx and Tx flow control */
 	adapter->rx_fc = true;
 	adapter->tx_fc = true;
@@ -2788,7 +3100,14 @@
 {
 	struct be_dma_mem *cmd = &adapter->stats_cmd;
 
-	cmd->size = sizeof(struct be_cmd_req_get_stats);
+	if (adapter->generation == BE_GEN2) {
+		cmd->size = sizeof(struct be_cmd_req_get_stats_v0);
+	} else {
+		if (lancer_chip(adapter))
+			cmd->size = sizeof(struct lancer_cmd_req_pport_stats);
+		else
+			cmd->size = sizeof(struct be_cmd_req_get_stats_v1);
+	}
 	cmd->va = dma_alloc_coherent(&adapter->pdev->dev, cmd->size, &cmd->dma,
 				     GFP_KERNEL);
 	if (cmd->va == NULL)
@@ -2814,6 +3133,7 @@
 
 	be_ctrl_cleanup(adapter);
 
+	kfree(adapter->vf_cfg);
 	be_sriov_disable(adapter);
 
 	be_msix_disable(adapter);
@@ -2841,7 +3161,8 @@
 
 	memset(mac, 0, ETH_ALEN);
 
-	if (be_physfn(adapter)) {
+	/* A default permanent address is given to each VF for Lancer*/
+	if (be_physfn(adapter) || lancer_chip(adapter)) {
 		status = be_cmd_mac_addr_query(adapter, mac,
 			MAC_ADDRESS_TYPE_NETWORK, true /*permanent */, 0);
 
@@ -2883,6 +3204,7 @@
 		adapter->generation = BE_GEN3;
 		break;
 	case OC_DEVICE_ID3:
+	case OC_DEVICE_ID4:
 		pci_read_config_dword(pdev, SLI_INTF_REG_OFFSET, &sli_intf);
 		if_type = (sli_intf & SLI_INTF_IF_TYPE_MASK) >>
 						SLI_INTF_IF_TYPE_SHIFT;
@@ -2892,10 +3214,6 @@
 			dev_err(&pdev->dev, "SLI_INTF reg val is not valid\n");
 			return -EINVAL;
 		}
-		if (num_vfs > 0) {
-			dev_err(&pdev->dev, "VFs not supported\n");
-			return -EINVAL;
-		}
 		adapter->sli_family = ((sli_intf & SLI_INTF_FAMILY_MASK) >>
 					 SLI_INTF_FAMILY_SHIFT);
 		adapter->generation = BE_GEN3;
@@ -2998,16 +3316,23 @@
 	}
 
 	be_sriov_enable(adapter);
+	if (adapter->sriov_enabled) {
+		adapter->vf_cfg = kcalloc(num_vfs,
+			sizeof(struct be_vf_cfg), GFP_KERNEL);
+
+		if (!adapter->vf_cfg)
+			goto free_netdev;
+	}
 
 	status = be_ctrl_init(adapter);
 	if (status)
-		goto free_netdev;
+		goto free_vf_cfg;
 
 	if (lancer_chip(adapter)) {
 		status = lancer_test_and_set_rdy_state(adapter);
 		if (status) {
 			dev_err(&pdev->dev, "Adapter in non recoverable error\n");
-			goto free_netdev;
+			goto ctrl_clean;
 		}
 	}
 
@@ -3050,9 +3375,24 @@
 	netif_carrier_off(netdev);
 
 	if (be_physfn(adapter) && adapter->sriov_enabled) {
-		status = be_vf_eth_addr_config(adapter);
-		if (status)
-			goto unreg_netdev;
+		u8 mac_speed;
+		bool link_up;
+		u16 vf, lnk_speed;
+
+		if (!lancer_chip(adapter)) {
+			status = be_vf_eth_addr_config(adapter);
+			if (status)
+				goto unreg_netdev;
+		}
+
+		for (vf = 0; vf < num_vfs; vf++) {
+			status = be_cmd_link_status_query(adapter, &link_up,
+					&mac_speed, &lnk_speed, vf + 1);
+			if (!status)
+				adapter->vf_cfg[vf].vf_tx_rate = lnk_speed * 10;
+			else
+				goto unreg_netdev;
+		}
 	}
 
 	dev_info(&pdev->dev, "%s port %d\n", nic_name(pdev), adapter->port_num);
@@ -3069,6 +3409,8 @@
 	be_stats_cleanup(adapter);
 ctrl_clean:
 	be_ctrl_cleanup(adapter);
+free_vf_cfg:
+	kfree(adapter->vf_cfg);
 free_netdev:
 	be_sriov_disable(adapter);
 	free_netdev(netdev);
@@ -3153,16 +3495,15 @@
 	if (!adapter)
 		return;
 
-	if (netif_running(adapter->netdev))
-		cancel_delayed_work_sync(&adapter->work);
+	cancel_delayed_work_sync(&adapter->work);
 
 	netif_device_detach(adapter->netdev);
 
-	be_cmd_reset_function(adapter);
-
 	if (adapter->wol)
 		be_setup_wol(adapter, true);
 
+	be_cmd_reset_function(adapter);
+
 	pci_disable_device(pdev);
 }
 
@@ -3274,13 +3615,6 @@
 		rx_frag_size = 2048;
 	}
 
-	if (num_vfs > 32) {
-		printk(KERN_WARNING DRV_NAME
-			" : Module param num_vfs must not be greater than 32."
-			"Using 32\n");
-		num_vfs = 32;
-	}
-
 	return pci_register_driver(&be_driver);
 }
 module_init(be_init_module);
diff -druN linux-2.6.39-libre/drivers/net/bfin_mac.c linux-3.0-rc7-libre/drivers/net/bfin_mac.c
--- linux-2.6.39-libre/drivers/net/bfin_mac.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/bfin_mac.c	2011-07-11 19:51:52.000000000 -0400
@@ -52,13 +52,13 @@
 MODULE_ALIAS("platform:bfin_mac");
 
 #if defined(CONFIG_BFIN_MAC_USE_L1)
-# define bfin_mac_alloc(dma_handle, size)  l1_data_sram_zalloc(size)
-# define bfin_mac_free(dma_handle, ptr)    l1_data_sram_free(ptr)
+# define bfin_mac_alloc(dma_handle, size, num)  l1_data_sram_zalloc(size*num)
+# define bfin_mac_free(dma_handle, ptr, num)    l1_data_sram_free(ptr)
 #else
-# define bfin_mac_alloc(dma_handle, size) \
-	dma_alloc_coherent(NULL, size, dma_handle, GFP_KERNEL)
-# define bfin_mac_free(dma_handle, ptr) \
-	dma_free_coherent(NULL, sizeof(*ptr), ptr, dma_handle)
+# define bfin_mac_alloc(dma_handle, size, num) \
+	dma_alloc_coherent(NULL, size*num, dma_handle, GFP_KERNEL)
+# define bfin_mac_free(dma_handle, ptr, num) \
+	dma_free_coherent(NULL, sizeof(*ptr)*num, ptr, dma_handle)
 #endif
 
 #define PKT_BUF_SZ 1580
@@ -95,7 +95,7 @@
 				t = t->next;
 			}
 		}
-		bfin_mac_free(dma_handle, tx_desc);
+		bfin_mac_free(dma_handle, tx_desc, CONFIG_BFIN_TX_DESC_NUM);
 	}
 
 	if (rx_desc) {
@@ -109,7 +109,7 @@
 				r = r->next;
 			}
 		}
-		bfin_mac_free(dma_handle, rx_desc);
+		bfin_mac_free(dma_handle, rx_desc, CONFIG_BFIN_RX_DESC_NUM);
 	}
 }
 
@@ -126,13 +126,13 @@
 #endif
 
 	tx_desc = bfin_mac_alloc(&dma_handle,
-				sizeof(struct net_dma_desc_tx) *
+				sizeof(struct net_dma_desc_tx),
 				CONFIG_BFIN_TX_DESC_NUM);
 	if (tx_desc == NULL)
 		goto init_error;
 
 	rx_desc = bfin_mac_alloc(&dma_handle,
-				sizeof(struct net_dma_desc_rx) *
+				sizeof(struct net_dma_desc_rx),
 				CONFIG_BFIN_RX_DESC_NUM);
 	if (rx_desc == NULL)
 		goto init_error;
diff -druN linux-2.6.39-libre/drivers/net/bna/bfa_ioc.c linux-3.0-rc7-libre/drivers/net/bna/bfa_ioc.c
--- linux-2.6.39-libre/drivers/net/bna/bfa_ioc.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/bna/bfa_ioc.c	2011-07-11 19:51:52.000000000 -0400
@@ -82,7 +82,6 @@
 static void bfa_ioc_boot(struct bfa_ioc *ioc, u32 boot_type,
 			 u32 boot_param);
 static u32 bfa_ioc_smem_pgnum(struct bfa_ioc *ioc, u32 fmaddr);
-static u32 bfa_ioc_smem_pgoff(struct bfa_ioc *ioc, u32 fmaddr);
 static void bfa_ioc_get_adapter_serial_num(struct bfa_ioc *ioc,
 						char *serial_num);
 static void bfa_ioc_get_adapter_fw_ver(struct bfa_ioc *ioc,
@@ -1274,13 +1273,12 @@
 void
 bfa_nw_ioc_fwver_get(struct bfa_ioc *ioc, struct bfi_ioc_image_hdr *fwhdr)
 {
-	u32	pgnum, pgoff;
+	u32	pgnum;
 	u32	loff = 0;
 	int		i;
 	u32	*fwsig = (u32 *) fwhdr;
 
 	pgnum = bfa_ioc_smem_pgnum(ioc, loff);
-	pgoff = bfa_ioc_smem_pgoff(ioc, loff);
 	writel(pgnum, ioc->ioc_regs.host_page_num_fn);
 
 	for (i = 0; i < (sizeof(struct bfi_ioc_image_hdr) / sizeof(u32));
@@ -1514,7 +1512,7 @@
 		    u32 boot_env)
 {
 	u32 *fwimg;
-	u32 pgnum, pgoff;
+	u32 pgnum;
 	u32 loff = 0;
 	u32 chunkno = 0;
 	u32 i;
@@ -1527,7 +1525,6 @@
 	fwimg = bfa_cb_image_get_chunk(BFA_IOC_FWIMG_TYPE(ioc), chunkno);
 
 	pgnum = bfa_ioc_smem_pgnum(ioc, loff);
-	pgoff = bfa_ioc_smem_pgoff(ioc, loff);
 
 	writel(pgnum, ioc->ioc_regs.host_page_num_fn);
 
@@ -1925,12 +1922,6 @@
 	return PSS_SMEM_PGNUM(ioc->ioc_regs.smem_pg0, fmaddr);
 }
 
-static u32
-bfa_ioc_smem_pgoff(struct bfa_ioc *ioc, u32 fmaddr)
-{
-	return PSS_SMEM_PGOFF(fmaddr);
-}
-
 /**
  * Register mailbox message handler function, to be called by common modules
  */
diff -druN linux-2.6.39-libre/drivers/net/bna/bna_ctrl.c linux-3.0-rc7-libre/drivers/net/bna/bna_ctrl.c
--- linux-2.6.39-libre/drivers/net/bna/bna_ctrl.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/bna/bna_ctrl.c	2011-07-11 19:51:52.000000000 -0400
@@ -246,7 +246,6 @@
 bna_mbox_flush_q(struct bna *bna, struct list_head *q)
 {
 	struct bna_mbox_qe *mb_qe = NULL;
-	struct bfi_mhdr *cmd_h;
 	struct list_head			*mb_q;
 	void 			(*cbfn)(void *arg, int status);
 	void 			*cbarg;
@@ -260,7 +259,6 @@
 		bfa_q_qe_init(mb_qe);
 		bna->mbox_mod.msg_pending--;
 
-		cmd_h = (struct bfi_mhdr *)(&mb_qe->cmd.msg[0]);
 		if (cbfn)
 			cbfn(cbarg, BNA_CB_NOT_EXEC);
 	}
@@ -2774,23 +2772,6 @@
 	}
 }
 
-static void
-bna_rit_mod_uninit(struct bna_rit_mod *rit_mod)
-{
-	struct bna_rit_segment *rit_segment;
-	struct list_head *qe;
-	int i;
-	int j;
-
-	for (i = 0; i < BFI_RIT_SEG_TOTAL_POOLS; i++) {
-		j = 0;
-		list_for_each(qe, &rit_mod->rit_seg_pool[i]) {
-			rit_segment = (struct bna_rit_segment *)qe;
-			j++;
-		}
-	}
-}
-
 /*
  * Public functions
  */
@@ -2977,8 +2958,6 @@
 
 	bna_ucam_mod_uninit(&bna->ucam_mod);
 
-	bna_rit_mod_uninit(&bna->rit_mod);
-
 	bna_ib_mod_uninit(&bna->ib_mod);
 
 	bna_rx_mod_uninit(&bna->rx_mod);
diff -druN linux-2.6.39-libre/drivers/net/bna/bnad.c linux-3.0-rc7-libre/drivers/net/bna/bnad.c
--- linux-2.6.39-libre/drivers/net/bna/bnad.c	2011-05-19 02:11:14.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/bna/bnad.c	2011-07-21 06:53:46.000000000 -0400
@@ -23,6 +23,7 @@
 #include <linux/if_vlan.h>
 #include <linux/if_ether.h>
 #include <linux/ip.h>
+#include <linux/prefetch.h>
 
 #include "bnad.h"
 #include "bna.h"
@@ -501,7 +502,7 @@
 
 		skb_put(skb, ntohs(cmpl->length));
 		if (likely
-		    (bnad->rx_csum &&
+		    ((bnad->netdev->features & NETIF_F_RXCSUM) &&
 		     (((flags & BNA_CQ_EF_IPV4) &&
 		      (flags & BNA_CQ_EF_L3_CKSUM_OK)) ||
 		      (flags & BNA_CQ_EF_IPV6)) &&
@@ -1110,7 +1111,7 @@
 		    struct bna_intr_info *intr_info)
 {
 	int 		err = 0;
-	unsigned long 	flags;
+	unsigned long 	irq_flags = 0, flags;
 	u32	irq;
 	irq_handler_t 	irq_handler;
 
@@ -1124,18 +1125,17 @@
 	if (bnad->cfg_flags & BNAD_CF_MSIX) {
 		irq_handler = (irq_handler_t)bnad_msix_mbox_handler;
 		irq = bnad->msix_table[bnad->msix_num - 1].vector;
-		flags = 0;
 		intr_info->intr_type = BNA_INTR_T_MSIX;
 		intr_info->idl[0].vector = bnad->msix_num - 1;
 	} else {
 		irq_handler = (irq_handler_t)bnad_isr;
 		irq = bnad->pcidev->irq;
-		flags = IRQF_SHARED;
+		irq_flags = IRQF_SHARED;
 		intr_info->intr_type = BNA_INTR_T_INTX;
 		/* intr_info->idl.vector = 0 ? */
 	}
 	spin_unlock_irqrestore(&bnad->bna_lock, flags);
-
+	flags = irq_flags;
 	sprintf(bnad->mbox_irq_name, "%s", BNAD_NAME);
 
 	/*
@@ -2902,23 +2902,20 @@
 {
 	struct net_device *netdev = bnad->netdev;
 
-	netdev->features |= NETIF_F_IPV6_CSUM;
-	netdev->features |= NETIF_F_TSO;
-	netdev->features |= NETIF_F_TSO6;
+	netdev->hw_features = NETIF_F_SG | NETIF_F_RXCSUM |
+		NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
+		NETIF_F_TSO | NETIF_F_TSO6 | NETIF_F_HW_VLAN_TX;
 
-	netdev->features |= NETIF_F_GRO;
-	pr_warn("bna: GRO enabled, using kernel stack GRO\n");
+	netdev->vlan_features = NETIF_F_SG | NETIF_F_HIGHDMA |
+		NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
+		NETIF_F_TSO | NETIF_F_TSO6;
 
-	netdev->features |= NETIF_F_SG | NETIF_F_IP_CSUM;
+	netdev->features |= netdev->hw_features |
+		NETIF_F_HW_VLAN_RX | NETIF_F_HW_VLAN_FILTER;
 
 	if (using_dac)
 		netdev->features |= NETIF_F_HIGHDMA;
 
-	netdev->features |=
-		NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX |
-		NETIF_F_HW_VLAN_FILTER;
-
-	netdev->vlan_features = netdev->features;
 	netdev->mem_start = bnad->mmio_start;
 	netdev->mem_end = bnad->mmio_start + bnad->mmio_len - 1;
 
@@ -2969,7 +2966,6 @@
 
 	bnad->txq_depth = BNAD_TXQ_DEPTH;
 	bnad->rxq_depth = BNAD_RXQ_DEPTH;
-	bnad->rx_csum = true;
 
 	bnad->tx_coalescing_timeo = BFI_TX_COALESCING_TIMEO;
 	bnad->rx_coalescing_timeo = BFI_RX_COALESCING_TIMEO;
diff -druN linux-2.6.39-libre/drivers/net/bna/bnad_ethtool.c linux-3.0-rc7-libre/drivers/net/bna/bnad_ethtool.c
--- linux-2.6.39-libre/drivers/net/bna/bnad_ethtool.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/bna/bnad_ethtool.c	2011-07-11 19:51:52.000000000 -0400
@@ -237,10 +237,10 @@
 	cmd->phy_address = 0;
 
 	if (netif_carrier_ok(netdev)) {
-		cmd->speed = SPEED_10000;
+		ethtool_cmd_speed_set(cmd, SPEED_10000);
 		cmd->duplex = DUPLEX_FULL;
 	} else {
-		cmd->speed = -1;
+		ethtool_cmd_speed_set(cmd, -1);
 		cmd->duplex = -1;
 	}
 	cmd->transceiver = XCVR_EXTERNAL;
@@ -256,7 +256,8 @@
 	/* 10G full duplex setting supported only */
 	if (cmd->autoneg == AUTONEG_ENABLE)
 		return -EOPNOTSUPP; else {
-		if ((cmd->speed == SPEED_10000) && (cmd->duplex == DUPLEX_FULL))
+		if ((ethtool_cmd_speed(cmd) == SPEED_10000)
+		    && (cmd->duplex == DUPLEX_FULL))
 			return 0;
 	}
 
@@ -806,61 +807,6 @@
 	return 0;
 }
 
-static u32
-bnad_get_rx_csum(struct net_device *netdev)
-{
-	u32 rx_csum;
-	struct bnad *bnad = netdev_priv(netdev);
-
-	rx_csum = bnad->rx_csum;
-	return rx_csum;
-}
-
-static int
-bnad_set_rx_csum(struct net_device *netdev, u32 rx_csum)
-{
-	struct bnad *bnad = netdev_priv(netdev);
-
-	mutex_lock(&bnad->conf_mutex);
-	bnad->rx_csum = rx_csum;
-	mutex_unlock(&bnad->conf_mutex);
-	return 0;
-}
-
-static int
-bnad_set_tx_csum(struct net_device *netdev, u32 tx_csum)
-{
-	struct bnad *bnad = netdev_priv(netdev);
-
-	mutex_lock(&bnad->conf_mutex);
-	if (tx_csum) {
-		netdev->features |= NETIF_F_IP_CSUM;
-		netdev->features |= NETIF_F_IPV6_CSUM;
-	} else {
-		netdev->features &= ~NETIF_F_IP_CSUM;
-		netdev->features &= ~NETIF_F_IPV6_CSUM;
-	}
-	mutex_unlock(&bnad->conf_mutex);
-	return 0;
-}
-
-static int
-bnad_set_tso(struct net_device *netdev, u32 tso)
-{
-	struct bnad *bnad = netdev_priv(netdev);
-
-	mutex_lock(&bnad->conf_mutex);
-	if (tso) {
-		netdev->features |= NETIF_F_TSO;
-		netdev->features |= NETIF_F_TSO6;
-	} else {
-		netdev->features &= ~NETIF_F_TSO;
-		netdev->features &= ~NETIF_F_TSO6;
-	}
-	mutex_unlock(&bnad->conf_mutex);
-	return 0;
-}
-
 static void
 bnad_get_strings(struct net_device *netdev, u32 stringset, u8 * string)
 {
@@ -1256,14 +1202,6 @@
 	.set_ringparam = bnad_set_ringparam,
 	.get_pauseparam = bnad_get_pauseparam,
 	.set_pauseparam = bnad_set_pauseparam,
-	.get_rx_csum = bnad_get_rx_csum,
-	.set_rx_csum = bnad_set_rx_csum,
-	.get_tx_csum = ethtool_op_get_tx_csum,
-	.set_tx_csum = bnad_set_tx_csum,
-	.get_sg = ethtool_op_get_sg,
-	.set_sg = ethtool_op_set_sg,
-	.get_tso = ethtool_op_get_tso,
-	.set_tso = bnad_set_tso,
 	.get_strings = bnad_get_strings,
 	.get_ethtool_stats = bnad_get_ethtool_stats,
 	.get_sset_count = bnad_get_sset_count
diff -druN linux-2.6.39-libre/drivers/net/bna/bnad.h linux-3.0-rc7-libre/drivers/net/bna/bnad.h
--- linux-2.6.39-libre/drivers/net/bna/bnad.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/bna/bnad.h	2011-07-11 19:51:52.000000000 -0400
@@ -237,8 +237,6 @@
 	struct bna_rx_config rx_config[BNAD_MAX_RXS];
 	struct bna_tx_config tx_config[BNAD_MAX_TXS];
 
-	u32		rx_csum;
-
 	void __iomem		*bar0;	/* BAR0 address */
 
 	struct bna bna;
diff -druN linux-2.6.39-libre/drivers/net/bna/bna_txrx.c linux-3.0-rc7-libre/drivers/net/bna/bna_txrx.c
--- linux-2.6.39-libre/drivers/net/bna/bna_txrx.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/bna/bna_txrx.c	2011-07-11 19:51:52.000000000 -0400
@@ -2229,14 +2229,11 @@
 bna_rit_create(struct bna_rx *rx)
 {
 	struct list_head	*qe_rxp;
-	struct bna *bna;
 	struct bna_rxp *rxp;
 	struct bna_rxq *q0 = NULL;
 	struct bna_rxq *q1 = NULL;
 	int offset;
 
-	bna = rx->bna;
-
 	offset = 0;
 	list_for_each(qe_rxp, &rx->rxp_q) {
 		rxp = (struct bna_rxp *)qe_rxp;
@@ -2830,7 +2827,7 @@
 	struct bna_mem_descr *dsqpt_mem;	/* s/w qpt for data */
 	struct bna_mem_descr *hpage_mem;	/* hdr page mem */
 	struct bna_mem_descr *dpage_mem;	/* data page mem */
-	int i, cpage_idx = 0, dpage_idx = 0, hpage_idx = 0, ret;
+	int i, cpage_idx = 0, dpage_idx = 0, hpage_idx = 0;
 	int dpage_count, hpage_count, rcb_idx;
 	struct bna_ib_config ibcfg;
 	/* Fail if we don't have enough RXPs, RXQs */
@@ -2924,7 +2921,7 @@
 		ibcfg.interpkt_timeo = BFI_RX_INTERPKT_TIMEO;
 		ibcfg.ctrl_flags = BFI_IB_CF_INT_ENABLE;
 
-		ret = bna_ib_config(rxp->cq.ib, &ibcfg);
+		bna_ib_config(rxp->cq.ib, &ibcfg);
 
 		/* Link rxqs to rxp */
 		_rxp_add_rxqs(rxp, q0, q1);
diff -druN linux-2.6.39-libre/drivers/net/bnx2.c linux-3.0-rc7-libre/drivers/net/bnx2.c
--- linux-2.6.39-libre/drivers/net/bnx2.c	2011-05-19 02:11:21.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/bnx2.c	2011-07-21 06:53:53.000000000 -0400
@@ -3170,7 +3170,7 @@
 		}
 
 		skb_checksum_none_assert(skb);
-		if (bp->rx_csum &&
+		if ((bp->dev->features & NETIF_F_RXCSUM) &&
 			(status & (L2_FHDR_STATUS_TCP_SEGMENT |
 			L2_FHDR_STATUS_UDP_DATAGRAM))) {
 
@@ -6692,17 +6692,16 @@
 
 	if (bp->autoneg & AUTONEG_SPEED) {
 		cmd->autoneg = AUTONEG_ENABLE;
-	}
-	else {
+	} else {
 		cmd->autoneg = AUTONEG_DISABLE;
 	}
 
 	if (netif_carrier_ok(dev)) {
-		cmd->speed = bp->line_speed;
+		ethtool_cmd_speed_set(cmd, bp->line_speed);
 		cmd->duplex = bp->duplex;
 	}
 	else {
-		cmd->speed = -1;
+		ethtool_cmd_speed_set(cmd, -1);
 		cmd->duplex = -1;
 	}
 	spin_unlock_bh(&bp->phy_lock);
@@ -6754,21 +6753,21 @@
 		advertising |= ADVERTISED_Autoneg;
 	}
 	else {
+		u32 speed = ethtool_cmd_speed(cmd);
 		if (cmd->port == PORT_FIBRE) {
-			if ((cmd->speed != SPEED_1000 &&
-			     cmd->speed != SPEED_2500) ||
+			if ((speed != SPEED_1000 &&
+			     speed != SPEED_2500) ||
 			    (cmd->duplex != DUPLEX_FULL))
 				goto err_out_unlock;
 
-			if (cmd->speed == SPEED_2500 &&
+			if (speed == SPEED_2500 &&
 			    !(bp->phy_flags & BNX2_PHY_FLAG_2_5G_CAPABLE))
 				goto err_out_unlock;
-		}
-		else if (cmd->speed == SPEED_1000 || cmd->speed == SPEED_2500)
+		} else if (speed == SPEED_1000 || speed == SPEED_2500)
 			goto err_out_unlock;
 
 		autoneg &= ~AUTONEG_SPEED;
-		req_line_speed = cmd->speed;
+		req_line_speed = speed;
 		req_duplex = cmd->duplex;
 		advertising = 0;
 	}
@@ -7185,38 +7184,6 @@
 	return 0;
 }
 
-static u32
-bnx2_get_rx_csum(struct net_device *dev)
-{
-	struct bnx2 *bp = netdev_priv(dev);
-
-	return bp->rx_csum;
-}
-
-static int
-bnx2_set_rx_csum(struct net_device *dev, u32 data)
-{
-	struct bnx2 *bp = netdev_priv(dev);
-
-	bp->rx_csum = data;
-	return 0;
-}
-
-static int
-bnx2_set_tso(struct net_device *dev, u32 data)
-{
-	struct bnx2 *bp = netdev_priv(dev);
-
-	if (data) {
-		dev->features |= NETIF_F_TSO | NETIF_F_TSO_ECN;
-		if (CHIP_NUM(bp) == CHIP_NUM_5709)
-			dev->features |= NETIF_F_TSO6;
-	} else
-		dev->features &= ~(NETIF_F_TSO | NETIF_F_TSO6 |
-				   NETIF_F_TSO_ECN);
-	return 0;
-}
-
 static struct {
 	char string[ETH_GSTRING_LEN];
 } bnx2_stats_str_arr[] = {
@@ -7491,82 +7458,74 @@
 }
 
 static int
-bnx2_phys_id(struct net_device *dev, u32 data)
+bnx2_set_phys_id(struct net_device *dev, enum ethtool_phys_id_state state)
 {
 	struct bnx2 *bp = netdev_priv(dev);
-	int i;
-	u32 save;
 
-	bnx2_set_power_state(bp, PCI_D0);
+	switch (state) {
+	case ETHTOOL_ID_ACTIVE:
+		bnx2_set_power_state(bp, PCI_D0);
 
-	if (data == 0)
-		data = 2;
+		bp->leds_save = REG_RD(bp, BNX2_MISC_CFG);
+		REG_WR(bp, BNX2_MISC_CFG, BNX2_MISC_CFG_LEDMODE_MAC);
+		return 1;	/* cycle on/off once per second */
 
-	save = REG_RD(bp, BNX2_MISC_CFG);
-	REG_WR(bp, BNX2_MISC_CFG, BNX2_MISC_CFG_LEDMODE_MAC);
+	case ETHTOOL_ID_ON:
+		REG_WR(bp, BNX2_EMAC_LED, BNX2_EMAC_LED_OVERRIDE |
+		       BNX2_EMAC_LED_1000MB_OVERRIDE |
+		       BNX2_EMAC_LED_100MB_OVERRIDE |
+		       BNX2_EMAC_LED_10MB_OVERRIDE |
+		       BNX2_EMAC_LED_TRAFFIC_OVERRIDE |
+		       BNX2_EMAC_LED_TRAFFIC);
+		break;
 
-	for (i = 0; i < (data * 2); i++) {
-		if ((i % 2) == 0) {
-			REG_WR(bp, BNX2_EMAC_LED, BNX2_EMAC_LED_OVERRIDE);
-		}
-		else {
-			REG_WR(bp, BNX2_EMAC_LED, BNX2_EMAC_LED_OVERRIDE |
-				BNX2_EMAC_LED_1000MB_OVERRIDE |
-				BNX2_EMAC_LED_100MB_OVERRIDE |
-				BNX2_EMAC_LED_10MB_OVERRIDE |
-				BNX2_EMAC_LED_TRAFFIC_OVERRIDE |
-				BNX2_EMAC_LED_TRAFFIC);
-		}
-		msleep_interruptible(500);
-		if (signal_pending(current))
-			break;
-	}
-	REG_WR(bp, BNX2_EMAC_LED, 0);
-	REG_WR(bp, BNX2_MISC_CFG, save);
+	case ETHTOOL_ID_OFF:
+		REG_WR(bp, BNX2_EMAC_LED, BNX2_EMAC_LED_OVERRIDE);
+		break;
 
-	if (!netif_running(dev))
-		bnx2_set_power_state(bp, PCI_D3hot);
+	case ETHTOOL_ID_INACTIVE:
+		REG_WR(bp, BNX2_EMAC_LED, 0);
+		REG_WR(bp, BNX2_MISC_CFG, bp->leds_save);
+
+		if (!netif_running(dev))
+			bnx2_set_power_state(bp, PCI_D3hot);
+		break;
+	}
 
 	return 0;
 }
 
-static int
-bnx2_set_tx_csum(struct net_device *dev, u32 data)
+static u32
+bnx2_fix_features(struct net_device *dev, u32 features)
 {
 	struct bnx2 *bp = netdev_priv(dev);
 
-	if (CHIP_NUM(bp) == CHIP_NUM_5709)
-		return ethtool_op_set_tx_ipv6_csum(dev, data);
-	else
-		return ethtool_op_set_tx_csum(dev, data);
+	if (!(bp->flags & BNX2_FLAG_CAN_KEEP_VLAN))
+		features |= NETIF_F_HW_VLAN_RX;
+
+	return features;
 }
 
 static int
-bnx2_set_flags(struct net_device *dev, u32 data)
+bnx2_set_features(struct net_device *dev, u32 features)
 {
 	struct bnx2 *bp = netdev_priv(dev);
-	int rc;
-
-	if (!(bp->flags & BNX2_FLAG_CAN_KEEP_VLAN) &&
-	    !(data & ETH_FLAG_RXVLAN))
-		return -EINVAL;
 
 	/* TSO with VLAN tag won't work with current firmware */
-	if (!(data & ETH_FLAG_TXVLAN))
-		return -EINVAL;
-
-	rc = ethtool_op_set_flags(dev, data, ETH_FLAG_RXHASH | ETH_FLAG_RXVLAN |
-				  ETH_FLAG_TXVLAN);
-	if (rc)
-		return rc;
+	if (features & NETIF_F_HW_VLAN_TX)
+		dev->vlan_features |= (dev->hw_features & NETIF_F_ALL_TSO);
+	else
+		dev->vlan_features &= ~NETIF_F_ALL_TSO;
 
-	if ((!!(data & ETH_FLAG_RXVLAN) !=
+	if ((!!(features & NETIF_F_HW_VLAN_RX) !=
 	    !!(bp->rx_mode & BNX2_EMAC_RX_MODE_KEEP_VLAN_TAG)) &&
 	    netif_running(dev)) {
 		bnx2_netif_stop(bp, false);
+		dev->features = features;
 		bnx2_set_rx_mode(dev);
 		bnx2_fw_sync(bp, BNX2_DRV_MSG_CODE_KEEP_VLAN_UPDATE, 0, 1);
 		bnx2_netif_start(bp, false);
+		return 1;
 	}
 
 	return 0;
@@ -7591,18 +7550,11 @@
 	.set_ringparam		= bnx2_set_ringparam,
 	.get_pauseparam		= bnx2_get_pauseparam,
 	.set_pauseparam		= bnx2_set_pauseparam,
-	.get_rx_csum		= bnx2_get_rx_csum,
-	.set_rx_csum		= bnx2_set_rx_csum,
-	.set_tx_csum		= bnx2_set_tx_csum,
-	.set_sg			= ethtool_op_set_sg,
-	.set_tso		= bnx2_set_tso,
 	.self_test		= bnx2_self_test,
 	.get_strings		= bnx2_get_strings,
-	.phys_id		= bnx2_phys_id,
+	.set_phys_id		= bnx2_set_phys_id,
 	.get_ethtool_stats	= bnx2_get_ethtool_stats,
 	.get_sset_count		= bnx2_get_sset_count,
-	.set_flags		= bnx2_set_flags,
-	.get_flags		= ethtool_op_get_flags,
 };
 
 /* Called with rtnl_lock */
@@ -8114,8 +8066,6 @@
 	bp->tx_ring_size = MAX_TX_DESC_CNT;
 	bnx2_set_rx_ring_size(bp, 255);
 
-	bp->rx_csum = 1;
-
 	bp->tx_quick_cons_trip_int = 2;
 	bp->tx_quick_cons_trip = 20;
 	bp->tx_ticks_int = 18;
@@ -8307,17 +8257,14 @@
 	.ndo_validate_addr	= eth_validate_addr,
 	.ndo_set_mac_address	= bnx2_change_mac_addr,
 	.ndo_change_mtu		= bnx2_change_mtu,
+	.ndo_fix_features	= bnx2_fix_features,
+	.ndo_set_features	= bnx2_set_features,
 	.ndo_tx_timeout		= bnx2_tx_timeout,
 #ifdef CONFIG_NET_POLL_CONTROLLER
 	.ndo_poll_controller	= poll_bnx2,
 #endif
 };
 
-static inline void vlan_features_add(struct net_device *dev, u32 flags)
-{
-	dev->vlan_features |= flags;
-}
-
 static int __devinit
 bnx2_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
 {
@@ -8357,20 +8304,17 @@
 	memcpy(dev->dev_addr, bp->mac_addr, 6);
 	memcpy(dev->perm_addr, bp->mac_addr, 6);
 
-	dev->features |= NETIF_F_IP_CSUM | NETIF_F_SG | NETIF_F_GRO |
-			 NETIF_F_RXHASH;
-	vlan_features_add(dev, NETIF_F_IP_CSUM | NETIF_F_SG);
-	if (CHIP_NUM(bp) == CHIP_NUM_5709) {
-		dev->features |= NETIF_F_IPV6_CSUM;
-		vlan_features_add(dev, NETIF_F_IPV6_CSUM);
-	}
-	dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
-	dev->features |= NETIF_F_TSO | NETIF_F_TSO_ECN;
-	vlan_features_add(dev, NETIF_F_TSO | NETIF_F_TSO_ECN);
-	if (CHIP_NUM(bp) == CHIP_NUM_5709) {
-		dev->features |= NETIF_F_TSO6;
-		vlan_features_add(dev, NETIF_F_TSO6);
-	}
+	dev->hw_features = NETIF_F_IP_CSUM | NETIF_F_SG |
+		NETIF_F_TSO | NETIF_F_TSO_ECN |
+		NETIF_F_RXHASH | NETIF_F_RXCSUM;
+
+	if (CHIP_NUM(bp) == CHIP_NUM_5709)
+		dev->hw_features |= NETIF_F_IPV6_CSUM | NETIF_F_TSO6;
+
+	dev->vlan_features = dev->hw_features;
+	dev->hw_features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
+	dev->features |= dev->hw_features;
+
 	if ((rc = register_netdev(dev))) {
 		dev_err(&pdev->dev, "Cannot register net device\n");
 		goto error;
diff -druN linux-2.6.39-libre/drivers/net/bnx2.h linux-3.0-rc7-libre/drivers/net/bnx2.h
--- linux-2.6.39-libre/drivers/net/bnx2.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/bnx2.h	2011-07-11 19:51:52.000000000 -0400
@@ -6754,8 +6754,6 @@
 	u32			rx_max_ring_idx;
 	u32			rx_max_pg_ring_idx;
 
-	u32			rx_csum;
-
 	/* TX constants */
 	int		tx_ring_size;
 	u32		tx_wake_thresh;
@@ -6922,6 +6920,7 @@
 	u8			num_tx_rings;
 	u8			num_rx_rings;
 
+	u32 			leds_save;
 	u32			idle_chk_status_idx;
 
 #ifdef BCM_CNIC
diff -druN linux-2.6.39-libre/drivers/net/bnx2x/bnx2x_cmn.c linux-3.0-rc7-libre/drivers/net/bnx2x/bnx2x_cmn.c
--- linux-2.6.39-libre/drivers/net/bnx2x/bnx2x_cmn.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/bnx2x/bnx2x_cmn.c	2011-07-11 19:51:52.000000000 -0400
@@ -1,6 +1,6 @@
 /* bnx2x_cmn.c: Broadcom Everest network driver.
  *
- * Copyright (c) 2007-2010 Broadcom Corporation
+ * Copyright (c) 2007-2011 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
@@ -21,12 +21,56 @@
 #include <net/ipv6.h>
 #include <net/ip6_checksum.h>
 #include <linux/firmware.h>
+#include <linux/prefetch.h>
 #include "bnx2x_cmn.h"
 
 #include "bnx2x_init.h"
 
 static int bnx2x_setup_irqs(struct bnx2x *bp);
 
+/**
+ * bnx2x_bz_fp - zero content of the fastpath structure.
+ *
+ * @bp:		driver handle
+ * @index:	fastpath index to be zeroed
+ *
+ * Makes sure the contents of the bp->fp[index].napi is kept
+ * intact.
+ */
+static inline void bnx2x_bz_fp(struct bnx2x *bp, int index)
+{
+	struct bnx2x_fastpath *fp = &bp->fp[index];
+	struct napi_struct orig_napi = fp->napi;
+	/* bzero bnx2x_fastpath contents */
+	memset(fp, 0, sizeof(*fp));
+
+	/* Restore the NAPI object as it has been already initialized */
+	fp->napi = orig_napi;
+}
+
+/**
+ * bnx2x_move_fp - move content of the fastpath structure.
+ *
+ * @bp:		driver handle
+ * @from:	source FP index
+ * @to:		destination FP index
+ *
+ * Makes sure the contents of the bp->fp[to].napi is kept
+ * intact.
+ */
+static inline void bnx2x_move_fp(struct bnx2x *bp, int from, int to)
+{
+	struct bnx2x_fastpath *from_fp = &bp->fp[from];
+	struct bnx2x_fastpath *to_fp = &bp->fp[to];
+	struct napi_struct orig_napi = to_fp->napi;
+	/* Move bnx2x_fastpath contents */
+	memcpy(to_fp, from_fp, sizeof(*to_fp));
+	to_fp->index = to;
+
+	/* Restore the NAPI object as it has been already initialized */
+	to_fp->napi = orig_napi;
+}
+
 /* free skb in the packet ring at pos idx
  * return idx of last bd freed
  */
@@ -87,7 +131,7 @@
 
 	/* release skb */
 	WARN_ON(!skb);
-	dev_kfree_skb(skb);
+	dev_kfree_skb_any(skb);
 	tx_buf->first_bd = 0;
 	tx_buf->skb = NULL;
 
@@ -265,13 +309,15 @@
  */
 #define TPA_TSTAMP_OPT_LEN	12
 /**
- * Calculate the approximate value of the MSS for this
- * aggregation using the first packet of it.
+ * bnx2x_set_lro_mss - calculate the approximate value of the MSS
  *
- * @param bp
- * @param parsing_flags Parsing flags from the START CQE
- * @param len_on_bd Total length of the first packet for the
- *		     aggregation.
+ * @bp:			driver handle
+ * @parsing_flags:	parsing flags from the START CQE
+ * @len_on_bd:		total length of the first packet for the
+ *			aggregation.
+ *
+ * Approximate value of the MSS for this aggregation calculated using
+ * the first packet of it.
  */
 static inline u16 bnx2x_set_lro_mss(struct bnx2x *bp, u16 parsing_flags,
 				    u16 len_on_bd)
@@ -419,7 +465,7 @@
 		} else {
 			DP(NETIF_MSG_RX_STATUS, "Failed to allocate new pages"
 			   " - dropping packet!\n");
-			dev_kfree_skb(skb);
+			dev_kfree_skb_any(skb);
 		}
 
 
@@ -640,7 +686,7 @@
 
 			skb_checksum_none_assert(skb);
 
-			if (bp->rx_csum) {
+			if (bp->dev->features & NETIF_F_RXCSUM) {
 				if (likely(BNX2X_RX_CSUM_OK(cqe)))
 					skb->ip_summed = CHECKSUM_UNNECESSARY;
 				else
@@ -758,35 +804,119 @@
 	return line_speed;
 }
 
+/**
+ * bnx2x_fill_report_data - fill link report data to report
+ *
+ * @bp:		driver handle
+ * @data:	link state to update
+ *
+ * It uses a none-atomic bit operations because is called under the mutex.
+ */
+static inline void bnx2x_fill_report_data(struct bnx2x *bp,
+					  struct bnx2x_link_report_data *data)
+{
+	u16 line_speed = bnx2x_get_mf_speed(bp);
+
+	memset(data, 0, sizeof(*data));
+
+	/* Fill the report data: efective line speed */
+	data->line_speed = line_speed;
+
+	/* Link is down */
+	if (!bp->link_vars.link_up || (bp->flags & MF_FUNC_DIS))
+		__set_bit(BNX2X_LINK_REPORT_LINK_DOWN,
+			  &data->link_report_flags);
+
+	/* Full DUPLEX */
+	if (bp->link_vars.duplex == DUPLEX_FULL)
+		__set_bit(BNX2X_LINK_REPORT_FD, &data->link_report_flags);
+
+	/* Rx Flow Control is ON */
+	if (bp->link_vars.flow_ctrl & BNX2X_FLOW_CTRL_RX)
+		__set_bit(BNX2X_LINK_REPORT_RX_FC_ON, &data->link_report_flags);
+
+	/* Tx Flow Control is ON */
+	if (bp->link_vars.flow_ctrl & BNX2X_FLOW_CTRL_TX)
+		__set_bit(BNX2X_LINK_REPORT_TX_FC_ON, &data->link_report_flags);
+}
+
+/**
+ * bnx2x_link_report - report link status to OS.
+ *
+ * @bp:		driver handle
+ *
+ * Calls the __bnx2x_link_report() under the same locking scheme
+ * as a link/PHY state managing code to ensure a consistent link
+ * reporting.
+ */
+
 void bnx2x_link_report(struct bnx2x *bp)
 {
-	if (bp->flags & MF_FUNC_DIS) {
-		netif_carrier_off(bp->dev);
-		netdev_err(bp->dev, "NIC Link is Down\n");
-		return;
-	}
+	bnx2x_acquire_phy_lock(bp);
+	__bnx2x_link_report(bp);
+	bnx2x_release_phy_lock(bp);
+}
 
-	if (bp->link_vars.link_up) {
-		u16 line_speed;
+/**
+ * __bnx2x_link_report - report link status to OS.
+ *
+ * @bp:		driver handle
+ *
+ * None atomic inmlementation.
+ * Should be called under the phy_lock.
+ */
+void __bnx2x_link_report(struct bnx2x *bp)
+{
+	struct bnx2x_link_report_data cur_data;
 
-		if (bp->state == BNX2X_STATE_OPEN)
-			netif_carrier_on(bp->dev);
-		netdev_info(bp->dev, "NIC Link is Up, ");
+	/* reread mf_cfg */
+	if (!CHIP_IS_E1(bp))
+		bnx2x_read_mf_cfg(bp);
 
-		line_speed = bnx2x_get_mf_speed(bp);
+	/* Read the current link report info */
+	bnx2x_fill_report_data(bp, &cur_data);
 
-		pr_cont("%d Mbps ", line_speed);
+	/* Don't report link down or exactly the same link status twice */
+	if (!memcmp(&cur_data, &bp->last_reported_link, sizeof(cur_data)) ||
+	    (test_bit(BNX2X_LINK_REPORT_LINK_DOWN,
+		      &bp->last_reported_link.link_report_flags) &&
+	     test_bit(BNX2X_LINK_REPORT_LINK_DOWN,
+		      &cur_data.link_report_flags)))
+		return;
 
-		if (bp->link_vars.duplex == DUPLEX_FULL)
+	bp->link_cnt++;
+
+	/* We are going to report a new link parameters now -
+	 * remember the current data for the next time.
+	 */
+	memcpy(&bp->last_reported_link, &cur_data, sizeof(cur_data));
+
+	if (test_bit(BNX2X_LINK_REPORT_LINK_DOWN,
+		     &cur_data.link_report_flags)) {
+		netif_carrier_off(bp->dev);
+		netdev_err(bp->dev, "NIC Link is Down\n");
+		return;
+	} else {
+		netif_carrier_on(bp->dev);
+		netdev_info(bp->dev, "NIC Link is Up, ");
+		pr_cont("%d Mbps ", cur_data.line_speed);
+
+		if (test_and_clear_bit(BNX2X_LINK_REPORT_FD,
+				       &cur_data.link_report_flags))
 			pr_cont("full duplex");
 		else
 			pr_cont("half duplex");
 
-		if (bp->link_vars.flow_ctrl != BNX2X_FLOW_CTRL_NONE) {
-			if (bp->link_vars.flow_ctrl & BNX2X_FLOW_CTRL_RX) {
+		/* Handle the FC at the end so that only these flags would be
+		 * possibly set. This way we may easily check if there is no FC
+		 * enabled.
+		 */
+		if (cur_data.link_report_flags) {
+			if (test_bit(BNX2X_LINK_REPORT_RX_FC_ON,
+				     &cur_data.link_report_flags)) {
 				pr_cont(", receive ");
-				if (bp->link_vars.flow_ctrl &
-				    BNX2X_FLOW_CTRL_TX)
+				if (test_bit(BNX2X_LINK_REPORT_TX_FC_ON,
+				     &cur_data.link_report_flags))
 					pr_cont("& transmit ");
 			} else {
 				pr_cont(", transmit ");
@@ -794,62 +924,9 @@
 			pr_cont("flow control ON");
 		}
 		pr_cont("\n");
-
-	} else { /* link_down */
-		netif_carrier_off(bp->dev);
-		netdev_err(bp->dev, "NIC Link is Down\n");
 	}
 }
 
-/* Returns the number of actually allocated BDs */
-static inline int bnx2x_alloc_rx_bds(struct bnx2x_fastpath *fp,
-				      int rx_ring_size)
-{
-	struct bnx2x *bp = fp->bp;
-	u16 ring_prod, cqe_ring_prod;
-	int i;
-
-	fp->rx_comp_cons = 0;
-	cqe_ring_prod = ring_prod = 0;
-	for (i = 0; i < rx_ring_size; i++) {
-		if (bnx2x_alloc_rx_skb(bp, fp, ring_prod) < 0) {
-			BNX2X_ERR("was only able to allocate "
-				  "%d rx skbs on queue[%d]\n", i, fp->index);
-			fp->eth_q_stats.rx_skb_alloc_failed++;
-			break;
-		}
-		ring_prod = NEXT_RX_IDX(ring_prod);
-		cqe_ring_prod = NEXT_RCQ_IDX(cqe_ring_prod);
-		WARN_ON(ring_prod <= i);
-	}
-
-	fp->rx_bd_prod = ring_prod;
-	/* Limit the CQE producer by the CQE ring size */
-	fp->rx_comp_prod = min_t(u16, NUM_RCQ_RINGS*RCQ_DESC_CNT,
-			       cqe_ring_prod);
-	fp->rx_pkt = fp->rx_calls = 0;
-
-	return i;
-}
-
-static inline void bnx2x_alloc_rx_bd_ring(struct bnx2x_fastpath *fp)
-{
-	struct bnx2x *bp = fp->bp;
-	int rx_ring_size = bp->rx_ring_size ? bp->rx_ring_size :
-					      MAX_RX_AVAIL/bp->num_queues;
-
-	rx_ring_size = max_t(int, MIN_RX_AVAIL, rx_ring_size);
-
-	bnx2x_alloc_rx_bds(fp, rx_ring_size);
-
-	/* Warning!
-	 * this will generate an interrupt (to the TSTORM)
-	 * must only be done after chip is initialized
-	 */
-	bnx2x_update_rx_prod(bp, fp, fp->rx_bd_prod, fp->rx_comp_prod,
-			     fp->rx_sge_prod);
-}
-
 void bnx2x_init_rx_rings(struct bnx2x *bp)
 {
 	int func = BP_FUNC(bp);
@@ -858,6 +935,7 @@
 	u16 ring_prod;
 	int i, j;
 
+	/* Allocate TPA resources */
 	for_each_rx_queue(bp, j) {
 		struct bnx2x_fastpath *fp = &bp->fp[j];
 
@@ -865,6 +943,7 @@
 		   "mtu %d  rx_buf_size %d\n", bp->dev->mtu, fp->rx_buf_size);
 
 		if (!fp->disable_tpa) {
+			/* Fill the per-aggregation pool */
 			for (i = 0; i < max_agg_queues; i++) {
 				fp->tpa_pool[i].skb =
 				   netdev_alloc_skb(bp->dev, fp->rx_buf_size);
@@ -919,13 +998,13 @@
 
 		fp->rx_bd_cons = 0;
 
-		bnx2x_set_next_page_rx_bd(fp);
-
-		/* CQ ring */
-		bnx2x_set_next_page_rx_cq(fp);
-
-		/* Allocate BDs and initialize BD ring */
-		bnx2x_alloc_rx_bd_ring(fp);
+		/* Activate BD ring */
+		/* Warning!
+		 * this will generate an interrupt (to the TSTORM)
+		 * must only be done after chip is initialized
+		 */
+		bnx2x_update_rx_prod(bp, fp, fp->rx_bd_prod, fp->rx_comp_prod,
+				     fp->rx_sge_prod);
 
 		if (j != 0)
 			continue;
@@ -959,27 +1038,40 @@
 	}
 }
 
+static void bnx2x_free_rx_bds(struct bnx2x_fastpath *fp)
+{
+	struct bnx2x *bp = fp->bp;
+	int i;
+
+	/* ring wasn't allocated */
+	if (fp->rx_buf_ring == NULL)
+		return;
+
+	for (i = 0; i < NUM_RX_BD; i++) {
+		struct sw_rx_bd *rx_buf = &fp->rx_buf_ring[i];
+		struct sk_buff *skb = rx_buf->skb;
+
+		if (skb == NULL)
+			continue;
+
+		dma_unmap_single(&bp->pdev->dev,
+				 dma_unmap_addr(rx_buf, mapping),
+				 fp->rx_buf_size, DMA_FROM_DEVICE);
+
+		rx_buf->skb = NULL;
+		dev_kfree_skb(skb);
+	}
+}
+
 static void bnx2x_free_rx_skbs(struct bnx2x *bp)
 {
-	int i, j;
+	int j;
 
 	for_each_rx_queue(bp, j) {
 		struct bnx2x_fastpath *fp = &bp->fp[j];
 
-		for (i = 0; i < NUM_RX_BD; i++) {
-			struct sw_rx_bd *rx_buf = &fp->rx_buf_ring[i];
-			struct sk_buff *skb = rx_buf->skb;
-
-			if (skb == NULL)
-				continue;
-
-			dma_unmap_single(&bp->pdev->dev,
-					 dma_unmap_addr(rx_buf, mapping),
-					 fp->rx_buf_size, DMA_FROM_DEVICE);
+		bnx2x_free_rx_bds(fp);
 
-			rx_buf->skb = NULL;
-			dev_kfree_skb(skb);
-		}
 		if (!fp->disable_tpa)
 			bnx2x_free_tpa_pool(bp, fp, CHIP_IS_E1(bp) ?
 					    ETH_MAX_AGGREGATION_QUEUES_E1 :
@@ -1345,29 +1437,47 @@
 
 	bp->state = BNX2X_STATE_OPENING_WAIT4_LOAD;
 
+	/* Set the initial link reported state to link down */
+	bnx2x_acquire_phy_lock(bp);
+	memset(&bp->last_reported_link, 0, sizeof(bp->last_reported_link));
+	__set_bit(BNX2X_LINK_REPORT_LINK_DOWN,
+		&bp->last_reported_link.link_report_flags);
+	bnx2x_release_phy_lock(bp);
+
 	/* must be called before memory allocation and HW init */
 	bnx2x_ilt_set_info(bp);
 
+	/* zero fastpath structures preserving invariants like napi which are
+	 * allocated only once
+	 */
+	for_each_queue(bp, i)
+		bnx2x_bz_fp(bp, i);
+
 	/* Set the receive queues buffer size */
 	bnx2x_set_rx_buf_size(bp);
 
+	for_each_queue(bp, i)
+		bnx2x_fp(bp, i, disable_tpa) =
+					((bp->flags & TPA_ENABLE_FLAG) == 0);
+
+#ifdef BCM_CNIC
+	/* We don't want TPA on FCoE L2 ring */
+	bnx2x_fcoe(bp, disable_tpa) = 1;
+#endif
+
 	if (bnx2x_alloc_mem(bp))
 		return -ENOMEM;
 
+	/* As long as bnx2x_alloc_mem() may possibly update
+	 * bp->num_queues, bnx2x_set_real_num_queues() should always
+	 * come after it.
+	 */
 	rc = bnx2x_set_real_num_queues(bp);
 	if (rc) {
 		BNX2X_ERR("Unable to set real_num_queues\n");
 		goto load_error0;
 	}
 
-	for_each_queue(bp, i)
-		bnx2x_fp(bp, i, disable_tpa) =
-					((bp->flags & TPA_ENABLE_FLAG) == 0);
-
-#ifdef BCM_CNIC
-	/* We don't want TPA on FCoE L2 ring */
-	bnx2x_fcoe(bp, disable_tpa) = 1;
-#endif
 	bnx2x_napi_enable(bp);
 
 	/* Send LOAD_REQUEST command to MCP
@@ -1976,12 +2086,11 @@
 }
 
 /**
- * Update PBD in GSO case.
+ * bnx2x_set_pbd_gso - update PBD in GSO case.
  *
- * @param skb
- * @param tx_start_bd
- * @param pbd
- * @param xmit_type
+ * @skb:	packet skb
+ * @pbd:	parse BD
+ * @xmit_type:	xmit flags
  */
 static inline void bnx2x_set_pbd_gso(struct sk_buff *skb,
 				     struct eth_tx_parse_bd_e1x *pbd,
@@ -2008,13 +2117,14 @@
 }
 
 /**
+ * bnx2x_set_pbd_csum_e2 - update PBD with checksum and return header length
  *
- * @param skb
- * @param tx_start_bd
- * @param pbd_e2
- * @param xmit_type
+ * @bp:			driver handle
+ * @skb:		packet skb
+ * @parsing_data:	data to be updated
+ * @xmit_type:		xmit flags
  *
- * @return header len
+ * 57712 related
  */
 static inline  u8 bnx2x_set_pbd_csum_e2(struct bnx2x *bp, struct sk_buff *skb,
 	u32 *parsing_data, u32 xmit_type)
@@ -2039,13 +2149,12 @@
 }
 
 /**
+ * bnx2x_set_pbd_csum - update PBD with checksum and return header length
  *
- * @param skb
- * @param tx_start_bd
- * @param pbd
- * @param xmit_type
- *
- * @return Header length
+ * @bp:		driver handle
+ * @skb:	packet skb
+ * @pbd:	parse BD to be updated
+ * @xmit_type:	xmit flags
  */
 static inline u8 bnx2x_set_pbd_csum(struct bnx2x *bp, struct sk_buff *skb,
 	struct eth_tx_parse_bd_e1x *pbd,
@@ -2393,6 +2502,232 @@
 	return 0;
 }
 
+static void bnx2x_free_fp_mem_at(struct bnx2x *bp, int fp_index)
+{
+	union host_hc_status_block *sb = &bnx2x_fp(bp, fp_index, status_blk);
+	struct bnx2x_fastpath *fp = &bp->fp[fp_index];
+
+	/* Common */
+#ifdef BCM_CNIC
+	if (IS_FCOE_IDX(fp_index)) {
+		memset(sb, 0, sizeof(union host_hc_status_block));
+		fp->status_blk_mapping = 0;
+
+	} else {
+#endif
+		/* status blocks */
+		if (CHIP_IS_E2(bp))
+			BNX2X_PCI_FREE(sb->e2_sb,
+				       bnx2x_fp(bp, fp_index,
+						status_blk_mapping),
+				       sizeof(struct host_hc_status_block_e2));
+		else
+			BNX2X_PCI_FREE(sb->e1x_sb,
+				       bnx2x_fp(bp, fp_index,
+						status_blk_mapping),
+				       sizeof(struct host_hc_status_block_e1x));
+#ifdef BCM_CNIC
+	}
+#endif
+	/* Rx */
+	if (!skip_rx_queue(bp, fp_index)) {
+		bnx2x_free_rx_bds(fp);
+
+		/* fastpath rx rings: rx_buf rx_desc rx_comp */
+		BNX2X_FREE(bnx2x_fp(bp, fp_index, rx_buf_ring));
+		BNX2X_PCI_FREE(bnx2x_fp(bp, fp_index, rx_desc_ring),
+			       bnx2x_fp(bp, fp_index, rx_desc_mapping),
+			       sizeof(struct eth_rx_bd) * NUM_RX_BD);
+
+		BNX2X_PCI_FREE(bnx2x_fp(bp, fp_index, rx_comp_ring),
+			       bnx2x_fp(bp, fp_index, rx_comp_mapping),
+			       sizeof(struct eth_fast_path_rx_cqe) *
+			       NUM_RCQ_BD);
+
+		/* SGE ring */
+		BNX2X_FREE(bnx2x_fp(bp, fp_index, rx_page_ring));
+		BNX2X_PCI_FREE(bnx2x_fp(bp, fp_index, rx_sge_ring),
+			       bnx2x_fp(bp, fp_index, rx_sge_mapping),
+			       BCM_PAGE_SIZE * NUM_RX_SGE_PAGES);
+	}
+
+	/* Tx */
+	if (!skip_tx_queue(bp, fp_index)) {
+		/* fastpath tx rings: tx_buf tx_desc */
+		BNX2X_FREE(bnx2x_fp(bp, fp_index, tx_buf_ring));
+		BNX2X_PCI_FREE(bnx2x_fp(bp, fp_index, tx_desc_ring),
+			       bnx2x_fp(bp, fp_index, tx_desc_mapping),
+			       sizeof(union eth_tx_bd_types) * NUM_TX_BD);
+	}
+	/* end of fastpath */
+}
+
+void bnx2x_free_fp_mem(struct bnx2x *bp)
+{
+	int i;
+	for_each_queue(bp, i)
+		bnx2x_free_fp_mem_at(bp, i);
+}
+
+static inline void set_sb_shortcuts(struct bnx2x *bp, int index)
+{
+	union host_hc_status_block status_blk = bnx2x_fp(bp, index, status_blk);
+	if (CHIP_IS_E2(bp)) {
+		bnx2x_fp(bp, index, sb_index_values) =
+			(__le16 *)status_blk.e2_sb->sb.index_values;
+		bnx2x_fp(bp, index, sb_running_index) =
+			(__le16 *)status_blk.e2_sb->sb.running_index;
+	} else {
+		bnx2x_fp(bp, index, sb_index_values) =
+			(__le16 *)status_blk.e1x_sb->sb.index_values;
+		bnx2x_fp(bp, index, sb_running_index) =
+			(__le16 *)status_blk.e1x_sb->sb.running_index;
+	}
+}
+
+static int bnx2x_alloc_fp_mem_at(struct bnx2x *bp, int index)
+{
+	union host_hc_status_block *sb;
+	struct bnx2x_fastpath *fp = &bp->fp[index];
+	int ring_size = 0;
+
+	/* if rx_ring_size specified - use it */
+	int rx_ring_size = bp->rx_ring_size ? bp->rx_ring_size :
+			   MAX_RX_AVAIL/bp->num_queues;
+
+	/* allocate at least number of buffers required by FW */
+	rx_ring_size = max_t(int, fp->disable_tpa ? MIN_RX_SIZE_NONTPA :
+						    MIN_RX_SIZE_TPA,
+				  rx_ring_size);
+
+	bnx2x_fp(bp, index, bp) = bp;
+	bnx2x_fp(bp, index, index) = index;
+
+	/* Common */
+	sb = &bnx2x_fp(bp, index, status_blk);
+#ifdef BCM_CNIC
+	if (!IS_FCOE_IDX(index)) {
+#endif
+		/* status blocks */
+		if (CHIP_IS_E2(bp))
+			BNX2X_PCI_ALLOC(sb->e2_sb,
+				&bnx2x_fp(bp, index, status_blk_mapping),
+				sizeof(struct host_hc_status_block_e2));
+		else
+			BNX2X_PCI_ALLOC(sb->e1x_sb,
+				&bnx2x_fp(bp, index, status_blk_mapping),
+			    sizeof(struct host_hc_status_block_e1x));
+#ifdef BCM_CNIC
+	}
+#endif
+	set_sb_shortcuts(bp, index);
+
+	/* Tx */
+	if (!skip_tx_queue(bp, index)) {
+		/* fastpath tx rings: tx_buf tx_desc */
+		BNX2X_ALLOC(bnx2x_fp(bp, index, tx_buf_ring),
+				sizeof(struct sw_tx_bd) * NUM_TX_BD);
+		BNX2X_PCI_ALLOC(bnx2x_fp(bp, index, tx_desc_ring),
+				&bnx2x_fp(bp, index, tx_desc_mapping),
+				sizeof(union eth_tx_bd_types) * NUM_TX_BD);
+	}
+
+	/* Rx */
+	if (!skip_rx_queue(bp, index)) {
+		/* fastpath rx rings: rx_buf rx_desc rx_comp */
+		BNX2X_ALLOC(bnx2x_fp(bp, index, rx_buf_ring),
+				sizeof(struct sw_rx_bd) * NUM_RX_BD);
+		BNX2X_PCI_ALLOC(bnx2x_fp(bp, index, rx_desc_ring),
+				&bnx2x_fp(bp, index, rx_desc_mapping),
+				sizeof(struct eth_rx_bd) * NUM_RX_BD);
+
+		BNX2X_PCI_ALLOC(bnx2x_fp(bp, index, rx_comp_ring),
+				&bnx2x_fp(bp, index, rx_comp_mapping),
+				sizeof(struct eth_fast_path_rx_cqe) *
+				NUM_RCQ_BD);
+
+		/* SGE ring */
+		BNX2X_ALLOC(bnx2x_fp(bp, index, rx_page_ring),
+				sizeof(struct sw_rx_page) * NUM_RX_SGE);
+		BNX2X_PCI_ALLOC(bnx2x_fp(bp, index, rx_sge_ring),
+				&bnx2x_fp(bp, index, rx_sge_mapping),
+				BCM_PAGE_SIZE * NUM_RX_SGE_PAGES);
+		/* RX BD ring */
+		bnx2x_set_next_page_rx_bd(fp);
+
+		/* CQ ring */
+		bnx2x_set_next_page_rx_cq(fp);
+
+		/* BDs */
+		ring_size = bnx2x_alloc_rx_bds(fp, rx_ring_size);
+		if (ring_size < rx_ring_size)
+			goto alloc_mem_err;
+	}
+
+	return 0;
+
+/* handles low memory cases */
+alloc_mem_err:
+	BNX2X_ERR("Unable to allocate full memory for queue %d (size %d)\n",
+						index, ring_size);
+	/* FW will drop all packets if queue is not big enough,
+	 * In these cases we disable the queue
+	 * Min size diferent for TPA and non-TPA queues
+	 */
+	if (ring_size < (fp->disable_tpa ?
+				MIN_RX_SIZE_NONTPA : MIN_RX_SIZE_TPA)) {
+			/* release memory allocated for this queue */
+			bnx2x_free_fp_mem_at(bp, index);
+			return -ENOMEM;
+	}
+	return 0;
+}
+
+int bnx2x_alloc_fp_mem(struct bnx2x *bp)
+{
+	int i;
+
+	/**
+	 * 1. Allocate FP for leading - fatal if error
+	 * 2. {CNIC} Allocate FCoE FP - fatal if error
+	 * 3. Allocate RSS - fix number of queues if error
+	 */
+
+	/* leading */
+	if (bnx2x_alloc_fp_mem_at(bp, 0))
+		return -ENOMEM;
+#ifdef BCM_CNIC
+	/* FCoE */
+	if (bnx2x_alloc_fp_mem_at(bp, FCOE_IDX))
+		return -ENOMEM;
+#endif
+	/* RSS */
+	for_each_nondefault_eth_queue(bp, i)
+		if (bnx2x_alloc_fp_mem_at(bp, i))
+			break;
+
+	/* handle memory failures */
+	if (i != BNX2X_NUM_ETH_QUEUES(bp)) {
+		int delta = BNX2X_NUM_ETH_QUEUES(bp) - i;
+
+		WARN_ON(delta < 0);
+#ifdef BCM_CNIC
+		/**
+		 * move non eth FPs next to last eth FP
+		 * must be done in that order
+		 * FCOE_IDX < FWD_IDX < OOO_IDX
+		 */
+
+		/* move FCoE fp */
+		bnx2x_move_fp(bp, FCOE_IDX, FCOE_IDX - delta);
+#endif
+		bp->num_queues -= delta;
+		BNX2X_ERR("Adjusted num of queues from %d to %d\n",
+			  bp->num_queues + delta, bp->num_queues);
+	}
+
+	return 0;
+}
 
 static int bnx2x_setup_irqs(struct bnx2x *bp)
 {
@@ -2457,11 +2792,21 @@
 
 }
 
+static int bnx2x_reload_if_running(struct net_device *dev)
+{
+	struct bnx2x *bp = netdev_priv(dev);
+
+	if (unlikely(!netif_running(dev)))
+		return 0;
+
+	bnx2x_nic_unload(bp, UNLOAD_NORMAL);
+	return bnx2x_nic_load(bp, LOAD_NORMAL);
+}
+
 /* called with rtnl_lock */
 int bnx2x_change_mtu(struct net_device *dev, int new_mtu)
 {
 	struct bnx2x *bp = netdev_priv(dev);
-	int rc = 0;
 
 	if (bp->recovery_state != BNX2X_RECOVERY_DONE) {
 		printk(KERN_ERR "Handling parity error recovery. Try again later\n");
@@ -2478,12 +2823,55 @@
 	 */
 	dev->mtu = new_mtu;
 
-	if (netif_running(dev)) {
-		bnx2x_nic_unload(bp, UNLOAD_NORMAL);
-		rc = bnx2x_nic_load(bp, LOAD_NORMAL);
+	return bnx2x_reload_if_running(dev);
+}
+
+u32 bnx2x_fix_features(struct net_device *dev, u32 features)
+{
+	struct bnx2x *bp = netdev_priv(dev);
+
+	/* TPA requires Rx CSUM offloading */
+	if (!(features & NETIF_F_RXCSUM) || bp->disable_tpa)
+		features &= ~NETIF_F_LRO;
+
+	return features;
+}
+
+int bnx2x_set_features(struct net_device *dev, u32 features)
+{
+	struct bnx2x *bp = netdev_priv(dev);
+	u32 flags = bp->flags;
+	bool bnx2x_reload = false;
+
+	if (features & NETIF_F_LRO)
+		flags |= TPA_ENABLE_FLAG;
+	else
+		flags &= ~TPA_ENABLE_FLAG;
+
+	if (features & NETIF_F_LOOPBACK) {
+		if (bp->link_params.loopback_mode != LOOPBACK_BMAC) {
+			bp->link_params.loopback_mode = LOOPBACK_BMAC;
+			bnx2x_reload = true;
+		}
+	} else {
+		if (bp->link_params.loopback_mode != LOOPBACK_NONE) {
+			bp->link_params.loopback_mode = LOOPBACK_NONE;
+			bnx2x_reload = true;
+		}
 	}
 
-	return rc;
+	if (flags ^ bp->flags) {
+		bp->flags = flags;
+		bnx2x_reload = true;
+	}
+
+	if (bnx2x_reload) {
+		if (bp->recovery_state == BNX2X_RECOVERY_DONE)
+			return bnx2x_reload_if_running(dev);
+		/* else: bnx2x_nic_load() will be called at end of recovery */
+	}
+
+	return 0;
 }
 
 void bnx2x_tx_timeout(struct net_device *dev)
diff -druN linux-2.6.39-libre/drivers/net/bnx2x/bnx2x_cmn.h linux-3.0-rc7-libre/drivers/net/bnx2x/bnx2x_cmn.h
--- linux-2.6.39-libre/drivers/net/bnx2x/bnx2x_cmn.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/bnx2x/bnx2x_cmn.h	2011-07-11 19:51:52.000000000 -0400
@@ -1,6 +1,6 @@
 /* bnx2x_cmn.h: Broadcom Everest network driver.
  *
- * Copyright (c) 2007-2010 Broadcom Corporation
+ * Copyright (c) 2007-2011 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
@@ -25,260 +25,277 @@
 
 extern int num_queues;
 
+/************************ Macros ********************************/
+#define BNX2X_PCI_FREE(x, y, size) \
+	do { \
+		if (x) { \
+			dma_free_coherent(&bp->pdev->dev, size, (void *)x, y); \
+			x = NULL; \
+			y = 0; \
+		} \
+	} while (0)
+
+#define BNX2X_FREE(x) \
+	do { \
+		if (x) { \
+			kfree((void *)x); \
+			x = NULL; \
+		} \
+	} while (0)
+
+#define BNX2X_PCI_ALLOC(x, y, size) \
+	do { \
+		x = dma_alloc_coherent(&bp->pdev->dev, size, y, GFP_KERNEL); \
+		if (x == NULL) \
+			goto alloc_mem_err; \
+		memset((void *)x, 0, size); \
+	} while (0)
+
+#define BNX2X_ALLOC(x, size) \
+	do { \
+		x = kzalloc(size, GFP_KERNEL); \
+		if (x == NULL) \
+			goto alloc_mem_err; \
+	} while (0)
+
 /*********************** Interfaces ****************************
  *  Functions that need to be implemented by each driver version
  */
 
 /**
- * Initialize link parameters structure variables.
- *
- * @param bp
- * @param load_mode
+ * bnx2x_initial_phy_init - initialize link parameters structure variables.
  *
- * @return u8
+ * @bp:		driver handle
+ * @load_mode:	current mode
  */
 u8 bnx2x_initial_phy_init(struct bnx2x *bp, int load_mode);
 
 /**
- * Configure hw according to link parameters structure.
+ * bnx2x_link_set - configure hw according to link parameters structure.
  *
- * @param bp
+ * @bp:		driver handle
  */
 void bnx2x_link_set(struct bnx2x *bp);
 
 /**
- * Query link status
+ * bnx2x_link_test - query link status.
  *
- * @param bp
- * @param is_serdes
+ * @bp:		driver handle
+ * @is_serdes:	bool
  *
- * @return 0 - link is UP
+ * Returns 0 if link is UP.
  */
 u8 bnx2x_link_test(struct bnx2x *bp, u8 is_serdes);
 
 /**
- * Handles link status change
+ * bnx2x__link_status_update - handles link status change.
  *
- * @param bp
+ * @bp:		driver handle
  */
 void bnx2x__link_status_update(struct bnx2x *bp);
 
 /**
- * Report link status to upper layer
- *
- * @param bp
+ * bnx2x_link_report - report link status to upper layer.
  *
- * @return int
+ * @bp:		driver handle
  */
 void bnx2x_link_report(struct bnx2x *bp);
 
+/* None-atomic version of bnx2x_link_report() */
+void __bnx2x_link_report(struct bnx2x *bp);
+
 /**
- * calculates MF speed according to current linespeed and MF
- * configuration
+ * bnx2x_get_mf_speed - calculate MF speed.
  *
- * @param bp
+ * @bp:		driver handle
  *
- * @return u16
+ * Takes into account current linespeed and MF configuration.
  */
 u16 bnx2x_get_mf_speed(struct bnx2x *bp);
 
 /**
- * MSI-X slowpath interrupt handler
- *
- * @param irq
- * @param dev_instance
+ * bnx2x_msix_sp_int - MSI-X slowpath interrupt handler
  *
- * @return irqreturn_t
+ * @irq:		irq number
+ * @dev_instance:	private instance
  */
 irqreturn_t bnx2x_msix_sp_int(int irq, void *dev_instance);
 
 /**
- * non MSI-X interrupt handler
- *
- * @param irq
- * @param dev_instance
+ * bnx2x_interrupt - non MSI-X interrupt handler
  *
- * @return irqreturn_t
+ * @irq:		irq number
+ * @dev_instance:	private instance
  */
 irqreturn_t bnx2x_interrupt(int irq, void *dev_instance);
 #ifdef BCM_CNIC
 
 /**
- * Send command to cnic driver
+ * bnx2x_cnic_notify - send command to cnic driver
  *
- * @param bp
- * @param cmd
+ * @bp:		driver handle
+ * @cmd:	command
  */
 int bnx2x_cnic_notify(struct bnx2x *bp, int cmd);
 
 /**
- * Provides cnic information for proper interrupt handling
+ * bnx2x_setup_cnic_irq_info - provides cnic with IRQ information
  *
- * @param bp
+ * @bp:		driver handle
  */
 void bnx2x_setup_cnic_irq_info(struct bnx2x *bp);
 #endif
 
 /**
- * Enable HW interrupts.
+ * bnx2x_int_enable - enable HW interrupts.
  *
- * @param bp
+ * @bp:		driver handle
  */
 void bnx2x_int_enable(struct bnx2x *bp);
 
 /**
- * Disable interrupts. This function ensures that there are no
- * ISRs or SP DPCs (sp_task) are running after it returns.
+ * bnx2x_int_disable_sync - disable interrupts.
  *
- * @param bp
- * @param disable_hw if true, disable HW interrupts.
+ * @bp:		driver handle
+ * @disable_hw:	true, disable HW interrupts.
+ *
+ * This function ensures that there are no
+ * ISRs or SP DPCs (sp_task) are running after it returns.
  */
 void bnx2x_int_disable_sync(struct bnx2x *bp, int disable_hw);
 
 /**
- * Loads device firmware
- *
- * @param bp
+ * bnx2x_init_firmware - loads device firmware
  *
- * @return int
+ * @bp:		driver handle
  */
 int bnx2x_init_firmware(struct bnx2x *bp);
 
 /**
- * Init HW blocks according to current initialization stage:
- * COMMON, PORT or FUNCTION.
- *
- * @param bp
- * @param load_code: COMMON, PORT or FUNCTION
+ * bnx2x_init_hw - init HW blocks according to current initialization stage.
  *
- * @return int
+ * @bp:		driver handle
+ * @load_code:	COMMON, PORT or FUNCTION
  */
 int bnx2x_init_hw(struct bnx2x *bp, u32 load_code);
 
 /**
- * Init driver internals:
+ * bnx2x_nic_init - init driver internals.
+ *
+ * @bp:		driver handle
+ * @load_code:	COMMON, PORT or FUNCTION
+ *
+ * Initializes:
  *  - rings
  *  - status blocks
  *  - etc.
- *
- * @param bp
- * @param load_code COMMON, PORT or FUNCTION
  */
 void bnx2x_nic_init(struct bnx2x *bp, u32 load_code);
 
 /**
- * Allocate driver's memory.
- *
- * @param bp
+ * bnx2x_alloc_mem - allocate driver's memory.
  *
- * @return int
+ * @bp:		driver handle
  */
 int bnx2x_alloc_mem(struct bnx2x *bp);
 
 /**
- * Release driver's memory.
+ * bnx2x_free_mem - release driver's memory.
  *
- * @param bp
+ * @bp:		driver handle
  */
 void bnx2x_free_mem(struct bnx2x *bp);
 
 /**
- * Setup eth Client.
- *
- * @param bp
- * @param fp
- * @param is_leading
+ * bnx2x_setup_client - setup eth client.
  *
- * @return int
+ * @bp:		driver handle
+ * @fp:		pointer to fastpath structure
+ * @is_leading:	boolean
  */
 int bnx2x_setup_client(struct bnx2x *bp, struct bnx2x_fastpath *fp,
 		       int is_leading);
 
 /**
- * Set number of queues according to mode
- *
- * @param bp
+ * bnx2x_set_num_queues - set number of queues according to mode.
  *
+ * @bp:		driver handle
  */
 void bnx2x_set_num_queues(struct bnx2x *bp);
 
 /**
- * Cleanup chip internals:
+ * bnx2x_chip_cleanup - cleanup chip internals.
+ *
+ * @bp:			driver handle
+ * @unload_mode:	COMMON, PORT, FUNCTION
+ *
  * - Cleanup MAC configuration.
- * - Close clients.
+ * - Closes clients.
  * - etc.
- *
- * @param bp
- * @param unload_mode
  */
 void bnx2x_chip_cleanup(struct bnx2x *bp, int unload_mode);
 
 /**
- * Acquire HW lock.
- *
- * @param bp
- * @param resource Resource bit which was locked
+ * bnx2x_acquire_hw_lock - acquire HW lock.
  *
- * @return int
+ * @bp:		driver handle
+ * @resource:	resource bit which was locked
  */
 int bnx2x_acquire_hw_lock(struct bnx2x *bp, u32 resource);
 
 /**
- * Release HW lock.
- *
- * @param bp driver handle
- * @param resource Resource bit which was locked
+ * bnx2x_release_hw_lock - release HW lock.
  *
- * @return int
+ * @bp:		driver handle
+ * @resource:	resource bit which was locked
  */
 int bnx2x_release_hw_lock(struct bnx2x *bp, u32 resource);
 
 /**
- * Configure eth MAC address in the HW according to the value in
- * netdev->dev_addr.
+ * bnx2x_set_eth_mac - configure eth MAC address in the HW
  *
- * @param bp driver handle
- * @param set
+ * @bp:		driver handle
+ * @set:	set or clear
+ *
+ * Configures according to the value in netdev->dev_addr.
  */
 void bnx2x_set_eth_mac(struct bnx2x *bp, int set);
 
 #ifdef BCM_CNIC
 /**
- * Set/Clear FIP MAC(s) at the next enties in the CAM after the ETH
- * MAC(s). This function will wait until the ramdord completion
- * returns.
+ * bnx2x_set_fip_eth_mac_addr - Set/Clear FIP MAC(s)
  *
- * @param bp driver handle
- * @param set set or clear the CAM entry
+ * @bp:		driver handle
+ * @set:	set or clear the CAM entry
  *
- * @return 0 if cussess, -ENODEV if ramrod doesn't return.
+ * Used next enties in the CAM after the ETH MAC(s).
+ * This function will wait until the ramdord completion returns.
+ * Return 0 if cussess, -ENODEV if ramrod doesn't return.
  */
 int bnx2x_set_fip_eth_mac_addr(struct bnx2x *bp, int set);
 
 /**
- * Set/Clear ALL_ENODE mcast MAC.
- *
- * @param bp
- * @param set
+ * bnx2x_set_all_enode_macs - Set/Clear ALL_ENODE mcast MAC.
  *
- * @return int
+ * @bp:		driver handle
+ * @set:	set or clear
  */
 int bnx2x_set_all_enode_macs(struct bnx2x *bp, int set);
 #endif
 
 /**
- * Set MAC filtering configurations.
+ * bnx2x_set_rx_mode - set MAC filtering configurations.
  *
- * @remarks called with netif_tx_lock from dev_mcast.c
+ * @dev:	netdevice
  *
- * @param dev net_device
+ * called with netif_tx_lock from dev_mcast.c
  */
 void bnx2x_set_rx_mode(struct net_device *dev);
 
 /**
- * Configure MAC filtering rules in a FW.
+ * bnx2x_set_storm_rx_mode - configure MAC filtering rules in a FW.
  *
- * @param bp driver handle
+ * @bp:		driver handle
  */
 void bnx2x_set_storm_rx_mode(struct bnx2x *bp);
 
@@ -290,63 +307,59 @@
 void bnx2x_disable_close_the_gate(struct bnx2x *bp);
 
 /**
- * Perform statistics handling according to event
+ * bnx2x_stats_handle - perform statistics handling according to event.
  *
- * @param bp driver handle
- * @param event bnx2x_stats_event
+ * @bp:		driver handle
+ * @event:	bnx2x_stats_event
  */
 void bnx2x_stats_handle(struct bnx2x *bp, enum bnx2x_stats_event event);
 
 /**
- * Handle ramrods completion
+ * bnx2x_sp_event - handle ramrods completion.
  *
- * @param fp fastpath handle for the event
- * @param rr_cqe eth_rx_cqe
+ * @fp:		fastpath handle for the event
+ * @rr_cqe:	eth_rx_cqe
  */
 void bnx2x_sp_event(struct bnx2x_fastpath *fp, union eth_rx_cqe *rr_cqe);
 
 /**
- * Init/halt function before/after sending
- * CLIENT_SETUP/CFC_DEL for the first/last client.
+ * bnx2x_func_start - init function
  *
- * @param bp
+ * @bp:		driver handle
  *
- * @return int
+ * Must be called before sending CLIENT_SETUP for the first client.
  */
 int bnx2x_func_start(struct bnx2x *bp);
 
 /**
- * Prepare ILT configurations according to current driver
- * parameters.
+ * bnx2x_ilt_set_info - prepare ILT configurations.
  *
- * @param bp
+ * @bp:		driver handle
  */
 void bnx2x_ilt_set_info(struct bnx2x *bp);
 
 /**
- * Inintialize dcbx protocol
+ * bnx2x_dcbx_init - initialize dcbx protocol.
  *
- * @param bp
+ * @bp:		driver handle
  */
 void bnx2x_dcbx_init(struct bnx2x *bp);
 
 /**
- * Set power state to the requested value. Currently only D0 and
- * D3hot are supported.
+ * bnx2x_set_power_state - set power state to the requested value.
  *
- * @param bp
- * @param state D0 or D3hot
+ * @bp:		driver handle
+ * @state:	required state D0 or D3hot
  *
- * @return int
+ * Currently only D0 and D3hot are supported.
  */
 int bnx2x_set_power_state(struct bnx2x *bp, pci_power_t state);
 
 /**
- * Updates MAX part of MF configuration in HW
- * (if required)
+ * bnx2x_update_max_mf_config - update MAX part of MF configuration in HW.
  *
- * @param bp
- * @param value
+ * @bp:		driver handle
+ * @value:	new value
  */
 void bnx2x_update_max_mf_config(struct bnx2x *bp, u32 value);
 
@@ -377,83 +390,72 @@
 /* Release IRQ vectors */
 void bnx2x_free_irq(struct bnx2x *bp);
 
+void bnx2x_free_fp_mem(struct bnx2x *bp);
+int bnx2x_alloc_fp_mem(struct bnx2x *bp);
+
 void bnx2x_init_rx_rings(struct bnx2x *bp);
 void bnx2x_free_skbs(struct bnx2x *bp);
 void bnx2x_netif_stop(struct bnx2x *bp, int disable_hw);
 void bnx2x_netif_start(struct bnx2x *bp);
 
 /**
- * Fill msix_table, request vectors, update num_queues according
- * to number of available vectors
+ * bnx2x_enable_msix - set msix configuration.
  *
- * @param bp
+ * @bp:		driver handle
  *
- * @return int
+ * fills msix_table, requests vectors, updates num_queues
+ * according to number of available vectors.
  */
 int bnx2x_enable_msix(struct bnx2x *bp);
 
 /**
- * Request msi mode from OS, updated internals accordingly
- *
- * @param bp
+ * bnx2x_enable_msi - request msi mode from OS, updated internals accordingly
  *
- * @return int
+ * @bp:		driver handle
  */
 int bnx2x_enable_msi(struct bnx2x *bp);
 
 /**
- * NAPI callback
+ * bnx2x_poll - NAPI callback
  *
- * @param napi
- * @param budget
+ * @napi:	napi structure
+ * @budget:
  *
- * @return int
  */
 int bnx2x_poll(struct napi_struct *napi, int budget);
 
 /**
- * Allocate/release memories outsize main driver structure
- *
- * @param bp
+ * bnx2x_alloc_mem_bp - allocate memories outsize main driver structure
  *
- * @return int
+ * @bp:		driver handle
  */
 int __devinit bnx2x_alloc_mem_bp(struct bnx2x *bp);
-void bnx2x_free_mem_bp(struct bnx2x *bp);
 
 /**
- * Change mtu netdev callback
- *
- * @param dev
- * @param new_mtu
+ * bnx2x_free_mem_bp - release memories outsize main driver structure
  *
- * @return int
+ * @bp:		driver handle
  */
-int bnx2x_change_mtu(struct net_device *dev, int new_mtu);
+void bnx2x_free_mem_bp(struct bnx2x *bp);
 
 /**
- * tx timeout netdev callback
+ * bnx2x_change_mtu - change mtu netdev callback
  *
- * @param dev
- * @param new_mtu
+ * @dev:	net device
+ * @new_mtu:	requested mtu
  *
- * @return int
  */
-void bnx2x_tx_timeout(struct net_device *dev);
+int bnx2x_change_mtu(struct net_device *dev, int new_mtu);
+
+u32 bnx2x_fix_features(struct net_device *dev, u32 features);
+int bnx2x_set_features(struct net_device *dev, u32 features);
 
-#ifdef BCM_VLAN
 /**
- * vlan rx register netdev callback
- *
- * @param dev
- * @param new_mtu
+ * bnx2x_tx_timeout - tx timeout netdev callback
  *
- * @return int
+ * @dev:	net device
  */
-void bnx2x_vlan_rx_register(struct net_device *dev,
-				   struct vlan_group *vlgrp);
-
-#endif
+void bnx2x_tx_timeout(struct net_device *dev);
 
 static inline void bnx2x_update_fpsb_idx(struct bnx2x_fastpath *fp)
 {
@@ -705,7 +707,7 @@
 /**
  * disables tx from stack point of view
  *
- * @param bp
+ * @bp:		driver handle
  */
 static inline void bnx2x_tx_disable(struct bnx2x *bp)
 {
@@ -838,7 +840,7 @@
 	mapping = dma_map_single(&bp->pdev->dev, skb->data, fp->rx_buf_size,
 				 DMA_FROM_DEVICE);
 	if (unlikely(dma_mapping_error(&bp->pdev->dev, mapping))) {
-		dev_kfree_skb(skb);
+		dev_kfree_skb_any(skb);
 		return -ENOMEM;
 	}
 
@@ -880,6 +882,9 @@
 {
 	int i;
 
+	if (fp->disable_tpa)
+		return;
+
 	for (i = 0; i < last; i++)
 		bnx2x_free_rx_sge(bp, fp, i);
 }
@@ -908,36 +913,39 @@
 	}
 }
 
-
-static inline void bnx2x_init_tx_rings(struct bnx2x *bp)
+static inline void bnx2x_init_tx_ring_one(struct bnx2x_fastpath *fp)
 {
-	int i, j;
+	int i;
 
-	for_each_tx_queue(bp, j) {
-		struct bnx2x_fastpath *fp = &bp->fp[j];
+	for (i = 1; i <= NUM_TX_RINGS; i++) {
+		struct eth_tx_next_bd *tx_next_bd =
+			&fp->tx_desc_ring[TX_DESC_CNT * i - 1].next_bd;
 
-		for (i = 1; i <= NUM_TX_RINGS; i++) {
-			struct eth_tx_next_bd *tx_next_bd =
-				&fp->tx_desc_ring[TX_DESC_CNT * i - 1].next_bd;
+		tx_next_bd->addr_hi =
+			cpu_to_le32(U64_HI(fp->tx_desc_mapping +
+				    BCM_PAGE_SIZE*(i % NUM_TX_RINGS)));
+		tx_next_bd->addr_lo =
+			cpu_to_le32(U64_LO(fp->tx_desc_mapping +
+				    BCM_PAGE_SIZE*(i % NUM_TX_RINGS)));
+	}
 
-			tx_next_bd->addr_hi =
-				cpu_to_le32(U64_HI(fp->tx_desc_mapping +
-					    BCM_PAGE_SIZE*(i % NUM_TX_RINGS)));
-			tx_next_bd->addr_lo =
-				cpu_to_le32(U64_LO(fp->tx_desc_mapping +
-					    BCM_PAGE_SIZE*(i % NUM_TX_RINGS)));
-		}
+	SET_FLAG(fp->tx_db.data.header.header, DOORBELL_HDR_DB_TYPE, 1);
+	fp->tx_db.data.zero_fill1 = 0;
+	fp->tx_db.data.prod = 0;
 
-		SET_FLAG(fp->tx_db.data.header.header, DOORBELL_HDR_DB_TYPE, 1);
-		fp->tx_db.data.zero_fill1 = 0;
-		fp->tx_db.data.prod = 0;
+	fp->tx_pkt_prod = 0;
+	fp->tx_pkt_cons = 0;
+	fp->tx_bd_prod = 0;
+	fp->tx_bd_cons = 0;
+	fp->tx_pkt = 0;
+}
 
-		fp->tx_pkt_prod = 0;
-		fp->tx_pkt_cons = 0;
-		fp->tx_bd_prod = 0;
-		fp->tx_bd_cons = 0;
-		fp->tx_pkt = 0;
-	}
+static inline void bnx2x_init_tx_rings(struct bnx2x *bp)
+{
+	int i;
+
+	for_each_tx_queue(bp, i)
+		bnx2x_init_tx_ring_one(&bp->fp[i]);
 }
 
 static inline void bnx2x_set_next_page_rx_bd(struct bnx2x_fastpath *fp)
@@ -992,6 +1000,44 @@
 	}
 }
 
+/* Returns the number of actually allocated BDs */
+static inline int bnx2x_alloc_rx_bds(struct bnx2x_fastpath *fp,
+				      int rx_ring_size)
+{
+	struct bnx2x *bp = fp->bp;
+	u16 ring_prod, cqe_ring_prod;
+	int i;
+
+	fp->rx_comp_cons = 0;
+	cqe_ring_prod = ring_prod = 0;
+
+	/* This routine is called only during fo init so
+	 * fp->eth_q_stats.rx_skb_alloc_failed = 0
+	 */
+	for (i = 0; i < rx_ring_size; i++) {
+		if (bnx2x_alloc_rx_skb(bp, fp, ring_prod) < 0) {
+			fp->eth_q_stats.rx_skb_alloc_failed++;
+			continue;
+		}
+		ring_prod = NEXT_RX_IDX(ring_prod);
+		cqe_ring_prod = NEXT_RCQ_IDX(cqe_ring_prod);
+		WARN_ON(ring_prod <= (i - fp->eth_q_stats.rx_skb_alloc_failed));
+	}
+
+	if (fp->eth_q_stats.rx_skb_alloc_failed)
+		BNX2X_ERR("was only able to allocate "
+			  "%d rx skbs on queue[%d]\n",
+			  (i - fp->eth_q_stats.rx_skb_alloc_failed), fp->index);
+
+	fp->rx_bd_prod = ring_prod;
+	/* Limit the CQE producer by the CQE ring size */
+	fp->rx_comp_prod = min_t(u16, NUM_RCQ_RINGS*RCQ_DESC_CNT,
+			       cqe_ring_prod);
+	fp->rx_pkt = fp->rx_calls = 0;
+
+	return i - fp->eth_q_stats.rx_skb_alloc_failed;
+}
+
 #ifdef BCM_CNIC
 static inline void bnx2x_init_fcoe_fp(struct bnx2x *bp)
 {
@@ -1041,12 +1087,23 @@
 				struct cmng_struct_per_port *cmng,
 				u8 port)
 {
-	size_t size = sizeof(struct cmng_struct_per_port);
+	size_t size =
+		sizeof(struct rate_shaping_vars_per_port) +
+		sizeof(struct fairness_vars_per_port) +
+		sizeof(struct safc_struct_per_port) +
+		sizeof(struct pfc_struct_per_port);
 
 	u32 addr = BAR_XSTRORM_INTMEM +
 			XSTORM_CMNG_PER_PORT_VARS_OFFSET(port);
 
 	__storm_memset_struct(bp, addr, size, (u32 *)cmng);
+
+	addr += size + 4 /* SKIP DCB+LLFC */;
+	size = sizeof(struct cmng_struct_per_port) -
+		size /* written */ - 4 /*skipped*/;
+
+	__storm_memset_struct(bp, addr, size,
+			      (u32 *)(cmng->traffic_type_to_priority_cos));
 }
 
 /* HW Lock for shared dual port PHYs */
@@ -1054,12 +1111,11 @@
 void bnx2x_release_phy_lock(struct bnx2x *bp);
 
 /**
- * Extracts MAX BW part from MF configuration.
+ * bnx2x_extract_max_cfg - extract MAX BW part from MF configuration.
  *
- * @param bp
- * @param mf_cfg
+ * @bp:		driver handle
+ * @mf_cfg:	MF configuration
  *
- * @return u16
  */
 static inline u16 bnx2x_extract_max_cfg(struct bnx2x *bp, u32 mf_cfg)
 {
diff -druN linux-2.6.39-libre/drivers/net/bnx2x/bnx2x_dcb.c linux-3.0-rc7-libre/drivers/net/bnx2x/bnx2x_dcb.c
--- linux-2.6.39-libre/drivers/net/bnx2x/bnx2x_dcb.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/bnx2x/bnx2x_dcb.c	2011-07-11 19:51:52.000000000 -0400
@@ -1,6 +1,6 @@
 /* bnx2x_dcb.c: Broadcom Everest network driver.
  *
- * Copyright 2009-2010 Broadcom Corporation
+ * Copyright 2009-2011 Broadcom Corporation
  *
  * Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
@@ -485,6 +485,36 @@
 	}
 }
 
+#ifdef BCM_DCBNL
+static int bnx2x_dcbx_read_shmem_remote_mib(struct bnx2x *bp)
+{
+	struct lldp_remote_mib remote_mib = {0};
+	u32 dcbx_remote_mib_offset = SHMEM2_RD(bp, dcbx_remote_mib_offset);
+	int rc;
+
+	DP(NETIF_MSG_LINK, "dcbx_remote_mib_offset 0x%x\n",
+	   dcbx_remote_mib_offset);
+
+	if (SHMEM_DCBX_REMOTE_MIB_NONE == dcbx_remote_mib_offset) {
+		BNX2X_ERR("FW doesn't support dcbx_remote_mib_offset\n");
+		return -EINVAL;
+	}
+
+	rc = bnx2x_dcbx_read_mib(bp, (u32 *)&remote_mib, dcbx_remote_mib_offset,
+				 DCBX_READ_REMOTE_MIB);
+
+	if (rc) {
+		BNX2X_ERR("Faild to read remote mib from FW\n");
+		return rc;
+	}
+
+	/* save features and flags */
+	bp->dcbx_remote_feat = remote_mib.features;
+	bp->dcbx_remote_flags = remote_mib.flags;
+	return 0;
+}
+#endif
+
 static int bnx2x_dcbx_read_shmem_neg_results(struct bnx2x *bp)
 {
 	struct lldp_local_mib local_mib = {0};
@@ -571,6 +601,28 @@
 {
 	switch (state) {
 	case BNX2X_DCBX_STATE_NEG_RECEIVED:
+#ifdef BCM_CNIC
+		if (bp->state != BNX2X_STATE_OPENING_WAIT4_LOAD) {
+			struct cnic_ops *c_ops;
+			struct cnic_eth_dev *cp = &bp->cnic_eth_dev;
+			bp->flags |= NO_ISCSI_OOO_FLAG | NO_ISCSI_FLAG;
+			cp->drv_state |= CNIC_DRV_STATE_NO_ISCSI_OOO;
+			cp->drv_state |= CNIC_DRV_STATE_NO_ISCSI;
+
+			rcu_read_lock();
+			c_ops = rcu_dereference(bp->cnic_ops);
+			if (c_ops) {
+				bnx2x_cnic_notify(bp, CNIC_CTL_STOP_ISCSI_CMD);
+				rcu_read_unlock();
+				return;
+			}
+			rcu_read_unlock();
+		}
+
+		/* fall through if no CNIC initialized  */
+	case BNX2X_DCBX_STATE_ISCSI_STOPPED:
+#endif
+
 		{
 			DP(NETIF_MSG_LINK, "BNX2X_DCBX_STATE_NEG_RECEIVED\n");
 #ifdef BCM_DCBNL
@@ -579,6 +631,10 @@
 			 * negotiation results
 			 */
 			bnx2x_dcbnl_update_applist(bp, true);
+
+			/* Read rmeote mib if dcbx is in the FW */
+			if (bnx2x_dcbx_read_shmem_remote_mib(bp))
+				return;
 #endif
 			/* Read neg results if dcbx is in the FW */
 			if (bnx2x_dcbx_read_shmem_neg_results(bp))
@@ -1057,12 +1113,6 @@
 	}
 }
 
-
-/*******************************************************************************
- * Description: single priority group
- *
- * Return:
- ******************************************************************************/
 static void bnx2x_dcbx_ets_disabled_entry_data(struct bnx2x *bp,
 					       struct cos_help_data *cos_data,
 					       u32 pri_join_mask)
@@ -1075,11 +1125,6 @@
 	cos_data->num_of_cos = 1;
 }
 
-/*******************************************************************************
- * Description: updating the cos bw
- *
- * Return:
- ******************************************************************************/
 static inline void bnx2x_dcbx_add_to_cos_bw(struct bnx2x *bp,
 					    struct cos_entry_help_data *data,
 					    u8 pg_bw)
@@ -1090,11 +1135,6 @@
 		data->cos_bw += pg_bw;
 }
 
-/*******************************************************************************
- * Description: single priority group
- *
- * Return:
- ******************************************************************************/
 static void bnx2x_dcbx_separate_pauseable_from_non(struct bnx2x *bp,
 			struct cos_help_data *cos_data,
 			u32 *pg_pri_orginal_spread,
@@ -1347,11 +1387,6 @@
 	}
 }
 
-/*******************************************************************************
- * Description: Still
- *
- * Return:
- ******************************************************************************/
 static void bnx2x_dcbx_three_pg_to_cos_params(
 			      struct bnx2x		*bp,
 			      struct pg_help_data	*pg_help_data,
@@ -1539,11 +1574,6 @@
 	}
 }
 
-/*******************************************************************************
- * Description: Fill pfc_config struct that will be sent in DCBX start ramrod
- *
- * Return:
- ******************************************************************************/
 static void bnx2x_pfc_fw_struct_e2(struct bnx2x *bp)
 {
 	struct flow_control_configuration   *pfc_fw_cfg = NULL;
@@ -2035,7 +2065,6 @@
 	return 0;
 }
 
-
 static u8 bnx2x_dcbnl_get_featcfg(struct net_device *netdev, int featid,
 				  u8 *flags)
 {
@@ -2115,31 +2144,100 @@
 	return rval;
 }
 
+static int bnx2x_peer_appinfo(struct net_device *netdev,
+			      struct dcb_peer_app_info *info, u16* app_count)
+{
+	int i;
+	struct bnx2x *bp = netdev_priv(netdev);
+
+	DP(NETIF_MSG_LINK, "APP-INFO\n");
+
+	info->willing = (bp->dcbx_remote_flags & DCBX_APP_REM_WILLING) ?: 0;
+	info->error = (bp->dcbx_remote_flags & DCBX_APP_RX_ERROR) ?: 0;
+	*app_count = 0;
+
+	for (i = 0; i < DCBX_MAX_APP_PROTOCOL; i++)
+		if (bp->dcbx_remote_feat.app.app_pri_tbl[i].appBitfield &
+		    DCBX_APP_ENTRY_VALID)
+			(*app_count)++;
+	return 0;
+}
+
+static int bnx2x_peer_apptable(struct net_device *netdev,
+			       struct dcb_app *table)
+{
+	int i, j;
+	struct bnx2x *bp = netdev_priv(netdev);
+
+	DP(NETIF_MSG_LINK, "APP-TABLE\n");
+
+	for (i = 0, j = 0; i < DCBX_MAX_APP_PROTOCOL; i++) {
+		struct dcbx_app_priority_entry *ent =
+			&bp->dcbx_remote_feat.app.app_pri_tbl[i];
+
+		if (ent->appBitfield & DCBX_APP_ENTRY_VALID) {
+			table[j].selector = bnx2x_dcbx_dcbnl_app_idtype(ent);
+			table[j].priority = bnx2x_dcbx_dcbnl_app_up(ent);
+			table[j++].protocol = ent->app_id;
+		}
+	}
+	return 0;
+}
+
+static int bnx2x_cee_peer_getpg(struct net_device *netdev, struct cee_pg *pg)
+{
+	int i;
+	struct bnx2x *bp = netdev_priv(netdev);
+
+	pg->willing = (bp->dcbx_remote_flags & DCBX_ETS_REM_WILLING) ?: 0;
+
+	for (i = 0; i < CEE_DCBX_MAX_PGS; i++) {
+		pg->pg_bw[i] =
+			DCBX_PG_BW_GET(bp->dcbx_remote_feat.ets.pg_bw_tbl, i);
+		pg->prio_pg[i] =
+			DCBX_PRI_PG_GET(bp->dcbx_remote_feat.ets.pri_pg_tbl, i);
+	}
+	return 0;
+}
+
+static int bnx2x_cee_peer_getpfc(struct net_device *netdev,
+				 struct cee_pfc *pfc)
+{
+	struct bnx2x *bp = netdev_priv(netdev);
+	pfc->tcs_supported = bp->dcbx_remote_feat.pfc.pfc_caps;
+	pfc->pfc_en = bp->dcbx_remote_feat.pfc.pri_en_bitmap;
+	return 0;
+}
+
 const struct dcbnl_rtnl_ops bnx2x_dcbnl_ops = {
-	.getstate       = bnx2x_dcbnl_get_state,
-	.setstate       = bnx2x_dcbnl_set_state,
-	.getpermhwaddr  = bnx2x_dcbnl_get_perm_hw_addr,
-	.setpgtccfgtx   = bnx2x_dcbnl_set_pg_tccfg_tx,
-	.setpgbwgcfgtx  = bnx2x_dcbnl_set_pg_bwgcfg_tx,
-	.setpgtccfgrx   = bnx2x_dcbnl_set_pg_tccfg_rx,
-	.setpgbwgcfgrx  = bnx2x_dcbnl_set_pg_bwgcfg_rx,
-	.getpgtccfgtx   = bnx2x_dcbnl_get_pg_tccfg_tx,
-	.getpgbwgcfgtx  = bnx2x_dcbnl_get_pg_bwgcfg_tx,
-	.getpgtccfgrx   = bnx2x_dcbnl_get_pg_tccfg_rx,
-	.getpgbwgcfgrx  = bnx2x_dcbnl_get_pg_bwgcfg_rx,
-	.setpfccfg      = bnx2x_dcbnl_set_pfc_cfg,
-	.getpfccfg      = bnx2x_dcbnl_get_pfc_cfg,
-	.setall         = bnx2x_dcbnl_set_all,
-	.getcap         = bnx2x_dcbnl_get_cap,
-	.getnumtcs      = bnx2x_dcbnl_get_numtcs,
-	.setnumtcs      = bnx2x_dcbnl_set_numtcs,
-	.getpfcstate    = bnx2x_dcbnl_get_pfc_state,
-	.setpfcstate    = bnx2x_dcbnl_set_pfc_state,
-	.setapp         = bnx2x_dcbnl_set_app_up,
-	.getdcbx        = bnx2x_dcbnl_get_dcbx,
-	.setdcbx        = bnx2x_dcbnl_set_dcbx,
-	.getfeatcfg     = bnx2x_dcbnl_get_featcfg,
-	.setfeatcfg     = bnx2x_dcbnl_set_featcfg,
+	.getstate		= bnx2x_dcbnl_get_state,
+	.setstate		= bnx2x_dcbnl_set_state,
+	.getpermhwaddr		= bnx2x_dcbnl_get_perm_hw_addr,
+	.setpgtccfgtx		= bnx2x_dcbnl_set_pg_tccfg_tx,
+	.setpgbwgcfgtx		= bnx2x_dcbnl_set_pg_bwgcfg_tx,
+	.setpgtccfgrx		= bnx2x_dcbnl_set_pg_tccfg_rx,
+	.setpgbwgcfgrx		= bnx2x_dcbnl_set_pg_bwgcfg_rx,
+	.getpgtccfgtx		= bnx2x_dcbnl_get_pg_tccfg_tx,
+	.getpgbwgcfgtx		= bnx2x_dcbnl_get_pg_bwgcfg_tx,
+	.getpgtccfgrx		= bnx2x_dcbnl_get_pg_tccfg_rx,
+	.getpgbwgcfgrx		= bnx2x_dcbnl_get_pg_bwgcfg_rx,
+	.setpfccfg		= bnx2x_dcbnl_set_pfc_cfg,
+	.getpfccfg		= bnx2x_dcbnl_get_pfc_cfg,
+	.setall			= bnx2x_dcbnl_set_all,
+	.getcap			= bnx2x_dcbnl_get_cap,
+	.getnumtcs		= bnx2x_dcbnl_get_numtcs,
+	.setnumtcs		= bnx2x_dcbnl_set_numtcs,
+	.getpfcstate		= bnx2x_dcbnl_get_pfc_state,
+	.setpfcstate		= bnx2x_dcbnl_set_pfc_state,
+	.setapp			= bnx2x_dcbnl_set_app_up,
+	.getdcbx		= bnx2x_dcbnl_get_dcbx,
+	.setdcbx		= bnx2x_dcbnl_set_dcbx,
+	.getfeatcfg		= bnx2x_dcbnl_get_featcfg,
+	.setfeatcfg		= bnx2x_dcbnl_set_featcfg,
+	.peer_getappinfo	= bnx2x_peer_appinfo,
+	.peer_getapptable	= bnx2x_peer_apptable,
+	.cee_peer_getpg		= bnx2x_cee_peer_getpg,
+	.cee_peer_getpfc	= bnx2x_cee_peer_getpfc,
 };
 
 #endif /* BCM_DCBNL */
diff -druN linux-2.6.39-libre/drivers/net/bnx2x/bnx2x_dcb.h linux-3.0-rc7-libre/drivers/net/bnx2x/bnx2x_dcb.h
--- linux-2.6.39-libre/drivers/net/bnx2x/bnx2x_dcb.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/bnx2x/bnx2x_dcb.h	2011-07-11 19:51:52.000000000 -0400
@@ -1,6 +1,6 @@
 /* bnx2x_dcb.h: Broadcom Everest network driver.
  *
- * Copyright 2009-2010 Broadcom Corporation
+ * Copyright 2009-2011 Broadcom Corporation
  *
  * Unless you and Broadcom execute a separate written software license
  * agreement governing use of this software, this software is licensed to you
@@ -61,9 +61,6 @@
 #define BNX2X_DCBX_OVERWRITE_SETTINGS_ENABLE		1
 #define BNX2X_DCBX_OVERWRITE_SETTINGS_INVALID	(BNX2X_DCBX_CONFIG_INV_VALUE)
 
-/*******************************************************************************
- * LLDP protocol configuration parameters.
- ******************************************************************************/
 struct bnx2x_config_lldp_params {
 	u32 overwrite_settings;
 	u32 msg_tx_hold;
@@ -83,9 +80,6 @@
 		u32 app_id;
 };
 
-/*******************************************************************************
- * DCBX protocol configuration parameters.
- ******************************************************************************/
 struct bnx2x_config_dcbx_params {
 	u32 overwrite_settings;
 	u32 admin_dcbx_version;
@@ -183,9 +177,13 @@
 
 enum {
 	BNX2X_DCBX_STATE_NEG_RECEIVED = 0x1,
-	BNX2X_DCBX_STATE_TX_PAUSED = 0x2,
-	BNX2X_DCBX_STATE_TX_RELEASED = 0x4
+#ifdef BCM_CNIC
+	BNX2X_DCBX_STATE_ISCSI_STOPPED,
+#endif
+	BNX2X_DCBX_STATE_TX_PAUSED,
+	BNX2X_DCBX_STATE_TX_RELEASED
 };
+
 void bnx2x_dcbx_set_params(struct bnx2x *bp, u32 state);
 
 /* DCB netlink */
diff -druN linux-2.6.39-libre/drivers/net/bnx2x/bnx2x_ethtool.c linux-3.0-rc7-libre/drivers/net/bnx2x/bnx2x_ethtool.c
--- linux-2.6.39-libre/drivers/net/bnx2x/bnx2x_ethtool.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/bnx2x/bnx2x_ethtool.c	2011-07-11 19:51:52.000000000 -0400
@@ -1,6 +1,6 @@
 /* bnx2x_ethtool.c: Broadcom Everest network driver.
  *
- * Copyright (c) 2007-2010 Broadcom Corporation
+ * Copyright (c) 2007-2011 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
@@ -167,6 +167,7 @@
 {
 	struct bnx2x *bp = netdev_priv(dev);
 	int cfg_idx = bnx2x_get_link_cfg_idx(bp);
+
 	/* Dual Media boards present all available port types */
 	cmd->supported = bp->port.supported[cfg_idx] |
 		(bp->port.supported[cfg_idx ^ 1] &
@@ -176,16 +177,16 @@
 	if ((bp->state == BNX2X_STATE_OPEN) &&
 	    !(bp->flags & MF_FUNC_DIS) &&
 	    (bp->link_vars.link_up)) {
-		cmd->speed = bp->link_vars.line_speed;
+		ethtool_cmd_speed_set(cmd, bp->link_vars.line_speed);
 		cmd->duplex = bp->link_vars.duplex;
 	} else {
-
-		cmd->speed = bp->link_params.req_line_speed[cfg_idx];
+		ethtool_cmd_speed_set(
+			cmd, bp->link_params.req_line_speed[cfg_idx]);
 		cmd->duplex = bp->link_params.req_duplex[cfg_idx];
 	}
 
 	if (IS_MF(bp))
-		cmd->speed = bnx2x_get_mf_speed(bp);
+		ethtool_cmd_speed_set(cmd, bnx2x_get_mf_speed(bp));
 
 	if (bp->port.supported[cfg_idx] & SUPPORTED_TP)
 		cmd->port = PORT_TP;
@@ -206,10 +207,11 @@
 	cmd->maxrxpkt = 0;
 
 	DP(NETIF_MSG_LINK, "ethtool_cmd: cmd %d\n"
-	   DP_LEVEL "  supported 0x%x  advertising 0x%x  speed %d\n"
+	   DP_LEVEL "  supported 0x%x  advertising 0x%x  speed %u\n"
 	   DP_LEVEL "  duplex %d  port %d  phy_address %d  transceiver %d\n"
 	   DP_LEVEL "  autoneg %d  maxtxpkt %d  maxrxpkt %d\n",
-	   cmd->cmd, cmd->supported, cmd->advertising, cmd->speed,
+	   cmd->cmd, cmd->supported, cmd->advertising,
+	   ethtool_cmd_speed(cmd),
 	   cmd->duplex, cmd->port, cmd->phy_address, cmd->transceiver,
 	   cmd->autoneg, cmd->maxtxpkt, cmd->maxrxpkt);
 
@@ -226,16 +228,15 @@
 		return 0;
 
 	DP(NETIF_MSG_LINK, "ethtool_cmd: cmd %d\n"
-	   "  supported 0x%x  advertising 0x%x  speed %d speed_hi %d\n"
+	   "  supported 0x%x  advertising 0x%x  speed %u\n"
 	   "  duplex %d  port %d  phy_address %d  transceiver %d\n"
 	   "  autoneg %d  maxtxpkt %d  maxrxpkt %d\n",
-	   cmd->cmd, cmd->supported, cmd->advertising, cmd->speed,
-	   cmd->speed_hi,
+	   cmd->cmd, cmd->supported, cmd->advertising,
+	   ethtool_cmd_speed(cmd),
 	   cmd->duplex, cmd->port, cmd->phy_address, cmd->transceiver,
 	   cmd->autoneg, cmd->maxtxpkt, cmd->maxrxpkt);
 
-	speed = cmd->speed;
-	speed |= (cmd->speed_hi << 16);
+	speed = ethtool_cmd_speed(cmd);
 
 	if (IS_MF_SI(bp)) {
 		u32 part;
@@ -439,7 +440,7 @@
 			break;
 
 		default:
-			DP(NETIF_MSG_LINK, "Unsupported speed %d\n", speed);
+			DP(NETIF_MSG_LINK, "Unsupported speed %u\n", speed);
 			return -EINVAL;
 		}
 
@@ -1219,7 +1220,8 @@
 	}
 
 	if ((ering->rx_pending > MAX_RX_AVAIL) ||
-	    (ering->rx_pending < MIN_RX_AVAIL) ||
+	    (ering->rx_pending < (bp->disable_tpa ? MIN_RX_SIZE_NONTPA :
+						    MIN_RX_SIZE_TPA)) ||
 	    (ering->tx_pending > MAX_TX_AVAIL) ||
 	    (ering->tx_pending <= MAX_SKB_FRAGS + 4))
 		return -EINVAL;
@@ -1299,91 +1301,6 @@
 	return 0;
 }
 
-static int bnx2x_set_flags(struct net_device *dev, u32 data)
-{
-	struct bnx2x *bp = netdev_priv(dev);
-	int changed = 0;
-	int rc = 0;
-
-	if (bp->recovery_state != BNX2X_RECOVERY_DONE) {
-		printk(KERN_ERR "Handling parity error recovery. Try again later\n");
-		return -EAGAIN;
-	}
-
-	if (!(data & ETH_FLAG_RXVLAN))
-		return -EINVAL;
-
-	if ((data & ETH_FLAG_LRO) && bp->rx_csum && bp->disable_tpa)
-		return -EINVAL;
-
-	rc = ethtool_op_set_flags(dev, data, ETH_FLAG_LRO | ETH_FLAG_RXVLAN |
-					ETH_FLAG_TXVLAN | ETH_FLAG_RXHASH);
-	if (rc)
-		return rc;
-
-	/* TPA requires Rx CSUM offloading */
-	if ((data & ETH_FLAG_LRO) && bp->rx_csum) {
-		if (!(bp->flags & TPA_ENABLE_FLAG)) {
-			bp->flags |= TPA_ENABLE_FLAG;
-			changed = 1;
-		}
-	} else if (bp->flags & TPA_ENABLE_FLAG) {
-		dev->features &= ~NETIF_F_LRO;
-		bp->flags &= ~TPA_ENABLE_FLAG;
-		changed = 1;
-	}
-
-	if (changed && netif_running(dev)) {
-		bnx2x_nic_unload(bp, UNLOAD_NORMAL);
-		rc = bnx2x_nic_load(bp, LOAD_NORMAL);
-	}
-
-	return rc;
-}
-
-static u32 bnx2x_get_rx_csum(struct net_device *dev)
-{
-	struct bnx2x *bp = netdev_priv(dev);
-
-	return bp->rx_csum;
-}
-
-static int bnx2x_set_rx_csum(struct net_device *dev, u32 data)
-{
-	struct bnx2x *bp = netdev_priv(dev);
-	int rc = 0;
-
-	if (bp->recovery_state != BNX2X_RECOVERY_DONE) {
-		printk(KERN_ERR "Handling parity error recovery. Try again later\n");
-		return -EAGAIN;
-	}
-
-	bp->rx_csum = data;
-
-	/* Disable TPA, when Rx CSUM is disabled. Otherwise all
-	   TPA'ed packets will be discarded due to wrong TCP CSUM */
-	if (!data) {
-		u32 flags = ethtool_op_get_flags(dev);
-
-		rc = bnx2x_set_flags(dev, (flags & ~ETH_FLAG_LRO));
-	}
-
-	return rc;
-}
-
-static int bnx2x_set_tso(struct net_device *dev, u32 data)
-{
-	if (data) {
-		dev->features |= (NETIF_F_TSO | NETIF_F_TSO_ECN);
-		dev->features |= NETIF_F_TSO6;
-	} else {
-		dev->features &= ~(NETIF_F_TSO | NETIF_F_TSO_ECN);
-		dev->features &= ~NETIF_F_TSO6;
-	}
-
-	return 0;
-}
-
 static const struct {
 	char string[ETH_GSTRING_LEN];
 } bnx2x_tests_str_arr[BNX2X_NUM_TESTS] = {
@@ -2097,35 +2014,37 @@
 	}
 }
 
-static int bnx2x_phys_id(struct net_device *dev, u32 data)
+static int bnx2x_set_phys_id(struct net_device *dev,
+			     enum ethtool_phys_id_state state)
 {
 	struct bnx2x *bp = netdev_priv(dev);
-	int i;
 
 	if (!netif_running(dev))
-		return 0;
+		return -EAGAIN;
 
 	if (!bp->port.pmf)
-		return 0;
+		return -EOPNOTSUPP;
 
-	if (data == 0)
-		data = 2;
+	switch (state) {
+	case ETHTOOL_ID_ACTIVE:
+		return 1;	/* cycle on/off once per second */
 
-	for (i = 0; i < (data * 2); i++) {
-		if ((i % 2) == 0)
-			bnx2x_set_led(&bp->link_params, &bp->link_vars,
-				      LED_MODE_ON, SPEED_1000);
-		else
-			bnx2x_set_led(&bp->link_params, &bp->link_vars,
-				      LED_MODE_FRONT_PANEL_OFF, 0);
+	case ETHTOOL_ID_ON:
+		bnx2x_set_led(&bp->link_params, &bp->link_vars,
+			      LED_MODE_ON, SPEED_1000);
+		break;
 
-		msleep_interruptible(500);
-		if (signal_pending(current))
-			break;
-	}
+	case ETHTOOL_ID_OFF:
+		bnx2x_set_led(&bp->link_params, &bp->link_vars,
+			      LED_MODE_FRONT_PANEL_OFF, 0);
 
-	bnx2x_set_led(&bp->link_params, &bp->link_vars,
-		      LED_MODE_OPER, bp->link_vars.line_speed);
+		break;
+
+	case ETHTOOL_ID_INACTIVE:
+		bnx2x_set_led(&bp->link_params, &bp->link_vars,
+			      LED_MODE_OPER,
+			      bp->link_vars.line_speed);
+	}
 
 	return 0;
 }
@@ -2204,20 +2123,10 @@
 	.set_ringparam		= bnx2x_set_ringparam,
 	.get_pauseparam		= bnx2x_get_pauseparam,
 	.set_pauseparam		= bnx2x_set_pauseparam,
-	.get_rx_csum		= bnx2x_get_rx_csum,
-	.set_rx_csum		= bnx2x_set_rx_csum,
-	.get_tx_csum		= ethtool_op_get_tx_csum,
-	.set_tx_csum		= ethtool_op_set_tx_hw_csum,
-	.set_flags		= bnx2x_set_flags,
-	.get_flags		= ethtool_op_get_flags,
-	.get_sg			= ethtool_op_get_sg,
-	.set_sg			= ethtool_op_set_sg,
-	.get_tso		= ethtool_op_get_tso,
-	.set_tso		= bnx2x_set_tso,
 	.self_test		= bnx2x_self_test,
 	.get_sset_count		= bnx2x_get_sset_count,
 	.get_strings		= bnx2x_get_strings,
-	.phys_id		= bnx2x_phys_id,
+	.set_phys_id		= bnx2x_set_phys_id,
 	.get_ethtool_stats	= bnx2x_get_ethtool_stats,
 	.get_rxnfc		= bnx2x_get_rxnfc,
 	.get_rxfh_indir		= bnx2x_get_rxfh_indir,
diff -druN linux-2.6.39-libre/drivers/net/bnx2x/bnx2x_fw_defs.h linux-3.0-rc7-libre/drivers/net/bnx2x/bnx2x_fw_defs.h
--- linux-2.6.39-libre/drivers/net/bnx2x/bnx2x_fw_defs.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/bnx2x/bnx2x_fw_defs.h	2011-07-11 19:51:52.000000000 -0400
@@ -1,6 +1,6 @@
 /* bnx2x_fw_defs.h: Broadcom Everest network driver.
  *
- * Copyright (c) 2007-2010 Broadcom Corporation
+ * Copyright (c) 2007-2011 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 -druN linux-2.6.39-libre/drivers/net/bnx2x/bnx2x_fw_file_hdr.h linux-3.0-rc7-libre/drivers/net/bnx2x/bnx2x_fw_file_hdr.h
--- linux-2.6.39-libre/drivers/net/bnx2x/bnx2x_fw_file_hdr.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/bnx2x/bnx2x_fw_file_hdr.h	2011-07-11 19:51:52.000000000 -0400
@@ -1,6 +1,6 @@
 /* bnx2x_fw_file_hdr.h: FW binary file header structure.
  *
- * Copyright (c) 2007-2009 Broadcom Corporation
+ * Copyright (c) 2007-2011 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 -druN linux-2.6.39-libre/drivers/net/bnx2x/bnx2x.h linux-3.0-rc7-libre/drivers/net/bnx2x/bnx2x.h
--- linux-2.6.39-libre/drivers/net/bnx2x/bnx2x.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/bnx2x/bnx2x.h	2011-07-11 19:51:52.000000000 -0400
@@ -1,6 +1,6 @@
 /* bnx2x.h: Broadcom Everest network driver.
  *
- * Copyright (c) 2007-2010 Broadcom Corporation
+ * Copyright (c) 2007-2011 Broadcom Corporation
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -22,8 +22,8 @@
  * (you will need to reboot afterwards) */
 /* #define BNX2X_STOP_ON_ERROR */
 
-#define DRV_MODULE_VERSION      "1.62.11-0"
-#define DRV_MODULE_RELDATE      "2011/01/31"
+#define DRV_MODULE_VERSION      "1.62.12-0"
+#define DRV_MODULE_RELDATE      "2011/03/20"
 #define BNX2X_BC_VER            0x040200
 
 #define BNX2X_MULTI_QUEUE
@@ -473,7 +473,8 @@
 #define NUM_RX_BD			(RX_DESC_CNT * NUM_RX_RINGS)
 #define MAX_RX_BD			(NUM_RX_BD - 1)
 #define MAX_RX_AVAIL			(MAX_RX_DESC_CNT * NUM_RX_RINGS - 2)
-#define MIN_RX_AVAIL			128
+#define MIN_RX_SIZE_TPA			72
+#define MIN_RX_SIZE_NONTPA		10
 #define INIT_JUMBO_RX_RING_SIZE		MAX_RX_AVAIL
 #define INIT_RX_RING_SIZE		MAX_RX_AVAIL
 #define NEXT_RX_IDX(x)		((((x) & RX_DESC_MASK) == \
@@ -893,6 +894,22 @@
 	(&bp->def_status_blk->sp_sb.\
 	index_values[HC_SP_INDEX_EQ_CONS])
 
+/* This is a data that will be used to create a link report message.
+ * We will keep the data used for the last link report in order
+ * to prevent reporting the same link parameters twice.
+ */
+struct bnx2x_link_report_data {
+	u16 line_speed;			/* Effective line speed */
+	unsigned long link_report_flags;/* BNX2X_LINK_REPORT_XXX flags */
+};
+
+enum {
+	BNX2X_LINK_REPORT_FD,		/* Full DUPLEX */
+	BNX2X_LINK_REPORT_LINK_DOWN,
+	BNX2X_LINK_REPORT_RX_FC_ON,
+	BNX2X_LINK_REPORT_TX_FC_ON,
+};
+
 struct bnx2x {
 	/* Fields used in the tx and intr/napi performance paths
 	 * are grouped together in the beginning of the structure
@@ -918,7 +935,6 @@
 
 	int			tx_ring_size;
 
-	u32			rx_csum;
 /* L2 header size + 2*VLANs (8 bytes) + LLC SNAP (8 bytes) */
 #define ETH_OVREHEAD		(ETH_HLEN + 8 + 8)
 #define ETH_MIN_PACKET_SIZE		60
@@ -1026,6 +1042,9 @@
 
 	struct link_params	link_params;
 	struct link_vars	link_vars;
+	u32			link_cnt;
+	struct bnx2x_link_report_data last_reported_link;
+
 	struct mdio_if_info	mdio;
 
 	struct bnx2x_common	common;
@@ -1223,6 +1242,10 @@
 	/* DCBX Negotiation results */
 	struct dcbx_features			dcbx_local_feat;
 	u32					dcbx_error;
+#ifdef BCM_DCBNL
+	struct dcbx_features			dcbx_remote_feat;
+	u32					dcbx_remote_flags;
+#endif
 	u32					pending_max;
 };
 
@@ -1442,6 +1465,8 @@
 #define WAIT_RAMROD_POLL	0x01
 #define WAIT_RAMROD_COMMON	0x02
 
+void bnx2x_read_mf_cfg(struct bnx2x *bp);
+
 /* dmae */
 void bnx2x_read_dmae(struct bnx2x *bp, u32 src_addr, u32 len32);
 void bnx2x_write_dmae(struct bnx2x *bp, dma_addr_t dma_addr, u32 dst_addr,
diff -druN linux-2.6.39-libre/drivers/net/bnx2x/bnx2x_hsi.h linux-3.0-rc7-libre/drivers/net/bnx2x/bnx2x_hsi.h
--- linux-2.6.39-libre/drivers/net/bnx2x/bnx2x_hsi.h	2011-05-19 02:11:32.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/bnx2x/bnx2x_hsi.h	2011-07-21 06:54:04.000000000 -0400
@@ -1,6 +1,6 @@
 /* bnx2x_hsi.h: Broadcom Everest network driver.
  *
- * Copyright (c) 2007-2010 Broadcom Corporation
+ * Copyright (c) 2007-2011 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 -druN linux-2.6.39-libre/drivers/net/bnx2x/bnx2x_init.h linux-3.0-rc7-libre/drivers/net/bnx2x/bnx2x_init.h
--- linux-2.6.39-libre/drivers/net/bnx2x/bnx2x_init.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/bnx2x/bnx2x_init.h	2011-07-11 19:51:52.000000000 -0400
@@ -1,7 +1,7 @@
 /* bnx2x_init.h: Broadcom Everest network driver.
  *               Structures and macroes needed during the initialization.
  *
- * Copyright (c) 2007-2009 Broadcom Corporation
+ * Copyright (c) 2007-2011 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 -druN linux-2.6.39-libre/drivers/net/bnx2x/bnx2x_init_ops.h linux-3.0-rc7-libre/drivers/net/bnx2x/bnx2x_init_ops.h
--- linux-2.6.39-libre/drivers/net/bnx2x/bnx2x_init_ops.h	2011-05-19 02:11:35.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/bnx2x/bnx2x_init_ops.h	2011-07-21 06:54:06.000000000 -0400
@@ -2,7 +2,7 @@
  *               Static functions needed during the initialization.
  *               This file is "included" in bnx2x_main.c.
  *
- * Copyright (c) 2007-2010 Broadcom Corporation
+ * Copyright (c) 2007-2011 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 -druN linux-2.6.39-libre/drivers/net/bnx2x/bnx2x_link.c linux-3.0-rc7-libre/drivers/net/bnx2x/bnx2x_link.c
--- linux-2.6.39-libre/drivers/net/bnx2x/bnx2x_link.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/bnx2x/bnx2x_link.c	2011-07-11 19:51:52.000000000 -0400
@@ -385,7 +385,7 @@
 	return 0;
 }
 /******************************************************************/
-/*			ETS section				  */
+/*			PFC section				  */
 /******************************************************************/
 
 static void bnx2x_bmac2_get_pfc_stat(struct link_params *params,
@@ -1301,14 +1301,12 @@
 	return 0;
 }
 
-/*
- * get_emac_base
- *
- * @param cb
- * @param mdc_mdio_access
- * @param port
+/**
+ * bnx2x_get_emac_base - retrive emac base address
  *
- * @return u32
+ * @bp:			driver handle
+ * @mdc_mdio_access:	access type
+ * @port:		port id
  *
  * This function selects the MDC/MDIO access (through emac0 or
  * emac1) depend on the mdc_mdio_access, port, port swapped. Each
diff -druN linux-2.6.39-libre/drivers/net/bnx2x/bnx2x_main.c linux-3.0-rc7-libre/drivers/net/bnx2x/bnx2x_main.c
--- linux-2.6.39-libre/drivers/net/bnx2x/bnx2x_main.c	2011-05-19 02:11:29.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/bnx2x/bnx2x_main.c	2011-07-21 06:54:00.000000000 -0400
@@ -1,6 +1,6 @@
 /* bnx2x_main.c: Broadcom Everest network driver.
  *
- * Copyright (c) 2007-2010 Broadcom Corporation
+ * Copyright (c) 2007-2011 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
@@ -49,6 +49,7 @@
 #include <linux/zlib.h>
 #include <linux/io.h>
 #include <linux/stringify.h>
+#include <linux/vmalloc.h>
 
 #define BNX2X_MAIN
 #include "bnx2x.h"
@@ -568,7 +569,7 @@
 				      struct dmae_command *dmae)
 {
 	u32 *wb_comp = bnx2x_sp(bp, wb_comp);
-	int cnt = CHIP_REV_IS_SLOW(bp) ? (400000) : 40;
+	int cnt = CHIP_REV_IS_SLOW(bp) ? (400000) : 4000;
 	int rc = 0;
 
 	DP(BNX2X_MSG_OFF, "data before [0x%08x 0x%08x 0x%08x 0x%08x]\n",
@@ -2033,7 +2034,7 @@
 	return CMNG_FNS_NONE;
 }
 
-static void bnx2x_read_mf_cfg(struct bnx2x *bp)
+void bnx2x_read_mf_cfg(struct bnx2x *bp)
 {
 	int vn, n = (CHIP_MODE_IS_4_PORT(bp) ? 2 : 1);
 
@@ -2120,7 +2121,6 @@
 /* This function is called upon link interrupt */
 static void bnx2x_link_attn(struct bnx2x *bp)
 {
-	u32 prev_link_status = bp->link_vars.link_status;
 	/* Make sure that we are synced with the current statistics */
 	bnx2x_stats_handle(bp, STATS_EVENT_STOP);
 
@@ -2165,17 +2165,15 @@
 			   "single function mode without fairness\n");
 	}
 
+	__bnx2x_link_report(bp);
+
 	if (IS_MF(bp))
 		bnx2x_link_sync_notify(bp);
-
-	/* indicate link status only if link status actually changed */
-	if (prev_link_status != bp->link_vars.link_status)
-		bnx2x_link_report(bp);
 }
 
 void bnx2x__link_status_update(struct bnx2x *bp)
 {
-	if ((bp->state != BNX2X_STATE_OPEN) || (bp->flags & MF_FUNC_DIS))
+	if (bp->state != BNX2X_STATE_OPEN)
 		return;
 
 	bnx2x_link_status_update(&bp->link_params, &bp->link_vars);
@@ -2185,10 +2183,6 @@
 	else
 		bnx2x_stats_handle(bp, STATS_EVENT_STOP);
 
-	/* the link status update could be the result of a DCC event
-	   hence re-read the shmem mf configuration */
-	bnx2x_read_mf_cfg(bp);
-
 	/* indicate link status */
 	bnx2x_link_report(bp);
 }
@@ -2226,12 +2220,13 @@
 u32 bnx2x_fw_command(struct bnx2x *bp, u32 command, u32 param)
 {
 	int mb_idx = BP_FW_MB_IDX(bp);
-	u32 seq = ++bp->fw_seq;
+	u32 seq;
 	u32 rc = 0;
 	u32 cnt = 1;
 	u8 delay = CHIP_REV_IS_SLOW(bp) ? 100 : 10;
 
 	mutex_lock(&bp->fw_mb_mutex);
+	seq = ++bp->fw_seq;
 	SHMEM_WR(bp, func_mb[mb_idx].drv_mb_param, param);
 	SHMEM_WR(bp, func_mb[mb_idx].drv_mb_header, (command | seq));
 
@@ -3117,10 +3112,14 @@
 			if (val & DRV_STATUS_SET_MF_BW)
 				bnx2x_set_mf_bw(bp);
 
-			bnx2x__link_status_update(bp);
 			if ((bp->port.pmf == 0) && (val & DRV_STATUS_PMF))
 				bnx2x_pmf_update(bp);
 
+			/* Always call it here: bnx2x_link_report() will
+			 * prevent the link indication duplication.
+			 */
+			bnx2x__link_status_update(bp);
+
 			if (bp->port.pmf &&
 			    (val & DRV_STATUS_DCBX_NEGOTIATION_RESULTS) &&
 				bp->dcbx_enabled > 0)
@@ -3666,7 +3665,8 @@
 				      union event_ring_elem *elem)
 {
 	if (!bp->cnic_eth_dev.starting_cid  ||
-	    cid < bp->cnic_eth_dev.starting_cid)
+	    (cid < bp->cnic_eth_dev.starting_cid &&
+	    cid != bp->cnic_eth_dev.iscsi_l2_cid))
 		return 1;
 
 	DP(BNX2X_MSG_SP, "got delete ramrod for CNIC CID %d\n", cid);
@@ -3901,10 +3901,9 @@
 
 	if (poll) {
 		struct bnx2x_fastpath *fp = &bp->fp[0];
-		int rc;
 
 		bnx2x_tx_int(fp);
-		rc = bnx2x_rx_int(fp, 1000);
+		bnx2x_rx_int(fp, 1000);
 	}
 
 	if (!BP_NOMCP(bp)) {
@@ -4059,7 +4058,6 @@
 	struct hc_status_block_data_e2 sb_data_e2;
 	struct hc_status_block_data_e1x sb_data_e1x;
 	struct hc_status_block_sm  *hc_sm_p;
-	struct hc_index_data *hc_index_p;
 	int data_size;
 	u32 *sb_data_p;
 
@@ -4080,7 +4078,6 @@
 		sb_data_e2.common.host_sb_addr.hi = U64_HI(mapping);
 		sb_data_e2.common.host_sb_addr.lo = U64_LO(mapping);
 		hc_sm_p = sb_data_e2.common.state_machine;
-		hc_index_p = sb_data_e2.index_data;
 		sb_data_p = (u32 *)&sb_data_e2;
 		data_size = sizeof(struct hc_status_block_data_e2)/sizeof(u32);
 	} else {
@@ -4094,7 +4091,6 @@
 		sb_data_e1x.common.host_sb_addr.hi = U64_HI(mapping);
 		sb_data_e1x.common.host_sb_addr.lo = U64_LO(mapping);
 		hc_sm_p = sb_data_e1x.common.state_machine;
-		hc_index_p = sb_data_e1x.index_data;
 		sb_data_p = (u32 *)&sb_data_e1x;
 		data_size = sizeof(struct hc_status_block_data_e1x)/sizeof(u32);
 	}
@@ -4451,7 +4447,7 @@
 
 	fp->state = BNX2X_FP_STATE_CLOSED;
 
-	fp->index = fp->cid = fp_idx;
+	fp->cid = fp_idx;
 	fp->cl_id = BP_L_ID(bp) + fp_idx;
 	fp->fw_sb_id = bp->base_fw_ndsb + fp->cl_id + CNIC_CONTEXT_USE;
 	fp->igu_sb_id = bp->igu_base_sb + fp_idx + CNIC_CONTEXT_USE;
@@ -4539,8 +4535,7 @@
 	if (bp->strm  == NULL)
 		goto gunzip_nomem2;
 
-	bp->strm->workspace = kmalloc(zlib_inflate_workspacesize(),
-				      GFP_KERNEL);
+	bp->strm->workspace = vmalloc(zlib_inflate_workspacesize());
 	if (bp->strm->workspace == NULL)
 		goto gunzip_nomem3;
 
@@ -4563,9 +4558,11 @@
 
 static void bnx2x_gunzip_end(struct bnx2x *bp)
 {
-	kfree(bp->strm->workspace);
-	kfree(bp->strm);
-	bp->strm = NULL;
+	if (bp->strm) {
+		vfree(bp->strm->workspace);
+		kfree(bp->strm);
+		bp->strm = NULL;
+	}
 
 	if (bp->gunzip_buf) {
 		dma_free_coherent(&bp->pdev->dev, FW_BUF_SIZE, bp->gunzip_buf,
@@ -5873,9 +5870,6 @@
 
 	bp->dmae_ready = 0;
 	spin_lock_init(&bp->dmae_lock);
-	rc = bnx2x_gunzip_init(bp);
-	if (rc)
-		return rc;
 
 	switch (load_code) {
 	case FW_MSG_CODE_DRV_LOAD_COMMON:
@@ -5919,80 +5913,10 @@
 
 void bnx2x_free_mem(struct bnx2x *bp)
 {
-
-#define BNX2X_PCI_FREE(x, y, size) \
-	do { \
-		if (x) { \
-			dma_free_coherent(&bp->pdev->dev, size, (void *)x, y); \
-			x = NULL; \
-			y = 0; \
-		} \
-	} while (0)
-
-#define BNX2X_FREE(x) \
-	do { \
-		if (x) { \
-			kfree((void *)x); \
-			x = NULL; \
-		} \
-	} while (0)
-
-	int i;
+	bnx2x_gunzip_end(bp);
 
 	/* fastpath */
-	/* Common */
-	for_each_queue(bp, i) {
-#ifdef BCM_CNIC
-		/* FCoE client uses default status block */
-		if (IS_FCOE_IDX(i)) {
-			union host_hc_status_block *sb =
-				&bnx2x_fp(bp, i, status_blk);
-			memset(sb, 0, sizeof(union host_hc_status_block));
-			bnx2x_fp(bp, i, status_blk_mapping) = 0;
-		} else {
-#endif
-		/* status blocks */
-		if (CHIP_IS_E2(bp))
-			BNX2X_PCI_FREE(bnx2x_fp(bp, i, status_blk.e2_sb),
-				       bnx2x_fp(bp, i, status_blk_mapping),
-				       sizeof(struct host_hc_status_block_e2));
-		else
-			BNX2X_PCI_FREE(bnx2x_fp(bp, i, status_blk.e1x_sb),
-				       bnx2x_fp(bp, i, status_blk_mapping),
-				       sizeof(struct host_hc_status_block_e1x));
-#ifdef BCM_CNIC
-		}
-#endif
-	}
-	/* Rx */
-	for_each_rx_queue(bp, i) {
-
-		/* fastpath rx rings: rx_buf rx_desc rx_comp */
-		BNX2X_FREE(bnx2x_fp(bp, i, rx_buf_ring));
-		BNX2X_PCI_FREE(bnx2x_fp(bp, i, rx_desc_ring),
-			       bnx2x_fp(bp, i, rx_desc_mapping),
-			       sizeof(struct eth_rx_bd) * NUM_RX_BD);
-
-		BNX2X_PCI_FREE(bnx2x_fp(bp, i, rx_comp_ring),
-			       bnx2x_fp(bp, i, rx_comp_mapping),
-			       sizeof(struct eth_fast_path_rx_cqe) *
-			       NUM_RCQ_BD);
-
-		/* SGE ring */
-		BNX2X_FREE(bnx2x_fp(bp, i, rx_page_ring));
-		BNX2X_PCI_FREE(bnx2x_fp(bp, i, rx_sge_ring),
-			       bnx2x_fp(bp, i, rx_sge_mapping),
-			       BCM_PAGE_SIZE * NUM_RX_SGE_PAGES);
-	}
-	/* Tx */
-	for_each_tx_queue(bp, i) {
-
-		/* fastpath tx rings: tx_buf tx_desc */
-		BNX2X_FREE(bnx2x_fp(bp, i, tx_buf_ring));
-		BNX2X_PCI_FREE(bnx2x_fp(bp, i, tx_desc_ring),
-			       bnx2x_fp(bp, i, tx_desc_mapping),
-			       sizeof(union eth_tx_bd_types) * NUM_TX_BD);
-	}
+	bnx2x_free_fp_mem(bp);
 	/* end of fastpath */
 
 	BNX2X_PCI_FREE(bp->def_status_blk, bp->def_status_blk_mapping,
@@ -6025,101 +5949,13 @@
 		       BCM_PAGE_SIZE * NUM_EQ_PAGES);
 
 	BNX2X_FREE(bp->rx_indir_table);
-
-#undef BNX2X_PCI_FREE
-#undef BNX2X_KFREE
 }
 
-static inline void set_sb_shortcuts(struct bnx2x *bp, int index)
-{
-	union host_hc_status_block status_blk = bnx2x_fp(bp, index, status_blk);
-	if (CHIP_IS_E2(bp)) {
-		bnx2x_fp(bp, index, sb_index_values) =
-			(__le16 *)status_blk.e2_sb->sb.index_values;
-		bnx2x_fp(bp, index, sb_running_index) =
-			(__le16 *)status_blk.e2_sb->sb.running_index;
-	} else {
-		bnx2x_fp(bp, index, sb_index_values) =
-			(__le16 *)status_blk.e1x_sb->sb.index_values;
-		bnx2x_fp(bp, index, sb_running_index) =
-			(__le16 *)status_blk.e1x_sb->sb.running_index;
-	}
-}
 
 int bnx2x_alloc_mem(struct bnx2x *bp)
 {
-#define BNX2X_PCI_ALLOC(x, y, size) \
-	do { \
-		x = dma_alloc_coherent(&bp->pdev->dev, size, y, GFP_KERNEL); \
-		if (x == NULL) \
-			goto alloc_mem_err; \
-		memset(x, 0, size); \
-	} while (0)
-
-#define BNX2X_ALLOC(x, size) \
-	do { \
-		x = kzalloc(size, GFP_KERNEL); \
-		if (x == NULL) \
-			goto alloc_mem_err; \
-	} while (0)
-
-	int i;
-
-	/* fastpath */
-	/* Common */
-	for_each_queue(bp, i) {
-		union host_hc_status_block *sb = &bnx2x_fp(bp, i, status_blk);
-		bnx2x_fp(bp, i, bp) = bp;
-		/* status blocks */
-#ifdef BCM_CNIC
-		if (!IS_FCOE_IDX(i)) {
-#endif
-			if (CHIP_IS_E2(bp))
-				BNX2X_PCI_ALLOC(sb->e2_sb,
-				    &bnx2x_fp(bp, i, status_blk_mapping),
-				    sizeof(struct host_hc_status_block_e2));
-			else
-				BNX2X_PCI_ALLOC(sb->e1x_sb,
-				    &bnx2x_fp(bp, i, status_blk_mapping),
-				    sizeof(struct host_hc_status_block_e1x));
-#ifdef BCM_CNIC
-		}
-#endif
-		set_sb_shortcuts(bp, i);
-	}
-	/* Rx */
-	for_each_queue(bp, i) {
-
-		/* fastpath rx rings: rx_buf rx_desc rx_comp */
-		BNX2X_ALLOC(bnx2x_fp(bp, i, rx_buf_ring),
-				sizeof(struct sw_rx_bd) * NUM_RX_BD);
-		BNX2X_PCI_ALLOC(bnx2x_fp(bp, i, rx_desc_ring),
-				&bnx2x_fp(bp, i, rx_desc_mapping),
-				sizeof(struct eth_rx_bd) * NUM_RX_BD);
-
-		BNX2X_PCI_ALLOC(bnx2x_fp(bp, i, rx_comp_ring),
-				&bnx2x_fp(bp, i, rx_comp_mapping),
-				sizeof(struct eth_fast_path_rx_cqe) *
-				NUM_RCQ_BD);
-
-		/* SGE ring */
-		BNX2X_ALLOC(bnx2x_fp(bp, i, rx_page_ring),
-				sizeof(struct sw_rx_page) * NUM_RX_SGE);
-		BNX2X_PCI_ALLOC(bnx2x_fp(bp, i, rx_sge_ring),
-				&bnx2x_fp(bp, i, rx_sge_mapping),
-				BCM_PAGE_SIZE * NUM_RX_SGE_PAGES);
-	}
-	/* Tx */
-	for_each_queue(bp, i) {
-
-		/* fastpath tx rings: tx_buf tx_desc */
-		BNX2X_ALLOC(bnx2x_fp(bp, i, tx_buf_ring),
-				sizeof(struct sw_tx_bd) * NUM_TX_BD);
-		BNX2X_PCI_ALLOC(bnx2x_fp(bp, i, tx_desc_ring),
-				&bnx2x_fp(bp, i, tx_desc_mapping),
-				sizeof(union eth_tx_bd_types) * NUM_TX_BD);
-	}
-	/* end of fastpath */
+	if (bnx2x_gunzip_init(bp))
+		return -ENOMEM;
 
 #ifdef BCM_CNIC
 	if (CHIP_IS_E2(bp))
@@ -6159,14 +5995,18 @@
 
 	BNX2X_ALLOC(bp->rx_indir_table, sizeof(bp->rx_indir_table[0]) *
 		    TSTORM_INDIRECTION_TABLE_SIZE);
+
+	/* fastpath */
+	/* need to be done at the end, since it's self adjusting to amount
+	 * of memory available for RSS queues
+	 */
+	if (bnx2x_alloc_fp_mem(bp))
+		goto alloc_mem_err;
 	return 0;
 
 alloc_mem_err:
 	bnx2x_free_mem(bp);
 	return -ENOMEM;
-
-#undef BNX2X_PCI_ALLOC
-#undef BNX2X_ALLOC
 }
 
 /*
@@ -6194,14 +6034,14 @@
 }
 
 /**
- * Sets a MAC in a CAM for a few L2 Clients for E1x chips
+ * bnx2x_set_mac_addr_gen - set a MAC in a CAM for a few L2 Clients for E1x chips
  *
- * @param bp driver descriptor
- * @param set set or clear an entry (1 or 0)
- * @param mac pointer to a buffer containing a MAC
- * @param cl_bit_vec bit vector of clients to register a MAC for
- * @param cam_offset offset in a CAM to use
- * @param is_bcast is the set MAC a broadcast address (for E1 only)
+ * @bp:		driver handle
+ * @set:	set or clear an entry (1 or 0)
+ * @mac:	pointer to a buffer containing a MAC
+ * @cl_bit_vec:	bit vector of clients to register a MAC for
+ * @cam_offset:	offset in a CAM to use
+ * @is_bcast:	is the set MAC a broadcast address (for E1 only)
  */
 static void bnx2x_set_mac_addr_gen(struct bnx2x *bp, int set, const u8 *mac,
 				   u32 cl_bit_vec, u8 cam_offset,
@@ -6561,14 +6401,13 @@
 
 #ifdef BCM_CNIC
 /**
- * Set iSCSI MAC(s) at the next enties in the CAM after the ETH
- * MAC(s). This function will wait until the ramdord completion
- * returns.
+ * bnx2x_set_iscsi_eth_mac_addr - set iSCSI MAC(s).
  *
- * @param bp driver handle
- * @param set set or clear the CAM entry
+ * @bp:		driver handle
+ * @set:	set or clear the CAM entry
  *
- * @return 0 if cussess, -ENODEV if ramrod doesn't return.
+ * This function will wait until the ramdord completion returns.
+ * Return 0 if success, -ENODEV if ramrod doesn't return.
  */
 static int bnx2x_set_iscsi_eth_mac_addr(struct bnx2x *bp, int set)
 {
@@ -6589,14 +6428,13 @@
 }
 
 /**
- * Set FCoE L2 MAC(s) at the next enties in the CAM after the
- * ETH MAC(s). This function will wait until the ramdord
- * completion returns.
+ * bnx2x_set_fip_eth_mac_addr - set FCoE L2 MAC(s)
  *
- * @param bp driver handle
- * @param set set or clear the CAM entry
+ * @bp:		driver handle
+ * @set:	set or clear the CAM entry
  *
- * @return 0 if cussess, -ENODEV if ramrod doesn't return.
+ * This function will wait until the ramrod completion returns.
+ * Returns 0 if success, -ENODEV if ramrod doesn't return.
  */
 int bnx2x_set_fip_eth_mac_addr(struct bnx2x *bp, int set)
 {
@@ -6800,12 +6638,11 @@
 }
 
 /**
- * Configure interrupt mode according to current configuration.
- * In case of MSI-X it will also try to enable MSI-X.
+ * bnx2x_set_int_mode - configure interrupt mode
  *
- * @param bp
+ * @bp:		driver handle
  *
- * @return int
+ * In case of MSI-X it will also try to enable MSI-X.
  */
 static int __devinit bnx2x_set_int_mode(struct bnx2x *bp)
 {
@@ -7389,10 +7226,11 @@
 	MF_CFG_WR(bp, shared_mf_config.clp_mb, val | SHARED_MF_CLP_MAGIC);
 }
 
-/* Restore the value of the `magic' bit.
+/**
+ * bnx2x_clp_reset_done - restore the value of the `magic' bit.
  *
- * @param pdev Device handle.
- * @param magic_val Old value of the `magic' bit.
+ * @bp:		driver handle
+ * @magic_val:	old value of the `magic' bit.
  */
 static void bnx2x_clp_reset_done(struct bnx2x *bp, u32 magic_val)
 {
@@ -7403,10 +7241,12 @@
 }
 
 /**
- * Prepares for MCP reset: takes care of CLP configurations.
+ * bnx2x_reset_mcp_prep - prepare for MCP reset.
  *
- * @param bp
- * @param magic_val Old value of 'magic' bit.
+ * @bp:		driver handle
+ * @magic_val:	old value of 'magic' bit.
+ *
+ * Takes care of CLP configurations.
  */
 static void bnx2x_reset_mcp_prep(struct bnx2x *bp, u32 *magic_val)
 {
@@ -7431,10 +7271,10 @@
 #define MCP_TIMEOUT      5000   /* 5 seconds (in ms) */
 #define MCP_ONE_TIMEOUT  100    /* 100 ms */
 
-/* Waits for MCP_ONE_TIMEOUT or MCP_ONE_TIMEOUT*10,
- * depending on the HW type.
+/**
+ * bnx2x_mcp_wait_one - wait for MCP_ONE_TIMEOUT
  *
- * @param bp
+ * @bp:	driver handle
  */
 static inline void bnx2x_mcp_wait_one(struct bnx2x *bp)
 {
@@ -7446,51 +7286,35 @@
 		msleep(MCP_ONE_TIMEOUT);
 }
 
-static int bnx2x_reset_mcp_comp(struct bnx2x *bp, u32 magic_val)
+/*
+ * initializes bp->common.shmem_base and waits for validity signature to appear
+ */
+static int bnx2x_init_shmem(struct bnx2x *bp)
 {
-	u32 shmem, cnt, validity_offset, val;
-	int rc = 0;
-
-	msleep(100);
-
-	/* Get shmem offset */
-	shmem = REG_RD(bp, MISC_REG_SHARED_MEM_ADDR);
-	if (shmem == 0) {
-		BNX2X_ERR("Shmem 0 return failure\n");
-		rc = -ENOTTY;
-		goto exit_lbl;
-	}
+	int cnt = 0;
+	u32 val = 0;
 
-	validity_offset = offsetof(struct shmem_region, validity_map[0]);
+	do {
+		bp->common.shmem_base = REG_RD(bp, MISC_REG_SHARED_MEM_ADDR);
+		if (bp->common.shmem_base) {
+			val = SHMEM_RD(bp, validity_map[BP_PORT(bp)]);
+			if (val & SHR_MEM_VALIDITY_MB)
+				return 0;
+		}
 
-	/* Wait for MCP to come up */
-	for (cnt = 0; cnt < (MCP_TIMEOUT / MCP_ONE_TIMEOUT); cnt++) {
-		/* TBD: its best to check validity map of last port.
-		 * currently checks on port 0.
-		 */
-		val = REG_RD(bp, shmem + validity_offset);
-		DP(NETIF_MSG_HW, "shmem 0x%x validity map(0x%x)=0x%x\n", shmem,
-		   shmem + validity_offset, val);
+		bnx2x_mcp_wait_one(bp);
 
-		/* check that shared memory is valid. */
-		if ((val & (SHR_MEM_VALIDITY_DEV_INFO | SHR_MEM_VALIDITY_MB))
-		    == (SHR_MEM_VALIDITY_DEV_INFO | SHR_MEM_VALIDITY_MB))
-			break;
+	} while (cnt++ < (MCP_TIMEOUT / MCP_ONE_TIMEOUT));
 
-		bnx2x_mcp_wait_one(bp);
-	}
+	BNX2X_ERR("BAD MCP validity signature\n");
 
-	DP(NETIF_MSG_HW, "Cnt=%d Shmem validity map 0x%x\n", cnt, val);
+	return -ENODEV;
+}
 
-	/* Check that shared memory is valid. This indicates that MCP is up. */
-	if ((val & (SHR_MEM_VALIDITY_DEV_INFO | SHR_MEM_VALIDITY_MB)) !=
-	    (SHR_MEM_VALIDITY_DEV_INFO | SHR_MEM_VALIDITY_MB)) {
-		BNX2X_ERR("Shmem signature not present. MCP is not up !!\n");
-		rc = -ENOTTY;
-		goto exit_lbl;
-	}
+static int bnx2x_reset_mcp_comp(struct bnx2x *bp, u32 magic_val)
+{
+	int rc = bnx2x_init_shmem(bp);
 
-exit_lbl:
 	/* Restore the `magic' bit value */
 	if (!CHIP_IS_E1(bp))
 		bnx2x_clp_reset_done(bp, magic_val);
@@ -8003,10 +7827,12 @@
 	BNX2X_DEV_INFO("flash_size 0x%x (%d)\n",
 		       bp->common.flash_size, bp->common.flash_size);
 
-	bp->common.shmem_base = REG_RD(bp, MISC_REG_SHARED_MEM_ADDR);
+	bnx2x_init_shmem(bp);
+
 	bp->common.shmem2_base = REG_RD(bp, (BP_PATH(bp) ?
 					MISC_REG_GENERIC_CR_1 :
 					MISC_REG_GENERIC_CR_0));
+
 	bp->link_params.shmem_base = bp->common.shmem_base;
 	bp->link_params.shmem2_base = bp->common.shmem2_base;
 	BNX2X_DEV_INFO("shmem offset 0x%x  shmem2 offset 0x%x\n",
@@ -8018,11 +7844,6 @@
 		return;
 	}
 
-	val = SHMEM_RD(bp, validity_map[BP_PORT(bp)]);
-	if ((val & (SHR_MEM_VALIDITY_DEV_INFO | SHR_MEM_VALIDITY_MB))
-		!= (SHR_MEM_VALIDITY_DEV_INFO | SHR_MEM_VALIDITY_MB))
-		BNX2X_ERR("BAD MCP validity signature\n");
-
 	bp->common.hw_config = SHMEM_RD(bp, dev_info.shared_hw_config.config);
 	BNX2X_DEV_INFO("hw_config 0x%08x\n", bp->common.hw_config);
 
@@ -8056,13 +7877,9 @@
 		(val >= REQ_BC_VER_4_VRFY_SPECIFIC_PHY_OPT_MDL) ?
 		FEATURE_CONFIG_BC_SUPPORTS_DUAL_PHY_OPT_MDL_VRFY : 0;
 
-	if (BP_E1HVN(bp) == 0) {
-		pci_read_config_word(bp->pdev, bp->pm_cap + PCI_PM_PMC, &pmc);
-		bp->flags |= (pmc & PCI_PM_CAP_PME_D3cold) ? 0 : NO_WOL_FLAG;
-	} else {
-		/* no WOL capability for E1HVN != 0 */
-		bp->flags |= NO_WOL_FLAG;
-	}
+	pci_read_config_word(bp->pdev, bp->pm_cap + PCI_PM_PMC, &pmc);
+	bp->flags |= (pmc & PCI_PM_CAP_PME_D3cold) ? 0 : NO_WOL_FLAG;
+
 	BNX2X_DEV_INFO("%sWoL capable\n",
 		       (bp->flags & NO_WOL_FLAG) ? "not " : "");
 
@@ -8568,15 +8385,6 @@
 				BNX2X_DEV_INFO("Read iSCSI MAC: "
 					       "0x%x:0x%04x\n", val2, val);
 				bnx2x_set_mac_buf(iscsi_mac, val, val2);
-
-				/* Disable iSCSI OOO if MAC configuration is
-				 * invalid.
-				 */
-				if (!is_valid_ether_addr(iscsi_mac)) {
-					bp->flags |= NO_ISCSI_OOO_FLAG |
-						     NO_ISCSI_FLAG;
-					memset(iscsi_mac, 0, ETH_ALEN);
-				}
 			} else
 				bp->flags |= NO_ISCSI_OOO_FLAG | NO_ISCSI_FLAG;
 
@@ -8589,13 +8397,6 @@
 					       "0x%x:0x%04x\n", val2, val);
 				bnx2x_set_mac_buf(fip_mac, val, val2);
 
-				/* Disable FCoE if MAC configuration is
-				 * invalid.
-				 */
-				if (!is_valid_ether_addr(fip_mac)) {
-					bp->flags |= NO_FCOE_FLAG;
-					memset(bp->fip_mac, 0, ETH_ALEN);
-				}
 			} else
 				bp->flags |= NO_FCOE_FLAG;
 		}
@@ -8626,13 +8427,29 @@
 		else if (!IS_MF(bp))
 			memcpy(fip_mac, iscsi_mac, ETH_ALEN);
 	}
+
+	/* Disable iSCSI if MAC configuration is
+	 * invalid.
+	 */
+	if (!is_valid_ether_addr(iscsi_mac)) {
+		bp->flags |= NO_ISCSI_FLAG;
+		memset(iscsi_mac, 0, ETH_ALEN);
+	}
+
+	/* Disable FCoE if MAC configuration is
+	 * invalid.
+	 */
+	if (!is_valid_ether_addr(fip_mac)) {
+		bp->flags |= NO_FCOE_FLAG;
+		memset(bp->fip_mac, 0, ETH_ALEN);
+	}
 #endif
 }
 
 static int __devinit bnx2x_get_hwinfo(struct bnx2x *bp)
 {
 	int /*abs*/func = BP_ABS_FUNC(bp);
-	int vn, port;
+	int vn;
 	u32 val = 0;
 	int rc = 0;
 
@@ -8667,7 +8484,6 @@
 	bp->mf_ov = 0;
 	bp->mf_mode = 0;
 	vn = BP_E1HVN(bp);
-	port = BP_PORT(bp);
 
 	if (!CHIP_IS_E1(bp) && !BP_NOMCP(bp)) {
 		DP(NETIF_MSG_PROBE,
@@ -8901,8 +8717,6 @@
 	bp->multi_mode = multi_mode;
 	bp->int_mode = int_mode;
 
-	bp->dev->features |= NETIF_F_GRO;
-
 	/* Set TPA flags */
 	if (disable_tpa) {
 		bp->flags &= ~TPA_ENABLE_FLAG;
@@ -8922,8 +8736,6 @@
 
 	bp->tx_ring_size = MAX_TX_AVAIL;
 
-	bp->rx_csum = 1;
-
 	/* make sure that the numbers are in the right granularity */
 	bp->tx_ticks = (50 / BNX2X_BTR) * BNX2X_BTR;
 	bp->rx_ticks = (25 / BNX2X_BTR) * BNX2X_BTR;
@@ -9301,6 +9113,8 @@
 	.ndo_validate_addr	= eth_validate_addr,
 	.ndo_do_ioctl		= bnx2x_ioctl,
 	.ndo_change_mtu		= bnx2x_change_mtu,
+	.ndo_fix_features	= bnx2x_fix_features,
+	.ndo_set_features	= bnx2x_set_features,
 	.ndo_tx_timeout		= bnx2x_tx_timeout,
 #ifdef CONFIG_NET_POLL_CONTROLLER
 	.ndo_poll_controller	= poll_bnx2x,
@@ -9427,20 +9241,20 @@
 
 	dev->netdev_ops = &bnx2x_netdev_ops;
 	bnx2x_set_ethtool_ops(dev);
-	dev->features |= NETIF_F_SG;
-	dev->features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;
+
+	dev->hw_features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
+		NETIF_F_TSO | NETIF_F_TSO_ECN | NETIF_F_TSO6 |
+		NETIF_F_RXCSUM | NETIF_F_LRO | NETIF_F_HW_VLAN_TX;
+
+	dev->vlan_features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
+		NETIF_F_TSO | NETIF_F_TSO_ECN | NETIF_F_TSO6 | NETIF_F_HIGHDMA;
+
+	dev->features |= dev->hw_features | NETIF_F_HW_VLAN_RX;
 	if (bp->flags & USING_DAC_FLAG)
 		dev->features |= NETIF_F_HIGHDMA;
-	dev->features |= (NETIF_F_TSO | NETIF_F_TSO_ECN);
-	dev->features |= NETIF_F_TSO6;
-	dev->features |= (NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX);
 
-	dev->vlan_features |= NETIF_F_SG;
-	dev->vlan_features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;
-	if (bp->flags & USING_DAC_FLAG)
-		dev->vlan_features |= NETIF_F_HIGHDMA;
-	dev->vlan_features |= (NETIF_F_TSO | NETIF_F_TSO_ECN);
-	dev->vlan_features |= NETIF_F_TSO6;
+	/* Add Loopback capability to the device */
+	dev->hw_features |= NETIF_F_LOOPBACK;
 
 #ifdef BCM_DCBNL
 	dev->dcbnl_ops = &bnx2x_dcbnl_ops;
@@ -10280,6 +10094,11 @@
 		break;
 	}
 
+	case DRV_CTL_ISCSI_STOPPED_CMD: {
+		bnx2x_dcbx_set_params(bp, BNX2X_DCBX_STATE_ISCSI_STOPPED);
+		break;
+	}
+
 	default:
 		BNX2X_ERR("unknown command %x\n", ctl->cmd);
 		rc = -EINVAL;
diff -druN linux-2.6.39-libre/drivers/net/bnx2x/bnx2x_reg.h linux-3.0-rc7-libre/drivers/net/bnx2x/bnx2x_reg.h
--- linux-2.6.39-libre/drivers/net/bnx2x/bnx2x_reg.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/bnx2x/bnx2x_reg.h	2011-07-11 19:51:52.000000000 -0400
@@ -1,6 +1,6 @@
 /* bnx2x_reg.h: Broadcom Everest network driver.
  *
- * Copyright (c) 2007-2010 Broadcom Corporation
+ * Copyright (c) 2007-2011 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 -druN linux-2.6.39-libre/drivers/net/bnx2x/bnx2x_stats.c linux-3.0-rc7-libre/drivers/net/bnx2x/bnx2x_stats.c
--- linux-2.6.39-libre/drivers/net/bnx2x/bnx2x_stats.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/bnx2x/bnx2x_stats.c	2011-07-11 19:51:52.000000000 -0400
@@ -1,6 +1,6 @@
 /* bnx2x_stats.c: Broadcom Everest network driver.
  *
- * Copyright (c) 2007-2010 Broadcom Corporation
+ * Copyright (c) 2007-2011 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 -druN linux-2.6.39-libre/drivers/net/bnx2x/bnx2x_stats.h linux-3.0-rc7-libre/drivers/net/bnx2x/bnx2x_stats.h
--- linux-2.6.39-libre/drivers/net/bnx2x/bnx2x_stats.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/bnx2x/bnx2x_stats.h	2011-07-11 19:51:52.000000000 -0400
@@ -1,6 +1,6 @@
 /* bnx2x_stats.h: Broadcom Everest network driver.
  *
- * Copyright (c) 2007-2010 Broadcom Corporation
+ * Copyright (c) 2007-2011 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 -druN linux-2.6.39-libre/drivers/net/bonding/bond_3ad.c linux-3.0-rc7-libre/drivers/net/bonding/bond_3ad.c
--- linux-2.6.39-libre/drivers/net/bonding/bond_3ad.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/bonding/bond_3ad.c	2011-07-11 19:51:52.000000000 -0400
@@ -716,11 +716,9 @@
 static u32 __get_agg_bandwidth(struct aggregator *aggregator)
 {
 	u32 bandwidth = 0;
-	u32 basic_speed;
 
 	if (aggregator->num_of_ports) {
-		basic_speed = __get_link_speed(aggregator->lag_ports);
-		switch (basic_speed) {
+		switch (__get_link_speed(aggregator->lag_ports)) {
 		case AD_LINK_SPEED_BITMASK_1MBPS:
 			bandwidth = aggregator->num_of_ports;
 			break;
@@ -2405,14 +2403,6 @@
 	struct ad_info ad_info;
 	int res = 1;
 
-	/* make sure that the slaves list will
-	 * not change during tx
-	 */
-	read_lock(&bond->lock);
-
-	if (!BOND_IS_OK(bond))
-		goto out;
-
 	if (bond_3ad_get_active_agg_info(bond, &ad_info)) {
 		pr_debug("%s: Error: bond_3ad_get_active_agg_info failed\n",
 			 dev->name);
@@ -2466,39 +2456,20 @@
 		/* no suitable interface, frame not sent */
 		dev_kfree_skb(skb);
 	}
-	read_unlock(&bond->lock);
+
 	return NETDEV_TX_OK;
 }
 
-int bond_3ad_lacpdu_recv(struct sk_buff *skb, struct net_device *dev, struct packet_type* ptype, struct net_device *orig_dev)
+void bond_3ad_lacpdu_recv(struct sk_buff *skb, struct bonding *bond,
+			  struct slave *slave)
 {
-	struct bonding *bond = netdev_priv(dev);
-	struct slave *slave = NULL;
-	int ret = NET_RX_DROP;
-
-	if (!(dev->flags & IFF_MASTER))
-		goto out;
-
-	skb = skb_share_check(skb, GFP_ATOMIC);
-	if (!skb)
-		goto out;
+	if (skb->protocol != PKT_TYPE_LACPDU)
+		return;
 
 	if (!pskb_may_pull(skb, sizeof(struct lacpdu)))
-		goto out;
+		return;
 
 	read_lock(&bond->lock);
-	slave = bond_get_slave_by_dev(netdev_priv(dev), orig_dev);
-	if (!slave)
-		goto out_unlock;
-
 	bond_3ad_rx_indication((struct lacpdu *) skb->data, slave, skb->len);
-
-	ret = NET_RX_SUCCESS;
-
-out_unlock:
 	read_unlock(&bond->lock);
-out:
-	dev_kfree_skb(skb);
-
-	return ret;
 }
diff -druN linux-2.6.39-libre/drivers/net/bonding/bond_3ad.h linux-3.0-rc7-libre/drivers/net/bonding/bond_3ad.h
--- linux-2.6.39-libre/drivers/net/bonding/bond_3ad.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/bonding/bond_3ad.h	2011-07-11 19:51:52.000000000 -0400
@@ -258,7 +258,6 @@
 				 * requested
 				 */
 	struct timer_list ad_timer;
-	struct packet_type ad_pkt_type;
 };
 
 struct ad_slave_info {
@@ -280,7 +279,8 @@
 void bond_3ad_handle_link_change(struct slave *slave, char link);
 int  bond_3ad_get_active_agg_info(struct bonding *bond, struct ad_info *ad_info);
 int bond_3ad_xmit_xor(struct sk_buff *skb, struct net_device *dev);
-int bond_3ad_lacpdu_recv(struct sk_buff *skb, struct net_device *dev, struct packet_type* ptype, struct net_device *orig_dev);
+void bond_3ad_lacpdu_recv(struct sk_buff *skb, struct bonding *bond,
+			  struct slave *slave);
 int bond_3ad_set_carrier(struct bonding *bond);
 #endif //__BOND_3AD_H__
 
diff -druN linux-2.6.39-libre/drivers/net/bonding/bond_alb.c linux-3.0-rc7-libre/drivers/net/bonding/bond_alb.c
--- linux-2.6.39-libre/drivers/net/bonding/bond_alb.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/bonding/bond_alb.c	2011-07-11 19:51:52.000000000 -0400
@@ -163,8 +163,6 @@
 	struct tlb_client_info *new_hashtbl;
 	int i;
 
-	spin_lock_init(&(bond_info->tx_hashtbl_lock));
-
 	new_hashtbl = kzalloc(size, GFP_KERNEL);
 	if (!new_hashtbl) {
 		pr_err("%s: Error: Failed to allocate TLB hash table\n",
@@ -308,49 +306,33 @@
 	_unlock_rx_hashtbl(bond);
 }
 
-static int rlb_arp_recv(struct sk_buff *skb, struct net_device *bond_dev, struct packet_type *ptype, struct net_device *orig_dev)
+static void rlb_arp_recv(struct sk_buff *skb, struct bonding *bond,
+			 struct slave *slave)
 {
-	struct bonding *bond;
-	struct arp_pkt *arp = (struct arp_pkt *)skb->data;
-	int res = NET_RX_DROP;
-
-	while (bond_dev->priv_flags & IFF_802_1Q_VLAN)
-		bond_dev = vlan_dev_real_dev(bond_dev);
+	struct arp_pkt *arp;
 
-	if (!(bond_dev->priv_flags & IFF_BONDING) ||
-	    !(bond_dev->flags & IFF_MASTER))
-		goto out;
+	if (skb->protocol != cpu_to_be16(ETH_P_ARP))
+		return;
 
+	arp = (struct arp_pkt *) skb->data;
 	if (!arp) {
 		pr_debug("Packet has no ARP data\n");
-		goto out;
+		return;
 	}
 
-	skb = skb_share_check(skb, GFP_ATOMIC);
-	if (!skb)
-		goto out;
-
-	if (!pskb_may_pull(skb, arp_hdr_len(bond_dev)))
-		goto out;
+	if (!pskb_may_pull(skb, arp_hdr_len(bond->dev)))
+		return;
 
 	if (skb->len < sizeof(struct arp_pkt)) {
 		pr_debug("Packet is too small to be an ARP\n");
-		goto out;
+		return;
 	}
 
 	if (arp->op_code == htons(ARPOP_REPLY)) {
 		/* update rx hash table for this ARP */
-		bond = netdev_priv(bond_dev);
 		rlb_update_entry_from_arp(bond, arp);
 		pr_debug("Server received an ARP Reply from client\n");
 	}
-
-	res = NET_RX_SUCCESS;
-
-out:
-	dev_kfree_skb(skb);
-
-	return res;
 }
 
 /* Caller must hold bond lock for read */
@@ -759,13 +741,10 @@
 static int rlb_initialize(struct bonding *bond)
 {
 	struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond));
-	struct packet_type *pk_type = &(BOND_ALB_INFO(bond).rlb_pkt_type);
 	struct rlb_client_info	*new_hashtbl;
 	int size = RLB_HASH_TABLE_SIZE * sizeof(struct rlb_client_info);
 	int i;
 
-	spin_lock_init(&(bond_info->rx_hashtbl_lock));
-
 	new_hashtbl = kmalloc(size, GFP_KERNEL);
 	if (!new_hashtbl) {
 		pr_err("%s: Error: Failed to allocate RLB hash table\n",
@@ -784,13 +763,8 @@
 
 	_unlock_rx_hashtbl(bond);
 
-	/*initialize packet type*/
-	pk_type->type = cpu_to_be16(ETH_P_ARP);
-	pk_type->dev = bond->dev;
-	pk_type->func = rlb_arp_recv;
-
 	/* register to receive ARPs */
-	dev_add_pack(pk_type);
+	bond->recv_probe = rlb_arp_recv;
 
 	return 0;
 }
@@ -799,8 +773,6 @@
 {
 	struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond));
 
-	dev_remove_pack(&(bond_info->rlb_pkt_type));
-
 	_lock_rx_hashtbl(bond);
 
 	kfree(bond_info->rx_hashtbl);
@@ -1249,16 +1221,10 @@
 	skb_reset_mac_header(skb);
 	eth_data = eth_hdr(skb);
 
-	/* make sure that the curr_active_slave and the slaves list do
-	 * not change during tx
+	/* make sure that the curr_active_slave do not change during tx
 	 */
-	read_lock(&bond->lock);
 	read_lock(&bond->curr_slave_lock);
 
-	if (!BOND_IS_OK(bond)) {
-		goto out;
-	}
-
 	switch (ntohs(skb->protocol)) {
 	case ETH_P_IP: {
 		const struct iphdr *iph = ip_hdr(skb);
@@ -1358,13 +1324,12 @@
 		}
 	}
 
-out:
 	if (res) {
 		/* no suitable interface, frame not sent */
 		dev_kfree_skb(skb);
 	}
 	read_unlock(&bond->curr_slave_lock);
-	read_unlock(&bond->lock);
+
 	return NETDEV_TX_OK;
 }
 
diff -druN linux-2.6.39-libre/drivers/net/bonding/bond_alb.h linux-3.0-rc7-libre/drivers/net/bonding/bond_alb.h
--- linux-2.6.39-libre/drivers/net/bonding/bond_alb.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/bonding/bond_alb.h	2011-07-11 19:51:52.000000000 -0400
@@ -129,7 +129,6 @@
 	int			lp_counter;
 	/* -------- rlb parameters -------- */
 	int rlb_enabled;
-	struct packet_type	rlb_pkt_type;
 	struct rlb_client_info	*rx_hashtbl;	/* Receive hash table */
 	spinlock_t		rx_hashtbl_lock;
 	u32			rx_hashtbl_head;
diff -druN linux-2.6.39-libre/drivers/net/bonding/bonding.h linux-3.0-rc7-libre/drivers/net/bonding/bonding.h
--- linux-2.6.39-libre/drivers/net/bonding/bonding.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/bonding/bonding.h	2011-07-11 19:51:52.000000000 -0400
@@ -24,8 +24,8 @@
 #include "bond_3ad.h"
 #include "bond_alb.h"
 
-#define DRV_VERSION	"3.7.0"
-#define DRV_RELDATE	"June 2, 2010"
+#define DRV_VERSION	"3.7.1"
+#define DRV_RELDATE	"April 27, 2011"
 #define DRV_NAME	"bonding"
 #define DRV_DESCRIPTION	"Ethernet Channel Bonding Driver"
 
@@ -39,16 +39,6 @@
 	       netif_carrier_ok(dev))
 
 /*
- * Checks whether bond is ready for transmit.
- *
- * Caller must hold bond->lock
- */
-#define BOND_IS_OK(bond)			     \
-		   (((bond)->dev->flags & IFF_UP) && \
-		    netif_running((bond)->dev)	  && \
-		    ((bond)->slave_cnt > 0))
-
-/*
  * Checks whether slave is ready for transmit.
  */
 #define SLAVE_IS_OK(slave)			        \
@@ -149,8 +139,7 @@
 	int mode;
 	int xmit_policy;
 	int miimon;
-	int num_grat_arp;
-	int num_unsol_na;
+	u8 num_peer_notif;
 	int arp_interval;
 	int arp_validate;
 	int use_carrier;
@@ -178,9 +167,6 @@
 	struct list_head vlan_list;
 	__be32 vlan_ip;
 	unsigned short vlan_id;
-#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
-	struct in6_addr vlan_ipv6;
-#endif
 };
 
 struct slave {
@@ -196,12 +182,12 @@
 	u8     backup:1,   /* indicates backup slave. Value corresponds with
 			      BOND_STATE_ACTIVE and BOND_STATE_BACKUP */
 	       inactive:1; /* indicates inactive slave */
+	u8     duplex;
 	u32    original_mtu;
 	u32    link_failure_count;
-	u8     perm_hwaddr[ETH_ALEN];
-	u16    speed;
-	u8     duplex;
+	u32    speed;
 	u16    queue_id;
+	u8     perm_hwaddr[ETH_ALEN];
 	struct ad_slave_info ad_info; /* HUGE - better to dynamically alloc */
 	struct tlb_slave_info tlb_info;
 #ifdef CONFIG_NET_POLL_CONTROLLER
@@ -231,11 +217,12 @@
 	struct   slave *primary_slave;
 	bool     force_primary;
 	s32      slave_cnt; /* never change this value outside the attach/detach wrappers */
+	void     (*recv_probe)(struct sk_buff *, struct bonding *,
+			       struct slave *);
 	rwlock_t lock;
 	rwlock_t curr_slave_lock;
 	s8       kill_timers;
-	s8	 send_grat_arp;
-	s8	 send_unsol_na;
+	u8	 send_peer_notif;
 	s8	 setup_by_slave;
 	s8       igmp_retrans;
 #ifdef CONFIG_PROC_FS
@@ -260,9 +247,6 @@
 	struct   delayed_work alb_work;
 	struct   delayed_work ad_work;
 	struct   delayed_work mcast_work;
-#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
-	struct   in6_addr master_ipv6;
-#endif
 #ifdef CONFIG_DEBUG_FS
 	/* debugging suport via debugfs */
 	struct	 dentry *debug_dir;
@@ -409,13 +393,12 @@
 int bond_parse_parm(const char *mode_arg, const struct bond_parm_tbl *tbl);
 void bond_select_active_slave(struct bonding *bond);
 void bond_change_active_slave(struct bonding *bond, struct slave *new_active);
-void bond_register_arp(struct bonding *);
-void bond_unregister_arp(struct bonding *);
 void bond_create_debugfs(void);
 void bond_destroy_debugfs(void);
 void bond_debug_register(struct bonding *bond);
 void bond_debug_unregister(struct bonding *bond);
 void bond_debug_reregister(struct bonding *bond);
+const char *bond_mode_name(int mode);
 
 struct bond_net {
 	struct net *		net;	/* Associated network namespace */
@@ -459,23 +442,4 @@
 extern const struct bond_parm_tbl pri_reselect_tbl[];
 extern struct bond_parm_tbl ad_select_tbl[];
 
-#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
-void bond_send_unsolicited_na(struct bonding *bond);
-void bond_register_ipv6_notifier(void);
-void bond_unregister_ipv6_notifier(void);
-#else
-static inline void bond_send_unsolicited_na(struct bonding *bond)
-{
-	return;
-}
-static inline void bond_register_ipv6_notifier(void)
-{
-	return;
-}
-static inline void bond_unregister_ipv6_notifier(void)
-{
-	return;
-}
-#endif
-
 #endif /* _LINUX_BONDING_H */
diff -druN linux-2.6.39-libre/drivers/net/bonding/bond_main.c linux-3.0-rc7-libre/drivers/net/bonding/bond_main.c
--- linux-2.6.39-libre/drivers/net/bonding/bond_main.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/bonding/bond_main.c	2011-07-11 19:51:52.000000000 -0400
@@ -89,8 +89,7 @@
 
 static int max_bonds	= BOND_DEFAULT_MAX_BONDS;
 static int tx_queues	= BOND_DEFAULT_TX_QUEUES;
-static int num_grat_arp = 1;
-static int num_unsol_na = 1;
+static int num_peer_notif = 1;
 static int miimon	= BOND_LINK_MON_INTERV;
 static int updelay;
 static int downdelay;
@@ -113,10 +112,12 @@
 MODULE_PARM_DESC(max_bonds, "Max number of bonded devices");
 module_param(tx_queues, int, 0);
 MODULE_PARM_DESC(tx_queues, "Max number of transmit queues (default = 16)");
-module_param(num_grat_arp, int, 0644);
-MODULE_PARM_DESC(num_grat_arp, "Number of gratuitous ARP packets to send on failover event");
-module_param(num_unsol_na, int, 0644);
-MODULE_PARM_DESC(num_unsol_na, "Number of unsolicited IPv6 Neighbor Advertisements packets to send on failover event");
+module_param_named(num_grat_arp, num_peer_notif, int, 0644);
+MODULE_PARM_DESC(num_grat_arp, "Number of peer notifications to send on "
+			       "failover event (alias of num_unsol_na)");
+module_param_named(num_unsol_na, num_peer_notif, int, 0644);
+MODULE_PARM_DESC(num_unsol_na, "Number of peer notifications to send on "
+			       "failover event (alias of num_grat_arp)");
 module_param(miimon, int, 0);
 MODULE_PARM_DESC(miimon, "Link check interval in milliseconds");
 module_param(updelay, int, 0);
@@ -128,7 +129,7 @@
 MODULE_PARM_DESC(use_carrier, "Use netif_carrier_ok (vs MII ioctls) in miimon; "
 			      "0 for off, 1 for on (default)");
 module_param(mode, charp, 0);
-MODULE_PARM_DESC(mode, "Mode of operation : 0 for balance-rr, "
+MODULE_PARM_DESC(mode, "Mode of operation; 0 for balance-rr, "
 		       "1 for active-backup, 2 for balance-xor, "
 		       "3 for broadcast, 4 for 802.3ad, 5 for balance-tlb, "
 		       "6 for balance-alb");
@@ -143,27 +144,35 @@
 				   "2 for only on active slave "
 				   "failure");
 module_param(lacp_rate, charp, 0);
-MODULE_PARM_DESC(lacp_rate, "LACPDU tx rate to request from 802.3ad partner "
-			    "(slow/fast)");
+MODULE_PARM_DESC(lacp_rate, "LACPDU tx rate to request from 802.3ad partner; "
+			    "0 for slow, 1 for fast");
 module_param(ad_select, charp, 0);
-MODULE_PARM_DESC(ad_select, "803.ad aggregation selection logic: stable (0, default), bandwidth (1), count (2)");
+MODULE_PARM_DESC(ad_select, "803.ad aggregation selection logic; "
+			    "0 for stable (default), 1 for bandwidth, "
+			    "2 for count");
 module_param(xmit_hash_policy, charp, 0);
-MODULE_PARM_DESC(xmit_hash_policy, "XOR hashing method: 0 for layer 2 (default)"
-				   ", 1 for layer 3+4");
+MODULE_PARM_DESC(xmit_hash_policy, "balance-xor and 802.3ad hashing method; "
+				   "0 for layer 2 (default), 1 for layer 3+4, "
+				   "2 for layer 2+3");
 module_param(arp_interval, int, 0);
 MODULE_PARM_DESC(arp_interval, "arp interval in milliseconds");
 module_param_array(arp_ip_target, charp, NULL, 0);
 MODULE_PARM_DESC(arp_ip_target, "arp targets in n.n.n.n form");
 module_param(arp_validate, charp, 0);
-MODULE_PARM_DESC(arp_validate, "validate src/dst of ARP probes: none (default), active, backup or all");
+MODULE_PARM_DESC(arp_validate, "validate src/dst of ARP probes; "
+			       "0 for none (default), 1 for active, "
+			       "2 for backup, 3 for all");
 module_param(fail_over_mac, charp, 0);
-MODULE_PARM_DESC(fail_over_mac, "For active-backup, do not set all slaves to the same MAC.  none (default), active or follow");
+MODULE_PARM_DESC(fail_over_mac, "For active-backup, do not set all slaves to "
+				"the same MAC; 0 for none (default), "
+				"1 for active, 2 for follow");
 module_param(all_slaves_active, int, 0);
 MODULE_PARM_DESC(all_slaves_active, "Keep all frames received on an interface"
-				     "by setting active flag for all slaves.  "
+				     "by setting active flag for all slaves; "
 				     "0 for never (default), 1 for always.");
 module_param(resend_igmp, int, 0);
-MODULE_PARM_DESC(resend_igmp, "Number of IGMP membership reports to send on link failure");
+MODULE_PARM_DESC(resend_igmp, "Number of IGMP membership reports to send on "
+			      "link failure");
 
 /*----------------------------- Global variables ----------------------------*/
 
@@ -234,7 +243,6 @@
 
 /*-------------------------- Forward declarations ---------------------------*/
 
-static void bond_send_gratuitous_arp(struct bonding *bond);
 static int bond_init(struct net_device *bond_dev);
 static void bond_uninit(struct net_device *bond_dev);
 
@@ -346,32 +354,6 @@
 }
 
 /**
- * bond_has_challenged_slaves
- * @bond: the bond we're working on
- *
- * Searches the slave list. Returns 1 if a vlan challenged slave
- * was found, 0 otherwise.
- *
- * Assumes bond->lock is held.
- */
-static int bond_has_challenged_slaves(struct bonding *bond)
-{
-	struct slave *slave;
-	int i;
-
-	bond_for_each_slave(bond, slave, i) {
-		if (slave->dev->features & NETIF_F_VLAN_CHALLENGED) {
-			pr_debug("found VLAN challenged slave - %s\n",
-				 slave->dev->name);
-			return 1;
-		}
-	}
-
-	pr_debug("no VLAN challenged slaves found\n");
-	return 0;
-}
-
-/**
  * bond_next_vlan - safely skip to the next item in the vlans list.
  * @bond: the bond we're working on
  * @curr: item we're advancing from
@@ -406,6 +388,8 @@
 	return next;
 }
 
+#define bond_queue_mapping(skb) (*(u16 *)((skb)->cb))
+
 /**
  * bond_dev_queue_xmit - Prepare skb for xmit.
  *
@@ -418,6 +402,9 @@
 {
 	skb->dev = slave_dev;
 	skb->priority = 1;
+
+	skb->queue_mapping = bond_queue_mapping(skb);
+
 	if (unlikely(netpoll_tx_running(slave_dev)))
 		bond_netpoll_send_skb(bond_get_slave_by_dev(bond, slave_dev), skb);
 	else
@@ -631,7 +618,8 @@
 static int bond_update_speed_duplex(struct slave *slave)
 {
 	struct net_device *slave_dev = slave->dev;
-	struct ethtool_cmd etool;
+	struct ethtool_cmd etool = { .cmd = ETHTOOL_GSET };
+	u32 slave_speed;
 	int res;
 
 	/* Fake speed and duplex */
@@ -645,7 +633,8 @@
 	if (res < 0)
 		return -1;
 
-	switch (etool.speed) {
+	slave_speed = ethtool_cmd_speed(&etool);
+	switch (slave_speed) {
 	case SPEED_10:
 	case SPEED_100:
 	case SPEED_1000:
@@ -663,7 +652,7 @@
 		return -1;
 	}
 
-	slave->speed = etool.speed;
+	slave->speed = slave_speed;
 	slave->duplex = etool.duplex;
 
 	return 0;
@@ -878,7 +867,7 @@
 static void bond_resend_igmp_join_requests_delayed(struct work_struct *work)
 {
 	struct bonding *bond = container_of(work, struct bonding,
-							mcast_work.work);
+					    mcast_work.work);
 	bond_resend_igmp_join_requests(bond);
 }
 
@@ -1087,6 +1076,21 @@
 	return bestslave;
 }
 
+static bool bond_should_notify_peers(struct bonding *bond)
+{
+	struct slave *slave = bond->curr_active_slave;
+
+	pr_debug("bond_should_notify_peers: bond %s slave %s\n",
+		 bond->dev->name, slave ? slave->dev->name : "NULL");
+
+	if (!slave || !bond->send_peer_notif ||
+	    test_bit(__LINK_STATE_LINKWATCH_PENDING, &slave->dev->state))
+		return false;
+
+	bond->send_peer_notif--;
+	return true;
+}
+
 /**
  * change_active_interface - change the active slave into the specified one
  * @bond: our bonding struct
@@ -1154,6 +1158,8 @@
 			bond_set_slave_inactive_flags(old_active);
 
 		if (new_active) {
+			bool should_notify_peers = false;
+
 			bond_set_slave_active_flags(new_active);
 
 			if (bond->params.fail_over_mac)
@@ -1161,17 +1167,19 @@
 						      old_active);
 
 			if (netif_running(bond->dev)) {
-				bond->send_grat_arp = bond->params.num_grat_arp;
-				bond_send_gratuitous_arp(bond);
-
-				bond->send_unsol_na = bond->params.num_unsol_na;
-				bond_send_unsolicited_na(bond);
+				bond->send_peer_notif =
+					bond->params.num_peer_notif;
+				should_notify_peers =
+					bond_should_notify_peers(bond);
 			}
 
 			write_unlock_bh(&bond->curr_slave_lock);
 			read_unlock(&bond->lock);
 
 			netdev_bonding_change(bond->dev, NETDEV_BONDING_FAILOVER);
+			if (should_notify_peers)
+				netdev_bonding_change(bond->dev,
+						      NETDEV_NOTIFY_PEERS);
 
 			read_lock(&bond->lock);
 			write_lock_bh(&bond->curr_slave_lock);
@@ -1179,10 +1187,12 @@
 	}
 
 	/* resend IGMP joins since active slave has changed or
-	 * all were sent on curr_active_slave */
-	if (((USES_PRIMARY(bond->params.mode) && new_active) ||
-	     bond->params.mode == BOND_MODE_ROUNDROBIN) &&
-	    netif_running(bond->dev)) {
+	 * all were sent on curr_active_slave.
+	 * resend only if bond is brought up with the affected
+	 * bonding modes and the retransmission is enabled */
+	if (netif_running(bond->dev) && (bond->params.resend_igmp > 0) &&
+	    ((USES_PRIMARY(bond->params.mode) && new_active) ||
+	     bond->params.mode == BOND_MODE_ROUNDROBIN)) {
 		bond->igmp_retrans = bond->params.resend_igmp;
 		queue_delayed_work(bond->wq, &bond->mcast_work, 0);
 	}
@@ -1287,6 +1297,7 @@
 		goto out;
 
 	np->dev = slave->dev;
+	strlcpy(np->dev_name, slave->dev->name, IFNAMSIZ);
 	err = __netpoll_setup(np);
 	if (err) {
 		kfree(np);
@@ -1387,52 +1398,68 @@
 	return 0;
 }
 
-#define BOND_VLAN_FEATURES \
-	(NETIF_F_VLAN_CHALLENGED | NETIF_F_HW_VLAN_RX | NETIF_F_HW_VLAN_TX | \
-	 NETIF_F_HW_VLAN_FILTER)
-
-/*
- * Compute the common dev->feature set available to all slaves.  Some
- * feature bits are managed elsewhere, so preserve those feature bits
- * on the master device.
- */
-static int bond_compute_features(struct bonding *bond)
+static u32 bond_fix_features(struct net_device *dev, u32 features)
 {
 	struct slave *slave;
-	struct net_device *bond_dev = bond->dev;
-	u32 features = bond_dev->features;
-	u32 vlan_features = 0;
-	unsigned short max_hard_header_len = max((u16)ETH_HLEN,
-						bond_dev->hard_header_len);
+	struct bonding *bond = netdev_priv(dev);
+	u32 mask;
 	int i;
 
-	features &= ~(NETIF_F_ALL_CSUM | BOND_VLAN_FEATURES);
-	features |=  NETIF_F_GSO_MASK | NETIF_F_NO_CSUM;
+	read_lock(&bond->lock);
 
-	if (!bond->first_slave)
-		goto done;
+	if (!bond->first_slave) {
+		/* Disable adding VLANs to empty bond. But why? --mq */
+		features |= NETIF_F_VLAN_CHALLENGED;
+		goto out;
+	}
 
+	mask = features;
 	features &= ~NETIF_F_ONE_FOR_ALL;
+	features |= NETIF_F_ALL_FOR_ALL;
 
-	vlan_features = bond->first_slave->dev->vlan_features;
 	bond_for_each_slave(bond, slave, i) {
 		features = netdev_increment_features(features,
 						     slave->dev->features,
-						     NETIF_F_ONE_FOR_ALL);
+						     mask);
+	}
+
+out:
+	read_unlock(&bond->lock);
+	return features;
+}
+
+#define BOND_VLAN_FEATURES	(NETIF_F_ALL_TX_OFFLOADS | \
+				 NETIF_F_SOFT_FEATURES | \
+				 NETIF_F_LRO)
+
+static void bond_compute_features(struct bonding *bond)
+{
+	struct slave *slave;
+	struct net_device *bond_dev = bond->dev;
+	u32 vlan_features = BOND_VLAN_FEATURES;
+	unsigned short max_hard_header_len = ETH_HLEN;
+	int i;
+
+	read_lock(&bond->lock);
+
+	if (!bond->first_slave)
+		goto done;
+
+	bond_for_each_slave(bond, slave, i) {
 		vlan_features = netdev_increment_features(vlan_features,
-							slave->dev->vlan_features,
-							NETIF_F_ONE_FOR_ALL);
+			slave->dev->vlan_features, BOND_VLAN_FEATURES);
+
 		if (slave->dev->hard_header_len > max_hard_header_len)
 			max_hard_header_len = slave->dev->hard_header_len;
 	}
 
 done:
-	features |= (bond_dev->features & BOND_VLAN_FEATURES);
-	bond_dev->features = netdev_fix_features(bond_dev, features);
-	bond_dev->vlan_features = netdev_fix_features(bond_dev, vlan_features);
+	bond_dev->vlan_features = vlan_features;
 	bond_dev->hard_header_len = max_hard_header_len;
 
-	return 0;
+	read_unlock(&bond->lock);
+
+	netdev_change_features(bond_dev);
 }
 
 static void bond_setup_by_slave(struct net_device *bond_dev,
@@ -1452,27 +1479,17 @@
 }
 
 /* On bonding slaves other than the currently active slave, suppress
- * duplicates except for 802.3ad ETH_P_SLOW, alb non-mcast/bcast, and
- * ARP on active-backup slaves with arp_validate enabled.
+ * duplicates except for alb non-mcast/bcast.
  */
 static bool bond_should_deliver_exact_match(struct sk_buff *skb,
 					    struct slave *slave,
 					    struct bonding *bond)
 {
 	if (bond_is_slave_inactive(slave)) {
-		if (slave_do_arp_validate(bond, slave) &&
-		    skb->protocol == __cpu_to_be16(ETH_P_ARP))
-			return false;
-
 		if (bond->params.mode == BOND_MODE_ALB &&
 		    skb->pkt_type != PACKET_BROADCAST &&
 		    skb->pkt_type != PACKET_MULTICAST)
-				return false;
-
-		if (bond->params.mode == BOND_MODE_8023AD &&
-		    skb->protocol == __cpu_to_be16(ETH_P_SLOW))
 			return false;
-
 		return true;
 	}
 	return false;
@@ -1496,6 +1513,15 @@
 	if (bond->params.arp_interval)
 		slave->dev->last_rx = jiffies;
 
+	if (bond->recv_probe) {
+		struct sk_buff *nskb = skb_clone(skb, GFP_ATOMIC);
+
+		if (likely(nskb)) {
+			bond->recv_probe(nskb, bond, slave);
+			dev_kfree_skb(nskb);
+		}
+	}
+
 	if (bond_should_deliver_exact_match(skb, slave, bond)) {
 		return RX_HANDLER_EXACT;
 	}
@@ -1526,7 +1552,6 @@
 	struct netdev_hw_addr *ha;
 	struct sockaddr addr;
 	int link_reporting;
-	int old_features = bond_dev->features;
 	int res = 0;
 
 	if (!bond->params.use_carrier && slave_dev->ethtool_ops == NULL &&
@@ -1535,12 +1560,6 @@
 			   bond_dev->name, slave_dev->name);
 	}
 
-	/* bond must be initialized by bond_open() before enslaving */
-	if (!(bond_dev->flags & IFF_UP)) {
-		pr_warning("%s: master_dev is not up in bond_enslave\n",
-			   bond_dev->name);
-	}
-
 	/* already enslaved */
 	if (slave_dev->flags & IFF_SLAVE) {
 		pr_debug("Error, Device was already enslaved\n");
@@ -1559,16 +1578,9 @@
 			pr_warning("%s: Warning: enslaved VLAN challenged slave %s. Adding VLANs will be blocked as long as %s is part of bond %s\n",
 				   bond_dev->name, slave_dev->name,
 				   slave_dev->name, bond_dev->name);
-			bond_dev->features |= NETIF_F_VLAN_CHALLENGED;
 		}
 	} else {
 		pr_debug("%s: ! NETIF_F_VLAN_CHALLENGED\n", slave_dev->name);
-		if (bond->slave_cnt == 0) {
-			/* First slave, and it is not VLAN challenged,
-			 * so remove the block of adding VLANs over the bond.
-			 */
-			bond_dev->features &= ~NETIF_F_VLAN_CHALLENGED;
-		}
 	}
 
 	/*
@@ -1640,6 +1652,8 @@
 		}
 	}
 
+	call_netdevice_notifiers(NETDEV_JOIN, slave_dev);
+
 	/* If this is the first slave, then we need to set the master's hardware
 	 * address to be the same as the slave's. */
 	if (is_zero_ether_addr(bond->dev->dev_addr))
@@ -1757,10 +1771,10 @@
 	new_slave->delay = 0;
 	new_slave->link_failure_count = 0;
 
-	bond_compute_features(bond);
-
 	write_unlock_bh(&bond->lock);
 
+	bond_compute_features(bond);
+
 	read_lock(&bond->lock);
 
 	new_slave->last_arp_rx = jiffies;
@@ -1940,7 +1954,7 @@
 	kfree(new_slave);
 
 err_undo_flags:
-	bond_dev->features = old_features;
+	bond_compute_features(bond);
 
 	return res;
 }
@@ -1961,6 +1975,7 @@
 	struct bonding *bond = netdev_priv(bond_dev);
 	struct slave *slave, *oldcurrent;
 	struct sockaddr addr;
+	u32 old_features = bond_dev->features;
 
 	/* slave is not a slave or master is not master of this slave */
 	if (!(slave_dev->flags & IFF_SLAVE) ||
@@ -1971,7 +1986,7 @@
 	}
 
 	block_netpoll_tx();
-	netdev_bonding_change(bond_dev, NETDEV_BONDING_DESLAVE);
+	netdev_bonding_change(bond_dev, NETDEV_RELEASE);
 	write_lock_bh(&bond->lock);
 
 	slave = bond_get_slave_by_dev(bond, slave_dev);
@@ -2021,8 +2036,6 @@
 	/* release the slave from its bond */
 	bond_detach_slave(bond, slave);
 
-	bond_compute_features(bond);
-
 	if (bond->primary_slave == slave)
 		bond->primary_slave = NULL;
 
@@ -2066,24 +2079,23 @@
 		 */
 		memset(bond_dev->dev_addr, 0, bond_dev->addr_len);
 
-		if (!bond->vlgrp) {
-			bond_dev->features |= NETIF_F_VLAN_CHALLENGED;
-		} else {
+		if (bond->vlgrp) {
 			pr_warning("%s: Warning: clearing HW address of %s while it still has VLANs.\n",
 				   bond_dev->name, bond_dev->name);
 			pr_warning("%s: When re-adding slaves, make sure the bond's HW address matches its VLANs'.\n",
 				   bond_dev->name);
 		}
-	} else if ((bond_dev->features & NETIF_F_VLAN_CHALLENGED) &&
-		   !bond_has_challenged_slaves(bond)) {
-		pr_info("%s: last VLAN challenged slave %s left bond %s. VLAN blocking is removed\n",
-			bond_dev->name, slave_dev->name, bond_dev->name);
-		bond_dev->features &= ~NETIF_F_VLAN_CHALLENGED;
 	}
 
 	write_unlock_bh(&bond->lock);
 	unblock_netpoll_tx();
 
+	bond_compute_features(bond);
+	if (!(bond_dev->features & NETIF_F_VLAN_CHALLENGED) &&
+	    (old_features & NETIF_F_VLAN_CHALLENGED))
+		pr_info("%s: last VLAN challenged slave %s left bond %s. VLAN blocking is removed\n",
+			bond_dev->name, slave_dev->name, bond_dev->name);
+
 	/* must do this from outside any spinlocks */
 	bond_destroy_slave_symlinks(bond_dev, slave_dev);
 
@@ -2201,8 +2213,6 @@
 			bond_alb_deinit_slave(bond, slave);
 		}
 
-		bond_compute_features(bond);
-
 		bond_destroy_slave_symlinks(bond_dev, slave_dev);
 		bond_del_vlans_from_slave(bond, slave_dev);
 
@@ -2251,9 +2261,7 @@
 	 */
 	memset(bond_dev->dev_addr, 0, bond_dev->addr_len);
 
-	if (!bond->vlgrp) {
-		bond_dev->features |= NETIF_F_VLAN_CHALLENGED;
-	} else {
+	if (bond->vlgrp) {
 		pr_warning("%s: Warning: clearing HW address of %s while it still has VLANs.\n",
 			   bond_dev->name, bond_dev->name);
 		pr_warning("%s: When re-adding slaves, make sure the bond's HW address matches its VLANs'.\n",
@@ -2264,6 +2272,9 @@
 
 out:
 	write_unlock_bh(&bond->lock);
+
+	bond_compute_features(bond);
+
 	return 0;
 }
 
@@ -2493,7 +2504,7 @@
 
 			bond_update_speed_duplex(slave);
 
-			pr_info("%s: link status definitely up for interface %s, %d Mbps %s duplex.\n",
+			pr_info("%s: link status definitely up for interface %s, %u Mbps %s duplex.\n",
 				bond->dev->name, slave->dev->name,
 				slave->speed, slave->duplex ? "full" : "half");
 
@@ -2570,6 +2581,7 @@
 {
 	struct bonding *bond = container_of(work, struct bonding,
 					    mii_work.work);
+	bool should_notify_peers = false;
 
 	read_lock(&bond->lock);
 	if (bond->kill_timers)
@@ -2578,17 +2590,7 @@
 	if (bond->slave_cnt == 0)
 		goto re_arm;
 
-	if (bond->send_grat_arp) {
-		read_lock(&bond->curr_slave_lock);
-		bond_send_gratuitous_arp(bond);
-		read_unlock(&bond->curr_slave_lock);
-	}
-
-	if (bond->send_unsol_na) {
-		read_lock(&bond->curr_slave_lock);
-		bond_send_unsolicited_na(bond);
-		read_unlock(&bond->curr_slave_lock);
-	}
+	should_notify_peers = bond_should_notify_peers(bond);
 
 	if (bond_miimon_inspect(bond)) {
 		read_unlock(&bond->lock);
@@ -2608,6 +2610,12 @@
 				   msecs_to_jiffies(bond->params.miimon));
 out:
 	read_unlock(&bond->lock);
+
+	if (should_notify_peers) {
+		rtnl_lock();
+		netdev_bonding_change(bond->dev, NETDEV_NOTIFY_PEERS);
+		rtnl_unlock();
+	}
 }
 
 static __be32 bond_glean_dev_ip(struct net_device *dev)
@@ -2751,44 +2759,6 @@
 	}
 }
 
-/*
- * Kick out a gratuitous ARP for an IP on the bonding master plus one
- * for each VLAN above us.
- *
- * Caller must hold curr_slave_lock for read or better
- */
-static void bond_send_gratuitous_arp(struct bonding *bond)
-{
-	struct slave *slave = bond->curr_active_slave;
-	struct vlan_entry *vlan;
-	struct net_device *vlan_dev;
-
-	pr_debug("bond_send_grat_arp: bond %s slave %s\n",
-		 bond->dev->name, slave ? slave->dev->name : "NULL");
-
-	if (!slave || !bond->send_grat_arp ||
-	    test_bit(__LINK_STATE_LINKWATCH_PENDING, &slave->dev->state))
-		return;
-
-	bond->send_grat_arp--;
-
-	if (bond->master_ip) {
-		bond_arp_send(slave->dev, ARPOP_REPLY, bond->master_ip,
-				bond->master_ip, 0);
-	}
-
-	if (!bond->vlgrp)
-		return;
-
-	list_for_each_entry(vlan, &bond->vlan_list, vlan_list) {
-		vlan_dev = vlan_group_get_device(bond->vlgrp, vlan->vlan_id);
-		if (vlan->vlan_ip) {
-			bond_arp_send(slave->dev, ARPOP_REPLY, vlan->vlan_ip,
-				      vlan->vlan_ip, vlan->vlan_id);
-		}
-	}
-}
-
 static void bond_validate_arp(struct bonding *bond, struct slave *slave, __be32 sip, __be32 tip)
 {
 	int i;
@@ -2806,48 +2776,26 @@
 	}
 }
 
-static int bond_arp_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt, struct net_device *orig_dev)
+static void bond_arp_rcv(struct sk_buff *skb, struct bonding *bond,
+			 struct slave *slave)
 {
 	struct arphdr *arp;
-	struct slave *slave;
-	struct bonding *bond;
 	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;
+	if (skb->protocol != __cpu_to_be16(ETH_P_ARP))
+		return;
 
-	bond = netdev_priv(dev);
 	read_lock(&bond->lock);
 
-	pr_debug("bond_arp_rcv: bond %s skb->dev %s orig_dev %s\n",
-		 bond->dev->name, skb->dev ? skb->dev->name : "NULL",
-		 orig_dev ? orig_dev->name : "NULL");
-
-	slave = bond_get_slave_by_dev(bond, orig_dev);
-	if (!slave || !slave_do_arp_validate(bond, slave))
-		goto out_unlock;
-
-	skb = skb_share_check(skb, GFP_ATOMIC);
-	if (!skb)
-		goto out_unlock;
+	pr_debug("bond_arp_rcv: bond %s skb->dev %s\n",
+		 bond->dev->name, skb->dev->name);
 
-	if (!pskb_may_pull(skb, arp_hdr_len(dev)))
+	if (!pskb_may_pull(skb, arp_hdr_len(bond->dev)))
 		goto out_unlock;
 
 	arp = arp_hdr(skb);
-	if (arp->ar_hln != dev->addr_len ||
+	if (arp->ar_hln != bond->dev->addr_len ||
 	    skb->pkt_type == PACKET_OTHERHOST ||
 	    skb->pkt_type == PACKET_LOOPBACK ||
 	    arp->ar_hrd != htons(ARPHRD_ETHER) ||
@@ -2856,9 +2804,9 @@
 		goto out_unlock;
 
 	arp_ptr = (unsigned char *)(arp + 1);
-	arp_ptr += dev->addr_len;
+	arp_ptr += bond->dev->addr_len;
 	memcpy(&sip, arp_ptr, 4);
-	arp_ptr += 4 + dev->addr_len;
+	arp_ptr += 4 + bond->dev->addr_len;
 	memcpy(&tip, arp_ptr, 4);
 
 	pr_debug("bond_arp_rcv: %s %s/%d av %d sv %d sip %pI4 tip %pI4\n",
@@ -2881,9 +2829,6 @@
 
 out_unlock:
 	read_unlock(&bond->lock);
-out:
-	dev_kfree_skb(skb);
-	return NET_RX_SUCCESS;
 }
 
 /*
@@ -3243,6 +3188,7 @@
 {
 	struct bonding *bond = container_of(work, struct bonding,
 					    arp_work.work);
+	bool should_notify_peers = false;
 	int delta_in_ticks;
 
 	read_lock(&bond->lock);
@@ -3255,17 +3201,7 @@
 	if (bond->slave_cnt == 0)
 		goto re_arm;
 
-	if (bond->send_grat_arp) {
-		read_lock(&bond->curr_slave_lock);
-		bond_send_gratuitous_arp(bond);
-		read_unlock(&bond->curr_slave_lock);
-	}
-
-	if (bond->send_unsol_na) {
-		read_lock(&bond->curr_slave_lock);
-		bond_send_unsolicited_na(bond);
-		read_unlock(&bond->curr_slave_lock);
-	}
+	should_notify_peers = bond_should_notify_peers(bond);
 
 	if (bond_ab_arp_inspect(bond, delta_in_ticks)) {
 		read_unlock(&bond->lock);
@@ -3286,6 +3222,12 @@
 		queue_delayed_work(bond->wq, &bond->arp_work, delta_in_ticks);
 out:
 	read_unlock(&bond->lock);
+
+	if (should_notify_peers) {
+		rtnl_lock();
+		netdev_bonding_change(bond->dev, NETDEV_NOTIFY_PEERS);
+		rtnl_unlock();
+	}
 }
 
 /*-------------------------- netdev event handling --------------------------*/
@@ -3339,8 +3281,8 @@
 
 			slave = bond_get_slave_by_dev(bond, slave_dev);
 			if (slave) {
-				u16 old_speed = slave->speed;
-				u16 old_duplex = slave->duplex;
+				u32 old_speed = slave->speed;
+				u8  old_duplex = slave->duplex;
 
 				bond_update_speed_duplex(slave);
 
@@ -3482,48 +3424,6 @@
 	.notifier_call = bond_inetaddr_event,
 };
 
-/*-------------------------- Packet type handling ---------------------------*/
-
-/* register to receive lacpdus on a bond */
-static void bond_register_lacpdu(struct bonding *bond)
-{
-	struct packet_type *pk_type = &(BOND_AD_INFO(bond).ad_pkt_type);
-
-	/* initialize packet type */
-	pk_type->type = PKT_TYPE_LACPDU;
-	pk_type->dev = bond->dev;
-	pk_type->func = bond_3ad_lacpdu_recv;
-
-	dev_add_pack(pk_type);
-}
-
-/* unregister to receive lacpdus on a bond */
-static void bond_unregister_lacpdu(struct bonding *bond)
-{
-	dev_remove_pack(&(BOND_AD_INFO(bond).ad_pkt_type));
-}
-
-void bond_register_arp(struct bonding *bond)
-{
-	struct packet_type *pt = &bond->arp_mon_pt;
-
-	if (pt->type)
-		return;
-
-	pt->type = htons(ETH_P_ARP);
-	pt->dev = bond->dev;
-	pt->func = bond_arp_rcv;
-	dev_add_pack(pt);
-}
-
-void bond_unregister_arp(struct bonding *bond)
-{
-	struct packet_type *pt = &bond->arp_mon_pt;
-
-	dev_remove_pack(pt);
-	pt->type = 0;
-}
-
 /*---------------------------- Hashing Policies -----------------------------*/
 
 /*
@@ -3617,14 +3517,14 @@
 
 		queue_delayed_work(bond->wq, &bond->arp_work, 0);
 		if (bond->params.arp_validate)
-			bond_register_arp(bond);
+			bond->recv_probe = bond_arp_rcv;
 	}
 
 	if (bond->params.mode == BOND_MODE_8023AD) {
 		INIT_DELAYED_WORK(&bond->ad_work, bond_3ad_state_machine_handler);
 		queue_delayed_work(bond->wq, &bond->ad_work, 0);
 		/* register to receive LACPDUs */
-		bond_register_lacpdu(bond);
+		bond->recv_probe = bond_3ad_lacpdu_recv;
 		bond_3ad_initiate_agg_selection(bond, 1);
 	}
 
@@ -3635,18 +3535,9 @@
 {
 	struct bonding *bond = netdev_priv(bond_dev);
 
-	if (bond->params.mode == BOND_MODE_8023AD) {
-		/* Unregister the receive of LACPDUs */
-		bond_unregister_lacpdu(bond);
-	}
-
-	if (bond->params.arp_validate)
-		bond_unregister_arp(bond);
-
 	write_lock_bh(&bond->lock);
 
-	bond->send_grat_arp = 0;
-	bond->send_unsol_na = 0;
+	bond->send_peer_notif = 0;
 
 	/* signal timers not to re-arm */
 	bond->kill_timers = 1;
@@ -3682,6 +3573,7 @@
 		 */
 		bond_alb_deinitialize(bond);
 	}
+	bond->recv_probe = NULL;
 
 	return 0;
 }
@@ -4105,10 +3997,6 @@
 	int i, slave_no, res = 1;
 	struct iphdr *iph = ip_hdr(skb);
 
-	read_lock(&bond->lock);
-
-	if (!BOND_IS_OK(bond))
-		goto out;
 	/*
 	 * Start with the curr_active_slave that joined the bond as the
 	 * default for sending IGMP traffic.  For failover purposes one
@@ -4155,7 +4043,7 @@
 		/* no suitable interface, frame not sent */
 		dev_kfree_skb(skb);
 	}
-	read_unlock(&bond->lock);
+
 	return NETDEV_TX_OK;
 }
 
@@ -4169,24 +4057,18 @@
 	struct bonding *bond = netdev_priv(bond_dev);
 	int res = 1;
 
-	read_lock(&bond->lock);
 	read_lock(&bond->curr_slave_lock);
 
-	if (!BOND_IS_OK(bond))
-		goto out;
-
-	if (!bond->curr_active_slave)
-		goto out;
-
-	res = bond_dev_queue_xmit(bond, skb, bond->curr_active_slave->dev);
+	if (bond->curr_active_slave)
+		res = bond_dev_queue_xmit(bond, skb,
+			bond->curr_active_slave->dev);
 
-out:
 	if (res)
 		/* no suitable interface, frame not sent */
 		dev_kfree_skb(skb);
 
 	read_unlock(&bond->curr_slave_lock);
-	read_unlock(&bond->lock);
+
 	return NETDEV_TX_OK;
 }
 
@@ -4203,11 +4085,6 @@
 	int i;
 	int res = 1;
 
-	read_lock(&bond->lock);
-
-	if (!BOND_IS_OK(bond))
-		goto out;
-
 	slave_no = bond->xmit_hash_policy(skb, bond->slave_cnt);
 
 	bond_for_each_slave(bond, slave, i) {
@@ -4227,12 +4104,11 @@
 		}
 	}
 
-out:
 	if (res) {
 		/* no suitable interface, frame not sent */
 		dev_kfree_skb(skb);
 	}
-	read_unlock(&bond->lock);
+
 	return NETDEV_TX_OK;
 }
 
@@ -4247,11 +4123,6 @@
 	int i;
 	int res = 1;
 
-	read_lock(&bond->lock);
-
-	if (!BOND_IS_OK(bond))
-		goto out;
-
 	read_lock(&bond->curr_slave_lock);
 	start_at = bond->curr_active_slave;
 	read_unlock(&bond->curr_slave_lock);
@@ -4290,7 +4161,6 @@
 		dev_kfree_skb(skb);
 
 	/* frame sent to all suitable interfaces */
-	read_unlock(&bond->lock);
 	return NETDEV_TX_OK;
 }
 
@@ -4322,10 +4192,8 @@
 	struct slave *slave = NULL;
 	struct slave *check_slave;
 
-	read_lock(&bond->lock);
-
-	if (!BOND_IS_OK(bond) || !skb->queue_mapping)
-		goto out;
+	if (!skb->queue_mapping)
+		return 1;
 
 	/* Find out if any slaves have the same mapping as this skb. */
 	bond_for_each_slave(bond, check_slave, i) {
@@ -4341,11 +4209,10 @@
 		res = bond_dev_queue_xmit(bond, skb, slave->dev);
 	}
 
-out:
-	read_unlock(&bond->lock);
 	return res;
 }
 
+
 static u16 bond_select_queue(struct net_device *dev, struct sk_buff *skb)
 {
 	/*
@@ -4356,25 +4223,23 @@
 	 */
 	u16 txq = skb_rx_queue_recorded(skb) ? skb_get_rx_queue(skb) : 0;
 
+	/*
+	 * Save the original txq to restore before passing to the driver
+	 */
+	bond_queue_mapping(skb) = skb->queue_mapping;
+
 	if (unlikely(txq >= dev->real_num_tx_queues)) {
-		do
+		do {
 			txq -= dev->real_num_tx_queues;
-		while (txq >= dev->real_num_tx_queues);
+		} while (txq >= dev->real_num_tx_queues);
 	}
 	return txq;
 }
 
-static netdev_tx_t bond_start_xmit(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t __bond_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
 	struct bonding *bond = netdev_priv(dev);
 
-	/*
-	 * If we risk deadlock from transmitting this in the
-	 * netpoll path, tell netpoll to queue the frame for later tx
-	 */
-	if (is_netpoll_tx_blocked(dev))
-		return NETDEV_TX_BUSY;
-
 	if (TX_QUEUE_OVERRIDE(bond->params.mode)) {
 		if (!bond_slave_override(bond, skb))
 			return NETDEV_TX_OK;
@@ -4404,6 +4269,29 @@
 	}
 }
 
+static netdev_tx_t bond_start_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+	struct bonding *bond = netdev_priv(dev);
+	netdev_tx_t ret = NETDEV_TX_OK;
+
+	/*
+	 * If we risk deadlock from transmitting this in the
+	 * netpoll path, tell netpoll to queue the frame for later tx
+	 */
+	if (is_netpoll_tx_blocked(dev))
+		return NETDEV_TX_BUSY;
+
+	read_lock(&bond->lock);
+
+	if (bond->slave_cnt)
+		ret = __bond_start_xmit(skb, dev);
+	else
+		dev_kfree_skb(skb);
+
+	read_unlock(&bond->lock);
+
+	return ret;
+}
 
 /*
  * set bond mode specific net device operations
@@ -4448,11 +4336,6 @@
 static const struct ethtool_ops bond_ethtool_ops = {
 	.get_drvinfo		= bond_ethtool_get_drvinfo,
 	.get_link		= ethtool_op_get_link,
-	.get_tx_csum		= ethtool_op_get_tx_csum,
-	.get_sg			= ethtool_op_get_sg,
-	.get_tso		= ethtool_op_get_tso,
-	.get_ufo		= ethtool_op_get_ufo,
-	.get_flags		= ethtool_op_get_flags,
 };
 
 static const struct net_device_ops bond_netdev_ops = {
@@ -4478,6 +4361,7 @@
 #endif
 	.ndo_add_slave		= bond_enslave,
 	.ndo_del_slave		= bond_release,
+	.ndo_fix_features	= bond_fix_features,
 };
 
 static void bond_destructor(struct net_device *bond_dev)
@@ -4533,14 +4417,14 @@
 	 * when there are slaves that are not hw accel
 	 * capable
 	 */
-	bond_dev->features |= (NETIF_F_HW_VLAN_TX |
-			       NETIF_F_HW_VLAN_RX |
-			       NETIF_F_HW_VLAN_FILTER);
 
-	/* By default, we enable GRO on bonding devices.
-	 * Actual support requires lowlevel drivers are GRO ready.
-	 */
-	bond_dev->features |= NETIF_F_GRO;
+	bond_dev->hw_features = BOND_VLAN_FEATURES |
+				NETIF_F_HW_VLAN_TX |
+				NETIF_F_HW_VLAN_RX |
+				NETIF_F_HW_VLAN_FILTER;
+
+	bond_dev->hw_features &= ~(NETIF_F_ALL_CSUM & ~NETIF_F_NO_CSUM);
+	bond_dev->features |= bond_dev->hw_features;
 }
 
 static void bond_work_cancel_all(struct bonding *bond)
@@ -4724,16 +4608,10 @@
 		use_carrier = 1;
 	}
 
-	if (num_grat_arp < 0 || num_grat_arp > 255) {
-		pr_warning("Warning: num_grat_arp (%d) not in range 0-255 so it was reset to 1\n",
-			   num_grat_arp);
-		num_grat_arp = 1;
-	}
-
-	if (num_unsol_na < 0 || num_unsol_na > 255) {
-		pr_warning("Warning: num_unsol_na (%d) not in range 0-255 so it was reset to 1\n",
-			   num_unsol_na);
-		num_unsol_na = 1;
+	if (num_peer_notif < 0 || num_peer_notif > 255) {
+		pr_warning("Warning: num_grat_arp/num_unsol_na (%d) not in range 0-255 so it was reset to 1\n",
+			   num_peer_notif);
+		num_peer_notif = 1;
 	}
 
 	/* reset values for 802.3ad */
@@ -4925,8 +4803,7 @@
 	params->mode = bond_mode;
 	params->xmit_policy = xmit_hashtype;
 	params->miimon = miimon;
-	params->num_grat_arp = num_grat_arp;
-	params->num_unsol_na = num_unsol_na;
+	params->num_peer_notif = num_peer_notif;
 	params->arp_interval = arp_interval;
 	params->arp_validate = arp_validate_value;
 	params->updelay = updelay;
@@ -4975,9 +4852,19 @@
 {
 	struct bonding *bond = netdev_priv(bond_dev);
 	struct bond_net *bn = net_generic(dev_net(bond_dev), bond_net_id);
+	struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond));
 
 	pr_debug("Begin bond_init for %s\n", bond_dev->name);
 
+	/*
+	 * Initialize locks that may be required during
+	 * en/deslave operations.  All of the bond_open work
+	 * (of which this is part) should really be moved to
+	 * a phase prior to dev_open
+	 */
+	spin_lock_init(&(bond_info->tx_hashtbl_lock));
+	spin_lock_init(&(bond_info->rx_hashtbl_lock));
+
 	bond->wq = create_singlethread_workqueue(bond_dev->name);
 	if (!bond->wq)
 		return -ENOMEM;
@@ -5025,8 +4912,9 @@
 
 	rtnl_lock();
 
-	bond_dev = alloc_netdev_mq(sizeof(struct bonding), name ? name : "",
-				bond_setup, tx_queues);
+	bond_dev = alloc_netdev_mq(sizeof(struct bonding),
+				   name ? name : "bond%d",
+				   bond_setup, tx_queues);
 	if (!bond_dev) {
 		pr_err("%s: eek! can't alloc netdev!\n", name);
 		rtnl_unlock();
@@ -5036,26 +4924,10 @@
 	dev_net_set(bond_dev, net);
 	bond_dev->rtnl_link_ops = &bond_link_ops;
 
-	if (!name) {
-		res = dev_alloc_name(bond_dev, "bond%d");
-		if (res < 0)
-			goto out;
-	} else {
-		/*
-		 * If we're given a name to register
-		 * we need to ensure that its not already
-		 * registered
-		 */
-		res = -EEXIST;
-		if (__dev_get_by_name(net, name) != NULL)
-			goto out;
-	}
-
 	res = register_netdevice(bond_dev);
 
 	netif_carrier_off(bond_dev);
 
-out:
 	rtnl_unlock();
 	if (res < 0)
 		bond_destructor(bond_dev);
@@ -5121,7 +4993,6 @@
 
 	register_netdevice_notifier(&bond_netdev_notifier);
 	register_inetaddr_notifier(&bond_inetaddr_notifier);
-	bond_register_ipv6_notifier();
 out:
 	return res;
 err:
@@ -5136,7 +5007,6 @@
 {
 	unregister_netdevice_notifier(&bond_netdev_notifier);
 	unregister_inetaddr_notifier(&bond_inetaddr_notifier);
-	bond_unregister_ipv6_notifier();
 
 	bond_destroy_sysfs();
 	bond_destroy_debugfs();
diff -druN linux-2.6.39-libre/drivers/net/bonding/bond_procfs.c linux-3.0-rc7-libre/drivers/net/bonding/bond_procfs.c
--- linux-2.6.39-libre/drivers/net/bonding/bond_procfs.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/bonding/bond_procfs.c	2011-07-11 19:51:52.000000000 -0400
@@ -4,8 +4,6 @@
 #include "bonding.h"
 
 
-extern const char *bond_mode_name(int mode);
-
 static void *bond_info_seq_start(struct seq_file *seq, loff_t *pos)
 	__acquires(RCU)
 	__acquires(&bond->lock)
diff -druN linux-2.6.39-libre/drivers/net/bonding/bond_sysfs.c linux-3.0-rc7-libre/drivers/net/bonding/bond_sysfs.c
--- linux-2.6.39-libre/drivers/net/bonding/bond_sysfs.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/bonding/bond_sysfs.c	2011-07-11 19:51:52.000000000 -0400
@@ -227,12 +227,6 @@
 	struct net_device *dev;
 	struct bonding *bond = to_bond(d);
 
-	/* Quick sanity check -- is the bond interface up? */
-	if (!(bond->dev->flags & IFF_UP)) {
-		pr_warning("%s: doing slave updates when interface is down.\n",
-			   bond->dev->name);
-	}
-
 	if (!rtnl_trylock())
 		return restart_syscall();
 
@@ -422,11 +416,6 @@
 		bond->dev->name, arp_validate_tbl[new_value].modename,
 		new_value);
 
-	if (!bond->params.arp_validate && new_value)
-		bond_register_arp(bond);
-	else if (bond->params.arp_validate && !new_value)
-		bond_unregister_arp(bond);
-
 	bond->params.arp_validate = new_value;
 
 	return count;
@@ -874,82 +863,28 @@
 		   bonding_show_ad_select, bonding_store_ad_select);
 
 /*
- * Show and set the number of grat ARP to send after a failover event.
+ * Show and set the number of peer notifications to send after a failover event.
  */
-static ssize_t bonding_show_n_grat_arp(struct device *d,
-				   struct device_attribute *attr,
-				   char *buf)
+static ssize_t bonding_show_num_peer_notif(struct device *d,
+					   struct device_attribute *attr,
+					   char *buf)
 {
 	struct bonding *bond = to_bond(d);
-
-	return sprintf(buf, "%d\n", bond->params.num_grat_arp);
+	return sprintf(buf, "%d\n", bond->params.num_peer_notif);
 }
 
-static ssize_t bonding_store_n_grat_arp(struct device *d,
-				    struct device_attribute *attr,
-				    const char *buf, size_t count)
+static ssize_t bonding_store_num_peer_notif(struct device *d,
+					    struct device_attribute *attr,
+					    const char *buf, size_t count)
 {
-	int new_value, ret = count;
 	struct bonding *bond = to_bond(d);
-
-	if (sscanf(buf, "%d", &new_value) != 1) {
-		pr_err("%s: no num_grat_arp value specified.\n",
-		       bond->dev->name);
-		ret = -EINVAL;
-		goto out;
-	}
-	if (new_value < 0 || new_value > 255) {
-		pr_err("%s: Invalid num_grat_arp value %d not in range 0-255; rejected.\n",
-		       bond->dev->name, new_value);
-		ret = -EINVAL;
-		goto out;
-	} else {
-		bond->params.num_grat_arp = new_value;
-	}
-out:
-	return ret;
+	int err = kstrtou8(buf, 10, &bond->params.num_peer_notif);
+	return err ? err : count;
 }
 static DEVICE_ATTR(num_grat_arp, S_IRUGO | S_IWUSR,
-		   bonding_show_n_grat_arp, bonding_store_n_grat_arp);
-
-/*
- * Show and set the number of unsolicited NA's to send after a failover event.
- */
-static ssize_t bonding_show_n_unsol_na(struct device *d,
-				       struct device_attribute *attr,
-				       char *buf)
-{
-	struct bonding *bond = to_bond(d);
-
-	return sprintf(buf, "%d\n", bond->params.num_unsol_na);
-}
-
-static ssize_t bonding_store_n_unsol_na(struct device *d,
-					struct device_attribute *attr,
-					const char *buf, size_t count)
-{
-	int new_value, ret = count;
-	struct bonding *bond = to_bond(d);
-
-	if (sscanf(buf, "%d", &new_value) != 1) {
-		pr_err("%s: no num_unsol_na value specified.\n",
-		       bond->dev->name);
-		ret = -EINVAL;
-		goto out;
-	}
-
-	if (new_value < 0 || new_value > 255) {
-		pr_err("%s: Invalid num_unsol_na value %d not in range 0-255; rejected.\n",
-		       bond->dev->name, new_value);
-		ret = -EINVAL;
-		goto out;
-	} else
-		bond->params.num_unsol_na = new_value;
-out:
-	return ret;
-}
+		   bonding_show_num_peer_notif, bonding_store_num_peer_notif);
 static DEVICE_ATTR(num_unsol_na, S_IRUGO | S_IWUSR,
-		   bonding_show_n_unsol_na, bonding_store_n_unsol_na);
+		   bonding_show_num_peer_notif, bonding_store_num_peer_notif);
 
 /*
  * Show and set the MII monitor interval.  There are two tricky bits
@@ -1001,7 +936,6 @@
 				bond->dev->name);
 			bond->params.arp_interval = 0;
 			if (bond->params.arp_validate) {
-				bond_unregister_arp(bond);
 				bond->params.arp_validate =
 					BOND_ARP_VALIDATE_NONE;
 			}
@@ -1599,8 +1533,8 @@
  * Show and set the number of IGMP membership reports to send on link failure
  */
 static ssize_t bonding_show_resend_igmp(struct device *d,
-					 struct device_attribute *attr,
-					 char *buf)
+					struct device_attribute *attr,
+					char *buf)
 {
 	struct bonding *bond = to_bond(d);
 
@@ -1608,8 +1542,8 @@
 }
 
 static ssize_t bonding_store_resend_igmp(struct device *d,
-					  struct device_attribute *attr,
-					  const char *buf, size_t count)
+					 struct device_attribute *attr,
+					 const char *buf, size_t count)
 {
 	int new_value, ret = count;
 	struct bonding *bond = to_bond(d);
@@ -1621,7 +1555,7 @@
 		goto out;
 	}
 
-	if (new_value < 0) {
+	if (new_value < 0 || new_value > 255) {
 		pr_err("%s: Invalid resend_igmp value %d not in range 0-255; rejected.\n",
 		       bond->dev->name, new_value);
 		ret = -EINVAL;
diff -druN linux-2.6.39-libre/drivers/net/bonding/Makefile linux-3.0-rc7-libre/drivers/net/bonding/Makefile
--- linux-2.6.39-libre/drivers/net/bonding/Makefile	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/bonding/Makefile	2011-07-11 19:51:52.000000000 -0400
@@ -9,6 +9,3 @@
 proc-$(CONFIG_PROC_FS) += bond_procfs.o
 bonding-objs += $(proc-y)
 
-ipv6-$(subst m,y,$(CONFIG_IPV6)) += bond_ipv6.o
-bonding-objs += $(ipv6-y)
-
diff -druN linux-2.6.39-libre/drivers/net/can/flexcan.c linux-3.0-rc7-libre/drivers/net/can/flexcan.c
--- linux-2.6.39-libre/drivers/net/can/flexcan.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/can/flexcan.c	2011-07-11 19:51:52.000000000 -0400
@@ -923,7 +923,7 @@
 	mem_size = resource_size(mem);
 	if (!request_mem_region(mem->start, mem_size, pdev->name)) {
 		err = -EBUSY;
-		goto failed_req;
+		goto failed_get;
 	}
 
 	base = ioremap(mem->start, mem_size);
@@ -977,9 +977,8 @@
 	iounmap(base);
  failed_map:
 	release_mem_region(mem->start, mem_size);
- failed_req:
-	clk_put(clk);
  failed_get:
+	clk_put(clk);
  failed_clock:
 	return err;
 }
diff -druN linux-2.6.39-libre/drivers/net/can/janz-ican3.c linux-3.0-rc7-libre/drivers/net/can/janz-ican3.c
--- linux-2.6.39-libre/drivers/net/can/janz-ican3.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/can/janz-ican3.c	2011-07-11 19:51:52.000000000 -0400
@@ -15,7 +15,6 @@
 #include <linux/interrupt.h>
 #include <linux/delay.h>
 #include <linux/platform_device.h>
-#include <linux/mfd/core.h>
 
 #include <linux/netdevice.h>
 #include <linux/can.h>
@@ -1644,7 +1643,7 @@
 	struct device *dev;
 	int ret;
 
-	pdata = mfd_get_data(pdev);
+	pdata = pdev->dev.platform_data;
 	if (!pdata)
 		return -ENXIO;
 
diff -druN linux-2.6.39-libre/drivers/net/can/Kconfig linux-3.0-rc7-libre/drivers/net/can/Kconfig
--- linux-2.6.39-libre/drivers/net/can/Kconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/can/Kconfig	2011-07-11 19:51:52.000000000 -0400
@@ -36,7 +36,7 @@
 config CAN_DEV
 	tristate "Platform CAN drivers with Netlink support"
 	depends on CAN
-	default Y
+	default y
 	---help---
 	  Enables the common framework for platform CAN drivers with Netlink
 	  support. This is the standard library for CAN drivers.
@@ -45,7 +45,7 @@
 config CAN_CALC_BITTIMING
 	bool "CAN bit-timing calculation"
 	depends on CAN_DEV
-	default Y
+	default y
 	---help---
 	  If enabled, CAN bit-timing parameters will be calculated for the
 	  bit-rate specified via Netlink argument "bitrate" when the device
diff -druN linux-2.6.39-libre/drivers/net/can/pch_can.c linux-3.0-rc7-libre/drivers/net/can/pch_can.c
--- linux-2.6.39-libre/drivers/net/can/pch_can.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/can/pch_can.c	2011-07-11 19:51:52.000000000 -0400
@@ -653,7 +653,7 @@
 	u16 data_reg;
 
 	do {
-		/* Reading the messsage object from the Message RAM */
+		/* Reading the message object from the Message RAM */
 		iowrite32(PCH_CMASK_RX_TX_GET, &priv->regs->ifregs[0].cmask);
 		pch_can_rw_msg_obj(&priv->regs->ifregs[0].creq, obj_num);
 
diff -druN linux-2.6.39-libre/drivers/net/can/softing/softing_cs.c linux-3.0-rc7-libre/drivers/net/can/softing/softing_cs.c
--- linux-2.6.39-libre/drivers/net/can/softing/softing_cs.c	2011-05-19 02:16:58.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/can/softing/softing_cs.c	2011-07-21 06:58:58.000000000 -0400
@@ -308,7 +308,7 @@
 	return ret ?: -ENODEV;
 }
 
-static /*const*/ struct pcmcia_device_id softingcs_ids[] = {
+static const struct pcmcia_device_id softingcs_ids[] = {
 	/* softing */
 	PCMCIA_DEVICE_MANF_CARD(0x0168, 0x0001),
 	PCMCIA_DEVICE_MANF_CARD(0x0168, 0x0002),
diff -druN linux-2.6.39-libre/drivers/net/can/softing/softing_main.c linux-3.0-rc7-libre/drivers/net/can/softing/softing_main.c
--- linux-2.6.39-libre/drivers/net/can/softing/softing_main.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/can/softing/softing_main.c	2011-07-11 19:51:52.000000000 -0400
@@ -797,7 +797,7 @@
 	ret = -EINVAL;
 	pres = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	if (!pres)
-		goto platform_resource_failed;;
+		goto platform_resource_failed;
 	card->dpram_phys = pres->start;
 	card->dpram_size = pres->end - pres->start + 1;
 	card->dpram = ioremap_nocache(card->dpram_phys, card->dpram_size);
diff -druN linux-2.6.39-libre/drivers/net/cassini.c linux-3.0-rc7-libre/drivers/net/cassini.c
--- linux-2.6.39-libre/drivers/net/cassini.c	2011-05-19 02:11:39.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/cassini.c	2011-07-21 06:54:10.000000000 -0400
@@ -709,10 +709,11 @@
 	if (ep->autoneg == AUTONEG_ENABLE)
 		cp->link_cntl = BMCR_ANENABLE;
 	else {
+		u32 speed = ethtool_cmd_speed(ep);
 		cp->link_cntl = 0;
-		if (ep->speed == SPEED_100)
+		if (speed == SPEED_100)
 			cp->link_cntl |= BMCR_SPEED100;
-		else if (ep->speed == SPEED_1000)
+		else if (speed == SPEED_1000)
 			cp->link_cntl |= CAS_BMCR_SPEED1000;
 		if (ep->duplex == DUPLEX_FULL)
 			cp->link_cntl |= BMCR_FULLDPLX;
@@ -4605,18 +4606,17 @@
 	if (bmcr & BMCR_ANENABLE) {
 		cmd->advertising |= ADVERTISED_Autoneg;
 		cmd->autoneg = AUTONEG_ENABLE;
-		cmd->speed = ((speed == 10) ?
-			      SPEED_10 :
-			      ((speed == 1000) ?
-			       SPEED_1000 : SPEED_100));
+		ethtool_cmd_speed_set(cmd, ((speed == 10) ?
+					    SPEED_10 :
+					    ((speed == 1000) ?
+					     SPEED_1000 : SPEED_100)));
 		cmd->duplex = full_duplex ? DUPLEX_FULL : DUPLEX_HALF;
 	} else {
 		cmd->autoneg = AUTONEG_DISABLE;
-		cmd->speed =
-			(bmcr & CAS_BMCR_SPEED1000) ?
-			SPEED_1000 :
-			((bmcr & BMCR_SPEED100) ? SPEED_100:
-			 SPEED_10);
+		ethtool_cmd_speed_set(cmd, ((bmcr & CAS_BMCR_SPEED1000) ?
+					    SPEED_1000 :
+					    ((bmcr & BMCR_SPEED100) ?
+					     SPEED_100 : SPEED_10)));
 		cmd->duplex =
 			(bmcr & BMCR_FULLDPLX) ?
 			DUPLEX_FULL : DUPLEX_HALF;
@@ -4633,14 +4633,14 @@
 		 * settings that we configured.
 		 */
 		if (cp->link_cntl & BMCR_ANENABLE) {
-			cmd->speed = 0;
+			ethtool_cmd_speed_set(cmd, 0);
 			cmd->duplex = 0xff;
 		} else {
-			cmd->speed = SPEED_10;
+			ethtool_cmd_speed_set(cmd, SPEED_10);
 			if (cp->link_cntl & BMCR_SPEED100) {
-				cmd->speed = SPEED_100;
+				ethtool_cmd_speed_set(cmd, SPEED_100);
 			} else if (cp->link_cntl & CAS_BMCR_SPEED1000) {
-				cmd->speed = SPEED_1000;
+				ethtool_cmd_speed_set(cmd, SPEED_1000);
 			}
 			cmd->duplex = (cp->link_cntl & BMCR_FULLDPLX)?
 				DUPLEX_FULL : DUPLEX_HALF;
@@ -4653,6 +4653,7 @@
 {
 	struct cas *cp = netdev_priv(dev);
 	unsigned long flags;
+	u32 speed = ethtool_cmd_speed(cmd);
 
 	/* Verify the settings we care about. */
 	if (cmd->autoneg != AUTONEG_ENABLE &&
@@ -4660,9 +4661,9 @@
 		return -EINVAL;
 
 	if (cmd->autoneg == AUTONEG_DISABLE &&
-	    ((cmd->speed != SPEED_1000 &&
-	      cmd->speed != SPEED_100 &&
-	      cmd->speed != SPEED_10) ||
+	    ((speed != SPEED_1000 &&
+	      speed != SPEED_100 &&
+	      speed != SPEED_10) ||
 	     (cmd->duplex != DUPLEX_HALF &&
 	      cmd->duplex != DUPLEX_FULL)))
 		return -EINVAL;
diff -druN linux-2.6.39-libre/drivers/net/chelsio/common.h linux-3.0-rc7-libre/drivers/net/chelsio/common.h
--- linux-2.6.39-libre/drivers/net/chelsio/common.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/chelsio/common.h	2011-07-11 19:51:52.000000000 -0400
@@ -264,11 +264,6 @@
 
 enum {                                           /* adapter flags */
 	FULL_INIT_DONE        = 1 << 0,
-	TSO_CAPABLE           = 1 << 2,
-	TCP_CSUM_CAPABLE      = 1 << 3,
-	UDP_CSUM_CAPABLE      = 1 << 4,
-	VLAN_ACCEL_CAPABLE    = 1 << 5,
-	RX_CSUM_ENABLED       = 1 << 6,
 };
 
 struct mdio_ops;
diff -druN linux-2.6.39-libre/drivers/net/chelsio/cxgb2.c linux-3.0-rc7-libre/drivers/net/chelsio/cxgb2.c
--- linux-2.6.39-libre/drivers/net/chelsio/cxgb2.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/chelsio/cxgb2.c	2011-07-11 19:51:52.000000000 -0400
@@ -192,10 +192,8 @@
 
 static void enable_hw_csum(struct adapter *adapter)
 {
-	if (adapter->flags & TSO_CAPABLE)
+	if (adapter->port[0].dev->hw_features & NETIF_F_TSO)
 		t1_tp_set_ip_checksum_offload(adapter->tp, 1);	/* for TSO only */
-	if (adapter->flags & UDP_CSUM_CAPABLE)
-		t1_tp_set_udp_checksum_offload(adapter->tp, 1);
 	t1_tp_set_tcp_checksum_offload(adapter->tp, 1);
 }
 
@@ -579,10 +577,10 @@
 	cmd->advertising = p->link_config.advertising;
 
 	if (netif_carrier_ok(dev)) {
-		cmd->speed = p->link_config.speed;
+		ethtool_cmd_speed_set(cmd, p->link_config.speed);
 		cmd->duplex = p->link_config.duplex;
 	} else {
-		cmd->speed = -1;
+		ethtool_cmd_speed_set(cmd, -1);
 		cmd->duplex = -1;
 	}
 
@@ -640,11 +638,12 @@
 		return -EOPNOTSUPP;             /* can't change speed/duplex */
 
 	if (cmd->autoneg == AUTONEG_DISABLE) {
-		int cap = speed_duplex_to_caps(cmd->speed, cmd->duplex);
+		u32 speed = ethtool_cmd_speed(cmd);
+		int cap = speed_duplex_to_caps(speed, cmd->duplex);
 
-		if (!(lc->supported & cap) || cmd->speed == SPEED_1000)
+		if (!(lc->supported & cap) || (speed == SPEED_1000))
 			return -EINVAL;
-		lc->requested_speed = cmd->speed;
+		lc->requested_speed = speed;
 		lc->requested_duplex = cmd->duplex;
 		lc->advertising = 0;
 	} else {
@@ -705,33 +704,6 @@
 	return 0;
 }
 
-static u32 get_rx_csum(struct net_device *dev)
-{
-	struct adapter *adapter = dev->ml_priv;
-
-	return (adapter->flags & RX_CSUM_ENABLED) != 0;
-}
-
-static int set_rx_csum(struct net_device *dev, u32 data)
-{
-	struct adapter *adapter = dev->ml_priv;
-
-	if (data)
-		adapter->flags |= RX_CSUM_ENABLED;
-	else
-		adapter->flags &= ~RX_CSUM_ENABLED;
-	return 0;
-}
-
-static int set_tso(struct net_device *dev, u32 value)
-{
-	struct adapter *adapter = dev->ml_priv;
-
-	if (!(adapter->flags & TSO_CAPABLE))
-		return value ? -EOPNOTSUPP : 0;
-	return ethtool_op_set_tso(dev, value);
-}
-
 static void get_sge_param(struct net_device *dev, struct ethtool_ringparam *e)
 {
 	struct adapter *adapter = dev->ml_priv;
@@ -831,17 +803,12 @@
 	.get_eeprom        = get_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_csum,
-	.set_sg            = ethtool_op_set_sg,
 	.get_link          = ethtool_op_get_link,
 	.get_strings       = get_strings,
 	.get_sset_count	   = get_sset_count,
 	.get_ethtool_stats = get_stats,
 	.get_regs_len      = get_regs_len,
 	.get_regs          = get_regs,
-	.set_tso           = set_tso,
 };
 
 static int t1_ioctl(struct net_device *dev, struct ifreq *req, int cmd)
@@ -1105,28 +1072,28 @@
 		netdev->mem_start = mmio_start;
 		netdev->mem_end = mmio_start + mmio_len - 1;
 		netdev->ml_priv = adapter;
-		netdev->features |= NETIF_F_SG | NETIF_F_IP_CSUM;
-		netdev->features |= NETIF_F_LLTX;
+		netdev->hw_features |= NETIF_F_SG | NETIF_F_IP_CSUM |
+			NETIF_F_RXCSUM;
+		netdev->features |= NETIF_F_SG | NETIF_F_IP_CSUM |
+			NETIF_F_RXCSUM | NETIF_F_LLTX;
 
-		adapter->flags |= RX_CSUM_ENABLED | TCP_CSUM_CAPABLE;
 		if (pci_using_dac)
 			netdev->features |= NETIF_F_HIGHDMA;
 		if (vlan_tso_capable(adapter)) {
 #if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
-			adapter->flags |= VLAN_ACCEL_CAPABLE;
 			netdev->features |=
 				NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
 #endif
 
 			/* T204: disable TSO */
 			if (!(is_T2(adapter)) || bi->port_number != 4) {
-				adapter->flags |= TSO_CAPABLE;
+				netdev->hw_features |= NETIF_F_TSO;
 				netdev->features |= NETIF_F_TSO;
 			}
 		}
 
 		netdev->netdev_ops = &cxgb_netdev_ops;
-		netdev->hard_header_len += (adapter->flags & TSO_CAPABLE) ?
+		netdev->hard_header_len += (netdev->hw_features & NETIF_F_TSO) ?
 			sizeof(struct cpl_tx_pkt_lso) : sizeof(struct cpl_tx_pkt);
 
 		netif_napi_add(netdev, &adapter->napi, t1_poll, 64);
diff -druN linux-2.6.39-libre/drivers/net/chelsio/sge.c linux-3.0-rc7-libre/drivers/net/chelsio/sge.c
--- linux-2.6.39-libre/drivers/net/chelsio/sge.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/chelsio/sge.c	2011-07-11 19:51:52.000000000 -0400
@@ -54,6 +54,7 @@
 #include <linux/in.h>
 #include <linux/if_arp.h>
 #include <linux/slab.h>
+#include <linux/prefetch.h>
 
 #include "cpl5_cmd.h"
 #include "sge.h"
@@ -929,7 +930,7 @@
 	u32 en = SGE_INT_ENABLE;
 	u32 val = readl(sge->adapter->regs + A_PL_ENABLE);
 
-	if (sge->adapter->flags & TSO_CAPABLE)
+	if (sge->adapter->port[0].dev->hw_features & NETIF_F_TSO)
 		en &= ~F_PACKET_TOO_BIG;
 	writel(en, sge->adapter->regs + A_SG_INT_ENABLE);
 	writel(val | SGE_PL_INTR_MASK, sge->adapter->regs + A_PL_ENABLE);
@@ -952,7 +953,7 @@
 	struct adapter *adapter = sge->adapter;
 	u32 cause = readl(adapter->regs + A_SG_INT_CAUSE);
 
-	if (adapter->flags & TSO_CAPABLE)
+	if (adapter->port[0].dev->hw_features & NETIF_F_TSO)
 		cause &= ~F_PACKET_TOO_BIG;
 	if (cause & F_RESPQ_EXHAUSTED)
 		sge->stats.respQ_empty++;
@@ -1369,6 +1370,7 @@
 	const struct cpl_rx_pkt *p;
 	struct adapter *adapter = sge->adapter;
 	struct sge_port_stats *st;
+	struct net_device *dev;
 
 	skb = get_packet(adapter->pdev, fl, len - sge->rx_pkt_pad);
 	if (unlikely(!skb)) {
@@ -1384,9 +1386,10 @@
 	__skb_pull(skb, sizeof(*p));
 
 	st = this_cpu_ptr(sge->port_stats[p->iff]);
+	dev = adapter->port[p->iff].dev;
 
-	skb->protocol = eth_type_trans(skb, adapter->port[p->iff].dev);
-	if ((adapter->flags & RX_CSUM_ENABLED) && p->csum == 0xffff &&
+	skb->protocol = eth_type_trans(skb, dev);
+	if ((dev->features & NETIF_F_RXCSUM) && p->csum == 0xffff &&
 	    skb->protocol == htons(ETH_P_IP) &&
 	    (skb->data[9] == IPPROTO_TCP || skb->data[9] == IPPROTO_UDP)) {
 		++st->rx_cso_good;
@@ -1838,8 +1841,7 @@
 			return NETDEV_TX_OK;
 		}
 
-		if (!(adapter->flags & UDP_CSUM_CAPABLE) &&
-		    skb->ip_summed == CHECKSUM_PARTIAL &&
+		if (skb->ip_summed == CHECKSUM_PARTIAL &&
 		    ip_hdr(skb)->protocol == IPPROTO_UDP) {
 			if (unlikely(skb_checksum_help(skb))) {
 				pr_debug("%s: unable to do udp checksum\n", dev->name);
diff -druN linux-2.6.39-libre/drivers/net/chelsio/tp.c linux-3.0-rc7-libre/drivers/net/chelsio/tp.c
--- linux-2.6.39-libre/drivers/net/chelsio/tp.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/chelsio/tp.c	2011-07-11 19:51:52.000000000 -0400
@@ -152,11 +152,6 @@
 	set_csum_offload(tp, F_IP_CSUM, enable);
 }
 
-void t1_tp_set_udp_checksum_offload(struct petp *tp, int enable)
-{
-	set_csum_offload(tp, F_UDP_CSUM, enable);
-}
-
 void t1_tp_set_tcp_checksum_offload(struct petp *tp, int enable)
 {
 	set_csum_offload(tp, F_TCP_CSUM, enable);
diff -druN linux-2.6.39-libre/drivers/net/chelsio/tp.h linux-3.0-rc7-libre/drivers/net/chelsio/tp.h
--- linux-2.6.39-libre/drivers/net/chelsio/tp.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/chelsio/tp.h	2011-07-11 19:51:52.000000000 -0400
@@ -65,7 +65,6 @@
 int t1_tp_intr_handler(struct petp *tp);
 
 void t1_tp_get_mib_statistics(adapter_t *adap, struct tp_mib_statistics *tps);
-void t1_tp_set_udp_checksum_offload(struct petp *tp, int enable);
 void t1_tp_set_tcp_checksum_offload(struct petp *tp, int enable);
 void t1_tp_set_ip_checksum_offload(struct petp *tp, int enable);
 int t1_tp_set_coalescing_size(struct petp *tp, unsigned int size);
diff -druN linux-2.6.39-libre/drivers/net/cnic.c linux-3.0-rc7-libre/drivers/net/cnic.c
--- linux-2.6.39-libre/drivers/net/cnic.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/cnic.c	2011-07-11 19:51:52.000000000 -0400
@@ -27,6 +27,7 @@
 #include <linux/delay.h>
 #include <linux/ethtool.h>
 #include <linux/if_vlan.h>
+#include <linux/prefetch.h>
 #if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
 #define BCM_VLAN 1
 #endif
@@ -2966,31 +2967,36 @@
 	return 0;
 }
 
-static void cnic_ulp_stop(struct cnic_dev *dev)
+static void cnic_ulp_stop_one(struct cnic_local *cp, int if_type)
 {
-	struct cnic_local *cp = dev->cnic_priv;
-	int if_type;
-
-	cnic_send_nlmsg(cp, ISCSI_KEVENT_IF_DOWN, NULL);
+	struct cnic_ulp_ops *ulp_ops;
 
-	for (if_type = 0; if_type < MAX_CNIC_ULP_TYPE; if_type++) {
-		struct cnic_ulp_ops *ulp_ops;
+	if (if_type == CNIC_ULP_ISCSI)
+		cnic_send_nlmsg(cp, ISCSI_KEVENT_IF_DOWN, NULL);
 
-		mutex_lock(&cnic_lock);
-		ulp_ops = rcu_dereference_protected(cp->ulp_ops[if_type],
-						    lockdep_is_held(&cnic_lock));
-		if (!ulp_ops) {
-			mutex_unlock(&cnic_lock);
-			continue;
-		}
-		set_bit(ULP_F_CALL_PENDING, &cp->ulp_flags[if_type]);
+	mutex_lock(&cnic_lock);
+	ulp_ops = rcu_dereference_protected(cp->ulp_ops[if_type],
+					    lockdep_is_held(&cnic_lock));
+	if (!ulp_ops) {
 		mutex_unlock(&cnic_lock);
+		return;
+	}
+	set_bit(ULP_F_CALL_PENDING, &cp->ulp_flags[if_type]);
+	mutex_unlock(&cnic_lock);
 
-		if (test_and_clear_bit(ULP_F_START, &cp->ulp_flags[if_type]))
-			ulp_ops->cnic_stop(cp->ulp_handle[if_type]);
+	if (test_and_clear_bit(ULP_F_START, &cp->ulp_flags[if_type]))
+		ulp_ops->cnic_stop(cp->ulp_handle[if_type]);
 
-		clear_bit(ULP_F_CALL_PENDING, &cp->ulp_flags[if_type]);
-	}
+	clear_bit(ULP_F_CALL_PENDING, &cp->ulp_flags[if_type]);
+}
+
+static void cnic_ulp_stop(struct cnic_dev *dev)
+{
+	struct cnic_local *cp = dev->cnic_priv;
+	int if_type;
+
+	for (if_type = 0; if_type < MAX_CNIC_ULP_TYPE; if_type++)
+		cnic_ulp_stop_one(cp, if_type);
 }
 
 static void cnic_ulp_start(struct cnic_dev *dev)
@@ -3039,6 +3045,12 @@
 
 		cnic_put(dev);
 		break;
+	case CNIC_CTL_STOP_ISCSI_CMD: {
+		struct cnic_local *cp = dev->cnic_priv;
+		set_bit(CNIC_LCL_FL_STOP_ISCSI, &cp->cnic_local_flags);
+		queue_delayed_work(cnic_wq, &cp->delete_task, 0);
+		break;
+	}
 	case CNIC_CTL_COMPLETION_CMD: {
 		u32 cid = BNX2X_SW_CID(info->data.comp.cid);
 		u32 l5_cid;
@@ -3562,8 +3574,12 @@
 
 static int cnic_cm_connect(struct cnic_sock *csk, struct cnic_sockaddr *saddr)
 {
+	struct cnic_local *cp = csk->dev->cnic_priv;
 	int err = 0;
 
+	if (cp->ethdev->drv_state & CNIC_DRV_STATE_NO_ISCSI)
+		return -EOPNOTSUPP;
+
 	if (!cnic_in_use(csk))
 		return -EINVAL;
 
@@ -3965,6 +3981,15 @@
 	cp = container_of(work, struct cnic_local, delete_task.work);
 	dev = cp->dev;
 
+	if (test_and_clear_bit(CNIC_LCL_FL_STOP_ISCSI, &cp->cnic_local_flags)) {
+		struct drv_ctl_info info;
+
+		cnic_ulp_stop_one(cp, CNIC_ULP_ISCSI);
+
+		info.cmd = DRV_CTL_ISCSI_STOPPED_CMD;
+		cp->ethdev->drv_ctl(dev->netdev, &info);
+	}
+
 	for (i = 0; i < cp->max_cid_space; i++) {
 		struct cnic_context *ctx = &cp->ctx_tbl[i];
 
diff -druN linux-2.6.39-libre/drivers/net/cnic.h linux-3.0-rc7-libre/drivers/net/cnic.h
--- linux-2.6.39-libre/drivers/net/cnic.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/cnic.h	2011-07-11 19:51:52.000000000 -0400
@@ -226,6 +226,7 @@
 #define	CNIC_LCL_FL_KWQ_INIT		0x0
 #define	CNIC_LCL_FL_L2_WAIT		0x1
 #define	CNIC_LCL_FL_RINGS_INITED	0x2
+#define	CNIC_LCL_FL_STOP_ISCSI		0x4
 
 	struct cnic_dev *dev;
 
diff -druN linux-2.6.39-libre/drivers/net/cnic_if.h linux-3.0-rc7-libre/drivers/net/cnic_if.h
--- linux-2.6.39-libre/drivers/net/cnic_if.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/cnic_if.h	2011-07-11 19:51:52.000000000 -0400
@@ -12,8 +12,8 @@
 #ifndef CNIC_IF_H
 #define CNIC_IF_H
 
-#define CNIC_MODULE_VERSION	"2.2.13"
-#define CNIC_MODULE_RELDATE	"Jan 31, 2011"
+#define CNIC_MODULE_VERSION	"2.2.14"
+#define CNIC_MODULE_RELDATE	"Mar 30, 2011"
 
 #define CNIC_ULP_RDMA		0
 #define CNIC_ULP_ISCSI		1
@@ -85,6 +85,7 @@
 #define CNIC_CTL_STOP_CMD		1
 #define CNIC_CTL_START_CMD		2
 #define CNIC_CTL_COMPLETION_CMD		3
+#define CNIC_CTL_STOP_ISCSI_CMD		4
 
 #define DRV_CTL_IO_WR_CMD		0x101
 #define DRV_CTL_IO_RD_CMD		0x102
@@ -94,6 +95,7 @@
 #define DRV_CTL_START_L2_CMD		0x106
 #define DRV_CTL_STOP_L2_CMD		0x107
 #define DRV_CTL_RET_L2_SPQ_CREDIT_CMD	0x10c
+#define DRV_CTL_ISCSI_STOPPED_CMD	0x10d
 
 struct cnic_ctl_completion {
 	u32	cid;
diff -druN linux-2.6.39-libre/drivers/net/cris/eth_v10.c linux-3.0-rc7-libre/drivers/net/cris/eth_v10.c
--- linux-2.6.39-libre/drivers/net/cris/eth_v10.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/cris/eth_v10.c	2011-07-11 19:51:52.000000000 -0400
@@ -491,8 +491,8 @@
 
 	/* allocate the irq corresponding to the receiving DMA */
 
-	if (request_irq(NETWORK_DMA_RX_IRQ_NBR, e100rxtx_interrupt,
-			IRQF_SAMPLE_RANDOM, cardname, (void *)dev)) {
+	if (request_irq(NETWORK_DMA_RX_IRQ_NBR, e100rxtx_interrupt, 0, cardname,
+			(void *)dev)) {
 		goto grace_exit0;
 	}
 
diff -druN linux-2.6.39-libre/drivers/net/cxgb3/adapter.h linux-3.0-rc7-libre/drivers/net/cxgb3/adapter.h
--- linux-2.6.39-libre/drivers/net/cxgb3/adapter.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/cxgb3/adapter.h	2011-07-11 19:51:52.000000000 -0400
@@ -50,11 +50,6 @@
 struct sge_qset;
 struct port_info;
 
-enum {			/* rx_offload flags */
-	T3_RX_CSUM	= 1 << 0,
-	T3_LRO		= 1 << 1,
-};
-
 enum mac_idx_types {
 	LAN_MAC_IDX	= 0,
 	SAN_MAC_IDX,
@@ -74,7 +69,6 @@
 	struct vlan_group *vlan_grp;
 	struct sge_qset *qs;
 	u8 port_id;
-	u8 rx_offload;
 	u8 nqsets;
 	u8 first_qset;
 	struct cphy phy;
@@ -212,7 +206,6 @@
 	struct sge_fl fl[SGE_RXQ_PER_SET];
 	struct sge_txq txq[SGE_TXQ_PER_SET];
 	int nomem;
-	int lro_enabled;
 	void *lro_va;
 	struct net_device *netdev;
 	struct netdev_queue *tx_q;	/* associated netdev TX queue */
diff -druN linux-2.6.39-libre/drivers/net/cxgb3/common.h linux-3.0-rc7-libre/drivers/net/cxgb3/common.h
--- linux-2.6.39-libre/drivers/net/cxgb3/common.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/cxgb3/common.h	2011-07-11 19:51:52.000000000 -0400
@@ -317,7 +317,6 @@
 
 struct qset_params {		/* SGE queue set parameters */
 	unsigned int polling;	/* polling/interrupt service for rspq */
-	unsigned int lro;	/* large receive offload */
 	unsigned int coalesce_usecs;	/* irq coalescing timer */
 	unsigned int rspq_size;	/* # of entries in response queue */
 	unsigned int fl_size;	/* # of entries in regular free list */
diff -druN linux-2.6.39-libre/drivers/net/cxgb3/cxgb3_main.c linux-3.0-rc7-libre/drivers/net/cxgb3/cxgb3_main.c
--- linux-2.6.39-libre/drivers/net/cxgb3/cxgb3_main.c	2011-05-19 02:11:43.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/cxgb3/cxgb3_main.c	2011-07-21 06:54:13.000000000 -0400
@@ -644,26 +644,6 @@
 }
 
 /**
- *	set_qset_lro - Turn a queue set's LRO capability on and off
- *	@dev: the device the qset is attached to
- *	@qset_idx: the queue set index
- *	@val: the LRO switch
- *
- *	Sets LRO on or off for a particular queue set.
- *	the device's features flag is updated to reflect the LRO
- *	capability when all queues belonging to the device are
- *	in the same state.
- */
-static void set_qset_lro(struct net_device *dev, int qset_idx, int val)
-{
-	struct port_info *pi = netdev_priv(dev);
-	struct adapter *adapter = pi->adapter;
-
-	adapter->params.sge.qset[qset_idx].lro = !!val;
-	adapter->sge.qs[qset_idx].lro_enabled = !!val;
-}
-
-/**
  *	setup_sge_qsets - configure SGE Tx/Rx/response queues
  *	@adap: the adapter
  *
@@ -685,7 +665,6 @@
 
 		pi->qs = &adap->sge.qs[pi->first_qset];
 		for (j = 0; j < pi->nqsets; ++j, ++qset_idx) {
-			set_qset_lro(dev, qset_idx, pi->rx_offload & T3_LRO);
 			err = t3_sge_alloc_qset(adap, qset_idx, 1,
 				(adap->flags & USING_MSIX) ? qset_idx + 1 :
 							     irq_idx,
@@ -1742,23 +1721,26 @@
 	return 0;
 }
 
-static int cxgb3_phys_id(struct net_device *dev, u32 data)
+static int set_phys_id(struct net_device *dev,
+		       enum ethtool_phys_id_state state)
 {
 	struct port_info *pi = netdev_priv(dev);
 	struct adapter *adapter = pi->adapter;
-	int i;
 
-	if (data == 0)
-		data = 2;
+	switch (state) {
+	case ETHTOOL_ID_ACTIVE:
+		return 1;	/* cycle on/off once per second */
 
-	for (i = 0; i < data * 2; i++) {
+	case ETHTOOL_ID_OFF:
+		t3_set_reg_field(adapter, A_T3DBG_GPIO_EN, F_GPIO0_OUT_VAL, 0);
+		break;
+
+	case ETHTOOL_ID_ON:
+	case ETHTOOL_ID_INACTIVE:
 		t3_set_reg_field(adapter, A_T3DBG_GPIO_EN, F_GPIO0_OUT_VAL,
-				 (i & 1) ? F_GPIO0_OUT_VAL : 0);
-		if (msleep_interruptible(500))
-			break;
-	}
-	t3_set_reg_field(adapter, A_T3DBG_GPIO_EN, F_GPIO0_OUT_VAL,
 			 F_GPIO0_OUT_VAL);
+	}
+
 	return 0;
 }
 
@@ -1770,10 +1752,10 @@
 	cmd->advertising = p->link_config.advertising;
 
 	if (netif_carrier_ok(dev)) {
-		cmd->speed = p->link_config.speed;
+		ethtool_cmd_speed_set(cmd, p->link_config.speed);
 		cmd->duplex = p->link_config.duplex;
 	} else {
-		cmd->speed = -1;
+		ethtool_cmd_speed_set(cmd, -1);
 		cmd->duplex = -1;
 	}
 
@@ -1832,7 +1814,8 @@
 		 * being requested.
 		 */
 		if (cmd->autoneg == AUTONEG_DISABLE) {
-			int cap = speed_duplex_to_caps(cmd->speed, cmd->duplex);
+			u32 speed = ethtool_cmd_speed(cmd);
+			int cap = speed_duplex_to_caps(speed, cmd->duplex);
 			if (lc->supported & cap)
 				return 0;
 		}
@@ -1840,11 +1823,12 @@
 	}
 
 	if (cmd->autoneg == AUTONEG_DISABLE) {
-		int cap = speed_duplex_to_caps(cmd->speed, cmd->duplex);
+		u32 speed = ethtool_cmd_speed(cmd);
+		int cap = speed_duplex_to_caps(speed, cmd->duplex);
 
-		if (!(lc->supported & cap) || cmd->speed == SPEED_1000)
+		if (!(lc->supported & cap) || (speed == SPEED_1000))
 			return -EINVAL;
-		lc->requested_speed = cmd->speed;
+		lc->requested_speed = speed;
 		lc->requested_duplex = cmd->duplex;
 		lc->advertising = 0;
 	} else {
@@ -1900,29 +1884,6 @@
 	return 0;
 }
 
-static u32 get_rx_csum(struct net_device *dev)
-{
-	struct port_info *p = netdev_priv(dev);
-
-	return p->rx_offload & T3_RX_CSUM;
-}
-
-static int set_rx_csum(struct net_device *dev, u32 data)
-{
-	struct port_info *p = netdev_priv(dev);
-
-	if (data) {
-		p->rx_offload |= T3_RX_CSUM;
-	} else {
-		int i;
-
-		p->rx_offload &= ~(T3_RX_CSUM | T3_LRO);
-		for (i = p->first_qset; i < p->first_qset + p->nqsets; i++)
-			set_qset_lro(dev, i, 0);
-	}
-	return 0;
-}
-
 static void get_sge_param(struct net_device *dev, struct ethtool_ringparam *e)
 {
 	struct port_info *pi = netdev_priv(dev);
@@ -2094,20 +2055,15 @@
 	.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_csum,
-	.set_sg = ethtool_op_set_sg,
 	.get_link = ethtool_op_get_link,
 	.get_strings = get_strings,
-	.phys_id = cxgb3_phys_id,
+	.set_phys_id = set_phys_id,
 	.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_tso = ethtool_op_set_tso,
 };
 
 static int in_range(int val, int lo, int hi)
@@ -2155,15 +2111,6 @@
 			      MAX_RSPQ_ENTRIES))
 			return -EINVAL;
 
-		if ((adapter->flags & FULL_INIT_DONE) && t.lro > 0)
-			for_each_port(adapter, i) {
-				pi = adap2pinfo(adapter, i);
-				if (t.qset_idx >= pi->first_qset &&
-				    t.qset_idx < pi->first_qset + pi->nqsets &&
-				    !(pi->rx_offload & T3_RX_CSUM))
-					return -EINVAL;
-			}
-
 		if ((adapter->flags & FULL_INIT_DONE) &&
 			(t.rspq_size >= 0 || t.fl_size[0] >= 0 ||
 			t.fl_size[1] >= 0 || t.txq_size[0] >= 0 ||
@@ -2224,8 +2171,14 @@
 				}
 			}
 		}
-		if (t.lro >= 0)
-			set_qset_lro(dev, t.qset_idx, t.lro);
+
+		if (t.lro >= 0) {
+			if (t.lro)
+				dev->wanted_features |= NETIF_F_GRO;
+			else
+				dev->wanted_features &= ~NETIF_F_GRO;
+			netdev_update_features(dev);
+		}
 
 		break;
 	}
@@ -2259,7 +2212,7 @@
 		t.fl_size[0] = q->fl_size;
 		t.fl_size[1] = q->jumbo_size;
 		t.polling = q->polling;
-		t.lro = q->lro;
+		t.lro = !!(dev->features & NETIF_F_GRO);
 		t.intr_lat = q->coalesce_usecs;
 		t.cong_thres = q->cong_thres;
 		t.qnum = q1;
@@ -3297,18 +3250,18 @@
 		adapter->port[i] = netdev;
 		pi = netdev_priv(netdev);
 		pi->adapter = adapter;
-		pi->rx_offload = T3_RX_CSUM | T3_LRO;
 		pi->port_id = i;
 		netif_carrier_off(netdev);
 		netdev->irq = pdev->irq;
 		netdev->mem_start = mmio_start;
 		netdev->mem_end = mmio_start + mmio_len - 1;
-		netdev->features |= NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO;
-		netdev->features |= NETIF_F_GRO;
+		netdev->hw_features = NETIF_F_SG | NETIF_F_IP_CSUM |
+			NETIF_F_TSO | NETIF_F_RXCSUM;
+		netdev->features |= netdev->hw_features |
+			NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
 		if (pci_using_dac)
 			netdev->features |= NETIF_F_HIGHDMA;
 
-		netdev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
 		netdev->netdev_ops = &cxgb_netdev_ops;
 		SET_ETHTOOL_OPS(netdev, &cxgb_ethtool_ops);
 	}
diff -druN linux-2.6.39-libre/drivers/net/cxgb3/sge.c linux-3.0-rc7-libre/drivers/net/cxgb3/sge.c
--- linux-2.6.39-libre/drivers/net/cxgb3/sge.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/cxgb3/sge.c	2011-07-11 19:51:52.000000000 -0400
@@ -37,6 +37,7 @@
 #include <linux/tcp.h>
 #include <linux/dma-mapping.h>
 #include <linux/slab.h>
+#include <linux/prefetch.h>
 #include <net/arp.h>
 #include "common.h"
 #include "regs.h"
@@ -2019,13 +2020,13 @@
 	skb_pull(skb, sizeof(*p) + pad);
 	skb->protocol = eth_type_trans(skb, adap->port[p->iff]);
 	pi = netdev_priv(skb->dev);
-	if ((pi->rx_offload & T3_RX_CSUM) && p->csum_valid &&
+	if ((skb->dev->features & NETIF_F_RXCSUM) && p->csum_valid &&
 	    p->csum == htons(0xffff) && !p->fragment) {
 		qs->port_stats[SGE_PSTAT_RX_CSUM_GOOD]++;
 		skb->ip_summed = CHECKSUM_UNNECESSARY;
 	} else
 		skb_checksum_none_assert(skb);
-	skb_record_rx_queue(skb, qs - &adap->sge.qs[0]);
+	skb_record_rx_queue(skb, qs - &adap->sge.qs[pi->first_qset]);
 
 	if (unlikely(p->vlan_valid)) {
 		struct vlan_group *grp = pi->vlan_grp;
@@ -2120,7 +2121,7 @@
 		offset = 2 + sizeof(struct cpl_rx_pkt);
 		cpl = qs->lro_va = sd->pg_chunk.va + 2;
 
-		if ((pi->rx_offload & T3_RX_CSUM) &&
+		if ((qs->netdev->features & NETIF_F_RXCSUM) &&
 		     cpl->csum_valid && cpl->csum == htons(0xffff)) {
 			skb->ip_summed = CHECKSUM_UNNECESSARY;
 			qs->port_stats[SGE_PSTAT_RX_CSUM_GOOD]++;
@@ -2144,7 +2145,7 @@
 	if (!complete)
 		return;
 
-	skb_record_rx_queue(skb, qs - &adap->sge.qs[0]);
+	skb_record_rx_queue(skb, qs - &adap->sge.qs[pi->first_qset]);
 
 	if (unlikely(cpl->vlan_valid)) {
 		struct vlan_group *grp = pi->vlan_grp;
@@ -2285,7 +2286,8 @@
 	q->next_holdoff = q->holdoff_tmr;
 
 	while (likely(budget_left && is_new_response(r, q))) {
-		int packet_complete, eth, ethpad = 2, lro = qs->lro_enabled;
+		int packet_complete, eth, ethpad = 2;
+		int lro = !!(qs->netdev->features & NETIF_F_GRO);
 		struct sk_buff *skb = NULL;
 		u32 len, flags;
 		__be32 rss_hi, rss_lo;
diff -druN linux-2.6.39-libre/drivers/net/cxgb4/cxgb4.h linux-3.0-rc7-libre/drivers/net/cxgb4/cxgb4.h
--- linux-2.6.39-libre/drivers/net/cxgb4/cxgb4.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/cxgb4/cxgb4.h	2011-07-11 19:51:52.000000000 -0400
@@ -290,7 +290,6 @@
 	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 */
 	u8     rss_mode;
@@ -298,11 +297,6 @@
 	u16   *rss;
 };
 
-/* port_info.rx_offload flags */
-enum {
-	RX_CSO = 1 << 0,
-};
-
 struct dentry;
 struct work_struct;
 
diff -druN linux-2.6.39-libre/drivers/net/cxgb4/cxgb4_main.c linux-3.0-rc7-libre/drivers/net/cxgb4/cxgb4_main.c
--- linux-2.6.39-libre/drivers/net/cxgb4/cxgb4_main.c	2011-05-19 02:11:47.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/cxgb4/cxgb4_main.c	2011-07-21 06:54:17.000000000 -0400
@@ -1336,15 +1336,20 @@
 	return 0;
 }
 
-static int identify_port(struct net_device *dev, u32 data)
+static int identify_port(struct net_device *dev,
+			 enum ethtool_phys_id_state state)
 {
+	unsigned int val;
 	struct adapter *adap = netdev2adap(dev);
 
-	if (data == 0)
-		data = 2;     /* default to 2 seconds */
+	if (state == ETHTOOL_ID_ACTIVE)
+		val = 0xffff;
+	else if (state == ETHTOOL_ID_INACTIVE)
+		val = 0;
+	else
+		return -EINVAL;
 
-	return t4_identify_port(adap, adap->fn, netdev2pinfo(dev)->viid,
-				data * 5);
+	return t4_identify_port(adap, adap->fn, netdev2pinfo(dev)->viid, val);
 }
 
 static unsigned int from_fw_linkcaps(unsigned int type, unsigned int caps)
@@ -1431,7 +1436,8 @@
 	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;
+	ethtool_cmd_speed_set(cmd,
+			      netif_carrier_ok(dev) ? p->link_cfg.speed : 0);
 	cmd->duplex = DUPLEX_FULL;
 	cmd->autoneg = p->link_cfg.autoneg;
 	cmd->maxtxpkt = 0;
@@ -1455,6 +1461,7 @@
 	unsigned int cap;
 	struct port_info *p = netdev_priv(dev);
 	struct link_config *lc = &p->link_cfg;
+	u32 speed = ethtool_cmd_speed(cmd);
 
 	if (cmd->duplex != DUPLEX_FULL)     /* only full-duplex supported */
 		return -EINVAL;
@@ -1465,16 +1472,16 @@
 		 * being requested.
 		 */
 		if (cmd->autoneg == AUTONEG_DISABLE &&
-		    (lc->supported & speed_to_caps(cmd->speed)))
-				return 0;
+		    (lc->supported & speed_to_caps(speed)))
+			return 0;
 		return -EINVAL;
 	}
 
 	if (cmd->autoneg == AUTONEG_DISABLE) {
-		cap = speed_to_caps(cmd->speed);
+		cap = speed_to_caps(speed);
 
-		if (!(lc->supported & cap) || cmd->speed == SPEED_1000 ||
-		    cmd->speed == SPEED_10000)
+		if (!(lc->supported & cap) || (speed == SPEED_1000) ||
+		    (speed == SPEED_10000))
 			return -EINVAL;
 		lc->requested_speed = cap;
 		lc->advertising = 0;
@@ -1526,24 +1533,6 @@
 	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);
@@ -1865,36 +1854,20 @@
 	return err;
 }
 
-#define TSO_FLAGS (NETIF_F_TSO | NETIF_F_TSO6 | NETIF_F_TSO_ECN)
-
-static int set_tso(struct net_device *dev, u32 value)
-{
-	if (value)
-		dev->features |= TSO_FLAGS;
-	else
-		dev->features &= ~TSO_FLAGS;
-	return 0;
-}
-
-static int set_flags(struct net_device *dev, u32 flags)
+static int cxgb_set_features(struct net_device *dev, u32 features)
 {
+	const struct port_info *pi = netdev_priv(dev);
+	u32 changed = dev->features ^ features;
 	int err;
-	unsigned long old_feat = dev->features;
-
-	err = ethtool_op_set_flags(dev, flags, ETH_FLAG_RXHASH |
-				   ETH_FLAG_RXVLAN | ETH_FLAG_TXVLAN);
-	if (err)
-		return err;
 
-	if ((old_feat ^ dev->features) & NETIF_F_HW_VLAN_RX) {
-		const struct port_info *pi = netdev_priv(dev);
+	if (!(changed & NETIF_F_HW_VLAN_RX))
+		return 0;
 
-		err = t4_set_rxmode(pi->adapter, pi->adapter->fn, pi->viid, -1,
-				    -1, -1, -1, !!(flags & ETH_FLAG_RXVLAN),
-				    true);
-		if (err)
-			dev->features = old_feat;
-	}
+	err = t4_set_rxmode(pi->adapter, pi->adapter->fn, pi->viid, -1,
+			    -1, -1, -1,
+			    !!(features & NETIF_F_HW_VLAN_RX), true);
+	if (unlikely(err))
+		dev->features = features ^ NETIF_F_HW_VLAN_RX;
 	return err;
 }
 
@@ -2005,13 +1978,9 @@
 	.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,
+	.set_phys_id       = identify_port,
 	.nway_reset        = restart_autoneg,
 	.get_sset_count    = get_sset_count,
 	.get_ethtool_stats = get_stats,
@@ -2019,8 +1988,6 @@
 	.get_regs          = get_regs,
 	.get_wol           = get_wol,
 	.set_wol           = set_wol,
-	.set_tso           = set_tso,
-	.set_flags         = set_flags,
 	.get_rxnfc         = get_rxnfc,
 	.get_rxfh_indir    = get_rss_table,
 	.set_rxfh_indir    = set_rss_table,
@@ -2877,6 +2844,7 @@
 	.ndo_get_stats64      = cxgb_get_stats,
 	.ndo_set_rx_mode      = cxgb_set_rxmode,
 	.ndo_set_mac_address  = cxgb_set_mac_addr,
+	.ndo_set_features     = cxgb_set_features,
 	.ndo_validate_addr    = eth_validate_addr,
 	.ndo_do_ioctl         = cxgb_ioctl,
 	.ndo_change_mtu       = cxgb_change_mtu,
@@ -3559,6 +3527,7 @@
 		t4_fw_bye(adapter, adapter->fn);
 }
 
+#define TSO_FLAGS (NETIF_F_TSO | NETIF_F_TSO6 | NETIF_F_TSO_ECN)
 #define VLAN_FEAT (NETIF_F_SG | NETIF_F_IP_CSUM | TSO_FLAGS | \
 		   NETIF_F_IPV6_CSUM | NETIF_F_HIGHDMA)
 
@@ -3660,14 +3629,14 @@
 		pi = netdev_priv(netdev);
 		pi->adapter = adapter;
 		pi->xact_addr_filt = -1;
-		pi->rx_offload = RX_CSO;
 		pi->port_id = i;
 		netdev->irq = pdev->irq;
 
-		netdev->features |= NETIF_F_SG | TSO_FLAGS;
-		netdev->features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;
-		netdev->features |= NETIF_F_GRO | NETIF_F_RXHASH | highdma;
-		netdev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
+		netdev->hw_features = NETIF_F_SG | TSO_FLAGS |
+			NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
+			NETIF_F_RXCSUM | NETIF_F_RXHASH |
+			NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
+		netdev->features |= netdev->hw_features | highdma;
 		netdev->vlan_features = netdev->features & VLAN_FEAT;
 
 		netdev->netdev_ops = &cxgb4_netdev_ops;
diff -druN linux-2.6.39-libre/drivers/net/cxgb4/sge.c linux-3.0-rc7-libre/drivers/net/cxgb4/sge.c
--- linux-2.6.39-libre/drivers/net/cxgb4/sge.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/cxgb4/sge.c	2011-07-11 19:51:52.000000000 -0400
@@ -39,6 +39,7 @@
 #include <linux/ip.h>
 #include <linux/dma-mapping.h>
 #include <linux/jiffies.h>
+#include <linux/prefetch.h>
 #include <net/ipv6.h>
 #include <net/tcp.h>
 #include "cxgb4.h"
@@ -1556,7 +1557,6 @@
 {
 	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);
 
@@ -1584,10 +1584,9 @@
 	if (skb->dev->features & NETIF_F_RXHASH)
 		skb->rxhash = (__force u32)pkt->rsshdr.hash_val;
 
-	pi = netdev_priv(skb->dev);
 	rxq->stats.pkts++;
 
-	if (csum_ok && (pi->rx_offload & RX_CSO) &&
+	if (csum_ok && (q->netdev->features & NETIF_F_RXCSUM) &&
 	    (pkt->l2info & htonl(RXF_UDP | RXF_TCP))) {
 		if (!pkt->ip_frag) {
 			skb->ip_summed = CHECKSUM_UNNECESSARY;
diff -druN linux-2.6.39-libre/drivers/net/cxgb4vf/adapter.h linux-3.0-rc7-libre/drivers/net/cxgb4vf/adapter.h
--- linux-2.6.39-libre/drivers/net/cxgb4vf/adapter.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/cxgb4vf/adapter.h	2011-07-11 19:51:52.000000000 -0400
@@ -97,17 +97,11 @@
 	u16 rss_size;			/* size of VI's RSS table slice */
 	u8 pidx;			/* index into adapter port[] */
 	u8 port_id;			/* physical port ID */
-	u8 rx_offload;			/* CSO, etc. */
 	u8 nqsets;			/* # of "Queue Sets" */
 	u8 first_qset;			/* index of first "Queue Set" */
 	struct link_config link_cfg;	/* physical port configuration */
 };
 
-/* port_info.rx_offload flags */
-enum {
-	RX_CSO = 1 << 0,
-};
-
 /*
  * Scatter Gather Engine resources for the "adapter".  Our ingress and egress
  * queues are organized into "Queue Sets" with one ingress and one egress
diff -druN linux-2.6.39-libre/drivers/net/cxgb4vf/cxgb4vf_main.c linux-3.0-rc7-libre/drivers/net/cxgb4vf/cxgb4vf_main.c
--- linux-2.6.39-libre/drivers/net/cxgb4vf/cxgb4vf_main.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/cxgb4vf/cxgb4vf_main.c	2011-07-11 19:51:52.000000000 -0400
@@ -1167,7 +1167,8 @@
 
 	cmd->supported = pi->link_cfg.supported;
 	cmd->advertising = pi->link_cfg.advertising;
-	cmd->speed = netif_carrier_ok(dev) ? pi->link_cfg.speed : -1;
+	ethtool_cmd_speed_set(cmd,
+			      netif_carrier_ok(dev) ? pi->link_cfg.speed : -1);
 	cmd->duplex = DUPLEX_FULL;
 
 	cmd->port = (cmd->supported & SUPPORTED_TP) ? PORT_TP : PORT_FIBRE;
@@ -1326,37 +1327,22 @@
 }
 
 /*
- * Return whether RX Checksum Offloading is currently enabled for the device.
- */
-static u32 cxgb4vf_get_rx_csum(struct net_device *dev)
-{
-	struct port_info *pi = netdev_priv(dev);
-
-	return (pi->rx_offload & RX_CSO) != 0;
-}
-
-/*
- * Turn RX Checksum Offloading on or off for the device.
+ * Identify the port by blinking the port's LED.
  */
-static int cxgb4vf_set_rx_csum(struct net_device *dev, u32 csum)
+static int cxgb4vf_phys_id(struct net_device *dev,
+			   enum ethtool_phys_id_state state)
 {
+	unsigned int val;
 	struct port_info *pi = netdev_priv(dev);
 
-	if (csum)
-		pi->rx_offload |= RX_CSO;
+	if (state == ETHTOOL_ID_ACTIVE)
+		val = 0xffff;
+	else if (state == ETHTOOL_ID_INACTIVE)
+		val = 0;
 	else
-		pi->rx_offload &= ~RX_CSO;
-	return 0;
-}
-
-/*
- * Identify the port by blinking the port's LED.
- */
-static int cxgb4vf_phys_id(struct net_device *dev, u32 id)
-{
-	struct port_info *pi = netdev_priv(dev);
+		return -EINVAL;
 
-	return t4vf_identify_port(pi->adapter, pi->viid, 5);
+	return t4vf_identify_port(pi->adapter, pi->viid, val);
 }
 
 /*
@@ -1560,18 +1546,6 @@
  */
 #define TSO_FLAGS (NETIF_F_TSO | NETIF_F_TSO6 | NETIF_F_TSO_ECN)
 
-/*
- * Set TCP Segmentation Offloading feature capabilities.
- */
-static int cxgb4vf_set_tso(struct net_device *dev, u32 tso)
-{
-	if (tso)
-		dev->features |= TSO_FLAGS;
-	else
-		dev->features &= ~TSO_FLAGS;
-	return 0;
-}
-
 static struct ethtool_ops cxgb4vf_ethtool_ops = {
 	.get_settings		= cxgb4vf_get_settings,
 	.get_drvinfo		= cxgb4vf_get_drvinfo,
@@ -1582,19 +1556,14 @@
 	.get_coalesce		= cxgb4vf_get_coalesce,
 	.set_coalesce		= cxgb4vf_set_coalesce,
 	.get_pauseparam		= cxgb4vf_get_pauseparam,
-	.get_rx_csum		= cxgb4vf_get_rx_csum,
-	.set_rx_csum		= cxgb4vf_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		= cxgb4vf_get_strings,
-	.phys_id		= cxgb4vf_phys_id,
+	.set_phys_id		= cxgb4vf_phys_id,
 	.get_sset_count		= cxgb4vf_get_sset_count,
 	.get_ethtool_stats	= cxgb4vf_get_ethtool_stats,
 	.get_regs_len		= cxgb4vf_get_regs_len,
 	.get_regs		= cxgb4vf_get_regs,
 	.get_wol		= cxgb4vf_get_wol,
-	.set_tso		= cxgb4vf_set_tso,
 };
 
 /*
@@ -2629,19 +2598,19 @@
 		 * it.
 		 */
 		pi->xact_addr_filt = -1;
-		pi->rx_offload = RX_CSO;
 		netif_carrier_off(netdev);
 		netdev->irq = pdev->irq;
 
-		netdev->features = (NETIF_F_SG | TSO_FLAGS |
-				    NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
-				    NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX |
-				    NETIF_F_GRO);
+		netdev->hw_features = NETIF_F_SG | TSO_FLAGS |
+			NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
+			NETIF_F_HW_VLAN_TX | NETIF_F_RXCSUM;
+		netdev->vlan_features = NETIF_F_SG | TSO_FLAGS |
+			NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
+			NETIF_F_HIGHDMA;
+		netdev->features = netdev->hw_features |
+			NETIF_F_HW_VLAN_RX;
 		if (pci_using_dac)
 			netdev->features |= NETIF_F_HIGHDMA;
-		netdev->vlan_features =
-			(netdev->features &
-			 ~(NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX));
 
 #ifdef HAVE_NET_DEVICE_OPS
 		netdev->netdev_ops = &cxgb4vf_netdev_ops;
diff -druN linux-2.6.39-libre/drivers/net/cxgb4vf/sge.c linux-3.0-rc7-libre/drivers/net/cxgb4vf/sge.c
--- linux-2.6.39-libre/drivers/net/cxgb4vf/sge.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/cxgb4vf/sge.c	2011-07-11 19:51:52.000000000 -0400
@@ -41,6 +41,7 @@
 #include <net/ipv6.h>
 #include <net/tcp.h>
 #include <linux/dma-mapping.h>
+#include <linux/prefetch.h>
 
 #include "t4vf_common.h"
 #include "t4vf_defs.h"
@@ -1555,8 +1556,8 @@
 	pi = netdev_priv(skb->dev);
 	rxq->stats.pkts++;
 
-	if (csum_ok && (pi->rx_offload & RX_CSO) && !pkt->err_vec &&
-	    (be32_to_cpu(pkt->l2info) & (RXF_UDP|RXF_TCP))) {
+	if (csum_ok && (rspq->netdev->features & NETIF_F_RXCSUM) &&
+	    !pkt->err_vec && (be32_to_cpu(pkt->l2info) & (RXF_UDP|RXF_TCP))) {
 		if (!pkt->ip_frag)
 			skb->ip_summed = CHECKSUM_UNNECESSARY;
 		else {
diff -druN linux-2.6.39-libre/drivers/net/davinci_emac.c linux-3.0-rc7-libre/drivers/net/davinci_emac.c
--- linux-2.6.39-libre/drivers/net/davinci_emac.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/davinci_emac.c	2011-07-11 19:51:52.000000000 -0400
@@ -1772,7 +1772,7 @@
 	/* obtain emac clock from kernel */
 	emac_clk = clk_get(&pdev->dev, NULL);
 	if (IS_ERR(emac_clk)) {
-		printk(KERN_ERR "DaVinci EMAC: Failed to get EMAC clock\n");
+		dev_err(&pdev->dev, "failed to get EMAC clock\n");
 		return -EBUSY;
 	}
 	emac_bus_frequency = clk_get_rate(emac_clk);
@@ -1780,9 +1780,9 @@
 
 	ndev = alloc_etherdev(sizeof(struct emac_priv));
 	if (!ndev) {
-		printk(KERN_ERR "DaVinci EMAC: Error allocating net_device\n");
-		clk_put(emac_clk);
-		return -ENOMEM;
+		dev_err(&pdev->dev, "error allocating net_device\n");
+		rc = -ENOMEM;
+		goto free_clk;
 	}
 
 	platform_set_drvdata(pdev, ndev);
@@ -1795,8 +1795,9 @@
 
 	pdata = pdev->dev.platform_data;
 	if (!pdata) {
-		printk(KERN_ERR "DaVinci EMAC: No platform data\n");
-		return -ENODEV;
+		dev_err(&pdev->dev, "no platform data\n");
+		rc = -ENODEV;
+		goto probe_quit;
 	}
 
 	/* MAC addr and PHY mask , RMII enable info from platform_data */
@@ -1814,7 +1815,7 @@
 	/* Get EMAC platform data */
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	if (!res) {
-		dev_err(emac_dev, "DaVinci EMAC: Error getting res\n");
+		dev_err(&pdev->dev,"error getting res\n");
 		rc = -ENOENT;
 		goto probe_quit;
 	}
@@ -1822,14 +1823,14 @@
 	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(&pdev->dev, "failed request_mem_region() for regs\n");
 		rc = -ENXIO;
 		goto probe_quit;
 	}
 
 	priv->remap_addr = ioremap(res->start, size);
 	if (!priv->remap_addr) {
-		dev_err(emac_dev, "Unable to map IO\n");
+		dev_err(&pdev->dev, "unable to map IO\n");
 		rc = -ENOMEM;
 		release_mem_region(res->start, size);
 		goto probe_quit;
@@ -1863,7 +1864,7 @@
 
 	priv->dma = cpdma_ctlr_create(&dma_params);
 	if (!priv->dma) {
-		dev_err(emac_dev, "DaVinci EMAC: Error initializing DMA\n");
+		dev_err(&pdev->dev, "error initializing DMA\n");
 		rc = -ENOMEM;
 		goto no_dma;
 	}
@@ -1879,7 +1880,7 @@
 
 	res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
 	if (!res) {
-		dev_err(emac_dev, "DaVinci EMAC: Error getting irq res\n");
+		dev_err(&pdev->dev, "error getting irq res\n");
 		rc = -ENOENT;
 		goto no_irq_res;
 	}
@@ -1888,8 +1889,8 @@
 	if (!is_valid_ether_addr(priv->mac_addr)) {
 		/* Use random MAC if none passed */
 		random_ether_addr(priv->mac_addr);
-		printk(KERN_WARNING "%s: using random MAC addr: %pM\n",
-				__func__, priv->mac_addr);
+		dev_warn(&pdev->dev, "using random MAC addr: %pM\n",
+							priv->mac_addr);
 	}
 
 	ndev->netdev_ops = &emac_netdev_ops;
@@ -1902,7 +1903,7 @@
 	SET_NETDEV_DEV(ndev, &pdev->dev);
 	rc = register_netdev(ndev);
 	if (rc) {
-		dev_err(emac_dev, "DaVinci EMAC: Error in register_netdev\n");
+		dev_err(&pdev->dev, "error in register_netdev\n");
 		rc = -ENODEV;
 		goto netdev_reg_err;
 	}
@@ -1929,8 +1930,9 @@
 	iounmap(priv->remap_addr);
 
 probe_quit:
-	clk_put(emac_clk);
 	free_netdev(ndev);
+free_clk:
+	clk_put(emac_clk);
 	return rc;
 }
 
diff -druN linux-2.6.39-libre/drivers/net/dl2k.c linux-3.0-rc7-libre/drivers/net/dl2k.c
--- linux-2.6.39-libre/drivers/net/dl2k.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/dl2k.c	2011-07-11 19:51:52.000000000 -0400
@@ -346,7 +346,7 @@
 	if (np->pdev->vendor == PCI_VENDOR_ID_DLINK) {	/* D-Link Only */
 		/* Check CRC */
 		crc = ~ether_crc_le (256 - 4, sromdata);
-		if (psrom->crc != crc) {
+		if (psrom->crc != cpu_to_le32(crc)) {
 			printk (KERN_ERR "%s: EEPROM data CRC error.\n",
 					dev->name);
 			return -1;
@@ -1189,10 +1189,10 @@
 		cmd->transceiver = XCVR_INTERNAL;
 	}
 	if ( np->link_status ) {
-		cmd->speed = np->speed;
+		ethtool_cmd_speed_set(cmd, np->speed);
 		cmd->duplex = np->full_duplex ? DUPLEX_FULL : DUPLEX_HALF;
 	} else {
-		cmd->speed = -1;
+		ethtool_cmd_speed_set(cmd, -1);
 		cmd->duplex = -1;
 	}
 	if ( np->an_enable)
@@ -1219,31 +1219,20 @@
 	} else {
 		np->an_enable = 0;
 		if (np->speed == 1000) {
-			cmd->speed = SPEED_100;
+			ethtool_cmd_speed_set(cmd, SPEED_100);
 			cmd->duplex = DUPLEX_FULL;
 			printk("Warning!! Can't disable Auto negotiation in 1000Mbps, change to Manual 100Mbps, Full duplex.\n");
 		}
-		switch(cmd->speed + cmd->duplex) {
-
-		case SPEED_10 + DUPLEX_HALF:
-			np->speed = 10;
-			np->full_duplex = 0;
-			break;
-
-		case SPEED_10 + DUPLEX_FULL:
+		switch (ethtool_cmd_speed(cmd)) {
+		case SPEED_10:
 			np->speed = 10;
-			np->full_duplex = 1;
-			break;
-		case SPEED_100 + DUPLEX_HALF:
-			np->speed = 100;
-			np->full_duplex = 0;
+			np->full_duplex = (cmd->duplex == DUPLEX_FULL);
 			break;
-		case SPEED_100 + DUPLEX_FULL:
+		case SPEED_100:
 			np->speed = 100;
-			np->full_duplex = 1;
+			np->full_duplex = (cmd->duplex == DUPLEX_FULL);
 			break;
-		case SPEED_1000 + DUPLEX_HALF:/* not supported */
-		case SPEED_1000 + DUPLEX_FULL:/* not supported */
+		case SPEED_1000: /* not supported */
 		default:
 			return -EINVAL;
 		}
diff -druN linux-2.6.39-libre/drivers/net/dm9000.c linux-3.0-rc7-libre/drivers/net/dm9000.c
--- linux-2.6.39-libre/drivers/net/dm9000.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/dm9000.c	2011-07-11 19:51:52.000000000 -0400
@@ -131,8 +131,6 @@
 	u32		msg_enable;
 	u32		wake_state;
 
-	int		rx_csum;
-	int		can_csum;
 	int		ip_summed;
 } board_info_t;
 
@@ -470,47 +468,20 @@
 	return mii_nway_restart(&dm->mii);
 }
 
-static uint32_t dm9000_get_rx_csum(struct net_device *dev)
-{
-	board_info_t *dm = to_dm9000_board(dev);
-	return dm->rx_csum;
-}
-
-static int dm9000_set_rx_csum_unlocked(struct net_device *dev, uint32_t data)
+static int dm9000_set_features(struct net_device *dev, u32 features)
 {
 	board_info_t *dm = to_dm9000_board(dev);
+	u32 changed = dev->features ^ features;
+	unsigned long flags;
 
-	if (dm->can_csum) {
-		dm->rx_csum = data;
-		iow(dm, DM9000_RCSR, dm->rx_csum ? RCSR_CSUM : 0);
-
+	if (!(changed & NETIF_F_RXCSUM))
 		return 0;
-	}
-
-	return -EOPNOTSUPP;
-}
-
-static int dm9000_set_rx_csum(struct net_device *dev, uint32_t data)
-{
-	board_info_t *dm = to_dm9000_board(dev);
-	unsigned long flags;
-	int ret;
 
 	spin_lock_irqsave(&dm->lock, flags);
-	ret = dm9000_set_rx_csum_unlocked(dev, data);
+	iow(dm, DM9000_RCSR, (features & NETIF_F_RXCSUM) ? RCSR_CSUM : 0);
 	spin_unlock_irqrestore(&dm->lock, flags);
 
-	return ret;
-}
-
-static int dm9000_set_tx_csum(struct net_device *dev, uint32_t data)
-{
-	board_info_t *dm = to_dm9000_board(dev);
-	int ret = -EOPNOTSUPP;
-
-	if (dm->can_csum)
-		ret = ethtool_op_set_tx_csum(dev, data);
-	return ret;
+	return 0;
 }
 
 static u32 dm9000_get_link(struct net_device *dev)
@@ -643,10 +614,6 @@
  	.get_eeprom_len		= dm9000_get_eeprom_len,
  	.get_eeprom		= dm9000_get_eeprom,
  	.set_eeprom		= dm9000_set_eeprom,
-	.get_rx_csum		= dm9000_get_rx_csum,
-	.set_rx_csum		= dm9000_set_rx_csum,
-	.get_tx_csum		= ethtool_op_get_tx_csum,
-	.set_tx_csum		= dm9000_set_tx_csum,
 };
 
 static void dm9000_show_carrier(board_info_t *db,
@@ -800,7 +767,9 @@
 	db->io_mode = ior(db, DM9000_ISR) >> 6;	/* ISR bit7:6 keeps I/O mode */
 
 	/* Checksum mode */
-	dm9000_set_rx_csum_unlocked(dev, db->rx_csum);
+	if (dev->hw_features & NETIF_F_RXCSUM)
+		iow(db, DM9000_RCSR,
+			(dev->features & NETIF_F_RXCSUM) ? RCSR_CSUM : 0);
 
 	iow(db, DM9000_GPCR, GPCR_GEP_CNTL);	/* Let GPIO0 output */
 
@@ -1049,7 +1018,7 @@
 
 			/* Pass to upper layer */
 			skb->protocol = eth_type_trans(skb, dev);
-			if (db->rx_csum) {
+			if (dev->features & NETIF_F_RXCSUM) {
 				if ((((rxbyte & 0x1c) << 3) & rxbyte) == 0)
 					skb->ip_summed = CHECKSUM_UNNECESSARY;
 				else
@@ -1188,9 +1157,6 @@
 
 	irqflags |= IRQF_SHARED;
 
-	if (request_irq(dev->irq, dm9000_interrupt, irqflags, dev->name, dev))
-		return -EAGAIN;
-
 	/* GPIO0 on pre-activate PHY, Reg 1F is not set by reset */
 	iow(db, DM9000_GPR, 0);	/* REG_1F bit0 activate phyxcer */
 	mdelay(1); /* delay needs by DM9000B */
@@ -1199,6 +1165,9 @@
 	dm9000_reset(db);
 	dm9000_init_dm9000(dev);
 
+	if (request_irq(dev->irq, dm9000_interrupt, irqflags, dev->name, dev))
+		return -EAGAIN;
+
 	/* Init driver variable */
 	db->dbug_cnt = 0;
 
@@ -1358,6 +1327,7 @@
 	.ndo_set_multicast_list	= dm9000_hash_table,
 	.ndo_do_ioctl		= dm9000_ioctl,
 	.ndo_change_mtu		= eth_change_mtu,
+	.ndo_set_features	= dm9000_set_features,
 	.ndo_validate_addr	= eth_validate_addr,
 	.ndo_set_mac_address	= eth_mac_addr,
 #ifdef CONFIG_NET_POLL_CONTROLLER
@@ -1551,9 +1521,8 @@
 
 	/* dm9000a/b are capable of hardware checksum offload */
 	if (db->type == TYPE_DM9000A || db->type == TYPE_DM9000B) {
-		db->can_csum = 1;
-		db->rx_csum = 1;
-		ndev->features |= NETIF_F_IP_CSUM;
+		ndev->hw_features = NETIF_F_RXCSUM | NETIF_F_IP_CSUM;
+		ndev->features |= ndev->hw_features;
 	}
 
 	/* from this point we assume that we have found a DM9000 */
diff -druN linux-2.6.39-libre/drivers/net/dummy.c linux-3.0-rc7-libre/drivers/net/dummy.c
--- linux-2.6.39-libre/drivers/net/dummy.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/dummy.c	2011-07-11 19:51:52.000000000 -0400
@@ -168,10 +168,6 @@
 	if (!dev_dummy)
 		return -ENOMEM;
 
-	err = dev_alloc_name(dev_dummy, dev_dummy->name);
-	if (err < 0)
-		goto err;
-
 	dev_dummy->rtnl_link_ops = &dummy_link_ops;
 	err = register_netdevice(dev_dummy);
 	if (err < 0)
diff -druN linux-2.6.39-libre/drivers/net/e1000/e1000_ethtool.c linux-3.0-rc7-libre/drivers/net/e1000/e1000_ethtool.c
--- linux-2.6.39-libre/drivers/net/e1000/e1000_ethtool.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/e1000/e1000_ethtool.c	2011-07-11 19:51:52.000000000 -0400
@@ -158,7 +158,7 @@
 
 		e1000_get_speed_and_duplex(hw, &adapter->link_speed,
 		                                   &adapter->link_duplex);
-		ecmd->speed = adapter->link_speed;
+		ethtool_cmd_speed_set(ecmd, adapter->link_speed);
 
 		/* unfortunately FULL_DUPLEX != DUPLEX_FULL
 		 *          and HALF_DUPLEX != DUPLEX_HALF */
@@ -168,7 +168,7 @@
 		else
 			ecmd->duplex = DUPLEX_HALF;
 	} else {
-		ecmd->speed = -1;
+		ethtool_cmd_speed_set(ecmd, -1);
 		ecmd->duplex = -1;
 	}
 
@@ -197,11 +197,13 @@
 			                         ADVERTISED_TP |
 			                         ADVERTISED_Autoneg;
 		ecmd->advertising = hw->autoneg_advertised;
-	} else
-		if (e1000_set_spd_dplx(adapter, ecmd->speed + ecmd->duplex)) {
+	} else {
+		u32 speed = ethtool_cmd_speed(ecmd);
+		if (e1000_set_spd_dplx(adapter, speed, ecmd->duplex)) {
 			clear_bit(__E1000_RESETTING, &adapter->flags);
 			return -EINVAL;
 		}
+	}
 
 	/* reset the link */
 
@@ -1753,46 +1755,28 @@
 	return 0;
 }
 
-/* toggle LED 4 times per second = 2 "blinks" per second */
-#define E1000_ID_INTERVAL	(HZ/4)
-
-/* bit defines for adapter->led_status */
-#define E1000_LED_ON		0
-
-static void e1000_led_blink_callback(unsigned long data)
+static int e1000_set_phys_id(struct net_device *netdev,
+			     enum ethtool_phys_id_state state)
 {
-	struct e1000_adapter *adapter = (struct e1000_adapter *) data;
+	struct e1000_adapter *adapter = netdev_priv(netdev);
 	struct e1000_hw *hw = &adapter->hw;
 
-	if (test_and_change_bit(E1000_LED_ON, &adapter->led_status))
-		e1000_led_off(hw);
-	else
-		e1000_led_on(hw);
-
-	mod_timer(&adapter->blink_timer, jiffies + E1000_ID_INTERVAL);
-}
+	switch (state) {
+	case ETHTOOL_ID_ACTIVE:
+		e1000_setup_led(hw);
+		return 2;
 
-static int e1000_phys_id(struct net_device *netdev, u32 data)
-{
-	struct e1000_adapter *adapter = netdev_priv(netdev);
-	struct e1000_hw *hw = &adapter->hw;
+	case ETHTOOL_ID_ON:
+		e1000_led_on(hw);
+		break;
 
-	if (!data)
-		data = INT_MAX;
+	case ETHTOOL_ID_OFF:
+		e1000_led_off(hw);
+		break;
 
-	if (!adapter->blink_timer.function) {
-		init_timer(&adapter->blink_timer);
-		adapter->blink_timer.function = e1000_led_blink_callback;
-		adapter->blink_timer.data = (unsigned long)adapter;
+	case ETHTOOL_ID_INACTIVE:
+		e1000_cleanup_led(hw);
 	}
-	e1000_setup_led(hw);
-	mod_timer(&adapter->blink_timer, jiffies);
-	msleep_interruptible(data * 1000);
-	del_timer_sync(&adapter->blink_timer);
-
-	e1000_led_off(hw);
-	clear_bit(E1000_LED_ON, &adapter->led_status);
-	e1000_cleanup_led(hw);
 
 	return 0;
 }
@@ -1929,7 +1913,7 @@
 	.set_tso                = e1000_set_tso,
 	.self_test              = e1000_diag_test,
 	.get_strings            = e1000_get_strings,
-	.phys_id                = e1000_phys_id,
+	.set_phys_id            = e1000_set_phys_id,
 	.get_ethtool_stats      = e1000_get_ethtool_stats,
 	.get_sset_count         = e1000_get_sset_count,
 	.get_coalesce           = e1000_get_coalesce,
diff -druN linux-2.6.39-libre/drivers/net/e1000/e1000.h linux-3.0-rc7-libre/drivers/net/e1000/e1000.h
--- linux-2.6.39-libre/drivers/net/e1000/e1000.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/e1000/e1000.h	2011-07-11 19:51:52.000000000 -0400
@@ -238,9 +238,6 @@
 	struct work_struct reset_task;
 	u8 fc_autoneg;
 
-	struct timer_list blink_timer;
-	unsigned long led_status;
-
 	/* TX */
 	struct e1000_tx_ring *tx_ring;      /* One per active queue */
 	unsigned int restart_queue;
@@ -349,7 +346,7 @@
 extern void e1000_down(struct e1000_adapter *adapter);
 extern void e1000_reinit_locked(struct e1000_adapter *adapter);
 extern void e1000_reset(struct e1000_adapter *adapter);
-extern int e1000_set_spd_dplx(struct e1000_adapter *adapter, u16 spddplx);
+extern int e1000_set_spd_dplx(struct e1000_adapter *adapter, u32 spd, u8 dplx);
 extern int e1000_setup_all_rx_resources(struct e1000_adapter *adapter);
 extern int e1000_setup_all_tx_resources(struct e1000_adapter *adapter);
 extern void e1000_free_all_rx_resources(struct e1000_adapter *adapter);
diff -druN linux-2.6.39-libre/drivers/net/e1000/e1000_main.c linux-3.0-rc7-libre/drivers/net/e1000/e1000_main.c
--- linux-2.6.39-libre/drivers/net/e1000/e1000_main.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/e1000/e1000_main.c	2011-07-11 19:51:52.000000000 -0400
@@ -29,6 +29,7 @@
 #include "e1000.h"
 #include <net/ip6_checksum.h>
 #include <linux/io.h>
+#include <linux/prefetch.h>
 
 /* Intel Media SOC GbE MDIO physical base address */
 static unsigned long ce4100_gbe_mdio_base_phy;
@@ -96,7 +97,6 @@
 void e1000_down(struct e1000_adapter *adapter);
 void e1000_reinit_locked(struct e1000_adapter *adapter);
 void e1000_reset(struct e1000_adapter *adapter);
-int e1000_set_spd_dplx(struct e1000_adapter *adapter, u16 spddplx);
 int e1000_setup_all_tx_resources(struct e1000_adapter *adapter);
 int e1000_setup_all_rx_resources(struct e1000_adapter *adapter);
 void e1000_free_all_tx_resources(struct e1000_adapter *adapter);
@@ -4385,7 +4385,6 @@
 	struct mii_ioctl_data *data = if_mii(ifr);
 	int retval;
 	u16 mii_reg;
-	u16 spddplx;
 	unsigned long flags;
 
 	if (hw->media_type != e1000_media_type_copper)
@@ -4424,17 +4423,18 @@
 					hw->autoneg = 1;
 					hw->autoneg_advertised = 0x2F;
 				} else {
+					u32 speed;
 					if (mii_reg & 0x40)
-						spddplx = SPEED_1000;
+						speed = SPEED_1000;
 					else if (mii_reg & 0x2000)
-						spddplx = SPEED_100;
+						speed = SPEED_100;
 					else
-						spddplx = SPEED_10;
-					spddplx += (mii_reg & 0x100)
-						   ? DUPLEX_FULL :
-						   DUPLEX_HALF;
-					retval = e1000_set_spd_dplx(adapter,
-								    spddplx);
+						speed = SPEED_10;
+					retval = e1000_set_spd_dplx(
+						adapter, speed,
+						((mii_reg & 0x100)
+						 ? DUPLEX_FULL :
+						 DUPLEX_HALF));
 					if (retval)
 						return retval;
 				}
@@ -4596,20 +4596,24 @@
 	}
 }
 
-int e1000_set_spd_dplx(struct e1000_adapter *adapter, u16 spddplx)
+int e1000_set_spd_dplx(struct e1000_adapter *adapter, u32 spd, u8 dplx)
 {
 	struct e1000_hw *hw = &adapter->hw;
 
 	hw->autoneg = 0;
 
+	/* Make sure dplx is at most 1 bit and lsb of speed is not set
+	 * for the switch() below to work */
+	if ((spd & 1) || (dplx & ~1))
+		goto err_inval;
+
 	/* Fiber NICs only allow 1000 gbps Full duplex */
 	if ((hw->media_type == e1000_media_type_fiber) &&
-		spddplx != (SPEED_1000 + DUPLEX_FULL)) {
-		e_err(probe, "Unsupported Speed/Duplex configuration\n");
-		return -EINVAL;
-	}
+	    spd != SPEED_1000 &&
+	    dplx != DUPLEX_FULL)
+		goto err_inval;
 
-	switch (spddplx) {
+	switch (spd + dplx) {
 	case SPEED_10 + DUPLEX_HALF:
 		hw->forced_speed_duplex = e1000_10_half;
 		break;
@@ -4628,10 +4632,13 @@
 		break;
 	case SPEED_1000 + DUPLEX_HALF: /* not supported */
 	default:
-		e_err(probe, "Unsupported Speed/Duplex configuration\n");
-		return -EINVAL;
+		goto err_inval;
 	}
 	return 0;
+
+err_inval:
+	e_err(probe, "Unsupported Speed/Duplex configuration\n");
+	return -EINVAL;
 }
 
 static int __e1000_shutdown(struct pci_dev *pdev, bool *enable_wake)
diff -druN linux-2.6.39-libre/drivers/net/e1000e/82571.c linux-3.0-rc7-libre/drivers/net/e1000e/82571.c
--- linux-2.6.39-libre/drivers/net/e1000e/82571.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/e1000e/82571.c	2011-07-11 19:51:52.000000000 -0400
@@ -300,6 +300,7 @@
 		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;
+		func->blink_led = e1000e_blink_led_generic;
 
 		/* FWSM register */
 		mac->has_fwsm = true;
@@ -320,6 +321,7 @@
 	default:
 		func->check_mng_mode = e1000e_check_mng_mode_generic;
 		func->led_on = e1000e_led_on_generic;
+		func->blink_led = e1000e_blink_led_generic;
 
 		/* FWSM register */
 		mac->has_fwsm = true;
@@ -431,9 +433,6 @@
 	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) {
 			adapter->flags |= FLAG_HAS_JUMBO_FRAMES;
 			adapter->max_hw_frame_size = DEFAULT_JUMBO;
@@ -594,7 +593,7 @@
 
 		extcnf_ctrl |= E1000_EXTCNF_CTRL_MDIO_SW_OWNERSHIP;
 
-		msleep(2);
+		usleep_range(2000, 4000);
 		i++;
 	} while (i < MDIO_OWNERSHIP_TIMEOUT);
 
@@ -816,7 +815,7 @@
 
 	/* Check for pending operations. */
 	for (i = 0; i < E1000_FLASH_UPDATES; i++) {
-		msleep(1);
+		usleep_range(1000, 2000);
 		if ((er32(EECD) & E1000_EECD_FLUPD) == 0)
 			break;
 	}
@@ -840,7 +839,7 @@
 	ew32(EECD, eecd);
 
 	for (i = 0; i < E1000_FLASH_UPDATES; i++) {
-		msleep(1);
+		usleep_range(1000, 2000);
 		if ((er32(EECD) & E1000_EECD_FLUPD) == 0)
 			break;
 	}
@@ -930,7 +929,7 @@
 		if (er32(EEMNGCTL) &
 		    E1000_NVM_CFG_DONE_PORT_0)
 			break;
-		msleep(1);
+		usleep_range(1000, 2000);
 		timeout--;
 	}
 	if (!timeout) {
@@ -1037,7 +1036,7 @@
 	ew32(TCTL, E1000_TCTL_PSP);
 	e1e_flush();
 
-	msleep(10);
+	usleep_range(10000, 20000);
 
 	/*
 	 * Must acquire the MDIO ownership before MAC reset.
@@ -2066,7 +2065,8 @@
 				  | FLAG_HAS_SMART_POWER_DOWN
 				  | FLAG_HAS_AMT
 				  | FLAG_HAS_SWSM_ON_LOAD,
-	.flags2			= FLAG2_DISABLE_ASPM_L1,
+	.flags2			= FLAG2_DISABLE_ASPM_L1
+				  | FLAG2_DISABLE_ASPM_L0S,
 	.pba			= 20,
 	.max_hw_frame_size	= ETH_FRAME_LEN + ETH_FCS_LEN,
 	.get_variants		= e1000_get_variants_82571,
@@ -2086,7 +2086,8 @@
 				  | FLAG_HAS_SMART_POWER_DOWN
 				  | FLAG_HAS_AMT
 				  | FLAG_HAS_CTRLEXT_ON_LOAD,
-	.flags2			  = FLAG2_CHECK_PHY_HANG,
+	.flags2			  = FLAG2_CHECK_PHY_HANG
+				  | FLAG2_DISABLE_ASPM_L0S,
 	.pba			= 32,
 	.max_hw_frame_size	= DEFAULT_JUMBO,
 	.get_variants		= e1000_get_variants_82571,
@@ -2104,6 +2105,7 @@
 				  | FLAG_HAS_SMART_POWER_DOWN
 				  | FLAG_HAS_AMT
 				  | FLAG_HAS_CTRLEXT_ON_LOAD,
+	.flags2			= FLAG2_DISABLE_ASPM_L0S,
 	.pba			= 32,
 	.max_hw_frame_size	= ETH_FRAME_LEN + ETH_FCS_LEN,
 	.get_variants		= e1000_get_variants_82571,
diff -druN linux-2.6.39-libre/drivers/net/e1000e/e1000.h linux-3.0-rc7-libre/drivers/net/e1000e/e1000.h
--- linux-2.6.39-libre/drivers/net/e1000e/e1000.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/e1000e/e1000.h	2011-07-11 19:51:52.000000000 -0400
@@ -31,6 +31,7 @@
 #ifndef _E1000_H_
 #define _E1000_H_
 
+#include <linux/bitops.h>
 #include <linux/types.h>
 #include <linux/timer.h>
 #include <linux/workqueue.h>
@@ -39,6 +40,7 @@
 #include <linux/pci.h>
 #include <linux/pci-aspm.h>
 #include <linux/crc32.h>
+#include <linux/if_vlan.h>
 
 #include "hw.h"
 
@@ -280,7 +282,7 @@
 
 	const struct e1000_info *ei;
 
-	struct vlan_group *vlgrp;
+	unsigned long active_vlans[BITS_TO_LONGS(VLAN_N_VID)];
 	u32 bd_number;
 	u32 rx_buffer_len;
 	u16 mng_vlan_id;
@@ -389,13 +391,10 @@
 
 	bool fc_autoneg;
 
-	unsigned long led_status;
-
 	unsigned int flags;
 	unsigned int flags2;
 	struct work_struct downshift_task;
 	struct work_struct update_phy_task;
-	struct work_struct led_blink_task;
 	struct work_struct print_hang_task;
 
 	bool idle_check;
@@ -456,6 +455,7 @@
 #define FLAG2_HAS_PHY_STATS               (1 << 4)
 #define FLAG2_HAS_EEE                     (1 << 5)
 #define FLAG2_DMA_BURST                   (1 << 6)
+#define FLAG2_DISABLE_ASPM_L0S            (1 << 7)
 #define FLAG2_DISABLE_AIM                 (1 << 8)
 #define FLAG2_CHECK_PHY_HANG              (1 << 9)
 
@@ -484,7 +484,6 @@
 
 extern void e1000e_check_options(struct e1000_adapter *adapter);
 extern void e1000e_set_ethtool_ops(struct net_device *netdev);
-extern void e1000e_led_blink_task(struct work_struct *work);
 
 extern int e1000e_up(struct e1000_adapter *adapter);
 extern void e1000e_down(struct e1000_adapter *adapter);
@@ -502,7 +501,6 @@
 extern void e1000e_reset_interrupt_capability(struct e1000_adapter *adapter);
 extern void e1000e_get_hw_control(struct e1000_adapter *adapter);
 extern void e1000e_release_hw_control(struct e1000_adapter *adapter);
-extern void e1000e_disable_aspm(struct pci_dev *pdev, u16 state);
 
 extern unsigned int copybreak;
 
@@ -573,7 +571,7 @@
 extern void e1000e_config_collision_dist(struct e1000_hw *hw);
 extern s32 e1000e_config_fc_after_link_up(struct e1000_hw *hw);
 extern s32 e1000e_force_mac_fc(struct e1000_hw *hw);
-extern s32 e1000e_blink_led(struct e1000_hw *hw);
+extern s32 e1000e_blink_led_generic(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);
diff -druN linux-2.6.39-libre/drivers/net/e1000e/es2lan.c linux-3.0-rc7-libre/drivers/net/e1000e/es2lan.c
--- linux-2.6.39-libre/drivers/net/e1000e/es2lan.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/e1000e/es2lan.c	2011-07-11 19:51:52.000000000 -0400
@@ -612,7 +612,7 @@
 	while (timeout) {
 		if (er32(EEMNGCTL) & mask)
 			break;
-		msleep(1);
+		usleep_range(1000, 2000);
 		timeout--;
 	}
 	if (!timeout) {
@@ -802,7 +802,7 @@
 	ew32(TCTL, E1000_TCTL_PSP);
 	e1e_flush();
 
-	msleep(10);
+	usleep_range(10000, 20000);
 
 	ctrl = er32(CTRL);
 
@@ -1434,6 +1434,7 @@
 static struct e1000_mac_operations es2_mac_ops = {
 	.read_mac_addr		= e1000_read_mac_addr_80003es2lan,
 	.id_led_init		= e1000e_id_led_init,
+	.blink_led		= e1000e_blink_led_generic,
 	.check_mng_mode		= e1000e_check_mng_mode_generic,
 	/* check_for_link dependent on media type */
 	.cleanup_led		= e1000e_cleanup_led_generic,
diff -druN linux-2.6.39-libre/drivers/net/e1000e/ethtool.c linux-3.0-rc7-libre/drivers/net/e1000e/ethtool.c
--- linux-2.6.39-libre/drivers/net/e1000e/ethtool.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/e1000e/ethtool.c	2011-07-11 19:51:52.000000000 -0400
@@ -122,6 +122,7 @@
 {
 	struct e1000_adapter *adapter = netdev_priv(netdev);
 	struct e1000_hw *hw = &adapter->hw;
+	u32 speed;
 
 	if (hw->phy.media_type == e1000_media_type_copper) {
 
@@ -159,23 +160,23 @@
 		ecmd->transceiver = XCVR_EXTERNAL;
 	}
 
-	ecmd->speed = -1;
+	speed = -1;
 	ecmd->duplex = -1;
 
 	if (netif_running(netdev)) {
 		if (netif_carrier_ok(netdev)) {
-			ecmd->speed = adapter->link_speed;
+			speed = adapter->link_speed;
 			ecmd->duplex = adapter->link_duplex - 1;
 		}
 	} else {
 		u32 status = er32(STATUS);
 		if (status & E1000_STATUS_LU) {
 			if (status & E1000_STATUS_SPEED_1000)
-				ecmd->speed = 1000;
+				speed = SPEED_1000;
 			else if (status & E1000_STATUS_SPEED_100)
-				ecmd->speed = 100;
+				speed = SPEED_100;
 			else
-				ecmd->speed = 10;
+				speed = SPEED_10;
 
 			if (status & E1000_STATUS_FD)
 				ecmd->duplex = DUPLEX_FULL;
@@ -184,6 +185,7 @@
 		}
 	}
 
+	ethtool_cmd_speed_set(ecmd, speed);
 	ecmd->autoneg = ((hw->phy.media_type == e1000_media_type_fiber) ||
 			 hw->mac.autoneg) ? AUTONEG_ENABLE : AUTONEG_DISABLE;
 
@@ -198,20 +200,25 @@
 	return 0;
 }
 
-static int e1000_set_spd_dplx(struct e1000_adapter *adapter, u16 spddplx)
+static int e1000_set_spd_dplx(struct e1000_adapter *adapter, u32 spd, u8 dplx)
 {
 	struct e1000_mac_info *mac = &adapter->hw.mac;
 
 	mac->autoneg = 0;
 
+	/* Make sure dplx is at most 1 bit and lsb of speed is not set
+	 * for the switch() below to work */
+	if ((spd & 1) || (dplx & ~1))
+		goto err_inval;
+
 	/* Fiber NICs only allow 1000 gbps Full duplex */
 	if ((adapter->hw.phy.media_type == e1000_media_type_fiber) &&
-		spddplx != (SPEED_1000 + DUPLEX_FULL)) {
-		e_err("Unsupported Speed/Duplex configuration\n");
-		return -EINVAL;
+	    spd != SPEED_1000 &&
+	    dplx != DUPLEX_FULL) {
+		goto err_inval;
 	}
 
-	switch (spddplx) {
+	switch (spd + dplx) {
 	case SPEED_10 + DUPLEX_HALF:
 		mac->forced_speed_duplex = ADVERTISE_10_HALF;
 		break;
@@ -230,10 +237,13 @@
 		break;
 	case SPEED_1000 + DUPLEX_HALF: /* not supported */
 	default:
-		e_err("Unsupported Speed/Duplex configuration\n");
-		return -EINVAL;
+		goto err_inval;
 	}
 	return 0;
+
+err_inval:
+	e_err("Unsupported Speed/Duplex configuration\n");
+	return -EINVAL;
 }
 
 static int e1000_set_settings(struct net_device *netdev,
@@ -253,7 +263,7 @@
 	}
 
 	while (test_and_set_bit(__E1000_RESETTING, &adapter->state))
-		msleep(1);
+		usleep_range(1000, 2000);
 
 	if (ecmd->autoneg == AUTONEG_ENABLE) {
 		hw->mac.autoneg = 1;
@@ -269,7 +279,8 @@
 		if (adapter->fc_autoneg)
 			hw->fc.requested_mode = e1000_fc_default;
 	} else {
-		if (e1000_set_spd_dplx(adapter, ecmd->speed + ecmd->duplex)) {
+		u32 speed = ethtool_cmd_speed(ecmd);
+		if (e1000_set_spd_dplx(adapter, speed, ecmd->duplex)) {
 			clear_bit(__E1000_RESETTING, &adapter->state);
 			return -EINVAL;
 		}
@@ -317,7 +328,7 @@
 	adapter->fc_autoneg = pause->autoneg;
 
 	while (test_and_set_bit(__E1000_RESETTING, &adapter->state))
-		msleep(1);
+		usleep_range(1000, 2000);
 
 	if (adapter->fc_autoneg == AUTONEG_ENABLE) {
 		hw->fc.requested_mode = e1000_fc_default;
@@ -673,7 +684,7 @@
 		return -EINVAL;
 
 	while (test_and_set_bit(__E1000_RESETTING, &adapter->state))
-		msleep(1);
+		usleep_range(1000, 2000);
 
 	if (netif_running(adapter->netdev))
 		e1000e_down(adapter);
@@ -952,7 +963,7 @@
 
 	/* Disable all the interrupts */
 	ew32(IMC, 0xFFFFFFFF);
-	msleep(10);
+	usleep_range(10000, 20000);
 
 	/* Test each interrupt */
 	for (i = 0; i < 10; i++) {
@@ -984,7 +995,7 @@
 			adapter->test_icr = 0;
 			ew32(IMC, mask);
 			ew32(ICS, mask);
-			msleep(10);
+			usleep_range(10000, 20000);
 
 			if (adapter->test_icr & mask) {
 				*data = 3;
@@ -1002,7 +1013,7 @@
 		adapter->test_icr = 0;
 		ew32(IMS, mask);
 		ew32(ICS, mask);
-		msleep(10);
+		usleep_range(10000, 20000);
 
 		if (!(adapter->test_icr & mask)) {
 			*data = 4;
@@ -1020,7 +1031,7 @@
 			adapter->test_icr = 0;
 			ew32(IMC, ~mask & 0x00007FFF);
 			ew32(ICS, ~mask & 0x00007FFF);
-			msleep(10);
+			usleep_range(10000, 20000);
 
 			if (adapter->test_icr) {
 				*data = 5;
@@ -1031,7 +1042,7 @@
 
 	/* Disable all the interrupts */
 	ew32(IMC, 0xFFFFFFFF);
-	msleep(10);
+	usleep_range(10000, 20000);
 
 	/* Unhook test interrupt handler */
 	free_irq(irq, netdev);
@@ -1406,7 +1417,7 @@
 	 */
 #define E1000_SERDES_LB_ON 0x410
 	ew32(SCTL, E1000_SERDES_LB_ON);
-	msleep(10);
+	usleep_range(10000, 20000);
 
 	return 0;
 }
@@ -1501,7 +1512,7 @@
 		    hw->phy.media_type == e1000_media_type_internal_serdes) {
 #define E1000_SERDES_LB_OFF 0x400
 			ew32(SCTL, E1000_SERDES_LB_OFF);
-			msleep(10);
+			usleep_range(10000, 20000);
 			break;
 		}
 		/* Fall Through */
@@ -1851,64 +1862,35 @@
 	return 0;
 }
 
-/* toggle LED 4 times per second = 2 "blinks" per second */
-#define E1000_ID_INTERVAL	(HZ/4)
-
-/* bit defines for adapter->led_status */
-#define E1000_LED_ON		0
-
-void e1000e_led_blink_task(struct work_struct *work)
-{
-	struct e1000_adapter *adapter = container_of(work,
-	                                struct e1000_adapter, led_blink_task);
-
-	if (test_and_change_bit(E1000_LED_ON, &adapter->led_status))
-		adapter->hw.mac.ops.led_off(&adapter->hw);
-	else
-		adapter->hw.mac.ops.led_on(&adapter->hw);
-}
-
-static void e1000_led_blink_callback(unsigned long data)
-{
-	struct e1000_adapter *adapter = (struct e1000_adapter *) data;
-
-	schedule_work(&adapter->led_blink_task);
-	mod_timer(&adapter->blink_timer, jiffies + E1000_ID_INTERVAL);
-}
-
-static int e1000_phys_id(struct net_device *netdev, u32 data)
+static int e1000_set_phys_id(struct net_device *netdev,
+			     enum ethtool_phys_id_state state)
 {
 	struct e1000_adapter *adapter = netdev_priv(netdev);
 	struct e1000_hw *hw = &adapter->hw;
 
-	if (!data)
-		data = INT_MAX;
+	switch (state) {
+	case ETHTOOL_ID_ACTIVE:
+		if (!hw->mac.ops.blink_led)
+			return 2;	/* cycle on/off twice per second */
 
-	if ((hw->phy.type == e1000_phy_ife) ||
-	    (hw->mac.type == e1000_pchlan) ||
-	    (hw->mac.type == e1000_pch2lan) ||
-	    (hw->mac.type == e1000_82583) ||
-	    (hw->mac.type == e1000_82574)) {
-		if (!adapter->blink_timer.function) {
-			init_timer(&adapter->blink_timer);
-			adapter->blink_timer.function =
-				e1000_led_blink_callback;
-			adapter->blink_timer.data = (unsigned long) adapter;
-		}
-		mod_timer(&adapter->blink_timer, jiffies);
-		msleep_interruptible(data * 1000);
-		del_timer_sync(&adapter->blink_timer);
+		hw->mac.ops.blink_led(hw);
+		break;
+
+	case ETHTOOL_ID_INACTIVE:
 		if (hw->phy.type == e1000_phy_ife)
 			e1e_wphy(hw, IFE_PHY_SPECIAL_CONTROL_LED, 0);
-	} else {
-		e1000e_blink_led(hw);
-		msleep_interruptible(data * 1000);
-	}
+		hw->mac.ops.led_off(hw);
+		hw->mac.ops.cleanup_led(hw);
+		break;
 
-	hw->mac.ops.led_off(hw);
-	clear_bit(E1000_LED_ON, &adapter->led_status);
-	hw->mac.ops.cleanup_led(hw);
+	case ETHTOOL_ID_ON:
+		adapter->hw.mac.ops.led_on(&adapter->hw);
+		break;
 
+	case ETHTOOL_ID_OFF:
+		adapter->hw.mac.ops.led_off(&adapter->hw);
+		break;
+	}
 	return 0;
 }
 
@@ -2020,6 +2002,31 @@
 	}
 }
 
+static int e1000e_set_flags(struct net_device *netdev, u32 data)
+{
+	struct e1000_adapter *adapter = netdev_priv(netdev);
+	bool need_reset = false;
+	int rc;
+
+	need_reset = (data & ETH_FLAG_RXVLAN) !=
+		     (netdev->features & NETIF_F_HW_VLAN_RX);
+
+	rc = ethtool_op_set_flags(netdev, data, ETH_FLAG_RXVLAN |
+				  ETH_FLAG_TXVLAN);
+
+	if (rc)
+		return rc;
+
+	if (need_reset) {
+		if (netif_running(netdev))
+			e1000e_reinit_locked(adapter);
+		else
+			e1000e_reset(adapter);
+	}
+
+	return 0;
+}
+
 static const struct ethtool_ops e1000_ethtool_ops = {
 	.get_settings		= e1000_get_settings,
 	.set_settings		= e1000_set_settings,
@@ -2049,12 +2056,13 @@
 	.set_tso		= e1000_set_tso,
 	.self_test		= e1000_diag_test,
 	.get_strings		= e1000_get_strings,
-	.phys_id		= e1000_phys_id,
+	.set_phys_id		= e1000_set_phys_id,
 	.get_ethtool_stats	= e1000_get_ethtool_stats,
 	.get_sset_count		= e1000e_get_sset_count,
 	.get_coalesce		= e1000_get_coalesce,
 	.set_coalesce		= e1000_set_coalesce,
 	.get_flags		= ethtool_op_get_flags,
+	.set_flags		= e1000e_set_flags,
 };
 
 void e1000e_set_ethtool_ops(struct net_device *netdev)
diff -druN linux-2.6.39-libre/drivers/net/e1000e/hw.h linux-3.0-rc7-libre/drivers/net/e1000e/hw.h
--- linux-2.6.39-libre/drivers/net/e1000e/hw.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/e1000e/hw.h	2011-07-11 19:51:52.000000000 -0400
@@ -756,6 +756,7 @@
 /* Function pointers and static data for the MAC. */
 struct e1000_mac_operations {
 	s32  (*id_led_init)(struct e1000_hw *);
+	s32  (*blink_led)(struct e1000_hw *);
 	bool (*check_mng_mode)(struct e1000_hw *);
 	s32  (*check_for_link)(struct e1000_hw *);
 	s32  (*cleanup_led)(struct e1000_hw *);
diff -druN linux-2.6.39-libre/drivers/net/e1000e/ich8lan.c linux-3.0-rc7-libre/drivers/net/e1000e/ich8lan.c
--- linux-2.6.39-libre/drivers/net/e1000e/ich8lan.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/e1000e/ich8lan.c	2011-07-11 19:51:52.000000000 -0400
@@ -338,7 +338,7 @@
 	/* Ungate automatic PHY configuration on non-managed 82579 */
 	if ((hw->mac.type == e1000_pch2lan) &&
 	    !(fwsm & E1000_ICH_FWSM_FW_VALID)) {
-		msleep(10);
+		usleep_range(10000, 20000);
 		e1000_gate_hw_phy_config_ich8lan(hw, false);
 	}
 
@@ -427,7 +427,7 @@
 	phy->id = 0;
 	while ((e1000_phy_unknown == e1000e_get_phy_type_from_id(phy->id)) &&
 	       (i++ < 100)) {
-		msleep(1);
+		usleep_range(1000, 2000);
 		ret_val = e1000e_get_phy_id(hw);
 		if (ret_val)
 			return ret_val;
@@ -564,6 +564,8 @@
 		mac->ops.check_mng_mode = e1000_check_mng_mode_ich8lan;
 		/* ID LED init */
 		mac->ops.id_led_init = e1000e_id_led_init;
+		/* blink LED */
+		mac->ops.blink_led = e1000e_blink_led_generic;
 		/* setup LED */
 		mac->ops.setup_led = e1000e_setup_led_generic;
 		/* cleanup LED */
@@ -767,6 +769,8 @@
 	     (!(er32(CTRL_EXT) & E1000_CTRL_EXT_LSECCK)))) {
 		adapter->flags &= ~FLAG_HAS_JUMBO_FRAMES;
 		adapter->max_hw_frame_size = ETH_FRAME_LEN + ETH_FCS_LEN;
+
+		hw->mac.ops.blink_led = NULL;
 	}
 
 	if ((adapter->hw.mac.type == e1000_ich8lan) &&
@@ -1704,7 +1708,7 @@
 		goto out;
 
 	/* Allow time for h/w to get to quiescent state after reset */
-	msleep(10);
+	usleep_range(10000, 20000);
 
 	/* Perform any necessary post-reset workarounds */
 	switch (hw->mac.type) {
@@ -1737,7 +1741,7 @@
 	if (hw->mac.type == e1000_pch2lan) {
 		/* Ungate automatic PHY configuration on non-managed 82579 */
 		if (!(er32(FWSM) & E1000_ICH_FWSM_FW_VALID)) {
-			msleep(10);
+			usleep_range(10000, 20000);
 			e1000_gate_hw_phy_config_ich8lan(hw, false);
 		}
 
@@ -2532,7 +2536,7 @@
 	 */
 	if (!ret_val) {
 		e1000e_reload_nvm(hw);
-		msleep(10);
+		usleep_range(10000, 20000);
 	}
 
 out:
@@ -3009,7 +3013,7 @@
 	ew32(TCTL, E1000_TCTL_PSP);
 	e1e_flush();
 
-	msleep(10);
+	usleep_range(10000, 20000);
 
 	/* Workaround for ICH8 bit corruption issue in FIFO memory */
 	if (hw->mac.type == e1000_ich8lan) {
diff -druN linux-2.6.39-libre/drivers/net/e1000e/lib.c linux-3.0-rc7-libre/drivers/net/e1000e/lib.c
--- linux-2.6.39-libre/drivers/net/e1000e/lib.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/e1000e/lib.c	2011-07-11 19:51:52.000000000 -0400
@@ -144,7 +144,7 @@
  *  @hw: pointer to the HW structure
  *  @rar_count: receive address registers
  *
- *  Setups the receive address registers by setting the base receive address
+ *  Setup the receive address registers by setting the base receive address
  *  register to the devices MAC address and clearing all the other receive
  *  address registers to 0.
  **/
@@ -868,7 +868,7 @@
 	 * milliseconds even if the other end is doing it in SW).
 	 */
 	for (i = 0; i < FIBER_LINK_UP_LIMIT; i++) {
-		msleep(10);
+		usleep_range(10000, 20000);
 		status = er32(STATUS);
 		if (status & E1000_STATUS_LU)
 			break;
@@ -930,7 +930,7 @@
 
 	ew32(CTRL, ctrl);
 	e1e_flush();
-	msleep(1);
+	usleep_range(1000, 2000);
 
 	/*
 	 * For these adapters, the SW definable pin 1 is set when the optics
@@ -1181,7 +1181,7 @@
 			 * of pause frames.  In this case, we had to advertise
 			 * FULL flow control because we could not advertise Rx
 			 * ONLY. Hence, we must now check to see if we need to
-			 * turn OFF  the TRANSMISSION of PAUSE frames.
+			 * turn OFF the TRANSMISSION of PAUSE frames.
 			 */
 			if (hw->fc.requested_mode == e1000_fc_full) {
 				hw->fc.current_mode = e1000_fc_full;
@@ -1385,7 +1385,7 @@
 	while (i < AUTO_READ_DONE_TIMEOUT) {
 		if (er32(EECD) & E1000_EECD_AUTO_RD)
 			break;
-		msleep(1);
+		usleep_range(1000, 2000);
 		i++;
 	}
 
@@ -1530,12 +1530,12 @@
 }
 
 /**
- *  e1000e_blink_led - Blink LED
+ *  e1000e_blink_led_generic - Blink LED
  *  @hw: pointer to the HW structure
  *
  *  Blink the LEDs which are set to be on.
  **/
-s32 e1000e_blink_led(struct e1000_hw *hw)
+s32 e1000e_blink_led_generic(struct e1000_hw *hw)
 {
 	u32 ledctl_blink = 0;
 	u32 i;
@@ -2087,8 +2087,6 @@
 	if (ret_val)
 		return ret_val;
 
-	msleep(10);
-
 	while (widx < words) {
 		u8 write_opcode = NVM_WRITE_OPCODE_SPI;
 
@@ -2132,7 +2130,7 @@
 		}
 	}
 
-	msleep(10);
+	usleep_range(10000, 20000);
 	nvm->ops.release(hw);
 	return 0;
 }
diff -druN linux-2.6.39-libre/drivers/net/e1000e/netdev.c linux-3.0-rc7-libre/drivers/net/e1000e/netdev.c
--- linux-2.6.39-libre/drivers/net/e1000e/netdev.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/e1000e/netdev.c	2011-07-11 19:51:52.000000000 -0400
@@ -49,6 +49,7 @@
 #include <linux/pm_qos_params.h>
 #include <linux/pm_runtime.h>
 #include <linux/aer.h>
+#include <linux/prefetch.h>
 
 #include "e1000.h"
 
@@ -58,6 +59,8 @@
 char e1000e_driver_name[] = "e1000e";
 const char e1000e_driver_version[] = DRV_VERSION;
 
+static void e1000e_disable_aspm(struct pci_dev *pdev, u16 state);
+
 static const struct e1000_info *e1000_info_tbl[] = {
 	[board_82571]		= &e1000_82571_info,
 	[board_82572]		= &e1000_82572_info,
@@ -459,13 +462,13 @@
 			      struct net_device *netdev, struct sk_buff *skb,
 			      u8 status, __le16 vlan)
 {
+	u16 tag = le16_to_cpu(vlan);
 	skb->protocol = eth_type_trans(skb, netdev);
 
-	if (adapter->vlgrp && (status & E1000_RXD_STAT_VP))
-		vlan_gro_receive(&adapter->napi, adapter->vlgrp,
-				 le16_to_cpu(vlan), skb);
-	else
-		napi_gro_receive(&adapter->napi, skb);
+	if (status & E1000_RXD_STAT_VP)
+		__vlan_hwaccel_put_tag(skb, tag);
+
+	napi_gro_receive(&adapter->napi, skb);
 }
 
 /**
@@ -2433,6 +2436,8 @@
 		vfta |= (1 << (vid & 0x1F));
 		hw->mac.ops.write_vfta(hw, index, vfta);
 	}
+
+	set_bit(vid, adapter->active_vlans);
 }
 
 static void e1000_vlan_rx_kill_vid(struct net_device *netdev, u16 vid)
@@ -2441,13 +2446,6 @@
 	struct e1000_hw *hw = &adapter->hw;
 	u32 vfta, index;
 
-	if (!test_bit(__E1000_DOWN, &adapter->state))
-		e1000_irq_disable(adapter);
-	vlan_group_set_device(adapter->vlgrp, vid, NULL);
-
-	if (!test_bit(__E1000_DOWN, &adapter->state))
-		e1000_irq_enable(adapter);
-
 	if ((adapter->hw.mng_cookie.status &
 	     E1000_MNG_DHCP_COOKIE_STATUS_VLAN) &&
 	    (vid == adapter->mng_vlan_id)) {
@@ -2463,93 +2461,105 @@
 		vfta &= ~(1 << (vid & 0x1F));
 		hw->mac.ops.write_vfta(hw, index, vfta);
 	}
+
+	clear_bit(vid, adapter->active_vlans);
 }
 
-static void e1000_update_mng_vlan(struct e1000_adapter *adapter)
+/**
+ * e1000e_vlan_filter_disable - helper to disable hw VLAN filtering
+ * @adapter: board private structure to initialize
+ **/
+static void e1000e_vlan_filter_disable(struct e1000_adapter *adapter)
 {
 	struct net_device *netdev = adapter->netdev;
-	u16 vid = adapter->hw.mng_cookie.vlan_id;
-	u16 old_vid = adapter->mng_vlan_id;
+	struct e1000_hw *hw = &adapter->hw;
+	u32 rctl;
 
-	if (!adapter->vlgrp)
-		return;
+	if (adapter->flags & FLAG_HAS_HW_VLAN_FILTER) {
+		/* disable VLAN receive filtering */
+		rctl = er32(RCTL);
+		rctl &= ~(E1000_RCTL_VFE | E1000_RCTL_CFIEN);
+		ew32(RCTL, rctl);
 
-	if (!vlan_group_get_device(adapter->vlgrp, vid)) {
-		adapter->mng_vlan_id = E1000_MNG_VLAN_NONE;
-		if (adapter->hw.mng_cookie.status &
-			E1000_MNG_DHCP_COOKIE_STATUS_VLAN) {
-			e1000_vlan_rx_add_vid(netdev, vid);
-			adapter->mng_vlan_id = vid;
+		if (adapter->mng_vlan_id != (u16)E1000_MNG_VLAN_NONE) {
+			e1000_vlan_rx_kill_vid(netdev, adapter->mng_vlan_id);
+			adapter->mng_vlan_id = E1000_MNG_VLAN_NONE;
 		}
-
-		if ((old_vid != (u16)E1000_MNG_VLAN_NONE) &&
-				(vid != old_vid) &&
-		    !vlan_group_get_device(adapter->vlgrp, old_vid))
-			e1000_vlan_rx_kill_vid(netdev, old_vid);
-	} else {
-		adapter->mng_vlan_id = vid;
 	}
 }
 
+/**
+ * e1000e_vlan_filter_enable - helper to enable HW VLAN filtering
+ * @adapter: board private structure to initialize
+ **/
+static void e1000e_vlan_filter_enable(struct e1000_adapter *adapter)
+{
+	struct e1000_hw *hw = &adapter->hw;
+	u32 rctl;
 
-static void e1000_vlan_rx_register(struct net_device *netdev,
-				   struct vlan_group *grp)
+	if (adapter->flags & FLAG_HAS_HW_VLAN_FILTER) {
+		/* enable VLAN receive filtering */
+		rctl = er32(RCTL);
+		rctl |= E1000_RCTL_VFE;
+		rctl &= ~E1000_RCTL_CFIEN;
+		ew32(RCTL, rctl);
+	}
+}
+
+/**
+ * e1000e_vlan_strip_enable - helper to disable HW VLAN stripping
+ * @adapter: board private structure to initialize
+ **/
+static void e1000e_vlan_strip_disable(struct e1000_adapter *adapter)
 {
-	struct e1000_adapter *adapter = netdev_priv(netdev);
 	struct e1000_hw *hw = &adapter->hw;
-	u32 ctrl, rctl;
+	u32 ctrl;
 
-	if (!test_bit(__E1000_DOWN, &adapter->state))
-		e1000_irq_disable(adapter);
-	adapter->vlgrp = grp;
+	/* disable VLAN tag insert/strip */
+	ctrl = er32(CTRL);
+	ctrl &= ~E1000_CTRL_VME;
+	ew32(CTRL, ctrl);
+}
 
-	if (grp) {
-		/* enable VLAN tag insert/strip */
-		ctrl = er32(CTRL);
-		ctrl |= E1000_CTRL_VME;
-		ew32(CTRL, ctrl);
+/**
+ * e1000e_vlan_strip_enable - helper to enable HW VLAN stripping
+ * @adapter: board private structure to initialize
+ **/
+static void e1000e_vlan_strip_enable(struct e1000_adapter *adapter)
+{
+	struct e1000_hw *hw = &adapter->hw;
+	u32 ctrl;
 
-		if (adapter->flags & FLAG_HAS_HW_VLAN_FILTER) {
-			/* enable VLAN receive filtering */
-			rctl = er32(RCTL);
-			rctl &= ~E1000_RCTL_CFIEN;
-			ew32(RCTL, rctl);
-			e1000_update_mng_vlan(adapter);
-		}
-	} else {
-		/* disable VLAN tag insert/strip */
-		ctrl = er32(CTRL);
-		ctrl &= ~E1000_CTRL_VME;
-		ew32(CTRL, ctrl);
+	/* enable VLAN tag insert/strip */
+	ctrl = er32(CTRL);
+	ctrl |= E1000_CTRL_VME;
+	ew32(CTRL, ctrl);
+}
 
-		if (adapter->flags & FLAG_HAS_HW_VLAN_FILTER) {
-			if (adapter->mng_vlan_id !=
-			    (u16)E1000_MNG_VLAN_NONE) {
-				e1000_vlan_rx_kill_vid(netdev,
-						       adapter->mng_vlan_id);
-				adapter->mng_vlan_id = E1000_MNG_VLAN_NONE;
-			}
-		}
+static void e1000_update_mng_vlan(struct e1000_adapter *adapter)
+{
+	struct net_device *netdev = adapter->netdev;
+	u16 vid = adapter->hw.mng_cookie.vlan_id;
+	u16 old_vid = adapter->mng_vlan_id;
+
+	if (adapter->hw.mng_cookie.status &
+	    E1000_MNG_DHCP_COOKIE_STATUS_VLAN) {
+		e1000_vlan_rx_add_vid(netdev, vid);
+		adapter->mng_vlan_id = vid;
 	}
 
-	if (!test_bit(__E1000_DOWN, &adapter->state))
-		e1000_irq_enable(adapter);
+	if ((old_vid != (u16)E1000_MNG_VLAN_NONE) && (vid != old_vid))
+		e1000_vlan_rx_kill_vid(netdev, old_vid);
 }
 
 static void e1000_restore_vlan(struct e1000_adapter *adapter)
 {
 	u16 vid;
 
-	e1000_vlan_rx_register(adapter->netdev, adapter->vlgrp);
-
-	if (!adapter->vlgrp)
-		return;
+	e1000_vlan_rx_add_vid(adapter->netdev, 0);
 
-	for (vid = 0; vid < VLAN_N_VID; vid++) {
-		if (!vlan_group_get_device(adapter->vlgrp, vid))
-			continue;
+	for_each_set_bit(vid, adapter->active_vlans, VLAN_N_VID)
 		e1000_vlan_rx_add_vid(adapter->netdev, vid);
-	}
 }
 
 static void e1000_init_manageability_pt(struct e1000_adapter *adapter)
@@ -2902,7 +2912,7 @@
 	rctl = er32(RCTL);
 	ew32(RCTL, rctl & ~E1000_RCTL_EN);
 	e1e_flush();
-	msleep(10);
+	usleep_range(10000, 20000);
 
 	if (adapter->flags2 & FLAG2_DMA_BURST) {
 		/*
@@ -3039,6 +3049,8 @@
 	if (netdev->flags & IFF_PROMISC) {
 		rctl |= (E1000_RCTL_UPE | E1000_RCTL_MPE);
 		rctl &= ~E1000_RCTL_VFE;
+		/* Do not hardware filter VLANs in promisc mode */
+		e1000e_vlan_filter_disable(adapter);
 	} else {
 		if (netdev->flags & IFF_ALLMULTI) {
 			rctl |= E1000_RCTL_MPE;
@@ -3046,8 +3058,7 @@
 		} else {
 			rctl &= ~(E1000_RCTL_UPE | E1000_RCTL_MPE);
 		}
-		if (adapter->flags & FLAG_HAS_HW_VLAN_FILTER)
-			rctl |= E1000_RCTL_VFE;
+		e1000e_vlan_filter_enable(adapter);
 	}
 
 	ew32(RCTL, rctl);
@@ -3072,6 +3083,11 @@
 		 */
 		e1000_update_mc_addr_list(hw, NULL, 0);
 	}
+
+	if (netdev->features & NETIF_F_HW_VLAN_RX)
+		e1000e_vlan_strip_enable(adapter);
+	else
+		e1000e_vlan_strip_disable(adapter);
 }
 
 /**
@@ -3383,7 +3399,7 @@
 	ew32(TCTL, tctl);
 	/* flush both disables and wait for them to finish */
 	e1e_flush();
-	msleep(10);
+	usleep_range(10000, 20000);
 
 	napi_disable(&adapter->napi);
 	e1000_irq_disable(adapter);
@@ -3418,7 +3434,7 @@
 {
 	might_sleep();
 	while (test_and_set_bit(__E1000_RESETTING, &adapter->state))
-		msleep(1);
+		usleep_range(1000, 2000);
 	e1000e_down(adapter);
 	e1000e_up(adapter);
 	clear_bit(__E1000_RESETTING, &adapter->state);
@@ -3721,10 +3737,8 @@
 	 * kill manageability vlan ID if supported, but not if a vlan with
 	 * the same ID is registered on the host OS (let 8021q kill it)
 	 */
-	if ((adapter->hw.mng_cookie.status &
-			  E1000_MNG_DHCP_COOKIE_STATUS_VLAN) &&
-	     !(adapter->vlgrp &&
-	       vlan_group_get_device(adapter->vlgrp, adapter->mng_vlan_id)))
+	if (adapter->hw.mng_cookie.status &
+	    E1000_MNG_DHCP_COOKIE_STATUS_VLAN)
 		e1000_vlan_rx_kill_vid(netdev, adapter->mng_vlan_id);
 
 	/*
@@ -4328,7 +4342,6 @@
 link_up:
 	spin_lock(&adapter->stats64_lock);
 	e1000e_update_stats(adapter);
-	spin_unlock(&adapter->stats64_lock);
 
 	mac->tx_packet_delta = adapter->stats.tpt - adapter->tpt_old;
 	adapter->tpt_old = adapter->stats.tpt;
@@ -4339,6 +4352,7 @@
 	adapter->gorc_old = adapter->stats.gorc;
 	adapter->gotc = adapter->stats.gotc - adapter->gotc_old;
 	adapter->gotc_old = adapter->stats.gotc;
+	spin_unlock(&adapter->stats64_lock);
 
 	e1000e_update_adaptive(&adapter->hw);
 
@@ -5028,7 +5042,7 @@
 	}
 
 	while (test_and_set_bit(__E1000_RESETTING, &adapter->state))
-		msleep(1);
+		usleep_range(1000, 2000);
 	/* e1000e_down -> e1000e_reset dependent on max_frame_size & mtu */
 	adapter->max_frame_size = max_frame;
 	e_info("changing MTU from %d to %d\n", netdev->mtu, new_mtu);
@@ -5347,7 +5361,7 @@
 #ifdef CONFIG_PCIEASPM
 static void __e1000e_disable_aspm(struct pci_dev *pdev, u16 state)
 {
-	pci_disable_link_state(pdev, state);
+	pci_disable_link_state_locked(pdev, state);
 }
 #else
 static void __e1000e_disable_aspm(struct pci_dev *pdev, u16 state)
@@ -5373,7 +5387,7 @@
 	pci_write_config_word(pdev->bus->self, pos + PCI_EXP_LNKCTL, reg16);
 }
 #endif
-void e1000e_disable_aspm(struct pci_dev *pdev, u16 state)
+static 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" : "",
@@ -5393,13 +5407,19 @@
 	struct net_device *netdev = pci_get_drvdata(pdev);
 	struct e1000_adapter *adapter = netdev_priv(netdev);
 	struct e1000_hw *hw = &adapter->hw;
+	u16 aspm_disable_flag = 0;
 	u32 err;
 
+	if (adapter->flags2 & FLAG2_DISABLE_ASPM_L0S)
+		aspm_disable_flag = PCIE_LINK_STATE_L0S;
+	if (adapter->flags2 & FLAG2_DISABLE_ASPM_L1)
+		aspm_disable_flag |= PCIE_LINK_STATE_L1;
+	if (aspm_disable_flag)
+		e1000e_disable_aspm(pdev, aspm_disable_flag);
+
 	pci_set_power_state(pdev, PCI_D0);
 	pci_restore_state(pdev);
 	pci_save_state(pdev);
-	if (adapter->flags2 & FLAG2_DISABLE_ASPM_L1)
-		e1000e_disable_aspm(pdev, PCIE_LINK_STATE_L1);
 
 	e1000e_set_interrupt_capability(adapter);
 	if (netif_running(netdev)) {
@@ -5643,11 +5663,17 @@
 	struct net_device *netdev = pci_get_drvdata(pdev);
 	struct e1000_adapter *adapter = netdev_priv(netdev);
 	struct e1000_hw *hw = &adapter->hw;
+	u16 aspm_disable_flag = 0;
 	int err;
 	pci_ers_result_t result;
 
+	if (adapter->flags2 & FLAG2_DISABLE_ASPM_L0S)
+		aspm_disable_flag = PCIE_LINK_STATE_L0S;
 	if (adapter->flags2 & FLAG2_DISABLE_ASPM_L1)
-		e1000e_disable_aspm(pdev, PCIE_LINK_STATE_L1);
+		aspm_disable_flag |= PCIE_LINK_STATE_L1;
+	if (aspm_disable_flag)
+		e1000e_disable_aspm(pdev, aspm_disable_flag);
+
 	err = pci_enable_device_mem(pdev);
 	if (err) {
 		dev_err(&pdev->dev,
@@ -5714,7 +5740,7 @@
 	u8 pba_str[E1000_PBANUM_LENGTH];
 
 	/* print bus type/speed/width info */
-	e_info("(PCI Express:2.5GB/s:%s) %pM\n",
+	e_info("(PCI Express:2.5GT/s:%s) %pM\n",
 	       /* bus width */
 	       ((hw->bus.width == e1000_bus_width_pcie_x4) ? "Width x4" :
 	        "Width x1"),
@@ -5759,7 +5785,6 @@
 	.ndo_tx_timeout		= e1000_tx_timeout,
 	.ndo_validate_addr	= eth_validate_addr,
 
-	.ndo_vlan_rx_register	= e1000_vlan_rx_register,
 	.ndo_vlan_rx_add_vid	= e1000_vlan_rx_add_vid,
 	.ndo_vlan_rx_kill_vid	= e1000_vlan_rx_kill_vid,
 #ifdef CONFIG_NET_POLL_CONTROLLER
@@ -5789,12 +5814,17 @@
 	resource_size_t flash_start, flash_len;
 
 	static int cards_found;
+	u16 aspm_disable_flag = 0;
 	int i, err, pci_using_dac;
 	u16 eeprom_data = 0;
 	u16 eeprom_apme_mask = E1000_EEPROM_APME;
 
+	if (ei->flags2 & FLAG2_DISABLE_ASPM_L0S)
+		aspm_disable_flag = PCIE_LINK_STATE_L0S;
 	if (ei->flags2 & FLAG2_DISABLE_ASPM_L1)
-		e1000e_disable_aspm(pdev, PCIE_LINK_STATE_L1);
+		aspm_disable_flag |= PCIE_LINK_STATE_L1;
+	if (aspm_disable_flag)
+		e1000e_disable_aspm(pdev, aspm_disable_flag);
 
 	err = pci_enable_device_mem(pdev);
 	if (err)
@@ -5991,7 +6021,6 @@
 	INIT_WORK(&adapter->downshift_task, e1000e_downshift_workaround);
 	INIT_WORK(&adapter->update_phy_task, e1000e_update_phy_task);
 	INIT_WORK(&adapter->print_hang_task, e1000_print_hw_hang);
-	INIT_WORK(&adapter->led_blink_task, e1000e_led_blink_task);
 
 	/* Initialize link parameters. User can change them with ethtool */
 	adapter->hw.mac.autoneg = 1;
@@ -6124,7 +6153,6 @@
 	cancel_work_sync(&adapter->watchdog_task);
 	cancel_work_sync(&adapter->downshift_task);
 	cancel_work_sync(&adapter->update_phy_task);
-	cancel_work_sync(&adapter->led_blink_task);
 	cancel_work_sync(&adapter->print_hang_task);
 
 	if (!(netdev->flags & IFF_UP))
diff -druN linux-2.6.39-libre/drivers/net/e1000e/phy.c linux-3.0-rc7-libre/drivers/net/e1000e/phy.c
--- linux-2.6.39-libre/drivers/net/e1000e/phy.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/e1000e/phy.c	2011-07-11 19:51:52.000000000 -0400
@@ -2372,7 +2372,7 @@
 				ret_val = 0;
 				goto out;
 			}
-			msleep(1);
+			usleep_range(1000, 2000);
 			i++;
 		} while (i < 10);
 	}
@@ -2740,7 +2740,7 @@
 	e1e_rphy(hw, PHY_CONTROL, &mii_reg);
 	mii_reg |= MII_CR_POWER_DOWN;
 	e1e_wphy(hw, PHY_CONTROL, mii_reg);
-	msleep(1);
+	usleep_range(1000, 2000);
 }
 
 /**
diff -druN linux-2.6.39-libre/drivers/net/e100.c linux-3.0-rc7-libre/drivers/net/e100.c
--- linux-2.6.39-libre/drivers/net/e100.c	2011-05-19 02:11:50.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/e100.c	2011-07-21 06:54:22.000000000 -0400
@@ -591,7 +591,6 @@
 	enum phy phy;
 	struct params params;
 	struct timer_list watchdog;
-	struct timer_list blink_timer;
 	struct mii_if_info mii;
 	struct work_struct tx_timeout_task;
 	enum loopback loopback;
@@ -616,7 +615,6 @@
 	u32 rx_tco_frames;
 	u32 rx_over_length_errors;
 
-	u16 leds;
 	u16 eeprom_wc;
 	__le16 eeprom[256];
 	spinlock_t mdio_lock;
@@ -1511,7 +1509,7 @@
 
 static int e100_hw_init(struct nic *nic)
 {
-	int err;
+	int err = 0;
 
 	e100_hw_reset(nic);
 
@@ -1667,7 +1665,8 @@
 static void e100_watchdog(unsigned long data)
 {
 	struct nic *nic = (struct nic *)data;
-	struct ethtool_cmd cmd;
+	struct ethtool_cmd cmd = { .cmd = ETHTOOL_GSET };
+	u32 speed;
 
 	netif_printk(nic, timer, KERN_DEBUG, nic->netdev,
 		     "right now = %ld\n", jiffies);
@@ -1675,10 +1674,11 @@
 	/* mii library handles link maintenance tasks */
 
 	mii_ethtool_gset(&nic->mii, &cmd);
+	speed = ethtool_cmd_speed(&cmd);
 
 	if (mii_link_ok(&nic->mii) && !netif_carrier_ok(nic->netdev)) {
 		netdev_info(nic->netdev, "NIC Link is Up %u Mbps %s Duplex\n",
-			    cmd.speed == SPEED_100 ? 100 : 10,
+			    speed == SPEED_100 ? 100 : 10,
 			    cmd.duplex == DUPLEX_FULL ? "Full" : "Half");
 	} else if (!mii_link_ok(&nic->mii) && netif_carrier_ok(nic->netdev)) {
 		netdev_info(nic->netdev, "NIC Link is Down\n");
@@ -1697,13 +1697,13 @@
 	spin_unlock_irq(&nic->cmd_lock);
 
 	e100_update_stats(nic);
-	e100_adjust_adaptive_ifs(nic, cmd.speed, cmd.duplex);
+	e100_adjust_adaptive_ifs(nic, speed, cmd.duplex);
 
 	if (nic->mac <= mac_82557_D100_C)
 		/* Issue a multicast command to workaround a 557 lock up */
 		e100_set_multicast_list(nic->netdev);
 
-	if (nic->flags & ich && cmd.speed==SPEED_10 && cmd.duplex==DUPLEX_HALF)
+	if (nic->flags & ich && speed == SPEED_10 && cmd.duplex == DUPLEX_HALF)
 		/* Need SW workaround for ICH[x] 10Mbps/half duplex Tx hang. */
 		nic->flags |= ich_10h_workaround;
 	else
@@ -2350,30 +2350,6 @@
 #define E100_82552_LED_OVERRIDE 0x19
 #define E100_82552_LED_ON       0x000F /* LEDTX and LED_RX both on */
 #define E100_82552_LED_OFF      0x000A /* LEDTX and LED_RX both off */
-static void e100_blink_led(unsigned long data)
-{
-	struct nic *nic = (struct nic *)data;
-	enum led_state {
-		led_on     = 0x01,
-		led_off    = 0x04,
-		led_on_559 = 0x05,
-		led_on_557 = 0x07,
-	};
-	u16 led_reg = MII_LED_CONTROL;
-
-	if (nic->phy == phy_82552_v) {
-		led_reg = E100_82552_LED_OVERRIDE;
-
-		nic->leds = (nic->leds == E100_82552_LED_ON) ?
-		            E100_82552_LED_OFF : E100_82552_LED_ON;
-	} else {
-		nic->leds = (nic->leds & led_on) ? led_off :
-		            (nic->mac < mac_82559_D101M) ? led_on_557 :
-		            led_on_559;
-	}
-	mdio_write(nic->netdev, nic->mii.phy_id, led_reg, nic->leds);
-	mod_timer(&nic->blink_timer, jiffies + HZ / 4);
-}
 
 static int e100_get_settings(struct net_device *netdev, struct ethtool_cmd *cmd)
 {
@@ -2597,19 +2573,38 @@
 	msleep_interruptible(4 * 1000);
 }
 
-static int e100_phys_id(struct net_device *netdev, u32 data)
+static int e100_set_phys_id(struct net_device *netdev,
+			    enum ethtool_phys_id_state state)
 {
 	struct nic *nic = netdev_priv(netdev);
+	enum led_state {
+		led_on     = 0x01,
+		led_off    = 0x04,
+		led_on_559 = 0x05,
+		led_on_557 = 0x07,
+	};
 	u16 led_reg = (nic->phy == phy_82552_v) ? E100_82552_LED_OVERRIDE :
-	              MII_LED_CONTROL;
+		MII_LED_CONTROL;
+	u16 leds = 0;
 
-	if (!data || data > (u32)(MAX_SCHEDULE_TIMEOUT / HZ))
-		data = (u32)(MAX_SCHEDULE_TIMEOUT / HZ);
-	mod_timer(&nic->blink_timer, jiffies);
-	msleep_interruptible(data * 1000);
-	del_timer_sync(&nic->blink_timer);
-	mdio_write(netdev, nic->mii.phy_id, led_reg, 0);
+	switch (state) {
+	case ETHTOOL_ID_ACTIVE:
+		return 2;
 
+	case ETHTOOL_ID_ON:
+		leds = (nic->phy == phy_82552_v) ? E100_82552_LED_ON :
+		       (nic->mac < mac_82559_D101M) ? led_on_557 : led_on_559;
+		break;
+
+	case ETHTOOL_ID_OFF:
+		leds = (nic->phy == phy_82552_v) ? E100_82552_LED_OFF : led_off;
+		break;
+
+	case ETHTOOL_ID_INACTIVE:
+		break;
+	}
+
+	mdio_write(netdev, nic->mii.phy_id, led_reg, leds);
 	return 0;
 }
 
@@ -2690,7 +2685,7 @@
 	.set_ringparam		= e100_set_ringparam,
 	.self_test		= e100_diag_test,
 	.get_strings		= e100_get_strings,
-	.phys_id		= e100_phys_id,
+	.set_phys_id		= e100_set_phys_id,
 	.get_ethtool_stats	= e100_get_ethtool_stats,
 	.get_sset_count		= e100_get_sset_count,
 };
@@ -2831,9 +2826,6 @@
 	init_timer(&nic->watchdog);
 	nic->watchdog.function = e100_watchdog;
 	nic->watchdog.data = (unsigned long)nic;
-	init_timer(&nic->blink_timer);
-	nic->blink_timer.function = e100_blink_led;
-	nic->blink_timer.data = (unsigned long)nic;
 
 	INIT_WORK(&nic->tx_timeout_task, e100_tx_timeout_task);
 
diff -druN linux-2.6.39-libre/drivers/net/eepro.c linux-3.0-rc7-libre/drivers/net/eepro.c
--- linux-2.6.39-libre/drivers/net/eepro.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/eepro.c	2011-07-11 19:51:52.000000000 -0400
@@ -1703,7 +1703,7 @@
 		cmd->advertising |= ADVERTISED_AUI;
 	}
 
-	cmd->speed = SPEED_10;
+	ethtool_cmd_speed_set(cmd, SPEED_10);
 
 	if (dev->if_port == TPE && lp->word[1] & ee_Duplex) {
 		cmd->duplex = DUPLEX_FULL;
diff -druN linux-2.6.39-libre/drivers/net/ehea/ehea_ethtool.c linux-3.0-rc7-libre/drivers/net/ehea/ehea_ethtool.c
--- linux-2.6.39-libre/drivers/net/ehea/ehea_ethtool.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/ehea/ehea_ethtool.c	2011-07-11 19:51:52.000000000 -0400
@@ -34,6 +34,7 @@
 static int ehea_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
 {
 	struct ehea_port *port = netdev_priv(dev);
+	u32 speed;
 	int ret;
 
 	ret = ehea_sense_port_attr(port);
@@ -43,17 +44,29 @@
 
 	if (netif_carrier_ok(dev)) {
 		switch (port->port_speed) {
-		case EHEA_SPEED_10M: cmd->speed = SPEED_10; break;
-		case EHEA_SPEED_100M: cmd->speed = SPEED_100; break;
-		case EHEA_SPEED_1G: cmd->speed = SPEED_1000; break;
-		case EHEA_SPEED_10G: cmd->speed = SPEED_10000; break;
+		case EHEA_SPEED_10M:
+			speed = SPEED_10;
+			break;
+		case EHEA_SPEED_100M:
+			speed = SPEED_100;
+			break;
+		case EHEA_SPEED_1G:
+			speed = SPEED_1000;
+			break;
+		case EHEA_SPEED_10G:
+			speed = SPEED_10000;
+			break;
+		default:
+			speed = -1;
+			break; /* BUG */
 		}
 		cmd->duplex = port->full_duplex == 1 ?
 						     DUPLEX_FULL : DUPLEX_HALF;
 	} else {
-		cmd->speed = -1;
+		speed = ~0;
 		cmd->duplex = -1;
 	}
+	ethtool_cmd_speed_set(cmd, speed);
 
 	if (cmd->speed == SPEED_10000) {
 		cmd->supported = (SUPPORTED_10000baseT_Full | SUPPORTED_FIBRE);
@@ -167,11 +180,6 @@
 	port->msg_enable = value;
 }
 
-static u32 ehea_get_rx_csum(struct net_device *dev)
-{
-	return 1;
-}
-
 static char ehea_ethtool_stats_keys[][ETH_GSTRING_LEN] = {
 	{"sig_comp_iv"},
 	{"swqe_refill_th"},
@@ -268,34 +276,16 @@
 
 }
 
-static int ehea_set_flags(struct net_device *dev, u32 data)
-{
-	/* Avoid changing the VLAN flags */
-	if ((data & (ETH_FLAG_RXVLAN | ETH_FLAG_TXVLAN)) !=
-	    (ethtool_op_get_flags(dev) & (ETH_FLAG_RXVLAN |
-					  ETH_FLAG_TXVLAN))){
-		return -EINVAL;
-	}
-
-	return ethtool_op_set_flags(dev, data, ETH_FLAG_LRO
-					| ETH_FLAG_TXVLAN
-					| ETH_FLAG_RXVLAN);
-}
-
 const struct ethtool_ops ehea_ethtool_ops = {
 	.get_settings = ehea_get_settings,
 	.get_drvinfo = ehea_get_drvinfo,
 	.get_msglevel = ehea_get_msglevel,
 	.set_msglevel = ehea_set_msglevel,
 	.get_link = ethtool_op_get_link,
-	.set_tso = ethtool_op_set_tso,
 	.get_strings = ehea_get_strings,
 	.get_sset_count = ehea_get_sset_count,
 	.get_ethtool_stats = ehea_get_ethtool_stats,
-	.get_rx_csum = ehea_get_rx_csum,
 	.set_settings = ehea_set_settings,
-	.get_flags = ethtool_op_get_flags,
-	.set_flags = ehea_set_flags,
 	.nway_reset = ehea_nway_reset,		/* Restart autonegotiation */
 };
 
diff -druN linux-2.6.39-libre/drivers/net/ehea/ehea_main.c linux-3.0-rc7-libre/drivers/net/ehea/ehea_main.c
--- linux-2.6.39-libre/drivers/net/ehea/ehea_main.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/ehea/ehea_main.c	2011-07-11 19:51:52.000000000 -0400
@@ -41,6 +41,7 @@
 #include <linux/memory.h>
 #include <asm/kexec.h>
 #include <linux/mutex.h>
+#include <linux/prefetch.h>
 
 #include <net/ip.h>
 
@@ -2082,7 +2083,7 @@
 	struct netdev_hw_addr *ha;
 	int ret;
 
-	if (dev->flags & IFF_PROMISC) {
+	if (port->promisc) {
 		ehea_promiscuous(dev, 1);
 		return;
 	}
@@ -3262,10 +3263,12 @@
 	dev->netdev_ops = &ehea_netdev_ops;
 	ehea_set_ethtool_ops(dev);
 
+	dev->hw_features = NETIF_F_SG | NETIF_F_FRAGLIST | NETIF_F_TSO
+		      | NETIF_F_IP_CSUM | NETIF_F_HW_VLAN_TX | NETIF_F_LRO;
 	dev->features = NETIF_F_SG | NETIF_F_FRAGLIST | NETIF_F_TSO
 		      | NETIF_F_HIGHDMA | NETIF_F_IP_CSUM | NETIF_F_HW_VLAN_TX
 		      | NETIF_F_HW_VLAN_RX | NETIF_F_HW_VLAN_FILTER
-		      | NETIF_F_LLTX;
+		      | NETIF_F_LLTX | NETIF_F_RXCSUM;
 	dev->watchdog_timeo = EHEA_WATCH_DOG_TIMEOUT;
 
 	if (use_lro)
diff -druN linux-2.6.39-libre/drivers/net/ehea/ehea_qmr.h linux-3.0-rc7-libre/drivers/net/ehea/ehea_qmr.h
--- linux-2.6.39-libre/drivers/net/ehea/ehea_qmr.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/ehea/ehea_qmr.h	2011-07-11 19:51:52.000000000 -0400
@@ -29,6 +29,7 @@
 #ifndef __EHEA_QMR_H__
 #define __EHEA_QMR_H__
 
+#include <linux/prefetch.h>
 #include "ehea.h"
 #include "ehea_hw.h"
 
diff -druN linux-2.6.39-libre/drivers/net/enc28j60.c linux-3.0-rc7-libre/drivers/net/enc28j60.c
--- linux-2.6.39-libre/drivers/net/enc28j60.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/enc28j60.c	2011-07-11 19:51:52.000000000 -0400
@@ -1488,7 +1488,7 @@
 	cmd->supported	= SUPPORTED_10baseT_Half
 			| SUPPORTED_10baseT_Full
 			| SUPPORTED_TP;
-	cmd->speed	= SPEED_10;
+	ethtool_cmd_speed_set(cmd,  SPEED_10);
 	cmd->duplex	= priv->full_duplex ? DUPLEX_FULL : DUPLEX_HALF;
 	cmd->port	= PORT_TP;
 	cmd->autoneg	= AUTONEG_DISABLE;
@@ -1499,7 +1499,8 @@
 static int
 enc28j60_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
 {
-	return enc28j60_setlink(dev, cmd->autoneg, cmd->speed, cmd->duplex);
+	return enc28j60_setlink(dev, cmd->autoneg,
+				ethtool_cmd_speed(cmd), cmd->duplex);
 }
 
 static u32 enc28j60_get_msglevel(struct net_device *dev)
diff -druN linux-2.6.39-libre/drivers/net/enic/enic_dev.c linux-3.0-rc7-libre/drivers/net/enic/enic_dev.c
--- linux-2.6.39-libre/drivers/net/enic/enic_dev.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/enic/enic_dev.c	2011-07-11 19:51:52.000000000 -0400
@@ -177,24 +177,24 @@
 	return err;
 }
 
-int enic_dev_init_prov(struct enic *enic, struct vic_provinfo *vp)
+int enic_dev_init_prov2(struct enic *enic, struct vic_provinfo *vp)
 {
 	int err;
 
 	spin_lock(&enic->devcmd_lock);
-	err = vnic_dev_init_prov(enic->vdev,
+	err = vnic_dev_init_prov2(enic->vdev,
 		(u8 *)vp, vic_provinfo_size(vp));
 	spin_unlock(&enic->devcmd_lock);
 
 	return err;
 }
 
-int enic_dev_init_done(struct enic *enic, int *done, int *error)
+int enic_dev_deinit_done(struct enic *enic, int *status)
 {
 	int err;
 
 	spin_lock(&enic->devcmd_lock);
-	err = vnic_dev_init_done(enic->vdev, done, error);
+	err = vnic_dev_deinit_done(enic->vdev, status);
 	spin_unlock(&enic->devcmd_lock);
 
 	return err;
@@ -219,3 +219,57 @@
 	enic_del_vlan(enic, vid);
 	spin_unlock(&enic->devcmd_lock);
 }
+
+int enic_dev_enable2(struct enic *enic, int active)
+{
+	int err;
+
+	spin_lock(&enic->devcmd_lock);
+	err = vnic_dev_enable2(enic->vdev, active);
+	spin_unlock(&enic->devcmd_lock);
+
+	return err;
+}
+
+int enic_dev_enable2_done(struct enic *enic, int *status)
+{
+	int err;
+
+	spin_lock(&enic->devcmd_lock);
+	err = vnic_dev_enable2_done(enic->vdev, status);
+	spin_unlock(&enic->devcmd_lock);
+
+	return err;
+}
+
+int enic_dev_status_to_errno(int devcmd_status)
+{
+	switch (devcmd_status) {
+	case ERR_SUCCESS:
+		return 0;
+	case ERR_EINVAL:
+		return -EINVAL;
+	case ERR_EFAULT:
+		return -EFAULT;
+	case ERR_EPERM:
+		return -EPERM;
+	case ERR_EBUSY:
+		return -EBUSY;
+	case ERR_ECMDUNKNOWN:
+	case ERR_ENOTSUPPORTED:
+		return -EOPNOTSUPP;
+	case ERR_EBADSTATE:
+		return -EINVAL;
+	case ERR_ENOMEM:
+		return -ENOMEM;
+	case ERR_ETIMEDOUT:
+		return -ETIMEDOUT;
+	case ERR_ELINKDOWN:
+		return -ENETDOWN;
+	case ERR_EINPROGRESS:
+		return -EINPROGRESS;
+	case ERR_EMAXRES:
+	default:
+		return (devcmd_status < 0) ? devcmd_status : -1;
+	}
+}
diff -druN linux-2.6.39-libre/drivers/net/enic/enic_dev.h linux-3.0-rc7-libre/drivers/net/enic/enic_dev.h
--- linux-2.6.39-libre/drivers/net/enic/enic_dev.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/enic/enic_dev.h	2011-07-11 19:51:52.000000000 -0400
@@ -35,7 +35,10 @@
 int enic_dev_enable(struct enic *enic);
 int enic_dev_disable(struct enic *enic);
 int enic_vnic_dev_deinit(struct enic *enic);
-int enic_dev_init_prov(struct enic *enic, struct vic_provinfo *vp);
-int enic_dev_init_done(struct enic *enic, int *done, int *error);
+int enic_dev_init_prov2(struct enic *enic, struct vic_provinfo *vp);
+int enic_dev_deinit_done(struct enic *enic, int *status);
+int enic_dev_enable2(struct enic *enic, int arg);
+int enic_dev_enable2_done(struct enic *enic, int *status);
+int enic_dev_status_to_errno(int devcmd_status);
 
 #endif /* _ENIC_DEV_H_ */
diff -druN linux-2.6.39-libre/drivers/net/enic/enic.h linux-3.0-rc7-libre/drivers/net/enic/enic.h
--- linux-2.6.39-libre/drivers/net/enic/enic.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/enic/enic.h	2011-07-11 19:51:52.000000000 -0400
@@ -32,7 +32,7 @@
 
 #define DRV_NAME		"enic"
 #define DRV_DESCRIPTION		"Cisco VIC Ethernet NIC Driver"
-#define DRV_VERSION		"2.1.1.12"
+#define DRV_VERSION		"2.1.1.13"
 #define DRV_COPYRIGHT		"Copyright 2008-2011 Cisco Systems, Inc"
 
 #define ENIC_BARS_MAX		6
@@ -84,7 +84,6 @@
 	unsigned int flags;
 	unsigned int mc_count;
 	unsigned int uc_count;
-	int csum_rx_enabled;
 	u32 port_mtu;
 	u32 rx_coalesce_usecs;
 	u32 tx_coalesce_usecs;
@@ -120,4 +119,6 @@
 	return &(enic->pdev->dev);
 }
 
+void enic_reset_addr_lists(struct enic *enic);
+
 #endif /* _ENIC_H_ */
diff -druN linux-2.6.39-libre/drivers/net/enic/enic_main.c linux-3.0-rc7-libre/drivers/net/enic/enic_main.c
--- linux-2.6.39-libre/drivers/net/enic/enic_main.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/enic/enic_main.c	2011-07-11 19:51:52.000000000 -0400
@@ -35,6 +35,7 @@
 #include <linux/ipv6.h>
 #include <linux/tcp.h>
 #include <linux/rtnetlink.h>
+#include <linux/prefetch.h>
 #include <net/ip6_checksum.h>
 
 #include "cq_enet_desc.h"
@@ -45,6 +46,7 @@
 #include "enic_res.h"
 #include "enic.h"
 #include "enic_dev.h"
+#include "enic_pp.h"
 
 #define ENIC_NOTIFY_TIMER_PERIOD	(2 * HZ)
 #define WQ_ENET_MAX_DESC_LEN		(1 << WQ_ENET_LEN_BITS)
@@ -179,10 +181,10 @@
 	ecmd->transceiver = XCVR_EXTERNAL;
 
 	if (netif_carrier_ok(netdev)) {
-		ecmd->speed = vnic_dev_port_speed(enic->vdev);
+		ethtool_cmd_speed_set(ecmd, vnic_dev_port_speed(enic->vdev));
 		ecmd->duplex = DUPLEX_FULL;
 	} else {
-		ecmd->speed = -1;
+		ethtool_cmd_speed_set(ecmd, -1);
 		ecmd->duplex = -1;
 	}
 
@@ -250,56 +252,6 @@
 		*(data++) = ((u64 *)&vstats->rx)[enic_rx_stats[i].offset];
 }
 
-static u32 enic_get_rx_csum(struct net_device *netdev)
-{
-	struct enic *enic = netdev_priv(netdev);
-	return enic->csum_rx_enabled;
-}
-
-static int enic_set_rx_csum(struct net_device *netdev, u32 data)
-{
-	struct enic *enic = netdev_priv(netdev);
-
-	if (data && !ENIC_SETTING(enic, RXCSUM))
-		return -EINVAL;
-
-	enic->csum_rx_enabled = !!data;
-
-	return 0;
-}
-
-static int enic_set_tx_csum(struct net_device *netdev, u32 data)
-{
-	struct enic *enic = netdev_priv(netdev);
-
-	if (data && !ENIC_SETTING(enic, TXCSUM))
-		return -EINVAL;
-
-	if (data)
-		netdev->features |= NETIF_F_HW_CSUM;
-	else
-		netdev->features &= ~NETIF_F_HW_CSUM;
-
-	return 0;
-}
-
-static int enic_set_tso(struct net_device *netdev, u32 data)
-{
-	struct enic *enic = netdev_priv(netdev);
-
-	if (data && !ENIC_SETTING(enic, TSO))
-		return -EINVAL;
-
-	if (data)
-		netdev->features |=
-			NETIF_F_TSO | NETIF_F_TSO6 | NETIF_F_TSO_ECN;
-	else
-		netdev->features &=
-			~(NETIF_F_TSO | NETIF_F_TSO6 | NETIF_F_TSO_ECN);
-
-	return 0;
-}
-
 static u32 enic_get_msglevel(struct net_device *netdev)
 {
 	struct enic *enic = netdev_priv(netdev);
@@ -387,17 +339,8 @@
 	.get_strings = enic_get_strings,
 	.get_sset_count = enic_get_sset_count,
 	.get_ethtool_stats = enic_get_ethtool_stats,
-	.get_rx_csum = enic_get_rx_csum,
-	.set_rx_csum = enic_set_rx_csum,
-	.get_tx_csum = ethtool_op_get_tx_csum,
-	.set_tx_csum = enic_set_tx_csum,
-	.get_sg = ethtool_op_get_sg,
-	.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,
 };
 
 static void enic_free_wq_buf(struct vnic_wq *wq, struct vnic_wq_buf *buf)
@@ -874,7 +817,7 @@
 	return net_stats;
 }
 
-static void enic_reset_addr_lists(struct enic *enic)
+void enic_reset_addr_lists(struct enic *enic)
 {
 	enic->mc_count = 0;
 	enic->uc_count = 0;
@@ -1112,157 +1055,77 @@
 		return -EINVAL;
 }
 
-static int enic_set_port_profile(struct enic *enic, u8 *mac)
-{
-	struct vic_provinfo *vp;
-	u8 oui[3] = VIC_PROVINFO_CISCO_OUI;
-	u16 os_type = VIC_GENERIC_PROV_OS_TYPE_LINUX;
-	char uuid_str[38];
-	char client_mac_str[18];
-	u8 *client_mac;
-	int err;
-
-	err = enic_vnic_dev_deinit(enic);
-	if (err)
-		return err;
-
-	enic_reset_addr_lists(enic);
-
-	switch (enic->pp.request) {
-
-	case PORT_REQUEST_ASSOCIATE:
-
-		if (!(enic->pp.set & ENIC_SET_NAME) || !strlen(enic->pp.name))
-			return -EINVAL;
-
-		if (!is_valid_ether_addr(mac))
-			return -EADDRNOTAVAIL;
-
-		vp = vic_provinfo_alloc(GFP_KERNEL, oui,
-			VIC_PROVINFO_GENERIC_TYPE);
-		if (!vp)
-			return -ENOMEM;
-
-		vic_provinfo_add_tlv(vp,
-			VIC_GENERIC_PROV_TLV_PORT_PROFILE_NAME_STR,
-			strlen(enic->pp.name) + 1, enic->pp.name);
-
-		if (!is_zero_ether_addr(enic->pp.mac_addr))
-			client_mac = enic->pp.mac_addr;
-		else
-			client_mac = mac;
-
-		vic_provinfo_add_tlv(vp,
-			VIC_GENERIC_PROV_TLV_CLIENT_MAC_ADDR,
-			ETH_ALEN, client_mac);
-
-		sprintf(client_mac_str, "%pM", client_mac);
-		vic_provinfo_add_tlv(vp,
-			VIC_GENERIC_PROV_TLV_CLUSTER_PORT_UUID_STR,
-			sizeof(client_mac_str), client_mac_str);
-
-		if (enic->pp.set & ENIC_SET_INSTANCE) {
-			sprintf(uuid_str, "%pUB", enic->pp.instance_uuid);
-			vic_provinfo_add_tlv(vp,
-				VIC_GENERIC_PROV_TLV_CLIENT_UUID_STR,
-				sizeof(uuid_str), uuid_str);
-		}
-
-		if (enic->pp.set & ENIC_SET_HOST) {
-			sprintf(uuid_str, "%pUB", enic->pp.host_uuid);
-			vic_provinfo_add_tlv(vp,
-				VIC_GENERIC_PROV_TLV_HOST_UUID_STR,
-				sizeof(uuid_str), uuid_str);
-		}
-
-		os_type = htons(os_type);
-		vic_provinfo_add_tlv(vp,
-			VIC_GENERIC_PROV_TLV_OS_TYPE,
-			sizeof(os_type), &os_type);
-
-		err = enic_dev_init_prov(enic, vp);
-		vic_provinfo_free(vp);
-		if (err)
-			return err;
-		break;
-
-	case PORT_REQUEST_DISASSOCIATE:
-		break;
-
-	default:
-		return -EINVAL;
-	}
-
-	/* Set flag to indicate that the port assoc/disassoc
-	 * request has been sent out to fw
-	 */
-	enic->pp.set |= ENIC_PORT_REQUEST_APPLIED;
-
-	return 0;
-}
-
 static int enic_set_vf_port(struct net_device *netdev, int vf,
 	struct nlattr *port[])
 {
 	struct enic *enic = netdev_priv(netdev);
-	struct enic_port_profile new_pp;
-	int err = 0;
+	struct enic_port_profile prev_pp;
+	int err = 0, restore_pp = 1;
 
-	memset(&new_pp, 0, sizeof(new_pp));
+	/* don't support VFs, yet */
+	if (vf != PORT_SELF_VF)
+		return -EOPNOTSUPP;
 
-	if (port[IFLA_PORT_REQUEST]) {
-		new_pp.set |= ENIC_SET_REQUEST;
-		new_pp.request = nla_get_u8(port[IFLA_PORT_REQUEST]);
-	}
+	if (!port[IFLA_PORT_REQUEST])
+		return -EOPNOTSUPP;
+
+	memcpy(&prev_pp, &enic->pp, sizeof(enic->pp));
+	memset(&enic->pp, 0, sizeof(enic->pp));
+
+	enic->pp.set |= ENIC_SET_REQUEST;
+	enic->pp.request = nla_get_u8(port[IFLA_PORT_REQUEST]);
 
 	if (port[IFLA_PORT_PROFILE]) {
-		new_pp.set |= ENIC_SET_NAME;
-		memcpy(new_pp.name, nla_data(port[IFLA_PORT_PROFILE]),
+		enic->pp.set |= ENIC_SET_NAME;
+		memcpy(enic->pp.name, nla_data(port[IFLA_PORT_PROFILE]),
 			PORT_PROFILE_MAX);
 	}
 
 	if (port[IFLA_PORT_INSTANCE_UUID]) {
-		new_pp.set |= ENIC_SET_INSTANCE;
-		memcpy(new_pp.instance_uuid,
+		enic->pp.set |= ENIC_SET_INSTANCE;
+		memcpy(enic->pp.instance_uuid,
 			nla_data(port[IFLA_PORT_INSTANCE_UUID]), PORT_UUID_MAX);
 	}
 
 	if (port[IFLA_PORT_HOST_UUID]) {
-		new_pp.set |= ENIC_SET_HOST;
-		memcpy(new_pp.host_uuid,
+		enic->pp.set |= ENIC_SET_HOST;
+		memcpy(enic->pp.host_uuid,
 			nla_data(port[IFLA_PORT_HOST_UUID]), PORT_UUID_MAX);
 	}
 
-	/* don't support VFs, yet */
-	if (vf != PORT_SELF_VF)
-		return -EOPNOTSUPP;
-
-	if (!(new_pp.set & ENIC_SET_REQUEST))
-		return -EOPNOTSUPP;
-
-	if (new_pp.request == PORT_REQUEST_ASSOCIATE) {
-		/* Special case handling */
-		if (!is_zero_ether_addr(enic->pp.vf_mac))
-			memcpy(new_pp.mac_addr, enic->pp.vf_mac, ETH_ALEN);
+	/* Special case handling: mac came from IFLA_VF_MAC */
+	if (!is_zero_ether_addr(prev_pp.vf_mac))
+		memcpy(enic->pp.mac_addr, prev_pp.vf_mac, ETH_ALEN);
 
 		if (is_zero_ether_addr(netdev->dev_addr))
 			random_ether_addr(netdev->dev_addr);
-	}
 
-	memcpy(&enic->pp, &new_pp, sizeof(struct enic_port_profile));
+	err = enic_process_set_pp_request(enic, &prev_pp, &restore_pp);
+	if (err) {
+		if (restore_pp) {
+			/* Things are still the way they were: Implicit
+			 * DISASSOCIATE failed
+			 */
+			memcpy(&enic->pp, &prev_pp, sizeof(enic->pp));
+		} else {
+			memset(&enic->pp, 0, sizeof(enic->pp));
+			memset(netdev->dev_addr, 0, ETH_ALEN);
+		}
+	} else {
+		/* Set flag to indicate that the port assoc/disassoc
+		 * request has been sent out to fw
+		 */
+		enic->pp.set |= ENIC_PORT_REQUEST_APPLIED;
 
-	err = enic_set_port_profile(enic, netdev->dev_addr);
-	if (err)
-		goto set_port_profile_cleanup;
+		/* If DISASSOCIATE, clean up all assigned/saved macaddresses */
+		if (enic->pp.request == PORT_REQUEST_DISASSOCIATE) {
+			memset(enic->pp.mac_addr, 0, ETH_ALEN);
+			memset(netdev->dev_addr, 0, ETH_ALEN);
+		}
+	}
 
-set_port_profile_cleanup:
 	memset(enic->pp.vf_mac, 0, ETH_ALEN);
 
-	if (err || enic->pp.request == PORT_REQUEST_DISASSOCIATE) {
-		memset(netdev->dev_addr, 0, ETH_ALEN);
-		memset(enic->pp.mac_addr, 0, ETH_ALEN);
-	}
-
 	return err;
 }
 
@@ -1270,34 +1133,15 @@
 	struct sk_buff *skb)
 {
 	struct enic *enic = netdev_priv(netdev);
-	int err, error, done;
 	u16 response = PORT_PROFILE_RESPONSE_SUCCESS;
+	int err;
 
 	if (!(enic->pp.set & ENIC_PORT_REQUEST_APPLIED))
 		return -ENODATA;
 
-	err = enic_dev_init_done(enic, &done, &error);
+	err = enic_process_get_pp_request(enic, enic->pp.request, &response);
 	if (err)
-		error = err;
-
-	switch (error) {
-	case ERR_SUCCESS:
-		if (!done)
-			response = PORT_PROFILE_RESPONSE_INPROGRESS;
-		break;
-	case ERR_EINVAL:
-		response = PORT_PROFILE_RESPONSE_INVALID;
-		break;
-	case ERR_EBADSTATE:
-		response = PORT_PROFILE_RESPONSE_BADSTATE;
-		break;
-	case ERR_ENOMEM:
-		response = PORT_PROFILE_RESPONSE_INSUFFICIENT_RESOURCES;
-		break;
-	default:
-		response = PORT_PROFILE_RESPONSE_ERROR;
-		break;
-	}
+		return err;
 
 	NLA_PUT_U16(skb, IFLA_PORT_REQUEST, enic->pp.request);
 	NLA_PUT_U16(skb, IFLA_PORT_RESPONSE, response);
@@ -1407,7 +1251,7 @@
 		skb_put(skb, bytes_written);
 		skb->protocol = eth_type_trans(skb, netdev);
 
-		if (enic->csum_rx_enabled && !csum_not_calc) {
+		if ((netdev->features & NETIF_F_RXCSUM) && !csum_not_calc) {
 			skb->csum = htons(checksum);
 			skb->ip_summed = CHECKSUM_COMPLETE;
 		}
@@ -2536,17 +2380,18 @@
 		dev_info(dev, "loopback tag=0x%04x\n", enic->loop_tag);
 	}
 	if (ENIC_SETTING(enic, TXCSUM))
-		netdev->features |= NETIF_F_SG | NETIF_F_HW_CSUM;
+		netdev->hw_features |= NETIF_F_SG | NETIF_F_HW_CSUM;
 	if (ENIC_SETTING(enic, TSO))
-		netdev->features |= NETIF_F_TSO |
+		netdev->hw_features |= NETIF_F_TSO |
 			NETIF_F_TSO6 | NETIF_F_TSO_ECN;
-	if (ENIC_SETTING(enic, LRO))
-		netdev->features |= NETIF_F_GRO;
+	if (ENIC_SETTING(enic, RXCSUM))
+		netdev->hw_features |= NETIF_F_RXCSUM;
+
+	netdev->features |= netdev->hw_features;
+
 	if (using_dac)
 		netdev->features |= NETIF_F_HIGHDMA;
 
-	enic->csum_rx_enabled = ENIC_SETTING(enic, RXCSUM);
-
 	err = register_netdev(netdev);
 	if (err) {
 		dev_err(dev, "Cannot register net device, aborting\n");
diff -druN linux-2.6.39-libre/drivers/net/enic/enic_pp.c linux-3.0-rc7-libre/drivers/net/enic/enic_pp.c
--- linux-2.6.39-libre/drivers/net/enic/enic_pp.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/net/enic/enic_pp.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,264 @@
+/*
+ * Copyright 2011 Cisco Systems, Inc.  All rights reserved.
+ *
+ * This program is free software; you may redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/errno.h>
+#include <linux/types.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/rtnetlink.h>
+#include <net/ip.h>
+
+#include "vnic_vic.h"
+#include "enic_res.h"
+#include "enic.h"
+#include "enic_dev.h"
+
+static int enic_set_port_profile(struct enic *enic)
+{
+	struct net_device *netdev = enic->netdev;
+	struct vic_provinfo *vp;
+	const u8 oui[3] = VIC_PROVINFO_CISCO_OUI;
+	const u16 os_type = htons(VIC_GENERIC_PROV_OS_TYPE_LINUX);
+	char uuid_str[38];
+	char client_mac_str[18];
+	u8 *client_mac;
+	int err;
+
+	if (!(enic->pp.set & ENIC_SET_NAME) || !strlen(enic->pp.name))
+		return -EINVAL;
+
+	vp = vic_provinfo_alloc(GFP_KERNEL, oui,
+		VIC_PROVINFO_GENERIC_TYPE);
+	if (!vp)
+		return -ENOMEM;
+
+	VIC_PROVINFO_ADD_TLV(vp,
+		VIC_GENERIC_PROV_TLV_PORT_PROFILE_NAME_STR,
+		strlen(enic->pp.name) + 1, enic->pp.name);
+
+	if (!is_zero_ether_addr(enic->pp.mac_addr))
+		client_mac = enic->pp.mac_addr;
+	else
+		client_mac = netdev->dev_addr;
+
+	VIC_PROVINFO_ADD_TLV(vp,
+		VIC_GENERIC_PROV_TLV_CLIENT_MAC_ADDR,
+		ETH_ALEN, client_mac);
+
+	snprintf(client_mac_str, sizeof(client_mac_str), "%pM", client_mac);
+	VIC_PROVINFO_ADD_TLV(vp,
+		VIC_GENERIC_PROV_TLV_CLUSTER_PORT_UUID_STR,
+		sizeof(client_mac_str), client_mac_str);
+
+	if (enic->pp.set & ENIC_SET_INSTANCE) {
+		sprintf(uuid_str, "%pUB", enic->pp.instance_uuid);
+		VIC_PROVINFO_ADD_TLV(vp,
+			VIC_GENERIC_PROV_TLV_CLIENT_UUID_STR,
+			sizeof(uuid_str), uuid_str);
+	}
+
+	if (enic->pp.set & ENIC_SET_HOST) {
+		sprintf(uuid_str, "%pUB", enic->pp.host_uuid);
+		VIC_PROVINFO_ADD_TLV(vp,
+			VIC_GENERIC_PROV_TLV_HOST_UUID_STR,
+			sizeof(uuid_str), uuid_str);
+	}
+
+	VIC_PROVINFO_ADD_TLV(vp,
+		VIC_GENERIC_PROV_TLV_OS_TYPE,
+		sizeof(os_type), &os_type);
+
+	err = enic_dev_status_to_errno(enic_dev_init_prov2(enic, vp));
+
+add_tlv_failure:
+	vic_provinfo_free(vp);
+
+	return err;
+}
+
+static int enic_unset_port_profile(struct enic *enic)
+{
+	int err;
+
+	err = enic_vnic_dev_deinit(enic);
+	if (err)
+		return enic_dev_status_to_errno(err);
+
+	enic_reset_addr_lists(enic);
+
+	return 0;
+}
+
+static int enic_are_pp_different(struct enic_port_profile *pp1,
+		struct enic_port_profile *pp2)
+{
+	return strcmp(pp1->name, pp2->name) | !!memcmp(pp1->instance_uuid,
+		pp2->instance_uuid, PORT_UUID_MAX) |
+		!!memcmp(pp1->host_uuid, pp2->host_uuid, PORT_UUID_MAX) |
+		!!memcmp(pp1->mac_addr, pp2->mac_addr, ETH_ALEN);
+}
+
+static int enic_pp_preassociate(struct enic *enic,
+	struct enic_port_profile *prev_pp, int *restore_pp);
+static int enic_pp_disassociate(struct enic *enic,
+	struct enic_port_profile *prev_pp, int *restore_pp);
+static int enic_pp_preassociate_rr(struct enic *enic,
+	struct enic_port_profile *prev_pp, int *restore_pp);
+static int enic_pp_associate(struct enic *enic,
+	struct enic_port_profile *prev_pp, int *restore_pp);
+
+static int (*enic_pp_handlers[])(struct enic *enic,
+		struct enic_port_profile *prev_state, int *restore_pp) = {
+	[PORT_REQUEST_PREASSOCIATE]	= enic_pp_preassociate,
+	[PORT_REQUEST_PREASSOCIATE_RR]	= enic_pp_preassociate_rr,
+	[PORT_REQUEST_ASSOCIATE]	= enic_pp_associate,
+	[PORT_REQUEST_DISASSOCIATE]	= enic_pp_disassociate,
+};
+
+static const int enic_pp_handlers_count =
+			sizeof(enic_pp_handlers)/sizeof(*enic_pp_handlers);
+
+static int enic_pp_preassociate(struct enic *enic,
+	struct enic_port_profile *prev_pp, int *restore_pp)
+{
+	return -EOPNOTSUPP;
+}
+
+static int enic_pp_disassociate(struct enic *enic,
+	struct enic_port_profile *prev_pp, int *restore_pp)
+{
+	return enic_unset_port_profile(enic);
+}
+
+static int enic_pp_preassociate_rr(struct enic *enic,
+	struct enic_port_profile *prev_pp, int *restore_pp)
+{
+	int err;
+	int active = 0;
+
+	if (enic->pp.request != PORT_REQUEST_ASSOCIATE) {
+		/* If pre-associate is not part of an associate.
+		We always disassociate first */
+		err = enic_pp_handlers[PORT_REQUEST_DISASSOCIATE](enic,
+			prev_pp, restore_pp);
+		if (err)
+			return err;
+
+		*restore_pp = 0;
+	}
+
+	*restore_pp = 0;
+
+	err = enic_set_port_profile(enic);
+	if (err)
+		return err;
+
+	/* If pre-associate is not part of an associate. */
+	if (enic->pp.request != PORT_REQUEST_ASSOCIATE)
+		err = enic_dev_status_to_errno(enic_dev_enable2(enic, active));
+
+	return err;
+}
+
+static int enic_pp_associate(struct enic *enic,
+	struct enic_port_profile *prev_pp, int *restore_pp)
+{
+	int err;
+	int active = 1;
+
+	/* Check if a pre-associate was called before */
+	if (prev_pp->request != PORT_REQUEST_PREASSOCIATE_RR ||
+		(prev_pp->request == PORT_REQUEST_PREASSOCIATE_RR &&
+			enic_are_pp_different(prev_pp, &enic->pp))) {
+		err = enic_pp_handlers[PORT_REQUEST_DISASSOCIATE](
+			enic, prev_pp, restore_pp);
+		if (err)
+			return err;
+
+		*restore_pp = 0;
+	}
+
+	err = enic_pp_handlers[PORT_REQUEST_PREASSOCIATE_RR](
+			enic, prev_pp, restore_pp);
+	if (err)
+		return err;
+
+	*restore_pp = 0;
+
+	return enic_dev_status_to_errno(enic_dev_enable2(enic, active));
+}
+
+int enic_process_set_pp_request(struct enic *enic,
+	struct enic_port_profile *prev_pp, int *restore_pp)
+{
+	if (enic->pp.request < enic_pp_handlers_count
+		&& enic_pp_handlers[enic->pp.request])
+		return enic_pp_handlers[enic->pp.request](enic,
+			prev_pp, restore_pp);
+	else
+		return -EOPNOTSUPP;
+}
+
+int enic_process_get_pp_request(struct enic *enic, int request,
+	u16 *response)
+{
+	int err, status = ERR_SUCCESS;
+
+	switch (request) {
+
+	case PORT_REQUEST_PREASSOCIATE_RR:
+	case PORT_REQUEST_ASSOCIATE:
+		err = enic_dev_enable2_done(enic, &status);
+		break;
+
+	case PORT_REQUEST_DISASSOCIATE:
+		err = enic_dev_deinit_done(enic, &status);
+		break;
+
+	default:
+		return -EINVAL;
+	}
+
+	if (err)
+		status = err;
+
+	switch (status) {
+	case ERR_SUCCESS:
+		*response = PORT_PROFILE_RESPONSE_SUCCESS;
+		break;
+	case ERR_EINVAL:
+		*response = PORT_PROFILE_RESPONSE_INVALID;
+		break;
+	case ERR_EBADSTATE:
+		*response = PORT_PROFILE_RESPONSE_BADSTATE;
+		break;
+	case ERR_ENOMEM:
+		*response = PORT_PROFILE_RESPONSE_INSUFFICIENT_RESOURCES;
+		break;
+	case ERR_EINPROGRESS:
+		*response = PORT_PROFILE_RESPONSE_INPROGRESS;
+		break;
+	default:
+		*response = PORT_PROFILE_RESPONSE_ERROR;
+		break;
+	}
+
+	return 0;
+}
diff -druN linux-2.6.39-libre/drivers/net/enic/enic_pp.h linux-3.0-rc7-libre/drivers/net/enic/enic_pp.h
--- linux-2.6.39-libre/drivers/net/enic/enic_pp.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/net/enic/enic_pp.h	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2011 Cisco Systems, Inc.  All rights reserved.
+ *
+ * This program is free software; you may redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", 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 _ENIC_PP_H_
+#define _ENIC_PP_H_
+
+int enic_process_set_pp_request(struct enic *enic,
+	struct enic_port_profile *prev_pp, int *restore_pp);
+int enic_process_get_pp_request(struct enic *enic, int request,
+	u16 *response);
+
+#endif /* _ENIC_PP_H_ */
diff -druN linux-2.6.39-libre/drivers/net/enic/enic_res.c linux-3.0-rc7-libre/drivers/net/enic/enic_res.c
--- linux-2.6.39-libre/drivers/net/enic/enic_res.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/enic/enic_res.c	2011-07-11 19:51:52.000000000 -0400
@@ -98,9 +98,9 @@
 		"vNIC MAC addr %pM wq/rq %d/%d mtu %d\n",
 		enic->mac_addr, c->wq_desc_count, c->rq_desc_count, c->mtu);
 	dev_info(enic_get_dev(enic), "vNIC csum tx/rx %d/%d "
-		"tso/lro %d/%d intr timer %d usec rss %d\n",
+		"tso %d intr timer %d usec rss %d\n",
 		ENIC_SETTING(enic, TXCSUM), ENIC_SETTING(enic, RXCSUM),
-		ENIC_SETTING(enic, TSO), ENIC_SETTING(enic, LRO),
+		ENIC_SETTING(enic, TSO),
 		c->intr_timer_usec, ENIC_SETTING(enic, RSS));
 
 	return 0;
diff -druN linux-2.6.39-libre/drivers/net/enic/Makefile linux-3.0-rc7-libre/drivers/net/enic/Makefile
--- linux-2.6.39-libre/drivers/net/enic/Makefile	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/enic/Makefile	2011-07-11 19:51:52.000000000 -0400
@@ -1,5 +1,5 @@
 obj-$(CONFIG_ENIC) := enic.o
 
 enic-y := enic_main.o vnic_cq.o vnic_intr.o vnic_wq.o \
-	enic_res.o enic_dev.o vnic_dev.o vnic_rq.o vnic_vic.o
+	enic_res.o enic_dev.o enic_pp.o vnic_dev.o vnic_rq.o vnic_vic.o
 
diff -druN linux-2.6.39-libre/drivers/net/enic/vnic_dev.c linux-3.0-rc7-libre/drivers/net/enic/vnic_dev.c
--- linux-2.6.39-libre/drivers/net/enic/vnic_dev.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/enic/vnic_dev.c	2011-07-11 19:51:52.000000000 -0400
@@ -786,48 +786,6 @@
 	return r;
 }
 
-int vnic_dev_init_done(struct vnic_dev *vdev, int *done, int *err)
-{
-	u64 a0 = 0, a1 = 0;
-	int wait = 1000;
-	int ret;
-
-	*done = 0;
-
-	ret = vnic_dev_cmd(vdev, CMD_INIT_STATUS, &a0, &a1, wait);
-	if (ret)
-		return ret;
-
-	*done = (a0 == 0);
-
-	*err = (a0 == 0) ? (int)a1:0;
-
-	return 0;
-}
-
-int vnic_dev_init_prov(struct vnic_dev *vdev, u8 *buf, u32 len)
-{
-	u64 a0, a1 = len;
-	int wait = 1000;
-	dma_addr_t prov_pa;
-	void *prov_buf;
-	int ret;
-
-	prov_buf = pci_alloc_consistent(vdev->pdev, len, &prov_pa);
-	if (!prov_buf)
-		return -ENOMEM;
-
-	memcpy(prov_buf, buf, len);
-
-	a0 = prov_pa;
-
-	ret = vnic_dev_cmd(vdev, CMD_INIT_PROV_INFO, &a0, &a1, wait);
-
-	pci_free_consistent(vdev->pdev, len, prov_buf, prov_pa);
-
-	return ret;
-}
-
 int vnic_dev_deinit(struct vnic_dev *vdev)
 {
 	u64 a0 = 0, a1 = 0;
@@ -927,4 +885,59 @@
 	return NULL;
 }
 
+int vnic_dev_init_prov2(struct vnic_dev *vdev, u8 *buf, u32 len)
+{
+	u64 a0, a1 = len;
+	int wait = 1000;
+	dma_addr_t prov_pa;
+	void *prov_buf;
+	int ret;
 
+	prov_buf = pci_alloc_consistent(vdev->pdev, len, &prov_pa);
+	if (!prov_buf)
+		return -ENOMEM;
+
+	memcpy(prov_buf, buf, len);
+
+	a0 = prov_pa;
+
+	ret = vnic_dev_cmd(vdev, CMD_INIT_PROV_INFO2, &a0, &a1, wait);
+
+	pci_free_consistent(vdev->pdev, len, prov_buf, prov_pa);
+
+	return ret;
+}
+
+int vnic_dev_enable2(struct vnic_dev *vdev, int active)
+{
+	u64 a0, a1 = 0;
+	int wait = 1000;
+
+	a0 = (active ? CMD_ENABLE2_ACTIVE : 0);
+
+	return vnic_dev_cmd(vdev, CMD_ENABLE2, &a0, &a1, wait);
+}
+
+static int vnic_dev_cmd_status(struct vnic_dev *vdev, enum vnic_devcmd_cmd cmd,
+	int *status)
+{
+	u64 a0 = cmd, a1 = 0;
+	int wait = 1000;
+	int ret;
+
+	ret = vnic_dev_cmd(vdev, CMD_STATUS, &a0, &a1, wait);
+	if (!ret)
+		*status = (int)a0;
+
+	return ret;
+}
+
+int vnic_dev_enable2_done(struct vnic_dev *vdev, int *status)
+{
+	return vnic_dev_cmd_status(vdev, CMD_ENABLE2, status);
+}
+
+int vnic_dev_deinit_done(struct vnic_dev *vdev, int *status)
+{
+	return vnic_dev_cmd_status(vdev, CMD_DEINIT, status);
+}
diff -druN linux-2.6.39-libre/drivers/net/enic/vnic_devcmd.h linux-3.0-rc7-libre/drivers/net/enic/vnic_devcmd.h
--- linux-2.6.39-libre/drivers/net/enic/vnic_devcmd.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/enic/vnic_devcmd.h	2011-07-11 19:51:52.000000000 -0400
@@ -267,17 +267,62 @@
 
 	/*
 	 * As for BY_BDF except a0 is index of hvnlink subordinate vnic
-	 * or SR-IOV virtual vnic */
+	 * or SR-IOV virtual vnic
+	 */
 	CMD_PROXY_BY_INDEX =    _CMDC(_CMD_DIR_RW, _CMD_VTYPE_ALL, 43),
 
 	/*
-	 * in:  (u64)a0=paddr of buffer to put latest VIC VIF-CONFIG-INFO TLV in
-	 *      (u32)a1=length of buffer in a0
-	 * out: (u64)a0=paddr of buffer with latest VIC VIF-CONFIG-INFO TLV
-	 *      (u32)a1=actual length of latest VIC VIF-CONFIG-INFO TLV */
+	 * For HPP toggle:
+	 * adapter-info-get
+	 * in:  (u64)a0=phsical address of buffer passed in from caller.
+	 *      (u16)a1=size of buffer specified in a0.
+	 * out: (u64)a0=phsical address of buffer passed in from caller.
+	 *      (u16)a1=actual bytes from VIF-CONFIG-INFO TLV, or
+	 *              0 if no VIF-CONFIG-INFO TLV was ever received. */
 	CMD_CONFIG_INFO_GET     = _CMDC(_CMD_DIR_RW, _CMD_VTYPE_ALL, 44),
+
+	/* init_prov_info2:
+	 * Variant of CMD_INIT_PROV_INFO, where it will not try to enable
+	 * the vnic until CMD_ENABLE2 is issued.
+	 *     (u64)a0=paddr of vnic_devcmd_provinfo
+	 *     (u32)a1=sizeof provision info */
+	CMD_INIT_PROV_INFO2  = _CMDC(_CMD_DIR_WRITE, _CMD_VTYPE_ENET, 47),
+
+	/* enable2:
+	 *      (u32)a0=0                  ==> standby
+	 *             =CMD_ENABLE2_ACTIVE ==> active
+	 */
+	CMD_ENABLE2 = _CMDC(_CMD_DIR_WRITE, _CMD_VTYPE_ENET, 48),
+
+	/*
+	 * cmd_status:
+	 *     Returns the status of the specified command
+	 * Input:
+	 *     a0 = command for which status is being queried.
+	 *          Possible values are:
+	 *              CMD_SOFT_RESET
+	 *              CMD_HANG_RESET
+	 *              CMD_OPEN
+	 *              CMD_INIT
+	 *              CMD_INIT_PROV_INFO
+	 *              CMD_DEINIT
+	 *              CMD_INIT_PROV_INFO2
+	 *              CMD_ENABLE2
+	 * Output:
+	 *     if status == STAT_ERROR
+	 *        a0 = ERR_ENOTSUPPORTED - status for command in a0 is
+	 *                                 not supported
+	 *     if status == STAT_NONE
+	 *        a0 = status of the devcmd specified in a0 as follows.
+	 *             ERR_SUCCESS   - command in a0 completed successfully
+	 *             ERR_EINPROGRESS - command in a0 is still in progress
+	 */
+	CMD_STATUS = _CMDC(_CMD_DIR_RW, _CMD_VTYPE_ALL, 49),
 };
 
+/* CMD_ENABLE2 flags */
+#define CMD_ENABLE2_ACTIVE  0x1
+
 /* flags for CMD_OPEN */
 #define CMD_OPENF_OPROM		0x1	/* open coming from option rom */
 
@@ -315,6 +360,8 @@
 	ERR_ETIMEDOUT = 8,
 	ERR_ELINKDOWN = 9,
 	ERR_EMAXRES = 10,
+	ERR_ENOTSUPPORTED = 11,
+	ERR_EINPROGRESS = 12,
 };
 
 /*
diff -druN linux-2.6.39-libre/drivers/net/enic/vnic_dev.h linux-3.0-rc7-libre/drivers/net/enic/vnic_dev.h
--- linux-2.6.39-libre/drivers/net/enic/vnic_dev.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/enic/vnic_dev.h	2011-07-11 19:51:52.000000000 -0400
@@ -108,8 +108,6 @@
 int vnic_dev_open(struct vnic_dev *vdev, int arg);
 int vnic_dev_open_done(struct vnic_dev *vdev, int *done);
 int vnic_dev_init(struct vnic_dev *vdev, int arg);
-int vnic_dev_init_done(struct vnic_dev *vdev, int *done, int *err);
-int vnic_dev_init_prov(struct vnic_dev *vdev, u8 *buf, u32 len);
 int vnic_dev_deinit(struct vnic_dev *vdev);
 int vnic_dev_hang_reset(struct vnic_dev *vdev, int arg);
 int vnic_dev_hang_reset_done(struct vnic_dev *vdev, int *done);
@@ -122,5 +120,9 @@
 struct vnic_dev *vnic_dev_register(struct vnic_dev *vdev,
 	void *priv, struct pci_dev *pdev, struct vnic_dev_bar *bar,
 	unsigned int num_bars);
+int vnic_dev_init_prov2(struct vnic_dev *vdev, u8 *buf, u32 len);
+int vnic_dev_enable2(struct vnic_dev *vdev, int active);
+int vnic_dev_enable2_done(struct vnic_dev *vdev, int *status);
+int vnic_dev_deinit_done(struct vnic_dev *vdev, int *status);
 
 #endif /* _VNIC_DEV_H_ */
diff -druN linux-2.6.39-libre/drivers/net/enic/vnic_vic.c linux-3.0-rc7-libre/drivers/net/enic/vnic_vic.c
--- linux-2.6.39-libre/drivers/net/enic/vnic_vic.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/enic/vnic_vic.c	2011-07-11 19:51:52.000000000 -0400
@@ -23,7 +23,8 @@
 
 #include "vnic_vic.h"
 
-struct vic_provinfo *vic_provinfo_alloc(gfp_t flags, u8 *oui, u8 type)
+struct vic_provinfo *vic_provinfo_alloc(gfp_t flags, const u8 *oui,
+	const u8 type)
 {
 	struct vic_provinfo *vp;
 
@@ -47,7 +48,7 @@
 }
 
 int vic_provinfo_add_tlv(struct vic_provinfo *vp, u16 type, u16 length,
-	void *value)
+	const void *value)
 {
 	struct vic_provinfo_tlv *tlv;
 
diff -druN linux-2.6.39-libre/drivers/net/enic/vnic_vic.h linux-3.0-rc7-libre/drivers/net/enic/vnic_vic.h
--- linux-2.6.39-libre/drivers/net/enic/vnic_vic.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/enic/vnic_vic.h	2011-07-11 19:51:52.000000000 -0400
@@ -47,6 +47,7 @@
 	VIC_GENERIC_PROV_OS_TYPE_ESX = 1,
 	VIC_GENERIC_PROV_OS_TYPE_LINUX = 2,
 	VIC_GENERIC_PROV_OS_TYPE_WINDOWS = 3,
+	VIC_GENERIC_PROV_OS_TYPE_SOLARIS = 4,
 };
 
 struct vic_provinfo {
@@ -61,14 +62,22 @@
 	} tlv[0];
 } __packed;
 
+#define VIC_PROVINFO_ADD_TLV(vp, tlvtype, tlvlen, data) \
+	do { \
+		err = vic_provinfo_add_tlv(vp, tlvtype, tlvlen, data); \
+		if (err) \
+			goto add_tlv_failure; \
+	} while (0)
+
 #define VIC_PROVINFO_MAX_DATA		1385
 #define VIC_PROVINFO_MAX_TLV_DATA (VIC_PROVINFO_MAX_DATA - \
 	sizeof(struct vic_provinfo))
 
-struct vic_provinfo *vic_provinfo_alloc(gfp_t flags, u8 *oui, u8 type);
+struct vic_provinfo *vic_provinfo_alloc(gfp_t flags, const u8 *oui,
+	const u8 type);
 void vic_provinfo_free(struct vic_provinfo *vp);
 int vic_provinfo_add_tlv(struct vic_provinfo *vp, u16 type, u16 length,
-	void *value);
+	const void *value);
 size_t vic_provinfo_size(struct vic_provinfo *vp);
 
 #endif	/* _VNIC_VIC_H_ */
diff -druN linux-2.6.39-libre/drivers/net/ewrk3.c linux-3.0-rc7-libre/drivers/net/ewrk3.c
--- linux-2.6.39-libre/drivers/net/ewrk3.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/ewrk3.c	2011-07-11 19:51:52.000000000 -0400
@@ -1545,7 +1545,7 @@
 	}
 
 	ecmd->supported |= SUPPORTED_10baseT_Half;
-	ecmd->speed = SPEED_10;
+	ethtool_cmd_speed_set(ecmd, SPEED_10);
 	ecmd->duplex = DUPLEX_HALF;
 	return 0;
 }
@@ -1604,55 +1604,47 @@
 	return !(cmr & CMR_LINK);
 }
 
-static int ewrk3_phys_id(struct net_device *dev, u32 data)
+static int ewrk3_set_phys_id(struct net_device *dev,
+			     enum ethtool_phys_id_state state)
 {
 	struct ewrk3_private *lp = netdev_priv(dev);
 	unsigned long iobase = dev->base_addr;
-	unsigned long flags;
 	u8 cr;
-	int count;
 
-	/* Toggle LED 4x per second */
-	count = data << 2;
-
-	spin_lock_irqsave(&lp->hw_lock, flags);
-
-	/* Bail if a PHYS_ID is already in progress */
-	if (lp->led_mask == 0) {
-		spin_unlock_irqrestore(&lp->hw_lock, flags);
-		return -EBUSY;
-	}
+	spin_lock_irq(&lp->hw_lock);
 
-	/* Prevent ISR from twiddling the LED */
-	lp->led_mask = 0;
+	switch (state) {
+	case ETHTOOL_ID_ACTIVE:
+		/* Prevent ISR from twiddling the LED */
+		lp->led_mask = 0;
+		spin_unlock_irq(&lp->hw_lock);
+		return 2;	/* cycle on/off twice per second */
 
-	while (count--) {
-		/* Toggle the LED */
+	case ETHTOOL_ID_ON:
 		cr = inb(EWRK3_CR);
-		outb(cr ^ CR_LED, EWRK3_CR);
+		outb(cr | CR_LED, EWRK3_CR);
+		break;
 
-		/* Wait a little while */
-		spin_unlock_irqrestore(&lp->hw_lock, flags);
-		msleep(250);
-		spin_lock_irqsave(&lp->hw_lock, flags);
+	case ETHTOOL_ID_OFF:
+		cr = inb(EWRK3_CR);
+		outb(cr & ~CR_LED, EWRK3_CR);
+		break;
 
-		/* Exit if we got a signal */
-		if (signal_pending(current))
-			break;
+	case ETHTOOL_ID_INACTIVE:
+		lp->led_mask = CR_LED;
+		cr = inb(EWRK3_CR);
+		outb(cr & ~CR_LED, EWRK3_CR);
 	}
+	spin_unlock_irq(&lp->hw_lock);
 
-	lp->led_mask = CR_LED;
-	cr = inb(EWRK3_CR);
-	outb(cr & ~CR_LED, EWRK3_CR);
-	spin_unlock_irqrestore(&lp->hw_lock, flags);
-	return signal_pending(current) ? -ERESTARTSYS : 0;
+	return 0;
 }
 
 static const struct ethtool_ops ethtool_ops_203 = {
 	.get_drvinfo = ewrk3_get_drvinfo,
 	.get_settings = ewrk3_get_settings,
 	.set_settings = ewrk3_set_settings,
-	.phys_id = ewrk3_phys_id,
+	.set_phys_id = ewrk3_set_phys_id,
 };
 
 static const struct ethtool_ops ethtool_ops = {
@@ -1660,7 +1652,7 @@
 	.get_settings = ewrk3_get_settings,
 	.set_settings = ewrk3_set_settings,
 	.get_link = ewrk3_get_link,
-	.phys_id = ewrk3_phys_id,
+	.set_phys_id = ewrk3_set_phys_id,
 };
 
 /*
diff -druN linux-2.6.39-libre/drivers/net/forcedeth.c linux-3.0-rc7-libre/drivers/net/forcedeth.c
--- linux-2.6.39-libre/drivers/net/forcedeth.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/forcedeth.c	2011-07-11 19:51:52.000000000 -0400
@@ -64,6 +64,7 @@
 #include <linux/dma-mapping.h>
 #include <linux/slab.h>
 #include <linux/uaccess.h>
+#include <linux/prefetch.h>
 #include  <linux/io.h>
 
 #include <asm/irq.h>
@@ -774,7 +775,6 @@
 	u32 driver_data;
 	u32 device_id;
 	u32 register_size;
-	int rx_csum;
 	u32 mac_in_use;
 	int mgmt_version;
 	int mgmt_sema;
@@ -3956,6 +3956,7 @@
 static int nv_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
 {
 	struct fe_priv *np = netdev_priv(dev);
+	u32 speed;
 	int adv;
 
 	spin_lock_irq(&np->lock);
@@ -3975,23 +3976,26 @@
 	if (netif_carrier_ok(dev)) {
 		switch (np->linkspeed & (NVREG_LINKSPEED_MASK)) {
 		case NVREG_LINKSPEED_10:
-			ecmd->speed = SPEED_10;
+			speed = SPEED_10;
 			break;
 		case NVREG_LINKSPEED_100:
-			ecmd->speed = SPEED_100;
+			speed = SPEED_100;
 			break;
 		case NVREG_LINKSPEED_1000:
-			ecmd->speed = SPEED_1000;
+			speed = SPEED_1000;
+			break;
+		default:
+			speed = -1;
 			break;
 		}
 		ecmd->duplex = DUPLEX_HALF;
 		if (np->duplex)
 			ecmd->duplex = DUPLEX_FULL;
 	} else {
-		ecmd->speed = -1;
+		speed = -1;
 		ecmd->duplex = -1;
 	}
-
+	ethtool_cmd_speed_set(ecmd, speed);
 	ecmd->autoneg = np->autoneg;
 
 	ecmd->advertising = ADVERTISED_MII;
@@ -4030,6 +4034,7 @@
 static int nv_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
 {
 	struct fe_priv *np = netdev_priv(dev);
+	u32 speed = ethtool_cmd_speed(ecmd);
 
 	if (ecmd->port != PORT_MII)
 		return -EINVAL;
@@ -4055,7 +4060,7 @@
 		/* Note: autonegotiation disable, speed 1000 intentionally
 		 * forbidden - no one should need that. */
 
-		if (ecmd->speed != SPEED_10 && ecmd->speed != SPEED_100)
+		if (speed != SPEED_10 && speed != SPEED_100)
 			return -EINVAL;
 		if (ecmd->duplex != DUPLEX_HALF && ecmd->duplex != DUPLEX_FULL)
 			return -EINVAL;
@@ -4139,13 +4144,13 @@
 
 		adv = mii_rw(dev, np->phyaddr, MII_ADVERTISE, MII_READ);
 		adv &= ~(ADVERTISE_ALL | ADVERTISE_100BASE4 | ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM);
-		if (ecmd->speed == SPEED_10 && ecmd->duplex == DUPLEX_HALF)
+		if (speed == SPEED_10 && ecmd->duplex == DUPLEX_HALF)
 			adv |= ADVERTISE_10HALF;
-		if (ecmd->speed == SPEED_10 && ecmd->duplex == DUPLEX_FULL)
+		if (speed == SPEED_10 && ecmd->duplex == DUPLEX_FULL)
 			adv |= ADVERTISE_10FULL;
-		if (ecmd->speed == SPEED_100 && ecmd->duplex == DUPLEX_HALF)
+		if (speed == SPEED_100 && ecmd->duplex == DUPLEX_HALF)
 			adv |= ADVERTISE_100HALF;
-		if (ecmd->speed == SPEED_100 && ecmd->duplex == DUPLEX_FULL)
+		if (speed == SPEED_100 && ecmd->duplex == DUPLEX_FULL)
 			adv |= ADVERTISE_100FULL;
 		np->pause_flags &= ~(NV_PAUSEFRAME_AUTONEG|NV_PAUSEFRAME_RX_ENABLE|NV_PAUSEFRAME_TX_ENABLE);
 		if (np->pause_flags & NV_PAUSEFRAME_RX_REQ) {/* for rx we set both advertisements but disable tx pause */
@@ -4264,16 +4269,6 @@
 	return ret;
 }
 
-static int nv_set_tso(struct net_device *dev, u32 value)
-{
-	struct fe_priv *np = netdev_priv(dev);
-
-	if ((np->driver_data & DEV_HAS_CHECKSUM))
-		return ethtool_op_set_tso(dev, value);
-	else
-		return -EOPNOTSUPP;
-}
-
 static void nv_get_ringparam(struct net_device *dev, struct ethtool_ringparam* ring)
 {
 	struct fe_priv *np = netdev_priv(dev);
@@ -4480,58 +4475,36 @@
 	return 0;
 }
 
-static u32 nv_get_rx_csum(struct net_device *dev)
+static u32 nv_fix_features(struct net_device *dev, u32 features)
 {
-	struct fe_priv *np = netdev_priv(dev);
-	return np->rx_csum != 0;
+	/* vlan is dependent on rx checksum offload */
+	if (features & (NETIF_F_HW_VLAN_TX|NETIF_F_HW_VLAN_RX))
+		features |= NETIF_F_RXCSUM;
+
+	return features;
 }
 
-static int nv_set_rx_csum(struct net_device *dev, u32 data)
+static int nv_set_features(struct net_device *dev, u32 features)
 {
 	struct fe_priv *np = netdev_priv(dev);
 	u8 __iomem *base = get_hwbase(dev);
-	int retcode = 0;
-
-	if (np->driver_data & DEV_HAS_CHECKSUM) {
-		if (data) {
-			np->rx_csum = 1;
-			np->txrxctl_bits |= NVREG_TXRXCTL_RXCHECK;
-		} else {
-			np->rx_csum = 0;
-			/* vlan is dependent on rx checksum offload */
-			if (!(np->vlanctl_bits & NVREG_VLANCONTROL_ENABLE))
-				np->txrxctl_bits &= ~NVREG_TXRXCTL_RXCHECK;
-		}
-		if (netif_running(dev)) {
-			spin_lock_irq(&np->lock);
-			writel(np->txrxctl_bits, base + NvRegTxRxControl);
-			spin_unlock_irq(&np->lock);
-		}
-	} else {
-		return -EINVAL;
-	}
+	u32 changed = dev->features ^ features;
 
-	return retcode;
-}
+	if (changed & NETIF_F_RXCSUM) {
+		spin_lock_irq(&np->lock);
 
-static int nv_set_tx_csum(struct net_device *dev, u32 data)
-{
-	struct fe_priv *np = netdev_priv(dev);
+		if (features & NETIF_F_RXCSUM)
+			np->txrxctl_bits |= NVREG_TXRXCTL_RXCHECK;
+		else
+			np->txrxctl_bits &= ~NVREG_TXRXCTL_RXCHECK;
 
-	if (np->driver_data & DEV_HAS_CHECKSUM)
-		return ethtool_op_set_tx_csum(dev, data);
-	else
-		return -EOPNOTSUPP;
-}
+		if (netif_running(dev))
+			writel(np->txrxctl_bits, base + NvRegTxRxControl);
 
-static int nv_set_sg(struct net_device *dev, u32 data)
-{
-	struct fe_priv *np = netdev_priv(dev);
+		spin_unlock_irq(&np->lock);
+	}
 
-	if (np->driver_data & DEV_HAS_CHECKSUM)
-		return ethtool_op_set_sg(dev, data);
-	else
-		return -EOPNOTSUPP;
+	return 0;
 }
 
 static int nv_get_sset_count(struct net_device *dev, int sset)
@@ -4896,15 +4869,10 @@
 	.get_regs_len = nv_get_regs_len,
 	.get_regs = nv_get_regs,
 	.nway_reset = nv_nway_reset,
-	.set_tso = nv_set_tso,
 	.get_ringparam = nv_get_ringparam,
 	.set_ringparam = nv_set_ringparam,
 	.get_pauseparam = nv_get_pauseparam,
 	.set_pauseparam = nv_set_pauseparam,
-	.get_rx_csum = nv_get_rx_csum,
-	.set_rx_csum = nv_set_rx_csum,
-	.set_tx_csum = nv_set_tx_csum,
-	.set_sg = nv_set_sg,
 	.get_strings = nv_get_strings,
 	.get_ethtool_stats = nv_get_ethtool_stats,
 	.get_sset_count = nv_get_sset_count,
@@ -5235,6 +5203,8 @@
 	.ndo_start_xmit		= nv_start_xmit,
 	.ndo_tx_timeout		= nv_tx_timeout,
 	.ndo_change_mtu		= nv_change_mtu,
+	.ndo_fix_features	= nv_fix_features,
+	.ndo_set_features	= nv_set_features,
 	.ndo_validate_addr	= eth_validate_addr,
 	.ndo_set_mac_address	= nv_set_mac_address,
 	.ndo_set_multicast_list	= nv_set_multicast,
@@ -5251,6 +5221,8 @@
 	.ndo_start_xmit		= nv_start_xmit_optimized,
 	.ndo_tx_timeout		= nv_tx_timeout,
 	.ndo_change_mtu		= nv_change_mtu,
+	.ndo_fix_features	= nv_fix_features,
+	.ndo_set_features	= nv_set_features,
 	.ndo_validate_addr	= eth_validate_addr,
 	.ndo_set_mac_address	= nv_set_mac_address,
 	.ndo_set_multicast_list	= nv_set_multicast,
@@ -5364,11 +5336,10 @@
 		np->pkt_limit = NV_PKTLIMIT_2;
 
 	if (id->driver_data & DEV_HAS_CHECKSUM) {
-		np->rx_csum = 1;
 		np->txrxctl_bits |= NVREG_TXRXCTL_RXCHECK;
-		dev->features |= NETIF_F_IP_CSUM | NETIF_F_SG;
-		dev->features |= NETIF_F_TSO;
-		dev->features |= NETIF_F_GRO;
+		dev->hw_features |= NETIF_F_IP_CSUM | NETIF_F_SG |
+			NETIF_F_TSO | NETIF_F_RXCSUM;
+		dev->features |= dev->hw_features;
 	}
 
 	np->vlanctl_bits = 0;
@@ -5384,7 +5355,6 @@
 		np->pause_flags |= NV_PAUSEFRAME_TX_CAPABLE | NV_PAUSEFRAME_TX_REQ;
 	}
 
-
 	err = -ENOMEM;
 	np->base = ioremap(addr, np->register_size);
 	if (!np->base)
diff -druN linux-2.6.39-libre/drivers/net/fs_enet/fs_enet-main.c linux-3.0-rc7-libre/drivers/net/fs_enet/fs_enet-main.c
--- linux-2.6.39-libre/drivers/net/fs_enet/fs_enet-main.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/fs_enet/fs_enet-main.c	2011-07-11 19:51:52.000000000 -0400
@@ -956,8 +956,6 @@
 	.get_link = ethtool_op_get_link,
 	.get_msglevel = fs_get_msglevel,
 	.set_msglevel = fs_set_msglevel,
-	.set_tx_csum = ethtool_op_set_tx_csum,	/* local! */
-	.set_sg = ethtool_op_set_sg,
 	.get_regs = fs_get_regs,
 };
 
diff -druN linux-2.6.39-libre/drivers/net/fs_enet/mac-fcc.c linux-3.0-rc7-libre/drivers/net/fs_enet/mac-fcc.c
--- linux-2.6.39-libre/drivers/net/fs_enet/mac-fcc.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/fs_enet/mac-fcc.c	2011-07-11 19:51:52.000000000 -0400
@@ -105,7 +105,7 @@
 		goto out_ep;
 
 	fep->fcc.mem = (void __iomem *)cpm2_immr;
-	fpi->dpram_offset = cpm_dpalloc(128, 8);
+	fpi->dpram_offset = cpm_dpalloc(128, 32);
 	if (IS_ERR_VALUE(fpi->dpram_offset)) {
 		ret = fpi->dpram_offset;
 		goto out_fcccp;
diff -druN linux-2.6.39-libre/drivers/net/gianfar.c linux-3.0-rc7-libre/drivers/net/gianfar.c
--- linux-2.6.39-libre/drivers/net/gianfar.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/gianfar.c	2011-07-11 19:51:52.000000000 -0400
@@ -10,7 +10,7 @@
  * Maintainer: Kumar Gala
  * Modifier: Sandeep Gopalpet <sandeep.kumar@freescale.com>
  *
- * Copyright 2002-2009 Freescale Semiconductor, Inc.
+ * Copyright 2002-2009, 2011 Freescale Semiconductor, Inc.
  * Copyright 2007 MontaVista Software, Inc.
  *
  * This program is free software; you can redistribute  it and/or modify it
@@ -365,7 +365,7 @@
 		gfar_write(&regs->rir0, DEFAULT_RIR0);
 	}
 
-	if (priv->rx_csum_enable)
+	if (ndev->features & NETIF_F_RXCSUM)
 		rctrl |= RCTRL_CHECKSUMMING;
 
 	if (priv->extended_hash) {
@@ -463,6 +463,7 @@
 	.ndo_start_xmit = gfar_start_xmit,
 	.ndo_stop = gfar_close,
 	.ndo_change_mtu = gfar_change_mtu,
+	.ndo_set_features = gfar_set_features,
 	.ndo_set_multicast_list = gfar_set_multi,
 	.ndo_tx_timeout = gfar_timeout,
 	.ndo_do_ioctl = gfar_ioctl,
@@ -475,9 +476,6 @@
 #endif
 };
 
-unsigned int ftp_rqfpr[MAX_FILER_IDX + 1];
-unsigned int ftp_rqfcr[MAX_FILER_IDX + 1];
-
 void lock_rx_qs(struct gfar_private *priv)
 {
 	int i = 0x0;
@@ -513,7 +511,7 @@
 /* Returns 1 if incoming frames use an FCB */
 static inline int gfar_uses_fcb(struct gfar_private *priv)
 {
-	return priv->vlgrp || priv->rx_csum_enable ||
+	return priv->vlgrp || (priv->ndev->features & NETIF_F_RXCSUM) ||
 		(priv->device_flags & FSL_GIANFAR_DEV_HAS_TIMER);
 }
 
@@ -867,28 +865,28 @@
 
 	rqfar--;
 	rqfcr = RQFCR_CLE | RQFCR_PID_MASK | RQFCR_CMP_EXACT;
-	ftp_rqfpr[rqfar] = rqfpr;
-	ftp_rqfcr[rqfar] = rqfcr;
+	priv->ftp_rqfpr[rqfar] = rqfpr;
+	priv->ftp_rqfcr[rqfar] = rqfcr;
 	gfar_write_filer(priv, rqfar, rqfcr, rqfpr);
 
 	rqfar--;
 	rqfcr = RQFCR_CMP_NOMATCH;
-	ftp_rqfpr[rqfar] = rqfpr;
-	ftp_rqfcr[rqfar] = rqfcr;
+	priv->ftp_rqfpr[rqfar] = rqfpr;
+	priv->ftp_rqfcr[rqfar] = rqfcr;
 	gfar_write_filer(priv, rqfar, rqfcr, rqfpr);
 
 	rqfar--;
 	rqfcr = RQFCR_CMP_EXACT | RQFCR_PID_PARSE | RQFCR_CLE | RQFCR_AND;
 	rqfpr = class;
-	ftp_rqfcr[rqfar] = rqfcr;
-	ftp_rqfpr[rqfar] = rqfpr;
+	priv->ftp_rqfcr[rqfar] = rqfcr;
+	priv->ftp_rqfpr[rqfar] = rqfpr;
 	gfar_write_filer(priv, rqfar, rqfcr, rqfpr);
 
 	rqfar--;
 	rqfcr = RQFCR_CMP_EXACT | RQFCR_PID_MASK | RQFCR_AND;
 	rqfpr = class;
-	ftp_rqfcr[rqfar] = rqfcr;
-	ftp_rqfpr[rqfar] = rqfpr;
+	priv->ftp_rqfcr[rqfar] = rqfcr;
+	priv->ftp_rqfpr[rqfar] = rqfpr;
 	gfar_write_filer(priv, rqfar, rqfcr, rqfpr);
 
 	return rqfar;
@@ -903,8 +901,8 @@
 
 	/* Default rule */
 	rqfcr = RQFCR_CMP_MATCH;
-	ftp_rqfcr[rqfar] = rqfcr;
-	ftp_rqfpr[rqfar] = rqfpr;
+	priv->ftp_rqfcr[rqfar] = rqfcr;
+	priv->ftp_rqfpr[rqfar] = rqfpr;
 	gfar_write_filer(priv, rqfar, rqfcr, rqfpr);
 
 	rqfar = cluster_entry_per_class(priv, rqfar, RQFPR_IPV6);
@@ -920,8 +918,8 @@
 	/* Rest are masked rules */
 	rqfcr = RQFCR_CMP_NOMATCH;
 	for (i = 0; i < rqfar; i++) {
-		ftp_rqfcr[i] = rqfcr;
-		ftp_rqfpr[i] = rqfpr;
+		priv->ftp_rqfcr[i] = rqfcr;
+		priv->ftp_rqfpr[i] = rqfpr;
 		gfar_write_filer(priv, i, rqfcr, rqfpr);
 	}
 }
@@ -1030,10 +1028,11 @@
 		netif_napi_add(dev, &priv->gfargrp[i].napi, gfar_poll, GFAR_DEV_WEIGHT);
 
 	if (priv->device_flags & FSL_GIANFAR_DEV_HAS_CSUM) {
-		priv->rx_csum_enable = 1;
-		dev->features |= NETIF_F_IP_CSUM | NETIF_F_SG | NETIF_F_HIGHDMA;
-	} else
-		priv->rx_csum_enable = 0;
+		dev->hw_features = NETIF_F_IP_CSUM | NETIF_F_SG |
+			NETIF_F_RXCSUM;
+		dev->features |= NETIF_F_IP_CSUM | NETIF_F_SG |
+			NETIF_F_RXCSUM | NETIF_F_HIGHDMA;
+	}
 
 	priv->vlgrp = NULL;
 
@@ -2697,7 +2696,7 @@
 	if (priv->padding)
 		skb_pull(skb, priv->padding);
 
-	if (priv->rx_csum_enable)
+	if (dev->features & NETIF_F_RXCSUM)
 		gfar_rx_checksum(skb, fcb);
 
 	/* Tell the skb what kind of packet this is */
diff -druN linux-2.6.39-libre/drivers/net/gianfar_ethtool.c linux-3.0-rc7-libre/drivers/net/gianfar_ethtool.c
--- linux-2.6.39-libre/drivers/net/gianfar_ethtool.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/gianfar_ethtool.c	2011-07-11 19:51:52.000000000 -0400
@@ -9,7 +9,7 @@
  *  Maintainer: Kumar Gala
  *  Modifier: Sandeep Gopalpet <sandeep.kumar@freescale.com>
  *
- *  Copyright 2003-2006, 2008-2009 Freescale Semiconductor, Inc.
+ *  Copyright 2003-2006, 2008-2009, 2011 Freescale Semiconductor, Inc.
  *
  *  This software may be used and distributed according to
  *  the terms of the GNU Public License, Version 2, incorporated herein
@@ -517,15 +517,15 @@
 	return err;
 }
 
-static int gfar_set_rx_csum(struct net_device *dev, uint32_t data)
+int gfar_set_features(struct net_device *dev, u32 features)
 {
 	struct gfar_private *priv = netdev_priv(dev);
 	unsigned long flags;
 	int err = 0, i = 0;
+	u32 changed = dev->features ^ features;
 
-	if (!(priv->device_flags & FSL_GIANFAR_DEV_HAS_CSUM))
-		return -EOPNOTSUPP;
-
+	if (!(changed & NETIF_F_RXCSUM))
+		return 0;
 
 	if (dev->flags & IFF_UP) {
 		/* Halt TX and RX, and process the frames which
@@ -546,58 +546,15 @@
 
 		/* Now we take down the rings to rebuild them */
 		stop_gfar(dev);
-	}
 
-	spin_lock_irqsave(&priv->bflock, flags);
-	priv->rx_csum_enable = data;
-	spin_unlock_irqrestore(&priv->bflock, flags);
+		dev->features = features;
 
-	if (dev->flags & IFF_UP) {
 		err = startup_gfar(dev);
 		netif_tx_wake_all_queues(dev);
 	}
 	return err;
 }
 
-static uint32_t gfar_get_rx_csum(struct net_device *dev)
-{
-	struct gfar_private *priv = netdev_priv(dev);
-
-	if (!(priv->device_flags & FSL_GIANFAR_DEV_HAS_CSUM))
-		return 0;
-
-	return priv->rx_csum_enable;
-}
-
-static int gfar_set_tx_csum(struct net_device *dev, uint32_t data)
-{
-	struct gfar_private *priv = netdev_priv(dev);
-
-	if (!(priv->device_flags & FSL_GIANFAR_DEV_HAS_CSUM))
-		return -EOPNOTSUPP;
-
-	netif_tx_lock_bh(dev);
-
-	if (data)
-		dev->features |= NETIF_F_IP_CSUM;
-	else
-		dev->features &= ~NETIF_F_IP_CSUM;
-
-	netif_tx_unlock_bh(dev);
-
-	return 0;
-}
-
-static uint32_t gfar_get_tx_csum(struct net_device *dev)
-{
-	struct gfar_private *priv = netdev_priv(dev);
-
-	if (!(priv->device_flags & FSL_GIANFAR_DEV_HAS_CSUM))
-		return 0;
-
-	return (dev->features & NETIF_F_IP_CSUM) != 0;
-}
-
 static uint32_t gfar_get_msglevel(struct net_device *dev)
 {
 	struct gfar_private *priv = netdev_priv(dev);
@@ -645,42 +602,6 @@
 }
 #endif
 
-static int gfar_ethflow_to_class(int flow_type, u64 *class)
-{
-	switch (flow_type) {
-	case TCP_V4_FLOW:
-		*class = CLASS_CODE_TCP_IPV4;
-		break;
-	case UDP_V4_FLOW:
-		*class = CLASS_CODE_UDP_IPV4;
-		break;
-	case AH_V4_FLOW:
-	case ESP_V4_FLOW:
-		*class = CLASS_CODE_AH_ESP_IPV4;
-		break;
-	case SCTP_V4_FLOW:
-		*class = CLASS_CODE_SCTP_IPV4;
-		break;
-	case TCP_V6_FLOW:
-		*class = CLASS_CODE_TCP_IPV6;
-		break;
-	case UDP_V6_FLOW:
-		*class = CLASS_CODE_UDP_IPV6;
-		break;
-	case AH_V6_FLOW:
-	case ESP_V6_FLOW:
-		*class = CLASS_CODE_AH_ESP_IPV6;
-		break;
-	case SCTP_V6_FLOW:
-		*class = CLASS_CODE_SCTP_IPV6;
-		break;
-	default:
-		return 0;
-	}
-
-	return 1;
-}
-
 static void ethflow_to_filer_rules (struct gfar_private *priv, u64 ethflow)
 {
 	u32 fcr = 0x0, fpr = FPR_FILER_MASK;
@@ -688,15 +609,15 @@
 	if (ethflow & RXH_L2DA) {
 		fcr = RQFCR_PID_DAH |RQFCR_CMP_NOMATCH |
 			RQFCR_HASH | RQFCR_AND | RQFCR_HASHTBL_0;
-		ftp_rqfpr[priv->cur_filer_idx] = fpr;
-		ftp_rqfcr[priv->cur_filer_idx] = fcr;
+		priv->ftp_rqfpr[priv->cur_filer_idx] = fpr;
+		priv->ftp_rqfcr[priv->cur_filer_idx] = fcr;
 		gfar_write_filer(priv, priv->cur_filer_idx, fcr, fpr);
 		priv->cur_filer_idx = priv->cur_filer_idx - 1;
 
 		fcr = RQFCR_PID_DAL | RQFCR_AND | RQFCR_CMP_NOMATCH |
 				RQFCR_HASH | RQFCR_AND | RQFCR_HASHTBL_0;
-		ftp_rqfpr[priv->cur_filer_idx] = fpr;
-		ftp_rqfcr[priv->cur_filer_idx] = fcr;
+		priv->ftp_rqfpr[priv->cur_filer_idx] = fpr;
+		priv->ftp_rqfcr[priv->cur_filer_idx] = fcr;
 		gfar_write_filer(priv, priv->cur_filer_idx, fcr, fpr);
 		priv->cur_filer_idx = priv->cur_filer_idx - 1;
 	}
@@ -705,16 +626,16 @@
 		fcr = RQFCR_PID_VID | RQFCR_CMP_NOMATCH | RQFCR_HASH |
 				RQFCR_AND | RQFCR_HASHTBL_0;
 		gfar_write_filer(priv, priv->cur_filer_idx, fcr, fpr);
-		ftp_rqfpr[priv->cur_filer_idx] = fpr;
-		ftp_rqfcr[priv->cur_filer_idx] = fcr;
+		priv->ftp_rqfpr[priv->cur_filer_idx] = fpr;
+		priv->ftp_rqfcr[priv->cur_filer_idx] = fcr;
 		priv->cur_filer_idx = priv->cur_filer_idx - 1;
 	}
 
 	if (ethflow & RXH_IP_SRC) {
 		fcr = RQFCR_PID_SIA | RQFCR_CMP_NOMATCH | RQFCR_HASH |
 			RQFCR_AND | RQFCR_HASHTBL_0;
-		ftp_rqfpr[priv->cur_filer_idx] = fpr;
-		ftp_rqfcr[priv->cur_filer_idx] = fcr;
+		priv->ftp_rqfpr[priv->cur_filer_idx] = fpr;
+		priv->ftp_rqfcr[priv->cur_filer_idx] = fcr;
 		gfar_write_filer(priv, priv->cur_filer_idx, fcr, fpr);
 		priv->cur_filer_idx = priv->cur_filer_idx - 1;
 	}
@@ -722,8 +643,8 @@
 	if (ethflow & (RXH_IP_DST)) {
 		fcr = RQFCR_PID_DIA | RQFCR_CMP_NOMATCH | RQFCR_HASH |
 			RQFCR_AND | RQFCR_HASHTBL_0;
-		ftp_rqfpr[priv->cur_filer_idx] = fpr;
-		ftp_rqfcr[priv->cur_filer_idx] = fcr;
+		priv->ftp_rqfpr[priv->cur_filer_idx] = fpr;
+		priv->ftp_rqfcr[priv->cur_filer_idx] = fcr;
 		gfar_write_filer(priv, priv->cur_filer_idx, fcr, fpr);
 		priv->cur_filer_idx = priv->cur_filer_idx - 1;
 	}
@@ -731,8 +652,8 @@
 	if (ethflow & RXH_L3_PROTO) {
 		fcr = RQFCR_PID_L4P | RQFCR_CMP_NOMATCH | RQFCR_HASH |
 			RQFCR_AND | RQFCR_HASHTBL_0;
-		ftp_rqfpr[priv->cur_filer_idx] = fpr;
-		ftp_rqfcr[priv->cur_filer_idx] = fcr;
+		priv->ftp_rqfpr[priv->cur_filer_idx] = fpr;
+		priv->ftp_rqfcr[priv->cur_filer_idx] = fcr;
 		gfar_write_filer(priv, priv->cur_filer_idx, fcr, fpr);
 		priv->cur_filer_idx = priv->cur_filer_idx - 1;
 	}
@@ -740,8 +661,8 @@
 	if (ethflow & RXH_L4_B_0_1) {
 		fcr = RQFCR_PID_SPT | RQFCR_CMP_NOMATCH | RQFCR_HASH |
 			RQFCR_AND | RQFCR_HASHTBL_0;
-		ftp_rqfpr[priv->cur_filer_idx] = fpr;
-		ftp_rqfcr[priv->cur_filer_idx] = fcr;
+		priv->ftp_rqfpr[priv->cur_filer_idx] = fpr;
+		priv->ftp_rqfcr[priv->cur_filer_idx] = fcr;
 		gfar_write_filer(priv, priv->cur_filer_idx, fcr, fpr);
 		priv->cur_filer_idx = priv->cur_filer_idx - 1;
 	}
@@ -749,8 +670,8 @@
 	if (ethflow & RXH_L4_B_2_3) {
 		fcr = RQFCR_PID_DPT | RQFCR_CMP_NOMATCH | RQFCR_HASH |
 			RQFCR_AND | RQFCR_HASHTBL_0;
-		ftp_rqfpr[priv->cur_filer_idx] = fpr;
-		ftp_rqfcr[priv->cur_filer_idx] = fcr;
+		priv->ftp_rqfpr[priv->cur_filer_idx] = fpr;
+		priv->ftp_rqfcr[priv->cur_filer_idx] = fcr;
 		gfar_write_filer(priv, priv->cur_filer_idx, fcr, fpr);
 		priv->cur_filer_idx = priv->cur_filer_idx - 1;
 	}
@@ -778,23 +699,18 @@
 	case UDP_V6_FLOW:
 		cmp_rqfpr = RQFPR_IPV6 |RQFPR_UDP;
 		break;
-	case IPV4_FLOW:
-		cmp_rqfpr = RQFPR_IPV4;
-	case IPV6_FLOW:
-		cmp_rqfpr = RQFPR_IPV6;
-		break;
 	default:
 		printk(KERN_ERR "Right now this class is not supported\n");
 		return 0;
 	}
 
 	for (i = 0; i < MAX_FILER_IDX + 1; i++) {
-		local_rqfpr[j] = ftp_rqfpr[i];
-		local_rqfcr[j] = ftp_rqfcr[i];
+		local_rqfpr[j] = priv->ftp_rqfpr[i];
+		local_rqfcr[j] = priv->ftp_rqfcr[i];
 		j--;
-		if ((ftp_rqfcr[i] == (RQFCR_PID_PARSE |
+		if ((priv->ftp_rqfcr[i] == (RQFCR_PID_PARSE |
 			RQFCR_CLE |RQFCR_AND)) &&
-			(ftp_rqfpr[i] == cmp_rqfpr))
+			(priv->ftp_rqfpr[i] == cmp_rqfpr))
 			break;
 	}
 
@@ -808,20 +724,22 @@
 	 * if it was already programmed, we need to overwrite these rules
 	 */
 	for (l = i+1; l < MAX_FILER_IDX; l++) {
-		if ((ftp_rqfcr[l] & RQFCR_CLE) &&
-			!(ftp_rqfcr[l] & RQFCR_AND)) {
-			ftp_rqfcr[l] = RQFCR_CLE | RQFCR_CMP_EXACT |
+		if ((priv->ftp_rqfcr[l] & RQFCR_CLE) &&
+			!(priv->ftp_rqfcr[l] & RQFCR_AND)) {
+			priv->ftp_rqfcr[l] = RQFCR_CLE | RQFCR_CMP_EXACT |
 				RQFCR_HASHTBL_0 | RQFCR_PID_MASK;
-			ftp_rqfpr[l] = FPR_FILER_MASK;
-			gfar_write_filer(priv, l, ftp_rqfcr[l], ftp_rqfpr[l]);
+			priv->ftp_rqfpr[l] = FPR_FILER_MASK;
+			gfar_write_filer(priv, l, priv->ftp_rqfcr[l],
+				priv->ftp_rqfpr[l]);
 			break;
 		}
 
-		if (!(ftp_rqfcr[l] & RQFCR_CLE) && (ftp_rqfcr[l] & RQFCR_AND))
+		if (!(priv->ftp_rqfcr[l] & RQFCR_CLE) &&
+			(priv->ftp_rqfcr[l] & RQFCR_AND))
 			continue;
 		else {
-			local_rqfpr[j] = ftp_rqfpr[l];
-			local_rqfcr[j] = ftp_rqfcr[l];
+			local_rqfpr[j] = priv->ftp_rqfpr[l];
+			local_rqfcr[j] = priv->ftp_rqfcr[l];
 			j--;
 		}
 	}
@@ -834,8 +752,8 @@
 
 	/* Write back the popped out rules again */
 	for (k = j+1; k < MAX_FILER_IDX; k++) {
-		ftp_rqfpr[priv->cur_filer_idx] = local_rqfpr[k];
-		ftp_rqfcr[priv->cur_filer_idx] = local_rqfcr[k];
+		priv->ftp_rqfpr[priv->cur_filer_idx] = local_rqfpr[k];
+		priv->ftp_rqfcr[priv->cur_filer_idx] = local_rqfcr[k];
 		gfar_write_filer(priv, priv->cur_filer_idx,
 				local_rqfcr[k], local_rqfpr[k]);
 		if (!priv->cur_filer_idx)
@@ -848,18 +766,9 @@
 
 static int gfar_set_hash_opts(struct gfar_private *priv, struct ethtool_rxnfc *cmd)
 {
-	u64 class;
-
-	if (!gfar_ethflow_to_class(cmd->flow_type, &class))
-		return -EINVAL;
-
-	if (class < CLASS_CODE_USER_PROG1 ||
-			class > CLASS_CODE_SCTP_IPV6)
-		return -EINVAL;
-
 	/* write the filer rules here */
 	if (!gfar_ethflow_to_filer_table(priv, cmd->data, cmd->flow_type))
-		return -1;
+		return -EINVAL;
 
 	return 0;
 }
@@ -894,11 +803,6 @@
 	.get_strings = gfar_gstrings,
 	.get_sset_count = gfar_sset_count,
 	.get_ethtool_stats = gfar_fill_stats,
-	.get_rx_csum = gfar_get_rx_csum,
-	.get_tx_csum = gfar_get_tx_csum,
-	.set_rx_csum = gfar_set_rx_csum,
-	.set_tx_csum = gfar_set_tx_csum,
-	.set_sg = ethtool_op_set_sg,
 	.get_msglevel = gfar_get_msglevel,
 	.set_msglevel = gfar_set_msglevel,
 #ifdef CONFIG_PM
diff -druN linux-2.6.39-libre/drivers/net/gianfar.h linux-3.0-rc7-libre/drivers/net/gianfar.h
--- linux-2.6.39-libre/drivers/net/gianfar.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/gianfar.h	2011-07-11 19:51:52.000000000 -0400
@@ -9,7 +9,7 @@
  * Maintainer: Kumar Gala
  * Modifier: Sandeep Gopalpet <sandeep.kumar@freescale.com>
  *
- * Copyright 2002-2009 Freescale Semiconductor, Inc.
+ * Copyright 2002-2009, 2011 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
@@ -382,23 +382,6 @@
 #define BD_LFLAG(flags) ((flags) << 16)
 #define BD_LENGTH_MASK		0x0000ffff
 
-#define CLASS_CODE_UNRECOG		0x00
-#define CLASS_CODE_DUMMY1		0x01
-#define CLASS_CODE_ETHERTYPE1		0x02
-#define CLASS_CODE_ETHERTYPE2		0x03
-#define CLASS_CODE_USER_PROG1		0x04
-#define CLASS_CODE_USER_PROG2		0x05
-#define CLASS_CODE_USER_PROG3		0x06
-#define CLASS_CODE_USER_PROG4		0x07
-#define CLASS_CODE_TCP_IPV4		0x08
-#define CLASS_CODE_UDP_IPV4		0x09
-#define CLASS_CODE_AH_ESP_IPV4		0x0a
-#define CLASS_CODE_SCTP_IPV4		0x0b
-#define CLASS_CODE_TCP_IPV6		0x0c
-#define CLASS_CODE_UDP_IPV6		0x0d
-#define CLASS_CODE_AH_ESP_IPV6		0x0e
-#define CLASS_CODE_SCTP_IPV6		0x0f
-
 #define FPR_FILER_MASK	0xFFFFFFFF
 #define MAX_FILER_IDX	0xFF
 
@@ -1100,7 +1083,7 @@
 	struct device_node *phy_node;
 	struct device_node *tbi_node;
 	u32 device_flags;
-	unsigned char rx_csum_enable:1,
+	unsigned char
 		extended_hash:1,
 		bd_stash_en:1,
 		rx_filer_enable:1,
@@ -1124,10 +1107,12 @@
 	/* HW time stamping enabled flag */
 	int hwts_rx_en;
 	int hwts_tx_en;
+
+	/*Filer table*/
+	unsigned int ftp_rqfpr[MAX_FILER_IDX + 1];
+	unsigned int ftp_rqfcr[MAX_FILER_IDX + 1];
 };
 
-extern unsigned int ftp_rqfpr[MAX_FILER_IDX + 1];
-extern unsigned int ftp_rqfcr[MAX_FILER_IDX + 1];
 
 static inline int gfar_has_errata(struct gfar_private *priv,
 				  enum gfar_errata err)
@@ -1170,6 +1155,7 @@
 extern void gfar_configure_coalescing(struct gfar_private *priv,
 		unsigned long tx_mask, unsigned long rx_mask);
 void gfar_init_sysfs(struct net_device *dev);
+int gfar_set_features(struct net_device *dev, u32 features);
 
 extern const struct ethtool_ops gfar_ethtool_ops;
 
diff -druN linux-2.6.39-libre/drivers/net/gianfar_ptp.c linux-3.0-rc7-libre/drivers/net/gianfar_ptp.c
--- linux-2.6.39-libre/drivers/net/gianfar_ptp.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/net/gianfar_ptp.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,588 @@
+/*
+ * PTP 1588 clock using the eTSEC
+ *
+ * Copyright (C) 2010 OMICRON electronics GmbH
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <linux/device.h>
+#include <linux/hrtimer.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_platform.h>
+#include <linux/timex.h>
+#include <linux/io.h>
+
+#include <linux/ptp_clock_kernel.h>
+
+#include "gianfar.h"
+
+/*
+ * gianfar ptp registers
+ * Generated by regen.tcl on Thu May 13 01:38:57 PM CEST 2010
+ */
+struct gianfar_ptp_registers {
+	u32 tmr_ctrl;     /* Timer control register */
+	u32 tmr_tevent;   /* Timestamp event register */
+	u32 tmr_temask;   /* Timer event mask register */
+	u32 tmr_pevent;   /* Timestamp event register */
+	u32 tmr_pemask;   /* Timer event mask register */
+	u32 tmr_stat;     /* Timestamp status register */
+	u32 tmr_cnt_h;    /* Timer counter high register */
+	u32 tmr_cnt_l;    /* Timer counter low register */
+	u32 tmr_add;      /* Timer drift compensation addend register */
+	u32 tmr_acc;      /* Timer accumulator register */
+	u32 tmr_prsc;     /* Timer prescale */
+	u8  res1[4];
+	u32 tmroff_h;     /* Timer offset high */
+	u32 tmroff_l;     /* Timer offset low */
+	u8  res2[8];
+	u32 tmr_alarm1_h; /* Timer alarm 1 high register */
+	u32 tmr_alarm1_l; /* Timer alarm 1 high register */
+	u32 tmr_alarm2_h; /* Timer alarm 2 high register */
+	u32 tmr_alarm2_l; /* Timer alarm 2 high register */
+	u8  res3[48];
+	u32 tmr_fiper1;   /* Timer fixed period interval */
+	u32 tmr_fiper2;   /* Timer fixed period interval */
+	u32 tmr_fiper3;   /* Timer fixed period interval */
+	u8  res4[20];
+	u32 tmr_etts1_h;  /* Timestamp of general purpose external trigger */
+	u32 tmr_etts1_l;  /* Timestamp of general purpose external trigger */
+	u32 tmr_etts2_h;  /* Timestamp of general purpose external trigger */
+	u32 tmr_etts2_l;  /* Timestamp of general purpose external trigger */
+};
+
+/* Bit definitions for the TMR_CTRL register */
+#define ALM1P                 (1<<31) /* Alarm1 output polarity */
+#define ALM2P                 (1<<30) /* Alarm2 output polarity */
+#define FS                    (1<<28) /* FIPER start indication */
+#define PP1L                  (1<<27) /* Fiper1 pulse loopback mode enabled. */
+#define PP2L                  (1<<26) /* Fiper2 pulse loopback mode enabled. */
+#define TCLK_PERIOD_SHIFT     (16) /* 1588 timer reference clock period. */
+#define TCLK_PERIOD_MASK      (0x3ff)
+#define RTPE                  (1<<15) /* Record Tx Timestamp to PAL Enable. */
+#define FRD                   (1<<14) /* FIPER Realignment Disable */
+#define ESFDP                 (1<<11) /* External Tx/Rx SFD Polarity. */
+#define ESFDE                 (1<<10) /* External Tx/Rx SFD Enable. */
+#define ETEP2                 (1<<9) /* External trigger 2 edge polarity */
+#define ETEP1                 (1<<8) /* External trigger 1 edge polarity */
+#define COPH                  (1<<7) /* Generated clock output phase. */
+#define CIPH                  (1<<6) /* External oscillator input clock phase */
+#define TMSR                  (1<<5) /* Timer soft reset. */
+#define BYP                   (1<<3) /* Bypass drift compensated clock */
+#define TE                    (1<<2) /* 1588 timer enable. */
+#define CKSEL_SHIFT           (0)    /* 1588 Timer reference clock source */
+#define CKSEL_MASK            (0x3)
+
+/* Bit definitions for the TMR_TEVENT register */
+#define ETS2                  (1<<25) /* External trigger 2 timestamp sampled */
+#define ETS1                  (1<<24) /* External trigger 1 timestamp sampled */
+#define ALM2                  (1<<17) /* Current time = alarm time register 2 */
+#define ALM1                  (1<<16) /* Current time = alarm time register 1 */
+#define PP1                   (1<<7)  /* periodic pulse generated on FIPER1 */
+#define PP2                   (1<<6)  /* periodic pulse generated on FIPER2 */
+#define PP3                   (1<<5)  /* periodic pulse generated on FIPER3 */
+
+/* Bit definitions for the TMR_TEMASK register */
+#define ETS2EN                (1<<25) /* External trigger 2 timestamp enable */
+#define ETS1EN                (1<<24) /* External trigger 1 timestamp enable */
+#define ALM2EN                (1<<17) /* Timer ALM2 event enable */
+#define ALM1EN                (1<<16) /* Timer ALM1 event enable */
+#define PP1EN                 (1<<7) /* Periodic pulse event 1 enable */
+#define PP2EN                 (1<<6) /* Periodic pulse event 2 enable */
+
+/* Bit definitions for the TMR_PEVENT register */
+#define TXP2                  (1<<9) /* PTP transmitted timestamp im TXTS2 */
+#define TXP1                  (1<<8) /* PTP transmitted timestamp in TXTS1 */
+#define RXP                   (1<<0) /* PTP frame has been received */
+
+/* Bit definitions for the TMR_PEMASK register */
+#define TXP2EN                (1<<9) /* Transmit PTP packet event 2 enable */
+#define TXP1EN                (1<<8) /* Transmit PTP packet event 1 enable */
+#define RXPEN                 (1<<0) /* Receive PTP packet event enable */
+
+/* Bit definitions for the TMR_STAT register */
+#define STAT_VEC_SHIFT        (0) /* Timer general purpose status vector */
+#define STAT_VEC_MASK         (0x3f)
+
+/* Bit definitions for the TMR_PRSC register */
+#define PRSC_OCK_SHIFT        (0) /* Output clock division/prescale factor. */
+#define PRSC_OCK_MASK         (0xffff)
+
+
+#define DRIVER		"gianfar_ptp"
+#define DEFAULT_CKSEL	1
+#define N_ALARM		1 /* first alarm is used internally to reset fipers */
+#define N_EXT_TS	2
+#define REG_SIZE	sizeof(struct gianfar_ptp_registers)
+
+struct etsects {
+	struct gianfar_ptp_registers *regs;
+	spinlock_t lock; /* protects regs */
+	struct ptp_clock *clock;
+	struct ptp_clock_info caps;
+	struct resource *rsrc;
+	int irq;
+	u64 alarm_interval; /* for periodic alarm */
+	u64 alarm_value;
+	u32 tclk_period;  /* nanoseconds */
+	u32 tmr_prsc;
+	u32 tmr_add;
+	u32 cksel;
+	u32 tmr_fiper1;
+	u32 tmr_fiper2;
+};
+
+/*
+ * Register access functions
+ */
+
+/* Caller must hold etsects->lock. */
+static u64 tmr_cnt_read(struct etsects *etsects)
+{
+	u64 ns;
+	u32 lo, hi;
+
+	lo = gfar_read(&etsects->regs->tmr_cnt_l);
+	hi = gfar_read(&etsects->regs->tmr_cnt_h);
+	ns = ((u64) hi) << 32;
+	ns |= lo;
+	return ns;
+}
+
+/* Caller must hold etsects->lock. */
+static void tmr_cnt_write(struct etsects *etsects, u64 ns)
+{
+	u32 hi = ns >> 32;
+	u32 lo = ns & 0xffffffff;
+
+	gfar_write(&etsects->regs->tmr_cnt_l, lo);
+	gfar_write(&etsects->regs->tmr_cnt_h, hi);
+}
+
+/* Caller must hold etsects->lock. */
+static void set_alarm(struct etsects *etsects)
+{
+	u64 ns;
+	u32 lo, hi;
+
+	ns = tmr_cnt_read(etsects) + 1500000000ULL;
+	ns = div_u64(ns, 1000000000UL) * 1000000000ULL;
+	ns -= etsects->tclk_period;
+	hi = ns >> 32;
+	lo = ns & 0xffffffff;
+	gfar_write(&etsects->regs->tmr_alarm1_l, lo);
+	gfar_write(&etsects->regs->tmr_alarm1_h, hi);
+}
+
+/* Caller must hold etsects->lock. */
+static void set_fipers(struct etsects *etsects)
+{
+	u32 tmr_ctrl = gfar_read(&etsects->regs->tmr_ctrl);
+
+	gfar_write(&etsects->regs->tmr_ctrl,   tmr_ctrl & (~TE));
+	gfar_write(&etsects->regs->tmr_prsc,   etsects->tmr_prsc);
+	gfar_write(&etsects->regs->tmr_fiper1, etsects->tmr_fiper1);
+	gfar_write(&etsects->regs->tmr_fiper2, etsects->tmr_fiper2);
+	set_alarm(etsects);
+	gfar_write(&etsects->regs->tmr_ctrl,   tmr_ctrl|TE);
+}
+
+/*
+ * Interrupt service routine
+ */
+
+static irqreturn_t isr(int irq, void *priv)
+{
+	struct etsects *etsects = priv;
+	struct ptp_clock_event event;
+	u64 ns;
+	u32 ack = 0, lo, hi, mask, val;
+
+	val = gfar_read(&etsects->regs->tmr_tevent);
+
+	if (val & ETS1) {
+		ack |= ETS1;
+		hi = gfar_read(&etsects->regs->tmr_etts1_h);
+		lo = gfar_read(&etsects->regs->tmr_etts1_l);
+		event.type = PTP_CLOCK_EXTTS;
+		event.index = 0;
+		event.timestamp = ((u64) hi) << 32;
+		event.timestamp |= lo;
+		ptp_clock_event(etsects->clock, &event);
+	}
+
+	if (val & ETS2) {
+		ack |= ETS2;
+		hi = gfar_read(&etsects->regs->tmr_etts2_h);
+		lo = gfar_read(&etsects->regs->tmr_etts2_l);
+		event.type = PTP_CLOCK_EXTTS;
+		event.index = 1;
+		event.timestamp = ((u64) hi) << 32;
+		event.timestamp |= lo;
+		ptp_clock_event(etsects->clock, &event);
+	}
+
+	if (val & ALM2) {
+		ack |= ALM2;
+		if (etsects->alarm_value) {
+			event.type = PTP_CLOCK_ALARM;
+			event.index = 0;
+			event.timestamp = etsects->alarm_value;
+			ptp_clock_event(etsects->clock, &event);
+		}
+		if (etsects->alarm_interval) {
+			ns = etsects->alarm_value + etsects->alarm_interval;
+			hi = ns >> 32;
+			lo = ns & 0xffffffff;
+			spin_lock(&etsects->lock);
+			gfar_write(&etsects->regs->tmr_alarm2_l, lo);
+			gfar_write(&etsects->regs->tmr_alarm2_h, hi);
+			spin_unlock(&etsects->lock);
+			etsects->alarm_value = ns;
+		} else {
+			gfar_write(&etsects->regs->tmr_tevent, ALM2);
+			spin_lock(&etsects->lock);
+			mask = gfar_read(&etsects->regs->tmr_temask);
+			mask &= ~ALM2EN;
+			gfar_write(&etsects->regs->tmr_temask, mask);
+			spin_unlock(&etsects->lock);
+			etsects->alarm_value = 0;
+			etsects->alarm_interval = 0;
+		}
+	}
+
+	if (val & PP1) {
+		ack |= PP1;
+		event.type = PTP_CLOCK_PPS;
+		ptp_clock_event(etsects->clock, &event);
+	}
+
+	if (ack) {
+		gfar_write(&etsects->regs->tmr_tevent, ack);
+		return IRQ_HANDLED;
+	} else
+		return IRQ_NONE;
+}
+
+/*
+ * PTP clock operations
+ */
+
+static int ptp_gianfar_adjfreq(struct ptp_clock_info *ptp, s32 ppb)
+{
+	u64 adj;
+	u32 diff, tmr_add;
+	int neg_adj = 0;
+	struct etsects *etsects = container_of(ptp, struct etsects, caps);
+
+	if (ppb < 0) {
+		neg_adj = 1;
+		ppb = -ppb;
+	}
+	tmr_add = etsects->tmr_add;
+	adj = tmr_add;
+	adj *= ppb;
+	diff = div_u64(adj, 1000000000ULL);
+
+	tmr_add = neg_adj ? tmr_add - diff : tmr_add + diff;
+
+	gfar_write(&etsects->regs->tmr_add, tmr_add);
+
+	return 0;
+}
+
+static int ptp_gianfar_adjtime(struct ptp_clock_info *ptp, s64 delta)
+{
+	s64 now;
+	unsigned long flags;
+	struct etsects *etsects = container_of(ptp, struct etsects, caps);
+
+	spin_lock_irqsave(&etsects->lock, flags);
+
+	now = tmr_cnt_read(etsects);
+	now += delta;
+	tmr_cnt_write(etsects, now);
+
+	spin_unlock_irqrestore(&etsects->lock, flags);
+
+	set_fipers(etsects);
+
+	return 0;
+}
+
+static int ptp_gianfar_gettime(struct ptp_clock_info *ptp, struct timespec *ts)
+{
+	u64 ns;
+	u32 remainder;
+	unsigned long flags;
+	struct etsects *etsects = container_of(ptp, struct etsects, caps);
+
+	spin_lock_irqsave(&etsects->lock, flags);
+
+	ns = tmr_cnt_read(etsects);
+
+	spin_unlock_irqrestore(&etsects->lock, flags);
+
+	ts->tv_sec = div_u64_rem(ns, 1000000000, &remainder);
+	ts->tv_nsec = remainder;
+	return 0;
+}
+
+static int ptp_gianfar_settime(struct ptp_clock_info *ptp,
+			       const struct timespec *ts)
+{
+	u64 ns;
+	unsigned long flags;
+	struct etsects *etsects = container_of(ptp, struct etsects, caps);
+
+	ns = ts->tv_sec * 1000000000ULL;
+	ns += ts->tv_nsec;
+
+	spin_lock_irqsave(&etsects->lock, flags);
+
+	tmr_cnt_write(etsects, ns);
+	set_fipers(etsects);
+
+	spin_unlock_irqrestore(&etsects->lock, flags);
+
+	return 0;
+}
+
+static int ptp_gianfar_enable(struct ptp_clock_info *ptp,
+			      struct ptp_clock_request *rq, int on)
+{
+	struct etsects *etsects = container_of(ptp, struct etsects, caps);
+	unsigned long flags;
+	u32 bit, mask;
+
+	switch (rq->type) {
+	case PTP_CLK_REQ_EXTTS:
+		switch (rq->extts.index) {
+		case 0:
+			bit = ETS1EN;
+			break;
+		case 1:
+			bit = ETS2EN;
+			break;
+		default:
+			return -EINVAL;
+		}
+		spin_lock_irqsave(&etsects->lock, flags);
+		mask = gfar_read(&etsects->regs->tmr_temask);
+		if (on)
+			mask |= bit;
+		else
+			mask &= ~bit;
+		gfar_write(&etsects->regs->tmr_temask, mask);
+		spin_unlock_irqrestore(&etsects->lock, flags);
+		return 0;
+
+	case PTP_CLK_REQ_PPS:
+		spin_lock_irqsave(&etsects->lock, flags);
+		mask = gfar_read(&etsects->regs->tmr_temask);
+		if (on)
+			mask |= PP1EN;
+		else
+			mask &= ~PP1EN;
+		gfar_write(&etsects->regs->tmr_temask, mask);
+		spin_unlock_irqrestore(&etsects->lock, flags);
+		return 0;
+
+	default:
+		break;
+	}
+
+	return -EOPNOTSUPP;
+}
+
+static struct ptp_clock_info ptp_gianfar_caps = {
+	.owner		= THIS_MODULE,
+	.name		= "gianfar clock",
+	.max_adj	= 512000,
+	.n_alarm	= N_ALARM,
+	.n_ext_ts	= N_EXT_TS,
+	.n_per_out	= 0,
+	.pps		= 1,
+	.adjfreq	= ptp_gianfar_adjfreq,
+	.adjtime	= ptp_gianfar_adjtime,
+	.gettime	= ptp_gianfar_gettime,
+	.settime	= ptp_gianfar_settime,
+	.enable		= ptp_gianfar_enable,
+};
+
+/* OF device tree */
+
+static int get_of_u32(struct device_node *node, char *str, u32 *val)
+{
+	int plen;
+	const u32 *prop = of_get_property(node, str, &plen);
+
+	if (!prop || plen != sizeof(*prop))
+		return -1;
+	*val = *prop;
+	return 0;
+}
+
+static int gianfar_ptp_probe(struct platform_device *dev)
+{
+	struct device_node *node = dev->dev.of_node;
+	struct etsects *etsects;
+	struct timespec now;
+	int err = -ENOMEM;
+	u32 tmr_ctrl;
+	unsigned long flags;
+
+	etsects = kzalloc(sizeof(*etsects), GFP_KERNEL);
+	if (!etsects)
+		goto no_memory;
+
+	err = -ENODEV;
+
+	etsects->caps = ptp_gianfar_caps;
+	etsects->cksel = DEFAULT_CKSEL;
+
+	if (get_of_u32(node, "fsl,tclk-period", &etsects->tclk_period) ||
+	    get_of_u32(node, "fsl,tmr-prsc", &etsects->tmr_prsc) ||
+	    get_of_u32(node, "fsl,tmr-add", &etsects->tmr_add) ||
+	    get_of_u32(node, "fsl,tmr-fiper1", &etsects->tmr_fiper1) ||
+	    get_of_u32(node, "fsl,tmr-fiper2", &etsects->tmr_fiper2) ||
+	    get_of_u32(node, "fsl,max-adj", &etsects->caps.max_adj)) {
+		pr_err("device tree node missing required elements\n");
+		goto no_node;
+	}
+
+	etsects->irq = platform_get_irq(dev, 0);
+
+	if (etsects->irq == NO_IRQ) {
+		pr_err("irq not in device tree\n");
+		goto no_node;
+	}
+	if (request_irq(etsects->irq, isr, 0, DRIVER, etsects)) {
+		pr_err("request_irq failed\n");
+		goto no_node;
+	}
+
+	etsects->rsrc = platform_get_resource(dev, IORESOURCE_MEM, 0);
+	if (!etsects->rsrc) {
+		pr_err("no resource\n");
+		goto no_resource;
+	}
+	if (request_resource(&ioport_resource, etsects->rsrc)) {
+		pr_err("resource busy\n");
+		goto no_resource;
+	}
+
+	spin_lock_init(&etsects->lock);
+
+	etsects->regs = ioremap(etsects->rsrc->start,
+				1 + etsects->rsrc->end - etsects->rsrc->start);
+	if (!etsects->regs) {
+		pr_err("ioremap ptp registers failed\n");
+		goto no_ioremap;
+	}
+	getnstimeofday(&now);
+	ptp_gianfar_settime(&etsects->caps, &now);
+
+	tmr_ctrl =
+	  (etsects->tclk_period & TCLK_PERIOD_MASK) << TCLK_PERIOD_SHIFT |
+	  (etsects->cksel & CKSEL_MASK) << CKSEL_SHIFT;
+
+	spin_lock_irqsave(&etsects->lock, flags);
+
+	gfar_write(&etsects->regs->tmr_ctrl,   tmr_ctrl);
+	gfar_write(&etsects->regs->tmr_add,    etsects->tmr_add);
+	gfar_write(&etsects->regs->tmr_prsc,   etsects->tmr_prsc);
+	gfar_write(&etsects->regs->tmr_fiper1, etsects->tmr_fiper1);
+	gfar_write(&etsects->regs->tmr_fiper2, etsects->tmr_fiper2);
+	set_alarm(etsects);
+	gfar_write(&etsects->regs->tmr_ctrl,   tmr_ctrl|FS|RTPE|TE);
+
+	spin_unlock_irqrestore(&etsects->lock, flags);
+
+	etsects->clock = ptp_clock_register(&etsects->caps);
+	if (IS_ERR(etsects->clock)) {
+		err = PTR_ERR(etsects->clock);
+		goto no_clock;
+	}
+
+	dev_set_drvdata(&dev->dev, etsects);
+
+	return 0;
+
+no_clock:
+no_ioremap:
+	release_resource(etsects->rsrc);
+no_resource:
+	free_irq(etsects->irq, etsects);
+no_node:
+	kfree(etsects);
+no_memory:
+	return err;
+}
+
+static int gianfar_ptp_remove(struct platform_device *dev)
+{
+	struct etsects *etsects = dev_get_drvdata(&dev->dev);
+
+	gfar_write(&etsects->regs->tmr_temask, 0);
+	gfar_write(&etsects->regs->tmr_ctrl,   0);
+
+	ptp_clock_unregister(etsects->clock);
+	iounmap(etsects->regs);
+	release_resource(etsects->rsrc);
+	free_irq(etsects->irq, etsects);
+	kfree(etsects);
+
+	return 0;
+}
+
+static struct of_device_id match_table[] = {
+	{ .compatible = "fsl,etsec-ptp" },
+	{},
+};
+
+static struct platform_driver gianfar_ptp_driver = {
+	.driver = {
+		.name		= "gianfar_ptp",
+		.of_match_table	= match_table,
+		.owner		= THIS_MODULE,
+	},
+	.probe       = gianfar_ptp_probe,
+	.remove      = gianfar_ptp_remove,
+};
+
+/* module operations */
+
+static int __init ptp_gianfar_init(void)
+{
+	return platform_driver_register(&gianfar_ptp_driver);
+}
+
+module_init(ptp_gianfar_init);
+
+static void __exit ptp_gianfar_exit(void)
+{
+	platform_driver_unregister(&gianfar_ptp_driver);
+}
+
+module_exit(ptp_gianfar_exit);
+
+MODULE_AUTHOR("Richard Cochran <richard.cochran@omicron.at>");
+MODULE_DESCRIPTION("PTP clock using the eTSEC");
+MODULE_LICENSE("GPL");
diff -druN linux-2.6.39-libre/drivers/net/greth.c linux-3.0-rc7-libre/drivers/net/greth.c
--- linux-2.6.39-libre/drivers/net/greth.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/greth.c	2011-07-11 19:51:52.000000000 -0400
@@ -901,7 +901,7 @@
 
 				skb_put(skb, pkt_len);
 
-				if (greth->flags & GRETH_FLAG_RX_CSUM && hw_checksummed(status))
+				if (dev->features & NETIF_F_RXCSUM && hw_checksummed(status))
 					skb->ip_summed = CHECKSUM_UNNECESSARY;
 				else
 					skb_checksum_none_assert(skb);
@@ -1015,11 +1015,10 @@
 		return -EINVAL;
 
 	memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
+	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]);
 
-	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;
 }
 
@@ -1142,41 +1141,6 @@
 		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,
@@ -1185,10 +1149,6 @@
 	.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,
 };
 
@@ -1570,9 +1530,10 @@
 	GRETH_REGSAVE(regs->status, 0xFF);
 
 	if (greth->gbit_mac) {
-		dev->features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_HIGHDMA;
+		dev->hw_features = NETIF_F_SG | NETIF_F_IP_CSUM |
+			NETIF_F_RXCSUM;
+		dev->features = dev->hw_features | NETIF_F_HIGHDMA;
 		greth_netdev_ops.ndo_start_xmit = greth_start_xmit_gbit;
-		greth->flags = GRETH_FLAG_RX_CSUM;
 	}
 
 	if (greth->multicast) {
diff -druN linux-2.6.39-libre/drivers/net/greth.h linux-3.0-rc7-libre/drivers/net/greth.h
--- linux-2.6.39-libre/drivers/net/greth.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/greth.h	2011-07-11 19:51:52.000000000 -0400
@@ -77,9 +77,6 @@
  */
 #define MAX_FRAME_SIZE		1520
 
-/* Flags */
-#define GRETH_FLAG_RX_CSUM 0x1
-
 /* GRETH APB registers */
 struct greth_regs {
 	u32 control;
@@ -133,7 +130,6 @@
 	unsigned int duplex;
 
 	u32 msg_enable;
-	u32 flags;
 
 	u8 phyaddr;
 	u8 multicast;
diff -druN linux-2.6.39-libre/drivers/net/hamachi.c linux-3.0-rc7-libre/drivers/net/hamachi.c
--- linux-2.6.39-libre/drivers/net/hamachi.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/hamachi.c	2011-07-11 19:51:52.000000000 -0400
@@ -132,13 +132,8 @@
 /*
  * RX_CHECKSUM turns on card-generated receive checksum generation for
  *   TCP and UDP packets.  Otherwise the upper layers do the calculation.
- * TX_CHECKSUM won't do anything too useful, even if it works.  There's no
- *   easy mechanism by which to tell the TCP/UDP stack that it need not
- *   generate checksums for this device.  But if somebody can find a way
- *   to get that to work, most of the card work is in here already.
  * 3/10/1999 Pete Wyckoff <wyckoff@ca.sandia.gov>
  */
-#undef  TX_CHECKSUM
 #define RX_CHECKSUM
 
 /* Operational parameters that usually are not changed. */
@@ -630,11 +625,6 @@
 
 	SET_NETDEV_DEV(dev, &pdev->dev);
 
-#ifdef TX_CHECKSUM
-	printk("check that skbcopy in ip_queue_xmit isn't happening\n");
-	dev->hard_header_len += 8;  /* for cksum tag */
-#endif
-
 	for (i = 0; i < 6; i++)
 		dev->dev_addr[i] = 1 ? read_eeprom(ioaddr, 4 + i)
 			: readb(ioaddr + StationAddr + i);
@@ -937,11 +927,7 @@
 
 	/* always 1, takes no more time to do it */
 	writew(0x0001, ioaddr + RxChecksum);
-#ifdef TX_CHECKSUM
-	writew(0x0001, ioaddr + TxChecksum);
-#else
 	writew(0x0000, ioaddr + TxChecksum);
-#endif
 	writew(0x8000, ioaddr + MACCnfg); /* Soft reset the MAC */
 	writew(0x215F, ioaddr + MACCnfg);
 	writew(0x000C, ioaddr + FrameGap0);
@@ -1226,40 +1212,6 @@
 }
 
 
-#ifdef TX_CHECKSUM
-#define csum_add(it, val) \
-do { \
-    it += (u16) (val); \
-    if (it & 0xffff0000) { \
-	it &= 0xffff; \
-	++it; \
-    } \
-} while (0)
-    /* printk("add %04x --> %04x\n", val, it); \ */
-
-/* uh->len already network format, do not swap */
-#define pseudo_csum_udp(sum,ih,uh) do { \
-    sum = 0; \
-    csum_add(sum, (ih)->saddr >> 16); \
-    csum_add(sum, (ih)->saddr & 0xffff); \
-    csum_add(sum, (ih)->daddr >> 16); \
-    csum_add(sum, (ih)->daddr & 0xffff); \
-    csum_add(sum, cpu_to_be16(IPPROTO_UDP)); \
-    csum_add(sum, (uh)->len); \
-} while (0)
-
-/* swap len */
-#define pseudo_csum_tcp(sum,ih,len) do { \
-    sum = 0; \
-    csum_add(sum, (ih)->saddr >> 16); \
-    csum_add(sum, (ih)->saddr & 0xffff); \
-    csum_add(sum, (ih)->daddr >> 16); \
-    csum_add(sum, (ih)->daddr & 0xffff); \
-    csum_add(sum, cpu_to_be16(IPPROTO_TCP)); \
-    csum_add(sum, htons(len)); \
-} while (0)
-#endif
-
 static netdev_tx_t hamachi_start_xmit(struct sk_buff *skb,
 				      struct net_device *dev)
 {
@@ -1292,36 +1244,6 @@
 
 	hmp->tx_skbuff[entry] = skb;
 
-#ifdef TX_CHECKSUM
-	{
-	    /* tack on checksum tag */
-	    u32 tagval = 0;
-	    struct ethhdr *eh = (struct ethhdr *)skb->data;
-	    if (eh->h_proto == cpu_to_be16(ETH_P_IP)) {
-		struct iphdr *ih = (struct iphdr *)((char *)eh + ETH_HLEN);
-		if (ih->protocol == IPPROTO_UDP) {
-		    struct udphdr *uh
-		      = (struct udphdr *)((char *)ih + ih->ihl*4);
-		    u32 offset = ((unsigned char *)uh + 6) - skb->data;
-		    u32 pseudo;
-		    pseudo_csum_udp(pseudo, ih, uh);
-		    pseudo = htons(pseudo);
-		    printk("udp cksum was %04x, sending pseudo %04x\n",
-		      uh->check, pseudo);
-		    uh->check = 0;  /* zero out uh->check before card calc */
-		    /*
-		     * start at 14 (skip ethhdr), store at offset (uh->check),
-		     * use pseudo value given.
-		     */
-		    tagval = (14 << 24) | (offset << 16) | pseudo;
-		} else if (ih->protocol == IPPROTO_TCP) {
-		    printk("tcp, no auto cksum\n");
-		}
-	    }
-	    *(u32 *)skb_push(skb, 8) = tagval;
-	}
-#endif
-
         hmp->tx_ring[entry].addr = cpu_to_leXX(pci_map_single(hmp->pci_dev,
 		skb->data, skb->len, PCI_DMA_TODEVICE));
 
diff -druN linux-2.6.39-libre/drivers/net/hamradio/6pack.c linux-3.0-rc7-libre/drivers/net/hamradio/6pack.c
--- linux-2.6.39-libre/drivers/net/hamradio/6pack.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/hamradio/6pack.c	2011-07-11 19:51:52.000000000 -0400
@@ -692,10 +692,10 @@
 {
 	struct sixpack *sp;
 
-	write_lock(&disc_data_lock);
+	write_lock_bh(&disc_data_lock);
 	sp = tty->disc_data;
 	tty->disc_data = NULL;
-	write_unlock(&disc_data_lock);
+	write_unlock_bh(&disc_data_lock);
 	if (!sp)
 		return;
 
diff -druN linux-2.6.39-libre/drivers/net/hamradio/baycom_epp.c linux-3.0-rc7-libre/drivers/net/hamradio/baycom_epp.c
--- linux-2.6.39-libre/drivers/net/hamradio/baycom_epp.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/hamradio/baycom_epp.c	2011-07-11 19:51:52.000000000 -0400
@@ -69,7 +69,7 @@
 
 static const char bc_drvname[] = "baycom_epp";
 static const char bc_drvinfo[] = KERN_INFO "baycom_epp: (C) 1998-2000 Thomas Sailer, HB9JNX/AE4WA\n"
-"baycom_epp: version 0.7 compiled " __TIME__ " " __DATE__ "\n";
+"baycom_epp: version 0.7\n";
 
 /* --------------------------------------------------------------------- */
 
diff -druN linux-2.6.39-libre/drivers/net/hamradio/baycom_par.c linux-3.0-rc7-libre/drivers/net/hamradio/baycom_par.c
--- linux-2.6.39-libre/drivers/net/hamradio/baycom_par.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/hamradio/baycom_par.c	2011-07-11 19:51:52.000000000 -0400
@@ -102,7 +102,7 @@
 
 static const char bc_drvname[] = "baycom_par";
 static const char bc_drvinfo[] = KERN_INFO "baycom_par: (C) 1996-2000 Thomas Sailer, HB9JNX/AE4WA\n"
-"baycom_par: version 0.9 compiled " __TIME__ " " __DATE__ "\n";
+"baycom_par: version 0.9\n";
 
 /* --------------------------------------------------------------------- */
 
diff -druN linux-2.6.39-libre/drivers/net/hamradio/baycom_ser_fdx.c linux-3.0-rc7-libre/drivers/net/hamradio/baycom_ser_fdx.c
--- linux-2.6.39-libre/drivers/net/hamradio/baycom_ser_fdx.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/hamradio/baycom_ser_fdx.c	2011-07-11 19:51:52.000000000 -0400
@@ -92,7 +92,7 @@
 
 static const char bc_drvname[] = "baycom_ser_fdx";
 static const char bc_drvinfo[] = KERN_INFO "baycom_ser_fdx: (C) 1996-2000 Thomas Sailer, HB9JNX/AE4WA\n"
-"baycom_ser_fdx: version 0.10 compiled " __TIME__ " " __DATE__ "\n";
+"baycom_ser_fdx: version 0.10\n";
 
 /* --------------------------------------------------------------------- */
 
diff -druN linux-2.6.39-libre/drivers/net/hamradio/baycom_ser_hdx.c linux-3.0-rc7-libre/drivers/net/hamradio/baycom_ser_hdx.c
--- linux-2.6.39-libre/drivers/net/hamradio/baycom_ser_hdx.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/hamradio/baycom_ser_hdx.c	2011-07-11 19:51:52.000000000 -0400
@@ -80,7 +80,7 @@
 
 static const char bc_drvname[] = "baycom_ser_hdx";
 static const char bc_drvinfo[] = KERN_INFO "baycom_ser_hdx: (C) 1996-2000 Thomas Sailer, HB9JNX/AE4WA\n"
-"baycom_ser_hdx: version 0.10 compiled " __TIME__ " " __DATE__ "\n";
+"baycom_ser_hdx: version 0.10\n";
 
 /* --------------------------------------------------------------------- */
 
diff -druN linux-2.6.39-libre/drivers/net/hamradio/bpqether.c linux-3.0-rc7-libre/drivers/net/hamradio/bpqether.c
--- linux-2.6.39-libre/drivers/net/hamradio/bpqether.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/hamradio/bpqether.c	2011-07-11 19:51:52.000000000 -0400
@@ -516,10 +516,6 @@
 	memcpy(bpq->dest_addr, bcast_addr, sizeof(bpq_eth_addr));
 	memcpy(bpq->acpt_addr, bcast_addr, sizeof(bpq_eth_addr));
 
-	err = dev_alloc_name(ndev, ndev->name);
-	if (err < 0) 
-		goto error;
-
 	err = register_netdevice(ndev);
 	if (err)
 		goto error;
diff -druN linux-2.6.39-libre/drivers/net/hamradio/hdlcdrv.c linux-3.0-rc7-libre/drivers/net/hamradio/hdlcdrv.c
--- linux-2.6.39-libre/drivers/net/hamradio/hdlcdrv.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/hamradio/hdlcdrv.c	2011-07-11 19:51:52.000000000 -0400
@@ -749,7 +749,7 @@
 static int __init hdlcdrv_init_driver(void)
 {
 	printk(KERN_INFO "hdlcdrv: (C) 1996-2000 Thomas Sailer HB9JNX/AE4WA\n");
-	printk(KERN_INFO "hdlcdrv: version 0.8 compiled " __TIME__ " " __DATE__ "\n");
+	printk(KERN_INFO "hdlcdrv: version 0.8\n");
 	return 0;
 }
 
diff -druN linux-2.6.39-libre/drivers/net/hamradio/mkiss.c linux-3.0-rc7-libre/drivers/net/hamradio/mkiss.c
--- linux-2.6.39-libre/drivers/net/hamradio/mkiss.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/hamradio/mkiss.c	2011-07-11 19:51:52.000000000 -0400
@@ -813,10 +813,10 @@
 {
 	struct mkiss *ax;
 
-	write_lock(&disc_data_lock);
+	write_lock_bh(&disc_data_lock);
 	ax = tty->disc_data;
 	tty->disc_data = NULL;
-	write_unlock(&disc_data_lock);
+	write_unlock_bh(&disc_data_lock);
 
 	if (!ax)
 		return;
diff -druN linux-2.6.39-libre/drivers/net/hp100.c linux-3.0-rc7-libre/drivers/net/hp100.c
--- linux-2.6.39-libre/drivers/net/hp100.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/hp100.c	2011-07-11 19:51:52.000000000 -0400
@@ -1580,12 +1580,12 @@
 	hp100_outl(ringptr->pdl_paddr, TX_PDA_L);	/* Low Prio. Queue */
 
 	lp->txrcommit++;
-	spin_unlock_irqrestore(&lp->lock, flags);
 
-	/* Update statistics */
 	dev->stats.tx_packets++;
 	dev->stats.tx_bytes += skb->len;
 
+	spin_unlock_irqrestore(&lp->lock, flags);
+
 	return NETDEV_TX_OK;
 
 drop:
diff -druN linux-2.6.39-libre/drivers/net/hplance.c linux-3.0-rc7-libre/drivers/net/hplance.c
--- linux-2.6.39-libre/drivers/net/hplance.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/hplance.c	2011-07-11 19:51:52.000000000 -0400
@@ -135,7 +135,7 @@
 }
 
 /* Initialise a single lance board at the given DIO device */
-static void __init hplance_init(struct net_device *dev, struct dio_dev *d)
+static void __devinit hplance_init(struct net_device *dev, struct dio_dev *d)
 {
         unsigned long va = (d->resource.start + DIO_VIRADDRBASE);
         struct hplance_private *lp;
diff -druN linux-2.6.39-libre/drivers/net/ibmlana.c linux-3.0-rc7-libre/drivers/net/ibmlana.c
--- linux-2.6.39-libre/drivers/net/ibmlana.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/ibmlana.c	2011-07-11 19:51:52.000000000 -0400
@@ -782,7 +782,8 @@
 
 	/* register resources - only necessary for IRQ */
 
-	result = request_irq(priv->realirq, irq_handler, IRQF_SHARED | IRQF_SAMPLE_RANDOM, dev->name, dev);
+	result = request_irq(priv->realirq, irq_handler, IRQF_SHARED,
+			     dev->name, dev);
 	if (result != 0) {
 		printk(KERN_ERR "%s: failed to register irq %d\n", dev->name, dev->irq);
 		return result;
diff -druN linux-2.6.39-libre/drivers/net/ibm_newemac/core.c linux-3.0-rc7-libre/drivers/net/ibm_newemac/core.c
--- linux-2.6.39-libre/drivers/net/ibm_newemac/core.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/ibm_newemac/core.c	2011-07-11 19:51:52.000000000 -0400
@@ -2053,13 +2053,6 @@
 	mutex_unlock(&dev->link_lock);
 }
 
-static u32 emac_ethtool_get_rx_csum(struct net_device *ndev)
-{
-	struct emac_instance *dev = netdev_priv(ndev);
-
-	return dev->tah_dev != NULL;
-}
-
 static int emac_get_regs_len(struct emac_instance *dev)
 {
 	if (emac_has_feature(dev, EMAC_FTR_EMAC4))
@@ -2203,15 +2196,11 @@
 	.get_ringparam = emac_ethtool_get_ringparam,
 	.get_pauseparam = emac_ethtool_get_pauseparam,
 
-	.get_rx_csum = emac_ethtool_get_rx_csum,
-
 	.get_strings = emac_ethtool_get_strings,
 	.get_sset_count = emac_ethtool_get_sset_count,
 	.get_ethtool_stats = emac_ethtool_get_ethtool_stats,
 
 	.get_link = ethtool_op_get_link,
-	.get_tx_csum = ethtool_op_get_tx_csum,
-	.get_sg = ethtool_op_get_sg,
 };
 
 static int emac_ioctl(struct net_device *ndev, struct ifreq *rq, int cmd)
@@ -2859,8 +2848,10 @@
 	if (err != 0)
 		goto err_detach_tah;
 
-	if (dev->tah_dev)
-		ndev->features |= NETIF_F_IP_CSUM | NETIF_F_SG;
+	if (dev->tah_dev) {
+		ndev->hw_features = NETIF_F_IP_CSUM | NETIF_F_SG;
+		ndev->features |= ndev->hw_features | NETIF_F_RXCSUM;
+	}
 	ndev->watchdog_timeo = 5 * HZ;
 	if (emac_phy_supports_gige(dev->phy_mode)) {
 		ndev->netdev_ops = &emac_gige_netdev_ops;
diff -druN linux-2.6.39-libre/drivers/net/ibmveth.c linux-3.0-rc7-libre/drivers/net/ibmveth.c
--- linux-2.6.39-libre/drivers/net/ibmveth.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/ibmveth.c	2011-07-11 19:51:52.000000000 -0400
@@ -710,7 +710,7 @@
 				SUPPORTED_FIBRE);
 	cmd->advertising = (ADVERTISED_1000baseT_Full | ADVERTISED_Autoneg |
 				ADVERTISED_FIBRE);
-	cmd->speed = SPEED_1000;
+	ethtool_cmd_speed_set(cmd, SPEED_1000);
 	cmd->duplex = DUPLEX_FULL;
 	cmd->port = PORT_FIBRE;
 	cmd->phy_address = 0;
@@ -729,45 +729,24 @@
 		sizeof(info->version) - 1);
 }
 
-static void ibmveth_set_rx_csum_flags(struct net_device *dev, u32 data)
+static u32 ibmveth_fix_features(struct net_device *dev, u32 features)
 {
-	struct ibmveth_adapter *adapter = netdev_priv(dev);
-
-	if (data) {
-		adapter->rx_csum = 1;
-	} else {
-		/*
-		 * Since the ibmveth firmware interface does not have the
-		 * concept of separate tx/rx checksum offload enable, if rx
-		 * checksum is disabled we also have to disable tx checksum
-		 * offload. Once we disable rx checksum offload, we are no
-		 * longer allowed to send tx buffers that are not properly
-		 * checksummed.
-		 */
-		adapter->rx_csum = 0;
-		dev->features &= ~NETIF_F_IP_CSUM;
-		dev->features &= ~NETIF_F_IPV6_CSUM;
-	}
-}
+	/*
+	 * Since the ibmveth firmware interface does not have the
+	 * concept of separate tx/rx checksum offload enable, if rx
+	 * checksum is disabled we also have to disable tx checksum
+	 * offload. Once we disable rx checksum offload, we are no
+	 * longer allowed to send tx buffers that are not properly
+	 * checksummed.
+	 */
 
-static void ibmveth_set_tx_csum_flags(struct net_device *dev, u32 data)
-{
-	struct ibmveth_adapter *adapter = netdev_priv(dev);
+	if (!(features & NETIF_F_RXCSUM))
+		features &= ~NETIF_F_ALL_CSUM;
 
-	if (data) {
-		if (adapter->fw_ipv4_csum_support)
-			dev->features |= NETIF_F_IP_CSUM;
-		if (adapter->fw_ipv6_csum_support)
-			dev->features |= NETIF_F_IPV6_CSUM;
-		adapter->rx_csum = 1;
-	} else {
-		dev->features &= ~NETIF_F_IP_CSUM;
-		dev->features &= ~NETIF_F_IPV6_CSUM;
-	}
+	return features;
 }
 
-static int ibmveth_set_csum_offload(struct net_device *dev, u32 data,
-				    void (*done) (struct net_device *, u32))
+static int ibmveth_set_csum_offload(struct net_device *dev, u32 data)
 {
 	struct ibmveth_adapter *adapter = netdev_priv(dev);
 	unsigned long set_attr, clr_attr, ret_attr;
@@ -827,8 +806,8 @@
 		} else
 			adapter->fw_ipv6_csum_support = data;
 
-		if (ret == H_SUCCESS || ret6 == H_SUCCESS)
-			done(dev, data);
+		if (ret != H_SUCCESS || ret6 != H_SUCCESS)
+			adapter->rx_csum = data;
 		else
 			rc1 = -EIO;
 	} else {
@@ -844,41 +823,22 @@
 	return rc1 ? rc1 : rc2;
 }
 
-static int ibmveth_set_rx_csum(struct net_device *dev, u32 data)
-{
-	struct ibmveth_adapter *adapter = netdev_priv(dev);
-
-	if ((data && adapter->rx_csum) || (!data && !adapter->rx_csum))
-		return 0;
-
-	return ibmveth_set_csum_offload(dev, data, ibmveth_set_rx_csum_flags);
-}
-
-static int ibmveth_set_tx_csum(struct net_device *dev, u32 data)
+static int ibmveth_set_features(struct net_device *dev, u32 features)
 {
 	struct ibmveth_adapter *adapter = netdev_priv(dev);
-	int rc = 0;
+	int rx_csum = !!(features & NETIF_F_RXCSUM);
+	int rc;
 
-	if (data && (dev->features & (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM)))
-		return 0;
-	if (!data && !(dev->features & (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM)))
+	if (rx_csum == adapter->rx_csum)
 		return 0;
 
-	if (data && !adapter->rx_csum)
-		rc = ibmveth_set_csum_offload(dev, data,
-					      ibmveth_set_tx_csum_flags);
-	else
-		ibmveth_set_tx_csum_flags(dev, data);
+	rc = ibmveth_set_csum_offload(dev, rx_csum);
+	if (rc && !adapter->rx_csum)
+		dev->features = features & ~(NETIF_F_ALL_CSUM | NETIF_F_RXCSUM);
 
 	return rc;
 }
 
-static u32 ibmveth_get_rx_csum(struct net_device *dev)
-{
-	struct ibmveth_adapter *adapter = netdev_priv(dev);
-	return adapter->rx_csum;
-}
-
 static void ibmveth_get_strings(struct net_device *dev, u32 stringset, u8 *data)
 {
 	int i;
@@ -914,13 +874,9 @@
 	.get_drvinfo		= netdev_get_drvinfo,
 	.get_settings		= netdev_get_settings,
 	.get_link		= ethtool_op_get_link,
-	.set_tx_csum		= ibmveth_set_tx_csum,
-	.get_rx_csum		= ibmveth_get_rx_csum,
-	.set_rx_csum		= ibmveth_set_rx_csum,
 	.get_strings		= ibmveth_get_strings,
 	.get_sset_count		= ibmveth_get_sset_count,
 	.get_ethtool_stats	= ibmveth_get_ethtool_stats,
-	.set_sg			= ethtool_op_set_sg,
 };
 
 static int ibmveth_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
@@ -1345,6 +1301,8 @@
 	.ndo_set_multicast_list	= ibmveth_set_multicast_list,
 	.ndo_do_ioctl		= ibmveth_ioctl,
 	.ndo_change_mtu		= ibmveth_change_mtu,
+	.ndo_fix_features	= ibmveth_fix_features,
+	.ndo_set_features	= ibmveth_set_features,
 	.ndo_validate_addr	= eth_validate_addr,
 	.ndo_set_mac_address	= eth_mac_addr,
 #ifdef CONFIG_NET_POLL_CONTROLLER
@@ -1412,7 +1370,9 @@
 	netdev->netdev_ops = &ibmveth_netdev_ops;
 	netdev->ethtool_ops = &netdev_ethtool_ops;
 	SET_NETDEV_DEV(netdev, &dev->dev);
-	netdev->features |= NETIF_F_SG;
+	netdev->hw_features = NETIF_F_SG | NETIF_F_RXCSUM |
+		NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;
+	netdev->features |= netdev->hw_features;
 
 	memcpy(netdev->dev_addr, &adapter->mac_addr, netdev->addr_len);
 
@@ -1437,7 +1397,7 @@
 
 	netdev_dbg(netdev, "registering netdev...\n");
 
-	ibmveth_set_csum_offload(netdev, 1, ibmveth_set_tx_csum_flags);
+	ibmveth_set_features(netdev, netdev->features);
 
 	rc = register_netdev(netdev);
 
diff -druN linux-2.6.39-libre/drivers/net/ifb.c linux-3.0-rc7-libre/drivers/net/ifb.c
--- linux-2.6.39-libre/drivers/net/ifb.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/ifb.c	2011-07-11 19:51:52.000000000 -0400
@@ -233,10 +233,6 @@
 	if (!dev_ifb)
 		return -ENOMEM;
 
-	err = dev_alloc_name(dev_ifb, dev_ifb->name);
-	if (err < 0)
-		goto err;
-
 	dev_ifb->rtnl_link_ops = &ifb_link_ops;
 	err = register_netdevice(dev_ifb);
 	if (err < 0)
diff -druN linux-2.6.39-libre/drivers/net/igb/e1000_82575.c linux-3.0-rc7-libre/drivers/net/igb/e1000_82575.c
--- linux-2.6.39-libre/drivers/net/igb/e1000_82575.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/igb/e1000_82575.c	2011-07-11 19:51:52.000000000 -0400
@@ -244,6 +244,14 @@
 	 */
 	size += NVM_WORD_SIZE_BASE_SHIFT;
 
+	/*
+	 * Check for invalid size
+	 */
+	if ((hw->mac.type == e1000_82576) && (size > 15)) {
+		printk("igb: The NVM size is not valid, "
+			"defaulting to 32K.\n");
+		size = 15;
+	}
 	nvm->word_size = 1 << size;
 	if (nvm->word_size == (1 << 15))
 		nvm->page_size = 128;
@@ -1877,7 +1885,7 @@
 	}
 
 	if (nvm_data & NVM_COMPATIBILITY_BIT_MASK) {
-		/* if chekcsums compatibility bit is set validate checksums
+		/* if checksums compatibility bit is set validate checksums
 		 * for all 4 ports. */
 		eeprom_regions_count = 4;
 	}
@@ -1988,6 +1996,7 @@
 out:
 	return ret_val;
 }
+
 /**
  *  igb_set_eee_i350 - Enable/disable EEE support
  *  @hw: pointer to the HW structure
diff -druN linux-2.6.39-libre/drivers/net/igb/igb_ethtool.c linux-3.0-rc7-libre/drivers/net/igb/igb_ethtool.c
--- linux-2.6.39-libre/drivers/net/igb/igb_ethtool.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/igb/igb_ethtool.c	2011-07-11 19:51:52.000000000 -0400
@@ -178,11 +178,11 @@
 
 		if ((status & E1000_STATUS_SPEED_1000) ||
 		    hw->phy.media_type != e1000_media_type_copper)
-			ecmd->speed = SPEED_1000;
+			ethtool_cmd_speed_set(ecmd, SPEED_1000);
 		else if (status & E1000_STATUS_SPEED_100)
-			ecmd->speed = SPEED_100;
+			ethtool_cmd_speed_set(ecmd, SPEED_100);
 		else
-			ecmd->speed = SPEED_10;
+			ethtool_cmd_speed_set(ecmd, SPEED_10);
 
 		if ((status & E1000_STATUS_FD) ||
 		    hw->phy.media_type != e1000_media_type_copper)
@@ -190,7 +190,7 @@
 		else
 			ecmd->duplex = DUPLEX_HALF;
 	} else {
-		ecmd->speed = -1;
+		ethtool_cmd_speed_set(ecmd, -1);
 		ecmd->duplex = -1;
 	}
 
@@ -223,7 +223,8 @@
 		if (adapter->fc_autoneg)
 			hw->fc.requested_mode = e1000_fc_default;
 	} else {
-		if (igb_set_spd_dplx(adapter, ecmd->speed + ecmd->duplex)) {
+		u32 speed = ethtool_cmd_speed(ecmd);
+		if (igb_set_spd_dplx(adapter, speed, ecmd->duplex)) {
 			clear_bit(__IGB_RESETTING, &adapter->state);
 			return -EINVAL;
 		}
@@ -1963,27 +1964,28 @@
 /* bit defines for adapter->led_status */
 #define IGB_LED_ON		0
 
-static int igb_phys_id(struct net_device *netdev, u32 data)
+static int igb_set_phys_id(struct net_device *netdev,
+			   enum ethtool_phys_id_state state)
 {
 	struct igb_adapter *adapter = netdev_priv(netdev);
 	struct e1000_hw *hw = &adapter->hw;
-	unsigned long timeout;
-
-	timeout = data * 1000;
-
-	/*
-	 *  msleep_interruptable only accepts unsigned int so we are limited
-	 * in how long a duration we can wait
-	 */
-	if (!timeout || timeout > UINT_MAX)
-		timeout = UINT_MAX;
 
-	igb_blink_led(hw);
-	msleep_interruptible(timeout);
-
-	igb_led_off(hw);
-	clear_bit(IGB_LED_ON, &adapter->led_status);
-	igb_cleanup_led(hw);
+	switch (state) {
+	case ETHTOOL_ID_ACTIVE:
+		igb_blink_led(hw);
+		return 2;
+	case ETHTOOL_ID_ON:
+		igb_blink_led(hw);
+		break;
+	case ETHTOOL_ID_OFF:
+		igb_led_off(hw);
+		break;
+	case ETHTOOL_ID_INACTIVE:
+		igb_led_off(hw);
+		clear_bit(IGB_LED_ON, &adapter->led_status);
+		igb_cleanup_led(hw);
+		break;
+	}
 
 	return 0;
 }
@@ -2215,7 +2217,7 @@
 	.set_tso                = igb_set_tso,
 	.self_test              = igb_diag_test,
 	.get_strings            = igb_get_strings,
-	.phys_id                = igb_phys_id,
+	.set_phys_id            = igb_set_phys_id,
 	.get_sset_count         = igb_get_sset_count,
 	.get_ethtool_stats      = igb_get_ethtool_stats,
 	.get_coalesce           = igb_get_coalesce,
diff -druN linux-2.6.39-libre/drivers/net/igb/igb.h linux-3.0-rc7-libre/drivers/net/igb/igb.h
--- linux-2.6.39-libre/drivers/net/igb/igb.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/igb/igb.h	2011-07-11 19:51:52.000000000 -0400
@@ -360,7 +360,7 @@
 extern void igb_down(struct igb_adapter *);
 extern void igb_reinit_locked(struct igb_adapter *);
 extern void igb_reset(struct igb_adapter *);
-extern int igb_set_spd_dplx(struct igb_adapter *, u16);
+extern int igb_set_spd_dplx(struct igb_adapter *, u32, u8);
 extern int igb_setup_tx_resources(struct igb_ring *);
 extern int igb_setup_rx_resources(struct igb_ring *);
 extern void igb_free_tx_resources(struct igb_ring *);
diff -druN linux-2.6.39-libre/drivers/net/igb/igb_main.c linux-3.0-rc7-libre/drivers/net/igb/igb_main.c
--- linux-2.6.39-libre/drivers/net/igb/igb_main.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/igb/igb_main.c	2011-07-11 19:51:52.000000000 -0400
@@ -45,6 +45,7 @@
 #include <linux/interrupt.h>
 #include <linux/if_ether.h>
 #include <linux/aer.h>
+#include <linux/prefetch.h>
 #ifdef CONFIG_IGB_DCA
 #include <linux/dca.h>
 #endif
@@ -2372,6 +2373,9 @@
 	}
 #endif /* CONFIG_PCI_IOV */
 	adapter->rss_queues = min_t(u32, IGB_MAX_RX_QUEUES, num_online_cpus());
+	/* i350 cannot do RSS and SR-IOV at the same time */
+	if (hw->mac.type == e1000_i350 && adapter->vfs_allocated_count)
+		adapter->rss_queues = 1;
 
 	/*
 	 * if rss_queues > 4 or vfs are going to be allocated with rss_queues
@@ -3532,6 +3536,25 @@
 	return link_active;
 }
 
+static bool igb_thermal_sensor_event(struct e1000_hw *hw, u32 event)
+{
+	bool ret = false;
+	u32 ctrl_ext, thstat;
+
+	/* check for thermal sensor event on i350, copper only */
+	if (hw->mac.type == e1000_i350) {
+		thstat = rd32(E1000_THSTAT);
+		ctrl_ext = rd32(E1000_CTRL_EXT);
+
+		if ((hw->phy.media_type == e1000_media_type_copper) &&
+		    !(ctrl_ext & E1000_CTRL_EXT_LINK_MODE_SGMII)) {
+			ret = !!(thstat & event);
+		}
+	}
+
+	return ret;
+}
+
 /**
  * igb_watchdog - Timer Call-back
  * @data: pointer to adapter cast into an unsigned long
@@ -3550,7 +3573,7 @@
                                                    watchdog_task);
 	struct e1000_hw *hw = &adapter->hw;
 	struct net_device *netdev = adapter->netdev;
-	u32 link, ctrl_ext, thstat;
+	u32 link;
 	int i;
 
 	link = igb_has_link(adapter);
@@ -3574,25 +3597,14 @@
 			       ((ctrl & E1000_CTRL_RFCE) ?  "RX" :
 			       ((ctrl & E1000_CTRL_TFCE) ?  "TX" : "None")));
 
-			/* check for thermal sensor event on i350,
-			 * copper only */
-			if (hw->mac.type == e1000_i350) {
-				thstat = rd32(E1000_THSTAT);
-				ctrl_ext = rd32(E1000_CTRL_EXT);
-				if ((hw->phy.media_type ==
-				     e1000_media_type_copper) && !(ctrl_ext &
-				     E1000_CTRL_EXT_LINK_MODE_SGMII)) {
-					if (thstat &
-					    E1000_THSTAT_LINK_THROTTLE) {
-						printk(KERN_INFO "igb: %s The "
-						       "network adapter link "
-						       "speed was downshifted "
-						       "because it "
-						       "overheated.\n",
-						       netdev->name);
-					}
-				}
+			/* check for thermal sensor event */
+			if (igb_thermal_sensor_event(hw, E1000_THSTAT_LINK_THROTTLE)) {
+				printk(KERN_INFO "igb: %s The network adapter "
+						 "link speed was downshifted "
+						 "because it overheated.\n",
+						 netdev->name);
 			}
+
 			/* adjust timeout factor according to speed/duplex */
 			adapter->tx_timeout_factor = 1;
 			switch (adapter->link_speed) {
@@ -3618,22 +3630,15 @@
 		if (netif_carrier_ok(netdev)) {
 			adapter->link_speed = 0;
 			adapter->link_duplex = 0;
-			/* check for thermal sensor event on i350
-			 * copper only*/
-			if (hw->mac.type == e1000_i350) {
-				thstat = rd32(E1000_THSTAT);
-				ctrl_ext = rd32(E1000_CTRL_EXT);
-				if ((hw->phy.media_type ==
-				     e1000_media_type_copper) && !(ctrl_ext &
-				     E1000_CTRL_EXT_LINK_MODE_SGMII)) {
-					if (thstat & E1000_THSTAT_PWR_DOWN) {
-						printk(KERN_ERR "igb: %s The "
-						"network adapter was stopped "
-						"because it overheated.\n",
+
+			/* check for thermal sensor event */
+			if (igb_thermal_sensor_event(hw, E1000_THSTAT_PWR_DOWN)) {
+				printk(KERN_ERR "igb: %s The network adapter "
+						"was stopped because it "
+						"overheated.\n",
 						netdev->name);
-					}
-				}
 			}
+
 			/* Links status message must follow this format */
 			printk(KERN_INFO "igb: %s NIC Link is Down\n",
 			       netdev->name);
@@ -6348,21 +6353,25 @@
 	}
 }
 
-int igb_set_spd_dplx(struct igb_adapter *adapter, u16 spddplx)
+int igb_set_spd_dplx(struct igb_adapter *adapter, u32 spd, u8 dplx)
 {
 	struct pci_dev *pdev = adapter->pdev;
 	struct e1000_mac_info *mac = &adapter->hw.mac;
 
 	mac->autoneg = 0;
 
+	/* Make sure dplx is at most 1 bit and lsb of speed is not set
+	 * for the switch() below to work */
+	if ((spd & 1) || (dplx & ~1))
+		goto err_inval;
+
 	/* Fiber NIC's only allow 1000 Gbps Full duplex */
 	if ((adapter->hw.phy.media_type == e1000_media_type_internal_serdes) &&
-		spddplx != (SPEED_1000 + DUPLEX_FULL)) {
-		dev_err(&pdev->dev, "Unsupported Speed/Duplex configuration\n");
-		return -EINVAL;
-	}
+	    spd != SPEED_1000 &&
+	    dplx != DUPLEX_FULL)
+		goto err_inval;
 
-	switch (spddplx) {
+	switch (spd + dplx) {
 	case SPEED_10 + DUPLEX_HALF:
 		mac->forced_speed_duplex = ADVERTISE_10_HALF;
 		break;
@@ -6381,10 +6390,13 @@
 		break;
 	case SPEED_1000 + DUPLEX_HALF: /* not supported */
 	default:
-		dev_err(&pdev->dev, "Unsupported Speed/Duplex configuration\n");
-		return -EINVAL;
+		goto err_inval;
 	}
 	return 0;
+
+err_inval:
+	dev_err(&pdev->dev, "Unsupported Speed/Duplex configuration\n");
+	return -EINVAL;
 }
 
 static int __igb_shutdown(struct pci_dev *pdev, bool *enable_wake)
diff -druN linux-2.6.39-libre/drivers/net/igbvf/ethtool.c linux-3.0-rc7-libre/drivers/net/igbvf/ethtool.c
--- linux-2.6.39-libre/drivers/net/igbvf/ethtool.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/igbvf/ethtool.c	2011-07-11 19:51:52.000000000 -0400
@@ -90,18 +90,18 @@
 	status = er32(STATUS);
 	if (status & E1000_STATUS_LU) {
 		if (status & E1000_STATUS_SPEED_1000)
-			ecmd->speed = 1000;
+			ethtool_cmd_speed_set(ecmd, SPEED_1000);
 		else if (status & E1000_STATUS_SPEED_100)
-			ecmd->speed = 100;
+			ethtool_cmd_speed_set(ecmd, SPEED_100);
 		else
-			ecmd->speed = 10;
+			ethtool_cmd_speed_set(ecmd, SPEED_10);
 
 		if (status & E1000_STATUS_FD)
 			ecmd->duplex = DUPLEX_FULL;
 		else
 			ecmd->duplex = DUPLEX_HALF;
 	} else {
-		ecmd->speed = -1;
+		ethtool_cmd_speed_set(ecmd, -1);
 		ecmd->duplex = -1;
 	}
 
@@ -391,11 +391,6 @@
 	return -EOPNOTSUPP;
 }
 
-static int igbvf_phys_id(struct net_device *netdev, u32 data)
-{
-	return 0;
-}
-
 static int igbvf_get_coalesce(struct net_device *netdev,
                               struct ethtool_coalesce *ec)
 {
@@ -527,7 +522,6 @@
 	.self_test		= igbvf_diag_test,
 	.get_sset_count		= igbvf_get_sset_count,
 	.get_strings		= igbvf_get_strings,
-	.phys_id		= igbvf_phys_id,
 	.get_ethtool_stats	= igbvf_get_ethtool_stats,
 	.get_coalesce		= igbvf_get_coalesce,
 	.set_coalesce		= igbvf_set_coalesce,
diff -druN linux-2.6.39-libre/drivers/net/igbvf/netdev.c linux-3.0-rc7-libre/drivers/net/igbvf/netdev.c
--- linux-2.6.39-libre/drivers/net/igbvf/netdev.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/igbvf/netdev.c	2011-07-11 19:51:52.000000000 -0400
@@ -41,6 +41,7 @@
 #include <linux/mii.h>
 #include <linux/ethtool.h>
 #include <linux/if_vlan.h>
+#include <linux/prefetch.h>
 
 #include "igbvf.h"
 
diff -druN linux-2.6.39-libre/drivers/net/ioc3-eth.c linux-3.0-rc7-libre/drivers/net/ioc3-eth.c
--- linux-2.6.39-libre/drivers/net/ioc3-eth.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/ioc3-eth.c	2011-07-11 19:51:52.000000000 -0400
@@ -90,8 +90,6 @@
 	u32 emcr, ehar_h, ehar_l;
 	spinlock_t ioc3_lock;
 	struct mii_if_info mii;
-	unsigned long flags;
-#define IOC3_FLAG_RX_CHECKSUMS	1
 
 	struct pci_dev *pdev;
 
@@ -609,7 +607,7 @@
 				goto next;
 			}
 
-			if (likely(ip->flags & IOC3_FLAG_RX_CHECKSUMS))
+			if (likely(dev->features & NETIF_F_RXCSUM))
 				ioc3_tcpudp_checksum(skb,
 					w0 & ERXBUF_IPCKSUM_MASK, len);
 
@@ -917,7 +915,7 @@
 
 			skb = ioc3_alloc_skb(RX_BUF_ALLOC_SIZE, GFP_ATOMIC);
 			if (!skb) {
-				show_free_areas();
+				show_free_areas(0);
 				continue;
 			}
 
@@ -1328,6 +1326,7 @@
 	dev->watchdog_timeo	= 5 * HZ;
 	dev->netdev_ops		= &ioc3_netdev_ops;
 	dev->ethtool_ops	= &ioc3_ethtool_ops;
+	dev->hw_features	= NETIF_F_IP_CSUM | NETIF_F_RXCSUM;
 	dev->features		= NETIF_F_IP_CSUM;
 
 	sw_physid1 = ioc3_mdio_read(dev, ip->mii.phy_id, MII_PHYSID1);
@@ -1618,37 +1617,12 @@
 	return rc;
 }
 
-static u32 ioc3_get_rx_csum(struct net_device *dev)
-{
-	struct ioc3_private *ip = netdev_priv(dev);
-
-	return ip->flags & IOC3_FLAG_RX_CHECKSUMS;
-}
-
-static int ioc3_set_rx_csum(struct net_device *dev, u32 data)
-{
-	struct ioc3_private *ip = netdev_priv(dev);
-
-	spin_lock_bh(&ip->ioc3_lock);
-	if (data)
-		ip->flags |= IOC3_FLAG_RX_CHECKSUMS;
-	else
-		ip->flags &= ~IOC3_FLAG_RX_CHECKSUMS;
-	spin_unlock_bh(&ip->ioc3_lock);
-
-	return 0;
-}
-
 static const struct ethtool_ops ioc3_ethtool_ops = {
 	.get_drvinfo		= ioc3_get_drvinfo,
 	.get_settings		= ioc3_get_settings,
 	.set_settings		= ioc3_set_settings,
 	.nway_reset		= ioc3_nway_reset,
 	.get_link		= ioc3_get_link,
-	.get_rx_csum		= ioc3_get_rx_csum,
-	.set_rx_csum		= ioc3_set_rx_csum,
-	.get_tx_csum		= ethtool_op_get_tx_csum,
-	.set_tx_csum		= ethtool_op_set_tx_csum
 };
 
 static int ioc3_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
diff -druN linux-2.6.39-libre/drivers/net/irda/ali-ircc.c linux-3.0-rc7-libre/drivers/net/irda/ali-ircc.c
--- linux-2.6.39-libre/drivers/net/irda/ali-ircc.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/irda/ali-ircc.c	2011-07-11 19:51:52.000000000 -0400
@@ -1800,7 +1800,7 @@
 	MessageCount = inb(iobase+ FIR_LSR)&0x07;
 	
 	if (MessageCount > 0)	
-		IRDA_DEBUG(0, "%s(), Messsage count = %d,\n", __func__ , MessageCount);
+		IRDA_DEBUG(0, "%s(), Message count = %d,\n", __func__ , MessageCount);
 		
 	for (i=0; i<=MessageCount; i++)
 	{
diff -druN linux-2.6.39-libre/drivers/net/irda/bfin_sir.c linux-3.0-rc7-libre/drivers/net/irda/bfin_sir.c
--- linux-2.6.39-libre/drivers/net/irda/bfin_sir.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/irda/bfin_sir.c	2011-07-11 19:51:52.000000000 -0400
@@ -67,27 +67,27 @@
 	disable_dma(port->tx_dma_channel);
 #endif
 
-	while (!(SIR_UART_GET_LSR(port) & THRE)) {
+	while (!(UART_GET_LSR(port) & THRE)) {
 		cpu_relax();
 		continue;
 	}
 
-	SIR_UART_STOP_TX(port);
+	UART_CLEAR_IER(port, ETBEI);
 }
 
 static void bfin_sir_enable_tx(struct bfin_sir_port *port)
 {
-	SIR_UART_ENABLE_TX(port);
+	UART_SET_IER(port, ETBEI);
 }
 
 static void bfin_sir_stop_rx(struct bfin_sir_port *port)
 {
-	SIR_UART_STOP_RX(port);
+	UART_CLEAR_IER(port, ERBFI);
 }
 
 static void bfin_sir_enable_rx(struct bfin_sir_port *port)
 {
-	SIR_UART_ENABLE_RX(port);
+	UART_SET_IER(port, ERBFI);
 }
 
 static int bfin_sir_set_speed(struct bfin_sir_port *port, int speed)
@@ -116,7 +116,7 @@
 
 		do {
 			udelay(utime);
-			lsr = SIR_UART_GET_LSR(port);
+			lsr = UART_GET_LSR(port);
 		} while (!(lsr & TEMT) && count--);
 
 		/* The useconds for 1 bits to transmit */
@@ -125,27 +125,27 @@
 		/* Clear UCEN bit to reset the UART state machine
 		 * and control registers
 		 */
-		val = SIR_UART_GET_GCTL(port);
+		val = UART_GET_GCTL(port);
 		val &= ~UCEN;
-		SIR_UART_PUT_GCTL(port, val);
+		UART_PUT_GCTL(port, val);
 
 		/* Set DLAB in LCR to Access THR RBR IER */
-		SIR_UART_SET_DLAB(port);
+		UART_SET_DLAB(port);
 		SSYNC();
 
-		SIR_UART_PUT_DLL(port, quot & 0xFF);
-		SIR_UART_PUT_DLH(port, (quot >> 8) & 0xFF);
+		UART_PUT_DLL(port, quot & 0xFF);
+		UART_PUT_DLH(port, (quot >> 8) & 0xFF);
 		SSYNC();
 
 		/* Clear DLAB in LCR */
-		SIR_UART_CLEAR_DLAB(port);
+		UART_CLEAR_DLAB(port);
 		SSYNC();
 
-		SIR_UART_PUT_LCR(port, lcr);
+		UART_PUT_LCR(port, lcr);
 
-		val = SIR_UART_GET_GCTL(port);
+		val = UART_GET_GCTL(port);
 		val |= UCEN;
-		SIR_UART_PUT_GCTL(port, val);
+		UART_PUT_GCTL(port, val);
 
 		ret = 0;
 		break;
@@ -154,12 +154,12 @@
 		break;
 	}
 
-	val = SIR_UART_GET_GCTL(port);
+	val = UART_GET_GCTL(port);
 	/* If not add the 'RPOLC', we can't catch the receive interrupt.
 	 * It's related with the HW layout and the IR transiver.
 	 */
 	val |= IREN | RPOLC;
-	SIR_UART_PUT_GCTL(port, val);
+	UART_PUT_GCTL(port, val);
 	return ret;
 }
 
@@ -168,7 +168,7 @@
 	struct bfin_sir_self *self = netdev_priv(dev);
 	struct bfin_sir_port *port = self->sir_port;
 
-	if (!(SIR_UART_GET_IER(port) & ERBFI))
+	if (!(UART_GET_IER(port) & ERBFI))
 		return 0;
 	return self->rx_buff.state != OUTSIDE_FRAME;
 }
@@ -182,7 +182,7 @@
 
 	if (self->tx_buff.len != 0) {
 		chr = *(self->tx_buff.data);
-		SIR_UART_PUT_CHAR(port, chr);
+		UART_PUT_CHAR(port, chr);
 		self->tx_buff.data++;
 		self->tx_buff.len--;
 	} else {
@@ -206,8 +206,8 @@
 	struct bfin_sir_port *port = self->sir_port;
 	unsigned char ch;
 
-	SIR_UART_CLEAR_LSR(port);
-	ch = SIR_UART_GET_CHAR(port);
+	UART_CLEAR_LSR(port);
+	ch = UART_GET_CHAR(port);
 	async_unwrap_char(dev, &self->stats, &self->rx_buff, ch);
 	dev->last_rx = jiffies;
 }
@@ -219,7 +219,7 @@
 	struct bfin_sir_port *port = self->sir_port;
 
 	spin_lock(&self->lock);
-	while ((SIR_UART_GET_LSR(port) & DR))
+	while ((UART_GET_LSR(port) & DR))
 		bfin_sir_rx_chars(dev);
 	spin_unlock(&self->lock);
 
@@ -233,7 +233,7 @@
 	struct bfin_sir_port *port = self->sir_port;
 
 	spin_lock(&self->lock);
-	if (SIR_UART_GET_LSR(port) & THRE)
+	if (UART_GET_LSR(port) & THRE)
 		bfin_sir_tx_chars(dev);
 	spin_unlock(&self->lock);
 
@@ -312,7 +312,7 @@
 	struct bfin_sir_port *port = self->sir_port;
 	int i;
 
-	SIR_UART_CLEAR_LSR(port);
+	UART_CLEAR_LSR(port);
 
 	for (i = port->rx_dma_buf.head; i < port->rx_dma_buf.tail; i++)
 		async_unwrap_char(dev, &self->stats, &self->rx_buff, port->rx_dma_buf.buf[i]);
@@ -430,11 +430,10 @@
 	unsigned short val;
 
 	bfin_sir_stop_rx(port);
-	SIR_UART_DISABLE_INTS(port);
 
-	val = SIR_UART_GET_GCTL(port);
+	val = UART_GET_GCTL(port);
 	val &= ~(UCEN | IREN | RPOLC);
-	SIR_UART_PUT_GCTL(port, val);
+	UART_PUT_GCTL(port, val);
 
 #ifdef CONFIG_SIR_BFIN_DMA
 	disable_dma(port->tx_dma_channel);
@@ -518,12 +517,12 @@
 	 * sending data. We also can set the speed, which will
 	 * reset all the UART.
 	 */
-	val = SIR_UART_GET_GCTL(port);
+	val = UART_GET_GCTL(port);
 	val &= ~(IREN | RPOLC);
-	SIR_UART_PUT_GCTL(port, val);
+	UART_PUT_GCTL(port, val);
 	SSYNC();
 	val |= IREN | RPOLC;
-	SIR_UART_PUT_GCTL(port, val);
+	UART_PUT_GCTL(port, val);
 	SSYNC();
 	/* bfin_sir_set_speed(port, self->speed); */
 
diff -druN linux-2.6.39-libre/drivers/net/irda/bfin_sir.h linux-3.0-rc7-libre/drivers/net/irda/bfin_sir.h
--- linux-2.6.39-libre/drivers/net/irda/bfin_sir.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/irda/bfin_sir.h	2011-07-11 19:51:52.000000000 -0400
@@ -26,7 +26,6 @@
 #include <asm/cacheflush.h>
 #include <asm/dma.h>
 #include <asm/portmux.h>
-#include <mach/bfin_serial_5xx.h>
 #undef DRIVER_NAME
 
 #ifdef CONFIG_SIR_BFIN_DMA
@@ -83,64 +82,10 @@
 
 #define DRIVER_NAME "bfin_sir"
 
-#define SIR_UART_GET_CHAR(port)    bfin_read16((port)->membase + OFFSET_RBR)
-#define SIR_UART_GET_DLL(port)     bfin_read16((port)->membase + OFFSET_DLL)
-#define SIR_UART_GET_DLH(port)     bfin_read16((port)->membase + OFFSET_DLH)
-#define SIR_UART_GET_LCR(port)     bfin_read16((port)->membase + OFFSET_LCR)
-#define SIR_UART_GET_GCTL(port)    bfin_read16((port)->membase + OFFSET_GCTL)
-
-#define SIR_UART_PUT_CHAR(port, v) bfin_write16(((port)->membase + OFFSET_THR), v)
-#define SIR_UART_PUT_DLL(port, v)  bfin_write16(((port)->membase + OFFSET_DLL), v)
-#define SIR_UART_PUT_DLH(port, v)  bfin_write16(((port)->membase + OFFSET_DLH), v)
-#define SIR_UART_PUT_LCR(port, v)  bfin_write16(((port)->membase + OFFSET_LCR), v)
-#define SIR_UART_PUT_GCTL(port, v) bfin_write16(((port)->membase + OFFSET_GCTL), v)
-
-#ifdef CONFIG_BF54x
-#define SIR_UART_GET_LSR(port)     bfin_read16((port)->membase + OFFSET_LSR)
-#define SIR_UART_GET_IER(port)     bfin_read16((port)->membase + OFFSET_IER_SET)
-#define SIR_UART_SET_IER(port, v)  bfin_write16(((port)->membase + OFFSET_IER_SET), v)
-#define SIR_UART_CLEAR_IER(port, v) bfin_write16(((port)->membase + OFFSET_IER_CLEAR), v)
-#define SIR_UART_PUT_LSR(port, v)  bfin_write16(((port)->membase + OFFSET_LSR), v)
-#define SIR_UART_CLEAR_LSR(port)   bfin_write16(((port)->membase + OFFSET_LSR), -1)
-
-#define SIR_UART_SET_DLAB(port)
-#define SIR_UART_CLEAR_DLAB(port)
-
-#define SIR_UART_ENABLE_INTS(port, v) SIR_UART_SET_IER(port, v)
-#define SIR_UART_DISABLE_INTS(port)   SIR_UART_CLEAR_IER(port, 0xF)
-#define SIR_UART_STOP_TX(port)     do { SIR_UART_PUT_LSR(port, TFI); SIR_UART_CLEAR_IER(port, ETBEI); } while (0)
-#define SIR_UART_ENABLE_TX(port)   do { SIR_UART_SET_IER(port, ETBEI); } while (0)
-#define SIR_UART_STOP_RX(port)     do { SIR_UART_CLEAR_IER(port, ERBFI); } while (0)
-#define SIR_UART_ENABLE_RX(port)   do { SIR_UART_SET_IER(port, ERBFI); } while (0)
-#else
-
-#define SIR_UART_GET_IIR(port)     bfin_read16((port)->membase + OFFSET_IIR)
-#define SIR_UART_GET_IER(port)     bfin_read16((port)->membase + OFFSET_IER)
-#define SIR_UART_PUT_IER(port, v)  bfin_write16(((port)->membase + OFFSET_IER), v)
-
-#define SIR_UART_SET_DLAB(port)    do { SIR_UART_PUT_LCR(port, SIR_UART_GET_LCR(port) | DLAB); } while (0)
-#define SIR_UART_CLEAR_DLAB(port)  do { SIR_UART_PUT_LCR(port, SIR_UART_GET_LCR(port) & ~DLAB); } while (0)
-
-#define SIR_UART_ENABLE_INTS(port, v) SIR_UART_PUT_IER(port, v)
-#define SIR_UART_DISABLE_INTS(port)   SIR_UART_PUT_IER(port, 0)
-#define SIR_UART_STOP_TX(port)     do { SIR_UART_PUT_IER(port, SIR_UART_GET_IER(port) & ~ETBEI); } while (0)
-#define SIR_UART_ENABLE_TX(port)   do { SIR_UART_PUT_IER(port, SIR_UART_GET_IER(port) | ETBEI); } while (0)
-#define SIR_UART_STOP_RX(port)     do { SIR_UART_PUT_IER(port, SIR_UART_GET_IER(port) & ~ERBFI); } while (0)
-#define SIR_UART_ENABLE_RX(port)   do { SIR_UART_PUT_IER(port, SIR_UART_GET_IER(port) | ERBFI); } while (0)
-
-static inline unsigned int SIR_UART_GET_LSR(struct bfin_sir_port *port)
-{
-	unsigned int lsr = bfin_read16(port->membase + OFFSET_LSR);
-	port->lsr |= (lsr & (BI|FE|PE|OE));
-	return lsr | port->lsr;
-}
-
-static inline void SIR_UART_CLEAR_LSR(struct bfin_sir_port *port)
-{
-	port->lsr = 0;
-	bfin_read16(port->membase + OFFSET_LSR);
-}
-#endif
+#define port_membase(port)     (((struct bfin_sir_port *)(port))->membase)
+#define get_lsr_cache(port)    (((struct bfin_sir_port *)(port))->lsr)
+#define put_lsr_cache(port, v) (((struct bfin_sir_port *)(port))->lsr = (v))
+#include <asm/bfin_serial.h>
 
 static const unsigned short per[][4] = {
 	/* rx pin      tx pin     NULL  uart_number */
diff -druN linux-2.6.39-libre/drivers/net/ixgb/ixgb_ethtool.c linux-3.0-rc7-libre/drivers/net/ixgb/ixgb_ethtool.c
--- linux-2.6.39-libre/drivers/net/ixgb/ixgb_ethtool.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/ixgb/ixgb_ethtool.c	2011-07-11 19:51:52.000000000 -0400
@@ -104,10 +104,10 @@
 	ecmd->transceiver = XCVR_EXTERNAL;
 
 	if (netif_carrier_ok(adapter->netdev)) {
-		ecmd->speed = SPEED_10000;
+		ethtool_cmd_speed_set(ecmd, SPEED_10000);
 		ecmd->duplex = DUPLEX_FULL;
 	} else {
-		ecmd->speed = -1;
+		ethtool_cmd_speed_set(ecmd, -1);
 		ecmd->duplex = -1;
 	}
 
@@ -129,9 +129,10 @@
 ixgb_set_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
 {
 	struct ixgb_adapter *adapter = netdev_priv(netdev);
+	u32 speed = ethtool_cmd_speed(ecmd);
 
 	if (ecmd->autoneg == AUTONEG_ENABLE ||
-	   ecmd->speed + ecmd->duplex != SPEED_10000 + DUPLEX_FULL)
+	    (speed + ecmd->duplex != SPEED_10000 + DUPLEX_FULL))
 		return -EINVAL;
 
 	if (netif_running(adapter->netdev)) {
@@ -610,45 +611,23 @@
 	return err;
 }
 
-/* toggle LED 4 times per second = 2 "blinks" per second */
-#define IXGB_ID_INTERVAL	(HZ/4)
-
-/* bit defines for adapter->led_status */
-#define IXGB_LED_ON		0
-
-static void
-ixgb_led_blink_callback(unsigned long data)
-{
-	struct ixgb_adapter *adapter = (struct ixgb_adapter *)data;
-
-	if (test_and_change_bit(IXGB_LED_ON, &adapter->led_status))
-		ixgb_led_off(&adapter->hw);
-	else
-		ixgb_led_on(&adapter->hw);
-
-	mod_timer(&adapter->blink_timer, jiffies + IXGB_ID_INTERVAL);
-}
-
 static int
-ixgb_phys_id(struct net_device *netdev, u32 data)
+ixgb_set_phys_id(struct net_device *netdev, enum ethtool_phys_id_state state)
 {
 	struct ixgb_adapter *adapter = netdev_priv(netdev);
 
-	if (!data)
-		data = INT_MAX;
-
-	if (!adapter->blink_timer.function) {
-		init_timer(&adapter->blink_timer);
-		adapter->blink_timer.function = ixgb_led_blink_callback;
-		adapter->blink_timer.data = (unsigned long)adapter;
-	}
+	switch (state) {
+	case ETHTOOL_ID_ACTIVE:
+		return 2;
 
-	mod_timer(&adapter->blink_timer, jiffies);
+	case ETHTOOL_ID_ON:
+		ixgb_led_on(&adapter->hw);
+		break;
 
-	msleep_interruptible(data * 1000);
-	del_timer_sync(&adapter->blink_timer);
-	ixgb_led_off(&adapter->hw);
-	clear_bit(IXGB_LED_ON, &adapter->led_status);
+	case ETHTOOL_ID_OFF:
+	case ETHTOOL_ID_INACTIVE:
+		ixgb_led_off(&adapter->hw);
+	}
 
 	return 0;
 }
@@ -766,7 +745,7 @@
 	.set_msglevel = ixgb_set_msglevel,
 	.set_tso = ixgb_set_tso,
 	.get_strings = ixgb_get_strings,
-	.phys_id = ixgb_phys_id,
+	.set_phys_id = ixgb_set_phys_id,
 	.get_sset_count = ixgb_get_sset_count,
 	.get_ethtool_stats = ixgb_get_ethtool_stats,
 	.get_flags = ethtool_op_get_flags,
diff -druN linux-2.6.39-libre/drivers/net/ixgb/ixgb.h linux-3.0-rc7-libre/drivers/net/ixgb/ixgb.h
--- linux-2.6.39-libre/drivers/net/ixgb/ixgb.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/ixgb/ixgb.h	2011-07-11 19:51:52.000000000 -0400
@@ -157,9 +157,6 @@
 	u16 link_duplex;
 	struct work_struct tx_timeout_task;
 
-	struct timer_list blink_timer;
-	unsigned long led_status;
-
 	/* TX */
 	struct ixgb_desc_ring tx_ring ____cacheline_aligned_in_smp;
 	unsigned int restart_queue;
diff -druN linux-2.6.39-libre/drivers/net/ixgb/ixgb_main.c linux-3.0-rc7-libre/drivers/net/ixgb/ixgb_main.c
--- linux-2.6.39-libre/drivers/net/ixgb/ixgb_main.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/ixgb/ixgb_main.c	2011-07-11 19:51:52.000000000 -0400
@@ -28,6 +28,7 @@
 
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 
+#include <linux/prefetch.h>
 #include "ixgb.h"
 
 char ixgb_driver_name[] = "ixgb";
diff -druN linux-2.6.39-libre/drivers/net/ixgbe/ixgbe_82598.c linux-3.0-rc7-libre/drivers/net/ixgbe/ixgbe_82598.c
--- linux-2.6.39-libre/drivers/net/ixgbe/ixgbe_82598.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/ixgbe/ixgbe_82598.c	2011-07-11 19:51:52.000000000 -0400
@@ -37,6 +37,7 @@
 #define IXGBE_82598_RAR_ENTRIES   16
 #define IXGBE_82598_MC_TBL_SIZE  128
 #define IXGBE_82598_VFT_TBL_SIZE 128
+#define IXGBE_82598_RX_PB_SIZE	 512
 
 static s32 ixgbe_setup_copper_link_82598(struct ixgbe_hw *hw,
                                          ixgbe_link_speed speed,
@@ -197,14 +198,35 @@
  *  @hw: pointer to hardware structure
  *
  *  Starts the hardware using the generic start_hw function.
- *  Then set pcie completion timeout
+ *  Disables relaxed ordering Then set pcie completion timeout
+ *
  **/
 static s32 ixgbe_start_hw_82598(struct ixgbe_hw *hw)
 {
+	u32 regval;
+	u32 i;
 	s32 ret_val = 0;
 
 	ret_val = ixgbe_start_hw_generic(hw);
 
+	/* Disable relaxed ordering */
+	for (i = 0; ((i < hw->mac.max_tx_queues) &&
+	     (i < IXGBE_DCA_MAX_QUEUES_82598)); i++) {
+		regval = IXGBE_READ_REG(hw, IXGBE_DCA_TXCTRL(i));
+		regval &= ~IXGBE_DCA_TXCTRL_TX_WB_RO_EN;
+		IXGBE_WRITE_REG(hw, IXGBE_DCA_TXCTRL(i), regval);
+	}
+
+	for (i = 0; ((i < hw->mac.max_rx_queues) &&
+	     (i < IXGBE_DCA_MAX_QUEUES_82598)); i++) {
+		regval = IXGBE_READ_REG(hw, IXGBE_DCA_RXCTRL(i));
+		regval &= ~(IXGBE_DCA_RXCTRL_DESC_WRO_EN |
+			    IXGBE_DCA_RXCTRL_DESC_HSRO_EN);
+		IXGBE_WRITE_REG(hw, IXGBE_DCA_RXCTRL(i), regval);
+	}
+
+	hw->mac.rx_pb_size = IXGBE_82598_RX_PB_SIZE;
+
 	/* set the completion timeout for interface */
 	if (ret_val == 0)
 		ixgbe_set_pcie_completion_timeout(hw);
@@ -1064,7 +1086,7 @@
 			sfp_stat = sfp_stat & IXGBE_I2C_EEPROM_STATUS_MASK;
 			if (sfp_stat != IXGBE_I2C_EEPROM_STATUS_IN_PROGRESS)
 				break;
-			msleep(10);
+			usleep_range(10000, 20000);
 		}
 
 		if (sfp_stat != IXGBE_I2C_EEPROM_STATUS_PASS) {
@@ -1188,6 +1210,38 @@
 	return physical_layer;
 }
 
+/**
+ *  ixgbe_set_lan_id_multi_port_pcie_82598 - Set LAN id for PCIe multiple
+ *  port devices.
+ *  @hw: pointer to the HW structure
+ *
+ *  Calls common function and corrects issue with some single port devices
+ *  that enable LAN1 but not LAN0.
+ **/
+static void ixgbe_set_lan_id_multi_port_pcie_82598(struct ixgbe_hw *hw)
+{
+	struct ixgbe_bus_info *bus = &hw->bus;
+	u16 pci_gen = 0;
+	u16 pci_ctrl2 = 0;
+
+	ixgbe_set_lan_id_multi_port_pcie(hw);
+
+	/* check if LAN0 is disabled */
+	hw->eeprom.ops.read(hw, IXGBE_PCIE_GENERAL_PTR, &pci_gen);
+	if ((pci_gen != 0) && (pci_gen != 0xFFFF)) {
+
+		hw->eeprom.ops.read(hw, pci_gen + IXGBE_PCIE_CTRL2, &pci_ctrl2);
+
+		/* if LAN0 is completely disabled force function to 0 */
+		if ((pci_ctrl2 & IXGBE_PCIE_CTRL2_LAN_DISABLE) &&
+		    !(pci_ctrl2 & IXGBE_PCIE_CTRL2_DISABLE_SELECT) &&
+		    !(pci_ctrl2 & IXGBE_PCIE_CTRL2_DUMMY_ENABLE)) {
+
+			bus->func = 0;
+		}
+	}
+}
+
 static struct ixgbe_mac_operations mac_ops_82598 = {
 	.init_hw		= &ixgbe_init_hw_generic,
 	.reset_hw		= &ixgbe_reset_hw_82598,
@@ -1199,7 +1253,7 @@
 	.get_mac_addr		= &ixgbe_get_mac_addr_generic,
 	.stop_adapter		= &ixgbe_stop_adapter_generic,
 	.get_bus_info           = &ixgbe_get_bus_info_generic,
-	.set_lan_id             = &ixgbe_set_lan_id_multi_port_pcie,
+	.set_lan_id             = &ixgbe_set_lan_id_multi_port_pcie_82598,
 	.read_analog_reg8	= &ixgbe_read_analog_reg8_82598,
 	.write_analog_reg8	= &ixgbe_write_analog_reg8_82598,
 	.setup_link		= &ixgbe_setup_mac_link_82598,
@@ -1227,6 +1281,7 @@
 static struct ixgbe_eeprom_operations eeprom_ops_82598 = {
 	.init_params		= &ixgbe_init_eeprom_params_generic,
 	.read			= &ixgbe_read_eerd_generic,
+	.read_buffer		= &ixgbe_read_eerd_buffer_generic,
 	.calc_checksum          = &ixgbe_calc_eeprom_checksum_generic,
 	.validate_checksum	= &ixgbe_validate_eeprom_checksum_generic,
 	.update_checksum	= &ixgbe_update_eeprom_checksum_generic,
diff -druN linux-2.6.39-libre/drivers/net/ixgbe/ixgbe_82599.c linux-3.0-rc7-libre/drivers/net/ixgbe/ixgbe_82599.c
--- linux-2.6.39-libre/drivers/net/ixgbe/ixgbe_82599.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/ixgbe/ixgbe_82599.c	2011-07-11 19:51:52.000000000 -0400
@@ -38,6 +38,7 @@
 #define IXGBE_82599_RAR_ENTRIES   128
 #define IXGBE_82599_MC_TBL_SIZE   128
 #define IXGBE_82599_VFT_TBL_SIZE  128
+#define IXGBE_82599_RX_PB_SIZE	  512
 
 static void ixgbe_disable_tx_laser_multispeed_fiber(struct ixgbe_hw *hw);
 static void ixgbe_enable_tx_laser_multispeed_fiber(struct ixgbe_hw *hw);
@@ -61,6 +62,7 @@
                                          bool autoneg,
                                          bool autoneg_wait_to_complete);
 static s32 ixgbe_verify_fw_version_82599(struct ixgbe_hw *hw);
+static bool ixgbe_verify_lesm_fw_enabled_82599(struct ixgbe_hw *hw);
 
 static void ixgbe_init_mac_link_ops_82599(struct ixgbe_hw *hw)
 {
@@ -86,7 +88,8 @@
 		if ((mac->ops.get_media_type(hw) ==
 		     ixgbe_media_type_backplane) &&
 		    (hw->phy.smart_speed == ixgbe_smart_speed_auto ||
-		     hw->phy.smart_speed == ixgbe_smart_speed_on))
+		     hw->phy.smart_speed == ixgbe_smart_speed_on) &&
+		     !ixgbe_verify_lesm_fw_enabled_82599(hw))
 			mac->ops.setup_link = &ixgbe_setup_mac_link_smartspeed;
 		else
 			mac->ops.setup_link = &ixgbe_setup_mac_link_82599;
@@ -107,7 +110,6 @@
 
 		ret_val = ixgbe_get_sfp_init_sequence_offsets(hw, &list_offset,
 		                                              &data_offset);
-
 		if (ret_val != 0)
 			goto setup_sfp_out;
 
@@ -127,9 +129,13 @@
 		}
 
 		/* Release the semaphore */
-		ixgbe_release_swfw_sync(hw, IXGBE_GSSR_MAC_CSR_SM);
-		/* Delay obtaining semaphore again to allow FW access */
-		msleep(hw->eeprom.semaphore_delay);
+		hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_MAC_CSR_SM);
+		/*
+		 * Delay obtaining semaphore again to allow FW access,
+		 * semaphore_delay is in ms usleep_range needs us.
+		 */
+		usleep_range(hw->eeprom.semaphore_delay * 1000,
+			     hw->eeprom.semaphore_delay * 2000);
 
 		/* Now restart DSP by setting Restart_AN and clearing LMS */
 		IXGBE_WRITE_REG(hw, IXGBE_AUTOC, ((IXGBE_READ_REG(hw,
@@ -138,7 +144,7 @@
 
 		/* Wait for AN to leave state 0 */
 		for (i = 0; i < 10; i++) {
-			msleep(4);
+			usleep_range(4000, 8000);
 			reg_anlp1 = IXGBE_READ_REG(hw, IXGBE_ANLP1);
 			if (reg_anlp1 & IXGBE_ANLP1_AN_STATE_MASK)
 				break;
@@ -353,6 +359,7 @@
 	case IXGBE_DEV_ID_82599_SFP:
 	case IXGBE_DEV_ID_82599_SFP_FCOE:
 	case IXGBE_DEV_ID_82599_SFP_EM:
+	case IXGBE_DEV_ID_82599_SFP_SF2:
 		media_type = ixgbe_media_type_fiber;
 		break;
 	case IXGBE_DEV_ID_82599_CX4:
@@ -361,6 +368,9 @@
 	case IXGBE_DEV_ID_82599_T3_LOM:
 		media_type = ixgbe_media_type_copper;
 		break;
+	case IXGBE_DEV_ID_82599_LS:
+		media_type = ixgbe_media_type_fiber_lco;
+		break;
 	default:
 		media_type = ixgbe_media_type_unknown;
 		break;
@@ -486,7 +496,7 @@
  *
  *  Set the link speed in the AUTOC register and restarts link.
  **/
-s32 ixgbe_setup_mac_link_multispeed_fiber(struct ixgbe_hw *hw,
+static s32 ixgbe_setup_mac_link_multispeed_fiber(struct ixgbe_hw *hw,
                                           ixgbe_link_speed speed,
                                           bool autoneg,
                                           bool autoneg_wait_to_complete)
@@ -1176,7 +1186,7 @@
 		if (IXGBE_READ_REG(hw, IXGBE_FDIRCTRL) &
 		                   IXGBE_FDIRCTRL_INIT_DONE)
 			break;
-		msleep(1);
+		usleep_range(1000, 2000);
 	}
 	if (i >= IXGBE_FDIR_INIT_DONE_POLL)
 		hw_dbg(hw, "Flow Director Signature poll time exceeded!\n");
@@ -1271,7 +1281,7 @@
 		if (IXGBE_READ_REG(hw, IXGBE_FDIRCTRL) &
 		                   IXGBE_FDIRCTRL_INIT_DONE)
 			break;
-		msleep(1);
+		usleep_range(1000, 2000);
 	}
 	if (i >= IXGBE_FDIR_INIT_DONE_POLL)
 		hw_dbg(hw, "Flow Director Perfect poll time exceeded!\n");
@@ -1740,30 +1750,29 @@
  *  ixgbe_start_hw_82599 - Prepare hardware for Tx/Rx
  *  @hw: pointer to hardware structure
  *
- *  Starts the hardware using the generic start_hw function.
- *  Then performs device-specific:
- *  Clears the rate limiter registers.
+ *  Starts the hardware using the generic start_hw function
+ *  and the generation start_hw function.
+ *  Then performs revision-specific operations, if any.
  **/
 static s32 ixgbe_start_hw_82599(struct ixgbe_hw *hw)
 {
-	u32 q_num;
-	s32 ret_val;
+	s32 ret_val = 0;
 
 	ret_val = ixgbe_start_hw_generic(hw);
+	if (ret_val != 0)
+		goto out;
 
-	/* Clear the rate limiters */
-	for (q_num = 0; q_num < hw->mac.max_tx_queues; q_num++) {
-		IXGBE_WRITE_REG(hw, IXGBE_RTTDQSEL, q_num);
-		IXGBE_WRITE_REG(hw, IXGBE_RTTBCNRC, 0);
-	}
-	IXGBE_WRITE_FLUSH(hw);
+	ret_val = ixgbe_start_hw_gen2(hw);
+	if (ret_val != 0)
+		goto out;
 
 	/* We need to run link autotry after the driver loads */
 	hw->mac.autotry_restart = true;
+	hw->mac.rx_pb_size = IXGBE_82599_RX_PB_SIZE;
 
 	if (ret_val == 0)
 		ret_val = ixgbe_verify_fw_version_82599(hw);
-
+out:
 	return ret_val;
 }
 
@@ -1775,7 +1784,7 @@
  *  If PHY already detected, maintains current PHY type in hw struct,
  *  otherwise executes the PHY detection routine.
  **/
-s32 ixgbe_identify_phy_82599(struct ixgbe_hw *hw)
+static s32 ixgbe_identify_phy_82599(struct ixgbe_hw *hw)
 {
 	s32 status = IXGBE_ERR_PHY_ADDR_INVALID;
 
@@ -1968,21 +1977,6 @@
 }
 
 /**
- *  ixgbe_get_device_caps_82599 - Get additional device capabilities
- *  @hw: pointer to hardware structure
- *  @device_caps: the EEPROM word with the extra device capabilities
- *
- *  This function will read the EEPROM location for the device capabilities,
- *  and return the word through device_caps.
- **/
-static s32 ixgbe_get_device_caps_82599(struct ixgbe_hw *hw, u16 *device_caps)
-{
-	hw->eeprom.ops.read(hw, IXGBE_DEVICE_CAPS, device_caps);
-
-	return 0;
-}
-
-/**
  *  ixgbe_verify_fw_version_82599 - verify fw version for 82599
  *  @hw: pointer to hardware structure
  *
@@ -2030,6 +2024,110 @@
 	return status;
 }
 
+/**
+ *  ixgbe_verify_lesm_fw_enabled_82599 - Checks LESM FW module state.
+ *  @hw: pointer to hardware structure
+ *
+ *  Returns true if the LESM FW module is present and enabled. Otherwise
+ *  returns false. Smart Speed must be disabled if LESM FW module is enabled.
+ **/
+static bool ixgbe_verify_lesm_fw_enabled_82599(struct ixgbe_hw *hw)
+{
+	bool lesm_enabled = false;
+	u16 fw_offset, fw_lesm_param_offset, fw_lesm_state;
+	s32 status;
+
+	/* get the offset to the Firmware Module block */
+	status = hw->eeprom.ops.read(hw, IXGBE_FW_PTR, &fw_offset);
+
+	if ((status != 0) ||
+	    (fw_offset == 0) || (fw_offset == 0xFFFF))
+		goto out;
+
+	/* get the offset to the LESM Parameters block */
+	status = hw->eeprom.ops.read(hw, (fw_offset +
+				     IXGBE_FW_LESM_PARAMETERS_PTR),
+				     &fw_lesm_param_offset);
+
+	if ((status != 0) ||
+	    (fw_lesm_param_offset == 0) || (fw_lesm_param_offset == 0xFFFF))
+		goto out;
+
+	/* get the lesm state word */
+	status = hw->eeprom.ops.read(hw, (fw_lesm_param_offset +
+				     IXGBE_FW_LESM_STATE_1),
+				     &fw_lesm_state);
+
+	if ((status == 0) &&
+	    (fw_lesm_state & IXGBE_FW_LESM_STATE_ENABLED))
+		lesm_enabled = true;
+
+out:
+	return lesm_enabled;
+}
+
+/**
+ *  ixgbe_read_eeprom_buffer_82599 - Read EEPROM word(s) using
+ *  fastest available method
+ *
+ *  @hw: pointer to hardware structure
+ *  @offset: offset of  word in EEPROM to read
+ *  @words: number of words
+ *  @data: word(s) read from the EEPROM
+ *
+ *  Retrieves 16 bit word(s) read from EEPROM
+ **/
+static s32 ixgbe_read_eeprom_buffer_82599(struct ixgbe_hw *hw, u16 offset,
+					  u16 words, u16 *data)
+{
+	struct ixgbe_eeprom_info *eeprom = &hw->eeprom;
+	s32 ret_val = IXGBE_ERR_CONFIG;
+
+	/*
+	 * If EEPROM is detected and can be addressed using 14 bits,
+	 * use EERD otherwise use bit bang
+	 */
+	if ((eeprom->type == ixgbe_eeprom_spi) &&
+	    (offset + (words - 1) <= IXGBE_EERD_MAX_ADDR))
+		ret_val = ixgbe_read_eerd_buffer_generic(hw, offset, words,
+							 data);
+	else
+		ret_val = ixgbe_read_eeprom_buffer_bit_bang_generic(hw, offset,
+								    words,
+								    data);
+
+	return ret_val;
+}
+
+/**
+ *  ixgbe_read_eeprom_82599 - Read EEPROM word using
+ *  fastest available method
+ *
+ *  @hw: pointer to hardware structure
+ *  @offset: offset of  word in the EEPROM to read
+ *  @data: word read from the EEPROM
+ *
+ *  Reads a 16 bit word from the EEPROM
+ **/
+static s32 ixgbe_read_eeprom_82599(struct ixgbe_hw *hw,
+				   u16 offset, u16 *data)
+{
+	struct ixgbe_eeprom_info *eeprom = &hw->eeprom;
+	s32 ret_val = IXGBE_ERR_CONFIG;
+
+	/*
+	 * If EEPROM is detected and can be addressed using 14 bits,
+	 * use EERD otherwise use bit bang
+	 */
+	if ((eeprom->type == ixgbe_eeprom_spi) &&
+	    (offset <= IXGBE_EERD_MAX_ADDR))
+		ret_val = ixgbe_read_eerd_generic(hw, offset, data);
+	else
+		ret_val = ixgbe_read_eeprom_bit_bang_generic(hw, offset, data);
+
+	return ret_val;
+}
+
 static struct ixgbe_mac_operations mac_ops_82599 = {
 	.init_hw                = &ixgbe_init_hw_generic,
 	.reset_hw               = &ixgbe_reset_hw_82599,
@@ -2040,7 +2138,7 @@
 	.enable_rx_dma          = &ixgbe_enable_rx_dma_82599,
 	.get_mac_addr           = &ixgbe_get_mac_addr_generic,
 	.get_san_mac_addr       = &ixgbe_get_san_mac_addr_generic,
-	.get_device_caps        = &ixgbe_get_device_caps_82599,
+	.get_device_caps        = &ixgbe_get_device_caps_generic,
 	.get_wwn_prefix         = &ixgbe_get_wwn_prefix_generic,
 	.stop_adapter           = &ixgbe_stop_adapter_generic,
 	.get_bus_info           = &ixgbe_get_bus_info_generic,
@@ -2076,8 +2174,10 @@
 
 static struct ixgbe_eeprom_operations eeprom_ops_82599 = {
 	.init_params		= &ixgbe_init_eeprom_params_generic,
-	.read			= &ixgbe_read_eerd_generic,
+	.read			= &ixgbe_read_eeprom_82599,
+	.read_buffer		= &ixgbe_read_eeprom_buffer_82599,
 	.write			= &ixgbe_write_eeprom_generic,
+	.write_buffer		= &ixgbe_write_eeprom_buffer_bit_bang_generic,
 	.calc_checksum		= &ixgbe_calc_eeprom_checksum_generic,
 	.validate_checksum	= &ixgbe_validate_eeprom_checksum_generic,
 	.update_checksum	= &ixgbe_update_eeprom_checksum_generic,
diff -druN linux-2.6.39-libre/drivers/net/ixgbe/ixgbe_common.c linux-3.0-rc7-libre/drivers/net/ixgbe/ixgbe_common.c
--- linux-2.6.39-libre/drivers/net/ixgbe/ixgbe_common.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/ixgbe/ixgbe_common.c	2011-07-11 19:51:52.000000000 -0400
@@ -54,6 +54,13 @@
 static s32 ixgbe_negotiate_fc(struct ixgbe_hw *hw, u32 adv_reg, u32 lp_reg,
 			      u32 adv_sym, u32 adv_asm, u32 lp_sym, u32 lp_asm);
 static s32 ixgbe_setup_fc(struct ixgbe_hw *hw, s32 packetbuf_num);
+static s32 ixgbe_poll_eerd_eewr_done(struct ixgbe_hw *hw, u32 ee_reg);
+static s32 ixgbe_read_eeprom_buffer_bit_bang(struct ixgbe_hw *hw, u16 offset,
+					     u16 words, u16 *data);
+static s32 ixgbe_write_eeprom_buffer_bit_bang(struct ixgbe_hw *hw, u16 offset,
+					     u16 words, u16 *data);
+static s32 ixgbe_detect_eeprom_page_size_generic(struct ixgbe_hw *hw,
+						 u16 offset);
 
 /**
  *  ixgbe_start_hw_generic - Prepare hardware for Tx/Rx
@@ -96,6 +103,45 @@
 }
 
 /**
+ *  ixgbe_start_hw_gen2 - Init sequence for common device family
+ *  @hw: pointer to hw structure
+ *
+ * Performs the init sequence common to the second generation
+ * of 10 GbE devices.
+ * Devices in the second generation:
+ *     82599
+ *     X540
+ **/
+s32 ixgbe_start_hw_gen2(struct ixgbe_hw *hw)
+{
+	u32 i;
+	u32 regval;
+
+	/* Clear the rate limiters */
+	for (i = 0; i < hw->mac.max_tx_queues; i++) {
+		IXGBE_WRITE_REG(hw, IXGBE_RTTDQSEL, i);
+		IXGBE_WRITE_REG(hw, IXGBE_RTTBCNRC, 0);
+	}
+	IXGBE_WRITE_FLUSH(hw);
+
+	/* Disable relaxed ordering */
+	for (i = 0; i < hw->mac.max_tx_queues; i++) {
+		regval = IXGBE_READ_REG(hw, IXGBE_DCA_TXCTRL_82599(i));
+		regval &= ~IXGBE_DCA_TXCTRL_TX_WB_RO_EN;
+		IXGBE_WRITE_REG(hw, IXGBE_DCA_TXCTRL_82599(i), regval);
+	}
+
+	for (i = 0; i < hw->mac.max_rx_queues; i++) {
+		regval = IXGBE_READ_REG(hw, IXGBE_DCA_RXCTRL(i));
+		regval &= ~(IXGBE_DCA_RXCTRL_DESC_WRO_EN |
+					IXGBE_DCA_RXCTRL_DESC_HSRO_EN);
+		IXGBE_WRITE_REG(hw, IXGBE_DCA_RXCTRL(i), regval);
+	}
+
+	return 0;
+}
+
+/**
  *  ixgbe_init_hw_generic - Generic hardware initialization
  *  @hw: pointer to hardware structure
  *
@@ -464,7 +510,7 @@
 	reg_val &= ~(IXGBE_RXCTRL_RXEN);
 	IXGBE_WRITE_REG(hw, IXGBE_RXCTRL, reg_val);
 	IXGBE_WRITE_FLUSH(hw);
-	msleep(2);
+	usleep_range(2000, 4000);
 
 	/* Clear interrupt mask to stop from interrupts being generated */
 	IXGBE_WRITE_REG(hw, IXGBE_EIMC, IXGBE_IRQ_CLEAR_MASK);
@@ -545,6 +591,8 @@
 		/* Set default semaphore delay to 10ms which is a well
 		 * tested value */
 		eeprom->semaphore_delay = 10;
+		/* Clear EEPROM page size, it will be initialized as needed */
+		eeprom->word_page_size = 0;
 
 		/*
 		 * Check for EEPROM present first.
@@ -577,26 +625,78 @@
 }
 
 /**
- *  ixgbe_write_eeprom_generic - Writes 16 bit value to EEPROM
+ *  ixgbe_write_eeprom_buffer_bit_bang_generic - Write EEPROM using bit-bang
  *  @hw: pointer to hardware structure
- *  @offset: offset within the EEPROM to be written to
- *  @data: 16 bit word to be written to the EEPROM
+ *  @offset: offset within the EEPROM to write
+ *  @words: number of words
+ *  @data: 16 bit word(s) to write to EEPROM
  *
- *  If ixgbe_eeprom_update_checksum is not called after this function, the
- *  EEPROM will most likely contain an invalid checksum.
+ *  Reads 16 bit word(s) from EEPROM through bit-bang method
  **/
-s32 ixgbe_write_eeprom_generic(struct ixgbe_hw *hw, u16 offset, u16 data)
+s32 ixgbe_write_eeprom_buffer_bit_bang_generic(struct ixgbe_hw *hw, u16 offset,
+					       u16 words, u16 *data)
 {
-	s32 status;
-	u8 write_opcode = IXGBE_EEPROM_WRITE_OPCODE_SPI;
+	s32 status = 0;
+	u16 i, count;
 
 	hw->eeprom.ops.init_params(hw);
 
-	if (offset >= hw->eeprom.word_size) {
+	if (words == 0) {
+		status = IXGBE_ERR_INVALID_ARGUMENT;
+		goto out;
+	}
+
+	if (offset + words > hw->eeprom.word_size) {
 		status = IXGBE_ERR_EEPROM;
 		goto out;
 	}
 
+	/*
+	 * The EEPROM page size cannot be queried from the chip. We do lazy
+	 * initialization. It is worth to do that when we write large buffer.
+	 */
+	if ((hw->eeprom.word_page_size == 0) &&
+	    (words > IXGBE_EEPROM_PAGE_SIZE_MAX))
+		ixgbe_detect_eeprom_page_size_generic(hw, offset);
+
+	/*
+	 * We cannot hold synchronization semaphores for too long
+	 * to avoid other entity starvation. However it is more efficient
+	 * to read in bursts than synchronizing access for each word.
+	 */
+	for (i = 0; i < words; i += IXGBE_EEPROM_RD_BUFFER_MAX_COUNT) {
+		count = (words - i) / IXGBE_EEPROM_RD_BUFFER_MAX_COUNT > 0 ?
+			 IXGBE_EEPROM_RD_BUFFER_MAX_COUNT : (words - i);
+		status = ixgbe_write_eeprom_buffer_bit_bang(hw, offset + i,
+							    count, &data[i]);
+
+		if (status != 0)
+			break;
+	}
+
+out:
+	return status;
+}
+
+/**
+ *  ixgbe_write_eeprom_buffer_bit_bang - Writes 16 bit word(s) to EEPROM
+ *  @hw: pointer to hardware structure
+ *  @offset: offset within the EEPROM to be written to
+ *  @words: number of word(s)
+ *  @data: 16 bit word(s) to be written to the EEPROM
+ *
+ *  If ixgbe_eeprom_update_checksum is not called after this function, the
+ *  EEPROM will most likely contain an invalid checksum.
+ **/
+static s32 ixgbe_write_eeprom_buffer_bit_bang(struct ixgbe_hw *hw, u16 offset,
+					      u16 words, u16 *data)
+{
+	s32 status;
+	u16 word;
+	u16 page_size;
+	u16 i;
+	u8 write_opcode = IXGBE_EEPROM_WRITE_OPCODE_SPI;
+
 	/* Prepare the EEPROM for writing  */
 	status = ixgbe_acquire_eeprom(hw);
 
@@ -608,54 +708,69 @@
 	}
 
 	if (status == 0) {
-		ixgbe_standby_eeprom(hw);
+		for (i = 0; i < words; i++) {
+			ixgbe_standby_eeprom(hw);
 
-		/*  Send the WRITE ENABLE command (8 bit opcode )  */
-		ixgbe_shift_out_eeprom_bits(hw, IXGBE_EEPROM_WREN_OPCODE_SPI,
-		                            IXGBE_EEPROM_OPCODE_BITS);
+			/*  Send the WRITE ENABLE command (8 bit opcode )  */
+			ixgbe_shift_out_eeprom_bits(hw,
+						  IXGBE_EEPROM_WREN_OPCODE_SPI,
+						  IXGBE_EEPROM_OPCODE_BITS);
 
-		ixgbe_standby_eeprom(hw);
+			ixgbe_standby_eeprom(hw);
 
-		/*
-		 * Some SPI eeproms use the 8th address bit embedded in the
-		 * opcode
-		 */
-		if ((hw->eeprom.address_bits == 8) && (offset >= 128))
-			write_opcode |= IXGBE_EEPROM_A8_OPCODE_SPI;
+			/*
+			 * Some SPI eeproms use the 8th address bit embedded
+			 * in the opcode
+			 */
+			if ((hw->eeprom.address_bits == 8) &&
+			    ((offset + i) >= 128))
+				write_opcode |= IXGBE_EEPROM_A8_OPCODE_SPI;
 
-		/* Send the Write command (8-bit opcode + addr) */
-		ixgbe_shift_out_eeprom_bits(hw, write_opcode,
-		                            IXGBE_EEPROM_OPCODE_BITS);
-		ixgbe_shift_out_eeprom_bits(hw, (u16)(offset*2),
-		                            hw->eeprom.address_bits);
+			/* Send the Write command (8-bit opcode + addr) */
+			ixgbe_shift_out_eeprom_bits(hw, write_opcode,
+						    IXGBE_EEPROM_OPCODE_BITS);
+			ixgbe_shift_out_eeprom_bits(hw, (u16)((offset + i) * 2),
+						    hw->eeprom.address_bits);
 
-		/* Send the data */
-		data = (data >> 8) | (data << 8);
-		ixgbe_shift_out_eeprom_bits(hw, data, 16);
-		ixgbe_standby_eeprom(hw);
+			page_size = hw->eeprom.word_page_size;
+
+			/* Send the data in burst via SPI*/
+			do {
+				word = data[i];
+				word = (word >> 8) | (word << 8);
+				ixgbe_shift_out_eeprom_bits(hw, word, 16);
 
+				if (page_size == 0)
+					break;
+
+				/* do not wrap around page */
+				if (((offset + i) & (page_size - 1)) ==
+				    (page_size - 1))
+					break;
+			} while (++i < words);
+
+			ixgbe_standby_eeprom(hw);
+			usleep_range(10000, 20000);
+		}
 		/* Done with writing - release the EEPROM */
 		ixgbe_release_eeprom(hw);
 	}
 
-out:
 	return status;
 }
 
 /**
- *  ixgbe_read_eeprom_bit_bang_generic - Read EEPROM word using bit-bang
+ *  ixgbe_write_eeprom_generic - Writes 16 bit value to EEPROM
  *  @hw: pointer to hardware structure
- *  @offset: offset within the EEPROM to be read
- *  @data: read 16 bit value from EEPROM
+ *  @offset: offset within the EEPROM to be written to
+ *  @data: 16 bit word to be written to the EEPROM
  *
- *  Reads 16 bit value from EEPROM through bit-bang method
+ *  If ixgbe_eeprom_update_checksum is not called after this function, the
+ *  EEPROM will most likely contain an invalid checksum.
  **/
-s32 ixgbe_read_eeprom_bit_bang_generic(struct ixgbe_hw *hw, u16 offset,
-                                       u16 *data)
+s32 ixgbe_write_eeprom_generic(struct ixgbe_hw *hw, u16 offset, u16 data)
 {
 	s32 status;
-	u16 word_in;
-	u8 read_opcode = IXGBE_EEPROM_READ_OPCODE_SPI;
 
 	hw->eeprom.ops.init_params(hw);
 
@@ -664,6 +779,76 @@
 		goto out;
 	}
 
+	status = ixgbe_write_eeprom_buffer_bit_bang(hw, offset, 1, &data);
+
+out:
+	return status;
+}
+
+/**
+ *  ixgbe_read_eeprom_buffer_bit_bang_generic - Read EEPROM using bit-bang
+ *  @hw: pointer to hardware structure
+ *  @offset: offset within the EEPROM to be read
+ *  @words: number of word(s)
+ *  @data: read 16 bit words(s) from EEPROM
+ *
+ *  Reads 16 bit word(s) from EEPROM through bit-bang method
+ **/
+s32 ixgbe_read_eeprom_buffer_bit_bang_generic(struct ixgbe_hw *hw, u16 offset,
+					      u16 words, u16 *data)
+{
+	s32 status = 0;
+	u16 i, count;
+
+	hw->eeprom.ops.init_params(hw);
+
+	if (words == 0) {
+		status = IXGBE_ERR_INVALID_ARGUMENT;
+		goto out;
+	}
+
+	if (offset + words > hw->eeprom.word_size) {
+		status = IXGBE_ERR_EEPROM;
+		goto out;
+	}
+
+	/*
+	 * We cannot hold synchronization semaphores for too long
+	 * to avoid other entity starvation. However it is more efficient
+	 * to read in bursts than synchronizing access for each word.
+	 */
+	for (i = 0; i < words; i += IXGBE_EEPROM_RD_BUFFER_MAX_COUNT) {
+		count = (words - i) / IXGBE_EEPROM_RD_BUFFER_MAX_COUNT > 0 ?
+			 IXGBE_EEPROM_RD_BUFFER_MAX_COUNT : (words - i);
+
+		status = ixgbe_read_eeprom_buffer_bit_bang(hw, offset + i,
+							   count, &data[i]);
+
+		if (status != 0)
+			break;
+	}
+
+out:
+	return status;
+}
+
+/**
+ *  ixgbe_read_eeprom_buffer_bit_bang - Read EEPROM using bit-bang
+ *  @hw: pointer to hardware structure
+ *  @offset: offset within the EEPROM to be read
+ *  @words: number of word(s)
+ *  @data: read 16 bit word(s) from EEPROM
+ *
+ *  Reads 16 bit word(s) from EEPROM through bit-bang method
+ **/
+static s32 ixgbe_read_eeprom_buffer_bit_bang(struct ixgbe_hw *hw, u16 offset,
+					     u16 words, u16 *data)
+{
+	s32 status;
+	u16 word_in;
+	u8 read_opcode = IXGBE_EEPROM_READ_OPCODE_SPI;
+	u16 i;
+
 	/* Prepare the EEPROM for reading  */
 	status = ixgbe_acquire_eeprom(hw);
 
@@ -675,29 +860,145 @@
 	}
 
 	if (status == 0) {
-		ixgbe_standby_eeprom(hw);
-
-		/*
-		 * Some SPI eeproms use the 8th address bit embedded in the
-		 * opcode
-		 */
-		if ((hw->eeprom.address_bits == 8) && (offset >= 128))
-			read_opcode |= IXGBE_EEPROM_A8_OPCODE_SPI;
+		for (i = 0; i < words; i++) {
+			ixgbe_standby_eeprom(hw);
+			/*
+			 * Some SPI eeproms use the 8th address bit embedded
+			 * in the opcode
+			 */
+			if ((hw->eeprom.address_bits == 8) &&
+			    ((offset + i) >= 128))
+				read_opcode |= IXGBE_EEPROM_A8_OPCODE_SPI;
 
-		/* Send the READ command (opcode + addr) */
-		ixgbe_shift_out_eeprom_bits(hw, read_opcode,
-		                            IXGBE_EEPROM_OPCODE_BITS);
-		ixgbe_shift_out_eeprom_bits(hw, (u16)(offset*2),
-		                            hw->eeprom.address_bits);
+			/* Send the READ command (opcode + addr) */
+			ixgbe_shift_out_eeprom_bits(hw, read_opcode,
+						    IXGBE_EEPROM_OPCODE_BITS);
+			ixgbe_shift_out_eeprom_bits(hw, (u16)((offset + i) * 2),
+						    hw->eeprom.address_bits);
 
-		/* Read the data. */
-		word_in = ixgbe_shift_in_eeprom_bits(hw, 16);
-		*data = (word_in >> 8) | (word_in << 8);
+			/* Read the data. */
+			word_in = ixgbe_shift_in_eeprom_bits(hw, 16);
+			data[i] = (word_in >> 8) | (word_in << 8);
+		}
 
 		/* End this read operation */
 		ixgbe_release_eeprom(hw);
 	}
 
+	return status;
+}
+
+/**
+ *  ixgbe_read_eeprom_bit_bang_generic - Read EEPROM word using bit-bang
+ *  @hw: pointer to hardware structure
+ *  @offset: offset within the EEPROM to be read
+ *  @data: read 16 bit value from EEPROM
+ *
+ *  Reads 16 bit value from EEPROM through bit-bang method
+ **/
+s32 ixgbe_read_eeprom_bit_bang_generic(struct ixgbe_hw *hw, u16 offset,
+				       u16 *data)
+{
+	s32 status;
+
+	hw->eeprom.ops.init_params(hw);
+
+	if (offset >= hw->eeprom.word_size) {
+		status = IXGBE_ERR_EEPROM;
+		goto out;
+	}
+
+	status = ixgbe_read_eeprom_buffer_bit_bang(hw, offset, 1, data);
+
+out:
+	return status;
+}
+
+/**
+ *  ixgbe_read_eerd_buffer_generic - Read EEPROM word(s) using EERD
+ *  @hw: pointer to hardware structure
+ *  @offset: offset of word in the EEPROM to read
+ *  @words: number of word(s)
+ *  @data: 16 bit word(s) from the EEPROM
+ *
+ *  Reads a 16 bit word(s) from the EEPROM using the EERD register.
+ **/
+s32 ixgbe_read_eerd_buffer_generic(struct ixgbe_hw *hw, u16 offset,
+				   u16 words, u16 *data)
+{
+	u32 eerd;
+	s32 status = 0;
+	u32 i;
+
+	hw->eeprom.ops.init_params(hw);
+
+	if (words == 0) {
+		status = IXGBE_ERR_INVALID_ARGUMENT;
+		goto out;
+	}
+
+	if (offset >= hw->eeprom.word_size) {
+		status = IXGBE_ERR_EEPROM;
+		goto out;
+	}
+
+	for (i = 0; i < words; i++) {
+		eerd = ((offset + i) << IXGBE_EEPROM_RW_ADDR_SHIFT) +
+		       IXGBE_EEPROM_RW_REG_START;
+
+		IXGBE_WRITE_REG(hw, IXGBE_EERD, eerd);
+		status = ixgbe_poll_eerd_eewr_done(hw, IXGBE_NVM_POLL_READ);
+
+		if (status == 0) {
+			data[i] = (IXGBE_READ_REG(hw, IXGBE_EERD) >>
+				   IXGBE_EEPROM_RW_REG_DATA);
+		} else {
+			hw_dbg(hw, "Eeprom read timed out\n");
+			goto out;
+		}
+	}
+out:
+	return status;
+}
+
+/**
+ *  ixgbe_detect_eeprom_page_size_generic - Detect EEPROM page size
+ *  @hw: pointer to hardware structure
+ *  @offset: offset within the EEPROM to be used as a scratch pad
+ *
+ *  Discover EEPROM page size by writing marching data at given offset.
+ *  This function is called only when we are writing a new large buffer
+ *  at given offset so the data would be overwritten anyway.
+ **/
+static s32 ixgbe_detect_eeprom_page_size_generic(struct ixgbe_hw *hw,
+						 u16 offset)
+{
+	u16 data[IXGBE_EEPROM_PAGE_SIZE_MAX];
+	s32 status = 0;
+	u16 i;
+
+	for (i = 0; i < IXGBE_EEPROM_PAGE_SIZE_MAX; i++)
+		data[i] = i;
+
+	hw->eeprom.word_page_size = IXGBE_EEPROM_PAGE_SIZE_MAX;
+	status = ixgbe_write_eeprom_buffer_bit_bang(hw, offset,
+					     IXGBE_EEPROM_PAGE_SIZE_MAX, data);
+	hw->eeprom.word_page_size = 0;
+	if (status != 0)
+		goto out;
+
+	status = ixgbe_read_eeprom_buffer_bit_bang(hw, offset, 1, data);
+	if (status != 0)
+		goto out;
+
+	/*
+	 * When writing in burst more than the actual page size
+	 * EEPROM address wraps around current page.
+	 */
+	hw->eeprom.word_page_size = IXGBE_EEPROM_PAGE_SIZE_MAX - data[0];
+
+	hw_dbg(hw, "Detected EEPROM page size = %d words.",
+	       hw->eeprom.word_page_size);
 out:
 	return status;
 }
@@ -712,33 +1013,75 @@
  **/
 s32 ixgbe_read_eerd_generic(struct ixgbe_hw *hw, u16 offset, u16 *data)
 {
-	u32 eerd;
-	s32 status;
+	return ixgbe_read_eerd_buffer_generic(hw, offset, 1, data);
+}
+
+/**
+ *  ixgbe_write_eewr_buffer_generic - Write EEPROM word(s) using EEWR
+ *  @hw: pointer to hardware structure
+ *  @offset: offset of  word in the EEPROM to write
+ *  @words: number of words
+ *  @data: word(s) write to the EEPROM
+ *
+ *  Write a 16 bit word(s) to the EEPROM using the EEWR register.
+ **/
+s32 ixgbe_write_eewr_buffer_generic(struct ixgbe_hw *hw, u16 offset,
+				    u16 words, u16 *data)
+{
+	u32 eewr;
+	s32 status = 0;
+	u16 i;
 
 	hw->eeprom.ops.init_params(hw);
 
+	if (words == 0) {
+		status = IXGBE_ERR_INVALID_ARGUMENT;
+		goto out;
+	}
+
 	if (offset >= hw->eeprom.word_size) {
 		status = IXGBE_ERR_EEPROM;
 		goto out;
 	}
 
-	eerd = (offset << IXGBE_EEPROM_RW_ADDR_SHIFT) +
-	       IXGBE_EEPROM_RW_REG_START;
+	for (i = 0; i < words; i++) {
+		eewr = ((offset + i) << IXGBE_EEPROM_RW_ADDR_SHIFT) |
+		       (data[i] << IXGBE_EEPROM_RW_REG_DATA) |
+		       IXGBE_EEPROM_RW_REG_START;
 
-	IXGBE_WRITE_REG(hw, IXGBE_EERD, eerd);
-	status = ixgbe_poll_eerd_eewr_done(hw, IXGBE_NVM_POLL_READ);
+		status = ixgbe_poll_eerd_eewr_done(hw, IXGBE_NVM_POLL_WRITE);
+		if (status != 0) {
+			hw_dbg(hw, "Eeprom write EEWR timed out\n");
+			goto out;
+		}
 
-	if (status == 0)
-		*data = (IXGBE_READ_REG(hw, IXGBE_EERD) >>
-		         IXGBE_EEPROM_RW_REG_DATA);
-	else
-		hw_dbg(hw, "Eeprom read timed out\n");
+		IXGBE_WRITE_REG(hw, IXGBE_EEWR, eewr);
+
+		status = ixgbe_poll_eerd_eewr_done(hw, IXGBE_NVM_POLL_WRITE);
+		if (status != 0) {
+			hw_dbg(hw, "Eeprom write EEWR timed out\n");
+			goto out;
+		}
+	}
 
 out:
 	return status;
 }
 
 /**
+ *  ixgbe_write_eewr_generic - Write EEPROM word using EEWR
+ *  @hw: pointer to hardware structure
+ *  @offset: offset of  word in the EEPROM to write
+ *  @data: word write to the EEPROM
+ *
+ *  Write a 16 bit word to the EEPROM using the EEWR register.
+ **/
+s32 ixgbe_write_eewr_generic(struct ixgbe_hw *hw, u16 offset, u16 data)
+{
+	return ixgbe_write_eewr_buffer_generic(hw, offset, 1, &data);
+}
+
+/**
  *  ixgbe_poll_eerd_eewr_done - Poll EERD read or EEWR write status
  *  @hw: pointer to hardware structure
  *  @ee_reg: EEPROM flag for polling
@@ -746,7 +1089,7 @@
  *  Polls the status bit (bit 1) of the EERD or EEWR to determine when the
  *  read or write is done respectively.
  **/
-s32 ixgbe_poll_eerd_eewr_done(struct ixgbe_hw *hw, u32 ee_reg)
+static s32 ixgbe_poll_eerd_eewr_done(struct ixgbe_hw *hw, u32 ee_reg)
 {
 	u32 i;
 	u32 reg;
@@ -846,6 +1189,28 @@
 		udelay(50);
 	}
 
+	if (i == timeout) {
+		hw_dbg(hw, "Driver can't access the Eeprom - SMBI Semaphore "
+		       "not granted.\n");
+		/*
+		 * this release is particularly important because our attempts
+		 * above to get the semaphore may have succeeded, and if there
+		 * was a timeout, we should unconditionally clear the semaphore
+		 * bits to free the driver to make progress
+		 */
+		ixgbe_release_eeprom_semaphore(hw);
+
+		udelay(50);
+		/*
+		 * one last try
+		 * If the SMBI bit is 0 when we read it, then the bit will be
+		 * set and we have the semaphore
+		 */
+		swsm = IXGBE_READ_REG(hw, IXGBE_SWSM);
+		if (!(swsm & IXGBE_SWSM_SMBI))
+			status = 0;
+	}
+
 	/* Now get the semaphore between SW/FW through the SWESMBI bit */
 	if (status == 0) {
 		for (i = 0; i < timeout; i++) {
@@ -1112,8 +1477,12 @@
 
 	hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM);
 
-	/* Delay before attempt to obtain semaphore again to allow FW access */
-	msleep(hw->eeprom.semaphore_delay);
+	/*
+	 * Delay before attempt to obtain semaphore again to allow FW
+	 * access. semaphore_delay is in ms we need us for usleep_range
+	 */
+	usleep_range(hw->eeprom.semaphore_delay * 1000,
+		     hw->eeprom.semaphore_delay * 2000);
 }
 
 /**
@@ -2189,7 +2558,7 @@
 		 * thread currently using resource (swmask)
 		 */
 		ixgbe_release_eeprom_semaphore(hw);
-		msleep(5);
+		usleep_range(5000, 10000);
 		timeout--;
 	}
 
@@ -2263,7 +2632,7 @@
 		autoc_reg |= IXGBE_AUTOC_AN_RESTART;
 		autoc_reg |= IXGBE_AUTOC_FLU;
 		IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc_reg);
-		msleep(10);
+		usleep_range(10000, 20000);
 	}
 
 	led_reg &= ~IXGBE_LED_MODE_MASK(index);
@@ -2883,3 +3252,18 @@
 		pfvfspoof &= ~(1 << vf_target_shift);
 	IXGBE_WRITE_REG(hw, IXGBE_PFVFSPOOF(vf_target_reg), pfvfspoof);
 }
+
+/**
+ *  ixgbe_get_device_caps_generic - Get additional device capabilities
+ *  @hw: pointer to hardware structure
+ *  @device_caps: the EEPROM word with the extra device capabilities
+ *
+ *  This function will read the EEPROM location for the device capabilities,
+ *  and return the word through device_caps.
+ **/
+s32 ixgbe_get_device_caps_generic(struct ixgbe_hw *hw, u16 *device_caps)
+{
+	hw->eeprom.ops.read(hw, IXGBE_DEVICE_CAPS, device_caps);
+
+	return 0;
+}
diff -druN linux-2.6.39-libre/drivers/net/ixgbe/ixgbe_common.h linux-3.0-rc7-libre/drivers/net/ixgbe/ixgbe_common.h
--- linux-2.6.39-libre/drivers/net/ixgbe/ixgbe_common.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/ixgbe/ixgbe_common.h	2011-07-11 19:51:52.000000000 -0400
@@ -35,6 +35,7 @@
 s32 ixgbe_init_ops_generic(struct ixgbe_hw *hw);
 s32 ixgbe_init_hw_generic(struct ixgbe_hw *hw);
 s32 ixgbe_start_hw_generic(struct ixgbe_hw *hw);
+s32 ixgbe_start_hw_gen2(struct ixgbe_hw *hw);
 s32 ixgbe_clear_hw_cntrs_generic(struct ixgbe_hw *hw);
 s32 ixgbe_read_pba_string_generic(struct ixgbe_hw *hw, u8 *pba_num,
                                   u32 pba_num_size);
@@ -48,14 +49,22 @@
 
 s32 ixgbe_init_eeprom_params_generic(struct ixgbe_hw *hw);
 s32 ixgbe_write_eeprom_generic(struct ixgbe_hw *hw, u16 offset, u16 data);
+s32 ixgbe_write_eeprom_buffer_bit_bang_generic(struct ixgbe_hw *hw, u16 offset,
+					       u16 words, u16 *data);
 s32 ixgbe_read_eerd_generic(struct ixgbe_hw *hw, u16 offset, u16 *data);
+s32 ixgbe_read_eerd_buffer_generic(struct ixgbe_hw *hw, u16 offset,
+				   u16 words, u16 *data);
+s32 ixgbe_write_eewr_generic(struct ixgbe_hw *hw, u16 offset, u16 data);
+s32 ixgbe_write_eewr_buffer_generic(struct ixgbe_hw *hw, u16 offset,
+				    u16 words, u16 *data);
 s32 ixgbe_read_eeprom_bit_bang_generic(struct ixgbe_hw *hw, u16 offset,
                                        u16 *data);
+s32 ixgbe_read_eeprom_buffer_bit_bang_generic(struct ixgbe_hw *hw, u16 offset,
+					      u16 words, u16 *data);
 u16 ixgbe_calc_eeprom_checksum_generic(struct ixgbe_hw *hw);
 s32 ixgbe_validate_eeprom_checksum_generic(struct ixgbe_hw *hw,
                                            u16 *checksum_val);
 s32 ixgbe_update_eeprom_checksum_generic(struct ixgbe_hw *hw);
-s32 ixgbe_poll_eerd_eewr_done(struct ixgbe_hw *hw, u32 ee_reg);
 
 s32 ixgbe_set_rar_generic(struct ixgbe_hw *hw, u32 index, u8 *addr, u32 vmdq,
                           u32 enable_addr);
@@ -89,6 +98,7 @@
 s32 ixgbe_blink_led_stop_generic(struct ixgbe_hw *hw, u32 index);
 void ixgbe_set_mac_anti_spoofing(struct ixgbe_hw *hw, bool enable, int pf);
 void ixgbe_set_vlan_anti_spoofing(struct ixgbe_hw *hw, bool enable, int vf);
+s32 ixgbe_get_device_caps_generic(struct ixgbe_hw *hw, u16 *device_caps);
 
 #define IXGBE_WRITE_REG(a, reg, value) writel((value), ((a)->hw_addr + (reg)))
 
diff -druN linux-2.6.39-libre/drivers/net/ixgbe/ixgbe_dcb_82598.c linux-3.0-rc7-libre/drivers/net/ixgbe/ixgbe_dcb_82598.c
--- linux-2.6.39-libre/drivers/net/ixgbe/ixgbe_dcb_82598.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/ixgbe/ixgbe_dcb_82598.c	2011-07-11 19:51:52.000000000 -0400
@@ -289,7 +289,7 @@
  * Configure queue statistics registers, all queues belonging to same traffic
  * class uses a single set of queue statistics counters.
  */
-s32 ixgbe_dcb_config_tc_stats_82598(struct ixgbe_hw *hw)
+static s32 ixgbe_dcb_config_tc_stats_82598(struct ixgbe_hw *hw)
 {
 	u32 reg = 0;
 	u8  i   = 0;
diff -druN linux-2.6.39-libre/drivers/net/ixgbe/ixgbe_dcb_82599.c linux-3.0-rc7-libre/drivers/net/ixgbe/ixgbe_dcb_82599.c
--- linux-2.6.39-libre/drivers/net/ixgbe/ixgbe_dcb_82599.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/ixgbe/ixgbe_dcb_82599.c	2011-07-11 19:51:52.000000000 -0400
@@ -39,36 +39,52 @@
  */
 static s32 ixgbe_dcb_config_packet_buffers_82599(struct ixgbe_hw *hw, u8 rx_pba)
 {
-	s32 ret_val = 0;
-	u32 value = IXGBE_RXPBSIZE_64KB;
+	int num_tcs = IXGBE_MAX_PACKET_BUFFERS;
+	u32 rx_pb_size = hw->mac.rx_pb_size << IXGBE_RXPBSIZE_SHIFT;
+	u32 rxpktsize;
+	u32 txpktsize;
+	u32 txpbthresh;
 	u8  i = 0;
 
-	/* Setup Rx packet buffer sizes */
-	switch (rx_pba) {
-	case pba_80_48:
-		/* Setup the first four at 80KB */
-		value = IXGBE_RXPBSIZE_80KB;
-		for (; i < 4; i++)
-			IXGBE_WRITE_REG(hw, IXGBE_RXPBSIZE(i), value);
-		/* Setup the last four at 48KB...don't re-init i */
-		value = IXGBE_RXPBSIZE_48KB;
-		/* Fall Through */
-	case pba_equal:
-	default:
-		for (; i < IXGBE_MAX_PACKET_BUFFERS; i++)
-			IXGBE_WRITE_REG(hw, IXGBE_RXPBSIZE(i), value);
+	/*
+	 * This really means configure the first half of the TCs
+	 * (Traffic Classes) to use 5/8 of the Rx packet buffer
+	 * space.  To determine the size of the buffer for each TC,
+	 * we are multiplying the average size by 5/4 and applying
+	 * it to half of the traffic classes.
+	 */
+	if (rx_pba == pba_80_48) {
+		rxpktsize = (rx_pb_size * 5) / (num_tcs * 4);
+		rx_pb_size -= rxpktsize * (num_tcs / 2);
+		for (; i < (num_tcs / 2); i++)
+			IXGBE_WRITE_REG(hw, IXGBE_RXPBSIZE(i), rxpktsize);
+	}
 
-		/* Setup Tx packet buffer sizes */
-		for (i = 0; i < IXGBE_MAX_PACKET_BUFFERS; i++) {
-			IXGBE_WRITE_REG(hw, IXGBE_TXPBSIZE(i),
-			                IXGBE_TXPBSIZE_20KB);
-			IXGBE_WRITE_REG(hw, IXGBE_TXPBTHRESH(i),
-			                IXGBE_TXPBTHRESH_DCB);
-		}
-		break;
+	/* Divide the remaining Rx packet buffer evenly among the TCs */
+	rxpktsize = rx_pb_size / (num_tcs - i);
+	for (; i < num_tcs; i++)
+		IXGBE_WRITE_REG(hw, IXGBE_RXPBSIZE(i), rxpktsize);
+
+	/*
+	 * Setup Tx packet buffer and threshold equally for all TCs
+	 * TXPBTHRESH register is set in K so divide by 1024 and subtract
+	 * 10 since the largest packet we support is just over 9K.
+	 */
+	txpktsize = IXGBE_TXPBSIZE_MAX / num_tcs;
+	txpbthresh = (txpktsize / 1024) - IXGBE_TXPKT_SIZE_MAX;
+	for (i = 0; i < num_tcs; i++) {
+		IXGBE_WRITE_REG(hw, IXGBE_TXPBSIZE(i), txpktsize);
+		IXGBE_WRITE_REG(hw, IXGBE_TXPBTHRESH(i), txpbthresh);
 	}
 
-	return ret_val;
+	/* Clear unused TCs, if any, to zero buffer size*/
+	for (; i < MAX_TRAFFIC_CLASS; i++) {
+		IXGBE_WRITE_REG(hw, IXGBE_RXPBSIZE(i), 0);
+		IXGBE_WRITE_REG(hw, IXGBE_TXPBSIZE(i), 0);
+		IXGBE_WRITE_REG(hw, IXGBE_TXPBTHRESH(i), 0);
+	}
+
+	return 0;
 }
 
 /**
@@ -285,12 +301,17 @@
 		IXGBE_WRITE_REG(hw, IXGBE_FCCFG, reg);
 		/*
 		 * Enable Receive PFC
-		 * We will always honor XOFF frames we receive when
-		 * we are in PFC mode.
+		 * 82599 will always honor XOFF frames we receive when
+		 * we are in PFC mode however X540 only honors enabled
+		 * traffic classes.
 		 */
 		reg = IXGBE_READ_REG(hw, IXGBE_MFLCN);
 		reg &= ~IXGBE_MFLCN_RFCE;
 		reg |= IXGBE_MFLCN_RPFCE | IXGBE_MFLCN_DPF;
+
+		if (hw->mac.type == ixgbe_mac_X540)
+			reg |= pfc_en << IXGBE_MFLCN_RPFCE_SHIFT;
+
 		IXGBE_WRITE_REG(hw, IXGBE_MFLCN, reg);
 
 	} else {
diff -druN linux-2.6.39-libre/drivers/net/ixgbe/ixgbe_dcb_82599.h linux-3.0-rc7-libre/drivers/net/ixgbe/ixgbe_dcb_82599.h
--- linux-2.6.39-libre/drivers/net/ixgbe/ixgbe_dcb_82599.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/ixgbe/ixgbe_dcb_82599.h	2011-07-11 19:51:52.000000000 -0400
@@ -92,8 +92,10 @@
 #define IXGBE_RXPBSIZE_64KB     0x00010000 /* 64KB Packet Buffer */
 #define IXGBE_RXPBSIZE_80KB     0x00014000 /* 80KB Packet Buffer */
 #define IXGBE_RXPBSIZE_128KB    0x00020000 /* 128KB Packet Buffer */
+#define IXGBE_TXPBSIZE_MAX	0x00028000 /* 160KB Packet Buffer*/
 
 #define IXGBE_TXPBTHRESH_DCB    0xA        /* THRESH value for DCB mode */
+#define IXGBE_TXPKT_SIZE_MAX    0xA        /* Max Tx Packet size  */
 
 /* SECTXMINIFG DCB */
 #define IXGBE_SECTX_DCB		0x00001F00 /* DCB TX Buffer IFG */
diff -druN linux-2.6.39-libre/drivers/net/ixgbe/ixgbe_dcb_nl.c linux-3.0-rc7-libre/drivers/net/ixgbe/ixgbe_dcb_nl.c
--- linux-2.6.39-libre/drivers/net/ixgbe/ixgbe_dcb_nl.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/ixgbe/ixgbe_dcb_nl.c	2011-07-11 19:51:52.000000000 -0400
@@ -347,18 +347,28 @@
 static u8 ixgbe_dcbnl_set_all(struct net_device *netdev)
 {
 	struct ixgbe_adapter *adapter = netdev_priv(netdev);
+	struct dcb_app app = {
+			      .selector = DCB_APP_IDTYPE_ETHTYPE,
+			      .protocol = ETH_P_FCOE,
+			     };
+	u8 up = dcb_getapp(netdev, &app);
 	int ret;
 
-	if (!adapter->dcb_set_bitmap ||
-	    !(adapter->dcbx_cap & DCB_CAP_DCBX_VER_CEE))
-		return DCB_NO_HW_CHG;
-
 	ret = ixgbe_copy_dcb_cfg(&adapter->temp_dcb_cfg, &adapter->dcb_cfg,
 				 MAX_TRAFFIC_CLASS);
-
 	if (ret)
 		return DCB_NO_HW_CHG;
 
+	/* In IEEE mode app data must be parsed into DCBX format for
+	 * hardware routines.
+	 */
+	if (adapter->dcbx_cap & DCB_CAP_DCBX_VER_IEEE)
+		up = (1 << up);
+
+#ifdef IXGBE_FCOE
+	if (up && (up != (1 << adapter->fcoe.up)))
+		adapter->dcb_set_bitmap |= BIT_APP_UPCHG;
+
 	/*
 	 * Only take down the adapter if an app change occurred. FCoE
 	 * may shuffle tx rings in this case and this can not be done
@@ -366,12 +376,15 @@
 	 */
 	if (adapter->dcb_set_bitmap & BIT_APP_UPCHG) {
 		while (test_and_set_bit(__IXGBE_RESETTING, &adapter->state))
-			msleep(1);
+			usleep_range(1000, 2000);
+
+		ixgbe_fcoe_setapp(adapter, up);
 
 		if (netif_running(netdev))
 			netdev->netdev_ops->ndo_stop(netdev);
 		ixgbe_clear_interrupt_scheme(adapter);
 	}
+#endif
 
 	if (adapter->dcb_cfg.pfc_mode_enable) {
 		switch (adapter->hw.mac.type) {
@@ -399,12 +412,14 @@
 		}
 	}
 
+#ifdef IXGBE_FCOE
 	if (adapter->dcb_set_bitmap & BIT_APP_UPCHG) {
 		ixgbe_init_interrupt_scheme(adapter);
 		if (netif_running(netdev))
 			netdev->netdev_ops->ndo_open(netdev);
 		ret = DCB_HW_CHG_RST;
 	}
+#endif
 
 	if (adapter->dcb_set_bitmap & BIT_PFC) {
 		u8 pfc_en;
@@ -558,68 +573,6 @@
 	return dcb_getapp(netdev, &app);
 }
 
-/**
- * ixgbe_dcbnl_setapp - set the DCBX application user priority
- * @netdev : the corresponding netdev
- * @idtype : identifies the id as ether type or TCP/UDP port number
- * @id: id is either ether type or TCP/UDP port number
- * @up: the 802.1p user priority bitmap
- *
- * Returns : 0 on success or 1 on error
- */
-static u8 ixgbe_dcbnl_setapp(struct net_device *netdev,
-                             u8 idtype, u16 id, u8 up)
-{
-	struct ixgbe_adapter *adapter = netdev_priv(netdev);
-	u8 rval = 1;
-	struct dcb_app app = {
-			      .selector = idtype,
-			      .protocol = id,
-			      .priority = up
-			     };
-
-	if (!(adapter->dcbx_cap & DCB_CAP_DCBX_VER_CEE))
-		return rval;
-
-	rval = dcb_setapp(netdev, &app);
-
-	switch (idtype) {
-	case DCB_APP_IDTYPE_ETHTYPE:
-#ifdef IXGBE_FCOE
-		if (id == ETH_P_FCOE) {
-			u8 old_tc;
-
-			/* Get current programmed tc */
-			old_tc = adapter->fcoe.tc;
-			rval = ixgbe_fcoe_setapp(adapter, up);
-
-			if (rval ||
-			   !(adapter->flags & IXGBE_FLAG_DCB_ENABLED) ||
-			   !(adapter->flags & IXGBE_FLAG_FCOE_ENABLED))
-				break;
-
-			/* The FCoE application priority may be changed multiple
-			 * times in quick succession with switches that build up
-			 * TLVs. To avoid creating uneeded device resets this
-			 * checks the actual HW configuration and clears
-			 * BIT_APP_UPCHG if a HW configuration change is not
-			 * need
-			 */
-			if (old_tc == adapter->fcoe.tc)
-				adapter->dcb_set_bitmap &= ~BIT_APP_UPCHG;
-			else
-				adapter->dcb_set_bitmap |= BIT_APP_UPCHG;
-		}
-#endif
-		break;
-	case DCB_APP_IDTYPE_PORTNUM:
-		break;
-	default:
-		break;
-	}
-	return rval;
-}
-
 static int ixgbe_dcbnl_ieee_getets(struct net_device *dev,
 				   struct ieee_ets *ets)
 {
@@ -745,25 +698,14 @@
 
 	if (!(adapter->dcbx_cap & DCB_CAP_DCBX_VER_IEEE))
 		return -EINVAL;
-#ifdef IXGBE_FCOE
-	if (app->selector == 1 && app->protocol == ETH_P_FCOE) {
-		if (adapter->fcoe.tc == app->priority)
-			goto setapp;
 
-		/* In IEEE mode map up to tc 1:1 */
-		adapter->fcoe.tc = app->priority;
-		adapter->fcoe.up = app->priority;
+	dcb_setapp(dev, app);
 
-		/* Force hardware reset required to push FCoE
-		 * setup on {tx|rx}_rings
-		 */
-		adapter->dcb_set_bitmap |= BIT_APP_UPCHG;
+#ifdef IXGBE_FCOE
+	if (app->selector == 1 && app->protocol == ETH_P_FCOE &&
+	    adapter->fcoe.tc == app->priority)
 		ixgbe_dcbnl_set_all(dev);
-	}
-
-setapp:
 #endif
-	dcb_setapp(dev, app);
 	return 0;
 }
 
@@ -838,7 +780,6 @@
 	.getpfcstate	= ixgbe_dcbnl_getpfcstate,
 	.setpfcstate	= ixgbe_dcbnl_setpfcstate,
 	.getapp		= ixgbe_dcbnl_getapp,
-	.setapp		= ixgbe_dcbnl_setapp,
 	.getdcbx	= ixgbe_dcbnl_getdcbx,
 	.setdcbx	= ixgbe_dcbnl_setdcbx,
 };
diff -druN linux-2.6.39-libre/drivers/net/ixgbe/ixgbe_ethtool.c linux-3.0-rc7-libre/drivers/net/ixgbe/ixgbe_ethtool.c
--- linux-2.6.39-libre/drivers/net/ixgbe/ixgbe_ethtool.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/ixgbe/ixgbe_ethtool.c	2011-07-11 19:51:52.000000000 -0400
@@ -84,6 +84,7 @@
 	{"hw_rsc_flushed", IXGBE_STAT(rsc_total_flush)},
 	{"fdir_match", IXGBE_STAT(stats.fdirmatch)},
 	{"fdir_miss", IXGBE_STAT(stats.fdirmiss)},
+	{"fdir_overflow", IXGBE_STAT(fdir_overflow)},
 	{"rx_fifo_errors", IXGBE_NETDEV_STAT(rx_fifo_errors)},
 	{"rx_missed_errors", IXGBE_NETDEV_STAT(rx_missed_errors)},
 	{"tx_aborted_errors", IXGBE_NETDEV_STAT(tx_aborted_errors)},
@@ -102,6 +103,10 @@
 	{"alloc_rx_page_failed", IXGBE_STAT(alloc_rx_page_failed)},
 	{"alloc_rx_buff_failed", IXGBE_STAT(alloc_rx_buff_failed)},
 	{"rx_no_dma_resources", IXGBE_STAT(hw_rx_no_dma_resources)},
+	{"os2bmc_rx_by_bmc", IXGBE_STAT(stats.o2bgptc)},
+	{"os2bmc_tx_by_bmc", IXGBE_STAT(stats.b2ospc)},
+	{"os2bmc_tx_by_host", IXGBE_STAT(stats.o2bspc)},
+	{"os2bmc_rx_by_host", IXGBE_STAT(stats.b2ogprc)},
 #ifdef IXGBE_FCOE
 	{"fcoe_bad_fccrc", IXGBE_STAT(stats.fccrc)},
 	{"rx_fcoe_dropped", IXGBE_STAT(stats.fcoerpdc)},
@@ -288,20 +293,20 @@
 	if (link_up) {
 		switch (link_speed) {
 		case IXGBE_LINK_SPEED_10GB_FULL:
-			ecmd->speed = SPEED_10000;
+			ethtool_cmd_speed_set(ecmd, SPEED_10000);
 			break;
 		case IXGBE_LINK_SPEED_1GB_FULL:
-			ecmd->speed = SPEED_1000;
+			ethtool_cmd_speed_set(ecmd, SPEED_1000);
 			break;
 		case IXGBE_LINK_SPEED_100_FULL:
-			ecmd->speed = SPEED_100;
+			ethtool_cmd_speed_set(ecmd, SPEED_100);
 			break;
 		default:
 			break;
 		}
 		ecmd->duplex = DUPLEX_FULL;
 	} else {
-		ecmd->speed = -1;
+		ethtool_cmd_speed_set(ecmd, -1);
 		ecmd->duplex = -1;
 	}
 
@@ -346,9 +351,10 @@
 		}
 	} else {
 		/* in this case we currently only support 10Gb/FULL */
+		u32 speed = ethtool_cmd_speed(ecmd);
 		if ((ecmd->autoneg == AUTONEG_ENABLE) ||
 		    (ecmd->advertising != ADVERTISED_10000baseT_Full) ||
-		    (ecmd->speed + ecmd->duplex != SPEED_10000 + DUPLEX_FULL))
+		    (speed + ecmd->duplex != SPEED_10000 + DUPLEX_FULL))
 			return -EINVAL;
 	}
 
@@ -846,11 +852,8 @@
 	if (!eeprom_buff)
 		return -ENOMEM;
 
-	for (i = 0; i < eeprom_len; i++) {
-		if ((ret_val = hw->eeprom.ops.read(hw, first_word + i,
-		    &eeprom_buff[i])))
-			break;
-	}
+	ret_val = hw->eeprom.ops.read_buffer(hw, first_word, eeprom_len,
+					     eeprom_buff);
 
 	/* Device's eeprom is always little-endian, word addressable */
 	for (i = 0; i < eeprom_len; i++)
@@ -931,7 +934,7 @@
 	}
 
 	while (test_and_set_bit(__IXGBE_RESETTING, &adapter->state))
-		msleep(1);
+		usleep_range(1000, 2000);
 
 	if (!netif_running(adapter->netdev)) {
 		for (i = 0; i < adapter->num_tx_queues; i++)
@@ -1030,9 +1033,6 @@
 		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;
 	}
@@ -1238,46 +1238,62 @@
 	{ 0, 0, 0, 0 }
 };
 
-static const u32 register_test_patterns[] = {
-	0x5A5A5A5A, 0xA5A5A5A5, 0x00000000, 0xFFFFFFFF
-};
+static bool reg_pattern_test(struct ixgbe_adapter *adapter, u64 *data, int reg,
+			     u32 mask, u32 write)
+{
+	u32 pat, val, before;
+	static const u32 test_pattern[] = {
+		0x5A5A5A5A, 0xA5A5A5A5, 0x00000000, 0xFFFFFFFF};
 
-#define REG_PATTERN_TEST(R, M, W)                                             \
-{                                                                             \
-	u32 pat, val, before;                                                 \
-	for (pat = 0; pat < ARRAY_SIZE(register_test_patterns); pat++) {      \
-		before = readl(adapter->hw.hw_addr + R);                      \
-		writel((register_test_patterns[pat] & W),                     \
-		       (adapter->hw.hw_addr + R));                            \
-		val = readl(adapter->hw.hw_addr + R);                         \
-		if (val != (register_test_patterns[pat] & W & M)) {           \
-			e_err(drv, "pattern test reg %04X failed: got "       \
-			      "0x%08X expected 0x%08X\n",                     \
-			      R, val, (register_test_patterns[pat] & W & M)); \
-			*data = R;                                            \
-			writel(before, adapter->hw.hw_addr + R);              \
-			return 1;                                             \
-		}                                                             \
-		writel(before, adapter->hw.hw_addr + R);                      \
-	}                                                                     \
+	for (pat = 0; pat < ARRAY_SIZE(test_pattern); pat++) {
+		before = readl(adapter->hw.hw_addr + reg);
+		writel((test_pattern[pat] & write),
+		       (adapter->hw.hw_addr + reg));
+		val = readl(adapter->hw.hw_addr + reg);
+		if (val != (test_pattern[pat] & write & mask)) {
+			e_err(drv, "pattern test reg %04X failed: got "
+			      "0x%08X expected 0x%08X\n",
+			      reg, val, (test_pattern[pat] & write & mask));
+			*data = reg;
+			writel(before, adapter->hw.hw_addr + reg);
+			return 1;
+		}
+		writel(before, adapter->hw.hw_addr + reg);
+	}
+	return 0;
 }
 
-#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)) {                                           \
-		e_err(drv, "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 bool reg_set_and_check(struct ixgbe_adapter *adapter, u64 *data, int reg,
+			      u32 mask, u32 write)
+{
+	u32 val, before;
+	before = readl(adapter->hw.hw_addr + reg);
+	writel((write & mask), (adapter->hw.hw_addr + reg));
+	val = readl(adapter->hw.hw_addr + reg);
+	if ((write & mask) != (val & mask)) {
+		e_err(drv, "set/check reg %04X test failed: got 0x%08X "
+		      "expected 0x%08X\n", reg, (val & mask), (write & mask));
+		*data = reg;
+		writel(before, (adapter->hw.hw_addr + reg));
+		return 1;
+	}
+	writel(before, (adapter->hw.hw_addr + reg));
+	return 0;
 }
 
+#define REG_PATTERN_TEST(reg, mask, write)				      \
+	do {								      \
+		if (reg_pattern_test(adapter, data, reg, mask, write))	      \
+			return 1;					      \
+	} while (0)							      \
+
+
+#define REG_SET_AND_CHECK(reg, mask, write)				      \
+	do {								      \
+		if (reg_set_and_check(adapter, data, reg, mask, write))	      \
+			return 1;					      \
+	} while (0)							      \
+
 static int ixgbe_reg_test(struct ixgbe_adapter *adapter, u64 *data)
 {
 	const struct ixgbe_reg_test *test;
@@ -1328,13 +1344,13 @@
 			switch (test->test_type) {
 			case PATTERN_TEST:
 				REG_PATTERN_TEST(test->reg + (i * 0x40),
-						test->mask,
-						test->write);
+						 test->mask,
+						 test->write);
 				break;
 			case SET_READ_TEST:
 				REG_SET_AND_CHECK(test->reg + (i * 0x40),
-						test->mask,
-						test->write);
+						  test->mask,
+						  test->write);
 				break;
 			case WRITE_NO_TEST:
 				writel(test->write,
@@ -1343,18 +1359,18 @@
 				break;
 			case TABLE32_TEST:
 				REG_PATTERN_TEST(test->reg + (i * 4),
-						test->mask,
-						test->write);
+						 test->mask,
+						 test->write);
 				break;
 			case TABLE64_TEST_LO:
 				REG_PATTERN_TEST(test->reg + (i * 8),
-						test->mask,
-						test->write);
+						 test->mask,
+						 test->write);
 				break;
 			case TABLE64_TEST_HI:
 				REG_PATTERN_TEST((test->reg + 4) + (i * 8),
-						test->mask,
-						test->write);
+						 test->mask,
+						 test->write);
 				break;
 			}
 		}
@@ -1417,7 +1433,7 @@
 
 	/* Disable all the interrupts */
 	IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMC, 0xFFFFFFFF);
-	msleep(10);
+	usleep_range(10000, 20000);
 
 	/* Test each interrupt */
 	for (; i < 10; i++) {
@@ -1437,7 +1453,7 @@
 			                ~mask & 0x00007FFF);
 			IXGBE_WRITE_REG(&adapter->hw, IXGBE_EICS,
 			                ~mask & 0x00007FFF);
-			msleep(10);
+			usleep_range(10000, 20000);
 
 			if (adapter->test_icr & mask) {
 				*data = 3;
@@ -1454,7 +1470,7 @@
 		adapter->test_icr = 0;
 		IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMS, mask);
 		IXGBE_WRITE_REG(&adapter->hw, IXGBE_EICS, mask);
-		msleep(10);
+		usleep_range(10000, 20000);
 
 		if (!(adapter->test_icr &mask)) {
 			*data = 4;
@@ -1474,7 +1490,7 @@
 			                ~mask & 0x00007FFF);
 			IXGBE_WRITE_REG(&adapter->hw, IXGBE_EICS,
 			                ~mask & 0x00007FFF);
-			msleep(10);
+			usleep_range(10000, 20000);
 
 			if (adapter->test_icr) {
 				*data = 5;
@@ -1485,7 +1501,7 @@
 
 	/* Disable all the interrupts */
 	IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMC, 0xFFFFFFFF);
-	msleep(10);
+	usleep_range(10000, 20000);
 
 	/* Unhook test interrupt handler */
 	free_irq(irq, netdev);
@@ -1598,6 +1614,13 @@
 	struct ixgbe_hw *hw = &adapter->hw;
 	u32 reg_data;
 
+	/* X540 needs to set the MACC.FLU bit to force link up */
+	if (adapter->hw.mac.type == ixgbe_mac_X540) {
+		reg_data = IXGBE_READ_REG(&adapter->hw, IXGBE_MACC);
+		reg_data |= IXGBE_MACC_FLU;
+		IXGBE_WRITE_REG(&adapter->hw, IXGBE_MACC, reg_data);
+	}
+
 	/* right now we only support MAC loopback in the driver */
 	reg_data = IXGBE_READ_REG(&adapter->hw, IXGBE_HLREG0);
 	/* Setup MAC loopback */
@@ -1613,7 +1636,7 @@
 	reg_data |= IXGBE_AUTOC_LMS_10G_LINK_NO_AN | IXGBE_AUTOC_FLU;
 	IXGBE_WRITE_REG(&adapter->hw, IXGBE_AUTOC, reg_data);
 	IXGBE_WRITE_FLUSH(&adapter->hw);
-	msleep(10);
+	usleep_range(10000, 20000);
 
 	/* Disable Atlas Tx lanes; re-enabled in reset path */
 	if (hw->mac.type == ixgbe_mac_82598EB) {
@@ -1999,25 +2022,30 @@
 	return 0;
 }
 
-static int ixgbe_phys_id(struct net_device *netdev, u32 data)
+static int ixgbe_set_phys_id(struct net_device *netdev,
+			     enum ethtool_phys_id_state state)
 {
 	struct ixgbe_adapter *adapter = netdev_priv(netdev);
 	struct ixgbe_hw *hw = &adapter->hw;
-	u32 led_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL);
-	u32 i;
 
-	if (!data || data > 300)
-		data = 300;
+	switch (state) {
+	case ETHTOOL_ID_ACTIVE:
+		adapter->led_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL);
+		return 2;
 
-	for (i = 0; i < (data * 1000); i += 400) {
+	case ETHTOOL_ID_ON:
 		hw->mac.ops.led_on(hw, IXGBE_LED_ON);
-		msleep_interruptible(200);
+		break;
+
+	case ETHTOOL_ID_OFF:
 		hw->mac.ops.led_off(hw, IXGBE_LED_ON);
-		msleep_interruptible(200);
-	}
+		break;
 
-	/* Restore LED settings */
-	IXGBE_WRITE_REG(&adapter->hw, IXGBE_LEDCTL, led_reg);
+	case ETHTOOL_ID_INACTIVE:
+		/* Restore LED settings */
+		IXGBE_WRITE_REG(&adapter->hw, IXGBE_LEDCTL, adapter->led_reg);
+		break;
+	}
 
 	return 0;
 }
@@ -2230,8 +2258,13 @@
 	need_reset = (data & ETH_FLAG_RXVLAN) !=
 		     (netdev->features & NETIF_F_HW_VLAN_RX);
 
+	if ((data & ETH_FLAG_RXHASH) &&
+	    !(adapter->flags & IXGBE_FLAG_RSS_ENABLED))
+		return -EOPNOTSUPP;
+
 	rc = ethtool_op_set_flags(netdev, data, ETH_FLAG_LRO | ETH_FLAG_NTUPLE |
-					ETH_FLAG_RXVLAN | ETH_FLAG_TXVLAN);
+				  ETH_FLAG_RXVLAN | ETH_FLAG_TXVLAN |
+				  ETH_FLAG_RXHASH);
 	if (rc)
 		return rc;
 
@@ -2465,7 +2498,7 @@
 	.set_tso                = ixgbe_set_tso,
 	.self_test              = ixgbe_diag_test,
 	.get_strings            = ixgbe_get_strings,
-	.phys_id                = ixgbe_phys_id,
+	.set_phys_id            = ixgbe_set_phys_id,
 	.get_sset_count         = ixgbe_get_sset_count,
 	.get_ethtool_stats      = ixgbe_get_ethtool_stats,
 	.get_coalesce           = ixgbe_get_coalesce,
diff -druN linux-2.6.39-libre/drivers/net/ixgbe/ixgbe_fcoe.c linux-3.0-rc7-libre/drivers/net/ixgbe/ixgbe_fcoe.c
--- linux-2.6.39-libre/drivers/net/ixgbe/ixgbe_fcoe.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/ixgbe/ixgbe_fcoe.c	2011-07-11 19:51:52.000000000 -0400
@@ -416,8 +416,7 @@
 	if (!ddp->udl)
 		goto ddp_out;
 
-	ddp->err = (fcerr | fceofe);
-	if (ddp->err)
+	if (fcerr | fceofe)
 		goto ddp_out;
 
 	fcstat = (sterr & IXGBE_RXDADV_STAT_FCSTAT);
@@ -428,6 +427,7 @@
 		if (fcstat == IXGBE_RXDADV_STAT_FCSTAT_FCPRSP) {
 			pci_unmap_sg(adapter->pdev, ddp->sgl,
 				     ddp->sgc, DMA_FROM_DEVICE);
+			ddp->err = (fcerr | fceofe);
 			ddp->sgl = NULL;
 			ddp->sgc = 0;
 		}
diff -druN linux-2.6.39-libre/drivers/net/ixgbe/ixgbe.h linux-3.0-rc7-libre/drivers/net/ixgbe/ixgbe.h
--- linux-2.6.39-libre/drivers/net/ixgbe/ixgbe.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/ixgbe/ixgbe.h	2011-07-11 19:51:52.000000000 -0400
@@ -106,6 +106,7 @@
 #define IXGBE_MAX_VF_FUNCTIONS          64
 #define IXGBE_MAX_VFTA_ENTRIES          128
 #define MAX_EMULATION_MAC_ADDRS         16
+#define IXGBE_MAX_PF_MACVLANS           15
 #define VMDQ_P(p)   ((p) + adapter->num_vfs)
 
 struct vf_data_storage {
@@ -121,6 +122,15 @@
 	u16 tx_rate;
 };
 
+struct vf_macvlans {
+	struct list_head l;
+	int vf;
+	int rar_entry;
+	bool free;
+	bool is_macvlan;
+	u8 vf_macvlan[ETH_ALEN];
+};
+
 /* wrapper around a pointer to a socket buffer,
  * so a DMA handle can be stored along with the buffer */
 struct ixgbe_tx_buffer {
@@ -331,10 +341,52 @@
 
 /* board specific private data structure */
 struct ixgbe_adapter {
-	struct timer_list watchdog_timer;
+	unsigned long state;
+
+	/* Some features need tri-state capability,
+	 * thus the additional *_CAPABLE flags.
+	 */
+	u32 flags;
+#define IXGBE_FLAG_RX_CSUM_ENABLED              (u32)(1)
+#define IXGBE_FLAG_MSI_CAPABLE                  (u32)(1 << 1)
+#define IXGBE_FLAG_MSI_ENABLED                  (u32)(1 << 2)
+#define IXGBE_FLAG_MSIX_CAPABLE                 (u32)(1 << 3)
+#define IXGBE_FLAG_MSIX_ENABLED                 (u32)(1 << 4)
+#define IXGBE_FLAG_RX_1BUF_CAPABLE              (u32)(1 << 6)
+#define IXGBE_FLAG_RX_PS_CAPABLE                (u32)(1 << 7)
+#define IXGBE_FLAG_RX_PS_ENABLED                (u32)(1 << 8)
+#define IXGBE_FLAG_IN_NETPOLL                   (u32)(1 << 9)
+#define IXGBE_FLAG_DCA_ENABLED                  (u32)(1 << 10)
+#define IXGBE_FLAG_DCA_CAPABLE                  (u32)(1 << 11)
+#define IXGBE_FLAG_IMIR_ENABLED                 (u32)(1 << 12)
+#define IXGBE_FLAG_MQ_CAPABLE                   (u32)(1 << 13)
+#define IXGBE_FLAG_DCB_ENABLED                  (u32)(1 << 14)
+#define IXGBE_FLAG_RSS_ENABLED                  (u32)(1 << 16)
+#define IXGBE_FLAG_RSS_CAPABLE                  (u32)(1 << 17)
+#define IXGBE_FLAG_VMDQ_CAPABLE                 (u32)(1 << 18)
+#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_NEED_LINK_CONFIG             (u32)(1 << 23)
+#define IXGBE_FLAG_FDIR_HASH_CAPABLE            (u32)(1 << 24)
+#define IXGBE_FLAG_FDIR_PERFECT_CAPABLE         (u32)(1 << 25)
+#define IXGBE_FLAG_FCOE_CAPABLE                 (u32)(1 << 26)
+#define IXGBE_FLAG_FCOE_ENABLED                 (u32)(1 << 27)
+#define IXGBE_FLAG_SRIOV_CAPABLE                (u32)(1 << 28)
+#define IXGBE_FLAG_SRIOV_ENABLED                (u32)(1 << 29)
+
+	u32 flags2;
+#define IXGBE_FLAG2_RSC_CAPABLE                 (u32)(1)
+#define IXGBE_FLAG2_RSC_ENABLED                 (u32)(1 << 1)
+#define IXGBE_FLAG2_TEMP_SENSOR_CAPABLE         (u32)(1 << 2)
+#define IXGBE_FLAG2_TEMP_SENSOR_EVENT           (u32)(1 << 3)
+#define IXGBE_FLAG2_SEARCH_FOR_SFP              (u32)(1 << 4)
+#define IXGBE_FLAG2_SFP_NEEDS_RESET             (u32)(1 << 5)
+#define IXGBE_FLAG2_RESET_REQUESTED             (u32)(1 << 6)
+#define IXGBE_FLAG2_FDIR_REQUIRES_REINIT        (u32)(1 << 7)
+
 	unsigned long active_vlans[BITS_TO_LONGS(VLAN_N_VID)];
 	u16 bd_number;
-	struct work_struct reset_task;
 	struct ixgbe_q_vector *q_vector[MAX_MSIX_Q_VECTORS];
 
 	/* DCB parameters */
@@ -377,43 +429,6 @@
 	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_MSI_CAPABLE                  (u32)(1 << 1)
-#define IXGBE_FLAG_MSI_ENABLED                  (u32)(1 << 2)
-#define IXGBE_FLAG_MSIX_CAPABLE                 (u32)(1 << 3)
-#define IXGBE_FLAG_MSIX_ENABLED                 (u32)(1 << 4)
-#define IXGBE_FLAG_RX_1BUF_CAPABLE              (u32)(1 << 6)
-#define IXGBE_FLAG_RX_PS_CAPABLE                (u32)(1 << 7)
-#define IXGBE_FLAG_RX_PS_ENABLED                (u32)(1 << 8)
-#define IXGBE_FLAG_IN_NETPOLL                   (u32)(1 << 9)
-#define IXGBE_FLAG_DCA_ENABLED                  (u32)(1 << 10)
-#define IXGBE_FLAG_DCA_CAPABLE                  (u32)(1 << 11)
-#define IXGBE_FLAG_IMIR_ENABLED                 (u32)(1 << 12)
-#define IXGBE_FLAG_MQ_CAPABLE                   (u32)(1 << 13)
-#define IXGBE_FLAG_DCB_ENABLED                  (u32)(1 << 14)
-#define IXGBE_FLAG_RSS_ENABLED                  (u32)(1 << 16)
-#define IXGBE_FLAG_RSS_CAPABLE                  (u32)(1 << 17)
-#define IXGBE_FLAG_VMDQ_CAPABLE                 (u32)(1 << 18)
-#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_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)
-#define IXGBE_FLAG2_RSC_ENABLED                 (u32)(1 << 1)
-#define IXGBE_FLAG2_TEMP_SENSOR_CAPABLE         (u32)(1 << 2)
 /* default to trying for four seconds */
 #define IXGBE_TRY_LINK_TIMEOUT (4 * HZ)
 
@@ -434,7 +449,6 @@
 	u32 rx_eitr_param;
 	u32 tx_eitr_param;
 
-	unsigned long state;
 	u64 tx_busy;
 	unsigned int tx_ring_count;
 	unsigned int rx_ring_count;
@@ -443,15 +457,12 @@
 	bool link_up;
 	unsigned long link_check_timeout;
 
-	struct work_struct watchdog_task;
-	struct work_struct sfp_task;
-	struct timer_list sfp_timer;
-	struct work_struct multispeed_fiber_task;
-	struct work_struct sfp_config_module_task;
+	struct work_struct service_task;
+	struct timer_list service_timer;
 	u32 fdir_pballoc;
 	u32 atr_sample_rate;
+	unsigned long fdir_overflow; /* number of times ATR was backed off */
 	spinlock_t fdir_perfect_lock;
-	struct work_struct fdir_reinit_task;
 #ifdef IXGBE_FCOE
 	struct ixgbe_fcoe fcoe;
 #endif /* IXGBE_FCOE */
@@ -461,7 +472,7 @@
 	u16 eeprom_version;
 
 	int node;
-	struct work_struct check_overtemp_task;
+	u32 led_reg;
 	u32 interrupt_event;
 	char lsc_int_name[IFNAMSIZ + 9];
 
@@ -470,13 +481,17 @@
 	unsigned int num_vfs;
 	struct vf_data_storage *vfinfo;
 	int vf_rate_link_speed;
+	struct vf_macvlans vf_mvs;
+	struct vf_macvlans *mv_list;
+	bool antispoofing_enabled;
 };
 
 enum ixbge_state_t {
 	__IXGBE_TESTING,
 	__IXGBE_RESETTING,
 	__IXGBE_DOWN,
-	__IXGBE_SFP_MODULE_NOT_FOUND
+	__IXGBE_SERVICE_SCHED,
+	__IXGBE_IN_SFP_INIT,
 };
 
 struct ixgbe_rsc_cb {
diff -druN linux-2.6.39-libre/drivers/net/ixgbe/ixgbe_main.c linux-3.0-rc7-libre/drivers/net/ixgbe/ixgbe_main.c
--- linux-2.6.39-libre/drivers/net/ixgbe/ixgbe_main.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/ixgbe/ixgbe_main.c	2011-07-11 19:51:52.000000000 -0400
@@ -41,6 +41,7 @@
 #include <net/ip6_checksum.h>
 #include <linux/ethtool.h>
 #include <linux/if_vlan.h>
+#include <linux/prefetch.h>
 #include <scsi/fc/fc_fcoe.h>
 
 #include "ixgbe.h"
@@ -51,8 +52,12 @@
 char ixgbe_driver_name[] = "ixgbe";
 static const char ixgbe_driver_string[] =
 			      "Intel(R) 10 Gigabit PCI Express Network Driver";
-
-#define DRV_VERSION "3.2.9-k2"
+#define MAJ 3
+#define MIN 3
+#define BUILD 8
+#define KFIX 2
+#define DRV_VERSION __stringify(MAJ) "." __stringify(MIN) "." \
+	__stringify(BUILD) "-k" __stringify(KFIX)
 const char ixgbe_driver_version[] = DRV_VERSION;
 static const char ixgbe_copyright[] =
 				"Copyright (c) 1999-2011 Intel Corporation.";
@@ -120,6 +125,10 @@
 	 board_82599 },
 	{PCI_VDEVICE(INTEL, IXGBE_DEV_ID_X540T),
 	 board_X540 },
+	{PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82599_SFP_SF2),
+	 board_82599 },
+	{PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82599_LS),
+	 board_82599 },
 
 	/* required last entry */
 	{0, }
@@ -185,6 +194,22 @@
 	adapter->flags &= ~IXGBE_FLAG_SRIOV_ENABLED;
 }
 
+static void ixgbe_service_event_schedule(struct ixgbe_adapter *adapter)
+{
+	if (!test_bit(__IXGBE_DOWN, &adapter->state) &&
+	    !test_and_set_bit(__IXGBE_SERVICE_SCHED, &adapter->state))
+		schedule_work(&adapter->service_task);
+}
+
+static void ixgbe_service_event_complete(struct ixgbe_adapter *adapter)
+{
+	BUG_ON(!test_bit(__IXGBE_SERVICE_SCHED, &adapter->state));
+
+	/* flush memory to make sure state is correct before next watchog */
+	smp_mb__before_clear_bit();
+	clear_bit(__IXGBE_SERVICE_SCHED, &adapter->state);
+}
+
 struct ixgbe_reg_info {
 	u32 ofs;
 	char *name;
@@ -811,7 +836,19 @@
 #define DESC_NEEDED (TXD_USE_COUNT(IXGBE_MAX_DATA_PER_TXD) /* skb->data */ + \
 	MAX_SKB_FRAGS * TXD_USE_COUNT(PAGE_SIZE) + 1) /* for context */
 
-static void ixgbe_tx_timeout(struct net_device *netdev);
+/**
+ * ixgbe_tx_timeout_reset - initiate reset due to Tx timeout
+ * @adapter: driver private struct
+ **/
+static void ixgbe_tx_timeout_reset(struct ixgbe_adapter *adapter)
+{
+
+	/* Do the reset outside of interrupt context */
+	if (!test_bit(__IXGBE_DOWN, &adapter->state)) {
+		adapter->flags2 |= IXGBE_FLAG2_RESET_REQUESTED;
+		ixgbe_service_event_schedule(adapter);
+	}
+}
 
 /**
  * ixgbe_clean_tx_irq - Reclaim resources after transmit completes
@@ -893,7 +930,7 @@
 			adapter->tx_timeout_count + 1, tx_ring->queue_index);
 
 		/* schedule immediate reset if we believe we hung */
-		ixgbe_tx_timeout(adapter->netdev);
+		ixgbe_tx_timeout_reset(adapter);
 
 		/* the adapter is about to reset, no point in enabling stuff */
 		return true;
@@ -943,8 +980,6 @@
 	rxctrl |= IXGBE_DCA_RXCTRL_DESC_DCA_EN;
 	rxctrl |= IXGBE_DCA_RXCTRL_HEAD_DCA_EN;
 	rxctrl &= ~(IXGBE_DCA_RXCTRL_DESC_RRO_EN);
-	rxctrl &= ~(IXGBE_DCA_RXCTRL_DESC_WRO_EN |
-		    IXGBE_DCA_RXCTRL_DESC_HSRO_EN);
 	IXGBE_WRITE_REG(hw, IXGBE_DCA_RXCTRL(reg_idx), rxctrl);
 }
 
@@ -962,7 +997,6 @@
 		txctrl &= ~IXGBE_DCA_TXCTRL_CPUID_MASK;
 		txctrl |= dca3_get_tag(&adapter->pdev->dev, cpu);
 		txctrl |= IXGBE_DCA_TXCTRL_DESC_DCA_EN;
-		txctrl &= ~IXGBE_DCA_TXCTRL_TX_WB_RO_EN;
 		IXGBE_WRITE_REG(hw, IXGBE_DCA_TXCTRL(reg_idx), txctrl);
 		break;
 	case ixgbe_mac_82599EB:
@@ -972,7 +1006,6 @@
 		txctrl |= (dca3_get_tag(&adapter->pdev->dev, cpu) <<
 			   IXGBE_DCA_TXCTRL_CPUID_SHIFT_82599);
 		txctrl |= IXGBE_DCA_TXCTRL_DESC_DCA_EN;
-		txctrl &= ~IXGBE_DCA_TXCTRL_TX_WB_RO_EN;
 		IXGBE_WRITE_REG(hw, IXGBE_DCA_TXCTRL_82599(reg_idx), txctrl);
 		break;
 	default:
@@ -1061,8 +1094,14 @@
 
 	return 0;
 }
-
 #endif /* CONFIG_IXGBE_DCA */
+
+static inline void ixgbe_rx_hash(union ixgbe_adv_rx_desc *rx_desc,
+				 struct sk_buff *skb)
+{
+	skb->rxhash = le32_to_cpu(rx_desc->wb.lower.hi_dword.rss);
+}
+
 /**
  * ixgbe_receive_skb - Send a completed packet up the stack
  * @adapter: board private structure
@@ -1454,6 +1493,8 @@
 		}
 
 		ixgbe_rx_checksum(adapter, rx_desc, skb);
+		if (adapter->netdev->features & NETIF_F_RXHASH)
+			ixgbe_rx_hash(rx_desc, skb);
 
 		/* probably a little skewed due to removing CRC */
 		total_rx_bytes += skb->len;
@@ -1787,35 +1828,51 @@
 }
 
 /**
- * ixgbe_check_overtemp_task - worker thread to check over tempurature
- * @work: pointer to work_struct containing our data
+ * ixgbe_check_overtemp_subtask - check for over tempurature
+ * @adapter: pointer to adapter
  **/
-static void ixgbe_check_overtemp_task(struct work_struct *work)
+static void ixgbe_check_overtemp_subtask(struct ixgbe_adapter *adapter)
 {
-	struct ixgbe_adapter *adapter = container_of(work,
-						     struct ixgbe_adapter,
-						     check_overtemp_task);
 	struct ixgbe_hw *hw = &adapter->hw;
 	u32 eicr = adapter->interrupt_event;
 
-	if (!(adapter->flags2 & IXGBE_FLAG2_TEMP_SENSOR_CAPABLE))
+	if (test_bit(__IXGBE_DOWN, &adapter->state))
 		return;
 
+	if (!(adapter->flags2 & IXGBE_FLAG2_TEMP_SENSOR_CAPABLE) &&
+	    !(adapter->flags2 & IXGBE_FLAG2_TEMP_SENSOR_EVENT))
+		return;
+
+	adapter->flags2 &= ~IXGBE_FLAG2_TEMP_SENSOR_EVENT;
+
 	switch (hw->device_id) {
-	case IXGBE_DEV_ID_82599_T3_LOM: {
-		u32 autoneg;
-		bool link_up = false;
+	case IXGBE_DEV_ID_82599_T3_LOM:
+		/*
+		 * Since the warning interrupt is for both ports
+		 * we don't have to check if:
+		 *  - This interrupt wasn't for our port.
+		 *  - We may have missed the interrupt so always have to
+		 *    check if we  got a LSC
+		 */
+		if (!(eicr & IXGBE_EICR_GPI_SDP0) &&
+		    !(eicr & IXGBE_EICR_LSC))
+			return;
+
+		if (!(eicr & IXGBE_EICR_LSC) && hw->mac.ops.check_link) {
+			u32 autoneg;
+			bool link_up = false;
 
-		if (hw->mac.ops.check_link)
 			hw->mac.ops.check_link(hw, &autoneg, &link_up, false);
 
-		if (((eicr & IXGBE_EICR_GPI_SDP0) && (!link_up)) ||
-		    (eicr & IXGBE_EICR_LSC))
-			/* Check if this is due to overtemp */
-			if (hw->phy.ops.check_overtemp(hw) == IXGBE_ERR_OVERTEMP)
-				break;
-		return;
-	}
+			if (link_up)
+				return;
+		}
+
+		/* Check if this is not due to overtemp */
+		if (hw->phy.ops.check_overtemp(hw) != IXGBE_ERR_OVERTEMP)
+			return;
+
+		break;
 	default:
 		if (!(eicr & IXGBE_EICR_GPI_SDP0))
 			return;
@@ -1825,8 +1882,8 @@
 	       "Network adapter has been stopped because it has over heated. "
 	       "Restart the computer. If the problem persists, "
 	       "power off the system and replace the adapter\n");
-	/* write to clear the interrupt */
-	IXGBE_WRITE_REG(hw, IXGBE_EICR, IXGBE_EICR_GPI_SDP0);
+
+	adapter->interrupt_event = 0;
 }
 
 static void ixgbe_check_fan_failure(struct ixgbe_adapter *adapter, u32 eicr)
@@ -1848,15 +1905,19 @@
 	if (eicr & IXGBE_EICR_GPI_SDP2) {
 		/* Clear the interrupt */
 		IXGBE_WRITE_REG(hw, IXGBE_EICR, IXGBE_EICR_GPI_SDP2);
-		if (!test_bit(__IXGBE_DOWN, &adapter->state))
-			schedule_work(&adapter->sfp_config_module_task);
+		if (!test_bit(__IXGBE_DOWN, &adapter->state)) {
+			adapter->flags2 |= IXGBE_FLAG2_SFP_NEEDS_RESET;
+			ixgbe_service_event_schedule(adapter);
+		}
 	}
 
 	if (eicr & IXGBE_EICR_GPI_SDP1) {
 		/* Clear the interrupt */
 		IXGBE_WRITE_REG(hw, IXGBE_EICR, IXGBE_EICR_GPI_SDP1);
-		if (!test_bit(__IXGBE_DOWN, &adapter->state))
-			schedule_work(&adapter->multispeed_fiber_task);
+		if (!test_bit(__IXGBE_DOWN, &adapter->state)) {
+			adapter->flags |= IXGBE_FLAG_NEED_LINK_CONFIG;
+			ixgbe_service_event_schedule(adapter);
+		}
 	}
 }
 
@@ -1870,7 +1931,7 @@
 	if (!test_bit(__IXGBE_DOWN, &adapter->state)) {
 		IXGBE_WRITE_REG(hw, IXGBE_EIMC, IXGBE_EIMC_LSC);
 		IXGBE_WRITE_FLUSH(hw);
-		schedule_work(&adapter->watchdog_task);
+		ixgbe_service_event_schedule(adapter);
 	}
 }
 
@@ -1898,26 +1959,32 @@
 
 	switch (hw->mac.type) {
 	case ixgbe_mac_82599EB:
-		ixgbe_check_sfp_event(adapter, eicr);
-		if ((adapter->flags2 & IXGBE_FLAG2_TEMP_SENSOR_CAPABLE) &&
-		    ((eicr & IXGBE_EICR_GPI_SDP0) || (eicr & IXGBE_EICR_LSC))) {
-			adapter->interrupt_event = eicr;
-			schedule_work(&adapter->check_overtemp_task);
-		}
-		/* now fallthrough to handle Flow Director */
 	case ixgbe_mac_X540:
 		/* Handle Flow Director Full threshold interrupt */
 		if (eicr & IXGBE_EICR_FLOW_DIR) {
+			int reinit_count = 0;
 			int i;
-			IXGBE_WRITE_REG(hw, IXGBE_EICR, IXGBE_EICR_FLOW_DIR);
-			/* Disable transmits before FDIR Re-initialization */
-			netif_tx_stop_all_queues(netdev);
 			for (i = 0; i < adapter->num_tx_queues; i++) {
-				struct ixgbe_ring *tx_ring =
-							    adapter->tx_ring[i];
+				struct ixgbe_ring *ring = adapter->tx_ring[i];
 				if (test_and_clear_bit(__IXGBE_TX_FDIR_INIT_DONE,
-						       &tx_ring->state))
-					schedule_work(&adapter->fdir_reinit_task);
+						       &ring->state))
+					reinit_count++;
+			}
+			if (reinit_count) {
+				/* no more flow director interrupts until after init */
+				IXGBE_WRITE_REG(hw, IXGBE_EIMC, IXGBE_EIMC_FLOW_DIR);
+				eicr &= ~IXGBE_EICR_FLOW_DIR;
+				adapter->flags2 |= IXGBE_FLAG2_FDIR_REQUIRES_REINIT;
+				ixgbe_service_event_schedule(adapter);
+			}
+		}
+		ixgbe_check_sfp_event(adapter, eicr);
+		if ((adapter->flags2 & IXGBE_FLAG2_TEMP_SENSOR_CAPABLE) &&
+		    ((eicr & IXGBE_EICR_GPI_SDP0) || (eicr & IXGBE_EICR_LSC))) {
+			if (!test_bit(__IXGBE_DOWN, &adapter->state)) {
+				adapter->interrupt_event = eicr;
+				adapter->flags2 |= IXGBE_FLAG2_TEMP_SENSOR_EVENT;
+				ixgbe_service_event_schedule(adapter);
 			}
 		}
 		break;
@@ -1927,8 +1994,10 @@
 
 	ixgbe_check_fan_failure(adapter, eicr);
 
+	/* re-enable the original interrupt state, no lsc, no queues */
 	if (!test_bit(__IXGBE_DOWN, &adapter->state))
-		IXGBE_WRITE_REG(hw, IXGBE_EIMS, IXGBE_EIMS_OTHER);
+		IXGBE_WRITE_REG(hw, IXGBE_EIMS, eicr &
+		                ~(IXGBE_EIMS_LSC | IXGBE_EIMS_RTX_QUEUE));
 
 	return IRQ_HANDLED;
 }
@@ -2513,8 +2582,11 @@
 		ixgbe_check_sfp_event(adapter, eicr);
 		if ((adapter->flags2 & IXGBE_FLAG2_TEMP_SENSOR_CAPABLE) &&
 		    ((eicr & IXGBE_EICR_GPI_SDP0) || (eicr & IXGBE_EICR_LSC))) {
-			adapter->interrupt_event = eicr;
-			schedule_work(&adapter->check_overtemp_task);
+			if (!test_bit(__IXGBE_DOWN, &adapter->state)) {
+				adapter->interrupt_event = eicr;
+				adapter->flags2 |= IXGBE_FLAG2_TEMP_SENSOR_EVENT;
+				ixgbe_service_event_schedule(adapter);
+			}
 		}
 		break;
 	default:
@@ -2731,7 +2803,7 @@
 
 	/* poll to verify queue is enabled */
 	do {
-		msleep(1);
+		usleep_range(1000, 2000);
 		txdctl = IXGBE_READ_REG(hw, IXGBE_TXDCTL(reg_idx));
 	} while (--wait_loop && !(txdctl & IXGBE_TXDCTL_ENABLE));
 	if (!wait_loop)
@@ -3023,7 +3095,7 @@
 		return;
 
 	do {
-		msleep(1);
+		usleep_range(1000, 2000);
 		rxdctl = IXGBE_READ_REG(hw, IXGBE_RXDCTL(reg_idx));
 	} while (--wait_loop && !(rxdctl & IXGBE_RXDCTL_ENABLE));
 
@@ -3178,7 +3250,9 @@
 	/* enable Tx loopback for VF/PF communication */
 	IXGBE_WRITE_REG(hw, IXGBE_PFDTXGSWC, IXGBE_PFDTXGSWC_VT_LBEN);
 	/* Enable MAC Anti-Spoofing */
-	hw->mac.ops.set_mac_anti_spoofing(hw, (adapter->num_vfs != 0),
+	hw->mac.ops.set_mac_anti_spoofing(hw,
+					  (adapter->antispoofing_enabled =
+					   (adapter->num_vfs != 0)),
 					  adapter->num_vfs);
 }
 
@@ -3487,7 +3561,7 @@
 	struct ixgbe_adapter *adapter = netdev_priv(netdev);
 	struct ixgbe_hw *hw = &adapter->hw;
 	unsigned int vfn = adapter->num_vfs;
-	unsigned int rar_entries = hw->mac.num_rar_entries - (vfn + 1);
+	unsigned int rar_entries = IXGBE_MAX_PF_MACVLANS;
 	int count = 0;
 
 	/* return ENOMEM indicating insufficient memory for addresses */
@@ -3760,31 +3834,16 @@
  **/
 static void ixgbe_sfp_link_config(struct ixgbe_adapter *adapter)
 {
-	struct ixgbe_hw *hw = &adapter->hw;
+	/*
+	 * We are assuming the worst case scenerio here, and that
+	 * is that an SFP was inserted/removed after the reset
+	 * but before SFP detection was enabled.  As such the best
+	 * solution is to just start searching as soon as we start
+	 */
+	if (adapter->hw.mac.type == ixgbe_mac_82598EB)
+		adapter->flags2 |= IXGBE_FLAG2_SEARCH_FOR_SFP;
 
-		if (hw->phy.multispeed_fiber) {
-			/*
-			 * In multispeed fiber setups, the device may not have
-			 * had a physical connection when the driver loaded.
-			 * If that's the case, the initial link configuration
-			 * couldn't get the MAC into 10G or 1G mode, so we'll
-			 * never have a link status change interrupt fire.
-			 * We need to try and force an autonegotiation
-			 * session, then bring up link.
-			 */
-			if (hw->mac.ops.setup_sfp)
-				hw->mac.ops.setup_sfp(hw);
-			if (!(adapter->flags & IXGBE_FLAG_IN_SFP_LINK_TASK))
-				schedule_work(&adapter->multispeed_fiber_task);
-		} else {
-			/*
-			 * Direct Attach Cu and non-multispeed fiber modules
-			 * still need to be configured properly prior to
-			 * attempting link.
-			 */
-			if (!(adapter->flags & IXGBE_FLAG_IN_SFP_MOD_TASK))
-				schedule_work(&adapter->sfp_config_module_task);
-		}
+	adapter->flags2 |= IXGBE_FLAG2_SFP_NEEDS_RESET;
 }
 
 /**
@@ -3860,9 +3919,10 @@
 	if (adapter->flags & IXGBE_FLAG_FAN_FAIL_CAPABLE)
 		gpie |= IXGBE_SDP1_GPIEN;
 
-	if (hw->mac.type == ixgbe_mac_82599EB)
+	if (hw->mac.type == ixgbe_mac_82599EB) {
 		gpie |= IXGBE_SDP1_GPIEN;
 		gpie |= IXGBE_SDP2_GPIEN;
+	}
 
 	IXGBE_WRITE_REG(hw, IXGBE_GPIE, gpie);
 }
@@ -3913,17 +3973,6 @@
 			e_crit(drv, "Fan has stopped, replace the adapter\n");
 	}
 
-	/*
-	 * For hot-pluggable SFP+ devices, a new SFP+ module may have
-	 * arrived before interrupts were enabled but after probe.  Such
-	 * devices wouldn't have their type identified yet. We need to
-	 * kick off the SFP+ module setup first, then try to bring up link.
-	 * If we're not hot-pluggable SFP+, we just need to configure link
-	 * and bring it up.
-	 */
-	if (hw->phy.type == ixgbe_phy_none)
-		schedule_work(&adapter->sfp_config_module_task);
-
 	/* enable transmits */
 	netif_tx_start_all_queues(adapter->netdev);
 
@@ -3931,7 +3980,7 @@
 	 * 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);
+	mod_timer(&adapter->service_timer, jiffies);
 
 	/* Set PF Reset Done bit so PF/VF Mail Ops can work */
 	ctrl_ext = IXGBE_READ_REG(hw, IXGBE_CTRL_EXT);
@@ -3944,8 +3993,11 @@
 void ixgbe_reinit_locked(struct ixgbe_adapter *adapter)
 {
 	WARN_ON(in_interrupt());
+	/* put off any impending NetWatchDogTimeout */
+	adapter->netdev->trans_start = jiffies;
+
 	while (test_and_set_bit(__IXGBE_RESETTING, &adapter->state))
-		msleep(1);
+		usleep_range(1000, 2000);
 	ixgbe_down(adapter);
 	/*
 	 * If SR-IOV enabled then wait a bit before bringing the adapter
@@ -3972,10 +4024,20 @@
 	struct ixgbe_hw *hw = &adapter->hw;
 	int err;
 
+	/* lock SFP init bit to prevent race conditions with the watchdog */
+	while (test_and_set_bit(__IXGBE_IN_SFP_INIT, &adapter->state))
+		usleep_range(1000, 2000);
+
+	/* clear all SFP and link config related flags while holding SFP_INIT */
+	adapter->flags2 &= ~(IXGBE_FLAG2_SEARCH_FOR_SFP |
+			     IXGBE_FLAG2_SFP_NEEDS_RESET);
+	adapter->flags &= ~IXGBE_FLAG_NEED_LINK_CONFIG;
+
 	err = hw->mac.ops.init_hw(hw);
 	switch (err) {
 	case 0:
 	case IXGBE_ERR_SFP_NOT_PRESENT:
+	case IXGBE_ERR_SFP_NOT_SUPPORTED:
 		break;
 	case IXGBE_ERR_MASTER_REQUESTS_PENDING:
 		e_dev_err("master disable timed out\n");
@@ -3993,6 +4055,8 @@
 		e_dev_err("Hardware Error: %d\n", err);
 	}
 
+	clear_bit(__IXGBE_IN_SFP_INIT, &adapter->state);
+
 	/* reprogram the RAR[0] in case user changed it. */
 	hw->mac.ops.set_rar(hw, 0, hw->mac.addr, adapter->num_vfs,
 			    IXGBE_RAH_AV);
@@ -4121,26 +4185,12 @@
 	struct net_device *netdev = adapter->netdev;
 	struct ixgbe_hw *hw = &adapter->hw;
 	u32 rxctrl;
-	u32 txdctl;
 	int i;
 	int num_q_vectors = adapter->num_msix_vectors - NON_Q_VECTORS;
 
 	/* signal that we are down to the interrupt handler */
 	set_bit(__IXGBE_DOWN, &adapter->state);
 
-	/* 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);
@@ -4150,15 +4200,11 @@
 		/* this call also flushes the previous write */
 		ixgbe_disable_rx_queue(adapter, adapter->rx_ring[i]);
 
-	msleep(10);
+	usleep_range(10000, 20000);
 
 	netif_tx_stop_all_queues(netdev);
 
-	clear_bit(__IXGBE_SFP_MODULE_NOT_FOUND, &adapter->state);
-	del_timer_sync(&adapter->sfp_timer);
-	del_timer_sync(&adapter->watchdog_timer);
-	cancel_work_sync(&adapter->watchdog_task);
-
+	/* call carrier off first to avoid false dev_watchdog timeouts */
 	netif_carrier_off(netdev);
 	netif_tx_disable(netdev);
 
@@ -4166,6 +4212,25 @@
 
 	ixgbe_napi_disable_all(adapter);
 
+	adapter->flags2 &= ~(IXGBE_FLAG2_FDIR_REQUIRES_REINIT |
+			     IXGBE_FLAG2_RESET_REQUESTED);
+	adapter->flags &= ~IXGBE_FLAG_NEED_LINK_UPDATE;
+
+	del_timer_sync(&adapter->service_timer);
+
+	/* 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;
+	}
+
 	/* Cleanup the affinity_hint CPU mask memory and callback */
 	for (i = 0; i < num_q_vectors; i++) {
 		struct ixgbe_q_vector *q_vector = adapter->q_vector[i];
@@ -4175,21 +4240,13 @@
 		free_cpumask_var(q_vector->affinity_mask);
 	}
 
-	if (adapter->flags & IXGBE_FLAG_FDIR_HASH_CAPABLE ||
-	    adapter->flags & IXGBE_FLAG_FDIR_PERFECT_CAPABLE)
-		cancel_work_sync(&adapter->fdir_reinit_task);
-
-	if (adapter->flags2 & IXGBE_FLAG2_TEMP_SENSOR_CAPABLE)
-		cancel_work_sync(&adapter->check_overtemp_task);
-
 	/* disable transmits in the hardware now that interrupts are off */
 	for (i = 0; i < adapter->num_tx_queues; i++) {
 		u8 reg_idx = adapter->tx_ring[i]->reg_idx;
-		txdctl = IXGBE_READ_REG(hw, IXGBE_TXDCTL(reg_idx));
-		IXGBE_WRITE_REG(hw, IXGBE_TXDCTL(reg_idx),
-				(txdctl & ~IXGBE_TXDCTL_ENABLE));
+		IXGBE_WRITE_REG(hw, IXGBE_TXDCTL(reg_idx), IXGBE_TXDCTL_SWFLSH);
 	}
-	/* Disable the Tx DMA engine on 82599 */
+
+	/* Disable the Tx DMA engine on 82599 and X540 */
 	switch (hw->mac.type) {
 	case ixgbe_mac_82599EB:
 	case ixgbe_mac_X540:
@@ -4201,9 +4258,6 @@
 		break;
 	}
 
-	/* clear n-tuple filters that are cached */
-	ethtool_ntuple_flush(netdev);
-
 	if (!pci_channel_offline(adapter->pdev))
 		ixgbe_reset(adapter);
 
@@ -4267,25 +4321,8 @@
 {
 	struct ixgbe_adapter *adapter = netdev_priv(netdev);
 
-	adapter->tx_timeout_count++;
-
 	/* Do the reset outside of interrupt context */
-	schedule_work(&adapter->reset_task);
-}
-
-static void ixgbe_reset_task(struct work_struct *work)
-{
-	struct ixgbe_adapter *adapter;
-	adapter = container_of(work, struct ixgbe_adapter, reset_task);
-
-	/* If we're already down or resetting, just bail */
-	if (test_bit(__IXGBE_DOWN, &adapter->state) ||
-	    test_bit(__IXGBE_RESETTING, &adapter->state))
-		return;
-
-	ixgbe_dump(adapter);
-	netdev_err(adapter->netdev, "Reset adapter\n");
-	ixgbe_reinit_locked(adapter);
+	ixgbe_tx_timeout_reset(adapter);
 }
 
 /**
@@ -4567,8 +4604,8 @@
 #ifdef CONFIG_IXGBE_DCB
 
 /* ixgbe_get_first_reg_idx - Return first register index associated with ring */
-void ixgbe_get_first_reg_idx(struct ixgbe_adapter *adapter, u8 tc,
-			     unsigned int *tx, unsigned int *rx)
+static void ixgbe_get_first_reg_idx(struct ixgbe_adapter *adapter, u8 tc,
+				    unsigned int *tx, unsigned int *rx)
 {
 	struct net_device *dev = adapter->netdev;
 	struct ixgbe_hw *hw = &adapter->hw;
@@ -5100,11 +5137,6 @@
 	return err;
 }
 
-static void ring_free_rcu(struct rcu_head *head)
-{
-	kfree(container_of(head, struct ixgbe_ring, rcu));
-}
-
 /**
  * ixgbe_clear_interrupt_scheme - Clear the current interrupt scheme settings
  * @adapter: board private structure to clear interrupt scheme on
@@ -5126,7 +5158,7 @@
 		/* ixgbe_get_stats64() might access this ring, we must wait
 		 * a grace period before freeing it.
 		 */
-		call_rcu(&ring->rcu, ring_free_rcu);
+		kfree_rcu(ring, rcu);
 		adapter->rx_ring[i] = NULL;
 	}
 
@@ -5138,57 +5170,6 @@
 }
 
 /**
- * ixgbe_sfp_timer - worker thread to find a missing module
- * @data: pointer to our adapter struct
- **/
-static void ixgbe_sfp_timer(unsigned long data)
-{
-	struct ixgbe_adapter *adapter = (struct ixgbe_adapter *)data;
-
-	/*
-	 * Do the sfp_timer outside of interrupt context due to the
-	 * delays that sfp+ detection requires
-	 */
-	schedule_work(&adapter->sfp_task);
-}
-
-/**
- * ixgbe_sfp_task - worker thread to find a missing module
- * @work: pointer to work_struct containing our data
- **/
-static void ixgbe_sfp_task(struct work_struct *work)
-{
-	struct ixgbe_adapter *adapter = container_of(work,
-						     struct ixgbe_adapter,
-						     sfp_task);
-	struct ixgbe_hw *hw = &adapter->hw;
-
-	if ((hw->phy.type == ixgbe_phy_nl) &&
-	    (hw->phy.sfp_type == ixgbe_sfp_type_not_present)) {
-		s32 ret = hw->phy.ops.identify_sfp(hw);
-		if (ret == IXGBE_ERR_SFP_NOT_PRESENT)
-			goto reschedule;
-		ret = hw->phy.ops.reset(hw);
-		if (ret == IXGBE_ERR_SFP_NOT_SUPPORTED) {
-			e_dev_err("failed to initialize because an unsupported "
-				  "SFP+ module type was detected.\n");
-			e_dev_err("Reload the driver after installing a "
-				  "supported module.\n");
-			unregister_netdev(adapter->netdev);
-		} else {
-			e_info(probe, "detected SFP+: %d\n", hw->phy.sfp_type);
-		}
-		/* don't need this routine any more */
-		clear_bit(__IXGBE_SFP_MODULE_NOT_FOUND, &adapter->state);
-	}
-	return;
-reschedule:
-	if (test_bit(__IXGBE_SFP_MODULE_NOT_FOUND, &adapter->state))
-		mod_timer(&adapter->sfp_timer,
-			  round_jiffies(jiffies + (2 * HZ)));
-}
-
-/**
  * ixgbe_sw_init - Initialize general software structures (struct ixgbe_adapter)
  * @adapter: board private structure to initialize
  *
@@ -5904,8 +5885,13 @@
 		hwstats->gotc += IXGBE_READ_REG(hw, IXGBE_GOTCH);
 		hwstats->tor += IXGBE_READ_REG(hw, IXGBE_TORH);
 		break;
-	case ixgbe_mac_82599EB:
 	case ixgbe_mac_X540:
+		/* OS2BMC stats are X540 only*/
+		hwstats->o2bgptc += IXGBE_READ_REG(hw, IXGBE_O2BGPTC);
+		hwstats->o2bspc += IXGBE_READ_REG(hw, IXGBE_O2BSPC);
+		hwstats->b2ospc += IXGBE_READ_REG(hw, IXGBE_B2OSPC);
+		hwstats->b2ogprc += IXGBE_READ_REG(hw, IXGBE_B2OGPRC);
+	case ixgbe_mac_82599EB:
 		hwstats->gorc += IXGBE_READ_REG(hw, IXGBE_GORCL);
 		IXGBE_READ_REG(hw, IXGBE_GORCH); /* to clear */
 		hwstats->gotc += IXGBE_READ_REG(hw, IXGBE_GOTCL);
@@ -5979,23 +5965,66 @@
 }
 
 /**
- * ixgbe_watchdog - Timer Call-back
- * @data: pointer to adapter cast into an unsigned long
+ * ixgbe_fdir_reinit_subtask - worker thread to reinit FDIR filter table
+ * @adapter - pointer to the device adapter structure
  **/
-static void ixgbe_watchdog(unsigned long data)
+static void ixgbe_fdir_reinit_subtask(struct ixgbe_adapter *adapter)
 {
-	struct ixgbe_adapter *adapter = (struct ixgbe_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 (!(adapter->flags2 & IXGBE_FLAG2_FDIR_REQUIRES_REINIT))
+		return;
+
+	adapter->flags2 &= ~IXGBE_FLAG2_FDIR_REQUIRES_REINIT;
 
+	/* if interface is down do nothing */
 	if (test_bit(__IXGBE_DOWN, &adapter->state))
-		goto watchdog_short_circuit;
+		return;
+
+	/* do nothing if we are not using signature filters */
+	if (!(adapter->flags & IXGBE_FLAG_FDIR_HASH_CAPABLE))
+		return;
+
+	adapter->fdir_overflow++;
+
+	if (ixgbe_reinit_fdir_tables_82599(hw) == 0) {
+		for (i = 0; i < adapter->num_tx_queues; i++)
+			set_bit(__IXGBE_TX_FDIR_INIT_DONE,
+			        &(adapter->tx_ring[i]->state));
+		/* re-enable flow director interrupts */
+		IXGBE_WRITE_REG(hw, IXGBE_EIMS, IXGBE_EIMS_FLOW_DIR);
+	} else {
+		e_err(probe, "failed to finish FDIR re-initialization, "
+		      "ignored adding FDIR ATR filters\n");
+	}
+}
+
+/**
+ * ixgbe_check_hang_subtask - check for hung queues and dropped interrupts
+ * @adapter - pointer to the device adapter structure
+ *
+ * This function serves two purposes.  First it strobes the interrupt lines
+ * in order to make certain interrupts are occuring.  Secondly it sets the
+ * bits needed to check for TX hangs.  As a result we should immediately
+ * determine if a hang has occured.
+ */
+static void ixgbe_check_hang_subtask(struct ixgbe_adapter *adapter)
+{
+	struct ixgbe_hw *hw = &adapter->hw;
+	u64 eics = 0;
+	int i;
+
+	/* If we're down or resetting, just bail */
+	if (test_bit(__IXGBE_DOWN, &adapter->state) ||
+	    test_bit(__IXGBE_RESETTING, &adapter->state))
+		return;
+
+	/* Force detection of hung controller */
+	if (netif_carrier_ok(adapter->netdev)) {
+		for (i = 0; i < adapter->num_tx_queues; i++)
+			set_check_for_tx_hang(adapter->tx_ring[i]);
+	}
 
 	if (!(adapter->flags & IXGBE_FLAG_MSIX_ENABLED)) {
 		/*
@@ -6005,108 +6034,172 @@
 		 */
 		IXGBE_WRITE_REG(hw, IXGBE_EICS,
 			(IXGBE_EICS_TCP_TIMER | IXGBE_EICS_OTHER));
-		goto watchdog_reschedule;
-	}
-
-	/* get one bit for every active tx/rx interrupt vector */
-	for (i = 0; i < adapter->num_msix_vectors - NON_Q_VECTORS; i++) {
-		struct ixgbe_q_vector *qv = adapter->q_vector[i];
-		if (qv->rxr_count || qv->txr_count)
-			eics |= ((u64)1 << i);
+	} else {
+		/* get one bit for every active tx/rx interrupt vector */
+		for (i = 0; i < adapter->num_msix_vectors - NON_Q_VECTORS; i++) {
+			struct ixgbe_q_vector *qv = adapter->q_vector[i];
+			if (qv->rxr_count || qv->txr_count)
+				eics |= ((u64)1 << i);
+		}
 	}
 
-	/* Cause software interrupt to ensure rx rings are cleaned */
+	/* Cause software interrupt to ensure rings are cleaned */
 	ixgbe_irq_rearm_queues(adapter, eics);
 
-watchdog_reschedule:
-	/* Reset the timer */
-	mod_timer(&adapter->watchdog_timer, round_jiffies(jiffies + 2 * HZ));
-
-watchdog_short_circuit:
-	schedule_work(&adapter->watchdog_task);
 }
 
 /**
- * ixgbe_multispeed_fiber_task - worker thread to configure multispeed fiber
- * @work: pointer to work_struct containing our data
+ * ixgbe_watchdog_update_link - update the link status
+ * @adapter - pointer to the device adapter structure
+ * @link_speed - pointer to a u32 to store the link_speed
  **/
-static void ixgbe_multispeed_fiber_task(struct work_struct *work)
+static void ixgbe_watchdog_update_link(struct ixgbe_adapter *adapter)
 {
-	struct ixgbe_adapter *adapter = container_of(work,
-						     struct ixgbe_adapter,
-						     multispeed_fiber_task);
 	struct ixgbe_hw *hw = &adapter->hw;
-	u32 autoneg;
-	bool negotiation;
+	u32 link_speed = adapter->link_speed;
+	bool link_up = adapter->link_up;
+	int i;
 
-	adapter->flags |= IXGBE_FLAG_IN_SFP_LINK_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;
-	adapter->flags &= ~IXGBE_FLAG_IN_SFP_LINK_TASK;
+	if (!(adapter->flags & IXGBE_FLAG_NEED_LINK_UPDATE))
+		return;
+
+	if (hw->mac.ops.check_link) {
+		hw->mac.ops.check_link(hw, &link_speed, &link_up, false);
+	} else {
+		/* always assume link is up, if no check link function */
+		link_speed = IXGBE_LINK_SPEED_10GB_FULL;
+		link_up = true;
+	}
+	if (link_up) {
+		if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) {
+			for (i = 0; i < MAX_TRAFFIC_CLASS; i++)
+				hw->mac.ops.fc_enable(hw, i);
+		} else {
+			hw->mac.ops.fc_enable(hw, 0);
+		}
+	}
+
+	if (link_up ||
+	    time_after(jiffies, (adapter->link_check_timeout +
+				 IXGBE_TRY_LINK_TIMEOUT))) {
+		adapter->flags &= ~IXGBE_FLAG_NEED_LINK_UPDATE;
+		IXGBE_WRITE_REG(hw, IXGBE_EIMS, IXGBE_EIMC_LSC);
+		IXGBE_WRITE_FLUSH(hw);
+	}
+
+	adapter->link_up = link_up;
+	adapter->link_speed = link_speed;
 }
 
 /**
- * ixgbe_sfp_config_module_task - worker thread to configure a new SFP+ module
- * @work: pointer to work_struct containing our data
+ * ixgbe_watchdog_link_is_up - update netif_carrier status and
+ *                             print link up message
+ * @adapter - pointer to the device adapter structure
  **/
-static void ixgbe_sfp_config_module_task(struct work_struct *work)
+static void ixgbe_watchdog_link_is_up(struct ixgbe_adapter *adapter)
 {
-	struct ixgbe_adapter *adapter = container_of(work,
-						     struct ixgbe_adapter,
-						     sfp_config_module_task);
+	struct net_device *netdev = adapter->netdev;
 	struct ixgbe_hw *hw = &adapter->hw;
-	u32 err;
+	u32 link_speed = adapter->link_speed;
+	bool flow_rx, flow_tx;
 
-	adapter->flags |= IXGBE_FLAG_IN_SFP_MOD_TASK;
+	/* only continue if link was previously down */
+	if (netif_carrier_ok(netdev))
+		return;
 
-	/* Time for electrical oscillations to settle down */
-	msleep(100);
-	err = hw->phy.ops.identify_sfp(hw);
+	adapter->flags2 &= ~IXGBE_FLAG2_SEARCH_FOR_SFP;
 
-	if (err == IXGBE_ERR_SFP_NOT_SUPPORTED) {
-		e_dev_err("failed to initialize because an unsupported SFP+ "
-			  "module type was detected.\n");
-		e_dev_err("Reload the driver after installing a supported "
-			  "module.\n");
-		unregister_netdev(adapter->netdev);
-		return;
+	switch (hw->mac.type) {
+	case ixgbe_mac_82598EB: {
+		u32 frctl = IXGBE_READ_REG(hw, IXGBE_FCTRL);
+		u32 rmcs = IXGBE_READ_REG(hw, IXGBE_RMCS);
+		flow_rx = !!(frctl & IXGBE_FCTRL_RFCE);
+		flow_tx = !!(rmcs & IXGBE_RMCS_TFCE_802_3X);
 	}
-	if (hw->mac.ops.setup_sfp)
-		hw->mac.ops.setup_sfp(hw);
+		break;
+	case ixgbe_mac_X540:
+	case ixgbe_mac_82599EB: {
+		u32 mflcn = IXGBE_READ_REG(hw, IXGBE_MFLCN);
+		u32 fccfg = IXGBE_READ_REG(hw, IXGBE_FCCFG);
+		flow_rx = !!(mflcn & IXGBE_MFLCN_RFCE);
+		flow_tx = !!(fccfg & IXGBE_FCCFG_TFCE_802_3X);
+	}
+		break;
+	default:
+		flow_tx = false;
+		flow_rx = false;
+		break;
+	}
+	e_info(drv, "NIC Link is Up %s, Flow Control: %s\n",
+	       (link_speed == IXGBE_LINK_SPEED_10GB_FULL ?
+	       "10 Gbps" :
+	       (link_speed == IXGBE_LINK_SPEED_1GB_FULL ?
+	       "1 Gbps" :
+	       (link_speed == IXGBE_LINK_SPEED_100_FULL ?
+	       "100 Mbps" :
+	       "unknown speed"))),
+	       ((flow_rx && flow_tx) ? "RX/TX" :
+	       (flow_rx ? "RX" :
+	       (flow_tx ? "TX" : "None"))));
 
-	if (!(adapter->flags & IXGBE_FLAG_IN_SFP_LINK_TASK))
-		/* This will also work for DA Twinax connections */
-		schedule_work(&adapter->multispeed_fiber_task);
-	adapter->flags &= ~IXGBE_FLAG_IN_SFP_MOD_TASK;
+	netif_carrier_on(netdev);
+#ifdef HAVE_IPLINK_VF_CONFIG
+	ixgbe_check_vf_rate_limit(adapter);
+#endif /* HAVE_IPLINK_VF_CONFIG */
 }
 
 /**
- * ixgbe_fdir_reinit_task - worker thread to reinit FDIR filter table
- * @work: pointer to work_struct containing our data
+ * ixgbe_watchdog_link_is_down - update netif_carrier status and
+ *                               print link down message
+ * @adapter - pointer to the adapter structure
  **/
-static void ixgbe_fdir_reinit_task(struct work_struct *work)
+static void ixgbe_watchdog_link_is_down(struct ixgbe_adapter* adapter)
 {
-	struct ixgbe_adapter *adapter = container_of(work,
-						     struct ixgbe_adapter,
-						     fdir_reinit_task);
+	struct net_device *netdev = adapter->netdev;
 	struct ixgbe_hw *hw = &adapter->hw;
+
+	adapter->link_up = false;
+	adapter->link_speed = 0;
+
+	/* only continue if link was up previously */
+	if (!netif_carrier_ok(netdev))
+		return;
+
+	/* poll for SFP+ cable when link is down */
+	if (ixgbe_is_sfp(hw) && hw->mac.type == ixgbe_mac_82598EB)
+		adapter->flags2 |= IXGBE_FLAG2_SEARCH_FOR_SFP;
+
+	e_info(drv, "NIC Link is Down\n");
+	netif_carrier_off(netdev);
+}
+
+/**
+ * ixgbe_watchdog_flush_tx - flush queues on link down
+ * @adapter - pointer to the device adapter structure
+ **/
+static void ixgbe_watchdog_flush_tx(struct ixgbe_adapter *adapter)
+{
 	int i;
+	int some_tx_pending = 0;
 
-	if (ixgbe_reinit_fdir_tables_82599(hw) == 0) {
-		for (i = 0; i < adapter->num_tx_queues; i++)
-			set_bit(__IXGBE_TX_FDIR_INIT_DONE,
-				&(adapter->tx_ring[i]->state));
-	} else {
-		e_err(probe, "failed to finish FDIR re-initialization, "
-		      "ignored adding FDIR ATR filters\n");
+	if (!netif_carrier_ok(adapter->netdev)) {
+		for (i = 0; i < adapter->num_tx_queues; i++) {
+			struct ixgbe_ring *tx_ring = adapter->tx_ring[i];
+			if (tx_ring->next_to_use != tx_ring->next_to_clean) {
+				some_tx_pending = 1;
+				break;
+			}
+		}
+
+		if (some_tx_pending) {
+			/* We've lost link, so the controller stops DMA,
+			 * but we've got queued Tx work that's never going
+			 * to get done, so reset controller to flush Tx.
+			 * (Do the reset outside of interrupt context).
+			 */
+			adapter->flags2 |= IXGBE_FLAG2_RESET_REQUESTED;
+		}
 	}
-	/* Done FDIR Re-initialization, enable transmits */
-	netif_tx_start_all_queues(adapter->netdev);
 }
 
 static void ixgbe_spoof_check(struct ixgbe_adapter *adapter)
@@ -6129,133 +6222,186 @@
 	e_warn(drv, "%d Spoofed packets detected\n", ssvpc);
 }
 
-static DEFINE_MUTEX(ixgbe_watchdog_lock);
+/**
+ * ixgbe_watchdog_subtask - check and bring link up
+ * @adapter - pointer to the device adapter structure
+ **/
+static void ixgbe_watchdog_subtask(struct ixgbe_adapter *adapter)
+{
+	/* if interface is down do nothing */
+	if (test_bit(__IXGBE_DOWN, &adapter->state))
+		return;
+
+	ixgbe_watchdog_update_link(adapter);
+
+	if (adapter->link_up)
+		ixgbe_watchdog_link_is_up(adapter);
+	else
+		ixgbe_watchdog_link_is_down(adapter);
+
+	ixgbe_spoof_check(adapter);
+	ixgbe_update_stats(adapter);
+
+	ixgbe_watchdog_flush_tx(adapter);
+}
 
 /**
- * ixgbe_watchdog_task - worker thread to bring link up
- * @work: pointer to work_struct containing our data
+ * ixgbe_sfp_detection_subtask - poll for SFP+ cable
+ * @adapter - the ixgbe adapter structure
  **/
-static void ixgbe_watchdog_task(struct work_struct *work)
+static void ixgbe_sfp_detection_subtask(struct ixgbe_adapter *adapter)
 {
-	struct ixgbe_adapter *adapter = container_of(work,
-						     struct ixgbe_adapter,
-						     watchdog_task);
-	struct net_device *netdev = adapter->netdev;
 	struct ixgbe_hw *hw = &adapter->hw;
-	u32 link_speed;
-	bool link_up;
-	int i;
-	struct ixgbe_ring *tx_ring;
-	int some_tx_pending = 0;
+	s32 err;
 
-	mutex_lock(&ixgbe_watchdog_lock);
+	/* not searching for SFP so there is nothing to do here */
+	if (!(adapter->flags2 & IXGBE_FLAG2_SEARCH_FOR_SFP) &&
+	    !(adapter->flags2 & IXGBE_FLAG2_SFP_NEEDS_RESET))
+		return;
 
-	link_up = adapter->link_up;
-	link_speed = adapter->link_speed;
+	/* someone else is in init, wait until next service event */
+	if (test_and_set_bit(__IXGBE_IN_SFP_INIT, &adapter->state))
+		return;
 
-	if (adapter->flags & IXGBE_FLAG_NEED_LINK_UPDATE) {
-		hw->mac.ops.check_link(hw, &link_speed, &link_up, false);
-		if (link_up) {
-#ifdef CONFIG_DCB
-			if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) {
-				for (i = 0; i < MAX_TRAFFIC_CLASS; i++)
-					hw->mac.ops.fc_enable(hw, i);
-			} else {
-				hw->mac.ops.fc_enable(hw, 0);
-			}
-#else
-			hw->mac.ops.fc_enable(hw, 0);
-#endif
-		}
+	err = hw->phy.ops.identify_sfp(hw);
+	if (err == IXGBE_ERR_SFP_NOT_SUPPORTED)
+		goto sfp_out;
 
-		if (link_up ||
-		    time_after(jiffies, (adapter->link_check_timeout +
-					 IXGBE_TRY_LINK_TIMEOUT))) {
-			adapter->flags &= ~IXGBE_FLAG_NEED_LINK_UPDATE;
-			IXGBE_WRITE_REG(hw, IXGBE_EIMS, IXGBE_EIMC_LSC);
-		}
-		adapter->link_up = link_up;
-		adapter->link_speed = link_speed;
+	if (err == IXGBE_ERR_SFP_NOT_PRESENT) {
+		/* If no cable is present, then we need to reset
+		 * the next time we find a good cable. */
+		adapter->flags2 |= IXGBE_FLAG2_SFP_NEEDS_RESET;
 	}
 
-	if (link_up) {
-		if (!netif_carrier_ok(netdev)) {
-			bool flow_rx, flow_tx;
+	/* exit on error */
+	if (err)
+		goto sfp_out;
 
-			switch (hw->mac.type) {
-			case ixgbe_mac_82598EB: {
-				u32 frctl = IXGBE_READ_REG(hw, IXGBE_FCTRL);
-				u32 rmcs = IXGBE_READ_REG(hw, IXGBE_RMCS);
-				flow_rx = !!(frctl & IXGBE_FCTRL_RFCE);
-				flow_tx = !!(rmcs & IXGBE_RMCS_TFCE_802_3X);
-			}
-				break;
-			case ixgbe_mac_82599EB:
-			case ixgbe_mac_X540: {
-				u32 mflcn = IXGBE_READ_REG(hw, IXGBE_MFLCN);
-				u32 fccfg = IXGBE_READ_REG(hw, IXGBE_FCCFG);
-				flow_rx = !!(mflcn & IXGBE_MFLCN_RFCE);
-				flow_tx = !!(fccfg & IXGBE_FCCFG_TFCE_802_3X);
-			}
-				break;
-			default:
-				flow_tx = false;
-				flow_rx = false;
-				break;
-			}
+	/* exit if reset not needed */
+	if (!(adapter->flags2 & IXGBE_FLAG2_SFP_NEEDS_RESET))
+		goto sfp_out;
 
-			e_info(drv, "NIC Link is Up %s, Flow Control: %s\n",
-			       (link_speed == IXGBE_LINK_SPEED_10GB_FULL ?
-			       "10 Gbps" :
-			       (link_speed == IXGBE_LINK_SPEED_1GB_FULL ?
-			       "1 Gbps" :
-			       (link_speed == IXGBE_LINK_SPEED_100_FULL ?
-			       "100 Mbps" :
-			       "unknown speed"))),
-			       ((flow_rx && flow_tx) ? "RX/TX" :
-			       (flow_rx ? "RX" :
-			       (flow_tx ? "TX" : "None"))));
+	adapter->flags2 &= ~IXGBE_FLAG2_SFP_NEEDS_RESET;
 
-			netif_carrier_on(netdev);
-			ixgbe_check_vf_rate_limit(adapter);
-		} else {
-			/* Force detection of hung controller */
-			for (i = 0; i < adapter->num_tx_queues; i++) {
-				tx_ring = adapter->tx_ring[i];
-				set_check_for_tx_hang(tx_ring);
-			}
-		}
-	} else {
-		adapter->link_up = false;
-		adapter->link_speed = 0;
-		if (netif_carrier_ok(netdev)) {
-			e_info(drv, "NIC Link is Down\n");
-			netif_carrier_off(netdev);
-		}
-	}
+	/*
+	 * A module may be identified correctly, but the EEPROM may not have
+	 * support for that module.  setup_sfp() will fail in that case, so
+	 * we should not allow that module to load.
+	 */
+	if (hw->mac.type == ixgbe_mac_82598EB)
+		err = hw->phy.ops.reset(hw);
+	else
+		err = hw->mac.ops.setup_sfp(hw);
 
-	if (!netif_carrier_ok(netdev)) {
-		for (i = 0; i < adapter->num_tx_queues; i++) {
-			tx_ring = adapter->tx_ring[i];
-			if (tx_ring->next_to_use != tx_ring->next_to_clean) {
-				some_tx_pending = 1;
-				break;
-			}
-		}
+	if (err == IXGBE_ERR_SFP_NOT_SUPPORTED)
+		goto sfp_out;
 
-		if (some_tx_pending) {
-			/* We've lost link, so the controller stops DMA,
-			 * but we've got queued Tx work that's never going
-			 * to get done, so reset controller to flush Tx.
-			 * (Do the reset outside of interrupt context).
-			 */
-			 schedule_work(&adapter->reset_task);
-		}
+	adapter->flags |= IXGBE_FLAG_NEED_LINK_CONFIG;
+	e_info(probe, "detected SFP+: %d\n", hw->phy.sfp_type);
+
+sfp_out:
+	clear_bit(__IXGBE_IN_SFP_INIT, &adapter->state);
+
+	if ((err == IXGBE_ERR_SFP_NOT_SUPPORTED) &&
+	    (adapter->netdev->reg_state == NETREG_REGISTERED)) {
+		e_dev_err("failed to initialize because an unsupported "
+			  "SFP+ module type was detected.\n");
+		e_dev_err("Reload the driver after installing a "
+			  "supported module.\n");
+		unregister_netdev(adapter->netdev);
 	}
+}
 
-	ixgbe_spoof_check(adapter);
-	ixgbe_update_stats(adapter);
-	mutex_unlock(&ixgbe_watchdog_lock);
+/**
+ * ixgbe_sfp_link_config_subtask - set up link SFP after module install
+ * @adapter - the ixgbe adapter structure
+ **/
+static void ixgbe_sfp_link_config_subtask(struct ixgbe_adapter *adapter)
+{
+	struct ixgbe_hw *hw = &adapter->hw;
+	u32 autoneg;
+	bool negotiation;
+
+	if (!(adapter->flags & IXGBE_FLAG_NEED_LINK_CONFIG))
+		return;
+
+	/* someone else is in init, wait until next service event */
+	if (test_and_set_bit(__IXGBE_IN_SFP_INIT, &adapter->state))
+		return;
+
+	adapter->flags &= ~IXGBE_FLAG_NEED_LINK_CONFIG;
+
+	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;
+	adapter->link_check_timeout = jiffies;
+	clear_bit(__IXGBE_IN_SFP_INIT, &adapter->state);
+}
+
+/**
+ * ixgbe_service_timer - Timer Call-back
+ * @data: pointer to adapter cast into an unsigned long
+ **/
+static void ixgbe_service_timer(unsigned long data)
+{
+	struct ixgbe_adapter *adapter = (struct ixgbe_adapter *)data;
+	unsigned long next_event_offset;
+
+	/* poll faster when waiting for link */
+	if (adapter->flags & IXGBE_FLAG_NEED_LINK_UPDATE)
+		next_event_offset = HZ / 10;
+	else
+		next_event_offset = HZ * 2;
+
+	/* Reset the timer */
+	mod_timer(&adapter->service_timer, next_event_offset + jiffies);
+
+	ixgbe_service_event_schedule(adapter);
+}
+
+static void ixgbe_reset_subtask(struct ixgbe_adapter *adapter)
+{
+	if (!(adapter->flags2 & IXGBE_FLAG2_RESET_REQUESTED))
+		return;
+
+	adapter->flags2 &= ~IXGBE_FLAG2_RESET_REQUESTED;
+
+	/* If we're already down or resetting, just bail */
+	if (test_bit(__IXGBE_DOWN, &adapter->state) ||
+	    test_bit(__IXGBE_RESETTING, &adapter->state))
+		return;
+
+	ixgbe_dump(adapter);
+	netdev_err(adapter->netdev, "Reset adapter\n");
+	adapter->tx_timeout_count++;
+
+	ixgbe_reinit_locked(adapter);
+}
+
+/**
+ * ixgbe_service_task - manages and runs subtasks
+ * @work: pointer to work_struct containing our data
+ **/
+static void ixgbe_service_task(struct work_struct *work)
+{
+	struct ixgbe_adapter *adapter = container_of(work,
+						     struct ixgbe_adapter,
+						     service_task);
+
+	ixgbe_reset_subtask(adapter);
+	ixgbe_sfp_detection_subtask(adapter);
+	ixgbe_sfp_link_config_subtask(adapter);
+	ixgbe_check_overtemp_subtask(adapter);
+	ixgbe_watchdog_subtask(adapter);
+	ixgbe_fdir_reinit_subtask(adapter);
+	ixgbe_check_hang_subtask(adapter);
+
+	ixgbe_service_event_complete(adapter);
 }
 
 static int ixgbe_tso(struct ixgbe_adapter *adapter,
@@ -7094,6 +7240,8 @@
 #ifdef CONFIG_PCI_IOV
 	struct ixgbe_hw *hw = &adapter->hw;
 	int err;
+	int num_vf_macvlans, i;
+	struct vf_macvlans *mv_list;
 
 	if (hw->mac.type == ixgbe_mac_82598EB || !max_vfs)
 		return;
@@ -7110,6 +7258,26 @@
 		e_err(probe, "Failed to enable PCI sriov: %d\n", err);
 		goto err_novfs;
 	}
+
+	num_vf_macvlans = hw->mac.num_rar_entries -
+		(IXGBE_MAX_PF_MACVLANS + 1 + adapter->num_vfs);
+
+	adapter->mv_list = mv_list = kcalloc(num_vf_macvlans,
+					     sizeof(struct vf_macvlans),
+					     GFP_KERNEL);
+	if (mv_list) {
+		/* Initialize list of VF macvlans */
+		INIT_LIST_HEAD(&adapter->vf_mvs.l);
+		for (i = 0; i < num_vf_macvlans; i++) {
+			mv_list->vf = -1;
+			mv_list->free = true;
+			mv_list->rar_entry = hw->mac.num_rar_entries -
+				(i + adapter->num_vfs + 1);
+			list_add(&mv_list->l, &adapter->vf_mvs.l);
+			mv_list++;
+		}
+	}
+
 	/* If call to enable VFs succeeded then allocate memory
 	 * for per VF control structures.
 	 */
@@ -7280,22 +7448,6 @@
 	hw->phy.mdio.mdio_read = ixgbe_mdio_read;
 	hw->phy.mdio.mdio_write = ixgbe_mdio_write;
 
-	/* set up this timer and work struct before calling get_invariants
-	 * which might start the timer
-	 */
-	init_timer(&adapter->sfp_timer);
-	adapter->sfp_timer.function = ixgbe_sfp_timer;
-	adapter->sfp_timer.data = (unsigned long) adapter;
-
-	INIT_WORK(&adapter->sfp_task, ixgbe_sfp_task);
-
-	/* multispeed fiber has its own tasklet, called from GPI SDP1 context */
-	INIT_WORK(&adapter->multispeed_fiber_task, ixgbe_multispeed_fiber_task);
-
-	/* a new SFP+ module arrival, called from GPI SDP2 context */
-	INIT_WORK(&adapter->sfp_config_module_task,
-		  ixgbe_sfp_config_module_task);
-
 	ii->get_invariants(hw);
 
 	/* setup the private structure */
@@ -7329,17 +7481,9 @@
 	hw->phy.reset_if_overtemp = false;
 	if (err == IXGBE_ERR_SFP_NOT_PRESENT &&
 	    hw->mac.type == ixgbe_mac_82598EB) {
-		/*
-		 * Start a kernel thread to watch for a module to arrive.
-		 * Only do this for 82598, since 82599 will generate
-		 * interrupts on module arrival.
-		 */
-		set_bit(__IXGBE_SFP_MODULE_NOT_FOUND, &adapter->state);
-		mod_timer(&adapter->sfp_timer,
-			  round_jiffies(jiffies + (2 * HZ)));
 		err = 0;
 	} else if (err == IXGBE_ERR_SFP_NOT_SUPPORTED) {
-		e_dev_err("failed to initialize because an unsupported SFP+ "
+		e_dev_err("failed to load because an unsupported SFP+ "
 			  "module type was detected.\n");
 		e_dev_err("Reload the driver after installing a supported "
 			  "module.\n");
@@ -7361,9 +7505,16 @@
 	netdev->features |= NETIF_F_TSO;
 	netdev->features |= NETIF_F_TSO6;
 	netdev->features |= NETIF_F_GRO;
+	netdev->features |= NETIF_F_RXHASH;
 
-	if (adapter->hw.mac.type == ixgbe_mac_82599EB)
+	switch (adapter->hw.mac.type) {
+	case ixgbe_mac_82599EB:
+	case ixgbe_mac_X540:
 		netdev->features |= NETIF_F_SCTP_CSUM;
+		break;
+	default:
+		break;
+	}
 
 	netdev->vlan_features |= NETIF_F_TSO;
 	netdev->vlan_features |= NETIF_F_TSO6;
@@ -7424,17 +7575,19 @@
 	      (hw->mac.type == ixgbe_mac_82599EB))))
 		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;
+	setup_timer(&adapter->service_timer, &ixgbe_service_timer,
+	            (unsigned long) adapter);
 
-	INIT_WORK(&adapter->reset_task, ixgbe_reset_task);
-	INIT_WORK(&adapter->watchdog_task, ixgbe_watchdog_task);
+	INIT_WORK(&adapter->service_task, ixgbe_service_task);
+	clear_bit(__IXGBE_SERVICE_SCHED, &adapter->state);
 
 	err = ixgbe_init_interrupt_scheme(adapter);
 	if (err)
 		goto err_sw_init;
 
+	if (!(adapter->flags & IXGBE_FLAG_RSS_ENABLED))
+		netdev->features &= ~NETIF_F_RXHASH;
+
 	switch (pdev->device) {
 	case IXGBE_DEV_ID_82599_SFP:
 		/* Only this subdevice supports WOL */
@@ -7463,8 +7616,8 @@
 
 	/* print bus type/speed/width info */
 	e_dev_info("(PCI Express:%s:%s) %pM\n",
-		   (hw->bus.speed == ixgbe_bus_speed_5000 ? "5.0Gb/s" :
-		    hw->bus.speed == ixgbe_bus_speed_2500 ? "2.5Gb/s" :
+		   (hw->bus.speed == ixgbe_bus_speed_5000 ? "5.0GT/s" :
+		    hw->bus.speed == ixgbe_bus_speed_2500 ? "2.5GT/s" :
 		    "Unknown"),
 		   (hw->bus.width == ixgbe_bus_width_pcie_x8 ? "Width x8" :
 		    hw->bus.width == ixgbe_bus_width_pcie_x4 ? "Width x4" :
@@ -7513,13 +7666,6 @@
 	/* carrier off reporting is important to ethtool even BEFORE open */
 	netif_carrier_off(netdev);
 
-	if (adapter->flags & IXGBE_FLAG_FDIR_HASH_CAPABLE ||
-	    adapter->flags & IXGBE_FLAG_FDIR_PERFECT_CAPABLE)
-		INIT_WORK(&adapter->fdir_reinit_task, ixgbe_fdir_reinit_task);
-
-	if (adapter->flags2 & IXGBE_FLAG2_TEMP_SENSOR_CAPABLE)
-		INIT_WORK(&adapter->check_overtemp_task,
-			  ixgbe_check_overtemp_task);
 #ifdef CONFIG_IXGBE_DCA
 	if (dca_add_requester(&pdev->dev) == 0) {
 		adapter->flags |= IXGBE_FLAG_DCA_ENABLED;
@@ -7546,11 +7692,7 @@
 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);
-	cancel_work_sync(&adapter->multispeed_fiber_task);
-	cancel_work_sync(&adapter->sfp_config_module_task);
+	adapter->flags2 &= ~IXGBE_FLAG2_SEARCH_FOR_SFP;
 	iounmap(hw->hw_addr);
 err_ioremap:
 	free_netdev(netdev);
@@ -7578,24 +7720,7 @@
 	struct net_device *netdev = adapter->netdev;
 
 	set_bit(__IXGBE_DOWN, &adapter->state);
-
-	/*
-	 * The timers may be rescheduled, so explicitly disable them
-	 * from being rescheduled.
-	 */
-	clear_bit(__IXGBE_SFP_MODULE_NOT_FOUND, &adapter->state);
-	del_timer_sync(&adapter->watchdog_timer);
-	del_timer_sync(&adapter->sfp_timer);
-
-	cancel_work_sync(&adapter->watchdog_task);
-	cancel_work_sync(&adapter->sfp_task);
-	cancel_work_sync(&adapter->multispeed_fiber_task);
-	cancel_work_sync(&adapter->sfp_config_module_task);
-	if (adapter->flags & IXGBE_FLAG_FDIR_HASH_CAPABLE ||
-	    adapter->flags & IXGBE_FLAG_FDIR_PERFECT_CAPABLE)
-		cancel_work_sync(&adapter->fdir_reinit_task);
-	if (adapter->flags2 & IXGBE_FLAG2_TEMP_SENSOR_CAPABLE)
-		cancel_work_sync(&adapter->check_overtemp_task);
+	cancel_work_sync(&adapter->service_task);
 
 #ifdef CONFIG_IXGBE_DCA
 	if (adapter->flags & IXGBE_FLAG_DCA_ENABLED) {
diff -druN linux-2.6.39-libre/drivers/net/ixgbe/ixgbe_mbx.h linux-3.0-rc7-libre/drivers/net/ixgbe/ixgbe_mbx.h
--- linux-2.6.39-libre/drivers/net/ixgbe/ixgbe_mbx.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/ixgbe/ixgbe_mbx.h	2011-07-11 19:51:52.000000000 -0400
@@ -36,9 +36,6 @@
 #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 */
@@ -70,6 +67,7 @@
 #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 */
+#define IXGBE_VF_SET_MACVLAN      0x06 /* VF requests PF for unicast filter */
 
 /* length of permanent address message returned from PF */
 #define IXGBE_VF_PERMADDR_MSG_LEN 4
diff -druN linux-2.6.39-libre/drivers/net/ixgbe/ixgbe_phy.c linux-3.0-rc7-libre/drivers/net/ixgbe/ixgbe_phy.c
--- linux-2.6.39-libre/drivers/net/ixgbe/ixgbe_phy.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/ixgbe/ixgbe_phy.c	2011-07-11 19:51:52.000000000 -0400
@@ -449,7 +449,8 @@
 				     MDIO_MMD_AN,
 				     &autoneg_reg);
 
-		autoneg_reg &= ~ADVERTISE_100FULL;
+		autoneg_reg &= ~(ADVERTISE_100FULL |
+				 ADVERTISE_100HALF);
 		if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_100_FULL)
 			autoneg_reg |= ADVERTISE_100FULL;
 
@@ -656,7 +657,8 @@
 				     MDIO_MMD_AN,
 				     &autoneg_reg);
 
-		autoneg_reg &= ~ADVERTISE_100FULL;
+		autoneg_reg &= ~(ADVERTISE_100FULL |
+				 ADVERTISE_100HALF);
 		if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_100_FULL)
 			autoneg_reg |= ADVERTISE_100FULL;
 
@@ -753,7 +755,7 @@
 		                     &phy_data);
 		if ((phy_data & MDIO_CTRL1_RESET) == 0)
 			break;
-		msleep(10);
+		usleep_range(10000, 20000);
 	}
 
 	if ((phy_data & MDIO_CTRL1_RESET) != 0) {
@@ -782,7 +784,7 @@
 		case IXGBE_DELAY_NL:
 			data_offset++;
 			hw_dbg(hw, "DELAY: %d MS\n", edata);
-			msleep(edata);
+			usleep_range(edata * 1000, edata * 2000);
 			break;
 		case IXGBE_DATA_NL:
 			hw_dbg(hw, "DATA:\n");
@@ -1220,7 +1222,7 @@
 		swfw_mask = IXGBE_GSSR_PHY0_SM;
 
 	do {
-		if (ixgbe_acquire_swfw_sync(hw, swfw_mask) != 0) {
+		if (hw->mac.ops.acquire_swfw_sync(hw, swfw_mask) != 0) {
 			status = IXGBE_ERR_SWFW_SYNC;
 			goto read_byte_out;
 		}
@@ -1267,7 +1269,7 @@
 		break;
 
 fail:
-		ixgbe_release_swfw_sync(hw, swfw_mask);
+		hw->mac.ops.release_swfw_sync(hw, swfw_mask);
 		msleep(100);
 		ixgbe_i2c_bus_clear(hw);
 		retry++;
@@ -1278,7 +1280,7 @@
 
 	} while (retry < max_retry);
 
-	ixgbe_release_swfw_sync(hw, swfw_mask);
+	hw->mac.ops.release_swfw_sync(hw, swfw_mask);
 
 read_byte_out:
 	return status;
@@ -1306,7 +1308,7 @@
 	else
 		swfw_mask = IXGBE_GSSR_PHY0_SM;
 
-	if (ixgbe_acquire_swfw_sync(hw, swfw_mask) != 0) {
+	if (hw->mac.ops.acquire_swfw_sync(hw, swfw_mask) != 0) {
 		status = IXGBE_ERR_SWFW_SYNC;
 		goto write_byte_out;
 	}
@@ -1350,7 +1352,7 @@
 			hw_dbg(hw, "I2C byte write error.\n");
 	} while (retry < max_retry);
 
-	ixgbe_release_swfw_sync(hw, swfw_mask);
+	hw->mac.ops.release_swfw_sync(hw, swfw_mask);
 
 write_byte_out:
 	return status;
diff -druN linux-2.6.39-libre/drivers/net/ixgbe/ixgbe_sriov.c linux-3.0-rc7-libre/drivers/net/ixgbe/ixgbe_sriov.c
--- linux-2.6.39-libre/drivers/net/ixgbe/ixgbe_sriov.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/ixgbe/ixgbe_sriov.c	2011-07-11 19:51:52.000000000 -0400
@@ -82,6 +82,21 @@
 	return 0;
 }
 
+static void ixgbe_restore_vf_macvlans(struct ixgbe_adapter *adapter)
+{
+	struct ixgbe_hw *hw = &adapter->hw;
+	struct list_head *pos;
+	struct vf_macvlans *entry;
+
+	list_for_each(pos, &adapter->vf_mvs.l) {
+		entry = list_entry(pos, struct vf_macvlans, l);
+		if (entry->free == false)
+			hw->mac.ops.set_rar(hw, entry->rar_entry,
+					    entry->vf_macvlan,
+					    entry->vf, IXGBE_RAH_AV);
+	}
+}
+
 void ixgbe_restore_vf_multicasts(struct ixgbe_adapter *adapter)
 {
 	struct ixgbe_hw *hw = &adapter->hw;
@@ -102,6 +117,9 @@
 			IXGBE_WRITE_REG(hw, IXGBE_MTA(vector_reg), mta_reg);
 		}
 	}
+
+	/* Restore any VF macvlans */
+	ixgbe_restore_vf_macvlans(adapter);
 }
 
 static int ixgbe_set_vf_vlan(struct ixgbe_adapter *adapter, int add, int vid,
@@ -110,7 +128,7 @@
 	return adapter->hw.mac.ops.set_vfta(&adapter->hw, vid, vf, (bool)add);
 }
 
-void ixgbe_set_vf_lpe(struct ixgbe_adapter *adapter, u32 *msgbuf)
+static void ixgbe_set_vf_lpe(struct ixgbe_adapter *adapter, u32 *msgbuf)
 {
 	struct ixgbe_hw *hw = &adapter->hw;
 	int new_mtu = msgbuf[1];
@@ -200,6 +218,61 @@
 	return 0;
 }
 
+static int ixgbe_set_vf_macvlan(struct ixgbe_adapter *adapter,
+				int vf, int index, unsigned char *mac_addr)
+{
+	struct ixgbe_hw *hw = &adapter->hw;
+	struct list_head *pos;
+	struct vf_macvlans *entry;
+
+	if (index <= 1) {
+		list_for_each(pos, &adapter->vf_mvs.l) {
+			entry = list_entry(pos, struct vf_macvlans, l);
+			if (entry->vf == vf) {
+				entry->vf = -1;
+				entry->free = true;
+				entry->is_macvlan = false;
+				hw->mac.ops.clear_rar(hw, entry->rar_entry);
+			}
+		}
+	}
+
+	/*
+	 * If index was zero then we were asked to clear the uc list
+	 * for the VF.  We're done.
+	 */
+	if (!index)
+		return 0;
+
+	entry = NULL;
+
+	list_for_each(pos, &adapter->vf_mvs.l) {
+		entry = list_entry(pos, struct vf_macvlans, l);
+		if (entry->free)
+			break;
+	}
+
+	/*
+	 * If we traversed the entire list and didn't find a free entry
+	 * then we're out of space on the RAR table.  Also entry may
+	 * be NULL because the original memory allocation for the list
+	 * failed, which is not fatal but does mean we can't support
+	 * VF requests for MACVLAN because we couldn't allocate
+	 * memory for the list management required.
+	 */
+	if (!entry || !entry->free)
+		return -ENOSPC;
+
+	entry->free = false;
+	entry->is_macvlan = true;
+	entry->vf = vf;
+	memcpy(entry->vf_macvlan, mac_addr, ETH_ALEN);
+
+	hw->mac.ops.set_rar(hw, entry->rar_entry, mac_addr, vf, IXGBE_RAH_AV);
+
+	return 0;
+}
+
 int ixgbe_vf_configuration(struct pci_dev *pdev, unsigned int event_mask)
 {
 	unsigned char vf_mac_addr[6];
@@ -251,12 +324,12 @@
 static int ixgbe_rcv_msg_from_vf(struct ixgbe_adapter *adapter, u32 vf)
 {
 	u32 mbx_size = IXGBE_VFMAILBOX_SIZE;
-	u32 msgbuf[mbx_size];
+	u32 msgbuf[IXGBE_VFMAILBOX_SIZE];
 	struct ixgbe_hw *hw = &adapter->hw;
 	s32 retval;
 	int entries;
 	u16 *hash_list;
-	int add, vid;
+	int add, vid, index;
 	u8 *new_mac;
 
 	retval = ixgbe_read_mbx(hw, msgbuf, mbx_size, vf);
@@ -345,6 +418,24 @@
 			retval = ixgbe_set_vf_vlan(adapter, add, vid, vf);
 		}
 		break;
+	case IXGBE_VF_SET_MACVLAN:
+		index = (msgbuf[0] & IXGBE_VT_MSGINFO_MASK) >>
+			IXGBE_VT_MSGINFO_SHIFT;
+		/*
+		 * If the VF is allowed to set MAC filters then turn off
+		 * anti-spoofing to avoid false positives.  An index
+		 * greater than 0 will indicate the VF is setting a
+		 * macvlan MAC filter.
+		 */
+		if (index > 0 && adapter->antispoofing_enabled) {
+			hw->mac.ops.set_mac_anti_spoofing(hw, false,
+							  adapter->num_vfs);
+			hw->mac.ops.set_vlan_anti_spoofing(hw, false, vf);
+			adapter->antispoofing_enabled = false;
+		}
+		retval = ixgbe_set_vf_macvlan(adapter, vf, index,
+					      (unsigned char *)(&msgbuf[1]));
+		break;
 	default:
 		e_err(drv, "Unhandled Msg %8.8x\n", msgbuf[0]);
 		retval = IXGBE_ERR_MBX;
@@ -452,7 +543,8 @@
 			goto out;
 		ixgbe_set_vmvir(adapter, vlan | (qos << VLAN_PRIO_SHIFT), vf);
 		ixgbe_set_vmolr(hw, vf, false);
-		hw->mac.ops.set_vlan_anti_spoofing(hw, true, vf);
+		if (adapter->antispoofing_enabled)
+			hw->mac.ops.set_vlan_anti_spoofing(hw, true, vf);
 		adapter->vfinfo[vf].pf_vlan = vlan;
 		adapter->vfinfo[vf].pf_qos = qos;
 		dev_info(&adapter->pdev->dev,
diff -druN linux-2.6.39-libre/drivers/net/ixgbe/ixgbe_type.h linux-3.0-rc7-libre/drivers/net/ixgbe/ixgbe_type.h
--- linux-2.6.39-libre/drivers/net/ixgbe/ixgbe_type.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/ixgbe/ixgbe_type.h	2011-07-11 19:51:52.000000000 -0400
@@ -58,9 +58,11 @@
 #define IXGBE_DEV_ID_82599_SFP_FCOE      0x1529
 #define IXGBE_SUBDEV_ID_82599_SFP        0x11A9
 #define IXGBE_DEV_ID_82599_SFP_EM        0x1507
+#define IXGBE_DEV_ID_82599_SFP_SF2       0x154D
 #define IXGBE_DEV_ID_82599_XAUI_LOM      0x10FC
 #define IXGBE_DEV_ID_82599_COMBO_BACKPLANE 0x10F8
 #define IXGBE_SUBDEV_ID_82599_KX4_KR_MEZZ  0x000C
+#define IXGBE_DEV_ID_82599_LS            0x154F
 #define IXGBE_DEV_ID_X540T               0x1528
 
 /* General Registers */
@@ -163,6 +165,9 @@
                          (0x0D018 + ((_i - 64) * 0x40)))
 #define IXGBE_RXDCTL(_i) (((_i) < 64) ? (0x01028 + ((_i) * 0x40)) : \
                           (0x0D028 + ((_i - 64) * 0x40)))
+#define IXGBE_RSCCTL(_i) (((_i) < 64) ? (0x0102C + ((_i) * 0x40)) : \
+                          (0x0D02C + ((_i - 64) * 0x40)))
+#define IXGBE_RSCDBU     0x03028
 #define IXGBE_RDDCC      0x02F20
 #define IXGBE_RXMEMWRAP  0x03190
 #define IXGBE_STARCTRL   0x03024
@@ -227,17 +232,23 @@
 #define IXGBE_VLVF(_i)  (0x0F100 + ((_i) * 4))  /* 64 of these (0-63) */
 #define IXGBE_VLVFB(_i) (0x0F200 + ((_i) * 4))  /* 128 of these (0-127) */
 #define IXGBE_VMVIR(_i) (0x08000 + ((_i) * 4))  /* 64 of these (0-63) */
-#define IXGBE_VT_CTL    0x051B0
-#define IXGBE_VFRE(_i)  (0x051E0 + ((_i) * 4))
-#define IXGBE_VFTE(_i)  (0x08110 + ((_i) * 4))
-#define IXGBE_VMECM(_i) (0x08790 + ((_i) * 4))
-#define IXGBE_QDE       0x2F04
-#define IXGBE_VMOLR(_i) (0x0F000 + ((_i) * 4)) /* 64 total */
-#define IXGBE_UTA(_i)   (0x0F400 + ((_i) * 4))
-#define IXGBE_VMRCTL(_i)        (0x0F600 + ((_i) * 4))
-#define IXGBE_VMRVLAN(_i)       (0x0F610 + ((_i) * 4))
-#define IXGBE_VMRVM(_i)         (0x0F630 + ((_i) * 4))
-#define IXGBE_L34T_IMIR(_i)      (0x0E800 + ((_i) * 4)) /*128 of these (0-127)*/
+#define IXGBE_VT_CTL         0x051B0
+#define IXGBE_PFMAILBOX(_i)  (0x04B00 + (4 * (_i))) /* 64 total */
+#define IXGBE_PFMBMEM(_i)    (0x13000 + (64 * (_i))) /* 64 Mailboxes, 16 DW each */
+#define IXGBE_PFMBICR(_i)    (0x00710 + (4 * (_i))) /* 4 total */
+#define IXGBE_PFMBIMR(_i)    (0x00720 + (4 * (_i))) /* 4 total */
+#define IXGBE_VFRE(_i)       (0x051E0 + ((_i) * 4))
+#define IXGBE_VFTE(_i)       (0x08110 + ((_i) * 4))
+#define IXGBE_VMECM(_i)      (0x08790 + ((_i) * 4))
+#define IXGBE_QDE            0x2F04
+#define IXGBE_VMTXSW(_i)     (0x05180 + ((_i) * 4)) /* 2 total */
+#define IXGBE_VMOLR(_i)      (0x0F000 + ((_i) * 4)) /* 64 total */
+#define IXGBE_UTA(_i)        (0x0F400 + ((_i) * 4))
+#define IXGBE_MRCTL(_i)      (0x0F600 + ((_i) * 4))
+#define IXGBE_VMRVLAN(_i)    (0x0F610 + ((_i) * 4))
+#define IXGBE_VMRVM(_i)      (0x0F630 + ((_i) * 4))
+#define IXGBE_L34T_IMIR(_i)  (0x0E800 + ((_i) * 4)) /*128 of these (0-127)*/
+#define IXGBE_RXFECCERR0         0x051B8
 #define IXGBE_LLITHRESH 0x0EC90
 #define IXGBE_IMIR(_i)  (0x05A80 + ((_i) * 4))  /* 8 of these (0-7) */
 #define IXGBE_IMIREXT(_i)       (0x05AA0 + ((_i) * 4))  /* 8 of these (0-7) */
@@ -364,7 +375,7 @@
 #define IXGBE_WUFC_FLX5 0x00200000 /* Flexible Filter 5 Enable */
 #define IXGBE_WUFC_FLX_FILTERS     0x000F0000 /* Mask for 4 flex filters */
 #define IXGBE_WUFC_EXT_FLX_FILTERS 0x00300000 /* Mask for Ext. flex filters */
-#define IXGBE_WUFC_ALL_FILTERS     0x003F00FF /* Mask for all 6 wakeup filters*/
+#define IXGBE_WUFC_ALL_FILTERS     0x003F00FF /* Mask for all wakeup filters */
 #define IXGBE_WUFC_FLX_OFFSET      16 /* Offset to the Flexible Filters bits */
 
 /* Wake Up Status */
@@ -406,7 +417,6 @@
 #define IXGBE_SECTXSTAT         0x08804
 #define IXGBE_SECTXBUFFAF       0x08808
 #define IXGBE_SECTXMINIFG       0x08810
-#define IXGBE_SECTXSTAT         0x08804
 #define IXGBE_SECRXCTRL         0x08D00
 #define IXGBE_SECRXSTAT         0x08D04
 
@@ -499,21 +509,6 @@
 
 #define IXGBE_SECTXCTRL_STORE_FORWARD_ENABLE    0x4
 
-/* HW RSC registers */
-#define IXGBE_RSCCTL(_i) (((_i) < 64) ? (0x0102C + ((_i) * 0x40)) : \
-                          (0x0D02C + ((_i - 64) * 0x40)))
-#define IXGBE_RSCDBU      0x03028
-#define IXGBE_RSCCTL_RSCEN          0x01
-#define IXGBE_RSCCTL_MAXDESC_1      0x00
-#define IXGBE_RSCCTL_MAXDESC_4      0x04
-#define IXGBE_RSCCTL_MAXDESC_8      0x08
-#define IXGBE_RSCCTL_MAXDESC_16     0x0C
-#define IXGBE_RXDADV_RSCCNT_SHIFT     17
-#define IXGBE_GPIE_RSC_DELAY_SHIFT    11
-#define IXGBE_RXDADV_RSCCNT_MASK    0x001E0000
-#define IXGBE_RSCDBU_RSCACKDIS      0x00000080
-#define IXGBE_RDRXCTL_RSCFRSTSIZE   0x003E0000
-
 /* DCB registers */
 #define IXGBE_RTRPCS      0x02430
 #define IXGBE_RTTDCS      0x04900
@@ -522,6 +517,7 @@
 #define IXGBE_RTRUP2TC    0x03020
 #define IXGBE_RTTUP2TC    0x0C800
 #define IXGBE_RTRPT4C(_i) (0x02140 + ((_i) * 4)) /* 8 of these (0-7) */
+#define IXGBE_TXLLQ(_i)   (0x082E0 + ((_i) * 4)) /* 4 of these (0-3) */
 #define IXGBE_RTRPT4S(_i) (0x02160 + ((_i) * 4)) /* 8 of these (0-7) */
 #define IXGBE_RTTDT2C(_i) (0x04910 + ((_i) * 4)) /* 8 of these (0-7) */
 #define IXGBE_RTTDT2S(_i) (0x04930 + ((_i) * 4)) /* 8 of these (0-7) */
@@ -540,7 +536,7 @@
 	(IXGBE_RTTBCNRC_RF_DEC_MASK << IXGBE_RTTBCNRC_RF_INT_SHIFT)
 
 
-/* FCoE registers */
+/* FCoE DMA Context Registers */
 #define IXGBE_FCPTRL    0x02410 /* FC User Desc. PTR Low */
 #define IXGBE_FCPTRH    0x02414 /* FC USer Desc. PTR High */
 #define IXGBE_FCBUFF    0x02418 /* FC Buffer Control */
@@ -677,6 +673,10 @@
 #define IXGBE_FCOEDWRC  0x0242C /* Number of FCoE DWords Received */
 #define IXGBE_FCOEPTC   0x08784 /* Number of FCoE Packets Transmitted */
 #define IXGBE_FCOEDWTC  0x08788 /* Number of FCoE DWords Transmitted */
+#define IXGBE_O2BGPTC   0x041C4
+#define IXGBE_O2BSPC    0x087B0
+#define IXGBE_B2OSPC    0x041C0
+#define IXGBE_B2OGPRC   0x02F90
 #define IXGBE_PCRC8ECL  0x0E810
 #define IXGBE_PCRC8ECH  0x0E811
 #define IXGBE_PCRC8ECH_MASK     0x1F
@@ -742,17 +742,10 @@
 #define IXGBE_PBACLR_82599      0x11068
 #define IXGBE_CIAA_82599        0x11088
 #define IXGBE_CIAD_82599        0x1108C
-#define IXGBE_PCIE_DIAG_0_82599 0x11090
-#define IXGBE_PCIE_DIAG_1_82599 0x11094
-#define IXGBE_PCIE_DIAG_2_82599 0x11098
-#define IXGBE_PCIE_DIAG_3_82599 0x1109C
-#define IXGBE_PCIE_DIAG_4_82599 0x110A0
-#define IXGBE_PCIE_DIAG_5_82599 0x110A4
-#define IXGBE_PCIE_DIAG_6_82599 0x110A8
-#define IXGBE_PCIE_DIAG_7_82599 0x110C0
-#define IXGBE_INTRPT_CSR_82599  0x110B0
-#define IXGBE_INTRPT_MASK_82599 0x110B8
+#define IXGBE_PICAUSE           0x110B0
+#define IXGBE_PIENA             0x110B8
 #define IXGBE_CDQ_MBR_82599     0x110B4
+#define IXGBE_PCIESPARE         0x110BC
 #define IXGBE_MISC_REG_82599    0x110F0
 #define IXGBE_ECC_CTRL_0_82599  0x11100
 #define IXGBE_ECC_CTRL_1_82599  0x11104
@@ -785,7 +778,19 @@
 #define IXGBE_SYSTIML    0x08C0C /* System time register Low - RO */
 #define IXGBE_SYSTIMH    0x08C10 /* System time register High - RO */
 #define IXGBE_TIMINCA    0x08C14 /* Increment attributes register - RW */
-#define IXGBE_RXUDP      0x08C1C /* Time Sync Rx UDP Port - RW */
+#define IXGBE_TIMADJL    0x08C18 /* Time Adjustment Offset register Low - RW */
+#define IXGBE_TIMADJH    0x08C1C /* Time Adjustment Offset register High - RW */
+#define IXGBE_TSAUXC     0x08C20 /* TimeSync Auxiliary Control register - RW */
+#define IXGBE_TRGTTIML0  0x08C24 /* Target Time Register 0 Low - RW */
+#define IXGBE_TRGTTIMH0  0x08C28 /* Target Time Register 0 High - RW */
+#define IXGBE_TRGTTIML1  0x08C2C /* Target Time Register 1 Low - RW */
+#define IXGBE_TRGTTIMH1  0x08C30 /* Target Time Register 1 High - RW */
+#define IXGBE_FREQOUT0   0x08C34 /* Frequency Out 0 Control register - RW */
+#define IXGBE_FREQOUT1   0x08C38 /* Frequency Out 1 Control register - RW */
+#define IXGBE_AUXSTMPL0  0x08C3C /* Auxiliary Time Stamp 0 register Low - RO */
+#define IXGBE_AUXSTMPH0  0x08C40 /* Auxiliary Time Stamp 0 register High - RO */
+#define IXGBE_AUXSTMPL1  0x08C44 /* Auxiliary Time Stamp 1 register Low - RO */
+#define IXGBE_AUXSTMPH1  0x08C48 /* Auxiliary Time Stamp 1 register High - RO */
 
 /* Diagnostic Registers */
 #define IXGBE_RDSTATCTL   0x02C20
@@ -829,8 +834,20 @@
 #define IXGBE_TXDATARDPTR(_i)   (0x0C720 + ((_i) * 4)) /* 8 of these C720-C72C*/
 #define IXGBE_TXDESCRDPTR(_i)   (0x0C730 + ((_i) * 4)) /* 8 of these C730-C73C*/
 #define IXGBE_PCIEECCCTL 0x1106C
+#define IXGBE_RXWRPTR(_i)       (0x03100 + ((_i) * 4)) /* 8 of these 3100-310C*/
+#define IXGBE_RXUSED(_i)        (0x03120 + ((_i) * 4)) /* 8 of these 3120-312C*/
+#define IXGBE_RXRDPTR(_i)       (0x03140 + ((_i) * 4)) /* 8 of these 3140-314C*/
+#define IXGBE_RXRDWRPTR(_i)     (0x03160 + ((_i) * 4)) /* 8 of these 3160-310C*/
+#define IXGBE_TXWRPTR(_i)       (0x0C100 + ((_i) * 4)) /* 8 of these C100-C10C*/
+#define IXGBE_TXUSED(_i)        (0x0C120 + ((_i) * 4)) /* 8 of these C120-C12C*/
+#define IXGBE_TXRDPTR(_i)       (0x0C140 + ((_i) * 4)) /* 8 of these C140-C14C*/
+#define IXGBE_TXRDWRPTR(_i)     (0x0C160 + ((_i) * 4)) /* 8 of these C160-C10C*/
 #define IXGBE_PCIEECCCTL0 0x11100
 #define IXGBE_PCIEECCCTL1 0x11104
+#define IXGBE_RXDBUECC  0x03F70
+#define IXGBE_TXDBUECC  0x0CF70
+#define IXGBE_RXDBUEST 0x03F74
+#define IXGBE_TXDBUEST 0x0CF74
 #define IXGBE_PBTXECC   0x0C300
 #define IXGBE_PBRXECC   0x03300
 #define IXGBE_GHECCR    0x110B0
@@ -871,6 +888,7 @@
 #define IXGBE_AUTOC3    0x042AC
 #define IXGBE_ANLP1     0x042B0
 #define IXGBE_ANLP2     0x042B4
+#define IXGBE_MACC      0x04330
 #define IXGBE_ATLASCTL  0x04800
 #define IXGBE_MMNGC     0x042D0
 #define IXGBE_ANLPNP1   0x042D4
@@ -883,14 +901,49 @@
 #define IXGBE_MPVC      0x04318
 #define IXGBE_SGMIIC    0x04314
 
+/* Statistics Registers */
+#define IXGBE_RXNFGPC      0x041B0
+#define IXGBE_RXNFGBCL     0x041B4
+#define IXGBE_RXNFGBCH     0x041B8
+#define IXGBE_RXDGPC       0x02F50
+#define IXGBE_RXDGBCL      0x02F54
+#define IXGBE_RXDGBCH      0x02F58
+#define IXGBE_RXDDGPC      0x02F5C
+#define IXGBE_RXDDGBCL     0x02F60
+#define IXGBE_RXDDGBCH     0x02F64
+#define IXGBE_RXLPBKGPC    0x02F68
+#define IXGBE_RXLPBKGBCL   0x02F6C
+#define IXGBE_RXLPBKGBCH   0x02F70
+#define IXGBE_RXDLPBKGPC   0x02F74
+#define IXGBE_RXDLPBKGBCL  0x02F78
+#define IXGBE_RXDLPBKGBCH  0x02F7C
+#define IXGBE_TXDGPC       0x087A0
+#define IXGBE_TXDGBCL      0x087A4
+#define IXGBE_TXDGBCH      0x087A8
+
+#define IXGBE_RXDSTATCTRL 0x02F40
+
+/* Copper Pond 2 link timeout */
 #define IXGBE_VALIDATE_LINK_READY_TIMEOUT 50
 
 /* Omer CORECTL */
 #define IXGBE_CORECTL           0x014F00
 /* BARCTRL */
-#define IXGBE_BARCTRL           0x110F4
-#define IXGBE_BARCTRL_FLSIZE    0x0700
-#define IXGBE_BARCTRL_CSRSIZE   0x2000
+#define IXGBE_BARCTRL               0x110F4
+#define IXGBE_BARCTRL_FLSIZE        0x0700
+#define IXGBE_BARCTRL_FLSIZE_SHIFT  8
+#define IXGBE_BARCTRL_CSRSIZE       0x2000
+
+/* RSCCTL Bit Masks */
+#define IXGBE_RSCCTL_RSCEN          0x01
+#define IXGBE_RSCCTL_MAXDESC_1      0x00
+#define IXGBE_RSCCTL_MAXDESC_4      0x04
+#define IXGBE_RSCCTL_MAXDESC_8      0x08
+#define IXGBE_RSCCTL_MAXDESC_16     0x0C
+
+/* RSCDBU Bit Masks */
+#define IXGBE_RSCDBU_RSCSMALDIS_MASK    0x0000007F
+#define IXGBE_RSCDBU_RSCACKDIS          0x00000080
 
 /* RDRXCTL Bit Masks */
 #define IXGBE_RDRXCTL_RDMTS_1_2     0x00000000 /* Rx Desc Min Threshold Size */
@@ -898,6 +951,8 @@
 #define IXGBE_RDRXCTL_MVMEN         0x00000020
 #define IXGBE_RDRXCTL_DMAIDONE      0x00000008 /* DMA init cycle done */
 #define IXGBE_RDRXCTL_AGGDIS        0x00010000 /* Aggregation disable */
+#define IXGBE_RDRXCTL_RSCFRSTSIZE   0x003E0000 /* RSC First packet size */
+#define IXGBE_RDRXCTL_RSCLLIDIS     0x00800000 /* Disable RSC compl on LLI */
 #define IXGBE_RDRXCTL_RSCACKC       0x02000000 /* must set 1 when RSC enabled */
 #define IXGBE_RDRXCTL_FCOE_WRFIX    0x04000000 /* must set 1 when RSC enabled */
 
@@ -969,8 +1024,8 @@
 #define IXGBE_MSCA_OP_CODE_SHIFT     26 /* OP CODE shift */
 #define IXGBE_MSCA_ADDR_CYCLE        0x00000000 /* OP CODE 00 (addr cycle) */
 #define IXGBE_MSCA_WRITE             0x04000000 /* OP CODE 01 (write) */
-#define IXGBE_MSCA_READ              0x08000000 /* OP CODE 10 (read) */
-#define IXGBE_MSCA_READ_AUTOINC      0x0C000000 /* OP CODE 11 (read, auto inc)*/
+#define IXGBE_MSCA_READ              0x0C000000 /* OP CODE 11 (read) */
+#define IXGBE_MSCA_READ_AUTOINC      0x08000000 /* OP CODE 10 (read, auto inc)*/
 #define IXGBE_MSCA_ST_CODE_MASK      0x30000000 /* ST Code mask */
 #define IXGBE_MSCA_ST_CODE_SHIFT     28 /* ST Code shift */
 #define IXGBE_MSCA_NEW_PROTOCOL      0x00000000 /* ST CODE 00 (new protocol) */
@@ -1057,6 +1112,7 @@
 #define IXGBE_GPIE_EIMEN         0x00000040 /* Immediate Interrupt Enable */
 #define IXGBE_GPIE_EIAME         0x40000000
 #define IXGBE_GPIE_PBA_SUPPORT   0x80000000
+#define IXGBE_GPIE_RSC_DELAY_SHIFT 11
 #define IXGBE_GPIE_VTMODE_MASK   0x0000C000 /* VT Mode Mask */
 #define IXGBE_GPIE_VTMODE_16     0x00004000 /* 16 VFs 8 queues per VF */
 #define IXGBE_GPIE_VTMODE_32     0x00008000 /* 32 VFs 4 queues per VF */
@@ -1291,6 +1347,11 @@
 #define IXGBE_FTQF_POOL_SHIFT           8
 #define IXGBE_FTQF_5TUPLE_MASK_MASK     0x0000001F
 #define IXGBE_FTQF_5TUPLE_MASK_SHIFT    25
+#define IXGBE_FTQF_SOURCE_ADDR_MASK     0x1E
+#define IXGBE_FTQF_DEST_ADDR_MASK       0x1D
+#define IXGBE_FTQF_SOURCE_PORT_MASK     0x1B
+#define IXGBE_FTQF_DEST_PORT_MASK       0x17
+#define IXGBE_FTQF_PROTOCOL_COMP_MASK   0x0F
 #define IXGBE_FTQF_POOL_MASK_EN         0x40000000
 #define IXGBE_FTQF_QUEUE_ENABLE         0x80000000
 
@@ -1333,11 +1394,11 @@
  *
  * Current filters:
  *    EAPOL 802.1x (0x888e): Filter 0
- *    BCN (0x8904):          Filter 1
+ *    FCoE (0x8906):         Filter 2
  *    1588 (0x88f7):         Filter 3
+ *    FIP  (0x8914):         Filter 4
  */
 #define IXGBE_ETQF_FILTER_EAPOL          0
-#define IXGBE_ETQF_FILTER_BCN            1
 #define IXGBE_ETQF_FILTER_FCOE           2
 #define IXGBE_ETQF_FILTER_1588           3
 #define IXGBE_ETQF_FILTER_FIP            4
@@ -1448,6 +1509,11 @@
 #define IXGBE_AUTOC2_10G_XFI (0x1 << IXGBE_AUTOC2_10G_SERIAL_PMA_PMD_SHIFT)
 #define IXGBE_AUTOC2_10G_SFI (0x2 << IXGBE_AUTOC2_10G_SERIAL_PMA_PMD_SHIFT)
 
+#define IXGBE_MACC_FLU       0x00000001
+#define IXGBE_MACC_FSV_10G   0x00030000
+#define IXGBE_MACC_FS        0x00040000
+#define IXGBE_MAC_RX2TX_LPBK 0x00000002
+
 /* LINKS Bit Masks */
 #define IXGBE_LINKS_KX_AN_COMP  0x80000000
 #define IXGBE_LINKS_UP          0x40000000
@@ -1501,7 +1567,6 @@
 #define IXGBE_ANLP1_ASM_PAUSE           0x0800
 #define IXGBE_ANLP1_AN_STATE_MASK       0x000f0000
 
-
 /* SW Semaphore Register bitmasks */
 #define IXGBE_SWSM_SMBI 0x00000001 /* Driver Semaphore bit */
 #define IXGBE_SWSM_SWESMBI 0x00000002 /* FW Semaphore bit */
@@ -1514,6 +1579,10 @@
 #define IXGBE_GSSR_PHY1_SM    0x0004
 #define IXGBE_GSSR_MAC_CSR_SM 0x0008
 #define IXGBE_GSSR_FLASH_SM   0x0010
+#define IXGBE_GSSR_SW_MNG_SM  0x0400
+
+/* FW Status register bitmask */
+#define IXGBE_FWSTS_FWRI    0x00000200 /* Firmware Reset Indication */
 
 /* EEC Register */
 #define IXGBE_EEC_SK        0x00000001 /* EEPROM Clock */
@@ -1534,6 +1603,7 @@
 /* EEPROM Addressing bits based on type (0-small, 1-large) */
 #define IXGBE_EEC_ADDR_SIZE 0x00000400
 #define IXGBE_EEC_SIZE      0x00007800 /* EEPROM Size */
+#define IXGBE_EERD_MAX_ADDR 0x00003FFF /* EERD alows 14 bits for addr. */
 
 #define IXGBE_EEC_SIZE_SHIFT          11
 #define IXGBE_EEPROM_WORD_SIZE_SHIFT  6
@@ -1563,8 +1633,10 @@
 #define IXGBE_FW_PTR            0x0F
 #define IXGBE_PBANUM0_PTR       0x15
 #define IXGBE_PBANUM1_PTR       0x16
-#define IXGBE_DEVICE_CAPS       0x2C
+#define IXGBE_FREE_SPACE_PTR    0X3E
 #define IXGBE_SAN_MAC_ADDR_PTR  0x28
+#define IXGBE_DEVICE_CAPS       0x2C
+#define IXGBE_SERIAL_NUMBER_MAC_ADDR 0x11
 #define IXGBE_PCIE_MSIX_82599_CAPS  0x72
 #define IXGBE_PCIE_MSIX_82598_CAPS  0x62
 
@@ -1601,6 +1673,10 @@
 
 #define IXGBE_ETH_LENGTH_OF_ADDRESS   6
 
+#define IXGBE_EEPROM_PAGE_SIZE_MAX       128
+#define IXGBE_EEPROM_RD_BUFFER_MAX_COUNT 512 /* EEPROM words # read in burst */
+#define IXGBE_EEPROM_WR_BUFFER_MAX_COUNT 256 /* EEPROM words # wr in burst */
+
 #ifndef IXGBE_EEPROM_GRANT_ATTEMPTS
 #define IXGBE_EEPROM_GRANT_ATTEMPTS 1000 /* EEPROM # attempts to gain grant */
 #endif
@@ -1616,14 +1692,25 @@
 #define IXGBE_FLUDONE_ATTEMPTS 20000
 #endif
 
+#define IXGBE_PCIE_CTRL2                 0x5   /* PCIe Control 2 Offset */
+#define IXGBE_PCIE_CTRL2_DUMMY_ENABLE    0x8   /* Dummy Function Enable */
+#define IXGBE_PCIE_CTRL2_LAN_DISABLE     0x2   /* LAN PCI Disable */
+#define IXGBE_PCIE_CTRL2_DISABLE_SELECT  0x1   /* LAN Disable Select */
+
 #define IXGBE_SAN_MAC_ADDR_PORT0_OFFSET  0x0
 #define IXGBE_SAN_MAC_ADDR_PORT1_OFFSET  0x3
 #define IXGBE_DEVICE_CAPS_ALLOW_ANY_SFP  0x1
 #define IXGBE_DEVICE_CAPS_FCOE_OFFLOADS  0x2
+#define IXGBE_FW_LESM_PARAMETERS_PTR     0x2
+#define IXGBE_FW_LESM_STATE_1            0x1
+#define IXGBE_FW_LESM_STATE_ENABLED      0x8000 /* LESM Enable bit */
 #define IXGBE_FW_PASSTHROUGH_PATCH_CONFIG_PTR   0x4
-#define IXGBE_FW_PATCH_VERSION_4   0x7
-
-/* Alternative SAN MAC Address Block */
+#define IXGBE_FW_PATCH_VERSION_4         0x7
+#define IXGBE_FCOE_IBA_CAPS_BLK_PTR         0x33 /* iSCSI/FCOE block */
+#define IXGBE_FCOE_IBA_CAPS_FCOE            0x20 /* FCOE flags */
+#define IXGBE_ISCSI_FCOE_BLK_PTR            0x17 /* iSCSI/FCOE block */
+#define IXGBE_ISCSI_FCOE_FLAGS_OFFSET       0x0  /* FCOE flags */
+#define IXGBE_ISCSI_FCOE_FLAGS_ENABLE       0x1  /* FCOE flags enable bit */
 #define IXGBE_ALT_SAN_MAC_ADDR_BLK_PTR      0x27 /* Alt. SAN MAC block */
 #define IXGBE_ALT_SAN_MAC_ADDR_CAPS_OFFSET  0x0 /* Alt. SAN MAC capability */
 #define IXGBE_ALT_SAN_MAC_ADDR_PORT0_OFFSET 0x1 /* Alt. SAN MAC 0 offset */
@@ -1688,6 +1775,7 @@
 /* Transmit Config masks */
 #define IXGBE_TXDCTL_ENABLE     0x02000000 /* Enable specific Tx Queue */
 #define IXGBE_TXDCTL_SWFLSH     0x04000000 /* Tx Desc. write-back flushing */
+#define IXGBE_TXDCTL_WTHRESH_SHIFT      16 /* shift to WTHRESH bits */
 /* Enable short packet padding to 64 bytes */
 #define IXGBE_TX_PAD_ENABLE     0x00000400
 #define IXGBE_JUMBO_FRAME_ENABLE 0x00000004  /* Allow jumbo frames */
@@ -1701,9 +1789,9 @@
 #define IXGBE_RXCTRL_RXEN       0x00000001  /* Enable Receiver */
 #define IXGBE_RXCTRL_DMBYPS     0x00000002  /* Descriptor Monitor Bypass */
 #define IXGBE_RXDCTL_ENABLE     0x02000000  /* Enable specific Rx Queue */
-#define IXGBE_RXDCTL_VME        0x40000000  /* VLAN mode enable */
 #define IXGBE_RXDCTL_RLPMLMASK  0x00003FFF  /* Only supported on the X540 */
 #define IXGBE_RXDCTL_RLPML_EN   0x00008000
+#define IXGBE_RXDCTL_VME        0x40000000  /* VLAN mode enable */
 
 #define IXGBE_FCTRL_SBP 0x00000002 /* Store Bad Packet */
 #define IXGBE_FCTRL_MPE 0x00000100 /* Multicast Promiscuous Ena*/
@@ -1719,6 +1807,8 @@
 #define IXGBE_MFLCN_RPFCE       0x00000004 /* Receive Priority FC Enable */
 #define IXGBE_MFLCN_RFCE        0x00000008 /* Receive FC Enable */
 
+#define IXGBE_MFLCN_RPFCE_SHIFT		 4
+
 /* Multiple Receive Queue Control */
 #define IXGBE_MRQC_RSSEN                 0x00000001  /* RSS Enable */
 #define IXGBE_MRQC_MRQE_MASK                    0xF /* Bits 3:0 */
@@ -1859,6 +1949,8 @@
 #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
@@ -1934,15 +2026,6 @@
 #define IXGBE_VFLRE(_i)                  (((_i & 1) ? 0x001C0 : 0x00600))
 #define IXGBE_VFLREC(_i)                 (0x00700 + (_i * 4))
 
-/* Little Endian defines */
-#ifndef __le32
-#define __le32  u32
-#endif
-#ifndef __le64
-#define __le64  u64
-
-#endif
-
 enum ixgbe_fdir_pballoc_type {
 	IXGBE_FDIR_PBALLOC_64K = 0,
 	IXGBE_FDIR_PBALLOC_128K,
@@ -2141,8 +2224,6 @@
                                         IXGBE_LINK_SPEED_1GB_FULL | \
                                         IXGBE_LINK_SPEED_10GB_FULL)
 
-#define IXGBE_PCIE_DEV_CTRL_2 0xC8
-#define PCIE_COMPL_TO_VALUE 0x05
 
 /* Physical layer type */
 typedef u32 ixgbe_physical_layer;
@@ -2315,6 +2396,7 @@
 enum ixgbe_media_type {
 	ixgbe_media_type_unknown = 0,
 	ixgbe_media_type_fiber,
+	ixgbe_media_type_fiber_lco,
 	ixgbe_media_type_copper,
 	ixgbe_media_type_backplane,
 	ixgbe_media_type_cx4,
@@ -2478,6 +2560,10 @@
 	u64 fcoeptc;
 	u64 fcoedwrc;
 	u64 fcoedwtc;
+	u64 b2ospc;
+	u64 b2ogprc;
+	u64 o2bgptc;
+	u64 o2bspc;
 };
 
 /* forward declaration */
@@ -2491,7 +2577,9 @@
 struct ixgbe_eeprom_operations {
 	s32 (*init_params)(struct ixgbe_hw *);
 	s32 (*read)(struct ixgbe_hw *, u16, u16 *);
+	s32 (*read_buffer)(struct ixgbe_hw *, u16, u16, u16 *);
 	s32 (*write)(struct ixgbe_hw *, u16, u16);
+	s32 (*write_buffer)(struct ixgbe_hw *, u16, u16, u16 *);
 	s32 (*validate_checksum)(struct ixgbe_hw *, u16 *);
 	s32 (*update_checksum)(struct ixgbe_hw *);
 	u16 (*calc_checksum)(struct ixgbe_hw *);
@@ -2577,6 +2665,7 @@
 	u32                             semaphore_delay;
 	u16                             word_size;
 	u16                             address_bits;
+	u16                             word_page_size;
 };
 
 #define IXGBE_FLAGS_DOUBLE_RESET_REQUIRED	0x01
@@ -2597,6 +2686,7 @@
 	u32                             vft_size;
 	u32                             num_rar_entries;
 	u32                             rar_highwater;
+	u32				rx_pb_size;
 	u32                             max_tx_queues;
 	u32                             max_rx_queues;
 	u32                             max_msix_vectors;
diff -druN linux-2.6.39-libre/drivers/net/ixgbe/ixgbe_x540.c linux-3.0-rc7-libre/drivers/net/ixgbe/ixgbe_x540.c
--- linux-2.6.39-libre/drivers/net/ixgbe/ixgbe_x540.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/ixgbe/ixgbe_x540.c	2011-07-11 19:51:52.000000000 -0400
@@ -37,6 +37,7 @@
 #define IXGBE_X540_RAR_ENTRIES   128
 #define IXGBE_X540_MC_TBL_SIZE   128
 #define IXGBE_X540_VFT_TBL_SIZE  128
+#define IXGBE_X540_RX_PB_SIZE	 384
 
 static s32 ixgbe_update_flash_X540(struct ixgbe_hw *hw);
 static s32 ixgbe_poll_flash_update_done_X540(struct ixgbe_hw *hw);
@@ -226,6 +227,28 @@
 }
 
 /**
+ *  ixgbe_start_hw_X540 - Prepare hardware for Tx/Rx
+ *  @hw: pointer to hardware structure
+ *
+ *  Starts the hardware using the generic start_hw function
+ *  and the generation start_hw function.
+ *  Then performs revision-specific operations, if any.
+ **/
+static s32 ixgbe_start_hw_X540(struct ixgbe_hw *hw)
+{
+	s32 ret_val = 0;
+
+	ret_val = ixgbe_start_hw_generic(hw);
+	if (ret_val != 0)
+		goto out;
+
+	ret_val = ixgbe_start_hw_gen2(hw);
+	hw->mac.rx_pb_size = IXGBE_X540_RX_PB_SIZE;
+out:
+	return ret_val;
+}
+
+/**
  *  ixgbe_get_supported_physical_layer_X540 - Returns physical layer type
  *  @hw: pointer to hardware structure
  *
@@ -281,74 +304,105 @@
 }
 
 /**
- * ixgbe_read_eerd_X540 - Read EEPROM word using EERD
- * @hw: pointer to hardware structure
- * @offset: offset of word in the EEPROM to read
- * @data: word read from the EERPOM
+ *  ixgbe_read_eerd_X540- Read EEPROM word using EERD
+ *  @hw: pointer to hardware structure
+ *  @offset: offset of  word in the EEPROM to read
+ *  @data: word read from the EEPROM
+ *
+ *  Reads a 16 bit word from the EEPROM using the EERD register.
  **/
 static s32 ixgbe_read_eerd_X540(struct ixgbe_hw *hw, u16 offset, u16 *data)
 {
-	s32 status;
+	s32 status = 0;
 
-	if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM) == 0)
+	if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM) ==
+	    0)
 		status = ixgbe_read_eerd_generic(hw, offset, data);
 	else
 		status = IXGBE_ERR_SWFW_SYNC;
 
-	ixgbe_release_swfw_sync_X540(hw, IXGBE_GSSR_EEP_SM);
+	hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM);
 	return status;
 }
 
 /**
- * ixgbe_write_eewr_X540 - Write EEPROM word using EEWR
- * @hw: pointer to hardware structure
- * @offset: offset of  word in the EEPROM to write
- * @data: word write to the EEPROM
+ *  ixgbe_read_eerd_buffer_X540 - Read EEPROM word(s) using EERD
+ *  @hw: pointer to hardware structure
+ *  @offset: offset of  word in the EEPROM to read
+ *  @words: number of words
+ *  @data: word(s) read from the EEPROM
  *
- * Write a 16 bit word to the EEPROM using the EEWR register.
+ *  Reads a 16 bit word(s) from the EEPROM using the EERD register.
  **/
-static s32 ixgbe_write_eewr_X540(struct ixgbe_hw *hw, u16 offset, u16 data)
+static s32 ixgbe_read_eerd_buffer_X540(struct ixgbe_hw *hw,
+				       u16 offset, u16 words, u16 *data)
 {
-	u32 eewr;
-	s32 status;
+	s32 status = 0;
 
-	hw->eeprom.ops.init_params(hw);
+	if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM) ==
+	    0)
+		status = ixgbe_read_eerd_buffer_generic(hw, offset,
+							words, data);
+	else
+		status = IXGBE_ERR_SWFW_SYNC;
 
-	if (offset >= hw->eeprom.word_size) {
-		status = IXGBE_ERR_EEPROM;
-		goto out;
-	}
+	hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM);
+	return status;
+}
 
-	eewr = (offset << IXGBE_EEPROM_RW_ADDR_SHIFT) |
-	       (data << IXGBE_EEPROM_RW_REG_DATA) |
-	       IXGBE_EEPROM_RW_REG_START;
+/**
+ *  ixgbe_write_eewr_X540 - Write EEPROM word using EEWR
+ *  @hw: pointer to hardware structure
+ *  @offset: offset of  word in the EEPROM to write
+ *  @data: word write to the EEPROM
+ *
+ *  Write a 16 bit word to the EEPROM using the EEWR register.
+ **/
+static s32 ixgbe_write_eewr_X540(struct ixgbe_hw *hw, u16 offset, u16 data)
+{
+	s32 status = 0;
 
-	if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM) == 0) {
-		status = ixgbe_poll_eerd_eewr_done(hw, IXGBE_NVM_POLL_WRITE);
-		if (status != 0) {
-			hw_dbg(hw, "Eeprom write EEWR timed out\n");
-			goto out;
-		}
+	if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM) == 0)
+		status = ixgbe_write_eewr_generic(hw, offset, data);
+	else
+		status = IXGBE_ERR_SWFW_SYNC;
 
-		IXGBE_WRITE_REG(hw, IXGBE_EEWR, eewr);
+	hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM);
+	return status;
+}
 
-		status = ixgbe_poll_eerd_eewr_done(hw, IXGBE_NVM_POLL_WRITE);
-		if (status != 0) {
-			hw_dbg(hw, "Eeprom write EEWR timed out\n");
-			goto out;
-		}
-	} else {
+/**
+ *  ixgbe_write_eewr_buffer_X540 - Write EEPROM word(s) using EEWR
+ *  @hw: pointer to hardware structure
+ *  @offset: offset of  word in the EEPROM to write
+ *  @words: number of words
+ *  @data: word(s) write to the EEPROM
+ *
+ *  Write a 16 bit word(s) to the EEPROM using the EEWR register.
+ **/
+static s32 ixgbe_write_eewr_buffer_X540(struct ixgbe_hw *hw,
+					u16 offset, u16 words, u16 *data)
+{
+	s32 status = 0;
+
+	if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM) ==
+	    0)
+		status = ixgbe_write_eewr_buffer_generic(hw, offset,
+							 words, data);
+	else
 		status = IXGBE_ERR_SWFW_SYNC;
-	}
 
-out:
-	ixgbe_release_swfw_sync_X540(hw, IXGBE_GSSR_EEP_SM);
+	hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM);
 	return status;
 }
 
 /**
- * ixgbe_calc_eeprom_checksum_X540 - Calculates and returns the checksum
- * @hw: pointer to hardware structure
+ *  ixgbe_calc_eeprom_checksum_X540 - Calculates and returns the checksum
+ *
+ *  This function does not use synchronization for EERD and EEWR. It can
+ *  be used internally by function which utilize ixgbe_acquire_swfw_sync_X540.
+ *
+ *  @hw: pointer to hardware structure
  **/
 static u16 ixgbe_calc_eeprom_checksum_X540(struct ixgbe_hw *hw)
 {
@@ -359,9 +413,15 @@
 	u16 pointer = 0;
 	u16 word = 0;
 
+	/*
+	 * Do not use hw->eeprom.ops.read because we do not want to take
+	 * the synchronization semaphores here. Instead use
+	 * ixgbe_read_eerd_generic
+	 */
+
 	/* Include 0x0-0x3F in the checksum */
 	for (i = 0; i < IXGBE_EEPROM_CHECKSUM; i++) {
-		if (hw->eeprom.ops.read(hw, i, &word) != 0) {
+		if (ixgbe_read_eerd_generic(hw, i, &word) != 0) {
 			hw_dbg(hw, "EEPROM read failed\n");
 			break;
 		}
@@ -376,7 +436,7 @@
 		if (i == IXGBE_PHY_PTR || i == IXGBE_OPTION_ROM_PTR)
 			continue;
 
-		if (hw->eeprom.ops.read(hw, i, &pointer) != 0) {
+		if (ixgbe_read_eerd_generic(hw, i, &pointer) != 0) {
 			hw_dbg(hw, "EEPROM read failed\n");
 			break;
 		}
@@ -386,7 +446,7 @@
 		    pointer >= hw->eeprom.word_size)
 			continue;
 
-		if (hw->eeprom.ops.read(hw, pointer, &length) != 0) {
+		if (ixgbe_read_eerd_generic(hw, pointer, &length) != 0) {
 			hw_dbg(hw, "EEPROM read failed\n");
 			break;
 		}
@@ -397,7 +457,7 @@
 			continue;
 
 		for (j = pointer+1; j <= pointer+length; j++) {
-			if (hw->eeprom.ops.read(hw, j, &word) != 0) {
+			if (ixgbe_read_eerd_generic(hw, j, &word) != 0) {
 				hw_dbg(hw, "EEPROM read failed\n");
 				break;
 			}
@@ -411,6 +471,62 @@
 }
 
 /**
+ *  ixgbe_validate_eeprom_checksum_X540 - Validate EEPROM checksum
+ *  @hw: pointer to hardware structure
+ *  @checksum_val: calculated checksum
+ *
+ *  Performs checksum calculation and validates the EEPROM checksum.  If the
+ *  caller does not need checksum_val, the value can be NULL.
+ **/
+static s32 ixgbe_validate_eeprom_checksum_X540(struct ixgbe_hw *hw,
+					       u16 *checksum_val)
+{
+	s32 status;
+	u16 checksum;
+	u16 read_checksum = 0;
+
+	/*
+	 * Read the first word from the EEPROM. If this times out or fails, do
+	 * not continue or we could be in for a very long wait while every
+	 * EEPROM read fails
+	 */
+	status = hw->eeprom.ops.read(hw, 0, &checksum);
+
+	if (status != 0) {
+		hw_dbg(hw, "EEPROM read failed\n");
+		goto out;
+	}
+
+	if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM) == 0) {
+		checksum = hw->eeprom.ops.calc_checksum(hw);
+
+		/*
+		 * Do not use hw->eeprom.ops.read because we do not want to take
+		 * the synchronization semaphores twice here.
+		 */
+		ixgbe_read_eerd_generic(hw, IXGBE_EEPROM_CHECKSUM,
+					&read_checksum);
+
+		/*
+		 * Verify read checksum from EEPROM is the same as
+		 * calculated checksum
+		 */
+		if (read_checksum != checksum)
+			status = IXGBE_ERR_EEPROM_CHECKSUM;
+
+		/* If the user cares, return the calculated checksum */
+		if (checksum_val)
+			*checksum_val = checksum;
+	} else {
+		status = IXGBE_ERR_SWFW_SYNC;
+	}
+
+	hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM);
+out:
+	return status;
+}
+
+/**
  * ixgbe_update_eeprom_checksum_X540 - Updates the EEPROM checksum and flash
  * @hw: pointer to hardware structure
  *
@@ -421,11 +537,35 @@
 static s32 ixgbe_update_eeprom_checksum_X540(struct ixgbe_hw *hw)
 {
 	s32 status;
+	u16 checksum;
 
-	status = ixgbe_update_eeprom_checksum_generic(hw);
+	/*
+	 * Read the first word from the EEPROM. If this times out or fails, do
+	 * not continue or we could be in for a very long wait while every
+	 * EEPROM read fails
+	 */
+	status = hw->eeprom.ops.read(hw, 0, &checksum);
 
-	if (status)
+	if (status != 0)
+		hw_dbg(hw, "EEPROM read failed\n");
+
+	if (hw->mac.ops.acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM) == 0) {
+		checksum = hw->eeprom.ops.calc_checksum(hw);
+
+		/*
+		 * Do not use hw->eeprom.ops.write because we do not want to
+		 * take the synchronization semaphores twice here.
+		 */
+		status = ixgbe_write_eewr_generic(hw, IXGBE_EEPROM_CHECKSUM,
+						  checksum);
+
+	if (status == 0)
 		status = ixgbe_update_flash_X540(hw);
+	else
+		status = IXGBE_ERR_SWFW_SYNC;
+	}
+
+	hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_EEP_SM);
 
 	return status;
 }
@@ -452,7 +592,7 @@
 	IXGBE_WRITE_REG(hw, IXGBE_EEC, flup);
 
 	status = ixgbe_poll_flash_update_done_X540(hw);
-	if (status)
+	if (status == 0)
 		hw_dbg(hw, "Flash update complete\n");
 	else
 		hw_dbg(hw, "Flash update time out\n");
@@ -466,11 +606,10 @@
 		}
 
 		status = ixgbe_poll_flash_update_done_X540(hw);
-		if (status)
+		if (status == 0)
 			hw_dbg(hw, "Flash update complete\n");
 		else
 			hw_dbg(hw, "Flash update time out\n");
-
 	}
 out:
 	return status;
@@ -542,7 +681,7 @@
 			 * resource (swmask)
 			 */
 			ixgbe_release_swfw_sync_semaphore(hw);
-			msleep(5);
+			usleep_range(5000, 10000);
 		}
 	}
 
@@ -564,7 +703,7 @@
 		}
 	}
 
-	msleep(5);
+	usleep_range(5000, 10000);
 	return 0;
 }
 
@@ -588,7 +727,7 @@
 	IXGBE_WRITE_REG(hw, IXGBE_SWFW_SYNC, swfw_sync);
 
 	ixgbe_release_swfw_sync_semaphore(hw);
-	msleep(5);
+	usleep_range(5000, 10000);
 }
 
 /**
@@ -658,10 +797,70 @@
 	IXGBE_WRITE_FLUSH(hw);
 }
 
+/**
+ * ixgbe_blink_led_start_X540 - Blink LED based on index.
+ * @hw: pointer to hardware structure
+ * @index: led number to blink
+ *
+ * Devices that implement the version 2 interface:
+ *   X540
+ **/
+static s32 ixgbe_blink_led_start_X540(struct ixgbe_hw *hw, u32 index)
+{
+	u32 macc_reg;
+	u32 ledctl_reg;
+
+	/*
+	 * In order for the blink bit in the LED control register
+	 * to work, link and speed must be forced in the MAC. We
+	 * will reverse this when we stop the blinking.
+	 */
+	macc_reg = IXGBE_READ_REG(hw, IXGBE_MACC);
+	macc_reg |= IXGBE_MACC_FLU | IXGBE_MACC_FSV_10G | IXGBE_MACC_FS;
+	IXGBE_WRITE_REG(hw, IXGBE_MACC, macc_reg);
+
+	/* Set the LED to LINK_UP + BLINK. */
+	ledctl_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL);
+	ledctl_reg &= ~IXGBE_LED_MODE_MASK(index);
+	ledctl_reg |= IXGBE_LED_BLINK(index);
+	IXGBE_WRITE_REG(hw, IXGBE_LEDCTL, ledctl_reg);
+	IXGBE_WRITE_FLUSH(hw);
+
+	return 0;
+}
+
+/**
+ * ixgbe_blink_led_stop_X540 - Stop blinking LED based on index.
+ * @hw: pointer to hardware structure
+ * @index: led number to stop blinking
+ *
+ * Devices that implement the version 2 interface:
+ *   X540
+ **/
+static s32 ixgbe_blink_led_stop_X540(struct ixgbe_hw *hw, u32 index)
+{
+	u32 macc_reg;
+	u32 ledctl_reg;
+
+	/* Restore the LED to its default value. */
+	ledctl_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL);
+	ledctl_reg &= ~IXGBE_LED_MODE_MASK(index);
+	ledctl_reg |= IXGBE_LED_LINK_ACTIVE << IXGBE_LED_MODE_SHIFT(index);
+	ledctl_reg &= ~IXGBE_LED_BLINK(index);
+	IXGBE_WRITE_REG(hw, IXGBE_LEDCTL, ledctl_reg);
+
+	/* Unforce link and speed in the MAC. */
+	macc_reg = IXGBE_READ_REG(hw, IXGBE_MACC);
+	macc_reg &= ~(IXGBE_MACC_FLU | IXGBE_MACC_FSV_10G | IXGBE_MACC_FS);
+	IXGBE_WRITE_REG(hw, IXGBE_MACC, macc_reg);
+	IXGBE_WRITE_FLUSH(hw);
+
+	return 0;
+}
 static struct ixgbe_mac_operations mac_ops_X540 = {
 	.init_hw                = &ixgbe_init_hw_generic,
 	.reset_hw               = &ixgbe_reset_hw_X540,
-	.start_hw               = &ixgbe_start_hw_generic,
+	.start_hw               = &ixgbe_start_hw_X540,
 	.clear_hw_cntrs         = &ixgbe_clear_hw_cntrs_generic,
 	.get_media_type         = &ixgbe_get_media_type_X540,
 	.get_supported_physical_layer =
@@ -669,7 +868,7 @@
 	.enable_rx_dma          = &ixgbe_enable_rx_dma_generic,
 	.get_mac_addr           = &ixgbe_get_mac_addr_generic,
 	.get_san_mac_addr       = &ixgbe_get_san_mac_addr_generic,
-	.get_device_caps        = NULL,
+	.get_device_caps        = &ixgbe_get_device_caps_generic,
 	.get_wwn_prefix         = &ixgbe_get_wwn_prefix_generic,
 	.stop_adapter           = &ixgbe_stop_adapter_generic,
 	.get_bus_info           = &ixgbe_get_bus_info_generic,
@@ -681,8 +880,8 @@
 	.get_link_capabilities  = &ixgbe_get_copper_link_capabilities_generic,
 	.led_on                 = &ixgbe_led_on_generic,
 	.led_off                = &ixgbe_led_off_generic,
-	.blink_led_start        = &ixgbe_blink_led_start_generic,
-	.blink_led_stop         = &ixgbe_blink_led_stop_generic,
+	.blink_led_start        = &ixgbe_blink_led_start_X540,
+	.blink_led_stop         = &ixgbe_blink_led_stop_X540,
 	.set_rar                = &ixgbe_set_rar_generic,
 	.clear_rar              = &ixgbe_clear_rar_generic,
 	.set_vmdq               = &ixgbe_set_vmdq_generic,
@@ -705,9 +904,11 @@
 static struct ixgbe_eeprom_operations eeprom_ops_X540 = {
 	.init_params            = &ixgbe_init_eeprom_params_X540,
 	.read                   = &ixgbe_read_eerd_X540,
+	.read_buffer		= &ixgbe_read_eerd_buffer_X540,
 	.write                  = &ixgbe_write_eewr_X540,
+	.write_buffer		= &ixgbe_write_eewr_buffer_X540,
 	.calc_checksum		= &ixgbe_calc_eeprom_checksum_X540,
-	.validate_checksum      = &ixgbe_validate_eeprom_checksum_generic,
+	.validate_checksum      = &ixgbe_validate_eeprom_checksum_X540,
 	.update_checksum        = &ixgbe_update_eeprom_checksum_X540,
 };
 
diff -druN linux-2.6.39-libre/drivers/net/ixgbevf/ethtool.c linux-3.0-rc7-libre/drivers/net/ixgbevf/ethtool.c
--- linux-2.6.39-libre/drivers/net/ixgbevf/ethtool.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/ixgbevf/ethtool.c	2011-07-11 19:51:52.000000000 -0400
@@ -104,11 +104,13 @@
 	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;
+		ethtool_cmd_speed_set(
+			ecmd,
+			(link_speed == IXGBE_LINK_SPEED_10GB_FULL) ?
+			SPEED_10000 : SPEED_1000);
 		ecmd->duplex = DUPLEX_FULL;
 	} else {
-		ecmd->speed = -1;
+		ethtool_cmd_speed_set(ecmd, -1);
 		ecmd->duplex = -1;
 	}
 
diff -druN linux-2.6.39-libre/drivers/net/ixgbevf/ixgbevf_main.c linux-3.0-rc7-libre/drivers/net/ixgbevf/ixgbevf_main.c
--- linux-2.6.39-libre/drivers/net/ixgbevf/ixgbevf_main.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/ixgbevf/ixgbevf_main.c	2011-07-11 19:51:52.000000000 -0400
@@ -44,6 +44,7 @@
 #include <net/ip6_checksum.h>
 #include <linux/ethtool.h>
 #include <linux/if_vlan.h>
+#include <linux/prefetch.h>
 
 #include "ixgbevf.h"
 
@@ -1460,6 +1461,34 @@
 	}
 }
 
+static int ixgbevf_write_uc_addr_list(struct net_device *netdev)
+{
+	struct ixgbevf_adapter *adapter = netdev_priv(netdev);
+	struct ixgbe_hw *hw = &adapter->hw;
+	int count = 0;
+
+	if ((netdev_uc_count(netdev)) > 10) {
+		printk(KERN_ERR "Too many unicast filters - No Space\n");
+		return -ENOSPC;
+	}
+
+	if (!netdev_uc_empty(netdev)) {
+		struct netdev_hw_addr *ha;
+		netdev_for_each_uc_addr(ha, netdev) {
+			hw->mac.ops.set_uc_addr(hw, ++count, ha->addr);
+			udelay(200);
+		}
+	} else {
+		/*
+		 * If the list is empty then send message to PF driver to
+		 * clear all macvlans on this VF.
+		 */
+		hw->mac.ops.set_uc_addr(hw, 0, NULL);
+	}
+
+	return count;
+}
+
 /**
  * ixgbevf_set_rx_mode - Multicast set
  * @netdev: network interface device structure
@@ -1476,6 +1505,8 @@
 	/* reprogram multicast list */
 	if (hw->mac.ops.update_mc_addr_list)
 		hw->mac.ops.update_mc_addr_list(hw, netdev);
+
+	ixgbevf_write_uc_addr_list(netdev);
 }
 
 static void ixgbevf_napi_enable_all(struct ixgbevf_adapter *adapter)
diff -druN linux-2.6.39-libre/drivers/net/ixgbevf/mbx.h linux-3.0-rc7-libre/drivers/net/ixgbevf/mbx.h
--- linux-2.6.39-libre/drivers/net/ixgbevf/mbx.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/ixgbevf/mbx.h	2011-07-11 19:51:52.000000000 -0400
@@ -81,6 +81,7 @@
 #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 */
+#define IXGBE_VF_SET_MACVLAN      0x06 /* VF requests PF for unicast filter */
 
 /* length of permanent address message returned from PF */
 #define IXGBE_VF_PERMADDR_MSG_LEN 4
diff -druN linux-2.6.39-libre/drivers/net/ixgbevf/vf.c linux-3.0-rc7-libre/drivers/net/ixgbevf/vf.c
--- linux-2.6.39-libre/drivers/net/ixgbevf/vf.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/ixgbevf/vf.c	2011-07-11 19:51:52.000000000 -0400
@@ -216,6 +216,39 @@
 	return 0;
 }
 
+static s32 ixgbevf_set_uc_addr_vf(struct ixgbe_hw *hw, u32 index, u8 *addr)
+{
+	struct ixgbe_mbx_info *mbx = &hw->mbx;
+	u32 msgbuf[3];
+	u8 *msg_addr = (u8 *)(&msgbuf[1]);
+	s32 ret_val;
+
+	memset(msgbuf, 0, sizeof(msgbuf));
+	/*
+	 * If index is one then this is the start of a new list and needs
+	 * indication to the PF so it can do it's own list management.
+	 * If it is zero then that tells the PF to just clear all of
+	 * this VF's macvlans and there is no new list.
+	 */
+	msgbuf[0] |= index << IXGBE_VT_MSGINFO_SHIFT;
+	msgbuf[0] |= IXGBE_VF_SET_MACVLAN;
+	if (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 (!ret_val)
+		if (msgbuf[0] ==
+		    (IXGBE_VF_SET_MACVLAN | IXGBE_VT_MSGTYPE_NACK))
+			ret_val = -ENOMEM;
+
+	return ret_val;
+}
+
 /**
  *  ixgbevf_set_rar_vf - set device MAC address
  *  @hw: pointer to hardware structure
@@ -378,6 +411,7 @@
 	.check_link          = ixgbevf_check_mac_link_vf,
 	.set_rar             = ixgbevf_set_rar_vf,
 	.update_mc_addr_list = ixgbevf_update_mc_addr_list_vf,
+	.set_uc_addr         = ixgbevf_set_uc_addr_vf,
 	.set_vfta            = ixgbevf_set_vfta_vf,
 };
 
diff -druN linux-2.6.39-libre/drivers/net/ixgbevf/vf.h linux-3.0-rc7-libre/drivers/net/ixgbevf/vf.h
--- linux-2.6.39-libre/drivers/net/ixgbevf/vf.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/ixgbevf/vf.h	2011-07-11 19:51:52.000000000 -0400
@@ -62,6 +62,7 @@
 
 	/* RAR, Multicast, VLAN */
 	s32 (*set_rar)(struct ixgbe_hw *, u32, u8 *, u32);
+	s32 (*set_uc_addr)(struct ixgbe_hw *, u32, u8 *);
 	s32 (*init_rx_addrs)(struct ixgbe_hw *);
 	s32 (*update_mc_addr_list)(struct ixgbe_hw *, struct net_device *);
 	s32 (*enable_mc)(struct ixgbe_hw *);
diff -druN linux-2.6.39-libre/drivers/net/jme.c linux-3.0-rc7-libre/drivers/net/jme.c
--- linux-2.6.39-libre/drivers/net/jme.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/jme.c	2011-07-11 19:51:52.000000000 -0400
@@ -2230,17 +2230,9 @@
 		jme_restart_rx_engine(jme);
 	}
 
-	if (new_mtu > 1900) {
-		netdev->features &= ~(NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
-				NETIF_F_TSO | NETIF_F_TSO6);
-	} else {
-		if (test_bit(JME_FLAG_TXCSUM, &jme->flags))
-			netdev->features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;
-		if (test_bit(JME_FLAG_TSO, &jme->flags))
-			netdev->features |= NETIF_F_TSO | NETIF_F_TSO6;
-	}
-
 	netdev->mtu = new_mtu;
+	netdev_update_features(netdev);
+
 	jme_reset_link(jme);
 
 	return 0;
@@ -2563,7 +2555,8 @@
 	struct jme_adapter *jme = netdev_priv(netdev);
 	int rc, fdc = 0;
 
-	if (ecmd->speed == SPEED_1000 && ecmd->autoneg != AUTONEG_ENABLE)
+	if (ethtool_cmd_speed(ecmd) == SPEED_1000
+	    && ecmd->autoneg != AUTONEG_ENABLE)
 		return -EINVAL;
 
 	/*
@@ -2640,19 +2633,20 @@
 }
 
 static u32
-jme_get_rx_csum(struct net_device *netdev)
+jme_fix_features(struct net_device *netdev, u32 features)
 {
-	struct jme_adapter *jme = netdev_priv(netdev);
-	return jme->reg_rxmcs & RXMCS_CHECKSUM;
+	if (netdev->mtu > 1900)
+		features &= ~(NETIF_F_ALL_TSO | NETIF_F_ALL_CSUM);
+	return features;
 }
 
 static int
-jme_set_rx_csum(struct net_device *netdev, u32 on)
+jme_set_features(struct net_device *netdev, u32 features)
 {
 	struct jme_adapter *jme = netdev_priv(netdev);
 
 	spin_lock_bh(&jme->rxmcs_lock);
-	if (on)
+	if (features & NETIF_F_RXCSUM)
 		jme->reg_rxmcs |= RXMCS_CHECKSUM;
 	else
 		jme->reg_rxmcs &= ~RXMCS_CHECKSUM;
@@ -2663,42 +2657,6 @@
 }
 
 static int
-jme_set_tx_csum(struct net_device *netdev, u32 on)
-{
-	struct jme_adapter *jme = netdev_priv(netdev);
-
-	if (on) {
-		set_bit(JME_FLAG_TXCSUM, &jme->flags);
-		if (netdev->mtu <= 1900)
-			netdev->features |=
-				NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;
-	} else {
-		clear_bit(JME_FLAG_TXCSUM, &jme->flags);
-		netdev->features &=
-				~(NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM);
-	}
-
-	return 0;
-}
-
-static int
-jme_set_tso(struct net_device *netdev, u32 on)
-{
-	struct jme_adapter *jme = netdev_priv(netdev);
-
-	if (on) {
-		set_bit(JME_FLAG_TSO, &jme->flags);
-		if (netdev->mtu <= 1900)
-			netdev->features |= NETIF_F_TSO | NETIF_F_TSO6;
-	} else {
-		clear_bit(JME_FLAG_TSO, &jme->flags);
-		netdev->features &= ~(NETIF_F_TSO | NETIF_F_TSO6);
-	}
-
-	return 0;
-}
-
-static int
 jme_nway_reset(struct net_device *netdev)
 {
 	struct jme_adapter *jme = netdev_priv(netdev);
@@ -2839,11 +2797,6 @@
 	.get_link		= jme_get_link,
 	.get_msglevel           = jme_get_msglevel,
 	.set_msglevel           = jme_set_msglevel,
-	.get_rx_csum		= jme_get_rx_csum,
-	.set_rx_csum		= jme_set_rx_csum,
-	.set_tx_csum		= jme_set_tx_csum,
-	.set_tso		= jme_set_tso,
-	.set_sg			= ethtool_op_set_sg,
 	.nway_reset             = jme_nway_reset,
 	.get_eeprom_len		= jme_get_eeprom_len,
 	.get_eeprom		= jme_get_eeprom,
@@ -2903,6 +2856,8 @@
 	.ndo_change_mtu		= jme_change_mtu,
 	.ndo_tx_timeout		= jme_tx_timeout,
 	.ndo_vlan_rx_register	= jme_vlan_rx_register,
+	.ndo_fix_features       = jme_fix_features,
+	.ndo_set_features       = jme_set_features,
 };
 
 static int __devinit
@@ -2957,6 +2912,12 @@
 	netdev->netdev_ops = &jme_netdev_ops;
 	netdev->ethtool_ops		= &jme_ethtool_ops;
 	netdev->watchdog_timeo		= TX_TIMEOUT;
+	netdev->hw_features		=	NETIF_F_IP_CSUM |
+						NETIF_F_IPV6_CSUM |
+						NETIF_F_SG |
+						NETIF_F_TSO |
+						NETIF_F_TSO6 |
+						NETIF_F_RXCSUM;
 	netdev->features		=	NETIF_F_IP_CSUM |
 						NETIF_F_IPV6_CSUM |
 						NETIF_F_SG |
@@ -3040,8 +3001,9 @@
 	jme->reg_txpfc = 0;
 	jme->reg_pmcs = PMCS_MFEN;
 	jme->reg_gpreg1 = GPREG1_DEFAULT;
-	set_bit(JME_FLAG_TXCSUM, &jme->flags);
-	set_bit(JME_FLAG_TSO, &jme->flags);
+
+	if (jme->reg_rxmcs & RXMCS_CHECKSUM)
+		netdev->features |= NETIF_F_RXCSUM;
 
 	/*
 	 * Get Max Read Req Size from PCI Config Space
diff -druN linux-2.6.39-libre/drivers/net/jme.h linux-3.0-rc7-libre/drivers/net/jme.h
--- linux-2.6.39-libre/drivers/net/jme.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/jme.h	2011-07-11 19:51:52.000000000 -0400
@@ -468,8 +468,6 @@
 enum jme_flags_bits {
 	JME_FLAG_MSI		= 1,
 	JME_FLAG_SSET		= 2,
-	JME_FLAG_TXCSUM		= 3,
-	JME_FLAG_TSO		= 4,
 	JME_FLAG_POLL		= 5,
 	JME_FLAG_SHUTDOWN	= 6,
 };
diff -druN linux-2.6.39-libre/drivers/net/Kconfig linux-3.0-rc7-libre/drivers/net/Kconfig
--- linux-2.6.39-libre/drivers/net/Kconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/Kconfig	2011-07-11 19:51:52.000000000 -0400
@@ -2017,6 +2017,13 @@
 	  from Faraday. It is used on Faraday A320, Andes AG101 and some
 	  other ARM/NDS32 SoC's.
 
+config LANTIQ_ETOP
+	tristate "Lantiq SoC ETOP driver"
+	depends on SOC_TYPE_XWAY
+	help
+	  Support for the MII0 inside the Lantiq SoC
+
+
 source "drivers/net/fs_enet/Kconfig"
 
 source "drivers/net/octeon/Kconfig"
@@ -3409,7 +3416,8 @@
 
 config NETCONSOLE_DYNAMIC
 	bool "Dynamic reconfiguration of logging targets"
-	depends on NETCONSOLE && SYSFS && CONFIGFS_FS
+	depends on NETCONSOLE && SYSFS && CONFIGFS_FS && \
+			!(NETCONSOLE=y && CONFIGFS_FS=m)
 	help
 	  This option enables the ability to dynamically reconfigure target
 	  parameters (interface, IP addresses, port numbers, MAC addresses)
diff -druN linux-2.6.39-libre/drivers/net/ks8842.c linux-3.0-rc7-libre/drivers/net/ks8842.c
--- linux-2.6.39-libre/drivers/net/ks8842.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/ks8842.c	2011-07-11 19:51:52.000000000 -0400
@@ -26,7 +26,6 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/platform_device.h>
-#include <linux/mfd/core.h>
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
 #include <linux/ethtool.h>
@@ -662,7 +661,7 @@
 
 	/* check the status */
 	if ((status & RXSR_VALID) && !(status & RXSR_ERROR)) {
-		struct sk_buff *skb = netdev_alloc_skb_ip_align(netdev, len);
+		struct sk_buff *skb = netdev_alloc_skb_ip_align(netdev, len + 3);
 
 		if (skb) {
 
@@ -1146,7 +1145,7 @@
 	struct resource *iomem;
 	struct net_device *netdev;
 	struct ks8842_adapter *adapter;
-	struct ks8842_platform_data *pdata = mfd_get_data(pdev);
+	struct ks8842_platform_data *pdata = pdev->dev.platform_data;
 	u16 id;
 	unsigned i;
 
diff -druN linux-2.6.39-libre/drivers/net/ksz884x.c linux-3.0-rc7-libre/drivers/net/ksz884x.c
--- linux-2.6.39-libre/drivers/net/ksz884x.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/ksz884x.c	2011-07-11 19:51:52.000000000 -0400
@@ -1221,7 +1221,6 @@
 #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)
 
@@ -3748,7 +3747,6 @@
 		if (1 == rc)
 			hw->features |= HALF_DUPLEX_SIGNAL_BUG;
 	}
-	hw->features |= IPV6_CSUM_GEN_HACK;
 	return rc;
 }
 
@@ -4887,8 +4885,7 @@
 	left = hw_alloc_pkt(hw, skb->len, num);
 	if (left) {
 		if (left < num ||
-				((hw->features & IPV6_CSUM_GEN_HACK) &&
-				(CHECKSUM_PARTIAL == skb->ip_summed) &&
+				((CHECKSUM_PARTIAL == skb->ip_summed) &&
 				(ETH_P_IPV6 == htons(skb->protocol)))) {
 			struct sk_buff *org_skb = skb;
 
@@ -6001,6 +5998,7 @@
 	struct dev_priv *priv = netdev_priv(dev);
 	struct dev_info *hw_priv = priv->adapter;
 	struct ksz_port *port = &priv->port;
+	u32 speed = ethtool_cmd_speed(cmd);
 	int rc;
 
 	/*
@@ -6009,11 +6007,11 @@
 	 */
 	if (cmd->autoneg && priv->advertising == cmd->advertising) {
 		cmd->advertising |= ADVERTISED_ALL;
-		if (10 == cmd->speed)
+		if (10 == speed)
 			cmd->advertising &=
 				~(ADVERTISED_100baseT_Full |
 				ADVERTISED_100baseT_Half);
-		else if (100 == cmd->speed)
+		else if (100 == speed)
 			cmd->advertising &=
 				~(ADVERTISED_10baseT_Full |
 				ADVERTISED_10baseT_Half);
@@ -6035,8 +6033,8 @@
 		port->force_link = 0;
 	} else {
 		port->duplex = cmd->duplex + 1;
-		if (cmd->speed != 1000)
-			port->speed = cmd->speed;
+		if (1000 != speed)
+			port->speed = speed;
 		if (cmd->autoneg)
 			port->force_link = 0;
 		else
@@ -6583,57 +6581,33 @@
 }
 
 /**
- * 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
+ * netdev_set_features - set receive checksum support
  * @dev:	Network device.
- * @data:	Zero to disable receive checksum support.
+ * @features:	New device features (offloads).
  *
  * 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)
+static int netdev_set_features(struct net_device *dev, u32 features)
 {
 	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);
-	}
+
+	/* see note in hw_setup() */
+	if (features & NETIF_F_RXCSUM)
+		hw->rx_cfg |= DMA_RX_CSUM_TCP | DMA_RX_CSUM_IP;
+	else
+		hw->rx_cfg &= ~(DMA_RX_CSUM_TCP | DMA_RX_CSUM_IP);
+
+	if (hw->enabled)
+		writel(hw->rx_cfg, hw->io + KS_DMA_RX_CTRL);
+
 	mutex_unlock(&hw_priv->lock);
+
 	return 0;
 }
 
@@ -6658,12 +6632,6 @@
 	.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,
 };
 
 /*
@@ -6828,14 +6796,15 @@
 	/* 500 ms timeout */
 	dev->watchdog_timeo = HZ / 2;
 
-	dev->features |= NETIF_F_IP_CSUM;
+	dev->hw_features = NETIF_F_IP_CSUM | NETIF_F_SG | NETIF_F_RXCSUM;
 
 	/*
 	 * Hardware does not really support IPv6 checksum generation, but
-	 * driver actually runs faster with this on.  Refer IPV6_CSUM_GEN_HACK.
+	 * driver actually runs faster with this on.
 	 */
-	dev->features |= NETIF_F_IPV6_CSUM;
-	dev->features |= NETIF_F_SG;
+	dev->hw_features |= NETIF_F_IPV6_CSUM;
+
+	dev->features |= dev->hw_features;
 
 	sema_init(&priv->proc_sem, 1);
 
@@ -6860,6 +6829,7 @@
 	.ndo_start_xmit		= netdev_tx,
 	.ndo_tx_timeout		= netdev_tx_timeout,
 	.ndo_change_mtu		= netdev_change_mtu,
+	.ndo_set_features	= netdev_set_features,
 	.ndo_set_mac_address	= netdev_set_mac_address,
 	.ndo_validate_addr	= eth_validate_addr,
 	.ndo_do_ioctl		= netdev_ioctl,
diff -druN linux-2.6.39-libre/drivers/net/lantiq_etop.c linux-3.0-rc7-libre/drivers/net/lantiq_etop.c
--- linux-2.6.39-libre/drivers/net/lantiq_etop.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/net/lantiq_etop.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,805 @@
+/*
+ *   This program is free software; you can redistribute it and/or modify it
+ *   under the terms of the GNU General Public License version 2 as published
+ *   by the Free Software Foundation.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+ *
+ *   Copyright (C) 2011 John Crispin <blogic@openwrt.org>
+ */
+
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/errno.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/uaccess.h>
+#include <linux/in.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/phy.h>
+#include <linux/ip.h>
+#include <linux/tcp.h>
+#include <linux/skbuff.h>
+#include <linux/mm.h>
+#include <linux/platform_device.h>
+#include <linux/ethtool.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+
+#include <asm/checksum.h>
+
+#include <lantiq_soc.h>
+#include <xway_dma.h>
+#include <lantiq_platform.h>
+
+#define LTQ_ETOP_MDIO		0x11804
+#define MDIO_REQUEST		0x80000000
+#define MDIO_READ		0x40000000
+#define MDIO_ADDR_MASK		0x1f
+#define MDIO_ADDR_OFFSET	0x15
+#define MDIO_REG_MASK		0x1f
+#define MDIO_REG_OFFSET		0x10
+#define MDIO_VAL_MASK		0xffff
+
+#define PPE32_CGEN		0x800
+#define LQ_PPE32_ENET_MAC_CFG	0x1840
+
+#define LTQ_ETOP_ENETS0		0x11850
+#define LTQ_ETOP_MAC_DA0	0x1186C
+#define LTQ_ETOP_MAC_DA1	0x11870
+#define LTQ_ETOP_CFG		0x16020
+#define LTQ_ETOP_IGPLEN		0x16080
+
+#define MAX_DMA_CHAN		0x8
+#define MAX_DMA_CRC_LEN		0x4
+#define MAX_DMA_DATA_LEN	0x600
+
+#define ETOP_FTCU		BIT(28)
+#define ETOP_MII_MASK		0xf
+#define ETOP_MII_NORMAL		0xd
+#define ETOP_MII_REVERSE	0xe
+#define ETOP_PLEN_UNDER		0x40
+#define ETOP_CGEN		0x800
+
+/* use 2 static channels for TX/RX */
+#define LTQ_ETOP_TX_CHANNEL	1
+#define LTQ_ETOP_RX_CHANNEL	6
+#define IS_TX(x)		(x == LTQ_ETOP_TX_CHANNEL)
+#define IS_RX(x)		(x == LTQ_ETOP_RX_CHANNEL)
+
+#define ltq_etop_r32(x)		ltq_r32(ltq_etop_membase + (x))
+#define ltq_etop_w32(x, y)	ltq_w32(x, ltq_etop_membase + (y))
+#define ltq_etop_w32_mask(x, y, z)	\
+		ltq_w32_mask(x, y, ltq_etop_membase + (z))
+
+#define DRV_VERSION	"1.0"
+
+static void __iomem *ltq_etop_membase;
+
+struct ltq_etop_chan {
+	int idx;
+	int tx_free;
+	struct net_device *netdev;
+	struct napi_struct napi;
+	struct ltq_dma_channel dma;
+	struct sk_buff *skb[LTQ_DESC_NUM];
+};
+
+struct ltq_etop_priv {
+	struct net_device *netdev;
+	struct ltq_eth_data *pldata;
+	struct resource *res;
+
+	struct mii_bus *mii_bus;
+	struct phy_device *phydev;
+
+	struct ltq_etop_chan ch[MAX_DMA_CHAN];
+	int tx_free[MAX_DMA_CHAN >> 1];
+
+	spinlock_t lock;
+};
+
+static int
+ltq_etop_alloc_skb(struct ltq_etop_chan *ch)
+{
+	ch->skb[ch->dma.desc] = dev_alloc_skb(MAX_DMA_DATA_LEN);
+	if (!ch->skb[ch->dma.desc])
+		return -ENOMEM;
+	ch->dma.desc_base[ch->dma.desc].addr = dma_map_single(NULL,
+		ch->skb[ch->dma.desc]->data, MAX_DMA_DATA_LEN,
+		DMA_FROM_DEVICE);
+	ch->dma.desc_base[ch->dma.desc].addr =
+		CPHYSADDR(ch->skb[ch->dma.desc]->data);
+	ch->dma.desc_base[ch->dma.desc].ctl =
+		LTQ_DMA_OWN | LTQ_DMA_RX_OFFSET(NET_IP_ALIGN) |
+		MAX_DMA_DATA_LEN;
+	skb_reserve(ch->skb[ch->dma.desc], NET_IP_ALIGN);
+	return 0;
+}
+
+static void
+ltq_etop_hw_receive(struct ltq_etop_chan *ch)
+{
+	struct ltq_etop_priv *priv = netdev_priv(ch->netdev);
+	struct ltq_dma_desc *desc = &ch->dma.desc_base[ch->dma.desc];
+	struct sk_buff *skb = ch->skb[ch->dma.desc];
+	int len = (desc->ctl & LTQ_DMA_SIZE_MASK) - MAX_DMA_CRC_LEN;
+	unsigned long flags;
+
+	spin_lock_irqsave(&priv->lock, flags);
+	if (ltq_etop_alloc_skb(ch)) {
+		netdev_err(ch->netdev,
+			"failed to allocate new rx buffer, stopping DMA\n");
+		ltq_dma_close(&ch->dma);
+	}
+	ch->dma.desc++;
+	ch->dma.desc %= LTQ_DESC_NUM;
+	spin_unlock_irqrestore(&priv->lock, flags);
+
+	skb_put(skb, len);
+	skb->dev = ch->netdev;
+	skb->protocol = eth_type_trans(skb, ch->netdev);
+	netif_receive_skb(skb);
+}
+
+static int
+ltq_etop_poll_rx(struct napi_struct *napi, int budget)
+{
+	struct ltq_etop_chan *ch = container_of(napi,
+				struct ltq_etop_chan, napi);
+	int rx = 0;
+	int complete = 0;
+
+	while ((rx < budget) && !complete) {
+		struct ltq_dma_desc *desc = &ch->dma.desc_base[ch->dma.desc];
+
+		if ((desc->ctl & (LTQ_DMA_OWN | LTQ_DMA_C)) == LTQ_DMA_C) {
+			ltq_etop_hw_receive(ch);
+			rx++;
+		} else {
+			complete = 1;
+		}
+	}
+	if (complete || !rx) {
+		napi_complete(&ch->napi);
+		ltq_dma_ack_irq(&ch->dma);
+	}
+	return rx;
+}
+
+static int
+ltq_etop_poll_tx(struct napi_struct *napi, int budget)
+{
+	struct ltq_etop_chan *ch =
+		container_of(napi, struct ltq_etop_chan, napi);
+	struct ltq_etop_priv *priv = netdev_priv(ch->netdev);
+	struct netdev_queue *txq =
+		netdev_get_tx_queue(ch->netdev, ch->idx >> 1);
+	unsigned long flags;
+
+	spin_lock_irqsave(&priv->lock, flags);
+	while ((ch->dma.desc_base[ch->tx_free].ctl &
+			(LTQ_DMA_OWN | LTQ_DMA_C)) == LTQ_DMA_C) {
+		dev_kfree_skb_any(ch->skb[ch->tx_free]);
+		ch->skb[ch->tx_free] = NULL;
+		memset(&ch->dma.desc_base[ch->tx_free], 0,
+			sizeof(struct ltq_dma_desc));
+		ch->tx_free++;
+		ch->tx_free %= LTQ_DESC_NUM;
+	}
+	spin_unlock_irqrestore(&priv->lock, flags);
+
+	if (netif_tx_queue_stopped(txq))
+		netif_tx_start_queue(txq);
+	napi_complete(&ch->napi);
+	ltq_dma_ack_irq(&ch->dma);
+	return 1;
+}
+
+static irqreturn_t
+ltq_etop_dma_irq(int irq, void *_priv)
+{
+	struct ltq_etop_priv *priv = _priv;
+	int ch = irq - LTQ_DMA_CH0_INT;
+
+	napi_schedule(&priv->ch[ch].napi);
+	return IRQ_HANDLED;
+}
+
+static void
+ltq_etop_free_channel(struct net_device *dev, struct ltq_etop_chan *ch)
+{
+	struct ltq_etop_priv *priv = netdev_priv(dev);
+
+	ltq_dma_free(&ch->dma);
+	if (ch->dma.irq)
+		free_irq(ch->dma.irq, priv);
+	if (IS_RX(ch->idx)) {
+		int desc;
+		for (desc = 0; desc < LTQ_DESC_NUM; desc++)
+			dev_kfree_skb_any(ch->skb[ch->dma.desc]);
+	}
+}
+
+static void
+ltq_etop_hw_exit(struct net_device *dev)
+{
+	struct ltq_etop_priv *priv = netdev_priv(dev);
+	int i;
+
+	ltq_pmu_disable(PMU_PPE);
+	for (i = 0; i < MAX_DMA_CHAN; i++)
+		if (IS_TX(i) || IS_RX(i))
+			ltq_etop_free_channel(dev, &priv->ch[i]);
+}
+
+static int
+ltq_etop_hw_init(struct net_device *dev)
+{
+	struct ltq_etop_priv *priv = netdev_priv(dev);
+	int i;
+
+	ltq_pmu_enable(PMU_PPE);
+
+	switch (priv->pldata->mii_mode) {
+	case PHY_INTERFACE_MODE_RMII:
+		ltq_etop_w32_mask(ETOP_MII_MASK,
+			ETOP_MII_REVERSE, LTQ_ETOP_CFG);
+		break;
+
+	case PHY_INTERFACE_MODE_MII:
+		ltq_etop_w32_mask(ETOP_MII_MASK,
+			ETOP_MII_NORMAL, LTQ_ETOP_CFG);
+		break;
+
+	default:
+		netdev_err(dev, "unknown mii mode %d\n",
+			priv->pldata->mii_mode);
+		return -ENOTSUPP;
+	}
+
+	/* enable crc generation */
+	ltq_etop_w32(PPE32_CGEN, LQ_PPE32_ENET_MAC_CFG);
+
+	ltq_dma_init_port(DMA_PORT_ETOP);
+
+	for (i = 0; i < MAX_DMA_CHAN; i++) {
+		int irq = LTQ_DMA_CH0_INT + i;
+		struct ltq_etop_chan *ch = &priv->ch[i];
+
+		ch->idx = ch->dma.nr = i;
+
+		if (IS_TX(i)) {
+			ltq_dma_alloc_tx(&ch->dma);
+			request_irq(irq, ltq_etop_dma_irq, IRQF_DISABLED,
+				"etop_tx", priv);
+		} else if (IS_RX(i)) {
+			ltq_dma_alloc_rx(&ch->dma);
+			for (ch->dma.desc = 0; ch->dma.desc < LTQ_DESC_NUM;
+					ch->dma.desc++)
+				if (ltq_etop_alloc_skb(ch))
+					return -ENOMEM;
+			ch->dma.desc = 0;
+			request_irq(irq, ltq_etop_dma_irq, IRQF_DISABLED,
+				"etop_rx", priv);
+		}
+		ch->dma.irq = irq;
+	}
+	return 0;
+}
+
+static void
+ltq_etop_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
+{
+	strcpy(info->driver, "Lantiq ETOP");
+	strcpy(info->bus_info, "internal");
+	strcpy(info->version, DRV_VERSION);
+}
+
+static int
+ltq_etop_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
+{
+	struct ltq_etop_priv *priv = netdev_priv(dev);
+
+	return phy_ethtool_gset(priv->phydev, cmd);
+}
+
+static int
+ltq_etop_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
+{
+	struct ltq_etop_priv *priv = netdev_priv(dev);
+
+	return phy_ethtool_sset(priv->phydev, cmd);
+}
+
+static int
+ltq_etop_nway_reset(struct net_device *dev)
+{
+	struct ltq_etop_priv *priv = netdev_priv(dev);
+
+	return phy_start_aneg(priv->phydev);
+}
+
+static const struct ethtool_ops ltq_etop_ethtool_ops = {
+	.get_drvinfo = ltq_etop_get_drvinfo,
+	.get_settings = ltq_etop_get_settings,
+	.set_settings = ltq_etop_set_settings,
+	.nway_reset = ltq_etop_nway_reset,
+};
+
+static int
+ltq_etop_mdio_wr(struct mii_bus *bus, int phy_addr, int phy_reg, u16 phy_data)
+{
+	u32 val = MDIO_REQUEST |
+		((phy_addr & MDIO_ADDR_MASK) << MDIO_ADDR_OFFSET) |
+		((phy_reg & MDIO_REG_MASK) << MDIO_REG_OFFSET) |
+		phy_data;
+
+	while (ltq_etop_r32(LTQ_ETOP_MDIO) & MDIO_REQUEST)
+		;
+	ltq_etop_w32(val, LTQ_ETOP_MDIO);
+	return 0;
+}
+
+static int
+ltq_etop_mdio_rd(struct mii_bus *bus, int phy_addr, int phy_reg)
+{
+	u32 val = MDIO_REQUEST | MDIO_READ |
+		((phy_addr & MDIO_ADDR_MASK) << MDIO_ADDR_OFFSET) |
+		((phy_reg & MDIO_REG_MASK) << MDIO_REG_OFFSET);
+
+	while (ltq_etop_r32(LTQ_ETOP_MDIO) & MDIO_REQUEST)
+		;
+	ltq_etop_w32(val, LTQ_ETOP_MDIO);
+	while (ltq_etop_r32(LTQ_ETOP_MDIO) & MDIO_REQUEST)
+		;
+	val = ltq_etop_r32(LTQ_ETOP_MDIO) & MDIO_VAL_MASK;
+	return val;
+}
+
+static void
+ltq_etop_mdio_link(struct net_device *dev)
+{
+	/* nothing to do  */
+}
+
+static int
+ltq_etop_mdio_probe(struct net_device *dev)
+{
+	struct ltq_etop_priv *priv = netdev_priv(dev);
+	struct phy_device *phydev = NULL;
+	int phy_addr;
+
+	for (phy_addr = 0; phy_addr < PHY_MAX_ADDR; phy_addr++) {
+		if (priv->mii_bus->phy_map[phy_addr]) {
+			phydev = priv->mii_bus->phy_map[phy_addr];
+			break;
+		}
+	}
+
+	if (!phydev) {
+		netdev_err(dev, "no PHY found\n");
+		return -ENODEV;
+	}
+
+	phydev = phy_connect(dev, dev_name(&phydev->dev), &ltq_etop_mdio_link,
+			0, priv->pldata->mii_mode);
+
+	if (IS_ERR(phydev)) {
+		netdev_err(dev, "Could not attach to PHY\n");
+		return PTR_ERR(phydev);
+	}
+
+	phydev->supported &= (SUPPORTED_10baseT_Half
+			      | SUPPORTED_10baseT_Full
+			      | SUPPORTED_100baseT_Half
+			      | SUPPORTED_100baseT_Full
+			      | SUPPORTED_Autoneg
+			      | SUPPORTED_MII
+			      | SUPPORTED_TP);
+
+	phydev->advertising = phydev->supported;
+	priv->phydev = phydev;
+	pr_info("%s: attached PHY [%s] (phy_addr=%s, irq=%d)\n",
+	       dev->name, phydev->drv->name,
+	       dev_name(&phydev->dev), phydev->irq);
+
+	return 0;
+}
+
+static int
+ltq_etop_mdio_init(struct net_device *dev)
+{
+	struct ltq_etop_priv *priv = netdev_priv(dev);
+	int i;
+	int err;
+
+	priv->mii_bus = mdiobus_alloc();
+	if (!priv->mii_bus) {
+		netdev_err(dev, "failed to allocate mii bus\n");
+		err = -ENOMEM;
+		goto err_out;
+	}
+
+	priv->mii_bus->priv = dev;
+	priv->mii_bus->read = ltq_etop_mdio_rd;
+	priv->mii_bus->write = ltq_etop_mdio_wr;
+	priv->mii_bus->name = "ltq_mii";
+	snprintf(priv->mii_bus->id, MII_BUS_ID_SIZE, "%x", 0);
+	priv->mii_bus->irq = kmalloc(sizeof(int) * PHY_MAX_ADDR, GFP_KERNEL);
+	if (!priv->mii_bus->irq) {
+		err = -ENOMEM;
+		goto err_out_free_mdiobus;
+	}
+
+	for (i = 0; i < PHY_MAX_ADDR; ++i)
+		priv->mii_bus->irq[i] = PHY_POLL;
+
+	if (mdiobus_register(priv->mii_bus)) {
+		err = -ENXIO;
+		goto err_out_free_mdio_irq;
+	}
+
+	if (ltq_etop_mdio_probe(dev)) {
+		err = -ENXIO;
+		goto err_out_unregister_bus;
+	}
+	return 0;
+
+err_out_unregister_bus:
+	mdiobus_unregister(priv->mii_bus);
+err_out_free_mdio_irq:
+	kfree(priv->mii_bus->irq);
+err_out_free_mdiobus:
+	mdiobus_free(priv->mii_bus);
+err_out:
+	return err;
+}
+
+static void
+ltq_etop_mdio_cleanup(struct net_device *dev)
+{
+	struct ltq_etop_priv *priv = netdev_priv(dev);
+
+	phy_disconnect(priv->phydev);
+	mdiobus_unregister(priv->mii_bus);
+	kfree(priv->mii_bus->irq);
+	mdiobus_free(priv->mii_bus);
+}
+
+static int
+ltq_etop_open(struct net_device *dev)
+{
+	struct ltq_etop_priv *priv = netdev_priv(dev);
+	int i;
+
+	for (i = 0; i < MAX_DMA_CHAN; i++) {
+		struct ltq_etop_chan *ch = &priv->ch[i];
+
+		if (!IS_TX(i) && (!IS_RX(i)))
+			continue;
+		ltq_dma_open(&ch->dma);
+		napi_enable(&ch->napi);
+	}
+	phy_start(priv->phydev);
+	netif_tx_start_all_queues(dev);
+	return 0;
+}
+
+static int
+ltq_etop_stop(struct net_device *dev)
+{
+	struct ltq_etop_priv *priv = netdev_priv(dev);
+	int i;
+
+	netif_tx_stop_all_queues(dev);
+	phy_stop(priv->phydev);
+	for (i = 0; i < MAX_DMA_CHAN; i++) {
+		struct ltq_etop_chan *ch = &priv->ch[i];
+
+		if (!IS_RX(i) && !IS_TX(i))
+			continue;
+		napi_disable(&ch->napi);
+		ltq_dma_close(&ch->dma);
+	}
+	return 0;
+}
+
+static int
+ltq_etop_tx(struct sk_buff *skb, struct net_device *dev)
+{
+	int queue = skb_get_queue_mapping(skb);
+	struct netdev_queue *txq = netdev_get_tx_queue(dev, queue);
+	struct ltq_etop_priv *priv = netdev_priv(dev);
+	struct ltq_etop_chan *ch = &priv->ch[(queue << 1) | 1];
+	struct ltq_dma_desc *desc = &ch->dma.desc_base[ch->dma.desc];
+	int len;
+	unsigned long flags;
+	u32 byte_offset;
+
+	len = skb->len < ETH_ZLEN ? ETH_ZLEN : skb->len;
+
+	if ((desc->ctl & (LTQ_DMA_OWN | LTQ_DMA_C)) || ch->skb[ch->dma.desc]) {
+		dev_kfree_skb_any(skb);
+		netdev_err(dev, "tx ring full\n");
+		netif_tx_stop_queue(txq);
+		return NETDEV_TX_BUSY;
+	}
+
+	/* dma needs to start on a 16 byte aligned address */
+	byte_offset = CPHYSADDR(skb->data) % 16;
+	ch->skb[ch->dma.desc] = skb;
+
+	dev->trans_start = jiffies;
+
+	spin_lock_irqsave(&priv->lock, flags);
+	desc->addr = ((unsigned int) dma_map_single(NULL, skb->data, len,
+						DMA_TO_DEVICE)) - byte_offset;
+	wmb();
+	desc->ctl = LTQ_DMA_OWN | LTQ_DMA_SOP | LTQ_DMA_EOP |
+		LTQ_DMA_TX_OFFSET(byte_offset) | (len & LTQ_DMA_SIZE_MASK);
+	ch->dma.desc++;
+	ch->dma.desc %= LTQ_DESC_NUM;
+	spin_unlock_irqrestore(&priv->lock, flags);
+
+	if (ch->dma.desc_base[ch->dma.desc].ctl & LTQ_DMA_OWN)
+		netif_tx_stop_queue(txq);
+
+	return NETDEV_TX_OK;
+}
+
+static int
+ltq_etop_change_mtu(struct net_device *dev, int new_mtu)
+{
+	int ret = eth_change_mtu(dev, new_mtu);
+
+	if (!ret) {
+		struct ltq_etop_priv *priv = netdev_priv(dev);
+		unsigned long flags;
+
+		spin_lock_irqsave(&priv->lock, flags);
+		ltq_etop_w32((ETOP_PLEN_UNDER << 16) | new_mtu,
+			LTQ_ETOP_IGPLEN);
+		spin_unlock_irqrestore(&priv->lock, flags);
+	}
+	return ret;
+}
+
+static int
+ltq_etop_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
+{
+	struct ltq_etop_priv *priv = netdev_priv(dev);
+
+	/* TODO: mii-toll reports "No MII transceiver present!." ?!*/
+	return phy_mii_ioctl(priv->phydev, rq, cmd);
+}
+
+static int
+ltq_etop_set_mac_address(struct net_device *dev, void *p)
+{
+	int ret = eth_mac_addr(dev, p);
+
+	if (!ret) {
+		struct ltq_etop_priv *priv = netdev_priv(dev);
+		unsigned long flags;
+
+		/* store the mac for the unicast filter */
+		spin_lock_irqsave(&priv->lock, flags);
+		ltq_etop_w32(*((u32 *)dev->dev_addr), LTQ_ETOP_MAC_DA0);
+		ltq_etop_w32(*((u16 *)&dev->dev_addr[4]) << 16,
+			LTQ_ETOP_MAC_DA1);
+		spin_unlock_irqrestore(&priv->lock, flags);
+	}
+	return ret;
+}
+
+static void
+ltq_etop_set_multicast_list(struct net_device *dev)
+{
+	struct ltq_etop_priv *priv = netdev_priv(dev);
+	unsigned long flags;
+
+	/* ensure that the unicast filter is not enabled in promiscious mode */
+	spin_lock_irqsave(&priv->lock, flags);
+	if ((dev->flags & IFF_PROMISC) || (dev->flags & IFF_ALLMULTI))
+		ltq_etop_w32_mask(ETOP_FTCU, 0, LTQ_ETOP_ENETS0);
+	else
+		ltq_etop_w32_mask(0, ETOP_FTCU, LTQ_ETOP_ENETS0);
+	spin_unlock_irqrestore(&priv->lock, flags);
+}
+
+static u16
+ltq_etop_select_queue(struct net_device *dev, struct sk_buff *skb)
+{
+	/* we are currently only using the first queue */
+	return 0;
+}
+
+static int
+ltq_etop_init(struct net_device *dev)
+{
+	struct ltq_etop_priv *priv = netdev_priv(dev);
+	struct sockaddr mac;
+	int err;
+
+	ether_setup(dev);
+	dev->watchdog_timeo = 10 * HZ;
+	err = ltq_etop_hw_init(dev);
+	if (err)
+		goto err_hw;
+	ltq_etop_change_mtu(dev, 1500);
+
+	memcpy(&mac, &priv->pldata->mac, sizeof(struct sockaddr));
+	if (!is_valid_ether_addr(mac.sa_data)) {
+		pr_warn("etop: invalid MAC, using random\n");
+		random_ether_addr(mac.sa_data);
+	}
+
+	err = ltq_etop_set_mac_address(dev, &mac);
+	if (err)
+		goto err_netdev;
+	ltq_etop_set_multicast_list(dev);
+	err = ltq_etop_mdio_init(dev);
+	if (err)
+		goto err_netdev;
+	return 0;
+
+err_netdev:
+	unregister_netdev(dev);
+	free_netdev(dev);
+err_hw:
+	ltq_etop_hw_exit(dev);
+	return err;
+}
+
+static void
+ltq_etop_tx_timeout(struct net_device *dev)
+{
+	int err;
+
+	ltq_etop_hw_exit(dev);
+	err = ltq_etop_hw_init(dev);
+	if (err)
+		goto err_hw;
+	dev->trans_start = jiffies;
+	netif_wake_queue(dev);
+	return;
+
+err_hw:
+	ltq_etop_hw_exit(dev);
+	netdev_err(dev, "failed to restart etop after TX timeout\n");
+}
+
+static const struct net_device_ops ltq_eth_netdev_ops = {
+	.ndo_open = ltq_etop_open,
+	.ndo_stop = ltq_etop_stop,
+	.ndo_start_xmit = ltq_etop_tx,
+	.ndo_change_mtu = ltq_etop_change_mtu,
+	.ndo_do_ioctl = ltq_etop_ioctl,
+	.ndo_set_mac_address = ltq_etop_set_mac_address,
+	.ndo_validate_addr = eth_validate_addr,
+	.ndo_set_multicast_list = ltq_etop_set_multicast_list,
+	.ndo_select_queue = ltq_etop_select_queue,
+	.ndo_init = ltq_etop_init,
+	.ndo_tx_timeout = ltq_etop_tx_timeout,
+};
+
+static int __init
+ltq_etop_probe(struct platform_device *pdev)
+{
+	struct net_device *dev;
+	struct ltq_etop_priv *priv;
+	struct resource *res;
+	int err;
+	int i;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res) {
+		dev_err(&pdev->dev, "failed to get etop resource\n");
+		err = -ENOENT;
+		goto err_out;
+	}
+
+	res = devm_request_mem_region(&pdev->dev, res->start,
+		resource_size(res), dev_name(&pdev->dev));
+	if (!res) {
+		dev_err(&pdev->dev, "failed to request etop resource\n");
+		err = -EBUSY;
+		goto err_out;
+	}
+
+	ltq_etop_membase = devm_ioremap_nocache(&pdev->dev,
+		res->start, resource_size(res));
+	if (!ltq_etop_membase) {
+		dev_err(&pdev->dev, "failed to remap etop engine %d\n",
+			pdev->id);
+		err = -ENOMEM;
+		goto err_out;
+	}
+
+	dev = alloc_etherdev_mq(sizeof(struct ltq_etop_priv), 4);
+	strcpy(dev->name, "eth%d");
+	dev->netdev_ops = &ltq_eth_netdev_ops;
+	dev->ethtool_ops = &ltq_etop_ethtool_ops;
+	priv = netdev_priv(dev);
+	priv->res = res;
+	priv->pldata = dev_get_platdata(&pdev->dev);
+	priv->netdev = dev;
+	spin_lock_init(&priv->lock);
+
+	for (i = 0; i < MAX_DMA_CHAN; i++) {
+		if (IS_TX(i))
+			netif_napi_add(dev, &priv->ch[i].napi,
+				ltq_etop_poll_tx, 8);
+		else if (IS_RX(i))
+			netif_napi_add(dev, &priv->ch[i].napi,
+				ltq_etop_poll_rx, 32);
+		priv->ch[i].netdev = dev;
+	}
+
+	err = register_netdev(dev);
+	if (err)
+		goto err_free;
+
+	platform_set_drvdata(pdev, dev);
+	return 0;
+
+err_free:
+	kfree(dev);
+err_out:
+	return err;
+}
+
+static int __devexit
+ltq_etop_remove(struct platform_device *pdev)
+{
+	struct net_device *dev = platform_get_drvdata(pdev);
+
+	if (dev) {
+		netif_tx_stop_all_queues(dev);
+		ltq_etop_hw_exit(dev);
+		ltq_etop_mdio_cleanup(dev);
+		unregister_netdev(dev);
+	}
+	return 0;
+}
+
+static struct platform_driver ltq_mii_driver = {
+	.remove = __devexit_p(ltq_etop_remove),
+	.driver = {
+		.name = "ltq_etop",
+		.owner = THIS_MODULE,
+	},
+};
+
+int __init
+init_ltq_etop(void)
+{
+	int ret = platform_driver_probe(&ltq_mii_driver, ltq_etop_probe);
+
+	if (ret)
+		pr_err("ltq_etop: Error registering platfom driver!");
+	return ret;
+}
+
+static void __exit
+exit_ltq_etop(void)
+{
+	platform_driver_unregister(&ltq_mii_driver);
+}
+
+module_init(init_ltq_etop);
+module_exit(exit_ltq_etop);
+
+MODULE_AUTHOR("John Crispin <blogic@openwrt.org>");
+MODULE_DESCRIPTION("Lantiq SoC ETOP");
+MODULE_LICENSE("GPL");
diff -druN linux-2.6.39-libre/drivers/net/loopback.c linux-3.0-rc7-libre/drivers/net/loopback.c
--- linux-2.6.39-libre/drivers/net/loopback.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/loopback.c	2011-07-11 19:51:52.000000000 -0400
@@ -174,7 +174,8 @@
 		| NETIF_F_HIGHDMA
 		| NETIF_F_LLTX
 		| NETIF_F_NETNS_LOCAL
-		| NETIF_F_VLAN_CHALLENGED;
+		| NETIF_F_VLAN_CHALLENGED
+		| NETIF_F_LOOPBACK;
 	dev->ethtool_ops	= &loopback_ethtool_ops;
 	dev->header_ops		= &eth_header_ops;
 	dev->netdev_ops		= &loopback_ops;
diff -druN linux-2.6.39-libre/drivers/net/macb.c linux-3.0-rc7-libre/drivers/net/macb.c
--- linux-2.6.39-libre/drivers/net/macb.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/macb.c	2011-07-11 19:51:52.000000000 -0400
@@ -576,6 +576,11 @@
 		 * add that if/when we get our hands on a full-blown MII PHY.
 		 */
 
+		if (status & MACB_BIT(ISR_ROVR)) {
+			/* We missed at least one packet */
+			bp->hw_stats.rx_overruns++;
+		}
+
 		if (status & MACB_BIT(HRESP)) {
 			/*
 			 * TODO: Reset the hardware, and maybe move the printk
@@ -1024,7 +1029,8 @@
 				   hwstat->rx_jabbers +
 				   hwstat->rx_undersize_pkts +
 				   hwstat->rx_length_mismatch);
-	nstat->rx_over_errors = hwstat->rx_resource_errors;
+	nstat->rx_over_errors = hwstat->rx_resource_errors +
+				   hwstat->rx_overruns;
 	nstat->rx_crc_errors = hwstat->rx_fcs_errors;
 	nstat->rx_frame_errors = hwstat->rx_align_errors;
 	nstat->rx_fifo_errors = hwstat->rx_overruns;
@@ -1171,8 +1177,7 @@
 	}
 
 	dev->irq = platform_get_irq(pdev, 0);
-	err = request_irq(dev->irq, macb_interrupt, IRQF_SAMPLE_RANDOM,
-			  dev->name, dev);
+	err = request_irq(dev->irq, macb_interrupt, 0, dev->name, dev);
 	if (err) {
 		printk(KERN_ERR
 		       "%s: Unable to request IRQ %d (error %d)\n",
@@ -1351,5 +1356,5 @@
 
 MODULE_LICENSE("GPL");
 MODULE_DESCRIPTION("Atmel MACB Ethernet driver");
-MODULE_AUTHOR("Haavard Skinnemoen <hskinnemoen@atmel.com>");
+MODULE_AUTHOR("Haavard Skinnemoen (Atmel)");
 MODULE_ALIAS("platform:macb");
diff -druN linux-2.6.39-libre/drivers/net/macvlan.c linux-3.0-rc7-libre/drivers/net/macvlan.c
--- linux-2.6.39-libre/drivers/net/macvlan.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/macvlan.c	2011-07-11 19:51:52.000000000 -0400
@@ -70,16 +70,17 @@
 	hlist_add_head_rcu(&vlan->hlist, &port->vlan_hash[addr[5]]);
 }
 
-static void macvlan_hash_del(struct macvlan_dev *vlan)
+static void macvlan_hash_del(struct macvlan_dev *vlan, bool sync)
 {
 	hlist_del_rcu(&vlan->hlist);
-	synchronize_rcu();
+	if (sync)
+		synchronize_rcu();
 }
 
 static void macvlan_hash_change_addr(struct macvlan_dev *vlan,
 					const unsigned char *addr)
 {
-	macvlan_hash_del(vlan);
+	macvlan_hash_del(vlan, true);
 	/* Now that we are unhashed it is safe to change the device
 	 * address without confusing packet delivery.
 	 */
@@ -237,10 +238,8 @@
 
 		dest = macvlan_hash_lookup(port, eth->h_dest);
 		if (dest && dest->mode == MACVLAN_MODE_BRIDGE) {
-			unsigned int length = skb->len + ETH_HLEN;
-			int ret = dest->forward(dest->dev, skb);
-			macvlan_count_rx(dest, length,
-					 ret == NET_RX_SUCCESS, 0);
+			/* send to lowerdev first for its network taps */
+			vlan->forward(vlan->lowerdev, skb);
 
 			return NET_XMIT_SUCCESS;
 		}
@@ -345,7 +344,7 @@
 	dev_uc_del(lowerdev, dev->dev_addr);
 
 hash_del:
-	macvlan_hash_del(vlan);
+	macvlan_hash_del(vlan, !dev->dismantle);
 	return 0;
 }
 
@@ -415,7 +414,7 @@
 #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_GRO)
+	 NETIF_F_TSO_ECN | NETIF_F_TSO6 | NETIF_F_GRO | NETIF_F_RXCSUM)
 
 #define MACVLAN_STATE_MASK \
 	((1<<__LINK_STATE_NOCARRIER) | (1<<__LINK_STATE_DORMANT))
@@ -517,12 +516,6 @@
 	snprintf(drvinfo->version, 32, "0.1");
 }
 
-static u32 macvlan_ethtool_get_rx_csum(struct net_device *dev)
-{
-	const struct macvlan_dev *vlan = netdev_priv(dev);
-	return dev_ethtool_get_rx_csum(vlan->lowerdev);
-}
-
 static int macvlan_ethtool_get_settings(struct net_device *dev,
 					struct ethtool_cmd *cmd)
 {
@@ -530,18 +523,10 @@
 	return dev_ethtool_get_settings(vlan->lowerdev, cmd);
 }
 
-static u32 macvlan_ethtool_get_flags(struct net_device *dev)
-{
-	const struct macvlan_dev *vlan = netdev_priv(dev);
-	return dev_ethtool_get_flags(vlan->lowerdev);
-}
-
 static const struct ethtool_ops macvlan_ethtool_ops = {
 	.get_link		= ethtool_op_get_link,
 	.get_settings		= macvlan_ethtool_get_settings,
-	.get_rx_csum		= macvlan_ethtool_get_rx_csum,
 	.get_drvinfo		= macvlan_ethtool_get_drvinfo,
-	.get_flags		= macvlan_ethtool_get_flags,
 };
 
 static const struct net_device_ops macvlan_netdev_ops = {
@@ -598,26 +583,18 @@
 	err = netdev_rx_handler_register(dev, macvlan_handle_frame, port);
 	if (err)
 		kfree(port);
-
-	dev->priv_flags |= IFF_MACVLAN_PORT;
+	else
+		dev->priv_flags |= IFF_MACVLAN_PORT;
 	return err;
 }
 
-static void macvlan_port_rcu_free(struct rcu_head *head)
-{
-	struct macvlan_port *port;
-
-	port = container_of(head, struct macvlan_port, rcu);
-	kfree(port);
-}
-
 static void macvlan_port_destroy(struct net_device *dev)
 {
 	struct macvlan_port *port = macvlan_port_get(dev);
 
 	dev->priv_flags &= ~IFF_MACVLAN_PORT;
 	netdev_rx_handler_unregister(dev);
-	call_rcu(&port->rcu, macvlan_port_rcu_free);
+	kfree_rcu(port, rcu);
 }
 
 static int macvlan_validate(struct nlattr *tb[], struct nlattr *data[])
@@ -799,6 +776,7 @@
 	struct net_device *dev = ptr;
 	struct macvlan_dev *vlan, *next;
 	struct macvlan_port *port;
+	LIST_HEAD(list_kill);
 
 	if (!macvlan_port_exists(dev))
 		return NOTIFY_DONE;
@@ -824,7 +802,9 @@
 			break;
 
 		list_for_each_entry_safe(vlan, next, &port->vlans, list)
-			vlan->dev->rtnl_link_ops->dellink(vlan->dev, NULL);
+			vlan->dev->rtnl_link_ops->dellink(vlan->dev, &list_kill);
+		unregister_netdevice_many(&list_kill);
+		list_del(&list_kill);
 		break;
 	case NETDEV_PRE_TYPE_CHANGE:
 		/* Forbid underlaying device to change its type. */
diff -druN linux-2.6.39-libre/drivers/net/Makefile linux-3.0-rc7-libre/drivers/net/Makefile
--- linux-2.6.39-libre/drivers/net/Makefile	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/Makefile	2011-07-11 19:51:52.000000000 -0400
@@ -31,6 +31,7 @@
 obj-$(CONFIG_ATL1E) += atl1e/
 obj-$(CONFIG_ATL1C) += atl1c/
 obj-$(CONFIG_GIANFAR) += gianfar_driver.o
+obj-$(CONFIG_PTP_1588_CLOCK_GIANFAR) += gianfar_ptp.o
 obj-$(CONFIG_TEHUTI) += tehuti.o
 obj-$(CONFIG_ENIC) += enic/
 obj-$(CONFIG_JME) += jme.o
@@ -259,6 +260,7 @@
 obj-$(CONFIG_ENC28J60) += enc28j60.o
 obj-$(CONFIG_ETHOC) += ethoc.o
 obj-$(CONFIG_GRETH) += greth.o
+obj-$(CONFIG_LANTIQ_ETOP) += lantiq_etop.o
 
 obj-$(CONFIG_XTENSA_XT2000_SONIC) += xtsonic.o
 
diff -druN linux-2.6.39-libre/drivers/net/mdio.c linux-3.0-rc7-libre/drivers/net/mdio.c
--- linux-2.6.39-libre/drivers/net/mdio.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/mdio.c	2011-07-11 19:51:52.000000000 -0400
@@ -176,6 +176,9 @@
  * @npage_adv: Modes currently advertised on next pages
  * @npage_lpa: Modes advertised by link partner on next pages
  *
+ * The @ecmd parameter is expected to have been cleared before calling
+ * mdio45_ethtool_gset_npage().
+ *
  * Since the CSRs for auto-negotiation using next pages are not fully
  * standardised, this function does not attempt to decode them.  The
  * caller must pass them in.
@@ -185,6 +188,7 @@
 			       u32 npage_adv, u32 npage_lpa)
 {
 	int reg;
+	u32 speed;
 
 	ecmd->transceiver = XCVR_INTERNAL;
 	ecmd->phy_address = mdio->prtad;
@@ -287,33 +291,36 @@
 		if (modes & (ADVERTISED_10000baseT_Full |
 			     ADVERTISED_10000baseKX4_Full |
 			     ADVERTISED_10000baseKR_Full)) {
-			ecmd->speed = SPEED_10000;
+			speed = SPEED_10000;
 			ecmd->duplex = DUPLEX_FULL;
 		} else if (modes & (ADVERTISED_1000baseT_Full |
 				    ADVERTISED_1000baseT_Half |
 				    ADVERTISED_1000baseKX_Full)) {
-			ecmd->speed = SPEED_1000;
+			speed = SPEED_1000;
 			ecmd->duplex = !(modes & ADVERTISED_1000baseT_Half);
 		} else if (modes & (ADVERTISED_100baseT_Full |
 				    ADVERTISED_100baseT_Half)) {
-			ecmd->speed = SPEED_100;
+			speed = SPEED_100;
 			ecmd->duplex = !!(modes & ADVERTISED_100baseT_Full);
 		} else {
-			ecmd->speed = SPEED_10;
+			speed = SPEED_10;
 			ecmd->duplex = !!(modes & ADVERTISED_10baseT_Full);
 		}
 	} else {
 		/* Report forced settings */
 		reg = mdio->mdio_read(mdio->dev, mdio->prtad, MDIO_MMD_PMAPMD,
 				      MDIO_CTRL1);
-		ecmd->speed = (((reg & MDIO_PMA_CTRL1_SPEED1000) ? 100 : 1) *
-			       ((reg & MDIO_PMA_CTRL1_SPEED100) ? 100 : 10));
+		speed = (((reg & MDIO_PMA_CTRL1_SPEED1000) ? 100 : 1)
+			 * ((reg & MDIO_PMA_CTRL1_SPEED100) ? 100 : 10));
 		ecmd->duplex = (reg & MDIO_CTRL1_FULLDPLX ||
-				ecmd->speed == SPEED_10000);
+				speed == SPEED_10000);
 	}
 
+	ethtool_cmd_speed_set(ecmd, speed);
+
 	/* 10GBASE-T MDI/MDI-X */
-	if (ecmd->port == PORT_TP && ecmd->speed == SPEED_10000) {
+	if (ecmd->port == PORT_TP
+	    && (ethtool_cmd_speed(ecmd) == SPEED_10000)) {
 		switch (mdio->mdio_read(mdio->dev, mdio->prtad, MDIO_MMD_PMAPMD,
 					MDIO_PMA_10GBT_SWAPPOL)) {
 		case MDIO_PMA_10GBT_SWAPPOL_ABNX | MDIO_PMA_10GBT_SWAPPOL_CDNX:
diff -druN linux-2.6.39-libre/drivers/net/mii.c linux-3.0-rc7-libre/drivers/net/mii.c
--- linux-2.6.39-libre/drivers/net/mii.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/mii.c	2011-07-11 19:51:52.000000000 -0400
@@ -62,6 +62,9 @@
  * @mii: MII interface
  * @ecmd: requested ethtool_cmd
  *
+ * The @ecmd parameter is expected to have been cleared before calling
+ * mii_ethtool_gset().
+ *
  * Returns 0 for success, negative on error.
  */
 int mii_ethtool_gset(struct mii_if_info *mii, struct ethtool_cmd *ecmd)
@@ -122,22 +125,25 @@
 
 		if (nego & (ADVERTISED_1000baseT_Full |
 			    ADVERTISED_1000baseT_Half)) {
-			ecmd->speed = SPEED_1000;
+			ethtool_cmd_speed_set(ecmd, SPEED_1000);
 			ecmd->duplex = !!(nego & ADVERTISED_1000baseT_Full);
 		} else if (nego & (ADVERTISED_100baseT_Full |
 				   ADVERTISED_100baseT_Half)) {
-			ecmd->speed = SPEED_100;
+			ethtool_cmd_speed_set(ecmd, SPEED_100);
 			ecmd->duplex = !!(nego & ADVERTISED_100baseT_Full);
 		} else {
-			ecmd->speed = SPEED_10;
+			ethtool_cmd_speed_set(ecmd, SPEED_10);
 			ecmd->duplex = !!(nego & ADVERTISED_10baseT_Full);
 		}
 	} else {
 		ecmd->autoneg = AUTONEG_DISABLE;
 
-		ecmd->speed = ((bmcr & BMCR_SPEED1000 &&
-				(bmcr & BMCR_SPEED100) == 0) ? SPEED_1000 :
-			       (bmcr & BMCR_SPEED100) ? SPEED_100 : SPEED_10);
+		ethtool_cmd_speed_set(ecmd,
+				      ((bmcr & BMCR_SPEED1000 &&
+					(bmcr & BMCR_SPEED100) == 0) ?
+				       SPEED_1000 :
+				       ((bmcr & BMCR_SPEED100) ?
+					SPEED_100 : SPEED_10)));
 		ecmd->duplex = (bmcr & BMCR_FULLDPLX) ? DUPLEX_FULL : DUPLEX_HALF;
 	}
 
@@ -158,10 +164,11 @@
 int mii_ethtool_sset(struct mii_if_info *mii, struct ethtool_cmd *ecmd)
 {
 	struct net_device *dev = mii->dev;
+	u32 speed = ethtool_cmd_speed(ecmd);
 
-	if (ecmd->speed != SPEED_10 &&
-	    ecmd->speed != SPEED_100 &&
-	    ecmd->speed != SPEED_1000)
+	if (speed != SPEED_10 &&
+	    speed != SPEED_100 &&
+	    speed != SPEED_1000)
 		return -EINVAL;
 	if (ecmd->duplex != DUPLEX_HALF && ecmd->duplex != DUPLEX_FULL)
 		return -EINVAL;
@@ -173,7 +180,7 @@
 		return -EINVAL;
 	if (ecmd->autoneg != AUTONEG_DISABLE && ecmd->autoneg != AUTONEG_ENABLE)
 		return -EINVAL;
-	if ((ecmd->speed == SPEED_1000) && (!mii->supports_gmii))
+	if ((speed == SPEED_1000) && (!mii->supports_gmii))
 		return -EINVAL;
 
 	/* ignore supported, maxtxpkt, maxrxpkt */
@@ -231,9 +238,9 @@
 		bmcr = mii->mdio_read(dev, mii->phy_id, MII_BMCR);
 		tmp = bmcr & ~(BMCR_ANENABLE | BMCR_SPEED100 |
 			       BMCR_SPEED1000 | BMCR_FULLDPLX);
-		if (ecmd->speed == SPEED_1000)
+		if (speed == SPEED_1000)
 			tmp |= BMCR_SPEED1000;
-		else if (ecmd->speed == SPEED_100)
+		else if (speed == SPEED_100)
 			tmp |= BMCR_SPEED100;
 		if (ecmd->duplex == DUPLEX_FULL) {
 			tmp |= BMCR_FULLDPLX;
diff -druN linux-2.6.39-libre/drivers/net/mlx4/en_ethtool.c linux-3.0-rc7-libre/drivers/net/mlx4/en_ethtool.c
--- linux-2.6.39-libre/drivers/net/mlx4/en_ethtool.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/mlx4/en_ethtool.c	2011-07-11 19:51:52.000000000 -0400
@@ -57,37 +57,6 @@
 	drvinfo->eedump_len = 0;
 }
 
-static u32 mlx4_en_get_tso(struct net_device *dev)
-{
-	return (dev->features & NETIF_F_TSO) != 0;
-}
-
-static int mlx4_en_set_tso(struct net_device *dev, u32 data)
-{
-	struct mlx4_en_priv *priv = netdev_priv(dev);
-
-	if (data) {
-		if (!priv->mdev->LSO_support)
-			return -EPERM;
-		dev->features |= (NETIF_F_TSO | NETIF_F_TSO6);
-	} else
-		dev->features &= ~(NETIF_F_TSO | NETIF_F_TSO6);
-	return 0;
-}
-
-static u32 mlx4_en_get_rx_csum(struct net_device *dev)
-{
-	struct mlx4_en_priv *priv = netdev_priv(dev);
-	return priv->rx_csum;
-}
-
-static int mlx4_en_set_rx_csum(struct net_device *dev, u32 data)
-{
-	struct mlx4_en_priv *priv = netdev_priv(dev);
-	priv->rx_csum = (data != 0);
-	return 0;
-}
-
 static const char main_strings[][ETH_GSTRING_LEN] = {
 	"rx_packets", "tx_packets", "rx_bytes", "tx_bytes", "rx_errors",
 	"tx_errors", "rx_dropped", "tx_dropped", "multicast", "collisions",
@@ -296,10 +265,10 @@
 
 	trans_type = priv->port_state.transciver;
 	if (netif_carrier_ok(dev)) {
-		cmd->speed = priv->port_state.link_speed;
+		ethtool_cmd_speed_set(cmd, priv->port_state.link_speed);
 		cmd->duplex = DUPLEX_FULL;
 	} else {
-		cmd->speed = -1;
+		ethtool_cmd_speed_set(cmd, -1);
 		cmd->duplex = -1;
 	}
 
@@ -323,7 +292,8 @@
 static int mlx4_en_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
 {
 	if ((cmd->autoneg == AUTONEG_ENABLE) ||
-	    (cmd->speed != SPEED_10000) || (cmd->duplex != DUPLEX_FULL))
+	    (ethtool_cmd_speed(cmd) != SPEED_10000) ||
+	    (cmd->duplex != DUPLEX_FULL))
 		return -EINVAL;
 
 	/* Nothing to change */
@@ -483,17 +453,7 @@
 	.get_drvinfo = mlx4_en_get_drvinfo,
 	.get_settings = mlx4_en_get_settings,
 	.set_settings = mlx4_en_set_settings,
-#ifdef NETIF_F_TSO
-	.get_tso = mlx4_en_get_tso,
-	.set_tso = mlx4_en_set_tso,
-#endif
-	.get_sg = ethtool_op_get_sg,
-	.set_sg = ethtool_op_set_sg,
 	.get_link = ethtool_op_get_link,
-	.get_rx_csum = mlx4_en_get_rx_csum,
-	.set_rx_csum = mlx4_en_set_rx_csum,
-	.get_tx_csum = ethtool_op_get_tx_csum,
-	.set_tx_csum = ethtool_op_set_tx_ipv6_csum,
 	.get_strings = mlx4_en_get_strings,
 	.get_sset_count = mlx4_en_get_sset_count,
 	.get_ethtool_stats = mlx4_en_get_ethtool_stats,
@@ -508,7 +468,6 @@
 	.set_pauseparam = mlx4_en_set_pauseparam,
 	.get_ringparam = mlx4_en_get_ringparam,
 	.set_ringparam = mlx4_en_set_ringparam,
-	.get_flags = ethtool_op_get_flags,
 };
 
 
diff -druN linux-2.6.39-libre/drivers/net/mlx4/en_netdev.c linux-3.0-rc7-libre/drivers/net/mlx4/en_netdev.c
--- linux-2.6.39-libre/drivers/net/mlx4/en_netdev.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/mlx4/en_netdev.c	2011-07-11 19:51:52.000000000 -0400
@@ -1083,7 +1083,6 @@
 	priv->prof = prof;
 	priv->port = port;
 	priv->port_up = false;
-	priv->rx_csum = 1;
 	priv->flags = prof->flags;
 	priv->tx_ring_num = prof->tx_ring_num;
 	priv->rx_ring_num = prof->rx_ring_num;
@@ -1141,21 +1140,16 @@
 	/*
 	 * Set driver features
 	 */
-	dev->features |= NETIF_F_SG;
-	dev->vlan_features |= NETIF_F_SG;
-	dev->features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;
-	dev->vlan_features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;
-	dev->features |= NETIF_F_HIGHDMA;
-	dev->features |= NETIF_F_HW_VLAN_TX |
-			 NETIF_F_HW_VLAN_RX |
-			 NETIF_F_HW_VLAN_FILTER;
-	dev->features |= NETIF_F_GRO;
-	if (mdev->LSO_support) {
-		dev->features |= NETIF_F_TSO;
-		dev->features |= NETIF_F_TSO6;
-		dev->vlan_features |= NETIF_F_TSO;
-		dev->vlan_features |= NETIF_F_TSO6;
-	}
+	dev->hw_features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;
+	if (mdev->LSO_support)
+		dev->hw_features |= NETIF_F_TSO | NETIF_F_TSO6;
+
+	dev->vlan_features = dev->hw_features;
+
+	dev->hw_features |= NETIF_F_RXCSUM;
+	dev->features = dev->hw_features | NETIF_F_HIGHDMA |
+			NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX |
+			NETIF_F_HW_VLAN_FILTER;
 
 	mdev->pndev[port] = dev;
 
diff -druN linux-2.6.39-libre/drivers/net/mlx4/en_rx.c linux-3.0-rc7-libre/drivers/net/mlx4/en_rx.c
--- linux-2.6.39-libre/drivers/net/mlx4/en_rx.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/mlx4/en_rx.c	2011-07-11 19:51:52.000000000 -0400
@@ -584,7 +584,7 @@
 		ring->bytes += length;
 		ring->packets++;
 
-		if (likely(priv->rx_csum)) {
+		if (likely(dev->features & NETIF_F_RXCSUM)) {
 			if ((cqe->status & cpu_to_be16(MLX4_CQE_STATUS_IPOK)) &&
 			    (cqe->checksum == cpu_to_be16(0xffff))) {
 				priv->port_stats.rx_chksum_good++;
diff -druN linux-2.6.39-libre/drivers/net/mlx4/mlx4_en.h linux-3.0-rc7-libre/drivers/net/mlx4/mlx4_en.h
--- linux-2.6.39-libre/drivers/net/mlx4/mlx4_en.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/mlx4/mlx4_en.h	2011-07-11 19:51:52.000000000 -0400
@@ -451,7 +451,6 @@
 	int registered;
 	int allocated;
 	int stride;
-	int rx_csum;
 	u64 mac;
 	int mac_index;
 	unsigned max_mtu;
diff -druN linux-2.6.39-libre/drivers/net/mv643xx_eth.c linux-3.0-rc7-libre/drivers/net/mv643xx_eth.c
--- linux-2.6.39-libre/drivers/net/mv643xx_eth.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/mv643xx_eth.c	2011-07-11 19:51:52.000000000 -0400
@@ -1444,13 +1444,13 @@
 	cmd->advertising = ADVERTISED_MII;
 	switch (port_status & PORT_SPEED_MASK) {
 	case PORT_SPEED_10:
-		cmd->speed = SPEED_10;
+		ethtool_cmd_speed_set(cmd, SPEED_10);
 		break;
 	case PORT_SPEED_100:
-		cmd->speed = SPEED_100;
+		ethtool_cmd_speed_set(cmd, SPEED_100);
 		break;
 	case PORT_SPEED_1000:
-		cmd->speed = SPEED_1000;
+		ethtool_cmd_speed_set(cmd, SPEED_1000);
 		break;
 	default:
 		cmd->speed = -1;
@@ -1575,18 +1575,12 @@
 	return 0;
 }
 
-static u32
-mv643xx_eth_get_rx_csum(struct net_device *dev)
-{
-	struct mv643xx_eth_private *mp = netdev_priv(dev);
-
-	return !!(rdlp(mp, PORT_CONFIG) & 0x02000000);
-}
 
 static int
-mv643xx_eth_set_rx_csum(struct net_device *dev, u32 rx_csum)
+mv643xx_eth_set_features(struct net_device *dev, u32 features)
 {
 	struct mv643xx_eth_private *mp = netdev_priv(dev);
+	u32 rx_csum = features & NETIF_F_RXCSUM;
 
 	wrlp(mp, PORT_CONFIG, rx_csum ? 0x02000000 : 0x00000000);
 
@@ -1634,11 +1628,6 @@
 	}
 }
 
-static int mv643xx_eth_set_flags(struct net_device *dev, u32 data)
-{
-	return ethtool_op_set_flags(dev, data, ETH_FLAG_LRO);
-}
-
 static int mv643xx_eth_get_sset_count(struct net_device *dev, int sset)
 {
 	if (sset == ETH_SS_STATS)
@@ -1657,14 +1646,8 @@
 	.set_coalesce		= mv643xx_eth_set_coalesce,
 	.get_ringparam		= mv643xx_eth_get_ringparam,
 	.set_ringparam		= mv643xx_eth_set_ringparam,
-	.get_rx_csum		= mv643xx_eth_get_rx_csum,
-	.set_rx_csum		= mv643xx_eth_set_rx_csum,
-	.set_tx_csum		= ethtool_op_set_tx_csum,
-	.set_sg			= ethtool_op_set_sg,
 	.get_strings		= mv643xx_eth_get_strings,
 	.get_ethtool_stats	= mv643xx_eth_get_ethtool_stats,
-	.get_flags		= ethtool_op_get_flags,
-	.set_flags		= mv643xx_eth_set_flags,
 	.get_sset_count		= mv643xx_eth_get_sset_count,
 };
 
@@ -2264,7 +2247,7 @@
 	 * frames to RX queue #0, and include the pseudo-header when
 	 * calculating receive checksums.
 	 */
-	wrlp(mp, PORT_CONFIG, 0x02000000);
+	mv643xx_eth_set_features(mp->dev, mp->dev->features);
 
 	/*
 	 * Treat BPDUs as normal multicasts, and disable partition mode.
@@ -2848,6 +2831,7 @@
 	.ndo_validate_addr	= eth_validate_addr,
 	.ndo_do_ioctl		= mv643xx_eth_ioctl,
 	.ndo_change_mtu		= mv643xx_eth_change_mtu,
+	.ndo_set_features	= mv643xx_eth_set_features,
 	.ndo_tx_timeout		= mv643xx_eth_tx_timeout,
 	.ndo_get_stats		= mv643xx_eth_get_stats,
 #ifdef CONFIG_NET_POLL_CONTROLLER
@@ -2930,7 +2914,9 @@
 	dev->watchdog_timeo = 2 * HZ;
 	dev->base_addr = 0;
 
-	dev->features = NETIF_F_SG | NETIF_F_IP_CSUM;
+	dev->hw_features = NETIF_F_SG | NETIF_F_IP_CSUM |
+		NETIF_F_RXCSUM | NETIF_F_LRO;
+	dev->features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_RXCSUM;
 	dev->vlan_features = NETIF_F_SG | NETIF_F_IP_CSUM;
 
 	SET_NETDEV_DEV(dev, &pdev->dev);
diff -druN linux-2.6.39-libre/drivers/net/myri10ge/myri10ge.c linux-3.0-rc7-libre/drivers/net/myri10ge/myri10ge.c
--- linux-2.6.39-libre/drivers/net/myri10ge/myri10ge.c	2011-05-19 02:12:05.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/myri10ge/myri10ge.c	2011-07-21 06:54:35.000000000 -0400
@@ -65,6 +65,7 @@
 #include <linux/io.h>
 #include <linux/log2.h>
 #include <linux/slab.h>
+#include <linux/prefetch.h>
 #include <net/checksum.h>
 #include <net/ip.h>
 #include <net/tcp.h>
@@ -205,7 +206,6 @@
 	int tx_boundary;	/* boundary transmits cannot cross */
 	int num_slices;
 	int running;		/* running?             */
-	int csum_flag;		/* rx_csums?            */
 	int small_bytes;
 	int big_bytes;
 	int max_intr_slots;
@@ -1383,7 +1383,7 @@
 	skb->protocol = eth_type_trans(skb, dev);
 	skb_record_rx_queue(skb, ss - &mgp->ss[0]);
 
-	if (mgp->csum_flag) {
+	if (dev->features & NETIF_F_RXCSUM) {
 		if ((skb->protocol == htons(ETH_P_IP)) ||
 		    (skb->protocol == htons(ETH_P_IPV6))) {
 			skb->csum = csum;
@@ -1642,7 +1642,7 @@
 	int i;
 
 	cmd->autoneg = AUTONEG_DISABLE;
-	cmd->speed = SPEED_10000;
+	ethtool_cmd_speed_set(cmd, SPEED_10000);
 	cmd->duplex = DUPLEX_FULL;
 
 	/*
@@ -1754,43 +1754,6 @@
 	ring->tx_pending = ring->tx_max_pending;
 }
 
-static u32 myri10ge_get_rx_csum(struct net_device *netdev)
-{
-	struct myri10ge_priv *mgp = netdev_priv(netdev);
-
-	if (mgp->csum_flag)
-		return 1;
-	else
-		return 0;
-}
-
-static int myri10ge_set_rx_csum(struct net_device *netdev, u32 csum_enabled)
-{
-	struct myri10ge_priv *mgp = netdev_priv(netdev);
-	int err = 0;
-
-	if (csum_enabled)
-		mgp->csum_flag = MXGEFW_FLAGS_CKSUM;
-	else {
-		netdev->features &= ~NETIF_F_LRO;
-		mgp->csum_flag = 0;
-
-	}
-	return err;
-}
-
-static int myri10ge_set_tso(struct net_device *netdev, u32 tso_enabled)
-{
-	struct myri10ge_priv *mgp = netdev_priv(netdev);
-	u32 flags = mgp->features & (NETIF_F_TSO6 | NETIF_F_TSO);
-
-	if (tso_enabled)
-		netdev->features |= flags;
-	else
-		netdev->features &= ~flags;
-	return 0;
-}
-
 static const char myri10ge_gstrings_main_stats[][ETH_GSTRING_LEN] = {
 	"rx_packets", "tx_packets", "rx_bytes", "tx_bytes", "rx_errors",
 	"tx_errors", "rx_dropped", "tx_dropped", "multicast", "collisions",
@@ -1941,11 +1904,6 @@
 	return mgp->msg_enable;
 }
 
-static int myri10ge_set_flags(struct net_device *netdev, u32 value)
-{
-	return ethtool_op_set_flags(netdev, value, ETH_FLAG_LRO);
-}
-
 static const struct ethtool_ops myri10ge_ethtool_ops = {
 	.get_settings = myri10ge_get_settings,
 	.get_drvinfo = myri10ge_get_drvinfo,
@@ -1954,19 +1912,12 @@
 	.get_pauseparam = myri10ge_get_pauseparam,
 	.set_pauseparam = myri10ge_set_pauseparam,
 	.get_ringparam = myri10ge_get_ringparam,
-	.get_rx_csum = myri10ge_get_rx_csum,
-	.set_rx_csum = myri10ge_set_rx_csum,
-	.set_tx_csum = ethtool_op_set_tx_hw_csum,
-	.set_sg = ethtool_op_set_sg,
-	.set_tso = myri10ge_set_tso,
 	.get_link = ethtool_op_get_link,
 	.get_strings = myri10ge_get_strings,
 	.get_sset_count = myri10ge_get_sset_count,
 	.get_ethtool_stats = myri10ge_get_ethtool_stats,
 	.set_msglevel = myri10ge_set_msglevel,
 	.get_msglevel = myri10ge_get_msglevel,
-	.get_flags = ethtool_op_get_flags,
-	.set_flags = myri10ge_set_flags
 };
 
 static int myri10ge_allocate_rings(struct myri10ge_slice_state *ss)
@@ -3133,6 +3084,14 @@
 	return 0;
 }
 
+static u32 myri10ge_fix_features(struct net_device *dev, u32 features)
+{
+	if (!(features & NETIF_F_RXCSUM))
+		features &= ~NETIF_F_LRO;
+
+	return features;
+}
+
 static int myri10ge_change_mtu(struct net_device *dev, int new_mtu)
 {
 	struct myri10ge_priv *mgp = netdev_priv(dev);
@@ -3824,6 +3783,7 @@
 	.ndo_get_stats		= myri10ge_get_stats,
 	.ndo_validate_addr	= eth_validate_addr,
 	.ndo_change_mtu		= myri10ge_change_mtu,
+	.ndo_fix_features	= myri10ge_fix_features,
 	.ndo_set_multicast_list = myri10ge_set_multicast_list,
 	.ndo_set_mac_address	= myri10ge_set_mac_address,
 };
@@ -3850,7 +3810,6 @@
 	mgp = netdev_priv(netdev);
 	mgp->dev = netdev;
 	mgp->pdev = pdev;
-	mgp->csum_flag = MXGEFW_FLAGS_CKSUM;
 	mgp->pause = myri10ge_flow_control;
 	mgp->intr_coal_delay = myri10ge_intr_coal_delay;
 	mgp->msg_enable = netif_msg_init(myri10ge_debug, MYRI10GE_MSG_DEFAULT);
@@ -3966,11 +3925,11 @@
 	netdev->netdev_ops = &myri10ge_netdev_ops;
 	netdev->mtu = myri10ge_initial_mtu;
 	netdev->base_addr = mgp->iomem_base;
-	netdev->features = mgp->features;
+	netdev->hw_features = mgp->features | NETIF_F_LRO | NETIF_F_RXCSUM;
+	netdev->features = netdev->hw_features;
 
 	if (dac_enabled)
 		netdev->features |= NETIF_F_HIGHDMA;
-	netdev->features |= NETIF_F_LRO;
 
 	netdev->vlan_features |= mgp->features;
 	if (mgp->fw_ver_tiny < 37)
diff -druN linux-2.6.39-libre/drivers/net/natsemi.c linux-3.0-rc7-libre/drivers/net/natsemi.c
--- linux-2.6.39-libre/drivers/net/natsemi.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/natsemi.c	2011-07-11 19:51:52.000000000 -0400
@@ -2360,7 +2360,8 @@
 					PCI_DMA_FROMDEVICE);
 			} else {
 				pci_unmap_single(np->pci_dev, np->rx_dma[entry],
-					buflen, PCI_DMA_FROMDEVICE);
+						 buflen + NATSEMI_PADDING,
+						 PCI_DMA_FROMDEVICE);
 				skb_put(skb = np->rx_skbuff[entry], pkt_len);
 				np->rx_skbuff[entry] = NULL;
 			}
@@ -2820,7 +2821,7 @@
 	u32 tmp;
 
 	ecmd->port        = dev->if_port;
-	ecmd->speed       = np->speed;
+	ethtool_cmd_speed_set(ecmd, np->speed);
 	ecmd->duplex      = np->duplex;
 	ecmd->autoneg     = np->autoneg;
 	ecmd->advertising = 0;
@@ -2878,9 +2879,9 @@
 		tmp = mii_nway_result(
 			np->advertising & mdio_read(dev, MII_LPA));
 		if (tmp == LPA_100FULL || tmp == LPA_100HALF)
-			ecmd->speed  = SPEED_100;
+			ethtool_cmd_speed_set(ecmd, SPEED_100);
 		else
-			ecmd->speed  = SPEED_10;
+			ethtool_cmd_speed_set(ecmd, SPEED_10);
 		if (tmp == LPA_100FULL || tmp == LPA_10FULL)
 			ecmd->duplex = DUPLEX_FULL;
 		else
@@ -2908,7 +2909,8 @@
 			return -EINVAL;
 		}
 	} else if (ecmd->autoneg == AUTONEG_DISABLE) {
-		if (ecmd->speed != SPEED_10 && ecmd->speed != SPEED_100)
+		u32 speed = ethtool_cmd_speed(ecmd);
+		if (speed != SPEED_10 && speed != SPEED_100)
 			return -EINVAL;
 		if (ecmd->duplex != DUPLEX_HALF && ecmd->duplex != DUPLEX_FULL)
 			return -EINVAL;
@@ -2956,7 +2958,7 @@
 		if (ecmd->advertising & ADVERTISED_100baseT_Full)
 			np->advertising |= ADVERTISE_100FULL;
 	} else {
-		np->speed  = ecmd->speed;
+		np->speed  = ethtool_cmd_speed(ecmd);
 		np->duplex = ecmd->duplex;
 		/* user overriding the initial full duplex parm? */
 		if (np->duplex == DUPLEX_HALF)
diff -druN linux-2.6.39-libre/drivers/net/netconsole.c linux-3.0-rc7-libre/drivers/net/netconsole.c
--- linux-2.6.39-libre/drivers/net/netconsole.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/netconsole.c	2011-07-11 19:51:52.000000000 -0400
@@ -242,34 +242,6 @@
 }
 
 /*
- * Wrapper over simple_strtol (base 10) with sanity and range checking.
- * We return (signed) long only because we may want to return errors.
- * Do not use this to convert numbers that are allowed to be negative.
- */
-static long strtol10_check_range(const char *cp, long min, long max)
-{
-	long ret;
-	char *p = (char *) cp;
-
-	WARN_ON(min < 0);
-	WARN_ON(max < min);
-
-	ret = simple_strtol(p, &p, 10);
-
-	if (*p && (*p != '\n')) {
-		printk(KERN_ERR "netconsole: invalid input\n");
-		return -EINVAL;
-	}
-	if ((ret < min) || (ret > max)) {
-		printk(KERN_ERR "netconsole: input %ld must be between "
-				"%ld and %ld\n", ret, min, max);
-		return -EINVAL;
-	}
-
-	return ret;
-}
-
-/*
  * Attribute operations for netconsole_target.
  */
 
@@ -327,12 +299,14 @@
 			     const char *buf,
 			     size_t count)
 {
+	int enabled;
 	int err;
-	long enabled;
 
-	enabled = strtol10_check_range(buf, 0, 1);
-	if (enabled < 0)
-		return enabled;
+	err = kstrtoint(buf, 10, &enabled);
+	if (err < 0)
+		return err;
+	if (enabled < 0 || enabled > 1)
+		return -EINVAL;
 
 	if (enabled) {	/* 1 */
 
@@ -384,8 +358,7 @@
 				const char *buf,
 				size_t count)
 {
-	long local_port;
-#define __U16_MAX	((__u16) ~0U)
+	int rv;
 
 	if (nt->enabled) {
 		printk(KERN_ERR "netconsole: target (%s) is enabled, "
@@ -394,12 +367,9 @@
 		return -EINVAL;
 	}
 
-	local_port = strtol10_check_range(buf, 0, __U16_MAX);
-	if (local_port < 0)
-		return local_port;
-
-	nt->np.local_port = local_port;
-
+	rv = kstrtou16(buf, 10, &nt->np.local_port);
+	if (rv < 0)
+		return rv;
 	return strnlen(buf, count);
 }
 
@@ -407,8 +377,7 @@
 				 const char *buf,
 				 size_t count)
 {
-	long remote_port;
-#define __U16_MAX	((__u16) ~0U)
+	int rv;
 
 	if (nt->enabled) {
 		printk(KERN_ERR "netconsole: target (%s) is enabled, "
@@ -417,12 +386,9 @@
 		return -EINVAL;
 	}
 
-	remote_port = strtol10_check_range(buf, 0, __U16_MAX);
-	if (remote_port < 0)
-		return remote_port;
-
-	nt->np.remote_port = remote_port;
-
+	rv = kstrtou16(buf, 10, &nt->np.remote_port);
+	if (rv < 0)
+		return rv;
 	return strnlen(buf, count);
 }
 
@@ -463,8 +429,6 @@
 				size_t count)
 {
 	u8 remote_mac[ETH_ALEN];
-	char *p = (char *) buf;
-	int i;
 
 	if (nt->enabled) {
 		printk(KERN_ERR "netconsole: target (%s) is enabled, "
@@ -473,23 +437,13 @@
 		return -EINVAL;
 	}
 
-	for (i = 0; i < ETH_ALEN - 1; i++) {
-		remote_mac[i] = simple_strtoul(p, &p, 16);
-		if (*p != ':')
-			goto invalid;
-		p++;
-	}
-	remote_mac[ETH_ALEN - 1] = simple_strtoul(p, &p, 16);
-	if (*p && (*p != '\n'))
-		goto invalid;
-
+	if (!mac_pton(buf, remote_mac))
+		return -EINVAL;
+	if (buf[3 * ETH_ALEN - 1] && buf[3 * ETH_ALEN - 1] != '\n')
+		return -EINVAL;
 	memcpy(nt->np.remote_mac, remote_mac, ETH_ALEN);
 
 	return strnlen(buf, count);
-
-invalid:
-	printk(KERN_ERR "netconsole: invalid input\n");
-	return -EINVAL;
 }
 
 /*
@@ -667,11 +621,10 @@
 	bool stopped = false;
 
 	if (!(event == NETDEV_CHANGENAME || event == NETDEV_UNREGISTER ||
-	      event == NETDEV_BONDING_DESLAVE || event == NETDEV_GOING_DOWN))
+	      event == NETDEV_RELEASE || event == NETDEV_JOIN))
 		goto done;
 
 	spin_lock_irqsave(&target_list_lock, flags);
-restart:
 	list_for_each_entry(nt, &target_list, list) {
 		netconsole_target_get(nt);
 		if (nt->np.dev == dev) {
@@ -679,6 +632,8 @@
 			case NETDEV_CHANGENAME:
 				strlcpy(nt->np.dev_name, dev->name, IFNAMSIZ);
 				break;
+			case NETDEV_RELEASE:
+			case NETDEV_JOIN:
 			case NETDEV_UNREGISTER:
 				/*
 				 * rtnl_lock already held
@@ -693,11 +648,7 @@
 					dev_put(nt->np.dev);
 					nt->np.dev = NULL;
 					netconsole_target_put(nt);
-					goto restart;
 				}
-				/* Fall through */
-			case NETDEV_GOING_DOWN:
-			case NETDEV_BONDING_DESLAVE:
 				nt->enabled = 0;
 				stopped = true;
 				break;
@@ -706,10 +657,21 @@
 		netconsole_target_put(nt);
 	}
 	spin_unlock_irqrestore(&target_list_lock, flags);
-	if (stopped && (event == NETDEV_UNREGISTER || event == NETDEV_BONDING_DESLAVE))
+	if (stopped) {
 		printk(KERN_INFO "netconsole: network logging stopped on "
-			"interface %s as it %s\n",  dev->name,
-			event == NETDEV_UNREGISTER ? "unregistered" : "released slaves");
+		       "interface %s as it ", dev->name);
+		switch (event) {
+		case NETDEV_UNREGISTER:
+			printk(KERN_CONT "unregistered\n");
+			break;
+		case NETDEV_RELEASE:
+			printk(KERN_CONT "released slaves\n");
+			break;
+		case NETDEV_JOIN:
+			printk(KERN_CONT "is joining a master device\n");
+			break;
+		}
+	}
 
 done:
 	return NOTIFY_DONE;
diff -druN linux-2.6.39-libre/drivers/net/netxen/netxen_nic_ethtool.c linux-3.0-rc7-libre/drivers/net/netxen/netxen_nic_ethtool.c
--- linux-2.6.39-libre/drivers/net/netxen/netxen_nic_ethtool.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/netxen/netxen_nic_ethtool.c	2011-07-11 19:51:52.000000000 -0400
@@ -117,7 +117,7 @@
 
 		ecmd->port = PORT_TP;
 
-		ecmd->speed = adapter->link_speed;
+		ethtool_cmd_speed_set(ecmd, adapter->link_speed);
 		ecmd->duplex = adapter->link_duplex;
 		ecmd->autoneg = adapter->link_autoneg;
 
@@ -134,7 +134,7 @@
 		}
 
 		if (netif_running(dev) && adapter->has_link_events) {
-			ecmd->speed = adapter->link_speed;
+			ethtool_cmd_speed_set(ecmd, adapter->link_speed);
 			ecmd->autoneg = adapter->link_autoneg;
 			ecmd->duplex = adapter->link_duplex;
 			goto skip;
@@ -146,10 +146,10 @@
 			u16 pcifn = adapter->ahw.pci_func;
 
 			val = NXRD32(adapter, P3_LINK_SPEED_REG(pcifn));
-			ecmd->speed = P3_LINK_SPEED_MHZ *
-					P3_LINK_SPEED_VAL(pcifn, val);
+			ethtool_cmd_speed_set(ecmd, P3_LINK_SPEED_MHZ *
+					      P3_LINK_SPEED_VAL(pcifn, val));
 		} else
-			ecmd->speed = SPEED_10000;
+			ethtool_cmd_speed_set(ecmd, SPEED_10000);
 
 		ecmd->duplex = DUPLEX_FULL;
 		ecmd->autoneg = AUTONEG_DISABLE;
@@ -251,6 +251,7 @@
 netxen_nic_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
 {
 	struct netxen_adapter *adapter = netdev_priv(dev);
+	u32 speed = ethtool_cmd_speed(ecmd);
 	int ret;
 
 	if (adapter->ahw.port_type != NETXEN_NIC_GBE)
@@ -259,14 +260,14 @@
 	if (!(adapter->capabilities & NX_FW_CAPABILITY_GBE_LINK_CFG))
 		return -EOPNOTSUPP;
 
-	ret = nx_fw_cmd_set_gbe_port(adapter, ecmd->speed, ecmd->duplex,
+	ret = nx_fw_cmd_set_gbe_port(adapter, speed, ecmd->duplex,
 				     ecmd->autoneg);
 	if (ret == NX_RCODE_NOT_SUPPORTED)
 		return -EOPNOTSUPP;
 	else if (ret)
 		return -EIO;
 
-	adapter->link_speed = ecmd->speed;
+	adapter->link_speed = speed;
 	adapter->link_duplex = ecmd->duplex;
 	adapter->link_autoneg = ecmd->autoneg;
 
@@ -676,62 +677,6 @@
 	}
 }
 
-static u32 netxen_nic_get_tx_csum(struct net_device *dev)
-{
-	return dev->features & NETIF_F_IP_CSUM;
-}
-
-static u32 netxen_nic_get_rx_csum(struct net_device *dev)
-{
-	struct netxen_adapter *adapter = netdev_priv(dev);
-	return adapter->rx_csum;
-}
-
-static int netxen_nic_set_rx_csum(struct net_device *dev, u32 data)
-{
-	struct netxen_adapter *adapter = netdev_priv(dev);
-
-	if (data) {
-		adapter->rx_csum = data;
-		return 0;
-	}
-
-	if (dev->features & NETIF_F_LRO) {
-		if (netxen_config_hw_lro(adapter, NETXEN_NIC_LRO_DISABLED))
-			return -EIO;
-
-		dev->features &= ~NETIF_F_LRO;
-		netxen_send_lro_cleanup(adapter);
-		netdev_info(dev, "disabling LRO as rx_csum is off\n");
-	}
-	adapter->rx_csum = data;
-	return 0;
-}
-
-static u32 netxen_nic_get_tso(struct net_device *dev)
-{
-	struct netxen_adapter *adapter = netdev_priv(dev);
-
-	if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
-		return (dev->features & (NETIF_F_TSO | NETIF_F_TSO6)) != 0;
-
-	return (dev->features & NETIF_F_TSO) != 0;
-}
-
-static int netxen_nic_set_tso(struct net_device *dev, u32 data)
-{
-	if (data) {
-		struct netxen_adapter *adapter = netdev_priv(dev);
-
-		dev->features |= NETIF_F_TSO;
-		if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
-			dev->features |= NETIF_F_TSO6;
-	} else
-		dev->features &= ~(NETIF_F_TSO | NETIF_F_TSO6);
-
-	return 0;
-}
-
 static void
 netxen_nic_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
 {
@@ -866,43 +811,6 @@
 	return 0;
 }
 
-static int netxen_nic_set_flags(struct net_device *netdev, u32 data)
-{
-	struct netxen_adapter *adapter = netdev_priv(netdev);
-	int hw_lro;
-
-	if (ethtool_invalid_flags(netdev, data, ETH_FLAG_LRO))
-		return -EINVAL;
-
-	if (!(adapter->capabilities & NX_FW_CAPABILITY_HW_LRO))
-		return -EINVAL;
-
-	if (!adapter->rx_csum) {
-		netdev_info(netdev, "rx csum is off, cannot toggle LRO\n");
-		return -EINVAL;
-	}
-
-	if (!!(data & ETH_FLAG_LRO) == !!(netdev->features & NETIF_F_LRO))
-		return 0;
-
-	if (data & ETH_FLAG_LRO) {
-		hw_lro = NETXEN_NIC_LRO_ENABLED;
-		netdev->features |= NETIF_F_LRO;
-	} else {
-		hw_lro = NETXEN_NIC_LRO_DISABLED;
-		netdev->features &= ~NETIF_F_LRO;
-	}
-
-	if (netxen_config_hw_lro(adapter, hw_lro))
-		return -EIO;
-
-	if ((hw_lro == 0) && netxen_send_lro_cleanup(adapter))
-		return -EIO;
-
-
-	return 0;
-}
-
 const struct ethtool_ops netxen_nic_ethtool_ops = {
 	.get_settings = netxen_nic_get_settings,
 	.set_settings = netxen_nic_set_settings,
@@ -916,21 +824,12 @@
 	.set_ringparam = netxen_nic_set_ringparam,
 	.get_pauseparam = netxen_nic_get_pauseparam,
 	.set_pauseparam = netxen_nic_set_pauseparam,
-	.get_tx_csum = netxen_nic_get_tx_csum,
-	.set_tx_csum = ethtool_op_set_tx_csum,
-	.set_sg = ethtool_op_set_sg,
-	.get_tso = netxen_nic_get_tso,
-	.set_tso = netxen_nic_set_tso,
 	.get_wol = netxen_nic_get_wol,
 	.set_wol = netxen_nic_set_wol,
 	.self_test = netxen_nic_diag_test,
 	.get_strings = netxen_nic_get_strings,
 	.get_ethtool_stats = netxen_nic_get_ethtool_stats,
 	.get_sset_count = netxen_get_sset_count,
-	.get_rx_csum = netxen_nic_get_rx_csum,
-	.set_rx_csum = netxen_nic_set_rx_csum,
 	.get_coalesce = netxen_get_intr_coalesce,
 	.set_coalesce = netxen_set_intr_coalesce,
-	.get_flags = ethtool_op_get_flags,
-	.set_flags = netxen_nic_set_flags,
 };
diff -druN linux-2.6.39-libre/drivers/net/netxen/netxen_nic.h linux-3.0-rc7-libre/drivers/net/netxen/netxen_nic.h
--- linux-2.6.39-libre/drivers/net/netxen/netxen_nic.h	2011-05-19 02:12:08.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/netxen/netxen_nic.h	2011-07-21 06:54:37.000000000 -0400
@@ -1177,7 +1177,7 @@
 	u8 max_sds_rings;
 	u8 driver_mismatch;
 	u8 msix_supported;
-	u8 rx_csum;
+	u8 __pad;
 	u8 pci_using_dac;
 	u8 portnum;
 	u8 physical_port;
diff -druN linux-2.6.39-libre/drivers/net/netxen/netxen_nic_init.c linux-3.0-rc7-libre/drivers/net/netxen/netxen_nic_init.c
--- linux-2.6.39-libre/drivers/net/netxen/netxen_nic_init.c	2011-05-19 02:12:05.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/netxen/netxen_nic_init.c	2011-07-21 06:54:35.000000000 -0400
@@ -1483,7 +1483,8 @@
 	if (!skb)
 		goto no_skb;
 
-	if (likely(adapter->rx_csum && cksum == STATUS_CKSUM_OK)) {
+	if (likely((adapter->netdev->features & NETIF_F_RXCSUM)
+	    && cksum == STATUS_CKSUM_OK)) {
 		adapter->stats.csummed++;
 		skb->ip_summed = CHECKSUM_UNNECESSARY;
 	} else
diff -druN linux-2.6.39-libre/drivers/net/netxen/netxen_nic_main.c linux-3.0-rc7-libre/drivers/net/netxen/netxen_nic_main.c
--- linux-2.6.39-libre/drivers/net/netxen/netxen_nic_main.c	2011-05-19 02:12:11.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/netxen/netxen_nic_main.c	2011-07-21 06:54:40.000000000 -0400
@@ -485,6 +485,37 @@
 	adapter->set_multi(dev);
 }
 
+static u32 netxen_fix_features(struct net_device *dev, u32 features)
+{
+	if (!(features & NETIF_F_RXCSUM)) {
+		netdev_info(dev, "disabling LRO as RXCSUM is off\n");
+
+		features &= ~NETIF_F_LRO;
+	}
+
+	return features;
+}
+
+static int netxen_set_features(struct net_device *dev, u32 features)
+{
+	struct netxen_adapter *adapter = netdev_priv(dev);
+	int hw_lro;
+
+	if (!((dev->features ^ features) & NETIF_F_LRO))
+		return 0;
+
+	hw_lro = (features & NETIF_F_LRO) ? NETXEN_NIC_LRO_ENABLED
+	         : NETXEN_NIC_LRO_DISABLED;
+
+	if (netxen_config_hw_lro(adapter, hw_lro))
+		return -EIO;
+
+	if (!(features & NETIF_F_LRO) && netxen_send_lro_cleanup(adapter))
+		return -EIO;
+
+	return 0;
+}
+
 static const struct net_device_ops netxen_netdev_ops = {
 	.ndo_open	   = netxen_nic_open,
 	.ndo_stop	   = netxen_nic_close,
@@ -495,6 +526,8 @@
 	.ndo_set_mac_address    = netxen_nic_set_mac,
 	.ndo_change_mtu	   = netxen_nic_change_mtu,
 	.ndo_tx_timeout	   = netxen_tx_timeout,
+	.ndo_fix_features = netxen_fix_features,
+	.ndo_set_features = netxen_set_features,
 #ifdef CONFIG_NET_POLL_CONTROLLER
 	.ndo_poll_controller = netxen_nic_poll_controller,
 #endif
@@ -905,7 +938,7 @@
 	struct nx_host_sds_ring *sds_ring;
 	int err, ring;
 
-	unsigned long flags = IRQF_SAMPLE_RANDOM;
+	unsigned long flags = 0;
 	struct net_device *netdev = adapter->netdev;
 	struct netxen_recv_context *recv_ctx = &adapter->recv_ctx;
 
@@ -1196,7 +1229,6 @@
 	int err = 0;
 	struct pci_dev *pdev = adapter->pdev;
 
-	adapter->rx_csum = 1;
 	adapter->mc_enabled = 0;
 	if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
 		adapter->max_mc_count = 38;
@@ -1210,14 +1242,13 @@
 
 	SET_ETHTOOL_OPS(netdev, &netxen_nic_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->hw_features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO |
+	                      NETIF_F_RXCSUM;
 
-	if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) {
-		netdev->features |= (NETIF_F_IPV6_CSUM | NETIF_F_TSO6);
-		netdev->vlan_features |= (NETIF_F_IPV6_CSUM | NETIF_F_TSO6);
-	}
+	if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
+		netdev->hw_features |= NETIF_F_IPV6_CSUM | NETIF_F_TSO6;
+
+	netdev->vlan_features |= netdev->hw_features;
 
 	if (adapter->pci_using_dac) {
 		netdev->features |= NETIF_F_HIGHDMA;
@@ -1225,10 +1256,12 @@
 	}
 
 	if (adapter->capabilities & NX_FW_CAPABILITY_FVLANTX)
-		netdev->features |= (NETIF_F_HW_VLAN_TX);
+		netdev->hw_features |= NETIF_F_HW_VLAN_TX;
 
 	if (adapter->capabilities & NX_FW_CAPABILITY_HW_LRO)
-		netdev->features |= NETIF_F_LRO;
+		netdev->hw_features |= NETIF_F_LRO;
+
+	netdev->features |= netdev->hw_features;
 
 	netdev->irq = adapter->msix_entries[0].vector;
 
@@ -1932,11 +1965,11 @@
 
 	netxen_tso_check(netdev, tx_ring, first_desc, skb);
 
-	netxen_nic_update_cmd_producer(adapter, tx_ring);
-
 	adapter->stats.txbytes += skb->len;
 	adapter->stats.xmitcalled++;
 
+	netxen_nic_update_cmd_producer(adapter, tx_ring);
+
 	return NETDEV_TX_OK;
 
 drop_packet:
diff -druN linux-2.6.39-libre/drivers/net/niu.c linux-3.0-rc7-libre/drivers/net/niu.c
--- linux-2.6.39-libre/drivers/net/niu.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/niu.c	2011-07-11 19:51:52.000000000 -0400
@@ -1233,7 +1233,7 @@
 
 	bmsr = err;
 	if (bmsr & BMSR_LSTATUS) {
-		u16 adv, lpa, common, estat;
+		u16 adv, lpa;
 
 		err = mii_read(np, np->phy_addr, MII_ADVERTISE);
 		if (err < 0)
@@ -1245,12 +1245,9 @@
 			goto out;
 		lpa = err;
 
-		common = adv & lpa;
-
 		err = mii_read(np, np->phy_addr, MII_ESTATUS);
 		if (err < 0)
 			goto out;
-		estat = err;
 		link_up = 1;
 		current_speed = SPEED_1000;
 		current_duplex = DUPLEX_FULL;
@@ -1650,7 +1647,7 @@
 		break;
 	}
 
-	return 0;
+	return err;
 }
 
 static int mii_reset(struct niu *np)
@@ -2381,17 +2378,14 @@
 	struct niu_link_config *lp = &np->link_config;
 	unsigned long ctrl_reg, test_cfg_reg, pll_cfg, i;
 	u64 ctrl_val, test_cfg_val, sig, mask, val;
-	u64 reset_val;
 
 	switch (np->port) {
 	case 0:
-		reset_val =  ENET_SERDES_RESET_0;
 		ctrl_reg = ENET_SERDES_0_CTRL_CFG;
 		test_cfg_reg = ENET_SERDES_0_TEST_CFG;
 		pll_cfg = ENET_SERDES_0_PLL_CFG;
 		break;
 	case 1:
-		reset_val =  ENET_SERDES_RESET_1;
 		ctrl_reg = ENET_SERDES_1_CTRL_CFG;
 		test_cfg_reg = ENET_SERDES_1_TEST_CFG;
 		pll_cfg = ENET_SERDES_1_PLL_CFG;
@@ -6071,8 +6065,7 @@
 	for (i = 0; i < np->num_ldg; i++) {
 		struct niu_ldg *lp = &np->ldg[i];
 
-		err = request_irq(lp->irq, niu_interrupt,
-				  IRQF_SHARED | IRQF_SAMPLE_RANDOM,
+		err = request_irq(lp->irq, niu_interrupt, IRQF_SHARED,
 				  np->irq_name[i], lp);
 		if (err)
 			goto out_free_irqs;
@@ -6851,7 +6844,7 @@
 	cmd->supported = lp->supported;
 	cmd->advertising = lp->active_advertising;
 	cmd->autoneg = lp->active_autoneg;
-	cmd->speed = lp->active_speed;
+	ethtool_cmd_speed_set(cmd, lp->active_speed);
 	cmd->duplex = lp->active_duplex;
 	cmd->port = (np->flags & NIU_FLAGS_FIBER) ? PORT_FIBRE : PORT_TP;
 	cmd->transceiver = (np->flags & NIU_FLAGS_XCVR_SERDES) ?
@@ -6866,7 +6859,7 @@
 	struct niu_link_config *lp = &np->link_config;
 
 	lp->advertising = cmd->advertising;
-	lp->speed = cmd->speed;
+	lp->speed = ethtool_cmd_speed(cmd);
 	lp->duplex = cmd->duplex;
 	lp->autoneg = cmd->autoneg;
 	return niu_init_link(np);
@@ -7023,6 +7016,7 @@
 	case UDP_V4_FLOW:
 		*class = CLASS_CODE_UDP_IPV4;
 		break;
+	case AH_ESP_V4_FLOW:
 	case AH_V4_FLOW:
 	case ESP_V4_FLOW:
 		*class = CLASS_CODE_AH_ESP_IPV4;
@@ -7036,6 +7030,7 @@
 	case UDP_V6_FLOW:
 		*class = CLASS_CODE_UDP_IPV6;
 		break;
+	case AH_ESP_V6_FLOW:
 	case AH_V6_FLOW:
 	case ESP_V6_FLOW:
 		*class = CLASS_CODE_AH_ESP_IPV6;
@@ -7889,37 +7884,35 @@
 	nw64_mac(reg, val);
 }
 
-static int niu_phys_id(struct net_device *dev, u32 data)
+static int niu_set_phys_id(struct net_device *dev,
+			   enum ethtool_phys_id_state state)
+
 {
 	struct niu *np = netdev_priv(dev);
-	u64 orig_led_state;
-	int i;
 
 	if (!netif_running(dev))
 		return -EAGAIN;
 
-	if (data == 0)
-		data = 2;
+	switch (state) {
+	case ETHTOOL_ID_ACTIVE:
+		np->orig_led_state = niu_led_state_save(np);
+		return 1;	/* cycle on/off once per second */
 
-	orig_led_state = niu_led_state_save(np);
-	for (i = 0; i < (data * 2); i++) {
-		int on = ((i % 2) == 0);
+	case ETHTOOL_ID_ON:
+		niu_force_led(np, 1);
+		break;
 
-		niu_force_led(np, on);
+	case ETHTOOL_ID_OFF:
+		niu_force_led(np, 0);
+		break;
 
-		if (msleep_interruptible(500))
-			break;
+	case ETHTOOL_ID_INACTIVE:
+		niu_led_state_restore(np, np->orig_led_state);
 	}
-	niu_led_state_restore(np, orig_led_state);
 
 	return 0;
 }
 
-static int niu_set_flags(struct net_device *dev, u32 data)
-{
-	return ethtool_op_set_flags(dev, data, ETH_FLAG_RXHASH);
-}
-
 static const struct ethtool_ops niu_ethtool_ops = {
 	.get_drvinfo		= niu_get_drvinfo,
 	.get_link		= ethtool_op_get_link,
@@ -7933,11 +7926,9 @@
 	.get_strings		= niu_get_strings,
 	.get_sset_count		= niu_get_sset_count,
 	.get_ethtool_stats	= niu_get_ethtool_stats,
-	.phys_id		= niu_phys_id,
+	.set_phys_id		= niu_set_phys_id,
 	.get_rxnfc		= niu_get_nfc,
 	.set_rxnfc		= niu_set_nfc,
-	.set_flags		= niu_set_flags,
-	.get_flags		= ethtool_op_get_flags,
 };
 
 static int niu_ldg_assign_ldn(struct niu *np, struct niu_parent *parent,
@@ -8131,7 +8122,7 @@
 	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;
+		int len, err, prop_len;
 		char namebuf[64];
 		u8 *prop_buf;
 		int max_len;
@@ -8147,8 +8138,6 @@
 		len = err;
 		start += 3;
 
-		instance = niu_pci_eeprom_read(np, start);
-		type = niu_pci_eeprom_read(np, start + 3);
 		prop_len = niu_pci_eeprom_read(np, start + 4);
 		err = niu_pci_vpd_get_propname(np, start + 5, namebuf, 64);
 		if (err < 0)
@@ -9768,8 +9757,8 @@
 
 static void __devinit niu_set_basic_features(struct net_device *dev)
 {
-	dev->features |= (NETIF_F_SG | NETIF_F_HW_CSUM |
-			  NETIF_F_GRO | NETIF_F_RXHASH);
+	dev->hw_features = NETIF_F_SG | NETIF_F_HW_CSUM | NETIF_F_RXHASH;
+	dev->features |= dev->hw_features | NETIF_F_RXCSUM;
 }
 
 static int __devinit niu_pci_init_one(struct pci_dev *pdev,
diff -druN linux-2.6.39-libre/drivers/net/niu.h linux-3.0-rc7-libre/drivers/net/niu.h
--- linux-2.6.39-libre/drivers/net/niu.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/niu.h	2011-07-11 19:51:52.000000000 -0400
@@ -3279,6 +3279,7 @@
 	unsigned long			xpcs_off;
 
 	struct timer_list		timer;
+	u64				orig_led_state;
 	const struct niu_phy_ops	*phy_ops;
 	int				phy_addr;
 
diff -druN linux-2.6.39-libre/drivers/net/ns83820.c linux-3.0-rc7-libre/drivers/net/ns83820.c
--- linux-2.6.39-libre/drivers/net/ns83820.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/ns83820.c	2011-07-11 19:51:52.000000000 -0400
@@ -1251,7 +1251,7 @@
 	/*
 	 * Here's the list of available ethtool commands from other drivers:
 	 *	cmd->advertising =
-	 *	cmd->speed =
+	 *	ethtool_cmd_speed_set(cmd, ...)
 	 *	cmd->duplex =
 	 *	cmd->port = 0;
 	 *	cmd->phy_address =
@@ -1289,13 +1289,13 @@
 	cmd->duplex = fullduplex ? DUPLEX_FULL : DUPLEX_HALF;
 	switch (cfg / CFG_SPDSTS0 & 3) {
 	case 2:
-		cmd->speed = SPEED_1000;
+		ethtool_cmd_speed_set(cmd, SPEED_1000);
 		break;
 	case 1:
-		cmd->speed = SPEED_100;
+		ethtool_cmd_speed_set(cmd, SPEED_100);
 		break;
 	default:
-		cmd->speed = SPEED_10;
+		ethtool_cmd_speed_set(cmd, SPEED_10);
 		break;
 	}
 	cmd->autoneg = (tbicr & TBICR_MR_AN_ENABLE)
diff -druN linux-2.6.39-libre/drivers/net/pasemi_mac.c linux-3.0-rc7-libre/drivers/net/pasemi_mac.c
--- linux-2.6.39-libre/drivers/net/pasemi_mac.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/pasemi_mac.c	2011-07-11 19:51:52.000000000 -0400
@@ -35,6 +35,7 @@
 #include <linux/tcp.h>
 #include <net/checksum.h>
 #include <linux/inet_lro.h>
+#include <linux/prefetch.h>
 
 #include <asm/irq.h>
 #include <asm/firmware.h>
diff -druN linux-2.6.39-libre/drivers/net/pch_gbe/pch_gbe_ethtool.c linux-3.0-rc7-libre/drivers/net/pch_gbe/pch_gbe_ethtool.c
--- linux-2.6.39-libre/drivers/net/pch_gbe/pch_gbe_ethtool.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/pch_gbe/pch_gbe_ethtool.c	2011-07-11 19:51:52.000000000 -0400
@@ -92,7 +92,7 @@
 	ecmd->advertising &= ~(ADVERTISED_TP | ADVERTISED_1000baseT_Half);
 
 	if (!netif_carrier_ok(adapter->netdev))
-		ecmd->speed = -1;
+		ethtool_cmd_speed_set(ecmd, -1);
 	return ret;
 }
 
@@ -109,12 +109,15 @@
 {
 	struct pch_gbe_adapter *adapter = netdev_priv(netdev);
 	struct pch_gbe_hw *hw = &adapter->hw;
+	u32 speed = ethtool_cmd_speed(ecmd);
 	int ret;
 
 	pch_gbe_hal_write_phy_reg(hw, MII_BMCR, BMCR_RESET);
 
-	if (ecmd->speed == USHRT_MAX) {
-		ecmd->speed = SPEED_1000;
+	/* when set_settings() is called with a ethtool_cmd previously
+	 * filled by get_settings() on a down link, speed is -1: */
+	if (speed == UINT_MAX) {
+		speed = SPEED_1000;
 		ecmd->duplex = DUPLEX_FULL;
 	}
 	ret = mii_ethtool_sset(&adapter->mii, ecmd);
@@ -122,7 +125,7 @@
 		pr_err("Error: mii_ethtool_sset\n");
 		return ret;
 	}
-	hw->mac.link_speed = ecmd->speed;
+	hw->mac.link_speed = speed;
 	hw->mac.link_duplex = ecmd->duplex;
 	hw->phy.autoneg_advertised = ecmd->advertising;
 	hw->mac.autoneg = ecmd->autoneg;
@@ -434,57 +437,6 @@
 }
 
 /**
- * pch_gbe_get_rx_csum - Report whether receive checksums are turned on or off
- * @netdev:  Network interface device structure
- * Returns
- *	true(1):  Checksum On
- *	false(0): Checksum Off
- */
-static u32 pch_gbe_get_rx_csum(struct net_device *netdev)
-{
-	struct pch_gbe_adapter *adapter = netdev_priv(netdev);
-
-	return adapter->rx_csum;
-}
-
-/**
- * pch_gbe_set_rx_csum - Turn receive checksum on or off
- * @netdev:  Network interface device structure
- * @data:    Checksum On[true] or Off[false]
- * Returns
- *	0:			Successful.
- *	Negative value:		Failed.
- */
-static int pch_gbe_set_rx_csum(struct net_device *netdev, u32 data)
-{
-	struct pch_gbe_adapter *adapter = netdev_priv(netdev);
-
-	adapter->rx_csum = data;
-	if ((netif_running(netdev)))
-		pch_gbe_reinit_locked(adapter);
-	else
-		pch_gbe_reset(adapter);
-
-	return 0;
-}
-
-/**
- * pch_gbe_set_tx_csum - Turn transmit checksums on or off
- * @netdev: Network interface device structure
- * @data:   Checksum on[true] or off[false]
- * Returns
- *	0:			Successful.
- *	Negative value:		Failed.
- */
-static int pch_gbe_set_tx_csum(struct net_device *netdev, u32 data)
-{
-	struct pch_gbe_adapter *adapter = netdev_priv(netdev);
-
-	adapter->tx_csum = data;
-	return ethtool_op_set_tx_ipv6_csum(netdev, data);
-}
-
-/**
  * pch_gbe_get_strings - Return a set of strings that describe the requested
  *			 objects
  * @netdev:    Network interface device structure
@@ -554,9 +506,6 @@
 	.set_ringparam = pch_gbe_set_ringparam,
 	.get_pauseparam = pch_gbe_get_pauseparam,
 	.set_pauseparam = pch_gbe_set_pauseparam,
-	.get_rx_csum = pch_gbe_get_rx_csum,
-	.set_rx_csum = pch_gbe_set_rx_csum,
-	.set_tx_csum = pch_gbe_set_tx_csum,
 	.get_strings = pch_gbe_get_strings,
 	.get_ethtool_stats = pch_gbe_get_ethtool_stats,
 	.get_sset_count = pch_gbe_get_sset_count,
diff -druN linux-2.6.39-libre/drivers/net/pch_gbe/pch_gbe.h linux-3.0-rc7-libre/drivers/net/pch_gbe/pch_gbe.h
--- linux-2.6.39-libre/drivers/net/pch_gbe/pch_gbe.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/pch_gbe/pch_gbe.h	2011-07-11 19:51:52.000000000 -0400
@@ -597,8 +597,6 @@
  * @rx_ring:		Pointer of Rx descriptor ring structure
  * @rx_buffer_len:	Receive buffer length
  * @tx_queue_len:	Transmit queue length
- * @rx_csum:		Receive TCP/IP checksum enable/disable
- * @tx_csum:		Transmit TCP/IP checksum enable/disable
  * @have_msi:		PCI MSI mode flag
  */
 
@@ -623,8 +621,6 @@
 	struct pch_gbe_rx_ring *rx_ring;
 	unsigned long rx_buffer_len;
 	unsigned long tx_queue_len;
-	bool rx_csum;
-	bool tx_csum;
 	bool have_msi;
 };
 
diff -druN linux-2.6.39-libre/drivers/net/pch_gbe/pch_gbe_main.c linux-3.0-rc7-libre/drivers/net/pch_gbe/pch_gbe_main.c
--- linux-2.6.39-libre/drivers/net/pch_gbe/pch_gbe_main.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/pch_gbe/pch_gbe_main.c	2011-07-11 19:51:52.000000000 -0400
@@ -20,6 +20,7 @@
 
 #include "pch_gbe.h"
 #include "pch_gbe_api.h"
+#include <linux/prefetch.h>
 
 #define DRV_VERSION     "1.00"
 const char pch_driver_version[] = DRV_VERSION;
@@ -659,6 +660,7 @@
  */
 static void pch_gbe_setup_rctl(struct pch_gbe_adapter *adapter)
 {
+	struct net_device *netdev = adapter->netdev;
 	struct pch_gbe_hw *hw = &adapter->hw;
 	u32 rx_mode, tcpip;
 
@@ -669,7 +671,7 @@
 
 	tcpip = ioread32(&hw->reg->TCPIP_ACC);
 
-	if (adapter->rx_csum) {
+	if (netdev->features & NETIF_F_RXCSUM) {
 		tcpip &= ~PCH_GBE_RX_TCPIPACC_OFF;
 		tcpip |= PCH_GBE_RX_TCPIPACC_EN;
 	} else {
@@ -890,12 +892,12 @@
 	struct pch_gbe_adapter *adapter = (struct pch_gbe_adapter *)data;
 	struct net_device *netdev = adapter->netdev;
 	struct pch_gbe_hw *hw = &adapter->hw;
-	struct ethtool_cmd cmd;
 
 	pr_debug("right now = %ld\n", jiffies);
 
 	pch_gbe_update_stats(adapter);
 	if ((mii_link_ok(&adapter->mii)) && (!netif_carrier_ok(netdev))) {
+		struct ethtool_cmd cmd = { .cmd = ETHTOOL_GSET };
 		netdev->tx_queue_len = adapter->tx_queue_len;
 		/* mii library handles link maintenance tasks */
 		if (mii_ethtool_gset(&adapter->mii, &cmd)) {
@@ -905,7 +907,7 @@
 						PCH_GBE_WATCHDOG_PERIOD));
 			return;
 		}
-		hw->mac.link_speed = cmd.speed;
+		hw->mac.link_speed = ethtool_cmd_speed(&cmd);
 		hw->mac.link_duplex = cmd.duplex;
 		/* Set the RGMII control. */
 		pch_gbe_set_rgmii_ctrl(adapter, hw->mac.link_speed,
@@ -915,7 +917,7 @@
 				 hw->mac.link_duplex);
 		netdev_dbg(netdev,
 			   "Link is Up %d Mbps %s-Duplex\n",
-			   cmd.speed,
+			   hw->mac.link_speed,
 			   cmd.duplex == DUPLEX_FULL ? "Full" : "Half");
 		netif_carrier_on(netdev);
 		netif_wake_queue(netdev);
@@ -953,7 +955,7 @@
 	frame_ctrl = 0;
 	if (unlikely(skb->len < PCH_GBE_SHORT_PKT))
 		frame_ctrl |= PCH_GBE_TXD_CTRL_APAD;
-	if (unlikely(!adapter->tx_csum))
+	if (skb->ip_summed == CHECKSUM_NONE)
 		frame_ctrl |= PCH_GBE_TXD_CTRL_TCPIP_ACC_OFF;
 
 	/* Performs checksum processing */
@@ -961,7 +963,7 @@
 	 * It is because the hardware accelerator does not support a checksum,
 	 * when the received data size is less than 64 bytes.
 	 */
-	if ((skb->len < PCH_GBE_SHORT_PKT) && (adapter->tx_csum)) {
+	if (skb->len < PCH_GBE_SHORT_PKT && skb->ip_summed != CHECKSUM_NONE) {
 		frame_ctrl |= PCH_GBE_TXD_CTRL_APAD |
 			      PCH_GBE_TXD_CTRL_TCPIP_ACC_OFF;
 		if (skb->protocol == htons(ETH_P_IP)) {
@@ -1429,7 +1431,7 @@
 			length = (rx_desc->rx_words_eob) - 3;
 
 			/* Decide the data conversion method */
-			if (!adapter->rx_csum) {
+			if (!(netdev->features & NETIF_F_RXCSUM)) {
 				/* [Header:14][payload] */
 				if (NET_IP_ALIGN) {
 					/* Because alignment differs,
@@ -2032,6 +2034,29 @@
 }
 
 /**
+ * pch_gbe_set_features - Reset device after features changed
+ * @netdev:   Network interface device structure
+ * @features:  New features
+ * Returns
+ *	0:		HW state updated successfully
+ */
+static int pch_gbe_set_features(struct net_device *netdev, u32 features)
+{
+	struct pch_gbe_adapter *adapter = netdev_priv(netdev);
+	u32 changed = features ^ netdev->features;
+
+	if (!(changed & NETIF_F_RXCSUM))
+		return 0;
+
+	if (netif_running(netdev))
+		pch_gbe_reinit_locked(adapter);
+	else
+		pch_gbe_reset(adapter);
+
+	return 0;
+}
+
+/**
  * pch_gbe_ioctl - Controls register through a MII interface
  * @netdev:   Network interface device structure
  * @ifr:      Pointer to ifr structure
@@ -2131,6 +2156,7 @@
 	.ndo_set_mac_address = pch_gbe_set_mac,
 	.ndo_tx_timeout = pch_gbe_tx_timeout,
 	.ndo_change_mtu = pch_gbe_change_mtu,
+	.ndo_set_features = pch_gbe_set_features,
 	.ndo_do_ioctl = pch_gbe_ioctl,
 	.ndo_set_multicast_list = &pch_gbe_set_multi,
 #ifdef CONFIG_NET_POLL_CONTROLLER
@@ -2336,7 +2362,9 @@
 	netdev->watchdog_timeo = PCH_GBE_WATCHDOG_PERIOD;
 	netif_napi_add(netdev, &adapter->napi,
 		       pch_gbe_napi_poll, PCH_GBE_RX_WEIGHT);
-	netdev->features = NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | NETIF_F_GRO;
+	netdev->hw_features = NETIF_F_RXCSUM |
+		NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;
+	netdev->features = netdev->hw_features;
 	pch_gbe_set_ethtool_ops(netdev);
 
 	pch_gbe_mac_load_mac_addr(&adapter->hw);
@@ -2375,11 +2403,6 @@
 
 	pch_gbe_check_options(adapter);
 
-	if (adapter->tx_csum)
-		netdev->features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;
-	else
-		netdev->features &= ~(NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM);
-
 	/* initialize the wol settings based on the eeprom settings */
 	adapter->wake_up_evt = PCH_GBE_WL_INIT_SETTING;
 	dev_info(&pdev->dev, "MAC address : %pM\n", netdev->dev_addr);
diff -druN linux-2.6.39-libre/drivers/net/pch_gbe/pch_gbe_param.c linux-3.0-rc7-libre/drivers/net/pch_gbe/pch_gbe_param.c
--- linux-2.6.39-libre/drivers/net/pch_gbe/pch_gbe_param.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/pch_gbe/pch_gbe_param.c	2011-07-11 19:51:52.000000000 -0400
@@ -426,6 +426,8 @@
 void pch_gbe_check_options(struct pch_gbe_adapter *adapter)
 {
 	struct pch_gbe_hw *hw = &adapter->hw;
+	struct net_device *dev = adapter->netdev;
+	int val;
 
 	{ /* Transmit Descriptor Count */
 		static const struct pch_gbe_option opt = {
@@ -466,9 +468,10 @@
 			.err  = "defaulting to Enabled",
 			.def  = PCH_GBE_DEFAULT_RX_CSUM
 		};
-		adapter->rx_csum = XsumRX;
-		pch_gbe_validate_option((int *)(&adapter->rx_csum),
-					&opt, adapter);
+		val = XsumRX;
+		pch_gbe_validate_option(&val, &opt, adapter);
+		if (!val)
+			dev->features &= ~NETIF_F_RXCSUM;
 	}
 	{ /* Checksum Offload Enable/Disable */
 		static const struct pch_gbe_option opt = {
@@ -477,9 +480,10 @@
 			.err  = "defaulting to Enabled",
 			.def  = PCH_GBE_DEFAULT_TX_CSUM
 		};
-		adapter->tx_csum = XsumTX;
-		pch_gbe_validate_option((int *)(&adapter->tx_csum),
-						&opt, adapter);
+		val = XsumTX;
+		pch_gbe_validate_option(&val, &opt, adapter);
+		if (!val)
+			dev->features &= ~NETIF_F_ALL_CSUM;
 	}
 	{ /* Flow Control */
 		static const struct pch_gbe_option opt = {
diff -druN linux-2.6.39-libre/drivers/net/pch_gbe/pch_gbe_phy.c linux-3.0-rc7-libre/drivers/net/pch_gbe/pch_gbe_phy.c
--- linux-2.6.39-libre/drivers/net/pch_gbe/pch_gbe_phy.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/pch_gbe/pch_gbe_phy.c	2011-07-11 19:51:52.000000000 -0400
@@ -247,7 +247,7 @@
 void pch_gbe_phy_init_setting(struct pch_gbe_hw *hw)
 {
 	struct pch_gbe_adapter *adapter;
-	struct ethtool_cmd     cmd;
+	struct ethtool_cmd     cmd = { .cmd = ETHTOOL_GSET };
 	int ret;
 	u16 mii_reg;
 
@@ -256,7 +256,7 @@
 	if (ret)
 		pr_err("Error: mii_ethtool_gset\n");
 
-	cmd.speed = hw->mac.link_speed;
+	ethtool_cmd_speed_set(&cmd, hw->mac.link_speed);
 	cmd.duplex = hw->mac.link_duplex;
 	cmd.advertising = hw->phy.autoneg_advertised;
 	cmd.autoneg = hw->mac.autoneg;
diff -druN linux-2.6.39-libre/drivers/net/pcmcia/3c574_cs.c linux-3.0-rc7-libre/drivers/net/pcmcia/3c574_cs.c
--- linux-2.6.39-libre/drivers/net/pcmcia/3c574_cs.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/pcmcia/3c574_cs.c	2011-07-11 19:51:52.000000000 -0400
@@ -1150,7 +1150,7 @@
 	return 0;
 }
 
-static struct pcmcia_device_id tc574_ids[] = {
+static const struct pcmcia_device_id tc574_ids[] = {
 	PCMCIA_DEVICE_MANF_CARD(0x0101, 0x0574),
 	PCMCIA_MFC_DEVICE_CIS_MANF_CARD(0, 0x0101, 0x0556, "cis/3CCFEM556.cis"),
 	PCMCIA_DEVICE_NULL,
diff -druN linux-2.6.39-libre/drivers/net/pcmcia/3c589_cs.c linux-3.0-rc7-libre/drivers/net/pcmcia/3c589_cs.c
--- linux-2.6.39-libre/drivers/net/pcmcia/3c589_cs.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/pcmcia/3c589_cs.c	2011-07-11 19:51:52.000000000 -0400
@@ -908,7 +908,7 @@
     return 0;
 }
 
-static struct pcmcia_device_id tc589_ids[] = {
+static const struct pcmcia_device_id tc589_ids[] = {
 	PCMCIA_MFC_DEVICE_MANF_CARD(0, 0x0101, 0x0562),
 	PCMCIA_MFC_DEVICE_PROD_ID1(0, "Motorola MARQUIS", 0xf03e4e77),
 	PCMCIA_DEVICE_MANF_CARD(0x0101, 0x0589),
diff -druN linux-2.6.39-libre/drivers/net/pcmcia/axnet_cs.c linux-3.0-rc7-libre/drivers/net/pcmcia/axnet_cs.c
--- linux-2.6.39-libre/drivers/net/pcmcia/axnet_cs.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/pcmcia/axnet_cs.c	2011-07-11 19:51:52.000000000 -0400
@@ -687,7 +687,7 @@
     outsw(nic_base + AXNET_DATAPORT, buf, count>>1);
 }
 
-static struct pcmcia_device_id axnet_ids[] = {
+static const struct pcmcia_device_id axnet_ids[] = {
 	PCMCIA_PFC_DEVICE_MANF_CARD(0, 0x016c, 0x0081),
 	PCMCIA_DEVICE_MANF_CARD(0x018a, 0x0301),
 	PCMCIA_DEVICE_MANF_CARD(0x01bf, 0x2328),
diff -druN linux-2.6.39-libre/drivers/net/pcmcia/com20020_cs.c linux-3.0-rc7-libre/drivers/net/pcmcia/com20020_cs.c
--- linux-2.6.39-libre/drivers/net/pcmcia/com20020_cs.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/pcmcia/com20020_cs.c	2011-07-11 19:51:52.000000000 -0400
@@ -316,7 +316,7 @@
 	return 0;
 }
 
-static struct pcmcia_device_id com20020_ids[] = {
+static const struct pcmcia_device_id com20020_ids[] = {
 	PCMCIA_DEVICE_PROD_ID12("Contemporary Control Systems, Inc.",
 			"PCM20 Arcnet Adapter", 0x59991666, 0x95dfffaf),
 	PCMCIA_DEVICE_PROD_ID12("SoHard AG",
diff -druN linux-2.6.39-libre/drivers/net/pcmcia/fmvj18x_cs.c linux-3.0-rc7-libre/drivers/net/pcmcia/fmvj18x_cs.c
--- linux-2.6.39-libre/drivers/net/pcmcia/fmvj18x_cs.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/pcmcia/fmvj18x_cs.c	2011-07-11 19:51:52.000000000 -0400
@@ -667,7 +667,7 @@
 
 /*====================================================================*/
 
-static struct pcmcia_device_id fmvj18x_ids[] = {
+static const struct pcmcia_device_id fmvj18x_ids[] = {
 	PCMCIA_DEVICE_MANF_CARD(0x0004, 0x0004),
 	PCMCIA_DEVICE_PROD_ID12("EAGLE Technology", "NE200 ETHERNET LAN MBH10302 04", 0x528c88c4, 0x74f91e59),
 	PCMCIA_DEVICE_PROD_ID12("Eiger Labs,Inc", "EPX-10BT PC Card Ethernet 10BT", 0x53af556e, 0x877f9922),
diff -druN linux-2.6.39-libre/drivers/net/pcmcia/ibmtr_cs.c linux-3.0-rc7-libre/drivers/net/pcmcia/ibmtr_cs.c
--- linux-2.6.39-libre/drivers/net/pcmcia/ibmtr_cs.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/pcmcia/ibmtr_cs.c	2011-07-11 19:51:52.000000000 -0400
@@ -340,7 +340,7 @@
     outb(0x40, dev->base_addr);
 }
 
-static struct pcmcia_device_id ibmtr_ids[] = {
+static const struct pcmcia_device_id ibmtr_ids[] = {
 	PCMCIA_DEVICE_PROD_ID12("3Com", "TokenLink Velocity PC Card", 0x41240e5b, 0x82c3734e),
 	PCMCIA_DEVICE_PROD_ID12("IBM", "TOKEN RING", 0xb569a6e5, 0xbf8eed47),
 	PCMCIA_DEVICE_NULL,
diff -druN linux-2.6.39-libre/drivers/net/pcmcia/nmclan_cs.c linux-3.0-rc7-libre/drivers/net/pcmcia/nmclan_cs.c
--- linux-2.6.39-libre/drivers/net/pcmcia/nmclan_cs.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/pcmcia/nmclan_cs.c	2011-07-11 19:51:52.000000000 -0400
@@ -1494,7 +1494,7 @@
 
 } /* set_multicast_list */
 
-static struct pcmcia_device_id nmclan_ids[] = {
+static const struct pcmcia_device_id nmclan_ids[] = {
 	PCMCIA_DEVICE_PROD_ID12("New Media Corporation", "Ethernet", 0x085a850b, 0x00b2e941),
 	PCMCIA_DEVICE_PROD_ID12("Portable Add-ons", "Ethernet+", 0xebf1d60, 0xad673aaf),
 	PCMCIA_DEVICE_NULL,
diff -druN linux-2.6.39-libre/drivers/net/pcmcia/pcnet_cs.c linux-3.0-rc7-libre/drivers/net/pcmcia/pcnet_cs.c
--- linux-2.6.39-libre/drivers/net/pcmcia/pcnet_cs.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/pcmcia/pcnet_cs.c	2011-07-11 19:51:52.000000000 -0400
@@ -1463,7 +1463,7 @@
 
 /*====================================================================*/
 
-static struct pcmcia_device_id pcnet_ids[] = {
+static const struct pcmcia_device_id pcnet_ids[] = {
 	PCMCIA_PFC_DEVICE_MANF_CARD(0, 0x0057, 0x0021),
 	PCMCIA_PFC_DEVICE_MANF_CARD(0, 0x0104, 0x000a),
 	PCMCIA_PFC_DEVICE_MANF_CARD(0, 0x0105, 0xea15),
diff -druN linux-2.6.39-libre/drivers/net/pcmcia/smc91c92_cs.c linux-3.0-rc7-libre/drivers/net/pcmcia/smc91c92_cs.c
--- linux-2.6.39-libre/drivers/net/pcmcia/smc91c92_cs.c	2011-05-19 02:13:03.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/pcmcia/smc91c92_cs.c	2011-07-21 06:55:31.000000000 -0400
@@ -1860,7 +1860,7 @@
     tmp = inw(ioaddr + CONFIG);
     ecmd->port = (tmp & CFG_AUI_SELECT) ? PORT_AUI : PORT_TP;
     ecmd->transceiver = XCVR_INTERNAL;
-    ecmd->speed = SPEED_10;
+    ethtool_cmd_speed_set(ecmd, SPEED_10);
     ecmd->phy_address = ioaddr + MGMT;
 
     SMC_SELECT_BANK(0);
@@ -1875,8 +1875,8 @@
     u16 tmp;
     unsigned int ioaddr = dev->base_addr;
 
-    if (ecmd->speed != SPEED_10)
-    	return -EINVAL;
+    if (ethtool_cmd_speed(ecmd) != SPEED_10)
+	return -EINVAL;
     if (ecmd->duplex != DUPLEX_HALF && ecmd->duplex != DUPLEX_FULL)
     	return -EINVAL;
     if (ecmd->port != PORT_TP && ecmd->port != PORT_AUI)
@@ -2014,7 +2014,7 @@
 	return rc;
 }
 
-static struct pcmcia_device_id smc91c92_ids[] = {
+static const struct pcmcia_device_id smc91c92_ids[] = {
 	PCMCIA_PFC_DEVICE_MANF_CARD(0, 0x0109, 0x0501),
 	PCMCIA_PFC_DEVICE_MANF_CARD(0, 0x0140, 0x000a),
 	PCMCIA_PFC_DEVICE_PROD_ID123(0, "MEGAHERTZ", "CC/XJEM3288", "DATA/FAX/CELL ETHERNET MODEM", 0xf510db04, 0x04cd2988, 0x46a52d63),
diff -druN linux-2.6.39-libre/drivers/net/pcmcia/xirc2ps_cs.c linux-3.0-rc7-libre/drivers/net/pcmcia/xirc2ps_cs.c
--- linux-2.6.39-libre/drivers/net/pcmcia/xirc2ps_cs.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/pcmcia/xirc2ps_cs.c	2011-07-11 19:51:52.000000000 -0400
@@ -1738,7 +1738,7 @@
     return 0;
 }
 
-static struct pcmcia_device_id xirc2ps_ids[] = {
+static const struct pcmcia_device_id xirc2ps_ids[] = {
 	PCMCIA_PFC_DEVICE_MANF_CARD(0, 0x0089, 0x110a),
 	PCMCIA_PFC_DEVICE_MANF_CARD(0, 0x0138, 0x110a),
 	PCMCIA_PFC_DEVICE_PROD_ID13(0, "Xircom", "CEM28", 0x2e3ee845, 0x0ea978ea),
diff -druN linux-2.6.39-libre/drivers/net/pcnet32.c linux-3.0-rc7-libre/drivers/net/pcnet32.c
--- linux-2.6.39-libre/drivers/net/pcnet32.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/pcnet32.c	2011-07-11 19:51:52.000000000 -0400
@@ -295,12 +295,14 @@
 	struct net_device	*next;
 	struct mii_if_info	mii_if;
 	struct timer_list	watchdog_timer;
-	struct timer_list	blink_timer;
 	u32			msg_enable;	/* debug message level */
 
 	/* each bit indicates an available PHY */
 	u32			phymask;
 	unsigned short		chip_version;	/* which variant this is */
+
+	/* saved registers during ethtool blink */
+	u16 			save_regs[4];
 };
 
 static int pcnet32_probe_pci(struct pci_dev *, const struct pci_device_id *);
@@ -324,8 +326,6 @@
 static void pcnet32_ethtool_test(struct net_device *dev,
 				 struct ethtool_test *eth_test, u64 * data);
 static int pcnet32_loopback_test(struct net_device *dev, uint64_t * data1);
-static int pcnet32_phys_id(struct net_device *dev, u32 data);
-static void pcnet32_led_blink_callback(struct net_device *dev);
 static int pcnet32_get_regs_len(struct net_device *dev);
 static void pcnet32_get_regs(struct net_device *dev, struct ethtool_regs *regs,
 			     void *ptr);
@@ -1022,7 +1022,8 @@
 	return rc;
 }				/* end pcnet32_loopback_test  */
 
-static void pcnet32_led_blink_callback(struct net_device *dev)
+static int pcnet32_set_phys_id(struct net_device *dev,
+			       enum ethtool_phys_id_state state)
 {
 	struct pcnet32_private *lp = netdev_priv(dev);
 	struct pcnet32_access *a = &lp->a;
@@ -1030,50 +1031,31 @@
 	unsigned long flags;
 	int i;
 
-	spin_lock_irqsave(&lp->lock, flags);
-	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);
-}
+	switch (state) {
+	case ETHTOOL_ID_ACTIVE:
+		/* Save the current value of the bcrs */
+		spin_lock_irqsave(&lp->lock, flags);
+		for (i = 4; i < 8; i++)
+			lp->save_regs[i - 4] = a->read_bcr(ioaddr, i);
+		spin_unlock_irqrestore(&lp->lock, flags);
+		return 2;	/* cycle on/off twice per second */
 
-static int pcnet32_phys_id(struct net_device *dev, u32 data)
-{
-	struct pcnet32_private *lp = netdev_priv(dev);
-	struct pcnet32_access *a = &lp->a;
-	ulong ioaddr = dev->base_addr;
-	unsigned long flags;
-	int i, regs[4];
+	case ETHTOOL_ID_ON:
+	case ETHTOOL_ID_OFF:
+		/* Blink the led */
+		spin_lock_irqsave(&lp->lock, flags);
+		for (i = 4; i < 8; i++)
+			a->write_bcr(ioaddr, i, a->read_bcr(ioaddr, i) ^ 0x4000);
+		spin_unlock_irqrestore(&lp->lock, flags);
+		break;
 
-	if (!lp->blink_timer.function) {
-		init_timer(&lp->blink_timer);
-		lp->blink_timer.function = (void *)pcnet32_led_blink_callback;
-		lp->blink_timer.data = (unsigned long)dev;
+	case ETHTOOL_ID_INACTIVE:
+		/* Restore the original value of the bcrs */
+		spin_lock_irqsave(&lp->lock, flags);
+		for (i = 4; i < 8; i++)
+			a->write_bcr(ioaddr, i, lp->save_regs[i - 4]);
+		spin_unlock_irqrestore(&lp->lock, flags);
 	}
-
-	/* Save the current value of the bcrs */
-	spin_lock_irqsave(&lp->lock, flags);
-	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);
-	set_current_state(TASK_INTERRUPTIBLE);
-
-	/* AV: the limit here makes no sense whatsoever */
-	if ((!data) || (data > (u32) (MAX_SCHEDULE_TIMEOUT / HZ)))
-		data = (u32) (MAX_SCHEDULE_TIMEOUT / HZ);
-
-	msleep_interruptible(data * 1000);
-	del_timer_sync(&lp->blink_timer);
-
-	/* Restore the original value of the bcrs */
-	spin_lock_irqsave(&lp->lock, flags);
-	for (i = 4; i < 8; i++)
-		a->write_bcr(ioaddr, i, regs[i - 4]);
-	spin_unlock_irqrestore(&lp->lock, flags);
-
 	return 0;
 }
 
@@ -1450,7 +1432,7 @@
 	.set_ringparam		= pcnet32_set_ringparam,
 	.get_strings		= pcnet32_get_strings,
 	.self_test		= pcnet32_ethtool_test,
-	.phys_id		= pcnet32_phys_id,
+	.set_phys_id		= pcnet32_set_phys_id,
 	.get_regs_len		= pcnet32_get_regs_len,
 	.get_regs		= pcnet32_get_regs,
 	.get_sset_count		= pcnet32_get_sset_count,
@@ -2117,7 +2099,7 @@
 		int first_phy = -1;
 		u16 bmcr;
 		u32 bcr9;
-		struct ethtool_cmd ecmd;
+		struct ethtool_cmd ecmd = { .cmd = ETHTOOL_GSET };
 
 		/*
 		 * There is really no good other way to handle multiple PHYs
@@ -2133,9 +2115,9 @@
 			ecmd.port = PORT_MII;
 			ecmd.transceiver = XCVR_INTERNAL;
 			ecmd.autoneg = AUTONEG_DISABLE;
-			ecmd.speed =
-			    lp->
-			    options & PCNET32_PORT_100 ? SPEED_100 : SPEED_10;
+			ethtool_cmd_speed_set(&ecmd,
+					      (lp->options & PCNET32_PORT_100) ?
+					      SPEED_100 : SPEED_10);
 			bcr9 = lp->a.read_bcr(ioaddr, 9);
 
 			if (lp->options & PCNET32_PORT_FD) {
@@ -2781,11 +2763,11 @@
 		netif_carrier_on(dev);
 		if (lp->mii) {
 			if (netif_msg_link(lp)) {
-				struct ethtool_cmd ecmd;
+				struct ethtool_cmd ecmd = {
+					.cmd = ETHTOOL_GSET };
 				mii_ethtool_gset(&lp->mii_if, &ecmd);
-				netdev_info(dev, "link up, %sMbps, %s-duplex\n",
-					    (ecmd.speed == SPEED_100)
-					    ? "100" : "10",
+				netdev_info(dev, "link up, %uMbps, %s-duplex\n",
+					    ethtool_cmd_speed(&ecmd),
 					    (ecmd.duplex == DUPLEX_FULL)
 					    ? "full" : "half");
 			}
diff -druN linux-2.6.39-libre/drivers/net/phy/dp83640.c linux-3.0-rc7-libre/drivers/net/phy/dp83640.c
--- linux-2.6.39-libre/drivers/net/phy/dp83640.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/net/phy/dp83640.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,1110 @@
+/*
+ * Driver for the National Semiconductor DP83640 PHYTER
+ *
+ * Copyright (C) 2010 OMICRON electronics GmbH
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the 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/ethtool.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/mii.h>
+#include <linux/module.h>
+#include <linux/net_tstamp.h>
+#include <linux/netdevice.h>
+#include <linux/phy.h>
+#include <linux/ptp_classify.h>
+#include <linux/ptp_clock_kernel.h>
+
+#include "dp83640_reg.h"
+
+#define DP83640_PHY_ID	0x20005ce1
+#define PAGESEL		0x13
+#define LAYER4		0x02
+#define LAYER2		0x01
+#define MAX_RXTS	4
+#define MAX_TXTS	4
+#define N_EXT_TS	1
+#define PSF_PTPVER	2
+#define PSF_EVNT	0x4000
+#define PSF_RX		0x2000
+#define PSF_TX		0x1000
+#define EXT_EVENT	1
+#define EXT_GPIO	1
+#define CAL_EVENT	2
+#define CAL_GPIO	9
+#define CAL_TRIGGER	2
+
+/* phyter seems to miss the mark by 16 ns */
+#define ADJTIME_FIX	16
+
+#if defined(__BIG_ENDIAN)
+#define ENDIAN_FLAG	0
+#elif defined(__LITTLE_ENDIAN)
+#define ENDIAN_FLAG	PSF_ENDIAN
+#endif
+
+#define SKB_PTP_TYPE(__skb) (*(unsigned int *)((__skb)->cb))
+
+struct phy_rxts {
+	u16 ns_lo;   /* ns[15:0] */
+	u16 ns_hi;   /* overflow[1:0], ns[29:16] */
+	u16 sec_lo;  /* sec[15:0] */
+	u16 sec_hi;  /* sec[31:16] */
+	u16 seqid;   /* sequenceId[15:0] */
+	u16 msgtype; /* messageType[3:0], hash[11:0] */
+};
+
+struct phy_txts {
+	u16 ns_lo;   /* ns[15:0] */
+	u16 ns_hi;   /* overflow[1:0], ns[29:16] */
+	u16 sec_lo;  /* sec[15:0] */
+	u16 sec_hi;  /* sec[31:16] */
+};
+
+struct rxts {
+	struct list_head list;
+	unsigned long tmo;
+	u64 ns;
+	u16 seqid;
+	u8  msgtype;
+	u16 hash;
+};
+
+struct dp83640_clock;
+
+struct dp83640_private {
+	struct list_head list;
+	struct dp83640_clock *clock;
+	struct phy_device *phydev;
+	struct work_struct ts_work;
+	int hwts_tx_en;
+	int hwts_rx_en;
+	int layer;
+	int version;
+	/* remember state of cfg0 during calibration */
+	int cfg0;
+	/* remember the last event time stamp */
+	struct phy_txts edata;
+	/* list of rx timestamps */
+	struct list_head rxts;
+	struct list_head rxpool;
+	struct rxts rx_pool_data[MAX_RXTS];
+	/* protects above three fields from concurrent access */
+	spinlock_t rx_lock;
+	/* queues of incoming and outgoing packets */
+	struct sk_buff_head rx_queue;
+	struct sk_buff_head tx_queue;
+};
+
+struct dp83640_clock {
+	/* keeps the instance in the 'phyter_clocks' list */
+	struct list_head list;
+	/* we create one clock instance per MII bus */
+	struct mii_bus *bus;
+	/* protects extended registers from concurrent access */
+	struct mutex extreg_lock;
+	/* remembers which page was last selected */
+	int page;
+	/* our advertised capabilities */
+	struct ptp_clock_info caps;
+	/* protects the three fields below from concurrent access */
+	struct mutex clock_lock;
+	/* the one phyter from which we shall read */
+	struct dp83640_private *chosen;
+	/* list of the other attached phyters, not chosen */
+	struct list_head phylist;
+	/* reference to our PTP hardware clock */
+	struct ptp_clock *ptp_clock;
+};
+
+/* globals */
+
+static int chosen_phy = -1;
+static ushort cal_gpio = 4;
+
+module_param(chosen_phy, int, 0444);
+module_param(cal_gpio, ushort, 0444);
+
+MODULE_PARM_DESC(chosen_phy, \
+	"The address of the PHY to use for the ancillary clock features");
+MODULE_PARM_DESC(cal_gpio, \
+	"Which GPIO line to use for synchronizing multiple PHYs");
+
+/* a list of clocks and a mutex to protect it */
+static LIST_HEAD(phyter_clocks);
+static DEFINE_MUTEX(phyter_clocks_lock);
+
+static void rx_timestamp_work(struct work_struct *work);
+
+/* extended register access functions */
+
+#define BROADCAST_ADDR 31
+
+static inline int broadcast_write(struct mii_bus *bus, u32 regnum, u16 val)
+{
+	return mdiobus_write(bus, BROADCAST_ADDR, regnum, val);
+}
+
+/* Caller must hold extreg_lock. */
+static int ext_read(struct phy_device *phydev, int page, u32 regnum)
+{
+	struct dp83640_private *dp83640 = phydev->priv;
+	int val;
+
+	if (dp83640->clock->page != page) {
+		broadcast_write(phydev->bus, PAGESEL, page);
+		dp83640->clock->page = page;
+	}
+	val = phy_read(phydev, regnum);
+
+	return val;
+}
+
+/* Caller must hold extreg_lock. */
+static void ext_write(int broadcast, struct phy_device *phydev,
+		      int page, u32 regnum, u16 val)
+{
+	struct dp83640_private *dp83640 = phydev->priv;
+
+	if (dp83640->clock->page != page) {
+		broadcast_write(phydev->bus, PAGESEL, page);
+		dp83640->clock->page = page;
+	}
+	if (broadcast)
+		broadcast_write(phydev->bus, regnum, val);
+	else
+		phy_write(phydev, regnum, val);
+}
+
+/* Caller must hold extreg_lock. */
+static int tdr_write(int bc, struct phy_device *dev,
+		     const struct timespec *ts, u16 cmd)
+{
+	ext_write(bc, dev, PAGE4, PTP_TDR, ts->tv_nsec & 0xffff);/* ns[15:0]  */
+	ext_write(bc, dev, PAGE4, PTP_TDR, ts->tv_nsec >> 16);   /* ns[31:16] */
+	ext_write(bc, dev, PAGE4, PTP_TDR, ts->tv_sec & 0xffff); /* sec[15:0] */
+	ext_write(bc, dev, PAGE4, PTP_TDR, ts->tv_sec >> 16);    /* sec[31:16]*/
+
+	ext_write(bc, dev, PAGE4, PTP_CTL, cmd);
+
+	return 0;
+}
+
+/* convert phy timestamps into driver timestamps */
+
+static void phy2rxts(struct phy_rxts *p, struct rxts *rxts)
+{
+	u32 sec;
+
+	sec = p->sec_lo;
+	sec |= p->sec_hi << 16;
+
+	rxts->ns = p->ns_lo;
+	rxts->ns |= (p->ns_hi & 0x3fff) << 16;
+	rxts->ns += ((u64)sec) * 1000000000ULL;
+	rxts->seqid = p->seqid;
+	rxts->msgtype = (p->msgtype >> 12) & 0xf;
+	rxts->hash = p->msgtype & 0x0fff;
+	rxts->tmo = jiffies + HZ;
+}
+
+static u64 phy2txts(struct phy_txts *p)
+{
+	u64 ns;
+	u32 sec;
+
+	sec = p->sec_lo;
+	sec |= p->sec_hi << 16;
+
+	ns = p->ns_lo;
+	ns |= (p->ns_hi & 0x3fff) << 16;
+	ns += ((u64)sec) * 1000000000ULL;
+
+	return ns;
+}
+
+/* ptp clock methods */
+
+static int ptp_dp83640_adjfreq(struct ptp_clock_info *ptp, s32 ppb)
+{
+	struct dp83640_clock *clock =
+		container_of(ptp, struct dp83640_clock, caps);
+	struct phy_device *phydev = clock->chosen->phydev;
+	u64 rate;
+	int neg_adj = 0;
+	u16 hi, lo;
+
+	if (ppb < 0) {
+		neg_adj = 1;
+		ppb = -ppb;
+	}
+	rate = ppb;
+	rate <<= 26;
+	rate = div_u64(rate, 1953125);
+
+	hi = (rate >> 16) & PTP_RATE_HI_MASK;
+	if (neg_adj)
+		hi |= PTP_RATE_DIR;
+
+	lo = rate & 0xffff;
+
+	mutex_lock(&clock->extreg_lock);
+
+	ext_write(1, phydev, PAGE4, PTP_RATEH, hi);
+	ext_write(1, phydev, PAGE4, PTP_RATEL, lo);
+
+	mutex_unlock(&clock->extreg_lock);
+
+	return 0;
+}
+
+static int ptp_dp83640_adjtime(struct ptp_clock_info *ptp, s64 delta)
+{
+	struct dp83640_clock *clock =
+		container_of(ptp, struct dp83640_clock, caps);
+	struct phy_device *phydev = clock->chosen->phydev;
+	struct timespec ts;
+	int err;
+
+	delta += ADJTIME_FIX;
+
+	ts = ns_to_timespec(delta);
+
+	mutex_lock(&clock->extreg_lock);
+
+	err = tdr_write(1, phydev, &ts, PTP_STEP_CLK);
+
+	mutex_unlock(&clock->extreg_lock);
+
+	return err;
+}
+
+static int ptp_dp83640_gettime(struct ptp_clock_info *ptp, struct timespec *ts)
+{
+	struct dp83640_clock *clock =
+		container_of(ptp, struct dp83640_clock, caps);
+	struct phy_device *phydev = clock->chosen->phydev;
+	unsigned int val[4];
+
+	mutex_lock(&clock->extreg_lock);
+
+	ext_write(0, phydev, PAGE4, PTP_CTL, PTP_RD_CLK);
+
+	val[0] = ext_read(phydev, PAGE4, PTP_TDR); /* ns[15:0] */
+	val[1] = ext_read(phydev, PAGE4, PTP_TDR); /* ns[31:16] */
+	val[2] = ext_read(phydev, PAGE4, PTP_TDR); /* sec[15:0] */
+	val[3] = ext_read(phydev, PAGE4, PTP_TDR); /* sec[31:16] */
+
+	mutex_unlock(&clock->extreg_lock);
+
+	ts->tv_nsec = val[0] | (val[1] << 16);
+	ts->tv_sec  = val[2] | (val[3] << 16);
+
+	return 0;
+}
+
+static int ptp_dp83640_settime(struct ptp_clock_info *ptp,
+			       const struct timespec *ts)
+{
+	struct dp83640_clock *clock =
+		container_of(ptp, struct dp83640_clock, caps);
+	struct phy_device *phydev = clock->chosen->phydev;
+	int err;
+
+	mutex_lock(&clock->extreg_lock);
+
+	err = tdr_write(1, phydev, ts, PTP_LOAD_CLK);
+
+	mutex_unlock(&clock->extreg_lock);
+
+	return err;
+}
+
+static int ptp_dp83640_enable(struct ptp_clock_info *ptp,
+			      struct ptp_clock_request *rq, int on)
+{
+	struct dp83640_clock *clock =
+		container_of(ptp, struct dp83640_clock, caps);
+	struct phy_device *phydev = clock->chosen->phydev;
+	u16 evnt;
+
+	switch (rq->type) {
+	case PTP_CLK_REQ_EXTTS:
+		if (rq->extts.index != 0)
+			return -EINVAL;
+		evnt = EVNT_WR | (EXT_EVENT & EVNT_SEL_MASK) << EVNT_SEL_SHIFT;
+		if (on) {
+			evnt |= (EXT_GPIO & EVNT_GPIO_MASK) << EVNT_GPIO_SHIFT;
+			evnt |= EVNT_RISE;
+		}
+		ext_write(0, phydev, PAGE5, PTP_EVNT, evnt);
+		return 0;
+	default:
+		break;
+	}
+
+	return -EOPNOTSUPP;
+}
+
+static u8 status_frame_dst[6] = { 0x01, 0x1B, 0x19, 0x00, 0x00, 0x00 };
+static u8 status_frame_src[6] = { 0x08, 0x00, 0x17, 0x0B, 0x6B, 0x0F };
+
+static void enable_status_frames(struct phy_device *phydev, bool on)
+{
+	u16 cfg0 = 0, ver;
+
+	if (on)
+		cfg0 = PSF_EVNT_EN | PSF_RXTS_EN | PSF_TXTS_EN | ENDIAN_FLAG;
+
+	ver = (PSF_PTPVER & VERSIONPTP_MASK) << VERSIONPTP_SHIFT;
+
+	ext_write(0, phydev, PAGE5, PSF_CFG0, cfg0);
+	ext_write(0, phydev, PAGE6, PSF_CFG1, ver);
+
+	if (!phydev->attached_dev) {
+		pr_warning("dp83640: expected to find an attached netdevice\n");
+		return;
+	}
+
+	if (on) {
+		if (dev_mc_add(phydev->attached_dev, status_frame_dst))
+			pr_warning("dp83640: failed to add mc address\n");
+	} else {
+		if (dev_mc_del(phydev->attached_dev, status_frame_dst))
+			pr_warning("dp83640: failed to delete mc address\n");
+	}
+}
+
+static bool is_status_frame(struct sk_buff *skb, int type)
+{
+	struct ethhdr *h = eth_hdr(skb);
+
+	if (PTP_CLASS_V2_L2 == type &&
+	    !memcmp(h->h_source, status_frame_src, sizeof(status_frame_src)))
+		return true;
+	else
+		return false;
+}
+
+static int expired(struct rxts *rxts)
+{
+	return time_after(jiffies, rxts->tmo);
+}
+
+/* Caller must hold rx_lock. */
+static void prune_rx_ts(struct dp83640_private *dp83640)
+{
+	struct list_head *this, *next;
+	struct rxts *rxts;
+
+	list_for_each_safe(this, next, &dp83640->rxts) {
+		rxts = list_entry(this, struct rxts, list);
+		if (expired(rxts)) {
+			list_del_init(&rxts->list);
+			list_add(&rxts->list, &dp83640->rxpool);
+		}
+	}
+}
+
+/* synchronize the phyters so they act as one clock */
+
+static void enable_broadcast(struct phy_device *phydev, int init_page, int on)
+{
+	int val;
+	phy_write(phydev, PAGESEL, 0);
+	val = phy_read(phydev, PHYCR2);
+	if (on)
+		val |= BC_WRITE;
+	else
+		val &= ~BC_WRITE;
+	phy_write(phydev, PHYCR2, val);
+	phy_write(phydev, PAGESEL, init_page);
+}
+
+static void recalibrate(struct dp83640_clock *clock)
+{
+	s64 now, diff;
+	struct phy_txts event_ts;
+	struct timespec ts;
+	struct list_head *this;
+	struct dp83640_private *tmp;
+	struct phy_device *master = clock->chosen->phydev;
+	u16 cfg0, evnt, ptp_trig, trigger, val;
+
+	trigger = CAL_TRIGGER;
+
+	mutex_lock(&clock->extreg_lock);
+
+	/*
+	 * enable broadcast, disable status frames, enable ptp clock
+	 */
+	list_for_each(this, &clock->phylist) {
+		tmp = list_entry(this, struct dp83640_private, list);
+		enable_broadcast(tmp->phydev, clock->page, 1);
+		tmp->cfg0 = ext_read(tmp->phydev, PAGE5, PSF_CFG0);
+		ext_write(0, tmp->phydev, PAGE5, PSF_CFG0, 0);
+		ext_write(0, tmp->phydev, PAGE4, PTP_CTL, PTP_ENABLE);
+	}
+	enable_broadcast(master, clock->page, 1);
+	cfg0 = ext_read(master, PAGE5, PSF_CFG0);
+	ext_write(0, master, PAGE5, PSF_CFG0, 0);
+	ext_write(0, master, PAGE4, PTP_CTL, PTP_ENABLE);
+
+	/*
+	 * enable an event timestamp
+	 */
+	evnt = EVNT_WR | EVNT_RISE | EVNT_SINGLE;
+	evnt |= (CAL_EVENT & EVNT_SEL_MASK) << EVNT_SEL_SHIFT;
+	evnt |= (cal_gpio & EVNT_GPIO_MASK) << EVNT_GPIO_SHIFT;
+
+	list_for_each(this, &clock->phylist) {
+		tmp = list_entry(this, struct dp83640_private, list);
+		ext_write(0, tmp->phydev, PAGE5, PTP_EVNT, evnt);
+	}
+	ext_write(0, master, PAGE5, PTP_EVNT, evnt);
+
+	/*
+	 * configure a trigger
+	 */
+	ptp_trig = TRIG_WR | TRIG_IF_LATE | TRIG_PULSE;
+	ptp_trig |= (trigger  & TRIG_CSEL_MASK) << TRIG_CSEL_SHIFT;
+	ptp_trig |= (cal_gpio & TRIG_GPIO_MASK) << TRIG_GPIO_SHIFT;
+	ext_write(0, master, PAGE5, PTP_TRIG, ptp_trig);
+
+	/* load trigger */
+	val = (trigger & TRIG_SEL_MASK) << TRIG_SEL_SHIFT;
+	val |= TRIG_LOAD;
+	ext_write(0, master, PAGE4, PTP_CTL, val);
+
+	/* enable trigger */
+	val &= ~TRIG_LOAD;
+	val |= TRIG_EN;
+	ext_write(0, master, PAGE4, PTP_CTL, val);
+
+	/* disable trigger */
+	val = (trigger & TRIG_SEL_MASK) << TRIG_SEL_SHIFT;
+	val |= TRIG_DIS;
+	ext_write(0, master, PAGE4, PTP_CTL, val);
+
+	/*
+	 * read out and correct offsets
+	 */
+	val = ext_read(master, PAGE4, PTP_STS);
+	pr_info("master PTP_STS  0x%04hx", val);
+	val = ext_read(master, PAGE4, PTP_ESTS);
+	pr_info("master PTP_ESTS 0x%04hx", val);
+	event_ts.ns_lo  = ext_read(master, PAGE4, PTP_EDATA);
+	event_ts.ns_hi  = ext_read(master, PAGE4, PTP_EDATA);
+	event_ts.sec_lo = ext_read(master, PAGE4, PTP_EDATA);
+	event_ts.sec_hi = ext_read(master, PAGE4, PTP_EDATA);
+	now = phy2txts(&event_ts);
+
+	list_for_each(this, &clock->phylist) {
+		tmp = list_entry(this, struct dp83640_private, list);
+		val = ext_read(tmp->phydev, PAGE4, PTP_STS);
+		pr_info("slave  PTP_STS  0x%04hx", val);
+		val = ext_read(tmp->phydev, PAGE4, PTP_ESTS);
+		pr_info("slave  PTP_ESTS 0x%04hx", val);
+		event_ts.ns_lo  = ext_read(tmp->phydev, PAGE4, PTP_EDATA);
+		event_ts.ns_hi  = ext_read(tmp->phydev, PAGE4, PTP_EDATA);
+		event_ts.sec_lo = ext_read(tmp->phydev, PAGE4, PTP_EDATA);
+		event_ts.sec_hi = ext_read(tmp->phydev, PAGE4, PTP_EDATA);
+		diff = now - (s64) phy2txts(&event_ts);
+		pr_info("slave offset %lld nanoseconds\n", diff);
+		diff += ADJTIME_FIX;
+		ts = ns_to_timespec(diff);
+		tdr_write(0, tmp->phydev, &ts, PTP_STEP_CLK);
+	}
+
+	/*
+	 * restore status frames
+	 */
+	list_for_each(this, &clock->phylist) {
+		tmp = list_entry(this, struct dp83640_private, list);
+		ext_write(0, tmp->phydev, PAGE5, PSF_CFG0, tmp->cfg0);
+	}
+	ext_write(0, master, PAGE5, PSF_CFG0, cfg0);
+
+	mutex_unlock(&clock->extreg_lock);
+}
+
+/* time stamping methods */
+
+static int decode_evnt(struct dp83640_private *dp83640,
+		       void *data, u16 ests)
+{
+	struct phy_txts *phy_txts;
+	struct ptp_clock_event event;
+	int words = (ests >> EVNT_TS_LEN_SHIFT) & EVNT_TS_LEN_MASK;
+	u16 ext_status = 0;
+
+	if (ests & MULT_EVNT) {
+		ext_status = *(u16 *) data;
+		data += sizeof(ext_status);
+	}
+
+	phy_txts = data;
+
+	switch (words) { /* fall through in every case */
+	case 3:
+		dp83640->edata.sec_hi = phy_txts->sec_hi;
+	case 2:
+		dp83640->edata.sec_lo = phy_txts->sec_lo;
+	case 1:
+		dp83640->edata.ns_hi = phy_txts->ns_hi;
+	case 0:
+		dp83640->edata.ns_lo = phy_txts->ns_lo;
+	}
+
+	event.type = PTP_CLOCK_EXTTS;
+	event.index = 0;
+	event.timestamp = phy2txts(&dp83640->edata);
+
+	ptp_clock_event(dp83640->clock->ptp_clock, &event);
+
+	words = ext_status ? words + 2 : words + 1;
+	return words * sizeof(u16);
+}
+
+static void decode_rxts(struct dp83640_private *dp83640,
+			struct phy_rxts *phy_rxts)
+{
+	struct rxts *rxts;
+	unsigned long flags;
+
+	spin_lock_irqsave(&dp83640->rx_lock, flags);
+
+	prune_rx_ts(dp83640);
+
+	if (list_empty(&dp83640->rxpool)) {
+		pr_warning("dp83640: rx timestamp pool is empty\n");
+		goto out;
+	}
+	rxts = list_first_entry(&dp83640->rxpool, struct rxts, list);
+	list_del_init(&rxts->list);
+	phy2rxts(phy_rxts, rxts);
+	list_add_tail(&rxts->list, &dp83640->rxts);
+out:
+	spin_unlock_irqrestore(&dp83640->rx_lock, flags);
+}
+
+static void decode_txts(struct dp83640_private *dp83640,
+			struct phy_txts *phy_txts)
+{
+	struct skb_shared_hwtstamps shhwtstamps;
+	struct sk_buff *skb;
+	u64 ns;
+
+	/* We must already have the skb that triggered this. */
+
+	skb = skb_dequeue(&dp83640->tx_queue);
+
+	if (!skb) {
+		pr_warning("dp83640: have timestamp but tx_queue empty\n");
+		return;
+	}
+	ns = phy2txts(phy_txts);
+	memset(&shhwtstamps, 0, sizeof(shhwtstamps));
+	shhwtstamps.hwtstamp = ns_to_ktime(ns);
+	skb_complete_tx_timestamp(skb, &shhwtstamps);
+}
+
+static void decode_status_frame(struct dp83640_private *dp83640,
+				struct sk_buff *skb)
+{
+	struct phy_rxts *phy_rxts;
+	struct phy_txts *phy_txts;
+	u8 *ptr;
+	int len, size;
+	u16 ests, type;
+
+	ptr = skb->data + 2;
+
+	for (len = skb_headlen(skb) - 2; len > sizeof(type); len -= size) {
+
+		type = *(u16 *)ptr;
+		ests = type & 0x0fff;
+		type = type & 0xf000;
+		len -= sizeof(type);
+		ptr += sizeof(type);
+
+		if (PSF_RX == type && len >= sizeof(*phy_rxts)) {
+
+			phy_rxts = (struct phy_rxts *) ptr;
+			decode_rxts(dp83640, phy_rxts);
+			size = sizeof(*phy_rxts);
+
+		} else if (PSF_TX == type && len >= sizeof(*phy_txts)) {
+
+			phy_txts = (struct phy_txts *) ptr;
+			decode_txts(dp83640, phy_txts);
+			size = sizeof(*phy_txts);
+
+		} else if (PSF_EVNT == type && len >= sizeof(*phy_txts)) {
+
+			size = decode_evnt(dp83640, ptr, ests);
+
+		} else {
+			size = 0;
+			break;
+		}
+		ptr += size;
+	}
+}
+
+static int match(struct sk_buff *skb, unsigned int type, struct rxts *rxts)
+{
+	u16 *seqid;
+	unsigned int offset;
+	u8 *msgtype, *data = skb_mac_header(skb);
+
+	/* check sequenceID, messageType, 12 bit hash of offset 20-29 */
+
+	switch (type) {
+	case PTP_CLASS_V1_IPV4:
+	case PTP_CLASS_V2_IPV4:
+		offset = ETH_HLEN + IPV4_HLEN(data) + UDP_HLEN;
+		break;
+	case PTP_CLASS_V1_IPV6:
+	case PTP_CLASS_V2_IPV6:
+		offset = OFF_PTP6;
+		break;
+	case PTP_CLASS_V2_L2:
+		offset = ETH_HLEN;
+		break;
+	case PTP_CLASS_V2_VLAN:
+		offset = ETH_HLEN + VLAN_HLEN;
+		break;
+	default:
+		return 0;
+	}
+
+	if (skb->len + ETH_HLEN < offset + OFF_PTP_SEQUENCE_ID + sizeof(*seqid))
+		return 0;
+
+	if (unlikely(type & PTP_CLASS_V1))
+		msgtype = data + offset + OFF_PTP_CONTROL;
+	else
+		msgtype = data + offset;
+
+	seqid = (u16 *)(data + offset + OFF_PTP_SEQUENCE_ID);
+
+	return (rxts->msgtype == (*msgtype & 0xf) &&
+		rxts->seqid   == ntohs(*seqid));
+}
+
+static void dp83640_free_clocks(void)
+{
+	struct dp83640_clock *clock;
+	struct list_head *this, *next;
+
+	mutex_lock(&phyter_clocks_lock);
+
+	list_for_each_safe(this, next, &phyter_clocks) {
+		clock = list_entry(this, struct dp83640_clock, list);
+		if (!list_empty(&clock->phylist)) {
+			pr_warning("phy list non-empty while unloading");
+			BUG();
+		}
+		list_del(&clock->list);
+		mutex_destroy(&clock->extreg_lock);
+		mutex_destroy(&clock->clock_lock);
+		put_device(&clock->bus->dev);
+		kfree(clock);
+	}
+
+	mutex_unlock(&phyter_clocks_lock);
+}
+
+static void dp83640_clock_init(struct dp83640_clock *clock, struct mii_bus *bus)
+{
+	INIT_LIST_HEAD(&clock->list);
+	clock->bus = bus;
+	mutex_init(&clock->extreg_lock);
+	mutex_init(&clock->clock_lock);
+	INIT_LIST_HEAD(&clock->phylist);
+	clock->caps.owner = THIS_MODULE;
+	sprintf(clock->caps.name, "dp83640 timer");
+	clock->caps.max_adj	= 1953124;
+	clock->caps.n_alarm	= 0;
+	clock->caps.n_ext_ts	= N_EXT_TS;
+	clock->caps.n_per_out	= 0;
+	clock->caps.pps		= 0;
+	clock->caps.adjfreq	= ptp_dp83640_adjfreq;
+	clock->caps.adjtime	= ptp_dp83640_adjtime;
+	clock->caps.gettime	= ptp_dp83640_gettime;
+	clock->caps.settime	= ptp_dp83640_settime;
+	clock->caps.enable	= ptp_dp83640_enable;
+	/*
+	 * Get a reference to this bus instance.
+	 */
+	get_device(&bus->dev);
+}
+
+static int choose_this_phy(struct dp83640_clock *clock,
+			   struct phy_device *phydev)
+{
+	if (chosen_phy == -1 && !clock->chosen)
+		return 1;
+
+	if (chosen_phy == phydev->addr)
+		return 1;
+
+	return 0;
+}
+
+static struct dp83640_clock *dp83640_clock_get(struct dp83640_clock *clock)
+{
+	if (clock)
+		mutex_lock(&clock->clock_lock);
+	return clock;
+}
+
+/*
+ * Look up and lock a clock by bus instance.
+ * If there is no clock for this bus, then create it first.
+ */
+static struct dp83640_clock *dp83640_clock_get_bus(struct mii_bus *bus)
+{
+	struct dp83640_clock *clock = NULL, *tmp;
+	struct list_head *this;
+
+	mutex_lock(&phyter_clocks_lock);
+
+	list_for_each(this, &phyter_clocks) {
+		tmp = list_entry(this, struct dp83640_clock, list);
+		if (tmp->bus == bus) {
+			clock = tmp;
+			break;
+		}
+	}
+	if (clock)
+		goto out;
+
+	clock = kzalloc(sizeof(struct dp83640_clock), GFP_KERNEL);
+	if (!clock)
+		goto out;
+
+	dp83640_clock_init(clock, bus);
+	list_add_tail(&phyter_clocks, &clock->list);
+out:
+	mutex_unlock(&phyter_clocks_lock);
+
+	return dp83640_clock_get(clock);
+}
+
+static void dp83640_clock_put(struct dp83640_clock *clock)
+{
+	mutex_unlock(&clock->clock_lock);
+}
+
+static int dp83640_probe(struct phy_device *phydev)
+{
+	struct dp83640_clock *clock;
+	struct dp83640_private *dp83640;
+	int err = -ENOMEM, i;
+
+	if (phydev->addr == BROADCAST_ADDR)
+		return 0;
+
+	clock = dp83640_clock_get_bus(phydev->bus);
+	if (!clock)
+		goto no_clock;
+
+	dp83640 = kzalloc(sizeof(struct dp83640_private), GFP_KERNEL);
+	if (!dp83640)
+		goto no_memory;
+
+	dp83640->phydev = phydev;
+	INIT_WORK(&dp83640->ts_work, rx_timestamp_work);
+
+	INIT_LIST_HEAD(&dp83640->rxts);
+	INIT_LIST_HEAD(&dp83640->rxpool);
+	for (i = 0; i < MAX_RXTS; i++)
+		list_add(&dp83640->rx_pool_data[i].list, &dp83640->rxpool);
+
+	phydev->priv = dp83640;
+
+	spin_lock_init(&dp83640->rx_lock);
+	skb_queue_head_init(&dp83640->rx_queue);
+	skb_queue_head_init(&dp83640->tx_queue);
+
+	dp83640->clock = clock;
+
+	if (choose_this_phy(clock, phydev)) {
+		clock->chosen = dp83640;
+		clock->ptp_clock = ptp_clock_register(&clock->caps);
+		if (IS_ERR(clock->ptp_clock)) {
+			err = PTR_ERR(clock->ptp_clock);
+			goto no_register;
+		}
+	} else
+		list_add_tail(&dp83640->list, &clock->phylist);
+
+	if (clock->chosen && !list_empty(&clock->phylist))
+		recalibrate(clock);
+	else
+		enable_broadcast(dp83640->phydev, clock->page, 1);
+
+	dp83640_clock_put(clock);
+	return 0;
+
+no_register:
+	clock->chosen = NULL;
+	kfree(dp83640);
+no_memory:
+	dp83640_clock_put(clock);
+no_clock:
+	return err;
+}
+
+static void dp83640_remove(struct phy_device *phydev)
+{
+	struct dp83640_clock *clock;
+	struct list_head *this, *next;
+	struct dp83640_private *tmp, *dp83640 = phydev->priv;
+
+	if (phydev->addr == BROADCAST_ADDR)
+		return;
+
+	enable_status_frames(phydev, false);
+	cancel_work_sync(&dp83640->ts_work);
+
+	clock = dp83640_clock_get(dp83640->clock);
+
+	if (dp83640 == clock->chosen) {
+		ptp_clock_unregister(clock->ptp_clock);
+		clock->chosen = NULL;
+	} else {
+		list_for_each_safe(this, next, &clock->phylist) {
+			tmp = list_entry(this, struct dp83640_private, list);
+			if (tmp == dp83640) {
+				list_del_init(&tmp->list);
+				break;
+			}
+		}
+	}
+
+	dp83640_clock_put(clock);
+	kfree(dp83640);
+}
+
+static int dp83640_hwtstamp(struct phy_device *phydev, struct ifreq *ifr)
+{
+	struct dp83640_private *dp83640 = phydev->priv;
+	struct hwtstamp_config cfg;
+	u16 txcfg0, rxcfg0;
+
+	if (copy_from_user(&cfg, ifr->ifr_data, sizeof(cfg)))
+		return -EFAULT;
+
+	if (cfg.flags) /* reserved for future extensions */
+		return -EINVAL;
+
+	switch (cfg.tx_type) {
+	case HWTSTAMP_TX_OFF:
+		dp83640->hwts_tx_en = 0;
+		break;
+	case HWTSTAMP_TX_ON:
+		dp83640->hwts_tx_en = 1;
+		break;
+	default:
+		return -ERANGE;
+	}
+
+	switch (cfg.rx_filter) {
+	case HWTSTAMP_FILTER_NONE:
+		dp83640->hwts_rx_en = 0;
+		dp83640->layer = 0;
+		dp83640->version = 0;
+		break;
+	case HWTSTAMP_FILTER_PTP_V1_L4_EVENT:
+	case HWTSTAMP_FILTER_PTP_V1_L4_SYNC:
+	case HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ:
+		dp83640->hwts_rx_en = 1;
+		dp83640->layer = LAYER4;
+		dp83640->version = 1;
+		break;
+	case HWTSTAMP_FILTER_PTP_V2_L4_EVENT:
+	case HWTSTAMP_FILTER_PTP_V2_L4_SYNC:
+	case HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ:
+		dp83640->hwts_rx_en = 1;
+		dp83640->layer = LAYER4;
+		dp83640->version = 2;
+		break;
+	case HWTSTAMP_FILTER_PTP_V2_L2_EVENT:
+	case HWTSTAMP_FILTER_PTP_V2_L2_SYNC:
+	case HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ:
+		dp83640->hwts_rx_en = 1;
+		dp83640->layer = LAYER2;
+		dp83640->version = 2;
+		break;
+	case HWTSTAMP_FILTER_PTP_V2_EVENT:
+	case HWTSTAMP_FILTER_PTP_V2_SYNC:
+	case HWTSTAMP_FILTER_PTP_V2_DELAY_REQ:
+		dp83640->hwts_rx_en = 1;
+		dp83640->layer = LAYER4|LAYER2;
+		dp83640->version = 2;
+		break;
+	default:
+		return -ERANGE;
+	}
+
+	txcfg0 = (dp83640->version & TX_PTP_VER_MASK) << TX_PTP_VER_SHIFT;
+	rxcfg0 = (dp83640->version & TX_PTP_VER_MASK) << TX_PTP_VER_SHIFT;
+
+	if (dp83640->layer & LAYER2) {
+		txcfg0 |= TX_L2_EN;
+		rxcfg0 |= RX_L2_EN;
+	}
+	if (dp83640->layer & LAYER4) {
+		txcfg0 |= TX_IPV6_EN | TX_IPV4_EN;
+		rxcfg0 |= RX_IPV6_EN | RX_IPV4_EN;
+	}
+
+	if (dp83640->hwts_tx_en)
+		txcfg0 |= TX_TS_EN;
+
+	if (dp83640->hwts_rx_en)
+		rxcfg0 |= RX_TS_EN;
+
+	mutex_lock(&dp83640->clock->extreg_lock);
+
+	if (dp83640->hwts_tx_en || dp83640->hwts_rx_en) {
+		enable_status_frames(phydev, true);
+		ext_write(0, phydev, PAGE4, PTP_CTL, PTP_ENABLE);
+	}
+
+	ext_write(0, phydev, PAGE5, PTP_TXCFG0, txcfg0);
+	ext_write(0, phydev, PAGE5, PTP_RXCFG0, rxcfg0);
+
+	mutex_unlock(&dp83640->clock->extreg_lock);
+
+	return copy_to_user(ifr->ifr_data, &cfg, sizeof(cfg)) ? -EFAULT : 0;
+}
+
+static void rx_timestamp_work(struct work_struct *work)
+{
+	struct dp83640_private *dp83640 =
+		container_of(work, struct dp83640_private, ts_work);
+	struct list_head *this, *next;
+	struct rxts *rxts;
+	struct skb_shared_hwtstamps *shhwtstamps;
+	struct sk_buff *skb;
+	unsigned int type;
+	unsigned long flags;
+
+	/* Deliver each deferred packet, with or without a time stamp. */
+
+	while ((skb = skb_dequeue(&dp83640->rx_queue)) != NULL) {
+		type = SKB_PTP_TYPE(skb);
+		spin_lock_irqsave(&dp83640->rx_lock, flags);
+		list_for_each_safe(this, next, &dp83640->rxts) {
+			rxts = list_entry(this, struct rxts, list);
+			if (match(skb, type, rxts)) {
+				shhwtstamps = skb_hwtstamps(skb);
+				memset(shhwtstamps, 0, sizeof(*shhwtstamps));
+				shhwtstamps->hwtstamp = ns_to_ktime(rxts->ns);
+				list_del_init(&rxts->list);
+				list_add(&rxts->list, &dp83640->rxpool);
+				break;
+			}
+		}
+		spin_unlock_irqrestore(&dp83640->rx_lock, flags);
+		netif_rx(skb);
+	}
+
+	/* Clear out expired time stamps. */
+
+	spin_lock_irqsave(&dp83640->rx_lock, flags);
+	prune_rx_ts(dp83640);
+	spin_unlock_irqrestore(&dp83640->rx_lock, flags);
+}
+
+static bool dp83640_rxtstamp(struct phy_device *phydev,
+			     struct sk_buff *skb, int type)
+{
+	struct dp83640_private *dp83640 = phydev->priv;
+
+	if (!dp83640->hwts_rx_en)
+		return false;
+
+	if (is_status_frame(skb, type)) {
+		decode_status_frame(dp83640, skb);
+		kfree_skb(skb);
+		return true;
+	}
+
+	SKB_PTP_TYPE(skb) = type;
+	skb_queue_tail(&dp83640->rx_queue, skb);
+	schedule_work(&dp83640->ts_work);
+
+	return true;
+}
+
+static void dp83640_txtstamp(struct phy_device *phydev,
+			     struct sk_buff *skb, int type)
+{
+	struct dp83640_private *dp83640 = phydev->priv;
+
+	if (!dp83640->hwts_tx_en) {
+		kfree_skb(skb);
+		return;
+	}
+	skb_queue_tail(&dp83640->tx_queue, skb);
+	schedule_work(&dp83640->ts_work);
+}
+
+static struct phy_driver dp83640_driver = {
+	.phy_id		= DP83640_PHY_ID,
+	.phy_id_mask	= 0xfffffff0,
+	.name		= "NatSemi DP83640",
+	.features	= PHY_BASIC_FEATURES,
+	.flags		= 0,
+	.probe		= dp83640_probe,
+	.remove		= dp83640_remove,
+	.config_aneg	= genphy_config_aneg,
+	.read_status	= genphy_read_status,
+	.hwtstamp	= dp83640_hwtstamp,
+	.rxtstamp	= dp83640_rxtstamp,
+	.txtstamp	= dp83640_txtstamp,
+	.driver		= {.owner = THIS_MODULE,}
+};
+
+static int __init dp83640_init(void)
+{
+	return phy_driver_register(&dp83640_driver);
+}
+
+static void __exit dp83640_exit(void)
+{
+	dp83640_free_clocks();
+	phy_driver_unregister(&dp83640_driver);
+}
+
+MODULE_DESCRIPTION("National Semiconductor DP83640 PHY driver");
+MODULE_AUTHOR("Richard Cochran <richard.cochran@omicron.at>");
+MODULE_LICENSE("GPL");
+
+module_init(dp83640_init);
+module_exit(dp83640_exit);
+
+static struct mdio_device_id __maybe_unused dp83640_tbl[] = {
+	{ DP83640_PHY_ID, 0xfffffff0 },
+	{ }
+};
+
+MODULE_DEVICE_TABLE(mdio, dp83640_tbl);
diff -druN linux-2.6.39-libre/drivers/net/phy/dp83640_reg.h linux-3.0-rc7-libre/drivers/net/phy/dp83640_reg.h
--- linux-2.6.39-libre/drivers/net/phy/dp83640_reg.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/net/phy/dp83640_reg.h	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,267 @@
+/* dp83640_reg.h
+ * Generated by regen.tcl on Thu Feb 17 10:02:48 AM CET 2011
+ */
+#ifndef HAVE_DP83640_REGISTERS
+#define HAVE_DP83640_REGISTERS
+
+#define PAGE0                     0x0000
+#define PHYCR2                    0x001c /* PHY Control Register 2 */
+
+#define PAGE4                     0x0004
+#define PTP_CTL                   0x0014 /* PTP Control Register */
+#define PTP_TDR                   0x0015 /* PTP Time Data Register */
+#define PTP_STS                   0x0016 /* PTP Status Register */
+#define PTP_TSTS                  0x0017 /* PTP Trigger Status Register */
+#define PTP_RATEL                 0x0018 /* PTP Rate Low Register */
+#define PTP_RATEH                 0x0019 /* PTP Rate High Register */
+#define PTP_RDCKSUM               0x001a /* PTP Read Checksum */
+#define PTP_WRCKSUM               0x001b /* PTP Write Checksum */
+#define PTP_TXTS                  0x001c /* PTP Transmit Timestamp Register, in four 16-bit reads */
+#define PTP_RXTS                  0x001d /* PTP Receive Timestamp Register, in six? 16-bit reads */
+#define PTP_ESTS                  0x001e /* PTP Event Status Register */
+#define PTP_EDATA                 0x001f /* PTP Event Data Register */
+
+#define PAGE5                     0x0005
+#define PTP_TRIG                  0x0014 /* PTP Trigger Configuration Register */
+#define PTP_EVNT                  0x0015 /* PTP Event Configuration Register */
+#define PTP_TXCFG0                0x0016 /* PTP Transmit Configuration Register 0 */
+#define PTP_TXCFG1                0x0017 /* PTP Transmit Configuration Register 1 */
+#define PSF_CFG0                  0x0018 /* PHY Status Frame Configuration Register 0 */
+#define PTP_RXCFG0                0x0019 /* PTP Receive Configuration Register 0 */
+#define PTP_RXCFG1                0x001a /* PTP Receive Configuration Register 1 */
+#define PTP_RXCFG2                0x001b /* PTP Receive Configuration Register 2 */
+#define PTP_RXCFG3                0x001c /* PTP Receive Configuration Register 3 */
+#define PTP_RXCFG4                0x001d /* PTP Receive Configuration Register 4 */
+#define PTP_TRDL                  0x001e /* PTP Temporary Rate Duration Low Register */
+#define PTP_TRDH                  0x001f /* PTP Temporary Rate Duration High Register */
+
+#define PAGE6                     0x0006
+#define PTP_COC                   0x0014 /* PTP Clock Output Control Register */
+#define PSF_CFG1                  0x0015 /* PHY Status Frame Configuration Register 1 */
+#define PSF_CFG2                  0x0016 /* PHY Status Frame Configuration Register 2 */
+#define PSF_CFG3                  0x0017 /* PHY Status Frame Configuration Register 3 */
+#define PSF_CFG4                  0x0018 /* PHY Status Frame Configuration Register 4 */
+#define PTP_SFDCFG                0x0019 /* PTP SFD Configuration Register */
+#define PTP_INTCTL                0x001a /* PTP Interrupt Control Register */
+#define PTP_CLKSRC                0x001b /* PTP Clock Source Register */
+#define PTP_ETR                   0x001c /* PTP Ethernet Type Register */
+#define PTP_OFF                   0x001d /* PTP Offset Register */
+#define PTP_GPIOMON               0x001e /* PTP GPIO Monitor Register */
+#define PTP_RXHASH                0x001f /* PTP Receive Hash Register */
+
+/* Bit definitions for the PHYCR2 register */
+#define BC_WRITE                  (1<<11) /* Broadcast Write Enable */
+
+/* Bit definitions for the PTP_CTL register */
+#define TRIG_SEL_SHIFT            (10)    /* PTP Trigger Select */
+#define TRIG_SEL_MASK             (0x7)
+#define TRIG_DIS                  (1<<9)  /* Disable PTP Trigger */
+#define TRIG_EN                   (1<<8)  /* Enable PTP Trigger */
+#define TRIG_READ                 (1<<7)  /* Read PTP Trigger */
+#define TRIG_LOAD                 (1<<6)  /* Load PTP Trigger */
+#define PTP_RD_CLK                (1<<5)  /* Read PTP Clock */
+#define PTP_LOAD_CLK              (1<<4)  /* Load PTP Clock */
+#define PTP_STEP_CLK              (1<<3)  /* Step PTP Clock */
+#define PTP_ENABLE                (1<<2)  /* Enable PTP Clock */
+#define PTP_DISABLE               (1<<1)  /* Disable PTP Clock */
+#define PTP_RESET                 (1<<0)  /* Reset PTP Clock */
+
+/* Bit definitions for the PTP_STS register */
+#define TXTS_RDY                  (1<<11) /* Transmit Timestamp Ready */
+#define RXTS_RDY                  (1<<10) /* Receive Timestamp Ready */
+#define TRIG_DONE                 (1<<9)  /* PTP Trigger Done */
+#define EVENT_RDY                 (1<<8)  /* PTP Event Timestamp Ready */
+#define TXTS_IE                   (1<<3)  /* Transmit Timestamp Interrupt Enable */
+#define RXTS_IE                   (1<<2)  /* Receive Timestamp Interrupt Enable */
+#define TRIG_IE                   (1<<1)  /* Trigger Interrupt Enable */
+#define EVENT_IE                  (1<<0)  /* Event Interrupt Enable */
+
+/* Bit definitions for the PTP_TSTS register */
+#define TRIG7_ERROR               (1<<15) /* Trigger 7 Error */
+#define TRIG7_ACTIVE              (1<<14) /* Trigger 7 Active */
+#define TRIG6_ERROR               (1<<13) /* Trigger 6 Error */
+#define TRIG6_ACTIVE              (1<<12) /* Trigger 6 Active */
+#define TRIG5_ERROR               (1<<11) /* Trigger 5 Error */
+#define TRIG5_ACTIVE              (1<<10) /* Trigger 5 Active */
+#define TRIG4_ERROR               (1<<9)  /* Trigger 4 Error */
+#define TRIG4_ACTIVE              (1<<8)  /* Trigger 4 Active */
+#define TRIG3_ERROR               (1<<7)  /* Trigger 3 Error */
+#define TRIG3_ACTIVE              (1<<6)  /* Trigger 3 Active */
+#define TRIG2_ERROR               (1<<5)  /* Trigger 2 Error */
+#define TRIG2_ACTIVE              (1<<4)  /* Trigger 2 Active */
+#define TRIG1_ERROR               (1<<3)  /* Trigger 1 Error */
+#define TRIG1_ACTIVE              (1<<2)  /* Trigger 1 Active */
+#define TRIG0_ERROR               (1<<1)  /* Trigger 0 Error */
+#define TRIG0_ACTIVE              (1<<0)  /* Trigger 0 Active */
+
+/* Bit definitions for the PTP_RATEH register */
+#define PTP_RATE_DIR              (1<<15) /* PTP Rate Direction */
+#define PTP_TMP_RATE              (1<<14) /* PTP Temporary Rate */
+#define PTP_RATE_HI_SHIFT         (0)     /* PTP Rate High 10-bits */
+#define PTP_RATE_HI_MASK          (0x3ff)
+
+/* Bit definitions for the PTP_ESTS register */
+#define EVNTS_MISSED_SHIFT        (8)     /* Indicates number of events missed */
+#define EVNTS_MISSED_MASK         (0x7)
+#define EVNT_TS_LEN_SHIFT         (6)     /* Indicates length of the Timestamp field in 16-bit words minus 1 */
+#define EVNT_TS_LEN_MASK          (0x3)
+#define EVNT_RF                   (1<<5)  /* Indicates whether the event is a rise or falling event */
+#define EVNT_NUM_SHIFT            (2)     /* Indicates Event Timestamp Unit which detected an event */
+#define EVNT_NUM_MASK             (0x7)
+#define MULT_EVNT                 (1<<1)  /* Indicates multiple events were detected at the same time */
+#define EVENT_DET                 (1<<0)  /* PTP Event Detected */
+
+/* Bit definitions for the PTP_EDATA register */
+#define E7_RISE                   (1<<15) /* Indicates direction of Event 7 */
+#define E7_DET                    (1<<14) /* Indicates Event 7 detected */
+#define E6_RISE                   (1<<13) /* Indicates direction of Event 6 */
+#define E6_DET                    (1<<12) /* Indicates Event 6 detected */
+#define E5_RISE                   (1<<11) /* Indicates direction of Event 5 */
+#define E5_DET                    (1<<10) /* Indicates Event 5 detected */
+#define E4_RISE                   (1<<9)  /* Indicates direction of Event 4 */
+#define E4_DET                    (1<<8)  /* Indicates Event 4 detected */
+#define E3_RISE                   (1<<7)  /* Indicates direction of Event 3 */
+#define E3_DET                    (1<<6)  /* Indicates Event 3 detected */
+#define E2_RISE                   (1<<5)  /* Indicates direction of Event 2 */
+#define E2_DET                    (1<<4)  /* Indicates Event 2 detected */
+#define E1_RISE                   (1<<3)  /* Indicates direction of Event 1 */
+#define E1_DET                    (1<<2)  /* Indicates Event 1 detected */
+#define E0_RISE                   (1<<1)  /* Indicates direction of Event 0 */
+#define E0_DET                    (1<<0)  /* Indicates Event 0 detected */
+
+/* Bit definitions for the PTP_TRIG register */
+#define TRIG_PULSE                (1<<15) /* generate a Pulse rather than a single edge */
+#define TRIG_PER                  (1<<14) /* generate a periodic signal */
+#define TRIG_IF_LATE              (1<<13) /* trigger immediately if already past */
+#define TRIG_NOTIFY               (1<<12) /* Trigger Notification Enable */
+#define TRIG_GPIO_SHIFT           (8)     /* Trigger GPIO Connection, value 1-12 */
+#define TRIG_GPIO_MASK            (0xf)
+#define TRIG_TOGGLE               (1<<7)  /* Trigger Toggle Mode Enable */
+#define TRIG_CSEL_SHIFT           (1)     /* Trigger Configuration Select */
+#define TRIG_CSEL_MASK            (0x7)
+#define TRIG_WR                   (1<<0)  /* Trigger Configuration Write */
+
+/* Bit definitions for the PTP_EVNT register */
+#define EVNT_RISE                 (1<<14) /* Event Rise Detect Enable */
+#define EVNT_FALL                 (1<<13) /* Event Fall Detect Enable */
+#define EVNT_SINGLE               (1<<12) /* enable single event capture operation */
+#define EVNT_GPIO_SHIFT           (8)     /* Event GPIO Connection, value 1-12 */
+#define EVNT_GPIO_MASK            (0xf)
+#define EVNT_SEL_SHIFT            (1)     /* Event Select */
+#define EVNT_SEL_MASK             (0x7)
+#define EVNT_WR                   (1<<0)  /* Event Configuration Write */
+
+/* Bit definitions for the PTP_TXCFG0 register */
+#define SYNC_1STEP                (1<<15) /* insert timestamp into transmit Sync Messages */
+#define DR_INSERT                 (1<<13) /* Insert Delay_Req Timestamp in Delay_Resp (dangerous) */
+#define NTP_TS_EN                 (1<<12) /* Enable Timestamping of NTP Packets */
+#define IGNORE_2STEP              (1<<11) /* Ignore Two_Step flag for One-Step operation */
+#define CRC_1STEP                 (1<<10) /* Disable checking of CRC for One-Step operation */
+#define CHK_1STEP                 (1<<9)  /* Enable UDP Checksum correction for One-Step Operation */
+#define IP1588_EN                 (1<<8)  /* Enable IEEE 1588 defined IP address filter */
+#define TX_L2_EN                  (1<<7)  /* Layer2 Timestamp Enable */
+#define TX_IPV6_EN                (1<<6)  /* IPv6 Timestamp Enable */
+#define TX_IPV4_EN                (1<<5)  /* IPv4 Timestamp Enable */
+#define TX_PTP_VER_SHIFT          (1)     /* Enable Timestamp capture for IEEE 1588 version X */
+#define TX_PTP_VER_MASK           (0xf)
+#define TX_TS_EN                  (1<<0)  /* Transmit Timestamp Enable */
+
+/* Bit definitions for the PTP_TXCFG1 register */
+#define BYTE0_MASK_SHIFT          (8)     /* Bit mask to be used for matching Byte0 of the PTP Message */
+#define BYTE0_MASK_MASK           (0xff)
+#define BYTE0_DATA_SHIFT          (0)     /* Data to be used for matching Byte0 of the PTP Message */
+#define BYTE0_DATA_MASK           (0xff)
+
+/* Bit definitions for the PSF_CFG0 register */
+#define MAC_SRC_ADD_SHIFT         (11)    /* Status Frame Mac Source Address */
+#define MAC_SRC_ADD_MASK          (0x3)
+#define MIN_PRE_SHIFT             (8)     /* Status Frame Minimum Preamble */
+#define MIN_PRE_MASK              (0x7)
+#define PSF_ENDIAN                (1<<7)  /* Status Frame Endian Control */
+#define PSF_IPV4                  (1<<6)  /* Status Frame IPv4 Enable */
+#define PSF_PCF_RD                (1<<5)  /* Control Frame Read PHY Status Frame Enable */
+#define PSF_ERR_EN                (1<<4)  /* Error PHY Status Frame Enable */
+#define PSF_TXTS_EN               (1<<3)  /* Transmit Timestamp PHY Status Frame Enable */
+#define PSF_RXTS_EN               (1<<2)  /* Receive Timestamp PHY Status Frame Enable */
+#define PSF_TRIG_EN               (1<<1)  /* Trigger PHY Status Frame Enable */
+#define PSF_EVNT_EN               (1<<0)  /* Event PHY Status Frame Enable */
+
+/* Bit definitions for the PTP_RXCFG0 register */
+#define DOMAIN_EN                 (1<<15) /* Domain Match Enable */
+#define ALT_MAST_DIS              (1<<14) /* Alternate Master Timestamp Disable */
+#define USER_IP_SEL               (1<<13) /* Selects portion of IP address accessible thru PTP_RXCFG2 */
+#define USER_IP_EN                (1<<12) /* Enable User-programmed IP address filter */
+#define RX_SLAVE                  (1<<11) /* Receive Slave Only */
+#define IP1588_EN_SHIFT           (8)     /* Enable IEEE 1588 defined IP address filters */
+#define IP1588_EN_MASK            (0xf)
+#define RX_L2_EN                  (1<<7)  /* Layer2 Timestamp Enable */
+#define RX_IPV6_EN                (1<<6)  /* IPv6 Timestamp Enable */
+#define RX_IPV4_EN                (1<<5)  /* IPv4 Timestamp Enable */
+#define RX_PTP_VER_SHIFT          (1)     /* Enable Timestamp capture for IEEE 1588 version X */
+#define RX_PTP_VER_MASK           (0xf)
+#define RX_TS_EN                  (1<<0)  /* Receive Timestamp Enable */
+
+/* Bit definitions for the PTP_RXCFG1 register */
+#define BYTE0_MASK_SHIFT          (8)     /* Bit mask to be used for matching Byte0 of the PTP Message */
+#define BYTE0_MASK_MASK           (0xff)
+#define BYTE0_DATA_SHIFT          (0)     /* Data to be used for matching Byte0 of the PTP Message */
+#define BYTE0_DATA_MASK           (0xff)
+
+/* Bit definitions for the PTP_RXCFG3 register */
+#define TS_MIN_IFG_SHIFT          (12)    /* Minimum Inter-frame Gap */
+#define TS_MIN_IFG_MASK           (0xf)
+#define ACC_UDP                   (1<<11) /* Record Timestamp if UDP Checksum Error */
+#define ACC_CRC                   (1<<10) /* Record Timestamp if CRC Error */
+#define TS_APPEND                 (1<<9)  /* Append Timestamp for L2 */
+#define TS_INSERT                 (1<<8)  /* Enable Timestamp Insertion */
+#define PTP_DOMAIN_SHIFT          (0)     /* PTP Message domainNumber field */
+#define PTP_DOMAIN_MASK           (0xff)
+
+/* Bit definitions for the PTP_RXCFG4 register */
+#define IPV4_UDP_MOD              (1<<15) /* Enable IPV4 UDP Modification */
+#define TS_SEC_EN                 (1<<14) /* Enable Timestamp Seconds */
+#define TS_SEC_LEN_SHIFT          (12)    /* Inserted Timestamp Seconds Length */
+#define TS_SEC_LEN_MASK           (0x3)
+#define RXTS_NS_OFF_SHIFT         (6)     /* Receive Timestamp Nanoseconds offset */
+#define RXTS_NS_OFF_MASK          (0x3f)
+#define RXTS_SEC_OFF_SHIFT        (0)     /* Receive Timestamp Seconds offset */
+#define RXTS_SEC_OFF_MASK         (0x3f)
+
+/* Bit definitions for the PTP_COC register */
+#define PTP_CLKOUT_EN             (1<<15) /* PTP Clock Output Enable */
+#define PTP_CLKOUT_SEL            (1<<14) /* PTP Clock Output Source Select */
+#define PTP_CLKOUT_SPEEDSEL       (1<<13) /* PTP Clock Output I/O Speed Select */
+#define PTP_CLKDIV_SHIFT          (0)     /* PTP Clock Divide-by Value */
+#define PTP_CLKDIV_MASK           (0xff)
+
+/* Bit definitions for the PSF_CFG1 register */
+#define PTPRESERVED_SHIFT         (12)    /* PTP v2 reserved field */
+#define PTPRESERVED_MASK          (0xf)
+#define VERSIONPTP_SHIFT          (8)     /* PTP v2 versionPTP field */
+#define VERSIONPTP_MASK           (0xf)
+#define TRANSPORT_SPECIFIC_SHIFT  (4)     /* PTP v2 Header transportSpecific field */
+#define TRANSPORT_SPECIFIC_MASK   (0xf)
+#define MESSAGETYPE_SHIFT         (0)     /* PTP v2 messageType field */
+#define MESSAGETYPE_MASK          (0xf)
+
+/* Bit definitions for the PTP_SFDCFG register */
+#define TX_SFD_GPIO_SHIFT         (4)     /* TX SFD GPIO Select, value 1-12 */
+#define TX_SFD_GPIO_MASK          (0xf)
+#define RX_SFD_GPIO_SHIFT         (0)     /* RX SFD GPIO Select, value 1-12 */
+#define RX_SFD_GPIO_MASK          (0xf)
+
+/* Bit definitions for the PTP_INTCTL register */
+#define PTP_INT_GPIO_SHIFT        (0)     /* PTP Interrupt GPIO Select */
+#define PTP_INT_GPIO_MASK         (0xf)
+
+/* Bit definitions for the PTP_CLKSRC register */
+#define CLK_SRC_SHIFT             (14)    /* PTP Clock Source Select */
+#define CLK_SRC_MASK              (0x3)
+#define CLK_SRC_PER_SHIFT         (0)     /* PTP Clock Source Period */
+#define CLK_SRC_PER_MASK          (0x7f)
+
+/* Bit definitions for the PTP_OFF register */
+#define PTP_OFFSET_SHIFT          (0)     /* PTP Message offset from preceding header */
+#define PTP_OFFSET_MASK           (0xff)
+
+#endif
diff -druN linux-2.6.39-libre/drivers/net/phy/Kconfig linux-3.0-rc7-libre/drivers/net/phy/Kconfig
--- linux-2.6.39-libre/drivers/net/phy/Kconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/phy/Kconfig	2011-07-11 19:51:52.000000000 -0400
@@ -58,6 +58,7 @@
 
 config BCM63XX_PHY
 	tristate "Drivers for Broadcom 63xx SOCs internal PHY"
+	depends on BCM63XX
 	---help---
 	  Currently supports the 6348 and 6358 PHYs.
 
diff -druN linux-2.6.39-libre/drivers/net/phy/Makefile linux-3.0-rc7-libre/drivers/net/phy/Makefile
--- linux-2.6.39-libre/drivers/net/phy/Makefile	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/phy/Makefile	2011-07-11 19:51:52.000000000 -0400
@@ -19,6 +19,7 @@
 obj-$(CONFIG_MDIO_BITBANG)	+= mdio-bitbang.o
 obj-$(CONFIG_MDIO_GPIO)		+= mdio-gpio.o
 obj-$(CONFIG_NATIONAL_PHY)	+= national.o
+obj-$(CONFIG_DP83640_PHY)	+= dp83640.o
 obj-$(CONFIG_STE10XP)		+= ste10Xp.o
 obj-$(CONFIG_MICREL_PHY)	+= micrel.o
 obj-$(CONFIG_MDIO_OCTEON)	+= mdio-octeon.o
diff -druN linux-2.6.39-libre/drivers/net/phy/phy.c linux-3.0-rc7-libre/drivers/net/phy/phy.c
--- linux-2.6.39-libre/drivers/net/phy/phy.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/phy/phy.c	2011-07-11 19:51:52.000000000 -0400
@@ -238,6 +238,8 @@
  */
 int phy_ethtool_sset(struct phy_device *phydev, struct ethtool_cmd *cmd)
 {
+	u32 speed = ethtool_cmd_speed(cmd);
+
 	if (cmd->phy_address != phydev->addr)
 		return -EINVAL;
 
@@ -253,16 +255,16 @@
 		return -EINVAL;
 
 	if (cmd->autoneg == AUTONEG_DISABLE &&
-	    ((cmd->speed != SPEED_1000 &&
-	      cmd->speed != SPEED_100 &&
-	      cmd->speed != SPEED_10) ||
+	    ((speed != SPEED_1000 &&
+	      speed != SPEED_100 &&
+	      speed != SPEED_10) ||
 	     (cmd->duplex != DUPLEX_HALF &&
 	      cmd->duplex != DUPLEX_FULL)))
 		return -EINVAL;
 
 	phydev->autoneg = cmd->autoneg;
 
-	phydev->speed = cmd->speed;
+	phydev->speed = speed;
 
 	phydev->advertising = cmd->advertising;
 
@@ -286,7 +288,7 @@
 
 	cmd->advertising = phydev->advertising;
 
-	cmd->speed = phydev->speed;
+	ethtool_cmd_speed_set(cmd, phydev->speed);
 	cmd->duplex = phydev->duplex;
 	cmd->port = PORT_MII;
 	cmd->phy_address = phydev->addr;
diff -druN linux-2.6.39-libre/drivers/net/ppp_async.c linux-3.0-rc7-libre/drivers/net/ppp_async.c
--- linux-2.6.39-libre/drivers/net/ppp_async.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/ppp_async.c	2011-07-11 19:51:52.000000000 -0400
@@ -523,7 +523,7 @@
 #define PUT_BYTE(ap, buf, c, islcp)	do {		\
 	if ((islcp && c < 0x20) || (ap->xaccm[c >> 5] & (1 << (c & 0x1f)))) {\
 		*buf++ = PPP_ESCAPE;			\
-		*buf++ = c ^ 0x20;			\
+		*buf++ = c ^ PPP_TRANS;			\
 	} else						\
 		*buf++ = c;				\
 } while (0)
@@ -896,7 +896,7 @@
 				sp = skb_put(skb, n);
 				memcpy(sp, buf, n);
 				if (ap->state & SC_ESCAPE) {
-					sp[0] ^= 0x20;
+					sp[0] ^= PPP_TRANS;
 					ap->state &= ~SC_ESCAPE;
 				}
 			}
diff -druN linux-2.6.39-libre/drivers/net/ppp_deflate.c linux-3.0-rc7-libre/drivers/net/ppp_deflate.c
--- linux-2.6.39-libre/drivers/net/ppp_deflate.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/ppp_deflate.c	2011-07-11 19:51:52.000000000 -0400
@@ -305,7 +305,7 @@
 
 	if (state) {
 		zlib_inflateEnd(&state->strm);
-		kfree(state->strm.workspace);
+		vfree(state->strm.workspace);
 		kfree(state);
 	}
 }
@@ -345,8 +345,7 @@
 
 	state->w_size         = w_size;
 	state->strm.next_out  = NULL;
-	state->strm.workspace = kmalloc(zlib_inflate_workspacesize(),
-					GFP_KERNEL|__GFP_REPEAT);
+	state->strm.workspace = vmalloc(zlib_inflate_workspacesize());
 	if (state->strm.workspace == NULL)
 		goto out_free;
 
diff -druN linux-2.6.39-libre/drivers/net/pptp.c linux-3.0-rc7-libre/drivers/net/pptp.c
--- linux-2.6.39-libre/drivers/net/pptp.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/pptp.c	2011-07-11 19:51:52.000000000 -0400
@@ -175,6 +175,7 @@
 	struct pptp_opt *opt = &po->proto.pptp;
 	struct pptp_gre_header *hdr;
 	unsigned int header_len = sizeof(*hdr);
+	struct flowi4 fl4;
 	int islcp;
 	int len;
 	unsigned char *data;
@@ -189,7 +190,7 @@
 	if (sk_pppox(po)->sk_state & PPPOX_DEAD)
 		goto tx_error;
 
-	rt = ip_route_output_ports(&init_net, NULL,
+	rt = ip_route_output_ports(&init_net, &fl4, NULL,
 				   opt->dst_addr.sin_addr.s_addr,
 				   opt->src_addr.sin_addr.s_addr,
 				   0, 0, IPPROTO_GRE,
@@ -270,8 +271,8 @@
 		iph->frag_off	=	0;
 	iph->protocol = IPPROTO_GRE;
 	iph->tos      = 0;
-	iph->daddr    = rt->rt_dst;
-	iph->saddr    = rt->rt_src;
+	iph->daddr    = fl4.daddr;
+	iph->saddr    = fl4.saddr;
 	iph->ttl      = ip4_dst_hoplimit(&rt->dst);
 	iph->tot_len  = htons(skb->len);
 
@@ -434,6 +435,7 @@
 	struct pppox_sock *po = pppox_sk(sk);
 	struct pptp_opt *opt = &po->proto.pptp;
 	struct rtable *rt;
+	struct flowi4 fl4;
 	int error = 0;
 
 	if (sp->sa_protocol != PX_PROTO_PPTP)
@@ -463,7 +465,7 @@
 	po->chan.private = sk;
 	po->chan.ops = &pptp_chan_ops;
 
-	rt = ip_route_output_ports(&init_net, sk,
+	rt = ip_route_output_ports(&init_net, &fl4, sk,
 				   opt->dst_addr.sin_addr.s_addr,
 				   opt->src_addr.sin_addr.s_addr,
 				   0, 0,
diff -druN linux-2.6.39-libre/drivers/net/ps3_gelic_net.c linux-3.0-rc7-libre/drivers/net/ps3_gelic_net.c
--- linux-2.6.39-libre/drivers/net/ps3_gelic_net.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/ps3_gelic_net.c	2011-07-11 19:51:52.000000000 -0400
@@ -951,7 +951,7 @@
 	skb->protocol = eth_type_trans(skb, netdev);
 
 	/* checksum offload */
-	if (card->rx_csum) {
+	if (netdev->features & NETIF_F_RXCSUM) {
 		if ((data_status & GELIC_DESCR_DATA_STATUS_CHK_MASK) &&
 		    (!(data_error & GELIC_DESCR_DATA_ERROR_CHK_MASK)))
 			skb->ip_summed = CHECKSUM_UNNECESSARY;
@@ -1243,17 +1243,17 @@
 
 	switch (card->ether_port_status & GELIC_LV1_ETHER_SPEED_MASK) {
 	case GELIC_LV1_ETHER_SPEED_10:
-		cmd->speed = SPEED_10;
+		ethtool_cmd_speed_set(cmd, SPEED_10);
 		break;
 	case GELIC_LV1_ETHER_SPEED_100:
-		cmd->speed = SPEED_100;
+		ethtool_cmd_speed_set(cmd, SPEED_100);
 		break;
 	case GELIC_LV1_ETHER_SPEED_1000:
-		cmd->speed = SPEED_1000;
+		ethtool_cmd_speed_set(cmd, SPEED_1000);
 		break;
 	default:
 		pr_info("%s: speed unknown\n", __func__);
-		cmd->speed = SPEED_10;
+		ethtool_cmd_speed_set(cmd, SPEED_10);
 		break;
 	}
 
@@ -1312,21 +1312,6 @@
 	return 0;
 }
 
-u32 gelic_net_get_rx_csum(struct net_device *netdev)
-{
-	struct gelic_card *card = netdev_card(netdev);
-
-	return card->rx_csum;
-}
-
-int gelic_net_set_rx_csum(struct net_device *netdev, u32 data)
-{
-	struct gelic_card *card = netdev_card(netdev);
-
-	card->rx_csum = data;
-	return 0;
-}
-
 static void gelic_net_get_wol(struct net_device *netdev,
 			      struct ethtool_wolinfo *wol)
 {
@@ -1411,10 +1396,6 @@
 	.get_settings	= gelic_ether_get_settings,
 	.set_settings	= gelic_ether_set_settings,
 	.get_link	= ethtool_op_get_link,
-	.get_tx_csum	= ethtool_op_get_tx_csum,
-	.set_tx_csum	= ethtool_op_set_tx_csum,
-	.get_rx_csum	= gelic_net_get_rx_csum,
-	.set_rx_csum	= gelic_net_set_rx_csum,
 	.get_wol	= gelic_net_get_wol,
 	.set_wol	= gelic_net_set_wol,
 };
@@ -1512,7 +1493,11 @@
 	int status;
 	u64 v1, v2;
 
+	netdev->hw_features = NETIF_F_IP_CSUM | NETIF_F_RXCSUM;
+
 	netdev->features = NETIF_F_IP_CSUM;
+	if (GELIC_CARD_RX_CSUM_DEFAULT)
+		netdev->features |= NETIF_F_RXCSUM;
 
 	status = lv1_net_control(bus_id(card), dev_id(card),
 				 GELIC_LV1_GET_MAC_ADDRESS,
@@ -1756,7 +1741,6 @@
 	/* setup card structure */
 	card->irq_mask = GELIC_CARD_RXINT | GELIC_CARD_TXINT |
 		GELIC_CARD_PORT_STATUS_CHANGED;
-	card->rx_csum = GELIC_CARD_RX_CSUM_DEFAULT;
 
 
 	if (gelic_card_init_chain(card, &card->tx_chain,
diff -druN linux-2.6.39-libre/drivers/net/ps3_gelic_net.h linux-3.0-rc7-libre/drivers/net/ps3_gelic_net.h
--- linux-2.6.39-libre/drivers/net/ps3_gelic_net.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/ps3_gelic_net.h	2011-07-11 19:51:52.000000000 -0400
@@ -290,7 +290,6 @@
 	struct gelic_descr_chain tx_chain;
 	struct gelic_descr_chain rx_chain;
 	int rx_dma_restart_required;
-	int rx_csum;
 	/*
 	 * tx_lock guards tx descriptor list and
 	 * tx_dma_progress.
@@ -377,8 +376,6 @@
 /* shared ethtool ops */
 extern void gelic_net_get_drvinfo(struct net_device *netdev,
 				  struct ethtool_drvinfo *info);
-extern u32 gelic_net_get_rx_csum(struct net_device *netdev);
-extern int gelic_net_set_rx_csum(struct net_device *netdev, u32 data);
 extern void gelic_net_poll_controller(struct net_device *netdev);
 
 #endif /* _GELIC_NET_H */
diff -druN linux-2.6.39-libre/drivers/net/ps3_gelic_wireless.c linux-3.0-rc7-libre/drivers/net/ps3_gelic_wireless.c
--- linux-2.6.39-libre/drivers/net/ps3_gelic_wireless.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/ps3_gelic_wireless.c	2011-07-11 19:51:52.000000000 -0400
@@ -2581,10 +2581,6 @@
 static const struct ethtool_ops gelic_wl_ethtool_ops = {
 	.get_drvinfo	= gelic_net_get_drvinfo,
 	.get_link	= gelic_wl_get_link,
-	.get_tx_csum	= ethtool_op_get_tx_csum,
-	.set_tx_csum	= ethtool_op_set_tx_csum,
-	.get_rx_csum	= gelic_net_get_rx_csum,
-	.set_rx_csum	= gelic_net_set_rx_csum,
 };
 
 static void __devinit gelic_wl_setup_netdev_ops(struct net_device *netdev)
diff -druN linux-2.6.39-libre/drivers/net/pxa168_eth.c linux-3.0-rc7-libre/drivers/net/pxa168_eth.c
--- linux-2.6.39-libre/drivers/net/pxa168_eth.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/pxa168_eth.c	2011-07-11 19:51:52.000000000 -0400
@@ -1273,7 +1273,7 @@
 	wmb();
 	wrl(pep, SDMA_CMD, SDMA_CMD_TXDH | SDMA_CMD_ERD);
 
-	stats->tx_bytes += skb->len;
+	stats->tx_bytes += length;
 	stats->tx_packets++;
 	dev->trans_start = jiffies;
 	if (pep->tx_ring_size - pep->tx_desc_count <= 1) {
diff -druN linux-2.6.39-libre/drivers/net/qla3xxx.c linux-3.0-rc7-libre/drivers/net/qla3xxx.c
--- linux-2.6.39-libre/drivers/net/qla3xxx.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/qla3xxx.c	2011-07-11 19:51:52.000000000 -0400
@@ -35,6 +35,7 @@
 #include <linux/if_vlan.h>
 #include <linux/delay.h>
 #include <linux/mm.h>
+#include <linux/prefetch.h>
 
 #include "qla3xxx.h"
 
@@ -1725,7 +1726,7 @@
 	}
 	ecmd->advertising = ql_supported_modes(qdev);
 	ecmd->autoneg = ql_get_auto_cfg_status(qdev);
-	ecmd->speed = ql_get_speed(qdev);
+	ethtool_cmd_speed_set(ecmd, ql_get_speed(qdev));
 	ecmd->duplex = ql_get_full_dup(qdev);
 	return 0;
 }
@@ -3468,7 +3469,7 @@
 {
 	struct net_device *ndev = qdev->ndev;
 	int err;
-	unsigned long irq_flags = IRQF_SAMPLE_RANDOM | IRQF_SHARED;
+	unsigned long irq_flags = IRQF_SHARED;
 	unsigned long hw_flags;
 
 	if (ql_alloc_mem_resources(qdev)) {
diff -druN linux-2.6.39-libre/drivers/net/qlcnic/qlcnic_ctx.c linux-3.0-rc7-libre/drivers/net/qlcnic/qlcnic_ctx.c
--- linux-2.6.39-libre/drivers/net/qlcnic/qlcnic_ctx.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/qlcnic/qlcnic_ctx.c	2011-07-11 19:51:52.000000000 -0400
@@ -64,14 +64,105 @@
 	return rcode;
 }
 
+static uint32_t qlcnic_temp_checksum(uint32_t *temp_buffer, u16 temp_size)
+{
+	uint64_t sum = 0;
+	int count = temp_size / sizeof(uint32_t);
+	while (count-- > 0)
+		sum += *temp_buffer++;
+	while (sum >> 32)
+		sum = (sum & 0xFFFFFFFF) + (sum >> 32);
+	return ~sum;
+}
+
+int qlcnic_fw_cmd_get_minidump_temp(struct qlcnic_adapter *adapter)
+{
+	int err, i;
+	u16 temp_size;
+	void *tmp_addr;
+	u32 version, csum, *template, *tmp_buf;
+	struct qlcnic_hardware_context *ahw;
+	struct qlcnic_dump_template_hdr *tmpl_hdr, *tmp_tmpl;
+	dma_addr_t tmp_addr_t = 0;
+
+	ahw = adapter->ahw;
+	err = qlcnic_issue_cmd(adapter,
+			adapter->ahw->pci_func,
+			adapter->fw_hal_version,
+			0,
+			0,
+			0,
+			QLCNIC_CDRP_CMD_TEMP_SIZE);
+	if (err != QLCNIC_RCODE_SUCCESS) {
+		err = QLCRD32(adapter, QLCNIC_ARG1_CRB_OFFSET);
+		dev_err(&adapter->pdev->dev,
+			"Failed to get template size %d\n", err);
+		err = -EIO;
+		return err;
+	}
+	version = QLCRD32(adapter, QLCNIC_ARG3_CRB_OFFSET);
+	temp_size = QLCRD32(adapter, QLCNIC_ARG2_CRB_OFFSET);
+	if (!temp_size)
+		return -EIO;
+
+	tmp_addr = dma_alloc_coherent(&adapter->pdev->dev, temp_size,
+			&tmp_addr_t, GFP_KERNEL);
+	if (!tmp_addr) {
+		dev_err(&adapter->pdev->dev,
+			"Can't get memory for FW dump template\n");
+		return -ENOMEM;
+	}
+	err = qlcnic_issue_cmd(adapter,
+		adapter->ahw->pci_func,
+		adapter->fw_hal_version,
+		LSD(tmp_addr_t),
+		MSD(tmp_addr_t),
+		temp_size,
+		QLCNIC_CDRP_CMD_GET_TEMP_HDR);
+
+	if (err != QLCNIC_RCODE_SUCCESS) {
+		dev_err(&adapter->pdev->dev,
+			"Failed to get mini dump template header %d\n", err);
+		err = -EIO;
+		goto error;
+	}
+	tmp_tmpl = (struct qlcnic_dump_template_hdr *) tmp_addr;
+	csum = qlcnic_temp_checksum((uint32_t *) tmp_addr, temp_size);
+	if (csum) {
+		dev_err(&adapter->pdev->dev,
+			"Template header checksum validation failed\n");
+		err = -EIO;
+		goto error;
+	}
+	ahw->fw_dump.tmpl_hdr = vzalloc(temp_size);
+	if (!ahw->fw_dump.tmpl_hdr) {
+		err = -EIO;
+		goto error;
+	}
+	tmp_buf = (u32 *) tmp_addr;
+	template = (u32 *) ahw->fw_dump.tmpl_hdr;
+	for (i = 0; i < temp_size/sizeof(u32); i++)
+		*template++ = __le32_to_cpu(*tmp_buf++);
+
+	tmpl_hdr = ahw->fw_dump.tmpl_hdr;
+	if (tmpl_hdr->cap_mask > QLCNIC_DUMP_MASK_DEF &&
+		tmpl_hdr->cap_mask <= QLCNIC_DUMP_MASK_MAX)
+		tmpl_hdr->drv_cap_mask = tmpl_hdr->cap_mask;
+	else
+		tmpl_hdr->drv_cap_mask = QLCNIC_DUMP_MASK_DEF;
+error:
+	dma_free_coherent(&adapter->pdev->dev, temp_size, tmp_addr, tmp_addr_t);
+	return err;
+}
+
 int
 qlcnic_fw_cmd_set_mtu(struct qlcnic_adapter *adapter, int mtu)
 {
-	struct qlcnic_recv_context *recv_ctx = &adapter->recv_ctx;
+	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,
+			adapter->ahw->pci_func,
 			adapter->fw_hal_version,
 			recv_ctx->context_id,
 			mtu,
@@ -102,12 +193,12 @@
 	dma_addr_t hostrq_phys_addr, cardrsp_phys_addr;
 	u64 phys_addr;
 
-	int i, nrds_rings, nsds_rings;
+	u8 i, nrds_rings, nsds_rings;
 	size_t rq_size, rsp_size;
 	u32 cap, reg, val, reg2;
 	int err;
 
-	struct qlcnic_recv_context *recv_ctx = &adapter->recv_ctx;
+	struct qlcnic_recv_context *recv_ctx = adapter->recv_ctx;
 
 	nrds_rings = adapter->max_rds_rings;
 	nsds_rings = adapter->max_sds_rings;
@@ -119,14 +210,14 @@
 		SIZEOF_CARDRSP_RX(struct qlcnic_cardrsp_rx_ctx, nrds_rings,
 						nsds_rings);
 
-	addr = pci_alloc_consistent(adapter->pdev,
-				rq_size, &hostrq_phys_addr);
+	addr = dma_alloc_coherent(&adapter->pdev->dev, rq_size,
+			&hostrq_phys_addr, GFP_KERNEL);
 	if (addr == NULL)
 		return -ENOMEM;
 	prq = (struct qlcnic_hostrq_rx_ctx *)addr;
 
-	addr = pci_alloc_consistent(adapter->pdev,
-			rsp_size, &cardrsp_phys_addr);
+	addr = dma_alloc_coherent(&adapter->pdev->dev, rsp_size,
+			&cardrsp_phys_addr, GFP_KERNEL);
 	if (addr == NULL) {
 		err = -ENOMEM;
 		goto out_free_rq;
@@ -151,7 +242,7 @@
 
 	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);
+	prq->rds_ring_offset = 0;
 
 	val = le32_to_cpu(prq->rds_ring_offset) +
 		(sizeof(struct qlcnic_hostrq_rds_ring) * nrds_rings);
@@ -187,7 +278,7 @@
 
 	phys_addr = hostrq_phys_addr;
 	err = qlcnic_issue_cmd(adapter,
-			adapter->ahw.pci_func,
+			adapter->ahw->pci_func,
 			adapter->fw_hal_version,
 			(u32)(phys_addr >> 32),
 			(u32)(phys_addr & 0xffffffff),
@@ -207,7 +298,7 @@
 		rds_ring = &recv_ctx->rds_rings[i];
 
 		reg = le32_to_cpu(prsp_rds[i].host_producer_crb);
-		rds_ring->crb_rcv_producer = adapter->ahw.pci_base0 + reg;
+		rds_ring->crb_rcv_producer = adapter->ahw->pci_base0 + reg;
 	}
 
 	prsp_sds = ((struct qlcnic_cardrsp_sds_ring *)
@@ -219,8 +310,8 @@
 		reg = le32_to_cpu(prsp_sds[i].host_consumer_crb);
 		reg2 = le32_to_cpu(prsp_sds[i].interrupt_crb);
 
-		sds_ring->crb_sts_consumer = adapter->ahw.pci_base0 + reg;
-		sds_ring->crb_intr_mask = adapter->ahw.pci_base0 + reg2;
+		sds_ring->crb_sts_consumer = adapter->ahw->pci_base0 + reg;
+		sds_ring->crb_intr_mask = adapter->ahw->pci_base0 + reg2;
 	}
 
 	recv_ctx->state = le32_to_cpu(prsp->host_ctx_state);
@@ -228,19 +319,20 @@
 	recv_ctx->virt_port = prsp->virt_port;
 
 out_free_rsp:
-	pci_free_consistent(adapter->pdev, rsp_size, prsp, cardrsp_phys_addr);
+	dma_free_coherent(&adapter->pdev->dev, rsp_size, prsp,
+		cardrsp_phys_addr);
 out_free_rq:
-	pci_free_consistent(adapter->pdev, rq_size, prq, hostrq_phys_addr);
+	dma_free_coherent(&adapter->pdev->dev, 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;
+	struct qlcnic_recv_context *recv_ctx = adapter->recv_ctx;
 
 	if (qlcnic_issue_cmd(adapter,
-			adapter->ahw.pci_func,
+			adapter->ahw->pci_func,
 			adapter->fw_hal_version,
 			recv_ctx->context_id,
 			QLCNIC_DESTROY_CTX_RESET,
@@ -274,14 +366,14 @@
 	*(tx_ring->hw_consumer) = 0;
 
 	rq_size = SIZEOF_HOSTRQ_TX(struct qlcnic_hostrq_tx_ctx);
-	rq_addr = pci_alloc_consistent(adapter->pdev,
-		rq_size, &rq_phys_addr);
+	rq_addr = dma_alloc_coherent(&adapter->pdev->dev, rq_size,
+			&rq_phys_addr, GFP_KERNEL);
 	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);
+	rsp_addr = dma_alloc_coherent(&adapter->pdev->dev, rsp_size,
+			&rsp_phys_addr, GFP_KERNEL);
 	if (!rsp_addr) {
 		err = -ENOMEM;
 		goto out_free_rq;
@@ -313,7 +405,7 @@
 
 	phys_addr = rq_phys_addr;
 	err = qlcnic_issue_cmd(adapter,
-			adapter->ahw.pci_func,
+			adapter->ahw->pci_func,
 			adapter->fw_hal_version,
 			(u32)(phys_addr >> 32),
 			((u32)phys_addr & 0xffffffff),
@@ -322,7 +414,7 @@
 
 	if (err == QLCNIC_RCODE_SUCCESS) {
 		temp = le32_to_cpu(prsp->cds_ring.host_producer_crb);
-		tx_ring->crb_cmd_producer = adapter->ahw.pci_base0 + temp;
+		tx_ring->crb_cmd_producer = adapter->ahw->pci_base0 + temp;
 
 		adapter->tx_context_id =
 			le16_to_cpu(prsp->context_id);
@@ -332,10 +424,11 @@
 		err = -EIO;
 	}
 
-	pci_free_consistent(adapter->pdev, rsp_size, rsp_addr, rsp_phys_addr);
+	dma_free_coherent(&adapter->pdev->dev, rsp_size, rsp_addr,
+		rsp_phys_addr);
 
 out_free_rq:
-	pci_free_consistent(adapter->pdev, rq_size, rq_addr, rq_phys_addr);
+	dma_free_coherent(&adapter->pdev->dev, rq_size, rq_addr, rq_phys_addr);
 
 	return err;
 }
@@ -344,7 +437,7 @@
 qlcnic_fw_cmd_destroy_tx_ctx(struct qlcnic_adapter *adapter)
 {
 	if (qlcnic_issue_cmd(adapter,
-			adapter->ahw.pci_func,
+			adapter->ahw->pci_func,
 			adapter->fw_hal_version,
 			adapter->tx_context_id,
 			QLCNIC_DESTROY_CTX_RESET,
@@ -357,33 +450,15 @@
 }
 
 int
-qlcnic_fw_cmd_query_phy(struct qlcnic_adapter *adapter, u32 reg, u32 *val)
-{
-
-	if (qlcnic_issue_cmd(adapter,
-			adapter->ahw.pci_func,
-			adapter->fw_hal_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)
+qlcnic_fw_cmd_set_port(struct qlcnic_adapter *adapter, u32 config)
 {
 	return qlcnic_issue_cmd(adapter,
-			adapter->ahw.pci_func,
+			adapter->ahw->pci_func,
 			adapter->fw_hal_version,
-			reg,
-			val,
+			config,
 			0,
-			QLCNIC_CDRP_CMD_WRITE_PHY);
+			0,
+			QLCNIC_CDRP_CMD_CONFIG_PORT);
 }
 
 int qlcnic_alloc_hw_resources(struct qlcnic_adapter *adapter)
@@ -398,20 +473,19 @@
 
 	struct pci_dev *pdev = adapter->pdev;
 
-	recv_ctx = &adapter->recv_ctx;
+	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);
+	tx_ring->hw_consumer = (__le32 *) dma_alloc_coherent(&pdev->dev,
+		sizeof(u32), &tx_ring->hw_cons_phys_addr, GFP_KERNEL);
 	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);
+	addr = dma_alloc_coherent(&pdev->dev, TX_DESC_RINGSIZE(tx_ring),
+			&tx_ring->phys_addr, GFP_KERNEL);
 
 	if (addr == NULL) {
 		dev_err(&pdev->dev, "failed to allocate tx desc ring\n");
@@ -423,9 +497,9 @@
 
 	for (ring = 0; ring < adapter->max_rds_rings; ring++) {
 		rds_ring = &recv_ctx->rds_rings[ring];
-		addr = pci_alloc_consistent(adapter->pdev,
+		addr = dma_alloc_coherent(&adapter->pdev->dev,
 				RCV_DESC_RINGSIZE(rds_ring),
-				&rds_ring->phys_addr);
+				&rds_ring->phys_addr, GFP_KERNEL);
 		if (addr == NULL) {
 			dev_err(&pdev->dev,
 				"failed to allocate rds ring [%d]\n", ring);
@@ -439,9 +513,9 @@
 	for (ring = 0; ring < adapter->max_sds_rings; ring++) {
 		sds_ring = &recv_ctx->sds_rings[ring];
 
-		addr = pci_alloc_consistent(adapter->pdev,
+		addr = dma_alloc_coherent(&adapter->pdev->dev,
 				STATUS_DESC_RINGSIZE(sds_ring),
-				&sds_ring->phys_addr);
+				&sds_ring->phys_addr, GFP_KERNEL);
 		if (addr == NULL) {
 			dev_err(&pdev->dev,
 				"failed to allocate sds ring [%d]\n", ring);
@@ -501,11 +575,11 @@
 	struct qlcnic_host_tx_ring *tx_ring;
 	int ring;
 
-	recv_ctx = &adapter->recv_ctx;
+	recv_ctx = adapter->recv_ctx;
 
 	tx_ring = adapter->tx_ring;
 	if (tx_ring->hw_consumer != NULL) {
-		pci_free_consistent(adapter->pdev,
+		dma_free_coherent(&adapter->pdev->dev,
 				sizeof(u32),
 				tx_ring->hw_consumer,
 				tx_ring->hw_cons_phys_addr);
@@ -513,7 +587,7 @@
 	}
 
 	if (tx_ring->desc_head != NULL) {
-		pci_free_consistent(adapter->pdev,
+		dma_free_coherent(&adapter->pdev->dev,
 				TX_DESC_RINGSIZE(tx_ring),
 				tx_ring->desc_head, tx_ring->phys_addr);
 		tx_ring->desc_head = NULL;
@@ -523,7 +597,7 @@
 		rds_ring = &recv_ctx->rds_rings[ring];
 
 		if (rds_ring->desc_head != NULL) {
-			pci_free_consistent(adapter->pdev,
+			dma_free_coherent(&adapter->pdev->dev,
 					RCV_DESC_RINGSIZE(rds_ring),
 					rds_ring->desc_head,
 					rds_ring->phys_addr);
@@ -535,7 +609,7 @@
 		sds_ring = &recv_ctx->sds_rings[ring];
 
 		if (sds_ring->desc_head != NULL) {
-			pci_free_consistent(adapter->pdev,
+			dma_free_coherent(&adapter->pdev->dev,
 				STATUS_DESC_RINGSIZE(sds_ring),
 				sds_ring->desc_head,
 				sds_ring->phys_addr);
@@ -551,9 +625,9 @@
 	int err;
 	u32 arg1;
 
-	arg1 = adapter->ahw.pci_func | BIT_8;
+	arg1 = adapter->ahw->pci_func | BIT_8;
 	err = qlcnic_issue_cmd(adapter,
-			adapter->ahw.pci_func,
+			adapter->ahw->pci_func,
 			adapter->fw_hal_version,
 			arg1,
 			0,
@@ -582,15 +656,15 @@
 	void *nic_info_addr;
 	size_t	nic_size = sizeof(struct qlcnic_info);
 
-	nic_info_addr = pci_alloc_consistent(adapter->pdev,
-		nic_size, &nic_dma_t);
+	nic_info_addr = dma_alloc_coherent(&adapter->pdev->dev, nic_size,
+				&nic_dma_t, GFP_KERNEL);
 	if (!nic_info_addr)
 		return -ENOMEM;
 	memset(nic_info_addr, 0, nic_size);
 
 	nic_info = (struct qlcnic_info *) nic_info_addr;
 	err = qlcnic_issue_cmd(adapter,
-			adapter->ahw.pci_func,
+			adapter->ahw->pci_func,
 			adapter->fw_hal_version,
 			MSD(nic_dma_t),
 			LSD(nic_dma_t),
@@ -623,7 +697,8 @@
 		err = -EIO;
 	}
 
-	pci_free_consistent(adapter->pdev, nic_size, nic_info_addr, nic_dma_t);
+	dma_free_coherent(&adapter->pdev->dev, nic_size, nic_info_addr,
+		nic_dma_t);
 	return err;
 }
 
@@ -639,8 +714,8 @@
 	if (adapter->op_mode != QLCNIC_MGMT_FUNC)
 		return err;
 
-	nic_info_addr = pci_alloc_consistent(adapter->pdev, nic_size,
-			&nic_dma_t);
+	nic_info_addr = dma_alloc_coherent(&adapter->pdev->dev, nic_size,
+			&nic_dma_t, GFP_KERNEL);
 	if (!nic_info_addr)
 		return -ENOMEM;
 
@@ -659,7 +734,7 @@
 	nic_info->max_tx_bw = cpu_to_le16(nic->max_tx_bw);
 
 	err = qlcnic_issue_cmd(adapter,
-			adapter->ahw.pci_func,
+			adapter->ahw->pci_func,
 			adapter->fw_hal_version,
 			MSD(nic_dma_t),
 			LSD(nic_dma_t),
@@ -672,7 +747,8 @@
 		err = -EIO;
 	}
 
-	pci_free_consistent(adapter->pdev, nic_size, nic_info_addr, nic_dma_t);
+	dma_free_coherent(&adapter->pdev->dev, nic_size, nic_info_addr,
+		nic_dma_t);
 	return err;
 }
 
@@ -687,15 +763,15 @@
 	size_t npar_size = sizeof(struct qlcnic_pci_info);
 	size_t pci_size = npar_size * QLCNIC_MAX_PCI_FUNC;
 
-	pci_info_addr = pci_alloc_consistent(adapter->pdev, pci_size,
-			&pci_info_dma_t);
+	pci_info_addr = dma_alloc_coherent(&adapter->pdev->dev, pci_size,
+			&pci_info_dma_t, GFP_KERNEL);
 	if (!pci_info_addr)
 		return -ENOMEM;
 	memset(pci_info_addr, 0, pci_size);
 
 	npar = (struct qlcnic_pci_info *) pci_info_addr;
 	err = qlcnic_issue_cmd(adapter,
-			adapter->ahw.pci_func,
+			adapter->ahw->pci_func,
 			adapter->fw_hal_version,
 			MSD(pci_info_dma_t),
 			LSD(pci_info_dma_t),
@@ -721,7 +797,7 @@
 		err = -EIO;
 	}
 
-	pci_free_consistent(adapter->pdev, pci_size, pci_info_addr,
+	dma_free_coherent(&adapter->pdev->dev, pci_size, pci_info_addr,
 		pci_info_dma_t);
 	return err;
 }
@@ -741,7 +817,7 @@
 	arg1 |= pci_func << 8;
 
 	err = qlcnic_issue_cmd(adapter,
-			adapter->ahw.pci_func,
+			adapter->ahw->pci_func,
 			adapter->fw_hal_version,
 			arg1,
 			0,
@@ -775,14 +851,14 @@
 		return -ENOMEM;
 
 	if (adapter->op_mode != QLCNIC_MGMT_FUNC &&
-	    func != adapter->ahw.pci_func) {
+	    func != adapter->ahw->pci_func) {
 		dev_err(&adapter->pdev->dev,
 			"Not privilege to query stats for func=%d", func);
 		return -EIO;
 	}
 
-	stats_addr = pci_alloc_consistent(adapter->pdev, stats_size,
-			&stats_dma_t);
+	stats_addr = dma_alloc_coherent(&adapter->pdev->dev, stats_size,
+			&stats_dma_t, GFP_KERNEL);
 	if (!stats_addr) {
 		dev_err(&adapter->pdev->dev, "Unable to allocate memory\n");
 		return -ENOMEM;
@@ -793,7 +869,7 @@
 	arg1 |= rx_tx << 15 | stats_size << 16;
 
 	err = qlcnic_issue_cmd(adapter,
-			adapter->ahw.pci_func,
+			adapter->ahw->pci_func,
 			adapter->fw_hal_version,
 			arg1,
 			MSD(stats_dma_t),
@@ -816,7 +892,7 @@
 		esw_stats->numbytes = le64_to_cpu(stats->numbytes);
 	}
 
-	pci_free_consistent(adapter->pdev, stats_size, stats_addr,
+	dma_free_coherent(&adapter->pdev->dev, stats_size, stats_addr,
 		stats_dma_t);
 	return err;
 }
@@ -900,7 +976,7 @@
 	arg1 |= BIT_14 | rx_tx << 15;
 
 	return qlcnic_issue_cmd(adapter,
-			adapter->ahw.pci_func,
+			adapter->ahw->pci_func,
 			adapter->fw_hal_version,
 			arg1,
 			0,
@@ -921,7 +997,7 @@
 	u8 pci_func;
 	pci_func = (*arg1 >> 8);
 	err = qlcnic_issue_cmd(adapter,
-			adapter->ahw.pci_func,
+			adapter->ahw->pci_func,
 			adapter->fw_hal_version,
 			*arg1,
 			0,
@@ -999,7 +1075,7 @@
 	}
 
 	err = qlcnic_issue_cmd(adapter,
-			adapter->ahw.pci_func,
+			adapter->ahw->pci_func,
 			adapter->fw_hal_version,
 			arg1,
 			arg2,
diff -druN linux-2.6.39-libre/drivers/net/qlcnic/qlcnic_ethtool.c linux-3.0-rc7-libre/drivers/net/qlcnic/qlcnic_ethtool.c
--- linux-2.6.39-libre/drivers/net/qlcnic/qlcnic_ethtool.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/qlcnic/qlcnic_ethtool.c	2011-07-11 19:51:52.000000000 -0400
@@ -150,10 +150,10 @@
 {
 	struct qlcnic_adapter *adapter = netdev_priv(dev);
 	int check_sfp_module = 0;
-	u16 pcifn = adapter->ahw.pci_func;
+	u16 pcifn = adapter->ahw->pci_func;
 
 	/* read which mode */
-	if (adapter->ahw.port_type == QLCNIC_GBE) {
+	if (adapter->ahw->port_type == QLCNIC_GBE) {
 		ecmd->supported = (SUPPORTED_10baseT_Half |
 				   SUPPORTED_10baseT_Full |
 				   SUPPORTED_100baseT_Half |
@@ -166,11 +166,11 @@
 				     ADVERTISED_1000baseT_Half |
 				     ADVERTISED_1000baseT_Full);
 
-		ecmd->speed = adapter->link_speed;
+		ethtool_cmd_speed_set(ecmd, adapter->link_speed);
 		ecmd->duplex = adapter->link_duplex;
 		ecmd->autoneg = adapter->link_autoneg;
 
-	} else if (adapter->ahw.port_type == QLCNIC_XGBE) {
+	} else if (adapter->ahw->port_type == QLCNIC_XGBE) {
 		u32 val;
 
 		val = QLCRD32(adapter, QLCNIC_PORT_MODE_ADDR);
@@ -183,15 +183,15 @@
 		}
 
 		if (netif_running(dev) && adapter->has_link_events) {
-			ecmd->speed = adapter->link_speed;
+			ethtool_cmd_speed_set(ecmd, adapter->link_speed);
 			ecmd->autoneg = adapter->link_autoneg;
 			ecmd->duplex = adapter->link_duplex;
 			goto skip;
 		}
 
 		val = QLCRD32(adapter, P3P_LINK_SPEED_REG(pcifn));
-		ecmd->speed = P3P_LINK_SPEED_MHZ *
-			P3P_LINK_SPEED_VAL(pcifn, val);
+		ethtool_cmd_speed_set(ecmd, P3P_LINK_SPEED_MHZ *
+				      P3P_LINK_SPEED_VAL(pcifn, val));
 		ecmd->duplex = DUPLEX_FULL;
 		ecmd->autoneg = AUTONEG_DISABLE;
 	} else
@@ -201,7 +201,7 @@
 	ecmd->phy_address = adapter->physical_port;
 	ecmd->transceiver = XCVR_EXTERNAL;
 
-	switch (adapter->ahw.board_type) {
+	switch (adapter->ahw->board_type) {
 	case QLCNIC_BRDTYPE_P3P_REF_QG:
 	case QLCNIC_BRDTYPE_P3P_4_GB:
 	case QLCNIC_BRDTYPE_P3P_4_GB_MM:
@@ -238,7 +238,7 @@
 		ecmd->autoneg = AUTONEG_DISABLE;
 		break;
 	case QLCNIC_BRDTYPE_P3P_10G_TP:
-		if (adapter->ahw.port_type == QLCNIC_XGBE) {
+		if (adapter->ahw->port_type == QLCNIC_XGBE) {
 			ecmd->autoneg = AUTONEG_DISABLE;
 			ecmd->supported |= (SUPPORTED_FIBRE | SUPPORTED_TP);
 			ecmd->advertising |=
@@ -256,7 +256,7 @@
 		break;
 	default:
 		dev_err(&adapter->pdev->dev, "Unsupported board model %d\n",
-			adapter->ahw.board_type);
+			adapter->ahw->board_type);
 		return -EIO;
 	}
 
@@ -284,50 +284,44 @@
 static int
 qlcnic_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
 {
+	u32 config = 0;
+	u32 ret = 0;
 	struct qlcnic_adapter *adapter = netdev_priv(dev);
-	__u32 status;
+
+	if (adapter->ahw->port_type != QLCNIC_GBE)
+		return -EOPNOTSUPP;
 
 	/* 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 (ecmd->duplex)
+		config |= 0x1;
 
-		if (qlcnic_fw_cmd_query_phy(adapter,
-			      QLCNIC_NIU_GB_MII_MGMT_ADDR_PHY_STATUS,
-			      &status) != 0)
-			return -EIO;
+	if (ecmd->autoneg)
+		config |= 0x2;
 
-		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;
-		}
+	switch (ethtool_cmd_speed(ecmd)) {
+	case SPEED_10:
+		config |= (0 << 8);
+		break;
+	case SPEED_100:
+		config |= (1 << 8);
+		break;
+	case SPEED_1000:
+		config |= (10 << 8);
+		break;
+	default:
+		return -EIO;
+	}
 
-		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
+	ret = qlcnic_fw_cmd_set_port(adapter, config);
+
+	if (ret == QLCNIC_RCODE_NOT_SUPPORTED)
 		return -EOPNOTSUPP;
+	else if (ret)
+		return -EIO;
+
+	adapter->link_speed = ethtool_cmd_speed(ecmd);
+	adapter->link_duplex = ecmd->duplex;
+	adapter->link_autoneg = ecmd->autoneg;
 
 	if (!netif_running(dev))
 		return 0;
@@ -340,14 +334,14 @@
 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_recv_context *recv_ctx = adapter->recv_ctx;
 	struct qlcnic_host_sds_ring *sds_ring;
 	u32 *regs_buff = p;
 	int ring, i = 0, j = 0;
 
 	memset(p, 0, qlcnic_get_regs_len(dev));
 	regs->version = (QLCNIC_ETHTOOL_REGS_VER << 24) |
-		(adapter->ahw.revision_id << 16) | (adapter->pdev)->device;
+		(adapter->ahw->revision_id << 16) | (adapter->pdev)->device;
 
 	regs_buff[0] = (0xcafe0000 | (QLCNIC_DEV_INFO_SIZE & 0xffff));
 	regs_buff[1] = QLCNIC_MGMT_API_VERSION;
@@ -382,7 +376,7 @@
 	u32 val;
 
 	val = QLCRD32(adapter, CRB_XG_STATE_P3P);
-	val = XG_LINK_STATE_P3P(adapter->ahw.pci_func, val);
+	val = XG_LINK_STATE_P3P(adapter->ahw->pci_func, val);
 	return (val == XG_LINK_UP_P3P) ? 0 : 1;
 }
 
@@ -474,6 +468,39 @@
 	return qlcnic_reset_context(adapter);
 }
 
+static void qlcnic_get_channels(struct net_device *dev,
+		struct ethtool_channels *channel)
+{
+	struct qlcnic_adapter *adapter = netdev_priv(dev);
+
+	channel->max_rx = rounddown_pow_of_two(min_t(int,
+			adapter->max_rx_ques, num_online_cpus()));
+	channel->max_tx = adapter->max_tx_ques;
+
+	channel->rx_count = adapter->max_sds_rings;
+	channel->tx_count = adapter->max_tx_ques;
+}
+
+static int qlcnic_set_channels(struct net_device *dev,
+		struct ethtool_channels *channel)
+{
+	struct qlcnic_adapter *adapter = netdev_priv(dev);
+	int err;
+
+	if (channel->other_count || channel->combined_count ||
+	    channel->tx_count != channel->max_tx)
+		return -EINVAL;
+
+	err = qlcnic_validate_max_rss(dev, channel->max_rx, channel->rx_count);
+	if (err)
+		return err;
+
+	err = qlcnic_set_max_rss(adapter, channel->rx_count);
+	netdev_info(dev, "allocated 0x%x sds rings\n",
+				 adapter->max_sds_rings);
+	return err;
+}
+
 static void
 qlcnic_get_pauseparam(struct net_device *netdev,
 			  struct ethtool_pauseparam *pause)
@@ -482,7 +509,7 @@
 	int port = adapter->physical_port;
 	__u32 val;
 
-	if (adapter->ahw.port_type == QLCNIC_GBE) {
+	if (adapter->ahw->port_type == QLCNIC_GBE) {
 		if ((port < 0) || (port > QLCNIC_NIU_MAX_GBE_PORTS))
 			return;
 		/* get flow control settings */
@@ -504,7 +531,7 @@
 			pause->tx_pause = !(qlcnic_gb_get_gb3_mask(val));
 			break;
 		}
-	} else if (adapter->ahw.port_type == QLCNIC_XGBE) {
+	} else if (adapter->ahw->port_type == QLCNIC_XGBE) {
 		if ((port < 0) || (port > QLCNIC_NIU_MAX_XG_PORTS))
 			return;
 		pause->rx_pause = 1;
@@ -515,7 +542,7 @@
 			pause->tx_pause = !(qlcnic_xg_get_xg1_mask(val));
 	} else {
 		dev_err(&netdev->dev, "Unknown board type: %x\n",
-					adapter->ahw.port_type);
+					adapter->ahw->port_type);
 	}
 }
 
@@ -528,7 +555,7 @@
 	__u32 val;
 
 	/* read mode */
-	if (adapter->ahw.port_type == QLCNIC_GBE) {
+	if (adapter->ahw->port_type == QLCNIC_GBE) {
 		if ((port < 0) || (port > QLCNIC_NIU_MAX_GBE_PORTS))
 			return -EIO;
 		/* set flow control */
@@ -571,7 +598,7 @@
 			break;
 		}
 		QLCWR32(adapter, QLCNIC_NIU_GB_PAUSE_CTL, val);
-	} else if (adapter->ahw.port_type == QLCNIC_XGBE) {
+	} else if (adapter->ahw->port_type == QLCNIC_XGBE) {
 		if (!pause->rx_pause || pause->autoneg)
 			return -EOPNOTSUPP;
 
@@ -593,7 +620,7 @@
 		QLCWR32(adapter, QLCNIC_NIU_XG_PAUSE_CTL, val);
 	} else {
 		dev_err(&netdev->dev, "Unknown board type: %x\n",
-				adapter->ahw.port_type);
+				adapter->ahw->port_type);
 	}
 	return 0;
 }
@@ -639,8 +666,8 @@
 		goto clear_it;
 
 	adapter->diag_cnt = 0;
-	ret = qlcnic_issue_cmd(adapter, adapter->ahw.pci_func,
-			adapter->fw_hal_version, adapter->portnum,
+	ret = qlcnic_issue_cmd(adapter, adapter->ahw->pci_func,
+			adapter->fw_hal_version, adapter->ahw->pci_func,
 			0, 0, 0x00000011);
 	if (ret)
 		goto done;
@@ -749,14 +776,14 @@
 		return;
 
 	memset(&port_stats, 0, sizeof(struct qlcnic_esw_statistics));
-	ret = qlcnic_get_port_stats(adapter, adapter->ahw.pci_func,
+	ret = qlcnic_get_port_stats(adapter, adapter->ahw->pci_func,
 			QLCNIC_QUERY_RX_COUNTER, &port_stats.rx);
 	if (ret)
 		return;
 
 	qlcnic_fill_device_stats(&index, data, &port_stats.rx);
 
-	ret = qlcnic_get_port_stats(adapter, adapter->ahw.pci_func,
+	ret = qlcnic_get_port_stats(adapter, adapter->ahw->pci_func,
 			QLCNIC_QUERY_TX_COUNTER, &port_stats.tx);
 	if (ret)
 		return;
@@ -764,115 +791,49 @@
 	qlcnic_fill_device_stats(&index, data, &port_stats.tx);
 }
 
-static int qlcnic_set_tx_csum(struct net_device *dev, u32 data)
-{
-	struct qlcnic_adapter *adapter = netdev_priv(dev);
-
-	if ((adapter->flags & QLCNIC_ESWITCH_ENABLED))
-		return -EOPNOTSUPP;
-	if (data)
-		dev->features |= (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM);
-	else
-		dev->features &= ~(NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM);
-
-	return 0;
-
-}
-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);
-
-	if ((adapter->flags & QLCNIC_ESWITCH_ENABLED))
-		return -EOPNOTSUPP;
-	if (!!data) {
-		adapter->rx_csum = !!data;
-		return 0;
-	}
-
-	if (dev->features & NETIF_F_LRO) {
-		if (qlcnic_config_hw_lro(adapter, QLCNIC_LRO_DISABLED))
-			return -EIO;
-
-		dev->features &= ~NETIF_F_LRO;
-		qlcnic_send_lro_cleanup(adapter);
-		dev_info(&adapter->pdev->dev,
-					"disabling LRO as rx_csum is off\n");
-	}
-	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)
-{
-	struct qlcnic_adapter *adapter = netdev_priv(dev);
-	if (!(adapter->capabilities & QLCNIC_FW_CAPABILITY_TSO))
-		return -EOPNOTSUPP;
-	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)
+static int qlcnic_set_led(struct net_device *dev,
+			  enum ethtool_phys_id_state state)
 {
 	struct qlcnic_adapter *adapter = netdev_priv(dev);
 	int max_sds_rings = adapter->max_sds_rings;
-	int dev_down = 0;
-	int ret;
 
-	if (!test_bit(__QLCNIC_DEV_UP, &adapter->state)) {
-		dev_down = 1;
-		if (test_and_set_bit(__QLCNIC_RESETTING, &adapter->state))
-			return -EIO;
+	switch (state) {
+	case ETHTOOL_ID_ACTIVE:
+		if (!test_bit(__QLCNIC_DEV_UP, &adapter->state)) {
+			if (test_and_set_bit(__QLCNIC_RESETTING, &adapter->state))
+				return -EIO;
 
-		ret = qlcnic_diag_alloc_res(dev, QLCNIC_LED_TEST);
-		if (ret) {
-			clear_bit(__QLCNIC_RESETTING, &adapter->state);
-			return ret;
+			if (qlcnic_diag_alloc_res(dev, QLCNIC_LED_TEST)) {
+				clear_bit(__QLCNIC_RESETTING, &adapter->state);
+				return -EIO;
+			}
+			set_bit(__QLCNIC_DIAG_RES_ALLOC, &adapter->state);
 		}
-	}
 
-	ret = adapter->nic_ops->config_led(adapter, 1, 0xf);
-	if (ret) {
+		if (adapter->nic_ops->config_led(adapter, 1, 0xf) == 0)
+			return 0;
+
 		dev_err(&adapter->pdev->dev,
 			"Failed to set LED blink state.\n");
-		goto done;
-	}
+		break;
 
-	msleep_interruptible(val * 1000);
+	case ETHTOOL_ID_INACTIVE:
+		if (adapter->nic_ops->config_led(adapter, 0, 0xf))
+			dev_err(&adapter->pdev->dev,
+				"Failed to reset LED blink state.\n");
 
-	ret = adapter->nic_ops->config_led(adapter, 0, 0xf);
-	if (ret) {
-		dev_err(&adapter->pdev->dev,
-			"Failed to reset LED blink state.\n");
-		goto done;
+		break;
+
+	default:
+		return -EINVAL;
 	}
 
-done:
-	if (dev_down) {
+	if (test_and_clear_bit(__QLCNIC_DIAG_RES_ALLOC, &adapter->state)) {
 		qlcnic_diag_free_res(dev, max_sds_rings);
 		clear_bit(__QLCNIC_RESETTING, &adapter->state);
 	}
-	return ret;
 
+	return -EIO;
 }
 
 static void
@@ -936,8 +897,8 @@
 	*/
 	if (ethcoal->rx_coalesce_usecs > 0xffff ||
 		ethcoal->rx_max_coalesced_frames > 0xffff ||
-		ethcoal->tx_coalesce_usecs > 0xffff ||
-		ethcoal->tx_max_coalesced_frames > 0xffff ||
+		ethcoal->tx_coalesce_usecs ||
+		ethcoal->tx_max_coalesced_frames ||
 		ethcoal->rx_coalesce_usecs_irq ||
 		ethcoal->rx_max_coalesced_frames_irq ||
 		ethcoal->tx_coalesce_usecs_irq ||
@@ -959,21 +920,17 @@
 
 	if (!ethcoal->rx_coalesce_usecs ||
 		!ethcoal->rx_max_coalesced_frames) {
-		adapter->coal.flags = QLCNIC_INTR_DEFAULT;
-		adapter->coal.normal.data.rx_time_us =
+		adapter->ahw->coal.flag = QLCNIC_INTR_DEFAULT;
+		adapter->ahw->coal.rx_time_us =
 			QLCNIC_DEFAULT_INTR_COALESCE_RX_TIME_US;
-		adapter->coal.normal.data.rx_packets =
+		adapter->ahw->coal.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->ahw->coal.flag = 0;
+		adapter->ahw->coal.rx_time_us = ethcoal->rx_coalesce_usecs;
+		adapter->ahw->coal.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);
 
@@ -988,66 +945,102 @@
 	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;
+	ethcoal->rx_coalesce_usecs = adapter->ahw->coal.rx_time_us;
+	ethcoal->rx_max_coalesced_frames = adapter->ahw->coal.rx_packets;
 
 	return 0;
 }
 
-static int qlcnic_set_flags(struct net_device *netdev, u32 data)
+static u32 qlcnic_get_msglevel(struct net_device *netdev)
 {
 	struct qlcnic_adapter *adapter = netdev_priv(netdev);
-	int hw_lro;
-
-	if (ethtool_invalid_flags(netdev, data, ETH_FLAG_LRO))
-		return -EINVAL;
 
-	if (!(adapter->capabilities & QLCNIC_FW_CAPABILITY_HW_LRO))
-		return -EINVAL;
-
-	if (!adapter->rx_csum) {
-		dev_info(&adapter->pdev->dev, "rx csum is off, "
-			"cannot toggle lro\n");
-		return -EINVAL;
-	}
-
-	if ((data & ETH_FLAG_LRO) && (netdev->features & NETIF_F_LRO))
-		return 0;
-
-	if (data & ETH_FLAG_LRO) {
-		hw_lro = QLCNIC_LRO_ENABLED;
-		netdev->features |= NETIF_F_LRO;
-	} else {
-		hw_lro = 0;
-		netdev->features &= ~NETIF_F_LRO;
-	}
+	return adapter->msg_enable;
+}
 
-	if (qlcnic_config_hw_lro(adapter, hw_lro))
-		return -EIO;
+static void qlcnic_set_msglevel(struct net_device *netdev, u32 msglvl)
+{
+	struct qlcnic_adapter *adapter = netdev_priv(netdev);
 
-	if ((hw_lro == 0) && qlcnic_send_lro_cleanup(adapter))
-		return -EIO;
+	adapter->msg_enable = msglvl;
+}
 
+static int
+qlcnic_get_dump_flag(struct net_device *netdev, struct ethtool_dump *dump)
+{
+	struct qlcnic_adapter *adapter = netdev_priv(netdev);
+	struct qlcnic_fw_dump *fw_dump = &adapter->ahw->fw_dump;
 
+	dump->len = fw_dump->tmpl_hdr->size + fw_dump->size;
+	dump->flag = fw_dump->tmpl_hdr->drv_cap_mask;
+	dump->version = adapter->fw_version;
 	return 0;
 }
 
-static u32 qlcnic_get_msglevel(struct net_device *netdev)
+static int
+qlcnic_get_dump_data(struct net_device *netdev, struct ethtool_dump *dump,
+			void *buffer)
 {
+	int i, copy_sz;
+	u32 *hdr_ptr, *data;
 	struct qlcnic_adapter *adapter = netdev_priv(netdev);
+	struct qlcnic_fw_dump *fw_dump = &adapter->ahw->fw_dump;
 
-	return adapter->msg_enable;
+	if (qlcnic_api_lock(adapter))
+		return -EIO;
+	if (!fw_dump->clr) {
+		netdev_info(netdev, "Dump not available\n");
+		qlcnic_api_unlock(adapter);
+		return -EINVAL;
+	}
+	/* Copy template header first */
+	copy_sz = fw_dump->tmpl_hdr->size;
+	hdr_ptr = (u32 *) fw_dump->tmpl_hdr;
+	data = (u32 *) buffer;
+	for (i = 0; i < copy_sz/sizeof(u32); i++)
+		*data++ = cpu_to_le32(*hdr_ptr++);
+
+	/* Copy captured dump data */
+	memcpy(buffer + copy_sz, fw_dump->data, fw_dump->size);
+	dump->len = copy_sz + fw_dump->size;
+	dump->flag = fw_dump->tmpl_hdr->drv_cap_mask;
+
+	/* Free dump area once data has been captured */
+	vfree(fw_dump->data);
+	fw_dump->data = NULL;
+	fw_dump->clr = 0;
+	qlcnic_api_unlock(adapter);
+
+	return 0;
 }
 
-static void qlcnic_set_msglevel(struct net_device *netdev, u32 msglvl)
+static int
+qlcnic_set_dump(struct net_device *netdev, struct ethtool_dump *val)
 {
+	int ret = 0;
 	struct qlcnic_adapter *adapter = netdev_priv(netdev);
+	struct qlcnic_fw_dump *fw_dump = &adapter->ahw->fw_dump;
 
-	adapter->msg_enable = msglvl;
+	if (val->flag == QLCNIC_FORCE_FW_DUMP_KEY) {
+		netdev_info(netdev, "Forcing a FW dump\n");
+		qlcnic_dev_request_reset(adapter);
+	} else {
+		if (val->flag > QLCNIC_DUMP_MASK_MAX ||
+			val->flag < QLCNIC_DUMP_MASK_MIN) {
+				netdev_info(netdev,
+				"Invalid dump level: 0x%x\n", val->flag);
+				ret = -EINVAL;
+				goto out;
+		}
+		if (qlcnic_api_lock(adapter))
+			return -EIO;
+		fw_dump->tmpl_hdr->drv_cap_mask = val->flag & 0xff;
+		qlcnic_api_unlock(adapter);
+		netdev_info(netdev, "Driver mask changed to: 0x%x\n",
+			fw_dump->tmpl_hdr->drv_cap_mask);
+	}
+out:
+	return ret;
 }
 
 const struct ethtool_ops qlcnic_ethtool_ops = {
@@ -1061,26 +1054,22 @@
 	.get_eeprom = qlcnic_get_eeprom,
 	.get_ringparam = qlcnic_get_ringparam,
 	.set_ringparam = qlcnic_set_ringparam,
+	.get_channels = qlcnic_get_channels,
+	.set_channels = qlcnic_set_channels,
 	.get_pauseparam = qlcnic_get_pauseparam,
 	.set_pauseparam = qlcnic_set_pauseparam,
-	.get_tx_csum = qlcnic_get_tx_csum,
-	.set_tx_csum = qlcnic_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,
+	.set_phys_id = qlcnic_set_led,
 	.set_msglevel = qlcnic_set_msglevel,
 	.get_msglevel = qlcnic_get_msglevel,
+	.get_dump_flag = qlcnic_get_dump_flag,
+	.get_dump_data = qlcnic_get_dump_data,
+	.set_dump = qlcnic_set_dump,
 };
diff -druN linux-2.6.39-libre/drivers/net/qlcnic/qlcnic.h linux-3.0-rc7-libre/drivers/net/qlcnic/qlcnic.h
--- linux-2.6.39-libre/drivers/net/qlcnic/qlcnic.h	2011-05-19 02:12:14.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/qlcnic/qlcnic.h	2011-07-21 06:54:43.000000000 -0400
@@ -29,13 +29,15 @@
 
 #include <linux/io.h>
 #include <asm/byteorder.h>
+#include <linux/bitops.h>
+#include <linux/if_vlan.h>
 
 #include "qlcnic_hdr.h"
 
 #define _QLCNIC_LINUX_MAJOR 5
 #define _QLCNIC_LINUX_MINOR 0
-#define _QLCNIC_LINUX_SUBVERSION 15
-#define QLCNIC_LINUX_VERSIONID  "5.0.15"
+#define _QLCNIC_LINUX_SUBVERSION 18
+#define QLCNIC_LINUX_VERSIONID  "5.0.18"
 #define QLCNIC_DRV_IDC_VER  0x01
 #define QLCNIC_DRIVER_VERSION  ((_QLCNIC_LINUX_MAJOR << 16) |\
 		 (_QLCNIC_LINUX_MINOR << 8) | (_QLCNIC_LINUX_SUBVERSION))
@@ -93,8 +95,6 @@
 #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
 
@@ -118,7 +118,6 @@
 #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
@@ -201,7 +200,7 @@
 	__le16 reserved;
 	__le32 buffer_length;	/* allocated buffer length (usually 2K) */
 	__le64 addr_buffer;
-};
+} __packed;
 
 /* opcode field in status_desc */
 #define QLCNIC_SYN_OFFLOAD	0x03
@@ -293,6 +292,7 @@
 /* Flash Defines and Structures */
 #define QLCNIC_FLT_LOCATION	0x3F1000
 #define QLCNIC_FW_IMAGE_REGION	0x74
+#define QLCNIC_BOOTLD_REGION    0X72
 struct qlcnic_flt_header {
 	u16 version;
 	u16 len;
@@ -307,7 +307,7 @@
 	u8 reserved1;
 	u32 size;
 	u32 start_addr;
-	u32 end_add;
+	u32 end_addr;
 };
 
 /* Magic number to let user know flash is programmed */
@@ -366,12 +366,6 @@
 	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
@@ -388,10 +382,10 @@
 
 /* In rx_buffer, we do not need multiple fragments as is a single buffer */
 struct qlcnic_rx_buffer {
-	struct list_head list;
+	u16 ref_handle;
 	struct sk_buff *skb;
+	struct list_head list;
 	u64 dma;
-	u16 ref_handle;
 };
 
 /* Board types */
@@ -399,6 +393,48 @@
 #define	QLCNIC_XGBE	0x02
 
 /*
+ * 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_INTR_DEFAULT			0x04
+#define QLCNIC_CONFIG_INTR_COALESCE		3
+
+struct qlcnic_nic_intr_coalesce {
+	u8	type;
+	u8	sts_ring_mask;
+	u16	rx_packets;
+	u16	rx_time_us;
+	u16	flag;
+	u32	timer_out;
+};
+
+struct qlcnic_dump_template_hdr {
+	__le32	type;
+	__le32	offset;
+	__le32	size;
+	__le32	cap_mask;
+	__le32	num_entries;
+	__le32	version;
+	__le32	timestamp;
+	__le32	checksum;
+	__le32	drv_cap_mask;
+	__le32	sys_info[3];
+	__le32	saved_state[16];
+	__le32	cap_sizes[8];
+	__le32	rsvd[0];
+};
+
+struct qlcnic_fw_dump {
+	u8	clr;	/* flag to indicate if dump is cleared */
+	u32	size;	/* total size of the dump */
+	void	*data;	/* dump data area */
+	struct	qlcnic_dump_template_hdr *tmpl_hdr;
+};
+
+/*
  * One hardware_context{} per adapter
  * contains interrupt info as well shared hardware info.
  */
@@ -416,6 +452,9 @@
 	u8 linkup;
 	u16 port_type;
 	u16 board_type;
+
+	struct qlcnic_nic_intr_coalesce coal;
+	struct qlcnic_fw_dump fw_dump;
 };
 
 struct qlcnic_adapter_stats {
@@ -443,50 +482,49 @@
  * be one Rcv Descriptor for normal packets, one for jumbo and may be others.
  */
 struct qlcnic_host_rds_ring {
-	u32 producer;
+	void __iomem *crb_rcv_producer;
+	struct rcv_desc *desc_head;
+	struct qlcnic_rx_buffer *rx_buf_arr;
 	u32 num_desc;
+	u32 producer;
 	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;
-};
+} ____cacheline_internodealigned_in_smp;
 
 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];
 
+	void __iomem *crb_intr_mask;
 	int irq;
 
 	dma_addr_t phys_addr;
 	char name[IFNAMSIZ+4];
-};
+} ____cacheline_internodealigned_in_smp;
 
 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;
+	void __iomem *crb_cmd_producer;
 	struct cmd_desc_type0 *desc_head;
+	struct qlcnic_cmd_buffer *cmd_buf_arr;
+	__le32 *hw_consumer;
+
 	dma_addr_t phys_addr;
 	dma_addr_t hw_cons_phys_addr;
-};
+	struct netdev_queue *txq;
+} ____cacheline_internodealigned_in_smp;
 
 /*
  * Receive context. There is one such structure per instance of the
@@ -495,12 +533,12 @@
  * present elsewhere.
  */
 struct qlcnic_recv_context {
+	struct qlcnic_host_rds_ring *rds_rings;
+	struct qlcnic_host_sds_ring *sds_rings;
 	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 */
@@ -539,9 +577,6 @@
 #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
@@ -550,17 +585,11 @@
 #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_MAC_ADDRESS		0x0000001f
 
 #define QLCNIC_CDRP_CMD_GET_PCI_INFO		0x00000020
 #define QLCNIC_CDRP_CMD_GET_NIC_INFO		0x00000021
 #define QLCNIC_CDRP_CMD_SET_NIC_INFO		0x00000022
-#define QLCNIC_CDRP_CMD_RESET_NPAR		0x00000023
 #define QLCNIC_CDRP_CMD_GET_ESWITCH_CAPABILITY	0x00000024
 #define QLCNIC_CDRP_CMD_TOGGLE_ESWITCH		0x00000025
 #define QLCNIC_CDRP_CMD_GET_ESWITCH_STATUS	0x00000026
@@ -568,8 +597,12 @@
 #define QLCNIC_CDRP_CMD_CONFIGURE_ESWITCH	0x00000028
 #define QLCNIC_CDRP_CMD_GET_ESWITCH_PORT_CONFIG	0x00000029
 #define QLCNIC_CDRP_CMD_GET_ESWITCH_STATS	0x0000002a
+#define QLCNIC_CDRP_CMD_CONFIG_PORT		0x0000002E
+#define QLCNIC_CDRP_CMD_TEMP_SIZE		0x0000002f
+#define QLCNIC_CDRP_CMD_GET_TEMP_HDR		0x00000030
 
 #define QLCNIC_RCODE_SUCCESS		0
+#define QLCNIC_RCODE_NOT_SUPPORTED	9
 #define QLCNIC_RCODE_TIMEOUT		17
 #define QLCNIC_DESTROY_CTX_RESET	0
 
@@ -598,14 +631,14 @@
 	__le32 ring_size;		/* Ring entries */
 	__le16 msi_index;
 	__le16 rsvd;		/* Padding */
-};
+} __packed;
 
 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 */
-};
+} __packed;
 
 struct qlcnic_hostrq_rx_ctx {
 	__le64 host_rsp_dma_addr;	/* Response dma'd here */
@@ -626,17 +659,17 @@
 	   - N hostrq_rds_rings
 	   - N hostrq_sds_rings */
 	char data[0];
-};
+} __packed;
 
 struct qlcnic_cardrsp_rds_ring{
 	__le32 host_producer_crb;	/* Crb to use */
 	__le32 rsvd1;		/* Padding */
-};
+} __packed;
 
 struct qlcnic_cardrsp_sds_ring {
 	__le32 host_consumer_crb;	/* Crb to use */
 	__le32 interrupt_crb;	/* Crb to use */
-};
+} __packed;
 
 struct qlcnic_cardrsp_rx_ctx {
 	/* These ring offsets are relative to data[0] below */
@@ -655,7 +688,7 @@
 	   - N cardrsp_rds_rings
 	   - N cardrs_sds_rings */
 	char data[0];
-};
+} __packed;
 
 #define SIZEOF_HOSTRQ_RX(HOSTRQ_RX, rds_rings, sds_rings)	\
 	(sizeof(HOSTRQ_RX) + 					\
@@ -675,7 +708,7 @@
 	__le64 host_phys_addr;	/* Ring base addr */
 	__le32 ring_size;		/* Ring entries */
 	__le32 rsvd;		/* Padding */
-};
+} __packed;
 
 struct qlcnic_hostrq_tx_ctx {
 	__le64 host_rsp_dma_addr;	/* Response dma'd here */
@@ -690,12 +723,12 @@
 	__le16 rsvd3;		/* Padding */
 	struct qlcnic_hostrq_cds_ring cds_ring;	/* Desc of cds ring */
 	u8  reserved[128];	/* future expansion */
-};
+} __packed;
 
 struct qlcnic_cardrsp_cds_ring {
 	__le32 host_producer_crb;	/* Crb to use */
 	__le32 interrupt_crb;	/* Crb to use */
-};
+} __packed;
 
 struct qlcnic_cardrsp_tx_ctx {
 	__le32 host_ctx_state;	/* Starting state */
@@ -704,7 +737,7 @@
 	u8  virt_port;		/* Virtual/Logical id of port */
 	struct qlcnic_cardrsp_cds_ring cds_ring;	/* Card cds settings */
 	u8  reserved[128];	/* future expansion */
-};
+} __packed;
 
 #define SIZEOF_HOSTRQ_TX(HOSTRQ_TX)	(sizeof(HOSTRQ_TX))
 #define SIZEOF_CARDRSP_TX(CARDRSP_TX)	(sizeof(CARDRSP_TX))
@@ -738,40 +771,6 @@
 	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
 
@@ -783,50 +782,20 @@
 /*
  * 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_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
+#define QLCNIC_H2C_OPCODE_CONFIG_RSS			0x1
+#define QLCNIC_H2C_OPCODE_CONFIG_INTR_COALESCE		0x3
+#define QLCNIC_H2C_OPCODE_CONFIG_LED			0x4
+#define QLCNIC_H2C_OPCODE_LRO_REQUEST			0x7
+#define QLCNIC_H2C_OPCODE_SET_MAC_RECEIVE_MODE		0xc
+#define QLCNIC_H2C_OPCODE_CONFIG_IPADDR		0x12
+#define QLCNIC_H2C_OPCODE_GET_LINKEVENT		0x15
+#define QLCNIC_H2C_OPCODE_CONFIG_BRIDGING		0x17
+#define QLCNIC_H2C_OPCODE_CONFIG_HW_LRO		0x18
 /*
  * 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 */
@@ -895,7 +864,7 @@
 	__le64 qhdr;
 	__le64 req_hdr;
 	__le64 words[6];
-};
+} __packed;
 
 struct qlcnic_mac_req {
 	u8 op;
@@ -906,7 +875,7 @@
 struct qlcnic_vlan_req {
 	__le16 vlan_id;
 	__le16 rsvd[3];
-};
+} __packed;
 
 struct qlcnic_ipaddr {
 	__be32 ipv4;
@@ -929,7 +898,8 @@
 #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_DEF_NUM_STS_DESC_RINGS	4
+#define QLCNIC_MIN_NUM_RSS_RINGS	2
 #define QLCNIC_MSIX_TBL_SPACE		8192
 #define QLCNIC_PCI_REG_MSIX_TBL 	0x44
 #define QLCNIC_MSIX_TBL_PGSIZE		4096
@@ -942,6 +912,7 @@
 #define __QLCNIC_RESETTING		2
 #define __QLCNIC_START_FW 		4
 #define __QLCNIC_AER			5
+#define __QLCNIC_DIAG_RES_ALLOC		6
 
 #define QLCNIC_INTERRUPT_TEST		1
 #define QLCNIC_LOOPBACK_TEST		2
@@ -965,14 +936,14 @@
 };
 
 struct qlcnic_adapter {
-	struct qlcnic_hardware_context ahw;
-
+	struct qlcnic_hardware_context *ahw;
+	struct qlcnic_recv_context *recv_ctx;
+	struct qlcnic_host_tx_ring *tx_ring;
 	struct net_device *netdev;
 	struct pci_dev *pdev;
-	struct list_head mac_list;
 
-	spinlock_t tx_clean_lock;
-	spinlock_t mac_learn_lock;
+	unsigned long state;
+	u32 flags;
 
 	u16 num_txd;
 	u16 num_rxd;
@@ -983,14 +954,12 @@
 	u8 max_rds_rings;
 	u8 max_sds_rings;
 	u8 msix_supported;
-	u8 rx_csum;
 	u8 portnum;
 	u8 physical_port;
 	u8 reset_context;
 
 	u8 mc_enabled;
 	u8 max_mc_count;
-	u8 rss_supported;
 	u8 fw_wait_cnt;
 	u8 fw_fail_cnt;
 	u8 tx_timeo_cnt;
@@ -1015,7 +984,6 @@
 
 	u32 fw_hal_version;
 	u32 capabilities;
-	u32 flags;
 	u32 irq;
 	u32 temp;
 
@@ -1033,31 +1001,29 @@
 	u8 mac_addr[ETH_ALEN];
 
 	u64 dev_rst_time;
+	unsigned long vlans[BITS_TO_LONGS(VLAN_N_VID)];
 
-	struct vlan_group *vlgrp;
 	struct qlcnic_npar_info *npars;
 	struct qlcnic_eswitch *eswitch;
 	struct qlcnic_nic_template *nic_ops;
 
 	struct qlcnic_adapter_stats stats;
-
-	struct qlcnic_recv_context recv_ctx;
-	struct qlcnic_host_tx_ring *tx_ring;
+	struct list_head mac_list;
 
 	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 msix_entry *msix_entries;
 
 	struct delayed_work fw_work;
 
-	struct qlcnic_nic_intr_coalesce coal;
 
 	struct qlcnic_filter_hash fhash;
 
-	unsigned long state;
+	spinlock_t tx_clean_lock;
+	spinlock_t mac_learn_lock;
 	__le32 file_prd_off;	/*File fw product offset*/
 	u32 fw_version;
 	const struct firmware *fw;
@@ -1079,7 +1045,7 @@
 	__le16	min_tx_bw;
 	__le16	max_tx_bw;
 	u8	reserved2[104];
-};
+} __packed;
 
 struct qlcnic_pci_info {
 	__le16	id; /* pci function id */
@@ -1093,7 +1059,7 @@
 
 	u8	mac[ETH_ALEN];
 	u8	reserved2[106];
-};
+} __packed;
 
 struct qlcnic_npar_info {
 	u16	pvid;
@@ -1210,15 +1176,160 @@
 	__le64 local_frames;
 	__le64 numbytes;
 	__le64 rsvd[3];
-};
+} __packed;
 
 struct qlcnic_esw_statistics {
 	struct __qlcnic_esw_statistics rx;
 	struct __qlcnic_esw_statistics tx;
 };
 
-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);
+struct qlcnic_common_entry_hdr {
+	__le32	type;
+	__le32	offset;
+	__le32	cap_size;
+	u8	mask;
+	u8	rsvd[2];
+	u8	flags;
+} __packed;
+
+struct __crb {
+	__le32	addr;
+	u8	stride;
+	u8	rsvd1[3];
+	__le32	data_size;
+	__le32	no_ops;
+	__le32	rsvd2[4];
+} __packed;
+
+struct __ctrl {
+	__le32	addr;
+	u8	stride;
+	u8	index_a;
+	__le16	timeout;
+	__le32	data_size;
+	__le32	no_ops;
+	u8	opcode;
+	u8	index_v;
+	u8	shl_val;
+	u8	shr_val;
+	__le32	val1;
+	__le32	val2;
+	__le32	val3;
+} __packed;
+
+struct __cache {
+	__le32	addr;
+	u8	stride;
+	u8	rsvd;
+	__le16	init_tag_val;
+	__le32	size;
+	__le32	no_ops;
+	__le32	ctrl_addr;
+	__le32	ctrl_val;
+	__le32	read_addr;
+	u8	read_addr_stride;
+	u8	read_addr_num;
+	u8	rsvd1[2];
+} __packed;
+
+struct __ocm {
+	u8	rsvd[8];
+	__le32	size;
+	__le32	no_ops;
+	u8	rsvd1[8];
+	__le32	read_addr;
+	__le32	read_addr_stride;
+} __packed;
+
+struct __mem {
+	u8	rsvd[24];
+	__le32	addr;
+	__le32	size;
+} __packed;
+
+struct __mux {
+	__le32	addr;
+	u8	rsvd[4];
+	__le32	size;
+	__le32	no_ops;
+	__le32	val;
+	__le32	val_stride;
+	__le32	read_addr;
+	u8	rsvd2[4];
+} __packed;
+
+struct __queue {
+	__le32	sel_addr;
+	__le16	stride;
+	u8	rsvd[2];
+	__le32	size;
+	__le32	no_ops;
+	u8	rsvd2[8];
+	__le32	read_addr;
+	u8	read_addr_stride;
+	u8	read_addr_cnt;
+	u8	rsvd3[2];
+} __packed;
+
+struct qlcnic_dump_entry {
+	struct qlcnic_common_entry_hdr hdr;
+	union {
+		struct __crb	crb;
+		struct __cache	cache;
+		struct __ocm	ocm;
+		struct __mem	mem;
+		struct __mux	mux;
+		struct __queue	que;
+		struct __ctrl	ctrl;
+	} region;
+} __packed;
+
+enum op_codes {
+	QLCNIC_DUMP_NOP		= 0,
+	QLCNIC_DUMP_READ_CRB	= 1,
+	QLCNIC_DUMP_READ_MUX	= 2,
+	QLCNIC_DUMP_QUEUE	= 3,
+	QLCNIC_DUMP_BRD_CONFIG	= 4,
+	QLCNIC_DUMP_READ_OCM	= 6,
+	QLCNIC_DUMP_PEG_REG	= 7,
+	QLCNIC_DUMP_L1_DTAG	= 8,
+	QLCNIC_DUMP_L1_ITAG	= 9,
+	QLCNIC_DUMP_L1_DATA	= 11,
+	QLCNIC_DUMP_L1_INST	= 12,
+	QLCNIC_DUMP_L2_DTAG	= 21,
+	QLCNIC_DUMP_L2_ITAG	= 22,
+	QLCNIC_DUMP_L2_DATA	= 23,
+	QLCNIC_DUMP_L2_INST	= 24,
+	QLCNIC_DUMP_READ_ROM	= 71,
+	QLCNIC_DUMP_READ_MEM	= 72,
+	QLCNIC_DUMP_READ_CTRL	= 98,
+	QLCNIC_DUMP_TLHDR	= 99,
+	QLCNIC_DUMP_RDEND	= 255
+};
+
+#define QLCNIC_DUMP_WCRB	BIT_0
+#define QLCNIC_DUMP_RWCRB	BIT_1
+#define QLCNIC_DUMP_ANDCRB	BIT_2
+#define QLCNIC_DUMP_ORCRB	BIT_3
+#define QLCNIC_DUMP_POLLCRB	BIT_4
+#define QLCNIC_DUMP_RD_SAVE	BIT_5
+#define QLCNIC_DUMP_WRT_SAVED	BIT_6
+#define QLCNIC_DUMP_MOD_SAVE_ST	BIT_7
+#define QLCNIC_DUMP_SKIP	BIT_7
+
+#define QLCNIC_DUMP_MASK_MIN		3
+#define QLCNIC_DUMP_MASK_DEF		0x0f
+#define QLCNIC_DUMP_MASK_MAX		0xff
+#define QLCNIC_FORCE_FW_DUMP_KEY	0xdeadfeed
+
+struct qlcnic_dump_operations {
+	enum op_codes opcode;
+	u32 (*handler)(struct qlcnic_adapter *,
+			struct qlcnic_dump_entry *, u32 *);
+};
+
+int qlcnic_fw_cmd_get_minidump_temp(struct qlcnic_adapter *adapter);
+int qlcnic_fw_cmd_set_port(struct qlcnic_adapter *adapter, u32 config);
 
 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);
@@ -1264,6 +1375,7 @@
 int qlcnic_config_led(struct qlcnic_adapter *adapter, u32 state, u32 rate);
 void qlcnic_prune_lb_filters(struct qlcnic_adapter *adapter);
 void qlcnic_delete_lb_filters(struct qlcnic_adapter *adapter);
+int qlcnic_dump_fw(struct qlcnic_adapter *);
 
 /* Functions from qlcnic_init.c */
 int qlcnic_load_firmware(struct qlcnic_adapter *adapter);
@@ -1274,7 +1386,7 @@
 int qlcnic_setup_idc_param(struct qlcnic_adapter *adapter);
 int qlcnic_check_flash_fw_ver(struct qlcnic_adapter *adapter);
 
-int qlcnic_rom_fast_read(struct qlcnic_adapter *adapter, int addr, int *valp);
+int qlcnic_rom_fast_read(struct qlcnic_adapter *adapter, u32 addr, u32 *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);
@@ -1294,7 +1406,7 @@
 
 int qlcnic_check_fw_status(struct qlcnic_adapter *adapter);
 void qlcnic_watchdog_task(struct work_struct *work);
-void qlcnic_post_rx_buffers(struct qlcnic_adapter *adapter, u32 ringid,
+void qlcnic_post_rx_buffers(struct qlcnic_adapter *adapter,
 		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);
@@ -1308,6 +1420,8 @@
 
 int qlcnic_fw_cmd_set_mtu(struct qlcnic_adapter *adapter, int mtu);
 int qlcnic_change_mtu(struct net_device *netdev, int new_mtu);
+u32 qlcnic_fix_features(struct net_device *netdev, u32 features);
+int qlcnic_set_features(struct net_device *netdev, u32 features);
 int qlcnic_config_hw_lro(struct qlcnic_adapter *adapter, int enable);
 int qlcnic_config_bridged_mode(struct qlcnic_adapter *adapter, u32 enable);
 int qlcnic_send_lro_cleanup(struct qlcnic_adapter *adapter);
@@ -1322,6 +1436,9 @@
 void qlcnic_diag_free_res(struct net_device *netdev, int max_sds_rings);
 int qlcnic_diag_alloc_res(struct net_device *netdev, int test);
 netdev_tx_t qlcnic_xmit_frame(struct sk_buff *skb, struct net_device *netdev);
+int qlcnic_validate_max_rss(struct net_device *netdev, u8 max_hw, u8 val);
+int qlcnic_set_max_rss(struct qlcnic_adapter *adapter, u8 data);
+void qlcnic_dev_request_reset(struct qlcnic_adapter *);
 
 /* Management functions */
 int qlcnic_get_mac_address(struct qlcnic_adapter *, u8*);
@@ -1379,8 +1496,7 @@
 
 static inline u32 qlcnic_tx_avail(struct qlcnic_host_tx_ring *tx_ring)
 {
-	smp_mb();
-	if (tx_ring->producer < tx_ring->sw_consumer)
+	if (likely(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 -
diff -druN linux-2.6.39-libre/drivers/net/qlcnic/qlcnic_hdr.h linux-3.0-rc7-libre/drivers/net/qlcnic/qlcnic_hdr.h
--- linux-2.6.39-libre/drivers/net/qlcnic/qlcnic_hdr.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/qlcnic/qlcnic_hdr.h	2011-07-11 19:51:52.000000000 -0400
@@ -492,10 +492,10 @@
 
 #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
+#define TA_CTL_START	BIT_0
+#define TA_CTL_ENABLE	BIT_1
+#define TA_CTL_WRITE	BIT_2
+#define TA_CTL_BUSY	BIT_3
 
 /*
  *   Register offsets for MN
@@ -765,6 +765,38 @@
 #define QLCNIC_MAX_PCI_FUNC	8
 #define QLCNIC_MAX_VLAN_FILTERS	64
 
+/* FW dump defines */
+#define MIU_TEST_CTR		0x41000090
+#define MIU_TEST_ADDR_LO	0x41000094
+#define MIU_TEST_ADDR_HI	0x41000098
+#define FLASH_ROM_WINDOW	0x42110030
+#define FLASH_ROM_DATA		0x42150000
+
+static const u32 MIU_TEST_READ_DATA[] = {
+	0x410000A8, 0x410000AC, 0x410000B8, 0x410000BC, };
+
+#define QLCNIC_FW_DUMP_REG1	0x00130060
+#define QLCNIC_FW_DUMP_REG2	0x001e0000
+#define QLCNIC_FLASH_SEM2_LK	0x0013C010
+#define QLCNIC_FLASH_SEM2_ULK	0x0013C014
+#define QLCNIC_FLASH_LOCK_ID	0x001B2100
+
+#define QLCNIC_RD_DUMP_REG(addr, bar0, data) do {			\
+	writel((addr & 0xFFFF0000), (void *) (bar0 +			\
+		QLCNIC_FW_DUMP_REG1));					\
+	readl((void *) (bar0 + QLCNIC_FW_DUMP_REG1));			\
+	*data = readl((void *) (bar0 + QLCNIC_FW_DUMP_REG2 +		\
+		LSW(addr)));						\
+} while (0)
+
+#define QLCNIC_WR_DUMP_REG(addr, bar0, data) do {			\
+	writel((addr & 0xFFFF0000), (void *) (bar0 +			\
+		QLCNIC_FW_DUMP_REG1));					\
+	readl((void *) (bar0 + QLCNIC_FW_DUMP_REG1));			\
+	writel(data, (void *) (bar0 + QLCNIC_FW_DUMP_REG2 + LSW(addr)));\
+	readl((void *) (bar0 + QLCNIC_FW_DUMP_REG2 + LSW(addr)));	\
+} while (0)
+
 /* PCI function operational mode */
 enum {
 	QLCNIC_MGMT_FUNC	= 0,
diff -druN linux-2.6.39-libre/drivers/net/qlcnic/qlcnic_hw.c linux-3.0-rc7-libre/drivers/net/qlcnic/qlcnic_hw.c
--- linux-2.6.39-libre/drivers/net/qlcnic/qlcnic_hw.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/qlcnic/qlcnic_hw.c	2011-07-11 19:51:52.000000000 -0400
@@ -9,6 +9,7 @@
 
 #include <linux/slab.h>
 #include <net/ip.h>
+#include <linux/bitops.h>
 
 #define MASK(n) ((1ULL<<(n))-1)
 #define OCM_WIN_P3P(addr) (addr & 0xffc0000)
@@ -457,7 +458,7 @@
 
 	req.qhdr = cpu_to_le64(QLCNIC_HOST_REQUEST << 23);
 
-	word = QLCNIC_H2C_OPCODE_PROXY_SET_VPORT_MISS_MODE |
+	word = QLCNIC_H2C_OPCODE_SET_MAC_RECEIVE_MODE |
 			((u64)adapter->portnum << 16);
 	req.req_hdr = cpu_to_le64(word);
 
@@ -532,33 +533,31 @@
 	}
 }
 
-#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;
+	int rv;
 
 	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]);
+	req.req_hdr = cpu_to_le64(QLCNIC_CONFIG_INTR_COALESCE |
+		((u64) adapter->portnum << 16));
 
+	req.words[0] = cpu_to_le64(((u64) adapter->ahw->coal.flag) << 32);
+	req.words[2] = cpu_to_le64(adapter->ahw->coal.rx_packets |
+			((u64) adapter->ahw->coal.rx_time_us) << 16);
+	req.words[5] = cpu_to_le64(adapter->ahw->coal.timer_out |
+			((u64) adapter->ahw->coal.type) << 32 |
+			((u64) adapter->ahw->coal.sts_ring_mask) << 40);
 	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;
 }
 
@@ -568,6 +567,9 @@
 	u64 word;
 	int rv;
 
+	if (!test_bit(__QLCNIC_FW_ATTACHED, &adapter->state))
+		return 0;
+
 	memset(&req, 0, sizeof(struct qlcnic_nic_req));
 
 	req.qhdr = cpu_to_le64(QLCNIC_HOST_REQUEST << 23);
@@ -713,6 +715,9 @@
 	u64 word;
 	int rv;
 
+	if (!test_bit(__QLCNIC_FW_ATTACHED, &adapter->state))
+		return 0;
+
 	memset(&req, 0, sizeof(struct qlcnic_nic_req));
 	req.qhdr = cpu_to_le64(QLCNIC_HOST_REQUEST << 23);
 
@@ -754,6 +759,43 @@
 	return rc;
 }
 
+
+u32 qlcnic_fix_features(struct net_device *netdev, u32 features)
+{
+	struct qlcnic_adapter *adapter = netdev_priv(netdev);
+
+	if ((adapter->flags & QLCNIC_ESWITCH_ENABLED)) {
+		u32 changed = features ^ netdev->features;
+		features ^= changed & (NETIF_F_ALL_CSUM | NETIF_F_RXCSUM);
+	}
+
+	if (!(features & NETIF_F_RXCSUM))
+		features &= ~NETIF_F_LRO;
+
+	return features;
+}
+
+
+int qlcnic_set_features(struct net_device *netdev, u32 features)
+{
+	struct qlcnic_adapter *adapter = netdev_priv(netdev);
+	u32 changed = netdev->features ^ features;
+	int hw_lro = (features & NETIF_F_LRO) ? QLCNIC_LRO_ENABLED : 0;
+
+	if (!(changed & NETIF_F_LRO))
+		return 0;
+
+	netdev->features = features ^ NETIF_F_LRO;
+
+	if (qlcnic_config_hw_lro(adapter, hw_lro))
+		return -EIO;
+
+	if ((hw_lro == 0) && qlcnic_send_lro_cleanup(adapter))
+		return -EIO;
+
+	return 0;
+}
+
 /*
  * Changes the CRB window to the specified window.
  */
@@ -780,7 +822,7 @@
 	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 +
+		*addr = adapter->ahw->pci_base0 + m->start_2M +
 			(off - m->start_128M);
 		return 0;
 	}
@@ -788,7 +830,7 @@
 	/*
 	 * Not in direct map, use crb window
 	 */
-	*addr = adapter->ahw.pci_base0 + CRB_INDIRECT_2M + (off & MASK(16));
+	*addr = adapter->ahw->pci_base0 + CRB_INDIRECT_2M + (off & MASK(16));
 	return 1;
 }
 
@@ -801,7 +843,7 @@
 qlcnic_pci_set_crbwindow_2M(struct qlcnic_adapter *adapter, ulong off)
 {
 	u32 window;
-	void __iomem *addr = adapter->ahw.pci_base0 + CRB_WINDOW_2M;
+	void __iomem *addr = adapter->ahw->pci_base0 + CRB_WINDOW_2M;
 
 	off -= QLCNIC_PCI_CRBSPACE;
 
@@ -838,13 +880,13 @@
 
 	if (rv > 0) {
 		/* indirect access */
-		write_lock_irqsave(&adapter->ahw.crb_lock, flags);
+		write_lock_irqsave(&adapter->ahw->crb_lock, flags);
 		crb_win_lock(adapter);
 		rv = qlcnic_pci_set_crbwindow_2M(adapter, off);
 		if (!rv)
 			writel(data, addr);
 		crb_win_unlock(adapter);
-		write_unlock_irqrestore(&adapter->ahw.crb_lock, flags);
+		write_unlock_irqrestore(&adapter->ahw->crb_lock, flags);
 		return rv;
 	}
 
@@ -869,12 +911,12 @@
 
 	if (rv > 0) {
 		/* indirect access */
-		write_lock_irqsave(&adapter->ahw.crb_lock, flags);
+		write_lock_irqsave(&adapter->ahw->crb_lock, flags);
 		crb_win_lock(adapter);
 		if (!qlcnic_pci_set_crbwindow_2M(adapter, off))
 			data = readl(addr);
 		crb_win_unlock(adapter);
-		write_unlock_irqrestore(&adapter->ahw.crb_lock, flags);
+		write_unlock_irqrestore(&adapter->ahw->crb_lock, flags);
 		return data;
 	}
 
@@ -904,9 +946,9 @@
 
 	window = OCM_WIN_P3P(addr);
 
-	writel(window, adapter->ahw.ocm_win_crb);
+	writel(window, adapter->ahw->ocm_win_crb);
 	/* read back to flush */
-	readl(adapter->ahw.ocm_win_crb);
+	readl(adapter->ahw->ocm_win_crb);
 
 	*start = QLCNIC_PCI_OCM0_2M + GET_MEM_OFFS_2M(addr);
 	return 0;
@@ -920,13 +962,13 @@
 	int ret;
 	u32 start;
 
-	mutex_lock(&adapter->ahw.mem_lock);
+	mutex_lock(&adapter->ahw->mem_lock);
 
 	ret = qlcnic_pci_set_window_2M(adapter, off, &start);
 	if (ret != 0)
 		goto unlock;
 
-	addr = adapter->ahw.pci_base0 + start;
+	addr = adapter->ahw->pci_base0 + start;
 
 	if (op == 0)	/* read */
 		*data = readq(addr);
@@ -934,7 +976,7 @@
 		writeq(*data, addr);
 
 unlock:
-	mutex_unlock(&adapter->ahw.mem_lock);
+	mutex_unlock(&adapter->ahw->mem_lock);
 
 	return ret;
 }
@@ -942,23 +984,23 @@
 void
 qlcnic_pci_camqm_read_2M(struct qlcnic_adapter *adapter, u64 off, u64 *data)
 {
-	void __iomem *addr = adapter->ahw.pci_base0 +
+	void __iomem *addr = adapter->ahw->pci_base0 +
 		QLCNIC_PCI_CAMQM_2M_BASE + (off - QLCNIC_PCI_CAMQM);
 
-	mutex_lock(&adapter->ahw.mem_lock);
+	mutex_lock(&adapter->ahw->mem_lock);
 	*data = readq(addr);
-	mutex_unlock(&adapter->ahw.mem_lock);
+	mutex_unlock(&adapter->ahw->mem_lock);
 }
 
 void
 qlcnic_pci_camqm_write_2M(struct qlcnic_adapter *adapter, u64 off, u64 data)
 {
-	void __iomem *addr = adapter->ahw.pci_base0 +
+	void __iomem *addr = adapter->ahw->pci_base0 +
 		QLCNIC_PCI_CAMQM_2M_BASE + (off - QLCNIC_PCI_CAMQM);
 
-	mutex_lock(&adapter->ahw.mem_lock);
+	mutex_lock(&adapter->ahw->mem_lock);
 	writeq(data, addr);
-	mutex_unlock(&adapter->ahw.mem_lock);
+	mutex_unlock(&adapter->ahw->mem_lock);
 }
 
 #define MAX_CTL_CHECK   1000
@@ -997,7 +1039,7 @@
 correct:
 	off8 = off & ~0xf;
 
-	mutex_lock(&adapter->ahw.mem_lock);
+	mutex_lock(&adapter->ahw->mem_lock);
 
 	writel(off8, (mem_crb + MIU_TEST_AGT_ADDR_LO));
 	writel(0, (mem_crb + MIU_TEST_AGT_ADDR_HI));
@@ -1049,7 +1091,7 @@
 		ret = 0;
 
 done:
-	mutex_unlock(&adapter->ahw.mem_lock);
+	mutex_unlock(&adapter->ahw->mem_lock);
 
 	return ret;
 }
@@ -1091,7 +1133,7 @@
 correct:
 	off8 = off & ~0xf;
 
-	mutex_lock(&adapter->ahw.mem_lock);
+	mutex_lock(&adapter->ahw->mem_lock);
 
 	writel(off8, (mem_crb + MIU_TEST_AGT_ADDR_LO));
 	writel(0, (mem_crb + MIU_TEST_AGT_ADDR_HI));
@@ -1121,7 +1163,7 @@
 		ret = 0;
 	}
 
-	mutex_unlock(&adapter->ahw.mem_lock);
+	mutex_unlock(&adapter->ahw->mem_lock);
 
 	return ret;
 }
@@ -1145,7 +1187,7 @@
 	if (qlcnic_rom_fast_read(adapter, offset, &board_type))
 		return -EIO;
 
-	adapter->ahw.board_type = board_type;
+	adapter->ahw->board_type = board_type;
 
 	if (board_type == QLCNIC_BRDTYPE_P3P_4_GB_MM) {
 		u32 gpio = QLCRD32(adapter, QLCNIC_ROMUSB_GLB_PAD_GPIO_I);
@@ -1164,20 +1206,20 @@
 	case QLCNIC_BRDTYPE_P3P_10G_SFP_QT:
 	case QLCNIC_BRDTYPE_P3P_10G_XFP:
 	case QLCNIC_BRDTYPE_P3P_10000_BASE_T:
-		adapter->ahw.port_type = QLCNIC_XGBE;
+		adapter->ahw->port_type = QLCNIC_XGBE;
 		break;
 	case QLCNIC_BRDTYPE_P3P_REF_QG:
 	case QLCNIC_BRDTYPE_P3P_4_GB:
 	case QLCNIC_BRDTYPE_P3P_4_GB_MM:
-		adapter->ahw.port_type = QLCNIC_GBE;
+		adapter->ahw->port_type = QLCNIC_GBE;
 		break;
 	case QLCNIC_BRDTYPE_P3P_10G_TP:
-		adapter->ahw.port_type = (adapter->portnum < 2) ?
+		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;
+		adapter->ahw->port_type = QLCNIC_XGBE;
 		break;
 	}
 
@@ -1220,3 +1262,462 @@
 
 	return rv;
 }
+
+/* FW dump related functions */
+static u32
+qlcnic_dump_crb(struct qlcnic_adapter *adapter, struct qlcnic_dump_entry *entry,
+		u32 *buffer)
+{
+	int i;
+	u32 addr, data;
+	struct __crb *crb = &entry->region.crb;
+	void __iomem *base = adapter->ahw->pci_base0;
+
+	addr = crb->addr;
+
+	for (i = 0; i < crb->no_ops; i++) {
+		QLCNIC_RD_DUMP_REG(addr, base, &data);
+		*buffer++ = cpu_to_le32(addr);
+		*buffer++ = cpu_to_le32(data);
+		addr += crb->stride;
+	}
+	return crb->no_ops * 2 * sizeof(u32);
+}
+
+static u32
+qlcnic_dump_ctrl(struct qlcnic_adapter *adapter,
+	struct qlcnic_dump_entry *entry, u32 *buffer)
+{
+	int i, k, timeout = 0;
+	void __iomem *base = adapter->ahw->pci_base0;
+	u32 addr, data;
+	u8 opcode, no_ops;
+	struct __ctrl *ctr = &entry->region.ctrl;
+	struct qlcnic_dump_template_hdr *t_hdr = adapter->ahw->fw_dump.tmpl_hdr;
+
+	addr = ctr->addr;
+	no_ops = ctr->no_ops;
+
+	for (i = 0; i < no_ops; i++) {
+		k = 0;
+		opcode = 0;
+		for (k = 0; k < 8; k++) {
+			if (!(ctr->opcode & (1 << k)))
+				continue;
+			switch (1 << k) {
+			case QLCNIC_DUMP_WCRB:
+				QLCNIC_WR_DUMP_REG(addr, base, ctr->val1);
+				break;
+			case QLCNIC_DUMP_RWCRB:
+				QLCNIC_RD_DUMP_REG(addr, base, &data);
+				QLCNIC_WR_DUMP_REG(addr, base, data);
+				break;
+			case QLCNIC_DUMP_ANDCRB:
+				QLCNIC_RD_DUMP_REG(addr, base, &data);
+				QLCNIC_WR_DUMP_REG(addr, base,
+					(data & ctr->val2));
+				break;
+			case QLCNIC_DUMP_ORCRB:
+				QLCNIC_RD_DUMP_REG(addr, base, &data);
+				QLCNIC_WR_DUMP_REG(addr, base,
+					(data | ctr->val3));
+				break;
+			case QLCNIC_DUMP_POLLCRB:
+				while (timeout <= ctr->timeout) {
+					QLCNIC_RD_DUMP_REG(addr, base, &data);
+					if ((data & ctr->val2) == ctr->val1)
+						break;
+					msleep(1);
+					timeout++;
+				}
+				if (timeout > ctr->timeout) {
+					dev_info(&adapter->pdev->dev,
+					"Timed out, aborting poll CRB\n");
+					return -EINVAL;
+				}
+				break;
+			case QLCNIC_DUMP_RD_SAVE:
+				if (ctr->index_a)
+					addr = t_hdr->saved_state[ctr->index_a];
+				QLCNIC_RD_DUMP_REG(addr, base, &data);
+				t_hdr->saved_state[ctr->index_v] = data;
+				break;
+			case QLCNIC_DUMP_WRT_SAVED:
+				if (ctr->index_v)
+					data = t_hdr->saved_state[ctr->index_v];
+				else
+					data = ctr->val1;
+				if (ctr->index_a)
+					addr = t_hdr->saved_state[ctr->index_a];
+				QLCNIC_WR_DUMP_REG(addr, base, data);
+				break;
+			case QLCNIC_DUMP_MOD_SAVE_ST:
+				data = t_hdr->saved_state[ctr->index_v];
+				data <<= ctr->shl_val;
+				data >>= ctr->shr_val;
+				if (ctr->val2)
+					data &= ctr->val2;
+				data |= ctr->val3;
+				data += ctr->val1;
+				t_hdr->saved_state[ctr->index_v] = data;
+				break;
+			default:
+				dev_info(&adapter->pdev->dev,
+					"Unknown opcode\n");
+				break;
+			}
+		}
+		addr += ctr->stride;
+	}
+	return 0;
+}
+
+static u32
+qlcnic_dump_mux(struct qlcnic_adapter *adapter, struct qlcnic_dump_entry *entry,
+	u32 *buffer)
+{
+	int loop;
+	u32 val, data = 0;
+	struct __mux *mux = &entry->region.mux;
+	void __iomem *base = adapter->ahw->pci_base0;
+
+	val = mux->val;
+	for (loop = 0; loop < mux->no_ops; loop++) {
+		QLCNIC_WR_DUMP_REG(mux->addr, base, val);
+		QLCNIC_RD_DUMP_REG(mux->read_addr, base, &data);
+		*buffer++ = cpu_to_le32(val);
+		*buffer++ = cpu_to_le32(data);
+		val += mux->val_stride;
+	}
+	return 2 * mux->no_ops * sizeof(u32);
+}
+
+static u32
+qlcnic_dump_que(struct qlcnic_adapter *adapter, struct qlcnic_dump_entry *entry,
+	u32 *buffer)
+{
+	int i, loop;
+	u32 cnt, addr, data, que_id = 0;
+	void __iomem *base = adapter->ahw->pci_base0;
+	struct __queue *que = &entry->region.que;
+
+	addr = que->read_addr;
+	cnt = que->read_addr_cnt;
+
+	for (loop = 0; loop < que->no_ops; loop++) {
+		QLCNIC_WR_DUMP_REG(que->sel_addr, base, que_id);
+		addr = que->read_addr;
+		for (i = 0; i < cnt; i++) {
+			QLCNIC_RD_DUMP_REG(addr, base, &data);
+			*buffer++ = cpu_to_le32(data);
+			addr += que->read_addr_stride;
+		}
+		que_id += que->stride;
+	}
+	return que->no_ops * cnt * sizeof(u32);
+}
+
+static u32
+qlcnic_dump_ocm(struct qlcnic_adapter *adapter, struct qlcnic_dump_entry *entry,
+	u32 *buffer)
+{
+	int i;
+	u32 data;
+	void __iomem *addr;
+	struct __ocm *ocm = &entry->region.ocm;
+
+	addr = adapter->ahw->pci_base0 + ocm->read_addr;
+	for (i = 0; i < ocm->no_ops; i++) {
+		data = readl(addr);
+		*buffer++ = cpu_to_le32(data);
+		addr += ocm->read_addr_stride;
+	}
+	return ocm->no_ops * sizeof(u32);
+}
+
+static u32
+qlcnic_read_rom(struct qlcnic_adapter *adapter, struct qlcnic_dump_entry *entry,
+	u32 *buffer)
+{
+	int i, count = 0;
+	u32 fl_addr, size, val, lck_val, addr;
+	struct __mem *rom = &entry->region.mem;
+	void __iomem *base = adapter->ahw->pci_base0;
+
+	fl_addr = rom->addr;
+	size = rom->size/4;
+lock_try:
+	lck_val = readl(base + QLCNIC_FLASH_SEM2_LK);
+	if (!lck_val && count < MAX_CTL_CHECK) {
+		msleep(10);
+		count++;
+		goto lock_try;
+	}
+	writel(adapter->ahw->pci_func, (base + QLCNIC_FLASH_LOCK_ID));
+	for (i = 0; i < size; i++) {
+		addr = fl_addr & 0xFFFF0000;
+		QLCNIC_WR_DUMP_REG(FLASH_ROM_WINDOW, base, addr);
+		addr = LSW(fl_addr) + FLASH_ROM_DATA;
+		QLCNIC_RD_DUMP_REG(addr, base, &val);
+		fl_addr += 4;
+		*buffer++ = cpu_to_le32(val);
+	}
+	readl(base + QLCNIC_FLASH_SEM2_ULK);
+	return rom->size;
+}
+
+static u32
+qlcnic_dump_l1_cache(struct qlcnic_adapter *adapter,
+	struct qlcnic_dump_entry *entry, u32 *buffer)
+{
+	int i;
+	u32 cnt, val, data, addr;
+	void __iomem *base = adapter->ahw->pci_base0;
+	struct __cache *l1 = &entry->region.cache;
+
+	val = l1->init_tag_val;
+
+	for (i = 0; i < l1->no_ops; i++) {
+		QLCNIC_WR_DUMP_REG(l1->addr, base, val);
+		QLCNIC_WR_DUMP_REG(l1->ctrl_addr, base, LSW(l1->ctrl_val));
+		addr = l1->read_addr;
+		cnt = l1->read_addr_num;
+		while (cnt) {
+			QLCNIC_RD_DUMP_REG(addr, base, &data);
+			*buffer++ = cpu_to_le32(data);
+			addr += l1->read_addr_stride;
+			cnt--;
+		}
+		val += l1->stride;
+	}
+	return l1->no_ops * l1->read_addr_num * sizeof(u32);
+}
+
+static u32
+qlcnic_dump_l2_cache(struct qlcnic_adapter *adapter,
+	struct qlcnic_dump_entry *entry, u32 *buffer)
+{
+	int i;
+	u32 cnt, val, data, addr;
+	u8 poll_mask, poll_to, time_out = 0;
+	void __iomem *base = adapter->ahw->pci_base0;
+	struct __cache *l2 = &entry->region.cache;
+
+	val = l2->init_tag_val;
+	poll_mask = LSB(MSW(l2->ctrl_val));
+	poll_to = MSB(MSW(l2->ctrl_val));
+
+	for (i = 0; i < l2->no_ops; i++) {
+		QLCNIC_WR_DUMP_REG(l2->addr, base, val);
+		do {
+			QLCNIC_WR_DUMP_REG(l2->ctrl_addr, base,
+				LSW(l2->ctrl_val));
+			QLCNIC_RD_DUMP_REG(l2->ctrl_addr, base, &data);
+			if (!(data & poll_mask))
+				break;
+			msleep(1);
+			time_out++;
+		} while (time_out <= poll_to);
+		if (time_out > poll_to)
+			return -EINVAL;
+
+		addr = l2->read_addr;
+		cnt = l2->read_addr_num;
+		while (cnt) {
+			QLCNIC_RD_DUMP_REG(addr, base, &data);
+			*buffer++ = cpu_to_le32(data);
+			addr += l2->read_addr_stride;
+			cnt--;
+		}
+		val += l2->stride;
+	}
+	return l2->no_ops * l2->read_addr_num * sizeof(u32);
+}
+
+static u32
+qlcnic_read_memory(struct qlcnic_adapter *adapter,
+	struct qlcnic_dump_entry *entry, u32 *buffer)
+{
+	u32 addr, data, test, ret = 0;
+	int i, reg_read;
+	struct __mem *mem = &entry->region.mem;
+	void __iomem *base = adapter->ahw->pci_base0;
+
+	reg_read = mem->size;
+	addr = mem->addr;
+	/* check for data size of multiple of 16 and 16 byte alignment */
+	if ((addr & 0xf) || (reg_read%16)) {
+		dev_info(&adapter->pdev->dev,
+			"Unaligned memory addr:0x%x size:0x%x\n",
+			addr, reg_read);
+		return -EINVAL;
+	}
+
+	mutex_lock(&adapter->ahw->mem_lock);
+
+	while (reg_read != 0) {
+		QLCNIC_WR_DUMP_REG(MIU_TEST_ADDR_LO, base, addr);
+		QLCNIC_WR_DUMP_REG(MIU_TEST_ADDR_HI, base, 0);
+		QLCNIC_WR_DUMP_REG(MIU_TEST_CTR, base,
+			TA_CTL_ENABLE | TA_CTL_START);
+
+		for (i = 0; i < MAX_CTL_CHECK; i++) {
+			QLCNIC_RD_DUMP_REG(MIU_TEST_CTR, base, &test);
+			if (!(test & TA_CTL_BUSY))
+				break;
+		}
+		if (i == MAX_CTL_CHECK) {
+			if (printk_ratelimit()) {
+				dev_err(&adapter->pdev->dev,
+					"failed to read through agent\n");
+				ret = -EINVAL;
+				goto out;
+			}
+		}
+		for (i = 0; i < 4; i++) {
+			QLCNIC_RD_DUMP_REG(MIU_TEST_READ_DATA[i], base, &data);
+			*buffer++ = cpu_to_le32(data);
+		}
+		addr += 16;
+		reg_read -= 16;
+		ret += 16;
+	}
+out:
+	mutex_unlock(&adapter->ahw->mem_lock);
+	return mem->size;
+}
+
+static u32
+qlcnic_dump_nop(struct qlcnic_adapter *adapter,
+	struct qlcnic_dump_entry *entry, u32 *buffer)
+{
+	entry->hdr.flags |= QLCNIC_DUMP_SKIP;
+	return 0;
+}
+
+struct qlcnic_dump_operations fw_dump_ops[] = {
+	{ QLCNIC_DUMP_NOP, qlcnic_dump_nop },
+	{ QLCNIC_DUMP_READ_CRB, qlcnic_dump_crb },
+	{ QLCNIC_DUMP_READ_MUX, qlcnic_dump_mux },
+	{ QLCNIC_DUMP_QUEUE, qlcnic_dump_que },
+	{ QLCNIC_DUMP_BRD_CONFIG, qlcnic_read_rom },
+	{ QLCNIC_DUMP_READ_OCM, qlcnic_dump_ocm },
+	{ QLCNIC_DUMP_PEG_REG, qlcnic_dump_ctrl },
+	{ QLCNIC_DUMP_L1_DTAG, qlcnic_dump_l1_cache },
+	{ QLCNIC_DUMP_L1_ITAG, qlcnic_dump_l1_cache },
+	{ QLCNIC_DUMP_L1_DATA, qlcnic_dump_l1_cache },
+	{ QLCNIC_DUMP_L1_INST, qlcnic_dump_l1_cache },
+	{ QLCNIC_DUMP_L2_DTAG, qlcnic_dump_l2_cache },
+	{ QLCNIC_DUMP_L2_ITAG, qlcnic_dump_l2_cache },
+	{ QLCNIC_DUMP_L2_DATA, qlcnic_dump_l2_cache },
+	{ QLCNIC_DUMP_L2_INST, qlcnic_dump_l2_cache },
+	{ QLCNIC_DUMP_READ_ROM, qlcnic_read_rom },
+	{ QLCNIC_DUMP_READ_MEM, qlcnic_read_memory },
+	{ QLCNIC_DUMP_READ_CTRL, qlcnic_dump_ctrl },
+	{ QLCNIC_DUMP_TLHDR, qlcnic_dump_nop },
+	{ QLCNIC_DUMP_RDEND, qlcnic_dump_nop },
+};
+
+/* Walk the template and collect dump for each entry in the dump template */
+static int
+qlcnic_valid_dump_entry(struct device *dev, struct qlcnic_dump_entry *entry,
+	u32 size)
+{
+	int ret = 1;
+	if (size != entry->hdr.cap_size) {
+		dev_info(dev,
+		"Invalidate dump, Type:%d\tMask:%d\tSize:%dCap_size:%d\n",
+		entry->hdr.type, entry->hdr.mask, size, entry->hdr.cap_size);
+		dev_info(dev, "Aborting further dump capture\n");
+		ret = 0;
+	}
+	return ret;
+}
+
+int qlcnic_dump_fw(struct qlcnic_adapter *adapter)
+{
+	u32 *buffer;
+	char mesg[64];
+	char *msg[] = {mesg, NULL};
+	int i, k, ops_cnt, ops_index, dump_size = 0;
+	u32 entry_offset, dump, no_entries, buf_offset = 0;
+	struct qlcnic_dump_entry *entry;
+	struct qlcnic_fw_dump *fw_dump = &adapter->ahw->fw_dump;
+	struct qlcnic_dump_template_hdr *tmpl_hdr = fw_dump->tmpl_hdr;
+
+	if (fw_dump->clr) {
+		dev_info(&adapter->pdev->dev,
+			"Previous dump not cleared, not capturing dump\n");
+		return -EIO;
+	}
+	/* Calculate the size for dump data area only */
+	for (i = 2, k = 1; (i & QLCNIC_DUMP_MASK_MAX); i <<= 1, k++)
+		if (i & tmpl_hdr->drv_cap_mask)
+			dump_size += tmpl_hdr->cap_sizes[k];
+	if (!dump_size)
+		return -EIO;
+
+	fw_dump->data = vzalloc(dump_size);
+	if (!fw_dump->data) {
+		dev_info(&adapter->pdev->dev,
+			"Unable to allocate (%d KB) for fw dump\n",
+			dump_size/1024);
+		return -ENOMEM;
+	}
+	buffer = fw_dump->data;
+	fw_dump->size = dump_size;
+	no_entries = tmpl_hdr->num_entries;
+	ops_cnt = ARRAY_SIZE(fw_dump_ops);
+	entry_offset = tmpl_hdr->offset;
+	tmpl_hdr->sys_info[0] = QLCNIC_DRIVER_VERSION;
+	tmpl_hdr->sys_info[1] = adapter->fw_version;
+
+	for (i = 0; i < no_entries; i++) {
+		entry = (struct qlcnic_dump_entry *) ((void *) tmpl_hdr +
+			entry_offset);
+		if (!(entry->hdr.mask & tmpl_hdr->drv_cap_mask)) {
+			entry->hdr.flags |= QLCNIC_DUMP_SKIP;
+			entry_offset += entry->hdr.offset;
+			continue;
+		}
+		/* Find the handler for this entry */
+		ops_index = 0;
+		while (ops_index < ops_cnt) {
+			if (entry->hdr.type == fw_dump_ops[ops_index].opcode)
+				break;
+			ops_index++;
+		}
+		if (ops_index == ops_cnt) {
+			dev_info(&adapter->pdev->dev,
+				"Invalid entry type %d, exiting dump\n",
+				entry->hdr.type);
+			goto error;
+		}
+		/* Collect dump for this entry */
+		dump = fw_dump_ops[ops_index].handler(adapter, entry, buffer);
+		if (dump && !qlcnic_valid_dump_entry(&adapter->pdev->dev, entry,
+			dump))
+			entry->hdr.flags |= QLCNIC_DUMP_SKIP;
+		buf_offset += entry->hdr.cap_size;
+		entry_offset += entry->hdr.offset;
+		buffer = fw_dump->data + buf_offset;
+	}
+	if (dump_size != buf_offset) {
+		dev_info(&adapter->pdev->dev,
+			"Captured(%d) and expected size(%d) do not match\n",
+			buf_offset, dump_size);
+		goto error;
+	} else {
+		fw_dump->clr = 1;
+		snprintf(mesg, sizeof(mesg), "FW dump for device: %d\n",
+			adapter->pdev->devfn);
+		dev_info(&adapter->pdev->dev, "Dump data, %d bytes captured\n",
+			fw_dump->size);
+		/* Send a udev event to notify availability of FW dump */
+		kobject_uevent_env(&adapter->pdev->dev.kobj, KOBJ_CHANGE, msg);
+		return 0;
+	}
+error:
+	vfree(fw_dump->data);
+	return -EINVAL;
+}
diff -druN linux-2.6.39-libre/drivers/net/qlcnic/qlcnic_init.c linux-3.0-rc7-libre/drivers/net/qlcnic/qlcnic_init.c
--- linux-2.6.39-libre/drivers/net/qlcnic/qlcnic_init.c	2011-05-19 02:12:12.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/qlcnic/qlcnic_init.c	2011-07-21 06:54:40.000000000 -0400
@@ -94,7 +94,7 @@
 	struct qlcnic_rx_buffer *rx_buf;
 	int i, ring;
 
-	recv_ctx = &adapter->recv_ctx;
+	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) {
@@ -119,7 +119,7 @@
 	struct qlcnic_rx_buffer *rx_buf;
 	int i, ring;
 
-	recv_ctx = &adapter->recv_ctx;
+	recv_ctx = adapter->recv_ctx;
 	for (ring = 0; ring < adapter->max_rds_rings; ring++) {
 		rds_ring = &recv_ctx->rds_rings[ring];
 
@@ -173,7 +173,7 @@
 	struct qlcnic_host_tx_ring *tx_ring;
 	int ring;
 
-	recv_ctx = &adapter->recv_ctx;
+	recv_ctx = adapter->recv_ctx;
 
 	if (recv_ctx->rds_rings == NULL)
 		goto skip_rds;
@@ -226,7 +226,7 @@
 	}
 	tx_ring->cmd_buf_arr = cmd_buf_arr;
 
-	recv_ctx = &adapter->recv_ctx;
+	recv_ctx = adapter->recv_ctx;
 
 	size = adapter->max_rds_rings * sizeof(struct qlcnic_host_rds_ring);
 	rds_ring = kzalloc(size, GFP_KERNEL);
@@ -345,7 +345,7 @@
 }
 
 static int do_rom_fast_read(struct qlcnic_adapter *adapter,
-			    int addr, int *valp)
+			    u32 addr, u32 *valp)
 {
 	QLCWR32(adapter, QLCNIC_ROMUSB_ROM_ADDRESS, addr);
 	QLCWR32(adapter, QLCNIC_ROMUSB_ROM_DUMMY_BYTE_CNT, 0);
@@ -398,7 +398,7 @@
 	return ret;
 }
 
-int qlcnic_rom_fast_read(struct qlcnic_adapter *adapter, int addr, int *valp)
+int qlcnic_rom_fast_read(struct qlcnic_adapter *adapter, u32 addr, u32 *valp)
 {
 	int ret;
 
@@ -864,7 +864,7 @@
 	for (i = 0; i < entries; i++) {
 
 		__le32 flags, file_chiprev, offs;
-		u8 chiprev = adapter->ahw.revision_id;
+		u8 chiprev = adapter->ahw->revision_id;
 		u32 flagbit;
 
 		offs = cpu_to_le32(ptab_descr->findex) +
@@ -1130,9 +1130,20 @@
 	} else {
 		u64 data;
 		u32 hi, lo;
+		int ret;
+		struct qlcnic_flt_entry bootld_entry;
 
-		size = (QLCNIC_IMAGE_START - QLCNIC_BOOTLD_START) / 8;
-		flashaddr = QLCNIC_BOOTLD_START;
+		ret = qlcnic_get_flt_entry(adapter, QLCNIC_BOOTLD_REGION,
+					&bootld_entry);
+		if (!ret) {
+			size = bootld_entry.size / 8;
+			flashaddr = bootld_entry.start_addr;
+		} else {
+			size = (QLCNIC_IMAGE_START - QLCNIC_BOOTLD_START) / 8;
+			flashaddr = QLCNIC_BOOTLD_START;
+			dev_info(&pdev->dev,
+				"using legacy method to get flash fw region");
+		}
 
 		for (i = 0; i < size; i++) {
 			if (qlcnic_rom_fast_read(adapter,
@@ -1379,8 +1390,8 @@
 
 	skb = buffer->skb;
 
-	if (likely(adapter->rx_csum && (cksum == STATUS_CKSUM_OK ||
-						cksum == STATUS_CKSUM_LOOP))) {
+	if (likely((adapter->netdev->features & NETIF_F_RXCSUM) &&
+	    (cksum == STATUS_CKSUM_OK || cksum == STATUS_CKSUM_LOOP))) {
 		adapter->stats.csummed++;
 		skb->ip_summed = CHECKSUM_UNNECESSARY;
 	} else {
@@ -1394,7 +1405,7 @@
 	return skb;
 }
 
-static int
+static inline int
 qlcnic_check_rx_tagging(struct qlcnic_adapter *adapter, struct sk_buff *skb,
 			u16 *vlan_tag)
 {
@@ -1425,7 +1436,7 @@
 		int ring, u64 sts_data0)
 {
 	struct net_device *netdev = adapter->netdev;
-	struct qlcnic_recv_context *recv_ctx = &adapter->recv_ctx;
+	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;
@@ -1467,10 +1478,10 @@
 
 	skb->protocol = eth_type_trans(skb, netdev);
 
-	if ((vid != 0xffff) && adapter->vlgrp)
-		vlan_gro_receive(&sds_ring->napi, adapter->vlgrp, vid, skb);
-	else
-		napi_gro_receive(&sds_ring->napi, skb);
+	if (vid != 0xffff)
+		__vlan_hwaccel_put_tag(skb, vid);
+
+	napi_gro_receive(&sds_ring->napi, skb);
 
 	adapter->stats.rx_pkts++;
 	adapter->stats.rxbytes += length;
@@ -1488,7 +1499,7 @@
 		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_recv_context *recv_ctx = adapter->recv_ctx;
 	struct qlcnic_rx_buffer *buffer;
 	struct sk_buff *skb;
 	struct qlcnic_host_rds_ring *rds_ring;
@@ -1552,10 +1563,9 @@
 
 	length = skb->len;
 
-	if ((vid != 0xffff) && adapter->vlgrp)
-		vlan_hwaccel_receive_skb(skb, adapter->vlgrp, vid);
-	else
-		netif_receive_skb(skb);
+	if (vid != 0xffff)
+		__vlan_hwaccel_put_tag(skb, vid);
+	netif_receive_skb(skb);
 
 	adapter->stats.lro_pkts++;
 	adapter->stats.lrobytes += length;
@@ -1625,7 +1635,7 @@
 
 	for (ring = 0; ring < adapter->max_rds_rings; ring++) {
 		struct qlcnic_host_rds_ring *rds_ring =
-			&adapter->recv_ctx.rds_rings[ring];
+			&adapter->recv_ctx->rds_rings[ring];
 
 		if (!list_empty(&sds_ring->free_list[ring])) {
 			list_for_each(cur, &sds_ring->free_list[ring]) {
@@ -1651,12 +1661,13 @@
 }
 
 void
-qlcnic_post_rx_buffers(struct qlcnic_adapter *adapter, u32 ringid,
+qlcnic_post_rx_buffers(struct qlcnic_adapter *adapter,
 	struct qlcnic_host_rds_ring *rds_ring)
 {
 	struct rcv_desc *pdesc;
 	struct qlcnic_rx_buffer *buffer;
-	int producer, count = 0;
+	int count = 0;
+	u32 producer;
 	struct list_head *head;
 
 	producer = rds_ring->producer;
@@ -1696,7 +1707,8 @@
 {
 	struct rcv_desc *pdesc;
 	struct qlcnic_rx_buffer *buffer;
-	int producer, count = 0;
+	int  count = 0;
+	uint32_t producer;
 	struct list_head *head;
 
 	if (!spin_trylock(&rds_ring->lock))
diff -druN linux-2.6.39-libre/drivers/net/qlcnic/qlcnic_main.c linux-3.0-rc7-libre/drivers/net/qlcnic/qlcnic_main.c
--- linux-2.6.39-libre/drivers/net/qlcnic/qlcnic_main.c	2011-05-19 02:12:18.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/qlcnic/qlcnic_main.c	2011-07-21 06:54:46.000000000 -0400
@@ -13,12 +13,12 @@
 
 #include <linux/swab.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>
 #include <linux/aer.h>
+#include <linux/log2.h>
 
 MODULE_DESCRIPTION("QLogic 1/10 GbE Converged/Intelligent Ethernet Driver");
 MODULE_LICENSE("GPL");
@@ -98,6 +98,9 @@
 static int qlcnicvf_start_firmware(struct qlcnic_adapter *);
 static void qlcnic_set_netdev_features(struct qlcnic_adapter *,
 				struct qlcnic_esw_func_cfg *);
+static void qlcnic_vlan_rx_add(struct net_device *, u16);
+static void qlcnic_vlan_rx_del(struct net_device *, u16);
+
 /*  PCI Device ID Table  */
 #define ENTRY(device) \
 	{PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, (device)), \
@@ -113,7 +116,7 @@
 MODULE_DEVICE_TABLE(pci, qlcnic_pci_tbl);
 
 
-void
+inline void
 qlcnic_update_cmd_producer(struct qlcnic_adapter *adapter,
 		struct qlcnic_host_tx_ring *tx_ring)
 {
@@ -169,7 +172,7 @@
 {
 	int ring;
 	struct qlcnic_host_sds_ring *sds_ring;
-	struct qlcnic_recv_context *recv_ctx = &adapter->recv_ctx;
+	struct qlcnic_recv_context *recv_ctx = adapter->recv_ctx;
 
 	if (qlcnic_alloc_sds_rings(recv_ctx, adapter->max_sds_rings))
 		return -ENOMEM;
@@ -193,14 +196,14 @@
 {
 	int ring;
 	struct qlcnic_host_sds_ring *sds_ring;
-	struct qlcnic_recv_context *recv_ctx = &adapter->recv_ctx;
+	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);
+	qlcnic_free_sds_rings(adapter->recv_ctx);
 }
 
 static void
@@ -208,7 +211,7 @@
 {
 	int ring;
 	struct qlcnic_host_sds_ring *sds_ring;
-	struct qlcnic_recv_context *recv_ctx = &adapter->recv_ctx;
+	struct qlcnic_recv_context *recv_ctx = adapter->recv_ctx;
 
 	if (adapter->is_up != QLCNIC_ADAPTER_UP_MAGIC)
 		return;
@@ -225,7 +228,7 @@
 {
 	int ring;
 	struct qlcnic_host_sds_ring *sds_ring;
-	struct qlcnic_recv_context *recv_ctx = &adapter->recv_ctx;
+	struct qlcnic_recv_context *recv_ctx = adapter->recv_ctx;
 
 	if (adapter->is_up != QLCNIC_ADAPTER_UP_MAGIC)
 		return;
@@ -317,13 +320,6 @@
 	return 0;
 }
 
-static void qlcnic_vlan_rx_register(struct net_device *netdev,
-		struct vlan_group *grp)
-{
-	struct qlcnic_adapter *adapter = netdev_priv(netdev);
-	adapter->vlgrp = grp;
-}
-
 static const struct net_device_ops qlcnic_netdev_ops = {
 	.ndo_open	   = qlcnic_open,
 	.ndo_stop	   = qlcnic_close,
@@ -333,8 +329,11 @@
 	.ndo_set_multicast_list = qlcnic_set_multi,
 	.ndo_set_mac_address    = qlcnic_set_mac,
 	.ndo_change_mtu	   = qlcnic_change_mtu,
+	.ndo_fix_features  = qlcnic_fix_features,
+	.ndo_set_features  = qlcnic_set_features,
 	.ndo_tx_timeout	   = qlcnic_tx_timeout,
-	.ndo_vlan_rx_register = qlcnic_vlan_rx_register,
+	.ndo_vlan_rx_add_vid	= qlcnic_vlan_rx_add,
+	.ndo_vlan_rx_kill_vid	= qlcnic_vlan_rx_del,
 #ifdef CONFIG_NET_POLL_CONTROLLER
 	.ndo_poll_controller = qlcnic_poll_controller,
 #endif
@@ -352,72 +351,87 @@
 	.start_firmware = qlcnicvf_start_firmware
 };
 
-static void
-qlcnic_setup_intr(struct qlcnic_adapter *adapter)
+static int qlcnic_enable_msix(struct qlcnic_adapter *adapter, u32 num_msix)
 {
-	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;
+	int err = -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) {
-
+ enable_msix:
 		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;
+			adapter->max_sds_rings = num_msix;
 
 			dev_info(&pdev->dev, "using msi-x interrupts\n");
-			return;
+			return err;
+		}
+		if (err > 0) {
+			num_msix = rounddown_pow_of_two(err);
+			if (num_msix)
+				goto enable_msix;
 		}
+	}
+	return err;
+}
 
-		if (err > 0)
-			pci_disable_msix(pdev);
 
-		/* fall through for msi */
-	}
+static void qlcnic_enable_msi_legacy(struct qlcnic_adapter *adapter)
+{
+	const struct qlcnic_legacy_intr_set *legacy_intrp;
+	struct pci_dev *pdev = adapter->pdev;
 
 	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]);
+				msi_tgt_status[adapter->ahw->pci_func]);
 		dev_info(&pdev->dev, "using msi interrupts\n");
 		adapter->msix_entries[0].vector = pdev->irq;
 		return;
 	}
 
+	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);
 	dev_info(&pdev->dev, "using legacy interrupts\n");
 	adapter->msix_entries[0].vector = pdev->irq;
 }
 
 static void
+qlcnic_setup_intr(struct qlcnic_adapter *adapter)
+{
+	int num_msix;
+
+	if (adapter->msix_supported) {
+		num_msix = (num_online_cpus() >=
+			QLCNIC_DEF_NUM_STS_DESC_RINGS) ?
+			QLCNIC_DEF_NUM_STS_DESC_RINGS :
+			QLCNIC_MIN_NUM_RSS_RINGS;
+	} else
+		num_msix = 1;
+
+	if (!qlcnic_enable_msix(adapter, num_msix))
+		return;
+
+	qlcnic_enable_msi_legacy(adapter);
+}
+
+static void
 qlcnic_teardown_intr(struct qlcnic_adapter *adapter)
 {
 	if (adapter->flags & QLCNIC_MSIX_ENABLED)
@@ -429,8 +443,8 @@
 static void
 qlcnic_cleanup_pci_map(struct qlcnic_adapter *adapter)
 {
-	if (adapter->ahw.pci_base0 != NULL)
-		iounmap(adapter->ahw.pci_base0);
+	if (adapter->ahw->pci_base0 != NULL)
+		iounmap(adapter->ahw->pci_base0);
 }
 
 static int
@@ -464,8 +478,10 @@
 
 	for (i = 0; i < QLCNIC_MAX_PCI_FUNC; i++) {
 		pfn = pci_info[i].id;
-		if (pfn > QLCNIC_MAX_PCI_FUNC)
-			return QL_STATUS_INVALID_PARAM;
+		if (pfn > QLCNIC_MAX_PCI_FUNC) {
+			ret = QL_STATUS_INVALID_PARAM;
+			goto err_eswitch;
+		}
 		adapter->npars[pfn].active = (u8)pci_info[i].active;
 		adapter->npars[pfn].type = (u8)pci_info[i].type;
 		adapter->npars[pfn].phy_port = (u8)pci_info[i].default_port;
@@ -498,7 +514,7 @@
 	u32 ref_count;
 	int i, ret = 1;
 	u32 data = QLCNIC_MGMT_FUNC;
-	void __iomem *priv_op = adapter->ahw.pci_base0 + QLCNIC_DRV_OP_MODE;
+	void __iomem *priv_op = adapter->ahw->pci_base0 + QLCNIC_DRV_OP_MODE;
 
 	/* If other drivers are not in use set their privilege level */
 	ref_count = QLCRD32(adapter, QLCNIC_CRB_DRV_ACTIVE);
@@ -510,16 +526,16 @@
 		for (i = 0; i < QLCNIC_MAX_PCI_FUNC; i++) {
 			id = i;
 			if (adapter->npars[i].type != QLCNIC_TYPE_NIC ||
-				id == adapter->ahw.pci_func)
+				id == adapter->ahw->pci_func)
 				continue;
 			data |= (qlcnic_config_npars &
 					QLC_DEV_SET_DRV(0xf, id));
 		}
 	} else {
 		data = readl(priv_op);
-		data = (data & ~QLC_DEV_SET_DRV(0xf, adapter->ahw.pci_func)) |
+		data = (data & ~QLC_DEV_SET_DRV(0xf, adapter->ahw->pci_func)) |
 			(QLC_DEV_SET_DRV(QLCNIC_MGMT_FUNC,
-			adapter->ahw.pci_func));
+			adapter->ahw->pci_func));
 	}
 	writel(data, priv_op);
 	qlcnic_api_unlock(adapter);
@@ -537,22 +553,23 @@
 	u32 op_mode, priv_level;
 
 	/* Determine FW API version */
-	adapter->fw_hal_version = readl(adapter->ahw.pci_base0 + QLCNIC_FW_API);
+	adapter->fw_hal_version = readl(adapter->ahw->pci_base0 +
+					QLCNIC_FW_API);
 
 	/* Find PCI function number */
 	pci_read_config_dword(adapter->pdev, QLCNIC_MSIX_TABLE_OFFSET, &func);
-	msix_base_addr = adapter->ahw.pci_base0 + QLCNIC_MSIX_BASE;
+	msix_base_addr = adapter->ahw->pci_base0 + QLCNIC_MSIX_BASE;
 	msix_base = readl(msix_base_addr);
 	func = (func - msix_base)/QLCNIC_MSIX_TBL_PGSIZE;
-	adapter->ahw.pci_func = func;
+	adapter->ahw->pci_func = func;
 
 	/* Determine function privilege level */
-	priv_op = adapter->ahw.pci_base0 + QLCNIC_DRV_OP_MODE;
+	priv_op = adapter->ahw->pci_base0 + QLCNIC_DRV_OP_MODE;
 	op_mode = readl(priv_op);
 	if (op_mode == QLC_DEV_DRV_DEFAULT)
 		priv_level = QLCNIC_MGMT_FUNC;
 	else
-		priv_level = QLC_DEV_GET_DRV(op_mode, adapter->ahw.pci_func);
+		priv_level = QLC_DEV_GET_DRV(op_mode, adapter->ahw->pci_func);
 
 	if (priv_level == QLCNIC_NON_PRIV_FUNC) {
 		adapter->op_mode = QLCNIC_NON_PRIV_FUNC;
@@ -591,13 +608,14 @@
 
 	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_base0 = mem_ptr0;
+	adapter->ahw->pci_len0 = pci_len0;
 
 	qlcnic_check_vf(adapter);
 
-	adapter->ahw.ocm_win_crb = qlcnic_get_ioaddr(adapter,
-		QLCNIC_PCIX_PS_REG(PCIX_OCM_WINDOW_REG(adapter->ahw.pci_func)));
+	adapter->ahw->ocm_win_crb = qlcnic_get_ioaddr(adapter,
+		QLCNIC_PCIX_PS_REG(PCIX_OCM_WINDOW_REG(
+			adapter->ahw->pci_func)));
 
 	return 0;
 }
@@ -639,7 +657,7 @@
 
 	dev_info(&pdev->dev, "firmware v%d.%d.%d\n",
 			fw_major, fw_minor, fw_build);
-	if (adapter->ahw.port_type == QLCNIC_XGBE) {
+	if (adapter->ahw->port_type == QLCNIC_XGBE) {
 		if (adapter->flags & QLCNIC_ESWITCH_ENABLED) {
 			adapter->num_rxd = DEFAULT_RCV_DESCRIPTORS_VF;
 			adapter->max_rxd = MAX_RCV_DESCRIPTORS_VF;
@@ -651,7 +669,7 @@
 		adapter->num_jumbo_rxd = MAX_JUMBO_RCV_DESCRIPTORS_10G;
 		adapter->max_jumbo_rxd = MAX_JUMBO_RCV_DESCRIPTORS_10G;
 
-	} else if (adapter->ahw.port_type == QLCNIC_GBE) {
+	} 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->max_jumbo_rxd = MAX_JUMBO_RCV_DESCRIPTORS_1G;
@@ -659,7 +677,6 @@
 	}
 
 	adapter->msix_supported = !!use_msi_x;
-	adapter->rss_supported = !!use_msi_x;
 
 	adapter->num_txd = MAX_CMD_DESCRIPTORS;
 
@@ -672,7 +689,7 @@
 	int err;
 	struct qlcnic_info nic_info;
 
-	err = qlcnic_get_nic_info(adapter, &nic_info, adapter->ahw.pci_func);
+	err = qlcnic_get_nic_info(adapter, &nic_info, adapter->ahw->pci_func);
 	if (err)
 		return err;
 
@@ -708,6 +725,22 @@
 }
 
 static void
+qlcnic_vlan_rx_add(struct net_device *netdev, u16 vid)
+{
+	struct qlcnic_adapter *adapter = netdev_priv(netdev);
+	set_bit(vid, adapter->vlans);
+}
+
+static void
+qlcnic_vlan_rx_del(struct net_device *netdev, u16 vid)
+{
+	struct qlcnic_adapter *adapter = netdev_priv(netdev);
+
+	qlcnic_restore_indev_addr(netdev, NETDEV_DOWN);
+	clear_bit(vid, adapter->vlans);
+}
+
+static void
 qlcnic_set_eswitch_port_features(struct qlcnic_adapter *adapter,
 		struct qlcnic_esw_func_cfg *esw_cfg)
 {
@@ -734,7 +767,7 @@
 	if (!(adapter->flags & QLCNIC_ESWITCH_ENABLED))
 		return 0;
 
-	esw_cfg.pci_func = adapter->ahw.pci_func;
+	esw_cfg.pci_func = adapter->ahw->pci_func;
 	if (qlcnic_get_eswitch_port_config(adapter, &esw_cfg))
 			return -EIO;
 	qlcnic_set_vlan_config(adapter, &esw_cfg);
@@ -750,28 +783,27 @@
 	struct net_device *netdev = adapter->netdev;
 	unsigned long features, vlan_features;
 
-	features = (NETIF_F_SG | NETIF_F_IP_CSUM |
+	features = (NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_RXCSUM |
 			NETIF_F_IPV6_CSUM | NETIF_F_GRO);
 	vlan_features = (NETIF_F_SG | NETIF_F_IP_CSUM |
-			NETIF_F_IPV6_CSUM);
+			NETIF_F_IPV6_CSUM | NETIF_F_HW_VLAN_FILTER);
 
 	if (adapter->capabilities & QLCNIC_FW_CAPABILITY_TSO) {
 		features |= (NETIF_F_TSO | NETIF_F_TSO6);
 		vlan_features |= (NETIF_F_TSO | NETIF_F_TSO6);
 	}
-	if (adapter->capabilities & QLCNIC_FW_CAPABILITY_HW_LRO)
+
+	if (netdev->features & NETIF_F_LRO)
 		features |= NETIF_F_LRO;
 
 	if (esw_cfg->offload_flags & BIT_0) {
 		netdev->features |= features;
-		adapter->rx_csum = 1;
 		if (!(esw_cfg->offload_flags & BIT_1))
 			netdev->features &= ~NETIF_F_TSO;
 		if (!(esw_cfg->offload_flags & BIT_2))
 			netdev->features &= ~NETIF_F_TSO6;
 	} else {
 		netdev->features &= ~features;
-		adapter->rx_csum = 0;
 	}
 
 	netdev->vlan_features = (features & vlan_features);
@@ -791,14 +823,14 @@
 	if (adapter->flags & QLCNIC_ADAPTER_INITIALIZED)
 		return 0;
 
-	priv_op = adapter->ahw.pci_base0 + QLCNIC_DRV_OP_MODE;
+	priv_op = adapter->ahw->pci_base0 + QLCNIC_DRV_OP_MODE;
 	op_mode = readl(priv_op);
-	priv_level = QLC_DEV_GET_DRV(op_mode, adapter->ahw.pci_func);
+	priv_level = QLC_DEV_GET_DRV(op_mode, adapter->ahw->pci_func);
 
 	if (op_mode == QLC_DEV_DRV_DEFAULT)
 		priv_level = QLCNIC_MGMT_FUNC;
 	else
-		priv_level = QLC_DEV_GET_DRV(op_mode, adapter->ahw.pci_func);
+		priv_level = QLC_DEV_GET_DRV(op_mode, adapter->ahw->pci_func);
 
 	if (adapter->flags & QLCNIC_ESWITCH_ENABLED) {
 		if (priv_level == QLCNIC_MGMT_FUNC) {
@@ -1038,7 +1070,7 @@
 
 	unsigned long flags = 0;
 	struct net_device *netdev = adapter->netdev;
-	struct qlcnic_recv_context *recv_ctx = &adapter->recv_ctx;
+	struct qlcnic_recv_context *recv_ctx = adapter->recv_ctx;
 
 	if (adapter->diag_test == QLCNIC_INTERRUPT_TEST) {
 		handler = qlcnic_tmp_intr;
@@ -1075,7 +1107,7 @@
 	int ring;
 	struct qlcnic_host_sds_ring *sds_ring;
 
-	struct qlcnic_recv_context *recv_ctx = &adapter->recv_ctx;
+	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];
@@ -1083,20 +1115,6 @@
 	}
 }
 
-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)
 {
@@ -1115,14 +1133,14 @@
 		return -EIO;
 
 	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);
+		rds_ring = &adapter->recv_ctx->rds_rings[ring];
+		qlcnic_post_rx_buffers(adapter, rds_ring);
 	}
 
 	qlcnic_set_multi(netdev);
 	qlcnic_fw_cmd_set_mtu(adapter, netdev->mtu);
 
-	adapter->ahw.linkup = 0;
+	adapter->ahw->linkup = 0;
 
 	if (adapter->max_sds_rings > 1)
 		qlcnic_config_rss(adapter, 1);
@@ -1230,8 +1248,6 @@
 		goto err_out_free_hw;
 	}
 
-	qlcnic_init_coalesce_defaults(adapter);
-
 	qlcnic_create_sysfs_entries(adapter);
 
 	adapter->is_up = QLCNIC_ADAPTER_UP_MAGIC;
@@ -1272,7 +1288,7 @@
 	clear_bit(__QLCNIC_DEV_UP, &adapter->state);
 	if (adapter->diag_test == QLCNIC_INTERRUPT_TEST) {
 		for (ring = 0; ring < adapter->max_sds_rings; ring++) {
-			sds_ring = &adapter->recv_ctx.sds_rings[ring];
+			sds_ring = &adapter->recv_ctx->sds_rings[ring];
 			qlcnic_disable_int(sds_ring);
 		}
 	}
@@ -1293,6 +1309,48 @@
 	netif_device_attach(netdev);
 }
 
+static int qlcnic_alloc_adapter_resources(struct qlcnic_adapter *adapter)
+{
+	int err = 0;
+	adapter->ahw = kzalloc(sizeof(struct qlcnic_hardware_context),
+				GFP_KERNEL);
+	if (!adapter->ahw) {
+		dev_err(&adapter->pdev->dev,
+			"Failed to allocate recv ctx resources for adapter\n");
+		err = -ENOMEM;
+		goto err_out;
+	}
+	adapter->recv_ctx = kzalloc(sizeof(struct qlcnic_recv_context),
+				GFP_KERNEL);
+	if (!adapter->recv_ctx) {
+		dev_err(&adapter->pdev->dev,
+			"Failed to allocate recv ctx resources for adapter\n");
+		kfree(adapter->ahw);
+		adapter->ahw = NULL;
+		err = -ENOMEM;
+		goto err_out;
+	}
+	/* Initialize interrupt coalesce parameters */
+	adapter->ahw->coal.flag = QLCNIC_INTR_DEFAULT;
+	adapter->ahw->coal.rx_time_us = QLCNIC_DEFAULT_INTR_COALESCE_RX_TIME_US;
+	adapter->ahw->coal.rx_packets = QLCNIC_DEFAULT_INTR_COALESCE_RX_PACKETS;
+err_out:
+	return err;
+}
+
+static void qlcnic_free_adapter_resources(struct qlcnic_adapter *adapter)
+{
+	kfree(adapter->recv_ctx);
+	adapter->recv_ctx = NULL;
+
+	if (adapter->ahw->fw_dump.tmpl_hdr) {
+		vfree(adapter->ahw->fw_dump.tmpl_hdr);
+		adapter->ahw->fw_dump.tmpl_hdr = NULL;
+	}
+	kfree(adapter->ahw);
+	adapter->ahw = NULL;
+}
+
 int qlcnic_diag_alloc_res(struct net_device *netdev, int test)
 {
 	struct qlcnic_adapter *adapter = netdev_priv(netdev);
@@ -1325,13 +1383,13 @@
 	}
 
 	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);
+		rds_ring = &adapter->recv_ctx->rds_rings[ring];
+		qlcnic_post_rx_buffers(adapter, rds_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];
+			sds_ring = &adapter->recv_ctx->sds_rings[ring];
 			qlcnic_enable_int(sds_ring);
 		}
 	}
@@ -1399,7 +1457,6 @@
 	int err;
 	struct pci_dev *pdev = adapter->pdev;
 
-	adapter->rx_csum = 1;
 	adapter->mc_enabled = 0;
 	adapter->max_mc_count = 38;
 
@@ -1410,26 +1467,24 @@
 
 	SET_ETHTOOL_OPS(netdev, &qlcnic_ethtool_ops);
 
-	netdev->features |= (NETIF_F_SG | NETIF_F_IP_CSUM |
-		NETIF_F_IPV6_CSUM | NETIF_F_GRO | NETIF_F_HW_VLAN_RX);
-	netdev->vlan_features |= (NETIF_F_SG | NETIF_F_IP_CSUM |
-		NETIF_F_IPV6_CSUM);
+	netdev->hw_features = NETIF_F_SG | NETIF_F_IP_CSUM |
+		NETIF_F_IPV6_CSUM | NETIF_F_RXCSUM;
 
-	if (adapter->capabilities & QLCNIC_FW_CAPABILITY_TSO) {
-		netdev->features |= (NETIF_F_TSO | NETIF_F_TSO6);
-		netdev->vlan_features |= (NETIF_F_TSO | NETIF_F_TSO6);
-	}
+	if (adapter->capabilities & QLCNIC_FW_CAPABILITY_TSO)
+		netdev->hw_features |= NETIF_F_TSO | NETIF_F_TSO6;
+	if (pci_using_dac)
+		netdev->hw_features |= NETIF_F_HIGHDMA;
 
-	if (pci_using_dac) {
-		netdev->features |= NETIF_F_HIGHDMA;
-		netdev->vlan_features |= NETIF_F_HIGHDMA;
-	}
+	netdev->vlan_features = netdev->hw_features;
 
 	if (adapter->capabilities & QLCNIC_FW_CAPABILITY_FVLANTX)
-		netdev->features |= (NETIF_F_HW_VLAN_TX);
-
+		netdev->hw_features |= NETIF_F_HW_VLAN_TX;
 	if (adapter->capabilities & QLCNIC_FW_CAPABILITY_HW_LRO)
-		netdev->features |= NETIF_F_LRO;
+		netdev->hw_features |= NETIF_F_LRO;
+
+	netdev->features |= netdev->hw_features |
+		NETIF_F_HW_VLAN_RX | NETIF_F_HW_VLAN_FILTER;
+
 	netdev->irq = adapter->msix_entries[0].vector;
 
 	netif_carrier_off(netdev);
@@ -1459,6 +1514,19 @@
 	return 0;
 }
 
+static int
+qlcnic_alloc_msix_entries(struct qlcnic_adapter *adapter, u16 count)
+{
+	adapter->msix_entries = kcalloc(count, sizeof(struct msix_entry),
+					GFP_KERNEL);
+
+	if (adapter->msix_entries)
+		return 0;
+
+	dev_err(&adapter->pdev->dev, "failed allocating msix_entries\n");
+	return -ENOMEM;
+}
+
 static int __devinit
 qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 {
@@ -1501,23 +1569,30 @@
 	adapter = netdev_priv(netdev);
 	adapter->netdev  = netdev;
 	adapter->pdev    = pdev;
-	adapter->dev_rst_time = jiffies;
 
+	if (qlcnic_alloc_adapter_resources(adapter))
+		goto err_out_free_netdev;
+
+	adapter->dev_rst_time = jiffies;
 	revision_id = pdev->revision;
-	adapter->ahw.revision_id = revision_id;
+	adapter->ahw->revision_id = revision_id;
 
-	rwlock_init(&adapter->ahw.crb_lock);
-	mutex_init(&adapter->ahw.mem_lock);
+	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;
+		goto err_out_free_hw;
 
 	/* This will be reset for mezz cards  */
-	adapter->portnum = adapter->ahw.pci_func;
+	adapter->portnum = adapter->ahw->pci_func;
+
+	/* Get FW dump template and store it */
+	if (adapter->op_mode != QLCNIC_NON_PRIV_FUNC)
+		qlcnic_fw_cmd_get_minidump_temp(adapter);
 
 	err = qlcnic_get_board_info(adapter);
 	if (err) {
@@ -1545,11 +1620,15 @@
 
 		pr_info("%s: %s Board Chip rev 0x%x\n",
 				module_name(THIS_MODULE),
-				brd_name, adapter->ahw.revision_id);
+				brd_name, adapter->ahw->revision_id);
 	}
 
 	qlcnic_clear_stats(adapter);
 
+	err = qlcnic_alloc_msix_entries(adapter, adapter->max_rx_ques);
+	if (err)
+		goto err_out_decr_ref;
+
 	qlcnic_setup_intr(adapter);
 
 	err = qlcnic_setup_netdev(adapter, netdev, pci_using_dac);
@@ -1560,7 +1639,7 @@
 
 	qlcnic_schedule_work(adapter, qlcnic_fw_poll_work, FW_POLL_DELAY);
 
-	switch (adapter->ahw.port_type) {
+	switch (adapter->ahw->port_type) {
 	case QLCNIC_GBE:
 		dev_info(&adapter->pdev->dev, "%s: GbE port initialized\n",
 				adapter->netdev->name);
@@ -1578,6 +1657,7 @@
 
 err_out_disable_msi:
 	qlcnic_teardown_intr(adapter);
+	kfree(adapter->msix_entries);
 
 err_out_decr_ref:
 	qlcnic_clr_all_drv_state(adapter, 0);
@@ -1585,6 +1665,9 @@
 err_out_iounmap:
 	qlcnic_cleanup_pci_map(adapter);
 
+err_out_free_hw:
+	qlcnic_free_adapter_resources(adapter);
+
 err_out_free_netdev:
 	free_netdev(netdev);
 
@@ -1626,6 +1709,7 @@
 	qlcnic_free_lb_filters_mem(adapter);
 
 	qlcnic_teardown_intr(adapter);
+	kfree(adapter->msix_entries);
 
 	qlcnic_remove_diag_entries(adapter);
 
@@ -1638,6 +1722,7 @@
 	pci_disable_device(pdev);
 	pci_set_drvdata(pdev, NULL);
 
+	qlcnic_free_adapter_resources(adapter);
 	free_netdev(netdev);
 }
 static int __qlcnic_shutdown(struct pci_dev *pdev)
@@ -1819,6 +1904,7 @@
 	vlan_req->vlan_id = vlan_id;
 
 	tx_ring->producer = get_next_index(producer, tx_ring->num_desc);
+	smp_mb();
 }
 
 #define QLCNIC_MAC_HASH(MAC)\
@@ -1879,58 +1965,122 @@
 	spin_unlock(&adapter->mac_learn_lock);
 }
 
-static void
-qlcnic_tso_check(struct net_device *netdev,
-		struct qlcnic_host_tx_ring *tx_ring,
+static int
+qlcnic_tx_pkt(struct qlcnic_adapter *adapter,
 		struct cmd_desc_type0 *first_desc,
 		struct sk_buff *skb)
 {
-	u8 opcode = TX_ETHER_PKT;
-	__be16 protocol = skb->protocol;
-	u16 flags = 0;
-	int copied, offset, copy_len, hdr_len = 0, tso = 0;
+	u8 opcode = 0, hdr_len = 0;
+	u16 flags = 0, vlan_tci = 0;
+	int copied, offset, copy_len;
 	struct cmd_desc_type0 *hwdesc;
 	struct vlan_ethhdr *vh;
-	struct qlcnic_adapter *adapter = netdev_priv(netdev);
+	struct qlcnic_host_tx_ring *tx_ring = adapter->tx_ring;
+	u16 protocol = ntohs(skb->protocol);
 	u32 producer = tx_ring->producer;
-	__le16 vlan_oob = first_desc->flags_opcode &
-				cpu_to_le16(FLAGS_VLAN_OOB);
+
+	if (protocol == ETH_P_8021Q) {
+		vh = (struct vlan_ethhdr *)skb->data;
+		flags = FLAGS_VLAN_TAGGED;
+		vlan_tci = vh->h_vlan_TCI;
+	} else if (vlan_tx_tag_present(skb)) {
+		flags = FLAGS_VLAN_OOB;
+		vlan_tci = vlan_tx_tag_get(skb);
+	}
+	if (unlikely(adapter->pvid)) {
+		if (vlan_tci && !(adapter->flags & QLCNIC_TAGGING_ENABLED))
+			return -EIO;
+		if (vlan_tci && (adapter->flags & QLCNIC_TAGGING_ENABLED))
+			goto set_flags;
+
+		flags = FLAGS_VLAN_OOB;
+		vlan_tci = adapter->pvid;
+	}
+set_flags:
+	qlcnic_set_tx_vlan_tci(first_desc, vlan_tci);
+	qlcnic_set_tx_flags_opcode(first_desc, flags, opcode);
 
 	if (*(skb->data) & BIT_0) {
 		flags |= BIT_0;
 		memcpy(&first_desc->eth_addr, skb->data, ETH_ALEN);
 	}
-
-	if ((netdev->features & (NETIF_F_TSO | NETIF_F_TSO6)) &&
+	opcode = TX_ETHER_PKT;
+	if ((adapter->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) {
+
+		opcode = (protocol == ETH_P_IPV6) ? TX_TCP_LSO6 : TX_TCP_LSO;
+
+		/* For LSO, we need to copy the MAC/IP/TCP headers into
+		* the descriptor ring */
+		copied = 0;
+		offset = 2;
+
+		if (flags & FLAGS_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;
+
+			/* 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(vlan_tci);
+
+			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);
 		}
 
-		opcode = (protocol == cpu_to_be16(ETH_P_IPV6)) ?
-				TX_TCP_LSO6 : TX_TCP_LSO;
-		tso = 1;
+		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;
+		smp_mb();
+		adapter->stats.lso_frames++;
 
 	} else if (skb->ip_summed == CHECKSUM_PARTIAL) {
 		u8 l4proto;
 
-		if (protocol == cpu_to_be16(ETH_P_IP)) {
+		if (protocol == 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)) {
+		} else if (protocol == ETH_P_IPV6) {
 			l4proto = ipv6_hdr(skb)->nexthdr;
 
 			if (l4proto == IPPROTO_TCP)
@@ -1939,63 +2089,11 @@
 				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
-	 */
-	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 = (__be16)swab16((u16)first_desc->vlan_TCI);
-
-		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++;
+	return 0;
 }
 
 static int
@@ -2046,39 +2144,22 @@
 	return -ENOMEM;
 }
 
-static int
-qlcnic_check_tx_tagging(struct qlcnic_adapter *adapter,
-			struct sk_buff *skb,
-			struct cmd_desc_type0 *first_desc)
+static void
+qlcnic_unmap_buffers(struct pci_dev *pdev, struct sk_buff *skb,
+			struct qlcnic_cmd_buffer *pbuf)
 {
-	u8 opcode = 0;
-	u16 flags = 0;
-	__be16 protocol = skb->protocol;
-	struct vlan_ethhdr *vh;
+	struct qlcnic_skb_frag *nf = &pbuf->frag_array[0];
+	int nr_frags = skb_shinfo(skb)->nr_frags;
+	int i;
 
-	if (protocol == cpu_to_be16(ETH_P_8021Q)) {
-		vh = (struct vlan_ethhdr *)skb->data;
-		protocol = vh->h_vlan_encapsulated_proto;
-		flags = FLAGS_VLAN_TAGGED;
-		qlcnic_set_tx_vlan_tci(first_desc, ntohs(vh->h_vlan_TCI));
-	} else if (vlan_tx_tag_present(skb)) {
-		flags = FLAGS_VLAN_OOB;
-		qlcnic_set_tx_vlan_tci(first_desc, vlan_tx_tag_get(skb));
+	for (i = 0; i < nr_frags; i++) {
+		nf = &pbuf->frag_array[i+1];
+		pci_unmap_page(pdev, nf->dma, nf->length, PCI_DMA_TODEVICE);
 	}
-	if (unlikely(adapter->pvid)) {
-		if (first_desc->vlan_TCI &&
-				!(adapter->flags & QLCNIC_TAGGING_ENABLED))
-			return -EIO;
-		if (first_desc->vlan_TCI &&
-				(adapter->flags & QLCNIC_TAGGING_ENABLED))
-			goto set_flags;
 
-		flags = FLAGS_VLAN_OOB;
-		qlcnic_set_tx_vlan_tci(first_desc, adapter->pvid);
-	}
-set_flags:
-	qlcnic_set_tx_flags_opcode(first_desc, flags, opcode);
-	return 0;
+	nf = &pbuf->frag_array[0];
+	pci_unmap_single(pdev, nf->dma, skb_headlen(skb), PCI_DMA_TODEVICE);
+	pbuf->skb = NULL;
 }
 
 static inline void
@@ -2103,7 +2184,7 @@
 	int i, k;
 
 	u32 producer;
-	int frag_count, no_of_desc;
+	int frag_count;
 	u32 num_txd = tx_ring->num_desc;
 
 	if (!test_bit(__QLCNIC_DEV_UP, &adapter->state)) {
@@ -2133,12 +2214,8 @@
 		frag_count = 1 + skb_shinfo(skb)->nr_frags;
 	}
 
-	/* 4 fragments per cmd des */
-	no_of_desc = (frag_count + 3) >> 2;
-
 	if (unlikely(qlcnic_tx_avail(tx_ring) <= TX_STOP_THRESH)) {
 		netif_stop_queue(netdev);
-		smp_mb();
 		if (qlcnic_tx_avail(tx_ring) > TX_STOP_THRESH)
 			netif_start_queue(netdev);
 		else {
@@ -2155,9 +2232,6 @@
 	first_desc = hwdesc = &tx_ring->desc_head[producer];
 	qlcnic_clear_cmddesc((u64 *)hwdesc);
 
-	if (qlcnic_check_tx_tagging(adapter, skb, first_desc))
-		goto drop_packet;
-
 	if (qlcnic_map_tx_skb(pdev, skb, pbuf)) {
 		adapter->stats.tx_dma_map_error++;
 		goto drop_packet;
@@ -2201,8 +2275,10 @@
 	}
 
 	tx_ring->producer = get_next_index(producer, num_txd);
+	smp_mb();
 
-	qlcnic_tso_check(netdev, tx_ring, first_desc, skb);
+	if (unlikely(qlcnic_tx_pkt(adapter, first_desc, skb)))
+		goto unwind_buff;
 
 	if (qlcnic_mac_learn)
 		qlcnic_send_filter(adapter, tx_ring, first_desc, skb);
@@ -2214,6 +2290,8 @@
 
 	return NETDEV_TX_OK;
 
+unwind_buff:
+	qlcnic_unmap_buffers(pdev, skb, pbuf);
 drop_packet:
 	adapter->stats.txdropped++;
 	dev_kfree_skb_any(skb);
@@ -2260,16 +2338,16 @@
 {
 	struct net_device *netdev = adapter->netdev;
 
-	if (adapter->ahw.linkup && !linkup) {
+	if (adapter->ahw->linkup && !linkup) {
 		netdev_info(netdev, "NIC Link is down\n");
-		adapter->ahw.linkup = 0;
+		adapter->ahw->linkup = 0;
 		if (netif_running(netdev)) {
 			netif_carrier_off(netdev);
 			netif_stop_queue(netdev);
 		}
-	} else if (!adapter->ahw.linkup && linkup) {
+	} else if (!adapter->ahw->linkup && linkup) {
 		netdev_info(netdev, "NIC Link is up\n");
-		adapter->ahw.linkup = 1;
+		adapter->ahw->linkup = 1;
 		if (netif_running(netdev)) {
 			netif_carrier_on(netdev);
 			netif_wake_queue(netdev);
@@ -2505,7 +2583,7 @@
 	int ring;
 	struct qlcnic_host_sds_ring *sds_ring;
 	struct qlcnic_adapter *adapter = netdev_priv(netdev);
-	struct qlcnic_recv_context *recv_ctx = &adapter->recv_ctx;
+	struct qlcnic_recv_context *recv_ctx = adapter->recv_ctx;
 
 	disable_irq(adapter->irq);
 	for (ring = 0; ring < adapter->max_sds_rings; ring++) {
@@ -2756,6 +2834,8 @@
 			set_bit(__QLCNIC_START_FW, &adapter->state);
 			QLCDB(adapter, DRV, "Restarting fw\n");
 			qlcnic_idc_debug_info(adapter, 0);
+			QLCDB(adapter, DRV, "Take FW dump\n");
+			qlcnic_dump_fw(adapter);
 		}
 
 		qlcnic_api_unlock(adapter);
@@ -2854,7 +2934,7 @@
 }
 
 /*Transit to RESET state from READY state only */
-static void
+void
 qlcnic_dev_request_reset(struct qlcnic_adapter *adapter)
 {
 	u32 state;
@@ -3266,6 +3346,56 @@
 	.store = qlcnic_store_diag_mode,
 };
 
+int qlcnic_validate_max_rss(struct net_device *netdev, u8 max_hw, u8 val)
+{
+	if (!use_msi_x && !use_msi) {
+		netdev_info(netdev, "no msix or msi support, hence no rss\n");
+		return -EINVAL;
+	}
+
+	if ((val > max_hw) || (val <  2) || !is_power_of_2(val)) {
+		netdev_info(netdev, "rss_ring valid range [2 - %x] in "
+			" powers of 2\n", max_hw);
+		return -EINVAL;
+	}
+	return 0;
+
+}
+
+int qlcnic_set_max_rss(struct qlcnic_adapter *adapter, u8 data)
+{
+	struct net_device *netdev = adapter->netdev;
+	int err = 0;
+
+	if (test_and_set_bit(__QLCNIC_RESETTING, &adapter->state))
+		return -EBUSY;
+
+	netif_device_detach(netdev);
+	if (netif_running(netdev))
+		__qlcnic_down(adapter, netdev);
+	qlcnic_detach(adapter);
+	qlcnic_teardown_intr(adapter);
+
+	if (qlcnic_enable_msix(adapter, data)) {
+		netdev_info(netdev, "failed setting max_rss; rss disabled\n");
+		qlcnic_enable_msi_legacy(adapter);
+	}
+
+	if (netif_running(netdev)) {
+		err = qlcnic_attach(adapter);
+		if (err)
+			goto done;
+		err = __qlcnic_up(adapter, netdev);
+		if (err)
+			goto done;
+		qlcnic_restore_indev_addr(netdev, NETDEV_UP);
+	}
+ done:
+	netif_device_attach(netdev);
+	clear_bit(__QLCNIC_RESETTING, &adapter->state);
+	return err;
+}
+
 static int
 qlcnic_sysfs_validate_crb(struct qlcnic_adapter *adapter,
 		loff_t offset, size_t size)
@@ -3396,7 +3526,6 @@
 	return size;
 }
 
-
 static struct bin_attribute bin_attr_crb = {
 	.attr = {.name = "crb", .mode = (S_IRUGO | S_IWUSR)},
 	.size = 0,
@@ -3515,7 +3644,7 @@
 	u8 pci_func;
 	int i;
 
-	op_mode = readl(adapter->ahw.pci_base0 + QLCNIC_DRV_OP_MODE);
+	op_mode = readl(adapter->ahw->pci_base0 + QLCNIC_DRV_OP_MODE);
 
 	for (i = 0; i < count; i++) {
 		pci_func = esw_cfg[i].pci_func;
@@ -3581,13 +3710,13 @@
 			if (qlcnic_config_switch_port(adapter, &esw_cfg[i]))
 				return QL_STATUS_INVALID_PARAM;
 
-		if (adapter->ahw.pci_func != esw_cfg[i].pci_func)
+		if (adapter->ahw->pci_func != esw_cfg[i].pci_func)
 			continue;
 
 		op_mode = esw_cfg[i].op_mode;
 		qlcnic_get_eswitch_port_config(adapter, &esw_cfg[i]);
 		esw_cfg[i].op_mode = op_mode;
-		esw_cfg[i].pci_func = adapter->ahw.pci_func;
+		esw_cfg[i].pci_func = adapter->ahw->pci_func;
 
 		switch (esw_cfg[i].op_mode) {
 		case QLCNIC_PORT_DEFAULTS:
@@ -3968,14 +4097,14 @@
 		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");
+	if (device_create_bin_file(dev, &bin_attr_pci_config))
+		dev_info(dev, "failed to create pci config sysfs entry");
 	if (!(adapter->flags & QLCNIC_ESWITCH_ENABLED))
 		return;
 	if (device_create_bin_file(dev, &bin_attr_esw_config))
 		dev_info(dev, "failed to create esw config sysfs entry");
 	if (adapter->op_mode != QLCNIC_MGMT_FUNC)
 		return;
-	if (device_create_bin_file(dev, &bin_attr_pci_config))
-		dev_info(dev, "failed to create pci config sysfs entry");
 	if (device_create_bin_file(dev, &bin_attr_npar_config))
 		dev_info(dev, "failed to create npar config sysfs entry");
 	if (device_create_bin_file(dev, &bin_attr_pm_config))
@@ -3996,12 +4125,12 @@
 	device_remove_file(dev, &dev_attr_diag_mode);
 	device_remove_bin_file(dev, &bin_attr_crb);
 	device_remove_bin_file(dev, &bin_attr_mem);
+	device_remove_bin_file(dev, &bin_attr_pci_config);
 	if (!(adapter->flags & QLCNIC_ESWITCH_ENABLED))
 		return;
 	device_remove_bin_file(dev, &bin_attr_esw_config);
 	if (adapter->op_mode != QLCNIC_MGMT_FUNC)
 		return;
-	device_remove_bin_file(dev, &bin_attr_pci_config);
 	device_remove_bin_file(dev, &bin_attr_npar_config);
 	device_remove_bin_file(dev, &bin_attr_pm_config);
 	device_remove_bin_file(dev, &bin_attr_esw_stats);
@@ -4048,14 +4177,10 @@
 
 	qlcnic_config_indev_addr(adapter, netdev, event);
 
-	if (!adapter->vlgrp)
-		return;
-
-	for (vid = 0; vid < VLAN_N_VID; vid++) {
-		dev = vlan_group_get_device(adapter->vlgrp, vid);
+	for_each_set_bit(vid, adapter->vlans, VLAN_N_VID) {
+		dev = vlan_find_dev(netdev, vid);
 		if (!dev)
 			continue;
-
 		qlcnic_config_indev_addr(adapter, dev, event);
 	}
 }
diff -druN linux-2.6.39-libre/drivers/net/qlge/qlge_ethtool.c linux-3.0-rc7-libre/drivers/net/qlge/qlge_ethtool.c
--- linux-2.6.39-libre/drivers/net/qlge/qlge_ethtool.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/qlge/qlge_ethtool.c	2011-07-11 19:51:52.000000000 -0400
@@ -356,7 +356,7 @@
 		ecmd->port = PORT_FIBRE;
 	}
 
-	ecmd->speed = SPEED_10000;
+	ethtool_cmd_speed_set(ecmd, SPEED_10000);
 	ecmd->duplex = DUPLEX_FULL;
 
 	return 0;
@@ -412,31 +412,31 @@
 	return 0;
 }
 
-static int ql_phys_id(struct net_device *ndev, u32 data)
+static int ql_set_phys_id(struct net_device *ndev,
+			  enum ethtool_phys_id_state state)
+
 {
 	struct ql_adapter *qdev = netdev_priv(ndev);
-	u32 led_reg, i;
-	int status;
 
-	/* Save the current LED settings */
-	status = ql_mb_get_led_cfg(qdev);
-	if (status)
-		return status;
-	led_reg = qdev->led_config;
-
-	/* Start blinking the led */
-	if (!data || data > 300)
-		data = 300;
+	switch (state) {
+	case ETHTOOL_ID_ACTIVE:
+		/* Save the current LED settings */
+		if (ql_mb_get_led_cfg(qdev))
+			return -EIO;
 
-	for (i = 0; i < (data * 10); i++)
+		/* Start blinking */
 		ql_mb_set_led_cfg(qdev, QL_LED_BLINK);
+		return 0;
 
-	/* Restore LED settings */
-	status = ql_mb_set_led_cfg(qdev, led_reg);
-	if (status)
-		return status;
+	case ETHTOOL_ID_INACTIVE:
+		/* Restore LED settings */
+		if (ql_mb_set_led_cfg(qdev, qdev->led_config))
+			return -EIO;
+		return 0;
 
-	return 0;
+	default:
+		return -EINVAL;
+	}
 }
 
 static int ql_start_loopback(struct ql_adapter *qdev)
@@ -655,32 +655,6 @@
 	return status;
 }
 
-static u32 ql_get_rx_csum(struct net_device *netdev)
-{
-	struct ql_adapter *qdev = netdev_priv(netdev);
-	return qdev->rx_csum;
-}
-
-static int ql_set_rx_csum(struct net_device *netdev, uint32_t data)
-{
-	struct ql_adapter *qdev = netdev_priv(netdev);
-	qdev->rx_csum = data;
-	return 0;
-}
-
-static int ql_set_tso(struct net_device *ndev, uint32_t data)
-{
-
-	if (data) {
-		ndev->features |= NETIF_F_TSO;
-		ndev->features |= NETIF_F_TSO6;
-	} else {
-		ndev->features &= ~NETIF_F_TSO;
-		ndev->features &= ~NETIF_F_TSO6;
-	}
-	return 0;
-}
-
 static u32 ql_get_msglevel(struct net_device *ndev)
 {
 	struct ql_adapter *qdev = netdev_priv(ndev);
@@ -703,18 +677,10 @@
 	.get_msglevel = ql_get_msglevel,
 	.set_msglevel = ql_set_msglevel,
 	.get_link = ethtool_op_get_link,
-	.phys_id		 = ql_phys_id,
+	.set_phys_id		 = ql_set_phys_id,
 	.self_test		 = ql_self_test,
 	.get_pauseparam		 = ql_get_pauseparam,
 	.set_pauseparam		 = ql_set_pauseparam,
-	.get_rx_csum = ql_get_rx_csum,
-	.set_rx_csum = ql_set_rx_csum,
-	.get_tx_csum = ethtool_op_get_tx_csum,
-	.set_tx_csum = ethtool_op_set_tx_csum,
-	.get_sg = ethtool_op_get_sg,
-	.set_sg = ethtool_op_set_sg,
-	.get_tso = ethtool_op_get_tso,
-	.set_tso = ql_set_tso,
 	.get_coalesce = ql_get_coalesce,
 	.set_coalesce = ql_set_coalesce,
 	.get_sset_count = ql_get_sset_count,
diff -druN linux-2.6.39-libre/drivers/net/qlge/qlge.h linux-3.0-rc7-libre/drivers/net/qlge/qlge.h
--- linux-2.6.39-libre/drivers/net/qlge/qlge.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/qlge/qlge.h	2011-07-11 19:51:52.000000000 -0400
@@ -16,7 +16,7 @@
  */
 #define DRV_NAME  	"qlge"
 #define DRV_STRING 	"QLogic 10 Gigabit PCI-E Ethernet Driver "
-#define DRV_VERSION	"v1.00.00.27.00.00-01"
+#define DRV_VERSION	"v1.00.00.29.00.00-01"
 
 #define WQ_ADDR_ALIGN	0x3	/* 4 byte alignment */
 
@@ -1996,6 +1996,7 @@
 	QL_LB_LINK_UP = 10,
 	QL_FRC_COREDUMP = 11,
 	QL_EEH_FATAL = 12,
+	QL_ASIC_RECOVERY = 14, /* We are in ascic recovery. */
 };
 
 /* link_status bit definitions */
@@ -2134,7 +2135,7 @@
 	struct delayed_work mpi_idc_work;
 	struct delayed_work mpi_core_to_log;
 	struct completion ide_completion;
-	struct nic_operations *nic_ops;
+	const struct nic_operations *nic_ops;
 	u16 device_id;
 	struct timer_list timer;
 	atomic_t lb_count;
diff -druN linux-2.6.39-libre/drivers/net/qlge/qlge_main.c linux-3.0-rc7-libre/drivers/net/qlge/qlge_main.c
--- linux-2.6.39-libre/drivers/net/qlge/qlge_main.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/qlge/qlge_main.c	2011-07-11 19:51:52.000000000 -0400
@@ -38,6 +38,7 @@
 #include <linux/delay.h>
 #include <linux/mm.h>
 #include <linux/vmalloc.h>
+#include <linux/prefetch.h>
 #include <net/ip6_checksum.h>
 
 #include "qlge.h"
@@ -1571,7 +1572,7 @@
 	skb->protocol = eth_type_trans(skb, ndev);
 	skb_checksum_none_assert(skb);
 
-	if (qdev->rx_csum &&
+	if ((ndev->features & NETIF_F_RXCSUM) &&
 		!(ib_mac_rsp->flags1 & IB_MAC_CSUM_ERR_MASK)) {
 		/* TCP frame. */
 		if (ib_mac_rsp->flags2 & IB_MAC_IOCB_RSP_T) {
@@ -1684,7 +1685,7 @@
 	/* If rx checksum is on, and there are no
 	 * csum or frame errors.
 	 */
-	if (qdev->rx_csum &&
+	if ((ndev->features & NETIF_F_RXCSUM) &&
 		!(ib_mac_rsp->flags1 & IB_MAC_CSUM_ERR_MASK)) {
 		/* TCP frame. */
 		if (ib_mac_rsp->flags2 & IB_MAC_IOCB_RSP_T) {
@@ -2004,7 +2005,7 @@
 	/* If rx checksum is on, and there are no
 	 * csum or frame errors.
 	 */
-	if (qdev->rx_csum &&
+	if ((ndev->features & NETIF_F_RXCSUM) &&
 		!(ib_mac_rsp->flags1 & IB_MAC_CSUM_ERR_MASK)) {
 		/* TCP frame. */
 		if (ib_mac_rsp->flags2 & IB_MAC_IOCB_RSP_T) {
@@ -2151,6 +2152,10 @@
 	 * thread
 	 */
 	clear_bit(QL_ADAPTER_UP, &qdev->flags);
+	/* Set asic recovery bit to indicate reset process that we are
+	 * in fatal error recovery process rather than normal close
+	 */
+	set_bit(QL_ASIC_RECOVERY, &qdev->flags);
 	queue_delayed_work(qdev->workqueue, &qdev->asic_reset_work, 0);
 }
 
@@ -2165,23 +2170,20 @@
 		return;
 
 	case CAM_LOOKUP_ERR_EVENT:
-		netif_err(qdev, link, qdev->ndev,
-			  "Multiple CAM hits lookup occurred.\n");
-		netif_err(qdev, drv, qdev->ndev,
-			  "This event shouldn't occur.\n");
+		netdev_err(qdev->ndev, "Multiple CAM hits lookup occurred.\n");
+		netdev_err(qdev->ndev, "This event shouldn't occur.\n");
 		ql_queue_asic_error(qdev);
 		return;
 
 	case SOFT_ECC_ERROR_EVENT:
-		netif_err(qdev, rx_err, qdev->ndev,
-			  "Soft ECC error detected.\n");
+		netdev_err(qdev->ndev, "Soft ECC error detected.\n");
 		ql_queue_asic_error(qdev);
 		break;
 
 	case PCI_ERR_ANON_BUF_RD:
-		netif_err(qdev, rx_err, qdev->ndev,
-			  "PCI error occurred when reading anonymous buffers from rx_ring %d.\n",
-			  ib_ae_rsp->q_id);
+		netdev_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;
 
@@ -2436,11 +2438,10 @@
 	 */
 	if (var & STS_FE) {
 		ql_queue_asic_error(qdev);
-		netif_err(qdev, intr, qdev->ndev,
-			  "Got fatal error, STS = %x.\n", var);
+		netdev_err(qdev->ndev, "Got fatal error, STS = %x.\n", var);
 		var = ql_read32(qdev, ERR_STS);
-		netif_err(qdev, intr, qdev->ndev,
-			  "Resetting chip. Error Status Register = 0x%x\n", var);
+		netdev_err(qdev->ndev, "Resetting chip. "
+					"Error Status Register = 0x%x\n", var);
 		return IRQ_HANDLED;
 	}
 
@@ -3817,11 +3818,17 @@
 	end_jiffies = jiffies +
 		max((unsigned long)1, usecs_to_jiffies(30));
 
-	/* Stop management traffic. */
-	ql_mb_set_mgmnt_traffic_ctl(qdev, MB_SET_MPI_TFK_STOP);
+	/* Check if bit is set then skip the mailbox command and
+	 * clear the bit, else we are in normal reset process.
+	 */
+	if (!test_bit(QL_ASIC_RECOVERY, &qdev->flags)) {
+		/* Stop management traffic. */
+		ql_mb_set_mgmnt_traffic_ctl(qdev, MB_SET_MPI_TFK_STOP);
 
-	/* Wait for the NIC and MGMNT FIFOs to empty. */
-	ql_wait_fifo_empty(qdev);
+		/* Wait for the NIC and MGMNT FIFOs to empty. */
+		ql_wait_fifo_empty(qdev);
+	} else
+		clear_bit(QL_ASIC_RECOVERY, &qdev->flags);
 
 	ql_write32(qdev, RST_FO, (RST_FO_FR << 16) | RST_FO_FR);
 
@@ -4412,12 +4419,12 @@
 	rtnl_unlock();
 }
 
-static struct nic_operations qla8012_nic_ops = {
+static const struct nic_operations qla8012_nic_ops = {
 	.get_flash		= ql_get_8012_flash_params,
 	.port_initialize	= ql_8012_port_initialize,
 };
 
-static struct nic_operations qla8000_nic_ops = {
+static const struct nic_operations qla8000_nic_ops = {
 	.get_flash		= ql_get_8000_flash_params,
 	.port_initialize	= ql_8000_port_initialize,
 };
@@ -4621,7 +4628,6 @@
 	/*
 	 * Set up the operating parameters.
 	 */
-	qdev->rx_csum = 1;
 	qdev->workqueue = create_singlethread_workqueue(ndev->name);
 	INIT_DELAYED_WORK(&qdev->asic_reset_work, ql_asic_reset_work);
 	INIT_DELAYED_WORK(&qdev->mpi_reset_work, ql_mpi_reset_work);
@@ -4695,15 +4701,11 @@
 
 	qdev = netdev_priv(ndev);
 	SET_NETDEV_DEV(ndev, &pdev->dev);
-	ndev->features = (0
-			  | NETIF_F_IP_CSUM
-			  | NETIF_F_SG
-			  | NETIF_F_TSO
-			  | NETIF_F_TSO6
-			  | NETIF_F_TSO_ECN
-			  | NETIF_F_HW_VLAN_TX
-			  | NETIF_F_HW_VLAN_RX | NETIF_F_HW_VLAN_FILTER);
-	ndev->features |= NETIF_F_GRO;
+	ndev->hw_features = NETIF_F_SG | NETIF_F_IP_CSUM |
+		NETIF_F_TSO | NETIF_F_TSO6 | NETIF_F_TSO_ECN |
+		NETIF_F_HW_VLAN_TX | NETIF_F_RXCSUM;
+	ndev->features = ndev->hw_features |
+		NETIF_F_HW_VLAN_RX | NETIF_F_HW_VLAN_FILTER;
 
 	if (test_bit(QL_DMA64, &qdev->flags))
 		ndev->features |= NETIF_F_HIGHDMA;
diff -druN linux-2.6.39-libre/drivers/net/r8169.c linux-3.0-rc7-libre/drivers/net/r8169.c
--- linux-2.6.39-libre/drivers/net/r8169.c	2011-05-19 02:12:22.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/r8169.c	2011-07-21 06:54:50.000000000 -0400
@@ -26,6 +26,7 @@
 #include <linux/pm_runtime.h>
 #include <linux/firmware.h>
 #include <linux/pci-aspm.h>
+#include <linux/prefetch.h>
 
 #include <asm/system.h>
 #include <asm/io.h>
@@ -37,6 +38,8 @@
 
 #define FIRMWARE_8168D_1	"/*(DEBLOBBED)*/"
 #define FIRMWARE_8168D_2	"/*(DEBLOBBED)*/"
+#define FIRMWARE_8168E_1	"/*(DEBLOBBED)*/"
+#define FIRMWARE_8168E_2	"/*(DEBLOBBED)*/"
 #define FIRMWARE_8105E_1	"/*(DEBLOBBED)*/"
 
 #ifdef RTL8169_DEBUG
@@ -96,89 +99,125 @@
 #define RTL_R32(reg)		readl (ioaddr + (reg))
 
 enum mac_version {
-	RTL_GIGA_MAC_NONE   = 0x00,
-	RTL_GIGA_MAC_VER_01 = 0x01, // 8169
-	RTL_GIGA_MAC_VER_02 = 0x02, // 8169S
-	RTL_GIGA_MAC_VER_03 = 0x03, // 8110S
-	RTL_GIGA_MAC_VER_04 = 0x04, // 8169SB
-	RTL_GIGA_MAC_VER_05 = 0x05, // 8110SCd
-	RTL_GIGA_MAC_VER_06 = 0x06, // 8110SCe
-	RTL_GIGA_MAC_VER_07 = 0x07, // 8102e
-	RTL_GIGA_MAC_VER_08 = 0x08, // 8102e
-	RTL_GIGA_MAC_VER_09 = 0x09, // 8102e
-	RTL_GIGA_MAC_VER_10 = 0x0a, // 8101e
-	RTL_GIGA_MAC_VER_11 = 0x0b, // 8168Bb
-	RTL_GIGA_MAC_VER_12 = 0x0c, // 8168Be
-	RTL_GIGA_MAC_VER_13 = 0x0d, // 8101Eb
-	RTL_GIGA_MAC_VER_14 = 0x0e, // 8101 ?
-	RTL_GIGA_MAC_VER_15 = 0x0f, // 8101 ?
-	RTL_GIGA_MAC_VER_16 = 0x11, // 8101Ec
-	RTL_GIGA_MAC_VER_17 = 0x10, // 8168Bf
-	RTL_GIGA_MAC_VER_18 = 0x12, // 8168CP
-	RTL_GIGA_MAC_VER_19 = 0x13, // 8168C
-	RTL_GIGA_MAC_VER_20 = 0x14, // 8168C
-	RTL_GIGA_MAC_VER_21 = 0x15, // 8168C
-	RTL_GIGA_MAC_VER_22 = 0x16, // 8168C
-	RTL_GIGA_MAC_VER_23 = 0x17, // 8168CP
-	RTL_GIGA_MAC_VER_24 = 0x18, // 8168CP
-	RTL_GIGA_MAC_VER_25 = 0x19, // 8168D
-	RTL_GIGA_MAC_VER_26 = 0x1a, // 8168D
-	RTL_GIGA_MAC_VER_27 = 0x1b, // 8168DP
-	RTL_GIGA_MAC_VER_28 = 0x1c, // 8168DP
-	RTL_GIGA_MAC_VER_29 = 0x1d, // 8105E
-	RTL_GIGA_MAC_VER_30 = 0x1e, // 8105E
+	RTL_GIGA_MAC_VER_01 = 0,
+	RTL_GIGA_MAC_VER_02,
+	RTL_GIGA_MAC_VER_03,
+	RTL_GIGA_MAC_VER_04,
+	RTL_GIGA_MAC_VER_05,
+	RTL_GIGA_MAC_VER_06,
+	RTL_GIGA_MAC_VER_07,
+	RTL_GIGA_MAC_VER_08,
+	RTL_GIGA_MAC_VER_09,
+	RTL_GIGA_MAC_VER_10,
+	RTL_GIGA_MAC_VER_11,
+	RTL_GIGA_MAC_VER_12,
+	RTL_GIGA_MAC_VER_13,
+	RTL_GIGA_MAC_VER_14,
+	RTL_GIGA_MAC_VER_15,
+	RTL_GIGA_MAC_VER_16,
+	RTL_GIGA_MAC_VER_17,
+	RTL_GIGA_MAC_VER_18,
+	RTL_GIGA_MAC_VER_19,
+	RTL_GIGA_MAC_VER_20,
+	RTL_GIGA_MAC_VER_21,
+	RTL_GIGA_MAC_VER_22,
+	RTL_GIGA_MAC_VER_23,
+	RTL_GIGA_MAC_VER_24,
+	RTL_GIGA_MAC_VER_25,
+	RTL_GIGA_MAC_VER_26,
+	RTL_GIGA_MAC_VER_27,
+	RTL_GIGA_MAC_VER_28,
+	RTL_GIGA_MAC_VER_29,
+	RTL_GIGA_MAC_VER_30,
+	RTL_GIGA_MAC_VER_31,
+	RTL_GIGA_MAC_VER_32,
+	RTL_GIGA_MAC_VER_33,
+	RTL_GIGA_MAC_NONE   = 0xff,
 };
 
-#define _R(NAME,MAC,MASK) \
-	{ .name = NAME, .mac_version = MAC, .RxConfigMask = MASK }
+enum rtl_tx_desc_version {
+	RTL_TD_0	= 0,
+	RTL_TD_1	= 1,
+};
+
+#define _R(NAME,TD,FW) \
+	{ .name = NAME, .txd_version = TD, .fw_name = FW }
 
 static const struct {
 	const char *name;
-	u8 mac_version;
-	u32 RxConfigMask;	/* Clears the bits supported by this chip */
-} rtl_chip_info[] = {
-	_R("RTL8169",		RTL_GIGA_MAC_VER_01, 0xff7e1880), // 8169
-	_R("RTL8169s",		RTL_GIGA_MAC_VER_02, 0xff7e1880), // 8169S
-	_R("RTL8110s",		RTL_GIGA_MAC_VER_03, 0xff7e1880), // 8110S
-	_R("RTL8169sb/8110sb",	RTL_GIGA_MAC_VER_04, 0xff7e1880), // 8169SB
-	_R("RTL8169sc/8110sc",	RTL_GIGA_MAC_VER_05, 0xff7e1880), // 8110SCd
-	_R("RTL8169sc/8110sc",	RTL_GIGA_MAC_VER_06, 0xff7e1880), // 8110SCe
-	_R("RTL8102e",		RTL_GIGA_MAC_VER_07, 0xff7e1880), // PCI-E
-	_R("RTL8102e",		RTL_GIGA_MAC_VER_08, 0xff7e1880), // PCI-E
-	_R("RTL8102e",		RTL_GIGA_MAC_VER_09, 0xff7e1880), // PCI-E
-	_R("RTL8101e",		RTL_GIGA_MAC_VER_10, 0xff7e1880), // PCI-E
-	_R("RTL8168b/8111b",	RTL_GIGA_MAC_VER_11, 0xff7e1880), // PCI-E
-	_R("RTL8168b/8111b",	RTL_GIGA_MAC_VER_12, 0xff7e1880), // PCI-E
-	_R("RTL8101e",		RTL_GIGA_MAC_VER_13, 0xff7e1880), // PCI-E 8139
-	_R("RTL8100e",		RTL_GIGA_MAC_VER_14, 0xff7e1880), // PCI-E 8139
-	_R("RTL8100e",		RTL_GIGA_MAC_VER_15, 0xff7e1880), // PCI-E 8139
-	_R("RTL8168b/8111b",	RTL_GIGA_MAC_VER_17, 0xff7e1880), // PCI-E
-	_R("RTL8101e",		RTL_GIGA_MAC_VER_16, 0xff7e1880), // PCI-E
-	_R("RTL8168cp/8111cp",	RTL_GIGA_MAC_VER_18, 0xff7e1880), // PCI-E
-	_R("RTL8168c/8111c",	RTL_GIGA_MAC_VER_19, 0xff7e1880), // PCI-E
-	_R("RTL8168c/8111c",	RTL_GIGA_MAC_VER_20, 0xff7e1880), // PCI-E
-	_R("RTL8168c/8111c",	RTL_GIGA_MAC_VER_21, 0xff7e1880), // PCI-E
-	_R("RTL8168c/8111c",	RTL_GIGA_MAC_VER_22, 0xff7e1880), // PCI-E
-	_R("RTL8168cp/8111cp",	RTL_GIGA_MAC_VER_23, 0xff7e1880), // PCI-E
-	_R("RTL8168cp/8111cp",	RTL_GIGA_MAC_VER_24, 0xff7e1880), // PCI-E
-	_R("RTL8168d/8111d",	RTL_GIGA_MAC_VER_25, 0xff7e1880), // PCI-E
-	_R("RTL8168d/8111d",	RTL_GIGA_MAC_VER_26, 0xff7e1880), // PCI-E
-	_R("RTL8168dp/8111dp",	RTL_GIGA_MAC_VER_27, 0xff7e1880), // PCI-E
-	_R("RTL8168dp/8111dp",	RTL_GIGA_MAC_VER_28, 0xff7e1880), // PCI-E
-	_R("RTL8105e",		RTL_GIGA_MAC_VER_29, 0xff7e1880), // PCI-E
-	_R("RTL8105e",		RTL_GIGA_MAC_VER_30, 0xff7e1880)  // PCI-E
-};
-#undef _R
-
-static const struct rtl_firmware_info {
-	int mac_version;
+	enum rtl_tx_desc_version txd_version;
 	const char *fw_name;
-} rtl_firmware_infos[] = {
-	{ .mac_version = RTL_GIGA_MAC_VER_25, .fw_name = FIRMWARE_8168D_1 },
-	{ .mac_version = RTL_GIGA_MAC_VER_26, .fw_name = FIRMWARE_8168D_2 },
-	{ .mac_version = RTL_GIGA_MAC_VER_29, .fw_name = FIRMWARE_8105E_1 },
-	{ .mac_version = RTL_GIGA_MAC_VER_30, .fw_name = FIRMWARE_8105E_1 }
+} rtl_chip_infos[] = {
+	/* PCI devices. */
+	[RTL_GIGA_MAC_VER_01] =
+		_R("RTL8169",		RTL_TD_0, NULL),
+	[RTL_GIGA_MAC_VER_02] =
+		_R("RTL8169s",		RTL_TD_0, NULL),
+	[RTL_GIGA_MAC_VER_03] =
+		_R("RTL8110s",		RTL_TD_0, NULL),
+	[RTL_GIGA_MAC_VER_04] =
+		_R("RTL8169sb/8110sb",	RTL_TD_0, NULL),
+	[RTL_GIGA_MAC_VER_05] =
+		_R("RTL8169sc/8110sc",	RTL_TD_0, NULL),
+	[RTL_GIGA_MAC_VER_06] =
+		_R("RTL8169sc/8110sc",	RTL_TD_0, NULL),
+	/* PCI-E devices. */
+	[RTL_GIGA_MAC_VER_07] =
+		_R("RTL8102e",		RTL_TD_1, NULL),
+	[RTL_GIGA_MAC_VER_08] =
+		_R("RTL8102e",		RTL_TD_1, NULL),
+	[RTL_GIGA_MAC_VER_09] =
+		_R("RTL8102e",		RTL_TD_1, NULL),
+	[RTL_GIGA_MAC_VER_10] =
+		_R("RTL8101e",		RTL_TD_0, NULL),
+	[RTL_GIGA_MAC_VER_11] =
+		_R("RTL8168b/8111b",	RTL_TD_0, NULL),
+	[RTL_GIGA_MAC_VER_12] =
+		_R("RTL8168b/8111b",	RTL_TD_0, NULL),
+	[RTL_GIGA_MAC_VER_13] =
+		_R("RTL8101e",		RTL_TD_0, NULL),
+	[RTL_GIGA_MAC_VER_14] =
+		_R("RTL8100e",		RTL_TD_0, NULL),
+	[RTL_GIGA_MAC_VER_15] =
+		_R("RTL8100e",		RTL_TD_0, NULL),
+	[RTL_GIGA_MAC_VER_16] =
+		_R("RTL8101e",		RTL_TD_0, NULL),
+	[RTL_GIGA_MAC_VER_17] =
+		_R("RTL8168b/8111b",	RTL_TD_0, NULL),
+	[RTL_GIGA_MAC_VER_18] =
+		_R("RTL8168cp/8111cp",	RTL_TD_1, NULL),
+	[RTL_GIGA_MAC_VER_19] =
+		_R("RTL8168c/8111c",	RTL_TD_1, NULL),
+	[RTL_GIGA_MAC_VER_20] =
+		_R("RTL8168c/8111c",	RTL_TD_1, NULL),
+	[RTL_GIGA_MAC_VER_21] =
+		_R("RTL8168c/8111c",	RTL_TD_1, NULL),
+	[RTL_GIGA_MAC_VER_22] =
+		_R("RTL8168c/8111c",	RTL_TD_1, NULL),
+	[RTL_GIGA_MAC_VER_23] =
+		_R("RTL8168cp/8111cp",	RTL_TD_1, NULL),
+	[RTL_GIGA_MAC_VER_24] =
+		_R("RTL8168cp/8111cp",	RTL_TD_1, NULL),
+	[RTL_GIGA_MAC_VER_25] =
+		_R("RTL8168d/8111d",	RTL_TD_1, FIRMWARE_8168D_1),
+	[RTL_GIGA_MAC_VER_26] =
+		_R("RTL8168d/8111d",	RTL_TD_1, FIRMWARE_8168D_2),
+	[RTL_GIGA_MAC_VER_27] =
+		_R("RTL8168dp/8111dp",	RTL_TD_1, NULL),
+	[RTL_GIGA_MAC_VER_28] =
+		_R("RTL8168dp/8111dp",	RTL_TD_1, NULL),
+	[RTL_GIGA_MAC_VER_29] =
+		_R("RTL8105e",		RTL_TD_1, FIRMWARE_8105E_1),
+	[RTL_GIGA_MAC_VER_30] =
+		_R("RTL8105e",		RTL_TD_1, FIRMWARE_8105E_1),
+	[RTL_GIGA_MAC_VER_31] =
+		_R("RTL8168dp/8111dp",	RTL_TD_1, NULL),
+	[RTL_GIGA_MAC_VER_32] =
+		_R("RTL8168e/8111e",	RTL_TD_1, FIRMWARE_8168E_1),
+	[RTL_GIGA_MAC_VER_33] =
+		_R("RTL8168e/8111e",	RTL_TD_1, FIRMWARE_8168E_2)
 };
+#undef _R
 
 enum cfg_version {
 	RTL_CFG_0 = 0x00,
@@ -232,6 +271,9 @@
 	IntrStatus	= 0x3e,
 	TxConfig	= 0x40,
 	RxConfig	= 0x44,
+
+#define RTL_RX_CONFIG_MASK		0xff7e1880u
+
 	RxMissed	= 0x4c,
 	Cfg9346		= 0x50,
 	Config0		= 0x51,
@@ -325,7 +367,9 @@
 #define OCPAR_FLAG			0x80000000
 #define OCPAR_GPHY_WRITE_CMD		0x8000f060
 #define OCPAR_GPHY_READ_CMD		0x0000f060
-	RDSAR1			= 0xd0	/* 8168c only. Undocumented on 8168dp */
+	RDSAR1			= 0xd0,	/* 8168c only. Undocumented on 8168dp */
+	MISC			= 0xf0,	/* 8168e only. */
+#define TXPLA_RST			(1 << 29)
 };
 
 enum rtl_register_content {
@@ -403,6 +447,7 @@
 	BWF		= (1 << 6),	/* Accept Broadcast wakeup frame */
 	MWF		= (1 << 5),	/* Accept Multicast wakeup frame */
 	UWF		= (1 << 4),	/* Accept Unicast wakeup frame */
+	Spi_en		= (1 << 3),
 	LanWake		= (1 << 1),	/* LanWake enable/disable */
 	PMEStatus	= (1 << 0),	/* PME status can be reset by PCI RST# */
 
@@ -451,21 +496,69 @@
 	CounterDump	= 0x8,
 };
 
-enum desc_status_bit {
+enum rtl_desc_bit {
+	/* First doubleword. */
 	DescOwn		= (1 << 31), /* Descriptor is owned by NIC */
 	RingEnd		= (1 << 30), /* End of descriptor ring */
 	FirstFrag	= (1 << 29), /* First segment of a packet */
 	LastFrag	= (1 << 28), /* Final segment of a packet */
+};
 
-	/* Tx private */
-	LargeSend	= (1 << 27), /* TCP Large Send Offload (TSO) */
-	MSSShift	= 16,        /* MSS value position */
-	MSSMask		= 0xfff,     /* MSS value + LargeSend bit: 12 bits */
-	IPCS		= (1 << 18), /* Calculate IP checksum */
-	UDPCS		= (1 << 17), /* Calculate UDP/IP checksum */
-	TCPCS		= (1 << 16), /* Calculate TCP/IP checksum */
-	TxVlanTag	= (1 << 17), /* Add VLAN tag */
+/* Generic case. */
+enum rtl_tx_desc_bit {
+	/* First doubleword. */
+	TD_LSO		= (1 << 27),		/* Large Send Offload */
+#define TD_MSS_MAX			0x07ffu	/* MSS value */
 
+	/* Second doubleword. */
+	TxVlanTag	= (1 << 17),		/* Add VLAN tag */
+};
+
+/* 8169, 8168b and 810x except 8102e. */
+enum rtl_tx_desc_bit_0 {
+	/* First doubleword. */
+#define TD0_MSS_SHIFT			16	/* MSS position (11 bits) */
+	TD0_TCP_CS	= (1 << 16),		/* Calculate TCP/IP checksum */
+	TD0_UDP_CS	= (1 << 17),		/* Calculate UDP/IP checksum */
+	TD0_IP_CS	= (1 << 18),		/* Calculate IP checksum */
+};
+
+/* 8102e, 8168c and beyond. */
+enum rtl_tx_desc_bit_1 {
+	/* Second doubleword. */
+#define TD1_MSS_SHIFT			18	/* MSS position (11 bits) */
+	TD1_IP_CS	= (1 << 29),		/* Calculate IP checksum */
+	TD1_TCP_CS	= (1 << 30),		/* Calculate TCP/IP checksum */
+	TD1_UDP_CS	= (1 << 31),		/* Calculate UDP/IP checksum */
+};
+
+static const struct rtl_tx_desc_info {
+	struct {
+		u32 udp;
+		u32 tcp;
+	} checksum;
+	u16 mss_shift;
+	u16 opts_offset;
+} tx_desc_info [] = {
+	[RTL_TD_0] = {
+		.checksum = {
+			.udp	= TD0_IP_CS | TD0_UDP_CS,
+			.tcp	= TD0_IP_CS | TD0_TCP_CS
+		},
+		.mss_shift	= TD0_MSS_SHIFT,
+		.opts_offset	= 0
+	},
+	[RTL_TD_1] = {
+		.checksum = {
+			.udp	= TD1_IP_CS | TD1_UDP_CS,
+			.tcp	= TD1_IP_CS | TD1_TCP_CS
+		},
+		.mss_shift	= TD1_MSS_SHIFT,
+		.opts_offset	= 1
+	}
+};
+
+enum rtl_rx_desc_bit {
 	/* Rx private */
 	PID1		= (1 << 18), /* Protocol ID bit 1/2 */
 	PID0		= (1 << 17), /* Protocol ID bit 2/2 */
@@ -525,13 +618,13 @@
 
 struct rtl8169_private {
 	void __iomem *mmio_addr;	/* memory map physical address */
-	struct pci_dev *pci_dev;	/* Index of PCI device */
+	struct pci_dev *pci_dev;
 	struct net_device *dev;
 	struct napi_struct napi;
-	spinlock_t lock;		/* spin lock flag */
+	spinlock_t lock;
 	u32 msg_enable;
-	int chipset;
-	int mac_version;
+	u16 txd_version;
+	u16 mac_version;
 	u32 cur_rx; /* Index into the Rx descriptor buffer of next Rx pkt. */
 	u32 cur_tx; /* Index into the Tx descriptor buffer of next Rx pkt. */
 	u32 dirty_rx;
@@ -547,7 +640,6 @@
 	u16 intr_event;
 	u16 napi_event;
 	u16 intr_mask;
-	int phy_1000_ctrl_reg;
 
 	struct mdio_ops {
 		void (*write)(void __iomem *, int, int);
@@ -646,7 +738,7 @@
 	msleep(2);
 	for (i = 0; i < 5; i++) {
 		udelay(100);
-		if (!(RTL_R32(ERIDR) & ERIAR_FLAG))
+		if (!(RTL_R32(ERIAR) & ERIAR_FLAG))
 			break;
 	}
 
@@ -657,32 +749,49 @@
 #define OOB_CMD_DRIVER_START	0x05
 #define OOB_CMD_DRIVER_STOP	0x06
 
+static u16 rtl8168_get_ocp_reg(struct rtl8169_private *tp)
+{
+	return (tp->mac_version == RTL_GIGA_MAC_VER_31) ? 0xb8 : 0x10;
+}
+
 static void rtl8168_driver_start(struct rtl8169_private *tp)
 {
+	u16 reg;
 	int i;
 
 	rtl8168_oob_notify(tp, OOB_CMD_DRIVER_START);
 
+	reg = rtl8168_get_ocp_reg(tp);
+
 	for (i = 0; i < 10; i++) {
 		msleep(10);
-		if (ocp_read(tp, 0x0f, 0x0010) & 0x00000800)
+		if (ocp_read(tp, 0x0f, reg) & 0x00000800)
 			break;
 	}
 }
 
 static void rtl8168_driver_stop(struct rtl8169_private *tp)
 {
+	u16 reg;
 	int i;
 
 	rtl8168_oob_notify(tp, OOB_CMD_DRIVER_STOP);
 
+	reg = rtl8168_get_ocp_reg(tp);
+
 	for (i = 0; i < 10; i++) {
 		msleep(10);
-		if ((ocp_read(tp, 0x0f, 0x0010) & 0x00000800) == 0)
+		if ((ocp_read(tp, 0x0f, reg) & 0x00000800) == 0)
 			break;
 	}
 }
 
+static int r8168dp_check_dash(struct rtl8169_private *tp)
+{
+	u16 reg = rtl8168_get_ocp_reg(tp);
+
+	return (ocp_read(tp, 0x0f, reg) & 0x00008000) ? 1 : 0;
+}
 
 static void r8169_mdio_write(void __iomem *ioaddr, int reg_addr, int value)
 {
@@ -981,9 +1090,8 @@
 }
 
 static void __rtl8169_check_link_status(struct net_device *dev,
-				      struct rtl8169_private *tp,
-				      void __iomem *ioaddr,
-				      bool pm)
+					struct rtl8169_private *tp,
+					void __iomem *ioaddr, bool pm)
 {
 	unsigned long flags;
 
@@ -1100,6 +1208,11 @@
 	return 0;
 }
 
+static const char *rtl_lookup_firmware_name(struct rtl8169_private *tp)
+{
+	return rtl_chip_infos[tp->mac_version].fw_name;
+}
+
 static void rtl8169_get_drvinfo(struct net_device *dev,
 				struct ethtool_drvinfo *info)
 {
@@ -1108,6 +1221,8 @@
 	strcpy(info->driver, MODULENAME);
 	strcpy(info->version, RTL8169_VERSION);
 	strcpy(info->bus_info, pci_name(tp->pci_dev));
+	strncpy(info->fw_version, IS_ERR_OR_NULL(tp->fw) ? "N/A" :
+		rtl_lookup_firmware_name(tp), sizeof(info->fw_version) - 1);
 }
 
 static int rtl8169_get_regs_len(struct net_device *dev)
@@ -1169,16 +1284,7 @@
 		giga_ctrl &= ~(ADVERTISE_1000FULL | ADVERTISE_1000HALF);
 
 		/* The 8100e/8101e/8102e do Fast Ethernet only. */
-		if ((tp->mac_version != RTL_GIGA_MAC_VER_07) &&
-		    (tp->mac_version != RTL_GIGA_MAC_VER_08) &&
-		    (tp->mac_version != RTL_GIGA_MAC_VER_09) &&
-		    (tp->mac_version != RTL_GIGA_MAC_VER_10) &&
-		    (tp->mac_version != RTL_GIGA_MAC_VER_13) &&
-		    (tp->mac_version != RTL_GIGA_MAC_VER_14) &&
-		    (tp->mac_version != RTL_GIGA_MAC_VER_15) &&
-		    (tp->mac_version != RTL_GIGA_MAC_VER_16) &&
-		    (tp->mac_version != RTL_GIGA_MAC_VER_29) &&
-		    (tp->mac_version != RTL_GIGA_MAC_VER_30)) {
+		if (tp->mii.supports_gmii) {
 			if (adv & ADVERTISED_1000baseT_Half)
 				giga_ctrl |= ADVERTISE_1000HALF;
 			if (adv & ADVERTISED_1000baseT_Full)
@@ -1208,12 +1314,10 @@
 			bmcr |= BMCR_FULLDPLX;
 	}
 
-	tp->phy_1000_ctrl_reg = giga_ctrl;
-
 	rtl_writephy(tp, MII_BMCR, bmcr);
 
-	if ((tp->mac_version == RTL_GIGA_MAC_VER_02) ||
-	    (tp->mac_version == RTL_GIGA_MAC_VER_03)) {
+	if (tp->mac_version == RTL_GIGA_MAC_VER_02 ||
+	    tp->mac_version == RTL_GIGA_MAC_VER_03) {
 		if ((speed == SPEED_100) && (autoneg != AUTONEG_ENABLE)) {
 			rtl_writephy(tp, 0x17, 0x2138);
 			rtl_writephy(tp, 0x0e, 0x0260);
@@ -1235,10 +1339,14 @@
 	int ret;
 
 	ret = tp->set_speed(dev, autoneg, speed, duplex, advertising);
+	if (ret < 0)
+		goto out;
 
-	if (netif_running(dev) && (tp->phy_1000_ctrl_reg & ADVERTISE_1000FULL))
+	if (netif_running(dev) && (autoneg == AUTONEG_ENABLE) &&
+	    (advertising & ADVERTISED_1000baseT_Full)) {
 		mod_timer(&tp->timer, jiffies + RTL8169_PHY_TIMEOUT);
-
+	}
+out:
 	return ret;
 }
 
@@ -1248,22 +1356,25 @@
 	unsigned long flags;
 	int ret;
 
+	del_timer_sync(&tp->timer);
+
 	spin_lock_irqsave(&tp->lock, flags);
-	ret = rtl8169_set_speed(dev,
-		cmd->autoneg, cmd->speed, cmd->duplex, cmd->advertising);
+	ret = rtl8169_set_speed(dev, cmd->autoneg, ethtool_cmd_speed(cmd),
+				cmd->duplex, cmd->advertising);
 	spin_unlock_irqrestore(&tp->lock, flags);
 
 	return ret;
 }
 
-static u32 rtl8169_get_rx_csum(struct net_device *dev)
+static u32 rtl8169_fix_features(struct net_device *dev, u32 features)
 {
-	struct rtl8169_private *tp = netdev_priv(dev);
+	if (dev->mtu > TD_MSS_MAX)
+		features &= ~NETIF_F_ALL_TSO;
 
-	return tp->cp_cmd & RxChkSum;
+	return features;
 }
 
-static int rtl8169_set_rx_csum(struct net_device *dev, u32 data)
+static int rtl8169_set_features(struct net_device *dev, u32 features)
 {
 	struct rtl8169_private *tp = netdev_priv(dev);
 	void __iomem *ioaddr = tp->mmio_addr;
@@ -1271,11 +1382,16 @@
 
 	spin_lock_irqsave(&tp->lock, flags);
 
-	if (data)
+	if (features & NETIF_F_RXCSUM)
 		tp->cp_cmd |= RxChkSum;
 	else
 		tp->cp_cmd &= ~RxChkSum;
 
+	if (dev->features & NETIF_F_HW_VLAN_RX)
+		tp->cp_cmd |= RxVlan;
+	else
+		tp->cp_cmd &= ~RxVlan;
+
 	RTL_W16(CPlusCmd, tp->cp_cmd);
 	RTL_R16(CPlusCmd);
 
@@ -1291,27 +1407,6 @@
 		TxVlanTag | swab16(vlan_tx_tag_get(skb)) : 0x00;
 }
 
-#define NETIF_F_HW_VLAN_TX_RX	(NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX)
-
-static void rtl8169_vlan_mode(struct net_device *dev)
-{
-	struct rtl8169_private *tp = netdev_priv(dev);
-	void __iomem *ioaddr = tp->mmio_addr;
-	unsigned long flags;
-
-	spin_lock_irqsave(&tp->lock, flags);
-	if (dev->features & NETIF_F_HW_VLAN_RX)
-		tp->cp_cmd |= RxVlan;
-	else
-		tp->cp_cmd &= ~RxVlan;
-	RTL_W16(CPlusCmd, tp->cp_cmd);
-	/* PCI commit */
-	RTL_R16(CPlusCmd);
-	spin_unlock_irqrestore(&tp->lock, flags);
-
-	dev->vlan_features = dev->features &~ NETIF_F_HW_VLAN_TX_RX;
-}
-
 static void rtl8169_rx_vlan_tag(struct RxDesc *desc, struct sk_buff *skb)
 {
 	u32 opts2 = le32_to_cpu(desc->opts2);
@@ -1337,7 +1432,7 @@
 	cmd->advertising = (status & TBINwEnable) ?  ADVERTISED_Autoneg : 0;
 	cmd->autoneg = !!(status & TBINwEnable);
 
-	cmd->speed = SPEED_1000;
+	ethtool_cmd_speed_set(cmd, SPEED_1000);
 	cmd->duplex = DUPLEX_FULL; /* Always set */
 
 	return 0;
@@ -1422,11 +1517,11 @@
 {
 	struct rtl8169_private *tp = netdev_priv(dev);
 	void __iomem *ioaddr = tp->mmio_addr;
+	struct device *d = &tp->pci_dev->dev;
 	struct rtl8169_counters *counters;
 	dma_addr_t paddr;
 	u32 cmd;
 	int wait = 1000;
-	struct device *d = &tp->pci_dev->dev;
 
 	/*
 	 * Some chips are unable to dump tally counters when the receiver
@@ -1446,7 +1541,6 @@
 
 	while (wait--) {
 		if ((RTL_R32(CounterAddrLow) & CounterDump) == 0) {
-			/* copy updated counters */
 			memcpy(&tp->counters, counters, sizeof(*counters));
 			break;
 		}
@@ -1492,28 +1586,6 @@
 	}
 }
 
-static int rtl8169_set_flags(struct net_device *dev, u32 data)
-{
-	struct rtl8169_private *tp = netdev_priv(dev);
-	unsigned long old_feat = dev->features;
-	int rc;
-
-	if ((tp->mac_version == RTL_GIGA_MAC_VER_05) &&
-	    !(data & ETH_FLAG_RXVLAN)) {
-		netif_info(tp, drv, dev, "8110SCd requires hardware Rx VLAN\n");
-		return -EINVAL;
-	}
-
-	rc = ethtool_op_set_flags(dev, data, ETH_FLAG_TXVLAN | ETH_FLAG_RXVLAN);
-	if (rc)
-		return rc;
-
-	if ((old_feat ^ dev->features) & NETIF_F_HW_VLAN_RX)
-		rtl8169_vlan_mode(dev);
-
-	return 0;
-}
-
 static const struct ethtool_ops rtl8169_ethtool_ops = {
 	.get_drvinfo		= rtl8169_get_drvinfo,
 	.get_regs_len		= rtl8169_get_regs_len,
@@ -1522,24 +1594,18 @@
 	.set_settings		= rtl8169_set_settings,
 	.get_msglevel		= rtl8169_get_msglevel,
 	.set_msglevel		= rtl8169_set_msglevel,
-	.get_rx_csum		= rtl8169_get_rx_csum,
-	.set_rx_csum		= rtl8169_set_rx_csum,
-	.set_tx_csum		= ethtool_op_set_tx_csum,
-	.set_sg			= ethtool_op_set_sg,
-	.set_tso		= ethtool_op_set_tso,
 	.get_regs		= rtl8169_get_regs,
 	.get_wol		= rtl8169_get_wol,
 	.set_wol		= rtl8169_set_wol,
 	.get_strings		= rtl8169_get_strings,
 	.get_sset_count		= rtl8169_get_sset_count,
 	.get_ethtool_stats	= rtl8169_get_ethtool_stats,
-	.set_flags		= rtl8169_set_flags,
-	.get_flags		= ethtool_op_get_flags,
 };
 
 static void rtl8169_get_mac_version(struct rtl8169_private *tp,
-				    void __iomem *ioaddr)
+				    struct net_device *dev, u8 default_version)
 {
+	void __iomem *ioaddr = tp->mmio_addr;
 	/*
 	 * The driver currently handles the 8168Bf and the 8168Be identically
 	 * but they can be identified more specifically through the test below
@@ -1551,11 +1617,16 @@
 	 *
 	 * (RTL_R32(TxConfig) & 0x700000) == 0x200000 ? 8101Eb : 8101Ec
 	 */
-	static const struct {
+	static const struct rtl_mac_info {
 		u32 mask;
 		u32 val;
 		int mac_version;
 	} mac_info[] = {
+		/* 8168E family. */
+		{ 0x7cf00000, 0x2c200000,	RTL_GIGA_MAC_VER_33 },
+		{ 0x7cf00000, 0x2c100000,	RTL_GIGA_MAC_VER_32 },
+		{ 0x7c800000, 0x2c000000,	RTL_GIGA_MAC_VER_33 },
+
 		/* 8168D family. */
 		{ 0x7cf00000, 0x28300000,	RTL_GIGA_MAC_VER_26 },
 		{ 0x7cf00000, 0x28100000,	RTL_GIGA_MAC_VER_25 },
@@ -1564,6 +1635,7 @@
 		/* 8168DP family. */
 		{ 0x7cf00000, 0x28800000,	RTL_GIGA_MAC_VER_27 },
 		{ 0x7cf00000, 0x28a00000,	RTL_GIGA_MAC_VER_28 },
+		{ 0x7cf00000, 0x28b00000,	RTL_GIGA_MAC_VER_31 },
 
 		/* 8168C family. */
 		{ 0x7cf00000, 0x3cb00000,	RTL_GIGA_MAC_VER_24 },
@@ -1583,6 +1655,7 @@
 		{ 0x7c800000, 0x30000000,	RTL_GIGA_MAC_VER_11 },
 
 		/* 8101 family. */
+		{ 0x7cf00000, 0x40b00000,	RTL_GIGA_MAC_VER_30 },
 		{ 0x7cf00000, 0x40a00000,	RTL_GIGA_MAC_VER_30 },
 		{ 0x7cf00000, 0x40900000,	RTL_GIGA_MAC_VER_29 },
 		{ 0x7c800000, 0x40800000,	RTL_GIGA_MAC_VER_30 },
@@ -1612,13 +1685,20 @@
 
 		/* Catch-all */
 		{ 0x00000000, 0x00000000,	RTL_GIGA_MAC_NONE   }
-	}, *p = mac_info;
+	};
+	const struct rtl_mac_info *p = mac_info;
 	u32 reg;
 
 	reg = RTL_R32(TxConfig);
 	while ((reg & p->mask) != p->val)
 		p++;
 	tp->mac_version = p->mac_version;
+
+	if (tp->mac_version == RTL_GIGA_MAC_NONE) {
+		netif_notice(tp, probe, dev,
+			     "unknown MAC, using family default\n");
+		tp->mac_version = default_version;
+	}
 }
 
 static void rtl8169_print_mac_version(struct rtl8169_private *tp)
@@ -1688,14 +1768,14 @@
 		case PHY_BJMPN:
 			if (regno > index) {
 				netif_err(tp, probe, tp->dev,
-					"Out of range of firmware\n");
+					  "Out of range of firmware\n");
 				return;
 			}
 			break;
 		case PHY_READCOUNT_EQ_SKIP:
 			if (index + 2 >= fw_size) {
 				netif_err(tp, probe, tp->dev,
-					"Out of range of firmware\n");
+					  "Out of range of firmware\n");
 				return;
 			}
 			break;
@@ -1704,7 +1784,7 @@
 		case PHY_SKIPN:
 			if (index + 1 + regno >= fw_size) {
 				netif_err(tp, probe, tp->dev,
-					"Out of range of firmware\n");
+					  "Out of range of firmware\n");
 				return;
 			}
 			break;
@@ -1760,10 +1840,7 @@
 			index++;
 			break;
 		case PHY_READCOUNT_EQ_SKIP:
-			if (count == data)
-				index += 2;
-			else
-				index += 1;
+			index += (count == data) ? 2 : 1;
 			break;
 		case PHY_COMP_EQ_SKIPN:
 			if (predata == data)
@@ -2174,7 +2251,7 @@
 
 		/*
 		 * Tx Error Issue
-		 * enhance line driver power
+		 * Enhance line driver power
 		 */
 		{ 0x1f, 0x0002 },
 		{ 0x06, 0x5561 },
@@ -2286,7 +2363,7 @@
 
 		/*
 		 * Tx Error Issue
-		 * enhance line driver power
+		 * Enhance line driver power
 		 */
 		{ 0x1f, 0x0002 },
 		{ 0x06, 0x5561 },
@@ -2442,6 +2519,79 @@
 	rtl_patchphy(tp, 0x0d, 1 << 5);
 }
 
+static void rtl8168e_hw_phy_config(struct rtl8169_private *tp)
+{
+	static const struct phy_reg phy_reg_init[] = {
+		/* Enable Delay cap */
+		{ 0x1f, 0x0005 },
+		{ 0x05, 0x8b80 },
+		{ 0x06, 0xc896 },
+		{ 0x1f, 0x0000 },
+
+		/* Channel estimation fine tune */
+		{ 0x1f, 0x0001 },
+		{ 0x0b, 0x6c20 },
+		{ 0x07, 0x2872 },
+		{ 0x1c, 0xefff },
+		{ 0x1f, 0x0003 },
+		{ 0x14, 0x6420 },
+		{ 0x1f, 0x0000 },
+
+		/* Update PFM & 10M TX idle timer */
+		{ 0x1f, 0x0007 },
+		{ 0x1e, 0x002f },
+		{ 0x15, 0x1919 },
+		{ 0x1f, 0x0000 },
+
+		{ 0x1f, 0x0007 },
+		{ 0x1e, 0x00ac },
+		{ 0x18, 0x0006 },
+		{ 0x1f, 0x0000 }
+	};
+
+	rtl_apply_firmware(tp);
+
+	rtl_writephy_batch(tp, phy_reg_init, ARRAY_SIZE(phy_reg_init));
+
+	/* DCO enable for 10M IDLE Power */
+	rtl_writephy(tp, 0x1f, 0x0007);
+	rtl_writephy(tp, 0x1e, 0x0023);
+	rtl_w1w0_phy(tp, 0x17, 0x0006, 0x0000);
+	rtl_writephy(tp, 0x1f, 0x0000);
+
+	/* For impedance matching */
+	rtl_writephy(tp, 0x1f, 0x0002);
+	rtl_w1w0_phy(tp, 0x08, 0x8000, 0x7f00);
+	rtl_writephy(tp, 0x1f, 0x0000);
+
+	/* PHY auto speed down */
+	rtl_writephy(tp, 0x1f, 0x0007);
+	rtl_writephy(tp, 0x1e, 0x002d);
+	rtl_w1w0_phy(tp, 0x18, 0x0050, 0x0000);
+	rtl_writephy(tp, 0x1f, 0x0000);
+	rtl_w1w0_phy(tp, 0x14, 0x8000, 0x0000);
+
+	rtl_writephy(tp, 0x1f, 0x0005);
+	rtl_writephy(tp, 0x05, 0x8b86);
+	rtl_w1w0_phy(tp, 0x06, 0x0001, 0x0000);
+	rtl_writephy(tp, 0x1f, 0x0000);
+
+	rtl_writephy(tp, 0x1f, 0x0005);
+	rtl_writephy(tp, 0x05, 0x8b85);
+	rtl_w1w0_phy(tp, 0x06, 0x0000, 0x2000);
+	rtl_writephy(tp, 0x1f, 0x0007);
+	rtl_writephy(tp, 0x1e, 0x0020);
+	rtl_w1w0_phy(tp, 0x15, 0x0000, 0x1100);
+	rtl_writephy(tp, 0x1f, 0x0006);
+	rtl_writephy(tp, 0x00, 0x5a00);
+	rtl_writephy(tp, 0x1f, 0x0000);
+	rtl_writephy(tp, 0x0d, 0x0007);
+	rtl_writephy(tp, 0x0e, 0x003c);
+	rtl_writephy(tp, 0x0d, 0x4007);
+	rtl_writephy(tp, 0x0e, 0x0000);
+	rtl_writephy(tp, 0x0d, 0x0000);
+}
+
 static void rtl8102e_hw_phy_config(struct rtl8169_private *tp)
 {
 	static const struct phy_reg phy_reg_init[] = {
@@ -2556,6 +2706,13 @@
 	case RTL_GIGA_MAC_VER_30:
 		rtl8105e_hw_phy_config(tp);
 		break;
+	case RTL_GIGA_MAC_VER_31:
+		/* None. */
+		break;
+	case RTL_GIGA_MAC_VER_32:
+	case RTL_GIGA_MAC_VER_33:
+		rtl8168e_hw_phy_config(tp);
+		break;
 
 	default:
 		break;
@@ -2572,9 +2729,6 @@
 
 	assert(tp->mac_version > RTL_GIGA_MAC_VER_01);
 
-	if (!(tp->phy_1000_ctrl_reg & ADVERTISE_1000FULL))
-		return;
-
 	spin_lock_irq(&tp->lock);
 
 	if (tp->phy_reset_pending(tp)) {
@@ -2599,28 +2753,6 @@
 	spin_unlock_irq(&tp->lock);
 }
 
-static inline void rtl8169_delete_timer(struct net_device *dev)
-{
-	struct rtl8169_private *tp = netdev_priv(dev);
-	struct timer_list *timer = &tp->timer;
-
-	if (tp->mac_version <= RTL_GIGA_MAC_VER_01)
-		return;
-
-	del_timer_sync(timer);
-}
-
-static inline void rtl8169_request_timer(struct net_device *dev)
-{
-	struct rtl8169_private *tp = netdev_priv(dev);
-	struct timer_list *timer = &tp->timer;
-
-	if (tp->mac_version <= RTL_GIGA_MAC_VER_01)
-		return;
-
-	mod_timer(timer, jiffies + RTL8169_PHY_TIMEOUT);
-}
-
 #ifdef CONFIG_NET_POLL_CONTROLLER
 /*
  * Polling 'interrupt' - used by things like netconsole to send skbs
@@ -2688,11 +2820,11 @@
 	rtl8169_phy_reset(dev, tp);
 
 	rtl8169_set_speed(dev, AUTONEG_ENABLE, SPEED_1000, DUPLEX_FULL,
-		ADVERTISED_10baseT_Half | ADVERTISED_10baseT_Full |
-		ADVERTISED_100baseT_Half | ADVERTISED_100baseT_Full |
-		(tp->mii.supports_gmii ?
-			ADVERTISED_1000baseT_Half |
-			ADVERTISED_1000baseT_Full : 0));
+			  ADVERTISED_10baseT_Half | ADVERTISED_10baseT_Full |
+			  ADVERTISED_100baseT_Half | ADVERTISED_100baseT_Full |
+			  (tp->mii.supports_gmii ?
+			   ADVERTISED_1000baseT_Half |
+			   ADVERTISED_1000baseT_Full : 0));
 
 	if (RTL_R8(PHYstatus) & TBI_Enable)
 		netif_info(tp, link, dev, "TBI auto-negotiating\n");
@@ -2745,7 +2877,8 @@
 	return netif_running(dev) ? tp->do_ioctl(tp, data, cmd) : -ENODEV;
 }
 
-static int rtl_xmii_ioctl(struct rtl8169_private *tp, struct mii_ioctl_data *data, int cmd)
+static int rtl_xmii_ioctl(struct rtl8169_private *tp,
+			  struct mii_ioctl_data *data, int cmd)
 {
 	switch (cmd) {
 	case SIOCGMIIPHY:
@@ -2845,6 +2978,8 @@
 	.ndo_tx_timeout		= rtl8169_tx_timeout,
 	.ndo_validate_addr	= eth_validate_addr,
 	.ndo_change_mtu		= rtl8169_change_mtu,
+	.ndo_fix_features	= rtl8169_fix_features,
+	.ndo_set_features	= rtl8169_set_features,
 	.ndo_set_mac_address	= rtl_set_mac_address,
 	.ndo_do_ioctl		= rtl8169_ioctl,
 	.ndo_set_multicast_list	= rtl_set_rx_mode,
@@ -2864,6 +2999,7 @@
 		ops->read	= r8168dp_1_mdio_read;
 		break;
 	case RTL_GIGA_MAC_VER_28:
+	case RTL_GIGA_MAC_VER_31:
 		ops->write	= r8168dp_2_mdio_write;
 		ops->read	= r8168dp_2_mdio_read;
 		break;
@@ -2905,33 +3041,82 @@
 static void r8168_phy_power_up(struct rtl8169_private *tp)
 {
 	rtl_writephy(tp, 0x1f, 0x0000);
-	rtl_writephy(tp, 0x0e, 0x0000);
+	switch (tp->mac_version) {
+	case RTL_GIGA_MAC_VER_11:
+	case RTL_GIGA_MAC_VER_12:
+	case RTL_GIGA_MAC_VER_17:
+	case RTL_GIGA_MAC_VER_18:
+	case RTL_GIGA_MAC_VER_19:
+	case RTL_GIGA_MAC_VER_20:
+	case RTL_GIGA_MAC_VER_21:
+	case RTL_GIGA_MAC_VER_22:
+	case RTL_GIGA_MAC_VER_23:
+	case RTL_GIGA_MAC_VER_24:
+	case RTL_GIGA_MAC_VER_25:
+	case RTL_GIGA_MAC_VER_26:
+	case RTL_GIGA_MAC_VER_27:
+	case RTL_GIGA_MAC_VER_28:
+	case RTL_GIGA_MAC_VER_31:
+		rtl_writephy(tp, 0x0e, 0x0000);
+		break;
+	default:
+		break;
+	}
 	rtl_writephy(tp, MII_BMCR, BMCR_ANENABLE);
 }
 
 static void r8168_phy_power_down(struct rtl8169_private *tp)
 {
 	rtl_writephy(tp, 0x1f, 0x0000);
-	rtl_writephy(tp, 0x0e, 0x0200);
-	rtl_writephy(tp, MII_BMCR, BMCR_PDOWN);
+	switch (tp->mac_version) {
+	case RTL_GIGA_MAC_VER_32:
+	case RTL_GIGA_MAC_VER_33:
+		rtl_writephy(tp, MII_BMCR, BMCR_ANENABLE | BMCR_PDOWN);
+		break;
+
+	case RTL_GIGA_MAC_VER_11:
+	case RTL_GIGA_MAC_VER_12:
+	case RTL_GIGA_MAC_VER_17:
+	case RTL_GIGA_MAC_VER_18:
+	case RTL_GIGA_MAC_VER_19:
+	case RTL_GIGA_MAC_VER_20:
+	case RTL_GIGA_MAC_VER_21:
+	case RTL_GIGA_MAC_VER_22:
+	case RTL_GIGA_MAC_VER_23:
+	case RTL_GIGA_MAC_VER_24:
+	case RTL_GIGA_MAC_VER_25:
+	case RTL_GIGA_MAC_VER_26:
+	case RTL_GIGA_MAC_VER_27:
+	case RTL_GIGA_MAC_VER_28:
+	case RTL_GIGA_MAC_VER_31:
+		rtl_writephy(tp, 0x0e, 0x0200);
+	default:
+		rtl_writephy(tp, MII_BMCR, BMCR_PDOWN);
+		break;
+	}
 }
 
 static void r8168_pll_power_down(struct rtl8169_private *tp)
 {
 	void __iomem *ioaddr = tp->mmio_addr;
 
-	if (((tp->mac_version == RTL_GIGA_MAC_VER_27) ||
-	     (tp->mac_version == RTL_GIGA_MAC_VER_28)) &&
-	    (ocp_read(tp, 0x0f, 0x0010) & 0x00008000)) {
+	if ((tp->mac_version == RTL_GIGA_MAC_VER_27 ||
+	     tp->mac_version == RTL_GIGA_MAC_VER_28 ||
+	     tp->mac_version == RTL_GIGA_MAC_VER_31) &&
+	    r8168dp_check_dash(tp)) {
 		return;
 	}
 
-	if (((tp->mac_version == RTL_GIGA_MAC_VER_23) ||
-	     (tp->mac_version == RTL_GIGA_MAC_VER_24)) &&
+	if ((tp->mac_version == RTL_GIGA_MAC_VER_23 ||
+	     tp->mac_version == RTL_GIGA_MAC_VER_24) &&
 	    (RTL_R16(CPlusCmd) & ASF)) {
 		return;
 	}
 
+	if (tp->mac_version == RTL_GIGA_MAC_VER_32 ||
+	    tp->mac_version == RTL_GIGA_MAC_VER_33)
+		rtl_ephy_write(ioaddr, 0x19, 0xff64);
+
 	if (__rtl8169_get_wol(tp) & WAKE_ANY) {
 		rtl_writephy(tp, 0x1f, 0x0000);
 		rtl_writephy(tp, MII_BMCR, 0x0000);
@@ -2948,6 +3133,9 @@
 	case RTL_GIGA_MAC_VER_26:
 	case RTL_GIGA_MAC_VER_27:
 	case RTL_GIGA_MAC_VER_28:
+	case RTL_GIGA_MAC_VER_31:
+	case RTL_GIGA_MAC_VER_32:
+	case RTL_GIGA_MAC_VER_33:
 		RTL_W8(PMCH, RTL_R8(PMCH) & ~0x80);
 		break;
 	}
@@ -2957,9 +3145,10 @@
 {
 	void __iomem *ioaddr = tp->mmio_addr;
 
-	if (((tp->mac_version == RTL_GIGA_MAC_VER_27) ||
-	     (tp->mac_version == RTL_GIGA_MAC_VER_28)) &&
-	    (ocp_read(tp, 0x0f, 0x0010) & 0x00008000)) {
+	if ((tp->mac_version == RTL_GIGA_MAC_VER_27 ||
+	     tp->mac_version == RTL_GIGA_MAC_VER_28 ||
+	     tp->mac_version == RTL_GIGA_MAC_VER_31) &&
+	    r8168dp_check_dash(tp)) {
 		return;
 	}
 
@@ -2968,6 +3157,9 @@
 	case RTL_GIGA_MAC_VER_26:
 	case RTL_GIGA_MAC_VER_27:
 	case RTL_GIGA_MAC_VER_28:
+	case RTL_GIGA_MAC_VER_31:
+	case RTL_GIGA_MAC_VER_32:
+	case RTL_GIGA_MAC_VER_33:
 		RTL_W8(PMCH, RTL_R8(PMCH) | 0x80);
 		break;
 	}
@@ -3022,6 +3214,9 @@
 	case RTL_GIGA_MAC_VER_26:
 	case RTL_GIGA_MAC_VER_27:
 	case RTL_GIGA_MAC_VER_28:
+	case RTL_GIGA_MAC_VER_31:
+	case RTL_GIGA_MAC_VER_32:
+	case RTL_GIGA_MAC_VER_33:
 		ops->down	= r8168_pll_power_down;
 		ops->up		= r8168_pll_power_up;
 		break;
@@ -3033,6 +3228,22 @@
 	}
 }
 
+static void rtl_hw_reset(struct rtl8169_private *tp)
+{
+	void __iomem *ioaddr = tp->mmio_addr;
+	int i;
+
+	/* Soft reset the chip. */
+	RTL_W8(ChipCmd, CmdReset);
+
+	/* Check that the chip has finished the reset. */
+	for (i = 0; i < 100; i++) {
+		if ((RTL_R8(ChipCmd) & CmdReset) == 0)
+			break;
+		msleep_interruptible(1);
+	}
+}
+
 static int __devinit
 rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
 {
@@ -3042,7 +3253,7 @@
 	struct mii_if_info *mii;
 	struct net_device *dev;
 	void __iomem *ioaddr;
-	unsigned int i;
+	int chipset, i;
 	int rc;
 
 	if (netif_msg_drv(&debug)) {
@@ -3132,6 +3343,7 @@
 		rc = -EIO;
 		goto err_out_free_res_3;
 	}
+	tp->mmio_addr = ioaddr;
 
 	tp->pcie_cap = pci_find_capability(pdev, PCI_CAP_ID_EXP);
 	if (!tp->pcie_cap)
@@ -3139,22 +3351,14 @@
 
 	RTL_W16(IntrMask, 0x0000);
 
-	/* Soft reset the chip. */
-	RTL_W8(ChipCmd, CmdReset);
-
-	/* Check that the chip has finished the reset. */
-	for (i = 0; i < 100; i++) {
-		if ((RTL_R8(ChipCmd) & CmdReset) == 0)
-			break;
-		msleep_interruptible(1);
-	}
+	rtl_hw_reset(tp);
 
 	RTL_W16(IntrStatus, 0xffff);
 
 	pci_set_master(pdev);
 
 	/* Identify chip attached to board */
-	rtl8169_get_mac_version(tp, ioaddr);
+	rtl8169_get_mac_version(tp, dev, cfg->default_ver);
 
 	/*
 	 * Pretend we are using VLANs; This bypasses a nasty bug where
@@ -3166,25 +3370,10 @@
 	rtl_init_mdio_ops(tp);
 	rtl_init_pll_power_ops(tp);
 
-	/* Use appropriate default if unknown */
-	if (tp->mac_version == RTL_GIGA_MAC_NONE) {
-		netif_notice(tp, probe, dev,
-			     "unknown MAC, using family default\n");
-		tp->mac_version = cfg->default_ver;
-	}
-
 	rtl8169_print_mac_version(tp);
 
-	for (i = 0; i < ARRAY_SIZE(rtl_chip_info); i++) {
-		if (tp->mac_version == rtl_chip_info[i].mac_version)
-			break;
-	}
-	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_4;
-	}
-	tp->chipset = i;
+	chipset = tp->mac_version;
+	tp->txd_version = rtl_chip_infos[chipset].txd_version;
 
 	RTL_W8(Cfg9346, Cfg9346_Unlock);
 	RTL_W8(Config1, RTL_R8(Config1) | PMEnable);
@@ -3204,8 +3393,6 @@
 		tp->phy_reset_pending = rtl8169_tbi_reset_pending;
 		tp->link_ok = rtl8169_tbi_link_ok;
 		tp->do_ioctl = rtl_tbi_ioctl;
-
-		tp->phy_1000_ctrl_reg = ADVERTISE_1000FULL; /* Implied by TBI */
 	} else {
 		tp->set_speed = rtl8169_set_speed_xmii;
 		tp->get_settings = rtl8169_gset_xmii;
@@ -3217,8 +3404,6 @@
 
 	spin_lock_init(&tp->lock);
 
-	tp->mmio_addr = ioaddr;
-
 	/* Get MAC address */
 	for (i = 0; i < MAC_ADDR_LEN; i++)
 		dev->dev_addr[i] = RTL_R8(MAC0 + i);
@@ -3231,7 +3416,19 @@
 
 	netif_napi_add(dev, &tp->napi, rtl8169_poll, R8169_NAPI_WEIGHT);
 
-	dev->features |= NETIF_F_HW_VLAN_TX_RX | NETIF_F_GRO;
+	/* don't enable SG, IP_CSUM and TSO by default - it might not work
+	 * properly for all devices */
+	dev->features |= NETIF_F_RXCSUM |
+		NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
+
+	dev->hw_features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO |
+		NETIF_F_RXCSUM | NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
+	dev->vlan_features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO |
+		NETIF_F_HIGHDMA;
+
+	if (tp->mac_version == RTL_GIGA_MAC_VER_05)
+		/* 8110SCd requires hardware Rx VLAN - disallow toggling */
+		dev->hw_features &= ~NETIF_F_HW_VLAN_RX;
 
 	tp->intr_mask = 0xffff;
 	tp->hw_start = cfg->hw_start;
@@ -3251,12 +3448,12 @@
 	pci_set_drvdata(pdev, dev);
 
 	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,
+		   rtl_chip_infos[chipset].name, dev->base_addr, dev->dev_addr,
 		   (u32)(RTL_R32(TxConfig) & 0x9cf0f8ff), dev->irq);
 
-	if ((tp->mac_version == RTL_GIGA_MAC_VER_27) ||
-	    (tp->mac_version == RTL_GIGA_MAC_VER_28)) {
+	if (tp->mac_version == RTL_GIGA_MAC_VER_27 ||
+	    tp->mac_version == RTL_GIGA_MAC_VER_28 ||
+	    tp->mac_version == RTL_GIGA_MAC_VER_31) {
 		rtl8168_driver_start(tp);
 	}
 
@@ -3288,8 +3485,9 @@
 	struct net_device *dev = pci_get_drvdata(pdev);
 	struct rtl8169_private *tp = netdev_priv(dev);
 
-	if ((tp->mac_version == RTL_GIGA_MAC_VER_27) ||
-	    (tp->mac_version == RTL_GIGA_MAC_VER_28)) {
+	if (tp->mac_version == RTL_GIGA_MAC_VER_27 ||
+	    tp->mac_version == RTL_GIGA_MAC_VER_28 ||
+	    tp->mac_version == RTL_GIGA_MAC_VER_31) {
 		rtl8168_driver_stop(tp);
 	}
 
@@ -3312,33 +3510,23 @@
 
 static void rtl_reject_firmware(struct rtl8169_private *tp)
 {
-	int i;
-
 	/* Return early if the firmware is already loaded / cached. */
-	if (!IS_ERR(tp->fw))
-		goto out;
-
-	for (i = 0; i < ARRAY_SIZE(rtl_firmware_infos); i++) {
-		const struct rtl_firmware_info *info = rtl_firmware_infos + i;
+	if (IS_ERR(tp->fw)) {
+		const char *name;
 
-		if (info->mac_version == tp->mac_version) {
-			const char *name = info->fw_name;
+		name = rtl_lookup_firmware_name(tp);
+		if (name) {
 			int rc;
 
 			rc = reject_firmware(&tp->fw, name, &tp->pci_dev->dev);
-			if (rc < 0) {
-				netif_warn(tp, ifup, tp->dev, "unable to load "
-					"firmware patch %s (%d)\n", name, rc);
-				goto out_disable_reject_firmware;
-			}
-			goto out;
+			if (rc >= 0)
+				return;
+
+			netif_warn(tp, ifup, tp->dev, "unable to load "
+				"firmware patch %s (%d)\n", name, rc);
 		}
+		tp->fw = NULL;
 	}
-
-out_disable_reject_firmware:
-	tp->fw = NULL;
-out:
-	return;
 }
 
 static int rtl8169_open(struct net_device *dev)
@@ -3384,14 +3572,12 @@
 
 	rtl8169_init_phy(dev, tp);
 
-	rtl8169_vlan_mode(dev);
+	rtl8169_set_features(dev, dev->features);
 
 	rtl_pll_power_up(tp);
 
 	rtl_hw_start(dev);
 
-	rtl8169_request_timer(dev);
-
 	tp->saved_wolopts = 0;
 	pm_runtime_put_noidle(&pdev->dev);
 
@@ -3423,7 +3609,8 @@
 	rtl8169_irq_mask_and_ack(ioaddr);
 
 	if (tp->mac_version == RTL_GIGA_MAC_VER_27 ||
-	    tp->mac_version == RTL_GIGA_MAC_VER_28) {
+	    tp->mac_version == RTL_GIGA_MAC_VER_28 ||
+	    tp->mac_version == RTL_GIGA_MAC_VER_31) {
 		while (RTL_R8(TxPoll) & NPQ)
 			udelay(20);
 
@@ -3441,7 +3628,7 @@
 	void __iomem *ioaddr = tp->mmio_addr;
 	u32 cfg = rtl8169_rx_config;
 
-	cfg |= (RTL_R32(RxConfig) & rtl_chip_info[tp->chipset].RxConfigMask);
+	cfg |= (RTL_R32(RxConfig) & RTL_RX_CONFIG_MASK);
 	RTL_W32(RxConfig, cfg);
 
 	/* Set DMA burst size and Interframe Gap Time */
@@ -3452,25 +3639,14 @@
 static void rtl_hw_start(struct net_device *dev)
 {
 	struct rtl8169_private *tp = netdev_priv(dev);
-	void __iomem *ioaddr = tp->mmio_addr;
-	unsigned int i;
 
-	/* Soft reset the chip. */
-	RTL_W8(ChipCmd, CmdReset);
-
-	/* Check that the chip has finished the reset. */
-	for (i = 0; i < 100; i++) {
-		if ((RTL_R8(ChipCmd) & CmdReset) == 0)
-			break;
-		msleep_interruptible(1);
-	}
+	rtl_hw_reset(tp);
 
 	tp->hw_start(dev);
 
 	netif_start_queue(dev);
 }
 
-
 static void rtl_set_rx_tx_desc_registers(struct rtl8169_private *tp,
 					 void __iomem *ioaddr)
 {
@@ -3502,7 +3678,7 @@
 
 static void rtl8169_set_magic_reg(void __iomem *ioaddr, unsigned mac_version)
 {
-	static const struct {
+	static const struct rtl_cfg2_info {
 		u32 mac_version;
 		u32 clk;
 		u32 val;
@@ -3511,7 +3687,8 @@
 		{ RTL_GIGA_MAC_VER_05, PCI_Clock_66MHz, 0x000fffff },
 		{ RTL_GIGA_MAC_VER_06, PCI_Clock_33MHz, 0x00ffff00 }, // 8110SCe
 		{ RTL_GIGA_MAC_VER_06, PCI_Clock_66MHz, 0x00ffffff }
-	}, *p = cfg2_info;
+	};
+	const struct rtl_cfg2_info *p = cfg2_info;
 	unsigned int i;
 	u32 clk;
 
@@ -3536,26 +3713,26 @@
 	}
 
 	RTL_W8(Cfg9346, Cfg9346_Unlock);
-	if ((tp->mac_version == RTL_GIGA_MAC_VER_01) ||
-	    (tp->mac_version == RTL_GIGA_MAC_VER_02) ||
-	    (tp->mac_version == RTL_GIGA_MAC_VER_03) ||
-	    (tp->mac_version == RTL_GIGA_MAC_VER_04))
+	if (tp->mac_version == RTL_GIGA_MAC_VER_01 ||
+	    tp->mac_version == RTL_GIGA_MAC_VER_02 ||
+	    tp->mac_version == RTL_GIGA_MAC_VER_03 ||
+	    tp->mac_version == RTL_GIGA_MAC_VER_04)
 		RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb);
 
 	RTL_W8(EarlyTxThres, NoEarlyTx);
 
 	rtl_set_rx_max_size(ioaddr, rx_buf_sz);
 
-	if ((tp->mac_version == RTL_GIGA_MAC_VER_01) ||
-	    (tp->mac_version == RTL_GIGA_MAC_VER_02) ||
-	    (tp->mac_version == RTL_GIGA_MAC_VER_03) ||
-	    (tp->mac_version == RTL_GIGA_MAC_VER_04))
+	if (tp->mac_version == RTL_GIGA_MAC_VER_01 ||
+	    tp->mac_version == RTL_GIGA_MAC_VER_02 ||
+	    tp->mac_version == RTL_GIGA_MAC_VER_03 ||
+	    tp->mac_version == RTL_GIGA_MAC_VER_04)
 		rtl_set_rx_tx_config_registers(tp);
 
 	tp->cp_cmd |= rtl_rw_cpluscmd(ioaddr) | PCIMulRW;
 
-	if ((tp->mac_version == RTL_GIGA_MAC_VER_02) ||
-	    (tp->mac_version == RTL_GIGA_MAC_VER_03)) {
+	if (tp->mac_version == RTL_GIGA_MAC_VER_02 ||
+	    tp->mac_version == RTL_GIGA_MAC_VER_03) {
 		dprintk("Set MAC Reg C+CR Offset 0xE0. "
 			"Bit-3 and bit-14 MUST be 1\n");
 		tp->cp_cmd |= (1 << 14);
@@ -3573,10 +3750,10 @@
 
 	rtl_set_rx_tx_desc_registers(tp, ioaddr);
 
-	if ((tp->mac_version != RTL_GIGA_MAC_VER_01) &&
-	    (tp->mac_version != RTL_GIGA_MAC_VER_02) &&
-	    (tp->mac_version != RTL_GIGA_MAC_VER_03) &&
-	    (tp->mac_version != RTL_GIGA_MAC_VER_04)) {
+	if (tp->mac_version != RTL_GIGA_MAC_VER_01 &&
+	    tp->mac_version != RTL_GIGA_MAC_VER_02 &&
+	    tp->mac_version != RTL_GIGA_MAC_VER_03 &&
+	    tp->mac_version != RTL_GIGA_MAC_VER_04) {
 		RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb);
 		rtl_set_rx_tx_config_registers(tp);
 	}
@@ -3820,6 +3997,17 @@
 	RTL_W16(CPlusCmd, RTL_R16(CPlusCmd) & ~R8168_CPCMD_QUIRK_MASK);
 }
 
+static void rtl_hw_start_8168dp(void __iomem *ioaddr, struct pci_dev *pdev)
+{
+	rtl_csi_access_enable_1(ioaddr);
+
+	rtl_tx_performance_tweak(pdev, 0x5 << MAX_READ_REQUEST_SHIFT);
+
+	RTL_W8(MaxTxPacketSize, TxPacketMax);
+
+	rtl_disable_clock_request(pdev);
+}
+
 static void rtl_hw_start_8168d_4(void __iomem *ioaddr, struct pci_dev *pdev)
 {
 	static const struct ephy_info e_info_8168d_4[] = {
@@ -3846,6 +4034,41 @@
 	rtl_enable_clock_request(pdev);
 }
 
+static void rtl_hw_start_8168e(void __iomem *ioaddr, struct pci_dev *pdev)
+{
+	static const struct ephy_info e_info_8168e[] = {
+		{ 0x00, 0x0200,	0x0100 },
+		{ 0x00, 0x0000,	0x0004 },
+		{ 0x06, 0x0002,	0x0001 },
+		{ 0x06, 0x0000,	0x0030 },
+		{ 0x07, 0x0000,	0x2000 },
+		{ 0x00, 0x0000,	0x0020 },
+		{ 0x03, 0x5800,	0x2000 },
+		{ 0x03, 0x0000,	0x0001 },
+		{ 0x01, 0x0800,	0x1000 },
+		{ 0x07, 0x0000,	0x4000 },
+		{ 0x1e, 0x0000,	0x2000 },
+		{ 0x19, 0xffff,	0xfe6c },
+		{ 0x0a, 0x0000,	0x0040 }
+	};
+
+	rtl_csi_access_enable_2(ioaddr);
+
+	rtl_ephy_init(ioaddr, e_info_8168e, ARRAY_SIZE(e_info_8168e));
+
+	rtl_tx_performance_tweak(pdev, 0x5 << MAX_READ_REQUEST_SHIFT);
+
+	RTL_W8(MaxTxPacketSize, TxPacketMax);
+
+	rtl_disable_clock_request(pdev);
+
+	/* Reset tx FIFO pointer */
+	RTL_W32(MISC, RTL_R32(MISC) | TXPLA_RST);
+	RTL_W32(MISC, RTL_R32(MISC) & ~TXPLA_RST);
+
+	RTL_W8(Config5, RTL_R8(Config5) & ~Spi_en);
+}
+
 static void rtl_hw_start_8168(struct net_device *dev)
 {
 	struct rtl8169_private *tp = netdev_priv(dev);
@@ -3883,55 +4106,64 @@
 	switch (tp->mac_version) {
 	case RTL_GIGA_MAC_VER_11:
 		rtl_hw_start_8168bb(ioaddr, pdev);
-	break;
+		break;
 
 	case RTL_GIGA_MAC_VER_12:
 	case RTL_GIGA_MAC_VER_17:
 		rtl_hw_start_8168bef(ioaddr, pdev);
-	break;
+		break;
 
 	case RTL_GIGA_MAC_VER_18:
 		rtl_hw_start_8168cp_1(ioaddr, pdev);
-	break;
+		break;
 
 	case RTL_GIGA_MAC_VER_19:
 		rtl_hw_start_8168c_1(ioaddr, pdev);
-	break;
+		break;
 
 	case RTL_GIGA_MAC_VER_20:
 		rtl_hw_start_8168c_2(ioaddr, pdev);
-	break;
+		break;
 
 	case RTL_GIGA_MAC_VER_21:
 		rtl_hw_start_8168c_3(ioaddr, pdev);
-	break;
+		break;
 
 	case RTL_GIGA_MAC_VER_22:
 		rtl_hw_start_8168c_4(ioaddr, pdev);
-	break;
+		break;
 
 	case RTL_GIGA_MAC_VER_23:
 		rtl_hw_start_8168cp_2(ioaddr, pdev);
-	break;
+		break;
 
 	case RTL_GIGA_MAC_VER_24:
 		rtl_hw_start_8168cp_3(ioaddr, pdev);
-	break;
+		break;
 
 	case RTL_GIGA_MAC_VER_25:
 	case RTL_GIGA_MAC_VER_26:
 	case RTL_GIGA_MAC_VER_27:
 		rtl_hw_start_8168d(ioaddr, pdev);
-	break;
+		break;
 
 	case RTL_GIGA_MAC_VER_28:
 		rtl_hw_start_8168d_4(ioaddr, pdev);
-	break;
+		break;
+
+	case RTL_GIGA_MAC_VER_31:
+		rtl_hw_start_8168dp(ioaddr, pdev);
+		break;
+
+	case RTL_GIGA_MAC_VER_32:
+	case RTL_GIGA_MAC_VER_33:
+		rtl_hw_start_8168e(ioaddr, pdev);
+		break;
 
 	default:
 		printk(KERN_ERR PFX "%s: unknown chipset (mac_version = %d).\n",
 			dev->name, tp->mac_version);
-	break;
+		break;
 	}
 
 	RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb);
@@ -4015,10 +4247,10 @@
 		{ 0x0a,	0, 0x0020 }
 	};
 
-	/* Force LAN exit from ASPM if Rx/Tx are not idel */
+	/* Force LAN exit from ASPM if Rx/Tx are not idle */
 	RTL_W32(FuncEvent, RTL_R32(FuncEvent) | 0x002800);
 
-	/* disable Early Tally Counter */
+	/* Disable Early Tally Counter */
 	RTL_W32(FuncEvent, RTL_R32(FuncEvent) & ~0x010000);
 
 	RTL_W8(MCU, RTL_R8(MCU) | EN_NDP | EN_OOB_RESET);
@@ -4039,8 +4271,8 @@
 	void __iomem *ioaddr = tp->mmio_addr;
 	struct pci_dev *pdev = tp->pci_dev;
 
-	if ((tp->mac_version == RTL_GIGA_MAC_VER_13) ||
-	    (tp->mac_version == RTL_GIGA_MAC_VER_16)) {
+	if (tp->mac_version == RTL_GIGA_MAC_VER_13 ||
+	    tp->mac_version == RTL_GIGA_MAC_VER_16) {
 		int cap = tp->pcie_cap;
 
 		if (cap) {
@@ -4103,6 +4335,8 @@
 		return -EINVAL;
 
 	dev->mtu = new_mtu;
+	netdev_update_features(dev);
+
 	return 0;
 }
 
@@ -4340,6 +4574,7 @@
 	struct rtl8169_private *tp =
 		container_of(work, struct rtl8169_private, task.work);
 	struct net_device *dev = tp->dev;
+	int i;
 
 	rtnl_lock();
 
@@ -4348,19 +4583,15 @@
 
 	rtl8169_wait_for_quiescence(dev);
 
-	rtl8169_rx_interrupt(dev, tp, tp->mmio_addr, ~(u32)0);
+	for (i = 0; i < NUM_RX_DESC; i++)
+		rtl8169_mark_to_asic(tp->RxDescArray + i, rx_buf_sz);
+
 	rtl8169_tx_clear(tp);
 
-	if (tp->dirty_rx == tp->cur_rx) {
-		rtl8169_init_ring_indexes(tp);
-		rtl_hw_start(dev);
-		netif_wake_queue(dev);
-		rtl8169_check_link_status(dev, tp, tp->mmio_addr);
-	} else {
-		if (net_ratelimit())
-			netif_emerg(tp, intr, dev, "Rx buffers shortage\n");
-		rtl8169_schedule_work(dev, rtl8169_reset_task);
-	}
+	rtl8169_init_ring_indexes(tp);
+	rtl_hw_start(dev);
+	netif_wake_queue(dev);
+	rtl8169_check_link_status(dev, tp, tp->mmio_addr);
 
 out_unlock:
 	rtnl_unlock();
@@ -4377,7 +4608,7 @@
 }
 
 static int rtl8169_xmit_frags(struct rtl8169_private *tp, struct sk_buff *skb,
-			      u32 opts1)
+			      u32 *opts)
 {
 	struct skb_shared_info *info = skb_shinfo(skb);
 	unsigned int cur_frag, entry;
@@ -4404,10 +4635,12 @@
 			goto err_out;
 		}
 
-		/* anti gcc 2.95.3 bugware (sic) */
-		status = opts1 | len | (RingEnd * !((entry + 1) % NUM_TX_DESC));
+		/* Anti gcc 2.95.3 bugware (sic) */
+		status = opts[0] | len |
+			(RingEnd * !((entry + 1) % NUM_TX_DESC));
 
 		txd->opts1 = cpu_to_le32(status);
+		txd->opts2 = cpu_to_le32(opts[1]);
 		txd->addr = cpu_to_le64(mapping);
 
 		tp->tx_skb[entry].len = len;
@@ -4425,24 +4658,26 @@
 	return -EIO;
 }
 
-static inline u32 rtl8169_tso_csum(struct sk_buff *skb, struct net_device *dev)
+static inline void rtl8169_tso_csum(struct rtl8169_private *tp,
+				    struct sk_buff *skb, u32 *opts)
 {
-	if (dev->features & NETIF_F_TSO) {
-		u32 mss = skb_shinfo(skb)->gso_size;
+	const struct rtl_tx_desc_info *info = tx_desc_info + tp->txd_version;
+	u32 mss = skb_shinfo(skb)->gso_size;
+	int offset = info->opts_offset;
 
-		if (mss)
-			return LargeSend | ((mss & MSSMask) << MSSShift);
-	}
-	if (skb->ip_summed == CHECKSUM_PARTIAL) {
+	if (mss) {
+		opts[0] |= TD_LSO;
+		opts[offset] |= min(mss, TD_MSS_MAX) << info->mss_shift;
+	} else if (skb->ip_summed == CHECKSUM_PARTIAL) {
 		const struct iphdr *ip = ip_hdr(skb);
 
 		if (ip->protocol == IPPROTO_TCP)
-			return IPCS | TCPCS;
+			opts[offset] |= info->checksum.tcp;
 		else if (ip->protocol == IPPROTO_UDP)
-			return IPCS | UDPCS;
-		WARN_ON(1);	/* we need a WARN() */
+			opts[offset] |= info->checksum.udp;
+		else
+			WARN_ON_ONCE(1);
 	}
-	return 0;
 }
 
 static netdev_tx_t rtl8169_start_xmit(struct sk_buff *skb,
@@ -4455,7 +4690,7 @@
 	struct device *d = &tp->pci_dev->dev;
 	dma_addr_t mapping;
 	u32 status, len;
-	u32 opts1;
+	u32 opts[2];
 	int frags;
 
 	if (unlikely(TX_BUFFS_AVAIL(tp) < skb_shinfo(skb)->nr_frags)) {
@@ -4476,31 +4711,35 @@
 
 	tp->tx_skb[entry].len = len;
 	txd->addr = cpu_to_le64(mapping);
-	txd->opts2 = cpu_to_le32(rtl8169_tx_vlan_tag(tp, skb));
 
-	opts1 = DescOwn | rtl8169_tso_csum(skb, dev);
+	opts[1] = cpu_to_le32(rtl8169_tx_vlan_tag(tp, skb));
+	opts[0] = DescOwn;
 
-	frags = rtl8169_xmit_frags(tp, skb, opts1);
+	rtl8169_tso_csum(tp, skb, opts);
+
+	frags = rtl8169_xmit_frags(tp, skb, opts);
 	if (frags < 0)
 		goto err_dma_1;
 	else if (frags)
-		opts1 |= FirstFrag;
+		opts[0] |= FirstFrag;
 	else {
-		opts1 |= FirstFrag | LastFrag;
+		opts[0] |= FirstFrag | LastFrag;
 		tp->tx_skb[entry].skb = skb;
 	}
 
+	txd->opts2 = cpu_to_le32(opts[1]);
+
 	wmb();
 
-	/* anti gcc 2.95.3 bugware (sic) */
-	status = opts1 | len | (RingEnd * !((entry + 1) % NUM_TX_DESC));
+	/* Anti gcc 2.95.3 bugware (sic) */
+	status = opts[0] | len | (RingEnd * !((entry + 1) % NUM_TX_DESC));
 	txd->opts1 = cpu_to_le32(status);
 
 	tp->cur_tx += frags + 1;
 
 	wmb();
 
-	RTL_W8(TxPoll, NPQ);	/* set polling bit */
+	RTL_W8(TxPoll, NPQ);
 
 	if (TX_BUFFS_AVAIL(tp) < MAX_SKB_FRAGS) {
 		netif_stop_queue(dev);
@@ -4657,20 +4896,12 @@
 	return skb;
 }
 
-/*
- * 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 count;
-	int polling = (budget != ~(u32)0) ? 1 : 0;
 
 	cur_rx = tp->cur_rx;
 	rx_left = NUM_RX_DESC + tp->dirty_rx - cur_rx;
@@ -4730,10 +4961,7 @@
 
 			rtl8169_rx_vlan_tag(desc, skb);
 
-			if (likely(polling))
-				napi_gro_receive(&tp->napi, skb);
-			else
-				netif_rx(skb);
+			napi_gro_receive(&tp->napi, skb);
 
 			dev->stats.rx_bytes += pkt_size;
 			dev->stats.rx_packets++;
@@ -4796,6 +5024,7 @@
 			case RTL_GIGA_MAC_VER_24:
 			case RTL_GIGA_MAC_VER_27:
 			case RTL_GIGA_MAC_VER_28:
+			case RTL_GIGA_MAC_VER_31:
 			/* Experimental science. Pktgen proof. */
 			case RTL_GIGA_MAC_VER_12:
 			case RTL_GIGA_MAC_VER_25:
@@ -4888,7 +5117,7 @@
 	struct rtl8169_private *tp = netdev_priv(dev);
 	void __iomem *ioaddr = tp->mmio_addr;
 
-	rtl8169_delete_timer(dev);
+	del_timer_sync(&tp->timer);
 
 	netif_stop_queue(dev);
 
@@ -4925,7 +5154,7 @@
 
 	pm_runtime_get_sync(&pdev->dev);
 
-	/* update counters before going down */
+	/* Update counters before going down */
 	rtl8169_update_counters(dev);
 
 	rtl8169_down(dev);
@@ -4980,7 +5209,7 @@
 	spin_lock_irqsave(&tp->lock, flags);
 
 	tmp = rtl8169_rx_config | rx_mode |
-	      (RTL_R32(RxConfig) & rtl_chip_info[tp->chipset].RxConfigMask);
+	      (RTL_R32(RxConfig) & RTL_RX_CONFIG_MASK);
 
 	if (tp->mac_version > RTL_GIGA_MAC_VER_06) {
 		u32 data = mc_filter[0];
@@ -5118,15 +5347,15 @@
 }
 
 static const struct dev_pm_ops rtl8169_pm_ops = {
-	.suspend = rtl8169_suspend,
-	.resume = rtl8169_resume,
-	.freeze = rtl8169_suspend,
-	.thaw = rtl8169_resume,
-	.poweroff = rtl8169_suspend,
-	.restore = rtl8169_resume,
-	.runtime_suspend = rtl8169_runtime_suspend,
-	.runtime_resume = rtl8169_runtime_resume,
-	.runtime_idle = rtl8169_runtime_idle,
+	.suspend		= rtl8169_suspend,
+	.resume			= rtl8169_resume,
+	.freeze			= rtl8169_suspend,
+	.thaw			= rtl8169_resume,
+	.poweroff		= rtl8169_suspend,
+	.restore		= rtl8169_resume,
+	.runtime_suspend	= rtl8169_runtime_suspend,
+	.runtime_resume		= rtl8169_runtime_resume,
+	.runtime_idle		= rtl8169_runtime_idle,
 };
 
 #define RTL8169_PM_OPS	(&rtl8169_pm_ops)
@@ -5145,7 +5374,7 @@
 
 	rtl8169_net_suspend(dev);
 
-	/* restore original MAC address */
+	/* Restore original MAC address */
 	rtl_rar_set(tp, dev->perm_addr);
 
 	spin_lock_irq(&tp->lock);
diff -druN linux-2.6.39-libre/drivers/net/rionet.c linux-3.0-rc7-libre/drivers/net/rionet.c
--- linux-2.6.39-libre/drivers/net/rionet.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/rionet.c	2011-07-11 19:51:52.000000000 -0400
@@ -162,8 +162,8 @@
 	rnet->tx_slot &= (RIONET_TX_RING_SIZE - 1);
 
 	if (netif_msg_tx_queued(rnet))
-		printk(KERN_INFO "%s: queued skb %8.8x len %8.8x\n", DRV_NAME,
-		       (u32) skb, skb->len);
+		printk(KERN_INFO "%s: queued skb len %8.8x\n", DRV_NAME,
+		       skb->len);
 
 	return 0;
 }
@@ -378,7 +378,7 @@
 
 static void rionet_remove(struct rio_dev *rdev)
 {
-	struct net_device *ndev = NULL;
+	struct net_device *ndev = rio_get_drvdata(rdev);
 	struct rionet_peer *peer, *tmp;
 
 	free_pages((unsigned long)rionet_active, rdev->net->hport->sys_size ?
@@ -433,22 +433,12 @@
 	.ndo_set_mac_address	= eth_mac_addr,
 };
 
-static int rionet_setup_netdev(struct rio_mport *mport)
+static int rionet_setup_netdev(struct rio_mport *mport, struct net_device *ndev)
 {
 	int rc = 0;
-	struct net_device *ndev = NULL;
 	struct rionet_private *rnet;
 	u16 device_id;
 
-	/* Allocate our net_device structure */
-	ndev = alloc_etherdev(sizeof(struct rionet_private));
-	if (ndev == NULL) {
-		printk(KERN_INFO "%s: could not allocate ethernet device.\n",
-		       DRV_NAME);
-		rc = -ENOMEM;
-		goto out;
-	}
-
 	rionet_active = (struct rio_dev **)__get_free_pages(GFP_KERNEL,
 			mport->sys_size ? __fls(sizeof(void *)) + 4 : 0);
 	if (!rionet_active) {
@@ -504,11 +494,21 @@
 	int rc = -ENODEV;
 	u32 lpef, lsrc_ops, ldst_ops;
 	struct rionet_peer *peer;
+	struct net_device *ndev = NULL;
 
 	/* If local device is not rionet capable, give up quickly */
 	if (!rionet_capable)
 		goto out;
 
+	/* Allocate our net_device structure */
+	ndev = alloc_etherdev(sizeof(struct rionet_private));
+	if (ndev == NULL) {
+		printk(KERN_INFO "%s: could not allocate ethernet device.\n",
+		       DRV_NAME);
+		rc = -ENOMEM;
+		goto out;
+	}
+
 	/*
 	 * First time through, make sure local device is rionet
 	 * capable, setup netdev,  and set flags so this is skipped
@@ -529,7 +529,7 @@
 			goto out;
 		}
 
-		rc = rionet_setup_netdev(rdev->net->hport);
+		rc = rionet_setup_netdev(rdev->net->hport, ndev);
 		rionet_check = 1;
 	}
 
@@ -546,6 +546,8 @@
 		list_add_tail(&peer->node, &rionet_peers);
 	}
 
+	rio_set_drvdata(rdev, ndev);
+
       out:
 	return rc;
 }
diff -druN linux-2.6.39-libre/drivers/net/s2io.c linux-3.0-rc7-libre/drivers/net/s2io.c
--- linux-2.6.39-libre/drivers/net/s2io.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/s2io.c	2011-07-11 19:51:52.000000000 -0400
@@ -78,6 +78,7 @@
 #include <linux/uaccess.h>
 #include <linux/io.h>
 #include <linux/slab.h>
+#include <linux/prefetch.h>
 #include <net/tcp.h>
 
 #include <asm/system.h>
@@ -2244,13 +2245,12 @@
 static void fix_mac_address(struct s2io_nic *sp)
 {
 	struct XENA_dev_config __iomem *bar0 = sp->bar0;
-	u64 val64;
 	int i = 0;
 
 	while (fix_mac[i] != END_SIGN) {
 		writeq(fix_mac[i++], &bar0->gpio_control);
 		udelay(10);
-		val64 = readq(&bar0->gpio_control);
+		(void) readq(&bar0->gpio_control);
 	}
 }
 
@@ -2727,7 +2727,6 @@
 	int j;
 	struct sk_buff *skb;
 	struct RxD_t *rxdp;
-	struct buffAdd *ba;
 	struct RxD1 *rxdp1;
 	struct RxD3 *rxdp3;
 	struct mac_info *mac_control = &sp->mac_control;
@@ -2751,7 +2750,6 @@
 			memset(rxdp, 0, sizeof(struct RxD1));
 		} else if (sp->rxd_mode == RXD_MODE_3B) {
 			rxdp3 = (struct RxD3 *)rxdp;
-			ba = &mac_control->rings[ring_no].ba[blk][j];
 			pci_unmap_single(sp->pdev,
 					 (dma_addr_t)rxdp3->Buffer0_ptr,
 					 BUF0_LEN,
@@ -5383,7 +5381,7 @@
 {
 	struct s2io_nic *sp = netdev_priv(dev);
 	if ((info->autoneg == AUTONEG_ENABLE) ||
-	    (info->speed != SPEED_10000) ||
+	    (ethtool_cmd_speed(info) != SPEED_10000) ||
 	    (info->duplex != DUPLEX_FULL))
 		return -EINVAL;
 	else {
@@ -5417,10 +5415,10 @@
 	info->transceiver = XCVR_EXTERNAL;
 
 	if (netif_carrier_ok(sp->dev)) {
-		info->speed = 10000;
+		ethtool_cmd_speed_set(info, SPEED_10000);
 		info->duplex = DUPLEX_FULL;
 	} else {
-		info->speed = -1;
+		ethtool_cmd_speed_set(info, -1);
 		info->duplex = -1;
 	}
 
@@ -5484,83 +5482,79 @@
 	}
 }
 
-/**
- *  s2io_phy_id  - timer function that alternates adapter LED.
- *  @data : address of the private member of the device structure, which
- *  is a pointer to the s2io_nic structure, provided as an u32.
- * Description: This is actually the timer function that alternates the
- * adapter LED bit of the adapter control bit to set/reset every time on
- * invocation. The timer is set for 1/2 a second, hence tha NIC blinks
- *  once every second.
+/*
+ *  s2io_set_led - control NIC led
  */
-static void s2io_phy_id(unsigned long data)
+static void s2io_set_led(struct s2io_nic *sp, bool on)
 {
-	struct s2io_nic *sp = (struct s2io_nic *)data;
 	struct XENA_dev_config __iomem *bar0 = sp->bar0;
-	u64 val64 = 0;
-	u16 subid;
+	u16 subid = sp->pdev->subsystem_device;
+	u64 val64;
 
-	subid = sp->pdev->subsystem_device;
 	if ((sp->device_type == XFRAME_II_DEVICE) ||
 	    ((subid & 0xFF) >= 0x07)) {
 		val64 = readq(&bar0->gpio_control);
-		val64 ^= GPIO_CTRL_GPIO_0;
+		if (on)
+			val64 |= GPIO_CTRL_GPIO_0;
+		else
+			val64 &= ~GPIO_CTRL_GPIO_0;
+
 		writeq(val64, &bar0->gpio_control);
 	} else {
 		val64 = readq(&bar0->adapter_control);
-		val64 ^= ADAPTER_LED_ON;
+		if (on)
+			val64 |= ADAPTER_LED_ON;
+		else
+			val64 &= ~ADAPTER_LED_ON;
+
 		writeq(val64, &bar0->adapter_control);
 	}
 
-	mod_timer(&sp->id_timer, jiffies + HZ / 2);
 }
 
 /**
- * s2io_ethtool_idnic - To physically identify the nic on the system.
- * @sp : private member of the device structure, which is a pointer to the
- * s2io_nic structure.
- * @id : pointer to the structure with identification parameters given by
- * ethtool.
+ * s2io_ethtool_set_led - To physically identify the nic on the system.
+ * @dev : network device
+ * @state: led setting
+ *
  * Description: Used to physically identify the NIC on the system.
  * The Link LED will blink for a time specified by the user for
  * identification.
  * NOTE: The Link has to be Up to be able to blink the LED. Hence
  * identification is possible only if it's link is up.
- * Return value:
- * int , returns 0 on success
  */
 
-static int s2io_ethtool_idnic(struct net_device *dev, u32 data)
+static int s2io_ethtool_set_led(struct net_device *dev,
+				enum ethtool_phys_id_state state)
 {
-	u64 val64 = 0, last_gpio_ctrl_val;
 	struct s2io_nic *sp = netdev_priv(dev);
 	struct XENA_dev_config __iomem *bar0 = sp->bar0;
-	u16 subid;
+	u16 subid = sp->pdev->subsystem_device;
 
-	subid = sp->pdev->subsystem_device;
-	last_gpio_ctrl_val = readq(&bar0->gpio_control);
 	if ((sp->device_type == XFRAME_I_DEVICE) && ((subid & 0xFF) < 0x07)) {
-		val64 = readq(&bar0->adapter_control);
+		u64 val64 = readq(&bar0->adapter_control);
 		if (!(val64 & ADAPTER_CNTL_EN)) {
 			pr_err("Adapter Link down, cannot blink LED\n");
-			return -EFAULT;
+			return -EAGAIN;
 		}
 	}
-	if (sp->id_timer.function == NULL) {
-		init_timer(&sp->id_timer);
-		sp->id_timer.function = s2io_phy_id;
-		sp->id_timer.data = (unsigned long)sp;
-	}
-	mod_timer(&sp->id_timer, jiffies);
-	if (data)
-		msleep_interruptible(data * HZ);
-	else
-		msleep_interruptible(MAX_FLICKER_TIME);
-	del_timer_sync(&sp->id_timer);
 
-	if (CARDS_WITH_FAULTY_LINK_INDICATORS(sp->device_type, subid)) {
-		writeq(last_gpio_ctrl_val, &bar0->gpio_control);
-		last_gpio_ctrl_val = readq(&bar0->gpio_control);
+	switch (state) {
+	case ETHTOOL_ID_ACTIVE:
+		sp->adapt_ctrl_org = readq(&bar0->gpio_control);
+		return 1;	/* cycle on/off once per second */
+
+	case ETHTOOL_ID_ON:
+		s2io_set_led(sp, true);
+		break;
+
+	case ETHTOOL_ID_OFF:
+		s2io_set_led(sp, false);
+		break;
+
+	case ETHTOOL_ID_INACTIVE:
+		if (CARDS_WITH_FAULTY_LINK_INDICATORS(sp->device_type, subid))
+			writeq(sp->adapt_ctrl_org, &bar0->gpio_control);
 	}
 
 	return 0;
@@ -6625,25 +6619,6 @@
 }
 
 
-static u32 s2io_ethtool_get_rx_csum(struct net_device *dev)
-{
-	struct s2io_nic *sp = netdev_priv(dev);
-
-	return sp->rx_csum;
-}
-
-static int s2io_ethtool_set_rx_csum(struct net_device *dev, u32 data)
-{
-	struct s2io_nic *sp = netdev_priv(dev);
-
-	if (data)
-		sp->rx_csum = 1;
-	else
-		sp->rx_csum = 0;
-
-	return 0;
-}
-
 static int s2io_get_eeprom_len(struct net_device *dev)
 {
 	return XENA_EEPROM_SPACE;
@@ -6695,61 +6670,27 @@
 	}
 }
 
-static int s2io_ethtool_op_set_tx_csum(struct net_device *dev, u32 data)
-{
-	if (data)
-		dev->features |= NETIF_F_IP_CSUM;
-	else
-		dev->features &= ~NETIF_F_IP_CSUM;
-
-	return 0;
-}
-
-static u32 s2io_ethtool_op_get_tso(struct net_device *dev)
-{
-	return (dev->features & NETIF_F_TSO) != 0;
-}
-
-static int s2io_ethtool_op_set_tso(struct net_device *dev, u32 data)
-{
-	if (data)
-		dev->features |= (NETIF_F_TSO | NETIF_F_TSO6);
-	else
-		dev->features &= ~(NETIF_F_TSO | NETIF_F_TSO6);
-
-	return 0;
-}
-
-static int s2io_ethtool_set_flags(struct net_device *dev, u32 data)
+static int s2io_set_features(struct net_device *dev, u32 features)
 {
 	struct s2io_nic *sp = netdev_priv(dev);
-	int rc = 0;
-	int changed = 0;
-
-	if (ethtool_invalid_flags(dev, data, ETH_FLAG_LRO))
-		return -EINVAL;
-
-	if (data & ETH_FLAG_LRO) {
-		if (!(dev->features & NETIF_F_LRO)) {
-			dev->features |= NETIF_F_LRO;
-			changed = 1;
-		}
-	} else if (dev->features & NETIF_F_LRO) {
-		dev->features &= ~NETIF_F_LRO;
-		changed = 1;
-	}
+	u32 changed = (features ^ dev->features) & NETIF_F_LRO;
 
 	if (changed && netif_running(dev)) {
+		int rc;
+
 		s2io_stop_all_tx_queue(sp);
 		s2io_card_down(sp);
+		dev->features = features;
 		rc = s2io_card_up(sp);
 		if (rc)
 			s2io_reset(sp);
 		else
 			s2io_start_all_tx_queue(sp);
+
+		return rc ? rc : 1;
 	}
 
-	return rc;
+	return 0;
 }
 
 static const struct ethtool_ops netdev_ethtool_ops = {
@@ -6765,18 +6706,9 @@
 	.get_ringparam = s2io_ethtool_gringparam,
 	.get_pauseparam = s2io_ethtool_getpause_data,
 	.set_pauseparam = s2io_ethtool_setpause_data,
-	.get_rx_csum = s2io_ethtool_get_rx_csum,
-	.set_rx_csum = s2io_ethtool_set_rx_csum,
-	.set_tx_csum = s2io_ethtool_op_set_tx_csum,
-	.set_flags = s2io_ethtool_set_flags,
-	.get_flags = ethtool_op_get_flags,
-	.set_sg = ethtool_op_set_sg,
-	.get_tso = s2io_ethtool_op_get_tso,
-	.set_tso = s2io_ethtool_op_set_tso,
-	.set_ufo = ethtool_op_set_ufo,
 	.self_test = s2io_ethtool_test,
 	.get_strings = s2io_ethtool_get_strings,
-	.phys_id = s2io_ethtool_idnic,
+	.set_phys_id = s2io_ethtool_set_led,
 	.get_ethtool_stats = s2io_get_ethtool_stats,
 	.get_sset_count = s2io_get_sset_count,
 };
@@ -7231,7 +7163,7 @@
 		/* As per the HW requirement we need to replenish the
 		 * receive buffer to avoid the ring bump. Since there is
 		 * no intention of processing the Rx frame at this pointwe are
-		 * just settting the ownership bit of rxd in Each Rx
+		 * just setting the ownership bit of rxd in Each Rx
 		 * ring to HW and set the appropriate buffer size
 		 * based on the ring mode
 		 */
@@ -7545,7 +7477,7 @@
 	if ((rxdp->Control_1 & TCP_OR_UDP_FRAME) &&
 	    ((!ring_data->lro) ||
 	     (ring_data->lro && (!(rxdp->Control_1 & RXD_FRAME_IP_FRAG)))) &&
-	    (sp->rx_csum)) {
+	    (dev->features & NETIF_F_RXCSUM)) {
 		l3_csum = RXD_GET_L3_CKSUM(rxdp->Control_1);
 		l4_csum = RXD_GET_L4_CKSUM(rxdp->Control_1);
 		if ((l3_csum == L3_CKSUM_OK) && (l4_csum == L4_CKSUM_OK)) {
@@ -7806,6 +7738,7 @@
 	.ndo_do_ioctl	   	= s2io_ioctl,
 	.ndo_set_mac_address    = s2io_set_mac_addr,
 	.ndo_change_mtu	   	= s2io_change_mtu,
+	.ndo_set_features	= s2io_set_features,
 	.ndo_vlan_rx_register   = s2io_vlan_rx_register,
 	.ndo_vlan_rx_kill_vid   = s2io_vlan_rx_kill_vid,
 	.ndo_tx_timeout	   	= s2io_tx_watchdog,
@@ -8047,17 +7980,18 @@
 	/*  Driver entry points */
 	dev->netdev_ops = &s2io_netdev_ops;
 	SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops);
-	dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
-	dev->features |= NETIF_F_LRO;
-	dev->features |= NETIF_F_SG | NETIF_F_IP_CSUM;
+	dev->hw_features = NETIF_F_SG | NETIF_F_IP_CSUM |
+		NETIF_F_TSO | NETIF_F_TSO6 |
+		NETIF_F_RXCSUM | NETIF_F_LRO;
+	dev->features |= dev->hw_features |
+		NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
+	if (sp->device_type & XFRAME_II_DEVICE) {
+		dev->hw_features |= NETIF_F_UFO;
+		if (ufo)
+			dev->features |= NETIF_F_UFO;
+	}
 	if (sp->high_dma_flag == true)
 		dev->features |= NETIF_F_HIGHDMA;
-	dev->features |= NETIF_F_TSO;
-	dev->features |= NETIF_F_TSO6;
-	if ((sp->device_type & XFRAME_II_DEVICE) && (ufo))  {
-		dev->features |= NETIF_F_UFO;
-		dev->features |= NETIF_F_HW_CSUM;
-	}
 	dev->watchdog_timeo = WATCH_DOG_TIMEOUT;
 	INIT_WORK(&sp->rst_timer_task, s2io_restart_nic);
 	INIT_WORK(&sp->set_link_task, s2io_set_link);
diff -druN linux-2.6.39-libre/drivers/net/s2io.h linux-3.0-rc7-libre/drivers/net/s2io.h
--- linux-2.6.39-libre/drivers/net/s2io.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/s2io.h	2011-07-11 19:51:52.000000000 -0400
@@ -893,9 +893,6 @@
 	u16 all_multi_pos;
 	u16 promisc_flg;
 
-	/*  Id timer, used to blink NIC to physically identify NIC. */
-	struct timer_list id_timer;
-
 	/*  Restart timer, used to restart NIC if the device is stuck and
 	 *  a schedule task that will set the correct Link state once the
 	 *  NIC's PHY has stabilized after a state change.
@@ -1005,18 +1002,16 @@
 #define LF	2
 static inline void SPECIAL_REG_WRITE(u64 val, void __iomem *addr, int order)
 {
-	u32 ret;
-
 	if (order == LF) {
 		writel((u32) (val), addr);
-		ret = readl(addr);
+		(void) readl(addr);
 		writel((u32) (val >> 32), (addr + 4));
-		ret = readl(addr + 4);
+		(void) readl(addr + 4);
 	} else {
 		writel((u32) (val >> 32), (addr + 4));
-		ret = readl(addr + 4);
+		(void) readl(addr + 4);
 		writel((u32) (val), addr);
-		ret = readl(addr);
+		(void) readl(addr);
 	}
 }
 
diff -druN linux-2.6.39-libre/drivers/net/sb1250-mac.c linux-3.0-rc7-libre/drivers/net/sb1250-mac.c
--- linux-2.6.39-libre/drivers/net/sb1250-mac.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/sb1250-mac.c	2011-07-11 19:51:52.000000000 -0400
@@ -43,6 +43,7 @@
 #include <linux/mii.h>
 #include <linux/phy.h>
 #include <linux/platform_device.h>
+#include <linux/prefetch.h>
 
 #include <asm/cache.h>
 #include <asm/io.h>
diff -druN linux-2.6.39-libre/drivers/net/sc92031.c linux-3.0-rc7-libre/drivers/net/sc92031.c
--- linux-2.6.39-libre/drivers/net/sc92031.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/sc92031.c	2011-07-11 19:51:52.000000000 -0400
@@ -1173,7 +1173,8 @@
 	if (phy_ctrl & PhyCtrlAne)
 		cmd->advertising |= ADVERTISED_Autoneg;
 
-	cmd->speed = (output_status & 0x2) ? SPEED_100 : SPEED_10;
+	ethtool_cmd_speed_set(cmd,
+			      (output_status & 0x2) ? SPEED_100 : SPEED_10);
 	cmd->duplex = (output_status & 0x4) ? DUPLEX_FULL : DUPLEX_HALF;
 	cmd->port = PORT_MII;
 	cmd->phy_address = phy_address;
@@ -1188,10 +1189,11 @@
 {
 	struct sc92031_priv *priv = netdev_priv(dev);
 	void __iomem *port_base = priv->port_base;
+	u32 speed = ethtool_cmd_speed(cmd);
 	u32 phy_ctrl;
 	u32 old_phy_ctrl;
 
-	if (!(cmd->speed == SPEED_10 || cmd->speed == SPEED_100))
+	if (!(speed == SPEED_10 || speed == SPEED_100))
 		return -EINVAL;
 	if (!(cmd->duplex == DUPLEX_HALF || cmd->duplex == DUPLEX_FULL))
 		return -EINVAL;
@@ -1229,7 +1231,7 @@
 		// FIXME: Whole branch guessed
 		phy_ctrl = 0;
 
-		if (cmd->speed == SPEED_10)
+		if (speed == SPEED_10)
 			phy_ctrl |= PhyCtrlSpd10;
 		else /* cmd->speed == SPEED_100 */
 			phy_ctrl |= PhyCtrlSpd100;
diff -druN linux-2.6.39-libre/drivers/net/sfc/efx.c linux-3.0-rc7-libre/drivers/net/sfc/efx.c
--- linux-2.6.39-libre/drivers/net/sfc/efx.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/sfc/efx.c	2011-07-11 19:51:52.000000000 -0400
@@ -798,11 +798,6 @@
 	if (!netif_running(efx->net_dev))
 		return;
 
-	if (efx->port_inhibited) {
-		netif_carrier_off(efx->net_dev);
-		return;
-	}
-
 	if (link_state->up != netif_carrier_ok(efx->net_dev)) {
 		efx->n_link_state_changes++;
 
@@ -838,7 +833,7 @@
 	}
 }
 
-void efx_link_set_wanted_fc(struct efx_nic *efx, enum efx_fc_type wanted_fc)
+void efx_link_set_wanted_fc(struct efx_nic *efx, u8 wanted_fc)
 {
 	efx->wanted_fc = wanted_fc;
 	if (efx->link_advertising) {
@@ -1319,8 +1314,20 @@
 
 static void efx_set_channels(struct efx_nic *efx)
 {
+	struct efx_channel *channel;
+	struct efx_tx_queue *tx_queue;
+
 	efx->tx_channel_offset =
 		separate_tx_channels ? efx->n_channels - efx->n_tx_channels : 0;
+
+	/* We need to adjust the TX queue numbers if we have separate
+	 * RX-only and TX-only channels.
+	 */
+	efx_for_each_channel(channel, efx) {
+		efx_for_each_channel_tx_queue(tx_queue, channel)
+			tx_queue->queue -= (efx->tx_channel_offset *
+					    EFX_TXQ_TYPES);
+	}
 }
 
 static int efx_probe_nic(struct efx_nic *efx)
@@ -1438,7 +1445,7 @@
 	 * restart the transmit interface early so the watchdog timer stops */
 	efx_start_port(efx);
 
-	if (efx_dev_registered(efx) && !efx->port_inhibited)
+	if (efx_dev_registered(efx) && netif_device_present(efx->net_dev))
 		netif_tx_wake_all_queues(efx->net_dev);
 
 	efx_for_each_channel(channel, efx)
@@ -1876,6 +1883,17 @@
 	/* Otherwise efx_start_port() will do this */
 }
 
+static int efx_set_features(struct net_device *net_dev, u32 data)
+{
+	struct efx_nic *efx = netdev_priv(net_dev);
+
+	/* If disabling RX n-tuple filtering, clear existing filters */
+	if (net_dev->features & ~data & NETIF_F_NTUPLE)
+		efx_filter_clear_rx(efx, EFX_FILTER_PRI_MANUAL);
+
+	return 0;
+}
+
 static const struct net_device_ops efx_netdev_ops = {
 	.ndo_open		= efx_net_open,
 	.ndo_stop		= efx_net_stop,
@@ -1887,6 +1905,7 @@
 	.ndo_change_mtu		= efx_change_mtu,
 	.ndo_set_mac_address	= efx_set_mac_address,
 	.ndo_set_multicast_list = efx_set_multicast_list,
+	.ndo_set_features	= efx_set_features,
 #ifdef CONFIG_NET_POLL_CONTROLLER
 	.ndo_poll_controller = efx_netpoll,
 #endif
@@ -2090,6 +2109,7 @@
 	netif_info(efx, drv, efx->net_dev, "resetting (%s)\n",
 		   RESET_TYPE(method));
 
+	netif_device_detach(efx->net_dev);
 	efx_reset_down(efx, method);
 
 	rc = efx->type->reset(efx, method);
@@ -2123,6 +2143,7 @@
 		efx->state = STATE_DISABLED;
 	} else {
 		netif_dbg(efx, drv, efx->net_dev, "reset complete\n");
+		netif_device_attach(efx->net_dev);
 	}
 	return rc;
 }
@@ -2235,7 +2256,7 @@
 	return false;
 }
 
-static struct efx_phy_operations efx_dummy_phy_operations = {
+static const struct efx_phy_operations efx_dummy_phy_operations = {
 	.init		 = efx_port_dummy_op_int,
 	.reconfigure	 = efx_port_dummy_op_int,
 	.poll		 = efx_port_dummy_op_poll,
@@ -2251,7 +2272,7 @@
 /* This zeroes out and then fills in the invariants in a struct
  * efx_nic (including all sub-structures).
  */
-static int efx_init_struct(struct efx_nic *efx, struct efx_nic_type *type,
+static int efx_init_struct(struct efx_nic *efx, const struct efx_nic_type *type,
 			   struct pci_dev *pci_dev, struct net_device *net_dev)
 {
 	int i;
@@ -2271,7 +2292,6 @@
 	strlcpy(efx->name, pci_name(pci_dev), sizeof(efx->name));
 
 	efx->net_dev = net_dev;
-	efx->rx_checksum_enabled = true;
 	spin_lock_init(&efx->stats_lock);
 	mutex_init(&efx->mac_lock);
 	efx->mac_op = type->default_mac_ops;
@@ -2442,7 +2462,7 @@
 static int __devinit efx_pci_probe(struct pci_dev *pci_dev,
 				   const struct pci_device_id *entry)
 {
-	struct efx_nic_type *type = (struct efx_nic_type *) entry->driver_data;
+	const struct efx_nic_type *type = (const struct efx_nic_type *) entry->driver_data;
 	struct net_device *net_dev;
 	struct efx_nic *efx;
 	int i, rc;
@@ -2454,12 +2474,15 @@
 		return -ENOMEM;
 	net_dev->features |= (type->offload_features | NETIF_F_SG |
 			      NETIF_F_HIGHDMA | NETIF_F_TSO |
-			      NETIF_F_GRO);
+			      NETIF_F_RXCSUM);
 	if (type->offload_features & NETIF_F_V6_CSUM)
 		net_dev->features |= NETIF_F_TSO6;
 	/* Mask for features that also apply to VLAN devices */
 	net_dev->vlan_features |= (NETIF_F_ALL_CSUM | NETIF_F_SG |
-				   NETIF_F_HIGHDMA | NETIF_F_TSO);
+				   NETIF_F_HIGHDMA | NETIF_F_ALL_TSO |
+				   NETIF_F_RXCSUM);
+	/* All offloads can be toggled */
+	net_dev->hw_features = net_dev->features & ~NETIF_F_HIGHDMA;
 	efx = netdev_priv(net_dev);
 	pci_set_drvdata(pci_dev, efx);
 	SET_NETDEV_DEV(net_dev, &pci_dev->dev);
diff -druN linux-2.6.39-libre/drivers/net/sfc/efx.h linux-3.0-rc7-libre/drivers/net/sfc/efx.h
--- linux-2.6.39-libre/drivers/net/sfc/efx.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/sfc/efx.h	2011-07-11 19:51:52.000000000 -0400
@@ -142,6 +142,6 @@
 
 extern void efx_link_status_changed(struct efx_nic *efx);
 extern void efx_link_set_advertising(struct efx_nic *efx, u32);
-extern void efx_link_set_wanted_fc(struct efx_nic *efx, enum efx_fc_type);
+extern void efx_link_set_wanted_fc(struct efx_nic *efx, u8);
 
 #endif /* EFX_EFX_H */
diff -druN linux-2.6.39-libre/drivers/net/sfc/ethtool.c linux-3.0-rc7-libre/drivers/net/sfc/ethtool.c
--- linux-2.6.39-libre/drivers/net/sfc/ethtool.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/sfc/ethtool.c	2011-07-11 19:51:52.000000000 -0400
@@ -178,19 +178,27 @@
  */
 
 /* Identify device by flashing LEDs */
-static int efx_ethtool_phys_id(struct net_device *net_dev, u32 count)
+static int efx_ethtool_phys_id(struct net_device *net_dev,
+			       enum ethtool_phys_id_state state)
 {
 	struct efx_nic *efx = netdev_priv(net_dev);
+	enum efx_led_mode mode = EFX_LED_DEFAULT;
 
-	do {
-		efx->type->set_id_led(efx, EFX_LED_ON);
-		schedule_timeout_interruptible(HZ / 2);
-
-		efx->type->set_id_led(efx, EFX_LED_OFF);
-		schedule_timeout_interruptible(HZ / 2);
-	} while (!signal_pending(current) && --count != 0);
+	switch (state) {
+	case ETHTOOL_ID_ON:
+		mode = EFX_LED_ON;
+		break;
+	case ETHTOOL_ID_OFF:
+		mode = EFX_LED_OFF;
+		break;
+	case ETHTOOL_ID_INACTIVE:
+		mode = EFX_LED_DEFAULT;
+		break;
+	case ETHTOOL_ID_ACTIVE:
+		return 1;	/* cycle on/off once per second */
+	}
 
-	efx->type->set_id_led(efx, EFX_LED_DEFAULT);
+	efx->type->set_id_led(efx, mode);
 	return 0;
 }
 
@@ -211,7 +219,7 @@
 	ecmd->supported |= SUPPORTED_Pause | SUPPORTED_Asym_Pause;
 
 	if (LOOPBACK_INTERNAL(efx)) {
-		ecmd->speed = link_state->speed;
+		ethtool_cmd_speed_set(ecmd, link_state->speed);
 		ecmd->duplex = link_state->fd ? DUPLEX_FULL : DUPLEX_HALF;
 	}
 
@@ -226,7 +234,8 @@
 	int rc;
 
 	/* GMAC does not support 1000Mbps HD */
-	if (ecmd->speed == SPEED_1000 && ecmd->duplex != DUPLEX_FULL) {
+	if ((ethtool_cmd_speed(ecmd) == SPEED_1000) &&
+	    (ecmd->duplex != DUPLEX_FULL)) {
 		netif_dbg(efx, drv, efx->net_dev,
 			  "rejecting unsupported 1000Mbps HD setting\n");
 		return -EINVAL;
@@ -518,72 +527,6 @@
 	}
 }
 
-static int efx_ethtool_set_tso(struct net_device *net_dev, u32 enable)
-{
-	struct efx_nic *efx __attribute__ ((unused)) = netdev_priv(net_dev);
-	u32 features;
-
-	features = NETIF_F_TSO;
-	if (efx->type->offload_features & NETIF_F_V6_CSUM)
-		features |= NETIF_F_TSO6;
-
-	if (enable)
-		net_dev->features |= features;
-	else
-		net_dev->features &= ~features;
-
-	return 0;
-}
-
-static int efx_ethtool_set_tx_csum(struct net_device *net_dev, u32 enable)
-{
-	struct efx_nic *efx = netdev_priv(net_dev);
-	u32 features = efx->type->offload_features & NETIF_F_ALL_CSUM;
-
-	if (enable)
-		net_dev->features |= features;
-	else
-		net_dev->features &= ~features;
-
-	return 0;
-}
-
-static int efx_ethtool_set_rx_csum(struct net_device *net_dev, u32 enable)
-{
-	struct efx_nic *efx = netdev_priv(net_dev);
-
-	/* No way to stop the hardware doing the checks; we just
-	 * ignore the result.
-	 */
-	efx->rx_checksum_enabled = !!enable;
-
-	return 0;
-}
-
-static u32 efx_ethtool_get_rx_csum(struct net_device *net_dev)
-{
-	struct efx_nic *efx = netdev_priv(net_dev);
-
-	return efx->rx_checksum_enabled;
-}
-
-static int efx_ethtool_set_flags(struct net_device *net_dev, u32 data)
-{
-	struct efx_nic *efx = netdev_priv(net_dev);
-	u32 supported = (efx->type->offload_features &
-			 (ETH_FLAG_RXHASH | ETH_FLAG_NTUPLE));
-	int rc;
-
-	rc = ethtool_op_set_flags(net_dev, data, supported);
-	if (rc)
-		return rc;
-
-	if (!(data & ETH_FLAG_NTUPLE))
-		efx_filter_clear_rx(efx, EFX_FILTER_PRI_MANUAL);
-
-	return 0;
-}
-
 static void efx_ethtool_self_test(struct net_device *net_dev,
 				  struct ethtool_test *test, u64 *data)
 {
@@ -755,7 +698,7 @@
 				      struct ethtool_pauseparam *pause)
 {
 	struct efx_nic *efx = netdev_priv(net_dev);
-	enum efx_fc_type wanted_fc, old_fc;
+	u8 wanted_fc, old_fc;
 	u32 old_adv;
 	bool reset;
 	int rc = 0;
@@ -1012,8 +955,9 @@
 
 	if (ntuple->fs.action == ETHTOOL_RXNTUPLE_ACTION_CLEAR)
 		return efx_filter_remove_filter(efx, &filter);
-	else
-		return efx_filter_insert_filter(efx, &filter, true);
+
+	rc = efx_filter_insert_filter(efx, &filter, true);
+	return rc < 0 ? rc : 0;
 }
 
 static int efx_ethtool_get_rxfh_indir(struct net_device *net_dev,
@@ -1070,22 +1014,10 @@
 	.set_ringparam		= efx_ethtool_set_ringparam,
 	.get_pauseparam         = efx_ethtool_get_pauseparam,
 	.set_pauseparam         = efx_ethtool_set_pauseparam,
-	.get_rx_csum		= efx_ethtool_get_rx_csum,
-	.set_rx_csum		= efx_ethtool_set_rx_csum,
-	.get_tx_csum		= ethtool_op_get_tx_csum,
-	/* Need to enable/disable IPv6 too */
-	.set_tx_csum		= efx_ethtool_set_tx_csum,
-	.get_sg			= ethtool_op_get_sg,
-	.set_sg			= ethtool_op_set_sg,
-	.get_tso		= ethtool_op_get_tso,
-	/* Need to enable/disable TSO-IPv6 too */
-	.set_tso		= efx_ethtool_set_tso,
-	.get_flags		= ethtool_op_get_flags,
-	.set_flags		= efx_ethtool_set_flags,
 	.get_sset_count		= efx_ethtool_get_sset_count,
 	.self_test		= efx_ethtool_self_test,
 	.get_strings		= efx_ethtool_get_strings,
-	.phys_id		= efx_ethtool_phys_id,
+	.set_phys_id		= efx_ethtool_phys_id,
 	.get_ethtool_stats	= efx_ethtool_get_stats,
 	.get_wol                = efx_ethtool_get_wol,
 	.set_wol                = efx_ethtool_set_wol,
diff -druN linux-2.6.39-libre/drivers/net/sfc/falcon.c linux-3.0-rc7-libre/drivers/net/sfc/falcon.c
--- linux-2.6.39-libre/drivers/net/sfc/falcon.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/sfc/falcon.c	2011-07-11 19:51:52.000000000 -0400
@@ -1703,7 +1703,7 @@
  **************************************************************************
  */
 
-struct efx_nic_type falcon_a1_nic_type = {
+const struct efx_nic_type falcon_a1_nic_type = {
 	.probe = falcon_probe_nic,
 	.remove = falcon_remove_nic,
 	.init = falcon_init_nic,
@@ -1744,7 +1744,7 @@
 	.reset_world_flags = ETH_RESET_IRQ,
 };
 
-struct efx_nic_type falcon_b0_nic_type = {
+const struct efx_nic_type falcon_b0_nic_type = {
 	.probe = falcon_probe_nic,
 	.remove = falcon_remove_nic,
 	.init = falcon_init_nic,
diff -druN linux-2.6.39-libre/drivers/net/sfc/falcon_xmac.c linux-3.0-rc7-libre/drivers/net/sfc/falcon_xmac.c
--- linux-2.6.39-libre/drivers/net/sfc/falcon_xmac.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/sfc/falcon_xmac.c	2011-07-11 19:51:52.000000000 -0400
@@ -362,7 +362,7 @@
 	falcon_ack_status_intr(efx);
 }
 
-struct efx_mac_operations falcon_xmac_operations = {
+const struct efx_mac_operations falcon_xmac_operations = {
 	.reconfigure	= falcon_reconfigure_xmac,
 	.update_stats	= falcon_update_stats_xmac,
 	.check_fault	= falcon_xmac_check_fault,
diff -druN linux-2.6.39-libre/drivers/net/sfc/mac.h linux-3.0-rc7-libre/drivers/net/sfc/mac.h
--- linux-2.6.39-libre/drivers/net/sfc/mac.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/sfc/mac.h	2011-07-11 19:51:52.000000000 -0400
@@ -13,8 +13,8 @@
 
 #include "net_driver.h"
 
-extern struct efx_mac_operations falcon_xmac_operations;
-extern struct efx_mac_operations efx_mcdi_mac_operations;
+extern const struct efx_mac_operations falcon_xmac_operations;
+extern const struct efx_mac_operations efx_mcdi_mac_operations;
 extern int efx_mcdi_mac_stats(struct efx_nic *efx, dma_addr_t dma_addr,
 			      u32 dma_len, int enable, int clear);
 
diff -druN linux-2.6.39-libre/drivers/net/sfc/mcdi_mac.c linux-3.0-rc7-libre/drivers/net/sfc/mcdi_mac.c
--- linux-2.6.39-libre/drivers/net/sfc/mcdi_mac.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/sfc/mcdi_mac.c	2011-07-11 19:51:52.000000000 -0400
@@ -138,7 +138,7 @@
 }
 
 
-struct efx_mac_operations efx_mcdi_mac_operations = {
+const struct efx_mac_operations efx_mcdi_mac_operations = {
 	.reconfigure	= efx_mcdi_mac_reconfigure,
 	.update_stats	= efx_port_dummy_op_void,
 	.check_fault 	= efx_mcdi_mac_check_fault,
diff -druN linux-2.6.39-libre/drivers/net/sfc/mcdi_phy.c linux-3.0-rc7-libre/drivers/net/sfc/mcdi_phy.c
--- linux-2.6.39-libre/drivers/net/sfc/mcdi_phy.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/sfc/mcdi_phy.c	2011-07-11 19:51:52.000000000 -0400
@@ -513,7 +513,7 @@
 	ecmd->supported =
 		mcdi_to_ethtool_cap(phy_cfg->media, phy_cfg->supported_cap);
 	ecmd->advertising = efx->link_advertising;
-	ecmd->speed = efx->link_state.speed;
+	ethtool_cmd_speed_set(ecmd, efx->link_state.speed);
 	ecmd->duplex = efx->link_state.fd;
 	ecmd->port = mcdi_to_ethtool_media(phy_cfg->media);
 	ecmd->phy_address = phy_cfg->port;
@@ -545,7 +545,7 @@
 		caps = (ethtool_to_mcdi_cap(ecmd->advertising) |
 			 1 << MC_CMD_PHY_CAP_AN_LBN);
 	} else if (ecmd->duplex) {
-		switch (ecmd->speed) {
+		switch (ethtool_cmd_speed(ecmd)) {
 		case 10:    caps = 1 << MC_CMD_PHY_CAP_10FDX_LBN;    break;
 		case 100:   caps = 1 << MC_CMD_PHY_CAP_100FDX_LBN;   break;
 		case 1000:  caps = 1 << MC_CMD_PHY_CAP_1000FDX_LBN;  break;
@@ -553,7 +553,7 @@
 		default:    return -EINVAL;
 		}
 	} else {
-		switch (ecmd->speed) {
+		switch (ethtool_cmd_speed(ecmd)) {
 		case 10:    caps = 1 << MC_CMD_PHY_CAP_10HDX_LBN;    break;
 		case 100:   caps = 1 << MC_CMD_PHY_CAP_100HDX_LBN;   break;
 		case 1000:  caps = 1 << MC_CMD_PHY_CAP_1000HDX_LBN;  break;
@@ -739,7 +739,7 @@
 	return NULL;
 }
 
-struct efx_phy_operations efx_mcdi_phy_ops = {
+const struct efx_phy_operations efx_mcdi_phy_ops = {
 	.probe		= efx_mcdi_phy_probe,
 	.init 	 	= efx_port_dummy_op_int,
 	.reconfigure	= efx_mcdi_phy_reconfigure,
diff -druN linux-2.6.39-libre/drivers/net/sfc/mdio_10g.c linux-3.0-rc7-libre/drivers/net/sfc/mdio_10g.c
--- linux-2.6.39-libre/drivers/net/sfc/mdio_10g.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/sfc/mdio_10g.c	2011-07-11 19:51:52.000000000 -0400
@@ -232,12 +232,12 @@
  */
 int efx_mdio_set_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd)
 {
-	struct ethtool_cmd prev;
+	struct ethtool_cmd prev = { .cmd = ETHTOOL_GSET };
 
 	efx->phy_op->get_settings(efx, &prev);
 
 	if (ecmd->advertising == prev.advertising &&
-	    ecmd->speed == prev.speed &&
+	    ethtool_cmd_speed(ecmd) == ethtool_cmd_speed(&prev) &&
 	    ecmd->duplex == prev.duplex &&
 	    ecmd->port == prev.port &&
 	    ecmd->autoneg == prev.autoneg)
@@ -284,7 +284,7 @@
 	efx_mdio_write(efx, MDIO_MMD_AN, MDIO_CTRL1, reg);
 }
 
-enum efx_fc_type efx_mdio_get_pause(struct efx_nic *efx)
+u8 efx_mdio_get_pause(struct efx_nic *efx)
 {
 	BUILD_BUG_ON(EFX_FC_AUTO & (EFX_FC_RX | EFX_FC_TX));
 
diff -druN linux-2.6.39-libre/drivers/net/sfc/mdio_10g.h linux-3.0-rc7-libre/drivers/net/sfc/mdio_10g.h
--- linux-2.6.39-libre/drivers/net/sfc/mdio_10g.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/sfc/mdio_10g.h	2011-07-11 19:51:52.000000000 -0400
@@ -92,7 +92,7 @@
 /* Get pause parameters from AN if available (otherwise return
  * requested pause parameters)
  */
-enum efx_fc_type efx_mdio_get_pause(struct efx_nic *efx);
+u8 efx_mdio_get_pause(struct efx_nic *efx);
 
 /* Wait for specified MMDs to exit reset within a timeout */
 extern int efx_mdio_wait_reset_mmds(struct efx_nic *efx,
diff -druN linux-2.6.39-libre/drivers/net/sfc/mtd.c linux-3.0-rc7-libre/drivers/net/sfc/mtd.c
--- linux-2.6.39-libre/drivers/net/sfc/mtd.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/sfc/mtd.c	2011-07-11 19:51:52.000000000 -0400
@@ -216,7 +216,7 @@
 	int rc;
 
 	for (;;) {
-		rc = del_mtd_device(&part->mtd);
+		rc = mtd_device_unregister(&part->mtd);
 		if (rc != -EBUSY)
 			break;
 		ssleep(1);
@@ -268,7 +268,7 @@
 		part->mtd.write = efx_mtd->ops->write;
 		part->mtd.sync = efx_mtd_sync;
 
-		if (add_mtd_device(&part->mtd))
+		if (mtd_device_register(&part->mtd, NULL, 0))
 			goto fail;
 	}
 
@@ -280,7 +280,7 @@
 		--part;
 		efx_mtd_remove_partition(part);
 	}
-	/* add_mtd_device() returns 1 if the MTD table is full */
+	/* mtd_device_register() returns 1 if the MTD table is full */
 	return -ENOMEM;
 }
 
diff -druN linux-2.6.39-libre/drivers/net/sfc/net_driver.h linux-3.0-rc7-libre/drivers/net/sfc/net_driver.h
--- linux-2.6.39-libre/drivers/net/sfc/net_driver.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/sfc/net_driver.h	2011-07-11 19:51:52.000000000 -0400
@@ -449,11 +449,9 @@
 struct efx_nic;
 
 /* Pseudo bit-mask flow control field */
-enum efx_fc_type {
-	EFX_FC_RX = FLOW_CTRL_RX,
-	EFX_FC_TX = FLOW_CTRL_TX,
-	EFX_FC_AUTO = 4,
-};
+#define EFX_FC_RX	FLOW_CTRL_RX
+#define EFX_FC_TX	FLOW_CTRL_TX
+#define EFX_FC_AUTO	4
 
 /**
  * struct efx_link_state - Current state of the link
@@ -465,7 +463,7 @@
 struct efx_link_state {
 	bool up;
 	bool fd;
-	enum efx_fc_type fc;
+	u8 fc;
 	unsigned int speed;
 };
 
@@ -670,16 +668,14 @@
  * @mtd_list: List of MTDs attached to the NIC
  * @nic_data: Hardware dependent state
  * @mac_lock: MAC access lock. Protects @port_enabled, @phy_mode,
- *	@port_inhibited, efx_monitor() and efx_reconfigure_port()
+ *	efx_monitor() and efx_reconfigure_port()
  * @port_enabled: Port enabled indicator.
  *	Serialises efx_stop_all(), efx_start_all(), efx_monitor() and
  *	efx_mac_work() with kernel interfaces. Safe to read under any
  *	one of the rtnl_lock, mac_lock, or netif_tx_lock, but all three must
  *	be held to modify it.
- * @port_inhibited: If set, the netif_carrier is always off. Hold the mac_lock
  * @port_initialized: Port initialized?
  * @net_dev: Operating system network device. Consider holding the rtnl lock
- * @rx_checksum_enabled: RX checksumming enabled
  * @stats_buffer: DMA buffer for statistics
  * @mac_op: MAC interface
  * @phy_type: PHY type
@@ -765,18 +761,16 @@
 	struct mutex mac_lock;
 	struct work_struct mac_work;
 	bool port_enabled;
-	bool port_inhibited;
 
 	bool port_initialized;
 	struct net_device *net_dev;
-	bool rx_checksum_enabled;
 
 	struct efx_buffer stats_buffer;
 
-	struct efx_mac_operations *mac_op;
+	const struct efx_mac_operations *mac_op;
 
 	unsigned int phy_type;
-	struct efx_phy_operations *phy_op;
+	const struct efx_phy_operations *phy_op;
 	void *phy_data;
 	struct mdio_if_info mdio;
 	unsigned int mdio_bus;
@@ -788,7 +782,7 @@
 
 	bool promiscuous;
 	union efx_multicast_hash multicast_hash;
-	enum efx_fc_type wanted_fc;
+	u8 wanted_fc;
 
 	atomic_t rx_reset;
 	enum efx_loopback_mode loopback_mode;
@@ -897,7 +891,7 @@
 	void (*resume_wol)(struct efx_nic *efx);
 	int (*test_registers)(struct efx_nic *efx);
 	int (*test_nvram)(struct efx_nic *efx);
-	struct efx_mac_operations *default_mac_ops;
+	const struct efx_mac_operations *default_mac_ops;
 
 	int revision;
 	unsigned int mem_map_size;
diff -druN linux-2.6.39-libre/drivers/net/sfc/nic.c linux-3.0-rc7-libre/drivers/net/sfc/nic.c
--- linux-2.6.39-libre/drivers/net/sfc/nic.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/sfc/nic.c	2011-07-11 19:51:52.000000000 -0400
@@ -852,7 +852,6 @@
 	unsigned expected_ptr;
 	bool rx_ev_pkt_ok, discard = false, checksummed;
 	struct efx_rx_queue *rx_queue;
-	struct efx_nic *efx = channel->efx;
 
 	/* Basic packet information */
 	rx_ev_byte_cnt = EFX_QWORD_FIELD(*event, FSF_AZ_RX_EV_BYTE_CNT);
@@ -875,9 +874,8 @@
 		 * UDP/IP, then we can rely on the hardware checksum.
 		 */
 		checksummed =
-			likely(efx->rx_checksum_enabled) &&
-			(rx_ev_hdr_type == FSE_CZ_RX_EV_HDR_TYPE_IPV4V6_TCP ||
-			 rx_ev_hdr_type == FSE_CZ_RX_EV_HDR_TYPE_IPV4V6_UDP);
+			rx_ev_hdr_type == FSE_CZ_RX_EV_HDR_TYPE_IPV4V6_TCP ||
+			rx_ev_hdr_type == FSE_CZ_RX_EV_HDR_TYPE_IPV4V6_UDP;
 	} else {
 		efx_handle_rx_not_ok(rx_queue, event, &rx_ev_pkt_ok, &discard);
 		checksummed = false;
diff -druN linux-2.6.39-libre/drivers/net/sfc/nic.h linux-3.0-rc7-libre/drivers/net/sfc/nic.h
--- linux-2.6.39-libre/drivers/net/sfc/nic.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/sfc/nic.h	2011-07-11 19:51:52.000000000 -0400
@@ -152,9 +152,9 @@
 	int wol_filter_id;
 };
 
-extern struct efx_nic_type falcon_a1_nic_type;
-extern struct efx_nic_type falcon_b0_nic_type;
-extern struct efx_nic_type siena_a0_nic_type;
+extern const struct efx_nic_type falcon_a1_nic_type;
+extern const struct efx_nic_type falcon_b0_nic_type;
+extern const struct efx_nic_type siena_a0_nic_type;
 
 /**************************************************************************
  *
diff -druN linux-2.6.39-libre/drivers/net/sfc/phy.h linux-3.0-rc7-libre/drivers/net/sfc/phy.h
--- linux-2.6.39-libre/drivers/net/sfc/phy.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/sfc/phy.h	2011-07-11 19:51:52.000000000 -0400
@@ -13,14 +13,14 @@
 /****************************************************************************
  * 10Xpress (SFX7101) PHY
  */
-extern struct efx_phy_operations falcon_sfx7101_phy_ops;
+extern const struct efx_phy_operations falcon_sfx7101_phy_ops;
 
 extern void tenxpress_set_id_led(struct efx_nic *efx, enum efx_led_mode mode);
 
 /****************************************************************************
  * AMCC/Quake QT202x PHYs
  */
-extern struct efx_phy_operations falcon_qt202x_phy_ops;
+extern const struct efx_phy_operations falcon_qt202x_phy_ops;
 
 /* These PHYs provide various H/W control states for LEDs */
 #define QUAKE_LED_LINK_INVAL	(0)
@@ -39,7 +39,7 @@
 /****************************************************************************
 * Transwitch CX4 retimer
 */
-extern struct efx_phy_operations falcon_txc_phy_ops;
+extern const struct efx_phy_operations falcon_txc_phy_ops;
 
 #define TXC_GPIO_DIR_INPUT	0
 #define TXC_GPIO_DIR_OUTPUT	1
@@ -50,7 +50,7 @@
 /****************************************************************************
  * Siena managed PHYs
  */
-extern struct efx_phy_operations efx_mcdi_phy_ops;
+extern const struct efx_phy_operations efx_mcdi_phy_ops;
 
 extern int efx_mcdi_mdio_read(struct efx_nic *efx, unsigned int bus,
 			      unsigned int prtad, unsigned int devad,
diff -druN linux-2.6.39-libre/drivers/net/sfc/qt202x_phy.c linux-3.0-rc7-libre/drivers/net/sfc/qt202x_phy.c
--- linux-2.6.39-libre/drivers/net/sfc/qt202x_phy.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/sfc/qt202x_phy.c	2011-07-11 19:51:52.000000000 -0400
@@ -449,7 +449,7 @@
 	efx->phy_data = NULL;
 }
 
-struct efx_phy_operations falcon_qt202x_phy_ops = {
+const struct efx_phy_operations falcon_qt202x_phy_ops = {
 	.probe		 = qt202x_phy_probe,
 	.init		 = qt202x_phy_init,
 	.reconfigure	 = qt202x_phy_reconfigure,
diff -druN linux-2.6.39-libre/drivers/net/sfc/rx.c linux-3.0-rc7-libre/drivers/net/sfc/rx.c
--- linux-2.6.39-libre/drivers/net/sfc/rx.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/sfc/rx.c	2011-07-11 19:51:52.000000000 -0400
@@ -14,6 +14,7 @@
 #include <linux/ip.h>
 #include <linux/tcp.h>
 #include <linux/udp.h>
+#include <linux/prefetch.h>
 #include <net/ip.h>
 #include <net/checksum.h>
 #include "net_driver.h"
@@ -605,6 +606,9 @@
 		skb_record_rx_queue(skb, channel->channel);
 	}
 
+	if (unlikely(!(efx->net_dev->features & NETIF_F_RXCSUM)))
+		checksummed = false;
+
 	if (likely(checksummed || rx_buf->is_page)) {
 		efx_rx_packet_gro(channel, rx_buf, eh, checksummed);
 		return;
diff -druN linux-2.6.39-libre/drivers/net/sfc/selftest.c linux-3.0-rc7-libre/drivers/net/sfc/selftest.c
--- linux-2.6.39-libre/drivers/net/sfc/selftest.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/sfc/selftest.c	2011-07-11 19:51:52.000000000 -0400
@@ -695,12 +695,12 @@
 	/* Offline (i.e. disruptive) testing
 	 * This checks MAC and PHY loopback on the specified port. */
 
-	/* force the carrier state off so the kernel doesn't transmit during
-	 * the loopback test, and the watchdog timeout doesn't fire. Also put
-	 * falcon into loopback for the register test.
+	/* Detach the device so the kernel doesn't transmit during the
+	 * loopback test and the watchdog timeout doesn't fire.
 	 */
+	netif_device_detach(efx->net_dev);
+
 	mutex_lock(&efx->mac_lock);
-	efx->port_inhibited = true;
 	if (efx->loopback_modes) {
 		/* We need the 312 clock from the PHY to test the XMAC
 		 * registers, so move into XGMII loopback if available */
@@ -750,12 +750,11 @@
 	/* restore the PHY to the previous state */
 	mutex_lock(&efx->mac_lock);
 	efx->phy_mode = phy_mode;
-	efx->port_inhibited = false;
 	efx->loopback_mode = loopback_mode;
 	__efx_reconfigure_port(efx);
 	mutex_unlock(&efx->mac_lock);
 
-	netif_tx_wake_all_queues(efx->net_dev);
+	netif_device_attach(efx->net_dev);
 
 	return rc_test;
 }
diff -druN linux-2.6.39-libre/drivers/net/sfc/siena.c linux-3.0-rc7-libre/drivers/net/sfc/siena.c
--- linux-2.6.39-libre/drivers/net/sfc/siena.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/sfc/siena.c	2011-07-11 19:51:52.000000000 -0400
@@ -599,7 +599,7 @@
  **************************************************************************
  */
 
-struct efx_nic_type siena_a0_nic_type = {
+const struct efx_nic_type siena_a0_nic_type = {
 	.probe = siena_probe_nic,
 	.remove = siena_remove_nic,
 	.init = siena_init_nic,
diff -druN linux-2.6.39-libre/drivers/net/sfc/tenxpress.c linux-3.0-rc7-libre/drivers/net/sfc/tenxpress.c
--- linux-2.6.39-libre/drivers/net/sfc/tenxpress.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/sfc/tenxpress.c	2011-07-11 19:51:52.000000000 -0400
@@ -460,7 +460,7 @@
 	/* In loopback, the PHY automatically brings up the correct interface,
 	 * but doesn't advertise the correct speed. So override it */
 	if (LOOPBACK_EXTERNAL(efx))
-		ecmd->speed = SPEED_10000;
+		ethtool_cmd_speed_set(ecmd, SPEED_10000);
 }
 
 static int tenxpress_set_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd)
@@ -478,7 +478,7 @@
 			  advertising & ADVERTISED_10000baseT_Full);
 }
 
-struct efx_phy_operations falcon_sfx7101_phy_ops = {
+const struct efx_phy_operations falcon_sfx7101_phy_ops = {
 	.probe		  = tenxpress_phy_probe,
 	.init             = tenxpress_phy_init,
 	.reconfigure      = tenxpress_phy_reconfigure,
diff -druN linux-2.6.39-libre/drivers/net/sfc/tx.c linux-3.0-rc7-libre/drivers/net/sfc/tx.c
--- linux-2.6.39-libre/drivers/net/sfc/tx.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/sfc/tx.c	2011-07-11 19:51:52.000000000 -0400
@@ -205,7 +205,9 @@
 					goto unwind;
 				}
 				smp_mb();
-				netif_tx_start_queue(tx_queue->core_txq);
+				if (likely(!efx->loopback_selftest))
+					netif_tx_start_queue(
+						tx_queue->core_txq);
 			}
 
 			insert_ptr = tx_queue->insert_count & tx_queue->ptr_mask;
@@ -338,8 +340,7 @@
 	struct efx_tx_queue *tx_queue;
 	unsigned index, type;
 
-	if (unlikely(efx->port_inhibited))
-		return NETDEV_TX_BUSY;
+	EFX_WARN_ON_PARANOID(!netif_device_present(net_dev));
 
 	index = skb_get_queue_mapping(skb);
 	type = skb->ip_summed == CHECKSUM_PARTIAL ? EFX_TXQ_TYPE_OFFLOAD : 0;
@@ -436,7 +437,7 @@
 	smp_mb();
 	if (unlikely(netif_tx_queue_stopped(tx_queue->core_txq)) &&
 	    likely(efx->port_enabled) &&
-	    likely(!efx->port_inhibited)) {
+	    likely(netif_device_present(efx->net_dev))) {
 		fill_level = tx_queue->insert_count - tx_queue->read_count;
 		if (fill_level < EFX_TXQ_THRESHOLD(efx)) {
 			EFX_BUG_ON_PARANOID(!efx_dev_registered(efx));
diff -druN linux-2.6.39-libre/drivers/net/sfc/txc43128_phy.c linux-3.0-rc7-libre/drivers/net/sfc/txc43128_phy.c
--- linux-2.6.39-libre/drivers/net/sfc/txc43128_phy.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/sfc/txc43128_phy.c	2011-07-11 19:51:52.000000000 -0400
@@ -545,7 +545,7 @@
 	mdio45_ethtool_gset(&efx->mdio, ecmd);
 }
 
-struct efx_phy_operations falcon_txc_phy_ops = {
+const struct efx_phy_operations falcon_txc_phy_ops = {
 	.probe		= txc43128_phy_probe,
 	.init		= txc43128_phy_init,
 	.reconfigure	= txc43128_phy_reconfigure,
diff -druN linux-2.6.39-libre/drivers/net/sgiseeq.c linux-3.0-rc7-libre/drivers/net/sgiseeq.c
--- linux-2.6.39-libre/drivers/net/sgiseeq.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/sgiseeq.c	2011-07-11 19:51:52.000000000 -0400
@@ -1,7 +1,7 @@
 /*
  * sgiseeq.c: Seeq8003 ethernet driver for SGI machines.
  *
- * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
+ * Copyright (C) 1996 David S. Miller (davem@davemloft.net)
  */
 
 #undef DEBUG
diff -druN linux-2.6.39-libre/drivers/net/sgiseeq.h linux-3.0-rc7-libre/drivers/net/sgiseeq.h
--- linux-2.6.39-libre/drivers/net/sgiseeq.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/sgiseeq.h	2011-07-11 19:51:52.000000000 -0400
@@ -1,7 +1,7 @@
 /*
  * sgiseeq.h: Defines for the Seeq8003 ethernet controller.
  *
- * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
+ * Copyright (C) 1996 David S. Miller (davem@davemloft.net)
  */
 #ifndef _SGISEEQ_H
 #define _SGISEEQ_H
diff -druN linux-2.6.39-libre/drivers/net/sh_eth.c linux-3.0-rc7-libre/drivers/net/sh_eth.c
--- linux-2.6.39-libre/drivers/net/sh_eth.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/sh_eth.c	2011-07-11 19:51:52.000000000 -0400
@@ -140,6 +140,8 @@
 	.tpauser	= 1,
 	.hw_swap	= 1,
 	.no_ade		= 1,
+	.rpadir		= 1,
+	.rpadir_value   = 2 << 16,
 };
 
 #define SH_GIGA_ETH_BASE	0xfee00000
@@ -1184,8 +1186,8 @@
 				mdp->cd->set_rate(ndev);
 		}
 		if (mdp->link == PHY_DOWN) {
-			sh_eth_write(ndev, (sh_eth_read(ndev, ECMR) & ~ECMR_TXF)
-					| ECMR_DM, ECMR);
+			sh_eth_write(ndev,
+				(sh_eth_read(ndev, ECMR) & ~ECMR_TXF), ECMR);
 			new_state = 1;
 			mdp->link = phydev->link;
 		}
diff -druN linux-2.6.39-libre/drivers/net/skge.c linux-3.0-rc7-libre/drivers/net/skge.c
--- linux-2.6.39-libre/drivers/net/skge.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/skge.c	2011-07-11 19:51:52.000000000 -0400
@@ -44,6 +44,7 @@
 #include <linux/mii.h>
 #include <linux/slab.h>
 #include <linux/dmi.h>
+#include <linux/prefetch.h>
 #include <asm/irq.h>
 
 #include "skge.h"
@@ -303,7 +304,7 @@
 
 	ecmd->advertising = skge->advertising;
 	ecmd->autoneg = skge->autoneg;
-	ecmd->speed = skge->speed;
+	ethtool_cmd_speed_set(ecmd, skge->speed);
 	ecmd->duplex = skge->duplex;
 	return 0;
 }
@@ -321,8 +322,9 @@
 		skge->speed = -1;
 	} else {
 		u32 setting;
+		u32 speed = ethtool_cmd_speed(ecmd);
 
-		switch (ecmd->speed) {
+		switch (speed) {
 		case SPEED_1000:
 			if (ecmd->duplex == DUPLEX_FULL)
 				setting = SUPPORTED_1000baseT_Full;
@@ -355,7 +357,7 @@
 		if ((setting & supported) == 0)
 			return -EINVAL;
 
-		skge->speed = ecmd->speed;
+		skge->speed = speed;
 		skge->duplex = ecmd->duplex;
 	}
 
@@ -537,46 +539,6 @@
 	return 0;
 }
 
-static int skge_set_sg(struct net_device *dev, u32 data)
-{
-	struct skge_port *skge = netdev_priv(dev);
-	struct skge_hw *hw = skge->hw;
-
-	if (hw->chip_id == CHIP_ID_GENESIS && data)
-		return -EOPNOTSUPP;
-	return ethtool_op_set_sg(dev, data);
-}
-
-static int skge_set_tx_csum(struct net_device *dev, u32 data)
-{
-	struct skge_port *skge = netdev_priv(dev);
-	struct skge_hw *hw = skge->hw;
-
-	if (hw->chip_id == CHIP_ID_GENESIS && data)
-		return -EOPNOTSUPP;
-
-	return ethtool_op_set_tx_csum(dev, data);
-}
-
-static u32 skge_get_rx_csum(struct net_device *dev)
-{
-	struct skge_port *skge = netdev_priv(dev);
-
-	return skge->rx_csum;
-}
-
-/* Only Yukon supports checksum offload. */
-static int skge_set_rx_csum(struct net_device *dev, u32 data)
-{
-	struct skge_port *skge = netdev_priv(dev);
-
-	if (skge->hw->chip_id == CHIP_ID_GENESIS && data)
-		return -EOPNOTSUPP;
-
-	skge->rx_csum = data;
-	return 0;
-}
-
 static void skge_get_pauseparam(struct net_device *dev,
 				struct ethtool_pauseparam *ecmd)
 {
@@ -786,28 +748,27 @@
 }
 
 /* blink LED's for finding board */
-static int skge_phys_id(struct net_device *dev, u32 data)
+static int skge_set_phys_id(struct net_device *dev,
+			    enum ethtool_phys_id_state state)
 {
 	struct skge_port *skge = netdev_priv(dev);
-	unsigned long ms;
-	enum led_mode mode = LED_MODE_TST;
 
-	if (!data || data > (u32)(MAX_SCHEDULE_TIMEOUT / HZ))
-		ms = jiffies_to_msecs(MAX_SCHEDULE_TIMEOUT / HZ) * 1000;
-	else
-		ms = data * 1000;
+	switch (state) {
+	case ETHTOOL_ID_ACTIVE:
+		return 2;	/* cycle on/off twice per second */
 
-	while (ms > 0) {
-		skge_led(skge, mode);
-		mode ^= LED_MODE_TST;
+	case ETHTOOL_ID_ON:
+		skge_led(skge, LED_MODE_TST);
+		break;
 
-		if (msleep_interruptible(BLINK_MS))
-			break;
-		ms -= BLINK_MS;
-	}
+	case ETHTOOL_ID_OFF:
+		skge_led(skge, LED_MODE_OFF);
+		break;
 
-	/* back to regular LED state */
-	skge_led(skge, netif_running(dev) ? LED_MODE_ON : LED_MODE_OFF);
+	case ETHTOOL_ID_INACTIVE:
+		/* back to regular LED state */
+		skge_led(skge, netif_running(dev) ? LED_MODE_ON : LED_MODE_OFF);
+	}
 
 	return 0;
 }
@@ -925,12 +886,8 @@
 	.set_pauseparam = skge_set_pauseparam,
 	.get_coalesce	= skge_get_coalesce,
 	.set_coalesce	= skge_set_coalesce,
-	.set_sg		= skge_set_sg,
-	.set_tx_csum	= skge_set_tx_csum,
-	.get_rx_csum	= skge_get_rx_csum,
-	.set_rx_csum	= skge_set_rx_csum,
 	.get_strings	= skge_get_strings,
-	.phys_id	= skge_phys_id,
+	.set_phys_id	= skge_set_phys_id,
 	.get_sset_count = skge_get_sset_count,
 	.get_ethtool_stats = skge_get_ethtool_stats,
 };
@@ -3085,7 +3042,8 @@
 	}
 
 	skb_put(skb, len);
-	if (skge->rx_csum) {
+
+	if (dev->features & NETIF_F_RXCSUM) {
 		skb->csum = csum;
 		skb->ip_summed = CHECKSUM_COMPLETE;
 	}
@@ -3847,10 +3805,10 @@
 	setup_timer(&skge->link_timer, xm_link_timer, (unsigned long) skge);
 
 	if (hw->chip_id != CHIP_ID_GENESIS) {
-		dev->features |= NETIF_F_IP_CSUM | NETIF_F_SG;
-		skge->rx_csum = 1;
+		dev->hw_features = NETIF_F_IP_CSUM | NETIF_F_SG |
+		                   NETIF_F_RXCSUM;
+		dev->features |= dev->hw_features;
 	}
-	dev->features |= NETIF_F_GRO;
 
 	/* read the mac address */
 	memcpy_fromio(dev->dev_addr, hw->regs + B2_MAC_1 + port*8, ETH_ALEN);
diff -druN linux-2.6.39-libre/drivers/net/skge.h linux-3.0-rc7-libre/drivers/net/skge.h
--- linux-2.6.39-libre/drivers/net/skge.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/skge.h	2011-07-11 19:51:52.000000000 -0400
@@ -2460,7 +2460,6 @@
 	struct timer_list    link_timer;
 	enum pause_control   flow_control;
 	enum pause_status    flow_status;
-	u8		     rx_csum;
 	u8		     blink_on;
 	u8		     wol;
 	u8		     autoneg;	/* AUTONEG_ENABLE, AUTONEG_DISABLE */
diff -druN linux-2.6.39-libre/drivers/net/sky2.c linux-3.0-rc7-libre/drivers/net/sky2.c
--- linux-2.6.39-libre/drivers/net/sky2.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/sky2.c	2011-07-11 19:51:52.000000000 -0400
@@ -1198,12 +1198,12 @@
 
 	sky2_write32(sky2->hw,
 		     Q_ADDR(rxqaddr[sky2->port], Q_CSR),
-		     (sky2->flags & SKY2_FLAG_RX_CHECKSUM)
+		     (sky2->netdev->features & NETIF_F_RXCSUM)
 		     ? BMU_ENA_RX_CHKSUM : BMU_DIS_RX_CHKSUM);
 }
 
 /* Enable/disable receive hash calculation (RSS) */
-static void rx_set_rss(struct net_device *dev)
+static void rx_set_rss(struct net_device *dev, u32 features)
 {
 	struct sky2_port *sky2 = netdev_priv(dev);
 	struct sky2_hw *hw = sky2->hw;
@@ -1216,7 +1216,7 @@
 	}
 
 	/* Program RSS initial values */
-	if (dev->features & NETIF_F_RXHASH) {
+	if (features & NETIF_F_RXHASH) {
 		u32 key[nkeys];
 
 		get_random_bytes(key, nkeys * sizeof(u32));
@@ -1322,32 +1322,32 @@
 	return err;
 }
 
-#define NETIF_F_ALL_VLAN (NETIF_F_HW_VLAN_TX|NETIF_F_HW_VLAN_RX)
+#define SKY2_VLAN_OFFLOADS (NETIF_F_IP_CSUM | NETIF_F_SG | NETIF_F_TSO)
 
-static void sky2_vlan_mode(struct net_device *dev)
+static void sky2_vlan_mode(struct net_device *dev, u32 features)
 {
 	struct sky2_port *sky2 = netdev_priv(dev);
 	struct sky2_hw *hw = sky2->hw;
 	u16 port = sky2->port;
 
-	if (dev->features & NETIF_F_HW_VLAN_RX)
+	if (features & NETIF_F_HW_VLAN_RX)
 		sky2_write32(hw, SK_REG(port, RX_GMF_CTRL_T),
 			     RX_VLAN_STRIP_ON);
 	else
 		sky2_write32(hw, SK_REG(port, RX_GMF_CTRL_T),
 			     RX_VLAN_STRIP_OFF);
 
-	dev->vlan_features = dev->features &~ NETIF_F_ALL_VLAN;
-	if (dev->features & NETIF_F_HW_VLAN_TX)
+	if (features & NETIF_F_HW_VLAN_TX) {
 		sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T),
 			     TX_VLAN_TAG_ON);
-	else {
+
+		dev->vlan_features |= SKY2_VLAN_OFFLOADS;
+	} else {
 		sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T),
 			     TX_VLAN_TAG_OFF);
 
 		/* Can't do transmit offload of vlan without hw vlan */
-		dev->vlan_features &= ~(NETIF_F_TSO | NETIF_F_SG
-					| NETIF_F_ALL_CSUM);
+		dev->vlan_features &= ~SKY2_VLAN_OFFLOADS;
 	}
 }
 
@@ -1463,7 +1463,7 @@
 		rx_set_checksum(sky2);
 
 	if (!(hw->flags & SKY2_HW_RSS_BROKEN))
-		rx_set_rss(sky2->netdev);
+		rx_set_rss(sky2->netdev, sky2->netdev->features);
 
 	/* submit Rx ring */
 	for (i = 0; i < sky2->rx_pending; i++) {
@@ -1626,7 +1626,8 @@
 	sky2_prefetch_init(hw, txqaddr[port], sky2->tx_le_map,
 			   sky2->tx_ring_size - 1);
 
-	sky2_vlan_mode(sky2->netdev);
+	sky2_vlan_mode(sky2->netdev, sky2->netdev->features);
+	netdev_update_features(sky2->netdev);
 
 	sky2_rx_start(sky2);
 }
@@ -2261,12 +2262,9 @@
 	     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;
+		netdev_update_features(dev);
 		return 0;
 	}
 
@@ -2288,6 +2286,7 @@
 	sky2_rx_clean(sky2);
 
 	dev->mtu = new_mtu;
+	netdev_update_features(dev);
 
 	mode = DATA_BLIND_VAL(DATA_BLIND_DEF) |
 		GM_SMOD_VLAN_ENA | IPG_DATA_VAL(IPG_DATA_DEF);
@@ -2535,8 +2534,11 @@
 			   "%s: receive checksum problem (status = %#x)\n",
 			   sky2->netdev->name, status);
 
-		/* Disable checksum offload */
-		sky2->flags &= ~SKY2_FLAG_RX_CHECKSUM;
+		/* Disable checksum offload
+		 * It will be reenabled on next ndo_set_features, but if it's
+		 * really broken, will get disabled again
+		 */
+		sky2->netdev->features &= ~NETIF_F_RXCSUM;
 		sky2_write32(sky2->hw, Q_ADDR(rxqaddr[sky2->port], Q_CSR),
 			     BMU_DIS_RX_CHKSUM);
 	}
@@ -2591,7 +2593,7 @@
 
 			/* This chip reports checksum status differently */
 			if (hw->flags & SKY2_HW_NEW_LE) {
-				if ((sky2->flags & SKY2_FLAG_RX_CHECKSUM) &&
+				if ((dev->features & NETIF_F_RXCSUM) &&
 				    (le->css & (CSS_ISIPV4 | CSS_ISIPV6)) &&
 				    (le->css & CSS_TCPUDPCSOK))
 					skb->ip_summed = CHECKSUM_UNNECESSARY;
@@ -2616,7 +2618,7 @@
 			sky2->rx_tag = length;
 			/* fall through */
 		case OP_RXCHKS:
-			if (likely(sky2->flags & SKY2_FLAG_RX_CHECKSUM))
+			if (likely(dev->features & NETIF_F_RXCSUM))
 				sky2_rx_checksum(sky2, status);
 			break;
 
@@ -3411,10 +3413,10 @@
 	ecmd->phy_address = PHY_ADDR_MARV;
 	if (sky2_is_copper(hw)) {
 		ecmd->port = PORT_TP;
-		ecmd->speed = sky2->speed;
+		ethtool_cmd_speed_set(ecmd, sky2->speed);
 		ecmd->supported |=  SUPPORTED_Autoneg | SUPPORTED_TP;
 	} else {
-		ecmd->speed = SPEED_1000;
+		ethtool_cmd_speed_set(ecmd, SPEED_1000);
 		ecmd->port = PORT_FIBRE;
 		ecmd->supported |=  SUPPORTED_Autoneg | SUPPORTED_FIBRE;
 	}
@@ -3450,8 +3452,9 @@
 		sky2->speed = -1;
 	} else {
 		u32 setting;
+		u32 speed = ethtool_cmd_speed(ecmd);
 
-		switch (ecmd->speed) {
+		switch (speed) {
 		case SPEED_1000:
 			if (ecmd->duplex == DUPLEX_FULL)
 				setting = SUPPORTED_1000baseT_Full;
@@ -3484,7 +3487,7 @@
 		if ((setting & supported) == 0)
 			return -EINVAL;
 
-		sky2->speed = ecmd->speed;
+		sky2->speed = speed;
 		sky2->duplex = ecmd->duplex;
 		sky2->flags &= ~SKY2_FLAG_AUTO_SPEED;
 	}
@@ -3552,28 +3555,6 @@
 	{ "tx_fifo_underrun", GM_TXE_FIFO_UR },
 };
 
-static u32 sky2_get_rx_csum(struct net_device *dev)
-{
-	struct sky2_port *sky2 = netdev_priv(dev);
-
-	return !!(sky2->flags & SKY2_FLAG_RX_CHECKSUM);
-}
-
-static int sky2_set_rx_csum(struct net_device *dev, u32 data)
-{
-	struct sky2_port *sky2 = netdev_priv(dev);
-
-	if (data)
-		sky2->flags |= SKY2_FLAG_RX_CHECKSUM;
-	else
-		sky2->flags &= ~SKY2_FLAG_RX_CHECKSUM;
-
-	sky2_write32(sky2->hw, Q_ADDR(rxqaddr[sky2->port], Q_CSR),
-		     data ? BMU_ENA_RX_CHKSUM : BMU_DIS_RX_CHKSUM);
-
-	return 0;
-}
-
 static u32 sky2_get_msglevel(struct net_device *netdev)
 {
 	struct sky2_port *sky2 = netdev_priv(netdev);
@@ -3826,23 +3807,24 @@
 }
 
 /* blink LED's for finding board */
-static int sky2_phys_id(struct net_device *dev, u32 data)
+static int sky2_set_phys_id(struct net_device *dev,
+			    enum ethtool_phys_id_state state)
 {
 	struct sky2_port *sky2 = netdev_priv(dev);
-	unsigned int i;
-
-	if (data == 0)
-		data = UINT_MAX;
 
-	for (i = 0; i < data; i++) {
+	switch (state) {
+	case ETHTOOL_ID_ACTIVE:
+		return 1;	/* cycle on/off once per second */
+	case ETHTOOL_ID_INACTIVE:
+		sky2_led(sky2, MO_LED_NORM);
+		break;
+	case ETHTOOL_ID_ON:
 		sky2_led(sky2, MO_LED_ON);
-		if (msleep_interruptible(500))
-			break;
+		break;
+	case ETHTOOL_ID_OFF:
 		sky2_led(sky2, MO_LED_OFF);
-		if (msleep_interruptible(500))
-			break;
+		break;
 	}
-	sky2_led(sky2, MO_LED_NORM);
 
 	return 0;
 }
@@ -4083,34 +4065,6 @@
 	}
 }
 
-/* In order to do Jumbo packets on these chips, need to turn off the
- * transmit store/forward. Therefore checksum offload won't work.
- */
-static int no_tx_offload(struct net_device *dev)
-{
-	const struct sky2_port *sky2 = netdev_priv(dev);
-	const struct sky2_hw *hw = sky2->hw;
-
-	return dev->mtu > ETH_DATA_LEN && hw->chip_id == CHIP_ID_YUKON_EC_U;
-}
-
-static int sky2_set_tx_csum(struct net_device *dev, u32 data)
-{
-	if (data && no_tx_offload(dev))
-		return -EINVAL;
-
-	return ethtool_op_set_tx_csum(dev, data);
-}
-
-
-static int sky2_set_tso(struct net_device *dev, u32 data)
-{
-	if (data && no_tx_offload(dev))
-		return -EINVAL;
-
-	return ethtool_op_set_tso(dev, data);
-}
-
 static int sky2_get_eeprom_len(struct net_device *dev)
 {
 	struct sky2_port *sky2 = netdev_priv(dev);
@@ -4213,31 +4167,36 @@
 	return sky2_vpd_write(sky2->hw, cap, data, eeprom->offset, eeprom->len);
 }
 
-static int sky2_set_flags(struct net_device *dev, u32 data)
+static u32 sky2_fix_features(struct net_device *dev, u32 features)
 {
-	struct sky2_port *sky2 = netdev_priv(dev);
-	unsigned long old_feat = dev->features;
-	u32 supported = 0;
-	int rc;
+	const struct sky2_port *sky2 = netdev_priv(dev);
+	const struct sky2_hw *hw = sky2->hw;
 
-	if (!(sky2->hw->flags & SKY2_HW_RSS_BROKEN))
-		supported |= ETH_FLAG_RXHASH;
+	/* In order to do Jumbo packets on these chips, need to turn off the
+	 * transmit store/forward. Therefore checksum offload won't work.
+	 */
+	if (dev->mtu > ETH_DATA_LEN && hw->chip_id == CHIP_ID_YUKON_EC_U)
+		features &= ~(NETIF_F_TSO|NETIF_F_SG|NETIF_F_ALL_CSUM);
 
-	if (!(sky2->hw->flags & SKY2_HW_VLAN_BROKEN))
-		supported |= ETH_FLAG_RXVLAN | ETH_FLAG_TXVLAN;
+	return features;
+}
 
-	printk(KERN_DEBUG "sky2 set_flags: supported %x data %x\n",
-	       supported, data);
+static int sky2_set_features(struct net_device *dev, u32 features)
+{
+	struct sky2_port *sky2 = netdev_priv(dev);
+	u32 changed = dev->features ^ features;
 
-	rc = ethtool_op_set_flags(dev, data, supported);
-	if (rc)
-		return rc;
+	if (changed & NETIF_F_RXCSUM) {
+		u32 on = features & NETIF_F_RXCSUM;
+		sky2_write32(sky2->hw, Q_ADDR(rxqaddr[sky2->port], Q_CSR),
+			     on ? BMU_ENA_RX_CHKSUM : BMU_DIS_RX_CHKSUM);
+	}
 
-	if ((old_feat ^ dev->features) & NETIF_F_RXHASH)
-		rx_set_rss(dev);
+	if (changed & NETIF_F_RXHASH)
+		rx_set_rss(dev, features);
 
-	if ((old_feat ^ dev->features) & NETIF_F_ALL_VLAN)
-		sky2_vlan_mode(dev);
+	if (changed & (NETIF_F_HW_VLAN_TX|NETIF_F_HW_VLAN_RX))
+		sky2_vlan_mode(dev, features);
 
 	return 0;
 }
@@ -4257,11 +4216,6 @@
 	.get_eeprom_len	= sky2_get_eeprom_len,
 	.get_eeprom	= sky2_get_eeprom,
 	.set_eeprom	= sky2_set_eeprom,
-	.set_sg 	= ethtool_op_set_sg,
-	.set_tx_csum	= sky2_set_tx_csum,
-	.set_tso	= sky2_set_tso,
-	.get_rx_csum	= sky2_get_rx_csum,
-	.set_rx_csum	= sky2_set_rx_csum,
 	.get_strings	= sky2_get_strings,
 	.get_coalesce	= sky2_get_coalesce,
 	.set_coalesce	= sky2_set_coalesce,
@@ -4269,11 +4223,9 @@
 	.set_ringparam	= sky2_set_ringparam,
 	.get_pauseparam = sky2_get_pauseparam,
 	.set_pauseparam = sky2_set_pauseparam,
-	.phys_id	= sky2_phys_id,
+	.set_phys_id	= sky2_set_phys_id,
 	.get_sset_count = sky2_get_sset_count,
 	.get_ethtool_stats = sky2_get_ethtool_stats,
-	.set_flags	= sky2_set_flags,
-	.get_flags	= ethtool_op_get_flags,
 };
 
 #ifdef CONFIG_SKY2_DEBUG
@@ -4553,6 +4505,8 @@
 	.ndo_set_mac_address	= sky2_set_mac_address,
 	.ndo_set_multicast_list	= sky2_set_multicast,
 	.ndo_change_mtu		= sky2_change_mtu,
+	.ndo_fix_features	= sky2_fix_features,
+	.ndo_set_features	= sky2_set_features,
 	.ndo_tx_timeout		= sky2_tx_timeout,
 	.ndo_get_stats64	= sky2_get_stats,
 #ifdef CONFIG_NET_POLL_CONTROLLER
@@ -4568,6 +4522,8 @@
 	.ndo_set_mac_address	= sky2_set_mac_address,
 	.ndo_set_multicast_list	= sky2_set_multicast,
 	.ndo_change_mtu		= sky2_change_mtu,
+	.ndo_fix_features	= sky2_fix_features,
+	.ndo_set_features	= sky2_set_features,
 	.ndo_tx_timeout		= sky2_tx_timeout,
 	.ndo_get_stats64	= sky2_get_stats,
   },
@@ -4600,7 +4556,7 @@
 	/* Auto speed and flow control */
 	sky2->flags = SKY2_FLAG_AUTO_SPEED | SKY2_FLAG_AUTO_PAUSE;
 	if (hw->chip_id != CHIP_ID_YUKON_XL)
-		sky2->flags |= SKY2_FLAG_RX_CHECKSUM;
+		dev->hw_features |= NETIF_F_RXCSUM;
 
 	sky2->flow_mode = FC_BOTH;
 
@@ -4619,18 +4575,21 @@
 
 	sky2->port = port;
 
-	dev->features |= NETIF_F_IP_CSUM | NETIF_F_SG
-		| NETIF_F_TSO | NETIF_F_GRO;
+	dev->hw_features |= NETIF_F_IP_CSUM | NETIF_F_SG | NETIF_F_TSO;
 
 	if (highmem)
 		dev->features |= NETIF_F_HIGHDMA;
 
 	/* Enable receive hashing unless hardware is known broken */
 	if (!(hw->flags & SKY2_HW_RSS_BROKEN))
-		dev->features |= NETIF_F_RXHASH;
+		dev->hw_features |= NETIF_F_RXHASH;
 
-	if (!(hw->flags & SKY2_HW_VLAN_BROKEN))
-		dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
+	if (!(hw->flags & SKY2_HW_VLAN_BROKEN)) {
+		dev->hw_features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
+		dev->vlan_features |= SKY2_VLAN_OFFLOADS;
+	}
+
+	dev->features |= dev->hw_features;
 
 	/* read the mac address */
 	memcpy_fromio(dev->dev_addr, hw->regs + B2_MAC_1 + port * 8, ETH_ALEN);
diff -druN linux-2.6.39-libre/drivers/net/sky2.h linux-3.0-rc7-libre/drivers/net/sky2.h
--- linux-2.6.39-libre/drivers/net/sky2.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/sky2.h	2011-07-11 19:51:52.000000000 -0400
@@ -2254,7 +2254,6 @@
 	u8		     wol;		/* WAKE_ bits */
 	u8		     duplex;		/* DUPLEX_HALF, DUPLEX_FULL */
 	u16		     flags;
-#define SKY2_FLAG_RX_CHECKSUM		0x0001
 #define SKY2_FLAG_AUTO_SPEED		0x0002
 #define SKY2_FLAG_AUTO_PAUSE		0x0004
 
diff -druN linux-2.6.39-libre/drivers/net/smc911x.c linux-3.0-rc7-libre/drivers/net/smc911x.c
--- linux-2.6.39-libre/drivers/net/smc911x.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/smc911x.c	2011-07-11 19:51:52.000000000 -0400
@@ -1488,9 +1488,9 @@
 				SUPPORTED_TP | SUPPORTED_AUI;
 
 		if (lp->ctl_rspeed == 10)
-			cmd->speed = SPEED_10;
+			ethtool_cmd_speed_set(cmd, SPEED_10);
 		else if (lp->ctl_rspeed == 100)
-			cmd->speed = SPEED_100;
+			ethtool_cmd_speed_set(cmd, SPEED_100);
 
 		cmd->autoneg = AUTONEG_DISABLE;
 		if (lp->mii.phy_id==1)
diff -druN linux-2.6.39-libre/drivers/net/smc91x.c linux-3.0-rc7-libre/drivers/net/smc91x.c
--- linux-2.6.39-libre/drivers/net/smc91x.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/smc91x.c	2011-07-11 19:51:52.000000000 -0400
@@ -1565,9 +1565,9 @@
 				 SUPPORTED_TP | SUPPORTED_AUI;
 
 		if (lp->ctl_rspeed == 10)
-			cmd->speed = SPEED_10;
+			ethtool_cmd_speed_set(cmd, SPEED_10);
 		else if (lp->ctl_rspeed == 100)
-			cmd->speed = SPEED_100;
+			ethtool_cmd_speed_set(cmd, SPEED_100);
 
 		cmd->autoneg = AUTONEG_DISABLE;
 		cmd->transceiver = XCVR_INTERNAL;
@@ -2400,8 +2400,10 @@
 	{ .compatible = "smsc,lan91c94", },
 	{ .compatible = "smsc,lan91c111", },
 	{},
-}
+};
 MODULE_DEVICE_TABLE(of, smc91x_match);
+#else
+#define smc91x_match NULL
 #endif
 
 static struct dev_pm_ops smc_drv_pm_ops = {
@@ -2416,9 +2418,7 @@
 		.name	= CARDNAME,
 		.owner	= THIS_MODULE,
 		.pm	= &smc_drv_pm_ops,
-#ifdef CONFIG_OF
 		.of_match_table = smc91x_match,
-#endif
 	},
 };
 
diff -druN linux-2.6.39-libre/drivers/net/smsc911x.c linux-3.0-rc7-libre/drivers/net/smsc911x.c
--- linux-2.6.39-libre/drivers/net/smsc911x.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/smsc911x.c	2011-07-11 19:51:52.000000000 -0400
@@ -29,6 +29,8 @@
  *
  */
 
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/crc32.h>
 #include <linux/delay.h>
 #include <linux/errno.h>
@@ -69,6 +71,17 @@
 module_param(debug, int, 0);
 MODULE_PARM_DESC(debug, "Debug level (0=none,...,16=all)");
 
+struct smsc911x_data;
+
+struct smsc911x_ops {
+	u32 (*reg_read)(struct smsc911x_data *pdata, u32 reg);
+	void (*reg_write)(struct smsc911x_data *pdata, u32 reg, u32 val);
+	void (*rx_readfifo)(struct smsc911x_data *pdata,
+				unsigned int *buf, unsigned int wordcount);
+	void (*tx_writefifo)(struct smsc911x_data *pdata,
+				unsigned int *buf, unsigned int wordcount);
+};
+
 struct smsc911x_data {
 	void __iomem *ioaddr;
 
@@ -116,8 +129,14 @@
 	unsigned int clear_bits_mask;
 	unsigned int hashhi;
 	unsigned int hashlo;
+
+	/* register access functions */
+	const struct smsc911x_ops *ops;
 };
 
+/* Easy access to information */
+#define __smsc_shift(pdata, reg) ((reg) << ((pdata)->config.shift))
+
 static inline u32 __smsc911x_reg_read(struct smsc911x_data *pdata, u32 reg)
 {
 	if (pdata->config.flags & SMSC911X_USE_32BIT)
@@ -131,13 +150,29 @@
 	return 0;
 }
 
+static inline u32
+__smsc911x_reg_read_shift(struct smsc911x_data *pdata, u32 reg)
+{
+	if (pdata->config.flags & SMSC911X_USE_32BIT)
+		return readl(pdata->ioaddr + __smsc_shift(pdata, reg));
+
+	if (pdata->config.flags & SMSC911X_USE_16BIT)
+		return (readw(pdata->ioaddr +
+				__smsc_shift(pdata, reg)) & 0xFFFF) |
+			((readw(pdata->ioaddr +
+			__smsc_shift(pdata, reg + 2)) & 0xFFFF) << 16);
+
+	BUG();
+	return 0;
+}
+
 static inline u32 smsc911x_reg_read(struct smsc911x_data *pdata, u32 reg)
 {
 	u32 data;
 	unsigned long flags;
 
 	spin_lock_irqsave(&pdata->dev_lock, flags);
-	data = __smsc911x_reg_read(pdata, reg);
+	data = pdata->ops->reg_read(pdata, reg);
 	spin_unlock_irqrestore(&pdata->dev_lock, flags);
 
 	return data;
@@ -160,13 +195,32 @@
 	BUG();
 }
 
+static inline void
+__smsc911x_reg_write_shift(struct smsc911x_data *pdata, u32 reg, u32 val)
+{
+	if (pdata->config.flags & SMSC911X_USE_32BIT) {
+		writel(val, pdata->ioaddr + __smsc_shift(pdata, reg));
+		return;
+	}
+
+	if (pdata->config.flags & SMSC911X_USE_16BIT) {
+		writew(val & 0xFFFF,
+			pdata->ioaddr + __smsc_shift(pdata, reg));
+		writew((val >> 16) & 0xFFFF,
+			pdata->ioaddr + __smsc_shift(pdata, reg + 2));
+		return;
+	}
+
+	BUG();
+}
+
 static inline void smsc911x_reg_write(struct smsc911x_data *pdata, u32 reg,
 				      u32 val)
 {
 	unsigned long flags;
 
 	spin_lock_irqsave(&pdata->dev_lock, flags);
-	__smsc911x_reg_write(pdata, reg, val);
+	pdata->ops->reg_write(pdata, reg, val);
 	spin_unlock_irqrestore(&pdata->dev_lock, flags);
 }
 
@@ -202,6 +256,40 @@
 	spin_unlock_irqrestore(&pdata->dev_lock, flags);
 }
 
+/* Writes a packet to the TX_DATA_FIFO - shifted version */
+static inline void
+smsc911x_tx_writefifo_shift(struct smsc911x_data *pdata, unsigned int *buf,
+		      unsigned int wordcount)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&pdata->dev_lock, flags);
+
+	if (pdata->config.flags & SMSC911X_SWAP_FIFO) {
+		while (wordcount--)
+			__smsc911x_reg_write_shift(pdata, TX_DATA_FIFO,
+					     swab32(*buf++));
+		goto out;
+	}
+
+	if (pdata->config.flags & SMSC911X_USE_32BIT) {
+		writesl(pdata->ioaddr + __smsc_shift(pdata,
+						TX_DATA_FIFO), buf, wordcount);
+		goto out;
+	}
+
+	if (pdata->config.flags & SMSC911X_USE_16BIT) {
+		while (wordcount--)
+			__smsc911x_reg_write_shift(pdata,
+						 TX_DATA_FIFO, *buf++);
+		goto out;
+	}
+
+	BUG();
+out:
+	spin_unlock_irqrestore(&pdata->dev_lock, flags);
+}
+
 /* Reads a packet out of the RX_DATA_FIFO */
 static inline void
 smsc911x_rx_readfifo(struct smsc911x_data *pdata, unsigned int *buf,
@@ -234,6 +322,40 @@
 	spin_unlock_irqrestore(&pdata->dev_lock, flags);
 }
 
+/* Reads a packet out of the RX_DATA_FIFO - shifted version */
+static inline void
+smsc911x_rx_readfifo_shift(struct smsc911x_data *pdata, unsigned int *buf,
+		     unsigned int wordcount)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&pdata->dev_lock, flags);
+
+	if (pdata->config.flags & SMSC911X_SWAP_FIFO) {
+		while (wordcount--)
+			*buf++ = swab32(__smsc911x_reg_read_shift(pdata,
+							    RX_DATA_FIFO));
+		goto out;
+	}
+
+	if (pdata->config.flags & SMSC911X_USE_32BIT) {
+		readsl(pdata->ioaddr + __smsc_shift(pdata,
+						RX_DATA_FIFO), buf, wordcount);
+		goto out;
+	}
+
+	if (pdata->config.flags & SMSC911X_USE_16BIT) {
+		while (wordcount--)
+			*buf++ = __smsc911x_reg_read_shift(pdata,
+								RX_DATA_FIFO);
+		goto out;
+	}
+
+	BUG();
+out:
+	spin_unlock_irqrestore(&pdata->dev_lock, flags);
+}
+
 /* waits for MAC not busy, with timeout.  Only called by smsc911x_mac_read
  * and smsc911x_mac_write, so assumes mac_lock is held */
 static int smsc911x_mac_complete(struct smsc911x_data *pdata)
@@ -248,8 +370,8 @@
 		if (!(val & MAC_CSR_CMD_CSR_BUSY_))
 			return 0;
 	}
-	SMSC_WARNING(HW, "Timed out waiting for MAC not BUSY. "
-		"MAC_CSR_CMD: 0x%08X", val);
+	SMSC_WARN(pdata, hw, "Timed out waiting for MAC not BUSY. "
+		  "MAC_CSR_CMD: 0x%08X", val);
 	return -EIO;
 }
 
@@ -262,7 +384,7 @@
 
 	temp = smsc911x_reg_read(pdata, MAC_CSR_CMD);
 	if (unlikely(temp & MAC_CSR_CMD_CSR_BUSY_)) {
-		SMSC_WARNING(HW, "MAC busy at entry");
+		SMSC_WARN(pdata, hw, "MAC busy at entry");
 		return 0xFFFFFFFF;
 	}
 
@@ -277,7 +399,7 @@
 	if (likely(smsc911x_mac_complete(pdata) == 0))
 		return smsc911x_reg_read(pdata, MAC_CSR_DATA);
 
-	SMSC_WARNING(HW, "MAC busy after read");
+	SMSC_WARN(pdata, hw, "MAC busy after read");
 	return 0xFFFFFFFF;
 }
 
@@ -291,8 +413,8 @@
 
 	temp = smsc911x_reg_read(pdata, MAC_CSR_CMD);
 	if (unlikely(temp & MAC_CSR_CMD_CSR_BUSY_)) {
-		SMSC_WARNING(HW,
-			"smsc911x_mac_write failed, MAC busy at entry");
+		SMSC_WARN(pdata, hw,
+			  "smsc911x_mac_write failed, MAC busy at entry");
 		return;
 	}
 
@@ -310,8 +432,7 @@
 	if (likely(smsc911x_mac_complete(pdata) == 0))
 		return;
 
-	SMSC_WARNING(HW,
-		"smsc911x_mac_write failed, MAC busy after write");
+	SMSC_WARN(pdata, hw, "smsc911x_mac_write failed, MAC busy after write");
 }
 
 /* Get a phy register */
@@ -326,8 +447,7 @@
 
 	/* Confirm MII not busy */
 	if (unlikely(smsc911x_mac_read(pdata, MII_ACC) & MII_ACC_MII_BUSY_)) {
-		SMSC_WARNING(HW,
-			"MII is busy in smsc911x_mii_read???");
+		SMSC_WARN(pdata, hw, "MII is busy in smsc911x_mii_read???");
 		reg = -EIO;
 		goto out;
 	}
@@ -343,7 +463,7 @@
 			goto out;
 		}
 
-	SMSC_WARNING(HW, "Timed out waiting for MII read to finish");
+	SMSC_WARN(pdata, hw, "Timed out waiting for MII read to finish");
 	reg = -EIO;
 
 out:
@@ -364,8 +484,7 @@
 
 	/* Confirm MII not busy */
 	if (unlikely(smsc911x_mac_read(pdata, MII_ACC) & MII_ACC_MII_BUSY_)) {
-		SMSC_WARNING(HW,
-			"MII is busy in smsc911x_mii_write???");
+		SMSC_WARN(pdata, hw, "MII is busy in smsc911x_mii_write???");
 		reg = -EIO;
 		goto out;
 	}
@@ -385,7 +504,7 @@
 			goto out;
 		}
 
-	SMSC_WARNING(HW, "Timed out waiting for MII write to finish");
+	SMSC_WARN(pdata, hw, "Timed out waiting for MII write to finish");
 	reg = -EIO;
 
 out:
@@ -426,18 +545,20 @@
 	unsigned int hwcfg = smsc911x_reg_read(pdata, HW_CFG);
 
 	if (pdata->config.flags & SMSC911X_FORCE_INTERNAL_PHY) {
-		SMSC_TRACE(HW, "Forcing internal PHY");
+		SMSC_TRACE(pdata, hw, "Forcing internal PHY");
 		pdata->using_extphy = 0;
 	} else if (pdata->config.flags & SMSC911X_FORCE_EXTERNAL_PHY) {
-		SMSC_TRACE(HW, "Forcing external PHY");
+		SMSC_TRACE(pdata, hw, "Forcing external PHY");
 		smsc911x_phy_enable_external(pdata);
 		pdata->using_extphy = 1;
 	} else if (hwcfg & HW_CFG_EXT_PHY_DET_) {
-		SMSC_TRACE(HW, "HW_CFG EXT_PHY_DET set, using external PHY");
+		SMSC_TRACE(pdata, hw,
+			   "HW_CFG EXT_PHY_DET set, using external PHY");
 		smsc911x_phy_enable_external(pdata);
 		pdata->using_extphy = 1;
 	} else {
-		SMSC_TRACE(HW, "HW_CFG EXT_PHY_DET clear, using internal PHY");
+		SMSC_TRACE(pdata, hw,
+			   "HW_CFG EXT_PHY_DET clear, using internal PHY");
 		pdata->using_extphy = 0;
 	}
 }
@@ -499,7 +620,7 @@
 		wrsz += (u32)((ulong)pdata->loopback_tx_pkt & 0x3);
 		wrsz >>= 2;
 
-		smsc911x_tx_writefifo(pdata, (unsigned int *)bufp, wrsz);
+		pdata->ops->tx_writefifo(pdata, (unsigned int *)bufp, wrsz);
 
 		/* Wait till transmit is done */
 		i = 60;
@@ -509,13 +630,13 @@
 		} while ((i--) && (!status));
 
 		if (!status) {
-			SMSC_WARNING(HW, "Failed to transmit "
-				"during loopback test");
+			SMSC_WARN(pdata, hw,
+				  "Failed to transmit during loopback test");
 			continue;
 		}
 		if (status & TX_STS_ES_) {
-			SMSC_WARNING(HW, "Transmit encountered "
-				"errors during loopback test");
+			SMSC_WARN(pdata, hw,
+				  "Transmit encountered errors during loopback test");
 			continue;
 		}
 
@@ -527,13 +648,13 @@
 		} while ((i--) && (!status));
 
 		if (!status) {
-			SMSC_WARNING(HW,
-				"Failed to receive during loopback test");
+			SMSC_WARN(pdata, hw,
+				  "Failed to receive during loopback test");
 			continue;
 		}
 		if (status & RX_STS_ES_) {
-			SMSC_WARNING(HW, "Receive encountered "
-				"errors during loopback test");
+			SMSC_WARN(pdata, hw,
+				  "Receive encountered errors during loopback test");
 			continue;
 		}
 
@@ -543,12 +664,12 @@
 		rdsz += (u32)((ulong)pdata->loopback_rx_pkt & 0x3);
 		rdsz >>= 2;
 
-		smsc911x_rx_readfifo(pdata, (unsigned int *)bufp, rdsz);
+		pdata->ops->rx_readfifo(pdata, (unsigned int *)bufp, rdsz);
 
 		if (pktlength != (MIN_PACKET_SIZE + 4)) {
-			SMSC_WARNING(HW, "Unexpected packet size "
-				"during loop back test, size=%d, will retry",
-				pktlength);
+			SMSC_WARN(pdata, hw, "Unexpected packet size "
+				  "during loop back test, size=%d, will retry",
+				  pktlength);
 		} else {
 			unsigned int j;
 			int mismatch = 0;
@@ -560,12 +681,12 @@
 				}
 			}
 			if (!mismatch) {
-				SMSC_TRACE(HW, "Successfully verified "
+				SMSC_TRACE(pdata, hw, "Successfully verified "
 					   "loopback packet");
 				return 0;
 			} else {
-				SMSC_WARNING(HW, "Data mismatch "
-					"during loop back test, will retry");
+				SMSC_WARN(pdata, hw, "Data mismatch "
+					  "during loop back test, will retry");
 			}
 		}
 	}
@@ -582,7 +703,7 @@
 	BUG_ON(!phy_dev);
 	BUG_ON(!phy_dev->bus);
 
-	SMSC_TRACE(HW, "Performing PHY BCR Reset");
+	SMSC_TRACE(pdata, hw, "Performing PHY BCR Reset");
 	smsc911x_mii_write(phy_dev->bus, phy_dev->addr, MII_BMCR, BMCR_RESET);
 	do {
 		msleep(1);
@@ -591,7 +712,7 @@
 	} while ((i--) && (temp & BMCR_RESET));
 
 	if (temp & BMCR_RESET) {
-		SMSC_WARNING(HW, "PHY reset failed to complete.");
+		SMSC_WARN(pdata, hw, "PHY reset failed to complete");
 		return -EIO;
 	}
 	/* Extra delay required because the phy may not be completed with
@@ -695,11 +816,11 @@
 		else
 			afc &= ~0xF;
 
-		SMSC_TRACE(HW, "rx pause %s, tx pause %s",
-			(cap & FLOW_CTRL_RX ? "enabled" : "disabled"),
-			(cap & FLOW_CTRL_TX ? "enabled" : "disabled"));
+		SMSC_TRACE(pdata, hw, "rx pause %s, tx pause %s",
+			   (cap & FLOW_CTRL_RX ? "enabled" : "disabled"),
+			   (cap & FLOW_CTRL_TX ? "enabled" : "disabled"));
 	} else {
-		SMSC_TRACE(HW, "half duplex");
+		SMSC_TRACE(pdata, hw, "half duplex");
 		flow = 0;
 		afc |= 0xF;
 	}
@@ -722,17 +843,17 @@
 
 	if (phy_dev->duplex != pdata->last_duplex) {
 		unsigned int mac_cr;
-		SMSC_TRACE(HW, "duplex state has changed");
+		SMSC_TRACE(pdata, hw, "duplex state has changed");
 
 		spin_lock_irqsave(&pdata->mac_lock, flags);
 		mac_cr = smsc911x_mac_read(pdata, MAC_CR);
 		if (phy_dev->duplex) {
-			SMSC_TRACE(HW,
-				"configuring for full duplex mode");
+			SMSC_TRACE(pdata, hw,
+				   "configuring for full duplex mode");
 			mac_cr |= MAC_CR_FDPX_;
 		} else {
-			SMSC_TRACE(HW,
-				"configuring for half duplex mode");
+			SMSC_TRACE(pdata, hw,
+				   "configuring for half duplex mode");
 			mac_cr &= ~MAC_CR_FDPX_;
 		}
 		smsc911x_mac_write(pdata, MAC_CR, mac_cr);
@@ -744,9 +865,9 @@
 
 	carrier = netif_carrier_ok(dev);
 	if (carrier != pdata->last_carrier) {
-		SMSC_TRACE(HW, "carrier state has changed");
+		SMSC_TRACE(pdata, hw, "carrier state has changed");
 		if (carrier) {
-			SMSC_TRACE(HW, "configuring for carrier OK");
+			SMSC_TRACE(pdata, hw, "configuring for carrier OK");
 			if ((pdata->gpio_orig_setting & GPIO_CFG_LED1_EN_) &&
 			    (!pdata->using_extphy)) {
 				/* Restore original GPIO configuration */
@@ -755,7 +876,7 @@
 					pdata->gpio_setting);
 			}
 		} else {
-			SMSC_TRACE(HW, "configuring for no carrier");
+			SMSC_TRACE(pdata, hw, "configuring for no carrier");
 			/* Check global setting that LED1
 			 * usage is 10/100 indicator */
 			pdata->gpio_setting = smsc911x_reg_read(pdata,
@@ -787,25 +908,25 @@
 	/* find the first phy */
 	phydev = phy_find_first(pdata->mii_bus);
 	if (!phydev) {
-		pr_err("%s: no PHY found\n", dev->name);
+		netdev_err(dev, "no PHY found\n");
 		return -ENODEV;
 	}
 
-	SMSC_TRACE(PROBE, "PHY: addr %d, phy_id 0x%08X",
-			phydev->addr, phydev->phy_id);
+	SMSC_TRACE(pdata, probe, "PHY: addr %d, phy_id 0x%08X",
+		   phydev->addr, phydev->phy_id);
 
 	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);
+		netdev_err(dev, "Could not attach to PHY\n");
 		return ret;
 	}
 
-	pr_info("%s: attached PHY driver [%s] (mii_bus:phy_addr=%s, irq=%d)\n",
-		dev->name, phydev->drv->name,
-		dev_name(&phydev->dev), phydev->irq);
+	netdev_info(dev,
+		    "attached PHY driver [%s] (mii_bus:phy_addr=%s, irq=%d)\n",
+		    phydev->drv->name, dev_name(&phydev->dev), phydev->irq);
 
 	/* mask with MAC supported features */
 	phydev->supported &= (PHY_BASIC_FEATURES | SUPPORTED_Pause |
@@ -818,13 +939,13 @@
 
 #ifdef USE_PHY_WORK_AROUND
 	if (smsc911x_phy_loopbacktest(dev) < 0) {
-		SMSC_WARNING(HW, "Failed Loop Back Test");
+		SMSC_WARN(pdata, hw, "Failed Loop Back Test");
 		return -ENODEV;
 	}
-	SMSC_TRACE(HW, "Passed Loop Back Test");
+	SMSC_TRACE(pdata, hw, "Passed Loop Back Test");
 #endif				/* USE_PHY_WORK_AROUND */
 
-	SMSC_TRACE(HW, "phy initialised successfully");
+	SMSC_TRACE(pdata, hw, "phy initialised successfully");
 	return 0;
 }
 
@@ -860,8 +981,8 @@
 		smsc911x_phy_initialise_external(pdata);
 		break;
 	default:
-		SMSC_TRACE(HW, "External PHY is not supported, "
-			"using internal PHY");
+		SMSC_TRACE(pdata, hw, "External PHY is not supported, "
+			   "using internal PHY");
 		pdata->using_extphy = 0;
 		break;
 	}
@@ -872,12 +993,12 @@
 	}
 
 	if (mdiobus_register(pdata->mii_bus)) {
-		SMSC_WARNING(PROBE, "Error registering mii bus");
+		SMSC_WARN(pdata, probe, "Error registering mii bus");
 		goto err_out_free_bus_2;
 	}
 
 	if (smsc911x_mii_probe(dev) < 0) {
-		SMSC_WARNING(PROBE, "Error registering mii bus");
+		SMSC_WARN(pdata, probe, "Error registering mii bus");
 		goto err_out_unregister_bus_3;
 	}
 
@@ -913,8 +1034,7 @@
 			 * does not reference a hardware defined reserved bit
 			 * but rather a driver defined one.
 			 */
-			SMSC_WARNING(HW,
-				"Packet tag reserved bit is high");
+			SMSC_WARN(pdata, hw, "Packet tag reserved bit is high");
 		} else {
 			if (unlikely(tx_stat & TX_STS_ES_)) {
 				dev->stats.tx_errors++;
@@ -977,8 +1097,8 @@
 		} while ((val & RX_DP_CTRL_RX_FFWD_) && --timeout);
 
 		if (unlikely(timeout == 0))
-			SMSC_WARNING(HW, "Timed out waiting for "
-				"RX FFWD to finish, RX_DP_CTRL: 0x%08X", val);
+			SMSC_WARN(pdata, hw, "Timed out waiting for "
+				  "RX FFWD to finish, RX_DP_CTRL: 0x%08X", val);
 	} else {
 		unsigned int temp;
 		while (pktwords--)
@@ -1021,8 +1141,8 @@
 		smsc911x_rx_counterrors(dev, rxstat);
 
 		if (unlikely(rxstat & RX_STS_ES_)) {
-			SMSC_WARNING(RX_ERR,
-				"Discarding packet with error bit set");
+			SMSC_WARN(pdata, rx_err,
+				  "Discarding packet with error bit set");
 			/* Packet has an error, discard it and continue with
 			 * the next */
 			smsc911x_rx_fastforward(pdata, pktwords);
@@ -1032,8 +1152,8 @@
 
 		skb = netdev_alloc_skb(dev, pktlength + NET_IP_ALIGN);
 		if (unlikely(!skb)) {
-			SMSC_WARNING(RX_ERR,
-				"Unable to allocate skb for rx packet");
+			SMSC_WARN(pdata, rx_err,
+				  "Unable to allocate skb for rx packet");
 			/* Drop the packet and stop this polling iteration */
 			smsc911x_rx_fastforward(pdata, pktwords);
 			dev->stats.rx_dropped++;
@@ -1046,8 +1166,8 @@
 		/* Align IP on 16B boundary */
 		skb_reserve(skb, NET_IP_ALIGN);
 		skb_put(skb, pktlength - 4);
-		smsc911x_rx_readfifo(pdata, (unsigned int *)skb->head,
-				     pktwords);
+		pdata->ops->rx_readfifo(pdata,
+				 (unsigned int *)skb->head, pktwords);
 		skb->protocol = eth_type_trans(skb, dev);
 		skb_checksum_none_assert(skb);
 		netif_receive_skb(skb);
@@ -1083,8 +1203,8 @@
 	smsc911x_mac_write(pdata, MAC_CR, mac_cr);
 	smsc911x_mac_write(pdata, HASHH, pdata->hashhi);
 	smsc911x_mac_write(pdata, HASHL, pdata->hashlo);
-	SMSC_TRACE(HW, "maccr 0x%08X, HASHH 0x%08X, HASHL 0x%08X",
-		mac_cr, pdata->hashhi, pdata->hashlo);
+	SMSC_TRACE(pdata, hw, "maccr 0x%08X, HASHH 0x%08X, HASHL 0x%08X",
+		   mac_cr, pdata->hashhi, pdata->hashlo);
 }
 
 static void smsc911x_rx_multicast_update_workaround(struct smsc911x_data *pdata)
@@ -1102,7 +1222,7 @@
 
 	/* Check Rx has stopped */
 	if (smsc911x_mac_read(pdata, MAC_CR) & MAC_CR_RXEN_)
-		SMSC_WARNING(DRV, "Rx not stopped");
+		SMSC_WARN(pdata, drv, "Rx not stopped");
 
 	/* Perform the update - safe to do now Rx has stopped */
 	smsc911x_rx_multicast_update(pdata);
@@ -1131,7 +1251,7 @@
 	} while ((--timeout) && (temp & HW_CFG_SRST_));
 
 	if (unlikely(temp & HW_CFG_SRST_)) {
-		SMSC_WARNING(DRV, "Failed to complete reset");
+		SMSC_WARN(pdata, drv, "Failed to complete reset");
 		return -EIO;
 	}
 	return 0;
@@ -1160,18 +1280,18 @@
 
 	/* if the phy is not yet registered, retry later*/
 	if (!pdata->phy_dev) {
-		SMSC_WARNING(HW, "phy_dev is NULL");
+		SMSC_WARN(pdata, hw, "phy_dev is NULL");
 		return -EAGAIN;
 	}
 
 	if (!is_valid_ether_addr(dev->dev_addr)) {
-		SMSC_WARNING(HW, "dev_addr is not a valid MAC address");
+		SMSC_WARN(pdata, hw, "dev_addr is not a valid MAC address");
 		return -EADDRNOTAVAIL;
 	}
 
 	/* Reset the LAN911x */
 	if (smsc911x_soft_reset(pdata)) {
-		SMSC_WARNING(HW, "soft reset failed");
+		SMSC_WARN(pdata, hw, "soft reset failed");
 		return -EIO;
 	}
 
@@ -1191,8 +1311,8 @@
 	}
 
 	if (unlikely(timeout == 0))
-		SMSC_WARNING(IFUP,
-			"Timed out waiting for EEPROM busy bit to clear");
+		SMSC_WARN(pdata, ifup,
+			  "Timed out waiting for EEPROM busy bit to clear");
 
 	smsc911x_reg_write(pdata, GPIO_CFG, 0x70070000);
 
@@ -1210,22 +1330,22 @@
 	intcfg = ((10 << 24) | INT_CFG_IRQ_EN_);
 
 	if (pdata->config.irq_polarity) {
-		SMSC_TRACE(IFUP, "irq polarity: active high");
+		SMSC_TRACE(pdata, ifup, "irq polarity: active high");
 		intcfg |= INT_CFG_IRQ_POL_;
 	} else {
-		SMSC_TRACE(IFUP, "irq polarity: active low");
+		SMSC_TRACE(pdata, ifup, "irq polarity: active low");
 	}
 
 	if (pdata->config.irq_type) {
-		SMSC_TRACE(IFUP, "irq type: push-pull");
+		SMSC_TRACE(pdata, ifup, "irq type: push-pull");
 		intcfg |= INT_CFG_IRQ_TYPE_;
 	} else {
-		SMSC_TRACE(IFUP, "irq type: open drain");
+		SMSC_TRACE(pdata, ifup, "irq type: open drain");
 	}
 
 	smsc911x_reg_write(pdata, INT_CFG, intcfg);
 
-	SMSC_TRACE(IFUP, "Testing irq handler using IRQ %d", dev->irq);
+	SMSC_TRACE(pdata, ifup, "Testing irq handler using IRQ %d", dev->irq);
 	pdata->software_irq_signal = 0;
 	smp_wmb();
 
@@ -1241,14 +1361,15 @@
 	}
 
 	if (!pdata->software_irq_signal) {
-		dev_warn(&dev->dev, "ISR failed signaling test (IRQ %d)\n",
-			 dev->irq);
+		netdev_warn(dev, "ISR failed signaling test (IRQ %d)\n",
+			    dev->irq);
 		return -ENODEV;
 	}
-	SMSC_TRACE(IFUP, "IRQ handler passed test using IRQ %d", dev->irq);
+	SMSC_TRACE(pdata, ifup, "IRQ handler passed test using IRQ %d",
+		   dev->irq);
 
-	dev_info(&dev->dev, "SMSC911x/921x identified at %#08lx, IRQ: %d\n",
-		 (unsigned long)pdata->ioaddr, dev->irq);
+	netdev_info(dev, "SMSC911x/921x identified at %#08lx, IRQ: %d\n",
+		    (unsigned long)pdata->ioaddr, dev->irq);
 
 	/* Reset the last known duplex and carrier */
 	pdata->last_duplex = -1;
@@ -1313,7 +1434,7 @@
 	if (pdata->phy_dev)
 		phy_stop(pdata->phy_dev);
 
-	SMSC_TRACE(IFDOWN, "Interface stopped");
+	SMSC_TRACE(pdata, ifdown, "Interface stopped");
 	return 0;
 }
 
@@ -1331,8 +1452,8 @@
 	freespace = smsc911x_reg_read(pdata, TX_FIFO_INF) & TX_FIFO_INF_TDFREE_;
 
 	if (unlikely(freespace < TX_FIFO_LOW_THRESHOLD))
-		SMSC_WARNING(TX_ERR,
-			"Tx data fifo low, space available: %d", freespace);
+		SMSC_WARN(pdata, tx_err,
+			  "Tx data fifo low, space available: %d", freespace);
 
 	/* Word alignment adjustment */
 	tx_cmd_a = (u32)((ulong)skb->data & 0x03) << 16;
@@ -1350,7 +1471,7 @@
 	wrsz += (u32)((ulong)skb->data & 0x3);
 	wrsz >>= 2;
 
-	smsc911x_tx_writefifo(pdata, (unsigned int *)bufp, wrsz);
+	pdata->ops->tx_writefifo(pdata, (unsigned int *)bufp, wrsz);
 	freespace -= (skb->len + 32);
 	dev_kfree_skb(skb);
 
@@ -1432,7 +1553,7 @@
 		 * receiving data */
 		if (!pdata->multicast_update_pending) {
 			unsigned int temp;
-			SMSC_TRACE(HW, "scheduling mcast update");
+			SMSC_TRACE(pdata, hw, "scheduling mcast update");
 			pdata->multicast_update_pending = 1;
 
 			/* Request the hardware to stop, then perform the
@@ -1474,7 +1595,7 @@
 	if (unlikely(intsts & inten & INT_STS_RXSTOP_INT_)) {
 		/* Called when there is a multicast update scheduled and
 		 * it is now safe to complete the update */
-		SMSC_TRACE(INTR, "RX Stop interrupt");
+		SMSC_TRACE(pdata, intr, "RX Stop interrupt");
 		smsc911x_reg_write(pdata, INT_STS, INT_STS_RXSTOP_INT_);
 		if (pdata->multicast_update_pending)
 			smsc911x_rx_multicast_update_workaround(pdata);
@@ -1491,7 +1612,7 @@
 	}
 
 	if (unlikely(intsts & inten & INT_STS_RXE_)) {
-		SMSC_TRACE(INTR, "RX Error interrupt");
+		SMSC_TRACE(pdata, intr, "RX Error interrupt");
 		smsc911x_reg_write(pdata, INT_STS, INT_STS_RXE_);
 		serviced = IRQ_HANDLED;
 	}
@@ -1505,8 +1626,7 @@
 			/* Schedule a NAPI poll */
 			__napi_schedule(&pdata->napi);
 		} else {
-			SMSC_WARNING(RX_ERR,
-				"napi_schedule_prep failed");
+			SMSC_WARN(pdata, rx_err, "napi_schedule_prep failed");
 		}
 		serviced = IRQ_HANDLED;
 	}
@@ -1543,7 +1663,7 @@
 	smsc911x_set_hw_mac_address(pdata, dev->dev_addr);
 	spin_unlock_irq(&pdata->mac_lock);
 
-	dev_info(&dev->dev, "MAC Address: %pM\n", dev->dev_addr);
+	netdev_info(dev, "MAC Address: %pM\n", dev->dev_addr);
 
 	return 0;
 }
@@ -1649,9 +1769,9 @@
 	int timeout = 100;
 	u32 e2cmd;
 
-	SMSC_TRACE(DRV, "op 0x%08x", op);
+	SMSC_TRACE(pdata, drv, "op 0x%08x", op);
 	if (smsc911x_reg_read(pdata, E2P_CMD) & E2P_CMD_EPC_BUSY_) {
-		SMSC_WARNING(DRV, "Busy at start");
+		SMSC_WARN(pdata, drv, "Busy at start");
 		return -EBUSY;
 	}
 
@@ -1664,12 +1784,12 @@
 	} while ((e2cmd & E2P_CMD_EPC_BUSY_) && (--timeout));
 
 	if (!timeout) {
-		SMSC_TRACE(DRV, "TIMED OUT");
+		SMSC_TRACE(pdata, drv, "TIMED OUT");
 		return -EAGAIN;
 	}
 
 	if (e2cmd & E2P_CMD_EPC_TIMEOUT_) {
-		SMSC_TRACE(DRV, "Error occurred during eeprom operation");
+		SMSC_TRACE(pdata, drv, "Error occurred during eeprom operation");
 		return -EINVAL;
 	}
 
@@ -1682,7 +1802,7 @@
 	u32 op = E2P_CMD_EPC_CMD_READ_ | address;
 	int ret;
 
-	SMSC_TRACE(DRV, "address 0x%x", address);
+	SMSC_TRACE(pdata, drv, "address 0x%x", address);
 	ret = smsc911x_eeprom_send_cmd(pdata, op);
 
 	if (!ret)
@@ -1698,7 +1818,7 @@
 	u32 temp;
 	int ret;
 
-	SMSC_TRACE(DRV, "address 0x%x, data 0x%x", address, data);
+	SMSC_TRACE(pdata, drv, "address 0x%x, data 0x%x", address, data);
 	ret = smsc911x_eeprom_send_cmd(pdata, op);
 
 	if (!ret) {
@@ -1811,26 +1931,26 @@
 	struct smsc911x_data *pdata = netdev_priv(dev);
 	unsigned int byte_test;
 
-	SMSC_TRACE(PROBE, "Driver Parameters:");
-	SMSC_TRACE(PROBE, "LAN base: 0x%08lX",
-		(unsigned long)pdata->ioaddr);
-	SMSC_TRACE(PROBE, "IRQ: %d", dev->irq);
-	SMSC_TRACE(PROBE, "PHY will be autodetected.");
+	SMSC_TRACE(pdata, probe, "Driver Parameters:");
+	SMSC_TRACE(pdata, probe, "LAN base: 0x%08lX",
+		   (unsigned long)pdata->ioaddr);
+	SMSC_TRACE(pdata, probe, "IRQ: %d", dev->irq);
+	SMSC_TRACE(pdata, probe, "PHY will be autodetected.");
 
 	spin_lock_init(&pdata->dev_lock);
 	spin_lock_init(&pdata->mac_lock);
 
 	if (pdata->ioaddr == 0) {
-		SMSC_WARNING(PROBE, "pdata->ioaddr: 0x00000000");
+		SMSC_WARN(pdata, probe, "pdata->ioaddr: 0x00000000");
 		return -ENODEV;
 	}
 
 	/* Check byte ordering */
 	byte_test = smsc911x_reg_read(pdata, BYTE_TEST);
-	SMSC_TRACE(PROBE, "BYTE_TEST: 0x%08X", byte_test);
+	SMSC_TRACE(pdata, probe, "BYTE_TEST: 0x%08X", byte_test);
 	if (byte_test == 0x43218765) {
-		SMSC_TRACE(PROBE, "BYTE_TEST looks swapped, "
-			"applying WORD_SWAP");
+		SMSC_TRACE(pdata, probe, "BYTE_TEST looks swapped, "
+			   "applying WORD_SWAP");
 		smsc911x_reg_write(pdata, WORD_SWAP, 0xffffffff);
 
 		/* 1 dummy read of BYTE_TEST is needed after a write to
@@ -1841,12 +1961,13 @@
 	}
 
 	if (byte_test != 0x87654321) {
-		SMSC_WARNING(DRV, "BYTE_TEST: 0x%08X", byte_test);
+		SMSC_WARN(pdata, drv, "BYTE_TEST: 0x%08X", byte_test);
 		if (((byte_test >> 16) & 0xFFFF) == (byte_test & 0xFFFF)) {
-			SMSC_WARNING(PROBE,
-				"top 16 bits equal to bottom 16 bits");
-			SMSC_TRACE(PROBE, "This may mean the chip is set "
-				"for 32 bit while the bus is reading 16 bit");
+			SMSC_WARN(pdata, probe,
+				  "top 16 bits equal to bottom 16 bits");
+			SMSC_TRACE(pdata, probe,
+				   "This may mean the chip is set "
+				   "for 32 bit while the bus is reading 16 bit");
 		}
 		return -ENODEV;
 	}
@@ -1881,17 +2002,18 @@
 		break;
 
 	default:
-		SMSC_WARNING(PROBE, "LAN911x not identified, idrev: 0x%08X",
-			pdata->idrev);
+		SMSC_WARN(pdata, probe, "LAN911x not identified, idrev: 0x%08X",
+			  pdata->idrev);
 		return -ENODEV;
 	}
 
-	SMSC_TRACE(PROBE, "LAN911x identified, idrev: 0x%08X, generation: %d",
-		pdata->idrev, pdata->generation);
+	SMSC_TRACE(pdata, probe,
+		   "LAN911x identified, idrev: 0x%08X, generation: %d",
+		   pdata->idrev, pdata->generation);
 
 	if (pdata->generation == 0)
-		SMSC_WARNING(PROBE,
-			"This driver is not intended for this chip revision");
+		SMSC_WARN(pdata, probe,
+			  "This driver is not intended for this chip revision");
 
 	/* workaround for platforms without an eeprom, where the mac address
 	 * is stored elsewhere and set by the bootloader.  This saves the
@@ -1931,7 +2053,7 @@
 	BUG_ON(!pdata->ioaddr);
 	BUG_ON(!pdata->phy_dev);
 
-	SMSC_TRACE(IFDOWN, "Stopping driver.");
+	SMSC_TRACE(pdata, ifdown, "Stopping driver");
 
 	phy_disconnect(pdata->phy_dev);
 	pdata->phy_dev = NULL;
@@ -1955,6 +2077,22 @@
 	return 0;
 }
 
+/* standard register acces */
+static const struct smsc911x_ops standard_smsc911x_ops = {
+	.reg_read = __smsc911x_reg_read,
+	.reg_write = __smsc911x_reg_write,
+	.rx_readfifo = smsc911x_rx_readfifo,
+	.tx_writefifo = smsc911x_tx_writefifo,
+};
+
+/* shifted register access */
+static const struct smsc911x_ops shifted_smsc911x_ops = {
+	.reg_read = __smsc911x_reg_read_shift,
+	.reg_write = __smsc911x_reg_write_shift,
+	.rx_readfifo = smsc911x_rx_readfifo_shift,
+	.tx_writefifo = smsc911x_tx_writefifo_shift,
+};
+
 static int __devinit smsc911x_drv_probe(struct platform_device *pdev)
 {
 	struct net_device *dev;
@@ -1965,11 +2103,11 @@
 	int res_size, irq_flags;
 	int retval;
 
-	pr_info("%s: Driver version %s.\n", SMSC_CHIPNAME, SMSC_DRV_VERSION);
+	pr_info("Driver version %s\n", SMSC_DRV_VERSION);
 
 	/* platform data specifies irq & dynamic bus configuration */
 	if (!pdev->dev.platform_data) {
-		pr_warning("%s: platform_data not provided\n", SMSC_CHIPNAME);
+		pr_warn("platform_data not provided\n");
 		retval = -ENODEV;
 		goto out_0;
 	}
@@ -1979,8 +2117,7 @@
 	if (!res)
 		res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	if (!res) {
-		pr_warning("%s: Could not allocate resource.\n",
-			SMSC_CHIPNAME);
+		pr_warn("Could not allocate resource\n");
 		retval = -ENODEV;
 		goto out_0;
 	}
@@ -1988,8 +2125,7 @@
 
 	irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
 	if (!irq_res) {
-		pr_warning("%s: Could not allocate irq resource.\n",
-			SMSC_CHIPNAME);
+		pr_warn("Could not allocate irq resource\n");
 		retval = -ENODEV;
 		goto out_0;
 	}
@@ -2001,7 +2137,7 @@
 
 	dev = alloc_etherdev(sizeof(struct smsc911x_data));
 	if (!dev) {
-		pr_warning("%s: Could not allocate device.\n", SMSC_CHIPNAME);
+		pr_warn("Could not allocate device\n");
 		retval = -ENOMEM;
 		goto out_release_io_1;
 	}
@@ -2021,12 +2157,17 @@
 	pdata->msg_enable = ((1 << debug) - 1);
 
 	if (pdata->ioaddr == NULL) {
-		SMSC_WARNING(PROBE,
-			"Error smsc911x base address invalid");
+		SMSC_WARN(pdata, probe, "Error smsc911x base address invalid");
 		retval = -ENOMEM;
 		goto out_free_netdev_2;
 	}
 
+	/* assume standard, non-shifted, access to HW registers */
+	pdata->ops = &standard_smsc911x_ops;
+	/* apply the right access if shifting is needed */
+	if (config->shift)
+		pdata->ops = &shifted_smsc911x_ops;
+
 	retval = smsc911x_init(dev);
 	if (retval < 0)
 		goto out_unmap_io_3;
@@ -2047,8 +2188,8 @@
 	retval = request_irq(dev->irq, smsc911x_irqhandler,
 			     irq_flags | IRQF_SHARED, dev->name, dev);
 	if (retval) {
-		SMSC_WARNING(PROBE,
-			"Unable to claim requested irq: %d", dev->irq);
+		SMSC_WARN(pdata, probe,
+			  "Unable to claim requested irq: %d", dev->irq);
 		goto out_unmap_io_3;
 	}
 
@@ -2056,17 +2197,16 @@
 
 	retval = register_netdev(dev);
 	if (retval) {
-		SMSC_WARNING(PROBE,
-			"Error %i registering device", retval);
+		SMSC_WARN(pdata, probe, "Error %i registering device", retval);
 		goto out_unset_drvdata_4;
 	} else {
-		SMSC_TRACE(PROBE, "Network interface: \"%s\"", dev->name);
+		SMSC_TRACE(pdata, probe,
+			   "Network interface: \"%s\"", dev->name);
 	}
 
 	retval = smsc911x_mii_init(pdev, dev);
 	if (retval) {
-		SMSC_WARNING(PROBE,
-			"Error %i initialising mii", retval);
+		SMSC_WARN(pdata, probe, "Error %i initialising mii", retval);
 		goto out_unregister_netdev_5;
 	}
 
@@ -2075,10 +2215,12 @@
 	/* Check if mac address has been specified when bringing interface up */
 	if (is_valid_ether_addr(dev->dev_addr)) {
 		smsc911x_set_hw_mac_address(pdata, dev->dev_addr);
-		SMSC_TRACE(PROBE, "MAC Address is specified by configuration");
+		SMSC_TRACE(pdata, probe,
+			   "MAC Address is specified by configuration");
 	} else if (is_valid_ether_addr(pdata->config.mac)) {
 		memcpy(dev->dev_addr, pdata->config.mac, 6);
-		SMSC_TRACE(PROBE, "MAC Address specified by platform data");
+		SMSC_TRACE(pdata, probe,
+			   "MAC Address specified by platform data");
 	} else {
 		/* Try reading mac address from device. if EEPROM is present
 		 * it will already have been set */
@@ -2086,20 +2228,20 @@
 
 		if (is_valid_ether_addr(dev->dev_addr)) {
 			/* eeprom values are valid  so use them */
-			SMSC_TRACE(PROBE,
-				"Mac Address is read from LAN911x EEPROM");
+			SMSC_TRACE(pdata, probe,
+				   "Mac Address is read from LAN911x EEPROM");
 		} else {
 			/* eeprom values are invalid, generate random MAC */
 			random_ether_addr(dev->dev_addr);
 			smsc911x_set_hw_mac_address(pdata, dev->dev_addr);
-			SMSC_TRACE(PROBE,
-				"MAC Address is set to random_ether_addr");
+			SMSC_TRACE(pdata, probe,
+				   "MAC Address is set to random_ether_addr");
 		}
 	}
 
 	spin_unlock_irq(&pdata->mac_lock);
 
-	dev_info(&dev->dev, "MAC Address: %pM\n", dev->dev_addr);
+	netdev_info(dev, "MAC Address: %pM\n", dev->dev_addr);
 
 	return 0;
 
diff -druN linux-2.6.39-libre/drivers/net/smsc911x.h linux-3.0-rc7-libre/drivers/net/smsc911x.h
--- linux-2.6.39-libre/drivers/net/smsc911x.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/smsc911x.h	2011-07-11 19:51:52.000000000 -0400
@@ -33,25 +33,21 @@
  * can be successfully looped back */
 #define USE_PHY_WORK_AROUND
 
-#define DPRINTK(nlevel, klevel, fmt, args...) \
-	((void)((NETIF_MSG_##nlevel & pdata->msg_enable) && \
-	printk(KERN_##klevel "%s: %s: " fmt "\n", \
-	pdata->dev->name, __func__, ## args)))
-
 #if USE_DEBUG >= 1
-#define SMSC_WARNING(nlevel, fmt, args...) \
-	DPRINTK(nlevel, WARNING, fmt, ## args)
+#define SMSC_WARN(pdata, nlevel, fmt, args...)			\
+	netif_warn(pdata, nlevel, (pdata)->dev,			\
+		   "%s: " fmt "\n", __func__, ##args)
 #else
-#define SMSC_WARNING(nlevel, fmt, args...) \
-	({ do {} while (0); 0; })
+#define SMSC_WARN(pdata, nlevel, fmt, args...)			\
+	no_printk(fmt "\n", ##args)
 #endif
 
 #if USE_DEBUG >= 2
-#define SMSC_TRACE(nlevel, fmt, args...) \
-	DPRINTK(nlevel, INFO, fmt, ## args)
+#define SMSC_TRACE(pdata, nlevel, fmt, args...)			\
+	netif_info(pdata, nlevel, pdata->dev, fmt "\n", ##args)
 #else
-#define SMSC_TRACE(nlevel, fmt, args...) \
-	({ do {} while (0); 0; })
+#define SMSC_TRACE(pdata, nlevel, fmt, args...)			\
+	no_printk(fmt "\n", ##args)
 #endif
 
 #ifdef CONFIG_DEBUG_SPINLOCK
diff -druN linux-2.6.39-libre/drivers/net/spider_net.c linux-3.0-rc7-libre/drivers/net/spider_net.c
--- linux-2.6.39-libre/drivers/net/spider_net.c	2011-05-19 02:12:29.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/spider_net.c	2011-07-21 06:54:56.000000000 -0400
@@ -994,15 +994,13 @@
 	skb->protocol = eth_type_trans(skb, netdev);
 
 	/* checksum offload */
-	if (card->options.rx_csum) {
+	skb_checksum_none_assert(skb);
+	if (netdev->features & NETIF_F_RXCSUM) {
 		if ( ( (data_status & SPIDER_NET_DATA_STATUS_CKSUM_MASK) ==
 		       SPIDER_NET_DATA_STATUS_CKSUM_MASK) &&
 		     !(data_error & SPIDER_NET_DATA_ERR_CKSUM_MASK))
 			skb->ip_summed = CHECKSUM_UNNECESSARY;
-		else
-			skb_checksum_none_assert(skb);
-	} else
-		skb_checksum_none_assert(skb);
+	}
 
 	if (data_status & SPIDER_NET_VLAN_PACKET) {
 		/* further enhancements: HW-accel VLAN
@@ -2322,14 +2320,15 @@
 	card->aneg_timer.function = spider_net_link_phy;
 	card->aneg_timer.data = (unsigned long) card;
 
-	card->options.rx_csum = SPIDER_NET_RX_CSUM_DEFAULT;
-
 	netif_napi_add(netdev, &card->napi,
 		       spider_net_poll, SPIDER_NET_NAPI_WEIGHT);
 
 	spider_net_setup_netdev_ops(netdev);
 
-	netdev->features = NETIF_F_IP_CSUM | NETIF_F_LLTX;
+	netdev->hw_features = NETIF_F_RXCSUM | NETIF_F_IP_CSUM;
+	if (SPIDER_NET_RX_CSUM_DEFAULT)
+		netdev->features |= NETIF_F_RXCSUM;
+	netdev->features |= NETIF_F_IP_CSUM | NETIF_F_LLTX;
 	/* some time: NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX |
 	 *		NETIF_F_HW_VLAN_FILTER */
 
diff -druN linux-2.6.39-libre/drivers/net/spider_net_ethtool.c linux-3.0-rc7-libre/drivers/net/spider_net_ethtool.c
--- linux-2.6.39-libre/drivers/net/spider_net_ethtool.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/spider_net_ethtool.c	2011-07-11 19:51:52.000000000 -0400
@@ -58,7 +58,7 @@
 	cmd->advertising = (ADVERTISED_1000baseT_Full |
 			     ADVERTISED_FIBRE);
 	cmd->port = PORT_FIBRE;
-	cmd->speed = card->phy.speed;
+	ethtool_cmd_speed_set(cmd, card->phy.speed);
 	cmd->duplex = DUPLEX_FULL;
 
 	return 0;
@@ -115,24 +115,6 @@
 	return 0;
 }
 
-static u32
-spider_net_ethtool_get_rx_csum(struct net_device *netdev)
-{
-	struct spider_net_card *card = netdev_priv(netdev);
-
-	return card->options.rx_csum;
-}
-
-static int
-spider_net_ethtool_set_rx_csum(struct net_device *netdev, u32 n)
-{
-	struct spider_net_card *card = netdev_priv(netdev);
-
-	card->options.rx_csum = n;
-	return 0;
-}
-
-
 static void
 spider_net_ethtool_get_ringparam(struct net_device *netdev,
 				 struct ethtool_ringparam *ering)
@@ -189,9 +171,6 @@
 	.set_msglevel		= spider_net_ethtool_set_msglevel,
 	.get_link		= ethtool_op_get_link,
 	.nway_reset		= spider_net_ethtool_nway_reset,
-	.get_rx_csum		= spider_net_ethtool_get_rx_csum,
-	.set_rx_csum		= spider_net_ethtool_set_rx_csum,
-	.set_tx_csum		= ethtool_op_set_tx_csum,
 	.get_ringparam          = spider_net_ethtool_get_ringparam,
 	.get_strings		= spider_net_get_strings,
 	.get_sset_count		= spider_net_get_sset_count,
diff -druN linux-2.6.39-libre/drivers/net/spider_net.h linux-3.0-rc7-libre/drivers/net/spider_net.h
--- linux-2.6.39-libre/drivers/net/spider_net.h	2011-05-19 02:12:31.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/spider_net.h	2011-07-21 06:54:58.000000000 -0400
@@ -429,12 +429,6 @@
  * 701b8000 would be correct, but every packets gets that flag */
 #define SPIDER_NET_DESTROY_RX_FLAGS	0x700b8000
 
-/* this will be bigger some time */
-struct spider_net_options {
-	int rx_csum; /* for rx: if 0 ip_summed=NONE,
-			if 1 and hw has verified, ip_summed=UNNECESSARY */
-};
-
 #define SPIDER_NET_DEFAULT_MSG		( NETIF_MSG_DRV | \
 					  NETIF_MSG_PROBE | \
 					  NETIF_MSG_LINK | \
@@ -487,7 +481,6 @@
 	/* for ethtool */
 	int msg_enable;
 	struct spider_net_extra_stats spider_stats;
-	struct spider_net_options options;
 
 	/* Must be last item in struct */
 	struct spider_net_descr darray[0];
diff -druN linux-2.6.39-libre/drivers/net/stmmac/dwmac1000_core.c linux-3.0-rc7-libre/drivers/net/stmmac/dwmac1000_core.c
--- linux-2.6.39-libre/drivers/net/stmmac/dwmac1000_core.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/stmmac/dwmac1000_core.c	2011-07-11 19:51:52.000000000 -0400
@@ -178,10 +178,11 @@
 {
 	unsigned int pmt = 0;
 
-	if (mode == WAKE_MAGIC) {
+	if (mode & WAKE_MAGIC) {
 		CHIP_DBG(KERN_DEBUG "GMAC: WOL Magic frame\n");
 		pmt |= power_down | magic_pkt_en;
-	} else if (mode == WAKE_UCAST) {
+	}
+	if (mode & WAKE_UCAST) {
 		CHIP_DBG(KERN_DEBUG "GMAC: WOL on global unicast\n");
 		pmt |= global_unicast;
 	}
diff -druN linux-2.6.39-libre/drivers/net/stmmac/stmmac_ethtool.c linux-3.0-rc7-libre/drivers/net/stmmac/stmmac_ethtool.c
--- linux-2.6.39-libre/drivers/net/stmmac/stmmac_ethtool.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/stmmac/stmmac_ethtool.c	2011-07-11 19:51:52.000000000 -0400
@@ -197,13 +197,6 @@
 	}
 }
 
-static u32 stmmac_ethtool_get_rx_csum(struct net_device *dev)
-{
-	struct stmmac_priv *priv = netdev_priv(dev);
-
-	return priv->rx_coe;
-}
-
 static void
 stmmac_get_pauseparam(struct net_device *netdev,
 		      struct ethtool_pauseparam *pause)
@@ -241,20 +234,11 @@
 		new_pause |= FLOW_TX;
 
 	priv->flow_ctrl = new_pause;
+	phy->autoneg = pause->autoneg;
 
 	if (phy->autoneg) {
-		if (netif_running(netdev)) {
-			struct ethtool_cmd cmd;
-			/* auto-negotiation automatically restarted */
-			cmd.cmd = ETHTOOL_NWAY_RST;
-			cmd.supported = phy->supported;
-			cmd.advertising = phy->advertising;
-			cmd.autoneg = phy->autoneg;
-			cmd.speed = phy->speed;
-			cmd.duplex = phy->duplex;
-			cmd.phy_address = phy->addr;
-			ret = phy_ethtool_sset(phy, &cmd);
-		}
+		if (netif_running(netdev))
+			ret = phy_start_aneg(phy);
 	} else
 		priv->hw->mac->flow_ctrl(priv->ioaddr, phy->duplex,
 					 priv->flow_ctrl, priv->pause);
@@ -315,7 +299,7 @@
 
 	spin_lock_irq(&priv->lock);
 	if (device_can_wakeup(priv->device)) {
-		wol->supported = WAKE_MAGIC;
+		wol->supported = WAKE_MAGIC | WAKE_UCAST;
 		wol->wolopts = priv->wolopts;
 	}
 	spin_unlock_irq(&priv->lock);
@@ -324,7 +308,7 @@
 static int stmmac_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
 {
 	struct stmmac_priv *priv = netdev_priv(dev);
-	u32 support = WAKE_MAGIC;
+	u32 support = WAKE_MAGIC | WAKE_UCAST;
 
 	if (!device_can_wakeup(priv->device))
 		return -EINVAL;
@@ -358,11 +342,6 @@
 	.get_regs = stmmac_ethtool_gregs,
 	.get_regs_len = stmmac_ethtool_get_regs_len,
 	.get_link = ethtool_op_get_link,
-	.get_rx_csum = stmmac_ethtool_get_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_pauseparam = stmmac_get_pauseparam,
 	.set_pauseparam = stmmac_set_pauseparam,
 	.get_ethtool_stats = stmmac_get_ethtool_stats,
@@ -370,8 +349,6 @@
 	.get_wol = stmmac_get_wol,
 	.set_wol = stmmac_set_wol,
 	.get_sset_count	= stmmac_get_sset_count,
-	.get_tso = ethtool_op_get_tso,
-	.set_tso = ethtool_op_set_tso,
 };
 
 void stmmac_set_ethtool_ops(struct net_device *netdev)
diff -druN linux-2.6.39-libre/drivers/net/stmmac/stmmac.h linux-3.0-rc7-libre/drivers/net/stmmac/stmmac.h
--- linux-2.6.39-libre/drivers/net/stmmac/stmmac.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/stmmac/stmmac.h	2011-07-11 19:51:52.000000000 -0400
@@ -21,7 +21,6 @@
 *******************************************************************************/
 
 #define DRV_MODULE_VERSION	"Nov_2010"
-#include <linux/platform_device.h>
 #include <linux/stmmac.h>
 
 #include "common.h"
diff -druN linux-2.6.39-libre/drivers/net/stmmac/stmmac_main.c linux-3.0-rc7-libre/drivers/net/stmmac/stmmac_main.c
--- linux-2.6.39-libre/drivers/net/stmmac/stmmac_main.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/stmmac/stmmac_main.c	2011-07-11 19:51:52.000000000 -0400
@@ -45,6 +45,7 @@
 #include <linux/if_vlan.h>
 #include <linux/dma-mapping.h>
 #include <linux/slab.h>
+#include <linux/prefetch.h>
 #include "stmmac.h"
 
 #define STMMAC_RESOURCE_NAME	"stmmaceth"
@@ -116,9 +117,6 @@
 module_param(tc, int, S_IRUGO | S_IWUSR);
 MODULE_PARM_DESC(tc, "DMA threshold control value");
 
-#define RX_NO_COALESCE	1	/* Always interrupt on completion */
-#define TX_NO_COALESCE	-1	/* No moderation by default */
-
 /* Pay attention to tune this parameter; take care of both
  * hardware capability and network stabitily/performance impact.
  * Many tests showed that ~4ms latency seems to be good enough. */
@@ -139,7 +137,6 @@
 				      NETIF_MSG_IFDOWN | NETIF_MSG_TIMER);
 
 static irqreturn_t stmmac_interrupt(int irq, void *dev_id);
-static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev);
 
 /**
  * stmmac_verify_args - verify the driver parameters.
@@ -831,6 +828,7 @@
 		pr_info("stmmac: Rx Checksum Offload Engine supported\n");
 	if (priv->plat->tx_coe)
 		pr_info("\tTX Checksum insertion supported\n");
+	netdev_update_features(dev);
 
 	/* Initialise the MMC (if present) to disable all interrupts. */
 	writel(0xffffffff, priv->ioaddr + MMC_HIGH_INTR_MASK);
@@ -934,46 +932,6 @@
 	return 0;
 }
 
-/*
- * To perform emulated hardware segmentation on skb.
- */
-static int stmmac_sw_tso(struct stmmac_priv *priv, struct sk_buff *skb)
-{
-	struct sk_buff *segs, *curr_skb;
-	int gso_segs = skb_shinfo(skb)->gso_segs;
-
-	/* Estimate the number of fragments in the worst case */
-	if (unlikely(stmmac_tx_avail(priv) < gso_segs)) {
-		netif_stop_queue(priv->dev);
-		TX_DBG(KERN_ERR "%s: TSO BUG! Tx Ring full when queue awake\n",
-		       __func__);
-		if (stmmac_tx_avail(priv) < gso_segs)
-			return NETDEV_TX_BUSY;
-
-		netif_wake_queue(priv->dev);
-	}
-	TX_DBG("\tstmmac_sw_tso: segmenting: skb %p (len %d)\n",
-	       skb, skb->len);
-
-	segs = skb_gso_segment(skb, priv->dev->features & ~NETIF_F_TSO);
-	if (IS_ERR(segs))
-		goto sw_tso_end;
-
-	do {
-		curr_skb = segs;
-		segs = segs->next;
-		TX_DBG("\t\tcurrent skb->len: %d, *curr %p,"
-		       "*next %p\n", curr_skb->len, curr_skb, segs);
-		curr_skb->next = NULL;
-		stmmac_xmit(curr_skb, priv->dev);
-	} while (segs);
-
-sw_tso_end:
-	dev_kfree_skb(skb);
-
-	return NETDEV_TX_OK;
-}
-
 static unsigned int stmmac_handle_jumbo_frames(struct sk_buff *skb,
 					       struct net_device *dev,
 					       int csum_insertion)
@@ -1051,16 +1009,7 @@
 		       !skb_is_gso(skb) ? "isn't" : "is");
 #endif
 
-	if (unlikely(skb_is_gso(skb)))
-		return stmmac_sw_tso(priv, skb);
-
-	if (likely((skb->ip_summed == CHECKSUM_PARTIAL))) {
-		if (unlikely((!priv->plat->tx_coe) ||
-			     (priv->no_csum_insertion)))
-			skb_checksum_help(skb);
-		else
-			csum_insertion = 1;
-	}
+	csum_insertion = (skb->ip_summed == CHECKSUM_PARTIAL);
 
 	desc = priv->dma_tx + entry;
 	first = desc;
@@ -1380,18 +1329,29 @@
 		return -EINVAL;
 	}
 
+	dev->mtu = new_mtu;
+	netdev_update_features(dev);
+
+	return 0;
+}
+
+static u32 stmmac_fix_features(struct net_device *dev, u32 features)
+{
+	struct stmmac_priv *priv = netdev_priv(dev);
+
+	if (!priv->rx_coe)
+		features &= ~NETIF_F_RXCSUM;
+	if (!priv->plat->tx_coe)
+		features &= ~NETIF_F_ALL_CSUM;
+
 	/* Some GMAC devices have a bugged Jumbo frame support that
 	 * needs to have the Tx COE disabled for oversized frames
 	 * (due to limited buffer sizes). In this case we disable
 	 * the TX csum insertionin the TDES and not use SF. */
-	if ((priv->plat->bugged_jumbo) && (priv->dev->mtu > ETH_DATA_LEN))
-		priv->no_csum_insertion = 1;
-	else
-		priv->no_csum_insertion = 0;
-
-	dev->mtu = new_mtu;
+	if (priv->plat->bugged_jumbo && (dev->mtu > ETH_DATA_LEN))
+		features &= ~NETIF_F_ALL_CSUM;
 
-	return 0;
+	return features;
 }
 
 static irqreturn_t stmmac_interrupt(int irq, void *dev_id)
@@ -1471,6 +1431,7 @@
 	.ndo_start_xmit = stmmac_xmit,
 	.ndo_stop = stmmac_release,
 	.ndo_change_mtu = stmmac_change_mtu,
+	.ndo_fix_features = stmmac_fix_features,
 	.ndo_set_multicast_list = stmmac_multicast_list,
 	.ndo_tx_timeout = stmmac_tx_timeout,
 	.ndo_do_ioctl = stmmac_ioctl,
@@ -1501,8 +1462,8 @@
 	dev->netdev_ops = &stmmac_netdev_ops;
 	stmmac_set_ethtool_ops(dev);
 
-	dev->features |= NETIF_F_SG | NETIF_F_HIGHDMA |
-		NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;
+	dev->hw_features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;
+	dev->features |= dev->hw_features | NETIF_F_HIGHDMA;
 	dev->watchdog_timeo = msecs_to_jiffies(watchdog);
 #ifdef STMMAC_VLAN_TAG_USED
 	/* Both mac100 and gmac support receive VLAN tag detection */
diff -druN linux-2.6.39-libre/drivers/net/sungem.c linux-3.0-rc7-libre/drivers/net/sungem.c
--- linux-2.6.39-libre/drivers/net/sungem.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/sungem.c	2011-07-11 19:51:52.000000000 -0400
@@ -1294,7 +1294,7 @@
 		autoneg = 1;
 	} else {
 		autoneg = 0;
-		speed = ep->speed;
+		speed = ethtool_cmd_speed(ep);
 		duplex = ep->duplex;
 	}
 
@@ -2642,7 +2642,7 @@
 		/* Return current PHY settings */
 		spin_lock_irq(&gp->lock);
 		cmd->autoneg = gp->want_autoneg;
-		cmd->speed = gp->phy_mii.speed;
+		ethtool_cmd_speed_set(cmd, gp->phy_mii.speed);
 		cmd->duplex = gp->phy_mii.duplex;
 		cmd->advertising = gp->phy_mii.advertising;
 
@@ -2659,7 +2659,7 @@
 			 SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full |
 			 SUPPORTED_Autoneg);
 		cmd->advertising = cmd->supported;
-		cmd->speed = 0;
+		ethtool_cmd_speed_set(cmd, 0);
 		cmd->duplex = cmd->port = cmd->phy_address =
 			cmd->transceiver = cmd->autoneg = 0;
 
@@ -2673,7 +2673,7 @@
 			cmd->advertising = cmd->supported;
 			cmd->transceiver = XCVR_INTERNAL;
 			if (gp->lstate == link_up)
-				cmd->speed = SPEED_1000;
+				ethtool_cmd_speed_set(cmd, SPEED_1000);
 			cmd->duplex = DUPLEX_FULL;
 			cmd->autoneg = 1;
 		}
@@ -2686,6 +2686,7 @@
 static int gem_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
 {
 	struct gem *gp = netdev_priv(dev);
+	u32 speed = ethtool_cmd_speed(cmd);
 
 	/* Verify the settings we care about. */
 	if (cmd->autoneg != AUTONEG_ENABLE &&
@@ -2697,9 +2698,9 @@
 		return -EINVAL;
 
 	if (cmd->autoneg == AUTONEG_DISABLE &&
-	    ((cmd->speed != SPEED_1000 &&
-	      cmd->speed != SPEED_100 &&
-	      cmd->speed != SPEED_10) ||
+	    ((speed != SPEED_1000 &&
+	      speed != SPEED_100 &&
+	      speed != SPEED_10) ||
 	     (cmd->duplex != DUPLEX_HALF &&
 	      cmd->duplex != DUPLEX_FULL)))
 		return -EINVAL;
@@ -3146,7 +3147,8 @@
 			    gp->phy_mii.def ? gp->phy_mii.def->name : "no");
 
 	/* GEM can do it all... */
-	dev->features |= NETIF_F_SG | NETIF_F_HW_CSUM | NETIF_F_LLTX;
+	dev->hw_features = NETIF_F_SG | NETIF_F_HW_CSUM;
+	dev->features |= dev->hw_features | NETIF_F_RXCSUM | NETIF_F_LLTX;
 	if (pci_using_dac)
 		dev->features |= NETIF_F_HIGHDMA;
 
diff -druN linux-2.6.39-libre/drivers/net/sunhme.c linux-3.0-rc7-libre/drivers/net/sunhme.c
--- linux-2.6.39-libre/drivers/net/sunhme.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/sunhme.c	2011-07-11 19:51:52.000000000 -0400
@@ -1383,7 +1383,7 @@
 		if (ep == NULL || ep->autoneg == AUTONEG_ENABLE) {
 			hp->sw_bmcr = BMCR_SPEED100;
 		} else {
-			if (ep->speed == SPEED_100)
+			if (ethtool_cmd_speed(ep) == SPEED_100)
 				hp->sw_bmcr = BMCR_SPEED100;
 			else
 				hp->sw_bmcr = 0;
@@ -2401,6 +2401,7 @@
 static int hme_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
 {
 	struct happy_meal *hp = netdev_priv(dev);
+	u32 speed;
 
 	cmd->supported =
 		(SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full |
@@ -2420,10 +2421,9 @@
 
 	if (hp->sw_bmcr & BMCR_ANENABLE) {
 		cmd->autoneg = AUTONEG_ENABLE;
-		cmd->speed =
-			(hp->sw_lpa & (LPA_100HALF | LPA_100FULL)) ?
-			SPEED_100 : SPEED_10;
-		if (cmd->speed == SPEED_100)
+		speed = ((hp->sw_lpa & (LPA_100HALF | LPA_100FULL)) ?
+			 SPEED_100 : SPEED_10);
+		if (speed == SPEED_100)
 			cmd->duplex =
 				(hp->sw_lpa & (LPA_100FULL)) ?
 				DUPLEX_FULL : DUPLEX_HALF;
@@ -2433,13 +2433,12 @@
 				DUPLEX_FULL : DUPLEX_HALF;
 	} else {
 		cmd->autoneg = AUTONEG_DISABLE;
-		cmd->speed =
-			(hp->sw_bmcr & BMCR_SPEED100) ?
-			SPEED_100 : SPEED_10;
+		speed = (hp->sw_bmcr & BMCR_SPEED100) ? SPEED_100 : SPEED_10;
 		cmd->duplex =
 			(hp->sw_bmcr & BMCR_FULLDPLX) ?
 			DUPLEX_FULL : DUPLEX_HALF;
 	}
+	ethtool_cmd_speed_set(cmd, speed);
 	return 0;
 }
 
@@ -2452,8 +2451,8 @@
 	    cmd->autoneg != AUTONEG_DISABLE)
 		return -EINVAL;
 	if (cmd->autoneg == AUTONEG_DISABLE &&
-	    ((cmd->speed != SPEED_100 &&
-	      cmd->speed != SPEED_10) ||
+	    ((ethtool_cmd_speed(cmd) != SPEED_100 &&
+	      ethtool_cmd_speed(cmd) != SPEED_10) ||
 	     (cmd->duplex != DUPLEX_HALF &&
 	      cmd->duplex != DUPLEX_FULL)))
 		return -EINVAL;
@@ -2788,7 +2787,8 @@
 	dev->ethtool_ops = &hme_ethtool_ops;
 
 	/* Happy Meal can do it all... */
-	dev->features |= NETIF_F_SG | NETIF_F_HW_CSUM;
+	dev->hw_features = NETIF_F_SG | NETIF_F_HW_CSUM;
+	dev->features |= dev->hw_features | NETIF_F_RXCSUM;
 
 	dev->irq = op->archdata.irqs[0];
 
@@ -3113,7 +3113,8 @@
 	dev->dma = 0;
 
 	/* Happy Meal can do it all... */
-	dev->features |= NETIF_F_SG | NETIF_F_HW_CSUM;
+	dev->hw_features = NETIF_F_SG | NETIF_F_HW_CSUM;
+	dev->features |= dev->hw_features | NETIF_F_RXCSUM;
 
 #if defined(CONFIG_SBUS) && defined(CONFIG_PCI)
 	/* Hook up PCI register/descriptor accessors. */
diff -druN linux-2.6.39-libre/drivers/net/tc35815.c linux-3.0-rc7-libre/drivers/net/tc35815.c
--- linux-2.6.39-libre/drivers/net/tc35815.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/tc35815.c	2011-07-11 19:51:52.000000000 -0400
@@ -47,6 +47,7 @@
 #include <linux/phy.h>
 #include <linux/workqueue.h>
 #include <linux/platform_device.h>
+#include <linux/prefetch.h>
 #include <asm/io.h>
 #include <asm/byteorder.h>
 
diff -druN linux-2.6.39-libre/drivers/net/tehuti.c linux-3.0-rc7-libre/drivers/net/tehuti.c
--- linux-2.6.39-libre/drivers/net/tehuti.c	2011-05-19 02:12:35.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/tehuti.c	2011-07-21 06:55:02.000000000 -0400
@@ -2017,9 +2017,11 @@
 		ndev->irq = pdev->irq;
 		ndev->features = NETIF_F_IP_CSUM | NETIF_F_SG | NETIF_F_TSO
 		    | NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX |
-		    NETIF_F_HW_VLAN_FILTER
+		    NETIF_F_HW_VLAN_FILTER | NETIF_F_RXCSUM
 		    /*| NETIF_F_FRAGLIST */
 		    ;
+		ndev->hw_features = NETIF_F_IP_CSUM | NETIF_F_SG |
+			NETIF_F_TSO | NETIF_F_HW_VLAN_TX;
 
 		if (pci_using_dac)
 			ndev->features |= NETIF_F_HIGHDMA;
@@ -2149,7 +2151,7 @@
 
 	ecmd->supported = (SUPPORTED_10000baseT_Full | SUPPORTED_FIBRE);
 	ecmd->advertising = (ADVERTISED_10000baseT_Full | ADVERTISED_FIBRE);
-	ecmd->speed = SPEED_10000;
+	ethtool_cmd_speed_set(ecmd, SPEED_10000);
 	ecmd->duplex = DUPLEX_FULL;
 	ecmd->port = PORT_FIBRE;
 	ecmd->transceiver = XCVR_EXTERNAL;	/* what does it mean? */
@@ -2188,24 +2190,6 @@
 }
 
 /*
- * bdx_get_rx_csum - report whether receive checksums are turned on or off
- * @netdev
- */
-static u32 bdx_get_rx_csum(struct net_device *netdev)
-{
-	return 1;		/* always on */
-}
-
-/*
- * bdx_get_tx_csum - report whether transmit checksums are turned on or off
- * @netdev
- */
-static u32 bdx_get_tx_csum(struct net_device *netdev)
-{
-	return (netdev->features & NETIF_F_IP_CSUM) != 0;
-}
-
-/*
  * bdx_get_coalesce - get interrupt coalescing parameters
  * @netdev
  * @ecoal
@@ -2424,10 +2408,6 @@
 		.set_coalesce = bdx_set_coalesce,
 		.get_ringparam = bdx_get_ringparam,
 		.set_ringparam = bdx_set_ringparam,
-		.get_rx_csum = bdx_get_rx_csum,
-		.get_tx_csum = bdx_get_tx_csum,
-		.get_sg = ethtool_op_get_sg,
-		.get_tso = ethtool_op_get_tso,
 		.get_strings = bdx_get_strings,
 		.get_sset_count = bdx_get_sset_count,
 		.get_ethtool_stats = bdx_get_ethtool_stats,
diff -druN linux-2.6.39-libre/drivers/net/tg3.c linux-3.0-rc7-libre/drivers/net/tg3.c
--- linux-2.6.39-libre/drivers/net/tg3.c	2011-05-19 02:12:44.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/tg3.c	2011-07-21 06:55:11.000000000 -0400
@@ -55,12 +55,36 @@
 
 #include "tg3.h"
 
+/* Functions & macros to verify TG3_FLAGS types */
+
+static inline int _tg3_flag(enum TG3_FLAGS flag, unsigned long *bits)
+{
+	return test_bit(flag, bits);
+}
+
+static inline void _tg3_flag_set(enum TG3_FLAGS flag, unsigned long *bits)
+{
+	set_bit(flag, bits);
+}
+
+static inline void _tg3_flag_clear(enum TG3_FLAGS flag, unsigned long *bits)
+{
+	clear_bit(flag, bits);
+}
+
+#define tg3_flag(tp, flag)				\
+	_tg3_flag(TG3_FLAG_##flag, (tp)->tg3_flags)
+#define tg3_flag_set(tp, flag)				\
+	_tg3_flag_set(TG3_FLAG_##flag, (tp)->tg3_flags)
+#define tg3_flag_clear(tp, flag)			\
+	_tg3_flag_clear(TG3_FLAG_##flag, (tp)->tg3_flags)
+
 #define DRV_MODULE_NAME		"tg3"
 #define TG3_MAJ_NUM			3
-#define TG3_MIN_NUM			117
+#define TG3_MIN_NUM			119
 #define DRV_MODULE_VERSION	\
 	__stringify(TG3_MAJ_NUM) "." __stringify(TG3_MIN_NUM)
-#define DRV_MODULE_RELDATE	"January 25, 2011"
+#define DRV_MODULE_RELDATE	"May 18, 2011"
 
 #define TG3_DEF_MAC_MODE	0
 #define TG3_DEF_RX_MODE		0
@@ -78,26 +102,25 @@
 /* length of time before we decide the hardware is borked,
  * and dev->tx_timeout() should be called to fix the problem
  */
+
 #define TG3_TX_TIMEOUT			(5 * HZ)
 
 /* hardware minimum and maximum for a single frame's data payload */
 #define TG3_MIN_MTU			60
 #define TG3_MAX_MTU(tp)	\
-	((tp->tg3_flags & TG3_FLAG_JUMBO_CAPABLE) ? 9000 : 1500)
+	(tg3_flag(tp, JUMBO_CAPABLE) ? 9000 : 1500)
 
 /* These numbers seem to be hard coded in the NIC firmware somehow.
  * You can't change the ring sizes, but you can change where you place
  * them in the NIC onboard memory.
  */
 #define TG3_RX_STD_RING_SIZE(tp) \
-	((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 || \
-	  GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719) ? \
-	 RX_STD_MAX_SIZE_5717 : 512)
+	(tg3_flag(tp, LRG_PROD_RING_CAP) ? \
+	 TG3_RX_STD_MAX_SIZE_5717 : TG3_RX_STD_MAX_SIZE_5700)
 #define TG3_DEF_RX_RING_PENDING		200
 #define TG3_RX_JMB_RING_SIZE(tp) \
-	((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 || \
-	  GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719) ? \
-	 1024 : 256)
+	(tg3_flag(tp, LRG_PROD_RING_CAP) ? \
+	 TG3_RX_JMB_MAX_SIZE_5717 : TG3_RX_JMB_MAX_SIZE_5700)
 #define TG3_DEF_RX_JUMBO_RING_PENDING	100
 #define TG3_RSS_INDIR_TBL_SIZE		128
 
@@ -160,11 +183,6 @@
 
 #define TG3_RAW_IP_ALIGN 2
 
-/* number of ETHTOOL_GSTATS u64's */
-#define TG3_NUM_STATS		(sizeof(struct tg3_ethtool_stats)/sizeof(u64))
-
-#define TG3_NUM_TEST		6
-
 #define TG3_FW_UPDATE_TIMEOUT_SEC	5
 
 #define FIRMWARE_TG3		"/*(DEBLOBBED)*/"
@@ -257,6 +275,7 @@
 	{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_BROADCOM, TG3PCI_DEVICE_TIGON3_5719)},
+	{PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, TG3PCI_DEVICE_TIGON3_5720)},
 	{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)},
@@ -264,6 +283,7 @@
 	{PCI_DEVICE(PCI_VENDOR_ID_ALTIMA, PCI_DEVICE_ID_ALTIMA_AC1003)},
 	{PCI_DEVICE(PCI_VENDOR_ID_ALTIMA, PCI_DEVICE_ID_ALTIMA_AC9100)},
 	{PCI_DEVICE(PCI_VENDOR_ID_APPLE, PCI_DEVICE_ID_APPLE_TIGON3)},
+	{PCI_DEVICE(0x10cf, 0x11a2)}, /* Fujitsu 1000base-SX with BCM5703SKHB */
 	{}
 };
 
@@ -271,7 +291,7 @@
 
 static const struct {
 	const char string[ETH_GSTRING_LEN];
-} ethtool_stats_keys[TG3_NUM_STATS] = {
+} ethtool_stats_keys[] = {
 	{ "rx_octets" },
 	{ "rx_fragments" },
 	{ "rx_ucast_packets" },
@@ -347,12 +367,17 @@
 	{ "ring_status_update" },
 	{ "nic_irqs" },
 	{ "nic_avoided_irqs" },
-	{ "nic_tx_threshold_hit" }
+	{ "nic_tx_threshold_hit" },
+
+	{ "mbuf_lwm_thresh_hit" },
 };
 
+#define TG3_NUM_STATS	ARRAY_SIZE(ethtool_stats_keys)
+
+
 static const struct {
 	const char string[ETH_GSTRING_LEN];
-} ethtool_test_keys[TG3_NUM_TEST] = {
+} ethtool_test_keys[] = {
 	{ "nvram test     (online) " },
 	{ "link test      (online) " },
 	{ "register test  (offline)" },
@@ -361,6 +386,9 @@
 	{ "interrupt test (offline)" },
 };
 
+#define TG3_NUM_TEST	ARRAY_SIZE(ethtool_test_keys)
+
+
 static void tg3_write32(struct tg3 *tp, u32 off, u32 val)
 {
 	writel(val, tp->regs + off);
@@ -458,8 +486,7 @@
  */
 static void _tw32_flush(struct tg3 *tp, u32 off, u32 val, u32 usec_wait)
 {
-	if ((tp->tg3_flags & TG3_FLAG_PCIX_TARGET_HWBUG) ||
-	    (tp->tg3_flags2 & TG3_FLG2_ICH_WORKAROUND))
+	if (tg3_flag(tp, PCIX_TARGET_HWBUG) || tg3_flag(tp, ICH_WORKAROUND))
 		/* Non-posted methods */
 		tp->write32(tp, off, val);
 	else {
@@ -479,8 +506,7 @@
 static inline void tw32_mailbox_flush(struct tg3 *tp, u32 off, u32 val)
 {
 	tp->write32_mbox(tp, off, val);
-	if (!(tp->tg3_flags & TG3_FLAG_MBOX_WRITE_REORDER) &&
-	    !(tp->tg3_flags2 & TG3_FLG2_ICH_WORKAROUND))
+	if (!tg3_flag(tp, MBOX_WRITE_REORDER) && !tg3_flag(tp, ICH_WORKAROUND))
 		tp->read32_mbox(tp, off);
 }
 
@@ -488,9 +514,9 @@
 {
 	void __iomem *mbox = tp->regs + off;
 	writel(val, mbox);
-	if (tp->tg3_flags & TG3_FLAG_TXD_MBOX_HWBUG)
+	if (tg3_flag(tp, TXD_MBOX_HWBUG))
 		writel(val, mbox);
-	if (tp->tg3_flags & TG3_FLAG_MBOX_WRITE_REORDER)
+	if (tg3_flag(tp, MBOX_WRITE_REORDER))
 		readl(mbox);
 }
 
@@ -519,12 +545,12 @@
 {
 	unsigned long flags;
 
-	if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) &&
+	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906 &&
 	    (off >= NIC_SRAM_STATS_BLK) && (off < NIC_SRAM_TX_BUFFER_DESC))
 		return;
 
 	spin_lock_irqsave(&tp->indirect_lock, flags);
-	if (tp->tg3_flags & TG3_FLAG_SRAM_USE_CONFIG) {
+	if (tg3_flag(tp, SRAM_USE_CONFIG)) {
 		pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_BASE_ADDR, off);
 		pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_DATA, val);
 
@@ -544,14 +570,14 @@
 {
 	unsigned long flags;
 
-	if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) &&
+	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906 &&
 	    (off >= NIC_SRAM_STATS_BLK) && (off < NIC_SRAM_TX_BUFFER_DESC)) {
 		*val = 0;
 		return;
 	}
 
 	spin_lock_irqsave(&tp->indirect_lock, flags);
-	if (tp->tg3_flags & TG3_FLAG_SRAM_USE_CONFIG) {
+	if (tg3_flag(tp, SRAM_USE_CONFIG)) {
 		pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_BASE_ADDR, off);
 		pci_read_config_dword(tp->pdev, TG3PCI_MEM_WIN_DATA, val);
 
@@ -588,7 +614,7 @@
 	int ret = 0;
 	u32 status, req, gnt;
 
-	if (!(tp->tg3_flags3 & TG3_FLG3_ENABLE_APE))
+	if (!tg3_flag(tp, ENABLE_APE))
 		return 0;
 
 	switch (locknum) {
@@ -634,7 +660,7 @@
 {
 	u32 gnt;
 
-	if (!(tp->tg3_flags3 & TG3_FLG3_ENABLE_APE))
+	if (!tg3_flag(tp, ENABLE_APE))
 		return;
 
 	switch (locknum) {
@@ -678,14 +704,14 @@
 		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)
+		if (tg3_flag(tp, 1SHOT_MSI))
 			tw32_mailbox_f(tnapi->int_mbox, tnapi->last_tag << 24);
 
 		tp->coal_now |= tnapi->coal_now;
 	}
 
 	/* Force an initial interrupt */
-	if (!(tp->tg3_flags & TG3_FLAG_TAGGED_STATUS) &&
+	if (!tg3_flag(tp, TAGGED_STATUS) &&
 	    (tp->napi[0].hw_status->status & SD_STATUS_UPDATED))
 		tw32(GRC_LOCAL_CTRL, tp->grc_local_ctrl | GRC_LCLCTRL_SETINT);
 	else
@@ -701,9 +727,7 @@
 	unsigned int work_exists = 0;
 
 	/* check for phy events */
-	if (!(tp->tg3_flags &
-	      (TG3_FLAG_USE_LINKCHG_REG |
-	       TG3_FLAG_POLL_SERDES))) {
+	if (!(tg3_flag(tp, USE_LINKCHG_REG) || tg3_flag(tp, POLL_SERDES))) {
 		if (sblk->status & SD_STATUS_LINK_CHG)
 			work_exists = 1;
 	}
@@ -731,8 +755,7 @@
 	 * The last_tag we write above tells the chip which piece of
 	 * work we've completed.
 	 */
-	if (!(tp->tg3_flags & TG3_FLAG_TAGGED_STATUS) &&
-	    tg3_has_work(tnapi))
+	if (!tg3_flag(tp, TAGGED_STATUS) && tg3_has_work(tnapi))
 		tw32(HOSTCC_MODE, tp->coalesce_mode |
 		     HOSTCC_MODE_ENABLE | tnapi->coal_now);
 }
@@ -742,8 +765,7 @@
 	u32 clock_ctrl;
 	u32 orig_clock_ctrl;
 
-	if ((tp->tg3_flags & TG3_FLAG_CPMU_PRESENT) ||
-	    (tp->tg3_flags2 & TG3_FLG2_5780_CLASS))
+	if (tg3_flag(tp, CPMU_PRESENT) || tg3_flag(tp, 5780_CLASS))
 		return;
 
 	clock_ctrl = tr32(TG3PCI_CLOCK_CTRL);
@@ -754,7 +776,7 @@
 		       0x1f);
 	tp->pci_clock_ctrl = clock_ctrl;
 
-	if (tp->tg3_flags2 & TG3_FLG2_5705_PLUS) {
+	if (tg3_flag(tp, 5705_PLUS)) {
 		if (orig_clock_ctrl & CLOCK_CTRL_625_CORE) {
 			tw32_wait_f(TG3PCI_CLOCK_CTRL,
 				    clock_ctrl | CLOCK_CTRL_625_CORE, 40);
@@ -871,6 +893,104 @@
 	return ret;
 }
 
+static int tg3_phy_cl45_write(struct tg3 *tp, u32 devad, u32 addr, u32 val)
+{
+	int err;
+
+	err = tg3_writephy(tp, MII_TG3_MMD_CTRL, devad);
+	if (err)
+		goto done;
+
+	err = tg3_writephy(tp, MII_TG3_MMD_ADDRESS, addr);
+	if (err)
+		goto done;
+
+	err = tg3_writephy(tp, MII_TG3_MMD_CTRL,
+			   MII_TG3_MMD_CTRL_DATA_NOINC | devad);
+	if (err)
+		goto done;
+
+	err = tg3_writephy(tp, MII_TG3_MMD_ADDRESS, val);
+
+done:
+	return err;
+}
+
+static int tg3_phy_cl45_read(struct tg3 *tp, u32 devad, u32 addr, u32 *val)
+{
+	int err;
+
+	err = tg3_writephy(tp, MII_TG3_MMD_CTRL, devad);
+	if (err)
+		goto done;
+
+	err = tg3_writephy(tp, MII_TG3_MMD_ADDRESS, addr);
+	if (err)
+		goto done;
+
+	err = tg3_writephy(tp, MII_TG3_MMD_CTRL,
+			   MII_TG3_MMD_CTRL_DATA_NOINC | devad);
+	if (err)
+		goto done;
+
+	err = tg3_readphy(tp, MII_TG3_MMD_ADDRESS, val);
+
+done:
+	return err;
+}
+
+static int tg3_phydsp_read(struct tg3 *tp, u32 reg, u32 *val)
+{
+	int err;
+
+	err = tg3_writephy(tp, MII_TG3_DSP_ADDRESS, reg);
+	if (!err)
+		err = tg3_readphy(tp, MII_TG3_DSP_RW_PORT, val);
+
+	return err;
+}
+
+static int tg3_phydsp_write(struct tg3 *tp, u32 reg, u32 val)
+{
+	int err;
+
+	err = tg3_writephy(tp, MII_TG3_DSP_ADDRESS, reg);
+	if (!err)
+		err = tg3_writephy(tp, MII_TG3_DSP_RW_PORT, val);
+
+	return err;
+}
+
+static int tg3_phy_auxctl_read(struct tg3 *tp, int reg, u32 *val)
+{
+	int err;
+
+	err = tg3_writephy(tp, MII_TG3_AUX_CTRL,
+			   (reg << MII_TG3_AUXCTL_MISC_RDSEL_SHIFT) |
+			   MII_TG3_AUXCTL_SHDWSEL_MISC);
+	if (!err)
+		err = tg3_readphy(tp, MII_TG3_AUX_CTRL, val);
+
+	return err;
+}
+
+static int tg3_phy_auxctl_write(struct tg3 *tp, int reg, u32 set)
+{
+	if (reg == MII_TG3_AUXCTL_SHDWSEL_MISC)
+		set |= MII_TG3_AUXCTL_MISC_WREN;
+
+	return tg3_writephy(tp, MII_TG3_AUX_CTRL, set | reg);
+}
+
+#define TG3_PHY_AUXCTL_SMDSP_ENABLE(tp) \
+	tg3_phy_auxctl_write((tp), MII_TG3_AUXCTL_SHDWSEL_AUXCTL, \
+			     MII_TG3_AUXCTL_ACTL_SMDSP_ENA | \
+			     MII_TG3_AUXCTL_ACTL_TX_6DB)
+
+#define TG3_PHY_AUXCTL_SMDSP_DISABLE(tp) \
+	tg3_phy_auxctl_write((tp), MII_TG3_AUXCTL_SHDWSEL_AUXCTL, \
+			     MII_TG3_AUXCTL_ACTL_TX_6DB);
+
 static int tg3_bmcr_reset(struct tg3 *tp)
 {
 	u32 phy_control;
@@ -973,7 +1093,7 @@
 		return;
 	}
 
-	if (!(tp->tg3_flags3 & TG3_FLG3_RGMII_INBAND_DISABLE))
+	if (!tg3_flag(tp, RGMII_INBAND_DISABLE))
 		val |= MAC_PHYCFG2_EMODE_MASK_MASK |
 		       MAC_PHYCFG2_FMODE_MASK_MASK |
 		       MAC_PHYCFG2_GMODE_MASK_MASK |
@@ -986,10 +1106,10 @@
 	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_INBAND_DISABLE)) {
-		if (tp->tg3_flags3 & TG3_FLG3_RGMII_EXT_IBND_RX_EN)
+	if (!tg3_flag(tp, RGMII_INBAND_DISABLE)) {
+		if (tg3_flag(tp, RGMII_EXT_IBND_RX_EN))
 			val |= MAC_PHYCFG1_RGMII_EXT_RX_DEC;
-		if (tp->tg3_flags3 & TG3_FLG3_RGMII_EXT_IBND_TX_EN)
+		if (tg3_flag(tp, RGMII_EXT_IBND_TX_EN))
 			val |= MAC_PHYCFG1_RGMII_SND_STAT_EN;
 	}
 	val |= MAC_PHYCFG1_RXCLK_TIMEOUT | MAC_PHYCFG1_TXCLK_TIMEOUT |
@@ -1004,13 +1124,13 @@
 		 MAC_RGMII_MODE_TX_ENABLE |
 		 MAC_RGMII_MODE_TX_LOWPWR |
 		 MAC_RGMII_MODE_TX_RESET);
-	if (!(tp->tg3_flags3 & TG3_FLG3_RGMII_INBAND_DISABLE)) {
-		if (tp->tg3_flags3 & TG3_FLG3_RGMII_EXT_IBND_RX_EN)
+	if (!tg3_flag(tp, RGMII_INBAND_DISABLE)) {
+		if (tg3_flag(tp, RGMII_EXT_IBND_RX_EN))
 			val |= MAC_RGMII_MODE_RX_INT_B |
 			       MAC_RGMII_MODE_RX_QUALITY |
 			       MAC_RGMII_MODE_RX_ACTIVITY |
 			       MAC_RGMII_MODE_RX_ENG_DET;
-		if (tp->tg3_flags3 & TG3_FLG3_RGMII_EXT_IBND_TX_EN)
+		if (tg3_flag(tp, RGMII_EXT_IBND_TX_EN))
 			val |= MAC_RGMII_MODE_TX_ENABLE |
 			       MAC_RGMII_MODE_TX_LOWPWR |
 			       MAC_RGMII_MODE_TX_RESET;
@@ -1024,7 +1144,7 @@
 	tw32_f(MAC_MI_MODE, tp->mi_mode);
 	udelay(80);
 
-	if ((tp->tg3_flags3 & TG3_FLG3_MDIOBUS_INITED) &&
+	if (tg3_flag(tp, MDIOBUS_INITED) &&
 	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5785)
 		tg3_mdio_config_5785(tp);
 }
@@ -1035,8 +1155,7 @@
 	u32 reg;
 	struct phy_device *phydev;
 
-	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 ||
-	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719) {
+	if (tg3_flag(tp, 5717_PLUS)) {
 		u32 is_serdes;
 
 		tp->phy_addr = PCI_FUNC(tp->pdev->devfn) + 1;
@@ -1053,8 +1172,7 @@
 
 	tg3_mdio_start(tp);
 
-	if (!(tp->tg3_flags3 & TG3_FLG3_USE_PHYLIB) ||
-	    (tp->tg3_flags3 & TG3_FLG3_MDIOBUS_INITED))
+	if (!tg3_flag(tp, USE_PHYLIB) || tg3_flag(tp, MDIOBUS_INITED))
 		return 0;
 
 	tp->mdio_bus = mdiobus_alloc();
@@ -1110,11 +1228,11 @@
 				     PHY_BRCM_RX_REFCLK_UNUSED |
 				     PHY_BRCM_DIS_TXCRXC_NOENRGY |
 				     PHY_BRCM_AUTO_PWRDWN_ENABLE;
-		if (tp->tg3_flags3 & TG3_FLG3_RGMII_INBAND_DISABLE)
+		if (tg3_flag(tp, RGMII_INBAND_DISABLE))
 			phydev->dev_flags |= PHY_BRCM_STD_IBND_DISABLE;
-		if (tp->tg3_flags3 & TG3_FLG3_RGMII_EXT_IBND_RX_EN)
+		if (tg3_flag(tp, 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)
+		if (tg3_flag(tp, RGMII_EXT_IBND_TX_EN))
 			phydev->dev_flags |= PHY_BRCM_EXT_IBND_TX_ENABLE;
 		/* fallthru */
 	case PHY_ID_RTL8211C:
@@ -1128,7 +1246,7 @@
 		break;
 	}
 
-	tp->tg3_flags3 |= TG3_FLG3_MDIOBUS_INITED;
+	tg3_flag_set(tp, MDIOBUS_INITED);
 
 	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5785)
 		tg3_mdio_config_5785(tp);
@@ -1138,59 +1256,13 @@
 
 static void tg3_mdio_fini(struct tg3 *tp)
 {
-	if (tp->tg3_flags3 & TG3_FLG3_MDIOBUS_INITED) {
-		tp->tg3_flags3 &= ~TG3_FLG3_MDIOBUS_INITED;
+	if (tg3_flag(tp, MDIOBUS_INITED)) {
+		tg3_flag_clear(tp, MDIOBUS_INITED);
 		mdiobus_unregister(tp->mdio_bus);
 		mdiobus_free(tp->mdio_bus);
 	}
 }
 
-static int tg3_phy_cl45_write(struct tg3 *tp, u32 devad, u32 addr, u32 val)
-{
-	int err;
-
-	err = tg3_writephy(tp, MII_TG3_MMD_CTRL, devad);
-	if (err)
-		goto done;
-
-	err = tg3_writephy(tp, MII_TG3_MMD_ADDRESS, addr);
-	if (err)
-		goto done;
-
-	err = tg3_writephy(tp, MII_TG3_MMD_CTRL,
-			   MII_TG3_MMD_CTRL_DATA_NOINC | devad);
-	if (err)
-		goto done;
-
-	err = tg3_writephy(tp, MII_TG3_MMD_ADDRESS, val);
-
-done:
-	return err;
-}
-
-static int tg3_phy_cl45_read(struct tg3 *tp, u32 devad, u32 addr, u32 *val)
-{
-	int err;
-
-	err = tg3_writephy(tp, MII_TG3_MMD_CTRL, devad);
-	if (err)
-		goto done;
-
-	err = tg3_writephy(tp, MII_TG3_MMD_ADDRESS, addr);
-	if (err)
-		goto done;
-
-	err = tg3_writephy(tp, MII_TG3_MMD_CTRL,
-			   MII_TG3_MMD_CTRL_DATA_NOINC | devad);
-	if (err)
-		goto done;
-
-	err = tg3_readphy(tp, MII_TG3_MMD_ADDRESS, val);
-
-done:
-	return err;
-}
-
 /* tp->lock is held. */
 static inline void tg3_generate_fw_event(struct tg3 *tp)
 {
@@ -1238,8 +1310,7 @@
 	u32 reg;
 	u32 val;
 
-	if (!(tp->tg3_flags2 & TG3_FLG2_5780_CLASS) ||
-	    !(tp->tg3_flags  & TG3_FLAG_ENABLE_ASF))
+	if (!tg3_flag(tp, 5780_CLASS) || !tg3_flag(tp, ENABLE_ASF))
 		return;
 
 	tg3_wait_for_event_ack(tp);
@@ -1299,6 +1370,11 @@
 			    "on" : "off",
 			    (tp->link_config.active_flowctrl & FLOW_CTRL_RX) ?
 			    "on" : "off");
+
+		if (tp->phy_flags & TG3_PHYFLG_EEE_CAP)
+			netdev_info(tp->dev, "EEE is %s\n",
+				    tp->setlpicnt ? "enabled" : "disabled");
+
 		tg3_ump_link_report(tp);
 	}
 }
@@ -1364,13 +1440,12 @@
 	u32 old_rx_mode = tp->rx_mode;
 	u32 old_tx_mode = tp->tx_mode;
 
-	if (tp->tg3_flags3 & TG3_FLG3_USE_PHYLIB)
+	if (tg3_flag(tp, USE_PHYLIB))
 		autoneg = tp->mdio_bus->phy_map[TG3_PHY_MII_ADDR]->autoneg;
 	else
 		autoneg = tp->link_config.autoneg;
 
-	if (autoneg == AUTONEG_ENABLE &&
-	    (tp->tg3_flags & TG3_FLAG_PAUSE_AUTONEG)) {
+	if (autoneg == AUTONEG_ENABLE && tg3_flag(tp, PAUSE_AUTONEG)) {
 		if (tp->phy_flags & TG3_PHYFLG_ANY_SERDES)
 			flowctrl = tg3_resolve_flowctrl_1000X(lcladv, rmtadv);
 		else
@@ -1567,28 +1642,6 @@
 	}
 }
 
-static int tg3_phydsp_read(struct tg3 *tp, u32 reg, u32 *val)
-{
-	int err;
-
-	err = tg3_writephy(tp, MII_TG3_DSP_ADDRESS, reg);
-	if (!err)
-		err = tg3_readphy(tp, MII_TG3_DSP_RW_PORT, val);
-
-	return err;
-}
-
-static int tg3_phydsp_write(struct tg3 *tp, u32 reg, u32 val)
-{
-	int err;
-
-	err = tg3_writephy(tp, MII_TG3_DSP_ADDRESS, reg);
-	if (!err)
-		err = tg3_writephy(tp, MII_TG3_DSP_RW_PORT, val);
-
-	return err;
-}
-
 static void tg3_phy_fet_toggle_apd(struct tg3 *tp, bool enable)
 {
 	u32 phytest;
@@ -1613,9 +1666,8 @@
 {
 	u32 reg;
 
-	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_5719) &&
+	if (!tg3_flag(tp, 5705_PLUS) ||
+	    (tg3_flag(tp, 5717_PLUS) &&
 	     (tp->phy_flags & TG3_PHYFLG_MII_SERDES)))
 		return;
 
@@ -1649,7 +1701,7 @@
 {
 	u32 phy;
 
-	if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS) ||
+	if (!tg3_flag(tp, 5705_PLUS) ||
 	    (tp->phy_flags & TG3_PHYFLG_ANY_SERDES))
 		return;
 
@@ -1671,31 +1723,33 @@
 			tg3_writephy(tp, MII_TG3_FET_TEST, ephy);
 		}
 	} else {
-		phy = MII_TG3_AUXCTL_MISC_RDSEL_MISC |
-		      MII_TG3_AUXCTL_SHDWSEL_MISC;
-		if (!tg3_writephy(tp, MII_TG3_AUX_CTRL, phy) &&
-		    !tg3_readphy(tp, MII_TG3_AUX_CTRL, &phy)) {
+		int ret;
+
+		ret = tg3_phy_auxctl_read(tp,
+					  MII_TG3_AUXCTL_SHDWSEL_MISC, &phy);
+		if (!ret) {
 			if (enable)
 				phy |= MII_TG3_AUXCTL_MISC_FORCE_AMDIX;
 			else
 				phy &= ~MII_TG3_AUXCTL_MISC_FORCE_AMDIX;
-			phy |= MII_TG3_AUXCTL_MISC_WREN;
-			tg3_writephy(tp, MII_TG3_AUX_CTRL, phy);
+			tg3_phy_auxctl_write(tp,
+					     MII_TG3_AUXCTL_SHDWSEL_MISC, phy);
 		}
 	}
 }
 
 static void tg3_phy_set_wirespeed(struct tg3 *tp)
 {
+	int ret;
 	u32 val;
 
 	if (tp->phy_flags & TG3_PHYFLG_NO_ETH_WIRE_SPEED)
 		return;
 
-	if (!tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x7007) &&
-	    !tg3_readphy(tp, MII_TG3_AUX_CTRL, &val))
-		tg3_writephy(tp, MII_TG3_AUX_CTRL,
-			     (val | (1 << 15) | (1 << 4)));
+	ret = tg3_phy_auxctl_read(tp, MII_TG3_AUXCTL_SHDWSEL_MISC, &val);
+	if (!ret)
+		tg3_phy_auxctl_write(tp, MII_TG3_AUXCTL_SHDWSEL_MISC,
+				     val | MII_TG3_AUXCTL_MISC_WIRESPD_EN);
 }
 
 static void tg3_phy_apply_otp(struct tg3 *tp)
@@ -1707,11 +1761,8 @@
 
 	otp = tp->phy_otp;
 
-	/* Enable SM_DSP clock and tx 6dB coding. */
-	phy = MII_TG3_AUXCTL_SHDWSEL_AUXCTL |
-	      MII_TG3_AUXCTL_ACTL_SMDSP_ENA |
-	      MII_TG3_AUXCTL_ACTL_TX_6DB;
-	tg3_writephy(tp, MII_TG3_AUX_CTRL, phy);
+	if (TG3_PHY_AUXCTL_SMDSP_ENABLE(tp))
+		return;
 
 	phy = ((otp & TG3_OTP_AGCTGT_MASK) >> TG3_OTP_AGCTGT_SHIFT);
 	phy |= MII_TG3_DSP_TAP1_AGCTGT_DFLT;
@@ -1735,10 +1786,7 @@
 	      ((otp & TG3_OTP_RCOFF_MASK) >> TG3_OTP_RCOFF_SHIFT);
 	tg3_phydsp_write(tp, MII_TG3_DSP_EXP97, phy);
 
-	/* Turn off SM_DSP clock. */
-	phy = MII_TG3_AUXCTL_SHDWSEL_AUXCTL |
-	      MII_TG3_AUXCTL_ACTL_TX_6DB;
-	tg3_writephy(tp, MII_TG3_AUX_CTRL, phy);
+	TG3_PHY_AUXCTL_SMDSP_DISABLE(tp);
 }
 
 static void tg3_phy_eee_adjust(struct tg3 *tp, u32 current_link_up)
@@ -1767,29 +1815,9 @@
 		tg3_phy_cl45_read(tp, MDIO_MMD_AN,
 				  TG3_CL45_D7_EEERES_STAT, &val);
 
-		switch (val) {
-		case TG3_CL45_D7_EEERES_STAT_LP_1000T:
-			switch (GET_ASIC_REV(tp->pci_chip_rev_id)) {
-			case ASIC_REV_5717:
-			case ASIC_REV_5719:
-			case ASIC_REV_57765:
-				/* Enable SM_DSP clock and tx 6dB coding. */
-				val = MII_TG3_AUXCTL_SHDWSEL_AUXCTL |
-				      MII_TG3_AUXCTL_ACTL_SMDSP_ENA |
-				      MII_TG3_AUXCTL_ACTL_TX_6DB;
-				tg3_writephy(tp, MII_TG3_AUX_CTRL, val);
-
-				tg3_phydsp_write(tp, MII_TG3_DSP_TAP26, 0x0000);
-
-				/* Turn off SM_DSP clock. */
-				val = MII_TG3_AUXCTL_SHDWSEL_AUXCTL |
-				      MII_TG3_AUXCTL_ACTL_TX_6DB;
-				tg3_writephy(tp, MII_TG3_AUX_CTRL, val);
-			}
-			/* Fallthrough */
-		case TG3_CL45_D7_EEERES_STAT_LP_100TX:
+		if (val == TG3_CL45_D7_EEERES_STAT_LP_1000T ||
+		    val == TG3_CL45_D7_EEERES_STAT_LP_100TX)
 			tp->setlpicnt = 2;
-		}
 	}
 
 	if (!tp->setlpicnt) {
@@ -1798,6 +1826,23 @@
 	}
 }
 
+static void tg3_phy_eee_enable(struct tg3 *tp)
+{
+	u32 val;
+
+	if (tp->link_config.active_speed == SPEED_1000 &&
+	    (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 ||
+	     GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719 ||
+	     GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765) &&
+	    !TG3_PHY_AUXCTL_SMDSP_ENABLE(tp)) {
+		tg3_phydsp_write(tp, MII_TG3_DSP_TAP26, 0x0003);
+		TG3_PHY_AUXCTL_SMDSP_DISABLE(tp);
+	}
+
+	val = tr32(TG3_CPMU_EEE_MODE);
+	tw32(TG3_CPMU_EEE_MODE, val | TG3_CPMU_EEEMD_LPI_ENABLE);
+}
+
 static int tg3_wait_macro_done(struct tg3 *tp)
 {
 	int limit = 100;
@@ -1936,8 +1981,9 @@
 			     (MII_TG3_CTRL_AS_MASTER |
 			      MII_TG3_CTRL_ENABLE_AS_MASTER));
 
-		/* Enable SM_DSP_CLOCK and 6dB.  */
-		tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x0c00);
+		err = TG3_PHY_AUXCTL_SMDSP_ENABLE(tp);
+		if (err)
+			return err;
 
 		/* Block the PHY control access.  */
 		tg3_phydsp_write(tp, 0x8005, 0x0800);
@@ -1956,13 +2002,7 @@
 	tg3_writephy(tp, MII_TG3_DSP_ADDRESS, 0x8200);
 	tg3_writephy(tp, MII_TG3_DSP_CONTROL, 0x0000);
 
-	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5703 ||
-	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704) {
-		/* Set Extended packet length bit for jumbo frames */
-		tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x4400);
-	} else {
-		tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x0400);
-	}
+	TG3_PHY_AUXCTL_SMDSP_DISABLE(tp);
 
 	tg3_writephy(tp, MII_TG3_CTRL, phy9_orig);
 
@@ -2038,8 +2078,7 @@
 		}
 	}
 
-	if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 ||
-	     GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719) &&
+	if (tg3_flag(tp, 5717_PLUS) &&
 	    (tp->phy_flags & TG3_PHYFLG_MII_SERDES))
 		return 0;
 
@@ -2051,49 +2090,57 @@
 		tg3_phy_toggle_apd(tp, false);
 
 out:
-	if (tp->phy_flags & TG3_PHYFLG_ADC_BUG) {
-		tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x0c00);
+	if ((tp->phy_flags & TG3_PHYFLG_ADC_BUG) &&
+	    !TG3_PHY_AUXCTL_SMDSP_ENABLE(tp)) {
 		tg3_phydsp_write(tp, 0x201f, 0x2aaa);
 		tg3_phydsp_write(tp, 0x000a, 0x0323);
-		tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x0400);
+		TG3_PHY_AUXCTL_SMDSP_DISABLE(tp);
 	}
+
 	if (tp->phy_flags & TG3_PHYFLG_5704_A0_BUG) {
 		tg3_writephy(tp, MII_TG3_MISC_SHDW, 0x8d68);
 		tg3_writephy(tp, MII_TG3_MISC_SHDW, 0x8d68);
 	}
+
 	if (tp->phy_flags & TG3_PHYFLG_BER_BUG) {
-		tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x0c00);
-		tg3_phydsp_write(tp, 0x000a, 0x310b);
-		tg3_phydsp_write(tp, 0x201f, 0x9506);
-		tg3_phydsp_write(tp, 0x401f, 0x14e2);
-		tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x0400);
+		if (!TG3_PHY_AUXCTL_SMDSP_ENABLE(tp)) {
+			tg3_phydsp_write(tp, 0x000a, 0x310b);
+			tg3_phydsp_write(tp, 0x201f, 0x9506);
+			tg3_phydsp_write(tp, 0x401f, 0x14e2);
+			TG3_PHY_AUXCTL_SMDSP_DISABLE(tp);
+		}
 	} else if (tp->phy_flags & TG3_PHYFLG_JITTER_BUG) {
-		tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x0c00);
-		tg3_writephy(tp, MII_TG3_DSP_ADDRESS, 0x000a);
-		if (tp->phy_flags & TG3_PHYFLG_ADJUST_TRIM) {
-			tg3_writephy(tp, MII_TG3_DSP_RW_PORT, 0x110b);
-			tg3_writephy(tp, MII_TG3_TEST1,
-				     MII_TG3_TEST1_TRIM_EN | 0x4);
-		} else
-			tg3_writephy(tp, MII_TG3_DSP_RW_PORT, 0x010b);
-		tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x0400);
+		if (!TG3_PHY_AUXCTL_SMDSP_ENABLE(tp)) {
+			tg3_writephy(tp, MII_TG3_DSP_ADDRESS, 0x000a);
+			if (tp->phy_flags & TG3_PHYFLG_ADJUST_TRIM) {
+				tg3_writephy(tp, MII_TG3_DSP_RW_PORT, 0x110b);
+				tg3_writephy(tp, MII_TG3_TEST1,
+					     MII_TG3_TEST1_TRIM_EN | 0x4);
+			} else
+				tg3_writephy(tp, MII_TG3_DSP_RW_PORT, 0x010b);
+
+			TG3_PHY_AUXCTL_SMDSP_DISABLE(tp);
+		}
 	}
+
 	/* Set Extended packet length bit (bit 14) on all chips that */
 	/* support jumbo frames */
 	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) {
+		tg3_phy_auxctl_write(tp, MII_TG3_AUXCTL_SHDWSEL_AUXCTL, 0x4c20);
+	} else if (tg3_flag(tp, JUMBO_CAPABLE)) {
 		/* Set bit 14 with read-modify-write to preserve other bits */
-		if (!tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x0007) &&
-		    !tg3_readphy(tp, MII_TG3_AUX_CTRL, &val))
-			tg3_writephy(tp, MII_TG3_AUX_CTRL, val | 0x4000);
+		err = tg3_phy_auxctl_read(tp,
+					  MII_TG3_AUXCTL_SHDWSEL_AUXCTL, &val);
+		if (!err)
+			tg3_phy_auxctl_write(tp, MII_TG3_AUXCTL_SHDWSEL_AUXCTL,
+					   val | MII_TG3_AUXCTL_ACTL_EXTPKTLEN);
 	}
 
 	/* Set phy register 0x10 bit 0 to high fifo elasticity to support
 	 * jumbo frames transmission.
 	 */
-	if (tp->tg3_flags & TG3_FLAG_JUMBO_CAPABLE) {
+	if (tg3_flag(tp, JUMBO_CAPABLE)) {
 		if (!tg3_readphy(tp, MII_TG3_EXT_CTRL, &val))
 			tg3_writephy(tp, MII_TG3_EXT_CTRL,
 				     val | MII_TG3_EXT_CTRL_FIFO_ELASTIC);
@@ -2114,14 +2161,15 @@
 	bool need_vaux = false;
 
 	/* The GPIOs do something completely different on 57765. */
-	if ((tp->tg3_flags2 & TG3_FLG2_IS_NIC) == 0 ||
+	if (!tg3_flag(tp, IS_NIC) ||
 	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719 ||
 	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765)
 		return;
 
 	if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704 ||
 	     GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5714 ||
-	     GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717) &&
+	     GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 ||
+	     GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5720) &&
 	    tp->pdev_peer != tp->pdev) {
 		struct net_device *dev_peer;
 
@@ -2131,17 +2179,16 @@
 		if (dev_peer) {
 			struct tg3 *tp_peer = netdev_priv(dev_peer);
 
-			if (tp_peer->tg3_flags & TG3_FLAG_INIT_COMPLETE)
+			if (tg3_flag(tp_peer, INIT_COMPLETE))
 				return;
 
-			if ((tp_peer->tg3_flags & TG3_FLAG_WOL_ENABLE) ||
-			    (tp_peer->tg3_flags & TG3_FLAG_ENABLE_ASF))
+			if (tg3_flag(tp_peer, WOL_ENABLE) ||
+			    tg3_flag(tp_peer, ENABLE_ASF))
 				need_vaux = true;
 		}
 	}
 
-	if ((tp->tg3_flags & TG3_FLAG_WOL_ENABLE) ||
-	    (tp->tg3_flags & TG3_FLAG_ENABLE_ASF))
+	if (tg3_flag(tp, WOL_ENABLE) || tg3_flag(tp, ENABLE_ASF))
 		need_vaux = true;
 
 	if (need_vaux) {
@@ -2295,11 +2342,10 @@
 		tg3_writephy(tp, MII_TG3_EXT_CTRL,
 			     MII_TG3_EXT_CTRL_FORCE_LED_OFF);
 
-		tg3_writephy(tp, MII_TG3_AUX_CTRL,
-			     MII_TG3_AUXCTL_SHDWSEL_PWRCTL |
-			     MII_TG3_AUXCTL_PCTL_100TX_LPWR |
-			     MII_TG3_AUXCTL_PCTL_SPR_ISOLATE |
-			     MII_TG3_AUXCTL_PCTL_VREG_11V);
+		val = MII_TG3_AUXCTL_PCTL_100TX_LPWR |
+		      MII_TG3_AUXCTL_PCTL_SPR_ISOLATE |
+		      MII_TG3_AUXCTL_PCTL_VREG_11V;
+		tg3_phy_auxctl_write(tp, MII_TG3_AUXCTL_SHDWSEL_PWRCTL, val);
 	}
 
 	/* The PHY should not be powered down on some chips because
@@ -2325,7 +2371,7 @@
 /* tp->lock is held. */
 static int tg3_nvram_lock(struct tg3 *tp)
 {
-	if (tp->tg3_flags & TG3_FLAG_NVRAM) {
+	if (tg3_flag(tp, NVRAM)) {
 		int i;
 
 		if (tp->nvram_lock_cnt == 0) {
@@ -2348,7 +2394,7 @@
 /* tp->lock is held. */
 static void tg3_nvram_unlock(struct tg3 *tp)
 {
-	if (tp->tg3_flags & TG3_FLAG_NVRAM) {
+	if (tg3_flag(tp, NVRAM)) {
 		if (tp->nvram_lock_cnt > 0)
 			tp->nvram_lock_cnt--;
 		if (tp->nvram_lock_cnt == 0)
@@ -2359,8 +2405,7 @@
 /* tp->lock is held. */
 static void tg3_enable_nvram_access(struct tg3 *tp)
 {
-	if ((tp->tg3_flags2 & TG3_FLG2_5750_PLUS) &&
-	    !(tp->tg3_flags3 & TG3_FLG3_PROTECTED_NVRAM)) {
+	if (tg3_flag(tp, 5750_PLUS) && !tg3_flag(tp, PROTECTED_NVRAM)) {
 		u32 nvaccess = tr32(NVRAM_ACCESS);
 
 		tw32(NVRAM_ACCESS, nvaccess | ACCESS_ENABLE);
@@ -2370,8 +2415,7 @@
 /* tp->lock is held. */
 static void tg3_disable_nvram_access(struct tg3 *tp)
 {
-	if ((tp->tg3_flags2 & TG3_FLG2_5750_PLUS) &&
-	    !(tp->tg3_flags3 & TG3_FLG3_PROTECTED_NVRAM)) {
+	if (tg3_flag(tp, 5750_PLUS) && !tg3_flag(tp, PROTECTED_NVRAM)) {
 		u32 nvaccess = tr32(NVRAM_ACCESS);
 
 		tw32(NVRAM_ACCESS, nvaccess & ~ACCESS_ENABLE);
@@ -2441,10 +2485,10 @@
 
 static u32 tg3_nvram_phys_addr(struct tg3 *tp, u32 addr)
 {
-	if ((tp->tg3_flags & TG3_FLAG_NVRAM) &&
-	    (tp->tg3_flags & TG3_FLAG_NVRAM_BUFFERED) &&
-	    (tp->tg3_flags2 & TG3_FLG2_FLASH) &&
-	   !(tp->tg3_flags3 & TG3_FLG3_NO_NVRAM_ADDR_TRANS) &&
+	if (tg3_flag(tp, NVRAM) &&
+	    tg3_flag(tp, NVRAM_BUFFERED) &&
+	    tg3_flag(tp, FLASH) &&
+	    !tg3_flag(tp, NO_NVRAM_ADDR_TRANS) &&
 	    (tp->nvram_jedecnum == JEDEC_ATMEL))
 
 		addr = ((addr / tp->nvram_pagesize) <<
@@ -2456,10 +2500,10 @@
 
 static u32 tg3_nvram_logical_addr(struct tg3 *tp, u32 addr)
 {
-	if ((tp->tg3_flags & TG3_FLAG_NVRAM) &&
-	    (tp->tg3_flags & TG3_FLAG_NVRAM_BUFFERED) &&
-	    (tp->tg3_flags2 & TG3_FLG2_FLASH) &&
-	   !(tp->tg3_flags3 & TG3_FLG3_NO_NVRAM_ADDR_TRANS) &&
+	if (tg3_flag(tp, NVRAM) &&
+	    tg3_flag(tp, NVRAM_BUFFERED) &&
+	    tg3_flag(tp, FLASH) &&
+	    !tg3_flag(tp, NO_NVRAM_ADDR_TRANS) &&
 	    (tp->nvram_jedecnum == JEDEC_ATMEL))
 
 		addr = ((addr >> ATMEL_AT45DB0X1B_PAGE_POS) *
@@ -2479,7 +2523,7 @@
 {
 	int ret;
 
-	if (!(tp->tg3_flags & TG3_FLAG_NVRAM))
+	if (!tg3_flag(tp, NVRAM))
 		return tg3_nvram_read_using_eeprom(tp, offset, val);
 
 	offset = tg3_nvram_phys_addr(tp, offset);
@@ -2571,7 +2615,7 @@
 	pci_set_power_state(tp->pdev, PCI_D0);
 
 	/* Switch out of Vaux if it is a NIC */
-	if (tp->tg3_flags2 & TG3_FLG2_IS_NIC)
+	if (tg3_flag(tp, IS_NIC))
 		tw32_wait_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl, 100);
 
 	return 0;
@@ -2585,7 +2629,7 @@
 	tg3_enable_register_access(tp);
 
 	/* Restore the CLKREQ setting. */
-	if (tp->tg3_flags3 & TG3_FLG3_CLKREQ_BUG) {
+	if (tg3_flag(tp, CLKREQ_BUG)) {
 		u16 lnkctl;
 
 		pci_read_config_word(tp->pdev,
@@ -2602,9 +2646,9 @@
 	     misc_host_ctrl | MISC_HOST_CTRL_MASK_PCI_INT);
 
 	device_should_wake = device_may_wakeup(&tp->pdev->dev) &&
-			     (tp->tg3_flags & TG3_FLAG_WOL_ENABLE);
+			     tg3_flag(tp, WOL_ENABLE);
 
-	if (tp->tg3_flags3 & TG3_FLG3_USE_PHYLIB) {
+	if (tg3_flag(tp, USE_PHYLIB)) {
 		do_low_power = false;
 		if ((tp->phy_flags & TG3_PHYFLG_IS_CONNECTED) &&
 		    !(tp->phy_flags & TG3_PHYFLG_IS_LOW_POWER)) {
@@ -2625,9 +2669,8 @@
 				      ADVERTISED_Autoneg |
 				      ADVERTISED_10baseT_Half;
 
-			if ((tp->tg3_flags & TG3_FLAG_ENABLE_ASF) ||
-			    device_should_wake) {
-				if (tp->tg3_flags & TG3_FLAG_WOL_SPEED_100MB)
+			if (tg3_flag(tp, ENABLE_ASF) || device_should_wake) {
+				if (tg3_flag(tp, WOL_SPEED_100MB))
 					advertising |=
 						ADVERTISED_100baseT_Half |
 						ADVERTISED_100baseT_Full |
@@ -2672,7 +2715,7 @@
 
 		val = tr32(GRC_VCPU_EXT_CTRL);
 		tw32(GRC_VCPU_EXT_CTRL, val | GRC_VCPU_EXT_CTRL_DISABLE_WOL);
-	} else if (!(tp->tg3_flags & TG3_FLAG_ENABLE_ASF)) {
+	} else if (!tg3_flag(tp, ENABLE_ASF)) {
 		int i;
 		u32 val;
 
@@ -2683,7 +2726,7 @@
 			msleep(1);
 		}
 	}
-	if (tp->tg3_flags & TG3_FLAG_WOL_CAP)
+	if (tg3_flag(tp, WOL_CAP))
 		tg3_write_mem(tp, NIC_SRAM_WOL_MBOX, WOL_SIGNATURE |
 						     WOL_DRV_STATE_SHUTDOWN |
 						     WOL_DRV_WOL |
@@ -2693,8 +2736,13 @@
 		u32 mac_mode;
 
 		if (!(tp->phy_flags & TG3_PHYFLG_PHY_SERDES)) {
-			if (do_low_power) {
-				tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x5a);
+			if (do_low_power &&
+			    !(tp->phy_flags & TG3_PHYFLG_IS_FET)) {
+				tg3_phy_auxctl_write(tp,
+					       MII_TG3_AUXCTL_SHDWSEL_PWRCTL,
+					       MII_TG3_AUXCTL_PCTL_WOL_EN |
+					       MII_TG3_AUXCTL_PCTL_100TX_LPWR |
+					       MII_TG3_AUXCTL_PCTL_CL_AB_TXDAC);
 				udelay(40);
 			}
 
@@ -2706,8 +2754,7 @@
 			mac_mode |= tp->mac_mode & MAC_MODE_LINK_POLARITY;
 			if (GET_ASIC_REV(tp->pci_chip_rev_id) ==
 			    ASIC_REV_5700) {
-				u32 speed = (tp->tg3_flags &
-					     TG3_FLAG_WOL_SPEED_100MB) ?
+				u32 speed = tg3_flag(tp, WOL_SPEED_100MB) ?
 					     SPEED_100 : SPEED_10;
 				if (tg3_5700_link_polarity(tp, speed))
 					mac_mode |= MAC_MODE_LINK_POLARITY;
@@ -2718,17 +2765,15 @@
 			mac_mode = MAC_MODE_PORT_MODE_TBI;
 		}
 
-		if (!(tp->tg3_flags2 & TG3_FLG2_5750_PLUS))
+		if (!tg3_flag(tp, 5750_PLUS))
 			tw32(MAC_LED_CTRL, tp->led_ctrl);
 
 		mac_mode |= MAC_MODE_MAGIC_PKT_ENABLE;
-		if (((tp->tg3_flags2 & TG3_FLG2_5705_PLUS) &&
-		    !(tp->tg3_flags2 & TG3_FLG2_5780_CLASS)) &&
-		    ((tp->tg3_flags & TG3_FLAG_ENABLE_ASF) ||
-		     (tp->tg3_flags3 & TG3_FLG3_ENABLE_APE)))
+		if ((tg3_flag(tp, 5705_PLUS) && !tg3_flag(tp, 5780_CLASS)) &&
+		    (tg3_flag(tp, ENABLE_ASF) || tg3_flag(tp, ENABLE_APE)))
 			mac_mode |= MAC_MODE_KEEP_FRAME_IN_WOL;
 
-		if (tp->tg3_flags3 & TG3_FLG3_ENABLE_APE)
+		if (tg3_flag(tp, ENABLE_APE))
 			mac_mode |= MAC_MODE_APE_TX_EN |
 				    MAC_MODE_APE_RX_EN |
 				    MAC_MODE_TDE_ENABLE;
@@ -2740,7 +2785,7 @@
 		udelay(10);
 	}
 
-	if (!(tp->tg3_flags & TG3_FLAG_WOL_SPEED_100MB) &&
+	if (!tg3_flag(tp, WOL_SPEED_100MB) &&
 	    (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700 ||
 	     GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5701)) {
 		u32 base_val;
@@ -2751,12 +2796,11 @@
 
 		tw32_wait_f(TG3PCI_CLOCK_CTRL, base_val | CLOCK_CTRL_ALTCLK |
 			    CLOCK_CTRL_PWRDOWN_PLL133, 40);
-	} else if ((tp->tg3_flags2 & TG3_FLG2_5780_CLASS) ||
-		   (tp->tg3_flags & TG3_FLAG_CPMU_PRESENT) ||
-		   (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906)) {
+	} else if (tg3_flag(tp, 5780_CLASS) ||
+		   tg3_flag(tp, CPMU_PRESENT) ||
+		   GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) {
 		/* do nothing */
-	} else if (!((tp->tg3_flags2 & TG3_FLG2_5750_PLUS) &&
-		     (tp->tg3_flags & TG3_FLAG_ENABLE_ASF))) {
+	} else if (!(tg3_flag(tp, 5750_PLUS) && tg3_flag(tp, ENABLE_ASF))) {
 		u32 newbits1, newbits2;
 
 		if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700 ||
@@ -2765,7 +2809,7 @@
 				    CLOCK_CTRL_TXCLK_DISABLE |
 				    CLOCK_CTRL_ALTCLK);
 			newbits2 = newbits1 | CLOCK_CTRL_44MHZ_CORE;
-		} else if (tp->tg3_flags2 & TG3_FLG2_5705_PLUS) {
+		} else if (tg3_flag(tp, 5705_PLUS)) {
 			newbits1 = CLOCK_CTRL_625_CORE;
 			newbits2 = newbits1 | CLOCK_CTRL_ALTCLK;
 		} else {
@@ -2779,7 +2823,7 @@
 		tw32_wait_f(TG3PCI_CLOCK_CTRL, tp->pci_clock_ctrl | newbits2,
 			    40);
 
-		if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS)) {
+		if (!tg3_flag(tp, 5705_PLUS)) {
 			u32 newbits3;
 
 			if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700 ||
@@ -2796,8 +2840,7 @@
 		}
 	}
 
-	if (!(device_should_wake) &&
-	    !(tp->tg3_flags & TG3_FLAG_ENABLE_ASF))
+	if (!(device_should_wake) && !tg3_flag(tp, ENABLE_ASF))
 		tg3_power_down_phy(tp, do_low_power);
 
 	tg3_frob_aux_power(tp);
@@ -2809,7 +2852,7 @@
 
 		val &= ~((1 << 16) | (1 << 4) | (1 << 2) | (1 << 1) | 1);
 		tw32(0x7d00, val);
-		if (!(tp->tg3_flags & TG3_FLAG_ENABLE_ASF)) {
+		if (!tg3_flag(tp, ENABLE_ASF)) {
 			int err;
 
 			err = tg3_nvram_lock(tp);
@@ -2828,7 +2871,7 @@
 {
 	tg3_power_down_prepare(tp);
 
-	pci_wake_from_d3(tp->pdev, tp->tg3_flags & TG3_FLAG_WOL_ENABLE);
+	pci_wake_from_d3(tp->pdev, tg3_flag(tp, WOL_ENABLE));
 	pci_set_power_state(tp->pdev, PCI_D3hot);
 }
 
@@ -2879,106 +2922,54 @@
 	}
 }
 
-static void tg3_phy_copper_begin(struct tg3 *tp)
+static int tg3_phy_autoneg_cfg(struct tg3 *tp, u32 advertise, u32 flowctrl)
 {
-	u32 new_adv;
-	int i;
-
-	if (tp->phy_flags & TG3_PHYFLG_IS_LOW_POWER) {
-		/* Entering low power mode.  Disable gigabit and
-		 * 100baseT advertisements.
-		 */
-		tg3_writephy(tp, MII_TG3_CTRL, 0);
-
-		new_adv = (ADVERTISE_10HALF | ADVERTISE_10FULL |
-			   ADVERTISE_CSMA | ADVERTISE_PAUSE_CAP);
-		if (tp->tg3_flags & TG3_FLAG_WOL_SPEED_100MB)
-			new_adv |= (ADVERTISE_100HALF | ADVERTISE_100FULL);
-
-		tg3_writephy(tp, MII_ADVERTISE, new_adv);
-	} else if (tp->link_config.speed == SPEED_INVALID) {
-		if (tp->phy_flags & TG3_PHYFLG_10_100_ONLY)
-			tp->link_config.advertising &=
-				~(ADVERTISED_1000baseT_Half |
-				  ADVERTISED_1000baseT_Full);
-
-		new_adv = ADVERTISE_CSMA;
-		if (tp->link_config.advertising & ADVERTISED_10baseT_Half)
-			new_adv |= ADVERTISE_10HALF;
-		if (tp->link_config.advertising & ADVERTISED_10baseT_Full)
-			new_adv |= ADVERTISE_10FULL;
-		if (tp->link_config.advertising & ADVERTISED_100baseT_Half)
-			new_adv |= ADVERTISE_100HALF;
-		if (tp->link_config.advertising & ADVERTISED_100baseT_Full)
-			new_adv |= ADVERTISE_100FULL;
+	int err = 0;
+	u32 val, new_adv;
 
-		new_adv |= tg3_advert_flowctrl_1000T(tp->link_config.flowctrl);
+	new_adv = ADVERTISE_CSMA;
+	if (advertise & ADVERTISED_10baseT_Half)
+		new_adv |= ADVERTISE_10HALF;
+	if (advertise & ADVERTISED_10baseT_Full)
+		new_adv |= ADVERTISE_10FULL;
+	if (advertise & ADVERTISED_100baseT_Half)
+		new_adv |= ADVERTISE_100HALF;
+	if (advertise & ADVERTISED_100baseT_Full)
+		new_adv |= ADVERTISE_100FULL;
 
-		tg3_writephy(tp, MII_ADVERTISE, new_adv);
+	new_adv |= tg3_advert_flowctrl_1000T(flowctrl);
 
-		if (tp->link_config.advertising &
-		    (ADVERTISED_1000baseT_Half | ADVERTISED_1000baseT_Full)) {
-			new_adv = 0;
-			if (tp->link_config.advertising & ADVERTISED_1000baseT_Half)
-				new_adv |= MII_TG3_CTRL_ADV_1000_HALF;
-			if (tp->link_config.advertising & ADVERTISED_1000baseT_Full)
-				new_adv |= MII_TG3_CTRL_ADV_1000_FULL;
-			if (!(tp->phy_flags & TG3_PHYFLG_10_100_ONLY) &&
-			    (tp->pci_chip_rev_id == CHIPREV_ID_5701_A0 ||
-			     tp->pci_chip_rev_id == CHIPREV_ID_5701_B0))
-				new_adv |= (MII_TG3_CTRL_AS_MASTER |
-					    MII_TG3_CTRL_ENABLE_AS_MASTER);
-			tg3_writephy(tp, MII_TG3_CTRL, new_adv);
-		} else {
-			tg3_writephy(tp, MII_TG3_CTRL, 0);
-		}
-	} else {
-		new_adv = tg3_advert_flowctrl_1000T(tp->link_config.flowctrl);
-		new_adv |= ADVERTISE_CSMA;
+	err = tg3_writephy(tp, MII_ADVERTISE, new_adv);
+	if (err)
+		goto done;
 
-		/* Asking for a specific link mode. */
-		if (tp->link_config.speed == SPEED_1000) {
-			tg3_writephy(tp, MII_ADVERTISE, new_adv);
+	if (tp->phy_flags & TG3_PHYFLG_10_100_ONLY)
+		goto done;
 
-			if (tp->link_config.duplex == DUPLEX_FULL)
-				new_adv = MII_TG3_CTRL_ADV_1000_FULL;
-			else
-				new_adv = MII_TG3_CTRL_ADV_1000_HALF;
-			if (tp->pci_chip_rev_id == CHIPREV_ID_5701_A0 ||
-			    tp->pci_chip_rev_id == CHIPREV_ID_5701_B0)
-				new_adv |= (MII_TG3_CTRL_AS_MASTER |
-					    MII_TG3_CTRL_ENABLE_AS_MASTER);
-		} else {
-			if (tp->link_config.speed == SPEED_100) {
-				if (tp->link_config.duplex == DUPLEX_FULL)
-					new_adv |= ADVERTISE_100FULL;
-				else
-					new_adv |= ADVERTISE_100HALF;
-			} else {
-				if (tp->link_config.duplex == DUPLEX_FULL)
-					new_adv |= ADVERTISE_10FULL;
-				else
-					new_adv |= ADVERTISE_10HALF;
-			}
-			tg3_writephy(tp, MII_ADVERTISE, new_adv);
+	new_adv = 0;
+	if (advertise & ADVERTISED_1000baseT_Half)
+		new_adv |= MII_TG3_CTRL_ADV_1000_HALF;
+	if (advertise & ADVERTISED_1000baseT_Full)
+		new_adv |= MII_TG3_CTRL_ADV_1000_FULL;
 
-			new_adv = 0;
-		}
+	if (tp->pci_chip_rev_id == CHIPREV_ID_5701_A0 ||
+	    tp->pci_chip_rev_id == CHIPREV_ID_5701_B0)
+		new_adv |= (MII_TG3_CTRL_AS_MASTER |
+			    MII_TG3_CTRL_ENABLE_AS_MASTER);
 
-		tg3_writephy(tp, MII_TG3_CTRL, new_adv);
-	}
+	err = tg3_writephy(tp, MII_TG3_CTRL, new_adv);
+	if (err)
+		goto done;
 
-	if (tp->phy_flags & TG3_PHYFLG_EEE_CAP) {
-		u32 val;
+	if (!(tp->phy_flags & TG3_PHYFLG_EEE_CAP))
+		goto done;
 
-		tw32(TG3_CPMU_EEE_MODE,
-		     tr32(TG3_CPMU_EEE_MODE) & ~TG3_CPMU_EEEMD_LPI_ENABLE);
+	tw32(TG3_CPMU_EEE_MODE,
+	     tr32(TG3_CPMU_EEE_MODE) & ~TG3_CPMU_EEEMD_LPI_ENABLE);
 
-		/* Enable SM_DSP clock and tx 6dB coding. */
-		val = MII_TG3_AUXCTL_SHDWSEL_AUXCTL |
-		      MII_TG3_AUXCTL_ACTL_SMDSP_ENA |
-		      MII_TG3_AUXCTL_ACTL_TX_6DB;
-		tg3_writephy(tp, MII_TG3_AUX_CTRL, val);
+	err = TG3_PHY_AUXCTL_SMDSP_ENABLE(tp);
+	if (!err) {
+		u32 err2;
 
 		switch (GET_ASIC_REV(tp->pci_chip_rev_id)) {
 		case ASIC_REV_5717:
@@ -2995,22 +2986,66 @@
 		}
 
 		val = 0;
-		if (tp->link_config.autoneg == AUTONEG_ENABLE) {
-			/* Advertise 100-BaseTX EEE ability */
-			if (tp->link_config.advertising &
-			    ADVERTISED_100baseT_Full)
-				val |= MDIO_AN_EEE_ADV_100TX;
-			/* Advertise 1000-BaseT EEE ability */
-			if (tp->link_config.advertising &
-			    ADVERTISED_1000baseT_Full)
-				val |= MDIO_AN_EEE_ADV_1000T;
+		/* Advertise 100-BaseTX EEE ability */
+		if (advertise & ADVERTISED_100baseT_Full)
+			val |= MDIO_AN_EEE_ADV_100TX;
+		/* Advertise 1000-BaseT EEE ability */
+		if (advertise & ADVERTISED_1000baseT_Full)
+			val |= MDIO_AN_EEE_ADV_1000T;
+		err = tg3_phy_cl45_write(tp, MDIO_MMD_AN, MDIO_AN_EEE_ADV, val);
+
+		err2 = TG3_PHY_AUXCTL_SMDSP_DISABLE(tp);
+		if (!err)
+			err = err2;
+	}
+
+done:
+	return err;
+}
+
+static void tg3_phy_copper_begin(struct tg3 *tp)
+{
+	u32 new_adv;
+	int i;
+
+	if (tp->phy_flags & TG3_PHYFLG_IS_LOW_POWER) {
+		new_adv = ADVERTISED_10baseT_Half |
+			  ADVERTISED_10baseT_Full;
+		if (tg3_flag(tp, WOL_SPEED_100MB))
+			new_adv |= ADVERTISED_100baseT_Half |
+				   ADVERTISED_100baseT_Full;
+
+		tg3_phy_autoneg_cfg(tp, new_adv,
+				    FLOW_CTRL_TX | FLOW_CTRL_RX);
+	} else if (tp->link_config.speed == SPEED_INVALID) {
+		if (tp->phy_flags & TG3_PHYFLG_10_100_ONLY)
+			tp->link_config.advertising &=
+				~(ADVERTISED_1000baseT_Half |
+				  ADVERTISED_1000baseT_Full);
+
+		tg3_phy_autoneg_cfg(tp, tp->link_config.advertising,
+				    tp->link_config.flowctrl);
+	} else {
+		/* Asking for a specific link mode. */
+		if (tp->link_config.speed == SPEED_1000) {
+			if (tp->link_config.duplex == DUPLEX_FULL)
+				new_adv = ADVERTISED_1000baseT_Full;
+			else
+				new_adv = ADVERTISED_1000baseT_Half;
+		} else if (tp->link_config.speed == SPEED_100) {
+			if (tp->link_config.duplex == DUPLEX_FULL)
+				new_adv = ADVERTISED_100baseT_Full;
+			else
+				new_adv = ADVERTISED_100baseT_Half;
+		} else {
+			if (tp->link_config.duplex == DUPLEX_FULL)
+				new_adv = ADVERTISED_10baseT_Full;
+			else
+				new_adv = ADVERTISED_10baseT_Half;
 		}
-		tg3_phy_cl45_write(tp, MDIO_MMD_AN, MDIO_AN_EEE_ADV, val);
 
-		/* Turn off SM_DSP clock. */
-		val = MII_TG3_AUXCTL_SHDWSEL_AUXCTL |
-		      MII_TG3_AUXCTL_ACTL_TX_6DB;
-		tg3_writephy(tp, MII_TG3_AUX_CTRL, val);
+		tg3_phy_autoneg_cfg(tp, new_adv,
+				    tp->link_config.flowctrl);
 	}
 
 	if (tp->link_config.autoneg == AUTONEG_DISABLE &&
@@ -3068,7 +3103,7 @@
 
 	/* Turn off tap power management. */
 	/* Set Extended packet length bit */
-	err  = tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x4c20);
+	err = tg3_phy_auxctl_write(tp, MII_TG3_AUXCTL_SHDWSEL_AUXCTL, 0x4c20);
 
 	err |= tg3_phydsp_write(tp, 0x0012, 0x1804);
 	err |= tg3_phydsp_write(tp, 0x0013, 0x1204);
@@ -3131,7 +3166,7 @@
 		if (curadv != reqadv)
 			return 0;
 
-		if (tp->tg3_flags & TG3_FLAG_PAUSE_AUTONEG)
+		if (tg3_flag(tp, PAUSE_AUTONEG))
 			tg3_readphy(tp, MII_LPA, rmtadv);
 	} else {
 		/* Reprogram the advertisement register, even if it
@@ -3174,7 +3209,7 @@
 		udelay(80);
 	}
 
-	tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x02);
+	tg3_phy_auxctl_write(tp, MII_TG3_AUXCTL_SHDWSEL_PWRCTL, 0);
 
 	/* Some third-party PHYs need to be reset on link going
 	 * down.
@@ -3194,7 +3229,7 @@
 	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))
+		    !tg3_flag(tp, INIT_COMPLETE))
 			bmsr = 0;
 
 		if (!(bmsr & BMSR_LSTATUS)) {
@@ -3255,11 +3290,13 @@
 	current_duplex = DUPLEX_INVALID;
 
 	if (tp->phy_flags & TG3_PHYFLG_CAPACITIVE_COUPLING) {
-		tg3_writephy(tp, MII_TG3_AUX_CTRL, 0x4007);
-		tg3_readphy(tp, MII_TG3_AUX_CTRL, &val);
-		if (!(val & (1 << 10))) {
-			val |= (1 << 10);
-			tg3_writephy(tp, MII_TG3_AUX_CTRL, val);
+		err = tg3_phy_auxctl_read(tp,
+					  MII_TG3_AUXCTL_SHDWSEL_MISCTEST,
+					  &val);
+		if (!err && !(val & (1 << 10))) {
+			tg3_phy_auxctl_write(tp,
+					     MII_TG3_AUXCTL_SHDWSEL_MISCTEST,
+					     val | (1 << 10));
 			goto relink;
 		}
 	}
@@ -3332,8 +3369,8 @@
 		tg3_phy_copper_begin(tp);
 
 		tg3_readphy(tp, MII_BMSR, &bmsr);
-		if (!tg3_readphy(tp, MII_BMSR, &bmsr) &&
-		    (bmsr & BMSR_LSTATUS))
+		if ((!tg3_readphy(tp, MII_BMSR, &bmsr) && (bmsr & BMSR_LSTATUS)) ||
+		    (tp->mac_mode & MAC_MODE_PORT_INT_LPBACK))
 			current_link_up = 1;
 	}
 
@@ -3376,7 +3413,7 @@
 
 	tg3_phy_eee_adjust(tp, current_link_up);
 
-	if (tp->tg3_flags & TG3_FLAG_USE_LINKCHG_REG) {
+	if (tg3_flag(tp, USE_LINKCHG_REG)) {
 		/* Polled via timer. */
 		tw32_f(MAC_EVENT, 0);
 	} else {
@@ -3387,8 +3424,7 @@
 	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700 &&
 	    current_link_up == 1 &&
 	    tp->link_config.active_speed == SPEED_1000 &&
-	    ((tp->tg3_flags & TG3_FLAG_PCIX_MODE) ||
-	     (tp->tg3_flags & TG3_FLAG_PCI_HIGH_SPEED))) {
+	    (tg3_flag(tp, PCIX_MODE) || tg3_flag(tp, PCI_HIGH_SPEED))) {
 		udelay(120);
 		tw32_f(MAC_STATUS,
 		     (MAC_STATUS_SYNC_CHANGED |
@@ -3400,7 +3436,7 @@
 	}
 
 	/* Prevent send BD corruption. */
-	if (tp->tg3_flags3 & TG3_FLG3_CLKREQ_BUG) {
+	if (tg3_flag(tp, CLKREQ_BUG)) {
 		u16 oldlnkctl, newlnkctl;
 
 		pci_read_config_word(tp->pdev,
@@ -3795,7 +3831,7 @@
 	int i;
 
 	/* Reset when initting first time or we have a link. */
-	if ((tp->tg3_flags & TG3_FLAG_INIT_COMPLETE) &&
+	if (tg3_flag(tp, INIT_COMPLETE) &&
 	    !(mac_status & MAC_STATUS_PCS_SYNCED))
 		return;
 
@@ -4056,9 +4092,9 @@
 	orig_active_speed = tp->link_config.active_speed;
 	orig_active_duplex = tp->link_config.active_duplex;
 
-	if (!(tp->tg3_flags2 & TG3_FLG2_HW_AUTONEG) &&
+	if (!tg3_flag(tp, HW_AUTONEG) &&
 	    netif_carrier_ok(tp->dev) &&
-	    (tp->tg3_flags & TG3_FLAG_INIT_COMPLETE)) {
+	    tg3_flag(tp, INIT_COMPLETE)) {
 		mac_status = tr32(MAC_STATUS);
 		mac_status &= (MAC_STATUS_PCS_SYNCED |
 			       MAC_STATUS_SIGNAL_DET |
@@ -4089,7 +4125,7 @@
 	current_link_up = 0;
 	mac_status = tr32(MAC_STATUS);
 
-	if (tp->tg3_flags2 & TG3_FLG2_HW_AUTONEG)
+	if (tg3_flag(tp, HW_AUTONEG))
 		current_link_up = tg3_setup_fiber_hw_autoneg(tp, mac_status);
 	else
 		current_link_up = tg3_setup_fiber_by_hand(tp, mac_status);
@@ -4288,7 +4324,7 @@
 					current_duplex = DUPLEX_FULL;
 				else
 					current_duplex = DUPLEX_HALF;
-			} else if (!(tp->tg3_flags2 & TG3_FLG2_5780_CLASS)) {
+			} else if (!tg3_flag(tp, 5780_CLASS)) {
 				/* Link is up via parallel detect */
 			} else {
 				current_link_up = 0;
@@ -4385,6 +4421,7 @@
 
 static int tg3_setup_phy(struct tg3 *tp, int force_reset)
 {
+	u32 val;
 	int err;
 
 	if (tp->phy_flags & TG3_PHYFLG_PHY_SERDES)
@@ -4395,7 +4432,7 @@
 		err = tg3_setup_copper_phy(tp, force_reset);
 
 	if (GET_CHIP_REV(tp->pci_chip_rev_id) == CHIPREV_5784_AX) {
-		u32 val, scale;
+		u32 scale;
 
 		val = tr32(TG3_CPMU_CLCK_STAT) & CPMU_CLCK_STAT_MAC_CLCK_MASK;
 		if (val == CPMU_CLCK_STAT_MAC_CLCK_62_5)
@@ -4410,19 +4447,22 @@
 		tw32(GRC_MISC_CFG, val);
 	}
 
+	val = (2 << TX_LENGTHS_IPG_CRS_SHIFT) |
+	      (6 << TX_LENGTHS_IPG_SHIFT);
+	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5720)
+		val |= tr32(MAC_TX_LENGTHS) &
+		       (TX_LENGTHS_JMB_FRM_LEN_MSK |
+			TX_LENGTHS_CNT_DWN_VAL_MSK);
+
 	if (tp->link_config.active_speed == SPEED_1000 &&
 	    tp->link_config.active_duplex == DUPLEX_HALF)
-		tw32(MAC_TX_LENGTHS,
-		     ((2 << TX_LENGTHS_IPG_CRS_SHIFT) |
-		      (6 << TX_LENGTHS_IPG_SHIFT) |
-		      (0xff << TX_LENGTHS_SLOT_TIME_SHIFT)));
+		tw32(MAC_TX_LENGTHS, val |
+		     (0xff << TX_LENGTHS_SLOT_TIME_SHIFT));
 	else
-		tw32(MAC_TX_LENGTHS,
-		     ((2 << TX_LENGTHS_IPG_CRS_SHIFT) |
-		      (6 << TX_LENGTHS_IPG_SHIFT) |
-		      (32 << TX_LENGTHS_SLOT_TIME_SHIFT)));
+		tw32(MAC_TX_LENGTHS, val |
+		     (32 << TX_LENGTHS_SLOT_TIME_SHIFT));
 
-	if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS)) {
+	if (!tg3_flag(tp, 5705_PLUS)) {
 		if (netif_carrier_ok(tp->dev)) {
 			tw32(HOSTCC_STAT_COAL_TICKS,
 			     tp->coal.stats_block_coalesce_usecs);
@@ -4431,8 +4471,8 @@
 		}
 	}
 
-	if (tp->tg3_flags & TG3_FLAG_ASPM_WORKAROUND) {
-		u32 val = tr32(PCIE_PWR_MGMT_THRESH);
+	if (tg3_flag(tp, ASPM_WORKAROUND)) {
+		val = tr32(PCIE_PWR_MGMT_THRESH);
 		if (!netif_carrier_ok(tp->dev))
 			val = (val & ~PCIE_PWR_MGMT_L1_THRESH_MSK) |
 			      tp->pwrmgmt_thresh;
@@ -4449,6 +4489,123 @@
 	return tp->irq_sync;
 }
 
+static inline void tg3_rd32_loop(struct tg3 *tp, u32 *dst, u32 off, u32 len)
+{
+	int i;
+
+	dst = (u32 *)((u8 *)dst + off);
+	for (i = 0; i < len; i += sizeof(u32))
+		*dst++ = tr32(off + i);
+}
+
+static void tg3_dump_legacy_regs(struct tg3 *tp, u32 *regs)
+{
+	tg3_rd32_loop(tp, regs, TG3PCI_VENDOR, 0xb0);
+	tg3_rd32_loop(tp, regs, MAILBOX_INTERRUPT_0, 0x200);
+	tg3_rd32_loop(tp, regs, MAC_MODE, 0x4f0);
+	tg3_rd32_loop(tp, regs, SNDDATAI_MODE, 0xe0);
+	tg3_rd32_loop(tp, regs, SNDDATAC_MODE, 0x04);
+	tg3_rd32_loop(tp, regs, SNDBDS_MODE, 0x80);
+	tg3_rd32_loop(tp, regs, SNDBDI_MODE, 0x48);
+	tg3_rd32_loop(tp, regs, SNDBDC_MODE, 0x04);
+	tg3_rd32_loop(tp, regs, RCVLPC_MODE, 0x20);
+	tg3_rd32_loop(tp, regs, RCVLPC_SELLST_BASE, 0x15c);
+	tg3_rd32_loop(tp, regs, RCVDBDI_MODE, 0x0c);
+	tg3_rd32_loop(tp, regs, RCVDBDI_JUMBO_BD, 0x3c);
+	tg3_rd32_loop(tp, regs, RCVDBDI_BD_PROD_IDX_0, 0x44);
+	tg3_rd32_loop(tp, regs, RCVDCC_MODE, 0x04);
+	tg3_rd32_loop(tp, regs, RCVBDI_MODE, 0x20);
+	tg3_rd32_loop(tp, regs, RCVCC_MODE, 0x14);
+	tg3_rd32_loop(tp, regs, RCVLSC_MODE, 0x08);
+	tg3_rd32_loop(tp, regs, MBFREE_MODE, 0x08);
+	tg3_rd32_loop(tp, regs, HOSTCC_MODE, 0x100);
+
+	if (tg3_flag(tp, SUPPORT_MSIX))
+		tg3_rd32_loop(tp, regs, HOSTCC_RXCOL_TICKS_VEC1, 0x180);
+
+	tg3_rd32_loop(tp, regs, MEMARB_MODE, 0x10);
+	tg3_rd32_loop(tp, regs, BUFMGR_MODE, 0x58);
+	tg3_rd32_loop(tp, regs, RDMAC_MODE, 0x08);
+	tg3_rd32_loop(tp, regs, WDMAC_MODE, 0x08);
+	tg3_rd32_loop(tp, regs, RX_CPU_MODE, 0x04);
+	tg3_rd32_loop(tp, regs, RX_CPU_STATE, 0x04);
+	tg3_rd32_loop(tp, regs, RX_CPU_PGMCTR, 0x04);
+	tg3_rd32_loop(tp, regs, RX_CPU_HWBKPT, 0x04);
+
+	if (!tg3_flag(tp, 5705_PLUS)) {
+		tg3_rd32_loop(tp, regs, TX_CPU_MODE, 0x04);
+		tg3_rd32_loop(tp, regs, TX_CPU_STATE, 0x04);
+		tg3_rd32_loop(tp, regs, TX_CPU_PGMCTR, 0x04);
+	}
+
+	tg3_rd32_loop(tp, regs, GRCMBOX_INTERRUPT_0, 0x110);
+	tg3_rd32_loop(tp, regs, FTQ_RESET, 0x120);
+	tg3_rd32_loop(tp, regs, MSGINT_MODE, 0x0c);
+	tg3_rd32_loop(tp, regs, DMAC_MODE, 0x04);
+	tg3_rd32_loop(tp, regs, GRC_MODE, 0x4c);
+
+	if (tg3_flag(tp, NVRAM))
+		tg3_rd32_loop(tp, regs, NVRAM_CMD, 0x24);
+}
+
+static void tg3_dump_state(struct tg3 *tp)
+{
+	int i;
+	u32 *regs;
+
+	regs = kzalloc(TG3_REG_BLK_SIZE, GFP_ATOMIC);
+	if (!regs) {
+		netdev_err(tp->dev, "Failed allocating register dump buffer\n");
+		return;
+	}
+
+	if (tg3_flag(tp, PCI_EXPRESS)) {
+		/* Read up to but not including private PCI registers */
+		for (i = 0; i < TG3_PCIE_TLDLPL_PORT; i += sizeof(u32))
+			regs[i / sizeof(u32)] = tr32(i);
+	} else
+		tg3_dump_legacy_regs(tp, regs);
+
+	for (i = 0; i < TG3_REG_BLK_SIZE / sizeof(u32); i += 4) {
+		if (!regs[i + 0] && !regs[i + 1] &&
+		    !regs[i + 2] && !regs[i + 3])
+			continue;
+
+		netdev_err(tp->dev, "0x%08x: 0x%08x, 0x%08x, 0x%08x, 0x%08x\n",
+			   i * 4,
+			   regs[i + 0], regs[i + 1], regs[i + 2], regs[i + 3]);
+	}
+
+	kfree(regs);
+
+	for (i = 0; i < tp->irq_cnt; i++) {
+		struct tg3_napi *tnapi = &tp->napi[i];
+
+		/* SW status block */
+		netdev_err(tp->dev,
+			 "%d: Host status block [%08x:%08x:(%04x:%04x:%04x):(%04x:%04x)]\n",
+			   i,
+			   tnapi->hw_status->status,
+			   tnapi->hw_status->status_tag,
+			   tnapi->hw_status->rx_jumbo_consumer,
+			   tnapi->hw_status->rx_consumer,
+			   tnapi->hw_status->rx_mini_consumer,
+			   tnapi->hw_status->idx[0].rx_producer,
+			   tnapi->hw_status->idx[0].tx_consumer);
+
+		netdev_err(tp->dev,
+		"%d: NAPI info [%08x:%08x:(%04x:%04x:%04x):%04x:(%04x:%04x:%04x:%04x)]\n",
+			   i,
+			   tnapi->last_tag, tnapi->last_irq_tag,
+			   tnapi->tx_prod, tnapi->tx_cons, tnapi->tx_pending,
+			   tnapi->rx_rcb_ptr,
+			   tnapi->prodring.rx_std_prod_idx,
+			   tnapi->prodring.rx_std_cons_idx,
+			   tnapi->prodring.rx_jmb_prod_idx,
+			   tnapi->prodring.rx_jmb_cons_idx);
+	}
+}
+
 /* This is called whenever we suspect that the system chipset is re-
  * ordering the sequence of MMIO to the tx send mailbox. The symptom
  * is bogus tx completions. We try to recover by setting the
@@ -4457,7 +4614,7 @@
  */
 static void tg3_tx_recover(struct tg3 *tp)
 {
-	BUG_ON((tp->tg3_flags & TG3_FLAG_MBOX_WRITE_REORDER) ||
+	BUG_ON(tg3_flag(tp, MBOX_WRITE_REORDER) ||
 	       tp->write32_tx_mbox == tg3_write_indirect_mbox);
 
 	netdev_warn(tp->dev,
@@ -4467,7 +4624,7 @@
 		    "and include system chipset information.\n");
 
 	spin_lock(&tp->lock);
-	tp->tg3_flags |= TG3_FLAG_TX_RECOVERY_PENDING;
+	tg3_flag_set(tp, TX_RECOVERY_PENDING);
 	spin_unlock(&tp->lock);
 }
 
@@ -4491,7 +4648,7 @@
 	struct netdev_queue *txq;
 	int index = tnapi - tp->napi;
 
-	if (tp->tg3_flags3 & TG3_FLG3_ENABLE_TSS)
+	if (tg3_flag(tp, ENABLE_TSS))
 		index--;
 
 	txq = netdev_get_tx_queue(tp->dev, index);
@@ -4806,7 +4963,7 @@
 			skb = copy_skb;
 		}
 
-		if ((tp->tg3_flags & TG3_FLAG_RX_CHECKSUMS) &&
+		if ((tp->dev->features & NETIF_F_RXCSUM) &&
 		    (desc->type_flags & RXD_FLAG_TCPUDP_CSUM) &&
 		    (((desc->ip_tcp_csum & RXD_TCPCSUM_MASK)
 		      >> RXD_TCPCSUM_SHIFT) == 0xffff))
@@ -4859,7 +5016,7 @@
 	tw32_rx_mbox(tnapi->consmbox, sw_idx);
 
 	/* Refill RX ring(s). */
-	if (!(tp->tg3_flags3 & TG3_FLG3_ENABLE_RSS)) {
+	if (!tg3_flag(tp, ENABLE_RSS)) {
 		if (work_mask & RXD_OPAQUE_RING_STD) {
 			tpr->rx_std_prod_idx = std_prod_idx &
 					       tp->rx_std_ring_mask;
@@ -4892,16 +5049,14 @@
 static void tg3_poll_link(struct tg3 *tp)
 {
 	/* handle link change and other phy events */
-	if (!(tp->tg3_flags &
-	      (TG3_FLAG_USE_LINKCHG_REG |
-	       TG3_FLAG_POLL_SERDES))) {
+	if (!(tg3_flag(tp, USE_LINKCHG_REG) || tg3_flag(tp, POLL_SERDES))) {
 		struct tg3_hw_status *sblk = tp->napi[0].hw_status;
 
 		if (sblk->status & SD_STATUS_LINK_CHG) {
 			sblk->status = SD_STATUS_UPDATED |
 				       (sblk->status & ~SD_STATUS_LINK_CHG);
 			spin_lock(&tp->lock);
-			if (tp->tg3_flags3 & TG3_FLG3_USE_PHYLIB) {
+			if (tg3_flag(tp, USE_PHYLIB)) {
 				tw32_f(MAC_STATUS,
 				     (MAC_STATUS_SYNC_CHANGED |
 				      MAC_STATUS_CFG_CHANGED |
@@ -5048,7 +5203,7 @@
 	/* run TX completion thread */
 	if (tnapi->hw_status->idx[0].tx_consumer != tnapi->tx_cons) {
 		tg3_tx(tnapi);
-		if (unlikely(tp->tg3_flags & TG3_FLAG_TX_RECOVERY_PENDING))
+		if (unlikely(tg3_flag(tp, TX_RECOVERY_PENDING)))
 			return work_done;
 	}
 
@@ -5059,7 +5214,7 @@
 	if (*(tnapi->rx_rcb_prod_idx) != tnapi->rx_rcb_ptr)
 		work_done += tg3_rx(tnapi, budget - work_done);
 
-	if ((tp->tg3_flags3 & TG3_FLG3_ENABLE_RSS) && tnapi == &tp->napi[1]) {
+	if (tg3_flag(tp, ENABLE_RSS) && tnapi == &tp->napi[1]) {
 		struct tg3_rx_prodring_set *dpr = &tp->napi[0].prodring;
 		int i, err = 0;
 		u32 std_prod_idx = dpr->rx_std_prod_idx;
@@ -5098,7 +5253,7 @@
 	while (1) {
 		work_done = tg3_poll_work(tnapi, work_done, budget);
 
-		if (unlikely(tp->tg3_flags & TG3_FLAG_TX_RECOVERY_PENDING))
+		if (unlikely(tg3_flag(tp, TX_RECOVERY_PENDING)))
 			goto tx_recovery;
 
 		if (unlikely(work_done >= budget))
@@ -5132,6 +5287,40 @@
 	return work_done;
 }
 
+static void tg3_process_error(struct tg3 *tp)
+{
+	u32 val;
+	bool real_error = false;
+
+	if (tg3_flag(tp, ERROR_PROCESSED))
+		return;
+
+	/* Check Flow Attention register */
+	val = tr32(HOSTCC_FLOW_ATTN);
+	if (val & ~HOSTCC_FLOW_ATTN_MBUF_LWM) {
+		netdev_err(tp->dev, "FLOW Attention error.  Resetting chip.\n");
+		real_error = true;
+	}
+
+	if (tr32(MSGINT_STATUS) & ~MSGINT_STATUS_MSI_REQ) {
+		netdev_err(tp->dev, "MSI Status error.  Resetting chip.\n");
+		real_error = true;
+	}
+
+	if (tr32(RDMAC_STATUS) || tr32(WDMAC_STATUS)) {
+		netdev_err(tp->dev, "DMA Status error.  Resetting chip.\n");
+		real_error = true;
+	}
+
+	if (!real_error)
+		return;
+
+	tg3_dump_state(tp);
+
+	tg3_flag_set(tp, ERROR_PROCESSED);
+	schedule_work(&tp->reset_task);
+}
+
 static int tg3_poll(struct napi_struct *napi, int budget)
 {
 	struct tg3_napi *tnapi = container_of(napi, struct tg3_napi, napi);
@@ -5140,17 +5329,20 @@
 	struct tg3_hw_status *sblk = tnapi->hw_status;
 
 	while (1) {
+		if (sblk->status & SD_STATUS_ERROR)
+			tg3_process_error(tp);
+
 		tg3_poll_link(tp);
 
 		work_done = tg3_poll_work(tnapi, work_done, budget);
 
-		if (unlikely(tp->tg3_flags & TG3_FLAG_TX_RECOVERY_PENDING))
+		if (unlikely(tg3_flag(tp, TX_RECOVERY_PENDING)))
 			goto tx_recovery;
 
 		if (unlikely(work_done >= budget))
 			break;
 
-		if (tp->tg3_flags & TG3_FLAG_TAGGED_STATUS) {
+		if (tg3_flag(tp, TAGGED_STATUS)) {
 			/* tp->last_tag is used in tg3_int_reenable() below
 			 * to tell the hw how much work has been processed,
 			 * so we must read it before checking for more work.
@@ -5317,7 +5509,7 @@
 	 * interrupt is ours and will flush the status block.
 	 */
 	if (unlikely(!(sblk->status & SD_STATUS_UPDATED))) {
-		if ((tp->tg3_flags & TG3_FLAG_CHIP_RESETTING) ||
+		if (tg3_flag(tp, CHIP_RESETTING) ||
 		    (tr32(TG3PCI_PCISTATE) & PCISTATE_INT_NOT_ACTIVE)) {
 			handled = 0;
 			goto out;
@@ -5366,7 +5558,7 @@
 	 * interrupt is ours and will flush the status block.
 	 */
 	if (unlikely(sblk->status_tag == tnapi->last_irq_tag)) {
-		if ((tp->tg3_flags & TG3_FLAG_CHIP_RESETTING) ||
+		if (tg3_flag(tp, CHIP_RESETTING) ||
 		    (tr32(TG3PCI_PCISTATE) & PCISTATE_INT_NOT_ACTIVE)) {
 			handled = 0;
 			goto out;
@@ -5479,14 +5671,14 @@
 
 	tg3_full_lock(tp, 1);
 
-	restart_timer = tp->tg3_flags2 & TG3_FLG2_RESTART_TIMER;
-	tp->tg3_flags2 &= ~TG3_FLG2_RESTART_TIMER;
+	restart_timer = tg3_flag(tp, RESTART_TIMER);
+	tg3_flag_clear(tp, RESTART_TIMER);
 
-	if (tp->tg3_flags & TG3_FLAG_TX_RECOVERY_PENDING) {
+	if (tg3_flag(tp, TX_RECOVERY_PENDING)) {
 		tp->write32_tx_mbox = tg3_write32_tx_mbox;
 		tp->write32_rx_mbox = tg3_write_flush_reg32;
-		tp->tg3_flags |= TG3_FLAG_MBOX_WRITE_REORDER;
-		tp->tg3_flags &= ~TG3_FLAG_TX_RECOVERY_PENDING;
+		tg3_flag_set(tp, MBOX_WRITE_REORDER);
+		tg3_flag_clear(tp, TX_RECOVERY_PENDING);
 	}
 
 	tg3_halt(tp, RESET_KIND_SHUTDOWN, 0);
@@ -5506,21 +5698,13 @@
 		tg3_phy_start(tp);
 }
 
-static void tg3_dump_short_state(struct tg3 *tp)
-{
-	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)
 {
 	struct tg3 *tp = netdev_priv(dev);
 
 	if (netif_msg_tx_err(tp)) {
 		netdev_err(dev, "transmit timed out, resetting\n");
-		tg3_dump_short_state(tp);
+		tg3_dump_state(tp);
 	}
 
 	schedule_work(&tp->reset_task);
@@ -5539,7 +5723,7 @@
 					  int len)
 {
 #if defined(CONFIG_HIGHMEM) && (BITS_PER_LONG == 64)
-	if (tp->tg3_flags & TG3_FLAG_40BIT_DMA_BUG)
+	if (tg3_flag(tp, 40BIT_DMA_BUG))
 		return ((u64) mapping + len) > DMA_BIT_MASK(40);
 	return 0;
 #else
@@ -5547,18 +5731,62 @@
 #endif
 }
 
-static void tg3_set_txd(struct tg3_napi *, int, dma_addr_t, int, u32, u32);
+static void tg3_set_txd(struct tg3_napi *tnapi, int entry,
+			dma_addr_t mapping, int len, u32 flags,
+			u32 mss_and_is_end)
+{
+	struct tg3_tx_buffer_desc *txd = &tnapi->tx_ring[entry];
+	int is_end = (mss_and_is_end & 0x1);
+	u32 mss = (mss_and_is_end >> 1);
+	u32 vlan_tag = 0;
+
+	if (is_end)
+		flags |= TXD_FLAG_END;
+	if (flags & TXD_FLAG_VLAN) {
+		vlan_tag = flags >> 16;
+		flags &= 0xffff;
+	}
+	vlan_tag |= (mss << TXD_MSS_SHIFT);
+
+	txd->addr_hi = ((u64) mapping >> 32);
+	txd->addr_lo = ((u64) mapping & 0xffffffff);
+	txd->len_flags = (len << TXD_LEN_SHIFT) | flags;
+	txd->vlan_tag = vlan_tag << TXD_VLAN_TAG_SHIFT;
+}
+
+static void tg3_skb_error_unmap(struct tg3_napi *tnapi,
+				struct sk_buff *skb, int last)
+{
+	int i;
+	u32 entry = tnapi->tx_prod;
+	struct ring_info *txb = &tnapi->tx_buffers[entry];
+
+	pci_unmap_single(tnapi->tp->pdev,
+			 dma_unmap_addr(txb, mapping),
+			 skb_headlen(skb),
+			 PCI_DMA_TODEVICE);
+	for (i = 0; i < last; i++) {
+		skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
+
+		entry = NEXT_TX(entry);
+		txb = &tnapi->tx_buffers[entry];
+
+		pci_unmap_page(tnapi->tp->pdev,
+			       dma_unmap_addr(txb, mapping),
+			       frag->size, PCI_DMA_TODEVICE);
+	}
+}
 
 /* Workaround 4GB and 40-bit hardware DMA bugs. */
 static int tigon3_dma_hwbug_workaround(struct tg3_napi *tnapi,
-				       struct sk_buff *skb, u32 last_plus_one,
-				       u32 *start, u32 base_flags, u32 mss)
+				       struct sk_buff *skb,
+				       u32 base_flags, u32 mss)
 {
 	struct tg3 *tp = tnapi->tp;
 	struct sk_buff *new_skb;
 	dma_addr_t new_addr = 0;
-	u32 entry = *start;
-	int i, ret = 0;
+	u32 entry = tnapi->tx_prod;
+	int ret = 0;
 
 	if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5701)
 		new_skb = skb_copy(skb, GFP_ATOMIC);
@@ -5574,55 +5802,30 @@
 		ret = -1;
 	} else {
 		/* New SKB is guaranteed to be linear. */
-		entry = *start;
 		new_addr = pci_map_single(tp->pdev, new_skb->data, new_skb->len,
 					  PCI_DMA_TODEVICE);
 		/* Make sure the mapping succeeded */
 		if (pci_dma_mapping_error(tp->pdev, new_addr)) {
 			ret = -1;
 			dev_kfree_skb(new_skb);
-			new_skb = NULL;
 
 		/* Make sure new skb does not cross any 4G boundaries.
 		 * Drop the packet if it does.
 		 */
-		} else if ((tp->tg3_flags3 & TG3_FLG3_4G_DMA_BNDRY_BUG) &&
-			    tg3_4g_overflow_test(new_addr, new_skb->len)) {
+		} else if (tg3_flag(tp, 4G_DMA_BNDRY_BUG) &&
+			   tg3_4g_overflow_test(new_addr, new_skb->len)) {
 			pci_unmap_single(tp->pdev, new_addr, new_skb->len,
 					 PCI_DMA_TODEVICE);
 			ret = -1;
 			dev_kfree_skb(new_skb);
-			new_skb = NULL;
 		} else {
+			tnapi->tx_buffers[entry].skb = new_skb;
+			dma_unmap_addr_set(&tnapi->tx_buffers[entry],
+					   mapping, new_addr);
+
 			tg3_set_txd(tnapi, entry, new_addr, new_skb->len,
 				    base_flags, 1 | (mss << 1));
-			*start = NEXT_TX(entry);
-		}
-	}
-
-	/* Now clean up the sw ring entries. */
-	i = 0;
-	while (entry != last_plus_one) {
-		int len;
-
-		if (i == 0)
-			len = skb_headlen(skb);
-		else
-			len = skb_shinfo(skb)->frags[i-1].size;
-
-		pci_unmap_single(tp->pdev,
-				 dma_unmap_addr(&tnapi->tx_buffers[entry],
-						mapping),
-				 len, PCI_DMA_TODEVICE);
-		if (i == 0) {
-			tnapi->tx_buffers[entry].skb = new_skb;
-			dma_unmap_addr_set(&tnapi->tx_buffers[entry], mapping,
-					   new_addr);
-		} else {
-			tnapi->tx_buffers[entry].skb = NULL;
 		}
-		entry = NEXT_TX(entry);
-		i++;
 	}
 
 	dev_kfree_skb(skb);
@@ -5630,202 +5833,7 @@
 	return ret;
 }
 
-static void tg3_set_txd(struct tg3_napi *tnapi, int entry,
-			dma_addr_t mapping, int len, u32 flags,
-			u32 mss_and_is_end)
-{
-	struct tg3_tx_buffer_desc *txd = &tnapi->tx_ring[entry];
-	int is_end = (mss_and_is_end & 0x1);
-	u32 mss = (mss_and_is_end >> 1);
-	u32 vlan_tag = 0;
-
-	if (is_end)
-		flags |= TXD_FLAG_END;
-	if (flags & TXD_FLAG_VLAN) {
-		vlan_tag = flags >> 16;
-		flags &= 0xffff;
-	}
-	vlan_tag |= (mss << TXD_MSS_SHIFT);
-
-	txd->addr_hi = ((u64) mapping >> 32);
-	txd->addr_lo = ((u64) mapping & 0xffffffff);
-	txd->len_flags = (len << TXD_LEN_SHIFT) | flags;
-	txd->vlan_tag = vlan_tag << TXD_VLAN_TAG_SHIFT;
-}
-
-/* hard_start_xmit for devices that don't have any bugs and
- * support TG3_FLG2_HW_TSO_2 and TG3_FLG2_HW_TSO_3 only.
- */
-static netdev_tx_t tg3_start_xmit(struct sk_buff *skb,
-				  struct net_device *dev)
-{
-	struct tg3 *tp = netdev_priv(dev);
-	u32 len, entry, base_flags, mss;
-	dma_addr_t mapping;
-	struct tg3_napi *tnapi;
-	struct netdev_queue *txq;
-	unsigned int i, last;
-
-	txq = netdev_get_tx_queue(dev, skb_get_queue_mapping(skb));
-	tnapi = &tp->napi[skb_get_queue_mapping(skb)];
-	if (tp->tg3_flags3 & TG3_FLG3_ENABLE_TSS)
-		tnapi++;
-
-	/* We are running in BH disabled context with netif_tx_lock
-	 * and TX reclaim runs via tp->napi.poll inside of a software
-	 * interrupt.  Furthermore, IRQ processing runs lockless so we have
-	 * no IRQ context deadlocks to worry about either.  Rejoice!
-	 */
-	if (unlikely(tg3_tx_avail(tnapi) <= (skb_shinfo(skb)->nr_frags + 1))) {
-		if (!netif_tx_queue_stopped(txq)) {
-			netif_tx_stop_queue(txq);
-
-			/* This is a hard error, log it. */
-			netdev_err(dev,
-				   "BUG! Tx Ring full when queue awake!\n");
-		}
-		return NETDEV_TX_BUSY;
-	}
-
-	entry = tnapi->tx_prod;
-	base_flags = 0;
-	mss = skb_shinfo(skb)->gso_size;
-	if (mss) {
-		int tcp_opt_len, ip_tcp_len;
-		u32 hdrlen;
-
-		if (skb_header_cloned(skb) &&
-		    pskb_expand_head(skb, 0, 0, GFP_ATOMIC)) {
-			dev_kfree_skb(skb);
-			goto out_unlock;
-		}
-
-		if (skb_is_gso_v6(skb)) {
-			hdrlen = skb_headlen(skb) - ETH_HLEN;
-		} else {
-			struct iphdr *iph = ip_hdr(skb);
-
-			tcp_opt_len = tcp_optlen(skb);
-			ip_tcp_len = ip_hdrlen(skb) + sizeof(struct tcphdr);
-
-			iph->check = 0;
-			iph->tot_len = htons(mss + ip_tcp_len + tcp_opt_len);
-			hdrlen = ip_tcp_len + tcp_opt_len;
-		}
-
-		if (tp->tg3_flags2 & TG3_FLG2_HW_TSO_3) {
-			mss |= (hdrlen & 0xc) << 12;
-			if (hdrlen & 0x10)
-				base_flags |= 0x00000010;
-			base_flags |= (hdrlen & 0x3e0) << 5;
-		} else
-			mss |= hdrlen << 9;
-
-		base_flags |= (TXD_FLAG_CPU_PRE_DMA |
-			       TXD_FLAG_CPU_POST_DMA);
-
-		tcp_hdr(skb)->check = 0;
-
-	} else if (skb->ip_summed == CHECKSUM_PARTIAL) {
-		base_flags |= TXD_FLAG_TCPUDP_CSUM;
-	}
-
-	if (vlan_tx_tag_present(skb))
-		base_flags |= (TXD_FLAG_VLAN |
-			       (vlan_tx_tag_get(skb) << 16));
-
-	len = skb_headlen(skb);
-
-	/* Queue skb data, a.k.a. the main skb fragment. */
-	mapping = pci_map_single(tp->pdev, skb->data, len, PCI_DMA_TODEVICE);
-	if (pci_dma_mapping_error(tp->pdev, mapping)) {
-		dev_kfree_skb(skb);
-		goto out_unlock;
-	}
-
-	tnapi->tx_buffers[entry].skb = skb;
-	dma_unmap_addr_set(&tnapi->tx_buffers[entry], mapping, mapping);
-
-	if ((tp->tg3_flags3 & TG3_FLG3_USE_JUMBO_BDFLAG) &&
-	    !mss && skb->len > VLAN_ETH_FRAME_LEN)
-		base_flags |= TXD_FLAG_JMB_PKT;
-
-	tg3_set_txd(tnapi, entry, mapping, len, base_flags,
-		    (skb_shinfo(skb)->nr_frags == 0) | (mss << 1));
-
-	entry = NEXT_TX(entry);
-
-	/* Now loop through additional data fragments, and queue them. */
-	if (skb_shinfo(skb)->nr_frags > 0) {
-		last = skb_shinfo(skb)->nr_frags - 1;
-		for (i = 0; i <= last; i++) {
-			skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
-
-			len = frag->size;
-			mapping = pci_map_page(tp->pdev,
-					       frag->page,
-					       frag->page_offset,
-					       len, PCI_DMA_TODEVICE);
-			if (pci_dma_mapping_error(tp->pdev, mapping))
-				goto dma_error;
-
-			tnapi->tx_buffers[entry].skb = NULL;
-			dma_unmap_addr_set(&tnapi->tx_buffers[entry], mapping,
-					   mapping);
-
-			tg3_set_txd(tnapi, entry, mapping, len,
-				    base_flags, (i == last) | (mss << 1));
-
-			entry = NEXT_TX(entry);
-		}
-	}
-
-	/* Packets are ready, update Tx producer idx local and on card. */
-	tw32_tx_mbox(tnapi->prodmbox, entry);
-
-	tnapi->tx_prod = entry;
-	if (unlikely(tg3_tx_avail(tnapi) <= (MAX_SKB_FRAGS + 1))) {
-		netif_tx_stop_queue(txq);
-
-		/* netif_tx_stop_queue() must be done before checking
-		 * checking tx index in tg3_tx_avail() below, because in
-		 * tg3_tx(), we update tx index before checking for
-		 * netif_tx_queue_stopped().
-		 */
-		smp_mb();
-		if (tg3_tx_avail(tnapi) > TG3_TX_WAKEUP_THRESH(tnapi))
-			netif_tx_wake_queue(txq);
-	}
-
-out_unlock:
-	mmiowb();
-
-	return NETDEV_TX_OK;
-
-dma_error:
-	last = i;
-	entry = tnapi->tx_prod;
-	tnapi->tx_buffers[entry].skb = NULL;
-	pci_unmap_single(tp->pdev,
-			 dma_unmap_addr(&tnapi->tx_buffers[entry], mapping),
-			 skb_headlen(skb),
-			 PCI_DMA_TODEVICE);
-	for (i = 0; i <= last; i++) {
-		skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
-		entry = NEXT_TX(entry);
-
-		pci_unmap_page(tp->pdev,
-			       dma_unmap_addr(&tnapi->tx_buffers[entry],
-					      mapping),
-			       frag->size, PCI_DMA_TODEVICE);
-	}
-
-	dev_kfree_skb(skb);
-	return NETDEV_TX_OK;
-}
-
-static netdev_tx_t tg3_start_xmit_dma_bug(struct sk_buff *,
-					  struct net_device *);
+static netdev_tx_t tg3_start_xmit(struct sk_buff *, struct net_device *);
 
 /* Use GSO to workaround a rare TSO bug that may be triggered when the
  * TSO header is greater than 80 bytes.
@@ -5859,7 +5867,7 @@
 		nskb = segs;
 		segs = segs->next;
 		nskb->next = NULL;
-		tg3_start_xmit_dma_bug(nskb, tp->dev);
+		tg3_start_xmit(nskb, tp->dev);
 	} while (segs);
 
 tg3_tso_bug_end:
@@ -5869,22 +5877,21 @@
 }
 
 /* hard_start_xmit for devices that have the 4G bug and/or 40-bit bug and
- * support TG3_FLG2_HW_TSO_1 or firmware TSO only.
+ * support TG3_FLAG_HW_TSO_1 or firmware TSO only.
  */
-static netdev_tx_t tg3_start_xmit_dma_bug(struct sk_buff *skb,
-					  struct net_device *dev)
+static netdev_tx_t tg3_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
 	struct tg3 *tp = netdev_priv(dev);
 	u32 len, entry, base_flags, mss;
-	int would_hit_hwbug;
+	int i = -1, would_hit_hwbug;
 	dma_addr_t mapping;
 	struct tg3_napi *tnapi;
 	struct netdev_queue *txq;
-	unsigned int i, last;
+	unsigned int last;
 
 	txq = netdev_get_tx_queue(dev, skb_get_queue_mapping(skb));
 	tnapi = &tp->napi[skb_get_queue_mapping(skb)];
-	if (tp->tg3_flags3 & TG3_FLG3_ENABLE_TSS)
+	if (tg3_flag(tp, ENABLE_TSS))
 		tnapi++;
 
 	/* We are running in BH disabled context with netif_tx_lock
@@ -5935,13 +5942,15 @@
 		}
 
 		if (unlikely((ETH_HLEN + hdr_len) > 80) &&
-			     (tp->tg3_flags2 & TG3_FLG2_TSO_BUG))
+		    tg3_flag(tp, TSO_BUG))
 			return tg3_tso_bug(tp, skb);
 
 		base_flags |= (TXD_FLAG_CPU_PRE_DMA |
 			       TXD_FLAG_CPU_POST_DMA);
 
-		if (tp->tg3_flags2 & TG3_FLG2_HW_TSO) {
+		if (tg3_flag(tp, HW_TSO_1) ||
+		    tg3_flag(tp, HW_TSO_2) ||
+		    tg3_flag(tp, HW_TSO_3)) {
 			tcp_hdr(skb)->check = 0;
 			base_flags &= ~TXD_FLAG_TCPUDP_CSUM;
 		} else
@@ -5950,14 +5959,14 @@
 								 IPPROTO_TCP,
 								 0);
 
-		if (tp->tg3_flags2 & TG3_FLG2_HW_TSO_3) {
+		if (tg3_flag(tp, HW_TSO_3)) {
 			mss |= (hdr_len & 0xc) << 12;
 			if (hdr_len & 0x10)
 				base_flags |= 0x00000010;
 			base_flags |= (hdr_len & 0x3e0) << 5;
-		} else if (tp->tg3_flags2 & TG3_FLG2_HW_TSO_2)
+		} else if (tg3_flag(tp, HW_TSO_2))
 			mss |= hdr_len << 9;
-		else if ((tp->tg3_flags2 & TG3_FLG2_HW_TSO_1) ||
+		else if (tg3_flag(tp, HW_TSO_1) ||
 			 GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705) {
 			if (tcp_opt_len || iph->ihl > 5) {
 				int tsflags;
@@ -5979,7 +5988,7 @@
 		base_flags |= (TXD_FLAG_VLAN |
 			       (vlan_tx_tag_get(skb) << 16));
 
-	if ((tp->tg3_flags3 & TG3_FLG3_USE_JUMBO_BDFLAG) &&
+	if (tg3_flag(tp, USE_JUMBO_BDFLAG) &&
 	    !mss && skb->len > VLAN_ETH_FRAME_LEN)
 		base_flags |= TXD_FLAG_JMB_PKT;
 
@@ -5996,18 +6005,18 @@
 
 	would_hit_hwbug = 0;
 
-	if ((tp->tg3_flags3 & TG3_FLG3_SHORT_DMA_BUG) && len <= 8)
+	if (tg3_flag(tp, SHORT_DMA_BUG) && len <= 8)
 		would_hit_hwbug = 1;
 
-	if ((tp->tg3_flags3 & TG3_FLG3_4G_DMA_BNDRY_BUG) &&
+	if (tg3_flag(tp, 4G_DMA_BNDRY_BUG) &&
 	    tg3_4g_overflow_test(mapping, len))
 		would_hit_hwbug = 1;
 
-	if ((tp->tg3_flags3 & TG3_FLG3_40BIT_DMA_LIMIT_BUG) &&
+	if (tg3_flag(tp, 40BIT_DMA_LIMIT_BUG) &&
 	    tg3_40bit_overflow_test(tp, mapping, len))
 		would_hit_hwbug = 1;
 
-	if (tp->tg3_flags3 & TG3_FLG3_5701_DMA_BUG)
+	if (tg3_flag(tp, 5701_DMA_BUG))
 		would_hit_hwbug = 1;
 
 	tg3_set_txd(tnapi, entry, mapping, len, base_flags,
@@ -6033,19 +6042,21 @@
 			if (pci_dma_mapping_error(tp->pdev, mapping))
 				goto dma_error;
 
-			if ((tp->tg3_flags3 & TG3_FLG3_SHORT_DMA_BUG) &&
+			if (tg3_flag(tp, SHORT_DMA_BUG) &&
 			    len <= 8)
 				would_hit_hwbug = 1;
 
-			if ((tp->tg3_flags3 & TG3_FLG3_4G_DMA_BNDRY_BUG) &&
+			if (tg3_flag(tp, 4G_DMA_BNDRY_BUG) &&
 			    tg3_4g_overflow_test(mapping, len))
 				would_hit_hwbug = 1;
 
-			if ((tp->tg3_flags3 & TG3_FLG3_40BIT_DMA_LIMIT_BUG) &&
+			if (tg3_flag(tp, 40BIT_DMA_LIMIT_BUG) &&
 			    tg3_40bit_overflow_test(tp, mapping, len))
 				would_hit_hwbug = 1;
 
-			if (tp->tg3_flags2 & TG3_FLG2_HW_TSO)
+			if (tg3_flag(tp, HW_TSO_1) ||
+			    tg3_flag(tp, HW_TSO_2) ||
+			    tg3_flag(tp, HW_TSO_3))
 				tg3_set_txd(tnapi, entry, mapping, len,
 					    base_flags, (i == last)|(mss << 1));
 			else
@@ -6057,20 +6068,15 @@
 	}
 
 	if (would_hit_hwbug) {
-		u32 last_plus_one = entry;
-		u32 start;
-
-		start = entry - 1 - skb_shinfo(skb)->nr_frags;
-		start &= (TG3_TX_RING_SIZE - 1);
+		tg3_skb_error_unmap(tnapi, skb, i);
 
 		/* If the workaround fails due to memory/mapping
 		 * failure, silently drop this packet.
 		 */
-		if (tigon3_dma_hwbug_workaround(tnapi, skb, last_plus_one,
-						&start, base_flags, mss))
+		if (tigon3_dma_hwbug_workaround(tnapi, skb, base_flags, mss))
 			goto out_unlock;
 
-		entry = start;
+		entry = NEXT_TX(tnapi->tx_prod);
 	}
 
 	/* Packets are ready, update Tx producer idx local and on card. */
@@ -6096,25 +6102,66 @@
 	return NETDEV_TX_OK;
 
 dma_error:
-	last = i;
-	entry = tnapi->tx_prod;
-	tnapi->tx_buffers[entry].skb = NULL;
-	pci_unmap_single(tp->pdev,
-			 dma_unmap_addr(&tnapi->tx_buffers[entry], mapping),
-			 skb_headlen(skb),
-			 PCI_DMA_TODEVICE);
-	for (i = 0; i <= last; i++) {
-		skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
-		entry = NEXT_TX(entry);
+	tg3_skb_error_unmap(tnapi, skb, i);
+	dev_kfree_skb(skb);
+	tnapi->tx_buffers[tnapi->tx_prod].skb = NULL;
+	return NETDEV_TX_OK;
+}
 
-		pci_unmap_page(tp->pdev,
-			       dma_unmap_addr(&tnapi->tx_buffers[entry],
-					      mapping),
-			       frag->size, PCI_DMA_TODEVICE);
+static void tg3_set_loopback(struct net_device *dev, u32 features)
+{
+	struct tg3 *tp = netdev_priv(dev);
+
+	if (features & NETIF_F_LOOPBACK) {
+		if (tp->mac_mode & MAC_MODE_PORT_INT_LPBACK)
+			return;
+
+		/*
+		 * Clear MAC_MODE_HALF_DUPLEX or you won't get packets back in
+		 * loopback mode if Half-Duplex mode was negotiated earlier.
+		 */
+		tp->mac_mode &= ~MAC_MODE_HALF_DUPLEX;
+
+		/* Enable internal MAC loopback mode */
+		tp->mac_mode |= MAC_MODE_PORT_INT_LPBACK;
+		spin_lock_bh(&tp->lock);
+		tw32(MAC_MODE, tp->mac_mode);
+		netif_carrier_on(tp->dev);
+		spin_unlock_bh(&tp->lock);
+		netdev_info(dev, "Internal MAC loopback mode enabled.\n");
+	} else {
+		if (!(tp->mac_mode & MAC_MODE_PORT_INT_LPBACK))
+			return;
+
+		/* Disable internal MAC loopback mode */
+		tp->mac_mode &= ~MAC_MODE_PORT_INT_LPBACK;
+		spin_lock_bh(&tp->lock);
+		tw32(MAC_MODE, tp->mac_mode);
+		/* Force link status check */
+		tg3_setup_phy(tp, 1);
+		spin_unlock_bh(&tp->lock);
+		netdev_info(dev, "Internal MAC loopback mode disabled.\n");
 	}
+}
 
-	dev_kfree_skb(skb);
-	return NETDEV_TX_OK;
+static u32 tg3_fix_features(struct net_device *dev, u32 features)
+{
+	struct tg3 *tp = netdev_priv(dev);
+
+	if (dev->mtu > ETH_DATA_LEN && tg3_flag(tp, 5780_CLASS))
+		features &= ~NETIF_F_ALL_TSO;
+
+	return features;
+}
+
+static int tg3_set_features(struct net_device *dev, u32 features)
+{
+	u32 changed = dev->features ^ features;
+
+	if ((changed & NETIF_F_LOOPBACK) && netif_running(dev))
+		tg3_set_loopback(dev, features);
+
+	return 0;
 }
 
 static inline void tg3_set_mtu(struct net_device *dev, struct tg3 *tp,
@@ -6123,16 +6170,18 @@
 	dev->mtu = new_mtu;
 
 	if (new_mtu > ETH_DATA_LEN) {
-		if (tp->tg3_flags2 & TG3_FLG2_5780_CLASS) {
-			tp->tg3_flags2 &= ~TG3_FLG2_TSO_CAPABLE;
-			ethtool_op_set_tso(dev, 0);
+		if (tg3_flag(tp, 5780_CLASS)) {
+			netdev_update_features(dev);
+			tg3_flag_clear(tp, TSO_CAPABLE);
 		} else {
-			tp->tg3_flags |= TG3_FLAG_JUMBO_RING_ENABLE;
+			tg3_flag_set(tp, JUMBO_RING_ENABLE);
 		}
 	} else {
-		if (tp->tg3_flags2 & TG3_FLG2_5780_CLASS)
-			tp->tg3_flags2 |= TG3_FLG2_TSO_CAPABLE;
-		tp->tg3_flags &= ~TG3_FLAG_JUMBO_RING_ENABLE;
+		if (tg3_flag(tp, 5780_CLASS)) {
+			tg3_flag_set(tp, TSO_CAPABLE);
+			netdev_update_features(dev);
+		}
+		tg3_flag_clear(tp, JUMBO_RING_ENABLE);
 	}
 }
 
@@ -6186,7 +6235,7 @@
 			tg3_rx_skb_free(tp, &tpr->rx_std_buffers[i],
 					tp->rx_pkt_map_sz);
 
-		if (tp->tg3_flags & TG3_FLAG_JUMBO_CAPABLE) {
+		if (tg3_flag(tp, JUMBO_CAPABLE)) {
 			for (i = tpr->rx_jmb_cons_idx;
 			     i != tpr->rx_jmb_prod_idx;
 			     i = (i + 1) & tp->rx_jmb_ring_mask) {
@@ -6202,8 +6251,7 @@
 		tg3_rx_skb_free(tp, &tpr->rx_std_buffers[i],
 				tp->rx_pkt_map_sz);
 
-	if ((tp->tg3_flags & TG3_FLAG_JUMBO_CAPABLE) &&
-	    !(tp->tg3_flags2 & TG3_FLG2_5780_CLASS)) {
+	if (tg3_flag(tp, JUMBO_CAPABLE) && !tg3_flag(tp, 5780_CLASS)) {
 		for (i = 0; i <= tp->rx_jmb_ring_mask; i++)
 			tg3_rx_skb_free(tp, &tpr->rx_jmb_buffers[i],
 					TG3_RX_JMB_MAP_SZ);
@@ -6240,7 +6288,7 @@
 	memset(tpr->rx_std, 0, TG3_RX_STD_RING_BYTES(tp));
 
 	rx_pkt_dma_sz = TG3_RX_STD_DMA_SZ;
-	if ((tp->tg3_flags2 & TG3_FLG2_5780_CLASS) &&
+	if (tg3_flag(tp, 5780_CLASS) &&
 	    tp->dev->mtu > ETH_DATA_LEN)
 		rx_pkt_dma_sz = TG3_RX_JMB_DMA_SZ;
 	tp->rx_pkt_map_sz = TG3_RX_DMA_TO_MAP_SZ(rx_pkt_dma_sz);
@@ -6273,13 +6321,12 @@
 		}
 	}
 
-	if (!(tp->tg3_flags & TG3_FLAG_JUMBO_CAPABLE) ||
-	    (tp->tg3_flags2 & TG3_FLG2_5780_CLASS))
+	if (!tg3_flag(tp, JUMBO_CAPABLE) || tg3_flag(tp, 5780_CLASS))
 		goto done;
 
 	memset(tpr->rx_jmb, 0, TG3_RX_JMB_RING_BYTES(tp));
 
-	if (!(tp->tg3_flags & TG3_FLAG_JUMBO_RING_ENABLE))
+	if (!tg3_flag(tp, JUMBO_RING_ENABLE))
 		goto done;
 
 	for (i = 0; i <= tp->rx_jmb_ring_mask; i++) {
@@ -6348,8 +6395,7 @@
 	if (!tpr->rx_std)
 		goto err_out;
 
-	if ((tp->tg3_flags & TG3_FLAG_JUMBO_CAPABLE) &&
-	    !(tp->tg3_flags2 & TG3_FLG2_5780_CLASS)) {
+	if (tg3_flag(tp, JUMBO_CAPABLE) && !tg3_flag(tp, 5780_CLASS)) {
 		tpr->rx_jmb_buffers = kzalloc(TG3_RX_JMB_BUFF_RING_SIZE(tp),
 					      GFP_KERNEL);
 		if (!tpr->rx_jmb_buffers)
@@ -6547,8 +6593,8 @@
 		/* If multivector TSS is enabled, vector 0 does not handle
 		 * tx interrupts.  Don't allocate any resources for it.
 		 */
-		if ((!i && !(tp->tg3_flags3 & TG3_FLG3_ENABLE_TSS)) ||
-		    (i && (tp->tg3_flags3 & TG3_FLG3_ENABLE_TSS))) {
+		if ((!i && !tg3_flag(tp, ENABLE_TSS)) ||
+		    (i && tg3_flag(tp, ENABLE_TSS))) {
 			tnapi->tx_buffers = kzalloc(sizeof(struct ring_info) *
 						    TG3_TX_RING_SIZE,
 						    GFP_KERNEL);
@@ -6588,7 +6634,7 @@
 		 * If multivector RSS is enabled, vector 0 does not handle
 		 * rx or tx interrupts.  Don't allocate any resources for it.
 		 */
-		if (!i && (tp->tg3_flags3 & TG3_FLG3_ENABLE_RSS))
+		if (!i && tg3_flag(tp, ENABLE_RSS))
 			continue;
 
 		tnapi->rx_rcb = dma_alloc_coherent(&tp->pdev->dev,
@@ -6618,7 +6664,7 @@
 	unsigned int i;
 	u32 val;
 
-	if (tp->tg3_flags2 & TG3_FLG2_5705_PLUS) {
+	if (tg3_flag(tp, 5705_PLUS)) {
 		switch (ofs) {
 		case RCVLSC_MODE:
 		case DMAC_MODE:
@@ -6728,7 +6774,7 @@
 	u32 apedata;
 
 	/* NCSI does not support APE events */
-	if (tp->tg3_flags3 & TG3_FLG3_APE_HAS_NCSI)
+	if (tg3_flag(tp, APE_HAS_NCSI))
 		return;
 
 	apedata = tg3_ape_read32(tp, TG3_APE_SEG_SIG);
@@ -6767,7 +6813,7 @@
 	u32 event;
 	u32 apedata;
 
-	if (!(tp->tg3_flags3 & TG3_FLG3_ENABLE_APE))
+	if (!tg3_flag(tp, ENABLE_APE))
 		return;
 
 	switch (kind) {
@@ -6796,7 +6842,7 @@
 		tg3_ape_write32(tp, TG3_APE_HOST_SEG_SIG, 0x0);
 
 		if (device_may_wakeup(&tp->pdev->dev) &&
-		    (tp->tg3_flags & TG3_FLAG_WOL_ENABLE)) {
+		    tg3_flag(tp, WOL_ENABLE)) {
 			tg3_ape_write32(tp, TG3_APE_HOST_WOL_SPEED,
 					    TG3_APE_HOST_WOL_SPEED_AUTO);
 			apedata = TG3_APE_HOST_DRVR_STATE_WOL;
@@ -6825,7 +6871,7 @@
 	tg3_write_mem(tp, NIC_SRAM_FIRMWARE_MBOX,
 		      NIC_SRAM_FIRMWARE_MBOX_MAGIC1);
 
-	if (tp->tg3_flags2 & TG3_FLG2_ASF_NEW_HANDSHAKE) {
+	if (tg3_flag(tp, ASF_NEW_HANDSHAKE)) {
 		switch (kind) {
 		case RESET_KIND_INIT:
 			tg3_write_mem(tp, NIC_SRAM_FW_DRV_STATE_MBOX,
@@ -6855,7 +6901,7 @@
 /* tp->lock is held. */
 static void tg3_write_sig_post_reset(struct tg3 *tp, int kind)
 {
-	if (tp->tg3_flags2 & TG3_FLG2_ASF_NEW_HANDSHAKE) {
+	if (tg3_flag(tp, ASF_NEW_HANDSHAKE)) {
 		switch (kind) {
 		case RESET_KIND_INIT:
 			tg3_write_mem(tp, NIC_SRAM_FW_DRV_STATE_MBOX,
@@ -6879,7 +6925,7 @@
 /* tp->lock is held. */
 static void tg3_write_sig_legacy(struct tg3 *tp, int kind)
 {
-	if (tp->tg3_flags & TG3_FLAG_ENABLE_ASF) {
+	if (tg3_flag(tp, ENABLE_ASF)) {
 		switch (kind) {
 		case RESET_KIND_INIT:
 			tg3_write_mem(tp, NIC_SRAM_FW_DRV_STATE_MBOX,
@@ -6930,9 +6976,8 @@
 	 * of the above loop as an error, but do report the lack of
 	 * running firmware once.
 	 */
-	if (i >= 100000 &&
-	    !(tp->tg3_flags2 & TG3_FLG2_NO_FWARE_REPORTED)) {
-		tp->tg3_flags2 |= TG3_FLG2_NO_FWARE_REPORTED;
+	if (i >= 100000 && !tg3_flag(tp, NO_FWARE_REPORTED)) {
+		tg3_flag_set(tp, NO_FWARE_REPORTED);
 
 		netdev_info(tp->dev, "No firmware running\n");
 	}
@@ -6965,10 +7010,10 @@
 	/* Set MAX PCI retry to zero. */
 	val = (PCISTATE_ROM_ENABLE | PCISTATE_ROM_RETRY_ENABLE);
 	if (tp->pci_chip_rev_id == CHIPREV_ID_5704_A0 &&
-	    (tp->tg3_flags & TG3_FLAG_PCIX_MODE))
+	    tg3_flag(tp, PCIX_MODE))
 		val |= PCISTATE_RETRY_SAME_DMA;
 	/* Allow reads and writes to the APE register and memory space. */
-	if (tp->tg3_flags3 & TG3_FLG3_ENABLE_APE)
+	if (tg3_flag(tp, ENABLE_APE))
 		val |= PCISTATE_ALLOW_APE_CTLSPC_WR |
 		       PCISTATE_ALLOW_APE_SHMEM_WR |
 		       PCISTATE_ALLOW_APE_PSPACE_WR;
@@ -6977,7 +7022,7 @@
 	pci_write_config_word(tp->pdev, PCI_COMMAND, tp->pci_cmd);
 
 	if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5785) {
-		if (tp->tg3_flags2 & TG3_FLG2_PCI_EXPRESS)
+		if (tg3_flag(tp, PCI_EXPRESS))
 			pcie_set_readrq(tp->pdev, tp->pcie_readrq);
 		else {
 			pci_write_config_byte(tp->pdev, PCI_CACHE_LINE_SIZE,
@@ -6988,7 +7033,7 @@
 	}
 
 	/* Make sure PCI-X relaxed ordering bit is clear. */
-	if (tp->tg3_flags & TG3_FLAG_PCIX_MODE) {
+	if (tg3_flag(tp, PCIX_MODE)) {
 		u16 pcix_cmd;
 
 		pci_read_config_word(tp->pdev, tp->pcix_cap + PCI_X_CMD,
@@ -6998,12 +7043,12 @@
 				      pcix_cmd);
 	}
 
-	if (tp->tg3_flags2 & TG3_FLG2_5780_CLASS) {
+	if (tg3_flag(tp, 5780_CLASS)) {
 
 		/* Chip reset on 5780 will reset MSI enable bit,
 		 * so need to restore it.
 		 */
-		if (tp->tg3_flags2 & TG3_FLG2_USING_MSI) {
+		if (tg3_flag(tp, USING_MSI)) {
 			u16 ctrl;
 
 			pci_read_config_word(tp->pdev,
@@ -7043,7 +7088,7 @@
 	tg3_save_pci_state(tp);
 
 	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5752 ||
-	    (tp->tg3_flags3 & TG3_FLG3_5755_PLUS))
+	    tg3_flag(tp, 5755_PLUS))
 		tw32(GRC_FASTBOOT_PC, 0);
 
 	/*
@@ -7062,7 +7107,7 @@
 	 * at this time, but the irq handler may still be called due to irq
 	 * sharing or irqpoll.
 	 */
-	tp->tg3_flags |= TG3_FLAG_CHIP_RESETTING;
+	tg3_flag_set(tp, CHIP_RESETTING);
 	for (i = 0; i < tp->irq_cnt; i++) {
 		struct tg3_napi *tnapi = &tp->napi[i];
 		if (tnapi->hw_status) {
@@ -7085,10 +7130,10 @@
 	/* do the reset */
 	val = GRC_MISC_CFG_CORECLK_RESET;
 
-	if (tp->tg3_flags2 & TG3_FLG2_PCI_EXPRESS) {
+	if (tg3_flag(tp, PCI_EXPRESS)) {
 		/* Force PCIe 1.0a mode */
 		if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5785 &&
-		    !(tp->tg3_flags3 & TG3_FLG3_5717_PLUS) &&
+		    !tg3_flag(tp, 57765_PLUS) &&
 		    tr32(TG3_PCIE_PHY_TSTCTL) ==
 		    (TG3_PCIE_PHY_TSTCTL_PCIE10 | TG3_PCIE_PHY_TSTCTL_PSCRAM))
 			tw32(TG3_PCIE_PHY_TSTCTL, TG3_PCIE_PHY_TSTCTL_PSCRAM);
@@ -7106,8 +7151,7 @@
 	}
 
 	/* Manage gphy power for all CPMU absent PCIe devices. */
-	if ((tp->tg3_flags2 & TG3_FLG2_5705_PLUS) &&
-	    !(tp->tg3_flags & TG3_FLAG_CPMU_PRESENT))
+	if (tg3_flag(tp, 5705_PLUS) && !tg3_flag(tp, CPMU_PRESENT))
 		val |= GRC_MISC_CFG_KEEP_GPHY_POWER;
 
 	tw32(GRC_MISC_CFG, val);
@@ -7140,7 +7184,7 @@
 
 	udelay(120);
 
-	if ((tp->tg3_flags2 & TG3_FLG2_PCI_EXPRESS) && tp->pcie_cap) {
+	if (tg3_flag(tp, PCI_EXPRESS) && tp->pcie_cap) {
 		u16 val16;
 
 		if (tp->pci_chip_rev_id == CHIPREV_ID_5750_A0) {
@@ -7166,7 +7210,7 @@
 		 * Older PCIe devices only support the 128 byte
 		 * MPS setting.  Enforce the restriction.
 		 */
-		if (!(tp->tg3_flags & TG3_FLAG_CPMU_PRESENT))
+		if (!tg3_flag(tp, CPMU_PRESENT))
 			val16 &= ~PCI_EXP_DEVCTL_PAYLOAD;
 		pci_write_config_word(tp->pdev,
 				      tp->pcie_cap + PCI_EXP_DEVCTL,
@@ -7185,10 +7229,11 @@
 
 	tg3_restore_pci_state(tp);
 
-	tp->tg3_flags &= ~TG3_FLAG_CHIP_RESETTING;
+	tg3_flag_clear(tp, CHIP_RESETTING);
+	tg3_flag_clear(tp, ERROR_PROCESSED);
 
 	val = 0;
-	if (tp->tg3_flags2 & TG3_FLG2_5780_CLASS)
+	if (tg3_flag(tp, 5780_CLASS))
 		val = tr32(MEMARB_MODE);
 	tw32(MEMARB_MODE, val | MEMARB_MODE_ENABLE);
 
@@ -7213,7 +7258,7 @@
 		tw32(TG3PCI_CLOCK_CTRL, tp->pci_clock_ctrl);
 	}
 
-	if (tp->tg3_flags3 & TG3_FLG3_ENABLE_APE)
+	if (tg3_flag(tp, ENABLE_APE))
 		tp->mac_mode = MAC_MODE_APE_TX_EN |
 			       MAC_MODE_APE_RX_EN |
 			       MAC_MODE_TDE_ENABLE;
@@ -7238,28 +7283,33 @@
 
 	tg3_mdio_start(tp);
 
-	if ((tp->tg3_flags2 & TG3_FLG2_PCI_EXPRESS) &&
+	if (tg3_flag(tp, PCI_EXPRESS) &&
 	    tp->pci_chip_rev_id != CHIPREV_ID_5750_A0 &&
 	    GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5785 &&
-	    !(tp->tg3_flags3 & TG3_FLG3_5717_PLUS)) {
+	    !tg3_flag(tp, 57765_PLUS)) {
 		val = tr32(0x7c00);
 
 		tw32(0x7c00, val | (1 << 25));
 	}
 
+	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5720) {
+		val = tr32(TG3_CPMU_CLCK_ORIDE);
+		tw32(TG3_CPMU_CLCK_ORIDE, val & ~CPMU_CLCK_ORIDE_MAC_ORIDE_EN);
+	}
+
 	/* Reprobe ASF enable state.  */
-	tp->tg3_flags &= ~TG3_FLAG_ENABLE_ASF;
-	tp->tg3_flags2 &= ~TG3_FLG2_ASF_NEW_HANDSHAKE;
+	tg3_flag_clear(tp, ENABLE_ASF);
+	tg3_flag_clear(tp, ASF_NEW_HANDSHAKE);
 	tg3_read_mem(tp, NIC_SRAM_DATA_SIG, &val);
 	if (val == NIC_SRAM_DATA_SIG_MAGIC) {
 		u32 nic_cfg;
 
 		tg3_read_mem(tp, NIC_SRAM_DATA_CFG, &nic_cfg);
 		if (nic_cfg & NIC_SRAM_DATA_CFG_ASF_ENABLE) {
-			tp->tg3_flags |= TG3_FLAG_ENABLE_ASF;
+			tg3_flag_set(tp, ENABLE_ASF);
 			tp->last_event_jiffies = jiffies;
-			if (tp->tg3_flags2 & TG3_FLG2_5750_PLUS)
-				tp->tg3_flags2 |= TG3_FLG2_ASF_NEW_HANDSHAKE;
+			if (tg3_flag(tp, 5750_PLUS))
+				tg3_flag_set(tp, ASF_NEW_HANDSHAKE);
 		}
 	}
 
@@ -7269,8 +7319,7 @@
 /* tp->lock is held. */
 static void tg3_stop_fw(struct tg3 *tp)
 {
-	if ((tp->tg3_flags & TG3_FLAG_ENABLE_ASF) &&
-	   !(tp->tg3_flags3 & TG3_FLG3_ENABLE_APE)) {
+	if (tg3_flag(tp, ENABLE_ASF) && !tg3_flag(tp, ENABLE_APE)) {
 		/* Wait for RX cpu to ACK the previous event. */
 		tg3_wait_for_event_ack(tp);
 
@@ -7316,8 +7365,7 @@
 {
 	int i;
 
-	BUG_ON(offset == TX_CPU_BASE &&
-	    (tp->tg3_flags2 & TG3_FLG2_5705_PLUS));
+	BUG_ON(offset == TX_CPU_BASE && tg3_flag(tp, 5705_PLUS));
 
 	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) {
 		u32 val = tr32(GRC_VCPU_EXT_CTRL);
@@ -7352,7 +7400,7 @@
 	}
 
 	/* Clear firmware's nvram arbitration. */
-	if (tp->tg3_flags & TG3_FLAG_NVRAM)
+	if (tg3_flag(tp, NVRAM))
 		tw32(NVRAM_SWARB, SWARB_REQ_CLR0);
 	return 0;
 }
@@ -7370,15 +7418,14 @@
 	int err, lock_err, i;
 	void (*write_op)(struct tg3 *, u32, u32);
 
-	if (cpu_base == TX_CPU_BASE &&
-	    (tp->tg3_flags2 & TG3_FLG2_5705_PLUS)) {
+	if (cpu_base == TX_CPU_BASE && tg3_flag(tp, 5705_PLUS)) {
 		netdev_err(tp->dev,
 			   "%s: Trying to load TX cpu firmware which is 5705\n",
 			   __func__);
 		return -EINVAL;
 	}
 
-	if (tp->tg3_flags2 & TG3_FLG2_5705_PLUS)
+	if (tg3_flag(tp, 5705_PLUS))
 		write_op = tg3_write_mem;
 	else
 		write_op = tg3_write_indirect_reg32;
@@ -7464,8 +7511,6 @@
 	return 0;
 }
 
-/* 5705 needs a special version of the TSO firmware.  */
-
 /* tp->lock is held. */
 static int tg3_load_tso_firmware(struct tg3 *tp)
 {
@@ -7474,7 +7519,9 @@
 	unsigned long cpu_base, cpu_scratch_base, cpu_scratch_size;
 	int err, i;
 
-	if (tp->tg3_flags2 & TG3_FLG2_HW_TSO)
+	if (tg3_flag(tp, HW_TSO_1) ||
+	    tg3_flag(tp, HW_TSO_2) ||
+	    tg3_flag(tp, HW_TSO_3))
 		return 0;
 
 	fw_data = (void *)tp->fw->data;
@@ -7543,7 +7590,7 @@
 	if (!netif_running(dev))
 		return 0;
 
-	if (tp->tg3_flags & TG3_FLAG_ENABLE_ASF) {
+	if (tg3_flag(tp, ENABLE_ASF)) {
 		u32 addr0_high, addr0_low, addr1_high, addr1_low;
 
 		addr0_high = tr32(MAC_ADDR_0_HIGH);
@@ -7578,7 +7625,7 @@
 		      (bdinfo_addr + TG3_BDINFO_MAXLEN_FLAGS),
 		       maxlen_flags);
 
-	if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS))
+	if (!tg3_flag(tp, 5705_PLUS))
 		tg3_write_mem(tp,
 			      (bdinfo_addr + TG3_BDINFO_NIC_ADDR),
 			      nic_addr);
@@ -7589,7 +7636,7 @@
 {
 	int i;
 
-	if (!(tp->tg3_flags3 & TG3_FLG3_ENABLE_TSS)) {
+	if (!tg3_flag(tp, ENABLE_TSS)) {
 		tw32(HOSTCC_TXCOL_TICKS, ec->tx_coalesce_usecs);
 		tw32(HOSTCC_TXMAX_FRAMES, ec->tx_max_coalesced_frames);
 		tw32(HOSTCC_TXCOAL_MAXF_INT, ec->tx_max_coalesced_frames_irq);
@@ -7599,7 +7646,7 @@
 		tw32(HOSTCC_TXCOAL_MAXF_INT, 0);
 	}
 
-	if (!(tp->tg3_flags3 & TG3_FLG3_ENABLE_RSS)) {
+	if (!tg3_flag(tp, ENABLE_RSS)) {
 		tw32(HOSTCC_RXCOL_TICKS, ec->rx_coalesce_usecs);
 		tw32(HOSTCC_RXMAX_FRAMES, ec->rx_max_coalesced_frames);
 		tw32(HOSTCC_RXCOAL_MAXF_INT, ec->rx_max_coalesced_frames_irq);
@@ -7609,7 +7656,7 @@
 		tw32(HOSTCC_RXCOAL_MAXF_INT, 0);
 	}
 
-	if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS)) {
+	if (!tg3_flag(tp, 5705_PLUS)) {
 		u32 val = ec->stats_block_coalesce_usecs;
 
 		tw32(HOSTCC_RXCOAL_TICK_INT, ec->rx_coalesce_usecs_irq);
@@ -7631,7 +7678,7 @@
 		reg = HOSTCC_RXCOAL_MAXF_INT_VEC1 + i * 0x18;
 		tw32(reg, ec->rx_max_coalesced_frames_irq);
 
-		if (tp->tg3_flags3 & TG3_FLG3_ENABLE_TSS) {
+		if (tg3_flag(tp, ENABLE_TSS)) {
 			reg = HOSTCC_TXCOL_TICKS_VEC1 + i * 0x18;
 			tw32(reg, ec->tx_coalesce_usecs);
 			reg = HOSTCC_TXMAX_FRAMES_VEC1 + i * 0x18;
@@ -7646,7 +7693,7 @@
 		tw32(HOSTCC_RXMAX_FRAMES_VEC1 + i * 0x18, 0);
 		tw32(HOSTCC_RXCOAL_MAXF_INT_VEC1 + i * 0x18, 0);
 
-		if (tp->tg3_flags3 & TG3_FLG3_ENABLE_TSS) {
+		if (tg3_flag(tp, ENABLE_TSS)) {
 			tw32(HOSTCC_TXCOL_TICKS_VEC1 + i * 0x18, 0);
 			tw32(HOSTCC_TXMAX_FRAMES_VEC1 + i * 0x18, 0);
 			tw32(HOSTCC_TXCOAL_MAXF_INT_VEC1 + i * 0x18, 0);
@@ -7662,10 +7709,9 @@
 	struct tg3_napi *tnapi = &tp->napi[0];
 
 	/* Disable all transmit rings but the first. */
-	if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS))
+	if (!tg3_flag(tp, 5705_PLUS))
 		limit = NIC_SRAM_SEND_RCB + TG3_BDINFO_SIZE * 16;
-	else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 ||
-		 GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719)
+	else if (tg3_flag(tp, 5717_PLUS))
 		limit = NIC_SRAM_SEND_RCB + TG3_BDINFO_SIZE * 4;
 	else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765)
 		limit = NIC_SRAM_SEND_RCB + TG3_BDINFO_SIZE * 2;
@@ -7679,10 +7725,9 @@
 
 
 	/* Disable all receive return rings but the first. */
-	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 ||
-	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719)
+	if (tg3_flag(tp, 5717_PLUS))
 		limit = NIC_SRAM_RCV_RET_RCB + TG3_BDINFO_SIZE * 17;
-	else if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS))
+	else if (!tg3_flag(tp, 5705_PLUS))
 		limit = NIC_SRAM_RCV_RET_RCB + TG3_BDINFO_SIZE * 16;
 	else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755 ||
 		 GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765)
@@ -7699,16 +7744,16 @@
 	tw32_mailbox_f(tp->napi[0].int_mbox, 1);
 
 	/* Zero mailbox registers. */
-	if (tp->tg3_flags & TG3_FLAG_SUPPORT_MSIX) {
+	if (tg3_flag(tp, SUPPORT_MSIX)) {
 		for (i = 1; i < tp->irq_max; i++) {
 			tp->napi[i].tx_prod = 0;
 			tp->napi[i].tx_cons = 0;
-			if (tp->tg3_flags3 & TG3_FLG3_ENABLE_TSS)
+			if (tg3_flag(tp, 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))
+		if (!tg3_flag(tp, ENABLE_TSS))
 			tw32_mailbox(tp->napi[0].prodmbox, 0);
 	} else {
 		tp->napi[0].tx_prod = 0;
@@ -7718,7 +7763,7 @@
 	}
 
 	/* Make sure the NIC-based send BD rings are disabled. */
-	if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS)) {
+	if (!tg3_flag(tp, 5705_PLUS)) {
 		u32 mbox = MAILBOX_SNDNIC_PROD_IDX_0 + TG3_64BIT_REG_LOW;
 		for (i = 0; i < 16; i++)
 			tw32_tx_mbox(mbox + i * 8, 0);
@@ -7778,6 +7823,47 @@
 	}
 }
 
+static void tg3_setup_rxbd_thresholds(struct tg3 *tp)
+{
+	u32 val, bdcache_maxcnt, host_rep_thresh, nic_rep_thresh;
+
+	if (!tg3_flag(tp, 5750_PLUS) ||
+	    tg3_flag(tp, 5780_CLASS) ||
+	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5750 ||
+	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5752)
+		bdcache_maxcnt = TG3_SRAM_RX_STD_BDCACHE_SIZE_5700;
+	else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755 ||
+		 GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5787)
+		bdcache_maxcnt = TG3_SRAM_RX_STD_BDCACHE_SIZE_5755;
+	else
+		bdcache_maxcnt = TG3_SRAM_RX_STD_BDCACHE_SIZE_5906;
+
+	nic_rep_thresh = min(bdcache_maxcnt / 2, tp->rx_std_max_post);
+	host_rep_thresh = max_t(u32, tp->rx_pending / 8, 1);
+
+	val = min(nic_rep_thresh, host_rep_thresh);
+	tw32(RCVBDI_STD_THRESH, val);
+
+	if (tg3_flag(tp, 57765_PLUS))
+		tw32(STD_REPLENISH_LWM, bdcache_maxcnt);
+
+	if (!tg3_flag(tp, JUMBO_CAPABLE) || tg3_flag(tp, 5780_CLASS))
+		return;
+
+	if (!tg3_flag(tp, 5705_PLUS))
+		bdcache_maxcnt = TG3_SRAM_RX_JMB_BDCACHE_SIZE_5700;
+	else
+		bdcache_maxcnt = TG3_SRAM_RX_JMB_BDCACHE_SIZE_5717;
+
+	host_rep_thresh = max_t(u32, tp->rx_jumbo_pending / 8, 1);
+
+	val = min(bdcache_maxcnt / 2, host_rep_thresh);
+	tw32(RCVBDI_JUMBO_THRESH, val);
+
+	if (tg3_flag(tp, 57765_PLUS))
+		tw32(JMB_REPLENISH_LWM, bdcache_maxcnt);
+}
+
 /* tp->lock is held. */
 static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
 {
@@ -7791,7 +7877,7 @@
 
 	tg3_write_sig_pre_reset(tp, RESET_KIND_INIT);
 
-	if (tp->tg3_flags & TG3_FLAG_INIT_COMPLETE)
+	if (tg3_flag(tp, INIT_COMPLETE))
 		tg3_abort_hw(tp, 1);
 
 	/* Enable MAC control of LPI */
@@ -7811,7 +7897,7 @@
 		if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5717)
 			val |= TG3_CPMU_EEEMD_SND_IDX_DET_EN;
 
-		if (tp->tg3_flags3 & TG3_FLG3_ENABLE_APE)
+		if (tg3_flag(tp, ENABLE_APE))
 			val |= TG3_CPMU_EEEMD_APE_TX_DET_EN;
 
 		tw32_f(TG3_CPMU_EEE_MODE, val);
@@ -7870,7 +7956,7 @@
 		tw32(TG3_PCIE_LNKCTL, val | TG3_PCIE_LNKCTL_L1_PLL_PD_DIS);
 	}
 
-	if (tp->tg3_flags3 & TG3_FLG3_L1PLLPD_EN) {
+	if (tg3_flag(tp, L1PLLPD_EN)) {
 		u32 grc_mode = tr32(GRC_MODE);
 
 		/* Access the lower 1K of PL PCIE block registers. */
@@ -7900,6 +7986,22 @@
 			tw32(GRC_MODE, grc_mode);
 		}
 
+		if (GET_CHIP_REV(tp->pci_chip_rev_id) != CHIPREV_57765_AX) {
+			u32 grc_mode = tr32(GRC_MODE);
+
+			/* Access the lower 1K of DL PCIE block registers. */
+			val = grc_mode & ~GRC_MODE_PCIE_PORT_MASK;
+			tw32(GRC_MODE, val | GRC_MODE_PCIE_DL_SEL);
+
+			val = tr32(TG3_PCIE_TLDLPL_PORT +
+				   TG3_PCIE_DL_LO_FTSMAX);
+			val &= ~TG3_PCIE_DL_LO_FTSMAX_MSK;
+			tw32(TG3_PCIE_TLDLPL_PORT + TG3_PCIE_DL_LO_FTSMAX,
+			     val | TG3_PCIE_DL_LO_FTSMAX_VAL);
+
+			tw32(GRC_MODE, grc_mode);
+		}
+
 		val = tr32(TG3_CPMU_LSPD_10MB_CLK);
 		val &= ~CPMU_LSPD_10MB_MACCLK_MASK;
 		val |= CPMU_LSPD_10MB_MACCLK_6_25;
@@ -7911,20 +8013,20 @@
 	 * other revision.  But do not set this on PCI Express
 	 * chips and don't even touch the clocks if the CPMU is present.
 	 */
-	if (!(tp->tg3_flags & TG3_FLAG_CPMU_PRESENT)) {
-		if (!(tp->tg3_flags2 & TG3_FLG2_PCI_EXPRESS))
+	if (!tg3_flag(tp, CPMU_PRESENT)) {
+		if (!tg3_flag(tp, PCI_EXPRESS))
 			tp->pci_clock_ctrl |= CLOCK_CTRL_DELAY_PCI_GRANT;
 		tw32_f(TG3PCI_CLOCK_CTRL, tp->pci_clock_ctrl);
 	}
 
 	if (tp->pci_chip_rev_id == CHIPREV_ID_5704_A0 &&
-	    (tp->tg3_flags & TG3_FLAG_PCIX_MODE)) {
+	    tg3_flag(tp, PCIX_MODE)) {
 		val = tr32(TG3PCI_PCISTATE);
 		val |= PCISTATE_RETRY_SAME_DMA;
 		tw32(TG3PCI_PCISTATE, val);
 	}
 
-	if (tp->tg3_flags3 & TG3_FLG3_ENABLE_APE) {
+	if (tg3_flag(tp, ENABLE_APE)) {
 		/* Allow reads and writes to the
 		 * APE register and memory space.
 		 */
@@ -7951,11 +8053,14 @@
 	if (err)
 		return err;
 
-	if (tp->tg3_flags3 & TG3_FLG3_5717_PLUS) {
+	if (tg3_flag(tp, 57765_PLUS)) {
 		val = tr32(TG3PCI_DMA_RW_CTRL) &
 		      ~DMA_RWCTRL_DIS_CACHE_ALIGNMENT;
 		if (tp->pci_chip_rev_id == CHIPREV_ID_57765_A0)
 			val &= ~DMA_RWCTRL_CRDRDR_RDMA_MRRS_MSK;
+		if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_57765 &&
+		    GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5717)
+			val |= DMA_RWCTRL_TAGGED_STAT_WA;
 		tw32(TG3PCI_DMA_RW_CTRL, val | tp->dma_rwctrl);
 	} else if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5784 &&
 		   GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5761) {
@@ -7990,7 +8095,7 @@
 	tw32(GRC_MISC_CFG, val);
 
 	/* Initialize MBUF/DESC pool. */
-	if (tp->tg3_flags2 & TG3_FLG2_5750_PLUS) {
+	if (tg3_flag(tp, 5750_PLUS)) {
 		/* Do nothing.  */
 	} else if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5705) {
 		tw32(BUFMGR_MB_POOL_ADDR, NIC_SRAM_MBUF_POOL_BASE);
@@ -8000,7 +8105,7 @@
 			tw32(BUFMGR_MB_POOL_SIZE, NIC_SRAM_MBUF_POOL_SIZE96);
 		tw32(BUFMGR_DMA_DESC_POOL_ADDR, NIC_SRAM_DMA_DESC_POOL_BASE);
 		tw32(BUFMGR_DMA_DESC_POOL_SIZE, NIC_SRAM_DMA_DESC_POOL_SIZE);
-	} else if (tp->tg3_flags2 & TG3_FLG2_TSO_CAPABLE) {
+	} else if (tg3_flag(tp, TSO_CAPABLE)) {
 		int fw_len;
 
 		fw_len = tp->fw_len;
@@ -8034,6 +8139,10 @@
 	val = BUFMGR_MODE_ENABLE | BUFMGR_MODE_ATTN_ENABLE;
 	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719)
 		val |= BUFMGR_MODE_NO_TX_UNDERRUN;
+	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 ||
+	    tp->pci_chip_rev_id == CHIPREV_ID_5719_A0 ||
+	    tp->pci_chip_rev_id == CHIPREV_ID_5720_A0)
+		val |= BUFMGR_MODE_MBLOW_ATTN_ENAB;
 	tw32(BUFMGR_MODE, val);
 	for (i = 0; i < 2000; i++) {
 		if (tr32(BUFMGR_MODE) & BUFMGR_MODE_ENABLE)
@@ -8045,21 +8154,10 @@
 		return -ENODEV;
 	}
 
-	/* Setup replenish threshold. */
-	val = tp->rx_pending / 8;
-	if (val == 0)
-		val = 1;
-	else if (val > tp->rx_std_max_post)
-		val = tp->rx_std_max_post;
-	else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) {
-		if (tp->pci_chip_rev_id == CHIPREV_ID_5906_A1)
-			tw32(ISO_PKT_TX, (tr32(ISO_PKT_TX) & ~0x3) | 0x2);
-
-		if (val > (TG3_RX_INTERNAL_RING_SZ_5906 / 2))
-			val = TG3_RX_INTERNAL_RING_SZ_5906 / 2;
-	}
+	if (tp->pci_chip_rev_id == CHIPREV_ID_5906_A1)
+		tw32(ISO_PKT_TX, (tr32(ISO_PKT_TX) & ~0x3) | 0x2);
 
-	tw32(RCVBDI_STD_THRESH, val);
+	tg3_setup_rxbd_thresholds(tp);
 
 	/* Initialize TG3_BDINFO's at:
 	 *  RCVDBDI_STD_BD:	standard eth size rx ring
@@ -8082,13 +8180,12 @@
 	     ((u64) tpr->rx_std_mapping >> 32));
 	tw32(RCVDBDI_STD_BD + TG3_BDINFO_HOST_ADDR + TG3_64BIT_REG_LOW,
 	     ((u64) tpr->rx_std_mapping & 0xffffffff));
-	if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5717 &&
-	    GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5719)
+	if (!tg3_flag(tp, 5717_PLUS))
 		tw32(RCVDBDI_STD_BD + TG3_BDINFO_NIC_ADDR,
 		     NIC_SRAM_RX_BUFFER_DESC);
 
 	/* Disable the mini ring */
-	if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS))
+	if (!tg3_flag(tp, 5705_PLUS))
 		tw32(RCVDBDI_MINI_BD + TG3_BDINFO_MAXLEN_FLAGS,
 		     BDINFO_FLAGS_DISABLED);
 
@@ -8096,20 +8193,18 @@
 	 * blocks on those devices that have them.
 	 */
 	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719 ||
-	    ((tp->tg3_flags & TG3_FLAG_JUMBO_CAPABLE) &&
-	    !(tp->tg3_flags2 & TG3_FLG2_5780_CLASS))) {
-		/* Setup replenish threshold. */
-		tw32(RCVBDI_JUMBO_THRESH, tp->rx_jumbo_pending / 8);
+	    (tg3_flag(tp, JUMBO_CAPABLE) && !tg3_flag(tp, 5780_CLASS))) {
 
-		if (tp->tg3_flags & TG3_FLAG_JUMBO_RING_ENABLE) {
+		if (tg3_flag(tp, JUMBO_RING_ENABLE)) {
 			tw32(RCVDBDI_JUMBO_BD + TG3_BDINFO_HOST_ADDR + TG3_64BIT_REG_HIGH,
 			     ((u64) tpr->rx_jmb_mapping >> 32));
 			tw32(RCVDBDI_JUMBO_BD + TG3_BDINFO_HOST_ADDR + TG3_64BIT_REG_LOW,
 			     ((u64) tpr->rx_jmb_mapping & 0xffffffff));
+			val = TG3_RX_JMB_RING_SIZE(tp) <<
+			      BDINFO_FLAGS_MAXLEN_SHIFT;
 			tw32(RCVDBDI_JUMBO_BD + TG3_BDINFO_MAXLEN_FLAGS,
-			     (RX_JUMBO_MAX_SIZE << BDINFO_FLAGS_MAXLEN_SHIFT) |
-			     BDINFO_FLAGS_USE_EXT_RECV);
-			if (!(tp->tg3_flags3 & TG3_FLG3_USE_JUMBO_BDFLAG) ||
+			     val | BDINFO_FLAGS_USE_EXT_RECV);
+			if (!tg3_flag(tp, USE_JUMBO_BDFLAG) ||
 			    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765)
 				tw32(RCVDBDI_JUMBO_BD + TG3_BDINFO_NIC_ADDR,
 				     NIC_SRAM_RX_JUMBO_BUFFER_DESC);
@@ -8118,32 +8213,27 @@
 			     BDINFO_FLAGS_DISABLED);
 		}
 
-		if (tp->tg3_flags3 & TG3_FLG3_5717_PLUS) {
+		if (tg3_flag(tp, 57765_PLUS)) {
 			if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765)
-				val = RX_STD_MAX_SIZE_5705;
+				val = TG3_RX_STD_MAX_SIZE_5700;
 			else
-				val = RX_STD_MAX_SIZE_5717;
+				val = TG3_RX_STD_MAX_SIZE_5717;
 			val <<= BDINFO_FLAGS_MAXLEN_SHIFT;
 			val |= (TG3_RX_STD_DMA_SZ << 2);
 		} else
 			val = TG3_RX_STD_DMA_SZ << BDINFO_FLAGS_MAXLEN_SHIFT;
 	} else
-		val = RX_STD_MAX_SIZE_5705 << BDINFO_FLAGS_MAXLEN_SHIFT;
+		val = TG3_RX_STD_MAX_SIZE_5700 << BDINFO_FLAGS_MAXLEN_SHIFT;
 
 	tw32(RCVDBDI_STD_BD + TG3_BDINFO_MAXLEN_FLAGS, val);
 
 	tpr->rx_std_prod_idx = tp->rx_pending;
 	tw32_rx_mbox(TG3_RX_STD_PROD_IDX_REG, tpr->rx_std_prod_idx);
 
-	tpr->rx_jmb_prod_idx = (tp->tg3_flags & TG3_FLAG_JUMBO_RING_ENABLE) ?
-			  tp->rx_jumbo_pending : 0;
+	tpr->rx_jmb_prod_idx =
+		tg3_flag(tp, JUMBO_RING_ENABLE) ? tp->rx_jumbo_pending : 0;
 	tw32_rx_mbox(TG3_RX_JMB_PROD_IDX_REG, tpr->rx_jmb_prod_idx);
 
-	if (tp->tg3_flags3 & TG3_FLG3_5717_PLUS) {
-		tw32(STD_REPLENISH_LWM, 32);
-		tw32(JMB_REPLENISH_LWM, 16);
-	}
-
 	tg3_rings_reset(tp);
 
 	/* Initialize MAC address and backoff seed. */
@@ -8156,10 +8246,16 @@
 	/* The slot time is changed by tg3_setup_phy if we
 	 * run at gigabit with half duplex.
 	 */
-	tw32(MAC_TX_LENGTHS,
-	     (2 << TX_LENGTHS_IPG_CRS_SHIFT) |
-	     (6 << TX_LENGTHS_IPG_SHIFT) |
-	     (32 << TX_LENGTHS_SLOT_TIME_SHIFT));
+	val = (2 << TX_LENGTHS_IPG_CRS_SHIFT) |
+	      (6 << TX_LENGTHS_IPG_SHIFT) |
+	      (32 << TX_LENGTHS_SLOT_TIME_SHIFT);
+
+	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5720)
+		val |= tr32(MAC_TX_LENGTHS) &
+		       (TX_LENGTHS_JMB_FRM_LEN_MSK |
+			TX_LENGTHS_CNT_DWN_VAL_MSK);
+
+	tw32(MAC_TX_LENGTHS, val);
 
 	/* Receive rules. */
 	tw32(MAC_RCV_RULE_CFG, RCV_RULE_CFG_DEFAULT_CLASS);
@@ -8186,33 +8282,39 @@
 
 	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705 &&
 	    tp->pci_chip_rev_id != CHIPREV_ID_5705_A0) {
-		if (tp->tg3_flags2 & TG3_FLG2_TSO_CAPABLE &&
+		if (tg3_flag(tp, TSO_CAPABLE) &&
 		    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705) {
 			rdmac_mode |= RDMAC_MODE_FIFO_SIZE_128;
 		} else if (!(tr32(TG3PCI_PCISTATE) & PCISTATE_BUS_SPEED_HIGH) &&
-			   !(tp->tg3_flags2 & TG3_FLG2_IS_5788)) {
+			   !tg3_flag(tp, IS_5788)) {
 			rdmac_mode |= RDMAC_MODE_FIFO_LONG_BURST;
 		}
 	}
 
-	if (tp->tg3_flags2 & TG3_FLG2_PCI_EXPRESS)
+	if (tg3_flag(tp, PCI_EXPRESS))
 		rdmac_mode |= RDMAC_MODE_FIFO_LONG_BURST;
 
-	if (tp->tg3_flags2 & TG3_FLG2_HW_TSO)
+	if (tg3_flag(tp, HW_TSO_1) ||
+	    tg3_flag(tp, HW_TSO_2) ||
+	    tg3_flag(tp, HW_TSO_3))
 		rdmac_mode |= RDMAC_MODE_IPV4_LSO_EN;
 
-	if ((tp->tg3_flags2 & TG3_FLG2_HW_TSO_3) ||
+	if (tg3_flag(tp, 57765_PLUS) ||
 	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5785 ||
 	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780)
 		rdmac_mode |= RDMAC_MODE_IPV6_LSO_EN;
 
+	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5720)
+		rdmac_mode |= tr32(RDMAC_MODE) & RDMAC_MODE_H2BNC_VLAN_DET;
+
 	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761 ||
 	    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 ||
-	    (tp->tg3_flags3 & TG3_FLG3_5717_PLUS)) {
+	    tg3_flag(tp, 57765_PLUS)) {
 		val = tr32(TG3_RDMA_RSRVCTRL_REG);
-		if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719) {
+		if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719 ||
+		    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5720) {
 			val &= ~(TG3_RDMA_RSRVCTRL_TXMRGN_MASK |
 				 TG3_RDMA_RSRVCTRL_FIFO_LWM_MASK |
 				 TG3_RDMA_RSRVCTRL_FIFO_HWM_MASK);
@@ -8224,7 +8326,8 @@
 		     val | TG3_RDMA_RSRVCTRL_FIFO_OFLW_FIX);
 	}
 
-	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719) {
+	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719 ||
+	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5720) {
 		val = tr32(TG3_LSO_RD_DMA_CRPTEN_CTRL);
 		tw32(TG3_LSO_RD_DMA_CRPTEN_CTRL, val |
 		     TG3_LSO_RD_DMA_CRPTEN_CTRL_BLEN_BD_4K |
@@ -8232,12 +8335,12 @@
 	}
 
 	/* Receive/send statistics. */
-	if (tp->tg3_flags2 & TG3_FLG2_5750_PLUS) {
+	if (tg3_flag(tp, 5750_PLUS)) {
 		val = tr32(RCVLPC_STATS_ENABLE);
 		val &= ~RCVLPC_STATSENAB_DACK_FIX;
 		tw32(RCVLPC_STATS_ENABLE, val);
 	} else if ((rdmac_mode & RDMAC_MODE_FIFO_SIZE_128) &&
-		   (tp->tg3_flags2 & TG3_FLG2_TSO_CAPABLE)) {
+		   tg3_flag(tp, TSO_CAPABLE)) {
 		val = tr32(RCVLPC_STATS_ENABLE);
 		val &= ~RCVLPC_STATSENAB_LNGBRST_RFIX;
 		tw32(RCVLPC_STATS_ENABLE, val);
@@ -8260,7 +8363,7 @@
 
 	__tg3_set_coalesce(tp, &tp->coal);
 
-	if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS)) {
+	if (!tg3_flag(tp, 5705_PLUS)) {
 		/* Status/statistics block address.  See tg3_timer,
 		 * the tg3_periodic_fetch_stats call there, and
 		 * tg3_get_stats to see how this works for 5705/5750 chips.
@@ -8286,7 +8389,7 @@
 
 	tw32(RCVCC_MODE, RCVCC_MODE_ENABLE | RCVCC_MODE_ATTN_ENABLE);
 	tw32(RCVLPC_MODE, RCVLPC_MODE_ENABLE);
-	if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS))
+	if (!tg3_flag(tp, 5705_PLUS))
 		tw32(RCVLSC_MODE, RCVLSC_MODE_ENABLE | RCVLSC_MODE_ATTN_ENABLE);
 
 	if (tp->phy_flags & TG3_PHYFLG_MII_SERDES) {
@@ -8296,13 +8399,13 @@
 		udelay(10);
 	}
 
-	if (tp->tg3_flags3 & TG3_FLG3_ENABLE_APE)
+	if (tg3_flag(tp, ENABLE_APE))
 		tp->mac_mode = MAC_MODE_APE_TX_EN | MAC_MODE_APE_RX_EN;
 	else
 		tp->mac_mode = 0;
 	tp->mac_mode |= MAC_MODE_TXSTAT_ENABLE | MAC_MODE_RXSTAT_ENABLE |
 		MAC_MODE_TDE_ENABLE | MAC_MODE_RDE_ENABLE | MAC_MODE_FHDE_ENABLE;
-	if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS) &&
+	if (!tg3_flag(tp, 5705_PLUS) &&
 	    !(tp->phy_flags & TG3_PHYFLG_PHY_SERDES) &&
 	    GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5700)
 		tp->mac_mode |= MAC_MODE_LINK_POLARITY;
@@ -8310,12 +8413,12 @@
 	udelay(40);
 
 	/* tp->grc_local_ctrl is partially set up during tg3_get_invariants().
-	 * If TG3_FLG2_IS_NIC is zero, we should read the
+	 * If TG3_FLAG_IS_NIC is zero, we should read the
 	 * register to preserve the GPIO settings for LOMs. The GPIOs,
 	 * whether used as inputs or outputs, are set by boot code after
 	 * reset.
 	 */
-	if (!(tp->tg3_flags2 & TG3_FLG2_IS_NIC)) {
+	if (!tg3_flag(tp, IS_NIC)) {
 		u32 gpio_mask;
 
 		gpio_mask = GRC_LCLCTRL_GPIO_OE0 | GRC_LCLCTRL_GPIO_OE1 |
@@ -8333,21 +8436,20 @@
 		tp->grc_local_ctrl |= tr32(GRC_LOCAL_CTRL) & gpio_mask;
 
 		/* GPIO1 must be driven high for eeprom write protect */
-		if (tp->tg3_flags & TG3_FLAG_EEPROM_WRITE_PROT)
+		if (tg3_flag(tp, EEPROM_WRITE_PROT))
 			tp->grc_local_ctrl |= (GRC_LCLCTRL_GPIO_OE1 |
 					       GRC_LCLCTRL_GPIO_OUTPUT1);
 	}
 	tw32_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl);
 	udelay(100);
 
-	if ((tp->tg3_flags2 & TG3_FLG2_USING_MSIX) &&
-		tp->irq_cnt > 1) {
+	if (tg3_flag(tp, USING_MSIX) && tp->irq_cnt > 1) {
 		val = tr32(MSGINT_MODE);
 		val |= MSGINT_MODE_MULTIVEC_EN | MSGINT_MODE_ENABLE;
 		tw32(MSGINT_MODE, val);
 	}
 
-	if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS)) {
+	if (!tg3_flag(tp, 5705_PLUS)) {
 		tw32_f(DMAC_MODE, DMAC_MODE_ENABLE);
 		udelay(40);
 	}
@@ -8360,18 +8462,18 @@
 
 	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705 &&
 	    tp->pci_chip_rev_id != CHIPREV_ID_5705_A0) {
-		if ((tp->tg3_flags2 & TG3_FLG2_TSO_CAPABLE) &&
+		if (tg3_flag(tp, TSO_CAPABLE) &&
 		    (tp->pci_chip_rev_id == CHIPREV_ID_5705_A1 ||
 		     tp->pci_chip_rev_id == CHIPREV_ID_5705_A2)) {
 			/* nothing */
 		} else if (!(tr32(TG3PCI_PCISTATE) & PCISTATE_BUS_SPEED_HIGH) &&
-			   !(tp->tg3_flags2 & TG3_FLG2_IS_5788)) {
+			   !tg3_flag(tp, IS_5788)) {
 			val |= WDMAC_MODE_RX_ACCEL;
 		}
 	}
 
 	/* Enable host coalescing bug fix */
-	if (tp->tg3_flags3 & TG3_FLG3_5755_PLUS)
+	if (tg3_flag(tp, 5755_PLUS))
 		val |= WDMAC_MODE_STATUS_TAG_FIX;
 
 	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5785)
@@ -8380,7 +8482,7 @@
 	tw32_f(WDMAC_MODE, val);
 	udelay(40);
 
-	if (tp->tg3_flags & TG3_FLAG_PCIX_MODE) {
+	if (tg3_flag(tp, PCIX_MODE)) {
 		u16 pcix_cmd;
 
 		pci_read_config_word(tp->pdev, tp->pcix_cap + PCI_X_CMD,
@@ -8400,7 +8502,7 @@
 	udelay(40);
 
 	tw32(RCVDCC_MODE, RCVDCC_MODE_ENABLE | RCVDCC_MODE_ATTN_ENABLE);
-	if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS))
+	if (!tg3_flag(tp, 5705_PLUS))
 		tw32(MBFREE_MODE, MBFREE_MODE_ENABLE);
 
 	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761)
@@ -8412,15 +8514,16 @@
 	tw32(SNDBDC_MODE, SNDBDC_MODE_ENABLE | SNDBDC_MODE_ATTN_ENABLE);
 	tw32(RCVBDI_MODE, RCVBDI_MODE_ENABLE | RCVBDI_MODE_RCB_ATTN_ENAB);
 	val = RCVDBDI_MODE_ENABLE | RCVDBDI_MODE_INV_RING_SZ;
-	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 ||
-	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719)
+	if (tg3_flag(tp, LRG_PROD_RING_CAP))
 		val |= RCVDBDI_MODE_LRG_RING_SZ;
 	tw32(RCVDBDI_MODE, val);
 	tw32(SNDDATAI_MODE, SNDDATAI_MODE_ENABLE);
-	if (tp->tg3_flags2 & TG3_FLG2_HW_TSO)
+	if (tg3_flag(tp, HW_TSO_1) ||
+	    tg3_flag(tp, HW_TSO_2) ||
+	    tg3_flag(tp, HW_TSO_3))
 		tw32(SNDDATAI_MODE, SNDDATAI_MODE_ENABLE | 0x8);
 	val = SNDBDI_MODE_ENABLE | SNDBDI_MODE_ATTN_ENABLE;
-	if (tp->tg3_flags3 & TG3_FLG3_ENABLE_TSS)
+	if (tg3_flag(tp, ENABLE_TSS))
 		val |= SNDBDI_MODE_MULTI_TXQ_EN;
 	tw32(SNDBDI_MODE, val);
 	tw32(SNDBDS_MODE, SNDBDS_MODE_ENABLE | SNDBDS_MODE_ATTN_ENABLE);
@@ -8431,20 +8534,28 @@
 			return err;
 	}
 
-	if (tp->tg3_flags2 & TG3_FLG2_TSO_CAPABLE) {
+	if (tg3_flag(tp, TSO_CAPABLE)) {
 		err = tg3_load_tso_firmware(tp);
 		if (err)
 			return err;
 	}
 
 	tp->tx_mode = TX_MODE_ENABLE;
-	if ((tp->tg3_flags3 & TG3_FLG3_5755_PLUS) ||
+
+	if (tg3_flag(tp, 5755_PLUS) ||
 	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906)
 		tp->tx_mode |= TX_MODE_MBUF_LOCKUP_FIX;
+
+	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5720) {
+		val = TX_MODE_JMB_FRM_LEN | TX_MODE_CNT_DN_MODE;
+		tp->tx_mode &= ~val;
+		tp->tx_mode |= tr32(MAC_TX_MODE) & val;
+	}
+
 	tw32_f(MAC_TX_MODE, tp->tx_mode);
 	udelay(100);
 
-	if (tp->tg3_flags3 & TG3_FLG3_ENABLE_RSS) {
+	if (tg3_flag(tp, ENABLE_RSS)) {
 		u32 reg = MAC_RSS_INDIR_TBL_0;
 		u8 *ent = (u8 *)&val;
 
@@ -8473,10 +8584,10 @@
 	}
 
 	tp->rx_mode = RX_MODE_ENABLE;
-	if (tp->tg3_flags3 & TG3_FLG3_5755_PLUS)
+	if (tg3_flag(tp, 5755_PLUS))
 		tp->rx_mode |= RX_MODE_IPV6_CSUM_ENABLE;
 
-	if (tp->tg3_flags3 & TG3_FLG3_ENABLE_RSS)
+	if (tg3_flag(tp, ENABLE_RSS))
 		tp->rx_mode |= RX_MODE_RSS_ENABLE |
 			       RX_MODE_RSS_ITBL_HASH_BITS_7 |
 			       RX_MODE_RSS_IPV6_HASH_EN |
@@ -8523,11 +8634,11 @@
 	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704 &&
 	    (tp->phy_flags & TG3_PHYFLG_PHY_SERDES)) {
 		/* Use hardware link auto-negotiation */
-		tp->tg3_flags2 |= TG3_FLG2_HW_AUTONEG;
+		tg3_flag_set(tp, HW_AUTONEG);
 	}
 
 	if ((tp->phy_flags & TG3_PHYFLG_MII_SERDES) &&
-	    (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5714)) {
+	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5714) {
 		u32 tmp;
 
 		tmp = tr32(SERDES_RX_CTRL);
@@ -8537,7 +8648,7 @@
 		tw32(GRC_LOCAL_CTRL, tp->grc_local_ctrl);
 	}
 
-	if (!(tp->tg3_flags3 & TG3_FLG3_USE_PHYLIB)) {
+	if (!tg3_flag(tp, USE_PHYLIB)) {
 		if (tp->phy_flags & TG3_PHYFLG_IS_LOW_POWER) {
 			tp->phy_flags &= ~TG3_PHYFLG_IS_LOW_POWER;
 			tp->link_config.speed = tp->link_config.orig_speed;
@@ -8570,12 +8681,11 @@
 	tw32(MAC_RCV_RULE_1,  0x86000004 & RCV_RULE_DISABLE_MASK);
 	tw32(MAC_RCV_VALUE_1, 0xffffffff & RCV_RULE_DISABLE_MASK);
 
-	if ((tp->tg3_flags2 & TG3_FLG2_5705_PLUS) &&
-	    !(tp->tg3_flags2 & TG3_FLG2_5780_CLASS))
+	if (tg3_flag(tp, 5705_PLUS) && !tg3_flag(tp, 5780_CLASS))
 		limit = 8;
 	else
 		limit = 16;
-	if (tp->tg3_flags & TG3_FLAG_ENABLE_ASF)
+	if (tg3_flag(tp, ENABLE_ASF))
 		limit -= 4;
 	switch (limit) {
 	case 16:
@@ -8613,7 +8723,7 @@
 		break;
 	}
 
-	if (tp->tg3_flags3 & TG3_FLG3_ENABLE_APE)
+	if (tg3_flag(tp, ENABLE_APE))
 		/* Write our heartbeat update interval to APE. */
 		tg3_ape_write32(tp, TG3_APE_HOST_HEARTBEAT_INT_MS,
 				APE_HOST_HEARTBEAT_INT_DISABLE);
@@ -8679,7 +8789,21 @@
 	TG3_STAT_ADD32(&sp->rx_undersize_packets, MAC_RX_STATS_UNDERSIZE);
 
 	TG3_STAT_ADD32(&sp->rxbds_empty, RCVLPC_NO_RCV_BD_CNT);
-	TG3_STAT_ADD32(&sp->rx_discards, RCVLPC_IN_DISCARDS_CNT);
+	if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5717 &&
+	    tp->pci_chip_rev_id != CHIPREV_ID_5719_A0 &&
+	    tp->pci_chip_rev_id != CHIPREV_ID_5720_A0) {
+		TG3_STAT_ADD32(&sp->rx_discards, RCVLPC_IN_DISCARDS_CNT);
+	} else {
+		u32 val = tr32(HOSTCC_FLOW_ATTN);
+		val = (val & HOSTCC_FLOW_ATTN_MBUF_LWM) ? 1 : 0;
+		if (val) {
+			tw32(HOSTCC_FLOW_ATTN, HOSTCC_FLOW_ATTN_MBUF_LWM);
+			sp->rx_discards.low += val;
+			if (sp->rx_discards.low < val)
+				sp->rx_discards.high += 1;
+		}
+		sp->mbuf_lwm_thresh_hit = sp->rx_discards;
+	}
 	TG3_STAT_ADD32(&sp->rx_errors, RCVLPC_IN_ERRORS_CNT);
 }
 
@@ -8692,7 +8816,7 @@
 
 	spin_lock(&tp->lock);
 
-	if (!(tp->tg3_flags & TG3_FLAG_TAGGED_STATUS)) {
+	if (!tg3_flag(tp, TAGGED_STATUS)) {
 		/* All of this garbage is because when using non-tagged
 		 * IRQ status the mailbox/status_block protocol the chip
 		 * uses with the cpu is race prone.
@@ -8706,7 +8830,7 @@
 		}
 
 		if (!(tr32(WDMAC_MODE) & WDMAC_MODE_ENABLE)) {
-			tp->tg3_flags2 |= TG3_FLG2_RESTART_TIMER;
+			tg3_flag_set(tp, RESTART_TIMER);
 			spin_unlock(&tp->lock);
 			schedule_work(&tp->reset_task);
 			return;
@@ -8715,16 +8839,13 @@
 
 	/* This part only runs once per second. */
 	if (!--tp->timer_counter) {
-		if (tp->tg3_flags2 & TG3_FLG2_5705_PLUS)
+		if (tg3_flag(tp, 5705_PLUS))
 			tg3_periodic_fetch_stats(tp);
 
-		if (tp->setlpicnt && !--tp->setlpicnt) {
-			u32 val = tr32(TG3_CPMU_EEE_MODE);
-			tw32(TG3_CPMU_EEE_MODE,
-			     val | TG3_CPMU_EEEMD_LPI_ENABLE);
-		}
+		if (tp->setlpicnt && !--tp->setlpicnt)
+			tg3_phy_eee_enable(tp);
 
-		if (tp->tg3_flags & TG3_FLAG_USE_LINKCHG_REG) {
+		if (tg3_flag(tp, USE_LINKCHG_REG)) {
 			u32 mac_stat;
 			int phy_event;
 
@@ -8739,7 +8860,7 @@
 
 			if (phy_event)
 				tg3_setup_phy(tp, 0);
-		} else if (tp->tg3_flags & TG3_FLAG_POLL_SERDES) {
+		} else if (tg3_flag(tp, POLL_SERDES)) {
 			u32 mac_stat = tr32(MAC_STATUS);
 			int need_setup = 0;
 
@@ -8764,7 +8885,7 @@
 				tg3_setup_phy(tp, 0);
 			}
 		} else if ((tp->phy_flags & TG3_PHYFLG_MII_SERDES) &&
-			   (tp->tg3_flags2 & TG3_FLG2_5780_CLASS)) {
+			   tg3_flag(tp, 5780_CLASS)) {
 			tg3_serdes_parallel_detect(tp);
 		}
 
@@ -8789,8 +8910,7 @@
 	 * resets.
 	 */
 	if (!--tp->asf_counter) {
-		if ((tp->tg3_flags & TG3_FLAG_ENABLE_ASF) &&
-		    !(tp->tg3_flags3 & TG3_FLG3_ENABLE_APE)) {
+		if (tg3_flag(tp, ENABLE_ASF) && !tg3_flag(tp, ENABLE_APE)) {
 			tg3_wait_for_event_ack(tp);
 
 			tg3_write_mem(tp, NIC_SRAM_FW_CMD_MBOX,
@@ -8826,16 +8946,16 @@
 		name[IFNAMSIZ-1] = 0;
 	}
 
-	if (tp->tg3_flags2 & TG3_FLG2_USING_MSI_OR_MSIX) {
+	if (tg3_flag(tp, USING_MSI) || tg3_flag(tp, USING_MSIX)) {
 		fn = tg3_msi;
-		if (tp->tg3_flags2 & TG3_FLG2_1SHOT_MSI)
+		if (tg3_flag(tp, 1SHOT_MSI))
 			fn = tg3_msi_1shot;
-		flags = IRQF_SAMPLE_RANDOM;
+		flags = 0;
 	} else {
 		fn = tg3_interrupt;
-		if (tp->tg3_flags & TG3_FLAG_TAGGED_STATUS)
+		if (tg3_flag(tp, TAGGED_STATUS))
 			fn = tg3_interrupt_tagged;
-		flags = IRQF_SHARED | IRQF_SAMPLE_RANDOM;
+		flags = IRQF_SHARED;
 	}
 
 	return request_irq(tnapi->irq_vec, fn, flags, name, tnapi);
@@ -8859,8 +8979,7 @@
 	 * Turn off MSI one shot mode.  Otherwise this test has no
 	 * observable way to know whether the interrupt was delivered.
 	 */
-	if ((tp->tg3_flags3 & TG3_FLG3_5717_PLUS) &&
-	    (tp->tg3_flags2 & TG3_FLG2_USING_MSI)) {
+	if (tg3_flag(tp, 57765_PLUS) && tg3_flag(tp, USING_MSI)) {
 		val = tr32(MSGINT_MODE) | MSGINT_MODE_ONE_SHOT_DISABLE;
 		tw32(MSGINT_MODE, val);
 	}
@@ -8902,8 +9021,7 @@
 
 	if (intr_ok) {
 		/* Reenable MSI one shot mode. */
-		if ((tp->tg3_flags3 & TG3_FLG3_5717_PLUS) &&
-		    (tp->tg3_flags2 & TG3_FLG2_USING_MSI)) {
+		if (tg3_flag(tp, 57765_PLUS) && tg3_flag(tp, USING_MSI)) {
 			val = tr32(MSGINT_MODE) & ~MSGINT_MODE_ONE_SHOT_DISABLE;
 			tw32(MSGINT_MODE, val);
 		}
@@ -8921,7 +9039,7 @@
 	int err;
 	u16 pci_cmd;
 
-	if (!(tp->tg3_flags2 & TG3_FLG2_USING_MSI))
+	if (!tg3_flag(tp, USING_MSI))
 		return 0;
 
 	/* Turn off SERR reporting in case MSI terminates with Master
@@ -8951,7 +9069,7 @@
 
 	pci_disable_msi(tp->pdev);
 
-	tp->tg3_flags2 &= ~TG3_FLG2_USING_MSI;
+	tg3_flag_clear(tp, USING_MSI);
 	tp->napi[0].irq_vec = tp->pdev->irq;
 
 	err = tg3_request_irq(tp, 0);
@@ -9048,9 +9166,11 @@
 	}
 
 	if (tp->irq_cnt > 1) {
-		tp->tg3_flags3 |= TG3_FLG3_ENABLE_RSS;
-		if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719) {
-			tp->tg3_flags3 |= TG3_FLG3_ENABLE_TSS;
+		tg3_flag_set(tp, ENABLE_RSS);
+
+		if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719 ||
+		    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5720) {
+			tg3_flag_set(tp, ENABLE_TSS);
 			netif_set_real_num_tx_queues(tp->dev, tp->irq_cnt - 1);
 		}
 	}
@@ -9060,8 +9180,8 @@
 
 static void tg3_ints_init(struct tg3 *tp)
 {
-	if ((tp->tg3_flags & TG3_FLAG_SUPPORT_MSI_OR_MSIX) &&
-	    !(tp->tg3_flags & TG3_FLAG_TAGGED_STATUS)) {
+	if ((tg3_flag(tp, SUPPORT_MSI) || tg3_flag(tp, SUPPORT_MSIX)) &&
+	    !tg3_flag(tp, TAGGED_STATUS)) {
 		/* All MSI supporting chips should support tagged
 		 * status.  Assert that this is the case.
 		 */
@@ -9070,21 +9190,19 @@
 		goto defcfg;
 	}
 
-	if ((tp->tg3_flags & TG3_FLAG_SUPPORT_MSIX) && tg3_enable_msix(tp))
-		tp->tg3_flags2 |= TG3_FLG2_USING_MSIX;
-	else if ((tp->tg3_flags & TG3_FLAG_SUPPORT_MSI) &&
-		 pci_enable_msi(tp->pdev) == 0)
-		tp->tg3_flags2 |= TG3_FLG2_USING_MSI;
+	if (tg3_flag(tp, SUPPORT_MSIX) && tg3_enable_msix(tp))
+		tg3_flag_set(tp, USING_MSIX);
+	else if (tg3_flag(tp, SUPPORT_MSI) && pci_enable_msi(tp->pdev) == 0)
+		tg3_flag_set(tp, USING_MSI);
 
-	if (tp->tg3_flags2 & TG3_FLG2_USING_MSI_OR_MSIX) {
+	if (tg3_flag(tp, USING_MSI) || tg3_flag(tp, USING_MSIX)) {
 		u32 msi_mode = tr32(MSGINT_MODE);
-		if ((tp->tg3_flags2 & TG3_FLG2_USING_MSIX) &&
-		    tp->irq_cnt > 1)
+		if (tg3_flag(tp, USING_MSIX) && tp->irq_cnt > 1)
 			msi_mode |= MSGINT_MODE_MULTIVEC_EN;
 		tw32(MSGINT_MODE, msi_mode | MSGINT_MODE_ENABLE);
 	}
 defcfg:
-	if (!(tp->tg3_flags2 & TG3_FLG2_USING_MSIX)) {
+	if (!tg3_flag(tp, USING_MSIX)) {
 		tp->irq_cnt = 1;
 		tp->napi[0].irq_vec = tp->pdev->irq;
 		netif_set_real_num_tx_queues(tp->dev, 1);
@@ -9094,12 +9212,14 @@
 
 static void tg3_ints_fini(struct tg3 *tp)
 {
-	if (tp->tg3_flags2 & TG3_FLG2_USING_MSIX)
+	if (tg3_flag(tp, USING_MSIX))
 		pci_disable_msix(tp->pdev);
-	else if (tp->tg3_flags2 & TG3_FLG2_USING_MSI)
+	else if (tg3_flag(tp, USING_MSI))
 		pci_disable_msi(tp->pdev);
-	tp->tg3_flags2 &= ~TG3_FLG2_USING_MSI_OR_MSIX;
-	tp->tg3_flags3 &= ~(TG3_FLG3_ENABLE_RSS | TG3_FLG3_ENABLE_TSS);
+	tg3_flag_clear(tp, USING_MSI);
+	tg3_flag_clear(tp, USING_MSIX);
+	tg3_flag_clear(tp, ENABLE_RSS);
+	tg3_flag_clear(tp, ENABLE_TSS);
 }
 
 static int tg3_open(struct net_device *dev)
@@ -9114,10 +9234,10 @@
 				return err;
 		} else if (err) {
 			netdev_warn(tp->dev, "TSO capability disabled\n");
-			tp->tg3_flags2 &= ~TG3_FLG2_TSO_CAPABLE;
-		} else if (!(tp->tg3_flags2 & TG3_FLG2_TSO_CAPABLE)) {
+			tg3_flag_clear(tp, TSO_CAPABLE);
+		} else if (!tg3_flag(tp, TSO_CAPABLE)) {
 			netdev_notice(tp->dev, "TSO capability restored\n");
-			tp->tg3_flags2 |= TG3_FLG2_TSO_CAPABLE;
+			tg3_flag_set(tp, TSO_CAPABLE);
 		}
 	}
 
@@ -9130,7 +9250,7 @@
 	tg3_full_lock(tp, 0);
 
 	tg3_disable_ints(tp);
-	tp->tg3_flags &= ~TG3_FLAG_INIT_COMPLETE;
+	tg3_flag_clear(tp, INIT_COMPLETE);
 
 	tg3_full_unlock(tp);
 
@@ -9171,7 +9291,7 @@
 		tg3_halt(tp, RESET_KIND_SHUTDOWN, 1);
 		tg3_free_rings(tp);
 	} else {
-		if (tp->tg3_flags & TG3_FLAG_TAGGED_STATUS)
+		if (tg3_flag(tp, TAGGED_STATUS))
 			tp->timer_offset = HZ;
 		else
 			tp->timer_offset = HZ / 10;
@@ -9193,7 +9313,7 @@
 	if (err)
 		goto err_out3;
 
-	if (tp->tg3_flags2 & TG3_FLG2_USING_MSI) {
+	if (tg3_flag(tp, USING_MSI)) {
 		err = tg3_test_msi(tp);
 
 		if (err) {
@@ -9205,8 +9325,7 @@
 			goto err_out2;
 		}
 
-		if (!(tp->tg3_flags3 & TG3_FLG3_5717_PLUS) &&
-		    (tp->tg3_flags2 & TG3_FLG2_USING_MSI)) {
+		if (!tg3_flag(tp, 57765_PLUS) && tg3_flag(tp, USING_MSI)) {
 			u32 val = tr32(PCIE_TRANSACTION_CFG);
 
 			tw32(PCIE_TRANSACTION_CFG,
@@ -9219,13 +9338,20 @@
 	tg3_full_lock(tp, 0);
 
 	add_timer(&tp->timer);
-	tp->tg3_flags |= TG3_FLAG_INIT_COMPLETE;
+	tg3_flag_set(tp, INIT_COMPLETE);
 	tg3_enable_ints(tp);
 
 	tg3_full_unlock(tp);
 
 	netif_tx_start_all_queues(dev);
 
+	/*
+	 * Reset loopback feature if it was turned on while the device was down
+	 * make sure that it's installed properly now.
+	 */
+	if (dev->features & NETIF_F_LOOPBACK)
+		tg3_set_loopback(dev, dev->features);
+
 	return 0;
 
 err_out3:
@@ -9268,7 +9394,7 @@
 
 	tg3_halt(tp, RESET_KIND_SHUTDOWN, 1);
 	tg3_free_rings(tp);
-	tp->tg3_flags &= ~TG3_FLAG_INIT_COMPLETE;
+	tg3_flag_clear(tp, INIT_COMPLETE);
 
 	tg3_full_unlock(tp);
 
@@ -9415,6 +9541,8 @@
 	ESTAT_ADD(nic_avoided_irqs);
 	ESTAT_ADD(nic_tx_threshold_hit);
 
+	ESTAT_ADD(mbuf_lwm_thresh_hit);
+
 	return estats;
 }
 
@@ -9525,7 +9653,7 @@
 	/* When ASF is in use, we always keep the RX_MODE_KEEP_VLAN_TAG
 	 * flag clear.
 	 */
-	if (!(tp->tg3_flags & TG3_FLAG_ENABLE_ASF))
+	if (!tg3_flag(tp, ENABLE_ASF))
 		rx_mode |= RX_MODE_KEEP_VLAN_TAG;
 #endif
 
@@ -9579,82 +9707,26 @@
 	tg3_full_unlock(tp);
 }
 
-#define TG3_REGDUMP_LEN		(32 * 1024)
-
 static int tg3_get_regs_len(struct net_device *dev)
 {
-	return TG3_REGDUMP_LEN;
+	return TG3_REG_BLK_SIZE;
 }
 
 static void tg3_get_regs(struct net_device *dev,
 		struct ethtool_regs *regs, void *_p)
 {
-	u32 *p = _p;
 	struct tg3 *tp = netdev_priv(dev);
-	u8 *orig_p = _p;
-	int i;
 
 	regs->version = 0;
 
-	memset(p, 0, TG3_REGDUMP_LEN);
+	memset(_p, 0, TG3_REG_BLK_SIZE);
 
 	if (tp->phy_flags & TG3_PHYFLG_IS_LOW_POWER)
 		return;
 
 	tg3_full_lock(tp, 0);
 
-#define __GET_REG32(reg)	(*(p)++ = tr32(reg))
-#define GET_REG32_LOOP(base, len)		\
-do {	p = (u32 *)(orig_p + (base));		\
-	for (i = 0; i < len; i += 4)		\
-		__GET_REG32((base) + i);	\
-} while (0)
-#define GET_REG32_1(reg)			\
-do {	p = (u32 *)(orig_p + (reg));		\
-	__GET_REG32((reg));			\
-} while (0)
-
-	GET_REG32_LOOP(TG3PCI_VENDOR, 0xb0);
-	GET_REG32_LOOP(MAILBOX_INTERRUPT_0, 0x200);
-	GET_REG32_LOOP(MAC_MODE, 0x4f0);
-	GET_REG32_LOOP(SNDDATAI_MODE, 0xe0);
-	GET_REG32_1(SNDDATAC_MODE);
-	GET_REG32_LOOP(SNDBDS_MODE, 0x80);
-	GET_REG32_LOOP(SNDBDI_MODE, 0x48);
-	GET_REG32_1(SNDBDC_MODE);
-	GET_REG32_LOOP(RCVLPC_MODE, 0x20);
-	GET_REG32_LOOP(RCVLPC_SELLST_BASE, 0x15c);
-	GET_REG32_LOOP(RCVDBDI_MODE, 0x0c);
-	GET_REG32_LOOP(RCVDBDI_JUMBO_BD, 0x3c);
-	GET_REG32_LOOP(RCVDBDI_BD_PROD_IDX_0, 0x44);
-	GET_REG32_1(RCVDCC_MODE);
-	GET_REG32_LOOP(RCVBDI_MODE, 0x20);
-	GET_REG32_LOOP(RCVCC_MODE, 0x14);
-	GET_REG32_LOOP(RCVLSC_MODE, 0x08);
-	GET_REG32_1(MBFREE_MODE);
-	GET_REG32_LOOP(HOSTCC_MODE, 0x100);
-	GET_REG32_LOOP(MEMARB_MODE, 0x10);
-	GET_REG32_LOOP(BUFMGR_MODE, 0x58);
-	GET_REG32_LOOP(RDMAC_MODE, 0x08);
-	GET_REG32_LOOP(WDMAC_MODE, 0x08);
-	GET_REG32_1(RX_CPU_MODE);
-	GET_REG32_1(RX_CPU_STATE);
-	GET_REG32_1(RX_CPU_PGMCTR);
-	GET_REG32_1(RX_CPU_HWBKPT);
-	GET_REG32_1(TX_CPU_MODE);
-	GET_REG32_1(TX_CPU_STATE);
-	GET_REG32_1(TX_CPU_PGMCTR);
-	GET_REG32_LOOP(GRCMBOX_INTERRUPT_0, 0x110);
-	GET_REG32_LOOP(FTQ_RESET, 0x120);
-	GET_REG32_LOOP(MSGINT_MODE, 0x0c);
-	GET_REG32_1(DMAC_MODE);
-	GET_REG32_LOOP(GRC_MODE, 0x4c);
-	if (tp->tg3_flags & TG3_FLAG_NVRAM)
-		GET_REG32_LOOP(NVRAM_CMD, 0x24);
-
-#undef __GET_REG32
-#undef GET_REG32_LOOP
-#undef GET_REG32_1
+	tg3_dump_legacy_regs(tp, (u32 *)_p);
 
 	tg3_full_unlock(tp);
 }
@@ -9674,7 +9746,7 @@
 	u32 i, offset, len, b_offset, b_count;
 	__be32 val;
 
-	if (tp->tg3_flags3 & TG3_FLG3_NO_NVRAM)
+	if (tg3_flag(tp, NO_NVRAM))
 		return -EINVAL;
 
 	if (tp->phy_flags & TG3_PHYFLG_IS_LOW_POWER)
@@ -9742,7 +9814,7 @@
 	if (tp->phy_flags & TG3_PHYFLG_IS_LOW_POWER)
 		return -EAGAIN;
 
-	if ((tp->tg3_flags3 & TG3_FLG3_NO_NVRAM) ||
+	if (tg3_flag(tp, NO_NVRAM) ||
 	    eeprom->magic != TG3_EEPROM_MAGIC)
 		return -EINVAL;
 
@@ -9794,7 +9866,7 @@
 {
 	struct tg3 *tp = netdev_priv(dev);
 
-	if (tp->tg3_flags3 & TG3_FLG3_USE_PHYLIB) {
+	if (tg3_flag(tp, USE_PHYLIB)) {
 		struct phy_device *phydev;
 		if (!(tp->phy_flags & TG3_PHYFLG_IS_CONNECTED))
 			return -EAGAIN;
@@ -9822,10 +9894,10 @@
 
 	cmd->advertising = tp->link_config.advertising;
 	if (netif_running(dev)) {
-		cmd->speed = tp->link_config.active_speed;
+		ethtool_cmd_speed_set(cmd, tp->link_config.active_speed);
 		cmd->duplex = tp->link_config.active_duplex;
 	} else {
-		cmd->speed = SPEED_INVALID;
+		ethtool_cmd_speed_set(cmd, SPEED_INVALID);
 		cmd->duplex = DUPLEX_INVALID;
 	}
 	cmd->phy_address = tp->phy_addr;
@@ -9839,8 +9911,9 @@
 static int tg3_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
 {
 	struct tg3 *tp = netdev_priv(dev);
+	u32 speed = ethtool_cmd_speed(cmd);
 
-	if (tp->tg3_flags3 & TG3_FLG3_USE_PHYLIB) {
+	if (tg3_flag(tp, USE_PHYLIB)) {
 		struct phy_device *phydev;
 		if (!(tp->phy_flags & TG3_PHYFLG_IS_CONNECTED))
 			return -EAGAIN;
@@ -9888,14 +9961,14 @@
 		cmd->advertising &= mask;
 	} else {
 		if (tp->phy_flags & TG3_PHYFLG_ANY_SERDES) {
-			if (cmd->speed != SPEED_1000)
+			if (speed != SPEED_1000)
 				return -EINVAL;
 
 			if (cmd->duplex != DUPLEX_FULL)
 				return -EINVAL;
 		} else {
-			if (cmd->speed != SPEED_100 &&
-			    cmd->speed != SPEED_10)
+			if (speed != SPEED_100 &&
+			    speed != SPEED_10)
 				return -EINVAL;
 		}
 	}
@@ -9910,7 +9983,7 @@
 		tp->link_config.duplex = DUPLEX_INVALID;
 	} else {
 		tp->link_config.advertising = 0;
-		tp->link_config.speed = cmd->speed;
+		tp->link_config.speed = speed;
 		tp->link_config.duplex = cmd->duplex;
 	}
 
@@ -9940,14 +10013,12 @@
 {
 	struct tg3 *tp = netdev_priv(dev);
 
-	if ((tp->tg3_flags & TG3_FLAG_WOL_CAP) &&
-	    device_can_wakeup(&tp->pdev->dev))
+	if (tg3_flag(tp, WOL_CAP) && device_can_wakeup(&tp->pdev->dev))
 		wol->supported = WAKE_MAGIC;
 	else
 		wol->supported = 0;
 	wol->wolopts = 0;
-	if ((tp->tg3_flags & TG3_FLAG_WOL_ENABLE) &&
-	    device_can_wakeup(&tp->pdev->dev))
+	if (tg3_flag(tp, WOL_ENABLE) && device_can_wakeup(&tp->pdev->dev))
 		wol->wolopts = WAKE_MAGIC;
 	memset(&wol->sopass, 0, sizeof(wol->sopass));
 }
@@ -9960,19 +10031,18 @@
 	if (wol->wolopts & ~WAKE_MAGIC)
 		return -EINVAL;
 	if ((wol->wolopts & WAKE_MAGIC) &&
-	    !((tp->tg3_flags & TG3_FLAG_WOL_CAP) && device_can_wakeup(dp)))
+	    !(tg3_flag(tp, WOL_CAP) && device_can_wakeup(dp)))
 		return -EINVAL;
 
 	device_set_wakeup_enable(dp, wol->wolopts & WAKE_MAGIC);
 
 	spin_lock_bh(&tp->lock);
 	if (device_may_wakeup(dp))
-		tp->tg3_flags |= TG3_FLAG_WOL_ENABLE;
+		tg3_flag_set(tp, WOL_ENABLE);
 	else
-		tp->tg3_flags &= ~TG3_FLAG_WOL_ENABLE;
+		tg3_flag_clear(tp, WOL_ENABLE);
 	spin_unlock_bh(&tp->lock);
 
-
 	return 0;
 }
 
@@ -9988,33 +10058,6 @@
 	tp->msg_enable = value;
 }
 
-static int tg3_set_tso(struct net_device *dev, u32 value)
-{
-	struct tg3 *tp = netdev_priv(dev);
-
-	if (!(tp->tg3_flags2 & TG3_FLG2_TSO_CAPABLE)) {
-		if (value)
-			return -EINVAL;
-		return 0;
-	}
-	if ((dev->features & NETIF_F_IPV6_CSUM) &&
-	    ((tp->tg3_flags2 & TG3_FLG2_HW_TSO_2) ||
-	     (tp->tg3_flags2 & TG3_FLG2_HW_TSO_3))) {
-		if (value) {
-			dev->features |= NETIF_F_TSO6;
-			if ((tp->tg3_flags2 & TG3_FLG2_HW_TSO_3) ||
-			    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761 ||
-			    (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5784 &&
-			     GET_CHIP_REV(tp->pci_chip_rev_id) != CHIPREV_5784_AX) ||
-			    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5785 ||
-			    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780)
-				dev->features |= NETIF_F_TSO_ECN;
-		} else
-			dev->features &= ~(NETIF_F_TSO6 | NETIF_F_TSO_ECN);
-	}
-	return ethtool_op_set_tso(dev, value);
-}
-
 static int tg3_nway_reset(struct net_device *dev)
 {
 	struct tg3 *tp = netdev_priv(dev);
@@ -10026,7 +10069,7 @@
 	if (tp->phy_flags & TG3_PHYFLG_PHY_SERDES)
 		return -EINVAL;
 
-	if (tp->tg3_flags3 & TG3_FLG3_USE_PHYLIB) {
+	if (tg3_flag(tp, USE_PHYLIB)) {
 		if (!(tp->phy_flags & TG3_PHYFLG_IS_CONNECTED))
 			return -EAGAIN;
 		r = phy_start_aneg(tp->mdio_bus->phy_map[TG3_PHY_MII_ADDR]);
@@ -10055,7 +10098,7 @@
 
 	ering->rx_max_pending = tp->rx_std_ring_mask;
 	ering->rx_mini_max_pending = 0;
-	if (tp->tg3_flags & TG3_FLAG_JUMBO_RING_ENABLE)
+	if (tg3_flag(tp, JUMBO_RING_ENABLE))
 		ering->rx_jumbo_max_pending = tp->rx_jmb_ring_mask;
 	else
 		ering->rx_jumbo_max_pending = 0;
@@ -10064,7 +10107,7 @@
 
 	ering->rx_pending = tp->rx_pending;
 	ering->rx_mini_pending = 0;
-	if (tp->tg3_flags & TG3_FLAG_JUMBO_RING_ENABLE)
+	if (tg3_flag(tp, JUMBO_RING_ENABLE))
 		ering->rx_jumbo_pending = tp->rx_jumbo_pending;
 	else
 		ering->rx_jumbo_pending = 0;
@@ -10081,7 +10124,7 @@
 	    (ering->rx_jumbo_pending > tp->rx_jmb_ring_mask) ||
 	    (ering->tx_pending > TG3_TX_RING_SIZE - 1) ||
 	    (ering->tx_pending <= MAX_SKB_FRAGS) ||
-	    ((tp->tg3_flags2 & TG3_FLG2_TSO_BUG) &&
+	    (tg3_flag(tp, TSO_BUG) &&
 	     (ering->tx_pending <= (MAX_SKB_FRAGS * 3))))
 		return -EINVAL;
 
@@ -10095,7 +10138,7 @@
 
 	tp->rx_pending = ering->rx_pending;
 
-	if ((tp->tg3_flags2 & TG3_FLG2_MAX_RXPEND_64) &&
+	if (tg3_flag(tp, MAX_RXPEND_64) &&
 	    tp->rx_pending > 63)
 		tp->rx_pending = 63;
 	tp->rx_jumbo_pending = ering->rx_jumbo_pending;
@@ -10122,7 +10165,7 @@
 {
 	struct tg3 *tp = netdev_priv(dev);
 
-	epause->autoneg = (tp->tg3_flags & TG3_FLAG_PAUSE_AUTONEG) != 0;
+	epause->autoneg = !!tg3_flag(tp, PAUSE_AUTONEG);
 
 	if (tp->link_config.active_flowctrl & FLOW_CTRL_RX)
 		epause->rx_pause = 1;
@@ -10140,7 +10183,7 @@
 	struct tg3 *tp = netdev_priv(dev);
 	int err = 0;
 
-	if (tp->tg3_flags3 & TG3_FLG3_USE_PHYLIB) {
+	if (tg3_flag(tp, USE_PHYLIB)) {
 		u32 newadv;
 		struct phy_device *phydev;
 
@@ -10168,9 +10211,9 @@
 			newadv = 0;
 
 		if (epause->autoneg)
-			tp->tg3_flags |= TG3_FLAG_PAUSE_AUTONEG;
+			tg3_flag_set(tp, PAUSE_AUTONEG);
 		else
-			tp->tg3_flags &= ~TG3_FLAG_PAUSE_AUTONEG;
+			tg3_flag_clear(tp, PAUSE_AUTONEG);
 
 		if (tp->phy_flags & TG3_PHYFLG_IS_CONNECTED) {
 			u32 oldadv = phydev->advertising &
@@ -10212,9 +10255,9 @@
 		tg3_full_lock(tp, irq_sync);
 
 		if (epause->autoneg)
-			tp->tg3_flags |= TG3_FLAG_PAUSE_AUTONEG;
+			tg3_flag_set(tp, PAUSE_AUTONEG);
 		else
-			tp->tg3_flags &= ~TG3_FLAG_PAUSE_AUTONEG;
+			tg3_flag_clear(tp, PAUSE_AUTONEG);
 		if (epause->rx_pause)
 			tp->link_config.flowctrl |= FLOW_CTRL_RX;
 		else
@@ -10237,50 +10280,6 @@
 	return err;
 }
 
-static u32 tg3_get_rx_csum(struct net_device *dev)
-{
-	struct tg3 *tp = netdev_priv(dev);
-	return (tp->tg3_flags & TG3_FLAG_RX_CHECKSUMS) != 0;
-}
-
-static int tg3_set_rx_csum(struct net_device *dev, u32 data)
-{
-	struct tg3 *tp = netdev_priv(dev);
-
-	if (tp->tg3_flags & TG3_FLAG_BROKEN_CHECKSUMS) {
-		if (data != 0)
-			return -EINVAL;
-		return 0;
-	}
-
-	spin_lock_bh(&tp->lock);
-	if (data)
-		tp->tg3_flags |= TG3_FLAG_RX_CHECKSUMS;
-	else
-		tp->tg3_flags &= ~TG3_FLAG_RX_CHECKSUMS;
-	spin_unlock_bh(&tp->lock);
-
-	return 0;
-}
-
-static int tg3_set_tx_csum(struct net_device *dev, u32 data)
-{
-	struct tg3 *tp = netdev_priv(dev);
-
-	if (tp->tg3_flags & TG3_FLAG_BROKEN_CHECKSUMS) {
-		if (data != 0)
-			return -EINVAL;
-		return 0;
-	}
-
-	if (tp->tg3_flags3 & TG3_FLG3_5755_PLUS)
-		ethtool_op_set_tx_ipv6_csum(dev, data);
-	else
-		ethtool_op_set_tx_csum(dev, data);
-
-	return 0;
-}
-
 static int tg3_get_sset_count(struct net_device *dev, int sset)
 {
 	switch (sset) {
@@ -10308,35 +10307,38 @@
 	}
 }
 
-static int tg3_phys_id(struct net_device *dev, u32 data)
+static int tg3_set_phys_id(struct net_device *dev,
+			    enum ethtool_phys_id_state state)
 {
 	struct tg3 *tp = netdev_priv(dev);
-	int i;
 
 	if (!netif_running(tp->dev))
 		return -EAGAIN;
 
-	if (data == 0)
-		data = UINT_MAX / 2;
+	switch (state) {
+	case ETHTOOL_ID_ACTIVE:
+		return 1;	/* cycle on/off once per second */
 
-	for (i = 0; i < (data * 2); i++) {
-		if ((i % 2) == 0)
-			tw32(MAC_LED_CTRL, LED_CTRL_LNKLED_OVERRIDE |
-					   LED_CTRL_1000MBPS_ON |
-					   LED_CTRL_100MBPS_ON |
-					   LED_CTRL_10MBPS_ON |
-					   LED_CTRL_TRAFFIC_OVERRIDE |
-					   LED_CTRL_TRAFFIC_BLINK |
-					   LED_CTRL_TRAFFIC_LED);
+	case ETHTOOL_ID_ON:
+		tw32(MAC_LED_CTRL, LED_CTRL_LNKLED_OVERRIDE |
+		     LED_CTRL_1000MBPS_ON |
+		     LED_CTRL_100MBPS_ON |
+		     LED_CTRL_10MBPS_ON |
+		     LED_CTRL_TRAFFIC_OVERRIDE |
+		     LED_CTRL_TRAFFIC_BLINK |
+		     LED_CTRL_TRAFFIC_LED);
+		break;
 
-		else
-			tw32(MAC_LED_CTRL, LED_CTRL_LNKLED_OVERRIDE |
-					   LED_CTRL_TRAFFIC_OVERRIDE);
+	case ETHTOOL_ID_OFF:
+		tw32(MAC_LED_CTRL, LED_CTRL_LNKLED_OVERRIDE |
+		     LED_CTRL_TRAFFIC_OVERRIDE);
+		break;
 
-		if (msleep_interruptible(500))
-			break;
+	case ETHTOOL_ID_INACTIVE:
+		tw32(MAC_LED_CTRL, tp->led_ctrl);
+		break;
 	}
-	tw32(MAC_LED_CTRL, tp->led_ctrl);
+
 	return 0;
 }
 
@@ -10347,6 +10349,80 @@
 	memcpy(tmp_stats, tg3_get_estats(tp), sizeof(tp->estats));
 }
 
+static __be32 * tg3_vpd_readblock(struct tg3 *tp)
+{
+	int i;
+	__be32 *buf;
+	u32 offset = 0, len = 0;
+	u32 magic, val;
+
+	if (tg3_flag(tp, NO_NVRAM) || tg3_nvram_read(tp, 0, &magic))
+		return NULL;
+
+	if (magic == TG3_EEPROM_MAGIC) {
+		for (offset = TG3_NVM_DIR_START;
+		     offset < TG3_NVM_DIR_END;
+		     offset += TG3_NVM_DIRENT_SIZE) {
+			if (tg3_nvram_read(tp, offset, &val))
+				return NULL;
+
+			if ((val >> TG3_NVM_DIRTYPE_SHIFT) ==
+			    TG3_NVM_DIRTYPE_EXTVPD)
+				break;
+		}
+
+		if (offset != TG3_NVM_DIR_END) {
+			len = (val & TG3_NVM_DIRTYPE_LENMSK) * 4;
+			if (tg3_nvram_read(tp, offset + 4, &offset))
+				return NULL;
+
+			offset = tg3_nvram_logical_addr(tp, offset);
+		}
+	}
+
+	if (!offset || !len) {
+		offset = TG3_NVM_VPD_OFF;
+		len = TG3_NVM_VPD_LEN;
+	}
+
+	buf = kmalloc(len, GFP_KERNEL);
+	if (buf == NULL)
+		return NULL;
+
+	if (magic == TG3_EEPROM_MAGIC) {
+		for (i = 0; i < len; i += 4) {
+			/* The data is in little-endian format in NVRAM.
+			 * Use the big-endian read routines to preserve
+			 * the byte order as it exists in NVRAM.
+			 */
+			if (tg3_nvram_read_be32(tp, offset + i, &buf[i/4]))
+				goto error;
+		}
+	} else {
+		u8 *ptr;
+		ssize_t cnt;
+		unsigned int pos = 0;
+
+		ptr = (u8 *)&buf[0];
+		for (i = 0; pos < len && i < 3; i++, pos += cnt, ptr += cnt) {
+			cnt = pci_read_vpd(tp->pdev, pos,
+					   len - pos, ptr);
+			if (cnt == -ETIMEDOUT || cnt == -EINTR)
+				cnt = 0;
+			else if (cnt < 0)
+				goto error;
+		}
+		if (pos != len)
+			goto error;
+	}
+
+	return buf;
+
+error:
+	kfree(buf);
+	return NULL;
+}
+
 #define NVRAM_TEST_SIZE 0x100
 #define NVRAM_SELFBOOT_FORMAT1_0_SIZE	0x14
 #define NVRAM_SELFBOOT_FORMAT1_2_SIZE	0x18
@@ -10360,7 +10436,7 @@
 	__be32 *buf;
 	int i, j, k, err = 0, size;
 
-	if (tp->tg3_flags3 & TG3_FLG3_NO_NVRAM)
+	if (tg3_flag(tp, NO_NVRAM))
 		return 0;
 
 	if (tg3_nvram_read(tp, 0, &magic) != 0)
@@ -10486,14 +10562,11 @@
 	if (csum != le32_to_cpu(buf[0xfc/4]))
 		goto out;
 
-	for (i = 0; i < TG3_NVM_VPD_LEN; i += 4) {
-		/* The data is in little-endian format in NVRAM.
-		 * Use the big-endian read routines to preserve
-		 * the byte order as it exists in NVRAM.
-		 */
-		if (tg3_nvram_read_be32(tp, TG3_NVM_VPD_OFF + i, &buf[i/4]))
-			goto out;
-	}
+	kfree(buf);
+
+	buf = tg3_vpd_readblock(tp);
+	if (!buf)
+		return -ENOMEM;
 
 	i = pci_vpd_find_tag((u8 *)buf, 0, TG3_NVM_VPD_LEN,
 			     PCI_VPD_LRDT_RO_DATA);
@@ -10705,9 +10778,9 @@
 	};
 
 	is_5705 = is_5750 = 0;
-	if (tp->tg3_flags2 & TG3_FLG2_5705_PLUS) {
+	if (tg3_flag(tp, 5705_PLUS)) {
 		is_5705 = 1;
-		if (tp->tg3_flags2 & TG3_FLG2_5750_PLUS)
+		if (tg3_flag(tp, 5750_PLUS))
 			is_5750 = 1;
 	}
 
@@ -10718,7 +10791,7 @@
 		if (!is_5705 && (reg_tbl[i].flags & TG3_FL_5705))
 			continue;
 
-		if ((tp->tg3_flags2 & TG3_FLG2_IS_5788) &&
+		if (tg3_flag(tp, IS_5788) &&
 		    (reg_tbl[i].flags & TG3_FL_NOT_5788))
 			continue;
 
@@ -10841,16 +10914,15 @@
 	int err = 0;
 	int i;
 
-	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 ||
-	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719)
+	if (tg3_flag(tp, 5717_PLUS))
 		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)
+	else if (tg3_flag(tp, 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;
-	else if (tp->tg3_flags2 & TG3_FLG2_5705_PLUS)
+	else if (tg3_flag(tp, 5705_PLUS))
 		mem_tbl = mem_tbl_5705;
 	else
 		mem_tbl = mem_tbl_570x;
@@ -10866,11 +10938,35 @@
 
 #define TG3_MAC_LOOPBACK	0
 #define TG3_PHY_LOOPBACK	1
+#define TG3_TSO_LOOPBACK	2
 
-static int tg3_run_loopback(struct tg3 *tp, int loopback_mode)
+#define TG3_TSO_MSS		500
+
+#define TG3_TSO_IP_HDR_LEN	20
+#define TG3_TSO_TCP_HDR_LEN	20
+#define TG3_TSO_TCP_OPT_LEN	12
+
+static const u8 tg3_tso_header[] = {
+0x08, 0x00,
+0x45, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x40, 0x00,
+0x40, 0x06, 0x00, 0x00,
+0x0a, 0x00, 0x00, 0x01,
+0x0a, 0x00, 0x00, 0x02,
+0x0d, 0x00, 0xe0, 0x00,
+0x00, 0x00, 0x01, 0x00,
+0x00, 0x00, 0x02, 0x00,
+0x80, 0x10, 0x10, 0x00,
+0x14, 0x09, 0x00, 0x00,
+0x01, 0x01, 0x08, 0x0a,
+0x11, 0x11, 0x11, 0x11,
+0x11, 0x11, 0x11, 0x11,
+};
+
+static int tg3_run_loopback(struct tg3 *tp, u32 pktsz, int loopback_mode)
 {
 	u32 mac_mode, rx_start_idx, rx_idx, tx_idx, opaque_key;
-	u32 desc_idx, coal_now;
+	u32 base_flags = 0, mss = 0, desc_idx, coal_now, data_off, val;
 	struct sk_buff *skb, *rx_skb;
 	u8 *tx_data;
 	dma_addr_t map;
@@ -10882,9 +10978,9 @@
 	tnapi = &tp->napi[0];
 	rnapi = &tp->napi[0];
 	if (tp->irq_cnt > 1) {
-		if (tp->tg3_flags3 & TG3_FLG3_ENABLE_RSS)
+		if (tg3_flag(tp, ENABLE_RSS))
 			rnapi = &tp->napi[1];
-		if (tp->tg3_flags3 & TG3_FLG3_ENABLE_TSS)
+		if (tg3_flag(tp, ENABLE_TSS))
 			tnapi = &tp->napi[1];
 	}
 	coal_now = tnapi->coal_now | rnapi->coal_now;
@@ -10896,22 +10992,20 @@
 		 * all newer ASIC revisions.
 		 */
 		if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5780 ||
-		    (tp->tg3_flags & TG3_FLAG_CPMU_PRESENT))
+		    tg3_flag(tp, CPMU_PRESENT))
 			return 0;
 
 		mac_mode = tp->mac_mode &
 			   ~(MAC_MODE_PORT_MODE_MASK | MAC_MODE_HALF_DUPLEX);
 		mac_mode |= MAC_MODE_PORT_INT_LPBACK;
-		if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS))
+		if (!tg3_flag(tp, 5705_PLUS))
 			mac_mode |= MAC_MODE_LINK_POLARITY;
 		if (tp->phy_flags & TG3_PHYFLG_10_100_ONLY)
 			mac_mode |= MAC_MODE_PORT_MODE_MII;
 		else
 			mac_mode |= MAC_MODE_PORT_MODE_GMII;
 		tw32(MAC_MODE, mac_mode);
-	} else if (loopback_mode == TG3_PHY_LOOPBACK) {
-		u32 val;
-
+	} else {
 		if (tp->phy_flags & TG3_PHYFLG_IS_FET) {
 			tg3_phy_fet_toggle_apd(tp, false);
 			val = BMCR_LOOPBACK | BMCR_FULLDPLX | BMCR_SPEED100;
@@ -10959,13 +11053,11 @@
 				break;
 			mdelay(1);
 		}
-	} else {
-		return -EINVAL;
 	}
 
 	err = -EIO;
 
-	tx_len = 1514;
+	tx_len = pktsz;
 	skb = netdev_alloc_skb(tp->dev, tx_len);
 	if (!skb)
 		return -ENOMEM;
@@ -10974,9 +11066,58 @@
 	memcpy(tx_data, tp->dev->dev_addr, 6);
 	memset(tx_data + 6, 0x0, 8);
 
-	tw32(MAC_RX_MTU_SIZE, tx_len + 4);
+	tw32(MAC_RX_MTU_SIZE, tx_len + ETH_FCS_LEN);
 
-	for (i = 14; i < tx_len; i++)
+	if (loopback_mode == TG3_TSO_LOOPBACK) {
+		struct iphdr *iph = (struct iphdr *)&tx_data[ETH_HLEN];
+
+		u32 hdr_len = TG3_TSO_IP_HDR_LEN + TG3_TSO_TCP_HDR_LEN +
+			      TG3_TSO_TCP_OPT_LEN;
+
+		memcpy(tx_data + ETH_ALEN * 2, tg3_tso_header,
+		       sizeof(tg3_tso_header));
+		mss = TG3_TSO_MSS;
+
+		val = tx_len - ETH_ALEN * 2 - sizeof(tg3_tso_header);
+		num_pkts = DIV_ROUND_UP(val, TG3_TSO_MSS);
+
+		/* Set the total length field in the IP header */
+		iph->tot_len = htons((u16)(mss + hdr_len));
+
+		base_flags = (TXD_FLAG_CPU_PRE_DMA |
+			      TXD_FLAG_CPU_POST_DMA);
+
+		if (tg3_flag(tp, HW_TSO_1) ||
+		    tg3_flag(tp, HW_TSO_2) ||
+		    tg3_flag(tp, HW_TSO_3)) {
+			struct tcphdr *th;
+			val = ETH_HLEN + TG3_TSO_IP_HDR_LEN;
+			th = (struct tcphdr *)&tx_data[val];
+			th->check = 0;
+		} else
+			base_flags |= TXD_FLAG_TCPUDP_CSUM;
+
+		if (tg3_flag(tp, HW_TSO_3)) {
+			mss |= (hdr_len & 0xc) << 12;
+			if (hdr_len & 0x10)
+				base_flags |= 0x00000010;
+			base_flags |= (hdr_len & 0x3e0) << 5;
+		} else if (tg3_flag(tp, HW_TSO_2))
+			mss |= hdr_len << 9;
+		else if (tg3_flag(tp, HW_TSO_1) ||
+			 GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705) {
+			mss |= (TG3_TSO_TCP_OPT_LEN << 9);
+		} else {
+			base_flags |= (TG3_TSO_TCP_OPT_LEN << 10);
+		}
+
+		data_off = ETH_ALEN * 2 + sizeof(tg3_tso_header);
+	} else {
+		num_pkts = 1;
+		data_off = ETH_HLEN;
+	}
+
+	for (i = data_off; i < tx_len; i++)
 		tx_data[i] = (u8) (i & 0xff);
 
 	map = pci_map_single(tp->pdev, skb->data, tx_len, PCI_DMA_TODEVICE);
@@ -10992,12 +11133,10 @@
 
 	rx_start_idx = rnapi->hw_status->idx[0].rx_producer;
 
-	num_pkts = 0;
-
-	tg3_set_txd(tnapi, tnapi->tx_prod, map, tx_len, 0, 1);
+	tg3_set_txd(tnapi, tnapi->tx_prod, map, tx_len,
+		    base_flags, (mss << 1) | 1);
 
 	tnapi->tx_prod++;
-	num_pkts++;
 
 	tw32_tx_mbox(tnapi->prodmbox, tnapi->tx_prod);
 	tr32_mailbox(tnapi->prodmbox);
@@ -11027,29 +11166,56 @@
 	if (rx_idx != rx_start_idx + num_pkts)
 		goto out;
 
-	desc = &rnapi->rx_rcb[rx_start_idx];
-	desc_idx = desc->opaque & RXD_OPAQUE_INDEX_MASK;
-	opaque_key = desc->opaque & RXD_OPAQUE_RING_MASK;
-	if (opaque_key != RXD_OPAQUE_RING_STD)
-		goto out;
+	val = data_off;
+	while (rx_idx != rx_start_idx) {
+		desc = &rnapi->rx_rcb[rx_start_idx++];
+		desc_idx = desc->opaque & RXD_OPAQUE_INDEX_MASK;
+		opaque_key = desc->opaque & RXD_OPAQUE_RING_MASK;
 
-	if ((desc->err_vlan & RXD_ERR_MASK) != 0 &&
-	    (desc->err_vlan != RXD_ERR_ODD_NIBBLE_RCVD_MII))
-		goto out;
+		if ((desc->err_vlan & RXD_ERR_MASK) != 0 &&
+		    (desc->err_vlan != RXD_ERR_ODD_NIBBLE_RCVD_MII))
+			goto out;
 
-	rx_len = ((desc->idx_len & RXD_LEN_MASK) >> RXD_LEN_SHIFT) - 4;
-	if (rx_len != tx_len)
-		goto out;
+		rx_len = ((desc->idx_len & RXD_LEN_MASK) >> RXD_LEN_SHIFT)
+			 - ETH_FCS_LEN;
 
-	rx_skb = tpr->rx_std_buffers[desc_idx].skb;
+		if (loopback_mode != TG3_TSO_LOOPBACK) {
+			if (rx_len != tx_len)
+				goto out;
 
-	map = dma_unmap_addr(&tpr->rx_std_buffers[desc_idx], mapping);
-	pci_dma_sync_single_for_cpu(tp->pdev, map, rx_len, PCI_DMA_FROMDEVICE);
+			if (pktsz <= TG3_RX_STD_DMA_SZ - ETH_FCS_LEN) {
+				if (opaque_key != RXD_OPAQUE_RING_STD)
+					goto out;
+			} else {
+				if (opaque_key != RXD_OPAQUE_RING_JUMBO)
+					goto out;
+			}
+		} else if ((desc->type_flags & RXD_FLAG_TCPUDP_CSUM) &&
+			   (desc->ip_tcp_csum & RXD_TCPCSUM_MASK)
+			    >> RXD_TCPCSUM_SHIFT != 0xffff) {
+			goto out;
+		}
 
-	for (i = 14; i < tx_len; i++) {
-		if (*(rx_skb->data + i) != (u8) (i & 0xff))
+		if (opaque_key == RXD_OPAQUE_RING_STD) {
+			rx_skb = tpr->rx_std_buffers[desc_idx].skb;
+			map = dma_unmap_addr(&tpr->rx_std_buffers[desc_idx],
+					     mapping);
+		} else if (opaque_key == RXD_OPAQUE_RING_JUMBO) {
+			rx_skb = tpr->rx_jmb_buffers[desc_idx].skb;
+			map = dma_unmap_addr(&tpr->rx_jmb_buffers[desc_idx],
+					     mapping);
+		} else
 			goto out;
+
+		pci_dma_sync_single_for_cpu(tp->pdev, map, rx_len,
+					    PCI_DMA_FROMDEVICE);
+
+		for (i = data_off; i < rx_len; i++, val++) {
+			if (*(rx_skb->data + i) != (u8) (val & 0xff))
+				goto out;
+		}
 	}
+
 	err = 0;
 
 	/* tg3_free_rings will unmap and free the rx_skb */
@@ -11057,10 +11223,13 @@
 	return err;
 }
 
-#define TG3_MAC_LOOPBACK_FAILED		1
-#define TG3_PHY_LOOPBACK_FAILED		2
-#define TG3_LOOPBACK_FAILED		(TG3_MAC_LOOPBACK_FAILED |	\
-					 TG3_PHY_LOOPBACK_FAILED)
+#define TG3_STD_LOOPBACK_FAILED		1
+#define TG3_JMB_LOOPBACK_FAILED		2
+#define TG3_TSO_LOOPBACK_FAILED		4
+
+#define TG3_MAC_LOOPBACK_SHIFT		0
+#define TG3_PHY_LOOPBACK_SHIFT		4
+#define TG3_LOOPBACK_FAILED		0x00000077
 
 static int tg3_test_loopback(struct tg3 *tp)
 {
@@ -11079,11 +11248,20 @@
 		goto done;
 	}
 
+	if (tg3_flag(tp, ENABLE_RSS)) {
+		int i;
+
+		/* Reroute all rx packets to the 1st queue */
+		for (i = MAC_RSS_INDIR_TBL_0;
+		     i < MAC_RSS_INDIR_TBL_0 + TG3_RSS_INDIR_TBL_SIZE; i += 4)
+			tw32(i, 0x0);
+	}
+
 	/* Turn off gphy autopowerdown. */
 	if (tp->phy_flags & TG3_PHYFLG_ENABLE_APD)
 		tg3_phy_toggle_apd(tp, false);
 
-	if (tp->tg3_flags & TG3_FLAG_CPMU_PRESENT) {
+	if (tg3_flag(tp, CPMU_PRESENT)) {
 		int i;
 		u32 status;
 
@@ -11109,10 +11287,14 @@
 				  CPMU_CTRL_LINK_AWARE_MODE));
 	}
 
-	if (tg3_run_loopback(tp, TG3_MAC_LOOPBACK))
-		err |= TG3_MAC_LOOPBACK_FAILED;
+	if (tg3_run_loopback(tp, ETH_FRAME_LEN, TG3_MAC_LOOPBACK))
+		err |= TG3_STD_LOOPBACK_FAILED << TG3_MAC_LOOPBACK_SHIFT;
 
-	if (tp->tg3_flags & TG3_FLAG_CPMU_PRESENT) {
+	if (tg3_flag(tp, JUMBO_RING_ENABLE) &&
+	    tg3_run_loopback(tp, 9000 + ETH_HLEN, TG3_MAC_LOOPBACK))
+		err |= TG3_JMB_LOOPBACK_FAILED << TG3_MAC_LOOPBACK_SHIFT;
+
+	if (tg3_flag(tp, CPMU_PRESENT)) {
 		tw32(TG3_CPMU_CTRL, cpmuctrl);
 
 		/* Release the mutex */
@@ -11120,9 +11302,18 @@
 	}
 
 	if (!(tp->phy_flags & TG3_PHYFLG_PHY_SERDES) &&
-	    !(tp->tg3_flags3 & TG3_FLG3_USE_PHYLIB)) {
-		if (tg3_run_loopback(tp, TG3_PHY_LOOPBACK))
-			err |= TG3_PHY_LOOPBACK_FAILED;
+	    !tg3_flag(tp, USE_PHYLIB)) {
+		if (tg3_run_loopback(tp, ETH_FRAME_LEN, TG3_PHY_LOOPBACK))
+			err |= TG3_STD_LOOPBACK_FAILED <<
+			       TG3_PHY_LOOPBACK_SHIFT;
+		if (tg3_flag(tp, TSO_CAPABLE) &&
+		    tg3_run_loopback(tp, ETH_FRAME_LEN, TG3_TSO_LOOPBACK))
+			err |= TG3_TSO_LOOPBACK_FAILED <<
+			       TG3_PHY_LOOPBACK_SHIFT;
+		if (tg3_flag(tp, JUMBO_RING_ENABLE) &&
+		    tg3_run_loopback(tp, 9000 + ETH_HLEN, TG3_PHY_LOOPBACK))
+			err |= TG3_JMB_LOOPBACK_FAILED <<
+			       TG3_PHY_LOOPBACK_SHIFT;
 	}
 
 	/* Re-enable gphy autopowerdown. */
@@ -11167,7 +11358,7 @@
 		tg3_halt(tp, RESET_KIND_SUSPEND, 1);
 		err = tg3_nvram_lock(tp);
 		tg3_halt_cpu(tp, RX_CPU_BASE);
-		if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS))
+		if (!tg3_flag(tp, 5705_PLUS))
 			tg3_halt_cpu(tp, TX_CPU_BASE);
 		if (!err)
 			tg3_nvram_unlock(tp);
@@ -11197,7 +11388,7 @@
 
 		tg3_halt(tp, RESET_KIND_SHUTDOWN, 1);
 		if (netif_running(dev)) {
-			tp->tg3_flags |= TG3_FLAG_INIT_COMPLETE;
+			tg3_flag_set(tp, INIT_COMPLETE);
 			err2 = tg3_restart_hw(tp, 1);
 			if (!err2)
 				tg3_netif_start(tp);
@@ -11219,7 +11410,7 @@
 	struct tg3 *tp = netdev_priv(dev);
 	int err;
 
-	if (tp->tg3_flags3 & TG3_FLG3_USE_PHYLIB) {
+	if (tg3_flag(tp, USE_PHYLIB)) {
 		struct phy_device *phydev;
 		if (!(tp->phy_flags & TG3_PHYFLG_IS_CONNECTED))
 			return -EAGAIN;
@@ -11238,9 +11429,7 @@
 		if (tp->phy_flags & TG3_PHYFLG_PHY_SERDES)
 			break;			/* We have no PHY */
 
-		if ((tp->phy_flags & TG3_PHYFLG_IS_LOW_POWER) ||
-		    ((tp->tg3_flags & TG3_FLAG_ENABLE_ASF) &&
-		     !netif_running(dev)))
+		if (!netif_running(dev))
 			return -EAGAIN;
 
 		spin_lock_bh(&tp->lock);
@@ -11256,9 +11445,7 @@
 		if (tp->phy_flags & TG3_PHYFLG_PHY_SERDES)
 			break;			/* We have no PHY */
 
-		if ((tp->phy_flags & TG3_PHYFLG_IS_LOW_POWER) ||
-		    ((tp->tg3_flags & TG3_FLAG_ENABLE_ASF) &&
-		     !netif_running(dev)))
+		if (!netif_running(dev))
 			return -EAGAIN;
 
 		spin_lock_bh(&tp->lock);
@@ -11288,7 +11475,7 @@
 	u32 max_rxcoal_tick_int = 0, max_txcoal_tick_int = 0;
 	u32 max_stat_coal_ticks = 0, min_stat_coal_ticks = 0;
 
-	if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS)) {
+	if (!tg3_flag(tp, 5705_PLUS)) {
 		max_rxcoal_tick_int = MAX_RXCOAL_TICK_INT;
 		max_txcoal_tick_int = MAX_TXCOAL_TICK_INT;
 		max_stat_coal_ticks = MAX_STAT_COAL_TICKS;
@@ -11355,14 +11542,9 @@
 	.set_ringparam		= tg3_set_ringparam,
 	.get_pauseparam		= tg3_get_pauseparam,
 	.set_pauseparam		= tg3_set_pauseparam,
-	.get_rx_csum		= tg3_get_rx_csum,
-	.set_rx_csum		= tg3_set_rx_csum,
-	.set_tx_csum		= tg3_set_tx_csum,
-	.set_sg			= ethtool_op_set_sg,
-	.set_tso		= tg3_set_tso,
 	.self_test		= tg3_self_test,
 	.get_strings		= tg3_get_strings,
-	.phys_id		= tg3_phys_id,
+	.set_phys_id		= tg3_set_phys_id,
 	.get_ethtool_stats	= tg3_get_ethtool_stats,
 	.get_coalesce		= tg3_get_coalesce,
 	.set_coalesce		= tg3_set_coalesce,
@@ -11407,8 +11589,7 @@
 {
 	u32 val;
 
-	if ((tp->tg3_flags3 & TG3_FLG3_NO_NVRAM) ||
-	    tg3_nvram_read(tp, 0, &val) != 0)
+	if (tg3_flag(tp, NO_NVRAM) || tg3_nvram_read(tp, 0, &val) != 0)
 		return;
 
 	/* Selfboot format */
@@ -11443,19 +11624,19 @@
 
 	nvcfg1 = tr32(NVRAM_CFG1);
 	if (nvcfg1 & NVRAM_CFG1_FLASHIF_ENAB) {
-		tp->tg3_flags2 |= TG3_FLG2_FLASH;
+		tg3_flag_set(tp, FLASH);
 	} else {
 		nvcfg1 &= ~NVRAM_CFG1_COMPAT_BYPASS;
 		tw32(NVRAM_CFG1, nvcfg1);
 	}
 
-	if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5750) ||
-	    (tp->tg3_flags2 & TG3_FLG2_5780_CLASS)) {
+	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5750 ||
+	    tg3_flag(tp, 5780_CLASS)) {
 		switch (nvcfg1 & NVRAM_CFG1_VENDOR_MASK) {
 		case FLASH_VENDOR_ATMEL_FLASH_BUFFERED:
 			tp->nvram_jedecnum = JEDEC_ATMEL;
 			tp->nvram_pagesize = ATMEL_AT45DB0X1B_PAGE_SIZE;
-			tp->tg3_flags |= TG3_FLAG_NVRAM_BUFFERED;
+			tg3_flag_set(tp, NVRAM_BUFFERED);
 			break;
 		case FLASH_VENDOR_ATMEL_FLASH_UNBUFFERED:
 			tp->nvram_jedecnum = JEDEC_ATMEL;
@@ -11464,12 +11645,12 @@
 		case FLASH_VENDOR_ATMEL_EEPROM:
 			tp->nvram_jedecnum = JEDEC_ATMEL;
 			tp->nvram_pagesize = ATMEL_AT24C512_CHIP_SIZE;
-			tp->tg3_flags |= TG3_FLAG_NVRAM_BUFFERED;
+			tg3_flag_set(tp, NVRAM_BUFFERED);
 			break;
 		case FLASH_VENDOR_ST:
 			tp->nvram_jedecnum = JEDEC_ST;
 			tp->nvram_pagesize = ST_M45PEX0_PAGE_SIZE;
-			tp->tg3_flags |= TG3_FLAG_NVRAM_BUFFERED;
+			tg3_flag_set(tp, NVRAM_BUFFERED);
 			break;
 		case FLASH_VENDOR_SAIFUN:
 			tp->nvram_jedecnum = JEDEC_SAIFUN;
@@ -11484,7 +11665,7 @@
 	} else {
 		tp->nvram_jedecnum = JEDEC_ATMEL;
 		tp->nvram_pagesize = ATMEL_AT45DB0X1B_PAGE_SIZE;
-		tp->tg3_flags |= TG3_FLAG_NVRAM_BUFFERED;
+		tg3_flag_set(tp, NVRAM_BUFFERED);
 	}
 }
 
@@ -11523,29 +11704,29 @@
 
 	/* NVRAM protection for TPM */
 	if (nvcfg1 & (1 << 27))
-		tp->tg3_flags3 |= TG3_FLG3_PROTECTED_NVRAM;
+		tg3_flag_set(tp, PROTECTED_NVRAM);
 
 	switch (nvcfg1 & NVRAM_CFG1_5752VENDOR_MASK) {
 	case FLASH_5752VENDOR_ATMEL_EEPROM_64KHZ:
 	case FLASH_5752VENDOR_ATMEL_EEPROM_376KHZ:
 		tp->nvram_jedecnum = JEDEC_ATMEL;
-		tp->tg3_flags |= TG3_FLAG_NVRAM_BUFFERED;
+		tg3_flag_set(tp, NVRAM_BUFFERED);
 		break;
 	case FLASH_5752VENDOR_ATMEL_FLASH_BUFFERED:
 		tp->nvram_jedecnum = JEDEC_ATMEL;
-		tp->tg3_flags |= TG3_FLAG_NVRAM_BUFFERED;
-		tp->tg3_flags2 |= TG3_FLG2_FLASH;
+		tg3_flag_set(tp, NVRAM_BUFFERED);
+		tg3_flag_set(tp, FLASH);
 		break;
 	case FLASH_5752VENDOR_ST_M45PE10:
 	case FLASH_5752VENDOR_ST_M45PE20:
 	case FLASH_5752VENDOR_ST_M45PE40:
 		tp->nvram_jedecnum = JEDEC_ST;
-		tp->tg3_flags |= TG3_FLAG_NVRAM_BUFFERED;
-		tp->tg3_flags2 |= TG3_FLG2_FLASH;
+		tg3_flag_set(tp, NVRAM_BUFFERED);
+		tg3_flag_set(tp, FLASH);
 		break;
 	}
 
-	if (tp->tg3_flags2 & TG3_FLG2_FLASH) {
+	if (tg3_flag(tp, FLASH)) {
 		tg3_nvram_get_pagesize(tp, nvcfg1);
 	} else {
 		/* For eeprom, set pagesize to maximum eeprom size */
@@ -11564,7 +11745,7 @@
 
 	/* NVRAM protection for TPM */
 	if (nvcfg1 & (1 << 27)) {
-		tp->tg3_flags3 |= TG3_FLG3_PROTECTED_NVRAM;
+		tg3_flag_set(tp, PROTECTED_NVRAM);
 		protect = 1;
 	}
 
@@ -11575,8 +11756,8 @@
 	case FLASH_5755VENDOR_ATMEL_FLASH_3:
 	case FLASH_5755VENDOR_ATMEL_FLASH_5:
 		tp->nvram_jedecnum = JEDEC_ATMEL;
-		tp->tg3_flags |= TG3_FLAG_NVRAM_BUFFERED;
-		tp->tg3_flags2 |= TG3_FLG2_FLASH;
+		tg3_flag_set(tp, NVRAM_BUFFERED);
+		tg3_flag_set(tp, FLASH);
 		tp->nvram_pagesize = 264;
 		if (nvcfg1 == FLASH_5755VENDOR_ATMEL_FLASH_1 ||
 		    nvcfg1 == FLASH_5755VENDOR_ATMEL_FLASH_5)
@@ -11593,8 +11774,8 @@
 	case FLASH_5752VENDOR_ST_M45PE20:
 	case FLASH_5752VENDOR_ST_M45PE40:
 		tp->nvram_jedecnum = JEDEC_ST;
-		tp->tg3_flags |= TG3_FLAG_NVRAM_BUFFERED;
-		tp->tg3_flags2 |= TG3_FLG2_FLASH;
+		tg3_flag_set(tp, NVRAM_BUFFERED);
+		tg3_flag_set(tp, FLASH);
 		tp->nvram_pagesize = 256;
 		if (nvcfg1 == FLASH_5752VENDOR_ST_M45PE10)
 			tp->nvram_size = (protect ?
@@ -11624,7 +11805,7 @@
 	case FLASH_5787VENDOR_MICRO_EEPROM_64KHZ:
 	case FLASH_5787VENDOR_MICRO_EEPROM_376KHZ:
 		tp->nvram_jedecnum = JEDEC_ATMEL;
-		tp->tg3_flags |= TG3_FLAG_NVRAM_BUFFERED;
+		tg3_flag_set(tp, NVRAM_BUFFERED);
 		tp->nvram_pagesize = ATMEL_AT24C512_CHIP_SIZE;
 
 		nvcfg1 &= ~NVRAM_CFG1_COMPAT_BYPASS;
@@ -11635,16 +11816,16 @@
 	case FLASH_5755VENDOR_ATMEL_FLASH_2:
 	case FLASH_5755VENDOR_ATMEL_FLASH_3:
 		tp->nvram_jedecnum = JEDEC_ATMEL;
-		tp->tg3_flags |= TG3_FLAG_NVRAM_BUFFERED;
-		tp->tg3_flags2 |= TG3_FLG2_FLASH;
+		tg3_flag_set(tp, NVRAM_BUFFERED);
+		tg3_flag_set(tp, FLASH);
 		tp->nvram_pagesize = 264;
 		break;
 	case FLASH_5752VENDOR_ST_M45PE10:
 	case FLASH_5752VENDOR_ST_M45PE20:
 	case FLASH_5752VENDOR_ST_M45PE40:
 		tp->nvram_jedecnum = JEDEC_ST;
-		tp->tg3_flags |= TG3_FLAG_NVRAM_BUFFERED;
-		tp->tg3_flags2 |= TG3_FLG2_FLASH;
+		tg3_flag_set(tp, NVRAM_BUFFERED);
+		tg3_flag_set(tp, FLASH);
 		tp->nvram_pagesize = 256;
 		break;
 	}
@@ -11658,7 +11839,7 @@
 
 	/* NVRAM protection for TPM */
 	if (nvcfg1 & (1 << 27)) {
-		tp->tg3_flags3 |= TG3_FLG3_PROTECTED_NVRAM;
+		tg3_flag_set(tp, PROTECTED_NVRAM);
 		protect = 1;
 	}
 
@@ -11673,9 +11854,9 @@
 	case FLASH_5761VENDOR_ATMEL_MDB081D:
 	case FLASH_5761VENDOR_ATMEL_MDB161D:
 		tp->nvram_jedecnum = JEDEC_ATMEL;
-		tp->tg3_flags |= TG3_FLAG_NVRAM_BUFFERED;
-		tp->tg3_flags2 |= TG3_FLG2_FLASH;
-		tp->tg3_flags3 |= TG3_FLG3_NO_NVRAM_ADDR_TRANS;
+		tg3_flag_set(tp, NVRAM_BUFFERED);
+		tg3_flag_set(tp, FLASH);
+		tg3_flag_set(tp, NO_NVRAM_ADDR_TRANS);
 		tp->nvram_pagesize = 256;
 		break;
 	case FLASH_5761VENDOR_ST_A_M45PE20:
@@ -11687,8 +11868,8 @@
 	case FLASH_5761VENDOR_ST_M_M45PE80:
 	case FLASH_5761VENDOR_ST_M_M45PE16:
 		tp->nvram_jedecnum = JEDEC_ST;
-		tp->tg3_flags |= TG3_FLAG_NVRAM_BUFFERED;
-		tp->tg3_flags2 |= TG3_FLG2_FLASH;
+		tg3_flag_set(tp, NVRAM_BUFFERED);
+		tg3_flag_set(tp, FLASH);
 		tp->nvram_pagesize = 256;
 		break;
 	}
@@ -11728,7 +11909,7 @@
 static void __devinit tg3_get_5906_nvram_info(struct tg3 *tp)
 {
 	tp->nvram_jedecnum = JEDEC_ATMEL;
-	tp->tg3_flags |= TG3_FLAG_NVRAM_BUFFERED;
+	tg3_flag_set(tp, NVRAM_BUFFERED);
 	tp->nvram_pagesize = ATMEL_AT24C512_CHIP_SIZE;
 }
 
@@ -11742,7 +11923,7 @@
 	case FLASH_5787VENDOR_ATMEL_EEPROM_376KHZ:
 	case FLASH_5787VENDOR_MICRO_EEPROM_376KHZ:
 		tp->nvram_jedecnum = JEDEC_ATMEL;
-		tp->tg3_flags |= TG3_FLAG_NVRAM_BUFFERED;
+		tg3_flag_set(tp, NVRAM_BUFFERED);
 		tp->nvram_pagesize = ATMEL_AT24C512_CHIP_SIZE;
 
 		nvcfg1 &= ~NVRAM_CFG1_COMPAT_BYPASS;
@@ -11756,8 +11937,8 @@
 	case FLASH_57780VENDOR_ATMEL_AT45DB041D:
 	case FLASH_57780VENDOR_ATMEL_AT45DB041B:
 		tp->nvram_jedecnum = JEDEC_ATMEL;
-		tp->tg3_flags |= TG3_FLAG_NVRAM_BUFFERED;
-		tp->tg3_flags2 |= TG3_FLG2_FLASH;
+		tg3_flag_set(tp, NVRAM_BUFFERED);
+		tg3_flag_set(tp, FLASH);
 
 		switch (nvcfg1 & NVRAM_CFG1_5752VENDOR_MASK) {
 		case FLASH_5752VENDOR_ATMEL_FLASH_BUFFERED:
@@ -11779,8 +11960,8 @@
 	case FLASH_5752VENDOR_ST_M45PE20:
 	case FLASH_5752VENDOR_ST_M45PE40:
 		tp->nvram_jedecnum = JEDEC_ST;
-		tp->tg3_flags |= TG3_FLAG_NVRAM_BUFFERED;
-		tp->tg3_flags2 |= TG3_FLG2_FLASH;
+		tg3_flag_set(tp, NVRAM_BUFFERED);
+		tg3_flag_set(tp, FLASH);
 
 		switch (nvcfg1 & NVRAM_CFG1_5752VENDOR_MASK) {
 		case FLASH_5752VENDOR_ST_M45PE10:
@@ -11795,13 +11976,13 @@
 		}
 		break;
 	default:
-		tp->tg3_flags3 |= TG3_FLG3_NO_NVRAM;
+		tg3_flag_set(tp, NO_NVRAM);
 		return;
 	}
 
 	tg3_nvram_get_pagesize(tp, nvcfg1);
 	if (tp->nvram_pagesize != 264 && tp->nvram_pagesize != 528)
-		tp->tg3_flags3 |= TG3_FLG3_NO_NVRAM_ADDR_TRANS;
+		tg3_flag_set(tp, NO_NVRAM_ADDR_TRANS);
 }
 
 
@@ -11815,7 +11996,7 @@
 	case FLASH_5717VENDOR_ATMEL_EEPROM:
 	case FLASH_5717VENDOR_MICRO_EEPROM:
 		tp->nvram_jedecnum = JEDEC_ATMEL;
-		tp->tg3_flags |= TG3_FLAG_NVRAM_BUFFERED;
+		tg3_flag_set(tp, NVRAM_BUFFERED);
 		tp->nvram_pagesize = ATMEL_AT24C512_CHIP_SIZE;
 
 		nvcfg1 &= ~NVRAM_CFG1_COMPAT_BYPASS;
@@ -11829,11 +12010,13 @@
 	case FLASH_5717VENDOR_ATMEL_ADB021D:
 	case FLASH_5717VENDOR_ATMEL_45USPT:
 		tp->nvram_jedecnum = JEDEC_ATMEL;
-		tp->tg3_flags |= TG3_FLAG_NVRAM_BUFFERED;
-		tp->tg3_flags2 |= TG3_FLG2_FLASH;
+		tg3_flag_set(tp, NVRAM_BUFFERED);
+		tg3_flag_set(tp, FLASH);
 
 		switch (nvcfg1 & NVRAM_CFG1_5752VENDOR_MASK) {
 		case FLASH_5717VENDOR_ATMEL_MDB021D:
+			/* Detect size with tg3_nvram_get_size() */
+			break;
 		case FLASH_5717VENDOR_ATMEL_ADB021B:
 		case FLASH_5717VENDOR_ATMEL_ADB021D:
 			tp->nvram_size = TG3_NVRAM_SIZE_256KB;
@@ -11854,13 +12037,15 @@
 	case FLASH_5717VENDOR_ST_25USPT:
 	case FLASH_5717VENDOR_ST_45USPT:
 		tp->nvram_jedecnum = JEDEC_ST;
-		tp->tg3_flags |= TG3_FLAG_NVRAM_BUFFERED;
-		tp->tg3_flags2 |= TG3_FLG2_FLASH;
+		tg3_flag_set(tp, NVRAM_BUFFERED);
+		tg3_flag_set(tp, FLASH);
 
 		switch (nvcfg1 & NVRAM_CFG1_5752VENDOR_MASK) {
 		case FLASH_5717VENDOR_ST_M_M25PE20:
-		case FLASH_5717VENDOR_ST_A_M25PE20:
 		case FLASH_5717VENDOR_ST_M_M45PE20:
+			/* Detect size with tg3_nvram_get_size() */
+			break;
+		case FLASH_5717VENDOR_ST_A_M25PE20:
 		case FLASH_5717VENDOR_ST_A_M45PE20:
 			tp->nvram_size = TG3_NVRAM_SIZE_256KB;
 			break;
@@ -11870,13 +12055,125 @@
 		}
 		break;
 	default:
-		tp->tg3_flags3 |= TG3_FLG3_NO_NVRAM;
+		tg3_flag_set(tp, NO_NVRAM);
 		return;
 	}
 
 	tg3_nvram_get_pagesize(tp, nvcfg1);
 	if (tp->nvram_pagesize != 264 && tp->nvram_pagesize != 528)
-		tp->tg3_flags3 |= TG3_FLG3_NO_NVRAM_ADDR_TRANS;
+		tg3_flag_set(tp, NO_NVRAM_ADDR_TRANS);
+}
+
+static void __devinit tg3_get_5720_nvram_info(struct tg3 *tp)
+{
+	u32 nvcfg1, nvmpinstrp;
+
+	nvcfg1 = tr32(NVRAM_CFG1);
+	nvmpinstrp = nvcfg1 & NVRAM_CFG1_5752VENDOR_MASK;
+
+	switch (nvmpinstrp) {
+	case FLASH_5720_EEPROM_HD:
+	case FLASH_5720_EEPROM_LD:
+		tp->nvram_jedecnum = JEDEC_ATMEL;
+		tg3_flag_set(tp, NVRAM_BUFFERED);
+
+		nvcfg1 &= ~NVRAM_CFG1_COMPAT_BYPASS;
+		tw32(NVRAM_CFG1, nvcfg1);
+		if (nvmpinstrp == FLASH_5720_EEPROM_HD)
+			tp->nvram_pagesize = ATMEL_AT24C512_CHIP_SIZE;
+		else
+			tp->nvram_pagesize = ATMEL_AT24C02_CHIP_SIZE;
+		return;
+	case FLASH_5720VENDOR_M_ATMEL_DB011D:
+	case FLASH_5720VENDOR_A_ATMEL_DB011B:
+	case FLASH_5720VENDOR_A_ATMEL_DB011D:
+	case FLASH_5720VENDOR_M_ATMEL_DB021D:
+	case FLASH_5720VENDOR_A_ATMEL_DB021B:
+	case FLASH_5720VENDOR_A_ATMEL_DB021D:
+	case FLASH_5720VENDOR_M_ATMEL_DB041D:
+	case FLASH_5720VENDOR_A_ATMEL_DB041B:
+	case FLASH_5720VENDOR_A_ATMEL_DB041D:
+	case FLASH_5720VENDOR_M_ATMEL_DB081D:
+	case FLASH_5720VENDOR_A_ATMEL_DB081D:
+	case FLASH_5720VENDOR_ATMEL_45USPT:
+		tp->nvram_jedecnum = JEDEC_ATMEL;
+		tg3_flag_set(tp, NVRAM_BUFFERED);
+		tg3_flag_set(tp, FLASH);
+
+		switch (nvmpinstrp) {
+		case FLASH_5720VENDOR_M_ATMEL_DB021D:
+		case FLASH_5720VENDOR_A_ATMEL_DB021B:
+		case FLASH_5720VENDOR_A_ATMEL_DB021D:
+			tp->nvram_size = TG3_NVRAM_SIZE_256KB;
+			break;
+		case FLASH_5720VENDOR_M_ATMEL_DB041D:
+		case FLASH_5720VENDOR_A_ATMEL_DB041B:
+		case FLASH_5720VENDOR_A_ATMEL_DB041D:
+			tp->nvram_size = TG3_NVRAM_SIZE_512KB;
+			break;
+		case FLASH_5720VENDOR_M_ATMEL_DB081D:
+		case FLASH_5720VENDOR_A_ATMEL_DB081D:
+			tp->nvram_size = TG3_NVRAM_SIZE_1MB;
+			break;
+		default:
+			tp->nvram_size = TG3_NVRAM_SIZE_128KB;
+			break;
+		}
+		break;
+	case FLASH_5720VENDOR_M_ST_M25PE10:
+	case FLASH_5720VENDOR_M_ST_M45PE10:
+	case FLASH_5720VENDOR_A_ST_M25PE10:
+	case FLASH_5720VENDOR_A_ST_M45PE10:
+	case FLASH_5720VENDOR_M_ST_M25PE20:
+	case FLASH_5720VENDOR_M_ST_M45PE20:
+	case FLASH_5720VENDOR_A_ST_M25PE20:
+	case FLASH_5720VENDOR_A_ST_M45PE20:
+	case FLASH_5720VENDOR_M_ST_M25PE40:
+	case FLASH_5720VENDOR_M_ST_M45PE40:
+	case FLASH_5720VENDOR_A_ST_M25PE40:
+	case FLASH_5720VENDOR_A_ST_M45PE40:
+	case FLASH_5720VENDOR_M_ST_M25PE80:
+	case FLASH_5720VENDOR_M_ST_M45PE80:
+	case FLASH_5720VENDOR_A_ST_M25PE80:
+	case FLASH_5720VENDOR_A_ST_M45PE80:
+	case FLASH_5720VENDOR_ST_25USPT:
+	case FLASH_5720VENDOR_ST_45USPT:
+		tp->nvram_jedecnum = JEDEC_ST;
+		tg3_flag_set(tp, NVRAM_BUFFERED);
+		tg3_flag_set(tp, FLASH);
+
+		switch (nvmpinstrp) {
+		case FLASH_5720VENDOR_M_ST_M25PE20:
+		case FLASH_5720VENDOR_M_ST_M45PE20:
+		case FLASH_5720VENDOR_A_ST_M25PE20:
+		case FLASH_5720VENDOR_A_ST_M45PE20:
+			tp->nvram_size = TG3_NVRAM_SIZE_256KB;
+			break;
+		case FLASH_5720VENDOR_M_ST_M25PE40:
+		case FLASH_5720VENDOR_M_ST_M45PE40:
+		case FLASH_5720VENDOR_A_ST_M25PE40:
+		case FLASH_5720VENDOR_A_ST_M45PE40:
+			tp->nvram_size = TG3_NVRAM_SIZE_512KB;
+			break;
+		case FLASH_5720VENDOR_M_ST_M25PE80:
+		case FLASH_5720VENDOR_M_ST_M45PE80:
+		case FLASH_5720VENDOR_A_ST_M25PE80:
+		case FLASH_5720VENDOR_A_ST_M45PE80:
+			tp->nvram_size = TG3_NVRAM_SIZE_1MB;
+			break;
+		default:
+			tp->nvram_size = TG3_NVRAM_SIZE_128KB;
+			break;
+		}
+		break;
+	default:
+		tg3_flag_set(tp, NO_NVRAM);
+		return;
+	}
+
+	tg3_nvram_get_pagesize(tp, nvcfg1);
+	if (tp->nvram_pagesize != 264 && tp->nvram_pagesize != 528)
+		tg3_flag_set(tp, NO_NVRAM_ADDR_TRANS);
 }
 
 /* Chips other than 5700/5701 use the NVRAM for fetching info. */
@@ -11896,7 +12193,7 @@
 
 	if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5700 &&
 	    GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5701) {
-		tp->tg3_flags |= TG3_FLAG_NVRAM;
+		tg3_flag_set(tp, NVRAM);
 
 		if (tg3_nvram_lock(tp)) {
 			netdev_warn(tp->dev,
@@ -11926,6 +12223,8 @@
 		else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 ||
 			 GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719)
 			tg3_get_5717_nvram_info(tp);
+		else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5720)
+			tg3_get_5720_nvram_info(tp);
 		else
 			tg3_get_nvram_info(tp);
 
@@ -11936,7 +12235,8 @@
 		tg3_nvram_unlock(tp);
 
 	} else {
-		tp->tg3_flags &= ~(TG3_FLAG_NVRAM | TG3_FLAG_NVRAM_BUFFERED);
+		tg3_flag_clear(tp, NVRAM);
+		tg3_flag_clear(tp, NVRAM_BUFFERED);
 
 		tg3_get_eeprom_size(tp);
 	}
@@ -12119,7 +12419,7 @@
 			nvram_cmd |= NVRAM_CMD_LAST;
 
 		if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5752 &&
-		    !(tp->tg3_flags3 & TG3_FLG3_5755_PLUS) &&
+		    !tg3_flag(tp, 5755_PLUS) &&
 		    (tp->nvram_jedecnum == JEDEC_ST) &&
 		    (nvram_cmd & NVRAM_CMD_FIRST)) {
 
@@ -12129,7 +12429,7 @@
 
 				break;
 		}
-		if (!(tp->tg3_flags2 & TG3_FLG2_FLASH)) {
+		if (!tg3_flag(tp, FLASH)) {
 			/* We always do complete word writes to eeprom. */
 			nvram_cmd |= (NVRAM_CMD_FIRST | NVRAM_CMD_LAST);
 		}
@@ -12145,13 +12445,13 @@
 {
 	int ret;
 
-	if (tp->tg3_flags & TG3_FLAG_EEPROM_WRITE_PROT) {
+	if (tg3_flag(tp, EEPROM_WRITE_PROT)) {
 		tw32_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl &
 		       ~GRC_LCLCTRL_GPIO_OUTPUT1);
 		udelay(40);
 	}
 
-	if (!(tp->tg3_flags & TG3_FLAG_NVRAM)) {
+	if (!tg3_flag(tp, NVRAM)) {
 		ret = tg3_nvram_write_block_using_eeprom(tp, offset, len, buf);
 	} else {
 		u32 grc_mode;
@@ -12161,16 +12461,13 @@
 			return ret;
 
 		tg3_enable_nvram_access(tp);
-		if ((tp->tg3_flags2 & TG3_FLG2_5750_PLUS) &&
-		    !(tp->tg3_flags3 & TG3_FLG3_PROTECTED_NVRAM))
+		if (tg3_flag(tp, 5750_PLUS) && !tg3_flag(tp, PROTECTED_NVRAM))
 			tw32(NVRAM_WRITE1, 0x406);
 
 		grc_mode = tr32(GRC_MODE);
 		tw32(GRC_MODE, grc_mode | GRC_MODE_NVRAM_WR_ENABLE);
 
-		if ((tp->tg3_flags & TG3_FLAG_NVRAM_BUFFERED) ||
-			!(tp->tg3_flags2 & TG3_FLG2_FLASH)) {
-
+		if (tg3_flag(tp, NVRAM_BUFFERED) || !tg3_flag(tp, FLASH)) {
 			ret = tg3_nvram_write_block_buffered(tp, offset, len,
 				buf);
 		} else {
@@ -12185,7 +12482,7 @@
 		tg3_nvram_unlock(tp);
 	}
 
-	if (tp->tg3_flags & TG3_FLAG_EEPROM_WRITE_PROT) {
+	if (tg3_flag(tp, EEPROM_WRITE_PROT)) {
 		tw32_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl);
 		udelay(40);
 	}
@@ -12307,19 +12604,20 @@
 	tp->led_ctrl = LED_CTRL_MODE_PHY_1;
 
 	/* Assume an onboard device and WOL capable by default.  */
-	tp->tg3_flags |= TG3_FLAG_EEPROM_WRITE_PROT | TG3_FLAG_WOL_CAP;
+	tg3_flag_set(tp, EEPROM_WRITE_PROT);
+	tg3_flag_set(tp, WOL_CAP);
 
 	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) {
 		if (!(tr32(PCIE_TRANSACTION_CFG) & PCIE_TRANS_CFG_LOM)) {
-			tp->tg3_flags &= ~TG3_FLAG_EEPROM_WRITE_PROT;
-			tp->tg3_flags2 |= TG3_FLG2_IS_NIC;
+			tg3_flag_clear(tp, EEPROM_WRITE_PROT);
+			tg3_flag_set(tp, IS_NIC);
 		}
 		val = tr32(VCPU_CFGSHDW);
 		if (val & VCPU_CFGSHDW_ASPM_DBNC)
-			tp->tg3_flags |= TG3_FLAG_ASPM_WORKAROUND;
+			tg3_flag_set(tp, ASPM_WORKAROUND);
 		if ((val & VCPU_CFGSHDW_WOL_ENABLE) &&
 		    (val & VCPU_CFGSHDW_WOL_MAGPKT)) {
-			tp->tg3_flags |= TG3_FLAG_WOL_ENABLE;
+			tg3_flag_set(tp, WOL_ENABLE);
 			device_set_wakeup_enable(&tp->pdev->dev, true);
 		}
 		goto done;
@@ -12336,9 +12634,9 @@
 
 		tg3_read_mem(tp, NIC_SRAM_DATA_VER, &ver);
 		ver >>= NIC_SRAM_DATA_VER_SHIFT;
-		if ((GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5700) &&
-		    (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5701) &&
-		    (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5703) &&
+		if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5700 &&
+		    GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5701 &&
+		    GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5703 &&
 		    (ver > 0) && (ver < 0x100))
 			tg3_read_mem(tp, NIC_SRAM_DATA_CFG_2, &cfg2);
 
@@ -12362,13 +12660,13 @@
 
 		tp->phy_id = eeprom_phy_id;
 		if (eeprom_phy_serdes) {
-			if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS))
+			if (!tg3_flag(tp, 5705_PLUS))
 				tp->phy_flags |= TG3_PHYFLG_PHY_SERDES;
 			else
 				tp->phy_flags |= TG3_PHYFLG_MII_SERDES;
 		}
 
-		if (tp->tg3_flags2 & TG3_FLG2_5750_PLUS)
+		if (tg3_flag(tp, 5750_PLUS))
 			led_cfg = cfg2 & (NIC_SRAM_DATA_CFG_LED_MODE_MASK |
 				    SHASTA_EXT_LED_MODE_MASK);
 		else
@@ -12428,34 +12726,34 @@
 			tp->led_ctrl = LED_CTRL_MODE_PHY_1;
 
 		if (nic_cfg & NIC_SRAM_DATA_CFG_EEPROM_WP) {
-			tp->tg3_flags |= TG3_FLAG_EEPROM_WRITE_PROT;
+			tg3_flag_set(tp, EEPROM_WRITE_PROT);
 			if ((tp->pdev->subsystem_vendor ==
 			     PCI_VENDOR_ID_ARIMA) &&
 			    (tp->pdev->subsystem_device == 0x205a ||
 			     tp->pdev->subsystem_device == 0x2063))
-				tp->tg3_flags &= ~TG3_FLAG_EEPROM_WRITE_PROT;
+				tg3_flag_clear(tp, EEPROM_WRITE_PROT);
 		} else {
-			tp->tg3_flags &= ~TG3_FLAG_EEPROM_WRITE_PROT;
-			tp->tg3_flags2 |= TG3_FLG2_IS_NIC;
+			tg3_flag_clear(tp, EEPROM_WRITE_PROT);
+			tg3_flag_set(tp, IS_NIC);
 		}
 
 		if (nic_cfg & NIC_SRAM_DATA_CFG_ASF_ENABLE) {
-			tp->tg3_flags |= TG3_FLAG_ENABLE_ASF;
-			if (tp->tg3_flags2 & TG3_FLG2_5750_PLUS)
-				tp->tg3_flags2 |= TG3_FLG2_ASF_NEW_HANDSHAKE;
+			tg3_flag_set(tp, ENABLE_ASF);
+			if (tg3_flag(tp, 5750_PLUS))
+				tg3_flag_set(tp, ASF_NEW_HANDSHAKE);
 		}
 
 		if ((nic_cfg & NIC_SRAM_DATA_CFG_APE_ENABLE) &&
-			(tp->tg3_flags2 & TG3_FLG2_5750_PLUS))
-			tp->tg3_flags3 |= TG3_FLG3_ENABLE_APE;
+		    tg3_flag(tp, 5750_PLUS))
+			tg3_flag_set(tp, ENABLE_APE);
 
 		if (tp->phy_flags & TG3_PHYFLG_ANY_SERDES &&
 		    !(nic_cfg & NIC_SRAM_DATA_CFG_FIBER_WOL))
-			tp->tg3_flags &= ~TG3_FLAG_WOL_CAP;
+			tg3_flag_clear(tp, WOL_CAP);
 
-		if ((tp->tg3_flags & TG3_FLAG_WOL_CAP) &&
+		if (tg3_flag(tp, WOL_CAP) &&
 		    (nic_cfg & NIC_SRAM_DATA_CFG_WOL_ENABLE)) {
-			tp->tg3_flags |= TG3_FLAG_WOL_ENABLE;
+			tg3_flag_set(tp, WOL_ENABLE);
 			device_set_wakeup_enable(&tp->pdev->dev, true);
 		}
 
@@ -12467,33 +12765,33 @@
 		if (cfg2 & (1 << 18))
 			tp->phy_flags |= TG3_PHYFLG_SERDES_PREEMPHASIS;
 
-		if (((tp->tg3_flags3 & TG3_FLG3_5717_PLUS) ||
-		    ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5784 &&
-		      GET_CHIP_REV(tp->pci_chip_rev_id) != CHIPREV_5784_AX))) &&
+		if ((tg3_flag(tp, 57765_PLUS) ||
+		     (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5784 &&
+		      GET_CHIP_REV(tp->pci_chip_rev_id) != CHIPREV_5784_AX)) &&
 		    (cfg2 & NIC_SRAM_DATA_CFG_2_APD_EN))
 			tp->phy_flags |= TG3_PHYFLG_ENABLE_APD;
 
-		if ((tp->tg3_flags2 & TG3_FLG2_PCI_EXPRESS) &&
+		if (tg3_flag(tp, PCI_EXPRESS) &&
 		    GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5785 &&
-		    !(tp->tg3_flags3 & TG3_FLG3_5717_PLUS)) {
+		    !tg3_flag(tp, 57765_PLUS)) {
 			u32 cfg3;
 
 			tg3_read_mem(tp, NIC_SRAM_DATA_CFG_3, &cfg3);
 			if (cfg3 & NIC_SRAM_ASPM_DEBOUNCE)
-				tp->tg3_flags |= TG3_FLAG_ASPM_WORKAROUND;
+				tg3_flag_set(tp, ASPM_WORKAROUND);
 		}
 
 		if (cfg4 & NIC_SRAM_RGMII_INBAND_DISABLE)
-			tp->tg3_flags3 |= TG3_FLG3_RGMII_INBAND_DISABLE;
+			tg3_flag_set(tp, RGMII_INBAND_DISABLE);
 		if (cfg4 & NIC_SRAM_RGMII_EXT_IBND_RX_EN)
-			tp->tg3_flags3 |= TG3_FLG3_RGMII_EXT_IBND_RX_EN;
+			tg3_flag_set(tp, RGMII_EXT_IBND_RX_EN);
 		if (cfg4 & NIC_SRAM_RGMII_EXT_IBND_TX_EN)
-			tp->tg3_flags3 |= TG3_FLG3_RGMII_EXT_IBND_TX_EN;
+			tg3_flag_set(tp, RGMII_EXT_IBND_TX_EN);
 	}
 done:
-	if (tp->tg3_flags & TG3_FLAG_WOL_CAP)
+	if (tg3_flag(tp, WOL_CAP))
 		device_set_wakeup_enable(&tp->pdev->dev,
-				 tp->tg3_flags & TG3_FLAG_WOL_ENABLE);
+					 tg3_flag(tp, WOL_ENABLE));
 	else
 		device_set_wakeup_capable(&tp->pdev->dev, false);
 }
@@ -12583,18 +12881,17 @@
 	int err;
 
 	/* flow control autonegotiation is default behavior */
-	tp->tg3_flags |= TG3_FLAG_PAUSE_AUTONEG;
+	tg3_flag_set(tp, PAUSE_AUTONEG);
 	tp->link_config.flowctrl = FLOW_CTRL_TX | FLOW_CTRL_RX;
 
-	if (tp->tg3_flags3 & TG3_FLG3_USE_PHYLIB)
+	if (tg3_flag(tp, USE_PHYLIB))
 		return tg3_phy_init(tp);
 
 	/* Reading the PHY ID register can conflict with ASF
 	 * firmware access to the PHY hardware.
 	 */
 	err = 0;
-	if ((tp->tg3_flags & TG3_FLAG_ENABLE_ASF) ||
-	    (tp->tg3_flags3 & TG3_FLG3_ENABLE_APE)) {
+	if (tg3_flag(tp, ENABLE_ASF) || tg3_flag(tp, ENABLE_APE)) {
 		hw_phy_id = hw_phy_id_masked = TG3_PHY_ID_INVALID;
 	} else {
 		/* Now read the physical PHY_ID from the chip and verify
@@ -12650,9 +12947,9 @@
 	tg3_phy_init_link_config(tp);
 
 	if (!(tp->phy_flags & TG3_PHYFLG_ANY_SERDES) &&
-	    !(tp->tg3_flags3 & TG3_FLG3_ENABLE_APE) &&
-	    !(tp->tg3_flags & TG3_FLAG_ENABLE_ASF)) {
-		u32 bmsr, adv_reg, tg3_ctrl, mask;
+	    !tg3_flag(tp, ENABLE_APE) &&
+	    !tg3_flag(tp, ENABLE_ASF)) {
+		u32 bmsr, mask;
 
 		tg3_readphy(tp, MII_BMSR, &bmsr);
 		if (!tg3_readphy(tp, MII_BMSR, &bmsr) &&
@@ -12663,36 +12960,18 @@
 		if (err)
 			return err;
 
-		adv_reg = (ADVERTISE_10HALF | ADVERTISE_10FULL |
-			   ADVERTISE_100HALF | ADVERTISE_100FULL |
-			   ADVERTISE_CSMA | ADVERTISE_PAUSE_CAP);
-		tg3_ctrl = 0;
-		if (!(tp->phy_flags & TG3_PHYFLG_10_100_ONLY)) {
-			tg3_ctrl = (MII_TG3_CTRL_ADV_1000_HALF |
-				    MII_TG3_CTRL_ADV_1000_FULL);
-			if (tp->pci_chip_rev_id == CHIPREV_ID_5701_A0 ||
-			    tp->pci_chip_rev_id == CHIPREV_ID_5701_B0)
-				tg3_ctrl |= (MII_TG3_CTRL_AS_MASTER |
-					     MII_TG3_CTRL_ENABLE_AS_MASTER);
-		}
+		tg3_phy_set_wirespeed(tp);
 
 		mask = (ADVERTISED_10baseT_Half | ADVERTISED_10baseT_Full |
 			ADVERTISED_100baseT_Half | ADVERTISED_100baseT_Full |
 			ADVERTISED_1000baseT_Half | ADVERTISED_1000baseT_Full);
 		if (!tg3_copper_is_advertising_all(tp, mask)) {
-			tg3_writephy(tp, MII_ADVERTISE, adv_reg);
-
-			if (!(tp->phy_flags & TG3_PHYFLG_10_100_ONLY))
-				tg3_writephy(tp, MII_TG3_CTRL, tg3_ctrl);
+			tg3_phy_autoneg_cfg(tp, tp->link_config.advertising,
+					    tp->link_config.flowctrl);
 
 			tg3_writephy(tp, MII_BMCR,
 				     BMCR_ANENABLE | BMCR_ANRESTART);
 		}
-		tg3_phy_set_wirespeed(tp);
-
-		tg3_writephy(tp, MII_ADVERTISE, adv_reg);
-		if (!(tp->phy_flags & TG3_PHYFLG_10_100_ONLY))
-			tg3_writephy(tp, MII_TG3_CTRL, tg3_ctrl);
 	}
 
 skip_phy_reset:
@@ -12712,46 +12991,11 @@
 	u8 *vpd_data;
 	unsigned int block_end, rosize, len;
 	int j, i = 0;
-	u32 magic;
 
-	if ((tp->tg3_flags3 & TG3_FLG3_NO_NVRAM) ||
-	    tg3_nvram_read(tp, 0x0, &magic))
-		goto out_no_vpd;
-
-	vpd_data = kmalloc(TG3_NVM_VPD_LEN, GFP_KERNEL);
+	vpd_data = (u8 *)tg3_vpd_readblock(tp);
 	if (!vpd_data)
 		goto out_no_vpd;
 
-	if (magic == TG3_EEPROM_MAGIC) {
-		for (i = 0; i < TG3_NVM_VPD_LEN; i += 4) {
-			u32 tmp;
-
-			/* The data is in little-endian format in NVRAM.
-			 * Use the big-endian read routines to preserve
-			 * the byte order as it exists in NVRAM.
-			 */
-			if (tg3_nvram_read_be32(tp, TG3_NVM_VPD_OFF + i, &tmp))
-				goto out_not_found;
-
-			memcpy(&vpd_data[i], &tmp, sizeof(tmp));
-		}
-	} else {
-		ssize_t cnt;
-		unsigned int pos = 0;
-
-		for (; pos < TG3_NVM_VPD_LEN && i < 3; i++, pos += cnt) {
-			cnt = pci_read_vpd(tp->pdev, pos,
-					   TG3_NVM_VPD_LEN - pos,
-					   &vpd_data[pos]);
-			if (cnt == -ETIMEDOUT || cnt == -EINTR)
-				cnt = 0;
-			else if (cnt < 0)
-				goto out_not_found;
-		}
-		if (pos != TG3_NVM_VPD_LEN)
-			goto out_not_found;
-	}
-
 	i = pci_vpd_find_tag(vpd_data, 0, TG3_NVM_VPD_LEN,
 			     PCI_VPD_LRDT_RO_DATA);
 	if (i < 0)
@@ -13005,7 +13249,7 @@
 	if (offset == TG3_NVM_DIR_END)
 		return;
 
-	if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS))
+	if (!tg3_flag(tp, 5705_PLUS))
 		start = 0x08000000;
 	else if (tg3_nvram_read(tp, offset - 4, &start))
 		return;
@@ -13045,8 +13289,7 @@
 	u32 apedata;
 	char *fwtype;
 
-	if (!(tp->tg3_flags3 & TG3_FLG3_ENABLE_APE) ||
-	    !(tp->tg3_flags  & TG3_FLAG_ENABLE_ASF))
+	if (!tg3_flag(tp, ENABLE_APE) || !tg3_flag(tp, ENABLE_ASF))
 		return;
 
 	apedata = tg3_ape_read32(tp, TG3_APE_SEG_SIG);
@@ -13060,7 +13303,7 @@
 	apedata = tg3_ape_read32(tp, TG3_APE_FW_VERSION);
 
 	if (tg3_ape_read32(tp, TG3_APE_FW_FEATURES) & TG3_APE_FW_FEATURE_NCSI) {
-		tp->tg3_flags3 |= TG3_FLG3_APE_HAS_NCSI;
+		tg3_flag_set(tp, APE_HAS_NCSI);
 		fwtype = "NCSI";
 	} else {
 		fwtype = "DASH";
@@ -13084,7 +13327,7 @@
 	if (tp->fw_ver[0] != 0)
 		vpd_vers = true;
 
-	if (tp->tg3_flags3 & TG3_FLG3_NO_NVRAM) {
+	if (tg3_flag(tp, NO_NVRAM)) {
 		strcat(tp->fw_ver, "sb");
 		return;
 	}
@@ -13101,8 +13344,7 @@
 	else
 		return;
 
-	if (!(tp->tg3_flags & TG3_FLAG_ENABLE_ASF) ||
-	     (tp->tg3_flags3 & TG3_FLG3_ENABLE_APE) || vpd_vers)
+	if (!tg3_flag(tp, ENABLE_ASF) || tg3_flag(tp, ENABLE_APE) || vpd_vers)
 		goto done;
 
 	tg3_read_mgmtfw_ver(tp);
@@ -13113,21 +13355,14 @@
 
 static struct pci_dev * __devinit tg3_find_peer(struct tg3 *);
 
-static inline void vlan_features_add(struct net_device *dev, unsigned long flags)
-{
-	dev->vlan_features |= flags;
-}
-
 static inline u32 tg3_rx_ret_ring_size(struct tg3 *tp)
 {
-	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 ||
-	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719)
-		return 4096;
-	else if ((tp->tg3_flags & TG3_FLAG_JUMBO_CAPABLE) &&
-		 !(tp->tg3_flags2 & TG3_FLG2_5780_CLASS))
-		return 1024;
+	if (tg3_flag(tp, LRG_PROD_RING_CAP))
+		return TG3_RX_RET_MAX_SIZE_5717;
+	else if (tg3_flag(tp, JUMBO_CAPABLE) && !tg3_flag(tp, 5780_CLASS))
+		return TG3_RX_RET_MAX_SIZE_5700;
 	else
-		return 512;
+		return TG3_RX_RET_MAX_SIZE_5705;
 }
 
 static DEFINE_PCI_DEVICE_TABLE(tg3_write_reorder_chipsets) = {
@@ -13172,7 +13407,8 @@
 
 		if (tp->pdev->device == TG3PCI_DEVICE_TIGON3_5717 ||
 		    tp->pdev->device == TG3PCI_DEVICE_TIGON3_5718 ||
-		    tp->pdev->device == TG3PCI_DEVICE_TIGON3_5719)
+		    tp->pdev->device == TG3PCI_DEVICE_TIGON3_5719 ||
+		    tp->pdev->device == TG3PCI_DEVICE_TIGON3_5720)
 			pci_read_config_dword(tp->pdev,
 					      TG3PCI_GEN2_PRODID_ASICREV,
 					      &prod_id_asic_rev);
@@ -13249,15 +13485,14 @@
 			if (bridge->subordinate &&
 			    (bridge->subordinate->number ==
 			     tp->pdev->bus->number)) {
-
-				tp->tg3_flags2 |= TG3_FLG2_ICH_WORKAROUND;
+				tg3_flag_set(tp, ICH_WORKAROUND);
 				pci_dev_put(bridge);
 				break;
 			}
 		}
 	}
 
-	if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5701)) {
+	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5701) {
 		static struct tg3_dev_id {
 			u32	vendor;
 			u32	device;
@@ -13282,7 +13517,7 @@
 			     tp->pdev->bus->number) &&
 			    (bridge->subordinate->subordinate >=
 			     tp->pdev->bus->number)) {
-				tp->tg3_flags3 |= TG3_FLG3_5701_DMA_BUG;
+				tg3_flag_set(tp, 5701_DMA_BUG);
 				pci_dev_put(bridge);
 				break;
 			}
@@ -13297,8 +13532,8 @@
 	 */
 	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5780 ||
 	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5714) {
-		tp->tg3_flags2 |= TG3_FLG2_5780_CLASS;
-		tp->tg3_flags |= TG3_FLAG_40BIT_DMA_BUG;
+		tg3_flag_set(tp, 5780_CLASS);
+		tg3_flag_set(tp, 40BIT_DMA_BUG);
 		tp->msi_cap = pci_find_capability(tp->pdev, PCI_CAP_ID_MSI);
 	} else {
 		struct pci_dev *bridge = NULL;
@@ -13312,7 +13547,7 @@
 			     tp->pdev->bus->number) &&
 			    (bridge->subordinate->subordinate >=
 			     tp->pdev->bus->number)) {
-				tp->tg3_flags |= TG3_FLAG_40BIT_DMA_BUG;
+				tg3_flag_set(tp, 40BIT_DMA_BUG);
 				pci_dev_put(bridge);
 				break;
 			}
@@ -13327,13 +13562,18 @@
 
 	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704 ||
 	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5714 ||
-	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717)
+	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 ||
+	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5720)
 		tp->pdev_peer = tg3_find_peer(tp);
 
 	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 ||
 	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719 ||
-	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765)
-		tp->tg3_flags3 |= TG3_FLG3_5717_PLUS;
+	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5720)
+		tg3_flag_set(tp, 5717_PLUS);
+
+	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57765 ||
+	    tg3_flag(tp, 5717_PLUS))
+		tg3_flag_set(tp, 57765_PLUS);
 
 	/* Intentionally exclude ASIC_REV_5906 */
 	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755 ||
@@ -13342,97 +13582,102 @@
 	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761 ||
 	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5785 ||
 	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780 ||
-	    (tp->tg3_flags3 & TG3_FLG3_5717_PLUS))
-		tp->tg3_flags3 |= TG3_FLG3_5755_PLUS;
+	    tg3_flag(tp, 57765_PLUS))
+		tg3_flag_set(tp, 5755_PLUS);
 
 	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5750 ||
 	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5752 ||
 	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906 ||
-	    (tp->tg3_flags3 & TG3_FLG3_5755_PLUS) ||
-	    (tp->tg3_flags2 & TG3_FLG2_5780_CLASS))
-		tp->tg3_flags2 |= TG3_FLG2_5750_PLUS;
-
-	if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705) ||
-	    (tp->tg3_flags2 & TG3_FLG2_5750_PLUS))
-		tp->tg3_flags2 |= TG3_FLG2_5705_PLUS;
-
-	/* 5700 B0 chips do not support checksumming correctly due
-	 * to hardware bugs.
-	 */
-	if (tp->pci_chip_rev_id == CHIPREV_ID_5700_B0)
-		tp->tg3_flags |= TG3_FLAG_BROKEN_CHECKSUMS;
-	else {
-		unsigned long features = NETIF_F_IP_CSUM | NETIF_F_SG | NETIF_F_GRO;
+	    tg3_flag(tp, 5755_PLUS) ||
+	    tg3_flag(tp, 5780_CLASS))
+		tg3_flag_set(tp, 5750_PLUS);
 
-		tp->tg3_flags |= TG3_FLAG_RX_CHECKSUMS;
-		if (tp->tg3_flags3 & TG3_FLG3_5755_PLUS)
-			features |= NETIF_F_IPV6_CSUM;
-		tp->dev->features |= features;
-		vlan_features_add(tp->dev, features);
-	}
+	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705 ||
+	    tg3_flag(tp, 5750_PLUS))
+		tg3_flag_set(tp, 5705_PLUS);
 
 	/* Determine TSO capabilities */
 	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719)
 		; /* Do nothing. HW bug. */
-	else if (tp->tg3_flags3 & TG3_FLG3_5717_PLUS)
-		tp->tg3_flags2 |= TG3_FLG2_HW_TSO_3;
-	else if ((tp->tg3_flags3 & TG3_FLG3_5755_PLUS) ||
+	else if (tg3_flag(tp, 57765_PLUS))
+		tg3_flag_set(tp, HW_TSO_3);
+	else if (tg3_flag(tp, 5755_PLUS) ||
 		 GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906)
-		tp->tg3_flags2 |= TG3_FLG2_HW_TSO_2;
-	else if (tp->tg3_flags2 & TG3_FLG2_5750_PLUS) {
-		tp->tg3_flags2 |= TG3_FLG2_HW_TSO_1 | TG3_FLG2_TSO_BUG;
+		tg3_flag_set(tp, HW_TSO_2);
+	else if (tg3_flag(tp, 5750_PLUS)) {
+		tg3_flag_set(tp, HW_TSO_1);
+		tg3_flag_set(tp, TSO_BUG);
 		if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5750 &&
 		    tp->pci_chip_rev_id >= CHIPREV_ID_5750_C2)
-			tp->tg3_flags2 &= ~TG3_FLG2_TSO_BUG;
+			tg3_flag_clear(tp, TSO_BUG);
 	} else if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5700 &&
 		   GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5701 &&
 		   tp->pci_chip_rev_id != CHIPREV_ID_5705_A0) {
-		tp->tg3_flags2 |= TG3_FLG2_TSO_BUG;
+			tg3_flag_set(tp, TSO_BUG);
 		if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705)
 			tp->fw_needed = FIRMWARE_TG3TSO5;
 		else
 			tp->fw_needed = FIRMWARE_TG3TSO;
 	}
 
+	/* Selectively allow TSO based on operating conditions */
+	if (tg3_flag(tp, HW_TSO_1) ||
+	    tg3_flag(tp, HW_TSO_2) ||
+	    tg3_flag(tp, HW_TSO_3) ||
+	    (tp->fw_needed && !tg3_flag(tp, ENABLE_ASF)))
+		tg3_flag_set(tp, TSO_CAPABLE);
+	else {
+		tg3_flag_clear(tp, TSO_CAPABLE);
+		tg3_flag_clear(tp, TSO_BUG);
+		tp->fw_needed = NULL;
+	}
+
+	if (tp->pci_chip_rev_id == CHIPREV_ID_5701_A0)
+		tp->fw_needed = FIRMWARE_TG3;
+
 	tp->irq_max = 1;
 
-	if (tp->tg3_flags2 & TG3_FLG2_5750_PLUS) {
-		tp->tg3_flags |= TG3_FLAG_SUPPORT_MSI;
+	if (tg3_flag(tp, 5750_PLUS)) {
+		tg3_flag_set(tp, SUPPORT_MSI);
 		if (GET_CHIP_REV(tp->pci_chip_rev_id) == CHIPREV_5750_AX ||
 		    GET_CHIP_REV(tp->pci_chip_rev_id) == CHIPREV_5750_BX ||
 		    (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5714 &&
 		     tp->pci_chip_rev_id <= CHIPREV_ID_5714_A2 &&
 		     tp->pdev_peer == tp->pdev))
-			tp->tg3_flags &= ~TG3_FLAG_SUPPORT_MSI;
+			tg3_flag_clear(tp, SUPPORT_MSI);
 
-		if ((tp->tg3_flags3 & TG3_FLG3_5755_PLUS) ||
+		if (tg3_flag(tp, 5755_PLUS) ||
 		    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) {
-			tp->tg3_flags2 |= TG3_FLG2_1SHOT_MSI;
+			tg3_flag_set(tp, 1SHOT_MSI);
 		}
 
-		if (tp->tg3_flags3 & TG3_FLG3_5717_PLUS) {
-			tp->tg3_flags |= TG3_FLAG_SUPPORT_MSIX;
+		if (tg3_flag(tp, 57765_PLUS)) {
+			tg3_flag_set(tp, SUPPORT_MSIX);
 			tp->irq_max = TG3_IRQ_MAX_VECS;
 		}
 	}
 
-	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 ||
-	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719 ||
-	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906)
-		tp->tg3_flags3 |= TG3_FLG3_SHORT_DMA_BUG;
-	else if (!(tp->tg3_flags3 & TG3_FLG3_5755_PLUS)) {
-		tp->tg3_flags3 |= TG3_FLG3_4G_DMA_BNDRY_BUG;
-		tp->tg3_flags3 |= TG3_FLG3_40BIT_DMA_LIMIT_BUG;
-	}
+	/* All chips can get confused if TX buffers
+	 * straddle the 4GB address boundary.
+	 */
+	tg3_flag_set(tp, 4G_DMA_BNDRY_BUG);
 
-	if ((tp->tg3_flags3 & TG3_FLG3_5717_PLUS) &&
+	if (tg3_flag(tp, 5755_PLUS))
+		tg3_flag_set(tp, SHORT_DMA_BUG);
+	else
+		tg3_flag_set(tp, 40BIT_DMA_LIMIT_BUG);
+
+	if (tg3_flag(tp, 5717_PLUS))
+		tg3_flag_set(tp, LRG_PROD_RING_CAP);
+
+	if (tg3_flag(tp, 57765_PLUS) &&
 	    GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5719)
-		tp->tg3_flags3 |= TG3_FLG3_USE_JUMBO_BDFLAG;
+		tg3_flag_set(tp, USE_JUMBO_BDFLAG);
 
-	if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS) ||
-	    (tp->tg3_flags2 & TG3_FLG2_5780_CLASS) ||
-	    (tp->tg3_flags3 & TG3_FLG3_USE_JUMBO_BDFLAG))
-		tp->tg3_flags |= TG3_FLAG_JUMBO_CAPABLE;
+	if (!tg3_flag(tp, 5705_PLUS) ||
+	    tg3_flag(tp, 5780_CLASS) ||
+	    tg3_flag(tp, USE_JUMBO_BDFLAG))
+		tg3_flag_set(tp, JUMBO_CAPABLE);
 
 	pci_read_config_dword(tp->pdev, TG3PCI_PCISTATE,
 			      &pci_state_reg);
@@ -13441,10 +13686,11 @@
 	if (tp->pcie_cap != 0) {
 		u16 lnkctl;
 
-		tp->tg3_flags2 |= TG3_FLG2_PCI_EXPRESS;
+		tg3_flag_set(tp, PCI_EXPRESS);
 
 		tp->pcie_readrq = 4096;
-		if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719)
+		if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719 ||
+		    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5720)
 			tp->pcie_readrq = 2048;
 
 		pcie_set_readrq(tp->pdev, tp->pcie_readrq);
@@ -13453,20 +13699,23 @@
 				     tp->pcie_cap + PCI_EXP_LNKCTL,
 				     &lnkctl);
 		if (lnkctl & PCI_EXP_LNKCTL_CLKREQ_EN) {
-			if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906)
-				tp->tg3_flags2 &= ~TG3_FLG2_HW_TSO_2;
+			if (GET_ASIC_REV(tp->pci_chip_rev_id) ==
+			    ASIC_REV_5906) {
+				tg3_flag_clear(tp, HW_TSO_2);
+				tg3_flag_clear(tp, TSO_CAPABLE);
+			}
 			if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5784 ||
 			    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761 ||
 			    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;
+				tg3_flag_set(tp, CLKREQ_BUG);
 		} else if (tp->pci_chip_rev_id == CHIPREV_ID_5717_A0) {
-			tp->tg3_flags3 |= TG3_FLG3_L1PLLPD_EN;
+			tg3_flag_set(tp, L1PLLPD_EN);
 		}
 	} else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5785) {
-		tp->tg3_flags2 |= TG3_FLG2_PCI_EXPRESS;
-	} else if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS) ||
-		   (tp->tg3_flags2 & TG3_FLG2_5780_CLASS)) {
+		tg3_flag_set(tp, PCI_EXPRESS);
+	} else if (!tg3_flag(tp, 5705_PLUS) ||
+		   tg3_flag(tp, 5780_CLASS)) {
 		tp->pcix_cap = pci_find_capability(tp->pdev, PCI_CAP_ID_PCIX);
 		if (!tp->pcix_cap) {
 			dev_err(&tp->pdev->dev,
@@ -13475,7 +13724,7 @@
 		}
 
 		if (!(pci_state_reg & PCISTATE_CONV_PCI_MODE))
-			tp->tg3_flags |= TG3_FLAG_PCIX_MODE;
+			tg3_flag_set(tp, PCIX_MODE);
 	}
 
 	/* If we have an AMD 762 or VIA K8T800 chipset, write
@@ -13485,8 +13734,8 @@
 	 * posted to the chip in order.
 	 */
 	if (pci_dev_present(tg3_write_reorder_chipsets) &&
-	    !(tp->tg3_flags2 & TG3_FLG2_PCI_EXPRESS))
-		tp->tg3_flags |= TG3_FLAG_MBOX_WRITE_REORDER;
+	    !tg3_flag(tp, PCI_EXPRESS))
+		tg3_flag_set(tp, MBOX_WRITE_REORDER);
 
 	pci_read_config_byte(tp->pdev, PCI_CACHE_LINE_SIZE,
 			     &tp->pci_cacheline_sz);
@@ -13503,17 +13752,17 @@
 		/* 5700 BX chips need to have their TX producer index
 		 * mailboxes written twice to workaround a bug.
 		 */
-		tp->tg3_flags |= TG3_FLAG_TXD_MBOX_HWBUG;
+		tg3_flag_set(tp, TXD_MBOX_HWBUG);
 
 		/* If we are in PCI-X mode, enable register write workaround.
 		 *
 		 * The workaround is to use indirect register accesses
 		 * for all chip writes not to mailbox registers.
 		 */
-		if (tp->tg3_flags & TG3_FLAG_PCIX_MODE) {
+		if (tg3_flag(tp, PCIX_MODE)) {
 			u32 pm_reg;
 
-			tp->tg3_flags |= TG3_FLAG_PCIX_TARGET_HWBUG;
+			tg3_flag_set(tp, PCIX_TARGET_HWBUG);
 
 			/* The chip can have it's power management PCI config
 			 * space registers clobbered due to this bug.
@@ -13536,9 +13785,9 @@
 	}
 
 	if ((pci_state_reg & PCISTATE_BUS_SPEED_HIGH) != 0)
-		tp->tg3_flags |= TG3_FLAG_PCI_HIGH_SPEED;
+		tg3_flag_set(tp, PCI_HIGH_SPEED);
 	if ((pci_state_reg & PCISTATE_BUS_32BIT) != 0)
-		tp->tg3_flags |= TG3_FLAG_PCI_32BIT;
+		tg3_flag_set(tp, PCI_32BIT);
 
 	/* Chip-specific fixup from Broadcom driver */
 	if ((tp->pci_chip_rev_id == CHIPREV_ID_5704_A0) &&
@@ -13556,10 +13805,10 @@
 	tp->write32_rx_mbox = tg3_write32;
 
 	/* Various workaround register access methods */
-	if (tp->tg3_flags & TG3_FLAG_PCIX_TARGET_HWBUG)
+	if (tg3_flag(tp, PCIX_TARGET_HWBUG))
 		tp->write32 = tg3_write_indirect_reg32;
 	else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5701 ||
-		 ((tp->tg3_flags2 & TG3_FLG2_PCI_EXPRESS) &&
+		 (tg3_flag(tp, PCI_EXPRESS) &&
 		  tp->pci_chip_rev_id == CHIPREV_ID_5750_A0)) {
 		/*
 		 * Back to back register writes can cause problems on these
@@ -13571,14 +13820,13 @@
 		tp->write32 = tg3_write_flush_reg32;
 	}
 
-	if ((tp->tg3_flags & TG3_FLAG_TXD_MBOX_HWBUG) ||
-	    (tp->tg3_flags & TG3_FLAG_MBOX_WRITE_REORDER)) {
+	if (tg3_flag(tp, TXD_MBOX_HWBUG) || tg3_flag(tp, MBOX_WRITE_REORDER)) {
 		tp->write32_tx_mbox = tg3_write32_tx_mbox;
-		if (tp->tg3_flags & TG3_FLAG_MBOX_WRITE_REORDER)
+		if (tg3_flag(tp, MBOX_WRITE_REORDER))
 			tp->write32_rx_mbox = tg3_write_flush_reg32;
 	}
 
-	if (tp->tg3_flags2 & TG3_FLG2_ICH_WORKAROUND) {
+	if (tg3_flag(tp, ICH_WORKAROUND)) {
 		tp->read32 = tg3_read_indirect_reg32;
 		tp->write32 = tg3_write_indirect_reg32;
 		tp->read32_mbox = tg3_read_indirect_mbox;
@@ -13601,13 +13849,13 @@
 	}
 
 	if (tp->write32 == tg3_write_indirect_reg32 ||
-	    ((tp->tg3_flags & TG3_FLAG_PCIX_MODE) &&
+	    (tg3_flag(tp, PCIX_MODE) &&
 	     (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700 ||
 	      GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5701)))
-		tp->tg3_flags |= TG3_FLAG_SRAM_USE_CONFIG;
+		tg3_flag_set(tp, SRAM_USE_CONFIG);
 
 	/* Get eeprom hw config before calling tg3_set_power_state().
-	 * In particular, the TG3_FLG2_IS_NIC flag must be
+	 * In particular, the TG3_FLAG_IS_NIC flag must be
 	 * determined before calling tg3_set_power_state() so that
 	 * we know whether or not to switch out of Vaux power.
 	 * When the flag is set, it means that GPIO1 is used for eeprom
@@ -13616,7 +13864,7 @@
 	 */
 	tg3_get_eeprom_hw_cfg(tp);
 
-	if (tp->tg3_flags3 & TG3_FLG3_ENABLE_APE) {
+	if (tg3_flag(tp, ENABLE_APE)) {
 		/* Allow reads and writes to the
 		 * APE register and memory space.
 		 */
@@ -13631,16 +13879,16 @@
 	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761 ||
 	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5785 ||
 	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780 ||
-	    (tp->tg3_flags3 & TG3_FLG3_5717_PLUS))
-		tp->tg3_flags |= TG3_FLAG_CPMU_PRESENT;
+	    tg3_flag(tp, 57765_PLUS))
+		tg3_flag_set(tp, CPMU_PRESENT);
 
-	/* Set up tp->grc_local_ctrl before calling tg_power_up().
+	/* Set up tp->grc_local_ctrl before calling tg3_power_up().
 	 * GPIO1 driven high will bring 5700's external PHY out of reset.
 	 * It is also used as eeprom write protect on LOMs.
 	 */
 	tp->grc_local_ctrl = GRC_LCLCTRL_INT_ON_ATTN | GRC_LCLCTRL_AUTO_SEEPROM;
-	if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700) ||
-	    (tp->tg3_flags & TG3_FLAG_EEPROM_WRITE_PROT))
+	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700 ||
+	    tg3_flag(tp, EEPROM_WRITE_PROT))
 		tp->grc_local_ctrl |= (GRC_LCLCTRL_GPIO_OE1 |
 				       GRC_LCLCTRL_GPIO_OUTPUT1);
 	/* Unused GPIO3 must be driven as output on 5752 because there
@@ -13658,7 +13906,7 @@
 	    tp->pdev->device == TG3PCI_DEVICE_TIGON3_5761S) {
 		/* Turn off the debug UART. */
 		tp->grc_local_ctrl |= GRC_LCLCTRL_GPIO_UART_SEL;
-		if (tp->tg3_flags2 & TG3_FLG2_IS_NIC)
+		if (tg3_flag(tp, IS_NIC))
 			/* Keep VMain power. */
 			tp->grc_local_ctrl |= GRC_LCLCTRL_GPIO_OE0 |
 					      GRC_LCLCTRL_GPIO_OUTPUT0;
@@ -13674,26 +13922,25 @@
 	/* Derive initial jumbo mode from MTU assigned in
 	 * ether_setup() via the alloc_etherdev() call
 	 */
-	if (tp->dev->mtu > ETH_DATA_LEN &&
-	    !(tp->tg3_flags2 & TG3_FLG2_5780_CLASS))
-		tp->tg3_flags |= TG3_FLAG_JUMBO_RING_ENABLE;
+	if (tp->dev->mtu > ETH_DATA_LEN && !tg3_flag(tp, 5780_CLASS))
+		tg3_flag_set(tp, JUMBO_RING_ENABLE);
 
 	/* Determine WakeOnLan speed to use. */
 	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700 ||
 	    tp->pci_chip_rev_id == CHIPREV_ID_5701_A0 ||
 	    tp->pci_chip_rev_id == CHIPREV_ID_5701_B0 ||
 	    tp->pci_chip_rev_id == CHIPREV_ID_5701_B2) {
-		tp->tg3_flags &= ~(TG3_FLAG_WOL_SPEED_100MB);
+		tg3_flag_clear(tp, WOL_SPEED_100MB);
 	} else {
-		tp->tg3_flags |= TG3_FLAG_WOL_SPEED_100MB;
+		tg3_flag_set(tp, WOL_SPEED_100MB);
 	}
 
 	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906)
 		tp->phy_flags |= TG3_PHYFLG_IS_FET;
 
 	/* A few boards don't want Ethernet@WireSpeed phy feature */
-	if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700) ||
-	    ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705) &&
+	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700 ||
+	    (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705 &&
 	     (tp->pci_chip_rev_id != CHIPREV_ID_5705_A0) &&
 	     (tp->pci_chip_rev_id != CHIPREV_ID_5705_A1)) ||
 	    (tp->phy_flags & TG3_PHYFLG_IS_FET) ||
@@ -13706,11 +13953,11 @@
 	if (tp->pci_chip_rev_id == CHIPREV_ID_5704_A0)
 		tp->phy_flags |= TG3_PHYFLG_5704_A0_BUG;
 
-	if ((tp->tg3_flags2 & TG3_FLG2_5705_PLUS) &&
+	if (tg3_flag(tp, 5705_PLUS) &&
 	    !(tp->phy_flags & TG3_PHYFLG_IS_FET) &&
 	    GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5785 &&
 	    GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_57780 &&
-	    !(tp->tg3_flags3 & TG3_FLG3_5717_PLUS)) {
+	    !tg3_flag(tp, 57765_PLUS)) {
 		if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755 ||
 		    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5787 ||
 		    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5784 ||
@@ -13731,7 +13978,7 @@
 			tp->phy_otp = TG3_OTP_DEFAULT;
 	}
 
-	if (tp->tg3_flags & TG3_FLAG_CPMU_PRESENT)
+	if (tg3_flag(tp, CPMU_PRESENT))
 		tp->mi_mode = MAC_MI_MODE_500KHZ_CONST;
 	else
 		tp->mi_mode = MAC_MI_MODE_BASE;
@@ -13741,9 +13988,17 @@
 	    GET_CHIP_REV(tp->pci_chip_rev_id) != CHIPREV_5700_BX)
 		tp->coalesce_mode |= HOSTCC_MODE_32BYTE;
 
+	/* Set these bits to enable statistics workaround. */
+	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 ||
+	    tp->pci_chip_rev_id == CHIPREV_ID_5719_A0 ||
+	    tp->pci_chip_rev_id == CHIPREV_ID_5720_A0) {
+		tp->coalesce_mode |= HOSTCC_MODE_ATTN;
+		tp->grc_mode |= GRC_MODE_IRQ_ON_FLOW_ATTN;
+	}
+
 	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5785 ||
 	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780)
-		tp->tg3_flags3 |= TG3_FLG3_USE_PHYLIB;
+		tg3_flag_set(tp, USE_PHYLIB);
 
 	err = tg3_mdio_init(tp);
 	if (err)
@@ -13751,7 +14006,15 @@
 
 	/* Initialize data/descriptor byte/word swapping. */
 	val = tr32(GRC_MODE);
-	val &= GRC_MODE_HOST_STACKUP;
+	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5720)
+		val &= (GRC_MODE_BYTE_SWAP_B2HRX_DATA |
+			GRC_MODE_WORD_SWAP_B2HRX_DATA |
+			GRC_MODE_B2HRX_ENABLE |
+			GRC_MODE_HTX2B_ENABLE |
+			GRC_MODE_HOST_STACKUP);
+	else
+		val &= GRC_MODE_HOST_STACKUP;
+
 	tw32(GRC_MODE, val | tp->grc_mode);
 
 	tg3_switch_clocks(tp);
@@ -13762,7 +14025,7 @@
 	pci_read_config_dword(tp->pdev, TG3PCI_PCISTATE,
 			      &pci_state_reg);
 	if ((pci_state_reg & PCISTATE_CONV_PCI_MODE) == 0 &&
-	    (tp->tg3_flags & TG3_FLAG_PCIX_TARGET_HWBUG) == 0) {
+	    !tg3_flag(tp, PCIX_TARGET_HWBUG)) {
 		u32 chiprevid = GET_CHIP_REV_ID(tp->misc_host_ctrl);
 
 		if (chiprevid == CHIPREV_ID_5701_A0 ||
@@ -13781,7 +14044,7 @@
 			writel(0x00000000, sram_base + 4);
 			writel(0xffffffff, sram_base + 4);
 			if (readl(sram_base) != 0x00000000)
-				tp->tg3_flags |= TG3_FLAG_PCIX_TARGET_HWBUG;
+				tg3_flag_set(tp, PCIX_TARGET_HWBUG);
 		}
 	}
 
@@ -13794,12 +14057,12 @@
 	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705 &&
 	    (grc_misc_cfg == GRC_MISC_CFG_BOARD_ID_5788 ||
 	     grc_misc_cfg == GRC_MISC_CFG_BOARD_ID_5788M))
-		tp->tg3_flags2 |= TG3_FLG2_IS_5788;
+		tg3_flag_set(tp, IS_5788);
 
-	if (!(tp->tg3_flags2 & TG3_FLG2_IS_5788) &&
-	    (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5700))
-		tp->tg3_flags |= TG3_FLAG_TAGGED_STATUS;
-	if (tp->tg3_flags & TG3_FLAG_TAGGED_STATUS) {
+	if (!tg3_flag(tp, IS_5788) &&
+	    GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5700)
+		tg3_flag_set(tp, TAGGED_STATUS);
+	if (tg3_flag(tp, TAGGED_STATUS)) {
 		tp->coalesce_mode |= (HOSTCC_MODE_CLRTICK_RXBD |
 				      HOSTCC_MODE_CLRTICK_TXBD);
 
@@ -13809,7 +14072,7 @@
 	}
 
 	/* Preserve the APE MAC_MODE bits */
-	if (tp->tg3_flags3 & TG3_FLG3_ENABLE_APE)
+	if (tg3_flag(tp, ENABLE_APE))
 		tp->mac_mode = MAC_MODE_APE_TX_EN | MAC_MODE_APE_RX_EN;
 	else
 		tp->mac_mode = TG3_DEF_MAC_MODE;
@@ -13856,9 +14119,9 @@
 	 * status register in those cases.
 	 */
 	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700)
-		tp->tg3_flags |= TG3_FLAG_USE_LINKCHG_REG;
+		tg3_flag_set(tp, USE_LINKCHG_REG);
 	else
-		tp->tg3_flags &= ~TG3_FLAG_USE_LINKCHG_REG;
+		tg3_flag_clear(tp, USE_LINKCHG_REG);
 
 	/* The led_ctrl is set during tg3_phy_probe, here we might
 	 * have to force the link status polling mechanism based
@@ -13868,19 +14131,19 @@
 	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5701 &&
 	    !(tp->phy_flags & TG3_PHYFLG_PHY_SERDES)) {
 		tp->phy_flags |= TG3_PHYFLG_USE_MI_INTERRUPT;
-		tp->tg3_flags |= TG3_FLAG_USE_LINKCHG_REG;
+		tg3_flag_set(tp, USE_LINKCHG_REG);
 	}
 
 	/* For all SERDES we poll the MAC status register. */
 	if (tp->phy_flags & TG3_PHYFLG_PHY_SERDES)
-		tp->tg3_flags |= TG3_FLAG_POLL_SERDES;
+		tg3_flag_set(tp, POLL_SERDES);
 	else
-		tp->tg3_flags &= ~TG3_FLAG_POLL_SERDES;
+		tg3_flag_clear(tp, POLL_SERDES);
 
 	tp->rx_offset = NET_IP_ALIGN;
 	tp->rx_copy_thresh = TG3_RX_COPY_THRESHOLD;
 	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5701 &&
-	    (tp->tg3_flags & TG3_FLAG_PCIX_MODE) != 0) {
+	    tg3_flag(tp, PCIX_MODE)) {
 		tp->rx_offset = 0;
 #ifndef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS
 		tp->rx_copy_thresh = ~(u16)0;
@@ -13901,7 +14164,7 @@
 	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755)
 		tp->rx_std_max_post = 8;
 
-	if (tp->tg3_flags & TG3_FLAG_ASPM_WORKAROUND)
+	if (tg3_flag(tp, ASPM_WORKAROUND))
 		tp->pwrmgmt_thresh = tr32(PCIE_PWR_MGMT_THRESH) &
 				     PCIE_PWR_MGMT_L1_THRESH_MSK;
 
@@ -13948,16 +14211,15 @@
 #endif
 
 	mac_offset = 0x7c;
-	if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704) ||
-	    (tp->tg3_flags2 & TG3_FLG2_5780_CLASS)) {
+	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704 ||
+	    tg3_flag(tp, 5780_CLASS)) {
 		if (tr32(TG3PCI_DUAL_MAC_CTRL) & DUAL_MAC_CTRL_ID)
 			mac_offset = 0xcc;
 		if (tg3_nvram_lock(tp))
 			tw32_f(NVRAM_CMD, NVRAM_CMD_RESET);
 		else
 			tg3_nvram_unlock(tp);
-	} else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717 ||
-		   GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719) {
+	} else if (tg3_flag(tp, 5717_PLUS)) {
 		if (PCI_FUNC(tp->pdev->devfn) & 1)
 			mac_offset = 0xcc;
 		if (PCI_FUNC(tp->pdev->devfn) > 1)
@@ -13982,7 +14244,7 @@
 	}
 	if (!addr_ok) {
 		/* Next, try NVRAM. */
-		if (!(tp->tg3_flags3 & TG3_FLG3_NO_NVRAM) &&
+		if (!tg3_flag(tp, NO_NVRAM) &&
 		    !tg3_nvram_read_be32(tp, mac_offset + 0, &hi) &&
 		    !tg3_nvram_read_be32(tp, mac_offset + 4, &lo)) {
 			memcpy(&dev->dev_addr[0], ((char *)&hi) + 2, 2);
@@ -14033,7 +14295,7 @@
 	 */
 	if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5700 &&
 	    GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5701 &&
-	    !(tp->tg3_flags2 & TG3_FLG2_PCI_EXPRESS))
+	    !tg3_flag(tp, PCI_EXPRESS))
 		goto out;
 
 #if defined(CONFIG_PPC64) || defined(CONFIG_IA64) || defined(CONFIG_PARISC)
@@ -14046,7 +14308,7 @@
 #endif
 #endif
 
-	if (tp->tg3_flags3 & TG3_FLG3_5717_PLUS) {
+	if (tg3_flag(tp, 57765_PLUS)) {
 		val = goal ? 0 : DMA_RWCTRL_DIS_CACHE_ALIGNMENT;
 		goto out;
 	}
@@ -14065,8 +14327,7 @@
 	 * other than 5700 and 5701 which do not implement the
 	 * boundary bits.
 	 */
-	if ((tp->tg3_flags & TG3_FLAG_PCIX_MODE) &&
-	    !(tp->tg3_flags2 & TG3_FLG2_PCI_EXPRESS)) {
+	if (tg3_flag(tp, PCIX_MODE) && !tg3_flag(tp, PCI_EXPRESS)) {
 		switch (cacheline_size) {
 		case 16:
 		case 32:
@@ -14091,7 +14352,7 @@
 				DMA_RWCTRL_WRITE_BNDRY_384_PCIX);
 			break;
 		}
-	} else if (tp->tg3_flags2 & TG3_FLG2_PCI_EXPRESS) {
+	} else if (tg3_flag(tp, PCI_EXPRESS)) {
 		switch (cacheline_size) {
 		case 16:
 		case 32:
@@ -14263,13 +14524,13 @@
 
 	tp->dma_rwctrl = tg3_calc_dma_bndry(tp, tp->dma_rwctrl);
 
-	if (tp->tg3_flags3 & TG3_FLG3_5717_PLUS)
+	if (tg3_flag(tp, 57765_PLUS))
 		goto out;
 
-	if (tp->tg3_flags2 & TG3_FLG2_PCI_EXPRESS) {
+	if (tg3_flag(tp, PCI_EXPRESS)) {
 		/* DMA read watermark not used on PCIE */
 		tp->dma_rwctrl |= 0x00180000;
-	} else if (!(tp->tg3_flags & TG3_FLAG_PCIX_MODE)) {
+	} else if (!tg3_flag(tp, PCIX_MODE)) {
 		if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705 ||
 		    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5750)
 			tp->dma_rwctrl |= 0x003f0000;
@@ -14285,7 +14546,7 @@
 			 * do the less restrictive ONE_DMA workaround for
 			 * better performance.
 			 */
-			if ((tp->tg3_flags & TG3_FLAG_40BIT_DMA_BUG) &&
+			if (tg3_flag(tp, 40BIT_DMA_BUG) &&
 			    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704)
 				tp->dma_rwctrl |= 0x8000;
 			else if (ccval == 0x6 || ccval == 0x7)
@@ -14414,7 +14675,6 @@
 	}
 	if ((tp->dma_rwctrl & DMA_RWCTRL_WRITE_BNDRY_MASK) !=
 	    DMA_RWCTRL_WRITE_BNDRY_16) {
-
 		/* DMA test passed without adjusting DMA boundary,
 		 * now look for chipsets that are known to expose the
 		 * DMA bug without failing the test.
@@ -14438,7 +14698,7 @@
 
 static void __devinit tg3_init_bufmgr_config(struct tg3 *tp)
 {
-	if (tp->tg3_flags3 & TG3_FLG3_5717_PLUS) {
+	if (tg3_flag(tp, 57765_PLUS)) {
 		tp->bufmgr_config.mbuf_read_dma_low_water =
 			DEFAULT_MB_RDMA_LOW_WATER_5705;
 		tp->bufmgr_config.mbuf_mac_rx_low_water =
@@ -14452,7 +14712,7 @@
 			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) {
+	} else if (tg3_flag(tp, 5705_PLUS)) {
 		tp->bufmgr_config.mbuf_read_dma_low_water =
 			DEFAULT_MB_RDMA_LOW_WATER_5705;
 		tp->bufmgr_config.mbuf_mac_rx_low_water =
@@ -14516,6 +14776,7 @@
 	case TG3_PHY_ID_BCM5718S:	return "5718S";
 	case TG3_PHY_ID_BCM57765:	return "57765";
 	case TG3_PHY_ID_BCM5719C:	return "5719C";
+	case TG3_PHY_ID_BCM5720C:	return "5720C";
 	case TG3_PHY_ID_BCM8002:	return "8002/serdes";
 	case 0:			return "serdes";
 	default:		return "unknown";
@@ -14524,10 +14785,10 @@
 
 static char * __devinit tg3_bus_string(struct tg3 *tp, char *str)
 {
-	if (tp->tg3_flags2 & TG3_FLG2_PCI_EXPRESS) {
+	if (tg3_flag(tp, PCI_EXPRESS)) {
 		strcpy(str, "PCI Express");
 		return str;
-	} else if (tp->tg3_flags & TG3_FLAG_PCIX_MODE) {
+	} else if (tg3_flag(tp, PCIX_MODE)) {
 		u32 clock_ctrl = tr32(TG3PCI_CLOCK_CTRL) & 0x1f;
 
 		strcpy(str, "PCIX:");
@@ -14546,12 +14807,12 @@
 			strcat(str, "100MHz");
 	} else {
 		strcpy(str, "PCI:");
-		if (tp->tg3_flags & TG3_FLAG_PCI_HIGH_SPEED)
+		if (tg3_flag(tp, PCI_HIGH_SPEED))
 			strcat(str, "66MHz");
 		else
 			strcat(str, "33MHz");
 	}
-	if (tp->tg3_flags & TG3_FLAG_PCI_32BIT)
+	if (tg3_flag(tp, PCI_32BIT))
 		strcat(str, ":32-bit");
 	else
 		strcat(str, ":64-bit");
@@ -14610,7 +14871,7 @@
 		ec->tx_coalesce_usecs_irq = DEFAULT_TXCOAL_TICK_INT_CLRTCKS;
 	}
 
-	if (tp->tg3_flags2 & TG3_FLG2_5705_PLUS) {
+	if (tg3_flag(tp, 5705_PLUS)) {
 		ec->rx_coalesce_usecs_irq = 0;
 		ec->tx_coalesce_usecs_irq = 0;
 		ec->stats_block_coalesce_usecs = 0;
@@ -14628,22 +14889,8 @@
 	.ndo_do_ioctl		= tg3_ioctl,
 	.ndo_tx_timeout		= tg3_tx_timeout,
 	.ndo_change_mtu		= tg3_change_mtu,
-#ifdef CONFIG_NET_POLL_CONTROLLER
-	.ndo_poll_controller	= tg3_poll_controller,
-#endif
-};
-
-static const struct net_device_ops tg3_netdev_ops_dma_bug = {
-	.ndo_open		= tg3_open,
-	.ndo_stop		= tg3_close,
-	.ndo_start_xmit		= tg3_start_xmit_dma_bug,
-	.ndo_get_stats64	= tg3_get_stats64,
-	.ndo_validate_addr	= eth_validate_addr,
-	.ndo_set_multicast_list	= tg3_set_rx_mode,
-	.ndo_set_mac_address	= tg3_set_mac_addr,
-	.ndo_do_ioctl		= tg3_ioctl,
-	.ndo_tx_timeout		= tg3_tx_timeout,
-	.ndo_change_mtu		= tg3_change_mtu,
+	.ndo_fix_features	= tg3_fix_features,
+	.ndo_set_features	= tg3_set_features,
 #ifdef CONFIG_NET_POLL_CONTROLLER
 	.ndo_poll_controller	= tg3_poll_controller,
 #endif
@@ -14658,6 +14905,7 @@
 	u32 sndmbx, rcvmbx, intmbx;
 	char str[40];
 	u64 dma_mask, persist_dma_mask;
+	u32 features = 0;
 
 	printk_once(KERN_INFO "%s\n", version);
 
@@ -14693,8 +14941,6 @@
 
 	SET_NETDEV_DEV(dev, &pdev->dev);
 
-	dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
-
 	tp = netdev_priv(dev);
 	tp->pdev = pdev;
 	tp->dev = dev;
@@ -14744,6 +14990,7 @@
 
 	dev->ethtool_ops = &tg3_ethtool_ops;
 	dev->watchdog_timeo = TG3_TX_TIMEOUT;
+	dev->netdev_ops = &tg3_netdev_ops;
 	dev->irq = pdev->irq;
 
 	err = tg3_get_invariants(tp);
@@ -14753,23 +15000,15 @@
 		goto err_out_iounmap;
 	}
 
-	if ((tp->tg3_flags3 & TG3_FLG3_5755_PLUS) &&
-	    GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5717 &&
-	    GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5719)
-		dev->netdev_ops = &tg3_netdev_ops;
-	else
-		dev->netdev_ops = &tg3_netdev_ops_dma_bug;
-
-
 	/* The EPB bridge inside 5714, 5715, and 5780 and any
 	 * device behind the EPB cannot support DMA addresses > 40-bit.
 	 * On 64-bit systems with IOMMU, use 40-bit dma_mask.
 	 * On 64-bit systems without IOMMU, use 64-bit dma_mask and
 	 * do DMA address check in tg3_start_xmit().
 	 */
-	if (tp->tg3_flags2 & TG3_FLG2_IS_5788)
+	if (tg3_flag(tp, IS_5788))
 		persist_dma_mask = dma_mask = DMA_BIT_MASK(32);
-	else if (tp->tg3_flags & TG3_FLAG_40BIT_DMA_BUG) {
+	else if (tg3_flag(tp, 40BIT_DMA_BUG)) {
 		persist_dma_mask = dma_mask = DMA_BIT_MASK(40);
 #ifdef CONFIG_HIGHMEM
 		dma_mask = DMA_BIT_MASK(64);
@@ -14781,7 +15020,7 @@
 	if (dma_mask > DMA_BIT_MASK(32)) {
 		err = pci_set_dma_mask(pdev, dma_mask);
 		if (!err) {
-			dev->features |= NETIF_F_HIGHDMA;
+			features |= NETIF_F_HIGHDMA;
 			err = pci_set_consistent_dma_mask(pdev,
 							  persist_dma_mask);
 			if (err < 0) {
@@ -14802,48 +15041,58 @@
 
 	tg3_init_bufmgr_config(tp);
 
-	/* Selectively allow TSO based on operating conditions */
-	if ((tp->tg3_flags2 & TG3_FLG2_HW_TSO) ||
-	    (tp->fw_needed && !(tp->tg3_flags & TG3_FLAG_ENABLE_ASF)))
-		tp->tg3_flags2 |= TG3_FLG2_TSO_CAPABLE;
-	else {
-		tp->tg3_flags2 &= ~(TG3_FLG2_TSO_CAPABLE | TG3_FLG2_TSO_BUG);
-		tp->fw_needed = NULL;
-	}
+	features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
 
-	if (tp->pci_chip_rev_id == CHIPREV_ID_5701_A0)
-		tp->fw_needed = FIRMWARE_TG3;
+	/* 5700 B0 chips do not support checksumming correctly due
+	 * to hardware bugs.
+	 */
+	if (tp->pci_chip_rev_id != CHIPREV_ID_5700_B0) {
+		features |= NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_RXCSUM;
+
+		if (tg3_flag(tp, 5755_PLUS))
+			features |= NETIF_F_IPV6_CSUM;
+	}
 
 	/* TSO is on by default on chips that support hardware TSO.
 	 * Firmware TSO on older chips gives lower performance, so it
 	 * is off by default, but can be enabled using ethtool.
 	 */
-	if ((tp->tg3_flags2 & TG3_FLG2_HW_TSO) &&
-	    (dev->features & NETIF_F_IP_CSUM)) {
-		dev->features |= NETIF_F_TSO;
-		vlan_features_add(dev, NETIF_F_TSO);
-	}
-	if ((tp->tg3_flags2 & TG3_FLG2_HW_TSO_2) ||
-	    (tp->tg3_flags2 & TG3_FLG2_HW_TSO_3)) {
-		if (dev->features & NETIF_F_IPV6_CSUM) {
-			dev->features |= NETIF_F_TSO6;
-			vlan_features_add(dev, NETIF_F_TSO6);
-		}
-		if ((tp->tg3_flags2 & TG3_FLG2_HW_TSO_3) ||
+	if ((tg3_flag(tp, HW_TSO_1) ||
+	     tg3_flag(tp, HW_TSO_2) ||
+	     tg3_flag(tp, HW_TSO_3)) &&
+	    (features & NETIF_F_IP_CSUM))
+		features |= NETIF_F_TSO;
+	if (tg3_flag(tp, HW_TSO_2) || tg3_flag(tp, HW_TSO_3)) {
+		if (features & NETIF_F_IPV6_CSUM)
+			features |= NETIF_F_TSO6;
+		if (tg3_flag(tp, HW_TSO_3) ||
 		    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5761 ||
 		    (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5784 &&
 		     GET_CHIP_REV(tp->pci_chip_rev_id) != CHIPREV_5784_AX) ||
-			GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5785 ||
-		    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780) {
-			dev->features |= NETIF_F_TSO_ECN;
-			vlan_features_add(dev, NETIF_F_TSO_ECN);
-		}
+		    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5785 ||
+		    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_57780)
+			features |= NETIF_F_TSO_ECN;
 	}
 
+	dev->features |= features;
+	dev->vlan_features |= features;
+
+	/*
+	 * Add loopback capability only for a subset of devices that support
+	 * MAC-LOOPBACK. Eventually this need to be enhanced to allow INT-PHY
+	 * loopback for the remaining devices.
+	 */
+	if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5780 &&
+	    !tg3_flag(tp, CPMU_PRESENT))
+		/* Add the loopback capability */
+		features |= NETIF_F_LOOPBACK;
+
+	dev->hw_features |= features;
+
 	if (tp->pci_chip_rev_id == CHIPREV_ID_5705_A1 &&
-	    !(tp->tg3_flags2 & TG3_FLG2_TSO_CAPABLE) &&
+	    !tg3_flag(tp, TSO_CAPABLE) &&
 	    !(tr32(TG3PCI_PCISTATE) & PCISTATE_BUS_SPEED_HIGH)) {
-		tp->tg3_flags2 |= TG3_FLG2_MAX_RXPEND_64;
+		tg3_flag_set(tp, MAX_RXPEND_64);
 		tp->rx_pending = 63;
 	}
 
@@ -14854,7 +15103,7 @@
 		goto err_out_iounmap;
 	}
 
-	if (tp->tg3_flags3 & TG3_FLG3_ENABLE_APE) {
+	if (tg3_flag(tp, ENABLE_APE)) {
 		tp->aperegs = pci_ioremap_bar(pdev, BAR_2);
 		if (!tp->aperegs) {
 			dev_err(&pdev->dev,
@@ -14865,7 +15114,7 @@
 
 		tg3_ape_lock_init(tp);
 
-		if (tp->tg3_flags & TG3_FLAG_ENABLE_ASF)
+		if (tg3_flag(tp, ENABLE_ASF))
 			tg3_read_dash_ver(tp);
 	}
 
@@ -14909,7 +15158,7 @@
 		else
 			tnapi->coal_now = HOSTCC_MODE_NOW;
 
-		if (!(tp->tg3_flags & TG3_FLAG_SUPPORT_MSIX))
+		if (!tg3_flag(tp, SUPPORT_MSIX))
 			break;
 
 		/*
@@ -14963,21 +15212,25 @@
 			ethtype = "10/100/1000Base-T";
 
 		netdev_info(dev, "attached PHY is %s (%s Ethernet) "
-			    "(WireSpeed[%d])\n", tg3_phy_string(tp), ethtype,
-			  (tp->phy_flags & TG3_PHYFLG_NO_ETH_WIRE_SPEED) == 0);
+			    "(WireSpeed[%d], EEE[%d])\n",
+			    tg3_phy_string(tp), ethtype,
+			    (tp->phy_flags & TG3_PHYFLG_NO_ETH_WIRE_SPEED) == 0,
+			    (tp->phy_flags & TG3_PHYFLG_EEE_CAP) != 0);
 	}
 
 	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,
+		    (dev->features & NETIF_F_RXCSUM) != 0,
+		    tg3_flag(tp, USE_LINKCHG_REG) != 0,
 		    (tp->phy_flags & TG3_PHYFLG_USE_MI_INTERRUPT) != 0,
-		    (tp->tg3_flags & TG3_FLAG_ENABLE_ASF) != 0,
-		    (tp->tg3_flags2 & TG3_FLG2_TSO_CAPABLE) != 0);
+		    tg3_flag(tp, ENABLE_ASF) != 0,
+		    tg3_flag(tp, 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);
 
+	pci_save_state(pdev);
+
 	return 0;
 
 err_out_apeunmap:
@@ -15016,7 +15269,7 @@
 
 		cancel_work_sync(&tp->reset_task);
 
-		if (tp->tg3_flags3 & TG3_FLG3_USE_PHYLIB) {
+		if (!tg3_flag(tp, USE_PHYLIB)) {
 			tg3_phy_fini(tp);
 			tg3_mdio_fini(tp);
 		}
@@ -15062,7 +15315,7 @@
 
 	tg3_full_lock(tp, 0);
 	tg3_halt(tp, RESET_KIND_SHUTDOWN, 1);
-	tp->tg3_flags &= ~TG3_FLAG_INIT_COMPLETE;
+	tg3_flag_clear(tp, INIT_COMPLETE);
 	tg3_full_unlock(tp);
 
 	err = tg3_power_down_prepare(tp);
@@ -15071,7 +15324,7 @@
 
 		tg3_full_lock(tp, 0);
 
-		tp->tg3_flags |= TG3_FLAG_INIT_COMPLETE;
+		tg3_flag_set(tp, INIT_COMPLETE);
 		err2 = tg3_restart_hw(tp, 1);
 		if (err2)
 			goto out;
@@ -15106,7 +15359,7 @@
 
 	tg3_full_lock(tp, 0);
 
-	tp->tg3_flags |= TG3_FLAG_INIT_COMPLETE;
+	tg3_flag_set(tp, INIT_COMPLETE);
 	err = tg3_restart_hw(tp, 1);
 	if (err)
 		goto out;
@@ -15134,11 +15387,156 @@
 
 #endif /* CONFIG_PM_SLEEP */
 
+/**
+ * tg3_io_error_detected - called when PCI error is detected
+ * @pdev: Pointer to PCI device
+ * @state: The current pci connection state
+ *
+ * This function is called after a PCI bus error affecting
+ * this device has been detected.
+ */
+static pci_ers_result_t tg3_io_error_detected(struct pci_dev *pdev,
+					      pci_channel_state_t state)
+{
+	struct net_device *netdev = pci_get_drvdata(pdev);
+	struct tg3 *tp = netdev_priv(netdev);
+	pci_ers_result_t err = PCI_ERS_RESULT_NEED_RESET;
+
+	netdev_info(netdev, "PCI I/O error detected\n");
+
+	rtnl_lock();
+
+	if (!netif_running(netdev))
+		goto done;
+
+	tg3_phy_stop(tp);
+
+	tg3_netif_stop(tp);
+
+	del_timer_sync(&tp->timer);
+	tg3_flag_clear(tp, RESTART_TIMER);
+
+	/* Want to make sure that the reset task doesn't run */
+	cancel_work_sync(&tp->reset_task);
+	tg3_flag_clear(tp, TX_RECOVERY_PENDING);
+	tg3_flag_clear(tp, RESTART_TIMER);
+
+	netif_device_detach(netdev);
+
+	/* Clean up software state, even if MMIO is blocked */
+	tg3_full_lock(tp, 0);
+	tg3_halt(tp, RESET_KIND_SHUTDOWN, 0);
+	tg3_full_unlock(tp);
+
+done:
+	if (state == pci_channel_io_perm_failure)
+		err = PCI_ERS_RESULT_DISCONNECT;
+	else
+		pci_disable_device(pdev);
+
+	rtnl_unlock();
+
+	return err;
+}
+
+/**
+ * tg3_io_slot_reset - called after the pci bus has been reset.
+ * @pdev: Pointer to PCI device
+ *
+ * Restart the card from scratch, as if from a cold-boot.
+ * At this point, the card has exprienced a hard reset,
+ * followed by fixups by BIOS, and has its config space
+ * set up identically to what it was at cold boot.
+ */
+static pci_ers_result_t tg3_io_slot_reset(struct pci_dev *pdev)
+{
+	struct net_device *netdev = pci_get_drvdata(pdev);
+	struct tg3 *tp = netdev_priv(netdev);
+	pci_ers_result_t rc = PCI_ERS_RESULT_DISCONNECT;
+	int err;
+
+	rtnl_lock();
+
+	if (pci_enable_device(pdev)) {
+		netdev_err(netdev, "Cannot re-enable PCI device after reset.\n");
+		goto done;
+	}
+
+	pci_set_master(pdev);
+	pci_restore_state(pdev);
+	pci_save_state(pdev);
+
+	if (!netif_running(netdev)) {
+		rc = PCI_ERS_RESULT_RECOVERED;
+		goto done;
+	}
+
+	err = tg3_power_up(tp);
+	if (err) {
+		netdev_err(netdev, "Failed to restore register access.\n");
+		goto done;
+	}
+
+	rc = PCI_ERS_RESULT_RECOVERED;
+
+done:
+	rtnl_unlock();
+
+	return rc;
+}
+
+/**
+ * tg3_io_resume - called when traffic can start flowing again.
+ * @pdev: Pointer to PCI device
+ *
+ * This callback is called when the error recovery driver tells
+ * us that its OK to resume normal operation.
+ */
+static void tg3_io_resume(struct pci_dev *pdev)
+{
+	struct net_device *netdev = pci_get_drvdata(pdev);
+	struct tg3 *tp = netdev_priv(netdev);
+	int err;
+
+	rtnl_lock();
+
+	if (!netif_running(netdev))
+		goto done;
+
+	tg3_full_lock(tp, 0);
+	tg3_flag_set(tp, INIT_COMPLETE);
+	err = tg3_restart_hw(tp, 1);
+	tg3_full_unlock(tp);
+	if (err) {
+		netdev_err(netdev, "Cannot restart hardware after reset.\n");
+		goto done;
+	}
+
+	netif_device_attach(netdev);
+
+	tp->timer.expires = jiffies + tp->timer_offset;
+	add_timer(&tp->timer);
+
+	tg3_netif_start(tp);
+
+	tg3_phy_start(tp);
+
+done:
+	rtnl_unlock();
+}
+
+static struct pci_error_handlers tg3_err_handler = {
+	.error_detected	= tg3_io_error_detected,
+	.slot_reset	= tg3_io_slot_reset,
+	.resume		= tg3_io_resume
+};
+
 static struct pci_driver tg3_driver = {
 	.name		= DRV_MODULE_NAME,
 	.id_table	= tg3_pci_tbl,
 	.probe		= tg3_init_one,
 	.remove		= __devexit_p(tg3_remove_one),
+	.err_handler	= &tg3_err_handler,
 	.driver.pm	= TG3_PM_OPS,
 };
 
diff -druN linux-2.6.39-libre/drivers/net/tg3.h linux-3.0-rc7-libre/drivers/net/tg3.h
--- linux-2.6.39-libre/drivers/net/tg3.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/tg3.h	2011-07-11 19:51:52.000000000 -0400
@@ -23,11 +23,13 @@
 #define TG3_BDINFO_NIC_ADDR		0xcUL /* 32-bit */
 #define TG3_BDINFO_SIZE			0x10UL
 
-#define TG3_RX_INTERNAL_RING_SZ_5906	32
-
-#define RX_STD_MAX_SIZE_5705		512
-#define RX_STD_MAX_SIZE_5717		2048
-#define RX_JUMBO_MAX_SIZE		0xdeadbeef /* XXX */
+#define TG3_RX_STD_MAX_SIZE_5700	512
+#define TG3_RX_STD_MAX_SIZE_5717	2048
+#define TG3_RX_JMB_MAX_SIZE_5700	256
+#define TG3_RX_JMB_MAX_SIZE_5717	1024
+#define TG3_RX_RET_MAX_SIZE_5700	1024
+#define TG3_RX_RET_MAX_SIZE_5705	512
+#define TG3_RX_RET_MAX_SIZE_5717	4096
 
 /* First 256 bytes are a mirror of PCI config space. */
 #define TG3PCI_VENDOR			0x00000000
@@ -54,6 +56,7 @@
 #define  TG3PCI_DEVICE_TIGON3_57791	 0x16b2
 #define  TG3PCI_DEVICE_TIGON3_57795	 0x16b6
 #define  TG3PCI_DEVICE_TIGON3_5719	 0x1657
+#define  TG3PCI_DEVICE_TIGON3_5720	 0x165f
 /* 0x04 --> 0x2c unused */
 #define TG3PCI_SUBVENDOR_ID_BROADCOM		PCI_VENDOR_ID_BROADCOM
 #define TG3PCI_SUBDEVICE_ID_BROADCOM_95700A6	0x1644
@@ -142,6 +145,7 @@
 #define  CHIPREV_ID_5717_A0		 0x05717000
 #define  CHIPREV_ID_57765_A0		 0x57785000
 #define  CHIPREV_ID_5719_A0		 0x05719000
+#define  CHIPREV_ID_5720_A0		 0x05720000
 #define  GET_ASIC_REV(CHIP_REV_ID)	((CHIP_REV_ID) >> 12)
 #define   ASIC_REV_5700			 0x07
 #define   ASIC_REV_5701			 0x00
@@ -163,6 +167,7 @@
 #define   ASIC_REV_5717			 0x5717
 #define   ASIC_REV_57765		 0x57785
 #define   ASIC_REV_5719			 0x5719
+#define   ASIC_REV_5720			 0x5720
 #define  GET_CHIP_REV(CHIP_REV_ID)	((CHIP_REV_ID) >> 8)
 #define   CHIPREV_5700_AX		 0x70
 #define   CHIPREV_5700_BX		 0x71
@@ -175,6 +180,7 @@
 #define   CHIPREV_5750_BX		 0x41
 #define   CHIPREV_5784_AX		 0x57840
 #define   CHIPREV_5761_AX		 0x57610
+#define   CHIPREV_57765_AX		 0x577650
 #define  GET_METAL_REV(CHIP_REV_ID)	((CHIP_REV_ID) & 0xff)
 #define   METAL_REV_A0			 0x00
 #define   METAL_REV_A1			 0x01
@@ -183,6 +189,7 @@
 #define   METAL_REV_B2			 0x02
 #define TG3PCI_DMA_RW_CTRL		0x0000006c
 #define  DMA_RWCTRL_DIS_CACHE_ALIGNMENT  0x00000001
+#define  DMA_RWCTRL_TAGGED_STAT_WA	 0x00000080
 #define  DMA_RWCTRL_CRDRDR_RDMA_MRRS_MSK 0x00000380
 #define  DMA_RWCTRL_READ_BNDRY_MASK	 0x00000700
 #define  DMA_RWCTRL_READ_BNDRY_DISAB	 0x00000000
@@ -473,6 +480,8 @@
 #define  TX_MODE_BIG_BCKOFF_ENABLE	 0x00000020
 #define  TX_MODE_LONG_PAUSE_ENABLE	 0x00000040
 #define  TX_MODE_MBUF_LOCKUP_FIX	 0x00000100
+#define  TX_MODE_JMB_FRM_LEN		 0x00400000
+#define  TX_MODE_CNT_DN_MODE		 0x00800000
 #define MAC_TX_STATUS			0x00000460
 #define  TX_STATUS_XOFFED		 0x00000001
 #define  TX_STATUS_SENT_XOFF		 0x00000002
@@ -487,6 +496,8 @@
 #define  TX_LENGTHS_IPG_SHIFT		 8
 #define  TX_LENGTHS_IPG_CRS_MASK	 0x00003000
 #define  TX_LENGTHS_IPG_CRS_SHIFT	 12
+#define  TX_LENGTHS_JMB_FRM_LEN_MSK	 0x00ff0000
+#define  TX_LENGTHS_CNT_DWN_VAL_MSK	 0xff000000
 #define MAC_RX_MODE			0x00000468
 #define  RX_MODE_RESET			 0x00000001
 #define  RX_MODE_ENABLE			 0x00000002
@@ -1079,6 +1090,9 @@
 #define  CPMU_HST_ACC_MACCLK_6_25	 0x00130000
 /* 0x3620 --> 0x3630 unused */
 
+#define TG3_CPMU_CLCK_ORIDE		0x00003624
+#define  CPMU_CLCK_ORIDE_MAC_ORIDE_EN	 0x80000000
+
 #define TG3_CPMU_CLCK_STAT		0x00003630
 #define  CPMU_CLCK_STAT_MAC_CLCK_MASK	 0x001f0000
 #define  CPMU_CLCK_STAT_MAC_CLCK_62_5	 0x00000000
@@ -1188,6 +1202,7 @@
 #define HOSTCC_STATS_BLK_NIC_ADDR	0x00003c40
 #define HOSTCC_STATUS_BLK_NIC_ADDR	0x00003c44
 #define HOSTCC_FLOW_ATTN		0x00003c48
+#define HOSTCC_FLOW_ATTN_MBUF_LWM	 0x00000040
 /* 0x3c4c --> 0x3c50 unused */
 #define HOSTCC_JUMBO_CON_IDX		0x00003c50
 #define HOSTCC_STD_CON_IDX		0x00003c54
@@ -1321,6 +1336,7 @@
 #define  RDMAC_MODE_MULT_DMA_RD_DIS	 0x01000000
 #define  RDMAC_MODE_IPV4_LSO_EN		 0x08000000
 #define  RDMAC_MODE_IPV6_LSO_EN		 0x10000000
+#define  RDMAC_MODE_H2BNC_VLAN_DET	 0x20000000
 #define RDMAC_STATUS			0x00004804
 #define  RDMAC_STATUS_TGTABORT		 0x00000004
 #define  RDMAC_STATUS_MSTABORT		 0x00000008
@@ -1597,6 +1613,7 @@
 #define  MSGINT_MODE_ONE_SHOT_DISABLE	 0x00000020
 #define  MSGINT_MODE_MULTIVEC_EN	 0x00000080
 #define MSGINT_STATUS			0x00006004
+#define  MSGINT_STATUS_MSI_REQ		 0x00000001
 #define MSGINT_FIFO			0x00006008
 /* 0x600c --> 0x6400 unused */
 
@@ -1613,6 +1630,8 @@
 #define  GRC_MODE_WSWAP_NONFRM_DATA	0x00000004
 #define  GRC_MODE_BSWAP_DATA		0x00000010
 #define  GRC_MODE_WSWAP_DATA		0x00000020
+#define  GRC_MODE_BYTE_SWAP_B2HRX_DATA	0x00000040
+#define  GRC_MODE_WORD_SWAP_B2HRX_DATA	0x00000080
 #define  GRC_MODE_SPLITHDR		0x00000100
 #define  GRC_MODE_NOFRM_CRACKING	0x00000200
 #define  GRC_MODE_INCL_CRC		0x00000400
@@ -1620,8 +1639,10 @@
 #define  GRC_MODE_NOIRQ_ON_SENDS	0x00002000
 #define  GRC_MODE_NOIRQ_ON_RCV		0x00004000
 #define  GRC_MODE_FORCE_PCI32BIT	0x00008000
+#define  GRC_MODE_B2HRX_ENABLE		0x00008000
 #define  GRC_MODE_HOST_STACKUP		0x00010000
 #define  GRC_MODE_HOST_SENDBDS		0x00020000
+#define  GRC_MODE_HTX2B_ENABLE		0x00040000
 #define  GRC_MODE_NO_TX_PHDR_CSUM	0x00100000
 #define  GRC_MODE_NVRAM_WR_ENABLE	0x00200000
 #define  GRC_MODE_PCIE_TL_SEL		0x00000000
@@ -1818,6 +1839,38 @@
 #define  FLASH_5717VENDOR_ATMEL_45USPT	 0x03400000
 #define  FLASH_5717VENDOR_ST_25USPT	 0x03400002
 #define  FLASH_5717VENDOR_ST_45USPT	 0x03400001
+#define  FLASH_5720_EEPROM_HD		 0x00000001
+#define  FLASH_5720_EEPROM_LD		 0x00000003
+#define  FLASH_5720VENDOR_M_ATMEL_DB011D 0x01000000
+#define  FLASH_5720VENDOR_M_ATMEL_DB021D 0x01000002
+#define  FLASH_5720VENDOR_M_ATMEL_DB041D 0x01000001
+#define  FLASH_5720VENDOR_M_ATMEL_DB081D 0x01000003
+#define  FLASH_5720VENDOR_M_ST_M25PE10	 0x02000000
+#define  FLASH_5720VENDOR_M_ST_M25PE20	 0x02000002
+#define  FLASH_5720VENDOR_M_ST_M25PE40	 0x02000001
+#define  FLASH_5720VENDOR_M_ST_M25PE80	 0x02000003
+#define  FLASH_5720VENDOR_M_ST_M45PE10	 0x03000000
+#define  FLASH_5720VENDOR_M_ST_M45PE20	 0x03000002
+#define  FLASH_5720VENDOR_M_ST_M45PE40	 0x03000001
+#define  FLASH_5720VENDOR_M_ST_M45PE80	 0x03000003
+#define  FLASH_5720VENDOR_A_ATMEL_DB011B 0x01800000
+#define  FLASH_5720VENDOR_A_ATMEL_DB021B 0x01800002
+#define  FLASH_5720VENDOR_A_ATMEL_DB041B 0x01800001
+#define  FLASH_5720VENDOR_A_ATMEL_DB011D 0x01c00000
+#define  FLASH_5720VENDOR_A_ATMEL_DB021D 0x01c00002
+#define  FLASH_5720VENDOR_A_ATMEL_DB041D 0x01c00001
+#define  FLASH_5720VENDOR_A_ATMEL_DB081D 0x01c00003
+#define  FLASH_5720VENDOR_A_ST_M25PE10	 0x02800000
+#define  FLASH_5720VENDOR_A_ST_M25PE20	 0x02800002
+#define  FLASH_5720VENDOR_A_ST_M25PE40	 0x02800001
+#define  FLASH_5720VENDOR_A_ST_M25PE80	 0x02800003
+#define  FLASH_5720VENDOR_A_ST_M45PE10	 0x02c00000
+#define  FLASH_5720VENDOR_A_ST_M45PE20	 0x02c00002
+#define  FLASH_5720VENDOR_A_ST_M45PE40	 0x02c00001
+#define  FLASH_5720VENDOR_A_ST_M45PE80	 0x02c00003
+#define  FLASH_5720VENDOR_ATMEL_45USPT	 0x03c00000
+#define  FLASH_5720VENDOR_ST_25USPT	 0x03c00002
+#define  FLASH_5720VENDOR_ST_45USPT	 0x03c00001
 #define  NVRAM_CFG1_5752PAGE_SIZE_MASK	 0x70000000
 #define  FLASH_5752PAGE_SIZE_256	 0x00000000
 #define  FLASH_5752PAGE_SIZE_512	 0x10000000
@@ -1899,11 +1952,16 @@
 
 /* Alternate PCIE definitions */
 #define TG3_PCIE_TLDLPL_PORT		0x00007c00
+#define TG3_PCIE_DL_LO_FTSMAX		0x0000000c
+#define TG3_PCIE_DL_LO_FTSMAX_MSK	0x000000ff
+#define TG3_PCIE_DL_LO_FTSMAX_VAL	0x0000002c
 #define TG3_PCIE_PL_LO_PHYCTL1		 0x00000004
 #define TG3_PCIE_PL_LO_PHYCTL1_L1PLLPD_EN	  0x00001000
 #define TG3_PCIE_PL_LO_PHYCTL5		 0x00000014
 #define TG3_PCIE_PL_LO_PHYCTL5_DIS_L2CLKREQ	  0x80000000
 
+#define TG3_REG_BLK_SIZE		0x00008000
+
 /* OTP bit definitions */
 #define TG3_OTP_AGCTGT_MASK		0x000000e0
 #define TG3_OTP_AGCTGT_SHIFT		1
@@ -1955,7 +2013,9 @@
 #define TG3_NVM_DIR_END			0x78
 #define TG3_NVM_DIRENT_SIZE		0xc
 #define TG3_NVM_DIRTYPE_SHIFT		24
+#define TG3_NVM_DIRTYPE_LENMSK		0x003fffff
 #define TG3_NVM_DIRTYPE_ASFINI		1
+#define TG3_NVM_DIRTYPE_EXTVPD		20
 #define TG3_NVM_PTREV_BCVER		0x94
 #define TG3_NVM_BCVER_MAJMSK		0x0000ff00
 #define TG3_NVM_BCVER_MAJSFT		8
@@ -2079,6 +2139,13 @@
 #define  NIC_SRAM_MBUF_POOL_BASE5705	0x00010000
 #define  NIC_SRAM_MBUF_POOL_SIZE5705	0x0000e000
 
+#define TG3_SRAM_RX_STD_BDCACHE_SIZE_5700	128
+#define TG3_SRAM_RX_STD_BDCACHE_SIZE_5755	64
+#define TG3_SRAM_RX_STD_BDCACHE_SIZE_5906	32
+
+#define TG3_SRAM_RX_JMB_BDCACHE_SIZE_5700	64
+#define TG3_SRAM_RX_JMB_BDCACHE_SIZE_5717	16
+
 
 /* Currently this is fixed. */
 #define TG3_PHY_MII_ADDR		0x01
@@ -2119,7 +2186,7 @@
 #define  MII_TG3_DSP_TAP26_OPCSINPT	0x0004
 #define MII_TG3_DSP_AADJ1CH0		0x001f
 #define MII_TG3_DSP_CH34TP2		0x4022
-#define MII_TG3_DSP_CH34TP2_HIBW01	0x0010
+#define MII_TG3_DSP_CH34TP2_HIBW01	0x017b
 #define MII_TG3_DSP_AADJ1CH3		0x601f
 #define  MII_TG3_DSP_AADJ1CH3_ADCCKADJ	0x0002
 #define MII_TG3_DSP_EXP1_INT_STAT	0x0f01
@@ -2132,19 +2199,26 @@
 
 #define MII_TG3_AUX_CTRL		0x18 /* auxiliary control register */
 
+#define MII_TG3_AUXCTL_SHDWSEL_AUXCTL	0x0000
+#define MII_TG3_AUXCTL_ACTL_TX_6DB	0x0400
+#define MII_TG3_AUXCTL_ACTL_SMDSP_ENA	0x0800
+#define MII_TG3_AUXCTL_ACTL_EXTPKTLEN	0x4000
+
+#define MII_TG3_AUXCTL_SHDWSEL_PWRCTL	0x0002
+#define MII_TG3_AUXCTL_PCTL_WOL_EN	0x0008
 #define MII_TG3_AUXCTL_PCTL_100TX_LPWR	0x0010
 #define MII_TG3_AUXCTL_PCTL_SPR_ISOLATE	0x0020
+#define MII_TG3_AUXCTL_PCTL_CL_AB_TXDAC	0x0040
 #define MII_TG3_AUXCTL_PCTL_VREG_11V	0x0180
-#define MII_TG3_AUXCTL_SHDWSEL_PWRCTL	0x0002
 
-#define MII_TG3_AUXCTL_MISC_WREN	0x8000
-#define MII_TG3_AUXCTL_MISC_FORCE_AMDIX	0x0200
-#define MII_TG3_AUXCTL_MISC_RDSEL_MISC	0x7000
+#define MII_TG3_AUXCTL_SHDWSEL_MISCTEST	0x0004
+
 #define MII_TG3_AUXCTL_SHDWSEL_MISC	0x0007
+#define MII_TG3_AUXCTL_MISC_WIRESPD_EN	0x0010
+#define MII_TG3_AUXCTL_MISC_FORCE_AMDIX	0x0200
+#define MII_TG3_AUXCTL_MISC_RDSEL_SHIFT	12
+#define MII_TG3_AUXCTL_MISC_WREN	0x8000
 
-#define MII_TG3_AUXCTL_ACTL_SMDSP_ENA	0x0800
-#define MII_TG3_AUXCTL_ACTL_TX_6DB	0x0400
-#define MII_TG3_AUXCTL_SHDWSEL_AUXCTL	0x0000
 
 #define MII_TG3_AUX_STAT		0x19 /* auxiliary status register */
 #define MII_TG3_AUX_STAT_LPASS		0x0004
@@ -2564,7 +2638,12 @@
 	tg3_stat64_t			nic_avoided_irqs;
 	tg3_stat64_t			nic_tx_threshold_hit;
 
-	u8				__reserved4[0xb00-0x9c0];
+	/* NOT a part of the hardware statistics block format.
+	 * These stats are here as storage for tg3_periodic_fetch_stats().
+	 */
+	tg3_stat64_t			mbuf_lwm_thresh_hit;
+
+	u8				__reserved4[0xb00-0x9c8];
 };
 
 /* 'mapping' is superfluous as the chip does not write into
@@ -2696,6 +2775,8 @@
 	u64		nic_irqs;
 	u64		nic_avoided_irqs;
 	u64		nic_tx_threshold_hit;
+
+	u64		mbuf_lwm_thresh_hit;
 };
 
 struct tg3_rx_prodring_set {
@@ -2745,6 +2826,86 @@
 	unsigned int			irq_vec;
 };
 
+enum TG3_FLAGS {
+	TG3_FLAG_TAGGED_STATUS = 0,
+	TG3_FLAG_TXD_MBOX_HWBUG,
+	TG3_FLAG_USE_LINKCHG_REG,
+	TG3_FLAG_ERROR_PROCESSED,
+	TG3_FLAG_ENABLE_ASF,
+	TG3_FLAG_ASPM_WORKAROUND,
+	TG3_FLAG_POLL_SERDES,
+	TG3_FLAG_MBOX_WRITE_REORDER,
+	TG3_FLAG_PCIX_TARGET_HWBUG,
+	TG3_FLAG_WOL_SPEED_100MB,
+	TG3_FLAG_WOL_ENABLE,
+	TG3_FLAG_EEPROM_WRITE_PROT,
+	TG3_FLAG_NVRAM,
+	TG3_FLAG_NVRAM_BUFFERED,
+	TG3_FLAG_SUPPORT_MSI,
+	TG3_FLAG_SUPPORT_MSIX,
+	TG3_FLAG_PCIX_MODE,
+	TG3_FLAG_PCI_HIGH_SPEED,
+	TG3_FLAG_PCI_32BIT,
+	TG3_FLAG_SRAM_USE_CONFIG,
+	TG3_FLAG_TX_RECOVERY_PENDING,
+	TG3_FLAG_WOL_CAP,
+	TG3_FLAG_JUMBO_RING_ENABLE,
+	TG3_FLAG_PAUSE_AUTONEG,
+	TG3_FLAG_CPMU_PRESENT,
+	TG3_FLAG_40BIT_DMA_BUG,
+	TG3_FLAG_BROKEN_CHECKSUMS,
+	TG3_FLAG_JUMBO_CAPABLE,
+	TG3_FLAG_CHIP_RESETTING,
+	TG3_FLAG_INIT_COMPLETE,
+	TG3_FLAG_RESTART_TIMER,
+	TG3_FLAG_TSO_BUG,
+	TG3_FLAG_IS_5788,
+	TG3_FLAG_MAX_RXPEND_64,
+	TG3_FLAG_TSO_CAPABLE,
+	TG3_FLAG_PCI_EXPRESS,
+	TG3_FLAG_ASF_NEW_HANDSHAKE,
+	TG3_FLAG_HW_AUTONEG,
+	TG3_FLAG_IS_NIC,
+	TG3_FLAG_FLASH,
+	TG3_FLAG_HW_TSO_1,
+	TG3_FLAG_5705_PLUS,
+	TG3_FLAG_5750_PLUS,
+	TG3_FLAG_HW_TSO_3,
+	TG3_FLAG_USING_MSI,
+	TG3_FLAG_USING_MSIX,
+	TG3_FLAG_ICH_WORKAROUND,
+	TG3_FLAG_5780_CLASS,
+	TG3_FLAG_HW_TSO_2,
+	TG3_FLAG_1SHOT_MSI,
+	TG3_FLAG_NO_FWARE_REPORTED,
+	TG3_FLAG_NO_NVRAM_ADDR_TRANS,
+	TG3_FLAG_ENABLE_APE,
+	TG3_FLAG_PROTECTED_NVRAM,
+	TG3_FLAG_5701_DMA_BUG,
+	TG3_FLAG_USE_PHYLIB,
+	TG3_FLAG_MDIOBUS_INITED,
+	TG3_FLAG_LRG_PROD_RING_CAP,
+	TG3_FLAG_RGMII_INBAND_DISABLE,
+	TG3_FLAG_RGMII_EXT_IBND_RX_EN,
+	TG3_FLAG_RGMII_EXT_IBND_TX_EN,
+	TG3_FLAG_CLKREQ_BUG,
+	TG3_FLAG_5755_PLUS,
+	TG3_FLAG_NO_NVRAM,
+	TG3_FLAG_ENABLE_RSS,
+	TG3_FLAG_ENABLE_TSS,
+	TG3_FLAG_4G_DMA_BNDRY_BUG,
+	TG3_FLAG_40BIT_DMA_LIMIT_BUG,
+	TG3_FLAG_SHORT_DMA_BUG,
+	TG3_FLAG_USE_JUMBO_BDFLAG,
+	TG3_FLAG_L1PLLPD_EN,
+	TG3_FLAG_57765_PLUS,
+	TG3_FLAG_APE_HAS_NCSI,
+	TG3_FLAG_5717_PLUS,
+
+	/* Add new flags before this comment and TG3_FLAG_NUMBER_OF_FLAGS */
+	TG3_FLAG_NUMBER_OF_FLAGS,	/* Last entry in enum TG3_FLAGS */
+};
+
 struct tg3 {
 	/* begin "general, frequently-used members" cacheline section */
 
@@ -2768,7 +2929,7 @@
 	/* SMP locking strategy:
 	 *
 	 * lock: Held during reset, PHY access, timer, and when
-	 *       updating tg3_flags and tg3_flags2.
+	 *       updating tg3_flags.
 	 *
 	 * netif_tx_lock: Held during tg3_start_xmit. tg3_tx holds
 	 *                netif_tx_lock when it needs to call
@@ -2825,94 +2986,13 @@
 	struct tg3_ethtool_stats	estats;
 	struct tg3_ethtool_stats	estats_prev;
 
+	DECLARE_BITMAP(tg3_flags, TG3_FLAG_NUMBER_OF_FLAGS);
+
 	union {
 	unsigned long			phy_crc_errors;
 	unsigned long			last_event_jiffies;
 	};
 
-	u32				tg3_flags;
-#define TG3_FLAG_TAGGED_STATUS		0x00000001
-#define TG3_FLAG_TXD_MBOX_HWBUG		0x00000002
-#define TG3_FLAG_RX_CHECKSUMS		0x00000004
-#define TG3_FLAG_USE_LINKCHG_REG	0x00000008
-#define TG3_FLAG_ENABLE_ASF		0x00000020
-#define TG3_FLAG_ASPM_WORKAROUND	0x00000040
-#define TG3_FLAG_POLL_SERDES		0x00000080
-#define TG3_FLAG_MBOX_WRITE_REORDER	0x00000100
-#define TG3_FLAG_PCIX_TARGET_HWBUG	0x00000200
-#define TG3_FLAG_WOL_SPEED_100MB	0x00000400
-#define TG3_FLAG_WOL_ENABLE		0x00000800
-#define TG3_FLAG_EEPROM_WRITE_PROT	0x00001000
-#define TG3_FLAG_NVRAM			0x00002000
-#define TG3_FLAG_NVRAM_BUFFERED		0x00004000
-#define TG3_FLAG_SUPPORT_MSI		0x00008000
-#define TG3_FLAG_SUPPORT_MSIX		0x00010000
-#define TG3_FLAG_SUPPORT_MSI_OR_MSIX	(TG3_FLAG_SUPPORT_MSI | \
-					 TG3_FLAG_SUPPORT_MSIX)
-#define TG3_FLAG_PCIX_MODE		0x00020000
-#define TG3_FLAG_PCI_HIGH_SPEED		0x00040000
-#define TG3_FLAG_PCI_32BIT		0x00080000
-#define TG3_FLAG_SRAM_USE_CONFIG	0x00100000
-#define TG3_FLAG_TX_RECOVERY_PENDING	0x00200000
-#define TG3_FLAG_WOL_CAP		0x00400000
-#define TG3_FLAG_JUMBO_RING_ENABLE	0x00800000
-#define TG3_FLAG_PAUSE_AUTONEG		0x02000000
-#define TG3_FLAG_CPMU_PRESENT		0x04000000
-#define TG3_FLAG_40BIT_DMA_BUG		0x08000000
-#define TG3_FLAG_BROKEN_CHECKSUMS	0x10000000
-#define TG3_FLAG_JUMBO_CAPABLE		0x20000000
-#define TG3_FLAG_CHIP_RESETTING		0x40000000
-#define TG3_FLAG_INIT_COMPLETE		0x80000000
-	u32				tg3_flags2;
-#define TG3_FLG2_RESTART_TIMER		0x00000001
-#define TG3_FLG2_TSO_BUG		0x00000002
-#define TG3_FLG2_IS_5788		0x00000008
-#define TG3_FLG2_MAX_RXPEND_64		0x00000010
-#define TG3_FLG2_TSO_CAPABLE		0x00000020
-#define TG3_FLG2_PCI_EXPRESS		0x00000200
-#define TG3_FLG2_ASF_NEW_HANDSHAKE	0x00000400
-#define TG3_FLG2_HW_AUTONEG		0x00000800
-#define TG3_FLG2_IS_NIC			0x00001000
-#define TG3_FLG2_FLASH			0x00008000
-#define TG3_FLG2_HW_TSO_1		0x00010000
-#define TG3_FLG2_5705_PLUS		0x00040000
-#define TG3_FLG2_5750_PLUS		0x00080000
-#define TG3_FLG2_HW_TSO_3		0x00100000
-#define TG3_FLG2_USING_MSI		0x00200000
-#define TG3_FLG2_USING_MSIX		0x00400000
-#define TG3_FLG2_USING_MSI_OR_MSIX	(TG3_FLG2_USING_MSI | \
-					TG3_FLG2_USING_MSIX)
-#define TG3_FLG2_ICH_WORKAROUND		0x02000000
-#define TG3_FLG2_5780_CLASS		0x04000000
-#define TG3_FLG2_HW_TSO_2		0x08000000
-#define TG3_FLG2_HW_TSO			(TG3_FLG2_HW_TSO_1 | \
-					 TG3_FLG2_HW_TSO_2 | \
-					 TG3_FLG2_HW_TSO_3)
-#define TG3_FLG2_1SHOT_MSI		0x10000000
-#define TG3_FLG2_NO_FWARE_REPORTED	0x40000000
-	u32				tg3_flags3;
-#define TG3_FLG3_NO_NVRAM_ADDR_TRANS	0x00000001
-#define TG3_FLG3_ENABLE_APE		0x00000002
-#define TG3_FLG3_PROTECTED_NVRAM	0x00000004
-#define TG3_FLG3_5701_DMA_BUG		0x00000008
-#define TG3_FLG3_USE_PHYLIB		0x00000010
-#define TG3_FLG3_MDIOBUS_INITED		0x00000020
-#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
-#define TG3_FLG3_5755_PLUS		0x00002000
-#define TG3_FLG3_NO_NVRAM		0x00004000
-#define TG3_FLG3_ENABLE_RSS		0x00020000
-#define TG3_FLG3_ENABLE_TSS		0x00040000
-#define TG3_FLG3_4G_DMA_BNDRY_BUG	0x00080000
-#define TG3_FLG3_40BIT_DMA_LIMIT_BUG	0x00100000
-#define TG3_FLG3_SHORT_DMA_BUG		0x00200000
-#define TG3_FLG3_USE_JUMBO_BDFLAG	0x00400000
-#define TG3_FLG3_L1PLLPD_EN		0x00800000
-#define TG3_FLG3_5717_PLUS		0x01000000
-#define TG3_FLG3_APE_HAS_NCSI		0x02000000
-
 	struct timer_list		timer;
 	u16				timer_counter;
 	u16				timer_multiplier;
@@ -2983,6 +3063,7 @@
 #define TG3_PHY_ID_BCM5718S		0xbc050ff0
 #define TG3_PHY_ID_BCM57765		0x5c0d8a40
 #define TG3_PHY_ID_BCM5719C		0x5c0d8a20
+#define TG3_PHY_ID_BCM5720C		0x5c0d8b60
 #define TG3_PHY_ID_BCM5906		0xdc00ac40
 #define TG3_PHY_ID_BCM8002		0x60010140
 #define TG3_PHY_ID_INVALID		0xffffffff
@@ -3049,6 +3130,7 @@
 
 	int				nvram_lock_cnt;
 	u32				nvram_size;
+#define TG3_NVRAM_SIZE_2KB		0x00000800
 #define TG3_NVRAM_SIZE_64KB		0x00010000
 #define TG3_NVRAM_SIZE_128KB		0x00020000
 #define TG3_NVRAM_SIZE_256KB		0x00040000
@@ -3064,6 +3146,9 @@
 #define JEDEC_SAIFUN			0x4f
 #define JEDEC_SST			0xbf
 
+#define ATMEL_AT24C02_CHIP_SIZE		TG3_NVRAM_SIZE_2KB
+#define ATMEL_AT24C02_PAGE_SIZE		(8)
+
 #define ATMEL_AT24C64_CHIP_SIZE		TG3_NVRAM_SIZE_64KB
 #define ATMEL_AT24C64_PAGE_SIZE		(32)
 
diff -druN linux-2.6.39-libre/drivers/net/tile/tilepro.c linux-3.0-rc7-libre/drivers/net/tile/tilepro.c
--- linux-2.6.39-libre/drivers/net/tile/tilepro.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/tile/tilepro.c	2011-07-11 19:51:52.000000000 -0400
@@ -1658,11 +1658,9 @@
 	while (tile_net_lepp_free_comps(dev, true))
 		/* loop */;
 
-	/* Wipe the EPP queue. */
+	/* Wipe the EPP queue, and wait till the stores hit the EPP. */
 	memset(priv->eq, 0, sizeof(lepp_queue_t));
-
-	/* Evict the EPP queue. */
-	finv_buffer(priv->eq, EQ_SIZE);
+	mb();
 
 	return 0;
 }
@@ -1930,7 +1928,7 @@
 	unsigned int len = skb->len;
 	unsigned char *data = skb->data;
 
-	unsigned int csum_start = skb->csum_start - skb_headroom(skb);
+	unsigned int csum_start = skb_checksum_start_offset(skb);
 
 	lepp_frag_t frags[LEPP_MAX_FRAGS];
 
@@ -2398,7 +2396,7 @@
 			struct net_device *dev = tile_net_devs[i];
 			struct tile_net_priv *priv = netdev_priv(dev);
 			unregister_netdev(dev);
-			finv_buffer(priv->eq, EQ_SIZE);
+			finv_buffer_remote(priv->eq, EQ_SIZE, 0);
 			__free_pages(priv->eq_pages, EQ_ORDER);
 			free_netdev(dev);
 		}
diff -druN linux-2.6.39-libre/drivers/net/tokenring/olympic.c linux-3.0-rc7-libre/drivers/net/tokenring/olympic.c
--- linux-2.6.39-libre/drivers/net/tokenring/olympic.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/tokenring/olympic.c	2011-07-11 19:51:52.000000000 -0400
@@ -86,6 +86,7 @@
 #include <linux/timer.h>
 #include <linux/in.h>
 #include <linux/ioport.h>
+#include <linux/seq_file.h>
 #include <linux/string.h>
 #include <linux/proc_fs.h>
 #include <linux/ptrace.h>
@@ -193,7 +194,7 @@
 static int olympic_change_mtu(struct net_device *dev, int mtu);
 static void olympic_srb_bh(struct net_device *dev) ; 
 static void olympic_asb_bh(struct net_device *dev) ; 
-static int olympic_proc_info(char *buffer, char **start, off_t offset, int length, int *eof, void *data) ; 
+static const struct file_operations olympic_proc_ops;
 
 static const struct net_device_ops olympic_netdev_ops = {
 	.ndo_open		= olympic_open,
@@ -272,7 +273,7 @@
 		char proc_name[20] ; 
 		strcpy(proc_name,"olympic_") ;
 		strcat(proc_name,dev->name) ; 
-		create_proc_read_entry(proc_name,0,init_net.proc_net,olympic_proc_info,(void *)dev) ;
+		proc_create_data(proc_name, 0, init_net.proc_net, &olympic_proc_ops, dev);
 		printk("Olympic: Network Monitor information: /proc/%s\n",proc_name); 
 	}
 	return  0 ;
@@ -1615,29 +1616,25 @@
 	return 0 ; 
 }
 
-static int olympic_proc_info(char *buffer, char **start, off_t offset, int length, int *eof, void *data)
+static int olympic_proc_show(struct seq_file *m, void *v)
 {
-	struct net_device *dev = (struct net_device *)data ; 
+	struct net_device *dev = m->private;
 	struct olympic_private *olympic_priv=netdev_priv(dev);
 	u8 __iomem *oat = (olympic_priv->olympic_lap + olympic_priv->olympic_addr_table_addr) ; 
 	u8 __iomem *opt = (olympic_priv->olympic_lap + olympic_priv->olympic_parms_addr) ; 
-	int size = 0 ; 
-	int len=0;
-	off_t begin=0;
-	off_t pos=0;
 	u8 addr[6];
 	u8 addr2[6];
 	int i;
 
-	size = sprintf(buffer, 
+	seq_printf(m,
 		"IBM Pit/Pit-Phy/Olympic Chipset Token Ring Adapter %s\n",dev->name);
-	size += sprintf(buffer+size, "\n%6s: Adapter Address   : Node Address      : Functional Addr\n",
+	seq_printf(m, "\n%6s: Adapter Address   : Node Address      : Functional Addr\n",
  	   dev->name); 
 
 	for (i = 0 ; i < 6 ; i++)
 		addr[i] = readb(oat+offsetof(struct olympic_adapter_addr_table,node_addr) + i);
 
-	size += sprintf(buffer+size, "%6s: %pM : %pM : %02x:%02x:%02x:%02x\n",
+	seq_printf(m, "%6s: %pM : %pM : %02x:%02x:%02x:%02x\n",
 	   dev->name,
 	   dev->dev_addr, addr,
 	   readb(oat+offsetof(struct olympic_adapter_addr_table,func_addr)), 
@@ -1645,9 +1642,9 @@
 	   readb(oat+offsetof(struct olympic_adapter_addr_table,func_addr)+2),
 	   readb(oat+offsetof(struct olympic_adapter_addr_table,func_addr)+3));
 	 
-	size += sprintf(buffer+size, "\n%6s: Token Ring Parameters Table:\n", dev->name);
+	seq_printf(m, "\n%6s: Token Ring Parameters Table:\n", dev->name);
 
-	size += sprintf(buffer+size, "%6s: Physical Addr : Up Node Address   : Poll Address      : AccPri : Auth Src : Att Code :\n",
+	seq_printf(m, "%6s: Physical Addr : Up Node Address   : Poll Address      : AccPri : Auth Src : Att Code :\n",
 	  dev->name) ; 
 
 	for (i = 0 ; i < 6 ; i++)
@@ -1655,7 +1652,7 @@
 	for (i = 0 ; i < 6 ; i++)
 		addr2[i] =  readb(opt+offsetof(struct olympic_parameters_table, poll_addr) + i);
 
-	size += sprintf(buffer+size, "%6s: %02x:%02x:%02x:%02x   : %pM : %pM : %04x   : %04x     :  %04x    :\n",
+	seq_printf(m, "%6s: %02x:%02x:%02x:%02x   : %pM : %pM : %04x   : %04x     :  %04x    :\n",
 	  dev->name,
 	  readb(opt+offsetof(struct olympic_parameters_table, phys_addr)),
 	  readb(opt+offsetof(struct olympic_parameters_table, phys_addr)+1),
@@ -1666,12 +1663,12 @@
 	  swab16(readw(opt+offsetof(struct olympic_parameters_table, auth_source_class))),
 	  swab16(readw(opt+offsetof(struct olympic_parameters_table, att_code))));
 
-	size += sprintf(buffer+size, "%6s: Source Address    : Bcn T : Maj. V : Lan St : Lcl Rg : Mon Err : Frame Correl : \n",
+	seq_printf(m, "%6s: Source Address    : Bcn T : Maj. V : Lan St : Lcl Rg : Mon Err : Frame Correl : \n",
 	  dev->name) ; 
 	
 	for (i = 0 ; i < 6 ; i++)
 		addr[i] = readb(opt+offsetof(struct olympic_parameters_table, source_addr) + i);
-	size += sprintf(buffer+size, "%6s: %pM : %04x  : %04x   : %04x   : %04x   : %04x    :     %04x     : \n",
+	seq_printf(m, "%6s: %pM : %04x  : %04x   : %04x   : %04x   : %04x    :     %04x     : \n",
 	  dev->name, addr,
 	  swab16(readw(opt+offsetof(struct olympic_parameters_table, beacon_type))),
 	  swab16(readw(opt+offsetof(struct olympic_parameters_table, major_vector))),
@@ -1680,12 +1677,12 @@
 	  swab16(readw(opt+offsetof(struct olympic_parameters_table, mon_error))),
 	  swab16(readw(opt+offsetof(struct olympic_parameters_table, frame_correl))));
 
-	size += sprintf(buffer+size, "%6s: Beacon Details :  Tx  :  Rx  : NAUN Node Address : NAUN Node Phys : \n",
+	seq_printf(m, "%6s: Beacon Details :  Tx  :  Rx  : NAUN Node Address : NAUN Node Phys : \n",
 	  dev->name) ; 
 
 	for (i = 0 ; i < 6 ; i++)
 		addr[i] = readb(opt+offsetof(struct olympic_parameters_table, beacon_naun) + i);
-	size += sprintf(buffer+size, "%6s:                :  %02x  :  %02x  : %pM : %02x:%02x:%02x:%02x    : \n",
+	seq_printf(m, "%6s:                :  %02x  :  %02x  : %pM : %02x:%02x:%02x:%02x    : \n",
 	  dev->name,
 	  swab16(readw(opt+offsetof(struct olympic_parameters_table, beacon_transmit))),
 	  swab16(readw(opt+offsetof(struct olympic_parameters_table, beacon_receive))),
@@ -1695,19 +1692,21 @@
 	  readb(opt+offsetof(struct olympic_parameters_table, beacon_phys)+2),
 	  readb(opt+offsetof(struct olympic_parameters_table, beacon_phys)+3));
 
-	len=size;
-	pos=begin+size;
-	if (pos<offset) {
-		len=0;
-		begin=pos;
-	}
-	*start=buffer+(offset-begin);	/* Start of wanted data */
-	len-=(offset-begin);		/* Start slop */
-	if(len>length)
-		len=length;		/* Ending slop */
-	return len;
+	return 0;
+}
+
+static int olympic_proc_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, olympic_proc_show, PDE(inode)->data);
 }
 
+static const struct file_operations olympic_proc_ops = {
+	.open		= olympic_proc_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
 static void __devexit olympic_remove_one(struct pci_dev *pdev) 
 {
 	struct net_device *dev = pci_get_drvdata(pdev) ; 
diff -druN linux-2.6.39-libre/drivers/net/tulip/21142.c linux-3.0-rc7-libre/drivers/net/tulip/21142.c
--- linux-2.6.39-libre/drivers/net/tulip/21142.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/tulip/21142.c	2011-07-11 19:51:52.000000000 -0400
@@ -122,8 +122,8 @@
 	tp->nway = tp->mediasense = 1;
 	tp->nwayset = tp->lpar = 0;
 	if (tulip_debug > 1)
-		printk(KERN_DEBUG "%s: Restarting 21143 autonegotiation, csr14=%08x\n",
-		       dev->name, csr14);
+		netdev_dbg(dev, "Restarting 21143 autonegotiation, csr14=%08x\n",
+			   csr14);
 	iowrite32(0x0001, ioaddr + CSR13);
 	udelay(100);
 	iowrite32(csr14, ioaddr + CSR14);
@@ -206,14 +206,14 @@
 #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 %08x\n",
-			       dev->name, ioread32(ioaddr + CSR5));
+			netdev_dbg(dev, " Restarting Tx and Rx, CSR5 is %08x\n",
+				   ioread32(ioaddr + CSR5));
 #endif
 		tulip_start_rxtx(tp);
 		if (tulip_debug > 2)
-			printk(KERN_DEBUG "%s:  Setting CSR6 %08x/%x CSR12 %08x\n",
-			       dev->name, tp->csr6, ioread32(ioaddr + CSR6),
-			       ioread32(ioaddr + CSR12));
+			netdev_dbg(dev, " Setting CSR6 %08x/%x CSR12 %08x\n",
+				   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) ||
diff -druN linux-2.6.39-libre/drivers/net/tulip/de2104x.c linux-3.0-rc7-libre/drivers/net/tulip/de2104x.c
--- linux-2.6.39-libre/drivers/net/tulip/de2104x.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/tulip/de2104x.c	2011-07-11 19:51:52.000000000 -0400
@@ -27,6 +27,8 @@
 
  */
 
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #define DRV_NAME		"de2104x"
 #define DRV_VERSION		"0.7"
 #define DRV_RELDATE		"Mar 17, 2004"
@@ -51,7 +53,7 @@
 
 /* These identify the driver base version and may not be removed. */
 static char version[] =
-KERN_INFO DRV_NAME " PCI Ethernet driver v" DRV_VERSION " (" DRV_RELDATE ")\n";
+"PCI Ethernet driver v" DRV_VERSION " (" DRV_RELDATE ")";
 
 MODULE_AUTHOR("Jeff Garzik <jgarzik@pobox.com>");
 MODULE_DESCRIPTION("Intel/Digital 21040/1 series PCI Ethernet driver");
@@ -73,8 +75,6 @@
 module_param (rx_copybreak, int, 0);
 MODULE_PARM_DESC (rx_copybreak, "de2104x Breakpoint at which Rx packets are copied");
 
-#define PFX			DRV_NAME ": "
-
 #define DE_DEF_MSG_ENABLE	(NETIF_MSG_DRV		| \
 				 NETIF_MSG_PROBE 	| \
 				 NETIF_MSG_LINK		| \
@@ -377,18 +377,16 @@
 static void de_rx_err_acct (struct de_private *de, unsigned rx_tail,
 			    u32 status, u32 len)
 {
-	if (netif_msg_rx_err (de))
-		printk (KERN_DEBUG
-			"%s: rx err, slot %d status 0x%x len %d\n",
-			de->dev->name, rx_tail, status, len);
+	netif_dbg(de, rx_err, de->dev,
+		  "rx err, slot %d status 0x%x len %d\n",
+		  rx_tail, status, len);
 
 	if ((status & 0x38000300) != 0x0300) {
 		/* Ingore earlier buffers. */
 		if ((status & 0xffff) != 0x7fff) {
-			if (netif_msg_rx_err(de))
-				dev_warn(&de->dev->dev,
-					 "Oversized Ethernet frame spanned multiple buffers, status %08x!\n",
-					 status);
+			netif_warn(de, rx_err, de->dev,
+				   "Oversized Ethernet frame spanned multiple buffers, status %08x!\n",
+				   status);
 			de->net_stats.rx_length_errors++;
 		}
 	} else if (status & RxError) {
@@ -435,10 +433,9 @@
 
 		copying_skb = (len <= rx_copybreak);
 
-		if (unlikely(netif_msg_rx_status(de)))
-			printk(KERN_DEBUG "%s: rx slot %d status 0x%x len %d copying? %d\n",
-			       de->dev->name, rx_tail, status, len,
-			       copying_skb);
+		netif_dbg(de, rx_status, de->dev,
+			  "rx slot %d status 0x%x len %d copying? %d\n",
+			  rx_tail, status, len, copying_skb);
 
 		buflen = copying_skb ? (len + RX_OFFSET) : de->rx_buf_sz;
 		copy_skb = dev_alloc_skb (buflen);
@@ -491,7 +488,7 @@
 	}
 
 	if (!rx_work)
-		dev_warn(&de->dev->dev, "rx work limit reached\n");
+		netdev_warn(de->dev, "rx work limit reached\n");
 
 	de->rx_tail = rx_tail;
 }
@@ -506,10 +503,9 @@
 	if ((!(status & (IntrOK|IntrErr))) || (status == 0xFFFF))
 		return IRQ_NONE;
 
-	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);
+	netif_dbg(de, intr, dev, "intr, status %08x mode %08x desc %u/%u/%u\n",
+		  status, dr32(MacMode),
+		  de->rx_tail, de->tx_head, de->tx_tail);
 
 	dw32(MacStatus, status);
 
@@ -534,9 +530,9 @@
 
 		pci_read_config_word(de->pdev, PCI_STATUS, &pci_status);
 		pci_write_config_word(de->pdev, PCI_STATUS, pci_status);
-		dev_err(&de->dev->dev,
-			"PCI bus error, status=%08x, PCI status=%04x\n",
-			status, pci_status);
+		netdev_err(de->dev,
+			   "PCI bus error, status=%08x, PCI status=%04x\n",
+			   status, pci_status);
 	}
 
 	return IRQ_HANDLED;
@@ -572,9 +568,9 @@
 
 		if (status & LastFrag) {
 			if (status & TxError) {
-				if (netif_msg_tx_err(de))
-					printk(KERN_DEBUG "%s: tx err, status 0x%x\n",
-					       de->dev->name, status);
+				netif_dbg(de, tx_err, de->dev,
+					  "tx err, status 0x%x\n",
+					  status);
 				de->net_stats.tx_errors++;
 				if (status & TxOWC)
 					de->net_stats.tx_window_errors++;
@@ -587,9 +583,8 @@
 			} else {
 				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);
+				netif_dbg(de, tx_done, de->dev,
+					  "tx done, slot %d\n", tx_tail);
 			}
 			dev_kfree_skb_irq(skb);
 		}
@@ -646,9 +641,8 @@
 	wmb();
 
 	de->tx_head = NEXT_TX(entry);
-	if (netif_msg_tx_queued(de))
-		printk(KERN_DEBUG "%s: tx queued, slot %d, skblen %d\n",
-		       dev->name, entry, skb->len);
+	netif_dbg(de, tx_queued, dev, "tx queued, slot %d, skblen %d\n",
+		  entry, skb->len);
 
 	if (tx_free == 0)
 		netif_stop_queue(dev);
@@ -873,7 +867,7 @@
 		udelay(100);
 	}
 
-	dev_warn(&de->dev->dev, "timeout expired stopping DMA\n");
+	netdev_warn(de->dev, "timeout expired, stopping DMA\n");
 }
 
 static inline void de_start_rxtx (struct de_private *de)
@@ -907,9 +901,8 @@
 {
 	if (!netif_carrier_ok(de->dev)) {
 		netif_carrier_on(de->dev);
-		if (netif_msg_link(de))
-			dev_info(&de->dev->dev, "link up, media %s\n",
-				 media_name[de->media_type]);
+		netif_info(de, link, de->dev, "link up, media %s\n",
+			   media_name[de->media_type]);
 	}
 }
 
@@ -917,8 +910,7 @@
 {
 	if (netif_carrier_ok(de->dev)) {
 		netif_carrier_off(de->dev);
-		if (netif_msg_link(de))
-			dev_info(&de->dev->dev, "link down\n");
+		netif_info(de, link, de->dev, "link down\n");
 	}
 }
 
@@ -928,8 +920,7 @@
 	u32 macmode = dr32(MacMode);
 
 	if (de_is_running(de))
-		dev_warn(&de->dev->dev,
-			 "chip is running while changing media!\n");
+		netdev_warn(de->dev, "chip is running while changing media!\n");
 
 	if (de->de21040)
 		dw32(CSR11, FULL_DUPLEX_MAGIC);
@@ -948,18 +939,13 @@
 	else
 		macmode &= ~FullDuplex;
 
-	if (netif_msg_link(de))
-		dev_info(&de->dev->dev, "set link %s\n", media_name[media]);
-	if (netif_msg_hw(de)) {
-		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);
-	}
+	netif_info(de, link, de->dev, "set link %s\n", media_name[media]);
+	netif_info(de, hw, de->dev, "mode 0x%x, sia 0x%x,0x%x,0x%x,0x%x\n",
+		   dr32(MacMode), dr32(SIAStatus),
+		   dr32(CSR13), dr32(CSR14), dr32(CSR15));
+	netif_info(de, hw, de->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);
 }
@@ -996,9 +982,8 @@
 		if (!netif_carrier_ok(dev))
 			de_link_up(de);
 		else
-			if (netif_msg_timer(de))
-				dev_info(&dev->dev, "%s link ok, status %x\n",
-					 media_name[de->media_type], status);
+			netif_info(de, timer, dev, "%s link ok, status %x\n",
+				   media_name[de->media_type], status);
 		return;
 	}
 
@@ -1025,9 +1010,8 @@
 	de->media_timer.expires = jiffies + DE_TIMER_NO_LINK;
 	add_timer(&de->media_timer);
 
-	if (netif_msg_timer(de))
-		dev_info(&dev->dev, "no link, trying media %s, status %x\n",
-			 media_name[de->media_type], status);
+	netif_info(de, timer, 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)
@@ -1085,11 +1069,10 @@
 		if (!netif_carrier_ok(dev))
 			de_link_up(de);
 		else
-			if (netif_msg_timer(de))
-				dev_info(&dev->dev,
-					 "%s link ok, mode %x status %x\n",
-					 media_name[de->media_type],
-					 dr32(MacMode), status);
+			netif_info(de, timer, dev,
+				   "%s link ok, mode %x status %x\n",
+				   media_name[de->media_type],
+				   dr32(MacMode), status);
 		return;
 	}
 
@@ -1163,9 +1146,8 @@
 	de->media_timer.expires = jiffies + DE_TIMER_NO_LINK;
 	add_timer(&de->media_timer);
 
-	if (netif_msg_timer(de))
-		dev_info(&dev->dev, "no link, trying media %s, status %x\n",
-			 media_name[de->media_type], status);
+	netif_info(de, timer, 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)
@@ -1401,14 +1383,13 @@
 	struct de_private *de = netdev_priv(dev);
 	int rc;
 
-	if (netif_msg_ifup(de))
-		printk(KERN_DEBUG "%s: enabling interface\n", dev->name);
+	netif_dbg(de, ifup, dev, "enabling interface\n");
 
 	de->rx_buf_sz = (dev->mtu <= 1500 ? PKT_BUF_SZ : dev->mtu + 32);
 
 	rc = de_alloc_rings(de);
 	if (rc) {
-		dev_err(&dev->dev, "ring allocation failure, err=%d\n", rc);
+		netdev_err(dev, "ring allocation failure, err=%d\n", rc);
 		return rc;
 	}
 
@@ -1416,14 +1397,14 @@
 
 	rc = request_irq(dev->irq, de_interrupt, IRQF_SHARED, dev->name, dev);
 	if (rc) {
-		dev_err(&dev->dev, "IRQ %d request failure, err=%d\n",
-			dev->irq, rc);
+		netdev_err(dev, "IRQ %d request failure, err=%d\n",
+			   dev->irq, rc);
 		goto err_out_free;
 	}
 
 	rc = de_init_hw(de);
 	if (rc) {
-		dev_err(&dev->dev, "h/w init failure, err=%d\n", rc);
+		netdev_err(dev, "h/w init failure, err=%d\n", rc);
 		goto err_out_free_irq;
 	}
 
@@ -1444,8 +1425,7 @@
 	struct de_private *de = netdev_priv(dev);
 	unsigned long flags;
 
-	if (netif_msg_ifdown(de))
-		printk(KERN_DEBUG "%s: disabling interface\n", dev->name);
+	netif_dbg(de, ifdown, dev, "disabling interface\n");
 
 	del_timer_sync(&de->media_timer);
 
@@ -1466,9 +1446,9 @@
 {
 	struct de_private *de = netdev_priv(dev);
 
-	printk(KERN_DEBUG "%s: NIC status %08x mode %08x sia %08x desc %u/%u/%u\n",
-	       dev->name, dr32(MacStatus), dr32(MacMode), dr32(SIAStatus),
-	       de->rx_tail, de->tx_head, de->tx_tail);
+	netdev_dbg(dev, "NIC status %08x mode %08x sia %08x desc %u/%u/%u\n",
+		   dr32(MacStatus), dr32(MacMode), dr32(SIAStatus),
+		   de->rx_tail, de->tx_head, de->tx_tail);
 
 	del_timer_sync(&de->media_timer);
 
@@ -1518,18 +1498,17 @@
 	switch (de->media_type) {
 	case DE_MEDIA_AUI:
 		ecmd->port = PORT_AUI;
-		ecmd->speed = 5;
 		break;
 	case DE_MEDIA_BNC:
 		ecmd->port = PORT_BNC;
-		ecmd->speed = 2;
 		break;
 	default:
 		ecmd->port = PORT_TP;
-		ecmd->speed = SPEED_10;
 		break;
 	}
 
+	ethtool_cmd_speed_set(ecmd, 10);
+
 	if (dr32(MacMode) & FullDuplex)
 		ecmd->duplex = DUPLEX_FULL;
 	else
@@ -1550,9 +1529,7 @@
 	u32 new_media;
 	unsigned int media_lock;
 
-	if (ecmd->speed != SPEED_10 && ecmd->speed != 5 && ecmd->speed != 2)
-		return -EINVAL;
-	if (de->de21040 && ecmd->speed == 2)
+	if (ethtool_cmd_speed(ecmd) != 10)
 		return -EINVAL;
 	if (ecmd->duplex != DUPLEX_HALF && ecmd->duplex != DUPLEX_FULL)
 		return -EINVAL;
@@ -1696,9 +1673,8 @@
 
 	status = dr32(SIAStatus);
 	dw32(SIAStatus, (status & ~NWayState) | NWayRestart);
-	if (netif_msg_link(de))
-		dev_info(&de->dev->dev, "link nway restart, status %x,%x\n",
-			 status, dr32(SIAStatus));
+	netif_info(de, link, dev, "link nway restart, status %x,%x\n",
+		   status, dr32(SIAStatus));
 	return 0;
 }
 
@@ -1743,7 +1719,8 @@
 		de->dev->dev_addr[i] = value;
 		udelay(1);
 		if (boguscnt <= 0)
-			pr_warning(PFX "timeout reading 21040 MAC address byte %u\n", i);
+			pr_warn("timeout reading 21040 MAC address byte %u\n",
+				i);
 	}
 }
 
@@ -1929,8 +1906,10 @@
 					de->media[idx].csr14,
 					de->media[idx].csr15);
 
-		} else if (netif_msg_probe(de))
-			pr_cont("\n");
+		} else {
+			if (netif_msg_probe(de))
+				pr_cont("\n");
+		}
 
 		if (bufp > ((void *)&ee_data[DE_EEPROM_SIZE - 3]))
 			break;
@@ -1999,7 +1978,7 @@
 
 #ifndef MODULE
 	if (board_idx == 0)
-		printk("%s", version);
+		pr_info("%s\n", version);
 #endif
 
 	/* allocate a new ethernet device structure, and fill in defaults */
@@ -2041,7 +2020,7 @@
 	/* check for invalid IRQ value */
 	if (pdev->irq < 2) {
 		rc = -EIO;
-		pr_err(PFX "invalid irq (%d) for pci dev %s\n",
+		pr_err("invalid irq (%d) for pci dev %s\n",
 		       pdev->irq, pci_name(pdev));
 		goto err_out_res;
 	}
@@ -2052,12 +2031,12 @@
 	pciaddr = pci_resource_start(pdev, 1);
 	if (!pciaddr) {
 		rc = -EIO;
-		pr_err(PFX "no MMIO resource for pci dev %s\n", pci_name(pdev));
+		pr_err("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;
-		pr_err(PFX "MMIO resource (%llx) too small on pci dev %s\n",
+		pr_err("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;
@@ -2067,7 +2046,7 @@
 	regs = ioremap_nocache(pciaddr, DE_REGS_SIZE);
 	if (!regs) {
 		rc = -EIO;
-		pr_err(PFX "Cannot map PCI MMIO (%llx@%lx) on pci dev %s\n",
+		pr_err("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;
@@ -2080,7 +2059,7 @@
 	/* make sure hardware is not running */
 	rc = de_reset_mac(de);
 	if (rc) {
-		pr_err(PFX "Cannot reset MAC, pci dev %s\n", pci_name(pdev));
+		pr_err("Cannot reset MAC, pci dev %s\n", pci_name(pdev));
 		goto err_out_iomap;
 	}
 
@@ -2100,11 +2079,11 @@
 		goto err_out_iomap;
 
 	/* print info about board and interface just registered */
-	dev_info(&dev->dev, "%s at 0x%lx, %pM, IRQ %d\n",
-		 de->de21040 ? "21040" : "21041",
-		 dev->base_addr,
-		 dev->dev_addr,
-		 dev->irq);
+	netdev_info(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);
 
@@ -2192,7 +2171,7 @@
 	if (!netif_running(dev))
 		goto out_attach;
 	if ((retval = pci_enable_device(pdev))) {
-		dev_err(&dev->dev, "pci_enable_device failed in resume\n");
+		netdev_err(dev, "pci_enable_device failed in resume\n");
 		goto out;
 	}
 	pci_set_master(pdev);
@@ -2221,7 +2200,7 @@
 static int __init de_init (void)
 {
 #ifdef MODULE
-	printk("%s", version);
+	pr_info("%s\n", version);
 #endif
 	return pci_register_driver(&de_driver);
 }
diff -druN linux-2.6.39-libre/drivers/net/tulip/dmfe.c linux-3.0-rc7-libre/drivers/net/tulip/dmfe.c
--- linux-2.6.39-libre/drivers/net/tulip/dmfe.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/tulip/dmfe.c	2011-07-11 19:51:52.000000000 -0400
@@ -295,8 +295,7 @@
 /* Global variable declaration ----------------------------- */
 static int __devinitdata printed_version;
 static const char version[] __devinitconst =
-	KERN_INFO DRV_NAME ": Davicom DM9xxx net driver, version "
-	DRV_VERSION " (" DRV_RELDATE ")\n";
+	"Davicom DM9xxx net driver, version " DRV_VERSION " (" DRV_RELDATE ")";
 
 static int dmfe_debug;
 static unsigned char dmfe_media_mode = DMFE_AUTO;
@@ -381,7 +380,7 @@
 	DMFE_DBUG(0, "dmfe_init_one()", 0);
 
 	if (!printed_version++)
-		printk(version);
+		pr_info("%s\n", version);
 
 	/*
 	 *	SPARC on-board DM910x chips should be handled by the main
@@ -406,7 +405,7 @@
 	SET_NETDEV_DEV(dev, &pdev->dev);
 
 	if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32))) {
-		pr_warning("32-bit PCI DMA not available\n");
+		pr_warn("32-bit PCI DMA not available\n");
 		err = -ENODEV;
 		goto err_out_free;
 	}
@@ -2203,7 +2202,7 @@
 {
 	int rc;
 
-	printk(version);
+	pr_info("%s\n", version);
 	printed_version = 1;
 
 	DMFE_DBUG(0, "init_module() ", debug);
diff -druN linux-2.6.39-libre/drivers/net/tulip/eeprom.c linux-3.0-rc7-libre/drivers/net/tulip/eeprom.c
--- linux-2.6.39-libre/drivers/net/tulip/eeprom.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/tulip/eeprom.c	2011-07-11 19:51:52.000000000 -0400
@@ -222,8 +222,8 @@
 	        /* there is no phy information, don't even try to build mtable */
 	        if (count == 0) {
 			if (tulip_debug > 0)
-				pr_warning("%s: no phy info, aborting mtable build\n",
-					   dev->name);
+				pr_warn("%s: no phy info, aborting mtable build\n",
+					dev->name);
 		        return;
 		}
 
diff -druN linux-2.6.39-libre/drivers/net/tulip/interrupt.c linux-3.0-rc7-libre/drivers/net/tulip/interrupt.c
--- linux-2.6.39-libre/drivers/net/tulip/interrupt.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/tulip/interrupt.c	2011-07-11 19:51:52.000000000 -0400
@@ -125,12 +125,12 @@
 #endif
 
 	if (tulip_debug > 4)
-		printk(KERN_DEBUG " In tulip_rx(), entry %d %08x\n",
-		       entry, tp->rx_ring[entry].status);
+		netdev_dbg(dev, " 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");
+			netdev_dbg(dev, " In tulip_poll(), hardware disappeared\n");
 			break;
 		}
                /* Acknowledge current RX interrupt sources. */
@@ -145,9 +145,9 @@
                        if (tp->dirty_rx + RX_RING_SIZE == tp->cur_rx)
                                break;
 
-                       if (tulip_debug > 5)
-                               printk(KERN_DEBUG "%s: In tulip_rx(), entry %d %08x\n",
-                                      dev->name, entry, status);
+		       if (tulip_debug > 5)
+				netdev_dbg(dev, "In tulip_rx(), entry %d %08x\n",
+					   entry, status);
 
 		       if (++work_done >= budget)
                                goto not_done;
@@ -184,9 +184,9 @@
 					}
 			       } else {
                                 /* There was a fatal error. */
-                                       if (tulip_debug > 2)
-                                               printk(KERN_DEBUG "%s: Receive error, Rx status %08x\n",
-                                                      dev->name, status);
+				       if (tulip_debug > 2)
+						netdev_dbg(dev, "Receive error, Rx status %08x\n",
+							   status);
 					dev->stats.rx_errors++; /* end of a packet.*/
 					if (pkt_len > 1518 ||
 					    (status & RxDescRunt))
@@ -367,16 +367,16 @@
 	int received = 0;
 
 	if (tulip_debug > 4)
-		printk(KERN_DEBUG " In tulip_rx(), entry %d %08x\n",
-		       entry, tp->rx_ring[entry].status);
+		netdev_dbg(dev, "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 %08x\n",
-			       dev->name, entry, status);
+			netdev_dbg(dev, "In tulip_rx(), entry %d %08x\n",
+				   entry, status);
 		if (--rx_work_limit < 0)
 			break;
 
@@ -404,16 +404,16 @@
 				/* Ingore earlier buffers. */
 				if ((status & 0xffff) != 0x7fff) {
 					if (tulip_debug > 1)
-						dev_warn(&dev->dev,
-							 "Oversized Ethernet frame spanned multiple buffers, status %08x!\n",
-							 status);
+						netdev_warn(dev,
+							    "Oversized Ethernet frame spanned multiple buffers, status %08x!\n",
+							    status);
 					dev->stats.rx_length_errors++;
 				}
 			} else {
 				/* There was a fatal error. */
 				if (tulip_debug > 2)
-					printk(KERN_DEBUG "%s: Receive error, Rx status %08x\n",
-					       dev->name, status);
+					netdev_dbg(dev, "Receive error, Rx status %08x\n",
+						   status);
 				dev->stats.rx_errors++; /* end of a packet.*/
 				if (pkt_len > 1518 ||
 				    (status & RxDescRunt))
@@ -573,8 +573,8 @@
 #endif /*  CONFIG_TULIP_NAPI */
 
 		if (tulip_debug > 4)
-			printk(KERN_DEBUG "%s: interrupt  csr5=%#8.8x new csr5=%#8.8x\n",
-			       dev->name, csr5, ioread32(ioaddr + CSR5));
+			netdev_dbg(dev, "interrupt  csr5=%#8.8x new csr5=%#8.8x\n",
+				   csr5, ioread32(ioaddr + CSR5));
 
 
 		if (csr5 & (TxNoBuf | TxDied | TxIntr | TimerInt)) {
@@ -605,8 +605,8 @@
 					/* There was an major error, log it. */
 #ifndef final_version
 					if (tulip_debug > 1)
-						printk(KERN_DEBUG "%s: Transmit error, Tx status %08x\n",
-						       dev->name, status);
+						netdev_dbg(dev, "Transmit error, Tx status %08x\n",
+							   status);
 #endif
 					dev->stats.tx_errors++;
 					if (status & 0x4104)
@@ -804,8 +804,8 @@
 	}
 
 	if (tulip_debug > 4)
-		printk(KERN_DEBUG "%s: exiting interrupt, csr5=%#04x\n",
-		       dev->name, ioread32(ioaddr + CSR5));
+		netdev_dbg(dev, "exiting interrupt, csr5=%#04x\n",
+			   ioread32(ioaddr + CSR5));
 
 	return IRQ_HANDLED;
 }
diff -druN linux-2.6.39-libre/drivers/net/tulip/Makefile linux-3.0-rc7-libre/drivers/net/tulip/Makefile
--- linux-2.6.39-libre/drivers/net/tulip/Makefile	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/tulip/Makefile	2011-07-11 19:51:52.000000000 -0400
@@ -2,6 +2,8 @@
 # Makefile for the Linux "Tulip" family network device drivers.
 #
 
+ccflags-$(CONFIG_NET_TULIP)	:= -DDEBUG
+
 obj-$(CONFIG_PCMCIA_XIRCOM)	+= xircom_cb.o
 obj-$(CONFIG_DM9102)		+= dmfe.o
 obj-$(CONFIG_WINBOND_840)	+= winbond-840.o
diff -druN linux-2.6.39-libre/drivers/net/tulip/media.c linux-3.0-rc7-libre/drivers/net/tulip/media.c
--- linux-2.6.39-libre/drivers/net/tulip/media.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/tulip/media.c	2011-07-11 19:51:52.000000000 -0400
@@ -182,8 +182,8 @@
 		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 %02x\n",
-				       dev->name, p[1]);
+				netdev_dbg(dev, "Using a 21140 non-MII transceiver with control setting %02x\n",
+					   p[1]);
 			dev->if_port = p[0];
 			if (startup)
 				iowrite32(mtable->csr12dir | 0x100, ioaddr + CSR12);
@@ -204,15 +204,14 @@
 				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);
+					netdev_dbg(dev, "Resetting the transceiver\n");
 				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 %04x/%04x\n",
-				       dev->name, medianame[dev->if_port],
-				       setup[0], setup[1]);
+				netdev_dbg(dev, "21143 non-MII %s transceiver control %04x/%04x\n",
+					   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];
@@ -239,8 +238,8 @@
 				if (startup) iowrite32(csr13val, ioaddr + CSR13);
 			}
 			if (tulip_debug > 1)
-				printk(KERN_DEBUG "%s:  Setting CSR15 to %08x/%08x\n",
-				       dev->name, csr15dir, csr15val);
+				netdev_dbg(dev, "Setting CSR15 to %08x/%08x\n",
+					   csr15dir, csr15val);
 			if (mleaf->type == 4)
 				new_csr6 = 0x82020000 | ((setup[2] & 0x71) << 18);
 			else
@@ -316,9 +315,9 @@
 				if (tp->mii_advertise == 0)
 					tp->mii_advertise = tp->advertising[phy_num];
 				if (tulip_debug > 1)
-					printk(KERN_DEBUG "%s:  Advertising %04x on MII %d\n",
-					       dev->name, tp->mii_advertise,
-					       tp->phys[phy_num]);
+					netdev_dbg(dev, " Advertising %04x on MII %d\n",
+						   tp->mii_advertise,
+						   tp->phys[phy_num]);
 				tulip_mdio_write(dev, tp->phys[phy_num], 4, tp->mii_advertise);
 			}
 			break;
@@ -335,8 +334,7 @@
 				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);
+					netdev_dbg(dev, "Resetting the transceiver\n");
 				for (i = 0; i < rst[0]; i++)
 					iowrite32(get_u16(rst + 1 + (i<<1)) << 16, ioaddr + CSR15);
 			}
@@ -344,20 +342,21 @@
 			break;
 		}
 		default:
-			printk(KERN_DEBUG "%s:  Invalid media table selection %d\n",
-			       dev->name, mleaf->type);
+			netdev_dbg(dev, " Invalid media table selection %d\n",
+				   mleaf->type);
 			new_csr6 = 0x020E0000;
 		}
 		if (tulip_debug > 1)
-			printk(KERN_DEBUG "%s: Using media type %s, CSR12 is %02x\n",
-			       dev->name, medianame[dev->if_port],
+			netdev_dbg(dev, "Using media type %s, CSR12 is %02x\n",
+				   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]);
+			netdev_dbg(dev, "PNIC PHY status is %3.3x, media %s\n",
+				   ioread32(ioaddr + 0xB8),
+				   medianame[dev->if_port]);
 		if (tp->mii_cnt) {
 			new_csr6 = 0x810C0000;
 			iowrite32(0x0001, ioaddr + CSR15);
@@ -388,9 +387,9 @@
 		} else
 			new_csr6 = 0x03860000;
 		if (tulip_debug > 1)
-			printk(KERN_DEBUG "%s: No media description table, assuming %s transceiver, CSR12 %02x\n",
-			       dev->name, medianame[dev->if_port],
-			       ioread32(ioaddr + CSR12));
+			netdev_dbg(dev, "No media description table, assuming %s transceiver, CSR12 %02x\n",
+				   medianame[dev->if_port],
+				   ioread32(ioaddr + CSR12));
 	}
 
 	tp->csr6 = new_csr6 | (tp->csr6 & 0xfdff) | (tp->full_duplex ? 0x0200 : 0);
@@ -504,8 +503,8 @@
 
 		/* Fixup for DLink with miswired PHY. */
 		if (mii_advert != to_advert) {
-			printk(KERN_DEBUG "tulip%d:  Advertising %04x on PHY %d, previously advertising %04x\n",
-			       board_idx, to_advert, phy, mii_advert);
+			pr_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);
 		}
 
diff -druN linux-2.6.39-libre/drivers/net/tulip/pnic2.c linux-3.0-rc7-libre/drivers/net/tulip/pnic2.c
--- linux-2.6.39-libre/drivers/net/tulip/pnic2.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/tulip/pnic2.c	2011-07-11 19:51:52.000000000 -0400
@@ -125,8 +125,8 @@
         csr14 |= 0x00001184;
 
 	if (tulip_debug > 1)
-		printk(KERN_DEBUG "%s: Restarting PNIC2 autonegotiation, csr14=%08x\n",
-		       dev->name, csr14);
+		netdev_dbg(dev, "Restarting PNIC2 autonegotiation, csr14=%08x\n",
+			   csr14);
 
         /* tell pnic2_lnk_change we are doing an nway negotiation */
 	dev->if_port = 0;
@@ -137,8 +137,7 @@
 
 	tp->csr6 = ioread32(ioaddr + CSR6);
 	if (tulip_debug > 1)
-		printk(KERN_DEBUG "%s: On Entry to Nway, csr6=%08x\n",
-		       dev->name, tp->csr6);
+		netdev_dbg(dev, "On Entry to Nway, csr6=%08x\n", tp->csr6);
 
         /* mask off any bits not to touch
          * comment at top of file explains mask value
@@ -271,9 +270,10 @@
 			iowrite32(1, ioaddr + CSR13);
 
 			if (tulip_debug > 2)
-			        printk(KERN_DEBUG "%s: Setting CSR6 %08x/%x CSR12 %08x\n",
-				       dev->name, tp->csr6,
-				       ioread32(ioaddr + CSR6), ioread32(ioaddr + CSR12));
+				netdev_dbg(dev, "Setting CSR6 %08x/%x CSR12 %08x\n",
+					   tp->csr6,
+					   ioread32(ioaddr + CSR6),
+					   ioread32(ioaddr + CSR12));
 
 			/* now the following actually writes out the
 			 * new csr6 values
@@ -324,7 +324,7 @@
 		/* Link blew? Maybe restart NWay. */
 
 		if (tulip_debug > 2)
-			printk(KERN_DEBUG "%s: Ugh! Link blew?\n", dev->name);
+			netdev_dbg(dev, "Ugh! Link blew?\n");
 
 		del_timer_sync(&tp->timer);
 		pnic2_start_nway(dev);
diff -druN linux-2.6.39-libre/drivers/net/tulip/pnic.c linux-3.0-rc7-libre/drivers/net/tulip/pnic.c
--- linux-2.6.39-libre/drivers/net/tulip/pnic.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/tulip/pnic.c	2011-07-11 19:51:52.000000000 -0400
@@ -40,8 +40,8 @@
 			new_csr6 |= 0x00000200;
 		}
 		if (tulip_debug > 1)
-			printk(KERN_DEBUG "%s: PNIC autonegotiated status %08x, %s\n",
-			       dev->name, phy_reg, medianame[dev->if_port]);
+			netdev_dbg(dev, "PNIC autonegotiated status %08x, %s\n",
+				   phy_reg, medianame[dev->if_port]);
 		if (tp->csr6 != new_csr6) {
 			tp->csr6 = new_csr6;
 			/* Restart Tx */
@@ -58,8 +58,8 @@
 	int phy_reg = ioread32(ioaddr + 0xB8);
 
 	if (tulip_debug > 1)
-		printk(KERN_DEBUG "%s: PNIC link changed state %08x, CSR5 %08x\n",
-		       dev->name, phy_reg, csr5);
+		netdev_dbg(dev, "PNIC link changed state %08x, CSR5 %08x\n",
+			   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,8 +114,8 @@
 		int csr5 = ioread32(ioaddr + CSR5);
 
 		if (tulip_debug > 1)
-			printk(KERN_DEBUG "%s: PNIC timer PHY status %08x, %s CSR5 %08x\n",
-			       dev->name, phy_reg, medianame[dev->if_port], csr5);
+			netdev_dbg(dev, "PNIC timer PHY status %08x, %s CSR5 %08x\n",
+				   phy_reg, medianame[dev->if_port], csr5);
 		if (phy_reg & 0x04000000) {	/* Remote link fault */
 			iowrite32(0x0201F078, ioaddr + 0xB8);
 			next_tick = 1*HZ;
@@ -125,11 +125,11 @@
 			next_tick = 60*HZ;
 		} else if (csr5 & TPLnkFail) { /* 100baseTx link beat */
 			if (tulip_debug > 1)
-				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));
+				netdev_dbg(dev, "%s link beat failed, CSR12 %04x, CSR5 %08x, PHY %03x\n",
+					   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)) {
diff -druN linux-2.6.39-libre/drivers/net/tulip/timer.c linux-3.0-rc7-libre/drivers/net/tulip/timer.c
--- linux-2.6.39-libre/drivers/net/tulip/timer.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/tulip/timer.c	2011-07-11 19:51:52.000000000 -0400
@@ -28,11 +28,11 @@
 	unsigned long flags;
 
 	if (tulip_debug > 2) {
-		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));
+		netdev_dbg(dev, "Media selection tick, %s, status %08x mode %08x SIA %08x %08x %08x %08x\n",
+			   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 @@
 			   Assume this a generic MII or SYM transceiver. */
 			next_tick = 60*HZ;
 			if (tulip_debug > 2)
-				printk(KERN_DEBUG "%s: network media monitor CSR6 %08x CSR12 0x%02x\n",
-				       dev->name,
-				       ioread32(ioaddr + CSR6), csr12 & 0xff);
+				netdev_dbg(dev, "network media monitor CSR6 %08x CSR12 0x%02x\n",
+					   ioread32(ioaddr + CSR6),
+					   csr12 & 0xff);
 			break;
 		}
 		mleaf = &tp->mtable->mleaf[tp->cur_index];
@@ -62,8 +62,8 @@
 			s8 bitnum = p[offset];
 			if (p[offset+1] & 0x80) {
 				if (tulip_debug > 1)
-					printk(KERN_DEBUG "%s: Transceiver monitor tick CSR12=%#02x, no media sense\n",
-					       dev->name, csr12);
+					netdev_dbg(dev, "Transceiver monitor tick CSR12=%#02x, no media sense\n",
+						   csr12);
 				if (mleaf->type == 4) {
 					if (mleaf->media == 3 && (csr12 & 0x02))
 						goto select_next_media;
@@ -71,17 +71,16 @@
 				break;
 			}
 			if (tulip_debug > 2)
-				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));
+				netdev_dbg(dev, "Transceiver monitor tick: CSR12=%#02x bit %d is %d, expecting %d\n",
+					   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,
-					       medianame[mleaf->media & MEDIA_MASK]);
+					netdev_dbg(dev, "Link beat detected for %s\n",
+						   medianame[mleaf->media & MEDIA_MASK]);
 				if ((p[2] & 0x61) == 0x01)	/* Bogus Znyx board. */
 					goto actually_mii;
 				netif_carrier_on(dev);
@@ -99,10 +98,9 @@
 			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],
-				       medianame[tp->mtable->mleaf[tp->cur_index].media]);
+				netdev_dbg(dev, "No link beat on media %s, trying transceiver type %s\n",
+					   medianame[mleaf->media & MEDIA_MASK],
+					   medianame[tp->mtable->mleaf[tp->cur_index].media]);
 			tulip_select_media(dev, 0);
 			/* Restart the transmit process. */
 			tulip_restart_rxtx(tp);
@@ -166,10 +164,9 @@
 	int next_tick = 60*HZ;
 
 	if (tulip_debug > 1)
-		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));
+		netdev_dbg(dev, "Comet link status %04x partner capability %04x\n",
+			   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 -druN linux-2.6.39-libre/drivers/net/tulip/tulip_core.c linux-3.0-rc7-libre/drivers/net/tulip/tulip_core.c
--- linux-2.6.39-libre/drivers/net/tulip/tulip_core.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/tulip/tulip_core.c	2011-07-11 19:51:52.000000000 -0400
@@ -12,6 +12,7 @@
 	Please submit bugs to http://bugzilla.kernel.org/ .
 */
 
+#define pr_fmt(fmt) "tulip: " fmt
 
 #define DRV_NAME	"tulip"
 #ifdef CONFIG_TULIP_NAPI
@@ -119,8 +120,6 @@
 module_param_array(options, int, NULL, 0);
 module_param_array(full_duplex, int, NULL, 0);
 
-#define PFX DRV_NAME ": "
-
 #ifdef TULIP_DEBUG
 int tulip_debug = TULIP_DEBUG;
 #else
@@ -331,8 +330,7 @@
 	udelay(100);
 
 	if (tulip_debug > 1)
-		printk(KERN_DEBUG "%s: tulip_up(), irq==%d\n",
-		       dev->name, dev->irq);
+		netdev_dbg(dev, "tulip_up(), irq==%d\n", dev->irq);
 
 	iowrite32(tp->rx_ring_dma, ioaddr + CSR3);
 	iowrite32(tp->tx_ring_dma, ioaddr + CSR4);
@@ -499,10 +497,10 @@
 	iowrite32(0, ioaddr + CSR2);		/* Rx poll demand */
 
 	if (tulip_debug > 2) {
-		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));
+		netdev_dbg(dev, "Done tulip_up(), CSR0 %08x, CSR5 %08x CSR6 %08x\n",
+			   ioread32(ioaddr + CSR0),
+			   ioread32(ioaddr + CSR5),
+			   ioread32(ioaddr + CSR6));
 	}
 
 	/* Set the timer to switch to check for link beat and perhaps switch
@@ -843,8 +841,7 @@
 	tulip_down (dev);
 
 	if (tulip_debug > 1)
-		dev_printk(KERN_DEBUG, &dev->dev,
-			   "Shutting down ethercard, status was %02x\n",
+		netdev_dbg(dev, "Shutting down ethercard, status was %02x\n",
 			   ioread32 (ioaddr + CSR5));
 
 	free_irq (dev->irq, dev);
@@ -1207,7 +1204,7 @@
 	u32 csr0;
 
 	if (tulip_debug > 3)
-		printk(KERN_DEBUG "%s: tulip_mwi_config()\n", pci_name(pdev));
+		netdev_dbg(dev, "tulip_mwi_config()\n");
 
 	tp->csr0 = csr0 = 0;
 
@@ -1269,8 +1266,8 @@
 out:
 	tp->csr0 = csr0;
 	if (tulip_debug > 2)
-		printk(KERN_DEBUG "%s: MWI config cacheline=%d, csr0=%08x\n",
-		       pci_name(pdev), cache, csr0);
+		netdev_dbg(dev, "MWI config cacheline=%d, csr0=%08x\n",
+			   cache, csr0);
 }
 #endif
 
@@ -1340,13 +1337,13 @@
 	 */
 
         if (pdev->subsystem_vendor == PCI_VENDOR_ID_LMC) {
-		pr_err(PFX "skipping LMC card\n");
+		pr_err("skipping LMC card\n");
 		return -ENODEV;
 	} else if (pdev->subsystem_vendor == PCI_VENDOR_ID_SBE &&
 		   (pdev->subsystem_device == PCI_SUBDEVICE_ID_SBE_T3E3 ||
 		    pdev->subsystem_device == PCI_SUBDEVICE_ID_SBE_2T3E3_P0 ||
 		    pdev->subsystem_device == PCI_SUBDEVICE_ID_SBE_2T3E3_P1)) {
-		pr_err(PFX "skipping SBE T3E3 port\n");
+		pr_err("skipping SBE T3E3 port\n");
 		return -ENODEV;
 	}
 
@@ -1362,13 +1359,13 @@
 
 		if (pdev->vendor == 0x1282 && pdev->device == 0x9100 &&
 		    pdev->revision < 0x30) {
-			pr_info(PFX "skipping early DM9100 with Crc bug (use dmfe)\n");
+			pr_info("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))) {
-			pr_info(PFX "skipping DM910x expansion card (use dmfe)\n");
+			pr_info("skipping DM910x expansion card (use dmfe)\n");
 			return -ENODEV;
 		}
 	}
@@ -1415,16 +1412,14 @@
 
 	i = pci_enable_device(pdev);
 	if (i) {
-		pr_err(PFX "Cannot enable tulip board #%d, aborting\n",
-		       board_idx);
+		pr_err("Cannot enable tulip board #%d, aborting\n", board_idx);
 		return i;
 	}
 
 	/* The chip will fail to enter a low-power state later unless
 	 * first explicitly commanded into D0 */
 	if (pci_set_power_state(pdev, PCI_D0)) {
-		printk (KERN_NOTICE PFX
-			"Failed to set power state to D0\n");
+		pr_notice("Failed to set power state to D0\n");
 	}
 
 	irq = pdev->irq;
@@ -1432,13 +1427,13 @@
 	/* alloc_etherdev ensures aligned and zeroed private structures */
 	dev = alloc_etherdev (sizeof (*tp));
 	if (!dev) {
-		pr_err(PFX "ether device alloc failed, aborting\n");
+		pr_err("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) {
-		pr_err(PFX "%s: I/O region (0x%llx@0x%llx) too small, aborting\n",
+		pr_err("%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));
@@ -1483,7 +1478,8 @@
 		if (sig == 0x09811317) {
 			tp->flags |= COMET_PM;
 			tp->wolinfo.supported = WAKE_PHY | WAKE_MAGIC;
-			printk(KERN_INFO "tulip_init_one: Enabled WOL support for AN983B\n");
+			pr_info("%s: Enabled WOL support for AN983B\n",
+				__func__);
 		}
 	}
 	tp->pdev = pdev;
@@ -1879,7 +1875,7 @@
 		tulip_set_wolopts(pdev, tp->wolinfo.wolopts);
 		rc = pci_enable_wake(pdev, pstate, tp->wolinfo.wolopts);
 		if (rc)
-			printk("tulip: pci_enable_wake failed (%d)\n", rc);
+			pr_err("pci_enable_wake failed (%d)\n", rc);
 	}
 	pci_set_power_state(pdev, pstate);
 
@@ -1905,12 +1901,12 @@
 		return 0;
 
 	if ((retval = pci_enable_device(pdev))) {
-		pr_err(PFX "pci_enable_device failed in resume\n");
+		pr_err("pci_enable_device failed in resume\n");
 		return retval;
 	}
 
 	if ((retval = request_irq(dev->irq, tulip_interrupt, IRQF_SHARED, dev->name, dev))) {
-		pr_err(PFX "request_irq failed in resume\n");
+		pr_err("request_irq failed in resume\n");
 		return retval;
 	}
 
diff -druN linux-2.6.39-libre/drivers/net/tulip/tulip.h linux-3.0-rc7-libre/drivers/net/tulip/tulip.h
--- linux-2.6.39-libre/drivers/net/tulip/tulip.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/tulip/tulip.h	2011-07-11 19:51:52.000000000 -0400
@@ -547,11 +547,9 @@
 			udelay(10);
 
 		if (!i)
-			printk(KERN_DEBUG "%s: tulip_stop_rxtx() failed"
-					" (CSR5 0x%x CSR6 0x%x)\n",
-					pci_name(tp->pdev),
-					ioread32(ioaddr + CSR5),
-					ioread32(ioaddr + CSR6));
+			netdev_dbg(tp->dev, "tulip_stop_rxtx() failed (CSR5 0x%x CSR6 0x%x)\n",
+				   ioread32(ioaddr + CSR5),
+				   ioread32(ioaddr + CSR6));
 	}
 }
 
diff -druN linux-2.6.39-libre/drivers/net/tulip/uli526x.c linux-3.0-rc7-libre/drivers/net/tulip/uli526x.c
--- linux-2.6.39-libre/drivers/net/tulip/uli526x.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/tulip/uli526x.c	2011-07-11 19:51:52.000000000 -0400
@@ -209,8 +209,7 @@
 /* Global variable declaration ----------------------------- */
 static int __devinitdata printed_version;
 static const char version[] __devinitconst =
-	KERN_INFO DRV_NAME ": ULi M5261/M5263 net driver, version "
-	DRV_VERSION " (" DRV_RELDATE ")\n";
+	"ULi M5261/M5263 net driver, version " DRV_VERSION " (" DRV_RELDATE ")";
 
 static int uli526x_debug;
 static unsigned char uli526x_media_mode = ULI526X_AUTO;
@@ -283,7 +282,7 @@
 	ULI526X_DBUG(0, "uli526x_init_one()", 0);
 
 	if (!printed_version++)
-		printk(version);
+		pr_info("%s\n", version);
 
 	/* Init network device */
 	dev = alloc_etherdev(sizeof(*db));
@@ -292,7 +291,7 @@
 	SET_NETDEV_DEV(dev, &pdev->dev);
 
 	if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32))) {
-		pr_warning("32-bit PCI DMA not available\n");
+		pr_warn("32-bit PCI DMA not available\n");
 		err = -ENODEV;
 		goto err_out_free;
 	}
@@ -390,9 +389,9 @@
 	if (err)
 		goto err_out_res;
 
-	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);
+	netdev_info(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);
 
@@ -524,7 +523,7 @@
 		}
 	}
 	if(phy_tmp == 32)
-		pr_warning("Can not find the phy address!!!");
+		pr_warn("Can not find the phy address!!!\n");
 	/* Parser SROM and media mode */
 	db->media_mode = uli526x_media_mode;
 
@@ -590,7 +589,7 @@
 
 	/* Too large packet check */
 	if (skb->len > MAX_PACKET_SIZE) {
-		pr_err("big packet = %d\n", (u16)skb->len);
+		netdev_err(dev, "big packet = %d\n", (u16)skb->len);
 		dev_kfree_skb(skb);
 		return NETDEV_TX_OK;
 	}
@@ -600,7 +599,7 @@
 	/* No Tx resource check, it never happen nromally */
 	if (db->tx_packet_cnt >= TX_FREE_DESC_CNT) {
 		spin_unlock_irqrestore(&db->lock, flags);
-		pr_err("No Tx resource %ld\n", db->tx_packet_cnt);
+		netdev_err(dev, "No Tx resource %ld\n", db->tx_packet_cnt);
 		return NETDEV_TX_BUSY;
 	}
 
@@ -667,15 +666,6 @@
 	/* free allocated rx buffer */
 	uli526x_free_rxbuffer(db);
 
-#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);
-#endif
-
 	return 0;
 }
 
@@ -755,7 +745,6 @@
 	txptr = db->tx_remove_ptr;
 	while(db->tx_packet_cnt) {
 		tdes0 = le32_to_cpu(txptr->tdes0);
-		/* printk(DRV_NAME ": tdes0=%x\n", tdes0); */
 		if (tdes0 & 0x80000000)
 			break;
 
@@ -765,7 +754,6 @@
 
 		/* Transmit statistic counter */
 		if ( tdes0 != 0x7fffffff ) {
-			/* printk(DRV_NAME ": 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) {
@@ -838,7 +826,6 @@
 			/* error summary bit check */
 			if (rdes0 & 0x8000) {
 				/* This is a error packet */
-				//printk(DRV_NAME ": rdes0: %lx\n", rdes0);
 				dev->stats.rx_errors++;
 				if (rdes0 & 1)
 					dev->stats.rx_fifo_errors++;
@@ -945,12 +932,12 @@
 
 	ecmd->transceiver = XCVR_EXTERNAL;
 
-	ecmd->speed = 10;
+	ethtool_cmd_speed_set(ecmd, SPEED_10);
 	ecmd->duplex = DUPLEX_HALF;
 
 	if(db->op_mode==ULI526X_100MHF || db->op_mode==ULI526X_100MFD)
 	{
-		ecmd->speed = 100;
+		ethtool_cmd_speed_set(ecmd, SPEED_100);
 	}
 	if(db->op_mode==ULI526X_10MFD || db->op_mode==ULI526X_100MFD)
 	{
@@ -958,7 +945,7 @@
 	}
 	if(db->link_failed)
 	{
-		ecmd->speed = -1;
+		ethtool_cmd_speed_set(ecmd, -1);
 		ecmd->duplex = -1;
 	}
 
@@ -1024,7 +1011,6 @@
 	struct net_device *dev = (struct net_device *) data;
 	struct uli526x_board_info *db = netdev_priv(dev);
  	unsigned long flags;
-	u8 TmpSpeed=10;
 
 	//ULI526X_DBUG(0, "uli526x_timer()", 0);
 	spin_lock_irqsave(&db->lock, flags);
@@ -1047,8 +1033,7 @@
 		if ( time_after(jiffies, dev_trans_start(dev) + ULI526X_TX_TIMEOUT) ) {
 			db->reset_TXtimeout++;
 			db->wait_reset = 1;
-			printk( "%s: Tx timeout - resetting\n",
-			       dev->name);
+			netdev_err(dev, " Tx timeout - resetting\n");
 		}
 	}
 
@@ -1070,7 +1055,7 @@
 		/* Link Failed */
 		ULI526X_DBUG(0, "Link Failed", tmp_cr12);
 		netif_carrier_off(dev);
-		pr_info("%s NIC Link is Down\n",dev->name);
+		netdev_info(dev, "NIC Link is Down\n");
 		db->link_failed = 1;
 
 		/* For Force 10/100M Half/Full mode: Enable Auto-Nego mode */
@@ -1096,18 +1081,13 @@
 
 			if(db->link_failed==0)
 			{
-				if(db->op_mode==ULI526X_100MHF || db->op_mode==ULI526X_100MFD)
-				{
-					TmpSpeed = 100;
-				}
-				if(db->op_mode==ULI526X_10MFD || db->op_mode==ULI526X_100MFD)
-				{
-					pr_info("%s NIC Link is Up %d Mbps Full duplex\n",dev->name,TmpSpeed);
-				}
-				else
-				{
-					pr_info("%s NIC Link is Up %d Mbps Half duplex\n",dev->name,TmpSpeed);
-				}
+				netdev_info(dev, "NIC Link is Up %d Mbps %s duplex\n",
+					    (db->op_mode == ULI526X_100MHF ||
+					     db->op_mode == ULI526X_100MFD)
+					    ? 100 : 10,
+					    (db->op_mode == ULI526X_10MFD ||
+					     db->op_mode == ULI526X_100MFD)
+					    ? "Full" : "Half");
 				netif_carrier_on(dev);
 			}
 			/* SHOW_MEDIA_TYPE(db->op_mode); */
@@ -1116,7 +1096,7 @@
 		{
 			if(db->init==1)
 			{
-				pr_info("%s NIC Link is Down\n",dev->name);
+				netdev_info(dev, "NIC Link is Down\n");
 				netif_carrier_off(dev);
 			}
 		}
@@ -1242,7 +1222,7 @@
 
 	err = pci_set_power_state(pdev, PCI_D0);
 	if (err) {
-		dev_warn(&dev->dev, "Could not put device into D0\n");
+		netdev_warn(dev, "Could not put device into D0\n");
 		return err;
 	}
 
@@ -1443,7 +1423,7 @@
 		update_cr6(db->cr6_data, dev->base_addr);
 		dev->trans_start = jiffies;
 	} else
-		pr_err("No Tx resource - Send_filter_frame!\n");
+		netdev_err(dev, "No Tx resource - Send_filter_frame!\n");
 }
 
 
@@ -1540,7 +1520,6 @@
 		else
 			phy_mode = 0x1000;
 
-		/* printk(DRV_NAME ": Phy_mode %x ",phy_mode); */
 		switch (phy_mode) {
 		case 0x1000: db->op_mode = ULI526X_10MHF; break;
 		case 0x2000: db->op_mode = ULI526X_10MFD; break;
@@ -1829,7 +1808,7 @@
 static int __init uli526x_init_module(void)
 {
 
-	printk(version);
+	pr_info("%s\n", version);
 	printed_version = 1;
 
 	ULI526X_DBUG(0, "init_module() ", debug);
diff -druN linux-2.6.39-libre/drivers/net/tulip/winbond-840.c linux-3.0-rc7-libre/drivers/net/tulip/winbond-840.c
--- linux-2.6.39-libre/drivers/net/tulip/winbond-840.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/tulip/winbond-840.c	2011-07-11 19:51:52.000000000 -0400
@@ -44,6 +44,8 @@
 	* Wake-On-LAN
 */
 
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #define DRV_NAME	"winbond-840"
 #define DRV_VERSION	"1.01-e"
 #define DRV_RELDATE	"Sep-11-2006"
@@ -139,7 +141,7 @@
 
 /* These identify the driver base version and may not be removed. */
 static const char version[] __initconst =
-	KERN_INFO DRV_NAME ".c:v" DRV_VERSION " (2.4 port) "
+	"v" DRV_VERSION " (2.4 port) "
 	DRV_RELDATE "  Donald Becker <becker@scyld.com>\n"
 	"  http://www.scyld.com/network/drivers.html\n";
 
@@ -375,8 +377,8 @@
 	irq = pdev->irq;
 
 	if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32))) {
-		pr_warning("Winbond-840: Device %s disabled due to DMA limitations\n",
-			   pci_name(pdev));
+		pr_warn("Device %s disabled due to DMA limitations\n",
+			pci_name(pdev));
 		return -EIO;
 	}
 	dev = alloc_etherdev(sizeof(*np));
@@ -643,8 +645,7 @@
 		goto out_err;
 
 	if (debug > 1)
-		printk(KERN_DEBUG "%s: w89c840_open() irq %d\n",
-		       dev->name, dev->irq);
+		netdev_dbg(dev, "w89c840_open() irq %d\n", dev->irq);
 
 	if((i=alloc_ringdesc(dev)))
 		goto out_err;
@@ -656,7 +657,7 @@
 
 	netif_start_queue(dev);
 	if (debug > 2)
-		printk(KERN_DEBUG "%s: Done netdev_open()\n", dev->name);
+		netdev_dbg(dev, "Done netdev_open()\n");
 
 	/* Set the timer to check for link beat. */
 	init_timer(&np->timer);
@@ -785,9 +786,9 @@
 	void __iomem *ioaddr = np->base_addr;
 
 	if (debug > 2)
-		printk(KERN_DEBUG "%s: Media selection timer tick, status %08x config %08x\n",
-		       dev->name, ioread32(ioaddr + IntrStatus),
-		       ioread32(ioaddr + NetworkConfig));
+		netdev_dbg(dev, "Media selection timer tick, status %08x config %08x\n",
+			   ioread32(ioaddr + IntrStatus),
+			   ioread32(ioaddr + NetworkConfig));
 	spin_lock_irq(&np->lock);
 	update_csr6(dev, update_link(dev));
 	spin_unlock_irq(&np->lock);
@@ -1054,8 +1055,8 @@
 	spin_unlock_irq(&np->lock);
 
 	if (debug > 4) {
-		printk(KERN_DEBUG "%s: Transmit frame #%d queued in slot %d\n",
-		       dev->name, np->cur_tx, entry);
+		netdev_dbg(dev, "Transmit frame #%d queued in slot %d\n",
+			   np->cur_tx, entry);
 	}
 	return NETDEV_TX_OK;
 }
@@ -1072,8 +1073,8 @@
 		if (tx_status & 0x8000) { 	/* There was an error, log it. */
 #ifndef final_version
 			if (debug > 1)
-				printk(KERN_DEBUG "%s: Transmit error, Tx status %08x\n",
-				       dev->name, tx_status);
+				netdev_dbg(dev, "Transmit error, Tx status %08x\n",
+					   tx_status);
 #endif
 			np->stats.tx_errors++;
 			if (tx_status & 0x0104) np->stats.tx_aborted_errors++;
@@ -1085,8 +1086,8 @@
 		} else {
 #ifndef final_version
 			if (debug > 3)
-				printk(KERN_DEBUG "%s: Transmit slot %d ok, Tx status %08x\n",
-				       dev->name, entry, tx_status);
+				netdev_dbg(dev, "Transmit slot %d ok, Tx status %08x\n",
+					   entry, tx_status);
 #endif
 			np->stats.tx_bytes += np->tx_skbuff[entry]->len;
 			np->stats.collisions += (tx_status >> 3) & 15;
@@ -1129,8 +1130,7 @@
 		iowrite32(intr_status & 0x001ffff, ioaddr + IntrStatus);
 
 		if (debug > 4)
-			printk(KERN_DEBUG "%s: Interrupt, status %04x\n",
-			       dev->name, intr_status);
+			netdev_dbg(dev, "Interrupt, status %04x\n", intr_status);
 
 		if ((intr_status & (NormalIntr|AbnormalIntr)) == 0)
 			break;
@@ -1171,8 +1171,8 @@
 	} while (1);
 
 	if (debug > 3)
-		printk(KERN_DEBUG "%s: exiting interrupt, status=%#4.4x\n",
-		       dev->name, ioread32(ioaddr + IntrStatus));
+		netdev_dbg(dev, "exiting interrupt, status=%#4.4x\n",
+			   ioread32(ioaddr + IntrStatus));
 	return IRQ_RETVAL(handled);
 }
 
@@ -1185,8 +1185,8 @@
 	int work_limit = np->dirty_rx + RX_RING_SIZE - np->cur_rx;
 
 	if (debug > 4) {
-		printk(KERN_DEBUG " In netdev_rx(), entry %d status %04x\n",
-		       entry, np->rx_ring[entry].status);
+		netdev_dbg(dev, " 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,8 +1195,8 @@
 		s32 status = desc->status;
 
 		if (debug > 4)
-			printk(KERN_DEBUG "  netdev_rx() status was %08x\n",
-			       status);
+			netdev_dbg(dev, "  netdev_rx() status was %08x\n",
+				   status);
 		if (status < 0)
 			break;
 		if ((status & 0x38008300) != 0x0300) {
@@ -1211,8 +1211,8 @@
 			} else if (status & 0x8000) {
 				/* There was a fatal error. */
 				if (debug > 2)
-					printk(KERN_DEBUG "%s: Receive error, Rx status %08x\n",
-					       dev->name, status);
+					netdev_dbg(dev, "Receive error, Rx status %08x\n",
+						   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 +1225,8 @@
 
 #ifndef final_version
 			if (debug > 4)
-				printk(KERN_DEBUG "  netdev_rx() normal Rx pkt length %d status %x\n",
-				       pkt_len, status);
+				netdev_dbg(dev, "  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,10 +1251,10 @@
 #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 %02x%02x %pI4\n",
-				       &skb->data[0], &skb->data[6],
-				       skb->data[12], skb->data[13],
-				       &skb->data[14]);
+				netdev_dbg(dev, "  Rx data %pM %pM %02x%02x %pI4\n",
+					   &skb->data[0], &skb->data[6],
+					   skb->data[12], skb->data[13],
+					   &skb->data[14]);
 #endif
 			skb->protocol = eth_type_trans(skb, dev);
 			netif_rx(skb);
@@ -1292,8 +1292,7 @@
 	void __iomem *ioaddr = np->base_addr;
 
 	if (debug > 2)
-		printk(KERN_DEBUG "%s: Abnormal event, %08x\n",
-		       dev->name, intr_status);
+		netdev_dbg(dev, "Abnormal event, %08x\n", intr_status);
 	if (intr_status == 0xffffffff)
 		return;
 	spin_lock(&np->lock);
@@ -1313,8 +1312,7 @@
 		 	new = 127; /* load full packet before starting */
 		new = (np->csr6 & ~(0x7F << 14)) | (new<<14);
 #endif
-		printk(KERN_DEBUG "%s: Tx underflow, new csr6 %08x\n",
-		       dev->name, new);
+		netdev_dbg(dev, "Tx underflow, new csr6 %08x\n", new);
 		update_csr6(dev, new);
 	}
 	if (intr_status & RxDied) {		/* Missed a Rx frame. */
@@ -1487,13 +1485,12 @@
 	netif_stop_queue(dev);
 
 	if (debug > 1) {
-		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);
+		netdev_dbg(dev, "Shutting down ethercard, status was %08x Config %08x\n",
+			   ioread32(ioaddr + IntrStatus),
+			   ioread32(ioaddr + NetworkConfig));
+		netdev_dbg(dev, "Queue pointers were Tx %d / %d,  Rx %d / %d\n",
+			   np->cur_tx, np->dirty_tx,
+			   np->cur_rx, np->dirty_rx);
 	}
 
  	/* Stop the chip's Tx and Rx processes. */
diff -druN linux-2.6.39-libre/drivers/net/tulip/xircom_cb.c linux-3.0-rc7-libre/drivers/net/tulip/xircom_cb.c
--- linux-2.6.39-libre/drivers/net/tulip/xircom_cb.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/tulip/xircom_cb.c	2011-07-11 19:51:52.000000000 -0400
@@ -37,15 +37,6 @@
 #include <asm/irq.h>
 #endif
 
-#ifdef DEBUG
-#define enter(x)   printk("Enter: %s, %s line %i\n",x,__FILE__,__LINE__)
-#define leave(x)   printk("Leave: %s, %s line %i\n",x,__FILE__,__LINE__)
-#else
-#define enter(x)   do {} while (0)
-#define leave(x)   do {} while (0)
-#endif
-
-
 MODULE_DESCRIPTION("Xircom Cardbus ethernet driver");
 MODULE_AUTHOR("Arjan van de Ven <arjanv@redhat.com>");
 MODULE_LICENSE("GPL");
@@ -161,7 +152,7 @@
 };
 
 
-#ifdef DEBUG
+#if defined DEBUG && DEBUG > 1
 static void print_binary(unsigned int number)
 {
 	int i,i2;
@@ -176,7 +167,7 @@
 		if ((i&3)==0)
 			buffer[i2++]=' ';
 	}
-	printk("%s\n",buffer);
+	pr_debug("%s\n",buffer);
 }
 #endif
 
@@ -205,7 +196,6 @@
 	struct xircom_private *private;
 	unsigned long flags;
 	unsigned short tmp16;
-	enter("xircom_probe");
 
 	/* First do the PCI initialisation */
 
@@ -272,8 +262,8 @@
 		goto reg_fail;
 	}
 
-	dev_info(&dev->dev, "Xircom cardbus revision %i at irq %i\n",
-		 pdev->revision, pdev->irq);
+	netdev_info(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);
@@ -285,7 +275,6 @@
 
 	trigger_receive(private);
 
-	leave("xircom_probe");
 	return 0;
 
 reg_fail:
@@ -310,7 +299,6 @@
 	struct net_device *dev = pci_get_drvdata(pdev);
 	struct xircom_private *card = netdev_priv(dev);
 
-	enter("xircom_remove");
 	pci_free_consistent(pdev,8192,card->rx_buffer,card->rx_dma_handle);
 	pci_free_consistent(pdev,8192,card->tx_buffer,card->tx_dma_handle);
 
@@ -318,7 +306,6 @@
 	unregister_netdev(dev);
 	free_netdev(dev);
 	pci_set_drvdata(pdev, NULL);
-	leave("xircom_remove");
 }
 
 static irqreturn_t xircom_interrupt(int irq, void *dev_instance)
@@ -328,17 +315,15 @@
 	unsigned int status;
 	int i;
 
-	enter("xircom_interrupt\n");
-
 	spin_lock(&card->lock);
 	status = inl(card->io_port+CSR5);
 
-#ifdef DEBUG
+#if defined DEBUG && DEBUG > 1
 	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]);
+	pr_debug("tx status 0x%08x 0x%08x\n",
+		 card->tx_buffer[0], card->tx_buffer[4]);
+	pr_debug("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) {
@@ -348,9 +333,9 @@
 
 	if (link_status_changed(card)) {
 		int newlink;
-		printk(KERN_DEBUG "xircom_cb: Link status has changed\n");
+		netdev_dbg(dev, "Link status has changed\n");
 		newlink = link_status(card);
-		dev_info(&dev->dev, "Link is %i mbit\n", newlink);
+		netdev_info(dev, "Link is %d mbit\n", newlink);
 		if (newlink)
 			netif_carrier_on(dev);
 		else
@@ -369,9 +354,7 @@
 	for (i=0;i<NUMDESCRIPTORS;i++)
 		investigate_read_descriptor(dev,card,i,bufferoffsets[i]);
 
-
 	spin_unlock(&card->lock);
-	leave("xircom_interrupt");
 	return IRQ_HANDLED;
 }
 
@@ -382,7 +365,6 @@
 	unsigned long flags;
 	int nextdescriptor;
 	int desc;
-	enter("xircom_start_xmit");
 
 	card = netdev_priv(dev);
 	spin_lock_irqsave(&card->lock,flags);
@@ -424,13 +406,10 @@
 				netif_stop_queue(dev);
 			}
 			card->transmit_used = nextdescriptor;
-			leave("xircom-start_xmit - sent");
 			spin_unlock_irqrestore(&card->lock,flags);
 			return NETDEV_TX_OK;
 	}
 
-
-
 	/* Uh oh... no free descriptor... drop the packet */
 	netif_stop_queue(dev);
 	spin_unlock_irqrestore(&card->lock,flags);
@@ -446,18 +425,16 @@
 {
 	struct xircom_private *xp = netdev_priv(dev);
 	int retval;
-	enter("xircom_open");
-	pr_info("xircom cardbus adaptor found, registering as %s, using irq %i\n",
-		dev->name, dev->irq);
+
+	netdev_info(dev, "xircom cardbus adaptor found, using irq %i\n",
+		    dev->irq);
 	retval = request_irq(dev->irq, xircom_interrupt, IRQF_SHARED, dev->name, dev);
-	if (retval) {
-		leave("xircom_open - No IRQ");
+	if (retval)
 		return retval;
-	}
 
 	xircom_up(xp);
 	xp->open = 1;
-	leave("xircom_open");
+
 	return 0;
 }
 
@@ -466,7 +443,6 @@
 	struct xircom_private *card;
 	unsigned long flags;
 
-	enter("xircom_close");
 	card = netdev_priv(dev);
 	netif_stop_queue(dev); /* we don't want new packets */
 
@@ -486,8 +462,6 @@
 	card->open = 0;
 	free_irq(dev->irq,dev);
 
-	leave("xircom_close");
-
 	return 0;
 
 }
@@ -507,8 +481,6 @@
 {
 	unsigned int val;
 	unsigned long flags;
-	enter("initialize_card");
-
 
 	spin_lock_irqsave(&card->lock, flags);
 
@@ -534,8 +506,6 @@
 	deactivate_transmitter(card);
 
 	spin_unlock_irqrestore(&card->lock, flags);
-
-	leave("initialize_card");
 }
 
 /*
@@ -547,12 +517,9 @@
 static void trigger_transmit(struct xircom_private *card)
 {
 	unsigned int val;
-	enter("trigger_transmit");
 
 	val = 0;
 	outl(val, card->io_port + CSR1);
-
-	leave("trigger_transmit");
 }
 
 /*
@@ -565,12 +532,9 @@
 static void trigger_receive(struct xircom_private *card)
 {
 	unsigned int val;
-	enter("trigger_receive");
 
 	val = 0;
 	outl(val, card->io_port + CSR2);
-
-	leave("trigger_receive");
 }
 
 /*
@@ -581,8 +545,6 @@
 {
 	u32 address;
 	int i;
-	enter("setup_descriptors");
-
 
 	BUG_ON(card->rx_buffer == NULL);
 	BUG_ON(card->tx_buffer == NULL);
@@ -636,8 +598,6 @@
 	/* wite the transmit descriptor ring to the card */
 	address = card->tx_dma_handle;
 	outl(address, card->io_port + CSR4);	/* xmit descr list address */
-
-	leave("setup_descriptors");
 }
 
 /*
@@ -647,13 +607,10 @@
 static void remove_descriptors(struct xircom_private *card)
 {
 	unsigned int val;
-	enter("remove_descriptors");
 
 	val = 0;
 	outl(val, card->io_port + CSR3);	/* Receive descriptor address */
 	outl(val, card->io_port + CSR4);	/* Send descriptor address */
-
-	leave("remove_descriptors");
 }
 
 /*
@@ -665,21 +622,17 @@
 static int link_status_changed(struct xircom_private *card)
 {
 	unsigned int val;
-	enter("link_status_changed");
 
 	val = inl(card->io_port + CSR5);	/* Status register */
 
-	if ((val & (1 << 27)) == 0) {	/* no change */
-		leave("link_status_changed - nochange");
+	if ((val & (1 << 27)) == 0)		/* no change */
 		return 0;
-	}
 
 	/* clear the event by writing a 1 to the bit in the
 	   status register. */
 	val = (1 << 27);
 	outl(val, card->io_port + CSR5);
 
-	leave("link_status_changed - changed");
 	return 1;
 }
 
@@ -691,16 +644,12 @@
 static int transmit_active(struct xircom_private *card)
 {
 	unsigned int val;
-	enter("transmit_active");
 
 	val = inl(card->io_port + CSR5);	/* Status register */
 
-	if ((val & (7 << 20)) == 0) {	/* transmitter disabled */
-		leave("transmit_active - inactive");
+	if ((val & (7 << 20)) == 0)		/* transmitter disabled */
 		return 0;
-	}
 
-	leave("transmit_active - active");
 	return 1;
 }
 
@@ -711,17 +660,12 @@
 static int receive_active(struct xircom_private *card)
 {
 	unsigned int val;
-	enter("receive_active");
-
 
 	val = inl(card->io_port + CSR5);	/* Status register */
 
-	if ((val & (7 << 17)) == 0) {	/* receiver disabled */
-		leave("receive_active - inactive");
+	if ((val & (7 << 17)) == 0)		/* receiver disabled */
 		return 0;
-	}
 
-	leave("receive_active - active");
 	return 1;
 }
 
@@ -739,8 +683,6 @@
 {
 	unsigned int val;
 	int counter;
-	enter("activate_receiver");
-
 
 	val = inl(card->io_port + CSR6);	/* Operation mode */
 
@@ -761,7 +703,7 @@
 		udelay(50);
 		counter--;
 		if (counter <= 0)
-			pr_err("Receiver failed to deactivate\n");
+			netdev_err(card->dev, "Receiver failed to deactivate\n");
 	}
 
 	/* enable the receiver */
@@ -778,10 +720,9 @@
 		udelay(50);
 		counter--;
 		if (counter <= 0)
-			pr_err("Receiver failed to re-activate\n");
+			netdev_err(card->dev,
+				   "Receiver failed to re-activate\n");
 	}
-
-	leave("activate_receiver");
 }
 
 /*
@@ -795,7 +736,6 @@
 {
 	unsigned int val;
 	int counter;
-	enter("deactivate_receiver");
 
 	val = inl(card->io_port + CSR6);	/* Operation mode */
 	val = val & ~2;				/* disable the receiver */
@@ -809,11 +749,8 @@
 		udelay(50);
 		counter--;
 		if (counter <= 0)
-			pr_err("Receiver failed to deactivate\n");
+			netdev_err(card->dev, "Receiver failed to deactivate\n");
 	}
-
-
-	leave("deactivate_receiver");
 }
 
 
@@ -831,8 +768,6 @@
 {
 	unsigned int val;
 	int counter;
-	enter("activate_transmitter");
-
 
 	val = inl(card->io_port + CSR6);	/* Operation mode */
 
@@ -852,7 +787,8 @@
 		udelay(50);
 		counter--;
 		if (counter <= 0)
-			pr_err("Transmitter failed to deactivate\n");
+			netdev_err(card->dev,
+				   "Transmitter failed to deactivate\n");
 	}
 
 	/* enable the transmitter */
@@ -869,10 +805,9 @@
 		udelay(50);
 		counter--;
 		if (counter <= 0)
-			pr_err("Transmitter failed to re-activate\n");
+			netdev_err(card->dev,
+				   "Transmitter failed to re-activate\n");
 	}
-
-	leave("activate_transmitter");
 }
 
 /*
@@ -886,7 +821,6 @@
 {
 	unsigned int val;
 	int counter;
-	enter("deactivate_transmitter");
 
 	val = inl(card->io_port + CSR6);	/* Operation mode */
 	val = val & ~2;		/* disable the transmitter */
@@ -900,11 +834,9 @@
 		udelay(50);
 		counter--;
 		if (counter <= 0)
-			pr_err("Transmitter failed to deactivate\n");
+			netdev_err(card->dev,
+				   "Transmitter failed to deactivate\n");
 	}
-
-
-	leave("deactivate_transmitter");
 }
 
 
@@ -916,13 +848,10 @@
 static void enable_transmit_interrupt(struct xircom_private *card)
 {
 	unsigned int val;
-	enter("enable_transmit_interrupt");
 
 	val = inl(card->io_port + CSR7);	/* Interrupt enable register */
 	val |= 1;				/* enable the transmit interrupt */
 	outl(val, card->io_port + CSR7);
-
-	leave("enable_transmit_interrupt");
 }
 
 
@@ -934,13 +863,10 @@
 static void enable_receive_interrupt(struct xircom_private *card)
 {
 	unsigned int val;
-	enter("enable_receive_interrupt");
 
 	val = inl(card->io_port + CSR7);	/* Interrupt enable register */
 	val = val | (1 << 6);			/* enable the receive interrupt */
 	outl(val, card->io_port + CSR7);
-
-	leave("enable_receive_interrupt");
 }
 
 /*
@@ -951,13 +877,10 @@
 static void enable_link_interrupt(struct xircom_private *card)
 {
 	unsigned int val;
-	enter("enable_link_interrupt");
 
 	val = inl(card->io_port + CSR7);	/* Interrupt enable register */
 	val = val | (1 << 27);			/* enable the link status chage interrupt */
 	outl(val, card->io_port + CSR7);
-
-	leave("enable_link_interrupt");
 }
 
 
@@ -970,12 +893,9 @@
 static void disable_all_interrupts(struct xircom_private *card)
 {
 	unsigned int val;
-	enter("enable_all_interrupts");
 
 	val = 0;				/* disable all interrupts */
 	outl(val, card->io_port + CSR7);
-
-	leave("disable_all_interrupts");
 }
 
 /*
@@ -986,7 +906,6 @@
 static void enable_common_interrupts(struct xircom_private *card)
 {
 	unsigned int val;
-	enter("enable_link_interrupt");
 
 	val = inl(card->io_port + CSR7);	/* Interrupt enable register */
 	val |= (1<<16); /* Normal Interrupt Summary */
@@ -998,8 +917,6 @@
 	val |= (1<<2);  /* Transmit Buffer Unavailable */
 	val |= (1<<1);  /* Transmit Process Stopped */
 	outl(val, card->io_port + CSR7);
-
-	leave("enable_link_interrupt");
 }
 
 /*
@@ -1010,13 +927,11 @@
 static int enable_promisc(struct xircom_private *card)
 {
 	unsigned int val;
-	enter("enable_promisc");
 
 	val = inl(card->io_port + CSR6);
 	val = val | (1 << 6);
 	outl(val, card->io_port + CSR6);
 
-	leave("enable_promisc");
 	return 1;
 }
 
@@ -1031,7 +946,6 @@
 static int link_status(struct xircom_private *card)
 {
 	unsigned int val;
-	enter("link_status");
 
 	val = inb(card->io_port + CSR12);
 
@@ -1042,7 +956,6 @@
 
 	/* If we get here -> no link at all */
 
-	leave("link_status");
 	return 0;
 }
 
@@ -1061,8 +974,6 @@
 	unsigned long flags;
 	int i;
 
-	enter("read_mac_address");
-
 	spin_lock_irqsave(&card->lock, flags);
 
 	outl(1 << 12, card->io_port + CSR9);	/* enable boot rom access */
@@ -1090,7 +1001,6 @@
 	}
 	spin_unlock_irqrestore(&card->lock, flags);
 	pr_debug(" %pM\n", card->dev->dev_addr);
-	leave("read_mac_address");
 }
 
 
@@ -1103,8 +1013,6 @@
 {
 	unsigned long flags;
 
-	enter("transceiver_voodoo");
-
 	/* disable all powermanagement */
 	pci_write_config_dword(card->pdev, PCI_POWERMGMT, 0x0000);
 
@@ -1122,7 +1030,6 @@
         spin_unlock_irqrestore(&card->lock, flags);
 
 	netif_start_queue(card->dev);
-	leave("transceiver_voodoo");
 }
 
 
@@ -1131,8 +1038,6 @@
 	unsigned long flags;
 	int i;
 
-	enter("xircom_up");
-
 	/* disable all powermanagement */
 	pci_write_config_dword(card->pdev, PCI_POWERMGMT, 0x0000);
 
@@ -1156,87 +1061,84 @@
 	trigger_receive(card);
 	trigger_transmit(card);
 	netif_start_queue(card->dev);
-	leave("xircom_up");
 }
 
 /* Bufferoffset is in BYTES */
-static void investigate_read_descriptor(struct net_device *dev,struct xircom_private *card, int descnr, unsigned int bufferoffset)
+static void
+investigate_read_descriptor(struct net_device *dev, struct xircom_private *card,
+			    int descnr, unsigned int bufferoffset)
 {
-		int status;
-
-		enter("investigate_read_descriptor");
-		status = le32_to_cpu(card->rx_buffer[4*descnr]);
-
-		if ((status > 0)) {	/* packet received */
+	int status;
 
-			/* TODO: discard error packets */
+	status = le32_to_cpu(card->rx_buffer[4*descnr]);
 
-			short pkt_len = ((status >> 16) & 0x7ff) - 4;	/* minus 4, we don't want the CRC */
-			struct sk_buff *skb;
+	if (status > 0) {		/* packet received */
 
-			if (pkt_len > 1518) {
-				pr_err("Packet length %i is bogus\n", pkt_len);
-				pkt_len = 1518;
-			}
+		/* TODO: discard error packets */
 
-			skb = dev_alloc_skb(pkt_len + 2);
-			if (skb == NULL) {
-				dev->stats.rx_dropped++;
-				goto out;
-			}
-			skb_reserve(skb, 2);
-			skb_copy_to_linear_data(skb, (unsigned char*)&card->rx_buffer[bufferoffset / 4], pkt_len);
-			skb_put(skb, pkt_len);
-			skb->protocol = eth_type_trans(skb, dev);
-			netif_rx(skb);
-			dev->stats.rx_packets++;
-			dev->stats.rx_bytes += pkt_len;
+		short pkt_len = ((status >> 16) & 0x7ff) - 4;
+					/* minus 4, we don't want the CRC */
+		struct sk_buff *skb;
 
-		      out:
-			/* give the buffer back to the card */
-			card->rx_buffer[4*descnr] =  cpu_to_le32(0x80000000);
-			trigger_receive(card);
+		if (pkt_len > 1518) {
+			netdev_err(dev, "Packet length %i is bogus\n", pkt_len);
+			pkt_len = 1518;
 		}
 
-		leave("investigate_read_descriptor");
+		skb = dev_alloc_skb(pkt_len + 2);
+		if (skb == NULL) {
+			dev->stats.rx_dropped++;
+			goto out;
+		}
+		skb_reserve(skb, 2);
+		skb_copy_to_linear_data(skb,
+					&card->rx_buffer[bufferoffset / 4],
+					pkt_len);
+		skb_put(skb, pkt_len);
+		skb->protocol = eth_type_trans(skb, dev);
+		netif_rx(skb);
+		dev->stats.rx_packets++;
+		dev->stats.rx_bytes += pkt_len;
 
+out:
+		/* give the buffer back to the card */
+		card->rx_buffer[4*descnr] = cpu_to_le32(0x80000000);
+		trigger_receive(card);
+	}
 }
 
 
 /* Bufferoffset is in BYTES */
-static void investigate_write_descriptor(struct net_device *dev, struct xircom_private *card, int descnr, unsigned int bufferoffset)
+static void
+investigate_write_descriptor(struct net_device *dev,
+			     struct xircom_private *card,
+			     int descnr, unsigned int bufferoffset)
 {
-		int status;
-
-		enter("investigate_write_descriptor");
+	int status;
 
-		status = le32_to_cpu(card->tx_buffer[4*descnr]);
+	status = le32_to_cpu(card->tx_buffer[4*descnr]);
 #if 0
-		if (status & 0x8000) {	/* Major error */
-			pr_err("Major transmit error status %x\n", status);
-			card->tx_buffer[4*descnr] = 0;
-			netif_wake_queue (dev);
-		}
+	if (status & 0x8000) {	/* Major error */
+		pr_err("Major transmit error status %x\n", status);
+		card->tx_buffer[4*descnr] = 0;
+		netif_wake_queue (dev);
+	}
 #endif
-		if (status > 0) {	/* bit 31 is 0 when done */
-			if (card->tx_skb[descnr]!=NULL) {
-				dev->stats.tx_bytes += card->tx_skb[descnr]->len;
-				dev_kfree_skb_irq(card->tx_skb[descnr]);
-			}
-			card->tx_skb[descnr] = NULL;
-			/* Bit 8 in the status field is 1 if there was a collision */
-			if (status&(1<<8))
-				dev->stats.collisions++;
-			card->tx_buffer[4*descnr] = 0; /* descriptor is free again */
-			netif_wake_queue (dev);
-			dev->stats.tx_packets++;
+	if (status > 0) {	/* bit 31 is 0 when done */
+		if (card->tx_skb[descnr]!=NULL) {
+			dev->stats.tx_bytes += card->tx_skb[descnr]->len;
+			dev_kfree_skb_irq(card->tx_skb[descnr]);
 		}
-
-		leave("investigate_write_descriptor");
-
+		card->tx_skb[descnr] = NULL;
+		/* Bit 8 in the status field is 1 if there was a collision */
+		if (status & (1 << 8))
+			dev->stats.collisions++;
+		card->tx_buffer[4*descnr] = 0; /* descriptor is free again */
+		netif_wake_queue (dev);
+		dev->stats.tx_packets++;
+	}
 }
 
-
 static int __init xircom_init(void)
 {
 	return pci_register_driver(&xircom_ops);
diff -druN linux-2.6.39-libre/drivers/net/tun.c linux-3.0-rc7-libre/drivers/net/tun.c
--- linux-2.6.39-libre/drivers/net/tun.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/tun.c	2011-07-11 19:51:52.000000000 -0400
@@ -123,6 +123,9 @@
 	gid_t			group;
 
 	struct net_device	*dev;
+	u32			set_features;
+#define TUN_USER_FEATURES (NETIF_F_HW_CSUM|NETIF_F_TSO_ECN|NETIF_F_TSO| \
+			  NETIF_F_TSO6|NETIF_F_UFO)
 	struct fasync_struct	*fasync;
 
 	struct tap_filter       txflt;
@@ -451,12 +454,39 @@
 	return 0;
 }
 
+static u32 tun_net_fix_features(struct net_device *dev, u32 features)
+{
+	struct tun_struct *tun = netdev_priv(dev);
+
+	return (features & tun->set_features) | (features & ~TUN_USER_FEATURES);
+}
+#ifdef CONFIG_NET_POLL_CONTROLLER
+static void tun_poll_controller(struct net_device *dev)
+{
+	/*
+	 * Tun only receives frames when:
+	 * 1) the char device endpoint gets data from user space
+	 * 2) the tun socket gets a sendmsg call from user space
+	 * Since both of those are syncronous operations, we are guaranteed
+	 * never to have pending data when we poll for it
+	 * so theres nothing to do here but return.
+	 * We need this though so netpoll recognizes us as an interface that
+	 * supports polling, which enables bridge devices in virt setups to
+	 * still use netconsole
+	 */
+	return;
+}
+#endif
 static const struct net_device_ops tun_netdev_ops = {
 	.ndo_uninit		= tun_net_uninit,
 	.ndo_open		= tun_net_open,
 	.ndo_stop		= tun_net_close,
 	.ndo_start_xmit		= tun_net_xmit,
 	.ndo_change_mtu		= tun_net_change_mtu,
+	.ndo_fix_features	= tun_net_fix_features,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+	.ndo_poll_controller	= tun_poll_controller,
+#endif
 };
 
 static const struct net_device_ops tap_netdev_ops = {
@@ -465,9 +495,13 @@
 	.ndo_stop		= tun_net_close,
 	.ndo_start_xmit		= tun_net_xmit,
 	.ndo_change_mtu		= tun_net_change_mtu,
+	.ndo_fix_features	= tun_net_fix_features,
 	.ndo_set_multicast_list	= tun_net_mclist,
 	.ndo_set_mac_address	= eth_mac_addr,
 	.ndo_validate_addr	= eth_validate_addr,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+	.ndo_poll_controller	= tun_poll_controller,
+#endif
 };
 
 /* Initialize net device. */
@@ -628,8 +662,7 @@
 			kfree_skb(skb);
 			return -EINVAL;
 		}
-	} else if (tun->flags & TUN_NOCHECKSUM)
-		skb->ip_summed = CHECKSUM_UNNECESSARY;
+	}
 
 	switch (tun->flags & TUN_TYPE_MASK) {
 	case TUN_TUN_DEV:
@@ -1088,11 +1121,9 @@
 
 		tun_net_init(dev);
 
-		if (strchr(dev->name, '%')) {
-			err = dev_alloc_name(dev, dev->name);
-			if (err < 0)
-				goto err_free_sk;
-		}
+		dev->hw_features = NETIF_F_SG | NETIF_F_FRAGLIST |
+			TUN_USER_FEATURES;
+		dev->features = dev->hw_features;
 
 		err = register_netdevice(tun->dev);
 		if (err < 0)
@@ -1158,18 +1189,12 @@
 
 /* This is like a cut-down ethtool ops, except done via tun fd so no
  * privs required. */
-static int set_offload(struct net_device *dev, unsigned long arg)
+static int set_offload(struct tun_struct *tun, unsigned long arg)
 {
-	u32 old_features, features;
-
-	old_features = dev->features;
-	/* Unset features, set them as we chew on the arg. */
-	features = (old_features & ~(NETIF_F_HW_CSUM|NETIF_F_SG|NETIF_F_FRAGLIST
-				    |NETIF_F_TSO_ECN|NETIF_F_TSO|NETIF_F_TSO6
-				    |NETIF_F_UFO));
+	u32 features = 0;
 
 	if (arg & TUN_F_CSUM) {
-		features |= NETIF_F_HW_CSUM|NETIF_F_SG|NETIF_F_FRAGLIST;
+		features |= NETIF_F_HW_CSUM;
 		arg &= ~TUN_F_CSUM;
 
 		if (arg & (TUN_F_TSO4|TUN_F_TSO6)) {
@@ -1195,9 +1220,8 @@
 	if (arg)
 		return -EINVAL;
 
-	dev->features = features;
-	if (old_features != dev->features)
-		netdev_features_change(dev);
+	tun->set_features = features;
+	netdev_update_features(tun->dev);
 
 	return 0;
 }
@@ -1262,12 +1286,9 @@
 
 	case TUNSETNOCSUM:
 		/* Disable/Enable checksum */
-		if (arg)
-			tun->flags |= TUN_NOCHECKSUM;
-		else
-			tun->flags &= ~TUN_NOCHECKSUM;
 
-		tun_debug(KERN_INFO, tun, "checksum %s\n",
+		/* [unimplemented] */
+		tun_debug(KERN_INFO, tun, "ignored: set checksum %s\n",
 			  arg ? "disabled" : "enabled");
 		break;
 
@@ -1316,7 +1337,7 @@
 		break;
 #endif
 	case TUNSETOFFLOAD:
-		ret = set_offload(tun->dev, arg);
+		ret = set_offload(tun, arg);
 		break;
 
 	case TUNSETTXFILTER:
@@ -1548,7 +1569,7 @@
 {
 	cmd->supported		= 0;
 	cmd->advertising	= 0;
-	cmd->speed		= SPEED_10;
+	ethtool_cmd_speed_set(cmd, SPEED_10);
 	cmd->duplex		= DUPLEX_FULL;
 	cmd->port		= PORT_TP;
 	cmd->phy_address	= 0;
@@ -1595,30 +1616,12 @@
 #endif
 }
 
-static u32 tun_get_rx_csum(struct net_device *dev)
-{
-	struct tun_struct *tun = netdev_priv(dev);
-	return (tun->flags & TUN_NOCHECKSUM) == 0;
-}
-
-static int tun_set_rx_csum(struct net_device *dev, u32 data)
-{
-	struct tun_struct *tun = netdev_priv(dev);
-	if (data)
-		tun->flags &= ~TUN_NOCHECKSUM;
-	else
-		tun->flags |= TUN_NOCHECKSUM;
-	return 0;
-}
-
 static const struct ethtool_ops tun_ethtool_ops = {
 	.get_settings	= tun_get_settings,
 	.get_drvinfo	= tun_get_drvinfo,
 	.get_msglevel	= tun_get_msglevel,
 	.set_msglevel	= tun_set_msglevel,
 	.get_link	= ethtool_op_get_link,
-	.get_rx_csum	= tun_get_rx_csum,
-	.set_rx_csum	= tun_set_rx_csum
 };
 
 
diff -druN linux-2.6.39-libre/drivers/net/typhoon.c linux-3.0-rc7-libre/drivers/net/typhoon.c
--- linux-2.6.39-libre/drivers/net/typhoon.c	2011-05-19 02:12:47.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/typhoon.c	2011-07-21 06:55:14.000000000 -0400
@@ -1050,7 +1050,7 @@
 
 	/* need to get stats to make these link speed/duplex valid */
 	typhoon_do_get_stats(tp);
-	cmd->speed = tp->speed;
+	ethtool_cmd_speed_set(cmd, tp->speed);
 	cmd->duplex = tp->duplex;
 	cmd->phy_address = 0;
 	cmd->transceiver = XCVR_INTERNAL;
@@ -1068,25 +1068,26 @@
 typhoon_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
 {
 	struct typhoon *tp = netdev_priv(dev);
+	u32 speed = ethtool_cmd_speed(cmd);
 	struct cmd_desc xp_cmd;
 	__le16 xcvr;
 	int err;
 
 	err = -EINVAL;
-	if(cmd->autoneg == AUTONEG_ENABLE) {
+	if (cmd->autoneg == AUTONEG_ENABLE) {
 		xcvr = TYPHOON_XCVR_AUTONEG;
 	} else {
-		if(cmd->duplex == DUPLEX_HALF) {
-			if(cmd->speed == SPEED_10)
+		if (cmd->duplex == DUPLEX_HALF) {
+			if (speed == SPEED_10)
 				xcvr = TYPHOON_XCVR_10HALF;
-			else if(cmd->speed == SPEED_100)
+			else if (speed == SPEED_100)
 				xcvr = TYPHOON_XCVR_100HALF;
 			else
 				goto out;
-		} else if(cmd->duplex == DUPLEX_FULL) {
-			if(cmd->speed == SPEED_10)
+		} else if (cmd->duplex == DUPLEX_FULL) {
+			if (speed == SPEED_10)
 				xcvr = TYPHOON_XCVR_10FULL;
-			else if(cmd->speed == SPEED_100)
+			else if (speed == SPEED_100)
 				xcvr = TYPHOON_XCVR_100FULL;
 			else
 				goto out;
@@ -1105,7 +1106,7 @@
 		tp->speed = 0xff;	/* invalid */
 		tp->duplex = 0xff;	/* invalid */
 	} else {
-		tp->speed = cmd->speed;
+		tp->speed = speed;
 		tp->duplex = cmd->duplex;
 	}
 
@@ -1144,28 +1145,6 @@
 	return 0;
 }
 
-static u32
-typhoon_get_rx_csum(struct net_device *dev)
-{
-	/* For now, we don't allow turning off RX checksums.
-	 */
-	return 1;
-}
-
-static int
-typhoon_set_flags(struct net_device *dev, u32 data)
-{
-	/* There's no way to turn off the RX VLAN offloading and stripping
-	 * on the current 3XP firmware -- it does not respect the offload
-	 * settings -- so we only allow the user to toggle the TX processing.
-	 */
-	if (!(data & ETH_FLAG_RXVLAN))
-		return -EINVAL;
-
-	return ethtool_op_set_flags(dev, data,
-				    ETH_FLAG_RXVLAN | ETH_FLAG_TXVLAN);
-}
-
 static void
 typhoon_get_ringparam(struct net_device *dev, struct ethtool_ringparam *ering)
 {
@@ -1187,13 +1166,7 @@
 	.get_wol		= typhoon_get_wol,
 	.set_wol		= typhoon_set_wol,
 	.get_link		= ethtool_op_get_link,
-	.get_rx_csum		= typhoon_get_rx_csum,
-	.set_tx_csum		= ethtool_op_set_tx_csum,
-	.set_sg			= ethtool_op_set_sg,
-	.set_tso		= ethtool_op_set_tso,
 	.get_ringparam		= typhoon_get_ringparam,
-	.set_flags		= typhoon_set_flags,
-	.get_flags		= ethtool_op_get_flags,
 };
 
 static int
@@ -2482,10 +2455,15 @@
 
 	/* We can handle scatter gather, up to 16 entries, and
 	 * we can do IP checksumming (only version 4, doh...)
+	 *
+	 * There's no way to turn off the RX VLAN offloading and stripping
+	 * on the current 3XP firmware -- it does not respect the offload
+	 * settings -- so we only allow the user to toggle the TX processing.
 	 */
-	dev->features |= NETIF_F_SG | NETIF_F_IP_CSUM;
-	dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
-	dev->features |= NETIF_F_TSO;
+	dev->hw_features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO |
+		NETIF_F_HW_VLAN_TX;
+	dev->features = dev->hw_features |
+		NETIF_F_HW_VLAN_RX | NETIF_F_RXCSUM;
 
 	if(register_netdev(dev) < 0) {
 		err_msg = "unable to register netdev";
diff -druN linux-2.6.39-libre/drivers/net/ucc_geth_ethtool.c linux-3.0-rc7-libre/drivers/net/ucc_geth_ethtool.c
--- linux-2.6.39-libre/drivers/net/ucc_geth_ethtool.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/ucc_geth_ethtool.c	2011-07-11 19:51:52.000000000 -0400
@@ -6,7 +6,7 @@
  * Author: Li Yang <leoli@freescale.com>
  *
  * Limitation:
- * Can only get/set setttings of the first queue.
+ * Can only get/set settings of the first queue.
  * Need to re-open the interface manually after changing some parameters.
  *
  * This program is free software; you can redistribute  it and/or modify it
@@ -410,7 +410,6 @@
 	.set_ringparam          = uec_set_ringparam,
 	.get_pauseparam         = uec_get_pauseparam,
 	.set_pauseparam         = uec_set_pauseparam,
-	.set_sg                 = ethtool_op_set_sg,
 	.get_sset_count		= uec_get_sset_count,
 	.get_strings            = uec_get_strings,
 	.get_ethtool_stats      = uec_get_ethtool_stats,
diff -druN linux-2.6.39-libre/drivers/net/usb/asix.c linux-3.0-rc7-libre/drivers/net/usb/asix.c
--- linux-2.6.39-libre/drivers/net/usb/asix.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/usb/asix.c	2011-07-11 19:51:52.000000000 -0400
@@ -847,7 +847,7 @@
 static int ax88172_link_reset(struct usbnet *dev)
 {
 	u8 mode;
-	struct ethtool_cmd ecmd;
+	struct ethtool_cmd ecmd = { .cmd = ETHTOOL_GSET };
 
 	mii_check_media(&dev->mii, 1, 1);
 	mii_ethtool_gset(&dev->mii, &ecmd);
@@ -856,8 +856,8 @@
 	if (ecmd.duplex != DUPLEX_FULL)
 		mode |= ~AX88172_MEDIUM_FD;
 
-	netdev_dbg(dev->net, "ax88172_link_reset() speed: %d duplex: %d setting mode to 0x%04x\n",
-		   ecmd.speed, ecmd.duplex, mode);
+	netdev_dbg(dev->net, "ax88172_link_reset() speed: %u duplex: %d setting mode to 0x%04x\n",
+		   ethtool_cmd_speed(&ecmd), ecmd.duplex, mode);
 
 	asix_write_medium_mode(dev, mode);
 
@@ -947,20 +947,20 @@
 static int ax88772_link_reset(struct usbnet *dev)
 {
 	u16 mode;
-	struct ethtool_cmd ecmd;
+	struct ethtool_cmd ecmd = { .cmd = ETHTOOL_GSET };
 
 	mii_check_media(&dev->mii, 1, 1);
 	mii_ethtool_gset(&dev->mii, &ecmd);
 	mode = AX88772_MEDIUM_DEFAULT;
 
-	if (ecmd.speed != SPEED_100)
+	if (ethtool_cmd_speed(&ecmd) != SPEED_100)
 		mode &= ~AX_MEDIUM_PS;
 
 	if (ecmd.duplex != DUPLEX_FULL)
 		mode &= ~AX_MEDIUM_FD;
 
-	netdev_dbg(dev->net, "ax88772_link_reset() speed: %d duplex: %d setting mode to 0x%04x\n",
-		   ecmd.speed, ecmd.duplex, mode);
+	netdev_dbg(dev->net, "ax88772_link_reset() speed: %u duplex: %d setting mode to 0x%04x\n",
+		   ethtool_cmd_speed(&ecmd), ecmd.duplex, mode);
 
 	asix_write_medium_mode(dev, mode);
 
@@ -1173,18 +1173,20 @@
 static int ax88178_link_reset(struct usbnet *dev)
 {
 	u16 mode;
-	struct ethtool_cmd ecmd;
+	struct ethtool_cmd ecmd = { .cmd = ETHTOOL_GSET };
 	struct asix_data *data = (struct asix_data *)&dev->data;
+	u32 speed;
 
 	netdev_dbg(dev->net, "ax88178_link_reset()\n");
 
 	mii_check_media(&dev->mii, 1, 1);
 	mii_ethtool_gset(&dev->mii, &ecmd);
 	mode = AX88178_MEDIUM_DEFAULT;
+	speed = ethtool_cmd_speed(&ecmd);
 
-	if (ecmd.speed == SPEED_1000)
+	if (speed == SPEED_1000)
 		mode |= AX_MEDIUM_GM;
-	else if (ecmd.speed == SPEED_100)
+	else if (speed == SPEED_100)
 		mode |= AX_MEDIUM_PS;
 	else
 		mode &= ~(AX_MEDIUM_PS | AX_MEDIUM_GM);
@@ -1196,13 +1198,13 @@
 	else
 		mode &= ~AX_MEDIUM_FD;
 
-	netdev_dbg(dev->net, "ax88178_link_reset() speed: %d duplex: %d setting mode to 0x%04x\n",
-		   ecmd.speed, ecmd.duplex, mode);
+	netdev_dbg(dev->net, "ax88178_link_reset() speed: %u duplex: %d setting mode to 0x%04x\n",
+		   speed, ecmd.duplex, mode);
 
 	asix_write_medium_mode(dev, mode);
 
 	if (data->phymode == PHY_MODE_MARVELL && data->ledmode)
-		marvell_led_status(dev, ecmd.speed);
+		marvell_led_status(dev, speed);
 
 	return 0;
 }
diff -druN linux-2.6.39-libre/drivers/net/usb/catc.c linux-3.0-rc7-libre/drivers/net/usb/catc.c
--- linux-2.6.39-libre/drivers/net/usb/catc.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/usb/catc.c	2011-07-11 19:51:52.000000000 -0400
@@ -495,7 +495,7 @@
 	if (!q->dir && q->buf && q->len)
 		memcpy(catc->ctrl_buf, q->buf, q->len);
 
-	if ((status = usb_submit_urb(catc->ctrl_urb, GFP_KERNEL)))
+	if ((status = usb_submit_urb(catc->ctrl_urb, GFP_ATOMIC)))
 		err("submit(ctrl_urb) status %d", status);
 }
 
@@ -686,7 +686,7 @@
 
 	cmd->supported = SUPPORTED_10baseT_Half | SUPPORTED_TP;
 	cmd->advertising = ADVERTISED_10baseT_Half | ADVERTISED_TP;
-	cmd->speed = SPEED_10;
+	ethtool_cmd_speed_set(cmd, SPEED_10);
 	cmd->duplex = DUPLEX_HALF;
 	cmd->port = PORT_TP; 
 	cmd->phy_address = 0;
diff -druN linux-2.6.39-libre/drivers/net/usb/cdc_ncm.c linux-3.0-rc7-libre/drivers/net/usb/cdc_ncm.c
--- linux-2.6.39-libre/drivers/net/usb/cdc_ncm.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/usb/cdc_ncm.c	2011-07-11 19:51:52.000000000 -0400
@@ -54,13 +54,13 @@
 #include <linux/usb/usbnet.h>
 #include <linux/usb/cdc.h>
 
-#define	DRIVER_VERSION				"23-Apr-2011"
+#define	DRIVER_VERSION				"01-June-2011"
 
 /* CDC NCM subclass 3.2.1 */
 #define USB_CDC_NCM_NDP16_LENGTH_MIN		0x10
 
 /* Maximum NTB length */
-#define	CDC_NCM_NTB_MAX_SIZE_TX			(16384 + 4) /* bytes, must be short terminated */
+#define	CDC_NCM_NTB_MAX_SIZE_TX			16384	/* bytes */
 #define	CDC_NCM_NTB_MAX_SIZE_RX			16384	/* bytes */
 
 /* Minimum value for MaxDatagramSize, ch. 6.2.9 */
@@ -134,8 +134,6 @@
 	u16 tx_ndp_modulus;
 	u16 tx_seq;
 	u16 connected;
-	u8 data_claimed;
-	u8 control_claimed;
 };
 
 static void cdc_ncm_tx_timeout(unsigned long arg);
@@ -460,17 +458,6 @@
 
 	del_timer_sync(&ctx->tx_timer);
 
-	if (ctx->data_claimed) {
-		usb_set_intfdata(ctx->data, NULL);
-		usb_driver_release_interface(driver_of(ctx->intf), ctx->data);
-	}
-
-	if (ctx->control_claimed) {
-		usb_set_intfdata(ctx->control, NULL);
-		usb_driver_release_interface(driver_of(ctx->intf),
-								ctx->control);
-	}
-
 	if (ctx->tx_rem_skb != NULL) {
 		dev_kfree_skb_any(ctx->tx_rem_skb);
 		ctx->tx_rem_skb = NULL;
@@ -495,7 +482,7 @@
 
 	ctx = kmalloc(sizeof(*ctx), GFP_KERNEL);
 	if (ctx == NULL)
-		goto error;
+		return -ENODEV;
 
 	memset(ctx, 0, sizeof(*ctx));
 
@@ -568,46 +555,36 @@
 
 	/* check if we got everything */
 	if ((ctx->control == NULL) || (ctx->data == NULL) ||
-	    (ctx->ether_desc == NULL))
+	    (ctx->ether_desc == NULL) || (ctx->control != intf))
 		goto error;
 
 	/* claim interfaces, if any */
-	if (ctx->data != intf) {
-		temp = usb_driver_claim_interface(driver, ctx->data, dev);
-		if (temp)
-			goto error;
-		ctx->data_claimed = 1;
-	}
-
-	if (ctx->control != intf) {
-		temp = usb_driver_claim_interface(driver, ctx->control, dev);
-		if (temp)
-			goto error;
-		ctx->control_claimed = 1;
-	}
+	temp = usb_driver_claim_interface(driver, ctx->data, dev);
+	if (temp)
+		goto error;
 
 	iface_no = ctx->data->cur_altsetting->desc.bInterfaceNumber;
 
 	/* reset data interface */
 	temp = usb_set_interface(dev->udev, iface_no, 0);
 	if (temp)
-		goto error;
+		goto error2;
 
 	/* initialize data interface */
 	if (cdc_ncm_setup(ctx))
-		goto error;
+		goto error2;
 
 	/* configure data interface */
 	temp = usb_set_interface(dev->udev, iface_no, 1);
 	if (temp)
-		goto error;
+		goto error2;
 
 	cdc_ncm_find_endpoints(ctx, ctx->data);
 	cdc_ncm_find_endpoints(ctx, ctx->control);
 
 	if ((ctx->in_ep == NULL) || (ctx->out_ep == NULL) ||
 	    (ctx->status_ep == NULL))
-		goto error;
+		goto error2;
 
 	dev->net->ethtool_ops = &cdc_ncm_ethtool_ops;
 
@@ -617,7 +594,7 @@
 
 	temp = usbnet_get_ethernet_addr(dev, ctx->ether_desc->iMACAddress);
 	if (temp)
-		goto error;
+		goto error2;
 
 	dev_info(&dev->udev->dev, "MAC-Address: "
 				"0x%02x:0x%02x:0x%02x:0x%02x:0x%02x:0x%02x\n",
@@ -642,38 +619,38 @@
 	ctx->tx_speed = ctx->rx_speed = 0;
 	return 0;
 
+error2:
+	usb_set_intfdata(ctx->control, NULL);
+	usb_set_intfdata(ctx->data, NULL);
+	usb_driver_release_interface(driver, ctx->data);
 error:
 	cdc_ncm_free((struct cdc_ncm_ctx *)dev->data[0]);
 	dev->data[0] = 0;
-	dev_info(&dev->udev->dev, "Descriptor failure\n");
+	dev_info(&dev->udev->dev, "bind() failure\n");
 	return -ENODEV;
 }
 
 static void cdc_ncm_unbind(struct usbnet *dev, struct usb_interface *intf)
 {
 	struct cdc_ncm_ctx *ctx = (struct cdc_ncm_ctx *)dev->data[0];
-	struct usb_driver *driver;
+	struct usb_driver *driver = driver_of(intf);
 
 	if (ctx == NULL)
 		return;		/* no setup */
 
-	driver = driver_of(intf);
-
-	usb_set_intfdata(ctx->data, NULL);
-	usb_set_intfdata(ctx->control, NULL);
-	usb_set_intfdata(ctx->intf, NULL);
-
-	/* release interfaces, if any */
-	if (ctx->data_claimed) {
+	/* disconnect master --> disconnect slave */
+	if (intf == ctx->control && ctx->data) {
+		usb_set_intfdata(ctx->data, NULL);
 		usb_driver_release_interface(driver, ctx->data);
-		ctx->data_claimed = 0;
-	}
+		ctx->data = NULL;
 
-	if (ctx->control_claimed) {
+	} else if (intf == ctx->data && ctx->control) {
+		usb_set_intfdata(ctx->control, NULL);
 		usb_driver_release_interface(driver, ctx->control);
-		ctx->control_claimed = 0;
+		ctx->control = NULL;
 	}
 
+	usb_set_intfdata(ctx->intf, NULL);
 	cdc_ncm_free(ctx);
 }
 
@@ -722,7 +699,7 @@
 
 	} else {
 		/* reset variables */
-		skb_out = alloc_skb(ctx->tx_max, GFP_ATOMIC);
+		skb_out = alloc_skb((ctx->tx_max + 1), GFP_ATOMIC);
 		if (skb_out == NULL) {
 			if (skb != NULL) {
 				dev_kfree_skb_any(skb);
@@ -861,8 +838,11 @@
 	/* store last offset */
 	last_offset = offset;
 
-	if ((last_offset < ctx->tx_max) && ((last_offset %
-			le16_to_cpu(ctx->out_ep->desc.wMaxPacketSize)) == 0)) {
+	if (((last_offset < ctx->tx_max) && ((last_offset %
+			le16_to_cpu(ctx->out_ep->desc.wMaxPacketSize)) == 0)) ||
+	    (((last_offset == ctx->tx_max) && ((ctx->tx_max %
+		le16_to_cpu(ctx->out_ep->desc.wMaxPacketSize)) == 0)) &&
+		(ctx->tx_max < le32_to_cpu(ctx->ncm_parm.dwNtbOutMaxSize)))) {
 		/* force short packet */
 		*(((u8 *)skb_out->data) + last_offset) = 0;
 		last_offset++;
@@ -1254,6 +1234,7 @@
 	.disconnect = cdc_ncm_disconnect,
 	.suspend = usbnet_suspend,
 	.resume = usbnet_resume,
+	.reset_resume =	usbnet_resume,
 	.supports_autosuspend = 1,
 };
 
diff -druN linux-2.6.39-libre/drivers/net/usb/dm9601.c linux-3.0-rc7-libre/drivers/net/usb/dm9601.c
--- linux-2.6.39-libre/drivers/net/usb/dm9601.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/usb/dm9601.c	2011-07-11 19:51:52.000000000 -0400
@@ -599,13 +599,13 @@
 
 static int dm9601_link_reset(struct usbnet *dev)
 {
-	struct ethtool_cmd ecmd;
+	struct ethtool_cmd ecmd = { .cmd = ETHTOOL_GSET };
 
 	mii_check_media(&dev->mii, 1, 1);
 	mii_ethtool_gset(&dev->mii, &ecmd);
 
-	netdev_dbg(dev->net, "link_reset() speed: %d duplex: %d\n",
-		   ecmd.speed, ecmd.duplex);
+	netdev_dbg(dev->net, "link_reset() speed: %u duplex: %d\n",
+		   ethtool_cmd_speed(&ecmd), ecmd.duplex);
 
 	return 0;
 }
diff -druN linux-2.6.39-libre/drivers/net/usb/kalmia.c linux-3.0-rc7-libre/drivers/net/usb/kalmia.c
--- linux-2.6.39-libre/drivers/net/usb/kalmia.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/net/usb/kalmia.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,392 @@
+/*
+ * USB network interface driver for Samsung Kalmia based LTE USB modem like the
+ * Samsung GT-B3730 and GT-B3710.
+ *
+ * Copyright (C) 2011 Marius Bjoernstad Kotsbak <marius@kotsbak.com>
+ *
+ * Sponsored by Quicklink Video Distribution Services Ltd.
+ *
+ * Based on the cdc_eem module.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/ctype.h>
+#include <linux/ethtool.h>
+#include <linux/workqueue.h>
+#include <linux/mii.h>
+#include <linux/usb.h>
+#include <linux/crc32.h>
+#include <linux/usb/cdc.h>
+#include <linux/usb/usbnet.h>
+#include <linux/gfp.h>
+
+/*
+ * The Samsung Kalmia based LTE USB modems have a CDC ACM port for modem control
+ * handled by the "option" module and an ethernet data port handled by this
+ * module.
+ *
+ * The stick must first be switched into modem mode by usb_modeswitch
+ * or similar tool. Then the modem gets sent two initialization packets by
+ * this module, which gives the MAC address of the device. User space can then
+ * connect the modem using AT commands through the ACM port and then use
+ * DHCP on the network interface exposed by this module. Network packets are
+ * sent to and from the modem in a proprietary format discovered after watching
+ * the behavior of the windows driver for the modem.
+ *
+ * More information about the use of the modem is available in usb_modeswitch
+ * forum and the project page:
+ *
+ * http://www.draisberghof.de/usb_modeswitch/bb/viewtopic.php?t=465
+ * https://github.com/mkotsbak/Samsung-GT-B3730-linux-driver
+ */
+
+/* #define	DEBUG */
+/* #define	VERBOSE */
+
+#define KALMIA_HEADER_LENGTH 6
+#define KALMIA_ALIGN_SIZE 4
+#define KALMIA_USB_TIMEOUT 10000
+
+/*-------------------------------------------------------------------------*/
+
+static int
+kalmia_send_init_packet(struct usbnet *dev, u8 *init_msg, u8 init_msg_len,
+	u8 *buffer, u8 expected_len)
+{
+	int act_len;
+	int status;
+
+	netdev_dbg(dev->net, "Sending init packet");
+
+	status = usb_bulk_msg(dev->udev, usb_sndbulkpipe(dev->udev, 0x02),
+		init_msg, init_msg_len, &act_len, KALMIA_USB_TIMEOUT);
+	if (status != 0) {
+		netdev_err(dev->net,
+			"Error sending init packet. Status %i, length %i\n",
+			status, act_len);
+		return status;
+	}
+	else if (act_len != init_msg_len) {
+		netdev_err(dev->net,
+			"Did not send all of init packet. Bytes sent: %i",
+			act_len);
+	}
+	else {
+		netdev_dbg(dev->net, "Successfully sent init packet.");
+	}
+
+	status = usb_bulk_msg(dev->udev, usb_rcvbulkpipe(dev->udev, 0x81),
+		buffer, expected_len, &act_len, KALMIA_USB_TIMEOUT);
+
+	if (status != 0)
+		netdev_err(dev->net,
+			"Error receiving init result. Status %i, length %i\n",
+			status, act_len);
+	else if (act_len != expected_len)
+		netdev_err(dev->net, "Unexpected init result length: %i\n",
+			act_len);
+
+	return status;
+}
+
+static int
+kalmia_init_and_get_ethernet_addr(struct usbnet *dev, u8 *ethernet_addr)
+{
+	const static char init_msg_1[] =
+		{ 0x57, 0x50, 0x04, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00,
+		0x00, 0x00 };
+	const static char init_msg_2[] =
+		{ 0x57, 0x50, 0x04, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0xf4,
+		0x00, 0x00 };
+	const static int buflen = 28;
+	char *usb_buf;
+	int status;
+
+	usb_buf = kmalloc(buflen, GFP_DMA | GFP_KERNEL);
+	if (!usb_buf)
+		return -ENOMEM;
+
+	memcpy(usb_buf, init_msg_1, 12);
+	status = kalmia_send_init_packet(dev, usb_buf, sizeof(init_msg_1)
+		/ sizeof(init_msg_1[0]), usb_buf, 24);
+	if (status != 0)
+		return status;
+
+	memcpy(usb_buf, init_msg_2, 12);
+	status = kalmia_send_init_packet(dev, usb_buf, sizeof(init_msg_2)
+		/ sizeof(init_msg_2[0]), usb_buf, 28);
+	if (status != 0)
+		return status;
+
+	memcpy(ethernet_addr, usb_buf + 10, ETH_ALEN);
+
+	kfree(usb_buf);
+	return status;
+}
+
+static int
+kalmia_bind(struct usbnet *dev, struct usb_interface *intf)
+{
+	int status;
+	u8 ethernet_addr[ETH_ALEN];
+
+	/* Don't bind to AT command interface */
+	if (intf->cur_altsetting->desc.bInterfaceClass != USB_CLASS_VENDOR_SPEC)
+		return -EINVAL;
+
+	dev->in = usb_rcvbulkpipe(dev->udev, 0x81 & USB_ENDPOINT_NUMBER_MASK);
+	dev->out = usb_sndbulkpipe(dev->udev, 0x02 & USB_ENDPOINT_NUMBER_MASK);
+	dev->status = NULL;
+
+	dev->net->hard_header_len += KALMIA_HEADER_LENGTH;
+	dev->hard_mtu = 1400;
+	dev->rx_urb_size = dev->hard_mtu * 10; // Found as optimal after testing
+
+	status = kalmia_init_and_get_ethernet_addr(dev, ethernet_addr);
+
+	if (status < 0) {
+		usb_set_intfdata(intf, NULL);
+		usb_driver_release_interface(driver_of(intf), intf);
+		return status;
+	}
+
+	memcpy(dev->net->dev_addr, ethernet_addr, ETH_ALEN);
+	memcpy(dev->net->perm_addr, ethernet_addr, ETH_ALEN);
+
+	return status;
+}
+
+static struct sk_buff *
+kalmia_tx_fixup(struct usbnet *dev, struct sk_buff *skb, gfp_t flags)
+{
+	struct sk_buff *skb2 = NULL;
+	u16 content_len;
+	unsigned char *header_start;
+	unsigned char ether_type_1, ether_type_2;
+	u8 remainder, padlen = 0;
+
+	if (!skb_cloned(skb)) {
+		int headroom = skb_headroom(skb);
+		int tailroom = skb_tailroom(skb);
+
+		if ((tailroom >= KALMIA_ALIGN_SIZE) && (headroom
+			>= KALMIA_HEADER_LENGTH))
+			goto done;
+
+		if ((headroom + tailroom) > (KALMIA_HEADER_LENGTH
+			+ KALMIA_ALIGN_SIZE)) {
+			skb->data = memmove(skb->head + KALMIA_HEADER_LENGTH,
+				skb->data, skb->len);
+			skb_set_tail_pointer(skb, skb->len);
+			goto done;
+		}
+	}
+
+	skb2 = skb_copy_expand(skb, KALMIA_HEADER_LENGTH,
+		KALMIA_ALIGN_SIZE, flags);
+	if (!skb2)
+		return NULL;
+
+	dev_kfree_skb_any(skb);
+	skb = skb2;
+
+done:
+	header_start = skb_push(skb, KALMIA_HEADER_LENGTH);
+	ether_type_1 = header_start[KALMIA_HEADER_LENGTH + 12];
+	ether_type_2 = header_start[KALMIA_HEADER_LENGTH + 13];
+
+	netdev_dbg(dev->net, "Sending etherType: %02x%02x", ether_type_1,
+		ether_type_2);
+
+	/* According to empiric data for data packages */
+	header_start[0] = 0x57;
+	header_start[1] = 0x44;
+	content_len = skb->len - KALMIA_HEADER_LENGTH;
+
+	put_unaligned_le16(content_len, &header_start[2]);
+	header_start[4] = ether_type_1;
+	header_start[5] = ether_type_2;
+
+	/* Align to 4 bytes by padding with zeros */
+	remainder = skb->len % KALMIA_ALIGN_SIZE;
+	if (remainder > 0) {
+		padlen = KALMIA_ALIGN_SIZE - remainder;
+		memset(skb_put(skb, padlen), 0, padlen);
+	}
+
+	netdev_dbg(
+		dev->net,
+		"Sending package with length %i and padding %i. Header: %02x:%02x:%02x:%02x:%02x:%02x.",
+		content_len, padlen, header_start[0], header_start[1],
+		header_start[2], header_start[3], header_start[4],
+		header_start[5]);
+
+	return skb;
+}
+
+static int
+kalmia_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
+{
+	/*
+	 * Our task here is to strip off framing, leaving skb with one
+	 * data frame for the usbnet framework code to process.
+	 */
+	const static u8 HEADER_END_OF_USB_PACKET[] =
+		{ 0x57, 0x5a, 0x00, 0x00, 0x08, 0x00 };
+	const static u8 EXPECTED_UNKNOWN_HEADER_1[] =
+		{ 0x57, 0x43, 0x1e, 0x00, 0x15, 0x02 };
+	const static u8 EXPECTED_UNKNOWN_HEADER_2[] =
+		{ 0x57, 0x50, 0x0e, 0x00, 0x00, 0x00 };
+	int i = 0;
+
+	/* incomplete header? */
+	if (skb->len < KALMIA_HEADER_LENGTH)
+		return 0;
+
+	do {
+		struct sk_buff *skb2 = NULL;
+		u8 *header_start;
+		u16 usb_packet_length, ether_packet_length;
+		int is_last;
+
+		header_start = skb->data;
+
+		if (unlikely(header_start[0] != 0x57 || header_start[1] != 0x44)) {
+			if (!memcmp(header_start, EXPECTED_UNKNOWN_HEADER_1,
+				sizeof(EXPECTED_UNKNOWN_HEADER_1)) || !memcmp(
+				header_start, EXPECTED_UNKNOWN_HEADER_2,
+				sizeof(EXPECTED_UNKNOWN_HEADER_2))) {
+				netdev_dbg(
+					dev->net,
+					"Received expected unknown frame header: %02x:%02x:%02x:%02x:%02x:%02x. Package length: %i\n",
+					header_start[0], header_start[1],
+					header_start[2], header_start[3],
+					header_start[4], header_start[5],
+					skb->len - KALMIA_HEADER_LENGTH);
+			}
+			else {
+				netdev_err(
+					dev->net,
+					"Received unknown frame header: %02x:%02x:%02x:%02x:%02x:%02x. Package length: %i\n",
+					header_start[0], header_start[1],
+					header_start[2], header_start[3],
+					header_start[4], header_start[5],
+					skb->len - KALMIA_HEADER_LENGTH);
+				return 0;
+			}
+		}
+		else
+			netdev_dbg(
+				dev->net,
+				"Received header: %02x:%02x:%02x:%02x:%02x:%02x. Package length: %i\n",
+				header_start[0], header_start[1], header_start[2],
+				header_start[3], header_start[4], header_start[5],
+				skb->len - KALMIA_HEADER_LENGTH);
+
+		/* subtract start header and end header */
+		usb_packet_length = skb->len - (2 * KALMIA_HEADER_LENGTH);
+		ether_packet_length = get_unaligned_le16(&header_start[2]);
+		skb_pull(skb, KALMIA_HEADER_LENGTH);
+
+		/* Some small packets misses end marker */
+		if (usb_packet_length < ether_packet_length) {
+			ether_packet_length = usb_packet_length
+				+ KALMIA_HEADER_LENGTH;
+			is_last = true;
+		}
+		else {
+			netdev_dbg(dev->net, "Correct package length #%i", i
+				+ 1);
+
+			is_last = (memcmp(skb->data + ether_packet_length,
+				HEADER_END_OF_USB_PACKET,
+				sizeof(HEADER_END_OF_USB_PACKET)) == 0);
+			if (!is_last) {
+				header_start = skb->data + ether_packet_length;
+				netdev_dbg(
+					dev->net,
+					"End header: %02x:%02x:%02x:%02x:%02x:%02x. Package length: %i\n",
+					header_start[0], header_start[1],
+					header_start[2], header_start[3],
+					header_start[4], header_start[5],
+					skb->len - KALMIA_HEADER_LENGTH);
+			}
+		}
+
+		if (is_last) {
+			skb2 = skb;
+		}
+		else {
+			skb2 = skb_clone(skb, GFP_ATOMIC);
+			if (unlikely(!skb2))
+				return 0;
+		}
+
+		skb_trim(skb2, ether_packet_length);
+
+		if (is_last) {
+			return 1;
+		}
+		else {
+			usbnet_skb_return(dev, skb2);
+			skb_pull(skb, ether_packet_length);
+		}
+
+		i++;
+	}
+	while (skb->len);
+
+	return 1;
+}
+
+static const struct driver_info kalmia_info = {
+	.description = "Samsung Kalmia LTE USB dongle",
+	.flags = FLAG_WWAN,
+	.bind = kalmia_bind,
+	.rx_fixup = kalmia_rx_fixup,
+	.tx_fixup = kalmia_tx_fixup
+};
+
+/*-------------------------------------------------------------------------*/
+
+static const struct usb_device_id products[] = {
+	/* The unswitched USB ID, to get the module auto loaded: */
+	{ USB_DEVICE(0x04e8, 0x689a) },
+	/* The stick swithed into modem (by e.g. usb_modeswitch): */
+	{ USB_DEVICE(0x04e8, 0x6889),
+		.driver_info = (unsigned long) &kalmia_info, },
+	{ /* EMPTY == end of list */} };
+MODULE_DEVICE_TABLE( usb, products);
+
+static struct usb_driver kalmia_driver = {
+	.name = "kalmia",
+	.id_table = products,
+	.probe = usbnet_probe,
+	.disconnect = usbnet_disconnect,
+	.suspend = usbnet_suspend,
+	.resume = usbnet_resume
+};
+
+static int __init kalmia_init(void)
+{
+	return usb_register(&kalmia_driver);
+}
+module_init( kalmia_init);
+
+static void __exit kalmia_exit(void)
+{
+	usb_deregister(&kalmia_driver);
+}
+module_exit( kalmia_exit);
+
+MODULE_AUTHOR("Marius Bjoernstad Kotsbak <marius@kotsbak.com>");
+MODULE_DESCRIPTION("Samsung Kalmia USB network driver");
+MODULE_LICENSE("GPL");
diff -druN linux-2.6.39-libre/drivers/net/usb/Kconfig linux-3.0-rc7-libre/drivers/net/usb/Kconfig
--- linux-2.6.39-libre/drivers/net/usb/Kconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/usb/Kconfig	2011-07-11 19:51:52.000000000 -0400
@@ -258,7 +258,7 @@
 	  optionally with LEDs that indicate traffic
 
 config USB_NET_PLUSB
-	tristate "Prolific PL-2301/2302 based cables"
+	tristate "Prolific PL-2301/2302/25A1 based cables"
 	# if the handshake/init/reset problems, from original 'plusb',
 	# are ever resolved ... then remove "experimental"
 	depends on USB_USBNET && EXPERIMENTAL
@@ -385,6 +385,16 @@
 	  router with USB ethernet port. This driver is for routers only,
 	  it will not work with ADSL modems (use cxacru driver instead).
 
+config USB_NET_KALMIA
+	tristate "Samsung Kalmia based LTE USB modem"
+	depends on USB_USBNET
+	help
+	  Choose this option if you have a Samsung Kalmia based USB modem
+	  as Samsung GT-B3730.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called kalmia.
+
 config USB_HSO
 	tristate "Option USB High Speed Mobile Devices"
 	depends on USB && RFKILL
diff -druN linux-2.6.39-libre/drivers/net/usb/Makefile linux-3.0-rc7-libre/drivers/net/usb/Makefile
--- linux-2.6.39-libre/drivers/net/usb/Makefile	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/usb/Makefile	2011-07-11 19:51:52.000000000 -0400
@@ -23,6 +23,7 @@
 obj-$(CONFIG_USB_USBNET)	+= usbnet.o
 obj-$(CONFIG_USB_NET_INT51X1)	+= int51x1.o
 obj-$(CONFIG_USB_CDC_PHONET)	+= cdc-phonet.o
+obj-$(CONFIG_USB_NET_KALMIA)	+= kalmia.o
 obj-$(CONFIG_USB_IPHETH)	+= ipheth.o
 obj-$(CONFIG_USB_SIERRA_NET)	+= sierra_net.o
 obj-$(CONFIG_USB_NET_CX82310_ETH)	+= cx82310_eth.o
diff -druN linux-2.6.39-libre/drivers/net/usb/plusb.c linux-3.0-rc7-libre/drivers/net/usb/plusb.c
--- linux-2.6.39-libre/drivers/net/usb/plusb.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/usb/plusb.c	2011-07-11 19:51:52.000000000 -0400
@@ -45,6 +45,14 @@
  * seems to get wedged under load.  Prolific docs are weak, and
  * don't identify differences between PL2301 and PL2302, much less
  * anything to explain the different PL2302 versions observed.
+ *
+ * NOTE:  pl2501 has several modes, including pl2301 and pl2302
+ * compatibility.   Some docs suggest the difference between 2301
+ * and 2302 is only to make MS-Windows use a different driver...
+ *
+ * pl25a1 glue based on patch from Tony Gibbs.  Prolific "docs" on
+ * this chip are as usual incomplete about what control messages
+ * are supported.
  */
 
 /*
@@ -86,16 +94,20 @@
 
 static int pl_reset(struct usbnet *dev)
 {
+	int status;
+
 	/* some units seem to need this reset, others reject it utterly.
 	 * FIXME be more like "naplink" or windows drivers.
 	 */
-	(void) pl_set_QuickLink_features(dev,
+	status = pl_set_QuickLink_features(dev,
 		PL_S_EN|PL_RESET_OUT|PL_RESET_IN|PL_PEER_E);
+	if (status != 0 && netif_msg_probe(dev))
+		netif_dbg(dev, link, dev->net, "pl_reset --> %d\n", status);
 	return 0;
 }
 
 static const struct driver_info	prolific_info = {
-	.description =	"Prolific PL-2301/PL-2302",
+	.description =	"Prolific PL-2301/PL-2302/PL-25A1",
 	.flags =	FLAG_POINTTOPOINT | FLAG_NO_SETINT,
 		/* some PL-2302 versions seem to fail usb_set_interface() */
 	.reset =	pl_reset,
@@ -111,6 +123,7 @@
 
 static const struct usb_device_id	products [] = {
 
+/* full speed cables */
 {
 	USB_DEVICE(0x067b, 0x0000),	// PL-2301
 	.driver_info =	(unsigned long) &prolific_info,
@@ -119,6 +132,15 @@
 	.driver_info =	(unsigned long) &prolific_info,
 },
 
+/* high speed cables */
+{
+	USB_DEVICE(0x067b, 0x25a1),     /* PL-25A1, no eeprom */
+	.driver_info =  (unsigned long) &prolific_info,
+}, {
+	USB_DEVICE(0x050d, 0x258a),     /* Belkin F5U258/F5U279 (PL-25A1) */
+	.driver_info =  (unsigned long) &prolific_info,
+},
+
 	{ },		// END
 };
 MODULE_DEVICE_TABLE(usb, products);
@@ -134,16 +156,16 @@
 
 static int __init plusb_init(void)
 {
- 	return usb_register(&plusb_driver);
+	return usb_register(&plusb_driver);
 }
 module_init(plusb_init);
 
 static void __exit plusb_exit(void)
 {
- 	usb_deregister(&plusb_driver);
+	usb_deregister(&plusb_driver);
 }
 module_exit(plusb_exit);
 
 MODULE_AUTHOR("David Brownell");
-MODULE_DESCRIPTION("Prolific PL-2301/2302 USB Host to Host Link Driver");
+MODULE_DESCRIPTION("Prolific PL-2301/2302/25A1 USB Host to Host Link Driver");
 MODULE_LICENSE("GPL");
diff -druN linux-2.6.39-libre/drivers/net/usb/rndis_host.c linux-3.0-rc7-libre/drivers/net/usb/rndis_host.c
--- linux-2.6.39-libre/drivers/net/usb/rndis_host.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/usb/rndis_host.c	2011-07-11 19:51:52.000000000 -0400
@@ -104,8 +104,10 @@
 int rndis_command(struct usbnet *dev, struct rndis_msg_hdr *buf, int buflen)
 {
 	struct cdc_state	*info = (void *) &dev->data;
+	struct usb_cdc_notification notification;
 	int			master_ifnum;
 	int			retval;
+	int			partial;
 	unsigned		count;
 	__le32			rsp;
 	u32			xid = 0, msg_len, request_id;
@@ -133,13 +135,20 @@
 	if (unlikely(retval < 0 || xid == 0))
 		return retval;
 
-	// FIXME Seems like some devices discard responses when
-	// we time out and cancel our "get response" requests...
-	// so, this is fragile.  Probably need to poll for status.
+	/* Some devices don't respond on the control channel until
+	 * polled on the status channel, so do that first. */
+	if (dev->driver_info->data & RNDIS_DRIVER_DATA_POLL_STATUS) {
+		retval = usb_interrupt_msg(
+			dev->udev,
+			usb_rcvintpipe(dev->udev,
+				       dev->status->desc.bEndpointAddress),
+			&notification, sizeof(notification), &partial,
+			RNDIS_CONTROL_TIMEOUT_MS);
+		if (unlikely(retval < 0))
+			return retval;
+	}
 
-	/* ignore status endpoint, just poll the control channel;
-	 * the request probably completed immediately
-	 */
+	/* Poll the control channel; the request probably completed immediately */
 	rsp = buf->msg_type | RNDIS_MSG_COMPLETION;
 	for (count = 0; count < 10; count++) {
 		memset(buf, 0, CONTROL_BUFFER_SIZE);
@@ -581,17 +590,33 @@
 	.tx_fixup =	rndis_tx_fixup,
 };
 
+static const struct driver_info	rndis_poll_status_info = {
+	.description =	"RNDIS device (poll status before control)",
+	.flags =	FLAG_ETHER | FLAG_POINTTOPOINT | FLAG_FRAMING_RN | FLAG_NO_SETINT,
+	.data =		RNDIS_DRIVER_DATA_POLL_STATUS,
+	.bind =		rndis_bind,
+	.unbind =	rndis_unbind,
+	.status =	rndis_status,
+	.rx_fixup =	rndis_rx_fixup,
+	.tx_fixup =	rndis_tx_fixup,
+};
+
 /*-------------------------------------------------------------------------*/
 
 static const struct usb_device_id	products [] = {
 {
+	/* 2Wire HomePortal 1000SW */
+	USB_DEVICE_AND_INTERFACE_INFO(0x1630, 0x0042,
+				      USB_CLASS_COMM, 2 /* ACM */, 0x0ff),
+	.driver_info = (unsigned long) &rndis_poll_status_info,
+}, {
 	/* RNDIS is MSFT's un-official variant of CDC ACM */
 	USB_INTERFACE_INFO(USB_CLASS_COMM, 2 /* ACM */, 0x0ff),
 	.driver_info = (unsigned long) &rndis_info,
 }, {
 	/* "ActiveSync" is an undocumented variant of RNDIS, used in WM5 */
 	USB_INTERFACE_INFO(USB_CLASS_MISC, 1, 1),
-	.driver_info = (unsigned long) &rndis_info,
+	.driver_info = (unsigned long) &rndis_poll_status_info,
 }, {
 	/* RNDIS for tethering */
 	USB_INTERFACE_INFO(USB_CLASS_WIRELESS_CONTROLLER, 1, 3),
diff -druN linux-2.6.39-libre/drivers/net/usb/rtl8150.c linux-3.0-rc7-libre/drivers/net/usb/rtl8150.c
--- linux-2.6.39-libre/drivers/net/usb/rtl8150.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/usb/rtl8150.c	2011-07-11 19:51:52.000000000 -0400
@@ -843,10 +843,11 @@
 	get_registers(dev, BMCR, 2, &bmcr);
 	get_registers(dev, ANLP, 2, &lpa);
 	if (bmcr & BMCR_ANENABLE) {
+		u32 speed = ((lpa & (LPA_100HALF | LPA_100FULL)) ?
+			     SPEED_100 : SPEED_10);
+		ethtool_cmd_speed_set(ecmd, speed);
 		ecmd->autoneg = AUTONEG_ENABLE;
-		ecmd->speed = (lpa & (LPA_100HALF | LPA_100FULL)) ?
-			     SPEED_100 : SPEED_10;
-		if (ecmd->speed == SPEED_100)
+		if (speed == SPEED_100)
 			ecmd->duplex = (lpa & LPA_100FULL) ?
 			    DUPLEX_FULL : DUPLEX_HALF;
 		else
@@ -854,8 +855,8 @@
 			    DUPLEX_FULL : DUPLEX_HALF;
 	} else {
 		ecmd->autoneg = AUTONEG_DISABLE;
-		ecmd->speed = (bmcr & BMCR_SPEED100) ?
-		    SPEED_100 : SPEED_10;
+		ethtool_cmd_speed_set(ecmd, ((bmcr & BMCR_SPEED100) ?
+					     SPEED_100 : SPEED_10));
 		ecmd->duplex = (bmcr & BMCR_FULLDPLX) ?
 		    DUPLEX_FULL : DUPLEX_HALF;
 	}
diff -druN linux-2.6.39-libre/drivers/net/usb/smsc75xx.c linux-3.0-rc7-libre/drivers/net/usb/smsc75xx.c
--- linux-2.6.39-libre/drivers/net/usb/smsc75xx.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/usb/smsc75xx.c	2011-07-11 19:51:52.000000000 -0400
@@ -65,7 +65,6 @@
 	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;
@@ -504,7 +503,7 @@
 static int smsc75xx_link_reset(struct usbnet *dev)
 {
 	struct mii_if_info *mii = &dev->mii;
-	struct ethtool_cmd ecmd;
+	struct ethtool_cmd ecmd = { .cmd = ETHTOOL_GSET };
 	u16 lcladv, rmtadv;
 	int ret;
 
@@ -520,8 +519,9 @@
 	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);
+	netif_dbg(dev, link, dev->net, "speed: %u duplex: %d lcladv: %04x"
+		  " rmtadv: %04x", ethtool_cmd_speed(&ecmd),
+		  ecmd.duplex, lcladv, rmtadv);
 
 	return smsc75xx_update_flowcontrol(dev, ecmd.duplex, lcladv, rmtadv);
 }
@@ -548,28 +548,6 @@
 			"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;
@@ -599,34 +577,6 @@
 	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,
@@ -638,12 +588,6 @@
 	.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)
@@ -782,6 +726,30 @@
 	return usbnet_change_mtu(netdev, new_mtu);
 }
 
+/* Enable or disable Rx checksum offload engine */
+static int smsc75xx_set_features(struct net_device *netdev, u32 features)
+{
+	struct usbnet *dev = netdev_priv(netdev);
+	struct smsc75xx_priv *pdata = (struct smsc75xx_priv *)(dev->data[0]);
+	unsigned long flags;
+	int ret;
+
+	spin_lock_irqsave(&pdata->rfe_ctl_lock, flags);
+
+	if (features & NETIF_F_RXCSUM)
+		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);
+	/* it's racing here! */
+
+	ret = smsc75xx_write_reg(dev, RFE_CTL, pdata->rfe_ctl);
+	check_warn_return(ret, "Error writing RFE_CTL");
+
+	return 0;
+}
+
 static int smsc75xx_reset(struct usbnet *dev)
 {
 	struct smsc75xx_priv *pdata = (struct smsc75xx_priv *)(dev->data[0]);
@@ -960,11 +928,7 @@
 	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_features(dev->net, dev->net->features);
 
 	smsc75xx_set_multicast(dev->net);
 
@@ -1037,6 +1001,7 @@
 	.ndo_validate_addr	= eth_validate_addr,
 	.ndo_do_ioctl 		= smsc75xx_ioctl,
 	.ndo_set_multicast_list = smsc75xx_set_multicast,
+	.ndo_set_features	= smsc75xx_set_features,
 };
 
 static int smsc75xx_bind(struct usbnet *dev, struct usb_interface *intf)
@@ -1065,10 +1030,17 @@
 
 	INIT_WORK(&pdata->set_multicast, smsc75xx_deferred_multicast_write);
 
-	pdata->use_rx_csum = DEFAULT_RX_CSUM_ENABLE;
+	if (DEFAULT_TX_CSUM_ENABLE) {
+		dev->net->features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;
+		if (DEFAULT_TSO_ENABLE)
+			dev->net->features |= NETIF_F_SG |
+				NETIF_F_TSO | NETIF_F_TSO6;
+	}
+	if (DEFAULT_RX_CSUM_ENABLE)
+		dev->net->features |= NETIF_F_RXCSUM;
 
-	/* We have to advertise SG otherwise TSO cannot be enabled */
-	dev->net->features |= NETIF_F_SG;
+	dev->net->hw_features = NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
+		NETIF_F_SG | NETIF_F_TSO | NETIF_F_TSO6 | NETIF_F_RXCSUM;
 
 	/* Init all registers */
 	ret = smsc75xx_reset(dev);
@@ -1091,10 +1063,11 @@
 	}
 }
 
-static void smsc75xx_rx_csum_offload(struct sk_buff *skb, u32 rx_cmd_a,
-				     u32 rx_cmd_b)
+static void smsc75xx_rx_csum_offload(struct usbnet *dev, struct sk_buff *skb,
+				     u32 rx_cmd_a, u32 rx_cmd_b)
 {
-	if (unlikely(rx_cmd_a & RX_CMD_A_LCSM)) {
+	if (!(dev->net->features & NETIF_F_RXCSUM) ||
+	    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));
@@ -1104,8 +1077,6 @@
 
 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;
@@ -1145,11 +1116,8 @@
 
 			/* 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;
+				smsc75xx_rx_csum_offload(dev, skb, rx_cmd_a,
+					rx_cmd_b);
 
 				skb_trim(skb, skb->len - 4); /* remove fcs */
 				skb->truesize = size + sizeof(struct sk_buff);
@@ -1167,11 +1135,8 @@
 			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;
+			smsc75xx_rx_csum_offload(dev, ax_skb, rx_cmd_a,
+				rx_cmd_b);
 
 			skb_trim(ax_skb, ax_skb->len - 4); /* remove fcs */
 			ax_skb->truesize = size + sizeof(struct sk_buff);
diff -druN linux-2.6.39-libre/drivers/net/usb/smsc95xx.c linux-3.0-rc7-libre/drivers/net/usb/smsc95xx.c
--- linux-2.6.39-libre/drivers/net/usb/smsc95xx.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/usb/smsc95xx.c	2011-07-11 19:51:52.000000000 -0400
@@ -52,8 +52,6 @@
 	u32 hash_hi;
 	u32 hash_lo;
 	spinlock_t mac_cr_lock;
-	bool use_tx_csum;
-	bool use_rx_csum;
 };
 
 struct usb_context {
@@ -459,7 +457,7 @@
 {
 	struct smsc95xx_priv *pdata = (struct smsc95xx_priv *)(dev->data[0]);
 	struct mii_if_info *mii = &dev->mii;
-	struct ethtool_cmd ecmd;
+	struct ethtool_cmd ecmd = { .cmd = ETHTOOL_GSET };
 	unsigned long flags;
 	u16 lcladv, rmtadv;
 	u32 intdata;
@@ -474,8 +472,9 @@
 	lcladv = smsc95xx_mdio_read(dev->net, mii->phy_id, MII_ADVERTISE);
 	rmtadv = smsc95xx_mdio_read(dev->net, mii->phy_id, MII_LPA);
 
-	netif_dbg(dev, link, dev->net, "speed: %d duplex: %d lcladv: %04x rmtadv: %04x\n",
-		  ecmd.speed, ecmd.duplex, lcladv, rmtadv);
+	netif_dbg(dev, link, dev->net,
+		  "speed: %u duplex: %d lcladv: %04x rmtadv: %04x\n",
+		  ethtool_cmd_speed(&ecmd), ecmd.duplex, lcladv, rmtadv);
 
 	spin_lock_irqsave(&pdata->mac_cr_lock, flags);
 	if (ecmd.duplex != DUPLEX_FULL) {
@@ -517,22 +516,24 @@
 }
 
 /* Enable or disable Tx & Rx checksum offload engines */
-static int smsc95xx_set_csums(struct usbnet *dev)
+static int smsc95xx_set_features(struct net_device *netdev, u32 features)
 {
-	struct smsc95xx_priv *pdata = (struct smsc95xx_priv *)(dev->data[0]);
+	struct usbnet *dev = netdev_priv(netdev);
 	u32 read_buf;
-	int ret = smsc95xx_read_reg(dev, COE_CR, &read_buf);
+	int ret;
+
+	ret = smsc95xx_read_reg(dev, COE_CR, &read_buf);
 	if (ret < 0) {
 		netdev_warn(dev->net, "Failed to read COE_CR: %d\n", ret);
 		return ret;
 	}
 
-	if (pdata->use_tx_csum)
+	if (features & NETIF_F_HW_CSUM)
 		read_buf |= Tx_COE_EN_;
 	else
 		read_buf &= ~Tx_COE_EN_;
 
-	if (pdata->use_rx_csum)
+	if (features & NETIF_F_RXCSUM)
 		read_buf |= Rx_COE_EN_;
 	else
 		read_buf &= ~Rx_COE_EN_;
@@ -576,43 +577,6 @@
 	return smsc95xx_write_eeprom(dev, ee->offset, ee->len, data);
 }
 
-static u32 smsc95xx_ethtool_get_rx_csum(struct net_device *netdev)
-{
-	struct usbnet *dev = netdev_priv(netdev);
-	struct smsc95xx_priv *pdata = (struct smsc95xx_priv *)(dev->data[0]);
-
-	return pdata->use_rx_csum;
-}
-
-static int smsc95xx_ethtool_set_rx_csum(struct net_device *netdev, u32 val)
-{
-	struct usbnet *dev = netdev_priv(netdev);
-	struct smsc95xx_priv *pdata = (struct smsc95xx_priv *)(dev->data[0]);
-
-	pdata->use_rx_csum = !!val;
-
-	return smsc95xx_set_csums(dev);
-}
-
-static u32 smsc95xx_ethtool_get_tx_csum(struct net_device *netdev)
-{
-	struct usbnet *dev = netdev_priv(netdev);
-	struct smsc95xx_priv *pdata = (struct smsc95xx_priv *)(dev->data[0]);
-
-	return pdata->use_tx_csum;
-}
-
-static int smsc95xx_ethtool_set_tx_csum(struct net_device *netdev, u32 val)
-{
-	struct usbnet *dev = netdev_priv(netdev);
-	struct smsc95xx_priv *pdata = (struct smsc95xx_priv *)(dev->data[0]);
-
-	pdata->use_tx_csum = !!val;
-
-	ethtool_op_set_tx_hw_csum(netdev, pdata->use_tx_csum);
-	return smsc95xx_set_csums(dev);
-}
-
 static const struct ethtool_ops smsc95xx_ethtool_ops = {
 	.get_link	= usbnet_get_link,
 	.nway_reset	= usbnet_nway_reset,
@@ -624,10 +588,6 @@
 	.get_eeprom_len	= smsc95xx_ethtool_get_eeprom_len,
 	.get_eeprom	= smsc95xx_ethtool_get_eeprom,
 	.set_eeprom	= smsc95xx_ethtool_set_eeprom,
-	.get_tx_csum	= smsc95xx_ethtool_get_tx_csum,
-	.set_tx_csum	= smsc95xx_ethtool_set_tx_csum,
-	.get_rx_csum	= smsc95xx_ethtool_get_rx_csum,
-	.set_rx_csum	= smsc95xx_ethtool_set_rx_csum,
 };
 
 static int smsc95xx_ioctl(struct net_device *netdev, struct ifreq *rq, int cmd)
@@ -755,7 +715,6 @@
 static int smsc95xx_reset(struct usbnet *dev)
 {
 	struct smsc95xx_priv *pdata = (struct smsc95xx_priv *)(dev->data[0]);
-	struct net_device *netdev = dev->net;
 	u32 read_buf, write_buf, burst_cap;
 	int ret = 0, timeout;
 
@@ -975,12 +934,7 @@
 	}
 
 	/* Enable or disable checksum offload engines */
-	ethtool_op_set_tx_hw_csum(netdev, pdata->use_tx_csum);
-	ret = smsc95xx_set_csums(dev);
-	if (ret < 0) {
-		netdev_warn(dev->net, "Failed to set csum offload: %d\n", ret);
-		return ret;
-	}
+	smsc95xx_set_features(dev->net, dev->net->features);
 
 	smsc95xx_set_multicast(dev->net);
 
@@ -1019,6 +973,7 @@
 	.ndo_validate_addr	= eth_validate_addr,
 	.ndo_do_ioctl 		= smsc95xx_ioctl,
 	.ndo_set_multicast_list = smsc95xx_set_multicast,
+	.ndo_set_features	= smsc95xx_set_features,
 };
 
 static int smsc95xx_bind(struct usbnet *dev, struct usb_interface *intf)
@@ -1045,8 +1000,12 @@
 
 	spin_lock_init(&pdata->mac_cr_lock);
 
-	pdata->use_tx_csum = DEFAULT_TX_CSUM_ENABLE;
-	pdata->use_rx_csum = DEFAULT_RX_CSUM_ENABLE;
+	if (DEFAULT_TX_CSUM_ENABLE)
+		dev->net->features |= NETIF_F_HW_CSUM;
+	if (DEFAULT_RX_CSUM_ENABLE)
+		dev->net->features |= NETIF_F_RXCSUM;
+
+	dev->net->hw_features = NETIF_F_HW_CSUM | NETIF_F_RXCSUM;
 
 	smsc95xx_init_mac_address(dev);
 
@@ -1056,7 +1015,7 @@
 	dev->net->netdev_ops = &smsc95xx_netdev_ops;
 	dev->net->ethtool_ops = &smsc95xx_ethtool_ops;
 	dev->net->flags |= IFF_MULTICAST;
-	dev->net->hard_header_len += SMSC95XX_TX_OVERHEAD;
+	dev->net->hard_header_len += SMSC95XX_TX_OVERHEAD_CSUM;
 	return 0;
 }
 
@@ -1080,8 +1039,6 @@
 
 static int smsc95xx_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
 {
-	struct smsc95xx_priv *pdata = (struct smsc95xx_priv *)(dev->data[0]);
-
 	while (skb->len > 0) {
 		u32 header, align_count;
 		struct sk_buff *ax_skb;
@@ -1123,7 +1080,7 @@
 
 			/* last frame in this batch */
 			if (skb->len == size) {
-				if (pdata->use_rx_csum)
+				if (dev->net->features & NETIF_F_RXCSUM)
 					smsc95xx_rx_csum_offload(skb);
 				skb_trim(skb, skb->len - 4); /* remove fcs */
 				skb->truesize = size + sizeof(struct sk_buff);
@@ -1141,7 +1098,7 @@
 			ax_skb->data = packet;
 			skb_set_tail_pointer(ax_skb, size);
 
-			if (pdata->use_rx_csum)
+			if (dev->net->features & NETIF_F_RXCSUM)
 				smsc95xx_rx_csum_offload(ax_skb);
 			skb_trim(ax_skb, ax_skb->len - 4); /* remove fcs */
 			ax_skb->truesize = size + sizeof(struct sk_buff);
@@ -1174,8 +1131,7 @@
 static struct sk_buff *smsc95xx_tx_fixup(struct usbnet *dev,
 					 struct sk_buff *skb, gfp_t flags)
 {
-	struct smsc95xx_priv *pdata = (struct smsc95xx_priv *)(dev->data[0]);
-	bool csum = pdata->use_tx_csum && (skb->ip_summed == CHECKSUM_PARTIAL);
+	bool csum = skb->ip_summed == CHECKSUM_PARTIAL;
 	int overhead = csum ? SMSC95XX_TX_OVERHEAD_CSUM : SMSC95XX_TX_OVERHEAD;
 	u32 tx_cmd_a, tx_cmd_b;
 
diff -druN linux-2.6.39-libre/drivers/net/usb/usbnet.c linux-3.0-rc7-libre/drivers/net/usb/usbnet.c
--- linux-2.6.39-libre/drivers/net/usb/usbnet.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/usb/usbnet.c	2011-07-11 19:51:52.000000000 -0400
@@ -109,7 +109,7 @@
 
 		/* take the first altsetting with in-bulk + out-bulk;
 		 * remember any status endpoint, just in case;
-		 * ignore other endpoints and altsetttings.
+		 * ignore other endpoints and altsettings.
 		 */
 		for (ep = 0; ep < alt->desc.bNumEndpoints; ep++) {
 			struct usb_host_endpoint	*e;
@@ -1541,9 +1541,9 @@
 
 static int __init usbnet_init(void)
 {
-	/* compiler should optimize this out */
-	BUILD_BUG_ON (sizeof (((struct sk_buff *)0)->cb)
-			< sizeof (struct skb_data));
+	/* Compiler should optimize this out. */
+	BUILD_BUG_ON(
+		FIELD_SIZEOF(struct sk_buff, cb) < sizeof(struct skb_data));
 
 	random_ether_addr(node_id);
 	return 0;
diff -druN linux-2.6.39-libre/drivers/net/usb/zaurus.c linux-3.0-rc7-libre/drivers/net/usb/zaurus.c
--- linux-2.6.39-libre/drivers/net/usb/zaurus.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/usb/zaurus.c	2011-07-11 19:51:52.000000000 -0400
@@ -331,17 +331,7 @@
 	ZAURUS_MASTER_INTERFACE,
 	.driver_info = ZAURUS_PXA_INFO,
 },
-
-
-/* At least some of the newest PXA units have very different lies about
- * their standards support:  they claim to be cell phones offering
- * direct access to their radios!  (No, they don't conform to CDC MDLM.)
- */
 {
-	USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_MDLM,
-			USB_CDC_PROTO_NONE),
-	.driver_info = (unsigned long) &bogus_mdlm_info,
-}, {
 	/* Motorola MOTOMAGX phones */
 	USB_DEVICE_AND_INTERFACE_INFO(0x22b8, 0x6425, USB_CLASS_COMM,
 			USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE),
diff -druN linux-2.6.39-libre/drivers/net/veth.c linux-3.0-rc7-libre/drivers/net/veth.c
--- linux-2.6.39-libre/drivers/net/veth.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/veth.c	2011-07-11 19:51:52.000000000 -0400
@@ -22,7 +22,6 @@
 
 #define MIN_MTU 68		/* Min L3 MTU */
 #define MAX_MTU 65535		/* Max L3 MTU (arbitrary) */
-#define MTU_PAD (ETH_HLEN + 4)  /* Max difference between L2 and L3 size MTU */
 
 struct veth_net_stats {
 	unsigned long	rx_packets;
@@ -36,7 +35,6 @@
 struct veth_priv {
 	struct net_device *peer;
 	struct veth_net_stats __percpu *stats;
-	unsigned ip_summed;
 };
 
 /*
@@ -53,7 +51,7 @@
 {
 	cmd->supported		= 0;
 	cmd->advertising	= 0;
-	cmd->speed		= SPEED_10000;
+	ethtool_cmd_speed_set(cmd, SPEED_10000);
 	cmd->duplex		= DUPLEX_FULL;
 	cmd->port		= PORT_TP;
 	cmd->phy_address	= 0;
@@ -99,47 +97,10 @@
 	data[0] = priv->peer->ifindex;
 }
 
-static u32 veth_get_rx_csum(struct net_device *dev)
-{
-	struct veth_priv *priv;
-
-	priv = netdev_priv(dev);
-	return priv->ip_summed == CHECKSUM_UNNECESSARY;
-}
-
-static int veth_set_rx_csum(struct net_device *dev, u32 data)
-{
-	struct veth_priv *priv;
-
-	priv = netdev_priv(dev);
-	priv->ip_summed = data ? CHECKSUM_UNNECESSARY : CHECKSUM_NONE;
-	return 0;
-}
-
-static u32 veth_get_tx_csum(struct net_device *dev)
-{
-	return (dev->features & NETIF_F_NO_CSUM) != 0;
-}
-
-static int veth_set_tx_csum(struct net_device *dev, u32 data)
-{
-	if (data)
-		dev->features |= NETIF_F_NO_CSUM;
-	else
-		dev->features &= ~NETIF_F_NO_CSUM;
-	return 0;
-}
-
 static const struct ethtool_ops veth_ethtool_ops = {
 	.get_settings		= veth_get_settings,
 	.get_drvinfo		= veth_get_drvinfo,
 	.get_link		= ethtool_op_get_link,
-	.get_rx_csum		= veth_get_rx_csum,
-	.set_rx_csum		= veth_set_rx_csum,
-	.get_tx_csum		= veth_get_tx_csum,
-	.set_tx_csum		= veth_set_tx_csum,
-	.get_sg			= ethtool_op_get_sg,
-	.set_sg			= ethtool_op_set_sg,
 	.get_strings		= veth_get_strings,
 	.get_sset_count		= veth_get_sset_count,
 	.get_ethtool_stats	= veth_get_ethtool_stats,
@@ -168,8 +129,9 @@
 
 	/* don't change ip_summed == CHECKSUM_PARTIAL, as that
 	   will cause bad checksum on forwarded packets */
-	if (skb->ip_summed == CHECKSUM_NONE)
-		skb->ip_summed = rcv_priv->ip_summed;
+	if (skb->ip_summed == CHECKSUM_NONE &&
+	    rcv->features & NETIF_F_RXCSUM)
+		skb->ip_summed = CHECKSUM_UNNECESSARY;
 
 	length = skb->len;
 	if (dev_forward_skb(rcv, skb) != NET_RX_SUCCESS)
@@ -304,6 +266,8 @@
 	dev->ethtool_ops = &veth_ethtool_ops;
 	dev->features |= NETIF_F_LLTX;
 	dev->destructor = veth_dev_free;
+
+	dev->hw_features = NETIF_F_NO_CSUM | NETIF_F_SG | NETIF_F_RXCSUM;
 }
 
 /*
diff -druN linux-2.6.39-libre/drivers/net/via-rhine.c linux-3.0-rc7-libre/drivers/net/via-rhine.c
--- linux-2.6.39-libre/drivers/net/via-rhine.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/via-rhine.c	2011-07-11 19:51:52.000000000 -0400
@@ -29,6 +29,8 @@
 
 */
 
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #define DRV_NAME	"via-rhine"
 #define DRV_VERSION	"1.5.0"
 #define DRV_RELDATE	"2010-10-09"
@@ -37,6 +39,7 @@
 /* A few user-configurable values.
    These may be modified when a driver module is loaded. */
 
+#define DEBUG
 static int debug = 1;	/* 1 normal messages, 0 quiet .. 7 verbose. */
 static int max_interrupt_work = 20;
 
@@ -111,8 +114,7 @@
 
 /* These identify the driver base version and may not be removed. */
 static const char version[] __devinitconst =
-	KERN_INFO DRV_NAME ".c:v1.10-LK" DRV_VERSION " " DRV_RELDATE
-	" Written by Donald Becker\n";
+	"v1.10-LK" DRV_VERSION " " DRV_RELDATE " Written by Donald Becker";
 
 /* This driver was written to use PCI memory space. Some early versions
    of the Rhine may only work correctly with I/O space accesses. */
@@ -495,14 +497,15 @@
 static void rhine_init_cam_filter(struct net_device *dev);
 static void rhine_update_vcam(struct net_device *dev);
 
-#define RHINE_WAIT_FOR(condition) do {					\
-	int i=1024;							\
-	while (!(condition) && --i)					\
-		;							\
-	if (debug > 1 && i < 512)					\
-		printk(KERN_INFO "%s: %4d cycles used @ %s:%d\n",	\
-				DRV_NAME, 1024-i, __func__, __LINE__);	\
-} while(0)
+#define RHINE_WAIT_FOR(condition)				\
+do {								\
+	int i = 1024;						\
+	while (!(condition) && --i)				\
+		;						\
+	if (debug > 1 && i < 512)				\
+		pr_info("%4d cycles used @ %s:%d\n",		\
+			1024 - i, __func__, __LINE__);		\
+} while (0)
 
 static inline u32 get_intr_status(struct net_device *dev)
 {
@@ -571,8 +574,8 @@
 			default:
 				reason = "Unknown";
 			}
-			printk(KERN_INFO "%s: Woke system up. Reason: %s.\n",
-			       DRV_NAME, reason);
+			netdev_info(dev, "Woke system up. Reason: %s\n",
+				    reason);
 		}
 	}
 }
@@ -586,8 +589,7 @@
 	IOSYNC;
 
 	if (ioread8(ioaddr + ChipCmd1) & Cmd1Reset) {
-		printk(KERN_INFO "%s: Reset not complete yet. "
-			"Trying harder.\n", DRV_NAME);
+		netdev_info(dev, "Reset not complete yet. Trying harder.\n");
 
 		/* Force reset */
 		if (rp->quirks & rqForceReset)
@@ -598,9 +600,9 @@
 	}
 
 	if (debug > 1)
-		printk(KERN_INFO "%s: Reset %s.\n", dev->name,
-			(ioread8(ioaddr + ChipCmd1) & Cmd1Reset) ?
-			"failed" : "succeeded");
+		netdev_info(dev, "Reset %s\n",
+			    (ioread8(ioaddr + ChipCmd1) & Cmd1Reset) ?
+			    "failed" : "succeeded");
 }
 
 #ifdef USE_MMIO
@@ -728,9 +730,7 @@
 
 /* when built into the kernel, we only print version if device is found */
 #ifndef MODULE
-	static int printed_version;
-	if (!printed_version++)
-		printk(version);
+	pr_info_once("%s\n", version);
 #endif
 
 	io_size = 256;
@@ -765,8 +765,8 @@
 	/* this should always be supported */
 	rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
 	if (rc) {
-		printk(KERN_ERR "32-bit PCI DMA addresses not supported by "
-		       "the card!?\n");
+		dev_err(&pdev->dev,
+			"32-bit PCI DMA addresses not supported by the card!?\n");
 		goto err_out;
 	}
 
@@ -774,7 +774,7 @@
 	if ((pci_resource_len(pdev, 0) < io_size) ||
 	    (pci_resource_len(pdev, 1) < io_size)) {
 		rc = -EIO;
-		printk(KERN_ERR "Insufficient PCI resources, aborting\n");
+		dev_err(&pdev->dev, "Insufficient PCI resources, aborting\n");
 		goto err_out;
 	}
 
@@ -786,7 +786,7 @@
 	dev = alloc_etherdev(sizeof(struct rhine_private));
 	if (!dev) {
 		rc = -ENOMEM;
-		printk(KERN_ERR "alloc_etherdev failed\n");
+		dev_err(&pdev->dev, "alloc_etherdev failed\n");
 		goto err_out;
 	}
 	SET_NETDEV_DEV(dev, &pdev->dev);
@@ -804,8 +804,9 @@
 	ioaddr = pci_iomap(pdev, bar, io_size);
 	if (!ioaddr) {
 		rc = -EIO;
-		printk(KERN_ERR "ioremap failed for device %s, region 0x%X "
-		       "@ 0x%lX\n", pci_name(pdev), io_size, memaddr);
+		dev_err(&pdev->dev,
+			"ioremap failed for device %s, region 0x%X @ 0x%lX\n",
+			pci_name(pdev), io_size, memaddr);
 		goto err_out_free_res;
 	}
 
@@ -820,8 +821,9 @@
 		unsigned char b = readb(ioaddr+reg);
 		if (a != b) {
 			rc = -EIO;
-			printk(KERN_ERR "MMIO do not match PIO [%02x] "
-			       "(%02x != %02x)\n", reg, a, b);
+			dev_err(&pdev->dev,
+				"MMIO do not match PIO [%02x] (%02x != %02x)\n",
+				reg, a, b);
 			goto err_out_unmap;
 		}
 	}
@@ -836,13 +838,15 @@
 
 	for (i = 0; i < 6; i++)
 		dev->dev_addr[i] = ioread8(ioaddr + StationAddr + i);
-	memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
 
-	if (!is_valid_ether_addr(dev->perm_addr)) {
-		rc = -EIO;
-		printk(KERN_ERR "Invalid MAC address\n");
-		goto err_out_unmap;
+	if (!is_valid_ether_addr(dev->dev_addr)) {
+		/* Report it and use a random ethernet address instead */
+		netdev_err(dev, "Invalid MAC address: %pM\n", dev->dev_addr);
+		random_ether_addr(dev->dev_addr);
+		netdev_info(dev, "Using random MAC address: %pM\n",
+			    dev->dev_addr);
 	}
+	memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
 
 	/* For Rhine-I/II, phy_id is loaded from EEPROM */
 	if (!phy_id)
@@ -878,14 +882,14 @@
 	if (rc)
 		goto err_out_unmap;
 
-	printk(KERN_INFO "%s: VIA %s at 0x%lx, %pM, IRQ %d.\n",
-	       dev->name, name,
+	netdev_info(dev, "VIA %s at 0x%lx, %pM, IRQ %d\n",
+		    name,
 #ifdef USE_MMIO
-	       memaddr,
+		    memaddr,
 #else
-	       (long)ioaddr,
+		    (long)ioaddr,
 #endif
-	       dev->dev_addr, pdev->irq);
+		    dev->dev_addr, pdev->irq);
 
 	pci_set_drvdata(pdev, dev);
 
@@ -896,11 +900,11 @@
 		mdio_write(dev, phy_id, MII_BMCR, mii_cmd);
 		if (mii_status != 0xffff && mii_status != 0x0000) {
 			rp->mii_if.advertising = mdio_read(dev, phy_id, 4);
-			printk(KERN_INFO "%s: MII PHY found at address "
-			       "%d, status 0x%4.4x advertising %4.4x "
-			       "Link %4.4x.\n", dev->name, phy_id,
-			       mii_status, rp->mii_if.advertising,
-			       mdio_read(dev, phy_id, 5));
+			netdev_info(dev,
+				    "MII PHY found at address %d, status 0x%04x advertising %04x Link %04x\n",
+				    phy_id,
+				    mii_status, rp->mii_if.advertising,
+				    mdio_read(dev, phy_id, 5));
 
 			/* set IFF_RUNNING */
 			if (mii_status & BMSR_LSTATUS)
@@ -912,8 +916,7 @@
 	}
 	rp->mii_if.phy_id = phy_id;
 	if (debug > 1 && avoid_D3)
-		printk(KERN_INFO "%s: No D3 power state at shutdown.\n",
-		       dev->name);
+		netdev_info(dev, "No D3 power state at shutdown\n");
 
 	return 0;
 
@@ -938,7 +941,7 @@
 				    TX_RING_SIZE * sizeof(struct tx_desc),
 				    &ring_dma);
 	if (!ring) {
-		printk(KERN_ERR "Could not allocate DMA memory.\n");
+		netdev_err(dev, "Could not allocate DMA memory\n");
 		return -ENOMEM;
 	}
 	if (rp->quirks & rqRhineI) {
@@ -1098,8 +1101,8 @@
 	    iowrite8(ioread8(ioaddr + ChipCmd1) & ~Cmd1FDuplex,
 		   ioaddr + ChipCmd1);
 	if (debug > 1)
-		printk(KERN_INFO "%s: force_media %d, carrier %d\n", dev->name,
-			rp->mii_if.force_media, netif_carrier_ok(dev));
+		netdev_info(dev, "force_media %d, carrier %d\n",
+			    rp->mii_if.force_media, netif_carrier_ok(dev));
 }
 
 /* Called after status of force_media possibly changed */
@@ -1113,9 +1116,8 @@
 	else	/* Let MMI library update carrier status */
 		rhine_check_media(mii->dev, 0);
 	if (debug > 1)
-		printk(KERN_INFO "%s: force_media %d, carrier %d\n",
-		       mii->dev->name, mii->force_media,
-		       netif_carrier_ok(mii->dev));
+		netdev_info(mii->dev, "force_media %d, carrier %d\n",
+			    mii->force_media, netif_carrier_ok(mii->dev));
 }
 
 /**
@@ -1402,8 +1404,7 @@
 		return rc;
 
 	if (debug > 1)
-		printk(KERN_DEBUG "%s: rhine_open() irq %d.\n",
-		       dev->name, rp->pdev->irq);
+		netdev_dbg(dev, "%s() irq %d\n", __func__, rp->pdev->irq);
 
 	rc = alloc_ring(dev);
 	if (rc) {
@@ -1415,10 +1416,9 @@
 	rhine_chip_reset(dev);
 	init_registers(dev);
 	if (debug > 2)
-		printk(KERN_DEBUG "%s: Done rhine_open(), status %4.4x "
-		       "MII status: %4.4x.\n",
-		       dev->name, ioread16(ioaddr + ChipCmd),
-		       mdio_read(dev, rp->mii_if.phy_id, MII_BMSR));
+		netdev_dbg(dev, "%s() Done - status %04x MII status: %04x\n",
+			   __func__, ioread16(ioaddr + ChipCmd),
+			   mdio_read(dev, rp->mii_if.phy_id, MII_BMSR));
 
 	netif_start_queue(dev);
 
@@ -1461,10 +1461,9 @@
 	struct rhine_private *rp = netdev_priv(dev);
 	void __iomem *ioaddr = rp->base;
 
-	printk(KERN_WARNING "%s: Transmit timed out, status %4.4x, PHY status "
-	       "%4.4x, resetting...\n",
-	       dev->name, ioread16(ioaddr + IntrStatus),
-	       mdio_read(dev, rp->mii_if.phy_id, MII_BMSR));
+	netdev_warn(dev, "Transmit timed out, status %04x, PHY status %04x, resetting...\n",
+		    ioread16(ioaddr + IntrStatus),
+		    mdio_read(dev, rp->mii_if.phy_id, MII_BMSR));
 
 	schedule_work(&rp->reset_task);
 }
@@ -1551,8 +1550,8 @@
 	spin_unlock_irqrestore(&rp->lock, flags);
 
 	if (debug > 4) {
-		printk(KERN_DEBUG "%s: Transmit frame #%d queued in slot %d.\n",
-		       dev->name, rp->cur_tx-1, entry);
+		netdev_dbg(dev, "Transmit frame #%d queued in slot %d\n",
+			   rp->cur_tx-1, entry);
 	}
 	return NETDEV_TX_OK;
 }
@@ -1578,8 +1577,8 @@
 		IOSYNC;
 
 		if (debug > 4)
-			printk(KERN_DEBUG "%s: Interrupt, status %8.8x.\n",
-			       dev->name, intr_status);
+			netdev_dbg(dev, "Interrupt, status %08x\n",
+				   intr_status);
 
 		if (intr_status & (IntrRxDone | IntrRxErr | IntrRxDropped |
 				   IntrRxWakeUp | IntrRxEmpty | IntrRxNoBuf)) {
@@ -1597,9 +1596,9 @@
 				RHINE_WAIT_FOR(!(ioread8(ioaddr+ChipCmd) & CmdTxOn));
 				if (debug > 2 &&
 				    ioread8(ioaddr+ChipCmd) & CmdTxOn)
-					printk(KERN_WARNING "%s: "
-					       "rhine_interrupt() Tx engine "
-					       "still on.\n", dev->name);
+					netdev_warn(dev,
+						    "%s: Tx engine still on\n",
+						    __func__);
 			}
 			rhine_tx(dev);
 		}
@@ -1611,16 +1610,15 @@
 			rhine_error(dev, intr_status);
 
 		if (--boguscnt < 0) {
-			printk(KERN_WARNING "%s: Too much work at interrupt, "
-			       "status=%#8.8x.\n",
-			       dev->name, intr_status);
+			netdev_warn(dev, "Too much work at interrupt, status=%#08x\n",
+				    intr_status);
 			break;
 		}
 	}
 
 	if (debug > 3)
-		printk(KERN_DEBUG "%s: exiting interrupt, status=%8.8x.\n",
-		       dev->name, ioread16(ioaddr + IntrStatus));
+		netdev_dbg(dev, "exiting interrupt, status=%08x\n",
+			   ioread16(ioaddr + IntrStatus));
 	return IRQ_RETVAL(handled);
 }
 
@@ -1637,15 +1635,14 @@
 	while (rp->dirty_tx != rp->cur_tx) {
 		txstatus = le32_to_cpu(rp->tx_ring[entry].tx_status);
 		if (debug > 6)
-			printk(KERN_DEBUG "Tx scavenge %d status %8.8x.\n",
-			       entry, txstatus);
+			netdev_dbg(dev, "Tx scavenge %d status %08x\n",
+				   entry, txstatus);
 		if (txstatus & DescOwn)
 			break;
 		if (txstatus & 0x8000) {
 			if (debug > 1)
-				printk(KERN_DEBUG "%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 & 0x0400)
 				dev->stats.tx_carrier_errors++;
@@ -1668,9 +1665,9 @@
 			else
 				dev->stats.collisions += txstatus & 0x0F;
 			if (debug > 6)
-				printk(KERN_DEBUG "collisions: %1.1x:%1.1x\n",
-				       (txstatus >> 3) & 0xF,
-				       txstatus & 0xF);
+				netdev_dbg(dev, "collisions: %1.1x:%1.1x\n",
+					   (txstatus >> 3) & 0xF,
+					   txstatus & 0xF);
 			dev->stats.tx_bytes += rp->tx_skbuff[entry]->len;
 			dev->stats.tx_packets++;
 		}
@@ -1703,7 +1700,7 @@
 static inline u16 rhine_get_vlan_tci(struct sk_buff *skb, int data_size)
 {
 	u8 *trailer = (u8 *)skb->data + ((data_size + 3) & ~3) + 2;
-	return ntohs(*(u16 *)trailer);
+	return be16_to_cpup((__be16 *)trailer);
 }
 
 /* Process up to limit frames from receive ring */
@@ -1714,9 +1711,9 @@
 	int entry = rp->cur_rx % RX_RING_SIZE;
 
 	if (debug > 4) {
-		printk(KERN_DEBUG "%s: rhine_rx(), entry %d status %8.8x.\n",
-		       dev->name, entry,
-		       le32_to_cpu(rp->rx_head_desc->rx_status));
+		netdev_dbg(dev, "%s(), entry %d status %08x\n",
+			   __func__, entry,
+			   le32_to_cpu(rp->rx_head_desc->rx_status));
 	}
 
 	/* If EOP is set on the next entry, it's a new packet. Send it up. */
@@ -1730,26 +1727,26 @@
 			break;
 
 		if (debug > 4)
-			printk(KERN_DEBUG "rhine_rx() status is %8.8x.\n",
-			       desc_status);
+			netdev_dbg(dev, "%s() status is %08x\n",
+				   __func__, desc_status);
 
 		if ((desc_status & (RxWholePkt | RxErr)) != RxWholePkt) {
 			if ((desc_status & RxWholePkt) != RxWholePkt) {
-				printk(KERN_WARNING "%s: Oversized Ethernet "
-				       "frame spanned multiple buffers, entry "
-				       "%#x length %d status %8.8x!\n",
-				       dev->name, entry, data_size,
-				       desc_status);
-				printk(KERN_WARNING "%s: Oversized Ethernet "
-				       "frame %p vs %p.\n", dev->name,
-				       rp->rx_head_desc, &rp->rx_ring[entry]);
+				netdev_warn(dev,
+	"Oversized Ethernet frame spanned multiple buffers, "
+	"entry %#x length %d status %08x!\n",
+					    entry, data_size,
+					    desc_status);
+				netdev_warn(dev,
+					    "Oversized Ethernet frame %p vs %p\n",
+					    rp->rx_head_desc,
+					    &rp->rx_ring[entry]);
 				dev->stats.rx_length_errors++;
 			} else if (desc_status & RxErr) {
 				/* There was a error. */
 				if (debug > 2)
-					printk(KERN_DEBUG "rhine_rx() Rx "
-					       "error was %8.8x.\n",
-					       desc_status);
+					netdev_dbg(dev, "%s() Rx error was %08x\n",
+						   __func__, desc_status);
 				dev->stats.rx_errors++;
 				if (desc_status & 0x0030)
 					dev->stats.rx_length_errors++;
@@ -1791,9 +1788,7 @@
 			} else {
 				skb = rp->rx_skbuff[entry];
 				if (skb == NULL) {
-					printk(KERN_ERR "%s: Inconsistent Rx "
-					       "descriptor chain.\n",
-					       dev->name);
+					netdev_err(dev, "Inconsistent Rx descriptor chain\n");
 					break;
 				}
 				rp->rx_skbuff[entry] = NULL;
@@ -1886,9 +1881,8 @@
 	else {
 		/* This should never happen */
 		if (debug > 1)
-			printk(KERN_WARNING "%s: rhine_restart_tx() "
-			       "Another error occurred %8.8x.\n",
-			       dev->name, intr_status);
+			netdev_warn(dev, "%s() Another error occurred %08x\n",
+				   __func__, intr_status);
 	}
 
 }
@@ -1909,21 +1903,19 @@
 	}
 	if (intr_status & IntrTxAborted) {
 		if (debug > 1)
-			printk(KERN_INFO "%s: Abort %8.8x, frame dropped.\n",
-			       dev->name, intr_status);
+			netdev_info(dev, "Abort %08x, frame dropped\n",
+				    intr_status);
 	}
 	if (intr_status & IntrTxUnderrun) {
 		if (rp->tx_thresh < 0xE0)
 			BYTE_REG_BITS_SET((rp->tx_thresh += 0x20), 0x80, ioaddr + TxConfig);
 		if (debug > 1)
-			printk(KERN_INFO "%s: Transmitter underrun, Tx "
-			       "threshold now %2.2x.\n",
-			       dev->name, rp->tx_thresh);
+			netdev_info(dev, "Transmitter underrun, Tx threshold now %02x\n",
+				    rp->tx_thresh);
 	}
 	if (intr_status & IntrTxDescRace) {
 		if (debug > 2)
-			printk(KERN_INFO "%s: Tx descriptor write-back race.\n",
-			       dev->name);
+			netdev_info(dev, "Tx descriptor write-back race\n");
 	}
 	if ((intr_status & IntrTxError) &&
 	    (intr_status & (IntrTxAborted |
@@ -1932,9 +1924,8 @@
 			BYTE_REG_BITS_SET((rp->tx_thresh += 0x20), 0x80, ioaddr + TxConfig);
 		}
 		if (debug > 1)
-			printk(KERN_INFO "%s: Unspecified error. Tx "
-			       "threshold now %2.2x.\n",
-			       dev->name, rp->tx_thresh);
+			netdev_info(dev, "Unspecified error. Tx threshold now %02x\n",
+				    rp->tx_thresh);
 	}
 	if (intr_status & (IntrTxAborted | IntrTxUnderrun | IntrTxDescRace |
 			   IntrTxError))
@@ -1944,8 +1935,8 @@
 			    IntrTxError | IntrTxAborted | IntrNormalSummary |
 			    IntrTxDescRace)) {
 		if (debug > 1)
-			printk(KERN_ERR "%s: Something Wicked happened! "
-			       "%8.8x.\n", dev->name, intr_status);
+			netdev_err(dev, "Something Wicked happened! %08x\n",
+				   intr_status);
 	}
 
 	spin_unlock(&rp->lock);
@@ -2145,9 +2136,8 @@
 	spin_lock_irq(&rp->lock);
 
 	if (debug > 1)
-		printk(KERN_DEBUG "%s: Shutting down ethercard, "
-		       "status was %4.4x.\n",
-		       dev->name, ioread16(ioaddr + ChipCmd));
+		netdev_dbg(dev, "Shutting down ethercard, status was %04x\n",
+			   ioread16(ioaddr + ChipCmd));
 
 	/* Switch to loopback mode to avoid hardware races. */
 	iowrite8(rp->tx_thresh | 0x02, ioaddr + TxConfig);
@@ -2265,12 +2255,12 @@
 		return 0;
 
 	if (request_irq(dev->irq, rhine_interrupt, IRQF_SHARED, dev->name, dev))
-		printk(KERN_ERR "via-rhine %s: request_irq failed\n", dev->name);
+		netdev_err(dev, "request_irq failed\n");
 
 	ret = pci_set_power_state(pdev, PCI_D0);
 	if (debug > 1)
-		printk(KERN_INFO "%s: Entering power state D0 %s (%d).\n",
-			dev->name, ret ? "failed" : "succeeded", ret);
+		netdev_info(dev, "Entering power state D0 %s (%d)\n",
+			    ret ? "failed" : "succeeded", ret);
 
 	pci_restore_state(pdev);
 
@@ -2326,17 +2316,15 @@
 {
 /* when a module, this is printed whether or not devices are found in probe */
 #ifdef MODULE
-	printk(version);
+	pr_info("%s\n", version);
 #endif
 	if (dmi_check_system(rhine_dmi_table)) {
 		/* these BIOSes fail at PXE boot if chip is in D3 */
 		avoid_D3 = 1;
-		printk(KERN_WARNING "%s: Broken BIOS detected, avoid_D3 "
-				    "enabled.\n",
-		       DRV_NAME);
+		pr_warn("Broken BIOS detected, avoid_D3 enabled\n");
 	}
 	else if (avoid_D3)
-		printk(KERN_INFO "%s: avoid_D3 set.\n", DRV_NAME);
+		pr_info("avoid_D3 set\n");
 
 	return pci_register_driver(&rhine_driver);
 }
diff -druN linux-2.6.39-libre/drivers/net/via-velocity.c linux-3.0-rc7-libre/drivers/net/via-velocity.c
--- linux-2.6.39-libre/drivers/net/via-velocity.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/via-velocity.c	2011-07-11 19:51:52.000000000 -0400
@@ -2600,8 +2600,7 @@
 	/*
 	 *	Handle hardware checksum
 	 */
-	if ((dev->features & NETIF_F_IP_CSUM) &&
-	    (skb->ip_summed == CHECKSUM_PARTIAL)) {
+	if (skb->ip_summed == CHECKSUM_PARTIAL) {
 		const struct iphdr *ip = ip_hdr(skb);
 		if (ip->protocol == IPPROTO_TCP)
 			td_ptr->tdesc1.TCR |= TCR0_TCPCK;
@@ -2841,6 +2840,7 @@
 	dev->ethtool_ops = &velocity_ethtool_ops;
 	netif_napi_add(dev, &vptr->napi, velocity_poll, VELOCITY_NAPI_WEIGHT);
 
+	dev->hw_features = NETIF_F_IP_CSUM | NETIF_F_SG | NETIF_F_HW_VLAN_TX;
 	dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_FILTER |
 		NETIF_F_HW_VLAN_RX | NETIF_F_IP_CSUM;
 
@@ -3182,7 +3182,8 @@
 		pci_set_power_state(vptr->pdev, PCI_D3hot);
 }
 
-static int velocity_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
+static int velocity_get_settings(struct net_device *dev,
+				 struct ethtool_cmd *cmd)
 {
 	struct velocity_info *vptr = netdev_priv(dev);
 	struct mac_regs __iomem *regs = vptr->mac_regs;
@@ -3228,12 +3229,14 @@
 			break;
 		}
 	}
+
 	if (status & VELOCITY_SPEED_1000)
-		cmd->speed = SPEED_1000;
+		ethtool_cmd_speed_set(cmd, SPEED_1000);
 	else if (status & VELOCITY_SPEED_100)
-		cmd->speed = SPEED_100;
+		ethtool_cmd_speed_set(cmd, SPEED_100);
 	else
-		cmd->speed = SPEED_10;
+		ethtool_cmd_speed_set(cmd, SPEED_10);
+
 	cmd->autoneg = (status & VELOCITY_AUTONEG_ENABLE) ? AUTONEG_ENABLE : AUTONEG_DISABLE;
 	cmd->port = PORT_TP;
 	cmd->transceiver = XCVR_INTERNAL;
@@ -3247,9 +3250,11 @@
 	return 0;
 }
 
-static int velocity_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
+static int velocity_set_settings(struct net_device *dev,
+				 struct ethtool_cmd *cmd)
 {
 	struct velocity_info *vptr = netdev_priv(dev);
+	u32 speed = ethtool_cmd_speed(cmd);
 	u32 curr_status;
 	u32 new_status = 0;
 	int ret = 0;
@@ -3258,9 +3263,9 @@
 	curr_status &= (~VELOCITY_LINK_FAIL);
 
 	new_status |= ((cmd->autoneg) ? VELOCITY_AUTONEG_ENABLE : 0);
-	new_status |= ((cmd->speed == SPEED_1000) ? VELOCITY_SPEED_1000 : 0);
-	new_status |= ((cmd->speed == SPEED_100) ? VELOCITY_SPEED_100 : 0);
-	new_status |= ((cmd->speed == SPEED_10) ? VELOCITY_SPEED_10 : 0);
+	new_status |= ((speed == SPEED_1000) ? VELOCITY_SPEED_1000 : 0);
+	new_status |= ((speed == SPEED_100) ? VELOCITY_SPEED_100 : 0);
+	new_status |= ((speed == SPEED_10) ? VELOCITY_SPEED_10 : 0);
 	new_status |= ((cmd->duplex == DUPLEX_FULL) ? VELOCITY_DUPLEX_FULL : 0);
 
 	if ((new_status & VELOCITY_AUTONEG_ENABLE) &&
@@ -3457,13 +3462,10 @@
 	.get_settings	=	velocity_get_settings,
 	.set_settings	=	velocity_set_settings,
 	.get_drvinfo	=	velocity_get_drvinfo,
-	.set_tx_csum	=	ethtool_op_set_tx_csum,
-	.get_tx_csum	=	ethtool_op_get_tx_csum,
 	.get_wol	=	velocity_ethtool_get_wol,
 	.set_wol	=	velocity_ethtool_set_wol,
 	.get_msglevel	=	velocity_get_msglevel,
 	.set_msglevel	=	velocity_set_msglevel,
-	.set_sg 	=	ethtool_op_set_sg,
 	.get_link	=	velocity_get_link,
 	.get_coalesce	=	velocity_get_coalesce,
 	.set_coalesce	=	velocity_set_coalesce,
diff -druN linux-2.6.39-libre/drivers/net/via-velocity.h linux-3.0-rc7-libre/drivers/net/via-velocity.h
--- linux-2.6.39-libre/drivers/net/via-velocity.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/via-velocity.h	2011-07-11 19:51:52.000000000 -0400
@@ -1096,7 +1096,7 @@
 
 	volatile __le16 PatternCRC[8];	/* 0xB0 */
 	volatile __le32 ByteMask[4][4];	/* 0xC0 */
-} __packed;
+};
 
 
 enum hw_mib {
diff -druN linux-2.6.39-libre/drivers/net/virtio_net.c linux-3.0-rc7-libre/drivers/net/virtio_net.c
--- linux-2.6.39-libre/drivers/net/virtio_net.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/virtio_net.c	2011-07-11 19:51:52.000000000 -0400
@@ -609,7 +609,7 @@
 	 * before it gets out of hand.  Naturally, this wastes entries. */
 	if (capacity < 2+MAX_SKB_FRAGS) {
 		netif_stop_queue(dev);
-		if (unlikely(!virtqueue_enable_cb(vi->svq))) {
+		if (unlikely(!virtqueue_enable_cb_delayed(vi->svq))) {
 			/* More just got used, free them then recheck. */
 			capacity += free_old_xmit_skbs(vi);
 			if (capacity >= 2+MAX_SKB_FRAGS) {
@@ -710,17 +710,6 @@
 	return 0;
 }
 
-static int virtnet_set_tx_csum(struct net_device *dev, u32 data)
-{
-	struct virtnet_info *vi = netdev_priv(dev);
-	struct virtio_device *vdev = vi->vdev;
-
-	if (data && !virtio_has_feature(vdev, VIRTIO_NET_F_CSUM))
-		return -ENOSYS;
-
-	return ethtool_op_set_tx_hw_csum(dev, data);
-}
-
 static void virtnet_set_rx_mode(struct net_device *dev)
 {
 	struct virtnet_info *vi = netdev_priv(dev);
@@ -822,10 +811,6 @@
 }
 
 static const struct ethtool_ops virtnet_ethtool_ops = {
-	.set_tx_csum = virtnet_set_tx_csum,
-	.set_sg = ethtool_op_set_sg,
-	.set_tso = ethtool_op_set_tso,
-	.set_ufo = ethtool_op_set_ufo,
 	.get_link = ethtool_op_get_link,
 };
 
@@ -912,22 +897,29 @@
 	SET_NETDEV_DEV(dev, &vdev->dev);
 
 	/* Do we support "hardware" checksums? */
-	if (csum && virtio_has_feature(vdev, VIRTIO_NET_F_CSUM)) {
+	if (virtio_has_feature(vdev, VIRTIO_NET_F_CSUM)) {
 		/* This opens up the world of extra features. */
-		dev->features |= NETIF_F_HW_CSUM|NETIF_F_SG|NETIF_F_FRAGLIST;
-		if (gso && virtio_has_feature(vdev, VIRTIO_NET_F_GSO)) {
-			dev->features |= NETIF_F_TSO | NETIF_F_UFO
+		dev->hw_features |= NETIF_F_HW_CSUM|NETIF_F_SG|NETIF_F_FRAGLIST;
+		if (csum)
+			dev->features |= NETIF_F_HW_CSUM|NETIF_F_SG|NETIF_F_FRAGLIST;
+
+		if (virtio_has_feature(vdev, VIRTIO_NET_F_GSO)) {
+			dev->hw_features |= NETIF_F_TSO | NETIF_F_UFO
 				| NETIF_F_TSO_ECN | NETIF_F_TSO6;
 		}
 		/* Individual feature bits: what can host handle? */
-		if (gso && virtio_has_feature(vdev, VIRTIO_NET_F_HOST_TSO4))
-			dev->features |= NETIF_F_TSO;
-		if (gso && virtio_has_feature(vdev, VIRTIO_NET_F_HOST_TSO6))
-			dev->features |= NETIF_F_TSO6;
-		if (gso && virtio_has_feature(vdev, VIRTIO_NET_F_HOST_ECN))
-			dev->features |= NETIF_F_TSO_ECN;
-		if (gso && virtio_has_feature(vdev, VIRTIO_NET_F_HOST_UFO))
-			dev->features |= NETIF_F_UFO;
+		if (virtio_has_feature(vdev, VIRTIO_NET_F_HOST_TSO4))
+			dev->hw_features |= NETIF_F_TSO;
+		if (virtio_has_feature(vdev, VIRTIO_NET_F_HOST_TSO6))
+			dev->hw_features |= NETIF_F_TSO6;
+		if (virtio_has_feature(vdev, VIRTIO_NET_F_HOST_ECN))
+			dev->hw_features |= NETIF_F_TSO_ECN;
+		if (virtio_has_feature(vdev, VIRTIO_NET_F_HOST_UFO))
+			dev->hw_features |= NETIF_F_UFO;
+
+		if (gso)
+			dev->features |= dev->hw_features & (NETIF_F_ALL_TSO|NETIF_F_UFO);
+		/* (!csum && gso) case will be fixed by register_netdev() */
 	}
 
 	/* Configuration may specify what MAC to use.  Otherwise random. */
diff -druN linux-2.6.39-libre/drivers/net/vmxnet3/vmxnet3_drv.c linux-3.0-rc7-libre/drivers/net/vmxnet3/vmxnet3_drv.c
--- linux-2.6.39-libre/drivers/net/vmxnet3/vmxnet3_drv.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/vmxnet3/vmxnet3_drv.c	2011-07-11 19:51:52.000000000 -0400
@@ -575,7 +575,7 @@
 	struct vmxnet3_cmd_ring *ring = &rq->rx_ring[ring_idx];
 	u32 val;
 
-	while (num_allocated < num_to_alloc) {
+	while (num_allocated <= num_to_alloc) {
 		struct vmxnet3_rx_buf_info *rbi;
 		union Vmxnet3_GenericDesc *gd;
 
@@ -621,9 +621,15 @@
 
 		BUG_ON(rbi->dma_addr == 0);
 		gd->rxd.addr = cpu_to_le64(rbi->dma_addr);
-		gd->dword[2] = cpu_to_le32((ring->gen << VMXNET3_RXD_GEN_SHIFT)
+		gd->dword[2] = cpu_to_le32((!ring->gen << VMXNET3_RXD_GEN_SHIFT)
 					   | val | rbi->len);
 
+		/* Fill the last buffer but dont mark it ready, or else the
+		 * device will think that the queue is full */
+		if (num_allocated == num_to_alloc)
+			break;
+
+		gd->dword[2] |= cpu_to_le32(ring->gen << VMXNET3_RXD_GEN_SHIFT);
 		num_allocated++;
 		vmxnet3_cmd_ring_adv_next2fill(ring);
 	}
@@ -1083,7 +1089,7 @@
 		struct sk_buff *skb,
 		union Vmxnet3_GenericDesc *gdesc)
 {
-	if (!gdesc->rcd.cnc && adapter->rxcsum) {
+	if (!gdesc->rcd.cnc && adapter->netdev->features & NETIF_F_RXCSUM) {
 		/* typical case: TCP/UDP over IP and both csums are correct */
 		if ((le32_to_cpu(gdesc->dword[3]) & VMXNET3_RCD_CSUM_OK) ==
 							VMXNET3_RCD_CSUM_OK) {
@@ -1140,6 +1146,7 @@
 		VMXNET3_REG_RXPROD, VMXNET3_REG_RXPROD2
 	};
 	u32 num_rxd = 0;
+	bool skip_page_frags = false;
 	struct Vmxnet3_RxCompDesc *rcd;
 	struct vmxnet3_rx_ctx *ctx = &rq->rx_ctx;
 #ifdef __BIG_ENDIAN_BITFIELD
@@ -1150,11 +1157,12 @@
 			  &rxComp);
 	while (rcd->gen == rq->comp_ring.gen) {
 		struct vmxnet3_rx_buf_info *rbi;
-		struct sk_buff *skb;
+		struct sk_buff *skb, *new_skb = NULL;
+		struct page *new_page = NULL;
 		int num_to_alloc;
 		struct Vmxnet3_RxDesc *rxd;
 		u32 idx, ring_idx;
-
+		struct vmxnet3_cmd_ring	*ring = NULL;
 		if (num_rxd >= quota) {
 			/* we may stop even before we see the EOP desc of
 			 * the current pkt
@@ -1165,6 +1173,7 @@
 		BUG_ON(rcd->rqID != rq->qid && rcd->rqID != rq->qid2);
 		idx = rcd->rxdIdx;
 		ring_idx = rcd->rqID < adapter->num_rx_queues ? 0 : 1;
+		ring = rq->rx_ring + ring_idx;
 		vmxnet3_getRxDesc(rxd, &rq->rx_ring[ring_idx].base[idx].rxd,
 				  &rxCmdDesc);
 		rbi = rq->buf_info[ring_idx] + idx;
@@ -1193,37 +1202,80 @@
 				goto rcd_done;
 			}
 
+			skip_page_frags = false;
 			ctx->skb = rbi->skb;
-			rbi->skb = NULL;
+			new_skb = dev_alloc_skb(rbi->len + NET_IP_ALIGN);
+			if (new_skb == NULL) {
+				/* Skb allocation failed, do not handover this
+				 * skb to stack. Reuse it. Drop the existing pkt
+				 */
+				rq->stats.rx_buf_alloc_failure++;
+				ctx->skb = NULL;
+				rq->stats.drop_total++;
+				skip_page_frags = true;
+				goto rcd_done;
+			}
 
 			pci_unmap_single(adapter->pdev, rbi->dma_addr, rbi->len,
 					 PCI_DMA_FROMDEVICE);
 
 			skb_put(ctx->skb, rcd->len);
+
+			/* Immediate refill */
+			new_skb->dev = adapter->netdev;
+			skb_reserve(new_skb, NET_IP_ALIGN);
+			rbi->skb = new_skb;
+			rbi->dma_addr = pci_map_single(adapter->pdev,
+					rbi->skb->data, rbi->len,
+					PCI_DMA_FROMDEVICE);
+			rxd->addr = cpu_to_le64(rbi->dma_addr);
+			rxd->len = rbi->len;
+
 		} else {
-			BUG_ON(ctx->skb == NULL);
+			BUG_ON(ctx->skb == NULL && !skip_page_frags);
+
 			/* non SOP buffer must be type 1 in most cases */
-			if (rbi->buf_type == VMXNET3_RX_BUF_PAGE) {
-				BUG_ON(rxd->btype != VMXNET3_RXD_BTYPE_BODY);
+			BUG_ON(rbi->buf_type != VMXNET3_RX_BUF_PAGE);
+			BUG_ON(rxd->btype != VMXNET3_RXD_BTYPE_BODY);
 
-				if (rcd->len) {
-					pci_unmap_page(adapter->pdev,
-						       rbi->dma_addr, rbi->len,
-						       PCI_DMA_FROMDEVICE);
+			/* If an sop buffer was dropped, skip all
+			 * following non-sop fragments. They will be reused.
+			 */
+			if (skip_page_frags)
+				goto rcd_done;
 
-					vmxnet3_append_frag(ctx->skb, rcd, rbi);
-					rbi->page = NULL;
-				}
-			} else {
-				/*
-				 * The only time a non-SOP buffer is type 0 is
-				 * when it's EOP and error flag is raised, which
-				 * has already been handled.
+			new_page = alloc_page(GFP_ATOMIC);
+			if (unlikely(new_page == NULL)) {
+				/* Replacement page frag could not be allocated.
+				 * Reuse this page. Drop the pkt and free the
+				 * skb which contained this page as a frag. Skip
+				 * processing all the following non-sop frags.
 				 */
-				BUG_ON(true);
+				rq->stats.rx_buf_alloc_failure++;
+				dev_kfree_skb(ctx->skb);
+				ctx->skb = NULL;
+				skip_page_frags = true;
+				goto rcd_done;
 			}
+
+			if (rcd->len) {
+				pci_unmap_page(adapter->pdev,
+					       rbi->dma_addr, rbi->len,
+					       PCI_DMA_FROMDEVICE);
+
+				vmxnet3_append_frag(ctx->skb, rcd, rbi);
+			}
+
+			/* Immediate refill */
+			rbi->page = new_page;
+			rbi->dma_addr = pci_map_page(adapter->pdev, rbi->page,
+						     0, PAGE_SIZE,
+						     PCI_DMA_FROMDEVICE);
+			rxd->addr = cpu_to_le64(rbi->dma_addr);
+			rxd->len = rbi->len;
 		}
 
+
 		skb = ctx->skb;
 		if (rcd->eop) {
 			skb->len += skb->data_len;
@@ -1244,26 +1296,27 @@
 		}
 
 rcd_done:
-		/* device may skip some rx descs */
-		rq->rx_ring[ring_idx].next2comp = idx;
-		VMXNET3_INC_RING_IDX_ONLY(rq->rx_ring[ring_idx].next2comp,
-					  rq->rx_ring[ring_idx].size);
+		/* device may have skipped some rx descs */
+		ring->next2comp = idx;
+		num_to_alloc = vmxnet3_cmd_ring_desc_avail(ring);
+		ring = rq->rx_ring + ring_idx;
+		while (num_to_alloc) {
+			vmxnet3_getRxDesc(rxd, &ring->base[ring->next2fill].rxd,
+					  &rxCmdDesc);
+			BUG_ON(!rxd->addr);
 
-		/* refill rx buffers frequently to avoid starving the h/w */
-		num_to_alloc = vmxnet3_cmd_ring_desc_avail(rq->rx_ring +
-							   ring_idx);
-		if (unlikely(num_to_alloc > VMXNET3_RX_ALLOC_THRESHOLD(rq,
-							ring_idx, adapter))) {
-			vmxnet3_rq_alloc_rx_buf(rq, ring_idx, num_to_alloc,
-						adapter);
+			/* Recv desc is ready to be used by the device */
+			rxd->gen = ring->gen;
+			vmxnet3_cmd_ring_adv_next2fill(ring);
+			num_to_alloc--;
+		}
 
-			/* if needed, update the register */
-			if (unlikely(rq->shared->updateRxProd)) {
-				VMXNET3_WRITE_BAR0_REG(adapter,
-					rxprod_reg[ring_idx] + rq->qid * 8,
-					rq->rx_ring[ring_idx].next2fill);
-				rq->uncommitted[ring_idx] = 0;
-			}
+		/* if needed, update the register */
+		if (unlikely(rq->shared->updateRxProd)) {
+			VMXNET3_WRITE_BAR0_REG(adapter,
+				rxprod_reg[ring_idx] + rq->qid * 8,
+				ring->next2fill);
+			rq->uncommitted[ring_idx] = 0;
 		}
 
 		vmxnet3_comp_ring_adv_next2proc(&rq->comp_ring);
@@ -2082,10 +2135,10 @@
 	devRead->misc.ddLen = cpu_to_le32(sizeof(struct vmxnet3_adapter));
 
 	/* set up feature flags */
-	if (adapter->rxcsum)
+	if (adapter->netdev->features & NETIF_F_RXCSUM)
 		devRead->misc.uptFeatures |= UPT1_F_RXCSUM;
 
-	if (adapter->lro) {
+	if (adapter->netdev->features & NETIF_F_LRO) {
 		devRead->misc.uptFeatures |= UPT1_F_LRO;
 		devRead->misc.maxNumRxSG = cpu_to_le16(1 + MAX_SKB_FRAGS);
 	}
@@ -2594,9 +2647,6 @@
 	if (new_mtu < VMXNET3_MIN_MTU || new_mtu > VMXNET3_MAX_MTU)
 		return -EINVAL;
 
-	if (new_mtu > 1500 && !adapter->jumbo_frame)
-		return -EINVAL;
-
 	netdev->mtu = new_mtu;
 
 	/*
@@ -2642,28 +2692,18 @@
 {
 	struct net_device *netdev = adapter->netdev;
 
-	netdev->features = NETIF_F_SG |
-		NETIF_F_HW_CSUM |
-		NETIF_F_HW_VLAN_TX |
-		NETIF_F_HW_VLAN_RX |
-		NETIF_F_HW_VLAN_FILTER |
-		NETIF_F_TSO |
-		NETIF_F_TSO6 |
-		NETIF_F_LRO;
-
-	printk(KERN_INFO "features: sg csum vlan jf tso tsoIPv6 lro");
-
-	adapter->rxcsum = true;
-	adapter->jumbo_frame = true;
-	adapter->lro = true;
-
-	if (dma64) {
+	netdev->hw_features = NETIF_F_SG | NETIF_F_RXCSUM |
+		NETIF_F_HW_CSUM | NETIF_F_HW_VLAN_TX |
+		NETIF_F_TSO | NETIF_F_TSO6 | NETIF_F_LRO;
+	if (dma64)
 		netdev->features |= NETIF_F_HIGHDMA;
-		printk(" highDMA");
-	}
+	netdev->vlan_features = netdev->hw_features & ~NETIF_F_HW_VLAN_TX;
+	netdev->features = netdev->hw_features |
+		NETIF_F_HW_VLAN_RX | NETIF_F_HW_VLAN_FILTER;
 
-	netdev->vlan_features = netdev->features;
-	printk("\n");
+	netdev_info(adapter->netdev,
+		"features: sg csum vlan jf tso tsoIPv6 lro%s\n",
+		dma64 ? " highDMA" : "");
 }
 
 
@@ -2876,6 +2916,7 @@
 		.ndo_start_xmit = vmxnet3_xmit_frame,
 		.ndo_set_mac_address = vmxnet3_set_mac_addr,
 		.ndo_change_mtu = vmxnet3_change_mtu,
+		.ndo_set_features = vmxnet3_set_features,
 		.ndo_get_stats = vmxnet3_get_stats,
 		.ndo_tx_timeout = vmxnet3_tx_timeout,
 		.ndo_set_multicast_list = vmxnet3_set_mc,
@@ -2896,6 +2937,9 @@
 	int num_tx_queues;
 	int num_rx_queues;
 
+	if (!pci_msi_enabled())
+		enable_mq = 0;
+
 #ifdef VMXNET3_RSS
 	if (enable_mq)
 		num_rx_queues = min(VMXNET3_DEVICE_MAX_RX_QUEUES,
@@ -2903,6 +2947,7 @@
 	else
 #endif
 		num_rx_queues = 1;
+	num_rx_queues = rounddown_pow_of_two(num_rx_queues);
 
 	if (enable_mq)
 		num_tx_queues = min(VMXNET3_DEVICE_MAX_TX_QUEUES,
@@ -2910,6 +2955,7 @@
 	else
 		num_tx_queues = 1;
 
+	num_tx_queues = rounddown_pow_of_two(num_tx_queues);
 	netdev = alloc_etherdev_mq(sizeof(struct vmxnet3_adapter),
 				   max(num_tx_queues, num_rx_queues));
 	printk(KERN_INFO "# of Tx queues : %d, # of Rx queues : %d\n",
@@ -3094,6 +3140,7 @@
 	else
 #endif
 		num_rx_queues = 1;
+	num_rx_queues = rounddown_pow_of_two(num_rx_queues);
 
 	cancel_work_sync(&adapter->work);
 
diff -druN linux-2.6.39-libre/drivers/net/vmxnet3/vmxnet3_ethtool.c linux-3.0-rc7-libre/drivers/net/vmxnet3/vmxnet3_ethtool.c
--- linux-2.6.39-libre/drivers/net/vmxnet3/vmxnet3_ethtool.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/vmxnet3/vmxnet3_ethtool.c	2011-07-11 19:51:52.000000000 -0400
@@ -33,40 +33,6 @@
 };
 
 
-static u32
-vmxnet3_get_rx_csum(struct net_device *netdev)
-{
-	struct vmxnet3_adapter *adapter = netdev_priv(netdev);
-	return adapter->rxcsum;
-}
-
-
-static int
-vmxnet3_set_rx_csum(struct net_device *netdev, u32 val)
-{
-	struct vmxnet3_adapter *adapter = netdev_priv(netdev);
-	unsigned long flags;
-
-	if (adapter->rxcsum != val) {
-		adapter->rxcsum = val;
-		if (netif_running(netdev)) {
-			if (val)
-				adapter->shared->devRead.misc.uptFeatures |=
-				UPT1_F_RXCSUM;
-			else
-				adapter->shared->devRead.misc.uptFeatures &=
-				~UPT1_F_RXCSUM;
-
-			spin_lock_irqsave(&adapter->cmd_lock, flags);
-			VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_CMD,
-					       VMXNET3_CMD_UPDATE_FEATURE);
-			spin_unlock_irqrestore(&adapter->cmd_lock, flags);
-		}
-	}
-	return 0;
-}
-
-
 /* per tq stats maintained by the device */
 static const struct vmxnet3_stat_desc
 vmxnet3_tq_dev_stats[] = {
@@ -296,31 +262,28 @@
 	}
 }
 
-static int
-vmxnet3_set_flags(struct net_device *netdev, u32 data)
+int vmxnet3_set_features(struct net_device *netdev, u32 features)
 {
 	struct vmxnet3_adapter *adapter = netdev_priv(netdev);
-	u8 lro_requested = (data & ETH_FLAG_LRO) == 0 ? 0 : 1;
-	u8 lro_present = (netdev->features & NETIF_F_LRO) == 0 ? 0 : 1;
 	unsigned long flags;
+	u32 changed = features ^ netdev->features;
 
-	if (ethtool_invalid_flags(netdev, data, ETH_FLAG_LRO))
-		return -EINVAL;
-
-	if (lro_requested ^ lro_present) {
-		/* toggle the LRO feature*/
-		netdev->features ^= NETIF_F_LRO;
-
-		/* Update private LRO flag */
-		adapter->lro = lro_requested;
+	if (changed & (NETIF_F_RXCSUM|NETIF_F_LRO)) {
+		if (features & NETIF_F_RXCSUM)
+			adapter->shared->devRead.misc.uptFeatures |=
+			UPT1_F_RXCSUM;
+		else
+			adapter->shared->devRead.misc.uptFeatures &=
+			~UPT1_F_RXCSUM;
 
 		/* update harware LRO capability accordingly */
-		if (lro_requested)
+		if (features & NETIF_F_LRO)
 			adapter->shared->devRead.misc.uptFeatures |=
 							UPT1_F_LRO;
 		else
 			adapter->shared->devRead.misc.uptFeatures &=
 							~UPT1_F_LRO;
+
 		spin_lock_irqsave(&adapter->cmd_lock, flags);
 		VMXNET3_WRITE_BAR1_REG(adapter, VMXNET3_REG_CMD,
 				       VMXNET3_CMD_UPDATE_FEATURE);
@@ -462,10 +425,10 @@
 	ecmd->transceiver = XCVR_INTERNAL;
 
 	if (adapter->link_speed) {
-		ecmd->speed = adapter->link_speed;
+		ethtool_cmd_speed_set(ecmd, adapter->link_speed);
 		ecmd->duplex = DUPLEX_FULL;
 	} else {
-		ecmd->speed = -1;
+		ethtool_cmd_speed_set(ecmd, -1);
 		ecmd->duplex = -1;
 	}
 	return 0;
@@ -657,17 +620,7 @@
 	.get_wol           = vmxnet3_get_wol,
 	.set_wol           = vmxnet3_set_wol,
 	.get_link          = ethtool_op_get_link,
-	.get_rx_csum       = vmxnet3_get_rx_csum,
-	.set_rx_csum       = vmxnet3_set_rx_csum,
-	.get_tx_csum       = ethtool_op_get_tx_csum,
-	.set_tx_csum       = ethtool_op_set_tx_hw_csum,
-	.get_sg            = ethtool_op_get_sg,
-	.set_sg            = ethtool_op_set_sg,
-	.get_tso           = ethtool_op_get_tso,
-	.set_tso           = ethtool_op_set_tso,
 	.get_strings       = vmxnet3_get_strings,
-	.get_flags	   = ethtool_op_get_flags,
-	.set_flags	   = vmxnet3_set_flags,
 	.get_sset_count	   = vmxnet3_get_sset_count,
 	.get_ethtool_stats = vmxnet3_get_ethtool_stats,
 	.get_ringparam     = vmxnet3_get_ringparam,
diff -druN linux-2.6.39-libre/drivers/net/vmxnet3/vmxnet3_int.h linux-3.0-rc7-libre/drivers/net/vmxnet3/vmxnet3_int.h
--- linux-2.6.39-libre/drivers/net/vmxnet3/vmxnet3_int.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/vmxnet3/vmxnet3_int.h	2011-07-11 19:51:52.000000000 -0400
@@ -55,6 +55,7 @@
 #include <linux/if_vlan.h>
 #include <linux/if_arp.h>
 #include <linux/inetdevice.h>
+#include <linux/log2.h>
 
 #include "vmxnet3_defs.h"
 
@@ -68,10 +69,10 @@
 /*
  * Version numbers
  */
-#define VMXNET3_DRIVER_VERSION_STRING   "1.0.25.0-k"
+#define VMXNET3_DRIVER_VERSION_STRING   "1.1.18.0-k"
 
 /* a 32-bit int, each byte encode a verion number in VMXNET3_DRIVER_VERSION */
-#define VMXNET3_DRIVER_VERSION_NUM      0x01001900
+#define VMXNET3_DRIVER_VERSION_NUM      0x01011200
 
 #if defined(CONFIG_PCI_MSI)
 	/* RSS only makes sense if MSI-X is supported. */
@@ -329,10 +330,6 @@
 	u8			__iomem *hw_addr0; /* for BAR 0 */
 	u8			__iomem *hw_addr1; /* for BAR 1 */
 
-	/* feature control */
-	bool				rxcsum;
-	bool				lro;
-	bool				jumbo_frame;
 #ifdef VMXNET3_RSS
 	struct UPT1_RSSConf		*rss_conf;
 	bool				rss;
@@ -404,6 +401,9 @@
 vmxnet3_rq_destroy_all(struct vmxnet3_adapter *adapter);
 
 int
+vmxnet3_set_features(struct net_device *netdev, u32 features);
+
+int
 vmxnet3_create_queues(struct vmxnet3_adapter *adapter,
 		      u32 tx_ring_size, u32 rx_ring_size, u32 rx_ring2_size);
 
diff -druN linux-2.6.39-libre/drivers/net/vxge/vxge-config.c linux-3.0-rc7-libre/drivers/net/vxge/vxge-config.c
--- linux-2.6.39-libre/drivers/net/vxge/vxge-config.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/vxge/vxge-config.c	2011-07-11 19:51:52.000000000 -0400
@@ -159,16 +159,15 @@
 		     u32 fw_memo, u32 offset, u64 *data0, u64 *data1,
 		     u64 *steer_ctrl)
 {
-	struct vxge_hw_vpath_reg __iomem *vp_reg;
+	struct vxge_hw_vpath_reg __iomem *vp_reg = vpath->vp_reg;
 	enum vxge_hw_status status;
 	u64 val64;
-	u32 retry = 0, max_retry = 100;
-
-	vp_reg = vpath->vp_reg;
+	u32 retry = 0, max_retry = 3;
 
-	if (vpath->vp_open) {
-		max_retry = 3;
-		spin_lock(&vpath->lock);
+	spin_lock(&vpath->lock);
+	if (!vpath->vp_open) {
+		spin_unlock(&vpath->lock);
+		max_retry = 100;
 	}
 
 	writeq(*data0, &vp_reg->rts_access_steer_data0);
@@ -1000,7 +999,7 @@
 /**
  * vxge_hw_device_hw_info_get - Get the hw information
  * Returns the vpath mask that has the bits set for each vpath allocated
- * for the driver, FW version information and the first mac addresse for
+ * for the driver, FW version information, and the first mac address for
  * each vpath
  */
 enum vxge_hw_status __devinit
@@ -1064,9 +1063,10 @@
 
 		val64 = readq(&toc->toc_vpath_pointer[i]);
 
+		spin_lock_init(&vpath.lock);
 		vpath.vp_reg = (struct vxge_hw_vpath_reg __iomem *)
 			       (bar0 + val64);
-		vpath.vp_open = 0;
+		vpath.vp_open = VXGE_HW_VP_NOT_OPEN;
 
 		status = __vxge_hw_vpath_pci_func_mode_get(&vpath, hw_info);
 		if (status != VXGE_HW_OK)
@@ -1090,7 +1090,7 @@
 		val64 = readq(&toc->toc_vpath_pointer[i]);
 		vpath.vp_reg = (struct vxge_hw_vpath_reg __iomem *)
 			       (bar0 + val64);
-		vpath.vp_open = 0;
+		vpath.vp_open = VXGE_HW_VP_NOT_OPEN;
 
 		status =  __vxge_hw_vpath_addr_get(&vpath,
 				hw_info->mac_addrs[i],
@@ -4646,7 +4646,27 @@
 		vpath->hldev->tim_int_mask1, vpath->vp_id);
 	hldev->stats.hw_dev_info_stats.vpath_info[vpath->vp_id] = NULL;
 
-	memset(vpath, 0, sizeof(struct __vxge_hw_virtualpath));
+	/* If the whole struct __vxge_hw_virtualpath is zeroed, nothing will
+	 * work after the interface is brought down.
+	 */
+	spin_lock(&vpath->lock);
+	vpath->vp_open = VXGE_HW_VP_NOT_OPEN;
+	spin_unlock(&vpath->lock);
+
+	vpath->vpmgmt_reg = NULL;
+	vpath->nofl_db = NULL;
+	vpath->max_mtu = 0;
+	vpath->vsport_number = 0;
+	vpath->max_kdfc_db = 0;
+	vpath->max_nofl_db = 0;
+	vpath->ringh = NULL;
+	vpath->fifoh = NULL;
+	memset(&vpath->vpath_handles, 0, sizeof(struct list_head));
+	vpath->stats_block = 0;
+	vpath->hw_stats = NULL;
+	vpath->hw_stats_sav = NULL;
+	vpath->sw_stats = NULL;
+
 exit:
 	return;
 }
@@ -4670,7 +4690,7 @@
 
 	vpath = &hldev->virtual_paths[vp_id];
 
-	spin_lock_init(&hldev->virtual_paths[vp_id].lock);
+	spin_lock_init(&vpath->lock);
 	vpath->vp_id = vp_id;
 	vpath->vp_open = VXGE_HW_VP_OPEN;
 	vpath->hldev = hldev;
@@ -5019,10 +5039,6 @@
 
 	__vxge_hw_vp_terminate(devh, vp_id);
 
-	spin_lock(&vpath->lock);
-	vpath->vp_open = VXGE_HW_VP_NOT_OPEN;
-	spin_unlock(&vpath->lock);
-
 vpath_close_exit:
 	return status;
 }
diff -druN linux-2.6.39-libre/drivers/net/vxge/vxge-config.h linux-3.0-rc7-libre/drivers/net/vxge/vxge-config.h
--- linux-2.6.39-libre/drivers/net/vxge/vxge-config.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/vxge/vxge-config.h	2011-07-11 19:51:52.000000000 -0400
@@ -412,44 +412,48 @@
  * See also: struct vxge_hw_tim_intr_config{}.
  */
 struct vxge_hw_device_config {
-	u32				dma_blockpool_initial;
-	u32				dma_blockpool_max;
-#define VXGE_HW_MIN_DMA_BLOCK_POOL_SIZE			0
-#define VXGE_HW_INITIAL_DMA_BLOCK_POOL_SIZE		0
-#define VXGE_HW_INCR_DMA_BLOCK_POOL_SIZE		4
-#define VXGE_HW_MAX_DMA_BLOCK_POOL_SIZE			4096
+	u32					device_poll_millis;
+#define VXGE_HW_MIN_DEVICE_POLL_MILLIS		1
+#define VXGE_HW_MAX_DEVICE_POLL_MILLIS		100000
+#define VXGE_HW_DEF_DEVICE_POLL_MILLIS		1000
 
-#define        VXGE_HW_MAX_PAYLOAD_SIZE_512		2
+	u32					dma_blockpool_initial;
+	u32					dma_blockpool_max;
+#define VXGE_HW_MIN_DMA_BLOCK_POOL_SIZE		0
+#define VXGE_HW_INITIAL_DMA_BLOCK_POOL_SIZE	0
+#define VXGE_HW_INCR_DMA_BLOCK_POOL_SIZE	4
+#define VXGE_HW_MAX_DMA_BLOCK_POOL_SIZE		4096
 
-	u32				intr_mode;
-#define VXGE_HW_INTR_MODE_IRQLINE			0
-#define VXGE_HW_INTR_MODE_MSIX				1
-#define VXGE_HW_INTR_MODE_MSIX_ONE_SHOT			2
+#define	VXGE_HW_MAX_PAYLOAD_SIZE_512		2
 
-#define VXGE_HW_INTR_MODE_DEF				0
+	u32					intr_mode:2,
+#define VXGE_HW_INTR_MODE_IRQLINE		0
+#define VXGE_HW_INTR_MODE_MSIX			1
+#define VXGE_HW_INTR_MODE_MSIX_ONE_SHOT		2
 
-	u32				rth_en;
-#define VXGE_HW_RTH_DISABLE				0
-#define VXGE_HW_RTH_ENABLE				1
-#define VXGE_HW_RTH_DEFAULT				0
+#define VXGE_HW_INTR_MODE_DEF			0
 
-	u32				rth_it_type;
-#define VXGE_HW_RTH_IT_TYPE_SOLO_IT			0
-#define VXGE_HW_RTH_IT_TYPE_MULTI_IT			1
-#define VXGE_HW_RTH_IT_TYPE_DEFAULT			0
+						rth_en:1,
+#define VXGE_HW_RTH_DISABLE			0
+#define VXGE_HW_RTH_ENABLE			1
+#define VXGE_HW_RTH_DEFAULT			0
 
-	u32				rts_mac_en;
+						rth_it_type:1,
+#define VXGE_HW_RTH_IT_TYPE_SOLO_IT		0
+#define VXGE_HW_RTH_IT_TYPE_MULTI_IT		1
+#define VXGE_HW_RTH_IT_TYPE_DEFAULT		0
+
+						rts_mac_en:1,
 #define VXGE_HW_RTS_MAC_DISABLE			0
 #define VXGE_HW_RTS_MAC_ENABLE			1
 #define VXGE_HW_RTS_MAC_DEFAULT			0
 
-	struct vxge_hw_vp_config	vp_config[VXGE_HW_MAX_VIRTUAL_PATHS];
-
-	u32				device_poll_millis;
-#define VXGE_HW_MIN_DEVICE_POLL_MILLIS			1
-#define VXGE_HW_MAX_DEVICE_POLL_MILLIS			100000
-#define VXGE_HW_DEF_DEVICE_POLL_MILLIS			1000
+						hwts_en:1;
+#define	VXGE_HW_HWTS_DISABLE			0
+#define	VXGE_HW_HWTS_ENABLE			1
+#define	VXGE_HW_HWTS_DEFAULT			1
 
+	struct vxge_hw_vp_config vp_config[VXGE_HW_MAX_VIRTUAL_PATHS];
 };
 
 /**
diff -druN linux-2.6.39-libre/drivers/net/vxge/vxge-ethtool.c linux-3.0-rc7-libre/drivers/net/vxge/vxge-ethtool.c
--- linux-2.6.39-libre/drivers/net/vxge/vxge-ethtool.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/vxge/vxge-ethtool.c	2011-07-11 19:51:52.000000000 -0400
@@ -33,7 +33,8 @@
 {
 	/* We currently only support 10Gb/FULL */
 	if ((info->autoneg == AUTONEG_ENABLE) ||
-	    (info->speed != SPEED_10000) || (info->duplex != DUPLEX_FULL))
+	    (ethtool_cmd_speed(info) != SPEED_10000) ||
+	    (info->duplex != DUPLEX_FULL))
 		return -EINVAL;
 
 	return 0;
@@ -58,10 +59,10 @@
 	info->transceiver = XCVR_EXTERNAL;
 
 	if (netif_carrier_ok(dev)) {
-		info->speed = SPEED_10000;
+		ethtool_cmd_speed_set(info, SPEED_10000);
 		info->duplex = DUPLEX_FULL;
 	} else {
-		info->speed = -1;
+		ethtool_cmd_speed_set(info, -1);
 		info->duplex = -1;
 	}
 
@@ -134,22 +135,29 @@
 /**
  * vxge_ethtool_idnic - To physically identify the nic on the system.
  * @dev : device pointer.
- * @id : pointer to the structure with identification parameters given by
- * ethtool.
+ * @state : requested LED state
  *
  * Used to physically identify the NIC on the system.
- * The Link LED will blink for a time specified by the user.
- * Return value:
  * 0 on success
  */
-static int vxge_ethtool_idnic(struct net_device *dev, u32 data)
+static int vxge_ethtool_idnic(struct net_device *dev,
+			      enum ethtool_phys_id_state state)
 {
 	struct vxgedev *vdev = netdev_priv(dev);
 	struct __vxge_hw_device *hldev = vdev->devh;
 
-	vxge_hw_device_flick_link_led(hldev, VXGE_FLICKER_ON);
-	msleep_interruptible(data ? (data * HZ) : VXGE_MAX_FLICKER_TIME);
-	vxge_hw_device_flick_link_led(hldev, VXGE_FLICKER_OFF);
+	switch (state) {
+	case ETHTOOL_ID_ACTIVE:
+		vxge_hw_device_flick_link_led(hldev, VXGE_FLICKER_ON);
+		break;
+
+	case ETHTOOL_ID_INACTIVE:
+		vxge_hw_device_flick_link_led(hldev, VXGE_FLICKER_OFF);
+		break;
+
+	default:
+		return -EINVAL;
+	}
 
 	return 0;
 }
@@ -1064,35 +1072,6 @@
 	return sizeof(struct vxge_hw_vpath_reg) * vdev->no_of_vpath;
 }
 
-static u32 vxge_get_rx_csum(struct net_device *dev)
-{
-	struct vxgedev *vdev = netdev_priv(dev);
-
-	return vdev->rx_csum;
-}
-
-static int vxge_set_rx_csum(struct net_device *dev, u32 data)
-{
-	struct vxgedev *vdev = netdev_priv(dev);
-
-	if (data)
-		vdev->rx_csum = 1;
-	else
-		vdev->rx_csum = 0;
-
-	return 0;
-}
-
-static int vxge_ethtool_op_set_tso(struct net_device *dev, u32 data)
-{
-	if (data)
-		dev->features |= (NETIF_F_TSO | NETIF_F_TSO6);
-	else
-		dev->features &= ~(NETIF_F_TSO | NETIF_F_TSO6);
-
-	return 0;
-}
-
 static int vxge_ethtool_get_sset_count(struct net_device *dev, int sset)
 {
 	struct vxgedev *vdev = netdev_priv(dev);
@@ -1112,40 +1091,6 @@
 	}
 }
 
-static int vxge_set_flags(struct net_device *dev, u32 data)
-{
-	struct vxgedev *vdev = netdev_priv(dev);
-	enum vxge_hw_status status;
-
-	if (ethtool_invalid_flags(dev, data, ETH_FLAG_RXHASH))
-		return -EINVAL;
-
-	if (!!(data & ETH_FLAG_RXHASH) == vdev->devh->config.rth_en)
-		return 0;
-
-	if (netif_running(dev) || (vdev->config.rth_steering == NO_STEERING))
-		return -EINVAL;
-
-	vdev->devh->config.rth_en = !!(data & ETH_FLAG_RXHASH);
-
-	/* Enabling RTH requires some of the logic in vxge_device_register and a
-	 * vpath reset.  Due to these restrictions, only allow modification
-	 * while the interface is down.
-	 */
-	status = vxge_reset_all_vpaths(vdev);
-	if (status != VXGE_HW_OK) {
-		vdev->devh->config.rth_en = !vdev->devh->config.rth_en;
-		return -EFAULT;
-	}
-
-	if (vdev->devh->config.rth_en)
-		dev->features |= NETIF_F_RXHASH;
-	else
-		dev->features &= ~NETIF_F_RXHASH;
-
-	return 0;
-}
-
 static int vxge_fw_flash(struct net_device *dev, struct ethtool_flash *parms)
 {
 	struct vxgedev *vdev = netdev_priv(dev);
@@ -1174,19 +1119,10 @@
 	.get_link		= ethtool_op_get_link,
 	.get_pauseparam		= vxge_ethtool_getpause_data,
 	.set_pauseparam		= vxge_ethtool_setpause_data,
-	.get_rx_csum		= vxge_get_rx_csum,
-	.set_rx_csum		= vxge_set_rx_csum,
-	.get_tx_csum		= ethtool_op_get_tx_csum,
-	.set_tx_csum		= ethtool_op_set_tx_ipv6_csum,
-	.get_sg			= ethtool_op_get_sg,
-	.set_sg			= ethtool_op_set_sg,
-	.get_tso		= ethtool_op_get_tso,
-	.set_tso		= vxge_ethtool_op_set_tso,
 	.get_strings		= vxge_ethtool_get_strings,
-	.phys_id		= vxge_ethtool_idnic,
+	.set_phys_id		= vxge_ethtool_idnic,
 	.get_sset_count		= vxge_ethtool_get_sset_count,
 	.get_ethtool_stats	= vxge_get_ethtool_stats,
-	.set_flags		= vxge_set_flags,
 	.flash_device		= vxge_fw_flash,
 };
 
diff -druN linux-2.6.39-libre/drivers/net/vxge/vxge-main.c linux-3.0-rc7-libre/drivers/net/vxge/vxge-main.c
--- linux-2.6.39-libre/drivers/net/vxge/vxge-main.c	2011-05-19 02:12:51.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/vxge/vxge-main.c	2011-07-21 06:55:18.000000000 -0400
@@ -52,6 +52,7 @@
 #include <linux/etherdevice.h>
 #include <linux/firmware.h>
 #include <linux/net_tstamp.h>
+#include <linux/prefetch.h>
 #include "vxge-main.h"
 #include "vxge-reg.h"
 
@@ -304,22 +305,14 @@
 		"%s: %s:%d  skb protocol = %d",
 		ring->ndev->name, __func__, __LINE__, skb->protocol);
 
-	if (ring->gro_enable) {
-		if (ring->vlgrp && ext_info->vlan &&
-			(ring->vlan_tag_strip ==
-				VXGE_HW_VPATH_RPA_STRIP_VLAN_TAG_ENABLE))
-			vlan_gro_receive(ring->napi_p, ring->vlgrp,
-					ext_info->vlan, skb);
-		else
-			napi_gro_receive(ring->napi_p, skb);
-	} else {
-		if (ring->vlgrp && vlan &&
-			(ring->vlan_tag_strip ==
-				VXGE_HW_VPATH_RPA_STRIP_VLAN_TAG_ENABLE))
-			vlan_hwaccel_receive_skb(skb, ring->vlgrp, vlan);
-		else
-			netif_receive_skb(skb);
-	}
+	if (ring->vlgrp && ext_info->vlan &&
+		(ring->vlan_tag_strip ==
+			VXGE_HW_VPATH_RPA_STRIP_VLAN_TAG_ENABLE))
+		vlan_gro_receive(ring->napi_p, ring->vlgrp,
+				ext_info->vlan, skb);
+	else
+		napi_gro_receive(ring->napi_p, skb);
+
 	vxge_debug_entryexit(VXGE_TRACE,
 		"%s: %s:%d Exiting...", ring->ndev->name, __func__, __LINE__);
 }
@@ -490,7 +483,7 @@
 
 		if ((ext_info.proto & VXGE_HW_FRAME_PROTO_TCP_OR_UDP) &&
 		    !(ext_info.proto & VXGE_HW_FRAME_PROTO_IP_FRAG) &&
-		    ring->rx_csum && /* Offload Rx side CSUM */
+		    (dev->features & NETIF_F_RXCSUM) && /* Offload Rx side CSUM */
 		    ext_info.l3_cksum == VXGE_HW_L3_CKSUM_OK &&
 		    ext_info.l4_cksum == VXGE_HW_L4_CKSUM_OK)
 			skb->ip_summed = CHECKSUM_UNNECESSARY;
@@ -2094,11 +2087,9 @@
 				vdev->config.fifo_indicate_max_pkts;
 			vpath->fifo.tx_vector_no = 0;
 			vpath->ring.rx_vector_no = 0;
-			vpath->ring.rx_csum = vdev->rx_csum;
 			vpath->ring.rx_hwts = vdev->rx_hwts;
 			vpath->is_open = 1;
 			vdev->vp_handles[i] = vpath->handle;
-			vpath->ring.gro_enable = vdev->config.gro_enable;
 			vpath->ring.vlan_tag_strip = vdev->vlan_tag_strip;
 			vdev->stats.vpaths_open++;
 		} else {
@@ -2670,6 +2661,40 @@
 	mod_timer(&vdev->vp_lockup_timer, jiffies + HZ / 1000);
 }
 
+static u32 vxge_fix_features(struct net_device *dev, u32 features)
+{
+	u32 changed = dev->features ^ features;
+
+	/* Enabling RTH requires some of the logic in vxge_device_register and a
+	 * vpath reset.  Due to these restrictions, only allow modification
+	 * while the interface is down.
+	 */
+	if ((changed & NETIF_F_RXHASH) && netif_running(dev))
+		features ^= NETIF_F_RXHASH;
+
+	return features;
+}
+
+static int vxge_set_features(struct net_device *dev, u32 features)
+{
+	struct vxgedev *vdev = netdev_priv(dev);
+	u32 changed = dev->features ^ features;
+
+	if (!(changed & NETIF_F_RXHASH))
+		return 0;
+
+	/* !netif_running() ensured by vxge_fix_features() */
+
+	vdev->devh->config.rth_en = !!(features & NETIF_F_RXHASH);
+	if (vxge_reset_all_vpaths(vdev) != VXGE_HW_OK) {
+		dev->features = features ^ NETIF_F_RXHASH;
+		vdev->devh->config.rth_en = !!(dev->features & NETIF_F_RXHASH);
+		return -EIO;
+	}
+
+	return 0;
+}
+
 /**
  * vxge_open
  * @dev: pointer to the device structure.
@@ -3112,8 +3137,7 @@
 	return net_stats;
 }
 
-static enum vxge_hw_status vxge_timestamp_config(struct vxgedev *vdev,
-						 int enable)
+static enum vxge_hw_status vxge_timestamp_config(struct __vxge_hw_device *devh)
 {
 	enum vxge_hw_status status;
 	u64 val64;
@@ -3123,27 +3147,24 @@
 	 * required for the driver to load (due to a hardware bug),
 	 * there is no need to do anything special here.
 	 */
-	if (enable)
-		val64 = VXGE_HW_XMAC_TIMESTAMP_EN |
-			VXGE_HW_XMAC_TIMESTAMP_USE_LINK_ID(0) |
-			VXGE_HW_XMAC_TIMESTAMP_INTERVAL(0);
-	else
-		val64 = 0;
+	val64 = VXGE_HW_XMAC_TIMESTAMP_EN |
+		VXGE_HW_XMAC_TIMESTAMP_USE_LINK_ID(0) |
+		VXGE_HW_XMAC_TIMESTAMP_INTERVAL(0);
 
-	status = vxge_hw_mgmt_reg_write(vdev->devh,
+	status = vxge_hw_mgmt_reg_write(devh,
 					vxge_hw_mgmt_reg_type_mrpcim,
 					0,
 					offsetof(struct vxge_hw_mrpcim_reg,
 						 xmac_timestamp),
 					val64);
-	vxge_hw_device_flush_io(vdev->devh);
+	vxge_hw_device_flush_io(devh);
+	devh->config.hwts_en = VXGE_HW_HWTS_ENABLE;
 	return status;
 }
 
 static int vxge_hwtstamp_ioctl(struct vxgedev *vdev, void __user *data)
 {
 	struct hwtstamp_config config;
-	enum vxge_hw_status status;
 	int i;
 
 	if (copy_from_user(&config, data, sizeof(config)))
@@ -3164,10 +3185,6 @@
 
 	switch (config.rx_filter) {
 	case HWTSTAMP_FILTER_NONE:
-		status = vxge_timestamp_config(vdev, 0);
-		if (status != VXGE_HW_OK)
-			return -EFAULT;
-
 		vdev->rx_hwts = 0;
 		config.rx_filter = HWTSTAMP_FILTER_NONE;
 		break;
@@ -3186,8 +3203,7 @@
 	case HWTSTAMP_FILTER_PTP_V2_EVENT:
 	case HWTSTAMP_FILTER_PTP_V2_SYNC:
 	case HWTSTAMP_FILTER_PTP_V2_DELAY_REQ:
-		status = vxge_timestamp_config(vdev, 1);
-		if (status != VXGE_HW_OK)
+		if (vdev->devh->config.hwts_en != VXGE_HW_HWTS_ENABLE)
 			return -EFAULT;
 
 		vdev->rx_hwts = 1;
@@ -3378,6 +3394,8 @@
 	.ndo_do_ioctl           = vxge_ioctl,
 	.ndo_set_mac_address    = vxge_set_mac_addr,
 	.ndo_change_mtu         = vxge_change_mtu,
+	.ndo_fix_features	= vxge_fix_features,
+	.ndo_set_features	= vxge_set_features,
 	.ndo_vlan_rx_register   = vxge_vlan_rx_register,
 	.ndo_vlan_rx_kill_vid   = vxge_vlan_rx_kill_vid,
 	.ndo_vlan_rx_add_vid	= vxge_vlan_rx_add_vid,
@@ -3424,14 +3442,21 @@
 	vdev->devh = hldev;
 	vdev->pdev = hldev->pdev;
 	memcpy(&vdev->config, config, sizeof(struct vxge_config));
-	vdev->rx_csum = 1;	/* Enable Rx CSUM by default. */
 	vdev->rx_hwts = 0;
 	vdev->titan1 = (vdev->pdev->revision == VXGE_HW_TITAN1_PCI_REVISION);
 
 	SET_NETDEV_DEV(ndev, &vdev->pdev->dev);
 
-	ndev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX |
-				NETIF_F_HW_VLAN_FILTER;
+	ndev->hw_features = NETIF_F_RXCSUM | NETIF_F_SG |
+		NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
+		NETIF_F_TSO | NETIF_F_TSO6 |
+		NETIF_F_HW_VLAN_TX;
+	if (vdev->config.rth_steering != NO_STEERING)
+		ndev->hw_features |= NETIF_F_RXHASH;
+
+	ndev->features |= ndev->hw_features |
+		NETIF_F_HW_VLAN_RX | NETIF_F_HW_VLAN_FILTER;
+
 	/*  Driver entry points */
 	ndev->irq = vdev->pdev->irq;
 	ndev->base_addr = (unsigned long) hldev->bar0;
@@ -3443,11 +3468,6 @@
 
 	vxge_initialize_ethtool_ops(ndev);
 
-	if (vdev->config.rth_steering != NO_STEERING) {
-		ndev->features |= NETIF_F_RXHASH;
-		hldev->config.rth_en = VXGE_HW_RTH_ENABLE;
-	}
-
 	/* Allocate memory for vpath */
 	vdev->vpaths = kzalloc((sizeof(struct vxge_vpath)) *
 				no_of_vpath, GFP_KERNEL);
@@ -3459,9 +3479,6 @@
 		goto _out1;
 	}
 
-	ndev->features |= NETIF_F_SG;
-
-	ndev->features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;
 	vxge_debug_init(vxge_hw_device_trace_level_get(hldev),
 		"%s : checksuming enabled", __func__);
 
@@ -3471,11 +3488,6 @@
 			"%s : using High DMA", __func__);
 	}
 
-	ndev->features |= NETIF_F_TSO | NETIF_F_TSO6;
-
-	if (vdev->config.gro_enable)
-		ndev->features |= NETIF_F_GRO;
-
 	ret = register_netdev(ndev);
 	if (ret) {
 		vxge_debug_init(vxge_hw_device_trace_level_get(hldev),
@@ -4005,15 +4017,6 @@
 		vdev->config.tx_steering_type = 0;
 	}
 
-	if (vdev->config.gro_enable) {
-		vxge_debug_init(VXGE_ERR,
-			"%s: Generic receive offload enabled",
-			vdev->ndev->name);
-	} else
-		vxge_debug_init(VXGE_TRACE,
-			"%s: Generic receive offload disabled",
-			vdev->ndev->name);
-
 	if (vdev->config.addr_learn_en)
 		vxge_debug_init(VXGE_TRACE,
 			"%s: MAC Address learning enabled", vdev->ndev->name);
@@ -4575,12 +4578,29 @@
 		goto _exit4;
 	}
 
+	/* Always enable HWTS.  This will always cause the FCS to be invalid,
+	 * due to the fact that HWTS is using the FCS as the location of the
+	 * timestamp.  The HW FCS checking will still correctly determine if
+	 * there is a valid checksum, and the FCS is being removed by the driver
+	 * anyway.  So no fucntionality is being lost.  Since it is always
+	 * enabled, we now simply use the ioctl call to set whether or not the
+	 * driver should be paying attention to the HWTS.
+	 */
+	if (is_privileged == VXGE_HW_OK) {
+		status = vxge_timestamp_config(hldev);
+		if (status != VXGE_HW_OK) {
+			vxge_debug_init(VXGE_ERR, "%s: HWTS enable failed",
+					VXGE_DRIVER_NAME);
+			ret = -EFAULT;
+			goto _exit4;
+		}
+	}
+
 	vxge_hw_device_debug_set(hldev, VXGE_ERR, VXGE_COMPONENT_LL);
 
 	/* set private device info */
 	pci_set_drvdata(pdev, hldev);
 
-	ll_config->gro_enable = VXGE_GRO_ALWAYS_AGGREGATE;
 	ll_config->fifo_indicate_max_pkts = VXGE_FIFO_INDICATE_MAX_PKTS;
 	ll_config->addr_learn_en = addr_learn_en;
 	ll_config->rth_algorithm = RTH_ALG_JENKINS;
diff -druN linux-2.6.39-libre/drivers/net/vxge/vxge-main.h linux-3.0-rc7-libre/drivers/net/vxge/vxge-main.h
--- linux-2.6.39-libre/drivers/net/vxge/vxge-main.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/vxge/vxge-main.h	2011-07-11 19:51:52.000000000 -0400
@@ -168,9 +168,6 @@
 
 #define	NEW_NAPI_WEIGHT	64
 	int		napi_weight;
-#define VXGE_GRO_DONOT_AGGREGATE		0
-#define VXGE_GRO_ALWAYS_AGGREGATE		1
-	int		gro_enable;
 	int		intr_type;
 #define INTA	0
 #define MSI	1
@@ -290,13 +287,11 @@
 	unsigned long interrupt_count;
 	unsigned long jiffies;
 
-	/* copy of the flag indicating whether rx_csum is to be used */
-	u32 rx_csum:1,
-	    rx_hwts:1;
+	/* copy of the flag indicating whether rx_hwts is to be used */
+	u32 rx_hwts:1;
 
 	int pkts_processed;
 	int budget;
-	int gro_enable;
 
 	struct napi_struct napi;
 	struct napi_struct *napi_p;
@@ -369,9 +364,8 @@
 	 */
 	u16		all_multi_flg;
 
-	 /* A flag indicating whether rx_csum is to be used or not. */
-	u32	rx_csum:1,
-		rx_hwts:1,
+	/* A flag indicating whether rx_hwts is to be used or not. */
+	u32	rx_hwts:1,
 		titan1:1;
 
 	struct vxge_msix_entry *vxge_entries;
diff -druN linux-2.6.39-libre/drivers/net/vxge/vxge-traffic.c linux-3.0-rc7-libre/drivers/net/vxge/vxge-traffic.c
--- linux-2.6.39-libre/drivers/net/vxge/vxge-traffic.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/vxge/vxge-traffic.c	2011-07-11 19:51:52.000000000 -0400
@@ -12,6 +12,7 @@
  * Copyright(c) 2002-2010 Exar Corp.
  ******************************************************************************/
 #include <linux/etherdevice.h>
+#include <linux/prefetch.h>
 
 #include "vxge-traffic.h"
 #include "vxge-config.h"
diff -druN linux-2.6.39-libre/drivers/net/vxge/vxge-traffic.h linux-3.0-rc7-libre/drivers/net/vxge/vxge-traffic.h
--- linux-2.6.39-libre/drivers/net/vxge/vxge-traffic.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/vxge/vxge-traffic.h	2011-07-11 19:51:52.000000000 -0400
@@ -240,7 +240,7 @@
 	u32				btimer_val;
 #define VXGE_HW_MIN_TIM_BTIMER_VAL				0
 #define VXGE_HW_MAX_TIM_BTIMER_VAL				67108864
-#define VXGE_HW_USE_FLASH_DEFAULT				0xffffffff
+#define VXGE_HW_USE_FLASH_DEFAULT				(~0)
 
 	u32				timer_ac_en;
 #define VXGE_HW_TIM_TIMER_AC_ENABLE				1
diff -druN linux-2.6.39-libre/drivers/net/vxge/vxge-version.h linux-3.0-rc7-libre/drivers/net/vxge/vxge-version.h
--- linux-2.6.39-libre/drivers/net/vxge/vxge-version.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/vxge/vxge-version.h	2011-07-11 19:51:52.000000000 -0400
@@ -16,8 +16,8 @@
 
 #define VXGE_VERSION_MAJOR	"2"
 #define VXGE_VERSION_MINOR	"5"
-#define VXGE_VERSION_FIX	"2"
-#define VXGE_VERSION_BUILD	"22259"
+#define VXGE_VERSION_FIX	"3"
+#define VXGE_VERSION_BUILD	"22640"
 #define VXGE_VERSION_FOR	"k"
 
 #define VXGE_FW_VER(maj, min, bld) (((maj) << 16) + ((min) << 8) + (bld))
diff -druN linux-2.6.39-libre/drivers/net/wan/dlci.c linux-3.0-rc7-libre/drivers/net/wan/dlci.c
--- linux-2.6.39-libre/drivers/net/wan/dlci.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wan/dlci.c	2011-07-11 19:51:52.000000000 -0400
@@ -341,10 +341,6 @@
 		}
 	}
 
-	err = dev_alloc_name(master, master->name);
-	if (err < 0)
-		goto err2;
-
 	*(short *)(master->dev_addr) = dlci->dlci;
 
 	dlp = netdev_priv(master);
diff -druN linux-2.6.39-libre/drivers/net/wan/farsync.c linux-3.0-rc7-libre/drivers/net/wan/farsync.c
--- linux-2.6.39-libre/drivers/net/wan/farsync.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wan/farsync.c	2011-07-11 19:51:52.000000000 -0400
@@ -2203,8 +2203,10 @@
 
 	if (port->mode != FST_RAW) {
 		err = hdlc_open(dev);
-		if (err)
+		if (err) {
+			module_put(THIS_MODULE);
 			return err;
+		}
 	}
 
 	fst_openport(port);
diff -druN linux-2.6.39-libre/drivers/net/wan/hdlc_fr.c linux-3.0-rc7-libre/drivers/net/wan/hdlc_fr.c
--- linux-2.6.39-libre/drivers/net/wan/hdlc_fr.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wan/hdlc_fr.c	2011-07-11 19:51:52.000000000 -0400
@@ -1070,7 +1070,7 @@
 	hdlc_device *hdlc = dev_to_hdlc(frad);
 	pvc_device *pvc;
 	struct net_device *dev;
-	int result, used;
+	int used;
 
 	if ((pvc = add_pvc(frad, dlci)) == NULL) {
 		printk(KERN_WARNING "%s: Memory squeeze on fr_add_pvc()\n",
@@ -1106,13 +1106,6 @@
 	dev->tx_queue_len = 0;
 	dev->ml_priv = pvc;
 
-	result = dev_alloc_name(dev, dev->name);
-	if (result < 0) {
-		free_netdev(dev);
-		delete_unused_pvcs(hdlc);
-		return result;
-	}
-
 	if (register_netdevice(dev) != 0) {
 		free_netdev(dev);
 		delete_unused_pvcs(hdlc);
diff -druN linux-2.6.39-libre/drivers/net/wan/lapbether.c linux-3.0-rc7-libre/drivers/net/wan/lapbether.c
--- linux-2.6.39-libre/drivers/net/wan/lapbether.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wan/lapbether.c	2011-07-11 19:51:52.000000000 -0400
@@ -338,10 +338,6 @@
 	dev_hold(dev);
 	lapbeth->ethdev = dev;
 
-	rc = dev_alloc_name(ndev, ndev->name);
-	if (rc < 0) 
-		goto fail;
-
 	rc = -EIO;
 	if (register_netdevice(ndev))
 		goto fail;
diff -druN linux-2.6.39-libre/drivers/net/wan/pc300_drv.c linux-3.0-rc7-libre/drivers/net/wan/pc300_drv.c
--- linux-2.6.39-libre/drivers/net/wan/pc300_drv.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wan/pc300_drv.c	2011-07-11 19:51:52.000000000 -0400
@@ -1445,7 +1445,7 @@
  * Description:	In the remote loopback mode the clock and data recovered
  *		from the line inputs RL1/2 or RDIP/RDIN are routed back
  *		to the line outputs XL1/2 or XDOP/XDON via the analog
- *		transmitter. As in normal mode they are processsed by
+ *		transmitter. As in normal mode they are processed by
  *		the synchronizer and then sent to the system interface.
  *----------------------------------------------------------------------------
  */
@@ -3242,8 +3242,7 @@
 	rcsdate++;
 	tmp = strrchr(rcsdate, ' ');
 	*tmp = '\0';
-	printk(KERN_INFO "Cyclades-PC300 driver %s %s (built %s %s)\n", 
-		rcsvers, rcsdate, __DATE__, __TIME__);
+	printk(KERN_INFO "Cyclades-PC300 driver %s %s\n", rcsvers, rcsdate);
 }				/* show_version */
 
 static const struct net_device_ops cpc_netdev_ops = {
diff -druN linux-2.6.39-libre/drivers/net/wireless/airo.c linux-3.0-rc7-libre/drivers/net/wireless/airo.c
--- linux-2.6.39-libre/drivers/net/wireless/airo.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/airo.c	2011-07-11 19:51:52.000000000 -0400
@@ -242,9 +242,8 @@
 static int proc_perm = 0644;
 
 MODULE_AUTHOR("Benjamin Reed");
-MODULE_DESCRIPTION("Support for Cisco/Aironet 802.11 wireless ethernet \
-cards.  Direct support for ISA/PCI/MPI cards and support \
-for PCMCIA when used with airo_cs.");
+MODULE_DESCRIPTION("Support for Cisco/Aironet 802.11 wireless ethernet cards.  "
+		   "Direct support for ISA/PCI/MPI cards and support for PCMCIA when used with airo_cs.");
 MODULE_LICENSE("Dual BSD/GPL");
 MODULE_SUPPORTED_DEVICE("Aironet 4500, 4800 and Cisco 340/350");
 module_param_array(io, int, NULL, 0);
@@ -252,18 +251,20 @@
 module_param_array(rates, int, NULL, 0);
 module_param_array(ssids, charp, NULL, 0);
 module_param(auto_wep, int, 0);
-MODULE_PARM_DESC(auto_wep, "If non-zero, the driver will keep looping through \
-the authentication options until an association is made.  The value of \
-auto_wep is number of the wep keys to check.  A value of 2 will try using \
-the key at index 0 and index 1.");
+MODULE_PARM_DESC(auto_wep,
+		 "If non-zero, the driver will keep looping through the authentication options until an association is made.  "
+		 "The value of auto_wep is number of the wep keys to check.  "
+		 "A value of 2 will try using the key at index 0 and index 1.");
 module_param(aux_bap, int, 0);
-MODULE_PARM_DESC(aux_bap, "If non-zero, the driver will switch into a mode \
-than seems to work better for older cards with some older buses.  Before \
-switching it checks that the switch is needed.");
+MODULE_PARM_DESC(aux_bap,
+		 "If non-zero, the driver will switch into a mode that seems to work better for older cards with some older buses.  "
+		 "Before switching it checks that the switch is needed.");
 module_param(maxencrypt, int, 0);
-MODULE_PARM_DESC(maxencrypt, "The maximum speed that the card can do \
-encryption.  Units are in 512kbs.  Zero (default) means there is no limit. \
-Older cards used to be limited to 2mbs (4).");
+MODULE_PARM_DESC(maxencrypt,
+		 "The maximum speed that the card can do encryption.  "
+		 "Units are in 512kbs.  "
+		 "Zero (default) means there is no limit.  "
+		 "Older cards used to be limited to 2mbs (4).");
 module_param(adhoc, int, 0);
 MODULE_PARM_DESC(adhoc, "If non-zero, the card will start in adhoc mode.");
 module_param(probe, int, 0);
@@ -4500,17 +4501,15 @@
 	struct proc_dir_entry *entry;
 	/* First setup the device directory */
 	strcpy(apriv->proc_name,dev->name);
-	apriv->proc_entry = create_proc_entry(apriv->proc_name,
-					      S_IFDIR|airo_perm,
-					      airo_entry);
+	apriv->proc_entry = proc_mkdir_mode(apriv->proc_name, airo_perm,
+					    airo_entry);
 	if (!apriv->proc_entry)
 		goto fail;
 	apriv->proc_entry->uid = proc_uid;
 	apriv->proc_entry->gid = proc_gid;
 
 	/* Setup the StatsDelta */
-	entry = proc_create_data("StatsDelta",
-				 S_IFREG | (S_IRUGO&proc_perm),
+	entry = proc_create_data("StatsDelta", S_IRUGO & proc_perm,
 				 apriv->proc_entry, &proc_statsdelta_ops, dev);
 	if (!entry)
 		goto fail_stats_delta;
@@ -4518,8 +4517,7 @@
 	entry->gid = proc_gid;
 
 	/* Setup the Stats */
-	entry = proc_create_data("Stats",
-				 S_IFREG | (S_IRUGO&proc_perm),
+	entry = proc_create_data("Stats", S_IRUGO & proc_perm,
 				 apriv->proc_entry, &proc_stats_ops, dev);
 	if (!entry)
 		goto fail_stats;
@@ -4527,8 +4525,7 @@
 	entry->gid = proc_gid;
 
 	/* Setup the Status */
-	entry = proc_create_data("Status",
-				 S_IFREG | (S_IRUGO&proc_perm),
+	entry = proc_create_data("Status", S_IRUGO & proc_perm,
 				 apriv->proc_entry, &proc_status_ops, dev);
 	if (!entry)
 		goto fail_status;
@@ -4536,8 +4533,7 @@
 	entry->gid = proc_gid;
 
 	/* Setup the Config */
-	entry = proc_create_data("Config",
-				 S_IFREG | proc_perm,
+	entry = proc_create_data("Config", proc_perm,
 				 apriv->proc_entry, &proc_config_ops, dev);
 	if (!entry)
 		goto fail_config;
@@ -4545,8 +4541,7 @@
 	entry->gid = proc_gid;
 
 	/* Setup the SSID */
-	entry = proc_create_data("SSID",
-				 S_IFREG | proc_perm,
+	entry = proc_create_data("SSID", proc_perm,
 				 apriv->proc_entry, &proc_SSID_ops, dev);
 	if (!entry)
 		goto fail_ssid;
@@ -4554,8 +4549,7 @@
 	entry->gid = proc_gid;
 
 	/* Setup the APList */
-	entry = proc_create_data("APList",
-				 S_IFREG | proc_perm,
+	entry = proc_create_data("APList", proc_perm,
 				 apriv->proc_entry, &proc_APList_ops, dev);
 	if (!entry)
 		goto fail_aplist;
@@ -4563,8 +4557,7 @@
 	entry->gid = proc_gid;
 
 	/* Setup the BSSList */
-	entry = proc_create_data("BSSList",
-				 S_IFREG | proc_perm,
+	entry = proc_create_data("BSSList", proc_perm,
 				 apriv->proc_entry, &proc_BSSList_ops, dev);
 	if (!entry)
 		goto fail_bsslist;
@@ -4572,8 +4565,7 @@
 	entry->gid = proc_gid;
 
 	/* Setup the WepKey */
-	entry = proc_create_data("WepKey",
-				 S_IFREG | proc_perm,
+	entry = proc_create_data("WepKey", proc_perm,
 				 apriv->proc_entry, &proc_wepkey_ops, dev);
 	if (!entry)
 		goto fail_wepkey;
@@ -5705,9 +5697,7 @@
 {
 	int i;
 
-	airo_entry = create_proc_entry("driver/aironet",
-				       S_IFDIR | airo_perm,
-				       NULL);
+	airo_entry = proc_mkdir_mode("driver/aironet", airo_perm, NULL);
 
 	if (airo_entry) {
 		airo_entry->uid = proc_uid;
diff -druN linux-2.6.39-libre/drivers/net/wireless/airo_cs.c linux-3.0-rc7-libre/drivers/net/wireless/airo_cs.c
--- linux-2.6.39-libre/drivers/net/wireless/airo_cs.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/airo_cs.c	2011-07-11 19:51:52.000000000 -0400
@@ -164,7 +164,7 @@
 	return 0;
 }
 
-static struct pcmcia_device_id airo_ids[] = {
+static const struct pcmcia_device_id airo_ids[] = {
 	PCMCIA_DEVICE_MANF_CARD(0x015f, 0x000a),
 	PCMCIA_DEVICE_MANF_CARD(0x015f, 0x0005),
 	PCMCIA_DEVICE_MANF_CARD(0x015f, 0x0007),
diff -druN linux-2.6.39-libre/drivers/net/wireless/ath/ar9170/ar9170.h linux-3.0-rc7-libre/drivers/net/wireless/ath/ar9170/ar9170.h
--- linux-2.6.39-libre/drivers/net/wireless/ath/ar9170/ar9170.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/ath/ar9170/ar9170.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,258 +0,0 @@
-/*
- * Atheros AR9170 driver
- *
- * Driver specific definitions
- *
- * Copyright 2008, Johannes Berg <johannes@sipsolutions.net>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; see the file COPYING.  If not, see
- * http://www.gnu.org/licenses/.
- *
- * This file incorporates work covered by the following copyright and
- * permission notice:
- *    Copyright (c) 2007-2008 Atheros Communications, Inc.
- *
- *    Permission to use, copy, modify, and/or distribute this software for any
- *    purpose with or without fee is hereby granted, provided that the above
- *    copyright notice and this permission notice appear in all copies.
- *
- *    THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- *    WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- *    MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- *    ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- *    WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- *    ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- *    OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-#ifndef __AR9170_H
-#define __AR9170_H
-
-#include <linux/completion.h>
-#include <linux/spinlock.h>
-#include <net/cfg80211.h>
-#include <net/mac80211.h>
-#ifdef CONFIG_AR9170_LEDS
-#include <linux/leds.h>
-#endif /* CONFIG_AR9170_LEDS */
-#include "eeprom.h"
-#include "hw.h"
-
-#include "../regd.h"
-
-#define PAYLOAD_MAX	(AR9170_MAX_CMD_LEN/4 - 1)
-
-enum ar9170_bw {
-	AR9170_BW_20,
-	AR9170_BW_40_BELOW,
-	AR9170_BW_40_ABOVE,
-
-	__AR9170_NUM_BW,
-};
-
-static inline enum ar9170_bw nl80211_to_ar9170(enum nl80211_channel_type type)
-{
-	switch (type) {
-	case NL80211_CHAN_NO_HT:
-	case NL80211_CHAN_HT20:
-		return AR9170_BW_20;
-	case NL80211_CHAN_HT40MINUS:
-		return AR9170_BW_40_BELOW;
-	case NL80211_CHAN_HT40PLUS:
-		return AR9170_BW_40_ABOVE;
-	default:
-		BUG();
-	}
-}
-
-enum ar9170_rf_init_mode {
-	AR9170_RFI_NONE,
-	AR9170_RFI_WARM,
-	AR9170_RFI_COLD,
-};
-
-#define AR9170_MAX_RX_BUFFER_SIZE		8192
-
-#ifdef CONFIG_AR9170_LEDS
-struct ar9170;
-
-struct ar9170_led {
-	struct ar9170 *ar;
-	struct led_classdev l;
-	char name[32];
-	unsigned int toggled;
-	bool last_state;
-	bool registered;
-};
-
-#endif /* CONFIG_AR9170_LEDS */
-
-enum ar9170_device_state {
-	AR9170_UNKNOWN_STATE,
-	AR9170_STOPPED,
-	AR9170_IDLE,
-	AR9170_STARTED,
-};
-
-struct ar9170_rxstream_mpdu_merge {
-	struct ar9170_rx_head plcp;
-	bool has_plcp;
-};
-
-struct ar9170_tx_queue_stats {
-	unsigned int len;
-	unsigned int limit;
-	unsigned int count;
-};
-
-#define AR9170_QUEUE_TIMEOUT		64
-#define AR9170_TX_TIMEOUT		8
-#define AR9170_JANITOR_DELAY		128
-#define AR9170_TX_INVALID_RATE		0xffffffff
-
-#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 *);
-	void (*stop)(struct ar9170 *);
-	int (*tx)(struct ar9170 *, struct sk_buff *);
-	int (*exec_cmd)(struct ar9170 *, enum ar9170_cmd, u32 ,
-			void *, u32 , void *);
-	void (*callback_cmd)(struct ar9170 *, u32 , void *);
-	int (*flush)(struct ar9170 *);
-
-	/* interface mode settings */
-	struct ieee80211_vif *vif;
-
-	/* beaconing */
-	struct sk_buff *beacon;
-	struct work_struct beacon_work;
-	bool enable_beacon;
-
-	/* cryptographic engine */
-	u64 usedkeys;
-	bool rx_software_decryption;
-	bool disable_offload;
-
-	/* filter settings */
-	u64 cur_mc_hash;
-	u32 cur_filter;
-	unsigned int filter_state;
-	bool sniffer_enabled;
-
-	/* PHY */
-	struct ieee80211_channel *channel;
-	int noise[4];
-
-	/* power calibration data */
-	u8 power_5G_leg[4];
-	u8 power_2G_cck[4];
-	u8 power_2G_ofdm[4];
-	u8 power_5G_ht20[8];
-	u8 power_5G_ht40[8];
-	u8 power_2G_ht20[8];
-	u8 power_2G_ht40[8];
-
-	u8 phy_heavy_clip;
-
-#ifdef CONFIG_AR9170_LEDS
-	struct delayed_work led_work;
-	struct ar9170_led leds[AR9170_NUM_LEDS];
-#endif /* CONFIG_AR9170_LEDS */
-
-	/* qos queue settings */
-	spinlock_t tx_stats_lock;
-	struct ar9170_tx_queue_stats tx_stats[5];
-	struct ieee80211_tx_queue_params edcf[5];
-
-	spinlock_t cmdlock;
-	__le32 cmdbuf[PAYLOAD_MAX + 1];
-
-	/* MAC statistics */
-	struct ieee80211_low_level_stats stats;
-
-	/* EEPROM */
-	struct ar9170_eeprom eeprom;
-
-	/* tx queues - as seen by hw - */
-	struct sk_buff_head tx_pending[__AR9170_NUM_TXQ];
-	struct sk_buff_head tx_status[__AR9170_NUM_TXQ];
-	struct delayed_work tx_janitor;
-
-	/* rxstream mpdu merge */
-	struct ar9170_rxstream_mpdu_merge rx_mpdu;
-	struct sk_buff *rx_failover;
-	int rx_failover_missing;
-
-	/* (cached) HW A-MPDU settings */
-	u8 global_ampdu_density;
-	u8 global_ampdu_factor;
-};
-
-struct ar9170_tx_info {
-	unsigned long timeout;
-};
-
-#define IS_STARTED(a)		(((struct ar9170 *)a)->state >= AR9170_STARTED)
-#define IS_ACCEPTING_CMD(a)	(((struct ar9170 *)a)->state >= AR9170_IDLE)
-
-/* exported interface */
-void *ar9170_alloc(size_t priv_size);
-int ar9170_register(struct ar9170 *ar, struct device *pdev);
-void ar9170_rx(struct ar9170 *ar, struct sk_buff *skb);
-void ar9170_unregister(struct ar9170 *ar);
-void ar9170_tx_callback(struct ar9170 *ar, struct sk_buff *skb);
-void ar9170_handle_command_response(struct ar9170 *ar, void *buf, u32 len);
-int ar9170_nag_limiter(struct ar9170 *ar);
-
-/* MAC */
-void ar9170_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb);
-int ar9170_init_mac(struct ar9170 *ar);
-int ar9170_set_qos(struct ar9170 *ar);
-int ar9170_update_multicast(struct ar9170 *ar, const u64 mc_hast);
-int ar9170_update_frame_filter(struct ar9170 *ar, const u32 filter);
-int ar9170_set_operating_mode(struct ar9170 *ar);
-int ar9170_set_beacon_timers(struct ar9170 *ar);
-int ar9170_set_dyn_sifs_ack(struct ar9170 *ar);
-int ar9170_set_slot_time(struct ar9170 *ar);
-int ar9170_set_basic_rates(struct ar9170 *ar);
-int ar9170_set_hwretry_limit(struct ar9170 *ar, u32 max_retry);
-int ar9170_update_beacon(struct ar9170 *ar);
-void ar9170_new_beacon(struct work_struct *work);
-int ar9170_upload_key(struct ar9170 *ar, u8 id, const u8 *mac, u8 ktype,
-		      u8 keyidx, u8 *keydata, int keylen);
-int ar9170_disable_key(struct ar9170 *ar, u8 id);
-
-/* LEDs */
-#ifdef CONFIG_AR9170_LEDS
-int ar9170_register_leds(struct ar9170 *ar);
-void ar9170_unregister_leds(struct ar9170 *ar);
-#endif /* CONFIG_AR9170_LEDS */
-int ar9170_init_leds(struct ar9170 *ar);
-int ar9170_set_leds_state(struct ar9170 *ar, u32 led_state);
-
-/* PHY / RF */
-int ar9170_init_phy(struct ar9170 *ar, enum ieee80211_band band);
-int ar9170_init_rf(struct ar9170 *ar);
-int ar9170_set_channel(struct ar9170 *ar, struct ieee80211_channel *channel,
-		       enum ar9170_rf_init_mode rfi, enum ar9170_bw bw);
-
-#endif /* __AR9170_H */
diff -druN linux-2.6.39-libre/drivers/net/wireless/ath/ar9170/cmd.c linux-3.0-rc7-libre/drivers/net/wireless/ath/ar9170/cmd.c
--- linux-2.6.39-libre/drivers/net/wireless/ath/ar9170/cmd.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/ath/ar9170/cmd.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,127 +0,0 @@
-/*
- * Atheros AR9170 driver
- *
- * Basic HW register/memory/command access functions
- *
- * Copyright 2008, Johannes Berg <johannes@sipsolutions.net>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; see the file COPYING.  If not, see
- * http://www.gnu.org/licenses/.
- *
- * This file incorporates work covered by the following copyright and
- * permission notice:
- *    Copyright (c) 2007-2008 Atheros Communications, Inc.
- *
- *    Permission to use, copy, modify, and/or distribute this software for any
- *    purpose with or without fee is hereby granted, provided that the above
- *    copyright notice and this permission notice appear in all copies.
- *
- *    THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- *    WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- *    MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- *    ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- *    WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- *    ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- *    OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include "ar9170.h"
-#include "cmd.h"
-
-int ar9170_write_mem(struct ar9170 *ar, const __le32 *data, size_t len)
-{
-	int err;
-
-	if (unlikely(!IS_ACCEPTING_CMD(ar)))
-		return 0;
-
-	err = ar->exec_cmd(ar, AR9170_CMD_WMEM, len, (u8 *) data, 0, NULL);
-	if (err)
-		wiphy_debug(ar->hw->wiphy, "writing memory failed\n");
-	return err;
-}
-
-int ar9170_write_reg(struct ar9170 *ar, const u32 reg, const u32 val)
-{
-	const __le32 buf[2] = {
-		cpu_to_le32(reg),
-		cpu_to_le32(val),
-	};
-	int err;
-
-	if (unlikely(!IS_ACCEPTING_CMD(ar)))
-		return 0;
-
-	err = ar->exec_cmd(ar, AR9170_CMD_WREG, sizeof(buf),
-			   (u8 *) buf, 0, NULL);
-	if (err)
-		wiphy_debug(ar->hw->wiphy, "writing reg %#x (val %#x) failed\n",
-			    reg, val);
-	return err;
-}
-
-int ar9170_read_mreg(struct ar9170 *ar, int nregs, const u32 *regs, u32 *out)
-{
-	int i, err;
-	__le32 *offs, *res;
-
-	if (unlikely(!IS_ACCEPTING_CMD(ar)))
-		return 0;
-
-	/* abuse "out" for the register offsets, must be same length */
-	offs = (__le32 *)out;
-	for (i = 0; i < nregs; i++)
-		offs[i] = cpu_to_le32(regs[i]);
-
-	/* also use the same buffer for the input */
-	res = (__le32 *)out;
-
-	err = ar->exec_cmd(ar, AR9170_CMD_RREG,
-			   4 * nregs, (u8 *)offs,
-			   4 * nregs, (u8 *)res);
-	if (err)
-		return err;
-
-	/* convert result to cpu endian */
-	for (i = 0; i < nregs; i++)
-		out[i] = le32_to_cpu(res[i]);
-
-	return 0;
-}
-
-int ar9170_read_reg(struct ar9170 *ar, u32 reg, u32 *val)
-{
-	return ar9170_read_mreg(ar, 1, &reg, val);
-}
-
-int ar9170_echo_test(struct ar9170 *ar, u32 v)
-{
-	__le32 echobuf = cpu_to_le32(v);
-	__le32 echores;
-	int err;
-
-	if (unlikely(!IS_ACCEPTING_CMD(ar)))
-		return -ENODEV;
-
-	err = ar->exec_cmd(ar, AR9170_CMD_ECHO,
-			   4, (u8 *)&echobuf,
-			   4, (u8 *)&echores);
-	if (err)
-		return err;
-
-	if (echobuf != echores)
-		return -EINVAL;
-
-	return 0;
-}
diff -druN linux-2.6.39-libre/drivers/net/wireless/ath/ar9170/cmd.h linux-3.0-rc7-libre/drivers/net/wireless/ath/ar9170/cmd.h
--- linux-2.6.39-libre/drivers/net/wireless/ath/ar9170/cmd.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/ath/ar9170/cmd.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,92 +0,0 @@
-/*
- * Atheros AR9170 driver
- *
- * Basic HW register/memory/command access functions
- *
- * Copyright 2008, Johannes Berg <johannes@sipsolutions.net>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; see the file COPYING.  If not, see
- * http://www.gnu.org/licenses/.
- *
- * This file incorporates work covered by the following copyright and
- * permission notice:
- *    Copyright (c) 2007-2008 Atheros Communications, Inc.
- *
- *    Permission to use, copy, modify, and/or distribute this software for any
- *    purpose with or without fee is hereby granted, provided that the above
- *    copyright notice and this permission notice appear in all copies.
- *
- *    THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- *    WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- *    MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- *    ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- *    WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- *    ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- *    OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-#ifndef __CMD_H
-#define __CMD_H
-
-#include "ar9170.h"
-
-/* basic HW access */
-int ar9170_write_mem(struct ar9170 *ar, const __le32 *data, size_t len);
-int ar9170_write_reg(struct ar9170 *ar, const u32 reg, const u32 val);
-int ar9170_read_reg(struct ar9170 *ar, u32 reg, u32 *val);
-int ar9170_read_mreg(struct ar9170 *ar, int nregs, const u32 *regs, u32 *out);
-int ar9170_echo_test(struct ar9170 *ar, u32 v);
-
-/*
- * Macros to facilitate writing multiple registers in a single
- * write-combining USB command. Note that when the first group
- * fails the whole thing will fail without any others attempted,
- * but you won't know which write in the group failed.
- */
-#define ar9170_regwrite_begin(ar)					\
-do {									\
-	int __nreg = 0, __err = 0;					\
-	struct ar9170 *__ar = ar;
-
-#define ar9170_regwrite(r, v) do {					\
-	__ar->cmdbuf[2 * __nreg + 1] = cpu_to_le32(r);			\
-	__ar->cmdbuf[2 * __nreg + 2] = cpu_to_le32(v);			\
-	__nreg++;							\
-	if ((__nreg >= PAYLOAD_MAX/2)) {				\
-		if (IS_ACCEPTING_CMD(__ar))				\
-			__err = ar->exec_cmd(__ar, AR9170_CMD_WREG,	\
-					     8 * __nreg,		\
-					     (u8 *) &__ar->cmdbuf[1],	\
-					     0, NULL);			\
-		__nreg = 0;						\
-		if (__err)						\
-			goto __regwrite_out;				\
-	}								\
-} while (0)
-
-#define ar9170_regwrite_finish()					\
-__regwrite_out :							\
-	if (__nreg) {							\
-		if (IS_ACCEPTING_CMD(__ar))				\
-			__err = ar->exec_cmd(__ar, AR9170_CMD_WREG,	\
-					     8 * __nreg,		\
-					     (u8 *) &__ar->cmdbuf[1],	\
-					     0, NULL);			\
-		__nreg = 0;						\
-	}
-
-#define ar9170_regwrite_result()					\
-	__err;								\
-} while (0);
-
-#endif /* __CMD_H */
diff -druN linux-2.6.39-libre/drivers/net/wireless/ath/ar9170/eeprom.h linux-3.0-rc7-libre/drivers/net/wireless/ath/ar9170/eeprom.h
--- linux-2.6.39-libre/drivers/net/wireless/ath/ar9170/eeprom.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/ath/ar9170/eeprom.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,179 +0,0 @@
-/*
- * Atheros AR9170 driver
- *
- * EEPROM layout
- *
- * Copyright 2008, Johannes Berg <johannes@sipsolutions.net>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; see the file COPYING.  If not, see
- * http://www.gnu.org/licenses/.
- *
- * This file incorporates work covered by the following copyright and
- * permission notice:
- *    Copyright (c) 2007-2008 Atheros Communications, Inc.
- *
- *    Permission to use, copy, modify, and/or distribute this software for any
- *    purpose with or without fee is hereby granted, provided that the above
- *    copyright notice and this permission notice appear in all copies.
- *
- *    THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- *    WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- *    MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- *    ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- *    WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- *    ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- *    OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-#ifndef __AR9170_EEPROM_H
-#define __AR9170_EEPROM_H
-
-#define AR5416_MAX_CHAINS		2
-#define AR5416_MODAL_SPURS		5
-
-struct ar9170_eeprom_modal {
-	__le32	antCtrlChain[AR5416_MAX_CHAINS];
-	__le32	antCtrlCommon;
-	s8	antennaGainCh[AR5416_MAX_CHAINS];
-	u8	switchSettling;
-	u8	txRxAttenCh[AR5416_MAX_CHAINS];
-	u8	rxTxMarginCh[AR5416_MAX_CHAINS];
-	s8	adcDesiredSize;
-	s8	pgaDesiredSize;
-	u8	xlnaGainCh[AR5416_MAX_CHAINS];
-	u8	txEndToXpaOff;
-	u8	txEndToRxOn;
-	u8	txFrameToXpaOn;
-	u8	thresh62;
-	s8	noiseFloorThreshCh[AR5416_MAX_CHAINS];
-	u8	xpdGain;
-	u8	xpd;
-	s8	iqCalICh[AR5416_MAX_CHAINS];
-	s8	iqCalQCh[AR5416_MAX_CHAINS];
-	u8	pdGainOverlap;
-	u8	ob;
-	u8	db;
-	u8	xpaBiasLvl;
-	u8	pwrDecreaseFor2Chain;
-	u8	pwrDecreaseFor3Chain;
-	u8	txFrameToDataStart;
-	u8	txFrameToPaOn;
-	u8	ht40PowerIncForPdadc;
-	u8	bswAtten[AR5416_MAX_CHAINS];
-	u8	bswMargin[AR5416_MAX_CHAINS];
-	u8	swSettleHt40;
-	u8	reserved[22];
-	struct spur_channel {
-		__le16 spurChan;
-		u8	spurRangeLow;
-		u8	spurRangeHigh;
-	} __packed spur_channels[AR5416_MODAL_SPURS];
-} __packed;
-
-#define AR5416_NUM_PD_GAINS		4
-#define AR5416_PD_GAIN_ICEPTS		5
-
-struct ar9170_calibration_data_per_freq {
-	u8	pwr_pdg[AR5416_NUM_PD_GAINS][AR5416_PD_GAIN_ICEPTS];
-	u8	vpd_pdg[AR5416_NUM_PD_GAINS][AR5416_PD_GAIN_ICEPTS];
-} __packed;
-
-#define AR5416_NUM_5G_CAL_PIERS		8
-#define AR5416_NUM_2G_CAL_PIERS		4
-
-#define AR5416_NUM_5G_TARGET_PWRS	8
-#define AR5416_NUM_2G_CCK_TARGET_PWRS	3
-#define AR5416_NUM_2G_OFDM_TARGET_PWRS	4
-#define AR5416_MAX_NUM_TGT_PWRS		8
-
-struct ar9170_calibration_target_power_legacy {
-	u8	freq;
-	u8	power[4];
-} __packed;
-
-struct ar9170_calibration_target_power_ht {
-	u8	freq;
-	u8	power[8];
-} __packed;
-
-#define AR5416_NUM_CTLS			24
-
-struct ar9170_calctl_edges {
-	u8	channel;
-#define AR9170_CALCTL_EDGE_FLAGS	0xC0
-	u8	power_flags;
-} __packed;
-
-#define AR5416_NUM_BAND_EDGES		8
-
-struct ar9170_calctl_data {
-	struct ar9170_calctl_edges
-		control_edges[AR5416_MAX_CHAINS][AR5416_NUM_BAND_EDGES];
-} __packed;
-
-
-struct ar9170_eeprom {
-	__le16	length;
-	__le16	checksum;
-	__le16	version;
-	u8	operating_flags;
-#define AR9170_OPFLAG_5GHZ		1
-#define AR9170_OPFLAG_2GHZ		2
-	u8	misc;
-	__le16	reg_domain[2];
-	u8	mac_address[6];
-	u8	rx_mask;
-	u8	tx_mask;
-	__le16	rf_silent;
-	__le16	bluetooth_options;
-	__le16	device_capabilities;
-	__le32	build_number;
-	u8	deviceType;
-	u8	reserved[33];
-
-	u8	customer_data[64];
-
-	struct ar9170_eeprom_modal
-		modal_header[2];
-
-	u8	cal_freq_pier_5G[AR5416_NUM_5G_CAL_PIERS];
-	u8	cal_freq_pier_2G[AR5416_NUM_2G_CAL_PIERS];
-
-	struct ar9170_calibration_data_per_freq
-		cal_pier_data_5G[AR5416_MAX_CHAINS][AR5416_NUM_5G_CAL_PIERS],
-		cal_pier_data_2G[AR5416_MAX_CHAINS][AR5416_NUM_2G_CAL_PIERS];
-
-	/* power calibration data */
-	struct ar9170_calibration_target_power_legacy
-		cal_tgt_pwr_5G[AR5416_NUM_5G_TARGET_PWRS];
-	struct ar9170_calibration_target_power_ht
-		cal_tgt_pwr_5G_ht20[AR5416_NUM_5G_TARGET_PWRS],
-		cal_tgt_pwr_5G_ht40[AR5416_NUM_5G_TARGET_PWRS];
-
-	struct ar9170_calibration_target_power_legacy
-		cal_tgt_pwr_2G_cck[AR5416_NUM_2G_CCK_TARGET_PWRS],
-		cal_tgt_pwr_2G_ofdm[AR5416_NUM_2G_OFDM_TARGET_PWRS];
-	struct ar9170_calibration_target_power_ht
-		cal_tgt_pwr_2G_ht20[AR5416_NUM_2G_OFDM_TARGET_PWRS],
-		cal_tgt_pwr_2G_ht40[AR5416_NUM_2G_OFDM_TARGET_PWRS];
-
-	/* conformance testing limits */
-	u8	ctl_index[AR5416_NUM_CTLS];
-	struct ar9170_calctl_data
-		ctl_data[AR5416_NUM_CTLS];
-
-	u8	pad;
-	__le16	subsystem_id;
-} __packed;
-
-#endif /* __AR9170_EEPROM_H */
diff -druN linux-2.6.39-libre/drivers/net/wireless/ath/ar9170/hw.h linux-3.0-rc7-libre/drivers/net/wireless/ath/ar9170/hw.h
--- linux-2.6.39-libre/drivers/net/wireless/ath/ar9170/hw.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/ath/ar9170/hw.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,430 +0,0 @@
-/*
- * Atheros AR9170 driver
- *
- * Hardware-specific definitions
- *
- * Copyright 2008, Johannes Berg <johannes@sipsolutions.net>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; see the file COPYING.  If not, see
- * http://www.gnu.org/licenses/.
- *
- * This file incorporates work covered by the following copyright and
- * permission notice:
- *    Copyright (c) 2007-2008 Atheros Communications, Inc.
- *
- *    Permission to use, copy, modify, and/or distribute this software for any
- *    purpose with or without fee is hereby granted, provided that the above
- *    copyright notice and this permission notice appear in all copies.
- *
- *    THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- *    WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- *    MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- *    ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- *    WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- *    ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- *    OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-#ifndef __AR9170_HW_H
-#define __AR9170_HW_H
-
-#define AR9170_MAX_CMD_LEN	64
-
-enum ar9170_cmd {
-	AR9170_CMD_RREG		= 0x00,
-	AR9170_CMD_WREG		= 0x01,
-	AR9170_CMD_RMEM		= 0x02,
-	AR9170_CMD_WMEM		= 0x03,
-	AR9170_CMD_BITAND	= 0x04,
-	AR9170_CMD_BITOR	= 0x05,
-	AR9170_CMD_EKEY		= 0x28,
-	AR9170_CMD_DKEY		= 0x29,
-	AR9170_CMD_FREQUENCY	= 0x30,
-	AR9170_CMD_RF_INIT	= 0x31,
-	AR9170_CMD_SYNTH	= 0x32,
-	AR9170_CMD_FREQ_START	= 0x33,
-	AR9170_CMD_ECHO		= 0x80,
-	AR9170_CMD_TALLY	= 0x81,
-	AR9170_CMD_TALLY_APD	= 0x82,
-	AR9170_CMD_CONFIG	= 0x83,
-	AR9170_CMD_RESET	= 0x90,
-	AR9170_CMD_DKRESET	= 0x91,
-	AR9170_CMD_DKTX_STATUS	= 0x92,
-	AR9170_CMD_FDC		= 0xA0,
-	AR9170_CMD_WREEPROM	= 0xB0,
-	AR9170_CMD_WFLASH	= 0xB0,
-	AR9170_CMD_FLASH_ERASE	= 0xB1,
-	AR9170_CMD_FLASH_PROG	= 0xB2,
-	AR9170_CMD_FLASH_CHKSUM	= 0xB3,
-	AR9170_CMD_FLASH_READ	= 0xB4,
-	AR9170_CMD_FW_DL_INIT	= 0xB5,
-	AR9170_CMD_MEM_WREEPROM	= 0xBB,
-};
-
-/* endpoints */
-#define AR9170_EP_TX				1
-#define AR9170_EP_RX				2
-#define AR9170_EP_IRQ				3
-#define AR9170_EP_CMD				4
-
-#define AR9170_EEPROM_START			0x1600
-
-#define AR9170_GPIO_REG_BASE			0x1d0100
-#define AR9170_GPIO_REG_PORT_TYPE		AR9170_GPIO_REG_BASE
-#define AR9170_GPIO_REG_DATA			(AR9170_GPIO_REG_BASE + 4)
-#define AR9170_NUM_LEDS				2
-
-
-#define AR9170_USB_REG_BASE			0x1e1000
-#define AR9170_USB_REG_DMA_CTL			(AR9170_USB_REG_BASE + 0x108)
-#define		AR9170_DMA_CTL_ENABLE_TO_DEVICE		0x1
-#define		AR9170_DMA_CTL_ENABLE_FROM_DEVICE	0x2
-#define		AR9170_DMA_CTL_HIGH_SPEED		0x4
-#define		AR9170_DMA_CTL_PACKET_MODE		0x8
-
-#define AR9170_USB_REG_MAX_AGG_UPLOAD		(AR9170_USB_REG_BASE + 0x110)
-#define AR9170_USB_REG_UPLOAD_TIME_CTL		(AR9170_USB_REG_BASE + 0x114)
-
-
-
-#define AR9170_MAC_REG_BASE			0x1c3000
-
-#define AR9170_MAC_REG_TSF_L			(AR9170_MAC_REG_BASE + 0x514)
-#define AR9170_MAC_REG_TSF_H			(AR9170_MAC_REG_BASE + 0x518)
-
-#define AR9170_MAC_REG_ATIM_WINDOW		(AR9170_MAC_REG_BASE + 0x51C)
-#define AR9170_MAC_REG_BCN_PERIOD		(AR9170_MAC_REG_BASE + 0x520)
-#define AR9170_MAC_REG_PRETBTT			(AR9170_MAC_REG_BASE + 0x524)
-
-#define AR9170_MAC_REG_MAC_ADDR_L		(AR9170_MAC_REG_BASE + 0x610)
-#define AR9170_MAC_REG_MAC_ADDR_H		(AR9170_MAC_REG_BASE + 0x614)
-#define AR9170_MAC_REG_BSSID_L			(AR9170_MAC_REG_BASE + 0x618)
-#define AR9170_MAC_REG_BSSID_H			(AR9170_MAC_REG_BASE + 0x61c)
-
-#define AR9170_MAC_REG_GROUP_HASH_TBL_L		(AR9170_MAC_REG_BASE + 0x624)
-#define AR9170_MAC_REG_GROUP_HASH_TBL_H		(AR9170_MAC_REG_BASE + 0x628)
-
-#define AR9170_MAC_REG_RX_TIMEOUT		(AR9170_MAC_REG_BASE + 0x62C)
-
-#define AR9170_MAC_REG_BASIC_RATE		(AR9170_MAC_REG_BASE + 0x630)
-#define AR9170_MAC_REG_MANDATORY_RATE		(AR9170_MAC_REG_BASE + 0x634)
-#define AR9170_MAC_REG_RTS_CTS_RATE		(AR9170_MAC_REG_BASE + 0x638)
-#define AR9170_MAC_REG_BACKOFF_PROTECT		(AR9170_MAC_REG_BASE + 0x63c)
-#define AR9170_MAC_REG_RX_THRESHOLD		(AR9170_MAC_REG_BASE + 0x640)
-#define AR9170_MAC_REG_RX_PE_DELAY		(AR9170_MAC_REG_BASE + 0x64C)
-
-#define AR9170_MAC_REG_DYNAMIC_SIFS_ACK		(AR9170_MAC_REG_BASE + 0x658)
-#define AR9170_MAC_REG_SNIFFER			(AR9170_MAC_REG_BASE + 0x674)
-#define		AR9170_MAC_REG_SNIFFER_ENABLE_PROMISC	BIT(0)
-#define		AR9170_MAC_REG_SNIFFER_DEFAULTS		0x02000000
-#define AR9170_MAC_REG_ENCRYPTION		(AR9170_MAC_REG_BASE + 0x678)
-#define		AR9170_MAC_REG_ENCRYPTION_RX_SOFTWARE	BIT(3)
-#define		AR9170_MAC_REG_ENCRYPTION_DEFAULTS	0x70
-
-#define AR9170_MAC_REG_MISC_680			(AR9170_MAC_REG_BASE + 0x680)
-#define AR9170_MAC_REG_TX_UNDERRUN		(AR9170_MAC_REG_BASE + 0x688)
-
-#define AR9170_MAC_REG_FRAMETYPE_FILTER		(AR9170_MAC_REG_BASE + 0x68c)
-#define		AR9170_MAC_REG_FTF_ASSOC_REQ		BIT(0)
-#define		AR9170_MAC_REG_FTF_ASSOC_RESP		BIT(1)
-#define		AR9170_MAC_REG_FTF_REASSOC_REQ		BIT(2)
-#define		AR9170_MAC_REG_FTF_REASSOC_RESP		BIT(3)
-#define		AR9170_MAC_REG_FTF_PRB_REQ		BIT(4)
-#define		AR9170_MAC_REG_FTF_PRB_RESP		BIT(5)
-#define		AR9170_MAC_REG_FTF_BIT6			BIT(6)
-#define		AR9170_MAC_REG_FTF_BIT7			BIT(7)
-#define		AR9170_MAC_REG_FTF_BEACON		BIT(8)
-#define		AR9170_MAC_REG_FTF_ATIM			BIT(9)
-#define		AR9170_MAC_REG_FTF_DEASSOC		BIT(10)
-#define		AR9170_MAC_REG_FTF_AUTH			BIT(11)
-#define		AR9170_MAC_REG_FTF_DEAUTH		BIT(12)
-#define		AR9170_MAC_REG_FTF_BIT13		BIT(13)
-#define		AR9170_MAC_REG_FTF_BIT14		BIT(14)
-#define		AR9170_MAC_REG_FTF_BIT15		BIT(15)
-#define		AR9170_MAC_REG_FTF_BAR			BIT(24)
-#define		AR9170_MAC_REG_FTF_BA			BIT(25)
-#define		AR9170_MAC_REG_FTF_PSPOLL		BIT(26)
-#define		AR9170_MAC_REG_FTF_RTS			BIT(27)
-#define		AR9170_MAC_REG_FTF_CTS			BIT(28)
-#define		AR9170_MAC_REG_FTF_ACK			BIT(29)
-#define		AR9170_MAC_REG_FTF_CFE			BIT(30)
-#define		AR9170_MAC_REG_FTF_CFE_ACK		BIT(31)
-#define		AR9170_MAC_REG_FTF_DEFAULTS		0x0700ffff
-#define		AR9170_MAC_REG_FTF_MONITOR		0xfd00ffff
-
-#define AR9170_MAC_REG_RX_TOTAL			(AR9170_MAC_REG_BASE + 0x6A0)
-#define AR9170_MAC_REG_RX_CRC32			(AR9170_MAC_REG_BASE + 0x6A4)
-#define AR9170_MAC_REG_RX_CRC16			(AR9170_MAC_REG_BASE + 0x6A8)
-#define AR9170_MAC_REG_RX_ERR_DECRYPTION_UNI	(AR9170_MAC_REG_BASE + 0x6AC)
-#define AR9170_MAC_REG_RX_OVERRUN		(AR9170_MAC_REG_BASE + 0x6B0)
-#define AR9170_MAC_REG_RX_ERR_DECRYPTION_MUL	(AR9170_MAC_REG_BASE + 0x6BC)
-#define AR9170_MAC_REG_TX_RETRY			(AR9170_MAC_REG_BASE + 0x6CC)
-#define AR9170_MAC_REG_TX_TOTAL			(AR9170_MAC_REG_BASE + 0x6F4)
-
-
-#define AR9170_MAC_REG_ACK_EXTENSION		(AR9170_MAC_REG_BASE + 0x690)
-#define AR9170_MAC_REG_EIFS_AND_SIFS		(AR9170_MAC_REG_BASE + 0x698)
-
-#define AR9170_MAC_REG_SLOT_TIME		(AR9170_MAC_REG_BASE + 0x6F0)
-
-#define AR9170_MAC_REG_POWERMANAGEMENT		(AR9170_MAC_REG_BASE + 0x700)
-#define		AR9170_MAC_REG_POWERMGT_IBSS		0xe0
-#define		AR9170_MAC_REG_POWERMGT_AP		0xa1
-#define		AR9170_MAC_REG_POWERMGT_STA		0x2
-#define		AR9170_MAC_REG_POWERMGT_AP_WDS		0x3
-#define		AR9170_MAC_REG_POWERMGT_DEFAULTS	(0xf << 24)
-
-#define AR9170_MAC_REG_ROLL_CALL_TBL_L		(AR9170_MAC_REG_BASE + 0x704)
-#define AR9170_MAC_REG_ROLL_CALL_TBL_H		(AR9170_MAC_REG_BASE + 0x708)
-
-#define AR9170_MAC_REG_AC0_CW			(AR9170_MAC_REG_BASE + 0xB00)
-#define AR9170_MAC_REG_AC1_CW			(AR9170_MAC_REG_BASE + 0xB04)
-#define AR9170_MAC_REG_AC2_CW			(AR9170_MAC_REG_BASE + 0xB08)
-#define AR9170_MAC_REG_AC3_CW			(AR9170_MAC_REG_BASE + 0xB0C)
-#define AR9170_MAC_REG_AC4_CW			(AR9170_MAC_REG_BASE + 0xB10)
-#define AR9170_MAC_REG_AC1_AC0_AIFS		(AR9170_MAC_REG_BASE + 0xB14)
-#define AR9170_MAC_REG_AC3_AC2_AIFS		(AR9170_MAC_REG_BASE + 0xB18)
-
-#define AR9170_MAC_REG_RETRY_MAX		(AR9170_MAC_REG_BASE + 0xB28)
-
-#define AR9170_MAC_REG_FCS_SELECT		(AR9170_MAC_REG_BASE + 0xBB0)
-#define		AR9170_MAC_FCS_SWFCS		0x1
-#define		AR9170_MAC_FCS_FIFO_PROT	0x4
-
-
-#define AR9170_MAC_REG_TXOP_NOT_ENOUGH_IND	(AR9170_MAC_REG_BASE + 0xB30)
-
-#define AR9170_MAC_REG_AC1_AC0_TXOP		(AR9170_MAC_REG_BASE + 0xB44)
-#define AR9170_MAC_REG_AC3_AC2_TXOP		(AR9170_MAC_REG_BASE + 0xB48)
-
-#define AR9170_MAC_REG_AMPDU_FACTOR		(AR9170_MAC_REG_BASE + 0xB9C)
-#define AR9170_MAC_REG_AMPDU_DENSITY		(AR9170_MAC_REG_BASE + 0xBA0)
-
-#define AR9170_MAC_REG_ACK_TABLE		(AR9170_MAC_REG_BASE + 0xC00)
-#define AR9170_MAC_REG_AMPDU_RX_THRESH		(AR9170_MAC_REG_BASE + 0xC50)
-
-#define AR9170_MAC_REG_TXRX_MPI			(AR9170_MAC_REG_BASE + 0xD7C)
-#define		AR9170_MAC_TXRX_MPI_TX_MPI_MASK	0x0000000f
-#define		AR9170_MAC_TXRX_MPI_TX_TO_MASK	0x0000fff0
-#define		AR9170_MAC_TXRX_MPI_RX_MPI_MASK	0x000f0000
-#define		AR9170_MAC_TXRX_MPI_RX_TO_MASK	0xfff00000
-
-#define AR9170_MAC_REG_BCN_ADDR			(AR9170_MAC_REG_BASE + 0xD84)
-#define AR9170_MAC_REG_BCN_LENGTH		(AR9170_MAC_REG_BASE + 0xD88)
-#define AR9170_MAC_REG_BCN_PLCP			(AR9170_MAC_REG_BASE + 0xD90)
-#define AR9170_MAC_REG_BCN_CTRL			(AR9170_MAC_REG_BASE + 0xD94)
-#define AR9170_MAC_REG_BCN_HT1			(AR9170_MAC_REG_BASE + 0xDA0)
-#define AR9170_MAC_REG_BCN_HT2			(AR9170_MAC_REG_BASE + 0xDA4)
-
-
-#define AR9170_PWR_REG_BASE			0x1D4000
-
-#define AR9170_PWR_REG_CLOCK_SEL		(AR9170_PWR_REG_BASE + 0x008)
-#define		AR9170_PWR_CLK_AHB_40MHZ	0
-#define		AR9170_PWR_CLK_AHB_20_22MHZ	1
-#define		AR9170_PWR_CLK_AHB_40_44MHZ	2
-#define		AR9170_PWR_CLK_AHB_80_88MHZ	3
-#define		AR9170_PWR_CLK_DAC_160_INV_DLY	0x70
-
-
-/* put beacon here in memory */
-#define AR9170_BEACON_BUFFER_ADDRESS		0x117900
-
-
-struct ar9170_tx_control {
-	__le16 length;
-	__le16 mac_control;
-	__le32 phy_control;
-	u8 frame_data[0];
-} __packed;
-
-/* these are either-or */
-#define AR9170_TX_MAC_PROT_RTS			0x0001
-#define AR9170_TX_MAC_PROT_CTS			0x0002
-
-#define AR9170_TX_MAC_NO_ACK			0x0004
-/* if unset, MAC will only do SIFS space before frame */
-#define AR9170_TX_MAC_BACKOFF			0x0008
-#define AR9170_TX_MAC_BURST			0x0010
-#define AR9170_TX_MAC_AGGR			0x0020
-
-/* encryption is a two-bit field */
-#define AR9170_TX_MAC_ENCR_NONE			0x0000
-#define AR9170_TX_MAC_ENCR_RC4			0x0040
-#define AR9170_TX_MAC_ENCR_CENC			0x0080
-#define AR9170_TX_MAC_ENCR_AES			0x00c0
-
-#define AR9170_TX_MAC_MMIC			0x0100
-#define AR9170_TX_MAC_HW_DURATION		0x0200
-#define AR9170_TX_MAC_QOS_SHIFT			10
-#define AR9170_TX_MAC_QOS_MASK			(3 << AR9170_TX_MAC_QOS_SHIFT)
-#define AR9170_TX_MAC_AGGR_QOS_BIT1		0x0400
-#define AR9170_TX_MAC_AGGR_QOS_BIT2		0x0800
-#define AR9170_TX_MAC_DISABLE_TXOP		0x1000
-#define AR9170_TX_MAC_TXOP_RIFS			0x2000
-#define AR9170_TX_MAC_IMM_AMPDU			0x4000
-#define AR9170_TX_MAC_RATE_PROBE		0x8000
-
-/* either-or */
-#define AR9170_TX_PHY_MOD_MASK			0x00000003
-#define AR9170_TX_PHY_MOD_CCK			0x00000000
-#define AR9170_TX_PHY_MOD_OFDM			0x00000001
-#define AR9170_TX_PHY_MOD_HT			0x00000002
-
-/* depends on modulation */
-#define AR9170_TX_PHY_SHORT_PREAMBLE		0x00000004
-#define AR9170_TX_PHY_GREENFIELD		0x00000004
-
-#define AR9170_TX_PHY_BW_SHIFT			3
-#define AR9170_TX_PHY_BW_MASK			(3 << AR9170_TX_PHY_BW_SHIFT)
-#define AR9170_TX_PHY_BW_20MHZ			0
-#define AR9170_TX_PHY_BW_40MHZ			2
-#define AR9170_TX_PHY_BW_40MHZ_DUP		3
-
-#define AR9170_TX_PHY_TX_HEAVY_CLIP_SHIFT	6
-#define AR9170_TX_PHY_TX_HEAVY_CLIP_MASK	(7 << AR9170_TX_PHY_TX_HEAVY_CLIP_SHIFT)
-
-#define AR9170_TX_PHY_TX_PWR_SHIFT		9
-#define AR9170_TX_PHY_TX_PWR_MASK		(0x3f << AR9170_TX_PHY_TX_PWR_SHIFT)
-
-/* not part of the hw-spec */
-#define AR9170_TX_PHY_QOS_SHIFT			25
-#define AR9170_TX_PHY_QOS_MASK			(3 << AR9170_TX_PHY_QOS_SHIFT)
-
-#define AR9170_TX_PHY_TXCHAIN_SHIFT		15
-#define AR9170_TX_PHY_TXCHAIN_MASK		(7 << AR9170_TX_PHY_TXCHAIN_SHIFT)
-#define AR9170_TX_PHY_TXCHAIN_1			1
-/* use for cck, ofdm 6/9/12/18/24 and HT if capable */
-#define AR9170_TX_PHY_TXCHAIN_2			5
-
-#define AR9170_TX_PHY_MCS_SHIFT			18
-#define AR9170_TX_PHY_MCS_MASK			(0x7f << AR9170_TX_PHY_MCS_SHIFT)
-
-#define AR9170_TX_PHY_SHORT_GI			0x80000000
-
-#define AR5416_MAX_RATE_POWER                   63
-
-struct ar9170_rx_head {
-	u8 plcp[12];
-} __packed;
-
-struct ar9170_rx_phystatus {
-	union {
-		struct {
-			u8 rssi_ant0, rssi_ant1, rssi_ant2,
-			   rssi_ant0x, rssi_ant1x, rssi_ant2x,
-			   rssi_combined;
-		} __packed;
-		u8 rssi[7];
-	} __packed;
-
-	u8 evm_stream0[6], evm_stream1[6];
-	u8 phy_err;
-} __packed;
-
-struct ar9170_rx_macstatus {
-	u8 SAidx, DAidx;
-	u8 error;
-	u8 status;
-} __packed;
-
-#define AR9170_ENC_ALG_NONE			0x0
-#define AR9170_ENC_ALG_WEP64			0x1
-#define AR9170_ENC_ALG_TKIP			0x2
-#define AR9170_ENC_ALG_AESCCMP			0x4
-#define AR9170_ENC_ALG_WEP128			0x5
-#define AR9170_ENC_ALG_WEP256			0x6
-#define AR9170_ENC_ALG_CENC			0x7
-
-#define AR9170_RX_ENC_SOFTWARE			0x8
-
-static inline u8 ar9170_get_decrypt_type(struct ar9170_rx_macstatus *t)
-{
-	return (t->SAidx & 0xc0) >> 4 |
-	       (t->DAidx & 0xc0) >> 6;
-}
-
-#define AR9170_RX_STATUS_MODULATION_MASK	0x03
-#define AR9170_RX_STATUS_MODULATION_CCK		0x00
-#define AR9170_RX_STATUS_MODULATION_OFDM	0x01
-#define AR9170_RX_STATUS_MODULATION_HT		0x02
-#define AR9170_RX_STATUS_MODULATION_DUPOFDM	0x03
-
-/* depends on modulation */
-#define AR9170_RX_STATUS_SHORT_PREAMBLE		0x08
-#define AR9170_RX_STATUS_GREENFIELD		0x08
-
-#define AR9170_RX_STATUS_MPDU_MASK		0x30
-#define AR9170_RX_STATUS_MPDU_SINGLE		0x00
-#define AR9170_RX_STATUS_MPDU_FIRST		0x20
-#define AR9170_RX_STATUS_MPDU_MIDDLE		0x30
-#define AR9170_RX_STATUS_MPDU_LAST		0x10
-
-#define AR9170_RX_ERROR_RXTO			0x01
-#define AR9170_RX_ERROR_OVERRUN			0x02
-#define AR9170_RX_ERROR_DECRYPT			0x04
-#define AR9170_RX_ERROR_FCS			0x08
-#define AR9170_RX_ERROR_WRONG_RA		0x10
-#define AR9170_RX_ERROR_PLCP			0x20
-#define AR9170_RX_ERROR_MMIC			0x40
-#define AR9170_RX_ERROR_FATAL			0x80
-
-struct ar9170_cmd_tx_status {
-	u8 dst[ETH_ALEN];
-	__le32 rate;
-	__le16 status;
-} __packed;
-
-#define AR9170_TX_STATUS_COMPLETE		0x00
-#define AR9170_TX_STATUS_RETRY			0x01
-#define AR9170_TX_STATUS_FAILED			0x02
-
-struct ar9170_cmd_ba_failed_count {
-	__le16 failed;
-	__le16 rate;
-} __packed;
-
-struct ar9170_cmd_response {
-	u8 flag;
-	u8 type;
-	__le16 padding;
-
-	union {
-		struct ar9170_cmd_tx_status		tx_status;
-		struct ar9170_cmd_ba_failed_count	ba_fail_cnt;
-		u8 data[0];
-	};
-} __packed;
-
-/* QoS */
-
-/* mac80211 queue to HW/FW map */
-static const u8 ar9170_qos_hwmap[4] = { 3, 2, 0, 1 };
-
-/* HW/FW queue to mac80211 map */
-static const u8 ar9170_qos_mac80211map[4] = { 2, 3, 1, 0 };
-
-enum ar9170_txq {
-	AR9170_TXQ_BE,
-	AR9170_TXQ_BK,
-	AR9170_TXQ_VI,
-	AR9170_TXQ_VO,
-
-	__AR9170_NUM_TXQ,
-};
-
-#define AR9170_TXQ_DEPTH	32
-#define AR9170_TX_MAX_PENDING	128
-#define AR9170_RX_STREAM_MAX_SIZE 65535
-
-#endif /* __AR9170_HW_H */
diff -druN linux-2.6.39-libre/drivers/net/wireless/ath/ar9170/Kconfig linux-3.0-rc7-libre/drivers/net/wireless/ath/ar9170/Kconfig
--- linux-2.6.39-libre/drivers/net/wireless/ath/ar9170/Kconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/ath/ar9170/Kconfig	1969-12-31 19:00:00.000000000 -0500
@@ -1,20 +0,0 @@
-config AR9170_USB
-	tristate "Atheros AR9170 802.11n USB support (OBSOLETE)"
-	depends on USB && MAC80211
-	select FW_LOADER
-	help
-	  This driver is going to get replaced by carl9170.
-
-	  This is a driver for the Atheros "otus" 802.11n USB devices.
-
-	  These devices require additional firmware (2 files).
-	  For now, these files can be downloaded from here:
-
-	  http://wireless.kernel.org/en/users/Drivers/ar9170
-
-	  If you choose to build a module, it'll be called ar9170usb.
-
-config AR9170_LEDS
-	bool
-	depends on AR9170_USB && MAC80211_LEDS && (LEDS_CLASS = y || LEDS_CLASS = AR9170_USB)
-	default y
diff -druN linux-2.6.39-libre/drivers/net/wireless/ath/ar9170/led.c linux-3.0-rc7-libre/drivers/net/wireless/ath/ar9170/led.c
--- linux-2.6.39-libre/drivers/net/wireless/ath/ar9170/led.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/ath/ar9170/led.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,181 +0,0 @@
-/*
- * Atheros AR9170 driver
- *
- * LED handling
- *
- * Copyright 2008, Johannes Berg <johannes@sipsolutions.net>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; see the file COPYING.  If not, see
- * http://www.gnu.org/licenses/.
- *
- * This file incorporates work covered by the following copyright and
- * permission notice:
- *    Copyright (c) 2007-2008 Atheros Communications, Inc.
- *
- *    Permission to use, copy, modify, and/or distribute this software for any
- *    purpose with or without fee is hereby granted, provided that the above
- *    copyright notice and this permission notice appear in all copies.
- *
- *    THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- *    WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- *    MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- *    ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- *    WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- *    ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- *    OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include "ar9170.h"
-#include "cmd.h"
-
-int ar9170_set_leds_state(struct ar9170 *ar, u32 led_state)
-{
-	return ar9170_write_reg(ar, AR9170_GPIO_REG_DATA, led_state);
-}
-
-int ar9170_init_leds(struct ar9170 *ar)
-{
-	int err;
-
-	/* disable LEDs */
-	/* GPIO [0/1 mode: output, 2/3: input] */
-	err = ar9170_write_reg(ar, AR9170_GPIO_REG_PORT_TYPE, 3);
-	if (err)
-		goto out;
-
-	/* GPIO 0/1 value: off */
-	err = ar9170_set_leds_state(ar, 0);
-
-out:
-	return err;
-}
-
-#ifdef CONFIG_AR9170_LEDS
-static void ar9170_update_leds(struct work_struct *work)
-{
-	struct ar9170 *ar = container_of(work, struct ar9170, led_work.work);
-	int i, tmp, blink_delay = 1000;
-	u32 led_val = 0;
-	bool rerun = false;
-
-	if (unlikely(!IS_ACCEPTING_CMD(ar)))
-		return ;
-
-	mutex_lock(&ar->mutex);
-	for (i = 0; i < AR9170_NUM_LEDS; i++)
-		if (ar->leds[i].registered && ar->leds[i].toggled) {
-			led_val |= 1 << i;
-
-			tmp = 70 + 200 / (ar->leds[i].toggled);
-			if (tmp < blink_delay)
-				blink_delay = tmp;
-
-			if (ar->leds[i].toggled > 1)
-				ar->leds[i].toggled = 0;
-
-			rerun = true;
-		}
-
-	ar9170_set_leds_state(ar, led_val);
-	mutex_unlock(&ar->mutex);
-
-	if (!rerun)
-		return;
-
-	ieee80211_queue_delayed_work(ar->hw,
-				     &ar->led_work,
-				     msecs_to_jiffies(blink_delay));
-}
-
-static void ar9170_led_brightness_set(struct led_classdev *led,
-				      enum led_brightness brightness)
-{
-	struct ar9170_led *arl = container_of(led, struct ar9170_led, l);
-	struct ar9170 *ar = arl->ar;
-
-	if (unlikely(!arl->registered))
-		return ;
-
-	if (arl->last_state != !!brightness) {
-		arl->toggled++;
-		arl->last_state = !!brightness;
-	}
-
-	if (likely(IS_ACCEPTING_CMD(ar) && arl->toggled))
-		ieee80211_queue_delayed_work(ar->hw, &ar->led_work, HZ/10);
-}
-
-static int ar9170_register_led(struct ar9170 *ar, int i, char *name,
-			       char *trigger)
-{
-	int err;
-
-	snprintf(ar->leds[i].name, sizeof(ar->leds[i].name),
-		 "ar9170-%s::%s", wiphy_name(ar->hw->wiphy), name);
-
-	ar->leds[i].ar = ar;
-	ar->leds[i].l.name = ar->leds[i].name;
-	ar->leds[i].l.brightness_set = ar9170_led_brightness_set;
-	ar->leds[i].l.brightness = 0;
-	ar->leds[i].l.default_trigger = trigger;
-
-	err = led_classdev_register(wiphy_dev(ar->hw->wiphy),
-				    &ar->leds[i].l);
-	if (err)
-		wiphy_err(ar->hw->wiphy, "failed to register %s LED (%d).\n",
-			  ar->leds[i].name, err);
-	else
-		ar->leds[i].registered = true;
-
-	return err;
-}
-
-void ar9170_unregister_leds(struct ar9170 *ar)
-{
-	int i;
-
-	for (i = 0; i < AR9170_NUM_LEDS; i++)
-		if (ar->leds[i].registered) {
-			led_classdev_unregister(&ar->leds[i].l);
-			ar->leds[i].registered = false;
-			ar->leds[i].toggled = 0;
-		}
-
-	cancel_delayed_work_sync(&ar->led_work);
-}
-
-int ar9170_register_leds(struct ar9170 *ar)
-{
-	int err;
-
-	INIT_DELAYED_WORK(&ar->led_work, ar9170_update_leds);
-
-	err = ar9170_register_led(ar, 0, "tx",
-				  ieee80211_get_tx_led_name(ar->hw));
-	if (err)
-		goto fail;
-
-	err = ar9170_register_led(ar, 1, "assoc",
-				 ieee80211_get_assoc_led_name(ar->hw));
-	if (err)
-		goto fail;
-
-	return 0;
-
-fail:
-	ar9170_unregister_leds(ar);
-	return err;
-}
-
-#endif /* CONFIG_AR9170_LEDS */
diff -druN linux-2.6.39-libre/drivers/net/wireless/ath/ar9170/mac.c linux-3.0-rc7-libre/drivers/net/wireless/ath/ar9170/mac.c
--- linux-2.6.39-libre/drivers/net/wireless/ath/ar9170/mac.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/ath/ar9170/mac.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,519 +0,0 @@
-/*
- * Atheros AR9170 driver
- *
- * MAC programming
- *
- * Copyright 2008, Johannes Berg <johannes@sipsolutions.net>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; see the file COPYING.  If not, see
- * http://www.gnu.org/licenses/.
- *
- * This file incorporates work covered by the following copyright and
- * permission notice:
- *    Copyright (c) 2007-2008 Atheros Communications, Inc.
- *
- *    Permission to use, copy, modify, and/or distribute this software for any
- *    purpose with or without fee is hereby granted, provided that the above
- *    copyright notice and this permission notice appear in all copies.
- *
- *    THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- *    WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- *    MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- *    ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- *    WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- *    ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- *    OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include <asm/unaligned.h>
-
-#include "ar9170.h"
-#include "cmd.h"
-
-int ar9170_set_dyn_sifs_ack(struct ar9170 *ar)
-{
-	u32 val;
-
-	if (conf_is_ht40(&ar->hw->conf))
-		val = 0x010a;
-	else {
-		if (ar->hw->conf.channel->band == IEEE80211_BAND_2GHZ)
-			val = 0x105;
-		else
-			val = 0x104;
-	}
-
-	return ar9170_write_reg(ar, AR9170_MAC_REG_DYNAMIC_SIFS_ACK, val);
-}
-
-int ar9170_set_slot_time(struct ar9170 *ar)
-{
-	u32 slottime = 20;
-
-	if (!ar->vif)
-		return 0;
-
-	if ((ar->hw->conf.channel->band == IEEE80211_BAND_5GHZ) ||
-	    ar->vif->bss_conf.use_short_slot)
-		slottime = 9;
-
-	return ar9170_write_reg(ar, AR9170_MAC_REG_SLOT_TIME, slottime << 10);
-}
-
-int ar9170_set_basic_rates(struct ar9170 *ar)
-{
-	u8 cck, ofdm;
-
-	if (!ar->vif)
-		return 0;
-
-	ofdm = ar->vif->bss_conf.basic_rates >> 4;
-
-	/* FIXME: is still necessary? */
-	if (ar->hw->conf.channel->band == IEEE80211_BAND_5GHZ)
-		cck = 0;
-	else
-		cck = ar->vif->bss_conf.basic_rates & 0xf;
-
-	return ar9170_write_reg(ar, AR9170_MAC_REG_BASIC_RATE,
-				ofdm << 8 | cck);
-}
-
-int ar9170_set_qos(struct ar9170 *ar)
-{
-	ar9170_regwrite_begin(ar);
-
-	ar9170_regwrite(AR9170_MAC_REG_AC0_CW, ar->edcf[0].cw_min |
-			(ar->edcf[0].cw_max << 16));
-	ar9170_regwrite(AR9170_MAC_REG_AC1_CW, ar->edcf[1].cw_min |
-			(ar->edcf[1].cw_max << 16));
-	ar9170_regwrite(AR9170_MAC_REG_AC2_CW, ar->edcf[2].cw_min |
-			(ar->edcf[2].cw_max << 16));
-	ar9170_regwrite(AR9170_MAC_REG_AC3_CW, ar->edcf[3].cw_min |
-			(ar->edcf[3].cw_max << 16));
-	ar9170_regwrite(AR9170_MAC_REG_AC4_CW, ar->edcf[4].cw_min |
-			(ar->edcf[4].cw_max << 16));
-
-	ar9170_regwrite(AR9170_MAC_REG_AC1_AC0_AIFS,
-			((ar->edcf[0].aifs * 9 + 10)) |
-			((ar->edcf[1].aifs * 9 + 10) << 12) |
-			((ar->edcf[2].aifs * 9 + 10) << 24));
-	ar9170_regwrite(AR9170_MAC_REG_AC3_AC2_AIFS,
-			((ar->edcf[2].aifs * 9 + 10) >> 8) |
-			((ar->edcf[3].aifs * 9 + 10) << 4) |
-			((ar->edcf[4].aifs * 9 + 10) << 16));
-
-	ar9170_regwrite(AR9170_MAC_REG_AC1_AC0_TXOP,
-			ar->edcf[0].txop | ar->edcf[1].txop << 16);
-	ar9170_regwrite(AR9170_MAC_REG_AC3_AC2_TXOP,
-			ar->edcf[2].txop | ar->edcf[3].txop << 16);
-
-	ar9170_regwrite_finish();
-
-	return ar9170_regwrite_result();
-}
-
-static int ar9170_set_ampdu_density(struct ar9170 *ar, u8 mpdudensity)
-{
-	u32 val;
-
-	/* don't allow AMPDU density > 8us */
-	if (mpdudensity > 6)
-		return -EINVAL;
-
-	/* Watch out! Otus uses slightly different density values. */
-	val = 0x140a00 | (mpdudensity ? (mpdudensity + 1) : 0);
-
-	ar9170_regwrite_begin(ar);
-	ar9170_regwrite(AR9170_MAC_REG_AMPDU_DENSITY, val);
-	ar9170_regwrite_finish();
-
-	return ar9170_regwrite_result();
-}
-
-int ar9170_init_mac(struct ar9170 *ar)
-{
-	ar9170_regwrite_begin(ar);
-
-	ar9170_regwrite(AR9170_MAC_REG_ACK_EXTENSION, 0x40);
-
-	ar9170_regwrite(AR9170_MAC_REG_RETRY_MAX, 0);
-
-	/* enable MMIC */
-	ar9170_regwrite(AR9170_MAC_REG_SNIFFER,
-			AR9170_MAC_REG_SNIFFER_DEFAULTS);
-
-	ar9170_regwrite(AR9170_MAC_REG_RX_THRESHOLD, 0xc1f80);
-
-	ar9170_regwrite(AR9170_MAC_REG_RX_PE_DELAY, 0x70);
-	ar9170_regwrite(AR9170_MAC_REG_EIFS_AND_SIFS, 0xa144000);
-	ar9170_regwrite(AR9170_MAC_REG_SLOT_TIME, 9 << 10);
-
-	/* CF-END mode */
-	ar9170_regwrite(0x1c3b2c, 0x19000000);
-
-	/* NAV protects ACK only (in TXOP) */
-	ar9170_regwrite(0x1c3b38, 0x201);
-
-	/* Set Beacon PHY CTRL's TPC to 0x7, TA1=1 */
-	/* OTUS set AM to 0x1 */
-	ar9170_regwrite(AR9170_MAC_REG_BCN_HT1, 0x8000170);
-
-	ar9170_regwrite(AR9170_MAC_REG_BACKOFF_PROTECT, 0x105);
-
-	/* AGG test code*/
-	/* Aggregation MAX number and timeout */
-	ar9170_regwrite(0x1c3b9c, 0x10000a);
-
-	ar9170_regwrite(AR9170_MAC_REG_FRAMETYPE_FILTER,
-			AR9170_MAC_REG_FTF_DEFAULTS);
-
-	/* Enable deaggregator, response in sniffer mode */
-	ar9170_regwrite(0x1c3c40, 0x1 | 1<<30);
-
-	/* rate sets */
-	ar9170_regwrite(AR9170_MAC_REG_BASIC_RATE, 0x150f);
-	ar9170_regwrite(AR9170_MAC_REG_MANDATORY_RATE, 0x150f);
-	ar9170_regwrite(AR9170_MAC_REG_RTS_CTS_RATE, 0x10b01bb);
-
-	/* MIMO response control */
-	ar9170_regwrite(0x1c3694, 0x4003C1E);/* bit 26~28  otus-AM */
-
-	/* switch MAC to OTUS interface */
-	ar9170_regwrite(0x1c3600, 0x3);
-
-	ar9170_regwrite(AR9170_MAC_REG_AMPDU_RX_THRESH, 0xffff);
-
-	/* set PHY register read timeout (??) */
-	ar9170_regwrite(AR9170_MAC_REG_MISC_680, 0xf00008);
-
-	/* Disable Rx TimeOut, workaround for BB. */
-	ar9170_regwrite(AR9170_MAC_REG_RX_TIMEOUT, 0x0);
-
-	/* Set CPU clock frequency to 88/80MHz */
-	ar9170_regwrite(AR9170_PWR_REG_CLOCK_SEL,
-			AR9170_PWR_CLK_AHB_80_88MHZ |
-			AR9170_PWR_CLK_DAC_160_INV_DLY);
-
-	/* Set WLAN DMA interrupt mode: generate int per packet */
-	ar9170_regwrite(AR9170_MAC_REG_TXRX_MPI, 0x110011);
-
-	ar9170_regwrite(AR9170_MAC_REG_FCS_SELECT,
-			AR9170_MAC_FCS_FIFO_PROT);
-
-	/* Disables the CF_END frame, undocumented register */
-	ar9170_regwrite(AR9170_MAC_REG_TXOP_NOT_ENOUGH_IND,
-			0x141E0F48);
-
-	ar9170_regwrite_finish();
-
-	return ar9170_regwrite_result();
-}
-
-static int ar9170_set_mac_reg(struct ar9170 *ar, const u32 reg, const u8 *mac)
-{
-	static const u8 zero[ETH_ALEN] = { 0 };
-
-	if (!mac)
-		mac = zero;
-
-	ar9170_regwrite_begin(ar);
-
-	ar9170_regwrite(reg, get_unaligned_le32(mac));
-	ar9170_regwrite(reg + 4, get_unaligned_le16(mac + 4));
-
-	ar9170_regwrite_finish();
-
-	return ar9170_regwrite_result();
-}
-
-int ar9170_update_multicast(struct ar9170 *ar, const u64 mc_hash)
-{
-	int err;
-
-	ar9170_regwrite_begin(ar);
-	ar9170_regwrite(AR9170_MAC_REG_GROUP_HASH_TBL_H, mc_hash >> 32);
-	ar9170_regwrite(AR9170_MAC_REG_GROUP_HASH_TBL_L, mc_hash);
-	ar9170_regwrite_finish();
-	err = ar9170_regwrite_result();
-	if (err)
-		return err;
-
-	ar->cur_mc_hash = mc_hash;
-	return 0;
-}
-
-int ar9170_update_frame_filter(struct ar9170 *ar, const u32 filter)
-{
-	int err;
-
-	err = ar9170_write_reg(ar, AR9170_MAC_REG_FRAMETYPE_FILTER, filter);
-	if (err)
-		return err;
-
-	ar->cur_filter = filter;
-	return 0;
-}
-
-static int ar9170_set_promiscouous(struct ar9170 *ar)
-{
-	u32 encr_mode, sniffer;
-	int err;
-
-	err = ar9170_read_reg(ar, AR9170_MAC_REG_SNIFFER, &sniffer);
-	if (err)
-		return err;
-
-	err = ar9170_read_reg(ar, AR9170_MAC_REG_ENCRYPTION, &encr_mode);
-	if (err)
-		return err;
-
-	if (ar->sniffer_enabled) {
-		sniffer |= AR9170_MAC_REG_SNIFFER_ENABLE_PROMISC;
-
-		/*
-		 * Rx decryption works in place.
-		 *
-		 * If we don't disable it, the hardware will render all
-		 * encrypted frames which are encrypted with an unknown
-		 * key useless.
-		 */
-
-		encr_mode |= AR9170_MAC_REG_ENCRYPTION_RX_SOFTWARE;
-		ar->sniffer_enabled = true;
-	} else {
-		sniffer &= ~AR9170_MAC_REG_SNIFFER_ENABLE_PROMISC;
-
-		if (ar->rx_software_decryption)
-			encr_mode |= AR9170_MAC_REG_ENCRYPTION_RX_SOFTWARE;
-		else
-			encr_mode &= ~AR9170_MAC_REG_ENCRYPTION_RX_SOFTWARE;
-	}
-
-	ar9170_regwrite_begin(ar);
-	ar9170_regwrite(AR9170_MAC_REG_ENCRYPTION, encr_mode);
-	ar9170_regwrite(AR9170_MAC_REG_SNIFFER, sniffer);
-	ar9170_regwrite_finish();
-
-	return ar9170_regwrite_result();
-}
-
-int ar9170_set_operating_mode(struct ar9170 *ar)
-{
-	struct ath_common *common = &ar->common;
-	u32 pm_mode = AR9170_MAC_REG_POWERMGT_DEFAULTS;
-	u8 *mac_addr, *bssid;
-	int err;
-
-	if (ar->vif) {
-		mac_addr = common->macaddr;
-		bssid = common->curbssid;
-
-		switch (ar->vif->type) {
-		case NL80211_IFTYPE_MESH_POINT:
-		case NL80211_IFTYPE_ADHOC:
-			pm_mode |= AR9170_MAC_REG_POWERMGT_IBSS;
-			break;
-		case NL80211_IFTYPE_AP:
-			pm_mode |= AR9170_MAC_REG_POWERMGT_AP;
-			break;
-		case NL80211_IFTYPE_WDS:
-			pm_mode |= AR9170_MAC_REG_POWERMGT_AP_WDS;
-			break;
-		case NL80211_IFTYPE_MONITOR:
-			ar->sniffer_enabled = true;
-			ar->rx_software_decryption = true;
-			break;
-		default:
-			pm_mode |= AR9170_MAC_REG_POWERMGT_STA;
-			break;
-		}
-	} else {
-		mac_addr = NULL;
-		bssid = NULL;
-	}
-
-	err = ar9170_set_mac_reg(ar, AR9170_MAC_REG_MAC_ADDR_L, mac_addr);
-	if (err)
-		return err;
-
-	err = ar9170_set_mac_reg(ar, AR9170_MAC_REG_BSSID_L, bssid);
-	if (err)
-		return err;
-
-	err = ar9170_set_promiscouous(ar);
-	if (err)
-		return err;
-
-	/* set AMPDU density to 8us. */
-	err = ar9170_set_ampdu_density(ar, 6);
-	if (err)
-		return err;
-
-	ar9170_regwrite_begin(ar);
-
-	ar9170_regwrite(AR9170_MAC_REG_POWERMANAGEMENT, pm_mode);
-	ar9170_regwrite_finish();
-
-	return ar9170_regwrite_result();
-}
-
-int ar9170_set_hwretry_limit(struct ar9170 *ar, unsigned int max_retry)
-{
-	u32 tmp = min_t(u32, 0x33333, max_retry * 0x11111);
-
-	return ar9170_write_reg(ar, AR9170_MAC_REG_RETRY_MAX, tmp);
-}
-
-int ar9170_set_beacon_timers(struct ar9170 *ar)
-{
-	u32 v = 0;
-	u32 pretbtt = 0;
-
-	if (ar->vif) {
-		v |= ar->vif->bss_conf.beacon_int;
-
-		if (ar->enable_beacon) {
-			switch (ar->vif->type) {
-			case NL80211_IFTYPE_MESH_POINT:
-			case NL80211_IFTYPE_ADHOC:
-				v |= BIT(25);
-				break;
-			case NL80211_IFTYPE_AP:
-				v |= BIT(24);
-				pretbtt = (ar->vif->bss_conf.beacon_int - 6) <<
-					  16;
-				break;
-			default:
-			break;
-			}
-		}
-
-		v |= ar->vif->bss_conf.dtim_period << 16;
-	}
-
-	ar9170_regwrite_begin(ar);
-	ar9170_regwrite(AR9170_MAC_REG_PRETBTT, pretbtt);
-	ar9170_regwrite(AR9170_MAC_REG_BCN_PERIOD, v);
-	ar9170_regwrite_finish();
-	return ar9170_regwrite_result();
-}
-
-int ar9170_update_beacon(struct ar9170 *ar)
-{
-	struct sk_buff *skb;
-	__le32 *data, *old = NULL;
-	u32 word;
-	int i;
-
-	skb = ieee80211_beacon_get(ar->hw, ar->vif);
-	if (!skb)
-		return -ENOMEM;
-
-	data = (__le32 *)skb->data;
-	if (ar->beacon)
-		old = (__le32 *)ar->beacon->data;
-
-	ar9170_regwrite_begin(ar);
-	for (i = 0; i < DIV_ROUND_UP(skb->len, 4); i++) {
-		/*
-		 * XXX: This accesses beyond skb data for up
-		 *	to the last 3 bytes!!
-		 */
-
-		if (old && (data[i] == old[i]))
-			continue;
-
-		word = le32_to_cpu(data[i]);
-		ar9170_regwrite(AR9170_BEACON_BUFFER_ADDRESS + 4 * i, word);
-	}
-
-	/* XXX: use skb->cb info */
-	if (ar->hw->conf.channel->band == IEEE80211_BAND_2GHZ)
-		ar9170_regwrite(AR9170_MAC_REG_BCN_PLCP,
-				((skb->len + 4) << (3 + 16)) + 0x0400);
-	else
-		ar9170_regwrite(AR9170_MAC_REG_BCN_PLCP,
-				((skb->len + 4) << 16) + 0x001b);
-
-	ar9170_regwrite(AR9170_MAC_REG_BCN_LENGTH, skb->len + 4);
-	ar9170_regwrite(AR9170_MAC_REG_BCN_ADDR, AR9170_BEACON_BUFFER_ADDRESS);
-	ar9170_regwrite(AR9170_MAC_REG_BCN_CTRL, 1);
-
-	ar9170_regwrite_finish();
-
-	dev_kfree_skb(ar->beacon);
-	ar->beacon = skb;
-
-	return ar9170_regwrite_result();
-}
-
-void ar9170_new_beacon(struct work_struct *work)
-{
-	struct ar9170 *ar = container_of(work, struct ar9170,
-					 beacon_work);
-	struct sk_buff *skb;
-
-	if (unlikely(!IS_STARTED(ar)))
-		return ;
-
-	mutex_lock(&ar->mutex);
-
-	if (!ar->vif)
-		goto out;
-
-	ar9170_update_beacon(ar);
-
-	rcu_read_lock();
-	while ((skb = ieee80211_get_buffered_bc(ar->hw, ar->vif)))
-		ar9170_op_tx(ar->hw, skb);
-
-	rcu_read_unlock();
-
- out:
-	mutex_unlock(&ar->mutex);
-}
-
-int ar9170_upload_key(struct ar9170 *ar, u8 id, const u8 *mac, u8 ktype,
-		      u8 keyidx, u8 *keydata, int keylen)
-{
-	__le32 vals[7];
-	static const u8 bcast[ETH_ALEN] =
-		{ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
-	u8 dummy;
-
-	mac = mac ? : bcast;
-
-	vals[0] = cpu_to_le32((keyidx << 16) + id);
-	vals[1] = cpu_to_le32(mac[1] << 24 | mac[0] << 16 | ktype);
-	vals[2] = cpu_to_le32(mac[5] << 24 | mac[4] << 16 |
-			      mac[3] << 8 | mac[2]);
-	memset(&vals[3], 0, 16);
-	if (keydata)
-		memcpy(&vals[3], keydata, keylen);
-
-	return ar->exec_cmd(ar, AR9170_CMD_EKEY,
-			    sizeof(vals), (u8 *)vals,
-			    1, &dummy);
-}
-
-int ar9170_disable_key(struct ar9170 *ar, u8 id)
-{
-	__le32 val = cpu_to_le32(id);
-	u8 dummy;
-
-	return ar->exec_cmd(ar, AR9170_CMD_EKEY,
-			    sizeof(val), (u8 *)&val,
-			    1, &dummy);
-}
diff -druN linux-2.6.39-libre/drivers/net/wireless/ath/ar9170/main.c linux-3.0-rc7-libre/drivers/net/wireless/ath/ar9170/main.c
--- linux-2.6.39-libre/drivers/net/wireless/ath/ar9170/main.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/ath/ar9170/main.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,2190 +0,0 @@
-/*
- * Atheros AR9170 driver
- *
- * mac80211 interaction code
- *
- * Copyright 2008, Johannes Berg <johannes@sipsolutions.net>
- * Copyright 2009, Christian Lamparter <chunkeey@web.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; see the file COPYING.  If not, see
- * http://www.gnu.org/licenses/.
- *
- * This file incorporates work covered by the following copyright and
- * permission notice:
- *    Copyright (c) 2007-2008 Atheros Communications, Inc.
- *
- *    Permission to use, copy, modify, and/or distribute this software for any
- *    purpose with or without fee is hereby granted, provided that the above
- *    copyright notice and this permission notice appear in all copies.
- *
- *    THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- *    WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- *    MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- *    ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- *    WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- *    ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- *    OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/module.h>
-#include <linux/etherdevice.h>
-#include <net/mac80211.h>
-#include "ar9170.h"
-#include "hw.h"
-#include "cmd.h"
-
-static int modparam_nohwcrypt;
-module_param_named(nohwcrypt, modparam_nohwcrypt, bool, S_IRUGO);
-MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption.");
-
-#define RATE(_bitrate, _hw_rate, _txpidx, _flags) {	\
-	.bitrate	= (_bitrate),			\
-	.flags		= (_flags),			\
-	.hw_value	= (_hw_rate) | (_txpidx) << 4,	\
-}
-
-static struct ieee80211_rate __ar9170_ratetable[] = {
-	RATE(10, 0, 0, 0),
-	RATE(20, 1, 1, IEEE80211_RATE_SHORT_PREAMBLE),
-	RATE(55, 2, 2, IEEE80211_RATE_SHORT_PREAMBLE),
-	RATE(110, 3, 3, IEEE80211_RATE_SHORT_PREAMBLE),
-	RATE(60, 0xb, 0, 0),
-	RATE(90, 0xf, 0, 0),
-	RATE(120, 0xa, 0, 0),
-	RATE(180, 0xe, 0, 0),
-	RATE(240, 0x9, 0, 0),
-	RATE(360, 0xd, 1, 0),
-	RATE(480, 0x8, 2, 0),
-	RATE(540, 0xc, 3, 0),
-};
-#undef RATE
-
-#define ar9170_g_ratetable	(__ar9170_ratetable + 0)
-#define ar9170_g_ratetable_size	12
-#define ar9170_a_ratetable	(__ar9170_ratetable + 4)
-#define ar9170_a_ratetable_size	8
-
-/*
- * NB: The hw_value is used as an index into the ar9170_phy_freq_params
- *     array in phy.c so that we don't have to do frequency lookups!
- */
-#define CHAN(_freq, _idx) {		\
-	.center_freq	= (_freq),	\
-	.hw_value	= (_idx),	\
-	.max_power	= 18, /* XXX */	\
-}
-
-static struct ieee80211_channel ar9170_2ghz_chantable[] = {
-	CHAN(2412,  0),
-	CHAN(2417,  1),
-	CHAN(2422,  2),
-	CHAN(2427,  3),
-	CHAN(2432,  4),
-	CHAN(2437,  5),
-	CHAN(2442,  6),
-	CHAN(2447,  7),
-	CHAN(2452,  8),
-	CHAN(2457,  9),
-	CHAN(2462, 10),
-	CHAN(2467, 11),
-	CHAN(2472, 12),
-	CHAN(2484, 13),
-};
-
-static struct ieee80211_channel ar9170_5ghz_chantable[] = {
-	CHAN(4920, 14),
-	CHAN(4940, 15),
-	CHAN(4960, 16),
-	CHAN(4980, 17),
-	CHAN(5040, 18),
-	CHAN(5060, 19),
-	CHAN(5080, 20),
-	CHAN(5180, 21),
-	CHAN(5200, 22),
-	CHAN(5220, 23),
-	CHAN(5240, 24),
-	CHAN(5260, 25),
-	CHAN(5280, 26),
-	CHAN(5300, 27),
-	CHAN(5320, 28),
-	CHAN(5500, 29),
-	CHAN(5520, 30),
-	CHAN(5540, 31),
-	CHAN(5560, 32),
-	CHAN(5580, 33),
-	CHAN(5600, 34),
-	CHAN(5620, 35),
-	CHAN(5640, 36),
-	CHAN(5660, 37),
-	CHAN(5680, 38),
-	CHAN(5700, 39),
-	CHAN(5745, 40),
-	CHAN(5765, 41),
-	CHAN(5785, 42),
-	CHAN(5805, 43),
-	CHAN(5825, 44),
-	CHAN(5170, 45),
-	CHAN(5190, 46),
-	CHAN(5210, 47),
-	CHAN(5230, 48),
-};
-#undef CHAN
-
-#define AR9170_HT_CAP							\
-{									\
-	.ht_supported	= true,						\
-	.cap		= IEEE80211_HT_CAP_MAX_AMSDU |			\
-			  IEEE80211_HT_CAP_SUP_WIDTH_20_40 |		\
-			  IEEE80211_HT_CAP_SGI_40 |			\
-			  IEEE80211_HT_CAP_GRN_FLD |			\
-			  IEEE80211_HT_CAP_DSSSCCK40 |			\
-			  IEEE80211_HT_CAP_SM_PS,			\
-	.ampdu_factor	= 3,						\
-	.ampdu_density	= 6,						\
-	.mcs		= {						\
-		.rx_mask = { 0xff, 0xff, 0, 0, 0x1, 0, 0, 0, 0, 0, },	\
-		.rx_highest = cpu_to_le16(300),				\
-		.tx_params = IEEE80211_HT_MCS_TX_DEFINED,		\
-	},								\
-}
-
-static struct ieee80211_supported_band ar9170_band_2GHz = {
-	.channels	= ar9170_2ghz_chantable,
-	.n_channels	= ARRAY_SIZE(ar9170_2ghz_chantable),
-	.bitrates	= ar9170_g_ratetable,
-	.n_bitrates	= ar9170_g_ratetable_size,
-	.ht_cap		= AR9170_HT_CAP,
-};
-
-static struct ieee80211_supported_band ar9170_band_5GHz = {
-	.channels	= ar9170_5ghz_chantable,
-	.n_channels	= ARRAY_SIZE(ar9170_5ghz_chantable),
-	.bitrates	= ar9170_a_ratetable,
-	.n_bitrates	= ar9170_a_ratetable_size,
-	.ht_cap		= AR9170_HT_CAP,
-};
-
-static void ar9170_tx(struct ar9170 *ar);
-
-static inline u16 ar9170_get_seq_h(struct ieee80211_hdr *hdr)
-{
-	return le16_to_cpu(hdr->seq_ctrl) >> 4;
-}
-
-static inline u16 ar9170_get_seq(struct sk_buff *skb)
-{
-	struct ar9170_tx_control *txc = (void *) skb->data;
-	return ar9170_get_seq_h((void *) txc->frame_data);
-}
-
-#ifdef AR9170_QUEUE_DEBUG
-static void ar9170_print_txheader(struct ar9170 *ar, struct sk_buff *skb)
-{
-	struct ar9170_tx_control *txc = (void *) skb->data;
-	struct ieee80211_tx_info *txinfo = IEEE80211_SKB_CB(skb);
-	struct ar9170_tx_info *arinfo = (void *) txinfo->rate_driver_data;
-	struct ieee80211_hdr *hdr = (void *) txc->frame_data;
-
-	wiphy_debug(ar->hw->wiphy,
-		    "=> FRAME [skb:%p, q:%d, DA:[%pM] s:%d "
-		    "mac_ctrl:%04x, phy_ctrl:%08x, timeout:[%d ms]]\n",
-		    skb, skb_get_queue_mapping(skb),
-		    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));
-}
-
-static void __ar9170_dump_txqueue(struct ar9170 *ar,
-				struct sk_buff_head *queue)
-{
-	struct sk_buff *skb;
-	int i = 0;
-
-	printk(KERN_DEBUG "---[ cut here ]---\n");
-	wiphy_debug(ar->hw->wiphy, "%d entries in queue.\n",
-		    skb_queue_len(queue));
-
-	skb_queue_walk(queue, skb) {
-		printk(KERN_DEBUG "index:%d =>\n", i++);
-		ar9170_print_txheader(ar, skb);
-	}
-	if (i != skb_queue_len(queue))
-		printk(KERN_DEBUG "WARNING: queue frame counter "
-		       "mismatch %d != %d\n", skb_queue_len(queue), i);
-	printk(KERN_DEBUG "---[ end ]---\n");
-}
-#endif /* AR9170_QUEUE_DEBUG */
-
-#ifdef AR9170_QUEUE_DEBUG
-static void ar9170_dump_txqueue(struct ar9170 *ar,
-				struct sk_buff_head *queue)
-{
-	unsigned long flags;
-
-	spin_lock_irqsave(&queue->lock, flags);
-	__ar9170_dump_txqueue(ar, queue);
-	spin_unlock_irqrestore(&queue->lock, flags);
-}
-#endif /* AR9170_QUEUE_DEBUG */
-
-#ifdef AR9170_QUEUE_STOP_DEBUG
-static void __ar9170_dump_txstats(struct ar9170 *ar)
-{
-	int i;
-
-	wiphy_debug(ar->hw->wiphy, "QoS queue stats\n");
-
-	for (i = 0; i < __AR9170_NUM_TXQ; i++)
-		wiphy_debug(ar->hw->wiphy,
-			    "queue:%d limit:%d len:%d waitack:%d stopped:%d\n",
-			    i, ar->tx_stats[i].limit, ar->tx_stats[i].len,
-			    skb_queue_len(&ar->tx_status[i]),
-			    ieee80211_queue_stopped(ar->hw, i));
-}
-#endif /* AR9170_QUEUE_STOP_DEBUG */
-
-/* caller must guarantee exclusive access for _bin_ queue. */
-static void ar9170_recycle_expired(struct ar9170 *ar,
-				   struct sk_buff_head *queue,
-				   struct sk_buff_head *bin)
-{
-	struct sk_buff *skb, *old = NULL;
-	unsigned long flags;
-
-	spin_lock_irqsave(&queue->lock, flags);
-	while ((skb = skb_peek(queue))) {
-		struct ieee80211_tx_info *txinfo;
-		struct ar9170_tx_info *arinfo;
-
-		txinfo = IEEE80211_SKB_CB(skb);
-		arinfo = (void *) txinfo->rate_driver_data;
-
-		if (time_is_before_jiffies(arinfo->timeout)) {
-#ifdef AR9170_QUEUE_DEBUG
-			wiphy_debug(ar->hw->wiphy,
-				    "[%ld > %ld] frame expired => recycle\n",
-				    jiffies, arinfo->timeout);
-			ar9170_print_txheader(ar, skb);
-#endif /* AR9170_QUEUE_DEBUG */
-			__skb_unlink(skb, queue);
-			__skb_queue_tail(bin, skb);
-		} else {
-			break;
-		}
-
-		if (unlikely(old == skb)) {
-			/* bail out - queue is shot. */
-
-			WARN_ON(1);
-			break;
-		}
-		old = skb;
-	}
-	spin_unlock_irqrestore(&queue->lock, flags);
-}
-
-static void ar9170_tx_status(struct ar9170 *ar, struct sk_buff *skb,
-				    u16 tx_status)
-{
-	struct ieee80211_tx_info *txinfo;
-	unsigned int retries = 0;
-
-	txinfo = IEEE80211_SKB_CB(skb);
-	ieee80211_tx_info_clear_status(txinfo);
-
-	switch (tx_status) {
-	case AR9170_TX_STATUS_RETRY:
-		retries = 2;
-	case AR9170_TX_STATUS_COMPLETE:
-		txinfo->flags |= IEEE80211_TX_STAT_ACK;
-		break;
-
-	case AR9170_TX_STATUS_FAILED:
-		retries = ar->hw->conf.long_frame_max_tx_count;
-		break;
-
-	default:
-		wiphy_err(ar->hw->wiphy,
-			  "invalid tx_status response (%x)\n", tx_status);
-		break;
-	}
-
-	txinfo->status.rates[0].count = retries + 1;
-	skb_pull(skb, sizeof(struct ar9170_tx_control));
-	ieee80211_tx_status_irqsafe(ar->hw, skb);
-}
-
-void ar9170_tx_callback(struct ar9170 *ar, struct sk_buff *skb)
-{
-	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
-	struct ar9170_tx_info *arinfo = (void *) info->rate_driver_data;
-	unsigned int queue = skb_get_queue_mapping(skb);
-	unsigned long flags;
-
-	spin_lock_irqsave(&ar->tx_stats_lock, flags);
-	ar->tx_stats[queue].len--;
-
-	if (ar->tx_stats[queue].len < AR9170_NUM_TX_LIMIT_SOFT) {
-#ifdef AR9170_QUEUE_STOP_DEBUG
-		wiphy_debug(ar->hw->wiphy, "wake queue %d\n", queue);
-		__ar9170_dump_txstats(ar);
-#endif /* AR9170_QUEUE_STOP_DEBUG */
-		ieee80211_wake_queue(ar->hw, queue);
-	}
-	spin_unlock_irqrestore(&ar->tx_stats_lock, flags);
-
-	if (info->flags & IEEE80211_TX_CTL_NO_ACK) {
-		ar9170_tx_status(ar, skb, AR9170_TX_STATUS_FAILED);
-	} else {
-		arinfo->timeout = jiffies +
-			  msecs_to_jiffies(AR9170_TX_TIMEOUT);
-
-		skb_queue_tail(&ar->tx_status[queue], skb);
-	}
-
-	if (!ar->tx_stats[queue].len &&
-	    !skb_queue_empty(&ar->tx_pending[queue])) {
-		ar9170_tx(ar);
-	}
-}
-
-static struct sk_buff *ar9170_get_queued_skb(struct ar9170 *ar,
-					     const u8 *mac,
-					     struct sk_buff_head *queue,
-					     const u32 rate)
-{
-	unsigned long flags;
-	struct sk_buff *skb;
-
-	/*
-	 * Unfortunately, the firmware does not tell to which (queued) frame
-	 * this transmission status report belongs to.
-	 *
-	 * So we have to make risky guesses - with the scarce information
-	 * the firmware provided (-> destination MAC, and phy_control) -
-	 * and hope that we picked the right one...
-	 */
-
-	spin_lock_irqsave(&queue->lock, flags);
-	skb_queue_walk(queue, skb) {
-		struct ar9170_tx_control *txc = (void *) skb->data;
-		struct ieee80211_hdr *hdr = (void *) txc->frame_data;
-		u32 r;
-
-		if (mac && compare_ether_addr(ieee80211_get_DA(hdr), mac)) {
-#ifdef AR9170_QUEUE_DEBUG
-			wiphy_debug(ar->hw->wiphy,
-				    "skip frame => DA %pM != %pM\n",
-				    mac, ieee80211_get_DA(hdr));
-			ar9170_print_txheader(ar, skb);
-#endif /* AR9170_QUEUE_DEBUG */
-			continue;
-		}
-
-		r = (le32_to_cpu(txc->phy_control) & AR9170_TX_PHY_MCS_MASK) >>
-		    AR9170_TX_PHY_MCS_SHIFT;
-
-		if ((rate != AR9170_TX_INVALID_RATE) && (r != rate)) {
-#ifdef AR9170_QUEUE_DEBUG
-			wiphy_debug(ar->hw->wiphy,
-				    "skip frame => rate %d != %d\n", rate, r);
-			ar9170_print_txheader(ar, skb);
-#endif /* AR9170_QUEUE_DEBUG */
-			continue;
-		}
-
-		__skb_unlink(skb, queue);
-		spin_unlock_irqrestore(&queue->lock, flags);
-		return skb;
-	}
-
-#ifdef AR9170_QUEUE_DEBUG
-	wiphy_err(ar->hw->wiphy,
-		  "ESS:[%pM] does not have any outstanding frames in queue.\n",
-		  mac);
-	__ar9170_dump_txqueue(ar, queue);
-#endif /* AR9170_QUEUE_DEBUG */
-	spin_unlock_irqrestore(&queue->lock, flags);
-
-	return NULL;
-}
-
-/*
- * This worker tries to keeps an maintain tx_status queues.
- * So we can guarantee that incoming tx_status reports are
- * actually for a pending frame.
- */
-
-static void ar9170_tx_janitor(struct work_struct *work)
-{
-	struct ar9170 *ar = container_of(work, struct ar9170,
-					 tx_janitor.work);
-	struct sk_buff_head waste;
-	unsigned int i;
-	bool resched = false;
-
-	if (unlikely(!IS_STARTED(ar)))
-		return ;
-
-	skb_queue_head_init(&waste);
-
-	for (i = 0; i < __AR9170_NUM_TXQ; i++) {
-#ifdef AR9170_QUEUE_DEBUG
-		wiphy_debug(ar->hw->wiphy, "garbage collector scans queue:%d\n",
-			    i);
-		ar9170_dump_txqueue(ar, &ar->tx_pending[i]);
-		ar9170_dump_txqueue(ar, &ar->tx_status[i]);
-#endif /* AR9170_QUEUE_DEBUG */
-
-		ar9170_recycle_expired(ar, &ar->tx_status[i], &waste);
-		ar9170_recycle_expired(ar, &ar->tx_pending[i], &waste);
-		skb_queue_purge(&waste);
-
-		if (!skb_queue_empty(&ar->tx_status[i]) ||
-		    !skb_queue_empty(&ar->tx_pending[i]))
-			resched = true;
-	}
-
-	if (!resched)
-		return;
-
-	ieee80211_queue_delayed_work(ar->hw,
-				     &ar->tx_janitor,
-				     msecs_to_jiffies(AR9170_JANITOR_DELAY));
-}
-
-void ar9170_handle_command_response(struct ar9170 *ar, void *buf, u32 len)
-{
-	struct ar9170_cmd_response *cmd = (void *) buf;
-
-	if ((cmd->type & 0xc0) != 0xc0) {
-		ar->callback_cmd(ar, len, buf);
-		return;
-	}
-
-	/* hardware event handlers */
-	switch (cmd->type) {
-	case 0xc1: {
-		/*
-		 * TX status notification:
-		 * bytes: 0c c1 XX YY M1 M2 M3 M4 M5 M6 R4 R3 R2 R1 S2 S1
-		 *
-		 * XX always 81
-		 * YY always 00
-		 * M1-M6 is the MAC address
-		 * R1-R4 is the transmit rate
-		 * S1-S2 is the transmit status
-		 */
-
-		struct sk_buff *skb;
-		u32 phy = le32_to_cpu(cmd->tx_status.rate);
-		u32 q = (phy & AR9170_TX_PHY_QOS_MASK) >>
-			AR9170_TX_PHY_QOS_SHIFT;
-#ifdef AR9170_QUEUE_DEBUG
-		wiphy_debug(ar->hw->wiphy,
-			    "recv tx_status for %pm, p:%08x, q:%d\n",
-			    cmd->tx_status.dst, phy, q);
-#endif /* AR9170_QUEUE_DEBUG */
-
-		skb = ar9170_get_queued_skb(ar, cmd->tx_status.dst,
-					    &ar->tx_status[q],
-					    AR9170_TX_INVALID_RATE);
-		if (unlikely(!skb))
-			return ;
-
-		ar9170_tx_status(ar, skb, le16_to_cpu(cmd->tx_status.status));
-		break;
-		}
-
-	case 0xc0:
-		/*
-		 * pre-TBTT event
-		 */
-		if (ar->vif && ar->vif->type == NL80211_IFTYPE_AP)
-			ieee80211_queue_work(ar->hw, &ar->beacon_work);
-		break;
-
-	case 0xc2:
-		/*
-		 * (IBSS) beacon send notification
-		 * bytes: 04 c2 XX YY B4 B3 B2 B1
-		 *
-		 * XX always 80
-		 * YY always 00
-		 * B1-B4 "should" be the number of send out beacons.
-		 */
-		break;
-
-	case 0xc3:
-		/* End of Atim Window */
-		break;
-
-	case 0xc4:
-		/* BlockACK bitmap */
-		break;
-
-	case 0xc5:
-		/* BlockACK events */
-		break;
-
-	case 0xc6:
-		/* Watchdog Interrupt */
-		break;
-
-	case 0xc9:
-		/* retransmission issue / SIFS/EIFS collision ?! */
-		break;
-
-	/* firmware debug */
-	case 0xca:
-		printk(KERN_DEBUG "ar9170 FW: %.*s\n", len - 4,
-				(char *)buf + 4);
-		break;
-	case 0xcb:
-		len -= 4;
-
-		switch (len) {
-		case 1:
-			printk(KERN_DEBUG "ar9170 FW: u8: %#.2x\n",
-				*((char *)buf + 4));
-			break;
-		case 2:
-			printk(KERN_DEBUG "ar9170 FW: u8: %#.4x\n",
-				le16_to_cpup((__le16 *)((char *)buf + 4)));
-			break;
-		case 4:
-			printk(KERN_DEBUG "ar9170 FW: u8: %#.8x\n",
-				le32_to_cpup((__le32 *)((char *)buf + 4)));
-			break;
-		case 8:
-			printk(KERN_DEBUG "ar9170 FW: u8: %#.16lx\n",
-				(unsigned long)le64_to_cpup(
-						(__le64 *)((char *)buf + 4)));
-			break;
-		}
-		break;
-	case 0xcc:
-		print_hex_dump_bytes("ar9170 FW:", DUMP_PREFIX_NONE,
-				     (char *)buf + 4, len - 4);
-		break;
-
-	default:
-		pr_info("received unhandled event %x\n", cmd->type);
-		print_hex_dump_bytes("dump:", DUMP_PREFIX_NONE, buf, len);
-		break;
-	}
-}
-
-static void ar9170_rx_reset_rx_mpdu(struct ar9170 *ar)
-{
-	memset(&ar->rx_mpdu.plcp, 0, sizeof(struct ar9170_rx_head));
-	ar->rx_mpdu.has_plcp = false;
-}
-
-int ar9170_nag_limiter(struct ar9170 *ar)
-{
-	bool print_message;
-
-	/*
-	 * we expect all sorts of errors in promiscuous mode.
-	 * don't bother with it, it's OK!
-	 */
-	if (ar->sniffer_enabled)
-		return false;
-
-	/*
-	 * only go for frequent errors! The hardware tends to
-	 * do some stupid thing once in a while under load, in
-	 * noisy environments or just for fun!
-	 */
-	if (time_before(jiffies, ar->bad_hw_nagger) && net_ratelimit())
-		print_message = true;
-	else
-		print_message = false;
-
-	/* reset threshold for "once in a while" */
-	ar->bad_hw_nagger = jiffies + HZ / 4;
-	return print_message;
-}
-
-static int ar9170_rx_mac_status(struct ar9170 *ar,
-				struct ar9170_rx_head *head,
-				struct ar9170_rx_macstatus *mac,
-				struct ieee80211_rx_status *status)
-{
-	u8 error, decrypt;
-
-	BUILD_BUG_ON(sizeof(struct ar9170_rx_head) != 12);
-	BUILD_BUG_ON(sizeof(struct ar9170_rx_macstatus) != 4);
-
-	error = mac->error;
-	if (error & AR9170_RX_ERROR_MMIC) {
-		status->flag |= RX_FLAG_MMIC_ERROR;
-		error &= ~AR9170_RX_ERROR_MMIC;
-	}
-
-	if (error & AR9170_RX_ERROR_PLCP) {
-		status->flag |= RX_FLAG_FAILED_PLCP_CRC;
-		error &= ~AR9170_RX_ERROR_PLCP;
-
-		if (!(ar->filter_state & FIF_PLCPFAIL))
-			return -EINVAL;
-	}
-
-	if (error & AR9170_RX_ERROR_FCS) {
-		status->flag |= RX_FLAG_FAILED_FCS_CRC;
-		error &= ~AR9170_RX_ERROR_FCS;
-
-		if (!(ar->filter_state & FIF_FCSFAIL))
-			return -EINVAL;
-	}
-
-	decrypt = ar9170_get_decrypt_type(mac);
-	if (!(decrypt & AR9170_RX_ENC_SOFTWARE) &&
-	    decrypt != AR9170_ENC_ALG_NONE)
-		status->flag |= RX_FLAG_DECRYPTED;
-
-	/* ignore wrong RA errors */
-	error &= ~AR9170_RX_ERROR_WRONG_RA;
-
-	if (error & AR9170_RX_ERROR_DECRYPT) {
-		error &= ~AR9170_RX_ERROR_DECRYPT;
-		/*
-		 * Rx decryption is done in place,
-		 * the original data is lost anyway.
-		 */
-
-		return -EINVAL;
-	}
-
-	/* drop any other error frames */
-	if (unlikely(error)) {
-		/* TODO: update netdevice's RX dropped/errors statistics */
-
-		if (ar9170_nag_limiter(ar))
-			wiphy_debug(ar->hw->wiphy,
-				    "received frame with suspicious error code (%#x).\n",
-				    error);
-
-		return -EINVAL;
-	}
-
-	status->band = ar->channel->band;
-	status->freq = ar->channel->center_freq;
-
-	switch (mac->status & AR9170_RX_STATUS_MODULATION_MASK) {
-	case AR9170_RX_STATUS_MODULATION_CCK:
-		if (mac->status & AR9170_RX_STATUS_SHORT_PREAMBLE)
-			status->flag |= RX_FLAG_SHORTPRE;
-		switch (head->plcp[0]) {
-		case 0x0a:
-			status->rate_idx = 0;
-			break;
-		case 0x14:
-			status->rate_idx = 1;
-			break;
-		case 0x37:
-			status->rate_idx = 2;
-			break;
-		case 0x6e:
-			status->rate_idx = 3;
-			break;
-		default:
-			if (ar9170_nag_limiter(ar))
-				wiphy_err(ar->hw->wiphy,
-					  "invalid plcp cck rate (%x).\n",
-					  head->plcp[0]);
-			return -EINVAL;
-		}
-		break;
-
-	case AR9170_RX_STATUS_MODULATION_DUPOFDM:
-	case AR9170_RX_STATUS_MODULATION_OFDM:
-		switch (head->plcp[0] & 0xf) {
-		case 0xb:
-			status->rate_idx = 0;
-			break;
-		case 0xf:
-			status->rate_idx = 1;
-			break;
-		case 0xa:
-			status->rate_idx = 2;
-			break;
-		case 0xe:
-			status->rate_idx = 3;
-			break;
-		case 0x9:
-			status->rate_idx = 4;
-			break;
-		case 0xd:
-			status->rate_idx = 5;
-			break;
-		case 0x8:
-			status->rate_idx = 6;
-			break;
-		case 0xc:
-			status->rate_idx = 7;
-			break;
-		default:
-			if (ar9170_nag_limiter(ar))
-				wiphy_err(ar->hw->wiphy,
-					  "invalid plcp ofdm rate (%x).\n",
-					  head->plcp[0]);
-			return -EINVAL;
-		}
-		if (status->band == IEEE80211_BAND_2GHZ)
-			status->rate_idx += 4;
-		break;
-
-	case AR9170_RX_STATUS_MODULATION_HT:
-		if (head->plcp[3] & 0x80)
-			status->flag |= RX_FLAG_40MHZ;
-		if (head->plcp[6] & 0x80)
-			status->flag |= RX_FLAG_SHORT_GI;
-
-		status->rate_idx = clamp(0, 75, head->plcp[6] & 0x7f);
-		status->flag |= RX_FLAG_HT;
-		break;
-
-	default:
-		if (ar9170_nag_limiter(ar))
-			wiphy_err(ar->hw->wiphy, "invalid modulation\n");
-		return -EINVAL;
-	}
-
-	return 0;
-}
-
-static void ar9170_rx_phy_status(struct ar9170 *ar,
-				 struct ar9170_rx_phystatus *phy,
-				 struct ieee80211_rx_status *status)
-{
-	int i;
-
-	BUILD_BUG_ON(sizeof(struct ar9170_rx_phystatus) != 20);
-
-	for (i = 0; i < 3; i++)
-		if (phy->rssi[i] != 0x80)
-			status->antenna |= BIT(i);
-
-	/* post-process RSSI */
-	for (i = 0; i < 7; i++)
-		if (phy->rssi[i] & 0x80)
-			phy->rssi[i] = ((phy->rssi[i] & 0x7f) + 1) & 0x7f;
-
-	/* TODO: we could do something with phy_errors */
-	status->signal = ar->noise[0] + phy->rssi_combined;
-}
-
-static struct sk_buff *ar9170_rx_copy_data(u8 *buf, int len)
-{
-	struct sk_buff *skb;
-	int reserved = 0;
-	struct ieee80211_hdr *hdr = (void *) buf;
-
-	if (ieee80211_is_data_qos(hdr->frame_control)) {
-		u8 *qc = ieee80211_get_qos_ctl(hdr);
-		reserved += NET_IP_ALIGN;
-
-		if (*qc & IEEE80211_QOS_CONTROL_A_MSDU_PRESENT)
-			reserved += NET_IP_ALIGN;
-	}
-
-	if (ieee80211_has_a4(hdr->frame_control))
-		reserved += NET_IP_ALIGN;
-
-	reserved = 32 + (reserved & NET_IP_ALIGN);
-
-	skb = dev_alloc_skb(len + reserved);
-	if (likely(skb)) {
-		skb_reserve(skb, reserved);
-		memcpy(skb_put(skb, len), buf, len);
-	}
-
-	return skb;
-}
-
-/*
- * If the frame alignment is right (or the kernel has
- * CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS), and there
- * is only a single MPDU in the USB frame, then we could
- * submit to mac80211 the SKB directly. However, since
- * there may be multiple packets in one SKB in stream
- * mode, and we need to observe the proper ordering,
- * this is non-trivial.
- */
-
-static void ar9170_handle_mpdu(struct ar9170 *ar, u8 *buf, int len)
-{
-	struct ar9170_rx_head *head;
-	struct ar9170_rx_macstatus *mac;
-	struct ar9170_rx_phystatus *phy = NULL;
-	struct ieee80211_rx_status status;
-	struct sk_buff *skb;
-	int mpdu_len;
-
-	if (unlikely(!IS_STARTED(ar) || len < (sizeof(*mac))))
-		return ;
-
-	/* Received MPDU */
-	mpdu_len = len - sizeof(*mac);
-
-	mac = (void *)(buf + mpdu_len);
-	if (unlikely(mac->error & AR9170_RX_ERROR_FATAL)) {
-		/* this frame is too damaged and can't be used - drop it */
-
-		return ;
-	}
-
-	switch (mac->status & AR9170_RX_STATUS_MPDU_MASK) {
-	case AR9170_RX_STATUS_MPDU_FIRST:
-		/* first mpdu packet has the plcp header */
-		if (likely(mpdu_len >= sizeof(struct ar9170_rx_head))) {
-			head = (void *) buf;
-			memcpy(&ar->rx_mpdu.plcp, (void *) buf,
-			       sizeof(struct ar9170_rx_head));
-
-			mpdu_len -= sizeof(struct ar9170_rx_head);
-			buf += sizeof(struct ar9170_rx_head);
-			ar->rx_mpdu.has_plcp = true;
-		} else {
-			if (ar9170_nag_limiter(ar))
-				wiphy_err(ar->hw->wiphy,
-					  "plcp info is clipped.\n");
-			return ;
-		}
-		break;
-
-	case AR9170_RX_STATUS_MPDU_LAST:
-		/* last mpdu has a extra tail with phy status information */
-
-		if (likely(mpdu_len >= sizeof(struct ar9170_rx_phystatus))) {
-			mpdu_len -= sizeof(struct ar9170_rx_phystatus);
-			phy = (void *)(buf + mpdu_len);
-		} else {
-			if (ar9170_nag_limiter(ar))
-				wiphy_err(ar->hw->wiphy,
-					  "frame tail is clipped.\n");
-			return ;
-		}
-
-	case AR9170_RX_STATUS_MPDU_MIDDLE:
-		/* middle mpdus are just data */
-		if (unlikely(!ar->rx_mpdu.has_plcp)) {
-			if (!ar9170_nag_limiter(ar))
-				return ;
-
-			wiphy_err(ar->hw->wiphy,
-				  "rx stream did not start with a first_mpdu frame tag.\n");
-
-			return ;
-		}
-
-		head = &ar->rx_mpdu.plcp;
-		break;
-
-	case AR9170_RX_STATUS_MPDU_SINGLE:
-		/* single mpdu - has plcp (head) and phy status (tail) */
-		head = (void *) buf;
-
-		mpdu_len -= sizeof(struct ar9170_rx_head);
-		mpdu_len -= sizeof(struct ar9170_rx_phystatus);
-
-		buf += sizeof(struct ar9170_rx_head);
-		phy = (void *)(buf + mpdu_len);
-		break;
-
-	default:
-		BUG_ON(1);
-		break;
-	}
-
-	if (unlikely(mpdu_len < FCS_LEN))
-		return ;
-
-	memset(&status, 0, sizeof(status));
-	if (unlikely(ar9170_rx_mac_status(ar, head, mac, &status)))
-		return ;
-
-	if (phy)
-		ar9170_rx_phy_status(ar, phy, &status);
-
-	skb = ar9170_rx_copy_data(buf, mpdu_len);
-	if (likely(skb)) {
-		memcpy(IEEE80211_SKB_RXCB(skb), &status, sizeof(status));
-		ieee80211_rx_irqsafe(ar->hw, skb);
-	}
-}
-
-void ar9170_rx(struct ar9170 *ar, struct sk_buff *skb)
-{
-	unsigned int i, tlen, resplen, wlen = 0, clen = 0;
-	u8 *tbuf, *respbuf;
-
-	tbuf = skb->data;
-	tlen = skb->len;
-
-	while (tlen >= 4) {
-		clen = tbuf[1] << 8 | tbuf[0];
-		wlen = ALIGN(clen, 4);
-
-		/* check if this is stream has a valid tag.*/
-		if (tbuf[2] != 0 || tbuf[3] != 0x4e) {
-			/*
-			 * TODO: handle the highly unlikely event that the
-			 * corrupted stream has the TAG at the right position.
-			 */
-
-			/* check if the frame can be repaired. */
-			if (!ar->rx_failover_missing) {
-				/* this is no "short read". */
-				if (ar9170_nag_limiter(ar)) {
-					wiphy_err(ar->hw->wiphy,
-						  "missing tag!\n");
-					goto err_telluser;
-				} else
-					goto err_silent;
-			}
-
-			if (ar->rx_failover_missing > tlen) {
-				if (ar9170_nag_limiter(ar)) {
-					wiphy_err(ar->hw->wiphy,
-						  "possible multi stream corruption!\n");
-					goto err_telluser;
-				} else
-					goto err_silent;
-			}
-
-			memcpy(skb_put(ar->rx_failover, tlen), tbuf, tlen);
-			ar->rx_failover_missing -= tlen;
-
-			if (ar->rx_failover_missing <= 0) {
-				/*
-				 * nested ar9170_rx call!
-				 * termination is guaranteed, even when the
-				 * combined frame also have a element with
-				 * a bad tag.
-				 */
-
-				ar->rx_failover_missing = 0;
-				ar9170_rx(ar, ar->rx_failover);
-
-				skb_reset_tail_pointer(ar->rx_failover);
-				skb_trim(ar->rx_failover, 0);
-			}
-
-			return ;
-		}
-
-		/* check if stream is clipped */
-		if (wlen > tlen - 4) {
-			if (ar->rx_failover_missing) {
-				/* TODO: handle double stream corruption. */
-				if (ar9170_nag_limiter(ar)) {
-					wiphy_err(ar->hw->wiphy,
-						  "double rx stream corruption!\n");
-					goto err_telluser;
-				} else
-					goto err_silent;
-			}
-
-			/*
-			 * save incomplete data set.
-			 * the firmware will resend the missing bits when
-			 * the rx - descriptor comes round again.
-			 */
-
-			memcpy(skb_put(ar->rx_failover, tlen), tbuf, tlen);
-			ar->rx_failover_missing = clen - tlen;
-			return ;
-		}
-		resplen = clen;
-		respbuf = tbuf + 4;
-		tbuf += wlen + 4;
-		tlen -= wlen + 4;
-
-		i = 0;
-
-		/* weird thing, but this is the same in the original driver */
-		while (resplen > 2 && i < 12 &&
-		       respbuf[0] == 0xff && respbuf[1] == 0xff) {
-			i += 2;
-			resplen -= 2;
-			respbuf += 2;
-		}
-
-		if (resplen < 4)
-			continue;
-
-		/* found the 6 * 0xffff marker? */
-		if (i == 12)
-			ar9170_handle_command_response(ar, respbuf, resplen);
-		else
-			ar9170_handle_mpdu(ar, respbuf, clen);
-	}
-
-	if (tlen) {
-		if (net_ratelimit())
-			wiphy_err(ar->hw->wiphy,
-				  "%d bytes of unprocessed data left in rx stream!\n",
-				  tlen);
-
-		goto err_telluser;
-	}
-
-	return ;
-
-err_telluser:
-	wiphy_err(ar->hw->wiphy,
-		  "damaged RX stream data [want:%d, data:%d, rx:%d, pending:%d ]\n",
-		  clen, wlen, tlen, ar->rx_failover_missing);
-
-	if (ar->rx_failover_missing)
-		print_hex_dump_bytes("rxbuf:", DUMP_PREFIX_OFFSET,
-				     ar->rx_failover->data,
-				     ar->rx_failover->len);
-
-	print_hex_dump_bytes("stream:", DUMP_PREFIX_OFFSET,
-			     skb->data, skb->len);
-
-	wiphy_err(ar->hw->wiphy,
-		  "If you see this message frequently, please check your hardware and cables.\n");
-
-err_silent:
-	if (ar->rx_failover_missing) {
-		skb_reset_tail_pointer(ar->rx_failover);
-		skb_trim(ar->rx_failover, 0);
-		ar->rx_failover_missing = 0;
-	}
-}
-
-#define AR9170_FILL_QUEUE(queue, ai_fs, cwmin, cwmax, _txop)		\
-do {									\
-	queue.aifs = ai_fs;						\
-	queue.cw_min = cwmin;						\
-	queue.cw_max = cwmax;						\
-	queue.txop = _txop;						\
-} while (0)
-
-static int ar9170_op_start(struct ieee80211_hw *hw)
-{
-	struct ar9170 *ar = hw->priv;
-	int err, i;
-
-	mutex_lock(&ar->mutex);
-
-	/* reinitialize queues statistics */
-	memset(&ar->tx_stats, 0, sizeof(ar->tx_stats));
-	for (i = 0; i < __AR9170_NUM_TXQ; i++)
-		ar->tx_stats[i].limit = AR9170_TXQ_DEPTH;
-
-	/* reset QoS defaults */
-	AR9170_FILL_QUEUE(ar->edcf[0], 3, 15, 1023,  0); /* BEST EFFORT*/
-	AR9170_FILL_QUEUE(ar->edcf[1], 7, 15, 1023,  0); /* BACKGROUND */
-	AR9170_FILL_QUEUE(ar->edcf[2], 2, 7,    15, 94); /* VIDEO */
-	AR9170_FILL_QUEUE(ar->edcf[3], 2, 3,     7, 47); /* VOICE */
-	AR9170_FILL_QUEUE(ar->edcf[4], 2, 3,     7,  0); /* SPECIAL */
-
-	/* set sane AMPDU defaults */
-	ar->global_ampdu_density = 6;
-	ar->global_ampdu_factor = 3;
-
-	ar->bad_hw_nagger = jiffies;
-
-	err = ar->open(ar);
-	if (err)
-		goto out;
-
-	err = ar9170_init_mac(ar);
-	if (err)
-		goto out;
-
-	err = ar9170_set_qos(ar);
-	if (err)
-		goto out;
-
-	err = ar9170_init_phy(ar, IEEE80211_BAND_2GHZ);
-	if (err)
-		goto out;
-
-	err = ar9170_init_rf(ar);
-	if (err)
-		goto out;
-
-	/* start DMA */
-	err = ar9170_write_reg(ar, 0x1c3d30, 0x100);
-	if (err)
-		goto out;
-
-	ar->state = AR9170_STARTED;
-
-out:
-	mutex_unlock(&ar->mutex);
-	return err;
-}
-
-static void ar9170_op_stop(struct ieee80211_hw *hw)
-{
-	struct ar9170 *ar = hw->priv;
-	unsigned int i;
-
-	if (IS_STARTED(ar))
-		ar->state = AR9170_IDLE;
-
-	cancel_delayed_work_sync(&ar->tx_janitor);
-#ifdef CONFIG_AR9170_LEDS
-	cancel_delayed_work_sync(&ar->led_work);
-#endif
-	cancel_work_sync(&ar->beacon_work);
-
-	mutex_lock(&ar->mutex);
-
-	if (IS_ACCEPTING_CMD(ar)) {
-		ar9170_set_leds_state(ar, 0);
-
-		/* stop DMA */
-		ar9170_write_reg(ar, 0x1c3d30, 0);
-		ar->stop(ar);
-	}
-
-	for (i = 0; i < __AR9170_NUM_TXQ; i++) {
-		skb_queue_purge(&ar->tx_pending[i]);
-		skb_queue_purge(&ar->tx_status[i]);
-	}
-
-	mutex_unlock(&ar->mutex);
-}
-
-static int ar9170_tx_prepare(struct ar9170 *ar, struct sk_buff *skb)
-{
-	struct ieee80211_hdr *hdr;
-	struct ar9170_tx_control *txc;
-	struct ieee80211_tx_info *info;
-	struct ieee80211_tx_rate *txrate;
-	struct ar9170_tx_info *arinfo;
-	unsigned int queue = skb_get_queue_mapping(skb);
-	u16 keytype = 0;
-	u16 len, icv = 0;
-
-	BUILD_BUG_ON(sizeof(*arinfo) > sizeof(info->rate_driver_data));
-
-	hdr = (void *)skb->data;
-	info = IEEE80211_SKB_CB(skb);
-	len = skb->len;
-
-	txc = (void *)skb_push(skb, sizeof(*txc));
-
-	if (info->control.hw_key) {
-		icv = info->control.hw_key->icv_len;
-
-		switch (info->control.hw_key->cipher) {
-		case WLAN_CIPHER_SUITE_WEP40:
-		case WLAN_CIPHER_SUITE_WEP104:
-		case WLAN_CIPHER_SUITE_TKIP:
-			keytype = AR9170_TX_MAC_ENCR_RC4;
-			break;
-		case WLAN_CIPHER_SUITE_CCMP:
-			keytype = AR9170_TX_MAC_ENCR_AES;
-			break;
-		default:
-			WARN_ON(1);
-			goto err_out;
-		}
-	}
-
-	/* Length */
-	txc->length = cpu_to_le16(len + icv + 4);
-
-	txc->mac_control = cpu_to_le16(AR9170_TX_MAC_HW_DURATION |
-				       AR9170_TX_MAC_BACKOFF);
-	txc->mac_control |= cpu_to_le16(ar9170_qos_hwmap[queue] <<
-					AR9170_TX_MAC_QOS_SHIFT);
-	txc->mac_control |= cpu_to_le16(keytype);
-	txc->phy_control = cpu_to_le32(0);
-
-	if (info->flags & IEEE80211_TX_CTL_NO_ACK)
-		txc->mac_control |= cpu_to_le16(AR9170_TX_MAC_NO_ACK);
-
-	txrate = &info->control.rates[0];
-	if (txrate->flags & IEEE80211_TX_RC_USE_CTS_PROTECT)
-		txc->mac_control |= cpu_to_le16(AR9170_TX_MAC_PROT_CTS);
-	else if (txrate->flags & IEEE80211_TX_RC_USE_RTS_CTS)
-		txc->mac_control |= cpu_to_le16(AR9170_TX_MAC_PROT_RTS);
-
-	arinfo = (void *)info->rate_driver_data;
-	arinfo->timeout = jiffies + msecs_to_jiffies(AR9170_QUEUE_TIMEOUT);
-
-	if (!(info->flags & IEEE80211_TX_CTL_NO_ACK) &&
-	     (is_valid_ether_addr(ieee80211_get_DA(hdr)))) {
-		/*
-		 * WARNING:
-		 * Putting the QoS queue bits into an unexplored territory is
-		 * certainly not elegant.
-		 *
-		 * In my defense: This idea provides a reasonable way to
-		 * smuggle valuable information to the tx_status callback.
-		 * Also, the idea behind this bit-abuse came straight from
-		 * the original driver code.
-		 */
-
-		txc->phy_control |=
-			cpu_to_le32(queue << AR9170_TX_PHY_QOS_SHIFT);
-
-		txc->mac_control |= cpu_to_le16(AR9170_TX_MAC_RATE_PROBE);
-	}
-
-	return 0;
-
-err_out:
-	skb_pull(skb, sizeof(*txc));
-	return -EINVAL;
-}
-
-static void ar9170_tx_prepare_phy(struct ar9170 *ar, struct sk_buff *skb)
-{
-	struct ar9170_tx_control *txc;
-	struct ieee80211_tx_info *info;
-	struct ieee80211_rate *rate = NULL;
-	struct ieee80211_tx_rate *txrate;
-	u32 power, chains;
-
-	txc = (void *) skb->data;
-	info = IEEE80211_SKB_CB(skb);
-	txrate = &info->control.rates[0];
-
-	if (txrate->flags & IEEE80211_TX_RC_GREEN_FIELD)
-		txc->phy_control |= cpu_to_le32(AR9170_TX_PHY_GREENFIELD);
-
-	if (txrate->flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE)
-		txc->phy_control |= cpu_to_le32(AR9170_TX_PHY_SHORT_PREAMBLE);
-
-	if (txrate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH)
-		txc->phy_control |= cpu_to_le32(AR9170_TX_PHY_BW_40MHZ);
-	/* this works because 40 MHz is 2 and dup is 3 */
-	if (txrate->flags & IEEE80211_TX_RC_DUP_DATA)
-		txc->phy_control |= cpu_to_le32(AR9170_TX_PHY_BW_40MHZ_DUP);
-
-	if (txrate->flags & IEEE80211_TX_RC_SHORT_GI)
-		txc->phy_control |= cpu_to_le32(AR9170_TX_PHY_SHORT_GI);
-
-	if (txrate->flags & IEEE80211_TX_RC_MCS) {
-		u32 r = txrate->idx;
-		u8 *txpower;
-
-		/* heavy clip control */
-		txc->phy_control |= cpu_to_le32((r & 0x7) << 7);
-
-		r <<= AR9170_TX_PHY_MCS_SHIFT;
-		BUG_ON(r & ~AR9170_TX_PHY_MCS_MASK);
-
-		txc->phy_control |= cpu_to_le32(r & AR9170_TX_PHY_MCS_MASK);
-		txc->phy_control |= cpu_to_le32(AR9170_TX_PHY_MOD_HT);
-
-		if (txrate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH) {
-			if (info->band == IEEE80211_BAND_5GHZ)
-				txpower = ar->power_5G_ht40;
-			else
-				txpower = ar->power_2G_ht40;
-		} else {
-			if (info->band == IEEE80211_BAND_5GHZ)
-				txpower = ar->power_5G_ht20;
-			else
-				txpower = ar->power_2G_ht20;
-		}
-
-		power = txpower[(txrate->idx) & 7];
-	} else {
-		u8 *txpower;
-		u32 mod;
-		u32 phyrate;
-		u8 idx = txrate->idx;
-
-		if (info->band != IEEE80211_BAND_2GHZ) {
-			idx += 4;
-			txpower = ar->power_5G_leg;
-			mod = AR9170_TX_PHY_MOD_OFDM;
-		} else {
-			if (idx < 4) {
-				txpower = ar->power_2G_cck;
-				mod = AR9170_TX_PHY_MOD_CCK;
-			} else {
-				mod = AR9170_TX_PHY_MOD_OFDM;
-				txpower = ar->power_2G_ofdm;
-			}
-		}
-
-		rate = &__ar9170_ratetable[idx];
-
-		phyrate = rate->hw_value & 0xF;
-		power = txpower[(rate->hw_value & 0x30) >> 4];
-		phyrate <<= AR9170_TX_PHY_MCS_SHIFT;
-
-		txc->phy_control |= cpu_to_le32(mod);
-		txc->phy_control |= cpu_to_le32(phyrate);
-	}
-
-	power <<= AR9170_TX_PHY_TX_PWR_SHIFT;
-	power &= AR9170_TX_PHY_TX_PWR_MASK;
-	txc->phy_control |= cpu_to_le32(power);
-
-	/* set TX chains */
-	if (ar->eeprom.tx_mask == 1) {
-		chains = AR9170_TX_PHY_TXCHAIN_1;
-	} else {
-		chains = AR9170_TX_PHY_TXCHAIN_2;
-
-		/* >= 36M legacy OFDM - use only one chain */
-		if (rate && rate->bitrate >= 360)
-			chains = AR9170_TX_PHY_TXCHAIN_1;
-	}
-	txc->phy_control |= cpu_to_le32(chains << AR9170_TX_PHY_TXCHAIN_SHIFT);
-}
-
-static void ar9170_tx(struct ar9170 *ar)
-{
-	struct sk_buff *skb;
-	unsigned long flags;
-	struct ieee80211_tx_info *info;
-	struct ar9170_tx_info *arinfo;
-	unsigned int i, frames, frames_failed, remaining_space;
-	int err;
-	bool schedule_garbagecollector = false;
-
-	BUILD_BUG_ON(sizeof(*arinfo) > sizeof(info->rate_driver_data));
-
-	if (unlikely(!IS_STARTED(ar)))
-		return ;
-
-	remaining_space = AR9170_TX_MAX_PENDING;
-
-	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
-			wiphy_debug(ar->hw->wiphy,
-				    "tx quota reached queue:%d, "
-				    "remaining slots:%d, needed:%d\n",
-				    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
-			wiphy_debug(ar->hw->wiphy, "queue %d full\n", i);
-			wiphy_debug(ar->hw->wiphy, "stuck frames: ===>\n");
-			ar9170_dump_txqueue(ar, &ar->tx_pending[i]);
-			ar9170_dump_txqueue(ar, &ar->tx_status[i]);
-#endif /* AR9170_QUEUE_DEBUG */
-
-#ifdef AR9170_QUEUE_STOP_DEBUG
-			wiphy_debug(ar->hw->wiphy, "stop queue %d\n", i);
-			__ar9170_dump_txstats(ar);
-#endif /* AR9170_QUEUE_STOP_DEBUG */
-			ieee80211_stop_queue(ar->hw, i);
-		}
-
-		spin_unlock_irqrestore(&ar->tx_stats_lock, flags);
-
-		if (!frames)
-			continue;
-
-		frames_failed = 0;
-		while (frames) {
-			skb = skb_dequeue(&ar->tx_pending[i]);
-			if (unlikely(!skb)) {
-				frames_failed += frames;
-				frames = 0;
-				break;
-			}
-
-			info = IEEE80211_SKB_CB(skb);
-			arinfo = (void *) info->rate_driver_data;
-
-			/* TODO: cancel stuck frames */
-			arinfo->timeout = jiffies +
-					  msecs_to_jiffies(AR9170_TX_TIMEOUT);
-
-#ifdef AR9170_QUEUE_DEBUG
-			wiphy_debug(ar->hw->wiphy, "send frame q:%d =>\n", i);
-			ar9170_print_txheader(ar, skb);
-#endif /* AR9170_QUEUE_DEBUG */
-
-			err = ar->tx(ar, skb);
-			if (unlikely(err)) {
-				frames_failed++;
-				dev_kfree_skb_any(skb);
-			} else {
-				remaining_space--;
-				schedule_garbagecollector = true;
-			}
-
-			frames--;
-		}
-
-#ifdef AR9170_QUEUE_DEBUG
-		wiphy_debug(ar->hw->wiphy,
-			    "ar9170_tx report for queue %d\n", i);
-
-		wiphy_debug(ar->hw->wiphy,
-			    "unprocessed pending frames left:\n");
-		ar9170_dump_txqueue(ar, &ar->tx_pending[i]);
-#endif /* AR9170_QUEUE_DEBUG */
-
-		if (unlikely(frames_failed)) {
-#ifdef AR9170_QUEUE_DEBUG
-			wiphy_debug(ar->hw->wiphy,
-				    "frames failed %d =>\n", frames_failed);
-#endif /* AR9170_QUEUE_DEBUG */
-
-			spin_lock_irqsave(&ar->tx_stats_lock, flags);
-			ar->tx_stats[i].len -= frames_failed;
-			ar->tx_stats[i].count -= frames_failed;
-#ifdef AR9170_QUEUE_STOP_DEBUG
-			wiphy_debug(ar->hw->wiphy, "wake queue %d\n", i);
-			__ar9170_dump_txstats(ar);
-#endif /* AR9170_QUEUE_STOP_DEBUG */
-			ieee80211_wake_queue(ar->hw, i);
-			spin_unlock_irqrestore(&ar->tx_stats_lock, flags);
-		}
-	}
-
-	if (!schedule_garbagecollector)
-		return;
-
-	ieee80211_queue_delayed_work(ar->hw,
-				     &ar->tx_janitor,
-				     msecs_to_jiffies(AR9170_JANITOR_DELAY));
-}
-
-void ar9170_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
-{
-	struct ar9170 *ar = hw->priv;
-	struct ieee80211_tx_info *info;
-	unsigned int queue;
-
-	if (unlikely(!IS_STARTED(ar)))
-		goto err_free;
-
-	if (unlikely(ar9170_tx_prepare(ar, skb)))
-		goto err_free;
-
-	queue = skb_get_queue_mapping(skb);
-	info = IEEE80211_SKB_CB(skb);
-	ar9170_tx_prepare_phy(ar, skb);
-	skb_queue_tail(&ar->tx_pending[queue], skb);
-
-	ar9170_tx(ar);
-	return;
-
-err_free:
-	dev_kfree_skb_any(skb);
-}
-
-static int ar9170_op_add_interface(struct ieee80211_hw *hw,
-				   struct ieee80211_vif *vif)
-{
-	struct ar9170 *ar = hw->priv;
-	struct ath_common *common = &ar->common;
-	int err = 0;
-
-	mutex_lock(&ar->mutex);
-
-	if (ar->vif) {
-		err = -EBUSY;
-		goto unlock;
-	}
-
-	ar->vif = vif;
-	memcpy(common->macaddr, vif->addr, ETH_ALEN);
-
-	if (modparam_nohwcrypt || (ar->vif->type != NL80211_IFTYPE_STATION)) {
-		ar->rx_software_decryption = true;
-		ar->disable_offload = true;
-	}
-
-	ar->cur_filter = 0;
-	err = ar9170_update_frame_filter(ar, AR9170_MAC_REG_FTF_DEFAULTS);
-	if (err)
-		goto unlock;
-
-	err = ar9170_set_operating_mode(ar);
-
-unlock:
-	mutex_unlock(&ar->mutex);
-	return err;
-}
-
-static void ar9170_op_remove_interface(struct ieee80211_hw *hw,
-				       struct ieee80211_vif *vif)
-{
-	struct ar9170 *ar = hw->priv;
-
-	mutex_lock(&ar->mutex);
-	ar->vif = NULL;
-	ar9170_update_frame_filter(ar, 0);
-	ar9170_set_beacon_timers(ar);
-	dev_kfree_skb(ar->beacon);
-	ar->beacon = NULL;
-	ar->sniffer_enabled = false;
-	ar->rx_software_decryption = false;
-	ar9170_set_operating_mode(ar);
-	mutex_unlock(&ar->mutex);
-}
-
-static int ar9170_op_config(struct ieee80211_hw *hw, u32 changed)
-{
-	struct ar9170 *ar = hw->priv;
-	int err = 0;
-
-	mutex_lock(&ar->mutex);
-
-	if (changed & IEEE80211_CONF_CHANGE_LISTEN_INTERVAL) {
-		/* TODO */
-		err = 0;
-	}
-
-	if (changed & IEEE80211_CONF_CHANGE_PS) {
-		/* TODO */
-		err = 0;
-	}
-
-	if (changed & IEEE80211_CONF_CHANGE_POWER) {
-		/* TODO */
-		err = 0;
-	}
-
-	if (changed & IEEE80211_CONF_CHANGE_RETRY_LIMITS) {
-		/*
-		 * is it long_frame_max_tx_count or short_frame_max_tx_count?
-		 */
-
-		err = ar9170_set_hwretry_limit(ar,
-			ar->hw->conf.long_frame_max_tx_count);
-		if (err)
-			goto out;
-	}
-
-	if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
-
-		/* adjust slot time for 5 GHz */
-		err = ar9170_set_slot_time(ar);
-		if (err)
-			goto out;
-
-		err = ar9170_set_dyn_sifs_ack(ar);
-		if (err)
-			goto out;
-
-		err = ar9170_set_channel(ar, hw->conf.channel,
-				AR9170_RFI_NONE,
-				nl80211_to_ar9170(hw->conf.channel_type));
-		if (err)
-			goto out;
-	}
-
-out:
-	mutex_unlock(&ar->mutex);
-	return err;
-}
-
-static u64 ar9170_op_prepare_multicast(struct ieee80211_hw *hw,
-				       struct netdev_hw_addr_list *mc_list)
-{
-	u64 mchash;
-	struct netdev_hw_addr *ha;
-
-	/* always get broadcast frames */
-	mchash = 1ULL << (0xff >> 2);
-
-	netdev_hw_addr_list_for_each(ha, mc_list)
-		mchash |= 1ULL << (ha->addr[5] >> 2);
-
-	return mchash;
-}
-
-static void ar9170_op_configure_filter(struct ieee80211_hw *hw,
-				       unsigned int changed_flags,
-				       unsigned int *new_flags,
-				       u64 multicast)
-{
-	struct ar9170 *ar = hw->priv;
-
-	if (unlikely(!IS_ACCEPTING_CMD(ar)))
-		return ;
-
-	mutex_lock(&ar->mutex);
-
-	/* mask supported flags */
-	*new_flags &= FIF_ALLMULTI | FIF_CONTROL | FIF_BCN_PRBRESP_PROMISC |
-		      FIF_PROMISC_IN_BSS | FIF_FCSFAIL | FIF_PLCPFAIL;
-	ar->filter_state = *new_flags;
-	/*
-	 * We can support more by setting the sniffer bit and
-	 * then checking the error flags, later.
-	 */
-
-	if (changed_flags & FIF_ALLMULTI && *new_flags & FIF_ALLMULTI)
-		multicast = ~0ULL;
-
-	if (multicast != ar->cur_mc_hash)
-		ar9170_update_multicast(ar, multicast);
-
-	if (changed_flags & FIF_CONTROL) {
-		u32 filter = AR9170_MAC_REG_FTF_PSPOLL |
-			     AR9170_MAC_REG_FTF_RTS |
-			     AR9170_MAC_REG_FTF_CTS |
-			     AR9170_MAC_REG_FTF_ACK |
-			     AR9170_MAC_REG_FTF_CFE |
-			     AR9170_MAC_REG_FTF_CFE_ACK;
-
-		if (*new_flags & FIF_CONTROL)
-			filter |= ar->cur_filter;
-		else
-			filter &= (~ar->cur_filter);
-
-		ar9170_update_frame_filter(ar, filter);
-	}
-
-	if (changed_flags & FIF_PROMISC_IN_BSS) {
-		ar->sniffer_enabled = ((*new_flags) & FIF_PROMISC_IN_BSS) != 0;
-		ar9170_set_operating_mode(ar);
-	}
-
-	mutex_unlock(&ar->mutex);
-}
-
-
-static void ar9170_op_bss_info_changed(struct ieee80211_hw *hw,
-				       struct ieee80211_vif *vif,
-				       struct ieee80211_bss_conf *bss_conf,
-				       u32 changed)
-{
-	struct ar9170 *ar = hw->priv;
-	struct ath_common *common = &ar->common;
-	int err = 0;
-
-	mutex_lock(&ar->mutex);
-
-	if (changed & BSS_CHANGED_BSSID) {
-		memcpy(common->curbssid, bss_conf->bssid, ETH_ALEN);
-		err = ar9170_set_operating_mode(ar);
-		if (err)
-			goto out;
-	}
-
-	if (changed & BSS_CHANGED_BEACON_ENABLED)
-		ar->enable_beacon = bss_conf->enable_beacon;
-
-	if (changed & BSS_CHANGED_BEACON) {
-		err = ar9170_update_beacon(ar);
-		if (err)
-			goto out;
-	}
-
-	if (changed & (BSS_CHANGED_BEACON_ENABLED | BSS_CHANGED_BEACON |
-		       BSS_CHANGED_BEACON_INT)) {
-		err = ar9170_set_beacon_timers(ar);
-		if (err)
-			goto out;
-	}
-
-	if (changed & BSS_CHANGED_ASSOC) {
-#ifndef CONFIG_AR9170_LEDS
-		/* enable assoc LED. */
-		err = ar9170_set_leds_state(ar, bss_conf->assoc ? 2 : 0);
-#endif /* CONFIG_AR9170_LEDS */
-	}
-
-	if (changed & BSS_CHANGED_HT) {
-		/* TODO */
-		err = 0;
-	}
-
-	if (changed & BSS_CHANGED_ERP_SLOT) {
-		err = ar9170_set_slot_time(ar);
-		if (err)
-			goto out;
-	}
-
-	if (changed & BSS_CHANGED_BASIC_RATES) {
-		err = ar9170_set_basic_rates(ar);
-		if (err)
-			goto out;
-	}
-
-out:
-	mutex_unlock(&ar->mutex);
-}
-
-static u64 ar9170_op_get_tsf(struct ieee80211_hw *hw)
-{
-	struct ar9170 *ar = hw->priv;
-	int err;
-	u64 tsf;
-#define NR 3
-	static const u32 addr[NR] = { AR9170_MAC_REG_TSF_H,
-				    AR9170_MAC_REG_TSF_L,
-				    AR9170_MAC_REG_TSF_H };
-	u32 val[NR];
-	int loops = 0;
-
-	mutex_lock(&ar->mutex);
-
-	while (loops++ < 10) {
-		err = ar9170_read_mreg(ar, NR, addr, val);
-		if (err || val[0] == val[2])
-			break;
-	}
-
-	mutex_unlock(&ar->mutex);
-
-	if (WARN_ON(err))
-		return 0;
-	tsf = val[0];
-	tsf = (tsf << 32) | val[1];
-	return tsf;
-#undef NR
-}
-
-static int ar9170_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
-			  struct ieee80211_vif *vif, struct ieee80211_sta *sta,
-			  struct ieee80211_key_conf *key)
-{
-	struct ar9170 *ar = hw->priv;
-	int err = 0, i;
-	u8 ktype;
-
-	if ((!ar->vif) || (ar->disable_offload))
-		return -EOPNOTSUPP;
-
-	switch (key->cipher) {
-	case WLAN_CIPHER_SUITE_WEP40:
-		ktype = AR9170_ENC_ALG_WEP64;
-		break;
-	case WLAN_CIPHER_SUITE_WEP104:
-		ktype = AR9170_ENC_ALG_WEP128;
-		break;
-	case WLAN_CIPHER_SUITE_TKIP:
-		ktype = AR9170_ENC_ALG_TKIP;
-		break;
-	case WLAN_CIPHER_SUITE_CCMP:
-		ktype = AR9170_ENC_ALG_AESCCMP;
-		break;
-	default:
-		return -EOPNOTSUPP;
-	}
-
-	mutex_lock(&ar->mutex);
-	if (cmd == SET_KEY) {
-		if (unlikely(!IS_STARTED(ar))) {
-			err = -EOPNOTSUPP;
-			goto out;
-		}
-
-		/* group keys need all-zeroes address */
-		if (!(key->flags & IEEE80211_KEY_FLAG_PAIRWISE))
-			sta = NULL;
-
-		if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE) {
-			for (i = 0; i < 64; i++)
-				if (!(ar->usedkeys & BIT(i)))
-					break;
-			if (i == 64) {
-				ar->rx_software_decryption = true;
-				ar9170_set_operating_mode(ar);
-				err = -ENOSPC;
-				goto out;
-			}
-		} else {
-			i = 64 + key->keyidx;
-		}
-
-		key->hw_key_idx = i;
-
-		err = ar9170_upload_key(ar, i, sta ? sta->addr : NULL, ktype, 0,
-					key->key, min_t(u8, 16, key->keylen));
-		if (err)
-			goto out;
-
-		if (key->cipher == WLAN_CIPHER_SUITE_TKIP) {
-			err = ar9170_upload_key(ar, i, sta ? sta->addr : NULL,
-						ktype, 1, key->key + 16, 16);
-			if (err)
-				goto out;
-
-			/*
-			 * hardware is not capable generating the MMIC
-			 * for fragmented frames!
-			 */
-			key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC;
-		}
-
-		if (i < 64)
-			ar->usedkeys |= BIT(i);
-
-		key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
-	} else {
-		if (unlikely(!IS_STARTED(ar))) {
-			/* The device is gone... together with the key ;-) */
-			err = 0;
-			goto out;
-		}
-
-		err = ar9170_disable_key(ar, key->hw_key_idx);
-		if (err)
-			goto out;
-
-		if (key->hw_key_idx < 64) {
-			ar->usedkeys &= ~BIT(key->hw_key_idx);
-		} else {
-			err = ar9170_upload_key(ar, key->hw_key_idx, NULL,
-						AR9170_ENC_ALG_NONE, 0,
-						NULL, 0);
-			if (err)
-				goto out;
-
-			if (key->cipher == WLAN_CIPHER_SUITE_TKIP) {
-				err = ar9170_upload_key(ar, key->hw_key_idx,
-							NULL,
-							AR9170_ENC_ALG_NONE, 1,
-							NULL, 0);
-				if (err)
-					goto out;
-			}
-
-		}
-	}
-
-	ar9170_regwrite_begin(ar);
-	ar9170_regwrite(AR9170_MAC_REG_ROLL_CALL_TBL_L, ar->usedkeys);
-	ar9170_regwrite(AR9170_MAC_REG_ROLL_CALL_TBL_H, ar->usedkeys >> 32);
-	ar9170_regwrite_finish();
-	err = ar9170_regwrite_result();
-
-out:
-	mutex_unlock(&ar->mutex);
-
-	return err;
-}
-
-static int ar9170_get_stats(struct ieee80211_hw *hw,
-			    struct ieee80211_low_level_stats *stats)
-{
-	struct ar9170 *ar = hw->priv;
-	u32 val;
-	int err;
-
-	mutex_lock(&ar->mutex);
-	err = ar9170_read_reg(ar, AR9170_MAC_REG_TX_RETRY, &val);
-	ar->stats.dot11ACKFailureCount += val;
-
-	memcpy(stats, &ar->stats, sizeof(*stats));
-	mutex_unlock(&ar->mutex);
-
-	return 0;
-}
-
-static int ar9170_get_survey(struct ieee80211_hw *hw, int idx,
-				struct survey_info *survey)
-{
-	struct ar9170 *ar = hw->priv;
-	struct ieee80211_conf *conf = &hw->conf;
-
-	if (idx != 0)
-		return -ENOENT;
-
-	/* TODO: update noise value, e.g. call ar9170_set_channel */
-
-	survey->channel = conf->channel;
-	survey->filled = SURVEY_INFO_NOISE_DBM;
-	survey->noise = ar->noise[0];
-
-	return 0;
-}
-
-static int ar9170_conf_tx(struct ieee80211_hw *hw, u16 queue,
-			  const struct ieee80211_tx_queue_params *param)
-{
-	struct ar9170 *ar = hw->priv;
-	int ret;
-
-	mutex_lock(&ar->mutex);
-	if (queue < __AR9170_NUM_TXQ) {
-		memcpy(&ar->edcf[ar9170_qos_hwmap[queue]],
-		       param, sizeof(*param));
-
-		ret = ar9170_set_qos(ar);
-	} else {
-		ret = -EINVAL;
-	}
-
-	mutex_unlock(&ar->mutex);
-	return ret;
-}
-
-static int ar9170_ampdu_action(struct ieee80211_hw *hw,
-			       struct ieee80211_vif *vif,
-			       enum ieee80211_ampdu_mlme_action action,
-			       struct ieee80211_sta *sta, u16 tid, u16 *ssn,
-			       u8 buf_size)
-{
-	switch (action) {
-	case IEEE80211_AMPDU_RX_START:
-	case IEEE80211_AMPDU_RX_STOP:
-		/* Handled by firmware */
-		break;
-
-	default:
-		return -EOPNOTSUPP;
-	}
-
-	return 0;
-}
-
-static const struct ieee80211_ops ar9170_ops = {
-	.start			= ar9170_op_start,
-	.stop			= ar9170_op_stop,
-	.tx			= ar9170_op_tx,
-	.add_interface		= ar9170_op_add_interface,
-	.remove_interface	= ar9170_op_remove_interface,
-	.config			= ar9170_op_config,
-	.prepare_multicast	= ar9170_op_prepare_multicast,
-	.configure_filter	= ar9170_op_configure_filter,
-	.conf_tx		= ar9170_conf_tx,
-	.bss_info_changed	= ar9170_op_bss_info_changed,
-	.get_tsf		= ar9170_op_get_tsf,
-	.set_key		= ar9170_set_key,
-	.get_stats		= ar9170_get_stats,
-	.get_survey		= ar9170_get_survey,
-	.ampdu_action		= ar9170_ampdu_action,
-};
-
-void *ar9170_alloc(size_t priv_size)
-{
-	struct ieee80211_hw *hw;
-	struct ar9170 *ar;
-	struct sk_buff *skb;
-	int i;
-
-	/*
-	 * this buffer is used for rx stream reconstruction.
-	 * Under heavy load this device (or the transport layer?)
-	 * tends to split the streams into separate rx descriptors.
-	 */
-
-	skb = __dev_alloc_skb(AR9170_RX_STREAM_MAX_SIZE, GFP_KERNEL);
-	if (!skb)
-		goto err_nomem;
-
-	hw = ieee80211_alloc_hw(priv_size, &ar9170_ops);
-	if (!hw)
-		goto err_nomem;
-
-	ar = hw->priv;
-	ar->hw = hw;
-	ar->rx_failover = skb;
-
-	mutex_init(&ar->mutex);
-	spin_lock_init(&ar->cmdlock);
-	spin_lock_init(&ar->tx_stats_lock);
-	for (i = 0; i < __AR9170_NUM_TXQ; i++) {
-		skb_queue_head_init(&ar->tx_status[i]);
-		skb_queue_head_init(&ar->tx_pending[i]);
-	}
-	ar9170_rx_reset_rx_mpdu(ar);
-	INIT_WORK(&ar->beacon_work, ar9170_new_beacon);
-	INIT_DELAYED_WORK(&ar->tx_janitor, ar9170_tx_janitor);
-
-	/* all hw supports 2.4 GHz, so set channel to 1 by default */
-	ar->channel = &ar9170_2ghz_chantable[0];
-
-	/* first part of wiphy init */
-	ar->hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
-					 BIT(NL80211_IFTYPE_WDS) |
-					 BIT(NL80211_IFTYPE_ADHOC);
-	ar->hw->flags |= IEEE80211_HW_RX_INCLUDES_FCS |
-			 IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING |
-			 IEEE80211_HW_SIGNAL_DBM;
-
-	ar->hw->queues = __AR9170_NUM_TXQ;
-	ar->hw->extra_tx_headroom = 8;
-
-	ar->hw->max_rates = 1;
-	ar->hw->max_rate_tries = 3;
-
-	for (i = 0; i < ARRAY_SIZE(ar->noise); i++)
-		ar->noise[i] = -95; /* ATH_DEFAULT_NOISE_FLOOR */
-
-	return ar;
-
-err_nomem:
-	kfree_skb(skb);
-	return ERR_PTR(-ENOMEM);
-}
-
-static int ar9170_read_eeprom(struct ar9170 *ar)
-{
-#define RW	8	/* number of words to read at once */
-#define RB	(sizeof(u32) * RW)
-	struct ath_regulatory *regulatory = &ar->common.regulatory;
-	u8 *eeprom = (void *)&ar->eeprom;
-	u8 *addr = ar->eeprom.mac_address;
-	__le32 offsets[RW];
-	unsigned int rx_streams, tx_streams, tx_params = 0;
-	int i, j, err, bands = 0;
-
-	BUILD_BUG_ON(sizeof(ar->eeprom) & 3);
-
-	BUILD_BUG_ON(RB > AR9170_MAX_CMD_LEN - 4);
-#ifndef __CHECKER__
-	/* don't want to handle trailing remains */
-	BUILD_BUG_ON(sizeof(ar->eeprom) % RB);
-#endif
-
-	for (i = 0; i < sizeof(ar->eeprom)/RB; i++) {
-		for (j = 0; j < RW; j++)
-			offsets[j] = cpu_to_le32(AR9170_EEPROM_START +
-						 RB * i + 4 * j);
-
-		err = ar->exec_cmd(ar, AR9170_CMD_RREG,
-				   RB, (u8 *) &offsets,
-				   RB, eeprom + RB * i);
-		if (err)
-			return err;
-	}
-
-#undef RW
-#undef RB
-
-	if (ar->eeprom.length == cpu_to_le16(0xFFFF))
-		return -ENODATA;
-
-	if (ar->eeprom.operating_flags & AR9170_OPFLAG_2GHZ) {
-		ar->hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &ar9170_band_2GHz;
-		bands++;
-	}
-	if (ar->eeprom.operating_flags & AR9170_OPFLAG_5GHZ) {
-		ar->hw->wiphy->bands[IEEE80211_BAND_5GHZ] = &ar9170_band_5GHz;
-		bands++;
-	}
-
-	rx_streams = hweight8(ar->eeprom.rx_mask);
-	tx_streams = hweight8(ar->eeprom.tx_mask);
-
-	if (rx_streams != tx_streams)
-		tx_params = IEEE80211_HT_MCS_TX_RX_DIFF;
-
-	if (tx_streams >= 1 && tx_streams <= IEEE80211_HT_MCS_TX_MAX_STREAMS)
-		tx_params = (tx_streams - 1) <<
-			    IEEE80211_HT_MCS_TX_MAX_STREAMS_SHIFT;
-
-	ar9170_band_2GHz.ht_cap.mcs.tx_params |= tx_params;
-	ar9170_band_5GHz.ht_cap.mcs.tx_params |= tx_params;
-
-	/*
-	 * I measured this, a bandswitch takes roughly
-	 * 135 ms and a frequency switch about 80.
-	 *
-	 * FIXME: measure these values again once EEPROM settings
-	 *	  are used, that will influence them!
-	 */
-	if (bands == 2)
-		ar->hw->channel_change_time = 135 * 1000;
-	else
-		ar->hw->channel_change_time = 80 * 1000;
-
-	regulatory->current_rd = le16_to_cpu(ar->eeprom.reg_domain[0]);
-	regulatory->current_rd_ext = le16_to_cpu(ar->eeprom.reg_domain[1]);
-
-	/* second part of wiphy init */
-	SET_IEEE80211_PERM_ADDR(ar->hw, addr);
-
-	return bands ? 0 : -EINVAL;
-}
-
-static int ar9170_reg_notifier(struct wiphy *wiphy,
-			struct regulatory_request *request)
-{
-	struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
-	struct ar9170 *ar = hw->priv;
-
-	return ath_reg_notifier_apply(wiphy, request, &ar->common.regulatory);
-}
-
-int ar9170_register(struct ar9170 *ar, struct device *pdev)
-{
-	struct ath_regulatory *regulatory = &ar->common.regulatory;
-	int err;
-
-	/* try to read EEPROM, init MAC addr */
-	err = ar9170_read_eeprom(ar);
-	if (err)
-		goto err_out;
-
-	err = ath_regd_init(regulatory, ar->hw->wiphy,
-			    ar9170_reg_notifier);
-	if (err)
-		goto err_out;
-
-	err = ieee80211_register_hw(ar->hw);
-	if (err)
-		goto err_out;
-
-	if (!ath_is_world_regd(regulatory))
-		regulatory_hint(ar->hw->wiphy, regulatory->alpha2);
-
-	err = ar9170_init_leds(ar);
-	if (err)
-		goto err_unreg;
-
-#ifdef CONFIG_AR9170_LEDS
-	err = ar9170_register_leds(ar);
-	if (err)
-		goto err_unreg;
-#endif /* CONFIG_AR9170_LEDS */
-
-	dev_info(pdev, "Atheros AR9170 is registered as '%s'\n",
-		 wiphy_name(ar->hw->wiphy));
-
-	ar->registered = true;
-	return 0;
-
-err_unreg:
-	ieee80211_unregister_hw(ar->hw);
-
-err_out:
-	return err;
-}
-
-void ar9170_unregister(struct ar9170 *ar)
-{
-	if (ar->registered) {
-#ifdef CONFIG_AR9170_LEDS
-		ar9170_unregister_leds(ar);
-#endif /* CONFIG_AR9170_LEDS */
-
-	ieee80211_unregister_hw(ar->hw);
-	}
-
-	kfree_skb(ar->rx_failover);
-	mutex_destroy(&ar->mutex);
-}
diff -druN linux-2.6.39-libre/drivers/net/wireless/ath/ar9170/Makefile linux-3.0-rc7-libre/drivers/net/wireless/ath/ar9170/Makefile
--- linux-2.6.39-libre/drivers/net/wireless/ath/ar9170/Makefile	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/ath/ar9170/Makefile	1969-12-31 19:00:00.000000000 -0500
@@ -1,3 +0,0 @@
-ar9170usb-objs := usb.o main.o cmd.o mac.o phy.o led.o
-
-obj-$(CONFIG_AR9170_USB) += ar9170usb.o
diff -druN linux-2.6.39-libre/drivers/net/wireless/ath/ar9170/phy.c linux-3.0-rc7-libre/drivers/net/wireless/ath/ar9170/phy.c
--- linux-2.6.39-libre/drivers/net/wireless/ath/ar9170/phy.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/ath/ar9170/phy.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,1719 +0,0 @@
-/*
- * Atheros AR9170 driver
- *
- * PHY and RF code
- *
- * Copyright 2008, Johannes Berg <johannes@sipsolutions.net>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; see the file COPYING.  If not, see
- * http://www.gnu.org/licenses/.
- *
- * This file incorporates work covered by the following copyright and
- * permission notice:
- *    Copyright (c) 2007-2008 Atheros Communications, Inc.
- *
- *    Permission to use, copy, modify, and/or distribute this software for any
- *    purpose with or without fee is hereby granted, provided that the above
- *    copyright notice and this permission notice appear in all copies.
- *
- *    THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- *    WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- *    MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- *    ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- *    WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- *    ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- *    OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include <linux/bitrev.h>
-#include "ar9170.h"
-#include "cmd.h"
-
-static int ar9170_init_power_cal(struct ar9170 *ar)
-{
-	ar9170_regwrite_begin(ar);
-
-	ar9170_regwrite(0x1bc000 + 0x993c, 0x7f);
-	ar9170_regwrite(0x1bc000 + 0x9934, 0x3f3f3f3f);
-	ar9170_regwrite(0x1bc000 + 0x9938, 0x3f3f3f3f);
-	ar9170_regwrite(0x1bc000 + 0xa234, 0x3f3f3f3f);
-	ar9170_regwrite(0x1bc000 + 0xa238, 0x3f3f3f3f);
-	ar9170_regwrite(0x1bc000 + 0xa38c, 0x3f3f3f3f);
-	ar9170_regwrite(0x1bc000 + 0xa390, 0x3f3f3f3f);
-	ar9170_regwrite(0x1bc000 + 0xa3cc, 0x3f3f3f3f);
-	ar9170_regwrite(0x1bc000 + 0xa3d0, 0x3f3f3f3f);
-	ar9170_regwrite(0x1bc000 + 0xa3d4, 0x3f3f3f3f);
-
-	ar9170_regwrite_finish();
-	return ar9170_regwrite_result();
-}
-
-struct ar9170_phy_init {
-	u32 reg, _5ghz_20, _5ghz_40, _2ghz_40, _2ghz_20;
-};
-
-static struct ar9170_phy_init ar5416_phy_init[] = {
-	{ 0x1c5800, 0x00000007, 0x00000007, 0x00000007, 0x00000007, },
-	{ 0x1c5804, 0x00000300, 0x000003c4, 0x000003c4, 0x00000300, },
-	{ 0x1c5808, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-	{ 0x1c580c, 0xad848e19, 0xad848e19, 0xad848e19, 0xad848e19, },
-	{ 0x1c5810, 0x7d14e000, 0x7d14e000, 0x7d14e000, 0x7d14e000, },
-	{ 0x1c5814, 0x9c0a9f6b, 0x9c0a9f6b, 0x9c0a9f6b, 0x9c0a9f6b, },
-	{ 0x1c5818, 0x00000090, 0x00000090, 0x00000090, 0x00000090, },
-	{ 0x1c581c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-	{ 0x1c5820, 0x02020200, 0x02020200, 0x02020200, 0x02020200, },
-	{ 0x1c5824, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, },
-	{ 0x1c5828, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001, },
-	{ 0x1c582c, 0x0000a000, 0x0000a000, 0x0000a000, 0x0000a000, },
-	{ 0x1c5830, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-	{ 0x1c5834, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, },
-	{ 0x1c5838, 0x00000007, 0x00000007, 0x00000007, 0x00000007, },
-	{ 0x1c583c, 0x00200400, 0x00200400, 0x00200400, 0x00200400, },
-	{ 0x1c5840, 0x206a002e, 0x206a002e, 0x206a002e, 0x206a002e, },
-	{ 0x1c5844, 0x1372161e, 0x13721c1e, 0x13721c24, 0x137216a4, },
-	{ 0x1c5848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, },
-	{ 0x1c584c, 0x1284233c, 0x1284233c, 0x1284233c, 0x1284233c, },
-	{ 0x1c5850, 0x6c48b4e4, 0x6c48b4e4, 0x6c48b0e4, 0x6c48b0e4, },
-	{ 0x1c5854, 0x00000859, 0x00000859, 0x00000859, 0x00000859, },
-	{ 0x1c5858, 0x7ec80d2e, 0x7ec80d2e, 0x7ec80d2e, 0x7ec80d2e, },
-	{ 0x1c585c, 0x31395c5e, 0x31395c5e, 0x31395c5e, 0x31395c5e, },
-	{ 0x1c5860, 0x0004dd10, 0x0004dd10, 0x0004dd20, 0x0004dd20, },
-	{ 0x1c5868, 0x409a4190, 0x409a4190, 0x409a4190, 0x409a4190, },
-	{ 0x1c586c, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081, },
-	{ 0x1c5900, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-	{ 0x1c5904, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-	{ 0x1c5908, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-	{ 0x1c590c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-	{ 0x1c5914, 0x000007d0, 0x000007d0, 0x00000898, 0x00000898, },
-	{ 0x1c5918, 0x00000118, 0x00000230, 0x00000268, 0x00000134, },
-	{ 0x1c591c, 0x10000fff, 0x10000fff, 0x10000fff, 0x10000fff, },
-	{ 0x1c5920, 0x0510081c, 0x0510081c, 0x0510001c, 0x0510001c, },
-	{ 0x1c5924, 0xd0058a15, 0xd0058a15, 0xd0058a15, 0xd0058a15, },
-	{ 0x1c5928, 0x00000001, 0x00000001, 0x00000001, 0x00000001, },
-	{ 0x1c592c, 0x00000004, 0x00000004, 0x00000004, 0x00000004, },
-	{ 0x1c5934, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, },
-	{ 0x1c5938, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, },
-	{ 0x1c593c, 0x0000007f, 0x0000007f, 0x0000007f, 0x0000007f, },
-	{ 0x1c5944, 0xdfb81020, 0xdfb81020, 0xdfb81020, 0xdfb81020, },
-	{ 0x1c5948, 0x9280b212, 0x9280b212, 0x9280b212, 0x9280b212, },
-	{ 0x1c594c, 0x00020028, 0x00020028, 0x00020028, 0x00020028, },
-	{ 0x1c5954, 0x5d50e188, 0x5d50e188, 0x5d50e188, 0x5d50e188, },
-	{ 0x1c5958, 0x00081fff, 0x00081fff, 0x00081fff, 0x00081fff, },
-	{ 0x1c5960, 0x00009b40, 0x00009b40, 0x00009b40, 0x00009b40, },
-	{ 0x1c5964, 0x00001120, 0x00001120, 0x00001120, 0x00001120, },
-	{ 0x1c5970, 0x190fb515, 0x190fb515, 0x190fb515, 0x190fb515, },
-	{ 0x1c5974, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-	{ 0x1c5978, 0x00000001, 0x00000001, 0x00000001, 0x00000001, },
-	{ 0x1c597c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-	{ 0x1c5980, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-	{ 0x1c5984, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-	{ 0x1c5988, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-	{ 0x1c598c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-	{ 0x1c5990, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-	{ 0x1c5994, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-	{ 0x1c5998, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-	{ 0x1c599c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-	{ 0x1c59a0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-	{ 0x1c59a4, 0x00000007, 0x00000007, 0x00000007, 0x00000007, },
-	{ 0x1c59a8, 0x001fff00, 0x001fff00, 0x001fff00, 0x001fff00, },
-	{ 0x1c59ac, 0x006f00c4, 0x006f00c4, 0x006f00c4, 0x006f00c4, },
-	{ 0x1c59b0, 0x03051000, 0x03051000, 0x03051000, 0x03051000, },
-	{ 0x1c59b4, 0x00000820, 0x00000820, 0x00000820, 0x00000820, },
-	{ 0x1c59c0, 0x038919be, 0x038919be, 0x038919be, 0x038919be, },
-	{ 0x1c59c4, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77, },
-	{ 0x1c59c8, 0x60f6532c, 0x60f6532c, 0x60f6532c, 0x60f6532c, },
-	{ 0x1c59cc, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8, },
-	{ 0x1c59d0, 0x00046384, 0x00046384, 0x00046384, 0x00046384, },
-	{ 0x1c59d4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-	{ 0x1c59d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-	{ 0x1c59dc, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-	{ 0x1c59e0, 0x00000200, 0x00000200, 0x00000200, 0x00000200, },
-	{ 0x1c59e4, 0x64646464, 0x64646464, 0x64646464, 0x64646464, },
-	{ 0x1c59e8, 0x3c787878, 0x3c787878, 0x3c787878, 0x3c787878, },
-	{ 0x1c59ec, 0x000000aa, 0x000000aa, 0x000000aa, 0x000000aa, },
-	{ 0x1c59f0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-	{ 0x1c59fc, 0x00001042, 0x00001042, 0x00001042, 0x00001042, },
-	{ 0x1c5a00, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-	{ 0x1c5a04, 0x00000040, 0x00000040, 0x00000040, 0x00000040, },
-	{ 0x1c5a08, 0x00000080, 0x00000080, 0x00000080, 0x00000080, },
-	{ 0x1c5a0c, 0x000001a1, 0x000001a1, 0x00000141, 0x00000141, },
-	{ 0x1c5a10, 0x000001e1, 0x000001e1, 0x00000181, 0x00000181, },
-	{ 0x1c5a14, 0x00000021, 0x00000021, 0x000001c1, 0x000001c1, },
-	{ 0x1c5a18, 0x00000061, 0x00000061, 0x00000001, 0x00000001, },
-	{ 0x1c5a1c, 0x00000168, 0x00000168, 0x00000041, 0x00000041, },
-	{ 0x1c5a20, 0x000001a8, 0x000001a8, 0x000001a8, 0x000001a8, },
-	{ 0x1c5a24, 0x000001e8, 0x000001e8, 0x000001e8, 0x000001e8, },
-	{ 0x1c5a28, 0x00000028, 0x00000028, 0x00000028, 0x00000028, },
-	{ 0x1c5a2c, 0x00000068, 0x00000068, 0x00000068, 0x00000068, },
-	{ 0x1c5a30, 0x00000189, 0x00000189, 0x000000a8, 0x000000a8, },
-	{ 0x1c5a34, 0x000001c9, 0x000001c9, 0x00000169, 0x00000169, },
-	{ 0x1c5a38, 0x00000009, 0x00000009, 0x000001a9, 0x000001a9, },
-	{ 0x1c5a3c, 0x00000049, 0x00000049, 0x000001e9, 0x000001e9, },
-	{ 0x1c5a40, 0x00000089, 0x00000089, 0x00000029, 0x00000029, },
-	{ 0x1c5a44, 0x00000170, 0x00000170, 0x00000069, 0x00000069, },
-	{ 0x1c5a48, 0x000001b0, 0x000001b0, 0x00000190, 0x00000190, },
-	{ 0x1c5a4c, 0x000001f0, 0x000001f0, 0x000001d0, 0x000001d0, },
-	{ 0x1c5a50, 0x00000030, 0x00000030, 0x00000010, 0x00000010, },
-	{ 0x1c5a54, 0x00000070, 0x00000070, 0x00000050, 0x00000050, },
-	{ 0x1c5a58, 0x00000191, 0x00000191, 0x00000090, 0x00000090, },
-	{ 0x1c5a5c, 0x000001d1, 0x000001d1, 0x00000151, 0x00000151, },
-	{ 0x1c5a60, 0x00000011, 0x00000011, 0x00000191, 0x00000191, },
-	{ 0x1c5a64, 0x00000051, 0x00000051, 0x000001d1, 0x000001d1, },
-	{ 0x1c5a68, 0x00000091, 0x00000091, 0x00000011, 0x00000011, },
-	{ 0x1c5a6c, 0x000001b8, 0x000001b8, 0x00000051, 0x00000051, },
-	{ 0x1c5a70, 0x000001f8, 0x000001f8, 0x00000198, 0x00000198, },
-	{ 0x1c5a74, 0x00000038, 0x00000038, 0x000001d8, 0x000001d8, },
-	{ 0x1c5a78, 0x00000078, 0x00000078, 0x00000018, 0x00000018, },
-	{ 0x1c5a7c, 0x00000199, 0x00000199, 0x00000058, 0x00000058, },
-	{ 0x1c5a80, 0x000001d9, 0x000001d9, 0x00000098, 0x00000098, },
-	{ 0x1c5a84, 0x00000019, 0x00000019, 0x00000159, 0x00000159, },
-	{ 0x1c5a88, 0x00000059, 0x00000059, 0x00000199, 0x00000199, },
-	{ 0x1c5a8c, 0x00000099, 0x00000099, 0x000001d9, 0x000001d9, },
-	{ 0x1c5a90, 0x000000d9, 0x000000d9, 0x00000019, 0x00000019, },
-	{ 0x1c5a94, 0x000000f9, 0x000000f9, 0x00000059, 0x00000059, },
-	{ 0x1c5a98, 0x000000f9, 0x000000f9, 0x00000099, 0x00000099, },
-	{ 0x1c5a9c, 0x000000f9, 0x000000f9, 0x000000d9, 0x000000d9, },
-	{ 0x1c5aa0, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
-	{ 0x1c5aa4, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
-	{ 0x1c5aa8, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
-	{ 0x1c5aac, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
-	{ 0x1c5ab0, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
-	{ 0x1c5ab4, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
-	{ 0x1c5ab8, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
-	{ 0x1c5abc, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
-	{ 0x1c5ac0, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
-	{ 0x1c5ac4, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
-	{ 0x1c5ac8, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
-	{ 0x1c5acc, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
-	{ 0x1c5ad0, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
-	{ 0x1c5ad4, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
-	{ 0x1c5ad8, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
-	{ 0x1c5adc, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
-	{ 0x1c5ae0, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
-	{ 0x1c5ae4, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
-	{ 0x1c5ae8, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
-	{ 0x1c5aec, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
-	{ 0x1c5af0, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
-	{ 0x1c5af4, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
-	{ 0x1c5af8, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
-	{ 0x1c5afc, 0x000000f9, 0x000000f9, 0x000000f9, 0x000000f9, },
-	{ 0x1c5b00, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-	{ 0x1c5b04, 0x00000001, 0x00000001, 0x00000001, 0x00000001, },
-	{ 0x1c5b08, 0x00000002, 0x00000002, 0x00000002, 0x00000002, },
-	{ 0x1c5b0c, 0x00000003, 0x00000003, 0x00000003, 0x00000003, },
-	{ 0x1c5b10, 0x00000004, 0x00000004, 0x00000004, 0x00000004, },
-	{ 0x1c5b14, 0x00000005, 0x00000005, 0x00000005, 0x00000005, },
-	{ 0x1c5b18, 0x00000008, 0x00000008, 0x00000008, 0x00000008, },
-	{ 0x1c5b1c, 0x00000009, 0x00000009, 0x00000009, 0x00000009, },
-	{ 0x1c5b20, 0x0000000a, 0x0000000a, 0x0000000a, 0x0000000a, },
-	{ 0x1c5b24, 0x0000000b, 0x0000000b, 0x0000000b, 0x0000000b, },
-	{ 0x1c5b28, 0x0000000c, 0x0000000c, 0x0000000c, 0x0000000c, },
-	{ 0x1c5b2c, 0x0000000d, 0x0000000d, 0x0000000d, 0x0000000d, },
-	{ 0x1c5b30, 0x00000010, 0x00000010, 0x00000010, 0x00000010, },
-	{ 0x1c5b34, 0x00000011, 0x00000011, 0x00000011, 0x00000011, },
-	{ 0x1c5b38, 0x00000012, 0x00000012, 0x00000012, 0x00000012, },
-	{ 0x1c5b3c, 0x00000013, 0x00000013, 0x00000013, 0x00000013, },
-	{ 0x1c5b40, 0x00000014, 0x00000014, 0x00000014, 0x00000014, },
-	{ 0x1c5b44, 0x00000015, 0x00000015, 0x00000015, 0x00000015, },
-	{ 0x1c5b48, 0x00000018, 0x00000018, 0x00000018, 0x00000018, },
-	{ 0x1c5b4c, 0x00000019, 0x00000019, 0x00000019, 0x00000019, },
-	{ 0x1c5b50, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a, },
-	{ 0x1c5b54, 0x0000001b, 0x0000001b, 0x0000001b, 0x0000001b, },
-	{ 0x1c5b58, 0x0000001c, 0x0000001c, 0x0000001c, 0x0000001c, },
-	{ 0x1c5b5c, 0x0000001d, 0x0000001d, 0x0000001d, 0x0000001d, },
-	{ 0x1c5b60, 0x00000020, 0x00000020, 0x00000020, 0x00000020, },
-	{ 0x1c5b64, 0x00000021, 0x00000021, 0x00000021, 0x00000021, },
-	{ 0x1c5b68, 0x00000022, 0x00000022, 0x00000022, 0x00000022, },
-	{ 0x1c5b6c, 0x00000023, 0x00000023, 0x00000023, 0x00000023, },
-	{ 0x1c5b70, 0x00000024, 0x00000024, 0x00000024, 0x00000024, },
-	{ 0x1c5b74, 0x00000025, 0x00000025, 0x00000025, 0x00000025, },
-	{ 0x1c5b78, 0x00000028, 0x00000028, 0x00000028, 0x00000028, },
-	{ 0x1c5b7c, 0x00000029, 0x00000029, 0x00000029, 0x00000029, },
-	{ 0x1c5b80, 0x0000002a, 0x0000002a, 0x0000002a, 0x0000002a, },
-	{ 0x1c5b84, 0x0000002b, 0x0000002b, 0x0000002b, 0x0000002b, },
-	{ 0x1c5b88, 0x0000002c, 0x0000002c, 0x0000002c, 0x0000002c, },
-	{ 0x1c5b8c, 0x0000002d, 0x0000002d, 0x0000002d, 0x0000002d, },
-	{ 0x1c5b90, 0x00000030, 0x00000030, 0x00000030, 0x00000030, },
-	{ 0x1c5b94, 0x00000031, 0x00000031, 0x00000031, 0x00000031, },
-	{ 0x1c5b98, 0x00000032, 0x00000032, 0x00000032, 0x00000032, },
-	{ 0x1c5b9c, 0x00000033, 0x00000033, 0x00000033, 0x00000033, },
-	{ 0x1c5ba0, 0x00000034, 0x00000034, 0x00000034, 0x00000034, },
-	{ 0x1c5ba4, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
-	{ 0x1c5ba8, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
-	{ 0x1c5bac, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
-	{ 0x1c5bb0, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
-	{ 0x1c5bb4, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
-	{ 0x1c5bb8, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
-	{ 0x1c5bbc, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
-	{ 0x1c5bc0, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
-	{ 0x1c5bc4, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
-	{ 0x1c5bc8, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
-	{ 0x1c5bcc, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
-	{ 0x1c5bd0, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
-	{ 0x1c5bd4, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
-	{ 0x1c5bd8, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
-	{ 0x1c5bdc, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
-	{ 0x1c5be0, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
-	{ 0x1c5be4, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
-	{ 0x1c5be8, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
-	{ 0x1c5bec, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
-	{ 0x1c5bf0, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
-	{ 0x1c5bf4, 0x00000035, 0x00000035, 0x00000035, 0x00000035, },
-	{ 0x1c5bf8, 0x00000010, 0x00000010, 0x00000010, 0x00000010, },
-	{ 0x1c5bfc, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a, },
-	{ 0x1c5c00, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-	{ 0x1c5c0c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-	{ 0x1c5c10, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-	{ 0x1c5c14, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-	{ 0x1c5c18, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-	{ 0x1c5c1c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-	{ 0x1c5c20, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-	{ 0x1c5c24, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-	{ 0x1c5c28, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-	{ 0x1c5c2c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-	{ 0x1c5c30, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-	{ 0x1c5c34, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-	{ 0x1c5c38, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-	{ 0x1c5c3c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-	{ 0x1c5cf0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-	{ 0x1c5cf4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-	{ 0x1c5cf8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-	{ 0x1c5cfc, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-	{ 0x1c6200, 0x00000008, 0x00000008, 0x0000000e, 0x0000000e, },
-	{ 0x1c6204, 0x00000440, 0x00000440, 0x00000440, 0x00000440, },
-	{ 0x1c6208, 0xd6be4788, 0xd6be4788, 0xd03e4788, 0xd03e4788, },
-	{ 0x1c620c, 0x012e8160, 0x012e8160, 0x012a8160, 0x012a8160, },
-	{ 0x1c6210, 0x40806333, 0x40806333, 0x40806333, 0x40806333, },
-	{ 0x1c6214, 0x00106c10, 0x00106c10, 0x00106c10, 0x00106c10, },
-	{ 0x1c6218, 0x009c4060, 0x009c4060, 0x009c4060, 0x009c4060, },
-	{ 0x1c621c, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a, },
-	{ 0x1c6220, 0x018830c6, 0x018830c6, 0x018830c6, 0x018830c6, },
-	{ 0x1c6224, 0x00000400, 0x00000400, 0x00000400, 0x00000400, },
-	{ 0x1c6228, 0x000009b5, 0x000009b5, 0x000009b5, 0x000009b5, },
-	{ 0x1c622c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-	{ 0x1c6230, 0x00000108, 0x00000210, 0x00000210, 0x00000108, },
-	{ 0x1c6234, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, },
-	{ 0x1c6238, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, },
-	{ 0x1c623c, 0x13c889af, 0x13c889af, 0x13c889af, 0x13c889af, },
-	{ 0x1c6240, 0x38490a20, 0x38490a20, 0x38490a20, 0x38490a20, },
-	{ 0x1c6244, 0x00007bb6, 0x00007bb6, 0x00007bb6, 0x00007bb6, },
-	{ 0x1c6248, 0x0fff3ffc, 0x0fff3ffc, 0x0fff3ffc, 0x0fff3ffc, },
-	{ 0x1c624c, 0x00000001, 0x00000001, 0x00000001, 0x00000001, },
-	{ 0x1c6250, 0x0000a000, 0x0000a000, 0x0000a000, 0x0000a000, },
-	{ 0x1c6254, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-	{ 0x1c6258, 0x0cc75380, 0x0cc75380, 0x0cc75380, 0x0cc75380, },
-	{ 0x1c625c, 0x0f0f0f01, 0x0f0f0f01, 0x0f0f0f01, 0x0f0f0f01, },
-	{ 0x1c6260, 0xdfa91f01, 0xdfa91f01, 0xdfa91f01, 0xdfa91f01, },
-	{ 0x1c6264, 0x00418a11, 0x00418a11, 0x00418a11, 0x00418a11, },
-	{ 0x1c6268, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-	{ 0x1c626c, 0x09249126, 0x09249126, 0x09249126, 0x09249126, },
-	{ 0x1c6274, 0x0a1a9caa, 0x0a1a9caa, 0x0a1a7caa, 0x0a1a7caa, },
-	{ 0x1c6278, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, },
-	{ 0x1c627c, 0x051701ce, 0x051701ce, 0x051701ce, 0x051701ce, },
-	{ 0x1c6300, 0x18010000, 0x18010000, 0x18010000, 0x18010000, },
-	{ 0x1c6304, 0x30032602, 0x30032602, 0x2e032402, 0x2e032402, },
-	{ 0x1c6308, 0x48073e06, 0x48073e06, 0x4a0a3c06, 0x4a0a3c06, },
-	{ 0x1c630c, 0x560b4c0a, 0x560b4c0a, 0x621a540b, 0x621a540b, },
-	{ 0x1c6310, 0x641a600f, 0x641a600f, 0x764f6c1b, 0x764f6c1b, },
-	{ 0x1c6314, 0x7a4f6e1b, 0x7a4f6e1b, 0x845b7a5a, 0x845b7a5a, },
-	{ 0x1c6318, 0x8c5b7e5a, 0x8c5b7e5a, 0x950f8ccf, 0x950f8ccf, },
-	{ 0x1c631c, 0x9d0f96cf, 0x9d0f96cf, 0xa5cf9b4f, 0xa5cf9b4f, },
-	{ 0x1c6320, 0xb51fa69f, 0xb51fa69f, 0xbddfaf1f, 0xbddfaf1f, },
-	{ 0x1c6324, 0xcb3fbd07, 0xcb3fbcbf, 0xd1ffc93f, 0xd1ffc93f, },
-	{ 0x1c6328, 0x0000d7bf, 0x0000d7bf, 0x00000000, 0x00000000, },
-	{ 0x1c632c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-	{ 0x1c6330, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-	{ 0x1c6334, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-	{ 0x1c6338, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-	{ 0x1c633c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-	{ 0x1c6340, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-	{ 0x1c6344, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-	{ 0x1c6348, 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff, },
-	{ 0x1c634c, 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff, },
-	{ 0x1c6350, 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff, },
-	{ 0x1c6354, 0x0003ffff, 0x0003ffff, 0x0003ffff, 0x0003ffff, },
-	{ 0x1c6358, 0x79a8aa1f, 0x79a8aa1f, 0x79a8aa1f, 0x79a8aa1f, },
-	{ 0x1c6388, 0x08000000, 0x08000000, 0x08000000, 0x08000000, },
-	{ 0x1c638c, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, },
-	{ 0x1c6390, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, },
-	{ 0x1c6394, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, },
-	{ 0x1c6398, 0x000001ce, 0x000001ce, 0x000001ce, 0x000001ce, },
-	{ 0x1c639c, 0x00000007, 0x00000007, 0x00000007, 0x00000007, },
-	{ 0x1c63a0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-	{ 0x1c63a4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-	{ 0x1c63a8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-	{ 0x1c63ac, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-	{ 0x1c63b0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-	{ 0x1c63b4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-	{ 0x1c63b8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-	{ 0x1c63bc, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-	{ 0x1c63c0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-	{ 0x1c63c4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-	{ 0x1c63c8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-	{ 0x1c63cc, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, },
-	{ 0x1c63d0, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, },
-	{ 0x1c63d4, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, 0x3f3f3f3f, },
-	{ 0x1c63d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, },
-	{ 0x1c63dc, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, },
-	{ 0x1c63e0, 0x000000c0, 0x000000c0, 0x000000c0, 0x000000c0, },
-	{ 0x1c6848, 0x00180a65, 0x00180a65, 0x00180a68, 0x00180a68, },
-	{ 0x1c6920, 0x0510001c, 0x0510001c, 0x0510001c, 0x0510001c, },
-	{ 0x1c6960, 0x00009b40, 0x00009b40, 0x00009b40, 0x00009b40, },
-	{ 0x1c720c, 0x012e8160, 0x012e8160, 0x012a8160, 0x012a8160, },
-	{ 0x1c726c, 0x09249126, 0x09249126, 0x09249126, 0x09249126, },
-	{ 0x1c7848, 0x00180a65, 0x00180a65, 0x00180a68, 0x00180a68, },
-	{ 0x1c7920, 0x0510001c, 0x0510001c, 0x0510001c, 0x0510001c, },
-	{ 0x1c7960, 0x00009b40, 0x00009b40, 0x00009b40, 0x00009b40, },
-	{ 0x1c820c, 0x012e8160, 0x012e8160, 0x012a8160, 0x012a8160, },
-	{ 0x1c826c, 0x09249126, 0x09249126, 0x09249126, 0x09249126, },
-/*	{ 0x1c8864, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00, }, */
-	{ 0x1c8864, 0x0001c600, 0x0001c600, 0x0001c600, 0x0001c600, },
-	{ 0x1c895c, 0x004b6a8e, 0x004b6a8e, 0x004b6a8e, 0x004b6a8e, },
-	{ 0x1c8968, 0x000003ce, 0x000003ce, 0x000003ce, 0x000003ce, },
-	{ 0x1c89bc, 0x00181400, 0x00181400, 0x00181400, 0x00181400, },
-	{ 0x1c9270, 0x00820820, 0x00820820, 0x00820820, 0x00820820, },
-	{ 0x1c935c, 0x066c420f, 0x066c420f, 0x066c420f, 0x066c420f, },
-	{ 0x1c9360, 0x0f282207, 0x0f282207, 0x0f282207, 0x0f282207, },
-	{ 0x1c9364, 0x17601685, 0x17601685, 0x17601685, 0x17601685, },
-	{ 0x1c9368, 0x1f801104, 0x1f801104, 0x1f801104, 0x1f801104, },
-	{ 0x1c936c, 0x37a00c03, 0x37a00c03, 0x37a00c03, 0x37a00c03, },
-	{ 0x1c9370, 0x3fc40883, 0x3fc40883, 0x3fc40883, 0x3fc40883, },
-	{ 0x1c9374, 0x57c00803, 0x57c00803, 0x57c00803, 0x57c00803, },
-	{ 0x1c9378, 0x5fd80682, 0x5fd80682, 0x5fd80682, 0x5fd80682, },
-	{ 0x1c937c, 0x7fe00482, 0x7fe00482, 0x7fe00482, 0x7fe00482, },
-	{ 0x1c9380, 0x7f3c7bba, 0x7f3c7bba, 0x7f3c7bba, 0x7f3c7bba, },
-	{ 0x1c9384, 0xf3307ff0, 0xf3307ff0, 0xf3307ff0, 0xf3307ff0, }
-};
-
-/*
- * look up a certain register in ar5416_phy_init[] and return the init. value
- * for the band and bandwidth given. Return 0 if register address not found.
- */
-static u32 ar9170_get_default_phy_reg_val(u32 reg, bool is_2ghz, bool is_40mhz)
-{
-	unsigned int i;
-	for (i = 0; i < ARRAY_SIZE(ar5416_phy_init); i++) {
-		if (ar5416_phy_init[i].reg != reg)
-			continue;
-
-		if (is_2ghz) {
-			if (is_40mhz)
-				return ar5416_phy_init[i]._2ghz_40;
-			else
-				return ar5416_phy_init[i]._2ghz_20;
-		} else {
-			if (is_40mhz)
-				return ar5416_phy_init[i]._5ghz_40;
-			else
-				return ar5416_phy_init[i]._5ghz_20;
-		}
-	}
-	return 0;
-}
-
-/*
- * initialize some phy regs from eeprom values in modal_header[]
- * acc. to band and bandwidth
- */
-static int ar9170_init_phy_from_eeprom(struct ar9170 *ar,
-				bool is_2ghz, bool is_40mhz)
-{
-	static const u8 xpd2pd[16] = {
-		0x2, 0x2, 0x2, 0x1, 0x2, 0x2, 0x6, 0x2,
-		0x2, 0x3, 0x7, 0x2, 0xB, 0x2, 0x2, 0x2
-	};
-	u32 defval, newval;
-	/* pointer to the modal_header acc. to band */
-	struct ar9170_eeprom_modal *m = &ar->eeprom.modal_header[is_2ghz];
-
-	ar9170_regwrite_begin(ar);
-
-	/* ant common control (index 0) */
-	newval = le32_to_cpu(m->antCtrlCommon);
-	ar9170_regwrite(0x1c5964, newval);
-
-	/* ant control chain 0 (index 1) */
-	newval = le32_to_cpu(m->antCtrlChain[0]);
-	ar9170_regwrite(0x1c5960, newval);
-
-	/* ant control chain 2 (index 2) */
-	newval = le32_to_cpu(m->antCtrlChain[1]);
-	ar9170_regwrite(0x1c7960, newval);
-
-	/* SwSettle (index 3) */
-	if (!is_40mhz) {
-		defval = ar9170_get_default_phy_reg_val(0x1c5844,
-							is_2ghz, is_40mhz);
-		newval = (defval & ~0x3f80) |
-			((m->switchSettling & 0x7f) << 7);
-		ar9170_regwrite(0x1c5844, newval);
-	}
-
-	/* adcDesired, pdaDesired (index 4) */
-	defval = ar9170_get_default_phy_reg_val(0x1c5850, is_2ghz, is_40mhz);
-	newval = (defval & ~0xffff) | ((u8)m->pgaDesiredSize << 8) |
-		((u8)m->adcDesiredSize);
-	ar9170_regwrite(0x1c5850, newval);
-
-	/* TxEndToXpaOff, TxFrameToXpaOn (index 5) */
-	defval = ar9170_get_default_phy_reg_val(0x1c5834, is_2ghz, is_40mhz);
-	newval = (m->txEndToXpaOff << 24) | (m->txEndToXpaOff << 16) |
-		(m->txFrameToXpaOn << 8) | m->txFrameToXpaOn;
-	ar9170_regwrite(0x1c5834, newval);
-
-	/* TxEndToRxOn (index 6) */
-	defval = ar9170_get_default_phy_reg_val(0x1c5828, is_2ghz, is_40mhz);
-	newval = (defval & ~0xff0000) | (m->txEndToRxOn << 16);
-	ar9170_regwrite(0x1c5828, newval);
-
-	/* thresh62 (index 7) */
-	defval = ar9170_get_default_phy_reg_val(0x1c8864, is_2ghz, is_40mhz);
-	newval = (defval & ~0x7f000) | (m->thresh62 << 12);
-	ar9170_regwrite(0x1c8864, newval);
-
-	/* tx/rx attenuation chain 0 (index 8) */
-	defval = ar9170_get_default_phy_reg_val(0x1c5848, is_2ghz, is_40mhz);
-	newval = (defval & ~0x3f000) | ((m->txRxAttenCh[0] & 0x3f) << 12);
-	ar9170_regwrite(0x1c5848, newval);
-
-	/* tx/rx attenuation chain 2 (index 9) */
-	defval = ar9170_get_default_phy_reg_val(0x1c7848, is_2ghz, is_40mhz);
-	newval = (defval & ~0x3f000) | ((m->txRxAttenCh[1] & 0x3f) << 12);
-	ar9170_regwrite(0x1c7848, newval);
-
-	/* tx/rx margin chain 0 (index 10) */
-	defval = ar9170_get_default_phy_reg_val(0x1c620c, is_2ghz, is_40mhz);
-	newval = (defval & ~0xfc0000) | ((m->rxTxMarginCh[0] & 0x3f) << 18);
-	/* bsw margin chain 0 for 5GHz only */
-	if (!is_2ghz)
-		newval = (newval & ~0x3c00) | ((m->bswMargin[0] & 0xf) << 10);
-	ar9170_regwrite(0x1c620c, newval);
-
-	/* tx/rx margin chain 2 (index 11) */
-	defval = ar9170_get_default_phy_reg_val(0x1c820c, is_2ghz, is_40mhz);
-	newval = (defval & ~0xfc0000) | ((m->rxTxMarginCh[1] & 0x3f) << 18);
-	ar9170_regwrite(0x1c820c, newval);
-
-	/* iqCall, iqCallq chain 0 (index 12) */
-	defval = ar9170_get_default_phy_reg_val(0x1c5920, is_2ghz, is_40mhz);
-	newval = (defval & ~0x7ff) | (((u8)m->iqCalICh[0] & 0x3f) << 5) |
-		((u8)m->iqCalQCh[0] & 0x1f);
-	ar9170_regwrite(0x1c5920, newval);
-
-	/* iqCall, iqCallq chain 2 (index 13) */
-	defval = ar9170_get_default_phy_reg_val(0x1c7920, is_2ghz, is_40mhz);
-	newval = (defval & ~0x7ff) | (((u8)m->iqCalICh[1] & 0x3f) << 5) |
-		((u8)m->iqCalQCh[1] & 0x1f);
-	ar9170_regwrite(0x1c7920, newval);
-
-	/* xpd gain mask (index 14) */
-	defval = ar9170_get_default_phy_reg_val(0x1c6258, is_2ghz, is_40mhz);
-	newval = (defval & ~0xf0000) | (xpd2pd[m->xpdGain & 0xf] << 16);
-	ar9170_regwrite(0x1c6258, newval);
-	ar9170_regwrite_finish();
-
-	return ar9170_regwrite_result();
-}
-
-int ar9170_init_phy(struct ar9170 *ar, enum ieee80211_band band)
-{
-	int i, err;
-	u32 val;
-	bool is_2ghz = band == IEEE80211_BAND_2GHZ;
-	bool is_40mhz = conf_is_ht40(&ar->hw->conf);
-
-	ar9170_regwrite_begin(ar);
-
-	for (i = 0; i < ARRAY_SIZE(ar5416_phy_init); i++) {
-		if (is_40mhz) {
-			if (is_2ghz)
-				val = ar5416_phy_init[i]._2ghz_40;
-			else
-				val = ar5416_phy_init[i]._5ghz_40;
-		} else {
-			if (is_2ghz)
-				val = ar5416_phy_init[i]._2ghz_20;
-			else
-				val = ar5416_phy_init[i]._5ghz_20;
-		}
-
-		ar9170_regwrite(ar5416_phy_init[i].reg, val);
-	}
-
-	ar9170_regwrite_finish();
-	err = ar9170_regwrite_result();
-	if (err)
-		return err;
-
-	err = ar9170_init_phy_from_eeprom(ar, is_2ghz, is_40mhz);
-	if (err)
-		return err;
-
-	err = ar9170_init_power_cal(ar);
-	if (err)
-		return err;
-
-	/* XXX: remove magic! */
-	if (is_2ghz)
-		err = ar9170_write_reg(ar, 0x1d4014, 0x5163);
-	else
-		err = ar9170_write_reg(ar, 0x1d4014, 0x5143);
-
-	return err;
-}
-
-struct ar9170_rf_init {
-	u32 reg, _5ghz, _2ghz;
-};
-
-static struct ar9170_rf_init ar9170_rf_init[] = {
-     /* bank 0 */
-     { 0x1c58b0,  0x1e5795e5,  0x1e5795e5},
-     { 0x1c58e0,  0x02008020,  0x02008020},
-     /* bank 1 */
-     { 0x1c58b0,  0x02108421,  0x02108421},
-     { 0x1c58ec,  0x00000008,  0x00000008},
-     /* bank 2 */
-     { 0x1c58b0,  0x0e73ff17,  0x0e73ff17},
-     { 0x1c58e0,  0x00000420,  0x00000420},
-     /* bank 3 */
-     { 0x1c58f0,  0x01400018,  0x01c00018},
-     /* bank 4 */
-     { 0x1c58b0,  0x000001a1,  0x000001a1},
-     { 0x1c58e8,  0x00000001,  0x00000001},
-     /* bank 5 */
-     { 0x1c58b0,  0x00000013,  0x00000013},
-     { 0x1c58e4,  0x00000002,  0x00000002},
-     /* bank 6 */
-     { 0x1c58b0,  0x00000000,  0x00000000},
-     { 0x1c58b0,  0x00000000,  0x00000000},
-     { 0x1c58b0,  0x00000000,  0x00000000},
-     { 0x1c58b0,  0x00000000,  0x00000000},
-     { 0x1c58b0,  0x00000000,  0x00000000},
-     { 0x1c58b0,  0x00004000,  0x00004000},
-     { 0x1c58b0,  0x00006c00,  0x00006c00},
-     { 0x1c58b0,  0x00002c00,  0x00002c00},
-     { 0x1c58b0,  0x00004800,  0x00004800},
-     { 0x1c58b0,  0x00004000,  0x00004000},
-     { 0x1c58b0,  0x00006000,  0x00006000},
-     { 0x1c58b0,  0x00001000,  0x00001000},
-     { 0x1c58b0,  0x00004000,  0x00004000},
-     { 0x1c58b0,  0x00007c00,  0x00007c00},
-     { 0x1c58b0,  0x00007c00,  0x00007c00},
-     { 0x1c58b0,  0x00007c00,  0x00007c00},
-     { 0x1c58b0,  0x00007c00,  0x00007c00},
-     { 0x1c58b0,  0x00007c00,  0x00007c00},
-     { 0x1c58b0,  0x00087c00,  0x00087c00},
-     { 0x1c58b0,  0x00007c00,  0x00007c00},
-     { 0x1c58b0,  0x00005400,  0x00005400},
-     { 0x1c58b0,  0x00000c00,  0x00000c00},
-     { 0x1c58b0,  0x00001800,  0x00001800},
-     { 0x1c58b0,  0x00007c00,  0x00007c00},
-     { 0x1c58b0,  0x00006c00,  0x00006c00},
-     { 0x1c58b0,  0x00006c00,  0x00006c00},
-     { 0x1c58b0,  0x00007c00,  0x00007c00},
-     { 0x1c58b0,  0x00002c00,  0x00002c00},
-     { 0x1c58b0,  0x00003c00,  0x00003c00},
-     { 0x1c58b0,  0x00003800,  0x00003800},
-     { 0x1c58b0,  0x00001c00,  0x00001c00},
-     { 0x1c58b0,  0x00000800,  0x00000800},
-     { 0x1c58b0,  0x00000408,  0x00000408},
-     { 0x1c58b0,  0x00004c15,  0x00004c15},
-     { 0x1c58b0,  0x00004188,  0x00004188},
-     { 0x1c58b0,  0x0000201e,  0x0000201e},
-     { 0x1c58b0,  0x00010408,  0x00010408},
-     { 0x1c58b0,  0x00000801,  0x00000801},
-     { 0x1c58b0,  0x00000c08,  0x00000c08},
-     { 0x1c58b0,  0x0000181e,  0x0000181e},
-     { 0x1c58b0,  0x00001016,  0x00001016},
-     { 0x1c58b0,  0x00002800,  0x00002800},
-     { 0x1c58b0,  0x00004010,  0x00004010},
-     { 0x1c58b0,  0x0000081c,  0x0000081c},
-     { 0x1c58b0,  0x00000115,  0x00000115},
-     { 0x1c58b0,  0x00000015,  0x00000015},
-     { 0x1c58b0,  0x00000066,  0x00000066},
-     { 0x1c58b0,  0x0000001c,  0x0000001c},
-     { 0x1c58b0,  0x00000000,  0x00000000},
-     { 0x1c58b0,  0x00000004,  0x00000004},
-     { 0x1c58b0,  0x00000015,  0x00000015},
-     { 0x1c58b0,  0x0000001f,  0x0000001f},
-     { 0x1c58e0,  0x00000000,  0x00000400},
-     /* bank 7 */
-     { 0x1c58b0,  0x000000a0,  0x000000a0},
-     { 0x1c58b0,  0x00000000,  0x00000000},
-     { 0x1c58b0,  0x00000040,  0x00000040},
-     { 0x1c58f0,  0x0000001c,  0x0000001c},
-};
-
-static int ar9170_init_rf_banks_0_7(struct ar9170 *ar, bool band5ghz)
-{
-	int err, i;
-
-	ar9170_regwrite_begin(ar);
-
-	for (i = 0; i < ARRAY_SIZE(ar9170_rf_init); i++)
-		ar9170_regwrite(ar9170_rf_init[i].reg,
-				band5ghz ? ar9170_rf_init[i]._5ghz
-					 : ar9170_rf_init[i]._2ghz);
-
-	ar9170_regwrite_finish();
-	err = ar9170_regwrite_result();
-	if (err)
-		wiphy_err(ar->hw->wiphy, "rf init failed\n");
-	return err;
-}
-
-static int ar9170_init_rf_bank4_pwr(struct ar9170 *ar, bool band5ghz,
-				    u32 freq, enum ar9170_bw bw)
-{
-	int err;
-	u32 d0, d1, td0, td1, fd0, fd1;
-	u8 chansel;
-	u8 refsel0 = 1, refsel1 = 0;
-	u8 lf_synth = 0;
-
-	switch (bw) {
-	case AR9170_BW_40_ABOVE:
-		freq += 10;
-		break;
-	case AR9170_BW_40_BELOW:
-		freq -= 10;
-		break;
-	case AR9170_BW_20:
-		break;
-	case __AR9170_NUM_BW:
-		BUG();
-	}
-
-	if (band5ghz) {
-		if (freq % 10) {
-			chansel = (freq - 4800) / 5;
-		} else {
-			chansel = ((freq - 4800) / 10) * 2;
-			refsel0 = 0;
-			refsel1 = 1;
-		}
-		chansel = byte_rev_table[chansel];
-	} else {
-		if (freq == 2484) {
-			chansel = 10 + (freq - 2274) / 5;
-			lf_synth = 1;
-		} else
-			chansel = 16 + (freq - 2272) / 5;
-		chansel *= 4;
-		chansel = byte_rev_table[chansel];
-	}
-
-	d1 =	chansel;
-	d0 =	0x21 |
-		refsel0 << 3 |
-		refsel1 << 2 |
-		lf_synth << 1;
-	td0 =	d0 & 0x1f;
-	td1 =	d1 & 0x1f;
-	fd0 =	td1 << 5 | td0;
-
-	td0 =	(d0 >> 5) & 0x7;
-	td1 =	(d1 >> 5) & 0x7;
-	fd1 =	td1 << 5 | td0;
-
-	ar9170_regwrite_begin(ar);
-
-	ar9170_regwrite(0x1c58b0, fd0);
-	ar9170_regwrite(0x1c58e8, fd1);
-
-	ar9170_regwrite_finish();
-	err = ar9170_regwrite_result();
-	if (err)
-		return err;
-
-	msleep(10);
-
-	return 0;
-}
-
-struct ar9170_phy_freq_params {
-	u8 coeff_exp;
-	u16 coeff_man;
-	u8 coeff_exp_shgi;
-	u16 coeff_man_shgi;
-};
-
-struct ar9170_phy_freq_entry {
-	u16 freq;
-	struct ar9170_phy_freq_params params[__AR9170_NUM_BW];
-};
-
-/* NB: must be in sync with channel tables in main! */
-static const struct ar9170_phy_freq_entry ar9170_phy_freq_params[] = {
-/*
- *	freq,
- *		20MHz,
- *		40MHz (below),
- *		40Mhz (above),
- */
-	{ 2412, {
-		{ 3, 21737, 3, 19563, },
-		{ 3, 21827, 3, 19644, },
-		{ 3, 21647, 3, 19482, },
-	} },
-	{ 2417, {
-		{ 3, 21692, 3, 19523, },
-		{ 3, 21782, 3, 19604, },
-		{ 3, 21602, 3, 19442, },
-	} },
-	{ 2422, {
-		{ 3, 21647, 3, 19482, },
-		{ 3, 21737, 3, 19563, },
-		{ 3, 21558, 3, 19402, },
-	} },
-	{ 2427, {
-		{ 3, 21602, 3, 19442, },
-		{ 3, 21692, 3, 19523, },
-		{ 3, 21514, 3, 19362, },
-	} },
-	{ 2432, {
-		{ 3, 21558, 3, 19402, },
-		{ 3, 21647, 3, 19482, },
-		{ 3, 21470, 3, 19323, },
-	} },
-	{ 2437, {
-		{ 3, 21514, 3, 19362, },
-		{ 3, 21602, 3, 19442, },
-		{ 3, 21426, 3, 19283, },
-	} },
-	{ 2442, {
-		{ 3, 21470, 3, 19323, },
-		{ 3, 21558, 3, 19402, },
-		{ 3, 21382, 3, 19244, },
-	} },
-	{ 2447, {
-		{ 3, 21426, 3, 19283, },
-		{ 3, 21514, 3, 19362, },
-		{ 3, 21339, 3, 19205, },
-	} },
-	{ 2452, {
-		{ 3, 21382, 3, 19244, },
-		{ 3, 21470, 3, 19323, },
-		{ 3, 21295, 3, 19166, },
-	} },
-	{ 2457, {
-		{ 3, 21339, 3, 19205, },
-		{ 3, 21426, 3, 19283, },
-		{ 3, 21252, 3, 19127, },
-	} },
-	{ 2462, {
-		{ 3, 21295, 3, 19166, },
-		{ 3, 21382, 3, 19244, },
-		{ 3, 21209, 3, 19088, },
-	} },
-	{ 2467, {
-		{ 3, 21252, 3, 19127, },
-		{ 3, 21339, 3, 19205, },
-		{ 3, 21166, 3, 19050, },
-	} },
-	{ 2472, {
-		{ 3, 21209, 3, 19088, },
-		{ 3, 21295, 3, 19166, },
-		{ 3, 21124, 3, 19011, },
-	} },
-	{ 2484, {
-		{ 3, 21107, 3, 18996, },
-		{ 3, 21192, 3, 19073, },
-		{ 3, 21022, 3, 18920, },
-	} },
-	{ 4920, {
-		{ 4, 21313, 4, 19181, },
-		{ 4, 21356, 4, 19220, },
-		{ 4, 21269, 4, 19142, },
-	} },
-	{ 4940, {
-		{ 4, 21226, 4, 19104, },
-		{ 4, 21269, 4, 19142, },
-		{ 4, 21183, 4, 19065, },
-	} },
-	{ 4960, {
-		{ 4, 21141, 4, 19027, },
-		{ 4, 21183, 4, 19065, },
-		{ 4, 21098, 4, 18988, },
-	} },
-	{ 4980, {
-		{ 4, 21056, 4, 18950, },
-		{ 4, 21098, 4, 18988, },
-		{ 4, 21014, 4, 18912, },
-	} },
-	{ 5040, {
-		{ 4, 20805, 4, 18725, },
-		{ 4, 20846, 4, 18762, },
-		{ 4, 20764, 4, 18687, },
-	} },
-	{ 5060, {
-		{ 4, 20723, 4, 18651, },
-		{ 4, 20764, 4, 18687, },
-		{ 4, 20682, 4, 18614, },
-	} },
-	{ 5080, {
-		{ 4, 20641, 4, 18577, },
-		{ 4, 20682, 4, 18614, },
-		{ 4, 20601, 4, 18541, },
-	} },
-	{ 5180, {
-		{ 4, 20243, 4, 18219, },
-		{ 4, 20282, 4, 18254, },
-		{ 4, 20204, 4, 18183, },
-	} },
-	{ 5200, {
-		{ 4, 20165, 4, 18148, },
-		{ 4, 20204, 4, 18183, },
-		{ 4, 20126, 4, 18114, },
-	} },
-	{ 5220, {
-		{ 4, 20088, 4, 18079, },
-		{ 4, 20126, 4, 18114, },
-		{ 4, 20049, 4, 18044, },
-	} },
-	{ 5240, {
-		{ 4, 20011, 4, 18010, },
-		{ 4, 20049, 4, 18044, },
-		{ 4, 19973, 4, 17976, },
-	} },
-	{ 5260, {
-		{ 4, 19935, 4, 17941, },
-		{ 4, 19973, 4, 17976, },
-		{ 4, 19897, 4, 17907, },
-	} },
-	{ 5280, {
-		{ 4, 19859, 4, 17873, },
-		{ 4, 19897, 4, 17907, },
-		{ 4, 19822, 4, 17840, },
-	} },
-	{ 5300, {
-		{ 4, 19784, 4, 17806, },
-		{ 4, 19822, 4, 17840, },
-		{ 4, 19747, 4, 17772, },
-	} },
-	{ 5320, {
-		{ 4, 19710, 4, 17739, },
-		{ 4, 19747, 4, 17772, },
-		{ 4, 19673, 4, 17706, },
-	} },
-	{ 5500, {
-		{ 4, 19065, 4, 17159, },
-		{ 4, 19100, 4, 17190, },
-		{ 4, 19030, 4, 17127, },
-	} },
-	{ 5520, {
-		{ 4, 18996, 4, 17096, },
-		{ 4, 19030, 4, 17127, },
-		{ 4, 18962, 4, 17065, },
-	} },
-	{ 5540, {
-		{ 4, 18927, 4, 17035, },
-		{ 4, 18962, 4, 17065, },
-		{ 4, 18893, 4, 17004, },
-	} },
-	{ 5560, {
-		{ 4, 18859, 4, 16973, },
-		{ 4, 18893, 4, 17004, },
-		{ 4, 18825, 4, 16943, },
-	} },
-	{ 5580, {
-		{ 4, 18792, 4, 16913, },
-		{ 4, 18825, 4, 16943, },
-		{ 4, 18758, 4, 16882, },
-	} },
-	{ 5600, {
-		{ 4, 18725, 4, 16852, },
-		{ 4, 18758, 4, 16882, },
-		{ 4, 18691, 4, 16822, },
-	} },
-	{ 5620, {
-		{ 4, 18658, 4, 16792, },
-		{ 4, 18691, 4, 16822, },
-		{ 4, 18625, 4, 16762, },
-	} },
-	{ 5640, {
-		{ 4, 18592, 4, 16733, },
-		{ 4, 18625, 4, 16762, },
-		{ 4, 18559, 4, 16703, },
-	} },
-	{ 5660, {
-		{ 4, 18526, 4, 16673, },
-		{ 4, 18559, 4, 16703, },
-		{ 4, 18493, 4, 16644, },
-	} },
-	{ 5680, {
-		{ 4, 18461, 4, 16615, },
-		{ 4, 18493, 4, 16644, },
-		{ 4, 18428, 4, 16586, },
-	} },
-	{ 5700, {
-		{ 4, 18396, 4, 16556, },
-		{ 4, 18428, 4, 16586, },
-		{ 4, 18364, 4, 16527, },
-	} },
-	{ 5745, {
-		{ 4, 18252, 4, 16427, },
-		{ 4, 18284, 4, 16455, },
-		{ 4, 18220, 4, 16398, },
-	} },
-	{ 5765, {
-		{ 4, 18189, 5, 32740, },
-		{ 4, 18220, 4, 16398, },
-		{ 4, 18157, 5, 32683, },
-	} },
-	{ 5785, {
-		{ 4, 18126, 5, 32626, },
-		{ 4, 18157, 5, 32683, },
-		{ 4, 18094, 5, 32570, },
-	} },
-	{ 5805, {
-		{ 4, 18063, 5, 32514, },
-		{ 4, 18094, 5, 32570, },
-		{ 4, 18032, 5, 32458, },
-	} },
-	{ 5825, {
-		{ 4, 18001, 5, 32402, },
-		{ 4, 18032, 5, 32458, },
-		{ 4, 17970, 5, 32347, },
-	} },
-	{ 5170, {
-		{ 4, 20282, 4, 18254, },
-		{ 4, 20321, 4, 18289, },
-		{ 4, 20243, 4, 18219, },
-	} },
-	{ 5190, {
-		{ 4, 20204, 4, 18183, },
-		{ 4, 20243, 4, 18219, },
-		{ 4, 20165, 4, 18148, },
-	} },
-	{ 5210, {
-		{ 4, 20126, 4, 18114, },
-		{ 4, 20165, 4, 18148, },
-		{ 4, 20088, 4, 18079, },
-	} },
-	{ 5230, {
-		{ 4, 20049, 4, 18044, },
-		{ 4, 20088, 4, 18079, },
-		{ 4, 20011, 4, 18010, },
-	} },
-};
-
-static const struct ar9170_phy_freq_params *
-ar9170_get_hw_dyn_params(struct ieee80211_channel *channel,
-			 enum ar9170_bw bw)
-{
-	unsigned int chanidx = 0;
-	u16 freq = 2412;
-
-	if (channel) {
-		chanidx = channel->hw_value;
-		freq = channel->center_freq;
-	}
-
-	BUG_ON(chanidx >= ARRAY_SIZE(ar9170_phy_freq_params));
-
-	BUILD_BUG_ON(__AR9170_NUM_BW != 3);
-
-	WARN_ON(ar9170_phy_freq_params[chanidx].freq != freq);
-
-	return &ar9170_phy_freq_params[chanidx].params[bw];
-}
-
-
-int ar9170_init_rf(struct ar9170 *ar)
-{
-	const struct ar9170_phy_freq_params *freqpar;
-	__le32 cmd[7];
-	int err;
-
-	err = ar9170_init_rf_banks_0_7(ar, false);
-	if (err)
-		return err;
-
-	err = ar9170_init_rf_bank4_pwr(ar, false, 2412, AR9170_BW_20);
-	if (err)
-		return err;
-
-	freqpar = ar9170_get_hw_dyn_params(NULL, AR9170_BW_20);
-
-	cmd[0] = cpu_to_le32(2412 * 1000);
-	cmd[1] = cpu_to_le32(0);
-	cmd[2] = cpu_to_le32(1);
-	cmd[3] = cpu_to_le32(freqpar->coeff_exp);
-	cmd[4] = cpu_to_le32(freqpar->coeff_man);
-	cmd[5] = cpu_to_le32(freqpar->coeff_exp_shgi);
-	cmd[6] = cpu_to_le32(freqpar->coeff_man_shgi);
-
-	/* RF_INIT echoes the command back to us */
-	err = ar->exec_cmd(ar, AR9170_CMD_RF_INIT,
-			   sizeof(cmd), (u8 *)cmd,
-			   sizeof(cmd), (u8 *)cmd);
-	if (err)
-		return err;
-
-	msleep(1000);
-
-	return ar9170_echo_test(ar, 0xaabbccdd);
-}
-
-static int ar9170_find_freq_idx(int nfreqs, u8 *freqs, u8 f)
-{
-	int idx = nfreqs - 2;
-
-	while (idx >= 0) {
-		if (f >= freqs[idx])
-			return idx;
-		idx--;
-	}
-
-	return 0;
-}
-
-static s32 ar9170_interpolate_s32(s32 x, s32 x1, s32 y1, s32 x2, s32 y2)
-{
-	/* nothing to interpolate, it's horizontal */
-	if (y2 == y1)
-		return y1;
-
-	/* check if we hit one of the edges */
-	if (x == x1)
-		return y1;
-	if (x == x2)
-		return y2;
-
-	/* x1 == x2 is bad, hopefully == x */
-	if (x2 == x1)
-		return y1;
-
-	return y1 + (((y2 - y1) * (x - x1)) / (x2 - x1));
-}
-
-static u8 ar9170_interpolate_u8(u8 x, u8 x1, u8 y1, u8 x2, u8 y2)
-{
-#define SHIFT		8
-	s32 y;
-
-	y = ar9170_interpolate_s32(x << SHIFT,
-				   x1 << SHIFT, y1 << SHIFT,
-				   x2 << SHIFT, y2 << SHIFT);
-
-	/*
-	 * XXX: unwrap this expression
-	 *	Isn't it just DIV_ROUND_UP(y, 1<<SHIFT)?
-	 *	Can we rely on the compiler to optimise away the div?
-	 */
-	return (y >> SHIFT) + ((y & (1<<(SHIFT-1))) >> (SHIFT - 1));
-#undef SHIFT
-}
-
-static u8 ar9170_interpolate_val(u8 x, u8 *x_array, u8 *y_array)
-{
-	int i;
-
-	for (i = 0; i < 3; i++)
-		if (x <= x_array[i + 1])
-			break;
-
-	return ar9170_interpolate_u8(x,
-				     x_array[i],
-				     y_array[i],
-				     x_array[i + 1],
-				     y_array[i + 1]);
-}
-
-static int ar9170_set_freq_cal_data(struct ar9170 *ar,
-				    struct ieee80211_channel *channel)
-{
-	u8 *cal_freq_pier;
-	u8 vpds[2][AR5416_PD_GAIN_ICEPTS];
-	u8 pwrs[2][AR5416_PD_GAIN_ICEPTS];
-	int chain, idx, i;
-	u32 phy_data = 0;
-	u8 f, tmp;
-
-	switch (channel->band) {
-	case IEEE80211_BAND_2GHZ:
-		f = channel->center_freq - 2300;
-		cal_freq_pier = ar->eeprom.cal_freq_pier_2G;
-		i = AR5416_NUM_2G_CAL_PIERS - 1;
-		break;
-
-	case IEEE80211_BAND_5GHZ:
-		f = (channel->center_freq - 4800) / 5;
-		cal_freq_pier = ar->eeprom.cal_freq_pier_5G;
-		i = AR5416_NUM_5G_CAL_PIERS - 1;
-		break;
-
-	default:
-		return -EINVAL;
-		break;
-	}
-
-	for (; i >= 0; i--) {
-		if (cal_freq_pier[i] != 0xff)
-			break;
-	}
-	if (i < 0)
-		return -EINVAL;
-
-	idx = ar9170_find_freq_idx(i, cal_freq_pier, f);
-
-	ar9170_regwrite_begin(ar);
-
-	for (chain = 0; chain < AR5416_MAX_CHAINS; chain++) {
-		for (i = 0; i < AR5416_PD_GAIN_ICEPTS; i++) {
-			struct ar9170_calibration_data_per_freq *cal_pier_data;
-			int j;
-
-			switch (channel->band) {
-			case IEEE80211_BAND_2GHZ:
-				cal_pier_data = &ar->eeprom.
-					cal_pier_data_2G[chain][idx];
-				break;
-
-			case IEEE80211_BAND_5GHZ:
-				cal_pier_data = &ar->eeprom.
-					cal_pier_data_5G[chain][idx];
-				break;
-
-			default:
-				return -EINVAL;
-			}
-
-			for (j = 0; j < 2; j++) {
-				vpds[j][i] = ar9170_interpolate_u8(f,
-					cal_freq_pier[idx],
-					cal_pier_data->vpd_pdg[j][i],
-					cal_freq_pier[idx + 1],
-					cal_pier_data[1].vpd_pdg[j][i]);
-
-				pwrs[j][i] = ar9170_interpolate_u8(f,
-					cal_freq_pier[idx],
-					cal_pier_data->pwr_pdg[j][i],
-					cal_freq_pier[idx + 1],
-					cal_pier_data[1].pwr_pdg[j][i]) / 2;
-			}
-		}
-
-		for (i = 0; i < 76; i++) {
-			if (i < 25) {
-				tmp = ar9170_interpolate_val(i, &pwrs[0][0],
-							     &vpds[0][0]);
-			} else {
-				tmp = ar9170_interpolate_val(i - 12,
-							     &pwrs[1][0],
-							     &vpds[1][0]);
-			}
-
-			phy_data |= tmp << ((i & 3) << 3);
-			if ((i & 3) == 3) {
-				ar9170_regwrite(0x1c6280 + chain * 0x1000 +
-						(i & ~3), phy_data);
-				phy_data = 0;
-			}
-		}
-
-		for (i = 19; i < 32; i++)
-			ar9170_regwrite(0x1c6280 + chain * 0x1000 + (i << 2),
-					0x0);
-	}
-
-	ar9170_regwrite_finish();
-	return ar9170_regwrite_result();
-}
-
-static u8 ar9170_get_max_edge_power(struct ar9170 *ar,
-				    struct ar9170_calctl_edges edges[],
-				    u32 freq)
-{
-	int i;
-	u8 rc = AR5416_MAX_RATE_POWER;
-	u8 f;
-	if (freq < 3000)
-		f = freq - 2300;
-	else
-		f = (freq - 4800) / 5;
-
-	for (i = 0; i < AR5416_NUM_BAND_EDGES; i++) {
-		if (edges[i].channel == 0xff)
-			break;
-		if (f == edges[i].channel) {
-			/* exact freq match */
-			rc = edges[i].power_flags & ~AR9170_CALCTL_EDGE_FLAGS;
-			break;
-		}
-		if (i > 0 && f < edges[i].channel) {
-			if (f > edges[i - 1].channel &&
-			    edges[i - 1].power_flags &
-			    AR9170_CALCTL_EDGE_FLAGS) {
-				/* lower channel has the inband flag set */
-				rc = edges[i - 1].power_flags &
-					~AR9170_CALCTL_EDGE_FLAGS;
-			}
-			break;
-		}
-	}
-
-	if (i == AR5416_NUM_BAND_EDGES) {
-		if (f > edges[i - 1].channel &&
-		    edges[i - 1].power_flags & AR9170_CALCTL_EDGE_FLAGS) {
-			/* lower channel has the inband flag set */
-			rc = edges[i - 1].power_flags &
-				~AR9170_CALCTL_EDGE_FLAGS;
-		}
-	}
-	return rc;
-}
-
-static u8 ar9170_get_heavy_clip(struct ar9170 *ar,
-				struct ar9170_calctl_edges edges[],
-				u32 freq, enum ar9170_bw bw)
-{
-	u8 f;
-	int i;
-	u8 rc = 0;
-
-	if (freq < 3000)
-		f = freq - 2300;
-	else
-		f = (freq - 4800) / 5;
-
-	if (bw == AR9170_BW_40_BELOW || bw == AR9170_BW_40_ABOVE)
-		rc |= 0xf0;
-
-	for (i = 0; i < AR5416_NUM_BAND_EDGES; i++) {
-		if (edges[i].channel == 0xff)
-			break;
-		if (f == edges[i].channel) {
-			if (!(edges[i].power_flags & AR9170_CALCTL_EDGE_FLAGS))
-				rc |= 0x0f;
-			break;
-		}
-	}
-
-	return rc;
-}
-
-/*
- * calculate the conformance test limits and the heavy clip parameter
- * and apply them to ar->power* (derived from otus hal/hpmain.c, line 3706)
- */
-static void ar9170_calc_ctl(struct ar9170 *ar, u32 freq, enum ar9170_bw bw)
-{
-	u8 ctl_grp; /* CTL group */
-	u8 ctl_idx; /* CTL index */
-	int i, j;
-	struct ctl_modes {
-		u8 ctl_mode;
-		u8 max_power;
-		u8 *pwr_cal_data;
-		int pwr_cal_len;
-	} *modes;
-
-	/*
-	 * order is relevant in the mode_list_*: we fall back to the
-	 * lower indices if any mode is missed in the EEPROM.
-	 */
-	struct ctl_modes mode_list_2ghz[] = {
-		{ CTL_11B, 0, ar->power_2G_cck, 4 },
-		{ CTL_11G, 0, ar->power_2G_ofdm, 4 },
-		{ CTL_2GHT20, 0, ar->power_2G_ht20, 8 },
-		{ CTL_2GHT40, 0, ar->power_2G_ht40, 8 },
-	};
-	struct ctl_modes mode_list_5ghz[] = {
-		{ CTL_11A, 0, ar->power_5G_leg, 4 },
-		{ CTL_5GHT20, 0, ar->power_5G_ht20, 8 },
-		{ CTL_5GHT40, 0, ar->power_5G_ht40, 8 },
-	};
-	int nr_modes;
-
-#define EDGES(c, n) (ar->eeprom.ctl_data[c].control_edges[n])
-
-	ar->phy_heavy_clip = 0;
-
-	/*
-	 * TODO: investigate the differences between OTUS'
-	 * hpreg.c::zfHpGetRegulatoryDomain() and
-	 * ath/regd.c::ath_regd_get_band_ctl() -
-	 * e.g. for FCC3_WORLD the OTUS procedure
-	 * always returns CTL_FCC, while the one in ath/ delivers
-	 * CTL_ETSI for 2GHz and CTL_FCC for 5GHz.
-	 */
-	ctl_grp = ath_regd_get_band_ctl(&ar->common.regulatory,
-					ar->hw->conf.channel->band);
-
-	/* ctl group not found - either invalid band (NO_CTL) or ww roaming */
-	if (ctl_grp == NO_CTL || ctl_grp == SD_NO_CTL)
-		ctl_grp = CTL_FCC;
-
-	if (ctl_grp != CTL_FCC)
-		/* skip CTL and heavy clip for CTL_MKK and CTL_ETSI */
-		return;
-
-	if (ar->hw->conf.channel->band == IEEE80211_BAND_2GHZ) {
-		modes = mode_list_2ghz;
-		nr_modes = ARRAY_SIZE(mode_list_2ghz);
-	} else {
-		modes = mode_list_5ghz;
-		nr_modes = ARRAY_SIZE(mode_list_5ghz);
-	}
-
-	for (i = 0; i < nr_modes; i++) {
-		u8 c = ctl_grp | modes[i].ctl_mode;
-		for (ctl_idx = 0; ctl_idx < AR5416_NUM_CTLS; ctl_idx++)
-			if (c == ar->eeprom.ctl_index[ctl_idx])
-				break;
-		if (ctl_idx < AR5416_NUM_CTLS) {
-			int f_off = 0;
-
-			/* determine heav clip parameter from
-			   the 11G edges array */
-			if (modes[i].ctl_mode == CTL_11G) {
-				ar->phy_heavy_clip =
-					ar9170_get_heavy_clip(ar,
-							      EDGES(ctl_idx, 1),
-							      freq, bw);
-			}
-
-			/* adjust freq for 40MHz */
-			if (modes[i].ctl_mode == CTL_2GHT40 ||
-			    modes[i].ctl_mode == CTL_5GHT40) {
-				if (bw == AR9170_BW_40_BELOW)
-					f_off = -10;
-				else
-					f_off = 10;
-			}
-
-			modes[i].max_power =
-				ar9170_get_max_edge_power(ar, EDGES(ctl_idx, 1),
-							  freq+f_off);
-
-			/*
-			 * TODO: check if the regulatory max. power is
-			 *  controlled by cfg80211 for DFS
-			 * (hpmain applies it to max_power itself for DFS freq)
-			 */
-
-		} else {
-			/*
-			 * Workaround in otus driver, hpmain.c, line 3906:
-			 * if no data for 5GHT20 are found, take the
-			 * legacy 5G value.
-			 * We extend this here to fallback from any other *HT or
-			 * 11G, too.
-			 */
-			int k = i;
-
-			modes[i].max_power = AR5416_MAX_RATE_POWER;
-			while (k-- > 0) {
-				if (modes[k].max_power !=
-				    AR5416_MAX_RATE_POWER) {
-					modes[i].max_power = modes[k].max_power;
-					break;
-				}
-			}
-		}
-
-		/* apply max power to pwr_cal_data (ar->power_*) */
-		for (j = 0; j < modes[i].pwr_cal_len; j++) {
-			modes[i].pwr_cal_data[j] = min(modes[i].pwr_cal_data[j],
-						       modes[i].max_power);
-		}
-	}
-
-	if (ar->phy_heavy_clip & 0xf0) {
-		ar->power_2G_ht40[0]--;
-		ar->power_2G_ht40[1]--;
-		ar->power_2G_ht40[2]--;
-	}
-	if (ar->phy_heavy_clip & 0xf) {
-		ar->power_2G_ht20[0]++;
-		ar->power_2G_ht20[1]++;
-		ar->power_2G_ht20[2]++;
-	}
-
-
-#undef EDGES
-}
-
-static int ar9170_set_power_cal(struct ar9170 *ar, u32 freq, enum ar9170_bw bw)
-{
-	struct ar9170_calibration_target_power_legacy *ctpl;
-	struct ar9170_calibration_target_power_ht *ctph;
-	u8 *ctpres;
-	int ntargets;
-	int idx, i, n;
-	u8 ackpower, ackchains, f;
-	u8 pwr_freqs[AR5416_MAX_NUM_TGT_PWRS];
-
-	if (freq < 3000)
-		f = freq - 2300;
-	else
-		f = (freq - 4800)/5;
-
-	/*
-	 * cycle through the various modes
-	 *
-	 * legacy modes first: 5G, 2G CCK, 2G OFDM
-	 */
-	for (i = 0; i < 3; i++) {
-		switch (i) {
-		case 0: /* 5 GHz legacy */
-			ctpl = &ar->eeprom.cal_tgt_pwr_5G[0];
-			ntargets = AR5416_NUM_5G_TARGET_PWRS;
-			ctpres = ar->power_5G_leg;
-			break;
-		case 1: /* 2.4 GHz CCK */
-			ctpl = &ar->eeprom.cal_tgt_pwr_2G_cck[0];
-			ntargets = AR5416_NUM_2G_CCK_TARGET_PWRS;
-			ctpres = ar->power_2G_cck;
-			break;
-		case 2: /* 2.4 GHz OFDM */
-			ctpl = &ar->eeprom.cal_tgt_pwr_2G_ofdm[0];
-			ntargets = AR5416_NUM_2G_OFDM_TARGET_PWRS;
-			ctpres = ar->power_2G_ofdm;
-			break;
-		default:
-			BUG();
-		}
-
-		for (n = 0; n < ntargets; n++) {
-			if (ctpl[n].freq == 0xff)
-				break;
-			pwr_freqs[n] = ctpl[n].freq;
-		}
-		ntargets = n;
-		idx = ar9170_find_freq_idx(ntargets, pwr_freqs, f);
-		for (n = 0; n < 4; n++)
-			ctpres[n] = ar9170_interpolate_u8(
-					f,
-					ctpl[idx + 0].freq,
-					ctpl[idx + 0].power[n],
-					ctpl[idx + 1].freq,
-					ctpl[idx + 1].power[n]);
-	}
-
-	/*
-	 * HT modes now: 5G HT20, 5G HT40, 2G CCK, 2G OFDM, 2G HT20, 2G HT40
-	 */
-	for (i = 0; i < 4; i++) {
-		switch (i) {
-		case 0: /* 5 GHz HT 20 */
-			ctph = &ar->eeprom.cal_tgt_pwr_5G_ht20[0];
-			ntargets = AR5416_NUM_5G_TARGET_PWRS;
-			ctpres = ar->power_5G_ht20;
-			break;
-		case 1: /* 5 GHz HT 40 */
-			ctph = &ar->eeprom.cal_tgt_pwr_5G_ht40[0];
-			ntargets = AR5416_NUM_5G_TARGET_PWRS;
-			ctpres = ar->power_5G_ht40;
-			break;
-		case 2: /* 2.4 GHz HT 20 */
-			ctph = &ar->eeprom.cal_tgt_pwr_2G_ht20[0];
-			ntargets = AR5416_NUM_2G_OFDM_TARGET_PWRS;
-			ctpres = ar->power_2G_ht20;
-			break;
-		case 3: /* 2.4 GHz HT 40 */
-			ctph = &ar->eeprom.cal_tgt_pwr_2G_ht40[0];
-			ntargets = AR5416_NUM_2G_OFDM_TARGET_PWRS;
-			ctpres = ar->power_2G_ht40;
-			break;
-		default:
-			BUG();
-		}
-
-		for (n = 0; n < ntargets; n++) {
-			if (ctph[n].freq == 0xff)
-				break;
-			pwr_freqs[n] = ctph[n].freq;
-		}
-		ntargets = n;
-		idx = ar9170_find_freq_idx(ntargets, pwr_freqs, f);
-		for (n = 0; n < 8; n++)
-			ctpres[n] = ar9170_interpolate_u8(
-					f,
-					ctph[idx + 0].freq,
-					ctph[idx + 0].power[n],
-					ctph[idx + 1].freq,
-					ctph[idx + 1].power[n]);
-	}
-
-
-	/* calc. conformance test limits and apply to ar->power*[] */
-	ar9170_calc_ctl(ar, freq, bw);
-
-	/* set ACK/CTS TX power */
-	ar9170_regwrite_begin(ar);
-
-	if (ar->eeprom.tx_mask != 1)
-		ackchains = AR9170_TX_PHY_TXCHAIN_2;
-	else
-		ackchains = AR9170_TX_PHY_TXCHAIN_1;
-
-	if (freq < 3000)
-		ackpower = ar->power_2G_ofdm[0] & 0x3f;
-	else
-		ackpower = ar->power_5G_leg[0] & 0x3f;
-
-	ar9170_regwrite(0x1c3694, ackpower << 20 | ackchains << 26);
-	ar9170_regwrite(0x1c3bb4, ackpower << 5 | ackchains << 11 |
-				  ackpower << 21 | ackchains << 27);
-
-	ar9170_regwrite_finish();
-	return ar9170_regwrite_result();
-}
-
-static int ar9170_calc_noise_dbm(u32 raw_noise)
-{
-	if (raw_noise & 0x100)
-		return ~((raw_noise & 0x0ff) >> 1);
-	else
-		return (raw_noise & 0xff) >> 1;
-}
-
-int ar9170_set_channel(struct ar9170 *ar, struct ieee80211_channel *channel,
-		       enum ar9170_rf_init_mode rfi, enum ar9170_bw bw)
-{
-	const struct ar9170_phy_freq_params *freqpar;
-	u32 cmd, tmp, offs;
-	__le32 vals[8];
-	int i, err;
-	bool bandswitch;
-
-	/* clear BB heavy clip enable */
-	err = ar9170_write_reg(ar, 0x1c59e0, 0x200);
-	if (err)
-		return err;
-
-	/* may be NULL at first setup */
-	if (ar->channel)
-		bandswitch = ar->channel->band != channel->band;
-	else
-		bandswitch = true;
-
-	/* HW workaround */
-	if (!ar->hw->wiphy->bands[IEEE80211_BAND_5GHZ] &&
-	    channel->center_freq <= 2417)
-		bandswitch = true;
-
-	err = ar->exec_cmd(ar, AR9170_CMD_FREQ_START, 0, NULL, 0, NULL);
-	if (err)
-		return err;
-
-	if (rfi != AR9170_RFI_NONE || bandswitch) {
-		u32 val = 0x400;
-
-		if (rfi == AR9170_RFI_COLD)
-			val = 0x800;
-
-		/* warm/cold reset BB/ADDA */
-		err = ar9170_write_reg(ar, 0x1d4004, val);
-		if (err)
-			return err;
-
-		err = ar9170_write_reg(ar, 0x1d4004, 0x0);
-		if (err)
-			return err;
-
-		err = ar9170_init_phy(ar, channel->band);
-		if (err)
-			return err;
-
-		err = ar9170_init_rf_banks_0_7(ar,
-			channel->band == IEEE80211_BAND_5GHZ);
-		if (err)
-			return err;
-
-		cmd = AR9170_CMD_RF_INIT;
-	} else {
-		cmd = AR9170_CMD_FREQUENCY;
-	}
-
-	err = ar9170_init_rf_bank4_pwr(ar,
-		channel->band == IEEE80211_BAND_5GHZ,
-		channel->center_freq, bw);
-	if (err)
-		return err;
-
-	switch (bw) {
-	case AR9170_BW_20:
-		tmp = 0x240;
-		offs = 0;
-		break;
-	case AR9170_BW_40_BELOW:
-		tmp = 0x2c4;
-		offs = 3;
-		break;
-	case AR9170_BW_40_ABOVE:
-		tmp = 0x2d4;
-		offs = 1;
-		break;
-	default:
-		BUG();
-		return -ENOSYS;
-	}
-
-	if (ar->eeprom.tx_mask != 1)
-		tmp |= 0x100;
-
-	err = ar9170_write_reg(ar, 0x1c5804, tmp);
-	if (err)
-		return err;
-
-	err = ar9170_set_freq_cal_data(ar, channel);
-	if (err)
-		return err;
-
-	err = ar9170_set_power_cal(ar, channel->center_freq, bw);
-	if (err)
-		return err;
-
-	freqpar = ar9170_get_hw_dyn_params(channel, bw);
-
-	vals[0] = cpu_to_le32(channel->center_freq * 1000);
-	vals[1] = cpu_to_le32(conf_is_ht40(&ar->hw->conf));
-	vals[2] = cpu_to_le32(offs << 2 | 1);
-	vals[3] = cpu_to_le32(freqpar->coeff_exp);
-	vals[4] = cpu_to_le32(freqpar->coeff_man);
-	vals[5] = cpu_to_le32(freqpar->coeff_exp_shgi);
-	vals[6] = cpu_to_le32(freqpar->coeff_man_shgi);
-	vals[7] = cpu_to_le32(1000);
-
-	err = ar->exec_cmd(ar, cmd, sizeof(vals), (u8 *)vals,
-			   sizeof(vals), (u8 *)vals);
-	if (err)
-		return err;
-
-	if (ar->phy_heavy_clip) {
-		err = ar9170_write_reg(ar, 0x1c59e0,
-				       0x200 | ar->phy_heavy_clip);
-		if (err) {
-			if (ar9170_nag_limiter(ar))
-				wiphy_err(ar->hw->wiphy,
-					  "failed to set heavy clip\n");
-		}
-	}
-
-	for (i = 0; i < 2; i++) {
-		ar->noise[i] = ar9170_calc_noise_dbm(
-				(le32_to_cpu(vals[2 + i]) >> 19) & 0x1ff);
-
-		ar->noise[i + 2] = ar9170_calc_noise_dbm(
-				    (le32_to_cpu(vals[5 + i]) >> 23) & 0x1ff);
-	}
-
-	ar->channel = channel;
-	return 0;
-}
diff -druN linux-2.6.39-libre/drivers/net/wireless/ath/ar9170/usb.c linux-3.0-rc7-libre/drivers/net/wireless/ath/ar9170/usb.c
--- linux-2.6.39-libre/drivers/net/wireless/ath/ar9170/usb.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/ath/ar9170/usb.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,1008 +0,0 @@
-/*
- * Atheros AR9170 driver
- *
- * USB - frontend
- *
- * Copyright 2008, Johannes Berg <johannes@sipsolutions.net>
- * Copyright 2009, Christian Lamparter <chunkeey@web.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; see the file COPYING.  If not, see
- * http://www.gnu.org/licenses/.
- *
- * This file incorporates work covered by the following copyright and
- * permission notice:
- *    Copyright (c) 2007-2008 Atheros Communications, Inc.
- *
- *    Permission to use, copy, modify, and/or distribute this software for any
- *    purpose with or without fee is hereby granted, provided that the above
- *    copyright notice and this permission notice appear in all copies.
- *
- *    THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- *    WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- *    MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- *    ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- *    WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- *    ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- *    OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/usb.h>
-#include <linux/firmware.h>
-#include <linux/etherdevice.h>
-#include <linux/device.h>
-#include <net/mac80211.h>
-#include "ar9170.h"
-#include "cmd.h"
-#include "hw.h"
-#include "usb.h"
-
-MODULE_AUTHOR("Johannes Berg <johannes@sipsolutions.net>");
-MODULE_AUTHOR("Christian Lamparter <chunkeey@web.de>");
-MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("Atheros AR9170 802.11n USB wireless");
-MODULE_FIRMWARE("ar9170.fw");
-
-enum ar9170_requirements {
-	AR9170_REQ_FW1_ONLY = 1,
-};
-
-static struct usb_device_id ar9170_usb_ids[] = {
-	/* Atheros 9170 */
-	{ USB_DEVICE(0x0cf3, 0x9170) },
-	/* Atheros TG121N */
-	{ USB_DEVICE(0x0cf3, 0x1001) },
-	/* TP-Link TL-WN821N v2 */
-	{ USB_DEVICE(0x0cf3, 0x1002) },
-	/* 3Com Dual Band 802.11n USB Adapter */
-	{ USB_DEVICE(0x0cf3, 0x1010) },
-	/* H3C Dual Band 802.11n USB Adapter */
-	{ USB_DEVICE(0x0cf3, 0x1011) },
-	/* Cace Airpcap NX */
-	{ USB_DEVICE(0xcace, 0x0300) },
-	/* D-Link DWA 160 A1 */
-	{ USB_DEVICE(0x07d1, 0x3c10) },
-	/* D-Link DWA 160 A2 */
-	{ USB_DEVICE(0x07d1, 0x3a09) },
-	/* Netgear WNA1000 */
-	{ USB_DEVICE(0x0846, 0x9040) },
-	/* Netgear WNDA3100 */
-	{ USB_DEVICE(0x0846, 0x9010) },
-	/* Netgear WN111 v2 */
-	{ USB_DEVICE(0x0846, 0x9001) },
-	/* Zydas ZD1221 */
-	{ USB_DEVICE(0x0ace, 0x1221) },
-	/* Proxim ORiNOCO 802.11n USB */
-	{ USB_DEVICE(0x1435, 0x0804) },
-	/* WNC Generic 11n USB Dongle */
-	{ USB_DEVICE(0x1435, 0x0326) },
-	/* ZyXEL NWD271N */
-	{ USB_DEVICE(0x0586, 0x3417) },
-	/* Z-Com UB81 BG */
-	{ 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 */
-	{ USB_DEVICE(0x2019, 0x5304) },
-	/* IO-Data WNGDNUS2 */
-	{ 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 },
-	/* Qwest/Actiontec 802AIN Wireless N USB Network Adapter */
-	{ USB_DEVICE(0x1668, 0x1200) },
-
-	/* terminate */
-	{}
-};
-MODULE_DEVICE_TABLE(usb, ar9170_usb_ids);
-
-static void ar9170_usb_submit_urb(struct ar9170_usb *aru)
-{
-	struct urb *urb;
-	unsigned long flags;
-	int err;
-
-	if (unlikely(!IS_STARTED(&aru->common)))
-		return ;
-
-	spin_lock_irqsave(&aru->tx_urb_lock, flags);
-	if (atomic_read(&aru->tx_submitted_urbs) >= AR9170_NUM_TX_URBS) {
-		spin_unlock_irqrestore(&aru->tx_urb_lock, flags);
-		return ;
-	}
-	atomic_inc(&aru->tx_submitted_urbs);
-
-	urb = usb_get_from_anchor(&aru->tx_pending);
-	if (!urb) {
-		atomic_dec(&aru->tx_submitted_urbs);
-		spin_unlock_irqrestore(&aru->tx_urb_lock, flags);
-
-		return ;
-	}
-	spin_unlock_irqrestore(&aru->tx_urb_lock, flags);
-
-	aru->tx_pending_urbs--;
-	usb_anchor_urb(urb, &aru->tx_submitted);
-
-	err = usb_submit_urb(urb, GFP_ATOMIC);
-	if (unlikely(err)) {
-		if (ar9170_nag_limiter(&aru->common))
-			dev_err(&aru->udev->dev, "submit_urb failed (%d).\n",
-				err);
-
-		usb_unanchor_urb(urb);
-		atomic_dec(&aru->tx_submitted_urbs);
-		ar9170_tx_callback(&aru->common, urb->context);
-	}
-
-	usb_free_urb(urb);
-}
-
-static void ar9170_usb_tx_urb_complete_frame(struct urb *urb)
-{
-	struct sk_buff *skb = urb->context;
-	struct ar9170_usb *aru = usb_get_intfdata(usb_ifnum_to_if(urb->dev, 0));
-
-	if (unlikely(!aru)) {
-		dev_kfree_skb_irq(skb);
-		return ;
-	}
-
-	atomic_dec(&aru->tx_submitted_urbs);
-
-	ar9170_tx_callback(&aru->common, skb);
-
-	ar9170_usb_submit_urb(aru);
-}
-
-static void ar9170_usb_tx_urb_complete(struct urb *urb)
-{
-}
-
-static void ar9170_usb_irq_completed(struct urb *urb)
-{
-	struct ar9170_usb *aru = urb->context;
-
-	switch (urb->status) {
-	/* everything is fine */
-	case 0:
-		break;
-
-	/* disconnect */
-	case -ENOENT:
-	case -ECONNRESET:
-	case -ENODEV:
-	case -ESHUTDOWN:
-		goto free;
-
-	default:
-		goto resubmit;
-	}
-
-	ar9170_handle_command_response(&aru->common, urb->transfer_buffer,
-				       urb->actual_length);
-
-resubmit:
-	usb_anchor_urb(urb, &aru->rx_submitted);
-	if (usb_submit_urb(urb, GFP_ATOMIC)) {
-		usb_unanchor_urb(urb);
-		goto free;
-	}
-
-	return;
-
-free:
-	usb_free_coherent(aru->udev, 64, urb->transfer_buffer, urb->transfer_dma);
-}
-
-static void ar9170_usb_rx_completed(struct urb *urb)
-{
-	struct sk_buff *skb = urb->context;
-	struct ar9170_usb *aru = usb_get_intfdata(usb_ifnum_to_if(urb->dev, 0));
-	int err;
-
-	if (!aru)
-		goto free;
-
-	switch (urb->status) {
-	/* everything is fine */
-	case 0:
-		break;
-
-	/* disconnect */
-	case -ENOENT:
-	case -ECONNRESET:
-	case -ENODEV:
-	case -ESHUTDOWN:
-		goto free;
-
-	default:
-		goto resubmit;
-	}
-
-	skb_put(skb, urb->actual_length);
-	ar9170_rx(&aru->common, skb);
-
-resubmit:
-	skb_reset_tail_pointer(skb);
-	skb_trim(skb, 0);
-
-	usb_anchor_urb(urb, &aru->rx_submitted);
-	err = usb_submit_urb(urb, GFP_ATOMIC);
-	if (unlikely(err)) {
-		usb_unanchor_urb(urb);
-		goto free;
-	}
-
-	return ;
-
-free:
-	dev_kfree_skb_irq(skb);
-}
-
-static int ar9170_usb_prep_rx_urb(struct ar9170_usb *aru,
-				  struct urb *urb, gfp_t gfp)
-{
-	struct sk_buff *skb;
-
-	skb = __dev_alloc_skb(AR9170_MAX_RX_BUFFER_SIZE + 32, gfp);
-	if (!skb)
-		return -ENOMEM;
-
-	/* reserve some space for mac80211's radiotap */
-	skb_reserve(skb, 32);
-
-	usb_fill_bulk_urb(urb, aru->udev,
-			  usb_rcvbulkpipe(aru->udev, AR9170_EP_RX),
-			  skb->data, min(skb_tailroom(skb),
-			  AR9170_MAX_RX_BUFFER_SIZE),
-			  ar9170_usb_rx_completed, skb);
-
-	return 0;
-}
-
-static int ar9170_usb_alloc_rx_irq_urb(struct ar9170_usb *aru)
-{
-	struct urb *urb = NULL;
-	void *ibuf;
-	int err = -ENOMEM;
-
-	/* initialize interrupt endpoint */
-	urb = usb_alloc_urb(0, GFP_KERNEL);
-	if (!urb)
-		goto out;
-
-	ibuf = usb_alloc_coherent(aru->udev, 64, GFP_KERNEL, &urb->transfer_dma);
-	if (!ibuf)
-		goto out;
-
-	usb_fill_int_urb(urb, aru->udev,
-			 usb_rcvintpipe(aru->udev, AR9170_EP_IRQ), ibuf,
-			 64, ar9170_usb_irq_completed, aru, 1);
-	urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
-
-	usb_anchor_urb(urb, &aru->rx_submitted);
-	err = usb_submit_urb(urb, GFP_KERNEL);
-	if (err) {
-		usb_unanchor_urb(urb);
-		usb_free_coherent(aru->udev, 64, urb->transfer_buffer,
-				  urb->transfer_dma);
-	}
-
-out:
-	usb_free_urb(urb);
-	return err;
-}
-
-static int ar9170_usb_alloc_rx_bulk_urbs(struct ar9170_usb *aru)
-{
-	struct urb *urb;
-	int i;
-	int err = -EINVAL;
-
-	for (i = 0; i < AR9170_NUM_RX_URBS; i++) {
-		err = -ENOMEM;
-		urb = usb_alloc_urb(0, GFP_KERNEL);
-		if (!urb)
-			goto err_out;
-
-		err = ar9170_usb_prep_rx_urb(aru, urb, GFP_KERNEL);
-		if (err) {
-			usb_free_urb(urb);
-			goto err_out;
-		}
-
-		usb_anchor_urb(urb, &aru->rx_submitted);
-		err = usb_submit_urb(urb, GFP_KERNEL);
-		if (err) {
-			usb_unanchor_urb(urb);
-			dev_kfree_skb_any((void *) urb->transfer_buffer);
-			usb_free_urb(urb);
-			goto err_out;
-		}
-		usb_free_urb(urb);
-	}
-
-	/* the device now waiting for a firmware. */
-	aru->common.state = AR9170_IDLE;
-	return 0;
-
-err_out:
-
-	usb_kill_anchored_urbs(&aru->rx_submitted);
-	return err;
-}
-
-static int ar9170_usb_flush(struct ar9170 *ar)
-{
-	struct ar9170_usb *aru = (void *) ar;
-	struct urb *urb;
-	int ret, err = 0;
-
-	if (IS_STARTED(ar))
-		aru->common.state = AR9170_IDLE;
-
-	usb_wait_anchor_empty_timeout(&aru->tx_pending,
-					    msecs_to_jiffies(800));
-	while ((urb = usb_get_from_anchor(&aru->tx_pending))) {
-		ar9170_tx_callback(&aru->common, (void *) urb->context);
-		usb_free_urb(urb);
-	}
-
-	/* lets wait a while until the tx - queues are dried out */
-	ret = usb_wait_anchor_empty_timeout(&aru->tx_submitted,
-					    msecs_to_jiffies(100));
-	if (ret == 0)
-		err = -ETIMEDOUT;
-
-	usb_kill_anchored_urbs(&aru->tx_submitted);
-
-	if (IS_ACCEPTING_CMD(ar))
-		aru->common.state = AR9170_STARTED;
-
-	return err;
-}
-
-static void ar9170_usb_cancel_urbs(struct ar9170_usb *aru)
-{
-	int err;
-
-	aru->common.state = AR9170_UNKNOWN_STATE;
-
-	err = ar9170_usb_flush(&aru->common);
-	if (err)
-		dev_err(&aru->udev->dev, "stuck tx urbs!\n");
-
-	usb_poison_anchored_urbs(&aru->tx_submitted);
-	usb_poison_anchored_urbs(&aru->rx_submitted);
-}
-
-static int ar9170_usb_exec_cmd(struct ar9170 *ar, enum ar9170_cmd cmd,
-			       unsigned int plen, void *payload,
-			       unsigned int outlen, void *out)
-{
-	struct ar9170_usb *aru = (void *) ar;
-	struct urb *urb = NULL;
-	unsigned long flags;
-	int err = -ENOMEM;
-
-	if (unlikely(!IS_ACCEPTING_CMD(ar)))
-		return -EPERM;
-
-	if (WARN_ON(plen > AR9170_MAX_CMD_LEN - 4))
-		return -EINVAL;
-
-	urb = usb_alloc_urb(0, GFP_ATOMIC);
-	if (unlikely(!urb))
-		goto err_free;
-
-	ar->cmdbuf[0] = cpu_to_le32(plen);
-	ar->cmdbuf[0] |= cpu_to_le32(cmd << 8);
-	/* writing multiple regs fills this buffer already */
-	if (plen && payload != (u8 *)(&ar->cmdbuf[1]))
-		memcpy(&ar->cmdbuf[1], payload, plen);
-
-	spin_lock_irqsave(&aru->common.cmdlock, flags);
-	aru->readbuf = (u8 *)out;
-	aru->readlen = outlen;
-	spin_unlock_irqrestore(&aru->common.cmdlock, flags);
-
-	usb_fill_int_urb(urb, aru->udev,
-			 usb_sndintpipe(aru->udev, AR9170_EP_CMD),
-			 aru->common.cmdbuf, plen + 4,
-			 ar9170_usb_tx_urb_complete, NULL, 1);
-
-	usb_anchor_urb(urb, &aru->tx_submitted);
-	err = usb_submit_urb(urb, GFP_ATOMIC);
-	if (unlikely(err)) {
-		usb_unanchor_urb(urb);
-		usb_free_urb(urb);
-		goto err_unbuf;
-	}
-	usb_free_urb(urb);
-
-	err = wait_for_completion_timeout(&aru->cmd_wait, HZ);
-	if (err == 0) {
-		err = -ETIMEDOUT;
-		goto err_unbuf;
-	}
-
-	if (aru->readlen != outlen) {
-		err = -EMSGSIZE;
-		goto err_unbuf;
-	}
-
-	return 0;
-
-err_unbuf:
-	/* Maybe the device was removed in the second we were waiting? */
-	if (IS_STARTED(ar)) {
-		dev_err(&aru->udev->dev, "no command feedback "
-					 "received (%d).\n", err);
-
-		/* provide some maybe useful debug information */
-		print_hex_dump_bytes("ar9170 cmd: ", DUMP_PREFIX_NONE,
-				     aru->common.cmdbuf, plen + 4);
-		dump_stack();
-	}
-
-	/* invalidate to avoid completing the next prematurely */
-	spin_lock_irqsave(&aru->common.cmdlock, flags);
-	aru->readbuf = NULL;
-	aru->readlen = 0;
-	spin_unlock_irqrestore(&aru->common.cmdlock, flags);
-
-err_free:
-
-	return err;
-}
-
-static int ar9170_usb_tx(struct ar9170 *ar, struct sk_buff *skb)
-{
-	struct ar9170_usb *aru = (struct ar9170_usb *) ar;
-	struct urb *urb;
-
-	if (unlikely(!IS_STARTED(ar))) {
-		/* Seriously, what were you drink... err... thinking!? */
-		return -EPERM;
-	}
-
-	urb = usb_alloc_urb(0, GFP_ATOMIC);
-	if (unlikely(!urb))
-		return -ENOMEM;
-
-	usb_fill_bulk_urb(urb, aru->udev,
-			  usb_sndbulkpipe(aru->udev, AR9170_EP_TX),
-			  skb->data, skb->len,
-			  ar9170_usb_tx_urb_complete_frame, skb);
-	urb->transfer_flags |= URB_ZERO_PACKET;
-
-	usb_anchor_urb(urb, &aru->tx_pending);
-	aru->tx_pending_urbs++;
-
-	usb_free_urb(urb);
-
-	ar9170_usb_submit_urb(aru);
-	return 0;
-}
-
-static void ar9170_usb_callback_cmd(struct ar9170 *ar, u32 len , void *buffer)
-{
-	struct ar9170_usb *aru = (void *) ar;
-	unsigned long flags;
-	u32 in, out;
-
-	if (unlikely(!buffer))
-		return ;
-
-	in = le32_to_cpup((__le32 *)buffer);
-	out = le32_to_cpu(ar->cmdbuf[0]);
-
-	/* mask off length byte */
-	out &= ~0xFF;
-
-	if (aru->readlen >= 0) {
-		/* add expected length */
-		out |= aru->readlen;
-	} else {
-		/* add obtained length */
-		out |= in & 0xFF;
-	}
-
-	/*
-	 * Some commands (e.g: AR9170_CMD_FREQUENCY) have a variable response
-	 * length and we cannot predict the correct length in advance.
-	 * So we only check if we provided enough space for the data.
-	 */
-	if (unlikely(out < in)) {
-		dev_warn(&aru->udev->dev, "received invalid command response "
-					  "got %d bytes, instead of %d bytes "
-					  "and the resp length is %d bytes\n",
-			 in, out, len);
-		print_hex_dump_bytes("ar9170 invalid resp: ",
-				     DUMP_PREFIX_OFFSET, buffer, len);
-		/*
-		 * Do not complete, then the command times out,
-		 * and we get a stack trace from there.
-		 */
-		return ;
-	}
-
-	spin_lock_irqsave(&aru->common.cmdlock, flags);
-	if (aru->readbuf && len > 0) {
-		memcpy(aru->readbuf, buffer + 4, len - 4);
-		aru->readbuf = NULL;
-	}
-	complete(&aru->cmd_wait);
-	spin_unlock_irqrestore(&aru->common.cmdlock, flags);
-}
-
-static int ar9170_usb_upload(struct ar9170_usb *aru, const void *data,
-			     size_t len, u32 addr, bool complete)
-{
-	int transfer, err;
-	u8 *buf = kmalloc(4096, GFP_KERNEL);
-
-	if (!buf)
-		return -ENOMEM;
-
-	while (len) {
-		transfer = min_t(int, len, 4096);
-		memcpy(buf, data, transfer);
-
-		err = usb_control_msg(aru->udev, usb_sndctrlpipe(aru->udev, 0),
-				      0x30 /* FW DL */, 0x40 | USB_DIR_OUT,
-				      addr >> 8, 0, buf, transfer, 1000);
-
-		if (err < 0) {
-			kfree(buf);
-			return err;
-		}
-
-		len -= transfer;
-		data += transfer;
-		addr += transfer;
-	}
-	kfree(buf);
-
-	if (complete) {
-		err = usb_control_msg(aru->udev, usb_sndctrlpipe(aru->udev, 0),
-				      0x31 /* FW DL COMPLETE */,
-				      0x40 | USB_DIR_OUT, 0, 0, NULL, 0, 5000);
-	}
-
-	return 0;
-}
-
-static int ar9170_usb_reset(struct ar9170_usb *aru)
-{
-	int ret, lock = (aru->intf->condition != USB_INTERFACE_BINDING);
-
-	if (lock) {
-		ret = usb_lock_device_for_reset(aru->udev, aru->intf);
-		if (ret < 0) {
-			dev_err(&aru->udev->dev, "unable to lock device "
-				"for reset (%d).\n", ret);
-			return ret;
-		}
-	}
-
-	ret = usb_reset_device(aru->udev);
-	if (lock)
-		usb_unlock_device(aru->udev);
-
-	/* let it rest - for a second - */
-	msleep(1000);
-
-	return ret;
-}
-
-static int ar9170_usb_upload_firmware(struct ar9170_usb *aru)
-{
-	int err;
-
-	if (!aru->init_values)
-		goto upload_fw_start;
-
-	/* First, upload initial values to device RAM */
-	err = ar9170_usb_upload(aru, aru->init_values->data,
-				aru->init_values->size, 0x102800, false);
-	if (err) {
-		dev_err(&aru->udev->dev, "firmware part 1 "
-			"upload failed (%d).\n", err);
-		return err;
-	}
-
-upload_fw_start:
-
-	/* Then, upload the firmware itself and start it */
-	return ar9170_usb_upload(aru, aru->firmware->data, aru->firmware->size,
-				0x200000, true);
-}
-
-static int ar9170_usb_init_transport(struct ar9170_usb *aru)
-{
-	struct ar9170 *ar = (void *) &aru->common;
-	int err;
-
-	ar9170_regwrite_begin(ar);
-
-	/* Set USB Rx stream mode MAX packet number to 2 */
-	ar9170_regwrite(AR9170_USB_REG_MAX_AGG_UPLOAD, 0x4);
-
-	/* Set USB Rx stream mode timeout to 10us */
-	ar9170_regwrite(AR9170_USB_REG_UPLOAD_TIME_CTL, 0x80);
-
-	ar9170_regwrite_finish();
-
-	err = ar9170_regwrite_result();
-	if (err)
-		dev_err(&aru->udev->dev, "USB setup failed (%d).\n", err);
-
-	return err;
-}
-
-static void ar9170_usb_stop(struct ar9170 *ar)
-{
-	struct ar9170_usb *aru = (void *) ar;
-	int ret;
-
-	if (IS_ACCEPTING_CMD(ar))
-		aru->common.state = AR9170_STOPPED;
-
-	ret = ar9170_usb_flush(ar);
-	if (ret)
-		dev_err(&aru->udev->dev, "kill pending tx urbs.\n");
-
-	usb_poison_anchored_urbs(&aru->tx_submitted);
-
-	/*
-	 * Note:
-	 * So far we freed all tx urbs, but we won't dare to touch any rx urbs.
-	 * Else we would end up with a unresponsive device...
-	 */
-}
-
-static int ar9170_usb_open(struct ar9170 *ar)
-{
-	struct ar9170_usb *aru = (void *) ar;
-	int err;
-
-	usb_unpoison_anchored_urbs(&aru->tx_submitted);
-	err = ar9170_usb_init_transport(aru);
-	if (err) {
-		usb_poison_anchored_urbs(&aru->tx_submitted);
-		return err;
-	}
-
-	aru->common.state = AR9170_IDLE;
-	return 0;
-}
-
-static int ar9170_usb_init_device(struct ar9170_usb *aru)
-{
-	int err;
-
-	err = ar9170_usb_alloc_rx_irq_urb(aru);
-	if (err)
-		goto err_out;
-
-	err = ar9170_usb_alloc_rx_bulk_urbs(aru);
-	if (err)
-		goto err_unrx;
-
-	err = ar9170_usb_upload_firmware(aru);
-	if (err) {
-		err = ar9170_echo_test(&aru->common, 0x60d43110);
-		if (err) {
-			/* force user invention, by disabling the device */
-			err = usb_driver_set_configuration(aru->udev, -1);
-			dev_err(&aru->udev->dev, "device is in a bad state. "
-						 "please reconnect it!\n");
-			goto err_unrx;
-		}
-	}
-
-	return 0;
-
-err_unrx:
-	ar9170_usb_cancel_urbs(aru);
-
-err_out:
-	return err;
-}
-
-static void ar9170_usb_firmware_failed(struct ar9170_usb *aru)
-{
-	struct device *parent = aru->udev->dev.parent;
-	struct usb_device *udev;
-
-	/*
-	 * Store a copy of the usb_device pointer locally.
-	 * This is because device_release_driver initiates
-	 * ar9170_usb_disconnect, which in turn frees our
-	 * driver context (aru).
-	 */
-	udev = aru->udev;
-
-	complete(&aru->firmware_loading_complete);
-
-	/* unbind anything failed */
-	if (parent)
-		device_lock(parent);
-
-	device_release_driver(&udev->dev);
-	if (parent)
-		device_unlock(parent);
-
-	usb_put_dev(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)
-		return false;
-	if (id->driver_info == AR9170_REQ_FW1_ONLY)
-		return true;
-	return false;
-}
-
-static int ar9170_usb_probe(struct usb_interface *intf,
-			const struct usb_device_id *id)
-{
-	struct ar9170_usb *aru;
-	struct ar9170 *ar;
-	struct usb_device *udev;
-	int err;
-
-	aru = ar9170_alloc(sizeof(*aru));
-	if (IS_ERR(aru)) {
-		err = PTR_ERR(aru);
-		goto out;
-	}
-
-	udev = interface_to_usbdev(intf);
-	usb_get_dev(udev);
-	aru->udev = udev;
-	aru->intf = intf;
-	ar = &aru->common;
-
-	aru->req_one_stage_fw = ar9170_requires_one_stage(id);
-
-	usb_set_intfdata(intf, aru);
-	SET_IEEE80211_DEV(ar->hw, &intf->dev);
-
-	init_usb_anchor(&aru->rx_submitted);
-	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;
-	atomic_set(&aru->tx_submitted_urbs, 0);
-
-	aru->common.stop = ar9170_usb_stop;
-	aru->common.flush = ar9170_usb_flush;
-	aru->common.open = ar9170_usb_open;
-	aru->common.tx = ar9170_usb_tx;
-	aru->common.exec_cmd = ar9170_usb_exec_cmd;
-	aru->common.callback_cmd = ar9170_usb_callback_cmd;
-
-#ifdef CONFIG_PM
-	udev->reset_resume = 1;
-#endif /* CONFIG_PM */
-	err = ar9170_usb_reset(aru);
-	if (err)
-		goto err_freehw;
-
-	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);
-	ieee80211_free_hw(ar->hw);
-out:
-	return err;
-}
-
-static void ar9170_usb_disconnect(struct usb_interface *intf)
-{
-	struct ar9170_usb *aru = usb_get_intfdata(intf);
-
-	if (!aru)
-		return;
-
-	aru->common.state = AR9170_IDLE;
-
-	wait_for_completion(&aru->firmware_loading_complete);
-
-	ar9170_unregister(&aru->common);
-	ar9170_usb_cancel_urbs(aru);
-
-	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
-static int ar9170_suspend(struct usb_interface *intf,
-			  pm_message_t  message)
-{
-	struct ar9170_usb *aru = usb_get_intfdata(intf);
-
-	if (!aru)
-		return -ENODEV;
-
-	aru->common.state = AR9170_IDLE;
-	ar9170_usb_cancel_urbs(aru);
-
-	return 0;
-}
-
-static int ar9170_resume(struct usb_interface *intf)
-{
-	struct ar9170_usb *aru = usb_get_intfdata(intf);
-	int err;
-
-	if (!aru)
-		return -ENODEV;
-
-	usb_unpoison_anchored_urbs(&aru->rx_submitted);
-	usb_unpoison_anchored_urbs(&aru->tx_submitted);
-
-	err = ar9170_usb_init_device(aru);
-	if (err)
-		goto err_unrx;
-
-	err = ar9170_usb_open(&aru->common);
-	if (err)
-		goto err_unrx;
-
-	return 0;
-
-err_unrx:
-	aru->common.state = AR9170_IDLE;
-	ar9170_usb_cancel_urbs(aru);
-
-	return err;
-}
-#endif /* CONFIG_PM */
-
-static struct usb_driver ar9170_driver = {
-	.name = "ar9170usb",
-	.probe = ar9170_usb_probe,
-	.disconnect = ar9170_usb_disconnect,
-	.id_table = ar9170_usb_ids,
-	.soft_unbind = 1,
-#ifdef CONFIG_PM
-	.suspend = ar9170_suspend,
-	.resume = ar9170_resume,
-	.reset_resume = ar9170_resume,
-#endif /* CONFIG_PM */
-};
-
-static int __init ar9170_init(void)
-{
-	return usb_register(&ar9170_driver);
-}
-
-static void __exit ar9170_exit(void)
-{
-	usb_deregister(&ar9170_driver);
-}
-
-module_init(ar9170_init);
-module_exit(ar9170_exit);
diff -druN linux-2.6.39-libre/drivers/net/wireless/ath/ar9170/usb.h linux-3.0-rc7-libre/drivers/net/wireless/ath/ar9170/usb.h
--- linux-2.6.39-libre/drivers/net/wireless/ath/ar9170/usb.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/ath/ar9170/usb.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,82 +0,0 @@
-/*
- * Atheros AR9170 USB driver
- *
- * Driver specific definitions
- *
- * Copyright 2008, Johannes Berg <johannes@sipsolutions.net>
- * Copyright 2009, Christian Lamparter <chunkeey@web.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; see the file COPYING.  If not, see
- * http://www.gnu.org/licenses/.
- *
- * This file incorporates work covered by the following copyright and
- * permission notice:
- *    Copyright (c) 2007-2008 Atheros Communications, Inc.
- *
- *    Permission to use, copy, modify, and/or distribute this software for any
- *    purpose with or without fee is hereby granted, provided that the above
- *    copyright notice and this permission notice appear in all copies.
- *
- *    THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- *    WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- *    MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- *    ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- *    WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- *    ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- *    OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-#ifndef __USB_H
-#define __USB_H
-
-#include <linux/usb.h>
-#include <linux/completion.h>
-#include <linux/spinlock.h>
-#include <linux/leds.h>
-#include <net/cfg80211.h>
-#include <net/mac80211.h>
-#include <linux/firmware.h>
-#include "eeprom.h"
-#include "hw.h"
-#include "ar9170.h"
-
-#define AR9170_NUM_RX_URBS			16
-#define AR9170_NUM_TX_URBS			8
-
-struct firmware;
-
-struct ar9170_usb {
-	struct ar9170 common;
-	struct usb_device *udev;
-	struct usb_interface *intf;
-
-	struct usb_anchor rx_submitted;
-	struct usb_anchor tx_pending;
-	struct usb_anchor tx_submitted;
-
-	bool req_one_stage_fw;
-
-	spinlock_t tx_urb_lock;
-	atomic_t tx_submitted_urbs;
-	unsigned int tx_pending_urbs;
-
-	struct completion cmd_wait;
-	struct completion firmware_loading_complete;
-	int readlen;
-	u8 *readbuf;
-
-	const struct firmware *init_values;
-	const struct firmware *firmware;
-};
-
-#endif /* __USB_H */
diff -druN linux-2.6.39-libre/drivers/net/wireless/ath/ath5k/ahb.c linux-3.0-rc7-libre/drivers/net/wireless/ath/ath5k/ahb.c
--- linux-2.6.39-libre/drivers/net/wireless/ath/ath5k/ahb.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/ath/ath5k/ahb.c	2011-07-11 19:51:52.000000000 -0400
@@ -18,6 +18,7 @@
 
 #include <linux/nl80211.h>
 #include <linux/platform_device.h>
+#include <linux/etherdevice.h>
 #include <ar231x_platform.h>
 #include "ath5k.h"
 #include "debug.h"
@@ -62,10 +63,27 @@
 	return 0;
 }
 
+static int ath5k_ahb_eeprom_read_mac(struct ath5k_hw *ah, u8 *mac)
+{
+	struct ath5k_softc *sc = ah->ah_sc;
+	struct platform_device *pdev = to_platform_device(sc->dev);
+	struct ar231x_board_config *bcfg = pdev->dev.platform_data;
+	u8 *cfg_mac;
+
+	if (to_platform_device(sc->dev)->id == 0)
+		cfg_mac = bcfg->config->wlan0_mac;
+	else
+		cfg_mac = bcfg->config->wlan1_mac;
+
+	memcpy(mac, cfg_mac, ETH_ALEN);
+	return 0;
+}
+
 static const struct ath_bus_ops ath_ahb_bus_ops = {
 	.ath_bus_type = ATH_AHB,
 	.read_cachesize = ath5k_ahb_read_cachesize,
 	.eeprom_read = ath5k_ahb_eeprom_read,
+	.eeprom_read_mac = ath5k_ahb_eeprom_read_mac,
 };
 
 /*Initialization*/
@@ -142,6 +160,16 @@
 		else
 			reg |= AR5K_AR5312_ENABLE_WLAN1;
 		__raw_writel(reg, (void __iomem *) AR5K_AR5312_ENABLE);
+
+		/*
+		 * On a dual-band AR5312, the multiband radio is only
+		 * used as pass-through. Disable 2 GHz support in the
+		 * driver for it
+		 */
+		if (to_platform_device(sc->dev)->id == 0 &&
+		    (bcfg->config->flags & (BD_WLAN0|BD_WLAN1)) ==
+		     (BD_WLAN1|BD_WLAN0))
+			__set_bit(ATH_STAT_2G_DISABLED, sc->status);
 	}
 
 	ret = ath5k_init_softc(sc, &ath_ahb_bus_ops);
diff -druN linux-2.6.39-libre/drivers/net/wireless/ath/ath5k/ath5k.h linux-3.0-rc7-libre/drivers/net/wireless/ath/ath5k/ath5k.h
--- linux-2.6.39-libre/drivers/net/wireless/ath/ath5k/ath5k.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/ath/ath5k/ath5k.h	2011-07-11 19:51:52.000000000 -0400
@@ -224,8 +224,7 @@
 
 /* SIFS */
 #define	AR5K_INIT_SIFS_TURBO			6
-/* XXX: 8 from initvals 10 from standard */
-#define	AR5K_INIT_SIFS_DEFAULT_BG		8
+#define	AR5K_INIT_SIFS_DEFAULT_BG		10
 #define	AR5K_INIT_SIFS_DEFAULT_A		16
 #define	AR5K_INIT_SIFS_HALF_RATE		32
 #define AR5K_INIT_SIFS_QUARTER_RATE		64
@@ -453,12 +452,10 @@
 	u16	ts_seqnum;
 	u16	ts_tstamp;
 	u8	ts_status;
-	u8	ts_rate[4];
-	u8	ts_retry[4];
 	u8	ts_final_idx;
+	u8	ts_final_retry;
 	s8	ts_rssi;
 	u8	ts_shortretry;
-	u8	ts_longretry;
 	u8	ts_virtcol;
 	u8	ts_antenna;
 };
@@ -875,6 +872,19 @@
 	AR5K_INT_QTRIG	=	0x40000000, /* Non common */
 	AR5K_INT_GLOBAL =	0x80000000,
 
+	AR5K_INT_TX_ALL = AR5K_INT_TXOK
+		| AR5K_INT_TXDESC
+		| AR5K_INT_TXERR
+		| AR5K_INT_TXEOL
+		| AR5K_INT_TXURN,
+
+	AR5K_INT_RX_ALL = AR5K_INT_RXOK
+		| AR5K_INT_RXDESC
+		| AR5K_INT_RXERR
+		| AR5K_INT_RXNOFRM
+		| AR5K_INT_RXEOL
+		| AR5K_INT_RXORN,
+
 	AR5K_INT_COMMON  = AR5K_INT_RXOK
 		| AR5K_INT_RXDESC
 		| AR5K_INT_RXERR
@@ -1058,6 +1068,7 @@
 	u8			ah_coverage_class;
 	bool			ah_ack_bitrate_high;
 	u8			ah_bwmode;
+	bool			ah_short_slot;
 
 	/* Antenna Control */
 	u32			ah_ant_ctl[AR5K_EEPROM_N_MODES][AR5K_ANT_MAX];
@@ -1144,6 +1155,13 @@
 		struct ath5k_rx_status *);
 };
 
+struct ath_bus_ops {
+	enum ath_bus_type ath_bus_type;
+	void (*read_cachesize)(struct ath_common *common, int *csz);
+	bool (*eeprom_read)(struct ath_common *common, u32 off, u16 *data);
+	int (*eeprom_read_mac)(struct ath5k_hw *ah, u8 *mac);
+};
+
 /*
  * Prototypes
  */
@@ -1227,13 +1245,12 @@
 /* EEPROM access functions */
 int ath5k_eeprom_init(struct ath5k_hw *ah);
 void ath5k_eeprom_detach(struct ath5k_hw *ah);
-int ath5k_eeprom_read_mac(struct ath5k_hw *ah, u8 *mac);
 
 
 /* Protocol Control Unit Functions */
 /* Helpers */
 int ath5k_hw_get_frame_duration(struct ath5k_hw *ah,
-		int len, struct ieee80211_rate *rate);
+		int len, struct ieee80211_rate *rate, bool shortpre);
 unsigned int ath5k_hw_get_default_slottime(struct ath5k_hw *ah);
 unsigned int ath5k_hw_get_default_sifs(struct ath5k_hw *ah);
 extern int ath5k_hw_set_opmode(struct ath5k_hw *ah, enum nl80211_iftype opmode);
diff -druN linux-2.6.39-libre/drivers/net/wireless/ath/ath5k/attach.c linux-3.0-rc7-libre/drivers/net/wireless/ath/ath5k/attach.c
--- linux-2.6.39-libre/drivers/net/wireless/ath/ath5k/attach.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/ath/ath5k/attach.c	2011-07-11 19:51:52.000000000 -0400
@@ -313,12 +313,17 @@
 		goto err;
 	}
 
+	if (test_bit(ATH_STAT_2G_DISABLED, sc->status)) {
+		__clear_bit(AR5K_MODE_11B, ah->ah_capabilities.cap_mode);
+		__clear_bit(AR5K_MODE_11G, ah->ah_capabilities.cap_mode);
+	}
+
 	/* Crypto settings */
 	common->keymax = (sc->ah->ah_version == AR5K_AR5210 ?
 			  AR5K_KEYTABLE_SIZE_5210 : AR5K_KEYTABLE_SIZE_5211);
 
 	if (srev >= AR5K_SREV_AR5212_V4 &&
-	    (ee->ee_version >= AR5K_EEPROM_VERSION_5_0 &&
+	    (ee->ee_version < AR5K_EEPROM_VERSION_5_0 ||
 	    !AR5K_EEPROM_AES_DIS(ee->ee_misc5)))
 		common->crypt_caps |= ATH_CRYPT_CAP_CIPHER_AESCCM;
 
diff -druN linux-2.6.39-libre/drivers/net/wireless/ath/ath5k/base.c linux-3.0-rc7-libre/drivers/net/wireless/ath/ath5k/base.c
--- linux-2.6.39-libre/drivers/net/wireless/ath/ath5k/base.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/ath/ath5k/base.c	2011-07-11 19:51:52.000000000 -0400
@@ -72,6 +72,11 @@
 module_param_named(all_channels, modparam_all_channels, bool, S_IRUGO);
 MODULE_PARM_DESC(all_channels, "Expose all channels the device can use.");
 
+static int modparam_fastchanswitch;
+module_param_named(fastchanswitch, modparam_fastchanswitch, bool, S_IRUGO);
+MODULE_PARM_DESC(fastchanswitch, "Enable fast channel switching for AR2413/AR5413 radios.");
+
+
 /* Module info */
 MODULE_AUTHOR("Jiri Slaby");
 MODULE_AUTHOR("Nick Kossifidis");
@@ -1444,6 +1449,21 @@
 }
 
 static void
+ath5k_set_current_imask(struct ath5k_softc *sc)
+{
+	enum ath5k_int imask = sc->imask;
+	unsigned long flags;
+
+	spin_lock_irqsave(&sc->irqlock, flags);
+	if (sc->rx_pending)
+		imask &= ~AR5K_INT_RX_ALL;
+	if (sc->tx_pending)
+		imask &= ~AR5K_INT_TX_ALL;
+	ath5k_hw_set_imr(sc->ah, imask);
+	spin_unlock_irqrestore(&sc->irqlock, flags);
+}
+
+static void
 ath5k_tasklet_rx(unsigned long data)
 {
 	struct ath5k_rx_status rs = {};
@@ -1506,6 +1526,8 @@
 	} while (ath5k_rxbuf_setup(sc, bf) == 0);
 unlock:
 	spin_unlock(&sc->rxbuflock);
+	sc->rx_pending = false;
+	ath5k_set_current_imask(sc);
 }
 
 
@@ -1573,28 +1595,28 @@
 			 struct ath5k_txq *txq, struct ath5k_tx_status *ts)
 {
 	struct ieee80211_tx_info *info;
+	u8 tries[3];
 	int i;
 
 	sc->stats.tx_all_count++;
 	sc->stats.tx_bytes_count += skb->len;
 	info = IEEE80211_SKB_CB(skb);
 
+	tries[0] = info->status.rates[0].count;
+	tries[1] = info->status.rates[1].count;
+	tries[2] = info->status.rates[2].count;
+
 	ieee80211_tx_info_clear_status(info);
-	for (i = 0; i < 4; i++) {
+
+	for (i = 0; i < ts->ts_final_idx; i++) {
 		struct ieee80211_tx_rate *r =
 			&info->status.rates[i];
 
-		if (ts->ts_rate[i]) {
-			r->idx = ath5k_hw_to_driver_rix(sc, ts->ts_rate[i]);
-			r->count = ts->ts_retry[i];
-		} else {
-			r->idx = -1;
-			r->count = 0;
-		}
+		r->count = tries[i];
 	}
 
-	/* count the successful attempt as well */
-	info->status.rates[ts->ts_final_idx].count++;
+	info->status.rates[ts->ts_final_idx].count = ts->ts_final_retry;
+	info->status.rates[ts->ts_final_idx + 1].idx = -1;
 
 	if (unlikely(ts->ts_status)) {
 		sc->stats.ack_fail++;
@@ -1609,6 +1631,9 @@
 	} else {
 		info->flags |= IEEE80211_TX_STAT_ACK;
 		info->status.ack_signal = ts->ts_rssi;
+
+		/* count the successful attempt as well */
+		info->status.rates[ts->ts_final_idx].count++;
 	}
 
 	/*
@@ -1690,6 +1715,9 @@
 	for (i=0; i < AR5K_NUM_TX_QUEUES; i++)
 		if (sc->txqs[i].setup && (sc->ah->ah_txq_isr & BIT(i)))
 			ath5k_tx_processq(sc, &sc->txqs[i]);
+
+	sc->tx_pending = false;
+	ath5k_set_current_imask(sc);
 }
 
 
@@ -2119,6 +2147,20 @@
 	 * AR5K_REG_ENABLE_BITS(ah, AR5K_CR, AR5K_CR_SWI); */
 }
 
+static void
+ath5k_schedule_rx(struct ath5k_softc *sc)
+{
+	sc->rx_pending = true;
+	tasklet_schedule(&sc->rxtq);
+}
+
+static void
+ath5k_schedule_tx(struct ath5k_softc *sc)
+{
+	sc->tx_pending = true;
+	tasklet_schedule(&sc->txtq);
+}
+
 irqreturn_t
 ath5k_intr(int irq, void *dev_id)
 {
@@ -2161,7 +2203,7 @@
 				ieee80211_queue_work(sc->hw, &sc->reset_work);
 			}
 			else
-				tasklet_schedule(&sc->rxtq);
+				ath5k_schedule_rx(sc);
 		} else {
 			if (status & AR5K_INT_SWBA) {
 				tasklet_hi_schedule(&sc->beacontq);
@@ -2179,10 +2221,10 @@
 				ath5k_hw_update_tx_triglevel(ah, true);
 			}
 			if (status & (AR5K_INT_RXOK | AR5K_INT_RXERR))
-				tasklet_schedule(&sc->rxtq);
+				ath5k_schedule_rx(sc);
 			if (status & (AR5K_INT_TXOK | AR5K_INT_TXDESC
 					| AR5K_INT_TXERR | AR5K_INT_TXEOL))
-				tasklet_schedule(&sc->txtq);
+				ath5k_schedule_tx(sc);
 			if (status & AR5K_INT_BMISS) {
 				/* TODO */
 			}
@@ -2201,6 +2243,9 @@
 
 	} while (ath5k_hw_is_intr_pending(ah) && --counter > 0);
 
+	if (sc->rx_pending || sc->tx_pending)
+		ath5k_set_current_imask(sc);
+
 	if (unlikely(!counter))
 		ATH5K_WARN(sc, "too many interrupts, giving up for now\n");
 
@@ -2354,7 +2399,7 @@
 	spin_lock_init(&sc->rxbuflock);
 	spin_lock_init(&sc->txbuflock);
 	spin_lock_init(&sc->block);
-
+	spin_lock_init(&sc->irqlock);
 
 	/* Setup interrupt handler */
 	ret = request_irq(sc->irq, ath5k_intr, IRQF_SHARED, "ath", sc);
@@ -2572,6 +2617,8 @@
 
 static void stop_tasklets(struct ath5k_softc *sc)
 {
+	sc->rx_pending = false;
+	sc->tx_pending = false;
 	tasklet_kill(&sc->rxtq);
 	tasklet_kill(&sc->txtq);
 	tasklet_kill(&sc->calib);
@@ -2644,6 +2691,7 @@
 	struct ath5k_hw *ah = sc->ah;
 	struct ath_common *common = ath5k_hw_common(ah);
 	int ret, ani_mode;
+	bool fast;
 
 	ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "resetting\n");
 
@@ -2663,7 +2711,10 @@
 	ath5k_drain_tx_buffs(sc);
 	if (chan)
 		sc->curchan = chan;
-	ret = ath5k_hw_reset(ah, sc->opmode, sc->curchan, chan != NULL,
+
+	fast = ((chan != NULL) && modparam_fastchanswitch) ? 1 : 0;
+
+	ret = ath5k_hw_reset(ah, sc->opmode, sc->curchan, fast,
 								skip_pcu);
 	if (ret) {
 		ATH5K_ERR(sc, "can't reset hardware (%d)\n", ret);
@@ -2838,7 +2889,7 @@
 	INIT_WORK(&sc->reset_work, ath5k_reset_work);
 	INIT_DELAYED_WORK(&sc->tx_complete_work, ath5k_tx_complete_poll_work);
 
-	ret = ath5k_eeprom_read_mac(ah, mac);
+	ret = ath5k_hw_common(ah)->bus_ops->eeprom_read_mac(ah, mac);
 	if (ret) {
 		ATH5K_ERR(sc, "unable to read address from EEPROM\n");
 		goto err_queues;
@@ -2898,7 +2949,6 @@
 	 * XXX: ??? detach ath5k_hw ???
 	 * Other than that, it's straightforward...
 	 */
-	ath5k_debug_finish_device(sc);
 	ieee80211_unregister_hw(hw);
 	ath5k_desc_free(sc);
 	ath5k_txq_release(sc);
diff -druN linux-2.6.39-libre/drivers/net/wireless/ath/ath5k/base.h linux-3.0-rc7-libre/drivers/net/wireless/ath/ath5k/base.h
--- linux-2.6.39-libre/drivers/net/wireless/ath/ath5k/base.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/ath/ath5k/base.h	2011-07-11 19:51:52.000000000 -0400
@@ -193,12 +193,13 @@
 	dma_addr_t		desc_daddr;	/* DMA (physical) address */
 	size_t			desc_len;	/* size of TX/RX descriptors */
 
-	DECLARE_BITMAP(status, 5);
+	DECLARE_BITMAP(status, 6);
 #define ATH_STAT_INVALID	0		/* disable hardware accesses */
 #define ATH_STAT_MRRETRY	1		/* multi-rate retry support */
 #define ATH_STAT_PROMISC	2
 #define ATH_STAT_LEDSOFT	3		/* enable LED gpio status */
 #define ATH_STAT_STARTED	4		/* opened & irqs enabled */
+#define ATH_STAT_2G_DISABLED	5		/* multiband radio without 2G */
 
 	unsigned int		filter_flags;	/* HW flags, AR5K_RX_FILTER_* */
 	struct ieee80211_channel *curchan;	/* current h/w channel */
@@ -207,6 +208,10 @@
 
 	enum ath5k_int		imask;		/* interrupt mask copy */
 
+	spinlock_t		irqlock;
+	bool			rx_pending;	/* rx tasklet pending */
+	bool			tx_pending;	/* tx tasklet pending */
+
 	u8			lladdr[ETH_ALEN];
 	u8			bssidmask[ETH_ALEN];
 
diff -druN linux-2.6.39-libre/drivers/net/wireless/ath/ath5k/caps.c linux-3.0-rc7-libre/drivers/net/wireless/ath/ath5k/caps.c
--- linux-2.6.39-libre/drivers/net/wireless/ath/ath5k/caps.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/ath/ath5k/caps.c	2011-07-11 19:51:52.000000000 -0400
@@ -94,6 +94,9 @@
 		}
 	}
 
+	if ((ah->ah_radio_5ghz_revision & 0xf0) == AR5K_SREV_RAD_2112)
+		__clear_bit(AR5K_MODE_11A, caps->cap_mode);
+
 	/* Set number of supported TX queues */
 	if (ah->ah_version == AR5K_AR5210)
 		caps->cap_queues.q_tx_num = AR5K_NUM_TX_QUEUES_NOQCU;
diff -druN linux-2.6.39-libre/drivers/net/wireless/ath/ath5k/debug.c linux-3.0-rc7-libre/drivers/net/wireless/ath/ath5k/debug.c
--- linux-2.6.39-libre/drivers/net/wireless/ath/ath5k/debug.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/ath/ath5k/debug.c	2011-07-11 19:51:52.000000000 -0400
@@ -888,65 +888,38 @@
 void
 ath5k_debug_init_device(struct ath5k_softc *sc)
 {
-	sc->debug.level = ath5k_debug;
+	struct dentry *phydir;
 
-	sc->debug.debugfs_phydir = debugfs_create_dir("ath5k",
-				sc->hw->wiphy->debugfsdir);
+	sc->debug.level = ath5k_debug;
 
-	sc->debug.debugfs_debug = debugfs_create_file("debug",
-				S_IWUSR | S_IRUSR,
-				sc->debug.debugfs_phydir, sc, &fops_debug);
+	phydir = debugfs_create_dir("ath5k", sc->hw->wiphy->debugfsdir);
+	if (!phydir)
+	    return;
 
-	sc->debug.debugfs_registers = debugfs_create_file("registers", S_IRUSR,
-				sc->debug.debugfs_phydir, sc, &fops_registers);
+	debugfs_create_file("debug", S_IWUSR | S_IRUSR, phydir, sc,
+			    &fops_debug);
 
-	sc->debug.debugfs_beacon = debugfs_create_file("beacon",
-				S_IWUSR | S_IRUSR,
-				sc->debug.debugfs_phydir, sc, &fops_beacon);
+	debugfs_create_file("registers", S_IRUSR, phydir, sc, &fops_registers);
 
-	sc->debug.debugfs_reset = debugfs_create_file("reset", S_IWUSR,
-				sc->debug.debugfs_phydir, sc, &fops_reset);
+	debugfs_create_file("beacon", S_IWUSR | S_IRUSR, phydir, sc,
+			    &fops_beacon);
 
-	sc->debug.debugfs_antenna = debugfs_create_file("antenna",
-				S_IWUSR | S_IRUSR,
-				sc->debug.debugfs_phydir, sc, &fops_antenna);
+	debugfs_create_file("reset", S_IWUSR, phydir, sc, &fops_reset);
 
-	sc->debug.debugfs_misc = debugfs_create_file("misc",
-				S_IRUSR,
-				sc->debug.debugfs_phydir, sc, &fops_misc);
+	debugfs_create_file("antenna", S_IWUSR | S_IRUSR, phydir, sc,
+			    &fops_antenna);
 
-	sc->debug.debugfs_frameerrors = debugfs_create_file("frameerrors",
-				S_IWUSR | S_IRUSR,
-				sc->debug.debugfs_phydir, sc,
-				&fops_frameerrors);
+	debugfs_create_file("misc", S_IRUSR, phydir, sc, &fops_misc);
 
-	sc->debug.debugfs_ani = debugfs_create_file("ani",
-				S_IWUSR | S_IRUSR,
-				sc->debug.debugfs_phydir, sc,
-				&fops_ani);
+	debugfs_create_file("frameerrors", S_IWUSR | S_IRUSR, phydir, sc,
+			    &fops_frameerrors);
 
-	sc->debug.debugfs_queue = debugfs_create_file("queue",
-				S_IWUSR | S_IRUSR,
-				sc->debug.debugfs_phydir, sc,
-				&fops_queue);
-}
+	debugfs_create_file("ani", S_IWUSR | S_IRUSR, phydir, sc, &fops_ani);
 
-void
-ath5k_debug_finish_device(struct ath5k_softc *sc)
-{
-	debugfs_remove(sc->debug.debugfs_debug);
-	debugfs_remove(sc->debug.debugfs_registers);
-	debugfs_remove(sc->debug.debugfs_beacon);
-	debugfs_remove(sc->debug.debugfs_reset);
-	debugfs_remove(sc->debug.debugfs_antenna);
-	debugfs_remove(sc->debug.debugfs_misc);
-	debugfs_remove(sc->debug.debugfs_frameerrors);
-	debugfs_remove(sc->debug.debugfs_ani);
-	debugfs_remove(sc->debug.debugfs_queue);
-	debugfs_remove(sc->debug.debugfs_phydir);
+	debugfs_create_file("queue", S_IWUSR | S_IRUSR, phydir, sc,
+			    &fops_queue);
 }
 
-
 /* functions used in other places */
 
 void
diff -druN linux-2.6.39-libre/drivers/net/wireless/ath/ath5k/debug.h linux-3.0-rc7-libre/drivers/net/wireless/ath/ath5k/debug.h
--- linux-2.6.39-libre/drivers/net/wireless/ath/ath5k/debug.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/ath/ath5k/debug.h	2011-07-11 19:51:52.000000000 -0400
@@ -68,17 +68,6 @@
 
 struct ath5k_dbg_info {
 	unsigned int		level;		/* debug level */
-	/* debugfs entries */
-	struct dentry		*debugfs_phydir;
-	struct dentry		*debugfs_debug;
-	struct dentry		*debugfs_registers;
-	struct dentry		*debugfs_beacon;
-	struct dentry		*debugfs_reset;
-	struct dentry		*debugfs_antenna;
-	struct dentry		*debugfs_misc;
-	struct dentry		*debugfs_frameerrors;
-	struct dentry		*debugfs_ani;
-	struct dentry		*debugfs_queue;
 };
 
 /**
@@ -141,9 +130,6 @@
 ath5k_debug_init_device(struct ath5k_softc *sc);
 
 void
-ath5k_debug_finish_device(struct ath5k_softc *sc);
-
-void
 ath5k_debug_printrxbuffs(struct ath5k_softc *sc, struct ath5k_hw *ah);
 
 void
@@ -167,9 +153,6 @@
 ath5k_debug_init_device(struct ath5k_softc *sc) {}
 
 static inline void
-ath5k_debug_finish_device(struct ath5k_softc *sc) {}
-
-static inline void
 ath5k_debug_printrxbuffs(struct ath5k_softc *sc, struct ath5k_hw *ah) {}
 
 static inline void
diff -druN linux-2.6.39-libre/drivers/net/wireless/ath/ath5k/desc.c linux-3.0-rc7-libre/drivers/net/wireless/ath/ath5k/desc.c
--- linux-2.6.39-libre/drivers/net/wireless/ath/ath5k/desc.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/ath/ath5k/desc.c	2011-07-11 19:51:52.000000000 -0400
@@ -107,10 +107,13 @@
 		case AR5K_PKT_TYPE_BEACON:
 		case AR5K_PKT_TYPE_PROBE_RESP:
 			frame_type = AR5K_AR5210_TX_DESC_FRAME_TYPE_NO_DELAY;
+			break;
 		case AR5K_PKT_TYPE_PIFS:
 			frame_type = AR5K_AR5210_TX_DESC_FRAME_TYPE_PIFS;
+			break;
 		default:
 			frame_type = type;
+			break;
 		}
 
 		tx_ctl->tx_control_0 |=
@@ -185,6 +188,12 @@
 	struct ath5k_hw_4w_tx_ctl *tx_ctl;
 	unsigned int frame_len;
 
+	/*
+	 * Use local variables for these to reduce load/store access on
+	 * uncached memory
+	 */
+	u32 txctl0 = 0, txctl1 = 0, txctl2 = 0, txctl3 = 0;
+
 	tx_ctl = &desc->ud.ds_tx5212.tx_ctl;
 
 	/*
@@ -208,8 +217,9 @@
 	if (tx_power > AR5K_TUNE_MAX_TXPOWER)
 		tx_power = AR5K_TUNE_MAX_TXPOWER;
 
-	/* Clear descriptor */
-	memset(&desc->ud.ds_tx5212, 0, sizeof(struct ath5k_hw_5212_tx_desc));
+	/* Clear descriptor status area */
+	memset(&desc->ud.ds_tx5212.tx_stat, 0,
+	       sizeof(desc->ud.ds_tx5212.tx_stat));
 
 	/* Setup control descriptor */
 
@@ -221,7 +231,7 @@
 	if (frame_len & ~AR5K_4W_TX_DESC_CTL0_FRAME_LEN)
 		return -EINVAL;
 
-	tx_ctl->tx_control_0 = frame_len & AR5K_4W_TX_DESC_CTL0_FRAME_LEN;
+	txctl0 = frame_len & AR5K_4W_TX_DESC_CTL0_FRAME_LEN;
 
 	/* Verify and set buffer length */
 
@@ -232,21 +242,17 @@
 	if (pkt_len & ~AR5K_4W_TX_DESC_CTL1_BUF_LEN)
 		return -EINVAL;
 
-	tx_ctl->tx_control_1 = pkt_len & AR5K_4W_TX_DESC_CTL1_BUF_LEN;
+	txctl1 = pkt_len & AR5K_4W_TX_DESC_CTL1_BUF_LEN;
 
-	tx_ctl->tx_control_0 |=
-		AR5K_REG_SM(tx_power, AR5K_4W_TX_DESC_CTL0_XMIT_POWER) |
-		AR5K_REG_SM(antenna_mode, AR5K_4W_TX_DESC_CTL0_ANT_MODE_XMIT);
-	tx_ctl->tx_control_1 |= AR5K_REG_SM(type,
-					AR5K_4W_TX_DESC_CTL1_FRAME_TYPE);
-	tx_ctl->tx_control_2 = AR5K_REG_SM(tx_tries0,
-					AR5K_4W_TX_DESC_CTL2_XMIT_TRIES0);
-	tx_ctl->tx_control_3 = tx_rate0 & AR5K_4W_TX_DESC_CTL3_XMIT_RATE0;
+	txctl0 |= AR5K_REG_SM(tx_power, AR5K_4W_TX_DESC_CTL0_XMIT_POWER) |
+		  AR5K_REG_SM(antenna_mode, AR5K_4W_TX_DESC_CTL0_ANT_MODE_XMIT);
+	txctl1 |= AR5K_REG_SM(type, AR5K_4W_TX_DESC_CTL1_FRAME_TYPE);
+	txctl2 = AR5K_REG_SM(tx_tries0, AR5K_4W_TX_DESC_CTL2_XMIT_TRIES0);
+	txctl3 = tx_rate0 & AR5K_4W_TX_DESC_CTL3_XMIT_RATE0;
 
 #define _TX_FLAGS(_c, _flag)					\
 	if (flags & AR5K_TXDESC_##_flag) {			\
-		tx_ctl->tx_control_##_c |=			\
-			AR5K_4W_TX_DESC_CTL##_c##_##_flag;	\
+		txctl##_c |= AR5K_4W_TX_DESC_CTL##_c##_##_flag;	\
 	}
 
 	_TX_FLAGS(0, CLRDMASK);
@@ -262,8 +268,8 @@
 	 * WEP crap
 	 */
 	if (key_index != AR5K_TXKEYIX_INVALID) {
-		tx_ctl->tx_control_0 |= AR5K_4W_TX_DESC_CTL0_ENCRYPT_KEY_VALID;
-		tx_ctl->tx_control_1 |= AR5K_REG_SM(key_index,
+		txctl0 |= AR5K_4W_TX_DESC_CTL0_ENCRYPT_KEY_VALID;
+		txctl1 |= AR5K_REG_SM(key_index,
 				AR5K_4W_TX_DESC_CTL1_ENCRYPT_KEY_IDX);
 	}
 
@@ -274,12 +280,16 @@
 		if ((flags & AR5K_TXDESC_RTSENA) &&
 				(flags & AR5K_TXDESC_CTSENA))
 			return -EINVAL;
-		tx_ctl->tx_control_2 |= rtscts_duration &
-				AR5K_4W_TX_DESC_CTL2_RTS_DURATION;
-		tx_ctl->tx_control_3 |= AR5K_REG_SM(rtscts_rate,
+		txctl2 |= rtscts_duration & AR5K_4W_TX_DESC_CTL2_RTS_DURATION;
+		txctl3 |= AR5K_REG_SM(rtscts_rate,
 				AR5K_4W_TX_DESC_CTL3_RTS_CTS_RATE);
 	}
 
+	tx_ctl->tx_control_0 = txctl0;
+	tx_ctl->tx_control_1 = txctl1;
+	tx_ctl->tx_control_2 = txctl2;
+	tx_ctl->tx_control_3 = txctl3;
+
 	return 0;
 }
 
@@ -364,7 +374,7 @@
 		AR5K_DESC_TX_STATUS0_SEND_TIMESTAMP);
 	ts->ts_shortretry = AR5K_REG_MS(tx_status->tx_status_0,
 		AR5K_DESC_TX_STATUS0_SHORT_RETRY_COUNT);
-	ts->ts_longretry = AR5K_REG_MS(tx_status->tx_status_0,
+	ts->ts_final_retry = AR5K_REG_MS(tx_status->tx_status_0,
 		AR5K_DESC_TX_STATUS0_LONG_RETRY_COUNT);
 	/*TODO: ts->ts_virtcol + test*/
 	ts->ts_seqnum = AR5K_REG_MS(tx_status->tx_status_1,
@@ -373,9 +383,6 @@
 		AR5K_DESC_TX_STATUS1_ACK_SIG_STRENGTH);
 	ts->ts_antenna = 1;
 	ts->ts_status = 0;
-	ts->ts_rate[0] = AR5K_REG_MS(tx_ctl->tx_control_0,
-		AR5K_2W_TX_DESC_CTL0_XMIT_RATE);
-	ts->ts_retry[0] = ts->ts_longretry;
 	ts->ts_final_idx = 0;
 
 	if (!(tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FRAME_XMIT_OK)) {
@@ -401,81 +408,48 @@
 {
 	struct ath5k_hw_4w_tx_ctl *tx_ctl;
 	struct ath5k_hw_tx_status *tx_status;
+	u32 txstat0, txstat1;
 
 	tx_ctl = &desc->ud.ds_tx5212.tx_ctl;
 	tx_status = &desc->ud.ds_tx5212.tx_stat;
 
+	txstat1 = ACCESS_ONCE(tx_status->tx_status_1);
+
 	/* No frame has been send or error */
-	if (unlikely(!(tx_status->tx_status_1 & AR5K_DESC_TX_STATUS1_DONE)))
+	if (unlikely(!(txstat1 & AR5K_DESC_TX_STATUS1_DONE)))
 		return -EINPROGRESS;
 
+	txstat0 = ACCESS_ONCE(tx_status->tx_status_0);
+
 	/*
 	 * Get descriptor status
 	 */
-	ts->ts_tstamp = AR5K_REG_MS(tx_status->tx_status_0,
+	ts->ts_tstamp = AR5K_REG_MS(txstat0,
 		AR5K_DESC_TX_STATUS0_SEND_TIMESTAMP);
-	ts->ts_shortretry = AR5K_REG_MS(tx_status->tx_status_0,
+	ts->ts_shortretry = AR5K_REG_MS(txstat0,
 		AR5K_DESC_TX_STATUS0_SHORT_RETRY_COUNT);
-	ts->ts_longretry = AR5K_REG_MS(tx_status->tx_status_0,
+	ts->ts_final_retry = AR5K_REG_MS(txstat0,
 		AR5K_DESC_TX_STATUS0_LONG_RETRY_COUNT);
-	ts->ts_seqnum = AR5K_REG_MS(tx_status->tx_status_1,
+	ts->ts_seqnum = AR5K_REG_MS(txstat1,
 		AR5K_DESC_TX_STATUS1_SEQ_NUM);
-	ts->ts_rssi = AR5K_REG_MS(tx_status->tx_status_1,
+	ts->ts_rssi = AR5K_REG_MS(txstat1,
 		AR5K_DESC_TX_STATUS1_ACK_SIG_STRENGTH);
-	ts->ts_antenna = (tx_status->tx_status_1 &
+	ts->ts_antenna = (txstat1 &
 		AR5K_DESC_TX_STATUS1_XMIT_ANTENNA_5212) ? 2 : 1;
 	ts->ts_status = 0;
 
-	ts->ts_final_idx = AR5K_REG_MS(tx_status->tx_status_1,
+	ts->ts_final_idx = AR5K_REG_MS(txstat1,
 			AR5K_DESC_TX_STATUS1_FINAL_TS_IX_5212);
 
-	/* The longretry counter has the number of un-acked retries
-	 * for the final rate. To get the total number of retries
-	 * we have to add the retry counters for the other rates
-	 * as well
-	 */
-	ts->ts_retry[ts->ts_final_idx] = ts->ts_longretry;
-	switch (ts->ts_final_idx) {
-	case 3:
-		ts->ts_rate[3] = AR5K_REG_MS(tx_ctl->tx_control_3,
-			AR5K_4W_TX_DESC_CTL3_XMIT_RATE3);
-
-		ts->ts_retry[2] = AR5K_REG_MS(tx_ctl->tx_control_2,
-			AR5K_4W_TX_DESC_CTL2_XMIT_TRIES2);
-		ts->ts_longretry += ts->ts_retry[2];
-		/* fall through */
-	case 2:
-		ts->ts_rate[2] = AR5K_REG_MS(tx_ctl->tx_control_3,
-			AR5K_4W_TX_DESC_CTL3_XMIT_RATE2);
-
-		ts->ts_retry[1] = AR5K_REG_MS(tx_ctl->tx_control_2,
-			AR5K_4W_TX_DESC_CTL2_XMIT_TRIES1);
-		ts->ts_longretry += ts->ts_retry[1];
-		/* fall through */
-	case 1:
-		ts->ts_rate[1] = AR5K_REG_MS(tx_ctl->tx_control_3,
-			AR5K_4W_TX_DESC_CTL3_XMIT_RATE1);
-
-		ts->ts_retry[0] = AR5K_REG_MS(tx_ctl->tx_control_2,
-			AR5K_4W_TX_DESC_CTL2_XMIT_TRIES1);
-		ts->ts_longretry += ts->ts_retry[0];
-		/* fall through */
-	case 0:
-		ts->ts_rate[0] = tx_ctl->tx_control_3 &
-			AR5K_4W_TX_DESC_CTL3_XMIT_RATE0;
-		break;
-	}
-
 	/* TX error */
-	if (!(tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FRAME_XMIT_OK)) {
-		if (tx_status->tx_status_0 &
-				AR5K_DESC_TX_STATUS0_EXCESSIVE_RETRIES)
+	if (!(txstat0 & AR5K_DESC_TX_STATUS0_FRAME_XMIT_OK)) {
+		if (txstat0 & AR5K_DESC_TX_STATUS0_EXCESSIVE_RETRIES)
 			ts->ts_status |= AR5K_TXERR_XRETRY;
 
-		if (tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FIFO_UNDERRUN)
+		if (txstat0 & AR5K_DESC_TX_STATUS0_FIFO_UNDERRUN)
 			ts->ts_status |= AR5K_TXERR_FIFO;
 
-		if (tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FILTERED)
+		if (txstat0 & AR5K_DESC_TX_STATUS0_FILTERED)
 			ts->ts_status |= AR5K_TXERR_FILT;
 	}
 
@@ -609,37 +583,37 @@
 					struct ath5k_rx_status *rs)
 {
 	struct ath5k_hw_rx_status *rx_status;
+	u32 rxstat0, rxstat1;
 
 	rx_status = &desc->ud.ds_rx.rx_stat;
+	rxstat1 = ACCESS_ONCE(rx_status->rx_status_1);
 
 	/* No frame received / not ready */
-	if (unlikely(!(rx_status->rx_status_1 &
-				AR5K_5212_RX_DESC_STATUS1_DONE)))
+	if (unlikely(!(rxstat1 & AR5K_5212_RX_DESC_STATUS1_DONE)))
 		return -EINPROGRESS;
 
 	memset(rs, 0, sizeof(struct ath5k_rx_status));
+	rxstat0 = ACCESS_ONCE(rx_status->rx_status_0);
 
 	/*
 	 * Frame receive status
 	 */
-	rs->rs_datalen = rx_status->rx_status_0 &
-		AR5K_5212_RX_DESC_STATUS0_DATA_LEN;
-	rs->rs_rssi = AR5K_REG_MS(rx_status->rx_status_0,
+	rs->rs_datalen = rxstat0 & AR5K_5212_RX_DESC_STATUS0_DATA_LEN;
+	rs->rs_rssi = AR5K_REG_MS(rxstat0,
 		AR5K_5212_RX_DESC_STATUS0_RECEIVE_SIGNAL);
-	rs->rs_rate = AR5K_REG_MS(rx_status->rx_status_0,
+	rs->rs_rate = AR5K_REG_MS(rxstat0,
 		AR5K_5212_RX_DESC_STATUS0_RECEIVE_RATE);
-	rs->rs_antenna = AR5K_REG_MS(rx_status->rx_status_0,
+	rs->rs_antenna = AR5K_REG_MS(rxstat0,
 		AR5K_5212_RX_DESC_STATUS0_RECEIVE_ANTENNA);
-	rs->rs_more = !!(rx_status->rx_status_0 &
-		AR5K_5212_RX_DESC_STATUS0_MORE);
-	rs->rs_tstamp = AR5K_REG_MS(rx_status->rx_status_1,
+	rs->rs_more = !!(rxstat0 & AR5K_5212_RX_DESC_STATUS0_MORE);
+	rs->rs_tstamp = AR5K_REG_MS(rxstat1,
 		AR5K_5212_RX_DESC_STATUS1_RECEIVE_TIMESTAMP);
 
 	/*
 	 * Key table status
 	 */
-	if (rx_status->rx_status_1 & AR5K_5212_RX_DESC_STATUS1_KEY_INDEX_VALID)
-		rs->rs_keyix = AR5K_REG_MS(rx_status->rx_status_1,
+	if (rxstat1 & AR5K_5212_RX_DESC_STATUS1_KEY_INDEX_VALID)
+		rs->rs_keyix = AR5K_REG_MS(rxstat1,
 					   AR5K_5212_RX_DESC_STATUS1_KEY_INDEX);
 	else
 		rs->rs_keyix = AR5K_RXKEYIX_INVALID;
@@ -647,27 +621,22 @@
 	/*
 	 * Receive/descriptor errors
 	 */
-	if (!(rx_status->rx_status_1 &
-	    AR5K_5212_RX_DESC_STATUS1_FRAME_RECEIVE_OK)) {
-		if (rx_status->rx_status_1 &
-				AR5K_5212_RX_DESC_STATUS1_CRC_ERROR)
+	if (!(rxstat1 & AR5K_5212_RX_DESC_STATUS1_FRAME_RECEIVE_OK)) {
+		if (rxstat1 & AR5K_5212_RX_DESC_STATUS1_CRC_ERROR)
 			rs->rs_status |= AR5K_RXERR_CRC;
 
-		if (rx_status->rx_status_1 &
-				AR5K_5212_RX_DESC_STATUS1_PHY_ERROR) {
+		if (rxstat1 & AR5K_5212_RX_DESC_STATUS1_PHY_ERROR) {
 			rs->rs_status |= AR5K_RXERR_PHY;
-			rs->rs_phyerr = AR5K_REG_MS(rx_status->rx_status_1,
+			rs->rs_phyerr = AR5K_REG_MS(rxstat1,
 				AR5K_5212_RX_DESC_STATUS1_PHY_ERROR_CODE);
 			if (!ah->ah_capabilities.cap_has_phyerr_counters)
 				ath5k_ani_phy_error_report(ah, rs->rs_phyerr);
 		}
 
-		if (rx_status->rx_status_1 &
-				AR5K_5212_RX_DESC_STATUS1_DECRYPT_CRC_ERROR)
+		if (rxstat1 & AR5K_5212_RX_DESC_STATUS1_DECRYPT_CRC_ERROR)
 			rs->rs_status |= AR5K_RXERR_DECRYPT;
 
-		if (rx_status->rx_status_1 &
-				AR5K_5212_RX_DESC_STATUS1_MIC_ERROR)
+		if (rxstat1 & AR5K_5212_RX_DESC_STATUS1_MIC_ERROR)
 			rs->rs_status |= AR5K_RXERR_MIC;
 	}
 	return 0;
diff -druN linux-2.6.39-libre/drivers/net/wireless/ath/ath5k/eeprom.c linux-3.0-rc7-libre/drivers/net/wireless/ath/ath5k/eeprom.c
--- linux-2.6.39-libre/drivers/net/wireless/ath/ath5k/eeprom.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/ath/ath5k/eeprom.c	2011-07-11 19:51:52.000000000 -0400
@@ -660,6 +660,51 @@
 		vp[i] = (ip[i] * max + (100 - ip[i]) * min) / 100;
 }
 
+static int
+ath5k_eeprom_free_pcal_info(struct ath5k_hw *ah, int mode)
+{
+	struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
+	struct ath5k_chan_pcal_info *chinfo;
+	u8 pier, pdg;
+
+	switch (mode) {
+	case AR5K_EEPROM_MODE_11A:
+		if (!AR5K_EEPROM_HDR_11A(ee->ee_header))
+			return 0;
+		chinfo = ee->ee_pwr_cal_a;
+		break;
+	case AR5K_EEPROM_MODE_11B:
+		if (!AR5K_EEPROM_HDR_11B(ee->ee_header))
+			return 0;
+		chinfo = ee->ee_pwr_cal_b;
+		break;
+	case AR5K_EEPROM_MODE_11G:
+		if (!AR5K_EEPROM_HDR_11G(ee->ee_header))
+			return 0;
+		chinfo = ee->ee_pwr_cal_g;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	for (pier = 0; pier < ee->ee_n_piers[mode]; pier++) {
+		if (!chinfo[pier].pd_curves)
+			continue;
+
+		for (pdg = 0; pdg < AR5K_EEPROM_N_PD_CURVES; pdg++) {
+			struct ath5k_pdgain_info *pd =
+					&chinfo[pier].pd_curves[pdg];
+
+			kfree(pd->pd_step);
+			kfree(pd->pd_pwr);
+		}
+
+		kfree(chinfo[pier].pd_curves);
+	}
+
+	return 0;
+}
+
 /* Convert RF5111 specific data to generic raw data
  * used by interpolation code */
 static int
@@ -684,7 +729,7 @@
 				GFP_KERNEL);
 
 		if (!chinfo[pier].pd_curves)
-			return -ENOMEM;
+			goto err_out;
 
 		/* Only one curve for RF5111
 		 * find out which one and place
@@ -708,12 +753,12 @@
 		pd->pd_step = kcalloc(AR5K_EEPROM_N_PWR_POINTS_5111,
 					sizeof(u8), GFP_KERNEL);
 		if (!pd->pd_step)
-			return -ENOMEM;
+			goto err_out;
 
 		pd->pd_pwr = kcalloc(AR5K_EEPROM_N_PWR_POINTS_5111,
 					sizeof(s16), GFP_KERNEL);
 		if (!pd->pd_pwr)
-			return -ENOMEM;
+			goto err_out;
 
 		/* Fill raw dataset
 		 * (convert power to 0.25dB units
@@ -734,6 +779,10 @@
 	}
 
 	return 0;
+
+err_out:
+	ath5k_eeprom_free_pcal_info(ah, mode);
+	return -ENOMEM;
 }
 
 /* Parse EEPROM data */
@@ -867,7 +916,7 @@
 					GFP_KERNEL);
 
 		if (!chinfo[pier].pd_curves)
-			return -ENOMEM;
+			goto err_out;
 
 		/* Fill pd_curves */
 		for (pdg = 0; pdg < ee->ee_pd_gains[mode]; pdg++) {
@@ -886,14 +935,13 @@
 						sizeof(u8), GFP_KERNEL);
 
 				if (!pd->pd_step)
-					return -ENOMEM;
+					goto err_out;
 
 				pd->pd_pwr = kcalloc(pd->pd_points,
 						sizeof(s16), GFP_KERNEL);
 
 				if (!pd->pd_pwr)
-					return -ENOMEM;
-
+					goto err_out;
 
 				/* Fill raw dataset
 				 * (all power levels are in 0.25dB units) */
@@ -925,13 +973,13 @@
 						sizeof(u8), GFP_KERNEL);
 
 				if (!pd->pd_step)
-					return -ENOMEM;
+					goto err_out;
 
 				pd->pd_pwr = kcalloc(pd->pd_points,
 						sizeof(s16), GFP_KERNEL);
 
 				if (!pd->pd_pwr)
-					return -ENOMEM;
+					goto err_out;
 
 				/* Fill raw dataset
 				 * (all power levels are in 0.25dB units) */
@@ -954,6 +1002,10 @@
 	}
 
 	return 0;
+
+err_out:
+	ath5k_eeprom_free_pcal_info(ah, mode);
+	return -ENOMEM;
 }
 
 /* Parse EEPROM data */
@@ -1156,7 +1208,7 @@
 					GFP_KERNEL);
 
 		if (!chinfo[pier].pd_curves)
-			return -ENOMEM;
+			goto err_out;
 
 		/* Fill pd_curves */
 		for (pdg = 0; pdg < ee->ee_pd_gains[mode]; pdg++) {
@@ -1177,13 +1229,13 @@
 					sizeof(u8), GFP_KERNEL);
 
 			if (!pd->pd_step)
-				return -ENOMEM;
+				goto err_out;
 
 			pd->pd_pwr = kcalloc(pd->pd_points,
 					sizeof(s16), GFP_KERNEL);
 
 			if (!pd->pd_pwr)
-				return -ENOMEM;
+				goto err_out;
 
 			/* Fill raw dataset
 			 * convert all pwr levels to
@@ -1213,6 +1265,10 @@
 	}
 
 	return 0;
+
+err_out:
+	ath5k_eeprom_free_pcal_info(ah, mode);
+	return -ENOMEM;
 }
 
 /* Parse EEPROM data */
@@ -1534,53 +1590,6 @@
 	return 0;
 }
 
-static int
-ath5k_eeprom_free_pcal_info(struct ath5k_hw *ah, int mode)
-{
-	struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
-	struct ath5k_chan_pcal_info *chinfo;
-	u8 pier, pdg;
-
-	switch (mode) {
-	case AR5K_EEPROM_MODE_11A:
-		if (!AR5K_EEPROM_HDR_11A(ee->ee_header))
-			return 0;
-		chinfo = ee->ee_pwr_cal_a;
-		break;
-	case AR5K_EEPROM_MODE_11B:
-		if (!AR5K_EEPROM_HDR_11B(ee->ee_header))
-			return 0;
-		chinfo = ee->ee_pwr_cal_b;
-		break;
-	case AR5K_EEPROM_MODE_11G:
-		if (!AR5K_EEPROM_HDR_11G(ee->ee_header))
-			return 0;
-		chinfo = ee->ee_pwr_cal_g;
-		break;
-	default:
-		return -EINVAL;
-	}
-
-	for (pier = 0; pier < ee->ee_n_piers[mode]; pier++) {
-		if (!chinfo[pier].pd_curves)
-			continue;
-
-		for (pdg = 0; pdg < ee->ee_pd_gains[mode]; pdg++) {
-			struct ath5k_pdgain_info *pd =
-					&chinfo[pier].pd_curves[pdg];
-
-			if (pd != NULL) {
-				kfree(pd->pd_step);
-				kfree(pd->pd_pwr);
-			}
-		}
-
-		kfree(chinfo[pier].pd_curves);
-	}
-
-	return 0;
-}
-
 /* Read conformance test limits used for regulatory control */
 static int
 ath5k_eeprom_read_ctl_info(struct ath5k_hw *ah)
@@ -1721,35 +1730,6 @@
 	return ret;
 }
 
-/*
- * Read the MAC address from eeprom
- */
-int ath5k_eeprom_read_mac(struct ath5k_hw *ah, u8 *mac)
-{
-	u8 mac_d[ETH_ALEN] = {};
-	u32 total, offset;
-	u16 data;
-	int octet;
-
-	AR5K_EEPROM_READ(0x20, data);
-
-	for (offset = 0x1f, octet = 0, total = 0; offset >= 0x1d; offset--) {
-		AR5K_EEPROM_READ(offset, data);
-
-		total += data;
-		mac_d[octet + 1] = data & 0xff;
-		mac_d[octet] = data >> 8;
-		octet += 2;
-	}
-
-	if (!total || total == 3 * 0xffff)
-		return -EINVAL;
-
-	memcpy(mac, mac_d, ETH_ALEN);
-
-	return 0;
-}
-
 
 /***********************\
 * Init/Detach functions *
diff -druN linux-2.6.39-libre/drivers/net/wireless/ath/ath5k/mac80211-ops.c linux-3.0-rc7-libre/drivers/net/wireless/ath/ath5k/mac80211-ops.c
--- linux-2.6.39-libre/drivers/net/wireless/ath/ath5k/mac80211-ops.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/ath/ath5k/mac80211-ops.c	2011-07-11 19:51:52.000000000 -0400
@@ -282,6 +282,15 @@
 	if (changes & BSS_CHANGED_BEACON_INT)
 		sc->bintval = bss_conf->beacon_int;
 
+	if (changes & BSS_CHANGED_ERP_SLOT) {
+		int slot_time;
+
+		ah->ah_short_slot = bss_conf->use_short_slot;
+		slot_time = ath5k_hw_get_default_slottime(ah) +
+			    3 * ah->ah_coverage_class;
+		ath5k_hw_set_ifs_intervals(ah, slot_time);
+	}
+
 	if (changes & BSS_CHANGED_ASSOC) {
 		avf->assoc = bss_conf->assoc;
 		if (bss_conf->assoc)
diff -druN linux-2.6.39-libre/drivers/net/wireless/ath/ath5k/pci.c linux-3.0-rc7-libre/drivers/net/wireless/ath/ath5k/pci.c
--- linux-2.6.39-libre/drivers/net/wireless/ath/ath5k/pci.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/ath/ath5k/pci.c	2011-07-11 19:51:52.000000000 -0400
@@ -17,6 +17,7 @@
 #include <linux/nl80211.h>
 #include <linux/pci.h>
 #include <linux/pci-aspm.h>
+#include <linux/etherdevice.h>
 #include "../ath.h"
 #include "ath5k.h"
 #include "debug.h"
@@ -108,11 +109,42 @@
 	return 0;
 }
 
+/*
+ * Read the MAC address from eeprom or platform_data
+ */
+static int ath5k_pci_eeprom_read_mac(struct ath5k_hw *ah, u8 *mac)
+{
+	u8 mac_d[ETH_ALEN] = {};
+	u32 total, offset;
+	u16 data;
+	int octet;
+
+	AR5K_EEPROM_READ(0x20, data);
+
+	for (offset = 0x1f, octet = 0, total = 0; offset >= 0x1d; offset--) {
+		AR5K_EEPROM_READ(offset, data);
+
+		total += data;
+		mac_d[octet + 1] = data & 0xff;
+		mac_d[octet] = data >> 8;
+		octet += 2;
+	}
+
+	if (!total || total == 3 * 0xffff)
+		return -EINVAL;
+
+	memcpy(mac, mac_d, ETH_ALEN);
+
+	return 0;
+}
+
+
 /* Common ath_bus_opts structure */
 static const struct ath_bus_ops ath_pci_bus_ops = {
 	.ath_bus_type = ATH_PCI,
 	.read_cachesize = ath5k_pci_read_cachesize,
 	.eeprom_read = ath5k_pci_eeprom_read,
+	.eeprom_read_mac = ath5k_pci_eeprom_read_mac,
 };
 
 /********************\
diff -druN linux-2.6.39-libre/drivers/net/wireless/ath/ath5k/pcu.c linux-3.0-rc7-libre/drivers/net/wireless/ath/ath5k/pcu.c
--- linux-2.6.39-libre/drivers/net/wireless/ath/ath5k/pcu.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/ath/ath5k/pcu.c	2011-07-11 19:51:52.000000000 -0400
@@ -75,7 +75,7 @@
  * bwmodes.
  */
 int ath5k_hw_get_frame_duration(struct ath5k_hw *ah,
-		int len, struct ieee80211_rate *rate)
+		int len, struct ieee80211_rate *rate, bool shortpre)
 {
 	struct ath5k_softc *sc = ah->ah_sc;
 	int sifs, preamble, plcp_bits, sym_time;
@@ -84,9 +84,15 @@
 
 	/* Fallback */
 	if (!ah->ah_bwmode) {
-		dur = ieee80211_generic_frame_duration(sc->hw,
-						NULL, len, rate);
-		return le16_to_cpu(dur);
+		__le16 raw_dur = ieee80211_generic_frame_duration(sc->hw,
+					NULL, len, rate);
+
+		/* subtract difference between long and short preamble */
+		dur = le16_to_cpu(raw_dur);
+		if (shortpre)
+			dur -= 96;
+
+		return dur;
 	}
 
 	bitrate = rate->bitrate;
@@ -145,9 +151,9 @@
 		slot_time = AR5K_INIT_SLOT_TIME_QUARTER_RATE;
 		break;
 	case AR5K_BWMODE_DEFAULT:
-		slot_time = AR5K_INIT_SLOT_TIME_DEFAULT;
 	default:
-		if (channel->hw_value & CHANNEL_CCK)
+		slot_time = AR5K_INIT_SLOT_TIME_DEFAULT;
+		if ((channel->hw_value & CHANNEL_CCK) && !ah->ah_short_slot)
 			slot_time = AR5K_INIT_SLOT_TIME_B;
 		break;
 	}
@@ -263,27 +269,14 @@
 		 * actual rate for this rate. See mac80211 tx.c
 		 * ieee80211_duration() for a brief description of
 		 * what rate we should choose to TX ACKs. */
-		tx_time = ath5k_hw_get_frame_duration(ah, 10, rate);
+		tx_time = ath5k_hw_get_frame_duration(ah, 10, rate, false);
 
 		ath5k_hw_reg_write(ah, tx_time, reg);
 
 		if (!(rate->flags & IEEE80211_RATE_SHORT_PREAMBLE))
 			continue;
 
-		/*
-		 * We're not distinguishing short preamble here,
-		 * This is true, all we'll get is a longer value here
-		 * which is not necessarilly bad. We could use
-		 * export ieee80211_frame_duration() but that needs to be
-		 * fixed first to be properly used by mac802111 drivers:
-		 *
-		 *  - remove erp stuff and let the routine figure ofdm
-		 *    erp rates
-		 *  - remove passing argument ieee80211_local as
-		 *    drivers don't have access to it
-		 *  - move drivers using ieee80211_generic_frame_duration()
-		 *    to this
-		 */
+		tx_time = ath5k_hw_get_frame_duration(ah, 10, rate, true);
 		ath5k_hw_reg_write(ah, tx_time,
 			reg + (AR5K_SET_SHORT_PREAMBLE << 2));
 	}
diff -druN linux-2.6.39-libre/drivers/net/wireless/ath/ath5k/qcu.c linux-3.0-rc7-libre/drivers/net/wireless/ath/ath5k/qcu.c
--- linux-2.6.39-libre/drivers/net/wireless/ath/ath5k/qcu.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/ath/ath5k/qcu.c	2011-07-11 19:51:52.000000000 -0400
@@ -519,7 +519,7 @@
 		return -EINVAL;
 
 	sifs = ath5k_hw_get_default_sifs(ah);
-	sifs_clock = ath5k_hw_htoclock(ah, sifs);
+	sifs_clock = ath5k_hw_htoclock(ah, sifs - 2);
 
 	/* EIFS
 	 * Txtime of ack at lowest rate + SIFS + DIFS
@@ -550,7 +550,7 @@
 	else
 		rate = &sc->sbands[IEEE80211_BAND_2GHZ].bitrates[0];
 
-	ack_tx_time = ath5k_hw_get_frame_duration(ah, 10, rate);
+	ack_tx_time = ath5k_hw_get_frame_duration(ah, 10, rate, false);
 
 	/* ack_tx_time includes an SIFS already */
 	eifs = ack_tx_time + sifs + 2 * slot_time;
diff -druN linux-2.6.39-libre/drivers/net/wireless/ath/ath5k/reset.c linux-3.0-rc7-libre/drivers/net/wireless/ath/ath5k/reset.c
--- linux-2.6.39-libre/drivers/net/wireless/ath/ath5k/reset.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/ath/ath5k/reset.c	2011-07-11 19:51:52.000000000 -0400
@@ -159,6 +159,11 @@
 	rxlat = AR5K_REG_MS(usec_reg, AR5K_USEC_RX_LATENCY_5211);
 
 	/*
+	 * Set default Tx frame to Tx data start delay
+	 */
+	txf2txs = AR5K_INIT_TXF2TXD_START_DEFAULT;
+
+	/*
 	 * 5210 initvals don't include usec settings
 	 * so we need to use magic values here for
 	 * tx/rx latencies
@@ -1119,8 +1124,11 @@
 			/* Non fatal, can happen eg.
 			 * on mode change */
 			ret = 0;
-		} else
+		} else {
+			ATH5K_DBG(ah->ah_sc, ATH5K_DEBUG_RESET,
+				"fast chan change successful\n");
 			return 0;
+		}
 	}
 
 	/*
diff -druN linux-2.6.39-libre/drivers/net/wireless/ath/ath9k/ahb.c linux-3.0-rc7-libre/drivers/net/wireless/ath/ath9k/ahb.c
--- linux-2.6.39-libre/drivers/net/wireless/ath/ath9k/ahb.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/ath/ath9k/ahb.c	2011-07-11 19:51:52.000000000 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008-2009 Atheros Communications Inc.
+ * Copyright (c) 2008-2011 Atheros Communications Inc.
  * Copyright (c) 2009 Gabor Juhos <juhosg@openwrt.org>
  * Copyright (c) 2009 Imre Kaloz <kaloz@openwrt.org>
  *
@@ -21,6 +21,18 @@
 #include <linux/ath9k_platform.h>
 #include "ath9k.h"
 
+static const struct platform_device_id ath9k_platform_id_table[] = {
+	{
+		.name = "ath9k",
+		.driver_data = AR5416_AR9100_DEVID,
+	},
+	{
+		.name = "ar934x_wmac",
+		.driver_data = AR9300_DEVID_AR9340,
+	},
+	{},
+};
+
 /* return bus cachesize in 4B word units */
 static void ath_ahb_read_cachesize(struct ath_common *common, int *csz)
 {
@@ -57,6 +69,7 @@
 	struct ath_softc *sc;
 	struct ieee80211_hw *hw;
 	struct resource *res;
+	const struct platform_device_id *id = platform_get_device_id(pdev);
 	int irq;
 	int ret = 0;
 	struct ath_hw *ah;
@@ -116,7 +129,7 @@
 		goto err_free_hw;
 	}
 
-	ret = ath9k_init_device(AR5416_AR9100_DEVID, sc, 0x0, &ath_ahb_bus_ops);
+	ret = ath9k_init_device(id->driver_data, sc, 0x0, &ath_ahb_bus_ops);
 	if (ret) {
 		dev_err(&pdev->dev, "failed to initialize device\n");
 		goto err_irq;
@@ -165,8 +178,11 @@
 		.name	= "ath9k",
 		.owner	= THIS_MODULE,
 	},
+	.id_table    = ath9k_platform_id_table,
 };
 
+MODULE_DEVICE_TABLE(platform, ath9k_platform_id_table);
+
 int ath_ahb_init(void)
 {
 	return platform_driver_register(&ath_ahb_driver);
diff -druN linux-2.6.39-libre/drivers/net/wireless/ath/ath9k/ani.c linux-3.0-rc7-libre/drivers/net/wireless/ath/ath9k/ani.c
--- linux-2.6.39-libre/drivers/net/wireless/ath/ath9k/ani.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/ath/ath9k/ani.c	2011-07-11 19:51:52.000000000 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008-2010 Atheros Communications Inc.
+ * Copyright (c) 2008-2011 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
@@ -899,12 +899,6 @@
 	 * check here default level should not modify INI setting.
 	 */
 	if (use_new_ani(ah)) {
-		const struct ani_ofdm_level_entry *entry_ofdm;
-		const struct ani_cck_level_entry *entry_cck;
-
-		entry_ofdm = &ofdm_level_table[ATH9K_ANI_OFDM_DEF_LEVEL];
-		entry_cck = &cck_level_table[ATH9K_ANI_CCK_DEF_LEVEL];
-
 		ah->aniperiod = ATH9K_ANI_PERIOD_NEW;
 		ah->config.ani_poll_interval = ATH9K_ANI_POLLINTERVAL_NEW;
 	} else {
diff -druN linux-2.6.39-libre/drivers/net/wireless/ath/ath9k/ani.h linux-3.0-rc7-libre/drivers/net/wireless/ath/ath9k/ani.h
--- linux-2.6.39-libre/drivers/net/wireless/ath/ath9k/ani.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/ath/ath9k/ani.h	2011-07-11 19:51:52.000000000 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008-2009 Atheros Communications Inc.
+ * Copyright (c) 2008-2011 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
diff -druN linux-2.6.39-libre/drivers/net/wireless/ath/ath9k/ar5008_initvals.h linux-3.0-rc7-libre/drivers/net/wireless/ath/ath9k/ar5008_initvals.h
--- linux-2.6.39-libre/drivers/net/wireless/ath/ath9k/ar5008_initvals.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/ath/ath9k/ar5008_initvals.h	2011-07-11 19:51:52.000000000 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010 Atheros Communications Inc.
+ * Copyright (c) 2010-2011 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
diff -druN linux-2.6.39-libre/drivers/net/wireless/ath/ath9k/ar5008_phy.c linux-3.0-rc7-libre/drivers/net/wireless/ath/ath9k/ar5008_phy.c
--- linux-2.6.39-libre/drivers/net/wireless/ath/ath9k/ar5008_phy.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/ath/ath9k/ar5008_phy.c	2011-07-11 19:51:52.000000000 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008-2010 Atheros Communications Inc.
+ * Copyright (c) 2008-2011 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
@@ -44,6 +44,34 @@
 static const int m2ThreshExt_off = 127;
 
 
+static void ar5008_rf_bank_setup(u32 *bank, struct ar5416IniArray *array,
+				 int col)
+{
+	int i;
+
+	for (i = 0; i < array->ia_rows; i++)
+		bank[i] = INI_RA(array, i, col);
+}
+
+
+#define REG_WRITE_RF_ARRAY(iniarray, regData, regWr) \
+	ar5008_write_rf_array(ah, iniarray, regData, &(regWr))
+
+static void ar5008_write_rf_array(struct ath_hw *ah, struct ar5416IniArray *array,
+				  u32 *data, unsigned int *writecnt)
+{
+	int r;
+
+	ENABLE_REGWRITE_BUFFER(ah);
+
+	for (r = 0; r < array->ia_rows; r++) {
+		REG_WRITE(ah, INI_RA(array, r, 0), data[r]);
+		DO_DELAY(*writecnt);
+	}
+
+	REGWRITE_BUFFER_FLUSH(ah);
+}
+
 /**
  * ar5008_hw_phy_modify_rx_buffer() - perform analog swizzling of parameters
  * @rfbuf:
@@ -530,16 +558,16 @@
 	eepMinorRev = ah->eep_ops->get_eeprom(ah, EEP_MINOR_REV);
 
 	/* Setup Bank 0 Write */
-	RF_BANK_SETUP(ah->analogBank0Data, &ah->iniBank0, 1);
+	ar5008_rf_bank_setup(ah->analogBank0Data, &ah->iniBank0, 1);
 
 	/* Setup Bank 1 Write */
-	RF_BANK_SETUP(ah->analogBank1Data, &ah->iniBank1, 1);
+	ar5008_rf_bank_setup(ah->analogBank1Data, &ah->iniBank1, 1);
 
 	/* Setup Bank 2 Write */
-	RF_BANK_SETUP(ah->analogBank2Data, &ah->iniBank2, 1);
+	ar5008_rf_bank_setup(ah->analogBank2Data, &ah->iniBank2, 1);
 
 	/* Setup Bank 6 Write */
-	RF_BANK_SETUP(ah->analogBank3Data, &ah->iniBank3,
+	ar5008_rf_bank_setup(ah->analogBank3Data, &ah->iniBank3,
 		      modesIndex);
 	{
 		int i;
@@ -569,7 +597,7 @@
 	}
 
 	/* Setup Bank 7 Setup */
-	RF_BANK_SETUP(ah->analogBank7Data, &ah->iniBank7, 1);
+	ar5008_rf_bank_setup(ah->analogBank7Data, &ah->iniBank7, 1);
 
 	/* Write Analog registers */
 	REG_WRITE_RF_ARRAY(&ah->iniBank0, ah->analogBank0Data,
@@ -729,6 +757,7 @@
 				 struct ath9k_channel *chan)
 {
 	struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
+	struct ath_common *common = ath9k_hw_common(ah);
 	int i, regWrites = 0;
 	struct ieee80211_channel *channel = chan->chan;
 	u32 modesIndex, freqIndex;
@@ -805,7 +834,8 @@
 		REG_WRITE(ah, reg, val);
 
 		if (reg >= 0x7800 && reg < 0x78a0
-		    && ah->config.analog_shiftreg) {
+		    && ah->config.analog_shiftreg
+		    && (common->bus_ops->ath_bus_type != ATH_USB)) {
 			udelay(100);
 		}
 
@@ -835,7 +865,8 @@
 		REG_WRITE(ah, reg, val);
 
 		if (reg >= 0x7800 && reg < 0x78a0
-		    && ah->config.analog_shiftreg) {
+		    && ah->config.analog_shiftreg
+		    && (common->bus_ops->ath_bus_type != ATH_USB)) {
 			udelay(100);
 		}
 
diff -druN linux-2.6.39-libre/drivers/net/wireless/ath/ath9k/ar9001_initvals.h linux-3.0-rc7-libre/drivers/net/wireless/ath/ath9k/ar9001_initvals.h
--- linux-2.6.39-libre/drivers/net/wireless/ath/ath9k/ar9001_initvals.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/ath/ath9k/ar9001_initvals.h	2011-07-11 19:51:52.000000000 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010 Atheros Communications Inc.
+ * Copyright (c) 2010-2011 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
diff -druN linux-2.6.39-libre/drivers/net/wireless/ath/ath9k/ar9002_calib.c linux-3.0-rc7-libre/drivers/net/wireless/ath/ath9k/ar9002_calib.c
--- linux-2.6.39-libre/drivers/net/wireless/ath/ath9k/ar9002_calib.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/ath/ath9k/ar9002_calib.c	2011-07-11 19:51:52.000000000 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008-2010 Atheros Communications Inc.
+ * Copyright (c) 2008-2011 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
@@ -26,6 +26,27 @@
 	IQ_MISMATCH_CAL = BIT(2),
 };
 
+static bool ar9002_hw_is_cal_supported(struct ath_hw *ah,
+				struct ath9k_channel *chan,
+				enum ar9002_cal_types cal_type)
+{
+	bool supported = false;
+	switch (ah->supp_cals & cal_type) {
+	case IQ_MISMATCH_CAL:
+		/* Run IQ Mismatch for non-CCK only */
+		if (!IS_CHAN_B(chan))
+			supported = true;
+		break;
+	case ADC_GAIN_CAL:
+	case ADC_DC_CAL:
+		/* Run ADC Gain Cal for non-CCK & non 2GHz-HT20 only */
+		if (!IS_CHAN_B(chan) &&
+		    !(IS_CHAN_2GHZ(chan) && IS_CHAN_HT20(chan)))
+			supported = true;
+		break;
+	}
+	return supported;
+}
 
 static void ar9002_hw_setup_calibration(struct ath_hw *ah,
 					struct ath9k_cal_list *currCal)
@@ -808,7 +829,7 @@
 	if (AR_SREV_9271(ah)) {
 		if (!ar9285_hw_cl_cal(ah, chan))
 			return false;
-	} else if (AR_SREV_9285_12_OR_LATER(ah)) {
+	} else if (AR_SREV_9285(ah) && AR_SREV_9285_12_OR_LATER(ah)) {
 		if (!ar9285_hw_clc(ah, chan))
 			return false;
 	} else {
@@ -858,26 +879,32 @@
 	if (AR_SREV_9100(ah) || AR_SREV_9160_10_OR_LATER(ah)) {
 		ah->supp_cals = IQ_MISMATCH_CAL;
 
-		if (AR_SREV_9160_10_OR_LATER(ah) &&
-		    !(IS_CHAN_2GHZ(chan) && IS_CHAN_HT20(chan))) {
+		if (AR_SREV_9160_10_OR_LATER(ah))
 			ah->supp_cals |= ADC_GAIN_CAL | ADC_DC_CAL;
 
+		if (AR_SREV_9287(ah))
+			ah->supp_cals &= ~ADC_GAIN_CAL;
 
+		if (ar9002_hw_is_cal_supported(ah, chan, ADC_GAIN_CAL)) {
 			INIT_CAL(&ah->adcgain_caldata);
 			INSERT_CAL(ah, &ah->adcgain_caldata);
 			ath_dbg(common, ATH_DBG_CALIBRATE,
-				"enabling ADC Gain Calibration.\n");
+					"enabling ADC Gain Calibration.\n");
+		}
 
+		if (ar9002_hw_is_cal_supported(ah, chan, ADC_DC_CAL)) {
 			INIT_CAL(&ah->adcdc_caldata);
 			INSERT_CAL(ah, &ah->adcdc_caldata);
 			ath_dbg(common, ATH_DBG_CALIBRATE,
-				"enabling ADC DC Calibration.\n");
+					"enabling ADC DC Calibration.\n");
 		}
 
-		INIT_CAL(&ah->iq_caldata);
-		INSERT_CAL(ah, &ah->iq_caldata);
-		ath_dbg(common, ATH_DBG_CALIBRATE,
-			"enabling IQ Calibration.\n");
+		if (ar9002_hw_is_cal_supported(ah, chan, IQ_MISMATCH_CAL)) {
+			INIT_CAL(&ah->iq_caldata);
+			INSERT_CAL(ah, &ah->iq_caldata);
+			ath_dbg(common, ATH_DBG_CALIBRATE,
+					"enabling IQ Calibration.\n");
+		}
 
 		ah->cal_list_curr = ah->cal_list;
 
diff -druN linux-2.6.39-libre/drivers/net/wireless/ath/ath9k/ar9002_hw.c linux-3.0-rc7-libre/drivers/net/wireless/ath/ath9k/ar9002_hw.c
--- linux-2.6.39-libre/drivers/net/wireless/ath/ath9k/ar9002_hw.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/ath/ath9k/ar9002_hw.c	2011-07-11 19:51:52.000000000 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008-2010 Atheros Communications Inc.
+ * Copyright (c) 2008-2011 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
diff -druN linux-2.6.39-libre/drivers/net/wireless/ath/ath9k/ar9002_initvals.h linux-3.0-rc7-libre/drivers/net/wireless/ath/ath9k/ar9002_initvals.h
--- linux-2.6.39-libre/drivers/net/wireless/ath/ath9k/ar9002_initvals.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/ath/ath9k/ar9002_initvals.h	2011-07-11 19:51:52.000000000 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010 Atheros Communications Inc.
+ * Copyright (c) 2010-2011 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
diff -druN linux-2.6.39-libre/drivers/net/wireless/ath/ath9k/ar9002_mac.c linux-3.0-rc7-libre/drivers/net/wireless/ath/ath9k/ar9002_mac.c
--- linux-2.6.39-libre/drivers/net/wireless/ath/ath9k/ar9002_mac.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/ath/ath9k/ar9002_mac.c	2011-07-11 19:51:52.000000000 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008-2009 Atheros Communications Inc.
+ * Copyright (c) 2008-2011 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
@@ -290,7 +290,6 @@
 		| (flags & ATH9K_TXDESC_VMF ? AR_VirtMoreFrag : 0)
 		| SM(txPower, AR_XmitPower)
 		| (flags & ATH9K_TXDESC_VEOL ? AR_VEOL : 0)
-		| (flags & ATH9K_TXDESC_CLRDMASK ? AR_ClrDestMask : 0)
 		| (flags & ATH9K_TXDESC_INTREQ ? AR_TxIntrReq : 0)
 		| (keyIx != ATH9K_TXKEYIX_INVALID ? AR_DestIdxValid : 0);
 
@@ -311,6 +310,16 @@
 	}
 }
 
+static void ar9002_hw_set_clrdmask(struct ath_hw *ah, void *ds, bool val)
+{
+	struct ar5416_desc *ads = AR5416DESC(ds);
+
+	if (val)
+		ads->ds_ctl0 |= AR_ClrDestMask;
+	else
+		ads->ds_ctl0 &= ~AR_ClrDestMask;
+}
+
 static void ar9002_hw_set11n_ratescenario(struct ath_hw *ah, void *ds,
 					  void *lastds,
 					  u32 durUpdateEn, u32 rtsctsRate,
@@ -406,26 +415,6 @@
 	ads->ds_ctl1 &= (~AR_IsAggr & ~AR_MoreAggr);
 }
 
-static void ar9002_hw_set11n_burstduration(struct ath_hw *ah, void *ds,
-					   u32 burstDuration)
-{
-	struct ar5416_desc *ads = AR5416DESC(ds);
-
-	ads->ds_ctl2 &= ~AR_BurstDur;
-	ads->ds_ctl2 |= SM(burstDuration, AR_BurstDur);
-}
-
-static void ar9002_hw_set11n_virtualmorefrag(struct ath_hw *ah, void *ds,
-					    u32 vmf)
-{
-	struct ar5416_desc *ads = AR5416DESC(ds);
-
-	if (vmf)
-		ads->ds_ctl0 |= AR_VirtMoreFrag;
-	else
-		ads->ds_ctl0 &= ~AR_VirtMoreFrag;
-}
-
 void ath9k_hw_setuprxdesc(struct ath_hw *ah, struct ath_desc *ds,
 			  u32 size, u32 flags)
 {
@@ -458,6 +447,5 @@
 	ops->set11n_aggr_middle = ar9002_hw_set11n_aggr_middle;
 	ops->set11n_aggr_last = ar9002_hw_set11n_aggr_last;
 	ops->clr11n_aggr = ar9002_hw_clr11n_aggr;
-	ops->set11n_burstduration = ar9002_hw_set11n_burstduration;
-	ops->set11n_virtualmorefrag = ar9002_hw_set11n_virtualmorefrag;
+	ops->set_clrdmask = ar9002_hw_set_clrdmask;
 }
diff -druN linux-2.6.39-libre/drivers/net/wireless/ath/ath9k/ar9002_phy.c linux-3.0-rc7-libre/drivers/net/wireless/ath/ath9k/ar9002_phy.c
--- linux-2.6.39-libre/drivers/net/wireless/ath/ath9k/ar9002_phy.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/ath/ath9k/ar9002_phy.c	2011-07-11 19:51:52.000000000 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008-2010 Atheros Communications Inc.
+ * Copyright (c) 2008-2011 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
@@ -517,23 +517,7 @@
 	}
 }
 
-void ar9002_hw_attach_phy_ops(struct ath_hw *ah)
-{
-	struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah);
-
-	priv_ops->set_rf_regs = NULL;
-	priv_ops->rf_alloc_ext_banks = NULL;
-	priv_ops->rf_free_ext_banks = NULL;
-	priv_ops->rf_set_freq = ar9002_hw_set_channel;
-	priv_ops->spur_mitigate_freq = ar9002_hw_spur_mitigate;
-	priv_ops->olc_init = ar9002_olc_init;
-	priv_ops->compute_pll_control = ar9002_hw_compute_pll_control;
-	priv_ops->do_getnf = ar9002_hw_do_getnf;
-
-	ar9002_hw_set_nf_limits(ah);
-}
-
-void ath9k_hw_antdiv_comb_conf_get(struct ath_hw *ah,
+static void ar9002_hw_antdiv_comb_conf_get(struct ath_hw *ah,
 				   struct ath_hw_antcomb_conf *antconf)
 {
 	u32 regval;
@@ -545,10 +529,11 @@
 				 AR_PHY_9285_ANT_DIV_ALT_LNACONF_S;
 	antconf->fast_div_bias = (regval & AR_PHY_9285_FAST_DIV_BIAS) >>
 				  AR_PHY_9285_FAST_DIV_BIAS_S;
+	antconf->lna1_lna2_delta = -3;
+	antconf->div_group = 0;
 }
-EXPORT_SYMBOL(ath9k_hw_antdiv_comb_conf_get);
 
-void ath9k_hw_antdiv_comb_conf_set(struct ath_hw *ah,
+static void ar9002_hw_antdiv_comb_conf_set(struct ath_hw *ah,
 				   struct ath_hw_antcomb_conf *antconf)
 {
 	u32 regval;
@@ -566,4 +551,23 @@
 
 	REG_WRITE(ah, AR_PHY_MULTICHAIN_GAIN_CTL, regval);
 }
-EXPORT_SYMBOL(ath9k_hw_antdiv_comb_conf_set);
+
+void ar9002_hw_attach_phy_ops(struct ath_hw *ah)
+{
+	struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah);
+	struct ath_hw_ops *ops = ath9k_hw_ops(ah);
+
+	priv_ops->set_rf_regs = NULL;
+	priv_ops->rf_alloc_ext_banks = NULL;
+	priv_ops->rf_free_ext_banks = NULL;
+	priv_ops->rf_set_freq = ar9002_hw_set_channel;
+	priv_ops->spur_mitigate_freq = ar9002_hw_spur_mitigate;
+	priv_ops->olc_init = ar9002_olc_init;
+	priv_ops->compute_pll_control = ar9002_hw_compute_pll_control;
+	priv_ops->do_getnf = ar9002_hw_do_getnf;
+
+	ops->antdiv_comb_conf_get = ar9002_hw_antdiv_comb_conf_get;
+	ops->antdiv_comb_conf_set = ar9002_hw_antdiv_comb_conf_set;
+
+	ar9002_hw_set_nf_limits(ah);
+}
diff -druN linux-2.6.39-libre/drivers/net/wireless/ath/ath9k/ar9002_phy.h linux-3.0-rc7-libre/drivers/net/wireless/ath/ath9k/ar9002_phy.h
--- linux-2.6.39-libre/drivers/net/wireless/ath/ath9k/ar9002_phy.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/ath/ath9k/ar9002_phy.h	2011-07-11 19:51:52.000000000 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008-2010 Atheros Communications Inc.
+ * Copyright (c) 2008-2011 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
@@ -483,7 +483,11 @@
 #define AR_PHY_TX_PWRCTRL_INIT_TX_GAIN     0x01F80000
 #define AR_PHY_TX_PWRCTRL_INIT_TX_GAIN_S   19
 
+#define AR_PHY_TX_PWRCTRL8       0xa278
+
 #define AR_PHY_TX_PWRCTRL9       0xa27C
+
+#define AR_PHY_TX_PWRCTRL10       0xa394
 #define AR_PHY_TX_DESIRED_SCALE_CCK        0x00007C00
 #define AR_PHY_TX_DESIRED_SCALE_CCK_S      10
 #define AR_PHY_TX_PWRCTRL9_RES_DC_REMOVAL  0x80000000
@@ -495,6 +499,8 @@
 
 #define AR_PHY_CH0_TX_PWRCTRL11  0xa398
 #define AR_PHY_CH1_TX_PWRCTRL11  0xb398
+#define AR_PHY_CH0_TX_PWRCTRL12  0xa3dc
+#define AR_PHY_CH0_TX_PWRCTRL13  0xa3e0
 #define AR_PHY_TX_PWRCTRL_OLPC_TEMP_COMP   0x0000FC00
 #define AR_PHY_TX_PWRCTRL_OLPC_TEMP_COMP_S 10
 
diff -druN linux-2.6.39-libre/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h linux-3.0-rc7-libre/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h
--- linux-2.6.39-libre/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h	2011-07-11 19:51:52.000000000 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010 Atheros Communications Inc.
+ * Copyright (c) 2010-2011 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
@@ -34,10 +34,10 @@
 
 static const u32 ar9300Modes_lowest_ob_db_tx_gain_table_2p2[][5] = {
 	/* Addr      5G_HT20     5G_HT40     2G_HT40     2G_HT20   */
-	{0x0000a2dc, 0x00033800, 0x00033800, 0x00637800, 0x00637800},
-	{0x0000a2e0, 0x0003c000, 0x0003c000, 0x03838000, 0x03838000},
-	{0x0000a2e4, 0x03fc0000, 0x03fc0000, 0x03fc0000, 0x03fc0000},
-	{0x0000a2e8, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+	{0x0000a2dc, 0x00033800, 0x00033800, 0x03aaa352, 0x03aaa352},
+	{0x0000a2e0, 0x0003c000, 0x0003c000, 0x03ccc584, 0x03ccc584},
+	{0x0000a2e4, 0x03fc0000, 0x03fc0000, 0x03f0f800, 0x03f0f800},
+	{0x0000a2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
 	{0x0000a410, 0x000050d9, 0x000050d9, 0x000050d9, 0x000050d9},
 	{0x0000a500, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
 	{0x0000a504, 0x06000003, 0x06000003, 0x04000002, 0x04000002},
@@ -119,14 +119,14 @@
 	{0x0000a634, 0x04411104, 0x04411104, 0x04015005, 0x04015005},
 	{0x0000a638, 0x04411104, 0x04411104, 0x04015005, 0x04015005},
 	{0x0000a63c, 0x04411104, 0x04411104, 0x04015005, 0x04015005},
-	{0x0000b2dc, 0x00033800, 0x00033800, 0x00637800, 0x00637800},
-	{0x0000b2e0, 0x0003c000, 0x0003c000, 0x03838000, 0x03838000},
-	{0x0000b2e4, 0x03fc0000, 0x03fc0000, 0x03fc0000, 0x03fc0000},
-	{0x0000b2e8, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
-	{0x0000c2dc, 0x00033800, 0x00033800, 0x00637800, 0x00637800},
-	{0x0000c2e0, 0x0003c000, 0x0003c000, 0x03838000, 0x03838000},
-	{0x0000c2e4, 0x03fc0000, 0x03fc0000, 0x03fc0000, 0x03fc0000},
-	{0x0000c2e8, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+	{0x0000b2dc, 0x00033800, 0x00033800, 0x03aaa352, 0x03aaa352},
+	{0x0000b2e0, 0x0003c000, 0x0003c000, 0x03ccc584, 0x03ccc584},
+	{0x0000b2e4, 0x03fc0000, 0x03fc0000, 0x03f0f800, 0x03f0f800},
+	{0x0000b2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
+	{0x0000c2dc, 0x00033800, 0x00033800, 0x03aaa352, 0x03aaa352},
+	{0x0000c2e0, 0x0003c000, 0x0003c000, 0x03ccc584, 0x03ccc584},
+	{0x0000c2e4, 0x03fc0000, 0x03fc0000, 0x03f0f800, 0x03f0f800},
+	{0x0000c2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
 	{0x00016044, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4},
 	{0x00016048, 0x62480001, 0x62480001, 0x62480001, 0x62480001},
 	{0x00016068, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
@@ -835,10 +835,10 @@
 
 static const u32 ar9300Modes_high_power_tx_gain_table_2p2[][5] = {
 	/* Addr      5G_HT20     5G_HT40     2G_HT40     2G_HT20   */
-	{0x0000a2dc, 0x0380c7fc, 0x0380c7fc, 0x00637800, 0x00637800},
-	{0x0000a2e0, 0x0000f800, 0x0000f800, 0x03838000, 0x03838000},
-	{0x0000a2e4, 0x03ff0000, 0x03ff0000, 0x03fc0000, 0x03fc0000},
-	{0x0000a2e8, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+	{0x0000a2dc, 0x0380c7fc, 0x0380c7fc, 0x03aaa352, 0x03aaa352},
+	{0x0000a2e0, 0x0000f800, 0x0000f800, 0x03ccc584, 0x03ccc584},
+	{0x0000a2e4, 0x03ff0000, 0x03ff0000, 0x03f0f800, 0x03f0f800},
+	{0x0000a2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
 	{0x0000a410, 0x000050d8, 0x000050d8, 0x000050d9, 0x000050d9},
 	{0x0000a500, 0x00002220, 0x00002220, 0x00000000, 0x00000000},
 	{0x0000a504, 0x04002222, 0x04002222, 0x04000002, 0x04000002},
@@ -920,14 +920,14 @@
 	{0x0000a634, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005},
 	{0x0000a638, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005},
 	{0x0000a63c, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005},
-	{0x0000b2dc, 0x0380c7fc, 0x0380c7fc, 0x00637800, 0x00637800},
-	{0x0000b2e0, 0x0000f800, 0x0000f800, 0x03838000, 0x03838000},
-	{0x0000b2e4, 0x03ff0000, 0x03ff0000, 0x03fc0000, 0x03fc0000},
-	{0x0000b2e8, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
-	{0x0000c2dc, 0x0380c7fc, 0x0380c7fc, 0x00637800, 0x00637800},
-	{0x0000c2e0, 0x0000f800, 0x0000f800, 0x03838000, 0x03838000},
-	{0x0000c2e4, 0x03ff0000, 0x03ff0000, 0x03fc0000, 0x03fc0000},
-	{0x0000c2e8, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+	{0x0000b2dc, 0x0380c7fc, 0x0380c7fc, 0x03aaa352, 0x03aaa352},
+	{0x0000b2e0, 0x0000f800, 0x0000f800, 0x03ccc584, 0x03ccc584},
+	{0x0000b2e4, 0x03ff0000, 0x03ff0000, 0x03f0f800, 0x03f0f800},
+	{0x0000b2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
+	{0x0000c2dc, 0x0380c7fc, 0x0380c7fc, 0x03aaa352, 0x03aaa352},
+	{0x0000c2e0, 0x0000f800, 0x0000f800, 0x03ccc584, 0x03ccc584},
+	{0x0000c2e4, 0x03ff0000, 0x03ff0000, 0x03f0f800, 0x03f0f800},
+	{0x0000c2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
 	{0x00016044, 0x056db2e6, 0x056db2e6, 0x056db2e6, 0x056db2e6},
 	{0x00016048, 0xae480001, 0xae480001, 0xae480001, 0xae480001},
 	{0x00016068, 0x6eb6db6c, 0x6eb6db6c, 0x6eb6db6c, 0x6eb6db6c},
@@ -941,10 +941,10 @@
 
 static const u32 ar9300Modes_high_ob_db_tx_gain_table_2p2[][5] = {
 	/* Addr      5G_HT20     5G_HT40     2G_HT40     2G_HT20   */
-	{0x0000a2dc, 0x01feee00, 0x01feee00, 0x00637800, 0x00637800},
-	{0x0000a2e0, 0x0000f000, 0x0000f000, 0x03838000, 0x03838000},
-	{0x0000a2e4, 0x01ff0000, 0x01ff0000, 0x03fc0000, 0x03fc0000},
-	{0x0000a2e8, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+	{0x0000a2dc, 0x01feee00, 0x01feee00, 0x03aaa352, 0x03aaa352},
+	{0x0000a2e0, 0x0000f000, 0x0000f000, 0x03ccc584, 0x03ccc584},
+	{0x0000a2e4, 0x01ff0000, 0x01ff0000, 0x03f0f800, 0x03f0f800},
+	{0x0000a2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
 	{0x0000a410, 0x000050d8, 0x000050d8, 0x000050d9, 0x000050d9},
 	{0x0000a500, 0x00002220, 0x00002220, 0x00000000, 0x00000000},
 	{0x0000a504, 0x04002222, 0x04002222, 0x04000002, 0x04000002},
@@ -1026,14 +1026,14 @@
 	{0x0000a634, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005},
 	{0x0000a638, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005},
 	{0x0000a63c, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005},
-	{0x0000b2dc, 0x01feee00, 0x01feee00, 0x00637800, 0x00637800},
-	{0x0000b2e0, 0x0000f000, 0x0000f000, 0x03838000, 0x03838000},
-	{0x0000b2e4, 0x01ff0000, 0x01ff0000, 0x03fc0000, 0x03fc0000},
-	{0x0000b2e8, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
-	{0x0000c2dc, 0x01feee00, 0x01feee00, 0x00637800, 0x00637800},
-	{0x0000c2e0, 0x0000f000, 0x0000f000, 0x03838000, 0x03838000},
-	{0x0000c2e4, 0x01ff0000, 0x01ff0000, 0x03fc0000, 0x03fc0000},
-	{0x0000c2e8, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+	{0x0000b2dc, 0x01feee00, 0x01feee00, 0x03aaa352, 0x03aaa352},
+	{0x0000b2e0, 0x0000f000, 0x0000f000, 0x03ccc584, 0x03ccc584},
+	{0x0000b2e4, 0x01ff0000, 0x01ff0000, 0x03f0f800, 0x03f0f800},
+	{0x0000b2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
+	{0x0000c2dc, 0x01feee00, 0x01feee00, 0x03aaa352, 0x03aaa352},
+	{0x0000c2e0, 0x0000f000, 0x0000f000, 0x03ccc584, 0x03ccc584},
+	{0x0000c2e4, 0x01ff0000, 0x01ff0000, 0x03f0f800, 0x03f0f800},
+	{0x0000c2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
 	{0x00016044, 0x056db2e4, 0x056db2e4, 0x056db2e4, 0x056db2e4},
 	{0x00016048, 0x8e480001, 0x8e480001, 0x8e480001, 0x8e480001},
 	{0x00016068, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
@@ -1307,10 +1307,10 @@
 
 static const u32 ar9300Modes_low_ob_db_tx_gain_table_2p2[][5] = {
 	/* Addr      5G_HT20     5G_HT40     2G_HT40     2G_HT20   */
-	{0x0000a2dc, 0x0380c7fc, 0x0380c7fc, 0x00637800, 0x00637800},
-	{0x0000a2e0, 0x0000f800, 0x0000f800, 0x03838000, 0x03838000},
-	{0x0000a2e4, 0x03ff0000, 0x03ff0000, 0x03fc0000, 0x03fc0000},
-	{0x0000a2e8, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+	{0x0000a2dc, 0x00033800, 0x00033800, 0x03aaa352, 0x03aaa352},
+	{0x0000a2e0, 0x0003c000, 0x0003c000, 0x03ccc584, 0x03ccc584},
+	{0x0000a2e4, 0x03fc0000, 0x03fc0000, 0x03f0f800, 0x03f0f800},
+	{0x0000a2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
 	{0x0000a410, 0x000050d9, 0x000050d9, 0x000050d9, 0x000050d9},
 	{0x0000a500, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
 	{0x0000a504, 0x06000003, 0x06000003, 0x04000002, 0x04000002},
@@ -1329,21 +1329,21 @@
 	{0x0000a538, 0x4702244a, 0x4702244a, 0x34000e24, 0x34000e24},
 	{0x0000a53c, 0x4b02244c, 0x4b02244c, 0x38001640, 0x38001640},
 	{0x0000a540, 0x4e02246c, 0x4e02246c, 0x3c001660, 0x3c001660},
-	{0x0000a544, 0x5302266c, 0x5302266c, 0x3f001861, 0x3f001861},
-	{0x0000a548, 0x5702286c, 0x5702286c, 0x43001a81, 0x43001a81},
-	{0x0000a54c, 0x5c02486b, 0x5c02486b, 0x47001a83, 0x47001a83},
-	{0x0000a550, 0x61024a6c, 0x61024a6c, 0x4a001c84, 0x4a001c84},
-	{0x0000a554, 0x66026a6c, 0x66026a6c, 0x4e001ce3, 0x4e001ce3},
-	{0x0000a558, 0x6b026e6c, 0x6b026e6c, 0x52001ce5, 0x52001ce5},
-	{0x0000a55c, 0x7002708c, 0x7002708c, 0x56001ce9, 0x56001ce9},
-	{0x0000a560, 0x7302b08a, 0x7302b08a, 0x5a001ceb, 0x5a001ceb},
-	{0x0000a564, 0x7702b08c, 0x7702b08c, 0x5d001eec, 0x5d001eec},
-	{0x0000a568, 0x7702b08c, 0x7702b08c, 0x5d001eec, 0x5d001eec},
-	{0x0000a56c, 0x7702b08c, 0x7702b08c, 0x5d001eec, 0x5d001eec},
-	{0x0000a570, 0x7702b08c, 0x7702b08c, 0x5d001eec, 0x5d001eec},
-	{0x0000a574, 0x7702b08c, 0x7702b08c, 0x5d001eec, 0x5d001eec},
-	{0x0000a578, 0x7702b08c, 0x7702b08c, 0x5d001eec, 0x5d001eec},
-	{0x0000a57c, 0x7702b08c, 0x7702b08c, 0x5d001eec, 0x5d001eec},
+	{0x0000a544, 0x52022470, 0x52022470, 0x3f001861, 0x3f001861},
+	{0x0000a548, 0x55022490, 0x55022490, 0x43001a81, 0x43001a81},
+	{0x0000a54c, 0x59022492, 0x59022492, 0x47001a83, 0x47001a83},
+	{0x0000a550, 0x5d022692, 0x5d022692, 0x4a001c84, 0x4a001c84},
+	{0x0000a554, 0x61022892, 0x61022892, 0x4e001ce3, 0x4e001ce3},
+	{0x0000a558, 0x65024890, 0x65024890, 0x52001ce5, 0x52001ce5},
+	{0x0000a55c, 0x69024892, 0x69024892, 0x56001ce9, 0x56001ce9},
+	{0x0000a560, 0x6e024c92, 0x6e024c92, 0x5a001ceb, 0x5a001ceb},
+	{0x0000a564, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec},
+	{0x0000a568, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec},
+	{0x0000a56c, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec},
+	{0x0000a570, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec},
+	{0x0000a574, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec},
+	{0x0000a578, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec},
+	{0x0000a57c, 0x74026e92, 0x74026e92, 0x5d001eec, 0x5d001eec},
 	{0x0000a580, 0x00800000, 0x00800000, 0x00800000, 0x00800000},
 	{0x0000a584, 0x06800003, 0x06800003, 0x04800002, 0x04800002},
 	{0x0000a588, 0x0a800020, 0x0a800020, 0x08800004, 0x08800004},
@@ -1361,45 +1361,45 @@
 	{0x0000a5b8, 0x4782244a, 0x4782244a, 0x34800e24, 0x34800e24},
 	{0x0000a5bc, 0x4b82244c, 0x4b82244c, 0x38801640, 0x38801640},
 	{0x0000a5c0, 0x4e82246c, 0x4e82246c, 0x3c801660, 0x3c801660},
-	{0x0000a5c4, 0x5382266c, 0x5382266c, 0x3f801861, 0x3f801861},
-	{0x0000a5c8, 0x5782286c, 0x5782286c, 0x43801a81, 0x43801a81},
-	{0x0000a5cc, 0x5c82486b, 0x5c82486b, 0x47801a83, 0x47801a83},
-	{0x0000a5d0, 0x61824a6c, 0x61824a6c, 0x4a801c84, 0x4a801c84},
-	{0x0000a5d4, 0x66826a6c, 0x66826a6c, 0x4e801ce3, 0x4e801ce3},
-	{0x0000a5d8, 0x6b826e6c, 0x6b826e6c, 0x52801ce5, 0x52801ce5},
-	{0x0000a5dc, 0x7082708c, 0x7082708c, 0x56801ce9, 0x56801ce9},
-	{0x0000a5e0, 0x7382b08a, 0x7382b08a, 0x5a801ceb, 0x5a801ceb},
-	{0x0000a5e4, 0x7782b08c, 0x7782b08c, 0x5d801eec, 0x5d801eec},
-	{0x0000a5e8, 0x7782b08c, 0x7782b08c, 0x5d801eec, 0x5d801eec},
-	{0x0000a5ec, 0x7782b08c, 0x7782b08c, 0x5d801eec, 0x5d801eec},
-	{0x0000a5f0, 0x7782b08c, 0x7782b08c, 0x5d801eec, 0x5d801eec},
-	{0x0000a5f4, 0x7782b08c, 0x7782b08c, 0x5d801eec, 0x5d801eec},
-	{0x0000a5f8, 0x7782b08c, 0x7782b08c, 0x5d801eec, 0x5d801eec},
-	{0x0000a5fc, 0x7782b08c, 0x7782b08c, 0x5d801eec, 0x5d801eec},
+	{0x0000a5c4, 0x52822470, 0x52822470, 0x3f801861, 0x3f801861},
+	{0x0000a5c8, 0x55822490, 0x55822490, 0x43801a81, 0x43801a81},
+	{0x0000a5cc, 0x59822492, 0x59822492, 0x47801a83, 0x47801a83},
+	{0x0000a5d0, 0x5d822692, 0x5d822692, 0x4a801c84, 0x4a801c84},
+	{0x0000a5d4, 0x61822892, 0x61822892, 0x4e801ce3, 0x4e801ce3},
+	{0x0000a5d8, 0x65824890, 0x65824890, 0x52801ce5, 0x52801ce5},
+	{0x0000a5dc, 0x69824892, 0x69824892, 0x56801ce9, 0x56801ce9},
+	{0x0000a5e0, 0x6e824c92, 0x6e824c92, 0x5a801ceb, 0x5a801ceb},
+	{0x0000a5e4, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec},
+	{0x0000a5e8, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec},
+	{0x0000a5ec, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec},
+	{0x0000a5f0, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec},
+	{0x0000a5f4, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec},
+	{0x0000a5f8, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec},
+	{0x0000a5fc, 0x74826e92, 0x74826e92, 0x5d801eec, 0x5d801eec},
 	{0x0000a600, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
 	{0x0000a604, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
 	{0x0000a608, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
 	{0x0000a60c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
 	{0x0000a610, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
-	{0x0000a614, 0x01404000, 0x01404000, 0x01404000, 0x01404000},
-	{0x0000a618, 0x01404501, 0x01404501, 0x01404501, 0x01404501},
-	{0x0000a61c, 0x02008802, 0x02008802, 0x02008501, 0x02008501},
-	{0x0000a620, 0x0300cc03, 0x0300cc03, 0x0280ca03, 0x0280ca03},
-	{0x0000a624, 0x0300cc03, 0x0300cc03, 0x03010c04, 0x03010c04},
-	{0x0000a628, 0x0300cc03, 0x0300cc03, 0x04014c04, 0x04014c04},
-	{0x0000a62c, 0x03810c03, 0x03810c03, 0x04015005, 0x04015005},
-	{0x0000a630, 0x03810e04, 0x03810e04, 0x04015005, 0x04015005},
-	{0x0000a634, 0x03810e04, 0x03810e04, 0x04015005, 0x04015005},
-	{0x0000a638, 0x03810e04, 0x03810e04, 0x04015005, 0x04015005},
-	{0x0000a63c, 0x03810e04, 0x03810e04, 0x04015005, 0x04015005},
-	{0x0000b2dc, 0x0380c7fc, 0x0380c7fc, 0x00637800, 0x00637800},
-	{0x0000b2e0, 0x0000f800, 0x0000f800, 0x03838000, 0x03838000},
-	{0x0000b2e4, 0x03ff0000, 0x03ff0000, 0x03fc0000, 0x03fc0000},
-	{0x0000b2e8, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
-	{0x0000c2dc, 0x0380c7fc, 0x0380c7fc, 0x00637800, 0x00637800},
-	{0x0000c2e0, 0x0000f800, 0x0000f800, 0x03838000, 0x03838000},
-	{0x0000c2e4, 0x03ff0000, 0x03ff0000, 0x03fc0000, 0x03fc0000},
-	{0x0000c2e8, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+	{0x0000a614, 0x02004000, 0x02004000, 0x01404000, 0x01404000},
+	{0x0000a618, 0x02004801, 0x02004801, 0x01404501, 0x01404501},
+	{0x0000a61c, 0x02808a02, 0x02808a02, 0x02008501, 0x02008501},
+	{0x0000a620, 0x0380ce03, 0x0380ce03, 0x0280ca03, 0x0280ca03},
+	{0x0000a624, 0x04411104, 0x04411104, 0x03010c04, 0x03010c04},
+	{0x0000a628, 0x04411104, 0x04411104, 0x04014c04, 0x04014c04},
+	{0x0000a62c, 0x04411104, 0x04411104, 0x04015005, 0x04015005},
+	{0x0000a630, 0x04411104, 0x04411104, 0x04015005, 0x04015005},
+	{0x0000a634, 0x04411104, 0x04411104, 0x04015005, 0x04015005},
+	{0x0000a638, 0x04411104, 0x04411104, 0x04015005, 0x04015005},
+	{0x0000a63c, 0x04411104, 0x04411104, 0x04015005, 0x04015005},
+	{0x0000b2dc, 0x00033800, 0x00033800, 0x03aaa352, 0x03aaa352},
+	{0x0000b2e0, 0x0003c000, 0x0003c000, 0x03ccc584, 0x03ccc584},
+	{0x0000b2e4, 0x03fc0000, 0x03fc0000, 0x03f0f800, 0x03f0f800},
+	{0x0000b2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
+	{0x0000c2dc, 0x00033800, 0x00033800, 0x03aaa352, 0x03aaa352},
+	{0x0000c2e0, 0x0003c000, 0x0003c000, 0x03ccc584, 0x03ccc584},
+	{0x0000c2e4, 0x03fc0000, 0x03fc0000, 0x03f0f800, 0x03f0f800},
+	{0x0000c2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
 	{0x00016044, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4},
 	{0x00016048, 0x66480001, 0x66480001, 0x66480001, 0x66480001},
 	{0x00016068, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c},
diff -druN linux-2.6.39-libre/drivers/net/wireless/ath/ath9k/ar9003_calib.c linux-3.0-rc7-libre/drivers/net/wireless/ath/ath9k/ar9003_calib.c
--- linux-2.6.39-libre/drivers/net/wireless/ath/ath9k/ar9003_calib.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/ath/ath9k/ar9003_calib.c	2011-07-11 19:51:52.000000000 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010 Atheros Communications Inc.
+ * Copyright (c) 2010-2011 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
@@ -18,13 +18,13 @@
 #include "hw-ops.h"
 #include "ar9003_phy.h"
 
-#define MPASS	3
 #define MAX_MEASUREMENT	8
-#define MAX_DIFFERENCE	10
+#define MAX_MAG_DELTA	11
+#define MAX_PHS_DELTA	10
 
 struct coeff {
-	int mag_coeff[AR9300_MAX_CHAINS][MAX_MEASUREMENT][MPASS];
-	int phs_coeff[AR9300_MAX_CHAINS][MAX_MEASUREMENT][MPASS];
+	int mag_coeff[AR9300_MAX_CHAINS][MAX_MEASUREMENT];
+	int phs_coeff[AR9300_MAX_CHAINS][MAX_MEASUREMENT];
 	int iqc_coeff[2];
 };
 
@@ -185,17 +185,19 @@
 
 	/* Accumulate IQ cal measures for active chains */
 	for (i = 0; i < AR5416_MAX_CHAINS; i++) {
-		ah->totalPowerMeasI[i] +=
-			REG_READ(ah, AR_PHY_CAL_MEAS_0(i));
-		ah->totalPowerMeasQ[i] +=
-			REG_READ(ah, AR_PHY_CAL_MEAS_1(i));
-		ah->totalIqCorrMeas[i] +=
-			(int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_2(i));
-		ath_dbg(ath9k_hw_common(ah), ATH_DBG_CALIBRATE,
-			"%d: Chn %d pmi=0x%08x;pmq=0x%08x;iqcm=0x%08x;\n",
-			ah->cal_samples, i, ah->totalPowerMeasI[i],
-			ah->totalPowerMeasQ[i],
-			ah->totalIqCorrMeas[i]);
+		if (ah->txchainmask & BIT(i)) {
+			ah->totalPowerMeasI[i] +=
+				REG_READ(ah, AR_PHY_CAL_MEAS_0(i));
+			ah->totalPowerMeasQ[i] +=
+				REG_READ(ah, AR_PHY_CAL_MEAS_1(i));
+			ah->totalIqCorrMeas[i] +=
+				(int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_2(i));
+			ath_dbg(ath9k_hw_common(ah), ATH_DBG_CALIBRATE,
+				"%d: Chn %d pmi=0x%08x;pmq=0x%08x;iqcm=0x%08x;\n",
+				ah->cal_samples, i, ah->totalPowerMeasI[i],
+				ah->totalPowerMeasQ[i],
+				ah->totalIqCorrMeas[i]);
+		}
 	}
 }
 
@@ -608,36 +610,48 @@
 	return true;
 }
 
-static bool ar9003_hw_compute_closest_pass_and_avg(int *mp_coeff, int *mp_avg)
+static void ar9003_hw_detect_outlier(int *mp_coeff, int nmeasurement,
+				     int max_delta)
 {
-	int diff[MPASS];
-
-	diff[0] = abs(mp_coeff[0] - mp_coeff[1]);
-	diff[1] = abs(mp_coeff[1] - mp_coeff[2]);
-	diff[2] = abs(mp_coeff[2] - mp_coeff[0]);
+	int mp_max = -64, max_idx = 0;
+	int mp_min = 63, min_idx = 0;
+	int mp_avg = 0, i, outlier_idx = 0;
 
-	if (diff[0] > MAX_DIFFERENCE &&
-	    diff[1] > MAX_DIFFERENCE &&
-	    diff[2] > MAX_DIFFERENCE)
-		return false;
+	/* find min/max mismatch across all calibrated gains */
+	for (i = 0; i < nmeasurement; i++) {
+		mp_avg += mp_coeff[i];
+		if (mp_coeff[i] > mp_max) {
+			mp_max = mp_coeff[i];
+			max_idx = i;
+		} else if (mp_coeff[i] < mp_min) {
+			mp_min = mp_coeff[i];
+			min_idx = i;
+		}
+	}
 
-	if (diff[0] <= diff[1] && diff[0] <= diff[2])
-		*mp_avg = (mp_coeff[0] + mp_coeff[1]) / 2;
-	else if (diff[1] <= diff[2])
-		*mp_avg = (mp_coeff[1] + mp_coeff[2]) / 2;
-	else
-		*mp_avg = (mp_coeff[2] + mp_coeff[0]) / 2;
+	/* find average (exclude max abs value) */
+	for (i = 0; i < nmeasurement; i++) {
+		if ((abs(mp_coeff[i]) < abs(mp_max)) ||
+		    (abs(mp_coeff[i]) < abs(mp_min)))
+			mp_avg += mp_coeff[i];
+	}
+	mp_avg /= (nmeasurement - 1);
 
-	return true;
+	/* detect outlier */
+	if (abs(mp_max - mp_min) > max_delta) {
+		if (abs(mp_max - mp_avg) > abs(mp_min - mp_avg))
+			outlier_idx = max_idx;
+		else
+			outlier_idx = min_idx;
+	}
+	mp_coeff[outlier_idx] = mp_avg;
 }
 
 static void ar9003_hw_tx_iqcal_load_avg_2_passes(struct ath_hw *ah,
 						 u8 num_chains,
 						 struct coeff *coeff)
 {
-	struct ath_common *common = ath9k_hw_common(ah);
 	int i, im, nmeasurement;
-	int magnitude, phase;
 	u32 tx_corr_coeff[MAX_MEASUREMENT][AR9300_MAX_CHAINS];
 
 	memset(tx_corr_coeff, 0, sizeof(tx_corr_coeff));
@@ -657,37 +671,28 @@
 
 	/* Load the average of 2 passes */
 	for (i = 0; i < num_chains; i++) {
-		if (AR_SREV_9485(ah))
-			nmeasurement = REG_READ_FIELD(ah,
-					AR_PHY_TX_IQCAL_STATUS_B0_9485,
-					AR_PHY_CALIBRATED_GAINS_0);
-		else
-			nmeasurement = REG_READ_FIELD(ah,
-					AR_PHY_TX_IQCAL_STATUS_B0,
-					AR_PHY_CALIBRATED_GAINS_0);
+		nmeasurement = REG_READ_FIELD(ah,
+				AR_PHY_TX_IQCAL_STATUS_B0,
+				AR_PHY_CALIBRATED_GAINS_0);
 
 		if (nmeasurement > MAX_MEASUREMENT)
 			nmeasurement = MAX_MEASUREMENT;
 
-		for (im = 0; im < nmeasurement; im++) {
-			/*
-			 * Determine which 2 passes are closest and compute avg
-			 * magnitude
-			 */
-			if (!ar9003_hw_compute_closest_pass_and_avg(coeff->mag_coeff[i][im],
-								    &magnitude))
-				goto disable_txiqcal;
+		/* detect outlier only if nmeasurement > 1 */
+		if (nmeasurement > 1) {
+			/* Detect magnitude outlier */
+			ar9003_hw_detect_outlier(coeff->mag_coeff[i],
+					nmeasurement, MAX_MAG_DELTA);
 
-			/*
-			 * Determine which 2 passes are closest and compute avg
-			 * phase
-			 */
-			if (!ar9003_hw_compute_closest_pass_and_avg(coeff->phs_coeff[i][im],
-								    &phase))
-				goto disable_txiqcal;
+			/* Detect phase outlier */
+			ar9003_hw_detect_outlier(coeff->phs_coeff[i],
+					nmeasurement, MAX_PHS_DELTA);
+		}
 
-			coeff->iqc_coeff[0] = (magnitude & 0x7f) |
-					      ((phase & 0x7f) << 7);
+		for (im = 0; im < nmeasurement; im++) {
+
+			coeff->iqc_coeff[0] = (coeff->mag_coeff[i][im] & 0x7f) |
+				((coeff->phs_coeff[i][im] & 0x7f) << 7);
 
 			if ((im % 2) == 0)
 				REG_RMW_FIELD(ah, tx_corr_coeff[im][i],
@@ -707,141 +712,37 @@
 
 	return;
 
-disable_txiqcal:
-	REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_CONTROL_3,
-		      AR_PHY_TX_IQCAL_CONTROL_3_IQCORR_EN, 0x0);
-	REG_RMW_FIELD(ah, AR_PHY_RX_IQCAL_CORR_B0,
-		      AR_PHY_RX_IQCAL_CORR_B0_LOOPBACK_IQCORR_EN, 0x0);
-
-	ath_dbg(common, ATH_DBG_CALIBRATE, "TX IQ Cal disabled\n");
 }
 
-static void ar9003_hw_tx_iq_cal(struct ath_hw *ah)
+static bool ar9003_hw_tx_iq_cal_run(struct ath_hw *ah)
 {
 	struct ath_common *common = ath9k_hw_common(ah);
-	static const u32 txiqcal_status[AR9300_MAX_CHAINS] = {
-		AR_PHY_TX_IQCAL_STATUS_B0,
-		AR_PHY_TX_IQCAL_STATUS_B1,
-		AR_PHY_TX_IQCAL_STATUS_B2,
-	};
-	static const u32 chan_info_tab[] = {
-		AR_PHY_CHAN_INFO_TAB_0,
-		AR_PHY_CHAN_INFO_TAB_1,
-		AR_PHY_CHAN_INFO_TAB_2,
-	};
-	struct coeff coeff;
-	s32 iq_res[6];
-	s32 i, j, ip, im, nmeasurement;
-	u8 nchains = get_streams(common->tx_chainmask);
-
-	for (ip = 0; ip < MPASS; ip++) {
-		REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_CONTROL_1,
-			      AR_PHY_TX_IQCAQL_CONTROL_1_IQCORR_I_Q_COFF_DELPT,
-			      DELPT);
-		REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_START,
-			      AR_PHY_TX_IQCAL_START_DO_CAL,
-			      AR_PHY_TX_IQCAL_START_DO_CAL);
-
-		if (!ath9k_hw_wait(ah, AR_PHY_TX_IQCAL_START,
-				   AR_PHY_TX_IQCAL_START_DO_CAL,
-				   0, AH_WAIT_TIMEOUT)) {
-			ath_dbg(common, ATH_DBG_CALIBRATE,
-				"Tx IQ Cal not complete.\n");
-			goto TX_IQ_CAL_FAILED;
-		}
-
-		nmeasurement = REG_READ_FIELD(ah, AR_PHY_TX_IQCAL_STATUS_B0,
-					      AR_PHY_CALIBRATED_GAINS_0);
-			if (nmeasurement > MAX_MEASUREMENT)
-				nmeasurement = MAX_MEASUREMENT;
-
-		for (i = 0; i < nchains; i++) {
-			ath_dbg(common, ATH_DBG_CALIBRATE,
-				"Doing Tx IQ Cal for chain %d.\n", i);
-			for (im = 0; im < nmeasurement; im++) {
-				if (REG_READ(ah, txiqcal_status[i]) &
-					     AR_PHY_TX_IQCAL_STATUS_FAILED) {
-					ath_dbg(common, ATH_DBG_CALIBRATE,
-						"Tx IQ Cal failed for chain %d.\n", i);
-					goto TX_IQ_CAL_FAILED;
-				}
-
-				for (j = 0; j < 3; j++) {
-					u8 idx = 2 * j,
-					   offset = 4 * (3 * im + j);
-
-					REG_RMW_FIELD(ah, AR_PHY_CHAN_INFO_MEMORY,
-						      AR_PHY_CHAN_INFO_TAB_S2_READ,
-						      0);
-
-					/* 32 bits */
-					iq_res[idx] = REG_READ(ah,
-							chan_info_tab[i] +
-							offset);
-
-					REG_RMW_FIELD(ah, AR_PHY_CHAN_INFO_MEMORY,
-						      AR_PHY_CHAN_INFO_TAB_S2_READ,
-						      1);
-
-					/* 16 bits */
-					iq_res[idx+1] = 0xffff & REG_READ(ah,
-								chan_info_tab[i] +
-								offset);
-
-					ath_dbg(common, ATH_DBG_CALIBRATE,
-						"IQ RES[%d]=0x%x IQ_RES[%d]=0x%x\n",
-						idx, iq_res[idx], idx+1, iq_res[idx+1]);
-				}
-
-				if (!ar9003_hw_calc_iq_corr(ah, i, iq_res,
-							    coeff.iqc_coeff)) {
-					ath_dbg(common, ATH_DBG_CALIBRATE,
-						"Failed in calculation of IQ correction.\n");
-					goto TX_IQ_CAL_FAILED;
-				}
-				coeff.mag_coeff[i][im][ip] =
-						coeff.iqc_coeff[0] & 0x7f;
-				coeff.phs_coeff[i][im][ip] =
-						(coeff.iqc_coeff[0] >> 7) & 0x7f;
-
-				if (coeff.mag_coeff[i][im][ip] > 63)
-					coeff.mag_coeff[i][im][ip] -= 128;
-				if (coeff.phs_coeff[i][im][ip] > 63)
-					coeff.phs_coeff[i][im][ip] -= 128;
-
-			}
-		}
-	}
-
-	ar9003_hw_tx_iqcal_load_avg_2_passes(ah, nchains, &coeff);
-
-	return;
-
-TX_IQ_CAL_FAILED:
-	ath_dbg(common, ATH_DBG_CALIBRATE, "Tx IQ Cal failed\n");
-}
-
-static void ar9003_hw_tx_iq_cal_run(struct ath_hw *ah)
-{
 	u8 tx_gain_forced;
 
-	REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_CONTROL_1_9485,
-		      AR_PHY_TX_IQCAQL_CONTROL_1_IQCORR_I_Q_COFF_DELPT, DELPT);
 	tx_gain_forced = REG_READ_FIELD(ah, AR_PHY_TX_FORCED_GAIN,
 					AR_PHY_TXGAIN_FORCE);
 	if (tx_gain_forced)
 		REG_RMW_FIELD(ah, AR_PHY_TX_FORCED_GAIN,
 			      AR_PHY_TXGAIN_FORCE, 0);
 
-	REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_START_9485,
-		      AR_PHY_TX_IQCAL_START_DO_CAL_9485, 1);
+	REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_START,
+		      AR_PHY_TX_IQCAL_START_DO_CAL, 1);
+
+	if (!ath9k_hw_wait(ah, AR_PHY_TX_IQCAL_START,
+			AR_PHY_TX_IQCAL_START_DO_CAL, 0,
+			AH_WAIT_TIMEOUT)) {
+		ath_dbg(common, ATH_DBG_CALIBRATE,
+			"Tx IQ Cal is not completed.\n");
+		return false;
+	}
+	return true;
 }
 
 static void ar9003_hw_tx_iq_cal_post_proc(struct ath_hw *ah)
 {
 	struct ath_common *common = ath9k_hw_common(ah);
 	const u32 txiqcal_status[AR9300_MAX_CHAINS] = {
-		AR_PHY_TX_IQCAL_STATUS_B0_9485,
+		AR_PHY_TX_IQCAL_STATUS_B0,
 		AR_PHY_TX_IQCAL_STATUS_B1,
 		AR_PHY_TX_IQCAL_STATUS_B2,
 	};
@@ -853,7 +754,7 @@
 	struct coeff coeff;
 	s32 iq_res[6];
 	u8 num_chains = 0;
-	int i, ip, im, j;
+	int i, im, j;
 	int nmeasurement;
 
 	for (i = 0; i < AR9300_MAX_CHAINS; i++) {
@@ -861,71 +762,69 @@
 			num_chains++;
 	}
 
-	for (ip = 0; ip < MPASS; ip++) {
-		for (i = 0; i < num_chains; i++) {
-			nmeasurement = REG_READ_FIELD(ah,
-					AR_PHY_TX_IQCAL_STATUS_B0_9485,
-					AR_PHY_CALIBRATED_GAINS_0);
-			if (nmeasurement > MAX_MEASUREMENT)
-				nmeasurement = MAX_MEASUREMENT;
+	for (i = 0; i < num_chains; i++) {
+		nmeasurement = REG_READ_FIELD(ah,
+				AR_PHY_TX_IQCAL_STATUS_B0,
+				AR_PHY_CALIBRATED_GAINS_0);
+		if (nmeasurement > MAX_MEASUREMENT)
+			nmeasurement = MAX_MEASUREMENT;
 
-			for (im = 0; im < nmeasurement; im++) {
-				ath_dbg(common, ATH_DBG_CALIBRATE,
-					"Doing Tx IQ Cal for chain %d.\n", i);
+		for (im = 0; im < nmeasurement; im++) {
+			ath_dbg(common, ATH_DBG_CALIBRATE,
+				"Doing Tx IQ Cal for chain %d.\n", i);
 
-				if (REG_READ(ah, txiqcal_status[i]) &
-				    AR_PHY_TX_IQCAL_STATUS_FAILED) {
-					ath_dbg(common, ATH_DBG_CALIBRATE,
+			if (REG_READ(ah, txiqcal_status[i]) &
+					AR_PHY_TX_IQCAL_STATUS_FAILED) {
+				ath_dbg(common, ATH_DBG_CALIBRATE,
 					"Tx IQ Cal failed for chain %d.\n", i);
-					goto tx_iqcal_fail;
-				}
+				goto tx_iqcal_fail;
+			}
 
-				for (j = 0; j < 3; j++) {
-					u32 idx = 2 * j, offset = 4 * (3 * im + j);
+			for (j = 0; j < 3; j++) {
+				u32 idx = 2 * j, offset = 4 * (3 * im + j);
 
-					REG_RMW_FIELD(ah,
+				REG_RMW_FIELD(ah,
 						AR_PHY_CHAN_INFO_MEMORY,
 						AR_PHY_CHAN_INFO_TAB_S2_READ,
 						0);
 
-					/* 32 bits */
-					iq_res[idx] = REG_READ(ah,
-							chan_info_tab[i] +
-							offset);
+				/* 32 bits */
+				iq_res[idx] = REG_READ(ah,
+						chan_info_tab[i] +
+						offset);
 
-					REG_RMW_FIELD(ah,
+				REG_RMW_FIELD(ah,
 						AR_PHY_CHAN_INFO_MEMORY,
 						AR_PHY_CHAN_INFO_TAB_S2_READ,
 						1);
 
-					/* 16 bits */
-					iq_res[idx + 1] = 0xffff & REG_READ(ah,
-							  chan_info_tab[i] + offset);
+				/* 16 bits */
+				iq_res[idx + 1] = 0xffff & REG_READ(ah,
+						chan_info_tab[i] + offset);
 
-					ath_dbg(common, ATH_DBG_CALIBRATE,
-						"IQ RES[%d]=0x%x"
-						"IQ_RES[%d]=0x%x\n",
-						idx, iq_res[idx], idx + 1,
-						iq_res[idx + 1]);
-				}
+				ath_dbg(common, ATH_DBG_CALIBRATE,
+					"IQ RES[%d]=0x%x"
+					"IQ_RES[%d]=0x%x\n",
+					idx, iq_res[idx], idx + 1,
+					iq_res[idx + 1]);
+			}
 
-				if (!ar9003_hw_calc_iq_corr(ah, i, iq_res,
-							    coeff.iqc_coeff)) {
-					ath_dbg(common, ATH_DBG_CALIBRATE,
-					 "Failed in calculation of IQ correction.\n");
-					goto tx_iqcal_fail;
-				}
+			if (!ar9003_hw_calc_iq_corr(ah, i, iq_res,
+						coeff.iqc_coeff)) {
+				ath_dbg(common, ATH_DBG_CALIBRATE,
+					"Failed in calculation of \
+					IQ correction.\n");
+				goto tx_iqcal_fail;
+			}
 
-				coeff.mag_coeff[i][im][ip] =
-						coeff.iqc_coeff[0] & 0x7f;
-				coeff.phs_coeff[i][im][ip] =
-						(coeff.iqc_coeff[0] >> 7) & 0x7f;
+			coeff.mag_coeff[i][im] = coeff.iqc_coeff[0] & 0x7f;
+			coeff.phs_coeff[i][im] =
+				(coeff.iqc_coeff[0] >> 7) & 0x7f;
 
-				if (coeff.mag_coeff[i][im][ip] > 63)
-					coeff.mag_coeff[i][im][ip] -= 128;
-				if (coeff.phs_coeff[i][im][ip] > 63)
-					coeff.phs_coeff[i][im][ip] -= 128;
-			}
+			if (coeff.mag_coeff[i][im] > 63)
+				coeff.mag_coeff[i][im] -= 128;
+			if (coeff.phs_coeff[i][im] > 63)
+				coeff.phs_coeff[i][im] -= 128;
 		}
 	}
 	ar9003_hw_tx_iqcal_load_avg_2_passes(ah, num_chains, &coeff);
@@ -940,31 +839,37 @@
 			       struct ath9k_channel *chan)
 {
 	struct ath_common *common = ath9k_hw_common(ah);
+	struct ath9k_hw_capabilities *pCap = &ah->caps;
 	int val;
+	bool txiqcal_done = false;
 
 	val = REG_READ(ah, AR_ENT_OTP);
 	ath_dbg(common, ATH_DBG_CALIBRATE, "ath9k: AR_ENT_OTP 0x%x\n", val);
 
-	if (AR_SREV_9485(ah))
-		ar9003_hw_set_chain_masks(ah, 0x1, 0x1);
-	else if (val & AR_ENT_OTP_CHAIN2_DISABLE)
+	/* Configure rx/tx chains before running AGC/TxiQ cals */
+	if (val & AR_ENT_OTP_CHAIN2_DISABLE)
 		ar9003_hw_set_chain_masks(ah, 0x3, 0x3);
 	else
-		/*
-		 * 0x7 = 0b111 , AR9003 needs to be configured for 3-chain
-		 * mode before running AGC/TxIQ cals
-		 */
-		ar9003_hw_set_chain_masks(ah, 0x7, 0x7);
+		ar9003_hw_set_chain_masks(ah, pCap->rx_chainmask,
+					  pCap->tx_chainmask);
 
 	/* Do Tx IQ Calibration */
-	if (AR_SREV_9485(ah))
-		ar9003_hw_tx_iq_cal_run(ah);
-	else
-		ar9003_hw_tx_iq_cal(ah);
+	REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_CONTROL_1,
+		      AR_PHY_TX_IQCAL_CONTROL_1_IQCORR_I_Q_COFF_DELPT,
+		      DELPT);
 
-	REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_DIS);
-	udelay(5);
-	REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_EN);
+	/*
+	 * For AR9485 or later chips, TxIQ cal runs as part of
+	 * AGC calibration
+	 */
+	if (AR_SREV_9485_OR_LATER(ah))
+		txiqcal_done = true;
+	else {
+		txiqcal_done = ar9003_hw_tx_iq_cal_run(ah);
+		REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_DIS);
+		udelay(5);
+		REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_EN);
+	}
 
 	/* Calibrate the AGC */
 	REG_WRITE(ah, AR_PHY_AGC_CONTROL,
@@ -979,7 +884,7 @@
 		return false;
 	}
 
-	if (AR_SREV_9485(ah))
+	if (txiqcal_done)
 		ar9003_hw_tx_iq_cal_post_proc(ah);
 
 	/* Revert chainmasks to their original values before NF cal */
diff -druN linux-2.6.39-libre/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c linux-3.0-rc7-libre/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
--- linux-2.6.39-libre/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c	2011-07-11 19:51:52.000000000 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010 Atheros Communications Inc.
+ * Copyright (c) 2010-2011 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
@@ -652,7 +652,7 @@
 		.regDmn = { LE16(0), LE16(0x1f) },
 		.txrxMask =  0x77, /* 4 bits tx and 4 bits rx */
 		.opCapFlags = {
-			.opFlags = AR5416_OPFLAGS_11G | AR5416_OPFLAGS_11A,
+			.opFlags = AR5416_OPFLAGS_11A,
 			.eepMisc = 0,
 		},
 		.rfSilent = 0,
@@ -922,7 +922,7 @@
 		.db_stage2 = {3, 3, 3}, /* 3 chain */
 		.db_stage3 = {3, 3, 3}, /* doesn't exist for 2G */
 		.db_stage4 = {3, 3, 3},	 /* don't exist for 2G */
-		.xpaBiasLvl = 0,
+		.xpaBiasLvl = 0xf,
 		.txFrameToDataStart = 0x0e,
 		.txFrameToPaOn = 0x0e,
 		.txClip = 3, /* 4 bits tx_clip, 4 bits dac_scale_cck */
@@ -3217,7 +3217,6 @@
 				    u8 *word, int length, int mdata_size)
 {
 	struct ath_common *common = ath9k_hw_common(ah);
-	u8 *dptr;
 	const struct ar9300_eeprom *eep = NULL;
 
 	switch (code) {
@@ -3235,7 +3234,6 @@
 		break;
 	case _CompressBlock:
 		if (reference == 0) {
-			dptr = mptr;
 		} else {
 			eep = ar9003_eeprom_struct_find_by_id(reference);
 			if (eep == NULL) {
@@ -3329,26 +3327,26 @@
 	else
 		cptr = AR9300_BASE_ADDR;
 	ath_dbg(common, ATH_DBG_EEPROM,
-		"Trying EEPROM accesss at Address 0x%04x\n", cptr);
+		"Trying EEPROM access at Address 0x%04x\n", cptr);
 	if (ar9300_check_eeprom_header(ah, read, cptr))
 		goto found;
 
 	cptr = AR9300_BASE_ADDR_512;
 	ath_dbg(common, ATH_DBG_EEPROM,
-		"Trying EEPROM accesss at Address 0x%04x\n", cptr);
+		"Trying EEPROM access at Address 0x%04x\n", cptr);
 	if (ar9300_check_eeprom_header(ah, read, cptr))
 		goto found;
 
 	read = ar9300_read_otp;
 	cptr = AR9300_BASE_ADDR;
 	ath_dbg(common, ATH_DBG_EEPROM,
-		"Trying OTP accesss at Address 0x%04x\n", cptr);
+		"Trying OTP access at Address 0x%04x\n", cptr);
 	if (ar9300_check_eeprom_header(ah, read, cptr))
 		goto found;
 
 	cptr = AR9300_BASE_ADDR_512;
 	ath_dbg(common, ATH_DBG_EEPROM,
-		"Trying OTP accesss at Address 0x%04x\n", cptr);
+		"Trying OTP access at Address 0x%04x\n", cptr);
 	if (ar9300_check_eeprom_header(ah, read, cptr))
 		goto found;
 
@@ -3444,13 +3442,15 @@
 {
 	int bias = ar9003_hw_xpa_bias_level_get(ah, is2ghz);
 
-	if (AR_SREV_9485(ah))
+	if (AR_SREV_9485(ah) || AR_SREV_9340(ah))
 		REG_RMW_FIELD(ah, AR_CH0_TOP2, AR_CH0_TOP2_XPABIASLVL, bias);
 	else {
 		REG_RMW_FIELD(ah, AR_CH0_TOP, AR_CH0_TOP_XPABIASLVL, bias);
-		REG_RMW_FIELD(ah, AR_CH0_THERM, AR_CH0_THERM_XPABIASLVL_MSB,
-			      bias >> 2);
-		REG_RMW_FIELD(ah, AR_CH0_THERM, AR_CH0_THERM_XPASHORT2GND, 1);
+		REG_RMW_FIELD(ah, AR_CH0_THERM,
+				AR_CH0_THERM_XPABIASLVL_MSB,
+				bias >> 2);
+		REG_RMW_FIELD(ah, AR_CH0_THERM,
+				AR_CH0_THERM_XPASHORT2GND, 1);
 	}
 }
 
@@ -3497,34 +3497,77 @@
 
 static void ar9003_hw_ant_ctrl_apply(struct ath_hw *ah, bool is2ghz)
 {
+	int chain;
+	u32 regval;
+	u32 ant_div_ctl1;
+	static const u32 switch_chain_reg[AR9300_MAX_CHAINS] = {
+			AR_PHY_SWITCH_CHAIN_0,
+			AR_PHY_SWITCH_CHAIN_1,
+			AR_PHY_SWITCH_CHAIN_2,
+	};
+
 	u32 value = ar9003_hw_ant_ctrl_common_get(ah, is2ghz);
+
 	REG_RMW_FIELD(ah, AR_PHY_SWITCH_COM, AR_SWITCH_TABLE_COM_ALL, value);
 
 	value = ar9003_hw_ant_ctrl_common_2_get(ah, is2ghz);
 	REG_RMW_FIELD(ah, AR_PHY_SWITCH_COM_2, AR_SWITCH_TABLE_COM2_ALL, value);
 
-	value = ar9003_hw_ant_ctrl_chain_get(ah, 0, is2ghz);
-	REG_RMW_FIELD(ah, AR_PHY_SWITCH_CHAIN_0, AR_SWITCH_TABLE_ALL, value);
-
-	if (!AR_SREV_9485(ah)) {
-		value = ar9003_hw_ant_ctrl_chain_get(ah, 1, is2ghz);
-		REG_RMW_FIELD(ah, AR_PHY_SWITCH_CHAIN_1, AR_SWITCH_TABLE_ALL,
-			      value);
-
-		value = ar9003_hw_ant_ctrl_chain_get(ah, 2, is2ghz);
-		REG_RMW_FIELD(ah, AR_PHY_SWITCH_CHAIN_2, AR_SWITCH_TABLE_ALL,
-			      value);
+	for (chain = 0; chain < AR9300_MAX_CHAINS; chain++) {
+		if ((ah->rxchainmask & BIT(chain)) ||
+		    (ah->txchainmask & BIT(chain))) {
+			value = ar9003_hw_ant_ctrl_chain_get(ah, chain,
+							     is2ghz);
+			REG_RMW_FIELD(ah, switch_chain_reg[chain],
+				      AR_SWITCH_TABLE_ALL, value);
+		}
 	}
 
 	if (AR_SREV_9485(ah)) {
 		value = ath9k_hw_ar9300_get_eeprom(ah, EEP_ANT_DIV_CTL1);
-		REG_RMW_FIELD(ah, AR_PHY_MC_GAIN_CTRL, AR_ANT_DIV_CTRL_ALL,
-			      value);
-		REG_RMW_FIELD(ah, AR_PHY_MC_GAIN_CTRL, AR_ANT_DIV_ENABLE,
-			      value >> 6);
-		REG_RMW_FIELD(ah, AR_PHY_CCK_DETECT, AR_FAST_DIV_ENABLE,
-			      value >> 7);
+		/*
+		 * main_lnaconf, alt_lnaconf, main_tb, alt_tb
+		 * are the fields present
+		 */
+		regval = REG_READ(ah, AR_PHY_MC_GAIN_CTRL);
+		regval &= (~AR_ANT_DIV_CTRL_ALL);
+		regval |= (value & 0x3f) << AR_ANT_DIV_CTRL_ALL_S;
+		/* enable_lnadiv */
+		regval &= (~AR_PHY_9485_ANT_DIV_LNADIV);
+		regval |= ((value >> 6) & 0x1) <<
+				AR_PHY_9485_ANT_DIV_LNADIV_S;
+		REG_WRITE(ah, AR_PHY_MC_GAIN_CTRL, regval);
+
+		/*enable fast_div */
+		regval = REG_READ(ah, AR_PHY_CCK_DETECT);
+		regval &= (~AR_FAST_DIV_ENABLE);
+		regval |= ((value >> 7) & 0x1) <<
+				AR_FAST_DIV_ENABLE_S;
+		REG_WRITE(ah, AR_PHY_CCK_DETECT, regval);
+		ant_div_ctl1 =
+			ah->eep_ops->get_eeprom(ah, EEP_ANT_DIV_CTL1);
+		/* check whether antenna diversity is enabled */
+		if ((ant_div_ctl1 >> 0x6) == 0x3) {
+			regval = REG_READ(ah, AR_PHY_MC_GAIN_CTRL);
+			/*
+			 * clear bits 25-30 main_lnaconf, alt_lnaconf,
+			 * main_tb, alt_tb
+			 */
+			regval &= (~(AR_PHY_9485_ANT_DIV_MAIN_LNACONF |
+					AR_PHY_9485_ANT_DIV_ALT_LNACONF |
+					AR_PHY_9485_ANT_DIV_ALT_GAINTB |
+					AR_PHY_9485_ANT_DIV_MAIN_GAINTB));
+			/* by default use LNA1 for the main antenna */
+			regval |= (AR_PHY_9485_ANT_DIV_LNA1 <<
+					AR_PHY_9485_ANT_DIV_MAIN_LNACONF_S);
+			regval |= (AR_PHY_9485_ANT_DIV_LNA2 <<
+					AR_PHY_9485_ANT_DIV_ALT_LNACONF_S);
+			REG_WRITE(ah, AR_PHY_MC_GAIN_CTRL, regval);
+		}
+
+
 	}
+
 }
 
 static void ar9003_hw_drive_strength_apply(struct ath_hw *ah)
@@ -3634,13 +3677,16 @@
 
 	/* Test value. if 0 then attenuation is unused. Don't load anything. */
 	for (i = 0; i < 3; i++) {
-		value = ar9003_hw_atten_chain_get(ah, i, chan);
-		REG_RMW_FIELD(ah, ext_atten_reg[i],
-			      AR_PHY_EXT_ATTEN_CTL_XATTEN1_DB, value);
+		if (ah->txchainmask & BIT(i)) {
+			value = ar9003_hw_atten_chain_get(ah, i, chan);
+			REG_RMW_FIELD(ah, ext_atten_reg[i],
+				      AR_PHY_EXT_ATTEN_CTL_XATTEN1_DB, value);
 
-		value = ar9003_hw_atten_chain_get_margin(ah, i, chan);
-		REG_RMW_FIELD(ah, ext_atten_reg[i],
-			      AR_PHY_EXT_ATTEN_CTL_XATTEN1_MARGIN, value);
+			value = ar9003_hw_atten_chain_get_margin(ah, i, chan);
+			REG_RMW_FIELD(ah, ext_atten_reg[i],
+				      AR_PHY_EXT_ATTEN_CTL_XATTEN1_MARGIN,
+				      value);
+		}
 	}
 }
 
@@ -3749,8 +3795,9 @@
 	ar9003_hw_ant_ctrl_apply(ah, IS_CHAN_2GHZ(chan));
 	ar9003_hw_drive_strength_apply(ah);
 	ar9003_hw_atten_apply(ah, chan);
-	ar9003_hw_internal_regulator_apply(ah);
-	if (AR_SREV_9485(ah))
+	if (!AR_SREV_9340(ah))
+		ar9003_hw_internal_regulator_apply(ah);
+	if (AR_SREV_9485(ah) || AR_SREV_9340(ah))
 		ar9003_hw_apply_tuning_caps(ah);
 }
 
@@ -3994,6 +4041,16 @@
 		  POW_SM(pPwrArray[ALL_TARGET_LEGACY_1L_5L], 0)
 	    );
 
+        /* Write the power for duplicated frames - HT40 */
+
+        /* dup40_cck (LSB), dup40_ofdm, ext20_cck, ext20_ofdm (MSB) */
+	REG_WRITE(ah, 0xa3e0,
+		  POW_SM(pPwrArray[ALL_TARGET_LEGACY_6_24], 24) |
+		  POW_SM(pPwrArray[ALL_TARGET_LEGACY_1L_5L], 16) |
+		  POW_SM(pPwrArray[ALL_TARGET_LEGACY_6_24],  8) |
+		  POW_SM(pPwrArray[ALL_TARGET_LEGACY_1L_5L],  0)
+	    );
+
 	/* Write the HT20 power per rate set */
 
 	/* 0/8/16 (LSB), 1-3/9-11/17-19, 4, 5 (MSB) */
@@ -4588,10 +4645,16 @@
 	case 1:
 		break;
 	case 2:
-		scaledPower -= REDUCE_SCALED_POWER_BY_TWO_CHAIN;
+		if (scaledPower > REDUCE_SCALED_POWER_BY_TWO_CHAIN)
+			scaledPower -= REDUCE_SCALED_POWER_BY_TWO_CHAIN;
+		else
+			scaledPower = 0;
 		break;
 	case 3:
-		scaledPower -= REDUCE_SCALED_POWER_BY_THREE_CHAIN;
+		if (scaledPower > REDUCE_SCALED_POWER_BY_THREE_CHAIN)
+			scaledPower -= REDUCE_SCALED_POWER_BY_THREE_CHAIN;
+		else
+			scaledPower = 0;
 		break;
 	}
 
diff -druN linux-2.6.39-libre/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h linux-3.0-rc7-libre/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h
--- linux-2.6.39-libre/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h	2011-07-11 19:51:52.000000000 -0400
@@ -1,3 +1,19 @@
+/*
+ * Copyright (c) 2010-2011 Atheros Communications Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
 #ifndef AR9003_EEPROM_H
 #define AR9003_EEPROM_H
 
diff -druN linux-2.6.39-libre/drivers/net/wireless/ath/ath9k/ar9003_hw.c linux-3.0-rc7-libre/drivers/net/wireless/ath/ath9k/ar9003_hw.c
--- linux-2.6.39-libre/drivers/net/wireless/ath/ath9k/ar9003_hw.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/ath/ath9k/ar9003_hw.c	2011-07-11 19:51:52.000000000 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008-2010 Atheros Communications Inc.
+ * Copyright (c) 2008-2011 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
@@ -18,6 +18,7 @@
 #include "ar9003_mac.h"
 #include "ar9003_2p2_initvals.h"
 #include "ar9485_initvals.h"
+#include "ar9340_initvals.h"
 
 /* General hardware code for the AR9003 hadware family */
 
@@ -28,109 +29,105 @@
  */
 static void ar9003_hw_init_mode_regs(struct ath_hw *ah)
 {
-	if (AR_SREV_9485_11(ah)) {
+	if (AR_SREV_9340(ah)) {
 		/* mac */
 		INIT_INI_ARRAY(&ah->iniMac[ATH_INI_PRE], NULL, 0, 0);
 		INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE],
-				ar9485_1_1_mac_core,
-				ARRAY_SIZE(ar9485_1_1_mac_core), 2);
+				ar9340_1p0_mac_core,
+				ARRAY_SIZE(ar9340_1p0_mac_core), 2);
 		INIT_INI_ARRAY(&ah->iniMac[ATH_INI_POST],
-				ar9485_1_1_mac_postamble,
-				ARRAY_SIZE(ar9485_1_1_mac_postamble), 5);
+				ar9340_1p0_mac_postamble,
+				ARRAY_SIZE(ar9340_1p0_mac_postamble), 5);
 
 		/* bb */
-		INIT_INI_ARRAY(&ah->iniBB[ATH_INI_PRE], ar9485_1_1,
-				ARRAY_SIZE(ar9485_1_1), 2);
+		INIT_INI_ARRAY(&ah->iniBB[ATH_INI_PRE], NULL, 0, 0);
 		INIT_INI_ARRAY(&ah->iniBB[ATH_INI_CORE],
-				ar9485_1_1_baseband_core,
-				ARRAY_SIZE(ar9485_1_1_baseband_core), 2);
+				ar9340_1p0_baseband_core,
+				ARRAY_SIZE(ar9340_1p0_baseband_core), 2);
 		INIT_INI_ARRAY(&ah->iniBB[ATH_INI_POST],
-				ar9485_1_1_baseband_postamble,
-				ARRAY_SIZE(ar9485_1_1_baseband_postamble), 5);
+				ar9340_1p0_baseband_postamble,
+				ARRAY_SIZE(ar9340_1p0_baseband_postamble), 5);
 
 		/* radio */
 		INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_PRE], NULL, 0, 0);
 		INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_CORE],
-				ar9485_1_1_radio_core,
-				ARRAY_SIZE(ar9485_1_1_radio_core), 2);
+				ar9340_1p0_radio_core,
+				ARRAY_SIZE(ar9340_1p0_radio_core), 2);
 		INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_POST],
-				ar9485_1_1_radio_postamble,
-				ARRAY_SIZE(ar9485_1_1_radio_postamble), 2);
+				ar9340_1p0_radio_postamble,
+				ARRAY_SIZE(ar9340_1p0_radio_postamble), 5);
 
 		/* soc */
 		INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_PRE],
-				ar9485_1_1_soc_preamble,
-				ARRAY_SIZE(ar9485_1_1_soc_preamble), 2);
+				ar9340_1p0_soc_preamble,
+				ARRAY_SIZE(ar9340_1p0_soc_preamble), 2);
 		INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_CORE], NULL, 0, 0);
-		INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_POST], NULL, 0, 0);
+		INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_POST],
+				ar9340_1p0_soc_postamble,
+				ARRAY_SIZE(ar9340_1p0_soc_postamble), 5);
 
 		/* rx/tx gain */
 		INIT_INI_ARRAY(&ah->iniModesRxGain,
-				ar9485_common_rx_gain_1_1,
-				ARRAY_SIZE(ar9485_common_rx_gain_1_1), 2);
+				ar9340Common_wo_xlna_rx_gain_table_1p0,
+				ARRAY_SIZE(ar9340Common_wo_xlna_rx_gain_table_1p0),
+				5);
 		INIT_INI_ARRAY(&ah->iniModesTxGain,
-				ar9485_modes_lowest_ob_db_tx_gain_1_1,
-				ARRAY_SIZE(ar9485_modes_lowest_ob_db_tx_gain_1_1),
+				ar9340Modes_high_ob_db_tx_gain_table_1p0,
+				ARRAY_SIZE(ar9340Modes_high_ob_db_tx_gain_table_1p0),
 				5);
 
-		/* Load PCIE SERDES settings from INI */
-
-		/* Awake Setting */
-
-		INIT_INI_ARRAY(&ah->iniPcieSerdes,
-				ar9485_1_1_pcie_phy_clkreq_disable_L1,
-				ARRAY_SIZE(ar9485_1_1_pcie_phy_clkreq_disable_L1),
-				2);
-
-		/* Sleep Setting */
+		INIT_INI_ARRAY(&ah->iniModesAdditional,
+				ar9340Modes_fast_clock_1p0,
+				ARRAY_SIZE(ar9340Modes_fast_clock_1p0),
+				3);
 
-		INIT_INI_ARRAY(&ah->iniPcieSerdesLowPower,
-				ar9485_1_1_pcie_phy_clkreq_disable_L1,
-				ARRAY_SIZE(ar9485_1_1_pcie_phy_clkreq_disable_L1),
+		INIT_INI_ARRAY(&ah->iniModesAdditional_40M,
+				ar9340_1p0_radio_core_40M,
+				ARRAY_SIZE(ar9340_1p0_radio_core_40M),
 				2);
-	} else if (AR_SREV_9485(ah)) {
+	} else if (AR_SREV_9485_11(ah)) {
 		/* mac */
 		INIT_INI_ARRAY(&ah->iniMac[ATH_INI_PRE], NULL, 0, 0);
 		INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE],
-				ar9485_1_0_mac_core,
-				ARRAY_SIZE(ar9485_1_0_mac_core), 2);
+				ar9485_1_1_mac_core,
+				ARRAY_SIZE(ar9485_1_1_mac_core), 2);
 		INIT_INI_ARRAY(&ah->iniMac[ATH_INI_POST],
-				ar9485_1_0_mac_postamble,
-				ARRAY_SIZE(ar9485_1_0_mac_postamble), 5);
+				ar9485_1_1_mac_postamble,
+				ARRAY_SIZE(ar9485_1_1_mac_postamble), 5);
 
 		/* bb */
-		INIT_INI_ARRAY(&ah->iniBB[ATH_INI_PRE], ar9485_1_0,
-				ARRAY_SIZE(ar9485_1_0), 2);
+		INIT_INI_ARRAY(&ah->iniBB[ATH_INI_PRE], ar9485_1_1,
+				ARRAY_SIZE(ar9485_1_1), 2);
 		INIT_INI_ARRAY(&ah->iniBB[ATH_INI_CORE],
-				ar9485_1_0_baseband_core,
-				ARRAY_SIZE(ar9485_1_0_baseband_core), 2);
+				ar9485_1_1_baseband_core,
+				ARRAY_SIZE(ar9485_1_1_baseband_core), 2);
 		INIT_INI_ARRAY(&ah->iniBB[ATH_INI_POST],
-				ar9485_1_0_baseband_postamble,
-				ARRAY_SIZE(ar9485_1_0_baseband_postamble), 5);
+				ar9485_1_1_baseband_postamble,
+				ARRAY_SIZE(ar9485_1_1_baseband_postamble), 5);
 
 		/* radio */
 		INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_PRE], NULL, 0, 0);
 		INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_CORE],
-				ar9485_1_0_radio_core,
-				ARRAY_SIZE(ar9485_1_0_radio_core), 2);
+				ar9485_1_1_radio_core,
+				ARRAY_SIZE(ar9485_1_1_radio_core), 2);
 		INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_POST],
-				ar9485_1_0_radio_postamble,
-				ARRAY_SIZE(ar9485_1_0_radio_postamble), 2);
+				ar9485_1_1_radio_postamble,
+				ARRAY_SIZE(ar9485_1_1_radio_postamble), 2);
 
 		/* soc */
 		INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_PRE],
-				ar9485_1_0_soc_preamble,
-				ARRAY_SIZE(ar9485_1_0_soc_preamble), 2);
+				ar9485_1_1_soc_preamble,
+				ARRAY_SIZE(ar9485_1_1_soc_preamble), 2);
 		INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_CORE], NULL, 0, 0);
 		INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_POST], NULL, 0, 0);
 
 		/* rx/tx gain */
 		INIT_INI_ARRAY(&ah->iniModesRxGain,
-				ar9485Common_rx_gain_1_0,
-				ARRAY_SIZE(ar9485Common_rx_gain_1_0), 2);
+				ar9485Common_wo_xlna_rx_gain_1_1,
+				ARRAY_SIZE(ar9485Common_wo_xlna_rx_gain_1_1), 2);
 		INIT_INI_ARRAY(&ah->iniModesTxGain,
-				ar9485Modes_lowest_ob_db_tx_gain_1_0,
-				ARRAY_SIZE(ar9485Modes_lowest_ob_db_tx_gain_1_0),
+				ar9485_modes_lowest_ob_db_tx_gain_1_1,
+				ARRAY_SIZE(ar9485_modes_lowest_ob_db_tx_gain_1_1),
 				5);
 
 		/* Load PCIE SERDES settings from INI */
@@ -138,15 +135,15 @@
 		/* Awake Setting */
 
 		INIT_INI_ARRAY(&ah->iniPcieSerdes,
-				ar9485_1_0_pcie_phy_pll_on_clkreq_disable_L1,
-				ARRAY_SIZE(ar9485_1_0_pcie_phy_pll_on_clkreq_disable_L1),
+				ar9485_1_1_pcie_phy_clkreq_disable_L1,
+				ARRAY_SIZE(ar9485_1_1_pcie_phy_clkreq_disable_L1),
 				2);
 
 		/* Sleep Setting */
 
 		INIT_INI_ARRAY(&ah->iniPcieSerdesLowPower,
-				ar9485_1_0_pcie_phy_pll_on_clkreq_disable_L1,
-				ARRAY_SIZE(ar9485_1_0_pcie_phy_pll_on_clkreq_disable_L1),
+				ar9485_1_1_pcie_phy_clkreq_disable_L1,
+				ARRAY_SIZE(ar9485_1_1_pcie_phy_clkreq_disable_L1),
 				2);
 	} else {
 		/* mac */
@@ -223,15 +220,15 @@
 	switch (ar9003_hw_get_tx_gain_idx(ah)) {
 	case 0:
 	default:
-		if (AR_SREV_9485_11(ah))
+		if (AR_SREV_9340(ah))
 			INIT_INI_ARRAY(&ah->iniModesTxGain,
-				       ar9485_modes_lowest_ob_db_tx_gain_1_1,
-				       ARRAY_SIZE(ar9485_modes_lowest_ob_db_tx_gain_1_1),
+					ar9340Modes_lowest_ob_db_tx_gain_table_1p0,
+				       ARRAY_SIZE(ar9340Modes_lowest_ob_db_tx_gain_table_1p0),
 				       5);
-		else if (AR_SREV_9485(ah))
+		else if (AR_SREV_9485_11(ah))
 			INIT_INI_ARRAY(&ah->iniModesTxGain,
-				       ar9485Modes_lowest_ob_db_tx_gain_1_0,
-				       ARRAY_SIZE(ar9485Modes_lowest_ob_db_tx_gain_1_0),
+				       ar9485_modes_lowest_ob_db_tx_gain_1_1,
+				       ARRAY_SIZE(ar9485_modes_lowest_ob_db_tx_gain_1_1),
 				       5);
 		else
 			INIT_INI_ARRAY(&ah->iniModesTxGain,
@@ -240,15 +237,15 @@
 				       5);
 		break;
 	case 1:
-		if (AR_SREV_9485_11(ah))
+		if (AR_SREV_9340(ah))
 			INIT_INI_ARRAY(&ah->iniModesTxGain,
-				       ar9485Modes_high_ob_db_tx_gain_1_1,
-				       ARRAY_SIZE(ar9485Modes_high_ob_db_tx_gain_1_1),
+					ar9340Modes_lowest_ob_db_tx_gain_table_1p0,
+				       ARRAY_SIZE(ar9340Modes_lowest_ob_db_tx_gain_table_1p0),
 				       5);
-		else if (AR_SREV_9485(ah))
+		else if (AR_SREV_9485_11(ah))
 			INIT_INI_ARRAY(&ah->iniModesTxGain,
-				       ar9485Modes_high_ob_db_tx_gain_1_0,
-				       ARRAY_SIZE(ar9485Modes_high_ob_db_tx_gain_1_0),
+				       ar9485Modes_high_ob_db_tx_gain_1_1,
+				       ARRAY_SIZE(ar9485Modes_high_ob_db_tx_gain_1_1),
 				       5);
 		else
 			INIT_INI_ARRAY(&ah->iniModesTxGain,
@@ -257,15 +254,15 @@
 				       5);
 		break;
 	case 2:
-		if (AR_SREV_9485_11(ah))
+		if (AR_SREV_9340(ah))
 			INIT_INI_ARRAY(&ah->iniModesTxGain,
-				       ar9485Modes_low_ob_db_tx_gain_1_1,
-				       ARRAY_SIZE(ar9485Modes_low_ob_db_tx_gain_1_1),
+					ar9340Modes_lowest_ob_db_tx_gain_table_1p0,
+				       ARRAY_SIZE(ar9340Modes_lowest_ob_db_tx_gain_table_1p0),
 				       5);
-		else if (AR_SREV_9485(ah))
+		else if (AR_SREV_9485_11(ah))
 			INIT_INI_ARRAY(&ah->iniModesTxGain,
-				       ar9485Modes_low_ob_db_tx_gain_1_0,
-				       ARRAY_SIZE(ar9485Modes_low_ob_db_tx_gain_1_0),
+				       ar9485Modes_low_ob_db_tx_gain_1_1,
+				       ARRAY_SIZE(ar9485Modes_low_ob_db_tx_gain_1_1),
 				       5);
 		else
 			INIT_INI_ARRAY(&ah->iniModesTxGain,
@@ -274,15 +271,15 @@
 				       5);
 		break;
 	case 3:
-		if (AR_SREV_9485_11(ah))
+		if (AR_SREV_9340(ah))
 			INIT_INI_ARRAY(&ah->iniModesTxGain,
-				       ar9485Modes_high_power_tx_gain_1_1,
-				       ARRAY_SIZE(ar9485Modes_high_power_tx_gain_1_1),
+					ar9340Modes_lowest_ob_db_tx_gain_table_1p0,
+				       ARRAY_SIZE(ar9340Modes_lowest_ob_db_tx_gain_table_1p0),
 				       5);
-		else if (AR_SREV_9485(ah))
+		else if (AR_SREV_9485_11(ah))
 			INIT_INI_ARRAY(&ah->iniModesTxGain,
-				       ar9485Modes_high_power_tx_gain_1_0,
-				       ARRAY_SIZE(ar9485Modes_high_power_tx_gain_1_0),
+				       ar9485Modes_high_power_tx_gain_1_1,
+				       ARRAY_SIZE(ar9485Modes_high_power_tx_gain_1_1),
 				       5);
 		else
 			INIT_INI_ARRAY(&ah->iniModesTxGain,
@@ -298,15 +295,15 @@
 	switch (ar9003_hw_get_rx_gain_idx(ah)) {
 	case 0:
 	default:
-		if (AR_SREV_9485_11(ah))
+		if (AR_SREV_9340(ah))
 			INIT_INI_ARRAY(&ah->iniModesRxGain,
-				       ar9485_common_rx_gain_1_1,
-				       ARRAY_SIZE(ar9485_common_rx_gain_1_1),
+				       ar9340Common_rx_gain_table_1p0,
+				       ARRAY_SIZE(ar9340Common_rx_gain_table_1p0),
 				       2);
-		else if (AR_SREV_9485(ah))
+		else if (AR_SREV_9485_11(ah))
 			INIT_INI_ARRAY(&ah->iniModesRxGain,
-				       ar9485Common_rx_gain_1_0,
-				       ARRAY_SIZE(ar9485Common_rx_gain_1_0),
+				       ar9485Common_wo_xlna_rx_gain_1_1,
+				       ARRAY_SIZE(ar9485Common_wo_xlna_rx_gain_1_1),
 				       2);
 		else
 			INIT_INI_ARRAY(&ah->iniModesRxGain,
@@ -315,15 +312,15 @@
 				       2);
 		break;
 	case 1:
-		if (AR_SREV_9485_11(ah))
+		if (AR_SREV_9340(ah))
 			INIT_INI_ARRAY(&ah->iniModesRxGain,
-				       ar9485Common_wo_xlna_rx_gain_1_1,
-				       ARRAY_SIZE(ar9485Common_wo_xlna_rx_gain_1_1),
+				       ar9340Common_wo_xlna_rx_gain_table_1p0,
+				       ARRAY_SIZE(ar9340Common_wo_xlna_rx_gain_table_1p0),
 				       2);
-		else if (AR_SREV_9485(ah))
+		else if (AR_SREV_9485_11(ah))
 			INIT_INI_ARRAY(&ah->iniModesRxGain,
-				       ar9485Common_wo_xlna_rx_gain_1_0,
-				       ARRAY_SIZE(ar9485Common_wo_xlna_rx_gain_1_0),
+				       ar9485Common_wo_xlna_rx_gain_1_1,
+				       ARRAY_SIZE(ar9485Common_wo_xlna_rx_gain_1_1),
 				       2);
 		else
 			INIT_INI_ARRAY(&ah->iniModesRxGain,
diff -druN linux-2.6.39-libre/drivers/net/wireless/ath/ath9k/ar9003_mac.c linux-3.0-rc7-libre/drivers/net/wireless/ath/ath9k/ar9003_mac.c
--- linux-2.6.39-libre/drivers/net/wireless/ath/ath9k/ar9003_mac.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/ath/ath9k/ar9003_mac.c	2011-07-11 19:51:52.000000000 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010 Atheros Communications Inc.
+ * Copyright (c) 2010-2011 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
@@ -329,7 +329,6 @@
 		| (flags & ATH9K_TXDESC_VMF ? AR_VirtMoreFrag : 0)
 		| SM(txpower, AR_XmitPower)
 		| (flags & ATH9K_TXDESC_VEOL ? AR_VEOL : 0)
-		| (flags & ATH9K_TXDESC_CLRDMASK ? AR_ClrDestMask : 0)
 		| (keyIx != ATH9K_TXKEYIX_INVALID ? AR_DestIdxValid : 0)
 		| (flags & ATH9K_TXDESC_LOWRXCHAIN ? AR_LowRxChain : 0);
 
@@ -350,6 +349,16 @@
 	ads->ctl22 = 0;
 }
 
+static void ar9003_hw_set_clrdmask(struct ath_hw *ah, void *ds, bool val)
+{
+	struct ar9003_txc *ads = (struct ar9003_txc *) ds;
+
+	if (val)
+		ads->ctl11 |= AR_ClrDestMask;
+	else
+		ads->ctl11 &= ~AR_ClrDestMask;
+}
+
 static void ar9003_hw_set11n_ratescenario(struct ath_hw *ah, void *ds,
 					  void *lastds,
 					  u32 durUpdateEn, u32 rtsctsRate,
@@ -475,27 +484,6 @@
 	ads->ctl12 &= (~AR_IsAggr & ~AR_MoreAggr);
 }
 
-static void ar9003_hw_set11n_burstduration(struct ath_hw *ah, void *ds,
-					   u32 burstDuration)
-{
-	struct ar9003_txc *ads = (struct ar9003_txc *) ds;
-
-	ads->ctl13 &= ~AR_BurstDur;
-	ads->ctl13 |= SM(burstDuration, AR_BurstDur);
-
-}
-
-static void ar9003_hw_set11n_virtualmorefrag(struct ath_hw *ah, void *ds,
-					     u32 vmf)
-{
-	struct ar9003_txc *ads = (struct ar9003_txc *) ds;
-
-	if (vmf)
-		ads->ctl11 |=  AR_VirtMoreFrag;
-	else
-		ads->ctl11 &= ~AR_VirtMoreFrag;
-}
-
 void ar9003_hw_set_paprd_txdesc(struct ath_hw *ah, void *ds, u8 chains)
 {
 	struct ar9003_txc *ads = ds;
@@ -520,8 +508,7 @@
 	ops->set11n_aggr_middle = ar9003_hw_set11n_aggr_middle;
 	ops->set11n_aggr_last = ar9003_hw_set11n_aggr_last;
 	ops->clr11n_aggr = ar9003_hw_clr11n_aggr;
-	ops->set11n_burstduration = ar9003_hw_set11n_burstduration;
-	ops->set11n_virtualmorefrag = ar9003_hw_set11n_virtualmorefrag;
+	ops->set_clrdmask = ar9003_hw_set_clrdmask;
 }
 
 void ath9k_hw_set_rx_bufsize(struct ath_hw *ah, u16 buf_size)
diff -druN linux-2.6.39-libre/drivers/net/wireless/ath/ath9k/ar9003_mac.h linux-3.0-rc7-libre/drivers/net/wireless/ath/ath9k/ar9003_mac.h
--- linux-2.6.39-libre/drivers/net/wireless/ath/ath9k/ar9003_mac.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/ath/ath9k/ar9003_mac.h	2011-07-11 19:51:52.000000000 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010 Atheros Communications Inc.
+ * Copyright (c) 2010-2011 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
diff -druN linux-2.6.39-libre/drivers/net/wireless/ath/ath9k/ar9003_paprd.c linux-3.0-rc7-libre/drivers/net/wireless/ath/ath9k/ar9003_paprd.c
--- linux-2.6.39-libre/drivers/net/wireless/ath/ath9k/ar9003_paprd.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/ath/ath9k/ar9003_paprd.c	2011-07-11 19:51:52.000000000 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010 Atheros Communications Inc.
+ * Copyright (c) 2010-2011 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
diff -druN linux-2.6.39-libre/drivers/net/wireless/ath/ath9k/ar9003_phy.c linux-3.0-rc7-libre/drivers/net/wireless/ath/ath9k/ar9003_phy.c
--- linux-2.6.39-libre/drivers/net/wireless/ath/ath9k/ar9003_phy.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/ath/ath9k/ar9003_phy.c	2011-07-11 19:51:52.000000000 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010 Atheros Communications Inc.
+ * Copyright (c) 2010-2011 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
@@ -75,16 +75,42 @@
 	freq = centers.synth_center;
 
 	if (freq < 4800) {     /* 2 GHz, fractional mode */
-		if (AR_SREV_9485(ah))
-			channelSel = CHANSEL_2G_9485(freq);
-		else
+		if (AR_SREV_9485(ah)) {
+			u32 chan_frac;
+
+			/*
+			 * freq_ref = 40 / (refdiva >> amoderefsel); where refdiva=1 and amoderefsel=0
+			 * ndiv = ((chan_mhz * 4) / 3) / freq_ref;
+			 * chansel = int(ndiv), chanfrac = (ndiv - chansel) * 0x20000
+			 */
+			channelSel = (freq * 4) / 120;
+			chan_frac = (((freq * 4) % 120) * 0x20000) / 120;
+			channelSel = (channelSel << 17) | chan_frac;
+		} else if (AR_SREV_9340(ah)) {
+			if (ah->is_clk_25mhz) {
+				u32 chan_frac;
+
+				channelSel = (freq * 2) / 75;
+				chan_frac = (((freq * 2) % 75) * 0x20000) / 75;
+				channelSel = (channelSel << 17) | chan_frac;
+			} else
+				channelSel = CHANSEL_2G(freq) >> 1;
+		} else
 			channelSel = CHANSEL_2G(freq);
 		/* Set to 2G mode */
 		bMode = 1;
 	} else {
-		channelSel = CHANSEL_5G(freq);
-		/* Doubler is ON, so, divide channelSel by 2. */
-		channelSel >>= 1;
+		if (AR_SREV_9340(ah) && ah->is_clk_25mhz) {
+			u32 chan_frac;
+
+			channelSel = (freq * 2) / 75;
+			chan_frac = ((freq % 75) * 0x20000) / 75;
+			channelSel = (channelSel << 17) | chan_frac;
+		} else {
+			channelSel = CHANSEL_5G(freq);
+			/* Doubler is ON, so, divide channelSel by 2. */
+			channelSel >>= 1;
+		}
 		/* Set to 5G mode */
 		bMode = 0;
 	}
@@ -142,7 +168,7 @@
 	 * is out-of-band and can be ignored.
 	 */
 
-	if (AR_SREV_9485(ah)) {
+	if (AR_SREV_9485(ah) || AR_SREV_9340(ah)) {
 		spur_fbin_ptr = ar9003_get_spur_chan_ptr(ah,
 							 IS_CHAN_2GHZ(chan));
 		if (spur_fbin_ptr[0] == 0) /* No spur */
@@ -167,7 +193,7 @@
 
 	for (i = 0; i < max_spur_cnts; i++) {
 		negative = 0;
-		if (AR_SREV_9485(ah))
+		if (AR_SREV_9485(ah) || AR_SREV_9340(ah))
 			cur_bb_spur = FBIN2FREQ(spur_fbin_ptr[i],
 					IS_CHAN_2GHZ(chan)) - synth_freq;
 		else
@@ -401,7 +427,7 @@
 
 	ar9003_hw_spur_ofdm_clear(ah);
 
-	for (i = 0; spurChansPtr[i] && i < 5; i++) {
+	for (i = 0; i < AR_EEPROM_MODAL_SPURS && spurChansPtr[i]; i++) {
 		freq_offset = FBIN2FREQ(spurChansPtr[i], mode) - synth_freq;
 		if (abs(freq_offset) < range) {
 			ar9003_hw_spur_ofdm_work(ah, chan, freq_offset);
@@ -590,29 +616,25 @@
 	struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
 	unsigned int regWrites = 0, i;
 	struct ieee80211_channel *channel = chan->chan;
-	u32 modesIndex, freqIndex;
+	u32 modesIndex;
 
 	switch (chan->chanmode) {
 	case CHANNEL_A:
 	case CHANNEL_A_HT20:
 		modesIndex = 1;
-		freqIndex = 1;
 		break;
 	case CHANNEL_A_HT40PLUS:
 	case CHANNEL_A_HT40MINUS:
 		modesIndex = 2;
-		freqIndex = 1;
 		break;
 	case CHANNEL_G:
 	case CHANNEL_G_HT20:
 	case CHANNEL_B:
 		modesIndex = 4;
-		freqIndex = 2;
 		break;
 	case CHANNEL_G_HT40PLUS:
 	case CHANNEL_G_HT40MINUS:
 		modesIndex = 3;
-		freqIndex = 2;
 		break;
 
 	default:
@@ -637,6 +659,9 @@
 		REG_WRITE_ARRAY(&ah->iniModesAdditional,
 				modesIndex, regWrites);
 
+	if (AR_SREV_9340(ah) && !ah->is_clk_25mhz)
+		REG_WRITE_ARRAY(&ah->iniModesAdditional_40M, 1, regWrites);
+
 	ar9003_hw_override_ini(ah);
 	ar9003_hw_set_channel_regs(ah, chan);
 	ar9003_hw_set_chain_masks(ah, ah->rxchainmask, ah->txchainmask);
@@ -1159,9 +1184,52 @@
 	conf->radar_inband = 8;
 }
 
+static void ar9003_hw_antdiv_comb_conf_get(struct ath_hw *ah,
+				   struct ath_hw_antcomb_conf *antconf)
+{
+	u32 regval;
+
+	regval = REG_READ(ah, AR_PHY_MC_GAIN_CTRL);
+	antconf->main_lna_conf = (regval & AR_PHY_9485_ANT_DIV_MAIN_LNACONF) >>
+				  AR_PHY_9485_ANT_DIV_MAIN_LNACONF_S;
+	antconf->alt_lna_conf = (regval & AR_PHY_9485_ANT_DIV_ALT_LNACONF) >>
+				 AR_PHY_9485_ANT_DIV_ALT_LNACONF_S;
+	antconf->fast_div_bias = (regval & AR_PHY_9485_ANT_FAST_DIV_BIAS) >>
+				  AR_PHY_9485_ANT_FAST_DIV_BIAS_S;
+	antconf->lna1_lna2_delta = -9;
+	antconf->div_group = 2;
+}
+
+static void ar9003_hw_antdiv_comb_conf_set(struct ath_hw *ah,
+				   struct ath_hw_antcomb_conf *antconf)
+{
+	u32 regval;
+
+	regval = REG_READ(ah, AR_PHY_MC_GAIN_CTRL);
+	regval &= ~(AR_PHY_9485_ANT_DIV_MAIN_LNACONF |
+		    AR_PHY_9485_ANT_DIV_ALT_LNACONF |
+		    AR_PHY_9485_ANT_FAST_DIV_BIAS |
+		    AR_PHY_9485_ANT_DIV_MAIN_GAINTB |
+		    AR_PHY_9485_ANT_DIV_ALT_GAINTB);
+	regval |= ((antconf->main_lna_conf <<
+					AR_PHY_9485_ANT_DIV_MAIN_LNACONF_S)
+		   & AR_PHY_9485_ANT_DIV_MAIN_LNACONF);
+	regval |= ((antconf->alt_lna_conf << AR_PHY_9485_ANT_DIV_ALT_LNACONF_S)
+		   & AR_PHY_9485_ANT_DIV_ALT_LNACONF);
+	regval |= ((antconf->fast_div_bias << AR_PHY_9485_ANT_FAST_DIV_BIAS_S)
+		   & AR_PHY_9485_ANT_FAST_DIV_BIAS);
+	regval |= ((antconf->main_gaintb << AR_PHY_9485_ANT_DIV_MAIN_GAINTB_S)
+		   & AR_PHY_9485_ANT_DIV_MAIN_GAINTB);
+	regval |= ((antconf->alt_gaintb << AR_PHY_9485_ANT_DIV_ALT_GAINTB_S)
+		   & AR_PHY_9485_ANT_DIV_ALT_GAINTB);
+
+	REG_WRITE(ah, AR_PHY_MC_GAIN_CTRL, regval);
+}
+
 void ar9003_hw_attach_phy_ops(struct ath_hw *ah)
 {
 	struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah);
+	struct ath_hw_ops *ops = ath9k_hw_ops(ah);
 	static const u32 ar9300_cca_regs[6] = {
 		AR_PHY_CCA_0,
 		AR_PHY_CCA_1,
@@ -1188,6 +1256,9 @@
 	priv_ops->ani_cache_ini_regs = ar9003_hw_ani_cache_ini_regs;
 	priv_ops->set_radar_params = ar9003_hw_set_radar_params;
 
+	ops->antdiv_comb_conf_get = ar9003_hw_antdiv_comb_conf_get;
+	ops->antdiv_comb_conf_set = ar9003_hw_antdiv_comb_conf_set;
+
 	ar9003_hw_set_nf_limits(ah);
 	ar9003_hw_set_radar_conf(ah);
 	memcpy(ah->nf_regs, ar9300_cca_regs, sizeof(ah->nf_regs));
@@ -1310,3 +1381,25 @@
 		"==== BB update: done ====\n\n");
 }
 EXPORT_SYMBOL(ar9003_hw_bb_watchdog_dbg_info);
+
+void ar9003_hw_disable_phy_restart(struct ath_hw *ah)
+{
+	u32 val;
+
+	/* While receiving unsupported rate frame rx state machine
+	 * gets into a state 0xb and if phy_restart happens in that
+	 * state, BB would go hang. If RXSM is in 0xb state after
+	 * first bb panic, ensure to disable the phy_restart.
+	 */
+	if (!((MS(ah->bb_watchdog_last_status,
+		  AR_PHY_WATCHDOG_RX_OFDM_SM) == 0xb) ||
+	    ah->bb_hang_rx_ofdm))
+		return;
+
+	ah->bb_hang_rx_ofdm = true;
+	val = REG_READ(ah, AR_PHY_RESTART);
+	val &= ~AR_PHY_RESTART_ENA;
+
+	REG_WRITE(ah, AR_PHY_RESTART, val);
+}
+EXPORT_SYMBOL(ar9003_hw_disable_phy_restart);
diff -druN linux-2.6.39-libre/drivers/net/wireless/ath/ath9k/ar9003_phy.h linux-3.0-rc7-libre/drivers/net/wireless/ath/ath9k/ar9003_phy.h
--- linux-2.6.39-libre/drivers/net/wireless/ath/ath9k/ar9003_phy.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/ath/ath9k/ar9003_phy.h	2011-07-11 19:51:52.000000000 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002-2010 Atheros Communications, Inc.
+ * Copyright (c) 2010-2011 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
@@ -261,12 +261,34 @@
 #define AR_PHY_EXT_CCA0         (AR_AGC_BASE + 0x20)
 #define AR_PHY_RESTART          (AR_AGC_BASE + 0x24)
 
+/*
+ * Antenna Diversity  settings
+ */
 #define AR_PHY_MC_GAIN_CTRL     (AR_AGC_BASE + 0x28)
 #define AR_ANT_DIV_CTRL_ALL	0x7e000000
 #define AR_ANT_DIV_CTRL_ALL_S	25
 #define AR_ANT_DIV_ENABLE	0x1000000
 #define AR_ANT_DIV_ENABLE_S	24
 
+
+#define AR_PHY_9485_ANT_FAST_DIV_BIAS			0x00007e00
+#define AR_PHY_9485_ANT_FAST_DIV_BIAS_S                  9
+#define AR_PHY_9485_ANT_DIV_LNADIV			0x01000000
+#define AR_PHY_9485_ANT_DIV_LNADIV_S			24
+#define AR_PHY_9485_ANT_DIV_ALT_LNACONF			0x06000000
+#define AR_PHY_9485_ANT_DIV_ALT_LNACONF_S		25
+#define AR_PHY_9485_ANT_DIV_MAIN_LNACONF		0x18000000
+#define AR_PHY_9485_ANT_DIV_MAIN_LNACONF_S		27
+#define AR_PHY_9485_ANT_DIV_ALT_GAINTB			0x20000000
+#define AR_PHY_9485_ANT_DIV_ALT_GAINTB_S		29
+#define AR_PHY_9485_ANT_DIV_MAIN_GAINTB			0x40000000
+#define AR_PHY_9485_ANT_DIV_MAIN_GAINTB_S		30
+
+#define AR_PHY_9485_ANT_DIV_LNA1_MINUS_LNA2		0x0
+#define AR_PHY_9485_ANT_DIV_LNA2			0x1
+#define AR_PHY_9485_ANT_DIV_LNA1			0x2
+#define AR_PHY_9485_ANT_DIV_LNA1_PLUS_LNA2		0x3
+
 #define AR_PHY_EXTCHN_PWRTHR1   (AR_AGC_BASE + 0x2c)
 #define AR_PHY_EXT_CHN_WIN      (AR_AGC_BASE + 0x30)
 #define AR_PHY_20_40_DET_THR    (AR_AGC_BASE + 0x34)
@@ -548,15 +570,12 @@
 
 #define AR_PHY_TXGAIN_TABLE      (AR_SM_BASE + 0x300)
 
-#define AR_PHY_TX_IQCAL_START_9485		(AR_SM_BASE + 0x3c4)
-#define AR_PHY_TX_IQCAL_START_DO_CAL_9485	0x80000000
-#define AR_PHY_TX_IQCAL_START_DO_CAL_9485_S	31
-#define AR_PHY_TX_IQCAL_CONTROL_1_9485		(AR_SM_BASE + 0x3c8)
-#define AR_PHY_TX_IQCAL_STATUS_B0_9485		(AR_SM_BASE + 0x3f0)
-
-#define AR_PHY_TX_IQCAL_CONTROL_1   (AR_SM_BASE + 0x448)
-#define AR_PHY_TX_IQCAL_START       (AR_SM_BASE + 0x440)
-#define AR_PHY_TX_IQCAL_STATUS_B0   (AR_SM_BASE + 0x48c)
+#define AR_PHY_TX_IQCAL_CONTROL_1   (AR_SM_BASE + AR_SREV_9485(ah) ? \
+						 0x3c8 : 0x448)
+#define AR_PHY_TX_IQCAL_START       (AR_SM_BASE + AR_SREV_9485(ah) ? \
+						 0x3c4 : 0x440)
+#define AR_PHY_TX_IQCAL_STATUS_B0   (AR_SM_BASE + AR_SREV_9485(ah) ? \
+						 0x3f0 : 0x48c)
 #define AR_PHY_TX_IQCAL_CORR_COEFF_B0(_i)    (AR_SM_BASE + \
 					     (AR_SREV_9485(ah) ? \
 					      0x3d0 : 0x450) + ((_i) << 2))
@@ -588,7 +607,7 @@
 #define AR_PHY_65NM_CH0_BIAS2       0x160c4
 #define AR_PHY_65NM_CH0_BIAS4       0x160cc
 #define AR_PHY_65NM_CH0_RXTX4       0x1610c
-#define AR_PHY_65NM_CH0_THERM       (AR_SREV_9485(ah) ? 0x1628c : 0x16290)
+#define AR_PHY_65NM_CH0_THERM       (AR_SREV_9300(ah) ? 0x16290 : 0x1628c)
 
 #define AR_PHY_65NM_CH0_THERM_LOCAL   0x80000000
 #define AR_PHY_65NM_CH0_THERM_LOCAL_S 31
@@ -758,10 +777,10 @@
 #define AR_PHY_SPECTRAL_SCAN_SHORT_REPEAT   0x01000000
 #define AR_PHY_SPECTRAL_SCAN_SHORT_REPEAT_S 24
 #define AR_PHY_CHANNEL_STATUS_RX_CLEAR      0x00000004
-#define AR_PHY_TX_IQCAQL_CONTROL_1_IQCORR_I_Q_COFF_DELPT             0x01fc0000
-#define AR_PHY_TX_IQCAQL_CONTROL_1_IQCORR_I_Q_COFF_DELPT_S                   18
-#define AR_PHY_TX_IQCAL_START_DO_CAL        0x00000001
-#define AR_PHY_TX_IQCAL_START_DO_CAL_S      0
+#define AR_PHY_TX_IQCAL_CONTROL_1_IQCORR_I_Q_COFF_DELPT             0x01fc0000
+#define AR_PHY_TX_IQCAL_CONTROL_1_IQCORR_I_Q_COFF_DELPT_S                   18
+#define AR_PHY_TX_IQCAL_START_DO_CAL	    0x00000001
+#define AR_PHY_TX_IQCAL_START_DO_CAL_S	    0
 
 #define AR_PHY_TX_IQCAL_STATUS_FAILED    0x00000001
 #define AR_PHY_CALIBRATED_GAINS_0	 0x3e
diff -druN linux-2.6.39-libre/drivers/net/wireless/ath/ath9k/ar9340_initvals.h linux-3.0-rc7-libre/drivers/net/wireless/ath/ath9k/ar9340_initvals.h
--- linux-2.6.39-libre/drivers/net/wireless/ath/ath9k/ar9340_initvals.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/net/wireless/ath/ath9k/ar9340_initvals.h	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,1525 @@
+/*
+ * Copyright (c) 2011 Atheros Communications Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef INITVALS_9340_H
+#define INITVALS_9340_H
+
+static const u32 ar9340_1p0_radio_postamble[][5] = {
+	/*  Addr      5G_HT20     5G_HT40     2G_HT40     2G_HT20  */
+	{0x000160ac, 0xa4646800, 0xa4646800, 0xa4646800, 0xa4646800},
+	{0x0001610c, 0x08000000, 0x08000000, 0x00000000, 0x00000000},
+	{0x00016140, 0x10804000, 0x10804000, 0x50804000, 0x50804000},
+	{0x0001650c, 0x08000000, 0x08000000, 0x00000000, 0x00000000},
+	{0x00016540, 0x10804000, 0x10804000, 0x50804000, 0x50804000},
+};
+
+static const u32 ar9340Modes_lowest_ob_db_tx_gain_table_1p0[][5] = {
+	/*   Addr     5G_HT20     5G_HT40     2G_HT40     2G_HT20  */
+	{0x0000a410, 0x000050d9, 0x000050d9, 0x000050d9, 0x000050d9},
+	{0x0000a500, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+	{0x0000a504, 0x06000003, 0x06000003, 0x04000002, 0x04000002},
+	{0x0000a508, 0x0a000020, 0x0a000020, 0x08000004, 0x08000004},
+	{0x0000a50c, 0x10000023, 0x10000023, 0x0b000200, 0x0b000200},
+	{0x0000a510, 0x16000220, 0x16000220, 0x0f000202, 0x0f000202},
+	{0x0000a514, 0x1c000223, 0x1c000223, 0x12000400, 0x12000400},
+	{0x0000a518, 0x21020220, 0x21020220, 0x16000402, 0x16000402},
+	{0x0000a51c, 0x27020223, 0x27020223, 0x19000404, 0x19000404},
+	{0x0000a520, 0x2b022220, 0x2b022220, 0x1c000603, 0x1c000603},
+	{0x0000a524, 0x2f022222, 0x2f022222, 0x21000a02, 0x21000a02},
+	{0x0000a528, 0x34022225, 0x34022225, 0x25000a04, 0x25000a04},
+	{0x0000a52c, 0x3a02222a, 0x3a02222a, 0x28000a20, 0x28000a20},
+	{0x0000a530, 0x3e02222c, 0x3e02222c, 0x2c000e20, 0x2c000e20},
+	{0x0000a534, 0x4202242a, 0x4202242a, 0x30000e22, 0x30000e22},
+	{0x0000a538, 0x4702244a, 0x4702244a, 0x34000e24, 0x34000e24},
+	{0x0000a53c, 0x4b02244c, 0x4b02244c, 0x38001640, 0x38001640},
+	{0x0000a540, 0x4e02246c, 0x4e02246c, 0x3c001660, 0x3c001660},
+	{0x0000a544, 0x5302266c, 0x5302266c, 0x3f001861, 0x3f001861},
+	{0x0000a548, 0x5702286c, 0x5702286c, 0x43001a81, 0x43001a81},
+	{0x0000a54c, 0x5c04286b, 0x5c04286b, 0x47001a83, 0x47001a83},
+	{0x0000a550, 0x61042a6c, 0x61042a6c, 0x4a001c84, 0x4a001c84},
+	{0x0000a554, 0x66062a6c, 0x66062a6c, 0x4e001ce3, 0x4e001ce3},
+	{0x0000a558, 0x6b062e6c, 0x6b062e6c, 0x52001ce5, 0x52001ce5},
+	{0x0000a55c, 0x7006308c, 0x7006308c, 0x56001ce9, 0x56001ce9},
+	{0x0000a560, 0x730a308a, 0x730a308a, 0x5a001ceb, 0x5a001ceb},
+	{0x0000a564, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec},
+	{0x0000a568, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec},
+	{0x0000a56c, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec},
+	{0x0000a570, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec},
+	{0x0000a574, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec},
+	{0x0000a578, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec},
+	{0x0000a57c, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec},
+	{0x0000a580, 0x00800000, 0x00800000, 0x00800000, 0x00800000},
+	{0x0000a584, 0x06800003, 0x06800003, 0x04800002, 0x04800002},
+	{0x0000a588, 0x0a800020, 0x0a800020, 0x08800004, 0x08800004},
+	{0x0000a58c, 0x10800023, 0x10800023, 0x0b800200, 0x0b800200},
+	{0x0000a590, 0x16800220, 0x16800220, 0x0f800202, 0x0f800202},
+	{0x0000a594, 0x1c800223, 0x1c800223, 0x12800400, 0x12800400},
+	{0x0000a598, 0x21820220, 0x21820220, 0x16800402, 0x16800402},
+	{0x0000a59c, 0x27820223, 0x27820223, 0x19800404, 0x19800404},
+	{0x0000a5a0, 0x2b822220, 0x2b822220, 0x1c800603, 0x1c800603},
+	{0x0000a5a4, 0x2f822222, 0x2f822222, 0x21800a02, 0x21800a02},
+	{0x0000a5a8, 0x34822225, 0x34822225, 0x25800a04, 0x25800a04},
+	{0x0000a5ac, 0x3a82222a, 0x3a82222a, 0x28800a20, 0x28800a20},
+	{0x0000a5b0, 0x3e82222c, 0x3e82222c, 0x2c800e20, 0x2c800e20},
+	{0x0000a5b4, 0x4282242a, 0x4282242a, 0x30800e22, 0x30800e22},
+	{0x0000a5b8, 0x4782244a, 0x4782244a, 0x34800e24, 0x34800e24},
+	{0x0000a5bc, 0x4b82244c, 0x4b82244c, 0x38801640, 0x38801640},
+	{0x0000a5c0, 0x4e82246c, 0x4e82246c, 0x3c801660, 0x3c801660},
+	{0x0000a5c4, 0x5382266c, 0x5382266c, 0x3f801861, 0x3f801861},
+	{0x0000a5c8, 0x5782286c, 0x5782286c, 0x43801a81, 0x43801a81},
+	{0x0000a5cc, 0x5c84286b, 0x5c84286b, 0x47801a83, 0x47801a83},
+	{0x0000a5d0, 0x61842a6c, 0x61842a6c, 0x4a801c84, 0x4a801c84},
+	{0x0000a5d4, 0x66862a6c, 0x66862a6c, 0x4e801ce3, 0x4e801ce3},
+	{0x0000a5d8, 0x6b862e6c, 0x6b862e6c, 0x52801ce5, 0x52801ce5},
+	{0x0000a5dc, 0x7086308c, 0x7086308c, 0x56801ce9, 0x56801ce9},
+	{0x0000a5e0, 0x738a308a, 0x738a308a, 0x5a801ceb, 0x5a801ceb},
+	{0x0000a5e4, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec},
+	{0x0000a5e8, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec},
+	{0x0000a5ec, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec},
+	{0x0000a5f0, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec},
+	{0x0000a5f4, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec},
+	{0x0000a5f8, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec},
+	{0x0000a5fc, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec},
+	{0x00016044, 0x056db2db, 0x056db2db, 0x056db2db, 0x056db2db},
+	{0x00016048, 0x24925266, 0x24925266, 0x24925266, 0x24925266},
+	{0x00016444, 0x056db2db, 0x056db2db, 0x056db2db, 0x056db2db},
+	{0x00016448, 0x24925266, 0x24925266, 0x24925266, 0x24925266},
+};
+
+static const u32 ar9340Modes_fast_clock_1p0[][3] = {
+	/*  Addr      5G_HT20     5G_HT40  */
+	{0x00001030, 0x00000268, 0x000004d0},
+	{0x00001070, 0x0000018c, 0x00000318},
+	{0x000010b0, 0x00000fd0, 0x00001fa0},
+	{0x00008014, 0x044c044c, 0x08980898},
+	{0x0000801c, 0x148ec02b, 0x148ec057},
+	{0x00008318, 0x000044c0, 0x00008980},
+	{0x00009e00, 0x03721821, 0x03721821},
+	{0x0000a230, 0x0000000b, 0x00000016},
+	{0x0000a254, 0x00000898, 0x00001130},
+};
+
+static const u32 ar9340_1p0_radio_core[][2] = {
+	/*  Addr     allmodes  */
+	{0x00016000, 0x36db6db6},
+	{0x00016004, 0x6db6db40},
+	{0x00016008, 0x73f00000},
+	{0x0001600c, 0x00000000},
+	{0x00016040, 0x7f80fff8},
+	{0x00016044, 0x03b6d2db},
+	{0x00016048, 0x24925266},
+	{0x0001604c, 0x000f0278},
+	{0x00016050, 0x6db6db6c},
+	{0x00016054, 0x6db60000},
+	{0x00016080, 0x00080000},
+	{0x00016084, 0x0e48048c},
+	{0x00016088, 0x14214514},
+	{0x0001608c, 0x119f081c},
+	{0x00016090, 0x24926490},
+	{0x00016094, 0x00000000},
+	{0x00016098, 0xd411eb84},
+	{0x0001609c, 0x03e47f32},
+	{0x000160a0, 0xc2108ffe},
+	{0x000160a4, 0x812fc370},
+	{0x000160a8, 0x423c8000},
+	{0x000160ac, 0xa4646800},
+	{0x000160b0, 0x00fe7f46},
+	{0x000160b4, 0x92480000},
+	{0x000160c0, 0x006db6db},
+	{0x000160c4, 0x6db6db60},
+	{0x000160c8, 0x6db6db6c},
+	{0x000160cc, 0x6de6db6c},
+	{0x000160d0, 0xb6da4924},
+	{0x00016100, 0x04cb0001},
+	{0x00016104, 0xfff80000},
+	{0x00016108, 0x00080010},
+	{0x0001610c, 0x00000000},
+	{0x00016140, 0x50804008},
+	{0x00016144, 0x01884080},
+	{0x00016148, 0x000080c0},
+	{0x00016280, 0x01000015},
+	{0x00016284, 0x05530000},
+	{0x00016288, 0x00318000},
+	{0x0001628c, 0x50000000},
+	{0x00016290, 0x4080294f},
+	{0x00016380, 0x00000000},
+	{0x00016384, 0x00000000},
+	{0x00016388, 0x00800700},
+	{0x0001638c, 0x00800700},
+	{0x00016390, 0x00800700},
+	{0x00016394, 0x00000000},
+	{0x00016398, 0x00000000},
+	{0x0001639c, 0x00000000},
+	{0x000163a0, 0x00000001},
+	{0x000163a4, 0x00000001},
+	{0x000163a8, 0x00000000},
+	{0x000163ac, 0x00000000},
+	{0x000163b0, 0x00000000},
+	{0x000163b4, 0x00000000},
+	{0x000163b8, 0x00000000},
+	{0x000163bc, 0x00000000},
+	{0x000163c0, 0x000000a0},
+	{0x000163c4, 0x000c0000},
+	{0x000163c8, 0x14021402},
+	{0x000163cc, 0x00001402},
+	{0x000163d0, 0x00000000},
+	{0x000163d4, 0x00000000},
+	{0x00016400, 0x36db6db6},
+	{0x00016404, 0x6db6db40},
+	{0x00016408, 0x73f00000},
+	{0x0001640c, 0x00000000},
+	{0x00016440, 0x7f80fff8},
+	{0x00016444, 0x03b6d2db},
+	{0x00016448, 0x24927266},
+	{0x0001644c, 0x000f0278},
+	{0x00016450, 0x6db6db6c},
+	{0x00016454, 0x6db60000},
+	{0x00016500, 0x04cb0001},
+	{0x00016504, 0xfff80000},
+	{0x00016508, 0x00080010},
+	{0x0001650c, 0x00000000},
+	{0x00016540, 0x50804008},
+	{0x00016544, 0x01884080},
+	{0x00016548, 0x000080c0},
+	{0x00016780, 0x00000000},
+	{0x00016784, 0x00000000},
+	{0x00016788, 0x00800700},
+	{0x0001678c, 0x00800700},
+	{0x00016790, 0x00800700},
+	{0x00016794, 0x00000000},
+	{0x00016798, 0x00000000},
+	{0x0001679c, 0x00000000},
+	{0x000167a0, 0x00000001},
+	{0x000167a4, 0x00000001},
+	{0x000167a8, 0x00000000},
+	{0x000167ac, 0x00000000},
+	{0x000167b0, 0x00000000},
+	{0x000167b4, 0x00000000},
+	{0x000167b8, 0x00000000},
+	{0x000167bc, 0x00000000},
+	{0x000167c0, 0x000000a0},
+	{0x000167c4, 0x000c0000},
+	{0x000167c8, 0x14021402},
+	{0x000167cc, 0x00001402},
+	{0x000167d0, 0x00000000},
+	{0x000167d4, 0x00000000},
+};
+
+static const u32 ar9340_1p0_radio_core_40M[][2] = {
+	{0x0001609c, 0x02566f3a},
+	{0x000160ac, 0xa4647c00},
+	{0x000160b0, 0x01885f5a},
+};
+
+static const u32 ar9340_1p0_mac_postamble[][5] = {
+	/* Addr       5G_HT20     5G_HT40     2G_HT40    2G_HT20  */
+	{0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160},
+	{0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c},
+	{0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38},
+	{0x00008014, 0x03e803e8, 0x07d007d0, 0x10801600, 0x08400b00},
+	{0x0000801c, 0x128d8027, 0x128d804f, 0x12e00057, 0x12e0002b},
+	{0x00008120, 0x08f04800, 0x08f04800, 0x08f04810, 0x08f04810},
+	{0x000081d0, 0x00003210, 0x00003210, 0x0000320a, 0x0000320a},
+	{0x00008318, 0x00003e80, 0x00007d00, 0x00006880, 0x00003440},
+};
+
+static const u32 ar9340_1p0_soc_postamble[][5] = {
+	/*   Addr     5G_HT20     5G_HT40     2G_HT40     2G_HT20  */
+	{0x00007010, 0x00000023, 0x00000023, 0x00000023, 0x00000023},
+};
+
+static const u32 ar9340_1p0_baseband_postamble[][5] = {
+	/*  Addr      5G_HT20     5G_HT40     2G_HT40     2G_HT20  */
+	{0x00009810, 0xd00a8005, 0xd00a8005, 0xd00a8011, 0xd00a8011},
+	{0x00009820, 0x206a022e, 0x206a022e, 0x206a022e, 0x206a022e},
+	{0x00009824, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0},
+	{0x00009828, 0x06903081, 0x06903081, 0x06903881, 0x06903881},
+	{0x0000982c, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4},
+	{0x00009830, 0x0000059c, 0x0000059c, 0x0000119c, 0x0000119c},
+	{0x00009c00, 0x00000044, 0x000000c4, 0x000000c4, 0x00000044},
+	{0x00009e00, 0x0372161e, 0x0372161e, 0x037216a0, 0x037216a0},
+	{0x00009e04, 0x00182020, 0x00182020, 0x00182020, 0x00182020},
+	{0x00009e0c, 0x6c4000e2, 0x6d4000e2, 0x6d4000e2, 0x6c4000e2},
+	{0x00009e10, 0x7ec88d2e, 0x7ec88d2e, 0x7ec88d2e, 0x7ec88d2e},
+	{0x00009e14, 0x31395d5e, 0x3139605e, 0x3139605e, 0x31395d5e},
+	{0x00009e18, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+	{0x00009e1c, 0x0001cf9c, 0x0001cf9c, 0x00021f9c, 0x00021f9c},
+	{0x00009e20, 0x000003b5, 0x000003b5, 0x000003ce, 0x000003ce},
+	{0x00009e2c, 0x0000001c, 0x0000001c, 0x00000021, 0x00000021},
+	{0x00009e44, 0x02321e27, 0x02321e27, 0x02291e27, 0x02291e27},
+	{0x00009e48, 0x5030201a, 0x5030201a, 0x50302012, 0x50302012},
+	{0x00009fc8, 0x0003f000, 0x0003f000, 0x0001a000, 0x0001a000},
+	{0x0000a204, 0x00003fc0, 0x00003fc4, 0x00003fc4, 0x00003fc0},
+	{0x0000a208, 0x00000104, 0x00000104, 0x00000004, 0x00000004},
+	{0x0000a230, 0x0000000a, 0x00000014, 0x00000016, 0x0000000b},
+	{0x0000a238, 0xffb81018, 0xffb81018, 0xffb81018, 0xffb81018},
+	{0x0000a250, 0x00000000, 0x00000000, 0x00000210, 0x00000108},
+	{0x0000a254, 0x000007d0, 0x00000fa0, 0x00001130, 0x00000898},
+	{0x0000a258, 0x02020002, 0x02020002, 0x02020002, 0x02020002},
+	{0x0000a25c, 0x01000e0e, 0x01000e0e, 0x01000e0e, 0x01000e0e},
+	{0x0000a260, 0x0a021501, 0x0a021501, 0x3a021501, 0x3a021501},
+	{0x0000a264, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e},
+	{0x0000a280, 0x00000007, 0x00000007, 0x0000000b, 0x0000000b},
+	{0x0000a284, 0x00000000, 0x00000000, 0x00000150, 0x00000150},
+	{0x0000a288, 0x00000220, 0x00000220, 0x00000110, 0x00000110},
+	{0x0000a28c, 0x00011111, 0x00011111, 0x00022222, 0x00022222},
+	{0x0000a2c4, 0x00158d18, 0x00158d18, 0x00158d18, 0x00158d18},
+	{0x0000a2d0, 0x00071981, 0x00071981, 0x00071981, 0x00071982},
+	{0x0000a2d8, 0xf999a83a, 0xf999a83a, 0xf999a83a, 0xf999a83a},
+	{0x0000a358, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+	{0x0000a830, 0x0000019c, 0x0000019c, 0x0000019c, 0x0000019c},
+	{0x0000ae04, 0x00180000, 0x00180000, 0x00180000, 0x00180000},
+	{0x0000ae18, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+	{0x0000ae1c, 0x0000019c, 0x0000019c, 0x0000019c, 0x0000019c},
+	{0x0000ae20, 0x000001b5, 0x000001b5, 0x000001ce, 0x000001ce},
+	{0x0000b284, 0x00000000, 0x00000000, 0x00000150, 0x00000150},
+};
+
+static const u32 ar9340_1p0_baseband_core[][2] = {
+	/*  Addr     allmodes  */
+	{0x00009800, 0xafe68e30},
+	{0x00009804, 0xfd14e000},
+	{0x00009808, 0x9c0a9f6b},
+	{0x0000980c, 0x04900000},
+	{0x00009814, 0xb280c00a},
+	{0x00009818, 0x00000000},
+	{0x0000981c, 0x00020028},
+	{0x00009834, 0x5f3ca3de},
+	{0x00009838, 0x0108ecff},
+	{0x0000983c, 0x14750600},
+	{0x00009880, 0x201fff00},
+	{0x00009884, 0x00001042},
+	{0x000098a4, 0x00200400},
+	{0x000098b0, 0x52440bbe},
+	{0x000098d0, 0x004b6a8e},
+	{0x000098d4, 0x00000820},
+	{0x000098dc, 0x00000000},
+	{0x000098f0, 0x00000000},
+	{0x000098f4, 0x00000000},
+	{0x00009c04, 0xff55ff55},
+	{0x00009c08, 0x0320ff55},
+	{0x00009c0c, 0x00000000},
+	{0x00009c10, 0x00000000},
+	{0x00009c14, 0x00046384},
+	{0x00009c18, 0x05b6b440},
+	{0x00009c1c, 0x00b6b440},
+	{0x00009d00, 0xc080a333},
+	{0x00009d04, 0x40206c10},
+	{0x00009d08, 0x009c4060},
+	{0x00009d0c, 0x9883800a},
+	{0x00009d10, 0x01834061},
+	{0x00009d14, 0x00c0040b},
+	{0x00009d18, 0x00000000},
+	{0x00009e08, 0x0038230c},
+	{0x00009e24, 0x990bb515},
+	{0x00009e28, 0x0c6f0000},
+	{0x00009e30, 0x06336f77},
+	{0x00009e34, 0x6af6532f},
+	{0x00009e38, 0x0cc80c00},
+	{0x00009e3c, 0xcf946222},
+	{0x00009e40, 0x0d261820},
+	{0x00009e4c, 0x00001004},
+	{0x00009e50, 0x00ff03f1},
+	{0x00009e54, 0x00000000},
+	{0x00009fc0, 0x803e4788},
+	{0x00009fc4, 0x0001efb5},
+	{0x00009fcc, 0x40000014},
+	{0x00009fd0, 0x01193b93},
+	{0x0000a20c, 0x00000000},
+	{0x0000a220, 0x00000000},
+	{0x0000a224, 0x00000000},
+	{0x0000a228, 0x10002310},
+	{0x0000a22c, 0x01036a1e},
+	{0x0000a234, 0x10000fff},
+	{0x0000a23c, 0x00000000},
+	{0x0000a244, 0x0c000000},
+	{0x0000a2a0, 0x00000001},
+	{0x0000a2c0, 0x00000001},
+	{0x0000a2c8, 0x00000000},
+	{0x0000a2cc, 0x18c43433},
+	{0x0000a2d4, 0x00000000},
+	{0x0000a2dc, 0x00000000},
+	{0x0000a2e0, 0x00000000},
+	{0x0000a2e4, 0x00000000},
+	{0x0000a2e8, 0x00000000},
+	{0x0000a2ec, 0x00000000},
+	{0x0000a2f0, 0x00000000},
+	{0x0000a2f4, 0x00000000},
+	{0x0000a2f8, 0x00000000},
+	{0x0000a344, 0x00000000},
+	{0x0000a34c, 0x00000000},
+	{0x0000a350, 0x0000a000},
+	{0x0000a364, 0x00000000},
+	{0x0000a370, 0x00000000},
+	{0x0000a390, 0x00000001},
+	{0x0000a394, 0x00000444},
+	{0x0000a398, 0x001f0e0f},
+	{0x0000a39c, 0x0075393f},
+	{0x0000a3a0, 0xb79f6427},
+	{0x0000a3a4, 0x00000000},
+	{0x0000a3a8, 0xaaaaaaaa},
+	{0x0000a3ac, 0x3c466478},
+	{0x0000a3c0, 0x20202020},
+	{0x0000a3c4, 0x22222220},
+	{0x0000a3c8, 0x20200020},
+	{0x0000a3cc, 0x20202020},
+	{0x0000a3d0, 0x20202020},
+	{0x0000a3d4, 0x20202020},
+	{0x0000a3d8, 0x20202020},
+	{0x0000a3dc, 0x20202020},
+	{0x0000a3e0, 0x20202020},
+	{0x0000a3e4, 0x20202020},
+	{0x0000a3e8, 0x20202020},
+	{0x0000a3ec, 0x20202020},
+	{0x0000a3f0, 0x00000000},
+	{0x0000a3f4, 0x00000246},
+	{0x0000a3f8, 0x0cdbd380},
+	{0x0000a3fc, 0x000f0f01},
+	{0x0000a400, 0x8fa91f01},
+	{0x0000a404, 0x00000000},
+	{0x0000a408, 0x0e79e5c6},
+	{0x0000a40c, 0x00820820},
+	{0x0000a414, 0x1ce739ce},
+	{0x0000a418, 0x2d001dce},
+	{0x0000a41c, 0x1ce739ce},
+	{0x0000a420, 0x000001ce},
+	{0x0000a424, 0x1ce739ce},
+	{0x0000a428, 0x000001ce},
+	{0x0000a42c, 0x1ce739ce},
+	{0x0000a430, 0x1ce739ce},
+	{0x0000a434, 0x00000000},
+	{0x0000a438, 0x00001801},
+	{0x0000a43c, 0x00000000},
+	{0x0000a440, 0x00000000},
+	{0x0000a444, 0x00000000},
+	{0x0000a448, 0x04000080},
+	{0x0000a44c, 0x00000001},
+	{0x0000a450, 0x00010000},
+	{0x0000a458, 0x00000000},
+	{0x0000a600, 0x00000000},
+	{0x0000a604, 0x00000000},
+	{0x0000a608, 0x00000000},
+	{0x0000a60c, 0x00000000},
+	{0x0000a610, 0x00000000},
+	{0x0000a614, 0x00000000},
+	{0x0000a618, 0x00000000},
+	{0x0000a61c, 0x00000000},
+	{0x0000a620, 0x00000000},
+	{0x0000a624, 0x00000000},
+	{0x0000a628, 0x00000000},
+	{0x0000a62c, 0x00000000},
+	{0x0000a630, 0x00000000},
+	{0x0000a634, 0x00000000},
+	{0x0000a638, 0x00000000},
+	{0x0000a63c, 0x00000000},
+	{0x0000a640, 0x00000000},
+	{0x0000a644, 0x3fad9d74},
+	{0x0000a648, 0x0048060a},
+	{0x0000a64c, 0x00000637},
+	{0x0000a670, 0x03020100},
+	{0x0000a674, 0x09080504},
+	{0x0000a678, 0x0d0c0b0a},
+	{0x0000a67c, 0x13121110},
+	{0x0000a680, 0x31301514},
+	{0x0000a684, 0x35343332},
+	{0x0000a688, 0x00000036},
+	{0x0000a690, 0x00000838},
+	{0x0000a7c0, 0x00000000},
+	{0x0000a7c4, 0xfffffffc},
+	{0x0000a7c8, 0x00000000},
+	{0x0000a7cc, 0x00000000},
+	{0x0000a7d0, 0x00000000},
+	{0x0000a7d4, 0x00000004},
+	{0x0000a7dc, 0x00000000},
+	{0x0000a8d0, 0x004b6a8e},
+	{0x0000a8d4, 0x00000820},
+	{0x0000a8dc, 0x00000000},
+	{0x0000a8f0, 0x00000000},
+	{0x0000a8f4, 0x00000000},
+	{0x0000b2d0, 0x00000080},
+	{0x0000b2d4, 0x00000000},
+	{0x0000b2dc, 0x00000000},
+	{0x0000b2e0, 0x00000000},
+	{0x0000b2e4, 0x00000000},
+	{0x0000b2e8, 0x00000000},
+	{0x0000b2ec, 0x00000000},
+	{0x0000b2f0, 0x00000000},
+	{0x0000b2f4, 0x00000000},
+	{0x0000b2f8, 0x00000000},
+	{0x0000b408, 0x0e79e5c0},
+	{0x0000b40c, 0x00820820},
+	{0x0000b420, 0x00000000},
+};
+
+static const u32 ar9340Modes_high_power_tx_gain_table_1p0[][5] = {
+	/*  Addr      5G_HT20     5G_HT40     2G_HT40     2G_HT20  */
+	{0x0000a410, 0x000050d8, 0x000050d8, 0x000050d9, 0x000050d9},
+	{0x0000a500, 0x00002220, 0x00002220, 0x00000000, 0x00000000},
+	{0x0000a504, 0x04002222, 0x04002222, 0x04000002, 0x04000002},
+	{0x0000a508, 0x09002421, 0x09002421, 0x08000004, 0x08000004},
+	{0x0000a50c, 0x0d002621, 0x0d002621, 0x0b000200, 0x0b000200},
+	{0x0000a510, 0x13004620, 0x13004620, 0x0f000202, 0x0f000202},
+	{0x0000a514, 0x19004a20, 0x19004a20, 0x11000400, 0x11000400},
+	{0x0000a518, 0x1d004e20, 0x1d004e20, 0x15000402, 0x15000402},
+	{0x0000a51c, 0x21005420, 0x21005420, 0x19000404, 0x19000404},
+	{0x0000a520, 0x26005e20, 0x26005e20, 0x1b000603, 0x1b000603},
+	{0x0000a524, 0x2b005e40, 0x2b005e40, 0x1f000a02, 0x1f000a02},
+	{0x0000a528, 0x2f005e42, 0x2f005e42, 0x23000a04, 0x23000a04},
+	{0x0000a52c, 0x33005e44, 0x33005e44, 0x26000a20, 0x26000a20},
+	{0x0000a530, 0x38005e65, 0x38005e65, 0x2a000e20, 0x2a000e20},
+	{0x0000a534, 0x3c005e69, 0x3c005e69, 0x2e000e22, 0x2e000e22},
+	{0x0000a538, 0x40005e6b, 0x40005e6b, 0x31000e24, 0x31000e24},
+	{0x0000a53c, 0x44005e6d, 0x44005e6d, 0x34001640, 0x34001640},
+	{0x0000a540, 0x49005e72, 0x49005e72, 0x38001660, 0x38001660},
+	{0x0000a544, 0x4e005eb2, 0x4e005eb2, 0x3b001861, 0x3b001861},
+	{0x0000a548, 0x53005f12, 0x53005f12, 0x3e001a81, 0x3e001a81},
+	{0x0000a54c, 0x59025eb5, 0x59025eb5, 0x42001a83, 0x42001a83},
+	{0x0000a550, 0x5e025f12, 0x5e025f12, 0x44001c84, 0x44001c84},
+	{0x0000a554, 0x61027f12, 0x61027f12, 0x48001ce3, 0x48001ce3},
+	{0x0000a558, 0x6702bf12, 0x6702bf12, 0x4c001ce5, 0x4c001ce5},
+	{0x0000a55c, 0x6b02bf14, 0x6b02bf14, 0x50001ce9, 0x50001ce9},
+	{0x0000a560, 0x6f02bf16, 0x6f02bf16, 0x54001ceb, 0x54001ceb},
+	{0x0000a564, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
+	{0x0000a568, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
+	{0x0000a56c, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
+	{0x0000a570, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
+	{0x0000a574, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
+	{0x0000a578, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
+	{0x0000a57c, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
+	{0x0000a580, 0x00802220, 0x00802220, 0x00800000, 0x00800000},
+	{0x0000a584, 0x04802222, 0x04802222, 0x04800002, 0x04800002},
+	{0x0000a588, 0x09802421, 0x09802421, 0x08800004, 0x08800004},
+	{0x0000a58c, 0x0d802621, 0x0d802621, 0x0b800200, 0x0b800200},
+	{0x0000a590, 0x13804620, 0x13804620, 0x0f800202, 0x0f800202},
+	{0x0000a594, 0x19804a20, 0x19804a20, 0x11800400, 0x11800400},
+	{0x0000a598, 0x1d804e20, 0x1d804e20, 0x15800402, 0x15800402},
+	{0x0000a59c, 0x21805420, 0x21805420, 0x19800404, 0x19800404},
+	{0x0000a5a0, 0x26805e20, 0x26805e20, 0x1b800603, 0x1b800603},
+	{0x0000a5a4, 0x2b805e40, 0x2b805e40, 0x1f800a02, 0x1f800a02},
+	{0x0000a5a8, 0x2f805e42, 0x2f805e42, 0x23800a04, 0x23800a04},
+	{0x0000a5ac, 0x33805e44, 0x33805e44, 0x26800a20, 0x26800a20},
+	{0x0000a5b0, 0x38805e65, 0x38805e65, 0x2a800e20, 0x2a800e20},
+	{0x0000a5b4, 0x3c805e69, 0x3c805e69, 0x2e800e22, 0x2e800e22},
+	{0x0000a5b8, 0x40805e6b, 0x40805e6b, 0x31800e24, 0x31800e24},
+	{0x0000a5bc, 0x44805e6d, 0x44805e6d, 0x34801640, 0x34801640},
+	{0x0000a5c0, 0x49805e72, 0x49805e72, 0x38801660, 0x38801660},
+	{0x0000a5c4, 0x4e805eb2, 0x4e805eb2, 0x3b801861, 0x3b801861},
+	{0x0000a5c8, 0x53805f12, 0x53805f12, 0x3e801a81, 0x3e801a81},
+	{0x0000a5cc, 0x59825eb2, 0x59825eb2, 0x42801a83, 0x42801a83},
+	{0x0000a5d0, 0x5e825f12, 0x5e825f12, 0x44801c84, 0x44801c84},
+	{0x0000a5d4, 0x61827f12, 0x61827f12, 0x48801ce3, 0x48801ce3},
+	{0x0000a5d8, 0x6782bf12, 0x6782bf12, 0x4c801ce5, 0x4c801ce5},
+	{0x0000a5dc, 0x6b82bf14, 0x6b82bf14, 0x50801ce9, 0x50801ce9},
+	{0x0000a5e0, 0x6f82bf16, 0x6f82bf16, 0x54801ceb, 0x54801ceb},
+	{0x0000a5e4, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
+	{0x0000a5e8, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
+	{0x0000a5ec, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
+	{0x0000a5f0, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
+	{0x0000a5f4, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
+	{0x0000a5f8, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
+	{0x0000a5fc, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
+	{0x00016044, 0x056db2db, 0x056db2db, 0x056db2db, 0x056db2db},
+	{0x00016048, 0x24925266, 0x24925266, 0x24925266, 0x24925266},
+	{0x00016444, 0x056db2db, 0x056db2db, 0x056db2db, 0x056db2db},
+	{0x00016448, 0x24925266, 0x24925266, 0x24925266, 0x24925266},
+};
+
+static const u32 ar9340Modes_high_ob_db_tx_gain_table_1p0[][5] = {
+	/*  Addr       5G_HT20    5G_HT40     2G_HT40     2G_HT20  */
+	{0x0000a410, 0x000050d8, 0x000050d8, 0x000050d9, 0x000050d9},
+	{0x0000a500, 0x00002220, 0x00002220, 0x00000000, 0x00000000},
+	{0x0000a504, 0x04002222, 0x04002222, 0x04000002, 0x04000002},
+	{0x0000a508, 0x09002421, 0x09002421, 0x08000004, 0x08000004},
+	{0x0000a50c, 0x0d002621, 0x0d002621, 0x0b000200, 0x0b000200},
+	{0x0000a510, 0x13004620, 0x13004620, 0x0f000202, 0x0f000202},
+	{0x0000a514, 0x19004a20, 0x19004a20, 0x11000400, 0x11000400},
+	{0x0000a518, 0x1d004e20, 0x1d004e20, 0x15000402, 0x15000402},
+	{0x0000a51c, 0x21005420, 0x21005420, 0x19000404, 0x19000404},
+	{0x0000a520, 0x26005e20, 0x26005e20, 0x1b000603, 0x1b000603},
+	{0x0000a524, 0x2b005e40, 0x2b005e40, 0x1f000a02, 0x1f000a02},
+	{0x0000a528, 0x2f005e42, 0x2f005e42, 0x23000a04, 0x23000a04},
+	{0x0000a52c, 0x33005e44, 0x33005e44, 0x26000a20, 0x26000a20},
+	{0x0000a530, 0x38005e65, 0x38005e65, 0x2a000e20, 0x2a000e20},
+	{0x0000a534, 0x3c005e69, 0x3c005e69, 0x2e000e22, 0x2e000e22},
+	{0x0000a538, 0x40005e6b, 0x40005e6b, 0x31000e24, 0x31000e24},
+	{0x0000a53c, 0x44005e6d, 0x44005e6d, 0x34001640, 0x34001640},
+	{0x0000a540, 0x49005e72, 0x49005e72, 0x38001660, 0x38001660},
+	{0x0000a544, 0x4e005eb2, 0x4e005eb2, 0x3b001861, 0x3b001861},
+	{0x0000a548, 0x53005f12, 0x53005f12, 0x3e001a81, 0x3e001a81},
+	{0x0000a54c, 0x59025eb5, 0x59025eb5, 0x42001a83, 0x42001a83},
+	{0x0000a550, 0x5e025f12, 0x5e025f12, 0x44001c84, 0x44001c84},
+	{0x0000a554, 0x61027f12, 0x61027f12, 0x48001ce3, 0x48001ce3},
+	{0x0000a558, 0x6702bf12, 0x6702bf12, 0x4c001ce5, 0x4c001ce5},
+	{0x0000a55c, 0x6b02bf14, 0x6b02bf14, 0x50001ce9, 0x50001ce9},
+	{0x0000a560, 0x6f02bf16, 0x6f02bf16, 0x54001ceb, 0x54001ceb},
+	{0x0000a564, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
+	{0x0000a568, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
+	{0x0000a56c, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
+	{0x0000a570, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
+	{0x0000a574, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
+	{0x0000a578, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
+	{0x0000a57c, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
+	{0x0000a580, 0x00802220, 0x00802220, 0x00800000, 0x00800000},
+	{0x0000a584, 0x04802222, 0x04802222, 0x04800002, 0x04800002},
+	{0x0000a588, 0x09802421, 0x09802421, 0x08800004, 0x08800004},
+	{0x0000a58c, 0x0d802621, 0x0d802621, 0x0b800200, 0x0b800200},
+	{0x0000a590, 0x13804620, 0x13804620, 0x0f800202, 0x0f800202},
+	{0x0000a594, 0x19804a20, 0x19804a20, 0x11800400, 0x11800400},
+	{0x0000a598, 0x1d804e20, 0x1d804e20, 0x15800402, 0x15800402},
+	{0x0000a59c, 0x21805420, 0x21805420, 0x19800404, 0x19800404},
+	{0x0000a5a0, 0x26805e20, 0x26805e20, 0x1b800603, 0x1b800603},
+	{0x0000a5a4, 0x2b805e40, 0x2b805e40, 0x1f800a02, 0x1f800a02},
+	{0x0000a5a8, 0x2f805e42, 0x2f805e42, 0x23800a04, 0x23800a04},
+	{0x0000a5ac, 0x33805e44, 0x33805e44, 0x26800a20, 0x26800a20},
+	{0x0000a5b0, 0x38805e65, 0x38805e65, 0x2a800e20, 0x2a800e20},
+	{0x0000a5b4, 0x3c805e69, 0x3c805e69, 0x2e800e22, 0x2e800e22},
+	{0x0000a5b8, 0x40805e6b, 0x40805e6b, 0x31800e24, 0x31800e24},
+	{0x0000a5bc, 0x44805e6d, 0x44805e6d, 0x34801640, 0x34801640},
+	{0x0000a5c0, 0x49805e72, 0x49805e72, 0x38801660, 0x38801660},
+	{0x0000a5c4, 0x4e805eb2, 0x4e805eb2, 0x3b801861, 0x3b801861},
+	{0x0000a5c8, 0x53805f12, 0x53805f12, 0x3e801a81, 0x3e801a81},
+	{0x0000a5cc, 0x59825eb2, 0x59825eb2, 0x42801a83, 0x42801a83},
+	{0x0000a5d0, 0x5e825f12, 0x5e825f12, 0x44801c84, 0x44801c84},
+	{0x0000a5d4, 0x61827f12, 0x61827f12, 0x48801ce3, 0x48801ce3},
+	{0x0000a5d8, 0x6782bf12, 0x6782bf12, 0x4c801ce5, 0x4c801ce5},
+	{0x0000a5dc, 0x6b82bf14, 0x6b82bf14, 0x50801ce9, 0x50801ce9},
+	{0x0000a5e0, 0x6f82bf16, 0x6f82bf16, 0x54801ceb, 0x54801ceb},
+	{0x0000a5e4, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
+	{0x0000a5e8, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
+	{0x0000a5ec, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
+	{0x0000a5f0, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
+	{0x0000a5f4, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
+	{0x0000a5f8, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
+	{0x0000a5fc, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
+	{0x00016044, 0x03b6d2e4, 0x03b6d2e4, 0x03b6d2e4, 0x03b6d2e4},
+	{0x00016048, 0x8e481266, 0x8e481266, 0x8e481266, 0x8e481266},
+	{0x00016444, 0x03b6d2e4, 0x03b6d2e4, 0x03b6d2e4, 0x03b6d2e4},
+	{0x00016448, 0x8e481266, 0x8e481266, 0x8e481266, 0x8e481266},
+};
+static const u32 ar9340Modes_ub124_tx_gain_table_1p0[][5] = {
+	/*  Addr      5G_HT20      5G_HT40     2G_HT40    2G_HT20  */
+	{0x0000a410, 0x000050d8, 0x000050d8, 0x000050d9, 0x000050d9},
+	{0x0000a500, 0x00002220, 0x00002220, 0x00000000, 0x00000000},
+	{0x0000a504, 0x04002222, 0x04002222, 0x04000002, 0x04000002},
+	{0x0000a508, 0x09002421, 0x09002421, 0x08000004, 0x08000004},
+	{0x0000a50c, 0x0d002621, 0x0d002621, 0x0b000200, 0x0b000200},
+	{0x0000a510, 0x13004620, 0x13004620, 0x0f000202, 0x0f000202},
+	{0x0000a514, 0x19004a20, 0x19004a20, 0x11000400, 0x11000400},
+	{0x0000a518, 0x1d004e20, 0x1d004e20, 0x15000402, 0x15000402},
+	{0x0000a51c, 0x21005420, 0x21005420, 0x19000404, 0x19000404},
+	{0x0000a520, 0x26005e20, 0x26005e20, 0x1b000603, 0x1b000603},
+	{0x0000a524, 0x2b005e40, 0x2b005e40, 0x1f000a02, 0x1f000a02},
+	{0x0000a528, 0x2f005e42, 0x2f005e42, 0x23000a04, 0x23000a04},
+	{0x0000a52c, 0x33005e44, 0x33005e44, 0x26000a20, 0x26000a20},
+	{0x0000a530, 0x38005e65, 0x38005e65, 0x2a000e20, 0x2a000e20},
+	{0x0000a534, 0x3c005e69, 0x3c005e69, 0x2e000e22, 0x2e000e22},
+	{0x0000a538, 0x40005e6b, 0x40005e6b, 0x31000e24, 0x31000e24},
+	{0x0000a53c, 0x44005e6d, 0x44005e6d, 0x34001640, 0x34001640},
+	{0x0000a540, 0x49005e72, 0x49005e72, 0x38001660, 0x38001660},
+	{0x0000a544, 0x4e005eb2, 0x4e005eb2, 0x3b001861, 0x3b001861},
+	{0x0000a548, 0x53005f12, 0x53005f12, 0x3e001a81, 0x3e001a81},
+	{0x0000a54c, 0x59025eb5, 0x59025eb5, 0x42001a83, 0x42001a83},
+	{0x0000a550, 0x5e025f12, 0x5e025f12, 0x44001c84, 0x44001c84},
+	{0x0000a554, 0x61027f12, 0x61027f12, 0x48001ce3, 0x48001ce3},
+	{0x0000a558, 0x6702bf12, 0x6702bf12, 0x4c001ce5, 0x4c001ce5},
+	{0x0000a55c, 0x6b02bf14, 0x6b02bf14, 0x50001ce9, 0x50001ce9},
+	{0x0000a560, 0x6f02bf16, 0x6f02bf16, 0x54001ceb, 0x54001ceb},
+	{0x0000a564, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
+	{0x0000a568, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
+	{0x0000a56c, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
+	{0x0000a570, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
+	{0x0000a574, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
+	{0x0000a578, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
+	{0x0000a57c, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
+	{0x0000a580, 0x00802220, 0x00802220, 0x00800000, 0x00800000},
+	{0x0000a584, 0x04802222, 0x04802222, 0x04800002, 0x04800002},
+	{0x0000a588, 0x09802421, 0x09802421, 0x08800004, 0x08800004},
+	{0x0000a58c, 0x0d802621, 0x0d802621, 0x0b800200, 0x0b800200},
+	{0x0000a590, 0x13804620, 0x13804620, 0x0f800202, 0x0f800202},
+	{0x0000a594, 0x19804a20, 0x19804a20, 0x11800400, 0x11800400},
+	{0x0000a598, 0x1d804e20, 0x1d804e20, 0x15800402, 0x15800402},
+	{0x0000a59c, 0x21805420, 0x21805420, 0x19800404, 0x19800404},
+	{0x0000a5a0, 0x26805e20, 0x26805e20, 0x1b800603, 0x1b800603},
+	{0x0000a5a4, 0x2b805e40, 0x2b805e40, 0x1f800a02, 0x1f800a02},
+	{0x0000a5a8, 0x2f805e42, 0x2f805e42, 0x23800a04, 0x23800a04},
+	{0x0000a5ac, 0x33805e44, 0x33805e44, 0x26800a20, 0x26800a20},
+	{0x0000a5b0, 0x38805e65, 0x38805e65, 0x2a800e20, 0x2a800e20},
+	{0x0000a5b4, 0x3c805e69, 0x3c805e69, 0x2e800e22, 0x2e800e22},
+	{0x0000a5b8, 0x40805e6b, 0x40805e6b, 0x31800e24, 0x31800e24},
+	{0x0000a5bc, 0x44805e6d, 0x44805e6d, 0x34801640, 0x34801640},
+	{0x0000a5c0, 0x49805e72, 0x49805e72, 0x38801660, 0x38801660},
+	{0x0000a5c4, 0x4e805eb2, 0x4e805eb2, 0x3b801861, 0x3b801861},
+	{0x0000a5c8, 0x53805f12, 0x53805f12, 0x3e801a81, 0x3e801a81},
+	{0x0000a5cc, 0x59825eb2, 0x59825eb2, 0x42801a83, 0x42801a83},
+	{0x0000a5d0, 0x5e825f12, 0x5e825f12, 0x44801c84, 0x44801c84},
+	{0x0000a5d4, 0x61827f12, 0x61827f12, 0x48801ce3, 0x48801ce3},
+	{0x0000a5d8, 0x6782bf12, 0x6782bf12, 0x4c801ce5, 0x4c801ce5},
+	{0x0000a5dc, 0x6b82bf14, 0x6b82bf14, 0x50801ce9, 0x50801ce9},
+	{0x0000a5e0, 0x6f82bf16, 0x6f82bf16, 0x54801ceb, 0x54801ceb},
+	{0x0000a5e4, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
+	{0x0000a5e8, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
+	{0x0000a5ec, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
+	{0x0000a5f0, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
+	{0x0000a5f4, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
+	{0x0000a5f8, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
+	{0x0000a5fc, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
+	{0x00016044, 0x036db2db, 0x036db2db, 0x036db2db, 0x036db2db},
+	{0x00016048, 0x69b65266, 0x69b65266, 0x69b65266, 0x69b65266},
+	{0x00016444, 0x036db2db, 0x036db2db, 0x036db2db, 0x036db2db},
+	{0x00016448, 0x69b65266, 0x69b65266, 0x69b65266, 0x69b65266},
+};
+
+
+static const u32 ar9340Common_rx_gain_table_1p0[][2] = {
+	/*   Addr     allmodes */
+	{0x0000a000, 0x00010000},
+	{0x0000a004, 0x00030002},
+	{0x0000a008, 0x00050004},
+	{0x0000a00c, 0x00810080},
+	{0x0000a010, 0x00830082},
+	{0x0000a014, 0x01810180},
+	{0x0000a018, 0x01830182},
+	{0x0000a01c, 0x01850184},
+	{0x0000a020, 0x01890188},
+	{0x0000a024, 0x018b018a},
+	{0x0000a028, 0x018d018c},
+	{0x0000a02c, 0x01910190},
+	{0x0000a030, 0x01930192},
+	{0x0000a034, 0x01950194},
+	{0x0000a038, 0x038a0196},
+	{0x0000a03c, 0x038c038b},
+	{0x0000a040, 0x0390038d},
+	{0x0000a044, 0x03920391},
+	{0x0000a048, 0x03940393},
+	{0x0000a04c, 0x03960395},
+	{0x0000a050, 0x00000000},
+	{0x0000a054, 0x00000000},
+	{0x0000a058, 0x00000000},
+	{0x0000a05c, 0x00000000},
+	{0x0000a060, 0x00000000},
+	{0x0000a064, 0x00000000},
+	{0x0000a068, 0x00000000},
+	{0x0000a06c, 0x00000000},
+	{0x0000a070, 0x00000000},
+	{0x0000a074, 0x00000000},
+	{0x0000a078, 0x00000000},
+	{0x0000a07c, 0x00000000},
+	{0x0000a080, 0x22222229},
+	{0x0000a084, 0x1d1d1d1d},
+	{0x0000a088, 0x1d1d1d1d},
+	{0x0000a08c, 0x1d1d1d1d},
+	{0x0000a090, 0x171d1d1d},
+	{0x0000a094, 0x11111717},
+	{0x0000a098, 0x00030311},
+	{0x0000a09c, 0x00000000},
+	{0x0000a0a0, 0x00000000},
+	{0x0000a0a4, 0x00000000},
+	{0x0000a0a8, 0x00000000},
+	{0x0000a0ac, 0x00000000},
+	{0x0000a0b0, 0x00000000},
+	{0x0000a0b4, 0x00000000},
+	{0x0000a0b8, 0x00000000},
+	{0x0000a0bc, 0x00000000},
+	{0x0000a0c0, 0x001f0000},
+	{0x0000a0c4, 0x01000101},
+	{0x0000a0c8, 0x011e011f},
+	{0x0000a0cc, 0x011c011d},
+	{0x0000a0d0, 0x02030204},
+	{0x0000a0d4, 0x02010202},
+	{0x0000a0d8, 0x021f0200},
+	{0x0000a0dc, 0x0302021e},
+	{0x0000a0e0, 0x03000301},
+	{0x0000a0e4, 0x031e031f},
+	{0x0000a0e8, 0x0402031d},
+	{0x0000a0ec, 0x04000401},
+	{0x0000a0f0, 0x041e041f},
+	{0x0000a0f4, 0x0502041d},
+	{0x0000a0f8, 0x05000501},
+	{0x0000a0fc, 0x051e051f},
+	{0x0000a100, 0x06010602},
+	{0x0000a104, 0x061f0600},
+	{0x0000a108, 0x061d061e},
+	{0x0000a10c, 0x07020703},
+	{0x0000a110, 0x07000701},
+	{0x0000a114, 0x00000000},
+	{0x0000a118, 0x00000000},
+	{0x0000a11c, 0x00000000},
+	{0x0000a120, 0x00000000},
+	{0x0000a124, 0x00000000},
+	{0x0000a128, 0x00000000},
+	{0x0000a12c, 0x00000000},
+	{0x0000a130, 0x00000000},
+	{0x0000a134, 0x00000000},
+	{0x0000a138, 0x00000000},
+	{0x0000a13c, 0x00000000},
+	{0x0000a140, 0x001f0000},
+	{0x0000a144, 0x01000101},
+	{0x0000a148, 0x011e011f},
+	{0x0000a14c, 0x011c011d},
+	{0x0000a150, 0x02030204},
+	{0x0000a154, 0x02010202},
+	{0x0000a158, 0x021f0200},
+	{0x0000a15c, 0x0302021e},
+	{0x0000a160, 0x03000301},
+	{0x0000a164, 0x031e031f},
+	{0x0000a168, 0x0402031d},
+	{0x0000a16c, 0x04000401},
+	{0x0000a170, 0x041e041f},
+	{0x0000a174, 0x0502041d},
+	{0x0000a178, 0x05000501},
+	{0x0000a17c, 0x051e051f},
+	{0x0000a180, 0x06010602},
+	{0x0000a184, 0x061f0600},
+	{0x0000a188, 0x061d061e},
+	{0x0000a18c, 0x07020703},
+	{0x0000a190, 0x07000701},
+	{0x0000a194, 0x00000000},
+	{0x0000a198, 0x00000000},
+	{0x0000a19c, 0x00000000},
+	{0x0000a1a0, 0x00000000},
+	{0x0000a1a4, 0x00000000},
+	{0x0000a1a8, 0x00000000},
+	{0x0000a1ac, 0x00000000},
+	{0x0000a1b0, 0x00000000},
+	{0x0000a1b4, 0x00000000},
+	{0x0000a1b8, 0x00000000},
+	{0x0000a1bc, 0x00000000},
+	{0x0000a1c0, 0x00000000},
+	{0x0000a1c4, 0x00000000},
+	{0x0000a1c8, 0x00000000},
+	{0x0000a1cc, 0x00000000},
+	{0x0000a1d0, 0x00000000},
+	{0x0000a1d4, 0x00000000},
+	{0x0000a1d8, 0x00000000},
+	{0x0000a1dc, 0x00000000},
+	{0x0000a1e0, 0x00000000},
+	{0x0000a1e4, 0x00000000},
+	{0x0000a1e8, 0x00000000},
+	{0x0000a1ec, 0x00000000},
+	{0x0000a1f0, 0x00000396},
+	{0x0000a1f4, 0x00000396},
+	{0x0000a1f8, 0x00000396},
+	{0x0000a1fc, 0x00000196},
+	{0x0000b000, 0x00010000},
+	{0x0000b004, 0x00030002},
+	{0x0000b008, 0x00050004},
+	{0x0000b00c, 0x00810080},
+	{0x0000b010, 0x00830082},
+	{0x0000b014, 0x01810180},
+	{0x0000b018, 0x01830182},
+	{0x0000b01c, 0x01850184},
+	{0x0000b020, 0x02810280},
+	{0x0000b024, 0x02830282},
+	{0x0000b028, 0x02850284},
+	{0x0000b02c, 0x02890288},
+	{0x0000b030, 0x028b028a},
+	{0x0000b034, 0x0388028c},
+	{0x0000b038, 0x038a0389},
+	{0x0000b03c, 0x038c038b},
+	{0x0000b040, 0x0390038d},
+	{0x0000b044, 0x03920391},
+	{0x0000b048, 0x03940393},
+	{0x0000b04c, 0x03960395},
+	{0x0000b050, 0x00000000},
+	{0x0000b054, 0x00000000},
+	{0x0000b058, 0x00000000},
+	{0x0000b05c, 0x00000000},
+	{0x0000b060, 0x00000000},
+	{0x0000b064, 0x00000000},
+	{0x0000b068, 0x00000000},
+	{0x0000b06c, 0x00000000},
+	{0x0000b070, 0x00000000},
+	{0x0000b074, 0x00000000},
+	{0x0000b078, 0x00000000},
+	{0x0000b07c, 0x00000000},
+	{0x0000b080, 0x32323232},
+	{0x0000b084, 0x2f2f3232},
+	{0x0000b088, 0x23282a2d},
+	{0x0000b08c, 0x1c1e2123},
+	{0x0000b090, 0x14171919},
+	{0x0000b094, 0x0e0e1214},
+	{0x0000b098, 0x03050707},
+	{0x0000b09c, 0x00030303},
+	{0x0000b0a0, 0x00000000},
+	{0x0000b0a4, 0x00000000},
+	{0x0000b0a8, 0x00000000},
+	{0x0000b0ac, 0x00000000},
+	{0x0000b0b0, 0x00000000},
+	{0x0000b0b4, 0x00000000},
+	{0x0000b0b8, 0x00000000},
+	{0x0000b0bc, 0x00000000},
+	{0x0000b0c0, 0x003f0020},
+	{0x0000b0c4, 0x00400041},
+	{0x0000b0c8, 0x0140005f},
+	{0x0000b0cc, 0x0160015f},
+	{0x0000b0d0, 0x017e017f},
+	{0x0000b0d4, 0x02410242},
+	{0x0000b0d8, 0x025f0240},
+	{0x0000b0dc, 0x027f0260},
+	{0x0000b0e0, 0x0341027e},
+	{0x0000b0e4, 0x035f0340},
+	{0x0000b0e8, 0x037f0360},
+	{0x0000b0ec, 0x04400441},
+	{0x0000b0f0, 0x0460045f},
+	{0x0000b0f4, 0x0541047f},
+	{0x0000b0f8, 0x055f0540},
+	{0x0000b0fc, 0x057f0560},
+	{0x0000b100, 0x06400641},
+	{0x0000b104, 0x0660065f},
+	{0x0000b108, 0x067e067f},
+	{0x0000b10c, 0x07410742},
+	{0x0000b110, 0x075f0740},
+	{0x0000b114, 0x077f0760},
+	{0x0000b118, 0x07800781},
+	{0x0000b11c, 0x07a0079f},
+	{0x0000b120, 0x07c107bf},
+	{0x0000b124, 0x000007c0},
+	{0x0000b128, 0x00000000},
+	{0x0000b12c, 0x00000000},
+	{0x0000b130, 0x00000000},
+	{0x0000b134, 0x00000000},
+	{0x0000b138, 0x00000000},
+	{0x0000b13c, 0x00000000},
+	{0x0000b140, 0x003f0020},
+	{0x0000b144, 0x00400041},
+	{0x0000b148, 0x0140005f},
+	{0x0000b14c, 0x0160015f},
+	{0x0000b150, 0x017e017f},
+	{0x0000b154, 0x02410242},
+	{0x0000b158, 0x025f0240},
+	{0x0000b15c, 0x027f0260},
+	{0x0000b160, 0x0341027e},
+	{0x0000b164, 0x035f0340},
+	{0x0000b168, 0x037f0360},
+	{0x0000b16c, 0x04400441},
+	{0x0000b170, 0x0460045f},
+	{0x0000b174, 0x0541047f},
+	{0x0000b178, 0x055f0540},
+	{0x0000b17c, 0x057f0560},
+	{0x0000b180, 0x06400641},
+	{0x0000b184, 0x0660065f},
+	{0x0000b188, 0x067e067f},
+	{0x0000b18c, 0x07410742},
+	{0x0000b190, 0x075f0740},
+	{0x0000b194, 0x077f0760},
+	{0x0000b198, 0x07800781},
+	{0x0000b19c, 0x07a0079f},
+	{0x0000b1a0, 0x07c107bf},
+	{0x0000b1a4, 0x000007c0},
+	{0x0000b1a8, 0x00000000},
+	{0x0000b1ac, 0x00000000},
+	{0x0000b1b0, 0x00000000},
+	{0x0000b1b4, 0x00000000},
+	{0x0000b1b8, 0x00000000},
+	{0x0000b1bc, 0x00000000},
+	{0x0000b1c0, 0x00000000},
+	{0x0000b1c4, 0x00000000},
+	{0x0000b1c8, 0x00000000},
+	{0x0000b1cc, 0x00000000},
+	{0x0000b1d0, 0x00000000},
+	{0x0000b1d4, 0x00000000},
+	{0x0000b1d8, 0x00000000},
+	{0x0000b1dc, 0x00000000},
+	{0x0000b1e0, 0x00000000},
+	{0x0000b1e4, 0x00000000},
+	{0x0000b1e8, 0x00000000},
+	{0x0000b1ec, 0x00000000},
+	{0x0000b1f0, 0x00000396},
+	{0x0000b1f4, 0x00000396},
+	{0x0000b1f8, 0x00000396},
+	{0x0000b1fc, 0x00000196},
+};
+
+static const u32 ar9340Modes_low_ob_db_tx_gain_table_1p0[][5] = {
+	/*  Addr      5G_HT20     5G_HT40     2G_HT40     2G_HT20  */
+	{0x0000a410, 0x000050d9, 0x000050d9, 0x000050d9, 0x000050d9},
+	{0x0000a500, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+	{0x0000a504, 0x06000003, 0x06000003, 0x04000002, 0x04000002},
+	{0x0000a508, 0x0a000020, 0x0a000020, 0x08000004, 0x08000004},
+	{0x0000a50c, 0x10000023, 0x10000023, 0x0b000200, 0x0b000200},
+	{0x0000a510, 0x16000220, 0x16000220, 0x0f000202, 0x0f000202},
+	{0x0000a514, 0x1c000223, 0x1c000223, 0x12000400, 0x12000400},
+	{0x0000a518, 0x21020220, 0x21020220, 0x16000402, 0x16000402},
+	{0x0000a51c, 0x27020223, 0x27020223, 0x19000404, 0x19000404},
+	{0x0000a520, 0x2b022220, 0x2b022220, 0x1c000603, 0x1c000603},
+	{0x0000a524, 0x2f022222, 0x2f022222, 0x21000a02, 0x21000a02},
+	{0x0000a528, 0x34022225, 0x34022225, 0x25000a04, 0x25000a04},
+	{0x0000a52c, 0x3a02222a, 0x3a02222a, 0x28000a20, 0x28000a20},
+	{0x0000a530, 0x3e02222c, 0x3e02222c, 0x2c000e20, 0x2c000e20},
+	{0x0000a534, 0x4202242a, 0x4202242a, 0x30000e22, 0x30000e22},
+	{0x0000a538, 0x4702244a, 0x4702244a, 0x34000e24, 0x34000e24},
+	{0x0000a53c, 0x4b02244c, 0x4b02244c, 0x38001640, 0x38001640},
+	{0x0000a540, 0x4e02246c, 0x4e02246c, 0x3c001660, 0x3c001660},
+	{0x0000a544, 0x5302266c, 0x5302266c, 0x3f001861, 0x3f001861},
+	{0x0000a548, 0x5702286c, 0x5702286c, 0x43001a81, 0x43001a81},
+	{0x0000a54c, 0x5c04286b, 0x5c04286b, 0x47001a83, 0x47001a83},
+	{0x0000a550, 0x61042a6c, 0x61042a6c, 0x4a001c84, 0x4a001c84},
+	{0x0000a554, 0x66062a6c, 0x66062a6c, 0x4e001ce3, 0x4e001ce3},
+	{0x0000a558, 0x6b062e6c, 0x6b062e6c, 0x52001ce5, 0x52001ce5},
+	{0x0000a55c, 0x7006308c, 0x7006308c, 0x56001ce9, 0x56001ce9},
+	{0x0000a560, 0x730a308a, 0x730a308a, 0x5a001ceb, 0x5a001ceb},
+	{0x0000a564, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec},
+	{0x0000a568, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec},
+	{0x0000a56c, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec},
+	{0x0000a570, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec},
+	{0x0000a574, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec},
+	{0x0000a578, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec},
+	{0x0000a57c, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec},
+	{0x0000a580, 0x00800000, 0x00800000, 0x00800000, 0x00800000},
+	{0x0000a584, 0x06800003, 0x06800003, 0x04800002, 0x04800002},
+	{0x0000a588, 0x0a800020, 0x0a800020, 0x08800004, 0x08800004},
+	{0x0000a58c, 0x10800023, 0x10800023, 0x0b800200, 0x0b800200},
+	{0x0000a590, 0x16800220, 0x16800220, 0x0f800202, 0x0f800202},
+	{0x0000a594, 0x1c800223, 0x1c800223, 0x12800400, 0x12800400},
+	{0x0000a598, 0x21820220, 0x21820220, 0x16800402, 0x16800402},
+	{0x0000a59c, 0x27820223, 0x27820223, 0x19800404, 0x19800404},
+	{0x0000a5a0, 0x2b822220, 0x2b822220, 0x1c800603, 0x1c800603},
+	{0x0000a5a4, 0x2f822222, 0x2f822222, 0x21800a02, 0x21800a02},
+	{0x0000a5a8, 0x34822225, 0x34822225, 0x25800a04, 0x25800a04},
+	{0x0000a5ac, 0x3a82222a, 0x3a82222a, 0x28800a20, 0x28800a20},
+	{0x0000a5b0, 0x3e82222c, 0x3e82222c, 0x2c800e20, 0x2c800e20},
+	{0x0000a5b4, 0x4282242a, 0x4282242a, 0x30800e22, 0x30800e22},
+	{0x0000a5b8, 0x4782244a, 0x4782244a, 0x34800e24, 0x34800e24},
+	{0x0000a5bc, 0x4b82244c, 0x4b82244c, 0x38801640, 0x38801640},
+	{0x0000a5c0, 0x4e82246c, 0x4e82246c, 0x3c801660, 0x3c801660},
+	{0x0000a5c4, 0x5382266c, 0x5382266c, 0x3f801861, 0x3f801861},
+	{0x0000a5c8, 0x5782286c, 0x5782286c, 0x43801a81, 0x43801a81},
+	{0x0000a5cc, 0x5c84286b, 0x5c84286b, 0x47801a83, 0x47801a83},
+	{0x0000a5d0, 0x61842a6c, 0x61842a6c, 0x4a801c84, 0x4a801c84},
+	{0x0000a5d4, 0x66862a6c, 0x66862a6c, 0x4e801ce3, 0x4e801ce3},
+	{0x0000a5d8, 0x6b862e6c, 0x6b862e6c, 0x52801ce5, 0x52801ce5},
+	{0x0000a5dc, 0x7086308c, 0x7086308c, 0x56801ce9, 0x56801ce9},
+	{0x0000a5e0, 0x738a308a, 0x738a308a, 0x5a801ceb, 0x5a801ceb},
+	{0x0000a5e4, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec},
+	{0x0000a5e8, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec},
+	{0x0000a5ec, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec},
+	{0x0000a5f0, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec},
+	{0x0000a5f4, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec},
+	{0x0000a5f8, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec},
+	{0x0000a5fc, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec},
+	{0x00016044, 0x056db2db, 0x056db2db, 0x056db2db, 0x056db2db},
+	{0x00016048, 0x24925266, 0x24925266, 0x24925266, 0x24925266},
+	{0x00016444, 0x056db2db, 0x056db2db, 0x056db2db, 0x056db2db},
+	{0x00016448, 0x24925266, 0x24925266, 0x24925266, 0x24925266},
+};
+
+static const u32 ar9340Modes_mixed_ob_db_tx_gain_table_1p0[][5] = {
+	/*  Addr       5G_HT20     5G_HT40     2G_HT40    2G_HT20  */
+	{0x0000a410, 0x000050d9, 0x000050d9, 0x000050d9, 0x000050d9},
+	{0x0000a500, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+	{0x0000a504, 0x06000003, 0x06000003, 0x04000002, 0x04000002},
+	{0x0000a508, 0x0a000020, 0x0a000020, 0x08000004, 0x08000004},
+	{0x0000a50c, 0x10000023, 0x10000023, 0x0b000200, 0x0b000200},
+	{0x0000a510, 0x16000220, 0x16000220, 0x0f000202, 0x0f000202},
+	{0x0000a514, 0x1c000223, 0x1c000223, 0x11000400, 0x11000400},
+	{0x0000a518, 0x21020220, 0x21020220, 0x15000402, 0x15000402},
+	{0x0000a51c, 0x27020223, 0x27020223, 0x19000404, 0x19000404},
+	{0x0000a520, 0x2b022220, 0x2b022220, 0x1b000603, 0x1b000603},
+	{0x0000a524, 0x2f022222, 0x2f022222, 0x1f000a02, 0x1f000a02},
+	{0x0000a528, 0x34022225, 0x34022225, 0x23000a04, 0x23000a04},
+	{0x0000a52c, 0x3a02222a, 0x3a02222a, 0x26000a20, 0x26000a20},
+	{0x0000a530, 0x3e02222c, 0x3e02222c, 0x2a000e20, 0x2a000e20},
+	{0x0000a534, 0x4202242a, 0x4202242a, 0x2e000e22, 0x2e000e22},
+	{0x0000a538, 0x4702244a, 0x4702244a, 0x31000e24, 0x31000e24},
+	{0x0000a53c, 0x4b02244c, 0x4b02244c, 0x34001640, 0x34001640},
+	{0x0000a540, 0x4e02246c, 0x4e02246c, 0x38001660, 0x38001660},
+	{0x0000a544, 0x5302266c, 0x5302266c, 0x3b001861, 0x3b001861},
+	{0x0000a548, 0x5702286c, 0x5702286c, 0x3e001a81, 0x3e001a81},
+	{0x0000a54c, 0x5c04286b, 0x5c04286b, 0x42001a83, 0x42001a83},
+	{0x0000a550, 0x61042a6c, 0x61042a6c, 0x44001c84, 0x44001c84},
+	{0x0000a554, 0x66062a6c, 0x66062a6c, 0x48001ce3, 0x48001ce3},
+	{0x0000a558, 0x6b062e6c, 0x6b062e6c, 0x4c001ce5, 0x4c001ce5},
+	{0x0000a55c, 0x7006308c, 0x7006308c, 0x50001ce9, 0x50001ce9},
+	{0x0000a560, 0x730a308a, 0x730a308a, 0x54001ceb, 0x54001ceb},
+	{0x0000a564, 0x770a308c, 0x770a308c, 0x56001eec, 0x56001eec},
+	{0x0000a568, 0x770a308c, 0x770a308c, 0x56001eec, 0x56001eec},
+	{0x0000a56c, 0x770a308c, 0x770a308c, 0x56001eec, 0x56001eec},
+	{0x0000a570, 0x770a308c, 0x770a308c, 0x56001eec, 0x56001eec},
+	{0x0000a574, 0x770a308c, 0x770a308c, 0x56001eec, 0x56001eec},
+	{0x0000a578, 0x770a308c, 0x770a308c, 0x56001eec, 0x56001eec},
+	{0x0000a57c, 0x770a308c, 0x770a308c, 0x56001eec, 0x56001eec},
+	{0x0000a580, 0x00800000, 0x00800000, 0x00800000, 0x00800000},
+	{0x0000a584, 0x06800003, 0x06800003, 0x04800002, 0x04800002},
+	{0x0000a588, 0x0a800020, 0x0a800020, 0x08800004, 0x08800004},
+	{0x0000a58c, 0x10800023, 0x10800023, 0x0b800200, 0x0b800200},
+	{0x0000a590, 0x16800220, 0x16800220, 0x0f800202, 0x0f800202},
+	{0x0000a594, 0x1c800223, 0x1c800223, 0x11800400, 0x11800400},
+	{0x0000a598, 0x21820220, 0x21820220, 0x15800402, 0x15800402},
+	{0x0000a59c, 0x27820223, 0x27820223, 0x19800404, 0x19800404},
+	{0x0000a5a0, 0x2b822220, 0x2b822220, 0x1b800603, 0x1b800603},
+	{0x0000a5a4, 0x2f822222, 0x2f822222, 0x1f800a02, 0x1f800a02},
+	{0x0000a5a8, 0x34822225, 0x34822225, 0x23800a04, 0x23800a04},
+	{0x0000a5ac, 0x3a82222a, 0x3a82222a, 0x26800a20, 0x26800a20},
+	{0x0000a5b0, 0x3e82222c, 0x3e82222c, 0x2a800e20, 0x2a800e20},
+	{0x0000a5b4, 0x4282242a, 0x4282242a, 0x2e800e22, 0x2e800e22},
+	{0x0000a5b8, 0x4782244a, 0x4782244a, 0x31800e24, 0x31800e24},
+	{0x0000a5bc, 0x4b82244c, 0x4b82244c, 0x34801640, 0x34801640},
+	{0x0000a5c0, 0x4e82246c, 0x4e82246c, 0x38801660, 0x38801660},
+	{0x0000a5c4, 0x5382266c, 0x5382266c, 0x3b801861, 0x3b801861},
+	{0x0000a5c8, 0x5782286c, 0x5782286c, 0x3e801a81, 0x3e801a81},
+	{0x0000a5cc, 0x5c84286b, 0x5c84286b, 0x42801a83, 0x42801a83},
+	{0x0000a5d0, 0x61842a6c, 0x61842a6c, 0x44801c84, 0x44801c84},
+	{0x0000a5d4, 0x66862a6c, 0x66862a6c, 0x48801ce3, 0x48801ce3},
+	{0x0000a5d8, 0x6b862e6c, 0x6b862e6c, 0x4c801ce5, 0x4c801ce5},
+	{0x0000a5dc, 0x7086308c, 0x7086308c, 0x50801ce9, 0x50801ce9},
+	{0x0000a5e0, 0x738a308a, 0x738a308a, 0x54801ceb, 0x54801ceb},
+	{0x0000a5e4, 0x778a308c, 0x778a308c, 0x56801eec, 0x56801eec},
+	{0x0000a5e8, 0x778a308c, 0x778a308c, 0x56801eec, 0x56801eec},
+	{0x0000a5ec, 0x778a308c, 0x778a308c, 0x56801eec, 0x56801eec},
+	{0x0000a5f0, 0x778a308c, 0x778a308c, 0x56801eec, 0x56801eec},
+	{0x0000a5f4, 0x778a308c, 0x778a308c, 0x56801eec, 0x56801eec},
+	{0x0000a5f8, 0x778a308c, 0x778a308c, 0x56801eec, 0x56801eec},
+	{0x0000a5fc, 0x778a308c, 0x778a308c, 0x56801eec, 0x56801eec},
+	{0x00016044, 0x056db2db, 0x056db2db, 0x03b6d2e4, 0x03b6d2e4},
+	{0x00016048, 0x24927266, 0x24927266, 0x8e483266, 0x8e483266},
+	{0x00016444, 0x056db2db, 0x056db2db, 0x03b6d2e4, 0x03b6d2e4},
+	{0x00016448, 0x24927266, 0x24927266, 0x8e482266, 0x8e482266},
+};
+
+static const u32 ar9340_1p0_mac_core[][2] = {
+	/*    Addr        allmodes        */
+	{0x00000008, 0x00000000},
+	{0x00000030, 0x00020085},
+	{0x00000034, 0x00000005},
+	{0x00000040, 0x00000000},
+	{0x00000044, 0x00000000},
+	{0x00000048, 0x00000008},
+	{0x0000004c, 0x00000010},
+	{0x00000050, 0x00000000},
+	{0x00001040, 0x002ffc0f},
+	{0x00001044, 0x002ffc0f},
+	{0x00001048, 0x002ffc0f},
+	{0x0000104c, 0x002ffc0f},
+	{0x00001050, 0x002ffc0f},
+	{0x00001054, 0x002ffc0f},
+	{0x00001058, 0x002ffc0f},
+	{0x0000105c, 0x002ffc0f},
+	{0x00001060, 0x002ffc0f},
+	{0x00001064, 0x002ffc0f},
+	{0x000010f0, 0x00000100},
+	{0x00001270, 0x00000000},
+	{0x000012b0, 0x00000000},
+	{0x000012f0, 0x00000000},
+	{0x0000143c, 0x00000000},
+	{0x0000147c, 0x00000000},
+	{0x00008000, 0x00000000},
+	{0x00008004, 0x00000000},
+	{0x00008008, 0x00000000},
+	{0x0000800c, 0x00000000},
+	{0x00008018, 0x00000000},
+	{0x00008020, 0x00000000},
+	{0x00008038, 0x00000000},
+	{0x0000803c, 0x00000000},
+	{0x00008040, 0x00000000},
+	{0x00008044, 0x00000000},
+	{0x00008048, 0x00000000},
+	{0x0000804c, 0xffffffff},
+	{0x00008054, 0x00000000},
+	{0x00008058, 0x00000000},
+	{0x0000805c, 0x000fc78f},
+	{0x00008060, 0x0000000f},
+	{0x00008064, 0x00000000},
+	{0x00008070, 0x00000310},
+	{0x00008074, 0x00000020},
+	{0x00008078, 0x00000000},
+	{0x0000809c, 0x0000000f},
+	{0x000080a0, 0x00000000},
+	{0x000080a4, 0x02ff0000},
+	{0x000080a8, 0x0e070605},
+	{0x000080ac, 0x0000000d},
+	{0x000080b0, 0x00000000},
+	{0x000080b4, 0x00000000},
+	{0x000080b8, 0x00000000},
+	{0x000080bc, 0x00000000},
+	{0x000080c0, 0x2a800000},
+	{0x000080c4, 0x06900168},
+	{0x000080c8, 0x13881c20},
+	{0x000080cc, 0x01f40000},
+	{0x000080d0, 0x00252500},
+	{0x000080d4, 0x00a00000},
+	{0x000080d8, 0x00400000},
+	{0x000080dc, 0x00000000},
+	{0x000080e0, 0xffffffff},
+	{0x000080e4, 0x0000ffff},
+	{0x000080e8, 0x3f3f3f3f},
+	{0x000080ec, 0x00000000},
+	{0x000080f0, 0x00000000},
+	{0x000080f4, 0x00000000},
+	{0x000080fc, 0x00020000},
+	{0x00008100, 0x00000000},
+	{0x00008108, 0x00000052},
+	{0x0000810c, 0x00000000},
+	{0x00008110, 0x00000000},
+	{0x00008114, 0x000007ff},
+	{0x00008118, 0x000000aa},
+	{0x0000811c, 0x00003210},
+	{0x00008124, 0x00000000},
+	{0x00008128, 0x00000000},
+	{0x0000812c, 0x00000000},
+	{0x00008130, 0x00000000},
+	{0x00008134, 0x00000000},
+	{0x00008138, 0x00000000},
+	{0x0000813c, 0x0000ffff},
+	{0x00008144, 0xffffffff},
+	{0x00008168, 0x00000000},
+	{0x0000816c, 0x00000000},
+	{0x00008170, 0x18486200},
+	{0x00008174, 0x33332210},
+	{0x00008178, 0x00000000},
+	{0x0000817c, 0x00020000},
+	{0x000081c0, 0x00000000},
+	{0x000081c4, 0x33332210},
+	{0x000081c8, 0x00000000},
+	{0x000081cc, 0x00000000},
+	{0x000081d4, 0x00000000},
+	{0x000081ec, 0x00000000},
+	{0x000081f0, 0x00000000},
+	{0x000081f4, 0x00000000},
+	{0x000081f8, 0x00000000},
+	{0x000081fc, 0x00000000},
+	{0x00008240, 0x00100000},
+	{0x00008244, 0x0010f424},
+	{0x00008248, 0x00000800},
+	{0x0000824c, 0x0001e848},
+	{0x00008250, 0x00000000},
+	{0x00008254, 0x00000000},
+	{0x00008258, 0x00000000},
+	{0x0000825c, 0x40000000},
+	{0x00008260, 0x00080922},
+	{0x00008264, 0x9d400010},
+	{0x00008268, 0xffffffff},
+	{0x0000826c, 0x0000ffff},
+	{0x00008270, 0x00000000},
+	{0x00008274, 0x40000000},
+	{0x00008278, 0x003e4180},
+	{0x0000827c, 0x00000004},
+	{0x00008284, 0x0000002c},
+	{0x00008288, 0x0000002c},
+	{0x0000828c, 0x000000ff},
+	{0x00008294, 0x00000000},
+	{0x00008298, 0x00000000},
+	{0x0000829c, 0x00000000},
+	{0x00008300, 0x00000140},
+	{0x00008314, 0x00000000},
+	{0x0000831c, 0x0000010d},
+	{0x00008328, 0x00000000},
+	{0x0000832c, 0x00000007},
+	{0x00008330, 0x00000302},
+	{0x00008334, 0x00000700},
+	{0x00008338, 0x00ff0000},
+	{0x0000833c, 0x02400000},
+	{0x00008340, 0x000107ff},
+	{0x00008344, 0xaa48105b},
+	{0x00008348, 0x008f0000},
+	{0x0000835c, 0x00000000},
+	{0x00008360, 0xffffffff},
+	{0x00008364, 0xffffffff},
+	{0x00008368, 0x00000000},
+	{0x00008370, 0x00000000},
+	{0x00008374, 0x000000ff},
+	{0x00008378, 0x00000000},
+	{0x0000837c, 0x00000000},
+	{0x00008380, 0xffffffff},
+	{0x00008384, 0xffffffff},
+	{0x00008390, 0xffffffff},
+	{0x00008394, 0xffffffff},
+	{0x00008398, 0x00000000},
+	{0x0000839c, 0x00000000},
+	{0x000083a0, 0x00000000},
+	{0x000083a4, 0x0000fa14},
+	{0x000083a8, 0x000f0c00},
+	{0x000083ac, 0x33332210},
+	{0x000083b0, 0x33332210},
+	{0x000083b4, 0x33332210},
+	{0x000083b8, 0x33332210},
+	{0x000083bc, 0x00000000},
+	{0x000083c0, 0x00000000},
+	{0x000083c4, 0x00000000},
+	{0x000083c8, 0x00000000},
+	{0x000083cc, 0x00000200},
+	{0x000083d0, 0x000301ff},
+};
+
+static const u32 ar9340Common_wo_xlna_rx_gain_table_1p0[][2] = {
+	/*    Addr        allmodes        */
+	{0x0000a000, 0x00010000},
+	{0x0000a004, 0x00030002},
+	{0x0000a008, 0x00050004},
+	{0x0000a00c, 0x00810080},
+	{0x0000a010, 0x00830082},
+	{0x0000a014, 0x01810180},
+	{0x0000a018, 0x01830182},
+	{0x0000a01c, 0x01850184},
+	{0x0000a020, 0x01890188},
+	{0x0000a024, 0x018b018a},
+	{0x0000a028, 0x018d018c},
+	{0x0000a02c, 0x03820190},
+	{0x0000a030, 0x03840383},
+	{0x0000a034, 0x03880385},
+	{0x0000a038, 0x038a0389},
+	{0x0000a03c, 0x038c038b},
+	{0x0000a040, 0x0390038d},
+	{0x0000a044, 0x03920391},
+	{0x0000a048, 0x03940393},
+	{0x0000a04c, 0x03960395},
+	{0x0000a050, 0x00000000},
+	{0x0000a054, 0x00000000},
+	{0x0000a058, 0x00000000},
+	{0x0000a05c, 0x00000000},
+	{0x0000a060, 0x00000000},
+	{0x0000a064, 0x00000000},
+	{0x0000a068, 0x00000000},
+	{0x0000a06c, 0x00000000},
+	{0x0000a070, 0x00000000},
+	{0x0000a074, 0x00000000},
+	{0x0000a078, 0x00000000},
+	{0x0000a07c, 0x00000000},
+	{0x0000a080, 0x29292929},
+	{0x0000a084, 0x29292929},
+	{0x0000a088, 0x29292929},
+	{0x0000a08c, 0x29292929},
+	{0x0000a090, 0x22292929},
+	{0x0000a094, 0x1d1d2222},
+	{0x0000a098, 0x0c111117},
+	{0x0000a09c, 0x00030303},
+	{0x0000a0a0, 0x00000000},
+	{0x0000a0a4, 0x00000000},
+	{0x0000a0a8, 0x00000000},
+	{0x0000a0ac, 0x00000000},
+	{0x0000a0b0, 0x00000000},
+	{0x0000a0b4, 0x00000000},
+	{0x0000a0b8, 0x00000000},
+	{0x0000a0bc, 0x00000000},
+	{0x0000a0c0, 0x001f0000},
+	{0x0000a0c4, 0x01000101},
+	{0x0000a0c8, 0x011e011f},
+	{0x0000a0cc, 0x011c011d},
+	{0x0000a0d0, 0x02030204},
+	{0x0000a0d4, 0x02010202},
+	{0x0000a0d8, 0x021f0200},
+	{0x0000a0dc, 0x0302021e},
+	{0x0000a0e0, 0x03000301},
+	{0x0000a0e4, 0x031e031f},
+	{0x0000a0e8, 0x0402031d},
+	{0x0000a0ec, 0x04000401},
+	{0x0000a0f0, 0x041e041f},
+	{0x0000a0f4, 0x0502041d},
+	{0x0000a0f8, 0x05000501},
+	{0x0000a0fc, 0x051e051f},
+	{0x0000a100, 0x06010602},
+	{0x0000a104, 0x061f0600},
+	{0x0000a108, 0x061d061e},
+	{0x0000a10c, 0x07020703},
+	{0x0000a110, 0x07000701},
+	{0x0000a114, 0x00000000},
+	{0x0000a118, 0x00000000},
+	{0x0000a11c, 0x00000000},
+	{0x0000a120, 0x00000000},
+	{0x0000a124, 0x00000000},
+	{0x0000a128, 0x00000000},
+	{0x0000a12c, 0x00000000},
+	{0x0000a130, 0x00000000},
+	{0x0000a134, 0x00000000},
+	{0x0000a138, 0x00000000},
+	{0x0000a13c, 0x00000000},
+	{0x0000a140, 0x001f0000},
+	{0x0000a144, 0x01000101},
+	{0x0000a148, 0x011e011f},
+	{0x0000a14c, 0x011c011d},
+	{0x0000a150, 0x02030204},
+	{0x0000a154, 0x02010202},
+	{0x0000a158, 0x021f0200},
+	{0x0000a15c, 0x0302021e},
+	{0x0000a160, 0x03000301},
+	{0x0000a164, 0x031e031f},
+	{0x0000a168, 0x0402031d},
+	{0x0000a16c, 0x04000401},
+	{0x0000a170, 0x041e041f},
+	{0x0000a174, 0x0502041d},
+	{0x0000a178, 0x05000501},
+	{0x0000a17c, 0x051e051f},
+	{0x0000a180, 0x06010602},
+	{0x0000a184, 0x061f0600},
+	{0x0000a188, 0x061d061e},
+	{0x0000a18c, 0x07020703},
+	{0x0000a190, 0x07000701},
+	{0x0000a194, 0x00000000},
+	{0x0000a198, 0x00000000},
+	{0x0000a19c, 0x00000000},
+	{0x0000a1a0, 0x00000000},
+	{0x0000a1a4, 0x00000000},
+	{0x0000a1a8, 0x00000000},
+	{0x0000a1ac, 0x00000000},
+	{0x0000a1b0, 0x00000000},
+	{0x0000a1b4, 0x00000000},
+	{0x0000a1b8, 0x00000000},
+	{0x0000a1bc, 0x00000000},
+	{0x0000a1c0, 0x00000000},
+	{0x0000a1c4, 0x00000000},
+	{0x0000a1c8, 0x00000000},
+	{0x0000a1cc, 0x00000000},
+	{0x0000a1d0, 0x00000000},
+	{0x0000a1d4, 0x00000000},
+	{0x0000a1d8, 0x00000000},
+	{0x0000a1dc, 0x00000000},
+	{0x0000a1e0, 0x00000000},
+	{0x0000a1e4, 0x00000000},
+	{0x0000a1e8, 0x00000000},
+	{0x0000a1ec, 0x00000000},
+	{0x0000a1f0, 0x00000396},
+	{0x0000a1f4, 0x00000396},
+	{0x0000a1f8, 0x00000396},
+	{0x0000a1fc, 0x00000196},
+	{0x0000b000, 0x00010000},
+	{0x0000b004, 0x00030002},
+	{0x0000b008, 0x00050004},
+	{0x0000b00c, 0x00810080},
+	{0x0000b010, 0x00830082},
+	{0x0000b014, 0x01810180},
+	{0x0000b018, 0x01830182},
+	{0x0000b01c, 0x01850184},
+	{0x0000b020, 0x02810280},
+	{0x0000b024, 0x02830282},
+	{0x0000b028, 0x02850284},
+	{0x0000b02c, 0x02890288},
+	{0x0000b030, 0x028b028a},
+	{0x0000b034, 0x0388028c},
+	{0x0000b038, 0x038a0389},
+	{0x0000b03c, 0x038c038b},
+	{0x0000b040, 0x0390038d},
+	{0x0000b044, 0x03920391},
+	{0x0000b048, 0x03940393},
+	{0x0000b04c, 0x03960395},
+	{0x0000b050, 0x00000000},
+	{0x0000b054, 0x00000000},
+	{0x0000b058, 0x00000000},
+	{0x0000b05c, 0x00000000},
+	{0x0000b060, 0x00000000},
+	{0x0000b064, 0x00000000},
+	{0x0000b068, 0x00000000},
+	{0x0000b06c, 0x00000000},
+	{0x0000b070, 0x00000000},
+	{0x0000b074, 0x00000000},
+	{0x0000b078, 0x00000000},
+	{0x0000b07c, 0x00000000},
+	{0x0000b080, 0x32323232},
+	{0x0000b084, 0x2f2f3232},
+	{0x0000b088, 0x23282a2d},
+	{0x0000b08c, 0x1c1e2123},
+	{0x0000b090, 0x14171919},
+	{0x0000b094, 0x0e0e1214},
+	{0x0000b098, 0x03050707},
+	{0x0000b09c, 0x00030303},
+	{0x0000b0a0, 0x00000000},
+	{0x0000b0a4, 0x00000000},
+	{0x0000b0a8, 0x00000000},
+	{0x0000b0ac, 0x00000000},
+	{0x0000b0b0, 0x00000000},
+	{0x0000b0b4, 0x00000000},
+	{0x0000b0b8, 0x00000000},
+	{0x0000b0bc, 0x00000000},
+	{0x0000b0c0, 0x003f0020},
+	{0x0000b0c4, 0x00400041},
+	{0x0000b0c8, 0x0140005f},
+	{0x0000b0cc, 0x0160015f},
+	{0x0000b0d0, 0x017e017f},
+	{0x0000b0d4, 0x02410242},
+	{0x0000b0d8, 0x025f0240},
+	{0x0000b0dc, 0x027f0260},
+	{0x0000b0e0, 0x0341027e},
+	{0x0000b0e4, 0x035f0340},
+	{0x0000b0e8, 0x037f0360},
+	{0x0000b0ec, 0x04400441},
+	{0x0000b0f0, 0x0460045f},
+	{0x0000b0f4, 0x0541047f},
+	{0x0000b0f8, 0x055f0540},
+	{0x0000b0fc, 0x057f0560},
+	{0x0000b100, 0x06400641},
+	{0x0000b104, 0x0660065f},
+	{0x0000b108, 0x067e067f},
+	{0x0000b10c, 0x07410742},
+	{0x0000b110, 0x075f0740},
+	{0x0000b114, 0x077f0760},
+	{0x0000b118, 0x07800781},
+	{0x0000b11c, 0x07a0079f},
+	{0x0000b120, 0x07c107bf},
+	{0x0000b124, 0x000007c0},
+	{0x0000b128, 0x00000000},
+	{0x0000b12c, 0x00000000},
+	{0x0000b130, 0x00000000},
+	{0x0000b134, 0x00000000},
+	{0x0000b138, 0x00000000},
+	{0x0000b13c, 0x00000000},
+	{0x0000b140, 0x003f0020},
+	{0x0000b144, 0x00400041},
+	{0x0000b148, 0x0140005f},
+	{0x0000b14c, 0x0160015f},
+	{0x0000b150, 0x017e017f},
+	{0x0000b154, 0x02410242},
+	{0x0000b158, 0x025f0240},
+	{0x0000b15c, 0x027f0260},
+	{0x0000b160, 0x0341027e},
+	{0x0000b164, 0x035f0340},
+	{0x0000b168, 0x037f0360},
+	{0x0000b16c, 0x04400441},
+	{0x0000b170, 0x0460045f},
+	{0x0000b174, 0x0541047f},
+	{0x0000b178, 0x055f0540},
+	{0x0000b17c, 0x057f0560},
+	{0x0000b180, 0x06400641},
+	{0x0000b184, 0x0660065f},
+	{0x0000b188, 0x067e067f},
+	{0x0000b18c, 0x07410742},
+	{0x0000b190, 0x075f0740},
+	{0x0000b194, 0x077f0760},
+	{0x0000b198, 0x07800781},
+	{0x0000b19c, 0x07a0079f},
+	{0x0000b1a0, 0x07c107bf},
+	{0x0000b1a4, 0x000007c0},
+	{0x0000b1a8, 0x00000000},
+	{0x0000b1ac, 0x00000000},
+	{0x0000b1b0, 0x00000000},
+	{0x0000b1b4, 0x00000000},
+	{0x0000b1b8, 0x00000000},
+	{0x0000b1bc, 0x00000000},
+	{0x0000b1c0, 0x00000000},
+	{0x0000b1c4, 0x00000000},
+	{0x0000b1c8, 0x00000000},
+	{0x0000b1cc, 0x00000000},
+	{0x0000b1d0, 0x00000000},
+	{0x0000b1d4, 0x00000000},
+	{0x0000b1d8, 0x00000000},
+	{0x0000b1dc, 0x00000000},
+	{0x0000b1e0, 0x00000000},
+	{0x0000b1e4, 0x00000000},
+	{0x0000b1e8, 0x00000000},
+	{0x0000b1ec, 0x00000000},
+	{0x0000b1f0, 0x00000396},
+	{0x0000b1f4, 0x00000396},
+	{0x0000b1f8, 0x00000396},
+	{0x0000b1fc, 0x00000196},
+};
+
+static const u32 ar9340_1p0_soc_preamble[][2] = {
+	/*    Addr        allmodes        */
+	{0x000040a4, 0x00a0c1c9},
+	{0x00007008, 0x00000000},
+	{0x00007020, 0x00000000},
+	{0x00007034, 0x00000002},
+	{0x00007038, 0x000004c2},
+};
+
+#endif
diff -druN linux-2.6.39-libre/drivers/net/wireless/ath/ath9k/ar9485_initvals.h linux-3.0-rc7-libre/drivers/net/wireless/ath/ath9k/ar9485_initvals.h
--- linux-2.6.39-libre/drivers/net/wireless/ath/ath9k/ar9485_initvals.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/ath/ath9k/ar9485_initvals.h	2011-07-11 19:51:52.000000000 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010 Atheros Communications Inc.
+ * Copyright (c) 2010-2011 Atheros Communications Inc.
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
@@ -17,931 +17,6 @@
 #ifndef INITVALS_9485_H
 #define INITVALS_9485_H
 
-static const u32 ar9485Common_1_0[][2] = {
-	/*   Addr     allmodes */
-	{0x00007010, 0x00000022},
-	{0x00007020, 0x00000000},
-	{0x00007034, 0x00000002},
-	{0x00007038, 0x000004c2},
-};
-
-static const u32 ar9485_1_0_mac_postamble[][5] = {
-	/* Addr     5G_HT20     5G_HT40     2G_HT40     2G_HT20    */
-	{0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160},
-	{0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c},
-	{0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38},
-	{0x00008014, 0x03e803e8, 0x07d007d0, 0x10801600, 0x08400b00},
-	{0x0000801c, 0x128d8027, 0x128d804f, 0x12e00057, 0x12e0002b},
-	{0x00008120, 0x08f04800, 0x08f04800, 0x08f04810, 0x08f04810},
-	{0x000081d0, 0x00003210, 0x00003210, 0x0000320a, 0x0000320a},
-	{0x00008318, 0x00003e80, 0x00007d00, 0x00006880, 0x00003440},
-};
-
-static const u32 ar9485_1_0_pcie_phy_pll_on_clkreq_disable_L1[][2] = {
-	/*   Addr     allmodes */
-	{0x00018c00, 0x10212e5e},
-	{0x00018c04, 0x000801d8},
-	{0x00018c08, 0x0000580c},
-};
-
-static const u32 ar9485Common_wo_xlna_rx_gain_1_0[][2] = {
-	/*   Addr     allmodes */
-	{0x0000a000, 0x00010000},
-	{0x0000a004, 0x00030002},
-	{0x0000a008, 0x00050004},
-	{0x0000a00c, 0x00810080},
-	{0x0000a010, 0x01800082},
-	{0x0000a014, 0x01820181},
-	{0x0000a018, 0x01840183},
-	{0x0000a01c, 0x01880185},
-	{0x0000a020, 0x018a0189},
-	{0x0000a024, 0x02850284},
-	{0x0000a028, 0x02890288},
-	{0x0000a02c, 0x03850384},
-	{0x0000a030, 0x03890388},
-	{0x0000a034, 0x038b038a},
-	{0x0000a038, 0x038d038c},
-	{0x0000a03c, 0x03910390},
-	{0x0000a040, 0x03930392},
-	{0x0000a044, 0x03950394},
-	{0x0000a048, 0x00000396},
-	{0x0000a04c, 0x00000000},
-	{0x0000a050, 0x00000000},
-	{0x0000a054, 0x00000000},
-	{0x0000a058, 0x00000000},
-	{0x0000a05c, 0x00000000},
-	{0x0000a060, 0x00000000},
-	{0x0000a064, 0x00000000},
-	{0x0000a068, 0x00000000},
-	{0x0000a06c, 0x00000000},
-	{0x0000a070, 0x00000000},
-	{0x0000a074, 0x00000000},
-	{0x0000a078, 0x00000000},
-	{0x0000a07c, 0x00000000},
-	{0x0000a080, 0x28282828},
-	{0x0000a084, 0x28282828},
-	{0x0000a088, 0x28282828},
-	{0x0000a08c, 0x28282828},
-	{0x0000a090, 0x28282828},
-	{0x0000a094, 0x21212128},
-	{0x0000a098, 0x171c1c1c},
-	{0x0000a09c, 0x02020212},
-	{0x0000a0a0, 0x00000202},
-	{0x0000a0a4, 0x00000000},
-	{0x0000a0a8, 0x00000000},
-	{0x0000a0ac, 0x00000000},
-	{0x0000a0b0, 0x00000000},
-	{0x0000a0b4, 0x00000000},
-	{0x0000a0b8, 0x00000000},
-	{0x0000a0bc, 0x00000000},
-	{0x0000a0c0, 0x001f0000},
-	{0x0000a0c4, 0x111f1100},
-	{0x0000a0c8, 0x111d111e},
-	{0x0000a0cc, 0x111b111c},
-	{0x0000a0d0, 0x22032204},
-	{0x0000a0d4, 0x22012202},
-	{0x0000a0d8, 0x221f2200},
-	{0x0000a0dc, 0x221d221e},
-	{0x0000a0e0, 0x33013302},
-	{0x0000a0e4, 0x331f3300},
-	{0x0000a0e8, 0x4402331e},
-	{0x0000a0ec, 0x44004401},
-	{0x0000a0f0, 0x441e441f},
-	{0x0000a0f4, 0x55015502},
-	{0x0000a0f8, 0x551f5500},
-	{0x0000a0fc, 0x6602551e},
-	{0x0000a100, 0x66006601},
-	{0x0000a104, 0x661e661f},
-	{0x0000a108, 0x7703661d},
-	{0x0000a10c, 0x77017702},
-	{0x0000a110, 0x00007700},
-	{0x0000a114, 0x00000000},
-	{0x0000a118, 0x00000000},
-	{0x0000a11c, 0x00000000},
-	{0x0000a120, 0x00000000},
-	{0x0000a124, 0x00000000},
-	{0x0000a128, 0x00000000},
-	{0x0000a12c, 0x00000000},
-	{0x0000a130, 0x00000000},
-	{0x0000a134, 0x00000000},
-	{0x0000a138, 0x00000000},
-	{0x0000a13c, 0x00000000},
-	{0x0000a140, 0x001f0000},
-	{0x0000a144, 0x111f1100},
-	{0x0000a148, 0x111d111e},
-	{0x0000a14c, 0x111b111c},
-	{0x0000a150, 0x22032204},
-	{0x0000a154, 0x22012202},
-	{0x0000a158, 0x221f2200},
-	{0x0000a15c, 0x221d221e},
-	{0x0000a160, 0x33013302},
-	{0x0000a164, 0x331f3300},
-	{0x0000a168, 0x4402331e},
-	{0x0000a16c, 0x44004401},
-	{0x0000a170, 0x441e441f},
-	{0x0000a174, 0x55015502},
-	{0x0000a178, 0x551f5500},
-	{0x0000a17c, 0x6602551e},
-	{0x0000a180, 0x66006601},
-	{0x0000a184, 0x661e661f},
-	{0x0000a188, 0x7703661d},
-	{0x0000a18c, 0x77017702},
-	{0x0000a190, 0x00007700},
-	{0x0000a194, 0x00000000},
-	{0x0000a198, 0x00000000},
-	{0x0000a19c, 0x00000000},
-	{0x0000a1a0, 0x00000000},
-	{0x0000a1a4, 0x00000000},
-	{0x0000a1a8, 0x00000000},
-	{0x0000a1ac, 0x00000000},
-	{0x0000a1b0, 0x00000000},
-	{0x0000a1b4, 0x00000000},
-	{0x0000a1b8, 0x00000000},
-	{0x0000a1bc, 0x00000000},
-	{0x0000a1c0, 0x00000000},
-	{0x0000a1c4, 0x00000000},
-	{0x0000a1c8, 0x00000000},
-	{0x0000a1cc, 0x00000000},
-	{0x0000a1d0, 0x00000000},
-	{0x0000a1d4, 0x00000000},
-	{0x0000a1d8, 0x00000000},
-	{0x0000a1dc, 0x00000000},
-	{0x0000a1e0, 0x00000000},
-	{0x0000a1e4, 0x00000000},
-	{0x0000a1e8, 0x00000000},
-	{0x0000a1ec, 0x00000000},
-	{0x0000a1f0, 0x00000396},
-	{0x0000a1f4, 0x00000396},
-	{0x0000a1f8, 0x00000396},
-	{0x0000a1fc, 0x00000296},
-};
-
-static const u32 ar9485Modes_high_power_tx_gain_1_0[][5] = {
-	/*   Addr      5G_HT20     5G_HT40     2G_HT40     2G_HT20 */
-	{0x0000a410, 0x000050d9, 0x000050d9, 0x000050d8, 0x000050d8},
-	{0x0000a500, 0x00022200, 0x00022200, 0x00000000, 0x00000000},
-	{0x0000a504, 0x05062002, 0x05062002, 0x04000002, 0x04000002},
-	{0x0000a508, 0x0c002e00, 0x0c002e00, 0x08000004, 0x08000004},
-	{0x0000a50c, 0x11062202, 0x11062202, 0x0d000200, 0x0d000200},
-	{0x0000a510, 0x17022e00, 0x17022e00, 0x11000202, 0x11000202},
-	{0x0000a514, 0x1d000ec2, 0x1d000ec2, 0x15000400, 0x15000400},
-	{0x0000a518, 0x25020ec0, 0x25020ec0, 0x19000402, 0x19000402},
-	{0x0000a51c, 0x2b020ec3, 0x2b020ec3, 0x1d000404, 0x1d000404},
-	{0x0000a520, 0x2f001f04, 0x2f001f04, 0x21000603, 0x21000603},
-	{0x0000a524, 0x35001fc4, 0x35001fc4, 0x25000605, 0x25000605},
-	{0x0000a528, 0x3c022f04, 0x3c022f04, 0x2a000a03, 0x2a000a03},
-	{0x0000a52c, 0x41023e85, 0x41023e85, 0x2c000a04, 0x2c000a04},
-	{0x0000a530, 0x48023ec6, 0x48023ec6, 0x2e000a20, 0x2e000a20},
-	{0x0000a534, 0x4d023f01, 0x4d023f01, 0x34000e20, 0x34000e20},
-	{0x0000a538, 0x53023f4b, 0x53023f4b, 0x38000e22, 0x38000e22},
-	{0x0000a53c, 0x5a027f09, 0x5a027f09, 0x3c000e24, 0x3c000e24},
-	{0x0000a540, 0x5f027fc9, 0x5f027fc9, 0x40000e26, 0x40000e26},
-	{0x0000a544, 0x6502feca, 0x6502feca, 0x43001640, 0x43001640},
-	{0x0000a548, 0x6b02ff4a, 0x6b02ff4a, 0x46001660, 0x46001660},
-	{0x0000a54c, 0x7203feca, 0x7203feca, 0x49001861, 0x49001861},
-	{0x0000a550, 0x7703ff0b, 0x7703ff0b, 0x4c001a81, 0x4c001a81},
-	{0x0000a554, 0x7d06ffcb, 0x7d06ffcb, 0x4f001a83, 0x4f001a83},
-	{0x0000a558, 0x8407ff0b, 0x8407ff0b, 0x54001c85, 0x54001c85},
-	{0x0000a55c, 0x8907ffcb, 0x8907ffcb, 0x58001ce5, 0x58001ce5},
-	{0x0000a560, 0x900fff0b, 0x900fff0b, 0x5b001ce9, 0x5b001ce9},
-	{0x0000a564, 0x960fffcb, 0x960fffcb, 0x60001eeb, 0x60001eeb},
-	{0x0000a568, 0x9c1fff0b, 0x9c1fff0b, 0x60001eeb, 0x60001eeb},
-	{0x0000a56c, 0x9c1fff0b, 0x9c1fff0b, 0x60001eeb, 0x60001eeb},
-	{0x0000a570, 0x9c1fff0b, 0x9c1fff0b, 0x60001eeb, 0x60001eeb},
-	{0x0000a574, 0x9c1fff0b, 0x9c1fff0b, 0x60001eeb, 0x60001eeb},
-	{0x0000a578, 0x9c1fff0b, 0x9c1fff0b, 0x60001eeb, 0x60001eeb},
-	{0x0000a57c, 0x9c1fff0b, 0x9c1fff0b, 0x60001eeb, 0x60001eeb},
-	{0x00016044, 0x05b6b2db, 0x05b6b2db, 0x05b6b2db, 0x05b6b2db},
-};
-
-static const u32 ar9485_1_0[][2] = {
-	/*  Addr      allmodes */
-	{0x0000a580, 0x00000000},
-	{0x0000a584, 0x00000000},
-	{0x0000a588, 0x00000000},
-	{0x0000a58c, 0x00000000},
-	{0x0000a590, 0x00000000},
-	{0x0000a594, 0x00000000},
-	{0x0000a598, 0x00000000},
-	{0x0000a59c, 0x00000000},
-	{0x0000a5a0, 0x00000000},
-	{0x0000a5a4, 0x00000000},
-	{0x0000a5a8, 0x00000000},
-	{0x0000a5ac, 0x00000000},
-	{0x0000a5b0, 0x00000000},
-	{0x0000a5b4, 0x00000000},
-	{0x0000a5b8, 0x00000000},
-	{0x0000a5bc, 0x00000000},
-};
-
-static const u32 ar9485_1_0_radio_core[][2] = {
-	/*   Addr     allmodes */
-	{0x00016000, 0x36db6db6},
-	{0x00016004, 0x6db6db40},
-	{0x00016008, 0x73800000},
-	{0x0001600c, 0x00000000},
-	{0x00016040, 0x7f80fff8},
-	{0x00016048, 0x6c92426e},
-	{0x0001604c, 0x000f0278},
-	{0x00016050, 0x6db6db6c},
-	{0x00016054, 0x6db60000},
-	{0x00016080, 0x00080000},
-	{0x00016084, 0x0e48048c},
-	{0x00016088, 0x14214514},
-	{0x0001608c, 0x119f081e},
-	{0x00016090, 0x24926490},
-	{0x00016098, 0xd28b3330},
-	{0x000160a0, 0xc2108ffe},
-	{0x000160a4, 0x812fc370},
-	{0x000160a8, 0x423c8000},
-	{0x000160b4, 0x92480040},
-	{0x000160c0, 0x006db6db},
-	{0x000160c4, 0x0186db60},
-	{0x000160c8, 0x6db6db6c},
-	{0x000160cc, 0x6de6fbe0},
-	{0x000160d0, 0xf7dfcf3c},
-	{0x00016100, 0x04cb0001},
-	{0x00016104, 0xfff80015},
-	{0x00016108, 0x00080010},
-	{0x00016144, 0x01884080},
-	{0x00016148, 0x00008040},
-	{0x00016180, 0x08453333},
-	{0x00016184, 0x18e82f01},
-	{0x00016188, 0x00000000},
-	{0x0001618c, 0x00000000},
-	{0x00016240, 0x08400000},
-	{0x00016244, 0x1bf90f00},
-	{0x00016248, 0x00000000},
-	{0x0001624c, 0x00000000},
-	{0x00016280, 0x01000015},
-	{0x00016284, 0x00d30000},
-	{0x00016288, 0x00318000},
-	{0x0001628c, 0x50000000},
-	{0x00016290, 0x4b96210f},
-	{0x00016380, 0x00000000},
-	{0x00016384, 0x00000000},
-	{0x00016388, 0x00800700},
-	{0x0001638c, 0x00800700},
-	{0x00016390, 0x00800700},
-	{0x00016394, 0x00000000},
-	{0x00016398, 0x00000000},
-	{0x0001639c, 0x00000000},
-	{0x000163a0, 0x00000001},
-	{0x000163a4, 0x00000001},
-	{0x000163a8, 0x00000000},
-	{0x000163ac, 0x00000000},
-	{0x000163b0, 0x00000000},
-	{0x000163b4, 0x00000000},
-	{0x000163b8, 0x00000000},
-	{0x000163bc, 0x00000000},
-	{0x000163c0, 0x000000a0},
-	{0x000163c4, 0x000c0000},
-	{0x000163c8, 0x14021402},
-	{0x000163cc, 0x00001402},
-	{0x000163d0, 0x00000000},
-	{0x000163d4, 0x00000000},
-	{0x00016c40, 0x1319c178},
-	{0x00016c44, 0x10000000},
-};
-
-static const u32 ar9485Modes_lowest_ob_db_tx_gain_1_0[][5] = {
-	/*  Addr       5G_HT20     5G_HT40     2G_HT40     2G_HT20 */
-	{0x0000a410, 0x000050d9, 0x000050d9, 0x000050d8, 0x000050d8},
-	{0x0000a500, 0x00022200, 0x00022200, 0x00000000, 0x00000000},
-	{0x0000a504, 0x05062002, 0x05062002, 0x04000002, 0x04000002},
-	{0x0000a508, 0x0c002e00, 0x0c002e00, 0x08000004, 0x08000004},
-	{0x0000a50c, 0x11062202, 0x11062202, 0x0d000200, 0x0d000200},
-	{0x0000a510, 0x17022e00, 0x17022e00, 0x11000202, 0x11000202},
-	{0x0000a514, 0x1d000ec2, 0x1d000ec2, 0x15000400, 0x15000400},
-	{0x0000a518, 0x25020ec0, 0x25020ec0, 0x19000402, 0x19000402},
-	{0x0000a51c, 0x2b020ec3, 0x2b020ec3, 0x1d000404, 0x1d000404},
-	{0x0000a520, 0x2f001f04, 0x2f001f04, 0x21000603, 0x21000603},
-	{0x0000a524, 0x35001fc4, 0x35001fc4, 0x25000605, 0x25000605},
-	{0x0000a528, 0x3c022f04, 0x3c022f04, 0x2a000a03, 0x2a000a03},
-	{0x0000a52c, 0x41023e85, 0x41023e85, 0x2c000a04, 0x2c000a04},
-	{0x0000a530, 0x48023ec6, 0x48023ec6, 0x2e000a20, 0x2e000a20},
-	{0x0000a534, 0x4d023f01, 0x4d023f01, 0x34000e20, 0x34000e20},
-	{0x0000a538, 0x53023f4b, 0x53023f4b, 0x38000e22, 0x38000e22},
-	{0x0000a53c, 0x5a027f09, 0x5a027f09, 0x3c000e24, 0x3c000e24},
-	{0x0000a540, 0x5f027fc9, 0x5f027fc9, 0x40000e26, 0x40000e26},
-	{0x0000a544, 0x6502feca, 0x6502feca, 0x43001640, 0x43001640},
-	{0x0000a548, 0x6b02ff4a, 0x6b02ff4a, 0x46001660, 0x46001660},
-	{0x0000a54c, 0x7203feca, 0x7203feca, 0x49001861, 0x49001861},
-	{0x0000a550, 0x7703ff0b, 0x7703ff0b, 0x4c001a81, 0x4c001a81},
-	{0x0000a554, 0x7d06ffcb, 0x7d06ffcb, 0x4f001a83, 0x4f001a83},
-	{0x0000a558, 0x8407ff0b, 0x8407ff0b, 0x54001c85, 0x54001c85},
-	{0x0000a55c, 0x8907ffcb, 0x8907ffcb, 0x58001ce5, 0x58001ce5},
-	{0x0000a560, 0x900fff0b, 0x900fff0b, 0x5b001ce9, 0x5b001ce9},
-	{0x0000a564, 0x960fffcb, 0x960fffcb, 0x60001eeb, 0x60001eeb},
-	{0x0000a568, 0x9c1fff0b, 0x9c1fff0b, 0x60001eeb, 0x60001eeb},
-	{0x0000a56c, 0x9c1fff0b, 0x9c1fff0b, 0x60001eeb, 0x60001eeb},
-	{0x0000a570, 0x9c1fff0b, 0x9c1fff0b, 0x60001eeb, 0x60001eeb},
-	{0x0000a574, 0x9c1fff0b, 0x9c1fff0b, 0x60001eeb, 0x60001eeb},
-	{0x0000a578, 0x9c1fff0b, 0x9c1fff0b, 0x60001eeb, 0x60001eeb},
-	{0x0000a57c, 0x9c1fff0b, 0x9c1fff0b, 0x60001eeb, 0x60001eeb},
-	{0x00016044, 0x05b6b2db, 0x05b6b2db, 0x05b6b2db, 0x05b6b2db},
-};
-
-static const u32 ar9485_1_0_baseband_core[][2] = {
-	/* Addr      allmodes  */
-	{0x00009800, 0xafe68e30},
-	{0x00009804, 0xfd14e000},
-	{0x00009808, 0x9c0a8f6b},
-	{0x0000980c, 0x04800000},
-	{0x00009814, 0x9280c00a},
-	{0x00009818, 0x00000000},
-	{0x0000981c, 0x00020028},
-	{0x00009834, 0x5f3ca3de},
-	{0x00009838, 0x0108ecff},
-	{0x0000983c, 0x14750600},
-	{0x00009880, 0x201fff00},
-	{0x00009884, 0x00001042},
-	{0x000098a4, 0x00200400},
-	{0x000098b0, 0x52440bbe},
-	{0x000098bc, 0x00000002},
-	{0x000098d0, 0x004b6a8e},
-	{0x000098d4, 0x00000820},
-	{0x000098dc, 0x00000000},
-	{0x000098f0, 0x00000000},
-	{0x000098f4, 0x00000000},
-	{0x00009c04, 0x00000000},
-	{0x00009c08, 0x03200000},
-	{0x00009c0c, 0x00000000},
-	{0x00009c10, 0x00000000},
-	{0x00009c14, 0x00046384},
-	{0x00009c18, 0x05b6b440},
-	{0x00009c1c, 0x00b6b440},
-	{0x00009d00, 0xc080a333},
-	{0x00009d04, 0x40206c10},
-	{0x00009d08, 0x009c4060},
-	{0x00009d0c, 0x1883800a},
-	{0x00009d10, 0x01834061},
-	{0x00009d14, 0x00c00400},
-	{0x00009d18, 0x00000000},
-	{0x00009d1c, 0x00000000},
-	{0x00009e08, 0x0038233c},
-	{0x00009e24, 0x990bb515},
-	{0x00009e28, 0x0a6f0000},
-	{0x00009e30, 0x06336f77},
-	{0x00009e34, 0x6af6532f},
-	{0x00009e38, 0x0cc80c00},
-	{0x00009e40, 0x0d261820},
-	{0x00009e4c, 0x00001004},
-	{0x00009e50, 0x00ff03f1},
-	{0x00009fc0, 0x80be4788},
-	{0x00009fc4, 0x0001efb5},
-	{0x00009fcc, 0x40000014},
-	{0x0000a20c, 0x00000000},
-	{0x0000a210, 0x00000000},
-	{0x0000a220, 0x00000000},
-	{0x0000a224, 0x00000000},
-	{0x0000a228, 0x10002310},
-	{0x0000a23c, 0x00000000},
-	{0x0000a244, 0x0c000000},
-	{0x0000a2a0, 0x00000001},
-	{0x0000a2c0, 0x00000001},
-	{0x0000a2c8, 0x00000000},
-	{0x0000a2cc, 0x18c43433},
-	{0x0000a2d4, 0x00000000},
-	{0x0000a2dc, 0x00000000},
-	{0x0000a2e0, 0x00000000},
-	{0x0000a2e4, 0x00000000},
-	{0x0000a2e8, 0x00000000},
-	{0x0000a2ec, 0x00000000},
-	{0x0000a2f0, 0x00000000},
-	{0x0000a2f4, 0x00000000},
-	{0x0000a2f8, 0x00000000},
-	{0x0000a344, 0x00000000},
-	{0x0000a34c, 0x00000000},
-	{0x0000a350, 0x0000a000},
-	{0x0000a364, 0x00000000},
-	{0x0000a370, 0x00000000},
-	{0x0000a390, 0x00000001},
-	{0x0000a394, 0x00000444},
-	{0x0000a398, 0x001f0e0f},
-	{0x0000a39c, 0x0075393f},
-	{0x0000a3a0, 0xb79f6427},
-	{0x0000a3a4, 0x00000000},
-	{0x0000a3a8, 0xaaaaaaaa},
-	{0x0000a3ac, 0x3c466478},
-	{0x0000a3c0, 0x20202020},
-	{0x0000a3c4, 0x22222220},
-	{0x0000a3c8, 0x20200020},
-	{0x0000a3cc, 0x20202020},
-	{0x0000a3d0, 0x20202020},
-	{0x0000a3d4, 0x20202020},
-	{0x0000a3d8, 0x20202020},
-	{0x0000a3dc, 0x20202020},
-	{0x0000a3e0, 0x20202020},
-	{0x0000a3e4, 0x20202020},
-	{0x0000a3e8, 0x20202020},
-	{0x0000a3ec, 0x20202020},
-	{0x0000a3f0, 0x00000000},
-	{0x0000a3f4, 0x00000006},
-	{0x0000a3f8, 0x0cdbd380},
-	{0x0000a3fc, 0x000f0f01},
-	{0x0000a400, 0x8fa91f01},
-	{0x0000a404, 0x00000000},
-	{0x0000a408, 0x0e79e5c6},
-	{0x0000a40c, 0x00820820},
-	{0x0000a414, 0x1ce739ce},
-	{0x0000a418, 0x2d0011ce},
-	{0x0000a41c, 0x1ce739ce},
-	{0x0000a420, 0x000001ce},
-	{0x0000a424, 0x1ce739ce},
-	{0x0000a428, 0x000001ce},
-	{0x0000a42c, 0x1ce739ce},
-	{0x0000a430, 0x1ce739ce},
-	{0x0000a434, 0x00000000},
-	{0x0000a438, 0x00001801},
-	{0x0000a43c, 0x00000000},
-	{0x0000a440, 0x00000000},
-	{0x0000a444, 0x00000000},
-	{0x0000a448, 0x04000000},
-	{0x0000a44c, 0x00000001},
-	{0x0000a450, 0x00010000},
-	{0x0000a458, 0x00000000},
-	{0x0000a5c4, 0x3fad9d74},
-	{0x0000a5c8, 0x0048060a},
-	{0x0000a5cc, 0x00000637},
-	{0x0000a760, 0x03020100},
-	{0x0000a764, 0x09080504},
-	{0x0000a768, 0x0d0c0b0a},
-	{0x0000a76c, 0x13121110},
-	{0x0000a770, 0x31301514},
-	{0x0000a774, 0x35343332},
-	{0x0000a778, 0x00000036},
-	{0x0000a780, 0x00000838},
-	{0x0000a7c0, 0x00000000},
-	{0x0000a7c4, 0xfffffffc},
-	{0x0000a7c8, 0x00000000},
-	{0x0000a7cc, 0x00000000},
-	{0x0000a7d0, 0x00000000},
-	{0x0000a7d4, 0x00000004},
-	{0x0000a7dc, 0x00000001},
-};
-
-static const u32 ar9485Modes_high_ob_db_tx_gain_1_0[][5] = {
-	/* Addr        5G_HT20     5G_HT40     2G_HT40    2G_HT20  */
-	{0x0000a410, 0x000050d9, 0x000050d9, 0x000050d8, 0x000050d8},
-	{0x0000a500, 0x00022200, 0x00022200, 0x00000000, 0x00000000},
-	{0x0000a504, 0x05062002, 0x05062002, 0x04000002, 0x04000002},
-	{0x0000a508, 0x0c002e00, 0x0c002e00, 0x08000004, 0x08000004},
-	{0x0000a50c, 0x11062202, 0x11062202, 0x0d000200, 0x0d000200},
-	{0x0000a510, 0x17022e00, 0x17022e00, 0x11000202, 0x11000202},
-	{0x0000a514, 0x1d000ec2, 0x1d000ec2, 0x15000400, 0x15000400},
-	{0x0000a518, 0x25020ec0, 0x25020ec0, 0x19000402, 0x19000402},
-	{0x0000a51c, 0x2b020ec3, 0x2b020ec3, 0x1d000404, 0x1d000404},
-	{0x0000a520, 0x2f001f04, 0x2f001f04, 0x21000603, 0x21000603},
-	{0x0000a524, 0x35001fc4, 0x35001fc4, 0x25000605, 0x25000605},
-	{0x0000a528, 0x3c022f04, 0x3c022f04, 0x2a000a03, 0x2a000a03},
-	{0x0000a52c, 0x41023e85, 0x41023e85, 0x2c000a04, 0x2c000a04},
-	{0x0000a530, 0x48023ec6, 0x48023ec6, 0x2e000a20, 0x2e000a20},
-	{0x0000a534, 0x4d023f01, 0x4d023f01, 0x34000e20, 0x34000e20},
-	{0x0000a538, 0x53023f4b, 0x53023f4b, 0x38000e22, 0x38000e22},
-	{0x0000a53c, 0x5a027f09, 0x5a027f09, 0x3c000e24, 0x3c000e24},
-	{0x0000a540, 0x5f027fc9, 0x5f027fc9, 0x40000e26, 0x40000e26},
-	{0x0000a544, 0x6502feca, 0x6502feca, 0x43001640, 0x43001640},
-	{0x0000a548, 0x6b02ff4a, 0x6b02ff4a, 0x46001660, 0x46001660},
-	{0x0000a54c, 0x7203feca, 0x7203feca, 0x49001861, 0x49001861},
-	{0x0000a550, 0x7703ff0b, 0x7703ff0b, 0x4c001a81, 0x4c001a81},
-	{0x0000a554, 0x7d06ffcb, 0x7d06ffcb, 0x4f001a83, 0x4f001a83},
-	{0x0000a558, 0x8407ff0b, 0x8407ff0b, 0x54001c85, 0x54001c85},
-	{0x0000a55c, 0x8907ffcb, 0x8907ffcb, 0x58001ce5, 0x58001ce5},
-	{0x0000a560, 0x900fff0b, 0x900fff0b, 0x5b001ce9, 0x5b001ce9},
-	{0x0000a564, 0x960fffcb, 0x960fffcb, 0x60001eeb, 0x60001eeb},
-	{0x0000a568, 0x9c1fff0b, 0x9c1fff0b, 0x60001eeb, 0x60001eeb},
-	{0x0000a56c, 0x9c1fff0b, 0x9c1fff0b, 0x60001eeb, 0x60001eeb},
-	{0x0000a570, 0x9c1fff0b, 0x9c1fff0b, 0x60001eeb, 0x60001eeb},
-	{0x0000a574, 0x9c1fff0b, 0x9c1fff0b, 0x60001eeb, 0x60001eeb},
-	{0x0000a578, 0x9c1fff0b, 0x9c1fff0b, 0x60001eeb, 0x60001eeb},
-	{0x0000a57c, 0x9c1fff0b, 0x9c1fff0b, 0x60001eeb, 0x60001eeb},
-	{0x00016044, 0x05b6b2db, 0x05b6b2db, 0x05b6b2db, 0x05b6b2db},
-};
-
-static const u32 ar9485Common_rx_gain_1_0[][2] = {
-	/* Addr      allmodes  */
-	{0x0000a000, 0x00010000},
-	{0x0000a004, 0x00030002},
-	{0x0000a008, 0x00050004},
-	{0x0000a00c, 0x00810080},
-	{0x0000a010, 0x01800082},
-	{0x0000a014, 0x01820181},
-	{0x0000a018, 0x01840183},
-	{0x0000a01c, 0x01880185},
-	{0x0000a020, 0x018a0189},
-	{0x0000a024, 0x02850284},
-	{0x0000a028, 0x02890288},
-	{0x0000a02c, 0x03850384},
-	{0x0000a030, 0x03890388},
-	{0x0000a034, 0x038b038a},
-	{0x0000a038, 0x038d038c},
-	{0x0000a03c, 0x03910390},
-	{0x0000a040, 0x03930392},
-	{0x0000a044, 0x03950394},
-	{0x0000a048, 0x00000396},
-	{0x0000a04c, 0x00000000},
-	{0x0000a050, 0x00000000},
-	{0x0000a054, 0x00000000},
-	{0x0000a058, 0x00000000},
-	{0x0000a05c, 0x00000000},
-	{0x0000a060, 0x00000000},
-	{0x0000a064, 0x00000000},
-	{0x0000a068, 0x00000000},
-	{0x0000a06c, 0x00000000},
-	{0x0000a070, 0x00000000},
-	{0x0000a074, 0x00000000},
-	{0x0000a078, 0x00000000},
-	{0x0000a07c, 0x00000000},
-	{0x0000a080, 0x28282828},
-	{0x0000a084, 0x28282828},
-	{0x0000a088, 0x28282828},
-	{0x0000a08c, 0x28282828},
-	{0x0000a090, 0x28282828},
-	{0x0000a094, 0x21212128},
-	{0x0000a098, 0x171c1c1c},
-	{0x0000a09c, 0x02020212},
-	{0x0000a0a0, 0x00000202},
-	{0x0000a0a4, 0x00000000},
-	{0x0000a0a8, 0x00000000},
-	{0x0000a0ac, 0x00000000},
-	{0x0000a0b0, 0x00000000},
-	{0x0000a0b4, 0x00000000},
-	{0x0000a0b8, 0x00000000},
-	{0x0000a0bc, 0x00000000},
-	{0x0000a0c0, 0x001f0000},
-	{0x0000a0c4, 0x111f1100},
-	{0x0000a0c8, 0x111d111e},
-	{0x0000a0cc, 0x111b111c},
-	{0x0000a0d0, 0x22032204},
-	{0x0000a0d4, 0x22012202},
-	{0x0000a0d8, 0x221f2200},
-	{0x0000a0dc, 0x221d221e},
-	{0x0000a0e0, 0x33013302},
-	{0x0000a0e4, 0x331f3300},
-	{0x0000a0e8, 0x4402331e},
-	{0x0000a0ec, 0x44004401},
-	{0x0000a0f0, 0x441e441f},
-	{0x0000a0f4, 0x55015502},
-	{0x0000a0f8, 0x551f5500},
-	{0x0000a0fc, 0x6602551e},
-	{0x0000a100, 0x66006601},
-	{0x0000a104, 0x661e661f},
-	{0x0000a108, 0x7703661d},
-	{0x0000a10c, 0x77017702},
-	{0x0000a110, 0x00007700},
-	{0x0000a114, 0x00000000},
-	{0x0000a118, 0x00000000},
-	{0x0000a11c, 0x00000000},
-	{0x0000a120, 0x00000000},
-	{0x0000a124, 0x00000000},
-	{0x0000a128, 0x00000000},
-	{0x0000a12c, 0x00000000},
-	{0x0000a130, 0x00000000},
-	{0x0000a134, 0x00000000},
-	{0x0000a138, 0x00000000},
-	{0x0000a13c, 0x00000000},
-	{0x0000a140, 0x001f0000},
-	{0x0000a144, 0x111f1100},
-	{0x0000a148, 0x111d111e},
-	{0x0000a14c, 0x111b111c},
-	{0x0000a150, 0x22032204},
-	{0x0000a154, 0x22012202},
-	{0x0000a158, 0x221f2200},
-	{0x0000a15c, 0x221d221e},
-	{0x0000a160, 0x33013302},
-	{0x0000a164, 0x331f3300},
-	{0x0000a168, 0x4402331e},
-	{0x0000a16c, 0x44004401},
-	{0x0000a170, 0x441e441f},
-	{0x0000a174, 0x55015502},
-	{0x0000a178, 0x551f5500},
-	{0x0000a17c, 0x6602551e},
-	{0x0000a180, 0x66006601},
-	{0x0000a184, 0x661e661f},
-	{0x0000a188, 0x7703661d},
-	{0x0000a18c, 0x77017702},
-	{0x0000a190, 0x00007700},
-	{0x0000a194, 0x00000000},
-	{0x0000a198, 0x00000000},
-	{0x0000a19c, 0x00000000},
-	{0x0000a1a0, 0x00000000},
-	{0x0000a1a4, 0x00000000},
-	{0x0000a1a8, 0x00000000},
-	{0x0000a1ac, 0x00000000},
-	{0x0000a1b0, 0x00000000},
-	{0x0000a1b4, 0x00000000},
-	{0x0000a1b8, 0x00000000},
-	{0x0000a1bc, 0x00000000},
-	{0x0000a1c0, 0x00000000},
-	{0x0000a1c4, 0x00000000},
-	{0x0000a1c8, 0x00000000},
-	{0x0000a1cc, 0x00000000},
-	{0x0000a1d0, 0x00000000},
-	{0x0000a1d4, 0x00000000},
-	{0x0000a1d8, 0x00000000},
-	{0x0000a1dc, 0x00000000},
-	{0x0000a1e0, 0x00000000},
-	{0x0000a1e4, 0x00000000},
-	{0x0000a1e8, 0x00000000},
-	{0x0000a1ec, 0x00000000},
-	{0x0000a1f0, 0x00000396},
-	{0x0000a1f4, 0x00000396},
-	{0x0000a1f8, 0x00000396},
-	{0x0000a1fc, 0x00000296},
-};
-
-static const u32 ar9485_1_0_pcie_phy_pll_on_clkreq_enable_L1[][2] = {
-	/*   Addr    allmodes  */
-	{0x00018c00, 0x10252e5e},
-	{0x00018c04, 0x000801d8},
-	{0x00018c08, 0x0000580c},
-};
-
-static const u32 ar9485_1_0_pcie_phy_clkreq_enable_L1[][2] = {
-	/*  Addr    allmodes   */
-	{0x00018c00, 0x10253e5e},
-	{0x00018c04, 0x000801d8},
-	{0x00018c08, 0x0000580c},
-};
-
-static const u32 ar9485_1_0_soc_preamble[][2] = {
-	/*   Addr     allmodes */
-	{0x00004090, 0x00aa10aa},
-	{0x000040a4, 0x00a0c9c9},
-	{0x00007048, 0x00000004},
-};
-
-static const u32 ar9485_fast_clock_1_0_baseband_postamble[][3] = {
-	/*   Addr      5G_HT20     5G_HT40 */
-	{0x00009e00, 0x03721821, 0x03721821},
-	{0x0000a230, 0x0000400b, 0x00004016},
-	{0x0000a254, 0x00000898, 0x00001130},
-};
-
-static const u32 ar9485_1_0_baseband_postamble[][5] = {
-	/* Addr        5G_HT20     5G_HT40     2G_HT40     2G_HT20 */
-	{0x00009810, 0xd00a8005, 0xd00a8005, 0xd00a8005, 0xd00a8005},
-	{0x00009820, 0x206a002e, 0x206a002e, 0x206a002e, 0x206a002e},
-	{0x00009824, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0},
-	{0x00009828, 0x06903081, 0x06903081, 0x06903881, 0x06903881},
-	{0x0000982c, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4},
-	{0x00009830, 0x0000059c, 0x0000059c, 0x0000059c, 0x0000059c},
-	{0x00009c00, 0x00000044, 0x00000044, 0x00000044, 0x00000044},
-	{0x00009e00, 0x0372161e, 0x0372161e, 0x037216a0, 0x037216a0},
-	{0x00009e04, 0x00182020, 0x00182020, 0x00182020, 0x00182020},
-	{0x00009e0c, 0x6c4000e2, 0x6d4000e2, 0x6d4000e2, 0x6c4000e2},
-	{0x00009e10, 0x7ec88d2e, 0x7ec88d2e, 0x7ec80d2e, 0x7ec80d2e},
-	{0x00009e14, 0x31395d5e, 0x3139605e, 0x3139605e, 0x31395d5e},
-	{0x00009e18, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
-	{0x00009e1c, 0x0001cf9c, 0x0001cf9c, 0x00021f9c, 0x00021f9c},
-	{0x00009e20, 0x000003b5, 0x000003b5, 0x000003ce, 0x000003ce},
-	{0x00009e2c, 0x0000001c, 0x0000001c, 0x00000021, 0x00000021},
-	{0x00009e3c, 0xcf946220, 0xcf946220, 0xcf946222, 0xcf946222},
-	{0x00009e44, 0x02321e27, 0x02321e27, 0x02282324, 0x02282324},
-	{0x00009e48, 0x5030201a, 0x5030201a, 0x50302010, 0x50302010},
-	{0x00009fc8, 0x0003f000, 0x0003f000, 0x0001a000, 0x0001a000},
-	{0x0000a204, 0x01303fc0, 0x01303fc4, 0x01303fc4, 0x01303fc0},
-	{0x0000a208, 0x00000104, 0x00000104, 0x00000004, 0x00000004},
-	{0x0000a230, 0x0000400a, 0x00004014, 0x00004016, 0x0000400b},
-	{0x0000a234, 0x10000fff, 0x10000fff, 0x10000fff, 0x10000fff},
-	{0x0000a238, 0xffb81018, 0xffb81018, 0xffb81018, 0xffb81018},
-	{0x0000a250, 0x00000000, 0x00000000, 0x00000210, 0x00000108},
-	{0x0000a254, 0x000007d0, 0x00000fa0, 0x00001130, 0x00000898},
-	{0x0000a258, 0x02020002, 0x02020002, 0x02020002, 0x02020002},
-	{0x0000a25c, 0x01000e0e, 0x01000e0e, 0x01000e0e, 0x01000e0e},
-	{0x0000a260, 0x3a021501, 0x3a021501, 0x3a021501, 0x3a021501},
-	{0x0000a264, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e},
-	{0x0000a280, 0x00000007, 0x00000007, 0x0000000b, 0x0000000b},
-	{0x0000a284, 0x00000000, 0x00000000, 0x000002a0, 0x000002a0},
-	{0x0000a288, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
-	{0x0000a28c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
-	{0x0000a2c4, 0x00158d18, 0x00158d18, 0x00158d18, 0x00158d18},
-	{0x0000a2d0, 0x00071981, 0x00071981, 0x00071981, 0x00071982},
-	{0x0000a2d8, 0xf999a83a, 0xf999a83a, 0xf999a83a, 0xf999a83a},
-	{0x0000a358, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
-	{0x0000be04, 0x00802020, 0x00802020, 0x00802020, 0x00802020},
-	{0x0000be18, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
-};
-
-static const u32 ar9485Modes_low_ob_db_tx_gain_1_0[][5] = {
-	/*  Addr      5G_HT20    5G_HT40     2G_HT40     2G_HT20   */
-	{0x0000a410, 0x000050d9, 0x000050d9, 0x000050d8, 0x000050d8},
-	{0x0000a500, 0x00022200, 0x00022200, 0x00000000, 0x00000000},
-	{0x0000a504, 0x05062002, 0x05062002, 0x04000002, 0x04000002},
-	{0x0000a508, 0x0c002e00, 0x0c002e00, 0x08000004, 0x08000004},
-	{0x0000a50c, 0x11062202, 0x11062202, 0x0d000200, 0x0d000200},
-	{0x0000a510, 0x17022e00, 0x17022e00, 0x11000202, 0x11000202},
-	{0x0000a514, 0x1d000ec2, 0x1d000ec2, 0x15000400, 0x15000400},
-	{0x0000a518, 0x25020ec0, 0x25020ec0, 0x19000402, 0x19000402},
-	{0x0000a51c, 0x2b020ec3, 0x2b020ec3, 0x1d000404, 0x1d000404},
-	{0x0000a520, 0x2f001f04, 0x2f001f04, 0x21000603, 0x21000603},
-	{0x0000a524, 0x35001fc4, 0x35001fc4, 0x25000605, 0x25000605},
-	{0x0000a528, 0x3c022f04, 0x3c022f04, 0x2a000a03, 0x2a000a03},
-	{0x0000a52c, 0x41023e85, 0x41023e85, 0x2c000a04, 0x2c000a04},
-	{0x0000a530, 0x48023ec6, 0x48023ec6, 0x2e000a20, 0x2e000a20},
-	{0x0000a534, 0x4d023f01, 0x4d023f01, 0x34000e20, 0x34000e20},
-	{0x0000a538, 0x53023f4b, 0x53023f4b, 0x38000e22, 0x38000e22},
-	{0x0000a53c, 0x5a027f09, 0x5a027f09, 0x3c000e24, 0x3c000e24},
-	{0x0000a540, 0x5f027fc9, 0x5f027fc9, 0x40000e26, 0x40000e26},
-	{0x0000a544, 0x6502feca, 0x6502feca, 0x43001640, 0x43001640},
-	{0x0000a548, 0x6b02ff4a, 0x6b02ff4a, 0x46001660, 0x46001660},
-	{0x0000a54c, 0x7203feca, 0x7203feca, 0x49001861, 0x49001861},
-	{0x0000a550, 0x7703ff0b, 0x7703ff0b, 0x4c001a81, 0x4c001a81},
-	{0x0000a554, 0x7d06ffcb, 0x7d06ffcb, 0x4f001a83, 0x4f001a83},
-	{0x0000a558, 0x8407ff0b, 0x8407ff0b, 0x54001c85, 0x54001c85},
-	{0x0000a55c, 0x8907ffcb, 0x8907ffcb, 0x58001ce5, 0x58001ce5},
-	{0x0000a560, 0x900fff0b, 0x900fff0b, 0x5b001ce9, 0x5b001ce9},
-	{0x0000a564, 0x960fffcb, 0x960fffcb, 0x60001eeb, 0x60001eeb},
-	{0x0000a568, 0x9c1fff0b, 0x9c1fff0b, 0x60001eeb, 0x60001eeb},
-	{0x0000a56c, 0x9c1fff0b, 0x9c1fff0b, 0x60001eeb, 0x60001eeb},
-	{0x0000a570, 0x9c1fff0b, 0x9c1fff0b, 0x60001eeb, 0x60001eeb},
-	{0x0000a574, 0x9c1fff0b, 0x9c1fff0b, 0x60001eeb, 0x60001eeb},
-	{0x0000a578, 0x9c1fff0b, 0x9c1fff0b, 0x60001eeb, 0x60001eeb},
-	{0x0000a57c, 0x9c1fff0b, 0x9c1fff0b, 0x60001eeb, 0x60001eeb},
-	{0x00016044, 0x05b6b2db, 0x05b6b2db, 0x05b6b2db, 0x05b6b2db},
-};
-
-static const u32 ar9485_1_0_pcie_phy_clkreq_disable_L1[][2] = {
-	/*   Addr     allmodes */
-	{0x00018c00, 0x10213e5e},
-	{0x00018c04, 0x000801d8},
-	{0x00018c08, 0x0000580c},
-};
-
-static const u32 ar9485_1_0_radio_postamble[][2] = {
-	/*   Addr     allmodes */
-	{0x0001609c, 0x0b283f31},
-	{0x000160ac, 0x24611800},
-	{0x000160b0, 0x03284f3e},
-	{0x0001610c, 0x00170000},
-	{0x00016140, 0x10804008},
-};
-
-static const u32 ar9485_1_0_mac_core[][2] = {
-	/*  Addr      allmodes */
-	{0x00000008, 0x00000000},
-	{0x00000030, 0x00020085},
-	{0x00000034, 0x00000005},
-	{0x00000040, 0x00000000},
-	{0x00000044, 0x00000000},
-	{0x00000048, 0x00000008},
-	{0x0000004c, 0x00000010},
-	{0x00000050, 0x00000000},
-	{0x00001040, 0x002ffc0f},
-	{0x00001044, 0x002ffc0f},
-	{0x00001048, 0x002ffc0f},
-	{0x0000104c, 0x002ffc0f},
-	{0x00001050, 0x002ffc0f},
-	{0x00001054, 0x002ffc0f},
-	{0x00001058, 0x002ffc0f},
-	{0x0000105c, 0x002ffc0f},
-	{0x00001060, 0x002ffc0f},
-	{0x00001064, 0x002ffc0f},
-	{0x000010f0, 0x00000100},
-	{0x00001270, 0x00000000},
-	{0x000012b0, 0x00000000},
-	{0x000012f0, 0x00000000},
-	{0x0000143c, 0x00000000},
-	{0x0000147c, 0x00000000},
-	{0x00008000, 0x00000000},
-	{0x00008004, 0x00000000},
-	{0x00008008, 0x00000000},
-	{0x0000800c, 0x00000000},
-	{0x00008018, 0x00000000},
-	{0x00008020, 0x00000000},
-	{0x00008038, 0x00000000},
-	{0x0000803c, 0x00000000},
-	{0x00008040, 0x00000000},
-	{0x00008044, 0x00000000},
-	{0x00008048, 0x00000000},
-	{0x0000804c, 0xffffffff},
-	{0x00008054, 0x00000000},
-	{0x00008058, 0x00000000},
-	{0x0000805c, 0x000fc78f},
-	{0x00008060, 0x0000000f},
-	{0x00008064, 0x00000000},
-	{0x00008070, 0x00000310},
-	{0x00008074, 0x00000020},
-	{0x00008078, 0x00000000},
-	{0x0000809c, 0x0000000f},
-	{0x000080a0, 0x00000000},
-	{0x000080a4, 0x02ff0000},
-	{0x000080a8, 0x0e070605},
-	{0x000080ac, 0x0000000d},
-	{0x000080b0, 0x00000000},
-	{0x000080b4, 0x00000000},
-	{0x000080b8, 0x00000000},
-	{0x000080bc, 0x00000000},
-	{0x000080c0, 0x2a800000},
-	{0x000080c4, 0x06900168},
-	{0x000080c8, 0x13881c20},
-	{0x000080cc, 0x01f40000},
-	{0x000080d0, 0x00252500},
-	{0x000080d4, 0x00a00000},
-	{0x000080d8, 0x00400000},
-	{0x000080dc, 0x00000000},
-	{0x000080e0, 0xffffffff},
-	{0x000080e4, 0x0000ffff},
-	{0x000080e8, 0x3f3f3f3f},
-	{0x000080ec, 0x00000000},
-	{0x000080f0, 0x00000000},
-	{0x000080f4, 0x00000000},
-	{0x000080fc, 0x00020000},
-	{0x00008100, 0x00000000},
-	{0x00008108, 0x00000052},
-	{0x0000810c, 0x00000000},
-	{0x00008110, 0x00000000},
-	{0x00008114, 0x000007ff},
-	{0x00008118, 0x000000aa},
-	{0x0000811c, 0x00003210},
-	{0x00008124, 0x00000000},
-	{0x00008128, 0x00000000},
-	{0x0000812c, 0x00000000},
-	{0x00008130, 0x00000000},
-	{0x00008134, 0x00000000},
-	{0x00008138, 0x00000000},
-	{0x0000813c, 0x0000ffff},
-	{0x00008144, 0xffffffff},
-	{0x00008168, 0x00000000},
-	{0x0000816c, 0x00000000},
-	{0x00008170, 0x18486200},
-	{0x00008174, 0x33332210},
-	{0x00008178, 0x00000000},
-	{0x0000817c, 0x00020000},
-	{0x000081c0, 0x00000000},
-	{0x000081c4, 0x33332210},
-	{0x000081c8, 0x00000000},
-	{0x000081cc, 0x00000000},
-	{0x000081d4, 0x00000000},
-	{0x000081ec, 0x00000000},
-	{0x000081f0, 0x00000000},
-	{0x000081f4, 0x00000000},
-	{0x000081f8, 0x00000000},
-	{0x000081fc, 0x00000000},
-	{0x00008240, 0x00100000},
-	{0x00008244, 0x0010f400},
-	{0x00008248, 0x00000800},
-	{0x0000824c, 0x0001e800},
-	{0x00008250, 0x00000000},
-	{0x00008254, 0x00000000},
-	{0x00008258, 0x00000000},
-	{0x0000825c, 0x40000000},
-	{0x00008260, 0x00080922},
-	{0x00008264, 0x9ca00010},
-	{0x00008268, 0xffffffff},
-	{0x0000826c, 0x0000ffff},
-	{0x00008270, 0x00000000},
-	{0x00008274, 0x40000000},
-	{0x00008278, 0x003e4180},
-	{0x0000827c, 0x00000004},
-	{0x00008284, 0x0000002c},
-	{0x00008288, 0x0000002c},
-	{0x0000828c, 0x000000ff},
-	{0x00008294, 0x00000000},
-	{0x00008298, 0x00000000},
-	{0x0000829c, 0x00000000},
-	{0x00008300, 0x00000140},
-	{0x00008314, 0x00000000},
-	{0x0000831c, 0x0000010d},
-	{0x00008328, 0x00000000},
-	{0x0000832c, 0x00000007},
-	{0x00008330, 0x00000302},
-	{0x00008334, 0x00000700},
-	{0x00008338, 0x00ff0000},
-	{0x0000833c, 0x02400000},
-	{0x00008340, 0x000107ff},
-	{0x00008344, 0xa248105b},
-	{0x00008348, 0x008f0000},
-	{0x0000835c, 0x00000000},
-	{0x00008360, 0xffffffff},
-	{0x00008364, 0xffffffff},
-	{0x00008368, 0x00000000},
-	{0x00008370, 0x00000000},
-	{0x00008374, 0x000000ff},
-	{0x00008378, 0x00000000},
-	{0x0000837c, 0x00000000},
-	{0x00008380, 0xffffffff},
-	{0x00008384, 0xffffffff},
-	{0x00008390, 0xffffffff},
-	{0x00008394, 0xffffffff},
-	{0x00008398, 0x00000000},
-	{0x0000839c, 0x00000000},
-	{0x000083a0, 0x00000000},
-	{0x000083a4, 0x0000fa14},
-	{0x000083a8, 0x000f0c00},
-	{0x000083ac, 0x33332210},
-	{0x000083b0, 0x33332210},
-	{0x000083b4, 0x33332210},
-	{0x000083b8, 0x33332210},
-	{0x000083bc, 0x00000000},
-	{0x000083c0, 0x00000000},
-	{0x000083c4, 0x00000000},
-	{0x000083c8, 0x00000000},
-	{0x000083cc, 0x00000200},
-	{0x000083d0, 0x000301ff},
-};
-
 static const u32 ar9485_1_1_mac_core[][2] = {
 	/*  Addr       allmodes */
 	{0x00000008, 0x00000000},
@@ -1321,7 +396,7 @@
 	{0x0000a54c, 0x7203feca, 0x7203feca, 0x51001865, 0x51001865},
 	{0x0000a550, 0x7703ff0b, 0x7703ff0b, 0x55001a86, 0x55001a86},
 	{0x0000a554, 0x7d06ffcb, 0x7d06ffcb, 0x57001ce9, 0x57001ce9},
-	{0x0000a558, 0x8407ff0b, 0x8407ff0b, 0x5a001eeb, 0x5a001eeb},
+	{0x0000a558, 0x8407ff0b, 0x8407ff0b, 0x5a001ceb, 0x5a001ceb},
 	{0x0000a55c, 0x8907ffcb, 0x8907ffcb, 0x5e001eeb, 0x5e001eeb},
 	{0x0000a560, 0x900fff0b, 0x900fff0b, 0x5e001eeb, 0x5e001eeb},
 	{0x0000a564, 0x960fffcb, 0x960fffcb, 0x5e001eeb, 0x5e001eeb},
@@ -1394,7 +469,7 @@
 	{0x0000a54c, 0x7203feca, 0x7203feca, 0x51001865, 0x51001865},
 	{0x0000a550, 0x7703ff0b, 0x7703ff0b, 0x55001a86, 0x55001a86},
 	{0x0000a554, 0x7d06ffcb, 0x7d06ffcb, 0x57001ce9, 0x57001ce9},
-	{0x0000a558, 0x8407ff0b, 0x8407ff0b, 0x5a001eeb, 0x5a001eeb},
+	{0x0000a558, 0x8407ff0b, 0x8407ff0b, 0x5a001ceb, 0x5a001ceb},
 	{0x0000a55c, 0x8907ffcb, 0x8907ffcb, 0x5e001eeb, 0x5e001eeb},
 	{0x0000a560, 0x900fff0b, 0x900fff0b, 0x5e001eeb, 0x5e001eeb},
 	{0x0000a564, 0x960fffcb, 0x960fffcb, 0x5e001eeb, 0x5e001eeb},
@@ -1560,7 +635,7 @@
 	{0x0000a54c, 0x7203feca, 0x7203feca, 0x51001865, 0x51001865},
 	{0x0000a550, 0x7703ff0b, 0x7703ff0b, 0x55001a86, 0x55001a86},
 	{0x0000a554, 0x7d06ffcb, 0x7d06ffcb, 0x57001ce9, 0x57001ce9},
-	{0x0000a558, 0x8407ff0b, 0x8407ff0b, 0x5a001eeb, 0x5a001eeb},
+	{0x0000a558, 0x8407ff0b, 0x8407ff0b, 0x5a001ceb, 0x5a001ceb},
 	{0x0000a55c, 0x8907ffcb, 0x8907ffcb, 0x5e001eeb, 0x5e001eeb},
 	{0x0000a560, 0x900fff0b, 0x900fff0b, 0x5e001eeb, 0x5e001eeb},
 	{0x0000a564, 0x960fffcb, 0x960fffcb, 0x5e001eeb, 0x5e001eeb},
@@ -1653,7 +728,7 @@
 	{0x0000a54c, 0x7203feca, 0x7203feca, 0x51001865, 0x51001865},
 	{0x0000a550, 0x7703ff0b, 0x7703ff0b, 0x55001a86, 0x55001a86},
 	{0x0000a554, 0x7d06ffcb, 0x7d06ffcb, 0x57001ce9, 0x57001ce9},
-	{0x0000a558, 0x8407ff0b, 0x8407ff0b, 0x5a001eeb, 0x5a001eeb},
+	{0x0000a558, 0x8407ff0b, 0x8407ff0b, 0x5a001ceb, 0x5a001ceb},
 	{0x0000a55c, 0x8907ffcb, 0x8907ffcb, 0x5e001eeb, 0x5e001eeb},
 	{0x0000a560, 0x900fff0b, 0x900fff0b, 0x5e001eeb, 0x5e001eeb},
 	{0x0000a564, 0x960fffcb, 0x960fffcb, 0x5e001eeb, 0x5e001eeb},
@@ -1752,7 +827,7 @@
 	{0x0000a54c, 0x7203feca, 0x7203feca, 0x51001865, 0x51001865},
 	{0x0000a550, 0x7703ff0b, 0x7703ff0b, 0x55001a86, 0x55001a86},
 	{0x0000a554, 0x7d06ffcb, 0x7d06ffcb, 0x57001ce9, 0x57001ce9},
-	{0x0000a558, 0x8407ff0b, 0x8407ff0b, 0x5a001eeb, 0x5a001eeb},
+	{0x0000a558, 0x8407ff0b, 0x8407ff0b, 0x5a001ceb, 0x5a001ceb},
 	{0x0000a55c, 0x8907ffcb, 0x8907ffcb, 0x5e001eeb, 0x5e001eeb},
 	{0x0000a560, 0x900fff0b, 0x900fff0b, 0x5e001eeb, 0x5e001eeb},
 	{0x0000a564, 0x960fffcb, 0x960fffcb, 0x5e001eeb, 0x5e001eeb},
diff -druN linux-2.6.39-libre/drivers/net/wireless/ath/ath9k/ath9k.h linux-3.0-rc7-libre/drivers/net/wireless/ath/ath9k/ath9k.h
--- linux-2.6.39-libre/drivers/net/wireless/ath/ath9k/ath9k.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/ath/ath9k/ath9k.h	2011-07-11 19:51:52.000000000 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008-2009 Atheros Communications Inc.
+ * Copyright (c) 2008-2011 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
@@ -62,7 +62,6 @@
 #define	ATH_TXQ_SETUP(sc, i)        ((sc)->tx.txqsetup & (1<<i))
 
 struct ath_config {
-	u32 ath_aggr_prot;
 	u16 txpowlimit;
 	u8 cabqReadytime;
 };
@@ -120,13 +119,11 @@
 /* RX / TX */
 /***********/
 
-#define ATH_MAX_ANTENNA         3
 #define ATH_RXBUF               512
 #define ATH_TXBUF               512
 #define ATH_TXBUF_RESERVE       5
 #define ATH_MAX_QDEPTH          (ATH_TXBUF / 4 - ATH_TXBUF_RESERVE)
 #define ATH_TXMAXTRY            13
-#define ATH_MGT_TXMAXTRY        4
 
 #define TID_TO_WME_AC(_tid)				\
 	((((_tid) == 0) || ((_tid) == 3)) ? WME_AC_BE :	\
@@ -202,6 +199,7 @@
 	int sched;
 	struct list_head list;
 	struct list_head tid_q;
+	bool clear_ps_filter;
 };
 
 struct ath_frame_info {
@@ -257,8 +255,12 @@
 #endif
 	struct ath_atx_tid tid[WME_NUM_TID];
 	struct ath_atx_ac ac[WME_NUM_AC];
+	int ps_key;
+
 	u16 maxampdu;
 	u8 mpdudensity;
+
+	bool sleeping;
 };
 
 #define AGGR_CLEANUP         BIT(1)
@@ -340,17 +342,18 @@
 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 ath_tx_aggr_wakeup(struct ath_softc *sc, struct ath_node *an);
+bool ath_tx_aggr_sleep(struct ath_softc *sc, struct ath_node *an);
+
 /********/
 /* VIFs */
 /********/
 
 struct ath_vif {
 	int av_bslot;
-	bool is_bslot_active;
+	bool is_bslot_active, primary_sta_vif;
 	__le64 tsf_adjust; /* TSF adjustment for staggered beacons */
-	enum nl80211_iftype av_opmode;
 	struct ath_buf *av_bcbuf;
-	u8 bssid[ETH_ALEN]; /* current BSSID from config_interface */
 };
 
 /*******************/
@@ -362,7 +365,7 @@
  * number of BSSIDs) if a given beacon does not go out even after waiting this
  * number of beacon intervals, the game's up.
  */
-#define BSTUCK_THRESH           	(9 * ATH_BCBUF)
+#define BSTUCK_THRESH           	9
 #define	ATH_BCBUF               	4
 #define ATH_DEFAULT_BINTVAL     	100 /* TU */
 #define ATH_DEFAULT_BMISS_LIMIT 	10
@@ -386,7 +389,7 @@
 	u32 beaconq;
 	u32 bmisscnt;
 	u32 ast_be_xmit;
-	u64 bc_tstamp;
+	u32 bc_tstamp;
 	struct ieee80211_vif *bslot[ATH_BCBUF];
 	int slottime;
 	int slotupdate;
@@ -394,6 +397,9 @@
 	struct ath_descdma bdma;
 	struct ath_txq *cabq;
 	struct list_head bbuf;
+
+	bool tx_processed;
+	bool tx_last;
 };
 
 void ath_beacon_tasklet(unsigned long data);
@@ -401,6 +407,7 @@
 int ath_beacon_alloc(struct ath_softc *sc, struct ieee80211_vif *vif);
 void ath_beacon_return(struct ath_softc *sc, struct ath_vif *avp);
 int ath_beaconq_config(struct ath_softc *sc);
+void ath_set_beacon(struct ath_softc *sc);
 void ath9k_set_beaconing_status(struct ath_softc *sc, bool status);
 
 /*******/
@@ -418,6 +425,7 @@
 #define ATH_PAPRD_TIMEOUT	100 /* msecs */
 
 void ath_hw_check(struct work_struct *work);
+void ath_hw_pll_work(struct work_struct *work);
 void ath_paprd_calibrate(struct work_struct *work);
 void ath_ani_calibrate(unsigned long data);
 
@@ -448,6 +456,7 @@
 
 #define ATH_LED_PIN_DEF 		1
 #define ATH_LED_PIN_9287		8
+#define ATH_LED_PIN_9300		10
 #define ATH_LED_PIN_9485		6
 
 #ifdef CONFIG_MAC80211_LEDS
@@ -477,7 +486,6 @@
 #define ATH_ANT_DIV_COMB_ALT_ANT_RATIO 30
 #define ATH_ANT_DIV_COMB_ALT_ANT_RATIO2 20
 
-#define ATH_ANT_DIV_COMB_LNA1_LNA2_DELTA -3
 #define ATH_ANT_DIV_COMB_LNA1_LNA2_SWITCH_DELTA -1
 #define ATH_ANT_DIV_COMB_LNA1_DELTA_HI -4
 #define ATH_ANT_DIV_COMB_LNA1_DELTA_MID -2
@@ -550,6 +558,7 @@
 #define SC_OP_BT_SCAN		     BIT(13)
 #define SC_OP_ANI_RUN		     BIT(14)
 #define SC_OP_ENABLE_APM	     BIT(15)
+#define SC_OP_PRIM_STA_VIF	     BIT(16)
 
 /* Powersave flags */
 #define PS_WAIT_FOR_BEACON        BIT(0)
@@ -557,6 +566,7 @@
 #define PS_WAIT_FOR_PSPOLL_DATA   BIT(2)
 #define PS_WAIT_FOR_TX_ACK        BIT(3)
 #define PS_BEACON_SYNC            BIT(4)
+#define PS_TSFOOR_SYNC            BIT(5)
 
 struct ath_rate_table;
 
@@ -667,7 +677,7 @@
 bool ath9k_setpower(struct ath_softc *sc, enum ath9k_power_mode mode);
 bool ath9k_uses_beacons(int type);
 
-#ifdef CONFIG_PCI
+#ifdef CONFIG_ATH9K_PCI
 int ath_pci_init(void);
 void ath_pci_exit(void);
 #else
@@ -675,7 +685,7 @@
 static inline void ath_pci_exit(void) {};
 #endif
 
-#ifdef CONFIG_ATHEROS_AR71XX
+#ifdef CONFIG_ATH9K_AHB
 int ath_ahb_init(void);
 void ath_ahb_exit(void);
 #else
@@ -688,8 +698,6 @@
 
 u8 ath_txchainmask_reduction(struct ath_softc *sc, u8 chainmask, u32 rate);
 
-void ath9k_set_bssid_mask(struct ieee80211_hw *hw, struct ieee80211_vif *vif);
-
 void ath_start_rfkill_poll(struct ath_softc *sc);
 extern void ath9k_rfkill_poll_state(struct ieee80211_hw *hw);
 void ath9k_calculate_iter_data(struct ieee80211_hw *hw,
diff -druN linux-2.6.39-libre/drivers/net/wireless/ath/ath9k/beacon.c linux-3.0-rc7-libre/drivers/net/wireless/ath/ath9k/beacon.c
--- linux-2.6.39-libre/drivers/net/wireless/ath/ath9k/beacon.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/ath/ath9k/beacon.c	2011-07-11 19:51:52.000000000 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008-2009 Atheros Communications Inc.
+ * Copyright (c) 2008-2011 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
@@ -18,6 +18,12 @@
 
 #define FUDGE 2
 
+static void ath9k_reset_beacon_status(struct ath_softc *sc)
+{
+	sc->beacon.tx_processed = false;
+	sc->beacon.tx_last = false;
+}
+
 /*
  *  This function will modify certain transmit queue properties depending on
  *  the operating mode of the station (AP or AdHoc).  Parameters are AIFS
@@ -57,8 +63,8 @@
 
 /*
  *  Associates the beacon frame buffer with a transmit descriptor.  Will set
- *  up all required antenna switch parameters, rate codes, and channel flags.
- *  Beacons are always sent out at the lowest rate, and are not retried.
+ *  up rate codes, and channel flags. Beacons are always sent out at the
+ *  lowest rate, and are not retried.
 */
 static void ath_beacon_setup(struct ath_softc *sc, struct ath_vif *avp,
 			     struct ath_buf *bf, int rateidx)
@@ -68,20 +74,16 @@
 	struct ath_common *common = ath9k_hw_common(ah);
 	struct ath_desc *ds;
 	struct ath9k_11n_rate_series series[4];
-	int flags, antenna, ctsrate = 0, ctsduration = 0;
+	int flags, ctsrate = 0, ctsduration = 0;
 	struct ieee80211_supported_band *sband;
 	u8 rate = 0;
 
+	ath9k_reset_beacon_status(sc);
+
 	ds = bf->bf_desc;
 	flags = ATH9K_TXDESC_NOACK;
 
 	ds->ds_link = 0;
-	/*
-	 * Switch antenna every beacon.
-	 * Should only switch every beacon period, not for every SWBA
-	 * XXX assumes two antennae
-	 */
-	antenna = ((sc->beacon.ast_be_xmit / sc->nbcnvifs) & 1 ? 2 : 1);
 
 	sband = &sc->sbands[common->hw->conf.channel->band];
 	rate = sband->bitrates[rateidx].hw_value;
@@ -140,6 +142,8 @@
 	struct ieee80211_tx_info *info;
 	int cabq_depth;
 
+	ath9k_reset_beacon_status(sc);
+
 	avp = (void *)vif->drv_priv;
 	cabq = sc->beacon.cabq;
 
@@ -278,7 +282,7 @@
 		return -ENOMEM;
 
 	tstamp = ((struct ieee80211_mgmt *)skb->data)->u.beacon.timestamp;
-	sc->beacon.bc_tstamp = le64_to_cpu(tstamp);
+	sc->beacon.bc_tstamp = (u32) le64_to_cpu(tstamp);
 	/* Calculate a TSF adjustment factor required for staggered beacons. */
 	if (avp->av_bslot > 0) {
 		u64 tsfadjust;
@@ -294,8 +298,8 @@
 		 * adjustment. Other slots are adjusted to get the timestamp
 		 * close to the TBTT for the BSS.
 		 */
-		tsfadjust = intval * avp->av_bslot / ATH_BCBUF;
-		avp->tsf_adjust = cpu_to_le64(TU_TO_USEC(tsfadjust));
+		tsfadjust = TU_TO_USEC(intval * avp->av_bslot) / ATH_BCBUF;
+		avp->tsf_adjust = cpu_to_le64(tsfadjust);
 
 		ath_dbg(common, ATH_DBG_BEACON,
 			"stagger beacons, bslot %d intval %u tsfadjust %llu\n",
@@ -326,9 +330,11 @@
 	if (avp->av_bcbuf != NULL) {
 		struct ath_buf *bf;
 
+		avp->is_bslot_active = false;
 		if (avp->av_bslot != -1) {
 			sc->beacon.bslot[avp->av_bslot] = NULL;
 			sc->nbcnvifs--;
+			avp->av_bslot = -1;
 		}
 
 		bf = avp->av_bcbuf;
@@ -355,9 +361,7 @@
 	struct ath_buf *bf = NULL;
 	struct ieee80211_vif *vif;
 	int slot;
-	u32 bfaddr, bc = 0, tsftu;
-	u64 tsf;
-	u16 intval;
+	u32 bfaddr, bc = 0;
 
 	/*
 	 * Check if the previous beacon has gone out.  If
@@ -369,12 +373,13 @@
 	if (ath9k_hw_numtxpending(ah, sc->beacon.beaconq) != 0) {
 		sc->beacon.bmisscnt++;
 
-		if (sc->beacon.bmisscnt < BSTUCK_THRESH) {
+		if (sc->beacon.bmisscnt < BSTUCK_THRESH * sc->nbcnvifs) {
 			ath_dbg(common, ATH_DBG_BSTUCK,
 				"missed %u consecutive beacons\n",
 				sc->beacon.bmisscnt);
 			ath9k_hw_stop_dma_queue(ah, sc->beacon.beaconq);
-			ath9k_hw_bstuck_nfcal(ah);
+			if (sc->beacon.bmisscnt > 3)
+				ath9k_hw_bstuck_nfcal(ah);
 		} else if (sc->beacon.bmisscnt >= BSTUCK_THRESH) {
 			ath_dbg(common, ATH_DBG_BSTUCK,
 				"beacon is officially stuck\n");
@@ -385,37 +390,33 @@
 		return;
 	}
 
-	if (sc->beacon.bmisscnt != 0) {
-		ath_dbg(common, ATH_DBG_BSTUCK,
-			"resume beacon xmit after %u misses\n",
-			sc->beacon.bmisscnt);
-		sc->beacon.bmisscnt = 0;
-	}
-
 	/*
 	 * Generate beacon frames. we are sending frames
 	 * staggered so calculate the slot for this frame based
 	 * on the tsf to safeguard against missing an swba.
 	 */
 
-	intval = cur_conf->beacon_interval ? : ATH_DEFAULT_BINTVAL;
 
-	tsf = ath9k_hw_gettsf64(ah);
-	tsftu = TSF_TO_TU(tsf>>32, tsf);
-	slot = ((tsftu % intval) * ATH_BCBUF) / intval;
-	/*
-	 * Reverse the slot order to get slot 0 on the TBTT offset that does
-	 * not require TSF adjustment and other slots adding
-	 * slot/ATH_BCBUF * beacon_int to timestamp. For example, with
-	 * ATH_BCBUF = 4, we process beacon slots as follows: 3 2 1 0 3 2 1 ..
-	 * and slot 0 is at correct offset to TBTT.
-	 */
-	slot = ATH_BCBUF - slot - 1;
-	vif = sc->beacon.bslot[slot];
+	if (ah->opmode == NL80211_IFTYPE_AP) {
+		u16 intval;
+		u32 tsftu;
+		u64 tsf;
+
+		intval = cur_conf->beacon_interval ? : ATH_DEFAULT_BINTVAL;
+		tsf = ath9k_hw_gettsf64(ah);
+		tsf += TU_TO_USEC(ah->config.sw_beacon_response_time);
+		tsftu = TSF_TO_TU((tsf * ATH_BCBUF) >>32, tsf * ATH_BCBUF);
+		slot = (tsftu % (intval * ATH_BCBUF)) / intval;
+		vif = sc->beacon.bslot[slot];
+
+		ath_dbg(common, ATH_DBG_BEACON,
+			"slot %d [tsf %llu tsftu %u intval %u] vif %p\n",
+			slot, tsf, tsftu / ATH_BCBUF, intval, vif);
+	} else {
+		slot = 0;
+		vif = sc->beacon.bslot[slot];
+	}
 
-	ath_dbg(common, ATH_DBG_BEACON,
-		"slot %d [tsf %llu tsftu %u intval %u] vif %p\n",
-		slot, tsf, tsftu, intval, vif);
 
 	bfaddr = 0;
 	if (vif) {
@@ -424,6 +425,13 @@
 			bfaddr = bf->bf_daddr;
 			bc = 1;
 		}
+
+		if (sc->beacon.bmisscnt != 0) {
+			ath_dbg(common, ATH_DBG_BSTUCK,
+				"resume beacon xmit after %u misses\n",
+				sc->beacon.bmisscnt);
+			sc->beacon.bmisscnt = 0;
+		}
 	}
 
 	/*
@@ -463,13 +471,17 @@
 			      u32 next_beacon,
 			      u32 beacon_period)
 {
-	if (beacon_period & ATH9K_BEACON_RESET_TSF)
+	if (sc->sc_flags & SC_OP_TSF_RESET) {
 		ath9k_ps_wakeup(sc);
+		ath9k_hw_reset_tsf(sc->sc_ah);
+	}
 
 	ath9k_hw_beaconinit(sc->sc_ah, next_beacon, beacon_period);
 
-	if (beacon_period & ATH9K_BEACON_RESET_TSF)
+	if (sc->sc_flags & SC_OP_TSF_RESET) {
 		ath9k_ps_restore(sc);
+		sc->sc_flags &= ~SC_OP_TSF_RESET;
+	}
 }
 
 /*
@@ -484,18 +496,14 @@
 	u32 nexttbtt, intval;
 
 	/* NB: the beacon interval is kept internally in TU's */
-	intval = conf->beacon_interval & ATH9K_BEACON_PERIOD;
+	intval = TU_TO_USEC(conf->beacon_interval & ATH9K_BEACON_PERIOD);
 	intval /= ATH_BCBUF;    /* for staggered beacons */
 	nexttbtt = intval;
 
-	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
 	 * prepare beacon frames.
 	 */
-	intval |= ATH9K_BEACON_ENA;
 	ah->imask |= ATH9K_INT_SWBA;
 	ath_beaconq_config(sc);
 
@@ -505,11 +513,6 @@
 	ath9k_beacon_init(sc, nexttbtt, intval);
 	sc->beacon.bmisscnt = 0;
 	ath9k_hw_set_interrupts(ah, ah->imask);
-
-	/* Clear the reset TSF flag, so that subsequent beacon updation
-	   will not reset the HW TSF. */
-
-	sc->sc_flags &= ~SC_OP_TSF_RESET;
 }
 
 /*
@@ -635,7 +638,13 @@
 	ath9k_hw_disable_interrupts(ah);
 	ath9k_hw_set_sta_beacon_timers(ah, &bs);
 	ah->imask |= ATH9K_INT_BMISS;
-	ath9k_hw_set_interrupts(ah, ah->imask);
+
+	/*
+	 * If the beacon config is called beacause of TSFOOR,
+	 * Interrupts will be enabled back at the end of ath9k_tasklet
+	 */
+	if (!(sc->ps_flags & PS_TSFOOR_SYNC))
+		ath9k_hw_set_interrupts(ah, ah->imask);
 }
 
 static void ath_beacon_config_adhoc(struct ath_softc *sc,
@@ -643,25 +652,22 @@
 {
 	struct ath_hw *ah = sc->sc_ah;
 	struct ath_common *common = ath9k_hw_common(ah);
-	u64 tsf;
-	u32 tsftu, intval, nexttbtt;
-
-	intval = conf->beacon_interval & ATH9K_BEACON_PERIOD;
-
+	u32 tsf, delta, intval, nexttbtt;
 
-	/* Pull nexttbtt forward to reflect the current TSF */
+	ath9k_reset_beacon_status(sc);
 
-	nexttbtt = TSF_TO_TU(sc->beacon.bc_tstamp >> 32, sc->beacon.bc_tstamp);
-	if (nexttbtt == 0)
-                nexttbtt = intval;
-        else if (intval)
-                nexttbtt = roundup(nexttbtt, intval);
+	tsf = ath9k_hw_gettsf32(ah) + TU_TO_USEC(FUDGE);
+	intval = TU_TO_USEC(conf->beacon_interval & ATH9K_BEACON_PERIOD);
 
-	tsf = ath9k_hw_gettsf64(ah);
-	tsftu = TSF_TO_TU((u32)(tsf>>32), (u32)tsf) + FUDGE;
-	do {
-		nexttbtt += intval;
-	} while (nexttbtt < tsftu);
+	if (!sc->beacon.bc_tstamp)
+		nexttbtt = tsf + intval;
+	else {
+		if (tsf > sc->beacon.bc_tstamp)
+			delta = (tsf - sc->beacon.bc_tstamp);
+		else
+			delta = (tsf + 1 + (~0U - sc->beacon.bc_tstamp));
+		nexttbtt = tsf + intval - (delta % intval);
+	}
 
 	ath_dbg(common, ATH_DBG_BEACON,
 		"IBSS nexttbtt %u intval %u (%u)\n",
@@ -672,7 +678,6 @@
 	 * if we need to manually prepare beacon frames.  Otherwise we use a
 	 * self-linked tx descriptor and let the hardware deal with things.
 	 */
-	intval |= ATH9K_BEACON_ENA;
 	ah->imask |= ATH9K_INT_SWBA;
 
 	ath_beaconq_config(sc);
@@ -682,25 +687,71 @@
 	ath9k_hw_disable_interrupts(ah);
 	ath9k_beacon_init(sc, nexttbtt, intval);
 	sc->beacon.bmisscnt = 0;
-	ath9k_hw_set_interrupts(ah, ah->imask);
+	/*
+	 * If the beacon config is called beacause of TSFOOR,
+	 * Interrupts will be enabled back at the end of ath9k_tasklet
+	 */
+	if (!(sc->ps_flags & PS_TSFOOR_SYNC))
+		ath9k_hw_set_interrupts(ah, ah->imask);
 }
 
-void ath_beacon_config(struct ath_softc *sc, struct ieee80211_vif *vif)
+static bool ath9k_allow_beacon_config(struct ath_softc *sc,
+				      struct ieee80211_vif *vif)
 {
 	struct ath_beacon_config *cur_conf = &sc->cur_beacon_conf;
 	struct ath_common *common = ath9k_hw_common(sc->sc_ah);
-	enum nl80211_iftype iftype;
+	struct ieee80211_bss_conf *bss_conf = &vif->bss_conf;
+	struct ath_vif *avp = (void *)vif->drv_priv;
 
-	/* Setup the beacon configuration parameters */
-	if (vif) {
-		struct ieee80211_bss_conf *bss_conf = &vif->bss_conf;
-		iftype = vif->type;
-		cur_conf->beacon_interval = bss_conf->beacon_int;
-		cur_conf->dtim_period = bss_conf->dtim_period;
-	} else {
-		iftype = sc->sc_ah->opmode;
+	/*
+	 * Can not have different beacon interval on multiple
+	 * AP interface case
+	 */
+	if ((sc->sc_ah->opmode == NL80211_IFTYPE_AP) &&
+	    (sc->nbcnvifs > 1) &&
+	    (vif->type == NL80211_IFTYPE_AP) &&
+	    (cur_conf->beacon_interval != bss_conf->beacon_int)) {
+		ath_dbg(common, ATH_DBG_CONFIG,
+			"Changing beacon interval of multiple \
+			AP interfaces !\n");
+		return false;
+	}
+	/*
+	 * Can not configure station vif's beacon config
+	 * while on AP opmode
+	 */
+	if ((sc->sc_ah->opmode == NL80211_IFTYPE_AP) &&
+	    (vif->type != NL80211_IFTYPE_AP)) {
+		ath_dbg(common, ATH_DBG_CONFIG,
+			"STA vif's beacon not allowed on AP mode\n");
+		return false;
 	}
+	/*
+	 * Do not allow beacon config if HW was already configured
+	 * with another STA vif
+	 */
+	if ((sc->sc_ah->opmode == NL80211_IFTYPE_STATION) &&
+	    (vif->type == NL80211_IFTYPE_STATION) &&
+	    (sc->sc_flags & SC_OP_BEACONS) &&
+	    !avp->primary_sta_vif) {
+		ath_dbg(common, ATH_DBG_CONFIG,
+			"Beacon already configured for a station interface\n");
+		return false;
+	}
+	return true;
+}
+
+void ath_beacon_config(struct ath_softc *sc, struct ieee80211_vif *vif)
+{
+	struct ath_beacon_config *cur_conf = &sc->cur_beacon_conf;
+	struct ieee80211_bss_conf *bss_conf = &vif->bss_conf;
+
+	if (!ath9k_allow_beacon_config(sc, vif))
+		return;
 
+	/* Setup the beacon configuration parameters */
+	cur_conf->beacon_interval = bss_conf->beacon_int;
+	cur_conf->dtim_period = bss_conf->dtim_period;
 	cur_conf->listen_interval = 1;
 	cur_conf->dtim_count = 1;
 	cur_conf->bmiss_timeout =
@@ -723,9 +774,37 @@
 	if (cur_conf->dtim_period == 0)
 		cur_conf->dtim_period = 1;
 
-	switch (iftype) {
+	ath_set_beacon(sc);
+}
+
+static bool ath_has_valid_bslot(struct ath_softc *sc)
+{
+	struct ath_vif *avp;
+	int slot;
+	bool found = false;
+
+	for (slot = 0; slot < ATH_BCBUF; slot++) {
+		if (sc->beacon.bslot[slot]) {
+			avp = (void *)sc->beacon.bslot[slot]->drv_priv;
+			if (avp->is_bslot_active) {
+				found = true;
+				break;
+			}
+		}
+	}
+	return found;
+}
+
+
+void ath_set_beacon(struct ath_softc *sc)
+{
+	struct ath_common *common = ath9k_hw_common(sc->sc_ah);
+	struct ath_beacon_config *cur_conf = &sc->cur_beacon_conf;
+
+	switch (sc->sc_ah->opmode) {
 	case NL80211_IFTYPE_AP:
-		ath_beacon_config_ap(sc, cur_conf);
+		if (ath_has_valid_bslot(sc))
+			ath_beacon_config_ap(sc, cur_conf);
 		break;
 	case NL80211_IFTYPE_ADHOC:
 	case NL80211_IFTYPE_MESH_POINT:
@@ -746,26 +825,15 @@
 void ath9k_set_beaconing_status(struct ath_softc *sc, bool status)
 {
 	struct ath_hw *ah = sc->sc_ah;
-	struct ath_vif *avp;
-	int slot;
-	bool found = false;
+
+	if (!ath_has_valid_bslot(sc))
+		return;
 
 	ath9k_ps_wakeup(sc);
 	if (status) {
-		for (slot = 0; slot < ATH_BCBUF; slot++) {
-			if (sc->beacon.bslot[slot]) {
-				avp = (void *)sc->beacon.bslot[slot]->drv_priv;
-				if (avp->is_bslot_active) {
-					found = true;
-					break;
-				}
-			}
-		}
-		if (found) {
-			/* Re-enable beaconing */
-			ah->imask |= ATH9K_INT_SWBA;
-			ath9k_hw_set_interrupts(ah, ah->imask);
-		}
+		/* Re-enable beaconing */
+		ah->imask |= ATH9K_INT_SWBA;
+		ath9k_hw_set_interrupts(ah, ah->imask);
 	} else {
 		/* Disable SWBA interrupt */
 		ah->imask &= ~ATH9K_INT_SWBA;
diff -druN linux-2.6.39-libre/drivers/net/wireless/ath/ath9k/btcoex.c linux-3.0-rc7-libre/drivers/net/wireless/ath/ath9k/btcoex.c
--- linux-2.6.39-libre/drivers/net/wireless/ath/ath9k/btcoex.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/ath/ath9k/btcoex.c	2011-07-11 19:51:52.000000000 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009 Atheros Communications Inc.
+ * Copyright (c) 2009-2011 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
@@ -51,6 +51,10 @@
 		.bt_hold_rx_clear = true,
 	};
 	u32 i;
+	bool rxclear_polarity = ath_bt_config.bt_rxclear_polarity;
+
+	if (AR_SREV_9300_20_OR_LATER(ah))
+		rxclear_polarity = !ath_bt_config.bt_rxclear_polarity;
 
 	btcoex_hw->bt_coex_mode =
 		(btcoex_hw->bt_coex_mode & AR_BT_QCU_THRESH) |
@@ -59,7 +63,7 @@
 		SM(ath_bt_config.bt_txframe_extend, AR_BT_TX_FRAME_EXTEND) |
 		SM(ath_bt_config.bt_mode, AR_BT_MODE) |
 		SM(ath_bt_config.bt_quiet_collision, AR_BT_QUIET) |
-		SM(ath_bt_config.bt_rxclear_polarity, AR_BT_RX_CLEAR_POLARITY) |
+		SM(rxclear_polarity, AR_BT_RX_CLEAR_POLARITY) |
 		SM(ath_bt_config.bt_priority_time, AR_BT_PRIORITY_TIME) |
 		SM(ath_bt_config.bt_first_slot_time, AR_BT_FIRST_SLOT_TIME) |
 		SM(qnum, AR_BT_QCU_THRESH);
@@ -142,6 +146,7 @@
 }
 EXPORT_SYMBOL(ath9k_hw_btcoex_set_weight);
 
+
 static void ath9k_hw_btcoex_enable_3wire(struct ath_hw *ah)
 {
 	struct ath_btcoex_hw *btcoex_hw = &ah->btcoex_hw;
@@ -152,9 +157,22 @@
 	 * enable coex 3-wire
 	 */
 	REG_WRITE(ah, AR_BT_COEX_MODE, btcoex_hw->bt_coex_mode);
-	REG_WRITE(ah, AR_BT_COEX_WEIGHT, btcoex_hw->bt_coex_weights);
 	REG_WRITE(ah, AR_BT_COEX_MODE2, btcoex_hw->bt_coex_mode2);
 
+
+	if (AR_SREV_9300_20_OR_LATER(ah)) {
+		REG_WRITE(ah, AR_BT_COEX_WL_WEIGHTS0, ah->bt_coex_wlan_weight[0]);
+		REG_WRITE(ah, AR_BT_COEX_WL_WEIGHTS1, ah->bt_coex_wlan_weight[1]);
+		REG_WRITE(ah, AR_BT_COEX_BT_WEIGHTS0, ah->bt_coex_bt_weight[0]);
+		REG_WRITE(ah, AR_BT_COEX_BT_WEIGHTS1, ah->bt_coex_bt_weight[1]);
+		REG_WRITE(ah, AR_BT_COEX_BT_WEIGHTS2, ah->bt_coex_bt_weight[2]);
+		REG_WRITE(ah, AR_BT_COEX_BT_WEIGHTS3, ah->bt_coex_bt_weight[3]);
+
+	} else
+		REG_WRITE(ah, AR_BT_COEX_WEIGHT, btcoex_hw->bt_coex_weights);
+
+
+
 	if (AR_SREV_9271(ah)) {
 		val = REG_READ(ah, 0x50040);
 		val &= 0xFFFFFEFF;
@@ -202,10 +220,86 @@
 
 	if (btcoex_hw->scheme == ATH_BTCOEX_CFG_3WIRE) {
 		REG_WRITE(ah, AR_BT_COEX_MODE, AR_BT_QUIET | AR_BT_MODE);
-		REG_WRITE(ah, AR_BT_COEX_WEIGHT, 0);
 		REG_WRITE(ah, AR_BT_COEX_MODE2, 0);
+
+		if (AR_SREV_9300_20_OR_LATER(ah)) {
+			REG_WRITE(ah, AR_BT_COEX_WL_WEIGHTS0, 0);
+			REG_WRITE(ah, AR_BT_COEX_WL_WEIGHTS1, 0);
+			REG_WRITE(ah, AR_BT_COEX_BT_WEIGHTS0, 0);
+			REG_WRITE(ah, AR_BT_COEX_BT_WEIGHTS1, 0);
+			REG_WRITE(ah, AR_BT_COEX_BT_WEIGHTS2, 0);
+			REG_WRITE(ah, AR_BT_COEX_BT_WEIGHTS3, 0);
+		} else
+			REG_WRITE(ah, AR_BT_COEX_WEIGHT, 0);
+
 	}
 
 	ah->btcoex_hw.enabled = false;
 }
 EXPORT_SYMBOL(ath9k_hw_btcoex_disable);
+
+static void ar9003_btcoex_bt_stomp(struct ath_hw *ah,
+			 enum ath_stomp_type stomp_type)
+{
+	ah->bt_coex_bt_weight[0] = AR9300_BT_WGHT;
+	ah->bt_coex_bt_weight[1] = AR9300_BT_WGHT;
+	ah->bt_coex_bt_weight[2] = AR9300_BT_WGHT;
+	ah->bt_coex_bt_weight[3] = AR9300_BT_WGHT;
+
+
+	switch (stomp_type) {
+	case ATH_BTCOEX_STOMP_ALL:
+		ah->bt_coex_wlan_weight[0] = AR9300_STOMP_ALL_WLAN_WGHT0;
+		ah->bt_coex_wlan_weight[1] = AR9300_STOMP_ALL_WLAN_WGHT1;
+		break;
+	case ATH_BTCOEX_STOMP_LOW:
+		ah->bt_coex_wlan_weight[0] = AR9300_STOMP_LOW_WLAN_WGHT0;
+		ah->bt_coex_wlan_weight[1] = AR9300_STOMP_LOW_WLAN_WGHT1;
+		break;
+	case ATH_BTCOEX_STOMP_NONE:
+		ah->bt_coex_wlan_weight[0] = AR9300_STOMP_NONE_WLAN_WGHT0;
+		ah->bt_coex_wlan_weight[1] = AR9300_STOMP_NONE_WLAN_WGHT1;
+		break;
+
+	default:
+		ath_dbg(ath9k_hw_common(ah), ATH_DBG_BTCOEX,
+				"Invalid Stomptype\n");
+		break;
+	}
+
+	ath9k_hw_btcoex_enable(ah);
+}
+
+/*
+ * Configures appropriate weight based on stomp type.
+ */
+void ath9k_hw_btcoex_bt_stomp(struct ath_hw *ah,
+			      enum ath_stomp_type stomp_type)
+{
+	if (AR_SREV_9300_20_OR_LATER(ah)) {
+		ar9003_btcoex_bt_stomp(ah, stomp_type);
+		return;
+	}
+
+	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_dbg(ath9k_hw_common(ah), ATH_DBG_BTCOEX,
+				"Invalid Stomptype\n");
+		break;
+	}
+
+	ath9k_hw_btcoex_enable(ah);
+}
+EXPORT_SYMBOL(ath9k_hw_btcoex_bt_stomp);
diff -druN linux-2.6.39-libre/drivers/net/wireless/ath/ath9k/btcoex.h linux-3.0-rc7-libre/drivers/net/wireless/ath/ath9k/btcoex.h
--- linux-2.6.39-libre/drivers/net/wireless/ath/ath9k/btcoex.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/ath/ath9k/btcoex.h	2011-07-11 19:51:52.000000000 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009 Atheros Communications Inc.
+ * Copyright (c) 2009-2011 Atheros Communications Inc.
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
@@ -19,9 +19,13 @@
 
 #include "hw.h"
 
-#define ATH_WLANACTIVE_GPIO	5
-#define ATH_BTACTIVE_GPIO	6
-#define ATH_BTPRIORITY_GPIO	7
+#define ATH_WLANACTIVE_GPIO_9280     5
+#define ATH_BTACTIVE_GPIO_9280       6
+#define ATH_BTPRIORITY_GPIO_9285     7
+
+#define ATH_WLANACTIVE_GPIO_9300     5
+#define ATH_BTACTIVE_GPIO_9300       4
+#define ATH_BTPRIORITY_GPIO_9300     8
 
 #define ATH_BTCOEX_DEF_BT_PERIOD  45
 #define ATH_BTCOEX_DEF_DUTY_CYCLE 55
@@ -32,6 +36,14 @@
 #define ATH_BT_CNT_THRESHOLD	       3
 #define ATH_BT_CNT_SCAN_THRESHOLD      15
 
+/* Defines the BT AR_BT_COEX_WGHT used */
+enum ath_stomp_type {
+	ATH_BTCOEX_NO_STOMP,
+	ATH_BTCOEX_STOMP_ALL,
+	ATH_BTCOEX_STOMP_LOW,
+	ATH_BTCOEX_STOMP_NONE
+};
+
 enum ath_btcoex_scheme {
 	ATH_BTCOEX_CFG_NONE,
 	ATH_BTCOEX_CFG_2WIRE,
@@ -57,5 +69,7 @@
 				u32 wlan_weight);
 void ath9k_hw_btcoex_enable(struct ath_hw *ah);
 void ath9k_hw_btcoex_disable(struct ath_hw *ah);
+void ath9k_hw_btcoex_bt_stomp(struct ath_hw *ah,
+			      enum ath_stomp_type stomp_type);
 
 #endif
diff -druN linux-2.6.39-libre/drivers/net/wireless/ath/ath9k/calib.c linux-3.0-rc7-libre/drivers/net/wireless/ath/ath9k/calib.c
--- linux-2.6.39-libre/drivers/net/wireless/ath/ath9k/calib.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/ath/ath9k/calib.c	2011-07-11 19:51:52.000000000 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008-2009 Atheros Communications Inc.
+ * Copyright (c) 2008-2011 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
@@ -69,15 +69,21 @@
 					      int16_t *nfarray)
 {
 	struct ath_common *common = ath9k_hw_common(ah);
+	struct ieee80211_conf *conf = &common->hw->conf;
 	struct ath_nf_limits *limit;
 	struct ath9k_nfcal_hist *h;
 	bool high_nf_mid = false;
+	u8 chainmask = (ah->rxchainmask << 3) | ah->rxchainmask;
 	int i;
 
 	h = cal->nfCalHist;
 	limit = ath9k_hw_get_nf_limits(ah, ah->curchan);
 
 	for (i = 0; i < NUM_NF_READINGS; i++) {
+		if (!(chainmask & (1 << i)) ||
+		    ((i >= AR5416_MAX_CHAINS) && !conf_is_ht40(conf)))
+			continue;
+
 		h[i].nfCalBuffer[h[i].currIndex] = nfarray[i];
 
 		if (++h[i].currIndex >= ATH9K_NF_CAL_HIST_MAX)
@@ -225,6 +231,7 @@
 	int32_t val;
 	u8 chainmask = (ah->rxchainmask << 3) | ah->rxchainmask;
 	struct ath_common *common = ath9k_hw_common(ah);
+	struct ieee80211_conf *conf = &common->hw->conf;
 	s16 default_nf = ath9k_hw_get_default_nf(ah, chan);
 
 	if (ah->caldata)
@@ -234,6 +241,9 @@
 		if (chainmask & (1 << i)) {
 			s16 nfval;
 
+			if ((i >= AR5416_MAX_CHAINS) && !conf_is_ht40(conf))
+				continue;
+
 			if (h)
 				nfval = h[i].privNF;
 			else
@@ -293,6 +303,9 @@
 	ENABLE_REGWRITE_BUFFER(ah);
 	for (i = 0; i < NUM_NF_READINGS; i++) {
 		if (chainmask & (1 << i)) {
+			if ((i >= AR5416_MAX_CHAINS) && !conf_is_ht40(conf))
+				continue;
+
 			val = REG_READ(ah, ah->nf_regs[i]);
 			val &= 0xFFFFFE00;
 			val |= (((u32) (-50) << 1) & 0x1ff);
@@ -396,14 +409,6 @@
 	}
 }
 
-s16 ath9k_hw_getchan_noise(struct ath_hw *ah, struct ath9k_channel *chan)
-{
-	if (!ah->curchan || !ah->curchan->noisefloor)
-		return ath9k_hw_get_default_nf(ah, chan);
-
-	return ah->curchan->noisefloor;
-}
-EXPORT_SYMBOL(ath9k_hw_getchan_noise);
 
 void ath9k_hw_bstuck_nfcal(struct ath_hw *ah)
 {
diff -druN linux-2.6.39-libre/drivers/net/wireless/ath/ath9k/calib.h linux-3.0-rc7-libre/drivers/net/wireless/ath/ath9k/calib.h
--- linux-2.6.39-libre/drivers/net/wireless/ath/ath9k/calib.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/ath/ath9k/calib.h	2011-07-11 19:51:52.000000000 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008-2009 Atheros Communications Inc.
+ * Copyright (c) 2008-2011 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
@@ -106,7 +106,6 @@
 void ath9k_init_nfcal_hist_buffer(struct ath_hw *ah,
 				  struct ath9k_channel *chan);
 void ath9k_hw_bstuck_nfcal(struct ath_hw *ah);
-s16 ath9k_hw_getchan_noise(struct ath_hw *ah, struct ath9k_channel *chan);
 void ath9k_hw_reset_calibration(struct ath_hw *ah,
 				struct ath9k_cal_list *currCal);
 
diff -druN linux-2.6.39-libre/drivers/net/wireless/ath/ath9k/common.c linux-3.0-rc7-libre/drivers/net/wireless/ath/ath9k/common.c
--- linux-2.6.39-libre/drivers/net/wireless/ath/ath9k/common.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/ath/ath9k/common.c	2011-07-11 19:51:52.000000000 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009 Atheros Communications Inc.
+ * Copyright (c) 2009-2011 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
@@ -116,7 +116,7 @@
 
 	if (chan->band == IEEE80211_BAND_2GHZ) {
 		ichan->chanmode = CHANNEL_G;
-		ichan->channelFlags = CHANNEL_2GHZ | CHANNEL_OFDM | CHANNEL_G;
+		ichan->channelFlags = CHANNEL_2GHZ | CHANNEL_OFDM;
 	} else {
 		ichan->chanmode = CHANNEL_A;
 		ichan->channelFlags = CHANNEL_5GHZ | CHANNEL_OFDM;
@@ -158,37 +158,6 @@
 }
 EXPORT_SYMBOL(ath9k_cmn_count_streams);
 
-/*
- * Configures appropriate weight based on stomp type.
- */
-void ath9k_cmn_btcoex_bt_stomp(struct ath_common *common,
-				  enum ath_stomp_type stomp_type)
-{
-	struct ath_hw *ah = common->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_dbg(common, ATH_DBG_BTCOEX,
-			"Invalid Stomptype\n");
-		break;
-	}
-
-	ath9k_hw_btcoex_enable(ah);
-}
-EXPORT_SYMBOL(ath9k_cmn_btcoex_bt_stomp);
-
 void ath9k_cmn_update_txpow(struct ath_hw *ah, u16 cur_txpow,
 			    u16 new_txpow, u16 *txpower)
 {
diff -druN linux-2.6.39-libre/drivers/net/wireless/ath/ath9k/common.h linux-3.0-rc7-libre/drivers/net/wireless/ath/ath9k/common.h
--- linux-2.6.39-libre/drivers/net/wireless/ath/ath9k/common.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/ath/ath9k/common.h	2011-07-11 19:51:52.000000000 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009 Atheros Communications Inc.
+ * Copyright (c) 2009-2011 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
@@ -50,14 +50,6 @@
 #define ATH_EP_RND(x, mul) 						\
 	((((x)%(mul)) >= ((mul)/2)) ? ((x) + ((mul) - 1)) / (mul) : (x)/(mul))
 
-/* Defines the BT AR_BT_COEX_WGHT used */
-enum ath_stomp_type {
-	ATH_BTCOEX_NO_STOMP,
-	ATH_BTCOEX_STOMP_ALL,
-	ATH_BTCOEX_STOMP_LOW,
-	ATH_BTCOEX_STOMP_NONE
-};
-
 int ath9k_cmn_padpos(__le16 frame_control);
 int ath9k_cmn_get_hw_crypto_keytype(struct sk_buff *skb);
 void ath9k_cmn_update_ichannel(struct ath9k_channel *ichan,
diff -druN linux-2.6.39-libre/drivers/net/wireless/ath/ath9k/debug.c linux-3.0-rc7-libre/drivers/net/wireless/ath/ath9k/debug.c
--- linux-2.6.39-libre/drivers/net/wireless/ath/ath9k/debug.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/ath/ath9k/debug.c	2011-07-11 19:51:52.000000000 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008-2009 Atheros Communications Inc.
+ * Copyright (c) 2008-2011 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
@@ -326,6 +326,8 @@
 		sc->debug.stats.istats.dtimsync++;
 	if (status & ATH9K_INT_DTIM)
 		sc->debug.stats.istats.dtim++;
+	if (status & ATH9K_INT_TSFOOR)
+		sc->debug.stats.istats.tsfoor++;
 }
 
 static ssize_t read_file_interrupt(struct file *file, char __user *user_buf,
@@ -380,8 +382,11 @@
 	len += snprintf(buf + len, sizeof(buf) - len,
 		"%8s: %10u\n", "DTIM", sc->debug.stats.istats.dtim);
 	len += snprintf(buf + len, sizeof(buf) - len,
+		"%8s: %10u\n", "TSFOOR", sc->debug.stats.istats.tsfoor);
+	len += snprintf(buf + len, sizeof(buf) - len,
 		"%8s: %10u\n", "TOTAL", sc->debug.stats.istats.total);
 
+
 	if (len > sizeof(buf))
 		len = sizeof(buf);
 
@@ -430,6 +435,7 @@
 			conf->channel_type,
 			channel_type_str(conf->channel_type));
 
+	ath9k_ps_wakeup(sc);
 	put_unaligned_le32(REG_READ_D(sc->sc_ah, AR_STA_ID0), addr);
 	put_unaligned_le16(REG_READ_D(sc->sc_ah, AR_STA_ID1) & 0xffff, addr + 4);
 	len += snprintf(buf + len, sizeof(buf) - len,
@@ -439,6 +445,7 @@
 	len += snprintf(buf + len, sizeof(buf) - len,
 			"addrmask: %pM\n", addr);
 	tmp = ath9k_hw_getrxfilter(sc->sc_ah);
+	ath9k_ps_restore(sc);
 	len += snprintf(buf + len, sizeof(buf) - len,
 			"rfilt: 0x%x", tmp);
 	if (tmp & ATH9K_RX_FILTER_UCAST)
@@ -720,6 +727,7 @@
 		break;
 	}
 
+	ath9k_ps_wakeup(sc);
 	len += snprintf(buf + len, size - len,
 			"curbssid: %pM\n"
 			"OP-Mode: %s(%i)\n"
@@ -729,6 +737,7 @@
 			REG_READ(ah, AR_BEACON_PERIOD));
 
 	reg = REG_READ(ah, AR_TIMER_MODE);
+	ath9k_ps_restore(sc);
 	len += snprintf(buf + len, size - len, "Timer-Mode-Register: 0x%x (",
 			reg);
 	if (reg & AR_TBTT_TIMER_EN)
@@ -845,7 +854,7 @@
 
 	struct ath_softc *sc = file->private_data;
 	char *buf;
-	unsigned int len = 0, size = 1152;
+	unsigned int len = 0, size = 1400;
 	ssize_t retval = 0;
 
 	buf = kzalloc(size, GFP_KERNEL);
@@ -874,6 +883,34 @@
 			"%18s : %10u\n", "DECRYPT BUSY ERR",
 			sc->debug.stats.rxstats.decrypt_busy_err);
 
+	len += snprintf(buf + len, size - len,
+			"%18s : %10d\n", "RSSI-CTL0",
+			sc->debug.stats.rxstats.rs_rssi_ctl0);
+
+	len += snprintf(buf + len, size - len,
+			"%18s : %10d\n", "RSSI-CTL1",
+			sc->debug.stats.rxstats.rs_rssi_ctl1);
+
+	len += snprintf(buf + len, size - len,
+			"%18s : %10d\n", "RSSI-CTL2",
+			sc->debug.stats.rxstats.rs_rssi_ctl2);
+
+	len += snprintf(buf + len, size - len,
+			"%18s : %10d\n", "RSSI-EXT0",
+			sc->debug.stats.rxstats.rs_rssi_ext0);
+
+	len += snprintf(buf + len, size - len,
+			"%18s : %10d\n", "RSSI-EXT1",
+			sc->debug.stats.rxstats.rs_rssi_ext1);
+
+	len += snprintf(buf + len, size - len,
+			"%18s : %10d\n", "RSSI-EXT2",
+			sc->debug.stats.rxstats.rs_rssi_ext2);
+
+	len += snprintf(buf + len, size - len,
+			"%18s : %10d\n", "Rx Antenna",
+			sc->debug.stats.rxstats.rs_antenna);
+
 	PHY_ERR("UNDERRUN", ATH9K_PHYERR_UNDERRUN);
 	PHY_ERR("TIMING", ATH9K_PHYERR_TIMING);
 	PHY_ERR("PARITY", ATH9K_PHYERR_PARITY);
@@ -948,6 +985,16 @@
 		RX_PHY_ERR_INC(phyerr);
 	}
 
+	sc->debug.stats.rxstats.rs_rssi_ctl0 = rs->rs_rssi_ctl0;
+	sc->debug.stats.rxstats.rs_rssi_ctl1 = rs->rs_rssi_ctl1;
+	sc->debug.stats.rxstats.rs_rssi_ctl2 = rs->rs_rssi_ctl2;
+
+	sc->debug.stats.rxstats.rs_rssi_ext0 = rs->rs_rssi_ext0;
+	sc->debug.stats.rxstats.rs_rssi_ext1 = rs->rs_rssi_ext1;
+	sc->debug.stats.rxstats.rs_rssi_ext2 = rs->rs_rssi_ext2;
+
+	sc->debug.stats.rxstats.rs_antenna = rs->rs_antenna;
+
 #undef RX_STAT_INC
 #undef RX_PHY_ERR_INC
 }
@@ -1007,7 +1054,9 @@
 	unsigned int len;
 	u32 regval;
 
+	ath9k_ps_wakeup(sc);
 	regval = REG_READ_D(ah, sc->debug.regidx);
+	ath9k_ps_restore(sc);
 	len = sprintf(buf, "0x%08x\n", regval);
 	return simple_read_from_buffer(user_buf, count, ppos, buf, len);
 }
@@ -1029,7 +1078,9 @@
 	if (strict_strtoul(buf, 0, &regval))
 		return -EINVAL;
 
+	ath9k_ps_wakeup(sc);
 	REG_WRITE_D(ah, sc->debug.regidx, regval);
+	ath9k_ps_restore(sc);
 	return count;
 }
 
@@ -1088,67 +1139,43 @@
 		return -ENOMEM;
 
 #ifdef CONFIG_ATH_DEBUG
-	if (!debugfs_create_file("debug", S_IRUSR | S_IWUSR,
-			sc->debug.debugfs_phy, sc, &fops_debug))
-		goto err;
+	debugfs_create_file("debug", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy,
+			    sc, &fops_debug);
 #endif
+	debugfs_create_file("dma", S_IRUSR, sc->debug.debugfs_phy, sc,
+			    &fops_dma);
+	debugfs_create_file("interrupt", S_IRUSR, sc->debug.debugfs_phy, sc,
+			    &fops_interrupt);
+	debugfs_create_file("wiphy", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy,
+			    sc, &fops_wiphy);
+	debugfs_create_file("xmit", S_IRUSR, sc->debug.debugfs_phy, sc,
+			    &fops_xmit);
+	debugfs_create_file("stations", S_IRUSR, sc->debug.debugfs_phy, sc,
+			    &fops_stations);
+	debugfs_create_file("misc", S_IRUSR, sc->debug.debugfs_phy, sc,
+			    &fops_misc);
+	debugfs_create_file("recv", S_IRUSR, sc->debug.debugfs_phy, sc,
+			    &fops_recv);
+	debugfs_create_file("rx_chainmask", S_IRUSR | S_IWUSR,
+			    sc->debug.debugfs_phy, sc, &fops_rx_chainmask);
+	debugfs_create_file("tx_chainmask", S_IRUSR | S_IWUSR,
+			    sc->debug.debugfs_phy, sc, &fops_tx_chainmask);
+	debugfs_create_file("regidx", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy,
+			    sc, &fops_regidx);
+	debugfs_create_file("regval", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy,
+			    sc, &fops_regval);
+	debugfs_create_bool("ignore_extcca", S_IRUSR | S_IWUSR,
+			    sc->debug.debugfs_phy,
+			    &ah->config.cwm_ignore_extcca);
+	debugfs_create_file("regdump", S_IRUSR, sc->debug.debugfs_phy, sc,
+			    &fops_regdump);
 
-	if (!debugfs_create_file("dma", S_IRUSR, sc->debug.debugfs_phy,
-			sc, &fops_dma))
-		goto err;
-
-	if (!debugfs_create_file("interrupt", S_IRUSR, sc->debug.debugfs_phy,
-			sc, &fops_interrupt))
-		goto err;
-
-	if (!debugfs_create_file("wiphy", S_IRUSR | S_IWUSR,
-			sc->debug.debugfs_phy, sc, &fops_wiphy))
-		goto err;
-
-	if (!debugfs_create_file("xmit", S_IRUSR, sc->debug.debugfs_phy,
-			sc, &fops_xmit))
-		goto err;
-
-	if (!debugfs_create_file("stations", S_IRUSR, sc->debug.debugfs_phy,
-			sc, &fops_stations))
-		goto err;
-
-	if (!debugfs_create_file("misc", S_IRUSR, sc->debug.debugfs_phy,
-			sc, &fops_misc))
-		goto err;
-
-	if (!debugfs_create_file("recv", S_IRUSR, sc->debug.debugfs_phy,
-			sc, &fops_recv))
-		goto err;
-
-	if (!debugfs_create_file("rx_chainmask", S_IRUSR | S_IWUSR,
-			sc->debug.debugfs_phy, sc, &fops_rx_chainmask))
-		goto err;
-
-	if (!debugfs_create_file("tx_chainmask", S_IRUSR | S_IWUSR,
-			sc->debug.debugfs_phy, sc, &fops_tx_chainmask))
-		goto err;
-
-	if (!debugfs_create_file("regidx", S_IRUSR | S_IWUSR,
-			sc->debug.debugfs_phy, sc, &fops_regidx))
-		goto err;
-
-	if (!debugfs_create_file("regval", S_IRUSR | S_IWUSR,
-			sc->debug.debugfs_phy, sc, &fops_regval))
-		goto err;
-
-	if (!debugfs_create_bool("ignore_extcca", S_IRUSR | S_IWUSR,
-			sc->debug.debugfs_phy, &ah->config.cwm_ignore_extcca))
-		goto err;
+	debugfs_create_u32("gpio_mask", S_IRUSR | S_IWUSR,
+			   sc->debug.debugfs_phy, &sc->sc_ah->gpio_mask);
 
-	if (!debugfs_create_file("regdump", S_IRUSR, sc->debug.debugfs_phy,
-			sc, &fops_regdump))
-		goto err;
+	debugfs_create_u32("gpio_val", S_IRUSR | S_IWUSR,
+			   sc->debug.debugfs_phy, &sc->sc_ah->gpio_val);
 
 	sc->debug.regidx = 0;
 	return 0;
-err:
-	debugfs_remove_recursive(sc->debug.debugfs_phy);
-	sc->debug.debugfs_phy = NULL;
-	return -ENOMEM;
 }
diff -druN linux-2.6.39-libre/drivers/net/wireless/ath/ath9k/debug.h linux-3.0-rc7-libre/drivers/net/wireless/ath/ath9k/debug.h
--- linux-2.6.39-libre/drivers/net/wireless/ath/ath9k/debug.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/ath/ath9k/debug.h	2011-07-11 19:51:52.000000000 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008-2009 Atheros Communications Inc.
+ * Copyright (c) 2008-2011 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
@@ -54,6 +54,9 @@
  * @dtimsync: DTIM sync lossage
  * @dtim: RX Beacon with DTIM
  * @bb_watchdog: Baseband watchdog
+ * @tsfoor: TSF out of range, indicates that the corrected TSF received
+ * from a beacon differs from the PCU's internal TSF by more than a
+ * (programmable) threshold
  */
 struct ath_interrupt_stats {
 	u32 total;
@@ -78,6 +81,7 @@
 	u32 dtimsync;
 	u32 dtim;
 	u32 bb_watchdog;
+	u32 tsfoor;
 };
 
 /**
@@ -157,6 +161,13 @@
 	u32 post_delim_crc_err;
 	u32 decrypt_busy_err;
 	u32 phy_err_stats[ATH9K_PHYERR_MAX];
+	int8_t rs_rssi_ctl0;
+	int8_t rs_rssi_ctl1;
+	int8_t rs_rssi_ctl2;
+	int8_t rs_rssi_ext0;
+	int8_t rs_rssi_ext1;
+	int8_t rs_rssi_ext2;
+	u8 rs_antenna;
 };
 
 struct ath_stats {
diff -druN linux-2.6.39-libre/drivers/net/wireless/ath/ath9k/eeprom_4k.c linux-3.0-rc7-libre/drivers/net/wireless/ath/ath9k/eeprom_4k.c
--- linux-2.6.39-libre/drivers/net/wireless/ath/ath9k/eeprom_4k.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/ath/ath9k/eeprom_4k.c	2011-07-11 19:51:52.000000000 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008-2009 Atheros Communications Inc.
+ * Copyright (c) 2008-2011 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
@@ -781,6 +781,7 @@
 {
 	struct modal_eep_4k_header *pModal;
 	struct ar5416_eeprom_4k *eep = &ah->eeprom.map4k;
+	struct base_eep_header_4k *pBase = &eep->baseEepHeader;
 	u8 txRxAttenLocal;
 	u8 ob[5], db1[5], db2[5];
 	u8 ant_div_control1, ant_div_control2;
@@ -1003,6 +1004,31 @@
 				      AR_PHY_SETTLING_SWITCH,
 				      pModal->swSettleHt40);
 	}
+	if (AR_SREV_9271(ah) || AR_SREV_9285(ah)) {
+		u8 bb_desired_scale = (pModal->bb_scale_smrt_antenna &
+				EEP_4K_BB_DESIRED_SCALE_MASK);
+		if ((pBase->txGainType == 0) && (bb_desired_scale != 0)) {
+			u32 pwrctrl, mask, clr;
+
+			mask = BIT(0)|BIT(5)|BIT(10)|BIT(15)|BIT(20)|BIT(25);
+			pwrctrl = mask * bb_desired_scale;
+			clr = mask * 0x1f;
+			REG_RMW(ah, AR_PHY_TX_PWRCTRL8, pwrctrl, clr);
+			REG_RMW(ah, AR_PHY_TX_PWRCTRL10, pwrctrl, clr);
+			REG_RMW(ah, AR_PHY_CH0_TX_PWRCTRL12, pwrctrl, clr);
+
+			mask = BIT(0)|BIT(5)|BIT(15);
+			pwrctrl = mask * bb_desired_scale;
+			clr = mask * 0x1f;
+			REG_RMW(ah, AR_PHY_TX_PWRCTRL9, pwrctrl, clr);
+
+			mask = BIT(0)|BIT(5);
+			pwrctrl = mask * bb_desired_scale;
+			clr = mask * 0x1f;
+			REG_RMW(ah, AR_PHY_CH0_TX_PWRCTRL11, pwrctrl, clr);
+			REG_RMW(ah, AR_PHY_CH0_TX_PWRCTRL13, pwrctrl, clr);
+		}
+	}
 }
 
 static u16 ath9k_hw_4k_get_spur_channel(struct ath_hw *ah, u16 i, bool is2GHz)
diff -druN linux-2.6.39-libre/drivers/net/wireless/ath/ath9k/eeprom_9287.c linux-3.0-rc7-libre/drivers/net/wireless/ath/ath9k/eeprom_9287.c
--- linux-2.6.39-libre/drivers/net/wireless/ath/ath9k/eeprom_9287.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/ath/ath9k/eeprom_9287.c	2011-07-11 19:51:52.000000000 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008-2009 Atheros Communications Inc.
+ * Copyright (c) 2008-2011 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
@@ -319,10 +319,9 @@
 	u16 numXpdGain, xpdMask;
 	u16 xpdGainValues[AR5416_NUM_PD_GAINS] = {0, 0, 0, 0};
 	u32 reg32, regOffset, regChainOffset, regval;
-	int16_t modalIdx, diff = 0;
+	int16_t diff = 0;
 	struct ar9287_eeprom *pEepData = &ah->eeprom.map9287;
 
-	modalIdx = IS_CHAN_2GHZ(chan) ? 1 : 0;
 	xpdMask = pEepData->modalHeader.xpdGain;
 
 	if ((pEepData->baseEepHeader.version & AR9287_EEP_VER_MINOR_MASK) >=
@@ -392,6 +391,8 @@
 							   numXpdGain);
 			}
 
+			ENABLE_REGWRITE_BUFFER(ah);
+
 			if (i == 0) {
 				if (!ath9k_hw_ar9287_get_eeprom(ah,
 							EEP_OL_PWRCTRL)) {
@@ -442,6 +443,7 @@
 					regOffset += 4;
 				}
 			}
+			REGWRITE_BUFFER_FLUSH(ah);
 		}
 	}
 
@@ -522,10 +524,16 @@
 	case 1:
 		break;
 	case 2:
-		scaledPower -= REDUCE_SCALED_POWER_BY_TWO_CHAIN;
+		if (scaledPower > REDUCE_SCALED_POWER_BY_TWO_CHAIN)
+			scaledPower -= REDUCE_SCALED_POWER_BY_TWO_CHAIN;
+		else
+			scaledPower = 0;
 		break;
 	case 3:
-		scaledPower -= REDUCE_SCALED_POWER_BY_THREE_CHAIN;
+		if (scaledPower > REDUCE_SCALED_POWER_BY_THREE_CHAIN)
+			scaledPower -= REDUCE_SCALED_POWER_BY_THREE_CHAIN;
+		else
+			scaledPower = 0;
 		break;
 	}
 	scaledPower = max((u16)0, scaledPower);
@@ -757,6 +765,8 @@
 			ratesArray[i] -= AR9287_PWR_TABLE_OFFSET_DB * 2;
 	}
 
+	ENABLE_REGWRITE_BUFFER(ah);
+
 	/* OFDM power per rate */
 	REG_WRITE(ah, AR_PHY_POWER_TX_RATE1,
 		  ATH9K_POW_SM(ratesArray[rate18mb], 24)
@@ -840,6 +850,7 @@
 			  | ATH9K_POW_SM(ratesArray[rateDupOfdm], 8)
 			  | ATH9K_POW_SM(ratesArray[rateDupCck], 0));
 	}
+	REGWRITE_BUFFER_FLUSH(ah);
 }
 
 static void ath9k_hw_ar9287_set_addac(struct ath_hw *ah,
@@ -852,35 +863,12 @@
 {
 	struct ar9287_eeprom *eep = &ah->eeprom.map9287;
 	struct modal_eep_ar9287_header *pModal = &eep->modalHeader;
-	u16 antWrites[AR9287_ANT_16S];
 	u32 regChainOffset, regval;
 	u8 txRxAttenLocal;
-	int i, j, offset_num;
+	int i;
 
 	pModal = &eep->modalHeader;
 
-	antWrites[0] = (u16)((pModal->antCtrlCommon >> 28) & 0xF);
-	antWrites[1] = (u16)((pModal->antCtrlCommon >> 24) & 0xF);
-	antWrites[2] = (u16)((pModal->antCtrlCommon >> 20) & 0xF);
-	antWrites[3] = (u16)((pModal->antCtrlCommon >> 16) & 0xF);
-	antWrites[4] = (u16)((pModal->antCtrlCommon >> 12) & 0xF);
-	antWrites[5] = (u16)((pModal->antCtrlCommon >> 8) & 0xF);
-	antWrites[6] = (u16)((pModal->antCtrlCommon >> 4)  & 0xF);
-	antWrites[7] = (u16)(pModal->antCtrlCommon & 0xF);
-
-	offset_num = 8;
-
-	for (i = 0, j = offset_num; i < AR9287_MAX_CHAINS; i++) {
-		antWrites[j++] = (u16)((pModal->antCtrlChain[i] >> 28) & 0xf);
-		antWrites[j++] = (u16)((pModal->antCtrlChain[i] >> 10) & 0x3);
-		antWrites[j++] = (u16)((pModal->antCtrlChain[i] >> 8) & 0x3);
-		antWrites[j++] = 0;
-		antWrites[j++] = (u16)((pModal->antCtrlChain[i] >> 6) & 0x3);
-		antWrites[j++] = (u16)((pModal->antCtrlChain[i] >> 4) & 0x3);
-		antWrites[j++] = (u16)((pModal->antCtrlChain[i] >> 2) & 0x3);
-		antWrites[j++] = (u16)(pModal->antCtrlChain[i] & 0x3);
-	}
-
 	REG_WRITE(ah, AR_PHY_SWITCH_COM, pModal->antCtrlCommon);
 
 	for (i = 0; i < AR9287_MAX_CHAINS; i++)	{
diff -druN linux-2.6.39-libre/drivers/net/wireless/ath/ath9k/eeprom.c linux-3.0-rc7-libre/drivers/net/wireless/ath/ath9k/eeprom.c
--- linux-2.6.39-libre/drivers/net/wireless/ath/ath9k/eeprom.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/ath/ath9k/eeprom.c	2011-07-11 19:51:52.000000000 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008-2009 Atheros Communications Inc.
+ * Copyright (c) 2008-2011 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
diff -druN linux-2.6.39-libre/drivers/net/wireless/ath/ath9k/eeprom_def.c linux-3.0-rc7-libre/drivers/net/wireless/ath/ath9k/eeprom_def.c
--- linux-2.6.39-libre/drivers/net/wireless/ath/ath9k/eeprom_def.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/ath/ath9k/eeprom_def.c	2011-07-11 19:51:52.000000000 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008-2009 Atheros Communications Inc.
+ * Copyright (c) 2008-2011 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
@@ -231,6 +231,10 @@
 				integer = swab32(pModal->antCtrlChain[i]);
 				pModal->antCtrlChain[i] = integer;
 			}
+			for (i = 0; i < 3; i++) {
+				word = swab16(pModal->xpaBiasLvlFreq[i]);
+				pModal->xpaBiasLvlFreq[i] = word;
+			}
 
 			for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) {
 				word = swab16(pModal->spurChans[i].spurChan);
@@ -799,6 +803,8 @@
 							   pwr_table_offset,
 							   &diff);
 
+			ENABLE_REGWRITE_BUFFER(ah);
+
 			if ((i == 0) || AR_SREV_5416_20_OR_LATER(ah)) {
 				if (OLC_FOR_AR9280_20_LATER) {
 					REG_WRITE(ah,
@@ -847,6 +853,7 @@
 
 				regOffset += 4;
 			}
+			REGWRITE_BUFFER_FLUSH(ah);
 		}
 	}
 
@@ -1205,6 +1212,8 @@
 		}
 	}
 
+	ENABLE_REGWRITE_BUFFER(ah);
+
 	REG_WRITE(ah, AR_PHY_POWER_TX_RATE1,
 		  ATH9K_POW_SM(ratesArray[rate18mb], 24)
 		  | ATH9K_POW_SM(ratesArray[rate12mb], 16)
@@ -1291,6 +1300,8 @@
 	REG_WRITE(ah, AR_PHY_POWER_TX_SUB,
 		  ATH9K_POW_SM(pModal->pwrDecreaseFor3Chain, 6)
 		  | ATH9K_POW_SM(pModal->pwrDecreaseFor2Chain, 0));
+
+	REGWRITE_BUFFER_FLUSH(ah);
 }
 
 static u16 ath9k_hw_def_get_spur_channel(struct ath_hw *ah, u16 i, bool is2GHz)
diff -druN linux-2.6.39-libre/drivers/net/wireless/ath/ath9k/eeprom.h linux-3.0-rc7-libre/drivers/net/wireless/ath/ath9k/eeprom.h
--- linux-2.6.39-libre/drivers/net/wireless/ath/ath9k/eeprom.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/ath/ath9k/eeprom.h	2011-07-11 19:51:52.000000000 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008-2009 Atheros Communications Inc.
+ * Copyright (c) 2008-2011 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
@@ -436,7 +436,11 @@
 	u8 db2_2:4, db2_3:4;
 	u8 db2_4:4, reserved:4;
 #endif
-	u8 futureModal[4];
+	u8 tx_diversity;
+	u8 flc_pwr_thresh;
+	u8 bb_scale_smrt_antenna;
+#define EEP_4K_BB_DESIRED_SCALE_MASK	0x1f
+	u8 futureModal[1];
 	struct spur_chan spurChans[AR_EEPROM_MODAL_SPURS];
 } __packed;
 
diff -druN linux-2.6.39-libre/drivers/net/wireless/ath/ath9k/gpio.c linux-3.0-rc7-libre/drivers/net/wireless/ath/ath9k/gpio.c
--- linux-2.6.39-libre/drivers/net/wireless/ath/ath9k/gpio.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/ath/ath9k/gpio.c	2011-07-11 19:51:52.000000000 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008-2009 Atheros Communications Inc.
+ * Copyright (c) 2008-2011 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
@@ -41,12 +41,16 @@
 {
 	int ret;
 
-	if (AR_SREV_9287(sc->sc_ah))
-		sc->sc_ah->led_pin = ATH_LED_PIN_9287;
-	else if (AR_SREV_9485(sc->sc_ah))
-		sc->sc_ah->led_pin = ATH_LED_PIN_9485;
-	else
-		sc->sc_ah->led_pin = ATH_LED_PIN_DEF;
+	if (sc->sc_ah->led_pin < 0) {
+		if (AR_SREV_9287(sc->sc_ah))
+			sc->sc_ah->led_pin = ATH_LED_PIN_9287;
+		else if (AR_SREV_9485(sc->sc_ah))
+			sc->sc_ah->led_pin = ATH_LED_PIN_9485;
+		else if (AR_SREV_9300(sc->sc_ah))
+			sc->sc_ah->led_pin = ATH_LED_PIN_9300;
+		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,
@@ -136,10 +140,10 @@
 
 static void ath9k_gen_timer_start(struct ath_hw *ah,
 				  struct ath_gen_timer *timer,
-				  u32 timer_next,
+				  u32 trig_timeout,
 				  u32 timer_period)
 {
-	ath9k_hw_gen_timer_start(ah, timer, timer_next, timer_period);
+	ath9k_hw_gen_timer_start(ah, timer, trig_timeout, timer_period);
 
 	if ((ah->imask & ATH9K_INT_GENTIMER) == 0) {
 		ath9k_hw_disable_interrupts(ah);
@@ -172,17 +176,17 @@
 	struct ath_softc *sc = (struct ath_softc *) data;
 	struct ath_hw *ah = sc->sc_ah;
 	struct ath_btcoex *btcoex = &sc->btcoex;
-	struct ath_common *common = ath9k_hw_common(ah);
 	u32 timer_period;
 	bool is_btscan;
 
+	ath9k_ps_wakeup(sc);
 	ath_detect_bt_priority(sc);
 
 	is_btscan = sc->sc_flags & SC_OP_BT_SCAN;
 
 	spin_lock_bh(&btcoex->btcoex_lock);
 
-	ath9k_cmn_btcoex_bt_stomp(common, is_btscan ? ATH_BTCOEX_STOMP_ALL :
+	ath9k_hw_btcoex_bt_stomp(ah, is_btscan ? ATH_BTCOEX_STOMP_ALL :
 			      btcoex->bt_stomp_type);
 
 	spin_unlock_bh(&btcoex->btcoex_lock);
@@ -193,11 +197,12 @@
 
 		timer_period = is_btscan ? btcoex->btscan_no_stomp :
 					   btcoex->btcoex_no_stomp;
-		ath9k_gen_timer_start(ah, btcoex->no_stomp_timer, 0,
+		ath9k_gen_timer_start(ah, btcoex->no_stomp_timer, timer_period,
 				      timer_period * 10);
 		btcoex->hw_timer_enabled = true;
 	}
 
+	ath9k_ps_restore(sc);
 	mod_timer(&btcoex->period_timer, jiffies +
 				  msecs_to_jiffies(ATH_BTCOEX_DEF_BT_PERIOD));
 }
@@ -217,14 +222,16 @@
 	ath_dbg(common, ATH_DBG_BTCOEX,
 		"no stomp timer running\n");
 
+	ath9k_ps_wakeup(sc);
 	spin_lock_bh(&btcoex->btcoex_lock);
 
 	if (btcoex->bt_stomp_type == ATH_BTCOEX_STOMP_LOW || is_btscan)
-		ath9k_cmn_btcoex_bt_stomp(common, ATH_BTCOEX_STOMP_NONE);
+		ath9k_hw_btcoex_bt_stomp(ah, ATH_BTCOEX_STOMP_NONE);
 	 else if (btcoex->bt_stomp_type == ATH_BTCOEX_STOMP_ALL)
-		ath9k_cmn_btcoex_bt_stomp(common, ATH_BTCOEX_STOMP_LOW);
+		ath9k_hw_btcoex_bt_stomp(ah, ATH_BTCOEX_STOMP_LOW);
 
 	spin_unlock_bh(&btcoex->btcoex_lock);
+	ath9k_ps_restore(sc);
 }
 
 int ath_init_btcoex_timer(struct ath_softc *sc)
diff -druN linux-2.6.39-libre/drivers/net/wireless/ath/ath9k/hif_usb.c linux-3.0-rc7-libre/drivers/net/wireless/ath/ath9k/hif_usb.c
--- linux-2.6.39-libre/drivers/net/wireless/ath/ath9k/hif_usb.c	2011-05-19 02:15:07.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/ath/ath9k/hif_usb.c	2011-07-21 06:57:31.000000000 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010 Atheros Communications Inc.
+ * Copyright (c) 2010-2011 Atheros Communications Inc.
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
@@ -17,9 +17,8 @@
 #include "htc.h"
 
 /* identify firmware images */
-#define FIRMWARE_AR7010		"/*(DEBLOBBED)*/"
-#define FIRMWARE_AR7010_1_1	"/*(DEBLOBBED)*/"
-#define FIRMWARE_AR9271		"/*(DEBLOBBED)*/"
+#define FIRMWARE_AR7010_1_1     "/*(DEBLOBBED)*/"
+#define FIRMWARE_AR9271         "/*(DEBLOBBED)*/"
 
 /*(DEBLOBBED)*/
 
@@ -78,7 +77,7 @@
 
 	if (cmd) {
 		ath9k_htc_txcompletion_cb(cmd->hif_dev->htc_handle,
-					  cmd->skb, 1);
+					  cmd->skb, true);
 		kfree(cmd);
 	}
 
@@ -124,6 +123,90 @@
 	return ret;
 }
 
+static void hif_usb_mgmt_cb(struct urb *urb)
+{
+	struct cmd_buf *cmd = (struct cmd_buf *)urb->context;
+	struct hif_device_usb *hif_dev = cmd->hif_dev;
+	bool txok = true;
+
+	if (!cmd || !cmd->skb || !cmd->hif_dev)
+		return;
+
+	switch (urb->status) {
+	case 0:
+		break;
+	case -ENOENT:
+	case -ECONNRESET:
+	case -ENODEV:
+	case -ESHUTDOWN:
+		txok = false;
+
+		/*
+		 * If the URBs are being flushed, no need to complete
+		 * this packet.
+		 */
+		spin_lock(&hif_dev->tx.tx_lock);
+		if (hif_dev->tx.flags & HIF_USB_TX_FLUSH) {
+			spin_unlock(&hif_dev->tx.tx_lock);
+			dev_kfree_skb_any(cmd->skb);
+			kfree(cmd);
+			return;
+		}
+		spin_unlock(&hif_dev->tx.tx_lock);
+
+		break;
+	default:
+		txok = false;
+		break;
+	}
+
+	skb_pull(cmd->skb, 4);
+	ath9k_htc_txcompletion_cb(cmd->hif_dev->htc_handle,
+				  cmd->skb, txok);
+	kfree(cmd);
+}
+
+static int hif_usb_send_mgmt(struct hif_device_usb *hif_dev,
+			     struct sk_buff *skb)
+{
+	struct urb *urb;
+	struct cmd_buf *cmd;
+	int ret = 0;
+	__le16 *hdr;
+
+	urb = usb_alloc_urb(0, GFP_ATOMIC);
+	if (urb == NULL)
+		return -ENOMEM;
+
+	cmd = kzalloc(sizeof(*cmd), GFP_ATOMIC);
+	if (cmd == NULL) {
+		usb_free_urb(urb);
+		return -ENOMEM;
+	}
+
+	cmd->skb = skb;
+	cmd->hif_dev = hif_dev;
+
+	hdr = (__le16 *) skb_push(skb, 4);
+	*hdr++ = cpu_to_le16(skb->len - 4);
+	*hdr++ = cpu_to_le16(ATH_USB_TX_STREAM_MODE_TAG);
+
+	usb_fill_bulk_urb(urb, hif_dev->udev,
+			 usb_sndbulkpipe(hif_dev->udev, USB_WLAN_TX_PIPE),
+			 skb->data, skb->len,
+			 hif_usb_mgmt_cb, cmd);
+
+	usb_anchor_urb(urb, &hif_dev->mgmt_submitted);
+	ret = usb_submit_urb(urb, GFP_ATOMIC);
+	if (ret) {
+		usb_unanchor_urb(urb);
+		kfree(cmd);
+	}
+	usb_free_urb(urb);
+
+	return ret;
+}
+
 static inline void ath9k_skb_queue_purge(struct hif_device_usb *hif_dev,
 					 struct sk_buff_head *list)
 {
@@ -131,7 +214,22 @@
 
 	while ((skb = __skb_dequeue(list)) != NULL) {
 		dev_kfree_skb_any(skb);
-		TX_STAT_INC(skb_dropped);
+	}
+}
+
+static inline void ath9k_skb_queue_complete(struct hif_device_usb *hif_dev,
+					    struct sk_buff_head *queue,
+					    bool txok)
+{
+	struct sk_buff *skb;
+
+	while ((skb = __skb_dequeue(queue)) != NULL) {
+		ath9k_htc_txcompletion_cb(hif_dev->htc_handle,
+					  skb, txok);
+		if (txok)
+			TX_STAT_INC(skb_success);
+		else
+			TX_STAT_INC(skb_failed);
 	}
 }
 
@@ -139,7 +237,7 @@
 {
 	struct tx_buf *tx_buf = (struct tx_buf *) urb->context;
 	struct hif_device_usb *hif_dev;
-	struct sk_buff *skb;
+	bool txok = true;
 
 	if (!tx_buf || !tx_buf->hif_dev)
 		return;
@@ -153,10 +251,7 @@
 	case -ECONNRESET:
 	case -ENODEV:
 	case -ESHUTDOWN:
-		/*
-		 * The URB has been killed, free the SKBs.
-		 */
-		ath9k_skb_queue_purge(hif_dev, &tx_buf->skb_queue);
+		txok = false;
 
 		/*
 		 * If the URBs are being flushed, no need to add this
@@ -165,41 +260,19 @@
 		spin_lock(&hif_dev->tx.tx_lock);
 		if (hif_dev->tx.flags & HIF_USB_TX_FLUSH) {
 			spin_unlock(&hif_dev->tx.tx_lock);
+			ath9k_skb_queue_purge(hif_dev, &tx_buf->skb_queue);
 			return;
 		}
 		spin_unlock(&hif_dev->tx.tx_lock);
 
-		/*
-		 * In the stop() case, this URB has to be added to
-		 * the free list.
-		 */
-		goto add_free;
+		break;
 	default:
+		txok = false;
 		break;
 	}
 
-	/*
-	 * Check if TX has been stopped, this is needed because
-	 * this CB could have been invoked just after the TX lock
-	 * was released in hif_stop() and kill_urb() hasn't been
-	 * called yet.
-	 */
-	spin_lock(&hif_dev->tx.tx_lock);
-	if (hif_dev->tx.flags & HIF_USB_TX_STOP) {
-		spin_unlock(&hif_dev->tx.tx_lock);
-		ath9k_skb_queue_purge(hif_dev, &tx_buf->skb_queue);
-		goto add_free;
-	}
-	spin_unlock(&hif_dev->tx.tx_lock);
-
-	/* Complete the queued SKBs. */
-	while ((skb = __skb_dequeue(&tx_buf->skb_queue)) != NULL) {
-		ath9k_htc_txcompletion_cb(hif_dev->htc_handle,
-					  skb, 1);
-		TX_STAT_INC(skb_completed);
-	}
+	ath9k_skb_queue_complete(hif_dev, &tx_buf->skb_queue, txok);
 
-add_free:
 	/* Re-initialize the SKB queue */
 	tx_buf->len = tx_buf->offset = 0;
 	__skb_queue_head_init(&tx_buf->skb_queue);
@@ -272,7 +345,7 @@
 	ret = usb_submit_urb(tx_buf->urb, GFP_ATOMIC);
 	if (ret) {
 		tx_buf->len = tx_buf->offset = 0;
-		ath9k_skb_queue_purge(hif_dev, &tx_buf->skb_queue);
+		ath9k_skb_queue_complete(hif_dev, &tx_buf->skb_queue, false);
 		__skb_queue_head_init(&tx_buf->skb_queue);
 		list_move_tail(&tx_buf->list, &hif_dev->tx.tx_buf);
 		hif_dev->tx.tx_buf_cnt++;
@@ -284,10 +357,11 @@
 	return ret;
 }
 
-static int hif_usb_send_tx(struct hif_device_usb *hif_dev, struct sk_buff *skb,
-			   struct ath9k_htc_tx_ctl *tx_ctl)
+static int hif_usb_send_tx(struct hif_device_usb *hif_dev, struct sk_buff *skb)
 {
+	struct ath9k_htc_tx_ctl *tx_ctl;
 	unsigned long flags;
+	int ret = 0;
 
 	spin_lock_irqsave(&hif_dev->tx.tx_lock, flags);
 
@@ -302,26 +376,36 @@
 		return -ENOMEM;
 	}
 
-	__skb_queue_tail(&hif_dev->tx.tx_skb_queue, skb);
-	hif_dev->tx.tx_skb_cnt++;
+	spin_unlock_irqrestore(&hif_dev->tx.tx_lock, flags);
 
-	/* Send normal frames immediately */
-	if (!tx_ctl || (tx_ctl && (tx_ctl->type == ATH9K_HTC_NORMAL)))
-		__hif_usb_tx(hif_dev);
+	tx_ctl = HTC_SKB_CB(skb);
+
+	/* Mgmt/Beacon frames don't use the TX buffer pool */
+	if ((tx_ctl->type == ATH9K_HTC_MGMT) ||
+	    (tx_ctl->type == ATH9K_HTC_BEACON)) {
+		ret = hif_usb_send_mgmt(hif_dev, skb);
+	}
+
+	spin_lock_irqsave(&hif_dev->tx.tx_lock, flags);
+
+	if ((tx_ctl->type == ATH9K_HTC_NORMAL) ||
+	    (tx_ctl->type == ATH9K_HTC_AMPDU)) {
+		__skb_queue_tail(&hif_dev->tx.tx_skb_queue, skb);
+		hif_dev->tx.tx_skb_cnt++;
+	}
 
 	/* Check if AMPDUs have to be sent immediately */
-	if (tx_ctl && (tx_ctl->type == ATH9K_HTC_AMPDU) &&
-	    (hif_dev->tx.tx_buf_cnt == MAX_TX_URB_NUM) &&
+	if ((hif_dev->tx.tx_buf_cnt == MAX_TX_URB_NUM) &&
 	    (hif_dev->tx.tx_skb_cnt < 2)) {
 		__hif_usb_tx(hif_dev);
 	}
 
 	spin_unlock_irqrestore(&hif_dev->tx.tx_lock, flags);
 
-	return 0;
+	return ret;
 }
 
-static void hif_usb_start(void *hif_handle, u8 pipe_id)
+static void hif_usb_start(void *hif_handle)
 {
 	struct hif_device_usb *hif_dev = (struct hif_device_usb *)hif_handle;
 	unsigned long flags;
@@ -333,14 +417,14 @@
 	spin_unlock_irqrestore(&hif_dev->tx.tx_lock, flags);
 }
 
-static void hif_usb_stop(void *hif_handle, u8 pipe_id)
+static void hif_usb_stop(void *hif_handle)
 {
 	struct hif_device_usb *hif_dev = (struct hif_device_usb *)hif_handle;
 	struct tx_buf *tx_buf = NULL, *tx_buf_tmp = NULL;
 	unsigned long flags;
 
 	spin_lock_irqsave(&hif_dev->tx.tx_lock, flags);
-	ath9k_skb_queue_purge(hif_dev, &hif_dev->tx.tx_skb_queue);
+	ath9k_skb_queue_complete(hif_dev, &hif_dev->tx.tx_skb_queue, false);
 	hif_dev->tx.tx_skb_cnt = 0;
 	hif_dev->tx.flags |= HIF_USB_TX_STOP;
 	spin_unlock_irqrestore(&hif_dev->tx.tx_lock, flags);
@@ -350,17 +434,18 @@
 				 &hif_dev->tx.tx_pending, list) {
 		usb_kill_urb(tx_buf->urb);
 	}
+
+	usb_kill_anchored_urbs(&hif_dev->mgmt_submitted);
 }
 
-static int hif_usb_send(void *hif_handle, u8 pipe_id, struct sk_buff *skb,
-			struct ath9k_htc_tx_ctl *tx_ctl)
+static int hif_usb_send(void *hif_handle, u8 pipe_id, struct sk_buff *skb)
 {
 	struct hif_device_usb *hif_dev = (struct hif_device_usb *)hif_handle;
 	int ret = 0;
 
 	switch (pipe_id) {
 	case USB_WLAN_TX_PIPE:
-		ret = hif_usb_send_tx(hif_dev, skb, tx_ctl);
+		ret = hif_usb_send_tx(hif_dev, skb);
 		break;
 	case USB_REG_OUT_PIPE:
 		ret = hif_usb_send_regout(hif_dev, skb);
@@ -375,6 +460,40 @@
 	return ret;
 }
 
+static inline bool check_index(struct sk_buff *skb, u8 idx)
+{
+	struct ath9k_htc_tx_ctl *tx_ctl;
+
+	tx_ctl = HTC_SKB_CB(skb);
+
+	if ((tx_ctl->type == ATH9K_HTC_AMPDU) &&
+	    (tx_ctl->sta_idx == idx))
+		return true;
+
+	return false;
+}
+
+static void hif_usb_sta_drain(void *hif_handle, u8 idx)
+{
+	struct hif_device_usb *hif_dev = (struct hif_device_usb *)hif_handle;
+	struct sk_buff *skb, *tmp;
+	unsigned long flags;
+
+	spin_lock_irqsave(&hif_dev->tx.tx_lock, flags);
+
+	skb_queue_walk_safe(&hif_dev->tx.tx_skb_queue, skb, tmp) {
+		if (check_index(skb, idx)) {
+			__skb_unlink(skb, &hif_dev->tx.tx_skb_queue);
+			ath9k_htc_txcompletion_cb(hif_dev->htc_handle,
+						  skb, false);
+			hif_dev->tx.tx_skb_cnt--;
+			TX_STAT_INC(skb_failed);
+		}
+	}
+
+	spin_unlock_irqrestore(&hif_dev->tx.tx_lock, flags);
+}
+
 static struct ath9k_htc_hif hif_usb = {
 	.transport = ATH9K_HIF_USB,
 	.name = "ath9k_hif_usb",
@@ -384,6 +503,7 @@
 
 	.start = hif_usb_start,
 	.stop = hif_usb_stop,
+	.sta_drain = hif_usb_sta_drain,
 	.send = hif_usb_send,
 };
 
@@ -565,6 +685,9 @@
 	case -ESHUTDOWN:
 		goto free;
 	default:
+		skb_reset_tail_pointer(skb);
+		skb_trim(skb, 0);
+
 		goto resubmit;
 	}
 
@@ -589,23 +712,15 @@
 						 USB_REG_IN_PIPE),
 				 nskb->data, MAX_REG_IN_BUF_SIZE,
 				 ath9k_hif_usb_reg_in_cb, nskb);
-
-		ret = usb_submit_urb(urb, GFP_ATOMIC);
-		if (ret) {
-			kfree_skb(nskb);
-			urb->context = NULL;
-		}
-
-		return;
 	}
 
 resubmit:
-	skb_reset_tail_pointer(skb);
-	skb_trim(skb, 0);
-
+	usb_anchor_urb(urb, &hif_dev->reg_in_submitted);
 	ret = usb_submit_urb(urb, GFP_ATOMIC);
-	if (ret)
+	if (ret) {
+		usb_unanchor_urb(urb);
 		goto free;
+	}
 
 	return;
 free:
@@ -639,6 +754,8 @@
 		kfree(tx_buf->buf);
 		kfree(tx_buf);
 	}
+
+	usb_kill_anchored_urbs(&hif_dev->mgmt_submitted);
 }
 
 static int ath9k_hif_usb_alloc_tx_urbs(struct hif_device_usb *hif_dev)
@@ -650,6 +767,7 @@
 	INIT_LIST_HEAD(&hif_dev->tx.tx_pending);
 	spin_lock_init(&hif_dev->tx.tx_lock);
 	__skb_queue_head_init(&hif_dev->tx.tx_skb_queue);
+	init_usb_anchor(&hif_dev->mgmt_submitted);
 
 	for (i = 0; i < MAX_TX_URB_NUM; i++) {
 		tx_buf = kzalloc(sizeof(struct tx_buf), GFP_KERNEL);
@@ -746,43 +864,67 @@
 	return ret;
 }
 
-static void ath9k_hif_usb_dealloc_reg_in_urb(struct hif_device_usb *hif_dev)
+static void ath9k_hif_usb_dealloc_reg_in_urbs(struct hif_device_usb *hif_dev)
 {
-	if (hif_dev->reg_in_urb) {
-		usb_kill_urb(hif_dev->reg_in_urb);
-		if (hif_dev->reg_in_urb->context)
-			kfree_skb((void *)hif_dev->reg_in_urb->context);
-		usb_free_urb(hif_dev->reg_in_urb);
-		hif_dev->reg_in_urb = NULL;
-	}
+	usb_kill_anchored_urbs(&hif_dev->reg_in_submitted);
 }
 
-static int ath9k_hif_usb_alloc_reg_in_urb(struct hif_device_usb *hif_dev)
+static int ath9k_hif_usb_alloc_reg_in_urbs(struct hif_device_usb *hif_dev)
 {
-	struct sk_buff *skb;
+	struct urb *urb = NULL;
+	struct sk_buff *skb = NULL;
+	int i, ret;
 
-	hif_dev->reg_in_urb = usb_alloc_urb(0, GFP_KERNEL);
-	if (hif_dev->reg_in_urb == NULL)
-		return -ENOMEM;
+	init_usb_anchor(&hif_dev->reg_in_submitted);
 
-	skb = alloc_skb(MAX_REG_IN_BUF_SIZE, GFP_KERNEL);
-	if (!skb)
-		goto err;
+	for (i = 0; i < MAX_REG_IN_URB_NUM; i++) {
 
-	usb_fill_bulk_urb(hif_dev->reg_in_urb, hif_dev->udev,
-			 usb_rcvbulkpipe(hif_dev->udev,
-					 USB_REG_IN_PIPE),
-			 skb->data, MAX_REG_IN_BUF_SIZE,
-			 ath9k_hif_usb_reg_in_cb, skb);
+		/* Allocate URB */
+		urb = usb_alloc_urb(0, GFP_KERNEL);
+		if (urb == NULL) {
+			ret = -ENOMEM;
+			goto err_urb;
+		}
 
-	if (usb_submit_urb(hif_dev->reg_in_urb, GFP_KERNEL) != 0)
-		goto err;
+		/* Allocate buffer */
+		skb = alloc_skb(MAX_REG_IN_BUF_SIZE, GFP_KERNEL);
+		if (!skb) {
+			ret = -ENOMEM;
+			goto err_skb;
+		}
+
+		usb_fill_bulk_urb(urb, hif_dev->udev,
+				  usb_rcvbulkpipe(hif_dev->udev,
+						  USB_REG_IN_PIPE),
+				  skb->data, MAX_REG_IN_BUF_SIZE,
+				  ath9k_hif_usb_reg_in_cb, skb);
+
+		/* Anchor URB */
+		usb_anchor_urb(urb, &hif_dev->reg_in_submitted);
+
+		/* Submit URB */
+		ret = usb_submit_urb(urb, GFP_KERNEL);
+		if (ret) {
+			usb_unanchor_urb(urb);
+			goto err_submit;
+		}
+
+		/*
+		 * Drop reference count.
+		 * This ensures that the URB is freed when killing them.
+		 */
+		usb_free_urb(urb);
+	}
 
 	return 0;
 
-err:
-	ath9k_hif_usb_dealloc_reg_in_urb(hif_dev);
-	return -ENOMEM;
+err_submit:
+	kfree_skb(skb);
+err_skb:
+	usb_free_urb(urb);
+err_urb:
+	ath9k_hif_usb_dealloc_reg_in_urbs(hif_dev);
+	return ret;
 }
 
 static int ath9k_hif_usb_alloc_urbs(struct hif_device_usb *hif_dev)
@@ -799,7 +941,7 @@
 		goto err_rx;
 
 	/* Register Read */
-	if (ath9k_hif_usb_alloc_reg_in_urb(hif_dev) < 0)
+	if (ath9k_hif_usb_alloc_reg_in_urbs(hif_dev) < 0)
 		goto err_reg;
 
 	return 0;
@@ -814,7 +956,7 @@
 static void ath9k_hif_usb_dealloc_urbs(struct hif_device_usb *hif_dev)
 {
 	usb_kill_anchored_urbs(&hif_dev->regout_submitted);
-	ath9k_hif_usb_dealloc_reg_in_urb(hif_dev);
+	ath9k_hif_usb_dealloc_reg_in_urbs(hif_dev);
 	ath9k_hif_usb_dealloc_tx_urbs(hif_dev);
 	ath9k_hif_usb_dealloc_rx_urbs(hif_dev);
 }
@@ -1024,10 +1166,7 @@
 	/* Find out which firmware to load */
 
 	if (IS_AR7010_DEVICE(id->driver_info))
-		if (le16_to_cpu(udev->descriptor.bcdDevice) == 0x0202)
-			hif_dev->fw_name = FIRMWARE_AR7010_1_1;
-		else
-			hif_dev->fw_name = FIRMWARE_AR7010;
+		hif_dev->fw_name = FIRMWARE_AR7010_1_1;
 	else
 		hif_dev->fw_name = FIRMWARE_AR9271;
 
diff -druN linux-2.6.39-libre/drivers/net/wireless/ath/ath9k/hif_usb.h linux-3.0-rc7-libre/drivers/net/wireless/ath/ath9k/hif_usb.h
--- linux-2.6.39-libre/drivers/net/wireless/ath/ath9k/hif_usb.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/ath/ath9k/hif_usb.h	2011-07-11 19:51:52.000000000 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010 Atheros Communications Inc.
+ * Copyright (c) 2010-2011 Atheros Communications Inc.
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
@@ -17,6 +17,9 @@
 #ifndef HTC_USB_H
 #define HTC_USB_H
 
+#define MAJOR_VERSION_REQ 1
+#define MINOR_VERSION_REQ 3
+
 #define IS_AR7010_DEVICE(_v) (((_v) == AR9280_USB) || ((_v) == AR9287_USB))
 
 #define AR9271_FIRMWARE       0x501000
@@ -31,7 +34,7 @@
 
 /* FIXME: Verify these numbers (with Windows) */
 #define MAX_TX_URB_NUM  8
-#define MAX_TX_BUF_NUM  1024
+#define MAX_TX_BUF_NUM  256
 #define MAX_TX_BUF_SIZE 32768
 #define MAX_TX_AGGR_NUM 20
 
@@ -40,7 +43,7 @@
 #define MAX_PKT_NUM_IN_TRANSFER 10
 
 #define MAX_REG_OUT_URB_NUM  1
-#define MAX_REG_OUT_BUF_NUM  8
+#define MAX_REG_IN_URB_NUM   64
 
 #define MAX_REG_IN_BUF_SIZE 64
 
@@ -90,9 +93,10 @@
 	const struct firmware *firmware;
 	struct htc_target *htc_handle;
 	struct hif_usb_tx tx;
-	struct urb *reg_in_urb;
 	struct usb_anchor regout_submitted;
 	struct usb_anchor rx_submitted;
+	struct usb_anchor reg_in_submitted;
+	struct usb_anchor mgmt_submitted;
 	struct sk_buff *remain_skb;
 	const char *fw_name;
 	int rx_remain_len;
diff -druN linux-2.6.39-libre/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c linux-3.0-rc7-libre/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c
--- linux-2.6.39-libre/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c	2011-07-11 19:51:52.000000000 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010 Atheros Communications Inc.
+ * Copyright (c) 2010-2011 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
@@ -18,6 +18,50 @@
 
 #define FUDGE 2
 
+void ath9k_htc_beaconq_config(struct ath9k_htc_priv *priv)
+{
+	struct ath_hw *ah = priv->ah;
+	struct ath9k_tx_queue_info qi, qi_be;
+
+	memset(&qi, 0, sizeof(struct ath9k_tx_queue_info));
+	memset(&qi_be, 0, sizeof(struct ath9k_tx_queue_info));
+
+	ath9k_hw_get_txq_props(ah, priv->beaconq, &qi);
+
+	if (priv->ah->opmode == NL80211_IFTYPE_AP) {
+		qi.tqi_aifs = 1;
+		qi.tqi_cwmin = 0;
+		qi.tqi_cwmax = 0;
+	} else if (priv->ah->opmode == NL80211_IFTYPE_ADHOC) {
+		int qnum = priv->hwq_map[WME_AC_BE];
+
+		ath9k_hw_get_txq_props(ah, qnum, &qi_be);
+
+		qi.tqi_aifs = qi_be.tqi_aifs;
+
+		/*
+		 * For WIFI Beacon Distribution
+		 * Long slot time  : 2x cwmin
+		 * Short slot time : 4x cwmin
+		 */
+		if (ah->slottime == ATH9K_SLOT_TIME_20)
+			qi.tqi_cwmin = 2*qi_be.tqi_cwmin;
+		else
+			qi.tqi_cwmin = 4*qi_be.tqi_cwmin;
+
+		qi.tqi_cwmax = qi_be.tqi_cwmax;
+
+	}
+
+	if (!ath9k_hw_set_txq_props(ah, priv->beaconq, &qi)) {
+		ath_err(ath9k_hw_common(ah),
+			"Unable to update beacon queue %u!\n", priv->beaconq);
+	} else {
+		ath9k_hw_resettxqueue(ah, priv->beaconq);
+	}
+}
+
+
 static void ath9k_htc_beacon_config_sta(struct ath9k_htc_priv *priv,
 					struct htc_beacon_config *bss_conf)
 {
@@ -30,7 +74,7 @@
 	__be32 htc_imask = 0;
 	u64 tsf;
 	int num_beacons, offset, dtim_dec_count, cfp_dec_count;
-	int ret;
+	int ret __attribute__ ((unused));
 	u8 cmd_rsp;
 
 	memset(&bs, 0, sizeof(bs));
@@ -146,7 +190,7 @@
 	enum ath9k_int imask = 0;
 	u32 nexttbtt, intval, tsftu;
 	__be32 htc_imask = 0;
-	int ret;
+	int ret __attribute__ ((unused));
 	u8 cmd_rsp;
 	u64 tsf;
 
@@ -154,8 +198,17 @@
 	intval /= ATH9K_HTC_MAX_BCN_VIF;
 	nexttbtt = intval;
 
+	/*
+	 * To reduce beacon misses under heavy TX load,
+	 * set the beacon response time to a larger value.
+	 */
+	if (intval > DEFAULT_SWBA_RESPONSE)
+		priv->ah->config.sw_beacon_response_time = DEFAULT_SWBA_RESPONSE;
+	else
+		priv->ah->config.sw_beacon_response_time = MIN_SWBA_RESPONSE;
+
 	if (priv->op_flags & OP_TSF_RESET) {
-		intval |= ATH9K_BEACON_RESET_TSF;
+		ath9k_hw_reset_tsf(priv->ah);
 		priv->op_flags &= ~OP_TSF_RESET;
 	} else {
 		/*
@@ -168,18 +221,20 @@
 		} while (nexttbtt < tsftu);
 	}
 
-	intval |= ATH9K_BEACON_ENA;
-
 	if (priv->op_flags & OP_ENABLE_BEACON)
 		imask |= ATH9K_INT_SWBA;
 
 	ath_dbg(common, ATH_DBG_CONFIG,
-		"AP Beacon config, intval: %d, nexttbtt: %u imask: 0x%x\n",
-		bss_conf->beacon_interval, nexttbtt, imask);
+		"AP Beacon config, intval: %d, nexttbtt: %u, resp_time: %d "
+		"imask: 0x%x\n",
+		bss_conf->beacon_interval, nexttbtt,
+		priv->ah->config.sw_beacon_response_time, imask);
+
+	ath9k_htc_beaconq_config(priv);
 
 	WMI_CMD(WMI_DISABLE_INTR_CMDID);
-	ath9k_hw_beaconinit(priv->ah, nexttbtt, intval);
-	priv->bmiss_cnt = 0;
+	ath9k_hw_beaconinit(priv->ah, TU_TO_USEC(nexttbtt), TU_TO_USEC(intval));
+	priv->cur_beacon_conf.bmiss_cnt = 0;
 	htc_imask = cpu_to_be32(imask);
 	WMI_CMD_BUF(WMI_ENABLE_INTR_CMDID, &htc_imask);
 }
@@ -191,7 +246,7 @@
 	enum ath9k_int imask = 0;
 	u32 nexttbtt, intval, tsftu;
 	__be32 htc_imask = 0;
-	int ret;
+	int ret __attribute__ ((unused));
 	u8 cmd_rsp;
 	u64 tsf;
 
@@ -207,17 +262,26 @@
 		nexttbtt += intval;
 	} while (nexttbtt < tsftu);
 
-	intval |= ATH9K_BEACON_ENA;
+	/*
+	 * Only one IBSS interfce is allowed.
+	 */
+	if (intval > DEFAULT_SWBA_RESPONSE)
+		priv->ah->config.sw_beacon_response_time = DEFAULT_SWBA_RESPONSE;
+	else
+		priv->ah->config.sw_beacon_response_time = MIN_SWBA_RESPONSE;
+
 	if (priv->op_flags & OP_ENABLE_BEACON)
 		imask |= ATH9K_INT_SWBA;
 
 	ath_dbg(common, ATH_DBG_CONFIG,
-		"IBSS Beacon config, intval: %d, nexttbtt: %u, imask: 0x%x\n",
-		bss_conf->beacon_interval, nexttbtt, imask);
+		"IBSS Beacon config, intval: %d, nexttbtt: %u, "
+		"resp_time: %d, imask: 0x%x\n",
+		bss_conf->beacon_interval, nexttbtt,
+		priv->ah->config.sw_beacon_response_time, imask);
 
 	WMI_CMD(WMI_DISABLE_INTR_CMDID);
-	ath9k_hw_beaconinit(priv->ah, nexttbtt, intval);
-	priv->bmiss_cnt = 0;
+	ath9k_hw_beaconinit(priv->ah, TU_TO_USEC(nexttbtt), TU_TO_USEC(intval));
+	priv->cur_beacon_conf.bmiss_cnt = 0;
 	htc_imask = cpu_to_be32(imask);
 	WMI_CMD_BUF(WMI_ENABLE_INTR_CMDID, &htc_imask);
 }
@@ -228,38 +292,101 @@
 	dev_kfree_skb_any(skb);
 }
 
-void ath9k_htc_swba(struct ath9k_htc_priv *priv, u8 beacon_pending)
+static void ath9k_htc_send_buffered(struct ath9k_htc_priv *priv,
+				    int slot)
 {
-	struct ath9k_htc_vif *avp = (void *)priv->vif->drv_priv;
+	struct ath_common *common = ath9k_hw_common(priv->ah);
+	struct ieee80211_vif *vif;
+	struct sk_buff *skb;
+	struct ieee80211_hdr *hdr;
+	int padpos, padsize, ret, tx_slot;
+
+	spin_lock_bh(&priv->beacon_lock);
+
+	vif = priv->cur_beacon_conf.bslot[slot];
+
+	skb = ieee80211_get_buffered_bc(priv->hw, vif);
+
+	while(skb) {
+		hdr = (struct ieee80211_hdr *) skb->data;
+
+		padpos = ath9k_cmn_padpos(hdr->frame_control);
+		padsize = padpos & 3;
+		if (padsize && skb->len > padpos) {
+			if (skb_headroom(skb) < padsize) {
+				dev_kfree_skb_any(skb);
+				goto next;
+			}
+			skb_push(skb, padsize);
+			memmove(skb->data, skb->data + padsize, padpos);
+		}
+
+		tx_slot = ath9k_htc_tx_get_slot(priv);
+		if (tx_slot < 0) {
+			ath_dbg(common, ATH_DBG_XMIT, "No free CAB slot\n");
+			dev_kfree_skb_any(skb);
+			goto next;
+		}
+
+		ret = ath9k_htc_tx_start(priv, skb, tx_slot, true);
+		if (ret != 0) {
+			ath9k_htc_tx_clear_slot(priv, tx_slot);
+			dev_kfree_skb_any(skb);
+
+			ath_dbg(common, ATH_DBG_XMIT,
+				"Failed to send CAB frame\n");
+		} else {
+			spin_lock_bh(&priv->tx.tx_lock);
+			priv->tx.queued_cnt++;
+			spin_unlock_bh(&priv->tx.tx_lock);
+		}
+	next:
+		skb = ieee80211_get_buffered_bc(priv->hw, vif);
+	}
+
+	spin_unlock_bh(&priv->beacon_lock);
+}
+
+static void ath9k_htc_send_beacon(struct ath9k_htc_priv *priv,
+				  int slot)
+{
+	struct ath_common *common = ath9k_hw_common(priv->ah);
+	struct ieee80211_vif *vif;
+	struct ath9k_htc_vif *avp;
 	struct tx_beacon_header beacon_hdr;
-	struct ath9k_htc_tx_ctl tx_ctl;
+	struct ath9k_htc_tx_ctl *tx_ctl;
 	struct ieee80211_tx_info *info;
+	struct ieee80211_mgmt *mgmt;
 	struct sk_buff *beacon;
 	u8 *tx_fhdr;
+	int ret;
 
 	memset(&beacon_hdr, 0, sizeof(struct tx_beacon_header));
-	memset(&tx_ctl, 0, sizeof(struct ath9k_htc_tx_ctl));
-
-	/* FIXME: Handle BMISS */
-	if (beacon_pending != 0) {
-		priv->bmiss_cnt++;
-		return;
-	}
 
 	spin_lock_bh(&priv->beacon_lock);
 
+	vif = priv->cur_beacon_conf.bslot[slot];
+	avp = (struct ath9k_htc_vif *)vif->drv_priv;
+
 	if (unlikely(priv->op_flags & OP_SCANNING)) {
 		spin_unlock_bh(&priv->beacon_lock);
 		return;
 	}
 
 	/* Get a new beacon */
-	beacon = ieee80211_beacon_get(priv->hw, priv->vif);
+	beacon = ieee80211_beacon_get(priv->hw, vif);
 	if (!beacon) {
 		spin_unlock_bh(&priv->beacon_lock);
 		return;
 	}
 
+	/*
+	 * Update the TSF adjust value here, the HW will
+	 * add this value for every beacon.
+	 */
+	mgmt = (struct ieee80211_mgmt *)beacon->data;
+	mgmt->u.beacon.timestamp = avp->tsfadjust;
+
 	info = IEEE80211_SKB_CB(beacon);
 	if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) {
 		struct ieee80211_hdr *hdr =
@@ -269,45 +396,149 @@
 		hdr->seq_ctrl |= cpu_to_le16(avp->seq_no);
 	}
 
-	tx_ctl.type = ATH9K_HTC_NORMAL;
+	tx_ctl = HTC_SKB_CB(beacon);
+	memset(tx_ctl, 0, sizeof(*tx_ctl));
+
+	tx_ctl->type = ATH9K_HTC_BEACON;
+	tx_ctl->epid = priv->beacon_ep;
+
 	beacon_hdr.vif_index = avp->index;
 	tx_fhdr = skb_push(beacon, sizeof(beacon_hdr));
 	memcpy(tx_fhdr, (u8 *) &beacon_hdr, sizeof(beacon_hdr));
 
-	htc_send(priv->htc, beacon, priv->beacon_ep, &tx_ctl);
+	ret = htc_send(priv->htc, beacon);
+	if (ret != 0) {
+		if (ret == -ENOMEM) {
+			ath_dbg(common, ATH_DBG_BSTUCK,
+				"Failed to send beacon, no free TX buffer\n");
+		}
+		dev_kfree_skb_any(beacon);
+	}
 
 	spin_unlock_bh(&priv->beacon_lock);
 }
 
-/* Currently, only for IBSS */
-void ath9k_htc_beaconq_config(struct ath9k_htc_priv *priv)
+static int ath9k_htc_choose_bslot(struct ath9k_htc_priv *priv,
+				  struct wmi_event_swba *swba)
 {
-	struct ath_hw *ah = priv->ah;
-	struct ath9k_tx_queue_info qi, qi_be;
-	int qnum = priv->hwq_map[WME_AC_BE];
+	struct ath_common *common = ath9k_hw_common(priv->ah);
+	u64 tsf;
+	u32 tsftu;
+	u16 intval;
+	int slot;
 
-	memset(&qi, 0, sizeof(struct ath9k_tx_queue_info));
-	memset(&qi_be, 0, sizeof(struct ath9k_tx_queue_info));
+	intval = priv->cur_beacon_conf.beacon_interval & ATH9K_BEACON_PERIOD;
 
-	ath9k_hw_get_txq_props(ah, qnum, &qi_be);
+	tsf = be64_to_cpu(swba->tsf);
+	tsftu = TSF_TO_TU(tsf >> 32, tsf);
+	slot = ((tsftu % intval) * ATH9K_HTC_MAX_BCN_VIF) / intval;
+	slot = ATH9K_HTC_MAX_BCN_VIF - slot - 1;
 
-	qi.tqi_aifs = qi_be.tqi_aifs;
-	/* For WIFI Beacon Distribution
-	 * Long slot time  : 2x cwmin
-	 * Short slot time : 4x cwmin
-	 */
-	if (ah->slottime == ATH9K_SLOT_TIME_20)
-		qi.tqi_cwmin = 2*qi_be.tqi_cwmin;
-	else
-		qi.tqi_cwmin = 4*qi_be.tqi_cwmin;
-	qi.tqi_cwmax = qi_be.tqi_cwmax;
+	ath_dbg(common, ATH_DBG_BEACON,
+		"Choose slot: %d, tsf: %llu, tsftu: %u, intval: %u\n",
+		slot, tsf, tsftu, intval);
 
-	if (!ath9k_hw_set_txq_props(ah, priv->beaconq, &qi)) {
-		ath_err(ath9k_hw_common(ah),
-			"Unable to update beacon queue %u!\n", qnum);
-	} else {
-		ath9k_hw_resettxqueue(ah, priv->beaconq);
+	return slot;
+}
+
+void ath9k_htc_swba(struct ath9k_htc_priv *priv,
+		    struct wmi_event_swba *swba)
+{
+	struct ath_common *common = ath9k_hw_common(priv->ah);
+	int slot;
+
+	if (swba->beacon_pending != 0) {
+		priv->cur_beacon_conf.bmiss_cnt++;
+		if (priv->cur_beacon_conf.bmiss_cnt > BSTUCK_THRESHOLD) {
+			ath_dbg(common, ATH_DBG_BSTUCK,
+				"Beacon stuck, HW reset\n");
+			ieee80211_queue_work(priv->hw,
+					     &priv->fatal_work);
+		}
+		return;
+	}
+
+	if (priv->cur_beacon_conf.bmiss_cnt) {
+		ath_dbg(common, ATH_DBG_BSTUCK,
+			"Resuming beacon xmit after %u misses\n",
+			priv->cur_beacon_conf.bmiss_cnt);
+		priv->cur_beacon_conf.bmiss_cnt = 0;
+	}
+
+	slot = ath9k_htc_choose_bslot(priv, swba);
+	spin_lock_bh(&priv->beacon_lock);
+	if (priv->cur_beacon_conf.bslot[slot] == NULL) {
+		spin_unlock_bh(&priv->beacon_lock);
+		return;
+	}
+	spin_unlock_bh(&priv->beacon_lock);
+
+	ath9k_htc_send_buffered(priv, slot);
+	ath9k_htc_send_beacon(priv, slot);
+}
+
+void ath9k_htc_assign_bslot(struct ath9k_htc_priv *priv,
+			    struct ieee80211_vif *vif)
+{
+	struct ath_common *common = ath9k_hw_common(priv->ah);
+	struct ath9k_htc_vif *avp = (struct ath9k_htc_vif *)vif->drv_priv;
+	int i = 0;
+
+	spin_lock_bh(&priv->beacon_lock);
+	for (i = 0; i < ATH9K_HTC_MAX_BCN_VIF; i++) {
+		if (priv->cur_beacon_conf.bslot[i] == NULL) {
+			avp->bslot = i;
+			break;
+		}
 	}
+
+	priv->cur_beacon_conf.bslot[avp->bslot] = vif;
+	spin_unlock_bh(&priv->beacon_lock);
+
+	ath_dbg(common, ATH_DBG_CONFIG,
+		"Added interface at beacon slot: %d\n", avp->bslot);
+}
+
+void ath9k_htc_remove_bslot(struct ath9k_htc_priv *priv,
+			    struct ieee80211_vif *vif)
+{
+	struct ath_common *common = ath9k_hw_common(priv->ah);
+	struct ath9k_htc_vif *avp = (struct ath9k_htc_vif *)vif->drv_priv;
+
+	spin_lock_bh(&priv->beacon_lock);
+	priv->cur_beacon_conf.bslot[avp->bslot] = NULL;
+	spin_unlock_bh(&priv->beacon_lock);
+
+	ath_dbg(common, ATH_DBG_CONFIG,
+		"Removed interface at beacon slot: %d\n", avp->bslot);
+}
+
+/*
+ * Calculate the TSF adjustment value for all slots
+ * other than zero.
+ */
+void ath9k_htc_set_tsfadjust(struct ath9k_htc_priv *priv,
+			     struct ieee80211_vif *vif)
+{
+	struct ath_common *common = ath9k_hw_common(priv->ah);
+	struct ath9k_htc_vif *avp = (struct ath9k_htc_vif *)vif->drv_priv;
+	struct htc_beacon_config *cur_conf = &priv->cur_beacon_conf;
+	u64 tsfadjust;
+
+	if (avp->bslot == 0)
+		return;
+
+	/*
+	 * The beacon interval cannot be different for multi-AP mode,
+	 * and we reach here only for VIF slots greater than zero,
+	 * so beacon_interval is guaranteed to be set in cur_conf.
+	 */
+	tsfadjust = cur_conf->beacon_interval * avp->bslot / ATH9K_HTC_MAX_BCN_VIF;
+	avp->tsfadjust = cpu_to_le64(TU_TO_USEC(tsfadjust));
+
+	ath_dbg(common, ATH_DBG_CONFIG,
+		"tsfadjust is: %llu for bslot: %d\n",
+		(unsigned long long)tsfadjust, avp->bslot);
 }
 
 static void ath9k_htc_beacon_iter(void *data, u8 *mac, struct ieee80211_vif *vif)
diff -druN linux-2.6.39-libre/drivers/net/wireless/ath/ath9k/htc_drv_debug.c linux-3.0-rc7-libre/drivers/net/wireless/ath/ath9k/htc_drv_debug.c
--- linux-2.6.39-libre/drivers/net/wireless/ath/ath9k/htc_drv_debug.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/net/wireless/ath/ath9k/htc_drv_debug.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,960 @@
+/*
+ * Copyright (c) 2010-2011 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 "htc.h"
+
+static int ath9k_debugfs_open(struct inode *inode, struct file *file)
+{
+	file->private_data = inode->i_private;
+	return 0;
+}
+
+static ssize_t read_file_tgt_int_stats(struct file *file, char __user *user_buf,
+				       size_t count, loff_t *ppos)
+{
+	struct ath9k_htc_priv *priv = file->private_data;
+	struct ath9k_htc_target_int_stats cmd_rsp;
+	char buf[512];
+	unsigned int len = 0;
+	int ret = 0;
+
+	memset(&cmd_rsp, 0, sizeof(cmd_rsp));
+
+	ath9k_htc_ps_wakeup(priv);
+
+	WMI_CMD(WMI_INT_STATS_CMDID);
+	if (ret) {
+		ath9k_htc_ps_restore(priv);
+		return -EINVAL;
+	}
+
+	ath9k_htc_ps_restore(priv);
+
+	len += snprintf(buf + len, sizeof(buf) - len,
+			"%20s : %10u\n", "RX",
+			be32_to_cpu(cmd_rsp.rx));
+
+	len += snprintf(buf + len, sizeof(buf) - len,
+			"%20s : %10u\n", "RXORN",
+			be32_to_cpu(cmd_rsp.rxorn));
+
+	len += snprintf(buf + len, sizeof(buf) - len,
+			"%20s : %10u\n", "RXEOL",
+			be32_to_cpu(cmd_rsp.rxeol));
+
+	len += snprintf(buf + len, sizeof(buf) - len,
+			"%20s : %10u\n", "TXURN",
+			be32_to_cpu(cmd_rsp.txurn));
+
+	len += snprintf(buf + len, sizeof(buf) - len,
+			"%20s : %10u\n", "TXTO",
+			be32_to_cpu(cmd_rsp.txto));
+
+	len += snprintf(buf + len, sizeof(buf) - len,
+			"%20s : %10u\n", "CST",
+			be32_to_cpu(cmd_rsp.cst));
+
+	if (len > sizeof(buf))
+		len = sizeof(buf);
+
+	return simple_read_from_buffer(user_buf, count, ppos, buf, len);
+}
+
+static const struct file_operations fops_tgt_int_stats = {
+	.read = read_file_tgt_int_stats,
+	.open = ath9k_debugfs_open,
+	.owner = THIS_MODULE,
+	.llseek = default_llseek,
+};
+
+static ssize_t read_file_tgt_tx_stats(struct file *file, char __user *user_buf,
+				      size_t count, loff_t *ppos)
+{
+	struct ath9k_htc_priv *priv = file->private_data;
+	struct ath9k_htc_target_tx_stats cmd_rsp;
+	char buf[512];
+	unsigned int len = 0;
+	int ret = 0;
+
+	memset(&cmd_rsp, 0, sizeof(cmd_rsp));
+
+	ath9k_htc_ps_wakeup(priv);
+
+	WMI_CMD(WMI_TX_STATS_CMDID);
+	if (ret) {
+		ath9k_htc_ps_restore(priv);
+		return -EINVAL;
+	}
+
+	ath9k_htc_ps_restore(priv);
+
+	len += snprintf(buf + len, sizeof(buf) - len,
+			"%20s : %10u\n", "Xretries",
+			be32_to_cpu(cmd_rsp.xretries));
+
+	len += snprintf(buf + len, sizeof(buf) - len,
+			"%20s : %10u\n", "FifoErr",
+			be32_to_cpu(cmd_rsp.fifoerr));
+
+	len += snprintf(buf + len, sizeof(buf) - len,
+			"%20s : %10u\n", "Filtered",
+			be32_to_cpu(cmd_rsp.filtered));
+
+	len += snprintf(buf + len, sizeof(buf) - len,
+			"%20s : %10u\n", "TimerExp",
+			be32_to_cpu(cmd_rsp.timer_exp));
+
+	len += snprintf(buf + len, sizeof(buf) - len,
+			"%20s : %10u\n", "ShortRetries",
+			be32_to_cpu(cmd_rsp.shortretries));
+
+	len += snprintf(buf + len, sizeof(buf) - len,
+			"%20s : %10u\n", "LongRetries",
+			be32_to_cpu(cmd_rsp.longretries));
+
+	len += snprintf(buf + len, sizeof(buf) - len,
+			"%20s : %10u\n", "QueueNull",
+			be32_to_cpu(cmd_rsp.qnull));
+
+	len += snprintf(buf + len, sizeof(buf) - len,
+			"%20s : %10u\n", "EncapFail",
+			be32_to_cpu(cmd_rsp.encap_fail));
+
+	len += snprintf(buf + len, sizeof(buf) - len,
+			"%20s : %10u\n", "NoBuf",
+			be32_to_cpu(cmd_rsp.nobuf));
+
+	if (len > sizeof(buf))
+		len = sizeof(buf);
+
+	return simple_read_from_buffer(user_buf, count, ppos, buf, len);
+}
+
+static const struct file_operations fops_tgt_tx_stats = {
+	.read = read_file_tgt_tx_stats,
+	.open = ath9k_debugfs_open,
+	.owner = THIS_MODULE,
+	.llseek = default_llseek,
+};
+
+static ssize_t read_file_tgt_rx_stats(struct file *file, char __user *user_buf,
+				      size_t count, loff_t *ppos)
+{
+	struct ath9k_htc_priv *priv = file->private_data;
+	struct ath9k_htc_target_rx_stats cmd_rsp;
+	char buf[512];
+	unsigned int len = 0;
+	int ret = 0;
+
+	memset(&cmd_rsp, 0, sizeof(cmd_rsp));
+
+	ath9k_htc_ps_wakeup(priv);
+
+	WMI_CMD(WMI_RX_STATS_CMDID);
+	if (ret) {
+		ath9k_htc_ps_restore(priv);
+		return -EINVAL;
+	}
+
+	ath9k_htc_ps_restore(priv);
+
+	len += snprintf(buf + len, sizeof(buf) - len,
+			"%20s : %10u\n", "NoBuf",
+			be32_to_cpu(cmd_rsp.nobuf));
+
+	len += snprintf(buf + len, sizeof(buf) - len,
+			"%20s : %10u\n", "HostSend",
+			be32_to_cpu(cmd_rsp.host_send));
+
+	len += snprintf(buf + len, sizeof(buf) - len,
+			"%20s : %10u\n", "HostDone",
+			be32_to_cpu(cmd_rsp.host_done));
+
+	if (len > sizeof(buf))
+		len = sizeof(buf);
+
+	return simple_read_from_buffer(user_buf, count, ppos, buf, len);
+}
+
+static const struct file_operations fops_tgt_rx_stats = {
+	.read = read_file_tgt_rx_stats,
+	.open = ath9k_debugfs_open,
+	.owner = THIS_MODULE,
+	.llseek = default_llseek,
+};
+
+static ssize_t read_file_xmit(struct file *file, char __user *user_buf,
+			      size_t count, loff_t *ppos)
+{
+	struct ath9k_htc_priv *priv = file->private_data;
+	char buf[512];
+	unsigned int len = 0;
+
+	len += snprintf(buf + len, sizeof(buf) - len,
+			"%20s : %10u\n", "Buffers queued",
+			priv->debug.tx_stats.buf_queued);
+	len += snprintf(buf + len, sizeof(buf) - len,
+			"%20s : %10u\n", "Buffers completed",
+			priv->debug.tx_stats.buf_completed);
+	len += snprintf(buf + len, sizeof(buf) - len,
+			"%20s : %10u\n", "SKBs queued",
+			priv->debug.tx_stats.skb_queued);
+	len += snprintf(buf + len, sizeof(buf) - len,
+			"%20s : %10u\n", "SKBs success",
+			priv->debug.tx_stats.skb_success);
+	len += snprintf(buf + len, sizeof(buf) - len,
+			"%20s : %10u\n", "SKBs failed",
+			priv->debug.tx_stats.skb_failed);
+	len += snprintf(buf + len, sizeof(buf) - len,
+			"%20s : %10u\n", "CAB queued",
+			priv->debug.tx_stats.cab_queued);
+
+	len += snprintf(buf + len, sizeof(buf) - len,
+			"%20s : %10u\n", "BE queued",
+			priv->debug.tx_stats.queue_stats[WME_AC_BE]);
+	len += snprintf(buf + len, sizeof(buf) - len,
+			"%20s : %10u\n", "BK queued",
+			priv->debug.tx_stats.queue_stats[WME_AC_BK]);
+	len += snprintf(buf + len, sizeof(buf) - len,
+			"%20s : %10u\n", "VI queued",
+			priv->debug.tx_stats.queue_stats[WME_AC_VI]);
+	len += snprintf(buf + len, sizeof(buf) - len,
+			"%20s : %10u\n", "VO queued",
+			priv->debug.tx_stats.queue_stats[WME_AC_VO]);
+
+	if (len > sizeof(buf))
+		len = sizeof(buf);
+
+	return simple_read_from_buffer(user_buf, count, ppos, buf, len);
+}
+
+static const struct file_operations fops_xmit = {
+	.read = read_file_xmit,
+	.open = ath9k_debugfs_open,
+	.owner = THIS_MODULE,
+	.llseek = default_llseek,
+};
+
+void ath9k_htc_err_stat_rx(struct ath9k_htc_priv *priv,
+			   struct ath_htc_rx_status *rxs)
+{
+#define RX_PHY_ERR_INC(c) priv->debug.rx_stats.err_phy_stats[c]++
+
+	if (rxs->rs_status & ATH9K_RXERR_CRC)
+		priv->debug.rx_stats.err_crc++;
+	if (rxs->rs_status & ATH9K_RXERR_DECRYPT)
+		priv->debug.rx_stats.err_decrypt_crc++;
+	if (rxs->rs_status & ATH9K_RXERR_MIC)
+		priv->debug.rx_stats.err_mic++;
+	if (rxs->rs_status & ATH9K_RX_DELIM_CRC_PRE)
+		priv->debug.rx_stats.err_pre_delim++;
+	if (rxs->rs_status & ATH9K_RX_DELIM_CRC_POST)
+		priv->debug.rx_stats.err_post_delim++;
+	if (rxs->rs_status & ATH9K_RX_DECRYPT_BUSY)
+		priv->debug.rx_stats.err_decrypt_busy++;
+
+	if (rxs->rs_status & ATH9K_RXERR_PHY) {
+		priv->debug.rx_stats.err_phy++;
+		if (rxs->rs_phyerr < ATH9K_PHYERR_MAX)
+			RX_PHY_ERR_INC(rxs->rs_phyerr);
+	}
+
+#undef RX_PHY_ERR_INC
+}
+
+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, "%20s : %10u\n", s,	\
+			priv->debug.rx_stats.err_phy_stats[p]);
+
+	struct ath9k_htc_priv *priv = file->private_data;
+	char *buf;
+	unsigned int len = 0, size = 1500;
+	ssize_t retval = 0;
+
+	buf = kzalloc(size, GFP_KERNEL);
+	if (buf == NULL)
+		return -ENOMEM;
+
+	len += snprintf(buf + len, size - len,
+			"%20s : %10u\n", "SKBs allocated",
+			priv->debug.rx_stats.skb_allocated);
+	len += snprintf(buf + len, size - len,
+			"%20s : %10u\n", "SKBs completed",
+			priv->debug.rx_stats.skb_completed);
+	len += snprintf(buf + len, size - len,
+			"%20s : %10u\n", "SKBs Dropped",
+			priv->debug.rx_stats.skb_dropped);
+
+	len += snprintf(buf + len, size - len,
+			"%20s : %10u\n", "CRC ERR",
+			priv->debug.rx_stats.err_crc);
+	len += snprintf(buf + len, size - len,
+			"%20s : %10u\n", "DECRYPT CRC ERR",
+			priv->debug.rx_stats.err_decrypt_crc);
+	len += snprintf(buf + len, size - len,
+			"%20s : %10u\n", "MIC ERR",
+			priv->debug.rx_stats.err_mic);
+	len += snprintf(buf + len, size - len,
+			"%20s : %10u\n", "PRE-DELIM CRC ERR",
+			priv->debug.rx_stats.err_pre_delim);
+	len += snprintf(buf + len, size - len,
+			"%20s : %10u\n", "POST-DELIM CRC ERR",
+			priv->debug.rx_stats.err_post_delim);
+	len += snprintf(buf + len, size - len,
+			"%20s : %10u\n", "DECRYPT BUSY ERR",
+			priv->debug.rx_stats.err_decrypt_busy);
+	len += snprintf(buf + len, size - len,
+			"%20s : %10u\n", "TOTAL PHY ERR",
+			priv->debug.rx_stats.err_phy);
+
+
+	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);
+
+	if (len > size)
+		len = size;
+
+	retval = simple_read_from_buffer(user_buf, count, ppos, buf, len);
+	kfree(buf);
+
+	return retval;
+
+#undef PHY_ERR
+}
+
+static const struct file_operations fops_recv = {
+	.read = read_file_recv,
+	.open = ath9k_debugfs_open,
+	.owner = THIS_MODULE,
+	.llseek = default_llseek,
+};
+
+static ssize_t read_file_slot(struct file *file, char __user *user_buf,
+			      size_t count, loff_t *ppos)
+{
+	struct ath9k_htc_priv *priv = file->private_data;
+	char buf[512];
+	unsigned int len = 0;
+
+	spin_lock_bh(&priv->tx.tx_lock);
+
+	len += snprintf(buf + len, sizeof(buf) - len, "TX slot bitmap : ");
+
+	len += bitmap_scnprintf(buf + len, sizeof(buf) - len,
+			       priv->tx.tx_slot, MAX_TX_BUF_NUM);
+
+	len += snprintf(buf + len, sizeof(buf) - len, "\n");
+
+	len += snprintf(buf + len, sizeof(buf) - len,
+			"Used slots     : %d\n",
+			bitmap_weight(priv->tx.tx_slot, MAX_TX_BUF_NUM));
+
+	spin_unlock_bh(&priv->tx.tx_lock);
+
+	if (len > sizeof(buf))
+		len = sizeof(buf);
+
+	return simple_read_from_buffer(user_buf, count, ppos, buf, len);
+}
+
+static const struct file_operations fops_slot = {
+	.read = read_file_slot,
+	.open = ath9k_debugfs_open,
+	.owner = THIS_MODULE,
+	.llseek = default_llseek,
+};
+
+static ssize_t read_file_queue(struct file *file, char __user *user_buf,
+			       size_t count, loff_t *ppos)
+{
+	struct ath9k_htc_priv *priv = file->private_data;
+	char buf[512];
+	unsigned int len = 0;
+
+	len += snprintf(buf + len, sizeof(buf) - len, "%20s : %10u\n",
+			"Mgmt endpoint", skb_queue_len(&priv->tx.mgmt_ep_queue));
+
+	len += snprintf(buf + len, sizeof(buf) - len, "%20s : %10u\n",
+			"Cab endpoint", skb_queue_len(&priv->tx.cab_ep_queue));
+
+	len += snprintf(buf + len, sizeof(buf) - len, "%20s : %10u\n",
+			"Data BE endpoint", skb_queue_len(&priv->tx.data_be_queue));
+
+	len += snprintf(buf + len, sizeof(buf) - len, "%20s : %10u\n",
+			"Data BK endpoint", skb_queue_len(&priv->tx.data_bk_queue));
+
+	len += snprintf(buf + len, sizeof(buf) - len, "%20s : %10u\n",
+			"Data VI endpoint", skb_queue_len(&priv->tx.data_vi_queue));
+
+	len += snprintf(buf + len, sizeof(buf) - len, "%20s : %10u\n",
+			"Data VO endpoint", skb_queue_len(&priv->tx.data_vo_queue));
+
+	len += snprintf(buf + len, sizeof(buf) - len, "%20s : %10u\n",
+			"Failed queue", skb_queue_len(&priv->tx.tx_failed));
+
+	spin_lock_bh(&priv->tx.tx_lock);
+	len += snprintf(buf + len, sizeof(buf) - len, "%20s : %10u\n",
+			"Queued count", priv->tx.queued_cnt);
+	spin_unlock_bh(&priv->tx.tx_lock);
+
+	if (len > sizeof(buf))
+		len = sizeof(buf);
+
+	return simple_read_from_buffer(user_buf, count, ppos, buf, len);
+
+}
+
+static const struct file_operations fops_queue = {
+	.read = read_file_queue,
+	.open = ath9k_debugfs_open,
+	.owner = THIS_MODULE,
+	.llseek = default_llseek,
+};
+
+static ssize_t read_file_debug(struct file *file, char __user *user_buf,
+			       size_t count, loff_t *ppos)
+{
+	struct ath9k_htc_priv *priv = file->private_data;
+	struct ath_common *common = ath9k_hw_common(priv->ah);
+	char buf[32];
+	unsigned int len;
+
+	len = sprintf(buf, "0x%08x\n", common->debug_mask);
+	return simple_read_from_buffer(user_buf, count, ppos, buf, len);
+}
+
+static ssize_t write_file_debug(struct file *file, const char __user *user_buf,
+				size_t count, loff_t *ppos)
+{
+	struct ath9k_htc_priv *priv = file->private_data;
+	struct ath_common *common = ath9k_hw_common(priv->ah);
+	unsigned long mask;
+	char buf[32];
+	ssize_t len;
+
+	len = min(count, sizeof(buf) - 1);
+	if (copy_from_user(buf, user_buf, len))
+		return -EFAULT;
+
+	buf[len] = '\0';
+	if (strict_strtoul(buf, 0, &mask))
+		return -EINVAL;
+
+	common->debug_mask = mask;
+	return count;
+}
+
+static const struct file_operations fops_debug = {
+	.read = read_file_debug,
+	.write = write_file_debug,
+	.open = ath9k_debugfs_open,
+	.owner = THIS_MODULE,
+	.llseek = default_llseek,
+};
+
+static ssize_t read_file_base_eeprom(struct file *file, char __user *user_buf,
+				     size_t count, loff_t *ppos)
+{
+	struct ath9k_htc_priv *priv = file->private_data;
+	struct ath_common *common = ath9k_hw_common(priv->ah);
+	struct base_eep_header *pBase = NULL;
+	unsigned int len = 0, size = 1500;
+	ssize_t retval = 0;
+	char *buf;
+
+	/*
+	 * This can be done since all the 3 EEPROM families have the
+	 * same base header upto a certain point, and we are interested in
+	 * the data only upto that point.
+	 */
+
+	if (AR_SREV_9271(priv->ah))
+		pBase = (struct base_eep_header *)
+			&priv->ah->eeprom.map4k.baseEepHeader;
+	else if (priv->ah->hw_version.usbdev == AR9280_USB)
+		pBase = (struct base_eep_header *)
+			&priv->ah->eeprom.def.baseEepHeader;
+	else if (priv->ah->hw_version.usbdev == AR9287_USB)
+		pBase = (struct base_eep_header *)
+			&priv->ah->eeprom.map9287.baseEepHeader;
+
+	if (pBase == NULL) {
+		ath_err(common, "Unknown EEPROM type\n");
+		return 0;
+	}
+
+	buf = kzalloc(size, GFP_KERNEL);
+	if (buf == NULL)
+		return -ENOMEM;
+
+	len += snprintf(buf + len, size - len,
+			"%20s : %10d\n", "Major Version",
+			pBase->version >> 12);
+	len += snprintf(buf + len, size - len,
+			"%20s : %10d\n", "Minor Version",
+			pBase->version & 0xFFF);
+	len += snprintf(buf + len, size - len,
+			"%20s : %10d\n", "Checksum",
+			pBase->checksum);
+	len += snprintf(buf + len, size - len,
+			"%20s : %10d\n", "Length",
+			pBase->length);
+	len += snprintf(buf + len, size - len,
+			"%20s : %10d\n", "RegDomain1",
+			pBase->regDmn[0]);
+	len += snprintf(buf + len, size - len,
+			"%20s : %10d\n", "RegDomain2",
+			pBase->regDmn[1]);
+	len += snprintf(buf + len, size - len,
+			"%20s : %10d\n",
+			"TX Mask", pBase->txMask);
+	len += snprintf(buf + len, size - len,
+			"%20s : %10d\n",
+			"RX Mask", pBase->rxMask);
+	len += snprintf(buf + len, size - len,
+			"%20s : %10d\n",
+			"Allow 5GHz",
+			!!(pBase->opCapFlags & AR5416_OPFLAGS_11A));
+	len += snprintf(buf + len, size - len,
+			"%20s : %10d\n",
+			"Allow 2GHz",
+			!!(pBase->opCapFlags & AR5416_OPFLAGS_11G));
+	len += snprintf(buf + len, size - len,
+			"%20s : %10d\n",
+			"Disable 2GHz HT20",
+			!!(pBase->opCapFlags & AR5416_OPFLAGS_N_2G_HT20));
+	len += snprintf(buf + len, size - len,
+			"%20s : %10d\n",
+			"Disable 2GHz HT40",
+			!!(pBase->opCapFlags & AR5416_OPFLAGS_N_2G_HT40));
+	len += snprintf(buf + len, size - len,
+			"%20s : %10d\n",
+			"Disable 5Ghz HT20",
+			!!(pBase->opCapFlags & AR5416_OPFLAGS_N_5G_HT20));
+	len += snprintf(buf + len, size - len,
+			"%20s : %10d\n",
+			"Disable 5Ghz HT40",
+			!!(pBase->opCapFlags & AR5416_OPFLAGS_N_5G_HT40));
+	len += snprintf(buf + len, size - len,
+			"%20s : %10d\n",
+			"Big Endian",
+			!!(pBase->eepMisc & 0x01));
+	len += snprintf(buf + len, size - len,
+			"%20s : %10d\n",
+			"Cal Bin Major Ver",
+			(pBase->binBuildNumber >> 24) & 0xFF);
+	len += snprintf(buf + len, size - len,
+			"%20s : %10d\n",
+			"Cal Bin Minor Ver",
+			(pBase->binBuildNumber >> 16) & 0xFF);
+	len += snprintf(buf + len, size - len,
+			"%20s : %10d\n",
+			"Cal Bin Build",
+			(pBase->binBuildNumber >> 8) & 0xFF);
+
+	/*
+	 * UB91 specific data.
+	 */
+	if (AR_SREV_9271(priv->ah)) {
+		struct base_eep_header_4k *pBase4k =
+			&priv->ah->eeprom.map4k.baseEepHeader;
+
+		len += snprintf(buf + len, size - len,
+				"%20s : %10d\n",
+				"TX Gain type",
+				pBase4k->txGainType);
+	}
+
+	/*
+	 * UB95 specific data.
+	 */
+	if (priv->ah->hw_version.usbdev == AR9287_USB) {
+		struct base_eep_ar9287_header *pBase9287 =
+			&priv->ah->eeprom.map9287.baseEepHeader;
+
+		len += snprintf(buf + len, size - len,
+				"%20s : %10ddB\n",
+				"Power Table Offset",
+				pBase9287->pwrTableOffset);
+
+		len += snprintf(buf + len, size - len,
+				"%20s : %10d\n",
+				"OpenLoop Power Ctrl",
+				pBase9287->openLoopPwrCntl);
+	}
+
+	len += snprintf(buf + len, size - len,
+			"%20s : %02X:%02X:%02X:%02X:%02X:%02X\n",
+			"MacAddress",
+			pBase->macAddr[0], pBase->macAddr[1], pBase->macAddr[2],
+			pBase->macAddr[3], pBase->macAddr[4], pBase->macAddr[5]);
+	if (len > size)
+		len = size;
+
+	retval = simple_read_from_buffer(user_buf, count, ppos, buf, len);
+	kfree(buf);
+
+	return retval;
+}
+
+static const struct file_operations fops_base_eeprom = {
+	.read = read_file_base_eeprom,
+	.open = ath9k_debugfs_open,
+	.owner = THIS_MODULE,
+	.llseek = default_llseek,
+};
+
+static ssize_t read_4k_modal_eeprom(struct file *file,
+				    char __user *user_buf,
+				    size_t count, loff_t *ppos)
+{
+#define PR_EEP(_s, _val)						\
+	do {								\
+		len += snprintf(buf + len, size - len, "%20s : %10d\n",	\
+				_s, (_val));				\
+	} while (0)
+
+	struct ath9k_htc_priv *priv = file->private_data;
+	struct modal_eep_4k_header *pModal = &priv->ah->eeprom.map4k.modalHeader;
+	unsigned int len = 0, size = 2048;
+	ssize_t retval = 0;
+	char *buf;
+
+	buf = kzalloc(size, GFP_KERNEL);
+	if (buf == NULL)
+		return -ENOMEM;
+
+	PR_EEP("Chain0 Ant. Control", pModal->antCtrlChain[0]);
+	PR_EEP("Ant. Common Control", pModal->antCtrlCommon);
+	PR_EEP("Chain0 Ant. Gain", pModal->antennaGainCh[0]);
+	PR_EEP("Switch Settle", pModal->switchSettling);
+	PR_EEP("Chain0 TxRxAtten", pModal->txRxAttenCh[0]);
+	PR_EEP("Chain0 RxTxMargin", pModal->rxTxMarginCh[0]);
+	PR_EEP("ADC Desired size", pModal->adcDesiredSize);
+	PR_EEP("PGA Desired size", pModal->pgaDesiredSize);
+	PR_EEP("Chain0 xlna Gain", pModal->xlnaGainCh[0]);
+	PR_EEP("txEndToXpaOff", pModal->txEndToXpaOff);
+	PR_EEP("txEndToRxOn", pModal->txEndToRxOn);
+	PR_EEP("txFrameToXpaOn", pModal->txFrameToXpaOn);
+	PR_EEP("CCA Threshold)", pModal->thresh62);
+	PR_EEP("Chain0 NF Threshold", pModal->noiseFloorThreshCh[0]);
+	PR_EEP("xpdGain", pModal->xpdGain);
+	PR_EEP("External PD", pModal->xpd);
+	PR_EEP("Chain0 I Coefficient", pModal->iqCalICh[0]);
+	PR_EEP("Chain0 Q Coefficient", pModal->iqCalQCh[0]);
+	PR_EEP("pdGainOverlap", pModal->pdGainOverlap);
+	PR_EEP("O/D Bias Version", pModal->version);
+	PR_EEP("CCK OutputBias", pModal->ob_0);
+	PR_EEP("BPSK OutputBias", pModal->ob_1);
+	PR_EEP("QPSK OutputBias", pModal->ob_2);
+	PR_EEP("16QAM OutputBias", pModal->ob_3);
+	PR_EEP("64QAM OutputBias", pModal->ob_4);
+	PR_EEP("CCK Driver1_Bias", pModal->db1_0);
+	PR_EEP("BPSK Driver1_Bias", pModal->db1_1);
+	PR_EEP("QPSK Driver1_Bias", pModal->db1_2);
+	PR_EEP("16QAM Driver1_Bias", pModal->db1_3);
+	PR_EEP("64QAM Driver1_Bias", pModal->db1_4);
+	PR_EEP("CCK Driver2_Bias", pModal->db2_0);
+	PR_EEP("BPSK Driver2_Bias", pModal->db2_1);
+	PR_EEP("QPSK Driver2_Bias", pModal->db2_2);
+	PR_EEP("16QAM Driver2_Bias", pModal->db2_3);
+	PR_EEP("64QAM Driver2_Bias", pModal->db2_4);
+	PR_EEP("xPA Bias Level", pModal->xpaBiasLvl);
+	PR_EEP("txFrameToDataStart", pModal->txFrameToDataStart);
+	PR_EEP("txFrameToPaOn", pModal->txFrameToPaOn);
+	PR_EEP("HT40 Power Inc.", pModal->ht40PowerIncForPdadc);
+	PR_EEP("Chain0 bswAtten", pModal->bswAtten[0]);
+	PR_EEP("Chain0 bswMargin", pModal->bswMargin[0]);
+	PR_EEP("HT40 Switch Settle", pModal->swSettleHt40);
+	PR_EEP("Chain0 xatten2Db", pModal->xatten2Db[0]);
+	PR_EEP("Chain0 xatten2Margin", pModal->xatten2Margin[0]);
+	PR_EEP("Ant. Diversity ctl1", pModal->antdiv_ctl1);
+	PR_EEP("Ant. Diversity ctl2", pModal->antdiv_ctl2);
+	PR_EEP("TX Diversity", pModal->tx_diversity);
+
+	if (len > size)
+		len = size;
+
+	retval = simple_read_from_buffer(user_buf, count, ppos, buf, len);
+	kfree(buf);
+
+	return retval;
+
+#undef PR_EEP
+}
+
+static ssize_t read_def_modal_eeprom(struct file *file,
+				     char __user *user_buf,
+				     size_t count, loff_t *ppos)
+{
+#define PR_EEP(_s, _val)						\
+	do {								\
+		if (pBase->opCapFlags & AR5416_OPFLAGS_11G) {		\
+			pModal = &priv->ah->eeprom.def.modalHeader[1];	\
+			len += snprintf(buf + len, size - len, "%20s : %8d%7s", \
+					_s, (_val), "|");		\
+		}							\
+		if (pBase->opCapFlags & AR5416_OPFLAGS_11A) {		\
+			pModal = &priv->ah->eeprom.def.modalHeader[0];	\
+			len += snprintf(buf + len, size - len, "%9d\n", \
+					(_val));			\
+		}							\
+	} while (0)
+
+	struct ath9k_htc_priv *priv = file->private_data;
+	struct base_eep_header *pBase = &priv->ah->eeprom.def.baseEepHeader;
+	struct modal_eep_header *pModal = NULL;
+	unsigned int len = 0, size = 3500;
+	ssize_t retval = 0;
+	char *buf;
+
+	buf = kzalloc(size, GFP_KERNEL);
+	if (buf == NULL)
+		return -ENOMEM;
+
+	len += snprintf(buf + len, size - len,
+			"%31s %15s\n", "2G", "5G");
+	len += snprintf(buf + len, size - len,
+			"%32s %16s\n", "====", "====\n");
+
+	PR_EEP("Chain0 Ant. Control", pModal->antCtrlChain[0]);
+	PR_EEP("Chain1 Ant. Control", pModal->antCtrlChain[1]);
+	PR_EEP("Chain2 Ant. Control", pModal->antCtrlChain[2]);
+	PR_EEP("Ant. Common Control", pModal->antCtrlCommon);
+	PR_EEP("Chain0 Ant. Gain", pModal->antennaGainCh[0]);
+	PR_EEP("Chain1 Ant. Gain", pModal->antennaGainCh[1]);
+	PR_EEP("Chain2 Ant. Gain", pModal->antennaGainCh[2]);
+	PR_EEP("Switch Settle", pModal->switchSettling);
+	PR_EEP("Chain0 TxRxAtten", pModal->txRxAttenCh[0]);
+	PR_EEP("Chain1 TxRxAtten", pModal->txRxAttenCh[1]);
+	PR_EEP("Chain2 TxRxAtten", pModal->txRxAttenCh[2]);
+	PR_EEP("Chain0 RxTxMargin", pModal->rxTxMarginCh[0]);
+	PR_EEP("Chain1 RxTxMargin", pModal->rxTxMarginCh[1]);
+	PR_EEP("Chain2 RxTxMargin", pModal->rxTxMarginCh[2]);
+	PR_EEP("ADC Desired size", pModal->adcDesiredSize);
+	PR_EEP("PGA Desired size", pModal->pgaDesiredSize);
+	PR_EEP("Chain0 xlna Gain", pModal->xlnaGainCh[0]);
+	PR_EEP("Chain1 xlna Gain", pModal->xlnaGainCh[1]);
+	PR_EEP("Chain2 xlna Gain", pModal->xlnaGainCh[2]);
+	PR_EEP("txEndToXpaOff", pModal->txEndToXpaOff);
+	PR_EEP("txEndToRxOn", pModal->txEndToRxOn);
+	PR_EEP("txFrameToXpaOn", pModal->txFrameToXpaOn);
+	PR_EEP("CCA Threshold)", pModal->thresh62);
+	PR_EEP("Chain0 NF Threshold", pModal->noiseFloorThreshCh[0]);
+	PR_EEP("Chain1 NF Threshold", pModal->noiseFloorThreshCh[1]);
+	PR_EEP("Chain2 NF Threshold", pModal->noiseFloorThreshCh[2]);
+	PR_EEP("xpdGain", pModal->xpdGain);
+	PR_EEP("External PD", pModal->xpd);
+	PR_EEP("Chain0 I Coefficient", pModal->iqCalICh[0]);
+	PR_EEP("Chain1 I Coefficient", pModal->iqCalICh[1]);
+	PR_EEP("Chain2 I Coefficient", pModal->iqCalICh[2]);
+	PR_EEP("Chain0 Q Coefficient", pModal->iqCalQCh[0]);
+	PR_EEP("Chain1 Q Coefficient", pModal->iqCalQCh[1]);
+	PR_EEP("Chain2 Q Coefficient", pModal->iqCalQCh[2]);
+	PR_EEP("pdGainOverlap", pModal->pdGainOverlap);
+	PR_EEP("Chain0 OutputBias", pModal->ob);
+	PR_EEP("Chain0 DriverBias", pModal->db);
+	PR_EEP("xPA Bias Level", pModal->xpaBiasLvl);
+	PR_EEP("2chain pwr decrease", pModal->pwrDecreaseFor2Chain);
+	PR_EEP("3chain pwr decrease", pModal->pwrDecreaseFor3Chain);
+	PR_EEP("txFrameToDataStart", pModal->txFrameToDataStart);
+	PR_EEP("txFrameToPaOn", pModal->txFrameToPaOn);
+	PR_EEP("HT40 Power Inc.", pModal->ht40PowerIncForPdadc);
+	PR_EEP("Chain0 bswAtten", pModal->bswAtten[0]);
+	PR_EEP("Chain1 bswAtten", pModal->bswAtten[1]);
+	PR_EEP("Chain2 bswAtten", pModal->bswAtten[2]);
+	PR_EEP("Chain0 bswMargin", pModal->bswMargin[0]);
+	PR_EEP("Chain1 bswMargin", pModal->bswMargin[1]);
+	PR_EEP("Chain2 bswMargin", pModal->bswMargin[2]);
+	PR_EEP("HT40 Switch Settle", pModal->swSettleHt40);
+	PR_EEP("Chain0 xatten2Db", pModal->xatten2Db[0]);
+	PR_EEP("Chain1 xatten2Db", pModal->xatten2Db[1]);
+	PR_EEP("Chain2 xatten2Db", pModal->xatten2Db[2]);
+	PR_EEP("Chain0 xatten2Margin", pModal->xatten2Margin[0]);
+	PR_EEP("Chain1 xatten2Margin", pModal->xatten2Margin[1]);
+	PR_EEP("Chain2 xatten2Margin", pModal->xatten2Margin[2]);
+	PR_EEP("Chain1 OutputBias", pModal->ob_ch1);
+	PR_EEP("Chain1 DriverBias", pModal->db_ch1);
+	PR_EEP("LNA Control", pModal->lna_ctl);
+	PR_EEP("XPA Bias Freq0", pModal->xpaBiasLvlFreq[0]);
+	PR_EEP("XPA Bias Freq1", pModal->xpaBiasLvlFreq[1]);
+	PR_EEP("XPA Bias Freq2", pModal->xpaBiasLvlFreq[2]);
+
+	if (len > size)
+		len = size;
+
+	retval = simple_read_from_buffer(user_buf, count, ppos, buf, len);
+	kfree(buf);
+
+	return retval;
+
+#undef PR_EEP
+}
+
+static ssize_t read_9287_modal_eeprom(struct file *file,
+				      char __user *user_buf,
+				      size_t count, loff_t *ppos)
+{
+#define PR_EEP(_s, _val)						\
+	do {								\
+		len += snprintf(buf + len, size - len, "%20s : %10d\n",	\
+				_s, (_val));				\
+	} while (0)
+
+	struct ath9k_htc_priv *priv = file->private_data;
+	struct modal_eep_ar9287_header *pModal = &priv->ah->eeprom.map9287.modalHeader;
+	unsigned int len = 0, size = 3000;
+	ssize_t retval = 0;
+	char *buf;
+
+	buf = kzalloc(size, GFP_KERNEL);
+	if (buf == NULL)
+		return -ENOMEM;
+
+	PR_EEP("Chain0 Ant. Control", pModal->antCtrlChain[0]);
+	PR_EEP("Chain1 Ant. Control", pModal->antCtrlChain[1]);
+	PR_EEP("Ant. Common Control", pModal->antCtrlCommon);
+	PR_EEP("Chain0 Ant. Gain", pModal->antennaGainCh[0]);
+	PR_EEP("Chain1 Ant. Gain", pModal->antennaGainCh[1]);
+	PR_EEP("Switch Settle", pModal->switchSettling);
+	PR_EEP("Chain0 TxRxAtten", pModal->txRxAttenCh[0]);
+	PR_EEP("Chain1 TxRxAtten", pModal->txRxAttenCh[1]);
+	PR_EEP("Chain0 RxTxMargin", pModal->rxTxMarginCh[0]);
+	PR_EEP("Chain1 RxTxMargin", pModal->rxTxMarginCh[1]);
+	PR_EEP("ADC Desired size", pModal->adcDesiredSize);
+	PR_EEP("txEndToXpaOff", pModal->txEndToXpaOff);
+	PR_EEP("txEndToRxOn", pModal->txEndToRxOn);
+	PR_EEP("txFrameToXpaOn", pModal->txFrameToXpaOn);
+	PR_EEP("CCA Threshold)", pModal->thresh62);
+	PR_EEP("Chain0 NF Threshold", pModal->noiseFloorThreshCh[0]);
+	PR_EEP("Chain1 NF Threshold", pModal->noiseFloorThreshCh[1]);
+	PR_EEP("xpdGain", pModal->xpdGain);
+	PR_EEP("External PD", pModal->xpd);
+	PR_EEP("Chain0 I Coefficient", pModal->iqCalICh[0]);
+	PR_EEP("Chain1 I Coefficient", pModal->iqCalICh[1]);
+	PR_EEP("Chain0 Q Coefficient", pModal->iqCalQCh[0]);
+	PR_EEP("Chain1 Q Coefficient", pModal->iqCalQCh[1]);
+	PR_EEP("pdGainOverlap", pModal->pdGainOverlap);
+	PR_EEP("xPA Bias Level", pModal->xpaBiasLvl);
+	PR_EEP("txFrameToDataStart", pModal->txFrameToDataStart);
+	PR_EEP("txFrameToPaOn", pModal->txFrameToPaOn);
+	PR_EEP("HT40 Power Inc.", pModal->ht40PowerIncForPdadc);
+	PR_EEP("Chain0 bswAtten", pModal->bswAtten[0]);
+	PR_EEP("Chain1 bswAtten", pModal->bswAtten[1]);
+	PR_EEP("Chain0 bswMargin", pModal->bswMargin[0]);
+	PR_EEP("Chain1 bswMargin", pModal->bswMargin[1]);
+	PR_EEP("HT40 Switch Settle", pModal->swSettleHt40);
+	PR_EEP("AR92x7 Version", pModal->version);
+	PR_EEP("DriverBias1", pModal->db1);
+	PR_EEP("DriverBias2", pModal->db1);
+	PR_EEP("CCK OutputBias", pModal->ob_cck);
+	PR_EEP("PSK OutputBias", pModal->ob_psk);
+	PR_EEP("QAM OutputBias", pModal->ob_qam);
+	PR_EEP("PAL_OFF OutputBias", pModal->ob_pal_off);
+
+	if (len > size)
+		len = size;
+
+	retval = simple_read_from_buffer(user_buf, count, ppos, buf, len);
+	kfree(buf);
+
+	return retval;
+
+#undef PR_EEP
+}
+
+static ssize_t read_file_modal_eeprom(struct file *file, char __user *user_buf,
+				      size_t count, loff_t *ppos)
+{
+	struct ath9k_htc_priv *priv = file->private_data;
+
+	if (AR_SREV_9271(priv->ah))
+		return read_4k_modal_eeprom(file, user_buf, count, ppos);
+	else if (priv->ah->hw_version.usbdev == AR9280_USB)
+		return read_def_modal_eeprom(file, user_buf, count, ppos);
+	else if (priv->ah->hw_version.usbdev == AR9287_USB)
+		return read_9287_modal_eeprom(file, user_buf, count, ppos);
+
+	return 0;
+}
+
+static const struct file_operations fops_modal_eeprom = {
+	.read = read_file_modal_eeprom,
+	.open = ath9k_debugfs_open,
+	.owner = THIS_MODULE,
+	.llseek = default_llseek,
+};
+
+int ath9k_htc_init_debug(struct ath_hw *ah)
+{
+	struct ath_common *common = ath9k_hw_common(ah);
+	struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *) common->priv;
+
+	priv->debug.debugfs_phy = debugfs_create_dir(KBUILD_MODNAME,
+					     priv->hw->wiphy->debugfsdir);
+	if (!priv->debug.debugfs_phy)
+		return -ENOMEM;
+
+	debugfs_create_file("tgt_int_stats", S_IRUSR, priv->debug.debugfs_phy,
+			    priv, &fops_tgt_int_stats);
+	debugfs_create_file("tgt_tx_stats", S_IRUSR, priv->debug.debugfs_phy,
+			    priv, &fops_tgt_tx_stats);
+	debugfs_create_file("tgt_rx_stats", S_IRUSR, priv->debug.debugfs_phy,
+			    priv, &fops_tgt_rx_stats);
+	debugfs_create_file("xmit", S_IRUSR, priv->debug.debugfs_phy,
+			    priv, &fops_xmit);
+	debugfs_create_file("recv", S_IRUSR, priv->debug.debugfs_phy,
+			    priv, &fops_recv);
+	debugfs_create_file("slot", S_IRUSR, priv->debug.debugfs_phy,
+			    priv, &fops_slot);
+	debugfs_create_file("queue", S_IRUSR, priv->debug.debugfs_phy,
+			    priv, &fops_queue);
+	debugfs_create_file("debug", S_IRUSR | S_IWUSR, priv->debug.debugfs_phy,
+			    priv, &fops_debug);
+	debugfs_create_file("base_eeprom", S_IRUSR, priv->debug.debugfs_phy,
+			    priv, &fops_base_eeprom);
+	debugfs_create_file("modal_eeprom", S_IRUSR, priv->debug.debugfs_phy,
+			    priv, &fops_modal_eeprom);
+
+	return 0;
+}
diff -druN linux-2.6.39-libre/drivers/net/wireless/ath/ath9k/htc_drv_gpio.c linux-3.0-rc7-libre/drivers/net/wireless/ath/ath9k/htc_drv_gpio.c
--- linux-2.6.39-libre/drivers/net/wireless/ath/ath9k/htc_drv_gpio.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/ath/ath9k/htc_drv_gpio.c	2011-07-11 19:51:52.000000000 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010 Atheros Communications Inc.
+ * Copyright (c) 2010-2011 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
@@ -65,17 +65,19 @@
 	u32 timer_period;
 	bool is_btscan;
 	int ret;
-	u8 cmd_rsp, aggr;
 
 	ath_detect_bt_priority(priv);
 
 	is_btscan = !!(priv->op_flags & OP_BT_SCAN);
 
-	aggr = priv->op_flags & OP_BT_PRIORITY_DETECTED;
-
-	WMI_CMD_BUF(WMI_AGGR_LIMIT_CMD, &aggr);
+	ret = ath9k_htc_update_cap_target(priv,
+				  !!(priv->op_flags & OP_BT_PRIORITY_DETECTED));
+	if (ret) {
+		ath_err(common, "Unable to set BTCOEX parameters\n");
+		return;
+	}
 
-	ath9k_cmn_btcoex_bt_stomp(common, is_btscan ? ATH_BTCOEX_STOMP_ALL :
+	ath9k_hw_btcoex_bt_stomp(priv->ah, is_btscan ? ATH_BTCOEX_STOMP_ALL :
 			btcoex->bt_stomp_type);
 
 	timer_period = is_btscan ? btcoex->btscan_no_stomp :
@@ -103,9 +105,9 @@
 		"time slice work for bt and wlan\n");
 
 	if (btcoex->bt_stomp_type == ATH_BTCOEX_STOMP_LOW || is_btscan)
-		ath9k_cmn_btcoex_bt_stomp(common, ATH_BTCOEX_STOMP_NONE);
+		ath9k_hw_btcoex_bt_stomp(ah, ATH_BTCOEX_STOMP_NONE);
 	else if (btcoex->bt_stomp_type == ATH_BTCOEX_STOMP_ALL)
-		ath9k_cmn_btcoex_bt_stomp(common, ATH_BTCOEX_STOMP_LOW);
+		ath9k_hw_btcoex_bt_stomp(ah, ATH_BTCOEX_STOMP_LOW);
 }
 
 void ath_htc_init_btcoex_work(struct ath9k_htc_priv *priv)
@@ -152,140 +154,41 @@
 /* LED */
 /*******/
 
-static void ath9k_led_blink_work(struct work_struct *work)
-{
-	struct ath9k_htc_priv *priv = container_of(work, struct ath9k_htc_priv,
-						   ath9k_led_blink_work.work);
-
-	if (!(priv->op_flags & OP_LED_ASSOCIATED))
-		return;
-
-	if ((priv->led_on_duration == ATH_LED_ON_DURATION_IDLE) ||
-	    (priv->led_off_duration == ATH_LED_OFF_DURATION_IDLE))
-		ath9k_hw_set_gpio(priv->ah, priv->ah->led_pin, 0);
-	else
-		ath9k_hw_set_gpio(priv->ah, priv->ah->led_pin,
-				  (priv->op_flags & OP_LED_ON) ? 1 : 0);
-
-	ieee80211_queue_delayed_work(priv->hw,
-				     &priv->ath9k_led_blink_work,
-				     (priv->op_flags & OP_LED_ON) ?
-				     msecs_to_jiffies(priv->led_off_duration) :
-				     msecs_to_jiffies(priv->led_on_duration));
-
-	priv->led_on_duration = priv->led_on_cnt ?
-		max((ATH_LED_ON_DURATION_IDLE - priv->led_on_cnt), 25) :
-		ATH_LED_ON_DURATION_IDLE;
-	priv->led_off_duration = priv->led_off_cnt ?
-		max((ATH_LED_OFF_DURATION_IDLE - priv->led_off_cnt), 10) :
-		ATH_LED_OFF_DURATION_IDLE;
-	priv->led_on_cnt = priv->led_off_cnt = 0;
-
-	if (priv->op_flags & OP_LED_ON)
-		priv->op_flags &= ~OP_LED_ON;
-	else
-		priv->op_flags |= OP_LED_ON;
-}
-
-static void ath9k_led_brightness_work(struct work_struct *work)
+#ifdef CONFIG_MAC80211_LEDS
+void ath9k_led_work(struct work_struct *work)
 {
-	struct ath_led *led = container_of(work, struct ath_led,
-					   brightness_work.work);
-	struct ath9k_htc_priv *priv = led->priv;
+	struct ath9k_htc_priv *priv = container_of(work,
+						   struct ath9k_htc_priv,
+						   led_work);
 
-	switch (led->brightness) {
-	case LED_OFF:
-		if (led->led_type == ATH_LED_ASSOC ||
-		    led->led_type == ATH_LED_RADIO) {
-			ath9k_hw_set_gpio(priv->ah, priv->ah->led_pin,
-					  (led->led_type == ATH_LED_RADIO));
-			priv->op_flags &= ~OP_LED_ASSOCIATED;
-			if (led->led_type == ATH_LED_RADIO)
-				priv->op_flags &= ~OP_LED_ON;
-		} else {
-			priv->led_off_cnt++;
-		}
-		break;
-	case LED_FULL:
-		if (led->led_type == ATH_LED_ASSOC) {
-			priv->op_flags |= OP_LED_ASSOCIATED;
-			ieee80211_queue_delayed_work(priv->hw,
-					     &priv->ath9k_led_blink_work, 0);
-		} else if (led->led_type == ATH_LED_RADIO) {
-			ath9k_hw_set_gpio(priv->ah, priv->ah->led_pin, 0);
-			priv->op_flags |= OP_LED_ON;
-		} else {
-			priv->led_on_cnt++;
-		}
-		break;
-	default:
-		break;
-	}
+	ath9k_hw_set_gpio(priv->ah, priv->ah->led_pin,
+			  (priv->brightness == LED_OFF));
 }
 
 static void ath9k_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 ath9k_htc_priv *priv = led->priv;
-
-	led->brightness = brightness;
-	if (!(priv->op_flags & OP_LED_DEINIT))
-		ieee80211_queue_delayed_work(priv->hw,
-					     &led->brightness_work, 0);
-}
-
-void ath9k_led_stop_brightness(struct ath9k_htc_priv *priv)
-{
-	cancel_delayed_work_sync(&priv->radio_led.brightness_work);
-	cancel_delayed_work_sync(&priv->assoc_led.brightness_work);
-	cancel_delayed_work_sync(&priv->tx_led.brightness_work);
-	cancel_delayed_work_sync(&priv->rx_led.brightness_work);
-}
-
-static int ath9k_register_led(struct ath9k_htc_priv *priv, struct ath_led *led,
-			      char *trigger)
-{
-	int ret;
-
-	led->priv = priv;
-	led->led_cdev.name = led->name;
-	led->led_cdev.default_trigger = trigger;
-	led->led_cdev.brightness_set = ath9k_led_brightness;
-
-	ret = led_classdev_register(wiphy_dev(priv->hw->wiphy), &led->led_cdev);
-	if (ret)
-		ath_err(ath9k_hw_common(priv->ah),
-			"Failed to register led:%s", led->name);
-	else
-		led->registered = 1;
-
-	INIT_DELAYED_WORK(&led->brightness_work, ath9k_led_brightness_work);
-
-	return ret;
-}
+	struct ath9k_htc_priv *priv = container_of(led_cdev,
+						   struct ath9k_htc_priv,
+						   led_cdev);
 
-static void ath9k_unregister_led(struct ath_led *led)
-{
-	if (led->registered) {
-		led_classdev_unregister(&led->led_cdev);
-		led->registered = 0;
-	}
+	/* Not locked, but it's just a tiny green light..*/
+	priv->brightness = brightness;
+	ieee80211_queue_work(priv->hw, &priv->led_work);
 }
 
 void ath9k_deinit_leds(struct ath9k_htc_priv *priv)
 {
-	priv->op_flags |= OP_LED_DEINIT;
-	ath9k_unregister_led(&priv->assoc_led);
-	priv->op_flags &= ~OP_LED_ASSOCIATED;
-	ath9k_unregister_led(&priv->tx_led);
-	ath9k_unregister_led(&priv->rx_led);
-	ath9k_unregister_led(&priv->radio_led);
+	if (!priv->led_registered)
+		return;
+
+	ath9k_led_brightness(&priv->led_cdev, LED_OFF);
+	led_classdev_unregister(&priv->led_cdev);
+	cancel_work_sync(&priv->led_work);
 }
 
 void ath9k_init_leds(struct ath9k_htc_priv *priv)
 {
-	char *trigger;
 	int ret;
 
 	if (AR_SREV_9287(priv->ah))
@@ -303,48 +206,21 @@
 	/* LED off, active low */
 	ath9k_hw_set_gpio(priv->ah, priv->ah->led_pin, 1);
 
-	INIT_DELAYED_WORK(&priv->ath9k_led_blink_work, ath9k_led_blink_work);
-
-	trigger = ieee80211_get_radio_led_name(priv->hw);
-	snprintf(priv->radio_led.name, sizeof(priv->radio_led.name),
-		"ath9k-%s::radio", wiphy_name(priv->hw->wiphy));
-	ret = ath9k_register_led(priv, &priv->radio_led, trigger);
-	priv->radio_led.led_type = ATH_LED_RADIO;
-	if (ret)
-		goto fail;
-
-	trigger = ieee80211_get_assoc_led_name(priv->hw);
-	snprintf(priv->assoc_led.name, sizeof(priv->assoc_led.name),
-		"ath9k-%s::assoc", wiphy_name(priv->hw->wiphy));
-	ret = ath9k_register_led(priv, &priv->assoc_led, trigger);
-	priv->assoc_led.led_type = ATH_LED_ASSOC;
-	if (ret)
-		goto fail;
-
-	trigger = ieee80211_get_tx_led_name(priv->hw);
-	snprintf(priv->tx_led.name, sizeof(priv->tx_led.name),
-		"ath9k-%s::tx", wiphy_name(priv->hw->wiphy));
-	ret = ath9k_register_led(priv, &priv->tx_led, trigger);
-	priv->tx_led.led_type = ATH_LED_TX;
-	if (ret)
-		goto fail;
+	snprintf(priv->led_name, sizeof(priv->led_name),
+		"ath9k_htc-%s", wiphy_name(priv->hw->wiphy));
+	priv->led_cdev.name = priv->led_name;
+	priv->led_cdev.brightness_set = ath9k_led_brightness;
 
-	trigger = ieee80211_get_rx_led_name(priv->hw);
-	snprintf(priv->rx_led.name, sizeof(priv->rx_led.name),
-		"ath9k-%s::rx", wiphy_name(priv->hw->wiphy));
-	ret = ath9k_register_led(priv, &priv->rx_led, trigger);
-	priv->rx_led.led_type = ATH_LED_RX;
-	if (ret)
-		goto fail;
+	ret = led_classdev_register(wiphy_dev(priv->hw->wiphy), &priv->led_cdev);
+	if (ret < 0)
+		return;
 
-	priv->op_flags &= ~OP_LED_DEINIT;
+	INIT_WORK(&priv->led_work, ath9k_led_work);
+	priv->led_registered = true;
 
 	return;
-
-fail:
-	cancel_delayed_work_sync(&priv->ath9k_led_blink_work);
-	ath9k_deinit_leds(priv);
 }
+#endif
 
 /*******************/
 /*	Rfkill	   */
@@ -398,9 +274,9 @@
 
 	/* Start TX */
 	htc_start(priv->htc);
-	spin_lock_bh(&priv->tx_lock);
-	priv->tx_queues_stop = false;
-	spin_unlock_bh(&priv->tx_lock);
+	spin_lock_bh(&priv->tx.tx_lock);
+	priv->tx.flags &= ~ATH9K_HTC_OP_TX_QUEUES_STOP;
+	spin_unlock_bh(&priv->tx.tx_lock);
 	ieee80211_wake_queues(hw);
 
 	WMI_CMD(WMI_ENABLE_INTR_CMDID);
@@ -429,13 +305,15 @@
 
 	/* Stop TX */
 	ieee80211_stop_queues(hw);
-	htc_stop(priv->htc);
+	ath9k_htc_tx_drain(priv);
 	WMI_CMD(WMI_DRAIN_TXQ_ALL_CMDID);
-	skb_queue_purge(&priv->tx_queue);
 
 	/* Stop RX */
 	WMI_CMD(WMI_STOP_RECV_CMDID);
 
+	/* Clear the WMI event queue */
+	ath9k_wmi_event_drain(priv);
+
 	/*
 	 * The MIB counters have to be disabled here,
 	 * since the target doesn't do it.
diff -druN linux-2.6.39-libre/drivers/net/wireless/ath/ath9k/htc_drv_init.c linux-3.0-rc7-libre/drivers/net/wireless/ath/ath9k/htc_drv_init.c
--- linux-2.6.39-libre/drivers/net/wireless/ath/ath9k/htc_drv_init.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/ath/ath9k/htc_drv_init.c	2011-07-11 19:51:52.000000000 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010 Atheros Communications Inc.
+ * Copyright (c) 2010-2011 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
@@ -117,6 +117,21 @@
 	RATE(540, 0x0c, 0),
 };
 
+#ifdef CONFIG_MAC80211_LEDS
+static const struct ieee80211_tpt_blink ath9k_htc_tpt_blink[] = {
+	{ .throughput = 0 * 1024, .blink_time = 334 },
+	{ .throughput = 1 * 1024, .blink_time = 260 },
+	{ .throughput = 5 * 1024, .blink_time = 220 },
+	{ .throughput = 10 * 1024, .blink_time = 190 },
+	{ .throughput = 20 * 1024, .blink_time = 170 },
+	{ .throughput = 50 * 1024, .blink_time = 150 },
+	{ .throughput = 70 * 1024, .blink_time = 130 },
+	{ .throughput = 100 * 1024, .blink_time = 110 },
+	{ .throughput = 200 * 1024, .blink_time = 80 },
+	{ .throughput = 300 * 1024, .blink_time = 50 },
+};
+#endif
+
 static int ath9k_htc_wait_for_target(struct ath9k_htc_priv *priv)
 {
 	int time_left;
@@ -140,7 +155,6 @@
 
 static void ath9k_deinit_priv(struct ath9k_htc_priv *priv)
 {
-	ath9k_htc_exit_debug(priv->ah);
 	ath9k_hw_deinit(priv->ah);
 	kfree(priv->ah);
 	priv->ah = NULL;
@@ -430,13 +444,16 @@
 	mutex_unlock(&priv->wmi->multi_write_mutex);
 }
 
-static const struct ath_ops ath9k_common_ops = {
-	.read = ath9k_regread,
-	.multi_read = ath9k_multi_regread,
-	.write = ath9k_regwrite,
-	.enable_write_buffer = ath9k_enable_regwrite_buffer,
-	.write_flush = ath9k_regwrite_flush,
-};
+static u32 ath9k_reg_rmw(void *hw_priv, u32 reg_offset, u32 set, u32 clr)
+{
+	u32 val;
+
+	val = ath9k_regread(hw_priv, reg_offset);
+	val &= ~clr;
+	val |= set;
+	ath9k_regwrite(hw_priv, val, reg_offset);
+	return val;
+}
 
 static void ath_usb_read_cachesize(struct ath_common *common, int *csz)
 {
@@ -561,13 +578,7 @@
 	int i = 0;
 
 	/* Get the hardware key cache size. */
-	common->keymax = priv->ah->caps.keycache_size;
-	if (common->keymax > ATH_KEYMAX) {
-		ath_dbg(common, ATH_DBG_ANY,
-			"Warning, using only %u entries in %u key cache\n",
-			ATH_KEYMAX, common->keymax);
-		common->keymax = ATH_KEYMAX;
-	}
+	common->keymax = AR_KEYTABLE_SIZE;
 
 	if (priv->ah->misc_mode & AR_PCU_MIC_NEW_LOC_ENA)
 		common->crypt_caps |= ATH_CRYPT_CAP_MIC_COMBINED;
@@ -646,7 +657,7 @@
 {
 	struct ath_hw *ah = NULL;
 	struct ath_common *common;
-	int ret = 0, csz = 0;
+	int i, ret = 0, csz = 0;
 
 	priv->op_flags |= OP_INVALID;
 
@@ -658,30 +669,35 @@
 	ah->hw_version.subsysid = 0; /* FIXME */
 	ah->hw_version.usbdev = drv_info;
 	ah->ah_flags |= AH_USE_EEPROM;
+	ah->reg_ops.read = ath9k_regread;
+	ah->reg_ops.multi_read = ath9k_multi_regread;
+	ah->reg_ops.write = ath9k_regwrite;
+	ah->reg_ops.enable_write_buffer = ath9k_enable_regwrite_buffer;
+	ah->reg_ops.write_flush = ath9k_regwrite_flush;
+	ah->reg_ops.rmw = ath9k_reg_rmw;
 	priv->ah = ah;
 
 	common = ath9k_hw_common(ah);
-	common->ops = &ath9k_common_ops;
+	common->ops = &ah->reg_ops;
 	common->bus_ops = &ath9k_usb_bus_ops;
 	common->ah = ah;
 	common->hw = priv->hw;
 	common->priv = priv;
 	common->debug_mask = ath9k_debug;
 
-	spin_lock_init(&priv->wmi->wmi_lock);
 	spin_lock_init(&priv->beacon_lock);
-	spin_lock_init(&priv->tx_lock);
+	spin_lock_init(&priv->tx.tx_lock);
 	mutex_init(&priv->mutex);
 	mutex_init(&priv->htc_pm_lock);
-	tasklet_init(&priv->swba_tasklet, ath9k_swba_tasklet,
-		     (unsigned long)priv);
 	tasklet_init(&priv->rx_tasklet, ath9k_rx_tasklet,
 		     (unsigned long)priv);
-	tasklet_init(&priv->tx_tasklet, ath9k_tx_tasklet,
+	tasklet_init(&priv->tx_failed_tasklet, ath9k_tx_failed_tasklet,
 		     (unsigned long)priv);
 	INIT_DELAYED_WORK(&priv->ani_work, ath9k_htc_ani_work);
 	INIT_WORK(&priv->ps_work, ath9k_ps_work);
 	INIT_WORK(&priv->fatal_work, ath9k_fatal_work);
+	setup_timer(&priv->tx.cleanup_timer, ath9k_htc_tx_cleanup_timer,
+		    (unsigned long)priv);
 
 	/*
 	 * Cache line size is used to size and align various
@@ -698,16 +714,13 @@
 		goto err_hw;
 	}
 
-	ret = ath9k_htc_init_debug(ah);
-	if (ret) {
-		ath_err(common, "Unable to create debugfs files\n");
-		goto err_debug;
-	}
-
 	ret = ath9k_init_queues(priv);
 	if (ret)
 		goto err_queues;
 
+	for (i = 0; i < ATH9K_HTC_MAX_BCN_VIF; i++)
+		priv->cur_beacon_conf.bslot[i] = NULL;
+
 	ath9k_init_crypto(priv);
 	ath9k_init_channels_rates(priv);
 	ath9k_init_misc(priv);
@@ -720,8 +733,6 @@
 	return 0;
 
 err_queues:
-	ath9k_htc_exit_debug(ah);
-err_debug:
 	ath9k_hw_deinit(ah);
 err_hw:
 
@@ -742,17 +753,22 @@
 		IEEE80211_HW_HAS_RATE_CONTROL |
 		IEEE80211_HW_RX_INCLUDES_FCS |
 		IEEE80211_HW_SUPPORTS_PS |
-		IEEE80211_HW_PS_NULLFUNC_STACK;
+		IEEE80211_HW_PS_NULLFUNC_STACK |
+		IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING;
 
 	hw->wiphy->interface_modes =
 		BIT(NL80211_IFTYPE_STATION) |
-		BIT(NL80211_IFTYPE_ADHOC);
+		BIT(NL80211_IFTYPE_ADHOC) |
+		BIT(NL80211_IFTYPE_AP) |
+		BIT(NL80211_IFTYPE_P2P_GO) |
+		BIT(NL80211_IFTYPE_P2P_CLIENT);
 
 	hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT;
 
 	hw->queues = 4;
 	hw->channel_change_time = 5000;
 	hw->max_listen_interval = 10;
+
 	hw->vif_data_size = sizeof(struct ath9k_htc_vif);
 	hw->sta_data_size = sizeof(struct ath9k_htc_sta);
 
@@ -779,6 +795,43 @@
 	SET_IEEE80211_PERM_ADDR(hw, common->macaddr);
 }
 
+static int ath9k_init_firmware_version(struct ath9k_htc_priv *priv)
+{
+	struct ieee80211_hw *hw = priv->hw;
+	struct wmi_fw_version cmd_rsp;
+	int ret;
+
+	memset(&cmd_rsp, 0, sizeof(cmd_rsp));
+
+	WMI_CMD(WMI_GET_FW_VERSION);
+	if (ret)
+		return -EINVAL;
+
+	priv->fw_version_major = be16_to_cpu(cmd_rsp.major);
+	priv->fw_version_minor = be16_to_cpu(cmd_rsp.minor);
+
+	snprintf(hw->wiphy->fw_version, ETHTOOL_BUSINFO_LEN, "%d.%d",
+		 priv->fw_version_major,
+		 priv->fw_version_minor);
+
+	dev_info(priv->dev, "ath9k_htc: FW Version: %d.%d\n",
+		 priv->fw_version_major,
+		 priv->fw_version_minor);
+
+	/*
+	 * Check if the available FW matches the driver's
+	 * required version.
+	 */
+	if (priv->fw_version_major != MAJOR_VERSION_REQ ||
+	    priv->fw_version_minor != MINOR_VERSION_REQ) {
+		dev_err(priv->dev, "ath9k_htc: Please upgrade to FW version %d.%d\n",
+			MAJOR_VERSION_REQ, MINOR_VERSION_REQ);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
 static int ath9k_init_device(struct ath9k_htc_priv *priv,
 			     u16 devid, char *product, u32 drv_info)
 {
@@ -798,6 +851,10 @@
 	common = ath9k_hw_common(ah);
 	ath9k_set_hw_capab(priv, hw);
 
+	error = ath9k_init_firmware_version(priv);
+	if (error != 0)
+		goto err_fw;
+
 	/* Initialize regulatory */
 	error = ath_regd_init(&common->regulatory, priv->hw->wiphy,
 			      ath9k_reg_notifier);
@@ -816,6 +873,13 @@
 	if (error != 0)
 		goto err_rx;
 
+#ifdef CONFIG_MAC80211_LEDS
+	/* must be initialized before ieee80211_register_hw */
+	priv->led_cdev.default_trigger = ieee80211_create_tpt_led_trigger(priv->hw,
+		IEEE80211_TPT_LEDTRIG_FL_RADIO, ath9k_htc_tpt_blink,
+		ARRAY_SIZE(ath9k_htc_tpt_blink));
+#endif
+
 	/* Register with mac80211 */
 	error = ieee80211_register_hw(hw);
 	if (error)
@@ -828,6 +892,12 @@
 			goto err_world;
 	}
 
+	error = ath9k_htc_init_debug(priv->ah);
+	if (error) {
+		ath_err(common, "Unable to create debugfs files\n");
+		goto err_world;
+	}
+
 	ath_dbg(common, ATH_DBG_CONFIG,
 		"WMI:%d, BCN:%d, CAB:%d, UAPSD:%d, MGMT:%d, "
 		"BE:%d, BK:%d, VI:%d, VO:%d\n",
@@ -858,6 +928,8 @@
 err_tx:
 	/* Nothing */
 err_regd:
+	/* Nothing */
+err_fw:
 	ath9k_deinit_priv(priv);
 err_init:
 	return error;
@@ -946,38 +1018,20 @@
 
 static int __init ath9k_htc_init(void)
 {
-	int error;
-
-	error = ath9k_htc_debug_create_root();
-	if (error < 0) {
-		printk(KERN_ERR
-			"ath9k_htc: Unable to create debugfs root: %d\n",
-			error);
-		goto err_dbg;
-	}
-
-	error = ath9k_hif_usb_init();
-	if (error < 0) {
+	if (ath9k_hif_usb_init() < 0) {
 		printk(KERN_ERR
 			"ath9k_htc: No USB devices found,"
 			" driver not installed.\n");
-		error = -ENODEV;
-		goto err_usb;
+		return -ENODEV;
 	}
 
 	return 0;
-
-err_usb:
-	ath9k_htc_debug_remove_root();
-err_dbg:
-	return error;
 }
 module_init(ath9k_htc_init);
 
 static void __exit ath9k_htc_exit(void)
 {
 	ath9k_hif_usb_exit();
-	ath9k_htc_debug_remove_root();
 	printk(KERN_INFO "ath9k_htc: Driver unloaded\n");
 }
 module_exit(ath9k_htc_exit);
diff -druN linux-2.6.39-libre/drivers/net/wireless/ath/ath9k/htc_drv_main.c linux-3.0-rc7-libre/drivers/net/wireless/ath/ath9k/htc_drv_main.c
--- linux-2.6.39-libre/drivers/net/wireless/ath/ath9k/htc_drv_main.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/ath/ath9k/htc_drv_main.c	2011-07-11 19:51:52.000000000 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010 Atheros Communications Inc.
+ * Copyright (c) 2010-2011 Atheros Communications Inc.
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
@@ -16,10 +16,6 @@
 
 #include "htc.h"
 
-#ifdef CONFIG_ATH9K_HTC_DEBUGFS
-static struct dentry *ath9k_debugfs_root;
-#endif
-
 /*************/
 /* Utilities */
 /*************/
@@ -30,7 +26,7 @@
 {
 	enum htc_phymode mode;
 
-	mode = HTC_MODE_AUTO;
+	mode = -EINVAL;
 
 	switch (ichan->chanmode) {
 	case CHANNEL_G:
@@ -49,6 +45,8 @@
 		break;
 	}
 
+	WARN_ON(mode < 0);
+
 	return mode;
 }
 
@@ -197,11 +195,16 @@
 
 	ath9k_htc_stop_ani(priv);
 	ieee80211_stop_queues(priv->hw);
-	htc_stop(priv->htc);
+
+	del_timer_sync(&priv->tx.cleanup_timer);
+	ath9k_htc_tx_drain(priv);
+
 	WMI_CMD(WMI_DISABLE_INTR_CMDID);
 	WMI_CMD(WMI_DRAIN_TXQ_ALL_CMDID);
 	WMI_CMD(WMI_STOP_RECV_CMDID);
 
+	ath9k_wmi_event_drain(priv);
+
 	caldata = &priv->caldata;
 	ret = ath9k_hw_reset(ah, ah->curchan, caldata, false);
 	if (ret) {
@@ -225,6 +228,9 @@
 	ath9k_htc_vif_reconfig(priv);
 	ieee80211_wake_queues(priv->hw);
 
+	mod_timer(&priv->tx.cleanup_timer,
+		  jiffies + msecs_to_jiffies(ATH9K_HTC_TX_CLEANUP_INTERVAL));
+
 	ath9k_htc_ps_restore(priv);
 	mutex_unlock(&priv->mutex);
 }
@@ -250,11 +256,16 @@
 	fastcc = !!(hw->conf.flags & IEEE80211_CONF_OFFCHANNEL);
 
 	ath9k_htc_ps_wakeup(priv);
-	htc_stop(priv->htc);
+
+	del_timer_sync(&priv->tx.cleanup_timer);
+	ath9k_htc_tx_drain(priv);
+
 	WMI_CMD(WMI_DISABLE_INTR_CMDID);
 	WMI_CMD(WMI_DRAIN_TXQ_ALL_CMDID);
 	WMI_CMD(WMI_STOP_RECV_CMDID);
 
+	ath9k_wmi_event_drain(priv);
+
 	ath_dbg(common, ATH_DBG_CONFIG,
 		"(%u MHz) -> (%u MHz), HT: %d, HT40: %d fastcc: %d\n",
 		priv->ah->curchan->channel,
@@ -263,6 +274,7 @@
 
 	if (!fastcc)
 		caldata = &priv->caldata;
+
 	ret = ath9k_hw_reset(ah, hchan, caldata, fastcc);
 	if (ret) {
 		ath_err(common,
@@ -296,6 +308,9 @@
 	    !(hw->conf.flags & IEEE80211_CONF_OFFCHANNEL))
 		ath9k_htc_vif_reconfig(priv);
 
+	mod_timer(&priv->tx.cleanup_timer,
+		  jiffies + msecs_to_jiffies(ATH9K_HTC_TX_CLEANUP_INTERVAL));
+
 err:
 	ath9k_htc_ps_restore(priv);
 	return ret;
@@ -319,6 +334,11 @@
 	memcpy(&hvif.myaddr, common->macaddr, ETH_ALEN);
 	hvif.index = priv->mon_vif_idx;
 	WMI_CMD_BUF(WMI_VAP_REMOVE_CMDID, &hvif);
+	if (ret) {
+		ath_err(common, "Unable to remove monitor interface at idx: %d\n",
+			priv->mon_vif_idx);
+	}
+
 	priv->nvifs--;
 	priv->vif_slot &= ~(1 << priv->mon_vif_idx);
 }
@@ -349,7 +369,7 @@
 	memset(&hvif, 0, sizeof(struct ath9k_htc_target_vif));
 	memcpy(&hvif.myaddr, common->macaddr, ETH_ALEN);
 
-	hvif.opmode = cpu_to_be32(HTC_M_MONITOR);
+	hvif.opmode = HTC_M_MONITOR;
 	hvif.index = ffz(priv->vif_slot);
 
 	WMI_CMD_BUF(WMI_VAP_CREATE_CMDID, &hvif);
@@ -382,7 +402,7 @@
 	tsta.is_vif_sta = 1;
 	tsta.sta_index = sta_idx;
 	tsta.vif_index = hvif.index;
-	tsta.maxampdu = 0xffff;
+	tsta.maxampdu = cpu_to_be16(0xffff);
 
 	WMI_CMD_BUF(WMI_NODE_CREATE_CMDID, &tsta);
 	if (ret) {
@@ -449,6 +469,7 @@
 	struct ath9k_htc_sta *ista;
 	int ret, sta_idx;
 	u8 cmd_rsp;
+	u16 maxampdu;
 
 	if (priv->nstations >= ATH9K_HTC_MAX_STA)
 		return -ENOBUFS;
@@ -463,9 +484,7 @@
 		ista = (struct ath9k_htc_sta *) sta->drv_priv;
 		memcpy(&tsta.macaddr, sta->addr, ETH_ALEN);
 		memcpy(&tsta.bssid, common->curbssid, ETH_ALEN);
-		tsta.associd = common->curaid;
 		tsta.is_vif_sta = 0;
-		tsta.valid = true;
 		ista->index = sta_idx;
 	} else {
 		memcpy(&tsta.macaddr, vif->addr, ETH_ALEN);
@@ -474,9 +493,14 @@
 
 	tsta.sta_index = sta_idx;
 	tsta.vif_index = avp->index;
-	tsta.maxampdu = 0xffff;
-	if (sta && sta->ht_cap.ht_supported)
-		tsta.flags = cpu_to_be16(ATH_HTC_STA_HT);
+
+	if (!sta) {
+		tsta.maxampdu = cpu_to_be16(0xffff);
+	} else {
+		maxampdu = 1 << (IEEE80211_HT_MAX_AMPDU_FACTOR +
+				 sta->ht_cap.ampdu_factor);
+		tsta.maxampdu = cpu_to_be16(maxampdu);
+	}
 
 	WMI_CMD_BUF(WMI_NODE_CREATE_CMDID, &tsta);
 	if (ret) {
@@ -547,7 +571,8 @@
 	return 0;
 }
 
-int ath9k_htc_update_cap_target(struct ath9k_htc_priv *priv)
+int ath9k_htc_update_cap_target(struct ath9k_htc_priv *priv,
+				u8 enable_coex)
 {
 	struct ath9k_htc_cap_target tcap;
 	int ret;
@@ -555,13 +580,9 @@
 
 	memset(&tcap, 0, sizeof(struct ath9k_htc_cap_target));
 
-	/* FIXME: Values are hardcoded */
-	tcap.flags = 0x240c40;
-	tcap.flags_ext = 0x80601000;
-	tcap.ampdu_limit = 0xffff0000;
-	tcap.ampdu_subframes = 20;
-	tcap.tx_chainmask_legacy = priv->ah->caps.tx_chainmask;
-	tcap.protmode = 1;
+	tcap.ampdu_limit = cpu_to_be32(0xffff);
+	tcap.ampdu_subframes = 0xff;
+	tcap.enable_coex = enable_coex;
 	tcap.tx_chainmask = priv->ah->caps.tx_chainmask;
 
 	WMI_CMD_BUF(WMI_TARGET_IC_UPDATE_CMDID, &tcap);
@@ -709,218 +730,13 @@
 			(aggr.aggr_enable) ? "Starting" : "Stopping",
 			sta->addr, tid);
 
-	spin_lock_bh(&priv->tx_lock);
+	spin_lock_bh(&priv->tx.tx_lock);
 	ista->tid_state[tid] = (aggr.aggr_enable && !ret) ? AGGR_START : AGGR_STOP;
-	spin_unlock_bh(&priv->tx_lock);
+	spin_unlock_bh(&priv->tx.tx_lock);
 
 	return ret;
 }
 
-/*********/
-/* DEBUG */
-/*********/
-
-#ifdef CONFIG_ATH9K_HTC_DEBUGFS
-
-static int ath9k_debugfs_open(struct inode *inode, struct file *file)
-{
-	file->private_data = inode->i_private;
-	return 0;
-}
-
-static ssize_t read_file_tgt_stats(struct file *file, char __user *user_buf,
-				   size_t count, loff_t *ppos)
-{
-	struct ath9k_htc_priv *priv = file->private_data;
-	struct ath9k_htc_target_stats cmd_rsp;
-	char buf[512];
-	unsigned int len = 0;
-	int ret = 0;
-
-	memset(&cmd_rsp, 0, sizeof(cmd_rsp));
-
-	WMI_CMD(WMI_TGT_STATS_CMDID);
-	if (ret)
-		return -EINVAL;
-
-
-	len += snprintf(buf + len, sizeof(buf) - len,
-			"%19s : %10u\n", "TX Short Retries",
-			be32_to_cpu(cmd_rsp.tx_shortretry));
-	len += snprintf(buf + len, sizeof(buf) - len,
-			"%19s : %10u\n", "TX Long Retries",
-			be32_to_cpu(cmd_rsp.tx_longretry));
-	len += snprintf(buf + len, sizeof(buf) - len,
-			"%19s : %10u\n", "TX Xretries",
-			be32_to_cpu(cmd_rsp.tx_xretries));
-	len += snprintf(buf + len, sizeof(buf) - len,
-			"%19s : %10u\n", "TX Unaggr. Xretries",
-			be32_to_cpu(cmd_rsp.ht_txunaggr_xretry));
-	len += snprintf(buf + len, sizeof(buf) - len,
-			"%19s : %10u\n", "TX Xretries (HT)",
-			be32_to_cpu(cmd_rsp.ht_tx_xretries));
-	len += snprintf(buf + len, sizeof(buf) - len,
-			"%19s : %10u\n", "TX Rate", priv->debug.txrate);
-
-	if (len > sizeof(buf))
-		len = sizeof(buf);
-
-	return simple_read_from_buffer(user_buf, count, ppos, buf, len);
-}
-
-static const struct file_operations fops_tgt_stats = {
-	.read = read_file_tgt_stats,
-	.open = ath9k_debugfs_open,
-	.owner = THIS_MODULE,
-	.llseek = default_llseek,
-};
-
-static ssize_t read_file_xmit(struct file *file, char __user *user_buf,
-			      size_t count, loff_t *ppos)
-{
-	struct ath9k_htc_priv *priv = file->private_data;
-	char buf[512];
-	unsigned int len = 0;
-
-	len += snprintf(buf + len, sizeof(buf) - len,
-			"%20s : %10u\n", "Buffers queued",
-			priv->debug.tx_stats.buf_queued);
-	len += snprintf(buf + len, sizeof(buf) - len,
-			"%20s : %10u\n", "Buffers completed",
-			priv->debug.tx_stats.buf_completed);
-	len += snprintf(buf + len, sizeof(buf) - len,
-			"%20s : %10u\n", "SKBs queued",
-			priv->debug.tx_stats.skb_queued);
-	len += snprintf(buf + len, sizeof(buf) - len,
-			"%20s : %10u\n", "SKBs completed",
-			priv->debug.tx_stats.skb_completed);
-	len += snprintf(buf + len, sizeof(buf) - len,
-			"%20s : %10u\n", "SKBs dropped",
-			priv->debug.tx_stats.skb_dropped);
-
-	len += snprintf(buf + len, sizeof(buf) - len,
-			"%20s : %10u\n", "BE queued",
-			priv->debug.tx_stats.queue_stats[WME_AC_BE]);
-	len += snprintf(buf + len, sizeof(buf) - len,
-			"%20s : %10u\n", "BK queued",
-			priv->debug.tx_stats.queue_stats[WME_AC_BK]);
-	len += snprintf(buf + len, sizeof(buf) - len,
-			"%20s : %10u\n", "VI queued",
-			priv->debug.tx_stats.queue_stats[WME_AC_VI]);
-	len += snprintf(buf + len, sizeof(buf) - len,
-			"%20s : %10u\n", "VO queued",
-			priv->debug.tx_stats.queue_stats[WME_AC_VO]);
-
-	if (len > sizeof(buf))
-		len = sizeof(buf);
-
-	return simple_read_from_buffer(user_buf, count, ppos, buf, len);
-}
-
-static const struct file_operations fops_xmit = {
-	.read = read_file_xmit,
-	.open = ath9k_debugfs_open,
-	.owner = THIS_MODULE,
-	.llseek = default_llseek,
-};
-
-static ssize_t read_file_recv(struct file *file, char __user *user_buf,
-			      size_t count, loff_t *ppos)
-{
-	struct ath9k_htc_priv *priv = file->private_data;
-	char buf[512];
-	unsigned int len = 0;
-
-	len += snprintf(buf + len, sizeof(buf) - len,
-			"%20s : %10u\n", "SKBs allocated",
-			priv->debug.rx_stats.skb_allocated);
-	len += snprintf(buf + len, sizeof(buf) - len,
-			"%20s : %10u\n", "SKBs completed",
-			priv->debug.rx_stats.skb_completed);
-	len += snprintf(buf + len, sizeof(buf) - len,
-			"%20s : %10u\n", "SKBs Dropped",
-			priv->debug.rx_stats.skb_dropped);
-
-	if (len > sizeof(buf))
-		len = sizeof(buf);
-
-	return simple_read_from_buffer(user_buf, count, ppos, buf, len);
-}
-
-static const struct file_operations fops_recv = {
-	.read = read_file_recv,
-	.open = ath9k_debugfs_open,
-	.owner = THIS_MODULE,
-	.llseek = default_llseek,
-};
-
-int ath9k_htc_init_debug(struct ath_hw *ah)
-{
-	struct ath_common *common = ath9k_hw_common(ah);
-	struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *) common->priv;
-
-	if (!ath9k_debugfs_root)
-		return -ENOENT;
-
-	priv->debug.debugfs_phy = debugfs_create_dir(wiphy_name(priv->hw->wiphy),
-						     ath9k_debugfs_root);
-	if (!priv->debug.debugfs_phy)
-		goto err;
-
-	priv->debug.debugfs_tgt_stats = debugfs_create_file("tgt_stats", S_IRUSR,
-						    priv->debug.debugfs_phy,
-						    priv, &fops_tgt_stats);
-	if (!priv->debug.debugfs_tgt_stats)
-		goto err;
-
-
-	priv->debug.debugfs_xmit = debugfs_create_file("xmit", S_IRUSR,
-						       priv->debug.debugfs_phy,
-						       priv, &fops_xmit);
-	if (!priv->debug.debugfs_xmit)
-		goto err;
-
-	priv->debug.debugfs_recv = debugfs_create_file("recv", S_IRUSR,
-						       priv->debug.debugfs_phy,
-						       priv, &fops_recv);
-	if (!priv->debug.debugfs_recv)
-		goto err;
-
-	return 0;
-
-err:
-	ath9k_htc_exit_debug(ah);
-	return -ENOMEM;
-}
-
-void ath9k_htc_exit_debug(struct ath_hw *ah)
-{
-	struct ath_common *common = ath9k_hw_common(ah);
-	struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *) common->priv;
-
-	debugfs_remove(priv->debug.debugfs_recv);
-	debugfs_remove(priv->debug.debugfs_xmit);
-	debugfs_remove(priv->debug.debugfs_tgt_stats);
-	debugfs_remove(priv->debug.debugfs_phy);
-}
-
-int ath9k_htc_debug_create_root(void)
-{
-	ath9k_debugfs_root = debugfs_create_dir(KBUILD_MODNAME, NULL);
-	if (!ath9k_debugfs_root)
-		return -ENOENT;
-
-	return 0;
-}
-
-void ath9k_htc_debug_remove_root(void)
-{
-	debugfs_remove(ath9k_debugfs_root);
-	ath9k_debugfs_root = NULL;
-}
-
-#endif /* CONFIG_ATH9K_HTC_DEBUGFS */
-
 /*******/
 /* ANI */
 /*******/
@@ -1040,7 +856,8 @@
 {
 	struct ieee80211_hdr *hdr;
 	struct ath9k_htc_priv *priv = hw->priv;
-	int padpos, padsize, ret;
+	struct ath_common *common = ath9k_hw_common(priv->ah);
+	int padpos, padsize, ret, slot;
 
 	hdr = (struct ieee80211_hdr *) skb->data;
 
@@ -1048,30 +865,32 @@
 	padpos = ath9k_cmn_padpos(hdr->frame_control);
 	padsize = padpos & 3;
 	if (padsize && skb->len > padpos) {
-		if (skb_headroom(skb) < padsize)
+		if (skb_headroom(skb) < padsize) {
+			ath_dbg(common, ATH_DBG_XMIT, "No room for padding\n");
 			goto fail_tx;
+		}
 		skb_push(skb, padsize);
 		memmove(skb->data, skb->data + padsize, padpos);
 	}
 
-	ret = ath9k_htc_tx_start(priv, skb);
-	if (ret != 0) {
-		if (ret == -ENOMEM) {
-			ath_dbg(ath9k_hw_common(priv->ah), ATH_DBG_XMIT,
-				"Stopping TX queues\n");
-			ieee80211_stop_queues(hw);
-			spin_lock_bh(&priv->tx_lock);
-			priv->tx_queues_stop = true;
-			spin_unlock_bh(&priv->tx_lock);
-		} else {
-			ath_dbg(ath9k_hw_common(priv->ah), ATH_DBG_XMIT,
-				"Tx failed\n");
-		}
+	slot = ath9k_htc_tx_get_slot(priv);
+	if (slot < 0) {
+		ath_dbg(common, ATH_DBG_XMIT, "No free TX slot\n");
 		goto fail_tx;
 	}
 
+	ret = ath9k_htc_tx_start(priv, skb, slot, false);
+	if (ret != 0) {
+		ath_dbg(common, ATH_DBG_XMIT, "Tx failed\n");
+		goto clear_slot;
+	}
+
+	ath9k_htc_check_stop_queues(priv);
+
 	return;
 
+clear_slot:
+	ath9k_htc_tx_clear_slot(priv, slot);
 fail_tx:
 	dev_kfree_skb_any(skb);
 }
@@ -1122,7 +941,7 @@
 
 	ath9k_host_rx_init(priv);
 
-	ret = ath9k_htc_update_cap_target(priv);
+	ret = ath9k_htc_update_cap_target(priv, 0);
 	if (ret)
 		ath_dbg(common, ATH_DBG_CONFIG,
 			"Failed to update capability in target\n");
@@ -1130,12 +949,15 @@
 	priv->op_flags &= ~OP_INVALID;
 	htc_start(priv->htc);
 
-	spin_lock_bh(&priv->tx_lock);
-	priv->tx_queues_stop = false;
-	spin_unlock_bh(&priv->tx_lock);
+	spin_lock_bh(&priv->tx.tx_lock);
+	priv->tx.flags &= ~ATH9K_HTC_OP_TX_QUEUES_STOP;
+	spin_unlock_bh(&priv->tx.tx_lock);
 
 	ieee80211_wake_queues(hw);
 
+	mod_timer(&priv->tx.cleanup_timer,
+		  jiffies + msecs_to_jiffies(ATH9K_HTC_TX_CLEANUP_INTERVAL));
+
 	if (ah->btcoex_hw.scheme == ATH_BTCOEX_CFG_3WIRE) {
 		ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT,
 					   AR_STOMP_LOW_WLAN_WGHT);
@@ -1152,7 +974,7 @@
 	struct ath9k_htc_priv *priv = hw->priv;
 	struct ath_hw *ah = priv->ah;
 	struct ath_common *common = ath9k_hw_common(ah);
-	int ret = 0;
+	int ret __attribute__ ((unused));
 	u8 cmd_rsp;
 
 	mutex_lock(&priv->mutex);
@@ -1164,25 +986,27 @@
 	}
 
 	ath9k_htc_ps_wakeup(priv);
-	htc_stop(priv->htc);
+
 	WMI_CMD(WMI_DISABLE_INTR_CMDID);
 	WMI_CMD(WMI_DRAIN_TXQ_ALL_CMDID);
 	WMI_CMD(WMI_STOP_RECV_CMDID);
 
-	tasklet_kill(&priv->swba_tasklet);
 	tasklet_kill(&priv->rx_tasklet);
-	tasklet_kill(&priv->tx_tasklet);
 
-	skb_queue_purge(&priv->tx_queue);
+	del_timer_sync(&priv->tx.cleanup_timer);
+	ath9k_htc_tx_drain(priv);
+	ath9k_wmi_event_drain(priv);
 
 	mutex_unlock(&priv->mutex);
 
 	/* Cancel all the running timers/work .. */
 	cancel_work_sync(&priv->fatal_work);
 	cancel_work_sync(&priv->ps_work);
-	cancel_delayed_work_sync(&priv->ath9k_led_blink_work);
+
+#ifdef CONFIG_MAC80211_LEDS
+	cancel_work_sync(&priv->led_work);
+#endif
 	ath9k_htc_stop_ani(priv);
-	ath9k_led_stop_brightness(priv);
 
 	mutex_lock(&priv->mutex);
 
@@ -1245,13 +1069,13 @@
 
 	switch (vif->type) {
 	case NL80211_IFTYPE_STATION:
-		hvif.opmode = cpu_to_be32(HTC_M_STA);
+		hvif.opmode = HTC_M_STA;
 		break;
 	case NL80211_IFTYPE_ADHOC:
-		hvif.opmode = cpu_to_be32(HTC_M_IBSS);
+		hvif.opmode = HTC_M_IBSS;
 		break;
 	case NL80211_IFTYPE_AP:
-		hvif.opmode = cpu_to_be32(HTC_M_HOSTAP);
+		hvif.opmode = HTC_M_HOSTAP;
 		break;
 	default:
 		ath_err(common,
@@ -1281,14 +1105,20 @@
 
 	priv->vif_slot |= (1 << avp->index);
 	priv->nvifs++;
-	priv->vif = vif;
 
 	INC_VIF(priv, vif->type);
+
+	if ((vif->type == NL80211_IFTYPE_AP) ||
+	    (vif->type == NL80211_IFTYPE_ADHOC))
+		ath9k_htc_assign_bslot(priv, vif);
+
 	ath9k_htc_set_opmode(priv);
 
 	if ((priv->ah->opmode == NL80211_IFTYPE_AP) &&
-	    !(priv->op_flags & OP_ANI_RUNNING))
+	    !(priv->op_flags & OP_ANI_RUNNING)) {
+		ath9k_hw_set_tsfadjust(priv->ah, 1);
 		ath9k_htc_start_ani(priv);
+	}
 
 	ath_dbg(common, ATH_DBG_CONFIG,
 		"Attach a VIF of type: %d at idx: %d\n", vif->type, avp->index);
@@ -1317,15 +1147,25 @@
 	memcpy(&hvif.myaddr, vif->addr, ETH_ALEN);
 	hvif.index = avp->index;
 	WMI_CMD_BUF(WMI_VAP_REMOVE_CMDID, &hvif);
+	if (ret) {
+		ath_err(common, "Unable to remove interface at idx: %d\n",
+			avp->index);
+	}
 	priv->nvifs--;
 	priv->vif_slot &= ~(1 << avp->index);
 
 	ath9k_htc_remove_station(priv, vif, NULL);
-	priv->vif = NULL;
 
 	DEC_VIF(priv, vif->type);
+
+	if ((vif->type == NL80211_IFTYPE_AP) ||
+	    (vif->type == NL80211_IFTYPE_ADHOC))
+		ath9k_htc_remove_bslot(priv, vif);
+
 	ath9k_htc_set_opmode(priv);
 
+	ath9k_htc_set_bssid_mask(priv, vif);
+
 	/*
 	 * Stop ANI only if there are no associated station interfaces.
 	 */
@@ -1493,10 +1333,13 @@
 				struct ieee80211_sta *sta)
 {
 	struct ath9k_htc_priv *priv = hw->priv;
+	struct ath9k_htc_sta *ista;
 	int ret;
 
 	mutex_lock(&priv->mutex);
 	ath9k_htc_ps_wakeup(priv);
+	ista = (struct ath9k_htc_sta *) sta->drv_priv;
+	htc_sta_drain(priv->htc, ista->index);
 	ret = ath9k_htc_remove_station(priv, vif, sta);
 	ath9k_htc_ps_restore(priv);
 	mutex_unlock(&priv->mutex);
@@ -1593,6 +1436,37 @@
 	return ret;
 }
 
+static void ath9k_htc_set_bssid(struct ath9k_htc_priv *priv)
+{
+	struct ath_common *common = ath9k_hw_common(priv->ah);
+
+	ath9k_hw_write_associd(priv->ah);
+	ath_dbg(common, ATH_DBG_CONFIG,
+		"BSSID: %pM aid: 0x%x\n",
+		common->curbssid, common->curaid);
+}
+
+static void ath9k_htc_bss_iter(void *data, u8 *mac, struct ieee80211_vif *vif)
+{
+	struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *)data;
+	struct ath_common *common = ath9k_hw_common(priv->ah);
+	struct ieee80211_bss_conf *bss_conf = &vif->bss_conf;
+
+	if ((vif->type == NL80211_IFTYPE_STATION) && bss_conf->assoc) {
+		common->curaid = bss_conf->aid;
+		memcpy(common->curbssid, bss_conf->bssid, ETH_ALEN);
+	}
+}
+
+static void ath9k_htc_choose_set_bssid(struct ath9k_htc_priv *priv)
+{
+	if (priv->num_sta_assoc_vif == 1) {
+		ieee80211_iterate_active_interfaces_atomic(priv->hw,
+							   ath9k_htc_bss_iter, priv);
+		ath9k_htc_set_bssid(priv);
+	}
+}
+
 static void ath9k_htc_bss_info_changed(struct ieee80211_hw *hw,
 				       struct ieee80211_vif *vif,
 				       struct ieee80211_bss_conf *bss_conf,
@@ -1601,49 +1475,39 @@
 	struct ath9k_htc_priv *priv = hw->priv;
 	struct ath_hw *ah = priv->ah;
 	struct ath_common *common = ath9k_hw_common(ah);
-	bool set_assoc;
 
 	mutex_lock(&priv->mutex);
 	ath9k_htc_ps_wakeup(priv);
 
-	/*
-	 * Set the HW AID/BSSID only for the first station interface
-	 * or in IBSS mode.
-	 */
-	set_assoc = !!((priv->ah->opmode == NL80211_IFTYPE_ADHOC) ||
-		       ((priv->ah->opmode == NL80211_IFTYPE_STATION) &&
-			(priv->num_sta_vif == 1)));
-
-
 	if (changed & BSS_CHANGED_ASSOC) {
-		if (set_assoc) {
-			ath_dbg(common, ATH_DBG_CONFIG, "BSS Changed ASSOC %d\n",
-				bss_conf->assoc);
+		ath_dbg(common, ATH_DBG_CONFIG, "BSS Changed ASSOC %d\n",
+			bss_conf->assoc);
 
-			common->curaid = bss_conf->assoc ?
-				bss_conf->aid : 0;
+		bss_conf->assoc ?
+			priv->num_sta_assoc_vif++ : priv->num_sta_assoc_vif--;
 
-			if (bss_conf->assoc)
+		if (priv->ah->opmode == NL80211_IFTYPE_STATION) {
+			if (bss_conf->assoc && (priv->num_sta_assoc_vif == 1))
 				ath9k_htc_start_ani(priv);
-			else
+			else if (priv->num_sta_assoc_vif == 0)
 				ath9k_htc_stop_ani(priv);
 		}
 	}
 
 	if (changed & BSS_CHANGED_BSSID) {
-		if (set_assoc) {
+		if (priv->ah->opmode == NL80211_IFTYPE_ADHOC) {
+			common->curaid = bss_conf->aid;
 			memcpy(common->curbssid, bss_conf->bssid, ETH_ALEN);
-			ath9k_hw_write_associd(ah);
-
-			ath_dbg(common, ATH_DBG_CONFIG,
-				"BSSID: %pM aid: 0x%x\n",
-				common->curbssid, common->curaid);
+			ath9k_htc_set_bssid(priv);
+		} else if (priv->ah->opmode == NL80211_IFTYPE_STATION) {
+			ath9k_htc_choose_set_bssid(priv);
 		}
 	}
 
 	if ((changed & BSS_CHANGED_BEACON_ENABLED) && bss_conf->enable_beacon) {
 		ath_dbg(common, ATH_DBG_CONFIG,
 			"Beacon enabled for BSS: %pM\n", bss_conf->bssid);
+		ath9k_htc_set_tsfadjust(priv, vif);
 		priv->op_flags |= OP_ENABLE_BEACON;
 		ath9k_htc_beacon_config(priv, vif);
 	}
@@ -1741,6 +1605,7 @@
 	int ret = 0;
 
 	mutex_lock(&priv->mutex);
+	ath9k_htc_ps_wakeup(priv);
 
 	switch (action) {
 	case IEEE80211_AMPDU_RX_START:
@@ -1758,14 +1623,15 @@
 		break;
 	case IEEE80211_AMPDU_TX_OPERATIONAL:
 		ista = (struct ath9k_htc_sta *) sta->drv_priv;
-		spin_lock_bh(&priv->tx_lock);
+		spin_lock_bh(&priv->tx.tx_lock);
 		ista->tid_state[tid] = AGGR_OPERATIONAL;
-		spin_unlock_bh(&priv->tx_lock);
+		spin_unlock_bh(&priv->tx.tx_lock);
 		break;
 	default:
 		ath_err(ath9k_hw_common(priv->ah), "Unknown AMPDU action\n");
 	}
 
+	ath9k_htc_ps_restore(priv);
 	mutex_unlock(&priv->mutex);
 
 	return ret;
@@ -1816,6 +1682,55 @@
 	mutex_unlock(&priv->mutex);
 }
 
+/*
+ * Currently, this is used only for selecting the minimum rate
+ * for management frames, rate selection for data frames remain
+ * unaffected.
+ */
+static int ath9k_htc_set_bitrate_mask(struct ieee80211_hw *hw,
+				      struct ieee80211_vif *vif,
+				      const struct cfg80211_bitrate_mask *mask)
+{
+	struct ath9k_htc_priv *priv = hw->priv;
+	struct ath_common *common = ath9k_hw_common(priv->ah);
+	struct ath9k_htc_target_rate_mask tmask;
+	struct ath9k_htc_vif *avp = (void *)vif->drv_priv;
+	int ret = 0;
+	u8 cmd_rsp;
+
+	memset(&tmask, 0, sizeof(struct ath9k_htc_target_rate_mask));
+
+	tmask.vif_index = avp->index;
+	tmask.band = IEEE80211_BAND_2GHZ;
+	tmask.mask = cpu_to_be32(mask->control[IEEE80211_BAND_2GHZ].legacy);
+
+	WMI_CMD_BUF(WMI_BITRATE_MASK_CMDID, &tmask);
+	if (ret) {
+		ath_err(common,
+			"Unable to set 2G rate mask for "
+			"interface at idx: %d\n", avp->index);
+		goto out;
+	}
+
+	tmask.band = IEEE80211_BAND_5GHZ;
+	tmask.mask = cpu_to_be32(mask->control[IEEE80211_BAND_5GHZ].legacy);
+
+	WMI_CMD_BUF(WMI_BITRATE_MASK_CMDID, &tmask);
+	if (ret) {
+		ath_err(common,
+			"Unable to set 5G rate mask for "
+			"interface at idx: %d\n", avp->index);
+		goto out;
+	}
+
+	ath_dbg(common, ATH_DBG_CONFIG,
+		"Set bitrate masks: 0x%x, 0x%x\n",
+		mask->control[IEEE80211_BAND_2GHZ].legacy,
+		mask->control[IEEE80211_BAND_5GHZ].legacy);
+out:
+	return ret;
+}
+
 struct ieee80211_ops ath9k_htc_ops = {
 	.tx                 = ath9k_htc_tx,
 	.start              = ath9k_htc_start,
@@ -1838,4 +1753,5 @@
 	.set_rts_threshold  = ath9k_htc_set_rts_threshold,
 	.rfkill_poll        = ath9k_htc_rfkill_poll_state,
 	.set_coverage_class = ath9k_htc_set_coverage_class,
+	.set_bitrate_mask   = ath9k_htc_set_bitrate_mask,
 };
diff -druN linux-2.6.39-libre/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c linux-3.0-rc7-libre/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c
--- linux-2.6.39-libre/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c	2011-07-11 19:51:52.000000000 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010 Atheros Communications Inc.
+ * Copyright (c) 2010-2011 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
@@ -53,6 +53,138 @@
 	}
 }
 
+void ath9k_htc_check_stop_queues(struct ath9k_htc_priv *priv)
+{
+	spin_lock_bh(&priv->tx.tx_lock);
+	priv->tx.queued_cnt++;
+	if ((priv->tx.queued_cnt >= ATH9K_HTC_TX_THRESHOLD) &&
+	    !(priv->tx.flags & ATH9K_HTC_OP_TX_QUEUES_STOP)) {
+		priv->tx.flags |= ATH9K_HTC_OP_TX_QUEUES_STOP;
+		ieee80211_stop_queues(priv->hw);
+	}
+	spin_unlock_bh(&priv->tx.tx_lock);
+}
+
+void ath9k_htc_check_wake_queues(struct ath9k_htc_priv *priv)
+{
+	spin_lock_bh(&priv->tx.tx_lock);
+	if ((priv->tx.queued_cnt < ATH9K_HTC_TX_THRESHOLD) &&
+	    (priv->tx.flags & ATH9K_HTC_OP_TX_QUEUES_STOP)) {
+		priv->tx.flags &= ~ATH9K_HTC_OP_TX_QUEUES_STOP;
+		ieee80211_wake_queues(priv->hw);
+	}
+	spin_unlock_bh(&priv->tx.tx_lock);
+}
+
+int ath9k_htc_tx_get_slot(struct ath9k_htc_priv *priv)
+{
+	int slot;
+
+	spin_lock_bh(&priv->tx.tx_lock);
+	slot = find_first_zero_bit(priv->tx.tx_slot, MAX_TX_BUF_NUM);
+	if (slot >= MAX_TX_BUF_NUM) {
+		spin_unlock_bh(&priv->tx.tx_lock);
+		return -ENOBUFS;
+	}
+	__set_bit(slot, priv->tx.tx_slot);
+	spin_unlock_bh(&priv->tx.tx_lock);
+
+	return slot;
+}
+
+void ath9k_htc_tx_clear_slot(struct ath9k_htc_priv *priv, int slot)
+{
+	spin_lock_bh(&priv->tx.tx_lock);
+	__clear_bit(slot, priv->tx.tx_slot);
+	spin_unlock_bh(&priv->tx.tx_lock);
+}
+
+static inline enum htc_endpoint_id get_htc_epid(struct ath9k_htc_priv *priv,
+						u16 qnum)
+{
+	enum htc_endpoint_id epid;
+
+	switch (qnum) {
+	case 0:
+		TX_QSTAT_INC(WME_AC_VO);
+		epid = priv->data_vo_ep;
+		break;
+	case 1:
+		TX_QSTAT_INC(WME_AC_VI);
+		epid = priv->data_vi_ep;
+		break;
+	case 2:
+		TX_QSTAT_INC(WME_AC_BE);
+		epid = priv->data_be_ep;
+		break;
+	case 3:
+	default:
+		TX_QSTAT_INC(WME_AC_BK);
+		epid = priv->data_bk_ep;
+		break;
+	}
+
+	return epid;
+}
+
+static inline struct sk_buff_head*
+get_htc_epid_queue(struct ath9k_htc_priv *priv, u8 epid)
+{
+	struct ath_common *common = ath9k_hw_common(priv->ah);
+	struct sk_buff_head *epid_queue = NULL;
+
+	if (epid == priv->mgmt_ep)
+		epid_queue = &priv->tx.mgmt_ep_queue;
+	else if (epid == priv->cab_ep)
+		epid_queue = &priv->tx.cab_ep_queue;
+	else if (epid == priv->data_be_ep)
+		epid_queue = &priv->tx.data_be_queue;
+	else if (epid == priv->data_bk_ep)
+		epid_queue = &priv->tx.data_bk_queue;
+	else if (epid == priv->data_vi_ep)
+		epid_queue = &priv->tx.data_vi_queue;
+	else if (epid == priv->data_vo_ep)
+		epid_queue = &priv->tx.data_vo_queue;
+	else
+		ath_err(common, "Invalid EPID: %d\n", epid);
+
+	return epid_queue;
+}
+
+/*
+ * Removes the driver header and returns the TX slot number
+ */
+static inline int strip_drv_header(struct ath9k_htc_priv *priv,
+				   struct sk_buff *skb)
+{
+	struct ath_common *common = ath9k_hw_common(priv->ah);
+	struct ath9k_htc_tx_ctl *tx_ctl;
+	int slot;
+
+	tx_ctl = HTC_SKB_CB(skb);
+
+	if (tx_ctl->epid == priv->mgmt_ep) {
+		struct tx_mgmt_hdr *tx_mhdr =
+			(struct tx_mgmt_hdr *)skb->data;
+		slot = tx_mhdr->cookie;
+		skb_pull(skb, sizeof(struct tx_mgmt_hdr));
+	} else if ((tx_ctl->epid == priv->data_bk_ep) ||
+		   (tx_ctl->epid == priv->data_be_ep) ||
+		   (tx_ctl->epid == priv->data_vi_ep) ||
+		   (tx_ctl->epid == priv->data_vo_ep) ||
+		   (tx_ctl->epid == priv->cab_ep)) {
+		struct tx_frame_hdr *tx_fhdr =
+			(struct tx_frame_hdr *)skb->data;
+		slot = tx_fhdr->cookie;
+		skb_pull(skb, sizeof(struct tx_frame_hdr));
+	} else {
+		ath_err(common, "Unsupported EPID: %d\n", tx_ctl->epid);
+		slot = -EINVAL;
+	}
+
+	return slot;
+}
+
 int ath_htc_txq_update(struct ath9k_htc_priv *priv, int qnum,
 		       struct ath9k_tx_queue_info *qinfo)
 {
@@ -79,23 +211,140 @@
 	return error;
 }
 
-int ath9k_htc_tx_start(struct ath9k_htc_priv *priv, struct sk_buff *skb)
+static void ath9k_htc_tx_mgmt(struct ath9k_htc_priv *priv,
+			      struct ath9k_htc_vif *avp,
+			      struct sk_buff *skb,
+			      u8 sta_idx, u8 vif_idx, u8 slot)
+{
+	struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
+	struct ieee80211_mgmt *mgmt;
+	struct ieee80211_hdr *hdr;
+	struct tx_mgmt_hdr mgmt_hdr;
+	struct ath9k_htc_tx_ctl *tx_ctl;
+	u8 *tx_fhdr;
+
+	tx_ctl = HTC_SKB_CB(skb);
+	hdr = (struct ieee80211_hdr *) skb->data;
+
+	memset(tx_ctl, 0, sizeof(*tx_ctl));
+	memset(&mgmt_hdr, 0, sizeof(struct tx_mgmt_hdr));
+
+	/*
+	 * Set the TSF adjust value for probe response
+	 * frame also.
+	 */
+	if (avp && unlikely(ieee80211_is_probe_resp(hdr->frame_control))) {
+		mgmt = (struct ieee80211_mgmt *)skb->data;
+		mgmt->u.probe_resp.timestamp = avp->tsfadjust;
+	}
+
+	tx_ctl->type = ATH9K_HTC_MGMT;
+
+	mgmt_hdr.node_idx = sta_idx;
+	mgmt_hdr.vif_idx = vif_idx;
+	mgmt_hdr.tidno = 0;
+	mgmt_hdr.flags = 0;
+	mgmt_hdr.cookie = slot;
+
+	mgmt_hdr.key_type = ath9k_cmn_get_hw_crypto_keytype(skb);
+	if (mgmt_hdr.key_type == ATH9K_KEY_TYPE_CLEAR)
+		mgmt_hdr.keyix = (u8) ATH9K_TXKEYIX_INVALID;
+	else
+		mgmt_hdr.keyix = tx_info->control.hw_key->hw_key_idx;
+
+	tx_fhdr = skb_push(skb, sizeof(mgmt_hdr));
+	memcpy(tx_fhdr, (u8 *) &mgmt_hdr, sizeof(mgmt_hdr));
+	tx_ctl->epid = priv->mgmt_ep;
+}
+
+static void ath9k_htc_tx_data(struct ath9k_htc_priv *priv,
+			      struct ieee80211_vif *vif,
+			      struct sk_buff *skb,
+			      u8 sta_idx, u8 vif_idx, u8 slot,
+			      bool is_cab)
+{
+	struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
+	struct ieee80211_hdr *hdr;
+	struct ath9k_htc_tx_ctl *tx_ctl;
+	struct tx_frame_hdr tx_hdr;
+	u32 flags = 0;
+	u8 *qc, *tx_fhdr;
+	u16 qnum;
+
+	tx_ctl = HTC_SKB_CB(skb);
+	hdr = (struct ieee80211_hdr *) skb->data;
+
+	memset(tx_ctl, 0, sizeof(*tx_ctl));
+	memset(&tx_hdr, 0, sizeof(struct tx_frame_hdr));
+
+	tx_hdr.node_idx = sta_idx;
+	tx_hdr.vif_idx = vif_idx;
+	tx_hdr.cookie = slot;
+
+	/*
+	 * This is a bit redundant but it helps to get
+	 * the per-packet index quickly when draining the
+	 * TX queue in the HIF layer. Otherwise we would
+	 * have to parse the packet contents ...
+	 */
+	tx_ctl->sta_idx = sta_idx;
+
+	if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) {
+		tx_ctl->type = ATH9K_HTC_AMPDU;
+		tx_hdr.data_type = ATH9K_HTC_AMPDU;
+	} else {
+		tx_ctl->type = ATH9K_HTC_NORMAL;
+		tx_hdr.data_type = ATH9K_HTC_NORMAL;
+	}
+
+	if (ieee80211_is_data_qos(hdr->frame_control)) {
+		qc = ieee80211_get_qos_ctl(hdr);
+		tx_hdr.tidno = qc[0] & IEEE80211_QOS_CTL_TID_MASK;
+	}
+
+	/* Check for RTS protection */
+	if (priv->hw->wiphy->rts_threshold != (u32) -1)
+		if (skb->len > priv->hw->wiphy->rts_threshold)
+			flags |= ATH9K_HTC_TX_RTSCTS;
+
+	/* CTS-to-self */
+	if (!(flags & ATH9K_HTC_TX_RTSCTS) &&
+	    (vif && vif->bss_conf.use_cts_prot))
+		flags |= ATH9K_HTC_TX_CTSONLY;
+
+	tx_hdr.flags = cpu_to_be32(flags);
+	tx_hdr.key_type = ath9k_cmn_get_hw_crypto_keytype(skb);
+	if (tx_hdr.key_type == ATH9K_KEY_TYPE_CLEAR)
+		tx_hdr.keyix = (u8) ATH9K_TXKEYIX_INVALID;
+	else
+		tx_hdr.keyix = tx_info->control.hw_key->hw_key_idx;
+
+	tx_fhdr = skb_push(skb, sizeof(tx_hdr));
+	memcpy(tx_fhdr, (u8 *) &tx_hdr, sizeof(tx_hdr));
+
+	if (is_cab) {
+		CAB_STAT_INC;
+		tx_ctl->epid = priv->cab_ep;
+		return;
+	}
+
+	qnum = skb_get_queue_mapping(skb);
+	tx_ctl->epid = get_htc_epid(priv, qnum);
+}
+
+int ath9k_htc_tx_start(struct ath9k_htc_priv *priv,
+		       struct sk_buff *skb,
+		       u8 slot, bool is_cab)
 {
 	struct ieee80211_hdr *hdr;
 	struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
 	struct ieee80211_sta *sta = tx_info->control.sta;
 	struct ieee80211_vif *vif = tx_info->control.vif;
 	struct ath9k_htc_sta *ista;
-	struct ath9k_htc_vif *avp;
-	struct ath9k_htc_tx_ctl tx_ctl;
-	enum htc_endpoint_id epid;
-	u16 qnum;
-	__le16 fc;
-	u8 *tx_fhdr;
+	struct ath9k_htc_vif *avp = NULL;
 	u8 sta_idx, vif_idx;
 
 	hdr = (struct ieee80211_hdr *) skb->data;
-	fc = hdr->frame_control;
 
 	/*
 	 * Find out on which interface this packet has to be
@@ -124,218 +373,430 @@
 		sta_idx = priv->vif_sta_pos[vif_idx];
 	}
 
-	memset(&tx_ctl, 0, sizeof(struct ath9k_htc_tx_ctl));
+	if (ieee80211_is_data(hdr->frame_control))
+		ath9k_htc_tx_data(priv, vif, skb,
+				  sta_idx, vif_idx, slot, is_cab);
+	else
+		ath9k_htc_tx_mgmt(priv, avp, skb,
+				  sta_idx, vif_idx, slot);
 
-	if (ieee80211_is_data(fc)) {
-		struct tx_frame_hdr tx_hdr;
-		u32 flags = 0;
-		u8 *qc;
 
-		memset(&tx_hdr, 0, sizeof(struct tx_frame_hdr));
+	return htc_send(priv->htc, skb);
+}
 
-		tx_hdr.node_idx = sta_idx;
-		tx_hdr.vif_idx = vif_idx;
+static inline bool __ath9k_htc_check_tx_aggr(struct ath9k_htc_priv *priv,
+					     struct ath9k_htc_sta *ista, u8 tid)
+{
+	bool ret = false;
 
-		if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) {
-			tx_ctl.type = ATH9K_HTC_AMPDU;
-			tx_hdr.data_type = ATH9K_HTC_AMPDU;
-		} else {
-			tx_ctl.type = ATH9K_HTC_NORMAL;
-			tx_hdr.data_type = ATH9K_HTC_NORMAL;
-		}
+	spin_lock_bh(&priv->tx.tx_lock);
+	if ((tid < ATH9K_HTC_MAX_TID) && (ista->tid_state[tid] == AGGR_STOP))
+		ret = true;
+	spin_unlock_bh(&priv->tx.tx_lock);
+
+	return ret;
+}
 
+static void ath9k_htc_check_tx_aggr(struct ath9k_htc_priv *priv,
+				    struct ieee80211_vif *vif,
+				    struct sk_buff *skb)
+{
+	struct ieee80211_sta *sta;
+	struct ieee80211_hdr *hdr;
+	__le16 fc;
+
+	hdr = (struct ieee80211_hdr *) skb->data;
+	fc = hdr->frame_control;
+
+	rcu_read_lock();
+
+	sta = ieee80211_find_sta(vif, hdr->addr1);
+	if (!sta) {
+		rcu_read_unlock();
+		return;
+	}
+
+	if (sta && conf_is_ht(&priv->hw->conf) &&
+	    !(skb->protocol == cpu_to_be16(ETH_P_PAE))) {
 		if (ieee80211_is_data_qos(fc)) {
+			u8 *qc, tid;
+			struct ath9k_htc_sta *ista;
+
 			qc = ieee80211_get_qos_ctl(hdr);
-			tx_hdr.tidno = qc[0] & IEEE80211_QOS_CTL_TID_MASK;
+			tid = qc[0] & 0xf;
+			ista = (struct ath9k_htc_sta *)sta->drv_priv;
+			if (__ath9k_htc_check_tx_aggr(priv, ista, tid)) {
+				ieee80211_start_tx_ba_session(sta, tid, 0);
+				spin_lock_bh(&priv->tx.tx_lock);
+				ista->tid_state[tid] = AGGR_PROGRESS;
+				spin_unlock_bh(&priv->tx.tx_lock);
+			}
 		}
+	}
 
-		/* Check for RTS protection */
-		if (priv->hw->wiphy->rts_threshold != (u32) -1)
-			if (skb->len > priv->hw->wiphy->rts_threshold)
-				flags |= ATH9K_HTC_TX_RTSCTS;
+	rcu_read_unlock();
+}
 
-		/* CTS-to-self */
-		if (!(flags & ATH9K_HTC_TX_RTSCTS) &&
-		    (vif && vif->bss_conf.use_cts_prot))
-			flags |= ATH9K_HTC_TX_CTSONLY;
+static void ath9k_htc_tx_process(struct ath9k_htc_priv *priv,
+				 struct sk_buff *skb,
+				 struct __wmi_event_txstatus *txs)
+{
+	struct ieee80211_vif *vif;
+	struct ath9k_htc_tx_ctl *tx_ctl;
+	struct ieee80211_tx_info *tx_info;
+	struct ieee80211_tx_rate *rate;
+	struct ieee80211_conf *cur_conf = &priv->hw->conf;
+	bool txok;
+	int slot;
 
-		tx_hdr.flags = cpu_to_be32(flags);
-		tx_hdr.key_type = ath9k_cmn_get_hw_crypto_keytype(skb);
-		if (tx_hdr.key_type == ATH9K_KEY_TYPE_CLEAR)
-			tx_hdr.keyix = (u8) ATH9K_TXKEYIX_INVALID;
-		else
-			tx_hdr.keyix = tx_info->control.hw_key->hw_key_idx;
+	slot = strip_drv_header(priv, skb);
+	if (slot < 0) {
+		dev_kfree_skb_any(skb);
+		return;
+	}
 
-		tx_fhdr = skb_push(skb, sizeof(tx_hdr));
-		memcpy(tx_fhdr, (u8 *) &tx_hdr, sizeof(tx_hdr));
+	tx_ctl = HTC_SKB_CB(skb);
+	txok = tx_ctl->txok;
+	tx_info = IEEE80211_SKB_CB(skb);
+	vif = tx_info->control.vif;
+	rate = &tx_info->status.rates[0];
 
-		qnum = skb_get_queue_mapping(skb);
+	memset(&tx_info->status, 0, sizeof(tx_info->status));
 
-		switch (qnum) {
-		case 0:
-			TX_QSTAT_INC(WME_AC_VO);
-			epid = priv->data_vo_ep;
-			break;
-		case 1:
-			TX_QSTAT_INC(WME_AC_VI);
-			epid = priv->data_vi_ep;
-			break;
-		case 2:
-			TX_QSTAT_INC(WME_AC_BE);
-			epid = priv->data_be_ep;
-			break;
-		case 3:
-		default:
-			TX_QSTAT_INC(WME_AC_BK);
-			epid = priv->data_bk_ep;
-			break;
-		}
-	} else {
-		struct tx_mgmt_hdr mgmt_hdr;
+	/*
+	 * URB submission failed for this frame, it never reached
+	 * the target.
+	 */
+	if (!txok || !vif || !txs)
+		goto send_mac80211;
 
-		memset(&mgmt_hdr, 0, sizeof(struct tx_mgmt_hdr));
+	if (txs->ts_flags & ATH9K_HTC_TXSTAT_ACK)
+		tx_info->flags |= IEEE80211_TX_STAT_ACK;
 
-		tx_ctl.type = ATH9K_HTC_NORMAL;
+	if (txs->ts_flags & ATH9K_HTC_TXSTAT_FILT)
+		tx_info->flags |= IEEE80211_TX_STAT_TX_FILTERED;
 
-		mgmt_hdr.node_idx = sta_idx;
-		mgmt_hdr.vif_idx = vif_idx;
-		mgmt_hdr.tidno = 0;
-		mgmt_hdr.flags = 0;
+	if (txs->ts_flags & ATH9K_HTC_TXSTAT_RTC_CTS)
+		rate->flags |= IEEE80211_TX_RC_USE_RTS_CTS;
 
-		mgmt_hdr.key_type = ath9k_cmn_get_hw_crypto_keytype(skb);
-		if (mgmt_hdr.key_type == ATH9K_KEY_TYPE_CLEAR)
-			mgmt_hdr.keyix = (u8) ATH9K_TXKEYIX_INVALID;
-		else
-			mgmt_hdr.keyix = tx_info->control.hw_key->hw_key_idx;
+	rate->count = 1;
+	rate->idx = MS(txs->ts_rate, ATH9K_HTC_TXSTAT_RATE);
 
-		tx_fhdr = skb_push(skb, sizeof(mgmt_hdr));
-		memcpy(tx_fhdr, (u8 *) &mgmt_hdr, sizeof(mgmt_hdr));
-		epid = priv->mgmt_ep;
+	if (txs->ts_flags & ATH9K_HTC_TXSTAT_MCS) {
+		rate->flags |= IEEE80211_TX_RC_MCS;
+
+		if (txs->ts_flags & ATH9K_HTC_TXSTAT_CW40)
+			rate->flags |= IEEE80211_TX_RC_40_MHZ_WIDTH;
+		if (txs->ts_flags & ATH9K_HTC_TXSTAT_SGI)
+			rate->flags |= IEEE80211_TX_RC_SHORT_GI;
+	} else {
+		if (cur_conf->channel->band == IEEE80211_BAND_5GHZ)
+			rate->idx += 4; /* No CCK rates */
 	}
 
-	return htc_send(priv->htc, skb, epid, &tx_ctl);
+	ath9k_htc_check_tx_aggr(priv, vif, skb);
+
+send_mac80211:
+	spin_lock_bh(&priv->tx.tx_lock);
+	if (WARN_ON(--priv->tx.queued_cnt < 0))
+		priv->tx.queued_cnt = 0;
+	spin_unlock_bh(&priv->tx.tx_lock);
+
+	ath9k_htc_tx_clear_slot(priv, slot);
+
+	/* Send status to mac80211 */
+	ieee80211_tx_status(priv->hw, skb);
 }
 
-static bool ath9k_htc_check_tx_aggr(struct ath9k_htc_priv *priv,
-				    struct ath9k_htc_sta *ista, u8 tid)
+static inline void ath9k_htc_tx_drainq(struct ath9k_htc_priv *priv,
+				       struct sk_buff_head *queue)
 {
-	bool ret = false;
+	struct sk_buff *skb;
 
-	spin_lock_bh(&priv->tx_lock);
-	if ((tid < ATH9K_HTC_MAX_TID) && (ista->tid_state[tid] == AGGR_STOP))
-		ret = true;
-	spin_unlock_bh(&priv->tx_lock);
+	while ((skb = skb_dequeue(queue)) != NULL) {
+		ath9k_htc_tx_process(priv, skb, NULL);
+	}
+}
 
-	return ret;
+void ath9k_htc_tx_drain(struct ath9k_htc_priv *priv)
+{
+	struct ath9k_htc_tx_event *event, *tmp;
+
+	spin_lock_bh(&priv->tx.tx_lock);
+	priv->tx.flags |= ATH9K_HTC_OP_TX_DRAIN;
+	spin_unlock_bh(&priv->tx.tx_lock);
+
+	/*
+	 * Ensure that all pending TX frames are flushed,
+	 * and that the TX completion/failed tasklets is killed.
+	 */
+	htc_stop(priv->htc);
+	tasklet_kill(&priv->wmi->wmi_event_tasklet);
+	tasklet_kill(&priv->tx_failed_tasklet);
+
+	ath9k_htc_tx_drainq(priv, &priv->tx.mgmt_ep_queue);
+	ath9k_htc_tx_drainq(priv, &priv->tx.cab_ep_queue);
+	ath9k_htc_tx_drainq(priv, &priv->tx.data_be_queue);
+	ath9k_htc_tx_drainq(priv, &priv->tx.data_bk_queue);
+	ath9k_htc_tx_drainq(priv, &priv->tx.data_vi_queue);
+	ath9k_htc_tx_drainq(priv, &priv->tx.data_vo_queue);
+	ath9k_htc_tx_drainq(priv, &priv->tx.tx_failed);
+
+	/*
+	 * The TX cleanup timer has already been killed.
+	 */
+	spin_lock_bh(&priv->wmi->event_lock);
+	list_for_each_entry_safe(event, tmp, &priv->wmi->pending_tx_events, list) {
+		list_del(&event->list);
+		kfree(event);
+	}
+	spin_unlock_bh(&priv->wmi->event_lock);
+
+	spin_lock_bh(&priv->tx.tx_lock);
+	priv->tx.flags &= ~ATH9K_HTC_OP_TX_DRAIN;
+	spin_unlock_bh(&priv->tx.tx_lock);
 }
 
-void ath9k_tx_tasklet(unsigned long data)
+void ath9k_tx_failed_tasklet(unsigned long data)
 {
 	struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *)data;
-	struct ieee80211_vif *vif;
-	struct ieee80211_sta *sta;
-	struct ieee80211_hdr *hdr;
-	struct ieee80211_tx_info *tx_info;
-	struct sk_buff *skb = NULL;
-	__le16 fc;
 
-	while ((skb = skb_dequeue(&priv->tx_queue)) != NULL) {
+	spin_lock_bh(&priv->tx.tx_lock);
+	if (priv->tx.flags & ATH9K_HTC_OP_TX_DRAIN) {
+		spin_unlock_bh(&priv->tx.tx_lock);
+		return;
+	}
+	spin_unlock_bh(&priv->tx.tx_lock);
 
-		hdr = (struct ieee80211_hdr *) skb->data;
-		fc = hdr->frame_control;
-		tx_info = IEEE80211_SKB_CB(skb);
-		vif = tx_info->control.vif;
+	ath9k_htc_tx_drainq(priv, &priv->tx.tx_failed);
+}
 
-		memset(&tx_info->status, 0, sizeof(tx_info->status));
+static inline bool check_cookie(struct ath9k_htc_priv *priv,
+				struct sk_buff *skb,
+				u8 cookie, u8 epid)
+{
+	u8 fcookie = 0;
 
-		if (!vif)
-			goto send_mac80211;
+	if (epid == priv->mgmt_ep) {
+		struct tx_mgmt_hdr *hdr;
+		hdr = (struct tx_mgmt_hdr *) skb->data;
+		fcookie = hdr->cookie;
+	} else if ((epid == priv->data_bk_ep) ||
+		   (epid == priv->data_be_ep) ||
+		   (epid == priv->data_vi_ep) ||
+		   (epid == priv->data_vo_ep) ||
+		   (epid == priv->cab_ep)) {
+		struct tx_frame_hdr *hdr;
+		hdr = (struct tx_frame_hdr *) skb->data;
+		fcookie = hdr->cookie;
+	}
 
-		rcu_read_lock();
+	if (fcookie == cookie)
+		return true;
 
-		sta = ieee80211_find_sta(vif, hdr->addr1);
-		if (!sta) {
-			rcu_read_unlock();
-			ieee80211_tx_status(priv->hw, skb);
-			continue;
+	return false;
+}
+
+static struct sk_buff* ath9k_htc_tx_get_packet(struct ath9k_htc_priv *priv,
+					       struct __wmi_event_txstatus *txs)
+{
+	struct ath_common *common = ath9k_hw_common(priv->ah);
+	struct sk_buff_head *epid_queue;
+	struct sk_buff *skb, *tmp;
+	unsigned long flags;
+	u8 epid = MS(txs->ts_rate, ATH9K_HTC_TXSTAT_EPID);
+
+	epid_queue = get_htc_epid_queue(priv, epid);
+	if (!epid_queue)
+		return NULL;
+
+	spin_lock_irqsave(&epid_queue->lock, flags);
+	skb_queue_walk_safe(epid_queue, skb, tmp) {
+		if (check_cookie(priv, skb, txs->cookie, epid)) {
+			__skb_unlink(skb, epid_queue);
+			spin_unlock_irqrestore(&epid_queue->lock, flags);
+			return skb;
 		}
+	}
+	spin_unlock_irqrestore(&epid_queue->lock, flags);
 
-		/* Check if we need to start aggregation */
+	ath_dbg(common, ATH_DBG_XMIT,
+		"No matching packet for cookie: %d, epid: %d\n",
+		txs->cookie, epid);
 
-		if (sta && conf_is_ht(&priv->hw->conf) &&
-		    !(skb->protocol == cpu_to_be16(ETH_P_PAE))) {
-			if (ieee80211_is_data_qos(fc)) {
-				u8 *qc, tid;
-				struct ath9k_htc_sta *ista;
+	return NULL;
+}
 
-				qc = ieee80211_get_qos_ctl(hdr);
-				tid = qc[0] & 0xf;
-				ista = (struct ath9k_htc_sta *)sta->drv_priv;
+void ath9k_htc_txstatus(struct ath9k_htc_priv *priv, void *wmi_event)
+{
+	struct wmi_event_txstatus *txs = (struct wmi_event_txstatus *)wmi_event;
+	struct __wmi_event_txstatus *__txs;
+	struct sk_buff *skb;
+	struct ath9k_htc_tx_event *tx_pend;
+	int i;
 
-				if (ath9k_htc_check_tx_aggr(priv, ista, tid)) {
-					ieee80211_start_tx_ba_session(sta, tid, 0);
-					spin_lock_bh(&priv->tx_lock);
-					ista->tid_state[tid] = AGGR_PROGRESS;
-					spin_unlock_bh(&priv->tx_lock);
-				}
-			}
-		}
+	for (i = 0; i < txs->cnt; i++) {
+		WARN_ON(txs->cnt > HTC_MAX_TX_STATUS);
 
-		rcu_read_unlock();
+		__txs = &txs->txstatus[i];
 
-	send_mac80211:
-		/* Send status to mac80211 */
-		ieee80211_tx_status(priv->hw, skb);
+		skb = ath9k_htc_tx_get_packet(priv, __txs);
+		if (!skb) {
+			/*
+			 * Store this event, so that the TX cleanup
+			 * routine can check later for the needed packet.
+			 */
+			tx_pend = kzalloc(sizeof(struct ath9k_htc_tx_event),
+					  GFP_ATOMIC);
+			if (!tx_pend)
+				continue;
+
+			memcpy(&tx_pend->txs, __txs,
+			       sizeof(struct __wmi_event_txstatus));
+
+			spin_lock(&priv->wmi->event_lock);
+			list_add_tail(&tx_pend->list,
+				      &priv->wmi->pending_tx_events);
+			spin_unlock(&priv->wmi->event_lock);
+
+			continue;
+		}
+
+		ath9k_htc_tx_process(priv, skb, __txs);
 	}
 
 	/* Wake TX queues if needed */
-	spin_lock_bh(&priv->tx_lock);
-	if (priv->tx_queues_stop) {
-		priv->tx_queues_stop = false;
-		spin_unlock_bh(&priv->tx_lock);
-		ath_dbg(ath9k_hw_common(priv->ah), ATH_DBG_XMIT,
-			"Waking up TX queues\n");
-		ieee80211_wake_queues(priv->hw);
-		return;
-	}
-	spin_unlock_bh(&priv->tx_lock);
+	ath9k_htc_check_wake_queues(priv);
 }
 
 void ath9k_htc_txep(void *drv_priv, struct sk_buff *skb,
 		    enum htc_endpoint_id ep_id, bool txok)
 {
 	struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *) drv_priv;
-	struct ath_common *common = ath9k_hw_common(priv->ah);
-	struct ieee80211_tx_info *tx_info;
+	struct ath9k_htc_tx_ctl *tx_ctl;
+	struct sk_buff_head *epid_queue;
 
-	if (!skb)
+	tx_ctl = HTC_SKB_CB(skb);
+	tx_ctl->txok = txok;
+	tx_ctl->timestamp = jiffies;
+
+	if (!txok) {
+		skb_queue_tail(&priv->tx.tx_failed, skb);
+		tasklet_schedule(&priv->tx_failed_tasklet);
 		return;
+	}
 
-	if (ep_id == priv->mgmt_ep) {
-		skb_pull(skb, sizeof(struct tx_mgmt_hdr));
-	} else if ((ep_id == priv->data_bk_ep) ||
-		   (ep_id == priv->data_be_ep) ||
-		   (ep_id == priv->data_vi_ep) ||
-		   (ep_id == priv->data_vo_ep)) {
-		skb_pull(skb, sizeof(struct tx_frame_hdr));
-	} else {
-		ath_err(common, "Unsupported TX EPID: %d\n", ep_id);
+	epid_queue = get_htc_epid_queue(priv, ep_id);
+	if (!epid_queue) {
 		dev_kfree_skb_any(skb);
 		return;
 	}
 
-	tx_info = IEEE80211_SKB_CB(skb);
+	skb_queue_tail(epid_queue, skb);
+}
 
-	if (txok)
-		tx_info->flags |= IEEE80211_TX_STAT_ACK;
+static inline bool check_packet(struct ath9k_htc_priv *priv, struct sk_buff *skb)
+{
+	struct ath_common *common = ath9k_hw_common(priv->ah);
+	struct ath9k_htc_tx_ctl *tx_ctl;
 
-	skb_queue_tail(&priv->tx_queue, skb);
-	tasklet_schedule(&priv->tx_tasklet);
+	tx_ctl = HTC_SKB_CB(skb);
+
+	if (time_after(jiffies,
+		       tx_ctl->timestamp +
+		       msecs_to_jiffies(ATH9K_HTC_TX_TIMEOUT_INTERVAL))) {
+		ath_dbg(common, ATH_DBG_XMIT,
+			"Dropping a packet due to TX timeout\n");
+		return true;
+	}
+
+	return false;
+}
+
+static void ath9k_htc_tx_cleanup_queue(struct ath9k_htc_priv *priv,
+				       struct sk_buff_head *epid_queue)
+{
+	bool process = false;
+	unsigned long flags;
+	struct sk_buff *skb, *tmp;
+	struct sk_buff_head queue;
+
+	skb_queue_head_init(&queue);
+
+	spin_lock_irqsave(&epid_queue->lock, flags);
+	skb_queue_walk_safe(epid_queue, skb, tmp) {
+		if (check_packet(priv, skb)) {
+			__skb_unlink(skb, epid_queue);
+			__skb_queue_tail(&queue, skb);
+			process = true;
+		}
+	}
+	spin_unlock_irqrestore(&epid_queue->lock, flags);
+
+	if (process) {
+		skb_queue_walk_safe(&queue, skb, tmp) {
+			__skb_unlink(skb, &queue);
+			ath9k_htc_tx_process(priv, skb, NULL);
+		}
+	}
+}
+
+void ath9k_htc_tx_cleanup_timer(unsigned long data)
+{
+	struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *) data;
+	struct ath_common *common = ath9k_hw_common(priv->ah);
+	struct ath9k_htc_tx_event *event, *tmp;
+	struct sk_buff *skb;
+
+	spin_lock(&priv->wmi->event_lock);
+	list_for_each_entry_safe(event, tmp, &priv->wmi->pending_tx_events, list) {
+
+		skb = ath9k_htc_tx_get_packet(priv, &event->txs);
+		if (skb) {
+			ath_dbg(common, ATH_DBG_XMIT,
+				"Found packet for cookie: %d, epid: %d\n",
+				event->txs.cookie,
+				MS(event->txs.ts_rate, ATH9K_HTC_TXSTAT_EPID));
+
+			ath9k_htc_tx_process(priv, skb, &event->txs);
+			list_del(&event->list);
+			kfree(event);
+			continue;
+		}
+
+		if (++event->count >= ATH9K_HTC_TX_TIMEOUT_COUNT) {
+			list_del(&event->list);
+			kfree(event);
+		}
+	}
+	spin_unlock(&priv->wmi->event_lock);
+
+	/*
+	 * Check if status-pending packets have to be cleaned up.
+	 */
+	ath9k_htc_tx_cleanup_queue(priv, &priv->tx.mgmt_ep_queue);
+	ath9k_htc_tx_cleanup_queue(priv, &priv->tx.cab_ep_queue);
+	ath9k_htc_tx_cleanup_queue(priv, &priv->tx.data_be_queue);
+	ath9k_htc_tx_cleanup_queue(priv, &priv->tx.data_bk_queue);
+	ath9k_htc_tx_cleanup_queue(priv, &priv->tx.data_vi_queue);
+	ath9k_htc_tx_cleanup_queue(priv, &priv->tx.data_vo_queue);
+
+	/* Wake TX queues if needed */
+	ath9k_htc_check_wake_queues(priv);
+
+	mod_timer(&priv->tx.cleanup_timer,
+		  jiffies + msecs_to_jiffies(ATH9K_HTC_TX_CLEANUP_INTERVAL));
 }
 
 int ath9k_tx_init(struct ath9k_htc_priv *priv)
 {
-	skb_queue_head_init(&priv->tx_queue);
+	skb_queue_head_init(&priv->tx.mgmt_ep_queue);
+	skb_queue_head_init(&priv->tx.cab_ep_queue);
+	skb_queue_head_init(&priv->tx.data_be_queue);
+	skb_queue_head_init(&priv->tx.data_bk_queue);
+	skb_queue_head_init(&priv->tx.data_vi_queue);
+	skb_queue_head_init(&priv->tx.data_vo_queue);
+	skb_queue_head_init(&priv->tx.tx_failed);
 	return 0;
 }
 
@@ -414,6 +875,7 @@
 		rfilt |= ATH9K_RX_FILTER_CONTROL;
 
 	if ((ah->opmode == NL80211_IFTYPE_STATION) &&
+	    (priv->nvifs <= 1) &&
 	    !(priv->rxfilter & FIF_BCN_PRBRESP_PROMISC))
 		rfilt |= ATH9K_RX_FILTER_MYBEACON;
 	else
@@ -427,6 +889,9 @@
 	if (priv->rxfilter & FIF_PSPOLL)
 		rfilt |= ATH9K_RX_FILTER_PSPOLL;
 
+	if (priv->nvifs > 1)
+		rfilt |= ATH9K_RX_FILTER_MCAST_BCAST_ALL;
+
 	return rfilt;
 
 #undef RX_FILTER_PRESERVE
@@ -507,8 +972,9 @@
 	int last_rssi = ATH_RSSI_DUMMY_MARKER;
 	__le16 fc;
 
-	if (skb->len <= HTC_RX_FRAME_HEADER_SIZE) {
-		ath_err(common, "Corrupted RX frame, dropping\n");
+	if (skb->len < HTC_RX_FRAME_HEADER_SIZE) {
+		ath_err(common, "Corrupted RX frame, dropping (len: %d)\n",
+			skb->len);
 		goto rx_next;
 	}
 
@@ -522,6 +988,8 @@
 		goto rx_next;
 	}
 
+	ath9k_htc_err_stat_rx(priv, rxstatus);
+
 	/* Get the RX status information */
 	memcpy(&rxbuf->rxstatus, rxstatus, HTC_RX_FRAME_HEADER_SIZE);
 	skb_pull(skb, HTC_RX_FRAME_HEADER_SIZE);
diff -druN linux-2.6.39-libre/drivers/net/wireless/ath/ath9k/htc.h linux-3.0-rc7-libre/drivers/net/wireless/ath/ath9k/htc.h
--- linux-2.6.39-libre/drivers/net/wireless/ath/ath9k/htc.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/ath/ath9k/htc.h	2011-07-11 19:51:52.000000000 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010 Atheros Communications Inc.
+ * Copyright (c) 2010-2011 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
@@ -46,15 +46,8 @@
 extern int htc_modparam_nohwcrypt;
 
 enum htc_phymode {
-	HTC_MODE_AUTO		= 0,
-	HTC_MODE_11A		= 1,
-	HTC_MODE_11B		= 2,
-	HTC_MODE_11G		= 3,
-	HTC_MODE_FH		= 4,
-	HTC_MODE_TURBO_A	= 5,
-	HTC_MODE_TURBO_G	= 6,
-	HTC_MODE_11NA		= 7,
-	HTC_MODE_11NG		= 8
+	HTC_MODE_11NA		= 0,
+	HTC_MODE_11NG		= 1
 };
 
 enum htc_opmode {
@@ -66,13 +59,13 @@
 	HTC_M_WDS	= 2
 };
 
-#define ATH9K_HTC_HDRSPACE sizeof(struct htc_frame_hdr)
-#define ATH9K_HTC_AMPDU	1
+#define ATH9K_HTC_AMPDU  1
 #define ATH9K_HTC_NORMAL 2
+#define ATH9K_HTC_BEACON 3
+#define ATH9K_HTC_MGMT   4
 
 #define ATH9K_HTC_TX_CTSONLY      0x1
 #define ATH9K_HTC_TX_RTSCTS       0x2
-#define ATH9K_HTC_TX_USE_MIN_RATE 0x100
 
 struct tx_frame_hdr {
 	u8 data_type;
@@ -82,7 +75,8 @@
 	__be32 flags; /* ATH9K_HTC_TX_* */
 	u8 key_type;
 	u8 keyix;
-	u8 reserved[26];
+	u8 cookie;
+	u8 pad;
 } __packed;
 
 struct tx_mgmt_hdr {
@@ -92,78 +86,46 @@
 	u8 flags;
 	u8 key_type;
 	u8 keyix;
-	u16 reserved;
+	u8 cookie;
+	u8 pad;
 } __packed;
 
 struct tx_beacon_header {
-	u8 len_changed;
 	u8 vif_index;
+	u8 len_changed;
 	u16 rev;
 } __packed;
 
-struct ath9k_htc_target_hw {
-	u32 flags;
-	u32 flags_ext;
-	u32 ampdu_limit;
-	u8 ampdu_subframes;
-	u8 tx_chainmask;
-	u8 tx_chainmask_legacy;
-	u8 rtscts_ratecode;
-	u8 protmode;
-} __packed;
+#define MAX_TX_AMPDU_SUBFRAMES_9271 17
+#define MAX_TX_AMPDU_SUBFRAMES_7010 22
 
 struct ath9k_htc_cap_target {
-	u32 flags;
-	u32 flags_ext;
-	u32 ampdu_limit;
+	__be32 ampdu_limit;
 	u8 ampdu_subframes;
+	u8 enable_coex;
 	u8 tx_chainmask;
-	u8 tx_chainmask_legacy;
-	u8 rtscts_ratecode;
-	u8 protmode;
+	u8 pad;
 } __packed;
 
 struct ath9k_htc_target_vif {
 	u8 index;
-	u8 des_bssid[ETH_ALEN];
-	__be32 opmode;
+	u8 opmode;
 	u8 myaddr[ETH_ALEN];
-	u8 bssid[ETH_ALEN];
-	u32 flags;
-	u32 flags_ext;
-	u16 ps_sta;
-	__be16 rtsthreshold;
 	u8 ath_cap;
-	u8 node;
-	s8 mcast_rate;
+	__be16 rtsthreshold;
+	u8 pad;
 } __packed;
 
-#define ATH_HTC_STA_AUTH  0x0001
-#define ATH_HTC_STA_QOS   0x0002
-#define ATH_HTC_STA_ERP   0x0004
-#define ATH_HTC_STA_HT    0x0008
-
-/* FIXME: UAPSD variables */
 struct ath9k_htc_target_sta {
-	u16 associd;
-	u16 txpower;
-	u32 ucastkey;
 	u8 macaddr[ETH_ALEN];
 	u8 bssid[ETH_ALEN];
 	u8 sta_index;
 	u8 vif_index;
-	u8 vif_sta;
-	__be16 flags; /* ATH_HTC_STA_* */
-	u16 htcap;
-	u8 valid;
-	u16 capinfo;
-	struct ath9k_htc_target_hw *hw;
-	struct ath9k_htc_target_vif *vif;
-	u16 txseqmgmt;
 	u8 is_vif_sta;
-	u16 maxampdu;
-	u16 iv16;
-	u32 iv32;
+	__be16 flags;
+	__be16 htcap;
+	__be16 maxampdu;
+	u8 pad;
 } __packed;
 
 struct ath9k_htc_target_aggr {
@@ -197,12 +159,38 @@
 	struct ath9k_htc_rate rates;
 };
 
-struct ath9k_htc_target_stats {
-	__be32 tx_shortretry;
-	__be32 tx_longretry;
-	__be32 tx_xretries;
-	__be32 ht_txunaggr_xretry;
-	__be32 ht_tx_xretries;
+struct ath9k_htc_target_rate_mask {
+	u8 vif_index;
+	u8 band;
+	__be32 mask;
+	u16 pad;
+} __packed;
+
+struct ath9k_htc_target_int_stats {
+	__be32 rx;
+	__be32 rxorn;
+	__be32 rxeol;
+	__be32 txurn;
+	__be32 txto;
+	__be32 cst;
+} __packed;
+
+struct ath9k_htc_target_tx_stats {
+	__be32 xretries;
+	__be32 fifoerr;
+	__be32 filtered;
+	__be32 timer_exp;
+	__be32 shortretries;
+	__be32 longretries;
+	__be32 qnull;
+	__be32 encap_fail;
+	__be32 nobuf;
+} __packed;
+
+struct ath9k_htc_target_rx_stats {
+	__be32 nobuf;
+	__be32 host_send;
+	__be32 host_done;
 } __packed;
 
 #define ATH9K_HTC_MAX_VIF 2
@@ -244,6 +232,8 @@
 	u8 index;
 	u16 seq_no;
 	bool beacon_configured;
+	int bslot;
+	__le64 tsfadjust;
 };
 
 struct ath9k_vif_iter_data {
@@ -282,23 +272,65 @@
 	spinlock_t rxbuflock;
 };
 
+#define ATH9K_HTC_TX_CLEANUP_INTERVAL 50 /* ms */
+#define ATH9K_HTC_TX_TIMEOUT_INTERVAL 3000 /* ms */
+#define ATH9K_HTC_TX_RESERVE 10
+#define ATH9K_HTC_TX_TIMEOUT_COUNT 40
+#define ATH9K_HTC_TX_THRESHOLD (MAX_TX_BUF_NUM - ATH9K_HTC_TX_RESERVE)
+
+#define ATH9K_HTC_OP_TX_QUEUES_STOP BIT(0)
+#define ATH9K_HTC_OP_TX_DRAIN       BIT(1)
+
+struct ath9k_htc_tx {
+	u8 flags;
+	int queued_cnt;
+	struct sk_buff_head mgmt_ep_queue;
+	struct sk_buff_head cab_ep_queue;
+	struct sk_buff_head data_be_queue;
+	struct sk_buff_head data_bk_queue;
+	struct sk_buff_head data_vi_queue;
+	struct sk_buff_head data_vo_queue;
+	struct sk_buff_head tx_failed;
+	DECLARE_BITMAP(tx_slot, MAX_TX_BUF_NUM);
+	struct timer_list cleanup_timer;
+	spinlock_t tx_lock;
+};
+
 struct ath9k_htc_tx_ctl {
 	u8 type; /* ATH9K_HTC_* */
+	u8 epid;
+	u8 txok;
+	u8 sta_idx;
+	unsigned long timestamp;
 };
 
+static inline struct ath9k_htc_tx_ctl *HTC_SKB_CB(struct sk_buff *skb)
+{
+	struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
+
+	BUILD_BUG_ON(sizeof(struct ath9k_htc_tx_ctl) >
+		     IEEE80211_TX_INFO_DRIVER_DATA_SIZE);
+	return (struct ath9k_htc_tx_ctl *) &tx_info->driver_data;
+}
+
 #ifdef CONFIG_ATH9K_HTC_DEBUGFS
 
 #define TX_STAT_INC(c) (hif_dev->htc_handle->drv_priv->debug.tx_stats.c++)
 #define RX_STAT_INC(c) (hif_dev->htc_handle->drv_priv->debug.rx_stats.c++)
+#define CAB_STAT_INC   priv->debug.tx_stats.cab_queued++
 
 #define TX_QSTAT_INC(q) (priv->debug.tx_stats.queue_stats[q]++)
 
+void ath9k_htc_err_stat_rx(struct ath9k_htc_priv *priv,
+			   struct ath_htc_rx_status *rxs);
+
 struct ath_tx_stats {
 	u32 buf_queued;
 	u32 buf_completed;
 	u32 skb_queued;
-	u32 skb_completed;
-	u32 skb_dropped;
+	u32 skb_success;
+	u32 skb_failed;
+	u32 cab_queued;
 	u32 queue_stats[WME_NUM_AC];
 };
 
@@ -306,55 +338,57 @@
 	u32 skb_allocated;
 	u32 skb_completed;
 	u32 skb_dropped;
+	u32 err_crc;
+	u32 err_decrypt_crc;
+	u32 err_mic;
+	u32 err_pre_delim;
+	u32 err_post_delim;
+	u32 err_decrypt_busy;
+	u32 err_phy;
+	u32 err_phy_stats[ATH9K_PHYERR_MAX];
 };
 
 struct ath9k_debug {
 	struct dentry *debugfs_phy;
-	struct dentry *debugfs_tgt_stats;
-	struct dentry *debugfs_xmit;
-	struct dentry *debugfs_recv;
 	struct ath_tx_stats tx_stats;
 	struct ath_rx_stats rx_stats;
-	u32 txrate;
 };
 
 #else
 
 #define TX_STAT_INC(c) do { } while (0)
 #define RX_STAT_INC(c) do { } while (0)
+#define CAB_STAT_INC   do { } while (0)
 
 #define TX_QSTAT_INC(c) do { } while (0)
 
+static inline void ath9k_htc_err_stat_rx(struct ath9k_htc_priv *priv,
+					 struct ath_htc_rx_status *rxs)
+{
+}
+
 #endif /* CONFIG_ATH9K_HTC_DEBUGFS */
 
 #define ATH_LED_PIN_DEF             1
-#define ATH_LED_PIN_9287            8
+#define ATH_LED_PIN_9287            10
 #define ATH_LED_PIN_9271            15
 #define ATH_LED_PIN_7010            12
-#define ATH_LED_ON_DURATION_IDLE    350	/* in msecs */
-#define ATH_LED_OFF_DURATION_IDLE   250	/* in msecs */
 
-enum ath_led_type {
-	ATH_LED_RADIO,
-	ATH_LED_ASSOC,
-	ATH_LED_TX,
-	ATH_LED_RX
-};
+#define BSTUCK_THRESHOLD 10
 
-struct ath_led {
-	struct ath9k_htc_priv *priv;
-	struct led_classdev led_cdev;
-	enum ath_led_type led_type;
-	struct delayed_work brightness_work;
-	char name[32];
-	bool registered;
-	int brightness;
-};
+/*
+ * Adjust these when the max. no of beaconing interfaces is
+ * increased.
+ */
+#define DEFAULT_SWBA_RESPONSE 40 /* in TUs */
+#define MIN_SWBA_RESPONSE     10 /* in TUs */
 
 struct htc_beacon_config {
+	struct ieee80211_vif *bslot[ATH9K_HTC_MAX_BCN_VIF];
 	u16 beacon_interval;
 	u16 dtim_period;
 	u16 bmiss_timeout;
+	u32 bmiss_cnt;
 };
 
 struct ath_btcoex {
@@ -372,14 +406,11 @@
 
 #define OP_INVALID		   BIT(0)
 #define OP_SCANNING		   BIT(1)
-#define OP_LED_ASSOCIATED	   BIT(2)
-#define OP_LED_ON		   BIT(3)
-#define OP_ENABLE_BEACON	   BIT(4)
-#define OP_LED_DEINIT		   BIT(5)
-#define OP_BT_PRIORITY_DETECTED    BIT(6)
-#define OP_BT_SCAN                 BIT(7)
-#define OP_ANI_RUNNING             BIT(8)
-#define OP_TSF_RESET               BIT(9)
+#define OP_ENABLE_BEACON           BIT(2)
+#define OP_BT_PRIORITY_DETECTED    BIT(3)
+#define OP_BT_SCAN                 BIT(4)
+#define OP_ANI_RUNNING             BIT(5)
+#define OP_TSF_RESET               BIT(6)
 
 struct ath9k_htc_priv {
 	struct device *dev;
@@ -388,6 +419,9 @@
 	struct htc_target *htc;
 	struct wmi *wmi;
 
+	u16 fw_version_major;
+	u16 fw_version_minor;
+
 	enum htc_endpoint_id wmi_cmd_ep;
 	enum htc_endpoint_id beacon_ep;
 	enum htc_endpoint_id cab_ep;
@@ -404,6 +438,7 @@
 	u8 vif_sta_pos[ATH9K_HTC_MAX_VIF];
 	u8 num_ibss_vif;
 	u8 num_sta_vif;
+	u8 num_sta_assoc_vif;
 	u8 num_ap_vif;
 
 	u16 op_flags;
@@ -411,27 +446,23 @@
 	u16 txpowlimit;
 	u16 nvifs;
 	u16 nstations;
-	u32 bmiss_cnt;
 	bool rearm_ani;
 	bool reconfig_beacon;
+	unsigned int rxfilter;
 
 	struct ath9k_hw_cal_data caldata;
+	struct ieee80211_supported_band sbands[IEEE80211_NUM_BANDS];
 
 	spinlock_t beacon_lock;
+	struct htc_beacon_config cur_beacon_conf;
 
-	bool tx_queues_stop;
-	spinlock_t tx_lock;
+	struct ath9k_htc_rx rx;
+	struct ath9k_htc_tx tx;
 
-	struct ieee80211_vif *vif;
-	struct htc_beacon_config cur_beacon_conf;
-	unsigned int rxfilter;
 	struct tasklet_struct swba_tasklet;
 	struct tasklet_struct rx_tasklet;
-	struct ieee80211_supported_band sbands[IEEE80211_NUM_BANDS];
-	struct ath9k_htc_rx rx;
-	struct tasklet_struct tx_tasklet;
-	struct sk_buff_head tx_queue;
 	struct delayed_work ani_work;
+	struct tasklet_struct tx_failed_tasklet;
 	struct work_struct ps_work;
 	struct work_struct fatal_work;
 
@@ -440,15 +471,13 @@
 	bool ps_enabled;
 	bool ps_idle;
 
-	struct ath_led radio_led;
-	struct ath_led assoc_led;
-	struct ath_led tx_led;
-	struct ath_led rx_led;
-	struct delayed_work ath9k_led_blink_work;
-	int led_on_duration;
-	int led_off_duration;
-	int led_on_cnt;
-	int led_off_cnt;
+#ifdef CONFIG_MAC80211_LEDS
+	enum led_brightness brightness;
+	bool led_registered;
+	char led_name[32];
+	struct led_classdev led_cdev;
+	struct work_struct led_work;
+#endif
 
 	int beaconq;
 	int cabq;
@@ -470,11 +499,18 @@
 
 void ath9k_htc_reset(struct ath9k_htc_priv *priv);
 
+void ath9k_htc_assign_bslot(struct ath9k_htc_priv *priv,
+			    struct ieee80211_vif *vif);
+void ath9k_htc_remove_bslot(struct ath9k_htc_priv *priv,
+			    struct ieee80211_vif *vif);
+void ath9k_htc_set_tsfadjust(struct ath9k_htc_priv *priv,
+			     struct ieee80211_vif *vif);
 void ath9k_htc_beaconq_config(struct ath9k_htc_priv *priv);
 void ath9k_htc_beacon_config(struct ath9k_htc_priv *priv,
 			     struct ieee80211_vif *vif);
 void ath9k_htc_beacon_reconfig(struct ath9k_htc_priv *priv);
-void ath9k_htc_swba(struct ath9k_htc_priv *priv, u8 beacon_pending);
+void ath9k_htc_swba(struct ath9k_htc_priv *priv,
+		    struct wmi_event_swba *swba);
 
 void ath9k_htc_rxep(void *priv, struct sk_buff *skb,
 		    enum htc_endpoint_id ep_id);
@@ -483,7 +519,8 @@
 void ath9k_htc_beaconep(void *drv_priv, struct sk_buff *skb,
 			enum htc_endpoint_id ep_id, bool txok);
 
-int ath9k_htc_update_cap_target(struct ath9k_htc_priv *priv);
+int ath9k_htc_update_cap_target(struct ath9k_htc_priv *priv,
+				u8 enable_coex);
 void ath9k_htc_station_work(struct work_struct *work);
 void ath9k_htc_aggr_work(struct work_struct *work);
 void ath9k_htc_ani_work(struct work_struct *work);
@@ -491,14 +528,23 @@
 void ath9k_htc_stop_ani(struct ath9k_htc_priv *priv);
 
 int ath9k_tx_init(struct ath9k_htc_priv *priv);
-void ath9k_tx_tasklet(unsigned long data);
-int ath9k_htc_tx_start(struct ath9k_htc_priv *priv, struct sk_buff *skb);
+int ath9k_htc_tx_start(struct ath9k_htc_priv *priv,
+		       struct sk_buff *skb, u8 slot, bool is_cab);
 void ath9k_tx_cleanup(struct ath9k_htc_priv *priv);
 bool ath9k_htc_txq_setup(struct ath9k_htc_priv *priv, int subtype);
 int ath9k_htc_cabq_setup(struct ath9k_htc_priv *priv);
 int get_hw_qnum(u16 queue, int *hwq_map);
 int ath_htc_txq_update(struct ath9k_htc_priv *priv, int qnum,
 		       struct ath9k_tx_queue_info *qinfo);
+void ath9k_htc_check_stop_queues(struct ath9k_htc_priv *priv);
+void ath9k_htc_check_wake_queues(struct ath9k_htc_priv *priv);
+int ath9k_htc_tx_get_slot(struct ath9k_htc_priv *priv);
+void ath9k_htc_tx_clear_slot(struct ath9k_htc_priv *priv, int slot);
+void ath9k_htc_tx_drain(struct ath9k_htc_priv *priv);
+void ath9k_htc_txstatus(struct ath9k_htc_priv *priv, void *wmi_event);
+void ath9k_htc_tx_failed(struct ath9k_htc_priv *priv);
+void ath9k_tx_failed_tasklet(unsigned long data);
+void ath9k_htc_tx_cleanup_timer(unsigned long data);
 
 int ath9k_rx_init(struct ath9k_htc_priv *priv);
 void ath9k_rx_cleanup(struct ath9k_htc_priv *priv);
@@ -516,9 +562,24 @@
 void ath9k_htc_rfkill_poll_state(struct ieee80211_hw *hw);
 void ath9k_htc_radio_enable(struct ieee80211_hw *hw);
 void ath9k_htc_radio_disable(struct ieee80211_hw *hw);
-void ath9k_led_stop_brightness(struct ath9k_htc_priv *priv);
+
+#ifdef CONFIG_MAC80211_LEDS
 void ath9k_init_leds(struct ath9k_htc_priv *priv);
 void ath9k_deinit_leds(struct ath9k_htc_priv *priv);
+void ath9k_led_work(struct work_struct *work);
+#else
+static inline void ath9k_init_leds(struct ath9k_htc_priv *priv)
+{
+}
+
+static inline void ath9k_deinit_leds(struct ath9k_htc_priv *priv)
+{
+}
+
+static inline void ath9k_led_work(struct work_struct *work)
+{
+}
+#endif
 
 int ath9k_htc_probe_device(struct htc_target *htc_handle, struct device *dev,
 			   u16 devid, char *product, u32 drv_info);
@@ -528,15 +589,9 @@
 int ath9k_htc_resume(struct htc_target *htc_handle);
 #endif
 #ifdef CONFIG_ATH9K_HTC_DEBUGFS
-int ath9k_htc_debug_create_root(void);
-void ath9k_htc_debug_remove_root(void);
 int ath9k_htc_init_debug(struct ath_hw *ah);
-void ath9k_htc_exit_debug(struct ath_hw *ah);
 #else
-static inline int ath9k_htc_debug_create_root(void) { return 0; };
-static inline void ath9k_htc_debug_remove_root(void) {};
 static inline int ath9k_htc_init_debug(struct ath_hw *ah) { return 0; };
-static inline void ath9k_htc_exit_debug(struct ath_hw *ah) {};
 #endif /* CONFIG_ATH9K_HTC_DEBUGFS */
 
 #endif /* HTC_H */
diff -druN linux-2.6.39-libre/drivers/net/wireless/ath/ath9k/htc_hst.c linux-3.0-rc7-libre/drivers/net/wireless/ath/ath9k/htc_hst.c
--- linux-2.6.39-libre/drivers/net/wireless/ath/ath9k/htc_hst.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/ath/ath9k/htc_hst.c	2011-07-11 19:51:52.000000000 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010 Atheros Communications Inc.
+ * Copyright (c) 2010-2011 Atheros Communications Inc.
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
@@ -17,8 +17,8 @@
 #include "htc.h"
 
 static int htc_issue_send(struct htc_target *target, struct sk_buff* skb,
-			  u16 len, u8 flags, u8 epid,
-			  struct ath9k_htc_tx_ctl *tx_ctl)
+			  u16 len, u8 flags, u8 epid)
+
 {
 	struct htc_frame_hdr *hdr;
 	struct htc_endpoint *endpoint = &target->endpoint[epid];
@@ -30,8 +30,8 @@
 	hdr->flags = flags;
 	hdr->payload_len = cpu_to_be16(len);
 
-	status = target->hif->send(target->hif_dev, endpoint->ul_pipeid, skb,
-				   tx_ctl);
+	status = target->hif->send(target->hif_dev, endpoint->ul_pipeid, skb);
+
 	return status;
 }
 
@@ -162,7 +162,7 @@
 
 	target->htc_flags |= HTC_OP_CONFIG_PIPE_CREDITS;
 
-	ret = htc_issue_send(target, skb, skb->len, 0, ENDPOINT0, NULL);
+	ret = htc_issue_send(target, skb, skb->len, 0, ENDPOINT0);
 	if (ret)
 		goto err;
 
@@ -197,7 +197,7 @@
 
 	target->htc_flags |= HTC_OP_START_WAIT;
 
-	ret = htc_issue_send(target, skb, skb->len, 0, ENDPOINT0, NULL);
+	ret = htc_issue_send(target, skb, skb->len, 0, ENDPOINT0);
 	if (ret)
 		goto err;
 
@@ -268,7 +268,7 @@
 	conn_msg->dl_pipeid = endpoint->dl_pipeid;
 	conn_msg->ul_pipeid = endpoint->ul_pipeid;
 
-	ret = htc_issue_send(target, skb, skb->len, 0, ENDPOINT0, NULL);
+	ret = htc_issue_send(target, skb, skb->len, 0, ENDPOINT0);
 	if (ret)
 		goto err;
 
@@ -286,35 +286,33 @@
 	return ret;
 }
 
-int htc_send(struct htc_target *target, struct sk_buff *skb,
-	     enum htc_endpoint_id epid, struct ath9k_htc_tx_ctl *tx_ctl)
+int htc_send(struct htc_target *target, struct sk_buff *skb)
 {
-	return htc_issue_send(target, skb, skb->len, 0, epid, tx_ctl);
+	struct ath9k_htc_tx_ctl *tx_ctl;
+
+	tx_ctl = HTC_SKB_CB(skb);
+	return htc_issue_send(target, skb, skb->len, 0, tx_ctl->epid);
 }
 
-void htc_stop(struct htc_target *target)
+int htc_send_epid(struct htc_target *target, struct sk_buff *skb,
+		  enum htc_endpoint_id epid)
 {
-	enum htc_endpoint_id epid;
-	struct htc_endpoint *endpoint;
+	return htc_issue_send(target, skb, skb->len, 0, epid);
+}
 
-	for (epid = ENDPOINT0; epid < ENDPOINT_MAX; epid++) {
-		endpoint = &target->endpoint[epid];
-		if (endpoint->service_id != 0)
-			target->hif->stop(target->hif_dev, endpoint->ul_pipeid);
-	}
+void htc_stop(struct htc_target *target)
+{
+	target->hif->stop(target->hif_dev);
 }
 
 void htc_start(struct htc_target *target)
 {
-	enum htc_endpoint_id epid;
-	struct htc_endpoint *endpoint;
+	target->hif->start(target->hif_dev);
+}
 
-	for (epid = ENDPOINT0; epid < ENDPOINT_MAX; epid++) {
-		endpoint = &target->endpoint[epid];
-		if (endpoint->service_id != 0)
-			target->hif->start(target->hif_dev,
-					   endpoint->ul_pipeid);
-	}
+void htc_sta_drain(struct htc_target *target, u8 idx)
+{
+	target->hif->sta_drain(target->hif_dev, idx);
 }
 
 void ath9k_htc_txcompletion_cb(struct htc_target *htc_handle,
diff -druN linux-2.6.39-libre/drivers/net/wireless/ath/ath9k/htc_hst.h linux-3.0-rc7-libre/drivers/net/wireless/ath/ath9k/htc_hst.h
--- linux-2.6.39-libre/drivers/net/wireless/ath/ath9k/htc_hst.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/ath/ath9k/htc_hst.h	2011-07-11 19:51:52.000000000 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010 Atheros Communications Inc.
+ * Copyright (c) 2010-2011 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
@@ -33,10 +33,10 @@
 	u8 control_dl_pipe;
 	u8 control_ul_pipe;
 
-	void (*start) (void *hif_handle, u8 pipe);
-	void (*stop) (void *hif_handle, u8 pipe);
-	int (*send) (void *hif_handle, u8 pipe, struct sk_buff *buf,
-		     struct ath9k_htc_tx_ctl *tx_ctl);
+	void (*start) (void *hif_handle);
+	void (*stop) (void *hif_handle);
+	void (*sta_drain) (void *hif_handle, u8 idx);
+	int (*send) (void *hif_handle, u8 pipe, struct sk_buff *buf);
 };
 
 enum htc_endpoint_id {
@@ -83,21 +83,10 @@
 	void (*rx) (void *, struct sk_buff *, enum htc_endpoint_id);
 };
 
-#define HTC_TX_QUEUE_SIZE 256
-
-struct htc_txq {
-	struct sk_buff *buf[HTC_TX_QUEUE_SIZE];
-	u32 txqdepth;
-	u16 txbuf_cnt;
-	u16 txq_head;
-	u16 txq_tail;
-};
-
 struct htc_endpoint {
 	u16 service_id;
 
 	struct htc_ep_callbacks ep_callbacks;
-	struct htc_txq htc_txq;
 	u32 max_txqdepth;
 	int max_msglen;
 
@@ -205,10 +194,12 @@
 int htc_connect_service(struct htc_target *target,
 			  struct htc_service_connreq *service_connreq,
 			  enum htc_endpoint_id *conn_rsp_eid);
-int htc_send(struct htc_target *target, struct sk_buff *skb,
-	     enum htc_endpoint_id eid, struct ath9k_htc_tx_ctl *tx_ctl);
+int htc_send(struct htc_target *target, struct sk_buff *skb);
+int htc_send_epid(struct htc_target *target, struct sk_buff *skb,
+		  enum htc_endpoint_id epid);
 void htc_stop(struct htc_target *target);
 void htc_start(struct htc_target *target);
+void htc_sta_drain(struct htc_target *target, u8 idx);
 
 void ath9k_htc_rx_msg(struct htc_target *htc_handle,
 		      struct sk_buff *skb, u32 len, u8 pipe_id);
diff -druN linux-2.6.39-libre/drivers/net/wireless/ath/ath9k/hw.c linux-3.0-rc7-libre/drivers/net/wireless/ath/ath9k/hw.c
--- linux-2.6.39-libre/drivers/net/wireless/ath/ath9k/hw.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/ath/ath9k/hw.c	2011-07-11 19:51:52.000000000 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008-2010 Atheros Communications Inc.
+ * Copyright (c) 2008-2011 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
@@ -130,6 +130,20 @@
 }
 EXPORT_SYMBOL(ath9k_hw_wait);
 
+void ath9k_hw_write_array(struct ath_hw *ah, struct ar5416IniArray *array,
+			  int column, unsigned int *writecnt)
+{
+	int r;
+
+	ENABLE_REGWRITE_BUFFER(ah);
+	for (r = 0; r < array->ia_rows; r++) {
+		REG_WRITE(ah, INI_RA(array, r, 0),
+			  INI_RA(array, r, column));
+		DO_DELAY(*writecnt);
+	}
+	REGWRITE_BUFFER_FLUSH(ah);
+}
+
 u32 ath9k_hw_reverse_bits(u32 val, u32 n)
 {
 	u32 retval;
@@ -142,25 +156,6 @@
 	return retval;
 }
 
-bool ath9k_get_channel_edges(struct ath_hw *ah,
-			     u16 flags, u16 *low,
-			     u16 *high)
-{
-	struct ath9k_hw_capabilities *pCap = &ah->caps;
-
-	if (flags & CHANNEL_5GHZ) {
-		*low = pCap->low_5ghz_chan;
-		*high = pCap->high_5ghz_chan;
-		return true;
-	}
-	if ((flags & CHANNEL_2GHZ)) {
-		*low = pCap->low_2ghz_chan;
-		*high = pCap->high_2ghz_chan;
-		return true;
-	}
-	return false;
-}
-
 u16 ath9k_hw_computetxtime(struct ath_hw *ah,
 			   u8 phy, int kbps,
 			   u32 frameLen, u16 rateix,
@@ -252,6 +247,17 @@
 {
 	u32 val;
 
+	switch (ah->hw_version.devid) {
+	case AR5416_AR9100_DEVID:
+		ah->hw_version.macVersion = AR_SREV_VERSION_9100;
+		break;
+	case AR9300_DEVID_AR9340:
+		ah->hw_version.macVersion = AR_SREV_VERSION_9340;
+		val = REG_READ(ah, AR_SREV);
+		ah->hw_version.macRev = MS(val, AR_SREV_REVISION2);
+		return;
+	}
+
 	val = REG_READ(ah, AR_SREV) & AR_SREV_ID;
 
 	if (val == 0xFF) {
@@ -364,11 +370,6 @@
 		ah->config.spurchans[i][1] = AR_NO_SPUR;
 	}
 
-	if (ah->hw_version.devid != AR2427_DEVID_PCIE)
-		ah->config.ht_enable = 1;
-	else
-		ah->config.ht_enable = 0;
-
 	/* PAPRD needs some more work to be enabled */
 	ah->config.paprd_disable = 1;
 
@@ -410,6 +411,8 @@
 	ah->sta_id1_defaults =
 		AR_STA_ID1_CRPT_MIC_ENABLE |
 		AR_STA_ID1_MCAST_KSRCH;
+	if (AR_SREV_9100(ah))
+		ah->sta_id1_defaults |= AR_STA_ID1_AR9100_BA_FIX;
 	ah->enable_32kHz_clock = DONT_USE_32KHZ;
 	ah->slottime = 20;
 	ah->globaltxtimeout = (u32) -1;
@@ -470,7 +473,7 @@
 		return ecode;
 	}
 
-	if (!AR_SREV_9100(ah)) {
+	if (!AR_SREV_9100(ah) && !AR_SREV_9340(ah)) {
 		ath9k_hw_ani_setup(ah);
 		ath9k_hw_ani_init(ah);
 	}
@@ -492,9 +495,6 @@
 	struct ath_common *common = ath9k_hw_common(ah);
 	int r = 0;
 
-	if (ah->hw_version.devid == AR5416_AR9100_DEVID)
-		ah->hw_version.macVersion = AR_SREV_VERSION_9100;
-
 	ath9k_hw_read_revisions(ah);
 
 	/*
@@ -552,6 +552,7 @@
 	case AR_SREV_VERSION_9271:
 	case AR_SREV_VERSION_9300:
 	case AR_SREV_VERSION_9485:
+	case AR_SREV_VERSION_9340:
 		break;
 	default:
 		ath_err(common,
@@ -560,7 +561,7 @@
 		return -EOPNOTSUPP;
 	}
 
-	if (AR_SREV_9271(ah) || AR_SREV_9100(ah))
+	if (AR_SREV_9271(ah) || AR_SREV_9100(ah) || AR_SREV_9340(ah))
 		ah->is_pciexpress = false;
 
 	ah->hw_version.phyRev = REG_READ(ah, AR_PHY_CHIP_ID);
@@ -629,6 +630,7 @@
 	case AR2427_DEVID_PCIE:
 	case AR9300_DEVID_PCIE:
 	case AR9300_DEVID_AR9485_PCIE:
+	case AR9300_DEVID_AR9340:
 		break;
 	default:
 		if (common->bus_ops->ath_bus_type == ATH_USB)
@@ -671,48 +673,89 @@
 	REGWRITE_BUFFER_FLUSH(ah);
 }
 
-unsigned long ar9003_get_pll_sqsum_dvc(struct ath_hw *ah)
+u32 ar9003_get_pll_sqsum_dvc(struct ath_hw *ah)
 {
-		REG_WRITE(ah, PLL3, (REG_READ(ah, PLL3) & ~(PLL3_DO_MEAS_MASK)));
-		udelay(100);
-		REG_WRITE(ah, PLL3, (REG_READ(ah, PLL3) | PLL3_DO_MEAS_MASK));
+	REG_CLR_BIT(ah, PLL3, PLL3_DO_MEAS_MASK);
+	udelay(100);
+	REG_SET_BIT(ah, PLL3, PLL3_DO_MEAS_MASK);
 
-		while ((REG_READ(ah, PLL4) & PLL4_MEAS_DONE) == 0)
-			udelay(100);
+	while ((REG_READ(ah, PLL4) & PLL4_MEAS_DONE) == 0)
+		udelay(100);
 
-		return (REG_READ(ah, PLL3) & SQSUM_DVC_MASK) >> 3;
+	return (REG_READ(ah, PLL3) & SQSUM_DVC_MASK) >> 3;
 }
 EXPORT_SYMBOL(ar9003_get_pll_sqsum_dvc);
 
-#define DPLL2_KD_VAL            0x3D
-#define DPLL2_KI_VAL            0x06
-#define DPLL3_PHASE_SHIFT_VAL   0x1
-
 static void ath9k_hw_init_pll(struct ath_hw *ah,
 			      struct ath9k_channel *chan)
 {
 	u32 pll;
 
 	if (AR_SREV_9485(ah)) {
-		REG_WRITE(ah, AR_RTC_PLL_CONTROL2, 0x886666);
-		REG_WRITE(ah, AR_CH0_DDR_DPLL2, 0x19e82f01);
-
-		REG_RMW_FIELD(ah, AR_CH0_DDR_DPLL3,
-			      AR_CH0_DPLL3_PHASE_SHIFT, DPLL3_PHASE_SHIFT_VAL);
 
-		REG_WRITE(ah, AR_RTC_PLL_CONTROL, 0x1142c);
-		udelay(1000);
+		/* program BB PLL ki and kd value, ki=0x4, kd=0x40 */
+		REG_RMW_FIELD(ah, AR_CH0_BB_DPLL2,
+			      AR_CH0_BB_DPLL2_PLL_PWD, 0x1);
+		REG_RMW_FIELD(ah, AR_CH0_BB_DPLL2,
+			      AR_CH0_DPLL2_KD, 0x40);
+		REG_RMW_FIELD(ah, AR_CH0_BB_DPLL2,
+			      AR_CH0_DPLL2_KI, 0x4);
 
-		REG_WRITE(ah, AR_RTC_PLL_CONTROL2, 0x886666);
+		REG_RMW_FIELD(ah, AR_CH0_BB_DPLL1,
+			      AR_CH0_BB_DPLL1_REFDIV, 0x5);
+		REG_RMW_FIELD(ah, AR_CH0_BB_DPLL1,
+			      AR_CH0_BB_DPLL1_NINI, 0x58);
+		REG_RMW_FIELD(ah, AR_CH0_BB_DPLL1,
+			      AR_CH0_BB_DPLL1_NFRAC, 0x0);
 
 		REG_RMW_FIELD(ah, AR_CH0_BB_DPLL2,
-			      AR_CH0_DPLL2_KD, DPLL2_KD_VAL);
+			      AR_CH0_BB_DPLL2_OUTDIV, 0x1);
 		REG_RMW_FIELD(ah, AR_CH0_BB_DPLL2,
-			      AR_CH0_DPLL2_KI, DPLL2_KI_VAL);
+			      AR_CH0_BB_DPLL2_LOCAL_PLL, 0x1);
+		REG_RMW_FIELD(ah, AR_CH0_BB_DPLL2,
+			      AR_CH0_BB_DPLL2_EN_NEGTRIG, 0x1);
 
+		/* program BB PLL phase_shift to 0x6 */
 		REG_RMW_FIELD(ah, AR_CH0_BB_DPLL3,
-			      AR_CH0_DPLL3_PHASE_SHIFT, DPLL3_PHASE_SHIFT_VAL);
-		REG_WRITE(ah, AR_RTC_PLL_CONTROL, 0x142c);
+			      AR_CH0_BB_DPLL3_PHASE_SHIFT, 0x6);
+
+		REG_RMW_FIELD(ah, AR_CH0_BB_DPLL2,
+			      AR_CH0_BB_DPLL2_PLL_PWD, 0x0);
+		udelay(1000);
+	} else if (AR_SREV_9340(ah)) {
+		u32 regval, pll2_divint, pll2_divfrac, refdiv;
+
+		REG_WRITE(ah, AR_RTC_PLL_CONTROL, 0x1142c);
+		udelay(1000);
+
+		REG_SET_BIT(ah, AR_PHY_PLL_MODE, 0x1 << 16);
+		udelay(100);
+
+		if (ah->is_clk_25mhz) {
+			pll2_divint = 0x54;
+			pll2_divfrac = 0x1eb85;
+			refdiv = 3;
+		} else {
+			pll2_divint = 88;
+			pll2_divfrac = 0;
+			refdiv = 5;
+		}
+
+		regval = REG_READ(ah, AR_PHY_PLL_MODE);
+		regval |= (0x1 << 16);
+		REG_WRITE(ah, AR_PHY_PLL_MODE, regval);
+		udelay(100);
+
+		REG_WRITE(ah, AR_PHY_PLL_CONTROL, (refdiv << 27) |
+			  (pll2_divint << 18) | pll2_divfrac);
+		udelay(100);
+
+		regval = REG_READ(ah, AR_PHY_PLL_MODE);
+		regval = (regval & 0x80071fff) | (0x1 << 30) | (0x1 << 13) |
+			 (0x4 << 26) | (0x18 << 19);
+		REG_WRITE(ah, AR_PHY_PLL_MODE, regval);
+		REG_WRITE(ah, AR_PHY_PLL_MODE,
+			  REG_READ(ah, AR_PHY_PLL_MODE) & 0xfffeffff);
 		udelay(1000);
 	}
 
@@ -720,6 +763,9 @@
 
 	REG_WRITE(ah, AR_RTC_PLL_CONTROL, pll);
 
+	if (AR_SREV_9485(ah) || AR_SREV_9340(ah))
+		udelay(1000);
+
 	/* Switch the core clock for ar9271 to 117Mhz */
 	if (AR_SREV_9271(ah)) {
 		udelay(500);
@@ -729,17 +775,34 @@
 	udelay(RTC_PLL_SETTLE_DELAY);
 
 	REG_WRITE(ah, AR_RTC_SLEEP_CLK, AR_RTC_FORCE_DERIVED_CLK);
+
+	if (AR_SREV_9340(ah)) {
+		if (ah->is_clk_25mhz) {
+			REG_WRITE(ah, AR_RTC_DERIVED_CLK, 0x17c << 1);
+			REG_WRITE(ah, AR_SLP32_MODE, 0x0010f3d7);
+			REG_WRITE(ah,  AR_SLP32_INC, 0x0001e7ae);
+		} else {
+			REG_WRITE(ah, AR_RTC_DERIVED_CLK, 0x261 << 1);
+			REG_WRITE(ah, AR_SLP32_MODE, 0x0010f400);
+			REG_WRITE(ah,  AR_SLP32_INC, 0x0001e800);
+		}
+		udelay(100);
+	}
 }
 
 static void ath9k_hw_init_interrupt_masks(struct ath_hw *ah,
 					  enum nl80211_iftype opmode)
 {
+	u32 sync_default = AR_INTR_SYNC_DEFAULT;
 	u32 imr_reg = AR_IMR_TXERR |
 		AR_IMR_TXURN |
 		AR_IMR_RXERR |
 		AR_IMR_RXORN |
 		AR_IMR_BCNMISC;
 
+	if (AR_SREV_9340(ah))
+		sync_default &= ~AR_INTR_SYNC_HOST1_FATAL;
+
 	if (AR_SREV_9300_20_OR_LATER(ah)) {
 		imr_reg |= AR_IMR_RXOK_HP;
 		if (ah->config.rx_intr_mitigation)
@@ -770,7 +833,7 @@
 
 	if (!AR_SREV_9100(ah)) {
 		REG_WRITE(ah, AR_INTR_SYNC_CAUSE, 0xFFFFFFFF);
-		REG_WRITE(ah, AR_INTR_SYNC_ENABLE, AR_INTR_SYNC_DEFAULT);
+		REG_WRITE(ah, AR_INTR_SYNC_ENABLE, sync_default);
 		REG_WRITE(ah, AR_INTR_SYNC_MASK, 0);
 	}
 
@@ -830,8 +893,7 @@
 		ah->misc_mode);
 
 	if (ah->misc_mode != 0)
-		REG_WRITE(ah, AR_PCU_MISC,
-			  REG_READ(ah, AR_PCU_MISC) | ah->misc_mode);
+		REG_SET_BIT(ah, AR_PCU_MISC, ah->misc_mode);
 
 	if (conf->channel && conf->channel->band == IEEE80211_BAND_5GHZ)
 		sifstime = 16;
@@ -899,23 +961,19 @@
 static inline void ath9k_hw_set_dma(struct ath_hw *ah)
 {
 	struct ath_common *common = ath9k_hw_common(ah);
-	u32 regval;
 
 	ENABLE_REGWRITE_BUFFER(ah);
 
 	/*
 	 * set AHB_MODE not to do cacheline prefetches
 	*/
-	if (!AR_SREV_9300_20_OR_LATER(ah)) {
-		regval = REG_READ(ah, AR_AHB_MODE);
-		REG_WRITE(ah, AR_AHB_MODE, regval | AR_AHB_PREFETCH_RD_EN);
-	}
+	if (!AR_SREV_9300_20_OR_LATER(ah))
+		REG_SET_BIT(ah, AR_AHB_MODE, AR_AHB_PREFETCH_RD_EN);
 
 	/*
 	 * let mac dma reads be in 128 byte chunks
 	 */
-	regval = REG_READ(ah, AR_TXCFG) & ~AR_TXCFG_DMASZ_MASK;
-	REG_WRITE(ah, AR_TXCFG, regval | AR_TXCFG_DMASZ_128B);
+	REG_RMW(ah, AR_TXCFG, AR_TXCFG_DMASZ_128B, AR_TXCFG_DMASZ_MASK);
 
 	REGWRITE_BUFFER_FLUSH(ah);
 
@@ -932,8 +990,7 @@
 	/*
 	 * let mac dma writes be in 128 byte chunks
 	 */
-	regval = REG_READ(ah, AR_RXCFG) & ~AR_RXCFG_DMASZ_MASK;
-	REG_WRITE(ah, AR_RXCFG, regval | AR_RXCFG_DMASZ_128B);
+	REG_RMW(ah, AR_RXCFG, AR_RXCFG_DMASZ_128B, AR_RXCFG_DMASZ_MASK);
 
 	/*
 	 * Setup receive FIFO threshold to hold off TX activities
@@ -972,30 +1029,27 @@
 
 static void ath9k_hw_set_operating_mode(struct ath_hw *ah, int opmode)
 {
-	u32 val;
+	u32 mask = AR_STA_ID1_STA_AP | AR_STA_ID1_ADHOC;
+	u32 set = AR_STA_ID1_KSRCH_MODE;
 
-	val = REG_READ(ah, AR_STA_ID1);
-	val &= ~(AR_STA_ID1_STA_AP | AR_STA_ID1_ADHOC);
 	switch (opmode) {
-	case NL80211_IFTYPE_AP:
-		REG_WRITE(ah, AR_STA_ID1, val | AR_STA_ID1_STA_AP
-			  | AR_STA_ID1_KSRCH_MODE);
-		REG_CLR_BIT(ah, AR_CFG, AR_CFG_AP_ADHOC_INDICATION);
-		break;
 	case NL80211_IFTYPE_ADHOC:
 	case NL80211_IFTYPE_MESH_POINT:
-		REG_WRITE(ah, AR_STA_ID1, val | AR_STA_ID1_ADHOC
-			  | AR_STA_ID1_KSRCH_MODE);
+		set |= AR_STA_ID1_ADHOC;
 		REG_SET_BIT(ah, AR_CFG, AR_CFG_AP_ADHOC_INDICATION);
 		break;
+	case NL80211_IFTYPE_AP:
+		set |= AR_STA_ID1_STA_AP;
+		/* fall through */
 	case NL80211_IFTYPE_STATION:
-		REG_WRITE(ah, AR_STA_ID1, val | AR_STA_ID1_KSRCH_MODE);
+		REG_CLR_BIT(ah, AR_CFG, AR_CFG_AP_ADHOC_INDICATION);
 		break;
 	default:
-		if (ah->is_monitoring)
-			REG_WRITE(ah, AR_STA_ID1, val | AR_STA_ID1_KSRCH_MODE);
+		if (!ah->is_monitoring)
+			set = 0;
 		break;
 	}
+	REG_RMW(ah, AR_STA_ID1, set, mask);
 }
 
 void ath9k_hw_get_delta_slope_vals(struct ath_hw *ah, u32 coef_scaled,
@@ -1021,10 +1075,8 @@
 	u32 tmpReg;
 
 	if (AR_SREV_9100(ah)) {
-		u32 val = REG_READ(ah, AR_RTC_DERIVED_CLK);
-		val &= ~AR_RTC_DERIVED_CLK_PERIOD;
-		val |= SM(1, AR_RTC_DERIVED_CLK_PERIOD);
-		REG_WRITE(ah, AR_RTC_DERIVED_CLK, val);
+		REG_RMW_FIELD(ah, AR_RTC_DERIVED_CLK,
+			      AR_RTC_DERIVED_CLK_PERIOD, 1);
 		(void)REG_READ(ah, AR_RTC_DERIVED_CLK);
 	}
 
@@ -1212,6 +1264,20 @@
 	return true;
 }
 
+static void ath9k_hw_apply_gpio_override(struct ath_hw *ah)
+{
+	u32 gpio_mask = ah->gpio_mask;
+	int i;
+
+	for (i = 0; gpio_mask; i++, gpio_mask >>= 1) {
+		if (!(gpio_mask & 1))
+			continue;
+
+		ath9k_hw_cfg_output(ah, i, AR_GPIO_OUTPUT_MUX_AS_OUTPUT);
+		ath9k_hw_set_gpio(ah, i, !!(ah->gpio_val & BIT(i)));
+	}
+}
+
 bool ath9k_hw_check_alive(struct ath_hw *ah)
 {
 	int count = 50;
@@ -1409,7 +1475,7 @@
 	REGWRITE_BUFFER_FLUSH(ah);
 
 	ah->intr_txqs = 0;
-	for (i = 0; i < ah->caps.total_queues; i++)
+	for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++)
 		ath9k_hw_resettxqueue(ah, i);
 
 	ath9k_hw_init_interrupt_masks(ah, ah->opmode);
@@ -1426,8 +1492,7 @@
 		ar9002_hw_enable_wep_aggregation(ah);
 	}
 
-	REG_WRITE(ah, AR_STA_ID1,
-		  REG_READ(ah, AR_STA_ID1) | AR_STA_ID1_PRESERVE_SEQNUM);
+	REG_SET_BIT(ah, AR_STA_ID1, AR_STA_ID1_PRESERVE_SEQNUM);
 
 	ath9k_hw_set_dma(ah);
 
@@ -1480,7 +1545,9 @@
 				REG_WRITE(ah, AR_CFG, AR_CFG_SWTD | AR_CFG_SWRD);
 		}
 #ifdef __BIG_ENDIAN
-                else
+		else if (AR_SREV_9340(ah))
+			REG_RMW(ah, AR_CFG, AR_CFG_SWRB | AR_CFG_SWTB, 0);
+		else
 			REG_WRITE(ah, AR_CFG, AR_CFG_SWTD | AR_CFG_SWRD);
 #endif
 	}
@@ -1488,9 +1555,14 @@
 	if (ah->btcoex_hw.enabled)
 		ath9k_hw_btcoex_enable(ah);
 
-	if (AR_SREV_9300_20_OR_LATER(ah))
+	if (AR_SREV_9300_20_OR_LATER(ah)) {
 		ar9003_hw_bb_watchdog_config(ah);
 
+		ar9003_hw_disable_phy_restart(ah);
+	}
+
+	ath9k_hw_apply_gpio_override(ah);
+
 	return 0;
 }
 EXPORT_SYMBOL(ath9k_hw_reset);
@@ -1670,21 +1742,15 @@
 	case NL80211_IFTYPE_MESH_POINT:
 		REG_SET_BIT(ah, AR_TXCFG,
 			    AR_TXCFG_ADHOC_BEACON_ATIM_TX_POLICY);
-		REG_WRITE(ah, AR_NEXT_NDP_TIMER,
-			  TU_TO_USEC(next_beacon +
-				     (ah->atim_window ? ah->
-				      atim_window : 1)));
+		REG_WRITE(ah, AR_NEXT_NDP_TIMER, next_beacon +
+			  TU_TO_USEC(ah->atim_window ? ah->atim_window : 1));
 		flags |= AR_NDP_TIMER_EN;
 	case NL80211_IFTYPE_AP:
-		REG_WRITE(ah, AR_NEXT_TBTT_TIMER, TU_TO_USEC(next_beacon));
-		REG_WRITE(ah, AR_NEXT_DMA_BEACON_ALERT,
-			  TU_TO_USEC(next_beacon -
-				     ah->config.
-				     dma_beacon_response_time));
-		REG_WRITE(ah, AR_NEXT_SWBA,
-			  TU_TO_USEC(next_beacon -
-				     ah->config.
-				     sw_beacon_response_time));
+		REG_WRITE(ah, AR_NEXT_TBTT_TIMER, next_beacon);
+		REG_WRITE(ah, AR_NEXT_DMA_BEACON_ALERT, next_beacon -
+			  TU_TO_USEC(ah->config.dma_beacon_response_time));
+		REG_WRITE(ah, AR_NEXT_SWBA, next_beacon -
+			  TU_TO_USEC(ah->config.sw_beacon_response_time));
 		flags |=
 			AR_TBTT_TIMER_EN | AR_DBA_TIMER_EN | AR_SWBA_TIMER_EN;
 		break;
@@ -1696,18 +1762,13 @@
 		break;
 	}
 
-	REG_WRITE(ah, AR_BEACON_PERIOD, TU_TO_USEC(beacon_period));
-	REG_WRITE(ah, AR_DMA_BEACON_PERIOD, TU_TO_USEC(beacon_period));
-	REG_WRITE(ah, AR_SWBA_PERIOD, TU_TO_USEC(beacon_period));
-	REG_WRITE(ah, AR_NDP_PERIOD, TU_TO_USEC(beacon_period));
+	REG_WRITE(ah, AR_BEACON_PERIOD, beacon_period);
+	REG_WRITE(ah, AR_DMA_BEACON_PERIOD, beacon_period);
+	REG_WRITE(ah, AR_SWBA_PERIOD, beacon_period);
+	REG_WRITE(ah, AR_NDP_PERIOD, beacon_period);
 
 	REGWRITE_BUFFER_FLUSH(ah);
 
-	beacon_period &= ~ATH9K_BEACON_ENA;
-	if (beacon_period & ATH9K_BEACON_RESET_TSF) {
-		ath9k_hw_reset_tsf(ah);
-	}
-
 	REG_SET_BIT(ah, AR_TIMER_MODE, flags);
 }
 EXPORT_SYMBOL(ath9k_hw_beaconinit);
@@ -1795,7 +1856,7 @@
 	struct ath_common *common = ath9k_hw_common(ah);
 	struct ath_btcoex_hw *btcoex_hw = &ah->btcoex_hw;
 
-	u16 capField = 0, eeval;
+	u16 eeval;
 	u8 ant_div_ctl1, tx_chainmask, rx_chainmask;
 
 	eeval = ah->eep_ops->get_eeprom(ah, EEP_REG_0);
@@ -1806,8 +1867,6 @@
 		eeval |= AR9285_RDEXT_DEFAULT;
 	regulatory->current_rd_ext = eeval;
 
-	capField = ah->eep_ops->get_eeprom(ah, EEP_OP_CAP);
-
 	if (ah->opmode != NL80211_IFTYPE_AP &&
 	    ah->hw_version.subvendorid == AR_SUBVENDOR_ID_NEW_A) {
 		if (regulatory->current_rd == 0x64 ||
@@ -1842,6 +1901,8 @@
 	    !(AR_SREV_9271(ah)))
 		/* CB71: GPIO 0 is pulled down to indicate 3 rx chains */
 		pCap->rx_chainmask = ath9k_hw_gpio_get(ah, 0) ? 0x5 : 0x7;
+	else if (AR_SREV_9100(ah))
+		pCap->rx_chainmask = 0x7;
 	else
 		/* Use rx_chainmask from EEPROM. */
 		pCap->rx_chainmask = ah->eep_ops->get_eeprom(ah, EEP_RX_MASK);
@@ -1852,36 +1913,13 @@
 	if (AR_SREV_9300_20_OR_LATER(ah))
 		ah->misc_mode |= AR_PCU_ALWAYS_PERFORM_KEYSEARCH;
 
-	pCap->low_2ghz_chan = 2312;
-	pCap->high_2ghz_chan = 2732;
-
-	pCap->low_5ghz_chan = 4920;
-	pCap->high_5ghz_chan = 6100;
-
 	common->crypt_caps |= ATH_CRYPT_CAP_CIPHER_AESCCM;
 
-	if (ah->config.ht_enable)
+	if (ah->hw_version.devid != AR2427_DEVID_PCIE)
 		pCap->hw_caps |= ATH9K_HW_CAP_HT;
 	else
 		pCap->hw_caps &= ~ATH9K_HW_CAP_HT;
 
-	if (capField & AR_EEPROM_EEPCAP_MAXQCU)
-		pCap->total_queues =
-			MS(capField, AR_EEPROM_EEPCAP_MAXQCU);
-	else
-		pCap->total_queues = ATH9K_NUM_TX_QUEUES;
-
-	if (capField & AR_EEPROM_EEPCAP_KC_ENTRIES)
-		pCap->keycache_size =
-			1 << MS(capField, AR_EEPROM_EEPCAP_KC_ENTRIES);
-	else
-		pCap->keycache_size = AR_KEYTABLE_SIZE;
-
-	if (AR_SREV_9285(ah) || AR_SREV_9271(ah))
-		pCap->tx_triglevel_max = MAX_TX_FIFO_THRESHOLD >> 1;
-	else
-		pCap->tx_triglevel_max = MAX_TX_FIFO_THRESHOLD;
-
 	if (AR_SREV_9271(ah))
 		pCap->num_gpio_pins = AR9271_NUM_GPIO;
 	else if (AR_DEVID_7010(ah))
@@ -1900,8 +1938,6 @@
 		pCap->rts_aggr_limit = (8 * 1024);
 	}
 
-	pCap->hw_caps |= ATH9K_HW_CAP_ENHANCEDPM;
-
 #if defined(CONFIG_RFKILL) || defined(CONFIG_RFKILL_MODULE)
 	ah->rfsilent = ah->eep_ops->get_eeprom(ah, EEP_RF_SILENT);
 	if (ah->rfsilent & EEP_RFSILENT_ENABLED) {
@@ -1923,32 +1959,23 @@
 	else
 		pCap->hw_caps |= ATH9K_HW_CAP_4KB_SPLITTRANS;
 
-	if (regulatory->current_rd_ext & (1 << REG_EXT_JAPAN_MIDBAND)) {
-		pCap->reg_cap =
-			AR_EEPROM_EEREGCAP_EN_KK_NEW_11A |
-			AR_EEPROM_EEREGCAP_EN_KK_U1_EVEN |
-			AR_EEPROM_EEREGCAP_EN_KK_U2 |
-			AR_EEPROM_EEREGCAP_EN_KK_MIDBAND;
-	} else {
-		pCap->reg_cap =
-			AR_EEPROM_EEREGCAP_EN_KK_NEW_11A |
-			AR_EEPROM_EEREGCAP_EN_KK_U1_EVEN;
-	}
-
-	/* Advertise midband for AR5416 with FCC midband set in eeprom */
-	if (regulatory->current_rd_ext & (1 << REG_EXT_FCC_MIDBAND) &&
-	    AR_SREV_5416(ah))
-		pCap->reg_cap |= AR_EEPROM_EEREGCAP_EN_FCC_MIDBAND;
-
-	if (AR_SREV_9280_20_OR_LATER(ah) && common->btcoex_enabled) {
-		btcoex_hw->btactive_gpio = ATH_BTACTIVE_GPIO;
-		btcoex_hw->wlanactive_gpio = ATH_WLANACTIVE_GPIO;
-
-		if (AR_SREV_9285(ah)) {
+	if (common->btcoex_enabled) {
+		if (AR_SREV_9300_20_OR_LATER(ah)) {
 			btcoex_hw->scheme = ATH_BTCOEX_CFG_3WIRE;
-			btcoex_hw->btpriority_gpio = ATH_BTPRIORITY_GPIO;
-		} else {
-			btcoex_hw->scheme = ATH_BTCOEX_CFG_2WIRE;
+			btcoex_hw->btactive_gpio = ATH_BTACTIVE_GPIO_9300;
+			btcoex_hw->wlanactive_gpio = ATH_WLANACTIVE_GPIO_9300;
+			btcoex_hw->btpriority_gpio = ATH_BTPRIORITY_GPIO_9300;
+		} else if (AR_SREV_9280_20_OR_LATER(ah)) {
+			btcoex_hw->btactive_gpio = ATH_BTACTIVE_GPIO_9280;
+			btcoex_hw->wlanactive_gpio = ATH_WLANACTIVE_GPIO_9280;
+
+			if (AR_SREV_9285(ah)) {
+				btcoex_hw->scheme = ATH_BTCOEX_CFG_3WIRE;
+				btcoex_hw->btpriority_gpio =
+						ATH_BTPRIORITY_GPIO_9285;
+			} else {
+				btcoex_hw->scheme = ATH_BTCOEX_CFG_2WIRE;
+			}
 		}
 	} else {
 		btcoex_hw->scheme = ATH_BTCOEX_CFG_NONE;
@@ -1998,6 +2025,22 @@
 	}
 
 
+	if (AR_SREV_9485(ah)) {
+		ant_div_ctl1 = ah->eep_ops->get_eeprom(ah, EEP_ANT_DIV_CTL1);
+		/*
+		 * enable the diversity-combining algorithm only when
+		 * both enable_lna_div and enable_fast_div are set
+		 *		Table for Diversity
+		 * ant_div_alt_lnaconf		bit 0-1
+		 * ant_div_main_lnaconf		bit 2-3
+		 * ant_div_alt_gaintb		bit 4
+		 * ant_div_main_gaintb		bit 5
+		 * enable_ant_div_lnadiv	bit 6
+		 * enable_ant_fast_div		bit 7
+		 */
+		if ((ant_div_ctl1 >> 0x6) == 0x3)
+			pCap->hw_caps |= ATH9K_HW_CAP_ANT_DIV_COMB;
+	}
 
 	if (AR_SREV_9485_10(ah)) {
 		pCap->pcie_lcr_extsync_en = true;
@@ -2186,11 +2229,9 @@
 	REG_WRITE(ah, AR_PHY_ERR, phybits);
 
 	if (phybits)
-		REG_WRITE(ah, AR_RXCFG,
-			  REG_READ(ah, AR_RXCFG) | AR_RXCFG_ZLFDMA);
+		REG_SET_BIT(ah, AR_RXCFG, AR_RXCFG_ZLFDMA);
 	else
-		REG_WRITE(ah, AR_RXCFG,
-			  REG_READ(ah, AR_RXCFG) & ~AR_RXCFG_ZLFDMA);
+		REG_CLR_BIT(ah, AR_RXCFG, AR_RXCFG_ZLFDMA);
 
 	REGWRITE_BUFFER_FLUSH(ah);
 }
@@ -2366,10 +2407,11 @@
 	return timer_table->gen_timer_index[b];
 }
 
-static u32 ath9k_hw_gettsf32(struct ath_hw *ah)
+u32 ath9k_hw_gettsf32(struct ath_hw *ah)
 {
 	return REG_READ(ah, AR_TSF_L32);
 }
+EXPORT_SYMBOL(ath9k_hw_gettsf32);
 
 struct ath_gen_timer *ath_gen_timer_alloc(struct ath_hw *ah,
 					  void (*trigger)(void *),
@@ -2402,11 +2444,11 @@
 
 void ath9k_hw_gen_timer_start(struct ath_hw *ah,
 			      struct ath_gen_timer *timer,
-			      u32 timer_next,
+			      u32 trig_timeout,
 			      u32 timer_period)
 {
 	struct ath_gen_timer_table *timer_table = &ah->hw_gen_timers;
-	u32 tsf;
+	u32 tsf, timer_next;
 
 	BUG_ON(!timer_period);
 
@@ -2414,18 +2456,13 @@
 
 	tsf = ath9k_hw_gettsf32(ah);
 
+	timer_next = tsf + trig_timeout;
+
 	ath_dbg(ath9k_hw_common(ah), ATH_DBG_HWTIMER,
 		"current tsf %x period %x timer_next %x\n",
 		tsf, timer_period, timer_next);
 
 	/*
-	 * Pull timer_next forward if the current TSF already passed it
-	 * because of software latency
-	 */
-	if (timer_next < tsf)
-		timer_next = tsf + timer_period;
-
-	/*
 	 * Program generic timer registers
 	 */
 	REG_WRITE(ah, gen_tmr_configuration[timer->index].next_addr,
diff -druN linux-2.6.39-libre/drivers/net/wireless/ath/ath9k/hw.h linux-3.0-rc7-libre/drivers/net/wireless/ath/ath9k/hw.h
--- linux-2.6.39-libre/drivers/net/wireless/ath/ath9k/hw.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/ath/ath9k/hw.h	2011-07-11 19:51:52.000000000 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008-2010 Atheros Communications Inc.
+ * Copyright (c) 2008-2011 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
@@ -43,6 +43,7 @@
 #define AR9287_DEVID_PCI	0x002d
 #define AR9287_DEVID_PCIE	0x002e
 #define AR9300_DEVID_PCIE	0x0030
+#define AR9300_DEVID_AR9340	0x0031
 #define AR9300_DEVID_AR9485_PCIE 0x0032
 
 #define AR5416_AR9100_DEVID	0x000b
@@ -55,6 +56,9 @@
 #define AT9285_COEX3WIRE_SA_SUBSYSID	0x30aa
 #define AT9285_COEX3WIRE_DA_SUBSYSID	0x30ab
 
+#define AR9300_NUM_BT_WEIGHTS   4
+#define AR9300_NUM_WLAN_WEIGHTS 4
+
 #define ATH_AMPDU_LIMIT_MAX        (64 * 1024 - 1)
 
 #define	ATH_DEFAULT_NOISE_FLOOR -95
@@ -65,53 +69,49 @@
 
 /* Register read/write primitives */
 #define REG_WRITE(_ah, _reg, _val) \
-	ath9k_hw_common(_ah)->ops->write((_ah), (_val), (_reg))
+	(_ah)->reg_ops.write((_ah), (_val), (_reg))
 
 #define REG_READ(_ah, _reg) \
-	ath9k_hw_common(_ah)->ops->read((_ah), (_reg))
+	(_ah)->reg_ops.read((_ah), (_reg))
 
 #define REG_READ_MULTI(_ah, _addr, _val, _cnt)		\
-	ath9k_hw_common(_ah)->ops->multi_read((_ah), (_addr), (_val), (_cnt))
+	(_ah)->reg_ops.multi_read((_ah), (_addr), (_val), (_cnt))
+
+#define REG_RMW(_ah, _reg, _set, _clr) \
+	(_ah)->reg_ops.rmw((_ah), (_reg), (_set), (_clr))
 
 #define ENABLE_REGWRITE_BUFFER(_ah)					\
 	do {								\
-		if (ath9k_hw_common(_ah)->ops->enable_write_buffer)	\
-			ath9k_hw_common(_ah)->ops->enable_write_buffer((_ah)); \
+		if ((_ah)->reg_ops.enable_write_buffer)	\
+			(_ah)->reg_ops.enable_write_buffer((_ah)); \
 	} while (0)
 
 #define REGWRITE_BUFFER_FLUSH(_ah)					\
 	do {								\
-		if (ath9k_hw_common(_ah)->ops->write_flush)		\
-			ath9k_hw_common(_ah)->ops->write_flush((_ah));	\
+		if ((_ah)->reg_ops.write_flush)		\
+			(_ah)->reg_ops.write_flush((_ah));	\
 	} while (0)
 
 #define SM(_v, _f)  (((_v) << _f##_S) & _f)
 #define MS(_v, _f)  (((_v) & _f) >> _f##_S)
-#define REG_RMW(_a, _r, _set, _clr)    \
-	REG_WRITE(_a, _r, (REG_READ(_a, _r) & ~(_clr)) | (_set))
 #define REG_RMW_FIELD(_a, _r, _f, _v) \
-	REG_WRITE(_a, _r, \
-	(REG_READ(_a, _r) & ~_f) | (((_v) << _f##_S) & _f))
+	REG_RMW(_a, _r, (((_v) << _f##_S) & _f), (_f))
 #define REG_READ_FIELD(_a, _r, _f) \
 	(((REG_READ(_a, _r) & _f) >> _f##_S))
 #define REG_SET_BIT(_a, _r, _f) \
-	REG_WRITE(_a, _r, REG_READ(_a, _r) | (_f))
+	REG_RMW(_a, _r, (_f), 0)
 #define REG_CLR_BIT(_a, _r, _f) \
-	REG_WRITE(_a, _r, REG_READ(_a, _r) & ~(_f))
+	REG_RMW(_a, _r, 0, (_f))
 
-#define DO_DELAY(x) do {			\
-		if ((++(x) % 64) == 0)          \
-			udelay(1);		\
+#define DO_DELAY(x) do {					\
+		if (((++(x) % 64) == 0) &&			\
+		    (ath9k_hw_common(ah)->bus_ops->ath_bus_type	\
+			!= ATH_USB))				\
+			udelay(1);				\
 	} while (0)
 
-#define REG_WRITE_ARRAY(iniarray, column, regWr) do {                   \
-		int r;							\
-		for (r = 0; r < ((iniarray)->ia_rows); r++) {		\
-			REG_WRITE(ah, INI_RA((iniarray), (r), 0),	\
-				  INI_RA((iniarray), r, (column)));	\
-			DO_DELAY(regWr);				\
-		}							\
-	} while (0)
+#define REG_WRITE_ARRAY(iniarray, column, regWr) \
+	ath9k_hw_write_array(ah, iniarray, column, &(regWr))
 
 #define AR_GPIO_OUTPUT_MUX_AS_OUTPUT             0
 #define AR_GPIO_OUTPUT_MUX_AS_PCIE_ATTENTION_LED 1
@@ -125,7 +125,7 @@
 #define AR_GPIO_BIT(_gpio)          (1 << (_gpio))
 
 #define BASE_ACTIVATE_DELAY         100
-#define RTC_PLL_SETTLE_DELAY        100
+#define RTC_PLL_SETTLE_DELAY        (AR_SREV_9340(ah) ? 1000 : 100)
 #define COEF_SCALE_S                24
 #define HT40_CHANNEL_CENTER_SHIFT   10
 
@@ -178,7 +178,6 @@
 	ATH9K_HW_CAP_HT                         = BIT(0),
 	ATH9K_HW_CAP_RFSILENT                   = BIT(1),
 	ATH9K_HW_CAP_CST                        = BIT(2),
-	ATH9K_HW_CAP_ENHANCEDPM                 = BIT(3),
 	ATH9K_HW_CAP_AUTOSLEEP                  = BIT(4),
 	ATH9K_HW_CAP_4KB_SPLITTRANS             = BIT(5),
 	ATH9K_HW_CAP_EDMA			= BIT(6),
@@ -195,17 +194,11 @@
 
 struct ath9k_hw_capabilities {
 	u32 hw_caps; /* ATH9K_HW_CAP_* from ath9k_hw_caps */
-	u16 total_queues;
-	u16 keycache_size;
-	u16 low_5ghz_chan, high_5ghz_chan;
-	u16 low_2ghz_chan, high_2ghz_chan;
 	u16 rts_aggr_limit;
 	u8 tx_chainmask;
 	u8 rx_chainmask;
 	u8 max_txchains;
 	u8 max_rxchains;
-	u16 tx_triglevel_max;
-	u16 reg_cap;
 	u8 num_gpio_pins;
 	u8 rx_hp_qdepth;
 	u8 rx_lp_qdepth;
@@ -227,7 +220,6 @@
 	u8 pcie_clock_req;
 	u32 pcie_waen;
 	u8 analog_shiftreg;
-	u8 ht_enable;
 	u8 paprd_disable;
 	u32 ofdm_trig_low;
 	u32 ofdm_trig_high;
@@ -412,8 +404,6 @@
 	u32 bs_nextdtim;
 	u32 bs_intval;
 #define ATH9K_BEACON_PERIOD       0x0000ffff
-#define ATH9K_BEACON_ENA          0x00800000
-#define ATH9K_BEACON_RESET_TSF    0x01000000
 #define ATH9K_TSFOOR_THRESHOLD    0x00004240 /* 16k us */
 	u32 bs_dtimperiod;
 	u16 bs_cfpperiod;
@@ -489,6 +479,10 @@
 	u8 main_lna_conf;
 	u8 alt_lna_conf;
 	u8 fast_div_bias;
+	u8 main_gaintb;
+	u8 alt_gaintb;
+	int lna1_lna2_delta;
+	u8 div_group;
 };
 
 /**
@@ -638,10 +632,12 @@
 				   u32 numDelims);
 	void (*set11n_aggr_last)(struct ath_hw *ah, void *ds);
 	void (*clr11n_aggr)(struct ath_hw *ah, void *ds);
-	void (*set11n_burstduration)(struct ath_hw *ah, void *ds,
-				     u32 burstDuration);
-	void (*set11n_virtualmorefrag)(struct ath_hw *ah, void *ds,
-				       u32 vmf);
+	void (*set_clrdmask)(struct ath_hw *ah, void *ds, bool val);
+	void (*antdiv_comb_conf_get)(struct ath_hw *ah,
+			struct ath_hw_antcomb_conf *antconf);
+	void (*antdiv_comb_conf_set)(struct ath_hw *ah,
+			struct ath_hw_antcomb_conf *antconf);
+
 };
 
 struct ath_nf_limits {
@@ -655,6 +651,8 @@
 #define AH_UNPLUGGED    0x2 /* The card has been physically removed. */
 
 struct ath_hw {
+	struct ath_ops reg_ops;
+
 	struct ieee80211_hw *hw;
 	struct ath_common common;
 	struct ath9k_hw_version hw_version;
@@ -784,6 +782,8 @@
 
 	/* Bluetooth coexistance */
 	struct ath_btcoex_hw btcoex_hw;
+	u32 bt_coex_bt_weight[AR9300_NUM_BT_WEIGHTS];
+	u32 bt_coex_wlan_weight[AR9300_NUM_WLAN_WEIGHTS];
 
 	u32 intr_txqs;
 	u8 txchainmask;
@@ -794,7 +794,9 @@
 	u32 originalGain[22];
 	int initPDADC;
 	int PDADCdelta;
-	u8 led_pin;
+	int led_pin;
+	u32 gpio_mask;
+	u32 gpio_val;
 
 	struct ar5416IniArray iniModes;
 	struct ar5416IniArray iniCommon;
@@ -810,6 +812,7 @@
 	struct ar5416IniArray iniPcieSerdes;
 	struct ar5416IniArray iniPcieSerdesLowPower;
 	struct ar5416IniArray iniModesAdditional;
+	struct ar5416IniArray iniModesAdditional_40M;
 	struct ar5416IniArray iniModesRxGain;
 	struct ar5416IniArray iniModesTxGain;
 	struct ar5416IniArray iniModes_9271_1_0_only;
@@ -839,6 +842,7 @@
 
 	u32 bb_watchdog_last_status;
 	u32 bb_watchdog_timeout_ms; /* in ms, 0 to disable */
+	u8 bb_hang_rx_ofdm; /* true if bb hang due to rx_ofdm */
 
 	unsigned int paprd_target_power;
 	unsigned int paprd_training_power;
@@ -856,6 +860,16 @@
 
 	/* Enterprise mode cap */
 	u32 ent_mode;
+
+	bool is_clk_25mhz;
+};
+
+struct ath_bus_ops {
+	enum ath_bus_type ath_bus_type;
+	void (*read_cachesize)(struct ath_common *common, int *csz);
+	bool (*eeprom_read)(struct ath_common *common, u32 off, u16 *data);
+	void (*bt_coex_prep)(struct ath_common *common);
+	void (*extn_synch_en)(struct ath_common *common);
 };
 
 static inline struct ath_common *ath9k_hw_common(struct ath_hw *ah)
@@ -900,15 +914,12 @@
 void ath9k_hw_set_gpio(struct ath_hw *ah, u32 gpio, u32 val);
 u32 ath9k_hw_getdefantenna(struct ath_hw *ah);
 void ath9k_hw_setantenna(struct ath_hw *ah, u32 antenna);
-void ath9k_hw_antdiv_comb_conf_get(struct ath_hw *ah,
-				   struct ath_hw_antcomb_conf *antconf);
-void ath9k_hw_antdiv_comb_conf_set(struct ath_hw *ah,
-				   struct ath_hw_antcomb_conf *antconf);
 
 /* General Operation */
 bool ath9k_hw_wait(struct ath_hw *ah, u32 reg, u32 mask, u32 val, u32 timeout);
+void ath9k_hw_write_array(struct ath_hw *ah, struct ar5416IniArray *array,
+			  int column, unsigned int *writecnt);
 u32 ath9k_hw_reverse_bits(u32 val, u32 n);
-bool ath9k_get_channel_edges(struct ath_hw *ah, u16 flags, u16 *low, u16 *high);
 u16 ath9k_hw_computetxtime(struct ath_hw *ah,
 			   u8 phy, int kbps,
 			   u32 frameLen, u16 rateix, bool shortPreamble);
@@ -924,12 +935,13 @@
 void ath9k_hw_setmcastfilter(struct ath_hw *ah, u32 filter0, u32 filter1);
 void ath9k_hw_setbssidmask(struct ath_hw *ah);
 void ath9k_hw_write_associd(struct ath_hw *ah);
+u32 ath9k_hw_gettsf32(struct ath_hw *ah);
 u64 ath9k_hw_gettsf64(struct ath_hw *ah);
 void ath9k_hw_settsf64(struct ath_hw *ah, u64 tsf64);
 void ath9k_hw_reset_tsf(struct ath_hw *ah);
 void ath9k_hw_set_tsfadjust(struct ath_hw *ah, u32 setting);
 void ath9k_hw_init_global_settings(struct ath_hw *ah);
-unsigned long ar9003_get_pll_sqsum_dvc(struct ath_hw *ah);
+u32 ar9003_get_pll_sqsum_dvc(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,
@@ -979,6 +991,7 @@
 void ar9003_hw_bb_watchdog_config(struct ath_hw *ah);
 void ar9003_hw_bb_watchdog_read(struct ath_hw *ah);
 void ar9003_hw_bb_watchdog_dbg_info(struct ath_hw *ah);
+void ar9003_hw_disable_phy_restart(struct ath_hw *ah);
 void ar9003_paprd_enable(struct ath_hw *ah, bool val);
 void ar9003_paprd_populate_single_table(struct ath_hw *ah,
 					struct ath9k_hw_cal_data *caldata,
diff -druN linux-2.6.39-libre/drivers/net/wireless/ath/ath9k/hw-ops.h linux-3.0-rc7-libre/drivers/net/wireless/ath/ath9k/hw-ops.h
--- linux-2.6.39-libre/drivers/net/wireless/ath/ath9k/hw-ops.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/ath/ath9k/hw-ops.h	2011-07-11 19:51:52.000000000 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010 Atheros Communications Inc.
+ * Copyright (c) 2010-2011 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
@@ -116,16 +116,21 @@
 	ath9k_hw_ops(ah)->clr11n_aggr(ah, ds);
 }
 
-static inline void ath9k_hw_set11n_burstduration(struct ath_hw *ah, void *ds,
-						 u32 burstDuration)
+static inline void ath9k_hw_set_clrdmask(struct ath_hw *ah, void *ds, bool val)
 {
-	ath9k_hw_ops(ah)->set11n_burstduration(ah, ds, burstDuration);
+	ath9k_hw_ops(ah)->set_clrdmask(ah, ds, val);
 }
 
-static inline void ath9k_hw_set11n_virtualmorefrag(struct ath_hw *ah, void *ds,
-						   u32 vmf)
+static inline void ath9k_hw_antdiv_comb_conf_get(struct ath_hw *ah,
+		struct ath_hw_antcomb_conf *antconf)
 {
-	ath9k_hw_ops(ah)->set11n_virtualmorefrag(ah, ds, vmf);
+	ath9k_hw_ops(ah)->antdiv_comb_conf_get(ah, antconf);
+}
+
+static inline void ath9k_hw_antdiv_comb_conf_set(struct ath_hw *ah,
+		struct ath_hw_antcomb_conf *antconf)
+{
+	ath9k_hw_ops(ah)->antdiv_comb_conf_set(ah, antconf);
 }
 
 /* Private hardware call ops */
diff -druN linux-2.6.39-libre/drivers/net/wireless/ath/ath9k/init.c linux-3.0-rc7-libre/drivers/net/wireless/ath/ath9k/init.c
--- linux-2.6.39-libre/drivers/net/wireless/ath/ath9k/init.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/ath/ath9k/init.c	2011-07-11 19:51:52.000000000 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008-2009 Atheros Communications Inc.
+ * Copyright (c) 2008-2011 Atheros Communications Inc.
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
@@ -15,6 +15,7 @@
  */
 
 #include <linux/slab.h>
+#include <linux/ath9k_platform.h>
 
 #include "ath9k.h"
 
@@ -195,10 +196,27 @@
 	return val;
 }
 
-static const struct ath_ops ath9k_common_ops = {
-	.read = ath9k_ioread32,
-	.write = ath9k_iowrite32,
-};
+static unsigned int ath9k_reg_rmw(void *hw_priv, u32 reg_offset, u32 set, u32 clr)
+{
+	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;
+	unsigned long uninitialized_var(flags);
+	u32 val;
+
+	if (ah->config.serialize_regmode == SER_REG_MODE_ON)
+		spin_lock_irqsave(&sc->sc_serial_rw, flags);
+
+	val = ioread32(sc->mem + reg_offset);
+	val &= ~clr;
+	val |= set;
+	iowrite32(val, sc->mem + reg_offset);
+
+	if (ah->config.serialize_regmode == SER_REG_MODE_ON)
+		spin_unlock_irqrestore(&sc->sc_serial_rw, flags);
+
+	return val;
+}
 
 /**************************/
 /*     Initialization     */
@@ -389,13 +407,7 @@
 	int i = 0;
 
 	/* Get the hardware key cache size. */
-	common->keymax = sc->sc_ah->caps.keycache_size;
-	if (common->keymax > ATH_KEYMAX) {
-		ath_dbg(common, ATH_DBG_ANY,
-			"Warning, using only %u entries in %u key cache\n",
-			ATH_KEYMAX, common->keymax);
-		common->keymax = ATH_KEYMAX;
-	}
+	common->keymax = AR_KEYTABLE_SIZE;
 
 	/*
 	 * Reset the key cache since some parts do not
@@ -537,6 +549,7 @@
 static int ath9k_init_softc(u16 devid, struct ath_softc *sc, u16 subsysid,
 			    const struct ath_bus_ops *bus_ops)
 {
+	struct ath9k_platform_data *pdata = sc->dev->platform_data;
 	struct ath_hw *ah = NULL;
 	struct ath_common *common;
 	int ret = 0, i;
@@ -549,13 +562,23 @@
 	ah->hw = sc->hw;
 	ah->hw_version.devid = devid;
 	ah->hw_version.subsysid = subsysid;
+	ah->reg_ops.read = ath9k_ioread32;
+	ah->reg_ops.write = ath9k_iowrite32;
+	ah->reg_ops.rmw = ath9k_reg_rmw;
 	sc->sc_ah = ah;
 
-	if (!sc->dev->platform_data)
+	if (!pdata) {
 		ah->ah_flags |= AH_USE_EEPROM;
+		sc->sc_ah->led_pin = -1;
+	} else {
+		sc->sc_ah->gpio_mask = pdata->gpio_mask;
+		sc->sc_ah->gpio_val = pdata->gpio_val;
+		sc->sc_ah->led_pin = pdata->led_pin;
+		ah->is_clk_25mhz = pdata->is_clk_25mhz;
+	}
 
 	common = ath9k_hw_common(ah);
-	common->ops = &ath9k_common_ops;
+	common->ops = &ah->reg_ops;
 	common->bus_ops = bus_ops;
 	common->ah = ah;
 	common->hw = sc->hw;
@@ -587,6 +610,9 @@
 	if (ret)
 		goto err_hw;
 
+	if (pdata && pdata->macaddr)
+		memcpy(common->macaddr, pdata->macaddr, ETH_ALEN);
+
 	ret = ath9k_init_queues(sc);
 	if (ret)
 		goto err_queues;
@@ -679,6 +705,8 @@
 	if (AR_SREV_5416(sc->sc_ah))
 		hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT;
 
+	hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN;
+
 	hw->queues = 4;
 	hw->max_rates = 4;
 	hw->channel_change_time = 5000;
@@ -773,6 +801,7 @@
 
 	INIT_WORK(&sc->hw_check_work, ath_hw_check);
 	INIT_WORK(&sc->paprd_work, ath_paprd_calibrate);
+	INIT_DELAYED_WORK(&sc->hw_pll_work, ath_hw_pll_work);
 	sc->last_rssi = ATH_RSSI_DUMMY_MARKER;
 
 	ath_init_leds(sc);
diff -druN linux-2.6.39-libre/drivers/net/wireless/ath/ath9k/Kconfig linux-3.0-rc7-libre/drivers/net/wireless/ath/ath9k/Kconfig
--- linux-2.6.39-libre/drivers/net/wireless/ath/ath9k/Kconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/ath/ath9k/Kconfig	2011-07-11 19:51:52.000000000 -0400
@@ -5,7 +5,7 @@
 
 config ATH9K
 	tristate "Atheros 802.11n wireless cards support"
-	depends on PCI && MAC80211
+	depends on MAC80211
 	select ATH9K_HW
 	select MAC80211_LEDS
 	select LEDS_CLASS
@@ -23,6 +23,24 @@
 
 	  If you choose to build a module, it'll be called ath9k.
 
+config ATH9K_PCI
+	bool "Atheros ath9k PCI/PCIe bus support"
+	depends on ATH9K && PCI
+	---help---
+	  This option enables the PCI bus support in ath9k.
+
+	  Say Y, if you have a compatible PCI/PCIe wireless card.
+
+config ATH9K_AHB
+	bool "Atheros ath9k AHB bus support"
+	depends on ATH9K
+	default n
+	---help---
+	  This option enables the AHB bus support in ath9k.
+
+	  Say Y, if you have a SoC with a compatible built-in
+	  wireless MAC. Say N if unsure.
+
 config ATH9K_DEBUGFS
 	bool "Atheros ath9k debugging"
 	depends on ATH9K && DEBUG_FS
diff -druN linux-2.6.39-libre/drivers/net/wireless/ath/ath9k/mac.c linux-3.0-rc7-libre/drivers/net/wireless/ath/ath9k/mac.c
--- linux-2.6.39-libre/drivers/net/wireless/ath/ath9k/mac.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/ath/ath9k/mac.c	2011-07-11 19:51:52.000000000 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008-2009 Atheros Communications Inc.
+ * Copyright (c) 2008-2011 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
@@ -209,15 +209,8 @@
 {
 	u32 cw;
 	struct ath_common *common = ath9k_hw_common(ah);
-	struct ath9k_hw_capabilities *pCap = &ah->caps;
 	struct ath9k_tx_queue_info *qi;
 
-	if (q >= pCap->total_queues) {
-		ath_dbg(common, ATH_DBG_QUEUE,
-			"Set TXQ properties, invalid queue: %u\n", q);
-		return false;
-	}
-
 	qi = &ah->txq[q];
 	if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {
 		ath_dbg(common, ATH_DBG_QUEUE,
@@ -280,15 +273,8 @@
 			    struct ath9k_tx_queue_info *qinfo)
 {
 	struct ath_common *common = ath9k_hw_common(ah);
-	struct ath9k_hw_capabilities *pCap = &ah->caps;
 	struct ath9k_tx_queue_info *qi;
 
-	if (q >= pCap->total_queues) {
-		ath_dbg(common, ATH_DBG_QUEUE,
-			"Get TXQ properties, invalid queue: %u\n", q);
-		return false;
-	}
-
 	qi = &ah->txq[q];
 	if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {
 		ath_dbg(common, ATH_DBG_QUEUE,
@@ -320,28 +306,27 @@
 {
 	struct ath_common *common = ath9k_hw_common(ah);
 	struct ath9k_tx_queue_info *qi;
-	struct ath9k_hw_capabilities *pCap = &ah->caps;
 	int q;
 
 	switch (type) {
 	case ATH9K_TX_QUEUE_BEACON:
-		q = pCap->total_queues - 1;
+		q = ATH9K_NUM_TX_QUEUES - 1;
 		break;
 	case ATH9K_TX_QUEUE_CAB:
-		q = pCap->total_queues - 2;
+		q = ATH9K_NUM_TX_QUEUES - 2;
 		break;
 	case ATH9K_TX_QUEUE_PSPOLL:
 		q = 1;
 		break;
 	case ATH9K_TX_QUEUE_UAPSD:
-		q = pCap->total_queues - 3;
+		q = ATH9K_NUM_TX_QUEUES - 3;
 		break;
 	case ATH9K_TX_QUEUE_DATA:
-		for (q = 0; q < pCap->total_queues; q++)
+		for (q = 0; q < ATH9K_NUM_TX_QUEUES; q++)
 			if (ah->txq[q].tqi_type ==
 			    ATH9K_TX_QUEUE_INACTIVE)
 				break;
-		if (q == pCap->total_queues) {
+		if (q == ATH9K_NUM_TX_QUEUES) {
 			ath_err(common, "No available TX queue\n");
 			return -1;
 		}
@@ -382,15 +367,9 @@
 
 bool ath9k_hw_releasetxqueue(struct ath_hw *ah, u32 q)
 {
-	struct ath9k_hw_capabilities *pCap = &ah->caps;
 	struct ath_common *common = ath9k_hw_common(ah);
 	struct ath9k_tx_queue_info *qi;
 
-	if (q >= pCap->total_queues) {
-		ath_dbg(common, ATH_DBG_QUEUE,
-			"Release TXQ, invalid queue: %u\n", q);
-		return false;
-	}
 	qi = &ah->txq[q];
 	if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {
 		ath_dbg(common, ATH_DBG_QUEUE,
@@ -414,18 +393,11 @@
 
 bool ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q)
 {
-	struct ath9k_hw_capabilities *pCap = &ah->caps;
 	struct ath_common *common = ath9k_hw_common(ah);
 	struct ath9k_channel *chan = ah->curchan;
 	struct ath9k_tx_queue_info *qi;
 	u32 cwMin, chanCwMin, value;
 
-	if (q >= pCap->total_queues) {
-		ath_dbg(common, ATH_DBG_QUEUE,
-			"Reset TXQ, invalid queue: %u\n", q);
-		return false;
-	}
-
 	qi = &ah->txq[q];
 	if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {
 		ath_dbg(common, ATH_DBG_QUEUE,
@@ -458,17 +430,21 @@
 		  SM(qi->tqi_shretry, AR_D_RETRY_LIMIT_FR_SH));
 
 	REG_WRITE(ah, AR_QMISC(q), AR_Q_MISC_DCU_EARLY_TERM_REQ);
-	REG_WRITE(ah, AR_DMISC(q),
-		  AR_D_MISC_CW_BKOFF_EN | AR_D_MISC_FRAG_WAIT_EN | 0x2);
+
+	if (AR_SREV_9340(ah))
+		REG_WRITE(ah, AR_DMISC(q),
+			  AR_D_MISC_CW_BKOFF_EN | AR_D_MISC_FRAG_WAIT_EN | 0x1);
+	else
+		REG_WRITE(ah, AR_DMISC(q),
+			  AR_D_MISC_CW_BKOFF_EN | AR_D_MISC_FRAG_WAIT_EN | 0x2);
 
 	if (qi->tqi_cbrPeriod) {
 		REG_WRITE(ah, AR_QCBRCFG(q),
 			  SM(qi->tqi_cbrPeriod, AR_Q_CBRCFG_INTERVAL) |
 			  SM(qi->tqi_cbrOverflowLimit, AR_Q_CBRCFG_OVF_THRESH));
-		REG_WRITE(ah, AR_QMISC(q),
-			  REG_READ(ah, AR_QMISC(q)) | AR_Q_MISC_FSP_CBR |
-			  (qi->tqi_cbrOverflowLimit ?
-			   AR_Q_MISC_CBR_EXP_CNTR_LIMIT_EN : 0));
+		REG_SET_BIT(ah, AR_QMISC(q), AR_Q_MISC_FSP_CBR |
+			    (qi->tqi_cbrOverflowLimit ?
+			     AR_Q_MISC_CBR_EXP_CNTR_LIMIT_EN : 0));
 	}
 	if (qi->tqi_readyTime && (qi->tqi_type != ATH9K_TX_QUEUE_CAB)) {
 		REG_WRITE(ah, AR_QRDYTIMECFG(q),
@@ -481,40 +457,31 @@
 		  (qi->tqi_burstTime ? AR_D_CHNTIME_EN : 0));
 
 	if (qi->tqi_burstTime
-	    && (qi->tqi_qflags & TXQ_FLAG_RDYTIME_EXP_POLICY_ENABLE)) {
-		REG_WRITE(ah, AR_QMISC(q),
-			  REG_READ(ah, AR_QMISC(q)) |
-			  AR_Q_MISC_RDYTIME_EXP_POLICY);
-
-	}
+	    && (qi->tqi_qflags & TXQ_FLAG_RDYTIME_EXP_POLICY_ENABLE))
+		REG_SET_BIT(ah, AR_QMISC(q), AR_Q_MISC_RDYTIME_EXP_POLICY);
 
-	if (qi->tqi_qflags & TXQ_FLAG_BACKOFF_DISABLE) {
-		REG_WRITE(ah, AR_DMISC(q),
-			  REG_READ(ah, AR_DMISC(q)) |
-			  AR_D_MISC_POST_FR_BKOFF_DIS);
-	}
+	if (qi->tqi_qflags & TXQ_FLAG_BACKOFF_DISABLE)
+		REG_SET_BIT(ah, AR_DMISC(q), AR_D_MISC_POST_FR_BKOFF_DIS);
 
 	REGWRITE_BUFFER_FLUSH(ah);
 
-	if (qi->tqi_qflags & TXQ_FLAG_FRAG_BURST_BACKOFF_ENABLE) {
-		REG_WRITE(ah, AR_DMISC(q),
-			  REG_READ(ah, AR_DMISC(q)) |
-			  AR_D_MISC_FRAG_BKOFF_EN);
-	}
+	if (qi->tqi_qflags & TXQ_FLAG_FRAG_BURST_BACKOFF_ENABLE)
+		REG_SET_BIT(ah, AR_DMISC(q), AR_D_MISC_FRAG_BKOFF_EN);
+
 	switch (qi->tqi_type) {
 	case ATH9K_TX_QUEUE_BEACON:
 		ENABLE_REGWRITE_BUFFER(ah);
 
-		REG_WRITE(ah, AR_QMISC(q), REG_READ(ah, AR_QMISC(q))
-			  | AR_Q_MISC_FSP_DBA_GATED
-			  | AR_Q_MISC_BEACON_USE
-			  | AR_Q_MISC_CBR_INCR_DIS1);
+		REG_SET_BIT(ah, AR_QMISC(q),
+			    AR_Q_MISC_FSP_DBA_GATED
+			    | AR_Q_MISC_BEACON_USE
+			    | AR_Q_MISC_CBR_INCR_DIS1);
 
-		REG_WRITE(ah, AR_DMISC(q), REG_READ(ah, AR_DMISC(q))
-			  | (AR_D_MISC_ARB_LOCKOUT_CNTRL_GLOBAL <<
+		REG_SET_BIT(ah, AR_DMISC(q),
+			    (AR_D_MISC_ARB_LOCKOUT_CNTRL_GLOBAL <<
 			     AR_D_MISC_ARB_LOCKOUT_CNTRL_S)
-			  | AR_D_MISC_BEACON_USE
-			  | AR_D_MISC_POST_FR_BKOFF_DIS);
+			    | AR_D_MISC_BEACON_USE
+			    | AR_D_MISC_POST_FR_BKOFF_DIS);
 
 		REGWRITE_BUFFER_FLUSH(ah);
 
@@ -533,41 +500,38 @@
 	case ATH9K_TX_QUEUE_CAB:
 		ENABLE_REGWRITE_BUFFER(ah);
 
-		REG_WRITE(ah, AR_QMISC(q), REG_READ(ah, AR_QMISC(q))
-			  | AR_Q_MISC_FSP_DBA_GATED
-			  | AR_Q_MISC_CBR_INCR_DIS1
-			  | AR_Q_MISC_CBR_INCR_DIS0);
+		REG_SET_BIT(ah, AR_QMISC(q),
+			    AR_Q_MISC_FSP_DBA_GATED
+			    | AR_Q_MISC_CBR_INCR_DIS1
+			    | AR_Q_MISC_CBR_INCR_DIS0);
 		value = (qi->tqi_readyTime -
 			 (ah->config.sw_beacon_response_time -
 			  ah->config.dma_beacon_response_time) -
 			 ah->config.additional_swba_backoff) * 1024;
 		REG_WRITE(ah, AR_QRDYTIMECFG(q),
 			  value | AR_Q_RDYTIMECFG_EN);
-		REG_WRITE(ah, AR_DMISC(q), REG_READ(ah, AR_DMISC(q))
-			  | (AR_D_MISC_ARB_LOCKOUT_CNTRL_GLOBAL <<
+		REG_SET_BIT(ah, AR_DMISC(q),
+			    (AR_D_MISC_ARB_LOCKOUT_CNTRL_GLOBAL <<
 			     AR_D_MISC_ARB_LOCKOUT_CNTRL_S));
 
 		REGWRITE_BUFFER_FLUSH(ah);
 
 		break;
 	case ATH9K_TX_QUEUE_PSPOLL:
-		REG_WRITE(ah, AR_QMISC(q),
-			  REG_READ(ah, AR_QMISC(q)) | AR_Q_MISC_CBR_INCR_DIS1);
+		REG_SET_BIT(ah, AR_QMISC(q), AR_Q_MISC_CBR_INCR_DIS1);
 		break;
 	case ATH9K_TX_QUEUE_UAPSD:
-		REG_WRITE(ah, AR_DMISC(q), REG_READ(ah, AR_DMISC(q)) |
-			  AR_D_MISC_POST_FR_BKOFF_DIS);
+		REG_SET_BIT(ah, AR_DMISC(q), AR_D_MISC_POST_FR_BKOFF_DIS);
 		break;
 	default:
 		break;
 	}
 
 	if (qi->tqi_intFlags & ATH9K_TXQ_USE_LOCKOUT_BKOFF_DIS) {
-		REG_WRITE(ah, AR_DMISC(q),
-			  REG_READ(ah, AR_DMISC(q)) |
-			  SM(AR_D_MISC_ARB_LOCKOUT_CNTRL_GLOBAL,
-			     AR_D_MISC_ARB_LOCKOUT_CNTRL) |
-			  AR_D_MISC_POST_FR_BKOFF_DIS);
+		REG_SET_BIT(ah, AR_DMISC(q),
+			    SM(AR_D_MISC_ARB_LOCKOUT_CNTRL_GLOBAL,
+			       AR_D_MISC_ARB_LOCKOUT_CNTRL) |
+			    AR_D_MISC_POST_FR_BKOFF_DIS);
 	}
 
 	if (AR_SREV_9300_20_OR_LATER(ah))
@@ -754,7 +718,6 @@
 bool ath9k_hw_stopdmarecv(struct ath_hw *ah, bool *reset)
 {
 #define AH_RX_STOP_DMA_TIMEOUT 10000   /* usec */
-#define AH_RX_TIME_QUANTUM     100     /* usec */
 	struct ath_common *common = ath9k_hw_common(ah);
 	u32 mac_status, last_mac_status = 0;
 	int i;
@@ -797,7 +760,6 @@
 		return true;
 	}
 
-#undef AH_RX_TIME_QUANTUM
 #undef AH_RX_STOP_DMA_TIMEOUT
 }
 EXPORT_SYMBOL(ath9k_hw_stopdmarecv);
@@ -855,10 +817,14 @@
 void ath9k_hw_enable_interrupts(struct ath_hw *ah)
 {
 	struct ath_common *common = ath9k_hw_common(ah);
+	u32 sync_default = AR_INTR_SYNC_DEFAULT;
 
 	if (!(ah->imask & ATH9K_INT_GLOBAL))
 		return;
 
+	if (AR_SREV_9340(ah))
+		sync_default &= ~AR_INTR_SYNC_HOST1_FATAL;
+
 	ath_dbg(common, ATH_DBG_INTERRUPT, "enable IER\n");
 	REG_WRITE(ah, AR_IER, AR_IER_ENABLE);
 	if (!AR_SREV_9100(ah)) {
@@ -867,10 +833,8 @@
 		REG_WRITE(ah, AR_INTR_ASYNC_MASK, AR_INTR_MAC_IRQ);
 
 
-		REG_WRITE(ah, AR_INTR_SYNC_ENABLE,
-			  AR_INTR_SYNC_DEFAULT);
-		REG_WRITE(ah, AR_INTR_SYNC_MASK,
-			  AR_INTR_SYNC_DEFAULT);
+		REG_WRITE(ah, AR_INTR_SYNC_ENABLE, sync_default);
+		REG_WRITE(ah, AR_INTR_SYNC_MASK, sync_default);
 	}
 	ath_dbg(common, ATH_DBG_INTERRUPT, "AR_IMR 0x%x IER 0x%x\n",
 		REG_READ(ah, AR_IMR), REG_READ(ah, AR_IER));
@@ -926,6 +890,9 @@
 			mask |= AR_IMR_GENTMR;
 	}
 
+	if (ints & ATH9K_INT_GENTIMER)
+		mask |= AR_IMR_GENTMR;
+
 	if (ints & (ATH9K_INT_BMISC)) {
 		mask |= AR_IMR_BCNMISC;
 		if (ints & ATH9K_INT_TIM)
diff -druN linux-2.6.39-libre/drivers/net/wireless/ath/ath9k/mac.h linux-3.0-rc7-libre/drivers/net/wireless/ath/ath9k/mac.h
--- linux-2.6.39-libre/drivers/net/wireless/ath/ath9k/mac.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/ath/ath9k/mac.h	2011-07-11 19:51:52.000000000 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008-2009 Atheros Communications Inc.
+ * Copyright (c) 2008-2011 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
@@ -239,7 +239,6 @@
 	void *ds_vdata;
 } __packed __aligned(4);
 
-#define ATH9K_TXDESC_CLRDMASK		0x0001
 #define ATH9K_TXDESC_NOACK		0x0002
 #define ATH9K_TXDESC_RTSENA		0x0004
 #define ATH9K_TXDESC_CTSENA		0x0008
diff -druN linux-2.6.39-libre/drivers/net/wireless/ath/ath9k/main.c linux-3.0-rc7-libre/drivers/net/wireless/ath/ath9k/main.c
--- linux-2.6.39-libre/drivers/net/wireless/ath/ath9k/main.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/ath/ath9k/main.c	2011-07-11 19:51:52.000000000 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008-2009 Atheros Communications Inc.
+ * Copyright (c) 2008-2011 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
@@ -299,7 +299,7 @@
 
 	if (!(sc->sc_flags & (SC_OP_OFFCHANNEL))) {
 		if (sc->sc_flags & SC_OP_BEACONS)
-			ath_beacon_config(sc, NULL);
+			ath_set_beacon(sc);
 		ieee80211_queue_delayed_work(sc->hw, &sc->tx_complete_work, 0);
 		ieee80211_queue_delayed_work(sc->hw, &sc->hw_pll_work, HZ/2);
 		ath_start_ani(common);
@@ -624,6 +624,43 @@
 	ath9k_ps_restore(sc);
 }
 
+static void ath_hw_pll_rx_hang_check(struct ath_softc *sc, u32 pll_sqsum)
+{
+	static int count;
+	struct ath_common *common = ath9k_hw_common(sc->sc_ah);
+
+	if (pll_sqsum >= 0x40000) {
+		count++;
+		if (count == 3) {
+			/* Rx is hung for more than 500ms. Reset it */
+			ath_dbg(common, ATH_DBG_RESET,
+				"Possible RX hang, resetting");
+			ath_reset(sc, true);
+			count = 0;
+		}
+	} else
+		count = 0;
+}
+
+void ath_hw_pll_work(struct work_struct *work)
+{
+	struct ath_softc *sc = container_of(work, struct ath_softc,
+					    hw_pll_work.work);
+	u32 pll_sqsum;
+
+	if (AR_SREV_9485(sc->sc_ah)) {
+
+		ath9k_ps_wakeup(sc);
+		pll_sqsum = ar9003_get_pll_sqsum_dvc(sc->sc_ah);
+		ath9k_ps_restore(sc);
+
+		ath_hw_pll_rx_hang_check(sc, pll_sqsum);
+
+		ieee80211_queue_delayed_work(sc->hw, &sc->hw_pll_work, HZ/5);
+	}
+}
+
+
 void ath9k_tasklet(unsigned long data)
 {
 	struct ath_softc *sc = (struct ath_softc *)data;
@@ -633,7 +670,8 @@
 	u32 status = sc->intrstatus;
 	u32 rxmask;
 
-	if (status & ATH9K_INT_FATAL) {
+	if ((status & ATH9K_INT_FATAL) ||
+	    (status & ATH9K_INT_BB_WATCHDOG)) {
 		ath_reset(sc, true);
 		return;
 	}
@@ -652,6 +690,17 @@
 	    !ath9k_hw_check_alive(ah))
 		ieee80211_queue_work(sc->hw, &sc->hw_check_work);
 
+	if ((status & ATH9K_INT_TSFOOR) && sc->ps_enabled) {
+		/*
+		 * TSF sync does not look correct; remain awake to sync with
+		 * the next Beacon.
+		 */
+		ath_dbg(common, ATH_DBG_PS,
+			"TSFOOR - Sync with next Beacon\n");
+		sc->ps_flags |= PS_WAIT_FOR_BEACON | PS_BEACON_SYNC |
+				PS_TSFOOR_SYNC;
+	}
+
 	if (ah->caps.hw_caps & ATH9K_HW_CAP_EDMA)
 		rxmask = (ATH9K_INT_RXHP | ATH9K_INT_RXLP | ATH9K_INT_RXEOL |
 			  ATH9K_INT_RXORN);
@@ -674,16 +723,6 @@
 			ath_tx_tasklet(sc);
 	}
 
-	if ((status & ATH9K_INT_TSFOOR) && sc->ps_enabled) {
-		/*
-		 * TSF sync does not look correct; remain awake to sync with
-		 * the next Beacon.
-		 */
-		ath_dbg(common, ATH_DBG_PS,
-			"TSFOOR - Sync with next Beacon\n");
-		sc->ps_flags |= PS_WAIT_FOR_BEACON | PS_BEACON_SYNC;
-	}
-
 	if (ah->btcoex_hw.scheme == ATH_BTCOEX_CFG_3WIRE)
 		if (status & ATH9K_INT_GENTIMER)
 			ath_gen_timer_isr(sc->sc_ah);
@@ -699,6 +738,7 @@
 {
 #define SCHED_INTR (				\
 		ATH9K_INT_FATAL |		\
+		ATH9K_INT_BB_WATCHDOG |		\
 		ATH9K_INT_RXORN |		\
 		ATH9K_INT_RXEOL |		\
 		ATH9K_INT_RX |			\
@@ -828,48 +868,6 @@
 #undef SCHED_INTR
 }
 
-static void ath9k_bss_assoc_info(struct ath_softc *sc,
-				 struct ieee80211_hw *hw,
-				 struct ieee80211_vif *vif,
-				 struct ieee80211_bss_conf *bss_conf)
-{
-	struct ath_hw *ah = sc->sc_ah;
-	struct ath_common *common = ath9k_hw_common(ah);
-
-	if (bss_conf->assoc) {
-		ath_dbg(common, ATH_DBG_CONFIG,
-			"Bss Info ASSOC %d, bssid: %pM\n",
-			bss_conf->aid, common->curbssid);
-
-		/* New association, store aid */
-		common->curaid = bss_conf->aid;
-		ath9k_hw_write_associd(ah);
-
-		/*
-		 * Request a re-configuration of Beacon related timers
-		 * on the receipt of the first Beacon frame (i.e.,
-		 * after time sync with the AP).
-		 */
-		sc->ps_flags |= PS_BEACON_SYNC;
-
-		/* Configure the beacon */
-		ath_beacon_config(sc, vif);
-
-		/* Reset rssi stats */
-		sc->last_rssi = ATH_RSSI_DUMMY_MARKER;
-		sc->sc_ah->stats.avgbrssi = ATH_RSSI_DUMMY_MARKER;
-
-		sc->sc_flags |= SC_OP_ANI_RUN;
-		ath_start_ani(common);
-	} else {
-		ath_dbg(common, ATH_DBG_CONFIG, "Bss Info DISASSOC\n");
-		common->curaid = 0;
-		/* Stop ANI */
-		sc->sc_flags &= ~SC_OP_ANI_RUN;
-		del_timer_sync(&common->ani.timer);
-	}
-}
-
 void ath_radio_enable(struct ath_softc *sc, struct ieee80211_hw *hw)
 {
 	struct ath_hw *ah = sc->sc_ah;
@@ -899,7 +897,7 @@
 		goto out;
 	}
 	if (sc->sc_flags & SC_OP_BEACONS)
-		ath_beacon_config(sc, NULL);	/* restart beacons */
+		ath_set_beacon(sc);	/* restart beacons */
 
 	/* Re-Enable  interrupts */
 	ath9k_hw_set_interrupts(ah, ah->imask);
@@ -1006,7 +1004,7 @@
 			       sc->config.txpowlimit, &sc->curtxpow);
 
 	if ((sc->sc_flags & SC_OP_BEACONS) || !(sc->sc_flags & (SC_OP_OFFCHANNEL)))
-		ath_beacon_config(sc, NULL);	/* restart beacons */
+		ath_set_beacon(sc);	/* restart beacons */
 
 	ath9k_hw_set_interrupts(ah, ah->imask);
 
@@ -1389,7 +1387,9 @@
 		ath9k_hw_set_tsfadjust(ah, 0);
 		sc->sc_flags &= ~SC_OP_TSF_RESET;
 
-		if (iter_data.nwds + iter_data.nmeshes)
+		if (iter_data.nmeshes)
+			ah->opmode = NL80211_IFTYPE_MESH_POINT;
+		else if (iter_data.nwds)
 			ah->opmode = NL80211_IFTYPE_AP;
 		else if (iter_data.nadhocs)
 			ah->opmode = NL80211_IFTYPE_ADHOC;
@@ -1413,6 +1413,7 @@
 
 	/* Set up ANI */
 	if ((iter_data.naps + iter_data.nadhocs) > 0) {
+		sc->sc_ah->stats.avgbrssi = ATH_RSSI_DUMMY_MARKER;
 		sc->sc_flags |= SC_OP_ANI_RUN;
 		ath_start_ani(common);
 	} else {
@@ -1452,7 +1453,6 @@
 	struct ath_softc *sc = hw->priv;
 	struct ath_hw *ah = sc->sc_ah;
 	struct ath_common *common = ath9k_hw_common(ah);
-	struct ath_vif *avp = (void *)vif->drv_priv;
 	int ret = 0;
 
 	ath9k_ps_wakeup(sc);
@@ -1482,8 +1482,9 @@
 		}
 	}
 
-	if ((vif->type == NL80211_IFTYPE_ADHOC) &&
-	    sc->nvifs > 0) {
+	if ((ah->opmode == NL80211_IFTYPE_ADHOC) ||
+	    ((vif->type == NL80211_IFTYPE_ADHOC) &&
+	     sc->nvifs > 0)) {
 		ath_err(common, "Cannot create ADHOC interface when other"
 			" interfaces already exist.\n");
 		ret = -EINVAL;
@@ -1493,10 +1494,6 @@
 	ath_dbg(common, ATH_DBG_CONFIG,
 		"Attach a VIF of type: %d\n", vif->type);
 
-	/* Set the VIF opmode */
-	avp->av_opmode = vif->type;
-	avp->av_bslot = -1;
-
 	sc->nvifs++;
 
 	ath9k_do_vif_add_setup(hw, vif);
@@ -1782,23 +1779,68 @@
 			 struct ieee80211_sta *sta)
 {
 	struct ath_softc *sc = hw->priv;
+	struct ath_common *common = ath9k_hw_common(sc->sc_ah);
+	struct ath_node *an = (struct ath_node *) sta->drv_priv;
+	struct ieee80211_key_conf ps_key = { };
 
 	ath_node_attach(sc, sta);
 
+	if (vif->type != NL80211_IFTYPE_AP &&
+	    vif->type != NL80211_IFTYPE_AP_VLAN)
+		return 0;
+
+	an->ps_key = ath_key_config(common, vif, sta, &ps_key);
+
 	return 0;
 }
 
+static void ath9k_del_ps_key(struct ath_softc *sc,
+			     struct ieee80211_vif *vif,
+			     struct ieee80211_sta *sta)
+{
+	struct ath_common *common = ath9k_hw_common(sc->sc_ah);
+	struct ath_node *an = (struct ath_node *) sta->drv_priv;
+	struct ieee80211_key_conf ps_key = { .hw_key_idx = an->ps_key };
+
+	if (!an->ps_key)
+	    return;
+
+	ath_key_delete(common, &ps_key);
+}
+
 static int ath9k_sta_remove(struct ieee80211_hw *hw,
 			    struct ieee80211_vif *vif,
 			    struct ieee80211_sta *sta)
 {
 	struct ath_softc *sc = hw->priv;
 
+	ath9k_del_ps_key(sc, vif, sta);
 	ath_node_detach(sc, sta);
 
 	return 0;
 }
 
+static void ath9k_sta_notify(struct ieee80211_hw *hw,
+			 struct ieee80211_vif *vif,
+			 enum sta_notify_cmd cmd,
+			 struct ieee80211_sta *sta)
+{
+	struct ath_softc *sc = hw->priv;
+	struct ath_node *an = (struct ath_node *) sta->drv_priv;
+
+	switch (cmd) {
+	case STA_NOTIFY_SLEEP:
+		an->sleeping = true;
+		if (ath_tx_aggr_sleep(sc, an))
+			ieee80211_sta_set_tim(sta);
+		break;
+	case STA_NOTIFY_AWAKE:
+		an->sleeping = false;
+		ath_tx_aggr_wakeup(sc, an);
+		break;
+	}
+}
+
 static int ath9k_conf_tx(struct ieee80211_hw *hw, u16 queue,
 			 const struct ieee80211_tx_queue_params *params)
 {
@@ -1855,12 +1897,29 @@
 	if (ath9k_modparam_nohwcrypt)
 		return -ENOSPC;
 
+	if (vif->type == NL80211_IFTYPE_ADHOC &&
+	    (key->cipher == WLAN_CIPHER_SUITE_TKIP ||
+	     key->cipher == WLAN_CIPHER_SUITE_CCMP) &&
+	    !(key->flags & IEEE80211_KEY_FLAG_PAIRWISE)) {
+		/*
+		 * For now, disable hw crypto for the RSN IBSS group keys. This
+		 * could be optimized in the future to use a modified key cache
+		 * design to support per-STA RX GTK, but until that gets
+		 * implemented, use of software crypto for group addressed
+		 * frames is a acceptable to allow RSN IBSS to be used.
+		 */
+		return -EOPNOTSUPP;
+	}
+
 	mutex_lock(&sc->mutex);
 	ath9k_ps_wakeup(sc);
 	ath_dbg(common, ATH_DBG_CONFIG, "Set HW Key\n");
 
 	switch (cmd) {
 	case SET_KEY:
+		if (sta)
+			ath9k_del_ps_key(sc, vif, sta);
+
 		ret = ath_key_config(common, vif, sta, key);
 		if (ret >= 0) {
 			key->hw_key_idx = ret;
@@ -1886,6 +1945,92 @@
 
 	return ret;
 }
+static void ath9k_bss_iter(void *data, u8 *mac, struct ieee80211_vif *vif)
+{
+	struct ath_softc *sc = data;
+	struct ath_common *common = ath9k_hw_common(sc->sc_ah);
+	struct ieee80211_bss_conf *bss_conf = &vif->bss_conf;
+	struct ath_vif *avp = (void *)vif->drv_priv;
+
+	switch (sc->sc_ah->opmode) {
+	case NL80211_IFTYPE_ADHOC:
+		/* There can be only one vif available */
+		memcpy(common->curbssid, bss_conf->bssid, ETH_ALEN);
+		common->curaid = bss_conf->aid;
+		ath9k_hw_write_associd(sc->sc_ah);
+		/* configure beacon */
+		if (bss_conf->enable_beacon)
+			ath_beacon_config(sc, vif);
+		break;
+	case NL80211_IFTYPE_STATION:
+		/*
+		 * Skip iteration if primary station vif's bss info
+		 * was not changed
+		 */
+		if (sc->sc_flags & SC_OP_PRIM_STA_VIF)
+			break;
+
+		if (bss_conf->assoc) {
+			sc->sc_flags |= SC_OP_PRIM_STA_VIF;
+			avp->primary_sta_vif = true;
+			memcpy(common->curbssid, bss_conf->bssid, ETH_ALEN);
+			common->curaid = bss_conf->aid;
+			ath9k_hw_write_associd(sc->sc_ah);
+			ath_dbg(common, ATH_DBG_CONFIG,
+				"Bss Info ASSOC %d, bssid: %pM\n",
+				bss_conf->aid, common->curbssid);
+			ath_beacon_config(sc, vif);
+			/*
+			 * Request a re-configuration of Beacon related timers
+			 * on the receipt of the first Beacon frame (i.e.,
+			 * after time sync with the AP).
+			 */
+			sc->ps_flags |= PS_BEACON_SYNC | PS_WAIT_FOR_BEACON;
+			/* Reset rssi stats */
+			sc->last_rssi = ATH_RSSI_DUMMY_MARKER;
+			sc->sc_ah->stats.avgbrssi = ATH_RSSI_DUMMY_MARKER;
+
+			sc->sc_flags |= SC_OP_ANI_RUN;
+			ath_start_ani(common);
+		}
+		break;
+	default:
+		break;
+	}
+}
+
+static void ath9k_config_bss(struct ath_softc *sc, struct ieee80211_vif *vif)
+{
+	struct ath_common *common = ath9k_hw_common(sc->sc_ah);
+	struct ieee80211_bss_conf *bss_conf = &vif->bss_conf;
+	struct ath_vif *avp = (void *)vif->drv_priv;
+
+	/* Reconfigure bss info */
+	if (avp->primary_sta_vif && !bss_conf->assoc) {
+		ath_dbg(common, ATH_DBG_CONFIG,
+			"Bss Info DISASSOC %d, bssid %pM\n",
+			common->curaid, common->curbssid);
+		sc->sc_flags &= ~(SC_OP_PRIM_STA_VIF | SC_OP_BEACONS);
+		avp->primary_sta_vif = false;
+		memset(common->curbssid, 0, ETH_ALEN);
+		common->curaid = 0;
+	}
+
+	ieee80211_iterate_active_interfaces_atomic(
+			sc->hw, ath9k_bss_iter, sc);
+
+	/*
+	 * None of station vifs are associated.
+	 * Clear bssid & aid
+	 */
+	if ((sc->sc_ah->opmode == NL80211_IFTYPE_STATION) &&
+	    !(sc->sc_flags & SC_OP_PRIM_STA_VIF)) {
+		ath9k_hw_write_associd(sc->sc_ah);
+		/* Stop ANI */
+		sc->sc_flags &= ~SC_OP_ANI_RUN;
+		del_timer_sync(&common->ani.timer);
+	}
+}
 
 static void ath9k_bss_info_changed(struct ieee80211_hw *hw,
 				   struct ieee80211_vif *vif,
@@ -1893,7 +2038,6 @@
 				   u32 changed)
 {
 	struct ath_softc *sc = hw->priv;
-	struct ath_beacon_config *cur_conf = &sc->cur_beacon_conf;
 	struct ath_hw *ah = sc->sc_ah;
 	struct ath_common *common = ath9k_hw_common(ah);
 	struct ath_vif *avp = (void *)vif->drv_priv;
@@ -1904,20 +2048,10 @@
 	mutex_lock(&sc->mutex);
 
 	if (changed & BSS_CHANGED_BSSID) {
-		/* Set BSSID */
-		memcpy(common->curbssid, bss_conf->bssid, ETH_ALEN);
-		memcpy(avp->bssid, bss_conf->bssid, ETH_ALEN);
-		common->curaid = 0;
-		ath9k_hw_write_associd(ah);
-
-		/* Set aggregation protection mode parameters */
-		sc->config.ath_aggr_prot = 0;
+		ath9k_config_bss(sc, vif);
 
 		ath_dbg(common, ATH_DBG_CONFIG, "BSSID: %pM aid: 0x%x\n",
 			common->curbssid, common->curaid);
-
-		/* need to reconfigure the beacon */
-		sc->sc_flags &= ~SC_OP_BEACONS ;
 	}
 
 	/* Enable transmission of beacons (AP, IBSS, MESH) */
@@ -1958,7 +2092,6 @@
 	}
 
 	if (changed & BSS_CHANGED_BEACON_INT) {
-		cur_conf->beacon_interval = bss_conf->beacon_int;
 		/*
 		 * In case of AP mode, the HW TSF has to be reset
 		 * when the beacon interval changes.
@@ -1970,9 +2103,8 @@
 			if (!error)
 				ath_beacon_config(sc, vif);
 			ath9k_set_beaconing_status(sc, true);
-		} else {
+		} else
 			ath_beacon_config(sc, vif);
-		}
 	}
 
 	if (changed & BSS_CHANGED_ERP_PREAMBLE) {
@@ -1994,12 +2126,6 @@
 			sc->sc_flags &= ~SC_OP_PROTECT_ENABLE;
 	}
 
-	if (changed & BSS_CHANGED_ASSOC) {
-		ath_dbg(common, ATH_DBG_CONFIG, "BSS Changed ASSOC %d\n",
-			bss_conf->assoc);
-		ath9k_bss_assoc_info(sc, hw, vif, bss_conf);
-	}
-
 	mutex_unlock(&sc->mutex);
 	ath9k_ps_restore(sc);
 }
@@ -2145,10 +2271,9 @@
 	struct ath_common *common = ath9k_hw_common(ah);
 	int timeout = 200; /* ms */
 	int i, j;
+	bool drain_txq;
 
-	ath9k_ps_wakeup(sc);
 	mutex_lock(&sc->mutex);
-
 	cancel_delayed_work_sync(&sc->tx_complete_work);
 
 	if (sc->sc_flags & SC_OP_INVALID) {
@@ -2161,7 +2286,7 @@
 		timeout = 1;
 
 	for (j = 0; j < timeout; j++) {
-		int npend = 0;
+		bool npend = false;
 
 		if (j)
 			usleep_range(1000, 2000);
@@ -2170,22 +2295,82 @@
 			if (!ATH_TXQ_SETUP(sc, i))
 				continue;
 
-			npend += ath9k_has_pending_frames(sc, &sc->tx.txq[i]);
+			npend = ath9k_has_pending_frames(sc, &sc->tx.txq[i]);
+
+			if (npend)
+				break;
 		}
 
 		if (!npend)
 		    goto out;
 	}
 
-	if (!ath_drain_all_txq(sc, false))
+	ath9k_ps_wakeup(sc);
+	spin_lock_bh(&sc->sc_pcu_lock);
+	drain_txq = ath_drain_all_txq(sc, false);
+	spin_unlock_bh(&sc->sc_pcu_lock);
+	if (!drain_txq)
 		ath_reset(sc, false);
-
+	ath9k_ps_restore(sc);
 	ieee80211_wake_queues(hw);
 
 out:
 	ieee80211_queue_delayed_work(hw, &sc->tx_complete_work, 0);
 	mutex_unlock(&sc->mutex);
-	ath9k_ps_restore(sc);
+}
+
+static bool ath9k_tx_frames_pending(struct ieee80211_hw *hw)
+{
+	struct ath_softc *sc = hw->priv;
+	int i;
+
+	for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) {
+		if (!ATH_TXQ_SETUP(sc, i))
+			continue;
+
+		if (ath9k_has_pending_frames(sc, &sc->tx.txq[i]))
+			return true;
+	}
+	return false;
+}
+
+int ath9k_tx_last_beacon(struct ieee80211_hw *hw)
+{
+	struct ath_softc *sc = hw->priv;
+	struct ath_hw *ah = sc->sc_ah;
+	struct ieee80211_vif *vif;
+	struct ath_vif *avp;
+	struct ath_buf *bf;
+	struct ath_tx_status ts;
+	int status;
+
+	vif = sc->beacon.bslot[0];
+	if (!vif)
+		return 0;
+
+	avp = (void *)vif->drv_priv;
+	if (!avp->is_bslot_active)
+		return 0;
+
+	if (!sc->beacon.tx_processed) {
+		tasklet_disable(&sc->bcon_tasklet);
+
+		bf = avp->av_bcbuf;
+		if (!bf || !bf->bf_mpdu)
+			goto skip;
+
+		status = ath9k_hw_txprocdesc(ah, bf->bf_desc, &ts);
+		if (status == -EINPROGRESS)
+			goto skip;
+
+		sc->beacon.tx_processed = true;
+		sc->beacon.tx_last = !(ts.ts_status & ATH9K_TXERR_MASK);
+
+skip:
+		tasklet_enable(&sc->bcon_tasklet);
+	}
+
+	return sc->beacon.tx_last;
 }
 
 struct ieee80211_ops ath9k_ops = {
@@ -2199,6 +2384,7 @@
 	.configure_filter   = ath9k_configure_filter,
 	.sta_add	    = ath9k_sta_add,
 	.sta_remove	    = ath9k_sta_remove,
+	.sta_notify         = ath9k_sta_notify,
 	.conf_tx 	    = ath9k_conf_tx,
 	.bss_info_changed   = ath9k_bss_info_changed,
 	.set_key            = ath9k_set_key,
@@ -2210,4 +2396,6 @@
 	.rfkill_poll        = ath9k_rfkill_poll_state,
 	.set_coverage_class = ath9k_set_coverage_class,
 	.flush		    = ath9k_flush,
+	.tx_frames_pending  = ath9k_tx_frames_pending,
+	.tx_last_beacon = ath9k_tx_last_beacon,
 };
diff -druN linux-2.6.39-libre/drivers/net/wireless/ath/ath9k/Makefile linux-3.0-rc7-libre/drivers/net/wireless/ath/ath9k/Makefile
--- linux-2.6.39-libre/drivers/net/wireless/ath/ath9k/Makefile	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/ath/ath9k/Makefile	2011-07-11 19:51:52.000000000 -0400
@@ -6,8 +6,8 @@
 		xmit.o \
 
 ath9k-$(CONFIG_ATH9K_RATE_CONTROL) += rc.o
-ath9k-$(CONFIG_PCI) += pci.o
-ath9k-$(CONFIG_ATHEROS_AR71XX) += ahb.o
+ath9k-$(CONFIG_ATH9K_PCI) += pci.o
+ath9k-$(CONFIG_ATH9K_AHB) += ahb.o
 ath9k-$(CONFIG_ATH9K_DEBUGFS) += debug.o
 
 obj-$(CONFIG_ATH9K) += ath9k.o
@@ -48,4 +48,6 @@
 		htc_drv_init.o \
 		htc_drv_gpio.o
 
+ath9k_htc-$(CONFIG_ATH9K_HTC_DEBUGFS) += htc_drv_debug.o
+
 obj-$(CONFIG_ATH9K_HTC) += ath9k_htc.o
diff -druN linux-2.6.39-libre/drivers/net/wireless/ath/ath9k/pci.c linux-3.0-rc7-libre/drivers/net/wireless/ath/ath9k/pci.c
--- linux-2.6.39-libre/drivers/net/wireless/ath/ath9k/pci.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/ath/ath9k/pci.c	2011-07-11 19:51:52.000000000 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008-2009 Atheros Communications Inc.
+ * Copyright (c) 2008-2011 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
@@ -278,6 +278,12 @@
 
 	ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, 1);
 
+	/* The device has to be moved to FULLSLEEP forcibly.
+	 * Otherwise the chip never moved to full sleep,
+	 * when no interface is up.
+	 */
+	ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_FULL_SLEEP);
+
 	return 0;
 }
 
diff -druN linux-2.6.39-libre/drivers/net/wireless/ath/ath9k/phy.h linux-3.0-rc7-libre/drivers/net/wireless/ath/ath9k/phy.h
--- linux-2.6.39-libre/drivers/net/wireless/ath/ath9k/phy.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/ath/ath9k/phy.h	2011-07-11 19:51:52.000000000 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008-2009 Atheros Communications Inc.
+ * Copyright (c) 2008-2011 Atheros Communications Inc.
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
@@ -19,7 +19,6 @@
 
 #define CHANSEL_DIV		15
 #define CHANSEL_2G(_freq)	(((_freq) * 0x10000) / CHANSEL_DIV)
-#define CHANSEL_2G_9485(_freq)	((((_freq) * 0x10000) - 215) / CHANSEL_DIV)
 #define CHANSEL_5G(_freq)	(((_freq) * 0x8000) / CHANSEL_DIV)
 
 #define AR_PHY_BASE     0x9800
@@ -38,26 +37,15 @@
 #define AR_PHY_CLC_Q0        0x0000ffd0
 #define AR_PHY_CLC_Q0_S      5
 
-#define REG_WRITE_RF_ARRAY(iniarray, regData, regWr) do {               \
-		int r;							\
-		for (r = 0; r < ((iniarray)->ia_rows); r++) {		\
-			REG_WRITE(ah, INI_RA((iniarray), r, 0), (regData)[r]); \
-			DO_DELAY(regWr);				\
-		}							\
-	} while (0)
-
 #define ANTSWAP_AB 0x0001
 #define REDUCE_CHAIN_0 0x00000050
 #define REDUCE_CHAIN_1 0x00000051
 #define AR_PHY_CHIP_ID 0x9818
 
-#define RF_BANK_SETUP(_bank, _iniarray, _col) do {			\
-		int i;							\
-		for (i = 0; i < (_iniarray)->ia_rows; i++)		\
-			(_bank)[i] = INI_RA((_iniarray), i, _col);;	\
-	} while (0)
-
 #define	AR_PHY_TIMING11_SPUR_FREQ_SD		0x3FF00000
 #define	AR_PHY_TIMING11_SPUR_FREQ_SD_S		20
 
+#define AR_PHY_PLL_CONTROL 0x16180
+#define AR_PHY_PLL_MODE 0x16184
+
 #endif
diff -druN linux-2.6.39-libre/drivers/net/wireless/ath/ath9k/rc.c linux-3.0-rc7-libre/drivers/net/wireless/ath/ath9k/rc.c
--- linux-2.6.39-libre/drivers/net/wireless/ath/ath9k/rc.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/ath/ath9k/rc.c	2011-07-11 19:51:52.000000000 -0400
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2004 Video54 Technologies, Inc.
- * Copyright (c) 2004-2009 Atheros Communications, Inc.
+ * Copyright (c) 2004-2011 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
@@ -689,7 +689,8 @@
 
 	if (WLAN_RC_PHY_HT(rate_table->info[rix].phy)) {
 		rate->flags |= IEEE80211_TX_RC_MCS;
-		if (WLAN_RC_PHY_40(rate_table->info[rix].phy))
+		if (WLAN_RC_PHY_40(rate_table->info[rix].phy) &&
+		    conf_is_ht40(&txrc->hw->conf))
 			rate->flags |= IEEE80211_TX_RC_40_MHZ_WIDTH;
 		if (WLAN_RC_PHY_SGI(rate_table->info[rix].phy))
 			rate->flags |= IEEE80211_TX_RC_SHORT_GI;
@@ -854,14 +855,13 @@
 	ath_rc_rate_set_rtscts(sc, rate_table, tx_info);
 }
 
-static bool ath_rc_update_per(struct ath_softc *sc,
+static void ath_rc_update_per(struct ath_softc *sc,
 			      const struct ath_rate_table *rate_table,
 			      struct ath_rate_priv *ath_rc_priv,
 				  struct ieee80211_tx_info *tx_info,
 			      int tx_rate, int xretries, int retries,
 			      u32 now_msec)
 {
-	bool state_change = false;
 	int count, n_bad_frames;
 	u8 last_per;
 	static const u32 nretry_to_per_lookup[10] = {
@@ -992,8 +992,6 @@
 
 		}
 	}
-
-	return state_change;
 }
 
 static void ath_debug_stat_retries(struct ath_rate_priv *rc, int rix,
@@ -1017,7 +1015,6 @@
 	u32 now_msec = jiffies_to_msecs(jiffies);
 	int rate;
 	u8 last_per;
-	bool state_change = false;
 	const struct ath_rate_table *rate_table = ath_rc_priv->rate_table;
 	int size = ath_rc_priv->rate_table_size;
 
@@ -1027,9 +1024,9 @@
 	last_per = ath_rc_priv->per[tx_rate];
 
 	/* Update PER first */
-	state_change = ath_rc_update_per(sc, rate_table, ath_rc_priv,
-					 tx_info, tx_rate, xretries,
-					 retries, now_msec);
+	ath_rc_update_per(sc, rate_table, ath_rc_priv,
+			  tx_info, tx_rate, xretries,
+			  retries, now_msec);
 
 	/*
 	 * If this rate looks bad (high PER) then stop using it for
@@ -1092,8 +1089,7 @@
 	if (!(rate->flags & IEEE80211_TX_RC_MCS))
 		return rate->idx;
 
-	while (rate->idx > mcs_rix_off[i] &&
-	       i < ARRAY_SIZE(mcs_rix_off)) {
+	while (i < ARRAY_SIZE(mcs_rix_off) && rate->idx > mcs_rix_off[i]) {
 		rix++; i++;
 	}
 
diff -druN linux-2.6.39-libre/drivers/net/wireless/ath/ath9k/rc.h linux-3.0-rc7-libre/drivers/net/wireless/ath/ath9k/rc.h
--- linux-2.6.39-libre/drivers/net/wireless/ath/ath9k/rc.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/ath/ath9k/rc.h	2011-07-11 19:51:52.000000000 -0400
@@ -1,7 +1,7 @@
 /*
  * Copyright (c) 2004 Sam Leffler, Errno Consulting
  * Copyright (c) 2004 Video54 Technologies, Inc.
- * Copyright (c) 2008-2009 Atheros Communications Inc.
+ * Copyright (c) 2008-2011 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
diff -druN linux-2.6.39-libre/drivers/net/wireless/ath/ath9k/recv.c linux-3.0-rc7-libre/drivers/net/wireless/ath/ath9k/recv.c
--- linux-2.6.39-libre/drivers/net/wireless/ath/ath9k/recv.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/ath/ath9k/recv.c	2011-07-11 19:51:52.000000000 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008-2009 Atheros Communications Inc.
+ * Copyright (c) 2008-2011 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
@@ -28,6 +28,33 @@
 		(alt_rssi_avg > main_rssi_avg + mindelta)) && (pkt_count > 50);
 }
 
+static inline bool ath_ant_div_comb_alt_check(u8 div_group, int alt_ratio,
+					int curr_main_set, int curr_alt_set,
+					int alt_rssi_avg, int main_rssi_avg)
+{
+	bool result = false;
+	switch (div_group) {
+	case 0:
+		if (alt_ratio > ATH_ANT_DIV_COMB_ALT_ANT_RATIO)
+			result = true;
+		break;
+	case 1:
+		if ((((curr_main_set == ATH_ANT_DIV_COMB_LNA2) &&
+			(curr_alt_set == ATH_ANT_DIV_COMB_LNA1) &&
+				(alt_rssi_avg >= (main_rssi_avg - 5))) ||
+			((curr_main_set == ATH_ANT_DIV_COMB_LNA1) &&
+			(curr_alt_set == ATH_ANT_DIV_COMB_LNA2) &&
+				(alt_rssi_avg >= (main_rssi_avg - 2)))) &&
+							(alt_rssi_avg >= 4))
+			result = true;
+		else
+			result = false;
+		break;
+	}
+
+	return result;
+}
+
 static inline bool ath9k_check_auto_sleep(struct ath_softc *sc)
 {
 	return sc->ps_enabled &&
@@ -75,7 +102,6 @@
 		*sc->rx.rxlink = bf->bf_daddr;
 
 	sc->rx.rxlink = &ds->ds_link;
-	ath9k_hw_rxena(ah);
 }
 
 static void ath_setdefantenna(struct ath_softc *sc, u32 antenna)
@@ -426,9 +452,7 @@
 	else
 		rfilt |= ATH9K_RX_FILTER_BEACON;
 
-	if ((AR_SREV_9280_20_OR_LATER(sc->sc_ah) ||
-	    AR_SREV_9285_12_OR_LATER(sc->sc_ah)) &&
-	    (sc->sc_ah->opmode == NL80211_IFTYPE_AP) &&
+	if ((sc->sc_ah->opmode == NL80211_IFTYPE_AP) ||
 	    (sc->rx.rxfilter & FIF_PSPOLL))
 		rfilt |= ATH9K_RX_FILTER_PSPOLL;
 
@@ -574,7 +598,8 @@
 		sc->ps_flags &= ~PS_BEACON_SYNC;
 		ath_dbg(common, ATH_DBG_PS,
 			"Reconfigure Beacon timers based on timestamp from the AP\n");
-		ath_beacon_config(sc, NULL);
+		ath_set_beacon(sc);
+		sc->ps_flags &= ~PS_TSFOOR_SYNC;
 	}
 
 	if (ath_beacon_dtim_pending_cab(skb)) {
@@ -919,7 +944,8 @@
 	int last_rssi;
 	__le16 fc;
 
-	if (ah->opmode != NL80211_IFTYPE_STATION)
+	if ((ah->opmode != NL80211_IFTYPE_STATION) &&
+	    (ah->opmode != NL80211_IFTYPE_ADHOC))
 		return;
 
 	fc = hdr->frame_control;
@@ -1291,49 +1317,138 @@
 	}
 }
 
-static void ath_ant_div_conf_fast_divbias(struct ath_hw_antcomb_conf *ant_conf)
+static void ath_ant_div_conf_fast_divbias(struct ath_hw_antcomb_conf *ant_conf,
+		struct ath_ant_comb *antcomb, int alt_ratio)
 {
-	/* Adjust the fast_div_bias based on main and alt lna conf */
-	switch ((ant_conf->main_lna_conf << 4) | ant_conf->alt_lna_conf) {
-	case (0x01): /* A-B LNA2 */
-		ant_conf->fast_div_bias = 0x3b;
-		break;
-	case (0x02): /* A-B LNA1 */
-		ant_conf->fast_div_bias = 0x3d;
-		break;
-	case (0x03): /* A-B A+B */
-		ant_conf->fast_div_bias = 0x1;
-		break;
-	case (0x10): /* LNA2 A-B */
-		ant_conf->fast_div_bias = 0x7;
-		break;
-	case (0x12): /* LNA2 LNA1 */
-		ant_conf->fast_div_bias = 0x2;
-		break;
-	case (0x13): /* LNA2 A+B */
-		ant_conf->fast_div_bias = 0x7;
-		break;
-	case (0x20): /* LNA1 A-B */
-		ant_conf->fast_div_bias = 0x6;
-		break;
-	case (0x21): /* LNA1 LNA2 */
-		ant_conf->fast_div_bias = 0x0;
-		break;
-	case (0x23): /* LNA1 A+B */
-		ant_conf->fast_div_bias = 0x6;
-		break;
-	case (0x30): /* A+B A-B */
-		ant_conf->fast_div_bias = 0x1;
-		break;
-	case (0x31): /* A+B LNA2 */
-		ant_conf->fast_div_bias = 0x3b;
-		break;
-	case (0x32): /* A+B LNA1 */
-		ant_conf->fast_div_bias = 0x3d;
-		break;
-	default:
-		break;
+	if (ant_conf->div_group == 0) {
+		/* Adjust the fast_div_bias based on main and alt lna conf */
+		switch ((ant_conf->main_lna_conf << 4) |
+				ant_conf->alt_lna_conf) {
+		case (0x01): /* A-B LNA2 */
+			ant_conf->fast_div_bias = 0x3b;
+			break;
+		case (0x02): /* A-B LNA1 */
+			ant_conf->fast_div_bias = 0x3d;
+			break;
+		case (0x03): /* A-B A+B */
+			ant_conf->fast_div_bias = 0x1;
+			break;
+		case (0x10): /* LNA2 A-B */
+			ant_conf->fast_div_bias = 0x7;
+			break;
+		case (0x12): /* LNA2 LNA1 */
+			ant_conf->fast_div_bias = 0x2;
+			break;
+		case (0x13): /* LNA2 A+B */
+			ant_conf->fast_div_bias = 0x7;
+			break;
+		case (0x20): /* LNA1 A-B */
+			ant_conf->fast_div_bias = 0x6;
+			break;
+		case (0x21): /* LNA1 LNA2 */
+			ant_conf->fast_div_bias = 0x0;
+			break;
+		case (0x23): /* LNA1 A+B */
+			ant_conf->fast_div_bias = 0x6;
+			break;
+		case (0x30): /* A+B A-B */
+			ant_conf->fast_div_bias = 0x1;
+			break;
+		case (0x31): /* A+B LNA2 */
+			ant_conf->fast_div_bias = 0x3b;
+			break;
+		case (0x32): /* A+B LNA1 */
+			ant_conf->fast_div_bias = 0x3d;
+			break;
+		default:
+			break;
+		}
+	} else if (ant_conf->div_group == 2) {
+		/* Adjust the fast_div_bias based on main and alt_lna_conf */
+		switch ((ant_conf->main_lna_conf << 4) |
+				ant_conf->alt_lna_conf) {
+		case (0x01): /* A-B LNA2 */
+			ant_conf->fast_div_bias = 0x1;
+			ant_conf->main_gaintb = 0;
+			ant_conf->alt_gaintb = 0;
+			break;
+		case (0x02): /* A-B LNA1 */
+			ant_conf->fast_div_bias = 0x1;
+			ant_conf->main_gaintb = 0;
+			ant_conf->alt_gaintb = 0;
+			break;
+		case (0x03): /* A-B A+B */
+			ant_conf->fast_div_bias = 0x1;
+			ant_conf->main_gaintb = 0;
+			ant_conf->alt_gaintb = 0;
+			break;
+		case (0x10): /* LNA2 A-B */
+			if (!(antcomb->scan) &&
+				(alt_ratio > ATH_ANT_DIV_COMB_ALT_ANT_RATIO))
+				ant_conf->fast_div_bias = 0x1;
+			else
+				ant_conf->fast_div_bias = 0x2;
+			ant_conf->main_gaintb = 0;
+			ant_conf->alt_gaintb = 0;
+			break;
+		case (0x12): /* LNA2 LNA1 */
+			ant_conf->fast_div_bias = 0x1;
+			ant_conf->main_gaintb = 0;
+			ant_conf->alt_gaintb = 0;
+			break;
+		case (0x13): /* LNA2 A+B */
+			if (!(antcomb->scan) &&
+				(alt_ratio > ATH_ANT_DIV_COMB_ALT_ANT_RATIO))
+				ant_conf->fast_div_bias = 0x1;
+			else
+				ant_conf->fast_div_bias = 0x2;
+			ant_conf->main_gaintb = 0;
+			ant_conf->alt_gaintb = 0;
+			break;
+		case (0x20): /* LNA1 A-B */
+			if (!(antcomb->scan) &&
+				(alt_ratio > ATH_ANT_DIV_COMB_ALT_ANT_RATIO))
+				ant_conf->fast_div_bias = 0x1;
+			else
+				ant_conf->fast_div_bias = 0x2;
+			ant_conf->main_gaintb = 0;
+			ant_conf->alt_gaintb = 0;
+			break;
+		case (0x21): /* LNA1 LNA2 */
+			ant_conf->fast_div_bias = 0x1;
+			ant_conf->main_gaintb = 0;
+			ant_conf->alt_gaintb = 0;
+			break;
+		case (0x23): /* LNA1 A+B */
+			if (!(antcomb->scan) &&
+				(alt_ratio > ATH_ANT_DIV_COMB_ALT_ANT_RATIO))
+				ant_conf->fast_div_bias = 0x1;
+			else
+				ant_conf->fast_div_bias = 0x2;
+			ant_conf->main_gaintb = 0;
+			ant_conf->alt_gaintb = 0;
+			break;
+		case (0x30): /* A+B A-B */
+			ant_conf->fast_div_bias = 0x1;
+			ant_conf->main_gaintb = 0;
+			ant_conf->alt_gaintb = 0;
+			break;
+		case (0x31): /* A+B LNA2 */
+			ant_conf->fast_div_bias = 0x1;
+			ant_conf->main_gaintb = 0;
+			ant_conf->alt_gaintb = 0;
+			break;
+		case (0x32): /* A+B LNA1 */
+			ant_conf->fast_div_bias = 0x1;
+			ant_conf->main_gaintb = 0;
+			ant_conf->alt_gaintb = 0;
+			break;
+		default:
+			break;
+		}
+
 	}
+
 }
 
 /* Antenna diversity and combining */
@@ -1342,7 +1457,7 @@
 	struct ath_hw_antcomb_conf div_ant_conf;
 	struct ath_ant_comb *antcomb = &sc->ant_comb;
 	int alt_ratio = 0, alt_rssi_avg = 0, main_rssi_avg = 0, curr_alt_set;
-	int curr_main_set, curr_bias;
+	int curr_main_set;
 	int main_rssi = rs->rs_rssi_ctl0;
 	int alt_rssi = rs->rs_rssi_ctl1;
 	int rx_ant_conf,  main_ant_conf;
@@ -1353,8 +1468,8 @@
 	main_ant_conf = (rs->rs_rssi_ctl2 >> ATH_ANT_RX_MAIN_SHIFT) &
 			 ATH_ANT_RX_MASK;
 
-	/* Record packet only when alt_rssi is positive */
-	if (alt_rssi > 0) {
+	/* Record packet only when both main_rssi and  alt_rssi is positive */
+	if (main_rssi > 0 && alt_rssi > 0) {
 		antcomb->total_pkt_count++;
 		antcomb->main_total_rssi += main_rssi;
 		antcomb->alt_total_rssi  += alt_rssi;
@@ -1396,7 +1511,6 @@
 	ath9k_hw_antdiv_comb_conf_get(sc->sc_ah, &div_ant_conf);
 	curr_alt_set = div_ant_conf.alt_lna_conf;
 	curr_main_set = div_ant_conf.main_lna_conf;
-	curr_bias = div_ant_conf.fast_div_bias;
 
 	antcomb->count++;
 
@@ -1415,7 +1529,9 @@
 	}
 
 	if (!antcomb->scan) {
-		if (alt_ratio > ATH_ANT_DIV_COMB_ALT_ANT_RATIO) {
+		if (ath_ant_div_comb_alt_check(div_ant_conf.div_group,
+					alt_ratio, curr_main_set, curr_alt_set,
+					alt_rssi_avg, main_rssi_avg)) {
 			if (curr_alt_set == ATH_ANT_DIV_COMB_LNA2) {
 				/* Switch main and alt LNA */
 				div_ant_conf.main_lna_conf =
@@ -1444,7 +1560,7 @@
 		}
 
 		if ((alt_rssi_avg < (main_rssi_avg +
-		    ATH_ANT_DIV_COMB_LNA1_LNA2_DELTA)))
+						div_ant_conf.lna1_lna2_delta)))
 			goto div_comb_done;
 	}
 
@@ -1558,8 +1674,7 @@
 	antcomb->quick_scan_cnt++;
 
 div_comb_done:
-	ath_ant_div_conf_fast_divbias(&div_ant_conf);
-
+	ath_ant_div_conf_fast_divbias(&div_ant_conf, antcomb, alt_ratio);
 	ath9k_hw_antdiv_comb_conf_set(sc->sc_ah, &div_ant_conf);
 
 	antcomb->scan_start_time = jiffies;
@@ -1746,7 +1861,7 @@
 		if ((sc->ps_flags & (PS_WAIT_FOR_BEACON |
 					      PS_WAIT_FOR_CAB |
 					      PS_WAIT_FOR_PSPOLL_DATA)) ||
-					unlikely(ath9k_check_auto_sleep(sc)))
+						ath9k_check_auto_sleep(sc))
 			ath_rx_ps(sc, skb);
 		spin_unlock_irqrestore(&sc->sc_pm_lock, flags);
 
@@ -1767,6 +1882,7 @@
 		} else {
 			list_move_tail(&bf->list, &sc->rx.rxbuf);
 			ath_rx_buf_link(sc, bf);
+			ath9k_hw_rxena(ah);
 		}
 	} while (1);
 
diff -druN linux-2.6.39-libre/drivers/net/wireless/ath/ath9k/reg.h linux-3.0-rc7-libre/drivers/net/wireless/ath/ath9k/reg.h
--- linux-2.6.39-libre/drivers/net/wireless/ath/ath9k/reg.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/ath/ath9k/reg.h	2011-07-11 19:51:52.000000000 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008-2009 Atheros Communications Inc.
+ * Copyright (c) 2008-2011 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
@@ -693,7 +693,7 @@
 #define AR_RC_APB            0x00000002
 #define AR_RC_HOSTIF         0x00000100
 
-#define AR_WA                		0x4004
+#define AR_WA			(AR_SREV_9340(ah) ? 0x40c4 : 0x4004)
 #define AR_WA_BIT6			(1 << 6)
 #define AR_WA_BIT7			(1 << 7)
 #define AR_WA_BIT23			(1 << 23)
@@ -712,7 +712,7 @@
 #define AR_PM_STATE                 0x4008
 #define AR_PM_STATE_PME_D3COLD_VAUX 0x00100000
 
-#define AR_HOST_TIMEOUT             0x4018
+#define AR_HOST_TIMEOUT             (AR_SREV_9340(ah) ? 0x4008 : 0x4018)
 #define AR_HOST_TIMEOUT_APB_CNTR    0x0000FFFF
 #define AR_HOST_TIMEOUT_APB_CNTR_S  0
 #define AR_HOST_TIMEOUT_LCL_CNTR    0xFFFF0000
@@ -742,7 +742,8 @@
 #define EEPROM_PROTECT_WP_1024_2047   0x8000
 
 #define AR_SREV \
-	((AR_SREV_9100(ah)) ? 0x0600 : 0x4020)
+	((AR_SREV_9100(ah)) ? 0x0600 : (AR_SREV_9340(ah) \
+					? 0x400c : 0x4020))
 
 #define AR_SREV_ID \
 	((AR_SREV_9100(ah)) ? 0x00000FFF : 0x000000FF)
@@ -790,6 +791,7 @@
 #define AR_SREV_VERSION_9485		0x240
 #define AR_SREV_REVISION_9485_10	0
 #define AR_SREV_REVISION_9485_11        1
+#define AR_SREV_VERSION_9340		0x300
 
 #define AR_SREV_5416(_ah) \
 	(((_ah)->hw_version.macVersion == AR_SREV_VERSION_5416_PCI) || \
@@ -858,9 +860,7 @@
 #define AR_SREV_9300(_ah) \
 	(((_ah)->hw_version.macVersion == AR_SREV_VERSION_9300))
 #define AR_SREV_9300_20_OR_LATER(_ah) \
-	(((_ah)->hw_version.macVersion > AR_SREV_VERSION_9300) || \
-	 (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9300) && \
-	  ((_ah)->hw_version.macRev >= AR_SREV_REVISION_9300_20)))
+	((_ah)->hw_version.macVersion >= AR_SREV_VERSION_9300)
 
 #define AR_SREV_9485(_ah) \
 	(((_ah)->hw_version.macVersion == AR_SREV_VERSION_9485))
@@ -870,6 +870,11 @@
 #define AR_SREV_9485_11(_ah) \
 	(AR_SREV_9485(_ah) && \
 	 ((_ah)->hw_version.macRev == AR_SREV_REVISION_9485_11))
+#define AR_SREV_9485_OR_LATER(_ah) \
+	(((_ah)->hw_version.macVersion >= AR_SREV_VERSION_9485))
+
+#define AR_SREV_9340(_ah) \
+	(((_ah)->hw_version.macVersion == AR_SREV_VERSION_9340))
 
 #define AR_SREV_9285E_20(_ah) \
     (AR_SREV_9285_12_OR_LATER(_ah) && \
@@ -912,11 +917,11 @@
 #define AR_INTR_SPURIOUS                      0xFFFFFFFF
 
 
-#define AR_INTR_SYNC_CAUSE_CLR                0x4028
+#define AR_INTR_SYNC_CAUSE                    (AR_SREV_9340(ah) ? 0x4010 : 0x4028)
+#define AR_INTR_SYNC_CAUSE_CLR                (AR_SREV_9340(ah) ? 0x4010 : 0x4028)
 
-#define AR_INTR_SYNC_CAUSE                    0x4028
 
-#define AR_INTR_SYNC_ENABLE                   0x402c
+#define AR_INTR_SYNC_ENABLE                   (AR_SREV_9340(ah) ? 0x4014 : 0x402c)
 #define AR_INTR_SYNC_ENABLE_GPIO              0xFFFC0000
 #define AR_INTR_SYNC_ENABLE_GPIO_S            18
 
@@ -956,24 +961,24 @@
 
 };
 
-#define AR_INTR_ASYNC_MASK                       0x4030
+#define AR_INTR_ASYNC_MASK                       (AR_SREV_9340(ah) ? 0x4018 : 0x4030)
 #define AR_INTR_ASYNC_MASK_GPIO                  0xFFFC0000
 #define AR_INTR_ASYNC_MASK_GPIO_S                18
 
-#define AR_INTR_SYNC_MASK                        0x4034
+#define AR_INTR_SYNC_MASK                        (AR_SREV_9340(ah) ? 0x401c : 0x4034)
 #define AR_INTR_SYNC_MASK_GPIO                   0xFFFC0000
 #define AR_INTR_SYNC_MASK_GPIO_S                 18
 
-#define AR_INTR_ASYNC_CAUSE_CLR                  0x4038
-#define AR_INTR_ASYNC_CAUSE                      0x4038
+#define AR_INTR_ASYNC_CAUSE_CLR                  (AR_SREV_9340(ah) ? 0x4020 : 0x4038)
+#define AR_INTR_ASYNC_CAUSE                      (AR_SREV_9340(ah) ? 0x4020 : 0x4038)
 
-#define AR_INTR_ASYNC_ENABLE                     0x403c
+#define AR_INTR_ASYNC_ENABLE                     (AR_SREV_9340(ah) ? 0x4024 : 0x403c)
 #define AR_INTR_ASYNC_ENABLE_GPIO                0xFFFC0000
 #define AR_INTR_ASYNC_ENABLE_GPIO_S              18
 
 #define AR_PCIE_SERDES                           0x4040
 #define AR_PCIE_SERDES2                          0x4044
-#define AR_PCIE_PM_CTRL                          0x4014
+#define AR_PCIE_PM_CTRL                          (AR_SREV_9340(ah) ? 0x4004 : 0x4014)
 #define AR_PCIE_PM_CTRL_ENA                      0x00080000
 
 #define AR_NUM_GPIO                              14
@@ -984,7 +989,7 @@
 #define AR9300_NUM_GPIO                          17
 #define AR7010_NUM_GPIO                          16
 
-#define AR_GPIO_IN_OUT                           0x4048
+#define AR_GPIO_IN_OUT                           (AR_SREV_9340(ah) ? 0x4028 : 0x4048)
 #define AR_GPIO_IN_VAL                           0x0FFFC000
 #define AR_GPIO_IN_VAL_S                         14
 #define AR928X_GPIO_IN_VAL                       0x000FFC00
@@ -998,11 +1003,12 @@
 #define AR7010_GPIO_IN_VAL                       0x0000FFFF
 #define AR7010_GPIO_IN_VAL_S                     0
 
-#define AR_GPIO_IN				 0x404c
+#define AR_GPIO_IN				 (AR_SREV_9340(ah) ? 0x402c : 0x404c)
 #define AR9300_GPIO_IN_VAL                       0x0001FFFF
 #define AR9300_GPIO_IN_VAL_S                     0
 
-#define AR_GPIO_OE_OUT                           (AR_SREV_9300_20_OR_LATER(ah) ? 0x4050 : 0x404c)
+#define AR_GPIO_OE_OUT                           (AR_SREV_9340(ah) ? 0x4030 : \
+						  (AR_SREV_9300_20_OR_LATER(ah) ? 0x4050 : 0x404c))
 #define AR_GPIO_OE_OUT_DRV                       0x3
 #define AR_GPIO_OE_OUT_DRV_NO                    0x0
 #define AR_GPIO_OE_OUT_DRV_LOW                   0x1
@@ -1024,11 +1030,13 @@
 #define AR7010_GPIO_INT_MASK                     0x52024
 #define AR7010_GPIO_FUNCTION                     0x52028
 
-#define AR_GPIO_INTR_POL                         (AR_SREV_9300_20_OR_LATER(ah) ? 0x4058 : 0x4050)
+#define AR_GPIO_INTR_POL                         (AR_SREV_9340(ah) ? 0x4038 : \
+						  (AR_SREV_9300_20_OR_LATER(ah) ? 0x4058 : 0x4050))
 #define AR_GPIO_INTR_POL_VAL                     0x0001FFFF
 #define AR_GPIO_INTR_POL_VAL_S                   0
 
-#define AR_GPIO_INPUT_EN_VAL                     (AR_SREV_9300_20_OR_LATER(ah) ? 0x405c : 0x4054)
+#define AR_GPIO_INPUT_EN_VAL                     (AR_SREV_9340(ah) ? 0x403c : \
+						  (AR_SREV_9300_20_OR_LATER(ah) ? 0x405c : 0x4054))
 #define AR_GPIO_INPUT_EN_VAL_BT_PRIORITY_DEF     0x00000004
 #define AR_GPIO_INPUT_EN_VAL_BT_PRIORITY_S       2
 #define AR_GPIO_INPUT_EN_VAL_BT_FREQUENCY_DEF    0x00000008
@@ -1046,13 +1054,15 @@
 #define AR_GPIO_RTC_RESET_OVERRIDE_ENABLE        0x00010000
 #define AR_GPIO_JTAG_DISABLE                     0x00020000
 
-#define AR_GPIO_INPUT_MUX1                       (AR_SREV_9300_20_OR_LATER(ah) ? 0x4060 : 0x4058)
+#define AR_GPIO_INPUT_MUX1                       (AR_SREV_9340(ah) ? 0x4040 : \
+						  (AR_SREV_9300_20_OR_LATER(ah) ? 0x4060 : 0x4058))
 #define AR_GPIO_INPUT_MUX1_BT_ACTIVE             0x000f0000
 #define AR_GPIO_INPUT_MUX1_BT_ACTIVE_S           16
 #define AR_GPIO_INPUT_MUX1_BT_PRIORITY           0x00000f00
 #define AR_GPIO_INPUT_MUX1_BT_PRIORITY_S         8
 
-#define AR_GPIO_INPUT_MUX2                       (AR_SREV_9300_20_OR_LATER(ah) ? 0x4064 : 0x405c)
+#define AR_GPIO_INPUT_MUX2                       (AR_SREV_9340(ah) ? 0x4044 : \
+						  (AR_SREV_9300_20_OR_LATER(ah) ? 0x4064 : 0x405c))
 #define AR_GPIO_INPUT_MUX2_CLK25                 0x0000000f
 #define AR_GPIO_INPUT_MUX2_CLK25_S               0
 #define AR_GPIO_INPUT_MUX2_RFSILENT              0x000000f0
@@ -1060,13 +1070,18 @@
 #define AR_GPIO_INPUT_MUX2_RTC_RESET             0x00000f00
 #define AR_GPIO_INPUT_MUX2_RTC_RESET_S           8
 
-#define AR_GPIO_OUTPUT_MUX1                      (AR_SREV_9300_20_OR_LATER(ah) ? 0x4068 : 0x4060)
-#define AR_GPIO_OUTPUT_MUX2                      (AR_SREV_9300_20_OR_LATER(ah) ? 0x406c : 0x4064)
-#define AR_GPIO_OUTPUT_MUX3                      (AR_SREV_9300_20_OR_LATER(ah) ? 0x4070 : 0x4068)
+#define AR_GPIO_OUTPUT_MUX1                      (AR_SREV_9340(ah) ? 0x4048 : \
+						  (AR_SREV_9300_20_OR_LATER(ah) ? 0x4068 : 0x4060))
+#define AR_GPIO_OUTPUT_MUX2                      (AR_SREV_9340(ah) ? 0x404c : \
+						  (AR_SREV_9300_20_OR_LATER(ah) ? 0x406c : 0x4064))
+#define AR_GPIO_OUTPUT_MUX3                      (AR_SREV_9340(ah) ? 0x4050 : \
+						  (AR_SREV_9300_20_OR_LATER(ah) ? 0x4070 : 0x4068))
 
-#define AR_INPUT_STATE                           (AR_SREV_9300_20_OR_LATER(ah) ? 0x4074 : 0x406c)
+#define AR_INPUT_STATE                           (AR_SREV_9340(ah) ? 0x4054 : \
+						  (AR_SREV_9300_20_OR_LATER(ah) ? 0x4074 : 0x406c))
 
-#define AR_EEPROM_STATUS_DATA                    (AR_SREV_9300_20_OR_LATER(ah) ? 0x4084 : 0x407c)
+#define AR_EEPROM_STATUS_DATA                    (AR_SREV_9340(ah) ? 0x40c8 : \
+						  (AR_SREV_9300_20_OR_LATER(ah) ? 0x4084 : 0x407c))
 #define AR_EEPROM_STATUS_DATA_VAL                0x0000ffff
 #define AR_EEPROM_STATUS_DATA_VAL_S              0
 #define AR_EEPROM_STATUS_DATA_BUSY               0x00010000
@@ -1074,28 +1089,51 @@
 #define AR_EEPROM_STATUS_DATA_PROT_ACCESS        0x00040000
 #define AR_EEPROM_STATUS_DATA_ABSENT_ACCESS      0x00080000
 
-#define AR_OBS                  (AR_SREV_9300_20_OR_LATER(ah) ? 0x4088 : 0x4080)
+#define AR_OBS                  (AR_SREV_9340(ah) ? 0x405c : \
+				 (AR_SREV_9300_20_OR_LATER(ah) ? 0x4088 : 0x4080))
 
 #define AR_GPIO_PDPU                             (AR_SREV_9300_20_OR_LATER(ah) ? 0x4090 : 0x4088)
 
-#define AR_PCIE_MSI                              (AR_SREV_9300_20_OR_LATER(ah) ? 0x40a4 : 0x4094)
+#define AR_PCIE_MSI                             (AR_SREV_9340(ah) ? 0x40d8 : \
+						 (AR_SREV_9300_20_OR_LATER(ah) ? 0x40a4 : 0x4094))
 #define AR_PCIE_MSI_ENABLE                       0x00000001
 
-#define AR_INTR_PRIO_SYNC_ENABLE  0x40c4
-#define AR_INTR_PRIO_ASYNC_MASK   0x40c8
-#define AR_INTR_PRIO_SYNC_MASK    0x40cc
-#define AR_INTR_PRIO_ASYNC_ENABLE 0x40d4
+#define AR_INTR_PRIO_SYNC_ENABLE  (AR_SREV_9340(ah) ? 0x4088 : 0x40c4)
+#define AR_INTR_PRIO_ASYNC_MASK   (AR_SREV_9340(ah) ? 0x408c : 0x40c8)
+#define AR_INTR_PRIO_SYNC_MASK    (AR_SREV_9340(ah) ? 0x4090 : 0x40cc)
+#define AR_INTR_PRIO_ASYNC_ENABLE (AR_SREV_9340(ah) ? 0x4094 : 0x40d4)
 #define AR_ENT_OTP		  0x40d8
 #define AR_ENT_OTP_CHAIN2_DISABLE               0x00020000
 #define AR_ENT_OTP_MPSD		0x00800000
-#define AR_CH0_BB_DPLL2          0x16184
+
+#define AR_CH0_BB_DPLL1		 0x16180
+#define AR_CH0_BB_DPLL1_REFDIV	 0xF8000000
+#define AR_CH0_BB_DPLL1_REFDIV_S 27
+#define AR_CH0_BB_DPLL1_NINI	 0x07FC0000
+#define AR_CH0_BB_DPLL1_NINI_S	 18
+#define AR_CH0_BB_DPLL1_NFRAC	 0x0003FFFF
+#define AR_CH0_BB_DPLL1_NFRAC_S	 0
+
+#define AR_CH0_BB_DPLL2		     0x16184
+#define AR_CH0_BB_DPLL2_LOCAL_PLL       0x40000000
+#define AR_CH0_BB_DPLL2_LOCAL_PLL_S     30
+#define AR_CH0_DPLL2_KI              0x3C000000
+#define AR_CH0_DPLL2_KI_S            26
+#define AR_CH0_DPLL2_KD              0x03F80000
+#define AR_CH0_DPLL2_KD_S            19
+#define AR_CH0_BB_DPLL2_EN_NEGTRIG   0x00040000
+#define AR_CH0_BB_DPLL2_EN_NEGTRIG_S 18
+#define AR_CH0_BB_DPLL2_PLL_PWD	     0x00010000
+#define AR_CH0_BB_DPLL2_PLL_PWD_S    16
+#define AR_CH0_BB_DPLL2_OUTDIV	     0x0000E000
+#define AR_CH0_BB_DPLL2_OUTDIV_S     13
+
 #define AR_CH0_BB_DPLL3          0x16188
+#define AR_CH0_BB_DPLL3_PHASE_SHIFT	0x3F800000
+#define AR_CH0_BB_DPLL3_PHASE_SHIFT_S	23
+
 #define AR_CH0_DDR_DPLL2         0x16244
 #define AR_CH0_DDR_DPLL3         0x16248
-#define AR_CH0_DPLL2_KD              0x03F80000
-#define AR_CH0_DPLL2_KD_S            19
-#define AR_CH0_DPLL2_KI              0x3C000000
-#define AR_CH0_DPLL2_KI_S            26
 #define AR_CH0_DPLL3_PHASE_SHIFT     0x3F800000
 #define AR_CH0_DPLL3_PHASE_SHIFT_S   23
 #define AR_PHY_CCA_NOM_VAL_2GHZ      -118
@@ -1144,6 +1182,7 @@
 #define AR_RTC_PLL_REFDIV_5     0x000000c0
 #define AR_RTC_PLL_CLKSEL       0x00000300
 #define AR_RTC_PLL_CLKSEL_S     8
+#define AR_RTC_PLL_BYPASS	0x00010000
 
 #define PLL3 0x16188
 #define PLL3_DO_MEAS_MASK 0x40000000
@@ -1190,7 +1229,8 @@
 
 /* RTC_DERIVED_* - only for AR9100 */
 
-#define AR_RTC_DERIVED_CLK           (AR_RTC_BASE + 0x0038)
+#define AR_RTC_DERIVED_CLK \
+	(AR_SREV_9100(ah) ? (AR_RTC_BASE + 0x0038) : 0x7038)
 #define AR_RTC_DERIVED_CLK_PERIOD    0x0000fffe
 #define AR_RTC_DERIVED_CLK_PERIOD_S  1
 
@@ -1396,6 +1436,7 @@
 #define AR_STA_ID1_PCF             0x00100000
 #define AR_STA_ID1_USE_DEFANT      0x00200000
 #define AR_STA_ID1_DEFANT_UPDATE   0x00400000
+#define AR_STA_ID1_AR9100_BA_FIX   0x00400000
 #define AR_STA_ID1_RTS_USE_DEF     0x00800000
 #define AR_STA_ID1_ACKCTS_6MB      0x01000000
 #define AR_STA_ID1_BASE_RATE_11B   0x02000000
@@ -1668,6 +1709,22 @@
 #define AR_BTCOEX_WL_WGHT          0xffff0000
 #define AR_BTCOEX_WL_WGHT_S        16
 
+#define AR_BT_COEX_WL_WEIGHTS0     0x8174
+#define AR_BT_COEX_WL_WEIGHTS1     0x81c4
+
+#define AR_BT_COEX_BT_WEIGHTS0     0x83ac
+#define AR_BT_COEX_BT_WEIGHTS1     0x83b0
+#define AR_BT_COEX_BT_WEIGHTS2     0x83b4
+#define AR_BT_COEX_BT_WEIGHTS3     0x83b8
+
+#define AR9300_BT_WGHT                     0xcccc4444
+#define AR9300_STOMP_ALL_WLAN_WGHT0        0xfffffff0
+#define AR9300_STOMP_ALL_WLAN_WGHT1        0xfffffff0
+#define AR9300_STOMP_LOW_WLAN_WGHT0        0x88888880
+#define AR9300_STOMP_LOW_WLAN_WGHT1        0x88888880
+#define AR9300_STOMP_NONE_WLAN_WGHT0       0x00000000
+#define AR9300_STOMP_NONE_WLAN_WGHT1       0x00000000
+
 #define AR_BT_COEX_MODE2           0x817c
 #define AR_BT_BCN_MISS_THRESH      0x000000ff
 #define AR_BT_BCN_MISS_THRESH_S    0
diff -druN linux-2.6.39-libre/drivers/net/wireless/ath/ath9k/wmi.c linux-3.0-rc7-libre/drivers/net/wireless/ath/ath9k/wmi.c
--- linux-2.6.39-libre/drivers/net/wireless/ath/ath9k/wmi.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/ath/ath9k/wmi.c	2011-07-11 19:51:52.000000000 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010 Atheros Communications Inc.
+ * Copyright (c) 2010-2011 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
@@ -23,20 +23,18 @@
 		return "WMI_ECHO_CMDID";
 	case WMI_ACCESS_MEMORY_CMDID:
 		return "WMI_ACCESS_MEMORY_CMDID";
+	case WMI_GET_FW_VERSION:
+		return "WMI_GET_FW_VERSION";
 	case WMI_DISABLE_INTR_CMDID:
 		return "WMI_DISABLE_INTR_CMDID";
 	case WMI_ENABLE_INTR_CMDID:
 		return "WMI_ENABLE_INTR_CMDID";
-	case WMI_RX_LINK_CMDID:
-		return "WMI_RX_LINK_CMDID";
 	case WMI_ATH_INIT_CMDID:
 		return "WMI_ATH_INIT_CMDID";
 	case WMI_ABORT_TXQ_CMDID:
 		return "WMI_ABORT_TXQ_CMDID";
 	case WMI_STOP_TX_DMA_CMDID:
 		return "WMI_STOP_TX_DMA_CMDID";
-	case WMI_STOP_DMA_RECV_CMDID:
-		return "WMI_STOP_DMA_RECV_CMDID";
 	case WMI_ABORT_TX_DMA_CMDID:
 		return "WMI_ABORT_TX_DMA_CMDID";
 	case WMI_DRAIN_TXQ_CMDID:
@@ -51,8 +49,6 @@
 		return "WMI_FLUSH_RECV_CMDID";
 	case WMI_SET_MODE_CMDID:
 		return "WMI_SET_MODE_CMDID";
-	case WMI_RESET_CMDID:
-		return "WMI_RESET_CMDID";
 	case WMI_NODE_CREATE_CMDID:
 		return "WMI_NODE_CREATE_CMDID";
 	case WMI_NODE_REMOVE_CMDID:
@@ -61,8 +57,6 @@
 		return "WMI_VAP_REMOVE_CMDID";
 	case WMI_VAP_CREATE_CMDID:
 		return "WMI_VAP_CREATE_CMDID";
-	case WMI_BEACON_UPDATE_CMDID:
-		return "WMI_BEACON_UPDATE_CMDID";
 	case WMI_REG_READ_CMDID:
 		return "WMI_REG_READ_CMDID";
 	case WMI_REG_WRITE_CMDID:
@@ -71,22 +65,22 @@
 		return "WMI_RC_STATE_CHANGE_CMDID";
 	case WMI_RC_RATE_UPDATE_CMDID:
 		return "WMI_RC_RATE_UPDATE_CMDID";
-	case WMI_DEBUG_INFO_CMDID:
-		return "WMI_DEBUG_INFO_CMDID";
-	case WMI_HOST_ATTACH:
-		return "WMI_HOST_ATTACH";
 	case WMI_TARGET_IC_UPDATE_CMDID:
 		return "WMI_TARGET_IC_UPDATE_CMDID";
-	case WMI_TGT_STATS_CMDID:
-		return "WMI_TGT_STATS_CMDID";
 	case WMI_TX_AGGR_ENABLE_CMDID:
 		return "WMI_TX_AGGR_ENABLE_CMDID";
 	case WMI_TGT_DETACH_CMDID:
 		return "WMI_TGT_DETACH_CMDID";
-	case WMI_TGT_TXQ_ENABLE_CMDID:
-		return "WMI_TGT_TXQ_ENABLE_CMDID";
-	case WMI_AGGR_LIMIT_CMD:
-		return "WMI_AGGR_LIMIT_CMD";
+	case WMI_NODE_UPDATE_CMDID:
+		return "WMI_NODE_UPDATE_CMDID";
+	case WMI_INT_STATS_CMDID:
+		return "WMI_INT_STATS_CMDID";
+	case WMI_TX_STATS_CMDID:
+		return "WMI_TX_STATS_CMDID";
+	case WMI_RX_STATS_CMDID:
+		return "WMI_RX_STATS_CMDID";
+	case WMI_BITRATE_MASK_CMDID:
+		return "WMI_BITRATE_MASK_CMDID";
 	}
 
 	return "Bogus";
@@ -102,9 +96,15 @@
 
 	wmi->drv_priv = priv;
 	wmi->stopped = false;
+	skb_queue_head_init(&wmi->wmi_event_queue);
+	spin_lock_init(&wmi->wmi_lock);
+	spin_lock_init(&wmi->event_lock);
 	mutex_init(&wmi->op_mutex);
 	mutex_init(&wmi->multi_write_mutex);
 	init_completion(&wmi->cmd_wait);
+	INIT_LIST_HEAD(&wmi->pending_tx_events);
+	tasklet_init(&wmi->wmi_event_tasklet, ath9k_wmi_event_tasklet,
+		     (unsigned long)wmi);
 
 	return wmi;
 }
@@ -120,11 +120,65 @@
 	kfree(priv->wmi);
 }
 
-void ath9k_swba_tasklet(unsigned long data)
+void ath9k_wmi_event_drain(struct ath9k_htc_priv *priv)
 {
-	struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *)data;
+	unsigned long flags;
 
-	ath9k_htc_swba(priv, priv->wmi->beacon_pending);
+	tasklet_kill(&priv->wmi->wmi_event_tasklet);
+	spin_lock_irqsave(&priv->wmi->wmi_lock, flags);
+	__skb_queue_purge(&priv->wmi->wmi_event_queue);
+	spin_unlock_irqrestore(&priv->wmi->wmi_lock, flags);
+}
+
+void ath9k_wmi_event_tasklet(unsigned long data)
+{
+	struct wmi *wmi = (struct wmi *)data;
+	struct ath9k_htc_priv *priv = wmi->drv_priv;
+	struct wmi_cmd_hdr *hdr;
+	void *wmi_event;
+	struct wmi_event_swba *swba;
+	struct sk_buff *skb = NULL;
+	unsigned long flags;
+	u16 cmd_id;
+
+	do {
+		spin_lock_irqsave(&wmi->wmi_lock, flags);
+		skb = __skb_dequeue(&wmi->wmi_event_queue);
+		if (!skb) {
+			spin_unlock_irqrestore(&wmi->wmi_lock, flags);
+			return;
+		}
+		spin_unlock_irqrestore(&wmi->wmi_lock, flags);
+
+		hdr = (struct wmi_cmd_hdr *) skb->data;
+		cmd_id = be16_to_cpu(hdr->command_id);
+		wmi_event = skb_pull(skb, sizeof(struct wmi_cmd_hdr));
+
+		switch (cmd_id) {
+		case WMI_SWBA_EVENTID:
+			swba = (struct wmi_event_swba *) wmi_event;
+			ath9k_htc_swba(priv, swba);
+			break;
+		case WMI_FATAL_EVENTID:
+			ieee80211_queue_work(wmi->drv_priv->hw,
+					     &wmi->drv_priv->fatal_work);
+			break;
+		case WMI_TXSTATUS_EVENTID:
+			spin_lock_bh(&priv->tx.tx_lock);
+			if (priv->tx.flags & ATH9K_HTC_OP_TX_DRAIN) {
+				spin_unlock_bh(&priv->tx.tx_lock);
+				break;
+			}
+			spin_unlock_bh(&priv->tx.tx_lock);
+
+			ath9k_htc_txstatus(priv, wmi_event);
+			break;
+		default:
+			break;
+		}
+
+		kfree_skb(skb);
+	} while (1);
 }
 
 void ath9k_fatal_work(struct work_struct *work)
@@ -153,10 +207,6 @@
 	struct wmi *wmi = (struct wmi *) priv;
 	struct wmi_cmd_hdr *hdr;
 	u16 cmd_id;
-	void *wmi_event;
-#ifdef CONFIG_ATH9K_HTC_DEBUGFS
-	__be32 txrate;
-#endif
 
 	if (unlikely(wmi->stopped))
 		goto free_skb;
@@ -165,26 +215,10 @@
 	cmd_id = be16_to_cpu(hdr->command_id);
 
 	if (cmd_id & 0x1000) {
-		wmi_event = skb_pull(skb, sizeof(struct wmi_cmd_hdr));
-		switch (cmd_id) {
-		case WMI_SWBA_EVENTID:
-			wmi->beacon_pending = *(u8 *)wmi_event;
-			tasklet_schedule(&wmi->drv_priv->swba_tasklet);
-			break;
-		case WMI_FATAL_EVENTID:
-			ieee80211_queue_work(wmi->drv_priv->hw,
-					     &wmi->drv_priv->fatal_work);
-			break;
-		case WMI_TXRATE_EVENTID:
-#ifdef CONFIG_ATH9K_HTC_DEBUGFS
-			txrate = ((struct wmi_event_txrate *)wmi_event)->txrate;
-			wmi->drv_priv->debug.txrate = be32_to_cpu(txrate);
-#endif
-			break;
-		default:
-			break;
-		}
-		kfree_skb(skb);
+		spin_lock(&wmi->wmi_lock);
+		__skb_queue_tail(&wmi->wmi_event_queue, skb);
+		spin_unlock(&wmi->wmi_lock);
+		tasklet_schedule(&wmi->wmi_event_tasklet);
 		return;
 	}
 
@@ -243,7 +277,7 @@
 	hdr->command_id = cpu_to_be16(cmd);
 	hdr->seq_no = cpu_to_be16(++wmi->tx_seq_id);
 
-	return htc_send(wmi->htc, skb, wmi->ctrl_epid, NULL);
+	return htc_send_epid(wmi->htc, skb, wmi->ctrl_epid);
 }
 
 int ath9k_wmi_cmd(struct wmi *wmi, enum wmi_cmd_id cmd_id,
diff -druN linux-2.6.39-libre/drivers/net/wireless/ath/ath9k/wmi.h linux-3.0-rc7-libre/drivers/net/wireless/ath/ath9k/wmi.h
--- linux-2.6.39-libre/drivers/net/wireless/ath/ath9k/wmi.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/ath/ath9k/wmi.h	2011-07-11 19:51:52.000000000 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010 Atheros Communications Inc.
+ * Copyright (c) 2010-2011 Atheros Communications Inc.
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
@@ -17,7 +17,6 @@
 #ifndef WMI_H
 #define WMI_H
 
-
 struct wmi_event_txrate {
 	__be32 txrate;
 	struct {
@@ -31,18 +30,65 @@
 	__be16 seq_no;
 } __packed;
 
+struct wmi_fw_version {
+	__be16 major;
+	__be16 minor;
+
+} __packed;
+
+struct wmi_event_swba {
+	__be64 tsf;
+	u8 beacon_pending;
+};
+
+/*
+ * 64 - HTC header - WMI header - 1 / txstatus
+ * And some other hdr. space is also accounted for.
+ * 12 seems to be the magic number.
+ */
+#define HTC_MAX_TX_STATUS 12
+
+#define ATH9K_HTC_TXSTAT_ACK        BIT(0)
+#define ATH9K_HTC_TXSTAT_FILT       BIT(1)
+#define ATH9K_HTC_TXSTAT_RTC_CTS    BIT(2)
+#define ATH9K_HTC_TXSTAT_MCS        BIT(3)
+#define ATH9K_HTC_TXSTAT_CW40       BIT(4)
+#define ATH9K_HTC_TXSTAT_SGI        BIT(5)
+
+/*
+ * Legacy rates are indicated as indices.
+ * HT rates are indicated as dot11 numbers.
+ * This allows us to resrict the rate field
+ * to 4 bits.
+ */
+#define ATH9K_HTC_TXSTAT_RATE       0x0f
+#define ATH9K_HTC_TXSTAT_RATE_S     0
+
+#define ATH9K_HTC_TXSTAT_EPID       0xf0
+#define ATH9K_HTC_TXSTAT_EPID_S     4
+
+struct __wmi_event_txstatus {
+	u8 cookie;
+	u8 ts_rate; /* Also holds EP ID */
+	u8 ts_flags;
+};
+
+struct wmi_event_txstatus {
+	u8 cnt;
+	struct __wmi_event_txstatus txstatus[HTC_MAX_TX_STATUS];
+} __packed;
+
 enum wmi_cmd_id {
 	WMI_ECHO_CMDID = 0x0001,
 	WMI_ACCESS_MEMORY_CMDID,
 
 	/* Commands to Target */
+	WMI_GET_FW_VERSION,
 	WMI_DISABLE_INTR_CMDID,
 	WMI_ENABLE_INTR_CMDID,
-	WMI_RX_LINK_CMDID,
 	WMI_ATH_INIT_CMDID,
 	WMI_ABORT_TXQ_CMDID,
 	WMI_STOP_TX_DMA_CMDID,
-	WMI_STOP_DMA_RECV_CMDID,
 	WMI_ABORT_TX_DMA_CMDID,
 	WMI_DRAIN_TXQ_CMDID,
 	WMI_DRAIN_TXQ_ALL_CMDID,
@@ -50,24 +96,22 @@
 	WMI_STOP_RECV_CMDID,
 	WMI_FLUSH_RECV_CMDID,
 	WMI_SET_MODE_CMDID,
-	WMI_RESET_CMDID,
 	WMI_NODE_CREATE_CMDID,
 	WMI_NODE_REMOVE_CMDID,
 	WMI_VAP_REMOVE_CMDID,
 	WMI_VAP_CREATE_CMDID,
-	WMI_BEACON_UPDATE_CMDID,
 	WMI_REG_READ_CMDID,
 	WMI_REG_WRITE_CMDID,
 	WMI_RC_STATE_CHANGE_CMDID,
 	WMI_RC_RATE_UPDATE_CMDID,
-	WMI_DEBUG_INFO_CMDID,
-	WMI_HOST_ATTACH,
 	WMI_TARGET_IC_UPDATE_CMDID,
-	WMI_TGT_STATS_CMDID,
 	WMI_TX_AGGR_ENABLE_CMDID,
 	WMI_TGT_DETACH_CMDID,
-	WMI_TGT_TXQ_ENABLE_CMDID,
-	WMI_AGGR_LIMIT_CMD = 0x0026,
+	WMI_NODE_UPDATE_CMDID,
+	WMI_INT_STATS_CMDID,
+	WMI_TX_STATS_CMDID,
+	WMI_RX_STATS_CMDID,
+	WMI_BITRATE_MASK_CMDID,
 };
 
 enum wmi_event_id {
@@ -76,9 +120,8 @@
 	WMI_FATAL_EVENTID,
 	WMI_TXTO_EVENTID,
 	WMI_BMISS_EVENTID,
-	WMI_WLAN_TXCOMP_EVENTID,
 	WMI_DELBA_EVENTID,
-	WMI_TXRATE_EVENTID,
+	WMI_TXSTATUS_EVENTID,
 };
 
 #define MAX_CMD_NUMBER 62
@@ -88,6 +131,12 @@
 	__be32 val;
 };
 
+struct ath9k_htc_tx_event {
+	int count;
+	struct __wmi_event_txstatus txs;
+	struct list_head list;
+};
+
 struct wmi {
 	struct ath9k_htc_priv *drv_priv;
 	struct htc_target *htc;
@@ -95,12 +144,16 @@
 	struct mutex op_mutex;
 	struct completion cmd_wait;
 	enum wmi_cmd_id last_cmd_id;
+	struct sk_buff_head wmi_event_queue;
+	struct tasklet_struct wmi_event_tasklet;
 	u16 tx_seq_id;
 	u8 *cmd_rsp_buf;
 	u32 cmd_rsp_len;
 	bool stopped;
 
-	u8 beacon_pending;
+	struct list_head pending_tx_events;
+	spinlock_t event_lock;
+
 	spinlock_t wmi_lock;
 
 	atomic_t mwrite_cnt;
@@ -117,8 +170,9 @@
 		  u8 *cmd_buf, u32 cmd_len,
 		  u8 *rsp_buf, u32 rsp_len,
 		  u32 timeout);
-void ath9k_swba_tasklet(unsigned long data);
+void ath9k_wmi_event_tasklet(unsigned long data);
 void ath9k_fatal_work(struct work_struct *work);
+void ath9k_wmi_event_drain(struct ath9k_htc_priv *priv);
 
 #define WMI_CMD(_wmi_cmd)						\
 	do {								\
diff -druN linux-2.6.39-libre/drivers/net/wireless/ath/ath9k/xmit.c linux-3.0-rc7-libre/drivers/net/wireless/ath/ath9k/xmit.c
--- linux-2.6.39-libre/drivers/net/wireless/ath/ath9k/xmit.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/ath/ath9k/xmit.c	2011-07-11 19:51:52.000000000 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008-2009 Atheros Communications Inc.
+ * Copyright (c) 2008-2011 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
@@ -357,6 +357,7 @@
 	struct ath_frame_info *fi;
 	int nframes;
 	u8 tidno;
+	bool clear_filter;
 
 	skb = bf->bf_mpdu;
 	hdr = (struct ieee80211_hdr *)skb->data;
@@ -441,22 +442,24 @@
 			/* transmit completion */
 			acked_cnt++;
 		} else {
-			if (!(tid->state & AGGR_CLEANUP) && retry) {
-				if (fi->retries < ATH_MAX_SW_RETRIES) {
-					ath_tx_set_retry(sc, txq, bf->bf_mpdu);
-					txpending = 1;
-				} else {
-					bf->bf_state.bf_type |= BUF_XRETRY;
-					txfail = 1;
-					sendbar = 1;
-					txfail_cnt++;
-				}
-			} else {
+			if ((tid->state & AGGR_CLEANUP) || !retry) {
 				/*
 				 * cleanup in progress, just fail
 				 * the un-acked sub-frames
 				 */
 				txfail = 1;
+			} else if (fi->retries < ATH_MAX_SW_RETRIES) {
+				if (!(ts->ts_status & ATH9K_TXERR_FILT) ||
+				    !an->sleeping)
+					ath_tx_set_retry(sc, txq, bf->bf_mpdu);
+
+				clear_filter = true;
+				txpending = 1;
+			} else {
+				bf->bf_state.bf_type |= BUF_XRETRY;
+				txfail = 1;
+				sendbar = 1;
+				txfail_cnt++;
 			}
 		}
 
@@ -496,6 +499,7 @@
 				!txfail, sendbar);
 		} else {
 			/* retry the un-acked ones */
+			ath9k_hw_set_clrdmask(sc->sc_ah, bf->bf_desc, false);
 			if (!(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA)) {
 				if (bf->bf_next == NULL && bf_last->bf_stale) {
 					struct ath_buf *tbf;
@@ -546,7 +550,12 @@
 
 	/* prepend un-acked frames to the beginning of the pending frame queue */
 	if (!list_empty(&bf_pending)) {
+		if (an->sleeping)
+			ieee80211_sta_set_tim(sta);
+
 		spin_lock_bh(&txq->axq_lock);
+		if (clear_filter)
+			tid->ac->clear_ps_filter = true;
 		list_splice(&bf_pending, &tid->buf_q);
 		ath_tx_queue_tid(txq, tid);
 		spin_unlock_bh(&txq->axq_lock);
@@ -816,6 +825,11 @@
 		bf = list_first_entry(&bf_q, struct ath_buf, list);
 		bf->bf_lastbf = list_entry(bf_q.prev, struct ath_buf, list);
 
+		if (tid->ac->clear_ps_filter) {
+			tid->ac->clear_ps_filter = false;
+			ath9k_hw_set_clrdmask(sc->sc_ah, bf->bf_desc, true);
+		}
+
 		/* if only one frame, send as non-aggregate */
 		if (bf == bf->bf_lastbf) {
 			fi = get_frame_info(bf->bf_mpdu);
@@ -896,6 +910,67 @@
 	ath_tx_flush_tid(sc, txtid);
 }
 
+bool ath_tx_aggr_sleep(struct ath_softc *sc, struct ath_node *an)
+{
+	struct ath_atx_tid *tid;
+	struct ath_atx_ac *ac;
+	struct ath_txq *txq;
+	bool buffered = false;
+	int tidno;
+
+	for (tidno = 0, tid = &an->tid[tidno];
+	     tidno < WME_NUM_TID; tidno++, tid++) {
+
+		if (!tid->sched)
+			continue;
+
+		ac = tid->ac;
+		txq = ac->txq;
+
+		spin_lock_bh(&txq->axq_lock);
+
+		if (!list_empty(&tid->buf_q))
+			buffered = true;
+
+		tid->sched = false;
+		list_del(&tid->list);
+
+		if (ac->sched) {
+			ac->sched = false;
+			list_del(&ac->list);
+		}
+
+		spin_unlock_bh(&txq->axq_lock);
+	}
+
+	return buffered;
+}
+
+void ath_tx_aggr_wakeup(struct ath_softc *sc, struct ath_node *an)
+{
+	struct ath_atx_tid *tid;
+	struct ath_atx_ac *ac;
+	struct ath_txq *txq;
+	int tidno;
+
+	for (tidno = 0, tid = &an->tid[tidno];
+	     tidno < WME_NUM_TID; tidno++, tid++) {
+
+		ac = tid->ac;
+		txq = ac->txq;
+
+		spin_lock_bh(&txq->axq_lock);
+		ac->clear_ps_filter = true;
+
+		if (!list_empty(&tid->buf_q) && !tid->paused) {
+			ath_tx_queue_tid(txq, tid);
+			ath_txq_schedule(sc, txq);
+		}
+
+		spin_unlock_bh(&txq->axq_lock);
+	}
+}
+
 void ath_tx_aggr_resume(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid)
 {
 	struct ath_atx_tid *txtid;
@@ -1451,7 +1526,7 @@
 	struct ieee80211_key_conf *hw_key = tx_info->control.hw_key;
 	struct ieee80211_hdr *hdr;
 	struct ath_frame_info *fi = get_frame_info(skb);
-	struct ath_node *an;
+	struct ath_node *an = NULL;
 	struct ath_atx_tid *tid;
 	enum ath9k_key_type keytype;
 	u16 seqno = 0;
@@ -1459,11 +1534,13 @@
 
 	keytype = ath9k_cmn_get_hw_crypto_keytype(skb);
 
+	if (sta)
+		an = (struct ath_node *) sta->drv_priv;
+
 	hdr = (struct ieee80211_hdr *)skb->data;
-	if (sta && ieee80211_is_data_qos(hdr->frame_control) &&
+	if (an && ieee80211_is_data_qos(hdr->frame_control) &&
 		conf_is_ht(&hw->conf) && (sc->sc_flags & SC_OP_TXAGGR)) {
 
-		an = (struct ath_node *) sta->drv_priv;
 		tidno = ieee80211_get_qos_ctl(hdr)[0] & IEEE80211_QOS_CTL_TID_MASK;
 
 		/*
@@ -1479,6 +1556,8 @@
 	memset(fi, 0, sizeof(*fi));
 	if (hw_key)
 		fi->keyix = hw_key->hw_key_idx;
+	else if (an && ieee80211_is_data(hdr->frame_control) && an->ps_key > 0)
+		fi->keyix = an->ps_key;
 	else
 		fi->keyix = ATH9K_TXKEYIX_INVALID;
 	fi->keytype = keytype;
@@ -1491,7 +1570,6 @@
 	struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
 	int flags = 0;
 
-	flags |= ATH9K_TXDESC_CLRDMASK; /* needed for crypto errors */
 	flags |= ATH9K_TXDESC_INTREQ;
 
 	if (tx_info->flags & IEEE80211_TX_CTL_NO_ACK)
@@ -1585,8 +1663,7 @@
 		rix = rates[i].idx;
 		series[i].Tries = rates[i].count;
 
-		if ((sc->config.ath_aggr_prot && bf_isaggr(bf)) ||
-		    (rates[i].flags & IEEE80211_TX_RC_USE_RTS_CTS)) {
+		    if (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) {
@@ -1655,8 +1732,6 @@
 				     !is_pspoll, ctsrate,
 				     0, series, 4, flags);
 
-	if (sc->config.ath_aggr_prot && flags)
-		ath9k_hw_set11n_burstduration(sc->sc_ah, bf->bf_desc, 8192);
 }
 
 static struct ath_buf *ath_tx_setup_buffer(struct ieee80211_hw *hw,
@@ -1754,6 +1829,9 @@
 		if (txctl->paprd)
 			bf->bf_state.bfs_paprd_timestamp = jiffies;
 
+		if (tx_info->flags & IEEE80211_TX_CTL_CLEAR_PS_FILT)
+			ath9k_hw_set_clrdmask(sc->sc_ah, bf->bf_desc, true);
+
 		ath_tx_send_normal(sc, txctl->txq, tid, &bf_head);
 	}
 
@@ -1767,6 +1845,7 @@
 	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
 	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
 	struct ieee80211_sta *sta = info->control.sta;
+	struct ieee80211_vif *vif = info->control.vif;
 	struct ath_softc *sc = hw->priv;
 	struct ath_txq *txq = txctl->txq;
 	struct ath_buf *bf;
@@ -1804,6 +1883,11 @@
 		memmove(skb->data, skb->data + padsize, padpos);
 	}
 
+	if ((vif && vif->type != NL80211_IFTYPE_AP &&
+	            vif->type != NL80211_IFTYPE_AP_VLAN) ||
+	    !ieee80211_is_data(hdr->frame_control))
+		info->flags |= IEEE80211_TX_CTL_CLEAR_PS_FILT;
+
 	setup_frame_info(hw, skb, frmlen);
 
 	/*
@@ -1980,7 +2064,7 @@
 		if (ieee80211_is_data(hdr->frame_control) &&
 		    (ts->ts_flags & (ATH9K_TX_DATA_UNDERRUN |
 		                     ATH9K_TX_DELIM_UNDERRUN)) &&
-		    ah->tx_trig_level >= sc->sc_ah->caps.tx_triglevel_max)
+		    ah->tx_trig_level >= sc->sc_ah->config.max_txtrig_level)
 			tx_info->status.rates[tx_rateindex].count =
 				hw->max_rate_tries;
 	}
@@ -2099,28 +2183,6 @@
 	}
 }
 
-static void ath_hw_pll_work(struct work_struct *work)
-{
-	struct ath_softc *sc = container_of(work, struct ath_softc,
-					    hw_pll_work.work);
-	static int count;
-
-	if (AR_SREV_9485(sc->sc_ah)) {
-		if (ar9003_get_pll_sqsum_dvc(sc->sc_ah) >= 0x40000) {
-			count++;
-
-			if (count == 3) {
-				/* Rx is hung for more than 500ms. Reset it */
-				ath_reset(sc, true);
-				count = 0;
-			}
-		} else
-			count = 0;
-
-		ieee80211_queue_delayed_work(sc->hw, &sc->hw_pll_work, HZ/5);
-	}
-}
-
 static void ath_tx_complete_poll_work(struct work_struct *work)
 {
 	struct ath_softc *sc = container_of(work, struct ath_softc,
@@ -2144,33 +2206,6 @@
 				} else {
 					txq->axq_tx_inprogress = true;
 				}
-			} else {
-				/* If the queue has pending buffers, then it
-				 * should be doing tx work (and have axq_depth).
-				 * Shouldn't get to this state I think..but
-				 * we do.
-				 */
-				if (!(sc->sc_flags & (SC_OP_OFFCHANNEL)) &&
-				    (txq->pending_frames > 0 ||
-				     !list_empty(&txq->axq_acq) ||
-				     txq->stopped)) {
-					ath_err(ath9k_hw_common(sc->sc_ah),
-						"txq: %p axq_qnum: %u,"
-						" mac80211_qnum: %i"
-						" axq_link: %p"
-						" pending frames: %i"
-						" axq_acq empty: %i"
-						" stopped: %i"
-						" axq_depth: 0  Attempting to"
-						" restart tx logic.\n",
-						txq, txq->axq_qnum,
-						txq->mac80211_qnum,
-						txq->axq_link,
-						txq->pending_frames,
-						list_empty(&txq->axq_acq),
-						txq->stopped);
-					ath_txq_schedule(sc, txq);
-				}
 			}
 			spin_unlock_bh(&txq->axq_lock);
 		}
@@ -2342,7 +2377,6 @@
 	}
 
 	INIT_DELAYED_WORK(&sc->tx_complete_work, ath_tx_complete_poll_work);
-	INIT_DELAYED_WORK(&sc->hw_pll_work, ath_hw_pll_work);
 
 	if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) {
 		error = ath_tx_edma_init(sc);
diff -druN linux-2.6.39-libre/drivers/net/wireless/ath/ath.h linux-3.0-rc7-libre/drivers/net/wireless/ath/ath.h
--- linux-2.6.39-libre/drivers/net/wireless/ath/ath.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/ath/ath.h	2011-07-11 19:51:52.000000000 -0400
@@ -119,17 +119,11 @@
 	void (*write)(void *, u32 val, u32 reg_offset);
 	void (*enable_write_buffer)(void *);
 	void (*write_flush) (void *);
+	u32 (*rmw)(void *, u32 reg_offset, u32 set, u32 clr);
 };
 
 struct ath_common;
-
-struct ath_bus_ops {
-	enum ath_bus_type ath_bus_type;
-	void (*read_cachesize)(struct ath_common *common, int *csz);
-	bool (*eeprom_read)(struct ath_common *common, u32 off, u16 *data);
-	void (*bt_coex_prep)(struct ath_common *common);
-	void (*extn_synch_en)(struct ath_common *common);
-};
+struct ath_bus_ops;
 
 struct ath_common {
 	void *ah;
diff -druN linux-2.6.39-libre/drivers/net/wireless/ath/carl9170/carl9170.h linux-3.0-rc7-libre/drivers/net/wireless/ath/carl9170/carl9170.h
--- linux-2.6.39-libre/drivers/net/wireless/ath/carl9170/carl9170.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/ath/carl9170/carl9170.h	2011-07-11 19:51:52.000000000 -0400
@@ -286,6 +286,10 @@
 		unsigned int tx_seq_table;
 	} fw;
 
+	/* interface configuration combinations */
+	struct ieee80211_iface_limit if_comb_limits[1];
+	struct ieee80211_iface_combination if_combs[1];
+
 	/* reset / stuck frames/queue detection */
 	struct work_struct restart_work;
 	struct work_struct ping_work;
@@ -448,6 +452,8 @@
 
 struct carl9170_sta_info {
 	bool ht_sta;
+	bool sleeping;
+	atomic_t pending_frames;
 	unsigned int ampdu_max_len;
 	struct carl9170_sta_tid *agg[CARL9170_NUM_TID];
 	struct carl9170_ba_stats stats[CARL9170_NUM_TID];
diff -druN linux-2.6.39-libre/drivers/net/wireless/ath/carl9170/fw.c linux-3.0-rc7-libre/drivers/net/wireless/ath/carl9170/fw.c
--- linux-2.6.39-libre/drivers/net/wireless/ath/carl9170/fw.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/ath/carl9170/fw.c	2011-07-11 19:51:52.000000000 -0400
@@ -151,6 +151,7 @@
 	const struct carl9170fw_chk_desc *chk_desc;
 	const struct carl9170fw_last_desc *last_desc;
 	const struct carl9170fw_txsq_desc *txsq_desc;
+	u16 if_comb_types;
 
 	last_desc = carl9170_fw_find_desc(ar, LAST_MAGIC,
 		sizeof(*last_desc), CARL9170FW_LAST_DESC_CUR_VER);
@@ -268,6 +269,9 @@
 	if (SUPP(CARL9170FW_WOL))
 		device_set_wakeup_enable(&ar->udev->dev, true);
 
+	if_comb_types = BIT(NL80211_IFTYPE_STATION) |
+			BIT(NL80211_IFTYPE_P2P_CLIENT);
+
 	ar->fw.vif_num = otus_desc->vif_num;
 	ar->fw.cmd_bufs = otus_desc->cmd_bufs;
 	ar->fw.address = le32_to_cpu(otus_desc->fw_address);
@@ -294,12 +298,25 @@
 		ar->hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_ADHOC);
 
 		if (SUPP(CARL9170FW_WLANTX_CAB)) {
-			ar->hw->wiphy->interface_modes |=
+			if_comb_types |=
 				BIT(NL80211_IFTYPE_AP) |
 				BIT(NL80211_IFTYPE_P2P_GO);
 		}
 	}
 
+	ar->if_comb_limits[0].max = ar->fw.vif_num;
+	ar->if_comb_limits[0].types = if_comb_types;
+
+	ar->if_combs[0].num_different_channels = 1;
+	ar->if_combs[0].max_interfaces = ar->fw.vif_num;
+	ar->if_combs[0].limits = ar->if_comb_limits;
+	ar->if_combs[0].n_limits = ARRAY_SIZE(ar->if_comb_limits);
+
+	ar->hw->wiphy->iface_combinations = ar->if_combs;
+	ar->hw->wiphy->n_iface_combinations = ARRAY_SIZE(ar->if_combs);
+
+	ar->hw->wiphy->interface_modes |= if_comb_types;
+
 	txsq_desc = carl9170_fw_find_desc(ar, TXSQ_MAGIC,
 		sizeof(*txsq_desc), CARL9170FW_TXSQ_DESC_CUR_VER);
 
diff -druN linux-2.6.39-libre/drivers/net/wireless/ath/carl9170/main.c linux-3.0-rc7-libre/drivers/net/wireless/ath/carl9170/main.c
--- linux-2.6.39-libre/drivers/net/wireless/ath/carl9170/main.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/ath/carl9170/main.c	2011-07-11 19:51:52.000000000 -0400
@@ -883,7 +883,7 @@
 	 * then checking the error flags, later.
 	 */
 
-	if (changed_flags & FIF_ALLMULTI && *new_flags & FIF_ALLMULTI)
+	if (*new_flags & FIF_ALLMULTI)
 		multicast = ~0ULL;
 
 	if (multicast != ar->cur_mc_hash)
@@ -1193,6 +1193,8 @@
 	struct carl9170_sta_info *sta_info = (void *) sta->drv_priv;
 	unsigned int i;
 
+	atomic_set(&sta_info->pending_frames, 0);
+
 	if (sta->ht_cap.ht_supported) {
 		if (sta->ht_cap.ampdu_density > 6) {
 			/*
@@ -1467,99 +1469,17 @@
 				   enum sta_notify_cmd cmd,
 				   struct ieee80211_sta *sta)
 {
-	struct ar9170 *ar = hw->priv;
 	struct carl9170_sta_info *sta_info = (void *) sta->drv_priv;
-	struct sk_buff *skb, *tmp;
-	struct sk_buff_head free;
-	int i;
 
 	switch (cmd) {
 	case STA_NOTIFY_SLEEP:
-		/*
-		 * Since the peer is no longer listening, we have to return
-		 * as many SKBs as possible back to the mac80211 stack.
-		 * It will deal with the retry procedure, once the peer
-		 * has become available again.
-		 *
-		 * NB: Ideally, the driver should return the all frames in
-		 * the correct, ascending order. However, I think that this
-		 * functionality should be implemented in the stack and not
-		 * here...
-		 */
-
-		__skb_queue_head_init(&free);
-
-		if (sta->ht_cap.ht_supported) {
-			rcu_read_lock();
-			for (i = 0; i < CARL9170_NUM_TID; i++) {
-				struct carl9170_sta_tid *tid_info;
-
-				tid_info = rcu_dereference(sta_info->agg[i]);
-
-				if (!tid_info)
-					continue;
-
-				spin_lock_bh(&ar->tx_ampdu_list_lock);
-				if (tid_info->state >
-				    CARL9170_TID_STATE_SUSPEND)
-					tid_info->state =
-						CARL9170_TID_STATE_SUSPEND;
-				spin_unlock_bh(&ar->tx_ampdu_list_lock);
-
-				spin_lock_bh(&tid_info->lock);
-				while ((skb = __skb_dequeue(&tid_info->queue)))
-					__skb_queue_tail(&free, skb);
-				spin_unlock_bh(&tid_info->lock);
-			}
-			rcu_read_unlock();
-		}
-
-		for (i = 0; i < ar->hw->queues; i++) {
-			spin_lock_bh(&ar->tx_pending[i].lock);
-			skb_queue_walk_safe(&ar->tx_pending[i], skb, tmp) {
-				struct _carl9170_tx_superframe *super;
-				struct ieee80211_hdr *hdr;
-				struct ieee80211_tx_info *info;
-
-				super = (void *) skb->data;
-				hdr = (void *) super->frame_data;
-
-				if (compare_ether_addr(hdr->addr1, sta->addr))
-					continue;
-
-				__skb_unlink(skb, &ar->tx_pending[i]);
-
-				info = IEEE80211_SKB_CB(skb);
-				if (info->flags & IEEE80211_TX_CTL_AMPDU)
-					atomic_dec(&ar->tx_ampdu_upload);
-
-				carl9170_tx_status(ar, skb, false);
-			}
-			spin_unlock_bh(&ar->tx_pending[i].lock);
-		}
-
-		while ((skb = __skb_dequeue(&free)))
-			carl9170_tx_status(ar, skb, false);
-
+		sta_info->sleeping = true;
+		if (atomic_read(&sta_info->pending_frames))
+			ieee80211_sta_block_awake(hw, sta, true);
 		break;
 
 	case STA_NOTIFY_AWAKE:
-		if (!sta->ht_cap.ht_supported)
-			return;
-
-		rcu_read_lock();
-		for (i = 0; i < CARL9170_NUM_TID; i++) {
-			struct carl9170_sta_tid *tid_info;
-
-			tid_info = rcu_dereference(sta_info->agg[i]);
-
-			if (!tid_info)
-				continue;
-
-			if ((tid_info->state == CARL9170_TID_STATE_SUSPEND))
-				tid_info->state = CARL9170_TID_STATE_IDLE;
-		}
-		rcu_read_unlock();
+		sta_info->sleeping = false;
 		break;
 	}
 }
@@ -1650,14 +1570,8 @@
 	INIT_LIST_HEAD(&ar->vif_list);
 	init_completion(&ar->tx_flush);
 
-	/*
-	 * Note:
-	 * IBSS/ADHOC and AP mode are only enabled, if the firmware
-	 * supports these modes. The code which will add the
-	 * additional interface_modes is in fw.c.
-	 */
-	hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
-				     BIT(NL80211_IFTYPE_P2P_CLIENT);
+	/* firmware decides which modes we support */
+	hw->wiphy->interface_modes = 0;
 
 	hw->flags |= IEEE80211_HW_RX_INCLUDES_FCS |
 		     IEEE80211_HW_REPORTS_TX_ACK_STATUS |
diff -druN linux-2.6.39-libre/drivers/net/wireless/ath/carl9170/tx.c linux-3.0-rc7-libre/drivers/net/wireless/ath/carl9170/tx.c
--- linux-2.6.39-libre/drivers/net/wireless/ath/carl9170/tx.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/ath/carl9170/tx.c	2011-07-11 19:51:52.000000000 -0400
@@ -104,12 +104,60 @@
 	spin_unlock_bh(&ar->tx_stats_lock);
 }
 
+/* needs rcu_read_lock */
+static struct ieee80211_sta *__carl9170_get_tx_sta(struct ar9170 *ar,
+						   struct sk_buff *skb)
+{
+	struct _carl9170_tx_superframe *super = (void *) skb->data;
+	struct ieee80211_hdr *hdr = (void *) super->frame_data;
+	struct ieee80211_vif *vif;
+	unsigned int vif_id;
+
+	vif_id = (super->s.misc & CARL9170_TX_SUPER_MISC_VIF_ID) >>
+		 CARL9170_TX_SUPER_MISC_VIF_ID_S;
+
+	if (WARN_ON_ONCE(vif_id >= AR9170_MAX_VIRTUAL_MAC))
+		return NULL;
+
+	vif = rcu_dereference(ar->vif_priv[vif_id].vif);
+	if (unlikely(!vif))
+		return NULL;
+
+	/*
+	 * Normally we should use wrappers like ieee80211_get_DA to get
+	 * the correct peer ieee80211_sta.
+	 *
+	 * But there is a problem with indirect traffic (broadcasts, or
+	 * data which is designated for other stations) in station mode.
+	 * The frame will be directed to the AP for distribution and not
+	 * to the actual destination.
+	 */
+
+	return ieee80211_find_sta(vif, hdr->addr1);
+}
+
+static void carl9170_tx_ps_unblock(struct ar9170 *ar, struct sk_buff *skb)
+{
+	struct ieee80211_sta *sta;
+	struct carl9170_sta_info *sta_info;
+
+	rcu_read_lock();
+	sta = __carl9170_get_tx_sta(ar, skb);
+	if (unlikely(!sta))
+		goto out_rcu;
+
+	sta_info = (struct carl9170_sta_info *) sta->drv_priv;
+	if (atomic_dec_return(&sta_info->pending_frames) == 0)
+		ieee80211_sta_block_awake(ar->hw, sta, false);
+
+out_rcu:
+	rcu_read_unlock();
+}
+
 static void carl9170_tx_accounting_free(struct ar9170 *ar, struct sk_buff *skb)
 {
-	struct ieee80211_tx_info *txinfo;
 	int queue;
 
-	txinfo = IEEE80211_SKB_CB(skb);
 	queue = skb_get_queue_mapping(skb);
 
 	spin_lock_bh(&ar->tx_stats_lock);
@@ -135,6 +183,7 @@
 	}
 
 	spin_unlock_bh(&ar->tx_stats_lock);
+
 	if (atomic_dec_and_test(&ar->tx_total_queued))
 		complete(&ar->tx_flush);
 }
@@ -329,13 +378,9 @@
 {
 	struct _carl9170_tx_superframe *super = (void *) skb->data;
 	struct ieee80211_hdr *hdr = (void *) super->frame_data;
-	struct ieee80211_tx_info *tx_info;
-	struct carl9170_tx_info *ar_info;
-	struct carl9170_sta_info *sta_info;
 	struct ieee80211_sta *sta;
+	struct carl9170_sta_info *sta_info;
 	struct carl9170_sta_tid *tid_info;
-	struct ieee80211_vif *vif;
-	unsigned int vif_id;
 	u8 tid;
 
 	if (!(txinfo->flags & IEEE80211_TX_CTL_AMPDU) ||
@@ -343,30 +388,8 @@
 	   (!(super->f.mac_control & cpu_to_le16(AR9170_TX_MAC_AGGR))))
 		return;
 
-	tx_info = IEEE80211_SKB_CB(skb);
-	ar_info = (void *) tx_info->rate_driver_data;
-
-	vif_id = (super->s.misc & CARL9170_TX_SUPER_MISC_VIF_ID) >>
-		 CARL9170_TX_SUPER_MISC_VIF_ID_S;
-
-	if (WARN_ON_ONCE(vif_id >= AR9170_MAX_VIRTUAL_MAC))
-		return;
-
 	rcu_read_lock();
-	vif = rcu_dereference(ar->vif_priv[vif_id].vif);
-	if (unlikely(!vif))
-		goto out_rcu;
-
-	/*
-	 * Normally we should use wrappers like ieee80211_get_DA to get
-	 * the correct peer ieee80211_sta.
-	 *
-	 * But there is a problem with indirect traffic (broadcasts, or
-	 * data which is designated for other stations) in station mode.
-	 * The frame will be directed to the AP for distribution and not
-	 * to the actual destination.
-	 */
-	sta = ieee80211_find_sta(vif, hdr->addr1);
+	sta = __carl9170_get_tx_sta(ar, skb);
 	if (unlikely(!sta))
 		goto out_rcu;
 
@@ -427,6 +450,7 @@
 	if (txinfo->flags & IEEE80211_TX_CTL_AMPDU)
 		carl9170_tx_status_process_ampdu(ar, skb, txinfo);
 
+	carl9170_tx_ps_unblock(ar, skb);
 	carl9170_tx_put_skb(skb);
 }
 
@@ -540,11 +564,7 @@
 	struct sk_buff *skb;
 	struct ieee80211_tx_info *txinfo;
 	struct carl9170_tx_info *arinfo;
-	struct _carl9170_tx_superframe *super;
 	struct ieee80211_sta *sta;
-	struct ieee80211_vif *vif;
-	struct ieee80211_hdr *hdr;
-	unsigned int vif_id;
 
 	rcu_read_lock();
 	list_for_each_entry_rcu(iter, &ar->tx_ampdu_list, list) {
@@ -562,20 +582,7 @@
 		    msecs_to_jiffies(CARL9170_QUEUE_TIMEOUT)))
 			goto unlock;
 
-		super = (void *) skb->data;
-		hdr = (void *) super->frame_data;
-
-		vif_id = (super->s.misc & CARL9170_TX_SUPER_MISC_VIF_ID) >>
-			 CARL9170_TX_SUPER_MISC_VIF_ID_S;
-
-		if (WARN_ON(vif_id >= AR9170_MAX_VIRTUAL_MAC))
-			goto unlock;
-
-		vif = rcu_dereference(ar->vif_priv[vif_id].vif);
-		if (WARN_ON(!vif))
-			goto unlock;
-
-		sta = ieee80211_find_sta(vif, hdr->addr1);
+		sta = __carl9170_get_tx_sta(ar, skb);
 		if (WARN_ON(!sta))
 			goto unlock;
 
@@ -611,7 +618,6 @@
 {
 	struct sk_buff *skb;
 	struct ieee80211_tx_info *txinfo;
-	struct carl9170_tx_info *arinfo;
 	unsigned int r, t, q;
 	bool success = true;
 
@@ -627,7 +633,6 @@
 	}
 
 	txinfo = IEEE80211_SKB_CB(skb);
-	arinfo = (void *) txinfo->rate_driver_data;
 
 	if (!(info & CARL9170_TX_STATUS_SUCCESS))
 		success = false;
@@ -1199,15 +1204,6 @@
 	arinfo = (void *) info->rate_driver_data;
 
 	arinfo->timeout = jiffies;
-
-	/*
-	 * increase ref count to "2".
-	 * Ref counting is the easiest way to solve the race between
-	 * the the urb's completion routine: carl9170_tx_callback and
-	 * wlan tx status functions: carl9170_tx_status/janitor.
-	 */
-	carl9170_tx_get_skb(skb);
-
 	return skb;
 
 err_unlock:
@@ -1228,6 +1224,36 @@
 	__carl9170_tx_process_status(ar, super->s.cookie, q);
 }
 
+static bool carl9170_tx_ps_drop(struct ar9170 *ar, struct sk_buff *skb)
+{
+	struct ieee80211_sta *sta;
+	struct carl9170_sta_info *sta_info;
+
+	rcu_read_lock();
+	sta = __carl9170_get_tx_sta(ar, skb);
+	if (!sta)
+		goto out_rcu;
+
+	sta_info = (void *) sta->drv_priv;
+	if (unlikely(sta_info->sleeping)) {
+		struct ieee80211_tx_info *tx_info;
+
+		rcu_read_unlock();
+
+		tx_info = IEEE80211_SKB_CB(skb);
+		if (tx_info->flags & IEEE80211_TX_CTL_AMPDU)
+			atomic_dec(&ar->tx_ampdu_upload);
+
+		tx_info->flags |= IEEE80211_TX_STAT_TX_FILTERED;
+		carl9170_tx_status(ar, skb, false);
+		return true;
+	}
+
+out_rcu:
+	rcu_read_unlock();
+	return false;
+}
+
 static void carl9170_tx(struct ar9170 *ar)
 {
 	struct sk_buff *skb;
@@ -1247,6 +1273,9 @@
 			if (unlikely(!skb))
 				break;
 
+			if (unlikely(carl9170_tx_ps_drop(ar, skb)))
+				continue;
+
 			atomic_inc(&ar->tx_total_pending);
 
 			q = __carl9170_get_queue(ar, i);
@@ -1256,6 +1285,16 @@
 			 */
 			skb_queue_tail(&ar->tx_status[q], skb);
 
+			/*
+			 * increase ref count to "2".
+			 * Ref counting is the easiest way to solve the
+			 * race between the urb's completion routine:
+			 *	carl9170_tx_callback
+			 * and wlan tx status functions:
+			 *	carl9170_tx_status/janitor.
+			 */
+			carl9170_tx_get_skb(skb);
+
 			carl9170_usb_tx(ar, skb);
 			schedule_garbagecollector = true;
 		}
@@ -1275,7 +1314,6 @@
 	struct carl9170_sta_info *sta_info;
 	struct carl9170_sta_tid *agg;
 	struct sk_buff *iter;
-	unsigned int max;
 	u16 tid, seq, qseq, off;
 	bool run = false;
 
@@ -1285,7 +1323,6 @@
 
 	rcu_read_lock();
 	agg = rcu_dereference(sta_info->agg[tid]);
-	max = sta_info->ampdu_max_len;
 
 	if (!agg)
 		goto err_unlock_rcu;
@@ -1368,6 +1405,11 @@
 	 * all ressouces which are associated with the frame.
 	 */
 
+	if (sta) {
+		struct carl9170_sta_info *stai = (void *) sta->drv_priv;
+		atomic_inc(&stai->pending_frames);
+	}
+
 	if (info->flags & IEEE80211_TX_CTL_AMPDU) {
 		run = carl9170_tx_ampdu_queue(ar, sta, skb);
 		if (run)
diff -druN linux-2.6.39-libre/drivers/net/wireless/ath/hw.c linux-3.0-rc7-libre/drivers/net/wireless/ath/hw.c
--- linux-2.6.39-libre/drivers/net/wireless/ath/hw.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/ath/hw.c	2011-07-11 19:51:52.000000000 -0400
@@ -43,7 +43,7 @@
  * set of  ~ ( MAC XOR BSSID ) for all bssids we handle.
  *
  * When you do this you are essentially computing the common bits of all your
- * BSSes. Later it is assumed the harware will "and" (&) the BSSID mask with
+ * BSSes. Later it is assumed the hardware will "and" (&) the BSSID mask with
  * the MAC address to obtain the relevant bits and compare the result with
  * (frame's BSSID & mask) to see if they match.
  *
@@ -71,8 +71,8 @@
  *             On loop iteration for BSSID-02:
  *             bssid_mask &= ~(0001   ^   1001)
  *             bssid_mask =   (1010)  & ~(0001 ^ 1001)
- *             bssid_mask =   (1010)  & ~(1001)
- *             bssid_mask =   (1010)  &  (0110)
+ *             bssid_mask =   (1010)  & ~(1000)
+ *             bssid_mask =   (1010)  &  (0111)
  *             bssid_mask =   0010
  *
  * A bssid_mask of 0010 means "only pay attention to the second least
@@ -102,11 +102,9 @@
  *
  * IFRAME-02:  0001 (we should allow)
  *
- *     allow = (0001 & 1010) == 1010
- *
  *     allow = (IFRAME-02 & bssid_mask) == (bssid_mask & MAC) ? 1 : 0;
  *  --> allow = (0001 & 0010) ==  (0010 & 0001) ? 1 :0;
- *  --> allow = (0010) == (0010)
+ *  --> allow = (0000) == (0000)
  *  --> allow = 1
  *
  * Other examples:
diff -druN linux-2.6.39-libre/drivers/net/wireless/ath/Kconfig linux-3.0-rc7-libre/drivers/net/wireless/ath/Kconfig
--- linux-2.6.39-libre/drivers/net/wireless/ath/Kconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/ath/Kconfig	2011-07-11 19:51:52.000000000 -0400
@@ -24,7 +24,6 @@
 
 source "drivers/net/wireless/ath/ath5k/Kconfig"
 source "drivers/net/wireless/ath/ath9k/Kconfig"
-source "drivers/net/wireless/ath/ar9170/Kconfig"
 source "drivers/net/wireless/ath/carl9170/Kconfig"
 
 endif
diff -druN linux-2.6.39-libre/drivers/net/wireless/ath/key.c linux-3.0-rc7-libre/drivers/net/wireless/ath/key.c
--- linux-2.6.39-libre/drivers/net/wireless/ath/key.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/ath/key.c	2011-07-11 19:51:52.000000000 -0400
@@ -23,6 +23,14 @@
 
 #define REG_READ			(common->ops->read)
 #define REG_WRITE(_ah, _reg, _val)	(common->ops->write)(_ah, _val, _reg)
+#define ENABLE_REGWRITE_BUFFER(_ah)			\
+	if (common->ops->enable_write_buffer)		\
+		common->ops->enable_write_buffer((_ah));
+
+#define REGWRITE_BUFFER_FLUSH(_ah)			\
+	if (common->ops->write_flush)			\
+		common->ops->write_flush((_ah));
+
 
 #define IEEE80211_WEP_NKID      4       /* number of key ids */
 
@@ -42,6 +50,8 @@
 
 	keyType = REG_READ(ah, AR_KEYTABLE_TYPE(entry));
 
+	ENABLE_REGWRITE_BUFFER(ah);
+
 	REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), 0);
 	REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), 0);
 	REG_WRITE(ah, AR_KEYTABLE_KEY2(entry), 0);
@@ -66,6 +76,8 @@
 
 	}
 
+	REGWRITE_BUFFER_FLUSH(ah);
+
 	return true;
 }
 EXPORT_SYMBOL(ath_hw_keyreset);
@@ -104,9 +116,13 @@
 	} else {
 		macLo = macHi = 0;
 	}
+	ENABLE_REGWRITE_BUFFER(ah);
+
 	REG_WRITE(ah, AR_KEYTABLE_MAC0(entry), macLo);
 	REG_WRITE(ah, AR_KEYTABLE_MAC1(entry), macHi | unicast_flag);
 
+	REGWRITE_BUFFER_FLUSH(ah);
+
 	return true;
 }
 
@@ -223,6 +239,8 @@
 			mic3 = get_unaligned_le16(k->kv_txmic + 0) & 0xffff;
 			mic4 = get_unaligned_le32(k->kv_txmic + 4);
 
+			ENABLE_REGWRITE_BUFFER(ah);
+
 			/* Write RX[31:0] and TX[31:16] */
 			REG_WRITE(ah, AR_KEYTABLE_KEY0(micentry), mic0);
 			REG_WRITE(ah, AR_KEYTABLE_KEY1(micentry), mic1);
@@ -236,6 +254,8 @@
 			REG_WRITE(ah, AR_KEYTABLE_TYPE(micentry),
 				  AR_KEYTABLE_TYPE_CLR);
 
+			REGWRITE_BUFFER_FLUSH(ah);
+
 		} else {
 			/*
 			 * TKIP uses four key cache entries (two for group
@@ -258,6 +278,8 @@
 			mic0 = get_unaligned_le32(k->kv_mic + 0);
 			mic2 = get_unaligned_le32(k->kv_mic + 4);
 
+			ENABLE_REGWRITE_BUFFER(ah);
+
 			/* Write MIC key[31:0] */
 			REG_WRITE(ah, AR_KEYTABLE_KEY0(micentry), mic0);
 			REG_WRITE(ah, AR_KEYTABLE_KEY1(micentry), 0);
@@ -270,8 +292,12 @@
 			REG_WRITE(ah, AR_KEYTABLE_KEY4(micentry), 0);
 			REG_WRITE(ah, AR_KEYTABLE_TYPE(micentry),
 				  AR_KEYTABLE_TYPE_CLR);
+
+			REGWRITE_BUFFER_FLUSH(ah);
 		}
 
+		ENABLE_REGWRITE_BUFFER(ah);
+
 		/* MAC address registers are reserved for the MIC entry */
 		REG_WRITE(ah, AR_KEYTABLE_MAC0(micentry), 0);
 		REG_WRITE(ah, AR_KEYTABLE_MAC1(micentry), 0);
@@ -283,7 +309,11 @@
 		 */
 		REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), key0);
 		REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), key1);
+
+		REGWRITE_BUFFER_FLUSH(ah);
 	} else {
+		ENABLE_REGWRITE_BUFFER(ah);
+
 		/* Write key[47:0] */
 		REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), key0);
 		REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), key1);
@@ -296,6 +326,8 @@
 		REG_WRITE(ah, AR_KEYTABLE_KEY4(entry), key4);
 		REG_WRITE(ah, AR_KEYTABLE_TYPE(entry), keyType);
 
+		REGWRITE_BUFFER_FLUSH(ah);
+
 		/* Write MAC address for the entry */
 		(void) ath_hw_keysetmac(common, entry, mac);
 	}
@@ -451,6 +483,9 @@
 	memset(&hk, 0, sizeof(hk));
 
 	switch (key->cipher) {
+	case 0:
+		hk.kv_type = ATH_CIPHER_CLR;
+		break;
 	case WLAN_CIPHER_SUITE_WEP40:
 	case WLAN_CIPHER_SUITE_WEP104:
 		hk.kv_type = ATH_CIPHER_WEP;
@@ -466,7 +501,8 @@
 	}
 
 	hk.kv_len = key->keylen;
-	memcpy(hk.kv_val, key->key, key->keylen);
+	if (key->keylen)
+		memcpy(hk.kv_val, key->key, key->keylen);
 
 	if (!(key->flags & IEEE80211_KEY_FLAG_PAIRWISE)) {
 		switch (vif->type) {
diff -druN linux-2.6.39-libre/drivers/net/wireless/ath/Makefile linux-3.0-rc7-libre/drivers/net/wireless/ath/Makefile
--- linux-2.6.39-libre/drivers/net/wireless/ath/Makefile	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/ath/Makefile	2011-07-11 19:51:52.000000000 -0400
@@ -1,6 +1,5 @@
 obj-$(CONFIG_ATH5K)		+= ath5k/
 obj-$(CONFIG_ATH9K_HW)		+= ath9k/
-obj-$(CONFIG_AR9170_USB)        += ar9170/
 obj-$(CONFIG_CARL9170)		+= carl9170/
 
 obj-$(CONFIG_ATH_COMMON)	+= ath.o
diff -druN linux-2.6.39-libre/drivers/net/wireless/ath/regd.c linux-3.0-rc7-libre/drivers/net/wireless/ath/regd.c
--- linux-2.6.39-libre/drivers/net/wireless/ath/regd.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/ath/regd.c	2011-07-11 19:51:52.000000000 -0400
@@ -97,8 +97,8 @@
 	}
 };
 
-/* Can be used by 0x67, 0x6A and 0x68 */
-static const struct ieee80211_regdomain ath_world_regdom_67_68_6A = {
+/* Can be used by 0x67, 0x68, 0x6A and 0x6C */
+static const struct ieee80211_regdomain ath_world_regdom_67_68_6A_6C = {
 	.n_reg_rules = 4,
 	.alpha2 =  "99",
 	.reg_rules = {
@@ -151,7 +151,8 @@
 	case 0x67:
 	case 0x68:
 	case 0x6A:
-		return &ath_world_regdom_67_68_6A;
+	case 0x6C:
+		return &ath_world_regdom_67_68_6A_6C;
 	default:
 		WARN_ON(1);
 		return ath_default_world_regdomain();
@@ -333,6 +334,7 @@
 	case 0x63:
 	case 0x66:
 	case 0x67:
+	case 0x6C:
 		ath_reg_apply_beaconing_flags(wiphy, initiator);
 		break;
 	case 0x68:
diff -druN linux-2.6.39-libre/drivers/net/wireless/ath/regd_common.h linux-3.0-rc7-libre/drivers/net/wireless/ath/regd_common.h
--- linux-2.6.39-libre/drivers/net/wireless/ath/regd_common.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/ath/regd_common.h	2011-07-11 19:51:52.000000000 -0400
@@ -86,6 +86,7 @@
 	WOR9_WORLD = 0x69,
 	WORA_WORLD = 0x6A,
 	WORB_WORLD = 0x6B,
+	WORC_WORLD = 0x6C,
 
 	MKK3_MKKB = 0x80,
 	MKK3_MKKA2 = 0x81,
@@ -282,6 +283,7 @@
 	{WOR9_WORLD, NO_CTL, NO_CTL},
 	{WORA_WORLD, NO_CTL, NO_CTL},
 	{WORB_WORLD, NO_CTL, NO_CTL},
+	{WORC_WORLD, NO_CTL, NO_CTL},
 };
 
 static struct country_code_to_enum_rd allCountries[] = {
diff -druN linux-2.6.39-libre/drivers/net/wireless/atmel_cs.c linux-3.0-rc7-libre/drivers/net/wireless/atmel_cs.c
--- linux-2.6.39-libre/drivers/net/wireless/atmel_cs.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/atmel_cs.c	2011-07-11 19:51:52.000000000 -0400
@@ -122,7 +122,7 @@
 {
 	local_info_t *dev;
 	int ret;
-	struct pcmcia_device_id *did;
+	const struct pcmcia_device_id *did;
 
 	dev = link->priv;
 	did = dev_get_drvdata(&link->dev);
@@ -211,7 +211,7 @@
 	.prod_id_hash = { (vh1), (vh2), 0, 0 }, \
         .driver_info = (kernel_ulong_t)(info), }
 
-static struct pcmcia_device_id atmel_ids[] = {
+static const struct pcmcia_device_id atmel_ids[] = {
 	PCMCIA_DEVICE_MANF_CARD_INFO(0x0101, 0x0620, ATMEL_FW_TYPE_502_3COM),
 	PCMCIA_DEVICE_MANF_CARD_INFO(0x0101, 0x0696, ATMEL_FW_TYPE_502_3COM),
 	PCMCIA_DEVICE_MANF_CARD_INFO(0x01bf, 0x3302, ATMEL_FW_TYPE_502E),
diff -druN linux-2.6.39-libre/drivers/net/wireless/b43/b43.h linux-3.0-rc7-libre/drivers/net/wireless/b43/b43.h
--- linux-2.6.39-libre/drivers/net/wireless/b43/b43.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/b43/b43.h	2011-07-11 19:51:52.000000000 -0400
@@ -567,6 +567,8 @@
 	struct b43_dmaring *tx_ring_mcast; /* Multicast */
 
 	struct b43_dmaring *rx_ring;
+
+	u32 translation; /* Routing bits */
 };
 
 struct b43_pio_txqueue;
@@ -648,8 +650,8 @@
 	char errors[B43_NR_FWTYPES][128];
 	/* Temporary buffer for storing the firmware name. */
 	char fwname[64];
-	/* A fatal error occurred while requesting. Firmware reqest
-	 * can not continue, as any other reqest will also fail. */
+	/* A fatal error occurred while requesting. Firmware request
+	 * can not continue, as any other request will also fail. */
 	int fatal_failure;
 };
 
@@ -705,7 +707,7 @@
 
 /* Data structure for one wireless device (802.11 core) */
 struct b43_wldev {
-	struct ssb_device *dev;
+	struct ssb_device *sdev;
 	struct b43_wl *wl;
 
 	/* The device initialization status.
@@ -879,22 +881,34 @@
 
 static inline u16 b43_read16(struct b43_wldev *dev, u16 offset)
 {
-	return ssb_read16(dev->dev, offset);
+	return ssb_read16(dev->sdev, offset);
 }
 
 static inline void b43_write16(struct b43_wldev *dev, u16 offset, u16 value)
 {
-	ssb_write16(dev->dev, offset, value);
+	ssb_write16(dev->sdev, offset, value);
 }
 
 static inline u32 b43_read32(struct b43_wldev *dev, u16 offset)
 {
-	return ssb_read32(dev->dev, offset);
+	return ssb_read32(dev->sdev, offset);
 }
 
 static inline void b43_write32(struct b43_wldev *dev, u16 offset, u32 value)
 {
-	ssb_write32(dev->dev, offset, value);
+	ssb_write32(dev->sdev, offset, value);
+}
+
+static inline void b43_block_read(struct b43_wldev *dev, void *buffer,
+				 size_t count, u16 offset, u8 reg_width)
+{
+	ssb_block_read(dev->sdev, buffer, count, offset, reg_width);
+}
+
+static inline void b43_block_write(struct b43_wldev *dev, const void *buffer,
+				   size_t count, u16 offset, u8 reg_width)
+{
+	ssb_block_write(dev->sdev, buffer, count, offset, reg_width);
 }
 
 static inline bool b43_using_pio_transfers(struct b43_wldev *dev)
diff -druN linux-2.6.39-libre/drivers/net/wireless/b43/dma.c linux-3.0-rc7-libre/drivers/net/wireless/b43/dma.c
--- linux-2.6.39-libre/drivers/net/wireless/b43/dma.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/b43/dma.c	2011-07-11 19:51:52.000000000 -0400
@@ -80,7 +80,7 @@
 	addr = (u32) (dmaaddr & ~SSB_DMA_TRANSLATION_MASK);
 	addrext = (u32) (dmaaddr & SSB_DMA_TRANSLATION_MASK)
 	    >> SSB_DMA_TRANSLATION_SHIFT;
-	addr |= ssb_dma_translation(ring->dev->dev);
+	addr |= ring->dev->dma.translation;
 	ctl = bufsize & B43_DMA32_DCTL_BYTECNT;
 	if (slot == ring->nr_slots - 1)
 		ctl |= B43_DMA32_DCTL_DTABLEEND;
@@ -174,7 +174,7 @@
 	addrhi = (((u64) dmaaddr >> 32) & ~SSB_DMA_TRANSLATION_MASK);
 	addrext = (((u64) dmaaddr >> 32) & SSB_DMA_TRANSLATION_MASK)
 	    >> SSB_DMA_TRANSLATION_SHIFT;
-	addrhi |= (ssb_dma_translation(ring->dev->dev) << 1);
+	addrhi |= (ring->dev->dma.translation << 1);
 	if (slot == ring->nr_slots - 1)
 		ctl0 |= B43_DMA64_DCTL0_DTABLEEND;
 	if (start)
@@ -333,10 +333,10 @@
 	dma_addr_t dmaaddr;
 
 	if (tx) {
-		dmaaddr = dma_map_single(ring->dev->dev->dma_dev,
+		dmaaddr = dma_map_single(ring->dev->sdev->dma_dev,
 					 buf, len, DMA_TO_DEVICE);
 	} else {
-		dmaaddr = dma_map_single(ring->dev->dev->dma_dev,
+		dmaaddr = dma_map_single(ring->dev->sdev->dma_dev,
 					 buf, len, DMA_FROM_DEVICE);
 	}
 
@@ -348,10 +348,10 @@
 			  dma_addr_t addr, size_t len, int tx)
 {
 	if (tx) {
-		dma_unmap_single(ring->dev->dev->dma_dev,
+		dma_unmap_single(ring->dev->sdev->dma_dev,
 				 addr, len, DMA_TO_DEVICE);
 	} else {
-		dma_unmap_single(ring->dev->dev->dma_dev,
+		dma_unmap_single(ring->dev->sdev->dma_dev,
 				 addr, len, DMA_FROM_DEVICE);
 	}
 }
@@ -361,7 +361,7 @@
 				 dma_addr_t addr, size_t len)
 {
 	B43_WARN_ON(ring->tx);
-	dma_sync_single_for_cpu(ring->dev->dev->dma_dev,
+	dma_sync_single_for_cpu(ring->dev->sdev->dma_dev,
 				    addr, len, DMA_FROM_DEVICE);
 }
 
@@ -370,7 +370,7 @@
 				    dma_addr_t addr, size_t len)
 {
 	B43_WARN_ON(ring->tx);
-	dma_sync_single_for_device(ring->dev->dev->dma_dev,
+	dma_sync_single_for_device(ring->dev->sdev->dma_dev,
 				   addr, len, DMA_FROM_DEVICE);
 }
 
@@ -401,7 +401,7 @@
 	 */
 	if (ring->type == B43_DMA_64BIT)
 		flags |= GFP_DMA;
-	ring->descbase = dma_alloc_coherent(ring->dev->dev->dma_dev,
+	ring->descbase = dma_alloc_coherent(ring->dev->sdev->dma_dev,
 					    B43_DMA_RINGMEMSIZE,
 					    &(ring->dmabase), flags);
 	if (!ring->descbase) {
@@ -415,7 +415,7 @@
 
 static void free_ringmemory(struct b43_dmaring *ring)
 {
-	dma_free_coherent(ring->dev->dev->dma_dev, B43_DMA_RINGMEMSIZE,
+	dma_free_coherent(ring->dev->sdev->dma_dev, B43_DMA_RINGMEMSIZE,
 			  ring->descbase, ring->dmabase);
 }
 
@@ -523,7 +523,7 @@
 				  dma_addr_t addr,
 				  size_t buffersize, bool dma_to_device)
 {
-	if (unlikely(dma_mapping_error(ring->dev->dev->dma_dev, addr)))
+	if (unlikely(dma_mapping_error(ring->dev->sdev->dma_dev, addr)))
 		return 1;
 
 	switch (ring->type) {
@@ -658,7 +658,7 @@
 	int err = 0;
 	u32 value;
 	u32 addrext;
-	u32 trans = ssb_dma_translation(ring->dev->dev);
+	u32 trans = ring->dev->dma.translation;
 
 	if (ring->tx) {
 		if (ring->type == B43_DMA_64BIT) {
@@ -869,7 +869,7 @@
 			goto err_kfree_meta;
 
 		/* test for ability to dma to txhdr_cache */
-		dma_test = dma_map_single(dev->dev->dma_dev,
+		dma_test = dma_map_single(dev->sdev->dma_dev,
 					  ring->txhdr_cache,
 					  b43_txhdr_size(dev),
 					  DMA_TO_DEVICE);
@@ -884,7 +884,7 @@
 			if (!ring->txhdr_cache)
 				goto err_kfree_meta;
 
-			dma_test = dma_map_single(dev->dev->dma_dev,
+			dma_test = dma_map_single(dev->sdev->dma_dev,
 						  ring->txhdr_cache,
 						  b43_txhdr_size(dev),
 						  DMA_TO_DEVICE);
@@ -898,7 +898,7 @@
 			}
 		}
 
-		dma_unmap_single(dev->dev->dma_dev,
+		dma_unmap_single(dev->sdev->dma_dev,
 				 dma_test, b43_txhdr_size(dev),
 				 DMA_TO_DEVICE);
 	}
@@ -1013,9 +1013,9 @@
 	/* Try to set the DMA mask. If it fails, try falling back to a
 	 * lower mask, as we can always also support a lower one. */
 	while (1) {
-		err = dma_set_mask(dev->dev->dma_dev, mask);
+		err = dma_set_mask(dev->sdev->dma_dev, mask);
 		if (!err) {
-			err = dma_set_coherent_mask(dev->dev->dma_dev, mask);
+			err = dma_set_coherent_mask(dev->sdev->dma_dev, mask);
 			if (!err)
 				break;
 		}
@@ -1055,6 +1055,7 @@
 	err = b43_dma_set_mask(dev, dmamask);
 	if (err)
 		return err;
+	dma->translation = ssb_dma_translation(dev->sdev);
 
 	err = -ENOMEM;
 	/* setup TX DMA channels. */
@@ -1084,7 +1085,7 @@
 		goto err_destroy_mcast;
 
 	/* No support for the TX status DMA ring. */
-	B43_WARN_ON(dev->dev->id.revision < 5);
+	B43_WARN_ON(dev->sdev->id.revision < 5);
 
 	b43dbg(dev->wl, "%u-bit DMA initialized\n",
 	       (unsigned int)type);
diff -druN linux-2.6.39-libre/drivers/net/wireless/b43/leds.c linux-3.0-rc7-libre/drivers/net/wireless/b43/leds.c
--- linux-2.6.39-libre/drivers/net/wireless/b43/leds.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/b43/leds.c	2011-07-11 19:51:52.000000000 -0400
@@ -138,7 +138,7 @@
 	led->led_dev.default_trigger = default_trigger;
 	led->led_dev.brightness_set = b43_led_brightness_set;
 
-	err = led_classdev_register(dev->dev->dev, &led->led_dev);
+	err = led_classdev_register(dev->sdev->dev, &led->led_dev);
 	if (err) {
 		b43warn(dev->wl, "LEDs: Failed to register %s\n", name);
 		led->wl = NULL;
@@ -215,7 +215,7 @@
 				  enum b43_led_behaviour *behaviour,
 				  bool *activelow)
 {
-	struct ssb_bus *bus = dev->dev->bus;
+	struct ssb_bus *bus = dev->sdev->bus;
 	u8 sprom[4];
 
 	sprom[0] = bus->sprom.gpio0;
diff -druN linux-2.6.39-libre/drivers/net/wireless/b43/lo.c linux-3.0-rc7-libre/drivers/net/wireless/b43/lo.c
--- linux-2.6.39-libre/drivers/net/wireless/b43/lo.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/b43/lo.c	2011-07-11 19:51:52.000000000 -0400
@@ -98,7 +98,7 @@
 		rfover |= pga;
 		rfover |= lna;
 		rfover |= trsw_rx;
-		if ((dev->dev->bus->sprom.boardflags_lo & B43_BFL_EXTLNA)
+		if ((dev->sdev->bus->sprom.boardflags_lo & B43_BFL_EXTLNA)
 		    && phy->rev > 6)
 			rfover |= B43_PHY_RFOVERVAL_EXTLNA;
 
@@ -387,7 +387,7 @@
 static void lo_measure_setup(struct b43_wldev *dev,
 			     struct lo_g_saved_values *sav)
 {
-	struct ssb_sprom *sprom = &dev->dev->bus->sprom;
+	struct ssb_sprom *sprom = &dev->sdev->bus->sprom;
 	struct b43_phy *phy = &dev->phy;
 	struct b43_phy_g *gphy = phy->g;
 	struct b43_txpower_lo_control *lo = gphy->lo_control;
diff -druN linux-2.6.39-libre/drivers/net/wireless/b43/main.c linux-3.0-rc7-libre/drivers/net/wireless/b43/main.c
--- linux-2.6.39-libre/drivers/net/wireless/b43/main.c	2011-05-19 02:13:30.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/b43/main.c	2011-07-21 06:55:56.000000000 -0400
@@ -541,7 +541,7 @@
 {
 	u32 low, high;
 
-	B43_WARN_ON(dev->dev->id.revision < 3);
+	B43_WARN_ON(dev->sdev->id.revision < 3);
 
 	/* The hardware guarantees us an atomic read, if we
 	 * read the low register first. */
@@ -579,7 +579,7 @@
 {
 	u32 low, high;
 
-	B43_WARN_ON(dev->dev->id.revision < 3);
+	B43_WARN_ON(dev->sdev->id.revision < 3);
 
 	low = tsf;
 	high = (tsf >> 32);
@@ -707,7 +707,7 @@
 		b43_ram_write(dev, i * 4, buffer[i]);
 
 	b43_write16(dev, 0x0568, 0x0000);
-	if (dev->dev->id.revision < 11)
+	if (dev->sdev->id.revision < 11)
 		b43_write16(dev, 0x07C0, 0x0000);
 	else
 		b43_write16(dev, 0x07C0, 0x0100);
@@ -1125,7 +1125,7 @@
 	b43_write32(dev, B43_MMIO_MACCTL, macctl);
 	/* Commit write */
 	b43_read32(dev, B43_MMIO_MACCTL);
-	if (awake && dev->dev->id.revision >= 5) {
+	if (awake && dev->sdev->id.revision >= 5) {
 		/* Wait for the microcode to wake up. */
 		for (i = 0; i < 100; i++) {
 			ucstat = b43_shm_read16(dev, B43_SHM_SHARED,
@@ -1137,29 +1137,35 @@
 	}
 }
 
-void b43_wireless_core_reset(struct b43_wldev *dev, u32 flags)
+static void b43_ssb_wireless_core_reset(struct b43_wldev *dev, u32 flags)
 {
 	u32 tmslow;
-	u32 macctl;
 
 	flags |= B43_TMSLOW_PHYCLKEN;
 	flags |= B43_TMSLOW_PHYRESET;
 	if (dev->phy.type == B43_PHYTYPE_N)
 		flags |= B43_TMSLOW_PHY_BANDWIDTH_20MHZ; /* Make 20 MHz def */
-	ssb_device_enable(dev->dev, flags);
+	ssb_device_enable(dev->sdev, flags);
 	msleep(2);		/* Wait for the PLL to turn on. */
 
 	/* Now take the PHY out of Reset again */
-	tmslow = ssb_read32(dev->dev, SSB_TMSLOW);
+	tmslow = ssb_read32(dev->sdev, SSB_TMSLOW);
 	tmslow |= SSB_TMSLOW_FGC;
 	tmslow &= ~B43_TMSLOW_PHYRESET;
-	ssb_write32(dev->dev, SSB_TMSLOW, tmslow);
-	ssb_read32(dev->dev, SSB_TMSLOW);	/* flush */
+	ssb_write32(dev->sdev, SSB_TMSLOW, tmslow);
+	ssb_read32(dev->sdev, SSB_TMSLOW);	/* flush */
 	msleep(1);
 	tmslow &= ~SSB_TMSLOW_FGC;
-	ssb_write32(dev->dev, SSB_TMSLOW, tmslow);
-	ssb_read32(dev->dev, SSB_TMSLOW);	/* flush */
+	ssb_write32(dev->sdev, SSB_TMSLOW, tmslow);
+	ssb_read32(dev->sdev, SSB_TMSLOW);	/* flush */
 	msleep(1);
+}
+
+void b43_wireless_core_reset(struct b43_wldev *dev, u32 flags)
+{
+	u32 macctl;
+
+	b43_ssb_wireless_core_reset(dev, flags);
 
 	/* Turn Analog ON, but only if we already know the PHY-type.
 	 * This protects against very early setup where we don't know the
@@ -1208,7 +1214,7 @@
 {
 	u32 dummy;
 
-	if (dev->dev->id.revision < 5)
+	if (dev->sdev->id.revision < 5)
 		return;
 	/* Read all entries from the microcode TXstatus FIFO
 	 * and throw them away.
@@ -1414,9 +1420,9 @@
 
 	/* Get the mask of available antennas. */
 	if (dev->phy.gmode)
-		antenna_mask = dev->dev->bus->sprom.ant_available_bg;
+		antenna_mask = dev->sdev->bus->sprom.ant_available_bg;
 	else
-		antenna_mask = dev->dev->bus->sprom.ant_available_a;
+		antenna_mask = dev->sdev->bus->sprom.ant_available_a;
 
 	if (!(antenna_mask & (1 << (antenna_nr - 1)))) {
 		/* This antenna is not available. Fall back to default. */
@@ -1631,7 +1637,7 @@
 	mutex_lock(&wl->mutex);
 	dev = wl->current_dev;
 	if (likely(dev && (b43_status(dev) >= B43_STAT_INITIALIZED))) {
-		if (dev->dev->bus->bustype == SSB_BUSTYPE_SDIO) {
+		if (dev->sdev->bus->bustype == SSB_BUSTYPE_SDIO) {
 			/* wl->mutex is enough. */
 			b43_do_beacon_update_trigger_work(dev);
 			mmiowb();
@@ -1676,7 +1682,7 @@
 static void b43_set_beacon_int(struct b43_wldev *dev, u16 beacon_int)
 {
 	b43_time_lock(dev);
-	if (dev->dev->id.revision >= 3) {
+	if (dev->sdev->id.revision >= 3) {
 		b43_write32(dev, B43_MMIO_TSF_CFP_REP, (beacon_int << 16));
 		b43_write32(dev, B43_MMIO_TSF_CFP_START, (beacon_int << 10));
 	} else {
@@ -2047,7 +2053,7 @@
 		B43_WARN_ON(1);
 		return -ENOSYS;
 	}
-	err = maybe_reject_firmware(&blob, ctx->fwname, ctx->dev->dev->dev);
+	err = maybe_reject_firmware(&blob, ctx->fwname, ctx->dev->sdev->dev);
 	if (err == -ENOENT) {
 		snprintf(ctx->errors[ctx->req_type],
 			 sizeof(ctx->errors[ctx->req_type]),
@@ -2097,13 +2103,12 @@
 {
 	struct b43_wldev *dev = ctx->dev;
 	struct b43_firmware *fw = &ctx->dev->fw;
-	const u8 rev = ctx->dev->dev->id.revision;
+	const u8 rev = ctx->dev->sdev->id.revision;
 	const char *filename;
 	u32 tmshigh;
 	int err;
 
 	/* Get microcode */
-	tmshigh = ssb_read32(dev->dev, SSB_TMSHIGH);
 	if ((rev >= 5) && (rev <= 10))
 		filename = "ucode5";
 	else if ((rev >= 11) && (rev <= 12))
@@ -2142,6 +2147,7 @@
 	switch (dev->phy.type) {
 	case B43_PHYTYPE_A:
 		if ((rev >= 5) && (rev <= 10)) {
+			tmshigh = ssb_read32(dev->sdev, SSB_TMSHIGH);
 			if (tmshigh & B43_TMSHIGH_HAVE_2GHZ_PHY)
 				filename = "a0g1initvals5";
 			else
@@ -2186,6 +2192,7 @@
 	switch (dev->phy.type) {
 	case B43_PHYTYPE_A:
 		if ((rev >= 5) && (rev <= 10)) {
+			tmshigh = ssb_read32(dev->sdev, SSB_TMSHIGH);
 			if (tmshigh & B43_TMSHIGH_HAVE_2GHZ_PHY)
 				filename = "a0g1bsinitvals5";
 			else
@@ -2436,7 +2443,7 @@
 
 	snprintf(wiphy->fw_version, sizeof(wiphy->fw_version), "%u.%u",
 			dev->fw.rev, dev->fw.patch);
-	wiphy->hw_version = dev->dev->id.coreid;
+	wiphy->hw_version = dev->sdev->id.coreid;
 
 	if (b43_is_old_txhdr_format(dev)) {
 		/* We're over the deadline, but we keep support for old fw
@@ -2552,10 +2559,20 @@
 /* Initialize the GPIOs
  * http://bcm-specs.sipsolutions.net/GPIO
  */
+static struct ssb_device *b43_ssb_gpio_dev(struct b43_wldev *dev)
+{
+	struct ssb_bus *bus = dev->sdev->bus;
+
+#ifdef CONFIG_SSB_DRIVER_PCICORE
+	return (bus->chipco.dev ? bus->chipco.dev : bus->pcicore.dev);
+#else
+	return bus->chipco.dev;
+#endif
+}
+
 static int b43_gpio_init(struct b43_wldev *dev)
 {
-	struct ssb_bus *bus = dev->dev->bus;
-	struct ssb_device *gpiodev, *pcidev = NULL;
+	struct ssb_device *gpiodev;
 	u32 mask, set;
 
 	b43_write32(dev, B43_MMIO_MACCTL, b43_read32(dev, B43_MMIO_MACCTL)
@@ -2566,7 +2583,7 @@
 
 	mask = 0x0000001F;
 	set = 0x0000000F;
-	if (dev->dev->bus->chip_id == 0x4301) {
+	if (dev->sdev->bus->chip_id == 0x4301) {
 		mask |= 0x0060;
 		set |= 0x0060;
 	}
@@ -2577,25 +2594,21 @@
 		mask |= 0x0180;
 		set |= 0x0180;
 	}
-	if (dev->dev->bus->sprom.boardflags_lo & B43_BFL_PACTRL) {
+	if (dev->sdev->bus->sprom.boardflags_lo & B43_BFL_PACTRL) {
 		b43_write16(dev, B43_MMIO_GPIO_MASK,
 			    b43_read16(dev, B43_MMIO_GPIO_MASK)
 			    | 0x0200);
 		mask |= 0x0200;
 		set |= 0x0200;
 	}
-	if (dev->dev->id.revision >= 2)
+	if (dev->sdev->id.revision >= 2)
 		mask |= 0x0010;	/* FIXME: This is redundant. */
 
-#ifdef CONFIG_SSB_DRIVER_PCICORE
-	pcidev = bus->pcicore.dev;
-#endif
-	gpiodev = bus->chipco.dev ? : pcidev;
-	if (!gpiodev)
-		return 0;
-	ssb_write32(gpiodev, B43_GPIO_CONTROL,
-		    (ssb_read32(gpiodev, B43_GPIO_CONTROL)
-		     & mask) | set);
+	gpiodev = b43_ssb_gpio_dev(dev);
+	if (gpiodev)
+		ssb_write32(gpiodev, B43_GPIO_CONTROL,
+			    (ssb_read32(gpiodev, B43_GPIO_CONTROL)
+			     & mask) | set);
 
 	return 0;
 }
@@ -2603,16 +2616,11 @@
 /* Turn off all GPIO stuff. Call this on module unload, for example. */
 static void b43_gpio_cleanup(struct b43_wldev *dev)
 {
-	struct ssb_bus *bus = dev->dev->bus;
-	struct ssb_device *gpiodev, *pcidev = NULL;
+	struct ssb_device *gpiodev;
 
-#ifdef CONFIG_SSB_DRIVER_PCICORE
-	pcidev = bus->pcicore.dev;
-#endif
-	gpiodev = bus->chipco.dev ? : pcidev;
-	if (!gpiodev)
-		return;
-	ssb_write32(gpiodev, B43_GPIO_CONTROL, 0);
+	gpiodev = b43_ssb_gpio_dev(dev);
+	if (gpiodev)
+		ssb_write32(gpiodev, B43_GPIO_CONTROL, 0);
 }
 
 /* http://bcm-specs.sipsolutions.net/EnableMac */
@@ -2681,6 +2689,17 @@
 	dev->mac_suspended++;
 }
 
+/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/MacPhyClkSet */
+void b43_mac_phy_clock_set(struct b43_wldev *dev, bool on)
+{
+	u32 tmslow = ssb_read32(dev->sdev, SSB_TMSLOW);
+	if (on)
+		tmslow |= B43_TMSLOW_MACPHYCLKEN;
+	else
+		tmslow &= ~B43_TMSLOW_MACPHYCLKEN;
+	ssb_write32(dev->sdev, SSB_TMSLOW, tmslow);
+}
+
 static void b43_adjust_opmode(struct b43_wldev *dev)
 {
 	struct b43_wl *wl = dev->wl;
@@ -2717,15 +2736,15 @@
 	/* Workaround: On old hardware the HW-MAC-address-filter
 	 * doesn't work properly, so always run promisc in filter
 	 * it in software. */
-	if (dev->dev->id.revision <= 4)
+	if (dev->sdev->id.revision <= 4)
 		ctl |= B43_MACCTL_PROMISC;
 
 	b43_write32(dev, B43_MMIO_MACCTL, ctl);
 
 	cfp_pretbtt = 2;
 	if ((ctl & B43_MACCTL_INFRA) && !(ctl & B43_MACCTL_AP)) {
-		if (dev->dev->bus->chip_id == 0x4306 &&
-		    dev->dev->bus->chip_rev == 3)
+		if (dev->sdev->bus->chip_id == 0x4306 &&
+		    dev->sdev->bus->chip_rev == 3)
 			cfp_pretbtt = 100;
 		else
 			cfp_pretbtt = 50;
@@ -2837,7 +2856,7 @@
 {
 	struct b43_phy *phy = &dev->phy;
 	int err;
-	u32 value32, macctl;
+	u32 macctl;
 	u16 value16;
 
 	/* Initialize the MAC control */
@@ -2883,7 +2902,7 @@
 		b43_write16(dev, 0x005E, value16);
 	}
 	b43_write32(dev, 0x0100, 0x01000000);
-	if (dev->dev->id.revision < 5)
+	if (dev->sdev->id.revision < 5)
 		b43_write32(dev, 0x010C, 0x01000000);
 
 	b43_write32(dev, B43_MMIO_MACCTL, b43_read32(dev, B43_MMIO_MACCTL)
@@ -2898,7 +2917,7 @@
 	/* Initially set the wireless operation mode. */
 	b43_adjust_opmode(dev);
 
-	if (dev->dev->id.revision < 3) {
+	if (dev->sdev->id.revision < 3) {
 		b43_write16(dev, 0x060E, 0x0000);
 		b43_write16(dev, 0x0610, 0x8000);
 		b43_write16(dev, 0x0604, 0x0000);
@@ -2915,12 +2934,10 @@
 	b43_write32(dev, B43_MMIO_DMA4_IRQ_MASK, 0x0000DC00);
 	b43_write32(dev, B43_MMIO_DMA5_IRQ_MASK, 0x0000DC00);
 
-	value32 = ssb_read32(dev->dev, SSB_TMSLOW);
-	value32 |= 0x00100000;
-	ssb_write32(dev->dev, SSB_TMSLOW, value32);
+	b43_mac_phy_clock_set(dev, true);
 
 	b43_write16(dev, B43_MMIO_POWERUP_DELAY,
-		    dev->dev->bus->chipco.fast_pwrup_delay);
+		    dev->sdev->bus->chipco.fast_pwrup_delay);
 
 	err = 0;
 	b43dbg(dev->wl, "Chip initialized\n");
@@ -3083,7 +3100,7 @@
 	b43_shm_write32(dev, B43_SHM_SHARED, 0, backup0);
 	b43_shm_write32(dev, B43_SHM_SHARED, 4, backup4);
 
-	if ((dev->dev->id.revision >= 3) && (dev->dev->id.revision <= 10)) {
+	if ((dev->sdev->id.revision >= 3) && (dev->sdev->id.revision <= 10)) {
 		/* The 32bit register shadows the two 16bit registers
 		 * with update sideeffects. Validate this. */
 		b43_write16(dev, B43_MMIO_TSF_CFP_START, 0xAAAA);
@@ -3436,7 +3453,7 @@
 
 static void b43_put_phy_into_reset(struct b43_wldev *dev)
 {
-	struct ssb_device *sdev = dev->dev;
+	struct ssb_device *sdev = dev->sdev;
 	u32 tmslow;
 
 	tmslow = ssb_read32(sdev, SSB_TMSLOW);
@@ -3932,7 +3949,7 @@
 
 	/* Disable interrupts on the device. */
 	b43_set_status(dev, B43_STAT_INITIALIZED);
-	if (dev->dev->bus->bustype == SSB_BUSTYPE_SDIO) {
+	if (dev->sdev->bus->bustype == SSB_BUSTYPE_SDIO) {
 		/* wl->mutex is locked. That is enough. */
 		b43_write32(dev, B43_MMIO_GEN_IRQ_MASK, 0);
 		b43_read32(dev, B43_MMIO_GEN_IRQ_MASK);	/* Flush */
@@ -3945,11 +3962,11 @@
 	/* Synchronize and free the interrupt handlers. Unlock to avoid deadlocks. */
 	orig_dev = dev;
 	mutex_unlock(&wl->mutex);
-	if (dev->dev->bus->bustype == SSB_BUSTYPE_SDIO) {
+	if (dev->sdev->bus->bustype == SSB_BUSTYPE_SDIO) {
 		b43_sdio_free_irq(dev);
 	} else {
-		synchronize_irq(dev->dev->irq);
-		free_irq(dev->dev->irq, dev);
+		synchronize_irq(dev->sdev->irq);
+		free_irq(dev->sdev->irq, dev);
 	}
 	mutex_lock(&wl->mutex);
 	dev = wl->current_dev;
@@ -3982,18 +3999,19 @@
 	B43_WARN_ON(b43_status(dev) != B43_STAT_INITIALIZED);
 
 	drain_txstatus_queue(dev);
-	if (dev->dev->bus->bustype == SSB_BUSTYPE_SDIO) {
+	if (dev->sdev->bus->bustype == SSB_BUSTYPE_SDIO) {
 		err = b43_sdio_request_irq(dev, b43_sdio_interrupt_handler);
 		if (err) {
 			b43err(dev->wl, "Cannot request SDIO IRQ\n");
 			goto out;
 		}
 	} else {
-		err = request_threaded_irq(dev->dev->irq, b43_interrupt_handler,
+		err = request_threaded_irq(dev->sdev->irq, b43_interrupt_handler,
 					   b43_interrupt_thread_handler,
 					   IRQF_SHARED, KBUILD_MODNAME, dev);
 		if (err) {
-			b43err(dev->wl, "Cannot request IRQ-%d\n", dev->dev->irq);
+			b43err(dev->wl, "Cannot request IRQ-%d\n",
+			       dev->sdev->irq);
 			goto out;
 		}
 	}
@@ -4073,10 +4091,10 @@
 	       analog_type, phy_type, phy_rev);
 
 	/* Get RADIO versioning */
-	if (dev->dev->bus->chip_id == 0x4317) {
-		if (dev->dev->bus->chip_rev == 0)
+	if (dev->sdev->bus->chip_id == 0x4317) {
+		if (dev->sdev->bus->chip_rev == 0)
 			tmp = 0x3205017F;
-		else if (dev->dev->bus->chip_rev == 1)
+		else if (dev->sdev->bus->chip_rev == 1)
 			tmp = 0x4205017F;
 		else
 			tmp = 0x5205017F;
@@ -4181,7 +4199,7 @@
 
 static void b43_bluetooth_coext_enable(struct b43_wldev *dev)
 {
-	struct ssb_sprom *sprom = &dev->dev->bus->sprom;
+	struct ssb_sprom *sprom = &dev->sdev->bus->sprom;
 	u64 hf;
 
 	if (!modparam_btcoex)
@@ -4208,33 +4226,18 @@
 
 static void b43_imcfglo_timeouts_workaround(struct b43_wldev *dev)
 {
-#ifdef CONFIG_SSB_DRIVER_PCICORE
-	struct ssb_bus *bus = dev->dev->bus;
+	struct ssb_bus *bus = dev->sdev->bus;
 	u32 tmp;
 
-	if (bus->pcicore.dev &&
-	    bus->pcicore.dev->id.coreid == SSB_DEV_PCI &&
-	    bus->pcicore.dev->id.revision <= 5) {
-		/* IMCFGLO timeouts workaround. */
-		tmp = ssb_read32(dev->dev, SSB_IMCFGLO);
-		switch (bus->bustype) {
-		case SSB_BUSTYPE_PCI:
-		case SSB_BUSTYPE_PCMCIA:
-			tmp &= ~SSB_IMCFGLO_REQTO;
-			tmp &= ~SSB_IMCFGLO_SERTO;
-			tmp |= 0x32;
-			break;
-		case SSB_BUSTYPE_SSB:
-			tmp &= ~SSB_IMCFGLO_REQTO;
-			tmp &= ~SSB_IMCFGLO_SERTO;
-			tmp |= 0x53;
-			break;
-		default:
-			break;
-		}
-		ssb_write32(dev->dev, SSB_IMCFGLO, tmp);
+	if ((bus->chip_id == 0x4311 && bus->chip_rev == 2) ||
+	    (bus->chip_id == 0x4312)) {
+		tmp = ssb_read32(dev->sdev, SSB_IMCFGLO);
+		tmp &= ~SSB_IMCFGLO_REQTO;
+		tmp &= ~SSB_IMCFGLO_SERTO;
+		tmp |= 0x3;
+		ssb_write32(dev->sdev, SSB_IMCFGLO, tmp);
+		ssb_commit_settings(bus);
 	}
-#endif /* CONFIG_SSB_DRIVER_PCICORE */
 }
 
 static void b43_set_synth_pu_delay(struct b43_wldev *dev, bool idle)
@@ -4302,14 +4305,14 @@
 		dev->wl->current_beacon = NULL;
 	}
 
-	ssb_device_disable(dev->dev, 0);
-	ssb_bus_may_powerdown(dev->dev->bus);
+	ssb_device_disable(dev->sdev, 0);
+	ssb_bus_may_powerdown(dev->sdev->bus);
 }
 
 /* Initialize a wireless core */
 static int b43_wireless_core_init(struct b43_wldev *dev)
 {
-	struct ssb_bus *bus = dev->dev->bus;
+	struct ssb_bus *bus = dev->sdev->bus;
 	struct ssb_sprom *sprom = &bus->sprom;
 	struct b43_phy *phy = &dev->phy;
 	int err;
@@ -4321,7 +4324,7 @@
 	err = ssb_bus_powerup(bus, 0);
 	if (err)
 		goto out;
-	if (!ssb_device_is_enabled(dev->dev)) {
+	if (!ssb_device_is_enabled(dev->sdev)) {
 		tmp = phy->gmode ? B43_TMSLOW_GMODE : 0;
 		b43_wireless_core_reset(dev, tmp);
 	}
@@ -4331,7 +4334,7 @@
 	phy->ops->prepare_structs(dev);
 
 	/* Enable IRQ routing to this device. */
-	ssb_pcicore_dev_irqvecs_enable(&bus->pcicore, dev->dev);
+	ssb_pcicore_dev_irqvecs_enable(&bus->pcicore, dev->sdev);
 
 	b43_imcfglo_timeouts_workaround(dev);
 	b43_bluetooth_coext_disable(dev);
@@ -4344,7 +4347,7 @@
 	if (err)
 		goto err_busdown;
 	b43_shm_write16(dev, B43_SHM_SHARED,
-			B43_SHM_SH_WLCOREREV, dev->dev->id.revision);
+			B43_SHM_SH_WLCOREREV, dev->sdev->id.revision);
 	hf = b43_hf_read(dev);
 	if (phy->type == B43_PHYTYPE_G) {
 		hf |= B43_HF_SYMW;
@@ -4391,8 +4394,8 @@
 	/* Maximum Contention Window */
 	b43_shm_write16(dev, B43_SHM_SCRATCH, B43_SHM_SC_MAXCONT, 0x3FF);
 
-	if ((dev->dev->bus->bustype == SSB_BUSTYPE_PCMCIA) ||
-	    (dev->dev->bus->bustype == SSB_BUSTYPE_SDIO) ||
+	if ((dev->sdev->bus->bustype == SSB_BUSTYPE_PCMCIA) ||
+	    (dev->sdev->bus->bustype == SSB_BUSTYPE_SDIO) ||
 	    dev->use_pio) {
 		dev->__using_pio_transfers = 1;
 		err = b43_pio_init(dev);
@@ -4729,7 +4732,7 @@
 static int b43_wireless_core_attach(struct b43_wldev *dev)
 {
 	struct b43_wl *wl = dev->wl;
-	struct ssb_bus *bus = dev->dev->bus;
+	struct ssb_bus *bus = dev->sdev->bus;
 	struct pci_dev *pdev = (bus->bustype == SSB_BUSTYPE_PCI) ? bus->host_pci : NULL;
 	int err;
 	bool have_2ghz_phy = 0, have_5ghz_phy = 0;
@@ -4748,10 +4751,10 @@
 		goto out;
 	}
 	/* Get the PHY type. */
-	if (dev->dev->id.revision >= 5) {
+	if (dev->sdev->id.revision >= 5) {
 		u32 tmshigh;
 
-		tmshigh = ssb_read32(dev->dev, SSB_TMSHIGH);
+		tmshigh = ssb_read32(dev->sdev, SSB_TMSHIGH);
 		have_2ghz_phy = !!(tmshigh & B43_TMSHIGH_HAVE_2GHZ_PHY);
 		have_5ghz_phy = !!(tmshigh & B43_TMSHIGH_HAVE_5GHZ_PHY);
 	} else
@@ -4824,7 +4827,7 @@
 	INIT_WORK(&dev->restart_work, b43_chip_reset);
 
 	dev->phy.ops->switch_analog(dev, 0);
-	ssb_device_disable(dev->dev, 0);
+	ssb_device_disable(dev->sdev, 0);
 	ssb_bus_may_powerdown(bus);
 
 out:
@@ -4858,31 +4861,14 @@
 static int b43_one_core_attach(struct ssb_device *dev, struct b43_wl *wl)
 {
 	struct b43_wldev *wldev;
-	struct pci_dev *pdev;
 	int err = -ENOMEM;
 
-	if (!list_empty(&wl->devlist)) {
-		/* We are not the first core on this chip. */
-		pdev = (dev->bus->bustype == SSB_BUSTYPE_PCI) ? dev->bus->host_pci : NULL;
-		/* Only special chips support more than one wireless
-		 * core, although some of the other chips have more than
-		 * one wireless core as well. Check for this and
-		 * bail out early.
-		 */
-		if (!pdev ||
-		    ((pdev->device != 0x4321) &&
-		     (pdev->device != 0x4313) && (pdev->device != 0x431A))) {
-			b43dbg(wl, "Ignoring unconnected 802.11 core\n");
-			return -ENODEV;
-		}
-	}
-
 	wldev = kzalloc(sizeof(*wldev), GFP_KERNEL);
 	if (!wldev)
 		goto out;
 
 	wldev->use_pio = b43_modparam_pio;
-	wldev->dev = dev;
+	wldev->sdev = dev;
 	wldev->wl = wl;
 	b43_set_status(wldev, B43_STAT_UNINIT);
 	wldev->bad_frames_preempt = modparam_bad_frames_preempt;
@@ -4943,19 +4929,16 @@
 	ieee80211_free_hw(hw);
 }
 
-static int b43_wireless_init(struct ssb_device *dev)
+static struct b43_wl *b43_wireless_init(struct ssb_device *dev)
 {
 	struct ssb_sprom *sprom = &dev->bus->sprom;
 	struct ieee80211_hw *hw;
 	struct b43_wl *wl;
-	int err = -ENOMEM;
-
-	b43_sprom_fixup(dev->bus);
 
 	hw = ieee80211_alloc_hw(sizeof(*wl), &b43_hw_ops);
 	if (!hw) {
 		b43err(NULL, "Could not allocate ieee80211 device\n");
-		goto out;
+		return ERR_PTR(-ENOMEM);
 	}
 	wl = hw_to_b43_wl(hw);
 
@@ -4989,15 +4972,12 @@
 	INIT_WORK(&wl->tx_work, b43_tx_work);
 	skb_queue_head_init(&wl->tx_queue);
 
-	ssb_set_devtypedata(dev, wl);
 	b43info(wl, "Broadcom %04X WLAN found (core revision %u)\n",
 		dev->bus->chip_id, dev->id.revision);
-	err = 0;
-out:
-	return err;
+	return wl;
 }
 
-static int b43_probe(struct ssb_device *dev, const struct ssb_device_id *id)
+static int b43_ssb_probe(struct ssb_device *dev, const struct ssb_device_id *id)
 {
 	struct b43_wl *wl;
 	int err;
@@ -5007,11 +4987,14 @@
 	if (!wl) {
 		/* Probing the first core. Must setup common struct b43_wl */
 		first = 1;
-		err = b43_wireless_init(dev);
-		if (err)
+		b43_sprom_fixup(dev->bus);
+		wl = b43_wireless_init(dev);
+		if (IS_ERR(wl)) {
+			err = PTR_ERR(wl);
 			goto out;
-		wl = ssb_get_devtypedata(dev);
-		B43_WARN_ON(!wl);
+		}
+		ssb_set_devtypedata(dev, wl);
+		B43_WARN_ON(ssb_get_devtypedata(dev) != wl);
 	}
 	err = b43_one_core_attach(dev, wl);
 	if (err)
@@ -5035,7 +5018,7 @@
 	return err;
 }
 
-static void b43_remove(struct ssb_device *dev)
+static void b43_ssb_remove(struct ssb_device *dev)
 {
 	struct b43_wl *wl = ssb_get_devtypedata(dev);
 	struct b43_wldev *wldev = ssb_get_drvdata(dev);
@@ -5078,8 +5061,8 @@
 static struct ssb_driver b43_ssb_driver = {
 	.name		= KBUILD_MODNAME,
 	.id_table	= b43_ssb_tbl,
-	.probe		= b43_probe,
-	.remove		= b43_remove,
+	.probe		= b43_ssb_probe,
+	.remove		= b43_ssb_remove,
 };
 
 static void b43_print_driverinfo(void)
diff -druN linux-2.6.39-libre/drivers/net/wireless/b43/main.h linux-3.0-rc7-libre/drivers/net/wireless/b43/main.h
--- linux-2.6.39-libre/drivers/net/wireless/b43/main.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/b43/main.h	2011-07-11 19:51:52.000000000 -0400
@@ -133,6 +133,7 @@
 
 void b43_mac_suspend(struct b43_wldev *dev);
 void b43_mac_enable(struct b43_wldev *dev);
+void b43_mac_phy_clock_set(struct b43_wldev *dev, bool on);
 
 
 struct b43_request_fw_context;
diff -druN linux-2.6.39-libre/drivers/net/wireless/b43/pcmcia.c linux-3.0-rc7-libre/drivers/net/wireless/b43/pcmcia.c
--- linux-2.6.39-libre/drivers/net/wireless/b43/pcmcia.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/b43/pcmcia.c	2011-07-11 19:51:52.000000000 -0400
@@ -32,7 +32,7 @@
 #include <pcmcia/cisreg.h>
 
 
-static /*const */ struct pcmcia_device_id b43_pcmcia_tbl[] = {
+static const struct pcmcia_device_id b43_pcmcia_tbl[] = {
 	PCMCIA_DEVICE_MANF_CARD(0x2D0, 0x448),
 	PCMCIA_DEVICE_MANF_CARD(0x2D0, 0x476),
 	PCMCIA_DEVICE_NULL,
diff -druN linux-2.6.39-libre/drivers/net/wireless/b43/phy_a.c linux-3.0-rc7-libre/drivers/net/wireless/b43/phy_a.c
--- linux-2.6.39-libre/drivers/net/wireless/b43/phy_a.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/b43/phy_a.c	2011-07-11 19:51:52.000000000 -0400
@@ -265,7 +265,7 @@
 
 void b43_phy_inita(struct b43_wldev *dev)
 {
-	struct ssb_bus *bus = dev->dev->bus;
+	struct ssb_bus *bus = dev->sdev->bus;
 	struct b43_phy *phy = &dev->phy;
 
 	/* This lowlevel A-PHY init is also called from G-PHY init.
@@ -311,7 +311,7 @@
 	}
 
 	if ((phy->type == B43_PHYTYPE_G) &&
-	    (dev->dev->bus->sprom.boardflags_lo & B43_BFL_PACTRL)) {
+	    (dev->sdev->bus->sprom.boardflags_lo & B43_BFL_PACTRL)) {
 		b43_phy_maskset(dev, B43_PHY_OFDM(0x6E), 0xE000, 0x3CF);
 	}
 }
@@ -323,17 +323,17 @@
 	struct b43_phy_a *aphy = phy->a;
 	s16 pab0, pab1, pab2;
 
-	pab0 = (s16) (dev->dev->bus->sprom.pa1b0);
-	pab1 = (s16) (dev->dev->bus->sprom.pa1b1);
-	pab2 = (s16) (dev->dev->bus->sprom.pa1b2);
+	pab0 = (s16) (dev->sdev->bus->sprom.pa1b0);
+	pab1 = (s16) (dev->sdev->bus->sprom.pa1b1);
+	pab2 = (s16) (dev->sdev->bus->sprom.pa1b2);
 
 	if (pab0 != 0 && pab1 != 0 && pab2 != 0 &&
 	    pab0 != -1 && pab1 != -1 && pab2 != -1) {
 		/* The pabX values are set in SPROM. Use them. */
-		if ((s8) dev->dev->bus->sprom.itssi_a != 0 &&
-		    (s8) dev->dev->bus->sprom.itssi_a != -1)
+		if ((s8) dev->sdev->bus->sprom.itssi_a != 0 &&
+		    (s8) dev->sdev->bus->sprom.itssi_a != -1)
 			aphy->tgt_idle_tssi =
-			    (s8) (dev->dev->bus->sprom.itssi_a);
+			    (s8) (dev->sdev->bus->sprom.itssi_a);
 		else
 			aphy->tgt_idle_tssi = 62;
 		aphy->tssi2dbm = b43_generate_dyn_tssi2dbm_tab(dev, pab0,
diff -druN linux-2.6.39-libre/drivers/net/wireless/b43/phy_common.c linux-3.0-rc7-libre/drivers/net/wireless/b43/phy_common.c
--- linux-2.6.39-libre/drivers/net/wireless/b43/phy_common.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/b43/phy_common.c	2011-07-11 19:51:52.000000000 -0400
@@ -168,7 +168,7 @@
 	B43_WARN_ON(dev->phy.phy_locked);
 	dev->phy.phy_locked = 1;
 #endif
-	B43_WARN_ON(dev->dev->id.revision < 3);
+	B43_WARN_ON(dev->sdev->id.revision < 3);
 
 	if (!b43_is_mode(dev->wl, NL80211_IFTYPE_AP))
 		b43_power_saving_ctl_bits(dev, B43_PS_AWAKE);
@@ -180,7 +180,7 @@
 	B43_WARN_ON(!dev->phy.phy_locked);
 	dev->phy.phy_locked = 0;
 #endif
-	B43_WARN_ON(dev->dev->id.revision < 3);
+	B43_WARN_ON(dev->sdev->id.revision < 3);
 
 	if (!b43_is_mode(dev->wl, NL80211_IFTYPE_AP))
 		b43_power_saving_ctl_bits(dev, 0);
@@ -368,8 +368,8 @@
 	/* The next check will be needed in two seconds, or later. */
 	phy->next_txpwr_check_time = round_jiffies(now + (HZ * 2));
 
-	if ((dev->dev->bus->boardinfo.vendor == SSB_BOARDVENDOR_BCM) &&
-	    (dev->dev->bus->boardinfo.type == SSB_BOARD_BU4306))
+	if ((dev->sdev->bus->boardinfo.vendor == SSB_BOARDVENDOR_BCM) &&
+	    (dev->sdev->bus->boardinfo.type == SSB_BOARD_BU4306))
 		return; /* No software txpower adjustment needed */
 
 	result = phy->ops->recalc_txpower(dev, !!(flags & B43_TXPWR_IGNORE_TSSI));
diff -druN linux-2.6.39-libre/drivers/net/wireless/b43/phy_g.c linux-3.0-rc7-libre/drivers/net/wireless/b43/phy_g.c
--- linux-2.6.39-libre/drivers/net/wireless/b43/phy_g.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/b43/phy_g.c	2011-07-11 19:51:52.000000000 -0400
@@ -718,7 +718,7 @@
 	B43_WARN_ON(phy->type != B43_PHYTYPE_G);
 
 	if (!phy->gmode ||
-	    !(dev->dev->bus->sprom.boardflags_lo & B43_BFL_RSSI)) {
+	    !(dev->sdev->bus->sprom.boardflags_lo & B43_BFL_RSSI)) {
 		tmp16 = b43_nrssi_hw_read(dev, 0x20);
 		if (tmp16 >= 0x20)
 			tmp16 -= 0x40;
@@ -1114,7 +1114,7 @@
 {
 	struct b43_phy *phy = &dev->phy;
 	struct b43_phy_g *gphy = phy->g;
-	struct ssb_sprom *sprom = &(dev->dev->bus->sprom);
+	struct ssb_sprom *sprom = &(dev->sdev->bus->sprom);
 
 	if (!phy->gmode)
 		return 0;
@@ -1491,7 +1491,7 @@
 
 static void b43_phy_initb5(struct b43_wldev *dev)
 {
-	struct ssb_bus *bus = dev->dev->bus;
+	struct ssb_bus *bus = dev->sdev->bus;
 	struct b43_phy *phy = &dev->phy;
 	struct b43_phy_g *gphy = phy->g;
 	u16 offset, value;
@@ -1620,7 +1620,7 @@
 		b43_radio_write16(dev, 0x5A, 0x88);
 		b43_radio_write16(dev, 0x5B, 0x6B);
 		b43_radio_write16(dev, 0x5C, 0x0F);
-		if (dev->dev->bus->sprom.boardflags_lo & B43_BFL_ALTIQ) {
+		if (dev->sdev->bus->sprom.boardflags_lo & B43_BFL_ALTIQ) {
 			b43_radio_write16(dev, 0x5D, 0xFA);
 			b43_radio_write16(dev, 0x5E, 0xD8);
 		} else {
@@ -1787,7 +1787,7 @@
 	b43_phy_set(dev, B43_PHY_RFOVER, 0x0100);
 	b43_phy_mask(dev, B43_PHY_RFOVERVAL, 0xCFFF);
 
-	if (dev->dev->bus->sprom.boardflags_lo & B43_BFL_EXTLNA) {
+	if (dev->sdev->bus->sprom.boardflags_lo & B43_BFL_EXTLNA) {
 		if (phy->rev >= 7) {
 			b43_phy_set(dev, B43_PHY_RFOVER, 0x0800);
 			b43_phy_set(dev, B43_PHY_RFOVERVAL, 0x8000);
@@ -1922,7 +1922,7 @@
 /* Initialize B/G PHY power control */
 static void b43_phy_init_pctl(struct b43_wldev *dev)
 {
-	struct ssb_bus *bus = dev->dev->bus;
+	struct ssb_bus *bus = dev->sdev->bus;
 	struct b43_phy *phy = &dev->phy;
 	struct b43_phy_g *gphy = phy->g;
 	struct b43_rfatt old_rfatt;
@@ -2053,7 +2053,7 @@
 	if (phy->rev >= 6) {
 		b43_phy_maskset(dev, B43_PHY_CCK(0x36), 0x0FFF, (gphy->lo_control->tx_bias << 12));
 	}
-	if (dev->dev->bus->sprom.boardflags_lo & B43_BFL_PACTRL)
+	if (dev->sdev->bus->sprom.boardflags_lo & B43_BFL_PACTRL)
 		b43_phy_write(dev, B43_PHY_CCK(0x2E), 0x8075);
 	else
 		b43_phy_write(dev, B43_PHY_CCK(0x2E), 0x807F);
@@ -2066,7 +2066,7 @@
 		b43_phy_write(dev, B43_PHY_LO_MASK, 0x8078);
 	}
 
-	if (!(dev->dev->bus->sprom.boardflags_lo & B43_BFL_RSSI)) {
+	if (!(dev->sdev->bus->sprom.boardflags_lo & B43_BFL_RSSI)) {
 		/* The specs state to update the NRSSI LT with
 		 * the value 0x7FFFFFFF here. I think that is some weird
 		 * compiler optimization in the original driver.
@@ -2088,8 +2088,8 @@
 	/* FIXME: The spec says in the following if, the 0 should be replaced
 	   'if OFDM may not be used in the current locale'
 	   but OFDM is legal everywhere */
-	if ((dev->dev->bus->chip_id == 0x4306
-	     && dev->dev->bus->chip_package == 2) || 0) {
+	if ((dev->sdev->bus->chip_id == 0x4306
+	     && dev->sdev->bus->chip_package == 2) || 0) {
 		b43_phy_mask(dev, B43_PHY_CRS0, 0xBFFF);
 		b43_phy_mask(dev, B43_PHY_OFDM(0xC3), 0x7FFF);
 	}
@@ -2105,7 +2105,7 @@
 	b43_write16(dev, B43_MMIO_CHANNEL, channel2freq_bg(channel));
 
 	if (channel == 14) {
-		if (dev->dev->bus->sprom.country_code ==
+		if (dev->sdev->bus->sprom.country_code ==
 		    SSB_SPROM1CCODE_JAPAN)
 			b43_hf_write(dev,
 				     b43_hf_read(dev) & ~B43_HF_ACPR);
@@ -2136,7 +2136,7 @@
 static void default_radio_attenuation(struct b43_wldev *dev,
 				      struct b43_rfatt *rf)
 {
-	struct ssb_bus *bus = dev->dev->bus;
+	struct ssb_bus *bus = dev->sdev->bus;
 	struct b43_phy *phy = &dev->phy;
 
 	rf->with_padmix = 0;
@@ -2384,11 +2384,11 @@
 	struct b43_phy_g *gphy = phy->g;
 	s16 pab0, pab1, pab2;
 
-	pab0 = (s16) (dev->dev->bus->sprom.pa0b0);
-	pab1 = (s16) (dev->dev->bus->sprom.pa0b1);
-	pab2 = (s16) (dev->dev->bus->sprom.pa0b2);
+	pab0 = (s16) (dev->sdev->bus->sprom.pa0b0);
+	pab1 = (s16) (dev->sdev->bus->sprom.pa0b1);
+	pab2 = (s16) (dev->sdev->bus->sprom.pa0b2);
 
-	B43_WARN_ON((dev->dev->bus->chip_id == 0x4301) &&
+	B43_WARN_ON((dev->sdev->bus->chip_id == 0x4301) &&
 		    (phy->radio_ver != 0x2050)); /* Not supported anymore */
 
 	gphy->dyn_tssi_tbl = 0;
@@ -2396,10 +2396,10 @@
 	if (pab0 != 0 && pab1 != 0 && pab2 != 0 &&
 	    pab0 != -1 && pab1 != -1 && pab2 != -1) {
 		/* The pabX values are set in SPROM. Use them. */
-		if ((s8) dev->dev->bus->sprom.itssi_bg != 0 &&
-		    (s8) dev->dev->bus->sprom.itssi_bg != -1) {
+		if ((s8) dev->sdev->bus->sprom.itssi_bg != 0 &&
+		    (s8) dev->sdev->bus->sprom.itssi_bg != -1) {
 			gphy->tgt_idle_tssi =
-				(s8) (dev->dev->bus->sprom.itssi_bg);
+				(s8) (dev->sdev->bus->sprom.itssi_bg);
 		} else
 			gphy->tgt_idle_tssi = 62;
 		gphy->tssi2dbm = b43_generate_dyn_tssi2dbm_tab(dev, pab0,
@@ -2840,7 +2840,7 @@
 				    B43_TXCTL_TXMIX;
 				rfatt += 2;
 				bbatt += 2;
-			} else if (dev->dev->bus->sprom.
+			} else if (dev->sdev->bus->sprom.
 				   boardflags_lo &
 				   B43_BFL_PACTRL) {
 				bbatt += 4 * (rfatt - 2);
@@ -2914,14 +2914,14 @@
 	estimated_pwr = b43_gphy_estimate_power_out(dev, average_tssi);
 
 	B43_WARN_ON(phy->type != B43_PHYTYPE_G);
-	max_pwr = dev->dev->bus->sprom.maxpwr_bg;
-	if (dev->dev->bus->sprom.boardflags_lo & B43_BFL_PACTRL)
+	max_pwr = dev->sdev->bus->sprom.maxpwr_bg;
+	if (dev->sdev->bus->sprom.boardflags_lo & B43_BFL_PACTRL)
 		max_pwr -= 3; /* minus 0.75 */
 	if (unlikely(max_pwr >= INT_TO_Q52(30/*dBm*/))) {
 		b43warn(dev->wl,
 			"Invalid max-TX-power value in SPROM.\n");
 		max_pwr = INT_TO_Q52(20); /* fake it */
-		dev->dev->bus->sprom.maxpwr_bg = max_pwr;
+		dev->sdev->bus->sprom.maxpwr_bg = max_pwr;
 	}
 
 	/* Get desired power (in Q5.2) */
@@ -3014,7 +3014,7 @@
 {
 	struct b43_phy *phy = &dev->phy;
 
-	if (!(dev->dev->bus->sprom.boardflags_lo & B43_BFL_RSSI))
+	if (!(dev->sdev->bus->sprom.boardflags_lo & B43_BFL_RSSI))
 		return;
 
 	b43_mac_suspend(dev);
diff -druN linux-2.6.39-libre/drivers/net/wireless/b43/phy_lp.c linux-3.0-rc7-libre/drivers/net/wireless/b43/phy_lp.c
--- linux-2.6.39-libre/drivers/net/wireless/b43/phy_lp.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/b43/phy_lp.c	2011-07-11 19:51:52.000000000 -0400
@@ -86,7 +86,7 @@
 static void lpphy_read_band_sprom(struct b43_wldev *dev)
 {
 	struct b43_phy_lp *lpphy = dev->phy.lp;
-	struct ssb_bus *bus = dev->dev->bus;
+	struct ssb_bus *bus = dev->sdev->bus;
 	u16 cckpo, maxpwr;
 	u32 ofdmpo;
 	int i;
@@ -214,7 +214,7 @@
 
 static void lpphy_baseband_rev0_1_init(struct b43_wldev *dev)
 {
-	struct ssb_bus *bus = dev->dev->bus;
+	struct ssb_bus *bus = dev->sdev->bus;
 	struct b43_phy_lp *lpphy = dev->phy.lp;
 	u16 tmp, tmp2;
 
@@ -412,7 +412,7 @@
 
 static void lpphy_baseband_rev2plus_init(struct b43_wldev *dev)
 {
-	struct ssb_bus *bus = dev->dev->bus;
+	struct ssb_bus *bus = dev->sdev->bus;
 	struct b43_phy_lp *lpphy = dev->phy.lp;
 
 	b43_phy_write(dev, B43_LPPHY_AFE_DAC_CTL, 0x50);
@@ -519,7 +519,7 @@
 static void lpphy_2062_init(struct b43_wldev *dev)
 {
 	struct b43_phy_lp *lpphy = dev->phy.lp;
-	struct ssb_bus *bus = dev->dev->bus;
+	struct ssb_bus *bus = dev->sdev->bus;
 	u32 crystalfreq, tmp, ref;
 	unsigned int i;
 	const struct b2062_freqdata *fd = NULL;
@@ -697,7 +697,7 @@
 		lpphy_sync_stx(dev);
 		b43_phy_write(dev, B43_PHY_OFDM(0xF0), 0x5F80);
 		b43_phy_write(dev, B43_PHY_OFDM(0xF1), 0);
-		if (dev->dev->bus->chip_id == 0x4325) {
+		if (dev->sdev->bus->chip_id == 0x4325) {
 			// TODO SSB PMU recalibration
 		}
 	}
@@ -1289,7 +1289,7 @@
 
 static void lpphy_rev2plus_rc_calib(struct b43_wldev *dev)
 {
-	struct ssb_bus *bus = dev->dev->bus;
+	struct ssb_bus *bus = dev->sdev->bus;
 	u32 crystal_freq = bus->chipco.pmu.crystalfreq * 1000;
 	u8 tmp = b43_radio_read(dev, B2063_RX_BB_SP8) & 0xFF;
 	int i;
@@ -1840,7 +1840,7 @@
 static void lpphy_papd_cal_txpwr(struct b43_wldev *dev)
 {
 	struct b43_phy_lp *lpphy = dev->phy.lp;
-	struct ssb_bus *bus = dev->dev->bus;
+	struct ssb_bus *bus = dev->sdev->bus;
 	struct lpphy_tx_gains gains, oldgains;
 	int old_txpctl, old_afe_ovr, old_rf, old_bbmult;
 
@@ -1870,7 +1870,7 @@
 			    bool rx, bool pa, struct lpphy_tx_gains *gains)
 {
 	struct b43_phy_lp *lpphy = dev->phy.lp;
-	struct ssb_bus *bus = dev->dev->bus;
+	struct ssb_bus *bus = dev->sdev->bus;
 	const struct lpphy_rx_iq_comp *iqcomp = NULL;
 	struct lpphy_tx_gains nogains, oldgains;
 	u16 tmp;
@@ -2408,7 +2408,7 @@
 
 static void lpphy_b2062_reset_pll_bias(struct b43_wldev *dev)
 {
-	struct ssb_bus *bus = dev->dev->bus;
+	struct ssb_bus *bus = dev->sdev->bus;
 
 	b43_radio_write(dev, B2062_S_RFPLL_CTL2, 0xFF);
 	udelay(20);
@@ -2432,7 +2432,7 @@
 			    unsigned int channel)
 {
 	struct b43_phy_lp *lpphy = dev->phy.lp;
-	struct ssb_bus *bus = dev->dev->bus;
+	struct ssb_bus *bus = dev->sdev->bus;
 	const struct b206x_channel *chandata = NULL;
 	u32 crystal_freq = bus->chipco.pmu.crystalfreq * 1000;
 	u32 tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8, tmp9;
@@ -2522,7 +2522,7 @@
 static int lpphy_b2063_tune(struct b43_wldev *dev,
 			    unsigned int channel)
 {
-	struct ssb_bus *bus = dev->dev->bus;
+	struct ssb_bus *bus = dev->sdev->bus;
 
 	static const struct b206x_channel *chandata = NULL;
 	u32 crystal_freq = bus->chipco.pmu.crystalfreq * 1000;
diff -druN linux-2.6.39-libre/drivers/net/wireless/b43/phy_n.c linux-3.0-rc7-libre/drivers/net/wireless/b43/phy_n.c
--- linux-2.6.39-libre/drivers/net/wireless/b43/phy_n.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/b43/phy_n.c	2011-07-11 19:51:52.000000000 -0400
@@ -299,7 +299,7 @@
 static void b43_nphy_tx_power_fix(struct b43_wldev *dev)
 {
 	struct b43_phy_n *nphy = dev->phy.n;
-	struct ssb_sprom *sprom = &(dev->dev->bus->sprom);
+	struct ssb_sprom *sprom = &(dev->sdev->bus->sprom);
 
 	u8 txpi[2], bbmult, i;
 	u16 tmp, radio_gain, dac_gain;
@@ -423,8 +423,8 @@
 static void b43_radio_init2055_post(struct b43_wldev *dev)
 {
 	struct b43_phy_n *nphy = dev->phy.n;
-	struct ssb_sprom *sprom = &(dev->dev->bus->sprom);
-	struct ssb_boardinfo *binfo = &(dev->dev->bus->boardinfo);
+	struct ssb_sprom *sprom = &(dev->sdev->bus->sprom);
+	struct ssb_boardinfo *binfo = &(dev->sdev->bus->boardinfo);
 	int i;
 	u16 val;
 	bool workaround = false;
@@ -609,12 +609,12 @@
 	if (dev->phy.type != B43_PHYTYPE_N)
 		return;
 
-	tmslow = ssb_read32(dev->dev, SSB_TMSLOW);
+	tmslow = ssb_read32(dev->sdev, SSB_TMSLOW);
 	if (force)
 		tmslow |= SSB_TMSLOW_FGC;
 	else
 		tmslow &= ~SSB_TMSLOW_FGC;
-	ssb_write32(dev->dev, SSB_TMSLOW, tmslow);
+	ssb_write32(dev->sdev, SSB_TMSLOW, tmslow);
 }
 
 /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/CCA */
@@ -959,7 +959,7 @@
 		b43_phy_write(dev, B43_NPHY_GPIO_LOOEN, 0);
 		b43_phy_write(dev, B43_NPHY_GPIO_HIOEN, 0);
 
-		ssb_chipco_gpio_control(&dev->dev->bus->chipco, 0xFC00,
+		ssb_chipco_gpio_control(&dev->sdev->bus->chipco, 0xFC00,
 					0xFC00);
 		b43_write32(dev, B43_MMIO_MACCTL,
 			b43_read32(dev, B43_MMIO_MACCTL) &
@@ -983,7 +983,7 @@
 {
 	u16 tmp;
 
-	if (dev->dev->id.revision == 16)
+	if (dev->sdev->id.revision == 16)
 		b43_mac_suspend(dev);
 
 	tmp = b43_phy_read(dev, B43_NPHY_CLASSCTL);
@@ -993,7 +993,7 @@
 	tmp |= (val & mask);
 	b43_phy_maskset(dev, B43_NPHY_CLASSCTL, 0xFFF8, tmp);
 
-	if (dev->dev->id.revision == 16)
+	if (dev->sdev->id.revision == 16)
 		b43_mac_enable(dev);
 
 	return tmp;
@@ -1168,7 +1168,7 @@
 static void b43_nphy_gain_ctrl_workarounds(struct b43_wldev *dev)
 {
 	struct b43_phy_n *nphy = dev->phy.n;
-	struct ssb_sprom *sprom = &(dev->dev->bus->sprom);
+	struct ssb_sprom *sprom = &(dev->sdev->bus->sprom);
 
 	/* PHY rev 0, 1, 2 */
 	u8 i, j;
@@ -1373,7 +1373,7 @@
 /* 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 ssb_bus *bus = dev->sdev->bus;
 	struct b43_phy *phy = &dev->phy;
 	struct b43_phy_n *nphy = phy->n;
 
@@ -2281,6 +2281,7 @@
 		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);
+		save_regs_phy[8] = 0;
 	} else {
 		save_regs_phy[0] = b43_phy_read(dev, B43_NPHY_AFECTL_C1);
 		save_regs_phy[1] = b43_phy_read(dev, B43_NPHY_AFECTL_C2);
@@ -2289,6 +2290,8 @@
 		save_regs_phy[4] = b43_phy_read(dev, B43_NPHY_RFCTL_OVER);
 		save_regs_phy[5] = b43_phy_read(dev, B43_NPHY_RFCTL_RSSIO1);
 		save_regs_phy[6] = b43_phy_read(dev, B43_NPHY_RFCTL_RSSIO2);
+		save_regs_phy[7] = 0;
+		save_regs_phy[8] = 0;
 	}
 
 	b43_nphy_rssi_select(dev, 5, type);
@@ -3090,7 +3093,7 @@
 	int freq;
 	bool avoid = false;
 	u8 length;
-	u16 tmp, core, type, count, max, numb, last, cmd;
+	u16 tmp, core, type, count, max, numb, last = 0, cmd;
 	const u16 *table;
 	bool phy6or5x;
 
@@ -3537,17 +3540,6 @@
 		return b43_nphy_rev2_cal_rx_iq(dev, target, type, debug);
 }
 
-/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/MacPhyClkSet */
-static void b43_nphy_mac_phy_clock_set(struct b43_wldev *dev, bool on)
-{
-	u32 tmslow = ssb_read32(dev->dev, SSB_TMSLOW);
-	if (on)
-		tmslow |= B43_TMSLOW_MACPHYCLKEN;
-	else
-		tmslow &= ~B43_TMSLOW_MACPHYCLKEN;
-	ssb_write32(dev->dev, SSB_TMSLOW, tmslow);
-}
-
 /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RxCoreSetState */
 static void b43_nphy_set_rx_core_state(struct b43_wldev *dev, u8 mask)
 {
@@ -3594,7 +3586,7 @@
  */
 int b43_phy_initn(struct b43_wldev *dev)
 {
-	struct ssb_bus *bus = dev->dev->bus;
+	struct ssb_bus *bus = dev->sdev->bus;
 	struct b43_phy *phy = &dev->phy;
 	struct b43_phy_n *nphy = phy->n;
 	u8 tx_pwr_state;
@@ -3609,7 +3601,7 @@
 	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);
+		chipco_set32(&dev->sdev->bus->chipco, SSB_CHIPCO_CHIPCTL, 0x40);
 	}
 	nphy->deaf_count = 0;
 	b43_nphy_tables_init(dev);
@@ -3688,7 +3680,7 @@
 	b43_phy_write(dev, B43_NPHY_BBCFG, tmp & ~B43_NPHY_BBCFG_RSTCCA);
 	b43_nphy_bmac_clock_fgc(dev, 0);
 
-	b43_nphy_mac_phy_clock_set(dev, true);
+	b43_mac_phy_clock_set(dev, true);
 
 	b43_nphy_pa_override(dev, false);
 	b43_nphy_force_rf_sequence(dev, B43_RFSEQ_RX2TX);
@@ -3845,8 +3837,8 @@
 {
 	struct b43_phy *phy = &dev->phy;
 
-	const struct b43_nphy_channeltab_entry_rev2 *tabent_r2;
-	const struct b43_nphy_channeltab_entry_rev3 *tabent_r3;
+	const struct b43_nphy_channeltab_entry_rev2 *tabent_r2 = NULL;
+	const struct b43_nphy_channeltab_entry_rev3 *tabent_r3 = NULL;
 
 	u8 tmp;
 
diff -druN linux-2.6.39-libre/drivers/net/wireless/b43/pio.c linux-3.0-rc7-libre/drivers/net/wireless/b43/pio.c
--- linux-2.6.39-libre/drivers/net/wireless/b43/pio.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/b43/pio.c	2011-07-11 19:51:52.000000000 -0400
@@ -111,7 +111,7 @@
 		B43_MMIO_PIO11_BASE5,
 	};
 
-	if (dev->dev->id.revision >= 11) {
+	if (dev->sdev->id.revision >= 11) {
 		B43_WARN_ON(index >= ARRAY_SIZE(bases_rev11));
 		return bases_rev11[index];
 	}
@@ -121,14 +121,14 @@
 
 static u16 pio_txqueue_offset(struct b43_wldev *dev)
 {
-	if (dev->dev->id.revision >= 11)
+	if (dev->sdev->id.revision >= 11)
 		return 0x18;
 	return 0;
 }
 
 static u16 pio_rxqueue_offset(struct b43_wldev *dev)
 {
-	if (dev->dev->id.revision >= 11)
+	if (dev->sdev->id.revision >= 11)
 		return 0x38;
 	return 8;
 }
@@ -144,7 +144,7 @@
 	if (!q)
 		return NULL;
 	q->dev = dev;
-	q->rev = dev->dev->id.revision;
+	q->rev = dev->sdev->id.revision;
 	q->mmio_base = index_to_pioqueue_base(dev, index) +
 		       pio_txqueue_offset(dev);
 	q->index = index;
@@ -178,7 +178,7 @@
 	if (!q)
 		return NULL;
 	q->dev = dev;
-	q->rev = dev->dev->id.revision;
+	q->rev = dev->sdev->id.revision;
 	q->mmio_base = index_to_pioqueue_base(dev, index) +
 		       pio_rxqueue_offset(dev);
 
@@ -339,7 +339,7 @@
 	ctl |= B43_PIO_TXCTL_WRITELO | B43_PIO_TXCTL_WRITEHI;
 	b43_piotx_write16(q, B43_PIO_TXCTL, ctl);
 
-	ssb_block_write(dev->dev, data, (data_len & ~1),
+	b43_block_write(dev, data, (data_len & ~1),
 			q->mmio_base + B43_PIO_TXDATA,
 			sizeof(u16));
 	if (data_len & 1) {
@@ -351,7 +351,7 @@
 		b43_piotx_write16(q, B43_PIO_TXCTL, ctl);
 		tail[0] = data[data_len - 1];
 		tail[1] = 0;
-		ssb_block_write(dev->dev, tail, 2,
+		b43_block_write(dev, tail, 2,
 				q->mmio_base + B43_PIO_TXDATA,
 				sizeof(u16));
 	}
@@ -393,7 +393,7 @@
 	       B43_PIO8_TXCTL_16_23 | B43_PIO8_TXCTL_24_31;
 	b43_piotx_write32(q, B43_PIO8_TXCTL, ctl);
 
-	ssb_block_write(dev->dev, data, (data_len & ~3),
+	b43_block_write(dev, data, (data_len & ~3),
 			q->mmio_base + B43_PIO8_TXDATA,
 			sizeof(u32));
 	if (data_len & 3) {
@@ -421,7 +421,7 @@
 			break;
 		}
 		b43_piotx_write32(q, B43_PIO8_TXCTL, ctl);
-		ssb_block_write(dev->dev, tail, 4,
+		b43_block_write(dev, tail, 4,
 				q->mmio_base + B43_PIO8_TXDATA,
 				sizeof(u32));
 	}
@@ -657,11 +657,11 @@
 
 	/* Get the preamble (RX header) */
 	if (q->rev >= 8) {
-		ssb_block_read(dev->dev, rxhdr, sizeof(*rxhdr),
+		b43_block_read(dev, rxhdr, sizeof(*rxhdr),
 			       q->mmio_base + B43_PIO8_RXDATA,
 			       sizeof(u32));
 	} else {
-		ssb_block_read(dev->dev, rxhdr, sizeof(*rxhdr),
+		b43_block_read(dev, rxhdr, sizeof(*rxhdr),
 			       q->mmio_base + B43_PIO_RXDATA,
 			       sizeof(u16));
 	}
@@ -697,7 +697,7 @@
 	skb_reserve(skb, 2);
 	skb_put(skb, len + padding);
 	if (q->rev >= 8) {
-		ssb_block_read(dev->dev, skb->data + padding, (len & ~3),
+		b43_block_read(dev, skb->data + padding, (len & ~3),
 			       q->mmio_base + B43_PIO8_RXDATA,
 			       sizeof(u32));
 		if (len & 3) {
@@ -705,7 +705,7 @@
 			BUILD_BUG_ON(sizeof(wl->pio_tailspace) < 4);
 
 			/* Read the last few bytes. */
-			ssb_block_read(dev->dev, tail, 4,
+			b43_block_read(dev, tail, 4,
 				       q->mmio_base + B43_PIO8_RXDATA,
 				       sizeof(u32));
 			switch (len & 3) {
@@ -724,7 +724,7 @@
 			}
 		}
 	} else {
-		ssb_block_read(dev->dev, skb->data + padding, (len & ~1),
+		b43_block_read(dev, skb->data + padding, (len & ~1),
 			       q->mmio_base + B43_PIO_RXDATA,
 			       sizeof(u16));
 		if (len & 1) {
@@ -732,7 +732,7 @@
 			BUILD_BUG_ON(sizeof(wl->pio_tailspace) < 2);
 
 			/* Read the last byte. */
-			ssb_block_read(dev->dev, tail, 2,
+			b43_block_read(dev, tail, 2,
 				       q->mmio_base + B43_PIO_RXDATA,
 				       sizeof(u16));
 			skb->data[len + padding - 1] = tail[0];
diff -druN linux-2.6.39-libre/drivers/net/wireless/b43/rfkill.c linux-3.0-rc7-libre/drivers/net/wireless/b43/rfkill.c
--- linux-2.6.39-libre/drivers/net/wireless/b43/rfkill.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/b43/rfkill.c	2011-07-11 19:51:52.000000000 -0400
@@ -37,7 +37,7 @@
 {
 	struct b43_wl *wl = hw_to_b43_wl(hw);
 	struct b43_wldev *dev = wl->current_dev;
-	struct ssb_bus *bus = dev->dev->bus;
+	struct ssb_bus *bus = dev->sdev->bus;
 	bool enabled;
 	bool brought_up = false;
 
@@ -47,7 +47,7 @@
 			mutex_unlock(&wl->mutex);
 			return;
 		}
-		ssb_device_enable(dev->dev, 0);
+		ssb_device_enable(dev->sdev, 0);
 		brought_up = true;
 	}
 
@@ -63,7 +63,7 @@
 	}
 
 	if (brought_up) {
-		ssb_device_disable(dev->dev, 0);
+		ssb_device_disable(dev->sdev, 0);
 		ssb_bus_may_powerdown(bus);
 	}
 
diff -druN linux-2.6.39-libre/drivers/net/wireless/b43/sdio.c linux-3.0-rc7-libre/drivers/net/wireless/b43/sdio.c
--- linux-2.6.39-libre/drivers/net/wireless/b43/sdio.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/b43/sdio.c	2011-07-11 19:51:52.000000000 -0400
@@ -66,7 +66,7 @@
 int b43_sdio_request_irq(struct b43_wldev *dev,
 			 void (*handler)(struct b43_wldev *dev))
 {
-	struct ssb_bus *bus = dev->dev->bus;
+	struct ssb_bus *bus = dev->sdev->bus;
 	struct sdio_func *func = bus->host_sdio;
 	struct b43_sdio *sdio = sdio_get_drvdata(func);
 	int err;
@@ -82,7 +82,7 @@
 
 void b43_sdio_free_irq(struct b43_wldev *dev)
 {
-	struct ssb_bus *bus = dev->dev->bus;
+	struct ssb_bus *bus = dev->sdev->bus;
 	struct sdio_func *func = bus->host_sdio;
 	struct b43_sdio *sdio = sdio_get_drvdata(func);
 
diff -druN linux-2.6.39-libre/drivers/net/wireless/b43/sysfs.c linux-3.0-rc7-libre/drivers/net/wireless/b43/sysfs.c
--- linux-2.6.39-libre/drivers/net/wireless/b43/sysfs.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/b43/sysfs.c	2011-07-11 19:51:52.000000000 -0400
@@ -140,7 +140,7 @@
 
 int b43_sysfs_register(struct b43_wldev *wldev)
 {
-	struct device *dev = wldev->dev->dev;
+	struct device *dev = wldev->sdev->dev;
 
 	B43_WARN_ON(b43_status(wldev) != B43_STAT_INITIALIZED);
 
@@ -149,7 +149,7 @@
 
 void b43_sysfs_unregister(struct b43_wldev *wldev)
 {
-	struct device *dev = wldev->dev->dev;
+	struct device *dev = wldev->sdev->dev;
 
 	device_remove_file(dev, &dev_attr_interference);
 }
diff -druN linux-2.6.39-libre/drivers/net/wireless/b43/tables_lpphy.c linux-3.0-rc7-libre/drivers/net/wireless/b43/tables_lpphy.c
--- linux-2.6.39-libre/drivers/net/wireless/b43/tables_lpphy.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/b43/tables_lpphy.c	2011-07-11 19:51:52.000000000 -0400
@@ -2304,7 +2304,7 @@
 
 void lpphy_rev2plus_table_init(struct b43_wldev *dev)
 {
-	struct ssb_bus *bus = dev->dev->bus;
+	struct ssb_bus *bus = dev->sdev->bus;
 	int i;
 
 	B43_WARN_ON(dev->phy.rev < 2);
@@ -2416,7 +2416,7 @@
 
 void lpphy_init_tx_gain_table(struct b43_wldev *dev)
 {
-	struct ssb_bus *bus = dev->dev->bus;
+	struct ssb_bus *bus = dev->sdev->bus;
 
 	switch (dev->phy.rev) {
 	case 0:
diff -druN linux-2.6.39-libre/drivers/net/wireless/b43/wa.c linux-3.0-rc7-libre/drivers/net/wireless/b43/wa.c
--- linux-2.6.39-libre/drivers/net/wireless/b43/wa.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/b43/wa.c	2011-07-11 19:51:52.000000000 -0400
@@ -458,7 +458,7 @@
 
 static void b43_wa_boards_a(struct b43_wldev *dev)
 {
-	struct ssb_bus *bus = dev->dev->bus;
+	struct ssb_bus *bus = dev->sdev->bus;
 
 	if (bus->boardinfo.vendor == SSB_BOARDVENDOR_BCM &&
 	    bus->boardinfo.type == SSB_BOARD_BU4306 &&
@@ -486,7 +486,7 @@
 
 static void b43_wa_boards_g(struct b43_wldev *dev)
 {
-	struct ssb_bus *bus = dev->dev->bus;
+	struct ssb_bus *bus = dev->sdev->bus;
 	struct b43_phy *phy = &dev->phy;
 
 	if (bus->boardinfo.vendor != SSB_BOARDVENDOR_BCM ||
diff -druN linux-2.6.39-libre/drivers/net/wireless/b43/xmit.c linux-3.0-rc7-libre/drivers/net/wireless/b43/xmit.c
--- linux-2.6.39-libre/drivers/net/wireless/b43/xmit.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/b43/xmit.c	2011-07-11 19:51:52.000000000 -0400
@@ -547,7 +547,7 @@
 			else
 				tmp -= 3;
 		} else {
-			if (dev->dev->bus->sprom.
+			if (dev->sdev->bus->sprom.
 			    boardflags_lo & B43_BFL_RSSI) {
 				if (in_rssi > 63)
 					in_rssi = 63;
diff -druN linux-2.6.39-libre/drivers/net/wireless/b43legacy/main.c linux-3.0-rc7-libre/drivers/net/wireless/b43legacy/main.c
--- linux-2.6.39-libre/drivers/net/wireless/b43legacy/main.c	2011-05-19 02:13:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/b43legacy/main.c	2011-07-21 06:55:59.000000000 -0400
@@ -2230,7 +2230,7 @@
 	b43legacy_write32(dev, B43legacy_MMIO_DMA5_IRQ_MASK, 0x0000DC00);
 
 	value32 = ssb_read32(dev->dev, SSB_TMSLOW);
-	value32 |= 0x00100000;
+	value32 |= B43legacy_TMSLOW_MACPHYCLKEN;
 	ssb_write32(dev->dev, SSB_TMSLOW, value32);
 
 	b43legacy_write16(dev, B43legacy_MMIO_POWERUP_DELAY,
@@ -3100,37 +3100,6 @@
 	memset(&dev->noisecalc, 0, sizeof(dev->noisecalc));
 }
 
-static void b43legacy_imcfglo_timeouts_workaround(struct b43legacy_wldev *dev)
-{
-#ifdef CONFIG_SSB_DRIVER_PCICORE
-	struct ssb_bus *bus = dev->dev->bus;
-	u32 tmp;
-
-	if (bus->pcicore.dev &&
-	    bus->pcicore.dev->id.coreid == SSB_DEV_PCI &&
-	    bus->pcicore.dev->id.revision <= 5) {
-		/* IMCFGLO timeouts workaround. */
-		tmp = ssb_read32(dev->dev, SSB_IMCFGLO);
-		switch (bus->bustype) {
-		case SSB_BUSTYPE_PCI:
-		case SSB_BUSTYPE_PCMCIA:
-			tmp &= ~SSB_IMCFGLO_REQTO;
-			tmp &= ~SSB_IMCFGLO_SERTO;
-			tmp |= 0x32;
-			break;
-		case SSB_BUSTYPE_SSB:
-			tmp &= ~SSB_IMCFGLO_REQTO;
-			tmp &= ~SSB_IMCFGLO_SERTO;
-			tmp |= 0x53;
-			break;
-		default:
-			break;
-		}
-		ssb_write32(dev->dev, SSB_IMCFGLO, tmp);
-	}
-#endif /* CONFIG_SSB_DRIVER_PCICORE */
-}
-
 static void b43legacy_set_synth_pu_delay(struct b43legacy_wldev *dev,
 					  bool idle) {
 	u16 pu_delay = 1050;
@@ -3274,7 +3243,6 @@
 	/* Enable IRQ routing to this device. */
 	ssb_pcicore_dev_irqvecs_enable(&bus->pcicore, dev->dev);
 
-	b43legacy_imcfglo_timeouts_workaround(dev);
 	prepare_phy_data_for_init(dev);
 	b43legacy_phy_calibrate(dev);
 	err = b43legacy_chip_init(dev);
@@ -3724,26 +3692,8 @@
 				     struct b43legacy_wl *wl)
 {
 	struct b43legacy_wldev *wldev;
-	struct pci_dev *pdev;
 	int err = -ENOMEM;
 
-	if (!list_empty(&wl->devlist)) {
-		/* We are not the first core on this chip. */
-		pdev = (dev->bus->bustype == SSB_BUSTYPE_PCI) ? dev->bus->host_pci : NULL;
-		/* Only special chips support more than one wireless
-		 * core, although some of the other chips have more than
-		 * one wireless core as well. Check for this and
-		 * bail out early.
-		 */
-		if (!pdev ||
-		    ((pdev->device != 0x4321) &&
-		     (pdev->device != 0x4313) &&
-		     (pdev->device != 0x431A))) {
-			b43legacydbg(wl, "Ignoring unconnected 802.11 core\n");
-			return -ENODEV;
-		}
-	}
-
 	wldev = kzalloc(sizeof(*wldev), GFP_KERNEL);
 	if (!wldev)
 		goto out;
diff -druN linux-2.6.39-libre/drivers/net/wireless/hostap/hostap_cs.c linux-3.0-rc7-libre/drivers/net/wireless/hostap/hostap_cs.c
--- linux-2.6.39-libre/drivers/net/wireless/hostap/hostap_cs.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/hostap/hostap_cs.c	2011-07-11 19:51:52.000000000 -0400
@@ -620,7 +620,7 @@
 	return 0;
 }
 
-static struct pcmcia_device_id hostap_cs_ids[] = {
+static const struct pcmcia_device_id hostap_cs_ids[] = {
 	PCMCIA_DEVICE_MANF_CARD(0x000b, 0x7100),
 	PCMCIA_DEVICE_MANF_CARD(0x000b, 0x7300),
 	PCMCIA_DEVICE_MANF_CARD(0x0101, 0x0777),
diff -druN linux-2.6.39-libre/drivers/net/wireless/hostap/hostap_main.c linux-3.0-rc7-libre/drivers/net/wireless/hostap/hostap_main.c
--- linux-2.6.39-libre/drivers/net/wireless/hostap/hostap_main.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/hostap/hostap_main.c	2011-07-11 19:51:52.000000000 -0400
@@ -79,13 +79,8 @@
 	if (!rtnl_locked)
 		rtnl_lock();
 
-	ret = 0;
-	if (strchr(dev->name, '%'))
-		ret = dev_alloc_name(dev, dev->name);
-
 	SET_NETDEV_DEV(dev, mdev->dev.parent);
-	if (ret >= 0)
-		ret = register_netdevice(dev);
+	ret = register_netdevice(dev);
 
 	if (!rtnl_locked)
 		rtnl_unlock();
diff -druN linux-2.6.39-libre/drivers/net/wireless/ipw2x00/ipw2200.c linux-3.0-rc7-libre/drivers/net/wireless/ipw2x00/ipw2200.c
--- linux-2.6.39-libre/drivers/net/wireless/ipw2x00/ipw2200.c	2011-05-19 02:14:10.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/ipw2x00/ipw2200.c	2011-07-21 06:56:35.000000000 -0400
@@ -7430,7 +7430,7 @@
 		priv->assoc_request.capability &=
 		    ~cpu_to_le16(WLAN_CAPABILITY_SHORT_SLOT_TIME);
 
-	IPW_DEBUG_ASSOC("%sssocation attempt: '%s', channel %d, "
+	IPW_DEBUG_ASSOC("%ssociation attempt: '%s', channel %d, "
 			"802.11%c [%d], %s[:%s], enc=%s%s%s%c%c\n",
 			roaming ? "Rea" : "A",
 			print_ssid(ssid, priv->essid, priv->essid_len),
diff -druN linux-2.6.39-libre/drivers/net/wireless/iwlegacy/iwl3945-base.c linux-3.0-rc7-libre/drivers/net/wireless/iwlegacy/iwl3945-base.c
--- linux-2.6.39-libre/drivers/net/wireless/iwlegacy/iwl3945-base.c	2011-05-19 02:14:14.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/iwlegacy/iwl3945-base.c	2011-07-21 06:56:39.000000000 -0400
@@ -2748,11 +2748,12 @@
 	struct iwl_priv *priv =
 	    container_of(data, struct iwl_priv, init_alive_start.work);
 
+	mutex_lock(&priv->mutex);
 	if (test_bit(STATUS_EXIT_PENDING, &priv->status))
-		return;
+		goto out;
 
-	mutex_lock(&priv->mutex);
 	iwl3945_init_alive_start(priv);
+out:
 	mutex_unlock(&priv->mutex);
 }
 
@@ -2761,11 +2762,12 @@
 	struct iwl_priv *priv =
 	    container_of(data, struct iwl_priv, alive_start.work);
 
+	mutex_lock(&priv->mutex);
 	if (test_bit(STATUS_EXIT_PENDING, &priv->status))
-		return;
+		goto out;
 
-	mutex_lock(&priv->mutex);
 	iwl3945_alive_start(priv);
+out:
 	mutex_unlock(&priv->mutex);
 }
 
@@ -2995,10 +2997,12 @@
 	} else {
 		iwl3945_down(priv);
 
-		if (test_bit(STATUS_EXIT_PENDING, &priv->status))
+		mutex_lock(&priv->mutex);
+		if (test_bit(STATUS_EXIT_PENDING, &priv->status)) {
+			mutex_unlock(&priv->mutex);
 			return;
+		}
 
-		mutex_lock(&priv->mutex);
 		__iwl3945_up(priv);
 		mutex_unlock(&priv->mutex);
 	}
@@ -3009,11 +3013,12 @@
 	struct iwl_priv *priv =
 	    container_of(data, struct iwl_priv, rx_replenish);
 
+	mutex_lock(&priv->mutex);
 	if (test_bit(STATUS_EXIT_PENDING, &priv->status))
-		return;
+		goto out;
 
-	mutex_lock(&priv->mutex);
 	iwl3945_rx_replenish(priv);
+out:
 	mutex_unlock(&priv->mutex);
 }
 
@@ -3810,7 +3815,6 @@
 	INIT_LIST_HEAD(&priv->free_frames);
 
 	mutex_init(&priv->mutex);
-	mutex_init(&priv->sync_cmd_mutex);
 
 	priv->ieee_channels = NULL;
 	priv->ieee_rates = NULL;
diff -druN linux-2.6.39-libre/drivers/net/wireless/iwlegacy/iwl4965-base.c linux-3.0-rc7-libre/drivers/net/wireless/iwlegacy/iwl4965-base.c
--- linux-2.6.39-libre/drivers/net/wireless/iwlegacy/iwl4965-base.c	2011-05-19 02:14:33.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/iwlegacy/iwl4965-base.c	2011-07-21 06:56:56.000000000 -0400
@@ -1069,9 +1069,12 @@
 	}
 
 	/* Re-enable all interrupts */
-	/* only Re-enable if diabled by irq */
+	/* only Re-enable if disabled by irq */
 	if (test_bit(STATUS_INT_ENABLED, &priv->status))
 		iwl_legacy_enable_interrupts(priv);
+	/* Re-enable RF_KILL if it occurred */
+	else if (handled & CSR_INT_BIT_RF_KILL)
+		iwl_legacy_enable_rfkill_int(priv);
 
 #ifdef CONFIG_IWLWIFI_LEGACY_DEBUG
 	if (iwl_legacy_get_debug_level(priv) & (IWL_DL_ISR)) {
@@ -2139,7 +2142,7 @@
 static void __iwl4965_down(struct iwl_priv *priv)
 {
 	unsigned long flags;
-	int exit_pending = test_bit(STATUS_EXIT_PENDING, &priv->status);
+	int exit_pending;
 
 	IWL_DEBUG_INFO(priv, DRV_NAME " is going down\n");
 
@@ -2401,11 +2404,12 @@
 	struct iwl_priv *priv =
 	    container_of(data, struct iwl_priv, init_alive_start.work);
 
+	mutex_lock(&priv->mutex);
 	if (test_bit(STATUS_EXIT_PENDING, &priv->status))
-		return;
+		goto out;
 
-	mutex_lock(&priv->mutex);
 	priv->cfg->ops->lib->init_alive_start(priv);
+out:
 	mutex_unlock(&priv->mutex);
 }
 
@@ -2414,11 +2418,12 @@
 	struct iwl_priv *priv =
 	    container_of(data, struct iwl_priv, alive_start.work);
 
+	mutex_lock(&priv->mutex);
 	if (test_bit(STATUS_EXIT_PENDING, &priv->status))
-		return;
+		goto out;
 
-	mutex_lock(&priv->mutex);
 	iwl4965_alive_start(priv);
+out:
 	mutex_unlock(&priv->mutex);
 }
 
@@ -2468,10 +2473,12 @@
 	} else {
 		iwl4965_down(priv);
 
-		if (test_bit(STATUS_EXIT_PENDING, &priv->status))
+		mutex_lock(&priv->mutex);
+		if (test_bit(STATUS_EXIT_PENDING, &priv->status)) {
+			mutex_unlock(&priv->mutex);
 			return;
+		}
 
-		mutex_lock(&priv->mutex);
 		__iwl4965_up(priv);
 		mutex_unlock(&priv->mutex);
 	}
@@ -2624,9 +2631,10 @@
 
 	flush_workqueue(priv->workqueue);
 
-	/* enable interrupts again in order to receive rfkill changes */
+	/* User space software may expect getting rfkill changes
+	 * even if interface is down */
 	iwl_write32(priv, CSR_INT, 0xFFFFFFFF);
-	iwl_legacy_enable_interrupts(priv);
+	iwl_legacy_enable_rfkill_int(priv);
 
 	IWL_DEBUG_MAC80211(priv, "leave\n");
 }
@@ -2847,21 +2855,19 @@
 
 	IWL_DEBUG_MAC80211(priv, "enter\n");
 
+	mutex_lock(&priv->mutex);
+
 	if (iwl_legacy_is_rfkill(priv))
-		goto out_exit;
+		goto out;
 
 	if (test_bit(STATUS_EXIT_PENDING, &priv->status) ||
-	    test_bit(STATUS_SCANNING, &priv->status))
-		goto out_exit;
+	    test_bit(STATUS_SCANNING, &priv->status) ||
+	    test_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->status))
+		goto out;
 
 	if (!iwl_legacy_is_associated_ctx(ctx))
-		goto out_exit;
-
-	/* channel switch in progress */
-	if (priv->switch_rxon.switch_in_progress == true)
-		goto out_exit;
+		goto out;
 
-	mutex_lock(&priv->mutex);
 	if (priv->cfg->ops->lib->set_channel_switch) {
 
 		ch = channel->hw_value;
@@ -2910,16 +2916,18 @@
 			 * at this point, staging_rxon has the
 			 * configuration for channel switch
 			 */
-			if (priv->cfg->ops->lib->set_channel_switch(priv,
-								    ch_switch))
-				priv->switch_rxon.switch_in_progress = false;
+			set_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->status);
+			priv->switch_channel = cpu_to_le16(ch);
+			if (priv->cfg->ops->lib->set_channel_switch(priv, ch_switch)) {
+				clear_bit(STATUS_CHANNEL_SWITCH_PENDING,
+					  &priv->status);
+				priv->switch_channel = 0;
+				ieee80211_chswitch_done(ctx->vif, false);
+			}
 		}
 	}
 out:
 	mutex_unlock(&priv->mutex);
-out_exit:
-	if (!priv->switch_rxon.switch_in_progress)
-		ieee80211_chswitch_done(ctx->vif, false);
 	IWL_DEBUG_MAC80211(priv, "leave\n");
 }
 
@@ -3116,7 +3124,6 @@
 	INIT_LIST_HEAD(&priv->free_frames);
 
 	mutex_init(&priv->mutex);
-	mutex_init(&priv->sync_cmd_mutex);
 
 	priv->ieee_channels = NULL;
 	priv->ieee_rates = NULL;
@@ -3173,7 +3180,7 @@
 {
 	priv->hw_rev = _iwl_legacy_read32(priv, CSR_HW_REV);
 	priv->hw_wa_rev = _iwl_legacy_read32(priv, CSR_HW_REV_WA_REG);
-	pci_read_config_byte(priv->pci_dev, PCI_REVISION_ID, &priv->rev_id);
+	priv->rev_id = priv->pci_dev->revision;
 	IWL_DEBUG_INFO(priv, "HW Revision ID = 0x%X\n", priv->rev_id);
 }
 
@@ -3406,14 +3413,14 @@
 	 * 8. Enable interrupts and read RFKILL state
 	 *********************************************/
 
-	/* enable interrupts if needed: hw bug w/a */
+	/* enable rfkill interrupt: hw bug w/a */
 	pci_read_config_word(priv->pci_dev, PCI_COMMAND, &pci_cmd);
 	if (pci_cmd & PCI_COMMAND_INTX_DISABLE) {
 		pci_cmd &= ~PCI_COMMAND_INTX_DISABLE;
 		pci_write_config_word(priv->pci_dev, PCI_COMMAND, pci_cmd);
 	}
 
-	iwl_legacy_enable_interrupts(priv);
+	iwl_legacy_enable_rfkill_int(priv);
 
 	/* If platform's RF_KILL switch is NOT set to KILL */
 	if (iwl_read32(priv, CSR_GP_CNTRL) &
diff -druN linux-2.6.39-libre/drivers/net/wireless/iwlegacy/iwl-4965.c linux-3.0-rc7-libre/drivers/net/wireless/iwlegacy/iwl-4965.c
--- linux-2.6.39-libre/drivers/net/wireless/iwlegacy/iwl-4965.c	2011-05-19 02:14:36.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/iwlegacy/iwl-4965.c	2011-07-21 06:56:59.000000000 -0400
@@ -1218,10 +1218,10 @@
 	 * receive commit_rxon request
 	 * abort any previous channel switch if still in process
 	 */
-	if (priv->switch_rxon.switch_in_progress &&
-	    (priv->switch_rxon.channel != ctx->staging.channel)) {
+	if (test_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->status) &&
+	    (priv->switch_channel != ctx->staging.channel)) {
 		IWL_DEBUG_11H(priv, "abort channel switch on %d\n",
-		      le16_to_cpu(priv->switch_rxon.channel));
+		      le16_to_cpu(priv->switch_channel));
 		iwl_legacy_chswitch_done(priv, false);
 	}
 
@@ -1237,7 +1237,7 @@
 
 		memcpy(active_rxon, &ctx->staging, sizeof(*active_rxon));
 		iwl_legacy_print_rx_config_cmd(priv, ctx);
-		return 0;
+		goto set_tx_power;
 	}
 
 	/* If we are currently associated and the new config requires
@@ -1317,6 +1317,7 @@
 
 	iwl4965_init_sensitivity(priv);
 
+set_tx_power:
 	/* If we issue a new RXON command which required a tune then we must
 	 * send a new TXPOWER command or we won't be able to Tx any frames */
 	ret = iwl_legacy_set_tx_power(priv, priv->tx_power_next, true);
@@ -1403,9 +1404,6 @@
 		return rc;
 	}
 
-	priv->switch_rxon.channel = cmd.channel;
-	priv->switch_rxon.switch_in_progress = true;
-
 	return iwl_legacy_send_cmd_pdu(priv,
 			 REPLY_CHANNEL_SWITCH, sizeof(cmd), &cmd);
 }
@@ -1543,7 +1541,7 @@
 	s32 temp;
 
 	temp = iwl4965_hw_get_temperature(priv);
-	if (temp < 0)
+	if (IWL_TX_POWER_TEMPERATURE_OUT_OF_RANGE(temp))
 		return;
 
 	if (priv->temperature != temp) {
diff -druN linux-2.6.39-libre/drivers/net/wireless/iwlegacy/iwl-4965-calib.c linux-3.0-rc7-libre/drivers/net/wireless/iwlegacy/iwl-4965-calib.c
--- linux-2.6.39-libre/drivers/net/wireless/iwlegacy/iwl-4965-calib.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/iwlegacy/iwl-4965-calib.c	2011-07-11 19:51:52.000000000 -0400
@@ -713,8 +713,8 @@
 			iwl4965_find_first_chain(priv->cfg->valid_tx_ant);
 			data->disconn_array[first_chain] = 0;
 			active_chains |= BIT(first_chain);
-			IWL_DEBUG_CALIB(priv, "All Tx chains are disconnected \
-					W/A - declare %d as connected\n",
+			IWL_DEBUG_CALIB(priv,
+					"All Tx chains are disconnected W/A - declare %d as connected\n",
 					first_chain);
 			break;
 		}
diff -druN linux-2.6.39-libre/drivers/net/wireless/iwlegacy/iwl-4965-lib.c linux-3.0-rc7-libre/drivers/net/wireless/iwlegacy/iwl-4965-lib.c
--- linux-2.6.39-libre/drivers/net/wireless/iwlegacy/iwl-4965-lib.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/iwlegacy/iwl-4965-lib.c	2011-07-11 19:51:52.000000000 -0400
@@ -628,11 +628,11 @@
 
 	/* rx_status carries information about the packet to mac80211 */
 	rx_status.mactime = le64_to_cpu(phy_res->timestamp);
+	rx_status.band = (phy_res->phy_flags & RX_RES_PHY_FLAGS_BAND_24_MSK) ?
+				IEEE80211_BAND_2GHZ : IEEE80211_BAND_5GHZ;
 	rx_status.freq =
 		ieee80211_channel_to_frequency(le16_to_cpu(phy_res->channel),
 							rx_status.band);
-	rx_status.band = (phy_res->phy_flags & RX_RES_PHY_FLAGS_BAND_24_MSK) ?
-				IEEE80211_BAND_2GHZ : IEEE80211_BAND_5GHZ;
 	rx_status.rate_idx =
 		iwl4965_hwrate_to_mac80211_idx(rate_n_flags, rx_status.band);
 	rx_status.flag = 0;
@@ -955,9 +955,6 @@
 	if (priv->cfg->scan_rx_antennas[band])
 		rx_ant = priv->cfg->scan_rx_antennas[band];
 
-	if (priv->cfg->scan_tx_antennas[band])
-		scan_tx_antennas = priv->cfg->scan_tx_antennas[band];
-
 	priv->scan_tx_ant[band] = iwl4965_toggle_tx_ant(priv,
 						priv->scan_tx_ant[band],
 						    scan_tx_antennas);
diff -druN linux-2.6.39-libre/drivers/net/wireless/iwlegacy/iwl-4965-rs.c linux-3.0-rc7-libre/drivers/net/wireless/iwlegacy/iwl-4965-rs.c
--- linux-2.6.39-libre/drivers/net/wireless/iwlegacy/iwl-4965-rs.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/iwlegacy/iwl-4965-rs.c	2011-07-11 19:51:52.000000000 -0400
@@ -2604,7 +2604,7 @@
 	struct iwl_lq_sta *lq_sta = file->private_data;
 	struct iwl_priv *priv;
 	char buf[64];
-	int buf_size;
+	size_t buf_size;
 	u32 parsed_rate;
 	struct iwl_station_priv *sta_priv =
 		container_of(lq_sta, struct iwl_station_priv, lq_sta);
@@ -2860,7 +2860,6 @@
 
 int iwl4965_rate_control_register(void)
 {
-	pr_err("Registering 4965 rate control operations\n");
 	return ieee80211_rate_control_register(&rs_4965_ops);
 }
 
diff -druN linux-2.6.39-libre/drivers/net/wireless/iwlegacy/iwl-core.c linux-3.0-rc7-libre/drivers/net/wireless/iwlegacy/iwl-core.c
--- linux-2.6.39-libre/drivers/net/wireless/iwlegacy/iwl-core.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/iwlegacy/iwl-core.c	2011-07-11 19:51:52.000000000 -0400
@@ -211,10 +211,7 @@
 		if (!iwl_legacy_is_channel_valid(ch))
 			continue;
 
-		if (iwl_legacy_is_channel_a_band(ch))
-			sband =  &priv->bands[IEEE80211_BAND_5GHZ];
-		else
-			sband =  &priv->bands[IEEE80211_BAND_2GHZ];
+		sband = &priv->bands[ch->band];
 
 		geo_ch = &sband->channels[sband->n_channels++];
 
@@ -862,12 +859,8 @@
 	if (test_bit(STATUS_EXIT_PENDING, &priv->status))
 		return;
 
-	if (priv->switch_rxon.switch_in_progress) {
+	if (test_and_clear_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->status))
 		ieee80211_chswitch_done(ctx->vif, is_success);
-		mutex_lock(&priv->mutex);
-		priv->switch_rxon.switch_in_progress = false;
-		mutex_unlock(&priv->mutex);
-	}
 }
 EXPORT_SYMBOL(iwl_legacy_chswitch_done);
 
@@ -879,19 +872,19 @@
 	struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
 	struct iwl_legacy_rxon_cmd *rxon = (void *)&ctx->active;
 
-	if (priv->switch_rxon.switch_in_progress) {
-		if (!le32_to_cpu(csa->status) &&
-		    (csa->channel == priv->switch_rxon.channel)) {
-			rxon->channel = csa->channel;
-			ctx->staging.channel = csa->channel;
-			IWL_DEBUG_11H(priv, "CSA notif: channel %d\n",
-			      le16_to_cpu(csa->channel));
-			iwl_legacy_chswitch_done(priv, true);
-		} else {
-			IWL_ERR(priv, "CSA notif (fail) : channel %d\n",
+	if (!test_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->status))
+		return;
+
+	if (!le32_to_cpu(csa->status) && csa->channel == priv->switch_channel) {
+		rxon->channel = csa->channel;
+		ctx->staging.channel = csa->channel;
+		IWL_DEBUG_11H(priv, "CSA notif: channel %d\n",
 			      le16_to_cpu(csa->channel));
-			iwl_legacy_chswitch_done(priv, false);
-		}
+		iwl_legacy_chswitch_done(priv, true);
+	} else {
+		IWL_ERR(priv, "CSA notif (fail) : channel %d\n",
+			le16_to_cpu(csa->channel));
+		iwl_legacy_chswitch_done(priv, false);
 	}
 }
 EXPORT_SYMBOL(iwl_legacy_rx_csa);
@@ -2117,10 +2110,9 @@
 	IWL_DEBUG_MAC80211(priv, "enter to channel %d changed 0x%X\n",
 					channel->hw_value, changed);
 
-	if (unlikely(!priv->cfg->mod_params->disable_hw_scan &&
-			test_bit(STATUS_SCANNING, &priv->status))) {
+	if (unlikely(test_bit(STATUS_SCANNING, &priv->status))) {
 		scan_active = 1;
-		IWL_DEBUG_MAC80211(priv, "leave - scanning\n");
+		IWL_DEBUG_MAC80211(priv, "scan active\n");
 	}
 
 	if (changed & (IEEE80211_CONF_CHANGE_SMPS |
@@ -2440,11 +2432,13 @@
 
 	IWL_DEBUG_MAC80211(priv, "changes = 0x%X\n", changes);
 
-	if (!iwl_legacy_is_alive(priv))
-		return;
-
 	mutex_lock(&priv->mutex);
 
+	if (!iwl_legacy_is_alive(priv)) {
+		mutex_unlock(&priv->mutex);
+		return;
+	}
+
 	if (changes & BSS_CHANGED_QOS) {
 		unsigned long flags;
 
@@ -2653,7 +2647,7 @@
 
 none:
 	/* re-enable interrupts here since we don't have anything to service. */
-	/* only Re-enable if diabled by irq */
+	/* only Re-enable if disabled by irq */
 	if (test_bit(STATUS_INT_ENABLED, &priv->status))
 		iwl_legacy_enable_interrupts(priv);
 	spin_unlock_irqrestore(&priv->lock, flags);
diff -druN linux-2.6.39-libre/drivers/net/wireless/iwlegacy/iwl-core.h linux-3.0-rc7-libre/drivers/net/wireless/iwlegacy/iwl-core.h
--- linux-2.6.39-libre/drivers/net/wireless/iwlegacy/iwl-core.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/iwlegacy/iwl-core.h	2011-07-11 19:51:52.000000000 -0400
@@ -287,7 +287,6 @@
 	struct iwl_base_params *base_params;
 	/* params likely to change within a device family */
 	u8 scan_rx_antennas[IEEE80211_NUM_BANDS];
-	u8 scan_tx_antennas[IEEE80211_NUM_BANDS];
 	enum iwl_led_mode led_mode;
 };
 
@@ -561,7 +560,7 @@
 #define STATUS_SCAN_HW		15
 #define STATUS_POWER_PMI	16
 #define STATUS_FW_ERROR		17
-
+#define STATUS_CHANNEL_SWITCH_PENDING 18
 
 static inline int iwl_legacy_is_ready(struct iwl_priv *priv)
 {
diff -druN linux-2.6.39-libre/drivers/net/wireless/iwlegacy/iwl-dev.h linux-3.0-rc7-libre/drivers/net/wireless/iwlegacy/iwl-dev.h
--- linux-2.6.39-libre/drivers/net/wireless/iwlegacy/iwl-dev.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/iwlegacy/iwl-dev.h	2011-07-11 19:51:52.000000000 -0400
@@ -134,7 +134,7 @@
 				* space more than this */
 	int high_mark;         /* high watermark, stop queue if free
 				* space less than this */
-} __packed;
+};
 
 /* One for each TFD */
 struct iwl_tx_info {
@@ -290,6 +290,7 @@
 	CMD_SIZE_HUGE = (1 << 0),
 	CMD_ASYNC = (1 << 1),
 	CMD_WANT_SKB = (1 << 2),
+	CMD_MAPPED = (1 << 3),
 };
 
 #define DEF_CMD_PAYLOAD_SIZE 320
@@ -854,17 +855,6 @@
 };
 
 /*
- * iwl_switch_rxon: "channel switch" structure
- *
- * @ switch_in_progress: channel switch in progress
- * @ channel: new channel
- */
-struct iwl_switch_rxon {
-	bool switch_in_progress;
-	__le16 channel;
-};
-
-/*
  * schedule the timer to wake up every UCODE_TRACE_PERIOD milliseconds
  * to perform continuous uCode event logging operation if enabled
  */
@@ -1076,7 +1066,6 @@
 	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;
@@ -1115,7 +1104,7 @@
 
 	struct iwl_rxon_context contexts[NUM_IWL_RXON_CTX];
 
-	struct iwl_switch_rxon switch_rxon;
+	__le16 switch_channel;
 
 	/* 1st responses from initialize and runtime uCode images.
 	 * _4965's initialize alive response contains some calibration data. */
diff -druN linux-2.6.39-libre/drivers/net/wireless/iwlegacy/iwl-hcmd.c linux-3.0-rc7-libre/drivers/net/wireless/iwlegacy/iwl-hcmd.c
--- linux-2.6.39-libre/drivers/net/wireless/iwlegacy/iwl-hcmd.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/iwlegacy/iwl-hcmd.c	2011-07-11 19:51:52.000000000 -0400
@@ -145,6 +145,8 @@
 	int cmd_idx;
 	int ret;
 
+	lockdep_assert_held(&priv->mutex);
+
 	BUG_ON(cmd->flags & CMD_ASYNC);
 
 	 /* A synchronous command can not have a callback set. */
@@ -152,7 +154,6 @@
 
 	IWL_DEBUG_INFO(priv, "Attempting to send sync command %s\n",
 			iwl_legacy_get_cmd_string(cmd->id));
-	mutex_lock(&priv->sync_cmd_mutex);
 
 	set_bit(STATUS_HCMD_ACTIVE, &priv->status);
 	IWL_DEBUG_INFO(priv, "Setting HCMD_ACTIVE for command %s\n",
@@ -224,7 +225,6 @@
 		cmd->reply_page = 0;
 	}
 out:
-	mutex_unlock(&priv->sync_cmd_mutex);
 	return ret;
 }
 EXPORT_SYMBOL(iwl_legacy_send_cmd_sync);
diff -druN linux-2.6.39-libre/drivers/net/wireless/iwlegacy/iwl-helpers.h linux-3.0-rc7-libre/drivers/net/wireless/iwlegacy/iwl-helpers.h
--- linux-2.6.39-libre/drivers/net/wireless/iwlegacy/iwl-helpers.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/iwlegacy/iwl-helpers.h	2011-07-11 19:51:52.000000000 -0400
@@ -149,6 +149,12 @@
 	IWL_DEBUG_ISR(priv, "Disabled interrupts\n");
 }
 
+static inline void iwl_legacy_enable_rfkill_int(struct iwl_priv *priv)
+{
+	IWL_DEBUG_ISR(priv, "Enabling rfkill interrupt\n");
+	iwl_write32(priv, CSR_INT_MASK, CSR_INT_BIT_RF_KILL);
+}
+
 static inline void iwl_legacy_enable_interrupts(struct iwl_priv *priv)
 {
 	IWL_DEBUG_ISR(priv, "Enabling interrupts\n");
diff -druN linux-2.6.39-libre/drivers/net/wireless/iwlegacy/iwl-tx.c linux-3.0-rc7-libre/drivers/net/wireless/iwlegacy/iwl-tx.c
--- linux-2.6.39-libre/drivers/net/wireless/iwlegacy/iwl-tx.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/iwlegacy/iwl-tx.c	2011-07-11 19:51:52.000000000 -0400
@@ -146,33 +146,32 @@
 {
 	struct iwl_tx_queue *txq = &priv->txq[priv->cmd_queue];
 	struct iwl_queue *q = &txq->q;
-	bool huge = false;
 	int i;
 
 	if (q->n_bd == 0)
 		return;
 
 	while (q->read_ptr != q->write_ptr) {
-		/* we have no way to tell if it is a huge cmd ATM */
 		i = iwl_legacy_get_cmd_index(q, q->read_ptr, 0);
 
-		if (txq->meta[i].flags & CMD_SIZE_HUGE)
-			huge = true;
-		else
+		if (txq->meta[i].flags & CMD_MAPPED) {
 			pci_unmap_single(priv->pci_dev,
 					 dma_unmap_addr(&txq->meta[i], mapping),
 					 dma_unmap_len(&txq->meta[i], len),
 					 PCI_DMA_BIDIRECTIONAL);
+			txq->meta[i].flags = 0;
+		}
 
 		q->read_ptr = iwl_legacy_queue_inc_wrap(q->read_ptr, q->n_bd);
 	}
 
-	if (huge) {
-		i = q->n_window;
+	i = q->n_window;
+	if (txq->meta[i].flags & CMD_MAPPED) {
 		pci_unmap_single(priv->pci_dev,
 				 dma_unmap_addr(&txq->meta[i], mapping),
 				 dma_unmap_len(&txq->meta[i], len),
 				 PCI_DMA_BIDIRECTIONAL);
+		txq->meta[i].flags = 0;
 	}
 }
 EXPORT_SYMBOL(iwl_legacy_cmd_queue_unmap);
@@ -467,29 +466,27 @@
 		return -EIO;
 	}
 
+	spin_lock_irqsave(&priv->hcmd_lock, flags);
+
 	if (iwl_legacy_queue_space(q) < ((cmd->flags & CMD_ASYNC) ? 2 : 1)) {
-		IWL_ERR(priv, "No space in command queue\n");
-		IWL_ERR(priv, "Restarting adapter due to queue full\n");
+		spin_unlock_irqrestore(&priv->hcmd_lock, flags);
+
+		IWL_ERR(priv, "Restarting adapter due to command queue full\n");
 		queue_work(priv->workqueue, &priv->restart);
 		return -ENOSPC;
 	}
 
-	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 = iwl_legacy_get_cmd_index(q, q->write_ptr, 0);
-		txq->meta[idx].flags = CMD_SIZE_HUGE;
-	}
-
 	idx = iwl_legacy_get_cmd_index(q, q->write_ptr, cmd->flags & CMD_SIZE_HUGE);
 	out_cmd = txq->cmd[idx];
 	out_meta = &txq->meta[idx];
 
+	if (WARN_ON(out_meta->flags & CMD_MAPPED)) {
+		spin_unlock_irqrestore(&priv->hcmd_lock, flags);
+		return -ENOSPC;
+	}
+
 	memset(out_meta, 0, sizeof(*out_meta));	/* re-initialize to NULL */
-	out_meta->flags = cmd->flags;
+	out_meta->flags = cmd->flags | CMD_MAPPED;
 	if (cmd->flags & CMD_WANT_SKB)
 		out_meta->source = cmd;
 	if (cmd->flags & CMD_ASYNC)
@@ -610,6 +607,7 @@
 	struct iwl_device_cmd *cmd;
 	struct iwl_cmd_meta *meta;
 	struct iwl_tx_queue *txq = &priv->txq[priv->cmd_queue];
+	unsigned long flags;
 
 	/* 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
@@ -623,14 +621,6 @@
 		return;
 	}
 
-	/* If this is a huge cmd, clear the huge flag on the meta.flags
-	 * of the _original_ cmd. So that iwl_legacy_cmd_queue_free won't unmap
-	 * the DMA buffer for the scan (huge) command.
-	 */
-	if (huge) {
-		cmd_index = iwl_legacy_get_cmd_index(&txq->q, index, 0);
-		txq->meta[cmd_index].flags = 0;
-	}
 	cmd_index = iwl_legacy_get_cmd_index(&txq->q, index, huge);
 	cmd = txq->cmd[cmd_index];
 	meta = &txq->meta[cmd_index];
@@ -647,6 +637,8 @@
 	} else if (meta->callback)
 		meta->callback(priv, cmd, pkt);
 
+	spin_lock_irqsave(&priv->hcmd_lock, flags);
+
 	iwl_legacy_hcmd_queue_reclaim(priv, txq_id, index, cmd_index);
 
 	if (!(meta->flags & CMD_ASYNC)) {
@@ -655,6 +647,10 @@
 			       iwl_legacy_get_cmd_string(cmd->hdr.cmd));
 		wake_up_interruptible(&priv->wait_command_queue);
 	}
+
+	/* Mark as unmapped */
 	meta->flags = 0;
+
+	spin_unlock_irqrestore(&priv->hcmd_lock, flags);
 }
 EXPORT_SYMBOL(iwl_legacy_tx_cmd_complete);
diff -druN linux-2.6.39-libre/drivers/net/wireless/iwlwifi/iwl-1000.c linux-3.0-rc7-libre/drivers/net/wireless/iwlwifi/iwl-1000.c
--- linux-2.6.39-libre/drivers/net/wireless/iwlwifi/iwl-1000.c	2011-05-19 02:14:27.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/iwlwifi/iwl-1000.c	2011-07-21 06:56:51.000000000 -0400
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
@@ -36,6 +36,7 @@
 #include <net/mac80211.h>
 #include <linux/etherdevice.h>
 #include <asm/unaligned.h>
+#include <linux/stringify.h>
 
 #include "iwl-eeprom.h"
 #include "iwl-dev.h"
@@ -45,8 +46,6 @@
 #include "iwl-agn.h"
 #include "iwl-helpers.h"
 #include "iwl-agn-hw.h"
-#include "iwl-agn-led.h"
-#include "iwl-agn-debugfs.h"
 
 /* Highest firmware API version supported */
 #define IWL1000_UCODE_API_MAX 5
@@ -57,12 +56,10 @@
 #define IWL100_UCODE_API_MIN 5
 
 #define IWL1000_FW_PRE "/*(DEBLOBBED)*/"
-#define _IWL1000_MODULE_FIRMWARE(api) IWL1000_FW_PRE /*(DEBLOBBED)*/
-#define IWL1000_MODULE_FIRMWARE(api) _IWL1000_MODULE_FIRMWARE(api)
+#define IWL1000_MODULE_FIRMWARE(api) IWL1000_FW_PRE __stringify(api) "/*(DEBLOBBED)*/
 
 #define IWL100_FW_PRE "/*(DEBLOBBED)*/"
-#define _IWL100_MODULE_FIRMWARE(api) IWL100_FW_PRE /*(DEBLOBBED)*/
-#define IWL100_MODULE_FIRMWARE(api) _IWL100_MODULE_FIRMWARE(api)
+#define IWL100_MODULE_FIRMWARE(api) IWL100_FW_PRE __stringify(api) "/*(DEBLOBBED)*/
 
 
 /*
@@ -124,10 +121,10 @@
 
 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 <= IWLAGN_NUM_QUEUES)
+	if (iwlagn_mod_params.num_of_queues >= IWL_MIN_NUM_QUEUES &&
+	    iwlagn_mod_params.num_of_queues <= IWLAGN_NUM_QUEUES)
 		priv->cfg->base_params->num_of_queues =
-			priv->cfg->mod_params->num_of_queues;
+			iwlagn_mod_params.num_of_queues;
 
 	priv->hw_params.max_txq_num = priv->cfg->base_params->num_of_queues;
 	priv->hw_params.dma_chnl_num = FH50_TCSR_CHNL_NUM;
@@ -141,7 +138,6 @@
 	priv->hw_params.max_data_size = IWLAGN_RTC_DATA_SIZE;
 	priv->hw_params.max_inst_size = IWLAGN_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;
@@ -176,24 +172,9 @@
 
 static struct iwl_lib_ops iwl1000_lib = {
 	.set_hw_params = iwl1000_hw_set_hw_params,
-	.txq_update_byte_cnt_tbl = iwlagn_txq_update_byte_cnt_tbl,
-	.txq_inval_byte_cnt_tbl = iwlagn_txq_inval_byte_cnt_tbl,
-	.txq_set_sched = iwlagn_txq_set_sched,
-	.txq_agg_enable = iwlagn_txq_agg_enable,
-	.txq_agg_disable = iwlagn_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 = iwlagn_rx_handler_setup,
 	.setup_deferred_work = iwlagn_setup_deferred_work,
 	.is_valid_rtc_data_addr = iwlagn_hw_valid_rtc_data_addr,
-	.load_ucode = iwlagn_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 = iwlagn_init_alive_start,
-	.alive_notify = iwlagn_alive_notify,
 	.send_tx_power = iwlagn_send_tx_power,
 	.update_chain_flags = iwl_update_chain_flags,
 	.apm_ops = {
@@ -208,45 +189,21 @@
 			EEPROM_REG_BAND_4_CHANNELS,
 			EEPROM_REG_BAND_5_CHANNELS,
 			EEPROM_REG_BAND_24_HT40_CHANNELS,
-			EEPROM_REG_BAND_52_HT40_CHANNELS
+			EEPROM_REGULATORY_BAND_NO_HT40,
 		},
-		.acquire_semaphore = iwlcore_eeprom_acquire_semaphore,
-		.release_semaphore = iwlcore_eeprom_release_semaphore,
-		.calib_version	= iwlagn_eeprom_calib_version,
 		.query_addr = iwlagn_eeprom_query_addr,
 	},
-	.isr_ops = {
-		.isr = iwl_isr_ict,
-		.free = iwl_free_isr_ict,
-		.alloc = iwl_alloc_isr_ict,
-		.reset = iwl_reset_ict,
-		.disable = iwl_disable_ict,
-	},
 	.temp_ops = {
 		.temperature = iwlagn_temperature,
 	 },
-	.debugfs_ops = {
-		.rx_stats_read = iwl_ucode_rx_stats_read,
-		.tx_stats_read = iwl_ucode_tx_stats_read,
-		.general_stats_read = iwl_ucode_general_stats_read,
-		.bt_stats_read = iwl_ucode_bt_stats_read,
-		.reply_tx_error = iwl_reply_tx_error_read,
-	},
 	.txfifo_flush = iwlagn_txfifo_flush,
 	.dev_txfifo_flush = iwlagn_dev_txfifo_flush,
-	.tt_ops = {
-		.lower_power_detection = iwl_tt_is_low_power_state,
-		.tt_power_mode = iwl_tt_current_power_mode,
-		.ct_kill_check = iwl_check_for_ct_kill,
-	}
 };
 
 static const struct iwl_ops iwl1000_ops = {
 	.lib = &iwl1000_lib,
 	.hcmd = &iwlagn_hcmd,
 	.utils = &iwlagn_hcmd_utils,
-	.led = &iwlagn_led_ops,
-	.ieee80211_ops = &iwlagn_hw_ops,
 };
 
 static struct iwl_base_params iwl1000_base_params = {
@@ -254,8 +211,6 @@
 	.num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES,
 	.eeprom_size = OTP_LOW_IMAGE_SIZE,
 	.pll_cfg_val = CSR50_ANA_PLL_CFG_VAL,
-	.set_l0s = true,
-	.use_bsm = false,
 	.max_ll_items = OTP_MAX_LL_ITEMS_1000,
 	.shadow_ram_support = false,
 	.led_compensation = 51,
@@ -265,9 +220,6 @@
 	.chain_noise_scale = 1000,
 	.wd_timeout = IWL_DEF_WD_TIMEOUT,
 	.max_event_log_size = 128,
-	.ucode_tracing = true,
-	.sensitivity_calib_by_driver = true,
-	.chain_noise_calib_by_driver = true,
 };
 static struct iwl_ht_params iwl1000_ht_params = {
 	.ht_greenfield_support = true,
@@ -281,7 +233,6 @@
 	.eeprom_ver = EEPROM_1000_EEPROM_VERSION,		\
 	.eeprom_calib_ver = EEPROM_1000_TX_POWER_VERSION,	\
 	.ops = &iwl1000_ops,					\
-	.mod_params = &iwlagn_mod_params,			\
 	.base_params = &iwl1000_base_params,			\
 	.led_mode = IWL_LED_BLINK
 
@@ -303,7 +254,6 @@
 	.eeprom_ver = EEPROM_1000_EEPROM_VERSION,		\
 	.eeprom_calib_ver = EEPROM_1000_TX_POWER_VERSION,	\
 	.ops = &iwl1000_ops,					\
-	.mod_params = &iwlagn_mod_params,			\
 	.base_params = &iwl1000_base_params,			\
 	.led_mode = IWL_LED_RF_STATE,				\
 	.rx_with_siso_diversity = true
diff -druN linux-2.6.39-libre/drivers/net/wireless/iwlwifi/iwl-2000.c linux-3.0-rc7-libre/drivers/net/wireless/iwlwifi/iwl-2000.c
--- linux-2.6.39-libre/drivers/net/wireless/iwlwifi/iwl-2000.c	2011-05-19 02:14:29.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/iwlwifi/iwl-2000.c	2011-07-21 06:56:53.000000000 -0400
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
@@ -36,6 +36,7 @@
 #include <net/mac80211.h>
 #include <linux/etherdevice.h>
 #include <asm/unaligned.h>
+#include <linux/stringify.h>
 
 #include "iwl-eeprom.h"
 #include "iwl-dev.h"
@@ -46,30 +47,25 @@
 #include "iwl-helpers.h"
 #include "iwl-agn-hw.h"
 #include "iwl-6000-hw.h"
-#include "iwl-agn-led.h"
-#include "iwl-agn-debugfs.h"
 
 /* Highest firmware API version supported */
 #define IWL2030_UCODE_API_MAX 5
 #define IWL2000_UCODE_API_MAX 5
-#define IWL200_UCODE_API_MAX 5
+#define IWL105_UCODE_API_MAX 5
 
 /* Lowest firmware API version supported */
 #define IWL2030_UCODE_API_MIN 5
 #define IWL2000_UCODE_API_MIN 5
-#define IWL200_UCODE_API_MIN 5
+#define IWL105_UCODE_API_MIN 5
 
 #define IWL2030_FW_PRE "iwlwifi-2030-"
-#define _IWL2030_MODULE_FIRMWARE(api) IWL2030_FW_PRE /*(DEBLOBBED)*/
-#define IWL2030_MODULE_FIRMWARE(api) _IWL2030_MODULE_FIRMWARE(api)
+#define IWL2030_MODULE_FIRMWARE(api) IWL2030_FW_PRE __stringify(api) "/*(DEBLOBBED)*/
 
 #define IWL2000_FW_PRE "iwlwifi-2000-"
-#define _IWL2000_MODULE_FIRMWARE(api) IWL2000_FW_PRE /*(DEBLOBBED)*/
-#define IWL2000_MODULE_FIRMWARE(api) _IWL2000_MODULE_FIRMWARE(api)
+#define IWL2000_MODULE_FIRMWARE(api) IWL2000_FW_PRE __stringify(api) "/*(DEBLOBBED)*/
 
-#define IWL200_FW_PRE "iwlwifi-200-"
-#define _IWL200_MODULE_FIRMWARE(api) IWL200_FW_PRE /*(DEBLOBBED)*/
-#define IWL200_MODULE_FIRMWARE(api) _IWL200_MODULE_FIRMWARE(api)
+#define IWL105_FW_PRE "iwlwifi-105-"
+#define IWL105_MODULE_FIRMWARE(api) IWL105_FW_PRE __stringify(api) "/*(DEBLOBBED)*/
 
 static void iwl2000_set_ct_threshold(struct iwl_priv *priv)
 {
@@ -101,6 +97,8 @@
 		iwl_set_bit(priv, CSR_GP_DRIVER_REG,
 			    CSR_GP_DRIVER_REG_BIT_RADIO_IQ_INVER);
 
+	if (priv->cfg->disable_otp_refresh)
+		iwl_write_prph(priv, APMG_ANALOG_SVR_REG, 0x80000010);
 }
 
 static struct iwl_sensitivity_ranges iwl2000_sensitivity = {
@@ -130,10 +128,10 @@
 
 static int iwl2000_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 <= IWLAGN_NUM_QUEUES)
+	if (iwlagn_mod_params.num_of_queues >= IWL_MIN_NUM_QUEUES &&
+	    iwlagn_mod_params.num_of_queues <= IWLAGN_NUM_QUEUES)
 		priv->cfg->base_params->num_of_queues =
-			priv->cfg->mod_params->num_of_queues;
+			iwlagn_mod_params.num_of_queues;
 
 	priv->hw_params.max_txq_num = priv->cfg->base_params->num_of_queues;
 	priv->hw_params.dma_chnl_num = FH50_TCSR_CHNL_NUM;
@@ -147,7 +145,6 @@
 	priv->hw_params.max_data_size = IWL60_RTC_DATA_SIZE;
 	priv->hw_params.max_inst_size = IWL60_RTC_INST_SIZE;
 
-	priv->hw_params.max_bsm_size = 0;
 	priv->hw_params.ht40_channel =  BIT(IEEE80211_BAND_2GHZ) |
 					BIT(IEEE80211_BAND_5GHZ);
 	priv->hw_params.rx_wrt_ptr_reg = FH_RSCSR_CHNL0_WPTR;
@@ -181,103 +178,14 @@
 	return 0;
 }
 
-static int iwl2030_hw_channel_switch(struct iwl_priv *priv,
-                                    struct ieee80211_channel_switch *ch_switch)
-{
-	/*
-	 * MULTI-FIXME
-	 * See iwl_mac_channel_switch.
-	 */
-	struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
-	struct iwl6000_channel_switch_cmd cmd;
-	const struct iwl_channel_info *ch_info;
-	u32 switch_time_in_usec, ucode_switch_time;
-	u16 ch;
-	u32 tsf_low;
-	u8 switch_count;
-	u16 beacon_interval = le16_to_cpu(ctx->timing.beacon_interval);
-	struct ieee80211_vif *vif = ctx->vif;
-	struct iwl_host_cmd hcmd = {
-		.id = REPLY_CHANNEL_SWITCH,
-		.len = sizeof(cmd),
-		.flags = CMD_SYNC,
-		.data = &cmd,
-	};
-
-	cmd.band = priv->band == IEEE80211_BAND_2GHZ;
-	ch = ch_switch->channel->hw_value;
-	IWL_DEBUG_11H(priv, "channel switch from %u to %u\n",
-		ctx->active.channel, ch);
-	cmd.channel = cpu_to_le16(ch);
-	cmd.rxon_flags = ctx->staging.flags;
-	cmd.rxon_filter_flags = ctx->staging.filter_flags;
-	switch_count = ch_switch->count;
-	tsf_low = ch_switch->timestamp & 0x0ffffffff;
-	/*
-	 * calculate the ucode channel switch time
-	 * adding TSF as one of the factor for when to switch
-	 */
-	if ((priv->ucode_beacon_time > tsf_low) && beacon_interval) {
-		if (switch_count > ((priv->ucode_beacon_time - tsf_low) /
-		    beacon_interval)) {
-			switch_count -= (priv->ucode_beacon_time -
-				tsf_low) / beacon_interval;
-		} else
-			switch_count = 0;
-	}
-	if (switch_count <= 1)
-		cmd.switch_time = cpu_to_le32(priv->ucode_beacon_time);
-	else {
-		switch_time_in_usec =
-			vif->bss_conf.beacon_int * switch_count * TIME_UNIT;
-		ucode_switch_time = iwl_usecs_to_beacons(priv,
-						switch_time_in_usec,
-						beacon_interval);
-		cmd.switch_time = iwl_add_beacon_time(priv,
-						priv->ucode_beacon_time,
-						ucode_switch_time,
-						beacon_interval);
-	}
-	IWL_DEBUG_11H(priv, "uCode time for the switch is 0x%x\n",
-		      cmd.switch_time);
-	ch_info = iwl_get_channel_info(priv, priv->band, ch);
-	if (ch_info)
-		cmd.expect_beacon = is_channel_radar(ch_info);
-	else {
-		IWL_ERR(priv, "invalid channel switch from %u to %u\n",
-			ctx->active.channel, ch);
-		return -EFAULT;
-	}
-	priv->switch_rxon.channel = cmd.channel;
-	priv->switch_rxon.switch_in_progress = true;
-
-	return iwl_send_cmd_sync(priv, &hcmd);
-}
-
 static struct iwl_lib_ops iwl2000_lib = {
 	.set_hw_params = iwl2000_hw_set_hw_params,
-	.txq_update_byte_cnt_tbl = iwlagn_txq_update_byte_cnt_tbl,
-	.txq_inval_byte_cnt_tbl = iwlagn_txq_inval_byte_cnt_tbl,
-	.txq_set_sched = iwlagn_txq_set_sched,
-	.txq_agg_enable = iwlagn_txq_agg_enable,
-	.txq_agg_disable = iwlagn_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 = iwlagn_rx_handler_setup,
 	.setup_deferred_work = iwlagn_bt_setup_deferred_work,
 	.cancel_deferred_work = iwlagn_bt_cancel_deferred_work,
 	.is_valid_rtc_data_addr = iwlagn_hw_valid_rtc_data_addr,
-	.load_ucode = iwlagn_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 = iwlagn_init_alive_start,
-	.alive_notify = iwlagn_alive_notify,
 	.send_tx_power = iwlagn_send_tx_power,
 	.update_chain_flags = iwl_update_chain_flags,
-	.set_channel_switch = iwl2030_hw_channel_switch,
 	.apm_ops = {
 		.init = iwl_apm_init,
 		.config = iwl2000_nic_config,
@@ -290,70 +198,40 @@
 			EEPROM_REG_BAND_4_CHANNELS,
 			EEPROM_REG_BAND_5_CHANNELS,
 			EEPROM_6000_REG_BAND_24_HT40_CHANNELS,
-			EEPROM_REG_BAND_52_HT40_CHANNELS
+			EEPROM_REGULATORY_BAND_NO_HT40,
 		},
-		.acquire_semaphore = iwlcore_eeprom_acquire_semaphore,
-		.release_semaphore = iwlcore_eeprom_release_semaphore,
-		.calib_version  = iwlagn_eeprom_calib_version,
 		.query_addr = iwlagn_eeprom_query_addr,
 		.update_enhanced_txpower = iwlcore_eeprom_enhanced_txpower,
 	},
-	.isr_ops = {
-		.isr = iwl_isr_ict,
-		.free = iwl_free_isr_ict,
-		.alloc = iwl_alloc_isr_ict,
-		.reset = iwl_reset_ict,
-		.disable = iwl_disable_ict,
-	},
 	.temp_ops = {
 		.temperature = iwlagn_temperature,
 	},
-	.debugfs_ops = {
-		.rx_stats_read = iwl_ucode_rx_stats_read,
-		.tx_stats_read = iwl_ucode_tx_stats_read,
-		.general_stats_read = iwl_ucode_general_stats_read,
-		.bt_stats_read = iwl_ucode_bt_stats_read,
-		.reply_tx_error = iwl_reply_tx_error_read,
-	},
 	.txfifo_flush = iwlagn_txfifo_flush,
 	.dev_txfifo_flush = iwlagn_dev_txfifo_flush,
-	.tt_ops = {
-		.lower_power_detection = iwl_tt_is_low_power_state,
-		.tt_power_mode = iwl_tt_current_power_mode,
-		.ct_kill_check = iwl_check_for_ct_kill,
-	}
 };
 
 static const struct iwl_ops iwl2000_ops = {
 	.lib = &iwl2000_lib,
 	.hcmd = &iwlagn_hcmd,
 	.utils = &iwlagn_hcmd_utils,
-	.led = &iwlagn_led_ops,
-	.ieee80211_ops = &iwlagn_hw_ops,
 };
 
 static const struct iwl_ops iwl2030_ops = {
 	.lib = &iwl2000_lib,
 	.hcmd = &iwlagn_bt_hcmd,
 	.utils = &iwlagn_hcmd_utils,
-	.led = &iwlagn_led_ops,
-	.ieee80211_ops = &iwlagn_hw_ops,
 };
 
-static const struct iwl_ops iwl200_ops = {
+static const struct iwl_ops iwl105_ops = {
 	.lib = &iwl2000_lib,
 	.hcmd = &iwlagn_hcmd,
 	.utils = &iwlagn_hcmd_utils,
-	.led = &iwlagn_led_ops,
-	.ieee80211_ops = &iwlagn_hw_ops,
 };
 
-static const struct iwl_ops iwl230_ops = {
+static const struct iwl_ops iwl135_ops = {
 	.lib = &iwl2000_lib,
 	.hcmd = &iwlagn_bt_hcmd,
 	.utils = &iwlagn_hcmd_utils,
-	.led = &iwlagn_led_ops,
-	.ieee80211_ops = &iwlagn_hw_ops,
 };
 
 static struct iwl_base_params iwl2000_base_params = {
@@ -361,8 +239,6 @@
 	.num_of_queues = IWLAGN_NUM_QUEUES,
 	.num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES,
 	.pll_cfg_val = 0,
-	.set_l0s = true,
-	.use_bsm = false,
 	.max_ll_items = OTP_MAX_LL_ITEMS_2x00,
 	.shadow_ram_support = true,
 	.led_compensation = 51,
@@ -373,9 +249,6 @@
 	.chain_noise_scale = 1000,
 	.wd_timeout = IWL_DEF_WD_TIMEOUT,
 	.max_event_log_size = 512,
-	.ucode_tracing = true,
-	.sensitivity_calib_by_driver = true,
-	.chain_noise_calib_by_driver = true,
 	.shadow_reg_enable = true,
 };
 
@@ -385,8 +258,6 @@
 	.num_of_queues = IWLAGN_NUM_QUEUES,
 	.num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES,
 	.pll_cfg_val = 0,
-	.set_l0s = true,
-	.use_bsm = false,
 	.max_ll_items = OTP_MAX_LL_ITEMS_2x00,
 	.shadow_ram_support = true,
 	.led_compensation = 57,
@@ -397,9 +268,6 @@
 	.chain_noise_scale = 1000,
 	.wd_timeout = IWL_LONG_WD_TIMEOUT,
 	.max_event_log_size = 512,
-	.ucode_tracing = true,
-	.sensitivity_calib_by_driver = true,
-	.chain_noise_calib_by_driver = true,
 	.shadow_reg_enable = true,
 };
 
@@ -409,7 +277,6 @@
 };
 
 static struct iwl_bt_params iwl2030_bt_params = {
-	.bt_statistics = true,
 	/* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */
 	.advanced_bt_coexist = true,
 	.agg_time_limit = BT_AGG_THRESHOLD_DEF,
@@ -426,12 +293,12 @@
 	.eeprom_ver = EEPROM_2000_EEPROM_VERSION,		\
 	.eeprom_calib_ver = EEPROM_2000_TX_POWER_VERSION,	\
 	.ops = &iwl2000_ops,					\
-	.mod_params = &iwlagn_mod_params,			\
 	.base_params = &iwl2000_base_params,			\
 	.need_dc_calib = true,					\
 	.need_temp_offset_calib = true,				\
 	.led_mode = IWL_LED_RF_STATE,				\
-	.iq_invert = true					\
+	.iq_invert = true,					\
+	.disable_otp_refresh = true				\
 
 struct iwl_cfg iwl2000_2bgn_cfg = {
 	.name = "2000 Series 2x2 BGN",
@@ -451,7 +318,6 @@
 	.eeprom_ver = EEPROM_2000_EEPROM_VERSION,		\
 	.eeprom_calib_ver = EEPROM_2000_TX_POWER_VERSION,	\
 	.ops = &iwl2030_ops,					\
-	.mod_params = &iwlagn_mod_params,			\
 	.base_params = &iwl2030_base_params,			\
 	.bt_params = &iwl2030_bt_params,			\
 	.need_dc_calib = true,					\
@@ -471,45 +337,13 @@
 	IWL_DEVICE_2030,
 };
 
-#define IWL_DEVICE_6035						\
-	.fw_name_pre = IWL2030_FW_PRE,				\
-	.ucode_api_max = IWL2030_UCODE_API_MAX,			\
-	.ucode_api_min = IWL2030_UCODE_API_MIN,			\
-	.eeprom_ver = EEPROM_6035_EEPROM_VERSION,		\
-	.eeprom_calib_ver = EEPROM_6035_TX_POWER_VERSION,	\
-	.ops = &iwl2030_ops,					\
-	.mod_params = &iwlagn_mod_params,			\
-	.base_params = &iwl2030_base_params,			\
-	.bt_params = &iwl2030_bt_params,			\
-	.need_dc_calib = true,					\
-	.need_temp_offset_calib = true,				\
-	.led_mode = IWL_LED_RF_STATE,				\
-	.adv_pm = true						\
-
-struct iwl_cfg iwl6035_2agn_cfg = {
-	.name = "2000 Series 2x2 AGN/BT",
-	IWL_DEVICE_6035,
-	.ht_params = &iwl2000_ht_params,
-};
-
-struct iwl_cfg iwl6035_2abg_cfg = {
-	.name = "2000 Series 2x2 ABG/BT",
-	IWL_DEVICE_6035,
-};
-
-struct iwl_cfg iwl6035_2bg_cfg = {
-	.name = "2000 Series 2x2 BG/BT",
-	IWL_DEVICE_6035,
-};
-
-#define IWL_DEVICE_200						\
-	.fw_name_pre = IWL200_FW_PRE,				\
-	.ucode_api_max = IWL200_UCODE_API_MAX,			\
-	.ucode_api_min = IWL200_UCODE_API_MIN,			\
+#define IWL_DEVICE_105						\
+	.fw_name_pre = IWL105_FW_PRE,				\
+	.ucode_api_max = IWL105_UCODE_API_MAX,			\
+	.ucode_api_min = IWL105_UCODE_API_MIN,			\
 	.eeprom_ver = EEPROM_2000_EEPROM_VERSION,		\
 	.eeprom_calib_ver = EEPROM_2000_TX_POWER_VERSION,	\
-	.ops = &iwl200_ops,					\
-	.mod_params = &iwlagn_mod_params,			\
+	.ops = &iwl105_ops,					\
 	.base_params = &iwl2000_base_params,			\
 	.need_dc_calib = true,					\
 	.need_temp_offset_calib = true,				\
@@ -517,25 +351,24 @@
 	.adv_pm = true,						\
 	.rx_with_siso_diversity = true				\
 
-struct iwl_cfg iwl200_bg_cfg = {
-	.name = "200 Series 1x1 BG",
-	IWL_DEVICE_200,
+struct iwl_cfg iwl105_bg_cfg = {
+	.name = "105 Series 1x1 BG",
+	IWL_DEVICE_105,
 };
 
-struct iwl_cfg iwl200_bgn_cfg = {
-	.name = "200 Series 1x1 BGN",
-	IWL_DEVICE_200,
+struct iwl_cfg iwl105_bgn_cfg = {
+	.name = "105 Series 1x1 BGN",
+	IWL_DEVICE_105,
 	.ht_params = &iwl2000_ht_params,
 };
 
-#define IWL_DEVICE_230						\
-	.fw_name_pre = IWL200_FW_PRE,				\
-	.ucode_api_max = IWL200_UCODE_API_MAX,			\
-	.ucode_api_min = IWL200_UCODE_API_MIN,			\
+#define IWL_DEVICE_135						\
+	.fw_name_pre = IWL105_FW_PRE,				\
+	.ucode_api_max = IWL105_UCODE_API_MAX,			\
+	.ucode_api_min = IWL105_UCODE_API_MIN,			\
 	.eeprom_ver = EEPROM_2000_EEPROM_VERSION,		\
 	.eeprom_calib_ver = EEPROM_2000_TX_POWER_VERSION,	\
-	.ops = &iwl230_ops,					\
-	.mod_params = &iwlagn_mod_params,			\
+	.ops = &iwl135_ops,					\
 	.base_params = &iwl2030_base_params,			\
 	.bt_params = &iwl2030_bt_params,			\
 	.need_dc_calib = true,					\
@@ -544,14 +377,14 @@
 	.adv_pm = true,						\
 	.rx_with_siso_diversity = true				\
 
-struct iwl_cfg iwl230_bg_cfg = {
-	.name = "200 Series 1x1 BG/BT",
-	IWL_DEVICE_230,
+struct iwl_cfg iwl135_bg_cfg = {
+	.name = "105 Series 1x1 BG/BT",
+	IWL_DEVICE_135,
 };
 
-struct iwl_cfg iwl230_bgn_cfg = {
-	.name = "200 Series 1x1 BGN/BT",
-	IWL_DEVICE_230,
+struct iwl_cfg iwl135_bgn_cfg = {
+	.name = "105 Series 1x1 BGN/BT",
+	IWL_DEVICE_135,
 	.ht_params = &iwl2000_ht_params,
 };
 
diff -druN linux-2.6.39-libre/drivers/net/wireless/iwlwifi/iwl-5000.c linux-3.0-rc7-libre/drivers/net/wireless/iwlwifi/iwl-5000.c
--- linux-2.6.39-libre/drivers/net/wireless/iwlwifi/iwl-5000.c	2011-05-19 02:14:23.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/iwlwifi/iwl-5000.c	2011-07-21 06:56:47.000000000 -0400
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2007 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2007 - 2011 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,6 +37,7 @@
 #include <net/mac80211.h>
 #include <linux/etherdevice.h>
 #include <asm/unaligned.h>
+#include <linux/stringify.h>
 
 #include "iwl-eeprom.h"
 #include "iwl-dev.h"
@@ -45,10 +46,8 @@
 #include "iwl-sta.h"
 #include "iwl-helpers.h"
 #include "iwl-agn.h"
-#include "iwl-agn-led.h"
 #include "iwl-agn-hw.h"
 #include "iwl-5000-hw.h"
-#include "iwl-agn-debugfs.h"
 
 /* Highest firmware API version supported */
 #define IWL5000_UCODE_API_MAX 5
@@ -59,12 +58,10 @@
 #define IWL5150_UCODE_API_MIN 1
 
 #define IWL5000_FW_PRE "/*(DEBLOBBED)*/"
-#define _IWL5000_MODULE_FIRMWARE(api) IWL5000_FW_PRE /*(DEBLOBBED)*/
-#define IWL5000_MODULE_FIRMWARE(api) _IWL5000_MODULE_FIRMWARE(api)
+#define IWL5000_MODULE_FIRMWARE(api) IWL5000_FW_PRE __stringify(api) "/*(DEBLOBBED)*/
 
 #define IWL5150_FW_PRE "/*(DEBLOBBED)*/"
-#define _IWL5150_MODULE_FIRMWARE(api) IWL5150_FW_PRE /*(DEBLOBBED)*/
-#define IWL5150_MODULE_FIRMWARE(api) _IWL5150_MODULE_FIRMWARE(api)
+#define IWL5150_MODULE_FIRMWARE(api) IWL5150_FW_PRE __stringify(api) "/*(DEBLOBBED)*/
 
 /* NIC configuration for 5000 series */
 static void iwl5000_nic_config(struct iwl_priv *priv)
@@ -168,10 +165,10 @@
 
 static int iwl5000_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 <= IWLAGN_NUM_QUEUES)
+	if (iwlagn_mod_params.num_of_queues >= IWL_MIN_NUM_QUEUES &&
+	    iwlagn_mod_params.num_of_queues <= IWLAGN_NUM_QUEUES)
 		priv->cfg->base_params->num_of_queues =
-			priv->cfg->mod_params->num_of_queues;
+			iwlagn_mod_params.num_of_queues;
 
 	priv->hw_params.max_txq_num = priv->cfg->base_params->num_of_queues;
 	priv->hw_params.dma_chnl_num = FH50_TCSR_CHNL_NUM;
@@ -185,7 +182,6 @@
 	priv->hw_params.max_data_size = IWLAGN_RTC_DATA_SIZE;
 	priv->hw_params.max_inst_size = IWLAGN_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;
@@ -214,10 +210,10 @@
 
 static int iwl5150_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 <= IWLAGN_NUM_QUEUES)
+	if (iwlagn_mod_params.num_of_queues >= IWL_MIN_NUM_QUEUES &&
+	    iwlagn_mod_params.num_of_queues <= IWLAGN_NUM_QUEUES)
 		priv->cfg->base_params->num_of_queues =
-			priv->cfg->mod_params->num_of_queues;
+			iwlagn_mod_params.num_of_queues;
 
 	priv->hw_params.max_txq_num = priv->cfg->base_params->num_of_queues;
 	priv->hw_params.dma_chnl_num = FH50_TCSR_CHNL_NUM;
@@ -231,7 +227,6 @@
 	priv->hw_params.max_data_size = IWLAGN_RTC_DATA_SIZE;
 	priv->hw_params.max_inst_size = IWLAGN_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;
@@ -263,7 +258,7 @@
 	u32 vt = 0;
 	s32 offset =  iwl_temp_calib_to_offset(priv);
 
-	vt = le32_to_cpu(priv->_agn.statistics.general.common.temperature);
+	vt = le32_to_cpu(priv->statistics.common.temperature);
 	vt = vt / IWL_5150_VOLTAGE_TO_TEMPERATURE_COEFF + offset;
 	/* now vt hold the temperature in Kelvin */
 	priv->temperature = KELVIN_TO_CELSIUS(vt);
@@ -288,9 +283,9 @@
 	struct ieee80211_vif *vif = ctx->vif;
 	struct iwl_host_cmd hcmd = {
 		.id = REPLY_CHANNEL_SWITCH,
-		.len = sizeof(cmd),
+		.len = { sizeof(cmd), },
 		.flags = CMD_SYNC,
-		.data = &cmd,
+		.data = { &cmd, },
 	};
 
 	cmd.band = priv->band == IEEE80211_BAND_2GHZ;
@@ -337,32 +332,15 @@
 			ctx->active.channel, ch);
 		return -EFAULT;
 	}
-	priv->switch_rxon.channel = cmd.channel;
-	priv->switch_rxon.switch_in_progress = true;
 
 	return iwl_send_cmd_sync(priv, &hcmd);
 }
 
 static struct iwl_lib_ops iwl5000_lib = {
 	.set_hw_params = iwl5000_hw_set_hw_params,
-	.txq_update_byte_cnt_tbl = iwlagn_txq_update_byte_cnt_tbl,
-	.txq_inval_byte_cnt_tbl = iwlagn_txq_inval_byte_cnt_tbl,
-	.txq_set_sched = iwlagn_txq_set_sched,
-	.txq_agg_enable = iwlagn_txq_agg_enable,
-	.txq_agg_disable = iwlagn_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 = iwlagn_rx_handler_setup,
 	.setup_deferred_work = iwlagn_setup_deferred_work,
 	.is_valid_rtc_data_addr = iwlagn_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 = iwlagn_load_ucode,
-	.init_alive_start = iwlagn_init_alive_start,
-	.alive_notify = iwlagn_alive_notify,
 	.send_tx_power = iwlagn_send_tx_power,
 	.update_chain_flags = iwl_update_chain_flags,
 	.set_channel_switch = iwl5000_hw_channel_switch,
@@ -380,56 +358,20 @@
 			EEPROM_REG_BAND_24_HT40_CHANNELS,
 			EEPROM_REG_BAND_52_HT40_CHANNELS
 		},
-		.acquire_semaphore = iwlcore_eeprom_acquire_semaphore,
-		.release_semaphore = iwlcore_eeprom_release_semaphore,
-		.calib_version	= iwlagn_eeprom_calib_version,
 		.query_addr = iwlagn_eeprom_query_addr,
 	},
-	.isr_ops = {
-		.isr = iwl_isr_ict,
-		.free = iwl_free_isr_ict,
-		.alloc = iwl_alloc_isr_ict,
-		.reset = iwl_reset_ict,
-		.disable = iwl_disable_ict,
-	},
 	.temp_ops = {
 		.temperature = iwlagn_temperature,
 	 },
-	.debugfs_ops = {
-		.rx_stats_read = iwl_ucode_rx_stats_read,
-		.tx_stats_read = iwl_ucode_tx_stats_read,
-		.general_stats_read = iwl_ucode_general_stats_read,
-		.bt_stats_read = iwl_ucode_bt_stats_read,
-		.reply_tx_error = iwl_reply_tx_error_read,
-	},
 	.txfifo_flush = iwlagn_txfifo_flush,
 	.dev_txfifo_flush = iwlagn_dev_txfifo_flush,
-	.tt_ops = {
-		.lower_power_detection = iwl_tt_is_low_power_state,
-		.tt_power_mode = iwl_tt_current_power_mode,
-		.ct_kill_check = iwl_check_for_ct_kill,
-	}
 };
 
 static struct iwl_lib_ops iwl5150_lib = {
 	.set_hw_params = iwl5150_hw_set_hw_params,
-	.txq_update_byte_cnt_tbl = iwlagn_txq_update_byte_cnt_tbl,
-	.txq_inval_byte_cnt_tbl = iwlagn_txq_inval_byte_cnt_tbl,
-	.txq_set_sched = iwlagn_txq_set_sched,
-	.txq_agg_enable = iwlagn_txq_agg_enable,
-	.txq_agg_disable = iwlagn_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 = iwlagn_rx_handler_setup,
 	.setup_deferred_work = iwlagn_setup_deferred_work,
 	.is_valid_rtc_data_addr = iwlagn_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 = iwlagn_load_ucode,
-	.init_alive_start = iwlagn_init_alive_start,
-	.alive_notify = iwlagn_alive_notify,
 	.send_tx_power = iwlagn_send_tx_power,
 	.update_chain_flags = iwl_update_chain_flags,
 	.set_channel_switch = iwl5000_hw_channel_switch,
@@ -447,51 +389,25 @@
 			EEPROM_REG_BAND_24_HT40_CHANNELS,
 			EEPROM_REG_BAND_52_HT40_CHANNELS
 		},
-		.acquire_semaphore = iwlcore_eeprom_acquire_semaphore,
-		.release_semaphore = iwlcore_eeprom_release_semaphore,
-		.calib_version	= iwlagn_eeprom_calib_version,
 		.query_addr = iwlagn_eeprom_query_addr,
 	},
-	.isr_ops = {
-		.isr = iwl_isr_ict,
-		.free = iwl_free_isr_ict,
-		.alloc = iwl_alloc_isr_ict,
-		.reset = iwl_reset_ict,
-		.disable = iwl_disable_ict,
-	},
 	.temp_ops = {
 		.temperature = iwl5150_temperature,
 	 },
-	.debugfs_ops = {
-		.rx_stats_read = iwl_ucode_rx_stats_read,
-		.tx_stats_read = iwl_ucode_tx_stats_read,
-		.general_stats_read = iwl_ucode_general_stats_read,
-		.bt_stats_read = iwl_ucode_bt_stats_read,
-		.reply_tx_error = iwl_reply_tx_error_read,
-	},
 	.txfifo_flush = iwlagn_txfifo_flush,
 	.dev_txfifo_flush = iwlagn_dev_txfifo_flush,
-	.tt_ops = {
-		.lower_power_detection = iwl_tt_is_low_power_state,
-		.tt_power_mode = iwl_tt_current_power_mode,
-		.ct_kill_check = iwl_check_for_ct_kill,
-	}
 };
 
 static const struct iwl_ops iwl5000_ops = {
 	.lib = &iwl5000_lib,
 	.hcmd = &iwlagn_hcmd,
 	.utils = &iwlagn_hcmd_utils,
-	.led = &iwlagn_led_ops,
-	.ieee80211_ops = &iwlagn_hw_ops,
 };
 
 static const struct iwl_ops iwl5150_ops = {
 	.lib = &iwl5150_lib,
 	.hcmd = &iwlagn_hcmd,
 	.utils = &iwlagn_hcmd_utils,
-	.led = &iwlagn_led_ops,
-	.ieee80211_ops = &iwlagn_hw_ops,
 };
 
 static struct iwl_base_params iwl5000_base_params = {
@@ -499,21 +415,15 @@
 	.num_of_queues = IWLAGN_NUM_QUEUES,
 	.num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES,
 	.pll_cfg_val = CSR50_ANA_PLL_CFG_VAL,
-	.set_l0s = true,
-	.use_bsm = false,
 	.led_compensation = 51,
 	.chain_noise_num_beacons = IWL_CAL_NUM_BEACONS,
 	.plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF,
 	.chain_noise_scale = 1000,
 	.wd_timeout = IWL_LONG_WD_TIMEOUT,
 	.max_event_log_size = 512,
-	.ucode_tracing = true,
-	.sensitivity_calib_by_driver = true,
-	.chain_noise_calib_by_driver = true,
 };
 static struct iwl_ht_params iwl5000_ht_params = {
 	.ht_greenfield_support = true,
-	.use_rts_for_aggregation = true, /* use rts/cts protection */
 };
 
 #define IWL_DEVICE_5000						\
@@ -523,7 +433,6 @@
 	.eeprom_ver = EEPROM_5000_EEPROM_VERSION,		\
 	.eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION,	\
 	.ops = &iwl5000_ops,					\
-	.mod_params = &iwlagn_mod_params,			\
 	.base_params = &iwl5000_base_params,			\
 	.led_mode = IWL_LED_BLINK
 
@@ -567,7 +476,6 @@
 	.eeprom_ver = EEPROM_5050_EEPROM_VERSION,
 	.eeprom_calib_ver = EEPROM_5050_TX_POWER_VERSION,
 	.ops = &iwl5000_ops,
-	.mod_params = &iwlagn_mod_params,
 	.base_params = &iwl5000_base_params,
 	.ht_params = &iwl5000_ht_params,
 	.led_mode = IWL_LED_BLINK,
@@ -581,7 +489,6 @@
 	.eeprom_ver = EEPROM_5050_EEPROM_VERSION,		\
 	.eeprom_calib_ver = EEPROM_5050_TX_POWER_VERSION,	\
 	.ops = &iwl5150_ops,					\
-	.mod_params = &iwlagn_mod_params,			\
 	.base_params = &iwl5000_base_params,			\
 	.need_dc_calib = true,					\
 	.led_mode = IWL_LED_BLINK,				\
diff -druN linux-2.6.39-libre/drivers/net/wireless/iwlwifi/iwl-5000-hw.h linux-3.0-rc7-libre/drivers/net/wireless/iwlwifi/iwl-5000-hw.h
--- linux-2.6.39-libre/drivers/net/wireless/iwlwifi/iwl-5000-hw.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/iwlwifi/iwl-5000-hw.h	2011-07-11 19:51:52.000000000 -0400
@@ -5,7 +5,7 @@
  *
  * GPL LICENSE SUMMARY
  *
- * Copyright(c) 2007 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2007 - 2011 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 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff -druN linux-2.6.39-libre/drivers/net/wireless/iwlwifi/iwl-6000.c linux-3.0-rc7-libre/drivers/net/wireless/iwlwifi/iwl-6000.c
--- linux-2.6.39-libre/drivers/net/wireless/iwlwifi/iwl-6000.c	2011-05-19 02:14:25.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/iwlwifi/iwl-6000.c	2011-07-21 06:56:49.000000000 -0400
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
@@ -36,6 +36,7 @@
 #include <net/mac80211.h>
 #include <linux/etherdevice.h>
 #include <asm/unaligned.h>
+#include <linux/stringify.h>
 
 #include "iwl-eeprom.h"
 #include "iwl-dev.h"
@@ -46,8 +47,6 @@
 #include "iwl-helpers.h"
 #include "iwl-agn-hw.h"
 #include "iwl-6000-hw.h"
-#include "iwl-agn-led.h"
-#include "iwl-agn-debugfs.h"
 
 /* Highest firmware API version supported */
 #define IWL6000_UCODE_API_MAX 4
@@ -60,20 +59,16 @@
 #define IWL6000G2_UCODE_API_MIN 4
 
 #define IWL6000_FW_PRE "/*(DEBLOBBED)*/"
-#define _IWL6000_MODULE_FIRMWARE(api) IWL6000_FW_PRE /*(DEBLOBBED)*/
-#define IWL6000_MODULE_FIRMWARE(api) _IWL6000_MODULE_FIRMWARE(api)
+#define IWL6000_MODULE_FIRMWARE(api) IWL6000_FW_PRE __stringify(api) "/*(DEBLOBBED)*/
 
 #define IWL6050_FW_PRE "/*(DEBLOBBED)*/"
-#define _IWL6050_MODULE_FIRMWARE(api) IWL6050_FW_PRE /*(DEBLOBBED)*/
-#define IWL6050_MODULE_FIRMWARE(api) _IWL6050_MODULE_FIRMWARE(api)
+#define IWL6050_MODULE_FIRMWARE(api) IWL6050_FW_PRE __stringify(api) "/*(DEBLOBBED)*/
 
 #define IWL6005_FW_PRE "/*(DEBLOBBED)*/"
-#define _IWL6005_MODULE_FIRMWARE(api) IWL6005_FW_PRE /*(DEBLOBBED)*/
-#define IWL6005_MODULE_FIRMWARE(api) _IWL6005_MODULE_FIRMWARE(api)
+#define IWL6005_MODULE_FIRMWARE(api) IWL6005_FW_PRE __stringify(api) "/*(DEBLOBBED)*/
 
 #define IWL6030_FW_PRE "/*(DEBLOBBED)*/"
-#define _IWL6030_MODULE_FIRMWARE(api) IWL6030_FW_PRE /*(DEBLOBBED)*/
-#define IWL6030_MODULE_FIRMWARE(api) _IWL6030_MODULE_FIRMWARE(api)
+#define IWL6030_MODULE_FIRMWARE(api) IWL6030_FW_PRE __stringify(api) "/*(DEBLOBBED)*/
 
 static void iwl6000_set_ct_threshold(struct iwl_priv *priv)
 {
@@ -85,7 +80,7 @@
 static void iwl6050_additional_nic_config(struct iwl_priv *priv)
 {
 	/* Indicate calibration version to uCode. */
-	if (priv->cfg->ops->lib->eeprom_ops.calib_version(priv) >= 6)
+	if (iwlagn_eeprom_calib_version(priv) >= 6)
 		iwl_set_bit(priv, CSR_GP_DRIVER_REG,
 				CSR_GP_DRIVER_REG_BIT_CALIB_VERSION6);
 }
@@ -93,7 +88,7 @@
 static void iwl6150_additional_nic_config(struct iwl_priv *priv)
 {
 	/* Indicate calibration version to uCode. */
-	if (priv->cfg->ops->lib->eeprom_ops.calib_version(priv) >= 6)
+	if (iwlagn_eeprom_calib_version(priv) >= 6)
 		iwl_set_bit(priv, CSR_GP_DRIVER_REG,
 				CSR_GP_DRIVER_REG_BIT_CALIB_VERSION6);
 	iwl_set_bit(priv, CSR_GP_DRIVER_REG,
@@ -159,10 +154,10 @@
 
 static int iwl6000_hw_set_hw_params(struct iwl_priv *priv)
 {
-	if (priv->cfg->mod_params->num_of_queues >= IWL_MIN_NUM_QUEUES &&
-	    priv->cfg->mod_params->num_of_queues <= IWLAGN_NUM_QUEUES)
+	if (iwlagn_mod_params.num_of_queues >= IWL_MIN_NUM_QUEUES &&
+	    iwlagn_mod_params.num_of_queues <= IWLAGN_NUM_QUEUES)
 		priv->cfg->base_params->num_of_queues =
-			priv->cfg->mod_params->num_of_queues;
+			iwlagn_mod_params.num_of_queues;
 
 	priv->hw_params.max_txq_num = priv->cfg->base_params->num_of_queues;
 	priv->hw_params.dma_chnl_num = FH50_TCSR_CHNL_NUM;
@@ -176,7 +171,6 @@
 	priv->hw_params.max_data_size = IWL60_RTC_DATA_SIZE;
 	priv->hw_params.max_inst_size = IWL60_RTC_INST_SIZE;
 
-	priv->hw_params.max_bsm_size = 0;
 	priv->hw_params.ht40_channel =  BIT(IEEE80211_BAND_2GHZ) |
 					BIT(IEEE80211_BAND_5GHZ);
 	priv->hw_params.rx_wrt_ptr_reg = FH_RSCSR_CHNL0_WPTR;
@@ -228,9 +222,9 @@
 	struct ieee80211_vif *vif = ctx->vif;
 	struct iwl_host_cmd hcmd = {
 		.id = REPLY_CHANNEL_SWITCH,
-		.len = sizeof(cmd),
+		.len = { sizeof(cmd), },
 		.flags = CMD_SYNC,
-		.data = &cmd,
+		.data = { &cmd, },
 	};
 
 	cmd.band = priv->band == IEEE80211_BAND_2GHZ;
@@ -277,32 +271,15 @@
 			ctx->active.channel, ch);
 		return -EFAULT;
 	}
-	priv->switch_rxon.channel = cmd.channel;
-	priv->switch_rxon.switch_in_progress = true;
 
 	return iwl_send_cmd_sync(priv, &hcmd);
 }
 
 static struct iwl_lib_ops iwl6000_lib = {
 	.set_hw_params = iwl6000_hw_set_hw_params,
-	.txq_update_byte_cnt_tbl = iwlagn_txq_update_byte_cnt_tbl,
-	.txq_inval_byte_cnt_tbl = iwlagn_txq_inval_byte_cnt_tbl,
-	.txq_set_sched = iwlagn_txq_set_sched,
-	.txq_agg_enable = iwlagn_txq_agg_enable,
-	.txq_agg_disable = iwlagn_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 = iwlagn_rx_handler_setup,
 	.setup_deferred_work = iwlagn_setup_deferred_work,
 	.is_valid_rtc_data_addr = iwlagn_hw_valid_rtc_data_addr,
-	.load_ucode = iwlagn_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 = iwlagn_init_alive_start,
-	.alive_notify = iwlagn_alive_notify,
 	.send_tx_power = iwlagn_send_tx_power,
 	.update_chain_flags = iwl_update_chain_flags,
 	.set_channel_switch = iwl6000_hw_channel_switch,
@@ -320,59 +297,22 @@
 			EEPROM_6000_REG_BAND_24_HT40_CHANNELS,
 			EEPROM_REG_BAND_52_HT40_CHANNELS
 		},
-		.acquire_semaphore = iwlcore_eeprom_acquire_semaphore,
-		.release_semaphore = iwlcore_eeprom_release_semaphore,
-		.calib_version	= iwlagn_eeprom_calib_version,
 		.query_addr = iwlagn_eeprom_query_addr,
 		.update_enhanced_txpower = iwlcore_eeprom_enhanced_txpower,
 	},
-	.isr_ops = {
-		.isr = iwl_isr_ict,
-		.free = iwl_free_isr_ict,
-		.alloc = iwl_alloc_isr_ict,
-		.reset = iwl_reset_ict,
-		.disable = iwl_disable_ict,
-	},
 	.temp_ops = {
 		.temperature = iwlagn_temperature,
 	 },
-	.debugfs_ops = {
-		.rx_stats_read = iwl_ucode_rx_stats_read,
-		.tx_stats_read = iwl_ucode_tx_stats_read,
-		.general_stats_read = iwl_ucode_general_stats_read,
-		.bt_stats_read = iwl_ucode_bt_stats_read,
-		.reply_tx_error = iwl_reply_tx_error_read,
-	},
 	.txfifo_flush = iwlagn_txfifo_flush,
 	.dev_txfifo_flush = iwlagn_dev_txfifo_flush,
-	.tt_ops = {
-		.lower_power_detection = iwl_tt_is_low_power_state,
-		.tt_power_mode = iwl_tt_current_power_mode,
-		.ct_kill_check = iwl_check_for_ct_kill,
-	}
 };
 
 static struct iwl_lib_ops iwl6030_lib = {
 	.set_hw_params = iwl6000_hw_set_hw_params,
-	.txq_update_byte_cnt_tbl = iwlagn_txq_update_byte_cnt_tbl,
-	.txq_inval_byte_cnt_tbl = iwlagn_txq_inval_byte_cnt_tbl,
-	.txq_set_sched = iwlagn_txq_set_sched,
-	.txq_agg_enable = iwlagn_txq_agg_enable,
-	.txq_agg_disable = iwlagn_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 = iwlagn_bt_rx_handler_setup,
 	.setup_deferred_work = iwlagn_bt_setup_deferred_work,
 	.cancel_deferred_work = iwlagn_bt_cancel_deferred_work,
 	.is_valid_rtc_data_addr = iwlagn_hw_valid_rtc_data_addr,
-	.load_ucode = iwlagn_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 = iwlagn_init_alive_start,
-	.alive_notify = iwlagn_alive_notify,
 	.send_tx_power = iwlagn_send_tx_power,
 	.update_chain_flags = iwl_update_chain_flags,
 	.set_channel_switch = iwl6000_hw_channel_switch,
@@ -390,36 +330,14 @@
 			EEPROM_6000_REG_BAND_24_HT40_CHANNELS,
 			EEPROM_REG_BAND_52_HT40_CHANNELS
 		},
-		.acquire_semaphore = iwlcore_eeprom_acquire_semaphore,
-		.release_semaphore = iwlcore_eeprom_release_semaphore,
-		.calib_version	= iwlagn_eeprom_calib_version,
 		.query_addr = iwlagn_eeprom_query_addr,
 		.update_enhanced_txpower = iwlcore_eeprom_enhanced_txpower,
 	},
-	.isr_ops = {
-		.isr = iwl_isr_ict,
-		.free = iwl_free_isr_ict,
-		.alloc = iwl_alloc_isr_ict,
-		.reset = iwl_reset_ict,
-		.disable = iwl_disable_ict,
-	},
 	.temp_ops = {
 		.temperature = iwlagn_temperature,
 	 },
-	.debugfs_ops = {
-		.rx_stats_read = iwl_ucode_rx_stats_read,
-		.tx_stats_read = iwl_ucode_tx_stats_read,
-		.general_stats_read = iwl_ucode_general_stats_read,
-		.bt_stats_read = iwl_ucode_bt_stats_read,
-		.reply_tx_error = iwl_reply_tx_error_read,
-	},
 	.txfifo_flush = iwlagn_txfifo_flush,
 	.dev_txfifo_flush = iwlagn_dev_txfifo_flush,
-	.tt_ops = {
-		.lower_power_detection = iwl_tt_is_low_power_state,
-		.tt_power_mode = iwl_tt_current_power_mode,
-		.ct_kill_check = iwl_check_for_ct_kill,
-	}
 };
 
 static struct iwl_nic_ops iwl6050_nic_ops = {
@@ -434,34 +352,26 @@
 	.lib = &iwl6000_lib,
 	.hcmd = &iwlagn_hcmd,
 	.utils = &iwlagn_hcmd_utils,
-	.led = &iwlagn_led_ops,
-	.ieee80211_ops = &iwlagn_hw_ops,
 };
 
 static const struct iwl_ops iwl6050_ops = {
 	.lib = &iwl6000_lib,
 	.hcmd = &iwlagn_hcmd,
 	.utils = &iwlagn_hcmd_utils,
-	.led = &iwlagn_led_ops,
 	.nic = &iwl6050_nic_ops,
-	.ieee80211_ops = &iwlagn_hw_ops,
 };
 
 static const struct iwl_ops iwl6150_ops = {
 	.lib = &iwl6000_lib,
 	.hcmd = &iwlagn_hcmd,
 	.utils = &iwlagn_hcmd_utils,
-	.led = &iwlagn_led_ops,
 	.nic = &iwl6150_nic_ops,
-	.ieee80211_ops = &iwlagn_hw_ops,
 };
 
 static const struct iwl_ops iwl6030_ops = {
 	.lib = &iwl6030_lib,
 	.hcmd = &iwlagn_bt_hcmd,
 	.utils = &iwlagn_hcmd_utils,
-	.led = &iwlagn_led_ops,
-	.ieee80211_ops = &iwlagn_hw_ops,
 };
 
 static struct iwl_base_params iwl6000_base_params = {
@@ -469,8 +379,6 @@
 	.num_of_queues = IWLAGN_NUM_QUEUES,
 	.num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES,
 	.pll_cfg_val = 0,
-	.set_l0s = true,
-	.use_bsm = false,
 	.max_ll_items = OTP_MAX_LL_ITEMS_6x00,
 	.shadow_ram_support = true,
 	.led_compensation = 51,
@@ -481,9 +389,6 @@
 	.chain_noise_scale = 1000,
 	.wd_timeout = IWL_DEF_WD_TIMEOUT,
 	.max_event_log_size = 512,
-	.ucode_tracing = true,
-	.sensitivity_calib_by_driver = true,
-	.chain_noise_calib_by_driver = true,
 	.shadow_reg_enable = true,
 };
 
@@ -492,8 +397,6 @@
 	.num_of_queues = IWLAGN_NUM_QUEUES,
 	.num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES,
 	.pll_cfg_val = 0,
-	.set_l0s = true,
-	.use_bsm = false,
 	.max_ll_items = OTP_MAX_LL_ITEMS_6x50,
 	.shadow_ram_support = true,
 	.led_compensation = 51,
@@ -504,9 +407,6 @@
 	.chain_noise_scale = 1500,
 	.wd_timeout = IWL_DEF_WD_TIMEOUT,
 	.max_event_log_size = 1024,
-	.ucode_tracing = true,
-	.sensitivity_calib_by_driver = true,
-	.chain_noise_calib_by_driver = true,
 	.shadow_reg_enable = true,
 };
 static struct iwl_base_params iwl6000_g2_base_params = {
@@ -514,8 +414,6 @@
 	.num_of_queues = IWLAGN_NUM_QUEUES,
 	.num_of_ampdu_queues = IWLAGN_NUM_AMPDU_QUEUES,
 	.pll_cfg_val = 0,
-	.set_l0s = true,
-	.use_bsm = false,
 	.max_ll_items = OTP_MAX_LL_ITEMS_6x00,
 	.shadow_ram_support = true,
 	.led_compensation = 57,
@@ -526,9 +424,6 @@
 	.chain_noise_scale = 1000,
 	.wd_timeout = IWL_LONG_WD_TIMEOUT,
 	.max_event_log_size = 512,
-	.ucode_tracing = true,
-	.sensitivity_calib_by_driver = true,
-	.chain_noise_calib_by_driver = true,
 	.shadow_reg_enable = true,
 };
 
@@ -538,7 +433,6 @@
 };
 
 static struct iwl_bt_params iwl6000_bt_params = {
-	.bt_statistics = true,
 	/* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */
 	.advanced_bt_coexist = true,
 	.agg_time_limit = BT_AGG_THRESHOLD_DEF,
@@ -554,7 +448,6 @@
 	.eeprom_ver = EEPROM_6005_EEPROM_VERSION,		\
 	.eeprom_calib_ver = EEPROM_6005_TX_POWER_VERSION,	\
 	.ops = &iwl6000_ops,					\
-	.mod_params = &iwlagn_mod_params,			\
 	.base_params = &iwl6000_g2_base_params,			\
 	.need_dc_calib = true,					\
 	.need_temp_offset_calib = true,				\
@@ -583,7 +476,6 @@
 	.eeprom_ver = EEPROM_6030_EEPROM_VERSION,		\
 	.eeprom_calib_ver = EEPROM_6030_TX_POWER_VERSION,	\
 	.ops = &iwl6030_ops,					\
-	.mod_params = &iwlagn_mod_params,			\
 	.base_params = &iwl6000_g2_base_params,			\
 	.bt_params = &iwl6000_bt_params,			\
 	.need_dc_calib = true,					\
@@ -613,6 +505,22 @@
 	IWL_DEVICE_6030,
 };
 
+struct iwl_cfg iwl6035_2agn_cfg = {
+	.name = "6035 Series 2x2 AGN/BT",
+	IWL_DEVICE_6030,
+	.ht_params = &iwl6000_ht_params,
+};
+
+struct iwl_cfg iwl6035_2abg_cfg = {
+	.name = "6035 Series 2x2 ABG/BT",
+	IWL_DEVICE_6030,
+};
+
+struct iwl_cfg iwl6035_2bg_cfg = {
+	.name = "6035 Series 2x2 BG/BT",
+	IWL_DEVICE_6030,
+};
+
 struct iwl_cfg iwl1030_bgn_cfg = {
 	.name = "Intel(R) Centrino(R) Wireless-N 1030 BGN",
 	IWL_DEVICE_6030,
@@ -649,7 +557,6 @@
 	.eeprom_ver = EEPROM_6000_EEPROM_VERSION,		\
 	.eeprom_calib_ver = EEPROM_6000_TX_POWER_VERSION,	\
 	.ops = &iwl6000_ops,					\
-	.mod_params = &iwlagn_mod_params,			\
 	.base_params = &iwl6000_base_params,			\
 	.pa_type = IWL_PA_INTERNAL,				\
 	.led_mode = IWL_LED_BLINK
@@ -679,7 +586,6 @@
 	.ops = &iwl6050_ops,					\
 	.eeprom_ver = EEPROM_6050_EEPROM_VERSION,		\
 	.eeprom_calib_ver = EEPROM_6050_TX_POWER_VERSION,	\
-	.mod_params = &iwlagn_mod_params,			\
 	.base_params = &iwl6050_base_params,			\
 	.need_dc_calib = true,					\
 	.led_mode = IWL_LED_BLINK,				\
@@ -696,20 +602,27 @@
 	IWL_DEVICE_6050,
 };
 
+#define IWL_DEVICE_6150						\
+	.fw_name_pre = IWL6050_FW_PRE,				\
+	.ucode_api_max = IWL6050_UCODE_API_MAX,			\
+	.ucode_api_min = IWL6050_UCODE_API_MIN,			\
+	.ops = &iwl6150_ops,					\
+	.eeprom_ver = EEPROM_6150_EEPROM_VERSION,		\
+	.eeprom_calib_ver = EEPROM_6150_TX_POWER_VERSION,	\
+	.base_params = &iwl6050_base_params,			\
+	.need_dc_calib = true,					\
+	.led_mode = IWL_LED_BLINK,				\
+	.internal_wimax_coex = true
+
 struct iwl_cfg iwl6150_bgn_cfg = {
 	.name = "Intel(R) Centrino(R) Wireless-N + WiMAX 6150 BGN",
-	.fw_name_pre = IWL6050_FW_PRE,
-	.ucode_api_max = IWL6050_UCODE_API_MAX,
-	.ucode_api_min = IWL6050_UCODE_API_MIN,
-	.eeprom_ver = EEPROM_6150_EEPROM_VERSION,
-	.eeprom_calib_ver = EEPROM_6150_TX_POWER_VERSION,
-	.ops = &iwl6150_ops,
-	.mod_params = &iwlagn_mod_params,
-	.base_params = &iwl6050_base_params,
+	IWL_DEVICE_6150,
 	.ht_params = &iwl6000_ht_params,
-	.need_dc_calib = true,
-	.led_mode = IWL_LED_RF_STATE,
-	.internal_wimax_coex = true,
+};
+
+struct iwl_cfg iwl6150_bg_cfg = {
+	.name = "Intel(R) Centrino(R) Wireless-N + WiMAX 6150 BG",
+	IWL_DEVICE_6150,
 };
 
 struct iwl_cfg iwl6000_3agn_cfg = {
@@ -720,7 +633,6 @@
 	.eeprom_ver = EEPROM_6000_EEPROM_VERSION,
 	.eeprom_calib_ver = EEPROM_6000_TX_POWER_VERSION,
 	.ops = &iwl6000_ops,
-	.mod_params = &iwlagn_mod_params,
 	.base_params = &iwl6000_base_params,
 	.ht_params = &iwl6000_ht_params,
 	.need_dc_calib = true,
diff -druN linux-2.6.39-libre/drivers/net/wireless/iwlwifi/iwl-6000-hw.h linux-3.0-rc7-libre/drivers/net/wireless/iwlwifi/iwl-6000-hw.h
--- linux-2.6.39-libre/drivers/net/wireless/iwlwifi/iwl-6000-hw.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/iwlwifi/iwl-6000-hw.h	2011-07-11 19:51:52.000000000 -0400
@@ -5,7 +5,7 @@
  *
  * GPL LICENSE SUMMARY
  *
- * Copyright(c) 2007 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2007 - 2011 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 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff -druN linux-2.6.39-libre/drivers/net/wireless/iwlwifi/iwl-agn.c linux-3.0-rc7-libre/drivers/net/wireless/iwlwifi/iwl-agn.c
--- linux-2.6.39-libre/drivers/net/wireless/iwlwifi/iwl-agn.c	2011-05-19 02:14:21.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/iwlwifi/iwl-agn.c	2011-07-21 06:56:45.000000000 -0400
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2003 - 2011 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.
@@ -59,7 +59,6 @@
 #include "iwl-sta.h"
 #include "iwl-agn-calib.h"
 #include "iwl-agn.h"
-#include "iwl-agn-led.h"
 
 
 /******************************************************************************
@@ -103,70 +102,6 @@
 	}
 }
 
-static void iwl_clear_free_frames(struct iwl_priv *priv)
-{
-	struct list_head *element;
-
-	IWL_DEBUG_INFO(priv, "%d frames on pre-allocated heap on clear.\n",
-		       priv->frames_count);
-
-	while (!list_empty(&priv->free_frames)) {
-		element = priv->free_frames.next;
-		list_del(element);
-		kfree(list_entry(element, struct iwl_frame, list));
-		priv->frames_count--;
-	}
-
-	if (priv->frames_count) {
-		IWL_WARN(priv, "%d frames still in use.  Did we lose one?\n",
-			    priv->frames_count);
-		priv->frames_count = 0;
-	}
-}
-
-static struct iwl_frame *iwl_get_free_frame(struct iwl_priv *priv)
-{
-	struct iwl_frame *frame;
-	struct list_head *element;
-	if (list_empty(&priv->free_frames)) {
-		frame = kzalloc(sizeof(*frame), GFP_KERNEL);
-		if (!frame) {
-			IWL_ERR(priv, "Could not allocate frame!\n");
-			return NULL;
-		}
-
-		priv->frames_count++;
-		return frame;
-	}
-
-	element = priv->free_frames.next;
-	list_del(element);
-	return list_entry(element, struct iwl_frame, list);
-}
-
-static void iwl_free_frame(struct iwl_priv *priv, struct iwl_frame *frame)
-{
-	memset(frame, 0, sizeof(*frame));
-	list_add(&frame->list, &priv->free_frames);
-}
-
-static u32 iwl_fill_beacon_frame(struct iwl_priv *priv,
-				 struct ieee80211_hdr *hdr,
-				 int left)
-{
-	lockdep_assert_held(&priv->mutex);
-
-	if (!priv->beacon_skb)
-		return 0;
-
-	if (priv->beacon_skb->len > left)
-		return 0;
-
-	memcpy(hdr, priv->beacon_skb->data, priv->beacon_skb->len);
-
-	return priv->beacon_skb->len;
-}
-
 /* Parse the beacon frame to find the TIM element and set tim_idx & tim_size */
 static void iwl_set_beacon_tim(struct iwl_priv *priv,
 			       struct iwl_tx_beacon_cmd *tx_beacon_cmd,
@@ -194,13 +129,16 @@
 		IWL_WARN(priv, "Unable to find TIM Element in beacon\n");
 }
 
-static unsigned int iwl_hw_get_beacon_cmd(struct iwl_priv *priv,
-				       struct iwl_frame *frame)
+int iwlagn_send_beacon_cmd(struct iwl_priv *priv)
 {
 	struct iwl_tx_beacon_cmd *tx_beacon_cmd;
+	struct iwl_host_cmd cmd = {
+		.id = REPLY_TX_BEACON,
+	};
 	u32 frame_size;
 	u32 rate_flags;
 	u32 rate;
+
 	/*
 	 * We have to set up the TX command, the TX Beacon command, and the
 	 * beacon contents.
@@ -213,17 +151,17 @@
 		return 0;
 	}
 
-	/* Initialize memory */
-	tx_beacon_cmd = &frame->u.beacon;
-	memset(tx_beacon_cmd, 0, sizeof(*tx_beacon_cmd));
+	if (WARN_ON(!priv->beacon_skb))
+		return -EINVAL;
 
-	/* Set up TX beacon contents */
-	frame_size = iwl_fill_beacon_frame(priv, tx_beacon_cmd->frame,
-				sizeof(frame->u) - sizeof(*tx_beacon_cmd));
-	if (WARN_ON_ONCE(frame_size > MAX_MPDU_SIZE))
-		return 0;
-	if (!frame_size)
-		return 0;
+	/* Allocate beacon command */
+	if (!priv->beacon_cmd)
+		priv->beacon_cmd = kzalloc(sizeof(*tx_beacon_cmd), GFP_KERNEL);
+	tx_beacon_cmd = priv->beacon_cmd;
+	if (!tx_beacon_cmd)
+		return -ENOMEM;
+
+	frame_size = priv->beacon_skb->len;
 
 	/* Set up TX command fields */
 	tx_beacon_cmd->tx.len = cpu_to_le16((u16)frame_size);
@@ -233,7 +171,7 @@
 		TX_CMD_FLG_TSF_MSK | TX_CMD_FLG_STA_RATE_MSK;
 
 	/* Set up TX beacon command fields */
-	iwl_set_beacon_tim(priv, tx_beacon_cmd, (u8 *)tx_beacon_cmd->frame,
+	iwl_set_beacon_tim(priv, tx_beacon_cmd, priv->beacon_skb->data,
 			   frame_size);
 
 	/* Set up packet rate and flags */
@@ -246,182 +184,15 @@
 	tx_beacon_cmd->tx.rate_n_flags = iwl_hw_set_rate_n_flags(rate,
 			rate_flags);
 
-	return sizeof(*tx_beacon_cmd) + frame_size;
-}
-
-int iwlagn_send_beacon_cmd(struct iwl_priv *priv)
-{
-	struct iwl_frame *frame;
-	unsigned int frame_size;
-	int rc;
-
-	frame = iwl_get_free_frame(priv);
-	if (!frame) {
-		IWL_ERR(priv, "Could not obtain free frame buffer for beacon "
-			  "command.\n");
-		return -ENOMEM;
-	}
-
-	frame_size = iwl_hw_get_beacon_cmd(priv, frame);
-	if (!frame_size) {
-		IWL_ERR(priv, "Error configuring the beacon command\n");
-		iwl_free_frame(priv, frame);
-		return -EINVAL;
-	}
-
-	rc = iwl_send_cmd_pdu(priv, REPLY_TX_BEACON, frame_size,
-			      &frame->u.cmd[0]);
-
-	iwl_free_frame(priv, frame);
-
-	return rc;
-}
-
-static inline dma_addr_t iwl_tfd_tb_get_addr(struct iwl_tfd *tfd, u8 idx)
-{
-	struct iwl_tfd_tb *tb = &tfd->tbs[idx];
-
-	dma_addr_t addr = get_unaligned_le32(&tb->lo);
-	if (sizeof(dma_addr_t) > sizeof(u32))
-		addr |=
-		((dma_addr_t)(le16_to_cpu(tb->hi_n_len) & 0xF) << 16) << 16;
-
-	return addr;
-}
-
-static inline u16 iwl_tfd_tb_get_len(struct iwl_tfd *tfd, u8 idx)
-{
-	struct iwl_tfd_tb *tb = &tfd->tbs[idx];
-
-	return le16_to_cpu(tb->hi_n_len) >> 4;
-}
-
-static inline void iwl_tfd_set_tb(struct iwl_tfd *tfd, u8 idx,
-				  dma_addr_t addr, u16 len)
-{
-	struct iwl_tfd_tb *tb = &tfd->tbs[idx];
-	u16 hi_n_len = len << 4;
-
-	put_unaligned_le32(addr, &tb->lo);
-	if (sizeof(dma_addr_t) > sizeof(u32))
-		hi_n_len |= ((addr >> 16) >> 16) & 0xF;
-
-	tb->hi_n_len = cpu_to_le16(hi_n_len);
-
-	tfd->num_tbs = idx + 1;
-}
-
-static inline u8 iwl_tfd_get_num_tbs(struct iwl_tfd *tfd)
-{
-	return tfd->num_tbs & 0x1f;
-}
-
-/**
- * iwl_hw_txq_free_tfd - Free all chunks referenced by TFD [txq->q.read_ptr]
- * @priv - driver private data
- * @txq - tx queue
- *
- * Does NOT advance any TFD circular buffer read/write indexes
- * Does NOT free the TFD itself (which is within circular buffer)
- */
-void iwl_hw_txq_free_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq)
-{
-	struct iwl_tfd *tfd_tmp = (struct iwl_tfd *)txq->tfds;
-	struct iwl_tfd *tfd;
-	struct pci_dev *dev = priv->pci_dev;
-	int index = txq->q.read_ptr;
-	int i;
-	int num_tbs;
-
-	tfd = &tfd_tmp[index];
-
-	/* Sanity check on number of chunks */
-	num_tbs = iwl_tfd_get_num_tbs(tfd);
-
-	if (num_tbs >= IWL_NUM_OF_TBS) {
-		IWL_ERR(priv, "Too many chunks: %i\n", num_tbs);
-		/* @todo issue fatal error, it is quite serious situation */
-		return;
-	}
-
-	/* Unmap tx_cmd */
-	if (num_tbs)
-		pci_unmap_single(dev,
-				dma_unmap_addr(&txq->meta[index], mapping),
-				dma_unmap_len(&txq->meta[index], len),
-				PCI_DMA_BIDIRECTIONAL);
-
-	/* Unmap chunks, if any. */
-	for (i = 1; i < num_tbs; i++)
-		pci_unmap_single(dev, iwl_tfd_tb_get_addr(tfd, i),
-				iwl_tfd_tb_get_len(tfd, i), PCI_DMA_TODEVICE);
-
-	/* free SKB */
-	if (txq->txb) {
-		struct sk_buff *skb;
-
-		skb = txq->txb[txq->q.read_ptr].skb;
-
-		/* can be called from irqs-disabled context */
-		if (skb) {
-			dev_kfree_skb_any(skb);
-			txq->txb[txq->q.read_ptr].skb = NULL;
-		}
-	}
-}
-
-int iwl_hw_txq_attach_buf_to_tfd(struct iwl_priv *priv,
-				 struct iwl_tx_queue *txq,
-				 dma_addr_t addr, u16 len,
-				 u8 reset, u8 pad)
-{
-	struct iwl_queue *q;
-	struct iwl_tfd *tfd, *tfd_tmp;
-	u32 num_tbs;
-
-	q = &txq->q;
-	tfd_tmp = (struct iwl_tfd *)txq->tfds;
-	tfd = &tfd_tmp[q->write_ptr];
-
-	if (reset)
-		memset(tfd, 0, sizeof(*tfd));
-
-	num_tbs = iwl_tfd_get_num_tbs(tfd);
-
-	/* Each TFD can point to a maximum 20 Tx buffers */
-	if (num_tbs >= IWL_NUM_OF_TBS) {
-		IWL_ERR(priv, "Error can not send more than %d chunks\n",
-			  IWL_NUM_OF_TBS);
-		return -EINVAL;
-	}
-
-	BUG_ON(addr & ~DMA_BIT_MASK(36));
-	if (unlikely(addr & ~IWL_TX_DMA_MASK))
-		IWL_ERR(priv, "Unaligned address = %llx\n",
-			  (unsigned long long)addr);
-
-	iwl_tfd_set_tb(tfd, num_tbs, addr, len);
-
-	return 0;
-}
-
-/*
- * Tell nic where to find circular buffer of Tx Frame Descriptors for
- * given Tx queue, and enable the DMA channel used for that queue.
- *
- * 4965 supports up to 16 Tx queues in DRAM, mapped to up to 8 Tx DMA
- * channels supported in hardware.
- */
-int iwl_hw_tx_queue_init(struct iwl_priv *priv,
-			 struct iwl_tx_queue *txq)
-{
-	int txq_id = txq->q.id;
-
-	/* Circular buffer (TFD queue in DRAM) physical base address */
-	iwl_write_direct32(priv, FH_MEM_CBBC_QUEUE(txq_id),
-			     txq->q.dma_addr >> 8);
+	/* Submit command */
+	cmd.len[0] = sizeof(*tx_beacon_cmd);
+	cmd.data[0] = tx_beacon_cmd;
+	cmd.dataflags[0] = IWL_HCMD_DFL_NOCOPY;
+	cmd.len[1] = frame_size;
+	cmd.data[1] = priv->beacon_skb->data;
+	cmd.dataflags[1] = IWL_HCMD_DFL_NOCOPY;
 
-	return 0;
+	return iwl_send_cmd_sync(priv, &cmd);
 }
 
 static void iwl_bg_beacon_update(struct work_struct *work)
@@ -483,12 +254,14 @@
 		container_of(work, struct iwl_priv, bt_full_concurrency);
 	struct iwl_rxon_context *ctx;
 
+	mutex_lock(&priv->mutex);
+
 	if (test_bit(STATUS_EXIT_PENDING, &priv->status))
-		return;
+		goto out;
 
 	/* dont send host command if rf-kill is on */
 	if (!iwl_is_ready_rf(priv))
-		return;
+		goto out;
 
 	IWL_DEBUG_INFO(priv, "BT coex in %s mode\n",
 		       priv->bt_full_concurrent ?
@@ -498,15 +271,15 @@
 	 * LQ & RXON updated cmds must be sent before BT Config cmd
 	 * to avoid 3-wire collisions
 	 */
-	mutex_lock(&priv->mutex);
 	for_each_context(priv, ctx) {
 		if (priv->cfg->ops->hcmd->set_rxon_chain)
 			priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx);
 		iwlcore_commit_rxon(priv, ctx);
 	}
-	mutex_unlock(&priv->mutex);
 
 	priv->cfg->ops->hcmd->send_bt_config(priv);
+out:
+	mutex_unlock(&priv->mutex);
 }
 
 /**
@@ -556,7 +329,7 @@
 	}
 
 	/* Set starting address; reads will auto-increment */
-	_iwl_write_direct32(priv, HBUS_TARG_MEM_RADDR, ptr);
+	iwl_write32(priv, HBUS_TARG_MEM_RADDR, ptr);
 	rmb();
 
 	/*
@@ -564,13 +337,13 @@
 	 * 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);
+		ev = iwl_read32(priv, HBUS_TARG_MEM_RDAT);
+		time = iwl_read32(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);
+			data = iwl_read32(priv, HBUS_TARG_MEM_RDAT);
 			trace_iwlwifi_dev_ucode_cont_event(priv,
 						time, data, ev);
 		}
@@ -588,10 +361,7 @@
 	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);
+	base = priv->device_pointers.error_event_table;
 	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)));
@@ -720,7 +490,10 @@
 		/* If an RXB doesn't have a Rx queue slot associated with it,
 		 * then a bug has been introduced in the queue refilling
 		 * routines -- catch it here */
-		BUG_ON(rxb == NULL);
+		if (WARN_ON(rxb == NULL)) {
+			i = (i + 1) & RX_QUEUE_MASK;
+			continue;
+		}
 
 		rxq->queue[i] = NULL;
 
@@ -760,13 +533,15 @@
 				if (w->cmd == pkt->hdr.cmd) {
 					w->triggered = true;
 					if (w->fn)
-						w->fn(priv, pkt);
+						w->fn(priv, pkt, w->fn_data);
 				}
 			}
 			spin_unlock(&priv->_agn.notif_wait_lock);
 
 			wake_up_all(&priv->_agn.notif_waitq);
 		}
+		if (priv->pre_rx_handler)
+			priv->pre_rx_handler(priv, rxb);
 
 		/* Based on type of command response or notification,
 		 *   handle those that need handling via function in
@@ -837,199 +612,6 @@
 		iwlagn_rx_queue_restock(priv);
 }
 
-/* call this function to flush any scheduled tasklet */
-static inline void iwl_synchronize_irq(struct iwl_priv *priv)
-{
-	/* wait to make sure we flush pending tasklet*/
-	synchronize_irq(priv->pci_dev->irq);
-	tasklet_kill(&priv->irq_tasklet);
-}
-
-static void iwl_irq_tasklet_legacy(struct iwl_priv *priv)
-{
-	u32 inta, handled = 0;
-	u32 inta_fh;
-	unsigned long flags;
-	u32 i;
-#ifdef CONFIG_IWLWIFI_DEBUG
-	u32 inta_mask;
-#endif
-
-	spin_lock_irqsave(&priv->lock, flags);
-
-	/* Ack/clear/reset pending uCode interrupts.
-	 * Note:  Some bits in CSR_INT are "OR" of bits in CSR_FH_INT_STATUS,
-	 *  and will clear only when CSR_FH_INT_STATUS gets cleared. */
-	inta = iwl_read32(priv, CSR_INT);
-	iwl_write32(priv, CSR_INT, inta);
-
-	/* Ack/clear/reset pending flow-handler (DMA) interrupts.
-	 * Any new interrupts that happen after this, either while we're
-	 * in this tasklet, or later, will show up in next ISR/tasklet. */
-	inta_fh = iwl_read32(priv, CSR_FH_INT_STATUS);
-	iwl_write32(priv, CSR_FH_INT_STATUS, inta_fh);
-
-#ifdef CONFIG_IWLWIFI_DEBUG
-	if (iwl_get_debug_level(priv) & IWL_DL_ISR) {
-		/* just for debug */
-		inta_mask = iwl_read32(priv, CSR_INT_MASK);
-		IWL_DEBUG_ISR(priv, "inta 0x%08x, enabled 0x%08x, fh 0x%08x\n",
-			      inta, inta_mask, inta_fh);
-	}
-#endif
-
-	spin_unlock_irqrestore(&priv->lock, flags);
-
-	/* Since CSR_INT and CSR_FH_INT_STATUS reads and clears are not
-	 * atomic, make sure that inta covers all the interrupts that
-	 * we've discovered, even if FH interrupt came in just after
-	 * reading CSR_INT. */
-	if (inta_fh & CSR49_FH_INT_RX_MASK)
-		inta |= CSR_INT_BIT_FH_RX;
-	if (inta_fh & CSR49_FH_INT_TX_MASK)
-		inta |= CSR_INT_BIT_FH_TX;
-
-	/* Now service all interrupt bits discovered above. */
-	if (inta & CSR_INT_BIT_HW_ERR) {
-		IWL_ERR(priv, "Hardware error detected.  Restarting.\n");
-
-		/* Tell the device to stop sending interrupts */
-		iwl_disable_interrupts(priv);
-
-		priv->isr_stats.hw++;
-		iwl_irq_handle_error(priv);
-
-		handled |= CSR_INT_BIT_HW_ERR;
-
-		return;
-	}
-
-#ifdef CONFIG_IWLWIFI_DEBUG
-	if (iwl_get_debug_level(priv) & (IWL_DL_ISR)) {
-		/* NIC fires this, but we don't use it, redundant with WAKEUP */
-		if (inta & CSR_INT_BIT_SCD) {
-			IWL_DEBUG_ISR(priv, "Scheduler finished to transmit "
-				      "the frame/frames.\n");
-			priv->isr_stats.sch++;
-		}
-
-		/* Alive notification via Rx interrupt will do the real work */
-		if (inta & CSR_INT_BIT_ALIVE) {
-			IWL_DEBUG_ISR(priv, "Alive interrupt\n");
-			priv->isr_stats.alive++;
-		}
-	}
-#endif
-	/* Safely ignore these bits for debug checks below */
-	inta &= ~(CSR_INT_BIT_SCD | CSR_INT_BIT_ALIVE);
-
-	/* HW RF KILL switch toggled */
-	if (inta & CSR_INT_BIT_RF_KILL) {
-		int hw_rf_kill = 0;
-		if (!(iwl_read32(priv, CSR_GP_CNTRL) &
-				CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW))
-			hw_rf_kill = 1;
-
-		IWL_WARN(priv, "RF_KILL bit toggled to %s.\n",
-				hw_rf_kill ? "disable radio" : "enable radio");
-
-		priv->isr_stats.rfkill++;
-
-		/* driver only loads ucode once setting the interface up.
-		 * the driver allows loading the ucode even if the radio
-		 * is killed. Hence update the killswitch state here. The
-		 * rfkill handler will care about restarting if needed.
-		 */
-		if (!test_bit(STATUS_ALIVE, &priv->status)) {
-			if (hw_rf_kill)
-				set_bit(STATUS_RF_KILL_HW, &priv->status);
-			else
-				clear_bit(STATUS_RF_KILL_HW, &priv->status);
-			wiphy_rfkill_set_hw_state(priv->hw->wiphy, hw_rf_kill);
-		}
-
-		handled |= CSR_INT_BIT_RF_KILL;
-	}
-
-	/* Chip got too hot and stopped itself */
-	if (inta & CSR_INT_BIT_CT_KILL) {
-		IWL_ERR(priv, "Microcode CT kill error detected.\n");
-		priv->isr_stats.ctkill++;
-		handled |= CSR_INT_BIT_CT_KILL;
-	}
-
-	/* Error detected by uCode */
-	if (inta & CSR_INT_BIT_SW_ERR) {
-		IWL_ERR(priv, "Microcode SW error detected. "
-			" Restarting 0x%X.\n", inta);
-		priv->isr_stats.sw++;
-		iwl_irq_handle_error(priv);
-		handled |= CSR_INT_BIT_SW_ERR;
-	}
-
-	/*
-	 * uCode wakes up after power-down sleep.
-	 * Tell device about any new tx or host commands enqueued,
-	 * and about any Rx buffers made available while asleep.
-	 */
-	if (inta & CSR_INT_BIT_WAKEUP) {
-		IWL_DEBUG_ISR(priv, "Wakeup interrupt\n");
-		iwl_rx_queue_update_write_ptr(priv, &priv->rxq);
-		for (i = 0; i < priv->hw_params.max_txq_num; i++)
-			iwl_txq_update_write_ptr(priv, &priv->txq[i]);
-		priv->isr_stats.wakeup++;
-		handled |= CSR_INT_BIT_WAKEUP;
-	}
-
-	/* All uCode command responses, including Tx command responses,
-	 * Rx "responses" (frame-received notification), and other
-	 * notifications from uCode come through here*/
-	if (inta & (CSR_INT_BIT_FH_RX | CSR_INT_BIT_SW_RX)) {
-		iwl_rx_handle(priv);
-		priv->isr_stats.rx++;
-		handled |= (CSR_INT_BIT_FH_RX | CSR_INT_BIT_SW_RX);
-	}
-
-	/* This "Tx" DMA channel is used only for loading uCode */
-	if (inta & CSR_INT_BIT_FH_TX) {
-		IWL_DEBUG_ISR(priv, "uCode load interrupt\n");
-		priv->isr_stats.tx++;
-		handled |= CSR_INT_BIT_FH_TX;
-		/* Wake up uCode load routine, now that load is complete */
-		priv->ucode_write_complete = 1;
-		wake_up_interruptible(&priv->wait_command_queue);
-	}
-
-	if (inta & ~handled) {
-		IWL_ERR(priv, "Unhandled INTA bits 0x%08x\n", inta & ~handled);
-		priv->isr_stats.unhandled++;
-	}
-
-	if (inta & ~(priv->inta_mask)) {
-		IWL_WARN(priv, "Disabled INTA bits 0x%08x were pending\n",
-			 inta & ~priv->inta_mask);
-		IWL_WARN(priv, "   with FH_INT = 0x%08x\n", inta_fh);
-	}
-
-	/* Re-enable all interrupts */
-	/* only Re-enable if disabled by irq */
-	if (test_bit(STATUS_INT_ENABLED, &priv->status))
-		iwl_enable_interrupts(priv);
-	/* Re-enable RF_KILL if it occurred */
-	else if (handled & CSR_INT_BIT_RF_KILL)
-		iwl_enable_rfkill_int(priv);
-
-#ifdef CONFIG_IWLWIFI_DEBUG
-	if (iwl_get_debug_level(priv) & (IWL_DL_ISR)) {
-		inta = iwl_read32(priv, CSR_INT);
-		inta_mask = iwl_read32(priv, CSR_INT_MASK);
-		inta_fh = iwl_read32(priv, CSR_FH_INT_STATUS);
-		IWL_DEBUG_ISR(priv, "End inta 0x%08x, enabled 0x%08x, fh 0x%08x, "
-			"flags 0x%08lx\n", inta, inta_mask, inta_fh, flags);
-	}
-#endif
-}
-
 /* tasklet for iwlagn interrupt */
 static void iwl_irq_tasklet(struct iwl_priv *priv)
 {
@@ -1171,7 +753,7 @@
 		if (inta & (CSR_INT_BIT_FH_RX | CSR_INT_BIT_SW_RX)) {
 			handled |= (CSR_INT_BIT_FH_RX | CSR_INT_BIT_SW_RX);
 			iwl_write32(priv, CSR_FH_INT_STATUS,
-					CSR49_FH_INT_RX_MASK);
+					CSR_FH_INT_RX_MASK);
 		}
 		if (inta & CSR_INT_BIT_RX_PERIODIC) {
 			handled |= CSR_INT_BIT_RX_PERIODIC;
@@ -1209,7 +791,7 @@
 
 	/* This "Tx" DMA channel is used only for loading uCode */
 	if (inta & CSR_INT_BIT_FH_TX) {
-		iwl_write32(priv, CSR_FH_INT_STATUS, CSR49_FH_INT_TX_MASK);
+		iwl_write32(priv, CSR_FH_INT_STATUS, CSR_FH_INT_TX_MASK);
 		IWL_DEBUG_ISR(priv, "uCode load interrupt\n");
 		priv->isr_stats.tx++;
 		handled |= CSR_INT_BIT_FH_TX;
@@ -1357,26 +939,48 @@
  *
  ******************************************************************************/
 
-static void iwl_dealloc_ucode_pci(struct iwl_priv *priv)
+static void iwl_free_fw_desc(struct pci_dev *pci_dev, struct fw_desc *desc)
 {
-	iwl_free_fw_desc(priv->pci_dev, &priv->ucode_code);
-	iwl_free_fw_desc(priv->pci_dev, &priv->ucode_data);
-	iwl_free_fw_desc(priv->pci_dev, &priv->ucode_data_backup);
-	iwl_free_fw_desc(priv->pci_dev, &priv->ucode_init);
-	iwl_free_fw_desc(priv->pci_dev, &priv->ucode_init_data);
-	iwl_free_fw_desc(priv->pci_dev, &priv->ucode_boot);
+	if (desc->v_addr)
+		dma_free_coherent(&pci_dev->dev, desc->len,
+				  desc->v_addr, desc->p_addr);
+	desc->v_addr = NULL;
+	desc->len = 0;
 }
 
-static void iwl_nic_start(struct iwl_priv *priv)
+static void iwl_free_fw_img(struct pci_dev *pci_dev, struct fw_img *img)
 {
-	/* Remove all resets to allow NIC to operate */
-	iwl_write32(priv, CSR_RESET, 0);
+	iwl_free_fw_desc(pci_dev, &img->code);
+	iwl_free_fw_desc(pci_dev, &img->data);
+}
+
+static int iwl_alloc_fw_desc(struct pci_dev *pci_dev, struct fw_desc *desc,
+			     const void *data, size_t len)
+{
+	if (!len) {
+		desc->v_addr = NULL;
+		return -EINVAL;
+	}
+
+	desc->v_addr = dma_alloc_coherent(&pci_dev->dev, len,
+					  &desc->p_addr, GFP_KERNEL);
+	if (!desc->v_addr)
+		return -ENOMEM;
+	desc->len = len;
+	memcpy(desc->v_addr, data, len);
+	return 0;
+}
+
+static void iwl_dealloc_ucode_pci(struct iwl_priv *priv)
+{
+	iwl_free_fw_img(priv->pci_dev, &priv->ucode_rt);
+	iwl_free_fw_img(priv->pci_dev, &priv->ucode_init);
 }
 
 struct iwlagn_ucode_capabilities {
 	u32 max_probe_length;
 	u32 standard_phy_calibration_size;
-	bool pan;
+	u32 flags;
 };
 
 static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context);
@@ -1422,8 +1026,8 @@
 }
 
 struct iwlagn_firmware_pieces {
-	const void *inst, *data, *init, *init_data, *boot;
-	size_t inst_size, data_size, init_size, init_data_size, boot_size;
+	const void *inst, *data, *init, *init_data;
+	size_t inst_size, data_size, init_size, init_data_size;
 
 	u32 build;
 
@@ -1444,28 +1048,18 @@
 
 	switch (api_ver) {
 	default:
-		/*
-		 * 4965 doesn't revision the firmware file format
-		 * along with the API version, it always uses v1
-		 * file format.
-		 */
-		if ((priv->hw_rev & CSR_HW_REV_TYPE_MSK) !=
-				CSR_HW_REV_TYPE_4965) {
-			hdr_size = 28;
-			if (ucode_raw->size < hdr_size) {
-				IWL_ERR(priv, "File size too small!\n");
-				return -EINVAL;
-			}
-			pieces->build = le32_to_cpu(ucode->u.v2.build);
-			pieces->inst_size = le32_to_cpu(ucode->u.v2.inst_size);
-			pieces->data_size = le32_to_cpu(ucode->u.v2.data_size);
-			pieces->init_size = le32_to_cpu(ucode->u.v2.init_size);
-			pieces->init_data_size = le32_to_cpu(ucode->u.v2.init_data_size);
-			pieces->boot_size = le32_to_cpu(ucode->u.v2.boot_size);
-			src = ucode->u.v2.data;
-			break;
+		hdr_size = 28;
+		if (ucode_raw->size < hdr_size) {
+			IWL_ERR(priv, "File size too small!\n");
+			return -EINVAL;
 		}
-		/* fall through for 4965 */
+		pieces->build = le32_to_cpu(ucode->u.v2.build);
+		pieces->inst_size = le32_to_cpu(ucode->u.v2.inst_size);
+		pieces->data_size = le32_to_cpu(ucode->u.v2.data_size);
+		pieces->init_size = le32_to_cpu(ucode->u.v2.init_size);
+		pieces->init_data_size = le32_to_cpu(ucode->u.v2.init_data_size);
+		src = ucode->u.v2.data;
+		break;
 	case 0:
 	case 1:
 	case 2:
@@ -1479,7 +1073,6 @@
 		pieces->data_size = le32_to_cpu(ucode->u.v1.data_size);
 		pieces->init_size = le32_to_cpu(ucode->u.v1.init_size);
 		pieces->init_data_size = le32_to_cpu(ucode->u.v1.init_data_size);
-		pieces->boot_size = le32_to_cpu(ucode->u.v1.boot_size);
 		src = ucode->u.v1.data;
 		break;
 	}
@@ -1487,7 +1080,7 @@
 	/* Verify size of file vs. image size info in file's header */
 	if (ucode_raw->size != hdr_size + pieces->inst_size +
 				pieces->data_size + pieces->init_size +
-				pieces->init_data_size + pieces->boot_size) {
+				pieces->init_data_size) {
 
 		IWL_ERR(priv,
 			"uCode file size %d does not match expected size\n",
@@ -1503,8 +1096,6 @@
 	src += pieces->init_size;
 	pieces->init_data = src;
 	src += pieces->init_data_size;
-	pieces->boot = src;
-	src += pieces->boot_size;
 
 	return 0;
 }
@@ -1605,8 +1196,7 @@
 			pieces->init_data_size = tlv_len;
 			break;
 		case IWL_UCODE_TLV_BOOT:
-			pieces->boot = tlv_data;
-			pieces->boot_size = tlv_len;
+			IWL_ERR(priv, "Found unexpected BOOT ucode\n");
 			break;
 		case IWL_UCODE_TLV_PROBE_MAX_LEN:
 			if (tlv_len != sizeof(u32))
@@ -1617,7 +1207,23 @@
 		case IWL_UCODE_TLV_PAN:
 			if (tlv_len)
 				goto invalid_tlv_len;
-			capa->pan = true;
+			capa->flags |= IWL_UCODE_TLV_FLAGS_PAN;
+			break;
+		case IWL_UCODE_TLV_FLAGS:
+			/* must be at least one u32 */
+			if (tlv_len < sizeof(u32))
+				goto invalid_tlv_len;
+			/* and a proper number of u32s */
+			if (tlv_len % sizeof(u32))
+				goto invalid_tlv_len;
+			/*
+			 * This driver only reads the first u32 as
+			 * right now no more features are defined,
+			 * if that changes then either the driver
+			 * will not work with the new firmware, or
+			 * it'll not take advantage of new features.
+			 */
+			capa->flags = le32_to_cpup((__le32 *)tlv_data);
 			break;
 		case IWL_UCODE_TLV_INIT_EVTLOG_PTR:
 			if (tlv_len != sizeof(u32))
@@ -1667,7 +1273,7 @@
 					le32_to_cpup((__le32 *)tlv_data);
 			break;
 		default:
-			IWL_WARN(priv, "unknown TLV: %d\n", tlv_type);
+			IWL_DEBUG_INFO(priv, "unknown TLV: %d\n", tlv_type);
 			break;
 		}
 	}
@@ -1806,8 +1412,6 @@
 		       pieces.init_size);
 	IWL_DEBUG_INFO(priv, "f/w package hdr init data size = %Zd\n",
 		       pieces.init_data_size);
-	IWL_DEBUG_INFO(priv, "f/w package hdr boot inst size = %Zd\n",
-		       pieces.boot_size);
 
 	/* Verify that uCode images will fit in card's SRAM */
 	if (pieces.inst_size > priv->hw_params.max_inst_size) {
@@ -1834,48 +1438,25 @@
 		goto try_again;
 	}
 
-	if (pieces.boot_size > priv->hw_params.max_bsm_size) {
-		IWL_ERR(priv, "uCode boot instr len %Zd too large to fit in\n",
-			pieces.boot_size);
-		goto try_again;
-	}
-
 	/* Allocate ucode buffers for card's bus-master loading ... */
 
 	/* Runtime instructions and 2 copies of data:
 	 * 1) unmodified from disk
 	 * 2) backup cache for save/restore during power-downs */
-	priv->ucode_code.len = pieces.inst_size;
-	iwl_alloc_fw_desc(priv->pci_dev, &priv->ucode_code);
-
-	priv->ucode_data.len = pieces.data_size;
-	iwl_alloc_fw_desc(priv->pci_dev, &priv->ucode_data);
-
-	priv->ucode_data_backup.len = pieces.data_size;
-	iwl_alloc_fw_desc(priv->pci_dev, &priv->ucode_data_backup);
-
-	if (!priv->ucode_code.v_addr || !priv->ucode_data.v_addr ||
-	    !priv->ucode_data_backup.v_addr)
+	if (iwl_alloc_fw_desc(priv->pci_dev, &priv->ucode_rt.code,
+			      pieces.inst, pieces.inst_size))
+		goto err_pci_alloc;
+	if (iwl_alloc_fw_desc(priv->pci_dev, &priv->ucode_rt.data,
+			      pieces.data, pieces.data_size))
 		goto err_pci_alloc;
 
 	/* Initialization instructions and data */
 	if (pieces.init_size && pieces.init_data_size) {
-		priv->ucode_init.len = pieces.init_size;
-		iwl_alloc_fw_desc(priv->pci_dev, &priv->ucode_init);
-
-		priv->ucode_init_data.len = pieces.init_data_size;
-		iwl_alloc_fw_desc(priv->pci_dev, &priv->ucode_init_data);
-
-		if (!priv->ucode_init.v_addr || !priv->ucode_init_data.v_addr)
+		if (iwl_alloc_fw_desc(priv->pci_dev, &priv->ucode_init.code,
+				      pieces.init, pieces.init_size))
 			goto err_pci_alloc;
-	}
-
-	/* Bootstrap (instructions only, no data) */
-	if (pieces.boot_size) {
-		priv->ucode_boot.len = pieces.boot_size;
-		iwl_alloc_fw_desc(priv->pci_dev, &priv->ucode_boot);
-
-		if (!priv->ucode_boot.v_addr)
+		if (iwl_alloc_fw_desc(priv->pci_dev, &priv->ucode_init.data,
+				      pieces.init_data, pieces.init_data_size))
 			goto err_pci_alloc;
 	}
 
@@ -1901,50 +1482,19 @@
 			priv->cfg->base_params->max_event_log_size;
 	priv->_agn.inst_errlog_ptr = pieces.inst_errlog_ptr;
 
-	if (ucode_capa.pan) {
+	priv->new_scan_threshold_behaviour =
+		!!(ucode_capa.flags & IWL_UCODE_TLV_FLAGS_NEWSCAN);
+
+	if (ucode_capa.flags & IWL_UCODE_TLV_FLAGS_PAN) {
 		priv->valid_contexts |= BIT(IWL_RXON_CTX_PAN);
 		priv->sta_key_max_num = STA_KEY_MAX_NUM_PAN;
 	} else
 		priv->sta_key_max_num = STA_KEY_MAX_NUM;
 
-	/* Copy images into buffers for card's bus-master reads ... */
-
-	/* Runtime instructions (first block of data in file) */
-	IWL_DEBUG_INFO(priv, "Copying (but not loading) uCode instr len %Zd\n",
-			pieces.inst_size);
-	memcpy(priv->ucode_code.v_addr, pieces.inst, pieces.inst_size);
-
-	IWL_DEBUG_INFO(priv, "uCode instr buf vaddr = 0x%p, paddr = 0x%08x\n",
-		priv->ucode_code.v_addr, (u32)priv->ucode_code.p_addr);
-
-	/*
-	 * Runtime data
-	 * NOTE:  Copy into backup buffer will be done in iwl_up()
-	 */
-	IWL_DEBUG_INFO(priv, "Copying (but not loading) uCode data len %Zd\n",
-			pieces.data_size);
-	memcpy(priv->ucode_data.v_addr, pieces.data, pieces.data_size);
-	memcpy(priv->ucode_data_backup.v_addr, pieces.data, pieces.data_size);
-
-	/* Initialization instructions */
-	if (pieces.init_size) {
-		IWL_DEBUG_INFO(priv, "Copying (but not loading) init instr len %Zd\n",
-				pieces.init_size);
-		memcpy(priv->ucode_init.v_addr, pieces.init, pieces.init_size);
-	}
-
-	/* Initialization data */
-	if (pieces.init_data_size) {
-		IWL_DEBUG_INFO(priv, "Copying (but not loading) init data len %Zd\n",
-			       pieces.init_data_size);
-		memcpy(priv->ucode_init_data.v_addr, pieces.init_data,
-		       pieces.init_data_size);
-	}
-
-	/* Bootstrap instructions */
-	IWL_DEBUG_INFO(priv, "Copying (but not loading) boot instr len %Zd\n",
-			pieces.boot_size);
-	memcpy(priv->ucode_boot.v_addr, pieces.boot, pieces.boot_size);
+	if (priv->valid_contexts != BIT(IWL_RXON_CTX_BSS))
+		priv->cmd_queue = IWL_IPAN_CMD_QUEUE_NUM;
+	else
+		priv->cmd_queue = IWL_DEFAULT_CMD_QUEUE_NUM;
 
 	/*
 	 * figure out the offset of chain noise reset and gain commands
@@ -2062,7 +1612,7 @@
 	max = ARRAY_SIZE(advanced_lookup) - 1;
 	for (i = 0; i < max; i++) {
 		if (advanced_lookup[i].num == num)
-			break;;
+			break;
 	}
 	return advanced_lookup[i].name;
 }
@@ -2072,17 +1622,14 @@
 
 void iwl_dump_nic_error_log(struct iwl_priv *priv)
 {
-	u32 data2, line;
-	u32 desc, time, count, base, data1;
-	u32 blink1, blink2, ilink1, ilink2;
-	u32 pc, hcmd;
+	u32 base;
+	struct iwl_error_event_table table;
 
-	if (priv->ucode_type == UCODE_INIT) {
-		base = le32_to_cpu(priv->card_alive_init.error_event_table_ptr);
+	base = priv->device_pointers.error_event_table;
+	if (priv->ucode_type == UCODE_SUBTYPE_INIT) {
 		if (!base)
 			base = priv->_agn.init_errlog_ptr;
 	} else {
-		base = le32_to_cpu(priv->card_alive.error_event_table_ptr);
 		if (!base)
 			base = priv->_agn.inst_errlog_ptr;
 	}
@@ -2090,41 +1637,48 @@
 	if (!priv->cfg->ops->lib->is_valid_rtc_data_addr(base)) {
 		IWL_ERR(priv,
 			"Not valid error log pointer 0x%08X for %s uCode\n",
-			base, (priv->ucode_type == UCODE_INIT) ? "Init" : "RT");
+			base,
+			(priv->ucode_type == UCODE_SUBTYPE_INIT)
+					? "Init" : "RT");
 		return;
 	}
 
-	count = iwl_read_targ_mem(priv, base);
+	iwl_read_targ_mem_words(priv, base, &table, sizeof(table));
 
-	if (ERROR_START_OFFSET <= count * ERROR_ELEM_SIZE) {
+	if (ERROR_START_OFFSET <= table.valid * ERROR_ELEM_SIZE) {
 		IWL_ERR(priv, "Start IWL Error Log Dump:\n");
 		IWL_ERR(priv, "Status: 0x%08lX, count: %d\n",
-			priv->status, count);
+			priv->status, table.valid);
 	}
 
-	desc = iwl_read_targ_mem(priv, base + 1 * sizeof(u32));
-	priv->isr_stats.err_code = desc;
-	pc = iwl_read_targ_mem(priv, base + 2 * sizeof(u32));
-	blink1 = iwl_read_targ_mem(priv, base + 3 * sizeof(u32));
-	blink2 = iwl_read_targ_mem(priv, base + 4 * sizeof(u32));
-	ilink1 = iwl_read_targ_mem(priv, base + 5 * sizeof(u32));
-	ilink2 = iwl_read_targ_mem(priv, base + 6 * sizeof(u32));
-	data1 = iwl_read_targ_mem(priv, base + 7 * sizeof(u32));
-	data2 = iwl_read_targ_mem(priv, base + 8 * sizeof(u32));
-	line = iwl_read_targ_mem(priv, base + 9 * sizeof(u32));
-	time = iwl_read_targ_mem(priv, base + 11 * sizeof(u32));
-	hcmd = iwl_read_targ_mem(priv, base + 22 * sizeof(u32));
-
-	trace_iwlwifi_dev_ucode_error(priv, desc, time, data1, data2, line,
-				      blink1, blink2, ilink1, ilink2);
+	priv->isr_stats.err_code = table.error_id;
 
-	IWL_ERR(priv, "Desc                                  Time       "
-		"data1      data2      line\n");
-	IWL_ERR(priv, "%-28s (0x%04X) %010u 0x%08X 0x%08X %u\n",
-		desc_lookup(desc), desc, time, data1, data2, line);
-	IWL_ERR(priv, "pc      blink1  blink2  ilink1  ilink2  hcmd\n");
-	IWL_ERR(priv, "0x%05X 0x%05X 0x%05X 0x%05X 0x%05X 0x%05X\n",
-		pc, blink1, blink2, ilink1, ilink2, hcmd);
+	trace_iwlwifi_dev_ucode_error(priv, table.error_id, table.tsf_low,
+				      table.data1, table.data2, table.line,
+				      table.blink1, table.blink2, table.ilink1,
+				      table.ilink2, table.bcon_time, table.gp1,
+				      table.gp2, table.gp3, table.ucode_ver,
+				      table.hw_ver, table.brd_ver);
+	IWL_ERR(priv, "0x%08X | %-28s\n", table.error_id,
+		desc_lookup(table.error_id));
+	IWL_ERR(priv, "0x%08X | uPc\n", table.pc);
+	IWL_ERR(priv, "0x%08X | branchlink1\n", table.blink1);
+	IWL_ERR(priv, "0x%08X | branchlink2\n", table.blink2);
+	IWL_ERR(priv, "0x%08X | interruptlink1\n", table.ilink1);
+	IWL_ERR(priv, "0x%08X | interruptlink2\n", table.ilink2);
+	IWL_ERR(priv, "0x%08X | data1\n", table.data1);
+	IWL_ERR(priv, "0x%08X | data2\n", table.data2);
+	IWL_ERR(priv, "0x%08X | line\n", table.line);
+	IWL_ERR(priv, "0x%08X | beacon time\n", table.bcon_time);
+	IWL_ERR(priv, "0x%08X | tsf low\n", table.tsf_low);
+	IWL_ERR(priv, "0x%08X | tsf hi\n", table.tsf_hi);
+	IWL_ERR(priv, "0x%08X | time gp1\n", table.gp1);
+	IWL_ERR(priv, "0x%08X | time gp2\n", table.gp2);
+	IWL_ERR(priv, "0x%08X | time gp3\n", table.gp3);
+	IWL_ERR(priv, "0x%08X | uCode version\n", table.ucode_ver);
+	IWL_ERR(priv, "0x%08X | hw version\n", table.hw_ver);
+	IWL_ERR(priv, "0x%08X | board version\n", table.brd_ver);
+	IWL_ERR(priv, "0x%08X | hcmd\n", table.hcmd);
 }
 
 #define EVENT_START_OFFSET  (4 * sizeof(u32))
@@ -2147,12 +1701,11 @@
 	if (num_events == 0)
 		return pos;
 
-	if (priv->ucode_type == UCODE_INIT) {
-		base = le32_to_cpu(priv->card_alive_init.log_event_table_ptr);
+	base = priv->device_pointers.log_event_table;
+	if (priv->ucode_type == UCODE_SUBTYPE_INIT) {
 		if (!base)
 			base = priv->_agn.init_evtlog_ptr;
 	} else {
-		base = le32_to_cpu(priv->card_alive.log_event_table_ptr);
 		if (!base)
 			base = priv->_agn.inst_evtlog_ptr;
 	}
@@ -2169,14 +1722,14 @@
 	iwl_grab_nic_access(priv);
 
 	/* Set starting address; reads will auto-increment */
-	_iwl_write_direct32(priv, HBUS_TARG_MEM_RADDR, ptr);
+	iwl_write32(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);
+		ev = iwl_read32(priv, HBUS_TARG_MEM_RDAT);
+		time = iwl_read32(priv, HBUS_TARG_MEM_RDAT);
 		if (mode == 0) {
 			/* data, ev */
 			if (bufsz) {
@@ -2190,7 +1743,7 @@
 					time, ev);
 			}
 		} else {
-			data = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT);
+			data = iwl_read32(priv, HBUS_TARG_MEM_RDAT);
 			if (bufsz) {
 				pos += scnprintf(*buf + pos, bufsz - pos,
 						"EVT_LOGT:%010u:0x%08x:%04u\n",
@@ -2261,13 +1814,12 @@
 	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);
+	base = priv->device_pointers.log_event_table;
+	if (priv->ucode_type == UCODE_SUBTYPE_INIT) {
 		logsize = priv->_agn.init_evtlog_size;
 		if (!base)
 			base = priv->_agn.init_evtlog_ptr;
 	} else {
-		base = le32_to_cpu(priv->card_alive.log_event_table_ptr);
 		logsize = priv->_agn.inst_evtlog_size;
 		if (!base)
 			base = priv->_agn.inst_evtlog_ptr;
@@ -2276,7 +1828,9 @@
 	if (!priv->cfg->ops->lib->is_valid_rtc_data_addr(base)) {
 		IWL_ERR(priv,
 			"Invalid event log pointer 0x%08X for %s uCode\n",
-			base, (priv->ucode_type == UCODE_INIT) ? "Init" : "RT");
+			base,
+			(priv->ucode_type == UCODE_SUBTYPE_INIT)
+					? "Init" : "RT");
 		return -EINVAL;
 	}
 
@@ -2406,8 +1960,8 @@
 	struct iwl_calib_cfg_cmd calib_cfg_cmd;
 	struct iwl_host_cmd cmd = {
 		.id = CALIBRATION_CFG_CMD,
-		.len = sizeof(struct iwl_calib_cfg_cmd),
-		.data = &calib_cfg_cmd,
+		.len = { sizeof(struct iwl_calib_cfg_cmd), },
+		.data = { &calib_cfg_cmd, },
 	};
 
 	memset(&calib_cfg_cmd, 0, sizeof(calib_cfg_cmd));
@@ -2423,30 +1977,14 @@
  *                   from protocol/runtime uCode (initialization uCode's
  *                   Alive gets handled by iwl_init_alive_start()).
  */
-static void iwl_alive_start(struct iwl_priv *priv)
+int iwl_alive_start(struct iwl_priv *priv)
 {
 	int ret = 0;
 	struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
 
-	IWL_DEBUG_INFO(priv, "Runtime Alive received.\n");
-
-	/* Initialize uCode has loaded Runtime uCode ... verify inst image.
-	 * This is a paranoid check, because we would not have gotten the
-	 * "runtime" alive if code weren't properly loaded.  */
-	if (iwl_verify_ucode(priv)) {
-		/* Runtime instruction load was bad;
-		 * take it all the way back down so we can try again */
-		IWL_DEBUG_INFO(priv, "Bad runtime uCode load.\n");
-		goto restart;
-	}
-
-	ret = priv->cfg->ops->lib->alive_notify(priv);
-	if (ret) {
-		IWL_WARN(priv,
-			"Could not complete ALIVE transition [ntf]: %d\n", ret);
-		goto restart;
-	}
+	iwl_reset_ict(priv);
 
+	IWL_DEBUG_INFO(priv, "Runtime Alive received.\n");
 
 	/* After the ALIVE response, we can send host commands to the uCode */
 	set_bit(STATUS_ALIVE, &priv->status);
@@ -2455,7 +1993,7 @@
 	iwl_setup_watchdog(priv);
 
 	if (iwl_is_rfkill(priv))
-		return;
+		return -ERFKILL;
 
 	/* download priority table before any calibration request */
 	if (priv->cfg->bt_params &&
@@ -2469,10 +2007,14 @@
 		iwlagn_send_prio_tbl(priv);
 
 		/* FIXME: w/a to force change uCode BT state machine */
-		iwlagn_send_bt_env(priv, IWL_BT_COEX_ENV_OPEN,
-			BT_COEX_PRIO_TBL_EVT_INIT_CALIB2);
-		iwlagn_send_bt_env(priv, IWL_BT_COEX_ENV_CLOSE,
-			BT_COEX_PRIO_TBL_EVT_INIT_CALIB2);
+		ret = iwlagn_send_bt_env(priv, IWL_BT_COEX_ENV_OPEN,
+					 BT_COEX_PRIO_TBL_EVT_INIT_CALIB2);
+		if (ret)
+			return ret;
+		ret = iwlagn_send_bt_env(priv, IWL_BT_COEX_ENV_CLOSE,
+					 BT_COEX_PRIO_TBL_EVT_INIT_CALIB2);
+		if (ret)
+			return ret;
 	}
 	if (priv->hw_params.calib_rt_cfg)
 		iwlagn_send_calib_cfg_rt(priv, priv->hw_params.calib_rt_cfg);
@@ -2514,30 +2056,23 @@
 	set_bit(STATUS_READY, &priv->status);
 
 	/* Configure the adapter for unassociated operation */
-	iwlcore_commit_rxon(priv, ctx);
+	ret = iwlcore_commit_rxon(priv, ctx);
+	if (ret)
+		return ret;
 
 	/* At this point, the NIC is initialized and operational */
 	iwl_rf_kill_ct_config(priv);
 
 	IWL_DEBUG_INFO(priv, "ALIVE processing complete.\n");
-	wake_up_interruptible(&priv->wait_command_queue);
 
-	iwl_power_update_mode(priv, true);
-	IWL_DEBUG_INFO(priv, "Updated power mode\n");
-
-
-	return;
-
- restart:
-	queue_work(priv->workqueue, &priv->restart);
+	return iwl_power_update_mode(priv, true);
 }
 
 static void iwl_cancel_deferred_work(struct iwl_priv *priv);
 
 static void __iwl_down(struct iwl_priv *priv)
 {
-	unsigned long flags;
-	int exit_pending = test_bit(STATUS_EXIT_PENDING, &priv->status);
+	int exit_pending;
 
 	IWL_DEBUG_INFO(priv, DRV_NAME " is going down\n");
 
@@ -2563,40 +2098,15 @@
 	priv->bt_full_concurrent = false;
 	priv->bt_ci_compliance = 0;
 
-	/* Unblock any waiting calls */
-	wake_up_interruptible_all(&priv->wait_command_queue);
-
 	/* Wipe out the EXIT_PENDING status bit if we are not actually
 	 * exiting the module */
 	if (!exit_pending)
 		clear_bit(STATUS_EXIT_PENDING, &priv->status);
 
-	/* stop and reset the on-board processor */
-	iwl_write32(priv, CSR_RESET, CSR_RESET_REG_FLAG_NEVO_RESET);
-
-	/* tell the device to stop sending interrupts */
-	spin_lock_irqsave(&priv->lock, flags);
-	iwl_disable_interrupts(priv);
-	spin_unlock_irqrestore(&priv->lock, flags);
-	iwl_synchronize_irq(priv);
-
 	if (priv->mac80211_registered)
 		ieee80211_stop_queues(priv->hw);
 
-	/* If we have not previously called iwl_init() then
-	 * clear all bits but the RF Kill bit and return */
-	if (!iwl_is_init(priv)) {
-		priv->status = test_bit(STATUS_RF_KILL_HW, &priv->status) <<
-					STATUS_RF_KILL_HW |
-			       test_bit(STATUS_GEO_CONFIGURED, &priv->status) <<
-					STATUS_GEO_CONFIGURED |
-			       test_bit(STATUS_EXIT_PENDING, &priv->status) <<
-					STATUS_EXIT_PENDING;
-		goto exit;
-	}
-
-	/* ...otherwise clear out all the status bits but the RF Kill
-	 * bit and continue taking the NIC down. */
+	/* Clear out all status bits but a few that are stable across reset */
 	priv->status &= test_bit(STATUS_RF_KILL_HW, &priv->status) <<
 				STATUS_RF_KILL_HW |
 			test_bit(STATUS_GEO_CONFIGURED, &priv->status) <<
@@ -2606,31 +2116,10 @@
 		       test_bit(STATUS_EXIT_PENDING, &priv->status) <<
 				STATUS_EXIT_PENDING;
 
-	/* device going down, Stop using ICT table */
-	if (priv->cfg->ops->lib->isr_ops.disable)
-		priv->cfg->ops->lib->isr_ops.disable(priv);
-
-	iwlagn_txq_ctx_stop(priv);
-	iwlagn_rxq_stop(priv);
-
-	/* Power-down device's busmaster DMA clocks */
-	iwl_write_prph(priv, APMG_CLK_DIS_REG, APMG_CLK_VAL_DMA_CLK_RQT);
-	udelay(5);
-
-	/* Make sure (redundant) we've released our request to stay awake */
-	iwl_clear_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
-
-	/* Stop the device, and put it in low power state */
-	iwl_apm_stop(priv);
-
- exit:
-	memset(&priv->card_alive, 0, sizeof(struct iwl_alive_resp));
+	iwlagn_stop_device(priv);
 
 	dev_kfree_skb(priv->beacon_skb);
 	priv->beacon_skb = NULL;
-
-	/* clear out any free frames */
-	iwl_clear_free_frames(priv);
 }
 
 static void iwl_down(struct iwl_priv *priv)
@@ -2644,9 +2133,10 @@
 
 #define HW_READY_TIMEOUT (50)
 
+/* Note: returns poll_bit return value, which is >= 0 if success */
 static int iwl_set_hw_ready(struct iwl_priv *priv)
 {
-	int ret = 0;
+	int ret;
 
 	iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG,
 		CSR_HW_IF_CONFIG_REG_BIT_NIC_READY);
@@ -2656,25 +2146,21 @@
 				CSR_HW_IF_CONFIG_REG_BIT_NIC_READY,
 				CSR_HW_IF_CONFIG_REG_BIT_NIC_READY,
 				HW_READY_TIMEOUT);
-	if (ret != -ETIMEDOUT)
-		priv->hw_ready = true;
-	else
-		priv->hw_ready = false;
 
-	IWL_DEBUG_INFO(priv, "hardware %s\n",
-		      (priv->hw_ready == 1) ? "ready" : "not ready");
+	IWL_DEBUG_INFO(priv, "hardware%s ready\n", ret < 0 ? " not" : "");
 	return ret;
 }
 
-static int iwl_prepare_card_hw(struct iwl_priv *priv)
+/* Note: returns standard 0/-ERROR code */
+int iwl_prepare_card_hw(struct iwl_priv *priv)
 {
-	int ret = 0;
+	int ret;
 
 	IWL_DEBUG_INFO(priv, "iwl_prepare_card_hw enter\n");
 
 	ret = iwl_set_hw_ready(priv);
-	if (priv->hw_ready)
-		return ret;
+	if (ret >= 0)
+		return 0;
 
 	/* If HW is not ready, prepare the conditions to check again */
 	iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG,
@@ -2684,10 +2170,13 @@
 			~CSR_HW_IF_CONFIG_REG_BIT_NIC_PREPARE_DONE,
 			CSR_HW_IF_CONFIG_REG_BIT_NIC_PREPARE_DONE, 150000);
 
-	/* HW should be ready by now, check again. */
-	if (ret != -ETIMEDOUT)
-		iwl_set_hw_ready(priv);
+	if (ret < 0)
+		return ret;
 
+	/* HW should be ready by now, check again. */
+	ret = iwl_set_hw_ready(priv);
+	if (ret >= 0)
+		return 0;
 	return ret;
 }
 
@@ -2696,19 +2185,15 @@
 static int __iwl_up(struct iwl_priv *priv)
 {
 	struct iwl_rxon_context *ctx;
-	int i;
 	int ret;
 
+	lockdep_assert_held(&priv->mutex);
+
 	if (test_bit(STATUS_EXIT_PENDING, &priv->status)) {
 		IWL_WARN(priv, "Exit pending; will not bring the NIC up\n");
 		return -EIO;
 	}
 
-	if (!priv->ucode_data_backup.v_addr || !priv->ucode_data.v_addr) {
-		IWL_ERR(priv, "ucode not available for device bringup\n");
-		return -EIO;
-	}
-
 	for_each_context(priv, ctx) {
 		ret = iwlagn_alloc_bcast_station(priv, ctx);
 		if (ret) {
@@ -2717,89 +2202,33 @@
 		}
 	}
 
-	iwl_prepare_card_hw(priv);
-
-	if (!priv->hw_ready) {
-		IWL_WARN(priv, "Exit HW not ready\n");
-		return -EIO;
-	}
-
-	/* If platform's RF_KILL switch is NOT set to KILL */
-	if (iwl_read32(priv, CSR_GP_CNTRL) & CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW)
-		clear_bit(STATUS_RF_KILL_HW, &priv->status);
-	else
-		set_bit(STATUS_RF_KILL_HW, &priv->status);
-
-	if (iwl_is_rfkill(priv)) {
-		wiphy_rfkill_set_hw_state(priv->hw->wiphy, true);
-
-		iwl_enable_interrupts(priv);
-		IWL_WARN(priv, "Radio disabled by HW RF Kill switch\n");
-		return 0;
+	ret = iwlagn_run_init_ucode(priv);
+	if (ret) {
+		IWL_ERR(priv, "Failed to run INIT ucode: %d\n", ret);
+		goto error;
 	}
 
-	iwl_write32(priv, CSR_INT, 0xFFFFFFFF);
-
-	/* must be initialised before iwl_hw_nic_init */
-	if (priv->valid_contexts != BIT(IWL_RXON_CTX_BSS))
-		priv->cmd_queue = IWL_IPAN_CMD_QUEUE_NUM;
-	else
-		priv->cmd_queue = IWL_DEFAULT_CMD_QUEUE_NUM;
-
-	ret = iwlagn_hw_nic_init(priv);
+	ret = iwlagn_load_ucode_wait_alive(priv,
+					   &priv->ucode_rt,
+					   UCODE_SUBTYPE_REGULAR,
+					   UCODE_SUBTYPE_REGULAR_NEW);
 	if (ret) {
-		IWL_ERR(priv, "Unable to init nic\n");
-		return ret;
+		IWL_ERR(priv, "Failed to start RT ucode: %d\n", ret);
+		goto error;
 	}
 
-	/* make sure rfkill handshake bits are cleared */
-	iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL);
-	iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR,
-		    CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED);
-
-	/* clear (again), then enable host interrupts */
-	iwl_write32(priv, CSR_INT, 0xFFFFFFFF);
-	iwl_enable_interrupts(priv);
-
-	/* really make sure rfkill handshake bits are cleared */
-	iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL);
-	iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL);
-
-	/* Copy original ucode data image from disk into backup cache.
-	 * This will be used to initialize the on-board processor's
-	 * data SRAM for a clean start when the runtime program first loads. */
-	memcpy(priv->ucode_data_backup.v_addr, priv->ucode_data.v_addr,
-	       priv->ucode_data.len);
-
-	for (i = 0; i < MAX_HW_RESTARTS; i++) {
-
-		/* load bootstrap state machine,
-		 * load bootstrap program into processor's memory,
-		 * prepare to load the "initialize" uCode */
-		ret = priv->cfg->ops->lib->load_ucode(priv);
-
-		if (ret) {
-			IWL_ERR(priv, "Unable to set up bootstrap uCode: %d\n",
-				ret);
-			continue;
-		}
-
-		/* start card; "initialize" will load runtime ucode */
-		iwl_nic_start(priv);
-
-		IWL_DEBUG_INFO(priv, DRV_NAME " is coming up\n");
-
-		return 0;
-	}
+	ret = iwl_alive_start(priv);
+	if (ret)
+		goto error;
+	return 0;
 
+ error:
 	set_bit(STATUS_EXIT_PENDING, &priv->status);
 	__iwl_down(priv);
 	clear_bit(STATUS_EXIT_PENDING, &priv->status);
 
-	/* tried to restart and config the device for as long as our
-	 * patience could withstand */
-	IWL_ERR(priv, "Unable to initialize device after %d attempts.\n", i);
-	return -EIO;
+	IWL_ERR(priv, "Unable to initialize device.\n");
+	return ret;
 }
 
 
@@ -2809,36 +2238,6 @@
  *
  *****************************************************************************/
 
-static void iwl_bg_init_alive_start(struct work_struct *data)
-{
-	struct iwl_priv *priv =
-	    container_of(data, struct iwl_priv, init_alive_start.work);
-
-	if (test_bit(STATUS_EXIT_PENDING, &priv->status))
-		return;
-
-	mutex_lock(&priv->mutex);
-	priv->cfg->ops->lib->init_alive_start(priv);
-	mutex_unlock(&priv->mutex);
-}
-
-static void iwl_bg_alive_start(struct work_struct *data)
-{
-	struct iwl_priv *priv =
-	    container_of(data, struct iwl_priv, alive_start.work);
-
-	if (test_bit(STATUS_EXIT_PENDING, &priv->status))
-		return;
-
-	/* enable dram interrupt */
-	if (priv->cfg->ops->lib->isr_ops.reset)
-		priv->cfg->ops->lib->isr_ops.reset(priv);
-
-	mutex_lock(&priv->mutex);
-	iwl_alive_start(priv);
-	mutex_unlock(&priv->mutex);
-}
-
 static void iwl_bg_run_time_calib_work(struct work_struct *work)
 {
 	struct iwl_priv *priv = container_of(work, struct iwl_priv,
@@ -2853,22 +2252,49 @@
 	}
 
 	if (priv->start_calib) {
-		if (iwl_bt_statistics(priv)) {
-			iwl_chain_noise_calibration(priv,
-					(void *)&priv->_agn.statistics_bt);
-			iwl_sensitivity_calibration(priv,
-					(void *)&priv->_agn.statistics_bt);
-		} else {
-			iwl_chain_noise_calibration(priv,
-					(void *)&priv->_agn.statistics);
-			iwl_sensitivity_calibration(priv,
-					(void *)&priv->_agn.statistics);
-		}
+		iwl_chain_noise_calibration(priv);
+		iwl_sensitivity_calibration(priv);
 	}
 
 	mutex_unlock(&priv->mutex);
 }
 
+static void iwlagn_prepare_restart(struct iwl_priv *priv)
+{
+	struct iwl_rxon_context *ctx;
+	bool bt_full_concurrent;
+	u8 bt_ci_compliance;
+	u8 bt_load;
+	u8 bt_status;
+
+	lockdep_assert_held(&priv->mutex);
+
+	for_each_context(priv, ctx)
+		ctx->vif = NULL;
+	priv->is_open = 0;
+
+	/*
+	 * __iwl_down() will clear the BT status variables,
+	 * which is correct, but when we restart we really
+	 * want to keep them so restore them afterwards.
+	 *
+	 * The restart process will later pick them up and
+	 * re-configure the hw when we reconfigure the BT
+	 * command.
+	 */
+	bt_full_concurrent = priv->bt_full_concurrent;
+	bt_ci_compliance = priv->bt_ci_compliance;
+	bt_load = priv->bt_traffic_load;
+	bt_status = priv->bt_status;
+
+	__iwl_down(priv);
+
+	priv->bt_full_concurrent = bt_full_concurrent;
+	priv->bt_ci_compliance = bt_ci_compliance;
+	priv->bt_traffic_load = bt_load;
+	priv->bt_status = bt_status;
+}
+
 static void iwl_bg_restart(struct work_struct *data)
 {
 	struct iwl_priv *priv = container_of(data, struct iwl_priv, restart);
@@ -2877,50 +2303,13 @@
 		return;
 
 	if (test_and_clear_bit(STATUS_FW_ERROR, &priv->status)) {
-		struct iwl_rxon_context *ctx;
-		bool bt_full_concurrent;
-		u8 bt_ci_compliance;
-		u8 bt_load;
-		u8 bt_status;
-
 		mutex_lock(&priv->mutex);
-		for_each_context(priv, ctx)
-			ctx->vif = NULL;
-		priv->is_open = 0;
-
-		/*
-		 * __iwl_down() will clear the BT status variables,
-		 * which is correct, but when we restart we really
-		 * want to keep them so restore them afterwards.
-		 *
-		 * The restart process will later pick them up and
-		 * re-configure the hw when we reconfigure the BT
-		 * command.
-		 */
-		bt_full_concurrent = priv->bt_full_concurrent;
-		bt_ci_compliance = priv->bt_ci_compliance;
-		bt_load = priv->bt_traffic_load;
-		bt_status = priv->bt_status;
-
-		__iwl_down(priv);
-
-		priv->bt_full_concurrent = bt_full_concurrent;
-		priv->bt_ci_compliance = bt_ci_compliance;
-		priv->bt_traffic_load = bt_load;
-		priv->bt_status = bt_status;
-
+		iwlagn_prepare_restart(priv);
 		mutex_unlock(&priv->mutex);
 		iwl_cancel_deferred_work(priv);
 		ieee80211_restart_hw(priv->hw);
 	} else {
-		iwl_down(priv);
-
-		if (test_bit(STATUS_EXIT_PENDING, &priv->status))
-			return;
-
-		mutex_lock(&priv->mutex);
-		__iwl_up(priv);
-		mutex_unlock(&priv->mutex);
+		WARN_ON(1);
 	}
 }
 
@@ -3031,8 +2420,6 @@
  *
  *****************************************************************************/
 
-#define UCODE_READY_TIMEOUT	(4 * HZ)
-
 /*
  * Not a mac80211 entry point function, but it fits in with all the
  * other mac80211 functions grouped here.
@@ -3055,14 +2442,16 @@
 
 	hw->max_tx_aggregation_subframes = LINK_QUAL_AGG_FRAME_LIMIT_DEF;
 
-	if (!priv->cfg->base_params->broken_powersave)
-		hw->flags |= IEEE80211_HW_SUPPORTS_PS |
-			     IEEE80211_HW_SUPPORTS_DYNAMIC_PS;
+	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;
 
+	if (capa->flags & IWL_UCODE_TLV_FLAGS_MFP)
+		hw->flags |= IEEE80211_HW_MFP_CAPABLE;
+
 	hw->sta_data_size = sizeof(struct iwl_station_priv);
 	hw->vif_data_size = sizeof(struct iwl_vif_priv);
 
@@ -3112,7 +2501,7 @@
 }
 
 
-int iwlagn_mac_start(struct ieee80211_hw *hw)
+static int iwlagn_mac_start(struct ieee80211_hw *hw)
 {
 	struct iwl_priv *priv = hw->priv;
 	int ret;
@@ -3123,37 +2512,23 @@
 	mutex_lock(&priv->mutex);
 	ret = __iwl_up(priv);
 	mutex_unlock(&priv->mutex);
-
 	if (ret)
 		return ret;
 
-	if (iwl_is_rfkill(priv))
-		goto out;
-
 	IWL_DEBUG_INFO(priv, "Start UP work done.\n");
 
-	/* Wait for START_ALIVE from Run Time ucode. Otherwise callbacks from
-	 * mac80211 will not be run successfully. */
-	ret = wait_event_interruptible_timeout(priv->wait_command_queue,
-			test_bit(STATUS_READY, &priv->status),
-			UCODE_READY_TIMEOUT);
-	if (!ret) {
-		if (!test_bit(STATUS_READY, &priv->status)) {
-			IWL_ERR(priv, "START_ALIVE timeout after %dms.\n",
-				jiffies_to_msecs(UCODE_READY_TIMEOUT));
-			return -ETIMEDOUT;
-		}
-	}
+	/* Now we should be done, and the READY bit should be set. */
+	if (WARN_ON(!test_bit(STATUS_READY, &priv->status)))
+		ret = -EIO;
 
 	iwlagn_led_enable(priv);
 
-out:
 	priv->is_open = 1;
 	IWL_DEBUG_MAC80211(priv, "leave\n");
 	return 0;
 }
 
-void iwlagn_mac_stop(struct ieee80211_hw *hw)
+static void iwlagn_mac_stop(struct ieee80211_hw *hw)
 {
 	struct iwl_priv *priv = hw->priv;
 
@@ -3176,7 +2551,7 @@
 	IWL_DEBUG_MAC80211(priv, "leave\n");
 }
 
-void iwlagn_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
+static void iwlagn_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
 {
 	struct iwl_priv *priv = hw->priv;
 
@@ -3191,11 +2566,11 @@
 	IWL_DEBUG_MACDUMP(priv, "leave\n");
 }
 
-void iwlagn_mac_update_tkip_key(struct ieee80211_hw *hw,
-				struct ieee80211_vif *vif,
-				struct ieee80211_key_conf *keyconf,
-				struct ieee80211_sta *sta,
-				u32 iv32, u16 *phase1key)
+static void iwlagn_mac_update_tkip_key(struct ieee80211_hw *hw,
+				       struct ieee80211_vif *vif,
+				       struct ieee80211_key_conf *keyconf,
+				       struct ieee80211_sta *sta,
+				       u32 iv32, u16 *phase1key)
 {
 	struct iwl_priv *priv = hw->priv;
 	struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv;
@@ -3208,9 +2583,10 @@
 	IWL_DEBUG_MAC80211(priv, "leave\n");
 }
 
-int iwlagn_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
-		       struct ieee80211_vif *vif, struct ieee80211_sta *sta,
-		       struct ieee80211_key_conf *key)
+static int iwlagn_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
+			      struct ieee80211_vif *vif,
+			      struct ieee80211_sta *sta,
+			      struct ieee80211_key_conf *key)
 {
 	struct iwl_priv *priv = hw->priv;
 	struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv;
@@ -3221,7 +2597,7 @@
 
 	IWL_DEBUG_MAC80211(priv, "enter\n");
 
-	if (priv->cfg->mod_params->sw_crypto) {
+	if (iwlagn_mod_params.sw_crypto) {
 		IWL_DEBUG_MAC80211(priv, "leave - hwcrypto disabled\n");
 		return -EOPNOTSUPP;
 	}
@@ -3285,11 +2661,11 @@
 	return ret;
 }
 
-int iwlagn_mac_ampdu_action(struct ieee80211_hw *hw,
-			    struct ieee80211_vif *vif,
-			    enum ieee80211_ampdu_mlme_action action,
-			    struct ieee80211_sta *sta, u16 tid, u16 *ssn,
-			    u8 buf_size)
+static int iwlagn_mac_ampdu_action(struct ieee80211_hw *hw,
+				   struct ieee80211_vif *vif,
+				   enum ieee80211_ampdu_mlme_action action,
+				   struct ieee80211_sta *sta, u16 tid, u16 *ssn,
+				   u8 buf_size)
 {
 	struct iwl_priv *priv = hw->priv;
 	int ret = -EINVAL;
@@ -3348,6 +2724,10 @@
 		}
 		break;
 	case IEEE80211_AMPDU_TX_OPERATIONAL:
+		buf_size = min_t(int, buf_size, LINK_QUAL_AGG_FRAME_LIMIT_DEF);
+
+		iwlagn_txq_agg_queue_setup(priv, sta, tid, buf_size);
+
 		/*
 		 * If the limit is 0, then it wasn't initialised yet,
 		 * use the default. We can do that since we take the
@@ -3392,9 +2772,9 @@
 	return ret;
 }
 
-int iwlagn_mac_sta_add(struct ieee80211_hw *hw,
-		       struct ieee80211_vif *vif,
-		       struct ieee80211_sta *sta)
+static int iwlagn_mac_sta_add(struct ieee80211_hw *hw,
+			      struct ieee80211_vif *vif,
+			      struct ieee80211_sta *sta)
 {
 	struct iwl_priv *priv = hw->priv;
 	struct iwl_station_priv *sta_priv = (void *)sta->drv_priv;
@@ -3435,8 +2815,8 @@
 	return 0;
 }
 
-void iwlagn_mac_channel_switch(struct ieee80211_hw *hw,
-			       struct ieee80211_channel_switch *ch_switch)
+static void iwlagn_mac_channel_switch(struct ieee80211_hw *hw,
+				struct ieee80211_channel_switch *ch_switch)
 {
 	struct iwl_priv *priv = hw->priv;
 	const struct iwl_channel_info *ch_info;
@@ -3457,21 +2837,19 @@
 
 	IWL_DEBUG_MAC80211(priv, "enter\n");
 
+	mutex_lock(&priv->mutex);
+
 	if (iwl_is_rfkill(priv))
-		goto out_exit;
+		goto out;
 
 	if (test_bit(STATUS_EXIT_PENDING, &priv->status) ||
-	    test_bit(STATUS_SCANNING, &priv->status))
-		goto out_exit;
+	    test_bit(STATUS_SCANNING, &priv->status) ||
+	    test_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->status))
+		goto out;
 
 	if (!iwl_is_associated_ctx(ctx))
-		goto out_exit;
-
-	/* channel switch in progress */
-	if (priv->switch_rxon.switch_in_progress == true)
-		goto out_exit;
+		goto out;
 
-	mutex_lock(&priv->mutex);
 	if (priv->cfg->ops->lib->set_channel_switch) {
 
 		ch = channel->hw_value;
@@ -3520,23 +2898,26 @@
 			 * at this point, staging_rxon has the
 			 * configuration for channel switch
 			 */
+			set_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->status);
+			priv->switch_channel = cpu_to_le16(ch);
 			if (priv->cfg->ops->lib->set_channel_switch(priv,
-								    ch_switch))
-				priv->switch_rxon.switch_in_progress = false;
+								    ch_switch)) {
+				clear_bit(STATUS_CHANNEL_SWITCH_PENDING,
+					  &priv->status);
+				priv->switch_channel = 0;
+				ieee80211_chswitch_done(ctx->vif, false);
+			}
 		}
 	}
 out:
 	mutex_unlock(&priv->mutex);
-out_exit:
-	if (!priv->switch_rxon.switch_in_progress)
-		ieee80211_chswitch_done(ctx->vif, false);
 	IWL_DEBUG_MAC80211(priv, "leave\n");
 }
 
-void iwlagn_configure_filter(struct ieee80211_hw *hw,
-			     unsigned int changed_flags,
-			     unsigned int *total_flags,
-			     u64 multicast)
+static void iwlagn_configure_filter(struct ieee80211_hw *hw,
+				    unsigned int changed_flags,
+				    unsigned int *total_flags,
+				    u64 multicast)
 {
 	struct iwl_priv *priv = hw->priv;
 	__le32 filter_or = 0, filter_nand = 0;
@@ -3583,7 +2964,7 @@
 			FIF_BCN_PRBRESP_PROMISC | FIF_CONTROL;
 }
 
-void iwlagn_mac_flush(struct ieee80211_hw *hw, bool drop)
+static void iwlagn_mac_flush(struct ieee80211_hw *hw, bool drop)
 {
 	struct iwl_priv *priv = hw->priv;
 
@@ -3729,8 +3110,6 @@
 	INIT_WORK(&priv->tx_flush, iwl_bg_tx_flush);
 	INIT_WORK(&priv->bt_full_concurrency, iwl_bg_bt_full_concurrency);
 	INIT_WORK(&priv->bt_runtime_config, iwl_bg_bt_runtime_config);
-	INIT_DELAYED_WORK(&priv->init_alive_start, iwl_bg_init_alive_start);
-	INIT_DELAYED_WORK(&priv->alive_start, iwl_bg_alive_start);
 	INIT_DELAYED_WORK(&priv->_agn.hw_roc_work, iwlagn_bg_roc_done);
 
 	iwl_setup_scan_deferred_work(priv);
@@ -3750,12 +3129,8 @@
 	priv->watchdog.data = (unsigned long)priv;
 	priv->watchdog.function = iwl_bg_watchdog;
 
-	if (!priv->cfg->base_params->use_isr_legacy)
-		tasklet_init(&priv->irq_tasklet, (void (*)(unsigned long))
-			iwl_irq_tasklet, (unsigned long)priv);
-	else
-		tasklet_init(&priv->irq_tasklet, (void (*)(unsigned long))
-			iwl_irq_tasklet_legacy, (unsigned long)priv);
+	tasklet_init(&priv->irq_tasklet, (void (*)(unsigned long))
+		iwl_irq_tasklet, (unsigned long)priv);
 }
 
 static void iwl_cancel_deferred_work(struct iwl_priv *priv)
@@ -3763,8 +3138,6 @@
 	if (priv->cfg->ops->lib->cancel_deferred_work)
 		priv->cfg->ops->lib->cancel_deferred_work(priv);
 
-	cancel_delayed_work_sync(&priv->init_alive_start);
-	cancel_delayed_work(&priv->alive_start);
 	cancel_work_sync(&priv->run_time_calib_work);
 	cancel_work_sync(&priv->beacon_update);
 
@@ -3805,10 +3178,7 @@
 	spin_lock_init(&priv->sta_lock);
 	spin_lock_init(&priv->hcmd_lock);
 
-	INIT_LIST_HEAD(&priv->free_frames);
-
 	mutex_init(&priv->mutex);
-	mutex_init(&priv->sync_cmd_mutex);
 
 	priv->ieee_channels = NULL;
 	priv->ieee_rates = NULL;
@@ -3845,12 +3215,6 @@
 		priv->dynamic_frag_thresh = BT_FRAG_THRESHOLD_DEF;
 	}
 
-	/* Set the tx_power_user_lmt to the lowest power level
-	 * this value will get overwritten by channel max power avg
-	 * from eeprom */
-	priv->tx_power_user_lmt = IWLAGN_TX_POWER_TARGET_POWER_MIN;
-	priv->tx_power_next = IWLAGN_TX_POWER_TARGET_POWER_MIN;
-
 	ret = iwl_init_channel_map(priv);
 	if (ret) {
 		IWL_ERR(priv, "initializing regulatory failed: %d\n", ret);
@@ -3878,6 +3242,7 @@
 	iwlcore_free_geos(priv);
 	iwl_free_channel_map(priv);
 	kfree(priv->scan_cmd);
+	kfree(priv->beacon_cmd);
 }
 
 struct ieee80211_ops iwlagn_hw_ops = {
@@ -3905,28 +3270,30 @@
 	.cancel_remain_on_channel = iwl_mac_cancel_remain_on_channel,
 	.offchannel_tx = iwl_mac_offchannel_tx,
 	.offchannel_tx_cancel_wait = iwl_mac_offchannel_tx_cancel_wait,
+	CFG80211_TESTMODE_CMD(iwl_testmode_cmd)
 };
 
-static void iwl_hw_detect(struct iwl_priv *priv)
+static u32 iwl_hw_detect(struct iwl_priv *priv)
 {
-	priv->hw_rev = _iwl_read32(priv, CSR_HW_REV);
-	priv->hw_wa_rev = _iwl_read32(priv, CSR_HW_REV_WA_REG);
-	priv->rev_id = priv->pci_dev->revision;
-	IWL_DEBUG_INFO(priv, "HW Revision ID = 0x%X\n", priv->rev_id);
+	u8 rev_id;
+
+	pci_read_config_byte(priv->pci_dev, PCI_REVISION_ID, &rev_id);
+	IWL_DEBUG_INFO(priv, "HW Revision ID = 0x%X\n", rev_id);
+	return iwl_read32(priv, CSR_HW_REV);
 }
 
 static int iwl_set_hw_params(struct iwl_priv *priv)
 {
 	priv->hw_params.max_rxq_size = RX_QUEUE_SIZE;
 	priv->hw_params.max_rxq_log = RX_QUEUE_SIZE_LOG;
-	if (priv->cfg->mod_params->amsdu_size_8K)
+	if (iwlagn_mod_params.amsdu_size_8K)
 		priv->hw_params.rx_page_order = get_order(IWL_RX_BUF_SIZE_8K);
 	else
 		priv->hw_params.rx_page_order = get_order(IWL_RX_BUF_SIZE_4K);
 
 	priv->hw_params.max_beacon_itrvl = IWL_MAX_UCODE_BEACON_INTERVAL;
 
-	if (priv->cfg->mod_params->disable_11n)
+	if (iwlagn_mod_params.disable_11n)
 		priv->cfg->sku &= ~IWL_SKU_N;
 
 	/* Device-specific setup */
@@ -3955,6 +3322,28 @@
 	7, 6, 5, 4,
 };
 
+/* This function both allocates and initializes hw and priv. */
+static struct ieee80211_hw *iwl_alloc_all(struct iwl_cfg *cfg)
+{
+	struct iwl_priv *priv;
+	/* mac80211 allocates memory for this device instance, including
+	 *   space for this driver's private structure */
+	struct ieee80211_hw *hw;
+
+	hw = ieee80211_alloc_hw(sizeof(struct iwl_priv), &iwlagn_hw_ops);
+	if (hw == NULL) {
+		pr_err("%s: Can not allocate network device\n",
+		       cfg->name);
+		goto out;
+	}
+
+	priv = hw->priv;
+	priv->hw = hw;
+
+out:
+	return hw;
+}
+
 static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 {
 	int err = 0, i;
@@ -3963,19 +3352,12 @@
 	struct iwl_cfg *cfg = (struct iwl_cfg *)(ent->driver_data);
 	unsigned long flags;
 	u16 pci_cmd, num_mac;
+	u32 hw_rev;
 
 	/************************
 	 * 1. Allocating HW data
 	 ************************/
 
-	/* Disabling hardware scan means that mac80211 will perform scans
-	 * "the hard way", rather than using device's scan. */
-	if (cfg->mod_params->disable_hw_scan) {
-		dev_printk(KERN_DEBUG, &(pdev->dev),
-			"sw scan support is deprecated\n");
-		iwlagn_hw_ops.hw_scan = NULL;
-	}
-
 	hw = iwl_alloc_all(cfg);
 	if (!hw) {
 		err = -ENOMEM;
@@ -3984,6 +3366,8 @@
 	priv = hw->priv;
 	/* At this point both hw and priv are allocated. */
 
+	priv->ucode_type = UCODE_SUBTYPE_NONE_LOADED;
+
 	/*
 	 * The default context is always valid,
 	 * more may be discovered when firmware
@@ -4116,16 +3500,15 @@
 	 */
 	iwl_write32(priv, CSR_RESET, CSR_RESET_REG_FLAG_NEVO_RESET);
 
-	iwl_hw_detect(priv);
+	hw_rev = iwl_hw_detect(priv);
 	IWL_INFO(priv, "Detected %s, REV=0x%X\n",
-		priv->cfg->name, priv->hw_rev);
+		priv->cfg->name, hw_rev);
 
 	/* We disable the RETRY_TIMEOUT register (0x41) to keep
 	 * PCI Tx retries from interfering with C3 CPU state */
 	pci_write_config_byte(pdev, PCI_CFG_RETRY_TIMEOUT, 0x00);
 
-	iwl_prepare_card_hw(priv);
-	if (!priv->hw_ready) {
+	if (iwl_prepare_card_hw(priv)) {
 		IWL_WARN(priv, "Failed, HW not ready\n");
 		goto out_iounmap;
 	}
@@ -4134,7 +3517,7 @@
 	 * 4. Read EEPROM
 	 *****************/
 	/* Read the EEPROM */
-	err = iwl_eeprom_init(priv);
+	err = iwl_eeprom_init(priv, hw_rev);
 	if (err) {
 		IWL_ERR(priv, "Unable to init EEPROM\n");
 		goto out_iounmap;
@@ -4186,10 +3569,9 @@
 
 	pci_enable_msi(priv->pci_dev);
 
-	if (priv->cfg->ops->lib->isr_ops.alloc)
-		priv->cfg->ops->lib->isr_ops.alloc(priv);
+	iwl_alloc_isr_ict(priv);
 
-	err = request_irq(priv->pci_dev->irq, priv->cfg->ops->lib->isr_ops.isr,
+	err = request_irq(priv->pci_dev->irq, iwl_isr_ict,
 			  IRQF_SHARED, DRV_NAME, priv);
 	if (err) {
 		IWL_ERR(priv, "Error allocating IRQ %d\n", priv->pci_dev->irq);
@@ -4198,6 +3580,7 @@
 
 	iwl_setup_deferred_work(priv);
 	iwl_setup_rx_handlers(priv);
+	iwl_testmode_init(priv);
 
 	/*********************************************
 	 * 8. Enable interrupts and read RFKILL state
@@ -4236,8 +3619,7 @@
 	destroy_workqueue(priv->workqueue);
 	priv->workqueue = NULL;
 	free_irq(priv->pci_dev->irq, priv);
-	if (priv->cfg->ops->lib->isr_ops.free)
-		priv->cfg->ops->lib->isr_ops.free(priv);
+	iwl_free_isr_ict(priv);
  out_disable_msi:
 	pci_disable_msi(priv->pci_dev);
 	iwl_uninit_drv(priv);
@@ -4278,22 +3660,15 @@
 	 */
 	set_bit(STATUS_EXIT_PENDING, &priv->status);
 
+	iwl_testmode_cleanup(priv);
 	iwl_leds_exit(priv);
 
 	if (priv->mac80211_registered) {
 		ieee80211_unregister_hw(priv->hw);
 		priv->mac80211_registered = 0;
-	} else {
-		iwl_down(priv);
 	}
 
-	/*
-	 * Make sure device is reset to low power before unloading driver.
-	 * This may be redundant with iwl_down(), but there are paths to
-	 * run iwl_down() without calling apm_ops.stop(), and there are
-	 * paths to avoid running iwl_down() at all before leaving driver.
-	 * This (inexpensive) call *makes sure* device is reset.
-	 */
+	/* Reset to low power before unloading driver. */
 	iwl_apm_stop(priv);
 
 	iwl_tt_exit(priv);
@@ -4335,8 +3710,7 @@
 
 	iwl_uninit_drv(priv);
 
-	if (priv->cfg->ops->lib->isr_ops.free)
-		priv->cfg->ops->lib->isr_ops.free(priv);
+	iwl_free_isr_ict(priv);
 
 	dev_kfree_skb(priv->beacon_skb);
 
@@ -4458,11 +3832,11 @@
 
 /* 6150 WiFi/WiMax Series */
 	{IWL_PCI_DEVICE(0x0885, 0x1305, iwl6150_bgn_cfg)},
-	{IWL_PCI_DEVICE(0x0885, 0x1306, iwl6150_bgn_cfg)},
+	{IWL_PCI_DEVICE(0x0885, 0x1307, iwl6150_bg_cfg)},
 	{IWL_PCI_DEVICE(0x0885, 0x1325, iwl6150_bgn_cfg)},
-	{IWL_PCI_DEVICE(0x0885, 0x1326, iwl6150_bgn_cfg)},
+	{IWL_PCI_DEVICE(0x0885, 0x1327, iwl6150_bg_cfg)},
 	{IWL_PCI_DEVICE(0x0886, 0x1315, iwl6150_bgn_cfg)},
-	{IWL_PCI_DEVICE(0x0886, 0x1316, iwl6150_bgn_cfg)},
+	{IWL_PCI_DEVICE(0x0886, 0x1317, iwl6150_bg_cfg)},
 
 /* 1000 Series WiFi */
 	{IWL_PCI_DEVICE(0x0083, 0x1205, iwl1000_bgn_cfg)},
@@ -4521,21 +3895,21 @@
 	{IWL_PCI_DEVICE(0x088F, 0x4266, iwl6035_2bg_cfg)},
 	{IWL_PCI_DEVICE(0x088E, 0x4466, iwl6035_2bg_cfg)},
 
-/* 200 Series */
-	{IWL_PCI_DEVICE(0x0894, 0x0022, iwl200_bgn_cfg)},
-	{IWL_PCI_DEVICE(0x0895, 0x0222, iwl200_bgn_cfg)},
-	{IWL_PCI_DEVICE(0x0894, 0x0422, iwl200_bgn_cfg)},
-	{IWL_PCI_DEVICE(0x0894, 0x0026, iwl200_bg_cfg)},
-	{IWL_PCI_DEVICE(0x0895, 0x0226, iwl200_bg_cfg)},
-	{IWL_PCI_DEVICE(0x0894, 0x0426, iwl200_bg_cfg)},
+/* 105 Series */
+	{IWL_PCI_DEVICE(0x0894, 0x0022, iwl105_bgn_cfg)},
+	{IWL_PCI_DEVICE(0x0895, 0x0222, iwl105_bgn_cfg)},
+	{IWL_PCI_DEVICE(0x0894, 0x0422, iwl105_bgn_cfg)},
+	{IWL_PCI_DEVICE(0x0894, 0x0026, iwl105_bg_cfg)},
+	{IWL_PCI_DEVICE(0x0895, 0x0226, iwl105_bg_cfg)},
+	{IWL_PCI_DEVICE(0x0894, 0x0426, iwl105_bg_cfg)},
 
-/* 230 Series */
-	{IWL_PCI_DEVICE(0x0892, 0x0062, iwl230_bgn_cfg)},
-	{IWL_PCI_DEVICE(0x0893, 0x0262, iwl230_bgn_cfg)},
-	{IWL_PCI_DEVICE(0x0892, 0x0462, iwl230_bgn_cfg)},
-	{IWL_PCI_DEVICE(0x0892, 0x0066, iwl230_bg_cfg)},
-	{IWL_PCI_DEVICE(0x0893, 0x0266, iwl230_bg_cfg)},
-	{IWL_PCI_DEVICE(0x0892, 0x0466, iwl230_bg_cfg)},
+/* 135 Series */
+	{IWL_PCI_DEVICE(0x0892, 0x0062, iwl135_bgn_cfg)},
+	{IWL_PCI_DEVICE(0x0893, 0x0262, iwl135_bgn_cfg)},
+	{IWL_PCI_DEVICE(0x0892, 0x0462, iwl135_bgn_cfg)},
+	{IWL_PCI_DEVICE(0x0892, 0x0066, iwl135_bg_cfg)},
+	{IWL_PCI_DEVICE(0x0893, 0x0266, iwl135_bg_cfg)},
+	{IWL_PCI_DEVICE(0x0892, 0x0466, iwl135_bg_cfg)},
 
 	{0}
 };
@@ -4585,43 +3959,21 @@
 module_init(iwl_init);
 
 #ifdef CONFIG_IWLWIFI_DEBUG
-module_param_named(debug50, iwl_debug_level, uint, S_IRUGO);
-MODULE_PARM_DESC(debug50, "50XX debug output mask (deprecated)");
 module_param_named(debug, iwl_debug_level, uint, S_IRUGO | S_IWUSR);
 MODULE_PARM_DESC(debug, "debug output mask");
 #endif
 
-module_param_named(swcrypto50, iwlagn_mod_params.sw_crypto, bool, S_IRUGO);
-MODULE_PARM_DESC(swcrypto50,
-		 "using crypto in software (default 0 [hardware]) (deprecated)");
 module_param_named(swcrypto, iwlagn_mod_params.sw_crypto, int, S_IRUGO);
 MODULE_PARM_DESC(swcrypto, "using crypto in software (default 0 [hardware])");
-module_param_named(queues_num50,
-		   iwlagn_mod_params.num_of_queues, int, S_IRUGO);
-MODULE_PARM_DESC(queues_num50,
-		 "number of hw queues in 50xx series (deprecated)");
 module_param_named(queues_num, iwlagn_mod_params.num_of_queues, int, S_IRUGO);
 MODULE_PARM_DESC(queues_num, "number of hw queues.");
-module_param_named(11n_disable50, iwlagn_mod_params.disable_11n, int, S_IRUGO);
-MODULE_PARM_DESC(11n_disable50, "disable 50XX 11n functionality (deprecated)");
 module_param_named(11n_disable, iwlagn_mod_params.disable_11n, int, S_IRUGO);
 MODULE_PARM_DESC(11n_disable, "disable 11n functionality");
-module_param_named(amsdu_size_8K50, iwlagn_mod_params.amsdu_size_8K,
-		   int, S_IRUGO);
-MODULE_PARM_DESC(amsdu_size_8K50,
-		 "enable 8K amsdu size in 50XX series (deprecated)");
 module_param_named(amsdu_size_8K, iwlagn_mod_params.amsdu_size_8K,
 		   int, S_IRUGO);
 MODULE_PARM_DESC(amsdu_size_8K, "enable 8K amsdu size");
-module_param_named(fw_restart50, iwlagn_mod_params.restart_fw, int, S_IRUGO);
-MODULE_PARM_DESC(fw_restart50,
-		 "restart firmware in case of error (deprecated)");
 module_param_named(fw_restart, iwlagn_mod_params.restart_fw, int, S_IRUGO);
 MODULE_PARM_DESC(fw_restart, "restart firmware in case of error");
-module_param_named(
-	disable_hw_scan, iwlagn_mod_params.disable_hw_scan, int, S_IRUGO);
-MODULE_PARM_DESC(disable_hw_scan,
-		 "disable hardware scanning (default 0) (deprecated)");
 
 module_param_named(ucode_alternative, iwlagn_wanted_ucode_alternative, int,
 		   S_IRUGO);
diff -druN linux-2.6.39-libre/drivers/net/wireless/iwlwifi/iwl-agn-calib.c linux-3.0-rc7-libre/drivers/net/wireless/iwlwifi/iwl-agn-calib.c
--- linux-2.6.39-libre/drivers/net/wireless/iwlwifi/iwl-agn-calib.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/iwlwifi/iwl-agn-calib.c	2011-07-11 19:51:52.000000000 -0400
@@ -5,7 +5,7 @@
  *
  * GPL LICENSE SUMMARY
  *
- * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2008 - 2011 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 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -87,14 +87,14 @@
 
 	struct iwl_host_cmd hcmd = {
 		.id = REPLY_PHY_CALIBRATION_CMD,
-		.flags = CMD_SIZE_HUGE,
 	};
 
 	for (i = 0; i < IWL_CALIB_MAX; i++) {
 		if ((BIT(i) & priv->hw_params.calib_init_cfg) &&
 		    priv->calib_results[i].buf) {
-			hcmd.len = priv->calib_results[i].buf_len;
-			hcmd.data = priv->calib_results[i].buf;
+			hcmd.len[0] = priv->calib_results[i].buf_len;
+			hcmd.data[0] = priv->calib_results[i].buf;
+			hcmd.dataflags[0] = IWL_HCMD_DFL_NOCOPY;
 			ret = iwl_send_cmd_sync(priv, &hcmd);
 			if (ret) {
 				IWL_ERR(priv, "Error %d iteration %d\n",
@@ -456,9 +456,9 @@
 	struct iwl_sensitivity_data *data = NULL;
 	struct iwl_host_cmd cmd_out = {
 		.id = SENSITIVITY_CMD,
-		.len = sizeof(struct iwl_sensitivity_cmd),
+		.len = { sizeof(struct iwl_sensitivity_cmd), },
 		.flags = CMD_ASYNC,
-		.data = &cmd,
+		.data = { &cmd, },
 	};
 
 	data = &(priv->sensitivity_data);
@@ -491,9 +491,9 @@
 	struct iwl_sensitivity_data *data = NULL;
 	struct iwl_host_cmd cmd_out = {
 		.id = SENSITIVITY_CMD,
-		.len = sizeof(struct iwl_enhance_sensitivity_cmd),
+		.len = { sizeof(struct iwl_enhance_sensitivity_cmd), },
 		.flags = CMD_ASYNC,
-		.data = &cmd,
+		.data = { &cmd, },
 	};
 
 	data = &(priv->sensitivity_data);
@@ -605,7 +605,7 @@
 	IWL_DEBUG_CALIB(priv, "<<return 0x%X\n", ret);
 }
 
-void iwl_sensitivity_calibration(struct iwl_priv *priv, void *resp)
+void iwl_sensitivity_calibration(struct iwl_priv *priv)
 {
 	u32 rx_enable_time;
 	u32 fa_cck;
@@ -631,16 +631,9 @@
 	}
 
 	spin_lock_irqsave(&priv->lock, flags);
-	if (iwl_bt_statistics(priv)) {
-		rx_info = &(((struct iwl_bt_notif_statistics *)resp)->
-			      rx.general.common);
-		ofdm = &(((struct iwl_bt_notif_statistics *)resp)->rx.ofdm);
-		cck = &(((struct iwl_bt_notif_statistics *)resp)->rx.cck);
-	} else {
-		rx_info = &(((struct iwl_notif_statistics *)resp)->rx.general);
-		ofdm = &(((struct iwl_notif_statistics *)resp)->rx.ofdm);
-		cck = &(((struct iwl_notif_statistics *)resp)->rx.cck);
-	}
+	rx_info = &priv->statistics.rx_non_phy;
+	ofdm = &priv->statistics.rx_ofdm;
+	cck = &priv->statistics.rx_cck;
 	if (rx_info->interference_data_flag != INTERFERENCE_DATA_AVAILABLE) {
 		IWL_DEBUG_CALIB(priv, "<< invalid data.\n");
 		spin_unlock_irqrestore(&priv->lock, flags);
@@ -824,8 +817,8 @@
 				find_first_chain(priv->cfg->valid_tx_ant);
 			data->disconn_array[first_chain] = 0;
 			active_chains |= BIT(first_chain);
-			IWL_DEBUG_CALIB(priv, "All Tx chains are disconnected \
-					W/A - declare %d as connected\n",
+			IWL_DEBUG_CALIB(priv,
+					"All Tx chains are disconnected W/A - declare %d as connected\n",
 					first_chain);
 			break;
 		}
@@ -851,7 +844,7 @@
  * 1)  Which antennas are connected.
  * 2)  Differential rx gain settings to balance the 3 receivers.
  */
-void iwl_chain_noise_calibration(struct iwl_priv *priv, void *stat_resp)
+void iwl_chain_noise_calibration(struct iwl_priv *priv)
 {
 	struct iwl_chain_noise_data *data = NULL;
 
@@ -896,13 +889,9 @@
 	}
 
 	spin_lock_irqsave(&priv->lock, flags);
-	if (iwl_bt_statistics(priv)) {
-		rx_info = &(((struct iwl_bt_notif_statistics *)stat_resp)->
-			      rx.general.common);
-	} else {
-		rx_info = &(((struct iwl_notif_statistics *)stat_resp)->
-			      rx.general);
-	}
+
+	rx_info = &priv->statistics.rx_non_phy;
+
 	if (rx_info->interference_data_flag != INTERFERENCE_DATA_AVAILABLE) {
 		IWL_DEBUG_CALIB(priv, " << Interference data unavailable\n");
 		spin_unlock_irqrestore(&priv->lock, flags);
@@ -911,19 +900,9 @@
 
 	rxon_band24 = !!(ctx->staging.flags & RXON_FLG_BAND_24G_MSK);
 	rxon_chnum = le16_to_cpu(ctx->staging.channel);
-	if (iwl_bt_statistics(priv)) {
-		stat_band24 = !!(((struct iwl_bt_notif_statistics *)
-				 stat_resp)->flag &
-				 STATISTICS_REPLY_FLG_BAND_24G_MSK);
-		stat_chnum = le32_to_cpu(((struct iwl_bt_notif_statistics *)
-					 stat_resp)->flag) >> 16;
-	} else {
-		stat_band24 = !!(((struct iwl_notif_statistics *)
-				 stat_resp)->flag &
-				 STATISTICS_REPLY_FLG_BAND_24G_MSK);
-		stat_chnum = le32_to_cpu(((struct iwl_notif_statistics *)
-					 stat_resp)->flag) >> 16;
-	}
+	stat_band24 =
+		!!(priv->statistics.flag & STATISTICS_REPLY_FLG_BAND_24G_MSK);
+	stat_chnum = le32_to_cpu(priv->statistics.flag) >> 16;
 
 	/* Make sure we accumulate data for just the associated channel
 	 *   (even if scanning). */
diff -druN linux-2.6.39-libre/drivers/net/wireless/iwlwifi/iwl-agn-calib.h linux-3.0-rc7-libre/drivers/net/wireless/iwlwifi/iwl-agn-calib.h
--- linux-2.6.39-libre/drivers/net/wireless/iwlwifi/iwl-agn-calib.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/iwlwifi/iwl-agn-calib.h	2011-07-11 19:51:52.000000000 -0400
@@ -5,7 +5,7 @@
  *
  * GPL LICENSE SUMMARY
  *
- * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2008 - 2011 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 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -66,8 +66,8 @@
 #include "iwl-core.h"
 #include "iwl-commands.h"
 
-void iwl_chain_noise_calibration(struct iwl_priv *priv, void *stat_resp);
-void iwl_sensitivity_calibration(struct iwl_priv *priv, void *resp);
+void iwl_chain_noise_calibration(struct iwl_priv *priv);
+void iwl_sensitivity_calibration(struct iwl_priv *priv);
 
 void iwl_init_sensitivity(struct iwl_priv *priv);
 void iwl_reset_run_time_calib(struct iwl_priv *priv);
diff -druN linux-2.6.39-libre/drivers/net/wireless/iwlwifi/iwl-agn-debugfs.c linux-3.0-rc7-libre/drivers/net/wireless/iwlwifi/iwl-agn-debugfs.c
--- linux-2.6.39-libre/drivers/net/wireless/iwlwifi/iwl-agn-debugfs.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/iwlwifi/iwl-agn-debugfs.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,1073 +0,0 @@
-/******************************************************************************
-*
-* GPL LICENSE SUMMARY
-*
-* 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
-* published by the Free Software Foundation.
-*
-* This program is distributed in the hope that it will be useful, but
-* WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-* General Public License for more details.
-*
-* You should have received a copy of the GNU General Public License
-* along with this program; if not, write to the Free Software
-* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
-* USA
-*
-* The full GNU General Public License is included in this distribution
-* in the file called LICENSE.GPL.
-*
-* Contact Information:
-*  Intel Linux Wireless <ilw@linux.intel.com>
-* Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
-*****************************************************************************/
-#include "iwl-agn.h"
-#include "iwl-agn-debugfs.h"
-
-static const char *fmt_value = "  %-30s %10u\n";
-static const char *fmt_hex   = "  %-30s       0x%02X\n";
-static const char *fmt_table = "  %-30s %10u  %10u  %10u  %10u\n";
-static const char *fmt_header =
-	"%-32s    current  cumulative       delta         max\n";
-
-static int iwl_statistics_flag(struct iwl_priv *priv, char *buf, int bufsz)
-{
-	int p = 0;
-	u32 flag;
-
-	if (iwl_bt_statistics(priv))
-		flag = le32_to_cpu(priv->_agn.statistics_bt.flag);
-	else
-		flag = le32_to_cpu(priv->_agn.statistics.flag);
-
-	p += scnprintf(buf + p, bufsz - p, "Statistics Flag(0x%X):\n", flag);
-	if (flag & UCODE_STATISTICS_CLEAR_MSK)
-		p += scnprintf(buf + p, bufsz - p,
-		"\tStatistics have been cleared\n");
-	p += scnprintf(buf + p, bufsz - p, "\tOperational Frequency: %s\n",
-		(flag & UCODE_STATISTICS_FREQUENCY_MSK)
-		? "2.4 GHz" : "5.2 GHz");
-	p += scnprintf(buf + p, bufsz - p, "\tTGj Narrow Band: %s\n",
-		(flag & UCODE_STATISTICS_NARROW_BAND_MSK)
-		 ? "enabled" : "disabled");
-
-	return p;
-}
-
-ssize_t iwl_ucode_rx_stats_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;
-	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, *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_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;
-
-	buf = kzalloc(bufsz, GFP_KERNEL);
-	if (!buf) {
-		IWL_ERR(priv, "Can not allocate Buffer\n");
-		return -ENOMEM;
-	}
-
-	/*
-	 * the statistic information display here is based on
-	 * the last statistics notification from uCode
-	 * might not reflect the current uCode activity
-	 */
-	if (iwl_bt_statistics(priv)) {
-		ofdm = &priv->_agn.statistics_bt.rx.ofdm;
-		cck = &priv->_agn.statistics_bt.rx.cck;
-		general = &priv->_agn.statistics_bt.rx.general.common;
-		ht = &priv->_agn.statistics_bt.rx.ofdm_ht;
-		accum_ofdm = &priv->_agn.accum_statistics_bt.rx.ofdm;
-		accum_cck = &priv->_agn.accum_statistics_bt.rx.cck;
-		accum_general =
-			&priv->_agn.accum_statistics_bt.rx.general.common;
-		accum_ht = &priv->_agn.accum_statistics_bt.rx.ofdm_ht;
-		delta_ofdm = &priv->_agn.delta_statistics_bt.rx.ofdm;
-		delta_cck = &priv->_agn.delta_statistics_bt.rx.cck;
-		delta_general =
-			&priv->_agn.delta_statistics_bt.rx.general.common;
-		delta_ht = &priv->_agn.delta_statistics_bt.rx.ofdm_ht;
-		max_ofdm = &priv->_agn.max_delta_bt.rx.ofdm;
-		max_cck = &priv->_agn.max_delta_bt.rx.cck;
-		max_general = &priv->_agn.max_delta_bt.rx.general.common;
-		max_ht = &priv->_agn.max_delta_bt.rx.ofdm_ht;
-	} else {
-		ofdm = &priv->_agn.statistics.rx.ofdm;
-		cck = &priv->_agn.statistics.rx.cck;
-		general = &priv->_agn.statistics.rx.general;
-		ht = &priv->_agn.statistics.rx.ofdm_ht;
-		accum_ofdm = &priv->_agn.accum_statistics.rx.ofdm;
-		accum_cck = &priv->_agn.accum_statistics.rx.cck;
-		accum_general = &priv->_agn.accum_statistics.rx.general;
-		accum_ht = &priv->_agn.accum_statistics.rx.ofdm_ht;
-		delta_ofdm = &priv->_agn.delta_statistics.rx.ofdm;
-		delta_cck = &priv->_agn.delta_statistics.rx.cck;
-		delta_general = &priv->_agn.delta_statistics.rx.general;
-		delta_ht = &priv->_agn.delta_statistics.rx.ofdm_ht;
-		max_ofdm = &priv->_agn.max_delta.rx.ofdm;
-		max_cck = &priv->_agn.max_delta.rx.cck;
-		max_general = &priv->_agn.max_delta.rx.general;
-		max_ht = &priv->_agn.max_delta.rx.ofdm_ht;
-	}
-
-	pos += iwl_statistics_flag(priv, buf, bufsz);
-	pos += scnprintf(buf + pos, bufsz - pos,
-			 fmt_header, "Statistics_Rx - OFDM:");
-	pos += scnprintf(buf + pos, bufsz - pos,
-			 fmt_table, "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,
-			 fmt_table, "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,
-			 fmt_table, "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,
-			 fmt_table, "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,
-			 fmt_table, "overrun_err:",
-			 le32_to_cpu(ofdm->overrun_err),
-			 accum_ofdm->overrun_err, delta_ofdm->overrun_err,
-			 max_ofdm->overrun_err);
-	pos += scnprintf(buf + pos, bufsz - pos,
-			 fmt_table, "early_overrun_err:",
-			 le32_to_cpu(ofdm->early_overrun_err),
-			 accum_ofdm->early_overrun_err,
-			 delta_ofdm->early_overrun_err,
-			 max_ofdm->early_overrun_err);
-	pos += scnprintf(buf + pos, bufsz - pos,
-			 fmt_table, "crc32_good:",
-			 le32_to_cpu(ofdm->crc32_good),
-			 accum_ofdm->crc32_good, delta_ofdm->crc32_good,
-			 max_ofdm->crc32_good);
-	pos += scnprintf(buf + pos, bufsz - pos,
-			 fmt_table, "false_alarm_cnt:",
-			 le32_to_cpu(ofdm->false_alarm_cnt),
-			 accum_ofdm->false_alarm_cnt,
-			 delta_ofdm->false_alarm_cnt,
-			 max_ofdm->false_alarm_cnt);
-	pos += scnprintf(buf + pos, bufsz - pos,
-			 fmt_table, "fina_sync_err_cnt:",
-			 le32_to_cpu(ofdm->fina_sync_err_cnt),
-			 accum_ofdm->fina_sync_err_cnt,
-			 delta_ofdm->fina_sync_err_cnt,
-			 max_ofdm->fina_sync_err_cnt);
-	pos += scnprintf(buf + pos, bufsz - pos,
-			 fmt_table, "sfd_timeout:",
-			 le32_to_cpu(ofdm->sfd_timeout),
-			 accum_ofdm->sfd_timeout, delta_ofdm->sfd_timeout,
-			 max_ofdm->sfd_timeout);
-	pos += scnprintf(buf + pos, bufsz - pos,
-			 fmt_table, "fina_timeout:",
-			 le32_to_cpu(ofdm->fina_timeout),
-			 accum_ofdm->fina_timeout, delta_ofdm->fina_timeout,
-			 max_ofdm->fina_timeout);
-	pos += scnprintf(buf + pos, bufsz - pos,
-			 fmt_table, "unresponded_rts:",
-			 le32_to_cpu(ofdm->unresponded_rts),
-			 accum_ofdm->unresponded_rts,
-			 delta_ofdm->unresponded_rts,
-			 max_ofdm->unresponded_rts);
-	pos += scnprintf(buf + pos, bufsz - pos,
-			 fmt_table, "rxe_frame_lmt_ovrun:",
-			 le32_to_cpu(ofdm->rxe_frame_limit_overrun),
-			 accum_ofdm->rxe_frame_limit_overrun,
-			 delta_ofdm->rxe_frame_limit_overrun,
-			 max_ofdm->rxe_frame_limit_overrun);
-	pos += scnprintf(buf + pos, bufsz - pos,
-			 fmt_table, "sent_ack_cnt:",
-			 le32_to_cpu(ofdm->sent_ack_cnt),
-			 accum_ofdm->sent_ack_cnt, delta_ofdm->sent_ack_cnt,
-			 max_ofdm->sent_ack_cnt);
-	pos += scnprintf(buf + pos, bufsz - pos,
-			 fmt_table, "sent_cts_cnt:",
-			 le32_to_cpu(ofdm->sent_cts_cnt),
-			 accum_ofdm->sent_cts_cnt, delta_ofdm->sent_cts_cnt,
-			 max_ofdm->sent_cts_cnt);
-	pos += scnprintf(buf + pos, bufsz - pos,
-			 fmt_table, "sent_ba_rsp_cnt:",
-			 le32_to_cpu(ofdm->sent_ba_rsp_cnt),
-			 accum_ofdm->sent_ba_rsp_cnt,
-			 delta_ofdm->sent_ba_rsp_cnt,
-			 max_ofdm->sent_ba_rsp_cnt);
-	pos += scnprintf(buf + pos, bufsz - pos,
-			 fmt_table, "dsp_self_kill:",
-			 le32_to_cpu(ofdm->dsp_self_kill),
-			 accum_ofdm->dsp_self_kill,
-			 delta_ofdm->dsp_self_kill,
-			 max_ofdm->dsp_self_kill);
-	pos += scnprintf(buf + pos, bufsz - pos,
-			 fmt_table, "mh_format_err:",
-			 le32_to_cpu(ofdm->mh_format_err),
-			 accum_ofdm->mh_format_err,
-			 delta_ofdm->mh_format_err,
-			 max_ofdm->mh_format_err);
-	pos += scnprintf(buf + pos, bufsz - pos,
-			 fmt_table, "re_acq_main_rssi_sum:",
-			 le32_to_cpu(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,
-			 fmt_header, "Statistics_Rx - CCK:");
-	pos += scnprintf(buf + pos, bufsz - pos,
-			 fmt_table, "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,
-			 fmt_table, "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,
-			 fmt_table, "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,
-			 fmt_table, "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,
-			 fmt_table, "overrun_err:",
-			 le32_to_cpu(cck->overrun_err),
-			 accum_cck->overrun_err, delta_cck->overrun_err,
-			 max_cck->overrun_err);
-	pos += scnprintf(buf + pos, bufsz - pos,
-			 fmt_table, "early_overrun_err:",
-			 le32_to_cpu(cck->early_overrun_err),
-			 accum_cck->early_overrun_err,
-			 delta_cck->early_overrun_err,
-			 max_cck->early_overrun_err);
-	pos += scnprintf(buf + pos, bufsz - pos,
-			 fmt_table, "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,
-			 fmt_table, "false_alarm_cnt:",
-			 le32_to_cpu(cck->false_alarm_cnt),
-			 accum_cck->false_alarm_cnt,
-			 delta_cck->false_alarm_cnt, max_cck->false_alarm_cnt);
-	pos += scnprintf(buf + pos, bufsz - pos,
-			 fmt_table, "fina_sync_err_cnt:",
-			 le32_to_cpu(cck->fina_sync_err_cnt),
-			 accum_cck->fina_sync_err_cnt,
-			 delta_cck->fina_sync_err_cnt,
-			 max_cck->fina_sync_err_cnt);
-	pos += scnprintf(buf + pos, bufsz - pos,
-			 fmt_table, "sfd_timeout:",
-			 le32_to_cpu(cck->sfd_timeout),
-			 accum_cck->sfd_timeout, delta_cck->sfd_timeout,
-			 max_cck->sfd_timeout);
-	pos += scnprintf(buf + pos, bufsz - pos,
-			 fmt_table, "fina_timeout:",
-			 le32_to_cpu(cck->fina_timeout),
-			 accum_cck->fina_timeout, delta_cck->fina_timeout,
-			 max_cck->fina_timeout);
-	pos += scnprintf(buf + pos, bufsz - pos,
-			 fmt_table, "unresponded_rts:",
-			 le32_to_cpu(cck->unresponded_rts),
-			 accum_cck->unresponded_rts, delta_cck->unresponded_rts,
-			 max_cck->unresponded_rts);
-	pos += scnprintf(buf + pos, bufsz - pos,
-			 fmt_table, "rxe_frame_lmt_ovrun:",
-			 le32_to_cpu(cck->rxe_frame_limit_overrun),
-			 accum_cck->rxe_frame_limit_overrun,
-			 delta_cck->rxe_frame_limit_overrun,
-			 max_cck->rxe_frame_limit_overrun);
-	pos += scnprintf(buf + pos, bufsz - pos,
-			 fmt_table, "sent_ack_cnt:",
-			 le32_to_cpu(cck->sent_ack_cnt),
-			 accum_cck->sent_ack_cnt, delta_cck->sent_ack_cnt,
-			 max_cck->sent_ack_cnt);
-	pos += scnprintf(buf + pos, bufsz - pos,
-			 fmt_table, "sent_cts_cnt:",
-			 le32_to_cpu(cck->sent_cts_cnt),
-			 accum_cck->sent_cts_cnt, delta_cck->sent_cts_cnt,
-			 max_cck->sent_cts_cnt);
-	pos += scnprintf(buf + pos, bufsz - pos,
-			 fmt_table, "sent_ba_rsp_cnt:",
-			 le32_to_cpu(cck->sent_ba_rsp_cnt),
-			 accum_cck->sent_ba_rsp_cnt,
-			 delta_cck->sent_ba_rsp_cnt,
-			 max_cck->sent_ba_rsp_cnt);
-	pos += scnprintf(buf + pos, bufsz - pos,
-			 fmt_table, "dsp_self_kill:",
-			 le32_to_cpu(cck->dsp_self_kill),
-			 accum_cck->dsp_self_kill, delta_cck->dsp_self_kill,
-			 max_cck->dsp_self_kill);
-	pos += scnprintf(buf + pos, bufsz - pos,
-			 fmt_table, "mh_format_err:",
-			 le32_to_cpu(cck->mh_format_err),
-			 accum_cck->mh_format_err, delta_cck->mh_format_err,
-			 max_cck->mh_format_err);
-	pos += scnprintf(buf + pos, bufsz - pos,
-			 fmt_table, "re_acq_main_rssi_sum:",
-			 le32_to_cpu(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,
-			 fmt_header, "Statistics_Rx - GENERAL:");
-	pos += scnprintf(buf + pos, bufsz - pos,
-			 fmt_table, "bogus_cts:",
-			 le32_to_cpu(general->bogus_cts),
-			 accum_general->bogus_cts, delta_general->bogus_cts,
-			 max_general->bogus_cts);
-	pos += scnprintf(buf + pos, bufsz - pos,
-			 fmt_table, "bogus_ack:",
-			 le32_to_cpu(general->bogus_ack),
-			 accum_general->bogus_ack, delta_general->bogus_ack,
-			 max_general->bogus_ack);
-	pos += scnprintf(buf + pos, bufsz - pos,
-			 fmt_table, "non_bssid_frames:",
-			 le32_to_cpu(general->non_bssid_frames),
-			 accum_general->non_bssid_frames,
-			 delta_general->non_bssid_frames,
-			 max_general->non_bssid_frames);
-	pos += scnprintf(buf + pos, bufsz - pos,
-			 fmt_table, "filtered_frames:",
-			 le32_to_cpu(general->filtered_frames),
-			 accum_general->filtered_frames,
-			 delta_general->filtered_frames,
-			 max_general->filtered_frames);
-	pos += scnprintf(buf + pos, bufsz - pos,
-			 fmt_table, "non_channel_beacons:",
-			 le32_to_cpu(general->non_channel_beacons),
-			 accum_general->non_channel_beacons,
-			 delta_general->non_channel_beacons,
-			 max_general->non_channel_beacons);
-	pos += scnprintf(buf + pos, bufsz - pos,
-			 fmt_table, "channel_beacons:",
-			 le32_to_cpu(general->channel_beacons),
-			 accum_general->channel_beacons,
-			 delta_general->channel_beacons,
-			 max_general->channel_beacons);
-	pos += scnprintf(buf + pos, bufsz - pos,
-			 fmt_table, "num_missed_bcon:",
-			 le32_to_cpu(general->num_missed_bcon),
-			 accum_general->num_missed_bcon,
-			 delta_general->num_missed_bcon,
-			 max_general->num_missed_bcon);
-	pos += scnprintf(buf + pos, bufsz - pos,
-			 fmt_table, "adc_rx_saturation_time:",
-			 le32_to_cpu(general->adc_rx_saturation_time),
-			 accum_general->adc_rx_saturation_time,
-			 delta_general->adc_rx_saturation_time,
-			 max_general->adc_rx_saturation_time);
-	pos += scnprintf(buf + pos, bufsz - pos,
-			 fmt_table, "ina_detect_search_tm:",
-			 le32_to_cpu(general->ina_detection_search_time),
-			 accum_general->ina_detection_search_time,
-			 delta_general->ina_detection_search_time,
-			 max_general->ina_detection_search_time);
-	pos += scnprintf(buf + pos, bufsz - pos,
-			 fmt_table, "beacon_silence_rssi_a:",
-			 le32_to_cpu(general->beacon_silence_rssi_a),
-			 accum_general->beacon_silence_rssi_a,
-			 delta_general->beacon_silence_rssi_a,
-			 max_general->beacon_silence_rssi_a);
-	pos += scnprintf(buf + pos, bufsz - pos,
-			 fmt_table, "beacon_silence_rssi_b:",
-			 le32_to_cpu(general->beacon_silence_rssi_b),
-			 accum_general->beacon_silence_rssi_b,
-			 delta_general->beacon_silence_rssi_b,
-			 max_general->beacon_silence_rssi_b);
-	pos += scnprintf(buf + pos, bufsz - pos,
-			 fmt_table, "beacon_silence_rssi_c:",
-			 le32_to_cpu(general->beacon_silence_rssi_c),
-			 accum_general->beacon_silence_rssi_c,
-			 delta_general->beacon_silence_rssi_c,
-			 max_general->beacon_silence_rssi_c);
-	pos += scnprintf(buf + pos, bufsz - pos,
-			 fmt_table, "interference_data_flag:",
-			 le32_to_cpu(general->interference_data_flag),
-			 accum_general->interference_data_flag,
-			 delta_general->interference_data_flag,
-			 max_general->interference_data_flag);
-	pos += scnprintf(buf + pos, bufsz - pos,
-			 fmt_table, "channel_load:",
-			 le32_to_cpu(general->channel_load),
-			 accum_general->channel_load,
-			 delta_general->channel_load,
-			 max_general->channel_load);
-	pos += scnprintf(buf + pos, bufsz - pos,
-			 fmt_table, "dsp_false_alarms:",
-			 le32_to_cpu(general->dsp_false_alarms),
-			 accum_general->dsp_false_alarms,
-			 delta_general->dsp_false_alarms,
-			 max_general->dsp_false_alarms);
-	pos += scnprintf(buf + pos, bufsz - pos,
-			 fmt_table, "beacon_rssi_a:",
-			 le32_to_cpu(general->beacon_rssi_a),
-			 accum_general->beacon_rssi_a,
-			 delta_general->beacon_rssi_a,
-			 max_general->beacon_rssi_a);
-	pos += scnprintf(buf + pos, bufsz - pos,
-			 fmt_table, "beacon_rssi_b:",
-			 le32_to_cpu(general->beacon_rssi_b),
-			 accum_general->beacon_rssi_b,
-			 delta_general->beacon_rssi_b,
-			 max_general->beacon_rssi_b);
-	pos += scnprintf(buf + pos, bufsz - pos,
-			 fmt_table, "beacon_rssi_c:",
-			 le32_to_cpu(general->beacon_rssi_c),
-			 accum_general->beacon_rssi_c,
-			 delta_general->beacon_rssi_c,
-			 max_general->beacon_rssi_c);
-	pos += scnprintf(buf + pos, bufsz - pos,
-			 fmt_table, "beacon_energy_a:",
-			 le32_to_cpu(general->beacon_energy_a),
-			 accum_general->beacon_energy_a,
-			 delta_general->beacon_energy_a,
-			 max_general->beacon_energy_a);
-	pos += scnprintf(buf + pos, bufsz - pos,
-			 fmt_table, "beacon_energy_b:",
-			 le32_to_cpu(general->beacon_energy_b),
-			 accum_general->beacon_energy_b,
-			 delta_general->beacon_energy_b,
-			 max_general->beacon_energy_b);
-	pos += scnprintf(buf + pos, bufsz - pos,
-			 fmt_table, "beacon_energy_c:",
-			 le32_to_cpu(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,
-			 fmt_header, "Statistics_Rx - OFDM_HT:");
-	pos += scnprintf(buf + pos, bufsz - pos,
-			 fmt_table, "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,
-			 fmt_table, "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,
-			 fmt_table, "early_overrun_err:",
-			 le32_to_cpu(ht->early_overrun_err),
-			 accum_ht->early_overrun_err,
-			 delta_ht->early_overrun_err,
-			 max_ht->early_overrun_err);
-	pos += scnprintf(buf + pos, bufsz - pos,
-			 fmt_table, "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,
-			 fmt_table, "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,
-			 fmt_table, "mh_format_err:",
-			 le32_to_cpu(ht->mh_format_err),
-			 accum_ht->mh_format_err,
-			 delta_ht->mh_format_err, max_ht->mh_format_err);
-	pos += scnprintf(buf + pos, bufsz - pos,
-			 fmt_table, "agg_crc32_good:",
-			 le32_to_cpu(ht->agg_crc32_good),
-			 accum_ht->agg_crc32_good,
-			 delta_ht->agg_crc32_good, max_ht->agg_crc32_good);
-	pos += scnprintf(buf + pos, bufsz - pos,
-			 fmt_table, "agg_mpdu_cnt:",
-			 le32_to_cpu(ht->agg_mpdu_cnt),
-			 accum_ht->agg_mpdu_cnt,
-			 delta_ht->agg_mpdu_cnt, max_ht->agg_mpdu_cnt);
-	pos += scnprintf(buf + pos, bufsz - pos,
-			 fmt_table, "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,
-			 fmt_table, "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);
-	return ret;
-}
-
-ssize_t iwl_ucode_tx_stats_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;
-	int bufsz = (sizeof(struct statistics_tx) * 48) + 250;
-	ssize_t ret;
-	struct statistics_tx *tx, *accum_tx, *delta_tx, *max_tx;
-
-	if (!iwl_is_alive(priv))
-		return -EAGAIN;
-
-	buf = kzalloc(bufsz, GFP_KERNEL);
-	if (!buf) {
-		IWL_ERR(priv, "Can not allocate Buffer\n");
-		return -ENOMEM;
-	}
-
-	/* the statistic information display here is based on
-	  * the last statistics notification from uCode
-	  * might not reflect the current uCode activity
-	  */
-	if (iwl_bt_statistics(priv)) {
-		tx = &priv->_agn.statistics_bt.tx;
-		accum_tx = &priv->_agn.accum_statistics_bt.tx;
-		delta_tx = &priv->_agn.delta_statistics_bt.tx;
-		max_tx = &priv->_agn.max_delta_bt.tx;
-	} else {
-		tx = &priv->_agn.statistics.tx;
-		accum_tx = &priv->_agn.accum_statistics.tx;
-		delta_tx = &priv->_agn.delta_statistics.tx;
-		max_tx = &priv->_agn.max_delta.tx;
-	}
-
-	pos += iwl_statistics_flag(priv, buf, bufsz);
-	pos += scnprintf(buf + pos, bufsz - pos,
-			 fmt_header, "Statistics_Tx:");
-	pos += scnprintf(buf + pos, bufsz - pos,
-			 fmt_table, "preamble:",
-			 le32_to_cpu(tx->preamble_cnt),
-			 accum_tx->preamble_cnt,
-			 delta_tx->preamble_cnt, max_tx->preamble_cnt);
-	pos += scnprintf(buf + pos, bufsz - pos,
-			 fmt_table, "rx_detected_cnt:",
-			 le32_to_cpu(tx->rx_detected_cnt),
-			 accum_tx->rx_detected_cnt,
-			 delta_tx->rx_detected_cnt, max_tx->rx_detected_cnt);
-	pos += scnprintf(buf + pos, bufsz - pos,
-			 fmt_table, "bt_prio_defer_cnt:",
-			 le32_to_cpu(tx->bt_prio_defer_cnt),
-			 accum_tx->bt_prio_defer_cnt,
-			 delta_tx->bt_prio_defer_cnt,
-			 max_tx->bt_prio_defer_cnt);
-	pos += scnprintf(buf + pos, bufsz - pos,
-			 fmt_table, "bt_prio_kill_cnt:",
-			 le32_to_cpu(tx->bt_prio_kill_cnt),
-			 accum_tx->bt_prio_kill_cnt,
-			 delta_tx->bt_prio_kill_cnt,
-			 max_tx->bt_prio_kill_cnt);
-	pos += scnprintf(buf + pos, bufsz - pos,
-			 fmt_table, "few_bytes_cnt:",
-			 le32_to_cpu(tx->few_bytes_cnt),
-			 accum_tx->few_bytes_cnt,
-			 delta_tx->few_bytes_cnt, max_tx->few_bytes_cnt);
-	pos += scnprintf(buf + pos, bufsz - pos,
-			 fmt_table, "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,
-			 fmt_table, "ack_timeout:",
-			 le32_to_cpu(tx->ack_timeout),
-			 accum_tx->ack_timeout,
-			 delta_tx->ack_timeout, max_tx->ack_timeout);
-	pos += scnprintf(buf + pos, bufsz - pos,
-			 fmt_table, "expected_ack_cnt:",
-			 le32_to_cpu(tx->expected_ack_cnt),
-			 accum_tx->expected_ack_cnt,
-			 delta_tx->expected_ack_cnt,
-			 max_tx->expected_ack_cnt);
-	pos += scnprintf(buf + pos, bufsz - pos,
-			 fmt_table, "actual_ack_cnt:",
-			 le32_to_cpu(tx->actual_ack_cnt),
-			 accum_tx->actual_ack_cnt,
-			 delta_tx->actual_ack_cnt,
-			 max_tx->actual_ack_cnt);
-	pos += scnprintf(buf + pos, bufsz - pos,
-			 fmt_table, "dump_msdu_cnt:",
-			 le32_to_cpu(tx->dump_msdu_cnt),
-			 accum_tx->dump_msdu_cnt,
-			 delta_tx->dump_msdu_cnt,
-			 max_tx->dump_msdu_cnt);
-	pos += scnprintf(buf + pos, bufsz - pos,
-			 fmt_table, "abort_nxt_frame_mismatch:",
-			 le32_to_cpu(tx->burst_abort_next_frame_mismatch_cnt),
-			 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,
-			 fmt_table, "abort_missing_nxt_frame:",
-			 le32_to_cpu(tx->burst_abort_missing_next_frame_cnt),
-			 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,
-			 fmt_table, "cts_timeout_collision:",
-			 le32_to_cpu(tx->cts_timeout_collision),
-			 accum_tx->cts_timeout_collision,
-			 delta_tx->cts_timeout_collision,
-			 max_tx->cts_timeout_collision);
-	pos += scnprintf(buf + pos, bufsz - pos,
-			 fmt_table, "ack_ba_timeout_collision:",
-			 le32_to_cpu(tx->ack_or_ba_timeout_collision),
-			 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,
-			 fmt_table, "agg ba_timeout:",
-			 le32_to_cpu(tx->agg.ba_timeout),
-			 accum_tx->agg.ba_timeout,
-			 delta_tx->agg.ba_timeout,
-			 max_tx->agg.ba_timeout);
-	pos += scnprintf(buf + pos, bufsz - pos,
-			 fmt_table, "agg ba_resched_frames:",
-			 le32_to_cpu(tx->agg.ba_reschedule_frames),
-			 accum_tx->agg.ba_reschedule_frames,
-			 delta_tx->agg.ba_reschedule_frames,
-			 max_tx->agg.ba_reschedule_frames);
-	pos += scnprintf(buf + pos, bufsz - pos,
-			 fmt_table, "agg scd_query_agg_frame:",
-			 le32_to_cpu(tx->agg.scd_query_agg_frame_cnt),
-			 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,
-			 fmt_table, "agg scd_query_no_agg:",
-			 le32_to_cpu(tx->agg.scd_query_no_agg),
-			 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,
-			 fmt_table, "agg scd_query_agg:",
-			 le32_to_cpu(tx->agg.scd_query_agg),
-			 accum_tx->agg.scd_query_agg,
-			 delta_tx->agg.scd_query_agg,
-			 max_tx->agg.scd_query_agg);
-	pos += scnprintf(buf + pos, bufsz - pos,
-			 fmt_table, "agg scd_query_mismatch:",
-			 le32_to_cpu(tx->agg.scd_query_mismatch),
-			 accum_tx->agg.scd_query_mismatch,
-			 delta_tx->agg.scd_query_mismatch,
-			 max_tx->agg.scd_query_mismatch);
-	pos += scnprintf(buf + pos, bufsz - pos,
-			 fmt_table, "agg frame_not_ready:",
-			 le32_to_cpu(tx->agg.frame_not_ready),
-			 accum_tx->agg.frame_not_ready,
-			 delta_tx->agg.frame_not_ready,
-			 max_tx->agg.frame_not_ready);
-	pos += scnprintf(buf + pos, bufsz - pos,
-			 fmt_table, "agg underrun:",
-			 le32_to_cpu(tx->agg.underrun),
-			 accum_tx->agg.underrun,
-			 delta_tx->agg.underrun, max_tx->agg.underrun);
-	pos += scnprintf(buf + pos, bufsz - pos,
-			 fmt_table, "agg bt_prio_kill:",
-			 le32_to_cpu(tx->agg.bt_prio_kill),
-			 accum_tx->agg.bt_prio_kill,
-			 delta_tx->agg.bt_prio_kill,
-			 max_tx->agg.bt_prio_kill);
-	pos += scnprintf(buf + pos, bufsz - pos,
-			 fmt_table, "agg rx_ba_rsp_cnt:",
-			 le32_to_cpu(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);
-
-	if (tx->tx_power.ant_a || tx->tx_power.ant_b || tx->tx_power.ant_c) {
-		pos += scnprintf(buf + pos, bufsz - pos,
-			"tx power: (1/2 dB step)\n");
-		if ((priv->cfg->valid_tx_ant & ANT_A) && tx->tx_power.ant_a)
-			pos += scnprintf(buf + pos, bufsz - pos,
-					fmt_hex, "antenna A:",
-					tx->tx_power.ant_a);
-		if ((priv->cfg->valid_tx_ant & ANT_B) && tx->tx_power.ant_b)
-			pos += scnprintf(buf + pos, bufsz - pos,
-					fmt_hex, "antenna B:",
-					tx->tx_power.ant_b);
-		if ((priv->cfg->valid_tx_ant & ANT_C) && tx->tx_power.ant_c)
-			pos += scnprintf(buf + pos, bufsz - pos,
-					fmt_hex, "antenna C:",
-					tx->tx_power.ant_c);
-	}
-	ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
-	kfree(buf);
-	return ret;
-}
-
-ssize_t iwl_ucode_general_stats_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;
-	int bufsz = sizeof(struct statistics_general) * 10 + 300;
-	ssize_t ret;
-	struct statistics_general_common *general, *accum_general;
-	struct statistics_general_common *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;
-
-	buf = kzalloc(bufsz, GFP_KERNEL);
-	if (!buf) {
-		IWL_ERR(priv, "Can not allocate Buffer\n");
-		return -ENOMEM;
-	}
-
-	/* the statistic information display here is based on
-	  * the last statistics notification from uCode
-	  * might not reflect the current uCode activity
-	  */
-	if (iwl_bt_statistics(priv)) {
-		general = &priv->_agn.statistics_bt.general.common;
-		dbg = &priv->_agn.statistics_bt.general.common.dbg;
-		div = &priv->_agn.statistics_bt.general.common.div;
-		accum_general = &priv->_agn.accum_statistics_bt.general.common;
-		accum_dbg = &priv->_agn.accum_statistics_bt.general.common.dbg;
-		accum_div = &priv->_agn.accum_statistics_bt.general.common.div;
-		delta_general = &priv->_agn.delta_statistics_bt.general.common;
-		max_general = &priv->_agn.max_delta_bt.general.common;
-		delta_dbg = &priv->_agn.delta_statistics_bt.general.common.dbg;
-		max_dbg = &priv->_agn.max_delta_bt.general.common.dbg;
-		delta_div = &priv->_agn.delta_statistics_bt.general.common.div;
-		max_div = &priv->_agn.max_delta_bt.general.common.div;
-	} else {
-		general = &priv->_agn.statistics.general.common;
-		dbg = &priv->_agn.statistics.general.common.dbg;
-		div = &priv->_agn.statistics.general.common.div;
-		accum_general = &priv->_agn.accum_statistics.general.common;
-		accum_dbg = &priv->_agn.accum_statistics.general.common.dbg;
-		accum_div = &priv->_agn.accum_statistics.general.common.div;
-		delta_general = &priv->_agn.delta_statistics.general.common;
-		max_general = &priv->_agn.max_delta.general.common;
-		delta_dbg = &priv->_agn.delta_statistics.general.common.dbg;
-		max_dbg = &priv->_agn.max_delta.general.common.dbg;
-		delta_div = &priv->_agn.delta_statistics.general.common.div;
-		max_div = &priv->_agn.max_delta.general.common.div;
-	}
-
-	pos += iwl_statistics_flag(priv, buf, bufsz);
-	pos += scnprintf(buf + pos, bufsz - pos,
-			 fmt_header, "Statistics_General:");
-	pos += scnprintf(buf + pos, bufsz - pos,
-			 fmt_value, "temperature:",
-			 le32_to_cpu(general->temperature));
-	pos += scnprintf(buf + pos, bufsz - pos,
-			 fmt_value, "temperature_m:",
-			 le32_to_cpu(general->temperature_m));
-	pos += scnprintf(buf + pos, bufsz - pos,
-			 fmt_value, "ttl_timestamp:",
-			 le32_to_cpu(general->ttl_timestamp));
-	pos += scnprintf(buf + pos, bufsz - pos,
-			 fmt_table, "burst_check:",
-			 le32_to_cpu(dbg->burst_check),
-			 accum_dbg->burst_check,
-			 delta_dbg->burst_check, max_dbg->burst_check);
-	pos += scnprintf(buf + pos, bufsz - pos,
-			 fmt_table, "burst_count:",
-			 le32_to_cpu(dbg->burst_count),
-			 accum_dbg->burst_count,
-			 delta_dbg->burst_count, max_dbg->burst_count);
-	pos += scnprintf(buf + pos, bufsz - pos,
-			 fmt_table, "wait_for_silence_timeout_count:",
-			 le32_to_cpu(dbg->wait_for_silence_timeout_cnt),
-			 accum_dbg->wait_for_silence_timeout_cnt,
-			 delta_dbg->wait_for_silence_timeout_cnt,
-			 max_dbg->wait_for_silence_timeout_cnt);
-	pos += scnprintf(buf + pos, bufsz - pos,
-			 fmt_table, "sleep_time:",
-			 le32_to_cpu(general->sleep_time),
-			 accum_general->sleep_time,
-			 delta_general->sleep_time, max_general->sleep_time);
-	pos += scnprintf(buf + pos, bufsz - pos,
-			 fmt_table, "slots_out:",
-			 le32_to_cpu(general->slots_out),
-			 accum_general->slots_out,
-			 delta_general->slots_out, max_general->slots_out);
-	pos += scnprintf(buf + pos, bufsz - pos,
-			 fmt_table, "slots_idle:",
-			 le32_to_cpu(general->slots_idle),
-			 accum_general->slots_idle,
-			 delta_general->slots_idle, max_general->slots_idle);
-	pos += scnprintf(buf + pos, bufsz - pos,
-			 fmt_table, "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,
-			 fmt_table, "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,
-			 fmt_table, "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,
-			 fmt_table, "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,
-			 fmt_table, "rx_enable_counter:",
-			 le32_to_cpu(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,
-			 fmt_table, "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;
-}
-
-ssize_t iwl_ucode_bt_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;
-	int pos = 0;
-	char *buf;
-	int bufsz = (sizeof(struct statistics_bt_activity) * 24) + 200;
-	ssize_t ret;
-	struct statistics_bt_activity *bt, *accum_bt;
-
-	if (!iwl_is_alive(priv))
-		return -EAGAIN;
-
-	if (!priv->bt_enable_flag)
-		return -EINVAL;
-
-	/* 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");
-		return -ENOMEM;
-	}
-
-	/*
-	 * the statistic information display here is based on
-	 * the last statistics notification from uCode
-	 * might not reflect the current uCode activity
-	 */
-	bt = &priv->_agn.statistics_bt.general.activity;
-	accum_bt = &priv->_agn.accum_statistics_bt.general.activity;
-
-	pos += iwl_statistics_flag(priv, buf, bufsz);
-	pos += scnprintf(buf + pos, bufsz - pos, "Statistics_BT:\n");
-	pos += scnprintf(buf + pos, bufsz - pos,
-			"\t\t\tcurrent\t\t\taccumulative\n");
-	pos += scnprintf(buf + pos, bufsz - pos,
-			 "hi_priority_tx_req_cnt:\t\t%u\t\t\t%u\n",
-			 le32_to_cpu(bt->hi_priority_tx_req_cnt),
-			 accum_bt->hi_priority_tx_req_cnt);
-	pos += scnprintf(buf + pos, bufsz - pos,
-			 "hi_priority_tx_denied_cnt:\t%u\t\t\t%u\n",
-			 le32_to_cpu(bt->hi_priority_tx_denied_cnt),
-			 accum_bt->hi_priority_tx_denied_cnt);
-	pos += scnprintf(buf + pos, bufsz - pos,
-			 "lo_priority_tx_req_cnt:\t\t%u\t\t\t%u\n",
-			 le32_to_cpu(bt->lo_priority_tx_req_cnt),
-			 accum_bt->lo_priority_tx_req_cnt);
-	pos += scnprintf(buf + pos, bufsz - pos,
-			 "lo_priority_tx_denied_cnt:\t%u\t\t\t%u\n",
-			 le32_to_cpu(bt->lo_priority_tx_denied_cnt),
-			 accum_bt->lo_priority_tx_denied_cnt);
-	pos += scnprintf(buf + pos, bufsz - pos,
-			 "hi_priority_rx_req_cnt:\t\t%u\t\t\t%u\n",
-			 le32_to_cpu(bt->hi_priority_rx_req_cnt),
-			 accum_bt->hi_priority_rx_req_cnt);
-	pos += scnprintf(buf + pos, bufsz - pos,
-			 "hi_priority_rx_denied_cnt:\t%u\t\t\t%u\n",
-			 le32_to_cpu(bt->hi_priority_rx_denied_cnt),
-			 accum_bt->hi_priority_rx_denied_cnt);
-	pos += scnprintf(buf + pos, bufsz - pos,
-			 "lo_priority_rx_req_cnt:\t\t%u\t\t\t%u\n",
-			 le32_to_cpu(bt->lo_priority_rx_req_cnt),
-			 accum_bt->lo_priority_rx_req_cnt);
-	pos += scnprintf(buf + pos, bufsz - pos,
-			 "lo_priority_rx_denied_cnt:\t%u\t\t\t%u\n",
-			 le32_to_cpu(bt->lo_priority_rx_denied_cnt),
-			 accum_bt->lo_priority_rx_denied_cnt);
-
-	pos += scnprintf(buf + pos, bufsz - pos,
-			 "(rx)num_bt_kills:\t\t%u\t\t\t%u\n",
-			 le32_to_cpu(priv->_agn.statistics_bt.rx.
-				general.num_bt_kills),
-			 priv->_agn.accum_statistics_bt.rx.
-				general.num_bt_kills);
-
-	ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
-	kfree(buf);
-	return ret;
-}
-
-ssize_t iwl_reply_tx_error_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;
-	int bufsz = (sizeof(struct reply_tx_error_statistics) * 24) +
-		(sizeof(struct reply_agg_tx_error_statistics) * 24) + 200;
-	ssize_t ret;
-
-	if (!iwl_is_alive(priv))
-		return -EAGAIN;
-
-	buf = kzalloc(bufsz, GFP_KERNEL);
-	if (!buf) {
-		IWL_ERR(priv, "Can not allocate Buffer\n");
-		return -ENOMEM;
-	}
-
-	pos += scnprintf(buf + pos, bufsz - pos, "Statistics_TX_Error:\n");
-	pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t\t%u\n",
-			 iwl_get_tx_fail_reason(TX_STATUS_POSTPONE_DELAY),
-			 priv->_agn.reply_tx_stats.pp_delay);
-	pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
-			 iwl_get_tx_fail_reason(TX_STATUS_POSTPONE_FEW_BYTES),
-			 priv->_agn.reply_tx_stats.pp_few_bytes);
-	pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
-			 iwl_get_tx_fail_reason(TX_STATUS_POSTPONE_BT_PRIO),
-			 priv->_agn.reply_tx_stats.pp_bt_prio);
-	pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
-			 iwl_get_tx_fail_reason(TX_STATUS_POSTPONE_QUIET_PERIOD),
-			 priv->_agn.reply_tx_stats.pp_quiet_period);
-	pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
-			 iwl_get_tx_fail_reason(TX_STATUS_POSTPONE_CALC_TTAK),
-			 priv->_agn.reply_tx_stats.pp_calc_ttak);
-	pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t%u\n",
-			 iwl_get_tx_fail_reason(
-				TX_STATUS_FAIL_INTERNAL_CROSSED_RETRY),
-			 priv->_agn.reply_tx_stats.int_crossed_retry);
-	pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
-			 iwl_get_tx_fail_reason(TX_STATUS_FAIL_SHORT_LIMIT),
-			 priv->_agn.reply_tx_stats.short_limit);
-	pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
-			 iwl_get_tx_fail_reason(TX_STATUS_FAIL_LONG_LIMIT),
-			 priv->_agn.reply_tx_stats.long_limit);
-	pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
-			 iwl_get_tx_fail_reason(TX_STATUS_FAIL_FIFO_UNDERRUN),
-			 priv->_agn.reply_tx_stats.fifo_underrun);
-	pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
-			 iwl_get_tx_fail_reason(TX_STATUS_FAIL_DRAIN_FLOW),
-			 priv->_agn.reply_tx_stats.drain_flow);
-	pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
-			 iwl_get_tx_fail_reason(TX_STATUS_FAIL_RFKILL_FLUSH),
-			 priv->_agn.reply_tx_stats.rfkill_flush);
-	pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
-			 iwl_get_tx_fail_reason(TX_STATUS_FAIL_LIFE_EXPIRE),
-			 priv->_agn.reply_tx_stats.life_expire);
-	pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
-			 iwl_get_tx_fail_reason(TX_STATUS_FAIL_DEST_PS),
-			 priv->_agn.reply_tx_stats.dest_ps);
-	pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
-			 iwl_get_tx_fail_reason(TX_STATUS_FAIL_HOST_ABORTED),
-			 priv->_agn.reply_tx_stats.host_abort);
-	pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
-			 iwl_get_tx_fail_reason(TX_STATUS_FAIL_BT_RETRY),
-			 priv->_agn.reply_tx_stats.pp_delay);
-	pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
-			 iwl_get_tx_fail_reason(TX_STATUS_FAIL_STA_INVALID),
-			 priv->_agn.reply_tx_stats.sta_invalid);
-	pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
-			 iwl_get_tx_fail_reason(TX_STATUS_FAIL_FRAG_DROPPED),
-			 priv->_agn.reply_tx_stats.frag_drop);
-	pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
-			 iwl_get_tx_fail_reason(TX_STATUS_FAIL_TID_DISABLE),
-			 priv->_agn.reply_tx_stats.tid_disable);
-	pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
-			 iwl_get_tx_fail_reason(TX_STATUS_FAIL_FIFO_FLUSHED),
-			 priv->_agn.reply_tx_stats.fifo_flush);
-	pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t%u\n",
-			 iwl_get_tx_fail_reason(
-				TX_STATUS_FAIL_INSUFFICIENT_CF_POLL),
-			 priv->_agn.reply_tx_stats.insuff_cf_poll);
-	pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
-			 iwl_get_tx_fail_reason(TX_STATUS_FAIL_PASSIVE_NO_RX),
-			 priv->_agn.reply_tx_stats.fail_hw_drop);
-	pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t%u\n",
-			 iwl_get_tx_fail_reason(
-				TX_STATUS_FAIL_NO_BEACON_ON_RADAR),
-			 priv->_agn.reply_tx_stats.sta_color_mismatch);
-	pos += scnprintf(buf + pos, bufsz - pos, "UNKNOWN:\t\t\t%u\n",
-			 priv->_agn.reply_tx_stats.unknown);
-
-	pos += scnprintf(buf + pos, bufsz - pos,
-			 "\nStatistics_Agg_TX_Error:\n");
-
-	pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
-			 iwl_get_agg_tx_fail_reason(AGG_TX_STATE_UNDERRUN_MSK),
-			 priv->_agn.reply_agg_tx_stats.underrun);
-	pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
-			 iwl_get_agg_tx_fail_reason(AGG_TX_STATE_BT_PRIO_MSK),
-			 priv->_agn.reply_agg_tx_stats.bt_prio);
-	pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
-			 iwl_get_agg_tx_fail_reason(AGG_TX_STATE_FEW_BYTES_MSK),
-			 priv->_agn.reply_agg_tx_stats.few_bytes);
-	pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
-			 iwl_get_agg_tx_fail_reason(AGG_TX_STATE_ABORT_MSK),
-			 priv->_agn.reply_agg_tx_stats.abort);
-	pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t%u\n",
-			 iwl_get_agg_tx_fail_reason(
-				AGG_TX_STATE_LAST_SENT_TTL_MSK),
-			 priv->_agn.reply_agg_tx_stats.last_sent_ttl);
-	pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t%u\n",
-			 iwl_get_agg_tx_fail_reason(
-				AGG_TX_STATE_LAST_SENT_TRY_CNT_MSK),
-			 priv->_agn.reply_agg_tx_stats.last_sent_try);
-	pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t%u\n",
-			 iwl_get_agg_tx_fail_reason(
-				AGG_TX_STATE_LAST_SENT_BT_KILL_MSK),
-			 priv->_agn.reply_agg_tx_stats.last_sent_bt_kill);
-	pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
-			 iwl_get_agg_tx_fail_reason(AGG_TX_STATE_SCD_QUERY_MSK),
-			 priv->_agn.reply_agg_tx_stats.scd_query);
-	pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t%u\n",
-			 iwl_get_agg_tx_fail_reason(
-				AGG_TX_STATE_TEST_BAD_CRC32_MSK),
-			 priv->_agn.reply_agg_tx_stats.bad_crc32);
-	pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
-			 iwl_get_agg_tx_fail_reason(AGG_TX_STATE_RESPONSE_MSK),
-			 priv->_agn.reply_agg_tx_stats.response);
-	pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
-			 iwl_get_agg_tx_fail_reason(AGG_TX_STATE_DUMP_TX_MSK),
-			 priv->_agn.reply_agg_tx_stats.dump_tx);
-	pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
-			 iwl_get_agg_tx_fail_reason(AGG_TX_STATE_DELAY_TX_MSK),
-			 priv->_agn.reply_agg_tx_stats.delay_tx);
-	pos += scnprintf(buf + pos, bufsz - pos, "UNKNOWN:\t\t\t%u\n",
-			 priv->_agn.reply_agg_tx_stats.unknown);
-
-	ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
-	kfree(buf);
-	return ret;
-}
diff -druN linux-2.6.39-libre/drivers/net/wireless/iwlwifi/iwl-agn-debugfs.h linux-3.0-rc7-libre/drivers/net/wireless/iwlwifi/iwl-agn-debugfs.h
--- linux-2.6.39-libre/drivers/net/wireless/iwlwifi/iwl-agn-debugfs.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/iwlwifi/iwl-agn-debugfs.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,70 +0,0 @@
-/******************************************************************************
- *
- * GPL LICENSE SUMMARY
- *
- * 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
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
- * USA
- *
- * The full GNU General Public License is included in this distribution
- * in the file called LICENSE.GPL.
- *
- * Contact Information:
- *  Intel Linux Wireless <ilw@linux.intel.com>
- * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
- *****************************************************************************/
-
-#include "iwl-dev.h"
-#include "iwl-core.h"
-#include "iwl-debug.h"
-
-#ifdef CONFIG_IWLWIFI_DEBUGFS
-ssize_t iwl_ucode_rx_stats_read(struct file *file, char __user *user_buf,
-				size_t count, loff_t *ppos);
-ssize_t iwl_ucode_tx_stats_read(struct file *file, char __user *user_buf,
-				size_t count, loff_t *ppos);
-ssize_t iwl_ucode_general_stats_read(struct file *file, char __user *user_buf,
-				     size_t count, loff_t *ppos);
-ssize_t iwl_ucode_bt_stats_read(struct file *file, char __user *user_buf,
-				size_t count, loff_t *ppos);
-ssize_t iwl_reply_tx_error_read(struct file *file, char __user *user_buf,
-				size_t count, loff_t *ppos);
-#else
-static ssize_t iwl_ucode_rx_stats_read(struct file *file, char __user *user_buf,
-				       size_t count, loff_t *ppos)
-{
-	return 0;
-}
-static ssize_t iwl_ucode_tx_stats_read(struct file *file, char __user *user_buf,
-				       size_t count, loff_t *ppos)
-{
-	return 0;
-}
-static ssize_t iwl_ucode_general_stats_read(struct file *file, char __user *user_buf,
-					    size_t count, loff_t *ppos)
-{
-	return 0;
-}
-static ssize_t iwl_ucode_bt_stats_read(struct file *file, char __user *user_buf,
-				       size_t count, loff_t *ppos)
-{
-	return 0;
-}
-static ssize_t iwl_reply_tx_error_read(struct file *file, char __user *user_buf,
-				       size_t count, loff_t *ppos)
-{
-	return 0;
-}
-#endif
diff -druN linux-2.6.39-libre/drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c linux-3.0-rc7-libre/drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c
--- linux-2.6.39-libre/drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c	2011-07-11 19:51:52.000000000 -0400
@@ -5,7 +5,7 @@
  *
  * GPL LICENSE SUMMARY
  *
- * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2008 - 2011 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 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -81,52 +81,13 @@
  *
 ******************************************************************************/
 
-/*
- * The device's EEPROM semaphore prevents conflicts between driver and uCode
- * when accessing the EEPROM; each access is a series of pulses to/from the
- * EEPROM chip, not a single event, so even reads could conflict if they
- * weren't arbitrated by the semaphore.
- */
-int iwlcore_eeprom_acquire_semaphore(struct iwl_priv *priv)
-{
-	u16 count;
-	int ret;
-
-	for (count = 0; count < EEPROM_SEM_RETRY_LIMIT; count++) {
-		/* Request semaphore */
-		iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG,
-			    CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM);
-
-		/* See if we got it */
-		ret = iwl_poll_bit(priv, CSR_HW_IF_CONFIG_REG,
-				CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM,
-				CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM,
-				EEPROM_SEM_TIMEOUT);
-		if (ret >= 0) {
-			IWL_DEBUG_IO(priv,
-				"Acquired semaphore after %d tries.\n",
-				count+1);
-			return ret;
-		}
-	}
-
-	return ret;
-}
-
-void iwlcore_eeprom_release_semaphore(struct iwl_priv *priv)
-{
-	iwl_clear_bit(priv, CSR_HW_IF_CONFIG_REG,
-		CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM);
-
-}
-
 int iwl_eeprom_check_version(struct iwl_priv *priv)
 {
 	u16 eeprom_ver;
 	u16 calib_ver;
 
 	eeprom_ver = iwl_eeprom_query16(priv, EEPROM_VERSION);
-	calib_ver = priv->cfg->ops->lib->eeprom_ops.calib_version(priv);
+	calib_ver = iwlagn_eeprom_calib_version(priv);
 
 	if (eeprom_ver < priv->cfg->eeprom_ver ||
 	    calib_ver < priv->cfg->eeprom_calib_ver)
diff -druN linux-2.6.39-libre/drivers/net/wireless/iwlwifi/iwl-agn.h linux-3.0-rc7-libre/drivers/net/wireless/iwlwifi/iwl-agn.h
--- linux-2.6.39-libre/drivers/net/wireless/iwlwifi/iwl-agn.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/iwlwifi/iwl-agn.h	2011-07-11 19:51:52.000000000 -0400
@@ -5,7 +5,7 @@
  *
  * GPL LICENSE SUMMARY
  *
- * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2008 - 2011 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 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -66,7 +66,6 @@
 #include "iwl-dev.h"
 
 /* configuration for the _agn devices */
-extern struct iwl_cfg iwl4965_agn_cfg;
 extern struct iwl_cfg iwl5300_agn_cfg;
 extern struct iwl_cfg iwl5100_agn_cfg;
 extern struct iwl_cfg iwl5350_agn_cfg;
@@ -90,6 +89,7 @@
 extern struct iwl_cfg iwl6050_2agn_cfg;
 extern struct iwl_cfg iwl6050_2abg_cfg;
 extern struct iwl_cfg iwl6150_bgn_cfg;
+extern struct iwl_cfg iwl6150_bg_cfg;
 extern struct iwl_cfg iwl1000_bgn_cfg;
 extern struct iwl_cfg iwl1000_bg_cfg;
 extern struct iwl_cfg iwl100_bgn_cfg;
@@ -103,10 +103,10 @@
 extern struct iwl_cfg iwl6035_2agn_cfg;
 extern struct iwl_cfg iwl6035_2abg_cfg;
 extern struct iwl_cfg iwl6035_2bg_cfg;
-extern struct iwl_cfg iwl200_bg_cfg;
-extern struct iwl_cfg iwl200_bgn_cfg;
-extern struct iwl_cfg iwl230_bg_cfg;
-extern struct iwl_cfg iwl230_bgn_cfg;
+extern struct iwl_cfg iwl105_bg_cfg;
+extern struct iwl_cfg iwl105_bgn_cfg;
+extern struct iwl_cfg iwl135_bg_cfg;
+extern struct iwl_cfg iwl135_bgn_cfg;
 
 extern struct iwl_mod_params iwlagn_mod_params;
 extern struct iwl_hcmd_ops iwlagn_hcmd;
@@ -114,7 +114,6 @@
 extern struct iwl_hcmd_utils_ops iwlagn_hcmd_utils;
 
 extern struct ieee80211_ops iwlagn_hw_ops;
-extern struct ieee80211_ops iwl4965_hw_ops;
 
 int iwl_reset_ict(struct iwl_priv *priv);
 void iwl_disable_ict(struct iwl_priv *priv);
@@ -122,21 +121,25 @@
 void iwl_free_isr_ict(struct iwl_priv *priv);
 irqreturn_t iwl_isr_ict(int irq, void *data);
 
+/* call this function to flush any scheduled tasklet */
+static inline void iwl_synchronize_irq(struct iwl_priv *priv)
+{
+	/* wait to make sure we flush pending tasklet*/
+	synchronize_irq(priv->pci_dev->irq);
+	tasklet_kill(&priv->irq_tasklet);
+}
+
+int iwl_prepare_card_hw(struct iwl_priv *priv);
+
+int iwlagn_start_device(struct iwl_priv *priv);
+void iwlagn_stop_device(struct iwl_priv *priv);
+
 /* tx queue */
 void iwlagn_set_wr_ptrs(struct iwl_priv *priv,
 		     int txq_id, u32 index);
 void iwlagn_tx_queue_set_status(struct iwl_priv *priv,
 			     struct iwl_tx_queue *txq,
 			     int tx_fifo_id, int scd_retry);
-void iwlagn_txq_update_byte_cnt_tbl(struct iwl_priv *priv,
-				    struct iwl_tx_queue *txq,
-				    u16 byte_cnt);
-void iwlagn_txq_inval_byte_cnt_tbl(struct iwl_priv *priv,
-				   struct iwl_tx_queue *txq);
-int iwlagn_txq_agg_enable(struct iwl_priv *priv, int txq_id,
-			  int tx_fifo, int sta_id, int tid, u16 ssn_idx);
-int iwlagn_txq_agg_disable(struct iwl_priv *priv, u16 txq_id,
-			   u16 ssn_idx, u8 tx_fifo);
 void iwlagn_txq_set_sched(struct iwl_priv *priv, u32 mask);
 void iwl_free_tfds_in_queue(struct iwl_priv *priv,
 			    int sta_id, int tid, int freed);
@@ -151,16 +154,14 @@
 			     u32 changes);
 
 /* uCode */
-int iwlagn_load_ucode(struct iwl_priv *priv);
 void iwlagn_rx_calib_result(struct iwl_priv *priv,
 			 struct iwl_rx_mem_buffer *rxb);
-void iwlagn_rx_calib_complete(struct iwl_priv *priv,
-			   struct iwl_rx_mem_buffer *rxb);
-void iwlagn_init_alive_start(struct iwl_priv *priv);
-int iwlagn_alive_notify(struct iwl_priv *priv);
-int iwl_verify_ucode(struct iwl_priv *priv);
-void iwlagn_send_bt_env(struct iwl_priv *priv, u8 action, u8 type);
+int iwlagn_send_bt_env(struct iwl_priv *priv, u8 action, u8 type);
 void iwlagn_send_prio_tbl(struct iwl_priv *priv);
+int iwlagn_run_init_ucode(struct iwl_priv *priv);
+int iwlagn_load_ucode_wait_alive(struct iwl_priv *priv,
+				 struct fw_img *image,
+				 int subtype, int alternate_subtype);
 
 /* lib */
 void iwl_check_abort_status(struct iwl_priv *priv,
@@ -179,8 +180,6 @@
 int iwlagn_wait_tx_queue_empty(struct iwl_priv *priv);
 int iwlagn_txfifo_flush(struct iwl_priv *priv, u16 flush_control);
 void iwlagn_dev_txfifo_flush(struct iwl_priv *priv, u16 flush_control);
-void iwl_dump_csr(struct iwl_priv *priv);
-int iwl_dump_fh(struct iwl_priv *priv, char **buf, bool display);
 
 /* rx */
 void iwlagn_rx_queue_restock(struct iwl_priv *priv);
@@ -193,12 +192,10 @@
 void iwl_setup_rx_handlers(struct iwl_priv *priv);
 
 /* tx */
-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,
+void iwlagn_txq_free_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq);
+int iwlagn_txq_attach_buf_to_tfd(struct iwl_priv *priv,
 				 struct iwl_tx_queue *txq,
-				 dma_addr_t addr, u16 len, u8 reset, u8 pad);
-int iwl_hw_tx_queue_init(struct iwl_priv *priv,
-			 struct iwl_tx_queue *txq);
+				 dma_addr_t addr, u16 len, u8 reset);
 void iwlagn_hwrate_to_tx_control(struct iwl_priv *priv, u32 rate_n_flags,
 			      struct ieee80211_tx_info *info);
 int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb);
@@ -206,6 +203,9 @@
 			struct ieee80211_sta *sta, u16 tid, u16 *ssn);
 int iwlagn_tx_agg_stop(struct iwl_priv *priv, struct ieee80211_vif *vif,
 		       struct ieee80211_sta *sta, u16 tid);
+void iwlagn_txq_agg_queue_setup(struct iwl_priv *priv,
+				struct ieee80211_sta *sta,
+				int tid, int frame_limit);
 int iwlagn_txq_check_empty(struct iwl_priv *priv,
 			   int sta_id, u8 tid, int txq_id);
 void iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv,
@@ -225,6 +225,7 @@
 	case TX_STATUS_DIRECT_DONE:
 		return IEEE80211_TX_STAT_ACK;
 	case TX_STATUS_FAIL_DEST_PS:
+	case TX_STATUS_FAIL_PASSIVE_NO_RX:
 		return IEEE80211_TX_STAT_TX_FILTERED;
 	default:
 		return 0;
@@ -249,8 +250,6 @@
 			       struct ieee80211_vif *vif, bool add);
 
 /* hcmd */
-int iwlagn_send_rxon_assoc(struct iwl_priv *priv,
-			   struct iwl_rxon_context *ctx);
 int iwlagn_send_tx_ant_config(struct iwl_priv *priv, u8 valid_tx_ant);
 int iwlagn_send_beacon_cmd(struct iwl_priv *priv);
 
@@ -311,7 +310,7 @@
 
 static inline u8 iwl_hw_get_rate(__le32 rate_n_flags)
 {
-	return le32_to_cpu(rate_n_flags) & 0xFF;
+	return le32_to_cpu(rate_n_flags) & RATE_MCS_RATE_MSK;
 }
 
 static inline __le32 iwl_hw_set_rate_n_flags(u8 rate, u32 flags)
@@ -322,50 +321,44 @@
 /* eeprom */
 void iwlcore_eeprom_enhanced_txpower(struct iwl_priv *priv);
 void iwl_eeprom_get_mac(const struct iwl_priv *priv, u8 *mac);
-int iwlcore_eeprom_acquire_semaphore(struct iwl_priv *priv);
-void iwlcore_eeprom_release_semaphore(struct iwl_priv *priv);
 
 /* notification wait support */
 void __acquires(wait_entry)
 iwlagn_init_notification_wait(struct iwl_priv *priv,
 			      struct iwl_notification_wait *wait_entry,
+			      u8 cmd,
 			      void (*fn)(struct iwl_priv *priv,
-					 struct iwl_rx_packet *pkt),
-			      u8 cmd);
-signed long __releases(wait_entry)
+					 struct iwl_rx_packet *pkt,
+					 void *data),
+			      void *fn_data);
+int __must_check __releases(wait_entry)
 iwlagn_wait_notification(struct iwl_priv *priv,
 			 struct iwl_notification_wait *wait_entry,
 			 unsigned long timeout);
 void __releases(wait_entry)
 iwlagn_remove_notification(struct iwl_priv *priv,
 			   struct iwl_notification_wait *wait_entry);
-
-/* mac80211 handlers (for 4965) */
-void iwlagn_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb);
-int iwlagn_mac_start(struct ieee80211_hw *hw);
-void iwlagn_mac_stop(struct ieee80211_hw *hw);
-void iwlagn_configure_filter(struct ieee80211_hw *hw,
-			     unsigned int changed_flags,
-			     unsigned int *total_flags,
-			     u64 multicast);
-int iwlagn_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
-		       struct ieee80211_vif *vif, struct ieee80211_sta *sta,
-		       struct ieee80211_key_conf *key);
-void iwlagn_mac_update_tkip_key(struct ieee80211_hw *hw,
-				struct ieee80211_vif *vif,
-				struct ieee80211_key_conf *keyconf,
-				struct ieee80211_sta *sta,
-				u32 iv32, u16 *phase1key);
-int iwlagn_mac_ampdu_action(struct ieee80211_hw *hw,
-			    struct ieee80211_vif *vif,
-			    enum ieee80211_ampdu_mlme_action action,
-			    struct ieee80211_sta *sta, u16 tid, u16 *ssn,
-			    u8 buf_size);
-int iwlagn_mac_sta_add(struct ieee80211_hw *hw,
-		       struct ieee80211_vif *vif,
-		       struct ieee80211_sta *sta);
-void iwlagn_mac_channel_switch(struct ieee80211_hw *hw,
-			       struct ieee80211_channel_switch *ch_switch);
-void iwlagn_mac_flush(struct ieee80211_hw *hw, bool drop);
+extern int iwlagn_init_alive_start(struct iwl_priv *priv);
+extern int iwl_alive_start(struct iwl_priv *priv);
+/* svtool */
+#ifdef CONFIG_IWLWIFI_DEVICE_SVTOOL
+extern int iwl_testmode_cmd(struct ieee80211_hw *hw, void *data, int len);
+extern void iwl_testmode_init(struct iwl_priv *priv);
+extern void iwl_testmode_cleanup(struct iwl_priv *priv);
+#else
+static inline
+int iwl_testmode_cmd(struct ieee80211_hw *hw, void *data, int len)
+{
+	return -ENOSYS;
+}
+static inline
+void iwl_testmode_init(struct iwl_priv *priv)
+{
+}
+static inline
+void iwl_testmode_cleanup(struct iwl_priv *priv)
+{
+}
+#endif
 
 #endif /* __iwl_agn_h__ */
diff -druN linux-2.6.39-libre/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c linux-3.0-rc7-libre/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c
--- linux-2.6.39-libre/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c	2011-07-11 19:51:52.000000000 -0400
@@ -2,7 +2,7 @@
  *
  * GPL LICENSE SUMMARY
  *
- * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2008 - 2011 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,54 +37,6 @@
 #include "iwl-io.h"
 #include "iwl-agn.h"
 
-int iwlagn_send_rxon_assoc(struct iwl_priv *priv,
-			   struct iwl_rxon_context *ctx)
-{
-	int ret = 0;
-	struct iwl5000_rxon_assoc_cmd rxon_assoc;
-	const struct iwl_rxon_cmd *rxon1 = &ctx->staging;
-	const struct iwl_rxon_cmd *rxon2 = &ctx->active;
-
-	if ((rxon1->flags == rxon2->flags) &&
-	    (rxon1->filter_flags == rxon2->filter_flags) &&
-	    (rxon1->cck_basic_rates == rxon2->cck_basic_rates) &&
-	    (rxon1->ofdm_ht_single_stream_basic_rates ==
-	     rxon2->ofdm_ht_single_stream_basic_rates) &&
-	    (rxon1->ofdm_ht_dual_stream_basic_rates ==
-	     rxon2->ofdm_ht_dual_stream_basic_rates) &&
-	    (rxon1->ofdm_ht_triple_stream_basic_rates ==
-	     rxon2->ofdm_ht_triple_stream_basic_rates) &&
-	    (rxon1->acquisition_data == rxon2->acquisition_data) &&
-	    (rxon1->rx_chain == rxon2->rx_chain) &&
-	    (rxon1->ofdm_basic_rates == rxon2->ofdm_basic_rates)) {
-		IWL_DEBUG_INFO(priv, "Using current RXON_ASSOC.  Not resending.\n");
-		return 0;
-	}
-
-	rxon_assoc.flags = ctx->staging.flags;
-	rxon_assoc.filter_flags = ctx->staging.filter_flags;
-	rxon_assoc.ofdm_basic_rates = ctx->staging.ofdm_basic_rates;
-	rxon_assoc.cck_basic_rates = ctx->staging.cck_basic_rates;
-	rxon_assoc.reserved1 = 0;
-	rxon_assoc.reserved2 = 0;
-	rxon_assoc.reserved3 = 0;
-	rxon_assoc.ofdm_ht_single_stream_basic_rates =
-	    ctx->staging.ofdm_ht_single_stream_basic_rates;
-	rxon_assoc.ofdm_ht_dual_stream_basic_rates =
-	    ctx->staging.ofdm_ht_dual_stream_basic_rates;
-	rxon_assoc.rx_chain_select_flags = ctx->staging.rx_chain;
-	rxon_assoc.ofdm_ht_triple_stream_basic_rates =
-		 ctx->staging.ofdm_ht_triple_stream_basic_rates;
-	rxon_assoc.acquisition_data = ctx->staging.acquisition_data;
-
-	ret = iwl_send_cmd_pdu_async(priv, ctx->rxon_assoc_cmd,
-				     sizeof(rxon_assoc), &rxon_assoc, NULL);
-	if (ret)
-		return ret;
-
-	return ret;
-}
-
 int iwlagn_send_tx_ant_config(struct iwl_priv *priv, u8 valid_tx_ant)
 {
 	struct iwl_tx_ant_config_cmd tx_ant_cmd = {
@@ -102,12 +54,6 @@
 	}
 }
 
-/* Currently this is the superset of everything */
-static u16 iwlagn_get_hcmd_size(u8 cmd_id, u16 len)
-{
-	return len;
-}
-
 static u16 iwlagn_build_addsta_hcmd(const struct iwl_addsta_cmd *cmd, u8 *data)
 {
 	u16 size = (u16)sizeof(struct iwl_addsta_cmd);
@@ -217,17 +163,9 @@
 				     __le16 fc, __le32 *tx_flags)
 {
 	if (info->control.rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS ||
-	    info->control.rates[0].flags & IEEE80211_TX_RC_USE_CTS_PROTECT) {
-		*tx_flags |= TX_CMD_FLG_PROT_REQUIRE_MSK;
-		return;
-	}
-
-	if (priv->cfg->ht_params &&
-	    priv->cfg->ht_params->use_rts_for_aggregation &&
-	    info->flags & IEEE80211_TX_CTL_AMPDU) {
+	    info->control.rates[0].flags & IEEE80211_TX_RC_USE_CTS_PROTECT ||
+	    info->flags & IEEE80211_TX_CTL_AMPDU)
 		*tx_flags |= TX_CMD_FLG_PROT_REQUIRE_MSK;
-		return;
-	}
 }
 
 /* Calc max signal level (dBm) among 3 possible receivers */
@@ -364,7 +302,6 @@
 }
 
 struct iwl_hcmd_ops iwlagn_hcmd = {
-	.rxon_assoc = iwlagn_send_rxon_assoc,
 	.commit_rxon = iwlagn_commit_rxon,
 	.set_rxon_chain = iwlagn_set_rxon_chain,
 	.set_tx_ant = iwlagn_send_tx_ant_config,
@@ -373,7 +310,6 @@
 };
 
 struct iwl_hcmd_ops iwlagn_bt_hcmd = {
-	.rxon_assoc = iwlagn_send_rxon_assoc,
 	.commit_rxon = iwlagn_commit_rxon,
 	.set_rxon_chain = iwlagn_set_rxon_chain,
 	.set_tx_ant = iwlagn_send_tx_ant_config,
@@ -382,7 +318,6 @@
 };
 
 struct iwl_hcmd_utils_ops iwlagn_hcmd_utils = {
-	.get_hcmd_size = iwlagn_get_hcmd_size,
 	.build_addsta_hcmd = iwlagn_build_addsta_hcmd,
 	.gain_computation = iwlagn_gain_computation,
 	.chain_noise_reset = iwlagn_chain_noise_reset,
diff -druN linux-2.6.39-libre/drivers/net/wireless/iwlwifi/iwl-agn-hw.h linux-3.0-rc7-libre/drivers/net/wireless/iwlwifi/iwl-agn-hw.h
--- linux-2.6.39-libre/drivers/net/wireless/iwlwifi/iwl-agn-hw.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/iwlwifi/iwl-agn-hw.h	2011-07-11 19:51:52.000000000 -0400
@@ -5,7 +5,7 @@
  *
  * GPL LICENSE SUMMARY
  *
- * Copyright(c) 2007 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2007 - 2011 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 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
diff -druN linux-2.6.39-libre/drivers/net/wireless/iwlwifi/iwl-agn-ict.c linux-3.0-rc7-libre/drivers/net/wireless/iwlwifi/iwl-agn-ict.c
--- linux-2.6.39-libre/drivers/net/wireless/iwlwifi/iwl-agn-ict.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/iwlwifi/iwl-agn-ict.c	2011-07-11 19:51:52.000000000 -0400
@@ -2,7 +2,7 @@
  *
  * GPL LICENSE SUMMARY
  *
- * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2008 - 2011 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
@@ -59,8 +59,6 @@
 int iwl_alloc_isr_ict(struct iwl_priv *priv)
 {
 
-	if (priv->cfg->base_params->use_isr_legacy)
-		return 0;
 	/* allocate shrared data table */
 	priv->_agn.ict_tbl_vir =
 		dma_alloc_coherent(&priv->pci_dev->dev,
diff -druN linux-2.6.39-libre/drivers/net/wireless/iwlwifi/iwl-agn-led.c linux-3.0-rc7-libre/drivers/net/wireless/iwlwifi/iwl-agn-led.c
--- linux-2.6.39-libre/drivers/net/wireless/iwlwifi/iwl-agn-led.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/iwlwifi/iwl-agn-led.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,73 +0,0 @@
-/******************************************************************************
- *
- * 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
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
- *
- * The full GNU General Public License is included in this distribution in the
- * file called LICENSE.
- *
- * Contact Information:
- *  Intel Linux Wireless <ilw@linux.intel.com>
- * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
- *
- *****************************************************************************/
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/pci.h>
-#include <linux/dma-mapping.h>
-#include <linux/delay.h>
-#include <linux/skbuff.h>
-#include <linux/netdevice.h>
-#include <linux/wireless.h>
-#include <net/mac80211.h>
-#include <linux/etherdevice.h>
-#include <asm/unaligned.h>
-
-#include "iwl-commands.h"
-#include "iwl-dev.h"
-#include "iwl-core.h"
-#include "iwl-io.h"
-#include "iwl-agn-led.h"
-
-/* Send led command */
-static int iwl_send_led_cmd(struct iwl_priv *priv, struct iwl_led_cmd *led_cmd)
-{
-	struct iwl_host_cmd cmd = {
-		.id = REPLY_LEDS_CMD,
-		.len = sizeof(struct iwl_led_cmd),
-		.data = led_cmd,
-		.flags = CMD_ASYNC,
-		.callback = NULL,
-	};
-	u32 reg;
-
-	reg = iwl_read32(priv, CSR_LED_REG);
-	if (reg != (reg & CSR_LED_BSM_CTRL_MSK))
-		iwl_write32(priv, CSR_LED_REG, reg & CSR_LED_BSM_CTRL_MSK);
-
-	return iwl_send_cmd(priv, &cmd);
-}
-
-/* Set led register off */
-void iwlagn_led_enable(struct iwl_priv *priv)
-{
-	iwl_write32(priv, CSR_LED_REG, CSR_LED_REG_TRUN_ON);
-}
-
-const struct iwl_led_ops iwlagn_led_ops = {
-	.cmd = iwl_send_led_cmd,
-};
diff -druN linux-2.6.39-libre/drivers/net/wireless/iwlwifi/iwl-agn-led.h linux-3.0-rc7-libre/drivers/net/wireless/iwlwifi/iwl-agn-led.h
--- linux-2.6.39-libre/drivers/net/wireless/iwlwifi/iwl-agn-led.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/iwlwifi/iwl-agn-led.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,33 +0,0 @@
-/******************************************************************************
- *
- * 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
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
- *
- * The full GNU General Public License is included in this distribution in the
- * file called LICENSE.
- *
- * Contact Information:
- *  Intel Linux Wireless <ilw@linux.intel.com>
- * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
- *
- *****************************************************************************/
-
-#ifndef __iwl_agn_led_h__
-#define __iwl_agn_led_h__
-
-extern const struct iwl_led_ops iwlagn_led_ops;
-void iwlagn_led_enable(struct iwl_priv *priv);
-
-#endif /* __iwl_agn_led_h__ */
diff -druN linux-2.6.39-libre/drivers/net/wireless/iwlwifi/iwl-agn-lib.c linux-3.0-rc7-libre/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
--- linux-2.6.39-libre/drivers/net/wireless/iwlwifi/iwl-agn-lib.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/iwlwifi/iwl-agn-lib.c	2011-07-11 19:51:52.000000000 -0400
@@ -2,7 +2,7 @@
  *
  * GPL LICENSE SUMMARY
  *
- * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2008 - 2011 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
@@ -172,6 +172,7 @@
 
 static void iwlagn_set_tx_status(struct iwl_priv *priv,
 				 struct ieee80211_tx_info *info,
+				 struct iwl_rxon_context *ctx,
 				 struct iwlagn_tx_resp *tx_resp,
 				 int txq_id, bool is_agg)
 {
@@ -186,6 +187,13 @@
 	if (!iwl_is_tx_success(status))
 		iwlagn_count_tx_err_status(priv, status);
 
+	if (status == TX_STATUS_FAIL_PASSIVE_NO_RX &&
+	    iwl_is_associated_ctx(ctx) && ctx->vif &&
+	    ctx->vif->type == NL80211_IFTYPE_STATION) {
+		ctx->last_tx_rejected = true;
+		iwl_stop_queue(priv, &priv->txq[txq_id]);
+	}
+
 	IWL_DEBUG_TX_REPLY(priv, "TXQ %d status %s (0x%08x) rate_n_flags "
 			   "0x%x retries %d\n",
 			   txq_id,
@@ -242,15 +250,16 @@
 
 	/* # frames attempted by Tx command */
 	if (agg->frame_count == 1) {
+		struct iwl_tx_info *txb;
+
 		/* Only one frame was attempted; no block-ack will arrive */
 		idx = start_idx;
 
 		IWL_DEBUG_TX_REPLY(priv, "FrameCnt = %d, StartIdx=%d idx=%d\n",
 				   agg->frame_count, agg->start_idx, idx);
-		iwlagn_set_tx_status(priv,
-				     IEEE80211_SKB_CB(
-					priv->txq[txq_id].txb[idx].skb),
-				     tx_resp, txq_id, true);
+		txb = &priv->txq[txq_id].txb[idx];
+		iwlagn_set_tx_status(priv, IEEE80211_SKB_CB(txb->skb),
+				     txb->ctx, tx_resp, txq_id, true);
 		agg->wait_for_ba = 0;
 	} else {
 		/* Two or more frames were attempted; expect block-ack */
@@ -391,7 +400,8 @@
 	struct iwl_tx_queue *txq = &priv->txq[txq_id];
 	struct ieee80211_tx_info *info;
 	struct iwlagn_tx_resp *tx_resp = (void *)&pkt->u.raw[0];
-	u32  status = le16_to_cpu(tx_resp->status.status);
+	struct iwl_tx_info *txb;
+	u32 status = le16_to_cpu(tx_resp->status.status);
 	int tid;
 	int sta_id;
 	int freed;
@@ -406,7 +416,8 @@
 	}
 
 	txq->time_stamp = jiffies;
-	info = IEEE80211_SKB_CB(txq->txb[txq->q.read_ptr].skb);
+	txb = &txq->txb[txq->q.read_ptr];
+	info = IEEE80211_SKB_CB(txb->skb);
 	memset(&info->status, 0, sizeof(info->status));
 
 	tid = (tx_resp->ra_tid & IWLAGN_TX_RES_TID_MSK) >>
@@ -450,12 +461,14 @@
 				iwl_wake_queue(priv, txq);
 		}
 	} else {
-		iwlagn_set_tx_status(priv, info, tx_resp, txq_id, false);
+		iwlagn_set_tx_status(priv, info, txb->ctx, tx_resp,
+				     txq_id, false);
 		freed = iwlagn_tx_queue_reclaim(priv, txq_id, index);
 		iwl_free_tfds_in_queue(priv, sta_id, tid, freed);
 
 		if (priv->mac80211_registered &&
-		    (iwl_queue_space(&txq->q) > txq->q.low_mark))
+		    iwl_queue_space(&txq->q) > txq->q.low_mark &&
+		    status != TX_STATUS_FAIL_PASSIVE_NO_RX)
 			iwl_wake_queue(priv, txq);
 	}
 
@@ -470,8 +483,6 @@
 	/* init calibration handlers */
 	priv->rx_handlers[CALIBRATION_RES_NOTIFICATION] =
 					iwlagn_rx_calib_result;
-	priv->rx_handlers[CALIBRATION_COMPLETE_NOTIFICATION] =
-					iwlagn_rx_calib_complete;
 	priv->rx_handlers[REPLY_TX] = iwlagn_rx_reply_tx;
 
 	/* set up notification wait support */
@@ -482,8 +493,10 @@
 
 void iwlagn_setup_deferred_work(struct iwl_priv *priv)
 {
-	/* in agn, the tx power calibration is done in uCode */
-	priv->disable_tx_power_cal = 1;
+	/*
+	 * nothing need to be done here anymore
+	 * still keep for future use if needed
+	 */
 }
 
 int iwlagn_hw_valid_rtc_data_addr(u32 addr)
@@ -534,9 +547,7 @@
 void iwlagn_temperature(struct iwl_priv *priv)
 {
 	/* store temperature from correct statistics (in Celsius) */
-	priv->temperature = le32_to_cpu((iwl_bt_statistics(priv)) ?
-		priv->_agn.statistics_bt.general.common.temperature :
-		priv->_agn.statistics.general.common.temperature);
+	priv->temperature = le32_to_cpu(priv->statistics.common.temperature);
 	iwl_tt_handler(priv);
 }
 
@@ -652,10 +663,9 @@
 	const u32 rfdnlog = RX_QUEUE_SIZE_LOG; /* 256 RBDs */
 	u32 rb_timeout = 0; /* FIXME: RX_RB_TIMEOUT for all devices? */
 
-	if (!priv->cfg->base_params->use_isr_legacy)
-		rb_timeout = RX_RB_TIMEOUT;
+	rb_timeout = RX_RB_TIMEOUT;
 
-	if (priv->cfg->mod_params->amsdu_size_8K)
+	if (iwlagn_mod_params.amsdu_size_8K)
 		rb_size = FH_RCSR_RX_CONFIG_REG_VAL_RB_SIZE_8K;
 	else
 		rb_size = FH_RCSR_RX_CONFIG_REG_VAL_RB_SIZE_4K;
@@ -913,7 +923,6 @@
 
 		list_add_tail(&rxb->list, &rxq->rx_free);
 		rxq->free_count++;
-		priv->alloc_rxb_page++;
 
 		spin_unlock_irqrestore(&rxq->lock, flags);
 	}
@@ -1131,8 +1140,7 @@
 {
 	struct iwl_host_cmd cmd = {
 		.id = REPLY_SCAN_CMD,
-		.len = sizeof(struct iwl_scan_cmd),
-		.flags = CMD_SIZE_HUGE,
+		.len = { sizeof(struct iwl_scan_cmd), },
 	};
 	struct iwl_scan_cmd *scan;
 	struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
@@ -1285,9 +1293,17 @@
 	 * 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.
+	 *
+	 * This was fixed in later versions along with some other
+	 * scan changes, and the threshold behaves as a flag in those
+	 * versions.
 	 */
-	scan->good_CRC_th = is_active ? IWL_GOOD_CRC_TH_DEFAULT :
-					IWL_GOOD_CRC_TH_NEVER;
+	if (priv->new_scan_threshold_behaviour)
+		scan->good_CRC_th = is_active ? IWL_GOOD_CRC_TH_DEFAULT :
+						IWL_GOOD_CRC_TH_DISABLED;
+	else
+		scan->good_CRC_th = is_active ? IWL_GOOD_CRC_TH_DEFAULT :
+						IWL_GOOD_CRC_TH_NEVER;
 
 	band = priv->scan_band;
 
@@ -1408,10 +1424,11 @@
 		return -EIO;
 	}
 
-	cmd.len += le16_to_cpu(scan->tx_cmd.len) +
+	cmd.len[0] += le16_to_cpu(scan->tx_cmd.len) +
 	    scan->channel_count * sizeof(struct iwl_scan_channel);
-	cmd.data = scan;
-	scan->len = cpu_to_le16(cmd.len);
+	cmd.data[0] = scan;
+	cmd.dataflags[0] = IWL_HCMD_DFL_NOCOPY;
+	scan->len = cpu_to_le16(cmd.len[0]);
 
 	/* set scan bit here for PAN params */
 	set_bit(STATUS_SCAN_HW, &priv->status);
@@ -1503,9 +1520,9 @@
 	struct iwl_txfifo_flush_cmd flush_cmd;
 	struct iwl_host_cmd cmd = {
 		.id = REPLY_TXFIFO_FLUSH,
-		.len = sizeof(struct iwl_txfifo_flush_cmd),
+		.len = { sizeof(struct iwl_txfifo_flush_cmd), },
 		.flags = CMD_SYNC,
-		.data = &flush_cmd,
+		.data = { &flush_cmd, },
 	};
 
 	might_sleep();
@@ -2245,34 +2262,44 @@
 /* notification wait support */
 void iwlagn_init_notification_wait(struct iwl_priv *priv,
 				   struct iwl_notification_wait *wait_entry,
+				   u8 cmd,
 				   void (*fn)(struct iwl_priv *priv,
-					      struct iwl_rx_packet *pkt),
-				   u8 cmd)
+					      struct iwl_rx_packet *pkt,
+					      void *data),
+				   void *fn_data)
 {
 	wait_entry->fn = fn;
+	wait_entry->fn_data = fn_data;
 	wait_entry->cmd = cmd;
 	wait_entry->triggered = false;
+	wait_entry->aborted = false;
 
 	spin_lock_bh(&priv->_agn.notif_wait_lock);
 	list_add(&wait_entry->list, &priv->_agn.notif_waits);
 	spin_unlock_bh(&priv->_agn.notif_wait_lock);
 }
 
-signed long iwlagn_wait_notification(struct iwl_priv *priv,
-				     struct iwl_notification_wait *wait_entry,
-				     unsigned long timeout)
+int iwlagn_wait_notification(struct iwl_priv *priv,
+			     struct iwl_notification_wait *wait_entry,
+			     unsigned long timeout)
 {
 	int ret;
 
 	ret = wait_event_timeout(priv->_agn.notif_waitq,
-				 wait_entry->triggered,
+				 wait_entry->triggered || wait_entry->aborted,
 				 timeout);
 
 	spin_lock_bh(&priv->_agn.notif_wait_lock);
 	list_del(&wait_entry->list);
 	spin_unlock_bh(&priv->_agn.notif_wait_lock);
 
-	return ret;
+	if (wait_entry->aborted)
+		return -EIO;
+
+	/* return value is always >= 0 */
+	if (ret <= 0)
+		return -ETIMEDOUT;
+	return 0;
 }
 
 void iwlagn_remove_notification(struct iwl_priv *priv,
@@ -2282,3 +2309,87 @@
 	list_del(&wait_entry->list);
 	spin_unlock_bh(&priv->_agn.notif_wait_lock);
 }
+
+int iwlagn_start_device(struct iwl_priv *priv)
+{
+	int ret;
+
+	if (iwl_prepare_card_hw(priv)) {
+		IWL_WARN(priv, "Exit HW not ready\n");
+		return -EIO;
+	}
+
+	/* If platform's RF_KILL switch is NOT set to KILL */
+	if (iwl_read32(priv, CSR_GP_CNTRL) & CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW)
+		clear_bit(STATUS_RF_KILL_HW, &priv->status);
+	else
+		set_bit(STATUS_RF_KILL_HW, &priv->status);
+
+	if (iwl_is_rfkill(priv)) {
+		wiphy_rfkill_set_hw_state(priv->hw->wiphy, true);
+		iwl_enable_interrupts(priv);
+		return -ERFKILL;
+	}
+
+	iwl_write32(priv, CSR_INT, 0xFFFFFFFF);
+
+	ret = iwlagn_hw_nic_init(priv);
+	if (ret) {
+		IWL_ERR(priv, "Unable to init nic\n");
+		return ret;
+	}
+
+	/* make sure rfkill handshake bits are cleared */
+	iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL);
+	iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR,
+		    CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED);
+
+	/* clear (again), then enable host interrupts */
+	iwl_write32(priv, CSR_INT, 0xFFFFFFFF);
+	iwl_enable_interrupts(priv);
+
+	/* really make sure rfkill handshake bits are cleared */
+	iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL);
+	iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL);
+
+	return 0;
+}
+
+void iwlagn_stop_device(struct iwl_priv *priv)
+{
+	unsigned long flags;
+
+	/* stop and reset the on-board processor */
+	iwl_write32(priv, CSR_RESET, CSR_RESET_REG_FLAG_NEVO_RESET);
+
+	/* tell the device to stop sending interrupts */
+	spin_lock_irqsave(&priv->lock, flags);
+	iwl_disable_interrupts(priv);
+	spin_unlock_irqrestore(&priv->lock, flags);
+	iwl_synchronize_irq(priv);
+
+	/* device going down, Stop using ICT table */
+	iwl_disable_ict(priv);
+
+	/*
+	 * If a HW restart happens during firmware loading,
+	 * then the firmware loading might call this function
+	 * and later it might be called again due to the
+	 * restart. So don't process again if the device is
+	 * already dead.
+	 */
+	if (test_bit(STATUS_DEVICE_ENABLED, &priv->status)) {
+                iwlagn_txq_ctx_stop(priv);
+                iwlagn_rxq_stop(priv);
+
+                /* Power-down device's busmaster DMA clocks */
+                iwl_write_prph(priv, APMG_CLK_DIS_REG, APMG_CLK_VAL_DMA_CLK_RQT);
+                udelay(5);
+        }
+
+	/* Make sure (redundant) we've released our request to stay awake */
+	iwl_clear_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
+
+	/* Stop the device, and put it in low power state */
+	iwl_apm_stop(priv);
+}
diff -druN linux-2.6.39-libre/drivers/net/wireless/iwlwifi/iwl-agn-rs.c linux-3.0-rc7-libre/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
--- linux-2.6.39-libre/drivers/net/wireless/iwlwifi/iwl-agn-rs.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/iwlwifi/iwl-agn-rs.c	2011-07-11 19:51:52.000000000 -0400
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2011 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
@@ -115,13 +115,18 @@
 	/* FIXME:RS:          ^^    should be INV (legacy) */
 };
 
+static inline u8 rs_extract_rate(u32 rate_n_flags)
+{
+	return (u8)(rate_n_flags & RATE_MCS_RATE_MSK);
+}
+
 static int iwl_hwrate_to_plcp_idx(u32 rate_n_flags)
 {
 	int idx = 0;
 
 	/* HT rate format */
 	if (rate_n_flags & RATE_MCS_HT_MSK) {
-		idx = (rate_n_flags & 0xff);
+		idx = rs_extract_rate(rate_n_flags);
 
 		if (idx >= IWL_RATE_MIMO3_6M_PLCP)
 			idx = idx - IWL_RATE_MIMO3_6M_PLCP;
@@ -138,7 +143,8 @@
 	/* legacy rate format, search for match in table */
 	} else {
 		for (idx = 0; idx < ARRAY_SIZE(iwl_rates); idx++)
-			if (iwl_rates[idx].plcp == (rate_n_flags & 0xFF))
+			if (iwl_rates[idx].plcp ==
+					rs_extract_rate(rate_n_flags))
 				return idx;
 	}
 
@@ -239,11 +245,6 @@
 
 #define MCS_INDEX_PER_STREAM	(8)
 
-static inline u8 rs_extract_rate(u32 rate_n_flags)
-{
-	return (u8)(rate_n_flags & 0xFF);
-}
-
 static void rs_rate_scale_clear_window(struct iwl_rate_scale_data *window)
 {
 	window->data = 0;
@@ -334,6 +335,32 @@
 	return tid;
 }
 
+#ifdef CONFIG_MAC80211_DEBUGFS
+static void rs_program_fix_rate(struct iwl_priv *priv,
+				struct iwl_lq_sta *lq_sta)
+{
+	struct iwl_station_priv *sta_priv =
+		container_of(lq_sta, struct iwl_station_priv, lq_sta);
+	struct iwl_rxon_context *ctx = sta_priv->common.ctx;
+
+	lq_sta->active_legacy_rate = 0x0FFF;	/* 1 - 54 MBits, includes CCK */
+	lq_sta->active_siso_rate   = 0x1FD0;	/* 6 - 60 MBits, no 9, no CCK */
+	lq_sta->active_mimo2_rate  = 0x1FD0;	/* 6 - 60 MBits, no 9, no CCK */
+	lq_sta->active_mimo3_rate  = 0x1FD0;	/* 6 - 60 MBits, no 9, no CCK */
+
+	lq_sta->dbg_fixed_rate = priv->dbg_fixed_rate;
+
+	IWL_DEBUG_RATE(priv, "sta_id %d rate 0x%X\n",
+		lq_sta->lq.sta_id, priv->dbg_fixed_rate);
+
+	if (priv->dbg_fixed_rate) {
+		rs_fill_link_cmd(NULL, lq_sta, priv->dbg_fixed_rate);
+		iwl_send_lq_cmd(lq_sta->drv, ctx, &lq_sta->lq, CMD_ASYNC,
+				false);
+	}
+}
+#endif
+
 /*
 	get the traffic load value for tid
 */
@@ -1045,7 +1072,10 @@
 	/* See if there's a better rate or modulation mode to try. */
 	if (sta && sta->supp_rates[sband->band])
 		rs_rate_scale_perform(priv, skb, sta, lq_sta);
-
+#ifdef CONFIG_MAC80211_DEBUGFS
+	if (priv->dbg_fixed_rate != lq_sta->dbg_fixed_rate)
+		rs_program_fix_rate(priv, lq_sta);
+#endif
 	if (priv->cfg->bt_params && priv->cfg->bt_params->advanced_bt_coexist)
 		rs_bt_update_lq(priv, ctx, lq_sta);
 }
@@ -2169,11 +2199,11 @@
  * setup rate table in uCode
  * return rate_n_flags as used in the table
  */
-static u32 rs_update_rate_tbl(struct iwl_priv *priv,
-			      struct iwl_rxon_context *ctx,
-				struct iwl_lq_sta *lq_sta,
-				struct iwl_scale_tbl_info *tbl,
-				int index, u8 is_green)
+static void rs_update_rate_tbl(struct iwl_priv *priv,
+			       struct iwl_rxon_context *ctx,
+			       struct iwl_lq_sta *lq_sta,
+			       struct iwl_scale_tbl_info *tbl,
+			       int index, u8 is_green)
 {
 	u32 rate;
 
@@ -2181,8 +2211,6 @@
 	rate = rate_n_flags_from_tbl(priv, tbl, index, is_green);
 	rs_fill_link_cmd(priv, lq_sta, rate);
 	iwl_send_lq_cmd(priv, ctx, &lq_sta->lq, CMD_ASYNC, false);
-
-	return rate;
 }
 
 /*
@@ -2211,7 +2239,6 @@
 	u8 update_lq = 0;
 	struct iwl_scale_tbl_info *tbl, *tbl1;
 	u16 rate_scale_index_msk = 0;
-	u32 rate;
 	u8 is_green = 0;
 	u8 active_tbl = 0;
 	u8 done_search = 0;
@@ -2298,8 +2325,8 @@
 			tbl = &(lq_sta->lq_info[lq_sta->active_tbl]);
 			/* get "active" rate info */
 			index = iwl_hwrate_to_plcp_idx(tbl->current_rate);
-			rate = rs_update_rate_tbl(priv, ctx, lq_sta,
-						  tbl, index, is_green);
+			rs_update_rate_tbl(priv, ctx, lq_sta, tbl,
+					   index, is_green);
 		}
 		return;
 	}
@@ -2540,8 +2567,7 @@
 lq_update:
 	/* Replace uCode's rate table for the destination station. */
 	if (update_lq)
-		rate = rs_update_rate_tbl(priv, ctx, lq_sta,
-					  tbl, index, is_green);
+		rs_update_rate_tbl(priv, ctx, lq_sta, tbl, index, is_green);
 
 	if (iwl_tx_ant_restriction(priv) == IWL_ANT_OK_MULTI) {
 		/* Should we stay with this modulation mode,
@@ -2770,16 +2796,13 @@
 static void *rs_alloc_sta(void *priv_rate, struct ieee80211_sta *sta,
 			  gfp_t gfp)
 {
-	struct iwl_lq_sta *lq_sta;
 	struct iwl_station_priv *sta_priv = (struct iwl_station_priv *) sta->drv_priv;
 	struct iwl_priv *priv;
 
 	priv = (struct iwl_priv *)priv_rate;
 	IWL_DEBUG_RATE(priv, "create station rate scale window\n");
 
-	lq_sta = &sta_priv->lq_sta;
-
-	return lq_sta;
+	return &sta_priv->lq_sta;
 }
 
 /*
@@ -2873,6 +2896,7 @@
 		lq_sta->last_txrate_idx += IWL_FIRST_OFDM_RATE;
 	lq_sta->is_agg = 0;
 
+	priv->dbg_fixed_rate = 0;
 #ifdef CONFIG_MAC80211_DEBUGFS
 	lq_sta->dbg_fixed_rate = 0;
 #endif
@@ -2912,7 +2936,8 @@
 		ant_toggle_cnt = 1;
 		repeat_rate = IWL_NUMBER_TRY;
 	} else {
-		repeat_rate = IWL_HT_NUMBER_TRY;
+		repeat_rate = min(IWL_HT_NUMBER_TRY,
+				  LINK_QUAL_AGG_DISABLE_START_DEF - 1);
 	}
 
 	lq_cmd->general_params.mimo_delimiter =
@@ -3046,7 +3071,6 @@
 	IWL_DEBUG_RATE(priv, "leave\n");
 }
 
-
 #ifdef CONFIG_MAC80211_DEBUGFS
 static int open_file_generic(struct inode *inode, struct file *file)
 {
@@ -3071,6 +3095,7 @@
 			IWL_DEBUG_RATE(priv, "Fixed rate ON\n");
 		} else {
 			lq_sta->dbg_fixed_rate = 0;
+			priv->dbg_fixed_rate = 0;
 			IWL_ERR(priv,
 			    "Invalid antenna selection 0x%X, Valid is 0x%X\n",
 			    ant_sel_tx, valid_tx_ant);
@@ -3087,11 +3112,9 @@
 	struct iwl_lq_sta *lq_sta = file->private_data;
 	struct iwl_priv *priv;
 	char buf[64];
-	int buf_size;
+	size_t buf_size;
 	u32 parsed_rate;
-	struct iwl_station_priv *sta_priv =
-		container_of(lq_sta, struct iwl_station_priv, lq_sta);
-	struct iwl_rxon_context *ctx = sta_priv->common.ctx;
+
 
 	priv = lq_sta->drv;
 	memset(buf, 0, sizeof(buf));
@@ -3100,23 +3123,11 @@
 		return -EFAULT;
 
 	if (sscanf(buf, "%x", &parsed_rate) == 1)
-		lq_sta->dbg_fixed_rate = parsed_rate;
+		priv->dbg_fixed_rate = lq_sta->dbg_fixed_rate = parsed_rate;
 	else
-		lq_sta->dbg_fixed_rate = 0;
-
-	lq_sta->active_legacy_rate = 0x0FFF;	/* 1 - 54 MBits, includes CCK */
-	lq_sta->active_siso_rate   = 0x1FD0;	/* 6 - 60 MBits, no 9, no CCK */
-	lq_sta->active_mimo2_rate  = 0x1FD0;	/* 6 - 60 MBits, no 9, no CCK */
-	lq_sta->active_mimo3_rate  = 0x1FD0;	/* 6 - 60 MBits, no 9, no CCK */
-
-	IWL_DEBUG_RATE(priv, "sta_id %d rate 0x%X\n",
-		lq_sta->lq.sta_id, lq_sta->dbg_fixed_rate);
+		priv->dbg_fixed_rate = lq_sta->dbg_fixed_rate = 0;
 
-	if (lq_sta->dbg_fixed_rate) {
-		rs_fill_link_cmd(NULL, lq_sta, lq_sta->dbg_fixed_rate);
-		iwl_send_lq_cmd(lq_sta->drv, ctx, &lq_sta->lq, CMD_ASYNC,
-				false);
-	}
+	rs_program_fix_rate(priv, lq_sta);
 
 	return count;
 }
@@ -3144,7 +3155,7 @@
 			lq_sta->total_failed, lq_sta->total_success,
 			lq_sta->active_legacy_rate);
 	desc += sprintf(buff+desc, "fixed rate 0x%X\n",
-			lq_sta->dbg_fixed_rate);
+			priv->dbg_fixed_rate);
 	desc += sprintf(buff+desc, "valid_tx_ant %s%s%s\n",
 	    (priv->hw_params.valid_tx_ant & ANT_A) ? "ANT_A," : "",
 	    (priv->hw_params.valid_tx_ant & ANT_B) ? "ANT_B," : "",
@@ -3255,15 +3266,10 @@
 static ssize_t rs_sta_dbgfs_rate_scale_data_read(struct file *file,
 			char __user *user_buf, size_t count, loff_t *ppos)
 {
-	char buff[120];
-	int desc = 0;
-	ssize_t ret;
-
 	struct iwl_lq_sta *lq_sta = file->private_data;
-	struct iwl_priv *priv;
 	struct iwl_scale_tbl_info *tbl = &lq_sta->lq_info[lq_sta->active_tbl];
-
-	priv = lq_sta->drv;
+	char buff[120];
+	int desc = 0;
 
 	if (is_Ht(tbl->lq_type))
 		desc += sprintf(buff+desc,
@@ -3274,8 +3280,7 @@
 				"Bit Rate= %d Mb/s\n",
 				iwl_rates[lq_sta->last_txrate_idx].ieee >> 1);
 
-	ret = simple_read_from_buffer(user_buf, count, ppos, buff, desc);
-	return ret;
+	return simple_read_from_buffer(user_buf, count, ppos, buff, desc);
 }
 
 static const struct file_operations rs_sta_dbgfs_rate_scale_data_ops = {
diff -druN linux-2.6.39-libre/drivers/net/wireless/iwlwifi/iwl-agn-rs.h linux-3.0-rc7-libre/drivers/net/wireless/iwlwifi/iwl-agn-rs.h
--- linux-2.6.39-libre/drivers/net/wireless/iwlwifi/iwl-agn-rs.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/iwlwifi/iwl-agn-rs.h	2011-07-11 19:51:52.000000000 -0400
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2003 - 2011 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
@@ -41,20 +41,6 @@
 	u8 next_rs_tgg;  /* next rate used in TGG rs algo */
 };
 
-struct iwl3945_rate_info {
-	u8 plcp;		/* uCode API:  IWL_RATE_6M_PLCP, etc. */
-	u8 ieee;		/* MAC header:  IWL_RATE_6M_IEEE, etc. */
-	u8 prev_ieee;		/* previous rate in IEEE speeds */
-	u8 next_ieee;		/* next rate in IEEE speeds */
-	u8 prev_rs;		/* previous rate used in rs algo */
-	u8 next_rs;		/* next rate used in rs algo */
-	u8 prev_rs_tgg;		/* previous rate used in TGG rs algo */
-	u8 next_rs_tgg;		/* next rate used in TGG rs algo */
-	u8 table_rs_index;	/* index in rate scale table cmd */
-	u8 prev_table_rs;	/* prev in rate table cmd */
-};
-
-
 /*
  * These serve as indexes into
  * struct iwl_rate_info iwl_rates[IWL_RATE_COUNT];
@@ -75,7 +61,6 @@
 	IWL_RATE_60M_INDEX,
 	IWL_RATE_COUNT, /*FIXME:RS:change to IWL_RATE_INDEX_COUNT,*/
 	IWL_RATE_COUNT_LEGACY = IWL_RATE_COUNT - 1,	/* Excluding 60M */
-	IWL_RATE_COUNT_3945 = IWL_RATE_COUNT - 1,
 	IWL_RATE_INVM_INDEX = IWL_RATE_COUNT,
 	IWL_RATE_INVALID = IWL_RATE_COUNT,
 };
@@ -98,7 +83,6 @@
 
 enum {
 	IWL_FIRST_OFDM_RATE = IWL_RATE_6M_INDEX,
-	IWL39_LAST_OFDM_RATE = IWL_RATE_54M_INDEX,
 	IWL_LAST_OFDM_RATE = IWL_RATE_60M_INDEX,
 	IWL_FIRST_CCK_RATE = IWL_RATE_1M_INDEX,
 	IWL_LAST_CCK_RATE = IWL_RATE_11M_INDEX,
@@ -213,7 +197,6 @@
 	 IWL_CCK_BASIC_RATES_MASK)
 
 #define IWL_RATES_MASK ((1 << IWL_RATE_COUNT) - 1)
-#define IWL_RATES_MASK_3945 ((1 << IWL_RATE_COUNT_3945) - 1)
 
 #define IWL_INVALID_VALUE    -1
 
@@ -453,19 +436,9 @@
 }
 
 
-/**
- * iwl3945_rate_scale_init - Initialize the rate scale table based on assoc info
- *
- * The specific throughput table used is based on the type of network
- * the associated with, including A, B, G, and G w/ TGG protection
- */
-extern void iwl3945_rate_scale_init(struct ieee80211_hw *hw, s32 sta_id);
-
 /* Initialize station's rate scaling information after adding station */
 extern void iwl_rs_rate_init(struct iwl_priv *priv,
 			     struct ieee80211_sta *sta, u8 sta_id);
-extern void iwl3945_rs_rate_init(struct iwl_priv *priv,
-				 struct ieee80211_sta *sta, u8 sta_id);
 
 /**
  * iwl_rate_control_register - Register the rate control algorithm callbacks
@@ -478,7 +451,6 @@
  *
  */
 extern int iwlagn_rate_control_register(void);
-extern int iwl3945_rate_control_register(void);
 
 /**
  * iwl_rate_control_unregister - Unregister the rate control callbacks
@@ -487,6 +459,5 @@
  * the driver is unloaded.
  */
 extern void iwlagn_rate_control_unregister(void);
-extern void iwl3945_rate_control_unregister(void);
 
 #endif /* __iwl_agn__rs__ */
diff -druN linux-2.6.39-libre/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c linux-3.0-rc7-libre/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c
--- linux-2.6.39-libre/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c	2011-07-11 19:51:52.000000000 -0400
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2003 - 2011 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
@@ -29,6 +29,7 @@
 #include "iwl-sta.h"
 #include "iwl-core.h"
 #include "iwl-agn-calib.h"
+#include "iwl-helpers.h"
 
 static int iwlagn_disable_bss(struct iwl_priv *priv,
 			      struct iwl_rxon_context *ctx,
@@ -57,8 +58,9 @@
 	u8 old_dev_type = send->dev_type;
 	int ret;
 
-	iwlagn_init_notification_wait(priv, &disable_wait, NULL,
-				      REPLY_WIPAN_DEACTIVATION_COMPLETE);
+	iwlagn_init_notification_wait(priv, &disable_wait,
+				      REPLY_WIPAN_DEACTIVATION_COMPLETE,
+				      NULL, NULL);
 
 	send->filter_flags &= ~RXON_FILTER_ASSOC_MSK;
 	send->dev_type = RXON_DEV_TYPE_P2P;
@@ -71,13 +73,9 @@
 		IWL_ERR(priv, "Error disabling PAN (%d)\n", ret);
 		iwlagn_remove_notification(priv, &disable_wait);
 	} else {
-		signed long wait_res;
-
-		wait_res = iwlagn_wait_notification(priv, &disable_wait, HZ);
-		if (wait_res == 0) {
+		ret = iwlagn_wait_notification(priv, &disable_wait, HZ);
+		if (ret)
 			IWL_ERR(priv, "Timed out waiting for PAN disable\n");
-			ret = -EIO;
-		}
 	}
 
 	return ret;
@@ -123,6 +121,151 @@
 	return iwlagn_send_beacon_cmd(priv);
 }
 
+static int iwlagn_send_rxon_assoc(struct iwl_priv *priv,
+			   struct iwl_rxon_context *ctx)
+{
+	int ret = 0;
+	struct iwl_rxon_assoc_cmd rxon_assoc;
+	const struct iwl_rxon_cmd *rxon1 = &ctx->staging;
+	const struct iwl_rxon_cmd *rxon2 = &ctx->active;
+
+	if ((rxon1->flags == rxon2->flags) &&
+	    (rxon1->filter_flags == rxon2->filter_flags) &&
+	    (rxon1->cck_basic_rates == rxon2->cck_basic_rates) &&
+	    (rxon1->ofdm_ht_single_stream_basic_rates ==
+	     rxon2->ofdm_ht_single_stream_basic_rates) &&
+	    (rxon1->ofdm_ht_dual_stream_basic_rates ==
+	     rxon2->ofdm_ht_dual_stream_basic_rates) &&
+	    (rxon1->ofdm_ht_triple_stream_basic_rates ==
+	     rxon2->ofdm_ht_triple_stream_basic_rates) &&
+	    (rxon1->acquisition_data == rxon2->acquisition_data) &&
+	    (rxon1->rx_chain == rxon2->rx_chain) &&
+	    (rxon1->ofdm_basic_rates == rxon2->ofdm_basic_rates)) {
+		IWL_DEBUG_INFO(priv, "Using current RXON_ASSOC.  Not resending.\n");
+		return 0;
+	}
+
+	rxon_assoc.flags = ctx->staging.flags;
+	rxon_assoc.filter_flags = ctx->staging.filter_flags;
+	rxon_assoc.ofdm_basic_rates = ctx->staging.ofdm_basic_rates;
+	rxon_assoc.cck_basic_rates = ctx->staging.cck_basic_rates;
+	rxon_assoc.reserved1 = 0;
+	rxon_assoc.reserved2 = 0;
+	rxon_assoc.reserved3 = 0;
+	rxon_assoc.ofdm_ht_single_stream_basic_rates =
+	    ctx->staging.ofdm_ht_single_stream_basic_rates;
+	rxon_assoc.ofdm_ht_dual_stream_basic_rates =
+	    ctx->staging.ofdm_ht_dual_stream_basic_rates;
+	rxon_assoc.rx_chain_select_flags = ctx->staging.rx_chain;
+	rxon_assoc.ofdm_ht_triple_stream_basic_rates =
+		 ctx->staging.ofdm_ht_triple_stream_basic_rates;
+	rxon_assoc.acquisition_data = ctx->staging.acquisition_data;
+
+	ret = iwl_send_cmd_pdu_async(priv, ctx->rxon_assoc_cmd,
+				     sizeof(rxon_assoc), &rxon_assoc, NULL);
+	if (ret)
+		return ret;
+
+	return ret;
+}
+
+static int iwlagn_rxon_disconn(struct iwl_priv *priv,
+			       struct iwl_rxon_context *ctx)
+{
+	int ret;
+	struct iwl_rxon_cmd *active = (void *)&ctx->active;
+
+	if (ctx->ctxid == IWL_RXON_CTX_BSS)
+		ret = iwlagn_disable_bss(priv, ctx, &ctx->staging);
+	else
+		ret = iwlagn_disable_pan(priv, ctx, &ctx->staging);
+	if (ret)
+		return ret;
+
+	/*
+	 * Un-assoc RXON clears the station table and WEP
+	 * keys, so we have to restore those afterwards.
+	 */
+	iwl_clear_ucode_stations(priv, ctx);
+	iwl_restore_stations(priv, ctx);
+	ret = iwl_restore_default_wep_keys(priv, ctx);
+	if (ret) {
+		IWL_ERR(priv, "Failed to restore WEP keys (%d)\n", ret);
+		return ret;
+	}
+
+	memcpy(active, &ctx->staging, sizeof(*active));
+	return 0;
+}
+
+static int iwlagn_rxon_connect(struct iwl_priv *priv,
+			       struct iwl_rxon_context *ctx)
+{
+	int ret;
+	struct iwl_rxon_cmd *active = (void *)&ctx->active;
+
+	/* RXON timing must be before associated RXON */
+	ret = iwl_send_rxon_timing(priv, ctx);
+	if (ret) {
+		IWL_ERR(priv, "Failed to send timing (%d)!\n", ret);
+		return ret;
+	}
+	/* QoS info may be cleared by previous un-assoc RXON */
+	iwlagn_update_qos(priv, ctx);
+
+	/*
+	 * We'll run into this code path when beaconing is
+	 * enabled, but then we also need to send the beacon
+	 * to the device.
+	 */
+	if (ctx->vif && (ctx->vif->type == NL80211_IFTYPE_AP)) {
+		ret = iwlagn_update_beacon(priv, ctx->vif);
+		if (ret) {
+			IWL_ERR(priv,
+				"Error sending required beacon (%d)!\n",
+				ret);
+			return ret;
+		}
+	}
+
+	priv->start_calib = 0;
+	/*
+	 * Apply the new configuration.
+	 *
+	 * Associated RXON doesn't clear the station table in uCode,
+	 * so we don't need to restore stations etc. after this.
+	 */
+	ret = iwl_send_cmd_pdu(priv, ctx->rxon_cmd,
+		      sizeof(struct iwl_rxon_cmd), &ctx->staging);
+	if (ret) {
+		IWL_ERR(priv, "Error setting new RXON (%d)\n", ret);
+		return ret;
+	}
+	memcpy(active, &ctx->staging, sizeof(*active));
+
+	iwl_reprogram_ap_sta(priv, ctx);
+
+	/* IBSS beacon needs to be sent after setting assoc */
+	if (ctx->vif && (ctx->vif->type == NL80211_IFTYPE_ADHOC))
+		if (iwlagn_update_beacon(priv, ctx->vif))
+			IWL_ERR(priv, "Error sending IBSS beacon\n");
+	iwl_init_sensitivity(priv);
+
+	/*
+	 * If we issue a new RXON command which required a tune then
+	 * we must send a new TXPOWER command or we won't be able to
+	 * Tx any frames.
+	 *
+	 * It's expected we set power here if channel is changing.
+	 */
+	ret = iwl_set_tx_power(priv, priv->tx_power_next, true);
+	if (ret) {
+		IWL_ERR(priv, "Error sending TX power (%d)\n", ret);
+		return ret;
+	}
+	return 0;
+}
+
 /**
  * iwlagn_commit_rxon - commit staging_rxon to hardware
  *
@@ -130,13 +273,22 @@
  * the active_rxon structure is updated with the new data.  This
  * function correctly transitions out of the RXON_ASSOC_MSK state if
  * a HW tune is required based on the RXON structure changes.
+ *
+ * The connect/disconnect flow should be as the following:
+ *
+ * 1. make sure send RXON command with association bit unset if not connect
+ *	this should include the channel and the band for the candidate
+ *	to be connected to
+ * 2. Add Station before RXON association with the AP
+ * 3. RXON_timing has to send before RXON for connection
+ * 4. full RXON command - associated bit set
+ * 5. use RXON_ASSOC command to update any flags changes
  */
 int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
 {
 	/* cast away the const for active_rxon in this function */
 	struct iwl_rxon_cmd *active = (void *)&ctx->active;
 	bool new_assoc = !!(ctx->staging.filter_flags & RXON_FILTER_ASSOC_MSK);
-	bool old_assoc = !!(ctx->active.filter_flags & RXON_FILTER_ASSOC_MSK);
 	int ret;
 
 	lockdep_assert_held(&priv->mutex);
@@ -173,12 +325,21 @@
 			return 0;
 	}
 
+	/*
+	 * force CTS-to-self frames protection if RTS-CTS is not preferred
+	 * one aggregation protection method
+	 */
+	if (!(priv->cfg->ht_params &&
+	      priv->cfg->ht_params->use_rts_for_aggregation))
+		ctx->staging.flags |= RXON_FLG_SELF_CTS_EN;
+
 	if ((ctx->vif && ctx->vif->bss_conf.use_short_slot) ||
 	    !(ctx->staging.flags & RXON_FLG_BAND_24G_MSK))
 		ctx->staging.flags |= RXON_FLG_SHORT_SLOT_MSK;
 	else
 		ctx->staging.flags &= ~RXON_FLG_SHORT_SLOT_MSK;
 
+	iwl_print_rx_config_cmd(priv, ctx);
 	ret = iwl_check_rxon_cmd(priv, ctx);
 	if (ret) {
 		IWL_ERR(priv, "Invalid RXON configuration. Not committing.\n");
@@ -189,10 +350,10 @@
 	 * receive commit_rxon request
 	 * abort any previous channel switch if still in process
 	 */
-	if (priv->switch_rxon.switch_in_progress &&
-	    (priv->switch_rxon.channel != ctx->staging.channel)) {
+	if (test_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->status) &&
+	    (priv->switch_channel != ctx->staging.channel)) {
 		IWL_DEBUG_11H(priv, "abort channel switch on %d\n",
-		      le16_to_cpu(priv->switch_rxon.channel));
+			      le16_to_cpu(priv->switch_channel));
 		iwl_chswitch_done(priv, false);
 	}
 
@@ -202,14 +363,18 @@
 	 * and other flags for the current radio configuration.
 	 */
 	if (!iwl_full_rxon_required(priv, ctx)) {
-		ret = iwl_send_rxon_assoc(priv, ctx);
+		ret = iwlagn_send_rxon_assoc(priv, ctx);
 		if (ret) {
 			IWL_ERR(priv, "Error setting RXON_ASSOC (%d)\n", ret);
 			return ret;
 		}
 
 		memcpy(active, &ctx->staging, sizeof(*active));
-		iwl_print_rx_config_cmd(priv, ctx);
+		/*
+		 * We do not commit tx power settings while channel changing,
+		 * do it now if after settings changed.
+		 */
+		iwl_set_tx_power(priv, priv->tx_power_next, false);
 		return 0;
 	}
 
@@ -219,7 +384,7 @@
 			return ret;
 	}
 
-	iwl_set_rxon_hwcrypto(priv, ctx, !priv->cfg->mod_params->sw_crypto);
+	iwl_set_rxon_hwcrypto(priv, ctx, !iwlagn_mod_params.sw_crypto);
 
 	IWL_DEBUG_INFO(priv,
 		       "Going to commit RXON\n"
@@ -236,93 +401,12 @@
 	 * AP station must be done after the BSSID is set to correctly
 	 * set up filters in the device.
 	 */
-	if ((old_assoc && new_assoc) || !new_assoc) {
-		if (ctx->ctxid == IWL_RXON_CTX_BSS)
-			ret = iwlagn_disable_bss(priv, ctx, &ctx->staging);
-		else
-			ret = iwlagn_disable_pan(priv, ctx, &ctx->staging);
-		if (ret)
-			return ret;
-
-		memcpy(active, &ctx->staging, sizeof(*active));
-
-		/*
-		 * Un-assoc RXON clears the station table and WEP
-		 * keys, so we have to restore those afterwards.
-		 */
-		iwl_clear_ucode_stations(priv, ctx);
-		iwl_restore_stations(priv, ctx);
-		ret = iwl_restore_default_wep_keys(priv, ctx);
-		if (ret) {
-			IWL_ERR(priv, "Failed to restore WEP keys (%d)\n", ret);
-			return ret;
-		}
-	}
-
-	/* RXON timing must be before associated RXON */
-	ret = iwl_send_rxon_timing(priv, ctx);
-	if (ret) {
-		IWL_ERR(priv, "Failed to send timing (%d)!\n", ret);
+	ret = iwlagn_rxon_disconn(priv, ctx);
+	if (ret)
 		return ret;
-	}
-
-	if (new_assoc) {
-		/* QoS info may be cleared by previous un-assoc RXON */
-		iwlagn_update_qos(priv, ctx);
-
-		/*
-		 * We'll run into this code path when beaconing is
-		 * enabled, but then we also need to send the beacon
-		 * to the device.
-		 */
-		if (ctx->vif && (ctx->vif->type == NL80211_IFTYPE_AP)) {
-			ret = iwlagn_update_beacon(priv, ctx->vif);
-			if (ret) {
-				IWL_ERR(priv,
-					"Error sending required beacon (%d)!\n",
-					ret);
-				return ret;
-			}
-		}
-
-		priv->start_calib = 0;
-		/*
-		 * Apply the new configuration.
-		 *
-		 * Associated RXON doesn't clear the station table in uCode,
-		 * so we don't need to restore stations etc. after this.
-		 */
-		ret = iwl_send_cmd_pdu(priv, ctx->rxon_cmd,
-			      sizeof(struct iwl_rxon_cmd), &ctx->staging);
-		if (ret) {
-			IWL_ERR(priv, "Error setting new RXON (%d)\n", ret);
-			return ret;
-		}
-		memcpy(active, &ctx->staging, sizeof(*active));
 
-		iwl_reprogram_ap_sta(priv, ctx);
-
-		/* IBSS beacon needs to be sent after setting assoc */
-		if (ctx->vif && (ctx->vif->type == NL80211_IFTYPE_ADHOC))
-			if (iwlagn_update_beacon(priv, ctx->vif))
-				IWL_ERR(priv, "Error sending IBSS beacon\n");
-	}
-
-	iwl_print_rx_config_cmd(priv, ctx);
-
-	iwl_init_sensitivity(priv);
-
-	/*
-	 * If we issue a new RXON command which required a tune then we must
-	 * send a new TXPOWER command or we won't be able to Tx any frames.
-	 *
-	 * It's expected we set power here if channel is changing.
-	 */
-	ret = iwl_set_tx_power(priv, priv->tx_power_next, true);
-	if (ret) {
-		IWL_ERR(priv, "Error sending TX power (%d)\n", ret);
-		return ret;
-	}
+	if (new_assoc)
+		return iwlagn_rxon_connect(priv, ctx);
 
 	return 0;
 }
@@ -595,6 +679,18 @@
 			priv->timestamp = bss_conf->timestamp;
 			ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK;
 		} else {
+			/*
+			 * If we disassociate while there are pending
+			 * frames, just wake up the queues and let the
+			 * frames "escape" ... This shouldn't really
+			 * be happening to start with, but we should
+			 * not get stuck in this case either since it
+			 * can happen if userspace gets confused.
+			 */
+			if (ctx->last_tx_rejected) {
+				ctx->last_tx_rejected = false;
+				iwl_wake_any_queue(priv, ctx);
+			}
 			ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
 		}
 	}
diff -druN linux-2.6.39-libre/drivers/net/wireless/iwlwifi/iwl-agn-sta.c linux-3.0-rc7-libre/drivers/net/wireless/iwlwifi/iwl-agn-sta.c
--- linux-2.6.39-libre/drivers/net/wireless/iwlwifi/iwl-agn-sta.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/iwlwifi/iwl-agn-sta.c	2011-07-11 19:51:52.000000000 -0400
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2003 - 2011 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.
@@ -144,7 +144,7 @@
 	size_t cmd_size  = sizeof(struct iwl_wep_cmd);
 	struct iwl_host_cmd cmd = {
 		.id = ctx->wep_key_cmd,
-		.data = wep_cmd,
+		.data = { wep_cmd, },
 		.flags = CMD_SYNC,
 	};
 
@@ -172,7 +172,7 @@
 
 	cmd_size += sizeof(struct iwl_wep_key) * WEP_KEYS_MAX;
 
-	cmd.len = cmd_size;
+	cmd.len[0] = cmd_size;
 
 	if (not_empty || send_if_empty)
 		return iwl_send_cmd(priv, &cmd);
@@ -474,7 +474,7 @@
 	memset(&priv->stations[sta_id].keyinfo, 0,
 					sizeof(struct iwl_hw_key));
 	memset(&priv->stations[sta_id].sta.key, 0,
-					sizeof(struct iwl4965_keyinfo));
+					sizeof(struct iwl_keyinfo));
 	priv->stations[sta_id].sta.key.key_flags =
 			STA_KEY_FLG_NO_ENC | STA_KEY_FLG_INVALID;
 	priv->stations[sta_id].sta.key.key_offset = WEP_INVALID_OFFSET;
diff -druN linux-2.6.39-libre/drivers/net/wireless/iwlwifi/iwl-agn-tt.c linux-3.0-rc7-libre/drivers/net/wireless/iwlwifi/iwl-agn-tt.c
--- linux-2.6.39-libre/drivers/net/wireless/iwlwifi/iwl-agn-tt.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/iwlwifi/iwl-agn-tt.c	2011-07-11 19:51:52.000000000 -0400
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2007 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2007 - 2011 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 -druN linux-2.6.39-libre/drivers/net/wireless/iwlwifi/iwl-agn-tt.h linux-3.0-rc7-libre/drivers/net/wireless/iwlwifi/iwl-agn-tt.h
--- linux-2.6.39-libre/drivers/net/wireless/iwlwifi/iwl-agn-tt.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/iwlwifi/iwl-agn-tt.h	2011-07-11 19:51:52.000000000 -0400
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2007 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2007 - 2011 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 -druN linux-2.6.39-libre/drivers/net/wireless/iwlwifi/iwl-agn-tx.c linux-3.0-rc7-libre/drivers/net/wireless/iwlwifi/iwl-agn-tx.c
--- linux-2.6.39-libre/drivers/net/wireless/iwlwifi/iwl-agn-tx.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/iwlwifi/iwl-agn-tx.c	2011-07-11 19:51:52.000000000 -0400
@@ -2,7 +2,7 @@
  *
  * GPL LICENSE SUMMARY
  *
- * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2008 - 2011 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
@@ -98,9 +98,9 @@
 /**
  * iwlagn_txq_update_byte_cnt_tbl - Set up entry in Tx byte-count array
  */
-void iwlagn_txq_update_byte_cnt_tbl(struct iwl_priv *priv,
-					    struct iwl_tx_queue *txq,
-					    u16 byte_cnt)
+static void iwlagn_txq_update_byte_cnt_tbl(struct iwl_priv *priv,
+					   struct iwl_tx_queue *txq,
+					   u16 byte_cnt)
 {
 	struct iwlagn_scd_bc_tbl *scd_bc_tbl = priv->scd_bc_tbls.addr;
 	int write_ptr = txq->q.write_ptr;
@@ -112,21 +112,19 @@
 
 	WARN_ON(len > 0xFFF || write_ptr >= TFD_QUEUE_SIZE_MAX);
 
-	if (txq_id != priv->cmd_queue) {
-		sta_id = txq->cmd[txq->q.write_ptr]->cmd.tx.sta_id;
-		sec_ctl = txq->cmd[txq->q.write_ptr]->cmd.tx.sec_ctl;
+	sta_id = txq->cmd[txq->q.write_ptr]->cmd.tx.sta_id;
+	sec_ctl = txq->cmd[txq->q.write_ptr]->cmd.tx.sec_ctl;
 
-		switch (sec_ctl & TX_CMD_SEC_MSK) {
-		case TX_CMD_SEC_CCM:
-			len += CCMP_MIC_LEN;
-			break;
-		case TX_CMD_SEC_TKIP:
-			len += TKIP_ICV_LEN;
-			break;
-		case TX_CMD_SEC_WEP:
-			len += WEP_IV_LEN + WEP_ICV_LEN;
-			break;
-		}
+	switch (sec_ctl & TX_CMD_SEC_MSK) {
+	case TX_CMD_SEC_CCM:
+		len += CCMP_MIC_LEN;
+		break;
+	case TX_CMD_SEC_TKIP:
+		len += TKIP_ICV_LEN;
+		break;
+	case TX_CMD_SEC_WEP:
+		len += WEP_IV_LEN + WEP_ICV_LEN;
+		break;
 	}
 
 	bc_ent = cpu_to_le16((len & 0xFFF) | (sta_id << 12));
@@ -138,8 +136,8 @@
 			tfd_offset[TFD_QUEUE_SIZE_MAX + write_ptr] = bc_ent;
 }
 
-void iwlagn_txq_inval_byte_cnt_tbl(struct iwl_priv *priv,
-					   struct iwl_tx_queue *txq)
+static void iwlagn_txq_inval_byte_cnt_tbl(struct iwl_priv *priv,
+					  struct iwl_tx_queue *txq)
 {
 	struct iwlagn_scd_bc_tbl *scd_bc_tbl = priv->scd_bc_tbls.addr;
 	int txq_id = txq->q.id;
@@ -222,13 +220,8 @@
 		       scd_retry ? "BA" : "AC/CMD", txq_id, tx_fifo_id);
 }
 
-int iwlagn_txq_agg_enable(struct iwl_priv *priv, int txq_id,
-			  int tx_fifo, int sta_id, int tid, u16 ssn_idx)
+static int iwlagn_txq_agg_enable(struct iwl_priv *priv, int txq_id, int sta_id, int tid)
 {
-	unsigned long flags;
-	u16 ra_tid;
-	int ret;
-
 	if ((IWLAGN_FIRST_AMPDU_QUEUE > txq_id) ||
 	    (IWLAGN_FIRST_AMPDU_QUEUE +
 		priv->cfg->base_params->num_of_ampdu_queues <= txq_id)) {
@@ -240,12 +233,33 @@
 		return -EINVAL;
 	}
 
-	ra_tid = BUILD_RAxTID(sta_id, tid);
-
 	/* Modify device's station table to Tx this TID */
-	ret = iwl_sta_tx_modify_enable_tid(priv, sta_id, tid);
-	if (ret)
-		return ret;
+	return iwl_sta_tx_modify_enable_tid(priv, sta_id, tid);
+}
+
+void iwlagn_txq_agg_queue_setup(struct iwl_priv *priv,
+				struct ieee80211_sta *sta,
+				int tid, int frame_limit)
+{
+	int sta_id, tx_fifo, txq_id, ssn_idx;
+	u16 ra_tid;
+	unsigned long flags;
+	struct iwl_tid_data *tid_data;
+
+	sta_id = iwl_sta_id(sta);
+	if (WARN_ON(sta_id == IWL_INVALID_STATION))
+		return;
+	if (WARN_ON(tid >= MAX_TID_COUNT))
+		return;
+
+	spin_lock_irqsave(&priv->sta_lock, flags);
+	tid_data = &priv->stations[sta_id].tid[tid];
+	ssn_idx = SEQ_TO_SN(tid_data->seq_number);
+	txq_id = tid_data->agg.txq_id;
+	tx_fifo = tid_data->agg.tx_fifo;
+	spin_unlock_irqrestore(&priv->sta_lock, flags);
+
+	ra_tid = BUILD_RAxTID(sta_id, tid);
 
 	spin_lock_irqsave(&priv->lock, flags);
 
@@ -271,10 +285,10 @@
 	iwl_write_targ_mem(priv, priv->scd_base_addr +
 			IWLAGN_SCD_CONTEXT_QUEUE_OFFSET(txq_id) +
 			sizeof(u32),
-			((SCD_WIN_SIZE <<
+			((frame_limit <<
 			IWLAGN_SCD_QUEUE_CTX_REG2_WIN_SIZE_POS) &
 			IWLAGN_SCD_QUEUE_CTX_REG2_WIN_SIZE_MSK) |
-			((SCD_FRAME_LIMIT <<
+			((frame_limit <<
 			IWLAGN_SCD_QUEUE_CTX_REG2_FRAME_LIMIT_POS) &
 			IWLAGN_SCD_QUEUE_CTX_REG2_FRAME_LIMIT_MSK));
 
@@ -284,12 +298,10 @@
 	iwlagn_tx_queue_set_status(priv, &priv->txq[txq_id], tx_fifo, 1);
 
 	spin_unlock_irqrestore(&priv->lock, flags);
-
-	return 0;
 }
 
-int iwlagn_txq_agg_disable(struct iwl_priv *priv, u16 txq_id,
-			   u16 ssn_idx, u8 tx_fifo)
+static int iwlagn_txq_agg_disable(struct iwl_priv *priv, u16 txq_id,
+				  u16 ssn_idx, u8 tx_fifo)
 {
 	if ((IWLAGN_FIRST_AMPDU_QUEUE > txq_id) ||
 	    (IWLAGN_FIRST_AMPDU_QUEUE +
@@ -525,7 +537,7 @@
 	struct iwl_tx_cmd *tx_cmd;
 	struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
 	int txq_id;
-	dma_addr_t phys_addr;
+	dma_addr_t phys_addr = 0;
 	dma_addr_t txcmd_phys;
 	dma_addr_t scratch_phys;
 	u16 len, firstlen, secondlen;
@@ -552,7 +564,7 @@
 	spin_lock_irqsave(&priv->lock, flags);
 	if (iwl_is_rfkill(priv)) {
 		IWL_DEBUG_DROP(priv, "Dropping - RF KILL\n");
-		goto drop_unlock;
+		goto drop_unlock_priv;
 	}
 
 	fc = hdr->frame_control;
@@ -577,7 +589,7 @@
 		if (sta_id == IWL_INVALID_STATION) {
 			IWL_DEBUG_DROP(priv, "Dropping - INVALID STATION: %pM\n",
 				       hdr->addr1);
-			goto drop_unlock;
+			goto drop_unlock_priv;
 		}
 	}
 
@@ -621,10 +633,10 @@
 	if (ieee80211_is_data_qos(fc)) {
 		qc = ieee80211_get_qos_ctl(hdr);
 		tid = qc[0] & IEEE80211_QOS_CTL_TID_MASK;
-		if (WARN_ON_ONCE(tid >= MAX_TID_COUNT)) {
-			spin_unlock(&priv->sta_lock);
-			goto drop_unlock;
-		}
+
+		if (WARN_ON_ONCE(tid >= MAX_TID_COUNT))
+			goto drop_unlock_sta;
+
 		seq_number = priv->stations[sta_id].tid[tid].seq_number;
 		seq_number &= IEEE80211_SCTL_SEQ;
 		hdr->seq_ctrl = hdr->seq_ctrl &
@@ -642,18 +654,8 @@
 	txq = &priv->txq[txq_id];
 	q = &txq->q;
 
-	if (unlikely(iwl_queue_space(q) < q->high_mark)) {
-		spin_unlock(&priv->sta_lock);
-		goto drop_unlock;
-	}
-
-	if (ieee80211_is_data_qos(fc)) {
-		priv->stations[sta_id].tid[tid].tfds_in_queue++;
-		if (!ieee80211_has_morefrags(fc))
-			priv->stations[sta_id].tid[tid].seq_number = seq_number;
-	}
-
-	spin_unlock(&priv->sta_lock);
+	if (unlikely(iwl_queue_space(q) < q->high_mark))
+		goto drop_unlock_sta;
 
 	/* Set up driver data for this TFD */
 	memset(&(txq->txb[q->write_ptr]), 0, sizeof(struct iwl_tx_info));
@@ -717,12 +719,10 @@
 	txcmd_phys = pci_map_single(priv->pci_dev,
 				    &out_cmd->hdr, firstlen,
 				    PCI_DMA_BIDIRECTIONAL);
+	if (unlikely(pci_dma_mapping_error(priv->pci_dev, txcmd_phys)))
+		goto drop_unlock_sta;
 	dma_unmap_addr_set(out_meta, mapping, txcmd_phys);
 	dma_unmap_len_set(out_meta, len, firstlen);
-	/* Add buffer containing Tx command and MAC(!) header to TFD's
-	 * first entry */
-	priv->cfg->ops->lib->txq_attach_buf_to_tfd(priv, txq,
-						   txcmd_phys, firstlen, 1, 0);
 
 	if (!ieee80211_has_morefrags(hdr->frame_control)) {
 		txq->need_update = 1;
@@ -737,11 +737,29 @@
 	if (secondlen > 0) {
 		phys_addr = pci_map_single(priv->pci_dev, skb->data + hdr_len,
 					   secondlen, PCI_DMA_TODEVICE);
-		priv->cfg->ops->lib->txq_attach_buf_to_tfd(priv, txq,
-							   phys_addr, secondlen,
-							   0, 0);
+		if (unlikely(pci_dma_mapping_error(priv->pci_dev, phys_addr))) {
+			pci_unmap_single(priv->pci_dev,
+					 dma_unmap_addr(out_meta, mapping),
+					 dma_unmap_len(out_meta, len),
+					 PCI_DMA_BIDIRECTIONAL);
+			goto drop_unlock_sta;
+		}
+	}
+
+	if (ieee80211_is_data_qos(fc)) {
+		priv->stations[sta_id].tid[tid].tfds_in_queue++;
+		if (!ieee80211_has_morefrags(fc))
+			priv->stations[sta_id].tid[tid].seq_number = seq_number;
 	}
 
+	spin_unlock(&priv->sta_lock);
+
+	/* Attach buffers to TFD */
+	iwlagn_txq_attach_buf_to_tfd(priv, txq, txcmd_phys, firstlen, 1);
+	if (secondlen > 0)
+		iwlagn_txq_attach_buf_to_tfd(priv, txq, phys_addr,
+					     secondlen, 0);
+
 	scratch_phys = txcmd_phys + sizeof(struct iwl_cmd_header) +
 				offsetof(struct iwl_tx_cmd, scratch);
 
@@ -759,8 +777,8 @@
 
 	/* Set up entry for this TFD in Tx byte-count array */
 	if (info->flags & IEEE80211_TX_CTL_AMPDU)
-		priv->cfg->ops->lib->txq_update_byte_cnt_tbl(priv, txq,
-						     le16_to_cpu(tx_cmd->len));
+		iwlagn_txq_update_byte_cnt_tbl(priv, txq,
+					       le16_to_cpu(tx_cmd->len));
 
 	pci_dma_sync_single_for_device(priv->pci_dev, txcmd_phys,
 				       firstlen, PCI_DMA_BIDIRECTIONAL);
@@ -806,7 +824,9 @@
 
 	return 0;
 
-drop_unlock:
+drop_unlock_sta:
+	spin_unlock(&priv->sta_lock);
+drop_unlock_priv:
 	spin_unlock_irqrestore(&priv->lock, flags);
 	return -1;
 }
@@ -894,7 +914,7 @@
 	spin_lock_irqsave(&priv->lock, flags);
 
 	/* Turn off all Tx DMA fifos */
-	priv->cfg->ops->lib->txq_set_sched(priv, 0);
+	iwlagn_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);
@@ -932,7 +952,7 @@
 	spin_lock_irqsave(&priv->lock, flags);
 
 	/* Turn off all Tx DMA fifos */
-	priv->cfg->ops->lib->txq_set_sched(priv, 0);
+	iwlagn_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);
@@ -958,7 +978,7 @@
 	/* Turn off all Tx DMA fifos */
 	spin_lock_irqsave(&priv->lock, flags);
 
-	priv->cfg->ops->lib->txq_set_sched(priv, 0);
+	iwlagn_txq_set_sched(priv, 0);
 
 	/* Stop each Tx DMA channel, and wait for it to be idle */
 	for (ch = 0; ch < priv->hw_params.dma_chnl_num; ch++) {
@@ -1039,11 +1059,11 @@
 	tid_data = &priv->stations[sta_id].tid[tid];
 	*ssn = SEQ_TO_SN(tid_data->seq_number);
 	tid_data->agg.txq_id = txq_id;
+	tid_data->agg.tx_fifo = tx_fifo;
 	iwl_set_swq_id(&priv->txq[txq_id], get_ac_from_tid(tid), txq_id);
 	spin_unlock_irqrestore(&priv->sta_lock, flags);
 
-	ret = priv->cfg->ops->lib->txq_agg_enable(priv, txq_id, tx_fifo,
-						  sta_id, tid, *ssn);
+	ret = iwlagn_txq_agg_enable(priv, txq_id, sta_id, tid);
 	if (ret)
 		return ret;
 
@@ -1130,8 +1150,7 @@
 	 * 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);
+	iwlagn_txq_agg_disable(priv, txq_id, ssn, tx_fifo_id);
 	spin_unlock_irqrestore(&priv->lock, flags);
 
 	ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid);
@@ -1160,8 +1179,7 @@
 			u16 ssn = SEQ_TO_SN(tid_data->seq_number);
 			int tx_fifo = get_fifo_from_tid(ctx, tid);
 			IWL_DEBUG_HT(priv, "HW queue empty: continue DELBA flow\n");
-			priv->cfg->ops->lib->txq_agg_disable(priv, txq_id,
-							     ssn, tx_fifo);
+			iwlagn_txq_agg_disable(priv, txq_id, ssn, tx_fifo);
 			tid_data->agg.state = IWL_AGG_OFF;
 			ieee80211_stop_tx_ba_cb_irqsafe(ctx->vif, addr, tid);
 		}
@@ -1241,10 +1259,9 @@
 				 txq_id >= IWLAGN_FIRST_AMPDU_QUEUE);
 		tx_info->skb = NULL;
 
-		if (priv->cfg->ops->lib->txq_inval_byte_cnt_tbl)
-			priv->cfg->ops->lib->txq_inval_byte_cnt_tbl(priv, txq);
+		iwlagn_txq_inval_byte_cnt_tbl(priv, txq);
 
-		priv->cfg->ops->lib->txq_free_tfd(priv, txq);
+		iwlagn_txq_free_tfd(priv, txq);
 	}
 	return nfreed;
 }
@@ -1260,11 +1277,11 @@
 				 struct iwl_compressed_ba_resp *ba_resp)
 
 {
-	int i, sh, ack;
+	int sh;
 	u16 seq_ctl = le16_to_cpu(ba_resp->seq_ctl);
 	u16 scd_flow = le16_to_cpu(ba_resp->scd_flow);
-	int successes = 0;
 	struct ieee80211_tx_info *info;
+	u64 bitmap, sent_bitmap;
 
 	if (unlikely(!agg->wait_for_ba))  {
 		if (unlikely(ba_resp->bitmap))
@@ -1278,70 +1295,42 @@
 
 	/* Calculate shift to align block-ack bits with our Tx window bits */
 	sh = agg->start_idx - SEQ_TO_INDEX(seq_ctl >> 4);
-	if (sh < 0) /* tbw something is wrong with indices */
+	if (sh < 0)
 		sh += 0x100;
 
-	if (agg->frame_count > (64 - sh)) {
-		IWL_DEBUG_TX_REPLY(priv, "more frames than bitmap size");
-		return -1;
-	}
-	if (!priv->cfg->base_params->no_agg_framecnt_info && ba_resp->txed) {
+	/*
+	 * Check for success or failure according to the
+	 * transmitted bitmap and block-ack bitmap
+	 */
+	bitmap = le64_to_cpu(ba_resp->bitmap) >> sh;
+	sent_bitmap = bitmap & agg->bitmap;
+
+	/* Sanity check values reported by uCode */
+	if (ba_resp->txed_2_done > ba_resp->txed) {
+		IWL_DEBUG_TX_REPLY(priv,
+			"bogus sent(%d) and ack(%d) count\n",
+			ba_resp->txed, ba_resp->txed_2_done);
 		/*
-		 * sent and ack information provided by uCode
-		 * use it instead of figure out ourself
+		 * set txed_2_done = txed,
+		 * so it won't impact rate scale
 		 */
-		if (ba_resp->txed_2_done > ba_resp->txed) {
-			IWL_DEBUG_TX_REPLY(priv,
-				"bogus sent(%d) and ack(%d) count\n",
-				ba_resp->txed, ba_resp->txed_2_done);
-			/*
-			 * set txed_2_done = txed,
-			 * so it won't impact rate scale
-			 */
-			ba_resp->txed = ba_resp->txed_2_done;
-		}
-		IWL_DEBUG_HT(priv, "agg frames sent:%d, acked:%d\n",
-				ba_resp->txed, ba_resp->txed_2_done);
-	} else {
-		u64 bitmap, sent_bitmap;
-
-		/* don't use 64-bit values for now */
-		bitmap = le64_to_cpu(ba_resp->bitmap) >> sh;
-
-		/* check for success or failure according to the
-		 * transmitted bitmap and block-ack bitmap */
-		sent_bitmap = bitmap & agg->bitmap;
-
-		/* For each frame attempted in aggregation,
-		 * update driver's record of tx frame's status. */
-		i = 0;
-		while (sent_bitmap) {
-			ack = sent_bitmap & 1ULL;
-			successes += ack;
-			IWL_DEBUG_TX_REPLY(priv, "%s ON i=%d idx=%d raw=%d\n",
-				ack ? "ACK" : "NACK", i,
-				(agg->start_idx + i) & 0xff,
-				agg->start_idx + i);
-			sent_bitmap >>= 1;
-			++i;
-		}
+		ba_resp->txed = ba_resp->txed_2_done;
+	}
+	IWL_DEBUG_HT(priv, "agg frames sent:%d, acked:%d\n",
+			ba_resp->txed, ba_resp->txed_2_done);
 
-		IWL_DEBUG_TX_REPLY(priv, "Bitmap %llx\n",
-				   (unsigned long long)bitmap);
+	/* Find the first ACKed frame to store the TX status */
+	while (sent_bitmap && !(sent_bitmap & 1)) {
+		agg->start_idx = (agg->start_idx + 1) & 0xff;
+		sent_bitmap >>= 1;
 	}
 
 	info = IEEE80211_SKB_CB(priv->txq[scd_flow].txb[agg->start_idx].skb);
 	memset(&info->status, 0, sizeof(info->status));
 	info->flags |= IEEE80211_TX_STAT_ACK;
 	info->flags |= IEEE80211_TX_STAT_AMPDU;
-	if (!priv->cfg->base_params->no_agg_framecnt_info && ba_resp->txed) {
-		info->status.ampdu_ack_len = ba_resp->txed_2_done;
-		info->status.ampdu_len = ba_resp->txed;
-
-	} else {
-		info->status.ampdu_ack_len = successes;
-		info->status.ampdu_len = agg->frame_count;
-	}
+	info->status.ampdu_ack_len = ba_resp->txed_2_done;
+	info->status.ampdu_len = ba_resp->txed;
 	iwlagn_hwrate_to_tx_control(priv, agg->rate_n_flags, info);
 
 	return 0;
diff -druN linux-2.6.39-libre/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c linux-3.0-rc7-libre/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c
--- linux-2.6.39-libre/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c	2011-07-11 19:51:52.000000000 -0400
@@ -2,7 +2,7 @@
  *
  * GPL LICENSE SUMMARY
  *
- * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2008 - 2011 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
@@ -161,47 +161,19 @@
 }
 
 static int iwlagn_load_given_ucode(struct iwl_priv *priv,
-		struct fw_desc *inst_image,
-		struct fw_desc *data_image)
+				   struct fw_img *image)
 {
 	int ret = 0;
 
-	ret = iwlagn_load_section(priv, "INST", inst_image,
+	ret = iwlagn_load_section(priv, "INST", &image->code,
 				   IWLAGN_RTC_INST_LOWER_BOUND);
 	if (ret)
 		return ret;
 
-	return iwlagn_load_section(priv, "DATA", data_image,
+	return iwlagn_load_section(priv, "DATA", &image->data,
 				    IWLAGN_RTC_DATA_LOWER_BOUND);
 }
 
-int iwlagn_load_ucode(struct iwl_priv *priv)
-{
-	int ret = 0;
-
-	/* check whether init ucode should be loaded, or rather runtime ucode */
-	if (priv->ucode_init.len && (priv->ucode_type == UCODE_NONE)) {
-		IWL_DEBUG_INFO(priv, "Init ucode found. Loading init ucode...\n");
-		ret = iwlagn_load_given_ucode(priv,
-			&priv->ucode_init, &priv->ucode_init_data);
-		if (!ret) {
-			IWL_DEBUG_INFO(priv, "Init ucode load complete.\n");
-			priv->ucode_type = UCODE_INIT;
-		}
-	} else {
-		IWL_DEBUG_INFO(priv, "Init ucode not found, or already loaded. "
-			"Loading runtime ucode...\n");
-		ret = iwlagn_load_given_ucode(priv,
-			&priv->ucode_code, &priv->ucode_data);
-		if (!ret) {
-			IWL_DEBUG_INFO(priv, "Runtime ucode load complete.\n");
-			priv->ucode_type = UCODE_RT;
-		}
-	}
-
-	return ret;
-}
-
 /*
  *  Calibration
  */
@@ -245,8 +217,8 @@
 	struct iwl_calib_cfg_cmd calib_cfg_cmd;
 	struct iwl_host_cmd cmd = {
 		.id = CALIBRATION_CFG_CMD,
-		.len = sizeof(struct iwl_calib_cfg_cmd),
-		.data = &calib_cfg_cmd,
+		.len = { sizeof(struct iwl_calib_cfg_cmd), },
+		.data = { &calib_cfg_cmd, },
 	};
 
 	memset(&calib_cfg_cmd, 0, sizeof(calib_cfg_cmd));
@@ -297,33 +269,9 @@
 	iwl_calib_set(&priv->calib_results[index], pkt->u.raw, len);
 }
 
-void iwlagn_rx_calib_complete(struct iwl_priv *priv,
-			       struct iwl_rx_mem_buffer *rxb)
-{
-	IWL_DEBUG_INFO(priv, "Init. calibration is completed, restarting fw.\n");
-	queue_work(priv->workqueue, &priv->restart);
-}
-
-void iwlagn_init_alive_start(struct iwl_priv *priv)
+int iwlagn_init_alive_start(struct iwl_priv *priv)
 {
-	int ret = 0;
-
-	/* initialize uCode was loaded... verify inst image.
-	 * This is a paranoid check, because we would not have gotten the
-	 * "initialize" alive if code weren't properly loaded.  */
-	if (iwl_verify_ucode(priv)) {
-		/* Runtime instruction load was bad;
-		 * take it all the way back down so we can try again */
-		IWL_DEBUG_INFO(priv, "Bad \"initialize\" uCode load.\n");
-		goto restart;
-	}
-
-	ret = priv->cfg->ops->lib->alive_notify(priv);
-	if (ret) {
-		IWL_WARN(priv,
-			"Could not complete ALIVE transition: %d\n", ret);
-		goto restart;
-	}
+	int ret;
 
 	if (priv->cfg->bt_params &&
 	    priv->cfg->bt_params->advanced_bt_coexist) {
@@ -333,24 +281,25 @@
 		 * no need to close the envlope since we are going
 		 * to load the runtime uCode later.
 		 */
-		iwlagn_send_bt_env(priv, IWL_BT_COEX_ENV_OPEN,
+		ret = iwlagn_send_bt_env(priv, IWL_BT_COEX_ENV_OPEN,
 			BT_COEX_PRIO_TBL_EVT_INIT_CALIB2);
+		if (ret)
+			return ret;
 
 	}
-	iwlagn_send_calib_cfg(priv);
+
+	ret = iwlagn_send_calib_cfg(priv);
+	if (ret)
+		return ret;
 
 	/**
 	 * temperature offset calibration is only needed for runtime ucode,
 	 * so prepare the value now.
 	 */
 	if (priv->cfg->need_temp_offset_calib)
-		iwlagn_set_temperature_offset_calib(priv);
-
-	return;
+		return iwlagn_set_temperature_offset_calib(priv);
 
-restart:
-	/* real restart (first load init_ucode) */
-	queue_work(priv->workqueue, &priv->restart);
+	return 0;
 }
 
 static int iwlagn_send_wimax_coex(struct iwl_priv *priv)
@@ -413,25 +362,30 @@
 		IWL_ERR(priv, "failed to send BT prio tbl command\n");
 }
 
-void iwlagn_send_bt_env(struct iwl_priv *priv, u8 action, u8 type)
+int iwlagn_send_bt_env(struct iwl_priv *priv, u8 action, u8 type)
 {
 	struct iwl_bt_coex_prot_env_cmd env_cmd;
+	int ret;
 
 	env_cmd.action = action;
 	env_cmd.type = type;
-	if (iwl_send_cmd_pdu(priv, REPLY_BT_COEX_PROT_ENV,
-			     sizeof(env_cmd), &env_cmd))
+	ret = iwl_send_cmd_pdu(priv, REPLY_BT_COEX_PROT_ENV,
+			       sizeof(env_cmd), &env_cmd);
+	if (ret)
 		IWL_ERR(priv, "failed to send BT env command\n");
+	return ret;
 }
 
 
-int iwlagn_alive_notify(struct iwl_priv *priv)
+static int iwlagn_alive_notify(struct iwl_priv *priv)
 {
 	const struct queue_to_fifo_ac *queue_to_fifo;
+	struct iwl_rxon_context *ctx;
 	u32 a;
 	unsigned long flags;
 	int i, chan;
 	u32 reg_val;
+	int ret;
 
 	spin_lock_irqsave(&priv->lock, flags);
 
@@ -486,7 +440,7 @@
 			IWL_MASK(0, priv->hw_params.max_txq_num));
 
 	/* Activate all Tx DMA/FIFO channels */
-	priv->cfg->ops->lib->txq_set_sched(priv, IWL_MASK(0, 7));
+	iwlagn_txq_set_sched(priv, IWL_MASK(0, 7));
 
 	/* map queues to FIFOs */
 	if (priv->valid_contexts != BIT(IWL_RXON_CTX_BSS))
@@ -500,6 +454,8 @@
 	memset(&priv->queue_stopped[0], 0, sizeof(priv->queue_stopped));
 	for (i = 0; i < 4; i++)
 		atomic_set(&priv->queue_stop_count[i], 0);
+	for_each_context(priv, ctx)
+		ctx->last_tx_rejected = false;
 
 	/* reset to 0 to enable all the queue first */
 	priv->txq_ctx_active_msk = 0;
@@ -527,12 +483,15 @@
 	iwl_clear_bits_prph(priv, APMG_PCIDEV_STT_REG,
 			  APMG_PCIDEV_STT_VAL_L1_ACT_DIS);
 
-	iwlagn_send_wimax_coex(priv);
+	ret = iwlagn_send_wimax_coex(priv);
+	if (ret)
+		return ret;
 
-	iwlagn_set_Xtal_calib(priv);
-	iwl_send_calib_results(priv);
+	ret = iwlagn_set_Xtal_calib(priv);
+	if (ret)
+		return ret;
 
-	return 0;
+	return iwl_send_calib_results(priv);
 }
 
 
@@ -541,11 +500,12 @@
  *   using sample data 100 bytes apart.  If these sample points are good,
  *   it's a pretty good bet that everything between them is good, too.
  */
-static int iwlcore_verify_inst_sparse(struct iwl_priv *priv, __le32 *image, u32 len)
+static int iwlcore_verify_inst_sparse(struct iwl_priv *priv,
+				      struct fw_desc *fw_desc)
 {
+	__le32 *image = (__le32 *)fw_desc->v_addr;
+	u32 len = fw_desc->len;
 	u32 val;
-	int ret = 0;
-	u32 errcnt = 0;
 	u32 i;
 
 	IWL_DEBUG_INFO(priv, "ucode inst image size is %u\n", len);
@@ -556,104 +516,204 @@
 		 * if IWL_DL_IO is set */
 		iwl_write_direct32(priv, HBUS_TARG_MEM_RADDR,
 			i + IWLAGN_RTC_INST_LOWER_BOUND);
-		val = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT);
-		if (val != le32_to_cpu(*image)) {
-			ret = -EIO;
-			errcnt++;
-			if (errcnt >= 3)
-				break;
-		}
+		val = iwl_read32(priv, HBUS_TARG_MEM_RDAT);
+		if (val != le32_to_cpu(*image))
+			return -EIO;
 	}
 
-	return ret;
+	return 0;
 }
 
-/**
- * iwlcore_verify_inst_full - verify runtime uCode image in card vs. host,
- *     looking at all data.
- */
-static int iwl_verify_inst_full(struct iwl_priv *priv, __le32 *image,
-				 u32 len)
+static void iwl_print_mismatch_inst(struct iwl_priv *priv,
+				    struct fw_desc *fw_desc)
 {
+	__le32 *image = (__le32 *)fw_desc->v_addr;
+	u32 len = fw_desc->len;
 	u32 val;
-	u32 save_len = len;
-	int ret = 0;
-	u32 errcnt;
+	u32 offs;
+	int errors = 0;
 
 	IWL_DEBUG_INFO(priv, "ucode inst image size is %u\n", len);
 
 	iwl_write_direct32(priv, HBUS_TARG_MEM_RADDR,
 			   IWLAGN_RTC_INST_LOWER_BOUND);
 
-	errcnt = 0;
-	for (; len > 0; len -= sizeof(u32), image++) {
+	for (offs = 0;
+	     offs < len && errors < 20;
+	     offs += sizeof(u32), image++) {
 		/* read data comes through single port, auto-incr addr */
-		/* NOTE: Use the debugless read so we don't flood kernel log
-		 * if IWL_DL_IO is set */
-		val = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT);
+		val = iwl_read32(priv, HBUS_TARG_MEM_RDAT);
 		if (val != le32_to_cpu(*image)) {
-			IWL_ERR(priv, "uCode INST section is invalid at "
-				  "offset 0x%x, is 0x%x, s/b 0x%x\n",
-				  save_len - len, val, le32_to_cpu(*image));
-			ret = -EIO;
-			errcnt++;
-			if (errcnt >= 20)
-				break;
+			IWL_ERR(priv, "uCode INST section at "
+				"offset 0x%x, is 0x%x, s/b 0x%x\n",
+				offs, val, le32_to_cpu(*image));
+			errors++;
 		}
 	}
-
-	if (!errcnt)
-		IWL_DEBUG_INFO(priv,
-		    "ucode image in INSTRUCTION memory is good\n");
-
-	return ret;
 }
 
 /**
  * iwl_verify_ucode - determine which instruction image is in SRAM,
  *    and verify its contents
  */
-int iwl_verify_ucode(struct iwl_priv *priv)
+static int iwl_verify_ucode(struct iwl_priv *priv, struct fw_img *img)
 {
-	__le32 *image;
-	u32 len;
+	if (!iwlcore_verify_inst_sparse(priv, &img->code)) {
+		IWL_DEBUG_INFO(priv, "uCode is good in inst SRAM\n");
+		return 0;
+	}
+
+	IWL_ERR(priv, "UCODE IMAGE IN INSTRUCTION SRAM NOT VALID!!\n");
+
+	iwl_print_mismatch_inst(priv, &img->code);
+	return -EIO;
+}
+
+struct iwlagn_alive_data {
+	bool valid;
+	u8 subtype;
+};
+
+static void iwlagn_alive_fn(struct iwl_priv *priv,
+			    struct iwl_rx_packet *pkt,
+			    void *data)
+{
+	struct iwlagn_alive_data *alive_data = data;
+	struct iwl_alive_resp *palive;
+
+	palive = &pkt->u.alive_frame;
+
+	IWL_DEBUG_INFO(priv, "Alive ucode status 0x%08X revision "
+		       "0x%01X 0x%01X\n",
+		       palive->is_valid, palive->ver_type,
+		       palive->ver_subtype);
+
+	priv->device_pointers.error_event_table =
+		le32_to_cpu(palive->error_event_table_ptr);
+	priv->device_pointers.log_event_table =
+		le32_to_cpu(palive->log_event_table_ptr);
+
+	alive_data->subtype = palive->ver_subtype;
+	alive_data->valid = palive->is_valid == UCODE_VALID_OK;
+}
+
+#define UCODE_ALIVE_TIMEOUT	HZ
+#define UCODE_CALIB_TIMEOUT	(2*HZ)
+
+int iwlagn_load_ucode_wait_alive(struct iwl_priv *priv,
+				 struct fw_img *image,
+				 int subtype, int alternate_subtype)
+{
+	struct iwl_notification_wait alive_wait;
+	struct iwlagn_alive_data alive_data;
 	int ret;
+	enum iwlagn_ucode_subtype old_type;
 
-	/* Try bootstrap */
-	image = (__le32 *)priv->ucode_boot.v_addr;
-	len = priv->ucode_boot.len;
-	ret = iwlcore_verify_inst_sparse(priv, image, len);
-	if (!ret) {
-		IWL_DEBUG_INFO(priv, "Bootstrap uCode is good in inst SRAM\n");
-		return 0;
+	ret = iwlagn_start_device(priv);
+	if (ret)
+		return ret;
+
+	iwlagn_init_notification_wait(priv, &alive_wait, REPLY_ALIVE,
+				      iwlagn_alive_fn, &alive_data);
+
+	old_type = priv->ucode_type;
+	priv->ucode_type = subtype;
+
+	ret = iwlagn_load_given_ucode(priv, image);
+	if (ret) {
+		priv->ucode_type = old_type;
+		iwlagn_remove_notification(priv, &alive_wait);
+		return ret;
 	}
 
-	/* Try initialize */
-	image = (__le32 *)priv->ucode_init.v_addr;
-	len = priv->ucode_init.len;
-	ret = iwlcore_verify_inst_sparse(priv, image, len);
-	if (!ret) {
-		IWL_DEBUG_INFO(priv, "Initialize uCode is good in inst SRAM\n");
-		return 0;
+	/* Remove all resets to allow NIC to operate */
+	iwl_write32(priv, CSR_RESET, 0);
+
+	/*
+	 * Some things may run in the background now, but we
+	 * just wait for the ALIVE notification here.
+	 */
+	ret = iwlagn_wait_notification(priv, &alive_wait, UCODE_ALIVE_TIMEOUT);
+	if (ret) {
+		priv->ucode_type = old_type;
+		return ret;
 	}
 
-	/* Try runtime/protocol */
-	image = (__le32 *)priv->ucode_code.v_addr;
-	len = priv->ucode_code.len;
-	ret = iwlcore_verify_inst_sparse(priv, image, len);
-	if (!ret) {
-		IWL_DEBUG_INFO(priv, "Runtime uCode is good in inst SRAM\n");
-		return 0;
+	if (!alive_data.valid) {
+		IWL_ERR(priv, "Loaded ucode is not valid!\n");
+		priv->ucode_type = old_type;
+		return -EIO;
 	}
 
-	IWL_ERR(priv, "NO VALID UCODE IMAGE IN INSTRUCTION SRAM!!\n");
+	if (alive_data.subtype != subtype &&
+	    alive_data.subtype != alternate_subtype) {
+		IWL_ERR(priv,
+			"Loaded ucode is not expected type (got %d, expected %d)!\n",
+			alive_data.subtype, subtype);
+		priv->ucode_type = old_type;
+		return -EIO;
+	}
 
-	/* Since nothing seems to match, show first several data entries in
-	 * instruction SRAM, so maybe visual inspection will give a clue.
-	 * Selection of bootstrap image (vs. other images) is arbitrary. */
-	image = (__le32 *)priv->ucode_boot.v_addr;
-	len = priv->ucode_boot.len;
-	ret = iwl_verify_inst_full(priv, image, len);
+	ret = iwl_verify_ucode(priv, image);
+	if (ret) {
+		priv->ucode_type = old_type;
+		return ret;
+	}
+
+	/* delay a bit to give rfkill time to run */
+	msleep(5);
+
+	ret = iwlagn_alive_notify(priv);
+	if (ret) {
+		IWL_WARN(priv,
+			"Could not complete ALIVE transition: %d\n", ret);
+		priv->ucode_type = old_type;
+		return ret;
+	}
 
+	return 0;
+}
+
+int iwlagn_run_init_ucode(struct iwl_priv *priv)
+{
+	struct iwl_notification_wait calib_wait;
+	int ret;
+
+	lockdep_assert_held(&priv->mutex);
+
+	/* No init ucode required? Curious, but maybe ok */
+	if (!priv->ucode_init.code.len)
+		return 0;
+
+	if (priv->ucode_type != UCODE_SUBTYPE_NONE_LOADED)
+		return 0;
+
+	iwlagn_init_notification_wait(priv, &calib_wait,
+				      CALIBRATION_COMPLETE_NOTIFICATION,
+				      NULL, NULL);
+
+	/* Will also start the device */
+	ret = iwlagn_load_ucode_wait_alive(priv, &priv->ucode_init,
+					   UCODE_SUBTYPE_INIT, -1);
+	if (ret)
+		goto error;
+
+	ret = iwlagn_init_alive_start(priv);
+	if (ret)
+		goto error;
+
+	/*
+	 * Some things may run in the background now, but we
+	 * just wait for the calibration complete notification.
+	 */
+	ret = iwlagn_wait_notification(priv, &calib_wait, UCODE_CALIB_TIMEOUT);
+
+	goto out;
+
+ error:
+	iwlagn_remove_notification(priv, &calib_wait);
+ out:
+	/* Whatever happened, stop the device */
+	iwlagn_stop_device(priv);
 	return ret;
 }
diff -druN linux-2.6.39-libre/drivers/net/wireless/iwlwifi/iwl-commands.h linux-3.0-rc7-libre/drivers/net/wireless/iwlwifi/iwl-commands.h
--- linux-2.6.39-libre/drivers/net/wireless/iwlwifi/iwl-commands.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/iwlwifi/iwl-commands.h	2011-07-11 19:51:52.000000000 -0400
@@ -5,7 +5,7 @@
  *
  * GPL LICENSE SUMMARY
  *
- * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2011 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 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -103,9 +103,7 @@
 	REPLY_WEPKEY = 0x20,
 
 	/* RX, TX, LEDs */
-	REPLY_3945_RX = 0x1b,           /* 3945 only */
 	REPLY_TX = 0x1c,
-	REPLY_RATE_SCALE = 0x47,	/* 3945 only */
 	REPLY_LEDS_CMD = 0x48,
 	REPLY_TX_LINK_QUALITY_CMD = 0x4e, /* for 4965 and up */
 
@@ -207,7 +205,6 @@
 #define QUEUE_TO_SEQ(q)	(((q) & 0x1f) << 8)
 #define SEQ_TO_INDEX(s)	((s) & 0xff)
 #define INDEX_TO_SEQ(i)	((i) & 0xff)
-#define SEQ_HUGE_FRAME	cpu_to_le16(0x4000)
 #define SEQ_RX_FRAME	cpu_to_le16(0x8000)
 
 /**
@@ -229,16 +226,14 @@
 	 * There is one exception:  uCode sets bit 15 when it originates
 	 * the response/notification, i.e. when the response/notification
 	 * is not a direct response to a command sent by the driver.  For
-	 * example, uCode issues REPLY_3945_RX when it sends a received frame
+	 * example, uCode issues REPLY_RX when it sends a received frame
 	 * to the driver; it is not a direct response to any driver command.
 	 *
 	 * The Linux driver uses the following format:
 	 *
 	 *  0:7		tfd index - position within TX queue
 	 *  8:12	TX queue id
-	 *  13		reserved
-	 *  14		huge - driver sets this to indicate command is in the
-	 *  		'huge' storage at the end of the command buffers
+	 *  13:14	reserved
 	 *  15		unsolicited RX or uCode-originated notification
 	 */
 	__le16 sequence;
@@ -249,36 +244,6 @@
 
 
 /**
- * struct iwl3945_tx_power
- *
- * Used in REPLY_TX_PWR_TABLE_CMD, REPLY_SCAN_CMD, REPLY_CHANNEL_SWITCH
- *
- * Each entry contains two values:
- * 1)  DSP gain (or sometimes called DSP attenuation).  This is a fine-grained
- *     linear value that multiplies the output of the digital signal processor,
- *     before being sent to the analog radio.
- * 2)  Radio gain.  This sets the analog gain of the radio Tx path.
- *     It is a coarser setting, and behaves in a logarithmic (dB) fashion.
- *
- * Driver obtains values from struct iwl3945_tx_power power_gain_table[][].
- */
-struct iwl3945_tx_power {
-	u8 tx_gain;		/* gain for analog radio */
-	u8 dsp_atten;		/* gain for DSP */
-} __packed;
-
-/**
- * struct iwl3945_power_per_rate
- *
- * Used in REPLY_TX_PWR_TABLE_CMD, REPLY_CHANNEL_SWITCH
- */
-struct iwl3945_power_per_rate {
-	u8 rate;		/* plcp */
-	struct iwl3945_tx_power tpc;
-	u8 reserved;
-} __packed;
-
-/**
  * iwlagn rate_n_flags bit fields
  *
  * rate_n_flags format is used in following iwlagn commands:
@@ -324,6 +289,8 @@
 #define RATE_MCS_SPATIAL_MSK 0x18
 #define RATE_MCS_HT_DUP_POS 5
 #define RATE_MCS_HT_DUP_MSK 0x20
+/* Both legacy and HT use bits 7:0 as the CCK/OFDM rate or HT MCS */
+#define RATE_MCS_RATE_MSK 0xff
 
 /* Bit 8: (1) HT format, (0) legacy format in bits 7:0 */
 #define RATE_MCS_FLAGS_POS 8
@@ -375,30 +342,6 @@
 #define IWL_PWR_CCK_ENTRIES			2
 
 /**
- * union iwl4965_tx_power_dual_stream
- *
- * Host format used for REPLY_TX_PWR_TABLE_CMD, REPLY_CHANNEL_SWITCH
- * Use __le32 version (struct tx_power_dual_stream) when building command.
- *
- * Driver provides radio gain and DSP attenuation settings to device in pairs,
- * one value for each transmitter chain.  The first value is for transmitter A,
- * second for transmitter B.
- *
- * For SISO bit rates, both values in a pair should be identical.
- * For MIMO rates, one value may be different from the other,
- * in order to balance the Tx output between the two transmitters.
- *
- * See more details in doc for TXPOWER in iwl-4965-hw.h.
- */
-union iwl4965_tx_power_dual_stream {
-	struct {
-		u8 radio_tx_gain[2];
-		u8 dsp_predis_atten[2];
-	} s;
-	u32 dw;
-};
-
-/**
  * struct tx_power_dual_stream
  *
  * Table entries in REPLY_TX_PWR_TABLE_CMD, REPLY_CHANNEL_SWITCH
@@ -410,15 +353,6 @@
 } __packed;
 
 /**
- * struct iwl4965_tx_power_db
- *
- * Entire table within REPLY_TX_PWR_TABLE_CMD, REPLY_CHANNEL_SWITCH
- */
-struct iwl4965_tx_power_db {
-	struct tx_power_dual_stream power_tbl[POWER_TABLE_NUM_ENTRIES];
-} __packed;
-
-/**
  * Command REPLY_TX_POWER_DBM_CMD = 0x98
  * struct iwlagn_tx_power_dbm_cmd
  */
@@ -449,55 +383,18 @@
  *****************************************************************************/
 
 #define UCODE_VALID_OK	cpu_to_le32(0x1)
-#define INITIALIZE_SUBTYPE    (9)
 
-/*
- * ("Initialize") REPLY_ALIVE = 0x1 (response only, not a command)
- *
- * uCode issues this "initialize alive" notification once the initialization
- * uCode image has completed its work, and is ready to load the runtime image.
- * This is the *first* "alive" notification that the driver will receive after
- * rebooting uCode; the "initialize" alive is indicated by subtype field == 9.
- *
- * See comments documenting "BSM" (bootstrap state machine).
- *
- * For 4965, this notification contains important calibration data for
- * calculating txpower settings:
- *
- * 1)  Power supply voltage indication.  The voltage sensor outputs higher
- *     values for lower voltage, and vice verse.
- *
- * 2)  Temperature measurement parameters, for each of two channel widths
- *     (20 MHz and 40 MHz) supported by the radios.  Temperature sensing
- *     is done via one of the receiver chains, and channel width influences
- *     the results.
- *
- * 3)  Tx gain compensation to balance 4965's 2 Tx chains for MIMO operation,
- *     for each of 5 frequency ranges.
- */
-struct iwl_init_alive_resp {
-	u8 ucode_minor;
-	u8 ucode_major;
-	__le16 reserved1;
-	u8 sw_rev[8];
-	u8 ver_type;
-	u8 ver_subtype;		/* "9" for initialize alive */
-	__le16 reserved2;
-	__le32 log_event_table_ptr;
-	__le32 error_event_table_ptr;
-	__le32 timestamp;
-	__le32 is_valid;
-
-	/* calibration values from "initialize" uCode */
-	__le32 voltage;		/* signed, higher value is lower voltage */
-	__le32 therm_r1[2];	/* signed, 1st for normal, 2nd for HT40 */
-	__le32 therm_r2[2];	/* signed */
-	__le32 therm_r3[2];	/* signed */
-	__le32 therm_r4[2];	/* signed */
-	__le32 tx_atten[5][2];	/* signed MIMO gain comp, 5 freq groups,
-				 * 2 Tx chains */
-} __packed;
+enum iwlagn_ucode_subtype {
+	UCODE_SUBTYPE_REGULAR	= 0,
+	UCODE_SUBTYPE_REGULAR_NEW = 1,
+	UCODE_SUBTYPE_INIT	= 9,
 
+	/*
+	 * Not a valid subtype, the ucode has just a u8, so
+	 * we can use something > 0xff for this value.
+	 */
+	UCODE_SUBTYPE_NONE_LOADED = 0x100,
+};
 
 /**
  * REPLY_ALIVE = 0x1 (response only, not a command)
@@ -533,49 +430,61 @@
  *
  * 2)  error_event_table_ptr indicates base of the error log.  This contains
  *     information about any uCode error that occurs.  For agn, the format
- *     of the error log is:
- *
- *	__le32 valid;        (nonzero) valid, (0) log is empty
- *	__le32 error_id;     type of error
- *	__le32 pc;           program counter
- *	__le32 blink1;       branch link
- *	__le32 blink2;       branch link
- *	__le32 ilink1;       interrupt link
- *	__le32 ilink2;       interrupt link
- *	__le32 data1;        error-specific data
- *	__le32 data2;        error-specific data
- *	__le32 line;         source code line of error
- *	__le32 bcon_time;    beacon timer
- *	__le32 tsf_low;      network timestamp function timer
- *	__le32 tsf_hi;       network timestamp function timer
- *	__le32 gp1;          GP1 timer register
- *	__le32 gp2;          GP2 timer register
- *	__le32 gp3;          GP3 timer register
- *	__le32 ucode_ver;    uCode version
- *	__le32 hw_ver;       HW Silicon version
- *	__le32 brd_ver;      HW board version
- *	__le32 log_pc;       log program counter
- *	__le32 frame_ptr;    frame pointer
- *	__le32 stack_ptr;    stack pointer
- *	__le32 hcmd;         last host command
- *	__le32 isr0;         isr status register LMPM_NIC_ISR0: rxtx_flag
- *	__le32 isr1;         isr status register LMPM_NIC_ISR1: host_flag
- *	__le32 isr2;         isr status register LMPM_NIC_ISR2: enc_flag
- *	__le32 isr3;         isr status register LMPM_NIC_ISR3: time_flag
- *	__le32 isr4;         isr status register LMPM_NIC_ISR4: wico interrupt
- *	__le32 isr_pref;     isr status register LMPM_NIC_PREF_STAT
- *	__le32 wait_event;   wait event() caller address
- *	__le32 l2p_control;  L2pControlField
- *	__le32 l2p_duration; L2pDurationField
- *	__le32 l2p_mhvalid;  L2pMhValidBits
- *	__le32 l2p_addr_match; L2pAddrMatchStat
- *	__le32 lmpm_pmg_sel; indicate which clocks are turned on (LMPM_PMG_SEL)
- *	__le32 u_timestamp;  indicate when the date and time of the compilation
- *	__le32 reserved;
+ *     of the error log is defined by struct iwl_error_event_table.
  *
  * The Linux driver can print both logs to the system log when a uCode error
  * occurs.
  */
+
+/*
+ * Note: This structure is read from the device with IO accesses,
+ * and the reading already does the endian conversion. As it is
+ * read with u32-sized accesses, any members with a different size
+ * need to be ordered correctly though!
+ */
+struct iwl_error_event_table {
+	u32 valid;		/* (nonzero) valid, (0) log is empty */
+	u32 error_id;		/* type of error */
+	u32 pc;			/* program counter */
+	u32 blink1;		/* branch link */
+	u32 blink2;		/* branch link */
+	u32 ilink1;		/* interrupt link */
+	u32 ilink2;		/* interrupt link */
+	u32 data1;		/* error-specific data */
+	u32 data2;		/* error-specific data */
+	u32 line;		/* source code line of error */
+	u32 bcon_time;		/* beacon timer */
+	u32 tsf_low;		/* network timestamp function timer */
+	u32 tsf_hi;		/* network timestamp function timer */
+	u32 gp1;		/* GP1 timer register */
+	u32 gp2;		/* GP2 timer register */
+	u32 gp3;		/* GP3 timer register */
+	u32 ucode_ver;		/* uCode version */
+	u32 hw_ver;		/* HW Silicon version */
+	u32 brd_ver;		/* HW board version */
+	u32 log_pc;		/* log program counter */
+	u32 frame_ptr;		/* frame pointer */
+	u32 stack_ptr;		/* stack pointer */
+	u32 hcmd;		/* last host command header */
+#if 0
+	/* no need to read the remainder, we don't use the values */
+	u32 isr0;		/* isr status register LMPM_NIC_ISR0: rxtx_flag */
+	u32 isr1;		/* isr status register LMPM_NIC_ISR1: host_flag */
+	u32 isr2;		/* isr status register LMPM_NIC_ISR2: enc_flag */
+	u32 isr3;		/* isr status register LMPM_NIC_ISR3: time_flag */
+	u32 isr4;		/* isr status register LMPM_NIC_ISR4: wico interrupt */
+	u32 isr_pref;		/* isr status register LMPM_NIC_PREF_STAT */
+	u32 wait_event;		/* wait event() caller address */
+	u32 l2p_control;	/* L2pControlField */
+	u32 l2p_duration;	/* L2pDurationField */
+	u32 l2p_mhvalid;	/* L2pMhValidBits */
+	u32 l2p_addr_match;	/* L2pAddrMatchStat */
+	u32 lmpm_pmg_sel;	/* indicate which clocks are turned on (LMPM_PMG_SEL) */
+	u32 u_timestamp;	/* indicate when the date and time of the compilation */
+	u32 flow_handler;	/* FH read/write pointers, RX credit */
+#endif
+} __packed;
+
 struct iwl_alive_resp {
 	u8 ucode_minor;
 	u8 ucode_major;
@@ -722,46 +631,6 @@
  *        regardless of whether RXON_FILTER_ASSOC_MSK is set.
  */
 
-struct iwl3945_rxon_cmd {
-	u8 node_addr[6];
-	__le16 reserved1;
-	u8 bssid_addr[6];
-	__le16 reserved2;
-	u8 wlap_bssid_addr[6];
-	__le16 reserved3;
-	u8 dev_type;
-	u8 air_propagation;
-	__le16 reserved4;
-	u8 ofdm_basic_rates;
-	u8 cck_basic_rates;
-	__le16 assoc_id;
-	__le32 flags;
-	__le32 filter_flags;
-	__le16 channel;
-	__le16 reserved5;
-} __packed;
-
-struct iwl4965_rxon_cmd {
-	u8 node_addr[6];
-	__le16 reserved1;
-	u8 bssid_addr[6];
-	__le16 reserved2;
-	u8 wlap_bssid_addr[6];
-	__le16 reserved3;
-	u8 dev_type;
-	u8 air_propagation;
-	__le16 rx_chain;
-	u8 ofdm_basic_rates;
-	u8 cck_basic_rates;
-	__le16 assoc_id;
-	__le32 flags;
-	__le32 filter_flags;
-	__le16 channel;
-	u8 ofdm_ht_single_stream_basic_rates;
-	u8 ofdm_ht_dual_stream_basic_rates;
-} __packed;
-
-/* 5000 HW just extend this command */
 struct iwl_rxon_cmd {
 	u8 node_addr[6];
 	__le16 reserved1;
@@ -789,26 +658,7 @@
 /*
  * REPLY_RXON_ASSOC = 0x11 (command, has simple generic response)
  */
-struct iwl3945_rxon_assoc_cmd {
-	__le32 flags;
-	__le32 filter_flags;
-	u8 ofdm_basic_rates;
-	u8 cck_basic_rates;
-	__le16 reserved;
-} __packed;
-
-struct iwl4965_rxon_assoc_cmd {
-	__le32 flags;
-	__le32 filter_flags;
-	u8 ofdm_basic_rates;
-	u8 cck_basic_rates;
-	u8 ofdm_ht_single_stream_basic_rates;
-	u8 ofdm_ht_dual_stream_basic_rates;
-	__le16 rx_chain_select_flags;
-	__le16 reserved;
-} __packed;
-
-struct iwl5000_rxon_assoc_cmd {
+struct iwl_rxon_assoc_cmd {
 	__le32 flags;
 	__le32 filter_flags;
 	u8 ofdm_basic_rates;
@@ -843,26 +693,6 @@
 /*
  * REPLY_CHANNEL_SWITCH = 0x72 (command, has simple generic response)
  */
-struct iwl3945_channel_switch_cmd {
-	u8 band;
-	u8 expect_beacon;
-	__le16 channel;
-	__le32 rxon_flags;
-	__le32 rxon_filter_flags;
-	__le32 switch_time;
-	struct iwl3945_power_per_rate power[IWL_MAX_RATES];
-} __packed;
-
-struct iwl4965_channel_switch_cmd {
-	u8 band;
-	u8 expect_beacon;
-	__le16 channel;
-	__le32 rxon_flags;
-	__le32 rxon_filter_flags;
-	__le32 switch_time;
-	struct iwl4965_tx_power_db tx_power;
-} __packed;
-
 /**
  * struct iwl5000_channel_switch_cmd
  * @band: 0- 5.2GHz, 1- 2.4GHz
@@ -976,15 +806,10 @@
 #define	IWL_AP_ID		0
 #define	IWL_AP_ID_PAN		1
 #define	IWL_STA_ID		2
-#define	IWL3945_BROADCAST_ID	24
-#define IWL3945_STATION_COUNT	25
-#define IWL4965_BROADCAST_ID	31
-#define	IWL4965_STATION_COUNT	32
 #define IWLAGN_PAN_BCAST_ID	14
 #define IWLAGN_BROADCAST_ID	15
 #define	IWLAGN_STATION_COUNT	16
 
-#define	IWL_STATION_COUNT	32 	/* MAX(3945,4965)*/
 #define	IWL_INVALID_STATION 	255
 
 #define STA_FLG_TX_RATE_MSK		cpu_to_le32(1 << 2)
@@ -1032,16 +857,6 @@
  * combined with Traffic ID (QOS priority), in format used by Tx Scheduler */
 #define BUILD_RAxTID(sta_id, tid)	(((sta_id) << 4) + (tid))
 
-struct iwl4965_keyinfo {
-	__le16 key_flags;
-	u8 tkip_rx_tsc_byte2;	/* TSC[2] for key mix ph1 detection */
-	u8 reserved1;
-	__le16 tkip_rx_ttak[5];	/* 10-byte unicast TKIP TTAK */
-	u8 key_offset;
-	u8 reserved2;
-	u8 key[16];		/* 16-byte unicast decryption key */
-} __packed;
-
 /* agn */
 struct iwl_keyinfo {
 	__le16 key_flags;
@@ -1083,7 +898,6 @@
  * with info on security keys, aggregation parameters, and Tx rates for
  * initial Tx attempt and any retries (agn devices uses
  * REPLY_TX_LINK_QUALITY_CMD,
- * 3945 uses REPLY_RATE_SCALE to set up rate tables).
  *
  * REPLY_ADD_STA sets up the table entry for one station, either creating
  * a new entry, or modifying a pre-existing one.
@@ -1103,72 +917,6 @@
  *        entries for all STAs in network, starting with index IWL_STA_ID.
  */
 
-struct iwl3945_addsta_cmd {
-	u8 mode;		/* 1: modify existing, 0: add new station */
-	u8 reserved[3];
-	struct sta_id_modify sta;
-	struct iwl4965_keyinfo key;
-	__le32 station_flags;		/* STA_FLG_* */
-	__le32 station_flags_msk;	/* STA_FLG_* */
-
-	/* bit field to disable (1) or enable (0) Tx for Traffic ID (TID)
-	 * corresponding to bit (e.g. bit 5 controls TID 5).
-	 * Set modify_mask bit STA_MODIFY_TID_DISABLE_TX to use this field. */
-	__le16 tid_disable_tx;
-
-	__le16 rate_n_flags;
-
-	/* TID for which to add block-ack support.
-	 * Set modify_mask bit STA_MODIFY_ADDBA_TID_MSK to use this field. */
-	u8 add_immediate_ba_tid;
-
-	/* TID for which to remove block-ack support.
-	 * Set modify_mask bit STA_MODIFY_DELBA_TID_MSK to use this field. */
-	u8 remove_immediate_ba_tid;
-
-	/* Starting Sequence Number for added block-ack support.
-	 * Set modify_mask bit STA_MODIFY_ADDBA_TID_MSK to use this field. */
-	__le16 add_immediate_ba_ssn;
-} __packed;
-
-struct iwl4965_addsta_cmd {
-	u8 mode;		/* 1: modify existing, 0: add new station */
-	u8 reserved[3];
-	struct sta_id_modify sta;
-	struct iwl4965_keyinfo key;
-	__le32 station_flags;		/* STA_FLG_* */
-	__le32 station_flags_msk;	/* STA_FLG_* */
-
-	/* bit field to disable (1) or enable (0) Tx for Traffic ID (TID)
-	 * corresponding to bit (e.g. bit 5 controls TID 5).
-	 * Set modify_mask bit STA_MODIFY_TID_DISABLE_TX to use this field. */
-	__le16 tid_disable_tx;
-
-	__le16	reserved1;
-
-	/* TID for which to add block-ack support.
-	 * Set modify_mask bit STA_MODIFY_ADDBA_TID_MSK to use this field. */
-	u8 add_immediate_ba_tid;
-
-	/* TID for which to remove block-ack support.
-	 * Set modify_mask bit STA_MODIFY_DELBA_TID_MSK to use this field. */
-	u8 remove_immediate_ba_tid;
-
-	/* Starting Sequence Number for added block-ack support.
-	 * Set modify_mask bit STA_MODIFY_ADDBA_TID_MSK to use this field. */
-	__le16 add_immediate_ba_ssn;
-
-	/*
-	 * Number of packets OK to transmit to station even though
-	 * it is asleep -- used to synchronise PS-poll and u-APSD
-	 * responses while ucode keeps track of STA sleep state.
-	 */
-	__le16 sleep_tx_count;
-
-	__le16 reserved2;
-} __packed;
-
-/* agn */
 struct iwl_addsta_cmd {
 	u8 mode;		/* 1: modify existing, 0: add new station */
 	u8 reserved[3];
@@ -1337,62 +1085,6 @@
 #define RX_MPDU_RES_STATUS_DEC_DONE_MSK	(0x800)
 
 
-struct iwl3945_rx_frame_stats {
-	u8 phy_count;
-	u8 id;
-	u8 rssi;
-	u8 agc;
-	__le16 sig_avg;
-	__le16 noise_diff;
-	u8 payload[0];
-} __packed;
-
-struct iwl3945_rx_frame_hdr {
-	__le16 channel;
-	__le16 phy_flags;
-	u8 reserved1;
-	u8 rate;
-	__le16 len;
-	u8 payload[0];
-} __packed;
-
-struct iwl3945_rx_frame_end {
-	__le32 status;
-	__le64 timestamp;
-	__le32 beacon_timestamp;
-} __packed;
-
-/*
- * REPLY_3945_RX = 0x1b (response only, not a command)
- *
- * NOTE:  DO NOT dereference from casts to this structure
- * It is provided only for calculating minimum data set size.
- * The actual offsets of the hdr and end are dynamic based on
- * stats.phy_count
- */
-struct iwl3945_rx_frame {
-	struct iwl3945_rx_frame_stats stats;
-	struct iwl3945_rx_frame_hdr hdr;
-	struct iwl3945_rx_frame_end end;
-} __packed;
-
-#define IWL39_RX_FRAME_SIZE	(4 + sizeof(struct iwl3945_rx_frame))
-
-/* Fixed (non-configurable) rx data from phy */
-
-#define IWL49_RX_RES_PHY_CNT 14
-#define IWL49_RX_PHY_FLAGS_ANTENNAE_OFFSET	(4)
-#define IWL49_RX_PHY_FLAGS_ANTENNAE_MASK	(0x70)
-#define IWL49_AGC_DB_MASK			(0x3f80)	/* MASK(7,13) */
-#define IWL49_AGC_DB_POS			(7)
-struct iwl4965_rx_non_cfg_phy {
-	__le16 ant_selection;	/* ant A bit 4, ant B bit 5, ant C bit 6 */
-	__le16 agc_info;	/* agc code 0:6, agc dB 7:13, reserved 14:15 */
-	u8 rssi_info[6];	/* we use even entries, 0/2/4 for A/B/C rssi */
-	u8 pad[0];
-} __packed;
-
-
 #define IWLAGN_RX_RES_PHY_CNT 8
 #define IWLAGN_RX_RES_AGC_IDX     1
 #define IWLAGN_RX_RES_RSSI_AB_IDX 2
@@ -1576,80 +1268,6 @@
  * REPLY_TX = 0x1c (command)
  */
 
-struct iwl3945_tx_cmd {
-	/*
-	 * MPDU byte count:
-	 * MAC header (24/26/30/32 bytes) + 2 bytes pad if 26/30 header size,
-	 * + 8 byte IV for CCM or TKIP (not used for WEP)
-	 * + Data payload
-	 * + 8-byte MIC (not used for CCM/WEP)
-	 * NOTE:  Does not include Tx command bytes, post-MAC pad bytes,
-	 *        MIC (CCM) 8 bytes, ICV (WEP/TKIP/CKIP) 4 bytes, CRC 4 bytes.i
-	 * Range: 14-2342 bytes.
-	 */
-	__le16 len;
-
-	/*
-	 * MPDU or MSDU byte count for next frame.
-	 * Used for fragmentation and bursting, but not 11n aggregation.
-	 * Same as "len", but for next frame.  Set to 0 if not applicable.
-	 */
-	__le16 next_frame_len;
-
-	__le32 tx_flags;	/* TX_CMD_FLG_* */
-
-	u8 rate;
-
-	/* Index of recipient station in uCode's station table */
-	u8 sta_id;
-	u8 tid_tspec;
-	u8 sec_ctl;
-	u8 key[16];
-	union {
-		u8 byte[8];
-		__le16 word[4];
-		__le32 dw[2];
-	} tkip_mic;
-	__le32 next_frame_info;
-	union {
-		__le32 life_time;
-		__le32 attempt;
-	} stop_time;
-	u8 supp_rates[2];
-	u8 rts_retry_limit;	/*byte 50 */
-	u8 data_retry_limit;	/*byte 51 */
-	union {
-		__le16 pm_frame_timeout;
-		__le16 attempt_duration;
-	} timeout;
-
-	/*
-	 * Duration of EDCA burst Tx Opportunity, in 32-usec units.
-	 * Set this if txop time is not specified by HCCA protocol (e.g. by AP).
-	 */
-	__le16 driver_txop;
-
-	/*
-	 * MAC header goes here, followed by 2 bytes padding if MAC header
-	 * length is 26 or 30 bytes, followed by payload data
-	 */
-	u8 payload[0];
-	struct ieee80211_hdr hdr[0];
-} __packed;
-
-/*
- * REPLY_TX = 0x1c (response)
- */
-struct iwl3945_tx_resp {
-	u8 failure_rts;
-	u8 failure_frame;
-	u8 bt_kill_count;
-	u8 rate;
-	__le32 wireless_media_time;
-	__le32 status;		/* TX status */
-} __packed;
-
-
 /*
  * 4965 uCode updates these Tx attempt count values in host DRAM.
  * Used for managing Tx retries when expecting block-acks.
@@ -1740,54 +1358,6 @@
 	struct ieee80211_hdr hdr[0];
 } __packed;
 
-/* TX command response is sent after *3945* transmission attempts.
- *
- * NOTES:
- *
- * TX_STATUS_FAIL_NEXT_FRAG
- *
- * If the fragment flag in the MAC header for the frame being transmitted
- * is set and there is insufficient time to transmit the next frame, the
- * TX status will be returned with 'TX_STATUS_FAIL_NEXT_FRAG'.
- *
- * TX_STATUS_FIFO_UNDERRUN
- *
- * Indicates the host did not provide bytes to the FIFO fast enough while
- * a TX was in progress.
- *
- * TX_STATUS_FAIL_MGMNT_ABORT
- *
- * This status is only possible if the ABORT ON MGMT RX parameter was
- * set to true with the TX command.
- *
- * If the MSB of the status parameter is set then an abort sequence is
- * required.  This sequence consists of the host activating the TX Abort
- * control line, and then waiting for the TX Abort command response.  This
- * indicates that a the device is no longer in a transmit state, and that the
- * command FIFO has been cleared.  The host must then deactivate the TX Abort
- * control line.  Receiving is still allowed in this case.
- */
-enum {
-	TX_3945_STATUS_SUCCESS = 0x01,
-	TX_3945_STATUS_DIRECT_DONE = 0x02,
-	TX_3945_STATUS_FAIL_SHORT_LIMIT = 0x82,
-	TX_3945_STATUS_FAIL_LONG_LIMIT = 0x83,
-	TX_3945_STATUS_FAIL_FIFO_UNDERRUN = 0x84,
-	TX_3945_STATUS_FAIL_MGMNT_ABORT = 0x85,
-	TX_3945_STATUS_FAIL_NEXT_FRAG = 0x86,
-	TX_3945_STATUS_FAIL_LIFE_EXPIRE = 0x87,
-	TX_3945_STATUS_FAIL_DEST_PS = 0x88,
-	TX_3945_STATUS_FAIL_ABORTED = 0x89,
-	TX_3945_STATUS_FAIL_BT_RETRY = 0x8a,
-	TX_3945_STATUS_FAIL_STA_INVALID = 0x8b,
-	TX_3945_STATUS_FAIL_FRAG_DROPPED = 0x8c,
-	TX_3945_STATUS_FAIL_TID_DISABLE = 0x8d,
-	TX_3945_STATUS_FAIL_FRAME_FLUSHED = 0x8e,
-	TX_3945_STATUS_FAIL_INSUFFICIENT_CF_POLL = 0x8f,
-	TX_3945_STATUS_FAIL_TX_LOCKED = 0x90,
-	TX_3945_STATUS_FAIL_NO_BEACON_ON_RADAR = 0x91,
-};
-
 /*
  * TX command response is sent after *agn* transmission attempts.
  *
@@ -1905,43 +1475,6 @@
 	__le16 sequence;
 } __packed;
 
-struct iwl4965_tx_resp {
-	u8 frame_count;		/* 1 no aggregation, >1 aggregation */
-	u8 bt_kill_count;	/* # blocked by bluetooth (unused for agg) */
-	u8 failure_rts;		/* # failures due to unsuccessful RTS */
-	u8 failure_frame;	/* # failures due to no ACK (unused for agg) */
-
-	/* For non-agg:  Rate at which frame was successful.
-	 * For agg:  Rate at which all frames were transmitted. */
-	__le32 rate_n_flags;	/* RATE_MCS_*  */
-
-	/* For non-agg:  RTS + CTS + frame tx attempts time + ACK.
-	 * For agg:  RTS + CTS + aggregation tx time + block-ack time. */
-	__le16 wireless_media_time;	/* uSecs */
-
-	__le16 reserved;
-	__le32 pa_power1;	/* RF power amplifier measurement (not used) */
-	__le32 pa_power2;
-
-	/*
-	 * For non-agg:  frame status TX_STATUS_*
-	 * For agg:  status of 1st frame, AGG_TX_STATE_*; other frame status
-	 *           fields follow this one, up to frame_count.
-	 *           Bit fields:
-	 *           11- 0:  AGG_TX_STATE_* status code
-	 *           15-12:  Retry count for 1st frame in aggregation (retries
-	 *                   occur if tx failed for this frame when it was a
-	 *                   member of a previous aggregation block).  If rate
-	 *                   scaling is used, retry count indicates the rate
-	 *                   table entry used for all frames in the new agg.
-	 *           31-16:  Sequence # for this frame's Tx cmd (not SSN!)
-	 */
-	union {
-		__le32 status;
-		struct agg_tx_status agg_status[0]; /* for each agg frame */
-	} u;
-} __packed;
-
 /*
  * definitions for initial rate index field
  * bits [3:0] initial rate index
@@ -2030,51 +1563,7 @@
 /*
  * REPLY_TX_PWR_TABLE_CMD = 0x97 (command, has simple generic response)
  *
- * See details under "TXPOWER" in iwl-4965-hw.h.
- */
-
-struct iwl3945_txpowertable_cmd {
-	u8 band;		/* 0: 5 GHz, 1: 2.4 GHz */
-	u8 reserved;
-	__le16 channel;
-	struct iwl3945_power_per_rate power[IWL_MAX_RATES];
-} __packed;
-
-struct iwl4965_txpowertable_cmd {
-	u8 band;		/* 0: 5 GHz, 1: 2.4 GHz */
-	u8 reserved;
-	__le16 channel;
-	struct iwl4965_tx_power_db tx_power;
-} __packed;
-
-
-/**
- * struct iwl3945_rate_scaling_cmd - Rate Scaling Command & Response
- *
- * REPLY_RATE_SCALE = 0x47 (command, has simple generic response)
- *
- * NOTE: The table of rates passed to the uCode via the
- * RATE_SCALE command sets up the corresponding order of
- * rates used for all related commands, including rate
- * masks, etc.
- *
- * For example, if you set 9MB (PLCP 0x0f) as the first
- * rate in the rate table, the bit mask for that rate
- * when passed through ofdm_basic_rates on the REPLY_RXON
- * command would be bit 0 (1 << 0)
  */
-struct iwl3945_rate_scaling_info {
-	__le16 rate_n_flags;
-	u8 try_cnt;
-	u8 next_rate_index;
-} __packed;
-
-struct iwl3945_rate_scaling_cmd {
-	u8 table_id;
-	u8 reserved[3];
-	struct iwl3945_rate_scaling_info table[IWL_MAX_RATES];
-} __packed;
-
 
 /*RS_NEW_API: only TLC_RTS remains and moved to bit 0 */
 #define  LINK_QUAL_FLAGS_SET_STA_TLC_RTS_MSK	(1 << 0)
@@ -2130,7 +1619,7 @@
 #define LINK_QUAL_AGG_DISABLE_START_MAX	(255)
 #define LINK_QUAL_AGG_DISABLE_START_MIN	(0)
 
-#define LINK_QUAL_AGG_FRAME_LIMIT_DEF	(31)
+#define LINK_QUAL_AGG_FRAME_LIMIT_DEF	(63)
 #define LINK_QUAL_AGG_FRAME_LIMIT_MAX	(63)
 #define LINK_QUAL_AGG_FRAME_LIMIT_MIN	(0)
 
@@ -2696,14 +2185,6 @@
 #define IWL_POWER_BT_SCO_ENA			cpu_to_le16(BIT(8))
 #define IWL_POWER_ADVANCE_PM_ENA_MSK		cpu_to_le16(BIT(9))
 
-struct iwl3945_powertable_cmd {
-	__le16 flags;
-	u8 reserved[2];
-	__le32 rx_data_timeout;
-	__le32 tx_data_timeout;
-	__le32 sleep_interval[IWL_POWER_VEC_SIZE];
-} __packed;
-
 struct iwl_powertable_cmd {
 	__le16 flags;
 	u8 keep_alive_seconds;		/* 3945 reserved */
@@ -2806,25 +2287,6 @@
  *     active_dwell < max_out_time
  */
 
-/* FIXME: rename to AP1, remove tpc */
-struct iwl3945_scan_channel {
-	/*
-	 * type is defined as:
-	 * 0:0 1 = active, 0 = passive
-	 * 1:4 SSID direct bit map; if a bit is set, then corresponding
-	 *     SSID IE is transmitted in probe request.
-	 * 5:7 reserved
-	 */
-	u8 type;
-	u8 channel;	/* band is selected by iwl3945_scan_cmd "flags" field */
-	struct iwl3945_tx_power tpc;
-	__le16 active_dwell;	/* in 1024-uSec TU (time units), typ 5-50 */
-	__le16 passive_dwell;	/* in 1024-uSec TU (time units), typ 20-500 */
-} __packed;
-
-/* set number of direct probes u8 type */
-#define IWL39_SCAN_PROBE_MASK(n) ((BIT(n) | (BIT(n) - BIT(1))))
-
 struct iwl_scan_channel {
 	/*
 	 * type is defined as:
@@ -2920,50 +2382,6 @@
  * struct iwl_scan_channel.
  */
 
-struct iwl3945_scan_cmd {
-	__le16 len;
-	u8 reserved0;
-	u8 channel_count;	/* # channels in channel list */
-	__le16 quiet_time;	/* dwell only this # millisecs on quiet channel
-				 * (only for active scan) */
-	__le16 quiet_plcp_th;	/* quiet chnl is < this # pkts (typ. 1) */
-	__le16 good_CRC_th;	/* passive -> active promotion threshold */
-	__le16 reserved1;
-	__le32 max_out_time;	/* max usec to be away from associated (service)
-				 * channel */
-	__le32 suspend_time;	/* pause scan this long (in "extended beacon
-				 * format") when returning to service channel:
-				 * 3945; 31:24 # beacons, 19:0 additional usec,
-				 * 4965; 31:22 # beacons, 21:0 additional usec.
-				 */
-	__le32 flags;		/* RXON_FLG_* */
-	__le32 filter_flags;	/* RXON_FILTER_* */
-
-	/* For active scans (set to all-0s for passive scans).
-	 * Does not include payload.  Must specify Tx rate; no rate scaling. */
-	struct iwl3945_tx_cmd tx_cmd;
-
-	/* For directed active scans (set to all-0s otherwise) */
-	struct iwl_ssid_ie direct_scan[PROBE_OPTION_MAX_3945];
-
-	/*
-	 * Probe request frame, followed by channel list.
-	 *
-	 * Size of probe request frame is specified by byte count in tx_cmd.
-	 * Channel list follows immediately after probe request frame.
-	 * Number of channels in list is specified by channel_count.
-	 * Each channel in list is of type:
-	 *
-	 * struct iwl3945_scan_channel channels[0];
-	 *
-	 * NOTE:  Only one band of channels can be scanned per pass.  You
-	 * must not mix 2.4GHz channels and 5.2GHz channels, and you must wait
-	 * for one scan to complete (i.e. receive SCAN_COMPLETE_NOTIFICATION)
-	 * before requesting another scan.
-	 */
-	u8 data[0];
-} __packed;
-
 enum iwl_scan_flags {
 	/* BIT(0) currently unused */
 	IWL_SCAN_FLAGS_ACTION_FRAME_TX	= BIT(1),
@@ -3090,20 +2508,6 @@
  * BEACON_NOTIFICATION = 0x90 (notification only, not a command)
  */
 
-struct iwl3945_beacon_notif {
-	struct iwl3945_tx_resp beacon_notify_hdr;
-	__le32 low_tsf;
-	__le32 high_tsf;
-	__le32 ibss_mgr_status;
-} __packed;
-
-struct iwl4965_beacon_notif {
-	struct iwl4965_tx_resp beacon_notify_hdr;
-	__le32 low_tsf;
-	__le32 high_tsf;
-	__le32 ibss_mgr_status;
-} __packed;
-
 struct iwlagn_beacon_notif {
 	struct iwlagn_tx_resp beacon_notify_hdr;
 	__le32 low_tsf;
@@ -3115,14 +2519,6 @@
  * REPLY_TX_BEACON = 0x91 (command, has simple generic response)
  */
 
-struct iwl3945_tx_beacon_cmd {
-	struct iwl3945_tx_cmd tx;
-	__le16 tim_idx;
-	u8 tim_size;
-	u8 reserved1;
-	struct ieee80211_hdr frame[0];	/* beacon frame */
-} __packed;
-
 struct iwl_tx_beacon_cmd {
 	struct iwl_tx_cmd tx;
 	__le16 tim_idx;
@@ -3159,53 +2555,6 @@
 
 /* statistics command response */
 
-struct iwl39_statistics_rx_phy {
-	__le32 ina_cnt;
-	__le32 fina_cnt;
-	__le32 plcp_err;
-	__le32 crc32_err;
-	__le32 overrun_err;
-	__le32 early_overrun_err;
-	__le32 crc32_good;
-	__le32 false_alarm_cnt;
-	__le32 fina_sync_err_cnt;
-	__le32 sfd_timeout;
-	__le32 fina_timeout;
-	__le32 unresponded_rts;
-	__le32 rxe_frame_limit_overrun;
-	__le32 sent_ack_cnt;
-	__le32 sent_cts_cnt;
-} __packed;
-
-struct iwl39_statistics_rx_non_phy {
-	__le32 bogus_cts;	/* CTS received when not expecting CTS */
-	__le32 bogus_ack;	/* ACK received when not expecting ACK */
-	__le32 non_bssid_frames;	/* number of frames with BSSID that
-					 * doesn't belong to the STA BSSID */
-	__le32 filtered_frames;	/* count frames that were dumped in the
-				 * filtering process */
-	__le32 non_channel_beacons;	/* beacons with our bss id but not on
-					 * our serving channel */
-} __packed;
-
-struct iwl39_statistics_rx {
-	struct iwl39_statistics_rx_phy ofdm;
-	struct iwl39_statistics_rx_phy cck;
-	struct iwl39_statistics_rx_non_phy general;
-} __packed;
-
-struct iwl39_statistics_tx {
-	__le32 preamble_cnt;
-	__le32 rx_detected_cnt;
-	__le32 bt_prio_defer_cnt;
-	__le32 bt_prio_kill_cnt;
-	__le32 few_bytes_cnt;
-	__le32 cts_timeout;
-	__le32 ack_timeout;
-	__le32 expected_ack_cnt;
-	__le32 actual_ack_cnt;
-} __packed;
-
 struct statistics_dbg {
 	__le32 burst_check;
 	__le32 burst_count;
@@ -3213,23 +2562,6 @@
 	__le32 reserved[3];
 } __packed;
 
-struct iwl39_statistics_div {
-	__le32 tx_on_a;
-	__le32 tx_on_b;
-	__le32 exec_time;
-	__le32 probe_time;
-} __packed;
-
-struct iwl39_statistics_general {
-	__le32 temperature;
-	struct statistics_dbg dbg;
-	__le32 sleep_time;
-	__le32 slots_out;
-	__le32 slots_idle;
-	__le32 ttl_timestamp;
-	struct iwl39_statistics_div div;
-} __packed;
-
 struct statistics_rx_phy {
 	__le32 ina_cnt;
 	__le32 fina_cnt;
@@ -3471,13 +2803,6 @@
 #define STATISTICS_REPLY_FLG_BAND_24G_MSK         cpu_to_le32(0x2)
 #define STATISTICS_REPLY_FLG_HT40_MODE_MSK        cpu_to_le32(0x8)
 
-struct iwl3945_notif_statistics {
-	__le32 flag;
-	struct iwl39_statistics_rx rx;
-	struct iwl39_statistics_tx tx;
-	struct iwl39_statistics_general general;
-} __packed;
-
 struct iwl_notif_statistics {
 	__le32 flag;
 	struct statistics_rx rx;
@@ -4451,10 +3776,6 @@
 	__le32 len_n_flags;
 	struct iwl_cmd_header hdr;
 	union {
-		struct iwl3945_rx_frame rx_frame;
-		struct iwl3945_tx_resp tx_resp;
-		struct iwl3945_beacon_notif beacon_status;
-
 		struct iwl_alive_resp alive_frame;
 		struct iwl_spectrum_notification spectrum_notif;
 		struct iwl_csa_notification csa_notif;
diff -druN linux-2.6.39-libre/drivers/net/wireless/iwlwifi/iwl-core.c linux-3.0-rc7-libre/drivers/net/wireless/iwlwifi/iwl-core.c
--- linux-2.6.39-libre/drivers/net/wireless/iwlwifi/iwl-core.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/iwlwifi/iwl-core.c	2011-07-11 19:51:52.000000000 -0400
@@ -2,7 +2,7 @@
  *
  * GPL LICENSE SUMMARY
  *
- * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2008 - 2011 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
@@ -41,6 +41,7 @@
 #include "iwl-power.h"
 #include "iwl-sta.h"
 #include "iwl-helpers.h"
+#include "iwl-agn.h"
 
 
 /*
@@ -67,30 +68,6 @@
 
 const u8 iwl_bcast_addr[ETH_ALEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
 
-
-/* This function both allocates and initializes hw and priv. */
-struct ieee80211_hw *iwl_alloc_all(struct iwl_cfg *cfg)
-{
-	struct iwl_priv *priv;
-	/* mac80211 allocates memory for this device instance, including
-	 *   space for this driver's private structure */
-	struct ieee80211_hw *hw;
-
-	hw = ieee80211_alloc_hw(sizeof(struct iwl_priv),
-				cfg->ops->ieee80211_ops);
-	if (hw == NULL) {
-		pr_err("%s: Can not allocate network device\n",
-		       cfg->name);
-		goto out;
-	}
-
-	priv = hw->priv;
-	priv->hw = hw;
-
-out:
-	return hw;
-}
-
 #define MAX_BIT_RATE_40_MHZ 150 /* Mbps */
 #define MAX_BIT_RATE_20_MHZ 72 /* Mbps */
 static void iwlcore_init_ht_hw_capab(const struct iwl_priv *priv,
@@ -118,7 +95,7 @@
 		max_bit_rate = MAX_BIT_RATE_40_MHZ;
 	}
 
-	if (priv->cfg->mod_params->amsdu_size_8K)
+	if (iwlagn_mod_params.amsdu_size_8K)
 		ht_info->cap |= IEEE80211_HT_CAP_MAX_AMSDU;
 
 	ht_info->ampdu_factor = CFG_HT_RX_AMPDU_FACTOR_DEF;
@@ -159,6 +136,7 @@
 	struct ieee80211_channel *geo_ch;
 	struct ieee80211_rate *rates;
 	int i = 0;
+	s8 max_tx_power = IWLAGN_TX_POWER_TARGET_POWER_MIN;
 
 	if (priv->bands[IEEE80211_BAND_2GHZ].n_bitrates ||
 	    priv->bands[IEEE80211_BAND_5GHZ].n_bitrates) {
@@ -232,8 +210,8 @@
 
 			geo_ch->flags |= ch->ht40_extension_channel;
 
-			if (ch->max_power_avg > priv->tx_power_device_lmt)
-				priv->tx_power_device_lmt = ch->max_power_avg;
+			if (ch->max_power_avg > max_tx_power)
+				max_tx_power = ch->max_power_avg;
 		} else {
 			geo_ch->flags |= IEEE80211_CHAN_DISABLED;
 		}
@@ -246,6 +224,10 @@
 				 geo_ch->flags);
 	}
 
+	priv->tx_power_device_lmt = max_tx_power;
+	priv->tx_power_user_lmt = max_tx_power;
+	priv->tx_power_next = max_tx_power;
+
 	if ((priv->bands[IEEE80211_BAND_5GHZ].n_channels == 0) &&
 	     priv->cfg->sku & IWL_SKU_A) {
 		IWL_INFO(priv, "Incorrectly detected BG card as ABG. "
@@ -434,72 +416,72 @@
 int iwl_check_rxon_cmd(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
 {
 	struct iwl_rxon_cmd *rxon = &ctx->staging;
-	bool error = false;
+	u32 errors = 0;
 
 	if (rxon->flags & RXON_FLG_BAND_24G_MSK) {
 		if (rxon->flags & RXON_FLG_TGJ_NARROW_BAND_MSK) {
 			IWL_WARN(priv, "check 2.4G: wrong narrow\n");
-			error = true;
+			errors |= BIT(0);
 		}
 		if (rxon->flags & RXON_FLG_RADAR_DETECT_MSK) {
 			IWL_WARN(priv, "check 2.4G: wrong radar\n");
-			error = true;
+			errors |= BIT(1);
 		}
 	} else {
 		if (!(rxon->flags & RXON_FLG_SHORT_SLOT_MSK)) {
 			IWL_WARN(priv, "check 5.2G: not short slot!\n");
-			error = true;
+			errors |= BIT(2);
 		}
 		if (rxon->flags & RXON_FLG_CCK_MSK) {
 			IWL_WARN(priv, "check 5.2G: CCK!\n");
-			error = true;
+			errors |= BIT(3);
 		}
 	}
 	if ((rxon->node_addr[0] | rxon->bssid_addr[0]) & 0x1) {
 		IWL_WARN(priv, "mac/bssid mcast!\n");
-		error = true;
+		errors |= BIT(4);
 	}
 
 	/* make sure basic rates 6Mbps and 1Mbps are supported */
 	if ((rxon->ofdm_basic_rates & IWL_RATE_6M_MASK) == 0 &&
 	    (rxon->cck_basic_rates & IWL_RATE_1M_MASK) == 0) {
 		IWL_WARN(priv, "neither 1 nor 6 are basic\n");
-		error = true;
+		errors |= BIT(5);
 	}
 
 	if (le16_to_cpu(rxon->assoc_id) > 2007) {
 		IWL_WARN(priv, "aid > 2007\n");
-		error = true;
+		errors |= BIT(6);
 	}
 
 	if ((rxon->flags & (RXON_FLG_CCK_MSK | RXON_FLG_SHORT_SLOT_MSK))
 			== (RXON_FLG_CCK_MSK | RXON_FLG_SHORT_SLOT_MSK)) {
 		IWL_WARN(priv, "CCK and short slot\n");
-		error = true;
+		errors |= BIT(7);
 	}
 
 	if ((rxon->flags & (RXON_FLG_CCK_MSK | RXON_FLG_AUTO_DETECT_MSK))
 			== (RXON_FLG_CCK_MSK | RXON_FLG_AUTO_DETECT_MSK)) {
 		IWL_WARN(priv, "CCK and auto detect");
-		error = true;
+		errors |= BIT(8);
 	}
 
 	if ((rxon->flags & (RXON_FLG_AUTO_DETECT_MSK |
 			    RXON_FLG_TGG_PROTECT_MSK)) ==
 			    RXON_FLG_TGG_PROTECT_MSK) {
 		IWL_WARN(priv, "TGg but no auto-detect\n");
-		error = true;
+		errors |= BIT(9);
 	}
 
-	if (error)
-		IWL_WARN(priv, "Tuning to channel %d\n",
-			    le16_to_cpu(rxon->channel));
-
-	if (error) {
-		IWL_ERR(priv, "Invalid RXON\n");
-		return -EINVAL;
+	if (rxon->channel == 0) {
+		IWL_WARN(priv, "zero channel is invalid\n");
+		errors |= BIT(10);
 	}
-	return 0;
+
+	WARN(errors, "Invalid RXON (%#x), channel %d",
+	     errors, le16_to_cpu(rxon->channel));
+
+	return errors ? -EINVAL : 0;
 }
 
 /**
@@ -861,12 +843,8 @@
 	if (test_bit(STATUS_EXIT_PENDING, &priv->status))
 		return;
 
-	if (priv->switch_rxon.switch_in_progress) {
+	if (test_and_clear_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->status))
 		ieee80211_chswitch_done(ctx->vif, is_success);
-		mutex_lock(&priv->mutex);
-		priv->switch_rxon.switch_in_progress = false;
-		mutex_unlock(&priv->mutex);
-	}
 }
 
 #ifdef CONFIG_IWLWIFI_DEBUG
@@ -890,10 +868,21 @@
 	IWL_DEBUG_RADIO(priv, "u16 assoc_id: 0x%x\n", le16_to_cpu(rxon->assoc_id));
 }
 #endif
-/**
- * iwl_irq_handle_error - called for HW or SW error interrupt from card
- */
-void iwl_irq_handle_error(struct iwl_priv *priv)
+
+static void iwlagn_abort_notification_waits(struct iwl_priv *priv)
+{
+	unsigned long flags;
+	struct iwl_notification_wait *wait_entry;
+
+	spin_lock_irqsave(&priv->_agn.notif_wait_lock, flags);
+	list_for_each_entry(wait_entry, &priv->_agn.notif_waits, list)
+		wait_entry->aborted = true;
+	spin_unlock_irqrestore(&priv->_agn.notif_wait_lock, flags);
+
+	wake_up_all(&priv->_agn.notif_waitq);
+}
+
+void iwlagn_fw_error(struct iwl_priv *priv, bool ondemand)
 {
 	unsigned int reload_msec;
 	unsigned long reload_jiffies;
@@ -904,18 +893,64 @@
 	/* Cancel currently queued command. */
 	clear_bit(STATUS_HCMD_ACTIVE, &priv->status);
 
+	iwlagn_abort_notification_waits(priv);
+
+	/* Keep the restart process from trying to send host
+	 * commands by clearing the ready bit */
+	clear_bit(STATUS_READY, &priv->status);
+
+	wake_up_interruptible(&priv->wait_command_queue);
+
+	if (!ondemand) {
+		/*
+		 * If firmware keep reloading, then it indicate something
+		 * serious wrong and firmware having problem to recover
+		 * from it. Instead of keep trying which will fill the syslog
+		 * and hang the system, let's just stop it
+		 */
+		reload_jiffies = jiffies;
+		reload_msec = jiffies_to_msecs((long) reload_jiffies -
+					(long) priv->reload_jiffies);
+		priv->reload_jiffies = reload_jiffies;
+		if (reload_msec <= IWL_MIN_RELOAD_DURATION) {
+			priv->reload_count++;
+			if (priv->reload_count >= IWL_MAX_CONTINUE_RELOAD_CNT) {
+				IWL_ERR(priv, "BUG_ON, Stop restarting\n");
+				return;
+			}
+		} else
+			priv->reload_count = 0;
+	}
+
+	if (!test_bit(STATUS_EXIT_PENDING, &priv->status)) {
+		if (iwlagn_mod_params.restart_fw) {
+			IWL_DEBUG(priv, IWL_DL_FW_ERRORS,
+				  "Restarting adapter due to uCode error.\n");
+			queue_work(priv->workqueue, &priv->restart);
+		} else
+			IWL_DEBUG(priv, IWL_DL_FW_ERRORS,
+				  "Detected FW error, but not restarting\n");
+	}
+}
+
+/**
+ * iwl_irq_handle_error - called for HW or SW error interrupt from card
+ */
+void iwl_irq_handle_error(struct iwl_priv *priv)
+{
 	/* W/A for WiFi/WiMAX coex and WiMAX own the RF */
 	if (priv->cfg->internal_wimax_coex &&
 	    (!(iwl_read_prph(priv, APMG_CLK_CTRL_REG) &
 			APMS_CLK_VAL_MRB_FUNC_MODE) ||
 	     (iwl_read_prph(priv, APMG_PS_CTRL_REG) &
 			APMG_PS_CTRL_VAL_RESET_REQ))) {
-		wake_up_interruptible(&priv->wait_command_queue);
 		/*
-		 *Keep the restart process from trying to send host
-		 * commands by clearing the INIT status bit
+		 * Keep the restart process from trying to send host
+		 * commands by clearing the ready bit.
 		 */
 		clear_bit(STATUS_READY, &priv->status);
+		clear_bit(STATUS_HCMD_ACTIVE, &priv->status);
+		wake_up_interruptible(&priv->wait_command_queue);
 		IWL_ERR(priv, "RF is used by WiMAX\n");
 		return;
 	}
@@ -923,50 +958,17 @@
 	IWL_ERR(priv, "Loaded firmware version: %s\n",
 		priv->hw->wiphy->fw_version);
 
-	priv->cfg->ops->lib->dump_nic_error_log(priv);
-	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);
+	iwl_dump_nic_error_log(priv);
+	iwl_dump_csr(priv);
+	iwl_dump_fh(priv, NULL, false);
+	iwl_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,
 					&priv->contexts[IWL_RXON_CTX_BSS]);
 #endif
 
-	wake_up_interruptible(&priv->wait_command_queue);
-
-	/* Keep the restart process from trying to send host
-	 * commands by clearing the INIT status bit */
-	clear_bit(STATUS_READY, &priv->status);
-
-	/*
-	 * If firmware keep reloading, then it indicate something
-	 * serious wrong and firmware having problem to recover
-	 * from it. Instead of keep trying which will fill the syslog
-	 * and hang the system, let's just stop it
-	 */
-	reload_jiffies = jiffies;
-	reload_msec = jiffies_to_msecs((long) reload_jiffies -
-				(long) priv->reload_jiffies);
-	priv->reload_jiffies = reload_jiffies;
-	if (reload_msec <= IWL_MIN_RELOAD_DURATION) {
-		priv->reload_count++;
-		if (priv->reload_count >= IWL_MAX_CONTINUE_RELOAD_CNT) {
-			IWL_ERR(priv, "BUG_ON, Stop restarting\n");
-			return;
-		}
-	} else
-		priv->reload_count = 0;
-
-	if (!test_bit(STATUS_EXIT_PENDING, &priv->status)) {
-		IWL_DEBUG(priv, IWL_DL_FW_ERRORS,
-			  "Restarting adapter due to uCode error.\n");
-
-		if (priv->cfg->mod_params->restart_fw)
-			queue_work(priv->workqueue, &priv->restart);
-	}
+	iwlagn_fw_error(priv, false);
 }
 
 static int iwl_apm_stop_master(struct iwl_priv *priv)
@@ -990,6 +992,8 @@
 {
 	IWL_DEBUG_INFO(priv, "Stop card, put in low power state\n");
 
+	clear_bit(STATUS_DEVICE_ENABLED, &priv->status);
+
 	/* Stop device's DMA activity */
 	iwl_apm_stop_master(priv);
 
@@ -1040,7 +1044,6 @@
 	/*
 	 * Enable HAP INTA (interrupt from management bus) to
 	 * wake device's PCI Express link L1a -> L0s
-	 * NOTE:  This is no-op for 3945 (non-existent bit)
 	 */
 	iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG,
 				    CSR_HW_IF_CONFIG_REG_BIT_HAP_WAKE_L1A);
@@ -1053,20 +1056,18 @@
 	 * If not (unlikely), enable L0S, so there is at least some
 	 *    power savings, even without L1.
 	 */
-	if (priv->cfg->base_params->set_l0s) {
-		lctl = iwl_pcie_link_ctl(priv);
-		if ((lctl & PCI_CFG_LINK_CTRL_VAL_L1_EN) ==
-					PCI_CFG_LINK_CTRL_VAL_L1_EN) {
-			/* L1-ASPM enabled; disable(!) L0S  */
-			iwl_set_bit(priv, CSR_GIO_REG,
-					CSR_GIO_REG_VAL_L0S_ENABLED);
-			IWL_DEBUG_POWER(priv, "L1 Enabled; Disabling L0S\n");
-		} else {
-			/* L1-ASPM disabled; enable(!) L0S */
-			iwl_clear_bit(priv, CSR_GIO_REG,
-					CSR_GIO_REG_VAL_L0S_ENABLED);
-			IWL_DEBUG_POWER(priv, "L1 Disabled; Enabling L0S\n");
-		}
+	lctl = iwl_pcie_link_ctl(priv);
+	if ((lctl & PCI_CFG_LINK_CTRL_VAL_L1_EN) ==
+				PCI_CFG_LINK_CTRL_VAL_L1_EN) {
+		/* L1-ASPM enabled; disable(!) L0S  */
+		iwl_set_bit(priv, CSR_GIO_REG,
+				CSR_GIO_REG_VAL_L0S_ENABLED);
+		IWL_DEBUG_POWER(priv, "L1 Enabled; Disabling L0S\n");
+	} else {
+		/* L1-ASPM disabled; enable(!) L0S */
+		iwl_clear_bit(priv, CSR_GIO_REG,
+				CSR_GIO_REG_VAL_L0S_ENABLED);
+		IWL_DEBUG_POWER(priv, "L1 Disabled; Enabling L0S\n");
 	}
 
 	/* Configure analog phase-lock-loop before activating to D0A */
@@ -1094,27 +1095,21 @@
 	}
 
 	/*
-	 * Enable DMA and BSM (if used) clocks, wait for them to stabilize.
-	 * BSM (Boostrap State Machine) is only in 3945 and 4965;
-	 * later devices (i.e. 5000 and later) have non-volatile SRAM,
-	 * and don't need BSM to restore data after power-saving sleep.
+	 * Enable DMA clock and wait for it to stabilize.
 	 *
 	 * Write to "CLK_EN_REG"; "1" bits enable clocks, while "0" bits
 	 * do not disable clocks.  This preserves any hardware bits already
 	 * set by default in "CLK_CTRL_REG" after reset.
 	 */
-	if (priv->cfg->base_params->use_bsm)
-		iwl_write_prph(priv, APMG_CLK_EN_REG,
-			APMG_CLK_VAL_DMA_CLK_RQT | APMG_CLK_VAL_BSM_CLK_RQT);
-	else
-		iwl_write_prph(priv, APMG_CLK_EN_REG,
-			APMG_CLK_VAL_DMA_CLK_RQT);
+	iwl_write_prph(priv, APMG_CLK_EN_REG, APMG_CLK_VAL_DMA_CLK_RQT);
 	udelay(20);
 
 	/* Disable L1-Active */
 	iwl_set_bits_prph(priv, APMG_PCIDEV_STT_REG,
 			  APMG_PCIDEV_STT_VAL_L1_ACT_DIS);
 
+	set_bit(STATUS_DEVICE_ENABLED, &priv->status);
+
 out:
 	return ret;
 }
@@ -1430,7 +1425,6 @@
 
 	iwl_teardown_interface(priv, vif, false);
 
-	memset(priv->bssid, 0, ETH_ALEN);
 	mutex_unlock(&priv->mutex);
 
 	IWL_DEBUG_MAC80211(priv, "leave\n");
@@ -1750,21 +1744,13 @@
 		 * detect failure), then fw_restart module parameter
 		 * need to be check before performing firmware reload
 		 */
-		if (!external && !priv->cfg->mod_params->restart_fw) {
+		if (!external && !iwlagn_mod_params.restart_fw) {
 			IWL_DEBUG_INFO(priv, "Cancel firmware reload based on "
 				       "module parameter setting\n");
 			break;
 		}
 		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);
+		iwlagn_fw_error(priv, true);
 		break;
 	}
 	return 0;
@@ -1775,7 +1761,9 @@
 {
 	struct iwl_priv *priv = hw->priv;
 	struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif);
+	struct iwl_rxon_context *bss_ctx = &priv->contexts[IWL_RXON_CTX_BSS];
 	struct iwl_rxon_context *tmp;
+	enum nl80211_iftype newviftype = newtype;
 	u32 interface_modes;
 	int err;
 
@@ -1783,6 +1771,15 @@
 
 	mutex_lock(&priv->mutex);
 
+	if (!ctx->vif || !iwl_is_ready_rf(priv)) {
+		/*
+		 * Huh? But wait ... this can maybe happen when
+		 * we're in the middle of a firmware restart!
+		 */
+		err = -EBUSY;
+		goto out;
+	}
+
 	interface_modes = ctx->interface_modes | ctx->exclusive_interface_modes;
 
 	if (!(interface_modes & BIT(newtype))) {
@@ -1790,6 +1787,19 @@
 		goto out;
 	}
 
+	/*
+	 * Refuse a change that should be done by moving from the PAN
+	 * context to the BSS context instead, if the BSS context is
+	 * available and can support the new interface type.
+	 */
+	if (ctx->ctxid == IWL_RXON_CTX_PAN && !bss_ctx->vif &&
+	    (bss_ctx->interface_modes & BIT(newtype) ||
+	     bss_ctx->exclusive_interface_modes & BIT(newtype))) {
+		BUILD_BUG_ON(NUM_IWL_RXON_CTX != 2);
+		err = -EBUSY;
+		goto out;
+	}
+
 	if (ctx->exclusive_interface_modes & BIT(newtype)) {
 		for_each_context(priv, tmp) {
 			if (ctx == tmp)
@@ -1809,7 +1819,8 @@
 
 	/* success */
 	iwl_teardown_interface(priv, vif, true);
-	vif->type = newtype;
+	vif->type = newviftype;
+	vif->p2p = newp2p;
 	err = iwl_setup_interface(priv, ctx);
 	WARN_ON(err);
 	/*
diff -druN linux-2.6.39-libre/drivers/net/wireless/iwlwifi/iwl-core.h linux-3.0-rc7-libre/drivers/net/wireless/iwlwifi/iwl-core.h
--- linux-2.6.39-libre/drivers/net/wireless/iwlwifi/iwl-core.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/iwlwifi/iwl-core.h	2011-07-11 19:51:52.000000000 -0400
@@ -5,7 +5,7 @@
  *
  * GPL LICENSE SUMMARY
  *
- * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2008 - 2011 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 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -73,7 +73,7 @@
 
 
 #define IWLWIFI_VERSION "in-tree:"
-#define DRV_COPYRIGHT	"Copyright(c) 2003-2010 Intel Corporation"
+#define DRV_COPYRIGHT	"Copyright(c) 2003-2011 Intel Corporation"
 #define DRV_AUTHOR     "<ilw@linux.intel.com>"
 
 #define IWL_PCI_DEVICE(dev, subdev, cfg) \
@@ -90,7 +90,6 @@
 #define IWL_CMD(x) case x: return #x
 
 struct iwl_hcmd_ops {
-	int (*rxon_assoc)(struct iwl_priv *priv, struct iwl_rxon_context *ctx);
 	int (*commit_rxon)(struct iwl_priv *priv, struct iwl_rxon_context *ctx);
 	void (*set_rxon_chain)(struct iwl_priv *priv,
 			       struct iwl_rxon_context *ctx);
@@ -100,7 +99,6 @@
 };
 
 struct iwl_hcmd_utils_ops {
-	u16 (*get_hcmd_size)(u8 cmd_id, u16 len);
 	u16 (*build_addsta_hcmd)(const struct iwl_addsta_cmd *cmd, u8 *data);
 	void (*gain_computation)(struct iwl_priv *priv,
 			u32 *average_noise,
@@ -122,79 +120,21 @@
 	void (*config)(struct iwl_priv *priv);
 };
 
-struct iwl_isr_ops {
-	irqreturn_t (*isr) (int irq, void *data);
-	void (*free)(struct iwl_priv *priv);
-	int (*alloc)(struct iwl_priv *priv);
-	int (*reset)(struct iwl_priv *priv);
-	void (*disable)(struct iwl_priv *priv);
-};
-
-struct iwl_debugfs_ops {
-	ssize_t (*rx_stats_read)(struct file *file, char __user *user_buf,
-				 size_t count, loff_t *ppos);
-	ssize_t (*tx_stats_read)(struct file *file, char __user *user_buf,
-				 size_t count, loff_t *ppos);
-	ssize_t (*general_stats_read)(struct file *file, char __user *user_buf,
-				      size_t count, loff_t *ppos);
-	ssize_t (*bt_stats_read)(struct file *file, char __user *user_buf,
-				 size_t count, loff_t *ppos);
-	ssize_t (*reply_tx_error)(struct file *file, char __user *user_buf,
-				 size_t count, loff_t *ppos);
-};
-
 struct iwl_temp_ops {
 	void (*temperature)(struct iwl_priv *priv);
 };
 
-struct iwl_tt_ops {
-	bool (*lower_power_detection)(struct iwl_priv *priv);
-	u8 (*tt_power_mode)(struct iwl_priv *priv);
-	bool (*ct_kill_check)(struct iwl_priv *priv);
-};
-
 struct iwl_lib_ops {
 	/* set hw dependent parameters */
 	int (*set_hw_params)(struct iwl_priv *priv);
-	/* Handling TX */
-	void (*txq_update_byte_cnt_tbl)(struct iwl_priv *priv,
-					struct iwl_tx_queue *txq,
-					u16 byte_cnt);
-	void (*txq_inval_byte_cnt_tbl)(struct iwl_priv *priv,
-				       struct iwl_tx_queue *txq);
-	void (*txq_set_sched)(struct iwl_priv *priv, u32 mask);
-	int (*txq_attach_buf_to_tfd)(struct iwl_priv *priv,
-				     struct iwl_tx_queue *txq,
-				     dma_addr_t addr,
-				     u16 len, u8 reset, u8 pad);
-	void (*txq_free_tfd)(struct iwl_priv *priv,
-			     struct iwl_tx_queue *txq);
-	int (*txq_init)(struct iwl_priv *priv,
-			struct iwl_tx_queue *txq);
-	/* aggregations */
-	int (*txq_agg_enable)(struct iwl_priv *priv, int txq_id, int tx_fifo,
-			      int sta_id, int tid, u16 ssn_idx);
-	int (*txq_agg_disable)(struct iwl_priv *priv, u16 txq_id, u16 ssn_idx,
-			       u8 tx_fifo);
 	/* setup Rx handler */
 	void (*rx_handler_setup)(struct iwl_priv *priv);
 	/* setup deferred work */
 	void (*setup_deferred_work)(struct iwl_priv *priv);
 	/* cancel deferred work */
 	void (*cancel_deferred_work)(struct iwl_priv *priv);
-	/* alive notification after init uCode load */
-	void (*init_alive_start)(struct iwl_priv *priv);
-	/* alive notification */
-	int (*alive_notify)(struct iwl_priv *priv);
 	/* check validity of rtc data address */
 	int (*is_valid_rtc_data_addr)(u32 addr);
-	/* 1st ucode load */
-	int (*load_ucode)(struct iwl_priv *priv);
-	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,
 				  struct ieee80211_channel_switch *ch_switch);
 	/* power management */
@@ -204,9 +144,6 @@
 	int (*send_tx_power) (struct iwl_priv *priv);
 	void (*update_chain_flags)(struct iwl_priv *priv);
 
-	/* isr */
-	struct iwl_isr_ops isr_ops;
-
 	/* eeprom operations (as defined in iwl-eeprom.h) */
 	struct iwl_eeprom_ops eeprom_ops;
 
@@ -216,14 +153,6 @@
 	int (*txfifo_flush)(struct iwl_priv *priv, u16 flush_control);
 	void (*dev_txfifo_flush)(struct iwl_priv *priv, u16 flush_control);
 
-	struct iwl_debugfs_ops debugfs_ops;
-
-	/* thermal throttling */
-	struct iwl_tt_ops tt_ops;
-};
-
-struct iwl_led_ops {
-	int (*cmd)(struct iwl_priv *priv, struct iwl_led_cmd *led_cmd);
 };
 
 /* NIC specific ops */
@@ -231,28 +160,15 @@
 	void (*additional_nic_config)(struct iwl_priv *priv);
 };
 
-struct iwl_legacy_ops {
-	void (*post_associate)(struct iwl_priv *priv);
-	void (*config_ap)(struct iwl_priv *priv);
-	/* station management */
-	int (*update_bcast_stations)(struct iwl_priv *priv);
-	int (*manage_ibss_station)(struct iwl_priv *priv,
-				   struct ieee80211_vif *vif, bool add);
-};
-
 struct iwl_ops {
 	const struct iwl_lib_ops *lib;
 	const struct iwl_hcmd_ops *hcmd;
 	const struct iwl_hcmd_utils_ops *utils;
-	const struct iwl_led_ops *led;
 	const struct iwl_nic_ops *nic;
-	const struct iwl_legacy_ops *legacy;
-	const struct ieee80211_ops *ieee80211_ops;
 };
 
 struct iwl_mod_params {
 	int sw_crypto;		/* def: 0 = using hardware encryption */
-	int disable_hw_scan;	/* def: 0 = use h/w scan */
 	int num_of_queues;	/* def: HW dependent */
 	int disable_11n;	/* def: 0 = 11n capabilities enabled */
 	int amsdu_size_8K;	/* def: 1 = enable 8K amsdu size */
@@ -278,16 +194,7 @@
  * @wd_timeout: TX queues watchdog timeout
  * @temperature_kelvin: temperature report by uCode in kelvin
  * @max_event_log_size: size of event log buffer size for ucode event logging
- * @tx_power_by_driver: tx power calibration performed by driver
- *	instead of uCode
- * @ucode_tracing: support ucode continuous tracing
- * @sensitivity_calib_by_driver: driver has the capability to perform
- *	sensitivity calibration operation
- * @chain_noise_calib_by_driver: driver has the capability to perform
- *	chain noise calibration operation
  * @shadow_reg_enable: HW shadhow register bit
- * @no_agg_framecnt_info: uCode do not provide aggregation frame count
- *	information
  */
 struct iwl_base_params {
 	int eeprom_size;
@@ -295,14 +202,10 @@
 	int num_of_ampdu_queues;/* def: HW dependent */
 	/* for iwl_apm_init() */
 	u32 pll_cfg_val;
-	bool set_l0s;
-	bool use_bsm;
 
-	bool use_isr_legacy;
 	const u16 max_ll_items;
 	const bool shadow_ram_support;
 	u16 led_compensation;
-	const bool broken_powersave;
 	int chain_noise_num_beacons;
 	bool adv_thermal_throttle;
 	bool support_ct_kill_exit;
@@ -312,18 +215,12 @@
 	unsigned int wd_timeout;
 	bool temperature_kelvin;
 	u32 max_event_log_size;
-	const bool tx_power_by_driver;
-	const bool ucode_tracing;
-	const bool sensitivity_calib_by_driver;
-	const bool chain_noise_calib_by_driver;
 	const bool shadow_reg_enable;
-	const bool no_agg_framecnt_info;
 };
 /*
  * @advanced_bt_coexist: support advanced bt coexist
  * @bt_init_traffic_load: specify initial bt traffic load
  * @bt_prio_boost: default bt priority boost value
- * @bt_statistics: use BT version of statistics notification
  * @agg_time_limit: maximum number of uSec in aggregation
  * @ampdu_factor: Maximum A-MPDU length factor
  * @ampdu_density: Minimum A-MPDU spacing
@@ -333,7 +230,6 @@
 	bool advanced_bt_coexist;
 	u8 bt_init_traffic_load;
 	u8 bt_prio_boost;
-	const bool bt_statistics;
 	u16 agg_time_limit;
 	u8 ampdu_factor;
 	u8 ampdu_density;
@@ -364,6 +260,7 @@
  * @rx_with_siso_diversity: 1x1 device with rx antenna diversity
  * @internal_wimax_coex: internal wifi/wimax combo device
  * @iq_invert: I/Q inversion
+ * @disable_otp_refresh: disable OTP refresh current limit
  *
  * We enable the driver to be backward compatible wrt API version. The
  * driver specifies which APIs it supports (with @ucode_api_max being the
@@ -398,8 +295,6 @@
 	u16  eeprom_ver;
 	u16  eeprom_calib_ver;
 	const struct iwl_ops *ops;
-	/* module based parameters which can be set from modprobe cmd */
-	const struct iwl_mod_params *mod_params;
 	/* params not likely to change within a device family */
 	struct iwl_base_params *base_params;
 	/* params likely to change within a device family */
@@ -414,13 +309,13 @@
 	const bool rx_with_siso_diversity;
 	const bool internal_wimax_coex;
 	const bool iq_invert;
+	const bool disable_otp_refresh;
 };
 
 /***************************
  *   L i b                 *
  ***************************/
 
-struct ieee80211_hw *iwl_alloc_all(struct iwl_cfg *cfg);
 int iwl_mac_conf_tx(struct ieee80211_hw *hw, u16 queue,
 		    const struct ieee80211_tx_queue_params *params);
 int iwl_mac_tx_last_beacon(struct ieee80211_hw *hw);
@@ -625,6 +520,8 @@
 void iwl_dump_nic_error_log(struct iwl_priv *priv);
 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,
 			     struct iwl_rxon_context *ctx);
@@ -662,6 +559,8 @@
 #define STATUS_SCAN_HW		15
 #define STATUS_POWER_PMI	16
 #define STATUS_FW_ERROR		17
+#define STATUS_DEVICE_ENABLED	18
+#define STATUS_CHANNEL_SWITCH_PENDING 19
 
 
 static inline int iwl_is_ready(struct iwl_priv *priv)
@@ -714,11 +613,6 @@
 int iwl_apm_init(struct iwl_priv *priv);
 
 int iwl_send_rxon_timing(struct iwl_priv *priv, struct iwl_rxon_context *ctx);
-static inline int iwl_send_rxon_assoc(struct iwl_priv *priv,
-				      struct iwl_rxon_context *ctx)
-{
-	return priv->cfg->ops->hcmd->rxon_assoc(priv, ctx);
-}
 static inline int iwlcore_commit_rxon(struct iwl_priv *priv,
 				      struct iwl_rxon_context *ctx)
 {
@@ -736,12 +630,10 @@
 	       priv->cfg->bt_params->advanced_bt_coexist;
 }
 
-static inline bool iwl_bt_statistics(struct iwl_priv *priv)
-{
-	return priv->cfg->bt_params && priv->cfg->bt_params->bt_statistics;
-}
-
 extern bool bt_coex_active;
 extern bool bt_siso_mode;
 
+
+void iwlagn_fw_error(struct iwl_priv *priv, bool ondemand);
+
 #endif /* __iwl_core_h__ */
diff -druN linux-2.6.39-libre/drivers/net/wireless/iwlwifi/iwl-csr.h linux-3.0-rc7-libre/drivers/net/wireless/iwlwifi/iwl-csr.h
--- linux-2.6.39-libre/drivers/net/wireless/iwlwifi/iwl-csr.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/iwlwifi/iwl-csr.h	2011-07-11 19:51:52.000000000 -0400
@@ -5,7 +5,7 @@
  *
  * GPL LICENSE SUMMARY
  *
- * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2011 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 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -155,18 +155,10 @@
 #define CSR_DBG_LINK_PWR_MGMT_REG	(CSR_BASE+0x250)
 
 /* Bits for CSR_HW_IF_CONFIG_REG */
-#define CSR49_HW_IF_CONFIG_REG_BIT_4965_R	(0x00000010)
 #define CSR_HW_IF_CONFIG_REG_MSK_BOARD_VER	(0x00000C00)
 #define CSR_HW_IF_CONFIG_REG_BIT_MAC_SI 	(0x00000100)
 #define CSR_HW_IF_CONFIG_REG_BIT_RADIO_SI	(0x00000200)
 
-#define CSR39_HW_IF_CONFIG_REG_BIT_3945_MB         (0x00000100)
-#define CSR39_HW_IF_CONFIG_REG_BIT_3945_MM         (0x00000200)
-#define CSR39_HW_IF_CONFIG_REG_BIT_SKU_MRC            (0x00000400)
-#define CSR39_HW_IF_CONFIG_REG_BIT_BOARD_TYPE         (0x00000800)
-#define CSR39_HW_IF_CONFIG_REG_BITS_SILICON_TYPE_A    (0x00000000)
-#define CSR39_HW_IF_CONFIG_REG_BITS_SILICON_TYPE_B    (0x00001000)
-
 #define CSR_HW_IF_CONFIG_REG_BIT_HAP_WAKE_L1A	(0x00080000)
 #define CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM	(0x00200000)
 #define CSR_HW_IF_CONFIG_REG_BIT_NIC_READY	(0x00400000) /* PCI_OWN_SEM */
@@ -186,7 +178,7 @@
 #define CSR_INT_BIT_SW_ERR       (1 << 25) /* uCode error */
 #define CSR_INT_BIT_RF_KILL      (1 << 7)  /* HW RFKILL switch GP_CNTRL[27] toggled */
 #define CSR_INT_BIT_CT_KILL      (1 << 6)  /* Critical temp (chip too hot) rfkill */
-#define CSR_INT_BIT_SW_RX        (1 << 3)  /* Rx, command responses, 3945 */
+#define CSR_INT_BIT_SW_RX        (1 << 3)  /* Rx, command responses */
 #define CSR_INT_BIT_WAKEUP       (1 << 1)  /* NIC controller waking up (pwr mgmt) */
 #define CSR_INT_BIT_ALIVE        (1 << 0)  /* uCode interrupts once it initializes */
 
@@ -202,29 +194,17 @@
 /* interrupt flags in FH (flow handler) (PCI busmaster DMA) */
 #define CSR_FH_INT_BIT_ERR       (1 << 31) /* Error */
 #define CSR_FH_INT_BIT_HI_PRIOR  (1 << 30) /* High priority Rx, bypass coalescing */
-#define CSR39_FH_INT_BIT_RX_CHNL2  (1 << 18) /* Rx channel 2 (3945 only) */
 #define CSR_FH_INT_BIT_RX_CHNL1  (1 << 17) /* Rx channel 1 */
 #define CSR_FH_INT_BIT_RX_CHNL0  (1 << 16) /* Rx channel 0 */
-#define CSR39_FH_INT_BIT_TX_CHNL6  (1 << 6)  /* Tx channel 6 (3945 only) */
 #define CSR_FH_INT_BIT_TX_CHNL1  (1 << 1)  /* Tx channel 1 */
 #define CSR_FH_INT_BIT_TX_CHNL0  (1 << 0)  /* Tx channel 0 */
 
-#define CSR39_FH_INT_RX_MASK	(CSR_FH_INT_BIT_HI_PRIOR | \
-				 CSR39_FH_INT_BIT_RX_CHNL2 | \
-				 CSR_FH_INT_BIT_RX_CHNL1 | \
-				 CSR_FH_INT_BIT_RX_CHNL0)
-
-
-#define CSR39_FH_INT_TX_MASK	(CSR39_FH_INT_BIT_TX_CHNL6 | \
-				 CSR_FH_INT_BIT_TX_CHNL1 | \
-				 CSR_FH_INT_BIT_TX_CHNL0)
-
-#define CSR49_FH_INT_RX_MASK	(CSR_FH_INT_BIT_HI_PRIOR | \
-				 CSR_FH_INT_BIT_RX_CHNL1 | \
-				 CSR_FH_INT_BIT_RX_CHNL0)
+#define CSR_FH_INT_RX_MASK	(CSR_FH_INT_BIT_HI_PRIOR | \
+				CSR_FH_INT_BIT_RX_CHNL1 | \
+				CSR_FH_INT_BIT_RX_CHNL0)
 
-#define CSR49_FH_INT_TX_MASK	(CSR_FH_INT_BIT_TX_CHNL1 | \
-				 CSR_FH_INT_BIT_TX_CHNL0)
+#define CSR_FH_INT_TX_MASK	(CSR_FH_INT_BIT_TX_CHNL1 | \
+				CSR_FH_INT_BIT_TX_CHNL0)
 
 /* GPIO */
 #define CSR_GPIO_IN_BIT_AUX_POWER                   (0x00000200)
@@ -268,7 +248,7 @@
  *         Indicates MAC (ucode processor, etc.) is powered up and can run.
  *         Internal resources are accessible.
  *         NOTE:  This does not indicate that the processor is actually running.
- *         NOTE:  This does not indicate that 4965 or 3945 has completed
+ *         NOTE:  This does not indicate that device has completed
  *                init or post-power-down restore of internal SRAM memory.
  *                Use CSR_UCODE_DRV_GP1_BIT_MAC_SLEEP as indication that
  *                SRAM is restored and uCode is in normal operation mode.
@@ -291,8 +271,6 @@
 
 /* HW REV */
 #define CSR_HW_REV_TYPE_MSK            (0x00001F0)
-#define CSR_HW_REV_TYPE_3945           (0x00000D0)
-#define CSR_HW_REV_TYPE_4965           (0x0000000)
 #define CSR_HW_REV_TYPE_5300           (0x0000020)
 #define CSR_HW_REV_TYPE_5350           (0x0000030)
 #define CSR_HW_REV_TYPE_5100           (0x0000050)
@@ -363,7 +341,7 @@
  *     0:  MAC_SLEEP
  *         uCode sets this when preparing a power-saving power-down.
  *         uCode resets this when power-up is complete and SRAM is sane.
- *         NOTE:  3945/4965 saves internal SRAM data to host when powering down,
+ *         NOTE:  device saves internal SRAM data to host when powering down,
  *                and must restore this data after powering back up.
  *                MAC_SLEEP is the best indication that restore is complete.
  *                Later devices (5xxx/6xxx/1xxx) use non-volatile SRAM, and
@@ -394,7 +372,6 @@
 #define CSR_LED_REG_TRUN_OFF (0x38)
 
 /* ANA_PLL */
-#define CSR39_ANA_PLL_CFG_VAL        (0x01000000)
 #define CSR50_ANA_PLL_CFG_VAL        (0x00880300)
 
 /* HPET MEM debug */
diff -druN linux-2.6.39-libre/drivers/net/wireless/iwlwifi/iwl-debugfs.c linux-3.0-rc7-libre/drivers/net/wireless/iwlwifi/iwl-debugfs.c
--- linux-2.6.39-libre/drivers/net/wireless/iwlwifi/iwl-debugfs.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/iwlwifi/iwl-debugfs.c	2011-07-11 19:51:52.000000000 -0400
@@ -2,7 +2,7 @@
  *
  * GPL LICENSE SUMMARY
  *
- * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2008 - 2011 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
@@ -39,6 +39,7 @@
 #include "iwl-debug.h"
 #include "iwl-core.h"
 #include "iwl-io.h"
+#include "iwl-agn.h"
 
 /* create and remove of files */
 #define DEBUGFS_ADD_FILE(name, parent, mode) do {			\
@@ -226,10 +227,10 @@
 	/* default is to dump the entire data segment */
 	if (!priv->dbgfs_sram_offset && !priv->dbgfs_sram_len) {
 		priv->dbgfs_sram_offset = 0x800000;
-		if (priv->ucode_type == UCODE_INIT)
-			priv->dbgfs_sram_len = priv->ucode_init_data.len;
+		if (priv->ucode_type == UCODE_SUBTYPE_INIT)
+			priv->dbgfs_sram_len = priv->ucode_init.data.len;
 		else
-			priv->dbgfs_sram_len = priv->ucode_data.len;
+			priv->dbgfs_sram_len = priv->ucode_rt.data.len;
 	}
 	len = priv->dbgfs_sram_len;
 
@@ -437,8 +438,7 @@
 	int pos = 0;
 	ssize_t ret = -ENOMEM;
 
-	ret = pos = priv->cfg->ops->lib->dump_nic_event_log(
-					priv, true, &buf, true);
+	ret = pos = iwl_dump_nic_event_log(priv, true, &buf, true);
 	if (buf) {
 		ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
 		kfree(buf);
@@ -462,8 +462,7 @@
 	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,
-							NULL, false);
+		iwl_dump_nic_event_log(priv, true, NULL, false);
 
 	return count;
 }
@@ -1039,13 +1038,463 @@
 	return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
 }
 
+static const char *fmt_value = "  %-30s %10u\n";
+static const char *fmt_hex   = "  %-30s       0x%02X\n";
+static const char *fmt_table = "  %-30s %10u  %10u  %10u  %10u\n";
+static const char *fmt_header =
+	"%-32s    current  cumulative       delta         max\n";
+
+static int iwl_statistics_flag(struct iwl_priv *priv, char *buf, int bufsz)
+{
+	int p = 0;
+	u32 flag;
+
+	flag = le32_to_cpu(priv->statistics.flag);
+
+	p += scnprintf(buf + p, bufsz - p, "Statistics Flag(0x%X):\n", flag);
+	if (flag & UCODE_STATISTICS_CLEAR_MSK)
+		p += scnprintf(buf + p, bufsz - p,
+		"\tStatistics have been cleared\n");
+	p += scnprintf(buf + p, bufsz - p, "\tOperational Frequency: %s\n",
+		(flag & UCODE_STATISTICS_FREQUENCY_MSK)
+		? "2.4 GHz" : "5.2 GHz");
+	p += scnprintf(buf + p, bufsz - p, "\tTGj Narrow Band: %s\n",
+		(flag & UCODE_STATISTICS_NARROW_BAND_MSK)
+		 ? "enabled" : "disabled");
+
+	return p;
+}
+
 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 = file->private_data;
-	return priv->cfg->ops->lib->debugfs_ops.rx_stats_read(file,
-			user_buf, count, ppos);
+	int pos = 0;
+	char *buf;
+	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, *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_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;
+
+	buf = kzalloc(bufsz, GFP_KERNEL);
+	if (!buf) {
+		IWL_ERR(priv, "Can not allocate Buffer\n");
+		return -ENOMEM;
+	}
+
+	/*
+	 * the statistic information display here is based on
+	 * the last statistics notification from uCode
+	 * might not reflect the current uCode activity
+	 */
+	ofdm = &priv->statistics.rx_ofdm;
+	cck = &priv->statistics.rx_cck;
+	general = &priv->statistics.rx_non_phy;
+	ht = &priv->statistics.rx_ofdm_ht;
+	accum_ofdm = &priv->accum_stats.rx_ofdm;
+	accum_cck = &priv->accum_stats.rx_cck;
+	accum_general = &priv->accum_stats.rx_non_phy;
+	accum_ht = &priv->accum_stats.rx_ofdm_ht;
+	delta_ofdm = &priv->delta_stats.rx_ofdm;
+	delta_cck = &priv->delta_stats.rx_cck;
+	delta_general = &priv->delta_stats.rx_non_phy;
+	delta_ht = &priv->delta_stats.rx_ofdm_ht;
+	max_ofdm = &priv->max_delta_stats.rx_ofdm;
+	max_cck = &priv->max_delta_stats.rx_cck;
+	max_general = &priv->max_delta_stats.rx_non_phy;
+	max_ht = &priv->max_delta_stats.rx_ofdm_ht;
+
+	pos += iwl_statistics_flag(priv, buf, bufsz);
+	pos += scnprintf(buf + pos, bufsz - pos,
+			 fmt_header, "Statistics_Rx - OFDM:");
+	pos += scnprintf(buf + pos, bufsz - pos,
+			 fmt_table, "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,
+			 fmt_table, "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,
+			 fmt_table, "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,
+			 fmt_table, "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,
+			 fmt_table, "overrun_err:",
+			 le32_to_cpu(ofdm->overrun_err),
+			 accum_ofdm->overrun_err, delta_ofdm->overrun_err,
+			 max_ofdm->overrun_err);
+	pos += scnprintf(buf + pos, bufsz - pos,
+			 fmt_table, "early_overrun_err:",
+			 le32_to_cpu(ofdm->early_overrun_err),
+			 accum_ofdm->early_overrun_err,
+			 delta_ofdm->early_overrun_err,
+			 max_ofdm->early_overrun_err);
+	pos += scnprintf(buf + pos, bufsz - pos,
+			 fmt_table, "crc32_good:",
+			 le32_to_cpu(ofdm->crc32_good),
+			 accum_ofdm->crc32_good, delta_ofdm->crc32_good,
+			 max_ofdm->crc32_good);
+	pos += scnprintf(buf + pos, bufsz - pos,
+			 fmt_table, "false_alarm_cnt:",
+			 le32_to_cpu(ofdm->false_alarm_cnt),
+			 accum_ofdm->false_alarm_cnt,
+			 delta_ofdm->false_alarm_cnt,
+			 max_ofdm->false_alarm_cnt);
+	pos += scnprintf(buf + pos, bufsz - pos,
+			 fmt_table, "fina_sync_err_cnt:",
+			 le32_to_cpu(ofdm->fina_sync_err_cnt),
+			 accum_ofdm->fina_sync_err_cnt,
+			 delta_ofdm->fina_sync_err_cnt,
+			 max_ofdm->fina_sync_err_cnt);
+	pos += scnprintf(buf + pos, bufsz - pos,
+			 fmt_table, "sfd_timeout:",
+			 le32_to_cpu(ofdm->sfd_timeout),
+			 accum_ofdm->sfd_timeout, delta_ofdm->sfd_timeout,
+			 max_ofdm->sfd_timeout);
+	pos += scnprintf(buf + pos, bufsz - pos,
+			 fmt_table, "fina_timeout:",
+			 le32_to_cpu(ofdm->fina_timeout),
+			 accum_ofdm->fina_timeout, delta_ofdm->fina_timeout,
+			 max_ofdm->fina_timeout);
+	pos += scnprintf(buf + pos, bufsz - pos,
+			 fmt_table, "unresponded_rts:",
+			 le32_to_cpu(ofdm->unresponded_rts),
+			 accum_ofdm->unresponded_rts,
+			 delta_ofdm->unresponded_rts,
+			 max_ofdm->unresponded_rts);
+	pos += scnprintf(buf + pos, bufsz - pos,
+			 fmt_table, "rxe_frame_lmt_ovrun:",
+			 le32_to_cpu(ofdm->rxe_frame_limit_overrun),
+			 accum_ofdm->rxe_frame_limit_overrun,
+			 delta_ofdm->rxe_frame_limit_overrun,
+			 max_ofdm->rxe_frame_limit_overrun);
+	pos += scnprintf(buf + pos, bufsz - pos,
+			 fmt_table, "sent_ack_cnt:",
+			 le32_to_cpu(ofdm->sent_ack_cnt),
+			 accum_ofdm->sent_ack_cnt, delta_ofdm->sent_ack_cnt,
+			 max_ofdm->sent_ack_cnt);
+	pos += scnprintf(buf + pos, bufsz - pos,
+			 fmt_table, "sent_cts_cnt:",
+			 le32_to_cpu(ofdm->sent_cts_cnt),
+			 accum_ofdm->sent_cts_cnt, delta_ofdm->sent_cts_cnt,
+			 max_ofdm->sent_cts_cnt);
+	pos += scnprintf(buf + pos, bufsz - pos,
+			 fmt_table, "sent_ba_rsp_cnt:",
+			 le32_to_cpu(ofdm->sent_ba_rsp_cnt),
+			 accum_ofdm->sent_ba_rsp_cnt,
+			 delta_ofdm->sent_ba_rsp_cnt,
+			 max_ofdm->sent_ba_rsp_cnt);
+	pos += scnprintf(buf + pos, bufsz - pos,
+			 fmt_table, "dsp_self_kill:",
+			 le32_to_cpu(ofdm->dsp_self_kill),
+			 accum_ofdm->dsp_self_kill,
+			 delta_ofdm->dsp_self_kill,
+			 max_ofdm->dsp_self_kill);
+	pos += scnprintf(buf + pos, bufsz - pos,
+			 fmt_table, "mh_format_err:",
+			 le32_to_cpu(ofdm->mh_format_err),
+			 accum_ofdm->mh_format_err,
+			 delta_ofdm->mh_format_err,
+			 max_ofdm->mh_format_err);
+	pos += scnprintf(buf + pos, bufsz - pos,
+			 fmt_table, "re_acq_main_rssi_sum:",
+			 le32_to_cpu(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,
+			 fmt_header, "Statistics_Rx - CCK:");
+	pos += scnprintf(buf + pos, bufsz - pos,
+			 fmt_table, "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,
+			 fmt_table, "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,
+			 fmt_table, "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,
+			 fmt_table, "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,
+			 fmt_table, "overrun_err:",
+			 le32_to_cpu(cck->overrun_err),
+			 accum_cck->overrun_err, delta_cck->overrun_err,
+			 max_cck->overrun_err);
+	pos += scnprintf(buf + pos, bufsz - pos,
+			 fmt_table, "early_overrun_err:",
+			 le32_to_cpu(cck->early_overrun_err),
+			 accum_cck->early_overrun_err,
+			 delta_cck->early_overrun_err,
+			 max_cck->early_overrun_err);
+	pos += scnprintf(buf + pos, bufsz - pos,
+			 fmt_table, "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,
+			 fmt_table, "false_alarm_cnt:",
+			 le32_to_cpu(cck->false_alarm_cnt),
+			 accum_cck->false_alarm_cnt,
+			 delta_cck->false_alarm_cnt, max_cck->false_alarm_cnt);
+	pos += scnprintf(buf + pos, bufsz - pos,
+			 fmt_table, "fina_sync_err_cnt:",
+			 le32_to_cpu(cck->fina_sync_err_cnt),
+			 accum_cck->fina_sync_err_cnt,
+			 delta_cck->fina_sync_err_cnt,
+			 max_cck->fina_sync_err_cnt);
+	pos += scnprintf(buf + pos, bufsz - pos,
+			 fmt_table, "sfd_timeout:",
+			 le32_to_cpu(cck->sfd_timeout),
+			 accum_cck->sfd_timeout, delta_cck->sfd_timeout,
+			 max_cck->sfd_timeout);
+	pos += scnprintf(buf + pos, bufsz - pos,
+			 fmt_table, "fina_timeout:",
+			 le32_to_cpu(cck->fina_timeout),
+			 accum_cck->fina_timeout, delta_cck->fina_timeout,
+			 max_cck->fina_timeout);
+	pos += scnprintf(buf + pos, bufsz - pos,
+			 fmt_table, "unresponded_rts:",
+			 le32_to_cpu(cck->unresponded_rts),
+			 accum_cck->unresponded_rts, delta_cck->unresponded_rts,
+			 max_cck->unresponded_rts);
+	pos += scnprintf(buf + pos, bufsz - pos,
+			 fmt_table, "rxe_frame_lmt_ovrun:",
+			 le32_to_cpu(cck->rxe_frame_limit_overrun),
+			 accum_cck->rxe_frame_limit_overrun,
+			 delta_cck->rxe_frame_limit_overrun,
+			 max_cck->rxe_frame_limit_overrun);
+	pos += scnprintf(buf + pos, bufsz - pos,
+			 fmt_table, "sent_ack_cnt:",
+			 le32_to_cpu(cck->sent_ack_cnt),
+			 accum_cck->sent_ack_cnt, delta_cck->sent_ack_cnt,
+			 max_cck->sent_ack_cnt);
+	pos += scnprintf(buf + pos, bufsz - pos,
+			 fmt_table, "sent_cts_cnt:",
+			 le32_to_cpu(cck->sent_cts_cnt),
+			 accum_cck->sent_cts_cnt, delta_cck->sent_cts_cnt,
+			 max_cck->sent_cts_cnt);
+	pos += scnprintf(buf + pos, bufsz - pos,
+			 fmt_table, "sent_ba_rsp_cnt:",
+			 le32_to_cpu(cck->sent_ba_rsp_cnt),
+			 accum_cck->sent_ba_rsp_cnt,
+			 delta_cck->sent_ba_rsp_cnt,
+			 max_cck->sent_ba_rsp_cnt);
+	pos += scnprintf(buf + pos, bufsz - pos,
+			 fmt_table, "dsp_self_kill:",
+			 le32_to_cpu(cck->dsp_self_kill),
+			 accum_cck->dsp_self_kill, delta_cck->dsp_self_kill,
+			 max_cck->dsp_self_kill);
+	pos += scnprintf(buf + pos, bufsz - pos,
+			 fmt_table, "mh_format_err:",
+			 le32_to_cpu(cck->mh_format_err),
+			 accum_cck->mh_format_err, delta_cck->mh_format_err,
+			 max_cck->mh_format_err);
+	pos += scnprintf(buf + pos, bufsz - pos,
+			 fmt_table, "re_acq_main_rssi_sum:",
+			 le32_to_cpu(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,
+			 fmt_header, "Statistics_Rx - GENERAL:");
+	pos += scnprintf(buf + pos, bufsz - pos,
+			 fmt_table, "bogus_cts:",
+			 le32_to_cpu(general->bogus_cts),
+			 accum_general->bogus_cts, delta_general->bogus_cts,
+			 max_general->bogus_cts);
+	pos += scnprintf(buf + pos, bufsz - pos,
+			 fmt_table, "bogus_ack:",
+			 le32_to_cpu(general->bogus_ack),
+			 accum_general->bogus_ack, delta_general->bogus_ack,
+			 max_general->bogus_ack);
+	pos += scnprintf(buf + pos, bufsz - pos,
+			 fmt_table, "non_bssid_frames:",
+			 le32_to_cpu(general->non_bssid_frames),
+			 accum_general->non_bssid_frames,
+			 delta_general->non_bssid_frames,
+			 max_general->non_bssid_frames);
+	pos += scnprintf(buf + pos, bufsz - pos,
+			 fmt_table, "filtered_frames:",
+			 le32_to_cpu(general->filtered_frames),
+			 accum_general->filtered_frames,
+			 delta_general->filtered_frames,
+			 max_general->filtered_frames);
+	pos += scnprintf(buf + pos, bufsz - pos,
+			 fmt_table, "non_channel_beacons:",
+			 le32_to_cpu(general->non_channel_beacons),
+			 accum_general->non_channel_beacons,
+			 delta_general->non_channel_beacons,
+			 max_general->non_channel_beacons);
+	pos += scnprintf(buf + pos, bufsz - pos,
+			 fmt_table, "channel_beacons:",
+			 le32_to_cpu(general->channel_beacons),
+			 accum_general->channel_beacons,
+			 delta_general->channel_beacons,
+			 max_general->channel_beacons);
+	pos += scnprintf(buf + pos, bufsz - pos,
+			 fmt_table, "num_missed_bcon:",
+			 le32_to_cpu(general->num_missed_bcon),
+			 accum_general->num_missed_bcon,
+			 delta_general->num_missed_bcon,
+			 max_general->num_missed_bcon);
+	pos += scnprintf(buf + pos, bufsz - pos,
+			 fmt_table, "adc_rx_saturation_time:",
+			 le32_to_cpu(general->adc_rx_saturation_time),
+			 accum_general->adc_rx_saturation_time,
+			 delta_general->adc_rx_saturation_time,
+			 max_general->adc_rx_saturation_time);
+	pos += scnprintf(buf + pos, bufsz - pos,
+			 fmt_table, "ina_detect_search_tm:",
+			 le32_to_cpu(general->ina_detection_search_time),
+			 accum_general->ina_detection_search_time,
+			 delta_general->ina_detection_search_time,
+			 max_general->ina_detection_search_time);
+	pos += scnprintf(buf + pos, bufsz - pos,
+			 fmt_table, "beacon_silence_rssi_a:",
+			 le32_to_cpu(general->beacon_silence_rssi_a),
+			 accum_general->beacon_silence_rssi_a,
+			 delta_general->beacon_silence_rssi_a,
+			 max_general->beacon_silence_rssi_a);
+	pos += scnprintf(buf + pos, bufsz - pos,
+			 fmt_table, "beacon_silence_rssi_b:",
+			 le32_to_cpu(general->beacon_silence_rssi_b),
+			 accum_general->beacon_silence_rssi_b,
+			 delta_general->beacon_silence_rssi_b,
+			 max_general->beacon_silence_rssi_b);
+	pos += scnprintf(buf + pos, bufsz - pos,
+			 fmt_table, "beacon_silence_rssi_c:",
+			 le32_to_cpu(general->beacon_silence_rssi_c),
+			 accum_general->beacon_silence_rssi_c,
+			 delta_general->beacon_silence_rssi_c,
+			 max_general->beacon_silence_rssi_c);
+	pos += scnprintf(buf + pos, bufsz - pos,
+			 fmt_table, "interference_data_flag:",
+			 le32_to_cpu(general->interference_data_flag),
+			 accum_general->interference_data_flag,
+			 delta_general->interference_data_flag,
+			 max_general->interference_data_flag);
+	pos += scnprintf(buf + pos, bufsz - pos,
+			 fmt_table, "channel_load:",
+			 le32_to_cpu(general->channel_load),
+			 accum_general->channel_load,
+			 delta_general->channel_load,
+			 max_general->channel_load);
+	pos += scnprintf(buf + pos, bufsz - pos,
+			 fmt_table, "dsp_false_alarms:",
+			 le32_to_cpu(general->dsp_false_alarms),
+			 accum_general->dsp_false_alarms,
+			 delta_general->dsp_false_alarms,
+			 max_general->dsp_false_alarms);
+	pos += scnprintf(buf + pos, bufsz - pos,
+			 fmt_table, "beacon_rssi_a:",
+			 le32_to_cpu(general->beacon_rssi_a),
+			 accum_general->beacon_rssi_a,
+			 delta_general->beacon_rssi_a,
+			 max_general->beacon_rssi_a);
+	pos += scnprintf(buf + pos, bufsz - pos,
+			 fmt_table, "beacon_rssi_b:",
+			 le32_to_cpu(general->beacon_rssi_b),
+			 accum_general->beacon_rssi_b,
+			 delta_general->beacon_rssi_b,
+			 max_general->beacon_rssi_b);
+	pos += scnprintf(buf + pos, bufsz - pos,
+			 fmt_table, "beacon_rssi_c:",
+			 le32_to_cpu(general->beacon_rssi_c),
+			 accum_general->beacon_rssi_c,
+			 delta_general->beacon_rssi_c,
+			 max_general->beacon_rssi_c);
+	pos += scnprintf(buf + pos, bufsz - pos,
+			 fmt_table, "beacon_energy_a:",
+			 le32_to_cpu(general->beacon_energy_a),
+			 accum_general->beacon_energy_a,
+			 delta_general->beacon_energy_a,
+			 max_general->beacon_energy_a);
+	pos += scnprintf(buf + pos, bufsz - pos,
+			 fmt_table, "beacon_energy_b:",
+			 le32_to_cpu(general->beacon_energy_b),
+			 accum_general->beacon_energy_b,
+			 delta_general->beacon_energy_b,
+			 max_general->beacon_energy_b);
+	pos += scnprintf(buf + pos, bufsz - pos,
+			 fmt_table, "beacon_energy_c:",
+			 le32_to_cpu(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,
+			 fmt_header, "Statistics_Rx - OFDM_HT:");
+	pos += scnprintf(buf + pos, bufsz - pos,
+			 fmt_table, "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,
+			 fmt_table, "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,
+			 fmt_table, "early_overrun_err:",
+			 le32_to_cpu(ht->early_overrun_err),
+			 accum_ht->early_overrun_err,
+			 delta_ht->early_overrun_err,
+			 max_ht->early_overrun_err);
+	pos += scnprintf(buf + pos, bufsz - pos,
+			 fmt_table, "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,
+			 fmt_table, "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,
+			 fmt_table, "mh_format_err:",
+			 le32_to_cpu(ht->mh_format_err),
+			 accum_ht->mh_format_err,
+			 delta_ht->mh_format_err, max_ht->mh_format_err);
+	pos += scnprintf(buf + pos, bufsz - pos,
+			 fmt_table, "agg_crc32_good:",
+			 le32_to_cpu(ht->agg_crc32_good),
+			 accum_ht->agg_crc32_good,
+			 delta_ht->agg_crc32_good, max_ht->agg_crc32_good);
+	pos += scnprintf(buf + pos, bufsz - pos,
+			 fmt_table, "agg_mpdu_cnt:",
+			 le32_to_cpu(ht->agg_mpdu_cnt),
+			 accum_ht->agg_mpdu_cnt,
+			 delta_ht->agg_mpdu_cnt, max_ht->agg_mpdu_cnt);
+	pos += scnprintf(buf + pos, bufsz - pos,
+			 fmt_table, "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,
+			 fmt_table, "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);
+	return ret;
 }
 
 static ssize_t iwl_dbgfs_ucode_tx_stats_read(struct file *file,
@@ -1053,8 +1502,190 @@
 					size_t count, loff_t *ppos)
 {
 	struct iwl_priv *priv = file->private_data;
-	return priv->cfg->ops->lib->debugfs_ops.tx_stats_read(file,
-			user_buf, count, ppos);
+	int pos = 0;
+	char *buf;
+	int bufsz = (sizeof(struct statistics_tx) * 48) + 250;
+	ssize_t ret;
+	struct statistics_tx *tx, *accum_tx, *delta_tx, *max_tx;
+
+	if (!iwl_is_alive(priv))
+		return -EAGAIN;
+
+	buf = kzalloc(bufsz, GFP_KERNEL);
+	if (!buf) {
+		IWL_ERR(priv, "Can not allocate Buffer\n");
+		return -ENOMEM;
+	}
+
+	/* the statistic information display here is based on
+	 * the last statistics notification from uCode
+	 * might not reflect the current uCode activity
+	 */
+	tx = &priv->statistics.tx;
+	accum_tx = &priv->accum_stats.tx;
+	delta_tx = &priv->delta_stats.tx;
+	max_tx = &priv->max_delta_stats.tx;
+
+	pos += iwl_statistics_flag(priv, buf, bufsz);
+	pos += scnprintf(buf + pos, bufsz - pos,
+			 fmt_header, "Statistics_Tx:");
+	pos += scnprintf(buf + pos, bufsz - pos,
+			 fmt_table, "preamble:",
+			 le32_to_cpu(tx->preamble_cnt),
+			 accum_tx->preamble_cnt,
+			 delta_tx->preamble_cnt, max_tx->preamble_cnt);
+	pos += scnprintf(buf + pos, bufsz - pos,
+			 fmt_table, "rx_detected_cnt:",
+			 le32_to_cpu(tx->rx_detected_cnt),
+			 accum_tx->rx_detected_cnt,
+			 delta_tx->rx_detected_cnt, max_tx->rx_detected_cnt);
+	pos += scnprintf(buf + pos, bufsz - pos,
+			 fmt_table, "bt_prio_defer_cnt:",
+			 le32_to_cpu(tx->bt_prio_defer_cnt),
+			 accum_tx->bt_prio_defer_cnt,
+			 delta_tx->bt_prio_defer_cnt,
+			 max_tx->bt_prio_defer_cnt);
+	pos += scnprintf(buf + pos, bufsz - pos,
+			 fmt_table, "bt_prio_kill_cnt:",
+			 le32_to_cpu(tx->bt_prio_kill_cnt),
+			 accum_tx->bt_prio_kill_cnt,
+			 delta_tx->bt_prio_kill_cnt,
+			 max_tx->bt_prio_kill_cnt);
+	pos += scnprintf(buf + pos, bufsz - pos,
+			 fmt_table, "few_bytes_cnt:",
+			 le32_to_cpu(tx->few_bytes_cnt),
+			 accum_tx->few_bytes_cnt,
+			 delta_tx->few_bytes_cnt, max_tx->few_bytes_cnt);
+	pos += scnprintf(buf + pos, bufsz - pos,
+			 fmt_table, "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,
+			 fmt_table, "ack_timeout:",
+			 le32_to_cpu(tx->ack_timeout),
+			 accum_tx->ack_timeout,
+			 delta_tx->ack_timeout, max_tx->ack_timeout);
+	pos += scnprintf(buf + pos, bufsz - pos,
+			 fmt_table, "expected_ack_cnt:",
+			 le32_to_cpu(tx->expected_ack_cnt),
+			 accum_tx->expected_ack_cnt,
+			 delta_tx->expected_ack_cnt,
+			 max_tx->expected_ack_cnt);
+	pos += scnprintf(buf + pos, bufsz - pos,
+			 fmt_table, "actual_ack_cnt:",
+			 le32_to_cpu(tx->actual_ack_cnt),
+			 accum_tx->actual_ack_cnt,
+			 delta_tx->actual_ack_cnt,
+			 max_tx->actual_ack_cnt);
+	pos += scnprintf(buf + pos, bufsz - pos,
+			 fmt_table, "dump_msdu_cnt:",
+			 le32_to_cpu(tx->dump_msdu_cnt),
+			 accum_tx->dump_msdu_cnt,
+			 delta_tx->dump_msdu_cnt,
+			 max_tx->dump_msdu_cnt);
+	pos += scnprintf(buf + pos, bufsz - pos,
+			 fmt_table, "abort_nxt_frame_mismatch:",
+			 le32_to_cpu(tx->burst_abort_next_frame_mismatch_cnt),
+			 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,
+			 fmt_table, "abort_missing_nxt_frame:",
+			 le32_to_cpu(tx->burst_abort_missing_next_frame_cnt),
+			 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,
+			 fmt_table, "cts_timeout_collision:",
+			 le32_to_cpu(tx->cts_timeout_collision),
+			 accum_tx->cts_timeout_collision,
+			 delta_tx->cts_timeout_collision,
+			 max_tx->cts_timeout_collision);
+	pos += scnprintf(buf + pos, bufsz - pos,
+			 fmt_table, "ack_ba_timeout_collision:",
+			 le32_to_cpu(tx->ack_or_ba_timeout_collision),
+			 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,
+			 fmt_table, "agg ba_timeout:",
+			 le32_to_cpu(tx->agg.ba_timeout),
+			 accum_tx->agg.ba_timeout,
+			 delta_tx->agg.ba_timeout,
+			 max_tx->agg.ba_timeout);
+	pos += scnprintf(buf + pos, bufsz - pos,
+			 fmt_table, "agg ba_resched_frames:",
+			 le32_to_cpu(tx->agg.ba_reschedule_frames),
+			 accum_tx->agg.ba_reschedule_frames,
+			 delta_tx->agg.ba_reschedule_frames,
+			 max_tx->agg.ba_reschedule_frames);
+	pos += scnprintf(buf + pos, bufsz - pos,
+			 fmt_table, "agg scd_query_agg_frame:",
+			 le32_to_cpu(tx->agg.scd_query_agg_frame_cnt),
+			 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,
+			 fmt_table, "agg scd_query_no_agg:",
+			 le32_to_cpu(tx->agg.scd_query_no_agg),
+			 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,
+			 fmt_table, "agg scd_query_agg:",
+			 le32_to_cpu(tx->agg.scd_query_agg),
+			 accum_tx->agg.scd_query_agg,
+			 delta_tx->agg.scd_query_agg,
+			 max_tx->agg.scd_query_agg);
+	pos += scnprintf(buf + pos, bufsz - pos,
+			 fmt_table, "agg scd_query_mismatch:",
+			 le32_to_cpu(tx->agg.scd_query_mismatch),
+			 accum_tx->agg.scd_query_mismatch,
+			 delta_tx->agg.scd_query_mismatch,
+			 max_tx->agg.scd_query_mismatch);
+	pos += scnprintf(buf + pos, bufsz - pos,
+			 fmt_table, "agg frame_not_ready:",
+			 le32_to_cpu(tx->agg.frame_not_ready),
+			 accum_tx->agg.frame_not_ready,
+			 delta_tx->agg.frame_not_ready,
+			 max_tx->agg.frame_not_ready);
+	pos += scnprintf(buf + pos, bufsz - pos,
+			 fmt_table, "agg underrun:",
+			 le32_to_cpu(tx->agg.underrun),
+			 accum_tx->agg.underrun,
+			 delta_tx->agg.underrun, max_tx->agg.underrun);
+	pos += scnprintf(buf + pos, bufsz - pos,
+			 fmt_table, "agg bt_prio_kill:",
+			 le32_to_cpu(tx->agg.bt_prio_kill),
+			 accum_tx->agg.bt_prio_kill,
+			 delta_tx->agg.bt_prio_kill,
+			 max_tx->agg.bt_prio_kill);
+	pos += scnprintf(buf + pos, bufsz - pos,
+			 fmt_table, "agg rx_ba_rsp_cnt:",
+			 le32_to_cpu(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);
+
+	if (tx->tx_power.ant_a || tx->tx_power.ant_b || tx->tx_power.ant_c) {
+		pos += scnprintf(buf + pos, bufsz - pos,
+			"tx power: (1/2 dB step)\n");
+		if ((priv->cfg->valid_tx_ant & ANT_A) && tx->tx_power.ant_a)
+			pos += scnprintf(buf + pos, bufsz - pos,
+					fmt_hex, "antenna A:",
+					tx->tx_power.ant_a);
+		if ((priv->cfg->valid_tx_ant & ANT_B) && tx->tx_power.ant_b)
+			pos += scnprintf(buf + pos, bufsz - pos,
+					fmt_hex, "antenna B:",
+					tx->tx_power.ant_b);
+		if ((priv->cfg->valid_tx_ant & ANT_C) && tx->tx_power.ant_c)
+			pos += scnprintf(buf + pos, bufsz - pos,
+					fmt_hex, "antenna C:",
+					tx->tx_power.ant_c);
+	}
+	ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
+	kfree(buf);
+	return ret;
 }
 
 static ssize_t iwl_dbgfs_ucode_general_stats_read(struct file *file,
@@ -1062,8 +1693,347 @@
 					size_t count, loff_t *ppos)
 {
 	struct iwl_priv *priv = file->private_data;
-	return priv->cfg->ops->lib->debugfs_ops.general_stats_read(file,
-			user_buf, count, ppos);
+	int pos = 0;
+	char *buf;
+	int bufsz = sizeof(struct statistics_general) * 10 + 300;
+	ssize_t ret;
+	struct statistics_general_common *general, *accum_general;
+	struct statistics_general_common *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;
+
+	buf = kzalloc(bufsz, GFP_KERNEL);
+	if (!buf) {
+		IWL_ERR(priv, "Can not allocate Buffer\n");
+		return -ENOMEM;
+	}
+
+	/* the statistic information display here is based on
+	 * the last statistics notification from uCode
+	 * might not reflect the current uCode activity
+	 */
+	general = &priv->statistics.common;
+	dbg = &priv->statistics.common.dbg;
+	div = &priv->statistics.common.div;
+	accum_general = &priv->accum_stats.common;
+	accum_dbg = &priv->accum_stats.common.dbg;
+	accum_div = &priv->accum_stats.common.div;
+	delta_general = &priv->delta_stats.common;
+	max_general = &priv->max_delta_stats.common;
+	delta_dbg = &priv->delta_stats.common.dbg;
+	max_dbg = &priv->max_delta_stats.common.dbg;
+	delta_div = &priv->delta_stats.common.div;
+	max_div = &priv->max_delta_stats.common.div;
+
+	pos += iwl_statistics_flag(priv, buf, bufsz);
+	pos += scnprintf(buf + pos, bufsz - pos,
+			 fmt_header, "Statistics_General:");
+	pos += scnprintf(buf + pos, bufsz - pos,
+			 fmt_value, "temperature:",
+			 le32_to_cpu(general->temperature));
+	pos += scnprintf(buf + pos, bufsz - pos,
+			 fmt_value, "temperature_m:",
+			 le32_to_cpu(general->temperature_m));
+	pos += scnprintf(buf + pos, bufsz - pos,
+			 fmt_value, "ttl_timestamp:",
+			 le32_to_cpu(general->ttl_timestamp));
+	pos += scnprintf(buf + pos, bufsz - pos,
+			 fmt_table, "burst_check:",
+			 le32_to_cpu(dbg->burst_check),
+			 accum_dbg->burst_check,
+			 delta_dbg->burst_check, max_dbg->burst_check);
+	pos += scnprintf(buf + pos, bufsz - pos,
+			 fmt_table, "burst_count:",
+			 le32_to_cpu(dbg->burst_count),
+			 accum_dbg->burst_count,
+			 delta_dbg->burst_count, max_dbg->burst_count);
+	pos += scnprintf(buf + pos, bufsz - pos,
+			 fmt_table, "wait_for_silence_timeout_count:",
+			 le32_to_cpu(dbg->wait_for_silence_timeout_cnt),
+			 accum_dbg->wait_for_silence_timeout_cnt,
+			 delta_dbg->wait_for_silence_timeout_cnt,
+			 max_dbg->wait_for_silence_timeout_cnt);
+	pos += scnprintf(buf + pos, bufsz - pos,
+			 fmt_table, "sleep_time:",
+			 le32_to_cpu(general->sleep_time),
+			 accum_general->sleep_time,
+			 delta_general->sleep_time, max_general->sleep_time);
+	pos += scnprintf(buf + pos, bufsz - pos,
+			 fmt_table, "slots_out:",
+			 le32_to_cpu(general->slots_out),
+			 accum_general->slots_out,
+			 delta_general->slots_out, max_general->slots_out);
+	pos += scnprintf(buf + pos, bufsz - pos,
+			 fmt_table, "slots_idle:",
+			 le32_to_cpu(general->slots_idle),
+			 accum_general->slots_idle,
+			 delta_general->slots_idle, max_general->slots_idle);
+	pos += scnprintf(buf + pos, bufsz - pos,
+			 fmt_table, "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,
+			 fmt_table, "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,
+			 fmt_table, "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,
+			 fmt_table, "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,
+			 fmt_table, "rx_enable_counter:",
+			 le32_to_cpu(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,
+			 fmt_table, "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;
+}
+
+static ssize_t iwl_dbgfs_ucode_bt_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;
+	int pos = 0;
+	char *buf;
+	int bufsz = (sizeof(struct statistics_bt_activity) * 24) + 200;
+	ssize_t ret;
+	struct statistics_bt_activity *bt, *accum_bt;
+
+	if (!iwl_is_alive(priv))
+		return -EAGAIN;
+
+	if (!priv->bt_enable_flag)
+		return -EINVAL;
+
+	/* 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");
+		return -ENOMEM;
+	}
+
+	/*
+	 * the statistic information display here is based on
+	 * the last statistics notification from uCode
+	 * might not reflect the current uCode activity
+	 */
+	bt = &priv->statistics.bt_activity;
+	accum_bt = &priv->accum_stats.bt_activity;
+
+	pos += iwl_statistics_flag(priv, buf, bufsz);
+	pos += scnprintf(buf + pos, bufsz - pos, "Statistics_BT:\n");
+	pos += scnprintf(buf + pos, bufsz - pos,
+			"\t\t\tcurrent\t\t\taccumulative\n");
+	pos += scnprintf(buf + pos, bufsz - pos,
+			 "hi_priority_tx_req_cnt:\t\t%u\t\t\t%u\n",
+			 le32_to_cpu(bt->hi_priority_tx_req_cnt),
+			 accum_bt->hi_priority_tx_req_cnt);
+	pos += scnprintf(buf + pos, bufsz - pos,
+			 "hi_priority_tx_denied_cnt:\t%u\t\t\t%u\n",
+			 le32_to_cpu(bt->hi_priority_tx_denied_cnt),
+			 accum_bt->hi_priority_tx_denied_cnt);
+	pos += scnprintf(buf + pos, bufsz - pos,
+			 "lo_priority_tx_req_cnt:\t\t%u\t\t\t%u\n",
+			 le32_to_cpu(bt->lo_priority_tx_req_cnt),
+			 accum_bt->lo_priority_tx_req_cnt);
+	pos += scnprintf(buf + pos, bufsz - pos,
+			 "lo_priority_tx_denied_cnt:\t%u\t\t\t%u\n",
+			 le32_to_cpu(bt->lo_priority_tx_denied_cnt),
+			 accum_bt->lo_priority_tx_denied_cnt);
+	pos += scnprintf(buf + pos, bufsz - pos,
+			 "hi_priority_rx_req_cnt:\t\t%u\t\t\t%u\n",
+			 le32_to_cpu(bt->hi_priority_rx_req_cnt),
+			 accum_bt->hi_priority_rx_req_cnt);
+	pos += scnprintf(buf + pos, bufsz - pos,
+			 "hi_priority_rx_denied_cnt:\t%u\t\t\t%u\n",
+			 le32_to_cpu(bt->hi_priority_rx_denied_cnt),
+			 accum_bt->hi_priority_rx_denied_cnt);
+	pos += scnprintf(buf + pos, bufsz - pos,
+			 "lo_priority_rx_req_cnt:\t\t%u\t\t\t%u\n",
+			 le32_to_cpu(bt->lo_priority_rx_req_cnt),
+			 accum_bt->lo_priority_rx_req_cnt);
+	pos += scnprintf(buf + pos, bufsz - pos,
+			 "lo_priority_rx_denied_cnt:\t%u\t\t\t%u\n",
+			 le32_to_cpu(bt->lo_priority_rx_denied_cnt),
+			 accum_bt->lo_priority_rx_denied_cnt);
+
+	pos += scnprintf(buf + pos, bufsz - pos,
+			 "(rx)num_bt_kills:\t\t%u\t\t\t%u\n",
+			 le32_to_cpu(priv->statistics.num_bt_kills),
+			 priv->statistics.accum_num_bt_kills);
+
+	ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
+	kfree(buf);
+	return ret;
+}
+
+static ssize_t iwl_dbgfs_reply_tx_error_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;
+	int bufsz = (sizeof(struct reply_tx_error_statistics) * 24) +
+		(sizeof(struct reply_agg_tx_error_statistics) * 24) + 200;
+	ssize_t ret;
+
+	if (!iwl_is_alive(priv))
+		return -EAGAIN;
+
+	buf = kzalloc(bufsz, GFP_KERNEL);
+	if (!buf) {
+		IWL_ERR(priv, "Can not allocate Buffer\n");
+		return -ENOMEM;
+	}
+
+	pos += scnprintf(buf + pos, bufsz - pos, "Statistics_TX_Error:\n");
+	pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t\t%u\n",
+			 iwl_get_tx_fail_reason(TX_STATUS_POSTPONE_DELAY),
+			 priv->_agn.reply_tx_stats.pp_delay);
+	pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
+			 iwl_get_tx_fail_reason(TX_STATUS_POSTPONE_FEW_BYTES),
+			 priv->_agn.reply_tx_stats.pp_few_bytes);
+	pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
+			 iwl_get_tx_fail_reason(TX_STATUS_POSTPONE_BT_PRIO),
+			 priv->_agn.reply_tx_stats.pp_bt_prio);
+	pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
+			 iwl_get_tx_fail_reason(TX_STATUS_POSTPONE_QUIET_PERIOD),
+			 priv->_agn.reply_tx_stats.pp_quiet_period);
+	pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
+			 iwl_get_tx_fail_reason(TX_STATUS_POSTPONE_CALC_TTAK),
+			 priv->_agn.reply_tx_stats.pp_calc_ttak);
+	pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t%u\n",
+			 iwl_get_tx_fail_reason(
+				TX_STATUS_FAIL_INTERNAL_CROSSED_RETRY),
+			 priv->_agn.reply_tx_stats.int_crossed_retry);
+	pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
+			 iwl_get_tx_fail_reason(TX_STATUS_FAIL_SHORT_LIMIT),
+			 priv->_agn.reply_tx_stats.short_limit);
+	pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
+			 iwl_get_tx_fail_reason(TX_STATUS_FAIL_LONG_LIMIT),
+			 priv->_agn.reply_tx_stats.long_limit);
+	pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
+			 iwl_get_tx_fail_reason(TX_STATUS_FAIL_FIFO_UNDERRUN),
+			 priv->_agn.reply_tx_stats.fifo_underrun);
+	pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
+			 iwl_get_tx_fail_reason(TX_STATUS_FAIL_DRAIN_FLOW),
+			 priv->_agn.reply_tx_stats.drain_flow);
+	pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
+			 iwl_get_tx_fail_reason(TX_STATUS_FAIL_RFKILL_FLUSH),
+			 priv->_agn.reply_tx_stats.rfkill_flush);
+	pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
+			 iwl_get_tx_fail_reason(TX_STATUS_FAIL_LIFE_EXPIRE),
+			 priv->_agn.reply_tx_stats.life_expire);
+	pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
+			 iwl_get_tx_fail_reason(TX_STATUS_FAIL_DEST_PS),
+			 priv->_agn.reply_tx_stats.dest_ps);
+	pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
+			 iwl_get_tx_fail_reason(TX_STATUS_FAIL_HOST_ABORTED),
+			 priv->_agn.reply_tx_stats.host_abort);
+	pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
+			 iwl_get_tx_fail_reason(TX_STATUS_FAIL_BT_RETRY),
+			 priv->_agn.reply_tx_stats.pp_delay);
+	pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
+			 iwl_get_tx_fail_reason(TX_STATUS_FAIL_STA_INVALID),
+			 priv->_agn.reply_tx_stats.sta_invalid);
+	pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
+			 iwl_get_tx_fail_reason(TX_STATUS_FAIL_FRAG_DROPPED),
+			 priv->_agn.reply_tx_stats.frag_drop);
+	pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
+			 iwl_get_tx_fail_reason(TX_STATUS_FAIL_TID_DISABLE),
+			 priv->_agn.reply_tx_stats.tid_disable);
+	pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
+			 iwl_get_tx_fail_reason(TX_STATUS_FAIL_FIFO_FLUSHED),
+			 priv->_agn.reply_tx_stats.fifo_flush);
+	pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t%u\n",
+			 iwl_get_tx_fail_reason(
+				TX_STATUS_FAIL_INSUFFICIENT_CF_POLL),
+			 priv->_agn.reply_tx_stats.insuff_cf_poll);
+	pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
+			 iwl_get_tx_fail_reason(TX_STATUS_FAIL_PASSIVE_NO_RX),
+			 priv->_agn.reply_tx_stats.fail_hw_drop);
+	pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t%u\n",
+			 iwl_get_tx_fail_reason(
+				TX_STATUS_FAIL_NO_BEACON_ON_RADAR),
+			 priv->_agn.reply_tx_stats.sta_color_mismatch);
+	pos += scnprintf(buf + pos, bufsz - pos, "UNKNOWN:\t\t\t%u\n",
+			 priv->_agn.reply_tx_stats.unknown);
+
+	pos += scnprintf(buf + pos, bufsz - pos,
+			 "\nStatistics_Agg_TX_Error:\n");
+
+	pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
+			 iwl_get_agg_tx_fail_reason(AGG_TX_STATE_UNDERRUN_MSK),
+			 priv->_agn.reply_agg_tx_stats.underrun);
+	pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
+			 iwl_get_agg_tx_fail_reason(AGG_TX_STATE_BT_PRIO_MSK),
+			 priv->_agn.reply_agg_tx_stats.bt_prio);
+	pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
+			 iwl_get_agg_tx_fail_reason(AGG_TX_STATE_FEW_BYTES_MSK),
+			 priv->_agn.reply_agg_tx_stats.few_bytes);
+	pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
+			 iwl_get_agg_tx_fail_reason(AGG_TX_STATE_ABORT_MSK),
+			 priv->_agn.reply_agg_tx_stats.abort);
+	pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t%u\n",
+			 iwl_get_agg_tx_fail_reason(
+				AGG_TX_STATE_LAST_SENT_TTL_MSK),
+			 priv->_agn.reply_agg_tx_stats.last_sent_ttl);
+	pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t%u\n",
+			 iwl_get_agg_tx_fail_reason(
+				AGG_TX_STATE_LAST_SENT_TRY_CNT_MSK),
+			 priv->_agn.reply_agg_tx_stats.last_sent_try);
+	pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t%u\n",
+			 iwl_get_agg_tx_fail_reason(
+				AGG_TX_STATE_LAST_SENT_BT_KILL_MSK),
+			 priv->_agn.reply_agg_tx_stats.last_sent_bt_kill);
+	pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
+			 iwl_get_agg_tx_fail_reason(AGG_TX_STATE_SCD_QUERY_MSK),
+			 priv->_agn.reply_agg_tx_stats.scd_query);
+	pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t%u\n",
+			 iwl_get_agg_tx_fail_reason(
+				AGG_TX_STATE_TEST_BAD_CRC32_MSK),
+			 priv->_agn.reply_agg_tx_stats.bad_crc32);
+	pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
+			 iwl_get_agg_tx_fail_reason(AGG_TX_STATE_RESPONSE_MSK),
+			 priv->_agn.reply_agg_tx_stats.response);
+	pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
+			 iwl_get_agg_tx_fail_reason(AGG_TX_STATE_DUMP_TX_MSK),
+			 priv->_agn.reply_agg_tx_stats.dump_tx);
+	pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n",
+			 iwl_get_agg_tx_fail_reason(AGG_TX_STATE_DELAY_TX_MSK),
+			 priv->_agn.reply_agg_tx_stats.delay_tx);
+	pos += scnprintf(buf + pos, bufsz - pos, "UNKNOWN:\t\t\t%u\n",
+			 priv->_agn.reply_agg_tx_stats.unknown);
+
+	ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
+	kfree(buf);
+	return ret;
 }
 
 static ssize_t iwl_dbgfs_sensitivity_read(struct file *file,
@@ -1268,8 +2238,7 @@
 	if (sscanf(buf, "%d", &csr) != 1)
 		return -EFAULT;
 
-	if (priv->cfg->ops->lib->dump_csr)
-		priv->cfg->ops->lib->dump_csr(priv);
+	iwl_dump_csr(priv);
 
 	return count;
 }
@@ -1359,13 +2328,11 @@
 	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);
-		}
+	ret = pos = iwl_dump_fh(priv, &buf, true);
+	if (buf) {
+		ret = simple_read_from_buffer(user_buf,
+					      count, ppos, buf, pos);
+		kfree(buf);
 	}
 
 	return ret;
@@ -1531,16 +2498,6 @@
 	return count;
 }
 
-static ssize_t iwl_dbgfs_ucode_bt_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;
-
-	return priv->cfg->ops->lib->debugfs_ops.bt_stats_read(file,
-			user_buf, count, ppos);
-}
-
 static ssize_t iwl_dbgfs_wd_timeout_write(struct file *file,
 					const char __user *user_buf,
 					size_t count, loff_t *ppos) {
@@ -1572,12 +2529,10 @@
 	int pos = 0;
 	char buf[200];
 	const size_t bufsz = sizeof(buf);
-	ssize_t ret;
 
 	if (!priv->bt_enable_flag) {
 		pos += scnprintf(buf + pos, bufsz - pos, "BT coex disabled\n");
-		ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
-		return ret;
+		return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
 	}
 	pos += scnprintf(buf + pos, bufsz - pos, "BT enable flag: 0x%x\n",
 		priv->bt_enable_flag);
@@ -1608,8 +2563,7 @@
 		break;
 	}
 
-	ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
-	return ret;
+	return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
 }
 
 static ssize_t iwl_dbgfs_protection_mode_read(struct file *file,
@@ -1658,18 +2612,6 @@
 	return count;
 }
 
-static ssize_t iwl_dbgfs_reply_tx_error_read(struct file *file,
-					char __user *user_buf,
-					size_t count, loff_t *ppos)
-{
-	struct iwl_priv *priv = file->private_data;
-
-	if (priv->cfg->ops->lib->debugfs_ops.reply_tx_error)
-		return priv->cfg->ops->lib->debugfs_ops.reply_tx_error(
-			file, user_buf, count, ppos);
-	else
-		return -ENODATA;
-}
 DEBUGFS_READ_FILE_OPS(rx_statistics);
 DEBUGFS_READ_FILE_OPS(tx_statistics);
 DEBUGFS_READ_WRITE_FILE_OPS(traffic_log);
@@ -1731,11 +2673,8 @@
 	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);
-	if (!priv->cfg->base_params->broken_powersave) {
-		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(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);
@@ -1758,29 +2697,20 @@
 		DEBUGFS_ADD_FILE(txfifo_flush, dir_debug, S_IWUSR);
 	DEBUGFS_ADD_FILE(protection_mode, dir_debug, S_IWUSR | S_IRUSR);
 
-	if (priv->cfg->base_params->sensitivity_calib_by_driver)
-		DEBUGFS_ADD_FILE(sensitivity, dir_debug, S_IRUSR);
-	if (priv->cfg->base_params->chain_noise_calib_by_driver)
-		DEBUGFS_ADD_FILE(chain_noise, dir_debug, S_IRUSR);
-	if (priv->cfg->base_params->ucode_tracing)
-		DEBUGFS_ADD_FILE(ucode_tracing, dir_debug, S_IWUSR | S_IRUSR);
-	if (iwl_bt_statistics(priv))
-		DEBUGFS_ADD_FILE(ucode_bt_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_FILE(ucode_bt_stats, dir_debug, S_IRUSR);
 	DEBUGFS_ADD_FILE(reply_tx_error, dir_debug, S_IRUSR);
 	DEBUGFS_ADD_FILE(rxon_flags, dir_debug, S_IWUSR);
 	DEBUGFS_ADD_FILE(rxon_filter_flags, dir_debug, S_IWUSR);
 	DEBUGFS_ADD_FILE(wd_timeout, dir_debug, S_IWUSR);
 	if (iwl_advanced_bt_coexist(priv))
 		DEBUGFS_ADD_FILE(bt_traffic, dir_debug, S_IRUSR);
-	if (priv->cfg->base_params->sensitivity_calib_by_driver)
-		DEBUGFS_ADD_BOOL(disable_sensitivity, dir_rf,
-				 &priv->disable_sens_cal);
-	if (priv->cfg->base_params->chain_noise_calib_by_driver)
-		DEBUGFS_ADD_BOOL(disable_chain_noise, dir_rf,
-				 &priv->disable_chain_noise_cal);
-	if (priv->cfg->base_params->tx_power_by_driver)
-		DEBUGFS_ADD_BOOL(disable_tx_power, dir_rf,
-				&priv->disable_tx_power_cal);
+	DEBUGFS_ADD_BOOL(disable_sensitivity, dir_rf,
+			 &priv->disable_sens_cal);
+	DEBUGFS_ADD_BOOL(disable_chain_noise, dir_rf,
+			 &priv->disable_chain_noise_cal);
 	return 0;
 
 err:
diff -druN linux-2.6.39-libre/drivers/net/wireless/iwlwifi/iwl-debug.h linux-3.0-rc7-libre/drivers/net/wireless/iwlwifi/iwl-debug.h
--- linux-2.6.39-libre/drivers/net/wireless/iwlwifi/iwl-debug.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/iwlwifi/iwl-debug.h	2011-07-11 19:51:52.000000000 -0400
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2003 - 2011 Intel Corporation. All rights reserved.
  *
  * Portions of this file are derived from the ipw3945 project.
  *
@@ -146,7 +146,6 @@
 #define IWL_DL_RX		(1 << 24)
 #define IWL_DL_ISR		(1 << 25)
 #define IWL_DL_HT		(1 << 26)
-#define IWL_DL_IO		(1 << 27)
 /* 0xF0000000 - 0x10000000 */
 #define IWL_DL_11H		(1 << 28)
 #define IWL_DL_STATS		(1 << 29)
@@ -174,7 +173,6 @@
 		IWL_DEBUG_LIMIT(p, IWL_DL_DROP, f, ## a)
 #define IWL_DEBUG_AP(p, f, a...)	IWL_DEBUG(p, IWL_DL_AP, f, ## a)
 #define IWL_DEBUG_TXPOWER(p, f, a...)	IWL_DEBUG(p, IWL_DL_TXPOWER, f, ## a)
-#define IWL_DEBUG_IO(p, f, a...)	IWL_DEBUG(p, IWL_DL_IO, f, ## a)
 #define IWL_DEBUG_RATE(p, f, a...)	IWL_DEBUG(p, IWL_DL_RATE, f, ## a)
 #define IWL_DEBUG_RATE_LIMIT(p, f, a...)	\
 		IWL_DEBUG_LIMIT(p, IWL_DL_RATE, f, ## a)
diff -druN linux-2.6.39-libre/drivers/net/wireless/iwlwifi/iwl-dev.h linux-3.0-rc7-libre/drivers/net/wireless/iwlwifi/iwl-dev.h
--- linux-2.6.39-libre/drivers/net/wireless/iwlwifi/iwl-dev.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/iwlwifi/iwl-dev.h	2011-07-11 19:51:52.000000000 -0400
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2003 - 2011 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,7 +26,6 @@
 /*
  * Please use this file (iwl-dev.h) for driver implementation definitions.
  * Please use iwl-commands.h for uCode API definitions.
- * Please use iwl-4965-hw.h for hardware-related definitions.
  */
 
 #ifndef __iwl_dev_h__
@@ -49,8 +48,6 @@
 #include "iwl-agn-rs.h"
 #include "iwl-agn-tt.h"
 
-#define U32_PAD(n)		((4-(n))&0x3)
-
 struct iwl_tx_queue;
 
 /* CT-KILL constants */
@@ -84,7 +81,7 @@
 #define MAX_RTS_THRESHOLD         2347U
 #define MAX_MSDU_SIZE		  2304U
 #define MAX_MPDU_SIZE		  2346U
-#define DEFAULT_BEACON_INTERVAL   100U
+#define DEFAULT_BEACON_INTERVAL   200U
 #define	DEFAULT_SHORT_RETRY_LIMIT 7U
 #define	DEFAULT_LONG_RETRY_LIMIT  4U
 
@@ -113,8 +110,6 @@
 			 struct iwl_device_cmd *cmd,
 			 struct iwl_rx_packet *pkt);
 
-	/* The CMD_SIZE_HUGE flag bit indicates that the command
-	 * structure is stored at the end of the shared queue memory. */
 	u32 flags;
 
 	DEFINE_DMA_UNMAP_ADDR(mapping);
@@ -124,7 +119,23 @@
 /*
  * Generic queue structure
  *
- * Contains common data for Rx and Tx queues
+ * Contains common data for Rx and Tx queues.
+ *
+ * Note the difference between n_bd and n_window: the hardware
+ * always assumes 256 descriptors, so n_bd is always 256 (unless
+ * there might be HW changes in the future). For the normal TX
+ * queues, n_window, which is the size of the software queue data
+ * is also 256; however, for the command queue, n_window is only
+ * 32 since we don't need so many commands pending. Since the HW
+ * still uses 256 BDs for DMA though, n_bd stays 256. As a result,
+ * the software buffers (in the variables @meta, @txb in struct
+ * iwl_tx_queue) only have 32 entries, while the HW buffers (@tfds
+ * in the same struct) have 256.
+ * This means that we end up with the following:
+ *  HW entries: | 0 | ... | N * 32 | ... | N * 32 + 31 | ... | 255 |
+ *  SW entries:           | 0      | ... | 31          |
+ * where N is a number between 0 and 7. This means that the SW
+ * data is a window overlayed over the HW queue.
  */
 struct iwl_queue {
 	int n_bd;              /* number of BDs in this queue */
@@ -166,7 +177,7 @@
 
 struct iwl_tx_queue {
 	struct iwl_queue q;
-	void *tfds;
+	struct iwl_tfd *tfds;
 	struct iwl_device_cmd **cmd;
 	struct iwl_cmd_meta *meta;
 	struct iwl_tx_info *txb;
@@ -179,53 +190,12 @@
 
 #define IWL_NUM_SCAN_RATES         (2)
 
-struct iwl4965_channel_tgd_info {
-	u8 type;
-	s8 max_power;
-};
-
-struct iwl4965_channel_tgh_info {
-	s64 last_radar_time;
-};
-
-#define IWL4965_MAX_RATE (33)
-
-struct iwl3945_clip_group {
-	/* maximum power level to prevent clipping for each rate, derived by
-	 *   us from this band's saturation power in EEPROM */
-	const s8 clip_powers[IWL_MAX_RATES];
-};
-
-/* current Tx power values to use, one for each rate for each channel.
- * requested power is limited by:
- * -- regulatory EEPROM limits for this channel
- * -- hardware capabilities (clip-powers)
- * -- spectrum management
- * -- user preference (e.g. iwconfig)
- * when requested power is set, base power index must also be set. */
-struct iwl3945_channel_power_info {
-	struct iwl3945_tx_power tpc;	/* actual radio and DSP gain settings */
-	s8 power_table_index;	/* actual (compenst'd) index into gain table */
-	s8 base_power_index;	/* gain index for power at factory temp. */
-	s8 requested_power;	/* power (dBm) requested for this chnl/rate */
-};
-
-/* current scan Tx power values to use, one for each scan rate for each
- * channel. */
-struct iwl3945_scan_power_info {
-	struct iwl3945_tx_power tpc;	/* actual radio and DSP gain settings */
-	s8 power_table_index;	/* actual (compenst'd) index into gain table */
-	s8 requested_power;	/* scan pwr (dBm) requested for chnl/rate */
-};
-
 /*
  * One for each channel, holds all channel setup data
  * Some of the fields (e.g. eeprom and flags/max_power_avg) are redundant
  *     with one another!
  */
 struct iwl_channel_info {
-	struct iwl4965_channel_tgd_info tgd;
-	struct iwl4965_channel_tgh_info tgh;
 	struct iwl_eeprom_channel eeprom;	/* EEPROM regulatory limit */
 	struct iwl_eeprom_channel ht40_eeprom;	/* EEPROM regulatory limit for
 						 * HT40 channel */
@@ -245,14 +215,6 @@
 	s8 ht40_max_power_avg;	/* (dBm) regul. eeprom, normal Tx, any rate */
 	u8 ht40_flags;		/* flags copied from EEPROM */
 	u8 ht40_extension_channel; /* HT_IE_EXT_CHANNEL_* */
-
-	/* Radio/DSP gain settings for each "normal" data Tx rate.
-	 * These include, in addition to RF and DSP gain, a few fields for
-	 *   remembering/modifying gain settings (indexes). */
-	struct iwl3945_channel_power_info power_info[IWL4965_MAX_RATE];
-
-	/* Radio/DSP gain settings for each scan rate, for directed scans. */
-	struct iwl3945_scan_power_info scan_pwr_info[IWL_NUM_SCAN_RATES];
 };
 
 #define IWL_TX_FIFO_BK		0	/* shared */
@@ -288,15 +250,6 @@
 #define IEEE80211_HLEN                  (IEEE80211_4ADDR_LEN)
 #define IEEE80211_FRAME_LEN             (IEEE80211_DATA_LEN + IEEE80211_HLEN)
 
-struct iwl_frame {
-	union {
-		struct ieee80211_hdr frame;
-		struct iwl_tx_beacon_cmd beacon;
-		u8 raw[IEEE80211_FRAME_LEN];
-		u8 cmd[360];
-	} u;
-	struct list_head list;
-};
 
 #define SEQ_TO_SN(seq) (((seq) & IEEE80211_SCTL_SEQ) >> 4)
 #define SN_TO_SEQ(ssn) (((ssn) << 4) & IEEE80211_SCTL_SEQ)
@@ -306,9 +259,9 @@
 	CMD_SYNC = 0,
 	CMD_SIZE_NORMAL = 0,
 	CMD_NO_SKB = 0,
-	CMD_SIZE_HUGE = (1 << 0),
 	CMD_ASYNC = (1 << 1),
 	CMD_WANT_SKB = (1 << 2),
+	CMD_MAPPED = (1 << 3),
 };
 
 #define DEF_CMD_PAYLOAD_SIZE 320
@@ -317,8 +270,8 @@
  * struct iwl_device_cmd
  *
  * For allocation of the command and tx queues, this establishes the overall
- * size of the largest command we send to uCode, except for a scan command
- * (which is relatively huge; space is allocated separately).
+ * size of the largest command we send to uCode, except for commands that
+ * aren't fully copied and use other TFD space.
  */
 struct iwl_device_cmd {
 	struct iwl_cmd_header hdr;	/* uCode API */
@@ -335,15 +288,21 @@
 
 #define TFD_MAX_PAYLOAD_SIZE (sizeof(struct iwl_device_cmd))
 
+#define IWL_MAX_CMD_TFDS	2
+
+enum iwl_hcmd_dataflag {
+	IWL_HCMD_DFL_NOCOPY	= BIT(0),
+};
 
 struct iwl_host_cmd {
-	const void *data;
+	const void *data[IWL_MAX_CMD_TFDS];
 	unsigned long reply_page;
 	void (*callback)(struct iwl_priv *priv,
 			 struct iwl_device_cmd *cmd,
 			 struct iwl_rx_packet *pkt);
 	u32 flags;
-	u16 len;
+	u16 len[IWL_MAX_CMD_TFDS];
+	u8 dataflags[IWL_MAX_CMD_TFDS];
 	u8 id;
 };
 
@@ -416,6 +375,7 @@
 #define IWL_EMPTYING_HW_QUEUE_ADDBA 2
 #define IWL_EMPTYING_HW_QUEUE_DELBA 3
 	u8 state;
+	u8 tx_fifo;
 };
 
 
@@ -499,9 +459,6 @@
  * When mac80211 creates a station it reserves some space (hw->sta_data_size)
  * in the structure for use by driver. This structure is places in that
  * space.
- *
- * The common struct MUST be first because it is shared between
- * 3945 and agn!
  */
 struct iwl_station_priv {
 	struct iwl_station_priv_common common;
@@ -530,6 +487,10 @@
 	u32 len;		/* bytes */
 };
 
+struct fw_img {
+	struct fw_desc code, data;
+};
+
 /* v1/v2 uCode file layout */
 struct iwl_ucode_header {
 	__le32 ver;	/* major/minor/API/serial */
@@ -586,6 +547,22 @@
 	IWL_UCODE_TLV_INIT_ERRLOG_PTR	= 13,
 	IWL_UCODE_TLV_ENHANCE_SENS_TBL	= 14,
 	IWL_UCODE_TLV_PHY_CALIBRATION_SIZE = 15,
+	/* 16 and 17 reserved for future use */
+	IWL_UCODE_TLV_FLAGS		= 18,
+};
+
+/**
+ * enum iwl_ucode_tlv_flag - ucode API flags
+ * @IWL_UCODE_TLV_FLAGS_PAN: This is PAN capable microcode; this previously
+ *	was a separate TLV but moved here to save space.
+ * @IWL_UCODE_TLV_FLAGS_NEWSCAN: new uCode scan behaviour on hidden SSID,
+ *	treats good CRC threshold as a boolean
+ * @IWL_UCODE_TLV_FLAGS_MFP: This uCode image supports MFP (802.11w).
+ */
+enum iwl_ucode_tlv_flag {
+	IWL_UCODE_TLV_FLAGS_PAN		= BIT(0),
+	IWL_UCODE_TLV_FLAGS_NEWSCAN	= BIT(1),
+	IWL_UCODE_TLV_FLAGS_MFP		= BIT(2),
 };
 
 struct iwl_ucode_tlv {
@@ -619,14 +596,6 @@
 	u8 data[0];
 };
 
-struct iwl4965_ibss_seq {
-	u8 mac[ETH_ALEN];
-	u16 seq_num;
-	u16 frag_num;
-	unsigned long packet_time;
-	struct list_head list;
-};
-
 struct iwl_sensitivity_ranges {
 	u16 min_nrg_cck;
 	u16 max_nrg_cck;
@@ -700,7 +669,6 @@
 	u8  max_beacon_itrvl;	/* in 1024 ms */
 	u32 max_inst_size;
 	u32 max_data_size;
-	u32 max_bsm_size;
 	u32 ct_kill_threshold; /* value in hw-dependent units */
 	u32 ct_kill_exit_threshold; /* value in hw-dependent units */
 				    /* for 1000, 6000 series and up */
@@ -722,8 +690,6 @@
  * Naming convention --
  * iwl_         <-- Is part of iwlwifi
  * iwlXXXX_     <-- Hardware specific (implemented in iwl-XXXX.c for XXXX)
- * iwl4965_bg_      <-- Called from work queue context
- * iwl4965_mac_     <-- mac80211 callback
  *
  ****************************************************************************/
 extern void iwl_update_chain_flags(struct iwl_priv *priv);
@@ -739,17 +705,8 @@
 }
 
 
-static inline u8 get_cmd_index(struct iwl_queue *q, u32 index, int is_huge)
+static inline u8 get_cmd_index(struct iwl_queue *q, u32 index)
 {
-	/*
-	 * This is for init calibration result and scan command which
-	 * required buffer > TFD_MAX_PAYLOAD_SIZE,
-	 * the big buffer at end of command array
-	 */
-	if (is_huge)
-		return q->n_window;	/* must be power of 2 */
-
-	/* Otherwise, use normal size buffers */
 	return index & (q->n_window - 1);
 }
 
@@ -772,7 +729,6 @@
 
 /* Sensitivity and chain noise calibration */
 #define INITIALIZATION_VALUE		0xFFFF
-#define IWL4965_CAL_NUM_BEACONS		20
 #define IWL_CAL_NUM_BEACONS		16
 #define MAXIMUM_ALLOWED_PATHLOSS	15
 
@@ -806,24 +762,19 @@
 #define NRG_NUM_PREV_STAT_L     20
 #define NUM_RX_CHAINS           3
 
-enum iwl4965_false_alarm_state {
+enum iwlagn_false_alarm_state {
 	IWL_FA_TOO_MANY = 0,
 	IWL_FA_TOO_FEW = 1,
 	IWL_FA_GOOD_RANGE = 2,
 };
 
-enum iwl4965_chain_noise_state {
+enum iwlagn_chain_noise_state {
 	IWL_CHAIN_NOISE_ALIVE = 0,  /* must be 0 */
 	IWL_CHAIN_NOISE_ACCUMULATE,
 	IWL_CHAIN_NOISE_CALIBRATED,
 	IWL_CHAIN_NOISE_DONE,
 };
 
-enum iwl4965_calib_enabled_state {
-	IWL_CALIB_DISABLED = 0,  /* must be 0 */
-	IWL_CALIB_ENABLED = 1,
-};
-
 
 /*
  * enum iwl_calib
@@ -847,12 +798,6 @@
 	size_t buf_len;
 };
 
-enum ucode_type {
-	UCODE_NONE = 0,
-	UCODE_INIT,
-	UCODE_RT
-};
-
 /* Sensitivity calib data */
 struct iwl_sensitivity_data {
 	u32 auto_corr_ofdm;
@@ -1037,17 +982,6 @@
 };
 
 /*
- * iwl_switch_rxon: "channel switch" structure
- *
- * @ switch_in_progress: channel switch in progress
- * @ channel: new channel
- */
-struct iwl_switch_rxon {
-	bool switch_in_progress;
-	__le16 channel;
-};
-
-/*
  * schedule the timer to wake up every UCODE_TRACE_PERIOD milliseconds
  * to perform continuous uCode event logging operation if enabled
  */
@@ -1131,12 +1065,6 @@
 
 /* extend beacon time format bit shifting  */
 /*
- * for _3945 devices
- * bits 31:24 - extended
- * bits 23:0  - interval
- */
-#define IWL3945_EXT_BEACON_TIME_POS	24
-/*
  * for _agn devices
  * bits 31:22 - extended
  * bits 21:0  - interval
@@ -1164,10 +1092,12 @@
 struct iwl_notification_wait {
 	struct list_head list;
 
-	void (*fn)(struct iwl_priv *priv, struct iwl_rx_packet *pkt);
+	void (*fn)(struct iwl_priv *priv, struct iwl_rx_packet *pkt,
+		   void *data);
+	void *fn_data;
 
 	u8 cmd;
-	bool triggered;
+	bool triggered, aborted;
 };
 
 enum iwl_rxon_context_id {
@@ -1228,6 +1158,8 @@
 		bool enabled, is_40mhz;
 		u8 extension_chan_offset;
 	} ht;
+
+	bool last_tx_rejected;
 };
 
 enum iwl_scan_type {
@@ -1236,6 +1168,14 @@
 	IWL_SCAN_OFFCH_TX,
 };
 
+#ifdef CONFIG_IWLWIFI_DEVICE_SVTOOL
+struct iwl_testmode_trace {
+	u8 *cpu_addr;
+	u8 *trace_addr;
+	dma_addr_t dma_addr;
+	bool trace_enabled;
+};
+#endif
 struct iwl_priv {
 
 	/* ieee device used by generic ieee processing code */
@@ -1244,13 +1184,10 @@
 	struct ieee80211_rate *ieee_rates;
 	struct iwl_cfg *cfg;
 
-	/* temporary frame storage list */
-	struct list_head free_frames;
-	int frames_count;
-
 	enum ieee80211_band band;
-	int alloc_rxb_page;
 
+	void (*pre_rx_handler)(struct iwl_priv *priv,
+			       struct iwl_rx_mem_buffer *rxb);
 	void (*rx_handlers[REPLY_MAX])(struct iwl_priv *priv,
 				       struct iwl_rx_mem_buffer *rxb);
 
@@ -1305,16 +1242,12 @@
 	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;
 
 	/* pci hardware address support */
 	void __iomem *hw_base;
-	u32  hw_rev;
-	u32  hw_wa_rev;
-	u8   rev_id;
 
 	/* microcode/device supports multiple contexts */
 	u8 valid_contexts;
@@ -1325,6 +1258,8 @@
 	/* max number of station keys */
 	u8 sta_key_max_num;
 
+	bool new_scan_threshold_behaviour;
+
 	/* EEPROM MAC addresses */
 	struct mac_address addresses[2];
 
@@ -1332,24 +1267,21 @@
 	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 */
-	struct fw_desc ucode_data;	/* runtime data original */
-	struct fw_desc ucode_data_backup;	/* runtime data save/restore */
-	struct fw_desc ucode_init;	/* initialization inst */
-	struct fw_desc ucode_init_data;	/* initialization data */
-	struct fw_desc ucode_boot;	/* bootstrap inst */
-	enum ucode_type ucode_type;
+	struct fw_img ucode_rt;
+	struct fw_img ucode_init;
+
+	enum iwlagn_ucode_subtype ucode_type;
 	u8 ucode_write_complete;	/* the image write is complete */
 	char firmware_name[25];
 
 	struct iwl_rxon_context contexts[NUM_IWL_RXON_CTX];
 
-	struct iwl_switch_rxon switch_rxon;
+	__le16 switch_channel;
 
-	/* 1st responses from initialize and runtime uCode images.
-	 * _agn's initialize alive response contains some calibration data. */
-	struct iwl_init_alive_resp card_alive_init;
-	struct iwl_alive_resp card_alive;
+	struct {
+		u32 error_event_table;
+		u32 log_event_table;
+	} device_pointers;
 
 	u16 active_rate;
 
@@ -1390,15 +1322,12 @@
 	struct iwl_power_mgr power_data;
 	struct iwl_tt_mgmt thermal_throttle;
 
-	/* context information */
-	u8 bssid[ETH_ALEN]; /* used only on 3945 but filled by core */
-
 	/* station table variables */
 
 	/* Note: if lock and sta_lock are needed, lock must be acquired first */
 	spinlock_t sta_lock;
 	int num_stations;
-	struct iwl_station_entry stations[IWL_STATION_COUNT];
+	struct iwl_station_entry stations[IWLAGN_STATION_COUNT];
 	unsigned long ucode_key_table;
 
 	/* queue refcounts */
@@ -1422,101 +1351,81 @@
 	/* Last Rx'd beacon timestamp */
 	u64 timestamp;
 
-	union {
-#if defined(CONFIG_IWL3945) || defined(CONFIG_IWL3945_MODULE)
-		struct {
-			void *shared_virt;
-			dma_addr_t shared_phys;
-
-			struct delayed_work thermal_periodic;
-			struct delayed_work rfkill_poll;
-
-			struct iwl3945_notif_statistics statistics;
+	struct {
+		__le32 flag;
+		struct statistics_general_common common;
+		struct statistics_rx_non_phy rx_non_phy;
+		struct statistics_rx_phy rx_ofdm;
+		struct statistics_rx_ht_phy rx_ofdm_ht;
+		struct statistics_rx_phy rx_cck;
+		struct statistics_tx tx;
 #ifdef CONFIG_IWLWIFI_DEBUGFS
-			struct iwl3945_notif_statistics accum_statistics;
-			struct iwl3945_notif_statistics delta_statistics;
-			struct iwl3945_notif_statistics max_delta;
+		struct statistics_bt_activity bt_activity;
+		__le32 num_bt_kills, accum_num_bt_kills;
 #endif
-
-			u32 sta_supp_rates;
-			int last_rx_rssi;	/* From Rx packet statistics */
-
-			/* Rx'd packet timing information */
-			u32 last_beacon_time;
-			u64 last_tsf;
-
-			/*
-			 * each calibration channel group in the
-			 * EEPROM has a derived clip setting for
-			 * each rate.
-			 */
-			const struct iwl3945_clip_group clip_groups[5];
-
-		} _3945;
+	} statistics;
+#ifdef CONFIG_IWLWIFI_DEBUGFS
+	struct {
+		struct statistics_general_common common;
+		struct statistics_rx_non_phy rx_non_phy;
+		struct statistics_rx_phy rx_ofdm;
+		struct statistics_rx_ht_phy rx_ofdm_ht;
+		struct statistics_rx_phy rx_cck;
+		struct statistics_tx tx;
+		struct statistics_bt_activity bt_activity;
+	} accum_stats, delta_stats, max_delta_stats;
 #endif
-#if defined(CONFIG_IWLAGN) || defined(CONFIG_IWLAGN_MODULE)
-		struct {
-			/* INT ICT Table */
-			__le32 *ict_tbl;
-			void *ict_tbl_vir;
-			dma_addr_t ict_tbl_dma;
-			dma_addr_t aligned_ict_tbl_dma;
-			int ict_index;
-			u32 inta;
-			bool use_ict;
-			/*
-			 * reporting the number of tids has AGG on. 0 means
-			 * no AGGREGATION
-			 */
-			u8 agg_tids_count;
 
-			struct iwl_rx_phy_res last_phy_res;
-			bool last_phy_res_valid;
+	struct {
+		/* INT ICT Table */
+		__le32 *ict_tbl;
+		void *ict_tbl_vir;
+		dma_addr_t ict_tbl_dma;
+		dma_addr_t aligned_ict_tbl_dma;
+		int ict_index;
+		u32 inta;
+		bool use_ict;
+		/*
+		 * reporting the number of tids has AGG on. 0 means
+		 * no AGGREGATION
+		 */
+		u8 agg_tids_count;
 
-			struct completion firmware_loading_complete;
+		struct iwl_rx_phy_res last_phy_res;
+		bool last_phy_res_valid;
 
-			u32 init_evtlog_ptr, init_evtlog_size, init_errlog_ptr;
-			u32 inst_evtlog_ptr, inst_evtlog_size, inst_errlog_ptr;
+		struct completion firmware_loading_complete;
 
-			/*
-			 * chain noise reset and gain commands are the
-			 * two extra calibration commands follows the standard
-			 * phy calibration commands
-			 */
-			u8 phy_calib_chain_noise_reset_cmd;
-			u8 phy_calib_chain_noise_gain_cmd;
+		u32 init_evtlog_ptr, init_evtlog_size, init_errlog_ptr;
+		u32 inst_evtlog_ptr, inst_evtlog_size, inst_errlog_ptr;
 
-			struct iwl_notif_statistics statistics;
-			struct iwl_bt_notif_statistics statistics_bt;
-			/* counts reply_tx error */
-			struct reply_tx_error_statistics reply_tx_stats;
-			struct reply_agg_tx_error_statistics reply_agg_tx_stats;
-#ifdef CONFIG_IWLWIFI_DEBUGFS
-			struct iwl_notif_statistics accum_statistics;
-			struct iwl_notif_statistics delta_statistics;
-			struct iwl_notif_statistics max_delta;
-			struct iwl_bt_notif_statistics accum_statistics_bt;
-			struct iwl_bt_notif_statistics delta_statistics_bt;
-			struct iwl_bt_notif_statistics max_delta_bt;
-#endif
+		/*
+		 * chain noise reset and gain commands are the
+		 * two extra calibration commands follows the standard
+		 * phy calibration commands
+		 */
+		u8 phy_calib_chain_noise_reset_cmd;
+		u8 phy_calib_chain_noise_gain_cmd;
 
-			/* notification wait support */
-			struct list_head notif_waits;
-			spinlock_t notif_wait_lock;
-			wait_queue_head_t notif_waitq;
+		/* counts reply_tx error */
+		struct reply_tx_error_statistics reply_tx_stats;
+		struct reply_agg_tx_error_statistics reply_agg_tx_stats;
+		/* notification wait support */
+		struct list_head notif_waits;
+		spinlock_t notif_wait_lock;
+		wait_queue_head_t notif_waitq;
 
-			/* remain-on-channel offload support */
-			struct ieee80211_channel *hw_roc_channel;
-			struct delayed_work hw_roc_work;
-			enum nl80211_channel_type hw_roc_chantype;
-			int hw_roc_duration;
+		/* remain-on-channel offload support */
+		struct ieee80211_channel *hw_roc_channel;
+		struct delayed_work hw_roc_work;
+		enum nl80211_channel_type hw_roc_chantype;
+		int hw_roc_duration;
+		bool hw_roc_setup;
 
-			struct sk_buff *offchan_tx_skb;
-			int offchan_tx_timeout;
-			struct ieee80211_channel *offchan_tx_chan;
-		} _agn;
-#endif
-	};
+		struct sk_buff *offchan_tx_skb;
+		int offchan_tx_timeout;
+		struct ieee80211_channel *offchan_tx_chan;
+	} _agn;
 
 	/* bt coex */
 	u8 bt_enable_flag;
@@ -1548,6 +1457,7 @@
 	struct work_struct beacon_update;
 	struct iwl_rxon_context *beacon_ctx;
 	struct sk_buff *beacon_skb;
+	void *beacon_cmd;
 
 	struct work_struct tt_work;
 	struct work_struct ct_enter;
@@ -1559,8 +1469,6 @@
 
 	struct tasklet_struct irq_tasklet;
 
-	struct delayed_work init_alive_start;
-	struct delayed_work alive_start;
 	struct delayed_work scan_check;
 
 	/* TX Power */
@@ -1589,18 +1497,21 @@
 	struct work_struct txpower_work;
 	u32 disable_sens_cal;
 	u32 disable_chain_noise_cal;
-	u32 disable_tx_power_cal;
 	struct work_struct run_time_calib_work;
 	struct timer_list statistics_periodic;
 	struct timer_list ucode_trace;
 	struct timer_list watchdog;
-	bool hw_ready;
 
 	struct iwl_event_log event_log;
 
 	struct led_classdev led;
 	unsigned long blink_on, blink_off;
 	bool led_registered;
+#ifdef CONFIG_IWLWIFI_DEVICE_SVTOOL
+	struct iwl_testmode_trace testmode_trace;
+#endif
+	u32 dbg_fixed_rate;
+
 }; /*iwl_priv */
 
 static inline void iwl_txq_ctx_activate(struct iwl_priv *priv, int txq_id)
@@ -1658,21 +1569,24 @@
 	     ctx < &priv->contexts[NUM_IWL_RXON_CTX]; ctx++)	\
 		if (priv->valid_contexts & BIT(ctx->ctxid))
 
-static inline int iwl_is_associated(struct iwl_priv *priv,
-				    enum iwl_rxon_context_id ctxid)
+static inline int iwl_is_associated_ctx(struct iwl_rxon_context *ctx)
 {
-	return (priv->contexts[ctxid].active.filter_flags &
-			RXON_FILTER_ASSOC_MSK) ? 1 : 0;
+	return (ctx->active.filter_flags & RXON_FILTER_ASSOC_MSK) ? 1 : 0;
 }
 
-static inline int iwl_is_any_associated(struct iwl_priv *priv)
+static inline int iwl_is_associated(struct iwl_priv *priv,
+				    enum iwl_rxon_context_id ctxid)
 {
-	return iwl_is_associated(priv, IWL_RXON_CTX_BSS);
+	return iwl_is_associated_ctx(&priv->contexts[ctxid]);
 }
 
-static inline int iwl_is_associated_ctx(struct iwl_rxon_context *ctx)
+static inline int iwl_is_any_associated(struct iwl_priv *priv)
 {
-	return (ctx->active.filter_flags & RXON_FILTER_ASSOC_MSK) ? 1 : 0;
+	struct iwl_rxon_context *ctx;
+	for_each_context(priv, ctx)
+		if (iwl_is_associated_ctx(ctx))
+			return true;
+	return false;
 }
 
 static inline int is_channel_valid(const struct iwl_channel_info *ch_info)
@@ -1710,12 +1624,10 @@
 static inline void __iwl_free_pages(struct iwl_priv *priv, struct page *page)
 {
 	__free_pages(page, priv->hw_params.rx_page_order);
-	priv->alloc_rxb_page--;
 }
 
 static inline void iwl_free_pages(struct iwl_priv *priv, unsigned long page)
 {
 	free_pages(page, priv->hw_params.rx_page_order);
-	priv->alloc_rxb_page--;
 }
 #endif				/* __iwl_dev_h__ */
diff -druN linux-2.6.39-libre/drivers/net/wireless/iwlwifi/iwl-devtrace.c linux-3.0-rc7-libre/drivers/net/wireless/iwlwifi/iwl-devtrace.c
--- linux-2.6.39-libre/drivers/net/wireless/iwlwifi/iwl-devtrace.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/iwlwifi/iwl-devtrace.c	2011-07-11 19:51:52.000000000 -0400
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2009 - 2011 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 -druN linux-2.6.39-libre/drivers/net/wireless/iwlwifi/iwl-devtrace.h linux-3.0-rc7-libre/drivers/net/wireless/iwlwifi/iwl-devtrace.h
--- linux-2.6.39-libre/drivers/net/wireless/iwlwifi/iwl-devtrace.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/iwlwifi/iwl-devtrace.h	2011-07-11 19:51:52.000000000 -0400
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2009 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2009 - 2011 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
@@ -137,20 +137,27 @@
 #define TRACE_SYSTEM iwlwifi
 
 TRACE_EVENT(iwlwifi_dev_hcmd,
-	TP_PROTO(struct iwl_priv *priv, void *hcmd, size_t len, u32 flags),
-	TP_ARGS(priv, hcmd, len, flags),
+	TP_PROTO(struct iwl_priv *priv, u32 flags,
+		 const void *hcmd0, size_t len0,
+		 const void *hcmd1, size_t len1,
+		 const void *hcmd2, size_t len2),
+	TP_ARGS(priv, flags, hcmd0, len0, hcmd1, len1, hcmd2, len2),
 	TP_STRUCT__entry(
 		PRIV_ENTRY
-		__dynamic_array(u8, hcmd, len)
+		__dynamic_array(u8, hcmd0, len0)
+		__dynamic_array(u8, hcmd1, len1)
+		__dynamic_array(u8, hcmd2, len2)
 		__field(u32, flags)
 	),
 	TP_fast_assign(
 		PRIV_ASSIGN;
-		memcpy(__get_dynamic_array(hcmd), hcmd, len);
+		memcpy(__get_dynamic_array(hcmd0), hcmd0, len0);
+		memcpy(__get_dynamic_array(hcmd1), hcmd1, len1);
+		memcpy(__get_dynamic_array(hcmd2), hcmd2, len2);
 		__entry->flags = flags;
 	),
 	TP_printk("[%p] hcmd %#.2x (%ssync)",
-		  __entry->priv, ((u8 *)__get_dynamic_array(hcmd))[0],
+		  __entry->priv, ((u8 *)__get_dynamic_array(hcmd0))[0],
 		  __entry->flags & CMD_ASYNC ? "a" : "")
 );
 
@@ -202,15 +209,18 @@
 );
 
 TRACE_EVENT(iwlwifi_dev_ucode_error,
-	TP_PROTO(struct iwl_priv *priv, u32 desc, u32 time,
+	TP_PROTO(struct iwl_priv *priv, u32 desc, u32 tsf_low,
 		 u32 data1, u32 data2, u32 line, u32 blink1,
-		 u32 blink2, u32 ilink1, u32 ilink2),
-	TP_ARGS(priv, desc, time, data1, data2, line,
-		blink1, blink2, ilink1, ilink2),
+		 u32 blink2, u32 ilink1, u32 ilink2, u32 bcon_time,
+		 u32 gp1, u32 gp2, u32 gp3, u32 ucode_ver, u32 hw_ver,
+		 u32 brd_ver),
+	TP_ARGS(priv, desc, tsf_low, data1, data2, line,
+		blink1, blink2, ilink1, ilink2, bcon_time, gp1, gp2,
+		gp3, ucode_ver, hw_ver, brd_ver),
 	TP_STRUCT__entry(
 		PRIV_ENTRY
 		__field(u32, desc)
-		__field(u32, time)
+		__field(u32, tsf_low)
 		__field(u32, data1)
 		__field(u32, data2)
 		__field(u32, line)
@@ -218,11 +228,18 @@
 		__field(u32, blink2)
 		__field(u32, ilink1)
 		__field(u32, ilink2)
+		__field(u32, bcon_time)
+		__field(u32, gp1)
+		__field(u32, gp2)
+		__field(u32, gp3)
+		__field(u32, ucode_ver)
+		__field(u32, hw_ver)
+		__field(u32, brd_ver)
 	),
 	TP_fast_assign(
 		PRIV_ASSIGN;
 		__entry->desc = desc;
-		__entry->time = time;
+		__entry->tsf_low = tsf_low;
 		__entry->data1 = data1;
 		__entry->data2 = data2;
 		__entry->line = line;
@@ -230,12 +247,25 @@
 		__entry->blink2 = blink2;
 		__entry->ilink1 = ilink1;
 		__entry->ilink2 = ilink2;
+		__entry->bcon_time = bcon_time;
+		__entry->gp1 = gp1;
+		__entry->gp2 = gp2;
+		__entry->gp3 = gp3;
+		__entry->ucode_ver = ucode_ver;
+		__entry->hw_ver = hw_ver;
+		__entry->brd_ver = brd_ver;
 	),
 	TP_printk("[%p] #%02d %010u data 0x%08X 0x%08X line %u, "
-		  "blink 0x%05X 0x%05X ilink 0x%05X 0x%05X",
-		  __entry->priv, __entry->desc, __entry->time, __entry->data1,
+		  "blink 0x%05X 0x%05X ilink 0x%05X 0x%05X "
+		  "bcon_tm %010u gp 0x%08X 0x%08X 0x%08X uCode 0x%08X "
+		  "hw 0x%08X brd 0x%08X",
+		  __entry->priv, __entry->desc, __entry->tsf_low,
+		  __entry->data1,
 		  __entry->data2, __entry->line, __entry->blink1,
-		  __entry->blink2, __entry->ilink1, __entry->ilink2)
+		  __entry->blink2, __entry->ilink1, __entry->ilink2,
+		  __entry->bcon_time, __entry->gp1, __entry->gp2,
+		  __entry->gp3, __entry->ucode_ver, __entry->hw_ver,
+		  __entry->brd_ver)
 );
 
 TRACE_EVENT(iwlwifi_dev_ucode_event,
diff -druN linux-2.6.39-libre/drivers/net/wireless/iwlwifi/iwl-eeprom.c linux-3.0-rc7-libre/drivers/net/wireless/iwlwifi/iwl-eeprom.c
--- linux-2.6.39-libre/drivers/net/wireless/iwlwifi/iwl-eeprom.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/iwlwifi/iwl-eeprom.c	2011-07-11 19:51:52.000000000 -0400
@@ -5,7 +5,7 @@
  *
  * GPL LICENSE SUMMARY
  *
- * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2008 - 2011 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 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -142,6 +142,45 @@
  *
 ******************************************************************************/
 
+/*
+ * The device's EEPROM semaphore prevents conflicts between driver and uCode
+ * when accessing the EEPROM; each access is a series of pulses to/from the
+ * EEPROM chip, not a single event, so even reads could conflict if they
+ * weren't arbitrated by the semaphore.
+ */
+static int iwl_eeprom_acquire_semaphore(struct iwl_priv *priv)
+{
+	u16 count;
+	int ret;
+
+	for (count = 0; count < EEPROM_SEM_RETRY_LIMIT; count++) {
+		/* Request semaphore */
+		iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG,
+			    CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM);
+
+		/* See if we got it */
+		ret = iwl_poll_bit(priv, CSR_HW_IF_CONFIG_REG,
+				CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM,
+				CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM,
+				EEPROM_SEM_TIMEOUT);
+		if (ret >= 0) {
+			IWL_DEBUG_EEPROM(priv,
+				"Acquired semaphore after %d tries.\n",
+				count+1);
+			return ret;
+		}
+	}
+
+	return ret;
+}
+
+static void iwl_eeprom_release_semaphore(struct iwl_priv *priv)
+{
+	iwl_clear_bit(priv, CSR_HW_IF_CONFIG_REG,
+		CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM);
+
+}
+
 static int iwl_eeprom_verify_signature(struct iwl_priv *priv)
 {
 	u32 gp = iwl_read32(priv, CSR_EEPROM_GP) & CSR_EEPROM_GP_VALID_MSK;
@@ -177,29 +216,26 @@
 
 static void iwl_set_otp_access(struct iwl_priv *priv, enum iwl_access_mode mode)
 {
-	u32 otpgp;
+	iwl_read32(priv, CSR_OTP_GP_REG);
 
-	otpgp = iwl_read32(priv, CSR_OTP_GP_REG);
 	if (mode == IWL_OTP_ACCESS_ABSOLUTE)
 		iwl_clear_bit(priv, CSR_OTP_GP_REG,
-				CSR_OTP_GP_REG_OTP_ACCESS_MODE);
+			      CSR_OTP_GP_REG_OTP_ACCESS_MODE);
 	else
 		iwl_set_bit(priv, CSR_OTP_GP_REG,
-				CSR_OTP_GP_REG_OTP_ACCESS_MODE);
+			    CSR_OTP_GP_REG_OTP_ACCESS_MODE);
 }
 
-static int iwlcore_get_nvm_type(struct iwl_priv *priv)
+static int iwlcore_get_nvm_type(struct iwl_priv *priv, u32 hw_rev)
 {
 	u32 otpgp;
 	int nvm_type;
 
 	/* OTP only valid for CP/PP and after */
-	switch (priv->hw_rev & CSR_HW_REV_TYPE_MSK) {
+	switch (hw_rev & CSR_HW_REV_TYPE_MSK) {
 	case CSR_HW_REV_TYPE_NONE:
 		IWL_ERR(priv, "Unknown hardware type\n");
 		return -ENOENT;
-	case CSR_HW_REV_TYPE_3945:
-	case CSR_HW_REV_TYPE_4965:
 	case CSR_HW_REV_TYPE_5300:
 	case CSR_HW_REV_TYPE_5350:
 	case CSR_HW_REV_TYPE_5100:
@@ -217,26 +253,20 @@
 	return  nvm_type;
 }
 
-const u8 *iwlcore_eeprom_query_addr(const struct iwl_priv *priv, size_t offset)
-{
-	BUG_ON(offset >= priv->cfg->base_params->eeprom_size);
-	return &priv->eeprom[offset];
-}
-
 static int iwl_init_otp_access(struct iwl_priv *priv)
 {
 	int ret;
 
 	/* Enable 40MHz radio clock */
-	_iwl_write32(priv, CSR_GP_CNTRL,
-		     _iwl_read32(priv, CSR_GP_CNTRL) |
-		     CSR_GP_CNTRL_REG_FLAG_INIT_DONE);
+	iwl_write32(priv, CSR_GP_CNTRL,
+		    iwl_read32(priv, CSR_GP_CNTRL) |
+		    CSR_GP_CNTRL_REG_FLAG_INIT_DONE);
 
 	/* wait for clock to be ready */
 	ret = iwl_poll_bit(priv, CSR_GP_CNTRL,
-				  CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY,
-				  CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY,
-				  25000);
+				 CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY,
+				 CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY,
+				 25000);
 	if (ret < 0)
 		IWL_ERR(priv, "Time out access OTP\n");
 	else {
@@ -263,17 +293,17 @@
 	u32 r;
 	u32 otpgp;
 
-	_iwl_write32(priv, CSR_EEPROM_REG,
-		     CSR_EEPROM_REG_MSK_ADDR & (addr << 1));
+	iwl_write32(priv, CSR_EEPROM_REG,
+		    CSR_EEPROM_REG_MSK_ADDR & (addr << 1));
 	ret = iwl_poll_bit(priv, CSR_EEPROM_REG,
-				  CSR_EEPROM_REG_READ_VALID_MSK,
-				  CSR_EEPROM_REG_READ_VALID_MSK,
-				  IWL_EEPROM_ACCESS_TIMEOUT);
+				 CSR_EEPROM_REG_READ_VALID_MSK,
+				 CSR_EEPROM_REG_READ_VALID_MSK,
+				 IWL_EEPROM_ACCESS_TIMEOUT);
 	if (ret < 0) {
 		IWL_ERR(priv, "Time out reading OTP[%d]\n", addr);
 		return ret;
 	}
-	r = _iwl_read_direct32(priv, CSR_EEPROM_REG);
+	r = iwl_read32(priv, CSR_EEPROM_REG);
 	/* check for ECC errors: */
 	otpgp = iwl_read32(priv, CSR_OTP_GP_REG);
 	if (otpgp & CSR_OTP_GP_REG_ECC_UNCORR_STATUS_MSK) {
@@ -396,7 +426,7 @@
  *
  * NOTE:  This routine uses the non-debug IO access functions.
  */
-int iwl_eeprom_init(struct iwl_priv *priv)
+int iwl_eeprom_init(struct iwl_priv *priv, u32 hw_rev)
 {
 	__le16 *e;
 	u32 gp = iwl_read32(priv, CSR_EEPROM_GP);
@@ -406,7 +436,7 @@
 	u16 validblockaddr = 0;
 	u16 cache_addr = 0;
 
-	priv->nvm_device_type = iwlcore_get_nvm_type(priv);
+	priv->nvm_device_type = iwlcore_get_nvm_type(priv, hw_rev);
 	if (priv->nvm_device_type == -ENOENT)
 		return -ENOENT;
 	/* allocate eeprom */
@@ -429,7 +459,7 @@
 	}
 
 	/* Make sure driver (instead of uCode) is allowed to read EEPROM */
-	ret = priv->cfg->ops->lib->eeprom_ops.acquire_semaphore(priv);
+	ret = iwl_eeprom_acquire_semaphore(priv);
 	if (ret < 0) {
 		IWL_ERR(priv, "Failed to acquire EEPROM semaphore.\n");
 		ret = -ENOENT;
@@ -444,9 +474,9 @@
 			ret = -ENOENT;
 			goto done;
 		}
-		_iwl_write32(priv, CSR_EEPROM_GP,
-			     iwl_read32(priv, CSR_EEPROM_GP) &
-			     ~CSR_EEPROM_GP_IF_OWNER_MSK);
+		iwl_write32(priv, CSR_EEPROM_GP,
+			    iwl_read32(priv, CSR_EEPROM_GP) &
+			    ~CSR_EEPROM_GP_IF_OWNER_MSK);
 
 		iwl_set_bit(priv, CSR_OTP_GP_REG,
 			     CSR_OTP_GP_REG_ECC_CORR_STATUS_MSK |
@@ -473,8 +503,8 @@
 		for (addr = 0; addr < sz; addr += sizeof(u16)) {
 			u32 r;
 
-			_iwl_write32(priv, CSR_EEPROM_REG,
-				     CSR_EEPROM_REG_MSK_ADDR & (addr << 1));
+			iwl_write32(priv, CSR_EEPROM_REG,
+				    CSR_EEPROM_REG_MSK_ADDR & (addr << 1));
 
 			ret = iwl_poll_bit(priv, CSR_EEPROM_REG,
 						  CSR_EEPROM_REG_READ_VALID_MSK,
@@ -484,7 +514,7 @@
 				IWL_ERR(priv, "Time out reading EEPROM[%d]\n", addr);
 				goto done;
 			}
-			r = _iwl_read_direct32(priv, CSR_EEPROM_REG);
+			r = iwl_read32(priv, CSR_EEPROM_REG);
 			e[addr / 2] = cpu_to_le16(r >> 16);
 		}
 	}
@@ -496,7 +526,7 @@
 
 	ret = 0;
 done:
-	priv->cfg->ops->lib->eeprom_ops.release_semaphore(priv);
+	iwl_eeprom_release_semaphore(priv);
 
 err:
 	if (ret)
@@ -719,13 +749,6 @@
 					     flags & EEPROM_CHANNEL_RADAR))
 				       ? "" : "not ");
 
-			/* Set the tx_power_user_lmt to the highest power
-			 * supported by any channel */
-			if (eeprom_ch_info[ch].max_power_avg >
-						priv->tx_power_user_lmt)
-				priv->tx_power_user_lmt =
-				    eeprom_ch_info[ch].max_power_avg;
-
 			ch_info++;
 		}
 	}
diff -druN linux-2.6.39-libre/drivers/net/wireless/iwlwifi/iwl-eeprom.h linux-3.0-rc7-libre/drivers/net/wireless/iwlwifi/iwl-eeprom.h
--- linux-2.6.39-libre/drivers/net/wireless/iwlwifi/iwl-eeprom.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/iwlwifi/iwl-eeprom.h	2011-07-11 19:51:52.000000000 -0400
@@ -5,7 +5,7 @@
  *
  * GPL LICENSE SUMMARY
  *
- * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2008 - 2011 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 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -110,10 +110,6 @@
 };
 
 /* SKU Capabilities */
-/* 3945 only */
-#define EEPROM_SKU_CAP_SW_RF_KILL_ENABLE                (1 << 0)
-#define EEPROM_SKU_CAP_HW_RF_KILL_ENABLE                (1 << 1)
-
 /* 5000 and up */
 #define EEPROM_SKU_CAP_BAND_POS				(4)
 #define EEPROM_SKU_CAP_BAND_SELECTION	                \
@@ -168,28 +164,6 @@
 	s8 mimo3_max;
 } __packed;
 
-/* 3945 Specific */
-#define EEPROM_3945_EEPROM_VERSION	(0x2f)
-
-/* 4965 has two radio transmitters (and 3 radio receivers) */
-#define EEPROM_TX_POWER_TX_CHAINS      (2)
-
-/* 4965 has room for up to 8 sets of txpower calibration data */
-#define EEPROM_TX_POWER_BANDS          (8)
-
-/* 4965 factory calibration measures txpower gain settings for
- * each of 3 target output levels */
-#define EEPROM_TX_POWER_MEASUREMENTS   (3)
-
-/* 4965 Specific */
-/* 4965 driver does not work with txpower calibration version < 5 */
-#define EEPROM_4965_TX_POWER_VERSION    (5)
-#define EEPROM_4965_EEPROM_VERSION	(0x2f)
-#define EEPROM_4965_CALIB_VERSION_OFFSET       (2*0xB6) /* 2 bytes */
-#define EEPROM_4965_CALIB_TXPOWER_OFFSET       (2*0xE8) /* 48  bytes */
-#define EEPROM_4965_BOARD_REVISION             (2*0x4F) /* 2 bytes */
-#define EEPROM_4965_BOARD_PBA                  (2*0x56+1) /* 9 bytes */
-
 /* 5000 Specific */
 #define EEPROM_5000_TX_POWER_VERSION    (4)
 #define EEPROM_5000_EEPROM_VERSION	(0x11A)
@@ -282,90 +256,6 @@
 /* 2.4 GHz */
 extern const u8 iwl_eeprom_band_1[14];
 
-/*
- * factory calibration data for one txpower level, on one channel,
- * measured on one of the 2 tx chains (radio transmitter and associated
- * antenna).  EEPROM contains:
- *
- * 1)  Temperature (degrees Celsius) of device when measurement was made.
- *
- * 2)  Gain table index used to achieve the target measurement power.
- *     This refers to the "well-known" gain tables (see iwl-4965-hw.h).
- *
- * 3)  Actual measured output power, in half-dBm ("34" = 17 dBm).
- *
- * 4)  RF power amplifier detector level measurement (not used).
- */
-struct iwl_eeprom_calib_measure {
-	u8 temperature;		/* Device temperature (Celsius) */
-	u8 gain_idx;		/* Index into gain table */
-	u8 actual_pow;		/* Measured RF output power, half-dBm */
-	s8 pa_det;		/* Power amp detector level (not used) */
-} __packed;
-
-
-/*
- * measurement set for one channel.  EEPROM contains:
- *
- * 1)  Channel number measured
- *
- * 2)  Measurements for each of 3 power levels for each of 2 radio transmitters
- *     (a.k.a. "tx chains") (6 measurements altogether)
- */
-struct iwl_eeprom_calib_ch_info {
-	u8 ch_num;
-	struct iwl_eeprom_calib_measure
-		measurements[EEPROM_TX_POWER_TX_CHAINS]
-			[EEPROM_TX_POWER_MEASUREMENTS];
-} __packed;
-
-/*
- * txpower subband info.
- *
- * For each frequency subband, EEPROM contains the following:
- *
- * 1)  First and last channels within range of the subband.  "0" values
- *     indicate that this sample set is not being used.
- *
- * 2)  Sample measurement sets for 2 channels close to the range endpoints.
- */
-struct iwl_eeprom_calib_subband_info {
-	u8 ch_from;	/* channel number of lowest channel in subband */
-	u8 ch_to;	/* channel number of highest channel in subband */
-	struct iwl_eeprom_calib_ch_info ch1;
-	struct iwl_eeprom_calib_ch_info ch2;
-} __packed;
-
-
-/*
- * txpower calibration info.  EEPROM contains:
- *
- * 1)  Factory-measured saturation power levels (maximum levels at which
- *     tx power amplifier can output a signal without too much distortion).
- *     There is one level for 2.4 GHz band and one for 5 GHz band.  These
- *     values apply to all channels within each of the bands.
- *
- * 2)  Factory-measured power supply voltage level.  This is assumed to be
- *     constant (i.e. same value applies to all channels/bands) while the
- *     factory measurements are being made.
- *
- * 3)  Up to 8 sets of factory-measured txpower calibration values.
- *     These are for different frequency ranges, since txpower gain
- *     characteristics of the analog radio circuitry vary with frequency.
- *
- *     Not all sets need to be filled with data;
- *     struct iwl_eeprom_calib_subband_info contains range of channels
- *     (0 if unused) for each set of data.
- */
-struct iwl_eeprom_calib_info {
-	u8 saturation_power24;	/* half-dBm (e.g. "34" = 17 dBm) */
-	u8 saturation_power52;	/* half-dBm */
-	__le16 voltage;		/* signed */
-	struct iwl_eeprom_calib_subband_info
-		band_info[EEPROM_TX_POWER_BANDS];
-} __packed;
-
-
 #define ADDRESS_MSK                 0x0000FFFF
 #define INDIRECT_TYPE_MSK           0x000F0000
 #define INDIRECT_HOST               0x00010000
@@ -398,103 +288,24 @@
 #define EEPROM_RF_CFG_TX_ANT_MSK(x) ((x >> 8)  & 0xF) /* bits 8-11  */
 #define EEPROM_RF_CFG_RX_ANT_MSK(x) ((x >> 12) & 0xF) /* bits 12-15 */
 
-#define EEPROM_3945_RF_CFG_TYPE_MAX  0x0
-#define EEPROM_4965_RF_CFG_TYPE_MAX  0x1
-
-/* Radio Config for 5000 and up */
-#define EEPROM_RF_CONFIG_TYPE_R3x3	0x0
-#define EEPROM_RF_CONFIG_TYPE_R2x2	0x1
-#define EEPROM_RF_CONFIG_TYPE_R1x2	0x2
 #define EEPROM_RF_CONFIG_TYPE_MAX	0x3
 
-/*
- * Per-channel regulatory data.
- *
- * Each channel that *might* be supported by iwl has a fixed location
- * in EEPROM containing EEPROM_CHANNEL_* usage flags (LSB) and max regulatory
- * txpower (MSB).
- *
- * Entries immediately below are for 20 MHz channel width.  HT40 (40 MHz)
- * channels (only for 4965, not supported by 3945) appear later in the EEPROM.
- *
- * 2.4 GHz channels 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14
- */
-#define EEPROM_REGULATORY_SKU_ID            (2*0x60)    /* 4  bytes */
-#define EEPROM_REGULATORY_BAND_1            (2*0x62)	/* 2  bytes */
-#define EEPROM_REGULATORY_BAND_1_CHANNELS   (2*0x63)	/* 28 bytes */
-
-/*
- * 4.9 GHz channels 183, 184, 185, 187, 188, 189, 192, 196,
- * 5.0 GHz channels 7, 8, 11, 12, 16
- * (4915-5080MHz) (none of these is ever supported)
- */
-#define EEPROM_REGULATORY_BAND_2            (2*0x71)	/* 2  bytes */
-#define EEPROM_REGULATORY_BAND_2_CHANNELS   (2*0x72)	/* 26 bytes */
-
-/*
- * 5.2 GHz channels 34, 36, 38, 40, 42, 44, 46, 48, 52, 56, 60, 64
- * (5170-5320MHz)
- */
-#define EEPROM_REGULATORY_BAND_3            (2*0x7F)	/* 2  bytes */
-#define EEPROM_REGULATORY_BAND_3_CHANNELS   (2*0x80)	/* 24 bytes */
-
-/*
- * 5.5 GHz channels 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140
- * (5500-5700MHz)
- */
-#define EEPROM_REGULATORY_BAND_4            (2*0x8C)	/* 2  bytes */
-#define EEPROM_REGULATORY_BAND_4_CHANNELS   (2*0x8D)	/* 22 bytes */
-
-/*
- * 5.7 GHz channels 145, 149, 153, 157, 161, 165
- * (5725-5825MHz)
- */
-#define EEPROM_REGULATORY_BAND_5            (2*0x98)	/* 2  bytes */
-#define EEPROM_REGULATORY_BAND_5_CHANNELS   (2*0x99)	/* 12 bytes */
-
-/*
- * 2.4 GHz HT40 channels 1 (5), 2 (6), 3 (7), 4 (8), 5 (9), 6 (10), 7 (11)
- *
- * The channel listed is the center of the lower 20 MHz half of the channel.
- * The overall center frequency is actually 2 channels (10 MHz) above that,
- * and the upper half of each HT40 channel is centered 4 channels (20 MHz) away
- * from the lower half; e.g. the upper half of HT40 channel 1 is channel 5,
- * and the overall HT40 channel width centers on channel 3.
- *
- * NOTE:  The RXON command uses 20 MHz channel numbers to specify the
- *        control channel to which to tune.  RXON also specifies whether the
- *        control channel is the upper or lower half of a HT40 channel.
- *
- * NOTE:  4965 does not support HT40 channels on 2.4 GHz.
- */
-#define EEPROM_4965_REGULATORY_BAND_24_HT40_CHANNELS (2*0xA0)	/* 14 bytes */
-
-/*
- * 5.2 GHz HT40 channels 36 (40), 44 (48), 52 (56), 60 (64),
- * 100 (104), 108 (112), 116 (120), 124 (128), 132 (136), 149 (153), 157 (161)
- */
-#define EEPROM_4965_REGULATORY_BAND_52_HT40_CHANNELS (2*0xA8)	/* 22 bytes */
-
 #define EEPROM_REGULATORY_BAND_NO_HT40			(0)
 
 struct iwl_eeprom_ops {
 	const u32 regulatory_bands[7];
-	int (*acquire_semaphore) (struct iwl_priv *priv);
-	void (*release_semaphore) (struct iwl_priv *priv);
-	u16 (*calib_version) (struct iwl_priv *priv);
 	const u8* (*query_addr) (const struct iwl_priv *priv, size_t offset);
 	void (*update_enhanced_txpower) (struct iwl_priv *priv);
 };
 
 
-int iwl_eeprom_init(struct iwl_priv *priv);
+int iwl_eeprom_init(struct iwl_priv *priv, u32 hw_rev);
 void iwl_eeprom_free(struct iwl_priv *priv);
 int  iwl_eeprom_check_version(struct iwl_priv *priv);
 int  iwl_eeprom_check_sku(struct iwl_priv *priv);
 const u8 *iwl_eeprom_query_addr(const struct iwl_priv *priv, size_t offset);
 int iwlcore_eeprom_verify_signature(struct iwl_priv *priv);
 u16 iwl_eeprom_query16(const struct iwl_priv *priv, size_t offset);
-const u8 *iwlcore_eeprom_query_addr(const struct iwl_priv *priv, size_t offset);
 int iwl_init_channel_map(struct iwl_priv *priv);
 void iwl_free_channel_map(struct iwl_priv *priv);
 const struct iwl_channel_info *iwl_get_channel_info(
diff -druN linux-2.6.39-libre/drivers/net/wireless/iwlwifi/iwl-fh.h linux-3.0-rc7-libre/drivers/net/wireless/iwlwifi/iwl-fh.h
--- linux-2.6.39-libre/drivers/net/wireless/iwlwifi/iwl-fh.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/iwlwifi/iwl-fh.h	2011-07-11 19:51:52.000000000 -0400
@@ -5,7 +5,7 @@
  *
  * GPL LICENSE SUMMARY
  *
- * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2011 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 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -77,14 +77,14 @@
 /**
  * Keep-Warm (KW) buffer base address.
  *
- * Driver must allocate a 4KByte buffer that is used by 4965 for keeping the
+ * Driver must allocate a 4KByte buffer that is for keeping the
  * host DRAM powered on (via dummy accesses to DRAM) to maintain low-latency
- * DRAM access when 4965 is Txing or Rxing.  The dummy accesses prevent host
+ * DRAM access when doing Txing or Rxing.  The dummy accesses prevent host
  * from going into a power-savings mode that would cause higher DRAM latency,
  * and possible data over/under-runs, before all Tx/Rx is complete.
  *
  * Driver loads FH_KW_MEM_ADDR_REG with the physical address (bits 35:4)
- * of the buffer, which must be 4K aligned.  Once this is set up, the 4965
+ * of the buffer, which must be 4K aligned.  Once this is set up, the device
  * automatically invokes keep-warm accesses when normal accesses might not
  * be sufficient to maintain fast DRAM response.
  *
@@ -97,7 +97,7 @@
 /**
  * TFD Circular Buffers Base (CBBC) addresses
  *
- * 4965 has 16 base pointer registers, one for each of 16 host-DRAM-resident
+ * Device has 16 base pointer registers, one for each of 16 host-DRAM-resident
  * circular buffers (CBs/queues) containing Transmit Frame Descriptors (TFDs)
  * (see struct iwl_tfd_frame).  These 16 pointer registers are offset by 0x04
  * bytes from one another.  Each TFD circular buffer in DRAM must be 256-byte
@@ -116,16 +116,16 @@
 /**
  * Rx SRAM Control and Status Registers (RSCSR)
  *
- * These registers provide handshake between driver and 4965 for the Rx queue
+ * These registers provide handshake between driver and device for the Rx queue
  * (this queue handles *all* command responses, notifications, Rx data, etc.
- * sent from 4965 uCode to host driver).  Unlike Tx, there is only one Rx
+ * sent from uCode to host driver).  Unlike Tx, there is only one Rx
  * queue, and only one Rx DMA/FIFO channel.  Also unlike Tx, which can
  * concatenate up to 20 DRAM buffers to form a Tx frame, each Receive Buffer
  * Descriptor (RBD) points to only one Rx Buffer (RB); there is a 1:1
  * mapping between RBDs and RBs.
  *
  * Driver must allocate host DRAM memory for the following, and set the
- * physical address of each into 4965 registers:
+ * physical address of each into device registers:
  *
  * 1)  Receive Buffer Descriptor (RBD) circular buffer (CB), typically with 256
  *     entries (although any power of 2, up to 4096, is selectable by driver).
@@ -140,20 +140,20 @@
  *     Driver sets physical address [35:8] of base of RBD circular buffer
  *     into FH_RSCSR_CHNL0_RBDCB_BASE_REG [27:0].
  *
- * 2)  Rx status buffer, 8 bytes, in which 4965 indicates which Rx Buffers
+ * 2)  Rx status buffer, 8 bytes, in which uCode indicates which Rx Buffers
  *     (RBs) have been filled, via a "write pointer", actually the index of
  *     the RB's corresponding RBD within the circular buffer.  Driver sets
  *     physical address [35:4] into FH_RSCSR_CHNL0_STTS_WPTR_REG [31:0].
  *
  *     Bit fields in lower dword of Rx status buffer (upper dword not used
- *     by driver; see struct iwl4965_shared, val0):
+ *     by driver:
  *     31-12:  Not used by driver
  *     11- 0:  Index of last filled Rx buffer descriptor
- *             (4965 writes, driver reads this value)
+ *             (device writes, driver reads this value)
  *
- * As the driver prepares Receive Buffers (RBs) for 4965 to fill, driver must
+ * As the driver prepares Receive Buffers (RBs) for device to fill, driver must
  * enter pointers to these RBs into contiguous RBD circular buffer entries,
- * and update the 4965's "write" index register,
+ * and update the device's "write" index register,
  * FH_RSCSR_CHNL0_RBDCB_WPTR_REG.
  *
  * This "write" index corresponds to the *next* RBD that the driver will make
@@ -162,12 +162,12 @@
  * RBs), should be 8 after preparing the first 8 RBs (for example), and must
  * wrap back to 0 at the end of the circular buffer (but don't wrap before
  * "read" index has advanced past 1!  See below).
- * NOTE:  4965 EXPECTS THE WRITE INDEX TO BE INCREMENTED IN MULTIPLES OF 8.
+ * NOTE:  DEVICE EXPECTS THE WRITE INDEX TO BE INCREMENTED IN MULTIPLES OF 8.
  *
- * As the 4965 fills RBs (referenced from contiguous RBDs within the circular
+ * As the device fills RBs (referenced from contiguous RBDs within the circular
  * buffer), it updates the Rx status buffer in host DRAM, 2) described above,
  * to tell the driver the index of the latest filled RBD.  The driver must
- * read this "read" index from DRAM after receiving an Rx interrupt from 4965.
+ * read this "read" index from DRAM after receiving an Rx interrupt from device
  *
  * The driver must also internally keep track of a third index, which is the
  * next RBD to process.  When receiving an Rx interrupt, driver should process
@@ -176,7 +176,7 @@
  * driver may process the RB pointed to by RBD 0.  Depending on volume of
  * traffic, there may be many RBs to process.
  *
- * If read index == write index, 4965 thinks there is no room to put new data.
+ * If read index == write index, device thinks there is no room to put new data.
  * Due to this, the maximum number of filled RBs is 255, instead of 256.  To
  * be safe, make sure that there is a gap of at least 2 RBDs between "write"
  * and "read" indexes; that is, make sure that there are no more than 254
@@ -303,7 +303,7 @@
 /**
  * Transmit DMA Channel Control/Status Registers (TCSR)
  *
- * 4965 has one configuration register for each of 8 Tx DMA/FIFO channels
+ * Device has one configuration register for each of 8 Tx DMA/FIFO channels
  * supported in hardware (don't confuse these with the 16 Tx queues in DRAM,
  * which feed the DMA/FIFO channels); config regs are separated by 0x20 bytes.
  *
@@ -326,7 +326,6 @@
 #define FH_TCSR_UPPER_BOUND  (FH_MEM_LOWER_BOUND + 0xE60)
 
 /* Find Control/Status reg for given Tx DMA/FIFO channel */
-#define FH49_TCSR_CHNL_NUM                            (7)
 #define FH50_TCSR_CHNL_NUM                            (8)
 
 /* TCSR: tx_config register values */
@@ -424,7 +423,6 @@
 #define RX_LOW_WATERMARK 8
 
 /* Size of one Rx buffer in host DRAM */
-#define IWL_RX_BUF_SIZE_3K (3 * 1000) /* 3945 only */
 #define IWL_RX_BUF_SIZE_4K (4 * 1024)
 #define IWL_RX_BUF_SIZE_8K (8 * 1024)
 
@@ -443,7 +441,7 @@
 	__le16 closed_fr_num;
 	__le16 finished_rb_num;
 	__le16 finished_fr_nam;
-	__le32 __unused; /* 3945 only */
+	__le32 __unused;
 } __packed;
 
 
diff -druN linux-2.6.39-libre/drivers/net/wireless/iwlwifi/iwl-hcmd.c linux-3.0-rc7-libre/drivers/net/wireless/iwlwifi/iwl-hcmd.c
--- linux-2.6.39-libre/drivers/net/wireless/iwlwifi/iwl-hcmd.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/iwlwifi/iwl-hcmd.c	2011-07-11 19:51:52.000000000 -0400
@@ -2,7 +2,7 @@
  *
  * GPL LICENSE SUMMARY
  *
- * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2008 - 2011 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
@@ -51,9 +51,7 @@
 		IWL_CMD(REPLY_REMOVE_ALL_STA);
 		IWL_CMD(REPLY_TXFIFO_FLUSH);
 		IWL_CMD(REPLY_WEPKEY);
-		IWL_CMD(REPLY_3945_RX);
 		IWL_CMD(REPLY_TX);
-		IWL_CMD(REPLY_RATE_SCALE);
 		IWL_CMD(REPLY_LEDS_CMD);
 		IWL_CMD(REPLY_TX_LINK_QUALITY_CMD);
 		IWL_CMD(COEX_PRIORITY_TABLE_CMD);
@@ -145,10 +143,12 @@
 {
 	int ret;
 
-	BUG_ON(!(cmd->flags & CMD_ASYNC));
+	if (WARN_ON(!(cmd->flags & CMD_ASYNC)))
+		return -EINVAL;
 
 	/* An asynchronous command can not expect an SKB to be set. */
-	BUG_ON(cmd->flags & CMD_WANT_SKB);
+	if (WARN_ON(cmd->flags & CMD_WANT_SKB))
+		return -EINVAL;
 
 	/* Assign a generic callback if one is not provided */
 	if (!cmd->callback)
@@ -171,14 +171,15 @@
 	int cmd_idx;
 	int ret;
 
-	BUG_ON(cmd->flags & CMD_ASYNC);
+	if (WARN_ON(cmd->flags & CMD_ASYNC))
+		return -EINVAL;
 
 	 /* A synchronous command can not have a callback set. */
-	BUG_ON(cmd->callback);
+	if (WARN_ON(cmd->callback))
+		return -EINVAL;
 
 	IWL_DEBUG_INFO(priv, "Attempting to send sync command %s\n",
 			get_cmd_string(cmd->id));
-	mutex_lock(&priv->sync_cmd_mutex);
 
 	set_bit(STATUS_HCMD_ACTIVE, &priv->status);
 	IWL_DEBUG_INFO(priv, "Setting HCMD_ACTIVE for command %s\n",
@@ -187,9 +188,10 @@
 	cmd_idx = iwl_enqueue_hcmd(priv, cmd);
 	if (cmd_idx < 0) {
 		ret = cmd_idx;
+		clear_bit(STATUS_HCMD_ACTIVE, &priv->status);
 		IWL_ERR(priv, "Error sending %s: enqueue_hcmd failed: %d\n",
 			  get_cmd_string(cmd->id), ret);
-		goto out;
+		return ret;
 	}
 
 	ret = wait_event_interruptible_timeout(priv->wait_command_queue,
@@ -229,8 +231,7 @@
 		goto cancel;
 	}
 
-	ret = 0;
-	goto out;
+	return 0;
 
 cancel:
 	if (cmd->flags & CMD_WANT_SKB) {
@@ -248,8 +249,7 @@
 		iwl_free_pages(priv, cmd->reply_page);
 		cmd->reply_page = 0;
 	}
-out:
-	mutex_unlock(&priv->sync_cmd_mutex);
+
 	return ret;
 }
 
@@ -265,8 +265,8 @@
 {
 	struct iwl_host_cmd cmd = {
 		.id = id,
-		.len = len,
-		.data = data,
+		.len = { len, },
+		.data = { data, },
 	};
 
 	return iwl_send_cmd_sync(priv, &cmd);
@@ -280,8 +280,8 @@
 {
 	struct iwl_host_cmd cmd = {
 		.id = id,
-		.len = len,
-		.data = data,
+		.len = { len, },
+		.data = { data, },
 	};
 
 	cmd.flags |= CMD_ASYNC;
diff -druN linux-2.6.39-libre/drivers/net/wireless/iwlwifi/iwl-helpers.h linux-3.0-rc7-libre/drivers/net/wireless/iwlwifi/iwl-helpers.h
--- linux-2.6.39-libre/drivers/net/wireless/iwlwifi/iwl-helpers.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/iwlwifi/iwl-helpers.h	2011-07-11 19:51:52.000000000 -0400
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2003 - 2011 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.
@@ -64,30 +64,6 @@
 	return --index & (n_bd - 1);
 }
 
-/* TODO: Move fw_desc functions to iwl-pci.ko */
-static inline void iwl_free_fw_desc(struct pci_dev *pci_dev,
-				    struct fw_desc *desc)
-{
-	if (desc->v_addr)
-		dma_free_coherent(&pci_dev->dev, desc->len,
-				  desc->v_addr, desc->p_addr);
-	desc->v_addr = NULL;
-	desc->len = 0;
-}
-
-static inline int iwl_alloc_fw_desc(struct pci_dev *pci_dev,
-				    struct fw_desc *desc)
-{
-	if (!desc->len) {
-		desc->v_addr = NULL;
-		return -EINVAL;
-	}
-
-	desc->v_addr = dma_alloc_coherent(&pci_dev->dev, desc->len,
-					  &desc->p_addr, GFP_KERNEL);
-	return (desc->v_addr != NULL) ? 0 : -ENOMEM;
-}
-
 /*
  * we have 8 bits used like this:
  *
@@ -131,6 +107,19 @@
 			ieee80211_stop_queue(priv->hw, ac);
 }
 
+static inline void iwl_wake_any_queue(struct iwl_priv *priv,
+				      struct iwl_rxon_context *ctx)
+{
+	u8 ac;
+
+	for (ac = 0; ac < AC_NUM; ac++) {
+		IWL_DEBUG_INFO(priv, "Queue Status: Q[%d] %s\n",
+			ac, (atomic_read(&priv->queue_stop_count[ac]) > 0)
+			      ? "stopped" : "awake");
+		iwl_wake_queue(priv, &priv->txq[ctx->ac_to_queue[ac]]);
+	}
+}
+
 #define ieee80211_stop_queue DO_NOT_USE_ieee80211_stop_queue
 #define ieee80211_wake_queue DO_NOT_USE_ieee80211_wake_queue
 
diff -druN linux-2.6.39-libre/drivers/net/wireless/iwlwifi/iwl-io.c linux-3.0-rc7-libre/drivers/net/wireless/iwlwifi/iwl-io.c
--- linux-2.6.39-libre/drivers/net/wireless/iwlwifi/iwl-io.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/net/wireless/iwlwifi/iwl-io.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,294 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2003 - 2011 Intel Corporation. All rights reserved.
+ *
+ * Portions of this file are derived from the ipw3945 project.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
+ *
+ * The full GNU General Public License is included in this distribution in the
+ * file called LICENSE.
+ *
+ * Contact Information:
+ *  Intel Linux Wireless <ilw@linux.intel.com>
+ * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+ *
+ *****************************************************************************/
+
+#include "iwl-io.h"
+
+#define IWL_POLL_INTERVAL 10	/* microseconds */
+
+static inline void __iwl_set_bit(struct iwl_priv *priv, u32 reg, u32 mask)
+{
+	iwl_write32(priv, reg, iwl_read32(priv, reg) | mask);
+}
+
+static inline void __iwl_clear_bit(struct iwl_priv *priv, u32 reg, u32 mask)
+{
+	iwl_write32(priv, reg, iwl_read32(priv, reg) & ~mask);
+}
+
+void iwl_set_bit(struct iwl_priv *priv, u32 reg, u32 mask)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&priv->reg_lock, flags);
+	__iwl_set_bit(priv, reg, mask);
+	spin_unlock_irqrestore(&priv->reg_lock, flags);
+}
+
+void iwl_clear_bit(struct iwl_priv *priv, u32 reg, u32 mask)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&priv->reg_lock, flags);
+	__iwl_clear_bit(priv, reg, mask);
+	spin_unlock_irqrestore(&priv->reg_lock, flags);
+}
+
+int iwl_poll_bit(struct iwl_priv *priv, u32 addr,
+		 u32 bits, u32 mask, int timeout)
+{
+	int t = 0;
+
+	do {
+		if ((iwl_read32(priv, addr) & mask) == (bits & mask))
+			return t;
+		udelay(IWL_POLL_INTERVAL);
+		t += IWL_POLL_INTERVAL;
+	} while (t < timeout);
+
+	return -ETIMEDOUT;
+}
+
+int iwl_grab_nic_access_silent(struct iwl_priv *priv)
+{
+	int ret;
+
+	lockdep_assert_held(&priv->reg_lock);
+
+	/* this bit wakes up the NIC */
+	__iwl_set_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
+
+	/*
+	 * These bits say the device is running, and should keep running for
+	 * at least a short while (at least as long as MAC_ACCESS_REQ stays 1),
+	 * but they do not indicate that embedded SRAM is restored yet;
+	 * 3945 and 4965 have volatile SRAM, and must save/restore contents
+	 * to/from host DRAM when sleeping/waking for power-saving.
+	 * Each direction takes approximately 1/4 millisecond; with this
+	 * overhead, it's a good idea to grab and hold MAC_ACCESS_REQUEST if a
+	 * series of register accesses are expected (e.g. reading Event Log),
+	 * to keep device from sleeping.
+	 *
+	 * CSR_UCODE_DRV_GP1 register bit MAC_SLEEP == 0 indicates that
+	 * SRAM is okay/restored.  We don't check that here because this call
+	 * is just for hardware register access; but GP1 MAC_SLEEP check is a
+	 * good idea before accessing 3945/4965 SRAM (e.g. reading Event Log).
+	 *
+	 * 5000 series and later (including 1000 series) have non-volatile SRAM,
+	 * and do not save/restore SRAM when power cycling.
+	 */
+	ret = iwl_poll_bit(priv, CSR_GP_CNTRL,
+			   CSR_GP_CNTRL_REG_VAL_MAC_ACCESS_EN,
+			   (CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY |
+			    CSR_GP_CNTRL_REG_FLAG_GOING_TO_SLEEP), 15000);
+	if (ret < 0) {
+		iwl_write32(priv, CSR_RESET, CSR_RESET_REG_FLAG_FORCE_NMI);
+		return -EIO;
+	}
+
+	return 0;
+}
+
+int iwl_grab_nic_access(struct iwl_priv *priv)
+{
+	int ret = iwl_grab_nic_access_silent(priv);
+	if (ret) {
+		u32 val = iwl_read32(priv, CSR_GP_CNTRL);
+		IWL_ERR(priv,
+			"MAC is in deep sleep!. CSR_GP_CNTRL = 0x%08X\n", val);
+	}
+
+	return ret;
+}
+
+void iwl_release_nic_access(struct iwl_priv *priv)
+{
+	lockdep_assert_held(&priv->reg_lock);
+	__iwl_clear_bit(priv, CSR_GP_CNTRL,
+			CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
+}
+
+u32 iwl_read_direct32(struct iwl_priv *priv, u32 reg)
+{
+	u32 value;
+	unsigned long flags;
+
+	spin_lock_irqsave(&priv->reg_lock, flags);
+	iwl_grab_nic_access(priv);
+	value = iwl_read32(priv, reg);
+	iwl_release_nic_access(priv);
+	spin_unlock_irqrestore(&priv->reg_lock, flags);
+
+	return value;
+}
+
+void iwl_write_direct32(struct iwl_priv *priv, u32 reg, u32 value)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&priv->reg_lock, flags);
+	if (!iwl_grab_nic_access(priv)) {
+		iwl_write32(priv, reg, value);
+		iwl_release_nic_access(priv);
+	}
+	spin_unlock_irqrestore(&priv->reg_lock, flags);
+}
+
+int iwl_poll_direct_bit(struct iwl_priv *priv, u32 addr, u32 mask,
+			int timeout)
+{
+	int t = 0;
+
+	do {
+		if ((iwl_read_direct32(priv, addr) & mask) == mask)
+			return t;
+		udelay(IWL_POLL_INTERVAL);
+		t += IWL_POLL_INTERVAL;
+	} while (t < timeout);
+
+	return -ETIMEDOUT;
+}
+
+static inline u32 __iwl_read_prph(struct iwl_priv *priv, u32 reg)
+{
+	iwl_write32(priv, HBUS_TARG_PRPH_RADDR, reg | (3 << 24));
+	rmb();
+	return iwl_read32(priv, HBUS_TARG_PRPH_RDAT);
+}
+
+static inline void __iwl_write_prph(struct iwl_priv *priv, u32 addr, u32 val)
+{
+	iwl_write32(priv, HBUS_TARG_PRPH_WADDR,
+		    ((addr & 0x0000FFFF) | (3 << 24)));
+	wmb();
+	iwl_write32(priv, HBUS_TARG_PRPH_WDAT, val);
+}
+
+u32 iwl_read_prph(struct iwl_priv *priv, u32 reg)
+{
+	unsigned long flags;
+	u32 val;
+
+	spin_lock_irqsave(&priv->reg_lock, flags);
+	iwl_grab_nic_access(priv);
+	val = __iwl_read_prph(priv, reg);
+	iwl_release_nic_access(priv);
+	spin_unlock_irqrestore(&priv->reg_lock, flags);
+	return val;
+}
+
+void iwl_write_prph(struct iwl_priv *priv, u32 addr, u32 val)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&priv->reg_lock, flags);
+	if (!iwl_grab_nic_access(priv)) {
+		__iwl_write_prph(priv, addr, val);
+		iwl_release_nic_access(priv);
+	}
+	spin_unlock_irqrestore(&priv->reg_lock, flags);
+}
+
+void iwl_set_bits_prph(struct iwl_priv *priv, u32 reg, u32 mask)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&priv->reg_lock, flags);
+	iwl_grab_nic_access(priv);
+	__iwl_write_prph(priv, reg, __iwl_read_prph(priv, reg) | mask);
+	iwl_release_nic_access(priv);
+	spin_unlock_irqrestore(&priv->reg_lock, flags);
+}
+
+void iwl_set_bits_mask_prph(struct iwl_priv *priv, u32 reg,
+			    u32 bits, u32 mask)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&priv->reg_lock, flags);
+	iwl_grab_nic_access(priv);
+	__iwl_write_prph(priv, reg,
+			 (__iwl_read_prph(priv, reg) & mask) | bits);
+	iwl_release_nic_access(priv);
+	spin_unlock_irqrestore(&priv->reg_lock, flags);
+}
+
+void iwl_clear_bits_prph(struct iwl_priv *priv, u32 reg, u32 mask)
+{
+	unsigned long flags;
+	u32 val;
+
+	spin_lock_irqsave(&priv->reg_lock, flags);
+	iwl_grab_nic_access(priv);
+	val = __iwl_read_prph(priv, reg);
+	__iwl_write_prph(priv, reg, (val & ~mask));
+	iwl_release_nic_access(priv);
+	spin_unlock_irqrestore(&priv->reg_lock, flags);
+}
+
+void _iwl_read_targ_mem_words(struct iwl_priv *priv, u32 addr,
+			      void *buf, int words)
+{
+	unsigned long flags;
+	int offs;
+	u32 *vals = buf;
+
+	spin_lock_irqsave(&priv->reg_lock, flags);
+	iwl_grab_nic_access(priv);
+
+	iwl_write32(priv, HBUS_TARG_MEM_RADDR, addr);
+	rmb();
+
+	for (offs = 0; offs < words; offs++)
+		vals[offs] = iwl_read32(priv, HBUS_TARG_MEM_RDAT);
+
+	iwl_release_nic_access(priv);
+	spin_unlock_irqrestore(&priv->reg_lock, flags);
+}
+
+u32 iwl_read_targ_mem(struct iwl_priv *priv, u32 addr)
+{
+	u32 value;
+
+	_iwl_read_targ_mem_words(priv, addr, &value, 1);
+
+	return value;
+}
+
+void iwl_write_targ_mem(struct iwl_priv *priv, u32 addr, u32 val)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&priv->reg_lock, flags);
+	if (!iwl_grab_nic_access(priv)) {
+		iwl_write32(priv, HBUS_TARG_MEM_WADDR, addr);
+		wmb();
+		iwl_write32(priv, HBUS_TARG_MEM_WDAT, val);
+		iwl_release_nic_access(priv);
+	}
+	spin_unlock_irqrestore(&priv->reg_lock, flags);
+}
diff -druN linux-2.6.39-libre/drivers/net/wireless/iwlwifi/iwl-io.h linux-3.0-rc7-libre/drivers/net/wireless/iwlwifi/iwl-io.h
--- linux-2.6.39-libre/drivers/net/wireless/iwlwifi/iwl-io.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/iwlwifi/iwl-io.h	2011-07-11 19:51:52.000000000 -0400
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2003 - 2011 Intel Corporation. All rights reserved.
  *
  * Portions of this file are derived from the ipw3945 project.
  *
@@ -35,494 +35,58 @@
 #include "iwl-debug.h"
 #include "iwl-devtrace.h"
 
-/*
- * IO, register, and NIC memory access functions
- *
- * NOTE on naming convention and macro usage for these
- *
- * A single _ prefix before a an access function means that no state
- * check or debug information is printed when that function is called.
- *
- * A double __ prefix before an access function means that state is checked
- * and the current line number and caller function name are printed in addition
- * to any other debug output.
- *
- * The non-prefixed name is the #define that maps the caller into a
- * #define that provides the caller's name and __LINE__ to the double
- * prefix version.
- *
- * If you wish to call the function without any debug or state checking,
- * you should use the single _ prefix version (as is used by dependent IO
- * routines, for example _iwl_read_direct32 calls the non-check version of
- * _iwl_read32.)
- *
- * These declarations are *extremely* useful in quickly isolating code deltas
- * which result in misconfiguration of the hardware I/O.  In combination with
- * git-bisect and the IO debug level you can quickly determine the specific
- * commit which breaks the IO sequence to the hardware.
- *
- */
-
-static inline void _iwl_write8(struct iwl_priv *priv, u32 ofs, u8 val)
+static inline void iwl_write8(struct iwl_priv *priv, u32 ofs, u8 val)
 {
 	trace_iwlwifi_dev_iowrite8(priv, ofs, val);
 	iowrite8(val, priv->hw_base + ofs);
 }
 
-#ifdef CONFIG_IWLWIFI_DEBUG
-static inline void __iwl_write8(const char *f, u32 l, struct iwl_priv *priv,
-				 u32 ofs, u8 val)
-{
-	IWL_DEBUG_IO(priv, "write8(0x%08X, 0x%02X) - %s %d\n", ofs, val, f, l);
-	_iwl_write8(priv, ofs, val);
-}
-#define iwl_write8(priv, ofs, val) \
-	__iwl_write8(__FILE__, __LINE__, priv, ofs, val)
-#else
-#define iwl_write8(priv, ofs, val) _iwl_write8(priv, ofs, val)
-#endif
-
-
-static inline void _iwl_write32(struct iwl_priv *priv, u32 ofs, u32 val)
+static inline void iwl_write32(struct iwl_priv *priv, u32 ofs, u32 val)
 {
 	trace_iwlwifi_dev_iowrite32(priv, ofs, val);
 	iowrite32(val, priv->hw_base + ofs);
 }
 
-#ifdef CONFIG_IWLWIFI_DEBUG
-static inline void __iwl_write32(const char *f, u32 l, struct iwl_priv *priv,
-				 u32 ofs, u32 val)
-{
-	IWL_DEBUG_IO(priv, "write32(0x%08X, 0x%08X) - %s %d\n", ofs, val, f, l);
-	_iwl_write32(priv, ofs, val);
-}
-#define iwl_write32(priv, ofs, val) \
-	__iwl_write32(__FILE__, __LINE__, priv, ofs, val)
-#else
-#define iwl_write32(priv, ofs, val) _iwl_write32(priv, ofs, val)
-#endif
-
-static inline u32 _iwl_read32(struct iwl_priv *priv, u32 ofs)
+static inline u32 iwl_read32(struct iwl_priv *priv, u32 ofs)
 {
 	u32 val = ioread32(priv->hw_base + ofs);
 	trace_iwlwifi_dev_ioread32(priv, ofs, val);
 	return val;
 }
 
-#ifdef CONFIG_IWLWIFI_DEBUG
-static inline u32 __iwl_read32(char *f, u32 l, struct iwl_priv *priv, u32 ofs)
-{
-	IWL_DEBUG_IO(priv, "read_direct32(0x%08X) - %s %d\n", ofs, f, l);
-	return _iwl_read32(priv, ofs);
-}
-#define iwl_read32(priv, ofs) __iwl_read32(__FILE__, __LINE__, priv, ofs)
-#else
-#define iwl_read32(p, o) _iwl_read32(p, o)
-#endif
-
-#define IWL_POLL_INTERVAL 10	/* microseconds */
-static inline int _iwl_poll_bit(struct iwl_priv *priv, u32 addr,
-				u32 bits, u32 mask, int timeout)
-{
-	int t = 0;
-
-	do {
-		if ((_iwl_read32(priv, addr) & mask) == (bits & mask))
-			return t;
-		udelay(IWL_POLL_INTERVAL);
-		t += IWL_POLL_INTERVAL;
-	} while (t < timeout);
-
-	return -ETIMEDOUT;
-}
-#ifdef CONFIG_IWLWIFI_DEBUG
-static inline int __iwl_poll_bit(const char *f, u32 l,
-				 struct iwl_priv *priv, u32 addr,
-				 u32 bits, u32 mask, int timeout)
-{
-	int ret = _iwl_poll_bit(priv, addr, bits, mask, timeout);
-	IWL_DEBUG_IO(priv, "poll_bit(0x%08X, 0x%08X, 0x%08X) - %s- %s %d\n",
-		     addr, bits, mask,
-		     unlikely(ret  == -ETIMEDOUT) ? "timeout" : "", f, l);
-	return ret;
-}
-#define iwl_poll_bit(priv, addr, bits, mask, timeout) \
-	__iwl_poll_bit(__FILE__, __LINE__, priv, addr, bits, mask, timeout)
-#else
-#define iwl_poll_bit(p, a, b, m, t) _iwl_poll_bit(p, a, b, m, t)
-#endif
-
-static inline void _iwl_set_bit(struct iwl_priv *priv, u32 reg, u32 mask)
-{
-	_iwl_write32(priv, reg, _iwl_read32(priv, reg) | mask);
-}
-#ifdef CONFIG_IWLWIFI_DEBUG
-static inline void __iwl_set_bit(const char *f, u32 l,
-				 struct iwl_priv *priv, u32 reg, u32 mask)
-{
-	u32 val = _iwl_read32(priv, reg) | mask;
-	IWL_DEBUG_IO(priv, "set_bit(0x%08X, 0x%08X) = 0x%08X\n", reg, mask, val);
-	_iwl_write32(priv, reg, val);
-}
-static inline void iwl_set_bit(struct iwl_priv *p, u32 r, u32 m)
-{
-	unsigned long reg_flags;
-
-	spin_lock_irqsave(&p->reg_lock, reg_flags);
-	__iwl_set_bit(__FILE__, __LINE__, p, r, m);
-	spin_unlock_irqrestore(&p->reg_lock, reg_flags);
-}
-#else
-static inline void iwl_set_bit(struct iwl_priv *p, u32 r, u32 m)
-{
-	unsigned long reg_flags;
-
-	spin_lock_irqsave(&p->reg_lock, reg_flags);
-	_iwl_set_bit(p, r, m);
-	spin_unlock_irqrestore(&p->reg_lock, reg_flags);
-}
-#endif
-
-static inline void _iwl_clear_bit(struct iwl_priv *priv, u32 reg, u32 mask)
-{
-	_iwl_write32(priv, reg, _iwl_read32(priv, reg) & ~mask);
-}
-#ifdef CONFIG_IWLWIFI_DEBUG
-static inline void __iwl_clear_bit(const char *f, u32 l,
-				   struct iwl_priv *priv, u32 reg, u32 mask)
-{
-	u32 val = _iwl_read32(priv, reg) & ~mask;
-	IWL_DEBUG_IO(priv, "clear_bit(0x%08X, 0x%08X) = 0x%08X\n", reg, mask, val);
-	_iwl_write32(priv, reg, val);
-}
-static inline void iwl_clear_bit(struct iwl_priv *p, u32 r, u32 m)
-{
-	unsigned long reg_flags;
-
-	spin_lock_irqsave(&p->reg_lock, reg_flags);
-	__iwl_clear_bit(__FILE__, __LINE__, p, r, m);
-	spin_unlock_irqrestore(&p->reg_lock, reg_flags);
-}
-#else
-static inline void iwl_clear_bit(struct iwl_priv *p, u32 r, u32 m)
-{
-	unsigned long reg_flags;
-
-	spin_lock_irqsave(&p->reg_lock, reg_flags);
-	_iwl_clear_bit(p, r, m);
-	spin_unlock_irqrestore(&p->reg_lock, reg_flags);
-}
-#endif
-
-static inline int _iwl_grab_nic_access(struct iwl_priv *priv)
-{
-	int ret;
-	u32 val;
-
-	/* this bit wakes up the NIC */
-	_iwl_set_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
-
-	/*
-	 * These bits say the device is running, and should keep running for
-	 * at least a short while (at least as long as MAC_ACCESS_REQ stays 1),
-	 * but they do not indicate that embedded SRAM is restored yet;
-	 * 3945 and 4965 have volatile SRAM, and must save/restore contents
-	 * to/from host DRAM when sleeping/waking for power-saving.
-	 * Each direction takes approximately 1/4 millisecond; with this
-	 * overhead, it's a good idea to grab and hold MAC_ACCESS_REQUEST if a
-	 * series of register accesses are expected (e.g. reading Event Log),
-	 * to keep device from sleeping.
-	 *
-	 * CSR_UCODE_DRV_GP1 register bit MAC_SLEEP == 0 indicates that
-	 * SRAM is okay/restored.  We don't check that here because this call
-	 * is just for hardware register access; but GP1 MAC_SLEEP check is a
-	 * good idea before accessing 3945/4965 SRAM (e.g. reading Event Log).
-	 *
-	 * 5000 series and later (including 1000 series) have non-volatile SRAM,
-	 * and do not save/restore SRAM when power cycling.
-	 */
-	ret = _iwl_poll_bit(priv, CSR_GP_CNTRL,
-			   CSR_GP_CNTRL_REG_VAL_MAC_ACCESS_EN,
-			   (CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY |
-			    CSR_GP_CNTRL_REG_FLAG_GOING_TO_SLEEP), 15000);
-	if (ret < 0) {
-		val = _iwl_read32(priv, CSR_GP_CNTRL);
-		IWL_ERR(priv, "MAC is in deep sleep!.  CSR_GP_CNTRL = 0x%08X\n", val);
-		_iwl_write32(priv, CSR_RESET, CSR_RESET_REG_FLAG_FORCE_NMI);
-		return -EIO;
-	}
-
-	return 0;
-}
-
-#ifdef CONFIG_IWLWIFI_DEBUG
-static inline int __iwl_grab_nic_access(const char *f, u32 l,
-					       struct iwl_priv *priv)
-{
-	IWL_DEBUG_IO(priv, "grabbing nic access - %s %d\n", f, l);
-	return _iwl_grab_nic_access(priv);
-}
-#define iwl_grab_nic_access(priv) \
-	__iwl_grab_nic_access(__FILE__, __LINE__, priv)
-#else
-#define iwl_grab_nic_access(priv) \
-	_iwl_grab_nic_access(priv)
-#endif
-
-static inline void _iwl_release_nic_access(struct iwl_priv *priv)
-{
-	_iwl_clear_bit(priv, CSR_GP_CNTRL,
-			CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
-}
-#ifdef CONFIG_IWLWIFI_DEBUG
-static inline void __iwl_release_nic_access(const char *f, u32 l,
-					    struct iwl_priv *priv)
-{
-
-	IWL_DEBUG_IO(priv, "releasing nic access - %s %d\n", f, l);
-	_iwl_release_nic_access(priv);
-}
-#define iwl_release_nic_access(priv) \
-	__iwl_release_nic_access(__FILE__, __LINE__, priv)
-#else
-#define iwl_release_nic_access(priv) \
-	_iwl_release_nic_access(priv)
-#endif
-
-static inline u32 _iwl_read_direct32(struct iwl_priv *priv, u32 reg)
-{
-	return _iwl_read32(priv, reg);
-}
-#ifdef CONFIG_IWLWIFI_DEBUG
-static inline u32 __iwl_read_direct32(const char *f, u32 l,
-					struct iwl_priv *priv, u32 reg)
-{
-	u32 value = _iwl_read_direct32(priv, reg);
-	IWL_DEBUG_IO(priv, "read_direct32(0x%4X) = 0x%08x - %s %d\n", reg, value,
-		     f, l);
-	return value;
-}
-static inline u32 iwl_read_direct32(struct iwl_priv *priv, u32 reg)
-{
-	u32 value;
-	unsigned long reg_flags;
-
-	spin_lock_irqsave(&priv->reg_lock, reg_flags);
-	iwl_grab_nic_access(priv);
-	value = __iwl_read_direct32(__FILE__, __LINE__, priv, reg);
-	iwl_release_nic_access(priv);
-	spin_unlock_irqrestore(&priv->reg_lock, reg_flags);
-	return value;
-}
-
-#else
-static inline u32 iwl_read_direct32(struct iwl_priv *priv, u32 reg)
-{
-	u32 value;
-	unsigned long reg_flags;
-
-	spin_lock_irqsave(&priv->reg_lock, reg_flags);
-	iwl_grab_nic_access(priv);
-	value = _iwl_read_direct32(priv, reg);
-	iwl_release_nic_access(priv);
-	spin_unlock_irqrestore(&priv->reg_lock, reg_flags);
-	return value;
-
-}
-#endif
-
-static inline void _iwl_write_direct32(struct iwl_priv *priv,
-					 u32 reg, u32 value)
-{
-	_iwl_write32(priv, reg, value);
-}
-static inline void iwl_write_direct32(struct iwl_priv *priv, u32 reg, u32 value)
-{
-	unsigned long reg_flags;
-
-	spin_lock_irqsave(&priv->reg_lock, reg_flags);
-	if (!iwl_grab_nic_access(priv)) {
-		_iwl_write_direct32(priv, reg, value);
-		iwl_release_nic_access(priv);
-	}
-	spin_unlock_irqrestore(&priv->reg_lock, reg_flags);
-}
-
-static inline void iwl_write_reg_buf(struct iwl_priv *priv,
-					       u32 reg, u32 len, u32 *values)
-{
-	u32 count = sizeof(u32);
-
-	if ((priv != NULL) && (values != NULL)) {
-		for (; 0 < len; len -= count, reg += count, values++)
-			iwl_write_direct32(priv, reg, *values);
-	}
-}
-
-static inline int _iwl_poll_direct_bit(struct iwl_priv *priv, u32 addr,
-				       u32 mask, int timeout)
-{
-	int t = 0;
-
-	do {
-		if ((iwl_read_direct32(priv, addr) & mask) == mask)
-			return t;
-		udelay(IWL_POLL_INTERVAL);
-		t += IWL_POLL_INTERVAL;
-	} while (t < timeout);
-
-	return -ETIMEDOUT;
-}
-
-#ifdef CONFIG_IWLWIFI_DEBUG
-static inline int __iwl_poll_direct_bit(const char *f, u32 l,
-					    struct iwl_priv *priv,
-					    u32 addr, u32 mask, int timeout)
-{
-	int ret  = _iwl_poll_direct_bit(priv, addr, mask, timeout);
-
-	if (unlikely(ret == -ETIMEDOUT))
-		IWL_DEBUG_IO(priv, "poll_direct_bit(0x%08X, 0x%08X) - "
-			     "timedout - %s %d\n", addr, mask, f, l);
-	else
-		IWL_DEBUG_IO(priv, "poll_direct_bit(0x%08X, 0x%08X) = 0x%08X "
-			     "- %s %d\n", addr, mask, ret, f, l);
-	return ret;
-}
-#define iwl_poll_direct_bit(priv, addr, mask, timeout) \
-	__iwl_poll_direct_bit(__FILE__, __LINE__, priv, addr, mask, timeout)
-#else
-#define iwl_poll_direct_bit _iwl_poll_direct_bit
-#endif
-
-static inline u32 _iwl_read_prph(struct iwl_priv *priv, u32 reg)
-{
-	_iwl_write_direct32(priv, HBUS_TARG_PRPH_RADDR, reg | (3 << 24));
-	rmb();
-	return _iwl_read_direct32(priv, HBUS_TARG_PRPH_RDAT);
-}
-static inline u32 iwl_read_prph(struct iwl_priv *priv, u32 reg)
-{
-	unsigned long reg_flags;
-	u32 val;
-
-	spin_lock_irqsave(&priv->reg_lock, reg_flags);
-	iwl_grab_nic_access(priv);
-	val = _iwl_read_prph(priv, reg);
-	iwl_release_nic_access(priv);
-	spin_unlock_irqrestore(&priv->reg_lock, reg_flags);
-	return val;
-}
-
-static inline void _iwl_write_prph(struct iwl_priv *priv,
-					     u32 addr, u32 val)
-{
-	_iwl_write_direct32(priv, HBUS_TARG_PRPH_WADDR,
-			      ((addr & 0x0000FFFF) | (3 << 24)));
-	wmb();
-	_iwl_write_direct32(priv, HBUS_TARG_PRPH_WDAT, val);
-}
-
-static inline void iwl_write_prph(struct iwl_priv *priv, u32 addr, u32 val)
-{
-	unsigned long reg_flags;
-
-	spin_lock_irqsave(&priv->reg_lock, reg_flags);
-	if (!iwl_grab_nic_access(priv)) {
-		_iwl_write_prph(priv, addr, val);
-		iwl_release_nic_access(priv);
-	}
-	spin_unlock_irqrestore(&priv->reg_lock, reg_flags);
-}
-
-#define _iwl_set_bits_prph(priv, reg, mask) \
-	_iwl_write_prph(priv, reg, (_iwl_read_prph(priv, reg) | mask))
-
-static inline void iwl_set_bits_prph(struct iwl_priv *priv, u32 reg, u32 mask)
-{
-	unsigned long reg_flags;
-
-	spin_lock_irqsave(&priv->reg_lock, reg_flags);
-	iwl_grab_nic_access(priv);
-	_iwl_set_bits_prph(priv, reg, mask);
-	iwl_release_nic_access(priv);
-	spin_unlock_irqrestore(&priv->reg_lock, reg_flags);
-}
-
-#define _iwl_set_bits_mask_prph(priv, reg, bits, mask) \
-	_iwl_write_prph(priv, reg, ((_iwl_read_prph(priv, reg) & mask) | bits))
-
-static inline void iwl_set_bits_mask_prph(struct iwl_priv *priv, u32 reg,
-				u32 bits, u32 mask)
-{
-	unsigned long reg_flags;
-
-	spin_lock_irqsave(&priv->reg_lock, reg_flags);
-	iwl_grab_nic_access(priv);
-	_iwl_set_bits_mask_prph(priv, reg, bits, mask);
-	iwl_release_nic_access(priv);
-	spin_unlock_irqrestore(&priv->reg_lock, reg_flags);
-}
-
-static inline void iwl_clear_bits_prph(struct iwl_priv
-						 *priv, u32 reg, u32 mask)
-{
-	unsigned long reg_flags;
-	u32 val;
-
-	spin_lock_irqsave(&priv->reg_lock, reg_flags);
-	iwl_grab_nic_access(priv);
-	val = _iwl_read_prph(priv, reg);
-	_iwl_write_prph(priv, reg, (val & ~mask));
-	iwl_release_nic_access(priv);
-	spin_unlock_irqrestore(&priv->reg_lock, reg_flags);
-}
-
-static inline u32 iwl_read_targ_mem(struct iwl_priv *priv, u32 addr)
-{
-	unsigned long reg_flags;
-	u32 value;
+void iwl_set_bit(struct iwl_priv *priv, u32 reg, u32 mask);
+void iwl_clear_bit(struct iwl_priv *priv, u32 reg, u32 mask);
 
-	spin_lock_irqsave(&priv->reg_lock, reg_flags);
-	iwl_grab_nic_access(priv);
+int iwl_poll_bit(struct iwl_priv *priv, u32 addr,
+		 u32 bits, u32 mask, int timeout);
+int iwl_poll_direct_bit(struct iwl_priv *priv, u32 addr, u32 mask,
+			int timeout);
 
-	_iwl_write_direct32(priv, HBUS_TARG_MEM_RADDR, addr);
-	rmb();
-	value = _iwl_read_direct32(priv, HBUS_TARG_MEM_RDAT);
+int iwl_grab_nic_access_silent(struct iwl_priv *priv);
+int iwl_grab_nic_access(struct iwl_priv *priv);
+void iwl_release_nic_access(struct iwl_priv *priv);
 
-	iwl_release_nic_access(priv);
-	spin_unlock_irqrestore(&priv->reg_lock, reg_flags);
-	return value;
-}
+u32 iwl_read_direct32(struct iwl_priv *priv, u32 reg);
+void iwl_write_direct32(struct iwl_priv *priv, u32 reg, u32 value);
 
-static inline void iwl_write_targ_mem(struct iwl_priv *priv, u32 addr, u32 val)
-{
-	unsigned long reg_flags;
 
-	spin_lock_irqsave(&priv->reg_lock, reg_flags);
-	if (!iwl_grab_nic_access(priv)) {
-		_iwl_write_direct32(priv, HBUS_TARG_MEM_WADDR, addr);
-		wmb();
-		_iwl_write_direct32(priv, HBUS_TARG_MEM_WDAT, val);
-		iwl_release_nic_access(priv);
-	}
-	spin_unlock_irqrestore(&priv->reg_lock, reg_flags);
-}
+u32 iwl_read_prph(struct iwl_priv *priv, u32 reg);
+void iwl_write_prph(struct iwl_priv *priv, u32 addr, u32 val);
+void iwl_set_bits_prph(struct iwl_priv *priv, u32 reg, u32 mask);
+void iwl_set_bits_mask_prph(struct iwl_priv *priv, u32 reg,
+			    u32 bits, u32 mask);
+void iwl_clear_bits_prph(struct iwl_priv *priv, u32 reg, u32 mask);
 
-static inline void iwl_write_targ_mem_buf(struct iwl_priv *priv, u32 addr,
-					  u32 len, u32 *values)
-{
-	unsigned long reg_flags;
+void _iwl_read_targ_mem_words(struct iwl_priv *priv, u32 addr,
+			      void *buf, int words);
 
-	spin_lock_irqsave(&priv->reg_lock, reg_flags);
-	if (!iwl_grab_nic_access(priv)) {
-		_iwl_write_direct32(priv, HBUS_TARG_MEM_WADDR, addr);
-		wmb();
-		for (; 0 < len; len -= sizeof(u32), values++)
-			_iwl_write_direct32(priv, HBUS_TARG_MEM_WDAT, *values);
+#define iwl_read_targ_mem_words(priv, addr, buf, bufsize)	\
+	do {							\
+		BUILD_BUG_ON((bufsize) % sizeof(u32));		\
+		_iwl_read_targ_mem_words(priv, addr, buf,	\
+					 (bufsize) / sizeof(u32));\
+	} while (0)
 
-		iwl_release_nic_access(priv);
-	}
-	spin_unlock_irqrestore(&priv->reg_lock, reg_flags);
-}
+u32 iwl_read_targ_mem(struct iwl_priv *priv, u32 addr);
+void iwl_write_targ_mem(struct iwl_priv *priv, u32 addr, u32 val);
 #endif
diff -druN linux-2.6.39-libre/drivers/net/wireless/iwlwifi/iwl-led.c linux-3.0-rc7-libre/drivers/net/wireless/iwlwifi/iwl-led.c
--- linux-2.6.39-libre/drivers/net/wireless/iwlwifi/iwl-led.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/iwlwifi/iwl-led.c	2011-07-11 19:51:52.000000000 -0400
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2003 - 2011 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
@@ -48,8 +48,21 @@
 MODULE_PARM_DESC(led_mode, "0=system default, "
 		"1=On(RF On)/Off(RF Off), 2=blinking");
 
+/* Throughput		OFF time(ms)	ON time (ms)
+ *	>300			25		25
+ *	>200 to 300		40		40
+ *	>100 to 200		55		55
+ *	>70 to 100		65		65
+ *	>50 to 70		75		75
+ *	>20 to 50		85		85
+ *	>10 to 20		95		95
+ *	>5 to 10		110		110
+ *	>1 to 5			130		130
+ *	>0 to 1			167		167
+ *	<=0					SOLID ON
+ */
 static const struct ieee80211_tpt_blink iwl_blink[] = {
-	{ .throughput = 0 * 1024 - 1, .blink_time = 334 },
+	{ .throughput = 0, .blink_time = 334 },
 	{ .throughput = 1 * 1024 - 1, .blink_time = 260 },
 	{ .throughput = 5 * 1024 - 1, .blink_time = 220 },
 	{ .throughput = 10 * 1024 - 1, .blink_time = 190 },
@@ -61,10 +74,16 @@
 	{ .throughput = 300 * 1024 - 1, .blink_time = 50 },
 };
 
+/* Set led register off */
+void iwlagn_led_enable(struct iwl_priv *priv)
+{
+	iwl_write32(priv, CSR_LED_REG, CSR_LED_REG_TRUN_ON);
+}
+
 /*
  * Adjust led blink rate to compensate on a MAC Clock difference on every HW
- * Led blink rate analysis showed an average deviation of 0% on 3945,
- * 5% on 4965 HW and 20% on 5000 series and up.
+ * Led blink rate analysis showed an average deviation of 20% on 5000 series
+ * and up.
  * Need to compensate on the led on/off time per HW according to the deviation
  * to achieve the desired led frequency
  * The calculation is: (100-averageDeviation)/100 * blinkTime
@@ -84,6 +103,24 @@
 	return (u8)((time * compensation) >> 6);
 }
 
+static int iwl_send_led_cmd(struct iwl_priv *priv, struct iwl_led_cmd *led_cmd)
+{
+	struct iwl_host_cmd cmd = {
+		.id = REPLY_LEDS_CMD,
+		.len = { sizeof(struct iwl_led_cmd), },
+		.data = { led_cmd, },
+		.flags = CMD_ASYNC,
+		.callback = NULL,
+	};
+	u32 reg;
+
+	reg = iwl_read32(priv, CSR_LED_REG);
+	if (reg != (reg & CSR_LED_BSM_CTRL_MSK))
+		iwl_write32(priv, CSR_LED_REG, reg & CSR_LED_BSM_CTRL_MSK);
+
+	return iwl_send_cmd(priv, &cmd);
+}
+
 /* Set led pattern command */
 static int iwl_led_cmd(struct iwl_priv *priv,
 		       unsigned long on,
@@ -101,6 +138,11 @@
 	if (priv->blink_on == on && priv->blink_off == off)
 		return 0;
 
+	if (off == 0) {
+		/* led is SOLID_ON */
+		on = IWL_LED_SOLID;
+	}
+
 	IWL_DEBUG_LED(priv, "Led blink time compensation=%u\n",
 			priv->cfg->base_params->led_compensation);
 	led_cmd.on = iwl_blink_compensation(priv, on,
@@ -108,7 +150,7 @@
 	led_cmd.off = iwl_blink_compensation(priv, off,
 				priv->cfg->base_params->led_compensation);
 
-	ret = priv->cfg->ops->led->cmd(priv, &led_cmd);
+	ret = iwl_send_led_cmd(priv, &led_cmd);
 	if (!ret) {
 		priv->blink_on = on;
 		priv->blink_off = off;
diff -druN linux-2.6.39-libre/drivers/net/wireless/iwlwifi/iwl-led.h linux-3.0-rc7-libre/drivers/net/wireless/iwlwifi/iwl-led.h
--- linux-2.6.39-libre/drivers/net/wireless/iwlwifi/iwl-led.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/iwlwifi/iwl-led.h	2011-07-11 19:51:52.000000000 -0400
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2003 - 2011 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
@@ -50,6 +50,7 @@
 	IWL_LED_BLINK,
 };
 
+void iwlagn_led_enable(struct iwl_priv *priv);
 void iwl_leds_init(struct iwl_priv *priv);
 void iwl_leds_exit(struct iwl_priv *priv);
 
diff -druN linux-2.6.39-libre/drivers/net/wireless/iwlwifi/iwl-power.c linux-3.0-rc7-libre/drivers/net/wireless/iwlwifi/iwl-power.c
--- linux-2.6.39-libre/drivers/net/wireless/iwlwifi/iwl-power.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/iwlwifi/iwl-power.c	2011-07-11 19:51:52.000000000 -0400
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2007 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2007 - 2011 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.
@@ -188,9 +188,10 @@
 			table = range_0;
 	}
 
-	BUG_ON(lvl < 0 || lvl >= IWL_POWER_NUM);
-
-	*cmd = table[lvl].cmd;
+	if (WARN_ON(lvl < 0 || lvl >= IWL_POWER_NUM))
+		memset(cmd, 0, sizeof(*cmd));
+	else
+		*cmd = table[lvl].cmd;
 
 	if (period == 0) {
 		skip = 0;
@@ -354,16 +355,12 @@
 
 	dtimper = priv->hw->conf.ps_dtim_period ?: 1;
 
-	if (priv->cfg->base_params->broken_powersave)
-		iwl_power_sleep_cam_cmd(priv, cmd);
-	else if (priv->hw->conf.flags & IEEE80211_CONF_IDLE)
+	if (priv->hw->conf.flags & IEEE80211_CONF_IDLE)
 		iwl_static_sleep_cmd(priv, cmd, IWL_POWER_INDEX_5, 20);
-	else if (priv->cfg->ops->lib->tt_ops.lower_power_detection &&
-		 priv->cfg->ops->lib->tt_ops.tt_power_mode &&
-		 priv->cfg->ops->lib->tt_ops.lower_power_detection(priv)) {
+	else if (iwl_tt_is_low_power_state(priv)) {
 		/* in thermal throttling low power state */
 		iwl_static_sleep_cmd(priv, cmd,
-		    priv->cfg->ops->lib->tt_ops.tt_power_mode(priv), dtimper);
+		    iwl_tt_current_power_mode(priv), dtimper);
 	} else if (!enabled)
 		iwl_power_sleep_cam_cmd(priv, cmd);
 	else if (priv->power_data.debug_sleep_level_override >= 0)
diff -druN linux-2.6.39-libre/drivers/net/wireless/iwlwifi/iwl-power.h linux-3.0-rc7-libre/drivers/net/wireless/iwlwifi/iwl-power.h
--- linux-2.6.39-libre/drivers/net/wireless/iwlwifi/iwl-power.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/iwlwifi/iwl-power.h	2011-07-11 19:51:52.000000000 -0400
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2007 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2007 - 2011 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 -druN linux-2.6.39-libre/drivers/net/wireless/iwlwifi/iwl-prph.h linux-3.0-rc7-libre/drivers/net/wireless/iwlwifi/iwl-prph.h
--- linux-2.6.39-libre/drivers/net/wireless/iwlwifi/iwl-prph.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/iwlwifi/iwl-prph.h	2011-07-11 19:51:52.000000000 -0400
@@ -5,7 +5,7 @@
  *
  * GPL LICENSE SUMMARY
  *
- * Copyright(c) 2005 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2011 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 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -91,7 +91,6 @@
 #define APMG_PS_CTRL_VAL_RESET_REQ		(0x04000000)
 #define APMG_PS_CTRL_MSK_PWR_SRC		(0x03000000)
 #define APMG_PS_CTRL_VAL_PWR_SRC_VMAIN		(0x00000000)
-#define APMG_PS_CTRL_VAL_PWR_SRC_MAX		(0x01000000) /* 3945 only */
 #define APMG_PS_CTRL_VAL_PWR_SRC_VAUX		(0x02000000)
 #define APMG_SVR_VOLTAGE_CONFIG_BIT_MSK	(0x000001E0) /* bit 8:5 */
 #define APMG_SVR_DIGITAL_VOLTAGE_1_32		(0x00000060)
@@ -99,152 +98,6 @@
 #define APMG_PCIDEV_STT_VAL_L1_ACT_DIS		(0x00000800)
 
 /**
- * BSM (Bootstrap State Machine)
- *
- * The Bootstrap State Machine (BSM) stores a short bootstrap uCode program
- * in special SRAM that does not power down when the embedded control
- * processor is sleeping (e.g. for periodic power-saving shutdowns of radio).
- *
- * When powering back up after sleeps (or during initial uCode load), the BSM
- * internally loads the short bootstrap program from the special SRAM into the
- * embedded processor's instruction SRAM, and starts the processor so it runs
- * the bootstrap program.
- *
- * This bootstrap program loads (via PCI busmaster DMA) instructions and data
- * images for a uCode program from host DRAM locations.  The host driver
- * indicates DRAM locations and sizes for instruction and data images via the
- * four BSM_DRAM_* registers.  Once the bootstrap program loads the new program,
- * the new program starts automatically.
- *
- * The uCode used for open-source drivers includes two programs:
- *
- * 1)  Initialization -- performs hardware calibration and sets up some
- *     internal data, then notifies host via "initialize alive" notification
- *     (struct iwl_init_alive_resp) that it has completed all of its work.
- *     After signal from host, it then loads and starts the runtime program.
- *     The initialization program must be used when initially setting up the
- *     NIC after loading the driver.
- *
- * 2)  Runtime/Protocol -- performs all normal runtime operations.  This
- *     notifies host via "alive" notification (struct iwl_alive_resp) that it
- *     is ready to be used.
- *
- * When initializing the NIC, the host driver does the following procedure:
- *
- * 1)  Load bootstrap program (instructions only, no data image for bootstrap)
- *     into bootstrap memory.  Use dword writes starting at BSM_SRAM_LOWER_BOUND
- *
- * 2)  Point (via BSM_DRAM_*) to the "initialize" uCode data and instruction
- *     images in host DRAM.
- *
- * 3)  Set up BSM to copy from BSM SRAM into uCode instruction SRAM when asked:
- *     BSM_WR_MEM_SRC_REG = 0
- *     BSM_WR_MEM_DST_REG = RTC_INST_LOWER_BOUND
- *     BSM_WR_MEM_DWCOUNT_REG = # dwords in bootstrap instruction image
- *
- * 4)  Load bootstrap into instruction SRAM:
- *     BSM_WR_CTRL_REG = BSM_WR_CTRL_REG_BIT_START
- *
- * 5)  Wait for load completion:
- *     Poll BSM_WR_CTRL_REG for BSM_WR_CTRL_REG_BIT_START = 0
- *
- * 6)  Enable future boot loads whenever NIC's power management triggers it:
- *     BSM_WR_CTRL_REG = BSM_WR_CTRL_REG_BIT_START_EN
- *
- * 7)  Start the NIC by removing all reset bits:
- *     CSR_RESET = 0
- *
- *     The bootstrap uCode (already in instruction SRAM) loads initialization
- *     uCode.  Initialization uCode performs data initialization, sends
- *     "initialize alive" notification to host, and waits for a signal from
- *     host to load runtime code.
- *
- * 4)  Point (via BSM_DRAM_*) to the "runtime" uCode data and instruction
- *     images in host DRAM.  The last register loaded must be the instruction
- *     byte count register ("1" in MSbit tells initialization uCode to load
- *     the runtime uCode):
- *     BSM_DRAM_INST_BYTECOUNT_REG = byte count | BSM_DRAM_INST_LOAD
- *
- * 5)  Wait for "alive" notification, then issue normal runtime commands.
- *
- * Data caching during power-downs:
- *
- * Just before the embedded controller powers down (e.g for automatic
- * power-saving modes, or for RFKILL), uCode stores (via PCI busmaster DMA)
- * a current snapshot of the embedded processor's data SRAM into host DRAM.
- * This caches the data while the embedded processor's memory is powered down.
- * Location and size are controlled by BSM_DRAM_DATA_* registers.
- *
- * NOTE:  Instruction SRAM does not need to be saved, since that doesn't
- *        change during operation; the original image (from uCode distribution
- *        file) can be used for reload.
- *
- * When powering back up, the BSM loads the bootstrap program.  Bootstrap looks
- * at the BSM_DRAM_* registers, which now point to the runtime instruction
- * image and the cached (modified) runtime data (*not* the initialization
- * uCode).  Bootstrap reloads these runtime images into SRAM, and restarts the
- * uCode from where it left off before the power-down.
- *
- * NOTE:  Initialization uCode does *not* run as part of the save/restore
- *        procedure.
- *
- * This save/restore method is mostly for autonomous power management during
- * normal operation (result of POWER_TABLE_CMD).  Platform suspend/resume and
- * RFKILL should use complete restarts (with total re-initialization) of uCode,
- * allowing total shutdown (including BSM memory).
- *
- * Note that, during normal operation, the host DRAM that held the initial
- * startup data for the runtime code is now being used as a backup data cache
- * for modified data!  If you need to completely re-initialize the NIC, make
- * sure that you use the runtime data image from the uCode distribution file,
- * not the modified/saved runtime data.  You may want to store a separate
- * "clean" runtime data image in DRAM to avoid disk reads of distribution file.
- */
-
-/* BSM bit fields */
-#define BSM_WR_CTRL_REG_BIT_START     (0x80000000) /* start boot load now */
-#define BSM_WR_CTRL_REG_BIT_START_EN  (0x40000000) /* enable boot after pwrup*/
-#define BSM_DRAM_INST_LOAD            (0x80000000) /* start program load now */
-
-/* BSM addresses */
-#define BSM_BASE                     (PRPH_BASE + 0x3400)
-#define BSM_END                      (PRPH_BASE + 0x3800)
-
-#define BSM_WR_CTRL_REG              (BSM_BASE + 0x000) /* ctl and status */
-#define BSM_WR_MEM_SRC_REG           (BSM_BASE + 0x004) /* source in BSM mem */
-#define BSM_WR_MEM_DST_REG           (BSM_BASE + 0x008) /* dest in SRAM mem */
-#define BSM_WR_DWCOUNT_REG           (BSM_BASE + 0x00C) /* bytes */
-#define BSM_WR_STATUS_REG            (BSM_BASE + 0x010) /* bit 0:  1 == done */
-
-/*
- * Pointers and size regs for bootstrap load and data SRAM save/restore.
- * NOTE:  3945 pointers use bits 31:0 of DRAM address.
- *        4965 pointers use bits 35:4 of DRAM address.
- */
-#define BSM_DRAM_INST_PTR_REG        (BSM_BASE + 0x090)
-#define BSM_DRAM_INST_BYTECOUNT_REG  (BSM_BASE + 0x094)
-#define BSM_DRAM_DATA_PTR_REG        (BSM_BASE + 0x098)
-#define BSM_DRAM_DATA_BYTECOUNT_REG  (BSM_BASE + 0x09C)
-
-/*
- * BSM special memory, stays powered on during power-save sleeps.
- * Read/write, address range from LOWER_BOUND to (LOWER_BOUND + SIZE -1)
- */
-#define BSM_SRAM_LOWER_BOUND         (PRPH_BASE + 0x3800)
-#define BSM_SRAM_SIZE			(1024) /* bytes */
-
-
-/* 3945 Tx scheduler registers */
-#define ALM_SCD_BASE                        (PRPH_BASE + 0x2E00)
-#define ALM_SCD_MODE_REG                    (ALM_SCD_BASE + 0x000)
-#define ALM_SCD_ARASTAT_REG                 (ALM_SCD_BASE + 0x004)
-#define ALM_SCD_TXFACT_REG                  (ALM_SCD_BASE + 0x010)
-#define ALM_SCD_TXF4MF_REG                  (ALM_SCD_BASE + 0x014)
-#define ALM_SCD_TXF5MF_REG                  (ALM_SCD_BASE + 0x020)
-#define ALM_SCD_SBYP_MODE_1_REG             (ALM_SCD_BASE + 0x02C)
-#define ALM_SCD_SBYP_MODE_2_REG             (ALM_SCD_BASE + 0x030)
-
-/**
  * Tx Scheduler
  *
  * The Tx Scheduler selects the next frame to be transmitted, choosing TFDs
@@ -254,17 +107,7 @@
  * device.  A queue maps to only one (selectable by driver) Tx DMA channel,
  * but one DMA channel may take input from several queues.
  *
- * Tx DMA FIFOs have dedicated purposes.  For 4965, they are used as follows
- * (cf. default_queue_to_tx_fifo in iwl-4965.c):
- *
- * 0 -- EDCA BK (background) frames, lowest priority
- * 1 -- EDCA BE (best effort) frames, normal priority
- * 2 -- EDCA VI (video) frames, higher priority
- * 3 -- EDCA VO (voice) and management frames, highest priority
- * 4 -- Commands (e.g. RXON, etc.)
- * 5 -- unused (HCCA)
- * 6 -- unused (HCCA)
- * 7 -- not used by driver (device-internal only)
+ * Tx DMA FIFOs have dedicated purposes.
  *
  * For 5000 series and up, they are used differently
  * (cf. iwl5000_default_queue_to_tx_fifo in iwl-5000.c):
@@ -298,7 +141,7 @@
  *     Tx completion may end up being out-of-order).
  *
  *     The driver must maintain the queue's Byte Count table in host DRAM
- *     (struct iwl4965_sched_queue_byte_cnt_tbl) for this mode.
+ *     for this mode.
  *     This mode does not support fragmentation.
  *
  * 2)  FIFO (a.k.a. non-Scheduler-ACK), in which each TFD is processed in order.
@@ -311,7 +154,7 @@
  *
  * Driver controls scheduler operation via 3 means:
  * 1)  Scheduler registers
- * 2)  Shared scheduler data base in internal 4956 SRAM
+ * 2)  Shared scheduler data base in internal SRAM
  * 3)  Shared data in host DRAM
  *
  * Initialization:
@@ -330,201 +173,10 @@
  * Max Tx window size is the max number of contiguous TFDs that the scheduler
  * can keep track of at one time when creating block-ack chains of frames.
  * Note that "64" matches the number of ack bits in a block-ack packet.
- * Driver should use SCD_WIN_SIZE and SCD_FRAME_LIMIT values to initialize
- * IWL49_SCD_CONTEXT_QUEUE_OFFSET(x) values.
  */
 #define SCD_WIN_SIZE				64
 #define SCD_FRAME_LIMIT				64
 
-/* SCD registers are internal, must be accessed via HBUS_TARG_PRPH regs */
-#define IWL49_SCD_START_OFFSET		0xa02c00
-
-/*
- * 4965 tells driver SRAM address for internal scheduler structs via this reg.
- * Value is valid only after "Alive" response from uCode.
- */
-#define IWL49_SCD_SRAM_BASE_ADDR           (IWL49_SCD_START_OFFSET + 0x0)
-
-/*
- * Driver may need to update queue-empty bits after changing queue's
- * write and read pointers (indexes) during (re-)initialization (i.e. when
- * scheduler is not tracking what's happening).
- * Bit fields:
- * 31-16:  Write mask -- 1: update empty bit, 0: don't change empty bit
- * 15-00:  Empty state, one for each queue -- 1: empty, 0: non-empty
- * NOTE:  This register is not used by Linux driver.
- */
-#define IWL49_SCD_EMPTY_BITS               (IWL49_SCD_START_OFFSET + 0x4)
-
-/*
- * Physical base address of array of byte count (BC) circular buffers (CBs).
- * Each Tx queue has a BC CB in host DRAM to support Scheduler-ACK mode.
- * This register points to BC CB for queue 0, must be on 1024-byte boundary.
- * Others are spaced by 1024 bytes.
- * Each BC CB is 2 bytes * (256 + 64) = 740 bytes, followed by 384 bytes pad.
- * (Index into a queue's BC CB) = (index into queue's TFD CB) = (SSN & 0xff).
- * Bit fields:
- * 25-00:  Byte Count CB physical address [35:10], must be 1024-byte aligned.
- */
-#define IWL49_SCD_DRAM_BASE_ADDR           (IWL49_SCD_START_OFFSET + 0x10)
-
-/*
- * Enables any/all Tx DMA/FIFO channels.
- * Scheduler generates requests for only the active channels.
- * Set this to 0xff to enable all 8 channels (normal usage).
- * Bit fields:
- *  7- 0:  Enable (1), disable (0), one bit for each channel 0-7
- */
-#define IWL49_SCD_TXFACT                   (IWL49_SCD_START_OFFSET + 0x1c)
-/*
- * Queue (x) Write Pointers (indexes, really!), one for each Tx queue.
- * Initialized and updated by driver as new TFDs are added to queue.
- * NOTE:  If using Block Ack, index must correspond to frame's
- *        Start Sequence Number; index = (SSN & 0xff)
- * NOTE:  Alternative to HBUS_TARG_WRPTR, which is what Linux driver uses?
- */
-#define IWL49_SCD_QUEUE_WRPTR(x)  (IWL49_SCD_START_OFFSET + 0x24 + (x) * 4)
-
-/*
- * Queue (x) Read Pointers (indexes, really!), one for each Tx queue.
- * For FIFO mode, index indicates next frame to transmit.
- * For Scheduler-ACK mode, index indicates first frame in Tx window.
- * Initialized by driver, updated by scheduler.
- */
-#define IWL49_SCD_QUEUE_RDPTR(x)  (IWL49_SCD_START_OFFSET + 0x64 + (x) * 4)
-
-/*
- * Select which queues work in chain mode (1) vs. not (0).
- * Use chain mode to build chains of aggregated frames.
- * Bit fields:
- * 31-16:  Reserved
- * 15-00:  Mode, one bit for each queue -- 1: Chain mode, 0: one-at-a-time
- * NOTE:  If driver sets up queue for chain mode, it should be also set up
- *        Scheduler-ACK mode as well, via SCD_QUEUE_STATUS_BITS(x).
- */
-#define IWL49_SCD_QUEUECHAIN_SEL  (IWL49_SCD_START_OFFSET + 0xd0)
-
-/*
- * Select which queues interrupt driver when scheduler increments
- * a queue's read pointer (index).
- * Bit fields:
- * 31-16:  Reserved
- * 15-00:  Interrupt enable, one bit for each queue -- 1: enabled, 0: disabled
- * NOTE:  This functionality is apparently a no-op; driver relies on interrupts
- *        from Rx queue to read Tx command responses and update Tx queues.
- */
-#define IWL49_SCD_INTERRUPT_MASK  (IWL49_SCD_START_OFFSET + 0xe4)
-
-/*
- * Queue search status registers.  One for each queue.
- * Sets up queue mode and assigns queue to Tx DMA channel.
- * Bit fields:
- * 19-10: Write mask/enable bits for bits 0-9
- *     9: Driver should init to "0"
- *     8: Scheduler-ACK mode (1), non-Scheduler-ACK (i.e. FIFO) mode (0).
- *        Driver should init to "1" for aggregation mode, or "0" otherwise.
- *   7-6: Driver should init to "0"
- *     5: Window Size Left; indicates whether scheduler can request
- *        another TFD, based on window size, etc.  Driver should init
- *        this bit to "1" for aggregation mode, or "0" for non-agg.
- *   4-1: Tx FIFO to use (range 0-7).
- *     0: Queue is active (1), not active (0).
- * Other bits should be written as "0"
- *
- * NOTE:  If enabling Scheduler-ACK mode, chain mode should also be enabled
- *        via SCD_QUEUECHAIN_SEL.
- */
-#define IWL49_SCD_QUEUE_STATUS_BITS(x)\
-	(IWL49_SCD_START_OFFSET + 0x104 + (x) * 4)
-
-/* Bit field positions */
-#define IWL49_SCD_QUEUE_STTS_REG_POS_ACTIVE	(0)
-#define IWL49_SCD_QUEUE_STTS_REG_POS_TXF	(1)
-#define IWL49_SCD_QUEUE_STTS_REG_POS_WSL	(5)
-#define IWL49_SCD_QUEUE_STTS_REG_POS_SCD_ACK	(8)
-
-/* Write masks */
-#define IWL49_SCD_QUEUE_STTS_REG_POS_SCD_ACT_EN	(10)
-#define IWL49_SCD_QUEUE_STTS_REG_MSK		(0x0007FC00)
-
-/**
- * 4965 internal SRAM structures for scheduler, shared with driver ...
- *
- * Driver should clear and initialize the following areas after receiving
- * "Alive" response from 4965 uCode, i.e. after initial
- * uCode load, or after a uCode load done for error recovery:
- *
- * SCD_CONTEXT_DATA_OFFSET (size 128 bytes)
- * SCD_TX_STTS_BITMAP_OFFSET (size 256 bytes)
- * SCD_TRANSLATE_TBL_OFFSET (size 32 bytes)
- *
- * Driver accesses SRAM via HBUS_TARG_MEM_* registers.
- * Driver reads base address of this scheduler area from SCD_SRAM_BASE_ADDR.
- * All OFFSET values must be added to this base address.
- */
-
-/*
- * Queue context.  One 8-byte entry for each of 16 queues.
- *
- * Driver should clear this entire area (size 0x80) to 0 after receiving
- * "Alive" notification from uCode.  Additionally, driver should init
- * each queue's entry as follows:
- *
- * LS Dword bit fields:
- *  0-06:  Max Tx window size for Scheduler-ACK.  Driver should init to 64.
- *
- * MS Dword bit fields:
- * 16-22:  Frame limit.  Driver should init to 10 (0xa).
- *
- * Driver should init all other bits to 0.
- *
- * Init must be done after driver receives "Alive" response from 4965 uCode,
- * and when setting up queue for aggregation.
- */
-#define IWL49_SCD_CONTEXT_DATA_OFFSET			0x380
-#define IWL49_SCD_CONTEXT_QUEUE_OFFSET(x) \
-			(IWL49_SCD_CONTEXT_DATA_OFFSET + ((x) * 8))
-
-#define IWL49_SCD_QUEUE_CTX_REG1_WIN_SIZE_POS		(0)
-#define IWL49_SCD_QUEUE_CTX_REG1_WIN_SIZE_MSK		(0x0000007F)
-#define IWL49_SCD_QUEUE_CTX_REG2_FRAME_LIMIT_POS	(16)
-#define IWL49_SCD_QUEUE_CTX_REG2_FRAME_LIMIT_MSK	(0x007F0000)
-
-/*
- * Tx Status Bitmap
- *
- * Driver should clear this entire area (size 0x100) to 0 after receiving
- * "Alive" notification from uCode.  Area is used only by device itself;
- * no other support (besides clearing) is required from driver.
- */
-#define IWL49_SCD_TX_STTS_BITMAP_OFFSET		0x400
-
-/*
- * RAxTID to queue translation mapping.
- *
- * When queue is in Scheduler-ACK mode, frames placed in a that queue must be
- * for only one combination of receiver address (RA) and traffic ID (TID), i.e.
- * one QOS priority level destined for one station (for this wireless link,
- * not final destination).  The SCD_TRANSLATE_TABLE area provides 16 16-bit
- * mappings, one for each of the 16 queues.  If queue is not in Scheduler-ACK
- * mode, the device ignores the mapping value.
- *
- * Bit fields, for each 16-bit map:
- * 15-9:  Reserved, set to 0
- *  8-4:  Index into device's station table for recipient station
- *  3-0:  Traffic ID (tid), range 0-15
- *
- * Driver should clear this entire area (size 32 bytes) to 0 after receiving
- * "Alive" notification from uCode.  To update a 16-bit map value, driver
- * must read a dword-aligned value from device SRAM, replace the 16-bit map
- * value of interest, and write the dword value back into device SRAM.
- */
-#define IWL49_SCD_TRANSLATE_TBL_OFFSET		0x500
-
-/* Find translation table dword to read/write for given queue */
-#define IWL49_SCD_TRANSLATE_TBL_OFFSET_QUEUE(x) \
-	((IWL49_SCD_TRANSLATE_TBL_OFFSET + ((x) * 2)) & 0xfffffffc)
-
 #define IWL_SCD_TXFIFO_POS_TID			(0)
 #define IWL_SCD_TXFIFO_POS_RA			(4)
 #define IWL_SCD_QUEUE_RA_TID_MAP_RATID_MSK	(0x01FF)
diff -druN linux-2.6.39-libre/drivers/net/wireless/iwlwifi/iwl-rx.c linux-3.0-rc7-libre/drivers/net/wireless/iwlwifi/iwl-rx.c
--- linux-2.6.39-libre/drivers/net/wireless/iwlwifi/iwl-rx.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/iwlwifi/iwl-rx.c	2011-07-11 19:51:52.000000000 -0400
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2003 - 2011 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.
@@ -225,55 +225,6 @@
  *
  ******************************************************************************/
 
-static void iwl_rx_reply_alive(struct iwl_priv *priv,
-			       struct iwl_rx_mem_buffer *rxb)
-{
-	struct iwl_rx_packet *pkt = rxb_addr(rxb);
-	struct iwl_alive_resp *palive;
-	struct delayed_work *pwork;
-
-	palive = &pkt->u.alive_frame;
-
-	IWL_DEBUG_INFO(priv, "Alive ucode status 0x%08X revision "
-		       "0x%01X 0x%01X\n",
-		       palive->is_valid, palive->ver_type,
-		       palive->ver_subtype);
-
-	if (palive->ver_subtype == INITIALIZE_SUBTYPE) {
-		IWL_DEBUG_INFO(priv, "Initialization Alive received.\n");
-		memcpy(&priv->card_alive_init,
-		       &pkt->u.alive_frame,
-		       sizeof(struct iwl_init_alive_resp));
-		pwork = &priv->init_alive_start;
-	} else {
-		IWL_DEBUG_INFO(priv, "Runtime Alive received.\n");
-		memcpy(&priv->card_alive, &pkt->u.alive_frame,
-		       sizeof(struct iwl_alive_resp));
-		pwork = &priv->alive_start;
-	}
-
-	/* We delay the ALIVE response by 5ms to
-	 * give the HW RF Kill time to activate... */
-	if (palive->is_valid == UCODE_VALID_OK)
-		queue_delayed_work(priv->workqueue, pwork,
-				   msecs_to_jiffies(5));
-	else {
-		IWL_WARN(priv, "%s uCode did not respond OK.\n",
-			(palive->ver_subtype == INITIALIZE_SUBTYPE) ?
-			"init" : "runtime");
-		/*
-		 * If fail to load init uCode,
-		 * let's try to load the init uCode again.
-		 * We should not get into this situation, but if it
-		 * does happen, we should not move on and loading "runtime"
-		 * without proper calibrate the device.
-		 */
-		if (palive->ver_subtype == INITIALIZE_SUBTYPE)
-			priv->ucode_type = UCODE_NONE;
-		queue_work(priv->workqueue, &priv->restart);
-	}
-}
-
 static void iwl_rx_reply_error(struct iwl_priv *priv,
 			       struct iwl_rx_mem_buffer *rxb)
 {
@@ -299,19 +250,19 @@
 	struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
 	struct iwl_rxon_cmd *rxon = (void *)&ctx->active;
 
-	if (priv->switch_rxon.switch_in_progress) {
-		if (!le32_to_cpu(csa->status) &&
-		    (csa->channel == priv->switch_rxon.channel)) {
-			rxon->channel = csa->channel;
-			ctx->staging.channel = csa->channel;
-			IWL_DEBUG_11H(priv, "CSA notif: channel %d\n",
-			      le16_to_cpu(csa->channel));
-			iwl_chswitch_done(priv, true);
-		} else {
-			IWL_ERR(priv, "CSA notif (fail) : channel %d\n",
+	if (!test_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->status))
+		return;
+
+	if (!le32_to_cpu(csa->status) && csa->channel == priv->switch_channel) {
+		rxon->channel = csa->channel;
+		ctx->staging.channel = csa->channel;
+		IWL_DEBUG_11H(priv, "CSA notif: channel %d\n",
 			      le16_to_cpu(csa->channel));
-			iwl_chswitch_done(priv, false);
-		}
+		iwl_chswitch_done(priv, true);
+	} else {
+		IWL_ERR(priv, "CSA notif (fail) : channel %d\n",
+			le16_to_cpu(csa->channel));
+		iwl_chswitch_done(priv, false);
 	}
 }
 
@@ -390,21 +341,16 @@
  * the BA_TIMEOUT_MAX, reload firmware and bring system back to normal
  * operation state.
  */
-static bool iwl_good_ack_health(struct iwl_priv *priv, struct iwl_rx_packet *pkt)
+static bool iwl_good_ack_health(struct iwl_priv *priv,
+				struct statistics_tx *cur)
 {
 	int actual_delta, expected_delta, ba_timeout_delta;
-	struct statistics_tx *cur, *old;
+	struct statistics_tx *old;
 
 	if (priv->_agn.agg_tids_count)
 		return true;
 
-	if (iwl_bt_statistics(priv)) {
-		cur = &pkt->u.stats_bt.tx;
-		old = &priv->_agn.statistics_bt.tx;
-	} else {
-		cur = &pkt->u.stats.tx;
-		old = &priv->_agn.statistics.tx;
-	}
+	old = &priv->statistics.tx;
 
 	actual_delta = le32_to_cpu(cur->actual_ack_cnt) -
 		       le32_to_cpu(old->actual_ack_cnt);
@@ -430,10 +376,10 @@
 		 * DEBUG is not, these will just compile out.
 		 */
 		IWL_DEBUG_RADIO(priv, "rx_detected_cnt delta %d\n",
-				priv->_agn.delta_statistics.tx.rx_detected_cnt);
+				priv->delta_stats.tx.rx_detected_cnt);
 		IWL_DEBUG_RADIO(priv,
 				"ack_or_ba_timeout_collision delta %d\n",
-				priv->_agn.delta_statistics.tx.ack_or_ba_timeout_collision);
+				priv->delta_stats.tx.ack_or_ba_timeout_collision);
 #endif
 
 		if (ba_timeout_delta >= BA_TIMEOUT_MAX)
@@ -450,7 +396,9 @@
  * to improve the throughput.
  */
 static bool iwl_good_plcp_health(struct iwl_priv *priv,
-				 struct iwl_rx_packet *pkt, unsigned int msecs)
+				 struct statistics_rx_phy *cur_ofdm,
+				 struct statistics_rx_ht_phy *cur_ofdm_ht,
+				 unsigned int msecs)
 {
 	int delta;
 	int threshold = priv->cfg->base_params->plcp_delta_threshold;
@@ -460,29 +408,12 @@
 		return true;
 	}
 
-	if (iwl_bt_statistics(priv)) {
-		struct statistics_rx_bt *cur, *old;
-
-		cur = &pkt->u.stats_bt.rx;
-		old = &priv->_agn.statistics_bt.rx;
-
-		delta = le32_to_cpu(cur->ofdm.plcp_err) -
-			le32_to_cpu(old->ofdm.plcp_err) +
-			le32_to_cpu(cur->ofdm_ht.plcp_err) -
-			le32_to_cpu(old->ofdm_ht.plcp_err);
-	} else {
-		struct statistics_rx *cur, *old;
-
-		cur = &pkt->u.stats.rx;
-		old = &priv->_agn.statistics.rx;
-
-		delta = le32_to_cpu(cur->ofdm.plcp_err) -
-			le32_to_cpu(old->ofdm.plcp_err) +
-			le32_to_cpu(cur->ofdm_ht.plcp_err) -
-			le32_to_cpu(old->ofdm_ht.plcp_err);
-	}
+	delta = le32_to_cpu(cur_ofdm->plcp_err) -
+		le32_to_cpu(priv->statistics.rx_ofdm.plcp_err) +
+		le32_to_cpu(cur_ofdm_ht->plcp_err) -
+		le32_to_cpu(priv->statistics.rx_ofdm_ht.plcp_err);
 
-	/* Can be negative if firmware reseted statistics */
+	/* Can be negative if firmware reset statistics */
 	if (delta <= 0)
 		return true;
 
@@ -497,44 +428,35 @@
 }
 
 static void iwl_recover_from_statistics(struct iwl_priv *priv,
-					struct iwl_rx_packet *pkt)
+					struct statistics_rx_phy *cur_ofdm,
+					struct statistics_rx_ht_phy *cur_ofdm_ht,
+					struct statistics_tx *tx,
+					unsigned long stamp)
 {
-	const struct iwl_mod_params *mod_params = priv->cfg->mod_params;
 	unsigned int msecs;
-	unsigned long stamp;
 
 	if (test_bit(STATUS_EXIT_PENDING, &priv->status))
 		return;
 
-	stamp = jiffies;
 	msecs = jiffies_to_msecs(stamp - priv->rx_statistics_jiffies);
 
 	/* Only gather statistics and update time stamp when not associated */
 	if (!iwl_is_any_associated(priv))
-		goto out;
+		return;
 
 	/* Do not check/recover when do not have enough statistics data */
 	if (msecs < 99)
 		return;
 
-	if (mod_params->ack_check && !iwl_good_ack_health(priv, pkt)) {
+	if (iwlagn_mod_params.ack_check && !iwl_good_ack_health(priv, tx)) {
 		IWL_ERR(priv, "low ack count detected, restart firmware\n");
 		if (!iwl_force_reset(priv, IWL_FW_RESET, false))
 			return;
 	}
 
-	if (mod_params->plcp_check && !iwl_good_plcp_health(priv, pkt, msecs))
+	if (iwlagn_mod_params.plcp_check &&
+	    !iwl_good_plcp_health(priv, cur_ofdm, cur_ofdm_ht, msecs))
 		iwl_force_reset(priv, IWL_RF_RESET, false);
-
-out:
-	if (iwl_bt_statistics(priv))
-		memcpy(&priv->_agn.statistics_bt, &pkt->u.stats_bt,
-			sizeof(priv->_agn.statistics_bt));
-	else
-		memcpy(&priv->_agn.statistics, &pkt->u.stats,
-			sizeof(priv->_agn.statistics));
-
-	priv->rx_statistics_jiffies = stamp;
 }
 
 /* Calculate noise level, based on measurements during network silence just
@@ -548,10 +470,8 @@
 	int bcn_silence_a, bcn_silence_b, bcn_silence_c;
 	int last_rx_noise;
 
-	if (iwl_bt_statistics(priv))
-		rx_info = &(priv->_agn.statistics_bt.rx.general.common);
-	else
-		rx_info = &(priv->_agn.statistics.rx.general);
+	rx_info = &priv->statistics.rx_non_phy;
+
 	bcn_silence_a =
 		le32_to_cpu(rx_info->beacon_silence_rssi_a) & IN_BAND_FILTER;
 	bcn_silence_b =
@@ -583,105 +503,153 @@
 			last_rx_noise);
 }
 
+#ifdef CONFIG_IWLWIFI_DEBUGFS
 /*
  *  based on the assumption of all statistics counter are in DWORD
  *  FIXME: This function is for debugging, do not deal with
  *  the case of counters roll-over.
  */
-static void iwl_accumulative_statistics(struct iwl_priv *priv,
-					__le32 *stats)
+static void accum_stats(__le32 *prev, __le32 *cur, __le32 *delta,
+			__le32 *max_delta, __le32 *accum, int size)
 {
-#ifdef CONFIG_IWLWIFI_DEBUGFS
-	int i, size;
-	__le32 *prev_stats;
-	u32 *accum_stats;
-	u32 *delta, *max_delta;
-	struct statistics_general_common *general, *accum_general;
-	struct statistics_tx *tx, *accum_tx;
+	int i;
 
-	if (iwl_bt_statistics(priv)) {
-		prev_stats = (__le32 *)&priv->_agn.statistics_bt;
-		accum_stats = (u32 *)&priv->_agn.accum_statistics_bt;
-		size = sizeof(struct iwl_bt_notif_statistics);
-		general = &priv->_agn.statistics_bt.general.common;
-		accum_general = &priv->_agn.accum_statistics_bt.general.common;
-		tx = &priv->_agn.statistics_bt.tx;
-		accum_tx = &priv->_agn.accum_statistics_bt.tx;
-		delta = (u32 *)&priv->_agn.delta_statistics_bt;
-		max_delta = (u32 *)&priv->_agn.max_delta_bt;
-	} else {
-		prev_stats = (__le32 *)&priv->_agn.statistics;
-		accum_stats = (u32 *)&priv->_agn.accum_statistics;
-		size = sizeof(struct iwl_notif_statistics);
-		general = &priv->_agn.statistics.general.common;
-		accum_general = &priv->_agn.accum_statistics.general.common;
-		tx = &priv->_agn.statistics.tx;
-		accum_tx = &priv->_agn.accum_statistics.tx;
-		delta = (u32 *)&priv->_agn.delta_statistics;
-		max_delta = (u32 *)&priv->_agn.max_delta;
-	}
-	for (i = sizeof(__le32); i < size;
-	     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)
+	for (i = 0;
+	     i < size / sizeof(__le32);
+	     i++, prev++, cur++, delta++, max_delta++, accum++) {
+		if (le32_to_cpu(*cur) > le32_to_cpu(*prev)) {
+			*delta = cpu_to_le32(
+				le32_to_cpu(*cur) - le32_to_cpu(*prev));
+			le32_add_cpu(accum, le32_to_cpu(*delta));
+			if (le32_to_cpu(*delta) > le32_to_cpu(*max_delta))
 				*max_delta = *delta;
 		}
 	}
+}
 
-	/* reset accumulative statistics for "no-counter" type statistics */
-	accum_general->temperature = general->temperature;
-	accum_general->temperature_m = general->temperature_m;
-	accum_general->ttl_timestamp = general->ttl_timestamp;
-	accum_tx->tx_power.ant_a = tx->tx_power.ant_a;
-	accum_tx->tx_power.ant_b = tx->tx_power.ant_b;
-	accum_tx->tx_power.ant_c = tx->tx_power.ant_c;
-#endif
+static void
+iwl_accumulative_statistics(struct iwl_priv *priv,
+			    struct statistics_general_common *common,
+			    struct statistics_rx_non_phy *rx_non_phy,
+			    struct statistics_rx_phy *rx_ofdm,
+			    struct statistics_rx_ht_phy *rx_ofdm_ht,
+			    struct statistics_rx_phy *rx_cck,
+			    struct statistics_tx *tx,
+			    struct statistics_bt_activity *bt_activity)
+{
+#define ACCUM(_name)	\
+	accum_stats((__le32 *)&priv->statistics._name,		\
+		    (__le32 *)_name,				\
+		    (__le32 *)&priv->delta_stats._name,		\
+		    (__le32 *)&priv->max_delta_stats._name,	\
+		    (__le32 *)&priv->accum_stats._name,		\
+		    sizeof(*_name));
+
+	ACCUM(common);
+	ACCUM(rx_non_phy);
+	ACCUM(rx_ofdm);
+	ACCUM(rx_ofdm_ht);
+	ACCUM(rx_cck);
+	ACCUM(tx);
+	if (bt_activity)
+		ACCUM(bt_activity);
+#undef ACCUM
+}
+#else
+static inline void
+iwl_accumulative_statistics(struct iwl_priv *priv,
+			    struct statistics_general_common *common,
+			    struct statistics_rx_non_phy *rx_non_phy,
+			    struct statistics_rx_phy *rx_ofdm,
+			    struct statistics_rx_ht_phy *rx_ofdm_ht,
+			    struct statistics_rx_phy *rx_cck,
+			    struct statistics_tx *tx,
+			    struct statistics_bt_activity *bt_activity)
+{
 }
+#endif
 
 static void iwl_rx_statistics(struct iwl_priv *priv,
 			      struct iwl_rx_mem_buffer *rxb)
 {
+	unsigned long stamp = jiffies;
 	const int reg_recalib_period = 60;
 	int change;
 	struct iwl_rx_packet *pkt = rxb_addr(rxb);
+	u32 len = le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK;
+	__le32 *flag;
+	struct statistics_general_common *common;
+	struct statistics_rx_non_phy *rx_non_phy;
+	struct statistics_rx_phy *rx_ofdm;
+	struct statistics_rx_ht_phy *rx_ofdm_ht;
+	struct statistics_rx_phy *rx_cck;
+	struct statistics_tx *tx;
+	struct statistics_bt_activity *bt_activity;
 
-	if (iwl_bt_statistics(priv)) {
-		IWL_DEBUG_RX(priv,
-			     "Statistics notification received (%d vs %d).\n",
-			     (int)sizeof(struct iwl_bt_notif_statistics),
-			     le32_to_cpu(pkt->len_n_flags) &
-			     FH_RSCSR_FRAME_SIZE_MSK);
+	len -= sizeof(struct iwl_cmd_header); /* skip header */
 
-		change = ((priv->_agn.statistics_bt.general.common.temperature !=
-			   pkt->u.stats_bt.general.common.temperature) ||
-			   ((priv->_agn.statistics_bt.flag &
-			   STATISTICS_REPLY_FLG_HT40_MODE_MSK) !=
-			   (pkt->u.stats_bt.flag &
-			   STATISTICS_REPLY_FLG_HT40_MODE_MSK)));
+	IWL_DEBUG_RX(priv, "Statistics notification received (%d bytes).\n",
+		     len);
 
-		iwl_accumulative_statistics(priv, (__le32 *)&pkt->u.stats_bt);
+	if (len == sizeof(struct iwl_bt_notif_statistics)) {
+		struct iwl_bt_notif_statistics *stats;
+		stats = &pkt->u.stats_bt;
+		flag = &stats->flag;
+		common = &stats->general.common;
+		rx_non_phy = &stats->rx.general.common;
+		rx_ofdm = &stats->rx.ofdm;
+		rx_ofdm_ht = &stats->rx.ofdm_ht;
+		rx_cck = &stats->rx.cck;
+		tx = &stats->tx;
+		bt_activity = &stats->general.activity;
+
+#ifdef CONFIG_IWLWIFI_DEBUGFS
+		/* handle this exception directly */
+		priv->statistics.num_bt_kills = stats->rx.general.num_bt_kills;
+		le32_add_cpu(&priv->statistics.accum_num_bt_kills,
+			     le32_to_cpu(stats->rx.general.num_bt_kills));
+#endif
+	} else if (len == sizeof(struct iwl_notif_statistics)) {
+		struct iwl_notif_statistics *stats;
+		stats = &pkt->u.stats;
+		flag = &stats->flag;
+		common = &stats->general.common;
+		rx_non_phy = &stats->rx.general;
+		rx_ofdm = &stats->rx.ofdm;
+		rx_ofdm_ht = &stats->rx.ofdm_ht;
+		rx_cck = &stats->rx.cck;
+		tx = &stats->tx;
+		bt_activity = NULL;
 	} else {
-		IWL_DEBUG_RX(priv,
-			     "Statistics notification received (%d vs %d).\n",
-			     (int)sizeof(struct iwl_notif_statistics),
-			     le32_to_cpu(pkt->len_n_flags) &
-			     FH_RSCSR_FRAME_SIZE_MSK);
+		WARN_ONCE(1, "len %d doesn't match BT (%zu) or normal (%zu)\n",
+			  len, sizeof(struct iwl_bt_notif_statistics),
+			  sizeof(struct iwl_notif_statistics));
+		return;
+	}
 
-		change = ((priv->_agn.statistics.general.common.temperature !=
-			   pkt->u.stats.general.common.temperature) ||
-			   ((priv->_agn.statistics.flag &
-			   STATISTICS_REPLY_FLG_HT40_MODE_MSK) !=
-			   (pkt->u.stats.flag &
-			   STATISTICS_REPLY_FLG_HT40_MODE_MSK)));
+	change = common->temperature != priv->statistics.common.temperature ||
+		 (*flag & STATISTICS_REPLY_FLG_HT40_MODE_MSK) !=
+		 (priv->statistics.flag & STATISTICS_REPLY_FLG_HT40_MODE_MSK);
 
-		iwl_accumulative_statistics(priv, (__le32 *)&pkt->u.stats);
-	}
+	iwl_accumulative_statistics(priv, common, rx_non_phy, rx_ofdm,
+				    rx_ofdm_ht, rx_cck, tx, bt_activity);
 
-	iwl_recover_from_statistics(priv, pkt);
+	iwl_recover_from_statistics(priv, rx_ofdm, rx_ofdm_ht, tx, stamp);
+
+	priv->statistics.flag = *flag;
+	memcpy(&priv->statistics.common, common, sizeof(*common));
+	memcpy(&priv->statistics.rx_non_phy, rx_non_phy, sizeof(*rx_non_phy));
+	memcpy(&priv->statistics.rx_ofdm, rx_ofdm, sizeof(*rx_ofdm));
+	memcpy(&priv->statistics.rx_ofdm_ht, rx_ofdm_ht, sizeof(*rx_ofdm_ht));
+	memcpy(&priv->statistics.rx_cck, rx_cck, sizeof(*rx_cck));
+	memcpy(&priv->statistics.tx, tx, sizeof(*tx));
+#ifdef CONFIG_IWLWIFI_DEBUGFS
+	if (bt_activity)
+		memcpy(&priv->statistics.bt_activity, bt_activity,
+			sizeof(*bt_activity));
+#endif
+
+	priv->rx_statistics_jiffies = stamp;
 
 	set_bit(STATUS_STATISTICS, &priv->status);
 
@@ -708,18 +676,12 @@
 
 	if (le32_to_cpu(pkt->u.stats.flag) & UCODE_STATISTICS_CLEAR_MSK) {
 #ifdef CONFIG_IWLWIFI_DEBUGFS
-		memset(&priv->_agn.accum_statistics, 0,
-			sizeof(struct iwl_notif_statistics));
-		memset(&priv->_agn.delta_statistics, 0,
-			sizeof(struct iwl_notif_statistics));
-		memset(&priv->_agn.max_delta, 0,
-			sizeof(struct iwl_notif_statistics));
-		memset(&priv->_agn.accum_statistics_bt, 0,
-			sizeof(struct iwl_bt_notif_statistics));
-		memset(&priv->_agn.delta_statistics_bt, 0,
-			sizeof(struct iwl_bt_notif_statistics));
-		memset(&priv->_agn.max_delta_bt, 0,
-			sizeof(struct iwl_bt_notif_statistics));
+		memset(&priv->accum_stats, 0,
+			sizeof(priv->accum_stats));
+		memset(&priv->delta_stats, 0,
+			sizeof(priv->delta_stats));
+		memset(&priv->max_delta_stats, 0,
+			sizeof(priv->max_delta_stats));
 #endif
 		IWL_DEBUG_RX(priv, "Statistics have been cleared\n");
 	}
@@ -873,6 +835,7 @@
 {
 	struct sk_buff *skb;
 	__le16 fc = hdr->frame_control;
+	struct iwl_rxon_context *ctx;
 
 	/* We only process data packets if the interface is open */
 	if (unlikely(!priv->is_open)) {
@@ -882,7 +845,7 @@
 	}
 
 	/* In case of HW accelerated crypto and bad decryption, drop */
-	if (!priv->cfg->mod_params->sw_crypto &&
+	if (!iwlagn_mod_params.sw_crypto &&
 	    iwl_set_decrypted_flag(priv, hdr, ampdu_status, stats))
 		return;
 
@@ -895,10 +858,29 @@
 	skb_add_rx_frag(skb, 0, rxb->page, (void *)hdr - rxb_addr(rxb), len);
 
 	iwl_update_stats(priv, false, fc, len);
+
+	/*
+	* Wake any queues that were stopped due to a passive channel tx
+	* failure. This can happen because the regulatory enforcement in
+	* the device waits for a beacon before allowing transmission,
+	* sometimes even after already having transmitted frames for the
+	* association because the new RXON may reset the information.
+	*/
+	if (unlikely(ieee80211_is_beacon(fc))) {
+		for_each_context(priv, ctx) {
+			if (!ctx->last_tx_rejected)
+				continue;
+			if (compare_ether_addr(hdr->addr3,
+					       ctx->active.bssid_addr))
+				continue;
+			ctx->last_tx_rejected = false;
+			iwl_wake_any_queue(priv, ctx);
+		}
+	}
+
 	memcpy(IEEE80211_SKB_RXCB(skb), stats, sizeof(*stats));
 
 	ieee80211_rx(priv->hw, skb);
-	priv->alloc_rxb_page--;
 	rxb->page = NULL;
 }
 
@@ -1093,7 +1075,6 @@
 
 	handlers = priv->rx_handlers;
 
-	handlers[REPLY_ALIVE]			= iwl_rx_reply_alive;
 	handlers[REPLY_ERROR]			= iwl_rx_reply_error;
 	handlers[CHANNEL_SWITCH_NOTIFICATION]	= iwl_rx_csa;
 	handlers[SPECTRUM_MEASURE_NOTIFICATION]	= iwl_rx_spectrum_measure_notif;
diff -druN linux-2.6.39-libre/drivers/net/wireless/iwlwifi/iwl-scan.c linux-3.0-rc7-libre/drivers/net/wireless/iwlwifi/iwl-scan.c
--- linux-2.6.39-libre/drivers/net/wireless/iwlwifi/iwl-scan.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/iwlwifi/iwl-scan.c	2011-07-11 19:51:52.000000000 -0400
@@ -2,7 +2,7 @@
  *
  * GPL LICENSE SUMMARY
  *
- * Copyright(c) 2008 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2008 - 2011 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 -druN linux-2.6.39-libre/drivers/net/wireless/iwlwifi/iwl-spectrum.h linux-3.0-rc7-libre/drivers/net/wireless/iwlwifi/iwl-spectrum.h
--- linux-2.6.39-libre/drivers/net/wireless/iwlwifi/iwl-spectrum.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/iwlwifi/iwl-spectrum.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,92 +0,0 @@
-/******************************************************************************
- *
- * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved.
- *
- * Portions of this file are derived from 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
- *
- *****************************************************************************/
-
-#ifndef __iwl_spectrum_h__
-#define __iwl_spectrum_h__
-enum {				/* ieee80211_basic_report.map */
-	IEEE80211_BASIC_MAP_BSS = (1 << 0),
-	IEEE80211_BASIC_MAP_OFDM = (1 << 1),
-	IEEE80211_BASIC_MAP_UNIDENTIFIED = (1 << 2),
-	IEEE80211_BASIC_MAP_RADAR = (1 << 3),
-	IEEE80211_BASIC_MAP_UNMEASURED = (1 << 4),
-	/* Bits 5-7 are reserved */
-
-};
-struct ieee80211_basic_report {
-	u8 channel;
-	__le64 start_time;
-	__le16 duration;
-	u8 map;
-} __packed;
-
-enum {				/* ieee80211_measurement_request.mode */
-	/* Bit 0 is reserved */
-	IEEE80211_MEASUREMENT_ENABLE = (1 << 1),
-	IEEE80211_MEASUREMENT_REQUEST = (1 << 2),
-	IEEE80211_MEASUREMENT_REPORT = (1 << 3),
-	/* Bits 4-7 are reserved */
-};
-
-enum {
-	IEEE80211_REPORT_BASIC = 0,	/* required */
-	IEEE80211_REPORT_CCA = 1,	/* optional */
-	IEEE80211_REPORT_RPI = 2,	/* optional */
-	/* 3-255 reserved */
-};
-
-struct ieee80211_measurement_params {
-	u8 channel;
-	__le64 start_time;
-	__le16 duration;
-} __packed;
-
-struct ieee80211_info_element {
-	u8 id;
-	u8 len;
-	u8 data[0];
-} __packed;
-
-struct ieee80211_measurement_request {
-	struct ieee80211_info_element ie;
-	u8 token;
-	u8 mode;
-	u8 type;
-	struct ieee80211_measurement_params params[0];
-} __packed;
-
-struct ieee80211_measurement_report {
-	struct ieee80211_info_element ie;
-	u8 token;
-	u8 mode;
-	u8 type;
-	union {
-		struct ieee80211_basic_report basic[0];
-	} u;
-} __packed;
-
-#endif
diff -druN linux-2.6.39-libre/drivers/net/wireless/iwlwifi/iwl-sta.c linux-3.0-rc7-libre/drivers/net/wireless/iwlwifi/iwl-sta.c
--- linux-2.6.39-libre/drivers/net/wireless/iwlwifi/iwl-sta.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/iwlwifi/iwl-sta.c	2011-07-11 19:51:52.000000000 -0400
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2003 - 2011 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.
@@ -141,7 +141,7 @@
 	struct iwl_host_cmd cmd = {
 		.id = REPLY_ADD_STA,
 		.flags = flags,
-		.data = data,
+		.data = { data, },
 	};
 	u8 sta_id __maybe_unused = sta->sta.sta_id;
 
@@ -155,7 +155,7 @@
 		might_sleep();
 	}
 
-	cmd.len = priv->cfg->ops->utils->build_addsta_hcmd(sta, data);
+	cmd.len[0] = priv->cfg->ops->utils->build_addsta_hcmd(sta, data);
 	ret = iwl_send_cmd(priv, &cmd);
 
 	if (ret || (flags & CMD_ASYNC))
@@ -233,7 +233,6 @@
 	struct iwl_station_entry *station;
 	int i;
 	u8 sta_id = IWL_INVALID_STATION;
-	u16 rate;
 
 	if (is_ap)
 		sta_id = ctx->ap_sta_id;
@@ -306,12 +305,6 @@
 	 */
 	iwl_set_ht_add_station(priv, sta_id, sta, ctx);
 
-	/* 3945 only */
-	rate = (priv->band == IEEE80211_BAND_5GHZ) ?
-		IWL_RATE_6M_PLCP : IWL_RATE_1M_PLCP;
-	/* Turn on both antennas for the station... */
-	station->sta.rate_n_flags = cpu_to_le16(rate | RATE_MCS_ANT_AB_MSK);
-
 	return sta_id;
 
 }
@@ -408,9 +401,9 @@
 
 	struct iwl_host_cmd cmd = {
 		.id = REPLY_REMOVE_STA,
-		.len = sizeof(struct iwl_rem_sta_cmd),
+		.len = { sizeof(struct iwl_rem_sta_cmd), },
 		.flags = CMD_SYNC,
-		.data = &rm_sta_cmd,
+		.data = { &rm_sta_cmd, },
 	};
 
 	memset(&rm_sta_cmd, 0, sizeof(rm_sta_cmd));
@@ -501,7 +494,8 @@
 
 	priv->num_stations--;
 
-	BUG_ON(priv->num_stations < 0);
+	if (WARN_ON(priv->num_stations < 0))
+		priv->num_stations = 0;
 
 	spin_unlock_irqrestore(&priv->sta_lock, flags);
 
@@ -686,7 +680,8 @@
 
 		priv->stations[i].used &= ~IWL_STA_UCODE_ACTIVE;
 		priv->num_stations--;
-		BUG_ON(priv->num_stations < 0);
+		if (WARN_ON(priv->num_stations < 0))
+			priv->num_stations = 0;
 		kfree(priv->stations[i].lq);
 		priv->stations[i].lq = NULL;
 	}
@@ -765,9 +760,9 @@
 
 	struct iwl_host_cmd cmd = {
 		.id = REPLY_TX_LINK_QUALITY_CMD,
-		.len = sizeof(struct iwl_link_quality_cmd),
+		.len = { sizeof(struct iwl_link_quality_cmd), },
 		.flags = flags,
-		.data = lq,
+		.data = { lq, },
 	};
 
 	if (WARN_ON(lq->sta_id == IWL_INVALID_STATION))
@@ -782,7 +777,8 @@
 	spin_unlock_irqrestore(&priv->sta_lock, flags_spin);
 
 	iwl_dump_lq_cmd(priv, lq);
-	BUG_ON(init && (cmd.flags & CMD_ASYNC));
+	if (WARN_ON(init && (cmd.flags & CMD_ASYNC)))
+		return -EINVAL;
 
 	if (is_lq_table_valid(priv, ctx, lq))
 		ret = iwl_send_cmd(priv, &cmd);
diff -druN linux-2.6.39-libre/drivers/net/wireless/iwlwifi/iwl-sta.h linux-3.0-rc7-libre/drivers/net/wireless/iwlwifi/iwl-sta.h
--- linux-2.6.39-libre/drivers/net/wireless/iwlwifi/iwl-sta.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/iwlwifi/iwl-sta.h	2011-07-11 19:51:52.000000000 -0400
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2003 - 2011 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 -druN linux-2.6.39-libre/drivers/net/wireless/iwlwifi/iwl-sv-open.c linux-3.0-rc7-libre/drivers/net/wireless/iwlwifi/iwl-sv-open.c
--- linux-2.6.39-libre/drivers/net/wireless/iwlwifi/iwl-sv-open.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/net/wireless/iwlwifi/iwl-sv-open.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,640 @@
+/******************************************************************************
+ *
+ * This file is provided under a dual BSD/GPLv2 license.  When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * Copyright(c) 2010 - 2011 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
+ * USA
+ *
+ * The full GNU General Public License is included in this distribution
+ * in the file called LICENSE.GPL.
+ *
+ * Contact Information:
+ *  Intel Linux Wireless <ilw@linux.intel.com>
+ * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+ *
+ * BSD LICENSE
+ *
+ * Copyright(c) 2010 - 2011 Intel Corporation. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *  * Neither the name Intel Corporation nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *****************************************************************************/
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <net/net_namespace.h>
+#include <linux/netdevice.h>
+#include <net/cfg80211.h>
+#include <net/mac80211.h>
+#include <net/netlink.h>
+
+
+#include "iwl-dev.h"
+#include "iwl-core.h"
+#include "iwl-debug.h"
+#include "iwl-fh.h"
+#include "iwl-io.h"
+#include "iwl-agn.h"
+#include "iwl-testmode.h"
+
+
+/* The TLVs used in the gnl message policy between the kernel module and
+ * user space application. iwl_testmode_gnl_msg_policy is to be carried
+ * through the NL80211_CMD_TESTMODE channel regulated by nl80211.
+ * See iwl-testmode.h
+ */
+static
+struct nla_policy iwl_testmode_gnl_msg_policy[IWL_TM_ATTR_MAX] = {
+	[IWL_TM_ATTR_COMMAND] = { .type = NLA_U32, },
+
+	[IWL_TM_ATTR_UCODE_CMD_ID] = { .type = NLA_U8, },
+	[IWL_TM_ATTR_UCODE_CMD_DATA] = { .type = NLA_UNSPEC, },
+
+	[IWL_TM_ATTR_REG_OFFSET] = { .type = NLA_U32, },
+	[IWL_TM_ATTR_REG_VALUE8] = { .type = NLA_U8, },
+	[IWL_TM_ATTR_REG_VALUE32] = { .type = NLA_U32, },
+
+	[IWL_TM_ATTR_SYNC_RSP] = { .type = NLA_UNSPEC, },
+	[IWL_TM_ATTR_UCODE_RX_PKT] = { .type = NLA_UNSPEC, },
+
+	[IWL_TM_ATTR_EEPROM] = { .type = NLA_UNSPEC, },
+
+	[IWL_TM_ATTR_TRACE_ADDR] = { .type = NLA_UNSPEC, },
+	[IWL_TM_ATTR_TRACE_DATA] = { .type = NLA_UNSPEC, },
+
+	[IWL_TM_ATTR_FIXRATE] = { .type = NLA_U32, },
+};
+
+/*
+ * See the struct iwl_rx_packet in iwl-commands.h for the format of the
+ * received events from the device
+ */
+static inline int get_event_length(struct iwl_rx_mem_buffer *rxb)
+{
+	struct iwl_rx_packet *pkt = rxb_addr(rxb);
+	if (pkt)
+		return le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK;
+	else
+		return 0;
+}
+
+
+/*
+ * This function multicasts the spontaneous messages from the device to the
+ * user space. It is invoked whenever there is a received messages
+ * from the device. This function is called within the ISR of the rx handlers
+ * in iwlagn driver.
+ *
+ * The parsing of the message content is left to the user space application,
+ * The message content is treated as unattacked raw data and is encapsulated
+ * with IWL_TM_ATTR_UCODE_RX_PKT multicasting to the user space.
+ *
+ * @priv: the instance of iwlwifi device
+ * @rxb: pointer to rx data content received by the ISR
+ *
+ * See the message policies and TLVs in iwl_testmode_gnl_msg_policy[].
+ * For the messages multicasting to the user application, the mandatory
+ * TLV fields are :
+ *	IWL_TM_ATTR_COMMAND must be IWL_TM_CMD_DEV2APP_UCODE_RX_PKT
+ *	IWL_TM_ATTR_UCODE_RX_PKT for carrying the message content
+ */
+
+static void iwl_testmode_ucode_rx_pkt(struct iwl_priv *priv,
+				struct iwl_rx_mem_buffer *rxb)
+{
+	struct ieee80211_hw *hw = priv->hw;
+	struct sk_buff *skb;
+	void *data;
+	int length;
+
+	data = (void *)rxb_addr(rxb);
+	length = get_event_length(rxb);
+
+	if (!data || length == 0)
+		return;
+
+	skb = cfg80211_testmode_alloc_event_skb(hw->wiphy, 20 + length,
+								GFP_ATOMIC);
+	if (skb == NULL) {
+		IWL_DEBUG_INFO(priv,
+			 "Run out of memory for messages to user space ?\n");
+		return;
+	}
+	NLA_PUT_U32(skb, IWL_TM_ATTR_COMMAND, IWL_TM_CMD_DEV2APP_UCODE_RX_PKT);
+	NLA_PUT(skb, IWL_TM_ATTR_UCODE_RX_PKT, length, data);
+	cfg80211_testmode_event(skb, GFP_ATOMIC);
+	return;
+
+nla_put_failure:
+	kfree_skb(skb);
+	IWL_DEBUG_INFO(priv, "Ouch, overran buffer, check allocation!\n");
+}
+
+void iwl_testmode_init(struct iwl_priv *priv)
+{
+	priv->pre_rx_handler = iwl_testmode_ucode_rx_pkt;
+	priv->testmode_trace.trace_enabled = false;
+}
+
+static void iwl_trace_cleanup(struct iwl_priv *priv)
+{
+	struct device *dev = &priv->pci_dev->dev;
+
+	if (priv->testmode_trace.trace_enabled) {
+		if (priv->testmode_trace.cpu_addr &&
+		    priv->testmode_trace.dma_addr)
+			dma_free_coherent(dev,
+					TRACE_TOTAL_SIZE,
+					priv->testmode_trace.cpu_addr,
+					priv->testmode_trace.dma_addr);
+		priv->testmode_trace.trace_enabled = false;
+		priv->testmode_trace.cpu_addr = NULL;
+		priv->testmode_trace.trace_addr = NULL;
+		priv->testmode_trace.dma_addr = 0;
+	}
+}
+
+
+void iwl_testmode_cleanup(struct iwl_priv *priv)
+{
+	iwl_trace_cleanup(priv);
+}
+
+/*
+ * This function handles the user application commands to the ucode.
+ *
+ * It retrieves the mandatory fields IWL_TM_ATTR_UCODE_CMD_ID and
+ * IWL_TM_ATTR_UCODE_CMD_DATA and calls to the handler to send the
+ * host command to the ucode.
+ *
+ * If any mandatory field is missing, -ENOMSG is replied to the user space
+ * application; otherwise, the actual execution result of the host command to
+ * ucode is replied.
+ *
+ * @hw: ieee80211_hw object that represents the device
+ * @tb: gnl message fields from the user space
+ */
+static int iwl_testmode_ucode(struct ieee80211_hw *hw, struct nlattr **tb)
+{
+	struct iwl_priv *priv = hw->priv;
+	struct iwl_host_cmd cmd;
+
+	memset(&cmd, 0, sizeof(struct iwl_host_cmd));
+
+	if (!tb[IWL_TM_ATTR_UCODE_CMD_ID] ||
+	    !tb[IWL_TM_ATTR_UCODE_CMD_DATA]) {
+		IWL_DEBUG_INFO(priv,
+			"Error finding ucode command mandatory fields\n");
+		return -ENOMSG;
+	}
+
+	cmd.id = nla_get_u8(tb[IWL_TM_ATTR_UCODE_CMD_ID]);
+	cmd.data[0] = nla_data(tb[IWL_TM_ATTR_UCODE_CMD_DATA]);
+	cmd.len[0] = nla_len(tb[IWL_TM_ATTR_UCODE_CMD_DATA]);
+	cmd.dataflags[0] = IWL_HCMD_DFL_NOCOPY;
+	IWL_INFO(priv, "testmode ucode command ID 0x%x, flags 0x%x,"
+				" len %d\n", cmd.id, cmd.flags, cmd.len[0]);
+	/* ok, let's submit the command to ucode */
+	return iwl_send_cmd(priv, &cmd);
+}
+
+
+/*
+ * This function handles the user application commands for register access.
+ *
+ * It retrieves command ID carried with IWL_TM_ATTR_COMMAND and calls to the
+ * handlers respectively.
+ *
+ * If it's an unknown commdn ID, -ENOSYS is returned; or -ENOMSG if the
+ * mandatory fields(IWL_TM_ATTR_REG_OFFSET,IWL_TM_ATTR_REG_VALUE32,
+ * IWL_TM_ATTR_REG_VALUE8) are missing; Otherwise 0 is replied indicating
+ * the success of the command execution.
+ *
+ * If IWL_TM_ATTR_COMMAND is IWL_TM_CMD_APP2DEV_REG_READ32, the register read
+ * value is returned with IWL_TM_ATTR_REG_VALUE32.
+ *
+ * @hw: ieee80211_hw object that represents the device
+ * @tb: gnl message fields from the user space
+ */
+static int iwl_testmode_reg(struct ieee80211_hw *hw, struct nlattr **tb)
+{
+	struct iwl_priv *priv = hw->priv;
+	u32 ofs, val32;
+	u8 val8;
+	struct sk_buff *skb;
+	int status = 0;
+
+	if (!tb[IWL_TM_ATTR_REG_OFFSET]) {
+		IWL_DEBUG_INFO(priv, "Error finding register offset\n");
+		return -ENOMSG;
+	}
+	ofs = nla_get_u32(tb[IWL_TM_ATTR_REG_OFFSET]);
+	IWL_INFO(priv, "testmode register access command offset 0x%x\n", ofs);
+
+	switch (nla_get_u32(tb[IWL_TM_ATTR_COMMAND])) {
+	case IWL_TM_CMD_APP2DEV_REG_READ32:
+		val32 = iwl_read32(priv, ofs);
+		IWL_INFO(priv, "32bit value to read 0x%x\n", val32);
+
+		skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy, 20);
+		if (!skb) {
+			IWL_DEBUG_INFO(priv, "Error allocating memory\n");
+			return -ENOMEM;
+		}
+		NLA_PUT_U32(skb, IWL_TM_ATTR_REG_VALUE32, val32);
+		status = cfg80211_testmode_reply(skb);
+		if (status < 0)
+			IWL_DEBUG_INFO(priv,
+				       "Error sending msg : %d\n", status);
+		break;
+	case IWL_TM_CMD_APP2DEV_REG_WRITE32:
+		if (!tb[IWL_TM_ATTR_REG_VALUE32]) {
+			IWL_DEBUG_INFO(priv,
+				       "Error finding value to write\n");
+			return -ENOMSG;
+		} else {
+			val32 = nla_get_u32(tb[IWL_TM_ATTR_REG_VALUE32]);
+			IWL_INFO(priv, "32bit value to write 0x%x\n", val32);
+			iwl_write32(priv, ofs, val32);
+		}
+		break;
+	case IWL_TM_CMD_APP2DEV_REG_WRITE8:
+		if (!tb[IWL_TM_ATTR_REG_VALUE8]) {
+			IWL_DEBUG_INFO(priv, "Error finding value to write\n");
+			return -ENOMSG;
+		} else {
+			val8 = nla_get_u8(tb[IWL_TM_ATTR_REG_VALUE8]);
+			IWL_INFO(priv, "8bit value to write 0x%x\n", val8);
+			iwl_write8(priv, ofs, val8);
+		}
+		break;
+	default:
+		IWL_DEBUG_INFO(priv, "Unknown testmode register command ID\n");
+		return -ENOSYS;
+	}
+
+	return status;
+
+nla_put_failure:
+	kfree_skb(skb);
+	return -EMSGSIZE;
+}
+
+
+static int iwl_testmode_cfg_init_calib(struct iwl_priv *priv)
+{
+	struct iwl_notification_wait calib_wait;
+	int ret;
+
+	iwlagn_init_notification_wait(priv, &calib_wait,
+				      CALIBRATION_COMPLETE_NOTIFICATION,
+				      NULL, NULL);
+	ret = iwlagn_init_alive_start(priv);
+	if (ret) {
+		IWL_DEBUG_INFO(priv,
+			"Error configuring init calibration: %d\n", ret);
+		goto cfg_init_calib_error;
+	}
+
+	ret = iwlagn_wait_notification(priv, &calib_wait, 2 * HZ);
+	if (ret)
+		IWL_DEBUG_INFO(priv, "Error detecting"
+			" CALIBRATION_COMPLETE_NOTIFICATION: %d\n", ret);
+	return ret;
+
+cfg_init_calib_error:
+	iwlagn_remove_notification(priv, &calib_wait);
+	return ret;
+}
+
+/*
+ * This function handles the user application commands for driver.
+ *
+ * It retrieves command ID carried with IWL_TM_ATTR_COMMAND and calls to the
+ * handlers respectively.
+ *
+ * If it's an unknown commdn ID, -ENOSYS is replied; otherwise, the returned
+ * value of the actual command execution is replied to the user application.
+ *
+ * If there's any message responding to the user space, IWL_TM_ATTR_SYNC_RSP
+ * is used for carry the message while IWL_TM_ATTR_COMMAND must set to
+ * IWL_TM_CMD_DEV2APP_SYNC_RSP.
+ *
+ * @hw: ieee80211_hw object that represents the device
+ * @tb: gnl message fields from the user space
+ */
+static int iwl_testmode_driver(struct ieee80211_hw *hw, struct nlattr **tb)
+{
+	struct iwl_priv *priv = hw->priv;
+	struct sk_buff *skb;
+	unsigned char *rsp_data_ptr = NULL;
+	int status = 0, rsp_data_len = 0;
+
+	switch (nla_get_u32(tb[IWL_TM_ATTR_COMMAND])) {
+	case IWL_TM_CMD_APP2DEV_GET_DEVICENAME:
+		rsp_data_ptr = (unsigned char *)priv->cfg->name;
+		rsp_data_len = strlen(priv->cfg->name);
+		skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy,
+							rsp_data_len + 20);
+		if (!skb) {
+			IWL_DEBUG_INFO(priv,
+				       "Error allocating memory\n");
+			return -ENOMEM;
+		}
+		NLA_PUT_U32(skb, IWL_TM_ATTR_COMMAND,
+			    IWL_TM_CMD_DEV2APP_SYNC_RSP);
+		NLA_PUT(skb, IWL_TM_ATTR_SYNC_RSP,
+			rsp_data_len, rsp_data_ptr);
+		status = cfg80211_testmode_reply(skb);
+		if (status < 0)
+			IWL_DEBUG_INFO(priv, "Error sending msg : %d\n",
+				       status);
+		break;
+
+	case IWL_TM_CMD_APP2DEV_LOAD_INIT_FW:
+		status = iwlagn_load_ucode_wait_alive(priv, &priv->ucode_init,
+					   UCODE_SUBTYPE_INIT, -1);
+		if (status)
+			IWL_DEBUG_INFO(priv,
+				"Error loading init ucode: %d\n", status);
+		break;
+
+	case IWL_TM_CMD_APP2DEV_CFG_INIT_CALIB:
+		iwl_testmode_cfg_init_calib(priv);
+		iwlagn_stop_device(priv);
+		break;
+
+	case IWL_TM_CMD_APP2DEV_LOAD_RUNTIME_FW:
+		status = iwlagn_load_ucode_wait_alive(priv,
+					   &priv->ucode_rt,
+					   UCODE_SUBTYPE_REGULAR,
+					   UCODE_SUBTYPE_REGULAR_NEW);
+		if (status) {
+			IWL_DEBUG_INFO(priv,
+				"Error loading runtime ucode: %d\n", status);
+			break;
+		}
+		status = iwl_alive_start(priv);
+		if (status)
+			IWL_DEBUG_INFO(priv,
+				"Error starting the device: %d\n", status);
+		break;
+
+	case IWL_TM_CMD_APP2DEV_GET_EEPROM:
+		if (priv->eeprom) {
+			skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy,
+				priv->cfg->base_params->eeprom_size + 20);
+			if (!skb) {
+				IWL_DEBUG_INFO(priv,
+				       "Error allocating memory\n");
+				return -ENOMEM;
+			}
+			NLA_PUT_U32(skb, IWL_TM_ATTR_COMMAND,
+				IWL_TM_CMD_DEV2APP_EEPROM_RSP);
+			NLA_PUT(skb, IWL_TM_ATTR_EEPROM,
+				priv->cfg->base_params->eeprom_size,
+				priv->eeprom);
+			status = cfg80211_testmode_reply(skb);
+			if (status < 0)
+				IWL_DEBUG_INFO(priv,
+					       "Error sending msg : %d\n",
+					       status);
+		} else
+			return -EFAULT;
+		break;
+
+	case IWL_TM_CMD_APP2DEV_FIXRATE_REQ:
+		if (!tb[IWL_TM_ATTR_FIXRATE]) {
+			IWL_DEBUG_INFO(priv,
+				       "Error finding fixrate setting\n");
+			return -ENOMSG;
+		}
+		priv->dbg_fixed_rate = nla_get_u32(tb[IWL_TM_ATTR_FIXRATE]);
+		break;
+
+	default:
+		IWL_DEBUG_INFO(priv, "Unknown testmode driver command ID\n");
+		return -ENOSYS;
+	}
+	return status;
+
+nla_put_failure:
+	kfree_skb(skb);
+	return -EMSGSIZE;
+}
+
+
+/*
+ * This function handles the user application commands for uCode trace
+ *
+ * It retrieves command ID carried with IWL_TM_ATTR_COMMAND and calls to the
+ * handlers respectively.
+ *
+ * If it's an unknown commdn ID, -ENOSYS is replied; otherwise, the returned
+ * value of the actual command execution is replied to the user application.
+ *
+ * @hw: ieee80211_hw object that represents the device
+ * @tb: gnl message fields from the user space
+ */
+static int iwl_testmode_trace(struct ieee80211_hw *hw, struct nlattr **tb)
+{
+	struct iwl_priv *priv = hw->priv;
+	struct sk_buff *skb;
+	int status = 0;
+	struct device *dev = &priv->pci_dev->dev;
+
+	switch (nla_get_u32(tb[IWL_TM_ATTR_COMMAND])) {
+	case IWL_TM_CMD_APP2DEV_BEGIN_TRACE:
+		if (priv->testmode_trace.trace_enabled)
+			return -EBUSY;
+
+		priv->testmode_trace.cpu_addr =
+			dma_alloc_coherent(dev,
+					   TRACE_TOTAL_SIZE,
+					   &priv->testmode_trace.dma_addr,
+					   GFP_KERNEL);
+		if (!priv->testmode_trace.cpu_addr)
+			return -ENOMEM;
+		priv->testmode_trace.trace_enabled = true;
+		priv->testmode_trace.trace_addr = (u8 *)PTR_ALIGN(
+			priv->testmode_trace.cpu_addr, 0x100);
+		memset(priv->testmode_trace.trace_addr, 0x03B,
+			TRACE_BUFF_SIZE);
+		skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy,
+			sizeof(priv->testmode_trace.dma_addr) + 20);
+		if (!skb) {
+			IWL_DEBUG_INFO(priv,
+				"Error allocating memory\n");
+			iwl_trace_cleanup(priv);
+			return -ENOMEM;
+		}
+		NLA_PUT(skb, IWL_TM_ATTR_TRACE_ADDR,
+			sizeof(priv->testmode_trace.dma_addr),
+			(u64 *)&priv->testmode_trace.dma_addr);
+		status = cfg80211_testmode_reply(skb);
+		if (status < 0) {
+			IWL_DEBUG_INFO(priv,
+				       "Error sending msg : %d\n",
+				       status);
+		}
+		break;
+
+	case IWL_TM_CMD_APP2DEV_END_TRACE:
+		iwl_trace_cleanup(priv);
+		break;
+
+	case IWL_TM_CMD_APP2DEV_READ_TRACE:
+		if (priv->testmode_trace.trace_enabled &&
+		    priv->testmode_trace.trace_addr) {
+			skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy,
+				20 + TRACE_BUFF_SIZE);
+			if (skb == NULL) {
+				IWL_DEBUG_INFO(priv,
+					"Error allocating memory\n");
+				return -ENOMEM;
+			}
+			NLA_PUT(skb, IWL_TM_ATTR_TRACE_DATA,
+				TRACE_BUFF_SIZE,
+				priv->testmode_trace.trace_addr);
+			status = cfg80211_testmode_reply(skb);
+			if (status < 0) {
+				IWL_DEBUG_INFO(priv,
+				       "Error sending msg : %d\n", status);
+			}
+		} else
+			return -EFAULT;
+		break;
+
+	default:
+		IWL_DEBUG_INFO(priv, "Unknown testmode mem command ID\n");
+		return -ENOSYS;
+	}
+	return status;
+
+nla_put_failure:
+	kfree_skb(skb);
+	if (nla_get_u32(tb[IWL_TM_ATTR_COMMAND]) ==
+	    IWL_TM_CMD_APP2DEV_BEGIN_TRACE)
+		iwl_trace_cleanup(priv);
+	return -EMSGSIZE;
+}
+
+/* The testmode gnl message handler that takes the gnl message from the
+ * user space and parses it per the policy iwl_testmode_gnl_msg_policy, then
+ * invoke the corresponding handlers.
+ *
+ * This function is invoked when there is user space application sending
+ * gnl message through the testmode tunnel NL80211_CMD_TESTMODE regulated
+ * by nl80211.
+ *
+ * It retrieves the mandatory field, IWL_TM_ATTR_COMMAND, before
+ * dispatching it to the corresponding handler.
+ *
+ * If IWL_TM_ATTR_COMMAND is missing, -ENOMSG is replied to user application;
+ * -ENOSYS is replied to the user application if the command is unknown;
+ * Otherwise, the command is dispatched to the respective handler.
+ *
+ * @hw: ieee80211_hw object that represents the device
+ * @data: pointer to user space message
+ * @len: length in byte of @data
+ */
+int iwl_testmode_cmd(struct ieee80211_hw *hw, void *data, int len)
+{
+	struct nlattr *tb[IWL_TM_ATTR_MAX - 1];
+	struct iwl_priv *priv = hw->priv;
+	int result;
+
+	result = nla_parse(tb, IWL_TM_ATTR_MAX - 1, data, len,
+			iwl_testmode_gnl_msg_policy);
+	if (result != 0) {
+		IWL_DEBUG_INFO(priv,
+			       "Error parsing the gnl message : %d\n", result);
+		return result;
+	}
+
+	/* IWL_TM_ATTR_COMMAND is absolutely mandatory */
+	if (!tb[IWL_TM_ATTR_COMMAND]) {
+		IWL_DEBUG_INFO(priv, "Error finding testmode command type\n");
+		return -ENOMSG;
+	}
+	/* in case multiple accesses to the device happens */
+	mutex_lock(&priv->mutex);
+
+	switch (nla_get_u32(tb[IWL_TM_ATTR_COMMAND])) {
+	case IWL_TM_CMD_APP2DEV_UCODE:
+		IWL_DEBUG_INFO(priv, "testmode cmd to uCode\n");
+		result = iwl_testmode_ucode(hw, tb);
+		break;
+	case IWL_TM_CMD_APP2DEV_REG_READ32:
+	case IWL_TM_CMD_APP2DEV_REG_WRITE32:
+	case IWL_TM_CMD_APP2DEV_REG_WRITE8:
+		IWL_DEBUG_INFO(priv, "testmode cmd to register\n");
+		result = iwl_testmode_reg(hw, tb);
+		break;
+	case IWL_TM_CMD_APP2DEV_GET_DEVICENAME:
+	case IWL_TM_CMD_APP2DEV_LOAD_INIT_FW:
+	case IWL_TM_CMD_APP2DEV_CFG_INIT_CALIB:
+	case IWL_TM_CMD_APP2DEV_LOAD_RUNTIME_FW:
+	case IWL_TM_CMD_APP2DEV_GET_EEPROM:
+	case IWL_TM_CMD_APP2DEV_FIXRATE_REQ:
+		IWL_DEBUG_INFO(priv, "testmode cmd to driver\n");
+		result = iwl_testmode_driver(hw, tb);
+		break;
+
+	case IWL_TM_CMD_APP2DEV_BEGIN_TRACE:
+	case IWL_TM_CMD_APP2DEV_END_TRACE:
+	case IWL_TM_CMD_APP2DEV_READ_TRACE:
+		IWL_DEBUG_INFO(priv, "testmode uCode trace cmd to driver\n");
+		result = iwl_testmode_trace(hw, tb);
+		break;
+
+	default:
+		IWL_DEBUG_INFO(priv, "Unknown testmode command\n");
+		result = -ENOSYS;
+		break;
+	}
+
+	mutex_unlock(&priv->mutex);
+	return result;
+}
diff -druN linux-2.6.39-libre/drivers/net/wireless/iwlwifi/iwl-testmode.h linux-3.0-rc7-libre/drivers/net/wireless/iwlwifi/iwl-testmode.h
--- linux-2.6.39-libre/drivers/net/wireless/iwlwifi/iwl-testmode.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/net/wireless/iwlwifi/iwl-testmode.h	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,185 @@
+/******************************************************************************
+ *
+ * This file is provided under a dual BSD/GPLv2 license.  When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * Copyright(c) 2010 - 2011 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
+ * USA
+ *
+ * The full GNU General Public License is included in this distribution
+ * in the file called LICENSE.GPL.
+ *
+ * Contact Information:
+ *  Intel Linux Wireless <ilw@linux.intel.com>
+ * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
+ *
+ * BSD LICENSE
+ *
+ * Copyright(c) 2010 - 2011 Intel Corporation. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *  * Neither the name Intel Corporation nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *****************************************************************************/
+#ifndef __IWL_TESTMODE_H__
+#define __IWL_TESTMODE_H__
+
+#include <linux/types.h>
+
+
+/* Commands from user space to kernel space(IWL_TM_CMD_ID_APP2DEV_XX) and
+ * from and kernel space to user space(IWL_TM_CMD_ID_DEV2APP_XX).
+ * The command ID is carried with IWL_TM_ATTR_COMMAND. There are three types of
+ * of command from user space and two types of command from kernel space.
+ * See below.
+ */
+enum iwl_tm_cmd_t {
+	/* commands from user application to the uCode,
+	 * the actual uCode host command ID is carried with
+	 * IWL_TM_ATTR_UCODE_CMD_ID */
+	IWL_TM_CMD_APP2DEV_UCODE = 1,
+
+	/* commands from user applicaiton to access register */
+	IWL_TM_CMD_APP2DEV_REG_READ32,
+	IWL_TM_CMD_APP2DEV_REG_WRITE32,
+	IWL_TM_CMD_APP2DEV_REG_WRITE8,
+
+	/* commands fom user space for pure driver level operations */
+	IWL_TM_CMD_APP2DEV_GET_DEVICENAME,
+	IWL_TM_CMD_APP2DEV_LOAD_INIT_FW,
+	IWL_TM_CMD_APP2DEV_CFG_INIT_CALIB,
+	IWL_TM_CMD_APP2DEV_LOAD_RUNTIME_FW,
+	IWL_TM_CMD_APP2DEV_GET_EEPROM,
+	IWL_TM_CMD_APP2DEV_FIXRATE_REQ,
+	/* if there is other new command for the driver layer operation,
+	 * append them here */
+
+	/* commands fom user space for uCode trace operations */
+	IWL_TM_CMD_APP2DEV_BEGIN_TRACE,
+	IWL_TM_CMD_APP2DEV_END_TRACE,
+	IWL_TM_CMD_APP2DEV_READ_TRACE,
+
+	/* commands from kernel space to carry the synchronous response
+	 * to user application */
+	IWL_TM_CMD_DEV2APP_SYNC_RSP,
+
+	/* commands from kernel space to multicast the spontaneous messages
+	 * to user application */
+	IWL_TM_CMD_DEV2APP_UCODE_RX_PKT,
+
+	/* commands from kernel space to carry the eeprom response
+	 * to user application */
+	IWL_TM_CMD_DEV2APP_EEPROM_RSP,
+
+	IWL_TM_CMD_MAX,
+};
+
+enum iwl_tm_attr_t {
+	IWL_TM_ATTR_NOT_APPLICABLE = 0,
+
+	/* From user space to kernel space:
+	 * the command either destines to ucode, driver, or register;
+	 * See enum iwl_tm_cmd_t.
+	 *
+	 * From kernel space to user space:
+	 * the command either carries synchronous response,
+	 * or the spontaneous message multicast from the device;
+	 * See enum iwl_tm_cmd_t. */
+	IWL_TM_ATTR_COMMAND,
+
+	/* When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_APP2DEV_UCODE,
+	 * The mandatory fields are :
+	 * IWL_TM_ATTR_UCODE_CMD_ID for recognizable command ID;
+	 * IWL_TM_ATTR_COMMAND_FLAG for the flags of the commands;
+	 * The optional fields are:
+	 * IWL_TM_ATTR_UCODE_CMD_DATA for the actual command payload
+	 * to the ucode */
+	IWL_TM_ATTR_UCODE_CMD_ID,
+	IWL_TM_ATTR_UCODE_CMD_DATA,
+
+	/* When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_APP2DEV_REG_XXX,
+	 * The mandatory fields are:
+	 * IWL_TM_ATTR_REG_OFFSET for the offset of the target register;
+	 * IWL_TM_ATTR_REG_VALUE8 or IWL_TM_ATTR_REG_VALUE32 for value */
+	IWL_TM_ATTR_REG_OFFSET,
+	IWL_TM_ATTR_REG_VALUE8,
+	IWL_TM_ATTR_REG_VALUE32,
+
+	/* When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_DEV2APP_SYNC_RSP,
+	 * The mandatory fields are:
+	 * IWL_TM_ATTR_SYNC_RSP for the data content responding to the user
+	 * application command */
+	IWL_TM_ATTR_SYNC_RSP,
+	/* When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_DEV2APP_UCODE_RX_PKT,
+	 * The mandatory fields are:
+	 * IWL_TM_ATTR_UCODE_RX_PKT for the data content multicast to the user
+	 * application */
+	IWL_TM_ATTR_UCODE_RX_PKT,
+
+	/* When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_DEV2APP_EEPROM,
+	 * The mandatory fields are:
+	 * IWL_TM_ATTR_EEPROM for the data content responging to the user
+	 * application */
+	IWL_TM_ATTR_EEPROM,
+
+	/* When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_APP2DEV_XXX_TRACE,
+	 * The mandatory fields are:
+	 * IWL_TM_ATTR_MEM_TRACE_ADDR for the trace address
+	 */
+	IWL_TM_ATTR_TRACE_ADDR,
+	IWL_TM_ATTR_TRACE_DATA,
+
+	/* When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_APP2DEV_FIXRATE_REQ,
+	 * The mandatory fields are:
+	 * IWL_TM_ATTR_FIXRATE for the fixed rate
+	 */
+	IWL_TM_ATTR_FIXRATE,
+
+	IWL_TM_ATTR_MAX,
+};
+
+/* uCode trace buffer */
+#define TRACE_BUFF_SIZE		0x20000
+#define TRACE_BUFF_PADD		0x2000
+#define TRACE_TOTAL_SIZE	(TRACE_BUFF_SIZE + TRACE_BUFF_PADD)
+
+#endif
diff -druN linux-2.6.39-libre/drivers/net/wireless/iwlwifi/iwl-tx.c linux-3.0-rc7-libre/drivers/net/wireless/iwlwifi/iwl-tx.c
--- linux-2.6.39-libre/drivers/net/wireless/iwlwifi/iwl-tx.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/iwlwifi/iwl-tx.c	2011-07-11 19:51:52.000000000 -0400
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2003 - 2011 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.
@@ -32,6 +32,7 @@
 #include <linux/slab.h>
 #include <net/mac80211.h>
 #include "iwl-eeprom.h"
+#include "iwl-agn.h"
 #include "iwl-dev.h"
 #include "iwl-core.h"
 #include "iwl-sta.h"
@@ -85,6 +86,159 @@
 	txq->need_update = 0;
 }
 
+static inline dma_addr_t iwl_tfd_tb_get_addr(struct iwl_tfd *tfd, u8 idx)
+{
+	struct iwl_tfd_tb *tb = &tfd->tbs[idx];
+
+	dma_addr_t addr = get_unaligned_le32(&tb->lo);
+	if (sizeof(dma_addr_t) > sizeof(u32))
+		addr |=
+		((dma_addr_t)(le16_to_cpu(tb->hi_n_len) & 0xF) << 16) << 16;
+
+	return addr;
+}
+
+static inline u16 iwl_tfd_tb_get_len(struct iwl_tfd *tfd, u8 idx)
+{
+	struct iwl_tfd_tb *tb = &tfd->tbs[idx];
+
+	return le16_to_cpu(tb->hi_n_len) >> 4;
+}
+
+static inline void iwl_tfd_set_tb(struct iwl_tfd *tfd, u8 idx,
+				  dma_addr_t addr, u16 len)
+{
+	struct iwl_tfd_tb *tb = &tfd->tbs[idx];
+	u16 hi_n_len = len << 4;
+
+	put_unaligned_le32(addr, &tb->lo);
+	if (sizeof(dma_addr_t) > sizeof(u32))
+		hi_n_len |= ((addr >> 16) >> 16) & 0xF;
+
+	tb->hi_n_len = cpu_to_le16(hi_n_len);
+
+	tfd->num_tbs = idx + 1;
+}
+
+static inline u8 iwl_tfd_get_num_tbs(struct iwl_tfd *tfd)
+{
+	return tfd->num_tbs & 0x1f;
+}
+
+static void iwlagn_unmap_tfd(struct iwl_priv *priv, struct iwl_cmd_meta *meta,
+			     struct iwl_tfd *tfd, int dma_dir)
+{
+	struct pci_dev *dev = priv->pci_dev;
+	int i;
+	int num_tbs;
+
+	/* Sanity check on number of chunks */
+	num_tbs = iwl_tfd_get_num_tbs(tfd);
+
+	if (num_tbs >= IWL_NUM_OF_TBS) {
+		IWL_ERR(priv, "Too many chunks: %i\n", num_tbs);
+		/* @todo issue fatal error, it is quite serious situation */
+		return;
+	}
+
+	/* Unmap tx_cmd */
+	if (num_tbs)
+		pci_unmap_single(dev,
+				dma_unmap_addr(meta, mapping),
+				dma_unmap_len(meta, len),
+				PCI_DMA_BIDIRECTIONAL);
+
+	/* Unmap chunks, if any. */
+	for (i = 1; i < num_tbs; i++)
+		pci_unmap_single(dev, iwl_tfd_tb_get_addr(tfd, i),
+				iwl_tfd_tb_get_len(tfd, i), dma_dir);
+}
+
+/**
+ * iwlagn_txq_free_tfd - Free all chunks referenced by TFD [txq->q.read_ptr]
+ * @priv - driver private data
+ * @txq - tx queue
+ *
+ * Does NOT advance any TFD circular buffer read/write indexes
+ * Does NOT free the TFD itself (which is within circular buffer)
+ */
+void iwlagn_txq_free_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq)
+{
+	struct iwl_tfd *tfd_tmp = txq->tfds;
+	int index = txq->q.read_ptr;
+
+	iwlagn_unmap_tfd(priv, &txq->meta[index], &tfd_tmp[index],
+			 PCI_DMA_TODEVICE);
+
+	/* free SKB */
+	if (txq->txb) {
+		struct sk_buff *skb;
+
+		skb = txq->txb[txq->q.read_ptr].skb;
+
+		/* can be called from irqs-disabled context */
+		if (skb) {
+			dev_kfree_skb_any(skb);
+			txq->txb[txq->q.read_ptr].skb = NULL;
+		}
+	}
+}
+
+int iwlagn_txq_attach_buf_to_tfd(struct iwl_priv *priv,
+				 struct iwl_tx_queue *txq,
+				 dma_addr_t addr, u16 len,
+				 u8 reset)
+{
+	struct iwl_queue *q;
+	struct iwl_tfd *tfd, *tfd_tmp;
+	u32 num_tbs;
+
+	q = &txq->q;
+	tfd_tmp = txq->tfds;
+	tfd = &tfd_tmp[q->write_ptr];
+
+	if (reset)
+		memset(tfd, 0, sizeof(*tfd));
+
+	num_tbs = iwl_tfd_get_num_tbs(tfd);
+
+	/* Each TFD can point to a maximum 20 Tx buffers */
+	if (num_tbs >= IWL_NUM_OF_TBS) {
+		IWL_ERR(priv, "Error can not send more than %d chunks\n",
+			  IWL_NUM_OF_TBS);
+		return -EINVAL;
+	}
+
+	if (WARN_ON(addr & ~DMA_BIT_MASK(36)))
+		return -EINVAL;
+
+	if (unlikely(addr & ~IWL_TX_DMA_MASK))
+		IWL_ERR(priv, "Unaligned address = %llx\n",
+			  (unsigned long long)addr);
+
+	iwl_tfd_set_tb(tfd, num_tbs, addr, len);
+
+	return 0;
+}
+
+/*
+ * Tell nic where to find circular buffer of Tx Frame Descriptors for
+ * given Tx queue, and enable the DMA channel used for that queue.
+ *
+ * supports up to 16 Tx queues in DRAM, mapped to up to 8 Tx DMA
+ * channels supported in hardware.
+ */
+static int iwlagn_tx_queue_init(struct iwl_priv *priv, struct iwl_tx_queue *txq)
+{
+	int txq_id = txq->q.id;
+
+	/* Circular buffer (TFD queue in DRAM) physical base address */
+	iwl_write_direct32(priv, FH_MEM_CBBC_QUEUE(txq_id),
+			     txq->q.dma_addr >> 8);
+
+	return 0;
+}
+
 /**
  * iwl_tx_queue_unmap -  Unmap any remaining DMA mappings and free skb's
  */
@@ -97,7 +251,7 @@
 		return;
 
 	 while (q->write_ptr != q->read_ptr) {
-		priv->cfg->ops->lib->txq_free_tfd(priv, txq);
+		iwlagn_txq_free_tfd(priv, txq);
 		q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd);
 	}
 }
@@ -149,32 +303,20 @@
 	struct iwl_tx_queue *txq = &priv->txq[priv->cmd_queue];
 	struct iwl_queue *q = &txq->q;
 	int i;
-	bool huge = false;
 
 	if (q->n_bd == 0)
 		return;
 
 	while (q->read_ptr != q->write_ptr) {
-		/* we have no way to tell if it is a huge cmd ATM */
-		i = get_cmd_index(q, q->read_ptr, 0);
+		i = get_cmd_index(q, q->read_ptr);
 
-		if (txq->meta[i].flags & CMD_SIZE_HUGE)
-			huge = true;
-		else
-			pci_unmap_single(priv->pci_dev,
-					 dma_unmap_addr(&txq->meta[i], mapping),
-					 dma_unmap_len(&txq->meta[i], len),
+		if (txq->meta[i].flags & CMD_MAPPED) {
+			iwlagn_unmap_tfd(priv, &txq->meta[i], &txq->tfds[i],
 					 PCI_DMA_BIDIRECTIONAL);
+			txq->meta[i].flags = 0;
+		}
 
-	     q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd);
-	}
-
-	if (huge) {
-		i = q->n_window;
-		pci_unmap_single(priv->pci_dev,
-				 dma_unmap_addr(&txq->meta[i], mapping),
-				 dma_unmap_len(&txq->meta[i], len),
-				 PCI_DMA_BIDIRECTIONAL);
+		q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd);
 	}
 }
 
@@ -195,7 +337,7 @@
 	iwl_cmd_queue_unmap(priv);
 
 	/* De-alloc array of command/tx buffers */
-	for (i = 0; i <= TFD_CMD_SLOTS; i++)
+	for (i = 0; i < TFD_CMD_SLOTS; i++)
 		kfree(txq->cmd[i]);
 
 	/* De-alloc circular buffer of TFDs */
@@ -233,7 +375,6 @@
  * reclaiming packets (on 'tx done IRQ), if free space become > high mark,
  * Tx queue resumed.
  *
- * See more detailed info in iwl-4965-hw.h.
  ***************************************************/
 
 int iwl_queue_space(const struct iwl_queue *q)
@@ -265,11 +406,13 @@
 
 	/* count must be power-of-two size, otherwise iwl_queue_inc_wrap
 	 * and iwl_queue_dec_wrap are broken. */
-	BUG_ON(!is_power_of_2(count));
+	if (WARN_ON(!is_power_of_2(count)))
+		return -EINVAL;
 
 	/* slots_num must be power-of-two size, otherwise
 	 * get_cmd_index is broken. */
-	BUG_ON(!is_power_of_2(slots_num));
+	if (WARN_ON(!is_power_of_2(slots_num)))
+		return -EINVAL;
 
 	q->low_mark = q->n_window / 4;
 	if (q->low_mark < 4)
@@ -334,33 +477,17 @@
 {
 	int i, len;
 	int ret;
-	int actual_slots = slots_num;
-
-	/*
-	 * Alloc buffer array for commands (Tx or other types of commands).
-	 * For the command queue (#4/#9), allocate command space + one big
-	 * command for scan, since scan command is very huge; the system will
-	 * not have two scans at the same time, so only one is needed.
-	 * For normal Tx queues (all other queues), no super-size command
-	 * space is needed.
-	 */
-	if (txq_id == priv->cmd_queue)
-		actual_slots++;
 
-	txq->meta = kzalloc(sizeof(struct iwl_cmd_meta) * actual_slots,
+	txq->meta = kzalloc(sizeof(struct iwl_cmd_meta) * slots_num,
 			    GFP_KERNEL);
-	txq->cmd = kzalloc(sizeof(struct iwl_device_cmd *) * actual_slots,
+	txq->cmd = kzalloc(sizeof(struct iwl_device_cmd *) * slots_num,
 			   GFP_KERNEL);
 
 	if (!txq->meta || !txq->cmd)
 		goto out_free_arrays;
 
 	len = sizeof(struct iwl_device_cmd);
-	for (i = 0; i < actual_slots; i++) {
-		/* only happens for cmd queue */
-		if (i == slots_num)
-			len = IWL_MAX_CMD_SIZE;
-
+	for (i = 0; i < slots_num; i++) {
 		txq->cmd[i] = kmalloc(len, GFP_KERNEL);
 		if (!txq->cmd[i])
 			goto err;
@@ -386,14 +513,16 @@
 	BUILD_BUG_ON(TFD_QUEUE_SIZE_MAX & (TFD_QUEUE_SIZE_MAX - 1));
 
 	/* 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);
+	ret = iwl_queue_init(priv, &txq->q, TFD_QUEUE_SIZE_MAX, slots_num, txq_id);
+	if (ret)
+		return ret;
 
 	/* Tell device where to find queue */
-	priv->cfg->ops->lib->txq_init(priv, txq);
+	iwlagn_tx_queue_init(priv, txq);
 
 	return 0;
 err:
-	for (i = 0; i < actual_slots; i++)
+	for (i = 0; i < slots_num; i++)
 		kfree(txq->cmd[i]);
 out_free_arrays:
 	kfree(txq->meta);
@@ -405,12 +534,7 @@
 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 == priv->cmd_queue)
-		actual_slots++;
-
-	memset(txq->meta, 0, sizeof(struct iwl_cmd_meta) * actual_slots);
+	memset(txq->meta, 0, sizeof(struct iwl_cmd_meta) * slots_num);
 
 	txq->need_update = 0;
 
@@ -418,7 +542,7 @@
 	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);
+	iwlagn_tx_queue_init(priv, txq);
 }
 
 /*************** HOST COMMAND QUEUE FUNCTIONS   *****/
@@ -440,22 +564,51 @@
 	struct iwl_cmd_meta *out_meta;
 	dma_addr_t phys_addr;
 	unsigned long flags;
-	int len;
 	u32 idx;
-	u16 fix_size;
+	u16 copy_size, cmd_size;
 	bool is_ct_kill = false;
+	bool had_nocopy = false;
+	int i;
+	u8 *cmd_dest;
+#ifdef CONFIG_IWLWIFI_DEVICE_TRACING
+	const void *trace_bufs[IWL_MAX_CMD_TFDS + 1] = {};
+	int trace_lens[IWL_MAX_CMD_TFDS + 1] = {};
+	int trace_idx;
+#endif
 
-	cmd->len = priv->cfg->ops->utils->get_hcmd_size(cmd->id, cmd->len);
-	fix_size = (u16)(cmd->len + sizeof(out_cmd->hdr));
+	if (test_bit(STATUS_FW_ERROR, &priv->status)) {
+		IWL_WARN(priv, "fw recovery, no hcmd send\n");
+		return -EIO;
+	}
 
-	/* 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
-	 * 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);
+	copy_size = sizeof(out_cmd->hdr);
+	cmd_size = sizeof(out_cmd->hdr);
+
+	/* need one for the header if the first is NOCOPY */
+	BUILD_BUG_ON(IWL_MAX_CMD_TFDS > IWL_NUM_OF_TBS - 1);
+
+	for (i = 0; i < IWL_MAX_CMD_TFDS; i++) {
+		if (!cmd->len[i])
+			continue;
+		if (cmd->dataflags[i] & IWL_HCMD_DFL_NOCOPY) {
+			had_nocopy = true;
+		} else {
+			/* NOCOPY must not be followed by normal! */
+			if (WARN_ON(had_nocopy))
+				return -EINVAL;
+			copy_size += cmd->len[i];
+		}
+		cmd_size += cmd->len[i];
+	}
+
+	/*
+	 * If any of the command structures end up being larger than
+	 * the TFD_MAX_PAYLOAD_SIZE and they aren't dynamically
+	 * allocated into separate TFDs, then we will need to
+	 * increase the size of the buffers.
+	 */
+	if (WARN_ON(copy_size > TFD_MAX_PAYLOAD_SIZE))
+		return -EINVAL;
 
 	if (iwl_is_rfkill(priv) || iwl_is_ctkill(priv)) {
 		IWL_WARN(priv, "Not sending command - %s KILL\n",
@@ -463,96 +616,120 @@
 		return -EIO;
 	}
 
+	spin_lock_irqsave(&priv->hcmd_lock, flags);
+
 	if (iwl_queue_space(q) < ((cmd->flags & CMD_ASYNC) ? 2 : 1)) {
+		spin_unlock_irqrestore(&priv->hcmd_lock, flags);
+
 		IWL_ERR(priv, "No space in command queue\n");
-		if (priv->cfg->ops->lib->tt_ops.ct_kill_check) {
-			is_ct_kill =
-				priv->cfg->ops->lib->tt_ops.ct_kill_check(priv);
-		}
+		is_ct_kill = iwl_check_for_ct_kill(priv);
 		if (!is_ct_kill) {
 			IWL_ERR(priv, "Restarting adapter due to queue full\n");
-			queue_work(priv->workqueue, &priv->restart);
+			iwlagn_fw_error(priv, false);
 		}
 		return -ENOSPC;
 	}
 
-	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);
+	idx = get_cmd_index(q, q->write_ptr);
 	out_cmd = txq->cmd[idx];
 	out_meta = &txq->meta[idx];
 
+	if (WARN_ON(out_meta->flags & CMD_MAPPED)) {
+		spin_unlock_irqrestore(&priv->hcmd_lock, flags);
+		return -ENOSPC;
+	}
+
 	memset(out_meta, 0, sizeof(*out_meta));	/* re-initialize to NULL */
-	out_meta->flags = cmd->flags;
 	if (cmd->flags & CMD_WANT_SKB)
 		out_meta->source = cmd;
 	if (cmd->flags & CMD_ASYNC)
 		out_meta->callback = cmd->callback;
 
-	out_cmd->hdr.cmd = cmd->id;
-	memcpy(&out_cmd->cmd.payload, cmd->data, cmd->len);
-
-	/* At this point, the out_cmd now has all of the incoming cmd
-	 * information */
+	/* set up the header */
 
+	out_cmd->hdr.cmd = cmd->id;
 	out_cmd->hdr.flags = 0;
 	out_cmd->hdr.sequence = cpu_to_le16(QUEUE_TO_SEQ(priv->cmd_queue) |
-			INDEX_TO_SEQ(q->write_ptr));
-	if (cmd->flags & CMD_SIZE_HUGE)
-		out_cmd->hdr.sequence |= SEQ_HUGE_FRAME;
-	len = sizeof(struct iwl_device_cmd);
-	if (idx == TFD_CMD_SLOTS)
-		len = IWL_MAX_CMD_SIZE;
+					    INDEX_TO_SEQ(q->write_ptr));
 
-#ifdef CONFIG_IWLWIFI_DEBUG
-	switch (out_cmd->hdr.cmd) {
-	case REPLY_TX_LINK_QUALITY_CMD:
-	case SENSITIVITY_CMD:
-		IWL_DEBUG_HC_DUMP(priv, "Sending command %s (#%x), seq: 0x%04X, "
-				"%d bytes at %d[%d]:%d\n",
-				get_cmd_string(out_cmd->hdr.cmd),
-				out_cmd->hdr.cmd,
-				le16_to_cpu(out_cmd->hdr.sequence), fix_size,
-				q->write_ptr, idx, priv->cmd_queue);
-		break;
-	default:
-		IWL_DEBUG_HC(priv, "Sending command %s (#%x), seq: 0x%04X, "
-				"%d bytes at %d[%d]:%d\n",
-				get_cmd_string(out_cmd->hdr.cmd),
-				out_cmd->hdr.cmd,
-				le16_to_cpu(out_cmd->hdr.sequence), fix_size,
-				q->write_ptr, idx, priv->cmd_queue);
+	/* and copy the data that needs to be copied */
+
+	cmd_dest = &out_cmd->cmd.payload[0];
+	for (i = 0; i < IWL_MAX_CMD_TFDS; i++) {
+		if (!cmd->len[i])
+			continue;
+		if (cmd->dataflags[i] & IWL_HCMD_DFL_NOCOPY)
+			break;
+		memcpy(cmd_dest, cmd->data[i], cmd->len[i]);
+		cmd_dest += cmd->len[i];
 	}
-#endif
-	txq->need_update = 1;
 
-	if (priv->cfg->ops->lib->txq_update_byte_cnt_tbl)
-		/* Set up entry in queue's byte count circular buffer */
-		priv->cfg->ops->lib->txq_update_byte_cnt_tbl(priv, txq, 0);
+	IWL_DEBUG_HC(priv, "Sending command %s (#%x), seq: 0x%04X, "
+			"%d bytes at %d[%d]:%d\n",
+			get_cmd_string(out_cmd->hdr.cmd),
+			out_cmd->hdr.cmd,
+			le16_to_cpu(out_cmd->hdr.sequence), cmd_size,
+			q->write_ptr, idx, priv->cmd_queue);
 
 	phys_addr = pci_map_single(priv->pci_dev, &out_cmd->hdr,
-				   fix_size, PCI_DMA_BIDIRECTIONAL);
+				   copy_size, PCI_DMA_BIDIRECTIONAL);
+	if (unlikely(pci_dma_mapping_error(priv->pci_dev, phys_addr))) {
+		idx = -ENOMEM;
+		goto out;
+	}
+
 	dma_unmap_addr_set(out_meta, mapping, phys_addr);
-	dma_unmap_len_set(out_meta, len, fix_size);
+	dma_unmap_len_set(out_meta, len, copy_size);
 
-	trace_iwlwifi_dev_hcmd(priv, &out_cmd->hdr, fix_size, cmd->flags);
+	iwlagn_txq_attach_buf_to_tfd(priv, txq, phys_addr, copy_size, 1);
+#ifdef CONFIG_IWLWIFI_DEVICE_TRACING
+	trace_bufs[0] = &out_cmd->hdr;
+	trace_lens[0] = copy_size;
+	trace_idx = 1;
+#endif
 
-	priv->cfg->ops->lib->txq_attach_buf_to_tfd(priv, txq,
-						   phys_addr, fix_size, 1,
-						   U32_PAD(cmd->len));
+	for (i = 0; i < IWL_MAX_CMD_TFDS; i++) {
+		if (!cmd->len[i])
+			continue;
+		if (!(cmd->dataflags[i] & IWL_HCMD_DFL_NOCOPY))
+			continue;
+		phys_addr = pci_map_single(priv->pci_dev, (void *)cmd->data[i],
+					   cmd->len[i], PCI_DMA_BIDIRECTIONAL);
+		if (pci_dma_mapping_error(priv->pci_dev, phys_addr)) {
+			iwlagn_unmap_tfd(priv, out_meta,
+					 &txq->tfds[q->write_ptr],
+					 PCI_DMA_BIDIRECTIONAL);
+			idx = -ENOMEM;
+			goto out;
+		}
+
+		iwlagn_txq_attach_buf_to_tfd(priv, txq, phys_addr,
+					     cmd->len[i], 0);
+#ifdef CONFIG_IWLWIFI_DEVICE_TRACING
+		trace_bufs[trace_idx] = cmd->data[i];
+		trace_lens[trace_idx] = cmd->len[i];
+		trace_idx++;
+#endif
+	}
+
+	out_meta->flags = cmd->flags | CMD_MAPPED;
+
+	txq->need_update = 1;
+
+	/* check that tracing gets all possible blocks */
+	BUILD_BUG_ON(IWL_MAX_CMD_TFDS + 1 != 3);
+#ifdef CONFIG_IWLWIFI_DEVICE_TRACING
+	trace_iwlwifi_dev_hcmd(priv, cmd->flags,
+			       trace_bufs[0], trace_lens[0],
+			       trace_bufs[1], trace_lens[1],
+			       trace_bufs[2], trace_lens[2]);
+#endif
 
 	/* Increment and update queue's write index */
 	q->write_ptr = iwl_queue_inc_wrap(q->write_ptr, q->n_bd);
 	iwl_txq_update_write_ptr(priv, txq);
 
+ out:
 	spin_unlock_irqrestore(&priv->hcmd_lock, flags);
 	return idx;
 }
@@ -564,8 +741,7 @@
  * need to be reclaimed. As result, some free space forms.  If there is
  * enough free space (> low mark), wake the stack that feeds us.
  */
-static void iwl_hcmd_queue_reclaim(struct iwl_priv *priv, int txq_id,
-				   int idx, int cmd_idx)
+static void iwl_hcmd_queue_reclaim(struct iwl_priv *priv, int txq_id, int idx)
 {
 	struct iwl_tx_queue *txq = &priv->txq[txq_id];
 	struct iwl_queue *q = &txq->q;
@@ -584,7 +760,7 @@
 		if (nfreed++ > 0) {
 			IWL_ERR(priv, "HCMD skipped: index (%d) %d %d\n", idx,
 					q->write_ptr, q->read_ptr);
-			queue_work(priv->workqueue, &priv->restart);
+			iwlagn_fw_error(priv, false);
 		}
 
 	}
@@ -605,10 +781,10 @@
 	int txq_id = SEQ_TO_QUEUE(sequence);
 	int index = SEQ_TO_INDEX(sequence);
 	int cmd_index;
-	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[priv->cmd_queue];
+	unsigned long flags;
 
 	/* 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
@@ -622,22 +798,11 @@
 		return;
 	}
 
-	/* 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_index = get_cmd_index(&txq->q, index);
 	cmd = txq->cmd[cmd_index];
 	meta = &txq->meta[cmd_index];
 
-	pci_unmap_single(priv->pci_dev,
-			 dma_unmap_addr(meta, mapping),
-			 dma_unmap_len(meta, len),
-			 PCI_DMA_BIDIRECTIONAL);
+	iwlagn_unmap_tfd(priv, meta, &txq->tfds[index], PCI_DMA_BIDIRECTIONAL);
 
 	/* Input error checking is done when commands are added to queue. */
 	if (meta->flags & CMD_WANT_SKB) {
@@ -646,7 +811,9 @@
 	} else if (meta->callback)
 		meta->callback(priv, cmd, pkt);
 
-	iwl_hcmd_queue_reclaim(priv, txq_id, index, cmd_index);
+	spin_lock_irqsave(&priv->hcmd_lock, flags);
+
+	iwl_hcmd_queue_reclaim(priv, txq_id, index);
 
 	if (!(meta->flags & CMD_ASYNC)) {
 		clear_bit(STATUS_HCMD_ACTIVE, &priv->status);
@@ -654,5 +821,9 @@
 			       get_cmd_string(cmd->hdr.cmd));
 		wake_up_interruptible(&priv->wait_command_queue);
 	}
+
+	/* Mark as unmapped */
 	meta->flags = 0;
+
+	spin_unlock_irqrestore(&priv->hcmd_lock, flags);
 }
diff -druN linux-2.6.39-libre/drivers/net/wireless/iwlwifi/Kconfig linux-3.0-rc7-libre/drivers/net/wireless/iwlwifi/Kconfig
--- linux-2.6.39-libre/drivers/net/wireless/iwlwifi/Kconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/iwlwifi/Kconfig	2011-07-11 19:51:52.000000000 -0400
@@ -102,6 +102,16 @@
 	  occur.
 endmenu
 
+config IWLWIFI_DEVICE_SVTOOL
+	bool "iwlwifi device svtool support"
+	depends on IWLAGN
+	select NL80211_TESTMODE
+	help
+	  This option enables the svtool support for iwlwifi device through
+	  NL80211_TESTMODE. svtool is a software validation tool that runs in
+	  the user space and interacts with the device in the kernel space
+	  through the generic netlink message via NL80211_TESTMODE channel.
+
 config IWL_P2P
 	bool "iwlwifi experimental P2P support"
 	depends on IWLAGN
diff -druN linux-2.6.39-libre/drivers/net/wireless/iwlwifi/Makefile linux-3.0-rc7-libre/drivers/net/wireless/iwlwifi/Makefile
--- linux-2.6.39-libre/drivers/net/wireless/iwlwifi/Makefile	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/iwlwifi/Makefile	2011-07-11 19:51:52.000000000 -0400
@@ -1,8 +1,8 @@
 # AGN
 obj-$(CONFIG_IWLAGN)	+= iwlagn.o
-iwlagn-objs		:= iwl-agn.o iwl-agn-rs.o iwl-agn-led.o
+iwlagn-objs		:= iwl-agn.o iwl-agn-rs.o
 iwlagn-objs		+= iwl-agn-ucode.o iwl-agn-tx.o
-iwlagn-objs		+= iwl-agn-lib.o iwl-agn-calib.o
+iwlagn-objs		+= iwl-agn-lib.o iwl-agn-calib.o iwl-io.o
 iwlagn-objs		+= iwl-agn-tt.o iwl-agn-sta.o iwl-agn-eeprom.o
 
 iwlagn-objs 		+= iwl-core.o iwl-eeprom.o iwl-hcmd.o iwl-power.o
@@ -14,9 +14,9 @@
 iwlagn-objs             += iwl-1000.o
 iwlagn-objs             += iwl-2000.o
 
-iwlagn-$(CONFIG_IWLWIFI_DEBUGFS) += iwl-agn-debugfs.o
 iwlagn-$(CONFIG_IWLWIFI_DEBUGFS) += iwl-debugfs.o
 iwlagn-$(CONFIG_IWLWIFI_DEVICE_TRACING) += iwl-devtrace.o
+iwlagn-$(CONFIG_IWLWIFI_DEVICE_SVTOOL) += iwl-sv-open.o
 
 CFLAGS_iwl-devtrace.o := -I$(src)
 
diff -druN linux-2.6.39-libre/drivers/net/wireless/iwmc3200wifi/rx.c linux-3.0-rc7-libre/drivers/net/wireless/iwmc3200wifi/rx.c
--- linux-2.6.39-libre/drivers/net/wireless/iwmc3200wifi/rx.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/iwmc3200wifi/rx.c	2011-07-11 19:51:52.000000000 -0400
@@ -565,7 +565,7 @@
 		if (!test_and_clear_bit(IWM_STATUS_SME_CONNECTING, &iwm->status)
 		    && iwm->conf.mode == UMAC_MODE_BSS) {
 			cancel_delayed_work(&iwm->disconnect);
-			cfg80211_roamed(iwm_to_ndev(iwm),
+			cfg80211_roamed(iwm_to_ndev(iwm), NULL,
 					complete->bssid,
 					iwm->req_ie, iwm->req_ie_len,
 					iwm->resp_ie, iwm->resp_ie_len,
@@ -586,7 +586,7 @@
 						WLAN_STATUS_SUCCESS,
 						GFP_KERNEL);
 		else
-			cfg80211_roamed(iwm_to_ndev(iwm),
+			cfg80211_roamed(iwm_to_ndev(iwm), NULL,
 					complete->bssid,
 					iwm->req_ie, iwm->req_ie_len,
 					iwm->resp_ie, iwm->resp_ie_len,
@@ -1576,7 +1576,8 @@
 	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);
+	ieee80211_amsdu_to_8023s(skb, &list, ndev->dev_addr, wdev->iftype, 0,
+									true);
 
 	while ((frame = __skb_dequeue(&list))) {
 		ndev->stats.rx_packets++;
diff -druN linux-2.6.39-libre/drivers/net/wireless/Kconfig linux-3.0-rc7-libre/drivers/net/wireless/Kconfig
--- linux-2.6.39-libre/drivers/net/wireless/Kconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/Kconfig	2011-07-11 19:51:52.000000000 -0400
@@ -284,5 +284,6 @@
 source "drivers/net/wireless/wl1251/Kconfig"
 source "drivers/net/wireless/wl12xx/Kconfig"
 source "drivers/net/wireless/zd1211rw/Kconfig"
+source "drivers/net/wireless/mwifiex/Kconfig"
 
 endif # WLAN
diff -druN linux-2.6.39-libre/drivers/net/wireless/libertas/cfg.c linux-3.0-rc7-libre/drivers/net/wireless/libertas/cfg.c
--- linux-2.6.39-libre/drivers/net/wireless/libertas/cfg.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/libertas/cfg.c	2011-07-11 19:51:52.000000000 -0400
@@ -6,6 +6,8 @@
  *
  */
 
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/sched.h>
 #include <linux/wait.h>
 #include <linux/slab.h>
@@ -122,8 +124,10 @@
 }
 
 
-/* Various firmware commands need the list of supported rates, but with
-   the hight-bit set for basic rates */
+/*
+ * Various firmware commands need the list of supported rates, but with
+ * the hight-bit set for basic rates
+ */
 static int lbs_add_rates(u8 *rates)
 {
 	size_t i;
@@ -425,7 +429,7 @@
 	return ie_len + 2;
 }
 
-/***************************************************************************
+/*
  * Set Channel
  */
 
@@ -452,7 +456,7 @@
 
 
 
-/***************************************************************************
+/*
  * Scanning
  */
 
@@ -538,8 +542,10 @@
 		goto done;
 	}
 
-	/* Validity check: the TLV holds TSF values with 8 bytes each, so
-	 * the size in the TLV must match the nr_sets value */
+	/*
+	 * Validity check: the TLV holds TSF values with 8 bytes each, so
+	 * the size in the TLV must match the nr_sets value
+	 */
 	i = get_unaligned_le16(tsfdesc);
 	tsfdesc += 2;
 	if (i / 8 != scanresp->nr_sets) {
@@ -581,8 +587,10 @@
 
 		/* To find out the channel, we must parse the IEs */
 		ie = pos;
-		/* 6+1+8+2+2: size of BSSID, RSSI, time stamp, beacon
-		   interval, capabilities */
+		/*
+		 * 6+1+8+2+2: size of BSSID, RSSI, time stamp, beacon
+		 * interval, capabilities
+		 */
 		ielen = left = len - (6 + 1 + 8 + 2 + 2);
 		while (left >= 2) {
 			u8 id, elen;
@@ -790,7 +798,7 @@
 
 
 
-/***************************************************************************
+/*
  * Events
  */
 
@@ -825,7 +833,7 @@
 
 
 
-/***************************************************************************
+/*
  * Connect/disconnect
  */
 
@@ -950,8 +958,10 @@
  * Set WPA/WPA key material
  */
 
-/* like "struct cmd_ds_802_11_key_material", but with cmd_header. Once we
- * get rid of WEXT, this should go into host.h */
+/*
+ * like "struct cmd_ds_802_11_key_material", but with cmd_header. Once we
+ * get rid of WEXT, this should go into host.h
+ */
 
 struct cmd_key_material {
 	struct cmd_header hdr;
@@ -1314,8 +1324,8 @@
 		sme->ssid, sme->ssid_len,
 		WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS);
 	if (!bss) {
-		lbs_pr_err("assoc: bss %pM not in scan results\n",
-			   sme->bssid);
+		wiphy_err(wiphy, "assoc: bss %pM not in scan results\n",
+			  sme->bssid);
 		ret = -ENOENT;
 		goto done;
 	}
@@ -1372,8 +1382,8 @@
 		lbs_enable_rsn(priv, sme->crypto.cipher_group != 0);
 		break;
 	default:
-		lbs_pr_err("unsupported cipher group 0x%x\n",
-			   sme->crypto.cipher_group);
+		wiphy_err(wiphy, "unsupported cipher group 0x%x\n",
+			  sme->crypto.cipher_group);
 		ret = -ENOTSUPP;
 		goto done;
 	}
@@ -1491,7 +1501,7 @@
 				     params->key, params->key_len);
 		break;
 	default:
-		lbs_pr_err("unhandled cipher 0x%x\n", params->cipher);
+		wiphy_err(wiphy, "unhandled cipher 0x%x\n", params->cipher);
 		ret = -ENOTSUPP;
 		break;
 	}
@@ -1536,7 +1546,7 @@
 }
 
 
-/***************************************************************************
+/*
  * Get station
  */
 
@@ -1581,7 +1591,7 @@
 
 
 
-/***************************************************************************
+/*
  * "Site survey", here just current channel and noise level
  */
 
@@ -1614,7 +1624,7 @@
 
 
 
-/***************************************************************************
+/*
  * Change interface
  */
 
@@ -1656,11 +1666,12 @@
 
 
 
-/***************************************************************************
+/*
  * IBSS (Ad-Hoc)
  */
 
-/* The firmware needs the following bits masked out of the beacon-derived
+/*
+ * The firmware needs the following bits masked out of the beacon-derived
  * capability field when associating/joining to a BSS:
  *  9 (QoS), 11 (APSD), 12 (unused), 14 (unused), 15 (unused)
  */
@@ -1999,7 +2010,7 @@
 
 
 
-/***************************************************************************
+/*
  * Initialization
  */
 
@@ -2118,13 +2129,13 @@
 
 	ret = wiphy_register(wdev->wiphy);
 	if (ret < 0)
-		lbs_pr_err("cannot register wiphy device\n");
+		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");
+		pr_err("cannot register network device\n");
 
 	INIT_DELAYED_WORK(&priv->scan_work, lbs_scan_worker);
 
diff -druN linux-2.6.39-libre/drivers/net/wireless/libertas/cmd.c linux-3.0-rc7-libre/drivers/net/wireless/libertas/cmd.c
--- linux-2.6.39-libre/drivers/net/wireless/libertas/cmd.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/libertas/cmd.c	2011-07-11 19:51:52.000000000 -0400
@@ -1,7 +1,7 @@
-/**
-  * This file contains the handling of command.
-  * It prepares command and sends it to firmware when it is ready.
-  */
+/*
+ * This file contains the handling of command.
+ * It prepares command and sends it to firmware when it is ready.
+ */
 
 #include <linux/kfifo.h>
 #include <linux/sched.h>
@@ -16,14 +16,14 @@
 #define CAL_RSSI(snr, nf)	((s32)((s32)(snr) + CAL_NF(nf)))
 
 /**
- *  @brief Simple callback that copies response back into command
+ * lbs_cmd_copyback - Simple callback that copies response back into command
  *
- *  @param priv    	A pointer to struct lbs_private structure
- *  @param extra  	A pointer to the original command structure for which
- *                      'resp' is a response
- *  @param resp         A pointer to the command response
+ * @priv:	A pointer to &struct lbs_private structure
+ * @extra:	A pointer to the original command structure for which
+ *		'resp' is a response
+ * @resp:	A pointer to the command response
  *
- *  @return 	   	0 on success, error on failure
+ * returns:	0 on success, error on failure
  */
 int lbs_cmd_copyback(struct lbs_private *priv, unsigned long extra,
 		     struct cmd_header *resp)
@@ -38,15 +38,15 @@
 EXPORT_SYMBOL_GPL(lbs_cmd_copyback);
 
 /**
- *  @brief Simple callback that ignores the result. Use this if
- *  you just want to send a command to the hardware, but don't
+ *  lbs_cmd_async_callback - Simple callback that ignores the result.
+ *  Use this if you just want to send a command to the hardware, but don't
  *  care for the result.
  *
- *  @param priv         ignored
- *  @param extra        ignored
- *  @param resp         ignored
+ *  @priv:	ignored
+ *  @extra:	ignored
+ *  @resp:	ignored
  *
- *  @return 	   	0 for success
+ *  returns:	0 for success
  */
 static int lbs_cmd_async_callback(struct lbs_private *priv, unsigned long extra,
 		     struct cmd_header *resp)
@@ -56,10 +56,11 @@
 
 
 /**
- *  @brief Checks whether a command is allowed in Power Save mode
+ *  is_command_allowed_in_ps - tests if a command is allowed in Power Save mode
  *
- *  @param command the command ID
- *  @return 	   1 if allowed, 0 if not allowed
+ *  @cmd:	the command ID
+ *
+ *  returns:	1 if allowed, 0 if not allowed
  */
 static u8 is_command_allowed_in_ps(u16 cmd)
 {
@@ -75,11 +76,12 @@
 }
 
 /**
- *  @brief Updates the hardware details like MAC address and regulatory region
+ *  lbs_update_hw_spec - Updates the hardware details like MAC address
+ *  and regulatory region
  *
- *  @param priv    	A pointer to struct lbs_private structure
+ *  @priv:	A pointer to &struct lbs_private structure
  *
- *  @return 	   	0 on success, error on failure
+ *  returns:	0 on success, error on failure
  */
 int lbs_update_hw_spec(struct lbs_private *priv)
 {
@@ -108,7 +110,7 @@
 	 * CF card    firmware 5.0.16p0:   cap 0x00000303
 	 * USB dongle firmware 5.110.17p2: cap 0x00000303
 	 */
-	lbs_pr_info("%pM, fw %u.%u.%up%u, cap 0x%08x\n",
+	netdev_info(priv->dev, "%pM, fw %u.%u.%up%u, cap 0x%08x\n",
 		cmd.permanentaddr,
 		priv->fwrelease >> 24 & 0xff,
 		priv->fwrelease >> 16 & 0xff,
@@ -139,7 +141,8 @@
 	/* if it's unidentified region code, use the default (USA) */
 	if (i >= MRVDRV_MAX_REGION_CODE) {
 		priv->regioncode = 0x10;
-		lbs_pr_info("unidentified region code; using the default (USA)\n");
+		netdev_info(priv->dev,
+			    "unidentified region code; using the default (USA)\n");
 	}
 
 	if (priv->current_addr[0] == 0xff)
@@ -209,7 +212,7 @@
 					(uint8_t *)&cmd_config.wol_conf,
 					sizeof(struct wol_config));
 	} else {
-		lbs_pr_info("HOST_SLEEP_CFG failed %d\n", ret);
+		netdev_info(priv->dev, "HOST_SLEEP_CFG failed %d\n", ret);
 	}
 
 	return ret;
@@ -217,14 +220,14 @@
 EXPORT_SYMBOL_GPL(lbs_host_sleep_cfg);
 
 /**
- *  @brief Sets the Power Save mode
+ *  lbs_set_ps_mode - Sets the Power Save mode
  *
- *  @param priv    	A pointer to struct lbs_private structure
- *  @param cmd_action	The Power Save operation (PS_MODE_ACTION_ENTER_PS or
+ *  @priv:	A pointer to &struct lbs_private structure
+ *  @cmd_action: The Power Save operation (PS_MODE_ACTION_ENTER_PS or
  *                         PS_MODE_ACTION_EXIT_PS)
- *  @param block	Whether to block on a response or not
+ *  @block:	Whether to block on a response or not
  *
- *  @return 	   	0 on success, error on failure
+ *  returns:	0 on success, error on failure
  */
 int lbs_set_ps_mode(struct lbs_private *priv, u16 cmd_action, bool block)
 {
@@ -312,7 +315,7 @@
 	if (priv->is_deep_sleep) {
 		if (!wait_event_interruptible_timeout(priv->ds_awake_q,
 					!priv->is_deep_sleep, (10 * HZ))) {
-			lbs_pr_err("ds_awake_q: timer expired\n");
+			netdev_err(priv->dev, "ds_awake_q: timer expired\n");
 			ret = -1;
 		}
 	}
@@ -337,7 +340,7 @@
 				netif_carrier_off(priv->dev);
 			}
 		} else {
-			lbs_pr_err("deep sleep: already enabled\n");
+			netdev_err(priv->dev, "deep sleep: already enabled\n");
 		}
 	} else {
 		if (priv->is_deep_sleep) {
@@ -347,8 +350,8 @@
 			if (!ret) {
 				ret = lbs_wait_for_ds_awake(priv);
 				if (ret)
-					lbs_pr_err("deep sleep: wakeup"
-							"failed\n");
+					netdev_err(priv->dev,
+						   "deep sleep: wakeup failed\n");
 			}
 		}
 	}
@@ -382,8 +385,9 @@
 			ret = lbs_host_sleep_cfg(priv, priv->wol_criteria,
 					(struct wol_config *)NULL);
 			if (ret) {
-				lbs_pr_info("Host sleep configuration failed: "
-						"%d\n", ret);
+				netdev_info(priv->dev,
+					    "Host sleep configuration failed: %d\n",
+					    ret);
 				return ret;
 			}
 			if (priv->psstate == PS_STATE_FULL_POWER) {
@@ -393,19 +397,21 @@
 						sizeof(cmd),
 						lbs_ret_host_sleep_activate, 0);
 				if (ret)
-					lbs_pr_info("HOST_SLEEP_ACTIVATE "
-							"failed: %d\n", ret);
+					netdev_info(priv->dev,
+						    "HOST_SLEEP_ACTIVATE failed: %d\n",
+						    ret);
 			}
 
 			if (!wait_event_interruptible_timeout(
 						priv->host_sleep_q,
 						priv->is_host_sleep_activated,
 						(10 * HZ))) {
-				lbs_pr_err("host_sleep_q: timer expired\n");
+				netdev_err(priv->dev,
+					   "host_sleep_q: timer expired\n");
 				ret = -1;
 			}
 		} else {
-			lbs_pr_err("host sleep: already enabled\n");
+			netdev_err(priv->dev, "host sleep: already enabled\n");
 		}
 	} else {
 		if (priv->is_host_sleep_activated)
@@ -417,13 +423,13 @@
 }
 
 /**
- *  @brief Set an SNMP MIB value
+ *  lbs_set_snmp_mib - Set an SNMP MIB value
  *
- *  @param priv    	A pointer to struct lbs_private structure
- *  @param oid  	The OID to set in the firmware
- *  @param val  	Value to set the OID to
+ *  @priv:	A pointer to &struct lbs_private structure
+ *  @oid:	The OID to set in the firmware
+ *  @val:	Value to set the OID to
  *
- *  @return 	   	0 on success, error on failure
+ *  returns: 	   	0 on success, error on failure
  */
 int lbs_set_snmp_mib(struct lbs_private *priv, u32 oid, u16 val)
 {
@@ -467,13 +473,13 @@
 }
 
 /**
- *  @brief Get an SNMP MIB value
+ *  lbs_get_snmp_mib - Get an SNMP MIB value
  *
- *  @param priv    	A pointer to struct lbs_private structure
- *  @param oid  	The OID to retrieve from the firmware
- *  @param out_val  	Location for the returned value
+ *  @priv:	A pointer to &struct lbs_private structure
+ *  @oid:	The OID to retrieve from the firmware
+ *  @out_val:	Location for the returned value
  *
- *  @return 	   	0 on success, error on failure
+ *  returns:	0 on success, error on failure
  */
 int lbs_get_snmp_mib(struct lbs_private *priv, u32 oid, u16 *out_val)
 {
@@ -510,14 +516,14 @@
 }
 
 /**
- *  @brief Get the min, max, and current TX power
+ *  lbs_get_tx_power - Get the min, max, and current TX power
  *
- *  @param priv    	A pointer to struct lbs_private structure
- *  @param curlevel  	Current power level in dBm
- *  @param minlevel  	Minimum supported power level in dBm (optional)
- *  @param maxlevel  	Maximum supported power level in dBm (optional)
+ *  @priv:	A pointer to &struct lbs_private structure
+ *  @curlevel:	Current power level in dBm
+ *  @minlevel:	Minimum supported power level in dBm (optional)
+ *  @maxlevel:	Maximum supported power level in dBm (optional)
  *
- *  @return 	   	0 on success, error on failure
+ *  returns:	0 on success, error on failure
  */
 int lbs_get_tx_power(struct lbs_private *priv, s16 *curlevel, s16 *minlevel,
 		     s16 *maxlevel)
@@ -545,12 +551,12 @@
 }
 
 /**
- *  @brief Set the TX power
+ *  lbs_set_tx_power - Set the TX power
  *
- *  @param priv    	A pointer to struct lbs_private structure
- *  @param dbm  	The desired power level in dBm
+ *  @priv:	A pointer to &struct lbs_private structure
+ *  @dbm:	The desired power level in dBm
  *
- *  @return 	   	0 on success, error on failure
+ *  returns: 	   	0 on success, error on failure
  */
 int lbs_set_tx_power(struct lbs_private *priv, s16 dbm)
 {
@@ -573,12 +579,13 @@
 }
 
 /**
- *  @brief Enable or disable monitor mode (only implemented on OLPC usb8388 FW)
+ *  lbs_set_monitor_mode - Enable or disable monitor mode
+ *  (only implemented on OLPC usb8388 FW)
  *
- *  @param priv        A pointer to struct lbs_private structure
- *  @param enable      1 to enable monitor mode, 0 to disable
+ *  @priv:	A pointer to &struct lbs_private structure
+ *  @enable:	1 to enable monitor mode, 0 to disable
  *
- *  @return            0 on success, error on failure
+ *  returns:	0 on success, error on failure
  */
 int lbs_set_monitor_mode(struct lbs_private *priv, int enable)
 {
@@ -604,11 +611,11 @@
 }
 
 /**
- *  @brief Get the radio channel
+ *  lbs_get_channel - Get the radio channel
  *
- *  @param priv    	A pointer to struct lbs_private structure
+ *  @priv:	A pointer to &struct lbs_private structure
  *
- *  @return 	   	The channel on success, error on failure
+ *  returns:	The channel on success, error on failure
  */
 static int lbs_get_channel(struct lbs_private *priv)
 {
@@ -650,12 +657,12 @@
 }
 
 /**
- *  @brief Set the radio channel
+ *  lbs_set_channel - Set the radio channel
  *
- *  @param priv    	A pointer to struct lbs_private structure
- *  @param channel  	The desired channel, or 0 to clear a locked channel
+ *  @priv:	A pointer to &struct lbs_private structure
+ *  @channel:	The desired channel, or 0 to clear a locked channel
  *
- *  @return 	   	0 on success, error on failure
+ *  returns:	0 on success, error on failure
  */
 int lbs_set_channel(struct lbs_private *priv, u8 channel)
 {
@@ -686,12 +693,13 @@
 }
 
 /**
- *  @brief Get current RSSI and noise floor
+ * lbs_get_rssi - Get current RSSI and noise floor
  *
- *  @param priv		A pointer to struct lbs_private structure
- *  @param rssi		On successful return, signal level in mBm
+ * @priv:	A pointer to &struct lbs_private structure
+ * @rssi:	On successful return, signal level in mBm
+ * @nf:		On successful return, Noise floor
  *
- *  @return 	   	The channel on success, error on failure
+ * returns:	The channel on success, error on failure
  */
 int lbs_get_rssi(struct lbs_private *priv, s8 *rssi, s8 *nf)
 {
@@ -719,13 +727,14 @@
 }
 
 /**
- *  @brief Send regulatory and 802.11d domain information to the firmware
+ *  lbs_set_11d_domain_info - Send regulatory and 802.11d domain information
+ *  to the firmware
  *
- *  @param priv		pointer to struct lbs_private
- *  @param request	cfg80211 regulatory request structure
- *  @param bands	the device's supported bands and channels
+ *  @priv:	pointer to &struct lbs_private
+ *  @request:	cfg80211 regulatory request structure
+ *  @bands:	the device's supported bands and channels
  *
- *  @return		0 on success, error code on failure
+ *  returns:	0 on success, error code on failure
 */
 int lbs_set_11d_domain_info(struct lbs_private *priv,
 			    struct regulatory_request *request,
@@ -842,15 +851,15 @@
 }
 
 /**
- *  @brief Read a MAC, Baseband, or RF register
+ *  lbs_get_reg - Read a MAC, Baseband, or RF register
  *
- *  @param priv		pointer to struct lbs_private
- *  @param cmd		register command, one of CMD_MAC_REG_ACCESS,
- *                        CMD_BBP_REG_ACCESS, or CMD_RF_REG_ACCESS
- *  @param offset       byte offset of the register to get
- *  @param value        on success, the value of the register at 'offset'
+ *  @priv:	pointer to &struct lbs_private
+ *  @reg:	register command, one of CMD_MAC_REG_ACCESS,
+ *		CMD_BBP_REG_ACCESS, or CMD_RF_REG_ACCESS
+ *  @offset:	byte offset of the register to get
+ *  @value:	on success, the value of the register at 'offset'
  *
- *  @return		0 on success, error code on failure
+ *  returns:	0 on success, error code on failure
 */
 int lbs_get_reg(struct lbs_private *priv, u16 reg, u16 offset, u32 *value)
 {
@@ -886,15 +895,15 @@
 }
 
 /**
- *  @brief Write a MAC, Baseband, or RF register
+ *  lbs_set_reg - Write a MAC, Baseband, or RF register
  *
- *  @param priv		pointer to struct lbs_private
- *  @param cmd		register command, one of CMD_MAC_REG_ACCESS,
- *                        CMD_BBP_REG_ACCESS, or CMD_RF_REG_ACCESS
- *  @param offset       byte offset of the register to set
- *  @param value        the value to write to the register at 'offset'
+ *  @priv:	pointer to &struct lbs_private
+ *  @reg:	register command, one of CMD_MAC_REG_ACCESS,
+ *		CMD_BBP_REG_ACCESS, or CMD_RF_REG_ACCESS
+ *  @offset:	byte offset of the register to set
+ *  @value:	the value to write to the register at 'offset'
  *
- *  @return		0 on success, error code on failure
+ *  returns:	0 on success, error code on failure
 */
 int lbs_set_reg(struct lbs_private *priv, u16 reg, u16 offset, u32 value)
 {
@@ -985,6 +994,8 @@
 	cmd = cmdnode->cmdbuf;
 
 	spin_lock_irqsave(&priv->driver_lock, flags);
+	priv->seqnum++;
+	cmd->seqnum = cpu_to_le16(priv->seqnum);
 	priv->cur_cmd = cmdnode;
 	spin_unlock_irqrestore(&priv->driver_lock, flags);
 
@@ -1002,7 +1013,8 @@
 	ret = priv->hw_host_to_card(priv, MVMS_CMD, (u8 *) cmd, cmdsize);
 
 	if (ret) {
-		lbs_pr_info("DNLD_CMD: hw_host_to_card failed: %d\n", ret);
+		netdev_info(priv->dev, "DNLD_CMD: hw_host_to_card failed: %d\n",
+			    ret);
 		/* Let the timer kick in and retry, and potentially reset
 		   the whole thing if the condition persists */
 		timeo = HZ/4;
@@ -1023,7 +1035,7 @@
 	lbs_deb_leave(LBS_DEB_HOST);
 }
 
-/**
+/*
  *  This function inserts command node to cmdfreeq
  *  after cleans it. Requires priv->driver_lock held.
  */
@@ -1125,11 +1137,12 @@
 }
 
 /**
- *  @brief This function allocates the command buffer and link
- *  it to command free queue.
+ *  lbs_allocate_cmd_buffer - allocates the command buffer and links
+ *  it to command free queue
  *
- *  @param priv		A pointer to struct lbs_private structure
- *  @return 		0 or -1
+ *  @priv:	A pointer to &struct lbs_private structure
+ *
+ *  returns:	0 for success or -1 on error
  */
 int lbs_allocate_cmd_buffer(struct lbs_private *priv)
 {
@@ -1171,10 +1184,11 @@
 }
 
 /**
- *  @brief This function frees the command buffer.
+ *  lbs_free_cmd_buffer - free the command buffer
  *
- *  @param priv		A pointer to struct lbs_private structure
- *  @return 		0 or -1
+ *  @priv:	A pointer to &struct lbs_private structure
+ *
+ *  returns:	0 for success
  */
 int lbs_free_cmd_buffer(struct lbs_private *priv)
 {
@@ -1211,11 +1225,13 @@
 }
 
 /**
- *  @brief This function gets a free command node if available in
- *  command free queue.
+ *  lbs_get_free_cmd_node - gets a free command node if available in
+ *  command free queue
  *
- *  @param priv		A pointer to struct lbs_private structure
- *  @return cmd_ctrl_node A pointer to cmd_ctrl_node structure or NULL
+ *  @priv:	A pointer to &struct lbs_private structure
+ *
+ *  returns:	A pointer to &cmd_ctrl_node structure on success
+ *		or %NULL on error
  */
 static struct cmd_ctrl_node *lbs_get_free_cmd_node(struct lbs_private *priv)
 {
@@ -1245,12 +1261,12 @@
 }
 
 /**
- *  @brief This function executes next command in command
- *  pending queue. It will put firmware back to PS mode
- *  if applicable.
+ *  lbs_execute_next_command - execute next command in command
+ *  pending queue. Will put firmware back to PS mode if applicable.
  *
- *  @param priv     A pointer to struct lbs_private structure
- *  @return 	   0 or -1
+ *  @priv:	A pointer to &struct lbs_private structure
+ *
+ *  returns:	0 on success or -1 on error
  */
 int lbs_execute_next_command(struct lbs_private *priv)
 {
@@ -1267,7 +1283,8 @@
 	spin_lock_irqsave(&priv->driver_lock, flags);
 
 	if (priv->cur_cmd) {
-		lbs_pr_alert( "EXEC_NEXT_CMD: already processing command!\n");
+		netdev_alert(priv->dev,
+			     "EXEC_NEXT_CMD: already processing command!\n");
 		spin_unlock_irqrestore(&priv->driver_lock, flags);
 		ret = -1;
 		goto done;
@@ -1431,7 +1448,7 @@
 	ret = priv->hw_host_to_card(priv, MVMS_CMD, (u8 *) &confirm_sleep,
 		sizeof(confirm_sleep));
 	if (ret) {
-		lbs_pr_alert("confirm_sleep failed\n");
+		netdev_alert(priv->dev, "confirm_sleep failed\n");
 		goto out;
 	}
 
@@ -1456,12 +1473,12 @@
 }
 
 /**
- *  @brief This function checks condition and prepares to
- *  send sleep confirm command to firmware if ok.
+ * lbs_ps_confirm_sleep - checks condition and prepares to
+ * send sleep confirm command to firmware if ok
  *
- *  @param priv    	A pointer to struct lbs_private structure
- *  @param psmode  	Power Saving mode
- *  @return 	   	n/a
+ * @priv:	A pointer to &struct lbs_private structure
+ *
+ * returns:	n/a
  */
 void lbs_ps_confirm_sleep(struct lbs_private *priv)
 {
@@ -1501,16 +1518,16 @@
 
 
 /**
- * @brief Configures the transmission power control functionality.
+ * lbs_set_tpc_cfg - Configures the transmission power control functionality
  *
- * @param priv		A pointer to struct lbs_private structure
- * @param enable	Transmission power control enable
- * @param p0		Power level when link quality is good (dBm).
- * @param p1		Power level when link quality is fair (dBm).
- * @param p2		Power level when link quality is poor (dBm).
- * @param usesnr	Use Signal to Noise Ratio in TPC
+ * @priv:	A pointer to &struct lbs_private structure
+ * @enable:	Transmission power control enable
+ * @p0:		Power level when link quality is good (dBm).
+ * @p1:		Power level when link quality is fair (dBm).
+ * @p2:		Power level when link quality is poor (dBm).
+ * @usesnr:	Use Signal to Noise Ratio in TPC
  *
- * @return 0 on success
+ * returns:	0 on success
  */
 int lbs_set_tpc_cfg(struct lbs_private *priv, int enable, int8_t p0, int8_t p1,
 		int8_t p2, int usesnr)
@@ -1533,15 +1550,15 @@
 }
 
 /**
- * @brief Configures the power adaptation settings.
+ * lbs_set_power_adapt_cfg - Configures the power adaptation settings
  *
- * @param priv		A pointer to struct lbs_private structure
- * @param enable	Power adaptation enable
- * @param p0		Power level for 1, 2, 5.5 and 11 Mbps (dBm).
- * @param p1		Power level for 6, 9, 12, 18, 22, 24 and 36 Mbps (dBm).
- * @param p2		Power level for 48 and 54 Mbps (dBm).
+ * @priv:	A pointer to &struct lbs_private structure
+ * @enable:	Power adaptation enable
+ * @p0:		Power level for 1, 2, 5.5 and 11 Mbps (dBm).
+ * @p1:		Power level for 6, 9, 12, 18, 22, 24 and 36 Mbps (dBm).
+ * @p2:		Power level for 48 and 54 Mbps (dBm).
  *
- * @return 0 on Success
+ * returns:	0 on Success
  */
 
 int lbs_set_power_adapt_cfg(struct lbs_private *priv, int enable, int8_t p0,
@@ -1606,11 +1623,9 @@
 	/* Copy the incoming command to the buffer */
 	memcpy(cmdnode->cmdbuf, in_cmd, in_cmd_size);
 
-	/* Set sequence number, clean result, move to buffer */
-	priv->seqnum++;
+	/* Set command, clean result, move to buffer */
 	cmdnode->cmdbuf->command = cpu_to_le16(command);
 	cmdnode->cmdbuf->size    = cpu_to_le16(in_cmd_size);
-	cmdnode->cmdbuf->seqnum  = cpu_to_le16(priv->seqnum);
 	cmdnode->cmdbuf->result  = 0;
 
 	lbs_deb_host("PREP_CMD: command 0x%04x\n", command);
@@ -1657,7 +1672,7 @@
 	spin_lock_irqsave(&priv->driver_lock, flags);
 	ret = cmdnode->result;
 	if (ret)
-		lbs_pr_info("PREP_CMD: command 0x%04x failed: %d\n",
+		netdev_info(priv->dev, "PREP_CMD: command 0x%04x failed: %d\n",
 			    command, ret);
 
 	__lbs_cleanup_and_insert_cmd(priv, cmdnode);
diff -druN linux-2.6.39-libre/drivers/net/wireless/libertas/cmdresp.c linux-3.0-rc7-libre/drivers/net/wireless/libertas/cmdresp.c
--- linux-2.6.39-libre/drivers/net/wireless/libertas/cmdresp.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/libertas/cmdresp.c	2011-07-11 19:51:52.000000000 -0400
@@ -1,7 +1,8 @@
-/**
-  * This file contains the handling of command
-  * responses as well as events generated by firmware.
-  */
+/*
+ * 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>
@@ -12,12 +13,13 @@
 #include "cmd.h"
 
 /**
- *  @brief This function handles disconnect event. it
- *  reports disconnect to upper layer, clean tx/rx packets,
- *  reset link state etc.
+ * lbs_mac_event_disconnected - handles disconnect event. It
+ * reports disconnect to upper layer, clean tx/rx packets,
+ * reset link state etc.
  *
- *  @param priv    A pointer to struct lbs_private structure
- *  @return 	   n/a
+ * @priv:	A pointer to struct lbs_private structure
+ *
+ * returns:	n/a
  */
 void lbs_mac_event_disconnected(struct lbs_private *priv)
 {
@@ -84,15 +86,18 @@
 	lbs_deb_hex(LBS_DEB_CMD, "CMD_RESP", (void *) resp, len);
 
 	if (resp->seqnum != priv->cur_cmd->cmdbuf->seqnum) {
-		lbs_pr_info("Received CMD_RESP with invalid sequence %d (expected %d)\n",
-			    le16_to_cpu(resp->seqnum), le16_to_cpu(priv->cur_cmd->cmdbuf->seqnum));
+		netdev_info(priv->dev,
+			    "Received CMD_RESP with invalid sequence %d (expected %d)\n",
+			    le16_to_cpu(resp->seqnum),
+			    le16_to_cpu(priv->cur_cmd->cmdbuf->seqnum));
 		spin_unlock_irqrestore(&priv->driver_lock, flags);
 		ret = -1;
 		goto done;
 	}
 	if (respcmd != CMD_RET(curcmd) &&
 	    respcmd != CMD_RET_802_11_ASSOCIATE && curcmd != CMD_802_11_ASSOCIATE) {
-		lbs_pr_info("Invalid CMD_RESP %x to command %x!\n", respcmd, curcmd);
+		netdev_info(priv->dev, "Invalid CMD_RESP %x to command %x!\n",
+			    respcmd, curcmd);
 		spin_unlock_irqrestore(&priv->driver_lock, flags);
 		ret = -1;
 		goto done;
@@ -101,7 +106,8 @@
 	if (resp->result == cpu_to_le16(0x0004)) {
 		/* 0x0004 means -EAGAIN. Drop the response, let it time out
 		   and be resubmitted */
-		lbs_pr_info("Firmware returns DEFER to command %x. Will let it time out...\n",
+		netdev_info(priv->dev,
+			    "Firmware returns DEFER to command %x. Will let it time out...\n",
 			    le16_to_cpu(resp->command));
 		spin_unlock_irqrestore(&priv->driver_lock, flags);
 		ret = -1;
@@ -313,28 +319,28 @@
 		lbs_deb_cmd("EVENT: ADHOC beacon lost\n");
 		break;
 	case MACREG_INT_CODE_RSSI_LOW:
-		lbs_pr_alert("EVENT: rssi low\n");
+		netdev_alert(priv->dev, "EVENT: rssi low\n");
 		break;
 	case MACREG_INT_CODE_SNR_LOW:
-		lbs_pr_alert("EVENT: snr low\n");
+		netdev_alert(priv->dev, "EVENT: snr low\n");
 		break;
 	case MACREG_INT_CODE_MAX_FAIL:
-		lbs_pr_alert("EVENT: max fail\n");
+		netdev_alert(priv->dev, "EVENT: max fail\n");
 		break;
 	case MACREG_INT_CODE_RSSI_HIGH:
-		lbs_pr_alert("EVENT: rssi high\n");
+		netdev_alert(priv->dev, "EVENT: rssi high\n");
 		break;
 	case MACREG_INT_CODE_SNR_HIGH:
-		lbs_pr_alert("EVENT: snr high\n");
+		netdev_alert(priv->dev, "EVENT: snr high\n");
 		break;
 
 	case MACREG_INT_CODE_MESH_AUTO_STARTED:
 		/* Ignore spurious autostart events */
-		lbs_pr_info("EVENT: MESH_AUTO_STARTED (ignoring)\n");
+		netdev_info(priv->dev, "EVENT: MESH_AUTO_STARTED (ignoring)\n");
 		break;
 
 	default:
-		lbs_pr_alert("EVENT: unknown event id %d\n", event);
+		netdev_alert(priv->dev, "EVENT: unknown event id %d\n", event);
 		break;
 	}
 
diff -druN linux-2.6.39-libre/drivers/net/wireless/libertas/debugfs.c linux-3.0-rc7-libre/drivers/net/wireless/libertas/debugfs.c
--- linux-2.6.39-libre/drivers/net/wireless/libertas/debugfs.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/libertas/debugfs.c	2011-07-11 19:51:52.000000000 -0400
@@ -151,13 +151,14 @@
 		ret = lbs_set_host_sleep(priv, 0);
 	else if (host_sleep == 1) {
 		if (priv->wol_criteria == EHS_REMOVE_WAKEUP) {
-			lbs_pr_info("wake parameters not configured");
+			netdev_info(priv->dev,
+				    "wake parameters not configured\n");
 			ret = -EINVAL;
 			goto out_unlock;
 		}
 		ret = lbs_set_host_sleep(priv, 1);
 	} else {
-		lbs_pr_err("invalid option\n");
+		netdev_err(priv->dev, "invalid option\n");
 		ret = -EINVAL;
 	}
 
@@ -849,15 +850,14 @@
 static int num_of_items = ARRAY_SIZE(items);
 
 /**
- *  @brief proc read function
+ * lbs_debugfs_read - proc read function
  *
- *  @param page	   pointer to buffer
- *  @param s       read data starting position
- *  @param off     offset
- *  @param cnt     counter
- *  @param eof     end of file flag
- *  @param data    data to output
- *  @return 	   number of output data
+ * @file:	file to read
+ * @userbuf:	pointer to buffer
+ * @count:	number of bytes to read
+ * @ppos:	read data starting position
+ *
+ * returns:	amount of data read or negative error code
  */
 static ssize_t lbs_debugfs_read(struct file *file, char __user *userbuf,
 			size_t count, loff_t *ppos)
@@ -897,13 +897,14 @@
 }
 
 /**
- *  @brief proc write function
+ * lbs_debugfs_write - proc write function
  *
- *  @param f	   file pointer
- *  @param buf     pointer to data buffer
- *  @param cnt     data number to write
- *  @param data    data to write
- *  @return 	   number of data
+ * @f:		file pointer
+ * @buf:	pointer to data buffer
+ * @cnt:	data number to write
+ * @ppos:	file position
+ *
+ * returns:	amount of data written
  */
 static ssize_t lbs_debugfs_write(struct file *f, const char __user *buf,
 			    size_t cnt, loff_t *ppos)
@@ -966,11 +967,11 @@
 };
 
 /**
- *  @brief create debug proc file
+ * lbs_debug_init - create debug proc file
  *
- *  @param priv	   pointer struct lbs_private
- *  @param dev     pointer net_device
- *  @return 	   N/A
+ * @priv:	pointer to &struct lbs_private
+ *
+ * returns:	N/A
  */
 static void lbs_debug_init(struct lbs_private *priv)
 {
diff -druN linux-2.6.39-libre/drivers/net/wireless/libertas/decl.h linux-3.0-rc7-libre/drivers/net/wireless/libertas/decl.h
--- linux-2.6.39-libre/drivers/net/wireless/libertas/decl.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/libertas/decl.h	2011-07-11 19:51:52.000000000 -0400
@@ -1,8 +1,8 @@
 
-/**
-  *  This file contains declaration referring to
-  *  functions defined in other source files
-  */
+/*
+ *  This file contains declaration referring to
+ *  functions defined in other source files
+ */
 
 #ifndef _LBS_DECL_H_
 #define _LBS_DECL_H_
diff -druN linux-2.6.39-libre/drivers/net/wireless/libertas/defs.h linux-3.0-rc7-libre/drivers/net/wireless/libertas/defs.h
--- linux-2.6.39-libre/drivers/net/wireless/libertas/defs.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/libertas/defs.h	2011-07-11 19:51:52.000000000 -0400
@@ -1,7 +1,7 @@
-/**
-  * This header file contains global constant/enum definitions,
-  * global variable declaration.
-  */
+/*
+ * This header file contains global constant/enum definitions,
+ * global variable declaration.
+ */
 #ifndef _LBS_DEFS_H_
 #define _LBS_DEFS_H_
 
@@ -89,13 +89,6 @@
 #define lbs_deb_spi(fmt, args...)       LBS_DEB_LL(LBS_DEB_SPI, " spi", fmt, ##args)
 #define lbs_deb_cfg80211(fmt, args...)  LBS_DEB_LL(LBS_DEB_CFG80211, " cfg80211", fmt, ##args)
 
-#define lbs_pr_info(format, args...) \
-	printk(KERN_INFO DRV_NAME": " format, ## args)
-#define lbs_pr_err(format, args...) \
-	printk(KERN_ERR DRV_NAME": " format, ## args)
-#define lbs_pr_alert(format, args...) \
-	printk(KERN_ALERT DRV_NAME": " format, ## args)
-
 #ifdef DEBUG
 static inline void lbs_deb_hex(unsigned int grp, const char *prompt, u8 *buf, int len)
 {
@@ -123,19 +116,19 @@
 
 
 
-/** Buffer Constants */
+/* Buffer Constants */
 
 /*	The size of SQ memory PPA, DPA are 8 DWORDs, that keep the physical
-*	addresses of TxPD buffers. Station has only 8 TxPD available, Whereas
-*	driver has more local TxPDs. Each TxPD on the host memory is associated
-*	with a Tx control node. The driver maintains 8 RxPD descriptors for
-*	station firmware to store Rx packet information.
-*
-*	Current version of MAC has a 32x6 multicast address buffer.
-*
-*	802.11b can have up to  14 channels, the driver keeps the
-*	BSSID(MAC address) of each APs or Ad hoc stations it has sensed.
-*/
+ *	addresses of TxPD buffers. Station has only 8 TxPD available, Whereas
+ *	driver has more local TxPDs. Each TxPD on the host memory is associated
+ *	with a Tx control node. The driver maintains 8 RxPD descriptors for
+ *	station firmware to store Rx packet information.
+ *
+ *	Current version of MAC has a 32x6 multicast address buffer.
+ *
+ *	802.11b can have up to  14 channels, the driver keeps the
+ *	BSSID(MAC address) of each APs or Ad hoc stations it has sensed.
+ */
 
 #define MRVDRV_MAX_MULTICAST_LIST_SIZE	32
 #define LBS_NUM_CMD_BUFFERS             10
@@ -166,7 +159,7 @@
 #define WOL_RESULT_NOSPC_ERR		1
 #define WOL_RESULT_EEXIST_ERR		2
 
-/** Misc constants */
+/* Misc constants */
 /* This section defines 802.11 specific contants */
 
 #define MRVDRV_MAX_BSS_DESCRIPTS		16
@@ -183,7 +176,8 @@
 
 #define MARVELL_MESH_IE_LENGTH		9
 
-/* Values used to populate the struct mrvl_mesh_ie.  The only time you need this
+/*
+ * Values used to populate the struct mrvl_mesh_ie.  The only time you need this
  * is when enabling the mesh using CMD_MESH_CONFIG.
  */
 #define MARVELL_MESH_IE_TYPE		4
@@ -193,7 +187,7 @@
 #define MARVELL_MESH_METRIC_ID		0
 #define MARVELL_MESH_CAPABILITY		0
 
-/** INT status Bit Definition*/
+/* INT status Bit Definition */
 #define MRVDRV_TX_DNLD_RDY		0x0001
 #define MRVDRV_RX_UPLD_RDY		0x0002
 #define MRVDRV_CMD_DNLD_RDY		0x0004
@@ -208,59 +202,63 @@
 #define TPC_DEFAULT_P1 10
 #define TPC_DEFAULT_P2 13
 
-/** TxPD status */
+/* TxPD status */
 
-/*	Station firmware use TxPD status field to report final Tx transmit
-*	result, Bit masks are used to present combined situations.
-*/
+/*
+ *	Station firmware use TxPD status field to report final Tx transmit
+ *	result, Bit masks are used to present combined situations.
+ */
 
 #define MRVDRV_TxPD_POWER_MGMT_NULL_PACKET 0x01
 #define MRVDRV_TxPD_POWER_MGMT_LAST_PACKET 0x08
 
-/** Tx mesh flag */
-/* Currently we are using normal WDS flag as mesh flag.
+/* Tx mesh flag */
+/*
+ * Currently we are using normal WDS flag as mesh flag.
  * TODO: change to proper mesh flag when MAC understands it.
  */
 #define TxPD_CONTROL_WDS_FRAME (1<<17)
 #define TxPD_MESH_FRAME TxPD_CONTROL_WDS_FRAME
 
-/** Mesh interface ID */
+/* Mesh interface ID */
 #define MESH_IFACE_ID					0x0001
-/** Mesh id should be in bits 14-13-12 */
+/* Mesh id should be in bits 14-13-12 */
 #define MESH_IFACE_BIT_OFFSET				0x000c
-/** Mesh enable bit in FW capability */
+/* Mesh enable bit in FW capability */
 #define MESH_CAPINFO_ENABLE_MASK			(1<<16)
 
-/** FW definition from Marvell v4 */
+/* FW definition from Marvell v4 */
 #define MRVL_FW_V4					(0x04)
-/** FW definition from Marvell v5 */
+/* FW definition from Marvell v5 */
 #define MRVL_FW_V5					(0x05)
-/** FW definition from Marvell v10 */
+/* FW definition from Marvell v10 */
 #define MRVL_FW_V10					(0x0a)
-/** FW major revision definition */
+/* FW major revision definition */
 #define MRVL_FW_MAJOR_REV(x)				((x)>>24)
 
-/** RxPD status */
+/* RxPD status */
 
 #define MRVDRV_RXPD_STATUS_OK                0x0001
 
-/** RxPD status - Received packet types */
-/** Rx mesh flag */
-/* Currently we are using normal WDS flag as mesh flag.
+/* RxPD status - Received packet types */
+/* Rx mesh flag */
+/*
+ * Currently we are using normal WDS flag as mesh flag.
  * TODO: change to proper mesh flag when MAC understands it.
  */
 #define RxPD_CONTROL_WDS_FRAME (0x40)
 #define RxPD_MESH_FRAME RxPD_CONTROL_WDS_FRAME
 
-/** RSSI-related defines */
-/*	RSSI constants are used to implement 802.11 RSSI threshold
-*	indication. if the Rx packet signal got too weak for 5 consecutive
-*	times, miniport driver (driver) will report this event to wrapper
-*/
+/* RSSI-related defines */
+/*
+ *	RSSI constants are used to implement 802.11 RSSI threshold
+ *	indication. if the Rx packet signal got too weak for 5 consecutive
+ *	times, miniport driver (driver) will report this event to wrapper
+ */
 
 #define MRVDRV_NF_DEFAULT_SCAN_VALUE		(-96)
 
-/** RTS/FRAG related defines */
+/* RTS/FRAG related defines */
 #define MRVDRV_RTS_MIN_VALUE		0
 #define MRVDRV_RTS_MAX_VALUE		2347
 #define MRVDRV_FRAG_MIN_VALUE		256
@@ -300,36 +298,36 @@
 
 #define	MAX_LEDS			8
 
-/** Global Variable Declaration */
+/* Global Variable Declaration */
 extern const char lbs_driver_version[];
 extern u16 lbs_region_code_to_index[MRVDRV_MAX_REGION_CODE];
 
 
-/** ENUM definition*/
-/** SNRNF_TYPE */
+/* ENUM definition */
+/* SNRNF_TYPE */
 enum SNRNF_TYPE {
 	TYPE_BEACON = 0,
 	TYPE_RXPD,
 	MAX_TYPE_B
 };
 
-/** SNRNF_DATA*/
+/* SNRNF_DATA */
 enum SNRNF_DATA {
 	TYPE_NOAVG = 0,
 	TYPE_AVG,
 	MAX_TYPE_AVG
 };
 
-/** LBS_802_11_POWER_MODE */
+/* LBS_802_11_POWER_MODE */
 enum LBS_802_11_POWER_MODE {
 	LBS802_11POWERMODECAM,
 	LBS802_11POWERMODEMAX_PSP,
 	LBS802_11POWERMODEFAST_PSP,
-	/*not a real mode, defined as an upper bound */
+	/* not a real mode, defined as an upper bound */
 	LBS802_11POWEMODEMAX
 };
 
-/** PS_STATE */
+/* PS_STATE */
 enum PS_STATE {
 	PS_STATE_FULL_POWER,
 	PS_STATE_AWAKE,
@@ -337,7 +335,7 @@
 	PS_STATE_SLEEP
 };
 
-/** DNLD_STATE */
+/* DNLD_STATE */
 enum DNLD_STATE {
 	DNLD_RES_RECEIVED,
 	DNLD_DATA_SENT,
@@ -345,19 +343,19 @@
 	DNLD_BOOTCMD_SENT,
 };
 
-/** LBS_MEDIA_STATE */
+/* LBS_MEDIA_STATE */
 enum LBS_MEDIA_STATE {
 	LBS_CONNECTED,
 	LBS_DISCONNECTED
 };
 
-/** LBS_802_11_PRIVACY_FILTER */
+/* LBS_802_11_PRIVACY_FILTER */
 enum LBS_802_11_PRIVACY_FILTER {
 	LBS802_11PRIVFILTERACCEPTALL,
 	LBS802_11PRIVFILTER8021XWEP
 };
 
-/** mv_ms_type */
+/* mv_ms_type */
 enum mv_ms_type {
 	MVMS_DAT = 0,
 	MVMS_CMD = 1,
@@ -365,14 +363,14 @@
 	MVMS_EVENT
 };
 
-/** KEY_TYPE_ID */
+/* KEY_TYPE_ID */
 enum KEY_TYPE_ID {
 	KEY_TYPE_ID_WEP = 0,
 	KEY_TYPE_ID_TKIP,
 	KEY_TYPE_ID_AES
 };
 
-/** KEY_INFO_WPA (applies to both TKIP and AES/CCMP) */
+/* KEY_INFO_WPA (applies to both TKIP and AES/CCMP) */
 enum KEY_INFO_WPA {
 	KEY_INFO_WPA_MCAST = 0x01,
 	KEY_INFO_WPA_UNICAST = 0x02,
diff -druN linux-2.6.39-libre/drivers/net/wireless/libertas/dev.h linux-3.0-rc7-libre/drivers/net/wireless/libertas/dev.h
--- linux-2.6.39-libre/drivers/net/wireless/libertas/dev.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/libertas/dev.h	2011-07-11 19:51:52.000000000 -0400
@@ -1,8 +1,8 @@
-/**
-  * This file contains definitions and data structures specific
-  * to Marvell 802.11 NIC. It contains the Device Information
-  * structure struct lbs_private..
-  */
+/*
+ * This file contains definitions and data structures specific
+ * to Marvell 802.11 NIC. It contains the Device Information
+ * structure struct lbs_private..
+ */
 #ifndef _LBS_DEV_H_
 #define _LBS_DEV_H_
 
@@ -12,7 +12,7 @@
 
 #include <linux/kfifo.h>
 
-/** sleep_params */
+/* sleep_params */
 struct sleep_params {
 	uint16_t sp_error;
 	uint16_t sp_offset;
@@ -23,7 +23,7 @@
 };
 
 
-/** Private structure for the MV device */
+/* Private structure for the MV device */
 struct lbs_private {
 
 	/* Basic networking */
@@ -125,12 +125,12 @@
 	/* Events sent from hardware to driver */
 	struct kfifo event_fifo;
 
-	/** thread to service interrupts */
+	/* thread to service interrupts */
 	struct task_struct *main_thread;
 	wait_queue_head_t waitq;
 	struct workqueue_struct *work_thread;
 
-	/** Encryption stuff */
+	/* Encryption stuff */
 	u8 authtype_auto;
 	u8 wep_tx_key;
 	u8 wep_key[4][WLAN_KEY_LEN_WEP104];
@@ -162,7 +162,7 @@
 	s16 txpower_min;
 	s16 txpower_max;
 
-	/** Scanning */
+	/* Scanning */
 	struct delayed_work scan_work;
 	int scan_channel;
 	/* Queue of things waiting for scan completion */
diff -druN linux-2.6.39-libre/drivers/net/wireless/libertas/ethtool.c linux-3.0-rc7-libre/drivers/net/wireless/libertas/ethtool.c
--- linux-2.6.39-libre/drivers/net/wireless/libertas/ethtool.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/libertas/ethtool.c	2011-07-11 19:51:52.000000000 -0400
@@ -20,7 +20,8 @@
 	strcpy(info->version, lbs_driver_version);
 }
 
-/* All 8388 parts have 16KiB EEPROM size at the time of writing.
+/*
+ * All 8388 parts have 16KiB EEPROM size at the time of writing.
  * In case that changes this needs fixing.
  */
 #define LBS_EEPROM_LEN 16384
diff -druN linux-2.6.39-libre/drivers/net/wireless/libertas/host.h linux-3.0-rc7-libre/drivers/net/wireless/libertas/host.h
--- linux-2.6.39-libre/drivers/net/wireless/libertas/host.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/libertas/host.h	2011-07-11 19:51:52.000000000 -0400
@@ -1,7 +1,7 @@
-/**
-  * This file function prototypes, data structure
-  * and  definitions for all the host/station commands
-  */
+/*
+ * This file function prototypes, data structure
+ * and  definitions for all the host/station commands
+ */
 
 #ifndef _LBS_HOST_H_
 #define _LBS_HOST_H_
@@ -13,9 +13,10 @@
 
 #define CMD_OPTION_WAITFORRSP                   0x0002
 
-/** Host command IDs */
+/* Host command IDs */
 
-/* Return command are almost always the same as the host command, but with
+/*
+ * Return command are almost always the same as the host command, but with
  * bit 15 set high.  There are a few exceptions, though...
  */
 #define CMD_RET(cmd)                            (0x8000 | cmd)
@@ -251,7 +252,7 @@
 	CMD_TYPE_MESH_GET_MESH_IE, /* GET_DEFAULTS is superset of GET_MESHIE */
 };
 
-/** Card Event definition */
+/* Card Event definition */
 #define MACREG_INT_CODE_TX_PPA_FREE		0
 #define MACREG_INT_CODE_TX_DMA_DONE		1
 #define MACREG_INT_CODE_LINK_LOST_W_SCAN	2
@@ -624,12 +625,14 @@
 struct cmd_ds_802_11_rssi {
 	struct cmd_header hdr;
 
-	/* request:  number of beacons (N) to average the SNR and NF over
+	/*
+	 * request:  number of beacons (N) to average the SNR and NF over
 	 * response: SNR of most recent beacon
 	 */
 	__le16 n_or_snr;
 
-	/* The following fields are only set in the response.
+	/*
+	 * The following fields are only set in the response.
 	 * In the request these are reserved and should be set to 0.
 	 */
 	__le16 nf;       /* most recent beacon noise floor */
@@ -680,14 +683,16 @@
 
 	__le16 action;
 
-	/* Interval for keepalive in PS mode:
+	/*
+	 * Interval for keepalive in PS mode:
 	 * 0x0000 = don't change
 	 * 0x001E = firmware default
 	 * 0xFFFF = disable
 	 */
 	__le16 nullpktinterval;
 
-	/* Number of DTIM intervals to wake up for:
+	/*
+	 * Number of DTIM intervals to wake up for:
 	 * 0 = don't change
 	 * 1 = firmware default
 	 * 5 = max
@@ -697,7 +702,8 @@
 	__le16 reserved;
 	__le16 locallisteninterval;
 
-	/* AdHoc awake period (FW v9+ only):
+	/*
+	 * AdHoc awake period (FW v9+ only):
 	 * 0 = don't change
 	 * 1 = always awake (IEEE standard behavior)
 	 * 2 - 31 = sleep for (n - 1) periods and awake for 1 period
@@ -771,7 +777,8 @@
 	__le16 capability;
 	u8 rates[MAX_RATES];
 
-	/* DO NOT ADD ANY FIELDS TO THIS STRUCTURE. It is used below in the
+	/*
+	 * DO NOT ADD ANY FIELDS TO THIS STRUCTURE. It is used below in the
 	 * Adhoc join command and will cause a binary layout mismatch with
 	 * the firmware
 	 */
diff -druN linux-2.6.39-libre/drivers/net/wireless/libertas/if_cs.c linux-3.0-rc7-libre/drivers/net/wireless/libertas/if_cs.c
--- linux-2.6.39-libre/drivers/net/wireless/libertas/if_cs.c	2011-05-19 02:14:43.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/libertas/if_cs.c	2011-07-21 06:57:05.000000000 -0400
@@ -21,6 +21,8 @@
 
 */
 
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/module.h>
 #include <linux/slab.h>
 #include <linux/delay.h>
@@ -306,7 +308,8 @@
 #define CF8385_MANFID		0x02df
 #define CF8385_CARDID		0x8103
 
-/* FIXME: just use the 'driver_info' field of 'struct pcmcia_device_id' when
+/*
+ * FIXME: just use the 'driver_info' field of 'struct pcmcia_device_id' when
  * that gets fixed.  Currently there's no way to access it from the probe hook.
  */
 static inline u32 get_model(u16 manf_id, u16 card_id)
@@ -355,7 +358,7 @@
 		if (status & IF_CS_BIT_COMMAND)
 			break;
 		if (++loops > 100) {
-			lbs_pr_err("card not ready for commands\n");
+			netdev_err(priv->dev, "card not ready for commands\n");
 			goto done;
 		}
 		mdelay(1);
@@ -425,14 +428,16 @@
 	/* is hardware ready? */
 	status = if_cs_read16(priv->card, IF_CS_CARD_STATUS);
 	if ((status & IF_CS_BIT_RESP) == 0) {
-		lbs_pr_err("no cmd response in card\n");
+		netdev_err(priv->dev, "no cmd response in card\n");
 		*len = 0;
 		goto out;
 	}
 
 	*len = if_cs_read16(priv->card, IF_CS_RESP_LEN);
 	if ((*len == 0) || (*len > LBS_CMD_BUFFER_SIZE)) {
-		lbs_pr_err("card cmd buffer has invalid # of bytes (%d)\n", *len);
+		netdev_err(priv->dev,
+			   "card cmd buffer has invalid # of bytes (%d)\n",
+			   *len);
 		goto out;
 	}
 
@@ -466,7 +471,9 @@
 
 	len = if_cs_read16(priv->card, IF_CS_READ_LEN);
 	if (len == 0 || len > MRVDRV_ETH_RX_PACKET_BUFFER_SIZE) {
-		lbs_pr_err("card data buffer has invalid # of bytes (%d)\n", len);
+		netdev_err(priv->dev,
+			   "card data buffer has invalid # of bytes (%d)\n",
+			   len);
 		priv->dev->stats.rx_dropped++;
 		goto dat_err;
 	}
@@ -615,8 +622,10 @@
 		if (remain < count)
 			count = remain;
 
-		/* "write the number of bytes to be sent to the I/O Command
-		 * write length register" */
+		/*
+		 * "write the number of bytes to be sent to the I/O Command
+		 * write length register"
+		 */
 		if_cs_write16(card, IF_CS_CMD_LEN, count);
 
 		/* "write this to I/O Command port register as 16 bit writes */
@@ -625,21 +634,27 @@
 				&fw->data[sent],
 				count >> 1);
 
-		/* "Assert the download over interrupt command in the Host
-		 * status register" */
+		/*
+		 * "Assert the download over interrupt command in the Host
+		 * status register"
+		 */
 		if_cs_write8(card, IF_CS_HOST_STATUS, IF_CS_BIT_COMMAND);
 
-		/* "Assert the download over interrupt command in the Card
-		 * interrupt case register" */
+		/*
+		 * "Assert the download over interrupt command in the Card
+		 * interrupt case register"
+		 */
 		if_cs_write16(card, IF_CS_HOST_INT_CAUSE, IF_CS_BIT_COMMAND);
 
-		/* "The host polls the Card Status register ... for 50 ms before
-		   declaring a failure */
+		/*
+		 * "The host polls the Card Status register ... for 50 ms before
+		 * declaring a failure"
+		 */
 		ret = if_cs_poll_while_fw_download(card, IF_CS_CARD_STATUS,
 			IF_CS_BIT_COMMAND);
 		if (ret < 0) {
-			lbs_pr_err("can't download helper at 0x%x, ret %d\n",
-				sent, ret);
+			pr_err("can't download helper at 0x%x, ret %d\n",
+			       sent, ret);
 			goto done;
 		}
 
@@ -669,7 +684,7 @@
 	ret = if_cs_poll_while_fw_download(card, IF_CS_SQ_READ_LOW,
 		IF_CS_SQ_HELPER_OK);
 	if (ret < 0) {
-		lbs_pr_err("helper firmware doesn't answer\n");
+		pr_err("helper firmware doesn't answer\n");
 		goto done;
 	}
 
@@ -677,13 +692,13 @@
 		len = if_cs_read16(card, IF_CS_SQ_READ_LOW);
 		if (len & 1) {
 			retry++;
-			lbs_pr_info("odd, need to retry this firmware block\n");
+			pr_info("odd, need to retry this firmware block\n");
 		} else {
 			retry = 0;
 		}
 
 		if (retry > 20) {
-			lbs_pr_err("could not download firmware\n");
+			pr_err("could not download firmware\n");
 			ret = -ENODEV;
 			goto done;
 		}
@@ -703,14 +718,14 @@
 		ret = if_cs_poll_while_fw_download(card, IF_CS_CARD_STATUS,
 			IF_CS_BIT_COMMAND);
 		if (ret < 0) {
-			lbs_pr_err("can't download firmware at 0x%x\n", sent);
+			pr_err("can't download firmware at 0x%x\n", sent);
 			goto done;
 		}
 	}
 
 	ret = if_cs_poll_while_fw_download(card, IF_CS_SCRATCH, 0x5a);
 	if (ret < 0)
-		lbs_pr_err("firmware download failed\n");
+		pr_err("firmware download failed\n");
 
 done:
 	lbs_deb_leave_args(LBS_DEB_CS, "ret %d", ret);
@@ -744,7 +759,8 @@
 		ret = if_cs_send_cmd(priv, buf, nb);
 		break;
 	default:
-		lbs_pr_err("%s: unsupported type %d\n", __func__, type);
+		netdev_err(priv->dev, "%s: unsupported type %d\n",
+			   __func__, type);
 	}
 
 	lbs_deb_leave_args(LBS_DEB_CS, "ret %d", ret);
@@ -773,7 +789,7 @@
 	p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_AUTO;
 
 	if (p_dev->resource[1]->end) {
-		lbs_pr_err("wrong CIS (check number of IO windows)\n");
+		pr_err("wrong CIS (check number of IO windows)\n");
 		return -ENODEV;
 	}
 
@@ -794,7 +810,7 @@
 
 	card = kzalloc(sizeof(struct if_cs_card), GFP_KERNEL);
 	if (!card) {
-		lbs_pr_err("error in kzalloc\n");
+		pr_err("error in kzalloc\n");
 		goto out;
 	}
 	card->p_dev = p_dev;
@@ -803,7 +819,7 @@
 	p_dev->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_SET_IO;
 
 	if (pcmcia_loop_config(p_dev, if_cs_ioprobe, NULL)) {
-		lbs_pr_err("error in pcmcia_loop_config\n");
+		pr_err("error in pcmcia_loop_config\n");
 		goto out1;
 	}
 
@@ -819,14 +835,14 @@
 	card->iobase = ioport_map(p_dev->resource[0]->start,
 				resource_size(p_dev->resource[0]));
 	if (!card->iobase) {
-		lbs_pr_err("error in ioport_map\n");
+		pr_err("error in ioport_map\n");
 		ret = -EIO;
 		goto out1;
 	}
 
 	ret = pcmcia_enable_device(p_dev);
 	if (ret) {
-		lbs_pr_err("error in pcmcia_enable_device\n");
+		pr_err("error in pcmcia_enable_device\n");
 		goto out2;
 	}
 
@@ -835,14 +851,14 @@
 
 	/*
 	 * Most of the libertas cards can do unaligned register access, but some
-	 * weird ones can not. That's especially true for the CF8305 card.
+	 * weird ones cannot. That's especially true for the CF8305 card.
 	 */
 	card->align_regs = 0;
 
 	card->model = get_model(p_dev->manf_id, p_dev->card_id);
 	if (card->model == MODEL_UNKNOWN) {
-		lbs_pr_err("unsupported manf_id 0x%04x / card_id 0x%04x\n",
-			   p_dev->manf_id, p_dev->card_id);
+		pr_err("unsupported manf_id 0x%04x / card_id 0x%04x\n",
+		       p_dev->manf_id, p_dev->card_id);
 		goto out2;
 	}
 
@@ -851,20 +867,20 @@
 	if (card->model == MODEL_8305) {
 		card->align_regs = 1;
 		if (prod_id < IF_CS_CF8305_B1_REV) {
-			lbs_pr_err("8305 rev B0 and older are not supported\n");
+			pr_err("8305 rev B0 and older are not supported\n");
 			ret = -ENODEV;
 			goto out2;
 		}
 	}
 
 	if ((card->model == MODEL_8381) && prod_id < IF_CS_CF8381_B3_REV) {
-		lbs_pr_err("8381 rev B2 and older are not supported\n");
+		pr_err("8381 rev B2 and older are not supported\n");
 		ret = -ENODEV;
 		goto out2;
 	}
 
 	if ((card->model == MODEL_8385) && prod_id < IF_CS_CF8385_B1_REV) {
-		lbs_pr_err("8385 rev B0 and older are not supported\n");
+		pr_err("8385 rev B0 and older are not supported\n");
 		ret = -ENODEV;
 		goto out2;
 	}
@@ -872,7 +888,7 @@
 	ret = lbs_get_firmware(&p_dev->dev, NULL, NULL, card->model,
 				&fw_table[0], &helper, &mainfw);
 	if (ret) {
-		lbs_pr_err("failed to find firmware (%d)\n", ret);
+		pr_err("failed to find firmware (%d)\n", ret);
 		goto out2;
 	}
 
@@ -903,18 +919,20 @@
 	ret = request_irq(p_dev->irq, if_cs_interrupt,
 		IRQF_SHARED, DRV_NAME, card);
 	if (ret) {
-		lbs_pr_err("error in request_irq\n");
+		pr_err("error in request_irq\n");
 		goto out3;
 	}
 
-	/* Clear any interrupt cause that happened while sending
-	 * firmware/initializing card */
+	/*
+	 * Clear any interrupt cause that happened while sending
+	 * firmware/initializing card
+	 */
 	if_cs_write16(card, IF_CS_CARD_INT_CAUSE, IF_CS_BIT_MASK);
 	if_cs_enable_ints(card);
 
 	/* And finally bring the card up */
 	if (lbs_start_card(priv) != 0) {
-		lbs_pr_err("could not activate card\n");
+		pr_err("could not activate card\n");
 		goto out3;
 	}
 
@@ -959,7 +977,7 @@
 /* Module initialization                                            */
 /********************************************************************/
 
-static struct pcmcia_device_id if_cs_ids[] = {
+static const struct pcmcia_device_id if_cs_ids[] = {
 	PCMCIA_DEVICE_MANF_CARD(CF8305_MANFID, CF8305_CARDID),
 	PCMCIA_DEVICE_MANF_CARD(CF8381_MANFID, CF8381_CARDID),
 	PCMCIA_DEVICE_MANF_CARD(CF8385_MANFID, CF8385_CARDID),
diff -druN linux-2.6.39-libre/drivers/net/wireless/libertas/if_sdio.c linux-3.0-rc7-libre/drivers/net/wireless/libertas/if_sdio.c
--- linux-2.6.39-libre/drivers/net/wireless/libertas/if_sdio.c	2011-05-19 02:14:45.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/libertas/if_sdio.c	2011-07-21 06:57:07.000000000 -0400
@@ -26,6 +26,8 @@
  * if_sdio_card_to_host() to pad the data.
  */
 
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/kernel.h>
 #include <linux/moduleparam.h>
 #include <linux/slab.h>
@@ -396,7 +398,7 @@
 
 out:
 	if (ret)
-		lbs_pr_err("problem fetching packet from firmware\n");
+		pr_err("problem fetching packet from firmware\n");
 
 	lbs_deb_leave_args(LBS_DEB_SDIO, "ret %d", ret);
 
@@ -433,7 +435,7 @@
 		}
 
 		if (ret)
-			lbs_pr_err("error %d sending packet to firmware\n", ret);
+			pr_err("error %d sending packet to firmware\n", ret);
 
 		sdio_release_host(card->func);
 
@@ -542,7 +544,7 @@
 
 out:
 	if (ret)
-		lbs_pr_err("failed to load helper firmware\n");
+		pr_err("failed to load helper firmware\n");
 
 	lbs_deb_leave_args(LBS_DEB_SDIO, "ret %d", ret);
 	return ret;
@@ -656,7 +658,7 @@
 
 out:
 	if (ret)
-		lbs_pr_err("failed to load firmware\n");
+		pr_err("failed to load firmware\n");
 
 	lbs_deb_leave_args(LBS_DEB_SDIO, "ret %d", ret);
 	return ret;
@@ -710,7 +712,7 @@
 	ret = lbs_get_firmware(&card->func->dev, lbs_helper_name, lbs_fw_name,
 				card->model, &fw_table[0], &helper, &mainfw);
 	if (ret) {
-		lbs_pr_err("failed to find firmware (%d)\n", ret);
+		pr_err("failed to find firmware (%d)\n", ret);
 		goto out;
 	}
 
@@ -836,7 +838,7 @@
 	ret = __lbs_cmd(priv, CMD_802_11_DEEP_SLEEP, &cmd, sizeof(cmd),
 			lbs_cmd_copyback, (unsigned long) &cmd);
 	if (ret)
-		lbs_pr_err("DEEP_SLEEP cmd failed\n");
+		netdev_err(priv->dev, "DEEP_SLEEP cmd failed\n");
 
 	mdelay(200);
 	return ret;
@@ -852,7 +854,7 @@
 
 	sdio_writeb(card->func, HOST_POWER_UP, CONFIGURATION_REG, &ret);
 	if (ret)
-		lbs_pr_err("sdio_writeb failed!\n");
+		netdev_err(priv->dev, "sdio_writeb failed!\n");
 
 	sdio_release_host(card->func);
 	lbs_deb_leave_args(LBS_DEB_SDIO, "ret %d", ret);
@@ -869,7 +871,7 @@
 
 	sdio_writeb(card->func, 0, CONFIGURATION_REG, &ret);
 	if (ret)
-		lbs_pr_err("sdio_writeb failed!\n");
+		netdev_err(priv->dev, "sdio_writeb failed!\n");
 
 	sdio_release_host(card->func);
 	lbs_deb_leave_args(LBS_DEB_SDIO, "ret %d", ret);
@@ -892,7 +894,7 @@
 	card = sdio_get_drvdata(func);
 
 	cause = sdio_readb(card->func, IF_SDIO_H_INT_STATUS, &ret);
-	if (ret)
+	if (ret || !cause)
 		goto out;
 
 	lbs_deb_sdio("interrupt: 0x%X\n", (unsigned)cause);
@@ -948,7 +950,7 @@
 	}
 
 	if (i == func->card->num_info) {
-		lbs_pr_err("unable to identify card model\n");
+		pr_err("unable to identify card model\n");
 		return -ENODEV;
 	}
 
@@ -982,7 +984,7 @@
 			break;
 	}
 	if (i == ARRAY_SIZE(fw_table)) {
-		lbs_pr_err("unknown card model 0x%x\n", card->model);
+		pr_err("unknown card model 0x%x\n", card->model);
 		ret = -ENODEV;
 		goto free;
 	}
@@ -993,10 +995,6 @@
 	if (ret)
 		goto release;
 
-	ret = sdio_claim_irq(func, if_sdio_interrupt);
-	if (ret)
-		goto disable;
-
 	/* For 1-bit transfers to the 8686 model, we need to enable the
 	 * interrupt flag in the CCCR register. Set the MMC_QUIRK_LENIENT_FN0
 	 * bit to allow access to non-vendor registers. */
@@ -1068,6 +1066,21 @@
 		card->rx_unit = 0;
 
 	/*
+	 * Set up the interrupt handler late.
+	 *
+	 * If we set it up earlier, the (buggy) hardware generates a spurious
+	 * interrupt, even before the interrupt has been enabled, with
+	 * CCCR_INTx = 0.
+	 *
+	 * We register the interrupt handler late so that we can handle any
+	 * spurious interrupts, and also to avoid generation of that known
+	 * spurious interrupt in the first place.
+	 */
+	ret = sdio_claim_irq(func, if_sdio_interrupt);
+	if (ret)
+		goto disable;
+
+	/*
 	 * Enable interrupts now that everything is set up
 	 */
 	sdio_writeb(func, 0x0f, IF_SDIO_H_INT_MASK, &ret);
@@ -1088,7 +1101,7 @@
 		lbs_deb_sdio("send function INIT command\n");
 		if (__lbs_cmd(priv, CMD_FUNC_INIT, &cmd, sizeof(cmd),
 				lbs_cmd_copyback, (unsigned long) &cmd))
-			lbs_pr_alert("CMD_FUNC_INIT cmd failed\n");
+			netdev_alert(priv->dev, "CMD_FUNC_INIT cmd failed\n");
 	}
 
 	ret = lbs_start_card(priv);
@@ -1150,7 +1163,7 @@
 		if (__lbs_cmd(card->priv, CMD_FUNC_SHUTDOWN,
 				&cmd, sizeof(cmd), lbs_cmd_copyback,
 				(unsigned long) &cmd))
-			lbs_pr_alert("CMD_FUNC_SHUTDOWN cmd failed\n");
+			pr_alert("CMD_FUNC_SHUTDOWN cmd failed\n");
 	}
 
 
@@ -1189,20 +1202,19 @@
 
 	mmc_pm_flag_t flags = sdio_get_host_pm_caps(func);
 
-	lbs_pr_info("%s: suspend: PM flags = 0x%x\n",
-						sdio_func_id(func), flags);
+	dev_info(dev, "%s: suspend: PM flags = 0x%x\n",
+		 sdio_func_id(func), flags);
 
 	/* If we aren't being asked to wake on anything, we should bail out
 	 * and let the SD stack power down the card.
 	 */
 	if (card->priv->wol_criteria == EHS_REMOVE_WAKEUP) {
-		lbs_pr_info("Suspend without wake params -- "
-						"powering down card.");
+		dev_info(dev, "Suspend without wake params -- powering down card\n");
 		return -ENOSYS;
 	}
 
 	if (!(flags & MMC_PM_KEEP_POWER)) {
-		lbs_pr_err("%s: cannot remain alive while host is suspended\n",
+		dev_err(dev, "%s: cannot remain alive while host is suspended\n",
 			sdio_func_id(func));
 		return -ENOSYS;
 	}
@@ -1224,7 +1236,7 @@
 	struct if_sdio_card *card = sdio_get_drvdata(func);
 	int ret;
 
-	lbs_pr_info("%s: resume: we're back\n", sdio_func_id(func));
+	dev_info(dev, "%s: resume: we're back\n", sdio_func_id(func));
 
 	ret = lbs_resume(card->priv);
 
diff -druN linux-2.6.39-libre/drivers/net/wireless/libertas/if_spi.c linux-3.0-rc7-libre/drivers/net/wireless/libertas/if_spi.c
--- linux-2.6.39-libre/drivers/net/wireless/libertas/if_spi.c	2011-05-19 02:14:47.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/libertas/if_spi.c	2011-07-21 06:57:10.000000000 -0400
@@ -17,6 +17,8 @@
  * (at your option) any later version.
  */
 
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/moduleparam.h>
 #include <linux/firmware.h>
 #include <linux/jiffies.h>
@@ -57,6 +59,7 @@
 	/* Handles all SPI communication (except for FW load) */
 	struct workqueue_struct		*workqueue;
 	struct work_struct		packet_work;
+	struct work_struct		resume_work;
 
 	u8				cmd_buffer[IF_SPI_CMD_BUF_SIZE];
 
@@ -68,6 +71,9 @@
 
 	/* Protects cmd_packet_list and data_packet_list */
 	spinlock_t			buffer_lock;
+
+	/* True is card suspended */
+	u8				suspended;
 };
 
 static void free_if_spi_card(struct if_spi_card *card)
@@ -131,8 +137,10 @@
 	card->prev_xfer_time = jiffies;
 }
 
-/* Write out a byte buffer to an SPI register,
- * using a series of 16-bit transfers. */
+/*
+ * Write out a byte buffer to an SPI register,
+ * using a series of 16-bit transfers.
+ */
 static int spu_write(struct if_spi_card *card, u16 reg, const u8 *buf, int len)
 {
 	int err = 0;
@@ -196,8 +204,10 @@
 	struct spi_transfer dummy_trans;
 	struct spi_transfer data_trans;
 
-	/* You must take an even number of bytes from the SPU, even if you
-	 * don't care about the last one.  */
+	/*
+	 * You must take an even number of bytes from the SPU, even if you
+	 * don't care about the last one.
+	 */
 	BUG_ON(len & 0x1);
 
 	spu_transaction_init(card);
@@ -246,8 +256,10 @@
 	return ret;
 }
 
-/* Read 32 bits from an SPI register.
- * The low 16 bits are read first. */
+/*
+ * Read 32 bits from an SPI register.
+ * The low 16 bits are read first.
+ */
 static int spu_read_u32(struct if_spi_card *card, u16 reg, u32 *val)
 {
 	__le32 buf;
@@ -259,13 +271,15 @@
 	return err;
 }
 
-/* Keep reading 16 bits from an SPI register until you get the correct result.
+/*
+ * Keep reading 16 bits from an SPI register until you get the correct result.
  *
  * If mask = 0, the correct result is any non-zero number.
  * If mask != 0, the correct result is any number where
  * number & target_mask == target
  *
- * Returns -ETIMEDOUT if a second passes without the correct result. */
+ * Returns -ETIMEDOUT if a second passes without the correct result.
+ */
 static int spu_wait_for_u16(struct if_spi_card *card, u16 reg,
 			u16 target_mask, u16 target)
 {
@@ -285,16 +299,17 @@
 		}
 		udelay(100);
 		if (time_after(jiffies, timeout)) {
-			lbs_pr_err("%s: timeout with val=%02x, "
-			       "target_mask=%02x, target=%02x\n",
+			pr_err("%s: timeout with val=%02x, target_mask=%02x, target=%02x\n",
 			       __func__, val, target_mask, target);
 			return -ETIMEDOUT;
 		}
 	}
 }
 
-/* Read 16 bits from an SPI register until you receive a specific value.
- * Returns -ETIMEDOUT if a 4 tries pass without success. */
+/*
+ * Read 16 bits from an SPI register until you receive a specific value.
+ * Returns -ETIMEDOUT if a 4 tries pass without success.
+ */
 static int spu_wait_for_u32(struct if_spi_card *card, u32 reg, u32 target)
 {
 	int err, try;
@@ -316,8 +331,10 @@
 {
 	int err = 0;
 
-	/* We can suppress a host interrupt by clearing the appropriate
-	 * bit in the "host interrupt status mask" register */
+	/*
+	 * We can suppress a host interrupt by clearing the appropriate
+	 * bit in the "host interrupt status mask" register
+	 */
 	if (suppress_host_int) {
 		err = spu_write_u16(card, IF_SPI_HOST_INT_STATUS_MASK_REG, 0);
 		if (err)
@@ -333,10 +350,12 @@
 			return err;
 	}
 
-	/* If auto-interrupts are on, the completion of certain transactions
+	/*
+	 * If auto-interrupts are on, the completion of certain transactions
 	 * will trigger an interrupt automatically. If auto-interrupts
 	 * are off, we need to set the "Card Interrupt Cause" register to
-	 * trigger a card interrupt. */
+	 * trigger a card interrupt.
+	 */
 	if (auto_int) {
 		err = spu_write_u16(card, IF_SPI_HOST_INT_CTRL_REG,
 				IF_SPI_HICT_TX_DOWNLOAD_OVER_AUTO |
@@ -379,7 +398,7 @@
 	if (err)
 		return err;
 	if ((rval & 0xF) != mode) {
-		lbs_pr_err("Can't read bus mode register.\n");
+		pr_err("Can't read bus mode register\n");
 		return -EIO;
 	}
 	return 0;
@@ -390,8 +409,10 @@
 	int err = 0;
 	u32 delay;
 
-	/* We have to start up in timed delay mode so that we can safely
-	 * read the Delay Read Register. */
+	/*
+	 * We have to start up in timed delay mode so that we can safely
+	 * read the Delay Read Register.
+	 */
 	card->use_dummy_writes = 0;
 	err = spu_set_bus_mode(card,
 				IF_SPI_BUS_MODE_SPI_CLOCK_PHASE_RISING |
@@ -447,8 +468,10 @@
 
 	/* Load helper firmware image */
 	while (bytes_remaining > 0) {
-		/* Scratch pad 1 should contain the number of bytes we
-		 * want to download to the firmware */
+		/*
+		 * Scratch pad 1 should contain the number of bytes we
+		 * want to download to the firmware
+		 */
 		err = spu_write_u16(card, IF_SPI_SCRATCH_1_REG,
 					HELPER_FW_LOAD_CHUNK_SZ);
 		if (err)
@@ -460,8 +483,10 @@
 		if (err)
 			goto out;
 
-		/* Feed the data into the command read/write port reg
-		 * in chunks of 64 bytes */
+		/*
+		 * Feed the data into the command read/write port reg
+		 * in chunks of 64 bytes
+		 */
 		memset(temp, 0, sizeof(temp));
 		memcpy(temp, fw,
 		       min(bytes_remaining, HELPER_FW_LOAD_CHUNK_SZ));
@@ -483,9 +508,11 @@
 		fw += HELPER_FW_LOAD_CHUNK_SZ;
 	}
 
-	/* Once the helper / single stage firmware download is complete,
+	/*
+	 * Once the helper / single stage firmware download is complete,
 	 * write 0 to scratch pad 1 and interrupt the
-	 * bootloader. This completes the helper download. */
+	 * bootloader. This completes the helper download.
+	 */
 	err = spu_write_u16(card, IF_SPI_SCRATCH_1_REG, FIRMWARE_DNLD_OK);
 	if (err)
 		goto out;
@@ -500,26 +527,30 @@
 
 out:
 	if (err)
-		lbs_pr_err("failed to load helper firmware (err=%d)\n", err);
+		pr_err("failed to load helper firmware (err=%d)\n", err);
 	lbs_deb_leave_args(LBS_DEB_SPI, "err %d", err);
 	return err;
 }
 
-/* Returns the length of the next packet the firmware expects us to send
- * Sets crc_err if the previous transfer had a CRC error. */
+/*
+ * Returns the length of the next packet the firmware expects us to send.
+ * Sets crc_err if the previous transfer had a CRC error.
+ */
 static int if_spi_prog_main_firmware_check_len(struct if_spi_card *card,
 						int *crc_err)
 {
 	u16 len;
 	int err = 0;
 
-	/* wait until the host interrupt status register indicates
-	 * that we are ready to download */
+	/*
+	 * wait until the host interrupt status register indicates
+	 * that we are ready to download
+	 */
 	err = spu_wait_for_u16(card, IF_SPI_HOST_INT_STATUS_REG,
 				IF_SPI_HIST_CMD_DOWNLOAD_RDY,
 				IF_SPI_HIST_CMD_DOWNLOAD_RDY);
 	if (err) {
-		lbs_pr_err("timed out waiting for host_int_status\n");
+		pr_err("timed out waiting for host_int_status\n");
 		return err;
 	}
 
@@ -529,9 +560,8 @@
 		return err;
 
 	if (len > IF_SPI_CMD_BUF_SIZE) {
-		lbs_pr_err("firmware load device requested a larger "
-			   "tranfer than we are prepared to "
-			   "handle. (len = %d)\n", len);
+		pr_err("firmware load device requested a larger transfer than we are prepared to handle (len = %d)\n",
+		       len);
 		return -EIO;
 	}
 	if (len & 0x1) {
@@ -547,6 +577,7 @@
 static int if_spi_prog_main_firmware(struct if_spi_card *card,
 					const struct firmware *firmware)
 {
+	struct lbs_private *priv = card->priv;
 	int len, prev_len;
 	int bytes, crc_err = 0, err = 0;
 	const u8 *fw;
@@ -560,8 +591,9 @@
 
 	err = spu_wait_for_u16(card, IF_SPI_SCRATCH_1_REG, 0, 0);
 	if (err) {
-		lbs_pr_err("%s: timed out waiting for initial "
-			   "scratch reg = 0\n", __func__);
+		netdev_err(priv->dev,
+			   "%s: timed out waiting for initial scratch reg = 0\n",
+			   __func__);
 		goto out;
 	}
 
@@ -575,17 +607,18 @@
 			goto out;
 		}
 		if (bytes < 0) {
-			/* If there are no more bytes left, we would normally
-			 * expect to have terminated with len = 0 */
-			lbs_pr_err("Firmware load wants more bytes "
-				   "than we have to offer.\n");
+			/*
+			 * If there are no more bytes left, we would normally
+			 * expect to have terminated with len = 0
+			 */
+			netdev_err(priv->dev,
+				   "Firmware load wants more bytes than we have to offer.\n");
 			break;
 		}
 		if (crc_err) {
 			/* Previous transfer failed. */
 			if (++num_crc_errs > MAX_MAIN_FW_LOAD_CRC_ERR) {
-				lbs_pr_err("Too many CRC errors encountered "
-					   "in firmware load.\n");
+				pr_err("Too many CRC errors encountered in firmware load.\n");
 				err = -EIO;
 				goto out;
 			}
@@ -614,21 +647,20 @@
 		prev_len = len;
 	}
 	if (bytes > prev_len) {
-		lbs_pr_err("firmware load wants fewer bytes than "
-			   "we have to offer.\n");
+		pr_err("firmware load wants fewer bytes than we have to offer\n");
 	}
 
 	/* Confirm firmware download */
 	err = spu_wait_for_u32(card, IF_SPI_SCRATCH_4_REG,
 					SUCCESSFUL_FW_DOWNLOAD_MAGIC);
 	if (err) {
-		lbs_pr_err("failed to confirm the firmware download\n");
+		pr_err("failed to confirm the firmware download\n");
 		goto out;
 	}
 
 out:
 	if (err)
-		lbs_pr_err("failed to load firmware (err=%d)\n", err);
+		pr_err("failed to load firmware (err=%d)\n", err);
 	lbs_deb_leave_args(LBS_DEB_SPI, "err %d", err);
 	return err;
 }
@@ -648,14 +680,18 @@
 	u16 len;
 	u8 i;
 
-	/* We need a buffer big enough to handle whatever people send to
-	 * hw_host_to_card */
+	/*
+	 * We need a buffer big enough to handle whatever people send to
+	 * hw_host_to_card
+	 */
 	BUILD_BUG_ON(IF_SPI_CMD_BUF_SIZE < LBS_CMD_BUFFER_SIZE);
 	BUILD_BUG_ON(IF_SPI_CMD_BUF_SIZE < LBS_UPLD_SIZE);
 
-	/* It's just annoying if the buffer size isn't a multiple of 4, because
-	 * then we might have len <  IF_SPI_CMD_BUF_SIZE but
-	 * ALIGN(len, 4) > IF_SPI_CMD_BUF_SIZE */
+	/*
+	 * It's just annoying if the buffer size isn't a multiple of 4, because
+	 * then we might have len < IF_SPI_CMD_BUF_SIZE but
+	 * ALIGN(len, 4) > IF_SPI_CMD_BUF_SIZE
+	 */
 	BUILD_BUG_ON(IF_SPI_CMD_BUF_SIZE % 4 != 0);
 
 	lbs_deb_enter(LBS_DEB_SPI);
@@ -665,13 +701,13 @@
 	if (err)
 		goto out;
 	if (!len) {
-		lbs_pr_err("%s: error: card has no data for host\n",
+		netdev_err(priv->dev, "%s: error: card has no data for host\n",
 			   __func__);
 		err = -EINVAL;
 		goto out;
 	} else if (len > IF_SPI_CMD_BUF_SIZE) {
-		lbs_pr_err("%s: error: response packet too large: "
-			   "%d bytes, but maximum is %d\n",
+		netdev_err(priv->dev,
+			   "%s: error: response packet too large: %d bytes, but maximum is %d\n",
 			   __func__, len, IF_SPI_CMD_BUF_SIZE);
 		err = -EINVAL;
 		goto out;
@@ -693,7 +729,7 @@
 
 out:
 	if (err)
-		lbs_pr_err("%s: err=%d\n", __func__, err);
+		netdev_err(priv->dev, "%s: err=%d\n", __func__, err);
 	lbs_deb_leave(LBS_DEB_SPI);
 	return err;
 }
@@ -701,6 +737,7 @@
 /* Move data from the card to the host */
 static int if_spi_c2h_data(struct if_spi_card *card)
 {
+	struct lbs_private *priv = card->priv;
 	struct sk_buff *skb;
 	char *data;
 	u16 len;
@@ -713,13 +750,13 @@
 	if (err)
 		goto out;
 	if (!len) {
-		lbs_pr_err("%s: error: card has no data for host\n",
+		netdev_err(priv->dev, "%s: error: card has no data for host\n",
 			   __func__);
 		err = -EINVAL;
 		goto out;
 	} else if (len > MRVDRV_ETH_RX_PACKET_BUFFER_SIZE) {
-		lbs_pr_err("%s: error: card has %d bytes of data, but "
-			   "our maximum skb size is %zu\n",
+		netdev_err(priv->dev,
+			   "%s: error: card has %d bytes of data, but our maximum skb size is %zu\n",
 			   __func__, len, MRVDRV_ETH_RX_PACKET_BUFFER_SIZE);
 		err = -EINVAL;
 		goto out;
@@ -751,7 +788,7 @@
 	dev_kfree_skb(skb);
 out:
 	if (err)
-		lbs_pr_err("%s: err=%d\n", __func__, err);
+		netdev_err(priv->dev, "%s: err=%d\n", __func__, err);
 	lbs_deb_leave(LBS_DEB_SPI);
 	return err;
 }
@@ -760,6 +797,7 @@
 static void if_spi_h2c(struct if_spi_card *card,
 			struct if_spi_packet *packet, int type)
 {
+	struct lbs_private *priv = card->priv;
 	int err = 0;
 	u16 int_type, port_reg;
 
@@ -773,7 +811,8 @@
 		port_reg = IF_SPI_CMD_RDWRPORT_REG;
 		break;
 	default:
-		lbs_pr_err("can't transfer buffer of type %d\n", type);
+		netdev_err(priv->dev, "can't transfer buffer of type %d\n",
+			   type);
 		err = -EINVAL;
 		goto out;
 	}
@@ -787,7 +826,7 @@
 	kfree(packet);
 
 	if (err)
-		lbs_pr_err("%s: error %d\n", __func__, err);
+		netdev_err(priv->dev, "%s: error %d\n", __func__, err);
 }
 
 /* Inform the host about a card event */
@@ -811,7 +850,7 @@
 	lbs_queue_event(priv, cause & 0xff);
 out:
 	if (err)
-		lbs_pr_err("%s: error %d\n", __func__, err);
+		netdev_err(priv->dev, "%s: error %d\n", __func__, err);
 }
 
 static void if_spi_host_to_card_worker(struct work_struct *work)
@@ -821,17 +860,21 @@
 	u16 hiStatus;
 	unsigned long flags;
 	struct if_spi_packet *packet;
+	struct lbs_private *priv;
 
 	card = container_of(work, struct if_spi_card, packet_work);
+	priv = card->priv;
 
 	lbs_deb_enter(LBS_DEB_SPI);
 
-	/* Read the host interrupt status register to see what we
-	 * can do. */
+	/*
+	 * Read the host interrupt status register to see what we
+	 * can do.
+	 */
 	err = spu_read_u16(card, IF_SPI_HOST_INT_STATUS_REG,
 				&hiStatus);
 	if (err) {
-		lbs_pr_err("I/O error\n");
+		netdev_err(priv->dev, "I/O error\n");
 		goto err;
 	}
 
@@ -846,12 +889,15 @@
 			goto err;
 	}
 
-	/* workaround: in PS mode, the card does not set the Command
-	 * Download Ready bit, but it sets TX Download Ready. */
+	/*
+	 * workaround: in PS mode, the card does not set the Command
+	 * Download Ready bit, but it sets TX Download Ready.
+	 */
 	if (hiStatus & IF_SPI_HIST_CMD_DOWNLOAD_RDY ||
 	   (card->priv->psstate != PS_STATE_FULL_POWER &&
 	    (hiStatus & IF_SPI_HIST_TX_DOWNLOAD_RDY))) {
-		/* This means two things. First of all,
+		/*
+		 * This means two things. First of all,
 		 * if there was a previous command sent, the card has
 		 * successfully received it.
 		 * Secondly, it is now ready to download another
@@ -859,8 +905,7 @@
 		 */
 		lbs_host_to_card_done(card->priv);
 
-		/* Do we have any command packets from the host to
-		 * send? */
+		/* Do we have any command packets from the host to send? */
 		packet = NULL;
 		spin_lock_irqsave(&card->buffer_lock, flags);
 		if (!list_empty(&card->cmd_packet_list)) {
@@ -874,8 +919,7 @@
 			if_spi_h2c(card, packet, MVMS_CMD);
 	}
 	if (hiStatus & IF_SPI_HIST_TX_DOWNLOAD_RDY) {
-		/* Do we have any data packets from the host to
-		 * send? */
+		/* Do we have any data packets from the host to send? */
 		packet = NULL;
 		spin_lock_irqsave(&card->buffer_lock, flags);
 		if (!list_empty(&card->data_packet_list)) {
@@ -893,7 +937,7 @@
 
 err:
 	if (err)
-		lbs_pr_err("%s: got error %d\n", __func__, err);
+		netdev_err(priv->dev, "%s: got error %d\n", __func__, err);
 
 	lbs_deb_leave(LBS_DEB_SPI);
 }
@@ -902,7 +946,8 @@
  * Host to Card
  *
  * Called from Libertas to transfer some data to the WLAN device
- * We can't sleep here. */
+ * We can't sleep here.
+ */
 static int if_spi_host_to_card(struct lbs_private *priv,
 				u8 type, u8 *buf, u16 nb)
 {
@@ -915,7 +960,8 @@
 	lbs_deb_enter_args(LBS_DEB_SPI, "type %d, bytes %d", type, nb);
 
 	if (nb == 0) {
-		lbs_pr_err("%s: invalid size requested: %d\n", __func__, nb);
+		netdev_err(priv->dev, "%s: invalid size requested: %d\n",
+			   __func__, nb);
 		err = -EINVAL;
 		goto out;
 	}
@@ -943,7 +989,8 @@
 		spin_unlock_irqrestore(&card->buffer_lock, flags);
 		break;
 	default:
-		lbs_pr_err("can't transfer buffer of type %d", type);
+		netdev_err(priv->dev, "can't transfer buffer of type %d\n",
+			   type);
 		err = -EINVAL;
 		break;
 	}
@@ -976,6 +1023,7 @@
 
 static int if_spi_init_card(struct if_spi_card *card)
 {
+	struct lbs_private *priv = card->priv;
 	struct spi_device *spi = card->spi;
 	int err, i;
 	u32 scratch;
@@ -1004,8 +1052,8 @@
 				break;
 		}
 		if (i == ARRAY_SIZE(fw_table)) {
-			lbs_pr_err("Unsupported chip_id: 0x%02x\n",
-					card->card_id);
+			netdev_err(priv->dev, "Unsupported chip_id: 0x%02x\n",
+				   card->card_id);
 			err = -ENODEV;
 			goto out;
 		}
@@ -1014,7 +1062,8 @@
 					card->card_id, &fw_table[0], &helper,
 					&mainfw);
 		if (err) {
-			lbs_pr_err("failed to find firmware (%d)\n", err);
+			netdev_err(priv->dev, "failed to find firmware (%d)\n",
+				   err);
 			goto out;
 		}
 
@@ -1049,6 +1098,28 @@
 	return err;
 }
 
+static void if_spi_resume_worker(struct work_struct *work)
+{
+	struct if_spi_card *card;
+
+	card = container_of(work, struct if_spi_card, resume_work);
+
+	if (card->suspended) {
+		if (card->pdata->setup)
+			card->pdata->setup(card->spi);
+
+		/* Init card ... */
+		if_spi_init_card(card);
+
+		enable_irq(card->spi->irq);
+
+		/* And resume it ... */
+		lbs_resume(card->priv);
+
+		card->suspended = 0;
+	}
+}
+
 static int __devinit if_spi_probe(struct spi_device *spi)
 {
 	struct if_spi_card *card;
@@ -1091,14 +1162,17 @@
 	if (err)
 		goto free_card;
 
-	/* Register our card with libertas.
-	 * This will call alloc_etherdev */
+	/*
+	 * Register our card with libertas.
+	 * This will call alloc_etherdev.
+	 */
 	priv = lbs_add_card(card, &spi->dev);
 	if (!priv) {
 		err = -ENOMEM;
 		goto free_card;
 	}
 	card->priv = priv;
+	priv->setup_fw_on_resume = 1;
 	priv->card = card;
 	priv->hw_host_to_card = if_spi_host_to_card;
 	priv->enter_deep_sleep = NULL;
@@ -1109,17 +1183,20 @@
 	/* Initialize interrupt handling stuff. */
 	card->workqueue = create_workqueue("libertas_spi");
 	INIT_WORK(&card->packet_work, if_spi_host_to_card_worker);
+	INIT_WORK(&card->resume_work, if_spi_resume_worker);
 
 	err = request_irq(spi->irq, if_spi_host_interrupt,
 			IRQF_TRIGGER_FALLING, "libertas_spi", card);
 	if (err) {
-		lbs_pr_err("can't get host irq line-- request_irq failed\n");
+		pr_err("can't get host irq line-- request_irq failed\n");
 		goto terminate_workqueue;
 	}
 
-	/* Start the card.
+	/*
+	 * Start the card.
 	 * This will call register_netdev, and we'll start
-	 * getting interrupts... */
+	 * getting interrupts...
+	 */
 	err = lbs_start_card(priv);
 	if (err)
 		goto release_irq;
@@ -1153,6 +1230,8 @@
 	lbs_deb_spi("libertas_spi_remove\n");
 	lbs_deb_enter(LBS_DEB_SPI);
 
+	cancel_work_sync(&card->resume_work);
+
 	lbs_stop_card(priv);
 	lbs_remove_card(priv); /* will call free_netdev */
 
@@ -1166,6 +1245,40 @@
 	return 0;
 }
 
+static int if_spi_suspend(struct device *dev)
+{
+	struct spi_device *spi = to_spi_device(dev);
+	struct if_spi_card *card = spi_get_drvdata(spi);
+
+	if (!card->suspended) {
+		lbs_suspend(card->priv);
+		flush_workqueue(card->workqueue);
+		disable_irq(spi->irq);
+
+		if (card->pdata->teardown)
+			card->pdata->teardown(spi);
+		card->suspended = 1;
+	}
+
+	return 0;
+}
+
+static int if_spi_resume(struct device *dev)
+{
+	struct spi_device *spi = to_spi_device(dev);
+	struct if_spi_card *card = spi_get_drvdata(spi);
+
+	/* Schedule delayed work */
+	schedule_work(&card->resume_work);
+
+	return 0;
+}
+
+static const struct dev_pm_ops if_spi_pm_ops = {
+	.suspend	= if_spi_suspend,
+	.resume		= if_spi_resume,
+};
+
 static struct spi_driver libertas_spi_driver = {
 	.probe	= if_spi_probe,
 	.remove = __devexit_p(libertas_spi_remove),
@@ -1173,6 +1286,7 @@
 		.name	= "libertas_spi",
 		.bus	= &spi_bus_type,
 		.owner	= THIS_MODULE,
+		.pm	= &if_spi_pm_ops,
 	},
 };
 
diff -druN linux-2.6.39-libre/drivers/net/wireless/libertas/if_spi.h linux-3.0-rc7-libre/drivers/net/wireless/libertas/if_spi.h
--- linux-2.6.39-libre/drivers/net/wireless/libertas/if_spi.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/libertas/if_spi.h	2011-07-11 19:51:52.000000000 -0400
@@ -86,34 +86,34 @@
 #define IF_SPI_DEVICEID_CTRL_REG_TO_CARD_REV(dc) (dc & 0x000000ff)
 
 /***************** IF_SPI_HOST_INT_CTRL_REG *****************/
-/** Host Interrupt Control bit : Wake up */
+/* Host Interrupt Control bit : Wake up */
 #define IF_SPI_HICT_WAKE_UP				(1<<0)
-/** Host Interrupt Control bit : WLAN ready */
+/* Host Interrupt Control bit : WLAN ready */
 #define IF_SPI_HICT_WLAN_READY				(1<<1)
 /*#define IF_SPI_HICT_FIFO_FIRST_HALF_EMPTY		(1<<2) */
 /*#define IF_SPI_HICT_FIFO_SECOND_HALF_EMPTY		(1<<3) */
 /*#define IF_SPI_HICT_IRQSRC_WLAN			(1<<4) */
-/** Host Interrupt Control bit : Tx auto download */
+/* Host Interrupt Control bit : Tx auto download */
 #define IF_SPI_HICT_TX_DOWNLOAD_OVER_AUTO		(1<<5)
-/** Host Interrupt Control bit : Rx auto upload */
+/* Host Interrupt Control bit : Rx auto upload */
 #define IF_SPI_HICT_RX_UPLOAD_OVER_AUTO			(1<<6)
-/** Host Interrupt Control bit : Command auto download */
+/* Host Interrupt Control bit : Command auto download */
 #define IF_SPI_HICT_CMD_DOWNLOAD_OVER_AUTO		(1<<7)
-/** Host Interrupt Control bit : Command auto upload */
+/* Host Interrupt Control bit : Command auto upload */
 #define IF_SPI_HICT_CMD_UPLOAD_OVER_AUTO		(1<<8)
 
 /***************** IF_SPI_CARD_INT_CAUSE_REG *****************/
-/** Card Interrupt Case bit : Tx download over */
+/* Card Interrupt Case bit : Tx download over */
 #define IF_SPI_CIC_TX_DOWNLOAD_OVER			(1<<0)
-/** Card Interrupt Case bit : Rx upload over */
+/* Card Interrupt Case bit : Rx upload over */
 #define IF_SPI_CIC_RX_UPLOAD_OVER			(1<<1)
-/** Card Interrupt Case bit : Command download over */
+/* Card Interrupt Case bit : Command download over */
 #define IF_SPI_CIC_CMD_DOWNLOAD_OVER			(1<<2)
-/** Card Interrupt Case bit : Host event */
+/* Card Interrupt Case bit : Host event */
 #define IF_SPI_CIC_HOST_EVENT				(1<<3)
-/** Card Interrupt Case bit : Command upload over */
+/* Card Interrupt Case bit : Command upload over */
 #define IF_SPI_CIC_CMD_UPLOAD_OVER			(1<<4)
-/** Card Interrupt Case bit : Power down */
+/* Card Interrupt Case bit : Power down */
 #define IF_SPI_CIC_POWER_DOWN				(1<<5)
 
 /***************** IF_SPI_CARD_INT_STATUS_REG *****************/
@@ -138,51 +138,51 @@
 #define IF_SPI_HICU_CMD_RD_FIFO_UNDERFLOW		(1<<10)
 
 /***************** IF_SPI_HOST_INT_STATUS_REG *****************/
-/** Host Interrupt Status bit : Tx download ready */
+/* Host Interrupt Status bit : Tx download ready */
 #define IF_SPI_HIST_TX_DOWNLOAD_RDY			(1<<0)
-/** Host Interrupt Status bit : Rx upload ready */
+/* Host Interrupt Status bit : Rx upload ready */
 #define IF_SPI_HIST_RX_UPLOAD_RDY			(1<<1)
-/** Host Interrupt Status bit : Command download ready */
+/* Host Interrupt Status bit : Command download ready */
 #define IF_SPI_HIST_CMD_DOWNLOAD_RDY			(1<<2)
-/** Host Interrupt Status bit : Card event */
+/* Host Interrupt Status bit : Card event */
 #define IF_SPI_HIST_CARD_EVENT				(1<<3)
-/** Host Interrupt Status bit : Command upload ready */
+/* Host Interrupt Status bit : Command upload ready */
 #define IF_SPI_HIST_CMD_UPLOAD_RDY			(1<<4)
-/** Host Interrupt Status bit : I/O write FIFO overflow */
+/* Host Interrupt Status bit : I/O write FIFO overflow */
 #define IF_SPI_HIST_IO_WR_FIFO_OVERFLOW			(1<<5)
-/** Host Interrupt Status bit : I/O read FIFO underflow */
+/* Host Interrupt Status bit : I/O read FIFO underflow */
 #define IF_SPI_HIST_IO_RD_FIFO_UNDRFLOW			(1<<6)
-/** Host Interrupt Status bit : Data write FIFO overflow */
+/* Host Interrupt Status bit : Data write FIFO overflow */
 #define IF_SPI_HIST_DATA_WR_FIFO_OVERFLOW		(1<<7)
-/** Host Interrupt Status bit : Data read FIFO underflow */
+/* Host Interrupt Status bit : Data read FIFO underflow */
 #define IF_SPI_HIST_DATA_RD_FIFO_UNDERFLOW		(1<<8)
-/** Host Interrupt Status bit : Command write FIFO overflow */
+/* Host Interrupt Status bit : Command write FIFO overflow */
 #define IF_SPI_HIST_CMD_WR_FIFO_OVERFLOW		(1<<9)
-/** Host Interrupt Status bit : Command read FIFO underflow */
+/* Host Interrupt Status bit : Command read FIFO underflow */
 #define IF_SPI_HIST_CMD_RD_FIFO_UNDERFLOW		(1<<10)
 
 /***************** IF_SPI_HOST_INT_STATUS_MASK_REG *****************/
-/** Host Interrupt Status Mask bit : Tx download ready */
+/* Host Interrupt Status Mask bit : Tx download ready */
 #define IF_SPI_HISM_TX_DOWNLOAD_RDY			(1<<0)
-/** Host Interrupt Status Mask bit : Rx upload ready */
+/* Host Interrupt Status Mask bit : Rx upload ready */
 #define IF_SPI_HISM_RX_UPLOAD_RDY			(1<<1)
-/** Host Interrupt Status Mask bit : Command download ready */
+/* Host Interrupt Status Mask bit : Command download ready */
 #define IF_SPI_HISM_CMD_DOWNLOAD_RDY			(1<<2)
-/** Host Interrupt Status Mask bit : Card event */
+/* Host Interrupt Status Mask bit : Card event */
 #define IF_SPI_HISM_CARDEVENT				(1<<3)
-/** Host Interrupt Status Mask bit : Command upload ready */
+/* Host Interrupt Status Mask bit : Command upload ready */
 #define IF_SPI_HISM_CMD_UPLOAD_RDY			(1<<4)
-/** Host Interrupt Status Mask bit : I/O write FIFO overflow */
+/* Host Interrupt Status Mask bit : I/O write FIFO overflow */
 #define IF_SPI_HISM_IO_WR_FIFO_OVERFLOW			(1<<5)
-/** Host Interrupt Status Mask bit : I/O read FIFO underflow */
+/* Host Interrupt Status Mask bit : I/O read FIFO underflow */
 #define IF_SPI_HISM_IO_RD_FIFO_UNDERFLOW		(1<<6)
-/** Host Interrupt Status Mask bit : Data write FIFO overflow */
+/* Host Interrupt Status Mask bit : Data write FIFO overflow */
 #define IF_SPI_HISM_DATA_WR_FIFO_OVERFLOW		(1<<7)
-/** Host Interrupt Status Mask bit : Data write FIFO underflow */
+/* Host Interrupt Status Mask bit : Data write FIFO underflow */
 #define IF_SPI_HISM_DATA_RD_FIFO_UNDERFLOW		(1<<8)
-/** Host Interrupt Status Mask bit : Command write FIFO overflow */
+/* Host Interrupt Status Mask bit : Command write FIFO overflow */
 #define IF_SPI_HISM_CMD_WR_FIFO_OVERFLOW		(1<<9)
-/** Host Interrupt Status Mask bit : Command write FIFO underflow */
+/* Host Interrupt Status Mask bit : Command write FIFO underflow */
 #define IF_SPI_HISM_CMD_RD_FIFO_UNDERFLOW		(1<<10)
 
 /***************** IF_SPI_SPU_BUS_MODE_REG *****************/
diff -druN linux-2.6.39-libre/drivers/net/wireless/libertas/if_usb.c linux-3.0-rc7-libre/drivers/net/wireless/libertas/if_usb.c
--- linux-2.6.39-libre/drivers/net/wireless/libertas/if_usb.c	2011-05-19 02:14:50.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/libertas/if_usb.c	2011-07-21 06:57:12.000000000 -0400
@@ -1,6 +1,9 @@
-/**
-  * This file contains functions used in USB interface module.
-  */
+/*
+ * This file contains functions used in USB interface module.
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/delay.h>
 #include <linux/moduleparam.h>
 #include <linux/firmware.h>
@@ -62,7 +65,7 @@
 
 /* sysfs hooks */
 
-/**
+/*
  *  Set function to write firmware to device's persistent memory
  */
 static ssize_t if_usb_firmware_set(struct device *dev,
@@ -85,7 +88,14 @@
 static DEVICE_ATTR(lbs_flash_fw, 0200, NULL, if_usb_firmware_set);
 
 /**
- *  Set function to write firmware to device's persistent memory
+ * if_usb_boot2_set - write firmware to device's persistent memory
+ *
+ * @dev: target device
+ * @attr: device attributes
+ * @buf: firmware buffer to write
+ * @count: number of bytes to write
+ *
+ * returns: number of bytes written or negative error code
  */
 static ssize_t if_usb_boot2_set(struct device *dev,
 		struct device_attribute *attr, const char *buf, size_t count)
@@ -107,9 +117,10 @@
 static DEVICE_ATTR(lbs_flash_boot2, 0200, NULL, if_usb_boot2_set);
 
 /**
- *  @brief  call back function to handle the status of the URB
- *  @param urb 		pointer to urb structure
- *  @return 	   	N/A
+ * if_usb_write_bulk_callback - callback function to handle the status
+ * of the URB
+ * @urb:	pointer to &urb structure
+ * returns:	N/A
  */
 static void if_usb_write_bulk_callback(struct urb *urb)
 {
@@ -131,14 +142,14 @@
 			lbs_host_to_card_done(priv);
 	} else {
 		/* print the failure status number for debug */
-		lbs_pr_info("URB in failure status: %d\n", urb->status);
+		pr_info("URB in failure status: %d\n", urb->status);
 	}
 }
 
 /**
- *  @brief  free tx/rx urb, skb and rx buffer
- *  @param cardp	pointer if_usb_card
- *  @return 	   	N/A
+ * if_usb_free - free tx/rx urb, skb and rx buffer
+ * @cardp:	pointer to &if_usb_card
+ * returns:	N/A
  */
 static void if_usb_free(struct if_usb_card *cardp)
 {
@@ -181,7 +192,7 @@
 	wake_method.hdr.size = cpu_to_le16(sizeof(wake_method));
 	wake_method.action = cpu_to_le16(CMD_ACT_GET);
 	if (lbs_cmd_with_response(priv, CMD_802_11_FW_WAKE_METHOD, &wake_method)) {
-		lbs_pr_info("Firmware does not seem to support PS mode\n");
+		netdev_info(priv->dev, "Firmware does not seem to support PS mode\n");
 		priv->fwcapinfo &= ~FW_CAPINFO_PS;
 	} else {
 		if (le16_to_cpu(wake_method.method) == CMD_WAKE_METHOD_COMMAND_INT) {
@@ -190,7 +201,8 @@
 			/* The versions which boot up this way don't seem to
 			   work even if we set it to the command interrupt */
 			priv->fwcapinfo &= ~FW_CAPINFO_PS;
-			lbs_pr_info("Firmware doesn't wake via command interrupt; disabling PS mode\n");
+			netdev_info(priv->dev,
+				    "Firmware doesn't wake via command interrupt; disabling PS mode\n");
 		}
 	}
 }
@@ -202,7 +214,7 @@
 	if (cardp->fwdnldover) {
 		lbs_deb_usb("Download complete, no event. Assuming success\n");
 	} else {
-		lbs_pr_err("Download timed out\n");
+		pr_err("Download timed out\n");
 		cardp->surprise_removed = 1;
 	}
 	wake_up(&cardp->fw_wq);
@@ -217,10 +229,10 @@
 #endif
 
 /**
- *  @brief sets the configuration values
- *  @param ifnum	interface number
- *  @param id		pointer to usb_device_id
- *  @return 	   	0 on success, error code on failure
+ * if_usb_probe - sets the configuration values
+ * @intf:	&usb_interface pointer
+ * @id:	pointer to usb_device_id
+ * returns:	0 on success, error code on failure
  */
 static int if_usb_probe(struct usb_interface *intf,
 			const struct usb_device_id *id)
@@ -236,7 +248,7 @@
 
 	cardp = kzalloc(sizeof(struct if_usb_card), GFP_KERNEL);
 	if (!cardp) {
-		lbs_pr_err("Out of memory allocating private data.\n");
+		pr_err("Out of memory allocating private data\n");
 		goto error;
 	}
 
@@ -326,10 +338,12 @@
 	usb_set_intfdata(intf, cardp);
 
 	if (device_create_file(&priv->dev->dev, &dev_attr_lbs_flash_fw))
-		lbs_pr_err("cannot register lbs_flash_fw attribute\n");
+		netdev_err(priv->dev,
+			   "cannot register lbs_flash_fw attribute\n");
 
 	if (device_create_file(&priv->dev->dev, &dev_attr_lbs_flash_boot2))
-		lbs_pr_err("cannot register lbs_flash_boot2 attribute\n");
+		netdev_err(priv->dev,
+			   "cannot register lbs_flash_boot2 attribute\n");
 
 	/*
 	 * EHS_REMOVE_WAKEUP is not supported on all versions of the firmware.
@@ -352,9 +366,9 @@
 }
 
 /**
- *  @brief free resource and cleanup
- *  @param intf		USB interface structure
- *  @return 	   	N/A
+ * if_usb_disconnect - free resource and cleanup
+ * @intf:	USB interface structure
+ * returns:	N/A
  */
 static void if_usb_disconnect(struct usb_interface *intf)
 {
@@ -384,9 +398,9 @@
 }
 
 /**
- *  @brief  This function download FW
- *  @param priv		pointer to struct lbs_private
- *  @return 	   	0
+ * if_usb_send_fw_pkt - download FW
+ * @cardp:	pointer to &struct if_usb_card
+ * returns:	0
  */
 static int if_usb_send_fw_pkt(struct if_usb_card *cardp)
 {
@@ -472,11 +486,11 @@
 }
 
 /**
- *  @brief This function transfer the data to the device.
- *  @param priv 	pointer to struct lbs_private
- *  @param payload	pointer to payload data
- *  @param nb		data length
- *  @return 	   	0 or -1
+ *  usb_tx_block - transfer the data to the device
+ *  @cardp: 	pointer to &struct if_usb_card
+ *  @payload:	pointer to payload data
+ *  @nb:	data length
+ *  returns:	0 for success or negative error code
  */
 static int usb_tx_block(struct if_usb_card *cardp, uint8_t *payload, uint16_t nb)
 {
@@ -514,7 +528,7 @@
 	int ret = -1;
 
 	if (!(skb = dev_alloc_skb(MRVDRV_ETH_RX_PACKET_BUFFER_SIZE))) {
-		lbs_pr_err("No free skb\n");
+		pr_err("No free skb\n");
 		goto rx_ret;
 	}
 
@@ -573,7 +587,7 @@
 
 		if (tmp[0] == cpu_to_le32(CMD_TYPE_INDICATION) &&
 		    tmp[1] == cpu_to_le32(MACREG_INT_CODE_FIRMWARE_READY)) {
-			lbs_pr_info("Firmware ready event received\n");
+			pr_info("Firmware ready event received\n");
 			wake_up(&cardp->fw_wq);
 		} else {
 			lbs_deb_usb("Waiting for confirmation; got %x %x\n",
@@ -600,20 +614,20 @@
 			    bootcmdresp.magic == cpu_to_le32(CMD_TYPE_DATA) ||
 			    bootcmdresp.magic == cpu_to_le32(CMD_TYPE_INDICATION)) {
 				if (!cardp->bootcmdresp)
-					lbs_pr_info("Firmware already seems alive; resetting\n");
+					pr_info("Firmware already seems alive; resetting\n");
 				cardp->bootcmdresp = -1;
 			} else {
-				lbs_pr_info("boot cmd response wrong magic number (0x%x)\n",
+				pr_info("boot cmd response wrong magic number (0x%x)\n",
 					    le32_to_cpu(bootcmdresp.magic));
 			}
 		} else if ((bootcmdresp.cmd != BOOT_CMD_FW_BY_USB) &&
 			   (bootcmdresp.cmd != BOOT_CMD_UPDATE_FW) &&
 			   (bootcmdresp.cmd != BOOT_CMD_UPDATE_BOOT2)) {
-			lbs_pr_info("boot cmd response cmd_tag error (%d)\n",
-				    bootcmdresp.cmd);
+			pr_info("boot cmd response cmd_tag error (%d)\n",
+				bootcmdresp.cmd);
 		} else if (bootcmdresp.result != BOOT_CMD_RESP_OK) {
-			lbs_pr_info("boot cmd response result error (%d)\n",
-				    bootcmdresp.result);
+			pr_info("boot cmd response result error (%d)\n",
+				bootcmdresp.result);
 		} else {
 			cardp->bootcmdresp = 1;
 			lbs_deb_usbd(&cardp->udev->dev,
@@ -713,11 +727,11 @@
 }
 
 /**
- *  @brief This function reads of the packet into the upload buff,
- *  wake up the main thread and initialise the Rx callack.
+ *  if_usb_receive - read the packet into the upload buffer,
+ *  wake up the main thread and initialise the Rx callack
  *
- *  @param urb		pointer to struct urb
- *  @return 	   	N/A
+ *  @urb:	pointer to &struct urb
+ *  returns:	N/A
  */
 static void if_usb_receive(struct urb *urb)
 {
@@ -788,12 +802,12 @@
 }
 
 /**
- *  @brief This function downloads data to FW
- *  @param priv		pointer to struct lbs_private structure
- *  @param type		type of data
- *  @param buf		pointer to data buffer
- *  @param len		number of bytes
- *  @return 	   	0 or -1
+ *  if_usb_host_to_card - downloads data to FW
+ *  @priv:	pointer to &struct lbs_private structure
+ *  @type:	type of data
+ *  @payload:	pointer to data buffer
+ *  @nb:	number of bytes
+ *  returns:	0 for success or negative error code
  */
 static int if_usb_host_to_card(struct lbs_private *priv, uint8_t type,
 			       uint8_t *payload, uint16_t nb)
@@ -817,10 +831,11 @@
 }
 
 /**
- *  @brief This function issues Boot command to the Boot2 code
- *  @param ivalue   1:Boot from FW by USB-Download
- *                  2:Boot from FW in EEPROM
- *  @return 	   	0
+ *  if_usb_issue_boot_command - issues Boot command to the Boot2 code
+ *  @cardp:	pointer to &if_usb_card
+ *  @ivalue:	1:Boot from FW by USB-Download
+ *		2:Boot from FW in EEPROM
+ *  returns:	0 for success or negative error code
  */
 static int if_usb_issue_boot_command(struct if_usb_card *cardp, int ivalue)
 {
@@ -839,11 +854,11 @@
 
 
 /**
- *  @brief This function checks the validity of Boot2/FW image.
+ *  check_fwfile_format - check the validity of Boot2/FW image
  *
- *  @param data              pointer to image
- *         len               image length
- *  @return     0 or -1
+ *  @data:	pointer to image
+ *  @totlen:	image length
+ *  returns:     0 (good) or 1 (failure)
  */
 static int check_fwfile_format(const uint8_t *data, uint32_t totlen)
 {
@@ -878,7 +893,7 @@
 	} while (!exit);
 
 	if (ret)
-		lbs_pr_err("firmware file format check FAIL\n");
+		pr_err("firmware file format check FAIL\n");
 	else
 		lbs_deb_fw("firmware file format check PASS\n");
 
@@ -887,13 +902,13 @@
 
 
 /**
-*  @brief This function programs the firmware subject to cmd
+*  if_usb_prog_firmware - programs the firmware subject to cmd
 *
-*  @param cardp             the if_usb_card descriptor
-*         fwname            firmware or boot2 image file name
-*         cmd               either BOOT_CMD_FW_BY_USB, BOOT_CMD_UPDATE_FW,
-*                           or BOOT_CMD_UPDATE_BOOT2.
-*  @return     0 or error code
+*  @cardp:	the if_usb_card descriptor
+*  @fwname:	firmware or boot2 image file name
+*  @cmd:	either BOOT_CMD_FW_BY_USB, BOOT_CMD_UPDATE_FW,
+*		or BOOT_CMD_UPDATE_BOOT2.
+*  returns:	0 or error code
 */
 static int if_usb_prog_firmware(struct if_usb_card *cardp,
 				const char *fwname, int cmd)
@@ -975,7 +990,7 @@
 
 	ret = get_fw(cardp, fwname);
 	if (ret) {
-		lbs_pr_err("failed to find firmware (%d)\n", ret);
+		pr_err("failed to find firmware (%d)\n", ret);
 		goto done;
 	}
 
@@ -1050,13 +1065,13 @@
 	usb_kill_urb(cardp->rx_urb);
 
 	if (!cardp->fwdnldover) {
-		lbs_pr_info("failed to load fw, resetting device!\n");
+		pr_info("failed to load fw, resetting device!\n");
 		if (--reset_count >= 0) {
 			if_usb_reset_device(cardp);
 			goto restart;
 		}
 
-		lbs_pr_info("FW download failure, time = %d ms\n", i * 100);
+		pr_info("FW download failure, time = %d ms\n", i * 100);
 		ret = -EIO;
 		goto release_fw;
 	}
diff -druN linux-2.6.39-libre/drivers/net/wireless/libertas/if_usb.h linux-3.0-rc7-libre/drivers/net/wireless/libertas/if_usb.h
--- linux-2.6.39-libre/drivers/net/wireless/libertas/if_usb.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/libertas/if_usb.h	2011-07-11 19:51:52.000000000 -0400
@@ -6,9 +6,9 @@
 
 struct lbs_private;
 
-/**
-  * This file contains definition for USB interface.
-  */
+/*
+ * This file contains definition for USB interface.
+ */
 #define CMD_TYPE_REQUEST		0xF00DFACE
 #define CMD_TYPE_DATA			0xBEADC0DE
 #define CMD_TYPE_INDICATION		0xBEEFFACE
@@ -40,7 +40,7 @@
 	uint8_t	pad[2];
 };
 
-/** USB card description structure*/
+/* USB card description structure*/
 struct if_usb_card {
 	struct usb_device *udev;
 	uint32_t model;  /* MODEL_* */
@@ -77,7 +77,7 @@
 	__le16 boot2_version;
 };
 
-/** fwheader */
+/* fwheader */
 struct fwheader {
 	__le32 dnldcmd;
 	__le32 baseaddr;
@@ -86,14 +86,14 @@
 };
 
 #define FW_MAX_DATA_BLK_SIZE	600
-/** FWData */
+/* FWData */
 struct fwdata {
 	struct fwheader hdr;
 	__le32 seqnum;
 	uint8_t data[0];
 };
 
-/** fwsyncheader */
+/* fwsyncheader */
 struct fwsyncheader {
 	__le32 cmd;
 	__le32 seqnum;
diff -druN linux-2.6.39-libre/drivers/net/wireless/libertas/main.c linux-3.0-rc7-libre/drivers/net/wireless/libertas/main.c
--- linux-2.6.39-libre/drivers/net/wireless/libertas/main.c	2011-05-19 02:14:41.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/libertas/main.c	2011-07-21 06:57:03.000000000 -0400
@@ -1,8 +1,10 @@
-/**
-  * This file contains the major functions in WLAN
-  * driver. It includes init, exit, open, close and main
-  * thread etc..
-  */
+/*
+ * This file contains the major functions in WLAN
+ * driver. It includes init, exit, open, close and main
+ * thread etc..
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 
 #include <linux/moduleparam.h>
 #include <linux/delay.h>
@@ -34,19 +36,25 @@
 EXPORT_SYMBOL_GPL(lbs_debug);
 module_param_named(libertas_debug, lbs_debug, int, 0644);
 
+unsigned int lbs_disablemesh;
+EXPORT_SYMBOL_GPL(lbs_disablemesh);
+module_param_named(libertas_disablemesh, lbs_disablemesh, int, 0644);
 
-/* This global structure is used to send the confirm_sleep command as
- * fast as possible down to the firmware. */
+
+/*
+ * This global structure is used to send the confirm_sleep command as
+ * fast as possible down to the firmware.
+ */
 struct cmd_confirm_sleep confirm_sleep;
 
 
-/**
+/*
  * the table to keep region code
  */
 u16 lbs_region_code_to_index[MRVDRV_MAX_REGION_CODE] =
     { 0x10, 0x20, 0x30, 0x31, 0x32, 0x40 };
 
-/**
+/*
  * FW rate table.  FW refers to rates by their index in this table, not by the
  * rate value itself.  Values of 0x00 are
  * reserved positions.
@@ -57,10 +65,10 @@
 };
 
 /**
- *  @brief use index to get the data rate
+ *  lbs_fw_index_to_data_rate - use index to get the data rate
  *
- *  @param idx                The index of data rate
- *  @return 	   		data rate or 0
+ *  @idx:	The index of data rate
+ *  returns:	data rate or 0
  */
 u32 lbs_fw_index_to_data_rate(u8 idx)
 {
@@ -70,10 +78,10 @@
 }
 
 /**
- *  @brief use rate to get the index
+ *  lbs_data_rate_to_fw_index - use rate to get the index
  *
- *  @param rate                 data rate
- *  @return 	   		index or 0
+ *  @rate:	data rate
+ *  returns:	index or 0
  */
 u8 lbs_data_rate_to_fw_index(u32 rate)
 {
@@ -91,10 +99,10 @@
 
 
 /**
- *  @brief This function opens the ethX interface
+ *  lbs_dev_open - open the ethX interface
  *
- *  @param dev     A pointer to net_device structure
- *  @return 	   0 or -EBUSY if monitor mode active
+ *  @dev:	A pointer to &net_device structure
+ *  returns:	0 or -EBUSY if monitor mode active
  */
 static int lbs_dev_open(struct net_device *dev)
 {
@@ -120,10 +128,10 @@
 }
 
 /**
- *  @brief This function closes the ethX interface
+ *  lbs_eth_stop - close the ethX interface
  *
- *  @param dev     A pointer to net_device structure
- *  @return 	   0
+ *  @dev:	A pointer to &net_device structure
+ *  returns:	0
  */
 static int lbs_eth_stop(struct net_device *dev)
 {
@@ -147,28 +155,6 @@
 	return 0;
 }
 
-static void lbs_tx_timeout(struct net_device *dev)
-{
-	struct lbs_private *priv = dev->ml_priv;
-
-	lbs_deb_enter(LBS_DEB_TX);
-
-	lbs_pr_err("tx watch dog timeout\n");
-
-	dev->trans_start = jiffies; /* prevent tx timeout */
-
-	if (priv->currenttxskb)
-		lbs_send_tx_feedback(priv, 0);
-
-	/* XX: Shouldn't we also call into the hw-specific driver
-	   to kick it somehow? */
-	lbs_host_to_card_done(priv);
-
-	/* FIXME: reset the card */
-
-	lbs_deb_leave(LBS_DEB_TX);
-}
-
 void lbs_host_to_card_done(struct lbs_private *priv)
 {
 	unsigned long flags;
@@ -336,12 +322,12 @@
 }
 
 /**
- *  @brief This function handles the major jobs in the LBS driver.
+ *  lbs_thread - handles the major jobs in the LBS driver.
  *  It handles all events generated by firmware, RX data received
  *  from firmware and TX data sent from kernel.
  *
- *  @param data    A pointer to lbs_thread structure
- *  @return 	   0
+ *  @data:	A pointer to &lbs_thread structure
+ *  returns:	0
  */
 static int lbs_thread(void *data)
 {
@@ -462,8 +448,8 @@
 		if (priv->cmd_timed_out && priv->cur_cmd) {
 			struct cmd_ctrl_node *cmdnode = priv->cur_cmd;
 
-			lbs_pr_info("Timeout submitting command 0x%04x\n",
-				le16_to_cpu(cmdnode->cmdbuf->command));
+			netdev_info(dev, "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);
@@ -490,8 +476,8 @@
 				 * after firmware fixes it
 				 */
 				priv->psstate = PS_STATE_AWAKE;
-				lbs_pr_alert("ignore PS_SleepConfirm in "
-					"non-connected state\n");
+				netdev_alert(dev,
+					     "ignore PS_SleepConfirm in non-connected state\n");
 			}
 		}
 
@@ -540,11 +526,11 @@
 }
 
 /**
- * @brief This function gets the HW spec from the firmware and sets
- *        some basic parameters.
+ * lbs_setup_firmware - gets the HW spec from the firmware and sets
+ *        some basic parameters
  *
- *  @param priv    A pointer to struct lbs_private structure
- *  @return        0 or -1
+ *  @priv:	A pointer to &struct lbs_private structure
+ *  returns:	0 or -1
  */
 static int lbs_setup_firmware(struct lbs_private *priv)
 {
@@ -585,7 +571,8 @@
 	if (priv->is_deep_sleep) {
 		ret = lbs_set_deep_sleep(priv, 0);
 		if (ret) {
-			lbs_pr_err("deep sleep cancellation failed: %d\n", ret);
+			netdev_err(priv->dev,
+				   "deep sleep cancellation failed: %d\n", ret);
 			return ret;
 		}
 		priv->deep_sleep_required = 1;
@@ -618,7 +605,8 @@
 		priv->deep_sleep_required = 0;
 		ret = lbs_set_deep_sleep(priv, 1);
 		if (ret)
-			lbs_pr_err("deep sleep activation failed: %d\n", ret);
+			netdev_err(priv->dev,
+				   "deep sleep activation failed: %d\n", ret);
 	}
 
 	if (priv->setup_fw_on_resume)
@@ -630,8 +618,10 @@
 EXPORT_SYMBOL_GPL(lbs_resume);
 
 /**
- *  This function handles the timeout of command sending.
- *  It will re-send the same command again.
+ * lbs_cmd_timeout_handler - handles the timeout of command sending.
+ * It will re-send the same command again.
+ *
+ * @data: &struct lbs_private pointer
  */
 static void lbs_cmd_timeout_handler(unsigned long data)
 {
@@ -644,8 +634,8 @@
 	if (!priv->cur_cmd)
 		goto out;
 
-	lbs_pr_info("command 0x%04x timed out\n",
-		le16_to_cpu(priv->cur_cmd->cmdbuf->command));
+	netdev_info(priv->dev, "command 0x%04x timed out\n",
+		    le16_to_cpu(priv->cur_cmd->cmdbuf->command));
 
 	priv->cmd_timed_out = 1;
 	wake_up_interruptible(&priv->waitq);
@@ -655,8 +645,10 @@
 }
 
 /**
- *  This function put the device back to deep sleep mode when timer expires
- *  and no activity (command, event, data etc.) is detected.
+ * auto_deepsleep_timer_fn - put the device back to deep sleep mode when
+ * timer expires and no activity (command, event, data etc.) is detected.
+ * @data:	&struct lbs_private pointer
+ * returns:	N/A
  */
 static void auto_deepsleep_timer_fn(unsigned long data)
 {
@@ -748,7 +740,7 @@
 
 	/* Allocate the command buffers */
 	if (lbs_allocate_cmd_buffer(priv)) {
-		lbs_pr_err("Out of memory allocating command buffers\n");
+		pr_err("Out of memory allocating command buffers\n");
 		ret = -ENOMEM;
 		goto out;
 	}
@@ -758,7 +750,7 @@
 	/* Create the event FIFO */
 	ret = kfifo_alloc(&priv->event_fifo, sizeof(u32) * 16, GFP_KERNEL);
 	if (ret) {
-		lbs_pr_err("Out of memory allocating event FIFO buffer\n");
+		pr_err("Out of memory allocating event FIFO buffer\n");
 		goto out;
 	}
 
@@ -785,18 +777,18 @@
 	.ndo_stop		= lbs_eth_stop,
 	.ndo_start_xmit		= lbs_hard_start_xmit,
 	.ndo_set_mac_address	= lbs_set_mac_address,
-	.ndo_tx_timeout 	= lbs_tx_timeout,
 	.ndo_set_multicast_list = lbs_set_multicast_list,
 	.ndo_change_mtu		= eth_change_mtu,
 	.ndo_validate_addr	= eth_validate_addr,
 };
 
 /**
- * @brief This function adds the card. it will probe the
+ * lbs_add_card - adds the card. It will probe the
  * card, allocate the lbs_priv and initialize the device.
  *
- *  @param card    A pointer to card
- *  @return 	   A pointer to struct lbs_private structure
+ * @card:	A pointer to card
+ * @dmdev:	A pointer to &struct device
+ * returns:	A pointer to &struct lbs_private structure
  */
 struct lbs_private *lbs_add_card(void *card, struct device *dmdev)
 {
@@ -809,7 +801,7 @@
 	/* Allocate an Ethernet device and register it */
 	wdev = lbs_cfg_alloc(dmdev);
 	if (IS_ERR(wdev)) {
-		lbs_pr_err("cfg80211 init failed\n");
+		pr_err("cfg80211 init failed\n");
 		goto done;
 	}
 
@@ -818,7 +810,7 @@
 	priv->wdev = wdev;
 
 	if (lbs_init_adapter(priv)) {
-		lbs_pr_err("failed to initialize adapter structure.\n");
+		pr_err("failed to initialize adapter structure\n");
 		goto err_wdev;
 	}
 
@@ -950,17 +942,20 @@
 		goto done;
 
 	if (lbs_cfg_register(priv)) {
-		lbs_pr_err("cannot register device\n");
+		pr_err("cannot register device\n");
 		goto done;
 	}
 
 	lbs_update_channel(priv);
 
-	lbs_init_mesh(priv);
+	if (!lbs_disablemesh)
+		lbs_init_mesh(priv);
+	else
+		pr_info("%s: mesh disabled\n", dev->name);
 
 	lbs_debugfs_init_one(priv, dev);
 
-	lbs_pr_info("%s: Marvell WLAN 802.11 adapter\n", dev->name);
+	netdev_info(dev, "Marvell WLAN 802.11 adapter\n");
 
 	ret = 0;
 
@@ -1057,19 +1052,19 @@
 EXPORT_SYMBOL_GPL(lbs_notify_command_response);
 
 /**
- *  @brief Retrieves two-stage firmware
+ *  lbs_get_firmware - Retrieves two-stage firmware
  *
- *  @param dev     	A pointer to device structure
- *  @param user_helper	User-defined helper firmware file
- *  @param user_mainfw	User-defined main firmware file
- *  @param card_model	Bus-specific card model ID used to filter firmware table
- *                         elements
- *  @param fw_table	Table of firmware file names and device model numbers
- *                         terminated by an entry with a NULL helper name
- *  @param helper	On success, the helper firmware; caller must free
- *  @param mainfw	On success, the main firmware; caller must free
+ *  @dev:     	A pointer to &device structure
+ *  @user_helper: User-defined helper firmware file
+ *  @user_mainfw: User-defined main firmware file
+ *  @card_model: Bus-specific card model ID used to filter firmware table
+ *		elements
+ *  @fw_table:	Table of firmware file names and device model numbers
+ *		terminated by an entry with a NULL helper name
+ *  @helper:	On success, the helper firmware; caller must free
+ *  @mainfw:	On success, the main firmware; caller must free
  *
- *  @return		0 on success, non-zero on failure
+ *  returns:		0 on success, non-zero on failure
  */
 int lbs_get_firmware(struct device *dev, const char *user_helper,
 			const char *user_mainfw, u32 card_model,
@@ -1087,16 +1082,16 @@
 	if (user_helper) {
 		ret = request_firmware(helper, user_helper, dev);
 		if (ret) {
-			lbs_pr_err("couldn't find helper firmware %s",
-					user_helper);
+			dev_err(dev, "couldn't find helper firmware %s\n",
+				user_helper);
 			goto fail;
 		}
 	}
 	if (user_mainfw) {
 		ret = request_firmware(mainfw, user_mainfw, dev);
 		if (ret) {
-			lbs_pr_err("couldn't find main firmware %s",
-					user_mainfw);
+			dev_err(dev, "couldn't find main firmware %s\n",
+				user_mainfw);
 			goto fail;
 		}
 	}
diff -druN linux-2.6.39-libre/drivers/net/wireless/libertas/mesh.c linux-3.0-rc7-libre/drivers/net/wireless/libertas/mesh.c
--- linux-2.6.39-libre/drivers/net/wireless/libertas/mesh.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/libertas/mesh.c	2011-07-11 19:51:52.000000000 -0400
@@ -1,3 +1,5 @@
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/delay.h>
 #include <linux/etherdevice.h>
 #include <linux/netdevice.h>
@@ -16,12 +18,15 @@
  * Mesh sysfs support
  */
 
-/**
+/*
  * Attributes exported through sysfs
  */
 
 /**
- * @brief Get function for sysfs attribute anycast_mask
+ * lbs_anycast_get - Get function for sysfs attribute anycast_mask
+ * @dev: the &struct device
+ * @attr: device attributes
+ * @buf: buffer where data will be returned
  */
 static ssize_t lbs_anycast_get(struct device *dev,
 		struct device_attribute *attr, char * buf)
@@ -40,7 +45,11 @@
 }
 
 /**
- * @brief Set function for sysfs attribute anycast_mask
+ * lbs_anycast_set - Set function for sysfs attribute anycast_mask
+ * @dev: the &struct device
+ * @attr: device attributes
+ * @buf: buffer that contains new attribute value
+ * @count: size of buffer
  */
 static ssize_t lbs_anycast_set(struct device *dev,
 		struct device_attribute *attr, const char * buf, size_t count)
@@ -62,7 +71,10 @@
 }
 
 /**
- * @brief Get function for sysfs attribute prb_rsp_limit
+ * lbs_prb_rsp_limit_get - Get function for sysfs attribute prb_rsp_limit
+ * @dev: the &struct device
+ * @attr: device attributes
+ * @buf: buffer where data will be returned
  */
 static ssize_t lbs_prb_rsp_limit_get(struct device *dev,
 		struct device_attribute *attr, char *buf)
@@ -85,7 +97,11 @@
 }
 
 /**
- * @brief Set function for sysfs attribute prb_rsp_limit
+ * lbs_prb_rsp_limit_set - Set function for sysfs attribute prb_rsp_limit
+ * @dev: the &struct device
+ * @attr: device attributes
+ * @buf: buffer that contains new attribute value
+ * @count: size of buffer
  */
 static ssize_t lbs_prb_rsp_limit_set(struct device *dev,
 		struct device_attribute *attr, const char *buf, size_t count)
@@ -114,7 +130,10 @@
 }
 
 /**
- * Get function for sysfs attribute mesh
+ * lbs_mesh_get - Get function for sysfs attribute mesh
+ * @dev: the &struct device
+ * @attr: device attributes
+ * @buf: buffer where data will be returned
  */
 static ssize_t lbs_mesh_get(struct device *dev,
 		struct device_attribute *attr, char * buf)
@@ -124,7 +143,11 @@
 }
 
 /**
- *  Set function for sysfs attribute mesh
+ * lbs_mesh_set - Set function for sysfs attribute mesh
+ * @dev: the &struct device
+ * @attr: device attributes
+ * @buf: buffer that contains new attribute value
+ * @count: size of buffer
  */
 static ssize_t lbs_mesh_set(struct device *dev,
 		struct device_attribute *attr, const char * buf, size_t count)
@@ -151,19 +174,19 @@
 	return count;
 }
 
-/**
+/*
  * lbs_mesh attribute to be exported per ethX interface
  * through sysfs (/sys/class/net/ethX/lbs_mesh)
  */
 static DEVICE_ATTR(lbs_mesh, 0644, lbs_mesh_get, lbs_mesh_set);
 
-/**
+/*
  * anycast_mask attribute to be exported per mshX interface
  * through sysfs (/sys/class/net/mshX/anycast_mask)
  */
 static DEVICE_ATTR(anycast_mask, 0644, lbs_anycast_get, lbs_anycast_set);
 
-/**
+/*
  * prb_rsp_limit attribute to be exported per mshX interface
  * through sysfs (/sys/class/net/mshX/prb_rsp_limit)
  */
@@ -246,7 +269,7 @@
 		lbs_add_mesh(priv);
 
 		if (device_create_file(&dev->dev, &dev_attr_lbs_mesh))
-			lbs_pr_err("cannot register lbs_mesh attribute\n");
+			netdev_err(dev, "cannot register lbs_mesh attribute\n");
 
 		ret = 1;
 	}
@@ -274,10 +297,10 @@
 
 
 /**
- *  @brief This function closes the mshX interface
+ * lbs_mesh_stop - close the mshX interface
  *
- *  @param dev     A pointer to net_device structure
- *  @return 	   0
+ * @dev:	A pointer to &net_device structure
+ * returns:	0
  */
 static int lbs_mesh_stop(struct net_device *dev)
 {
@@ -301,10 +324,10 @@
 }
 
 /**
- *  @brief This function opens the mshX interface
+ * lbs_mesh_dev_open - open the mshX interface
  *
- *  @param dev     A pointer to net_device structure
- *  @return 	   0 or -EBUSY if monitor mode active
+ * @dev:	A pointer to &net_device structure
+ * returns:	0 or -EBUSY if monitor mode active
  */
 static int lbs_mesh_dev_open(struct net_device *dev)
 {
@@ -342,10 +365,10 @@
 };
 
 /**
- * @brief This function adds mshX interface
+ * lbs_add_mesh - add mshX interface
  *
- *  @param priv    A pointer to the struct lbs_private structure
- *  @return 	   0 if successful, -X otherwise
+ * @priv:	A pointer to the &struct lbs_private structure
+ * returns:	0 if successful, -X otherwise
  */
 int lbs_add_mesh(struct lbs_private *priv)
 {
@@ -374,7 +397,7 @@
 	/* Register virtual mesh interface */
 	ret = register_netdev(mesh_dev);
 	if (ret) {
-		lbs_pr_err("cannot register mshX virtual interface\n");
+		pr_err("cannot register mshX virtual interface\n");
 		goto err_free;
 	}
 
@@ -456,13 +479,13 @@
  */
 
 /**
- *  @brief Add or delete Mesh Blinding Table entries
+ * lbs_mesh_bt_add_del - Add or delete Mesh Blinding Table entries
  *
- *  @param priv    	A pointer to struct lbs_private structure
- *  @param add  	TRUE to add the entry, FALSE to delete it
- *  @param addr1        Destination address to blind or unblind
+ * @priv:	A pointer to &struct lbs_private structure
+ * @add:	TRUE to add the entry, FALSE to delete it
+ * @addr1:	Destination address to blind or unblind
  *
- *  @return 	   	0 on success, error on failure
+ * returns:	0 on success, error on failure
  */
 int lbs_mesh_bt_add_del(struct lbs_private *priv, bool add, u8 *addr1)
 {
@@ -493,11 +516,11 @@
 }
 
 /**
- *  @brief Reset/clear the mesh blinding table
+ * lbs_mesh_bt_reset - Reset/clear the mesh blinding table
  *
- *  @param priv    	A pointer to struct lbs_private structure
+ * @priv:	A pointer to &struct lbs_private structure
  *
- *  @return 	   	0 on success, error on failure
+ * returns:	0 on success, error on failure
  */
 int lbs_mesh_bt_reset(struct lbs_private *priv)
 {
@@ -517,17 +540,18 @@
 }
 
 /**
- *  @brief Gets the inverted status of the mesh blinding table
+ * lbs_mesh_bt_get_inverted - Gets the inverted status of the mesh
+ * blinding table
  *
- *  Normally the firmware "blinds" or ignores traffic from mesh nodes in the
- *  table, but an inverted table allows *only* traffic from nodes listed in
- *  the table.
+ * Normally the firmware "blinds" or ignores traffic from mesh nodes in the
+ * table, but an inverted table allows *only* traffic from nodes listed in
+ * the table.
  *
- *  @param priv    	A pointer to struct lbs_private structure
- *  @param invert  	On success, TRUE if the blinding table is inverted,
- *                        FALSE if it is not inverted
+ * @priv:	A pointer to &struct lbs_private structure
+ * @inverted:  	On success, TRUE if the blinding table is inverted,
+ *		FALSE if it is not inverted
  *
- *  @return 	   	0 on success, error on failure
+ * returns:	0 on success, error on failure
  */
 int lbs_mesh_bt_get_inverted(struct lbs_private *priv, bool *inverted)
 {
@@ -551,18 +575,19 @@
 }
 
 /**
- *  @brief Sets the inverted status of the mesh blinding table
+ * lbs_mesh_bt_set_inverted - Sets the inverted status of the mesh
+ * blinding table
  *
- *  Normally the firmware "blinds" or ignores traffic from mesh nodes in the
- *  table, but an inverted table allows *only* traffic from nodes listed in
- *  the table.
+ * Normally the firmware "blinds" or ignores traffic from mesh nodes in the
+ * table, but an inverted table allows *only* traffic from nodes listed in
+ * the table.
  *
- *  @param priv    	A pointer to struct lbs_private structure
- *  @param invert  	TRUE to invert the blinding table (only traffic from
- *                         listed nodes allowed), FALSE to return it
- *                         to normal state (listed nodes ignored)
+ * @priv:	A pointer to &struct lbs_private structure
+ * @inverted:	TRUE to invert the blinding table (only traffic from
+ *		listed nodes allowed), FALSE to return it
+ *		to normal state (listed nodes ignored)
  *
- *  @return 	   	0 on success, error on failure
+ * returns:	0 on success, error on failure
  */
 int lbs_mesh_bt_set_inverted(struct lbs_private *priv, bool inverted)
 {
@@ -583,13 +608,13 @@
 }
 
 /**
- *  @brief List an entry in the mesh blinding table
+ * lbs_mesh_bt_get_entry - List an entry in the mesh blinding table
  *
- *  @param priv    	A pointer to struct lbs_private structure
- *  @param id		The ID of the entry to list
- *  @param addr1	MAC address associated with the table entry
+ * @priv:	A pointer to &struct lbs_private structure
+ * @id:		The ID of the entry to list
+ * @addr1:	MAC address associated with the table entry
  *
- *  @return 	   	0 on success, error on failure
+ * returns: 	   	0 on success, error on failure
  */
 int lbs_mesh_bt_get_entry(struct lbs_private *priv, u32 id, u8 *addr1)
 {
@@ -614,14 +639,14 @@
 }
 
 /**
- *  @brief Access the mesh forwarding table
+ * lbs_cmd_fwt_access - Access the mesh forwarding table
  *
- *  @param priv    	A pointer to struct lbs_private structure
- *  @param cmd_action	The forwarding table action to perform
- *  @param cmd		The pre-filled FWT_ACCESS command
+ * @priv:	A pointer to &struct lbs_private structure
+ * @cmd_action:	The forwarding table action to perform
+ * @cmd:	The pre-filled FWT_ACCESS command
  *
- *  @return 	   	0 on success and 'cmd' will be filled with the
- *                        firmware's response
+ * returns:	0 on success and 'cmd' will be filled with the
+ *		firmware's response
  */
 int lbs_cmd_fwt_access(struct lbs_private *priv, u16 cmd_action,
 			struct cmd_ds_fwt_access *cmd)
@@ -774,7 +799,10 @@
 }
 
 /**
- * @brief Get function for sysfs attribute bootflag
+ * bootflag_get - Get function for sysfs attribute bootflag
+ * @dev: the &struct device
+ * @attr: device attributes
+ * @buf: buffer where data will be returned
  */
 static ssize_t bootflag_get(struct device *dev,
 			    struct device_attribute *attr, char *buf)
@@ -791,7 +819,11 @@
 }
 
 /**
- * @brief Set function for sysfs attribute bootflag
+ * bootflag_set - Set function for sysfs attribute bootflag
+ * @dev: the &struct device
+ * @attr: device attributes
+ * @buf: buffer that contains new attribute value
+ * @count: size of buffer
  */
 static ssize_t bootflag_set(struct device *dev, struct device_attribute *attr,
 			    const char *buf, size_t count)
@@ -817,7 +849,10 @@
 }
 
 /**
- * @brief Get function for sysfs attribute boottime
+ * boottime_get - Get function for sysfs attribute boottime
+ * @dev: the &struct device
+ * @attr: device attributes
+ * @buf: buffer where data will be returned
  */
 static ssize_t boottime_get(struct device *dev,
 			    struct device_attribute *attr, char *buf)
@@ -834,7 +869,11 @@
 }
 
 /**
- * @brief Set function for sysfs attribute boottime
+ * boottime_set - Set function for sysfs attribute boottime
+ * @dev: the &struct device
+ * @attr: device attributes
+ * @buf: buffer that contains new attribute value
+ * @count: size of buffer
  */
 static ssize_t boottime_set(struct device *dev,
 		struct device_attribute *attr, const char *buf, size_t count)
@@ -869,7 +908,10 @@
 }
 
 /**
- * @brief Get function for sysfs attribute channel
+ * channel_get - Get function for sysfs attribute channel
+ * @dev: the &struct device
+ * @attr: device attributes
+ * @buf: buffer where data will be returned
  */
 static ssize_t channel_get(struct device *dev,
 			   struct device_attribute *attr, char *buf)
@@ -886,7 +928,11 @@
 }
 
 /**
- * @brief Set function for sysfs attribute channel
+ * channel_set - Set function for sysfs attribute channel
+ * @dev: the &struct device
+ * @attr: device attributes
+ * @buf: buffer that contains new attribute value
+ * @count: size of buffer
  */
 static ssize_t channel_set(struct device *dev, struct device_attribute *attr,
 			   const char *buf, size_t count)
@@ -912,7 +958,10 @@
 }
 
 /**
- * @brief Get function for sysfs attribute mesh_id
+ * mesh_id_get - Get function for sysfs attribute mesh_id
+ * @dev: the &struct device
+ * @attr: device attributes
+ * @buf: buffer where data will be returned
  */
 static ssize_t mesh_id_get(struct device *dev, struct device_attribute *attr,
 			   char *buf)
@@ -926,7 +975,7 @@
 		return ret;
 
 	if (defs.meshie.val.mesh_id_len > IEEE80211_MAX_SSID_LEN) {
-		lbs_pr_err("inconsistent mesh ID length");
+		dev_err(dev, "inconsistent mesh ID length\n");
 		defs.meshie.val.mesh_id_len = IEEE80211_MAX_SSID_LEN;
 	}
 
@@ -938,7 +987,11 @@
 }
 
 /**
- * @brief Set function for sysfs attribute mesh_id
+ * mesh_id_set - Set function for sysfs attribute mesh_id
+ * @dev: the &struct device
+ * @attr: device attributes
+ * @buf: buffer that contains new attribute value
+ * @count: size of buffer
  */
 static ssize_t mesh_id_set(struct device *dev, struct device_attribute *attr,
 			   const char *buf, size_t count)
@@ -980,7 +1033,10 @@
 }
 
 /**
- * @brief Get function for sysfs attribute protocol_id
+ * protocol_id_get - Get function for sysfs attribute protocol_id
+ * @dev: the &struct device
+ * @attr: device attributes
+ * @buf: buffer where data will be returned
  */
 static ssize_t protocol_id_get(struct device *dev,
 			       struct device_attribute *attr, char *buf)
@@ -997,7 +1053,11 @@
 }
 
 /**
- * @brief Set function for sysfs attribute protocol_id
+ * protocol_id_set - Set function for sysfs attribute protocol_id
+ * @dev: the &struct device
+ * @attr: device attributes
+ * @buf: buffer that contains new attribute value
+ * @count: size of buffer
  */
 static ssize_t protocol_id_set(struct device *dev,
 		struct device_attribute *attr, const char *buf, size_t count)
@@ -1034,7 +1094,10 @@
 }
 
 /**
- * @brief Get function for sysfs attribute metric_id
+ * metric_id_get - Get function for sysfs attribute metric_id
+ * @dev: the &struct device
+ * @attr: device attributes
+ * @buf: buffer where data will be returned
  */
 static ssize_t metric_id_get(struct device *dev,
 		struct device_attribute *attr, char *buf)
@@ -1051,7 +1114,11 @@
 }
 
 /**
- * @brief Set function for sysfs attribute metric_id
+ * metric_id_set - Set function for sysfs attribute metric_id
+ * @dev: the &struct device
+ * @attr: device attributes
+ * @buf: buffer that contains new attribute value
+ * @count: size of buffer
  */
 static ssize_t metric_id_set(struct device *dev, struct device_attribute *attr,
 			     const char *buf, size_t count)
@@ -1088,7 +1155,10 @@
 }
 
 /**
- * @brief Get function for sysfs attribute capability
+ * capability_get - Get function for sysfs attribute capability
+ * @dev: the &struct device
+ * @attr: device attributes
+ * @buf: buffer where data will be returned
  */
 static ssize_t capability_get(struct device *dev,
 		struct device_attribute *attr, char *buf)
@@ -1105,7 +1175,11 @@
 }
 
 /**
- * @brief Set function for sysfs attribute capability
+ * capability_set - Set function for sysfs attribute capability
+ * @dev: the &struct device
+ * @attr: device attributes
+ * @buf: buffer that contains new attribute value
+ * @count: size of buffer
  */
 static ssize_t capability_set(struct device *dev, struct device_attribute *attr,
 			      const char *buf, size_t count)
diff -druN linux-2.6.39-libre/drivers/net/wireless/libertas/mesh.h linux-3.0-rc7-libre/drivers/net/wireless/libertas/mesh.h
--- linux-2.6.39-libre/drivers/net/wireless/libertas/mesh.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/libertas/mesh.h	2011-07-11 19:51:52.000000000 -0400
@@ -1,6 +1,6 @@
-/**
-  * Contains all definitions needed for the Libertas' MESH implementation.
-  */
+/*
+ * Contains all definitions needed for the Libertas' MESH implementation.
+ */
 #ifndef _LBS_MESH_H_
 #define _LBS_MESH_H_
 
diff -druN linux-2.6.39-libre/drivers/net/wireless/libertas/rx.c linux-3.0-rc7-libre/drivers/net/wireless/libertas/rx.c
--- linux-2.6.39-libre/drivers/net/wireless/libertas/rx.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/libertas/rx.c	2011-07-11 19:51:52.000000000 -0400
@@ -1,6 +1,9 @@
-/**
-  * This file contains the handling of RX in wlan driver.
-  */
+/*
+ * This file contains the handling of RX in wlan driver.
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/etherdevice.h>
 #include <linux/slab.h>
 #include <linux/types.h>
@@ -40,12 +43,12 @@
 	struct sk_buff *skb);
 
 /**
- *  @brief This function processes received packet and forwards it
- *  to kernel/upper layer
+ * lbs_process_rxed_packet - processes received packet and forwards it
+ * to kernel/upper layer
  *
- *  @param	priv	A pointer to struct lbs_private
- *  @param	skb		A pointer to skb which includes the received packet
- *  @return	0 or -1
+ * @priv:	A pointer to &struct lbs_private
+ * @skb:	A pointer to skb which includes the received packet
+ * returns:	0 or -1
  */
 int lbs_process_rxed_packet(struct lbs_private *priv, struct sk_buff *skb)
 {
@@ -156,11 +159,11 @@
 EXPORT_SYMBOL_GPL(lbs_process_rxed_packet);
 
 /**
- *  @brief This function converts Tx/Rx rates from the Marvell WLAN format
- *  (see Table 2 in Section 3.1) to IEEE80211_RADIOTAP_RATE units (500 Kb/s)
+ * convert_mv_rate_to_radiotap - converts Tx/Rx rates from Marvell WLAN format
+ * (see Table 2 in Section 3.1) to IEEE80211_RADIOTAP_RATE units (500 Kb/s)
  *
- *  @param	rate	Input rate
- *  @return	Output Rate (0 if invalid)
+ * @rate:	Input rate
+ * returns:	Output Rate (0 if invalid)
  */
 static u8 convert_mv_rate_to_radiotap(u8 rate)
 {
@@ -191,17 +194,17 @@
 	case 12:		/*  54 Mbps */
 		return 108;
 	}
-	lbs_pr_alert("Invalid Marvell WLAN rate %i\n", rate);
+	pr_alert("Invalid Marvell WLAN rate %i\n", rate);
 	return 0;
 }
 
 /**
- *  @brief This function processes a received 802.11 packet and forwards it
- *  to kernel/upper layer
+ * process_rxed_802_11_packet - processes a received 802.11 packet and forwards
+ * it to kernel/upper layer
  *
- *  @param	priv	A pointer to struct lbs_private
- *  @param	skb		A pointer to skb which includes the received packet
- *  @return	0 or -1
+ * @priv:	A pointer to &struct lbs_private
+ * @skb:	A pointer to skb which includes the received packet
+ * returns:	0 or -1
  */
 static int process_rxed_802_11_packet(struct lbs_private *priv,
 	struct sk_buff *skb)
@@ -248,7 +251,7 @@
 	/* add space for the new radio header */
 	if ((skb_headroom(skb) < sizeof(struct rx_radiotap_hdr)) &&
 	    pskb_expand_head(skb, sizeof(struct rx_radiotap_hdr), 0, GFP_ATOMIC)) {
-		lbs_pr_alert("%s: couldn't pskb_expand_head\n", __func__);
+		netdev_alert(dev, "%s: couldn't pskb_expand_head\n", __func__);
 		ret = -ENOMEM;
 		kfree_skb(skb);
 		goto done;
diff -druN linux-2.6.39-libre/drivers/net/wireless/libertas/tx.c linux-3.0-rc7-libre/drivers/net/wireless/libertas/tx.c
--- linux-2.6.39-libre/drivers/net/wireless/libertas/tx.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/libertas/tx.c	2011-07-11 19:51:52.000000000 -0400
@@ -1,6 +1,6 @@
-/**
-  * This file contains the handling of TX in wlan driver.
-  */
+/*
+ * This file contains the handling of TX in wlan driver.
+ */
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
 #include <linux/sched.h>
@@ -13,11 +13,11 @@
 #include "dev.h"
 
 /**
- *  @brief This function converts Tx/Rx rates from IEEE80211_RADIOTAP_RATE
- *  units (500 Kb/s) into Marvell WLAN format (see Table 8 in Section 3.2.1)
+ * convert_radiotap_rate_to_mv - converts Tx/Rx rates from IEEE80211_RADIOTAP_RATE
+ * units (500 Kb/s) into Marvell WLAN format (see Table 8 in Section 3.2.1)
  *
- *  @param rate    Input rate
- *  @return      Output Rate (0 if invalid)
+ * @rate:	Input rate
+ * returns:	Output Rate (0 if invalid)
  */
 static u32 convert_radiotap_rate_to_mv(u8 rate)
 {
@@ -51,12 +51,12 @@
 }
 
 /**
- *  @brief This function checks the conditions and sends packet to IF
- *  layer if everything is ok.
+ * lbs_hard_start_xmit - checks the conditions and sends packet to IF
+ * layer if everything is ok
  *
- *  @param priv    A pointer to struct lbs_private structure
- *  @param skb     A pointer to skb which includes TX packet
- *  @return 	   0 or -1
+ * @skb:	A pointer to skb which includes TX packet
+ * @dev:	A pointer to the &struct net_device
+ * returns:	0 or -1
  */
 netdev_tx_t lbs_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
@@ -168,13 +168,13 @@
 }
 
 /**
- *  @brief This function sends to the host the last transmitted packet,
- *  filling the radiotap headers with transmission information.
+ * lbs_send_tx_feedback - sends to the host the last transmitted packet,
+ * filling the radiotap headers with transmission information.
  *
- *  @param priv     A pointer to struct lbs_private structure
- *  @param status   A 32 bit value containing transmission status.
+ * @priv:	A pointer to &struct lbs_private structure
+ * @try_count:	A 32-bit value containing transmission retry status.
  *
- *  @returns void
+ * returns:	void
  */
 void lbs_send_tx_feedback(struct lbs_private *priv, u32 try_count)
 {
diff -druN linux-2.6.39-libre/drivers/net/wireless/libertas/types.h linux-3.0-rc7-libre/drivers/net/wireless/libertas/types.h
--- linux-2.6.39-libre/drivers/net/wireless/libertas/types.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/libertas/types.h	2011-07-11 19:51:52.000000000 -0400
@@ -1,6 +1,6 @@
-/**
-  * This header file contains definition for global types
-  */
+/*
+ * This header file contains definition for global types
+ */
 #ifndef _LBS_TYPES_H_
 #define _LBS_TYPES_H_
 
@@ -54,7 +54,7 @@
 	struct ieee_ie_ds_param_set ds;
 } __packed;
 
-/** TLV  type ID definition */
+/* TLV  type ID definition */
 #define PROPRIETARY_TLV_BASE_ID		0x0100
 
 /* Terminating TLV type */
@@ -96,7 +96,7 @@
 #define TLV_TYPE_MESH_ID            (PROPRIETARY_TLV_BASE_ID + 37)
 #define TLV_TYPE_OLD_MESH_ID        (PROPRIETARY_TLV_BASE_ID + 291)
 
-/** TLV related data structures*/
+/* TLV related data structures */
 struct mrvl_ie_header {
 	__le16 type;
 	__le16 len;
@@ -177,7 +177,7 @@
 	__le16 auth;
 } __packed;
 
-/**  Local Power capability */
+/*  Local Power capability */
 struct mrvl_ie_power_capability {
 	struct mrvl_ie_header header;
 	s8 minpower;
@@ -235,9 +235,11 @@
 	struct led_bhv ledbhv[1];
 } __packed;
 
-/* Meant to be packed as the value member of a struct ieee80211_info_element.
+/*
+ * Meant to be packed as the value member of a struct ieee80211_info_element.
  * Note that the len member of the ieee80211_info_element varies depending on
- * the mesh_id_len */
+ * the mesh_id_len
+ */
 struct mrvl_meshie_val {
 	uint8_t oui[3];
 	uint8_t type;
diff -druN linux-2.6.39-libre/drivers/net/wireless/mac80211_hwsim.c linux-3.0-rc7-libre/drivers/net/wireless/mac80211_hwsim.c
--- linux-2.6.39-libre/drivers/net/wireless/mac80211_hwsim.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/mac80211_hwsim.c	2011-07-11 19:51:52.000000000 -0400
@@ -1515,19 +1515,10 @@
 	if (hwsim_mon == NULL)
 		goto failed;
 
-	rtnl_lock();
-
-	err = dev_alloc_name(hwsim_mon, hwsim_mon->name);
-	if (err < 0)
-		goto failed_mon;
-
-
-	err = register_netdevice(hwsim_mon);
+	err = register_netdev(hwsim_mon);
 	if (err < 0)
 		goto failed_mon;
 
-	rtnl_unlock();
-
 	return 0;
 
 failed_mon:
diff -druN linux-2.6.39-libre/drivers/net/wireless/Makefile linux-3.0-rc7-libre/drivers/net/wireless/Makefile
--- linux-2.6.39-libre/drivers/net/wireless/Makefile	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/Makefile	2011-07-11 19:51:52.000000000 -0400
@@ -56,3 +56,5 @@
 obj-$(CONFIG_WL12XX_PLATFORM_DATA)	+= wl12xx/
 
 obj-$(CONFIG_IWM)	+= iwmc3200wifi/
+
+obj-$(CONFIG_MWIFIEX)	+= mwifiex/
diff -druN linux-2.6.39-libre/drivers/net/wireless/mwifiex/11n_aggr.c linux-3.0-rc7-libre/drivers/net/wireless/mwifiex/11n_aggr.c
--- linux-2.6.39-libre/drivers/net/wireless/mwifiex/11n_aggr.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/net/wireless/mwifiex/11n_aggr.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,302 @@
+/*
+ * Marvell Wireless LAN device driver: 802.11n Aggregation
+ *
+ * Copyright (C) 2011, Marvell International Ltd.
+ *
+ * This software file (the "File") is distributed by Marvell International
+ * Ltd. under the terms of the GNU General Public License Version 2, June 1991
+ * (the "License").  You may use, redistribute and/or modify this File in
+ * accordance with the terms and conditions of the License, a copy of which
+ * is available by writing to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
+ * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
+ *
+ * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
+ * ARE EXPRESSLY DISCLAIMED.  The License provides additional details about
+ * this warranty disclaimer.
+ */
+
+#include "decl.h"
+#include "ioctl.h"
+#include "util.h"
+#include "fw.h"
+#include "main.h"
+#include "wmm.h"
+#include "11n.h"
+#include "11n_aggr.h"
+
+/*
+ * Creates an AMSDU subframe for aggregation into one AMSDU packet.
+ *
+ * The resultant AMSDU subframe format is -
+ *
+ * +---- ~ -----+---- ~ ------+---- ~ -----+----- ~ -----+---- ~ -----+
+ * |     DA     |     SA      |   Length   | SNAP header |   MSDU     |
+ * | data[0..5] | data[6..11] |            |             | data[14..] |
+ * +---- ~ -----+---- ~ ------+---- ~ -----+----- ~ -----+---- ~ -----+
+ * <--6-bytes--> <--6-bytes--> <--2-bytes--><--8-bytes--> <--n-bytes-->
+ *
+ * This function also computes the amount of padding required to make the
+ * buffer length multiple of 4 bytes.
+ *
+ * Data => |DA|SA|SNAP-TYPE|........    .|
+ * MSDU => |DA|SA|Length|SNAP|......   ..|
+ */
+static int
+mwifiex_11n_form_amsdu_pkt(struct sk_buff *skb_aggr,
+			   struct sk_buff *skb_src, int *pad)
+
+{
+	int dt_offset;
+	struct rfc_1042_hdr snap = {
+		0xaa,		/* LLC DSAP */
+		0xaa,		/* LLC SSAP */
+		0x03,		/* LLC CTRL */
+		{0x00, 0x00, 0x00},	/* SNAP OUI */
+		0x0000		/* SNAP type */
+			/*
+			 * This field will be overwritten
+			 * later with ethertype
+			 */
+	};
+	struct tx_packet_hdr *tx_header;
+
+	skb_put(skb_aggr, sizeof(*tx_header));
+
+	tx_header = (struct tx_packet_hdr *) skb_aggr->data;
+
+	/* Copy DA and SA */
+	dt_offset = 2 * ETH_ALEN;
+	memcpy(&tx_header->eth803_hdr, skb_src->data, dt_offset);
+
+	/* Copy SNAP header */
+	snap.snap_type = *(u16 *) ((u8 *)skb_src->data + dt_offset);
+	dt_offset += sizeof(u16);
+
+	memcpy(&tx_header->rfc1042_hdr, &snap, sizeof(struct rfc_1042_hdr));
+
+	skb_pull(skb_src, dt_offset);
+
+	/* Update Length field */
+	tx_header->eth803_hdr.h_proto = htons(skb_src->len + LLC_SNAP_LEN);
+
+	/* Add payload */
+	skb_put(skb_aggr, skb_src->len);
+	memcpy(skb_aggr->data + sizeof(*tx_header), skb_src->data,
+							skb_src->len);
+	*pad = (((skb_src->len + LLC_SNAP_LEN) & 3)) ? (4 - (((skb_src->len +
+						      LLC_SNAP_LEN)) & 3)) : 0;
+	skb_put(skb_aggr, *pad);
+
+	return skb_aggr->len + *pad;
+}
+
+/*
+ * Adds TxPD to AMSDU header.
+ *
+ * Each AMSDU packet will contain one TxPD at the beginning,
+ * followed by multiple AMSDU subframes.
+ */
+static void
+mwifiex_11n_form_amsdu_txpd(struct mwifiex_private *priv,
+			    struct sk_buff *skb)
+{
+	struct txpd *local_tx_pd;
+
+	skb_push(skb, sizeof(*local_tx_pd));
+
+	local_tx_pd = (struct txpd *) skb->data;
+	memset(local_tx_pd, 0, sizeof(struct txpd));
+
+	/* Original priority has been overwritten */
+	local_tx_pd->priority = (u8) skb->priority;
+	local_tx_pd->pkt_delay_2ms =
+		mwifiex_wmm_compute_drv_pkt_delay(priv, skb);
+	local_tx_pd->bss_num = priv->bss_num;
+	local_tx_pd->bss_type = priv->bss_type;
+	/* Always zero as the data is followed by struct txpd */
+	local_tx_pd->tx_pkt_offset = cpu_to_le16(sizeof(struct txpd));
+	local_tx_pd->tx_pkt_type = cpu_to_le16(PKT_TYPE_AMSDU);
+	local_tx_pd->tx_pkt_length = cpu_to_le16(skb->len -
+			sizeof(*local_tx_pd));
+
+	if (local_tx_pd->tx_control == 0)
+		/* TxCtrl set by user or default */
+		local_tx_pd->tx_control = cpu_to_le32(priv->pkt_tx_ctrl);
+
+	if ((GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_STA) &&
+		(priv->adapter->pps_uapsd_mode)) {
+		if (true == mwifiex_check_last_packet_indication(priv)) {
+			priv->adapter->tx_lock_flag = true;
+			local_tx_pd->flags =
+				MWIFIEX_TxPD_POWER_MGMT_LAST_PACKET;
+		}
+	}
+}
+
+/*
+ * Create aggregated packet.
+ *
+ * This function creates an aggregated MSDU packet, by combining buffers
+ * from the RA list. Each individual buffer is encapsulated as an AMSDU
+ * subframe and all such subframes are concatenated together to form the
+ * AMSDU packet.
+ *
+ * A TxPD is also added to the front of the resultant AMSDU packets for
+ * transmission. The resultant packets format is -
+ *
+ * +---- ~ ----+------ ~ ------+------ ~ ------+-..-+------ ~ ------+
+ * |    TxPD   |AMSDU sub-frame|AMSDU sub-frame| .. |AMSDU sub-frame|
+ * |           |       1       |       2       | .. |       n       |
+ * +---- ~ ----+------ ~ ------+------ ~ ------+ .. +------ ~ ------+
+ */
+int
+mwifiex_11n_aggregate_pkt(struct mwifiex_private *priv,
+			  struct mwifiex_ra_list_tbl *pra_list, int headroom,
+			  int ptrindex, unsigned long ra_list_flags)
+			  __releases(&priv->wmm.ra_list_spinlock)
+{
+	struct mwifiex_adapter *adapter = priv->adapter;
+	struct sk_buff *skb_aggr, *skb_src;
+	struct mwifiex_txinfo *tx_info_aggr, *tx_info_src;
+	int pad = 0, ret;
+	struct mwifiex_tx_param tx_param;
+	struct txpd *ptx_pd = NULL;
+
+	if (skb_queue_empty(&pra_list->skb_head)) {
+		spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock,
+				       ra_list_flags);
+		return 0;
+	}
+	skb_src = skb_peek(&pra_list->skb_head);
+	tx_info_src = MWIFIEX_SKB_TXCB(skb_src);
+	skb_aggr = dev_alloc_skb(adapter->tx_buf_size);
+	if (!skb_aggr) {
+		dev_err(adapter->dev, "%s: alloc skb_aggr\n", __func__);
+		spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock,
+				       ra_list_flags);
+		return -1;
+	}
+	skb_reserve(skb_aggr, headroom + sizeof(struct txpd));
+	tx_info_aggr =  MWIFIEX_SKB_TXCB(skb_aggr);
+
+	tx_info_aggr->bss_index = tx_info_src->bss_index;
+	skb_aggr->priority = skb_src->priority;
+
+	while (skb_src && ((skb_headroom(skb_aggr) + skb_src->len
+					+ LLC_SNAP_LEN)
+				<= adapter->tx_buf_size)) {
+
+		if (!skb_queue_empty(&pra_list->skb_head))
+			skb_src = skb_dequeue(&pra_list->skb_head);
+		else
+			skb_src = NULL;
+
+		if (skb_src)
+			pra_list->total_pkts_size -= skb_src->len;
+
+		atomic_dec(&priv->wmm.tx_pkts_queued);
+
+		spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock,
+				       ra_list_flags);
+		mwifiex_11n_form_amsdu_pkt(skb_aggr, skb_src, &pad);
+
+		mwifiex_write_data_complete(adapter, skb_src, 0);
+
+		spin_lock_irqsave(&priv->wmm.ra_list_spinlock, ra_list_flags);
+
+		if (!mwifiex_is_ralist_valid(priv, pra_list, ptrindex)) {
+			spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock,
+					       ra_list_flags);
+			return -1;
+		}
+
+		if (!skb_queue_empty(&pra_list->skb_head))
+			skb_src = skb_peek(&pra_list->skb_head);
+		else
+			skb_src = NULL;
+	}
+
+	spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, ra_list_flags);
+
+	/* Last AMSDU packet does not need padding */
+	skb_trim(skb_aggr, skb_aggr->len - pad);
+
+	/* Form AMSDU */
+	mwifiex_11n_form_amsdu_txpd(priv, skb_aggr);
+	if (GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_STA)
+		ptx_pd = (struct txpd *)skb_aggr->data;
+
+	skb_push(skb_aggr, headroom);
+
+	tx_param.next_pkt_len = ((pra_list->total_pkts_size) ?
+				 (((pra_list->total_pkts_size) >
+				   adapter->tx_buf_size) ? adapter->
+				  tx_buf_size : pra_list->total_pkts_size +
+				  LLC_SNAP_LEN + sizeof(struct txpd)) : 0);
+	ret = adapter->if_ops.host_to_card(adapter, MWIFIEX_TYPE_DATA,
+					     skb_aggr->data,
+					     skb_aggr->len, &tx_param);
+	switch (ret) {
+	case -EBUSY:
+		spin_lock_irqsave(&priv->wmm.ra_list_spinlock, ra_list_flags);
+		if (!mwifiex_is_ralist_valid(priv, pra_list, ptrindex)) {
+			spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock,
+					       ra_list_flags);
+			mwifiex_write_data_complete(adapter, skb_aggr, -1);
+			return -1;
+		}
+		if ((GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_STA) &&
+			(adapter->pps_uapsd_mode) &&
+			(adapter->tx_lock_flag)) {
+				priv->adapter->tx_lock_flag = false;
+				if (ptx_pd)
+					ptx_pd->flags = 0;
+		}
+
+		skb_queue_tail(&pra_list->skb_head, skb_aggr);
+
+		pra_list->total_pkts_size += skb_aggr->len;
+
+		atomic_inc(&priv->wmm.tx_pkts_queued);
+
+		tx_info_aggr->flags |= MWIFIEX_BUF_FLAG_REQUEUED_PKT;
+		spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock,
+				       ra_list_flags);
+		dev_dbg(adapter->dev, "data: -EBUSY is returned\n");
+		break;
+	case -1:
+		adapter->data_sent = false;
+		dev_err(adapter->dev, "%s: host_to_card failed: %#x\n",
+						__func__, ret);
+		adapter->dbg.num_tx_host_to_card_failure++;
+		mwifiex_write_data_complete(adapter, skb_aggr, ret);
+		return 0;
+	case -EINPROGRESS:
+		adapter->data_sent = false;
+		break;
+	case 0:
+		mwifiex_write_data_complete(adapter, skb_aggr, ret);
+		break;
+	default:
+		break;
+	}
+	if (ret != -EBUSY) {
+		spin_lock_irqsave(&priv->wmm.ra_list_spinlock, ra_list_flags);
+		if (mwifiex_is_ralist_valid(priv, pra_list, ptrindex)) {
+			priv->wmm.packets_out[ptrindex]++;
+			priv->wmm.tid_tbl_ptr[ptrindex].ra_list_curr = pra_list;
+		}
+		/* Now bss_prio_cur pointer points to next node */
+		adapter->bss_prio_tbl[priv->bss_priority].bss_prio_cur =
+			list_first_entry(
+				&adapter->bss_prio_tbl[priv->bss_priority]
+				.bss_prio_cur->list,
+				struct mwifiex_bss_prio_node, list);
+		spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock,
+				       ra_list_flags);
+	}
+
+	return 0;
+}
diff -druN linux-2.6.39-libre/drivers/net/wireless/mwifiex/11n_aggr.h linux-3.0-rc7-libre/drivers/net/wireless/mwifiex/11n_aggr.h
--- linux-2.6.39-libre/drivers/net/wireless/mwifiex/11n_aggr.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/net/wireless/mwifiex/11n_aggr.h	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,32 @@
+/*
+ * Marvell Wireless LAN device driver: 802.11n Aggregation
+ *
+ * Copyright (C) 2011, Marvell International Ltd.
+ *
+ * This software file (the "File") is distributed by Marvell International
+ * Ltd. under the terms of the GNU General Public License Version 2, June 1991
+ * (the "License").  You may use, redistribute and/or modify this File in
+ * accordance with the terms and conditions of the License, a copy of which
+ * is available by writing to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
+ * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
+ *
+ * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
+ * ARE EXPRESSLY DISCLAIMED.  The License provides additional details about
+ * this warranty disclaimer.
+ */
+
+#ifndef _MWIFIEX_11N_AGGR_H_
+#define _MWIFIEX_11N_AGGR_H_
+
+#define PKT_TYPE_AMSDU	0xE6
+
+int mwifiex_11n_deaggregate_pkt(struct mwifiex_private *priv,
+				struct sk_buff *skb);
+int mwifiex_11n_aggregate_pkt(struct mwifiex_private *priv,
+			      struct mwifiex_ra_list_tbl *ptr, int headroom,
+			      int ptr_index, unsigned long flags)
+			      __releases(&priv->wmm.ra_list_spinlock);
+
+#endif /* !_MWIFIEX_11N_AGGR_H_ */
diff -druN linux-2.6.39-libre/drivers/net/wireless/mwifiex/11n.c linux-3.0-rc7-libre/drivers/net/wireless/mwifiex/11n.c
--- linux-2.6.39-libre/drivers/net/wireless/mwifiex/11n.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/net/wireless/mwifiex/11n.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,744 @@
+/*
+ * Marvell Wireless LAN device driver: 802.11n
+ *
+ * Copyright (C) 2011, Marvell International Ltd.
+ *
+ * This software file (the "File") is distributed by Marvell International
+ * Ltd. under the terms of the GNU General Public License Version 2, June 1991
+ * (the "License").  You may use, redistribute and/or modify this File in
+ * accordance with the terms and conditions of the License, a copy of which
+ * is available by writing to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
+ * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
+ *
+ * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
+ * ARE EXPRESSLY DISCLAIMED.  The License provides additional details about
+ * this warranty disclaimer.
+ */
+
+#include "decl.h"
+#include "ioctl.h"
+#include "util.h"
+#include "fw.h"
+#include "main.h"
+#include "wmm.h"
+#include "11n.h"
+
+/*
+ * Fills HT capability information field, AMPDU Parameters field, HT extended
+ * capability field, and supported MCS set fields.
+ *
+ * HT capability information field, AMPDU Parameters field, supported MCS set
+ * fields are retrieved from cfg80211 stack
+ *
+ * RD responder bit to set to clear in the extended capability header.
+ */
+void
+mwifiex_fill_cap_info(struct mwifiex_private *priv, u8 radio_type,
+		      struct mwifiex_ie_types_htcap *ht_cap)
+{
+	uint16_t ht_ext_cap = le16_to_cpu(ht_cap->ht_cap.extended_ht_cap_info);
+	struct ieee80211_supported_band *sband =
+					priv->wdev->wiphy->bands[radio_type];
+
+	ht_cap->ht_cap.ampdu_params_info =
+		(sband->ht_cap.ampdu_factor &
+		 IEEE80211_HT_AMPDU_PARM_FACTOR)|
+		((sband->ht_cap.ampdu_density <<
+		 IEEE80211_HT_AMPDU_PARM_DENSITY_SHIFT) &
+		 IEEE80211_HT_AMPDU_PARM_DENSITY);
+
+	memcpy((u8 *) &ht_cap->ht_cap.mcs, &sband->ht_cap.mcs,
+						sizeof(sband->ht_cap.mcs));
+
+	if (priv->bss_mode == NL80211_IFTYPE_STATION ||
+			(sband->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40))
+		/* Set MCS32 for infra mode or ad-hoc mode with 40MHz support */
+		SETHT_MCS32(ht_cap->ht_cap.mcs.rx_mask);
+
+	/* Clear RD responder bit */
+	ht_ext_cap &= ~IEEE80211_HT_EXT_CAP_RD_RESPONDER;
+
+	ht_cap->ht_cap.cap_info = cpu_to_le16(sband->ht_cap.cap);
+	ht_cap->ht_cap.extended_ht_cap_info = cpu_to_le16(ht_ext_cap);
+}
+
+/*
+ * This function returns the pointer to an entry in BA Stream
+ * table which matches the requested BA status.
+ */
+static struct mwifiex_tx_ba_stream_tbl *
+mwifiex_11n_get_tx_ba_stream_status(struct mwifiex_private *priv,
+				  enum mwifiex_ba_status ba_status)
+{
+	struct mwifiex_tx_ba_stream_tbl *tx_ba_tsr_tbl;
+	unsigned long flags;
+
+	spin_lock_irqsave(&priv->tx_ba_stream_tbl_lock, flags);
+	list_for_each_entry(tx_ba_tsr_tbl, &priv->tx_ba_stream_tbl_ptr, list) {
+		if (tx_ba_tsr_tbl->ba_status == ba_status) {
+			spin_unlock_irqrestore(&priv->tx_ba_stream_tbl_lock,
+					       flags);
+			return tx_ba_tsr_tbl;
+		}
+	}
+	spin_unlock_irqrestore(&priv->tx_ba_stream_tbl_lock, flags);
+	return NULL;
+}
+
+/*
+ * This function handles the command response of delete a block
+ * ack request.
+ *
+ * The function checks the response success status and takes action
+ * accordingly (send an add BA request in case of success, or recreate
+ * the deleted stream in case of failure, if the add BA was also
+ * initiated by us).
+ */
+int mwifiex_ret_11n_delba(struct mwifiex_private *priv,
+			  struct host_cmd_ds_command *resp)
+{
+	int tid;
+	struct mwifiex_tx_ba_stream_tbl *tx_ba_tbl;
+	struct host_cmd_ds_11n_delba *del_ba =
+		(struct host_cmd_ds_11n_delba *) &resp->params.del_ba;
+	uint16_t del_ba_param_set = le16_to_cpu(del_ba->del_ba_param_set);
+
+	tid = del_ba_param_set >> DELBA_TID_POS;
+	if (del_ba->del_result == BA_RESULT_SUCCESS) {
+		mwifiex_11n_delete_ba_stream_tbl(priv, tid,
+				del_ba->peer_mac_addr, TYPE_DELBA_SENT,
+				INITIATOR_BIT(del_ba_param_set));
+
+		tx_ba_tbl = mwifiex_11n_get_tx_ba_stream_status(priv,
+						BA_STREAM_SETUP_INPROGRESS);
+		if (tx_ba_tbl)
+			mwifiex_send_addba(priv, tx_ba_tbl->tid,
+					   tx_ba_tbl->ra);
+	} else { /*
+		  * In case of failure, recreate the deleted stream in case
+		  * we initiated the ADDBA
+		  */
+		if (INITIATOR_BIT(del_ba_param_set)) {
+			mwifiex_11n_create_tx_ba_stream_tbl(priv,
+					del_ba->peer_mac_addr, tid,
+					BA_STREAM_SETUP_INPROGRESS);
+
+			tx_ba_tbl = mwifiex_11n_get_tx_ba_stream_status(priv,
+					BA_STREAM_SETUP_INPROGRESS);
+			if (tx_ba_tbl)
+				mwifiex_11n_delete_ba_stream_tbl(priv,
+						tx_ba_tbl->tid, tx_ba_tbl->ra,
+						TYPE_DELBA_SENT, true);
+		}
+	}
+
+	return 0;
+}
+
+/*
+ * This function handles the command response of add a block
+ * ack request.
+ *
+ * Handling includes changing the header fields to CPU formats, checking
+ * the response success status and taking actions accordingly (delete the
+ * BA stream table in case of failure).
+ */
+int mwifiex_ret_11n_addba_req(struct mwifiex_private *priv,
+			      struct host_cmd_ds_command *resp)
+{
+	int tid;
+	struct host_cmd_ds_11n_addba_rsp *add_ba_rsp =
+		(struct host_cmd_ds_11n_addba_rsp *) &resp->params.add_ba_rsp;
+	struct mwifiex_tx_ba_stream_tbl *tx_ba_tbl;
+
+	add_ba_rsp->ssn = cpu_to_le16((le16_to_cpu(add_ba_rsp->ssn))
+			& SSN_MASK);
+
+	tid = (le16_to_cpu(add_ba_rsp->block_ack_param_set)
+		& IEEE80211_ADDBA_PARAM_TID_MASK)
+		>> BLOCKACKPARAM_TID_POS;
+	if (le16_to_cpu(add_ba_rsp->status_code) == BA_RESULT_SUCCESS) {
+		tx_ba_tbl = mwifiex_11n_get_tx_ba_stream_tbl(priv, tid,
+						add_ba_rsp->peer_mac_addr);
+		if (tx_ba_tbl) {
+			dev_dbg(priv->adapter->dev, "info: BA stream complete\n");
+			tx_ba_tbl->ba_status = BA_STREAM_SETUP_COMPLETE;
+		} else {
+			dev_err(priv->adapter->dev, "BA stream not created\n");
+		}
+	} else {
+		mwifiex_11n_delete_ba_stream_tbl(priv, tid,
+						add_ba_rsp->peer_mac_addr,
+						TYPE_DELBA_SENT, true);
+		if (add_ba_rsp->add_rsp_result != BA_RESULT_TIMEOUT)
+			priv->aggr_prio_tbl[tid].ampdu_ap =
+				BA_STREAM_NOT_ALLOWED;
+	}
+
+	return 0;
+}
+
+/*
+ * This function handles the command response of 11n configuration request.
+ *
+ * Handling includes changing the header fields into CPU format.
+ */
+int mwifiex_ret_11n_cfg(struct host_cmd_ds_command *resp, void *data_buf)
+{
+	struct mwifiex_ds_11n_tx_cfg *tx_cfg;
+	struct host_cmd_ds_11n_cfg *htcfg = &resp->params.htcfg;
+
+	if (data_buf) {
+		tx_cfg = (struct mwifiex_ds_11n_tx_cfg *) data_buf;
+		tx_cfg->tx_htcap = le16_to_cpu(htcfg->ht_tx_cap);
+		tx_cfg->tx_htinfo = le16_to_cpu(htcfg->ht_tx_info);
+	}
+	return 0;
+}
+
+/*
+ * This function prepares command of reconfigure Tx buffer.
+ *
+ * Preparation includes -
+ *      - Setting command ID, action and proper size
+ *      - Setting Tx buffer size (for SET only)
+ *      - Ensuring correct endian-ness
+ */
+int mwifiex_cmd_recfg_tx_buf(struct mwifiex_private *priv,
+			     struct host_cmd_ds_command *cmd, int cmd_action,
+			     void *data_buf)
+{
+	struct host_cmd_ds_txbuf_cfg *tx_buf = &cmd->params.tx_buf;
+	u16 action = (u16) cmd_action;
+	u16 buf_size = *((u16 *) data_buf);
+
+	cmd->command = cpu_to_le16(HostCmd_CMD_RECONFIGURE_TX_BUFF);
+	cmd->size =
+		cpu_to_le16(sizeof(struct host_cmd_ds_txbuf_cfg) + S_DS_GEN);
+	tx_buf->action = cpu_to_le16(action);
+	switch (action) {
+	case HostCmd_ACT_GEN_SET:
+		dev_dbg(priv->adapter->dev, "cmd: set tx_buf=%d\n", buf_size);
+		tx_buf->buff_size = cpu_to_le16(buf_size);
+		break;
+	case HostCmd_ACT_GEN_GET:
+	default:
+		tx_buf->buff_size = 0;
+		break;
+	}
+	return 0;
+}
+
+/*
+ * This function prepares command of AMSDU aggregation control.
+ *
+ * Preparation includes -
+ *      - Setting command ID, action and proper size
+ *      - Setting AMSDU control parameters (for SET only)
+ *      - Ensuring correct endian-ness
+ */
+int mwifiex_cmd_amsdu_aggr_ctrl(struct host_cmd_ds_command *cmd,
+				int cmd_action, void *data_buf)
+{
+	struct host_cmd_ds_amsdu_aggr_ctrl *amsdu_ctrl =
+		&cmd->params.amsdu_aggr_ctrl;
+	u16 action = (u16) cmd_action;
+	struct mwifiex_ds_11n_amsdu_aggr_ctrl *aa_ctrl =
+		(struct mwifiex_ds_11n_amsdu_aggr_ctrl *) data_buf;
+
+	cmd->command = cpu_to_le16(HostCmd_CMD_AMSDU_AGGR_CTRL);
+	cmd->size = cpu_to_le16(sizeof(struct host_cmd_ds_amsdu_aggr_ctrl)
+				+ S_DS_GEN);
+	amsdu_ctrl->action = cpu_to_le16(action);
+	switch (action) {
+	case HostCmd_ACT_GEN_SET:
+		amsdu_ctrl->enable = cpu_to_le16(aa_ctrl->enable);
+		amsdu_ctrl->curr_buf_size = 0;
+		break;
+	case HostCmd_ACT_GEN_GET:
+	default:
+		amsdu_ctrl->curr_buf_size = 0;
+		break;
+	}
+	return 0;
+}
+
+/*
+ * This function handles the command response of AMSDU aggregation
+ * control request.
+ *
+ * Handling includes changing the header fields into CPU format.
+ */
+int mwifiex_ret_amsdu_aggr_ctrl(struct host_cmd_ds_command *resp,
+				void *data_buf)
+{
+	struct mwifiex_ds_11n_amsdu_aggr_ctrl *amsdu_aggr_ctrl;
+	struct host_cmd_ds_amsdu_aggr_ctrl *amsdu_ctrl =
+		&resp->params.amsdu_aggr_ctrl;
+
+	if (data_buf) {
+		amsdu_aggr_ctrl =
+			(struct mwifiex_ds_11n_amsdu_aggr_ctrl *) data_buf;
+		amsdu_aggr_ctrl->enable = le16_to_cpu(amsdu_ctrl->enable);
+		amsdu_aggr_ctrl->curr_buf_size =
+			le16_to_cpu(amsdu_ctrl->curr_buf_size);
+	}
+	return 0;
+}
+
+/*
+ * This function prepares 11n configuration command.
+ *
+ * Preparation includes -
+ *      - Setting command ID, action and proper size
+ *      - Setting HT Tx capability and HT Tx information fields
+ *      - Ensuring correct endian-ness
+ */
+int mwifiex_cmd_11n_cfg(struct host_cmd_ds_command *cmd,
+			u16 cmd_action, void *data_buf)
+{
+	struct host_cmd_ds_11n_cfg *htcfg = &cmd->params.htcfg;
+	struct mwifiex_ds_11n_tx_cfg *txcfg =
+		(struct mwifiex_ds_11n_tx_cfg *) data_buf;
+
+	cmd->command = cpu_to_le16(HostCmd_CMD_11N_CFG);
+	cmd->size = cpu_to_le16(sizeof(struct host_cmd_ds_11n_cfg) + S_DS_GEN);
+	htcfg->action = cpu_to_le16(cmd_action);
+	htcfg->ht_tx_cap = cpu_to_le16(txcfg->tx_htcap);
+	htcfg->ht_tx_info = cpu_to_le16(txcfg->tx_htinfo);
+	return 0;
+}
+
+/*
+ * This function appends an 11n TLV to a buffer.
+ *
+ * Buffer allocation is responsibility of the calling
+ * function. No size validation is made here.
+ *
+ * The function fills up the following sections, if applicable -
+ *      - HT capability IE
+ *      - HT information IE (with channel list)
+ *      - 20/40 BSS Coexistence IE
+ *      - HT Extended Capabilities IE
+ */
+int
+mwifiex_cmd_append_11n_tlv(struct mwifiex_private *priv,
+			   struct mwifiex_bssdescriptor *bss_desc,
+			   u8 **buffer)
+{
+	struct mwifiex_ie_types_htcap *ht_cap;
+	struct mwifiex_ie_types_htinfo *ht_info;
+	struct mwifiex_ie_types_chan_list_param_set *chan_list;
+	struct mwifiex_ie_types_2040bssco *bss_co_2040;
+	struct mwifiex_ie_types_extcap *ext_cap;
+	int ret_len = 0;
+	struct ieee80211_supported_band *sband;
+	u8 radio_type;
+
+	if (!buffer || !*buffer)
+		return ret_len;
+
+	radio_type = mwifiex_band_to_radio_type((u8) bss_desc->bss_band);
+	sband = priv->wdev->wiphy->bands[radio_type];
+
+	if (bss_desc->bcn_ht_cap) {
+		ht_cap = (struct mwifiex_ie_types_htcap *) *buffer;
+		memset(ht_cap, 0, sizeof(struct mwifiex_ie_types_htcap));
+		ht_cap->header.type = cpu_to_le16(WLAN_EID_HT_CAPABILITY);
+		ht_cap->header.len =
+				cpu_to_le16(sizeof(struct ieee80211_ht_cap));
+		memcpy((u8 *) ht_cap + sizeof(struct mwifiex_ie_types_header),
+		       (u8 *) bss_desc->bcn_ht_cap +
+		       sizeof(struct ieee_types_header),
+		       le16_to_cpu(ht_cap->header.len));
+
+		mwifiex_fill_cap_info(priv, radio_type, ht_cap);
+
+		*buffer += sizeof(struct mwifiex_ie_types_htcap);
+		ret_len += sizeof(struct mwifiex_ie_types_htcap);
+	}
+
+	if (bss_desc->bcn_ht_info) {
+		if (priv->bss_mode == NL80211_IFTYPE_ADHOC) {
+			ht_info = (struct mwifiex_ie_types_htinfo *) *buffer;
+			memset(ht_info, 0,
+			       sizeof(struct mwifiex_ie_types_htinfo));
+			ht_info->header.type =
+					cpu_to_le16(WLAN_EID_HT_INFORMATION);
+			ht_info->header.len =
+				cpu_to_le16(sizeof(struct ieee80211_ht_info));
+
+			memcpy((u8 *) ht_info +
+			       sizeof(struct mwifiex_ie_types_header),
+			       (u8 *) bss_desc->bcn_ht_info +
+			       sizeof(struct ieee_types_header),
+			       le16_to_cpu(ht_info->header.len));
+
+			if (!(sband->ht_cap.cap &
+					IEEE80211_HT_CAP_SUP_WIDTH_20_40))
+				ht_info->ht_info.ht_param &=
+					~(IEEE80211_HT_PARAM_CHAN_WIDTH_ANY |
+					IEEE80211_HT_PARAM_CHA_SEC_OFFSET);
+
+			*buffer += sizeof(struct mwifiex_ie_types_htinfo);
+			ret_len += sizeof(struct mwifiex_ie_types_htinfo);
+		}
+
+		chan_list =
+			(struct mwifiex_ie_types_chan_list_param_set *) *buffer;
+		memset(chan_list, 0,
+		       sizeof(struct mwifiex_ie_types_chan_list_param_set));
+		chan_list->header.type = cpu_to_le16(TLV_TYPE_CHANLIST);
+		chan_list->header.len = cpu_to_le16(
+			sizeof(struct mwifiex_ie_types_chan_list_param_set) -
+			sizeof(struct mwifiex_ie_types_header));
+		chan_list->chan_scan_param[0].chan_number =
+			bss_desc->bcn_ht_info->control_chan;
+		chan_list->chan_scan_param[0].radio_type =
+			mwifiex_band_to_radio_type((u8) bss_desc->bss_band);
+
+		if ((sband->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40)
+			&& (bss_desc->bcn_ht_info->ht_param &
+				IEEE80211_HT_PARAM_CHAN_WIDTH_ANY))
+			SET_SECONDARYCHAN(chan_list->chan_scan_param[0].
+					  radio_type,
+					  (bss_desc->bcn_ht_info->ht_param &
+					  IEEE80211_HT_PARAM_CHA_SEC_OFFSET));
+
+		*buffer += sizeof(struct mwifiex_ie_types_chan_list_param_set);
+		ret_len += sizeof(struct mwifiex_ie_types_chan_list_param_set);
+	}
+
+	if (bss_desc->bcn_bss_co_2040) {
+		bss_co_2040 = (struct mwifiex_ie_types_2040bssco *) *buffer;
+		memset(bss_co_2040, 0,
+		       sizeof(struct mwifiex_ie_types_2040bssco));
+		bss_co_2040->header.type = cpu_to_le16(WLAN_EID_BSS_COEX_2040);
+		bss_co_2040->header.len =
+		       cpu_to_le16(sizeof(bss_co_2040->bss_co_2040));
+
+		memcpy((u8 *) bss_co_2040 +
+		       sizeof(struct mwifiex_ie_types_header),
+		       (u8 *) bss_desc->bcn_bss_co_2040 +
+		       sizeof(struct ieee_types_header),
+		       le16_to_cpu(bss_co_2040->header.len));
+
+		*buffer += sizeof(struct mwifiex_ie_types_2040bssco);
+		ret_len += sizeof(struct mwifiex_ie_types_2040bssco);
+	}
+
+	if (bss_desc->bcn_ext_cap) {
+		ext_cap = (struct mwifiex_ie_types_extcap *) *buffer;
+		memset(ext_cap, 0, sizeof(struct mwifiex_ie_types_extcap));
+		ext_cap->header.type = cpu_to_le16(WLAN_EID_EXT_CAPABILITY);
+		ext_cap->header.len = cpu_to_le16(sizeof(ext_cap->ext_cap));
+
+		memcpy((u8 *) ext_cap +
+		       sizeof(struct mwifiex_ie_types_header),
+		       (u8 *) bss_desc->bcn_ext_cap +
+		       sizeof(struct ieee_types_header),
+		       le16_to_cpu(ext_cap->header.len));
+
+		*buffer += sizeof(struct mwifiex_ie_types_extcap);
+		ret_len += sizeof(struct mwifiex_ie_types_extcap);
+	}
+
+	return ret_len;
+}
+
+/*
+ * This function reconfigures the Tx buffer size in firmware.
+ *
+ * This function prepares a firmware command and issues it, if
+ * the current Tx buffer size is different from the one requested.
+ * Maximum configurable Tx buffer size is limited by the HT capability
+ * field value.
+ */
+void
+mwifiex_cfg_tx_buf(struct mwifiex_private *priv,
+		   struct mwifiex_bssdescriptor *bss_desc)
+{
+	u16 max_amsdu = MWIFIEX_TX_DATA_BUF_SIZE_2K;
+	u16 tx_buf, curr_tx_buf_size = 0;
+
+	if (bss_desc->bcn_ht_cap) {
+		if (le16_to_cpu(bss_desc->bcn_ht_cap->cap_info) &
+				IEEE80211_HT_CAP_MAX_AMSDU)
+			max_amsdu = MWIFIEX_TX_DATA_BUF_SIZE_8K;
+		else
+			max_amsdu = MWIFIEX_TX_DATA_BUF_SIZE_4K;
+	}
+
+	tx_buf = min(priv->adapter->max_tx_buf_size, max_amsdu);
+
+	dev_dbg(priv->adapter->dev, "info: max_amsdu=%d, max_tx_buf=%d\n",
+			max_amsdu, priv->adapter->max_tx_buf_size);
+
+	if (priv->adapter->curr_tx_buf_size <= MWIFIEX_TX_DATA_BUF_SIZE_2K)
+		curr_tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_2K;
+	else if (priv->adapter->curr_tx_buf_size <= MWIFIEX_TX_DATA_BUF_SIZE_4K)
+		curr_tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_4K;
+	else if (priv->adapter->curr_tx_buf_size <= MWIFIEX_TX_DATA_BUF_SIZE_8K)
+		curr_tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_8K;
+	if (curr_tx_buf_size != tx_buf)
+		mwifiex_send_cmd_async(priv, HostCmd_CMD_RECONFIGURE_TX_BUFF,
+				       HostCmd_ACT_GEN_SET, 0, &tx_buf);
+}
+
+/*
+ * This function checks if the given pointer is valid entry of
+ * Tx BA Stream table.
+ */
+static int mwifiex_is_tx_ba_stream_ptr_valid(struct mwifiex_private *priv,
+				struct mwifiex_tx_ba_stream_tbl *tx_tbl_ptr)
+{
+	struct mwifiex_tx_ba_stream_tbl *tx_ba_tsr_tbl;
+
+	list_for_each_entry(tx_ba_tsr_tbl, &priv->tx_ba_stream_tbl_ptr, list) {
+		if (tx_ba_tsr_tbl == tx_tbl_ptr)
+			return true;
+	}
+
+	return false;
+}
+
+/*
+ * This function deletes the given entry in Tx BA Stream table.
+ *
+ * The function also performs a validity check on the supplied
+ * pointer before trying to delete.
+ */
+void mwifiex_11n_delete_tx_ba_stream_tbl_entry(struct mwifiex_private *priv,
+				struct mwifiex_tx_ba_stream_tbl *tx_ba_tsr_tbl)
+{
+	if (!tx_ba_tsr_tbl &&
+			mwifiex_is_tx_ba_stream_ptr_valid(priv, tx_ba_tsr_tbl))
+		return;
+
+	dev_dbg(priv->adapter->dev, "info: tx_ba_tsr_tbl %p\n", tx_ba_tsr_tbl);
+
+	list_del(&tx_ba_tsr_tbl->list);
+
+	kfree(tx_ba_tsr_tbl);
+}
+
+/*
+ * This function deletes all the entries in Tx BA Stream table.
+ */
+void mwifiex_11n_delete_all_tx_ba_stream_tbl(struct mwifiex_private *priv)
+{
+	int i;
+	struct mwifiex_tx_ba_stream_tbl *del_tbl_ptr, *tmp_node;
+	unsigned long flags;
+
+	spin_lock_irqsave(&priv->tx_ba_stream_tbl_lock, flags);
+	list_for_each_entry_safe(del_tbl_ptr, tmp_node,
+				 &priv->tx_ba_stream_tbl_ptr, list)
+		mwifiex_11n_delete_tx_ba_stream_tbl_entry(priv, del_tbl_ptr);
+	spin_unlock_irqrestore(&priv->tx_ba_stream_tbl_lock, flags);
+
+	INIT_LIST_HEAD(&priv->tx_ba_stream_tbl_ptr);
+
+	for (i = 0; i < MAX_NUM_TID; ++i)
+		priv->aggr_prio_tbl[i].ampdu_ap =
+			priv->aggr_prio_tbl[i].ampdu_user;
+}
+
+/*
+ * This function returns the pointer to an entry in BA Stream
+ * table which matches the given RA/TID pair.
+ */
+struct mwifiex_tx_ba_stream_tbl *
+mwifiex_11n_get_tx_ba_stream_tbl(struct mwifiex_private *priv,
+				 int tid, u8 *ra)
+{
+	struct mwifiex_tx_ba_stream_tbl *tx_ba_tsr_tbl;
+	unsigned long flags;
+
+	spin_lock_irqsave(&priv->tx_ba_stream_tbl_lock, flags);
+	list_for_each_entry(tx_ba_tsr_tbl, &priv->tx_ba_stream_tbl_ptr, list) {
+		if ((!memcmp(tx_ba_tsr_tbl->ra, ra, ETH_ALEN))
+		    && (tx_ba_tsr_tbl->tid == tid)) {
+			spin_unlock_irqrestore(&priv->tx_ba_stream_tbl_lock,
+					       flags);
+			return tx_ba_tsr_tbl;
+		}
+	}
+	spin_unlock_irqrestore(&priv->tx_ba_stream_tbl_lock, flags);
+	return NULL;
+}
+
+/*
+ * This function creates an entry in Tx BA stream table for the
+ * given RA/TID pair.
+ */
+void mwifiex_11n_create_tx_ba_stream_tbl(struct mwifiex_private *priv,
+					 u8 *ra, int tid,
+					 enum mwifiex_ba_status ba_status)
+{
+	struct mwifiex_tx_ba_stream_tbl *new_node;
+	unsigned long flags;
+
+	if (!mwifiex_11n_get_tx_ba_stream_tbl(priv, tid, ra)) {
+		new_node = kzalloc(sizeof(struct mwifiex_tx_ba_stream_tbl),
+				   GFP_ATOMIC);
+		if (!new_node) {
+			dev_err(priv->adapter->dev,
+				"%s: failed to alloc new_node\n", __func__);
+			return;
+		}
+
+		INIT_LIST_HEAD(&new_node->list);
+
+		new_node->tid = tid;
+		new_node->ba_status = ba_status;
+		memcpy(new_node->ra, ra, ETH_ALEN);
+
+		spin_lock_irqsave(&priv->tx_ba_stream_tbl_lock, flags);
+		list_add_tail(&new_node->list, &priv->tx_ba_stream_tbl_ptr);
+		spin_unlock_irqrestore(&priv->tx_ba_stream_tbl_lock, flags);
+	}
+}
+
+/*
+ * This function sends an add BA request to the given TID/RA pair.
+ */
+int mwifiex_send_addba(struct mwifiex_private *priv, int tid, u8 *peer_mac)
+{
+	struct host_cmd_ds_11n_addba_req add_ba_req;
+	static u8 dialog_tok;
+	int ret;
+
+	dev_dbg(priv->adapter->dev, "cmd: %s: tid %d\n", __func__, tid);
+
+	add_ba_req.block_ack_param_set = cpu_to_le16(
+		(u16) ((tid << BLOCKACKPARAM_TID_POS) |
+			 (priv->add_ba_param.
+			  tx_win_size << BLOCKACKPARAM_WINSIZE_POS) |
+			 IMMEDIATE_BLOCK_ACK));
+	add_ba_req.block_ack_tmo = cpu_to_le16((u16)priv->add_ba_param.timeout);
+
+	++dialog_tok;
+
+	if (dialog_tok == 0)
+		dialog_tok = 1;
+
+	add_ba_req.dialog_token = dialog_tok;
+	memcpy(&add_ba_req.peer_mac_addr, peer_mac, ETH_ALEN);
+
+	/* We don't wait for the response of this command */
+	ret = mwifiex_send_cmd_async(priv, HostCmd_CMD_11N_ADDBA_REQ,
+				     0, 0, &add_ba_req);
+
+	return ret;
+}
+
+/*
+ * This function sends a delete BA request to the given TID/RA pair.
+ */
+int mwifiex_send_delba(struct mwifiex_private *priv, int tid, u8 *peer_mac,
+		       int initiator)
+{
+	struct host_cmd_ds_11n_delba delba;
+	int ret;
+	uint16_t del_ba_param_set;
+
+	memset(&delba, 0, sizeof(delba));
+	delba.del_ba_param_set = cpu_to_le16(tid << DELBA_TID_POS);
+
+	del_ba_param_set = le16_to_cpu(delba.del_ba_param_set);
+	if (initiator)
+		del_ba_param_set |= IEEE80211_DELBA_PARAM_INITIATOR_MASK;
+	else
+		del_ba_param_set &= ~IEEE80211_DELBA_PARAM_INITIATOR_MASK;
+
+	memcpy(&delba.peer_mac_addr, peer_mac, ETH_ALEN);
+
+	/* We don't wait for the response of this command */
+	ret = mwifiex_send_cmd_async(priv, HostCmd_CMD_11N_DELBA,
+				     HostCmd_ACT_GEN_SET, 0, &delba);
+
+	return ret;
+}
+
+/*
+ * This function handles the command response of a delete BA request.
+ */
+void mwifiex_11n_delete_ba_stream(struct mwifiex_private *priv, u8 *del_ba)
+{
+	struct host_cmd_ds_11n_delba *cmd_del_ba =
+		(struct host_cmd_ds_11n_delba *) del_ba;
+	uint16_t del_ba_param_set = le16_to_cpu(cmd_del_ba->del_ba_param_set);
+	int tid;
+
+	tid = del_ba_param_set >> DELBA_TID_POS;
+
+	mwifiex_11n_delete_ba_stream_tbl(priv, tid, cmd_del_ba->peer_mac_addr,
+					 TYPE_DELBA_RECEIVE,
+					 INITIATOR_BIT(del_ba_param_set));
+}
+
+/*
+ * This function retrieves the Rx reordering table.
+ */
+int mwifiex_get_rx_reorder_tbl(struct mwifiex_private *priv,
+			       struct mwifiex_ds_rx_reorder_tbl *buf)
+{
+	int i;
+	struct mwifiex_ds_rx_reorder_tbl *rx_reo_tbl = buf;
+	struct mwifiex_rx_reorder_tbl *rx_reorder_tbl_ptr;
+	int count = 0;
+	unsigned long flags;
+
+	spin_lock_irqsave(&priv->rx_reorder_tbl_lock, flags);
+	list_for_each_entry(rx_reorder_tbl_ptr, &priv->rx_reorder_tbl_ptr,
+			    list) {
+		rx_reo_tbl->tid = (u16) rx_reorder_tbl_ptr->tid;
+		memcpy(rx_reo_tbl->ta, rx_reorder_tbl_ptr->ta, ETH_ALEN);
+		rx_reo_tbl->start_win = rx_reorder_tbl_ptr->start_win;
+		rx_reo_tbl->win_size = rx_reorder_tbl_ptr->win_size;
+		for (i = 0; i < rx_reorder_tbl_ptr->win_size; ++i) {
+			if (rx_reorder_tbl_ptr->rx_reorder_ptr[i])
+				rx_reo_tbl->buffer[i] = true;
+			else
+				rx_reo_tbl->buffer[i] = false;
+		}
+		rx_reo_tbl++;
+		count++;
+
+		if (count >= MWIFIEX_MAX_RX_BASTREAM_SUPPORTED)
+			break;
+	}
+	spin_unlock_irqrestore(&priv->rx_reorder_tbl_lock, flags);
+
+	return count;
+}
+
+/*
+ * This function retrieves the Tx BA stream table.
+ */
+int mwifiex_get_tx_ba_stream_tbl(struct mwifiex_private *priv,
+				 struct mwifiex_ds_tx_ba_stream_tbl *buf)
+{
+	struct mwifiex_tx_ba_stream_tbl *tx_ba_tsr_tbl;
+	struct mwifiex_ds_tx_ba_stream_tbl *rx_reo_tbl = buf;
+	int count = 0;
+	unsigned long flags;
+
+	spin_lock_irqsave(&priv->tx_ba_stream_tbl_lock, flags);
+	list_for_each_entry(tx_ba_tsr_tbl, &priv->tx_ba_stream_tbl_ptr, list) {
+		rx_reo_tbl->tid = (u16) tx_ba_tsr_tbl->tid;
+		dev_dbg(priv->adapter->dev, "data: %s tid=%d\n",
+						__func__, rx_reo_tbl->tid);
+		memcpy(rx_reo_tbl->ra, tx_ba_tsr_tbl->ra, ETH_ALEN);
+		rx_reo_tbl++;
+		count++;
+		if (count >= MWIFIEX_MAX_TX_BASTREAM_SUPPORTED)
+			break;
+	}
+	spin_unlock_irqrestore(&priv->tx_ba_stream_tbl_lock, flags);
+
+	return count;
+}
diff -druN linux-2.6.39-libre/drivers/net/wireless/mwifiex/11n.h linux-3.0-rc7-libre/drivers/net/wireless/mwifiex/11n.h
--- linux-2.6.39-libre/drivers/net/wireless/mwifiex/11n.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/net/wireless/mwifiex/11n.h	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,161 @@
+/*
+ * Marvell Wireless LAN device driver: 802.11n
+ *
+ * Copyright (C) 2011, Marvell International Ltd.
+ *
+ * This software file (the "File") is distributed by Marvell International
+ * Ltd. under the terms of the GNU General Public License Version 2, June 1991
+ * (the "License").  You may use, redistribute and/or modify this File in
+ * accordance with the terms and conditions of the License, a copy of which
+ * is available by writing to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
+ * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
+ *
+ * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
+ * ARE EXPRESSLY DISCLAIMED.  The License provides additional details about
+ * this warranty disclaimer.
+ */
+
+#ifndef _MWIFIEX_11N_H_
+#define _MWIFIEX_11N_H_
+
+#include "11n_aggr.h"
+#include "11n_rxreorder.h"
+#include "wmm.h"
+
+int mwifiex_ret_11n_delba(struct mwifiex_private *priv,
+			  struct host_cmd_ds_command *resp);
+int mwifiex_ret_11n_addba_req(struct mwifiex_private *priv,
+			      struct host_cmd_ds_command *resp);
+int mwifiex_ret_11n_cfg(struct host_cmd_ds_command *resp,
+			void *data_buf);
+int mwifiex_cmd_11n_cfg(struct host_cmd_ds_command *cmd,
+			u16 cmd_action, void *data_buf);
+
+int mwifiex_cmd_append_11n_tlv(struct mwifiex_private *priv,
+			       struct mwifiex_bssdescriptor *bss_desc,
+			       u8 **buffer);
+void mwifiex_cfg_tx_buf(struct mwifiex_private *priv,
+			struct mwifiex_bssdescriptor *bss_desc);
+void mwifiex_fill_cap_info(struct mwifiex_private *, u8 radio_type,
+			   struct mwifiex_ie_types_htcap *);
+int mwifiex_set_get_11n_htcap_cfg(struct mwifiex_private *priv,
+				  u16 action, int *htcap_cfg);
+void mwifiex_11n_delete_tx_ba_stream_tbl_entry(struct mwifiex_private *priv,
+					     struct mwifiex_tx_ba_stream_tbl
+					     *tx_tbl);
+void mwifiex_11n_delete_all_tx_ba_stream_tbl(struct mwifiex_private *priv);
+struct mwifiex_tx_ba_stream_tbl *mwifiex_11n_get_tx_ba_stream_tbl(struct
+							     mwifiex_private
+							     *priv, int tid,
+							     u8 *ra);
+void mwifiex_11n_create_tx_ba_stream_tbl(struct mwifiex_private *priv, u8 *ra,
+				       int tid,
+				       enum mwifiex_ba_status ba_status);
+int mwifiex_send_addba(struct mwifiex_private *priv, int tid, u8 *peer_mac);
+int mwifiex_send_delba(struct mwifiex_private *priv, int tid, u8 *peer_mac,
+		       int initiator);
+void mwifiex_11n_delete_ba_stream(struct mwifiex_private *priv, u8 *del_ba);
+int mwifiex_get_rx_reorder_tbl(struct mwifiex_private *priv,
+			      struct mwifiex_ds_rx_reorder_tbl *buf);
+int mwifiex_get_tx_ba_stream_tbl(struct mwifiex_private *priv,
+			       struct mwifiex_ds_tx_ba_stream_tbl *buf);
+int mwifiex_ret_amsdu_aggr_ctrl(struct host_cmd_ds_command *resp,
+				void *data_buf);
+int mwifiex_cmd_recfg_tx_buf(struct mwifiex_private *priv,
+			     struct host_cmd_ds_command *cmd,
+			     int cmd_action, void *data_buf);
+int mwifiex_cmd_amsdu_aggr_ctrl(struct host_cmd_ds_command *cmd,
+				int cmd_action, void *data_buf);
+
+/*
+ * This function checks whether AMPDU is allowed or not for a particular TID.
+ */
+static inline u8
+mwifiex_is_ampdu_allowed(struct mwifiex_private *priv, int tid)
+{
+	return ((priv->aggr_prio_tbl[tid].ampdu_ap != BA_STREAM_NOT_ALLOWED)
+		? true : false);
+}
+
+/*
+ * This function checks whether AMSDU is allowed or not for a particular TID.
+ */
+static inline u8
+mwifiex_is_amsdu_allowed(struct mwifiex_private *priv, int tid)
+{
+	return (((priv->aggr_prio_tbl[tid].amsdu != BA_STREAM_NOT_ALLOWED)
+			&& ((priv->is_data_rate_auto)
+			|| !((priv->bitmap_rates[2]) & 0x03)))
+		? true : false);
+}
+
+/*
+ * This function checks whether a space is available for new BA stream or not.
+ */
+static inline u8 mwifiex_space_avail_for_new_ba_stream(
+					struct mwifiex_adapter *adapter)
+{
+	struct mwifiex_private *priv;
+	u8 i;
+	u32 ba_stream_num = 0;
+
+	for (i = 0; i < adapter->priv_num; i++) {
+		priv = adapter->priv[i];
+		if (priv)
+			ba_stream_num += mwifiex_wmm_list_len(
+						(struct list_head *)
+						&priv->tx_ba_stream_tbl_ptr);
+	}
+
+	return ((ba_stream_num <
+		 MWIFIEX_MAX_TX_BASTREAM_SUPPORTED) ? true : false);
+}
+
+/*
+ * This function finds the correct Tx BA stream to delete.
+ *
+ * Upon successfully locating, both the TID and the RA are returned.
+ */
+static inline u8
+mwifiex_find_stream_to_delete(struct mwifiex_private *priv, int ptr_tid,
+			      int *ptid, u8 *ra)
+{
+	int tid;
+	u8 ret = false;
+	struct mwifiex_tx_ba_stream_tbl *tx_tbl;
+	unsigned long flags;
+
+	tid = priv->aggr_prio_tbl[ptr_tid].ampdu_user;
+
+	spin_lock_irqsave(&priv->tx_ba_stream_tbl_lock, flags);
+	list_for_each_entry(tx_tbl, &priv->tx_ba_stream_tbl_ptr, list) {
+		if (tid > priv->aggr_prio_tbl[tx_tbl->tid].ampdu_user) {
+			tid = priv->aggr_prio_tbl[tx_tbl->tid].ampdu_user;
+			*ptid = tx_tbl->tid;
+			memcpy(ra, tx_tbl->ra, ETH_ALEN);
+			ret = true;
+		}
+	}
+	spin_unlock_irqrestore(&priv->tx_ba_stream_tbl_lock, flags);
+
+	return ret;
+}
+
+/*
+ * This function checks whether BA stream is set up or not.
+ */
+static inline int
+mwifiex_is_ba_stream_setup(struct mwifiex_private *priv,
+			  struct mwifiex_ra_list_tbl *ptr, int tid)
+{
+	struct mwifiex_tx_ba_stream_tbl *tx_tbl;
+
+	tx_tbl = mwifiex_11n_get_tx_ba_stream_tbl(priv, tid, ptr->ra);
+	if (tx_tbl && IS_BASTREAM_SETUP(tx_tbl))
+		return true;
+
+	return false;
+}
+#endif /* !_MWIFIEX_11N_H_ */
diff -druN linux-2.6.39-libre/drivers/net/wireless/mwifiex/11n_rxreorder.c linux-3.0-rc7-libre/drivers/net/wireless/mwifiex/11n_rxreorder.c
--- linux-2.6.39-libre/drivers/net/wireless/mwifiex/11n_rxreorder.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/net/wireless/mwifiex/11n_rxreorder.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,616 @@
+/*
+ * Marvell Wireless LAN device driver: 802.11n RX Re-ordering
+ *
+ * Copyright (C) 2011, Marvell International Ltd.
+ *
+ * This software file (the "File") is distributed by Marvell International
+ * Ltd. under the terms of the GNU General Public License Version 2, June 1991
+ * (the "License").  You may use, redistribute and/or modify this File in
+ * accordance with the terms and conditions of the License, a copy of which
+ * is available by writing to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
+ * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
+ *
+ * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
+ * ARE EXPRESSLY DISCLAIMED.  The License provides additional details about
+ * this warranty disclaimer.
+ */
+
+#include "decl.h"
+#include "ioctl.h"
+#include "util.h"
+#include "fw.h"
+#include "main.h"
+#include "wmm.h"
+#include "11n.h"
+#include "11n_rxreorder.h"
+
+/*
+ * This function dispatches all packets in the Rx reorder table.
+ *
+ * There could be holes in the buffer, which are skipped by the function.
+ * Since the buffer is linear, the function uses rotation to simulate
+ * circular buffer.
+ */
+static int
+mwifiex_11n_dispatch_pkt_until_start_win(struct mwifiex_private *priv,
+					 struct mwifiex_rx_reorder_tbl
+					 *rx_reor_tbl_ptr, int start_win)
+{
+	int no_pkt_to_send, i;
+	void *rx_tmp_ptr;
+	unsigned long flags;
+
+	no_pkt_to_send = (start_win > rx_reor_tbl_ptr->start_win) ?
+		min((start_win - rx_reor_tbl_ptr->start_win),
+		    rx_reor_tbl_ptr->win_size) : rx_reor_tbl_ptr->win_size;
+
+	for (i = 0; i < no_pkt_to_send; ++i) {
+		spin_lock_irqsave(&priv->rx_pkt_lock, flags);
+		rx_tmp_ptr = NULL;
+		if (rx_reor_tbl_ptr->rx_reorder_ptr[i]) {
+			rx_tmp_ptr = rx_reor_tbl_ptr->rx_reorder_ptr[i];
+			rx_reor_tbl_ptr->rx_reorder_ptr[i] = NULL;
+		}
+		spin_unlock_irqrestore(&priv->rx_pkt_lock, flags);
+		if (rx_tmp_ptr)
+			mwifiex_process_rx_packet(priv->adapter, rx_tmp_ptr);
+	}
+
+	spin_lock_irqsave(&priv->rx_pkt_lock, flags);
+	/*
+	 * We don't have a circular buffer, hence use rotation to simulate
+	 * circular buffer
+	 */
+	for (i = 0; i < rx_reor_tbl_ptr->win_size - no_pkt_to_send; ++i) {
+		rx_reor_tbl_ptr->rx_reorder_ptr[i] =
+			rx_reor_tbl_ptr->rx_reorder_ptr[no_pkt_to_send + i];
+		rx_reor_tbl_ptr->rx_reorder_ptr[no_pkt_to_send + i] = NULL;
+	}
+
+	rx_reor_tbl_ptr->start_win = start_win;
+	spin_unlock_irqrestore(&priv->rx_pkt_lock, flags);
+
+	return 0;
+}
+
+/*
+ * This function dispatches all packets in the Rx reorder table until
+ * a hole is found.
+ *
+ * The start window is adjusted automatically when a hole is located.
+ * Since the buffer is linear, the function uses rotation to simulate
+ * circular buffer.
+ */
+static int
+mwifiex_11n_scan_and_dispatch(struct mwifiex_private *priv,
+			      struct mwifiex_rx_reorder_tbl *rx_reor_tbl_ptr)
+{
+	int i, j, xchg;
+	void *rx_tmp_ptr;
+	unsigned long flags;
+
+	for (i = 0; i < rx_reor_tbl_ptr->win_size; ++i) {
+		spin_lock_irqsave(&priv->rx_pkt_lock, flags);
+		if (!rx_reor_tbl_ptr->rx_reorder_ptr[i]) {
+			spin_unlock_irqrestore(&priv->rx_pkt_lock, flags);
+			break;
+		}
+		rx_tmp_ptr = rx_reor_tbl_ptr->rx_reorder_ptr[i];
+		rx_reor_tbl_ptr->rx_reorder_ptr[i] = NULL;
+		spin_unlock_irqrestore(&priv->rx_pkt_lock, flags);
+		mwifiex_process_rx_packet(priv->adapter, rx_tmp_ptr);
+	}
+
+	spin_lock_irqsave(&priv->rx_pkt_lock, flags);
+	/*
+	 * We don't have a circular buffer, hence use rotation to simulate
+	 * circular buffer
+	 */
+	if (i > 0) {
+		xchg = rx_reor_tbl_ptr->win_size - i;
+		for (j = 0; j < xchg; ++j) {
+			rx_reor_tbl_ptr->rx_reorder_ptr[j] =
+				rx_reor_tbl_ptr->rx_reorder_ptr[i + j];
+			rx_reor_tbl_ptr->rx_reorder_ptr[i + j] = NULL;
+		}
+	}
+	rx_reor_tbl_ptr->start_win = (rx_reor_tbl_ptr->start_win + i)
+		&(MAX_TID_VALUE - 1);
+	spin_unlock_irqrestore(&priv->rx_pkt_lock, flags);
+	return 0;
+}
+
+/*
+ * This function deletes the Rx reorder table and frees the memory.
+ *
+ * The function stops the associated timer and dispatches all the
+ * pending packets in the Rx reorder table before deletion.
+ */
+static void
+mwifiex_11n_delete_rx_reorder_tbl_entry(struct mwifiex_private *priv,
+				       struct mwifiex_rx_reorder_tbl
+				       *rx_reor_tbl_ptr)
+{
+	unsigned long flags;
+
+	if (!rx_reor_tbl_ptr)
+		return;
+
+	mwifiex_11n_dispatch_pkt_until_start_win(priv, rx_reor_tbl_ptr,
+						 (rx_reor_tbl_ptr->start_win +
+						  rx_reor_tbl_ptr->win_size)
+						 &(MAX_TID_VALUE - 1));
+
+	del_timer(&rx_reor_tbl_ptr->timer_context.timer);
+
+	spin_lock_irqsave(&priv->rx_reorder_tbl_lock, flags);
+	list_del(&rx_reor_tbl_ptr->list);
+	spin_unlock_irqrestore(&priv->rx_reorder_tbl_lock, flags);
+
+	kfree(rx_reor_tbl_ptr->rx_reorder_ptr);
+	kfree(rx_reor_tbl_ptr);
+}
+
+/*
+ * This function returns the pointer to an entry in Rx reordering
+ * table which matches the given TA/TID pair.
+ */
+static struct mwifiex_rx_reorder_tbl *
+mwifiex_11n_get_rx_reorder_tbl(struct mwifiex_private *priv, int tid, u8 *ta)
+{
+	struct mwifiex_rx_reorder_tbl *rx_reor_tbl_ptr;
+	unsigned long flags;
+
+	spin_lock_irqsave(&priv->rx_reorder_tbl_lock, flags);
+	list_for_each_entry(rx_reor_tbl_ptr, &priv->rx_reorder_tbl_ptr, list) {
+		if ((!memcmp(rx_reor_tbl_ptr->ta, ta, ETH_ALEN))
+		    && (rx_reor_tbl_ptr->tid == tid)) {
+			spin_unlock_irqrestore(&priv->rx_reorder_tbl_lock,
+					       flags);
+			return rx_reor_tbl_ptr;
+		}
+	}
+	spin_unlock_irqrestore(&priv->rx_reorder_tbl_lock, flags);
+
+	return NULL;
+}
+
+/*
+ * This function finds the last sequence number used in the packets
+ * buffered in Rx reordering table.
+ */
+static int
+mwifiex_11n_find_last_seq_num(struct mwifiex_rx_reorder_tbl *rx_reorder_tbl_ptr)
+{
+	int i;
+
+	for (i = (rx_reorder_tbl_ptr->win_size - 1); i >= 0; --i)
+		if (rx_reorder_tbl_ptr->rx_reorder_ptr[i])
+			return i;
+
+	return -1;
+}
+
+/*
+ * This function flushes all the packets in Rx reordering table.
+ *
+ * The function checks if any packets are currently buffered in the
+ * table or not. In case there are packets available, it dispatches
+ * them and then dumps the Rx reordering table.
+ */
+static void
+mwifiex_flush_data(unsigned long context)
+{
+	struct reorder_tmr_cnxt *reorder_cnxt =
+		(struct reorder_tmr_cnxt *) context;
+	int start_win;
+
+	start_win = mwifiex_11n_find_last_seq_num(reorder_cnxt->ptr);
+	if (start_win >= 0) {
+		dev_dbg(reorder_cnxt->priv->adapter->dev,
+				"info: flush data %d\n", start_win);
+		mwifiex_11n_dispatch_pkt_until_start_win(reorder_cnxt->priv,
+				reorder_cnxt->ptr,
+				((reorder_cnxt->ptr->start_win +
+				  start_win + 1) & (MAX_TID_VALUE - 1)));
+	}
+}
+
+/*
+ * This function creates an entry in Rx reordering table for the
+ * given TA/TID.
+ *
+ * The function also initializes the entry with sequence number, window
+ * size as well as initializes the timer.
+ *
+ * If the received TA/TID pair is already present, all the packets are
+ * dispatched and the window size is moved until the SSN.
+ */
+static void
+mwifiex_11n_create_rx_reorder_tbl(struct mwifiex_private *priv, u8 *ta,
+				 int tid, int win_size, int seq_num)
+{
+	int i;
+	struct mwifiex_rx_reorder_tbl *rx_reor_tbl_ptr, *new_node;
+	u16 last_seq = 0;
+	unsigned long flags;
+
+	/*
+	 * If we get a TID, ta pair which is already present dispatch all the
+	 * the packets and move the window size until the ssn
+	 */
+	rx_reor_tbl_ptr = mwifiex_11n_get_rx_reorder_tbl(priv, tid, ta);
+	if (rx_reor_tbl_ptr) {
+		mwifiex_11n_dispatch_pkt_until_start_win(priv, rx_reor_tbl_ptr,
+							 seq_num);
+		return;
+	}
+	/* if !rx_reor_tbl_ptr then create one */
+	new_node = kzalloc(sizeof(struct mwifiex_rx_reorder_tbl), GFP_KERNEL);
+	if (!new_node) {
+		dev_err(priv->adapter->dev, "%s: failed to alloc new_node\n",
+		       __func__);
+		return;
+	}
+
+	INIT_LIST_HEAD(&new_node->list);
+	new_node->tid = tid;
+	memcpy(new_node->ta, ta, ETH_ALEN);
+	new_node->start_win = seq_num;
+	if (mwifiex_queuing_ra_based(priv))
+		/* TODO for adhoc */
+		dev_dbg(priv->adapter->dev,
+			"info: ADHOC:last_seq=%d start_win=%d\n",
+			last_seq, new_node->start_win);
+	else
+		last_seq = priv->rx_seq[tid];
+
+	if (last_seq >= new_node->start_win)
+		new_node->start_win = last_seq + 1;
+
+	new_node->win_size = win_size;
+
+	new_node->rx_reorder_ptr = kzalloc(sizeof(void *) * win_size,
+					GFP_KERNEL);
+	if (!new_node->rx_reorder_ptr) {
+		kfree((u8 *) new_node);
+		dev_err(priv->adapter->dev,
+			"%s: failed to alloc reorder_ptr\n", __func__);
+		return;
+	}
+
+	new_node->timer_context.ptr = new_node;
+	new_node->timer_context.priv = priv;
+
+	init_timer(&new_node->timer_context.timer);
+	new_node->timer_context.timer.function = mwifiex_flush_data;
+	new_node->timer_context.timer.data =
+			(unsigned long) &new_node->timer_context;
+
+	for (i = 0; i < win_size; ++i)
+		new_node->rx_reorder_ptr[i] = NULL;
+
+	spin_lock_irqsave(&priv->rx_reorder_tbl_lock, flags);
+	list_add_tail(&new_node->list, &priv->rx_reorder_tbl_ptr);
+	spin_unlock_irqrestore(&priv->rx_reorder_tbl_lock, flags);
+}
+
+/*
+ * This function prepares command for adding a BA request.
+ *
+ * Preparation includes -
+ *      - Setting command ID and proper size
+ *      - Setting add BA request buffer
+ *      - Ensuring correct endian-ness
+ */
+int mwifiex_cmd_11n_addba_req(struct host_cmd_ds_command *cmd, void *data_buf)
+{
+	struct host_cmd_ds_11n_addba_req *add_ba_req =
+		(struct host_cmd_ds_11n_addba_req *)
+		&cmd->params.add_ba_req;
+
+	cmd->command = cpu_to_le16(HostCmd_CMD_11N_ADDBA_REQ);
+	cmd->size = cpu_to_le16(sizeof(*add_ba_req) + S_DS_GEN);
+	memcpy(add_ba_req, data_buf, sizeof(*add_ba_req));
+
+	return 0;
+}
+
+/*
+ * This function prepares command for adding a BA response.
+ *
+ * Preparation includes -
+ *      - Setting command ID and proper size
+ *      - Setting add BA response buffer
+ *      - Ensuring correct endian-ness
+ */
+int mwifiex_cmd_11n_addba_rsp_gen(struct mwifiex_private *priv,
+				  struct host_cmd_ds_command *cmd,
+				  void *data_buf)
+{
+	struct host_cmd_ds_11n_addba_rsp *add_ba_rsp =
+		(struct host_cmd_ds_11n_addba_rsp *)
+		&cmd->params.add_ba_rsp;
+	struct host_cmd_ds_11n_addba_req *cmd_addba_req =
+		(struct host_cmd_ds_11n_addba_req *) data_buf;
+	u8 tid;
+	int win_size;
+	uint16_t block_ack_param_set;
+
+	cmd->command = cpu_to_le16(HostCmd_CMD_11N_ADDBA_RSP);
+	cmd->size = cpu_to_le16(sizeof(*add_ba_rsp) + S_DS_GEN);
+
+	memcpy(add_ba_rsp->peer_mac_addr, cmd_addba_req->peer_mac_addr,
+	       ETH_ALEN);
+	add_ba_rsp->dialog_token = cmd_addba_req->dialog_token;
+	add_ba_rsp->block_ack_tmo = cmd_addba_req->block_ack_tmo;
+	add_ba_rsp->ssn = cmd_addba_req->ssn;
+
+	block_ack_param_set = le16_to_cpu(cmd_addba_req->block_ack_param_set);
+	tid = (block_ack_param_set & IEEE80211_ADDBA_PARAM_TID_MASK)
+		>> BLOCKACKPARAM_TID_POS;
+	add_ba_rsp->status_code = cpu_to_le16(ADDBA_RSP_STATUS_ACCEPT);
+	block_ack_param_set &= ~IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK;
+	/* We donot support AMSDU inside AMPDU, hence reset the bit */
+	block_ack_param_set &= ~BLOCKACKPARAM_AMSDU_SUPP_MASK;
+	block_ack_param_set |= (priv->add_ba_param.rx_win_size <<
+					     BLOCKACKPARAM_WINSIZE_POS);
+	add_ba_rsp->block_ack_param_set = cpu_to_le16(block_ack_param_set);
+	win_size = (le16_to_cpu(add_ba_rsp->block_ack_param_set)
+					& IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK)
+					>> BLOCKACKPARAM_WINSIZE_POS;
+	cmd_addba_req->block_ack_param_set = cpu_to_le16(block_ack_param_set);
+
+	mwifiex_11n_create_rx_reorder_tbl(priv, cmd_addba_req->peer_mac_addr,
+			    tid, win_size, le16_to_cpu(cmd_addba_req->ssn));
+	return 0;
+}
+
+/*
+ * This function prepares command for deleting a BA request.
+ *
+ * Preparation includes -
+ *      - Setting command ID and proper size
+ *      - Setting del BA request buffer
+ *      - Ensuring correct endian-ness
+ */
+int mwifiex_cmd_11n_delba(struct host_cmd_ds_command *cmd, void *data_buf)
+{
+	struct host_cmd_ds_11n_delba *del_ba = (struct host_cmd_ds_11n_delba *)
+		&cmd->params.del_ba;
+
+	cmd->command = cpu_to_le16(HostCmd_CMD_11N_DELBA);
+	cmd->size = cpu_to_le16(sizeof(*del_ba) + S_DS_GEN);
+	memcpy(del_ba, data_buf, sizeof(*del_ba));
+
+	return 0;
+}
+
+/*
+ * This function identifies if Rx reordering is needed for a received packet.
+ *
+ * In case reordering is required, the function will do the reordering
+ * before sending it to kernel.
+ *
+ * The Rx reorder table is checked first with the received TID/TA pair. If
+ * not found, the received packet is dispatched immediately. But if found,
+ * the packet is reordered and all the packets in the updated Rx reordering
+ * table is dispatched until a hole is found.
+ *
+ * For sequence number less than the starting window, the packet is dropped.
+ */
+int mwifiex_11n_rx_reorder_pkt(struct mwifiex_private *priv,
+				u16 seq_num, u16 tid,
+				u8 *ta, u8 pkt_type, void *payload)
+{
+	struct mwifiex_rx_reorder_tbl *rx_reor_tbl_ptr;
+	int start_win, end_win, win_size, ret;
+	u16 pkt_index;
+
+	rx_reor_tbl_ptr =
+		mwifiex_11n_get_rx_reorder_tbl((struct mwifiex_private *) priv,
+						tid, ta);
+	if (!rx_reor_tbl_ptr) {
+		if (pkt_type != PKT_TYPE_BAR)
+			mwifiex_process_rx_packet(priv->adapter, payload);
+		return 0;
+	}
+	start_win = rx_reor_tbl_ptr->start_win;
+	win_size = rx_reor_tbl_ptr->win_size;
+	end_win = ((start_win + win_size) - 1) & (MAX_TID_VALUE - 1);
+	del_timer(&rx_reor_tbl_ptr->timer_context.timer);
+	mod_timer(&rx_reor_tbl_ptr->timer_context.timer, jiffies
+			+ (MIN_FLUSH_TIMER_MS * win_size * HZ) / 1000);
+
+	/*
+	 * If seq_num is less then starting win then ignore and drop the
+	 * packet
+	 */
+	if ((start_win + TWOPOW11) > (MAX_TID_VALUE - 1)) {/* Wrap */
+		if (seq_num >= ((start_win + (TWOPOW11)) & (MAX_TID_VALUE - 1))
+				&& (seq_num < start_win))
+			return -1;
+	} else if ((seq_num < start_win)
+			|| (seq_num > (start_win + (TWOPOW11)))) {
+		return -1;
+	}
+
+	/*
+	 * If this packet is a BAR we adjust seq_num as
+	 * WinStart = seq_num
+	 */
+	if (pkt_type == PKT_TYPE_BAR)
+		seq_num = ((seq_num + win_size) - 1) & (MAX_TID_VALUE - 1);
+
+	if (((end_win < start_win)
+	     && (seq_num < (TWOPOW11 - (MAX_TID_VALUE - start_win)))
+	     && (seq_num > end_win)) || ((end_win > start_win)
+	     && ((seq_num > end_win) || (seq_num < start_win)))) {
+		end_win = seq_num;
+		if (((seq_num - win_size) + 1) >= 0)
+			start_win = (end_win - win_size) + 1;
+		else
+			start_win = (MAX_TID_VALUE - (win_size - seq_num)) + 1;
+		ret = mwifiex_11n_dispatch_pkt_until_start_win(priv,
+						rx_reor_tbl_ptr, start_win);
+
+		if (ret)
+			return ret;
+	}
+
+	if (pkt_type != PKT_TYPE_BAR) {
+		if (seq_num >= start_win)
+			pkt_index = seq_num - start_win;
+		else
+			pkt_index = (seq_num+MAX_TID_VALUE) - start_win;
+
+		if (rx_reor_tbl_ptr->rx_reorder_ptr[pkt_index])
+			return -1;
+
+		rx_reor_tbl_ptr->rx_reorder_ptr[pkt_index] = payload;
+	}
+
+	/*
+	 * Dispatch all packets sequentially from start_win until a
+	 * hole is found and adjust the start_win appropriately
+	 */
+	ret = mwifiex_11n_scan_and_dispatch(priv, rx_reor_tbl_ptr);
+
+	return ret;
+}
+
+/*
+ * This function deletes an entry for a given TID/TA pair.
+ *
+ * The TID/TA are taken from del BA event body.
+ */
+void
+mwifiex_11n_delete_ba_stream_tbl(struct mwifiex_private *priv, int tid,
+				u8 *peer_mac, u8 type, int initiator)
+{
+	struct mwifiex_rx_reorder_tbl *rx_reor_tbl_ptr;
+	struct mwifiex_tx_ba_stream_tbl *ptx_tbl;
+	u8 cleanup_rx_reorder_tbl;
+	unsigned long flags;
+
+	if (type == TYPE_DELBA_RECEIVE)
+		cleanup_rx_reorder_tbl = (initiator) ? true : false;
+	else
+		cleanup_rx_reorder_tbl = (initiator) ? false : true;
+
+	dev_dbg(priv->adapter->dev, "event: DELBA: %pM tid=%d, "
+	       "initiator=%d\n", peer_mac, tid, initiator);
+
+	if (cleanup_rx_reorder_tbl) {
+		rx_reor_tbl_ptr = mwifiex_11n_get_rx_reorder_tbl(priv, tid,
+								 peer_mac);
+		if (!rx_reor_tbl_ptr) {
+			dev_dbg(priv->adapter->dev,
+					"event: TID, TA not found in table\n");
+			return;
+		}
+		mwifiex_11n_delete_rx_reorder_tbl_entry(priv, rx_reor_tbl_ptr);
+	} else {
+		ptx_tbl = mwifiex_11n_get_tx_ba_stream_tbl(priv, tid, peer_mac);
+		if (!ptx_tbl) {
+			dev_dbg(priv->adapter->dev,
+					"event: TID, RA not found in table\n");
+			return;
+		}
+
+		spin_lock_irqsave(&priv->tx_ba_stream_tbl_lock, flags);
+		mwifiex_11n_delete_tx_ba_stream_tbl_entry(priv, ptx_tbl);
+		spin_unlock_irqrestore(&priv->tx_ba_stream_tbl_lock, flags);
+	}
+}
+
+/*
+ * This function handles the command response of an add BA response.
+ *
+ * Handling includes changing the header fields into CPU format and
+ * creating the stream, provided the add BA is accepted.
+ */
+int mwifiex_ret_11n_addba_resp(struct mwifiex_private *priv,
+			       struct host_cmd_ds_command *resp)
+{
+	struct host_cmd_ds_11n_addba_rsp *add_ba_rsp =
+		(struct host_cmd_ds_11n_addba_rsp *)
+		&resp->params.add_ba_rsp;
+	int tid, win_size;
+	struct mwifiex_rx_reorder_tbl *rx_reor_tbl_ptr;
+	uint16_t block_ack_param_set;
+
+	block_ack_param_set = le16_to_cpu(add_ba_rsp->block_ack_param_set);
+
+	tid = (block_ack_param_set & IEEE80211_ADDBA_PARAM_TID_MASK)
+		>> BLOCKACKPARAM_TID_POS;
+	/*
+	 * Check if we had rejected the ADDBA, if yes then do not create
+	 * the stream
+	 */
+	if (le16_to_cpu(add_ba_rsp->status_code) == BA_RESULT_SUCCESS) {
+		win_size = (block_ack_param_set &
+			IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK)
+			>> BLOCKACKPARAM_WINSIZE_POS;
+
+		dev_dbg(priv->adapter->dev, "cmd: ADDBA RSP: %pM"
+		       " tid=%d ssn=%d win_size=%d\n",
+		       add_ba_rsp->peer_mac_addr,
+		       tid, add_ba_rsp->ssn, win_size);
+	} else {
+		dev_err(priv->adapter->dev, "ADDBA RSP: failed %pM tid=%d)\n",
+					add_ba_rsp->peer_mac_addr, tid);
+
+		rx_reor_tbl_ptr = mwifiex_11n_get_rx_reorder_tbl(priv,
+					tid, add_ba_rsp->peer_mac_addr);
+		if (rx_reor_tbl_ptr)
+			mwifiex_11n_delete_rx_reorder_tbl_entry(priv,
+				rx_reor_tbl_ptr);
+	}
+
+	return 0;
+}
+
+/*
+ * This function handles BA stream timeout event by preparing and sending
+ * a command to the firmware.
+ */
+void mwifiex_11n_ba_stream_timeout(struct mwifiex_private *priv,
+				   struct host_cmd_ds_11n_batimeout *event)
+{
+	struct host_cmd_ds_11n_delba delba;
+
+	memset(&delba, 0, sizeof(struct host_cmd_ds_11n_delba));
+	memcpy(delba.peer_mac_addr, event->peer_mac_addr, ETH_ALEN);
+
+	delba.del_ba_param_set |=
+		cpu_to_le16((u16) event->tid << DELBA_TID_POS);
+	delba.del_ba_param_set |= cpu_to_le16(
+		(u16) event->origninator << DELBA_INITIATOR_POS);
+	delba.reason_code = cpu_to_le16(WLAN_REASON_QSTA_TIMEOUT);
+	mwifiex_send_cmd_async(priv, HostCmd_CMD_11N_DELBA, 0, 0, &delba);
+}
+
+/*
+ * This function cleans up the Rx reorder table by deleting all the entries
+ * and re-initializing.
+ */
+void mwifiex_11n_cleanup_reorder_tbl(struct mwifiex_private *priv)
+{
+	struct mwifiex_rx_reorder_tbl *del_tbl_ptr, *tmp_node;
+	unsigned long flags;
+
+	spin_lock_irqsave(&priv->rx_reorder_tbl_lock, flags);
+	list_for_each_entry_safe(del_tbl_ptr, tmp_node,
+				 &priv->rx_reorder_tbl_ptr, list) {
+		spin_unlock_irqrestore(&priv->rx_reorder_tbl_lock, flags);
+		mwifiex_11n_delete_rx_reorder_tbl_entry(priv, del_tbl_ptr);
+		spin_lock_irqsave(&priv->rx_reorder_tbl_lock, flags);
+	}
+	spin_unlock_irqrestore(&priv->rx_reorder_tbl_lock, flags);
+
+	INIT_LIST_HEAD(&priv->rx_reorder_tbl_ptr);
+	memset(priv->rx_seq, 0, sizeof(priv->rx_seq));
+}
diff -druN linux-2.6.39-libre/drivers/net/wireless/mwifiex/11n_rxreorder.h linux-3.0-rc7-libre/drivers/net/wireless/mwifiex/11n_rxreorder.h
--- linux-2.6.39-libre/drivers/net/wireless/mwifiex/11n_rxreorder.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/net/wireless/mwifiex/11n_rxreorder.h	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,65 @@
+/*
+ * Marvell Wireless LAN device driver: 802.11n RX Re-ordering
+ *
+ * Copyright (C) 2011, Marvell International Ltd.
+ *
+ * This software file (the "File") is distributed by Marvell International
+ * Ltd. under the terms of the GNU General Public License Version 2, June 1991
+ * (the "License").  You may use, redistribute and/or modify this File in
+ * accordance with the terms and conditions of the License, a copy of which
+ * is available by writing to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
+ * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
+ *
+ * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
+ * ARE EXPRESSLY DISCLAIMED.  The License provides additional details about
+ * this warranty disclaimer.
+ */
+
+#ifndef _MWIFIEX_11N_RXREORDER_H_
+#define _MWIFIEX_11N_RXREORDER_H_
+
+#define MIN_FLUSH_TIMER_MS		50
+
+#define PKT_TYPE_BAR 0xE7
+#define MAX_TID_VALUE			(2 << 11)
+#define TWOPOW11			(2 << 10)
+
+#define BLOCKACKPARAM_TID_POS		2
+#define BLOCKACKPARAM_AMSDU_SUPP_MASK	0x1
+#define BLOCKACKPARAM_WINSIZE_POS	6
+#define DELBA_TID_POS			12
+#define DELBA_INITIATOR_POS		11
+#define TYPE_DELBA_SENT			1
+#define TYPE_DELBA_RECEIVE		2
+#define IMMEDIATE_BLOCK_ACK		0x2
+
+#define ADDBA_RSP_STATUS_ACCEPT 0
+
+int mwifiex_11n_rx_reorder_pkt(struct mwifiex_private *,
+			       u16 seqNum,
+			       u16 tid, u8 *ta,
+			       u8 pkttype, void *payload);
+void mwifiex_11n_delete_ba_stream_tbl(struct mwifiex_private *priv, int Tid,
+				     u8 *PeerMACAddr, u8 type,
+				     int initiator);
+void mwifiex_11n_ba_stream_timeout(struct mwifiex_private *priv,
+				   struct host_cmd_ds_11n_batimeout *event);
+int mwifiex_ret_11n_addba_resp(struct mwifiex_private *priv,
+			       struct host_cmd_ds_command
+			       *resp);
+int mwifiex_cmd_11n_delba(struct host_cmd_ds_command *cmd,
+			  void *data_buf);
+int mwifiex_cmd_11n_addba_rsp_gen(struct mwifiex_private *priv,
+				  struct host_cmd_ds_command
+				  *cmd, void *data_buf);
+int mwifiex_cmd_11n_addba_req(struct host_cmd_ds_command *cmd,
+			      void *data_buf);
+void mwifiex_11n_cleanup_reorder_tbl(struct mwifiex_private *priv);
+struct mwifiex_rx_reorder_tbl *mwifiex_11n_get_rxreorder_tbl(struct
+							   mwifiex_private
+							   *priv, int tid,
+							   u8 *ta);
+
+#endif /* _MWIFIEX_11N_RXREORDER_H_ */
diff -druN linux-2.6.39-libre/drivers/net/wireless/mwifiex/cfg80211.c linux-3.0-rc7-libre/drivers/net/wireless/mwifiex/cfg80211.c
--- linux-2.6.39-libre/drivers/net/wireless/mwifiex/cfg80211.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/net/wireless/mwifiex/cfg80211.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,1419 @@
+/*
+ * Marvell Wireless LAN device driver: CFG80211
+ *
+ * Copyright (C) 2011, Marvell International Ltd.
+ *
+ * This software file (the "File") is distributed by Marvell International
+ * Ltd. under the terms of the GNU General Public License Version 2, June 1991
+ * (the "License").  You may use, redistribute and/or modify this File in
+ * accordance with the terms and conditions of the License, a copy of which
+ * is available by writing to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
+ * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
+ *
+ * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
+ * ARE EXPRESSLY DISCLAIMED.  The License provides additional details about
+ * this warranty disclaimer.
+ */
+
+#include "cfg80211.h"
+#include "main.h"
+
+/*
+ * This function maps the nl802.11 channel type into driver channel type.
+ *
+ * The mapping is as follows -
+ *      NL80211_CHAN_NO_HT     -> NO_SEC_CHANNEL
+ *      NL80211_CHAN_HT20      -> NO_SEC_CHANNEL
+ *      NL80211_CHAN_HT40PLUS  -> SEC_CHANNEL_ABOVE
+ *      NL80211_CHAN_HT40MINUS -> SEC_CHANNEL_BELOW
+ *      Others                 -> NO_SEC_CHANNEL
+ */
+static int
+mwifiex_cfg80211_channel_type_to_mwifiex_channels(enum nl80211_channel_type
+						  channel_type)
+{
+	switch (channel_type) {
+	case NL80211_CHAN_NO_HT:
+	case NL80211_CHAN_HT20:
+		return NO_SEC_CHANNEL;
+	case NL80211_CHAN_HT40PLUS:
+		return SEC_CHANNEL_ABOVE;
+	case NL80211_CHAN_HT40MINUS:
+		return SEC_CHANNEL_BELOW;
+	default:
+		return NO_SEC_CHANNEL;
+	}
+}
+
+/*
+ * This function maps the driver channel type into nl802.11 channel type.
+ *
+ * The mapping is as follows -
+ *      NO_SEC_CHANNEL      -> NL80211_CHAN_HT20
+ *      SEC_CHANNEL_ABOVE   -> NL80211_CHAN_HT40PLUS
+ *      SEC_CHANNEL_BELOW   -> NL80211_CHAN_HT40MINUS
+ *      Others              -> NL80211_CHAN_HT20
+ */
+static enum nl80211_channel_type
+mwifiex_channels_to_cfg80211_channel_type(int channel_type)
+{
+	switch (channel_type) {
+	case NO_SEC_CHANNEL:
+		return NL80211_CHAN_HT20;
+	case SEC_CHANNEL_ABOVE:
+		return NL80211_CHAN_HT40PLUS;
+	case SEC_CHANNEL_BELOW:
+		return NL80211_CHAN_HT40MINUS;
+	default:
+		return NL80211_CHAN_HT20;
+	}
+}
+
+/*
+ * This function checks whether WEP is set.
+ */
+static int
+mwifiex_is_alg_wep(u32 cipher)
+{
+	switch (cipher) {
+	case WLAN_CIPHER_SUITE_WEP40:
+	case WLAN_CIPHER_SUITE_WEP104:
+		return 1;
+	default:
+		break;
+	}
+
+	return 0;
+}
+
+/*
+ * This function retrieves the private structure from kernel wiphy structure.
+ */
+static void *mwifiex_cfg80211_get_priv(struct wiphy *wiphy)
+{
+	return (void *) (*(unsigned long *) wiphy_priv(wiphy));
+}
+
+/*
+ * CFG802.11 operation handler to delete a network key.
+ */
+static int
+mwifiex_cfg80211_del_key(struct wiphy *wiphy, struct net_device *netdev,
+			 u8 key_index, bool pairwise, const u8 *mac_addr)
+{
+	struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy);
+
+	if (mwifiex_set_encode(priv, NULL, 0, key_index, 1)) {
+		wiphy_err(wiphy, "deleting the crypto keys\n");
+		return -EFAULT;
+	}
+
+	wiphy_dbg(wiphy, "info: crypto keys deleted\n");
+	return 0;
+}
+
+/*
+ * CFG802.11 operation handler to set Tx power.
+ */
+static int
+mwifiex_cfg80211_set_tx_power(struct wiphy *wiphy,
+			      enum nl80211_tx_power_setting type,
+			      int dbm)
+{
+	struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy);
+	struct mwifiex_power_cfg power_cfg;
+
+	if (type == NL80211_TX_POWER_FIXED) {
+		power_cfg.is_power_auto = 0;
+		power_cfg.power_level = dbm;
+	} else {
+		power_cfg.is_power_auto = 1;
+	}
+
+	return mwifiex_set_tx_power(priv, &power_cfg);
+}
+
+/*
+ * CFG802.11 operation handler to set Power Save option.
+ *
+ * The timeout value, if provided, is currently ignored.
+ */
+static int
+mwifiex_cfg80211_set_power_mgmt(struct wiphy *wiphy,
+				struct net_device *dev,
+				bool enabled, int timeout)
+{
+	struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy);
+	u32 ps_mode;
+
+	if (timeout)
+		wiphy_dbg(wiphy,
+			"info: ignoring the timeout value"
+			" for IEEE power save\n");
+
+	ps_mode = enabled;
+
+	return mwifiex_drv_set_power(priv, &ps_mode);
+}
+
+/*
+ * CFG802.11 operation handler to set the default network key.
+ */
+static int
+mwifiex_cfg80211_set_default_key(struct wiphy *wiphy, struct net_device *netdev,
+				 u8 key_index, bool unicast,
+				 bool multicast)
+{
+	struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy);
+
+	/* Return if WEP key not configured */
+	if (priv->sec_info.wep_status == MWIFIEX_802_11_WEP_DISABLED)
+		return 0;
+
+	if (mwifiex_set_encode(priv, NULL, 0, key_index, 0)) {
+		wiphy_err(wiphy, "set default Tx key index\n");
+		return -EFAULT;
+	}
+
+	return 0;
+}
+
+/*
+ * CFG802.11 operation handler to add a network key.
+ */
+static int
+mwifiex_cfg80211_add_key(struct wiphy *wiphy, struct net_device *netdev,
+			 u8 key_index, bool pairwise, const u8 *mac_addr,
+			 struct key_params *params)
+{
+	struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy);
+
+	if (mwifiex_set_encode(priv, params->key, params->key_len,
+							key_index, 0)) {
+		wiphy_err(wiphy, "crypto keys added\n");
+		return -EFAULT;
+	}
+
+	return 0;
+}
+
+/*
+ * This function sends domain information to the firmware.
+ *
+ * The following information are passed to the firmware -
+ *      - Country codes
+ *      - Sub bands (first channel, number of channels, maximum Tx power)
+ */
+static int mwifiex_send_domain_info_cmd_fw(struct wiphy *wiphy)
+{
+	u8 no_of_triplet = 0;
+	struct ieee80211_country_ie_triplet *t;
+	u8 no_of_parsed_chan = 0;
+	u8 first_chan = 0, next_chan = 0, max_pwr = 0;
+	u8 i, flag = 0;
+	enum ieee80211_band band;
+	struct ieee80211_supported_band *sband;
+	struct ieee80211_channel *ch;
+	struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy);
+	struct mwifiex_adapter *adapter = priv->adapter;
+	struct mwifiex_802_11d_domain_reg *domain_info = &adapter->domain_reg;
+
+	/* Set country code */
+	domain_info->country_code[0] = priv->country_code[0];
+	domain_info->country_code[1] = priv->country_code[1];
+	domain_info->country_code[2] = ' ';
+
+	band = mwifiex_band_to_radio_type(adapter->config_bands);
+	if (!wiphy->bands[band]) {
+		wiphy_err(wiphy, "11D: setting domain info in FW\n");
+		return -1;
+	}
+
+	sband = wiphy->bands[band];
+
+	for (i = 0; i < sband->n_channels ; i++) {
+		ch = &sband->channels[i];
+		if (ch->flags & IEEE80211_CHAN_DISABLED)
+			continue;
+
+		if (!flag) {
+			flag = 1;
+			first_chan = (u32) ch->hw_value;
+			next_chan = first_chan;
+			max_pwr = ch->max_power;
+			no_of_parsed_chan = 1;
+			continue;
+		}
+
+		if (ch->hw_value == next_chan + 1 &&
+				ch->max_power == max_pwr) {
+			next_chan++;
+			no_of_parsed_chan++;
+		} else {
+			t = &domain_info->triplet[no_of_triplet];
+			t->chans.first_channel = first_chan;
+			t->chans.num_channels = no_of_parsed_chan;
+			t->chans.max_power = max_pwr;
+			no_of_triplet++;
+			first_chan = (u32) ch->hw_value;
+			next_chan = first_chan;
+			max_pwr = ch->max_power;
+			no_of_parsed_chan = 1;
+		}
+	}
+
+	if (flag) {
+		t = &domain_info->triplet[no_of_triplet];
+		t->chans.first_channel = first_chan;
+		t->chans.num_channels = no_of_parsed_chan;
+		t->chans.max_power = max_pwr;
+		no_of_triplet++;
+	}
+
+	domain_info->no_of_triplet = no_of_triplet;
+
+	if (mwifiex_send_cmd_async(priv, HostCmd_CMD_802_11D_DOMAIN_INFO,
+				     HostCmd_ACT_GEN_SET, 0, NULL)) {
+		wiphy_err(wiphy, "11D: setting domain info in FW\n");
+		return -1;
+	}
+
+	return 0;
+}
+
+/*
+ * CFG802.11 regulatory domain callback function.
+ *
+ * This function is called when the regulatory domain is changed due to the
+ * following reasons -
+ *      - Set by driver
+ *      - Set by system core
+ *      - Set by user
+ *      - Set bt Country IE
+ */
+static int mwifiex_reg_notifier(struct wiphy *wiphy,
+		struct regulatory_request *request)
+{
+	struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy);
+
+	wiphy_dbg(wiphy, "info: cfg80211 regulatory domain callback for domain"
+			" %c%c\n", request->alpha2[0], request->alpha2[1]);
+
+	memcpy(priv->country_code, request->alpha2, sizeof(request->alpha2));
+
+	switch (request->initiator) {
+	case NL80211_REGDOM_SET_BY_DRIVER:
+	case NL80211_REGDOM_SET_BY_CORE:
+	case NL80211_REGDOM_SET_BY_USER:
+		break;
+		/* Todo: apply driver specific changes in channel flags based
+		   on the request initiator if necessary. */
+	case NL80211_REGDOM_SET_BY_COUNTRY_IE:
+		break;
+	}
+	mwifiex_send_domain_info_cmd_fw(wiphy);
+
+	return 0;
+}
+
+/*
+ * This function sets the RF channel.
+ *
+ * This function creates multiple IOCTL requests, populates them accordingly
+ * and issues them to set the band/channel and frequency.
+ */
+static int
+mwifiex_set_rf_channel(struct mwifiex_private *priv,
+		       struct ieee80211_channel *chan,
+		       enum nl80211_channel_type channel_type)
+{
+	struct mwifiex_chan_freq_power cfp;
+	struct mwifiex_ds_band_cfg band_cfg;
+	u32 config_bands = 0;
+	struct wiphy *wiphy = priv->wdev->wiphy;
+
+	if (chan) {
+		memset(&band_cfg, 0, sizeof(band_cfg));
+		/* Set appropriate bands */
+		if (chan->band == IEEE80211_BAND_2GHZ)
+			config_bands = BAND_B | BAND_G | BAND_GN;
+		else
+			config_bands = BAND_AN | BAND_A;
+		if (priv->bss_mode == NL80211_IFTYPE_STATION
+		    || priv->bss_mode == NL80211_IFTYPE_UNSPECIFIED) {
+			band_cfg.config_bands = config_bands;
+		} else if (priv->bss_mode == NL80211_IFTYPE_ADHOC) {
+			band_cfg.config_bands = config_bands;
+			band_cfg.adhoc_start_band = config_bands;
+		}
+
+		band_cfg.sec_chan_offset =
+			mwifiex_cfg80211_channel_type_to_mwifiex_channels
+			(channel_type);
+
+		if (mwifiex_set_radio_band_cfg(priv, &band_cfg))
+			return -EFAULT;
+
+		mwifiex_send_domain_info_cmd_fw(wiphy);
+	}
+
+	wiphy_dbg(wiphy, "info: setting band %d, channel offset %d and "
+		"mode %d\n", config_bands, band_cfg.sec_chan_offset,
+		priv->bss_mode);
+	if (!chan)
+		return 0;
+
+	memset(&cfp, 0, sizeof(cfp));
+	cfp.freq = chan->center_freq;
+	cfp.channel = ieee80211_frequency_to_channel(chan->center_freq);
+
+	if (mwifiex_bss_set_channel(priv, &cfp))
+		return -EFAULT;
+
+	return mwifiex_drv_change_adhoc_chan(priv, cfp.channel);
+}
+
+/*
+ * CFG802.11 operation handler to set channel.
+ *
+ * This function can only be used when station is not connected.
+ */
+static int
+mwifiex_cfg80211_set_channel(struct wiphy *wiphy, struct net_device *dev,
+			     struct ieee80211_channel *chan,
+			     enum nl80211_channel_type channel_type)
+{
+	struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy);
+
+	if (priv->media_connected) {
+		wiphy_err(wiphy, "This setting is valid only when station "
+				"is not connected\n");
+		return -EINVAL;
+	}
+
+	return mwifiex_set_rf_channel(priv, chan, channel_type);
+}
+
+/*
+ * This function sets the fragmentation threshold.
+ *
+ * The fragmentation threshold value must lie between MWIFIEX_FRAG_MIN_VALUE
+ * and MWIFIEX_FRAG_MAX_VALUE.
+ */
+static int
+mwifiex_set_frag(struct mwifiex_private *priv, u32 frag_thr)
+{
+	int ret;
+
+	if (frag_thr < MWIFIEX_FRAG_MIN_VALUE
+	    || frag_thr > MWIFIEX_FRAG_MAX_VALUE)
+		return -EINVAL;
+
+	/* Send request to firmware */
+	ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_SNMP_MIB,
+				    HostCmd_ACT_GEN_SET, FRAG_THRESH_I,
+				    &frag_thr);
+
+	return ret;
+}
+
+/*
+ * This function sets the RTS threshold.
+
+ * The rts value must lie between MWIFIEX_RTS_MIN_VALUE
+ * and MWIFIEX_RTS_MAX_VALUE.
+ */
+static int
+mwifiex_set_rts(struct mwifiex_private *priv, u32 rts_thr)
+{
+	if (rts_thr < MWIFIEX_RTS_MIN_VALUE || rts_thr > MWIFIEX_RTS_MAX_VALUE)
+		rts_thr = MWIFIEX_RTS_MAX_VALUE;
+
+	return mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_SNMP_MIB,
+				    HostCmd_ACT_GEN_SET, RTS_THRESH_I,
+				    &rts_thr);
+}
+
+/*
+ * CFG802.11 operation handler to set wiphy parameters.
+ *
+ * This function can be used to set the RTS threshold and the
+ * Fragmentation threshold of the driver.
+ */
+static int
+mwifiex_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
+{
+	struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy);
+	int ret = 0;
+
+	if (changed & WIPHY_PARAM_RTS_THRESHOLD) {
+		ret = mwifiex_set_rts(priv, wiphy->rts_threshold);
+		if (ret)
+			return ret;
+	}
+
+	if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
+		ret = mwifiex_set_frag(priv, wiphy->frag_threshold);
+
+	return ret;
+}
+
+/*
+ * CFG802.11 operation handler to change interface type.
+ */
+static int
+mwifiex_cfg80211_change_virtual_intf(struct wiphy *wiphy,
+				     struct net_device *dev,
+				     enum nl80211_iftype type, u32 *flags,
+				     struct vif_params *params)
+{
+	int ret;
+	struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
+
+	if (priv->bss_mode == type) {
+		wiphy_warn(wiphy, "already set to required type\n");
+		return 0;
+	}
+
+	priv->bss_mode = type;
+
+	switch (type) {
+	case NL80211_IFTYPE_ADHOC:
+		dev->ieee80211_ptr->iftype = NL80211_IFTYPE_ADHOC;
+		wiphy_dbg(wiphy, "info: setting interface type to adhoc\n");
+		break;
+	case NL80211_IFTYPE_STATION:
+		dev->ieee80211_ptr->iftype = NL80211_IFTYPE_STATION;
+		wiphy_dbg(wiphy, "info: setting interface type to managed\n");
+		break;
+	case NL80211_IFTYPE_UNSPECIFIED:
+		dev->ieee80211_ptr->iftype = NL80211_IFTYPE_STATION;
+		wiphy_dbg(wiphy, "info: setting interface type to auto\n");
+		return 0;
+	default:
+		wiphy_err(wiphy, "unknown interface type: %d\n", type);
+		return -EINVAL;
+	}
+
+	mwifiex_deauthenticate(priv, NULL);
+
+	priv->sec_info.authentication_mode = NL80211_AUTHTYPE_OPEN_SYSTEM;
+
+	ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_SET_BSS_MODE,
+				    HostCmd_ACT_GEN_SET, 0, NULL);
+
+	return ret;
+}
+
+/*
+ * This function dumps the station information on a buffer.
+ *
+ * The following information are shown -
+ *      - Total bytes transmitted
+ *      - Total bytes received
+ *      - Total packets transmitted
+ *      - Total packets received
+ *      - Signal quality level
+ *      - Transmission rate
+ */
+static int
+mwifiex_dump_station_info(struct mwifiex_private *priv,
+			  struct station_info *sinfo)
+{
+	struct mwifiex_ds_get_signal signal;
+	struct mwifiex_rate_cfg rate;
+	int ret = 0;
+
+	sinfo->filled = STATION_INFO_RX_BYTES | STATION_INFO_TX_BYTES |
+		STATION_INFO_RX_PACKETS |
+		STATION_INFO_TX_PACKETS
+		| STATION_INFO_SIGNAL | STATION_INFO_TX_BITRATE;
+
+	/* Get signal information from the firmware */
+	memset(&signal, 0, sizeof(struct mwifiex_ds_get_signal));
+	if (mwifiex_get_signal_info(priv, &signal)) {
+		dev_err(priv->adapter->dev, "getting signal information\n");
+		ret = -EFAULT;
+	}
+
+	if (mwifiex_drv_get_data_rate(priv, &rate)) {
+		dev_err(priv->adapter->dev, "getting data rate\n");
+		ret = -EFAULT;
+	}
+
+	sinfo->rx_bytes = priv->stats.rx_bytes;
+	sinfo->tx_bytes = priv->stats.tx_bytes;
+	sinfo->rx_packets = priv->stats.rx_packets;
+	sinfo->tx_packets = priv->stats.tx_packets;
+	sinfo->signal = priv->w_stats.qual.level;
+	sinfo->txrate.legacy = rate.rate;
+
+	return ret;
+}
+
+/*
+ * CFG802.11 operation handler to get station information.
+ *
+ * This function only works in connected mode, and dumps the
+ * requested station information, if available.
+ */
+static int
+mwifiex_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
+			     u8 *mac, struct station_info *sinfo)
+{
+	struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
+
+	mwifiex_dump_station_info(priv, sinfo);
+
+	if (!priv->media_connected)
+		return -ENOENT;
+	if (memcmp(mac, priv->cfg_bssid, ETH_ALEN))
+		return -ENOENT;
+
+	return mwifiex_dump_station_info(priv, sinfo);
+}
+
+/* Supported rates to be advertised to the cfg80211 */
+
+static struct ieee80211_rate mwifiex_rates[] = {
+	{.bitrate = 10, .hw_value = 2, },
+	{.bitrate = 20, .hw_value = 4, },
+	{.bitrate = 55, .hw_value = 11, },
+	{.bitrate = 110, .hw_value = 22, },
+	{.bitrate = 220, .hw_value = 44, },
+	{.bitrate = 60, .hw_value = 12, },
+	{.bitrate = 90, .hw_value = 18, },
+	{.bitrate = 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, },
+};
+
+/* Channel definitions to be advertised to cfg80211 */
+
+static struct ieee80211_channel mwifiex_channels_2ghz[] = {
+	{.center_freq = 2412, .hw_value = 1, },
+	{.center_freq = 2417, .hw_value = 2, },
+	{.center_freq = 2422, .hw_value = 3, },
+	{.center_freq = 2427, .hw_value = 4, },
+	{.center_freq = 2432, .hw_value = 5, },
+	{.center_freq = 2437, .hw_value = 6, },
+	{.center_freq = 2442, .hw_value = 7, },
+	{.center_freq = 2447, .hw_value = 8, },
+	{.center_freq = 2452, .hw_value = 9, },
+	{.center_freq = 2457, .hw_value = 10, },
+	{.center_freq = 2462, .hw_value = 11, },
+	{.center_freq = 2467, .hw_value = 12, },
+	{.center_freq = 2472, .hw_value = 13, },
+	{.center_freq = 2484, .hw_value = 14, },
+};
+
+static struct ieee80211_supported_band mwifiex_band_2ghz = {
+	.channels = mwifiex_channels_2ghz,
+	.n_channels = ARRAY_SIZE(mwifiex_channels_2ghz),
+	.bitrates = mwifiex_rates,
+	.n_bitrates = 14,
+};
+
+static struct ieee80211_channel mwifiex_channels_5ghz[] = {
+	{.center_freq = 5040, .hw_value = 8, },
+	{.center_freq = 5060, .hw_value = 12, },
+	{.center_freq = 5080, .hw_value = 16, },
+	{.center_freq = 5170, .hw_value = 34, },
+	{.center_freq = 5190, .hw_value = 38, },
+	{.center_freq = 5210, .hw_value = 42, },
+	{.center_freq = 5230, .hw_value = 46, },
+	{.center_freq = 5180, .hw_value = 36, },
+	{.center_freq = 5200, .hw_value = 40, },
+	{.center_freq = 5220, .hw_value = 44, },
+	{.center_freq = 5240, .hw_value = 48, },
+	{.center_freq = 5260, .hw_value = 52, },
+	{.center_freq = 5280, .hw_value = 56, },
+	{.center_freq = 5300, .hw_value = 60, },
+	{.center_freq = 5320, .hw_value = 64, },
+	{.center_freq = 5500, .hw_value = 100, },
+	{.center_freq = 5520, .hw_value = 104, },
+	{.center_freq = 5540, .hw_value = 108, },
+	{.center_freq = 5560, .hw_value = 112, },
+	{.center_freq = 5580, .hw_value = 116, },
+	{.center_freq = 5600, .hw_value = 120, },
+	{.center_freq = 5620, .hw_value = 124, },
+	{.center_freq = 5640, .hw_value = 128, },
+	{.center_freq = 5660, .hw_value = 132, },
+	{.center_freq = 5680, .hw_value = 136, },
+	{.center_freq = 5700, .hw_value = 140, },
+	{.center_freq = 5745, .hw_value = 149, },
+	{.center_freq = 5765, .hw_value = 153, },
+	{.center_freq = 5785, .hw_value = 157, },
+	{.center_freq = 5805, .hw_value = 161, },
+	{.center_freq = 5825, .hw_value = 165, },
+};
+
+static struct ieee80211_supported_band mwifiex_band_5ghz = {
+	.channels = mwifiex_channels_5ghz,
+	.n_channels = ARRAY_SIZE(mwifiex_channels_5ghz),
+	.bitrates = mwifiex_rates - 4,
+	.n_bitrates = ARRAY_SIZE(mwifiex_rates) + 4,
+};
+
+
+/* Supported crypto cipher suits to be advertised to cfg80211 */
+
+static const u32 mwifiex_cipher_suites[] = {
+	WLAN_CIPHER_SUITE_WEP40,
+	WLAN_CIPHER_SUITE_WEP104,
+	WLAN_CIPHER_SUITE_TKIP,
+	WLAN_CIPHER_SUITE_CCMP,
+};
+
+/*
+ * CFG802.11 operation handler for disconnection request.
+ *
+ * This function does not work when there is already a disconnection
+ * procedure going on.
+ */
+static int
+mwifiex_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *dev,
+			    u16 reason_code)
+{
+	struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
+
+	if (priv->disconnect)
+		return -EBUSY;
+
+	priv->disconnect = 1;
+	if (mwifiex_deauthenticate(priv, NULL))
+		return -EFAULT;
+
+	wiphy_dbg(wiphy, "info: successfully disconnected from %pM:"
+		" reason code %d\n", priv->cfg_bssid, reason_code);
+
+	queue_work(priv->workqueue, &priv->cfg_workqueue);
+
+	return 0;
+}
+
+/*
+ * This function informs the CFG802.11 subsystem of a new IBSS.
+ *
+ * The following information are sent to the CFG802.11 subsystem
+ * to register the new IBSS. If we do not register the new IBSS,
+ * a kernel panic will result.
+ *      - SSID
+ *      - SSID length
+ *      - BSSID
+ *      - Channel
+ */
+static int mwifiex_cfg80211_inform_ibss_bss(struct mwifiex_private *priv)
+{
+	struct ieee80211_channel *chan;
+	struct mwifiex_bss_info bss_info;
+	int ie_len;
+	u8 ie_buf[IEEE80211_MAX_SSID_LEN + sizeof(struct ieee_types_header)];
+
+	if (mwifiex_get_bss_info(priv, &bss_info))
+		return -1;
+
+	ie_buf[0] = WLAN_EID_SSID;
+	ie_buf[1] = bss_info.ssid.ssid_len;
+
+	memcpy(&ie_buf[sizeof(struct ieee_types_header)],
+			&bss_info.ssid.ssid,
+			bss_info.ssid.ssid_len);
+	ie_len = ie_buf[1] + sizeof(struct ieee_types_header);
+
+	chan = __ieee80211_get_channel(priv->wdev->wiphy,
+			ieee80211_channel_to_frequency(bss_info.bss_chan,
+						priv->curr_bss_params.band));
+
+	cfg80211_inform_bss(priv->wdev->wiphy, chan,
+		bss_info.bssid, 0, WLAN_CAPABILITY_IBSS,
+		0, ie_buf, ie_len, 0, GFP_KERNEL);
+	memcpy(priv->cfg_bssid, bss_info.bssid, ETH_ALEN);
+
+	return 0;
+}
+
+/*
+ * This function informs the CFG802.11 subsystem of a new BSS connection.
+ *
+ * The following information are sent to the CFG802.11 subsystem
+ * to register the new BSS connection. If we do not register the new BSS,
+ * a kernel panic will result.
+ *      - MAC address
+ *      - Capabilities
+ *      - Beacon period
+ *      - RSSI value
+ *      - Channel
+ *      - Supported rates IE
+ *      - Extended capabilities IE
+ *      - DS parameter set IE
+ *      - HT Capability IE
+ *      - Vendor Specific IE (221)
+ *      - WPA IE
+ *      - RSN IE
+ */
+static int mwifiex_inform_bss_from_scan_result(struct mwifiex_private *priv,
+					       struct mwifiex_802_11_ssid *ssid)
+{
+	struct mwifiex_bssdescriptor *scan_table;
+	int i, j;
+	struct ieee80211_channel *chan;
+	u8 *ie, *ie_buf;
+	u32 ie_len;
+	u8 *beacon;
+	int beacon_size;
+	u8 element_id, element_len;
+
+#define MAX_IE_BUF	2048
+	ie_buf = kzalloc(MAX_IE_BUF, GFP_KERNEL);
+	if (!ie_buf) {
+		dev_err(priv->adapter->dev, "%s: failed to alloc ie_buf\n",
+						__func__);
+		return -ENOMEM;
+	}
+
+	scan_table = priv->adapter->scan_table;
+	for (i = 0; i < priv->adapter->num_in_scan_table; i++) {
+		if (ssid) {
+			/* Inform specific BSS only */
+			if (memcmp(ssid->ssid, scan_table[i].ssid.ssid,
+					   ssid->ssid_len))
+				continue;
+		}
+		memset(ie_buf, 0, MAX_IE_BUF);
+		ie_buf[0] = WLAN_EID_SSID;
+		ie_buf[1] = scan_table[i].ssid.ssid_len;
+		memcpy(&ie_buf[sizeof(struct ieee_types_header)],
+		       scan_table[i].ssid.ssid, ie_buf[1]);
+
+		ie = ie_buf + ie_buf[1] + sizeof(struct ieee_types_header);
+		ie_len = ie_buf[1] + sizeof(struct ieee_types_header);
+
+		ie[0] = WLAN_EID_SUPP_RATES;
+
+		for (j = 0; j < sizeof(scan_table[i].supported_rates); j++) {
+			if (!scan_table[i].supported_rates[j])
+				break;
+			else
+				ie[j + sizeof(struct ieee_types_header)] =
+					scan_table[i].supported_rates[j];
+		}
+
+		ie[1] = j;
+		ie_len += ie[1] + sizeof(struct ieee_types_header);
+
+		beacon = scan_table[i].beacon_buf;
+		beacon_size = scan_table[i].beacon_buf_size;
+
+		/* Skip time stamp, beacon interval and capability */
+
+		if (beacon) {
+			beacon += sizeof(scan_table[i].beacon_period)
+				+ sizeof(scan_table[i].time_stamp) +
+				+sizeof(scan_table[i].cap_info_bitmap);
+
+			beacon_size -= sizeof(scan_table[i].beacon_period)
+				+ sizeof(scan_table[i].time_stamp)
+				+ sizeof(scan_table[i].cap_info_bitmap);
+		}
+
+		while (beacon_size >= sizeof(struct ieee_types_header)) {
+			ie = ie_buf + ie_len;
+			element_id = *beacon;
+			element_len = *(beacon + 1);
+			if (beacon_size < (int) element_len +
+			    sizeof(struct ieee_types_header)) {
+				dev_err(priv->adapter->dev, "%s: in processing"
+					" IE, bytes left < IE length\n",
+					__func__);
+				break;
+			}
+			switch (element_id) {
+			case WLAN_EID_EXT_CAPABILITY:
+			case WLAN_EID_DS_PARAMS:
+			case WLAN_EID_HT_CAPABILITY:
+			case WLAN_EID_VENDOR_SPECIFIC:
+			case WLAN_EID_RSN:
+			case WLAN_EID_BSS_AC_ACCESS_DELAY:
+				ie[0] = element_id;
+				ie[1] = element_len;
+				memcpy(&ie[sizeof(struct ieee_types_header)],
+				       (u8 *) beacon
+				       + sizeof(struct ieee_types_header),
+				       element_len);
+				ie_len += ie[1] +
+					sizeof(struct ieee_types_header);
+				break;
+			default:
+				break;
+			}
+			beacon += element_len +
+					sizeof(struct ieee_types_header);
+			beacon_size -= element_len +
+					sizeof(struct ieee_types_header);
+		}
+		chan = ieee80211_get_channel(priv->wdev->wiphy,
+						scan_table[i].freq);
+		cfg80211_inform_bss(priv->wdev->wiphy, chan,
+					scan_table[i].mac_address,
+					0, scan_table[i].cap_info_bitmap,
+					scan_table[i].beacon_period,
+					ie_buf, ie_len,
+					scan_table[i].rssi, GFP_KERNEL);
+	}
+
+	kfree(ie_buf);
+	return 0;
+}
+
+/*
+ * This function connects with a BSS.
+ *
+ * This function handles both Infra and Ad-Hoc modes. It also performs
+ * validity checking on the provided parameters, disconnects from the
+ * current BSS (if any), sets up the association/scan parameters,
+ * including security settings, and performs specific SSID scan before
+ * trying to connect.
+ *
+ * For Infra mode, the function returns failure if the specified SSID
+ * is not found in scan table. However, for Ad-Hoc mode, it can create
+ * the IBSS if it does not exist. On successful completion in either case,
+ * the function notifies the CFG802.11 subsystem of the new BSS connection,
+ * otherwise the kernel will panic.
+ */
+static int
+mwifiex_cfg80211_assoc(struct mwifiex_private *priv, size_t ssid_len, u8 *ssid,
+		       u8 *bssid, int mode, struct ieee80211_channel *channel,
+		       struct cfg80211_connect_params *sme, bool privacy)
+{
+	struct mwifiex_802_11_ssid req_ssid;
+	struct mwifiex_ssid_bssid ssid_bssid;
+	int ret, auth_type = 0;
+
+	memset(&req_ssid, 0, sizeof(struct mwifiex_802_11_ssid));
+	memset(&ssid_bssid, 0, sizeof(struct mwifiex_ssid_bssid));
+
+	req_ssid.ssid_len = ssid_len;
+	if (ssid_len > IEEE80211_MAX_SSID_LEN) {
+		dev_err(priv->adapter->dev, "invalid SSID - aborting\n");
+		return -EINVAL;
+	}
+
+	memcpy(req_ssid.ssid, ssid, ssid_len);
+	if (!req_ssid.ssid_len || req_ssid.ssid[0] < 0x20) {
+		dev_err(priv->adapter->dev, "invalid SSID - aborting\n");
+		return -EINVAL;
+	}
+
+	/* disconnect before try to associate */
+	mwifiex_deauthenticate(priv, NULL);
+
+	if (channel)
+		ret = mwifiex_set_rf_channel(priv, channel,
+				mwifiex_channels_to_cfg80211_channel_type
+				(priv->adapter->chan_offset));
+
+	ret = mwifiex_set_encode(priv, NULL, 0, 0, 1);	/* Disable keys */
+
+	if (mode == NL80211_IFTYPE_ADHOC) {
+		/* "privacy" is set only for ad-hoc mode */
+		if (privacy) {
+			/*
+			 * Keep WLAN_CIPHER_SUITE_WEP104 for now so that
+			 * the firmware can find a matching network from the
+			 * scan. The cfg80211 does not give us the encryption
+			 * mode at this stage so just setting it to WEP here.
+			 */
+			priv->sec_info.encryption_mode =
+					WLAN_CIPHER_SUITE_WEP104;
+			priv->sec_info.authentication_mode =
+					NL80211_AUTHTYPE_OPEN_SYSTEM;
+		}
+
+		goto done;
+	}
+
+	/* Now handle infra mode. "sme" is valid for infra mode only */
+	if (sme->auth_type == NL80211_AUTHTYPE_AUTOMATIC
+			|| sme->auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM)
+		auth_type = NL80211_AUTHTYPE_OPEN_SYSTEM;
+	else if (sme->auth_type == NL80211_AUTHTYPE_SHARED_KEY)
+		auth_type = NL80211_AUTHTYPE_SHARED_KEY;
+
+	if (sme->crypto.n_ciphers_pairwise) {
+		priv->sec_info.encryption_mode =
+						sme->crypto.ciphers_pairwise[0];
+		priv->sec_info.authentication_mode = auth_type;
+	}
+
+	if (sme->crypto.cipher_group) {
+		priv->sec_info.encryption_mode = sme->crypto.cipher_group;
+		priv->sec_info.authentication_mode = auth_type;
+	}
+	if (sme->ie)
+		ret = mwifiex_set_gen_ie(priv, sme->ie, sme->ie_len);
+
+	if (sme->key) {
+		if (mwifiex_is_alg_wep(0) | mwifiex_is_alg_wep(0)) {
+			dev_dbg(priv->adapter->dev,
+				"info: setting wep encryption"
+				" with key len %d\n", sme->key_len);
+			ret = mwifiex_set_encode(priv, sme->key, sme->key_len,
+							sme->key_idx, 0);
+		}
+	}
+done:
+	/* Do specific SSID scanning */
+	if (mwifiex_request_scan(priv, &req_ssid)) {
+		dev_err(priv->adapter->dev, "scan error\n");
+		return -EFAULT;
+	}
+
+
+	memcpy(&ssid_bssid.ssid, &req_ssid, sizeof(struct mwifiex_802_11_ssid));
+
+	if (mode != NL80211_IFTYPE_ADHOC) {
+		if (mwifiex_find_best_bss(priv, &ssid_bssid))
+			return -EFAULT;
+		/* Inform the BSS information to kernel, otherwise
+		 * kernel will give a panic after successful assoc */
+		if (mwifiex_inform_bss_from_scan_result(priv, &req_ssid))
+			return -EFAULT;
+	}
+
+	dev_dbg(priv->adapter->dev, "info: trying to associate to %s and bssid %pM\n",
+	       (char *) req_ssid.ssid, ssid_bssid.bssid);
+
+	memcpy(&priv->cfg_bssid, ssid_bssid.bssid, 6);
+
+	/* Connect to BSS by ESSID */
+	memset(&ssid_bssid.bssid, 0, ETH_ALEN);
+
+	if (!netif_queue_stopped(priv->netdev))
+		netif_stop_queue(priv->netdev);
+
+	if (mwifiex_bss_start(priv, &ssid_bssid))
+		return -EFAULT;
+
+	if (mode == NL80211_IFTYPE_ADHOC) {
+		/* Inform the BSS information to kernel, otherwise
+		 * kernel will give a panic after successful assoc */
+		if (mwifiex_cfg80211_inform_ibss_bss(priv))
+			return -EFAULT;
+	}
+
+	return ret;
+}
+
+/*
+ * CFG802.11 operation handler for association request.
+ *
+ * This function does not work when the current mode is set to Ad-Hoc, or
+ * when there is already an association procedure going on. The given BSS
+ * information is used to associate.
+ */
+static int
+mwifiex_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
+			 struct cfg80211_connect_params *sme)
+{
+	struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
+	int ret = 0;
+
+	if (priv->assoc_request)
+		return -EBUSY;
+
+	if (priv->bss_mode == NL80211_IFTYPE_ADHOC) {
+		wiphy_err(wiphy, "received infra assoc request "
+				"when station is in ibss mode\n");
+		goto done;
+	}
+
+	priv->assoc_request = -EINPROGRESS;
+
+	wiphy_dbg(wiphy, "info: Trying to associate to %s and bssid %pM\n",
+	       (char *) sme->ssid, sme->bssid);
+
+	ret = mwifiex_cfg80211_assoc(priv, sme->ssid_len, sme->ssid, sme->bssid,
+				     priv->bss_mode, sme->channel, sme, 0);
+
+	priv->assoc_request = 1;
+done:
+	priv->assoc_result = ret;
+	queue_work(priv->workqueue, &priv->cfg_workqueue);
+	return ret;
+}
+
+/*
+ * CFG802.11 operation handler to join an IBSS.
+ *
+ * This function does not work in any mode other than Ad-Hoc, or if
+ * a join operation is already in progress.
+ */
+static int
+mwifiex_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev,
+			   struct cfg80211_ibss_params *params)
+{
+	struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy);
+	int ret = 0;
+
+	if (priv->ibss_join_request)
+		return -EBUSY;
+
+	if (priv->bss_mode != NL80211_IFTYPE_ADHOC) {
+		wiphy_err(wiphy, "request to join ibss received "
+				"when station is not in ibss mode\n");
+		goto done;
+	}
+
+	priv->ibss_join_request = -EINPROGRESS;
+
+	wiphy_dbg(wiphy, "info: trying to join to %s and bssid %pM\n",
+	       (char *) params->ssid, params->bssid);
+
+	ret = mwifiex_cfg80211_assoc(priv, params->ssid_len, params->ssid,
+				params->bssid, priv->bss_mode,
+				params->channel, NULL, params->privacy);
+
+	priv->ibss_join_request = 1;
+done:
+	priv->ibss_join_result = ret;
+	queue_work(priv->workqueue, &priv->cfg_workqueue);
+	return ret;
+}
+
+/*
+ * CFG802.11 operation handler to leave an IBSS.
+ *
+ * This function does not work if a leave operation is
+ * already in progress.
+ */
+static int
+mwifiex_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *dev)
+{
+	struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy);
+
+	if (priv->disconnect)
+		return -EBUSY;
+
+	priv->disconnect = 1;
+
+	wiphy_dbg(wiphy, "info: disconnecting from essid %pM\n",
+			priv->cfg_bssid);
+	if (mwifiex_deauthenticate(priv, NULL))
+		return -EFAULT;
+
+	queue_work(priv->workqueue, &priv->cfg_workqueue);
+
+	return 0;
+}
+
+/*
+ * CFG802.11 operation handler for scan request.
+ *
+ * This function issues a scan request to the firmware based upon
+ * the user specified scan configuration. On successfull completion,
+ * it also informs the results.
+ */
+static int
+mwifiex_cfg80211_scan(struct wiphy *wiphy, struct net_device *dev,
+		      struct cfg80211_scan_request *request)
+{
+	struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
+
+	wiphy_dbg(wiphy, "info: received scan request on %s\n", dev->name);
+
+	if (priv->scan_request && priv->scan_request != request)
+		return -EBUSY;
+
+	priv->scan_request = request;
+
+	queue_work(priv->workqueue, &priv->cfg_workqueue);
+	return 0;
+}
+
+/*
+ * This function sets up the CFG802.11 specific HT capability fields
+ * with default values.
+ *
+ * The following default values are set -
+ *      - HT Supported = True
+ *      - Maximum AMPDU length factor = IEEE80211_HT_MAX_AMPDU_64K
+ *      - Minimum AMPDU spacing = IEEE80211_HT_MPDU_DENSITY_NONE
+ *      - HT Capabilities supported by firmware
+ *      - MCS information, Rx mask = 0xff
+ *      - MCD information, Tx parameters = IEEE80211_HT_MCS_TX_DEFINED (0x01)
+ */
+static void
+mwifiex_setup_ht_caps(struct ieee80211_sta_ht_cap *ht_info,
+		      struct mwifiex_private *priv)
+{
+	int rx_mcs_supp;
+	struct ieee80211_mcs_info mcs_set;
+	u8 *mcs = (u8 *)&mcs_set;
+	struct mwifiex_adapter *adapter = priv->adapter;
+
+	ht_info->ht_supported = true;
+	ht_info->ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K;
+	ht_info->ampdu_density = IEEE80211_HT_MPDU_DENSITY_NONE;
+
+	memset(&ht_info->mcs, 0, sizeof(ht_info->mcs));
+
+	/* Fill HT capability information */
+	if (ISSUPP_CHANWIDTH40(adapter->hw_dot_11n_dev_cap))
+		ht_info->cap |= IEEE80211_HT_CAP_SUP_WIDTH_20_40;
+	else
+		ht_info->cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
+
+	if (ISSUPP_SHORTGI20(adapter->hw_dot_11n_dev_cap))
+		ht_info->cap |= IEEE80211_HT_CAP_SGI_20;
+	else
+		ht_info->cap &= ~IEEE80211_HT_CAP_SGI_20;
+
+	if (ISSUPP_SHORTGI40(adapter->hw_dot_11n_dev_cap))
+		ht_info->cap |= IEEE80211_HT_CAP_SGI_40;
+	else
+		ht_info->cap &= ~IEEE80211_HT_CAP_SGI_40;
+
+	if (ISSUPP_RXSTBC(adapter->hw_dot_11n_dev_cap))
+		ht_info->cap |= 1 << IEEE80211_HT_CAP_RX_STBC_SHIFT;
+	else
+		ht_info->cap &= ~(3 << IEEE80211_HT_CAP_RX_STBC_SHIFT);
+
+	if (ISSUPP_TXSTBC(adapter->hw_dot_11n_dev_cap))
+		ht_info->cap |= IEEE80211_HT_CAP_TX_STBC;
+	else
+		ht_info->cap &= ~IEEE80211_HT_CAP_TX_STBC;
+
+	ht_info->cap &= ~IEEE80211_HT_CAP_MAX_AMSDU;
+	ht_info->cap |= IEEE80211_HT_CAP_SM_PS;
+
+	rx_mcs_supp = GET_RXMCSSUPP(adapter->hw_dev_mcs_support);
+	/* Set MCS for 1x1 */
+	memset(mcs, 0xff, rx_mcs_supp);
+	/* Clear all the other values */
+	memset(&mcs[rx_mcs_supp], 0,
+			sizeof(struct ieee80211_mcs_info) - rx_mcs_supp);
+	if (priv->bss_mode == NL80211_IFTYPE_STATION ||
+			ISSUPP_CHANWIDTH40(adapter->hw_dot_11n_dev_cap))
+		/* Set MCS32 for infra mode or ad-hoc mode with 40MHz support */
+		SETHT_MCS32(mcs_set.rx_mask);
+
+	memcpy((u8 *) &ht_info->mcs, mcs, sizeof(struct ieee80211_mcs_info));
+
+	ht_info->mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED;
+}
+
+/* station cfg80211 operations */
+static struct cfg80211_ops mwifiex_cfg80211_ops = {
+	.change_virtual_intf = mwifiex_cfg80211_change_virtual_intf,
+	.scan = mwifiex_cfg80211_scan,
+	.connect = mwifiex_cfg80211_connect,
+	.disconnect = mwifiex_cfg80211_disconnect,
+	.get_station = mwifiex_cfg80211_get_station,
+	.set_wiphy_params = mwifiex_cfg80211_set_wiphy_params,
+	.set_channel = mwifiex_cfg80211_set_channel,
+	.join_ibss = mwifiex_cfg80211_join_ibss,
+	.leave_ibss = mwifiex_cfg80211_leave_ibss,
+	.add_key = mwifiex_cfg80211_add_key,
+	.del_key = mwifiex_cfg80211_del_key,
+	.set_default_key = mwifiex_cfg80211_set_default_key,
+	.set_power_mgmt = mwifiex_cfg80211_set_power_mgmt,
+	.set_tx_power = mwifiex_cfg80211_set_tx_power,
+};
+
+/*
+ * This function registers the device with CFG802.11 subsystem.
+ *
+ * The function creates the wireless device/wiphy, populates it with
+ * default parameters and handler function pointers, and finally
+ * registers the device.
+ */
+int mwifiex_register_cfg80211(struct net_device *dev, u8 *mac,
+			      struct mwifiex_private *priv)
+{
+	int ret;
+	void *wdev_priv;
+	struct wireless_dev *wdev;
+
+	wdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL);
+	if (!wdev) {
+		dev_err(priv->adapter->dev, "%s: allocating wireless device\n",
+						__func__);
+		return -ENOMEM;
+	}
+	wdev->wiphy =
+		wiphy_new(&mwifiex_cfg80211_ops,
+			  sizeof(struct mwifiex_private *));
+	if (!wdev->wiphy) {
+		kfree(wdev);
+		return -ENOMEM;
+	}
+	wdev->iftype = NL80211_IFTYPE_STATION;
+	wdev->wiphy->max_scan_ssids = 10;
+	wdev->wiphy->interface_modes =
+		BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_ADHOC);
+
+	wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = &mwifiex_band_2ghz;
+	mwifiex_setup_ht_caps(
+		&wdev->wiphy->bands[IEEE80211_BAND_2GHZ]->ht_cap, priv);
+
+	if (priv->adapter->config_bands & BAND_A) {
+		wdev->wiphy->bands[IEEE80211_BAND_5GHZ] = &mwifiex_band_5ghz;
+		mwifiex_setup_ht_caps(
+			&wdev->wiphy->bands[IEEE80211_BAND_5GHZ]->ht_cap, priv);
+	} else {
+		wdev->wiphy->bands[IEEE80211_BAND_5GHZ] = NULL;
+	}
+
+	/* Initialize cipher suits */
+	wdev->wiphy->cipher_suites = mwifiex_cipher_suites;
+	wdev->wiphy->n_cipher_suites = ARRAY_SIZE(mwifiex_cipher_suites);
+
+	memcpy(wdev->wiphy->perm_addr, mac, 6);
+	wdev->wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
+
+	/* We are using custom domains */
+	wdev->wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY;
+
+	wdev->wiphy->reg_notifier = mwifiex_reg_notifier;
+
+	/* Set struct mwifiex_private pointer in wiphy_priv */
+	wdev_priv = wiphy_priv(wdev->wiphy);
+
+	*(unsigned long *) wdev_priv = (unsigned long) priv;
+
+	set_wiphy_dev(wdev->wiphy, (struct device *) priv->adapter->dev);
+
+	ret = wiphy_register(wdev->wiphy);
+	if (ret < 0) {
+		dev_err(priv->adapter->dev, "%s: registering cfg80211 device\n",
+						__func__);
+		wiphy_free(wdev->wiphy);
+		kfree(wdev);
+		return ret;
+	} else {
+		dev_dbg(priv->adapter->dev,
+				"info: successfully registered wiphy device\n");
+	}
+
+	dev_net_set(dev, wiphy_net(wdev->wiphy));
+	dev->ieee80211_ptr = wdev;
+	memcpy(dev->dev_addr, wdev->wiphy->perm_addr, 6);
+	memcpy(dev->perm_addr, wdev->wiphy->perm_addr, 6);
+	SET_NETDEV_DEV(dev, wiphy_dev(wdev->wiphy));
+	priv->wdev = wdev;
+
+	dev->flags |= IFF_BROADCAST | IFF_MULTICAST;
+	dev->watchdog_timeo = MWIFIEX_DEFAULT_WATCHDOG_TIMEOUT;
+	dev->hard_header_len += MWIFIEX_MIN_DATA_HEADER_LEN;
+
+	return ret;
+}
+
+/*
+ * This function handles the result of different pending network operations.
+ *
+ * The following operations are handled and CFG802.11 subsystem is
+ * notified accordingly -
+ *      - Scan request completion
+ *      - Association request completion
+ *      - IBSS join request completion
+ *      - Disconnect request completion
+ */
+void
+mwifiex_cfg80211_results(struct work_struct *work)
+{
+	struct mwifiex_private *priv =
+		container_of(work, struct mwifiex_private, cfg_workqueue);
+	struct mwifiex_user_scan_cfg *scan_req;
+	int ret = 0, i;
+	struct ieee80211_channel *chan;
+
+	if (priv->scan_request) {
+		scan_req = kzalloc(sizeof(struct mwifiex_user_scan_cfg),
+				   GFP_KERNEL);
+		if (!scan_req) {
+			dev_err(priv->adapter->dev, "failed to alloc "
+						    "scan_req\n");
+			return;
+		}
+		for (i = 0; i < priv->scan_request->n_ssids; i++) {
+			memcpy(scan_req->ssid_list[i].ssid,
+					priv->scan_request->ssids[i].ssid,
+					priv->scan_request->ssids[i].ssid_len);
+			scan_req->ssid_list[i].max_len =
+					priv->scan_request->ssids[i].ssid_len;
+		}
+		for (i = 0; i < priv->scan_request->n_channels; i++) {
+			chan = priv->scan_request->channels[i];
+			scan_req->chan_list[i].chan_number = chan->hw_value;
+			scan_req->chan_list[i].radio_type = chan->band;
+			if (chan->flags & IEEE80211_CHAN_DISABLED)
+				scan_req->chan_list[i].scan_type =
+					MWIFIEX_SCAN_TYPE_PASSIVE;
+			else
+				scan_req->chan_list[i].scan_type =
+					MWIFIEX_SCAN_TYPE_ACTIVE;
+			scan_req->chan_list[i].scan_time = 0;
+		}
+		if (mwifiex_set_user_scan_ioctl(priv, scan_req)) {
+			ret = -EFAULT;
+			goto done;
+		}
+		if (mwifiex_inform_bss_from_scan_result(priv, NULL))
+			ret = -EFAULT;
+done:
+		priv->scan_result_status = ret;
+		dev_dbg(priv->adapter->dev, "info: %s: sending scan results\n",
+							__func__);
+		cfg80211_scan_done(priv->scan_request,
+				(priv->scan_result_status < 0));
+		priv->scan_request = NULL;
+		kfree(scan_req);
+	}
+
+	if (priv->assoc_request == 1) {
+		if (!priv->assoc_result) {
+			cfg80211_connect_result(priv->netdev, priv->cfg_bssid,
+						NULL, 0, NULL, 0,
+						WLAN_STATUS_SUCCESS,
+						GFP_KERNEL);
+			dev_dbg(priv->adapter->dev,
+				"info: associated to bssid %pM successfully\n",
+			       priv->cfg_bssid);
+		} else {
+			dev_dbg(priv->adapter->dev,
+				"info: association to bssid %pM failed\n",
+			       priv->cfg_bssid);
+			memset(priv->cfg_bssid, 0, ETH_ALEN);
+		}
+		priv->assoc_request = 0;
+		priv->assoc_result = 0;
+	}
+
+	if (priv->ibss_join_request == 1) {
+		if (!priv->ibss_join_result) {
+			cfg80211_ibss_joined(priv->netdev, priv->cfg_bssid,
+					     GFP_KERNEL);
+			dev_dbg(priv->adapter->dev,
+				"info: joined/created adhoc network with bssid"
+					" %pM successfully\n", priv->cfg_bssid);
+		} else {
+			dev_dbg(priv->adapter->dev,
+				"info: failed creating/joining adhoc network\n");
+		}
+		priv->ibss_join_request = 0;
+		priv->ibss_join_result = 0;
+	}
+
+	if (priv->disconnect) {
+		memset(priv->cfg_bssid, 0, ETH_ALEN);
+		priv->disconnect = 0;
+	}
+}
diff -druN linux-2.6.39-libre/drivers/net/wireless/mwifiex/cfg80211.h linux-3.0-rc7-libre/drivers/net/wireless/mwifiex/cfg80211.h
--- linux-2.6.39-libre/drivers/net/wireless/mwifiex/cfg80211.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/net/wireless/mwifiex/cfg80211.h	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,31 @@
+/*
+ * Marvell Wireless LAN device driver: CFG80211
+ *
+ * Copyright (C) 2011, Marvell International Ltd.
+ *
+ * This software file (the "File") is distributed by Marvell International
+ * Ltd. under the terms of the GNU General Public License Version 2, June 1991
+ * (the "License").  You may use, redistribute and/or modify this File in
+ * accordance with the terms and conditions of the License, a copy of which
+ * is available by writing to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
+ * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
+ *
+ * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
+ * ARE EXPRESSLY DISCLAIMED.  The License provides additional details about
+ * this warranty disclaimer.
+ */
+
+#ifndef __MWIFIEX_CFG80211__
+#define __MWIFIEX_CFG80211__
+
+#include <net/cfg80211.h>
+
+#include "main.h"
+
+int mwifiex_register_cfg80211(struct net_device *, u8 *,
+				struct mwifiex_private *);
+
+void mwifiex_cfg80211_results(struct work_struct *work);
+#endif
diff -druN linux-2.6.39-libre/drivers/net/wireless/mwifiex/cfp.c linux-3.0-rc7-libre/drivers/net/wireless/mwifiex/cfp.c
--- linux-2.6.39-libre/drivers/net/wireless/mwifiex/cfp.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/net/wireless/mwifiex/cfp.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,360 @@
+/*
+ * Marvell Wireless LAN device driver: Channel, Frequence and Power
+ *
+ * Copyright (C) 2011, Marvell International Ltd.
+ *
+ * This software file (the "File") is distributed by Marvell International
+ * Ltd. under the terms of the GNU General Public License Version 2, June 1991
+ * (the "License").  You may use, redistribute and/or modify this File in
+ * accordance with the terms and conditions of the License, a copy of which
+ * is available by writing to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
+ * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
+ *
+ * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
+ * ARE EXPRESSLY DISCLAIMED.  The License provides additional details about
+ * this warranty disclaimer.
+ */
+
+#include "decl.h"
+#include "ioctl.h"
+#include "util.h"
+#include "fw.h"
+#include "main.h"
+#include "cfg80211.h"
+
+/* 100mW */
+#define MWIFIEX_TX_PWR_DEFAULT     20
+/* 100mW */
+#define MWIFIEX_TX_PWR_US_DEFAULT      20
+/* 50mW */
+#define MWIFIEX_TX_PWR_JP_DEFAULT      16
+/* 100mW */
+#define MWIFIEX_TX_PWR_FR_100MW        20
+/* 10mW */
+#define MWIFIEX_TX_PWR_FR_10MW         10
+/* 100mW */
+#define MWIFIEX_TX_PWR_EMEA_DEFAULT    20
+
+static u8 adhoc_rates_b[B_SUPPORTED_RATES] = { 0x82, 0x84, 0x8b, 0x96, 0 };
+
+static u8 adhoc_rates_g[G_SUPPORTED_RATES] = { 0x8c, 0x12, 0x98, 0x24,
+					       0xb0, 0x48, 0x60, 0x6c, 0 };
+
+static u8 adhoc_rates_bg[BG_SUPPORTED_RATES] = { 0x82, 0x84, 0x8b, 0x96,
+						 0x0c, 0x12, 0x18, 0x24,
+						 0x30, 0x48, 0x60, 0x6c, 0 };
+
+static u8 adhoc_rates_a[A_SUPPORTED_RATES] = { 0x8c, 0x12, 0x98, 0x24,
+					       0xb0, 0x48, 0x60, 0x6c, 0 };
+u8 supported_rates_a[A_SUPPORTED_RATES] = { 0x0c, 0x12, 0x18, 0x24,
+					0xb0, 0x48, 0x60, 0x6c, 0 };
+static u16 mwifiex_data_rates[MWIFIEX_SUPPORTED_RATES_EXT] = { 0x02, 0x04,
+					0x0B, 0x16, 0x00, 0x0C, 0x12, 0x18,
+					0x24, 0x30, 0x48, 0x60, 0x6C, 0x90,
+					0x0D, 0x1A, 0x27, 0x34, 0x4E, 0x68,
+					0x75, 0x82, 0x0C, 0x1B, 0x36, 0x51,
+					0x6C, 0xA2, 0xD8, 0xF3, 0x10E, 0x00 };
+
+u8 supported_rates_b[B_SUPPORTED_RATES] = { 0x02, 0x04, 0x0b, 0x16, 0 };
+
+u8 supported_rates_g[G_SUPPORTED_RATES] = { 0x0c, 0x12, 0x18, 0x24,
+					0x30, 0x48, 0x60, 0x6c, 0 };
+
+u8 supported_rates_bg[BG_SUPPORTED_RATES] = { 0x02, 0x04, 0x0b, 0x0c,
+					0x12, 0x16, 0x18, 0x24, 0x30, 0x48,
+					0x60, 0x6c, 0 };
+
+u16 region_code_index[MWIFIEX_MAX_REGION_CODE] = { 0x10, 0x20, 0x30,
+						0x32, 0x40, 0x41, 0xff };
+
+u8 supported_rates_n[N_SUPPORTED_RATES] = { 0x02, 0x04, 0 };
+
+/*
+ * This function maps an index in supported rates table into
+ * the corresponding data rate.
+ */
+u32 mwifiex_index_to_data_rate(u8 index, u8 ht_info)
+{
+	u16 mcs_rate[4][8] = {
+		{0x1b, 0x36, 0x51, 0x6c, 0xa2, 0xd8, 0xf3, 0x10e}
+	,			/* LG 40M */
+	{0x1e, 0x3c, 0x5a, 0x78, 0xb4, 0xf0, 0x10e, 0x12c}
+	,			/* SG 40M */
+	{0x0d, 0x1a, 0x27, 0x34, 0x4e, 0x68, 0x75, 0x82}
+	,			/* LG 20M */
+	{0x0e, 0x1c, 0x2b, 0x39, 0x56, 0x73, 0x82, 0x90}
+	};			/* SG 20M */
+
+	u32 rate;
+
+	if (ht_info & BIT(0)) {
+		if (index == MWIFIEX_RATE_BITMAP_MCS0) {
+			if (ht_info & BIT(2))
+				rate = 0x0D;	/* MCS 32 SGI rate */
+			else
+				rate = 0x0C;	/* MCS 32 LGI rate */
+		} else if (index < 8) {
+			if (ht_info & BIT(1)) {
+				if (ht_info & BIT(2))
+					/* SGI, 40M */
+					rate = mcs_rate[1][index];
+				else
+					/* LGI, 40M */
+					rate = mcs_rate[0][index];
+			} else {
+				if (ht_info & BIT(2))
+					/* SGI, 20M */
+					rate = mcs_rate[3][index];
+				else
+					/* LGI, 20M */
+					rate = mcs_rate[2][index];
+			}
+		} else
+			rate = mwifiex_data_rates[0];
+	} else {
+		if (index >= MWIFIEX_SUPPORTED_RATES_EXT)
+			index = 0;
+		rate = mwifiex_data_rates[index];
+	}
+	return rate;
+}
+
+/*
+ * This function maps a data rate value into corresponding index in supported
+ * rates table.
+ */
+u8 mwifiex_data_rate_to_index(u32 rate)
+{
+	u16 *ptr;
+
+	if (rate) {
+		ptr = memchr(mwifiex_data_rates, rate,
+				sizeof(mwifiex_data_rates));
+		if (ptr)
+			return (u8) (ptr - mwifiex_data_rates);
+	}
+	return 0;
+}
+
+/*
+ * This function returns the current active data rates.
+ *
+ * The result may vary depending upon connection status.
+ */
+u32 mwifiex_get_active_data_rates(struct mwifiex_private *priv, u8 *rates)
+{
+	if (!priv->media_connected)
+		return mwifiex_get_supported_rates(priv, rates);
+	else
+		return mwifiex_copy_rates(rates, 0,
+				       priv->curr_bss_params.data_rates,
+				       priv->curr_bss_params.num_of_rates);
+}
+
+/*
+ * This function locates the Channel-Frequency-Power triplet based upon
+ * band and channel parameters.
+ */
+struct mwifiex_chan_freq_power *
+mwifiex_get_cfp_by_band_and_channel_from_cfg80211(struct mwifiex_private
+						  *priv, u8 band, u16 channel)
+{
+	struct mwifiex_chan_freq_power *cfp = NULL;
+	struct ieee80211_supported_band *sband;
+	struct ieee80211_channel *ch;
+	int i;
+
+	if (mwifiex_band_to_radio_type(band) == HostCmd_SCAN_RADIO_TYPE_BG)
+		sband = priv->wdev->wiphy->bands[IEEE80211_BAND_2GHZ];
+	else
+		sband = priv->wdev->wiphy->bands[IEEE80211_BAND_5GHZ];
+
+	if (!sband) {
+		dev_err(priv->adapter->dev, "%s: cannot find cfp by band %d"
+				" & channel %d\n", __func__, band, channel);
+		return cfp;
+	}
+
+	for (i = 0; i < sband->n_channels; i++) {
+		ch = &sband->channels[i];
+		if (((ch->hw_value == channel) ||
+			(channel == FIRST_VALID_CHANNEL))
+			&& !(ch->flags & IEEE80211_CHAN_DISABLED)) {
+			priv->cfp.channel = channel;
+			priv->cfp.freq = ch->center_freq;
+			priv->cfp.max_tx_power = ch->max_power;
+			cfp = &priv->cfp;
+			break;
+		}
+	}
+	if (i == sband->n_channels)
+		dev_err(priv->adapter->dev, "%s: cannot find cfp by band %d"
+				" & channel %d\n", __func__, band, channel);
+
+	return cfp;
+}
+
+/*
+ * This function locates the Channel-Frequency-Power triplet based upon
+ * band and frequency parameters.
+ */
+struct mwifiex_chan_freq_power *
+mwifiex_get_cfp_by_band_and_freq_from_cfg80211(struct mwifiex_private *priv,
+					       u8 band, u32 freq)
+{
+	struct mwifiex_chan_freq_power *cfp = NULL;
+	struct ieee80211_supported_band *sband;
+	struct ieee80211_channel *ch;
+	int i;
+
+	if (mwifiex_band_to_radio_type(band) == HostCmd_SCAN_RADIO_TYPE_BG)
+		sband = priv->wdev->wiphy->bands[IEEE80211_BAND_2GHZ];
+	else
+		sband = priv->wdev->wiphy->bands[IEEE80211_BAND_5GHZ];
+
+	if (!sband) {
+		dev_err(priv->adapter->dev, "%s: cannot find cfp by band %d"
+				" & freq %d\n", __func__, band, freq);
+		return cfp;
+	}
+
+	for (i = 0; i < sband->n_channels; i++) {
+		ch = &sband->channels[i];
+		if ((ch->center_freq == freq) &&
+			!(ch->flags & IEEE80211_CHAN_DISABLED)) {
+			priv->cfp.channel = ch->hw_value;
+			priv->cfp.freq = freq;
+			priv->cfp.max_tx_power = ch->max_power;
+			cfp = &priv->cfp;
+			break;
+		}
+	}
+	if (i == sband->n_channels)
+		dev_err(priv->adapter->dev, "%s: cannot find cfp by band %d"
+				" & freq %d\n", __func__, band, freq);
+
+	return cfp;
+}
+
+/*
+ * This function checks if the data rate is set to auto.
+ */
+u8
+mwifiex_is_rate_auto(struct mwifiex_private *priv)
+{
+	u32 i;
+	int rate_num = 0;
+
+	for (i = 0; i < ARRAY_SIZE(priv->bitmap_rates); i++)
+		if (priv->bitmap_rates[i])
+			rate_num++;
+
+	if (rate_num > 1)
+		return true;
+	else
+		return false;
+}
+
+/*
+ * This function converts rate bitmap into rate index.
+ */
+int mwifiex_get_rate_index(u16 *rate_bitmap, int size)
+{
+	int i;
+
+	for (i = 0; i < size * 8; i++)
+		if (rate_bitmap[i / 16] & (1 << (i % 16)))
+			return i;
+
+	return 0;
+}
+
+/*
+ * This function gets the supported data rates.
+ *
+ * The function works in both Ad-Hoc and infra mode by printing the
+ * band and returning the data rates.
+ */
+u32 mwifiex_get_supported_rates(struct mwifiex_private *priv, u8 *rates)
+{
+	u32 k = 0;
+	struct mwifiex_adapter *adapter = priv->adapter;
+	if (priv->bss_mode == NL80211_IFTYPE_STATION) {
+		switch (adapter->config_bands) {
+		case BAND_B:
+			dev_dbg(adapter->dev, "info: infra band=%d "
+				"supported_rates_b\n", adapter->config_bands);
+			k = mwifiex_copy_rates(rates, k, supported_rates_b,
+					       sizeof(supported_rates_b));
+			break;
+		case BAND_G:
+		case BAND_G | BAND_GN:
+			dev_dbg(adapter->dev, "info: infra band=%d "
+				"supported_rates_g\n", adapter->config_bands);
+			k = mwifiex_copy_rates(rates, k, supported_rates_g,
+					       sizeof(supported_rates_g));
+			break;
+		case BAND_B | BAND_G:
+		case BAND_A | BAND_B | BAND_G:
+		case BAND_A | BAND_B:
+		case BAND_A | BAND_B | BAND_G | BAND_GN | BAND_AN:
+		case BAND_B | BAND_G | BAND_GN:
+			dev_dbg(adapter->dev, "info: infra band=%d "
+				"supported_rates_bg\n", adapter->config_bands);
+			k = mwifiex_copy_rates(rates, k, supported_rates_bg,
+					       sizeof(supported_rates_bg));
+			break;
+		case BAND_A:
+		case BAND_A | BAND_G:
+			dev_dbg(adapter->dev, "info: infra band=%d "
+				"supported_rates_a\n", adapter->config_bands);
+			k = mwifiex_copy_rates(rates, k, supported_rates_a,
+					       sizeof(supported_rates_a));
+			break;
+		case BAND_A | BAND_AN:
+		case BAND_A | BAND_G | BAND_AN | BAND_GN:
+			dev_dbg(adapter->dev, "info: infra band=%d "
+				"supported_rates_a\n", adapter->config_bands);
+			k = mwifiex_copy_rates(rates, k, supported_rates_a,
+					       sizeof(supported_rates_a));
+			break;
+		case BAND_GN:
+			dev_dbg(adapter->dev, "info: infra band=%d "
+				"supported_rates_n\n", adapter->config_bands);
+			k = mwifiex_copy_rates(rates, k, supported_rates_n,
+					       sizeof(supported_rates_n));
+			break;
+		}
+	} else {
+		/* Ad-hoc mode */
+		switch (adapter->adhoc_start_band) {
+		case BAND_B:
+			dev_dbg(adapter->dev, "info: adhoc B\n");
+			k = mwifiex_copy_rates(rates, k, adhoc_rates_b,
+					       sizeof(adhoc_rates_b));
+			break;
+		case BAND_G:
+		case BAND_G | BAND_GN:
+			dev_dbg(adapter->dev, "info: adhoc G only\n");
+			k = mwifiex_copy_rates(rates, k, adhoc_rates_g,
+					       sizeof(adhoc_rates_g));
+			break;
+		case BAND_B | BAND_G:
+		case BAND_B | BAND_G | BAND_GN:
+			dev_dbg(adapter->dev, "info: adhoc BG\n");
+			k = mwifiex_copy_rates(rates, k, adhoc_rates_bg,
+					       sizeof(adhoc_rates_bg));
+			break;
+		case BAND_A:
+		case BAND_A | BAND_AN:
+			dev_dbg(adapter->dev, "info: adhoc A\n");
+			k = mwifiex_copy_rates(rates, k, adhoc_rates_a,
+					       sizeof(adhoc_rates_a));
+			break;
+		}
+	}
+
+	return k;
+}
diff -druN linux-2.6.39-libre/drivers/net/wireless/mwifiex/cmdevt.c linux-3.0-rc7-libre/drivers/net/wireless/mwifiex/cmdevt.c
--- linux-2.6.39-libre/drivers/net/wireless/mwifiex/cmdevt.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/net/wireless/mwifiex/cmdevt.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,1414 @@
+/*
+ * Marvell Wireless LAN device driver: commands and events
+ *
+ * Copyright (C) 2011, Marvell International Ltd.
+ *
+ * This software file (the "File") is distributed by Marvell International
+ * Ltd. under the terms of the GNU General Public License Version 2, June 1991
+ * (the "License").  You may use, redistribute and/or modify this File in
+ * accordance with the terms and conditions of the License, a copy of which
+ * is available by writing to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
+ * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
+ *
+ * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
+ * ARE EXPRESSLY DISCLAIMED.  The License provides additional details about
+ * this warranty disclaimer.
+ */
+
+#include "decl.h"
+#include "ioctl.h"
+#include "util.h"
+#include "fw.h"
+#include "main.h"
+#include "wmm.h"
+#include "11n.h"
+
+/*
+ * This function initializes a command node.
+ *
+ * The actual allocation of the node is not done by this function. It only
+ * initiates a node by filling it with default parameters. Similarly,
+ * allocation of the different buffers used (IOCTL buffer, data buffer) are
+ * not done by this function either.
+ */
+static void
+mwifiex_init_cmd_node(struct mwifiex_private *priv,
+		      struct cmd_ctrl_node *cmd_node,
+		      u32 cmd_oid, void *data_buf)
+{
+	cmd_node->priv = priv;
+	cmd_node->cmd_oid = cmd_oid;
+	cmd_node->wait_q_enabled = priv->adapter->cmd_wait_q_required;
+	priv->adapter->cmd_wait_q_required = false;
+	cmd_node->data_buf = data_buf;
+	cmd_node->cmd_skb = cmd_node->skb;
+}
+
+/*
+ * This function returns a command node from the free queue depending upon
+ * availability.
+ */
+static struct cmd_ctrl_node *
+mwifiex_get_cmd_node(struct mwifiex_adapter *adapter)
+{
+	struct cmd_ctrl_node *cmd_node;
+	unsigned long flags;
+
+	spin_lock_irqsave(&adapter->cmd_free_q_lock, flags);
+	if (list_empty(&adapter->cmd_free_q)) {
+		dev_err(adapter->dev, "GET_CMD_NODE: cmd node not available\n");
+		spin_unlock_irqrestore(&adapter->cmd_free_q_lock, flags);
+		return NULL;
+	}
+	cmd_node = list_first_entry(&adapter->cmd_free_q,
+			struct cmd_ctrl_node, list);
+	list_del(&cmd_node->list);
+	spin_unlock_irqrestore(&adapter->cmd_free_q_lock, flags);
+
+	return cmd_node;
+}
+
+/*
+ * This function cleans up a command node.
+ *
+ * The function resets the fields including the buffer pointers.
+ * This function does not try to free the buffers. They must be
+ * freed before calling this function.
+ *
+ * This function will however call the receive completion callback
+ * in case a response buffer is still available before resetting
+ * the pointer.
+ */
+static void
+mwifiex_clean_cmd_node(struct mwifiex_adapter *adapter,
+		       struct cmd_ctrl_node *cmd_node)
+{
+	cmd_node->cmd_oid = 0;
+	cmd_node->cmd_flag = 0;
+	cmd_node->data_buf = NULL;
+	cmd_node->wait_q_enabled = false;
+
+	if (cmd_node->resp_skb) {
+		dev_kfree_skb_any(cmd_node->resp_skb);
+		cmd_node->resp_skb = NULL;
+	}
+}
+
+/*
+ * This function sends a host command to the firmware.
+ *
+ * The function copies the host command into the driver command
+ * buffer, which will be transferred to the firmware later by the
+ * main thread.
+ */
+static int mwifiex_cmd_host_cmd(struct mwifiex_private *priv,
+				struct host_cmd_ds_command *cmd, void *data_buf)
+{
+	struct mwifiex_ds_misc_cmd *pcmd_ptr =
+		(struct mwifiex_ds_misc_cmd *) data_buf;
+
+	/* Copy the HOST command to command buffer */
+	memcpy((void *) cmd, pcmd_ptr->cmd, pcmd_ptr->len);
+	dev_dbg(priv->adapter->dev, "cmd: host cmd size = %d\n", pcmd_ptr->len);
+	return 0;
+}
+
+/*
+ * This function downloads a command to the firmware.
+ *
+ * The function performs sanity tests, sets the command sequence
+ * number and size, converts the header fields to CPU format before
+ * sending. Afterwards, it logs the command ID and action for debugging
+ * and sets up the command timeout timer.
+ */
+static int mwifiex_dnld_cmd_to_fw(struct mwifiex_private *priv,
+				  struct cmd_ctrl_node *cmd_node)
+{
+
+	struct mwifiex_adapter *adapter = priv->adapter;
+	int ret;
+	struct host_cmd_ds_command *host_cmd;
+	uint16_t cmd_code;
+	uint16_t cmd_size;
+	struct timeval tstamp;
+	unsigned long flags;
+
+	if (!adapter || !cmd_node)
+		return -1;
+
+	host_cmd = (struct host_cmd_ds_command *) (cmd_node->cmd_skb->data);
+
+	/* Sanity test */
+	if (host_cmd == NULL || host_cmd->size == 0) {
+		dev_err(adapter->dev, "DNLD_CMD: host_cmd is null"
+			" or cmd size is 0, not sending\n");
+		if (cmd_node->wait_q_enabled)
+			adapter->cmd_wait_q.status = -1;
+		mwifiex_insert_cmd_to_free_q(adapter, cmd_node);
+		return -1;
+	}
+
+	/* Set command sequence number */
+	adapter->seq_num++;
+	host_cmd->seq_num = cpu_to_le16(HostCmd_SET_SEQ_NO_BSS_INFO
+			    (adapter->seq_num, cmd_node->priv->bss_num,
+			     cmd_node->priv->bss_type));
+
+	spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags);
+	adapter->curr_cmd = cmd_node;
+	spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags);
+
+	cmd_code = le16_to_cpu(host_cmd->command);
+	cmd_size = le16_to_cpu(host_cmd->size);
+
+	skb_trim(cmd_node->cmd_skb, cmd_size);
+
+	do_gettimeofday(&tstamp);
+	dev_dbg(adapter->dev, "cmd: DNLD_CMD: (%lu.%lu): %#x, act %#x, len %d,"
+		" seqno %#x\n",
+		tstamp.tv_sec, tstamp.tv_usec, cmd_code,
+	       le16_to_cpu(*(__le16 *) ((u8 *) host_cmd + S_DS_GEN)), cmd_size,
+	       le16_to_cpu(host_cmd->seq_num));
+
+	skb_push(cmd_node->cmd_skb, INTF_HEADER_LEN);
+
+	ret = adapter->if_ops.host_to_card(adapter, MWIFIEX_TYPE_CMD,
+					     cmd_node->cmd_skb->data,
+					     cmd_node->cmd_skb->len, NULL);
+
+	skb_pull(cmd_node->cmd_skb, INTF_HEADER_LEN);
+
+	if (ret == -1) {
+		dev_err(adapter->dev, "DNLD_CMD: host to card failed\n");
+		if (cmd_node->wait_q_enabled)
+			adapter->cmd_wait_q.status = -1;
+		mwifiex_insert_cmd_to_free_q(adapter, adapter->curr_cmd);
+
+		spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags);
+		adapter->curr_cmd = NULL;
+		spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags);
+
+		adapter->dbg.num_cmd_host_to_card_failure++;
+		return -1;
+	}
+
+	/* Save the last command id and action to debug log */
+	adapter->dbg.last_cmd_index =
+		(adapter->dbg.last_cmd_index + 1) % DBG_CMD_NUM;
+	adapter->dbg.last_cmd_id[adapter->dbg.last_cmd_index] = cmd_code;
+	adapter->dbg.last_cmd_act[adapter->dbg.last_cmd_index] =
+		le16_to_cpu(*(__le16 *) ((u8 *) host_cmd + S_DS_GEN));
+
+	/* Clear BSS_NO_BITS from HostCmd */
+	cmd_code &= HostCmd_CMD_ID_MASK;
+
+	/* Setup the timer after transmit command */
+	mod_timer(&adapter->cmd_timer,
+		jiffies + (MWIFIEX_TIMER_10S * HZ) / 1000);
+
+	return 0;
+}
+
+/*
+ * This function downloads a sleep confirm command to the firmware.
+ *
+ * The function performs sanity tests, sets the command sequence
+ * number and size, converts the header fields to CPU format before
+ * sending.
+ *
+ * No responses are needed for sleep confirm command.
+ */
+static int mwifiex_dnld_sleep_confirm_cmd(struct mwifiex_adapter *adapter)
+{
+	int ret;
+	struct mwifiex_private *priv;
+	struct mwifiex_opt_sleep_confirm *sleep_cfm_buf =
+				(struct mwifiex_opt_sleep_confirm *)
+				adapter->sleep_cfm->data;
+	priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY);
+
+	sleep_cfm_buf->seq_num =
+		cpu_to_le16((HostCmd_SET_SEQ_NO_BSS_INFO
+					(adapter->seq_num, priv->bss_num,
+					 priv->bss_type)));
+	adapter->seq_num++;
+
+	skb_push(adapter->sleep_cfm, INTF_HEADER_LEN);
+	ret = adapter->if_ops.host_to_card(adapter, MWIFIEX_TYPE_CMD,
+					     adapter->sleep_cfm->data,
+					     adapter->sleep_cfm->len, NULL);
+	skb_pull(adapter->sleep_cfm, INTF_HEADER_LEN);
+
+	if (ret == -1) {
+		dev_err(adapter->dev, "SLEEP_CFM: failed\n");
+		adapter->dbg.num_cmd_sleep_cfm_host_to_card_failure++;
+		return -1;
+	}
+	if (GET_BSS_ROLE(mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY))
+			== MWIFIEX_BSS_ROLE_STA) {
+		if (!sleep_cfm_buf->resp_ctrl)
+			/* Response is not needed for sleep
+			   confirm command */
+			adapter->ps_state = PS_STATE_SLEEP;
+		else
+			adapter->ps_state = PS_STATE_SLEEP_CFM;
+
+		if (!sleep_cfm_buf->resp_ctrl
+				&& (adapter->is_hs_configured
+					&& !adapter->sleep_period.period)) {
+			adapter->pm_wakeup_card_req = true;
+			mwifiex_hs_activated_event(mwifiex_get_priv(adapter,
+						MWIFIEX_BSS_ROLE_STA), true);
+		}
+	}
+
+	return ret;
+}
+
+/*
+ * This function allocates the command buffers and links them to
+ * the command free queue.
+ *
+ * The driver uses a pre allocated number of command buffers, which
+ * are created at driver initializations and freed at driver cleanup.
+ * Every command needs to obtain a command buffer from this pool before
+ * it can be issued. The command free queue lists the command buffers
+ * currently free to use, while the command pending queue lists the
+ * command buffers already in use and awaiting handling. Command buffers
+ * are returned to the free queue after use.
+ */
+int mwifiex_alloc_cmd_buffer(struct mwifiex_adapter *adapter)
+{
+	struct cmd_ctrl_node *cmd_array;
+	u32 buf_size;
+	u32 i;
+
+	/* Allocate and initialize struct cmd_ctrl_node */
+	buf_size = sizeof(struct cmd_ctrl_node) * MWIFIEX_NUM_OF_CMD_BUFFER;
+	cmd_array = kzalloc(buf_size, GFP_KERNEL);
+	if (!cmd_array) {
+		dev_err(adapter->dev, "%s: failed to alloc cmd_array\n",
+				__func__);
+		return -ENOMEM;
+	}
+
+	adapter->cmd_pool = cmd_array;
+	memset(adapter->cmd_pool, 0, buf_size);
+
+	/* Allocate and initialize command buffers */
+	for (i = 0; i < MWIFIEX_NUM_OF_CMD_BUFFER; i++) {
+		cmd_array[i].skb = dev_alloc_skb(MWIFIEX_SIZE_OF_CMD_BUFFER);
+		if (!cmd_array[i].skb) {
+			dev_err(adapter->dev, "ALLOC_CMD_BUF: out of memory\n");
+			return -1;
+		}
+	}
+
+	for (i = 0; i < MWIFIEX_NUM_OF_CMD_BUFFER; i++)
+		mwifiex_insert_cmd_to_free_q(adapter, &cmd_array[i]);
+
+	return 0;
+}
+
+/*
+ * This function frees the command buffers.
+ *
+ * The function calls the completion callback for all the command
+ * buffers that still have response buffers associated with them.
+ */
+int mwifiex_free_cmd_buffer(struct mwifiex_adapter *adapter)
+{
+	struct cmd_ctrl_node *cmd_array;
+	u32 i;
+
+	/* Need to check if cmd pool is allocated or not */
+	if (!adapter->cmd_pool) {
+		dev_dbg(adapter->dev, "info: FREE_CMD_BUF: cmd_pool is null\n");
+		return 0;
+	}
+
+	cmd_array = adapter->cmd_pool;
+
+	/* Release shared memory buffers */
+	for (i = 0; i < MWIFIEX_NUM_OF_CMD_BUFFER; i++) {
+		if (cmd_array[i].skb) {
+			dev_dbg(adapter->dev, "cmd: free cmd buffer %d\n", i);
+			dev_kfree_skb_any(cmd_array[i].skb);
+		}
+		if (!cmd_array[i].resp_skb)
+			continue;
+		dev_kfree_skb_any(cmd_array[i].resp_skb);
+	}
+	/* Release struct cmd_ctrl_node */
+	if (adapter->cmd_pool) {
+		dev_dbg(adapter->dev, "cmd: free cmd pool\n");
+		kfree(adapter->cmd_pool);
+		adapter->cmd_pool = NULL;
+	}
+
+	return 0;
+}
+
+/*
+ * This function handles events generated by firmware.
+ *
+ * Event body of events received from firmware are not used (though they are
+ * saved), only the event ID is used. Some events are re-invoked by
+ * the driver, with a new event body.
+ *
+ * After processing, the function calls the completion callback
+ * for cleanup.
+ */
+int mwifiex_process_event(struct mwifiex_adapter *adapter)
+{
+	int ret;
+	struct mwifiex_private *priv =
+		mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY);
+	struct sk_buff *skb = adapter->event_skb;
+	u32 eventcause = adapter->event_cause;
+	struct timeval tstamp;
+	struct mwifiex_rxinfo *rx_info;
+
+	/* Save the last event to debug log */
+	adapter->dbg.last_event_index =
+		(adapter->dbg.last_event_index + 1) % DBG_CMD_NUM;
+	adapter->dbg.last_event[adapter->dbg.last_event_index] =
+		(u16) eventcause;
+
+	/* Get BSS number and corresponding priv */
+	priv = mwifiex_get_priv_by_id(adapter, EVENT_GET_BSS_NUM(eventcause),
+				      EVENT_GET_BSS_TYPE(eventcause));
+	if (!priv)
+		priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY);
+	/* Clear BSS_NO_BITS from event */
+	eventcause &= EVENT_ID_MASK;
+	adapter->event_cause = eventcause;
+
+	if (skb) {
+		rx_info = MWIFIEX_SKB_RXCB(skb);
+		rx_info->bss_index = priv->bss_index;
+	}
+
+	if (eventcause != EVENT_PS_SLEEP && eventcause != EVENT_PS_AWAKE) {
+		do_gettimeofday(&tstamp);
+		dev_dbg(adapter->dev, "event: %lu.%lu: cause: %#x\n",
+		       tstamp.tv_sec, tstamp.tv_usec, eventcause);
+	}
+
+	ret = mwifiex_process_sta_event(priv);
+
+	adapter->event_cause = 0;
+	adapter->event_skb = NULL;
+
+	dev_kfree_skb_any(skb);
+
+	return ret;
+}
+
+/*
+ * This function is used to send synchronous command to the firmware.
+ *
+ * it allocates a wait queue for the command and wait for the command
+ * response.
+ */
+int mwifiex_send_cmd_sync(struct mwifiex_private *priv, uint16_t cmd_no,
+			  u16 cmd_action, u32 cmd_oid, void *data_buf)
+{
+	int ret = 0;
+	struct mwifiex_adapter *adapter = priv->adapter;
+
+	adapter->cmd_wait_q_required = true;
+	adapter->cmd_wait_q.condition = false;
+
+	ret = mwifiex_send_cmd_async(priv, cmd_no, cmd_action, cmd_oid,
+				     data_buf);
+	if (!ret)
+		ret = mwifiex_wait_queue_complete(adapter);
+
+	return ret;
+}
+
+
+/*
+ * This function prepares a command and asynchronously send it to the firmware.
+ *
+ * Preparation includes -
+ *      - Sanity tests to make sure the card is still present or the FW
+ *        is not reset
+ *      - Getting a new command node from the command free queue
+ *      - Initializing the command node for default parameters
+ *      - Fill up the non-default parameters and buffer pointers
+ *      - Add the command to pending queue
+ */
+int mwifiex_send_cmd_async(struct mwifiex_private *priv, uint16_t cmd_no,
+			   u16 cmd_action, u32 cmd_oid, void *data_buf)
+{
+	int ret;
+	struct mwifiex_adapter *adapter = priv->adapter;
+	struct cmd_ctrl_node *cmd_node;
+	struct host_cmd_ds_command *cmd_ptr;
+
+	if (!adapter) {
+		pr_err("PREP_CMD: adapter is NULL\n");
+		return -1;
+	}
+
+	if (adapter->is_suspended) {
+		dev_err(adapter->dev, "PREP_CMD: device in suspended state\n");
+		return -1;
+	}
+
+	if (adapter->surprise_removed) {
+		dev_err(adapter->dev, "PREP_CMD: card is removed\n");
+		return -1;
+	}
+
+	if (adapter->hw_status == MWIFIEX_HW_STATUS_RESET) {
+		if (cmd_no != HostCmd_CMD_FUNC_INIT) {
+			dev_err(adapter->dev, "PREP_CMD: FW in reset state\n");
+			return -1;
+		}
+	}
+
+	/* Get a new command node */
+	cmd_node = mwifiex_get_cmd_node(adapter);
+
+	if (!cmd_node) {
+		dev_err(adapter->dev, "PREP_CMD: no free cmd node\n");
+		return -1;
+	}
+
+	/* Initialize the command node */
+	mwifiex_init_cmd_node(priv, cmd_node, cmd_oid, data_buf);
+
+	if (!cmd_node->cmd_skb) {
+		dev_err(adapter->dev, "PREP_CMD: no free cmd buf\n");
+		return -1;
+	}
+
+	memset(skb_put(cmd_node->cmd_skb, sizeof(struct host_cmd_ds_command)),
+	       0, sizeof(struct host_cmd_ds_command));
+
+	cmd_ptr = (struct host_cmd_ds_command *) (cmd_node->cmd_skb->data);
+	cmd_ptr->command = cpu_to_le16(cmd_no);
+	cmd_ptr->result = 0;
+
+	/* Prepare command */
+	if (cmd_no) {
+		ret = mwifiex_sta_prepare_cmd(priv, cmd_no, cmd_action,
+					      cmd_oid, data_buf, cmd_ptr);
+	} else {
+		ret = mwifiex_cmd_host_cmd(priv, cmd_ptr, data_buf);
+		cmd_node->cmd_flag |= CMD_F_HOSTCMD;
+	}
+
+	/* Return error, since the command preparation failed */
+	if (ret) {
+		dev_err(adapter->dev, "PREP_CMD: cmd %#x preparation failed\n",
+							cmd_no);
+		mwifiex_insert_cmd_to_free_q(adapter, cmd_node);
+		return -1;
+	}
+
+	/* Send command */
+	if (cmd_no == HostCmd_CMD_802_11_SCAN)
+		mwifiex_queue_scan_cmd(priv, cmd_node);
+	else
+		mwifiex_insert_cmd_to_pending_q(adapter, cmd_node, true);
+
+	return ret;
+}
+
+/*
+ * This function returns a command to the command free queue.
+ *
+ * The function also calls the completion callback if required, before
+ * cleaning the command node and re-inserting it into the free queue.
+ */
+void
+mwifiex_insert_cmd_to_free_q(struct mwifiex_adapter *adapter,
+			     struct cmd_ctrl_node *cmd_node)
+{
+	unsigned long flags;
+
+	if (!cmd_node)
+		return;
+
+	if (cmd_node->wait_q_enabled)
+		mwifiex_complete_cmd(adapter);
+	/* Clean the node */
+	mwifiex_clean_cmd_node(adapter, cmd_node);
+
+	/* Insert node into cmd_free_q */
+	spin_lock_irqsave(&adapter->cmd_free_q_lock, flags);
+	list_add_tail(&cmd_node->list, &adapter->cmd_free_q);
+	spin_unlock_irqrestore(&adapter->cmd_free_q_lock, flags);
+}
+
+/*
+ * This function queues a command to the command pending queue.
+ *
+ * This in effect adds the command to the command list to be executed.
+ * Exit PS command is handled specially, by placing it always to the
+ * front of the command queue.
+ */
+void
+mwifiex_insert_cmd_to_pending_q(struct mwifiex_adapter *adapter,
+				struct cmd_ctrl_node *cmd_node, u32 add_tail)
+{
+	struct host_cmd_ds_command *host_cmd = NULL;
+	u16 command;
+	unsigned long flags;
+
+	host_cmd = (struct host_cmd_ds_command *) (cmd_node->cmd_skb->data);
+	if (!host_cmd) {
+		dev_err(adapter->dev, "QUEUE_CMD: host_cmd is NULL\n");
+		return;
+	}
+
+	command = le16_to_cpu(host_cmd->command);
+
+	/* Exit_PS command needs to be queued in the header always. */
+	if (command == HostCmd_CMD_802_11_PS_MODE_ENH) {
+		struct host_cmd_ds_802_11_ps_mode_enh *pm =
+			&host_cmd->params.psmode_enh;
+		if ((le16_to_cpu(pm->action) == DIS_PS)
+		    || (le16_to_cpu(pm->action) == DIS_AUTO_PS)) {
+			if (adapter->ps_state != PS_STATE_AWAKE)
+				add_tail = false;
+		}
+	}
+
+	spin_lock_irqsave(&adapter->cmd_pending_q_lock, flags);
+	if (add_tail)
+		list_add_tail(&cmd_node->list, &adapter->cmd_pending_q);
+	else
+		list_add(&cmd_node->list, &adapter->cmd_pending_q);
+	spin_unlock_irqrestore(&adapter->cmd_pending_q_lock, flags);
+
+	dev_dbg(adapter->dev, "cmd: QUEUE_CMD: cmd=%#x is queued\n", command);
+}
+
+/*
+ * This function executes the next command in command pending queue.
+ *
+ * This function will fail if a command is already in processing stage,
+ * otherwise it will dequeue the first command from the command pending
+ * queue and send to the firmware.
+ *
+ * If the device is currently in host sleep mode, any commands, except the
+ * host sleep configuration command will de-activate the host sleep. For PS
+ * mode, the function will put the firmware back to sleep if applicable.
+ */
+int mwifiex_exec_next_cmd(struct mwifiex_adapter *adapter)
+{
+	struct mwifiex_private *priv;
+	struct cmd_ctrl_node *cmd_node;
+	int ret = 0;
+	struct host_cmd_ds_command *host_cmd;
+	unsigned long cmd_flags;
+	unsigned long cmd_pending_q_flags;
+
+	/* Check if already in processing */
+	if (adapter->curr_cmd) {
+		dev_err(adapter->dev, "EXEC_NEXT_CMD: cmd in processing\n");
+		return -1;
+	}
+
+	spin_lock_irqsave(&adapter->mwifiex_cmd_lock, cmd_flags);
+	/* Check if any command is pending */
+	spin_lock_irqsave(&adapter->cmd_pending_q_lock, cmd_pending_q_flags);
+	if (list_empty(&adapter->cmd_pending_q)) {
+		spin_unlock_irqrestore(&adapter->cmd_pending_q_lock,
+				       cmd_pending_q_flags);
+		spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, cmd_flags);
+		return 0;
+	}
+	cmd_node = list_first_entry(&adapter->cmd_pending_q,
+				    struct cmd_ctrl_node, list);
+	spin_unlock_irqrestore(&adapter->cmd_pending_q_lock,
+			       cmd_pending_q_flags);
+
+	host_cmd = (struct host_cmd_ds_command *) (cmd_node->cmd_skb->data);
+	priv = cmd_node->priv;
+
+	if (adapter->ps_state != PS_STATE_AWAKE) {
+		dev_err(adapter->dev, "%s: cannot send cmd in sleep state,"
+				" this should not happen\n", __func__);
+		spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, cmd_flags);
+		return ret;
+	}
+
+	spin_lock_irqsave(&adapter->cmd_pending_q_lock, cmd_pending_q_flags);
+	list_del(&cmd_node->list);
+	spin_unlock_irqrestore(&adapter->cmd_pending_q_lock,
+			       cmd_pending_q_flags);
+
+	spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, cmd_flags);
+	ret = mwifiex_dnld_cmd_to_fw(priv, cmd_node);
+	priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY);
+	/* Any command sent to the firmware when host is in sleep
+	 * mode should de-configure host sleep. We should skip the
+	 * host sleep configuration command itself though
+	 */
+	if (priv && (host_cmd->command !=
+	     cpu_to_le16(HostCmd_CMD_802_11_HS_CFG_ENH))) {
+		if (adapter->hs_activated) {
+			adapter->is_hs_configured = false;
+			mwifiex_hs_activated_event(priv, false);
+		}
+	}
+
+	return ret;
+}
+
+/*
+ * This function handles the command response.
+ *
+ * After processing, the function cleans the command node and puts
+ * it back to the command free queue.
+ */
+int mwifiex_process_cmdresp(struct mwifiex_adapter *adapter)
+{
+	struct host_cmd_ds_command *resp;
+	struct mwifiex_private *priv =
+		mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY);
+	int ret = 0;
+	uint16_t orig_cmdresp_no;
+	uint16_t cmdresp_no;
+	uint16_t cmdresp_result;
+	struct timeval tstamp;
+	unsigned long flags;
+
+	/* Now we got response from FW, cancel the command timer */
+	del_timer(&adapter->cmd_timer);
+
+	if (!adapter->curr_cmd || !adapter->curr_cmd->resp_skb) {
+		resp = (struct host_cmd_ds_command *) adapter->upld_buf;
+		dev_err(adapter->dev, "CMD_RESP: NULL curr_cmd, %#x\n",
+		       le16_to_cpu(resp->command));
+		return -1;
+	}
+
+	adapter->num_cmd_timeout = 0;
+
+	resp = (struct host_cmd_ds_command *) adapter->curr_cmd->resp_skb->data;
+	if (adapter->curr_cmd->cmd_flag & CMD_F_CANCELED) {
+		dev_err(adapter->dev, "CMD_RESP: %#x been canceled\n",
+				le16_to_cpu(resp->command));
+		mwifiex_insert_cmd_to_free_q(adapter, adapter->curr_cmd);
+		spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags);
+		adapter->curr_cmd = NULL;
+		spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags);
+		return -1;
+	}
+
+	if (adapter->curr_cmd->cmd_flag & CMD_F_HOSTCMD) {
+		/* Copy original response back to response buffer */
+		struct mwifiex_ds_misc_cmd *hostcmd = NULL;
+		uint16_t size = le16_to_cpu(resp->size);
+		dev_dbg(adapter->dev, "info: host cmd resp size = %d\n", size);
+		size = min_t(u16, size, MWIFIEX_SIZE_OF_CMD_BUFFER);
+		if (adapter->curr_cmd->data_buf) {
+			hostcmd = (struct mwifiex_ds_misc_cmd *)
+						adapter->curr_cmd->data_buf;
+			hostcmd->len = size;
+			memcpy(hostcmd->cmd, (void *) resp, size);
+		}
+	}
+	orig_cmdresp_no = le16_to_cpu(resp->command);
+
+	/* Get BSS number and corresponding priv */
+	priv = mwifiex_get_priv_by_id(adapter,
+			HostCmd_GET_BSS_NO(le16_to_cpu(resp->seq_num)),
+			HostCmd_GET_BSS_TYPE(le16_to_cpu(resp->seq_num)));
+	if (!priv)
+		priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY);
+	/* Clear RET_BIT from HostCmd */
+	resp->command = cpu_to_le16(orig_cmdresp_no & HostCmd_CMD_ID_MASK);
+
+	cmdresp_no = le16_to_cpu(resp->command);
+	cmdresp_result = le16_to_cpu(resp->result);
+
+	/* Save the last command response to debug log */
+	adapter->dbg.last_cmd_resp_index =
+		(adapter->dbg.last_cmd_resp_index + 1) % DBG_CMD_NUM;
+	adapter->dbg.last_cmd_resp_id[adapter->dbg.last_cmd_resp_index] =
+		orig_cmdresp_no;
+
+	do_gettimeofday(&tstamp);
+	dev_dbg(adapter->dev, "cmd: CMD_RESP: (%lu.%lu): 0x%x, result %d,"
+		" len %d, seqno 0x%x\n",
+	       tstamp.tv_sec, tstamp.tv_usec, orig_cmdresp_no, cmdresp_result,
+	       le16_to_cpu(resp->size), le16_to_cpu(resp->seq_num));
+
+	if (!(orig_cmdresp_no & HostCmd_RET_BIT)) {
+		dev_err(adapter->dev, "CMD_RESP: invalid cmd resp\n");
+		if (adapter->curr_cmd->wait_q_enabled)
+			adapter->cmd_wait_q.status = -1;
+
+		mwifiex_insert_cmd_to_free_q(adapter, adapter->curr_cmd);
+		spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags);
+		adapter->curr_cmd = NULL;
+		spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags);
+		return -1;
+	}
+
+	if (adapter->curr_cmd->cmd_flag & CMD_F_HOSTCMD) {
+		adapter->curr_cmd->cmd_flag &= ~CMD_F_HOSTCMD;
+		if ((cmdresp_result == HostCmd_RESULT_OK)
+		    && (cmdresp_no == HostCmd_CMD_802_11_HS_CFG_ENH))
+			ret = mwifiex_ret_802_11_hs_cfg(priv, resp);
+	} else {
+		/* handle response */
+		ret = mwifiex_process_sta_cmdresp(priv, cmdresp_no, resp);
+	}
+
+	/* Check init command response */
+	if (adapter->hw_status == MWIFIEX_HW_STATUS_INITIALIZING) {
+		if (ret == -1) {
+			dev_err(adapter->dev, "%s: cmd %#x failed during "
+				"initialization\n", __func__, cmdresp_no);
+			mwifiex_init_fw_complete(adapter);
+			return -1;
+		} else if (adapter->last_init_cmd == cmdresp_no)
+			adapter->hw_status = MWIFIEX_HW_STATUS_INIT_DONE;
+	}
+
+	if (adapter->curr_cmd) {
+		if (adapter->curr_cmd->wait_q_enabled && (!ret))
+			adapter->cmd_wait_q.status = 0;
+		else if (adapter->curr_cmd->wait_q_enabled && (ret == -1))
+			adapter->cmd_wait_q.status = -1;
+
+		/* Clean up and put current command back to cmd_free_q */
+		mwifiex_insert_cmd_to_free_q(adapter, adapter->curr_cmd);
+
+		spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags);
+		adapter->curr_cmd = NULL;
+		spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags);
+	}
+
+	return ret;
+}
+
+/*
+ * This function handles the timeout of command sending.
+ *
+ * It will re-send the same command again.
+ */
+void
+mwifiex_cmd_timeout_func(unsigned long function_context)
+{
+	struct mwifiex_adapter *adapter =
+		(struct mwifiex_adapter *) function_context;
+	struct cmd_ctrl_node *cmd_node;
+	struct timeval tstamp;
+
+	adapter->num_cmd_timeout++;
+	adapter->dbg.num_cmd_timeout++;
+	if (!adapter->curr_cmd) {
+		dev_dbg(adapter->dev, "cmd: empty curr_cmd\n");
+		return;
+	}
+	cmd_node = adapter->curr_cmd;
+	if (cmd_node->wait_q_enabled)
+		adapter->cmd_wait_q.status = -ETIMEDOUT;
+
+	if (cmd_node) {
+		adapter->dbg.timeout_cmd_id =
+			adapter->dbg.last_cmd_id[adapter->dbg.last_cmd_index];
+		adapter->dbg.timeout_cmd_act =
+			adapter->dbg.last_cmd_act[adapter->dbg.last_cmd_index];
+		do_gettimeofday(&tstamp);
+		dev_err(adapter->dev, "%s: Timeout cmd id (%lu.%lu) = %#x,"
+			" act = %#x\n", __func__,
+		       tstamp.tv_sec, tstamp.tv_usec,
+		       adapter->dbg.timeout_cmd_id,
+		       adapter->dbg.timeout_cmd_act);
+
+		dev_err(adapter->dev, "num_data_h2c_failure = %d\n",
+		       adapter->dbg.num_tx_host_to_card_failure);
+		dev_err(adapter->dev, "num_cmd_h2c_failure = %d\n",
+		       adapter->dbg.num_cmd_host_to_card_failure);
+
+		dev_err(adapter->dev, "num_cmd_timeout = %d\n",
+		       adapter->dbg.num_cmd_timeout);
+		dev_err(adapter->dev, "num_tx_timeout = %d\n",
+		       adapter->dbg.num_tx_timeout);
+
+		dev_err(adapter->dev, "last_cmd_index = %d\n",
+		       adapter->dbg.last_cmd_index);
+		print_hex_dump_bytes("last_cmd_id: ", DUMP_PREFIX_OFFSET,
+				adapter->dbg.last_cmd_id, DBG_CMD_NUM);
+		print_hex_dump_bytes("last_cmd_act: ", DUMP_PREFIX_OFFSET,
+				adapter->dbg.last_cmd_act, DBG_CMD_NUM);
+
+		dev_err(adapter->dev, "last_cmd_resp_index = %d\n",
+		       adapter->dbg.last_cmd_resp_index);
+		print_hex_dump_bytes("last_cmd_resp_id: ", DUMP_PREFIX_OFFSET,
+				adapter->dbg.last_cmd_resp_id, DBG_CMD_NUM);
+
+		dev_err(adapter->dev, "last_event_index = %d\n",
+		       adapter->dbg.last_event_index);
+		print_hex_dump_bytes("last_event: ", DUMP_PREFIX_OFFSET,
+				adapter->dbg.last_event, DBG_CMD_NUM);
+
+		dev_err(adapter->dev, "data_sent=%d cmd_sent=%d\n",
+		       adapter->data_sent, adapter->cmd_sent);
+
+		dev_err(adapter->dev, "ps_mode=%d ps_state=%d\n",
+				adapter->ps_mode, adapter->ps_state);
+	}
+	if (adapter->hw_status == MWIFIEX_HW_STATUS_INITIALIZING)
+		mwifiex_init_fw_complete(adapter);
+}
+
+/*
+ * This function cancels all the pending commands.
+ *
+ * The current command, all commands in command pending queue and all scan
+ * commands in scan pending queue are cancelled. All the completion callbacks
+ * are called with failure status to ensure cleanup.
+ */
+void
+mwifiex_cancel_all_pending_cmd(struct mwifiex_adapter *adapter)
+{
+	struct cmd_ctrl_node *cmd_node = NULL, *tmp_node;
+	unsigned long flags;
+
+	/* Cancel current cmd */
+	if ((adapter->curr_cmd) && (adapter->curr_cmd->wait_q_enabled)) {
+		spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags);
+		adapter->curr_cmd->wait_q_enabled = false;
+		spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags);
+		adapter->cmd_wait_q.status = -1;
+		mwifiex_complete_cmd(adapter);
+	}
+	/* Cancel all pending command */
+	spin_lock_irqsave(&adapter->cmd_pending_q_lock, flags);
+	list_for_each_entry_safe(cmd_node, tmp_node,
+				 &adapter->cmd_pending_q, list) {
+		list_del(&cmd_node->list);
+		spin_unlock_irqrestore(&adapter->cmd_pending_q_lock, flags);
+
+		if (cmd_node->wait_q_enabled) {
+			adapter->cmd_wait_q.status = -1;
+			mwifiex_complete_cmd(adapter);
+			cmd_node->wait_q_enabled = false;
+		}
+		mwifiex_insert_cmd_to_free_q(adapter, cmd_node);
+		spin_lock_irqsave(&adapter->cmd_pending_q_lock, flags);
+	}
+	spin_unlock_irqrestore(&adapter->cmd_pending_q_lock, flags);
+
+	/* Cancel all pending scan command */
+	spin_lock_irqsave(&adapter->scan_pending_q_lock, flags);
+	list_for_each_entry_safe(cmd_node, tmp_node,
+				 &adapter->scan_pending_q, list) {
+		list_del(&cmd_node->list);
+		spin_unlock_irqrestore(&adapter->scan_pending_q_lock, flags);
+
+		cmd_node->wait_q_enabled = false;
+		mwifiex_insert_cmd_to_free_q(adapter, cmd_node);
+		spin_lock_irqsave(&adapter->scan_pending_q_lock, flags);
+	}
+	spin_unlock_irqrestore(&adapter->scan_pending_q_lock, flags);
+
+	spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags);
+	adapter->scan_processing = false;
+	spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags);
+}
+
+/*
+ * This function cancels all pending commands that matches with
+ * the given IOCTL request.
+ *
+ * Both the current command buffer and the pending command queue are
+ * searched for matching IOCTL request. The completion callback of
+ * the matched command is called with failure status to ensure cleanup.
+ * In case of scan commands, all pending commands in scan pending queue
+ * are cancelled.
+ */
+void
+mwifiex_cancel_pending_ioctl(struct mwifiex_adapter *adapter)
+{
+	struct cmd_ctrl_node *cmd_node = NULL, *tmp_node = NULL;
+	unsigned long cmd_flags;
+	unsigned long cmd_pending_q_flags;
+	unsigned long scan_pending_q_flags;
+	uint16_t cancel_scan_cmd = false;
+
+	if ((adapter->curr_cmd) &&
+	     (adapter->curr_cmd->wait_q_enabled)) {
+		spin_lock_irqsave(&adapter->mwifiex_cmd_lock, cmd_flags);
+		cmd_node = adapter->curr_cmd;
+		cmd_node->wait_q_enabled = false;
+		cmd_node->cmd_flag |= CMD_F_CANCELED;
+		spin_lock_irqsave(&adapter->cmd_pending_q_lock,
+				  cmd_pending_q_flags);
+		list_del(&cmd_node->list);
+		spin_unlock_irqrestore(&adapter->cmd_pending_q_lock,
+				       cmd_pending_q_flags);
+		mwifiex_insert_cmd_to_free_q(adapter, cmd_node);
+		spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, cmd_flags);
+	}
+
+	/* Cancel all pending scan command */
+	spin_lock_irqsave(&adapter->scan_pending_q_lock,
+			  scan_pending_q_flags);
+	list_for_each_entry_safe(cmd_node, tmp_node,
+				 &adapter->scan_pending_q, list) {
+		list_del(&cmd_node->list);
+		spin_unlock_irqrestore(&adapter->scan_pending_q_lock,
+				       scan_pending_q_flags);
+		cmd_node->wait_q_enabled = false;
+		mwifiex_insert_cmd_to_free_q(adapter, cmd_node);
+		spin_lock_irqsave(&adapter->scan_pending_q_lock,
+				  scan_pending_q_flags);
+		cancel_scan_cmd = true;
+	}
+	spin_unlock_irqrestore(&adapter->scan_pending_q_lock,
+			       scan_pending_q_flags);
+
+	if (cancel_scan_cmd) {
+		spin_lock_irqsave(&adapter->mwifiex_cmd_lock, cmd_flags);
+		adapter->scan_processing = false;
+		spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, cmd_flags);
+	}
+	adapter->cmd_wait_q.status = -1;
+	mwifiex_complete_cmd(adapter);
+}
+
+/*
+ * This function sends the sleep confirm command to firmware, if
+ * possible.
+ *
+ * The sleep confirm command cannot be issued if command response,
+ * data response or event response is awaiting handling, or if we
+ * are in the middle of sending a command, or expecting a command
+ * response.
+ */
+void
+mwifiex_check_ps_cond(struct mwifiex_adapter *adapter)
+{
+	if (!adapter->cmd_sent &&
+	    !adapter->curr_cmd && !IS_CARD_RX_RCVD(adapter))
+		mwifiex_dnld_sleep_confirm_cmd(adapter);
+	else
+		dev_dbg(adapter->dev,
+			"cmd: Delay Sleep Confirm (%s%s%s)\n",
+		       (adapter->cmd_sent) ? "D" : "",
+		       (adapter->curr_cmd) ? "C" : "",
+		       (IS_CARD_RX_RCVD(adapter)) ? "R" : "");
+}
+
+/*
+ * This function sends a Host Sleep activated event to applications.
+ *
+ * This event is generated by the driver, with a blank event body.
+ */
+void
+mwifiex_hs_activated_event(struct mwifiex_private *priv, u8 activated)
+{
+	if (activated) {
+		if (priv->adapter->is_hs_configured) {
+			priv->adapter->hs_activated = true;
+			dev_dbg(priv->adapter->dev, "event: hs_activated\n");
+			priv->adapter->hs_activate_wait_q_woken = true;
+			wake_up_interruptible(
+				&priv->adapter->hs_activate_wait_q);
+		} else {
+			dev_dbg(priv->adapter->dev, "event: HS not configured\n");
+		}
+	} else {
+		dev_dbg(priv->adapter->dev, "event: hs_deactivated\n");
+		priv->adapter->hs_activated = false;
+	}
+}
+
+/*
+ * This function handles the command response of a Host Sleep configuration
+ * command.
+ *
+ * Handling includes changing the header fields into CPU format
+ * and setting the current host sleep activation status in driver.
+ *
+ * In case host sleep status change, the function generates an event to
+ * notify the applications.
+ */
+int mwifiex_ret_802_11_hs_cfg(struct mwifiex_private *priv,
+			      struct host_cmd_ds_command *resp)
+{
+	struct mwifiex_adapter *adapter = priv->adapter;
+	struct host_cmd_ds_802_11_hs_cfg_enh *phs_cfg =
+		&resp->params.opt_hs_cfg;
+	uint32_t conditions = le32_to_cpu(phs_cfg->params.hs_config.conditions);
+
+	if (phs_cfg->action == cpu_to_le16(HS_ACTIVATE)) {
+		mwifiex_hs_activated_event(priv, true);
+		return 0;
+	} else {
+		dev_dbg(adapter->dev, "cmd: CMD_RESP: HS_CFG cmd reply"
+			" result=%#x, conditions=0x%x gpio=0x%x gap=0x%x\n",
+			resp->result, conditions,
+		       phs_cfg->params.hs_config.gpio,
+		       phs_cfg->params.hs_config.gap);
+	}
+	if (conditions != HOST_SLEEP_CFG_CANCEL) {
+		adapter->is_hs_configured = true;
+	} else {
+		adapter->is_hs_configured = false;
+		if (adapter->hs_activated)
+			mwifiex_hs_activated_event(priv, false);
+	}
+
+	return 0;
+}
+
+/*
+ * This function wakes up the adapter and generates a Host Sleep
+ * cancel event on receiving the power up interrupt.
+ */
+void
+mwifiex_process_hs_config(struct mwifiex_adapter *adapter)
+{
+	dev_dbg(adapter->dev, "info: %s: auto cancelling host sleep"
+		" since there is interrupt from the firmware\n", __func__);
+
+	adapter->if_ops.wakeup(adapter);
+	adapter->hs_activated = false;
+	adapter->is_hs_configured = false;
+	mwifiex_hs_activated_event(mwifiex_get_priv(adapter,
+				   MWIFIEX_BSS_ROLE_ANY), false);
+}
+
+/*
+ * This function handles the command response of a sleep confirm command.
+ *
+ * The function sets the card state to SLEEP if the response indicates success.
+ */
+void
+mwifiex_process_sleep_confirm_resp(struct mwifiex_adapter *adapter,
+				   u8 *pbuf, u32 upld_len)
+{
+	struct host_cmd_ds_command *cmd = (struct host_cmd_ds_command *) pbuf;
+	struct mwifiex_private *priv =
+		mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY);
+	uint16_t result = le16_to_cpu(cmd->result);
+	uint16_t command = le16_to_cpu(cmd->command);
+	uint16_t seq_num = le16_to_cpu(cmd->seq_num);
+
+	if (!upld_len) {
+		dev_err(adapter->dev, "%s: cmd size is 0\n", __func__);
+		return;
+	}
+
+	/* Get BSS number and corresponding priv */
+	priv = mwifiex_get_priv_by_id(adapter, HostCmd_GET_BSS_NO(seq_num),
+				      HostCmd_GET_BSS_TYPE(seq_num));
+	if (!priv)
+		priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY);
+
+	/* Update sequence number */
+	seq_num = HostCmd_GET_SEQ_NO(seq_num);
+	/* Clear RET_BIT from HostCmd */
+	command &= HostCmd_CMD_ID_MASK;
+
+	if (command != HostCmd_CMD_802_11_PS_MODE_ENH) {
+		dev_err(adapter->dev, "%s: received unexpected response for"
+			" cmd %x, result = %x\n", __func__, command, result);
+		return;
+	}
+
+	if (result) {
+		dev_err(adapter->dev, "%s: sleep confirm cmd failed\n",
+						__func__);
+		adapter->pm_wakeup_card_req = false;
+		adapter->ps_state = PS_STATE_AWAKE;
+		return;
+	}
+	adapter->pm_wakeup_card_req = true;
+	if (adapter->is_hs_configured)
+		mwifiex_hs_activated_event(mwifiex_get_priv(adapter,
+					   MWIFIEX_BSS_ROLE_ANY), true);
+	adapter->ps_state = PS_STATE_SLEEP;
+	cmd->command = cpu_to_le16(command);
+	cmd->seq_num = cpu_to_le16(seq_num);
+}
+EXPORT_SYMBOL_GPL(mwifiex_process_sleep_confirm_resp);
+
+/*
+ * This function prepares an enhanced power mode command.
+ *
+ * This function can be used to disable power save or to configure
+ * power save with auto PS or STA PS or auto deep sleep.
+ *
+ * Preparation includes -
+ *      - Setting command ID, action and proper size
+ *      - Setting Power Save bitmap, PS parameters TLV, PS mode TLV,
+ *        auto deep sleep TLV (as required)
+ *      - Ensuring correct endian-ness
+ */
+int mwifiex_cmd_enh_power_mode(struct mwifiex_private *priv,
+			       struct host_cmd_ds_command *cmd,
+			       u16 cmd_action, uint16_t ps_bitmap,
+			       void *data_buf)
+{
+	struct host_cmd_ds_802_11_ps_mode_enh *psmode_enh =
+		&cmd->params.psmode_enh;
+	u8 *tlv;
+	u16 cmd_size = 0;
+
+	cmd->command = cpu_to_le16(HostCmd_CMD_802_11_PS_MODE_ENH);
+	if (cmd_action == DIS_AUTO_PS) {
+		psmode_enh->action = cpu_to_le16(DIS_AUTO_PS);
+		psmode_enh->params.ps_bitmap = cpu_to_le16(ps_bitmap);
+		cmd->size = cpu_to_le16(S_DS_GEN + sizeof(psmode_enh->action) +
+				sizeof(psmode_enh->params.ps_bitmap));
+	} else if (cmd_action == GET_PS) {
+		psmode_enh->action = cpu_to_le16(GET_PS);
+		psmode_enh->params.ps_bitmap = cpu_to_le16(ps_bitmap);
+		cmd->size = cpu_to_le16(S_DS_GEN + sizeof(psmode_enh->action) +
+				sizeof(psmode_enh->params.ps_bitmap));
+	} else if (cmd_action == EN_AUTO_PS) {
+		psmode_enh->action = cpu_to_le16(EN_AUTO_PS);
+		psmode_enh->params.ps_bitmap = cpu_to_le16(ps_bitmap);
+		cmd_size = S_DS_GEN + sizeof(psmode_enh->action) +
+				sizeof(psmode_enh->params.ps_bitmap);
+		tlv = (u8 *) cmd + cmd_size;
+		if (ps_bitmap & BITMAP_STA_PS) {
+			struct mwifiex_adapter *adapter = priv->adapter;
+			struct mwifiex_ie_types_ps_param *ps_tlv =
+				(struct mwifiex_ie_types_ps_param *) tlv;
+			struct mwifiex_ps_param *ps_mode = &ps_tlv->param;
+			ps_tlv->header.type = cpu_to_le16(TLV_TYPE_PS_PARAM);
+			ps_tlv->header.len = cpu_to_le16(sizeof(*ps_tlv) -
+					sizeof(struct mwifiex_ie_types_header));
+			cmd_size += sizeof(*ps_tlv);
+			tlv += sizeof(*ps_tlv);
+			dev_dbg(adapter->dev, "cmd: PS Command: Enter PS\n");
+			ps_mode->null_pkt_interval =
+				cpu_to_le16(adapter->null_pkt_interval);
+			ps_mode->multiple_dtims =
+				cpu_to_le16(adapter->multiple_dtim);
+			ps_mode->bcn_miss_timeout =
+				cpu_to_le16(adapter->bcn_miss_time_out);
+			ps_mode->local_listen_interval =
+				cpu_to_le16(adapter->local_listen_interval);
+			ps_mode->adhoc_wake_period =
+				cpu_to_le16(adapter->adhoc_awake_period);
+			ps_mode->delay_to_ps =
+				cpu_to_le16(adapter->delay_to_ps);
+			ps_mode->mode =
+				cpu_to_le16(adapter->enhanced_ps_mode);
+
+		}
+		if (ps_bitmap & BITMAP_AUTO_DS) {
+			struct mwifiex_ie_types_auto_ds_param *auto_ds_tlv =
+				(struct mwifiex_ie_types_auto_ds_param *) tlv;
+			u16 idletime = 0;
+
+			auto_ds_tlv->header.type =
+				cpu_to_le16(TLV_TYPE_AUTO_DS_PARAM);
+			auto_ds_tlv->header.len =
+				cpu_to_le16(sizeof(*auto_ds_tlv) -
+					sizeof(struct mwifiex_ie_types_header));
+			cmd_size += sizeof(*auto_ds_tlv);
+			tlv += sizeof(*auto_ds_tlv);
+			if (data_buf)
+				idletime = ((struct mwifiex_ds_auto_ds *)
+					     data_buf)->idle_time;
+			dev_dbg(priv->adapter->dev,
+					"cmd: PS Command: Enter Auto Deep Sleep\n");
+			auto_ds_tlv->deep_sleep_timeout = cpu_to_le16(idletime);
+		}
+		cmd->size = cpu_to_le16(cmd_size);
+	}
+	return 0;
+}
+
+/*
+ * This function handles the command response of an enhanced power mode
+ * command.
+ *
+ * Handling includes changing the header fields into CPU format
+ * and setting the current enhanced power mode in driver.
+ */
+int mwifiex_ret_enh_power_mode(struct mwifiex_private *priv,
+			       struct host_cmd_ds_command *resp,
+			       void *data_buf)
+{
+	struct mwifiex_adapter *adapter = priv->adapter;
+	struct host_cmd_ds_802_11_ps_mode_enh *ps_mode =
+		&resp->params.psmode_enh;
+	uint16_t action = le16_to_cpu(ps_mode->action);
+	uint16_t ps_bitmap = le16_to_cpu(ps_mode->params.ps_bitmap);
+	uint16_t auto_ps_bitmap =
+		le16_to_cpu(ps_mode->params.ps_bitmap);
+
+	dev_dbg(adapter->dev, "info: %s: PS_MODE cmd reply result=%#x action=%#X\n",
+					__func__, resp->result, action);
+	if (action == EN_AUTO_PS) {
+		if (auto_ps_bitmap & BITMAP_AUTO_DS) {
+			dev_dbg(adapter->dev, "cmd: Enabled auto deep sleep\n");
+			priv->adapter->is_deep_sleep = true;
+		}
+		if (auto_ps_bitmap & BITMAP_STA_PS) {
+			dev_dbg(adapter->dev, "cmd: Enabled STA power save\n");
+			if (adapter->sleep_period.period)
+				dev_dbg(adapter->dev, "cmd: set to uapsd/pps mode\n");
+		}
+	} else if (action == DIS_AUTO_PS) {
+		if (ps_bitmap & BITMAP_AUTO_DS) {
+			priv->adapter->is_deep_sleep = false;
+			dev_dbg(adapter->dev, "cmd: Disabled auto deep sleep\n");
+		}
+		if (ps_bitmap & BITMAP_STA_PS) {
+			dev_dbg(adapter->dev, "cmd: Disabled STA power save\n");
+			if (adapter->sleep_period.period) {
+				adapter->delay_null_pkt = false;
+				adapter->tx_lock_flag = false;
+				adapter->pps_uapsd_mode = false;
+			}
+		}
+	} else if (action == GET_PS) {
+		if (ps_bitmap & BITMAP_STA_PS)
+			adapter->ps_mode = MWIFIEX_802_11_POWER_MODE_PSP;
+		else
+			adapter->ps_mode = MWIFIEX_802_11_POWER_MODE_CAM;
+
+		dev_dbg(adapter->dev, "cmd: ps_bitmap=%#x\n", ps_bitmap);
+
+		if (data_buf) {
+			/* This section is for get power save mode */
+			struct mwifiex_ds_pm_cfg *pm_cfg =
+					(struct mwifiex_ds_pm_cfg *)data_buf;
+			if (ps_bitmap & BITMAP_STA_PS)
+				pm_cfg->param.ps_mode = 1;
+			else
+				pm_cfg->param.ps_mode = 0;
+		}
+	}
+	return 0;
+}
+
+/*
+ * This function prepares command to get hardware specifications.
+ *
+ * Preparation includes -
+ *      - Setting command ID, action and proper size
+ *      - Setting permanent address parameter
+ *      - Ensuring correct endian-ness
+ */
+int mwifiex_cmd_get_hw_spec(struct mwifiex_private *priv,
+			    struct host_cmd_ds_command *cmd)
+{
+	struct host_cmd_ds_get_hw_spec *hw_spec = &cmd->params.hw_spec;
+
+	cmd->command = cpu_to_le16(HostCmd_CMD_GET_HW_SPEC);
+	cmd->size =
+		cpu_to_le16(sizeof(struct host_cmd_ds_get_hw_spec) + S_DS_GEN);
+	memcpy(hw_spec->permanent_addr, priv->curr_addr, ETH_ALEN);
+
+	return 0;
+}
+
+/*
+ * This function handles the command response of get hardware
+ * specifications.
+ *
+ * Handling includes changing the header fields into CPU format
+ * and saving/updating the following parameters in driver -
+ *      - Firmware capability information
+ *      - Firmware band settings
+ *      - Ad-hoc start band and channel
+ *      - Ad-hoc 11n activation status
+ *      - Firmware release number
+ *      - Number of antennas
+ *      - Hardware address
+ *      - Hardware interface version
+ *      - Firmware version
+ *      - Region code
+ *      - 11n capabilities
+ *      - MCS support fields
+ *      - MP end port
+ */
+int mwifiex_ret_get_hw_spec(struct mwifiex_private *priv,
+			    struct host_cmd_ds_command *resp)
+{
+	struct host_cmd_ds_get_hw_spec *hw_spec = &resp->params.hw_spec;
+	struct mwifiex_adapter *adapter = priv->adapter;
+	int i;
+
+	adapter->fw_cap_info = le32_to_cpu(hw_spec->fw_cap_info);
+
+	if (IS_SUPPORT_MULTI_BANDS(adapter))
+		adapter->fw_bands = (u8) GET_FW_DEFAULT_BANDS(adapter);
+	else
+		adapter->fw_bands = BAND_B;
+
+	adapter->config_bands = adapter->fw_bands;
+
+	if (adapter->fw_bands & BAND_A) {
+		if (adapter->fw_bands & BAND_GN) {
+			adapter->config_bands |= BAND_AN;
+			adapter->fw_bands |= BAND_AN;
+		}
+		if (adapter->fw_bands & BAND_AN) {
+			adapter->adhoc_start_band = BAND_A | BAND_AN;
+			adapter->adhoc_11n_enabled = true;
+		} else {
+			adapter->adhoc_start_band = BAND_A;
+		}
+		priv->adhoc_channel = DEFAULT_AD_HOC_CHANNEL_A;
+	} else if (adapter->fw_bands & BAND_GN) {
+		adapter->adhoc_start_band = BAND_G | BAND_B | BAND_GN;
+		priv->adhoc_channel = DEFAULT_AD_HOC_CHANNEL;
+		adapter->adhoc_11n_enabled = true;
+	} else if (adapter->fw_bands & BAND_G) {
+		adapter->adhoc_start_band = BAND_G | BAND_B;
+		priv->adhoc_channel = DEFAULT_AD_HOC_CHANNEL;
+	} else if (adapter->fw_bands & BAND_B) {
+		adapter->adhoc_start_band = BAND_B;
+		priv->adhoc_channel = DEFAULT_AD_HOC_CHANNEL;
+	}
+
+	adapter->fw_release_number = le32_to_cpu(hw_spec->fw_release_number);
+	adapter->number_of_antenna = le16_to_cpu(hw_spec->number_of_antenna);
+
+	dev_dbg(adapter->dev, "info: GET_HW_SPEC: fw_release_number- %#x\n",
+	       adapter->fw_release_number);
+	dev_dbg(adapter->dev, "info: GET_HW_SPEC: permanent addr: %pM\n",
+					hw_spec->permanent_addr);
+	dev_dbg(adapter->dev, "info: GET_HW_SPEC: hw_if_version=%#x  version=%#x\n",
+		le16_to_cpu(hw_spec->hw_if_version),
+	       le16_to_cpu(hw_spec->version));
+
+	if (priv->curr_addr[0] == 0xff)
+		memmove(priv->curr_addr, hw_spec->permanent_addr, ETH_ALEN);
+
+	adapter->region_code = le16_to_cpu(hw_spec->region_code);
+
+	for (i = 0; i < MWIFIEX_MAX_REGION_CODE; i++)
+		/* Use the region code to search for the index */
+		if (adapter->region_code == region_code_index[i])
+			break;
+
+	/* If it's unidentified region code, use the default (USA) */
+	if (i >= MWIFIEX_MAX_REGION_CODE) {
+		adapter->region_code = 0x10;
+		dev_dbg(adapter->dev, "cmd: unknown region code, use default (USA)\n");
+	}
+
+	adapter->hw_dot_11n_dev_cap = le32_to_cpu(hw_spec->dot_11n_dev_cap);
+	adapter->hw_dev_mcs_support = hw_spec->dev_mcs_support;
+
+	if (adapter->if_ops.update_mp_end_port)
+		adapter->if_ops.update_mp_end_port(adapter,
+					le16_to_cpu(hw_spec->mp_end_port));
+
+	return 0;
+}
diff -druN linux-2.6.39-libre/drivers/net/wireless/mwifiex/debugfs.c linux-3.0-rc7-libre/drivers/net/wireless/mwifiex/debugfs.c
--- linux-2.6.39-libre/drivers/net/wireless/mwifiex/debugfs.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/net/wireless/mwifiex/debugfs.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,770 @@
+/*
+ * Marvell Wireless LAN device driver: debugfs
+ *
+ * Copyright (C) 2011, Marvell International Ltd.
+ *
+ * This software file (the "File") is distributed by Marvell International
+ * Ltd. under the terms of the GNU General Public License Version 2, June 1991
+ * (the "License").  You may use, redistribute and/or modify this File in
+ * accordance with the terms and conditions of the License, a copy of which
+ * is available by writing to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
+ * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
+ *
+ * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
+ * ARE EXPRESSLY DISCLAIMED.  The License provides additional details about
+ * this warranty disclaimer.
+ */
+
+#include <linux/debugfs.h>
+
+#include "main.h"
+#include "11n.h"
+
+
+static struct dentry *mwifiex_dfs_dir;
+
+static char *bss_modes[] = {
+	"Unknown",
+	"Managed",
+	"Ad-hoc",
+	"Auto"
+};
+
+/* size/addr for mwifiex_debug_info */
+#define item_size(n)		(FIELD_SIZEOF(struct mwifiex_debug_info, n))
+#define item_addr(n)		(offsetof(struct mwifiex_debug_info, n))
+
+/* size/addr for struct mwifiex_adapter */
+#define adapter_item_size(n)	(FIELD_SIZEOF(struct mwifiex_adapter, n))
+#define adapter_item_addr(n)	(offsetof(struct mwifiex_adapter, n))
+
+struct mwifiex_debug_data {
+	char name[32];		/* variable/array name */
+	u32 size;		/* size of the variable/array */
+	size_t addr;		/* address of the variable/array */
+	int num;		/* number of variables in an array */
+};
+
+static struct mwifiex_debug_data items[] = {
+	{"int_counter", item_size(int_counter),
+	 item_addr(int_counter), 1},
+	{"wmm_ac_vo", item_size(packets_out[WMM_AC_VO]),
+	 item_addr(packets_out[WMM_AC_VO]), 1},
+	{"wmm_ac_vi", item_size(packets_out[WMM_AC_VI]),
+	 item_addr(packets_out[WMM_AC_VI]), 1},
+	{"wmm_ac_be", item_size(packets_out[WMM_AC_BE]),
+	 item_addr(packets_out[WMM_AC_BE]), 1},
+	{"wmm_ac_bk", item_size(packets_out[WMM_AC_BK]),
+	 item_addr(packets_out[WMM_AC_BK]), 1},
+	{"max_tx_buf_size", item_size(max_tx_buf_size),
+	 item_addr(max_tx_buf_size), 1},
+	{"tx_buf_size", item_size(tx_buf_size),
+	 item_addr(tx_buf_size), 1},
+	{"curr_tx_buf_size", item_size(curr_tx_buf_size),
+	 item_addr(curr_tx_buf_size), 1},
+	{"ps_mode", item_size(ps_mode),
+	 item_addr(ps_mode), 1},
+	{"ps_state", item_size(ps_state),
+	 item_addr(ps_state), 1},
+	{"is_deep_sleep", item_size(is_deep_sleep),
+	 item_addr(is_deep_sleep), 1},
+	{"wakeup_dev_req", item_size(pm_wakeup_card_req),
+	 item_addr(pm_wakeup_card_req), 1},
+	{"wakeup_tries", item_size(pm_wakeup_fw_try),
+	 item_addr(pm_wakeup_fw_try), 1},
+	{"hs_configured", item_size(is_hs_configured),
+	 item_addr(is_hs_configured), 1},
+	{"hs_activated", item_size(hs_activated),
+	 item_addr(hs_activated), 1},
+	{"num_tx_timeout", item_size(num_tx_timeout),
+	 item_addr(num_tx_timeout), 1},
+	{"num_cmd_timeout", item_size(num_cmd_timeout),
+	 item_addr(num_cmd_timeout), 1},
+	{"timeout_cmd_id", item_size(timeout_cmd_id),
+	 item_addr(timeout_cmd_id), 1},
+	{"timeout_cmd_act", item_size(timeout_cmd_act),
+	 item_addr(timeout_cmd_act), 1},
+	{"last_cmd_id", item_size(last_cmd_id),
+	 item_addr(last_cmd_id), DBG_CMD_NUM},
+	{"last_cmd_act", item_size(last_cmd_act),
+	 item_addr(last_cmd_act), DBG_CMD_NUM},
+	{"last_cmd_index", item_size(last_cmd_index),
+	 item_addr(last_cmd_index), 1},
+	{"last_cmd_resp_id", item_size(last_cmd_resp_id),
+	 item_addr(last_cmd_resp_id), DBG_CMD_NUM},
+	{"last_cmd_resp_index", item_size(last_cmd_resp_index),
+	 item_addr(last_cmd_resp_index), 1},
+	{"last_event", item_size(last_event),
+	 item_addr(last_event), DBG_CMD_NUM},
+	{"last_event_index", item_size(last_event_index),
+	 item_addr(last_event_index), 1},
+	{"num_cmd_h2c_fail", item_size(num_cmd_host_to_card_failure),
+	 item_addr(num_cmd_host_to_card_failure), 1},
+	{"num_cmd_sleep_cfm_fail",
+	 item_size(num_cmd_sleep_cfm_host_to_card_failure),
+	 item_addr(num_cmd_sleep_cfm_host_to_card_failure), 1},
+	{"num_tx_h2c_fail", item_size(num_tx_host_to_card_failure),
+	 item_addr(num_tx_host_to_card_failure), 1},
+	{"num_evt_deauth", item_size(num_event_deauth),
+	 item_addr(num_event_deauth), 1},
+	{"num_evt_disassoc", item_size(num_event_disassoc),
+	 item_addr(num_event_disassoc), 1},
+	{"num_evt_link_lost", item_size(num_event_link_lost),
+	 item_addr(num_event_link_lost), 1},
+	{"num_cmd_deauth", item_size(num_cmd_deauth),
+	 item_addr(num_cmd_deauth), 1},
+	{"num_cmd_assoc_ok", item_size(num_cmd_assoc_success),
+	 item_addr(num_cmd_assoc_success), 1},
+	{"num_cmd_assoc_fail", item_size(num_cmd_assoc_failure),
+	 item_addr(num_cmd_assoc_failure), 1},
+	{"cmd_sent", item_size(cmd_sent),
+	 item_addr(cmd_sent), 1},
+	{"data_sent", item_size(data_sent),
+	 item_addr(data_sent), 1},
+	{"cmd_resp_received", item_size(cmd_resp_received),
+	 item_addr(cmd_resp_received), 1},
+	{"event_received", item_size(event_received),
+	 item_addr(event_received), 1},
+
+	/* variables defined in struct mwifiex_adapter */
+	{"cmd_pending", adapter_item_size(cmd_pending),
+	 adapter_item_addr(cmd_pending), 1},
+	{"tx_pending", adapter_item_size(tx_pending),
+	 adapter_item_addr(tx_pending), 1},
+	{"rx_pending", adapter_item_size(rx_pending),
+	 adapter_item_addr(rx_pending), 1},
+};
+
+static int num_of_items = ARRAY_SIZE(items);
+
+/*
+ * Generic proc file open handler.
+ *
+ * This function is called every time a file is accessed for read or write.
+ */
+static int
+mwifiex_open_generic(struct inode *inode, struct file *file)
+{
+	file->private_data = inode->i_private;
+	return 0;
+}
+
+/*
+ * Proc info file read handler.
+ *
+ * This function is called when the 'info' file is opened for reading.
+ * It prints the following driver related information -
+ *      - Driver name
+ *      - Driver version
+ *      - Driver extended version
+ *      - Interface name
+ *      - BSS mode
+ *      - Media state (connected or disconnected)
+ *      - MAC address
+ *      - Total number of Tx bytes
+ *      - Total number of Rx bytes
+ *      - Total number of Tx packets
+ *      - Total number of Rx packets
+ *      - Total number of dropped Tx packets
+ *      - Total number of dropped Rx packets
+ *      - Total number of corrupted Tx packets
+ *      - Total number of corrupted Rx packets
+ *      - Carrier status (on or off)
+ *      - Tx queue status (started or stopped)
+ *
+ * For STA mode drivers, it also prints the following extra -
+ *      - ESSID
+ *      - BSSID
+ *      - Channel
+ *      - Region code
+ *      - Multicast count
+ *      - Multicast addresses
+ */
+static ssize_t
+mwifiex_info_read(struct file *file, char __user *ubuf,
+		  size_t count, loff_t *ppos)
+{
+	struct mwifiex_private *priv =
+		(struct mwifiex_private *) file->private_data;
+	struct net_device *netdev = priv->netdev;
+	struct netdev_hw_addr *ha;
+	unsigned long page = get_zeroed_page(GFP_KERNEL);
+	char *p = (char *) page, fmt[64];
+	struct mwifiex_bss_info info;
+	ssize_t ret;
+	int i = 0;
+
+	if (!p)
+		return -ENOMEM;
+
+	memset(&info, 0, sizeof(info));
+	ret = mwifiex_get_bss_info(priv, &info);
+	if (ret)
+		goto free_and_exit;
+
+	mwifiex_drv_get_driver_version(priv->adapter, fmt, sizeof(fmt) - 1);
+
+	if (!priv->version_str[0])
+		mwifiex_get_ver_ext(priv);
+
+	p += sprintf(p, "driver_name = " "\"mwifiex\"\n");
+	p += sprintf(p, "driver_version = %s", fmt);
+	p += sprintf(p, "\nverext = %s", priv->version_str);
+	p += sprintf(p, "\ninterface_name=\"%s\"\n", netdev->name);
+	p += sprintf(p, "bss_mode=\"%s\"\n", bss_modes[info.bss_mode]);
+	p += sprintf(p, "media_state=\"%s\"\n",
+		     (!priv->media_connected ? "Disconnected" : "Connected"));
+	p += sprintf(p, "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]);
+
+	if (GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_STA) {
+		p += sprintf(p, "multicast_count=\"%d\"\n",
+			     netdev_mc_count(netdev));
+		p += sprintf(p, "essid=\"%s\"\n", info.ssid.ssid);
+		p += sprintf(p, "bssid=\"%02x:%02x:%02x:%02x:%02x:%02x\"\n",
+			     info.bssid[0], info.bssid[1],
+			     info.bssid[2], info.bssid[3],
+			     info.bssid[4], info.bssid[5]);
+		p += sprintf(p, "channel=\"%d\"\n", (int) info.bss_chan);
+		p += sprintf(p, "region_code = \"%02x\"\n", info.region_code);
+
+		netdev_for_each_mc_addr(ha, netdev)
+			p += sprintf(p, "multicast_address[%d]="
+				     "\"%02x:%02x:%02x:%02x:%02x:%02x\"\n", i++,
+				     ha->addr[0], ha->addr[1],
+				     ha->addr[2], ha->addr[3],
+				     ha->addr[4], ha->addr[5]);
+	}
+
+	p += sprintf(p, "num_tx_bytes = %lu\n", priv->stats.tx_bytes);
+	p += sprintf(p, "num_rx_bytes = %lu\n", priv->stats.rx_bytes);
+	p += sprintf(p, "num_tx_pkts = %lu\n", priv->stats.tx_packets);
+	p += sprintf(p, "num_rx_pkts = %lu\n", priv->stats.rx_packets);
+	p += sprintf(p, "num_tx_pkts_dropped = %lu\n", priv->stats.tx_dropped);
+	p += sprintf(p, "num_rx_pkts_dropped = %lu\n", priv->stats.rx_dropped);
+	p += sprintf(p, "num_tx_pkts_err = %lu\n", priv->stats.tx_errors);
+	p += sprintf(p, "num_rx_pkts_err = %lu\n", priv->stats.rx_errors);
+	p += sprintf(p, "carrier %s\n", ((netif_carrier_ok(priv->netdev))
+					 ? "on" : "off"));
+	p += sprintf(p, "tx queue %s\n", ((netif_queue_stopped(priv->netdev))
+					  ? "stopped" : "started"));
+
+	ret = simple_read_from_buffer(ubuf, count, ppos, (char *) page,
+				      (unsigned long) p - page);
+
+free_and_exit:
+	free_page(page);
+	return ret;
+}
+
+/*
+ * Proc getlog file read handler.
+ *
+ * This function is called when the 'getlog' file is opened for reading
+ * It prints the following log information -
+ *      - Number of multicast Tx frames
+ *      - Number of failed packets
+ *      - Number of Tx retries
+ *      - Number of multicast Tx retries
+ *      - Number of duplicate frames
+ *      - Number of RTS successes
+ *      - Number of RTS failures
+ *      - Number of ACK failures
+ *      - Number of fragmented Rx frames
+ *      - Number of multicast Rx frames
+ *      - Number of FCS errors
+ *      - Number of Tx frames
+ *      - WEP ICV error counts
+ */
+static ssize_t
+mwifiex_getlog_read(struct file *file, char __user *ubuf,
+		    size_t count, loff_t *ppos)
+{
+	struct mwifiex_private *priv =
+		(struct mwifiex_private *) file->private_data;
+	unsigned long page = get_zeroed_page(GFP_KERNEL);
+	char *p = (char *) page;
+	ssize_t ret;
+	struct mwifiex_ds_get_stats stats;
+
+	if (!p)
+		return -ENOMEM;
+
+	memset(&stats, 0, sizeof(stats));
+	ret = mwifiex_get_stats_info(priv, &stats);
+	if (ret)
+		goto free_and_exit;
+
+	p += sprintf(p, "\n"
+		     "mcasttxframe     %u\n"
+		     "failed           %u\n"
+		     "retry            %u\n"
+		     "multiretry       %u\n"
+		     "framedup         %u\n"
+		     "rtssuccess       %u\n"
+		     "rtsfailure       %u\n"
+		     "ackfailure       %u\n"
+		     "rxfrag           %u\n"
+		     "mcastrxframe     %u\n"
+		     "fcserror         %u\n"
+		     "txframe          %u\n"
+		     "wepicverrcnt-1   %u\n"
+		     "wepicverrcnt-2   %u\n"
+		     "wepicverrcnt-3   %u\n"
+		     "wepicverrcnt-4   %u\n",
+		     stats.mcast_tx_frame,
+		     stats.failed,
+		     stats.retry,
+		     stats.multi_retry,
+		     stats.frame_dup,
+		     stats.rts_success,
+		     stats.rts_failure,
+		     stats.ack_failure,
+		     stats.rx_frag,
+		     stats.mcast_rx_frame,
+		     stats.fcs_error,
+		     stats.tx_frame,
+		     stats.wep_icv_error[0],
+		     stats.wep_icv_error[1],
+		     stats.wep_icv_error[2],
+		     stats.wep_icv_error[3]);
+
+
+	ret = simple_read_from_buffer(ubuf, count, ppos, (char *) page,
+				      (unsigned long) p - page);
+
+free_and_exit:
+	free_page(page);
+	return ret;
+}
+
+static struct mwifiex_debug_info info;
+
+/*
+ * Proc debug file read handler.
+ *
+ * This function is called when the 'debug' file is opened for reading
+ * It prints the following log information -
+ *      - Interrupt count
+ *      - WMM AC VO packets count
+ *      - WMM AC VI packets count
+ *      - WMM AC BE packets count
+ *      - WMM AC BK packets count
+ *      - Maximum Tx buffer size
+ *      - Tx buffer size
+ *      - Current Tx buffer size
+ *      - Power Save mode
+ *      - Power Save state
+ *      - Deep Sleep status
+ *      - Device wakeup required status
+ *      - Number of wakeup tries
+ *      - Host Sleep configured status
+ *      - Host Sleep activated status
+ *      - Number of Tx timeouts
+ *      - Number of command timeouts
+ *      - Last timed out command ID
+ *      - Last timed out command action
+ *      - Last command ID
+ *      - Last command action
+ *      - Last command index
+ *      - Last command response ID
+ *      - Last command response index
+ *      - Last event
+ *      - Last event index
+ *      - Number of host to card command failures
+ *      - Number of sleep confirm command failures
+ *      - Number of host to card data failure
+ *      - Number of deauthentication events
+ *      - Number of disassociation events
+ *      - Number of link lost events
+ *      - Number of deauthentication commands
+ *      - Number of association success commands
+ *      - Number of association failure commands
+ *      - Number of commands sent
+ *      - Number of data packets sent
+ *      - Number of command responses received
+ *      - Number of events received
+ *      - Tx BA stream table (TID, RA)
+ *      - Rx reorder table (TID, TA, Start window, Window size, Buffer)
+ */
+static ssize_t
+mwifiex_debug_read(struct file *file, char __user *ubuf,
+		   size_t count, loff_t *ppos)
+{
+	struct mwifiex_private *priv =
+		(struct mwifiex_private *) file->private_data;
+	struct mwifiex_debug_data *d = &items[0];
+	unsigned long page = get_zeroed_page(GFP_KERNEL);
+	char *p = (char *) page;
+	ssize_t ret;
+	size_t size, addr;
+	long val;
+	int i, j;
+
+	if (!p)
+		return -ENOMEM;
+
+	ret = mwifiex_get_debug_info(priv, &info);
+	if (ret)
+		goto free_and_exit;
+
+	for (i = 0; i < num_of_items; i++) {
+		p += sprintf(p, "%s=", d[i].name);
+
+		size = d[i].size / d[i].num;
+
+		if (i < (num_of_items - 3))
+			addr = d[i].addr + (size_t) &info;
+		else /* The last 3 items are struct mwifiex_adapter variables */
+			addr = d[i].addr + (size_t) priv->adapter;
+
+		for (j = 0; j < d[i].num; j++) {
+			switch (size) {
+			case 1:
+				val = *((u8 *) addr);
+				break;
+			case 2:
+				val = *((u16 *) addr);
+				break;
+			case 4:
+				val = *((u32 *) addr);
+				break;
+			case 8:
+				val = *((long long *) addr);
+				break;
+			default:
+				val = -1;
+				break;
+			}
+
+			p += sprintf(p, "%#lx ", val);
+			addr += size;
+		}
+
+		p += sprintf(p, "\n");
+	}
+
+	if (info.tx_tbl_num) {
+		p += sprintf(p, "Tx BA stream table:\n");
+		for (i = 0; i < info.tx_tbl_num; i++)
+			p += sprintf(p, "tid = %d, "
+				     "ra = %02x:%02x:%02x:%02x:%02x:%02x\n",
+				     info.tx_tbl[i].tid, info.tx_tbl[i].ra[0],
+				     info.tx_tbl[i].ra[1], info.tx_tbl[i].ra[2],
+				     info.tx_tbl[i].ra[3], info.tx_tbl[i].ra[4],
+				     info.tx_tbl[i].ra[5]);
+	}
+
+	if (info.rx_tbl_num) {
+		p += sprintf(p, "Rx reorder table:\n");
+		for (i = 0; i < info.rx_tbl_num; i++) {
+
+			p += sprintf(p, "tid = %d, "
+				     "ta = %02x:%02x:%02x:%02x:%02x:%02x, "
+				     "start_win = %d, "
+				     "win_size = %d, buffer: ",
+				     info.rx_tbl[i].tid,
+				     info.rx_tbl[i].ta[0], info.rx_tbl[i].ta[1],
+				     info.rx_tbl[i].ta[2], info.rx_tbl[i].ta[3],
+				     info.rx_tbl[i].ta[4], info.rx_tbl[i].ta[5],
+				     info.rx_tbl[i].start_win,
+				     info.rx_tbl[i].win_size);
+
+			for (j = 0; j < info.rx_tbl[i].win_size; j++)
+				p += sprintf(p, "%c ",
+					     info.rx_tbl[i].buffer[j] ?
+					     '1' : '0');
+
+			p += sprintf(p, "\n");
+		}
+	}
+
+	ret = simple_read_from_buffer(ubuf, count, ppos, (char *) page,
+				      (unsigned long) p - page);
+
+free_and_exit:
+	free_page(page);
+	return ret;
+}
+
+static u32 saved_reg_type, saved_reg_offset, saved_reg_value;
+
+/*
+ * Proc regrdwr file write handler.
+ *
+ * This function is called when the 'regrdwr' file is opened for writing
+ *
+ * This function can be used to write to a register.
+ */
+static ssize_t
+mwifiex_regrdwr_write(struct file *file,
+		      const char __user *ubuf, size_t count, loff_t *ppos)
+{
+	unsigned long addr = get_zeroed_page(GFP_KERNEL);
+	char *buf = (char *) addr;
+	size_t buf_size = min(count, (size_t) (PAGE_SIZE - 1));
+	int ret;
+	u32 reg_type = 0, reg_offset = 0, reg_value = UINT_MAX;
+
+	if (!buf)
+		return -ENOMEM;
+
+
+	if (copy_from_user(buf, ubuf, buf_size)) {
+		ret = -EFAULT;
+		goto done;
+	}
+
+	sscanf(buf, "%u %x %x", &reg_type, &reg_offset, &reg_value);
+
+	if (reg_type == 0 || reg_offset == 0) {
+		ret = -EINVAL;
+		goto done;
+	} else {
+		saved_reg_type = reg_type;
+		saved_reg_offset = reg_offset;
+		saved_reg_value = reg_value;
+		ret = count;
+	}
+done:
+	free_page(addr);
+	return ret;
+}
+
+/*
+ * Proc regrdwr file read handler.
+ *
+ * This function is called when the 'regrdwr' file is opened for reading
+ *
+ * This function can be used to read from a register.
+ */
+static ssize_t
+mwifiex_regrdwr_read(struct file *file, char __user *ubuf,
+		     size_t count, loff_t *ppos)
+{
+	struct mwifiex_private *priv =
+		(struct mwifiex_private *) file->private_data;
+	unsigned long addr = get_zeroed_page(GFP_KERNEL);
+	char *buf = (char *) addr;
+	int pos = 0, ret = 0;
+	u32 reg_value;
+
+	if (!buf)
+		return -ENOMEM;
+
+	if (!saved_reg_type) {
+		/* No command has been given */
+		pos += snprintf(buf, PAGE_SIZE, "0");
+		goto done;
+	}
+	/* Set command has been given */
+	if (saved_reg_value != UINT_MAX) {
+		ret = mwifiex_reg_write(priv, saved_reg_type, saved_reg_offset,
+					saved_reg_value);
+
+		pos += snprintf(buf, PAGE_SIZE, "%u 0x%x 0x%x\n",
+				saved_reg_type, saved_reg_offset,
+				saved_reg_value);
+
+		ret = simple_read_from_buffer(ubuf, count, ppos, buf, pos);
+
+		goto done;
+	}
+	/* Get command has been given */
+	ret = mwifiex_reg_read(priv, saved_reg_type,
+			       saved_reg_offset, &reg_value);
+	if (ret) {
+		ret = -EINVAL;
+		goto done;
+	}
+
+	pos += snprintf(buf, PAGE_SIZE, "%u 0x%x 0x%x\n", saved_reg_type,
+			saved_reg_offset, reg_value);
+
+	ret = simple_read_from_buffer(ubuf, count, ppos, buf, pos);
+
+done:
+	free_page(addr);
+	return ret;
+}
+
+static u32 saved_offset = -1, saved_bytes = -1;
+
+/*
+ * Proc rdeeprom file write handler.
+ *
+ * This function is called when the 'rdeeprom' file is opened for writing
+ *
+ * This function can be used to write to a RDEEPROM location.
+ */
+static ssize_t
+mwifiex_rdeeprom_write(struct file *file,
+		       const char __user *ubuf, size_t count, loff_t *ppos)
+{
+	unsigned long addr = get_zeroed_page(GFP_KERNEL);
+	char *buf = (char *) addr;
+	size_t buf_size = min(count, (size_t) (PAGE_SIZE - 1));
+	int ret = 0;
+	int offset = -1, bytes = -1;
+
+	if (!buf)
+		return -ENOMEM;
+
+
+	if (copy_from_user(buf, ubuf, buf_size)) {
+		ret = -EFAULT;
+		goto done;
+	}
+
+	sscanf(buf, "%d %d", &offset, &bytes);
+
+	if (offset == -1 || bytes == -1) {
+		ret = -EINVAL;
+		goto done;
+	} else {
+		saved_offset = offset;
+		saved_bytes = bytes;
+		ret = count;
+	}
+done:
+	free_page(addr);
+	return ret;
+}
+
+/*
+ * Proc rdeeprom read write handler.
+ *
+ * This function is called when the 'rdeeprom' file is opened for reading
+ *
+ * This function can be used to read from a RDEEPROM location.
+ */
+static ssize_t
+mwifiex_rdeeprom_read(struct file *file, char __user *ubuf,
+		      size_t count, loff_t *ppos)
+{
+	struct mwifiex_private *priv =
+		(struct mwifiex_private *) file->private_data;
+	unsigned long addr = get_zeroed_page(GFP_KERNEL);
+	char *buf = (char *) addr;
+	int pos = 0, ret = 0, i;
+	u8 value[MAX_EEPROM_DATA];
+
+	if (!buf)
+		return -ENOMEM;
+
+	if (saved_offset == -1) {
+		/* No command has been given */
+		pos += snprintf(buf, PAGE_SIZE, "0");
+		goto done;
+	}
+
+	/* Get command has been given */
+	ret = mwifiex_eeprom_read(priv, (u16) saved_offset,
+				  (u16) saved_bytes, value);
+	if (ret) {
+		ret = -EINVAL;
+		goto done;
+	}
+
+	pos += snprintf(buf, PAGE_SIZE, "%d %d ", saved_offset, saved_bytes);
+
+	for (i = 0; i < saved_bytes; i++)
+		pos += snprintf(buf + strlen(buf), PAGE_SIZE, "%d ", value[i]);
+
+	ret = simple_read_from_buffer(ubuf, count, ppos, buf, pos);
+
+done:
+	free_page(addr);
+	return ret;
+}
+
+
+#define MWIFIEX_DFS_ADD_FILE(name) do {                                 \
+	if (!debugfs_create_file(#name, 0644, priv->dfs_dev_dir,        \
+			priv, &mwifiex_dfs_##name##_fops))              \
+		return;                                                 \
+} while (0);
+
+#define MWIFIEX_DFS_FILE_OPS(name)                                      \
+static const struct file_operations mwifiex_dfs_##name##_fops = {       \
+	.read = mwifiex_##name##_read,                                  \
+	.write = mwifiex_##name##_write,                                \
+	.open = mwifiex_open_generic,                                   \
+};
+
+#define MWIFIEX_DFS_FILE_READ_OPS(name)                                 \
+static const struct file_operations mwifiex_dfs_##name##_fops = {       \
+	.read = mwifiex_##name##_read,                                  \
+	.open = mwifiex_open_generic,                                   \
+};
+
+#define MWIFIEX_DFS_FILE_WRITE_OPS(name)                                \
+static const struct file_operations mwifiex_dfs_##name##_fops = {       \
+	.write = mwifiex_##name##_write,                                \
+	.open = mwifiex_open_generic,                                   \
+};
+
+
+MWIFIEX_DFS_FILE_READ_OPS(info);
+MWIFIEX_DFS_FILE_READ_OPS(debug);
+MWIFIEX_DFS_FILE_READ_OPS(getlog);
+MWIFIEX_DFS_FILE_OPS(regrdwr);
+MWIFIEX_DFS_FILE_OPS(rdeeprom);
+
+/*
+ * This function creates the debug FS directory structure and the files.
+ */
+void
+mwifiex_dev_debugfs_init(struct mwifiex_private *priv)
+{
+	if (!mwifiex_dfs_dir || !priv)
+		return;
+
+	priv->dfs_dev_dir = debugfs_create_dir(priv->netdev->name,
+					       mwifiex_dfs_dir);
+
+	if (!priv->dfs_dev_dir)
+		return;
+
+	MWIFIEX_DFS_ADD_FILE(info);
+	MWIFIEX_DFS_ADD_FILE(debug);
+	MWIFIEX_DFS_ADD_FILE(getlog);
+	MWIFIEX_DFS_ADD_FILE(regrdwr);
+	MWIFIEX_DFS_ADD_FILE(rdeeprom);
+}
+
+/*
+ * This function removes the debug FS directory structure and the files.
+ */
+void
+mwifiex_dev_debugfs_remove(struct mwifiex_private *priv)
+{
+	if (!priv)
+		return;
+
+	debugfs_remove_recursive(priv->dfs_dev_dir);
+}
+
+/*
+ * This function creates the top level proc directory.
+ */
+void
+mwifiex_debugfs_init(void)
+{
+	if (!mwifiex_dfs_dir)
+		mwifiex_dfs_dir = debugfs_create_dir("mwifiex", NULL);
+}
+
+/*
+ * This function removes the top level proc directory.
+ */
+void
+mwifiex_debugfs_remove(void)
+{
+	if (mwifiex_dfs_dir)
+		debugfs_remove(mwifiex_dfs_dir);
+}
diff -druN linux-2.6.39-libre/drivers/net/wireless/mwifiex/decl.h linux-3.0-rc7-libre/drivers/net/wireless/mwifiex/decl.h
--- linux-2.6.39-libre/drivers/net/wireless/mwifiex/decl.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/net/wireless/mwifiex/decl.h	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,129 @@
+/*
+ * Marvell Wireless LAN device driver: generic data structures and APIs
+ *
+ * Copyright (C) 2011, Marvell International Ltd.
+ *
+ * This software file (the "File") is distributed by Marvell International
+ * Ltd. under the terms of the GNU General Public License Version 2, June 1991
+ * (the "License").  You may use, redistribute and/or modify this File in
+ * accordance with the terms and conditions of the License, a copy of which
+ * is available by writing to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
+ * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
+ *
+ * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
+ * ARE EXPRESSLY DISCLAIMED.  The License provides additional details about
+ * this warranty disclaimer.
+ */
+
+#ifndef _MWIFIEX_DECL_H_
+#define _MWIFIEX_DECL_H_
+
+#undef pr_fmt
+#define pr_fmt(fmt)	KBUILD_MODNAME ": " fmt
+
+#include <linux/wait.h>
+#include <linux/timer.h>
+#include <linux/ieee80211.h>
+
+
+#define MWIFIEX_MAX_BSS_NUM         (1)
+
+#define MWIFIEX_MIN_DATA_HEADER_LEN 32	/* (sizeof(mwifiex_txpd)) */
+
+#define MWIFIEX_MAX_TX_BASTREAM_SUPPORTED	2
+#define MWIFIEX_MAX_RX_BASTREAM_SUPPORTED	16
+
+#define MWIFIEX_AMPDU_DEF_TXWINSIZE        32
+#define MWIFIEX_AMPDU_DEF_RXWINSIZE        16
+#define MWIFIEX_DEFAULT_BLOCK_ACK_TIMEOUT  0xffff
+
+#define MWIFIEX_RATE_INDEX_HRDSSS0 0
+#define MWIFIEX_RATE_INDEX_HRDSSS3 3
+#define MWIFIEX_RATE_INDEX_OFDM0   4
+#define MWIFIEX_RATE_INDEX_OFDM7   11
+#define MWIFIEX_RATE_INDEX_MCS0    12
+
+#define MWIFIEX_RATE_BITMAP_OFDM0  16
+#define MWIFIEX_RATE_BITMAP_OFDM7  23
+#define MWIFIEX_RATE_BITMAP_MCS0   32
+#define MWIFIEX_RATE_BITMAP_MCS127 159
+
+#define MWIFIEX_RX_DATA_BUF_SIZE     (4 * 1024)
+
+#define MWIFIEX_RTS_MIN_VALUE              (0)
+#define MWIFIEX_RTS_MAX_VALUE              (2347)
+#define MWIFIEX_FRAG_MIN_VALUE             (256)
+#define MWIFIEX_FRAG_MAX_VALUE             (2346)
+
+#define MWIFIEX_SDIO_BLOCK_SIZE            256
+
+#define MWIFIEX_BUF_FLAG_REQUEUED_PKT      BIT(0)
+
+enum mwifiex_bss_type {
+	MWIFIEX_BSS_TYPE_STA = 0,
+	MWIFIEX_BSS_TYPE_UAP = 1,
+	MWIFIEX_BSS_TYPE_ANY = 0xff,
+};
+
+enum mwifiex_bss_role {
+	MWIFIEX_BSS_ROLE_STA = 0,
+	MWIFIEX_BSS_ROLE_UAP = 1,
+	MWIFIEX_BSS_ROLE_ANY = 0xff,
+};
+
+#define BSS_ROLE_BIT_MASK    BIT(0)
+
+#define GET_BSS_ROLE(priv)   ((priv)->bss_role & BSS_ROLE_BIT_MASK)
+
+enum mwifiex_data_frame_type {
+	MWIFIEX_DATA_FRAME_TYPE_ETH_II = 0,
+	MWIFIEX_DATA_FRAME_TYPE_802_11,
+};
+
+struct mwifiex_fw_image {
+	u8 *helper_buf;
+	u32 helper_len;
+	u8 *fw_buf;
+	u32 fw_len;
+};
+
+struct mwifiex_802_11_ssid {
+	u32 ssid_len;
+	u8 ssid[IEEE80211_MAX_SSID_LEN];
+};
+
+struct mwifiex_wait_queue {
+	wait_queue_head_t wait;
+	u16 condition;
+	int status;
+};
+
+struct mwifiex_rxinfo {
+	u8 bss_index;
+	struct sk_buff *parent;
+	u8 use_count;
+};
+
+struct mwifiex_txinfo {
+	u32 status_code;
+	u8 flags;
+	u8 bss_index;
+};
+
+struct mwifiex_bss_attr {
+	u8 bss_type;
+	u8 frame_type;
+	u8 active;
+	u8 bss_priority;
+	u8 bss_num;
+};
+
+enum mwifiex_wmm_ac_e {
+	WMM_AC_BK,
+	WMM_AC_BE,
+	WMM_AC_VI,
+	WMM_AC_VO
+} __packed;
+#endif /* !_MWIFIEX_DECL_H_ */
diff -druN linux-2.6.39-libre/drivers/net/wireless/mwifiex/fw.h linux-3.0-rc7-libre/drivers/net/wireless/mwifiex/fw.h
--- linux-2.6.39-libre/drivers/net/wireless/mwifiex/fw.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/net/wireless/mwifiex/fw.h	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,1187 @@
+/*
+ * Marvell Wireless LAN device driver: Firmware specific macros & structures
+ *
+ * Copyright (C) 2011, Marvell International Ltd.
+ *
+ * This software file (the "File") is distributed by Marvell International
+ * Ltd. under the terms of the GNU General Public License Version 2, June 1991
+ * (the "License").  You may use, redistribute and/or modify this File in
+ * accordance with the terms and conditions of the License, a copy of which
+ * is available by writing to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
+ * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
+ *
+ * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
+ * ARE EXPRESSLY DISCLAIMED.  The License provides additional details about
+ * this warranty disclaimer.
+ */
+
+#ifndef _MWIFIEX_FW_H_
+#define _MWIFIEX_FW_H_
+
+#include <linux/if_ether.h>
+
+
+#define INTF_HEADER_LEN     4
+
+struct rfc_1042_hdr {
+	u8 llc_dsap;
+	u8 llc_ssap;
+	u8 llc_ctrl;
+	u8 snap_oui[3];
+	u16 snap_type;
+};
+
+struct rx_packet_hdr {
+	struct ethhdr eth803_hdr;
+	struct rfc_1042_hdr rfc1042_hdr;
+};
+
+struct tx_packet_hdr {
+	struct ethhdr eth803_hdr;
+	struct rfc_1042_hdr rfc1042_hdr;
+};
+
+#define B_SUPPORTED_RATES               5
+#define G_SUPPORTED_RATES               9
+#define BG_SUPPORTED_RATES              13
+#define A_SUPPORTED_RATES               9
+#define HOSTCMD_SUPPORTED_RATES         14
+#define N_SUPPORTED_RATES               3
+#define ALL_802_11_BANDS           (BAND_A | BAND_B | BAND_G | BAND_GN)
+
+#define FW_MULTI_BANDS_SUPPORT  (BIT(8) | BIT(9) | BIT(10) | BIT(11))
+#define IS_SUPPORT_MULTI_BANDS(adapter)        \
+	(adapter->fw_cap_info & FW_MULTI_BANDS_SUPPORT)
+#define GET_FW_DEFAULT_BANDS(adapter)  \
+	((adapter->fw_cap_info >> 8) & ALL_802_11_BANDS)
+
+extern u8 supported_rates_b[B_SUPPORTED_RATES];
+extern u8 supported_rates_g[G_SUPPORTED_RATES];
+extern u8 supported_rates_bg[BG_SUPPORTED_RATES];
+extern u8 supported_rates_a[A_SUPPORTED_RATES];
+extern u8 supported_rates_n[N_SUPPORTED_RATES];
+
+#define HostCmd_WEP_KEY_INDEX_MASK              0x3fff
+
+#define KEY_INFO_ENABLED        0x01
+enum KEY_TYPE_ID {
+	KEY_TYPE_ID_WEP = 0,
+	KEY_TYPE_ID_TKIP,
+	KEY_TYPE_ID_AES,
+	KEY_TYPE_ID_WAPI,
+};
+#define KEY_MCAST	BIT(0)
+#define KEY_UNICAST	BIT(1)
+#define KEY_ENABLED	BIT(2)
+
+#define WAPI_KEY_LEN			50
+
+#define MAX_POLL_TRIES			100
+
+#define MAX_MULTI_INTERFACE_POLL_TRIES  1000
+
+#define MAX_FIRMWARE_POLL_TRIES			100
+
+#define FIRMWARE_READY				0xfedc
+
+enum MWIFIEX_802_11_PRIVACY_FILTER {
+	MWIFIEX_802_11_PRIV_FILTER_ACCEPT_ALL,
+	MWIFIEX_802_11_PRIV_FILTER_8021X_WEP
+};
+
+enum MWIFIEX_802_11_WEP_STATUS {
+	MWIFIEX_802_11_WEP_ENABLED,
+	MWIFIEX_802_11_WEP_DISABLED,
+};
+
+#define CAL_SNR(RSSI, NF)		((s16)((s16)(RSSI)-(s16)(NF)))
+
+#define PROPRIETARY_TLV_BASE_ID                 0x0100
+#define TLV_TYPE_KEY_MATERIAL       (PROPRIETARY_TLV_BASE_ID + 0)
+#define TLV_TYPE_CHANLIST           (PROPRIETARY_TLV_BASE_ID + 1)
+#define TLV_TYPE_NUMPROBES          (PROPRIETARY_TLV_BASE_ID + 2)
+#define TLV_TYPE_PASSTHROUGH        (PROPRIETARY_TLV_BASE_ID + 10)
+#define TLV_TYPE_WMMQSTATUS         (PROPRIETARY_TLV_BASE_ID + 16)
+#define TLV_TYPE_WILDCARDSSID       (PROPRIETARY_TLV_BASE_ID + 18)
+#define TLV_TYPE_TSFTIMESTAMP       (PROPRIETARY_TLV_BASE_ID + 19)
+#define TLV_TYPE_AUTH_TYPE          (PROPRIETARY_TLV_BASE_ID + 31)
+#define TLV_TYPE_CHANNELBANDLIST    (PROPRIETARY_TLV_BASE_ID + 42)
+#define TLV_TYPE_RATE_DROP_CONTROL  (PROPRIETARY_TLV_BASE_ID + 82)
+#define TLV_TYPE_RATE_SCOPE         (PROPRIETARY_TLV_BASE_ID + 83)
+#define TLV_TYPE_POWER_GROUP        (PROPRIETARY_TLV_BASE_ID + 84)
+#define TLV_TYPE_WAPI_IE            (PROPRIETARY_TLV_BASE_ID + 94)
+#define TLV_TYPE_AUTO_DS_PARAM      (PROPRIETARY_TLV_BASE_ID + 113)
+#define TLV_TYPE_PS_PARAM           (PROPRIETARY_TLV_BASE_ID + 114)
+
+#define MWIFIEX_TX_DATA_BUF_SIZE_2K        2048
+
+#define SSN_MASK         0xfff0
+
+#define BA_RESULT_SUCCESS        0x0
+#define BA_RESULT_TIMEOUT        0x2
+
+#define IS_BASTREAM_SETUP(ptr)  (ptr->ba_status)
+
+#define BA_STREAM_NOT_ALLOWED   0xff
+
+#define IS_11N_ENABLED(priv) ((priv->adapter->config_bands & BAND_GN || \
+			priv->adapter->config_bands & BAND_AN) \
+			&& priv->curr_bss_params.bss_descriptor.bcn_ht_cap)
+#define INITIATOR_BIT(DelBAParamSet) (((DelBAParamSet) &\
+			BIT(DELBA_INITIATOR_POS)) >> DELBA_INITIATOR_POS)
+
+#define MWIFIEX_TX_DATA_BUF_SIZE_4K        4096
+#define MWIFIEX_TX_DATA_BUF_SIZE_8K        8192
+
+#define ISSUPP_11NENABLED(FwCapInfo) (FwCapInfo & BIT(11))
+
+/* dev_cap bitmap
+ * BIT
+ * 0-16		reserved
+ * 17		IEEE80211_HT_CAP_SUP_WIDTH_20_40
+ * 18-22	reserved
+ * 23		IEEE80211_HT_CAP_SGI_20
+ * 24		IEEE80211_HT_CAP_SGI_40
+ * 25		IEEE80211_HT_CAP_TX_STBC
+ * 26		IEEE80211_HT_CAP_RX_STBC
+ * 27-28	reserved
+ * 29		IEEE80211_HT_CAP_GRN_FLD
+ * 30-31	reserved
+ */
+#define ISSUPP_CHANWIDTH40(Dot11nDevCap) (Dot11nDevCap & BIT(17))
+#define ISSUPP_SHORTGI20(Dot11nDevCap) (Dot11nDevCap & BIT(23))
+#define ISSUPP_SHORTGI40(Dot11nDevCap) (Dot11nDevCap & BIT(24))
+#define ISSUPP_TXSTBC(Dot11nDevCap) (Dot11nDevCap & BIT(25))
+#define ISSUPP_RXSTBC(Dot11nDevCap) (Dot11nDevCap & BIT(26))
+#define ISSUPP_GREENFIELD(Dot11nDevCap) (Dot11nDevCap & BIT(29))
+
+#define GET_RXMCSSUPP(DevMCSSupported) (DevMCSSupported & 0x0f)
+#define SETHT_MCS32(x) (x[4] |= 1)
+
+#define SET_SECONDARYCHAN(RadioType, SECCHAN) (RadioType |= (SECCHAN << 4))
+
+#define LLC_SNAP_LEN    8
+
+#define MOD_CLASS_HR_DSSS       0x03
+#define MOD_CLASS_OFDM          0x07
+#define MOD_CLASS_HT            0x08
+#define HT_BW_20    0
+#define HT_BW_40    1
+
+#define HostCmd_CMD_GET_HW_SPEC                       0x0003
+#define HostCmd_CMD_802_11_SCAN                       0x0006
+#define HostCmd_CMD_802_11_GET_LOG                    0x000b
+#define HostCmd_CMD_MAC_MULTICAST_ADR                 0x0010
+#define HostCmd_CMD_802_11_EEPROM_ACCESS              0x0059
+#define HostCmd_CMD_802_11_ASSOCIATE                  0x0012
+#define HostCmd_CMD_802_11_SNMP_MIB                   0x0016
+#define HostCmd_CMD_MAC_REG_ACCESS                    0x0019
+#define HostCmd_CMD_BBP_REG_ACCESS                    0x001a
+#define HostCmd_CMD_RF_REG_ACCESS                     0x001b
+#define HostCmd_CMD_PMIC_REG_ACCESS                   0x00ad
+#define HostCmd_CMD_802_11_RF_CHANNEL                 0x001d
+#define HostCmd_CMD_802_11_DEAUTHENTICATE             0x0024
+#define HostCmd_CMD_MAC_CONTROL                       0x0028
+#define HostCmd_CMD_802_11_AD_HOC_START               0x002b
+#define HostCmd_CMD_802_11_AD_HOC_JOIN                0x002c
+#define HostCmd_CMD_802_11_AD_HOC_STOP                0x0040
+#define HostCmd_CMD_802_11_MAC_ADDRESS                0x004D
+#define HostCmd_CMD_802_11D_DOMAIN_INFO               0x005b
+#define HostCmd_CMD_802_11_KEY_MATERIAL               0x005e
+#define HostCmd_CMD_802_11_BG_SCAN_QUERY              0x006c
+#define HostCmd_CMD_WMM_GET_STATUS                    0x0071
+#define HostCmd_CMD_802_11_TX_RATE_QUERY              0x007f
+#define HostCmd_CMD_802_11_IBSS_COALESCING_STATUS     0x0083
+#define HostCmd_CMD_VERSION_EXT                       0x0097
+#define HostCmd_CMD_RSSI_INFO                         0x00a4
+#define HostCmd_CMD_FUNC_INIT                         0x00a9
+#define HostCmd_CMD_FUNC_SHUTDOWN                     0x00aa
+#define HostCmd_CMD_11N_CFG                           0x00cd
+#define HostCmd_CMD_11N_ADDBA_REQ                     0x00ce
+#define HostCmd_CMD_11N_ADDBA_RSP                     0x00cf
+#define HostCmd_CMD_11N_DELBA                         0x00d0
+#define HostCmd_CMD_RECONFIGURE_TX_BUFF               0x00d9
+#define HostCmd_CMD_AMSDU_AGGR_CTRL                   0x00df
+#define HostCmd_CMD_TXPWR_CFG                         0x00d1
+#define HostCmd_CMD_TX_RATE_CFG                       0x00d6
+#define HostCmd_CMD_802_11_PS_MODE_ENH                0x00e4
+#define HostCmd_CMD_802_11_HS_CFG_ENH                 0x00e5
+#define HostCmd_CMD_CAU_REG_ACCESS                    0x00ed
+#define HostCmd_CMD_SET_BSS_MODE                      0x00f7
+
+
+enum ENH_PS_MODES {
+	EN_PS = 1,
+	DIS_PS = 2,
+	EN_AUTO_DS = 3,
+	DIS_AUTO_DS = 4,
+	SLEEP_CONFIRM = 5,
+	GET_PS = 0,
+	EN_AUTO_PS = 0xff,
+	DIS_AUTO_PS = 0xfe,
+};
+
+#define HostCmd_RET_BIT                       0x8000
+#define HostCmd_ACT_GEN_GET                   0x0000
+#define HostCmd_ACT_GEN_SET                   0x0001
+#define HostCmd_RESULT_OK                     0x0000
+
+#define HostCmd_ACT_MAC_RX_ON                 0x0001
+#define HostCmd_ACT_MAC_TX_ON                 0x0002
+#define HostCmd_ACT_MAC_WEP_ENABLE            0x0008
+#define HostCmd_ACT_MAC_ETHERNETII_ENABLE     0x0010
+#define HostCmd_ACT_MAC_PROMISCUOUS_ENABLE    0x0080
+#define HostCmd_ACT_MAC_ALL_MULTICAST_ENABLE  0x0100
+#define HostCmd_ACT_MAC_ADHOC_G_PROTECTION_ON     0x2000
+
+#define HostCmd_BSS_MODE_IBSS               0x0002
+#define HostCmd_BSS_MODE_ANY                0x0003
+
+#define HostCmd_SCAN_RADIO_TYPE_BG          0
+#define HostCmd_SCAN_RADIO_TYPE_A           1
+
+#define HOST_SLEEP_CFG_CANCEL		0xffffffff
+#define HOST_SLEEP_CFG_COND_DEF		0x0000000f
+#define HOST_SLEEP_CFG_GPIO_DEF		0xff
+#define HOST_SLEEP_CFG_GAP_DEF		0
+
+#define CMD_F_HOSTCMD           (1 << 0)
+#define CMD_F_CANCELED          (1 << 1)
+
+#define HostCmd_CMD_ID_MASK             0x0fff
+
+#define HostCmd_SEQ_NUM_MASK            0x00ff
+
+#define HostCmd_BSS_NUM_MASK            0x0f00
+
+#define HostCmd_BSS_TYPE_MASK           0xf000
+
+#define HostCmd_SET_SEQ_NO_BSS_INFO(seq, num, type) {   \
+	(((seq) & 0x00ff) |                             \
+	 (((num) & 0x000f) << 8)) |                     \
+	(((type) & 0x000f) << 12);                  }
+
+#define HostCmd_GET_SEQ_NO(seq)       \
+	((seq) & HostCmd_SEQ_NUM_MASK)
+
+#define HostCmd_GET_BSS_NO(seq)         \
+	(((seq) & HostCmd_BSS_NUM_MASK) >> 8)
+
+#define HostCmd_GET_BSS_TYPE(seq)       \
+	(((seq) & HostCmd_BSS_TYPE_MASK) >> 12)
+
+#define EVENT_DUMMY_HOST_WAKEUP_SIGNAL  0x00000001
+#define EVENT_LINK_LOST                 0x00000003
+#define EVENT_LINK_SENSED               0x00000004
+#define EVENT_MIB_CHANGED               0x00000006
+#define EVENT_INIT_DONE                 0x00000007
+#define EVENT_DEAUTHENTICATED           0x00000008
+#define EVENT_DISASSOCIATED             0x00000009
+#define EVENT_PS_AWAKE                  0x0000000a
+#define EVENT_PS_SLEEP                  0x0000000b
+#define EVENT_MIC_ERR_MULTICAST         0x0000000d
+#define EVENT_MIC_ERR_UNICAST           0x0000000e
+#define EVENT_DEEP_SLEEP_AWAKE          0x00000010
+#define EVENT_ADHOC_BCN_LOST            0x00000011
+
+#define EVENT_WMM_STATUS_CHANGE         0x00000017
+#define EVENT_BG_SCAN_REPORT            0x00000018
+#define EVENT_RSSI_LOW                  0x00000019
+#define EVENT_SNR_LOW                   0x0000001a
+#define EVENT_MAX_FAIL                  0x0000001b
+#define EVENT_RSSI_HIGH                 0x0000001c
+#define EVENT_SNR_HIGH                  0x0000001d
+#define EVENT_IBSS_COALESCED            0x0000001e
+#define EVENT_DATA_RSSI_LOW             0x00000024
+#define EVENT_DATA_SNR_LOW              0x00000025
+#define EVENT_DATA_RSSI_HIGH            0x00000026
+#define EVENT_DATA_SNR_HIGH             0x00000027
+#define EVENT_LINK_QUALITY              0x00000028
+#define EVENT_PORT_RELEASE              0x0000002b
+#define EVENT_PRE_BEACON_LOST           0x00000031
+#define EVENT_ADDBA                     0x00000033
+#define EVENT_DELBA                     0x00000034
+#define EVENT_BA_STREAM_TIEMOUT         0x00000037
+#define EVENT_AMSDU_AGGR_CTRL           0x00000042
+#define EVENT_WEP_ICV_ERR               0x00000046
+#define EVENT_HS_ACT_REQ                0x00000047
+#define EVENT_BW_CHANGE                 0x00000048
+
+#define EVENT_HOSTWAKE_STAIE		0x0000004d
+
+#define EVENT_ID_MASK                   0xffff
+#define BSS_NUM_MASK                    0xf
+
+#define EVENT_GET_BSS_NUM(event_cause)          \
+	(((event_cause) >> 16) & BSS_NUM_MASK)
+
+#define EVENT_GET_BSS_TYPE(event_cause)         \
+	(((event_cause) >> 24) & 0x00ff)
+
+struct mwifiex_ie_types_header {
+	__le16 type;
+	__le16 len;
+} __packed;
+
+struct mwifiex_ie_types_data {
+	struct mwifiex_ie_types_header header;
+	u8 data[1];
+} __packed;
+
+#define MWIFIEX_TxPD_POWER_MGMT_NULL_PACKET 0x01
+#define MWIFIEX_TxPD_POWER_MGMT_LAST_PACKET 0x08
+
+struct txpd {
+	u8 bss_type;
+	u8 bss_num;
+	__le16 tx_pkt_length;
+	__le16 tx_pkt_offset;
+	__le16 tx_pkt_type;
+	__le32 tx_control;
+	u8 priority;
+	u8 flags;
+	u8 pkt_delay_2ms;
+	u8 reserved1;
+} __packed;
+
+struct rxpd {
+	u8 bss_type;
+	u8 bss_num;
+	u16 rx_pkt_length;
+	u16 rx_pkt_offset;
+	u16 rx_pkt_type;
+	u16 seq_num;
+	u8 priority;
+	u8 rx_rate;
+	s8 snr;
+	s8 nf;
+	/* Ht Info [Bit 0] RxRate format: LG=0, HT=1
+	 * [Bit 1]  HT Bandwidth: BW20 = 0, BW40 = 1
+	 * [Bit 2]  HT Guard Interval: LGI = 0, SGI = 1 */
+	u8 ht_info;
+	u8 reserved;
+} __packed;
+
+enum mwifiex_chan_scan_mode_bitmasks {
+	MWIFIEX_PASSIVE_SCAN = BIT(0),
+	MWIFIEX_DISABLE_CHAN_FILT = BIT(1),
+};
+
+#define SECOND_CHANNEL_BELOW    0x30
+#define SECOND_CHANNEL_ABOVE    0x10
+struct mwifiex_chan_scan_param_set {
+	u8 radio_type;
+	u8 chan_number;
+	u8 chan_scan_mode_bitmap;
+	__le16 min_scan_time;
+	__le16 max_scan_time;
+} __packed;
+
+struct mwifiex_ie_types_chan_list_param_set {
+	struct mwifiex_ie_types_header header;
+	struct mwifiex_chan_scan_param_set chan_scan_param[1];
+} __packed;
+
+struct chan_band_param_set {
+	u8 radio_type;
+	u8 chan_number;
+};
+
+struct mwifiex_ie_types_chan_band_list_param_set {
+	struct mwifiex_ie_types_header header;
+	struct chan_band_param_set chan_band_param[1];
+} __packed;
+
+struct mwifiex_ie_types_rates_param_set {
+	struct mwifiex_ie_types_header header;
+	u8 rates[1];
+} __packed;
+
+struct mwifiex_ie_types_ssid_param_set {
+	struct mwifiex_ie_types_header header;
+	u8 ssid[1];
+} __packed;
+
+struct mwifiex_ie_types_num_probes {
+	struct mwifiex_ie_types_header header;
+	__le16 num_probes;
+} __packed;
+
+struct mwifiex_ie_types_wildcard_ssid_params {
+	struct mwifiex_ie_types_header header;
+	u8 max_ssid_length;
+	u8 ssid[1];
+} __packed;
+
+#define TSF_DATA_SIZE            8
+struct mwifiex_ie_types_tsf_timestamp {
+	struct mwifiex_ie_types_header header;
+	u8 tsf_data[1];
+} __packed;
+
+struct mwifiex_cf_param_set {
+	u8 cfp_cnt;
+	u8 cfp_period;
+	u16 cfp_max_duration;
+	u16 cfp_duration_remaining;
+} __packed;
+
+struct mwifiex_ibss_param_set {
+	u16 atim_window;
+} __packed;
+
+struct mwifiex_ie_types_ss_param_set {
+	struct mwifiex_ie_types_header header;
+	union {
+		struct mwifiex_cf_param_set cf_param_set[1];
+		struct mwifiex_ibss_param_set ibss_param_set[1];
+	} cf_ibss;
+} __packed;
+
+struct mwifiex_fh_param_set {
+	u16 dwell_time;
+	u8 hop_set;
+	u8 hop_pattern;
+	u8 hop_index;
+} __packed;
+
+struct mwifiex_ds_param_set {
+	u8 current_chan;
+} __packed;
+
+struct mwifiex_ie_types_phy_param_set {
+	struct mwifiex_ie_types_header header;
+	union {
+		struct mwifiex_fh_param_set fh_param_set[1];
+		struct mwifiex_ds_param_set ds_param_set[1];
+	} fh_ds;
+} __packed;
+
+struct mwifiex_ie_types_auth_type {
+	struct mwifiex_ie_types_header header;
+	__le16 auth_type;
+} __packed;
+
+struct mwifiex_ie_types_vendor_param_set {
+	struct mwifiex_ie_types_header header;
+	u8 ie[MWIFIEX_MAX_VSIE_LEN];
+};
+
+struct mwifiex_ie_types_rsn_param_set {
+	struct mwifiex_ie_types_header header;
+	u8 rsn_ie[1];
+} __packed;
+
+#define KEYPARAMSET_FIXED_LEN 6
+
+struct mwifiex_ie_type_key_param_set {
+	__le16 type;
+	__le16 length;
+	__le16 key_type_id;
+	__le16 key_info;
+	__le16 key_len;
+	u8 key[50];
+} __packed;
+
+struct host_cmd_ds_802_11_key_material {
+	__le16 action;
+	struct mwifiex_ie_type_key_param_set key_param_set;
+} __packed;
+
+struct host_cmd_ds_gen {
+	u16 command;
+	u16 size;
+	u16 seq_num;
+	u16 result;
+};
+
+#define S_DS_GEN        sizeof(struct host_cmd_ds_gen)
+
+enum sleep_resp_ctrl {
+	RESP_NOT_NEEDED = 0,
+	RESP_NEEDED,
+};
+
+struct mwifiex_ps_param {
+	__le16 null_pkt_interval;
+	__le16 multiple_dtims;
+	__le16 bcn_miss_timeout;
+	__le16 local_listen_interval;
+	__le16 adhoc_wake_period;
+	__le16 mode;
+	__le16 delay_to_ps;
+};
+
+#define BITMAP_AUTO_DS         0x01
+#define BITMAP_STA_PS          0x10
+
+struct mwifiex_ie_types_auto_ds_param {
+	struct mwifiex_ie_types_header header;
+	__le16 deep_sleep_timeout;
+} __packed;
+
+struct mwifiex_ie_types_ps_param {
+	struct mwifiex_ie_types_header header;
+	struct mwifiex_ps_param param;
+} __packed;
+
+struct host_cmd_ds_802_11_ps_mode_enh {
+	__le16 action;
+
+	union {
+		struct mwifiex_ps_param opt_ps;
+		__le16 ps_bitmap;
+	} params;
+} __packed;
+
+struct host_cmd_ds_get_hw_spec {
+	__le16 hw_if_version;
+	__le16 version;
+	__le16 reserved;
+	__le16 num_of_mcast_adr;
+	u8 permanent_addr[ETH_ALEN];
+	__le16 region_code;
+	__le16 number_of_antenna;
+	__le32 fw_release_number;
+	__le32 reserved_1;
+	__le32 reserved_2;
+	__le32 reserved_3;
+	__le32 fw_cap_info;
+	__le32 dot_11n_dev_cap;
+	u8 dev_mcs_support;
+	__le16 mp_end_port;	/* SDIO only, reserved for other interfacces */
+	__le16 reserved_4;
+} __packed;
+
+struct host_cmd_ds_802_11_rssi_info {
+	__le16 action;
+	__le16 ndata;
+	__le16 nbcn;
+	__le16 reserved[9];
+	long long reserved_1;
+};
+
+struct host_cmd_ds_802_11_rssi_info_rsp {
+	__le16 action;
+	__le16 ndata;
+	__le16 nbcn;
+	__le16 data_rssi_last;
+	__le16 data_nf_last;
+	__le16 data_rssi_avg;
+	__le16 data_nf_avg;
+	__le16 bcn_rssi_last;
+	__le16 bcn_nf_last;
+	__le16 bcn_rssi_avg;
+	__le16 bcn_nf_avg;
+	long long tsf_bcn;
+};
+
+struct host_cmd_ds_802_11_mac_address {
+	__le16 action;
+	u8 mac_addr[ETH_ALEN];
+};
+
+struct host_cmd_ds_mac_control {
+	__le16 action;
+	__le16 reserved;
+};
+
+struct host_cmd_ds_mac_multicast_adr {
+	__le16 action;
+	__le16 num_of_adrs;
+	u8 mac_list[MWIFIEX_MAX_MULTICAST_LIST_SIZE][ETH_ALEN];
+} __packed;
+
+struct host_cmd_ds_802_11_deauthenticate {
+	u8 mac_addr[ETH_ALEN];
+	__le16 reason_code;
+} __packed;
+
+struct host_cmd_ds_802_11_associate {
+	u8 peer_sta_addr[ETH_ALEN];
+	__le16 cap_info_bitmap;
+	__le16 listen_interval;
+	__le16 beacon_period;
+	u8 dtim_period;
+} __packed;
+
+struct ieee_types_assoc_rsp {
+	__le16 cap_info_bitmap;
+	__le16 status_code;
+	__le16 a_id;
+	u8 ie_buffer[1];
+} __packed;
+
+struct host_cmd_ds_802_11_associate_rsp {
+	struct ieee_types_assoc_rsp assoc_rsp;
+} __packed;
+
+struct ieee_types_cf_param_set {
+	u8 element_id;
+	u8 len;
+	u8 cfp_cnt;
+	u8 cfp_period;
+	u16 cfp_max_duration;
+	u16 cfp_duration_remaining;
+} __packed;
+
+struct ieee_types_ibss_param_set {
+	u8 element_id;
+	u8 len;
+	__le16 atim_window;
+} __packed;
+
+union ieee_types_ss_param_set {
+	struct ieee_types_cf_param_set cf_param_set;
+	struct ieee_types_ibss_param_set ibss_param_set;
+} __packed;
+
+struct ieee_types_fh_param_set {
+	u8 element_id;
+	u8 len;
+	__le16 dwell_time;
+	u8 hop_set;
+	u8 hop_pattern;
+	u8 hop_index;
+} __packed;
+
+struct ieee_types_ds_param_set {
+	u8 element_id;
+	u8 len;
+	u8 current_chan;
+} __packed;
+
+union ieee_types_phy_param_set {
+	struct ieee_types_fh_param_set fh_param_set;
+	struct ieee_types_ds_param_set ds_param_set;
+} __packed;
+
+struct host_cmd_ds_802_11_ad_hoc_start {
+	u8 ssid[IEEE80211_MAX_SSID_LEN];
+	u8 bss_mode;
+	__le16 beacon_period;
+	u8 dtim_period;
+	union ieee_types_ss_param_set ss_param_set;
+	union ieee_types_phy_param_set phy_param_set;
+	u16 reserved1;
+	__le16 cap_info_bitmap;
+	u8 DataRate[HOSTCMD_SUPPORTED_RATES];
+} __packed;
+
+struct host_cmd_ds_802_11_ad_hoc_result {
+	u8 pad[3];
+	u8 bssid[ETH_ALEN];
+} __packed;
+
+struct adhoc_bss_desc {
+	u8 bssid[ETH_ALEN];
+	u8 ssid[IEEE80211_MAX_SSID_LEN];
+	u8 bss_mode;
+	__le16 beacon_period;
+	u8 dtim_period;
+	u8 time_stamp[8];
+	u8 local_time[8];
+	union ieee_types_phy_param_set phy_param_set;
+	union ieee_types_ss_param_set ss_param_set;
+	__le16 cap_info_bitmap;
+	u8 data_rates[HOSTCMD_SUPPORTED_RATES];
+
+	/*
+	 *  DO NOT ADD ANY FIELDS TO THIS STRUCTURE.
+	 *  It is used in the Adhoc join command and will cause a
+	 *  binary layout mismatch with the firmware
+	 */
+} __packed;
+
+struct host_cmd_ds_802_11_ad_hoc_join {
+	struct adhoc_bss_desc bss_descriptor;
+	u16 reserved1;
+	u16 reserved2;
+} __packed;
+
+struct host_cmd_ds_802_11_get_log {
+	__le32 mcast_tx_frame;
+	__le32 failed;
+	__le32 retry;
+	__le32 multi_retry;
+	__le32 frame_dup;
+	__le32 rts_success;
+	__le32 rts_failure;
+	__le32 ack_failure;
+	__le32 rx_frag;
+	__le32 mcast_rx_frame;
+	__le32 fcs_error;
+	__le32 tx_frame;
+	__le32 reserved;
+	__le32 wep_icv_err_cnt[4];
+};
+
+struct host_cmd_ds_tx_rate_query {
+	u8 tx_rate;
+	/* Ht Info [Bit 0] RxRate format: LG=0, HT=1
+	 * [Bit 1]  HT Bandwidth: BW20 = 0, BW40 = 1
+	 * [Bit 2]  HT Guard Interval: LGI = 0, SGI = 1 */
+	u8 ht_info;
+} __packed;
+
+enum Host_Sleep_Action {
+	HS_CONFIGURE = 0x0001,
+	HS_ACTIVATE  = 0x0002,
+};
+
+struct mwifiex_hs_config_param {
+	__le32 conditions;
+	u8 gpio;
+	u8 gap;
+} __packed;
+
+struct hs_activate_param {
+	u16 resp_ctrl;
+} __packed;
+
+struct host_cmd_ds_802_11_hs_cfg_enh {
+	__le16 action;
+
+	union {
+		struct mwifiex_hs_config_param hs_config;
+		struct hs_activate_param hs_activate;
+	} params;
+} __packed;
+
+enum SNMP_MIB_INDEX {
+	OP_RATE_SET_I = 1,
+	DTIM_PERIOD_I = 3,
+	RTS_THRESH_I = 5,
+	SHORT_RETRY_LIM_I = 6,
+	LONG_RETRY_LIM_I = 7,
+	FRAG_THRESH_I = 8,
+	DOT11D_I = 9,
+};
+
+#define MAX_SNMP_BUF_SIZE   128
+
+struct host_cmd_ds_802_11_snmp_mib {
+	__le16 query_type;
+	__le16 oid;
+	__le16 buf_size;
+	u8 value[1];
+} __packed;
+
+struct mwifiex_rate_scope {
+	__le16 type;
+	__le16 length;
+	__le16 hr_dsss_rate_bitmap;
+	__le16 ofdm_rate_bitmap;
+	__le16 ht_mcs_rate_bitmap[8];
+} __packed;
+
+struct mwifiex_rate_drop_pattern {
+	__le16 type;
+	__le16 length;
+	__le32 rate_drop_mode;
+} __packed;
+
+struct host_cmd_ds_tx_rate_cfg {
+	__le16 action;
+	__le16 cfg_index;
+} __packed;
+
+struct mwifiex_power_group {
+	u8 modulation_class;
+	u8 first_rate_code;
+	u8 last_rate_code;
+	s8 power_step;
+	s8 power_min;
+	s8 power_max;
+	u8 ht_bandwidth;
+	u8 reserved;
+} __packed;
+
+struct mwifiex_types_power_group {
+	u16 type;
+	u16 length;
+} __packed;
+
+struct host_cmd_ds_txpwr_cfg {
+	__le16 action;
+	__le16 cfg_index;
+	__le32 mode;
+} __packed;
+
+#define MWIFIEX_USER_SCAN_CHAN_MAX             50
+
+#define MWIFIEX_MAX_SSID_LIST_LENGTH         10
+
+struct mwifiex_scan_cmd_config {
+	/*
+	 *  BSS mode to be sent in the firmware command
+	 */
+	u8 bss_mode;
+
+	/* Specific BSSID used to filter scan results in the firmware */
+	u8 specific_bssid[ETH_ALEN];
+
+	/* Length of TLVs sent in command starting at tlvBuffer */
+	u32 tlv_buf_len;
+
+	/*
+	 *  SSID TLV(s) and ChanList TLVs to be sent in the firmware command
+	 *
+	 *  TLV_TYPE_CHANLIST, mwifiex_ie_types_chan_list_param_set
+	 *  WLAN_EID_SSID, mwifiex_ie_types_ssid_param_set
+	 */
+	u8 tlv_buf[1];	/* SSID TLV(s) and ChanList TLVs are stored
+				   here */
+} __packed;
+
+struct mwifiex_user_scan_chan {
+	u8 chan_number;
+	u8 radio_type;
+	u8 scan_type;
+	u8 reserved;
+	u32 scan_time;
+} __packed;
+
+struct mwifiex_user_scan_ssid {
+	u8 ssid[IEEE80211_MAX_SSID_LEN + 1];
+	u8 max_len;
+} __packed;
+
+struct mwifiex_user_scan_cfg {
+	/*
+	 *  Flag set to keep the previous scan table intact
+	 *
+	 *  If set, the scan results will accumulate, replacing any previous
+	 *   matched entries for a BSS with the new scan data
+	 */
+	u8 keep_previous_scan;
+	/*
+	 *  BSS mode to be sent in the firmware command
+	 */
+	u8 bss_mode;
+	/* Configure the number of probe requests for active chan scans */
+	u8 num_probes;
+	u8 reserved;
+	/* BSSID filter sent in the firmware command to limit the results */
+	u8 specific_bssid[ETH_ALEN];
+	/* SSID filter list used in the to limit the scan results */
+	struct mwifiex_user_scan_ssid ssid_list[MWIFIEX_MAX_SSID_LIST_LENGTH];
+	/* Variable number (fixed maximum) of channels to scan up */
+	struct mwifiex_user_scan_chan chan_list[MWIFIEX_USER_SCAN_CHAN_MAX];
+} __packed;
+
+struct ie_body {
+	u8 grp_key_oui[4];
+	u8 ptk_cnt[2];
+	u8 ptk_body[4];
+} __packed;
+
+struct host_cmd_ds_802_11_scan {
+	u8 bss_mode;
+	u8 bssid[ETH_ALEN];
+	u8 tlv_buffer[1];
+} __packed;
+
+struct host_cmd_ds_802_11_scan_rsp {
+	__le16 bss_descript_size;
+	u8 number_of_sets;
+	u8 bss_desc_and_tlv_buffer[1];
+} __packed;
+
+struct host_cmd_ds_802_11_bg_scan_query {
+	u8 flush;
+} __packed;
+
+struct host_cmd_ds_802_11_bg_scan_query_rsp {
+	u32 report_condition;
+	struct host_cmd_ds_802_11_scan_rsp scan_resp;
+} __packed;
+
+struct mwifiex_ietypes_domain_param_set {
+	struct mwifiex_ie_types_header header;
+	u8 country_code[IEEE80211_COUNTRY_STRING_LEN];
+	struct ieee80211_country_ie_triplet triplet[1];
+} __packed;
+
+struct host_cmd_ds_802_11d_domain_info {
+	__le16 action;
+	struct mwifiex_ietypes_domain_param_set domain;
+} __packed;
+
+struct host_cmd_ds_802_11d_domain_info_rsp {
+	__le16 action;
+	struct mwifiex_ietypes_domain_param_set domain;
+} __packed;
+
+struct host_cmd_ds_11n_addba_req {
+	u8 add_req_result;
+	u8 peer_mac_addr[ETH_ALEN];
+	u8 dialog_token;
+	__le16 block_ack_param_set;
+	__le16 block_ack_tmo;
+	__le16 ssn;
+} __packed;
+
+struct host_cmd_ds_11n_addba_rsp {
+	u8 add_rsp_result;
+	u8 peer_mac_addr[ETH_ALEN];
+	u8 dialog_token;
+	__le16 status_code;
+	__le16 block_ack_param_set;
+	__le16 block_ack_tmo;
+	__le16 ssn;
+} __packed;
+
+struct host_cmd_ds_11n_delba {
+	u8 del_result;
+	u8 peer_mac_addr[ETH_ALEN];
+	__le16 del_ba_param_set;
+	__le16 reason_code;
+	u8 reserved;
+} __packed;
+
+struct host_cmd_ds_11n_batimeout {
+	u8 tid;
+	u8 peer_mac_addr[ETH_ALEN];
+	u8 origninator;
+} __packed;
+
+struct host_cmd_ds_11n_cfg {
+	__le16 action;
+	__le16 ht_tx_cap;
+	__le16 ht_tx_info;
+} __packed;
+
+struct host_cmd_ds_txbuf_cfg {
+	__le16 action;
+	__le16 buff_size;
+	__le16 mp_end_port;	/* SDIO only, reserved for other interfacces */
+	__le16 reserved3;
+} __packed;
+
+struct host_cmd_ds_amsdu_aggr_ctrl {
+	__le16 action;
+	__le16 enable;
+	__le16 curr_buf_size;
+} __packed;
+
+struct mwifiex_ie_types_wmm_param_set {
+	struct mwifiex_ie_types_header header;
+	u8 wmm_ie[1];
+};
+
+struct mwifiex_ie_types_wmm_queue_status {
+	struct mwifiex_ie_types_header header;
+	u8 queue_index;
+	u8 disabled;
+	u16 medium_time;
+	u8 flow_required;
+	u8 flow_created;
+	u32 reserved;
+};
+
+struct ieee_types_vendor_header {
+	u8 element_id;
+	u8 len;
+	u8 oui[3];
+	u8 oui_type;
+	u8 oui_subtype;
+	u8 version;
+} __packed;
+
+struct ieee_types_wmm_ac_parameters {
+	u8 aci_aifsn_bitmap;
+	u8 ecw_bitmap;
+	__le16 tx_op_limit;
+} __packed;
+
+struct ieee_types_wmm_parameter {
+	/*
+	 * WMM Parameter IE - Vendor Specific Header:
+	 *   element_id  [221/0xdd]
+	 *   Len         [24]
+	 *   Oui         [00:50:f2]
+	 *   OuiType     [2]
+	 *   OuiSubType  [1]
+	 *   Version     [1]
+	 */
+	struct ieee_types_vendor_header vend_hdr;
+	u8 qos_info_bitmap;
+	u8 reserved;
+	struct ieee_types_wmm_ac_parameters ac_params[IEEE80211_MAX_QUEUES];
+} __packed;
+
+struct ieee_types_wmm_info {
+
+	/*
+	 * WMM Info IE - Vendor Specific Header:
+	 *   element_id  [221/0xdd]
+	 *   Len         [7]
+	 *   Oui         [00:50:f2]
+	 *   OuiType     [2]
+	 *   OuiSubType  [0]
+	 *   Version     [1]
+	 */
+	struct ieee_types_vendor_header vend_hdr;
+
+	u8 qos_info_bitmap;
+} __packed;
+
+struct host_cmd_ds_wmm_get_status {
+	u8 queue_status_tlv[sizeof(struct mwifiex_ie_types_wmm_queue_status) *
+			      IEEE80211_MAX_QUEUES];
+	u8 wmm_param_tlv[sizeof(struct ieee_types_wmm_parameter) + 2];
+} __packed;
+
+struct mwifiex_wmm_ac_status {
+	u8 disabled;
+	u8 flow_required;
+	u8 flow_created;
+};
+
+struct mwifiex_ie_types_htcap {
+	struct mwifiex_ie_types_header header;
+	struct ieee80211_ht_cap ht_cap;
+} __packed;
+
+struct mwifiex_ie_types_htinfo {
+	struct mwifiex_ie_types_header header;
+	struct ieee80211_ht_info ht_info;
+} __packed;
+
+struct mwifiex_ie_types_2040bssco {
+	struct mwifiex_ie_types_header header;
+	u8 bss_co_2040;
+} __packed;
+
+struct mwifiex_ie_types_extcap {
+	struct mwifiex_ie_types_header header;
+	u8 ext_cap;
+} __packed;
+
+struct host_cmd_ds_mac_reg_access {
+	__le16 action;
+	__le16 offset;
+	__le32 value;
+} __packed;
+
+struct host_cmd_ds_bbp_reg_access {
+	__le16 action;
+	__le16 offset;
+	u8 value;
+	u8 reserved[3];
+} __packed;
+
+struct host_cmd_ds_rf_reg_access {
+	__le16 action;
+	__le16 offset;
+	u8 value;
+	u8 reserved[3];
+} __packed;
+
+struct host_cmd_ds_pmic_reg_access {
+	__le16 action;
+	__le16 offset;
+	u8 value;
+	u8 reserved[3];
+} __packed;
+
+struct host_cmd_ds_802_11_eeprom_access {
+	__le16 action;
+
+	__le16 offset;
+	__le16 byte_count;
+	u8 value;
+} __packed;
+
+struct host_cmd_ds_802_11_rf_channel {
+	__le16 action;
+	__le16 current_channel;
+	__le16 rf_type;
+	__le16 reserved;
+	u8 reserved_1[32];
+} __packed;
+
+struct host_cmd_ds_version_ext {
+	u8 version_str_sel;
+	char version_str[128];
+} __packed;
+
+struct host_cmd_ds_802_11_ibss_status {
+	__le16 action;
+	__le16 enable;
+	u8 bssid[ETH_ALEN];
+	__le16 beacon_interval;
+	__le16 atim_window;
+	__le16 use_g_rate_protect;
+} __packed;
+
+#define CONNECTION_TYPE_INFRA   0
+#define CONNECTION_TYPE_ADHOC   1
+
+struct host_cmd_ds_set_bss_mode {
+	u8 con_type;
+} __packed;
+
+struct host_cmd_ds_command {
+	__le16 command;
+	__le16 size;
+	__le16 seq_num;
+	__le16 result;
+	union {
+		struct host_cmd_ds_get_hw_spec hw_spec;
+		struct host_cmd_ds_mac_control mac_ctrl;
+		struct host_cmd_ds_802_11_mac_address mac_addr;
+		struct host_cmd_ds_mac_multicast_adr mc_addr;
+		struct host_cmd_ds_802_11_get_log get_log;
+		struct host_cmd_ds_802_11_rssi_info rssi_info;
+		struct host_cmd_ds_802_11_rssi_info_rsp rssi_info_rsp;
+		struct host_cmd_ds_802_11_snmp_mib smib;
+		struct host_cmd_ds_802_11_rf_channel rf_channel;
+		struct host_cmd_ds_tx_rate_query tx_rate;
+		struct host_cmd_ds_tx_rate_cfg tx_rate_cfg;
+		struct host_cmd_ds_txpwr_cfg txp_cfg;
+		struct host_cmd_ds_802_11_ps_mode_enh psmode_enh;
+		struct host_cmd_ds_802_11_hs_cfg_enh opt_hs_cfg;
+		struct host_cmd_ds_802_11_scan scan;
+		struct host_cmd_ds_802_11_scan_rsp scan_resp;
+		struct host_cmd_ds_802_11_bg_scan_query bg_scan_query;
+		struct host_cmd_ds_802_11_bg_scan_query_rsp bg_scan_query_resp;
+		struct host_cmd_ds_802_11_associate associate;
+		struct host_cmd_ds_802_11_associate_rsp associate_rsp;
+		struct host_cmd_ds_802_11_deauthenticate deauth;
+		struct host_cmd_ds_802_11_ad_hoc_start adhoc_start;
+		struct host_cmd_ds_802_11_ad_hoc_result adhoc_result;
+		struct host_cmd_ds_802_11_ad_hoc_join adhoc_join;
+		struct host_cmd_ds_802_11d_domain_info domain_info;
+		struct host_cmd_ds_802_11d_domain_info_rsp domain_info_resp;
+		struct host_cmd_ds_11n_addba_req add_ba_req;
+		struct host_cmd_ds_11n_addba_rsp add_ba_rsp;
+		struct host_cmd_ds_11n_delba del_ba;
+		struct host_cmd_ds_txbuf_cfg tx_buf;
+		struct host_cmd_ds_amsdu_aggr_ctrl amsdu_aggr_ctrl;
+		struct host_cmd_ds_11n_cfg htcfg;
+		struct host_cmd_ds_wmm_get_status get_wmm_status;
+		struct host_cmd_ds_802_11_key_material key_material;
+		struct host_cmd_ds_version_ext verext;
+		struct host_cmd_ds_802_11_ibss_status ibss_coalescing;
+		struct host_cmd_ds_mac_reg_access mac_reg;
+		struct host_cmd_ds_bbp_reg_access bbp_reg;
+		struct host_cmd_ds_rf_reg_access rf_reg;
+		struct host_cmd_ds_pmic_reg_access pmic_reg;
+		struct host_cmd_ds_set_bss_mode bss_mode;
+		struct host_cmd_ds_802_11_eeprom_access eeprom;
+	} params;
+} __packed;
+
+struct mwifiex_opt_sleep_confirm {
+	__le16 command;
+	__le16 size;
+	__le16 seq_num;
+	__le16 result;
+	__le16 action;
+	__le16 resp_ctrl;
+} __packed;
+#endif /* !_MWIFIEX_FW_H_ */
diff -druN linux-2.6.39-libre/drivers/net/wireless/mwifiex/init.c linux-3.0-rc7-libre/drivers/net/wireless/mwifiex/init.c
--- linux-2.6.39-libre/drivers/net/wireless/mwifiex/init.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/net/wireless/mwifiex/init.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,645 @@
+/*
+ * Marvell Wireless LAN device driver: HW/FW Initialization
+ *
+ * Copyright (C) 2011, Marvell International Ltd.
+ *
+ * This software file (the "File") is distributed by Marvell International
+ * Ltd. under the terms of the GNU General Public License Version 2, June 1991
+ * (the "License").  You may use, redistribute and/or modify this File in
+ * accordance with the terms and conditions of the License, a copy of which
+ * is available by writing to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
+ * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
+ *
+ * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
+ * ARE EXPRESSLY DISCLAIMED.  The License provides additional details about
+ * this warranty disclaimer.
+ */
+
+#include "decl.h"
+#include "ioctl.h"
+#include "util.h"
+#include "fw.h"
+#include "main.h"
+#include "wmm.h"
+#include "11n.h"
+
+/*
+ * This function adds a BSS priority table to the table list.
+ *
+ * The function allocates a new BSS priority table node and adds it to
+ * the end of BSS priority table list, kept in driver memory.
+ */
+static int mwifiex_add_bss_prio_tbl(struct mwifiex_private *priv)
+{
+	struct mwifiex_adapter *adapter = priv->adapter;
+	struct mwifiex_bss_prio_node *bss_prio;
+	unsigned long flags;
+
+	bss_prio = kzalloc(sizeof(struct mwifiex_bss_prio_node), GFP_KERNEL);
+	if (!bss_prio) {
+		dev_err(adapter->dev, "%s: failed to alloc bss_prio\n",
+						__func__);
+		return -ENOMEM;
+	}
+
+	bss_prio->priv = priv;
+	INIT_LIST_HEAD(&bss_prio->list);
+	if (!adapter->bss_prio_tbl[priv->bss_priority].bss_prio_cur)
+		adapter->bss_prio_tbl[priv->bss_priority].bss_prio_cur =
+			bss_prio;
+
+	spin_lock_irqsave(&adapter->bss_prio_tbl[priv->bss_priority]
+			.bss_prio_lock, flags);
+	list_add_tail(&bss_prio->list,
+			&adapter->bss_prio_tbl[priv->bss_priority]
+			.bss_prio_head);
+	spin_unlock_irqrestore(&adapter->bss_prio_tbl[priv->bss_priority]
+			.bss_prio_lock, flags);
+
+	return 0;
+}
+
+/*
+ * This function initializes the private structure and sets default
+ * values to the members.
+ *
+ * Additionally, it also initializes all the locks and sets up all the
+ * lists.
+ */
+static int mwifiex_init_priv(struct mwifiex_private *priv)
+{
+	u32 i;
+
+	priv->media_connected = false;
+	memset(priv->curr_addr, 0xff, ETH_ALEN);
+
+	priv->pkt_tx_ctrl = 0;
+	priv->bss_mode = NL80211_IFTYPE_STATION;
+	priv->data_rate = 0;	/* Initially indicate the rate as auto */
+	priv->is_data_rate_auto = true;
+	priv->bcn_avg_factor = DEFAULT_BCN_AVG_FACTOR;
+	priv->data_avg_factor = DEFAULT_DATA_AVG_FACTOR;
+
+	priv->sec_info.wep_status = MWIFIEX_802_11_WEP_DISABLED;
+	priv->sec_info.authentication_mode = NL80211_AUTHTYPE_OPEN_SYSTEM;
+	priv->sec_info.encryption_mode = 0;
+	for (i = 0; i < ARRAY_SIZE(priv->wep_key); i++)
+		memset(&priv->wep_key[i], 0, sizeof(struct mwifiex_wep_key));
+	priv->wep_key_curr_index = 0;
+	priv->curr_pkt_filter = HostCmd_ACT_MAC_RX_ON | HostCmd_ACT_MAC_TX_ON |
+				HostCmd_ACT_MAC_ETHERNETII_ENABLE;
+
+	priv->beacon_period = 100; /* beacon interval */ ;
+	priv->attempted_bss_desc = NULL;
+	memset(&priv->curr_bss_params, 0, sizeof(priv->curr_bss_params));
+	priv->listen_interval = MWIFIEX_DEFAULT_LISTEN_INTERVAL;
+
+	memset(&priv->prev_ssid, 0, sizeof(priv->prev_ssid));
+	memset(&priv->prev_bssid, 0, sizeof(priv->prev_bssid));
+	memset(&priv->assoc_rsp_buf, 0, sizeof(priv->assoc_rsp_buf));
+	priv->assoc_rsp_size = 0;
+	priv->adhoc_channel = DEFAULT_AD_HOC_CHANNEL;
+	priv->atim_window = 0;
+	priv->adhoc_state = ADHOC_IDLE;
+	priv->tx_power_level = 0;
+	priv->max_tx_power_level = 0;
+	priv->min_tx_power_level = 0;
+	priv->tx_rate = 0;
+	priv->rxpd_htinfo = 0;
+	priv->rxpd_rate = 0;
+	priv->rate_bitmap = 0;
+	priv->data_rssi_last = 0;
+	priv->data_rssi_avg = 0;
+	priv->data_nf_avg = 0;
+	priv->data_nf_last = 0;
+	priv->bcn_rssi_last = 0;
+	priv->bcn_rssi_avg = 0;
+	priv->bcn_nf_avg = 0;
+	priv->bcn_nf_last = 0;
+	memset(&priv->wpa_ie, 0, sizeof(priv->wpa_ie));
+	memset(&priv->aes_key, 0, sizeof(priv->aes_key));
+	priv->wpa_ie_len = 0;
+	priv->wpa_is_gtk_set = false;
+
+	memset(&priv->assoc_tlv_buf, 0, sizeof(priv->assoc_tlv_buf));
+	priv->assoc_tlv_buf_len = 0;
+	memset(&priv->wps, 0, sizeof(priv->wps));
+	memset(&priv->gen_ie_buf, 0, sizeof(priv->gen_ie_buf));
+	priv->gen_ie_buf_len = 0;
+	memset(priv->vs_ie, 0, sizeof(priv->vs_ie));
+
+	priv->wmm_required = true;
+	priv->wmm_enabled = false;
+	priv->wmm_qosinfo = 0;
+	priv->curr_bcn_buf = NULL;
+	priv->curr_bcn_size = 0;
+
+	priv->scan_block = false;
+
+	return mwifiex_add_bss_prio_tbl(priv);
+}
+
+/*
+ * This function allocates buffers for members of the adapter
+ * structure.
+ *
+ * The memory allocated includes scan table, command buffers, and
+ * sleep confirm command buffer. In addition, the queues are
+ * also initialized.
+ */
+static int mwifiex_allocate_adapter(struct mwifiex_adapter *adapter)
+{
+	int ret;
+	u32 buf_size;
+	struct mwifiex_bssdescriptor *temp_scan_table;
+
+	/* Allocate buffer to store the BSSID list */
+	buf_size = sizeof(struct mwifiex_bssdescriptor) * IW_MAX_AP;
+	temp_scan_table = kzalloc(buf_size, GFP_KERNEL);
+	if (!temp_scan_table) {
+		dev_err(adapter->dev, "%s: failed to alloc temp_scan_table\n",
+		       __func__);
+		return -ENOMEM;
+	}
+
+	adapter->scan_table = temp_scan_table;
+
+	/* Allocate command buffer */
+	ret = mwifiex_alloc_cmd_buffer(adapter);
+	if (ret) {
+		dev_err(adapter->dev, "%s: failed to alloc cmd buffer\n",
+		       __func__);
+		return -1;
+	}
+
+	adapter->sleep_cfm =
+		dev_alloc_skb(sizeof(struct mwifiex_opt_sleep_confirm)
+				+ INTF_HEADER_LEN);
+
+	if (!adapter->sleep_cfm) {
+		dev_err(adapter->dev, "%s: failed to alloc sleep cfm"
+			" cmd buffer\n", __func__);
+		return -1;
+	}
+	skb_reserve(adapter->sleep_cfm, INTF_HEADER_LEN);
+
+	return 0;
+}
+
+/*
+ * This function initializes the adapter structure and sets default
+ * values to the members of adapter.
+ *
+ * This also initializes the WMM related parameters in the driver private
+ * structures.
+ */
+static void mwifiex_init_adapter(struct mwifiex_adapter *adapter)
+{
+	struct mwifiex_opt_sleep_confirm *sleep_cfm_buf = NULL;
+
+	skb_put(adapter->sleep_cfm, sizeof(struct mwifiex_opt_sleep_confirm));
+	sleep_cfm_buf = (struct mwifiex_opt_sleep_confirm *)
+						(adapter->sleep_cfm->data);
+
+	adapter->cmd_sent = false;
+	adapter->data_sent = true;
+	adapter->cmd_resp_received = false;
+	adapter->event_received = false;
+	adapter->data_received = false;
+
+	adapter->surprise_removed = false;
+
+	adapter->hw_status = MWIFIEX_HW_STATUS_INITIALIZING;
+
+	adapter->ps_mode = MWIFIEX_802_11_POWER_MODE_CAM;
+	adapter->ps_state = PS_STATE_AWAKE;
+	adapter->need_to_wakeup = false;
+
+	adapter->scan_mode = HostCmd_BSS_MODE_ANY;
+	adapter->specific_scan_time = MWIFIEX_SPECIFIC_SCAN_CHAN_TIME;
+	adapter->active_scan_time = MWIFIEX_ACTIVE_SCAN_CHAN_TIME;
+	adapter->passive_scan_time = MWIFIEX_PASSIVE_SCAN_CHAN_TIME;
+
+	adapter->num_in_scan_table = 0;
+	memset(adapter->scan_table, 0,
+	       (sizeof(struct mwifiex_bssdescriptor) * IW_MAX_AP));
+	adapter->scan_probes = 1;
+
+	memset(adapter->bcn_buf, 0, sizeof(adapter->bcn_buf));
+	adapter->bcn_buf_end = adapter->bcn_buf;
+
+	adapter->multiple_dtim = 1;
+
+	adapter->local_listen_interval = 0;	/* default value in firmware
+						   will be used */
+
+	adapter->is_deep_sleep = false;
+
+	adapter->delay_null_pkt = false;
+	adapter->delay_to_ps = 1000;
+	adapter->enhanced_ps_mode = PS_MODE_AUTO;
+
+	adapter->gen_null_pkt = false;	/* Disable NULL Pkg generation by
+					   default */
+	adapter->pps_uapsd_mode = false; /* Disable pps/uapsd mode by
+					   default */
+	adapter->pm_wakeup_card_req = false;
+
+	adapter->pm_wakeup_fw_try = false;
+
+	adapter->max_tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_2K;
+	adapter->tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_2K;
+	adapter->curr_tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_2K;
+
+	adapter->is_hs_configured = false;
+	adapter->hs_cfg.conditions = cpu_to_le32(HOST_SLEEP_CFG_COND_DEF);
+	adapter->hs_cfg.gpio = HOST_SLEEP_CFG_GPIO_DEF;
+	adapter->hs_cfg.gap = HOST_SLEEP_CFG_GAP_DEF;
+	adapter->hs_activated = false;
+
+	memset(adapter->event_body, 0, sizeof(adapter->event_body));
+	adapter->hw_dot_11n_dev_cap = 0;
+	adapter->hw_dev_mcs_support = 0;
+	adapter->chan_offset = 0;
+	adapter->adhoc_11n_enabled = false;
+
+	mwifiex_wmm_init(adapter);
+
+	if (adapter->sleep_cfm) {
+		memset(sleep_cfm_buf, 0, adapter->sleep_cfm->len);
+		sleep_cfm_buf->command =
+				cpu_to_le16(HostCmd_CMD_802_11_PS_MODE_ENH);
+		sleep_cfm_buf->size =
+				cpu_to_le16(adapter->sleep_cfm->len);
+		sleep_cfm_buf->result = 0;
+		sleep_cfm_buf->action = cpu_to_le16(SLEEP_CONFIRM);
+		sleep_cfm_buf->resp_ctrl = cpu_to_le16(RESP_NEEDED);
+	}
+	memset(&adapter->sleep_params, 0, sizeof(adapter->sleep_params));
+	memset(&adapter->sleep_period, 0, sizeof(adapter->sleep_period));
+	adapter->tx_lock_flag = false;
+	adapter->null_pkt_interval = 0;
+	adapter->fw_bands = 0;
+	adapter->config_bands = 0;
+	adapter->adhoc_start_band = 0;
+	adapter->scan_channels = NULL;
+	adapter->fw_release_number = 0;
+	adapter->fw_cap_info = 0;
+	memset(&adapter->upld_buf, 0, sizeof(adapter->upld_buf));
+	adapter->event_cause = 0;
+	adapter->region_code = 0;
+	adapter->bcn_miss_time_out = DEFAULT_BCN_MISS_TIMEOUT;
+	adapter->adhoc_awake_period = 0;
+	memset(&adapter->arp_filter, 0, sizeof(adapter->arp_filter));
+	adapter->arp_filter_size = 0;
+}
+
+/*
+ * This function frees the adapter structure.
+ *
+ * The freeing operation is done recursively, by canceling all
+ * pending commands, freeing the member buffers previously
+ * allocated (command buffers, scan table buffer, sleep confirm
+ * command buffer), stopping the timers and calling the cleanup
+ * routines for every interface, before the actual adapter
+ * structure is freed.
+ */
+static void
+mwifiex_free_adapter(struct mwifiex_adapter *adapter)
+{
+	if (!adapter) {
+		pr_err("%s: adapter is NULL\n", __func__);
+		return;
+	}
+
+	mwifiex_cancel_all_pending_cmd(adapter);
+
+	/* Free lock variables */
+	mwifiex_free_lock_list(adapter);
+
+	/* Free command buffer */
+	dev_dbg(adapter->dev, "info: free cmd buffer\n");
+	mwifiex_free_cmd_buffer(adapter);
+
+	del_timer(&adapter->cmd_timer);
+
+	dev_dbg(adapter->dev, "info: free scan table\n");
+	kfree(adapter->scan_table);
+	adapter->scan_table = NULL;
+
+	adapter->if_ops.cleanup_if(adapter);
+
+	dev_kfree_skb_any(adapter->sleep_cfm);
+}
+
+/*
+ *  This function intializes the lock variables and
+ *  the list heads.
+ */
+int mwifiex_init_lock_list(struct mwifiex_adapter *adapter)
+{
+	struct mwifiex_private *priv;
+	s32 i, j;
+
+	spin_lock_init(&adapter->mwifiex_lock);
+	spin_lock_init(&adapter->int_lock);
+	spin_lock_init(&adapter->main_proc_lock);
+	spin_lock_init(&adapter->mwifiex_cmd_lock);
+	for (i = 0; i < adapter->priv_num; i++) {
+		if (adapter->priv[i]) {
+			priv = adapter->priv[i];
+			spin_lock_init(&priv->rx_pkt_lock);
+			spin_lock_init(&priv->wmm.ra_list_spinlock);
+			spin_lock_init(&priv->curr_bcn_buf_lock);
+		}
+	}
+
+	/* Initialize cmd_free_q */
+	INIT_LIST_HEAD(&adapter->cmd_free_q);
+	/* Initialize cmd_pending_q */
+	INIT_LIST_HEAD(&adapter->cmd_pending_q);
+	/* Initialize scan_pending_q */
+	INIT_LIST_HEAD(&adapter->scan_pending_q);
+
+	spin_lock_init(&adapter->cmd_free_q_lock);
+	spin_lock_init(&adapter->cmd_pending_q_lock);
+	spin_lock_init(&adapter->scan_pending_q_lock);
+
+	for (i = 0; i < adapter->priv_num; ++i) {
+		INIT_LIST_HEAD(&adapter->bss_prio_tbl[i].bss_prio_head);
+		adapter->bss_prio_tbl[i].bss_prio_cur = NULL;
+		spin_lock_init(&adapter->bss_prio_tbl[i].bss_prio_lock);
+	}
+
+	for (i = 0; i < adapter->priv_num; i++) {
+		if (!adapter->priv[i])
+			continue;
+		priv = adapter->priv[i];
+		for (j = 0; j < MAX_NUM_TID; ++j) {
+			INIT_LIST_HEAD(&priv->wmm.tid_tbl_ptr[j].ra_list);
+			spin_lock_init(&priv->wmm.tid_tbl_ptr[j].tid_tbl_lock);
+		}
+		INIT_LIST_HEAD(&priv->tx_ba_stream_tbl_ptr);
+		INIT_LIST_HEAD(&priv->rx_reorder_tbl_ptr);
+
+		spin_lock_init(&priv->tx_ba_stream_tbl_lock);
+		spin_lock_init(&priv->rx_reorder_tbl_lock);
+	}
+
+	return 0;
+}
+
+/*
+ *  This function releases the lock variables and frees the locks and
+ *  associated locks.
+ */
+void mwifiex_free_lock_list(struct mwifiex_adapter *adapter)
+{
+	struct mwifiex_private *priv;
+	s32 i, j;
+
+	/* Free lists */
+	list_del(&adapter->cmd_free_q);
+	list_del(&adapter->cmd_pending_q);
+	list_del(&adapter->scan_pending_q);
+
+	for (i = 0; i < adapter->priv_num; i++)
+		list_del(&adapter->bss_prio_tbl[i].bss_prio_head);
+
+	for (i = 0; i < adapter->priv_num; i++) {
+		if (adapter->priv[i]) {
+			priv = adapter->priv[i];
+			for (j = 0; j < MAX_NUM_TID; ++j)
+				list_del(&priv->wmm.tid_tbl_ptr[j].ra_list);
+			list_del(&priv->tx_ba_stream_tbl_ptr);
+			list_del(&priv->rx_reorder_tbl_ptr);
+		}
+	}
+}
+
+/*
+ * This function initializes the firmware.
+ *
+ * The following operations are performed sequentially -
+ *      - Allocate adapter structure
+ *      - Initialize the adapter structure
+ *      - Initialize the private structure
+ *      - Add BSS priority tables to the adapter structure
+ *      - For each interface, send the init commands to firmware
+ *      - Send the first command in command pending queue, if available
+ */
+int mwifiex_init_fw(struct mwifiex_adapter *adapter)
+{
+	int ret;
+	struct mwifiex_private *priv;
+	u8 i, first_sta = true;
+	int is_cmd_pend_q_empty;
+	unsigned long flags;
+
+	adapter->hw_status = MWIFIEX_HW_STATUS_INITIALIZING;
+
+	/* Allocate memory for member of adapter structure */
+	ret = mwifiex_allocate_adapter(adapter);
+	if (ret)
+		return -1;
+
+	/* Initialize adapter structure */
+	mwifiex_init_adapter(adapter);
+
+	for (i = 0; i < adapter->priv_num; i++) {
+		if (adapter->priv[i]) {
+			priv = adapter->priv[i];
+
+			/* Initialize private structure */
+			ret = mwifiex_init_priv(priv);
+			if (ret)
+				return -1;
+		}
+	}
+	for (i = 0; i < adapter->priv_num; i++) {
+		if (adapter->priv[i]) {
+			ret = mwifiex_sta_init_cmd(adapter->priv[i], first_sta);
+			if (ret == -1)
+				return -1;
+
+			first_sta = false;
+		}
+	}
+
+	spin_lock_irqsave(&adapter->cmd_pending_q_lock, flags);
+	is_cmd_pend_q_empty = list_empty(&adapter->cmd_pending_q);
+	spin_unlock_irqrestore(&adapter->cmd_pending_q_lock, flags);
+	if (!is_cmd_pend_q_empty) {
+		/* Send the first command in queue and return */
+		if (mwifiex_main_process(adapter) != -1)
+			ret = -EINPROGRESS;
+	} else {
+		adapter->hw_status = MWIFIEX_HW_STATUS_READY;
+	}
+
+	return ret;
+}
+
+/*
+ * This function deletes the BSS priority tables.
+ *
+ * The function traverses through all the allocated BSS priority nodes
+ * in every BSS priority table and frees them.
+ */
+static void mwifiex_delete_bss_prio_tbl(struct mwifiex_private *priv)
+{
+	int i;
+	struct mwifiex_adapter *adapter = priv->adapter;
+	struct mwifiex_bss_prio_node *bssprio_node, *tmp_node, **cur;
+	struct list_head *head;
+	spinlock_t *lock;
+	unsigned long flags;
+
+	for (i = 0; i < adapter->priv_num; ++i) {
+		head = &adapter->bss_prio_tbl[i].bss_prio_head;
+		cur = &adapter->bss_prio_tbl[i].bss_prio_cur;
+		lock = &adapter->bss_prio_tbl[i].bss_prio_lock;
+		dev_dbg(adapter->dev, "info: delete BSS priority table,"
+				" index = %d, i = %d, head = %p, cur = %p\n",
+			      priv->bss_index, i, head, *cur);
+		if (*cur) {
+			spin_lock_irqsave(lock, flags);
+			if (list_empty(head)) {
+				spin_unlock_irqrestore(lock, flags);
+				continue;
+			}
+			bssprio_node = list_first_entry(head,
+					struct mwifiex_bss_prio_node, list);
+			spin_unlock_irqrestore(lock, flags);
+
+			list_for_each_entry_safe(bssprio_node, tmp_node, head,
+						 list) {
+				if (bssprio_node->priv == priv) {
+					dev_dbg(adapter->dev, "info: Delete "
+						"node %p, next = %p\n",
+						bssprio_node, tmp_node);
+					spin_lock_irqsave(lock, flags);
+					list_del(&bssprio_node->list);
+					spin_unlock_irqrestore(lock, flags);
+					kfree(bssprio_node);
+				}
+			}
+			*cur = (struct mwifiex_bss_prio_node *)head;
+		}
+	}
+}
+
+/*
+ * This function is used to shutdown the driver.
+ *
+ * The following operations are performed sequentially -
+ *      - Check if already shut down
+ *      - Make sure the main process has stopped
+ *      - Clean up the Tx and Rx queues
+ *      - Delete BSS priority tables
+ *      - Free the adapter
+ *      - Notify completion
+ */
+int
+mwifiex_shutdown_drv(struct mwifiex_adapter *adapter)
+{
+	int ret = -EINPROGRESS;
+	struct mwifiex_private *priv;
+	s32 i;
+	unsigned long flags;
+
+	/* mwifiex already shutdown */
+	if (adapter->hw_status == MWIFIEX_HW_STATUS_NOT_READY)
+		return 0;
+
+	adapter->hw_status = MWIFIEX_HW_STATUS_CLOSING;
+	/* wait for mwifiex_process to complete */
+	if (adapter->mwifiex_processing) {
+		dev_warn(adapter->dev, "main process is still running\n");
+		return ret;
+	}
+
+	/* shut down mwifiex */
+	dev_dbg(adapter->dev, "info: shutdown mwifiex...\n");
+
+	/* Clean up Tx/Rx queues and delete BSS priority table */
+	for (i = 0; i < adapter->priv_num; i++) {
+		if (adapter->priv[i]) {
+			priv = adapter->priv[i];
+
+			mwifiex_clean_txrx(priv);
+			mwifiex_delete_bss_prio_tbl(priv);
+		}
+	}
+
+	spin_lock_irqsave(&adapter->mwifiex_lock, flags);
+
+	/* Free adapter structure */
+	mwifiex_free_adapter(adapter);
+
+	spin_unlock_irqrestore(&adapter->mwifiex_lock, flags);
+
+	/* Notify completion */
+	ret = mwifiex_shutdown_fw_complete(adapter);
+
+	return ret;
+}
+
+/*
+ * This function downloads the firmware to the card.
+ *
+ * The actual download is preceded by two sanity checks -
+ *      - Check if firmware is already running
+ *      - Check if the interface is the winner to download the firmware
+ *
+ * ...and followed by another -
+ *      - Check if the firmware is downloaded successfully
+ *
+ * After download is successfully completed, the host interrupts are enabled.
+ */
+int mwifiex_dnld_fw(struct mwifiex_adapter *adapter,
+		    struct mwifiex_fw_image *pmfw)
+{
+	int ret, winner;
+	u32 poll_num = 1;
+
+	/* Check if firmware is already running */
+	ret = adapter->if_ops.check_fw_status(adapter, poll_num, &winner);
+	if (!ret) {
+		dev_notice(adapter->dev,
+				"WLAN FW already running! Skip FW download\n");
+		goto done;
+	}
+	poll_num = MAX_FIRMWARE_POLL_TRIES;
+
+	/* Check if we are the winner for downloading FW */
+	if (!winner) {
+		dev_notice(adapter->dev,
+				"Other interface already running!"
+				" Skip FW download\n");
+		poll_num = MAX_MULTI_INTERFACE_POLL_TRIES;
+		goto poll_fw;
+	}
+	if (pmfw) {
+		/* Download firmware with helper */
+		ret = adapter->if_ops.prog_fw(adapter, pmfw);
+		if (ret) {
+			dev_err(adapter->dev, "prog_fw failed ret=%#x\n", ret);
+			return ret;
+		}
+	}
+
+poll_fw:
+	/* Check if the firmware is downloaded successfully or not */
+	ret = adapter->if_ops.check_fw_status(adapter, poll_num, NULL);
+	if (ret) {
+		dev_err(adapter->dev, "FW failed to be active in time\n");
+		return -1;
+	}
+done:
+	/* re-enable host interrupt for mwifiex after fw dnld is successful */
+	adapter->if_ops.enable_int(adapter);
+	return ret;
+}
diff -druN linux-2.6.39-libre/drivers/net/wireless/mwifiex/ioctl.h linux-3.0-rc7-libre/drivers/net/wireless/mwifiex/ioctl.h
--- linux-2.6.39-libre/drivers/net/wireless/mwifiex/ioctl.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/net/wireless/mwifiex/ioctl.h	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,331 @@
+/*
+ * Marvell Wireless LAN device driver: ioctl data structures & APIs
+ *
+ * Copyright (C) 2011, Marvell International Ltd.
+ *
+ * This software file (the "File") is distributed by Marvell International
+ * Ltd. under the terms of the GNU General Public License Version 2, June 1991
+ * (the "License").  You may use, redistribute and/or modify this File in
+ * accordance with the terms and conditions of the License, a copy of which
+ * is available by writing to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
+ * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
+ *
+ * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
+ * ARE EXPRESSLY DISCLAIMED.  The License provides additional details about
+ * this warranty disclaimer.
+ */
+
+#ifndef _MWIFIEX_IOCTL_H_
+#define _MWIFIEX_IOCTL_H_
+
+#include <net/mac80211.h>
+
+enum {
+	MWIFIEX_SCAN_TYPE_UNCHANGED = 0,
+	MWIFIEX_SCAN_TYPE_ACTIVE,
+	MWIFIEX_SCAN_TYPE_PASSIVE
+};
+
+struct mwifiex_user_scan {
+	u32 scan_cfg_len;
+	u8 scan_cfg_buf[1];
+};
+
+#define MWIFIEX_PROMISC_MODE            1
+#define MWIFIEX_MULTICAST_MODE		2
+#define	MWIFIEX_ALL_MULTI_MODE		4
+#define MWIFIEX_MAX_MULTICAST_LIST_SIZE	32
+
+struct mwifiex_multicast_list {
+	u32 mode;
+	u32 num_multicast_addr;
+	u8 mac_list[MWIFIEX_MAX_MULTICAST_LIST_SIZE][ETH_ALEN];
+};
+
+struct mwifiex_chan_freq {
+	u32 channel;
+	u32 freq;
+};
+
+struct mwifiex_ssid_bssid {
+	struct mwifiex_802_11_ssid ssid;
+	u8 bssid[ETH_ALEN];
+};
+
+enum {
+	BAND_B = 1,
+	BAND_G = 2,
+	BAND_A = 4,
+	BAND_GN = 8,
+	BAND_AN = 16,
+};
+
+#define NO_SEC_CHANNEL               0
+#define SEC_CHANNEL_ABOVE            1
+#define SEC_CHANNEL_BELOW            3
+
+struct mwifiex_ds_band_cfg {
+	u32 config_bands;
+	u32 adhoc_start_band;
+	u32 adhoc_channel;
+	u32 sec_chan_offset;
+};
+
+enum {
+	ADHOC_IDLE,
+	ADHOC_STARTED,
+	ADHOC_JOINED,
+	ADHOC_COALESCED
+};
+
+struct mwifiex_ds_get_stats {
+	u32 mcast_tx_frame;
+	u32 failed;
+	u32 retry;
+	u32 multi_retry;
+	u32 frame_dup;
+	u32 rts_success;
+	u32 rts_failure;
+	u32 ack_failure;
+	u32 rx_frag;
+	u32 mcast_rx_frame;
+	u32 fcs_error;
+	u32 tx_frame;
+	u32 wep_icv_error[4];
+};
+
+#define BCN_RSSI_AVG_MASK               0x00000002
+#define BCN_NF_AVG_MASK                 0x00000200
+#define ALL_RSSI_INFO_MASK              0x00000fff
+
+struct mwifiex_ds_get_signal {
+	/*
+	 * Bit0:  Last Beacon RSSI,  Bit1:  Average Beacon RSSI,
+	 * Bit2:  Last Data RSSI,    Bit3:  Average Data RSSI,
+	 * Bit4:  Last Beacon SNR,   Bit5:  Average Beacon SNR,
+	 * Bit6:  Last Data SNR,     Bit7:  Average Data SNR,
+	 * Bit8:  Last Beacon NF,    Bit9:  Average Beacon NF,
+	 * Bit10: Last Data NF,      Bit11: Average Data NF
+	 */
+	u16 selector;
+	s16 bcn_rssi_last;
+	s16 bcn_rssi_avg;
+	s16 data_rssi_last;
+	s16 data_rssi_avg;
+	s16 bcn_snr_last;
+	s16 bcn_snr_avg;
+	s16 data_snr_last;
+	s16 data_snr_avg;
+	s16 bcn_nf_last;
+	s16 bcn_nf_avg;
+	s16 data_nf_last;
+	s16 data_nf_avg;
+};
+
+#define MWIFIEX_MAX_VER_STR_LEN    128
+
+struct mwifiex_ver_ext {
+	u32 version_str_sel;
+	char version_str[MWIFIEX_MAX_VER_STR_LEN];
+};
+
+struct mwifiex_bss_info {
+	u32 bss_mode;
+	struct mwifiex_802_11_ssid ssid;
+	u32 scan_table_idx;
+	u32 bss_chan;
+	u32 region_code;
+	u32 media_connected;
+	u32 max_power_level;
+	u32 min_power_level;
+	u32 adhoc_state;
+	signed int bcn_nf_last;
+	u32 wep_status;
+	u32 is_hs_configured;
+	u32 is_deep_sleep;
+	u8 bssid[ETH_ALEN];
+};
+
+#define MAX_NUM_TID     8
+
+#define MAX_RX_WINSIZE  64
+
+struct mwifiex_ds_rx_reorder_tbl {
+	u16 tid;
+	u8 ta[ETH_ALEN];
+	u32 start_win;
+	u32 win_size;
+	u32 buffer[MAX_RX_WINSIZE];
+};
+
+struct mwifiex_ds_tx_ba_stream_tbl {
+	u16 tid;
+	u8 ra[ETH_ALEN];
+};
+
+#define DBG_CMD_NUM	5
+
+struct mwifiex_debug_info {
+	u32 int_counter;
+	u32 packets_out[MAX_NUM_TID];
+	u32 max_tx_buf_size;
+	u32 tx_buf_size;
+	u32 curr_tx_buf_size;
+	u32 tx_tbl_num;
+	struct mwifiex_ds_tx_ba_stream_tbl
+		tx_tbl[MWIFIEX_MAX_TX_BASTREAM_SUPPORTED];
+	u32 rx_tbl_num;
+	struct mwifiex_ds_rx_reorder_tbl rx_tbl
+		[MWIFIEX_MAX_RX_BASTREAM_SUPPORTED];
+	u16 ps_mode;
+	u32 ps_state;
+	u8 is_deep_sleep;
+	u8 pm_wakeup_card_req;
+	u32 pm_wakeup_fw_try;
+	u8 is_hs_configured;
+	u8 hs_activated;
+	u32 num_cmd_host_to_card_failure;
+	u32 num_cmd_sleep_cfm_host_to_card_failure;
+	u32 num_tx_host_to_card_failure;
+	u32 num_event_deauth;
+	u32 num_event_disassoc;
+	u32 num_event_link_lost;
+	u32 num_cmd_deauth;
+	u32 num_cmd_assoc_success;
+	u32 num_cmd_assoc_failure;
+	u32 num_tx_timeout;
+	u32 num_cmd_timeout;
+	u16 timeout_cmd_id;
+	u16 timeout_cmd_act;
+	u16 last_cmd_id[DBG_CMD_NUM];
+	u16 last_cmd_act[DBG_CMD_NUM];
+	u16 last_cmd_index;
+	u16 last_cmd_resp_id[DBG_CMD_NUM];
+	u16 last_cmd_resp_index;
+	u16 last_event[DBG_CMD_NUM];
+	u16 last_event_index;
+	u8 data_sent;
+	u8 cmd_sent;
+	u8 cmd_resp_received;
+	u8 event_received;
+};
+
+#define MWIFIEX_KEY_INDEX_UNICAST	0x40000000
+#define WAPI_RXPN_LEN			16
+
+struct mwifiex_ds_encrypt_key {
+	u32 key_disable;
+	u32 key_index;
+	u32 key_len;
+	u8 key_material[WLAN_MAX_KEY_LEN];
+	u8 mac_addr[ETH_ALEN];
+	u32 is_wapi_key;
+	u8 wapi_rxpn[WAPI_RXPN_LEN];
+};
+
+struct mwifiex_rate_cfg {
+	u32 action;
+	u32 is_rate_auto;
+	u32 rate;
+};
+
+struct mwifiex_power_cfg {
+	u32 is_power_auto;
+	u32 power_level;
+};
+
+struct mwifiex_ds_hs_cfg {
+	u32 is_invoke_hostcmd;
+	/*  Bit0: non-unicast data
+	 *  Bit1: unicast data
+	 *  Bit2: mac events
+	 *  Bit3: magic packet
+	 */
+	u32 conditions;
+	u32 gpio;
+	u32 gap;
+};
+
+#define DEEP_SLEEP_ON  1
+#define DEEP_SLEEP_IDLE_TIME	100
+#define PS_MODE_AUTO		1
+
+struct mwifiex_ds_auto_ds {
+	u16 auto_ds;
+	u16 idle_time;
+};
+
+struct mwifiex_ds_pm_cfg {
+	union {
+		u32 ps_mode;
+		struct mwifiex_ds_hs_cfg hs_cfg;
+		struct mwifiex_ds_auto_ds auto_deep_sleep;
+		u32 sleep_period;
+	} param;
+};
+
+struct mwifiex_ds_11n_tx_cfg {
+	u16 tx_htcap;
+	u16 tx_htinfo;
+};
+
+struct mwifiex_ds_11n_amsdu_aggr_ctrl {
+	u16 enable;
+	u16 curr_buf_size;
+};
+
+#define MWIFIEX_NUM_OF_CMD_BUFFER	20
+#define MWIFIEX_SIZE_OF_CMD_BUFFER	2048
+
+enum {
+	MWIFIEX_IE_TYPE_GEN_IE = 0,
+	MWIFIEX_IE_TYPE_ARP_FILTER,
+};
+
+enum {
+	MWIFIEX_REG_MAC = 1,
+	MWIFIEX_REG_BBP,
+	MWIFIEX_REG_RF,
+	MWIFIEX_REG_PMIC,
+	MWIFIEX_REG_CAU,
+};
+
+struct mwifiex_ds_reg_rw {
+	__le32 type;
+	__le32 offset;
+	__le32 value;
+};
+
+#define MAX_EEPROM_DATA 256
+
+struct mwifiex_ds_read_eeprom {
+	__le16 offset;
+	__le16 byte_count;
+	u8 value[MAX_EEPROM_DATA];
+};
+
+struct mwifiex_ds_misc_gen_ie {
+	u32 type;
+	u32 len;
+	u8 ie_data[IW_CUSTOM_MAX];
+};
+
+struct mwifiex_ds_misc_cmd {
+	u32 len;
+	u8 cmd[MWIFIEX_SIZE_OF_CMD_BUFFER];
+};
+
+#define MWIFIEX_MAX_VSIE_LEN       (256)
+#define MWIFIEX_MAX_VSIE_NUM       (8)
+#define MWIFIEX_VSIE_MASK_SCAN     0x01
+#define MWIFIEX_VSIE_MASK_ASSOC    0x02
+#define MWIFIEX_VSIE_MASK_ADHOC    0x04
+
+enum {
+	MWIFIEX_FUNC_INIT = 1,
+	MWIFIEX_FUNC_SHUTDOWN,
+};
+
+#endif /* !_MWIFIEX_IOCTL_H_ */
diff -druN linux-2.6.39-libre/drivers/net/wireless/mwifiex/join.c linux-3.0-rc7-libre/drivers/net/wireless/mwifiex/join.c
--- linux-2.6.39-libre/drivers/net/wireless/mwifiex/join.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/net/wireless/mwifiex/join.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,1423 @@
+/*
+ * Marvell Wireless LAN device driver: association and ad-hoc start/join
+ *
+ * Copyright (C) 2011, Marvell International Ltd.
+ *
+ * This software file (the "File") is distributed by Marvell International
+ * Ltd. under the terms of the GNU General Public License Version 2, June 1991
+ * (the "License").  You may use, redistribute and/or modify this File in
+ * accordance with the terms and conditions of the License, a copy of which
+ * is available by writing to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
+ * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
+ *
+ * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
+ * ARE EXPRESSLY DISCLAIMED.  The License provides additional details about
+ * this warranty disclaimer.
+ */
+
+#include "decl.h"
+#include "ioctl.h"
+#include "util.h"
+#include "fw.h"
+#include "main.h"
+#include "wmm.h"
+#include "11n.h"
+
+#define CAPINFO_MASK    (~(BIT(15) | BIT(14) | BIT(12) | BIT(11) | BIT(9)))
+
+/*
+ * Append a generic IE as a pass through TLV to a TLV buffer.
+ *
+ * This function is called from the network join command preparation routine.
+ *
+ * If the IE buffer has been setup by the application, this routine appends
+ * the buffer as a pass through TLV type to the request.
+ */
+static int
+mwifiex_cmd_append_generic_ie(struct mwifiex_private *priv, u8 **buffer)
+{
+	int ret_len = 0;
+	struct mwifiex_ie_types_header ie_header;
+
+	/* Null Checks */
+	if (!buffer)
+		return 0;
+	if (!(*buffer))
+		return 0;
+
+	/*
+	 * If there is a generic ie buffer setup, append it to the return
+	 *   parameter buffer pointer.
+	 */
+	if (priv->gen_ie_buf_len) {
+		dev_dbg(priv->adapter->dev, "info: %s: append generic %d to %p\n",
+				__func__, priv->gen_ie_buf_len, *buffer);
+
+		/* Wrap the generic IE buffer with a pass through TLV type */
+		ie_header.type = cpu_to_le16(TLV_TYPE_PASSTHROUGH);
+		ie_header.len = cpu_to_le16(priv->gen_ie_buf_len);
+		memcpy(*buffer, &ie_header, sizeof(ie_header));
+
+		/* Increment the return size and the return buffer pointer
+		   param */
+		*buffer += sizeof(ie_header);
+		ret_len += sizeof(ie_header);
+
+		/* Copy the generic IE buffer to the output buffer, advance
+		   pointer */
+		memcpy(*buffer, priv->gen_ie_buf, priv->gen_ie_buf_len);
+
+		/* Increment the return size and the return buffer pointer
+		   param */
+		*buffer += priv->gen_ie_buf_len;
+		ret_len += priv->gen_ie_buf_len;
+
+		/* Reset the generic IE buffer */
+		priv->gen_ie_buf_len = 0;
+	}
+
+	/* return the length appended to the buffer */
+	return ret_len;
+}
+
+/*
+ * Append TSF tracking info from the scan table for the target AP.
+ *
+ * This function is called from the network join command preparation routine.
+ *
+ * The TSF table TSF sent to the firmware contains two TSF values:
+ *      - The TSF of the target AP from its previous beacon/probe response
+ *      - The TSF timestamp of our local MAC at the time we observed the
+ *        beacon/probe response.
+ *
+ * The firmware uses the timestamp values to set an initial TSF value
+ * in the MAC for the new association after a reassociation attempt.
+ */
+static int
+mwifiex_cmd_append_tsf_tlv(struct mwifiex_private *priv, u8 **buffer,
+			   struct mwifiex_bssdescriptor *bss_desc)
+{
+	struct mwifiex_ie_types_tsf_timestamp tsf_tlv;
+	__le64 tsf_val;
+
+	/* Null Checks */
+	if (buffer == NULL)
+		return 0;
+	if (*buffer == NULL)
+		return 0;
+
+	memset(&tsf_tlv, 0x00, sizeof(struct mwifiex_ie_types_tsf_timestamp));
+
+	tsf_tlv.header.type = cpu_to_le16(TLV_TYPE_TSFTIMESTAMP);
+	tsf_tlv.header.len = cpu_to_le16(2 * sizeof(tsf_val));
+
+	memcpy(*buffer, &tsf_tlv, sizeof(tsf_tlv.header));
+	*buffer += sizeof(tsf_tlv.header);
+
+	/* TSF at the time when beacon/probe_response was received */
+	tsf_val = cpu_to_le64(bss_desc->network_tsf);
+	memcpy(*buffer, &tsf_val, sizeof(tsf_val));
+	*buffer += sizeof(tsf_val);
+
+	memcpy(&tsf_val, bss_desc->time_stamp, sizeof(tsf_val));
+
+	dev_dbg(priv->adapter->dev, "info: %s: TSF offset calc: %016llx - "
+			"%016llx\n", __func__, tsf_val, bss_desc->network_tsf);
+
+	memcpy(*buffer, &tsf_val, sizeof(tsf_val));
+	*buffer += sizeof(tsf_val);
+
+	return sizeof(tsf_tlv.header) + (2 * sizeof(tsf_val));
+}
+
+/*
+ * This function finds out the common rates between rate1 and rate2.
+ *
+ * It will fill common rates in rate1 as output if found.
+ *
+ * NOTE: Setting the MSB of the basic rates needs to be taken
+ * care of, either before or after calling this function.
+ */
+static int mwifiex_get_common_rates(struct mwifiex_private *priv, u8 *rate1,
+				    u32 rate1_size, u8 *rate2, u32 rate2_size)
+{
+	int ret;
+	u8 *ptr = rate1, *tmp;
+	u32 i, j;
+
+	tmp = kmalloc(rate1_size, GFP_KERNEL);
+	if (!tmp) {
+		dev_err(priv->adapter->dev, "failed to alloc tmp buf\n");
+		return -ENOMEM;
+	}
+
+	memcpy(tmp, rate1, rate1_size);
+	memset(rate1, 0, rate1_size);
+
+	for (i = 0; rate2[i] && i < rate2_size; i++) {
+		for (j = 0; tmp[j] && j < rate1_size; j++) {
+			/* Check common rate, excluding the bit for
+			   basic rate */
+			if ((rate2[i] & 0x7F) == (tmp[j] & 0x7F)) {
+				*rate1++ = tmp[j];
+				break;
+			}
+		}
+	}
+
+	dev_dbg(priv->adapter->dev, "info: Tx data rate set to %#x\n",
+						priv->data_rate);
+
+	if (!priv->is_data_rate_auto) {
+		while (*ptr) {
+			if ((*ptr & 0x7f) == priv->data_rate) {
+				ret = 0;
+				goto done;
+			}
+			ptr++;
+		}
+		dev_err(priv->adapter->dev, "previously set fixed data rate %#x"
+			" is not compatible with the network\n",
+			priv->data_rate);
+
+		ret = -1;
+		goto done;
+	}
+
+	ret = 0;
+done:
+	kfree(tmp);
+	return ret;
+}
+
+/*
+ * This function creates the intersection of the rates supported by a
+ * target BSS and our adapter settings for use in an assoc/join command.
+ */
+static int
+mwifiex_setup_rates_from_bssdesc(struct mwifiex_private *priv,
+				 struct mwifiex_bssdescriptor *bss_desc,
+				 u8 *out_rates, u32 *out_rates_size)
+{
+	u8 card_rates[MWIFIEX_SUPPORTED_RATES];
+	u32 card_rates_size;
+
+	/* Copy AP supported rates */
+	memcpy(out_rates, bss_desc->supported_rates, MWIFIEX_SUPPORTED_RATES);
+	/* Get the STA supported rates */
+	card_rates_size = mwifiex_get_active_data_rates(priv, card_rates);
+	/* Get the common rates between AP and STA supported rates */
+	if (mwifiex_get_common_rates(priv, out_rates, MWIFIEX_SUPPORTED_RATES,
+				     card_rates, card_rates_size)) {
+		*out_rates_size = 0;
+		dev_err(priv->adapter->dev, "%s: cannot get common rates\n",
+						__func__);
+		return -1;
+	}
+
+	*out_rates_size =
+		min_t(size_t, strlen(out_rates), MWIFIEX_SUPPORTED_RATES);
+
+	return 0;
+}
+
+/*
+ * This function updates the scan entry TSF timestamps to reflect
+ * a new association.
+ */
+static void
+mwifiex_update_tsf_timestamps(struct mwifiex_private *priv,
+			      struct mwifiex_bssdescriptor *new_bss_desc)
+{
+	struct mwifiex_adapter *adapter = priv->adapter;
+	u32 table_idx;
+	long long new_tsf_base;
+	signed long long tsf_delta;
+
+	memcpy(&new_tsf_base, new_bss_desc->time_stamp, sizeof(new_tsf_base));
+
+	tsf_delta = new_tsf_base - new_bss_desc->network_tsf;
+
+	dev_dbg(adapter->dev, "info: TSF: update TSF timestamps, "
+		"0x%016llx -> 0x%016llx\n",
+	       new_bss_desc->network_tsf, new_tsf_base);
+
+	for (table_idx = 0; table_idx < adapter->num_in_scan_table;
+	     table_idx++)
+		adapter->scan_table[table_idx].network_tsf += tsf_delta;
+}
+
+/*
+ * This function appends a WAPI IE.
+ *
+ * This function is called from the network join command preparation routine.
+ *
+ * If the IE buffer has been setup by the application, this routine appends
+ * the buffer as a WAPI TLV type to the request.
+ */
+static int
+mwifiex_cmd_append_wapi_ie(struct mwifiex_private *priv, u8 **buffer)
+{
+	int retLen = 0;
+	struct mwifiex_ie_types_header ie_header;
+
+	/* Null Checks */
+	if (buffer == NULL)
+		return 0;
+	if (*buffer == NULL)
+		return 0;
+
+	/*
+	 * If there is a wapi ie buffer setup, append it to the return
+	 *   parameter buffer pointer.
+	 */
+	if (priv->wapi_ie_len) {
+		dev_dbg(priv->adapter->dev, "cmd: append wapi ie %d to %p\n",
+				priv->wapi_ie_len, *buffer);
+
+		/* Wrap the generic IE buffer with a pass through TLV type */
+		ie_header.type = cpu_to_le16(TLV_TYPE_WAPI_IE);
+		ie_header.len = cpu_to_le16(priv->wapi_ie_len);
+		memcpy(*buffer, &ie_header, sizeof(ie_header));
+
+		/* Increment the return size and the return buffer pointer
+		   param */
+		*buffer += sizeof(ie_header);
+		retLen += sizeof(ie_header);
+
+		/* Copy the wapi IE buffer to the output buffer, advance
+		   pointer */
+		memcpy(*buffer, priv->wapi_ie, priv->wapi_ie_len);
+
+		/* Increment the return size and the return buffer pointer
+		   param */
+		*buffer += priv->wapi_ie_len;
+		retLen += priv->wapi_ie_len;
+
+	}
+	/* return the length appended to the buffer */
+	return retLen;
+}
+
+/*
+ * This function appends rsn ie tlv for wpa/wpa2 security modes.
+ * It is called from the network join command preparation routine.
+ */
+static int mwifiex_append_rsn_ie_wpa_wpa2(struct mwifiex_private *priv,
+					  u8 **buffer)
+{
+	struct mwifiex_ie_types_rsn_param_set *rsn_ie_tlv;
+	int rsn_ie_len;
+
+	if (!buffer || !(*buffer))
+		return 0;
+
+	rsn_ie_tlv = (struct mwifiex_ie_types_rsn_param_set *) (*buffer);
+	rsn_ie_tlv->header.type = cpu_to_le16((u16) priv->wpa_ie[0]);
+	rsn_ie_tlv->header.type = cpu_to_le16(
+				 le16_to_cpu(rsn_ie_tlv->header.type) & 0x00FF);
+	rsn_ie_tlv->header.len = cpu_to_le16((u16) priv->wpa_ie[1]);
+	rsn_ie_tlv->header.len = cpu_to_le16(le16_to_cpu(rsn_ie_tlv->header.len)
+							& 0x00FF);
+	if (le16_to_cpu(rsn_ie_tlv->header.len) <= (sizeof(priv->wpa_ie) - 2))
+		memcpy(rsn_ie_tlv->rsn_ie, &priv->wpa_ie[2],
+					le16_to_cpu(rsn_ie_tlv->header.len));
+	else
+		return -1;
+
+	rsn_ie_len = sizeof(rsn_ie_tlv->header) +
+					le16_to_cpu(rsn_ie_tlv->header.len);
+	*buffer += rsn_ie_len;
+
+	return rsn_ie_len;
+}
+
+/*
+ * This function prepares command for association.
+ *
+ * This sets the following parameters -
+ *      - Peer MAC address
+ *      - Listen interval
+ *      - Beacon interval
+ *      - Capability information
+ *
+ * ...and the following TLVs, as required -
+ *      - SSID TLV
+ *      - PHY TLV
+ *      - SS TLV
+ *      - Rates TLV
+ *      - Authentication TLV
+ *      - Channel TLV
+ *      - WPA/WPA2 IE
+ *      - 11n TLV
+ *      - Vendor specific TLV
+ *      - WMM TLV
+ *      - WAPI IE
+ *      - Generic IE
+ *      - TSF TLV
+ *
+ * Preparation also includes -
+ *      - Setting command ID and proper size
+ *      - Ensuring correct endian-ness
+ */
+int mwifiex_cmd_802_11_associate(struct mwifiex_private *priv,
+				 struct host_cmd_ds_command *cmd,
+				 void *data_buf)
+{
+	struct host_cmd_ds_802_11_associate *assoc = &cmd->params.associate;
+	struct mwifiex_bssdescriptor *bss_desc;
+	struct mwifiex_ie_types_ssid_param_set *ssid_tlv;
+	struct mwifiex_ie_types_phy_param_set *phy_tlv;
+	struct mwifiex_ie_types_ss_param_set *ss_tlv;
+	struct mwifiex_ie_types_rates_param_set *rates_tlv;
+	struct mwifiex_ie_types_auth_type *auth_tlv;
+	struct mwifiex_ie_types_chan_list_param_set *chan_tlv;
+	u8 rates[MWIFIEX_SUPPORTED_RATES];
+	u32 rates_size;
+	u16 tmp_cap;
+	u8 *pos;
+	int rsn_ie_len = 0;
+
+	bss_desc = (struct mwifiex_bssdescriptor *) data_buf;
+	pos = (u8 *) assoc;
+
+	mwifiex_cfg_tx_buf(priv, bss_desc);
+
+	cmd->command = cpu_to_le16(HostCmd_CMD_802_11_ASSOCIATE);
+
+	/* Save so we know which BSS Desc to use in the response handler */
+	priv->attempted_bss_desc = bss_desc;
+
+	memcpy(assoc->peer_sta_addr,
+	       bss_desc->mac_address, sizeof(assoc->peer_sta_addr));
+	pos += sizeof(assoc->peer_sta_addr);
+
+	/* Set the listen interval */
+	assoc->listen_interval = cpu_to_le16(priv->listen_interval);
+	/* Set the beacon period */
+	assoc->beacon_period = cpu_to_le16(bss_desc->beacon_period);
+
+	pos += sizeof(assoc->cap_info_bitmap);
+	pos += sizeof(assoc->listen_interval);
+	pos += sizeof(assoc->beacon_period);
+	pos += sizeof(assoc->dtim_period);
+
+	ssid_tlv = (struct mwifiex_ie_types_ssid_param_set *) pos;
+	ssid_tlv->header.type = cpu_to_le16(WLAN_EID_SSID);
+	ssid_tlv->header.len = cpu_to_le16((u16) bss_desc->ssid.ssid_len);
+	memcpy(ssid_tlv->ssid, bss_desc->ssid.ssid,
+		le16_to_cpu(ssid_tlv->header.len));
+	pos += sizeof(ssid_tlv->header) + le16_to_cpu(ssid_tlv->header.len);
+
+	phy_tlv = (struct mwifiex_ie_types_phy_param_set *) pos;
+	phy_tlv->header.type = cpu_to_le16(WLAN_EID_DS_PARAMS);
+	phy_tlv->header.len = cpu_to_le16(sizeof(phy_tlv->fh_ds.ds_param_set));
+	memcpy(&phy_tlv->fh_ds.ds_param_set,
+	       &bss_desc->phy_param_set.ds_param_set.current_chan,
+	       sizeof(phy_tlv->fh_ds.ds_param_set));
+	pos += sizeof(phy_tlv->header) + le16_to_cpu(phy_tlv->header.len);
+
+	ss_tlv = (struct mwifiex_ie_types_ss_param_set *) pos;
+	ss_tlv->header.type = cpu_to_le16(WLAN_EID_CF_PARAMS);
+	ss_tlv->header.len = cpu_to_le16(sizeof(ss_tlv->cf_ibss.cf_param_set));
+	pos += sizeof(ss_tlv->header) + le16_to_cpu(ss_tlv->header.len);
+
+	/* Get the common rates supported between the driver and the BSS Desc */
+	if (mwifiex_setup_rates_from_bssdesc
+	    (priv, bss_desc, rates, &rates_size))
+		return -1;
+
+	/* Save the data rates into Current BSS state structure */
+	priv->curr_bss_params.num_of_rates = rates_size;
+	memcpy(&priv->curr_bss_params.data_rates, rates, rates_size);
+
+	/* Setup the Rates TLV in the association command */
+	rates_tlv = (struct mwifiex_ie_types_rates_param_set *) pos;
+	rates_tlv->header.type = cpu_to_le16(WLAN_EID_SUPP_RATES);
+	rates_tlv->header.len = cpu_to_le16((u16) rates_size);
+	memcpy(rates_tlv->rates, rates, rates_size);
+	pos += sizeof(rates_tlv->header) + rates_size;
+	dev_dbg(priv->adapter->dev, "info: ASSOC_CMD: rates size = %d\n",
+					rates_size);
+
+	/* Add the Authentication type to be used for Auth frames */
+	auth_tlv = (struct mwifiex_ie_types_auth_type *) pos;
+	auth_tlv->header.type = cpu_to_le16(TLV_TYPE_AUTH_TYPE);
+	auth_tlv->header.len = cpu_to_le16(sizeof(auth_tlv->auth_type));
+	if (priv->sec_info.wep_status == MWIFIEX_802_11_WEP_ENABLED)
+		auth_tlv->auth_type = cpu_to_le16(
+				(u16) priv->sec_info.authentication_mode);
+	else
+		auth_tlv->auth_type = cpu_to_le16(NL80211_AUTHTYPE_OPEN_SYSTEM);
+
+	pos += sizeof(auth_tlv->header) + le16_to_cpu(auth_tlv->header.len);
+
+	if (IS_SUPPORT_MULTI_BANDS(priv->adapter)
+	    && !(ISSUPP_11NENABLED(priv->adapter->fw_cap_info)
+		&& (!bss_desc->disable_11n)
+		 && (priv->adapter->config_bands & BAND_GN
+		     || priv->adapter->config_bands & BAND_AN)
+		 && (bss_desc->bcn_ht_cap)
+	    )
+		) {
+		/* Append a channel TLV for the channel the attempted AP was
+		   found on */
+		chan_tlv = (struct mwifiex_ie_types_chan_list_param_set *) pos;
+		chan_tlv->header.type = cpu_to_le16(TLV_TYPE_CHANLIST);
+		chan_tlv->header.len =
+			cpu_to_le16(sizeof(struct mwifiex_chan_scan_param_set));
+
+		memset(chan_tlv->chan_scan_param, 0x00,
+		       sizeof(struct mwifiex_chan_scan_param_set));
+		chan_tlv->chan_scan_param[0].chan_number =
+			(bss_desc->phy_param_set.ds_param_set.current_chan);
+		dev_dbg(priv->adapter->dev, "info: Assoc: TLV Chan = %d\n",
+		       chan_tlv->chan_scan_param[0].chan_number);
+
+		chan_tlv->chan_scan_param[0].radio_type =
+			mwifiex_band_to_radio_type((u8) bss_desc->bss_band);
+
+		dev_dbg(priv->adapter->dev, "info: Assoc: TLV Band = %d\n",
+		       chan_tlv->chan_scan_param[0].radio_type);
+		pos += sizeof(chan_tlv->header) +
+			sizeof(struct mwifiex_chan_scan_param_set);
+	}
+
+	if (!priv->wps.session_enable) {
+		if (priv->sec_info.wpa_enabled || priv->sec_info.wpa2_enabled)
+			rsn_ie_len = mwifiex_append_rsn_ie_wpa_wpa2(priv, &pos);
+
+		if (rsn_ie_len == -1)
+			return -1;
+	}
+
+	if (ISSUPP_11NENABLED(priv->adapter->fw_cap_info)
+		&& (!bss_desc->disable_11n)
+	    && (priv->adapter->config_bands & BAND_GN
+		|| priv->adapter->config_bands & BAND_AN))
+		mwifiex_cmd_append_11n_tlv(priv, bss_desc, &pos);
+
+	/* Append vendor specific IE TLV */
+	mwifiex_cmd_append_vsie_tlv(priv, MWIFIEX_VSIE_MASK_ASSOC, &pos);
+
+	mwifiex_wmm_process_association_req(priv, &pos, &bss_desc->wmm_ie,
+					    bss_desc->bcn_ht_cap);
+	if (priv->sec_info.wapi_enabled && priv->wapi_ie_len)
+		mwifiex_cmd_append_wapi_ie(priv, &pos);
+
+
+	mwifiex_cmd_append_generic_ie(priv, &pos);
+
+	mwifiex_cmd_append_tsf_tlv(priv, &pos, bss_desc);
+
+	cmd->size = cpu_to_le16((u16) (pos - (u8 *) assoc) + S_DS_GEN);
+
+	/* Set the Capability info at last */
+	tmp_cap = bss_desc->cap_info_bitmap;
+
+	if (priv->adapter->config_bands == BAND_B)
+		tmp_cap &= ~WLAN_CAPABILITY_SHORT_SLOT_TIME;
+
+	tmp_cap &= CAPINFO_MASK;
+	dev_dbg(priv->adapter->dev, "info: ASSOC_CMD: tmp_cap=%4X CAPINFO_MASK=%4lX\n",
+	       tmp_cap, CAPINFO_MASK);
+	assoc->cap_info_bitmap = cpu_to_le16(tmp_cap);
+
+	return 0;
+}
+
+/*
+ * Association firmware command response handler
+ *
+ * The response buffer for the association command has the following
+ * memory layout.
+ *
+ * For cases where an association response was not received (indicated
+ * by the CapInfo and AId field):
+ *
+ *     .------------------------------------------------------------.
+ *     |  Header(4 * sizeof(t_u16)):  Standard command response hdr |
+ *     .------------------------------------------------------------.
+ *     |  cap_info/Error Return(t_u16):                             |
+ *     |           0xFFFF(-1): Internal error                       |
+ *     |           0xFFFE(-2): Authentication unhandled message     |
+ *     |           0xFFFD(-3): Authentication refused               |
+ *     |           0xFFFC(-4): Timeout waiting for AP response      |
+ *     .------------------------------------------------------------.
+ *     |  status_code(t_u16):                                       |
+ *     |        If cap_info is -1:                                  |
+ *     |           An internal firmware failure prevented the       |
+ *     |           command from being processed.  The status_code   |
+ *     |           will be set to 1.                                |
+ *     |                                                            |
+ *     |        If cap_info is -2:                                  |
+ *     |           An authentication frame was received but was     |
+ *     |           not handled by the firmware.  IEEE Status        |
+ *     |           code for the failure is returned.                |
+ *     |                                                            |
+ *     |        If cap_info is -3:                                  |
+ *     |           An authentication frame was received and the     |
+ *     |           status_code is the IEEE Status reported in the   |
+ *     |           response.                                        |
+ *     |                                                            |
+ *     |        If cap_info is -4:                                  |
+ *     |           (1) Association response timeout                 |
+ *     |           (2) Authentication response timeout              |
+ *     .------------------------------------------------------------.
+ *     |  a_id(t_u16): 0xFFFF                                       |
+ *     .------------------------------------------------------------.
+ *
+ *
+ * For cases where an association response was received, the IEEE
+ * standard association response frame is returned:
+ *
+ *     .------------------------------------------------------------.
+ *     |  Header(4 * sizeof(t_u16)):  Standard command response hdr |
+ *     .------------------------------------------------------------.
+ *     |  cap_info(t_u16): IEEE Capability                          |
+ *     .------------------------------------------------------------.
+ *     |  status_code(t_u16): IEEE Status Code                      |
+ *     .------------------------------------------------------------.
+ *     |  a_id(t_u16): IEEE Association ID                          |
+ *     .------------------------------------------------------------.
+ *     |  IEEE IEs(variable): Any received IEs comprising the       |
+ *     |                      remaining portion of a received       |
+ *     |                      association response frame.           |
+ *     .------------------------------------------------------------.
+ *
+ * For simplistic handling, the status_code field can be used to determine
+ * an association success (0) or failure (non-zero).
+ */
+int mwifiex_ret_802_11_associate(struct mwifiex_private *priv,
+			     struct host_cmd_ds_command *resp)
+{
+	struct mwifiex_adapter *adapter = priv->adapter;
+	int ret = 0;
+	struct ieee_types_assoc_rsp *assoc_rsp;
+	struct mwifiex_bssdescriptor *bss_desc;
+	u8 enable_data = true;
+
+	assoc_rsp = (struct ieee_types_assoc_rsp *) &resp->params;
+
+	priv->assoc_rsp_size = min(le16_to_cpu(resp->size) - S_DS_GEN,
+				     sizeof(priv->assoc_rsp_buf));
+
+	memcpy(priv->assoc_rsp_buf, &resp->params, priv->assoc_rsp_size);
+
+	if (le16_to_cpu(assoc_rsp->status_code)) {
+		priv->adapter->dbg.num_cmd_assoc_failure++;
+		dev_err(priv->adapter->dev, "ASSOC_RESP: association failed, "
+		       "status code = %d, error = 0x%x, a_id = 0x%x\n",
+		       le16_to_cpu(assoc_rsp->status_code),
+		       le16_to_cpu(assoc_rsp->cap_info_bitmap),
+		       le16_to_cpu(assoc_rsp->a_id));
+
+		ret = -1;
+		goto done;
+	}
+
+	/* Send a Media Connected event, according to the Spec */
+	priv->media_connected = true;
+
+	priv->adapter->ps_state = PS_STATE_AWAKE;
+	priv->adapter->pps_uapsd_mode = false;
+	priv->adapter->tx_lock_flag = false;
+
+	/* Set the attempted BSSID Index to current */
+	bss_desc = priv->attempted_bss_desc;
+
+	dev_dbg(priv->adapter->dev, "info: ASSOC_RESP: %s\n",
+						bss_desc->ssid.ssid);
+
+	/* Make a copy of current BSSID descriptor */
+	memcpy(&priv->curr_bss_params.bss_descriptor,
+	       bss_desc, sizeof(struct mwifiex_bssdescriptor));
+
+	/* Update curr_bss_params */
+	priv->curr_bss_params.bss_descriptor.channel
+		= bss_desc->phy_param_set.ds_param_set.current_chan;
+
+	priv->curr_bss_params.band = (u8) bss_desc->bss_band;
+
+	/*
+	 * Adjust the timestamps in the scan table to be relative to the newly
+	 * associated AP's TSF
+	 */
+	mwifiex_update_tsf_timestamps(priv, bss_desc);
+
+	if (bss_desc->wmm_ie.vend_hdr.element_id == WLAN_EID_VENDOR_SPECIFIC)
+		priv->curr_bss_params.wmm_enabled = true;
+	else
+		priv->curr_bss_params.wmm_enabled = false;
+
+	if ((priv->wmm_required || bss_desc->bcn_ht_cap)
+			&& priv->curr_bss_params.wmm_enabled)
+		priv->wmm_enabled = true;
+	else
+		priv->wmm_enabled = false;
+
+	priv->curr_bss_params.wmm_uapsd_enabled = false;
+
+	if (priv->wmm_enabled)
+		priv->curr_bss_params.wmm_uapsd_enabled
+			= ((bss_desc->wmm_ie.qos_info_bitmap &
+				IEEE80211_WMM_IE_AP_QOSINFO_UAPSD) ? 1 : 0);
+
+	dev_dbg(priv->adapter->dev, "info: ASSOC_RESP: curr_pkt_filter is %#x\n",
+	       priv->curr_pkt_filter);
+	if (priv->sec_info.wpa_enabled || priv->sec_info.wpa2_enabled)
+		priv->wpa_is_gtk_set = false;
+
+	if (priv->wmm_enabled) {
+		/* Don't re-enable carrier until we get the WMM_GET_STATUS
+		   event */
+		enable_data = false;
+	} else {
+		/* Since WMM is not enabled, setup the queues with the
+		   defaults */
+		mwifiex_wmm_setup_queue_priorities(priv, NULL);
+		mwifiex_wmm_setup_ac_downgrade(priv);
+	}
+
+	if (enable_data)
+		dev_dbg(priv->adapter->dev,
+			"info: post association, re-enabling data flow\n");
+
+	/* Reset SNR/NF/RSSI values */
+	priv->data_rssi_last = 0;
+	priv->data_nf_last = 0;
+	priv->data_rssi_avg = 0;
+	priv->data_nf_avg = 0;
+	priv->bcn_rssi_last = 0;
+	priv->bcn_nf_last = 0;
+	priv->bcn_rssi_avg = 0;
+	priv->bcn_nf_avg = 0;
+	priv->rxpd_rate = 0;
+	priv->rxpd_htinfo = 0;
+
+	mwifiex_save_curr_bcn(priv);
+
+	priv->adapter->dbg.num_cmd_assoc_success++;
+
+	dev_dbg(priv->adapter->dev, "info: ASSOC_RESP: associated\n");
+
+	/* Add the ra_list here for infra mode as there will be only 1 ra
+	   always */
+	mwifiex_ralist_add(priv,
+			   priv->curr_bss_params.bss_descriptor.mac_address);
+
+	if (!netif_carrier_ok(priv->netdev))
+		netif_carrier_on(priv->netdev);
+	if (netif_queue_stopped(priv->netdev))
+		netif_wake_queue(priv->netdev);
+
+	if (priv->sec_info.wpa_enabled || priv->sec_info.wpa2_enabled)
+		priv->scan_block = true;
+
+done:
+	/* Need to indicate IOCTL complete */
+	if (adapter->curr_cmd->wait_q_enabled) {
+		if (ret)
+			adapter->cmd_wait_q.status = -1;
+		else
+			adapter->cmd_wait_q.status = 0;
+	}
+
+	return ret;
+}
+
+/*
+ * This function prepares command for ad-hoc start.
+ *
+ * Driver will fill up SSID, BSS mode, IBSS parameters, physical
+ * parameters, probe delay, and capability information. Firmware
+ * will fill up beacon period, basic rates and operational rates.
+ *
+ * In addition, the following TLVs are added -
+ *      - Channel TLV
+ *      - Vendor specific IE
+ *      - WPA/WPA2 IE
+ *      - HT Capabilities IE
+ *      - HT Information IE
+ *
+ * Preparation also includes -
+ *      - Setting command ID and proper size
+ *      - Ensuring correct endian-ness
+ */
+int
+mwifiex_cmd_802_11_ad_hoc_start(struct mwifiex_private *priv,
+				struct host_cmd_ds_command *cmd, void *data_buf)
+{
+	int rsn_ie_len = 0;
+	struct mwifiex_adapter *adapter = priv->adapter;
+	struct host_cmd_ds_802_11_ad_hoc_start *adhoc_start =
+		&cmd->params.adhoc_start;
+	struct mwifiex_bssdescriptor *bss_desc;
+	u32 cmd_append_size = 0;
+	u32 i;
+	u16 tmp_cap;
+	uint16_t ht_cap_info;
+	struct mwifiex_ie_types_chan_list_param_set *chan_tlv;
+
+	struct mwifiex_ie_types_htcap *ht_cap;
+	struct mwifiex_ie_types_htinfo *ht_info;
+	u8 *pos = (u8 *) adhoc_start +
+			sizeof(struct host_cmd_ds_802_11_ad_hoc_start);
+
+	if (!adapter)
+		return -1;
+
+	cmd->command = cpu_to_le16(HostCmd_CMD_802_11_AD_HOC_START);
+
+	bss_desc = &priv->curr_bss_params.bss_descriptor;
+	priv->attempted_bss_desc = bss_desc;
+
+	/*
+	 * Fill in the parameters for 2 data structures:
+	 *   1. struct host_cmd_ds_802_11_ad_hoc_start command
+	 *   2. bss_desc
+	 * Driver will fill up SSID, bss_mode,IBSS param, Physical Param,
+	 * probe delay, and Cap info.
+	 * Firmware will fill up beacon period, Basic rates
+	 * and operational rates.
+	 */
+
+	memset(adhoc_start->ssid, 0, IEEE80211_MAX_SSID_LEN);
+
+	memcpy(adhoc_start->ssid,
+	       ((struct mwifiex_802_11_ssid *) data_buf)->ssid,
+	       ((struct mwifiex_802_11_ssid *) data_buf)->ssid_len);
+
+	dev_dbg(adapter->dev, "info: ADHOC_S_CMD: SSID = %s\n",
+				adhoc_start->ssid);
+
+	memset(bss_desc->ssid.ssid, 0, IEEE80211_MAX_SSID_LEN);
+	memcpy(bss_desc->ssid.ssid,
+	       ((struct mwifiex_802_11_ssid *) data_buf)->ssid,
+	       ((struct mwifiex_802_11_ssid *) data_buf)->ssid_len);
+
+	bss_desc->ssid.ssid_len =
+		((struct mwifiex_802_11_ssid *) data_buf)->ssid_len;
+
+	/* Set the BSS mode */
+	adhoc_start->bss_mode = HostCmd_BSS_MODE_IBSS;
+	bss_desc->bss_mode = NL80211_IFTYPE_ADHOC;
+	adhoc_start->beacon_period = cpu_to_le16(priv->beacon_period);
+	bss_desc->beacon_period = priv->beacon_period;
+
+	/* Set Physical param set */
+/* Parameter IE Id */
+#define DS_PARA_IE_ID   3
+/* Parameter IE length */
+#define DS_PARA_IE_LEN  1
+
+	adhoc_start->phy_param_set.ds_param_set.element_id = DS_PARA_IE_ID;
+	adhoc_start->phy_param_set.ds_param_set.len = DS_PARA_IE_LEN;
+
+	if (!mwifiex_get_cfp_by_band_and_channel_from_cfg80211
+			(priv, adapter->adhoc_start_band, (u16)
+				priv->adhoc_channel)) {
+		struct mwifiex_chan_freq_power *cfp;
+		cfp = mwifiex_get_cfp_by_band_and_channel_from_cfg80211(priv,
+				adapter->adhoc_start_band, FIRST_VALID_CHANNEL);
+		if (cfp)
+			priv->adhoc_channel = (u8) cfp->channel;
+	}
+
+	if (!priv->adhoc_channel) {
+		dev_err(adapter->dev, "ADHOC_S_CMD: adhoc_channel cannot be 0\n");
+		return -1;
+	}
+
+	dev_dbg(adapter->dev, "info: ADHOC_S_CMD: creating ADHOC on channel %d\n",
+				priv->adhoc_channel);
+
+	priv->curr_bss_params.bss_descriptor.channel = priv->adhoc_channel;
+	priv->curr_bss_params.band = adapter->adhoc_start_band;
+
+	bss_desc->channel = priv->adhoc_channel;
+	adhoc_start->phy_param_set.ds_param_set.current_chan =
+		priv->adhoc_channel;
+
+	memcpy(&bss_desc->phy_param_set, &adhoc_start->phy_param_set,
+	       sizeof(union ieee_types_phy_param_set));
+
+	/* Set IBSS param set */
+/* IBSS parameter IE Id */
+#define IBSS_PARA_IE_ID   6
+/* IBSS parameter IE length */
+#define IBSS_PARA_IE_LEN  2
+
+	adhoc_start->ss_param_set.ibss_param_set.element_id = IBSS_PARA_IE_ID;
+	adhoc_start->ss_param_set.ibss_param_set.len = IBSS_PARA_IE_LEN;
+	adhoc_start->ss_param_set.ibss_param_set.atim_window
+		= cpu_to_le16(priv->atim_window);
+	memcpy(&bss_desc->ss_param_set, &adhoc_start->ss_param_set,
+	       sizeof(union ieee_types_ss_param_set));
+
+	/* Set Capability info */
+	bss_desc->cap_info_bitmap |= WLAN_CAPABILITY_IBSS;
+	tmp_cap = le16_to_cpu(adhoc_start->cap_info_bitmap);
+	tmp_cap &= ~WLAN_CAPABILITY_ESS;
+	tmp_cap |= WLAN_CAPABILITY_IBSS;
+
+	/* Set up privacy in bss_desc */
+	if (priv->sec_info.encryption_mode) {
+		/* Ad-Hoc capability privacy on */
+		dev_dbg(adapter->dev,
+			"info: ADHOC_S_CMD: wep_status set privacy to WEP\n");
+		bss_desc->privacy = MWIFIEX_802_11_PRIV_FILTER_8021X_WEP;
+		tmp_cap |= WLAN_CAPABILITY_PRIVACY;
+	} else {
+		dev_dbg(adapter->dev, "info: ADHOC_S_CMD: wep_status NOT set,"
+				" setting privacy to ACCEPT ALL\n");
+		bss_desc->privacy = MWIFIEX_802_11_PRIV_FILTER_ACCEPT_ALL;
+	}
+
+	memset(adhoc_start->DataRate, 0, sizeof(adhoc_start->DataRate));
+	mwifiex_get_active_data_rates(priv, adhoc_start->DataRate);
+	if ((adapter->adhoc_start_band & BAND_G) &&
+	    (priv->curr_pkt_filter & HostCmd_ACT_MAC_ADHOC_G_PROTECTION_ON)) {
+		if (mwifiex_send_cmd_async(priv, HostCmd_CMD_MAC_CONTROL,
+					     HostCmd_ACT_GEN_SET, 0,
+					     &priv->curr_pkt_filter)) {
+			dev_err(adapter->dev,
+			       "ADHOC_S_CMD: G Protection config failed\n");
+			return -1;
+		}
+	}
+	/* Find the last non zero */
+	for (i = 0; i < sizeof(adhoc_start->DataRate) &&
+			adhoc_start->DataRate[i];
+			i++)
+			;
+
+	priv->curr_bss_params.num_of_rates = i;
+
+	/* Copy the ad-hoc creating rates into Current BSS rate structure */
+	memcpy(&priv->curr_bss_params.data_rates,
+	       &adhoc_start->DataRate, priv->curr_bss_params.num_of_rates);
+
+	dev_dbg(adapter->dev, "info: ADHOC_S_CMD: rates=%02x %02x %02x %02x\n",
+	       adhoc_start->DataRate[0], adhoc_start->DataRate[1],
+	       adhoc_start->DataRate[2], adhoc_start->DataRate[3]);
+
+	dev_dbg(adapter->dev, "info: ADHOC_S_CMD: AD-HOC Start command is ready\n");
+
+	if (IS_SUPPORT_MULTI_BANDS(adapter)) {
+		/* Append a channel TLV */
+		chan_tlv = (struct mwifiex_ie_types_chan_list_param_set *) pos;
+		chan_tlv->header.type = cpu_to_le16(TLV_TYPE_CHANLIST);
+		chan_tlv->header.len =
+			cpu_to_le16(sizeof(struct mwifiex_chan_scan_param_set));
+
+		memset(chan_tlv->chan_scan_param, 0x00,
+		       sizeof(struct mwifiex_chan_scan_param_set));
+		chan_tlv->chan_scan_param[0].chan_number =
+			(u8) priv->curr_bss_params.bss_descriptor.channel;
+
+		dev_dbg(adapter->dev, "info: ADHOC_S_CMD: TLV Chan = %d\n",
+		       chan_tlv->chan_scan_param[0].chan_number);
+
+		chan_tlv->chan_scan_param[0].radio_type
+		       = mwifiex_band_to_radio_type(priv->curr_bss_params.band);
+		if (adapter->adhoc_start_band & BAND_GN
+		    || adapter->adhoc_start_band & BAND_AN) {
+			if (adapter->chan_offset == SEC_CHANNEL_ABOVE)
+				chan_tlv->chan_scan_param[0].radio_type |=
+					SECOND_CHANNEL_ABOVE;
+			else if (adapter->chan_offset == SEC_CHANNEL_BELOW)
+				chan_tlv->chan_scan_param[0].radio_type |=
+					SECOND_CHANNEL_BELOW;
+		}
+		dev_dbg(adapter->dev, "info: ADHOC_S_CMD: TLV Band = %d\n",
+		       chan_tlv->chan_scan_param[0].radio_type);
+		pos += sizeof(chan_tlv->header) +
+			sizeof(struct mwifiex_chan_scan_param_set);
+		cmd_append_size +=
+			sizeof(chan_tlv->header) +
+			sizeof(struct mwifiex_chan_scan_param_set);
+	}
+
+	/* Append vendor specific IE TLV */
+	cmd_append_size += mwifiex_cmd_append_vsie_tlv(priv,
+				MWIFIEX_VSIE_MASK_ADHOC, &pos);
+
+	if (priv->sec_info.wpa_enabled) {
+		rsn_ie_len = mwifiex_append_rsn_ie_wpa_wpa2(priv, &pos);
+		if (rsn_ie_len == -1)
+			return -1;
+		cmd_append_size += rsn_ie_len;
+	}
+
+	if (adapter->adhoc_11n_enabled) {
+		{
+			ht_cap = (struct mwifiex_ie_types_htcap *) pos;
+			memset(ht_cap, 0,
+			       sizeof(struct mwifiex_ie_types_htcap));
+			ht_cap->header.type =
+				cpu_to_le16(WLAN_EID_HT_CAPABILITY);
+			ht_cap->header.len =
+			       cpu_to_le16(sizeof(struct ieee80211_ht_cap));
+			ht_cap_info = le16_to_cpu(ht_cap->ht_cap.cap_info);
+
+			ht_cap_info |= IEEE80211_HT_CAP_SGI_20;
+			if (adapter->chan_offset) {
+				ht_cap_info |= IEEE80211_HT_CAP_SGI_40;
+				ht_cap_info |= IEEE80211_HT_CAP_DSSSCCK40;
+				ht_cap_info |= IEEE80211_HT_CAP_SUP_WIDTH_20_40;
+				SETHT_MCS32(ht_cap->ht_cap.mcs.rx_mask);
+			}
+
+			ht_cap->ht_cap.ampdu_params_info
+					= IEEE80211_HT_MAX_AMPDU_64K;
+			ht_cap->ht_cap.mcs.rx_mask[0] = 0xff;
+			pos += sizeof(struct mwifiex_ie_types_htcap);
+			cmd_append_size +=
+				sizeof(struct mwifiex_ie_types_htcap);
+		}
+		{
+			ht_info = (struct mwifiex_ie_types_htinfo *) pos;
+			memset(ht_info, 0,
+			       sizeof(struct mwifiex_ie_types_htinfo));
+			ht_info->header.type =
+				cpu_to_le16(WLAN_EID_HT_INFORMATION);
+			ht_info->header.len =
+				cpu_to_le16(sizeof(struct ieee80211_ht_info));
+			ht_info->ht_info.control_chan =
+				(u8) priv->curr_bss_params.bss_descriptor.
+				channel;
+			if (adapter->chan_offset) {
+				ht_info->ht_info.ht_param =
+					adapter->chan_offset;
+				ht_info->ht_info.ht_param |=
+					IEEE80211_HT_PARAM_CHAN_WIDTH_ANY;
+			}
+			ht_info->ht_info.operation_mode =
+			     cpu_to_le16(IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT);
+			ht_info->ht_info.basic_set[0] = 0xff;
+			pos += sizeof(struct mwifiex_ie_types_htinfo);
+			cmd_append_size +=
+				sizeof(struct mwifiex_ie_types_htinfo);
+		}
+	}
+
+	cmd->size = cpu_to_le16((u16)
+			    (sizeof(struct host_cmd_ds_802_11_ad_hoc_start)
+			     + S_DS_GEN + cmd_append_size));
+
+	if (adapter->adhoc_start_band == BAND_B)
+		tmp_cap &= ~WLAN_CAPABILITY_SHORT_SLOT_TIME;
+	else
+		tmp_cap |= WLAN_CAPABILITY_SHORT_SLOT_TIME;
+
+	adhoc_start->cap_info_bitmap = cpu_to_le16(tmp_cap);
+
+	return 0;
+}
+
+/*
+ * This function prepares command for ad-hoc join.
+ *
+ * Most of the parameters are set up by copying from the target BSS descriptor
+ * from the scan response.
+ *
+ * In addition, the following TLVs are added -
+ *      - Channel TLV
+ *      - Vendor specific IE
+ *      - WPA/WPA2 IE
+ *      - 11n IE
+ *
+ * Preparation also includes -
+ *      - Setting command ID and proper size
+ *      - Ensuring correct endian-ness
+ */
+int
+mwifiex_cmd_802_11_ad_hoc_join(struct mwifiex_private *priv,
+			       struct host_cmd_ds_command *cmd, void *data_buf)
+{
+	int rsn_ie_len = 0;
+	struct host_cmd_ds_802_11_ad_hoc_join *adhoc_join =
+		&cmd->params.adhoc_join;
+	struct mwifiex_bssdescriptor *bss_desc =
+		(struct mwifiex_bssdescriptor *) data_buf;
+	struct mwifiex_ie_types_chan_list_param_set *chan_tlv;
+	u32 cmd_append_size = 0;
+	u16 tmp_cap;
+	u32 i, rates_size = 0;
+	u16 curr_pkt_filter;
+	u8 *pos =
+		(u8 *) adhoc_join +
+		sizeof(struct host_cmd_ds_802_11_ad_hoc_join);
+
+/* Use G protection */
+#define USE_G_PROTECTION        0x02
+	if (bss_desc->erp_flags & USE_G_PROTECTION) {
+		curr_pkt_filter =
+			priv->
+			curr_pkt_filter | HostCmd_ACT_MAC_ADHOC_G_PROTECTION_ON;
+
+		if (mwifiex_send_cmd_async(priv, HostCmd_CMD_MAC_CONTROL,
+					     HostCmd_ACT_GEN_SET, 0,
+					     &curr_pkt_filter)) {
+			dev_err(priv->adapter->dev,
+			       "ADHOC_J_CMD: G Protection config failed\n");
+			return -1;
+		}
+	}
+
+	priv->attempted_bss_desc = bss_desc;
+
+	cmd->command = cpu_to_le16(HostCmd_CMD_802_11_AD_HOC_JOIN);
+
+	adhoc_join->bss_descriptor.bss_mode = HostCmd_BSS_MODE_IBSS;
+
+	adhoc_join->bss_descriptor.beacon_period
+		= cpu_to_le16(bss_desc->beacon_period);
+
+	memcpy(&adhoc_join->bss_descriptor.bssid,
+	       &bss_desc->mac_address, ETH_ALEN);
+
+	memcpy(&adhoc_join->bss_descriptor.ssid,
+	       &bss_desc->ssid.ssid, bss_desc->ssid.ssid_len);
+
+	memcpy(&adhoc_join->bss_descriptor.phy_param_set,
+	       &bss_desc->phy_param_set,
+	       sizeof(union ieee_types_phy_param_set));
+
+	memcpy(&adhoc_join->bss_descriptor.ss_param_set,
+	       &bss_desc->ss_param_set, sizeof(union ieee_types_ss_param_set));
+
+	tmp_cap = bss_desc->cap_info_bitmap;
+
+	tmp_cap &= CAPINFO_MASK;
+
+	dev_dbg(priv->adapter->dev, "info: ADHOC_J_CMD: tmp_cap=%4X"
+			" CAPINFO_MASK=%4lX\n", tmp_cap, CAPINFO_MASK);
+
+	/* Information on BSSID descriptor passed to FW */
+	dev_dbg(priv->adapter->dev, "info: ADHOC_J_CMD: BSSID = %pM, SSID = %s\n",
+				adhoc_join->bss_descriptor.bssid,
+				adhoc_join->bss_descriptor.ssid);
+
+	for (i = 0; bss_desc->supported_rates[i] &&
+			i < MWIFIEX_SUPPORTED_RATES;
+			i++)
+			;
+	rates_size = i;
+
+	/* Copy Data Rates from the Rates recorded in scan response */
+	memset(adhoc_join->bss_descriptor.data_rates, 0,
+	       sizeof(adhoc_join->bss_descriptor.data_rates));
+	memcpy(adhoc_join->bss_descriptor.data_rates,
+	       bss_desc->supported_rates, rates_size);
+
+	/* Copy the adhoc join rates into Current BSS state structure */
+	priv->curr_bss_params.num_of_rates = rates_size;
+	memcpy(&priv->curr_bss_params.data_rates, bss_desc->supported_rates,
+	       rates_size);
+
+	/* Copy the channel information */
+	priv->curr_bss_params.bss_descriptor.channel = bss_desc->channel;
+	priv->curr_bss_params.band = (u8) bss_desc->bss_band;
+
+	if (priv->sec_info.wep_status == MWIFIEX_802_11_WEP_ENABLED
+	    || priv->sec_info.wpa_enabled)
+		tmp_cap |= WLAN_CAPABILITY_PRIVACY;
+
+	if (IS_SUPPORT_MULTI_BANDS(priv->adapter)) {
+		/* Append a channel TLV */
+		chan_tlv = (struct mwifiex_ie_types_chan_list_param_set *) pos;
+		chan_tlv->header.type = cpu_to_le16(TLV_TYPE_CHANLIST);
+		chan_tlv->header.len =
+			cpu_to_le16(sizeof(struct mwifiex_chan_scan_param_set));
+
+		memset(chan_tlv->chan_scan_param, 0x00,
+		       sizeof(struct mwifiex_chan_scan_param_set));
+		chan_tlv->chan_scan_param[0].chan_number =
+			(bss_desc->phy_param_set.ds_param_set.current_chan);
+		dev_dbg(priv->adapter->dev, "info: ADHOC_J_CMD: TLV Chan = %d\n",
+		       chan_tlv->chan_scan_param[0].chan_number);
+
+		chan_tlv->chan_scan_param[0].radio_type =
+			mwifiex_band_to_radio_type((u8) bss_desc->bss_band);
+
+		dev_dbg(priv->adapter->dev, "info: ADHOC_J_CMD: TLV Band = %d\n",
+		       chan_tlv->chan_scan_param[0].radio_type);
+		pos += sizeof(chan_tlv->header) +
+			sizeof(struct mwifiex_chan_scan_param_set);
+		cmd_append_size += sizeof(chan_tlv->header) +
+			sizeof(struct mwifiex_chan_scan_param_set);
+	}
+
+	if (priv->sec_info.wpa_enabled)
+		rsn_ie_len = mwifiex_append_rsn_ie_wpa_wpa2(priv, &pos);
+	if (rsn_ie_len == -1)
+		return -1;
+	cmd_append_size += rsn_ie_len;
+
+	if (ISSUPP_11NENABLED(priv->adapter->fw_cap_info))
+		cmd_append_size += mwifiex_cmd_append_11n_tlv(priv,
+			bss_desc, &pos);
+
+	/* Append vendor specific IE TLV */
+	cmd_append_size += mwifiex_cmd_append_vsie_tlv(priv,
+			MWIFIEX_VSIE_MASK_ADHOC, &pos);
+
+	cmd->size = cpu_to_le16((u16)
+			    (sizeof(struct host_cmd_ds_802_11_ad_hoc_join)
+			     + S_DS_GEN + cmd_append_size));
+
+	adhoc_join->bss_descriptor.cap_info_bitmap = cpu_to_le16(tmp_cap);
+
+	return 0;
+}
+
+/*
+ * This function handles the command response of ad-hoc start and
+ * ad-hoc join.
+ *
+ * The function generates a device-connected event to notify
+ * the applications, in case of successful ad-hoc start/join, and
+ * saves the beacon buffer.
+ */
+int mwifiex_ret_802_11_ad_hoc(struct mwifiex_private *priv,
+			      struct host_cmd_ds_command *resp)
+{
+	int ret = 0;
+	struct mwifiex_adapter *adapter = priv->adapter;
+	struct host_cmd_ds_802_11_ad_hoc_result *adhoc_result;
+	struct mwifiex_bssdescriptor *bss_desc;
+
+	adhoc_result = &resp->params.adhoc_result;
+
+	bss_desc = priv->attempted_bss_desc;
+
+	/* Join result code 0 --> SUCCESS */
+	if (le16_to_cpu(resp->result)) {
+		dev_err(priv->adapter->dev, "ADHOC_RESP: failed\n");
+		if (priv->media_connected)
+			mwifiex_reset_connect_state(priv);
+
+		memset(&priv->curr_bss_params.bss_descriptor,
+		       0x00, sizeof(struct mwifiex_bssdescriptor));
+
+		ret = -1;
+		goto done;
+	}
+
+	/* Send a Media Connected event, according to the Spec */
+	priv->media_connected = true;
+
+	if (le16_to_cpu(resp->command) == HostCmd_CMD_802_11_AD_HOC_START) {
+		dev_dbg(priv->adapter->dev, "info: ADHOC_S_RESP %s\n",
+				bss_desc->ssid.ssid);
+
+		/* Update the created network descriptor with the new BSSID */
+		memcpy(bss_desc->mac_address,
+		       adhoc_result->bssid, ETH_ALEN);
+
+		priv->adhoc_state = ADHOC_STARTED;
+	} else {
+		/*
+		 * Now the join cmd should be successful.
+		 * If BSSID has changed use SSID to compare instead of BSSID
+		 */
+		dev_dbg(priv->adapter->dev, "info: ADHOC_J_RESP %s\n",
+				bss_desc->ssid.ssid);
+
+		/*
+		 * Make a copy of current BSSID descriptor, only needed for
+		 * join since the current descriptor is already being used
+		 * for adhoc start
+		 */
+		memcpy(&priv->curr_bss_params.bss_descriptor,
+		       bss_desc, sizeof(struct mwifiex_bssdescriptor));
+
+		priv->adhoc_state = ADHOC_JOINED;
+	}
+
+	dev_dbg(priv->adapter->dev, "info: ADHOC_RESP: channel = %d\n",
+				priv->adhoc_channel);
+	dev_dbg(priv->adapter->dev, "info: ADHOC_RESP: BSSID = %pM\n",
+	       priv->curr_bss_params.bss_descriptor.mac_address);
+
+	if (!netif_carrier_ok(priv->netdev))
+		netif_carrier_on(priv->netdev);
+	if (netif_queue_stopped(priv->netdev))
+		netif_wake_queue(priv->netdev);
+
+	mwifiex_save_curr_bcn(priv);
+
+done:
+	/* Need to indicate IOCTL complete */
+	if (adapter->curr_cmd->wait_q_enabled) {
+		if (ret)
+			adapter->cmd_wait_q.status = -1;
+		else
+			adapter->cmd_wait_q.status = 0;
+
+	}
+
+	return ret;
+}
+
+/*
+ * This function associates to a specific BSS discovered in a scan.
+ *
+ * It clears any past association response stored for application
+ * retrieval and calls the command preparation routine to send the
+ * command to firmware.
+ */
+int mwifiex_associate(struct mwifiex_private *priv,
+		      struct mwifiex_bssdescriptor *bss_desc)
+{
+	u8 current_bssid[ETH_ALEN];
+
+	/* Return error if the adapter or table entry is not marked as infra */
+	if ((priv->bss_mode != NL80211_IFTYPE_STATION) ||
+	    (bss_desc->bss_mode != NL80211_IFTYPE_STATION))
+		return -1;
+
+	memcpy(&current_bssid,
+	       &priv->curr_bss_params.bss_descriptor.mac_address,
+	       sizeof(current_bssid));
+
+	/* Clear any past association response stored for application
+	   retrieval */
+	priv->assoc_rsp_size = 0;
+
+	return mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_ASSOCIATE,
+				    HostCmd_ACT_GEN_SET, 0, bss_desc);
+}
+
+/*
+ * This function starts an ad-hoc network.
+ *
+ * It calls the command preparation routine to send the command to firmware.
+ */
+int
+mwifiex_adhoc_start(struct mwifiex_private *priv,
+		    struct mwifiex_802_11_ssid *adhoc_ssid)
+{
+	dev_dbg(priv->adapter->dev, "info: Adhoc Channel = %d\n",
+		priv->adhoc_channel);
+	dev_dbg(priv->adapter->dev, "info: curr_bss_params.channel = %d\n",
+	       priv->curr_bss_params.bss_descriptor.channel);
+	dev_dbg(priv->adapter->dev, "info: curr_bss_params.band = %d\n",
+	       priv->curr_bss_params.band);
+
+	return mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_AD_HOC_START,
+				    HostCmd_ACT_GEN_SET, 0, adhoc_ssid);
+}
+
+/*
+ * This function joins an ad-hoc network found in a previous scan.
+ *
+ * It calls the command preparation routine to send the command to firmware,
+ * if already not connected to the requested SSID.
+ */
+int mwifiex_adhoc_join(struct mwifiex_private *priv,
+		       struct mwifiex_bssdescriptor *bss_desc)
+{
+	dev_dbg(priv->adapter->dev, "info: adhoc join: curr_bss ssid =%s\n",
+	       priv->curr_bss_params.bss_descriptor.ssid.ssid);
+	dev_dbg(priv->adapter->dev, "info: adhoc join: curr_bss ssid_len =%u\n",
+	       priv->curr_bss_params.bss_descriptor.ssid.ssid_len);
+	dev_dbg(priv->adapter->dev, "info: adhoc join: ssid =%s\n",
+		bss_desc->ssid.ssid);
+	dev_dbg(priv->adapter->dev, "info: adhoc join: ssid_len =%u\n",
+	       bss_desc->ssid.ssid_len);
+
+	/* Check if the requested SSID is already joined */
+	if (priv->curr_bss_params.bss_descriptor.ssid.ssid_len &&
+	    !mwifiex_ssid_cmp(&bss_desc->ssid,
+			      &priv->curr_bss_params.bss_descriptor.ssid) &&
+	    (priv->curr_bss_params.bss_descriptor.bss_mode ==
+							NL80211_IFTYPE_ADHOC)) {
+		dev_dbg(priv->adapter->dev, "info: ADHOC_J_CMD: new ad-hoc SSID"
+			" is the same as current; not attempting to re-join\n");
+		return -1;
+	}
+
+	dev_dbg(priv->adapter->dev, "info: curr_bss_params.channel = %d\n",
+	       priv->curr_bss_params.bss_descriptor.channel);
+	dev_dbg(priv->adapter->dev, "info: curr_bss_params.band = %c\n",
+	       priv->curr_bss_params.band);
+
+	return mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_AD_HOC_JOIN,
+				    HostCmd_ACT_GEN_SET, 0, bss_desc);
+}
+
+/*
+ * This function deauthenticates/disconnects from infra network by sending
+ * deauthentication request.
+ */
+static int mwifiex_deauthenticate_infra(struct mwifiex_private *priv, u8 *mac)
+{
+	u8 mac_address[ETH_ALEN];
+	int ret;
+	u8 zero_mac[ETH_ALEN] = { 0, 0, 0, 0, 0, 0 };
+
+	if (mac) {
+		if (!memcmp(mac, zero_mac, sizeof(zero_mac)))
+			memcpy((u8 *) &mac_address,
+			       (u8 *) &priv->curr_bss_params.bss_descriptor.
+			       mac_address, ETH_ALEN);
+		else
+			memcpy((u8 *) &mac_address, (u8 *) mac, ETH_ALEN);
+	} else {
+		memcpy((u8 *) &mac_address, (u8 *) &priv->curr_bss_params.
+		       bss_descriptor.mac_address, ETH_ALEN);
+	}
+
+	ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_DEAUTHENTICATE,
+				    HostCmd_ACT_GEN_SET, 0, &mac_address);
+
+	return ret;
+}
+
+/*
+ * This function deauthenticates/disconnects from a BSS.
+ *
+ * In case of infra made, it sends deauthentication request, and
+ * in case of ad-hoc mode, a stop network request is sent to the firmware.
+ */
+int mwifiex_deauthenticate(struct mwifiex_private *priv, u8 *mac)
+{
+	int ret = 0;
+
+	if (priv->media_connected) {
+		if (priv->bss_mode == NL80211_IFTYPE_STATION) {
+			ret = mwifiex_deauthenticate_infra(priv, mac);
+		} else if (priv->bss_mode == NL80211_IFTYPE_ADHOC) {
+			ret = mwifiex_send_cmd_sync(priv,
+						HostCmd_CMD_802_11_AD_HOC_STOP,
+						HostCmd_ACT_GEN_SET, 0, NULL);
+		}
+	}
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(mwifiex_deauthenticate);
+
+/*
+ * This function converts band to radio type used in channel TLV.
+ */
+u8
+mwifiex_band_to_radio_type(u8 band)
+{
+	switch (band) {
+	case BAND_A:
+	case BAND_AN:
+	case BAND_A | BAND_AN:
+		return HostCmd_SCAN_RADIO_TYPE_A;
+	case BAND_B:
+	case BAND_G:
+	case BAND_B | BAND_G:
+	default:
+		return HostCmd_SCAN_RADIO_TYPE_BG;
+	}
+}
diff -druN linux-2.6.39-libre/drivers/net/wireless/mwifiex/Kconfig linux-3.0-rc7-libre/drivers/net/wireless/mwifiex/Kconfig
--- linux-2.6.39-libre/drivers/net/wireless/mwifiex/Kconfig	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/net/wireless/mwifiex/Kconfig	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,21 @@
+config MWIFIEX
+	tristate "Marvell WiFi-Ex Driver"
+	depends on CFG80211
+	select LIB80211
+	---help---
+	  This adds support for wireless adapters based on Marvell
+	  802.11n chipsets.
+
+	  If you choose to build it as a module, it will be called
+	  mwifiex.
+
+config MWIFIEX_SDIO
+	tristate "Marvell WiFi-Ex Driver for SD8787"
+	depends on MWIFIEX && MMC
+	select FW_LOADER
+	---help---
+	  This adds support for wireless adapters based on Marvell
+	  8787 chipset with SDIO interface.
+
+	  If you choose to build it as a module, it will be called
+	  mwifiex_sdio.
diff -druN linux-2.6.39-libre/drivers/net/wireless/mwifiex/main.c linux-3.0-rc7-libre/drivers/net/wireless/mwifiex/main.c
--- linux-2.6.39-libre/drivers/net/wireless/mwifiex/main.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/net/wireless/mwifiex/main.c	2011-07-21 06:57:18.000000000 -0400
@@ -0,0 +1,1055 @@
+/*
+ * Marvell Wireless LAN device driver: major functions
+ *
+ * Copyright (C) 2011, Marvell International Ltd.
+ *
+ * This software file (the "File") is distributed by Marvell International
+ * Ltd. under the terms of the GNU General Public License Version 2, June 1991
+ * (the "License").  You may use, redistribute and/or modify this File in
+ * accordance with the terms and conditions of the License, a copy of which
+ * is available by writing to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
+ * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
+ *
+ * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
+ * ARE EXPRESSLY DISCLAIMED.  The License provides additional details about
+ * this warranty disclaimer.
+ */
+
+#include "main.h"
+#include "wmm.h"
+#include "cfg80211.h"
+#include "11n.h"
+
+#define VERSION	"1.0"
+
+const char driver_version[] = "mwifiex " VERSION " (%s) ";
+
+struct mwifiex_adapter *g_adapter;
+EXPORT_SYMBOL_GPL(g_adapter);
+
+static struct mwifiex_bss_attr mwifiex_bss_sta[] = {
+	{MWIFIEX_BSS_TYPE_STA, MWIFIEX_DATA_FRAME_TYPE_ETH_II, true, 0, 0},
+};
+
+static int drv_mode = DRV_MODE_STA;
+
+static char fw_name[32] = DEFAULT_FW_NAME;
+
+/* Supported drv_mode table */
+static struct mwifiex_drv_mode mwifiex_drv_mode_tbl[] = {
+	{
+		.drv_mode = DRV_MODE_STA,
+		.intf_num = ARRAY_SIZE(mwifiex_bss_sta),
+		.bss_attr = mwifiex_bss_sta,
+	},
+};
+
+/*
+ * This function registers the device and performs all the necessary
+ * initializations.
+ *
+ * The following initialization operations are performed -
+ *      - Allocate adapter structure
+ *      - Save interface specific operations table in adapter
+ *      - Call interface specific initialization routine
+ *      - Allocate private structures
+ *      - Set default adapter structure parameters
+ *      - Initialize locks
+ *
+ * In case of any errors during inittialization, this function also ensures
+ * proper cleanup before exiting.
+ */
+static int mwifiex_register(void *card, struct mwifiex_if_ops *if_ops,
+			    struct mwifiex_drv_mode *drv_mode_ptr)
+{
+	struct mwifiex_adapter *adapter;
+	int i;
+
+	adapter = kzalloc(sizeof(struct mwifiex_adapter), GFP_KERNEL);
+	if (!adapter)
+		return -ENOMEM;
+
+	g_adapter = adapter;
+	adapter->card = card;
+
+	/* Save interface specific operations in adapter */
+	memmove(&adapter->if_ops, if_ops, sizeof(struct mwifiex_if_ops));
+
+	/* card specific initialization has been deferred until now .. */
+	if (adapter->if_ops.init_if(adapter))
+		goto error;
+
+	adapter->priv_num = 0;
+	for (i = 0; i < drv_mode_ptr->intf_num; i++) {
+		adapter->priv[i] = NULL;
+
+		if (!drv_mode_ptr->bss_attr[i].active)
+			continue;
+
+		/* Allocate memory for private structure */
+		adapter->priv[i] = kzalloc(sizeof(struct mwifiex_private),
+				GFP_KERNEL);
+		if (!adapter->priv[i]) {
+			dev_err(adapter->dev, "%s: failed to alloc priv[%d]\n",
+			       __func__, i);
+			goto error;
+		}
+
+		adapter->priv_num++;
+		adapter->priv[i]->adapter = adapter;
+		/* Save bss_type, frame_type & bss_priority */
+		adapter->priv[i]->bss_type = drv_mode_ptr->bss_attr[i].bss_type;
+		adapter->priv[i]->frame_type =
+					drv_mode_ptr->bss_attr[i].frame_type;
+		adapter->priv[i]->bss_priority =
+					drv_mode_ptr->bss_attr[i].bss_priority;
+
+		if (drv_mode_ptr->bss_attr[i].bss_type == MWIFIEX_BSS_TYPE_STA)
+			adapter->priv[i]->bss_role = MWIFIEX_BSS_ROLE_STA;
+		else if (drv_mode_ptr->bss_attr[i].bss_type ==
+							MWIFIEX_BSS_TYPE_UAP)
+			adapter->priv[i]->bss_role = MWIFIEX_BSS_ROLE_UAP;
+
+		/* Save bss_index & bss_num */
+		adapter->priv[i]->bss_index = i;
+		adapter->priv[i]->bss_num = drv_mode_ptr->bss_attr[i].bss_num;
+	}
+	adapter->drv_mode = drv_mode_ptr;
+
+	if (mwifiex_init_lock_list(adapter))
+		goto error;
+
+	init_timer(&adapter->cmd_timer);
+	adapter->cmd_timer.function = mwifiex_cmd_timeout_func;
+	adapter->cmd_timer.data = (unsigned long) adapter;
+
+	return 0;
+
+error:
+	dev_dbg(adapter->dev, "info: leave mwifiex_register with error\n");
+
+	mwifiex_free_lock_list(adapter);
+	for (i = 0; i < drv_mode_ptr->intf_num; i++)
+		kfree(adapter->priv[i]);
+	kfree(adapter);
+
+	return -1;
+}
+
+/*
+ * This function unregisters the device and performs all the necessary
+ * cleanups.
+ *
+ * The following cleanup operations are performed -
+ *      - Free the timers
+ *      - Free beacon buffers
+ *      - Free private structures
+ *      - Free adapter structure
+ */
+static int mwifiex_unregister(struct mwifiex_adapter *adapter)
+{
+	s32 i;
+
+	del_timer(&adapter->cmd_timer);
+
+	/* Free private structures */
+	for (i = 0; i < adapter->priv_num; i++) {
+		if (adapter->priv[i]) {
+			mwifiex_free_curr_bcn(adapter->priv[i]);
+			kfree(adapter->priv[i]);
+		}
+	}
+
+	kfree(adapter);
+	return 0;
+}
+
+/*
+ * The main process.
+ *
+ * This function is the main procedure of the driver and handles various driver
+ * operations. It runs in a loop and provides the core functionalities.
+ *
+ * The main responsibilities of this function are -
+ *      - Ensure concurrency control
+ *      - Handle pending interrupts and call interrupt handlers
+ *      - Wake up the card if required
+ *      - Handle command responses and call response handlers
+ *      - Handle events and call event handlers
+ *      - Execute pending commands
+ *      - Transmit pending data packets
+ */
+int mwifiex_main_process(struct mwifiex_adapter *adapter)
+{
+	int ret = 0;
+	unsigned long flags;
+
+	spin_lock_irqsave(&adapter->main_proc_lock, flags);
+
+	/* Check if already processing */
+	if (adapter->mwifiex_processing) {
+		spin_unlock_irqrestore(&adapter->main_proc_lock, flags);
+		goto exit_main_proc;
+	} else {
+		adapter->mwifiex_processing = true;
+		spin_unlock_irqrestore(&adapter->main_proc_lock, flags);
+	}
+process_start:
+	do {
+		if ((adapter->hw_status == MWIFIEX_HW_STATUS_CLOSING) ||
+		    (adapter->hw_status == MWIFIEX_HW_STATUS_NOT_READY))
+			break;
+
+		/* Handle pending interrupt if any */
+		if (adapter->int_status) {
+			if (adapter->hs_activated)
+				mwifiex_process_hs_config(adapter);
+			adapter->if_ops.process_int_status(adapter);
+		}
+
+		/* Need to wake up the card ? */
+		if ((adapter->ps_state == PS_STATE_SLEEP) &&
+		    (adapter->pm_wakeup_card_req &&
+		     !adapter->pm_wakeup_fw_try) &&
+		    (is_command_pending(adapter)
+		     || !mwifiex_wmm_lists_empty(adapter))) {
+			adapter->pm_wakeup_fw_try = true;
+			adapter->if_ops.wakeup(adapter);
+			continue;
+		}
+		if (IS_CARD_RX_RCVD(adapter)) {
+			adapter->pm_wakeup_fw_try = false;
+			if (adapter->ps_state == PS_STATE_SLEEP)
+				adapter->ps_state = PS_STATE_AWAKE;
+		} else {
+			/* We have tried to wakeup the card already */
+			if (adapter->pm_wakeup_fw_try)
+				break;
+			if (adapter->ps_state != PS_STATE_AWAKE ||
+			    adapter->tx_lock_flag)
+				break;
+
+			if (adapter->scan_processing || adapter->data_sent
+			    || mwifiex_wmm_lists_empty(adapter)) {
+				if (adapter->cmd_sent || adapter->curr_cmd
+				    || (!is_command_pending(adapter)))
+					break;
+			}
+		}
+
+		/* Check for Cmd Resp */
+		if (adapter->cmd_resp_received) {
+			adapter->cmd_resp_received = false;
+			mwifiex_process_cmdresp(adapter);
+
+			/* call mwifiex back when init_fw is done */
+			if (adapter->hw_status == MWIFIEX_HW_STATUS_INIT_DONE) {
+				adapter->hw_status = MWIFIEX_HW_STATUS_READY;
+				mwifiex_init_fw_complete(adapter);
+			}
+		}
+
+		/* Check for event */
+		if (adapter->event_received) {
+			adapter->event_received = false;
+			mwifiex_process_event(adapter);
+		}
+
+		/* Check if we need to confirm Sleep Request
+		   received previously */
+		if (adapter->ps_state == PS_STATE_PRE_SLEEP) {
+			if (!adapter->cmd_sent && !adapter->curr_cmd)
+				mwifiex_check_ps_cond(adapter);
+		}
+
+		/* * The ps_state may have been changed during processing of
+		 * Sleep Request event.
+		 */
+		if ((adapter->ps_state == PS_STATE_SLEEP)
+		    || (adapter->ps_state == PS_STATE_PRE_SLEEP)
+		    || (adapter->ps_state == PS_STATE_SLEEP_CFM)
+		    || adapter->tx_lock_flag)
+			continue;
+
+		if (!adapter->cmd_sent && !adapter->curr_cmd) {
+			if (mwifiex_exec_next_cmd(adapter) == -1) {
+				ret = -1;
+				break;
+			}
+		}
+
+		if (!adapter->scan_processing && !adapter->data_sent &&
+		    !mwifiex_wmm_lists_empty(adapter)) {
+			mwifiex_wmm_process_tx(adapter);
+			if (adapter->hs_activated) {
+				adapter->is_hs_configured = false;
+				mwifiex_hs_activated_event
+					(mwifiex_get_priv
+					 (adapter, MWIFIEX_BSS_ROLE_ANY),
+					 false);
+			}
+		}
+
+		if (adapter->delay_null_pkt && !adapter->cmd_sent &&
+		    !adapter->curr_cmd && !is_command_pending(adapter)
+		    && mwifiex_wmm_lists_empty(adapter)) {
+			if (!mwifiex_send_null_packet
+			    (mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_STA),
+			     MWIFIEX_TxPD_POWER_MGMT_NULL_PACKET |
+			     MWIFIEX_TxPD_POWER_MGMT_LAST_PACKET)) {
+				adapter->delay_null_pkt = false;
+				adapter->ps_state = PS_STATE_SLEEP;
+			}
+			break;
+		}
+	} while (true);
+
+	if ((adapter->int_status) || IS_CARD_RX_RCVD(adapter))
+		goto process_start;
+
+	spin_lock_irqsave(&adapter->main_proc_lock, flags);
+	adapter->mwifiex_processing = false;
+	spin_unlock_irqrestore(&adapter->main_proc_lock, flags);
+
+exit_main_proc:
+	if (adapter->hw_status == MWIFIEX_HW_STATUS_CLOSING)
+		mwifiex_shutdown_drv(adapter);
+	return ret;
+}
+
+/*
+ * This function initializes the software.
+ *
+ * The main work includes allocating and initializing the adapter structure
+ * and initializing the private structures.
+ */
+static int
+mwifiex_init_sw(void *card, struct mwifiex_if_ops *if_ops)
+{
+	int i;
+	struct mwifiex_drv_mode *drv_mode_ptr;
+
+	/* find mwifiex_drv_mode entry from mwifiex_drv_mode_tbl */
+	drv_mode_ptr = NULL;
+	for (i = 0; i < ARRAY_SIZE(mwifiex_drv_mode_tbl); i++) {
+		if (mwifiex_drv_mode_tbl[i].drv_mode == drv_mode) {
+			drv_mode_ptr = &mwifiex_drv_mode_tbl[i];
+			break;
+		}
+	}
+
+	if (!drv_mode_ptr) {
+		pr_err("invalid drv_mode=%d\n", drv_mode);
+		return -1;
+	}
+
+	if (mwifiex_register(card, if_ops, drv_mode_ptr))
+		return -1;
+
+	return 0;
+}
+
+/*
+ * This function frees the adapter structure.
+ *
+ * Additionally, this closes the netlink socket, frees the timers
+ * and private structures.
+ */
+static void mwifiex_free_adapter(struct mwifiex_adapter *adapter)
+{
+	if (!adapter) {
+		pr_err("%s: adapter is NULL\n", __func__);
+		return;
+	}
+
+	mwifiex_unregister(adapter);
+	pr_debug("info: %s: free adapter\n", __func__);
+}
+
+/*
+ * This function initializes the hardware and firmware.
+ *
+ * The main initialization steps followed are -
+ *      - Download the correct firmware to card
+ *      - Allocate and initialize the adapter structure
+ *      - Initialize the private structures
+ *      - Issue the init commands to firmware
+ */
+static int mwifiex_init_hw_fw(struct mwifiex_adapter *adapter)
+{
+	int ret, err;
+	struct mwifiex_fw_image fw;
+
+	memset(&fw, 0, sizeof(struct mwifiex_fw_image));
+
+	switch (adapter->revision_id) {
+	case SD8787_W0:
+	case SD8787_W1:
+		strcpy(fw_name, SD8787_W1_FW_NAME);
+		break;
+	case SD8787_A0:
+	case SD8787_A1:
+		strcpy(fw_name, SD8787_AX_FW_NAME);
+		break;
+	default:
+		break;
+	}
+
+	err = reject_firmware(&adapter->firmware, fw_name, adapter->dev);
+	if (err < 0) {
+		dev_err(adapter->dev, "reject_firmware() returned"
+				" error code %#x\n", err);
+		ret = -1;
+		goto done;
+	}
+	fw.fw_buf = (u8 *) adapter->firmware->data;
+	fw.fw_len = adapter->firmware->size;
+
+	ret = mwifiex_dnld_fw(adapter, &fw);
+	if (ret == -1)
+		goto done;
+
+	dev_notice(adapter->dev, "WLAN FW is active\n");
+
+	adapter->init_wait_q_woken = false;
+	ret = mwifiex_init_fw(adapter);
+	if (ret == -1) {
+		goto done;
+	} else if (!ret) {
+		adapter->hw_status = MWIFIEX_HW_STATUS_READY;
+		goto done;
+	}
+	/* Wait for mwifiex_init to complete */
+	wait_event_interruptible(adapter->init_wait_q,
+				 adapter->init_wait_q_woken);
+	if (adapter->hw_status != MWIFIEX_HW_STATUS_READY) {
+		ret = -1;
+		goto done;
+	}
+	ret = 0;
+
+done:
+	if (adapter->firmware)
+		release_firmware(adapter->firmware);
+	if (ret)
+		ret = -1;
+	return ret;
+}
+
+/*
+ * This function fills a driver buffer.
+ *
+ * The function associates a given SKB with the provided driver buffer
+ * and also updates some of the SKB parameters, including IP header,
+ * priority and timestamp.
+ */
+static void
+mwifiex_fill_buffer(struct sk_buff *skb)
+{
+	struct ethhdr *eth;
+	struct iphdr *iph;
+	struct timeval tv;
+	u8 tid = 0;
+
+	eth = (struct ethhdr *) skb->data;
+	switch (eth->h_proto) {
+	case __constant_htons(ETH_P_IP):
+		iph = ip_hdr(skb);
+		tid = IPTOS_PREC(iph->tos);
+		pr_debug("data: packet type ETH_P_IP: %04x, tid=%#x prio=%#x\n",
+		       eth->h_proto, tid, skb->priority);
+		break;
+	case __constant_htons(ETH_P_ARP):
+		pr_debug("data: ARP packet: %04x\n", eth->h_proto);
+	default:
+		break;
+	}
+/* Offset for TOS field in the IP header */
+#define IPTOS_OFFSET 5
+	tid = (tid >> IPTOS_OFFSET);
+	skb->priority = tid;
+	/* Record the current time the packet was queued; used to
+	   determine the amount of time the packet was queued in
+	   the driver before it was sent to the firmware.
+	   The delay is then sent along with the packet to the
+	   firmware for aggregate delay calculation for stats and
+	   MSDU lifetime expiry.
+	 */
+	do_gettimeofday(&tv);
+	skb->tstamp = timeval_to_ktime(tv);
+}
+
+/*
+ * CFG802.11 network device handler for open.
+ *
+ * Starts the data queue.
+ */
+static int
+mwifiex_open(struct net_device *dev)
+{
+	netif_start_queue(dev);
+	return 0;
+}
+
+/*
+ * CFG802.11 network device handler for close.
+ */
+static int
+mwifiex_close(struct net_device *dev)
+{
+	return 0;
+}
+
+/*
+ * CFG802.11 network device handler for data transmission.
+ */
+static int
+mwifiex_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+	struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
+	struct sk_buff *new_skb;
+	struct mwifiex_txinfo *tx_info;
+
+	dev_dbg(priv->adapter->dev, "data: %lu BSS(%d): Data <= kernel\n",
+				jiffies, priv->bss_index);
+
+	if (priv->adapter->surprise_removed) {
+		kfree_skb(skb);
+		priv->stats.tx_dropped++;
+		return 0;
+	}
+	if (!skb->len || (skb->len > ETH_FRAME_LEN)) {
+		dev_err(priv->adapter->dev, "Tx: bad skb len %d\n", skb->len);
+		kfree_skb(skb);
+		priv->stats.tx_dropped++;
+		return 0;
+	}
+	if (skb_headroom(skb) < MWIFIEX_MIN_DATA_HEADER_LEN) {
+		dev_dbg(priv->adapter->dev,
+			"data: Tx: insufficient skb headroom %d\n",
+		       skb_headroom(skb));
+		/* Insufficient skb headroom - allocate a new skb */
+		new_skb =
+			skb_realloc_headroom(skb, MWIFIEX_MIN_DATA_HEADER_LEN);
+		if (unlikely(!new_skb)) {
+			dev_err(priv->adapter->dev, "Tx: cannot alloca new_skb\n");
+			kfree_skb(skb);
+			priv->stats.tx_dropped++;
+			return 0;
+		}
+		kfree_skb(skb);
+		skb = new_skb;
+		dev_dbg(priv->adapter->dev, "info: new skb headroomd %d\n",
+				skb_headroom(skb));
+	}
+
+	tx_info = MWIFIEX_SKB_TXCB(skb);
+	tx_info->bss_index = priv->bss_index;
+	mwifiex_fill_buffer(skb);
+
+	mwifiex_wmm_add_buf_txqueue(priv->adapter, skb);
+	atomic_inc(&priv->adapter->tx_pending);
+
+	if (atomic_read(&priv->adapter->tx_pending) >= MAX_TX_PENDING) {
+		netif_stop_queue(priv->netdev);
+		dev->trans_start = jiffies;
+	}
+
+	queue_work(priv->adapter->workqueue, &priv->adapter->main_work);
+
+	return 0;
+}
+
+/*
+ * CFG802.11 network device handler for setting MAC address.
+ */
+static int
+mwifiex_set_mac_address(struct net_device *dev, void *addr)
+{
+	struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
+	struct sockaddr *hw_addr = (struct sockaddr *) addr;
+	int ret;
+
+	memcpy(priv->curr_addr, hw_addr->sa_data, ETH_ALEN);
+
+	/* Send request to firmware */
+	ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_MAC_ADDRESS,
+				    HostCmd_ACT_GEN_SET, 0, NULL);
+
+	if (!ret)
+		memcpy(priv->netdev->dev_addr, priv->curr_addr, ETH_ALEN);
+	else
+		dev_err(priv->adapter->dev, "set mac address failed: ret=%d"
+					    "\n", ret);
+
+	memcpy(dev->dev_addr, priv->curr_addr, ETH_ALEN);
+
+	return ret;
+}
+
+/*
+ * CFG802.11 network device handler for setting multicast list.
+ */
+static void mwifiex_set_multicast_list(struct net_device *dev)
+{
+	struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
+	struct mwifiex_multicast_list mcast_list;
+
+	if (dev->flags & IFF_PROMISC) {
+		mcast_list.mode = MWIFIEX_PROMISC_MODE;
+	} else if (dev->flags & IFF_ALLMULTI ||
+		   netdev_mc_count(dev) > MWIFIEX_MAX_MULTICAST_LIST_SIZE) {
+		mcast_list.mode = MWIFIEX_ALL_MULTI_MODE;
+	} else {
+		mcast_list.mode = MWIFIEX_MULTICAST_MODE;
+		if (netdev_mc_count(dev))
+			mcast_list.num_multicast_addr =
+				mwifiex_copy_mcast_addr(&mcast_list, dev);
+	}
+	mwifiex_request_set_multicast_list(priv, &mcast_list);
+}
+
+/*
+ * CFG802.11 network device handler for transmission timeout.
+ */
+static void
+mwifiex_tx_timeout(struct net_device *dev)
+{
+	struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
+
+	dev_err(priv->adapter->dev, "%lu : Tx timeout, bss_index=%d\n",
+				jiffies, priv->bss_index);
+	dev->trans_start = jiffies;
+	priv->num_tx_timeout++;
+}
+
+/*
+ * CFG802.11 network device handler for statistics retrieval.
+ */
+static struct net_device_stats *mwifiex_get_stats(struct net_device *dev)
+{
+	struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
+
+	return &priv->stats;
+}
+
+/* Network device handlers */
+static const struct net_device_ops mwifiex_netdev_ops = {
+	.ndo_open = mwifiex_open,
+	.ndo_stop = mwifiex_close,
+	.ndo_start_xmit = mwifiex_hard_start_xmit,
+	.ndo_set_mac_address = mwifiex_set_mac_address,
+	.ndo_tx_timeout = mwifiex_tx_timeout,
+	.ndo_get_stats = mwifiex_get_stats,
+	.ndo_set_multicast_list = mwifiex_set_multicast_list,
+};
+
+/*
+ * This function initializes the private structure parameters.
+ *
+ * The following wait queues are initialized -
+ *      - IOCTL wait queue
+ *      - Command wait queue
+ *      - Statistics wait queue
+ *
+ * ...and the following default parameters are set -
+ *      - Current key index     : Set to 0
+ *      - Rate index            : Set to auto
+ *      - Media connected       : Set to disconnected
+ *      - Adhoc link sensed     : Set to false
+ *      - Nick name             : Set to null
+ *      - Number of Tx timeout  : Set to 0
+ *      - Device address        : Set to current address
+ *
+ * In addition, the CFG80211 work queue is also created.
+ */
+static void
+mwifiex_init_priv_params(struct mwifiex_private *priv, struct net_device *dev)
+{
+	dev->netdev_ops = &mwifiex_netdev_ops;
+	/* Initialize private structure */
+	priv->current_key_index = 0;
+	priv->media_connected = false;
+	memset(&priv->nick_name, 0, sizeof(priv->nick_name));
+	priv->num_tx_timeout = 0;
+	priv->workqueue = create_singlethread_workqueue("cfg80211_wq");
+	INIT_WORK(&priv->cfg_workqueue, mwifiex_cfg80211_results);
+	memcpy(dev->dev_addr, priv->curr_addr, ETH_ALEN);
+}
+
+/*
+ * This function adds a new logical interface.
+ *
+ * It allocates, initializes and registers the interface by performing
+ * the following opearations -
+ *      - Allocate a new net device structure
+ *      - Assign device name
+ *      - Register the new device with CFG80211 subsystem
+ *      - Initialize semaphore and private structure
+ *      - Register the new device with kernel
+ *      - Create the complete debug FS structure if configured
+ */
+static struct mwifiex_private *mwifiex_add_interface(
+			struct mwifiex_adapter *adapter,
+			u8 bss_index, u8 bss_type)
+{
+	struct net_device *dev;
+	struct mwifiex_private *priv;
+	void *mdev_priv;
+
+	dev = alloc_netdev_mq(sizeof(struct mwifiex_private *), "mlan%d",
+			      ether_setup, 1);
+	if (!dev) {
+		dev_err(adapter->dev, "no memory available for netdevice\n");
+		goto error;
+	}
+
+	if (mwifiex_register_cfg80211(dev, adapter->priv[bss_index]->curr_addr,
+				      adapter->priv[bss_index]) != 0) {
+		dev_err(adapter->dev, "cannot register netdevice with cfg80211\n");
+		goto error;
+	}
+	/* Save the priv pointer in netdev */
+	priv = adapter->priv[bss_index];
+	mdev_priv = netdev_priv(dev);
+	*((unsigned long *) mdev_priv) = (unsigned long) priv;
+
+	priv->netdev = dev;
+
+	sema_init(&priv->async_sem, 1);
+	priv->scan_pending_on_block = false;
+
+	mwifiex_init_priv_params(priv, dev);
+
+	SET_NETDEV_DEV(dev, adapter->dev);
+
+	/* Register network device */
+	if (register_netdev(dev)) {
+		dev_err(adapter->dev, "cannot register virtual network device\n");
+		goto error;
+	}
+
+	dev_dbg(adapter->dev, "info: %s: Marvell 802.11 Adapter\n", dev->name);
+#ifdef CONFIG_DEBUG_FS
+	mwifiex_dev_debugfs_init(priv);
+#endif
+	return priv;
+error:
+	if (dev)
+		free_netdev(dev);
+	return NULL;
+}
+
+/*
+ * This function removes a logical interface.
+ *
+ * It deregisters, resets and frees the interface by performing
+ * the following operations -
+ *      - Disconnect the device if connected, send wireless event to
+ *        notify applications.
+ *      - Remove the debug FS structure if configured
+ *      - Unregister the device from kernel
+ *      - Free the net device structure
+ *      - Cancel all works and destroy work queue
+ *      - Unregister and free the wireless device from CFG80211 subsystem
+ */
+static void
+mwifiex_remove_interface(struct mwifiex_adapter *adapter, u8 bss_index)
+{
+	struct net_device *dev;
+	struct mwifiex_private *priv = adapter->priv[bss_index];
+
+	if (!priv)
+		return;
+	dev = priv->netdev;
+
+	if (priv->media_connected)
+		priv->media_connected = false;
+
+#ifdef CONFIG_DEBUG_FS
+	mwifiex_dev_debugfs_remove(priv);
+#endif
+	/* Last reference is our one */
+	dev_dbg(adapter->dev, "info: %s: refcnt = %d\n",
+				dev->name, netdev_refcnt_read(dev));
+
+	if (dev->reg_state == NETREG_REGISTERED)
+		unregister_netdev(dev);
+
+	/* Clear the priv in adapter */
+	priv->netdev = NULL;
+	if (dev)
+		free_netdev(dev);
+
+	cancel_work_sync(&priv->cfg_workqueue);
+	flush_workqueue(priv->workqueue);
+	destroy_workqueue(priv->workqueue);
+	wiphy_unregister(priv->wdev->wiphy);
+	wiphy_free(priv->wdev->wiphy);
+	kfree(priv->wdev);
+}
+
+/*
+ * This function check if command is pending.
+ */
+int is_command_pending(struct mwifiex_adapter *adapter)
+{
+	unsigned long flags;
+	int is_cmd_pend_q_empty;
+
+	spin_lock_irqsave(&adapter->cmd_pending_q_lock, flags);
+	is_cmd_pend_q_empty = list_empty(&adapter->cmd_pending_q);
+	spin_unlock_irqrestore(&adapter->cmd_pending_q_lock, flags);
+
+	return !is_cmd_pend_q_empty;
+}
+
+/*
+ * This function returns the correct private structure pointer based
+ * upon the BSS number.
+ */
+struct mwifiex_private *
+mwifiex_bss_index_to_priv(struct mwifiex_adapter *adapter, u8 bss_index)
+{
+	if (!adapter || (bss_index >= adapter->priv_num))
+		return NULL;
+	return adapter->priv[bss_index];
+}
+
+/*
+ * This is the main work queue function.
+ *
+ * It handles the main process, which in turn handles the complete
+ * driver operations.
+ */
+static void mwifiex_main_work_queue(struct work_struct *work)
+{
+	struct mwifiex_adapter *adapter =
+		container_of(work, struct mwifiex_adapter, main_work);
+
+	if (adapter->surprise_removed)
+		return;
+	mwifiex_main_process(adapter);
+}
+
+/*
+ * This function cancels all works in the queue and destroys
+ * the main workqueue.
+ */
+static void
+mwifiex_terminate_workqueue(struct mwifiex_adapter *adapter)
+{
+	flush_workqueue(adapter->workqueue);
+	destroy_workqueue(adapter->workqueue);
+	adapter->workqueue = NULL;
+}
+
+/*
+ * This function adds the card.
+ *
+ * This function follows the following major steps to set up the device -
+ *      - Initialize software. This includes probing the card, registering
+ *        the interface operations table, and allocating/initializing the
+ *        adapter structure
+ *      - Set up the netlink socket
+ *      - Create and start the main work queue
+ *      - Register the device
+ *      - Initialize firmware and hardware
+ *      - Add logical interfaces
+ */
+int
+mwifiex_add_card(void *card, struct semaphore *sem,
+		 struct mwifiex_if_ops *if_ops)
+{
+	int i;
+	struct mwifiex_adapter *adapter;
+
+	if (down_interruptible(sem))
+		goto exit_sem_err;
+
+	if (mwifiex_init_sw(card, if_ops)) {
+		pr_err("%s: software init failed\n", __func__);
+		goto err_init_sw;
+	}
+
+	adapter = g_adapter;
+
+	adapter->hw_status = MWIFIEX_HW_STATUS_INITIALIZING;
+	adapter->surprise_removed = false;
+	init_waitqueue_head(&adapter->init_wait_q);
+	adapter->is_suspended = false;
+	adapter->hs_activated = false;
+	init_waitqueue_head(&adapter->hs_activate_wait_q);
+	adapter->cmd_wait_q_required = false;
+	init_waitqueue_head(&adapter->cmd_wait_q.wait);
+	adapter->cmd_wait_q.condition = false;
+	adapter->cmd_wait_q.status = 0;
+
+	adapter->workqueue = create_workqueue("MWIFIEX_WORK_QUEUE");
+	if (!adapter->workqueue)
+		goto err_kmalloc;
+
+	INIT_WORK(&adapter->main_work, mwifiex_main_work_queue);
+
+	/* Register the device. Fill up the private data structure with relevant
+	   information from the card and request for the required IRQ. */
+	if (adapter->if_ops.register_dev(adapter)) {
+		pr_err("%s: failed to register mwifiex device\n", __func__);
+		goto err_registerdev;
+	}
+
+	if (mwifiex_init_hw_fw(adapter)) {
+		pr_err("%s: firmware init failed\n", __func__);
+		goto err_init_fw;
+	}
+
+	/* Add interfaces */
+	for (i = 0; i < adapter->drv_mode->intf_num; i++) {
+		if (!mwifiex_add_interface(adapter, i,
+				adapter->drv_mode->bss_attr[i].bss_type)) {
+			goto err_add_intf;
+		}
+	}
+
+	up(sem);
+
+	return 0;
+
+err_add_intf:
+	for (i = 0; i < adapter->priv_num; i++)
+		mwifiex_remove_interface(adapter, i);
+err_init_fw:
+	pr_debug("info: %s: unregister device\n", __func__);
+	adapter->if_ops.unregister_dev(adapter);
+err_registerdev:
+	adapter->surprise_removed = true;
+	mwifiex_terminate_workqueue(adapter);
+err_kmalloc:
+	if ((adapter->hw_status == MWIFIEX_HW_STATUS_FW_READY) ||
+	    (adapter->hw_status == MWIFIEX_HW_STATUS_READY)) {
+		pr_debug("info: %s: shutdown mwifiex\n", __func__);
+		adapter->init_wait_q_woken = false;
+
+		if (mwifiex_shutdown_drv(adapter) == -EINPROGRESS)
+			wait_event_interruptible(adapter->init_wait_q,
+						 adapter->init_wait_q_woken);
+	}
+
+	mwifiex_free_adapter(adapter);
+
+err_init_sw:
+	up(sem);
+
+exit_sem_err:
+	return -1;
+}
+EXPORT_SYMBOL_GPL(mwifiex_add_card);
+
+/*
+ * This function removes the card.
+ *
+ * This function follows the following major steps to remove the device -
+ *      - Stop data traffic
+ *      - Shutdown firmware
+ *      - Remove the logical interfaces
+ *      - Terminate the work queue
+ *      - Unregister the device
+ *      - Free the adapter structure
+ */
+int mwifiex_remove_card(struct mwifiex_adapter *adapter, struct semaphore *sem)
+{
+	struct mwifiex_private *priv = NULL;
+	int i;
+
+	if (down_interruptible(sem))
+		goto exit_sem_err;
+
+	if (!adapter)
+		goto exit_remove;
+
+	adapter->surprise_removed = true;
+
+	/* Stop data */
+	for (i = 0; i < adapter->priv_num; i++) {
+		priv = adapter->priv[i];
+		if (priv) {
+			if (!netif_queue_stopped(priv->netdev))
+				netif_stop_queue(priv->netdev);
+			if (netif_carrier_ok(priv->netdev))
+				netif_carrier_off(priv->netdev);
+		}
+	}
+
+	dev_dbg(adapter->dev, "cmd: calling mwifiex_shutdown_drv...\n");
+	adapter->init_wait_q_woken = false;
+
+	if (mwifiex_shutdown_drv(adapter) == -EINPROGRESS)
+		wait_event_interruptible(adapter->init_wait_q,
+					 adapter->init_wait_q_woken);
+	dev_dbg(adapter->dev, "cmd: mwifiex_shutdown_drv done\n");
+	if (atomic_read(&adapter->rx_pending) ||
+	    atomic_read(&adapter->tx_pending) ||
+	    atomic_read(&adapter->cmd_pending)) {
+		dev_err(adapter->dev, "rx_pending=%d, tx_pending=%d, "
+		       "cmd_pending=%d\n",
+		       atomic_read(&adapter->rx_pending),
+		       atomic_read(&adapter->tx_pending),
+		       atomic_read(&adapter->cmd_pending));
+	}
+
+	/* Remove interface */
+	for (i = 0; i < adapter->priv_num; i++)
+		mwifiex_remove_interface(adapter, i);
+
+	mwifiex_terminate_workqueue(adapter);
+
+	/* Unregister device */
+	dev_dbg(adapter->dev, "info: unregister device\n");
+	adapter->if_ops.unregister_dev(adapter);
+	/* Free adapter structure */
+	dev_dbg(adapter->dev, "info: free adapter\n");
+	mwifiex_free_adapter(adapter);
+
+exit_remove:
+	up(sem);
+exit_sem_err:
+	return 0;
+}
+EXPORT_SYMBOL_GPL(mwifiex_remove_card);
+
+/*
+ * This function initializes the module.
+ *
+ * The debug FS is also initialized if configured.
+ */
+static int
+mwifiex_init_module(void)
+{
+#ifdef CONFIG_DEBUG_FS
+	mwifiex_debugfs_init();
+#endif
+	return 0;
+}
+
+/*
+ * This function cleans up the module.
+ *
+ * The debug FS is removed if available.
+ */
+static void
+mwifiex_cleanup_module(void)
+{
+#ifdef CONFIG_DEBUG_FS
+	mwifiex_debugfs_remove();
+#endif
+}
+
+module_init(mwifiex_init_module);
+module_exit(mwifiex_cleanup_module);
+
+MODULE_AUTHOR("Marvell International Ltd.");
+MODULE_DESCRIPTION("Marvell WiFi-Ex Driver version " VERSION);
+MODULE_VERSION(VERSION);
+MODULE_LICENSE("GPL v2");
diff -druN linux-2.6.39-libre/drivers/net/wireless/mwifiex/main.h linux-3.0-rc7-libre/drivers/net/wireless/mwifiex/main.h
--- linux-2.6.39-libre/drivers/net/wireless/mwifiex/main.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/net/wireless/mwifiex/main.h	2011-07-21 06:57:20.000000000 -0400
@@ -0,0 +1,1009 @@
+/*
+ * Marvell Wireless LAN device driver: major data structures and prototypes
+ *
+ * Copyright (C) 2011, Marvell International Ltd.
+ *
+ * This software file (the "File") is distributed by Marvell International
+ * Ltd. under the terms of the GNU General Public License Version 2, June 1991
+ * (the "License").  You may use, redistribute and/or modify this File in
+ * accordance with the terms and conditions of the License, a copy of which
+ * is available by writing to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
+ * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
+ *
+ * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
+ * ARE EXPRESSLY DISCLAIMED.  The License provides additional details about
+ * this warranty disclaimer.
+ */
+
+#ifndef _MWIFIEX_MAIN_H_
+#define _MWIFIEX_MAIN_H_
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/semaphore.h>
+#include <linux/ip.h>
+#include <linux/skbuff.h>
+#include <linux/if_arp.h>
+#include <linux/etherdevice.h>
+#include <net/sock.h>
+#include <net/lib80211.h>
+#include <linux/firmware.h>
+#include <linux/ctype.h>
+
+#include "decl.h"
+#include "ioctl.h"
+#include "util.h"
+#include "fw.h"
+
+extern const char driver_version[];
+extern struct mwifiex_adapter *g_adapter;
+
+enum {
+	MWIFIEX_ASYNC_CMD,
+	MWIFIEX_SYNC_CMD
+};
+
+#define DRV_MODE_STA       0x1
+
+#define SD8787_W0   0x30
+#define SD8787_W1   0x31
+#define SD8787_A0   0x40
+#define SD8787_A1   0x41
+
+#define DEFAULT_FW_NAME "/*(DEBLOBBED)*/"
+#define SD8787_W1_FW_NAME "/*(DEBLOBBED)*/"
+#define SD8787_AX_FW_NAME "/*(DEBLOBBED)*/"
+
+struct mwifiex_drv_mode {
+	u16 drv_mode;
+	u16 intf_num;
+	struct mwifiex_bss_attr *bss_attr;
+};
+
+
+#define MWIFIEX_DEFAULT_WATCHDOG_TIMEOUT	(5 * HZ)
+
+#define MWIFIEX_TIMER_10S			10000
+#define MWIFIEX_TIMER_1S			1000
+
+#define MAX_TX_PENDING      100
+#define LOW_TX_PENDING      80
+
+#define MWIFIEX_UPLD_SIZE               (2312)
+
+#define MAX_EVENT_SIZE                  1024
+
+#define ARP_FILTER_MAX_BUF_SIZE         68
+
+#define MWIFIEX_KEY_BUFFER_SIZE			16
+#define MWIFIEX_DEFAULT_LISTEN_INTERVAL 10
+#define MWIFIEX_MAX_REGION_CODE         7
+
+#define DEFAULT_BCN_AVG_FACTOR          8
+#define DEFAULT_DATA_AVG_FACTOR         8
+
+#define FIRST_VALID_CHANNEL				0xff
+#define DEFAULT_AD_HOC_CHANNEL			6
+#define DEFAULT_AD_HOC_CHANNEL_A		36
+
+#define DEFAULT_BCN_MISS_TIMEOUT		5
+
+#define MAX_SCAN_BEACON_BUFFER			8000
+
+#define SCAN_BEACON_ENTRY_PAD			6
+
+#define MWIFIEX_PASSIVE_SCAN_CHAN_TIME	200
+#define MWIFIEX_ACTIVE_SCAN_CHAN_TIME	200
+#define MWIFIEX_SPECIFIC_SCAN_CHAN_TIME	110
+
+#define SCAN_RSSI(RSSI)					(0x100 - ((u8)(RSSI)))
+
+#define MWIFIEX_MAX_TOTAL_SCAN_TIME	(MWIFIEX_TIMER_10S - MWIFIEX_TIMER_1S)
+
+#define RSN_GTK_OUI_OFFSET				2
+
+#define MWIFIEX_OUI_NOT_PRESENT			0
+#define MWIFIEX_OUI_PRESENT				1
+
+#define IS_CARD_RX_RCVD(adapter) (adapter->cmd_resp_received || \
+					adapter->event_received || \
+					adapter->data_received)
+
+#define MWIFIEX_TYPE_CMD				1
+#define MWIFIEX_TYPE_DATA				0
+#define MWIFIEX_TYPE_EVENT				3
+
+#define DBG_CMD_NUM						5
+
+#define MAX_BITMAP_RATES_SIZE			10
+
+#define MAX_CHANNEL_BAND_BG     14
+
+#define MAX_FREQUENCY_BAND_BG   2484
+
+struct mwifiex_dbg {
+	u32 num_cmd_host_to_card_failure;
+	u32 num_cmd_sleep_cfm_host_to_card_failure;
+	u32 num_tx_host_to_card_failure;
+	u32 num_event_deauth;
+	u32 num_event_disassoc;
+	u32 num_event_link_lost;
+	u32 num_cmd_deauth;
+	u32 num_cmd_assoc_success;
+	u32 num_cmd_assoc_failure;
+	u32 num_tx_timeout;
+	u32 num_cmd_timeout;
+	u16 timeout_cmd_id;
+	u16 timeout_cmd_act;
+	u16 last_cmd_id[DBG_CMD_NUM];
+	u16 last_cmd_act[DBG_CMD_NUM];
+	u16 last_cmd_index;
+	u16 last_cmd_resp_id[DBG_CMD_NUM];
+	u16 last_cmd_resp_index;
+	u16 last_event[DBG_CMD_NUM];
+	u16 last_event_index;
+};
+
+enum MWIFIEX_HARDWARE_STATUS {
+	MWIFIEX_HW_STATUS_READY,
+	MWIFIEX_HW_STATUS_INITIALIZING,
+	MWIFIEX_HW_STATUS_FW_READY,
+	MWIFIEX_HW_STATUS_INIT_DONE,
+	MWIFIEX_HW_STATUS_RESET,
+	MWIFIEX_HW_STATUS_CLOSING,
+	MWIFIEX_HW_STATUS_NOT_READY
+};
+
+enum MWIFIEX_802_11_POWER_MODE {
+	MWIFIEX_802_11_POWER_MODE_CAM,
+	MWIFIEX_802_11_POWER_MODE_PSP
+};
+
+struct mwifiex_tx_param {
+	u32 next_pkt_len;
+};
+
+enum MWIFIEX_PS_STATE {
+	PS_STATE_AWAKE,
+	PS_STATE_PRE_SLEEP,
+	PS_STATE_SLEEP_CFM,
+	PS_STATE_SLEEP
+};
+
+struct mwifiex_add_ba_param {
+	u32 tx_win_size;
+	u32 rx_win_size;
+	u32 timeout;
+};
+
+struct mwifiex_tx_aggr {
+	u8 ampdu_user;
+	u8 ampdu_ap;
+	u8 amsdu;
+};
+
+struct mwifiex_ra_list_tbl {
+	struct list_head list;
+	struct sk_buff_head skb_head;
+	u8 ra[ETH_ALEN];
+	u32 total_pkts_size;
+	u32 is_11n_enabled;
+};
+
+struct mwifiex_tid_tbl {
+	struct list_head ra_list;
+	/* spin lock for tid table */
+	spinlock_t tid_tbl_lock;
+	struct mwifiex_ra_list_tbl *ra_list_curr;
+};
+
+#define WMM_HIGHEST_PRIORITY		7
+#define HIGH_PRIO_TID				7
+#define LOW_PRIO_TID				0
+#define NO_PKT_PRIO_TID				(-1)
+
+struct mwifiex_wmm_desc {
+	struct mwifiex_tid_tbl tid_tbl_ptr[MAX_NUM_TID];
+	u32 packets_out[MAX_NUM_TID];
+	/* spin lock to protect ra_list */
+	spinlock_t ra_list_spinlock;
+	struct mwifiex_wmm_ac_status ac_status[IEEE80211_MAX_QUEUES];
+	enum mwifiex_wmm_ac_e ac_down_graded_vals[IEEE80211_MAX_QUEUES];
+	u32 drv_pkt_delay_max;
+	u8 queue_priority[IEEE80211_MAX_QUEUES];
+	u32 user_pri_pkt_tx_ctrl[WMM_HIGHEST_PRIORITY + 1];	/* UP: 0 to 7 */
+	/* Number of transmit packets queued */
+	atomic_t tx_pkts_queued;
+	/* Tracks highest priority with a packet queued */
+	atomic_t highest_queued_prio;
+};
+
+struct mwifiex_802_11_security {
+	u8 wpa_enabled;
+	u8 wpa2_enabled;
+	u8 wapi_enabled;
+	u8 wapi_key_on;
+	enum MWIFIEX_802_11_WEP_STATUS wep_status;
+	u32 authentication_mode;
+	u32 encryption_mode;
+};
+
+struct ieee_types_header {
+	u8 element_id;
+	u8 len;
+} __packed;
+
+struct ieee_obss_scan_param {
+	u16 obss_scan_passive_dwell;
+	u16 obss_scan_active_dwell;
+	u16 bss_chan_width_trigger_scan_int;
+	u16 obss_scan_passive_total;
+	u16 obss_scan_active_total;
+	u16 bss_width_chan_trans_delay;
+	u16 obss_scan_active_threshold;
+} __packed;
+
+struct ieee_types_obss_scan_param {
+	struct ieee_types_header ieee_hdr;
+	struct ieee_obss_scan_param obss_scan;
+} __packed;
+
+#define MWIFIEX_SUPPORTED_RATES                 14
+
+#define MWIFIEX_SUPPORTED_RATES_EXT             32
+
+#define IEEE_MAX_IE_SIZE			256
+
+struct ieee_types_vendor_specific {
+	struct ieee_types_vendor_header vend_hdr;
+	u8 data[IEEE_MAX_IE_SIZE - sizeof(struct ieee_types_vendor_header)];
+} __packed;
+
+struct ieee_types_generic {
+	struct ieee_types_header ieee_hdr;
+	u8 data[IEEE_MAX_IE_SIZE - sizeof(struct ieee_types_header)];
+} __packed;
+
+struct mwifiex_bssdescriptor {
+	u8 mac_address[ETH_ALEN];
+	struct mwifiex_802_11_ssid ssid;
+	u32 privacy;
+	s32 rssi;
+	u32 channel;
+	u32 freq;
+	u16 beacon_period;
+	u8 erp_flags;
+	u32 bss_mode;
+	u8 supported_rates[MWIFIEX_SUPPORTED_RATES];
+	u8 data_rates[MWIFIEX_SUPPORTED_RATES];
+	/* Network band.
+	 * BAND_B(0x01): 'b' band
+	 * BAND_G(0x02): 'g' band
+	 * BAND_A(0X04): 'a' band
+	 */
+	u16 bss_band;
+	u64 network_tsf;
+	u8 time_stamp[8];
+	union ieee_types_phy_param_set phy_param_set;
+	union ieee_types_ss_param_set ss_param_set;
+	u16 cap_info_bitmap;
+	struct ieee_types_wmm_parameter wmm_ie;
+	u8  disable_11n;
+	struct ieee80211_ht_cap *bcn_ht_cap;
+	u16 ht_cap_offset;
+	struct ieee80211_ht_info *bcn_ht_info;
+	u16 ht_info_offset;
+	u8 *bcn_bss_co_2040;
+	u16 bss_co_2040_offset;
+	u8 *bcn_ext_cap;
+	u16 ext_cap_offset;
+	struct ieee_types_obss_scan_param *bcn_obss_scan;
+	u16 overlap_bss_offset;
+	struct ieee_types_vendor_specific *bcn_wpa_ie;
+	u16 wpa_offset;
+	struct ieee_types_generic *bcn_rsn_ie;
+	u16 rsn_offset;
+	struct ieee_types_generic *bcn_wapi_ie;
+	u16 wapi_offset;
+	u8 *beacon_buf;
+	u32 beacon_buf_size;
+	u32 beacon_buf_size_max;
+
+};
+
+struct mwifiex_current_bss_params {
+	struct mwifiex_bssdescriptor bss_descriptor;
+	u8 wmm_enabled;
+	u8 wmm_uapsd_enabled;
+	u8 band;
+	u32 num_of_rates;
+	u8 data_rates[MWIFIEX_SUPPORTED_RATES];
+};
+
+struct mwifiex_sleep_params {
+	u16 sp_error;
+	u16 sp_offset;
+	u16 sp_stable_time;
+	u8 sp_cal_control;
+	u8 sp_ext_sleep_clk;
+	u16 sp_reserved;
+};
+
+struct mwifiex_sleep_period {
+	u16 period;
+	u16 reserved;
+};
+
+struct mwifiex_wep_key {
+	u32 length;
+	u32 key_index;
+	u32 key_length;
+	u8 key_material[MWIFIEX_KEY_BUFFER_SIZE];
+};
+
+#define MAX_REGION_CHANNEL_NUM  2
+
+struct mwifiex_chan_freq_power {
+	u16 channel;
+	u32 freq;
+	u16 max_tx_power;
+	u8 unsupported;
+};
+
+enum state_11d_t {
+	DISABLE_11D = 0,
+	ENABLE_11D = 1,
+};
+
+#define MWIFIEX_MAX_TRIPLET_802_11D		83
+
+struct mwifiex_802_11d_domain_reg {
+	u8 country_code[IEEE80211_COUNTRY_STRING_LEN];
+	u8 no_of_triplet;
+	struct ieee80211_country_ie_triplet
+		triplet[MWIFIEX_MAX_TRIPLET_802_11D];
+};
+
+struct mwifiex_vendor_spec_cfg_ie {
+	u16 mask;
+	u16 flag;
+	u8 ie[MWIFIEX_MAX_VSIE_LEN];
+};
+
+struct wps {
+	u8 session_enable;
+};
+
+struct mwifiex_adapter;
+struct mwifiex_private;
+
+struct mwifiex_private {
+	struct mwifiex_adapter *adapter;
+	u8 bss_index;
+	u8 bss_type;
+	u8 bss_role;
+	u8 bss_priority;
+	u8 bss_num;
+	u8 frame_type;
+	u8 curr_addr[ETH_ALEN];
+	u8 media_connected;
+	u32 num_tx_timeout;
+	struct net_device *netdev;
+	struct net_device_stats stats;
+	u16 curr_pkt_filter;
+	u32 bss_mode;
+	u32 pkt_tx_ctrl;
+	u16 tx_power_level;
+	u8 max_tx_power_level;
+	u8 min_tx_power_level;
+	u8 tx_rate;
+	u8 tx_htinfo;
+	u8 rxpd_htinfo;
+	u8 rxpd_rate;
+	u16 rate_bitmap;
+	u16 bitmap_rates[MAX_BITMAP_RATES_SIZE];
+	u32 data_rate;
+	u8 is_data_rate_auto;
+	u16 bcn_avg_factor;
+	u16 data_avg_factor;
+	s16 data_rssi_last;
+	s16 data_nf_last;
+	s16 data_rssi_avg;
+	s16 data_nf_avg;
+	s16 bcn_rssi_last;
+	s16 bcn_nf_last;
+	s16 bcn_rssi_avg;
+	s16 bcn_nf_avg;
+	struct mwifiex_bssdescriptor *attempted_bss_desc;
+	struct mwifiex_802_11_ssid prev_ssid;
+	u8 prev_bssid[ETH_ALEN];
+	struct mwifiex_current_bss_params curr_bss_params;
+	u16 beacon_period;
+	u16 listen_interval;
+	u16 atim_window;
+	u8 adhoc_channel;
+	u8 adhoc_is_link_sensed;
+	u8 adhoc_state;
+	struct mwifiex_802_11_security sec_info;
+	struct mwifiex_wep_key wep_key[NUM_WEP_KEYS];
+	u16 wep_key_curr_index;
+	u8 wpa_ie[256];
+	u8 wpa_ie_len;
+	u8 wpa_is_gtk_set;
+	struct host_cmd_ds_802_11_key_material aes_key;
+	u8 wapi_ie[256];
+	u8 wapi_ie_len;
+	u8 wmm_required;
+	u8 wmm_enabled;
+	u8 wmm_qosinfo;
+	struct mwifiex_wmm_desc wmm;
+	struct list_head tx_ba_stream_tbl_ptr;
+	/* spin lock for tx_ba_stream_tbl_ptr queue */
+	spinlock_t tx_ba_stream_tbl_lock;
+	struct mwifiex_tx_aggr aggr_prio_tbl[MAX_NUM_TID];
+	struct mwifiex_add_ba_param add_ba_param;
+	u16 rx_seq[MAX_NUM_TID];
+	struct list_head rx_reorder_tbl_ptr;
+	/* spin lock for rx_reorder_tbl_ptr queue */
+	spinlock_t rx_reorder_tbl_lock;
+	/* spin lock for Rx packets */
+	spinlock_t rx_pkt_lock;
+
+#define MWIFIEX_ASSOC_RSP_BUF_SIZE  500
+	u8 assoc_rsp_buf[MWIFIEX_ASSOC_RSP_BUF_SIZE];
+	u32 assoc_rsp_size;
+
+#define MWIFIEX_GENIE_BUF_SIZE      256
+	u8 gen_ie_buf[MWIFIEX_GENIE_BUF_SIZE];
+	u8 gen_ie_buf_len;
+
+	struct mwifiex_vendor_spec_cfg_ie vs_ie[MWIFIEX_MAX_VSIE_NUM];
+
+#define MWIFIEX_ASSOC_TLV_BUF_SIZE  256
+	u8 assoc_tlv_buf[MWIFIEX_ASSOC_TLV_BUF_SIZE];
+	u8 assoc_tlv_buf_len;
+
+	u8 *curr_bcn_buf;
+	u32 curr_bcn_size;
+	/* spin lock for beacon buffer */
+	spinlock_t curr_bcn_buf_lock;
+	struct wireless_dev *wdev;
+	struct mwifiex_chan_freq_power cfp;
+	char version_str[128];
+#ifdef CONFIG_DEBUG_FS
+	struct dentry *dfs_dev_dir;
+#endif
+	u8 nick_name[16];
+	struct iw_statistics w_stats;
+	u16 current_key_index;
+	struct semaphore async_sem;
+	u8 scan_pending_on_block;
+	u8 report_scan_result;
+	struct cfg80211_scan_request *scan_request;
+	int scan_result_status;
+	int assoc_request;
+	u16 assoc_result;
+	int ibss_join_request;
+	u16 ibss_join_result;
+	bool disconnect;
+	u8 cfg_bssid[6];
+	struct workqueue_struct *workqueue;
+	struct work_struct cfg_workqueue;
+	u8 country_code[IEEE80211_COUNTRY_STRING_LEN];
+	struct wps wps;
+	u8 scan_block;
+};
+
+enum mwifiex_ba_status {
+	BA_STREAM_NOT_SETUP = 0,
+	BA_STREAM_SETUP_INPROGRESS,
+	BA_STREAM_SETUP_COMPLETE
+};
+
+struct mwifiex_tx_ba_stream_tbl {
+	struct list_head list;
+	int tid;
+	u8 ra[ETH_ALEN];
+	enum mwifiex_ba_status ba_status;
+};
+
+struct mwifiex_rx_reorder_tbl;
+
+struct reorder_tmr_cnxt {
+	struct timer_list timer;
+	struct mwifiex_rx_reorder_tbl *ptr;
+	struct mwifiex_private *priv;
+};
+
+struct mwifiex_rx_reorder_tbl {
+	struct list_head list;
+	int tid;
+	u8 ta[ETH_ALEN];
+	int start_win;
+	int win_size;
+	void **rx_reorder_ptr;
+	struct reorder_tmr_cnxt timer_context;
+};
+
+struct mwifiex_bss_prio_node {
+	struct list_head list;
+	struct mwifiex_private *priv;
+};
+
+struct mwifiex_bss_prio_tbl {
+	struct list_head bss_prio_head;
+	/* spin lock for bss priority  */
+	spinlock_t bss_prio_lock;
+	struct mwifiex_bss_prio_node *bss_prio_cur;
+};
+
+struct cmd_ctrl_node {
+	struct list_head list;
+	struct mwifiex_private *priv;
+	u32 cmd_oid;
+	u32 cmd_flag;
+	struct sk_buff *cmd_skb;
+	struct sk_buff *resp_skb;
+	void *data_buf;
+	u32 wait_q_enabled;
+	struct sk_buff *skb;
+};
+
+struct mwifiex_if_ops {
+	int (*init_if) (struct mwifiex_adapter *);
+	void (*cleanup_if) (struct mwifiex_adapter *);
+	int (*check_fw_status) (struct mwifiex_adapter *, u32, int *);
+	int (*prog_fw) (struct mwifiex_adapter *, struct mwifiex_fw_image *);
+	int (*register_dev) (struct mwifiex_adapter *);
+	void (*unregister_dev) (struct mwifiex_adapter *);
+	int (*enable_int) (struct mwifiex_adapter *);
+	int (*process_int_status) (struct mwifiex_adapter *);
+	int (*host_to_card) (struct mwifiex_adapter *, u8,
+			     u8 *payload, u32 pkt_len,
+			     struct mwifiex_tx_param *);
+	int (*wakeup) (struct mwifiex_adapter *);
+	int (*wakeup_complete) (struct mwifiex_adapter *);
+
+	void (*update_mp_end_port) (struct mwifiex_adapter *, u16);
+	void (*cleanup_mpa_buf) (struct mwifiex_adapter *);
+};
+
+struct mwifiex_adapter {
+	struct mwifiex_private *priv[MWIFIEX_MAX_BSS_NUM];
+	u8 priv_num;
+	struct mwifiex_drv_mode *drv_mode;
+	const struct firmware *firmware;
+	struct device *dev;
+	bool surprise_removed;
+	u32 fw_release_number;
+	u32 revision_id;
+	u16 init_wait_q_woken;
+	wait_queue_head_t init_wait_q;
+	void *card;
+	struct mwifiex_if_ops if_ops;
+	atomic_t rx_pending;
+	atomic_t tx_pending;
+	atomic_t cmd_pending;
+	struct workqueue_struct *workqueue;
+	struct work_struct main_work;
+	struct mwifiex_bss_prio_tbl bss_prio_tbl[MWIFIEX_MAX_BSS_NUM];
+	/* spin lock for init/shutdown */
+	spinlock_t mwifiex_lock;
+	/* spin lock for main process */
+	spinlock_t main_proc_lock;
+	u32 mwifiex_processing;
+	u16 max_tx_buf_size;
+	u16 tx_buf_size;
+	u16 curr_tx_buf_size;
+	u32 ioport;
+	enum MWIFIEX_HARDWARE_STATUS hw_status;
+	u16 number_of_antenna;
+	u32 fw_cap_info;
+	/* spin lock for interrupt handling */
+	spinlock_t int_lock;
+	u8 int_status;
+	u32 event_cause;
+	struct sk_buff *event_skb;
+	u8 upld_buf[MWIFIEX_UPLD_SIZE];
+	u8 data_sent;
+	u8 cmd_sent;
+	u8 cmd_resp_received;
+	u8 event_received;
+	u8 data_received;
+	u16 seq_num;
+	struct cmd_ctrl_node *cmd_pool;
+	struct cmd_ctrl_node *curr_cmd;
+	/* spin lock for command */
+	spinlock_t mwifiex_cmd_lock;
+	u32 num_cmd_timeout;
+	u16 last_init_cmd;
+	struct timer_list cmd_timer;
+	struct list_head cmd_free_q;
+	/* spin lock for cmd_free_q */
+	spinlock_t cmd_free_q_lock;
+	struct list_head cmd_pending_q;
+	/* spin lock for cmd_pending_q */
+	spinlock_t cmd_pending_q_lock;
+	struct list_head scan_pending_q;
+	/* spin lock for scan_pending_q */
+	spinlock_t scan_pending_q_lock;
+	u32 scan_processing;
+	u16 region_code;
+	struct mwifiex_802_11d_domain_reg domain_reg;
+	struct mwifiex_bssdescriptor *scan_table;
+	u32 num_in_scan_table;
+	u16 scan_probes;
+	u32 scan_mode;
+	u16 specific_scan_time;
+	u16 active_scan_time;
+	u16 passive_scan_time;
+	u8 bcn_buf[MAX_SCAN_BEACON_BUFFER];
+	u8 *bcn_buf_end;
+	u8 fw_bands;
+	u8 adhoc_start_band;
+	u8 config_bands;
+	struct mwifiex_chan_scan_param_set *scan_channels;
+	u8 tx_lock_flag;
+	struct mwifiex_sleep_params sleep_params;
+	struct mwifiex_sleep_period sleep_period;
+	u16 ps_mode;
+	u32 ps_state;
+	u8 need_to_wakeup;
+	u16 multiple_dtim;
+	u16 local_listen_interval;
+	u16 null_pkt_interval;
+	struct sk_buff *sleep_cfm;
+	u16 bcn_miss_time_out;
+	u16 adhoc_awake_period;
+	u8 is_deep_sleep;
+	u8 delay_null_pkt;
+	u16 delay_to_ps;
+	u16 enhanced_ps_mode;
+	u8 pm_wakeup_card_req;
+	u16 gen_null_pkt;
+	u16 pps_uapsd_mode;
+	u32 pm_wakeup_fw_try;
+	u8 is_hs_configured;
+	struct mwifiex_hs_config_param hs_cfg;
+	u8 hs_activated;
+	u16 hs_activate_wait_q_woken;
+	wait_queue_head_t hs_activate_wait_q;
+	bool is_suspended;
+	u8 event_body[MAX_EVENT_SIZE];
+	u32 hw_dot_11n_dev_cap;
+	u8 hw_dev_mcs_support;
+	u8 adhoc_11n_enabled;
+	u8 chan_offset;
+	struct mwifiex_dbg dbg;
+	u8 arp_filter[ARP_FILTER_MAX_BUF_SIZE];
+	u32 arp_filter_size;
+	u16 cmd_wait_q_required;
+	struct mwifiex_wait_queue cmd_wait_q;
+};
+
+int mwifiex_init_lock_list(struct mwifiex_adapter *adapter);
+void mwifiex_free_lock_list(struct mwifiex_adapter *adapter);
+
+int mwifiex_init_fw(struct mwifiex_adapter *adapter);
+
+int mwifiex_init_fw_complete(struct mwifiex_adapter *adapter);
+
+int mwifiex_shutdown_drv(struct mwifiex_adapter *adapter);
+
+int mwifiex_shutdown_fw_complete(struct mwifiex_adapter *adapter);
+
+int mwifiex_dnld_fw(struct mwifiex_adapter *, struct mwifiex_fw_image *);
+
+int mwifiex_recv_packet(struct mwifiex_adapter *, struct sk_buff *skb);
+
+int mwifiex_process_event(struct mwifiex_adapter *adapter);
+
+int mwifiex_complete_cmd(struct mwifiex_adapter *adapter);
+
+int mwifiex_send_cmd_async(struct mwifiex_private *priv, uint16_t cmd_no,
+			   u16 cmd_action, u32 cmd_oid, void *data_buf);
+
+int mwifiex_send_cmd_sync(struct mwifiex_private *priv, uint16_t cmd_no,
+			  u16 cmd_action, u32 cmd_oid, void *data_buf);
+
+void mwifiex_cmd_timeout_func(unsigned long function_context);
+
+int mwifiex_get_debug_info(struct mwifiex_private *,
+			   struct mwifiex_debug_info *);
+
+int mwifiex_alloc_cmd_buffer(struct mwifiex_adapter *adapter);
+int mwifiex_free_cmd_buffer(struct mwifiex_adapter *adapter);
+void mwifiex_cancel_all_pending_cmd(struct mwifiex_adapter *adapter);
+void mwifiex_cancel_pending_ioctl(struct mwifiex_adapter *adapter);
+
+void mwifiex_insert_cmd_to_free_q(struct mwifiex_adapter *adapter,
+				  struct cmd_ctrl_node *cmd_node);
+
+void mwifiex_insert_cmd_to_pending_q(struct mwifiex_adapter *adapter,
+				     struct cmd_ctrl_node *cmd_node,
+				     u32 addtail);
+
+int mwifiex_exec_next_cmd(struct mwifiex_adapter *adapter);
+int mwifiex_process_cmdresp(struct mwifiex_adapter *adapter);
+int mwifiex_handle_rx_packet(struct mwifiex_adapter *adapter,
+			     struct sk_buff *skb);
+int mwifiex_process_tx(struct mwifiex_private *priv, struct sk_buff *skb,
+		       struct mwifiex_tx_param *tx_param);
+int mwifiex_send_null_packet(struct mwifiex_private *priv, u8 flags);
+int mwifiex_write_data_complete(struct mwifiex_adapter *adapter,
+				struct sk_buff *skb, int status);
+int mwifiex_recv_packet_complete(struct mwifiex_adapter *,
+				 struct sk_buff *skb, int status);
+void mwifiex_clean_txrx(struct mwifiex_private *priv);
+u8 mwifiex_check_last_packet_indication(struct mwifiex_private *priv);
+void mwifiex_check_ps_cond(struct mwifiex_adapter *adapter);
+void mwifiex_process_sleep_confirm_resp(struct mwifiex_adapter *, u8 *,
+					u32);
+int mwifiex_cmd_enh_power_mode(struct mwifiex_private *priv,
+			       struct host_cmd_ds_command *cmd,
+			       u16 cmd_action, uint16_t ps_bitmap,
+			       void *data_buf);
+int mwifiex_ret_enh_power_mode(struct mwifiex_private *priv,
+			       struct host_cmd_ds_command *resp,
+			       void *data_buf);
+void mwifiex_process_hs_config(struct mwifiex_adapter *adapter);
+void mwifiex_hs_activated_event(struct mwifiex_private *priv,
+					u8 activated);
+int mwifiex_ret_802_11_hs_cfg(struct mwifiex_private *priv,
+			      struct host_cmd_ds_command *resp);
+int mwifiex_process_rx_packet(struct mwifiex_adapter *adapter,
+			      struct sk_buff *skb);
+int mwifiex_sta_prepare_cmd(struct mwifiex_private *, uint16_t cmd_no,
+			    u16 cmd_action, u32 cmd_oid,
+			    void *data_buf, void *cmd_buf);
+int mwifiex_process_sta_cmdresp(struct mwifiex_private *, u16 cmdresp_no,
+				void *cmd_buf);
+int mwifiex_process_sta_rx_packet(struct mwifiex_adapter *,
+				  struct sk_buff *skb);
+int mwifiex_process_sta_event(struct mwifiex_private *);
+void *mwifiex_process_sta_txpd(struct mwifiex_private *, struct sk_buff *skb);
+int mwifiex_sta_init_cmd(struct mwifiex_private *, u8 first_sta);
+int mwifiex_scan_networks(struct mwifiex_private *priv,
+			  const struct mwifiex_user_scan_cfg *user_scan_in);
+int mwifiex_cmd_802_11_scan(struct host_cmd_ds_command *cmd,
+			    void *data_buf);
+void mwifiex_queue_scan_cmd(struct mwifiex_private *priv,
+			    struct cmd_ctrl_node *cmd_node);
+int mwifiex_ret_802_11_scan(struct mwifiex_private *priv,
+			    struct host_cmd_ds_command *resp);
+s32 mwifiex_find_ssid_in_list(struct mwifiex_private *priv,
+				struct mwifiex_802_11_ssid *ssid, u8 *bssid,
+				u32 mode);
+s32 mwifiex_find_bssid_in_list(struct mwifiex_private *priv, u8 *bssid,
+				 u32 mode);
+int mwifiex_find_best_network(struct mwifiex_private *priv,
+			      struct mwifiex_ssid_bssid *req_ssid_bssid);
+s32 mwifiex_ssid_cmp(struct mwifiex_802_11_ssid *ssid1,
+		       struct mwifiex_802_11_ssid *ssid2);
+int mwifiex_associate(struct mwifiex_private *priv,
+		      struct mwifiex_bssdescriptor *bss_desc);
+int mwifiex_cmd_802_11_associate(struct mwifiex_private *priv,
+				 struct host_cmd_ds_command
+				 *cmd, void *data_buf);
+int mwifiex_ret_802_11_associate(struct mwifiex_private *priv,
+				 struct host_cmd_ds_command *resp);
+void mwifiex_reset_connect_state(struct mwifiex_private *priv);
+void mwifiex_2040_coex_event(struct mwifiex_private *priv);
+u8 mwifiex_band_to_radio_type(u8 band);
+int mwifiex_deauthenticate(struct mwifiex_private *priv, u8 *mac);
+int mwifiex_adhoc_start(struct mwifiex_private *priv,
+			struct mwifiex_802_11_ssid *adhoc_ssid);
+int mwifiex_adhoc_join(struct mwifiex_private *priv,
+		       struct mwifiex_bssdescriptor *bss_desc);
+int mwifiex_cmd_802_11_ad_hoc_start(struct mwifiex_private *priv,
+				    struct host_cmd_ds_command *cmd,
+				    void *data_buf);
+int mwifiex_cmd_802_11_ad_hoc_join(struct mwifiex_private *priv,
+				   struct host_cmd_ds_command *cmd,
+				   void *data_buf);
+int mwifiex_ret_802_11_ad_hoc(struct mwifiex_private *priv,
+			      struct host_cmd_ds_command *resp);
+int mwifiex_cmd_802_11_bg_scan_query(struct host_cmd_ds_command *cmd);
+struct mwifiex_chan_freq_power *
+			mwifiex_get_cfp_by_band_and_channel_from_cfg80211(
+						struct mwifiex_private *priv,
+						u8 band, u16 channel);
+struct mwifiex_chan_freq_power *mwifiex_get_cfp_by_band_and_freq_from_cfg80211(
+						struct mwifiex_private *priv,
+						u8 band, u32 freq);
+u32 mwifiex_index_to_data_rate(u8 index, u8 ht_info);
+u32 mwifiex_find_freq_from_band_chan(u8, u8);
+int mwifiex_cmd_append_vsie_tlv(struct mwifiex_private *priv, u16 vsie_mask,
+				u8 **buffer);
+u32 mwifiex_get_active_data_rates(struct mwifiex_private *priv,
+				    u8 *rates);
+u32 mwifiex_get_supported_rates(struct mwifiex_private *priv, u8 *rates);
+u8 mwifiex_data_rate_to_index(u32 rate);
+u8 mwifiex_is_rate_auto(struct mwifiex_private *priv);
+int mwifiex_get_rate_index(u16 *rateBitmap, int size);
+extern u16 region_code_index[MWIFIEX_MAX_REGION_CODE];
+void mwifiex_save_curr_bcn(struct mwifiex_private *priv);
+void mwifiex_free_curr_bcn(struct mwifiex_private *priv);
+int mwifiex_cmd_get_hw_spec(struct mwifiex_private *priv,
+			    struct host_cmd_ds_command *cmd);
+int mwifiex_ret_get_hw_spec(struct mwifiex_private *priv,
+			    struct host_cmd_ds_command *resp);
+int is_command_pending(struct mwifiex_adapter *adapter);
+
+/*
+ * This function checks if the queuing is RA based or not.
+ */
+static inline u8
+mwifiex_queuing_ra_based(struct mwifiex_private *priv)
+{
+	/*
+	 * Currently we assume if we are in Infra, then DA=RA. This might not be
+	 * true in the future
+	 */
+	if ((priv->bss_mode == NL80211_IFTYPE_STATION) &&
+	    (GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_STA))
+		return false;
+
+	return true;
+}
+
+/*
+ * This function copies rates.
+ */
+static inline u32
+mwifiex_copy_rates(u8 *dest, u32 pos, u8 *src, int len)
+{
+	int i;
+
+	for (i = 0; i < len && src[i]; i++, pos++) {
+		if (pos >= MWIFIEX_SUPPORTED_RATES)
+			break;
+		dest[pos] = src[i];
+	}
+
+	return pos;
+}
+
+/*
+ * This function returns the correct private structure pointer based
+ * upon the BSS type and BSS number.
+ */
+static inline struct mwifiex_private *
+mwifiex_get_priv_by_id(struct mwifiex_adapter *adapter,
+		       u8 bss_num, u8 bss_type)
+{
+	int i;
+
+	for (i = 0; i < adapter->priv_num; i++) {
+		if (adapter->priv[i]) {
+			if ((adapter->priv[i]->bss_num == bss_num)
+			    && (adapter->priv[i]->bss_type == bss_type))
+				break;
+		}
+	}
+	return ((i < adapter->priv_num) ? adapter->priv[i] : NULL);
+}
+
+/*
+ * This function returns the first available private structure pointer
+ * based upon the BSS role.
+ */
+static inline struct mwifiex_private *
+mwifiex_get_priv(struct mwifiex_adapter *adapter,
+		 enum mwifiex_bss_role bss_role)
+{
+	int i;
+
+	for (i = 0; i < adapter->priv_num; i++) {
+		if (adapter->priv[i]) {
+			if (bss_role == MWIFIEX_BSS_ROLE_ANY ||
+			    GET_BSS_ROLE(adapter->priv[i]) == bss_role)
+				break;
+		}
+	}
+
+	return ((i < adapter->priv_num) ? adapter->priv[i] : NULL);
+}
+
+/*
+ * This function returns the driver private structure of a network device.
+ */
+static inline struct mwifiex_private *
+mwifiex_netdev_get_priv(struct net_device *dev)
+{
+	return (struct mwifiex_private *) (*(unsigned long *) netdev_priv(dev));
+}
+
+struct mwifiex_private *mwifiex_bss_index_to_priv(struct mwifiex_adapter
+						*adapter, u8 bss_index);
+int mwifiex_init_shutdown_fw(struct mwifiex_private *priv,
+			     u32 func_init_shutdown);
+int mwifiex_add_card(void *, struct semaphore *, struct mwifiex_if_ops *);
+int mwifiex_remove_card(struct mwifiex_adapter *, struct semaphore *);
+
+void mwifiex_get_version(struct mwifiex_adapter *adapter, char *version,
+			 int maxlen);
+int mwifiex_request_set_multicast_list(struct mwifiex_private *priv,
+			struct mwifiex_multicast_list *mcast_list);
+int mwifiex_copy_mcast_addr(struct mwifiex_multicast_list *mlist,
+			    struct net_device *dev);
+int mwifiex_wait_queue_complete(struct mwifiex_adapter *adapter);
+int mwifiex_bss_start(struct mwifiex_private *priv,
+		      struct mwifiex_ssid_bssid *ssid_bssid);
+int mwifiex_set_hs_params(struct mwifiex_private *priv,
+			      u16 action, int cmd_type,
+			      struct mwifiex_ds_hs_cfg *hscfg);
+int mwifiex_cancel_hs(struct mwifiex_private *priv, int cmd_type);
+int mwifiex_enable_hs(struct mwifiex_adapter *adapter);
+int mwifiex_get_signal_info(struct mwifiex_private *priv,
+			    struct mwifiex_ds_get_signal *signal);
+int mwifiex_drv_get_data_rate(struct mwifiex_private *priv,
+			      struct mwifiex_rate_cfg *rate);
+int mwifiex_find_best_bss(struct mwifiex_private *priv,
+			  struct mwifiex_ssid_bssid *ssid_bssid);
+int mwifiex_request_scan(struct mwifiex_private *priv,
+			 struct mwifiex_802_11_ssid *req_ssid);
+int mwifiex_set_user_scan_ioctl(struct mwifiex_private *priv,
+				struct mwifiex_user_scan_cfg *scan_req);
+int mwifiex_change_adhoc_chan(struct mwifiex_private *priv, int channel);
+int mwifiex_set_radio(struct mwifiex_private *priv, u8 option);
+
+int mwifiex_drv_change_adhoc_chan(struct mwifiex_private *priv, int channel);
+
+int mwifiex_set_encode(struct mwifiex_private *priv, const u8 *key,
+		       int key_len, u8 key_index, int disable);
+
+int mwifiex_set_gen_ie(struct mwifiex_private *priv, u8 *ie, int ie_len);
+
+int mwifiex_get_ver_ext(struct mwifiex_private *priv);
+
+int mwifiex_get_stats_info(struct mwifiex_private *priv,
+			   struct mwifiex_ds_get_stats *log);
+
+int mwifiex_reg_write(struct mwifiex_private *priv, u32 reg_type,
+		      u32 reg_offset, u32 reg_value);
+
+int mwifiex_reg_read(struct mwifiex_private *priv, u32 reg_type,
+		     u32 reg_offset, u32 *value);
+
+int mwifiex_eeprom_read(struct mwifiex_private *priv, u16 offset, u16 bytes,
+			u8 *value);
+
+int mwifiex_set_11n_httx_cfg(struct mwifiex_private *priv, int data);
+
+int mwifiex_get_11n_httx_cfg(struct mwifiex_private *priv, int *data);
+
+int mwifiex_set_tx_rate_cfg(struct mwifiex_private *priv, int tx_rate_index);
+
+int mwifiex_get_tx_rate_cfg(struct mwifiex_private *priv, int *tx_rate_index);
+
+int mwifiex_drv_set_power(struct mwifiex_private *priv, u32 *ps_mode);
+
+int mwifiex_drv_get_driver_version(struct mwifiex_adapter *adapter,
+				   char *version, int max_len);
+
+int mwifiex_set_tx_power(struct mwifiex_private *priv,
+			 struct mwifiex_power_cfg *power_cfg);
+
+int mwifiex_main_process(struct mwifiex_adapter *);
+
+int mwifiex_bss_set_channel(struct mwifiex_private *,
+			    struct mwifiex_chan_freq_power *cfp);
+int mwifiex_bss_ioctl_find_bss(struct mwifiex_private *,
+			       struct mwifiex_ssid_bssid *);
+int mwifiex_set_radio_band_cfg(struct mwifiex_private *,
+			 struct mwifiex_ds_band_cfg *);
+int mwifiex_get_bss_info(struct mwifiex_private *,
+			 struct mwifiex_bss_info *);
+
+#ifdef CONFIG_DEBUG_FS
+void mwifiex_debugfs_init(void);
+void mwifiex_debugfs_remove(void);
+
+void mwifiex_dev_debugfs_init(struct mwifiex_private *priv);
+void mwifiex_dev_debugfs_remove(struct mwifiex_private *priv);
+#endif
+#endif /* !_MWIFIEX_MAIN_H_ */
diff -druN linux-2.6.39-libre/drivers/net/wireless/mwifiex/Makefile linux-3.0-rc7-libre/drivers/net/wireless/mwifiex/Makefile
--- linux-2.6.39-libre/drivers/net/wireless/mwifiex/Makefile	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/net/wireless/mwifiex/Makefile	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,41 @@
+#
+# Copyright (C) 2011, Marvell International Ltd.
+#
+# This software file (the "File") is distributed by Marvell International
+# Ltd. under the terms of the GNU General Public License Version 2, June 1991
+# (the "License").  You may use, redistribute and/or modify this File in
+# accordance with the terms and conditions of the License, a copy of which
+# is available by writing to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
+# worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
+#
+# THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
+# ARE EXPRESSLY DISCLAIMED.  The License provides additional details about
+# this warranty disclaimer.
+
+
+mwifiex-y += main.o
+mwifiex-y += init.o
+mwifiex-y += cfp.o
+mwifiex-y += cmdevt.o
+mwifiex-y += util.o
+mwifiex-y += txrx.o
+mwifiex-y += wmm.o
+mwifiex-y += 11n.o
+mwifiex-y += 11n_aggr.o
+mwifiex-y += 11n_rxreorder.o
+mwifiex-y += scan.o
+mwifiex-y += join.o
+mwifiex-y += sta_ioctl.o
+mwifiex-y += sta_cmd.o
+mwifiex-y += sta_cmdresp.o
+mwifiex-y += sta_event.o
+mwifiex-y += sta_tx.o
+mwifiex-y += sta_rx.o
+mwifiex-y += cfg80211.o
+mwifiex-$(CONFIG_DEBUG_FS) += debugfs.o
+obj-$(CONFIG_MWIFIEX) += mwifiex.o
+
+mwifiex_sdio-y += sdio.o
+obj-$(CONFIG_MWIFIEX_SDIO) += mwifiex_sdio.o
diff -druN linux-2.6.39-libre/drivers/net/wireless/mwifiex/README linux-3.0-rc7-libre/drivers/net/wireless/mwifiex/README
--- linux-2.6.39-libre/drivers/net/wireless/mwifiex/README	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/net/wireless/mwifiex/README	2011-07-21 06:57:18.000000000 -0400
@@ -0,0 +1,203 @@
+# Copyright (C) 2011, Marvell International Ltd.
+#
+# This software file (the "File") is distributed by Marvell International
+# Ltd. under the terms of the GNU General Public License Version 2, June 1991
+# (the "License").  You may use, redistribute and/or modify this File in
+# accordance with the terms and conditions of the License, a copy of which
+# is available by writing to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
+# worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
+#
+# THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
+# ARE EXPRESSLY DISCLAIMED.  The License provides additional details about
+# this warranty disclaimer.
+
+
+===============================================================================
+			U S E R  M A N U A L
+
+1) FOR DRIVER INSTALL
+
+	a) /*(DEBLOBBED)*/
+	b) Install WLAN driver,
+		insmod mwifiex.ko
+	c) Uninstall WLAN driver,
+		ifconfig mlanX down
+		rmmod mwifiex
+
+
+2) FOR DRIVER CONFIGURATION AND INFO
+	The configurations can be done either using the 'iw' user space
+	utility or debugfs.
+
+	a) 'iw' utility commands
+
+	Following are some useful iw commands:-
+
+iw dev mlan0 scan
+
+	This command will trigger a scan.
+	The command will then display the scan table entries
+
+iw dev mlan0 connect -w <SSID> [<freq in MHz>] [<bssid>] [key 0:abcde d:1123456789a]
+	The above command can be used to connect to an AP with a particular SSID.
+	Ap's operating frequency can be specified or even the bssid. If the AP is using
+	WEP encryption, wep keys can be specified in the command.
+	Note: Every time before connecting to an AP scan command (iw dev mlan0 scan) should be used by user.
+
+iw dev mlan0 disconnect
+	This command will be used to disconnect from an AP.
+
+
+iw dev mlan0 ibss join <SSID> <freq in MHz> [fixed-freq] [fixed-bssid] [key 0:abcde]
+	The command will be used to join or create an ibss. Optionally, operating frequency,
+	bssid and the security related parameters can be specified while joining/creating
+	and ibss.
+
+iw dev mlan0 ibss leave
+	The command will be used to leave an ibss network.
+
+iw dev mlan0 link
+	The command will be used to get the connection status. The command will return parameters
+	such as SSID, operating frequency, rx/tx packets, signal strength, tx bitrate.
+
+	Apart from the iw utility all standard configurations using the 'iwconfig' utility are also supported.
+
+	b) Debugfs interface
+
+	The debugfs interface can be used for configurations and for getting
+	some useful information from the driver.
+	The section below explains the configurations that can be
+	done.
+
+	Mount debugfs to /debugfs mount point:
+
+		mkdir /debugfs
+		mount -t debugfs debugfs /debugfs
+
+	The information is provided in /debugfs/mwifiex/mlanX/:
+
+iw reg set <country code>
+	The command will be used to change the regulatory domain.
+
+iw reg get
+	The command will be used to get current regulatory domain.
+
+info
+	This command is used to get driver info.
+
+	Usage:
+		cat info
+
+	driver_name = "mwifiex"
+	driver_version = <driver_name, driver_version, (firmware_version)>
+	interface_name = "mlanX"
+	bss_mode = "Ad-hoc" | "Managed" | "Auto" | "Unknown"
+	media_state = "Disconnected" | "Connected"
+	mac_address = <6-byte adapter MAC address>
+	multicase_count = <multicast address count>
+	essid = <current SSID>
+	bssid = <current BSSID>
+	channel = <current channel>
+	region_code = <current region code>
+	multicasr_address[n] = <multicast address>
+	num_tx_bytes = <number of bytes sent to device>
+	num_rx_bytes = <number of bytes received from device and sent to kernel>
+	num_tx_pkts = <number of packets sent to device>
+	num_rx_pkts = <number of packets received from device and sent to kernel>
+	num_tx_pkts_dropped = <number of Tx packets dropped by driver>
+	num_rx_pkts_dropped = <number of Rx packets dropped by driver>
+	num_tx_pkts_err = <number of Tx packets failed to send to device>
+	num_rx_pkts_err = <number of Rx packets failed to receive from device>
+	carrier "on" | "off"
+	tx queue "stopped" | "started"
+
+	The following debug info are provided in /debugfs/mwifiex/mlanX/debug:
+
+	int_counter = <interrupt count, cleared when interrupt handled>
+	wmm_ac_vo = <number of packets sent to device from WMM AcVo queue>
+	wmm_ac_vi = <number of packets sent to device from WMM AcVi queue>
+	wmm_ac_be = <number of packets sent to device from WMM AcBE queue>
+	wmm_ac_bk = <number of packets sent to device from WMM AcBK queue>
+	max_tx_buf_size = <maximum Tx buffer size>
+	tx_buf_size = <current Tx buffer size>
+	curr_tx_buf_size = <current Tx buffer size>
+	ps_mode = <0/1, CAM mode/PS mode>
+	ps_state = <0/1/2/3, full power state/awake state/pre-sleep state/sleep state>
+	is_deep_sleep = <0/1, not deep sleep state/deep sleep state>
+	wakeup_dev_req = <0/1, wakeup device not required/required>
+	wakeup_tries = <wakeup device count, cleared when device awake>
+	hs_configured = <0/1, host sleep not configured/configured>
+	hs_activated = <0/1, extended host sleep not activated/activated>
+	num_tx_timeout = <number of Tx timeout>
+	num_cmd_timeout = <number of timeout commands>
+	timeout_cmd_id = <command id of the last timeout command>
+	timeout_cmd_act = <command action of the last timeout command>
+	last_cmd_id = <command id of the last several commands sent to device>
+	last_cmd_act = <command action of the last several commands sent to device>
+	last_cmd_index = <0 based last command index>
+	last_cmd_resp_id = <command id of the last several command responses received from device>
+	last_cmd_resp_index = <0 based last command response index>
+	last_event = <event id of the last several events received from device>
+	last_event_index = <0 based last event index>
+	num_cmd_h2c_fail = <number of commands failed to send to device>
+	num_cmd_sleep_cfm_fail = <number of sleep confirm failed to send to device>
+	num_tx_h2c_fail = <number of data packets failed to send to device>
+	num_evt_deauth = <number of deauthenticated events received from device>
+	num_evt_disassoc = <number of disassociated events received from device>
+	num_evt_link_lost = <number of link lost events received from device>
+	num_cmd_deauth = <number of deauthenticate commands sent to device>
+	num_cmd_assoc_ok = <number of associate commands with success return>
+	num_cmd_assoc_fail = <number of associate commands with failure return>
+	cmd_sent = <0/1, send command resources available/sending command to device>
+	data_sent = <0/1, send data resources available/sending data to device>
+	mp_rd_bitmap = <SDIO multi-port read bitmap>
+	mp_wr_bitmap = <SDIO multi-port write bitmap>
+	cmd_resp_received = <0/1, no cmd response to process/response received and yet to process>
+	event_received = <0/1, no event to process/event received and yet to process>
+	cmd_pending = <number of cmd pending>
+	tx_pending = <number of Tx packet pending>
+	rx_pending = <number of Rx packet pending>
+
+
+3) FOR DRIVER CONFIGURATION
+
+regrdwr
+	This command is used to read/write the adapter register.
+
+	Usage:
+		echo " <type> <offset> [value]" > regrdwr
+		cat regrdwr
+
+	where the parameters are,
+		<type>:     1:MAC/SOC, 2:BBP, 3:RF, 4:PMIC, 5:CAU
+		<offset>:   offset of register
+		[value]:    value to be written
+
+	Examples:
+		echo "1 0xa060" > regrdwr           : Read the MAC register
+		echo "1 0xa060 0x12" > regrdwr      : Write the MAC register
+		echo "1 0xa794 0x80000000" > regrdwr
+		                                    : Write 0x80000000 to MAC register
+rdeeprom
+	This command is used to read the EEPROM contents of the card.
+
+	Usage:
+		echo "<offset> <length>" > rdeeprom
+		cat rdeeprom
+
+	where the parameters are,
+		<offset>:   multiples of 4
+		<length>:   4-20, multiples of 4
+
+	Example:
+		echo "0 20" > rdeeprom      : Read 20 bytes of EEPROM data from offset 0
+
+getlog
+        This command is used to get the statistics available in the station.
+	Usage:
+
+	cat getlog
+
+===============================================================================
diff -druN linux-2.6.39-libre/drivers/net/wireless/mwifiex/scan.c linux-3.0-rc7-libre/drivers/net/wireless/mwifiex/scan.c
--- linux-2.6.39-libre/drivers/net/wireless/mwifiex/scan.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/net/wireless/mwifiex/scan.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,3025 @@
+/*
+ * Marvell Wireless LAN device driver: scan ioctl and command handling
+ *
+ * Copyright (C) 2011, Marvell International Ltd.
+ *
+ * This software file (the "File") is distributed by Marvell International
+ * Ltd. under the terms of the GNU General Public License Version 2, June 1991
+ * (the "License").  You may use, redistribute and/or modify this File in
+ * accordance with the terms and conditions of the License, a copy of which
+ * is available by writing to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
+ * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
+ *
+ * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
+ * ARE EXPRESSLY DISCLAIMED.  The License provides additional details about
+ * this warranty disclaimer.
+ */
+
+#include "decl.h"
+#include "ioctl.h"
+#include "util.h"
+#include "fw.h"
+#include "main.h"
+#include "11n.h"
+#include "cfg80211.h"
+
+/* The maximum number of channels the firmware can scan per command */
+#define MWIFIEX_MAX_CHANNELS_PER_SPECIFIC_SCAN   14
+
+#define MWIFIEX_CHANNELS_PER_SCAN_CMD            4
+
+/* Memory needed to store a max sized Channel List TLV for a firmware scan */
+#define CHAN_TLV_MAX_SIZE  (sizeof(struct mwifiex_ie_types_header)         \
+				+ (MWIFIEX_MAX_CHANNELS_PER_SPECIFIC_SCAN     \
+				*sizeof(struct mwifiex_chan_scan_param_set)))
+
+/* Memory needed to store supported rate */
+#define RATE_TLV_MAX_SIZE   (sizeof(struct mwifiex_ie_types_rates_param_set) \
+				+ HOSTCMD_SUPPORTED_RATES)
+
+/* Memory needed to store a max number/size WildCard SSID TLV for a firmware
+	scan */
+#define WILDCARD_SSID_TLV_MAX_SIZE  \
+	(MWIFIEX_MAX_SSID_LIST_LENGTH *					\
+		(sizeof(struct mwifiex_ie_types_wildcard_ssid_params)	\
+			+ IEEE80211_MAX_SSID_LEN))
+
+/* Maximum memory needed for a mwifiex_scan_cmd_config with all TLVs at max */
+#define MAX_SCAN_CFG_ALLOC (sizeof(struct mwifiex_scan_cmd_config)        \
+				+ sizeof(struct mwifiex_ie_types_num_probes)   \
+				+ sizeof(struct mwifiex_ie_types_htcap)       \
+				+ CHAN_TLV_MAX_SIZE                 \
+				+ RATE_TLV_MAX_SIZE                 \
+				+ WILDCARD_SSID_TLV_MAX_SIZE)
+
+
+union mwifiex_scan_cmd_config_tlv {
+	/* Scan configuration (variable length) */
+	struct mwifiex_scan_cmd_config config;
+	/* Max allocated block */
+	u8 config_alloc_buf[MAX_SCAN_CFG_ALLOC];
+};
+
+enum cipher_suite {
+	CIPHER_SUITE_TKIP,
+	CIPHER_SUITE_CCMP,
+	CIPHER_SUITE_MAX
+};
+static u8 mwifiex_wpa_oui[CIPHER_SUITE_MAX][4] = {
+	{ 0x00, 0x50, 0xf2, 0x02 },	/* TKIP */
+	{ 0x00, 0x50, 0xf2, 0x04 },	/* AES  */
+};
+static u8 mwifiex_rsn_oui[CIPHER_SUITE_MAX][4] = {
+	{ 0x00, 0x0f, 0xac, 0x02 },	/* TKIP */
+	{ 0x00, 0x0f, 0xac, 0x04 },	/* AES  */
+};
+
+/*
+ * This function parses a given IE for a given OUI.
+ *
+ * This is used to parse a WPA/RSN IE to find if it has
+ * a given oui in PTK.
+ */
+static u8
+mwifiex_search_oui_in_ie(struct ie_body *iebody, u8 *oui)
+{
+	u8 count;
+
+	count = iebody->ptk_cnt[0];
+
+	/* There could be multiple OUIs for PTK hence
+	   1) Take the length.
+	   2) Check all the OUIs for AES.
+	   3) If one of them is AES then pass success. */
+	while (count) {
+		if (!memcmp(iebody->ptk_body, oui, sizeof(iebody->ptk_body)))
+			return MWIFIEX_OUI_PRESENT;
+
+		--count;
+		if (count)
+			iebody = (struct ie_body *) ((u8 *) iebody +
+						sizeof(iebody->ptk_body));
+	}
+
+	pr_debug("info: %s: OUI is not found in PTK\n", __func__);
+	return MWIFIEX_OUI_NOT_PRESENT;
+}
+
+/*
+ * This function checks if a given OUI is present in a RSN IE.
+ *
+ * The function first checks if a RSN IE is present or not in the
+ * BSS descriptor. It tries to locate the OUI only if such an IE is
+ * present.
+ */
+static u8
+mwifiex_is_rsn_oui_present(struct mwifiex_bssdescriptor *bss_desc, u32 cipher)
+{
+	u8 *oui;
+	struct ie_body *iebody;
+	u8 ret = MWIFIEX_OUI_NOT_PRESENT;
+
+	if (((bss_desc->bcn_rsn_ie) && ((*(bss_desc->bcn_rsn_ie)).
+					ieee_hdr.element_id == WLAN_EID_RSN))) {
+		iebody = (struct ie_body *)
+			 (((u8 *) bss_desc->bcn_rsn_ie->data) +
+			 RSN_GTK_OUI_OFFSET);
+		oui = &mwifiex_rsn_oui[cipher][0];
+		ret = mwifiex_search_oui_in_ie(iebody, oui);
+		if (ret)
+			return ret;
+	}
+	return ret;
+}
+
+/*
+ * This function checks if a given OUI is present in a WPA IE.
+ *
+ * The function first checks if a WPA IE is present or not in the
+ * BSS descriptor. It tries to locate the OUI only if such an IE is
+ * present.
+ */
+static u8
+mwifiex_is_wpa_oui_present(struct mwifiex_bssdescriptor *bss_desc, u32 cipher)
+{
+	u8 *oui;
+	struct ie_body *iebody;
+	u8 ret = MWIFIEX_OUI_NOT_PRESENT;
+
+	if (((bss_desc->bcn_wpa_ie) && ((*(bss_desc->bcn_wpa_ie)).
+				      vend_hdr.element_id == WLAN_EID_WPA))) {
+		iebody = (struct ie_body *) bss_desc->bcn_wpa_ie->data;
+		oui = &mwifiex_wpa_oui[cipher][0];
+		ret = mwifiex_search_oui_in_ie(iebody, oui);
+		if (ret)
+			return ret;
+	}
+	return ret;
+}
+
+/*
+ * This function compares two SSIDs and checks if they match.
+ */
+s32
+mwifiex_ssid_cmp(struct mwifiex_802_11_ssid *ssid1,
+		 struct mwifiex_802_11_ssid *ssid2)
+{
+	if (!ssid1 || !ssid2 || (ssid1->ssid_len != ssid2->ssid_len))
+		return -1;
+	return memcmp(ssid1->ssid, ssid2->ssid, ssid1->ssid_len);
+}
+
+/*
+ * Sends IOCTL request to get the best BSS.
+ *
+ * This function allocates the IOCTL request buffer, fills it
+ * with requisite parameters and calls the IOCTL handler.
+ */
+int mwifiex_find_best_bss(struct mwifiex_private *priv,
+			  struct mwifiex_ssid_bssid *ssid_bssid)
+{
+	struct mwifiex_ssid_bssid tmp_ssid_bssid;
+	u8 *mac;
+
+	if (!ssid_bssid)
+		return -1;
+
+	memcpy(&tmp_ssid_bssid, ssid_bssid,
+	       sizeof(struct mwifiex_ssid_bssid));
+
+	if (!mwifiex_bss_ioctl_find_bss(priv, &tmp_ssid_bssid)) {
+		memcpy(ssid_bssid, &tmp_ssid_bssid,
+		       sizeof(struct mwifiex_ssid_bssid));
+		mac = (u8 *) &ssid_bssid->bssid;
+		dev_dbg(priv->adapter->dev, "cmd: found network: ssid=%s,"
+				" %pM\n", ssid_bssid->ssid.ssid, mac);
+		return 0;
+	}
+
+	return -1;
+}
+
+/*
+ * Sends IOCTL request to start a scan with user configurations.
+ *
+ * This function allocates the IOCTL request buffer, fills it
+ * with requisite parameters and calls the IOCTL handler.
+ *
+ * Upon completion, it also generates a wireless event to notify
+ * applications.
+ */
+int mwifiex_set_user_scan_ioctl(struct mwifiex_private *priv,
+				struct mwifiex_user_scan_cfg *scan_req)
+{
+	int status;
+
+	priv->adapter->cmd_wait_q.condition = false;
+
+	status = mwifiex_scan_networks(priv, scan_req);
+	if (!status)
+		status = mwifiex_wait_queue_complete(priv->adapter);
+
+	return status;
+}
+
+/*
+ * This function checks if wapi is enabled in driver and scanned network is
+ * compatible with it.
+ */
+static bool
+mwifiex_is_network_compatible_for_wapi(struct mwifiex_private *priv,
+				       struct mwifiex_bssdescriptor *bss_desc)
+{
+	if (priv->sec_info.wapi_enabled &&
+	    (bss_desc->bcn_wapi_ie &&
+	     ((*(bss_desc->bcn_wapi_ie)).ieee_hdr.element_id ==
+			WLAN_EID_BSS_AC_ACCESS_DELAY))) {
+		return true;
+	}
+	return false;
+}
+
+/*
+ * This function checks if driver is configured with no security mode and
+ * scanned network is compatible with it.
+ */
+static bool
+mwifiex_is_network_compatible_for_no_sec(struct mwifiex_private *priv,
+				       struct mwifiex_bssdescriptor *bss_desc)
+{
+	if (priv->sec_info.wep_status == MWIFIEX_802_11_WEP_DISABLED
+	    && !priv->sec_info.wpa_enabled && !priv->sec_info.wpa2_enabled
+	    && ((!bss_desc->bcn_wpa_ie) ||
+		((*(bss_desc->bcn_wpa_ie)).vend_hdr.element_id !=
+	    WLAN_EID_WPA))
+	    && ((!bss_desc->bcn_rsn_ie) ||
+		((*(bss_desc->bcn_rsn_ie)).ieee_hdr.element_id !=
+	    WLAN_EID_RSN))
+	    && !priv->sec_info.encryption_mode
+	    && !bss_desc->privacy) {
+		return true;
+	}
+	return false;
+}
+
+/*
+ * This function checks if static WEP is enabled in driver and scanned network
+ * is compatible with it.
+ */
+static bool
+mwifiex_is_network_compatible_for_static_wep(struct mwifiex_private *priv,
+				       struct mwifiex_bssdescriptor *bss_desc)
+{
+	if (priv->sec_info.wep_status == MWIFIEX_802_11_WEP_ENABLED
+	    && !priv->sec_info.wpa_enabled && !priv->sec_info.wpa2_enabled
+	    && bss_desc->privacy) {
+		return true;
+	}
+	return false;
+}
+
+/*
+ * This function checks if wpa is enabled in driver and scanned network is
+ * compatible with it.
+ */
+static bool
+mwifiex_is_network_compatible_for_wpa(struct mwifiex_private *priv,
+				      struct mwifiex_bssdescriptor *bss_desc,
+				      int index)
+{
+	if (priv->sec_info.wep_status == MWIFIEX_802_11_WEP_DISABLED
+	    && priv->sec_info.wpa_enabled && !priv->sec_info.wpa2_enabled
+	    && ((bss_desc->bcn_wpa_ie) && ((*(bss_desc->bcn_wpa_ie)).vend_hdr.
+						element_id == WLAN_EID_WPA))
+	   /*
+	    * Privacy bit may NOT be set in some APs like
+	    * LinkSys WRT54G && bss_desc->privacy
+	    */
+	 ) {
+		dev_dbg(priv->adapter->dev, "info: %s: WPA: index=%d"
+			" wpa_ie=%#x wpa2_ie=%#x WEP=%s WPA=%s WPA2=%s "
+			"EncMode=%#x privacy=%#x\n", __func__, index,
+			(bss_desc->bcn_wpa_ie) ?
+			(*(bss_desc->bcn_wpa_ie)).
+			vend_hdr.element_id : 0,
+			(bss_desc->bcn_rsn_ie) ?
+			(*(bss_desc->bcn_rsn_ie)).
+			ieee_hdr.element_id : 0,
+			(priv->sec_info.wep_status ==
+			MWIFIEX_802_11_WEP_ENABLED) ? "e" : "d",
+			(priv->sec_info.wpa_enabled) ? "e" : "d",
+			(priv->sec_info.wpa2_enabled) ? "e" : "d",
+			priv->sec_info.encryption_mode,
+			bss_desc->privacy);
+		return true;
+	}
+	return false;
+}
+
+/*
+ * This function checks if wpa2 is enabled in driver and scanned network is
+ * compatible with it.
+ */
+static bool
+mwifiex_is_network_compatible_for_wpa2(struct mwifiex_private *priv,
+				       struct mwifiex_bssdescriptor *bss_desc,
+				       int index)
+{
+	if (priv->sec_info.wep_status == MWIFIEX_802_11_WEP_DISABLED
+	   && !priv->sec_info.wpa_enabled && priv->sec_info.wpa2_enabled
+	   && ((bss_desc->bcn_rsn_ie) && ((*(bss_desc->bcn_rsn_ie)).ieee_hdr.
+						element_id == WLAN_EID_RSN))
+	   /*
+	    * Privacy bit may NOT be set in some APs like
+	    * LinkSys WRT54G && bss_desc->privacy
+	    */
+	 ) {
+		dev_dbg(priv->adapter->dev, "info: %s: WPA2: index=%d"
+			" wpa_ie=%#x wpa2_ie=%#x WEP=%s WPA=%s WPA2=%s "
+			"EncMode=%#x privacy=%#x\n", __func__, index,
+			(bss_desc->bcn_wpa_ie) ?
+			(*(bss_desc->bcn_wpa_ie)).
+			vend_hdr.element_id : 0,
+			(bss_desc->bcn_rsn_ie) ?
+			(*(bss_desc->bcn_rsn_ie)).
+			ieee_hdr.element_id : 0,
+			(priv->sec_info.wep_status ==
+			MWIFIEX_802_11_WEP_ENABLED) ? "e" : "d",
+			(priv->sec_info.wpa_enabled) ? "e" : "d",
+			(priv->sec_info.wpa2_enabled) ? "e" : "d",
+			priv->sec_info.encryption_mode,
+			bss_desc->privacy);
+		return true;
+	}
+	return false;
+}
+
+/*
+ * This function checks if adhoc AES is enabled in driver and scanned network is
+ * compatible with it.
+ */
+static bool
+mwifiex_is_network_compatible_for_adhoc_aes(struct mwifiex_private *priv,
+				       struct mwifiex_bssdescriptor *bss_desc)
+{
+	if (priv->sec_info.wep_status == MWIFIEX_802_11_WEP_DISABLED
+	    && !priv->sec_info.wpa_enabled && !priv->sec_info.wpa2_enabled
+	    && ((!bss_desc->bcn_wpa_ie) || ((*(bss_desc->bcn_wpa_ie)).vend_hdr.
+		   element_id != WLAN_EID_WPA))
+	    && ((!bss_desc->bcn_rsn_ie) || ((*(bss_desc->bcn_rsn_ie)).ieee_hdr.
+		   element_id != WLAN_EID_RSN))
+	    && !priv->sec_info.encryption_mode
+	    && bss_desc->privacy) {
+		return true;
+	}
+	return false;
+}
+
+/*
+ * This function checks if dynamic WEP is enabled in driver and scanned network
+ * is compatible with it.
+ */
+static bool
+mwifiex_is_network_compatible_for_dynamic_wep(struct mwifiex_private *priv,
+				       struct mwifiex_bssdescriptor *bss_desc,
+				       int index)
+{
+	if (priv->sec_info.wep_status == MWIFIEX_802_11_WEP_DISABLED
+	    && !priv->sec_info.wpa_enabled && !priv->sec_info.wpa2_enabled
+	    && ((!bss_desc->bcn_wpa_ie) || ((*(bss_desc->bcn_wpa_ie)).vend_hdr.
+		   element_id != WLAN_EID_WPA))
+	    && ((!bss_desc->bcn_rsn_ie) || ((*(bss_desc->bcn_rsn_ie)).ieee_hdr.
+		   element_id != WLAN_EID_RSN))
+	    && priv->sec_info.encryption_mode
+	    && bss_desc->privacy) {
+		dev_dbg(priv->adapter->dev, "info: %s: dynamic "
+			"WEP: index=%d wpa_ie=%#x wpa2_ie=%#x "
+			"EncMode=%#x privacy=%#x\n",
+			__func__, index,
+			(bss_desc->bcn_wpa_ie) ?
+			(*(bss_desc->bcn_wpa_ie)).
+			vend_hdr.element_id : 0,
+			(bss_desc->bcn_rsn_ie) ?
+			(*(bss_desc->bcn_rsn_ie)).
+			ieee_hdr.element_id : 0,
+			priv->sec_info.encryption_mode,
+			bss_desc->privacy);
+		return true;
+	}
+	return false;
+}
+
+/*
+ * This function checks if a scanned network is compatible with the driver
+ * settings.
+ *
+ *   WEP     WPA    WPA2   ad-hoc encrypt                  Network
+ * enabled enabled enabled  AES    mode   Privacy WPA WPA2 Compatible
+ *    0       0       0      0     NONE      0     0   0   yes No security
+ *    0       1       0      0      x        1x    1   x   yes WPA (disable
+ *                                                         HT if no AES)
+ *    0       0       1      0      x        1x    x   1   yes WPA2 (disable
+ *                                                         HT if no AES)
+ *    0       0       0      1     NONE      1     0   0   yes Ad-hoc AES
+ *    1       0       0      0     NONE      1     0   0   yes Static WEP
+ *                                                         (disable HT)
+ *    0       0       0      0    !=NONE     1     0   0   yes Dynamic WEP
+ *
+ * Compatibility is not matched while roaming, except for mode.
+ */
+static s32
+mwifiex_is_network_compatible(struct mwifiex_private *priv, u32 index, u32 mode)
+{
+	struct mwifiex_adapter *adapter = priv->adapter;
+	struct mwifiex_bssdescriptor *bss_desc;
+
+	bss_desc = &adapter->scan_table[index];
+	bss_desc->disable_11n = false;
+
+	/* Don't check for compatibility if roaming */
+	if (priv->media_connected && (priv->bss_mode == NL80211_IFTYPE_STATION)
+	    && (bss_desc->bss_mode == NL80211_IFTYPE_STATION))
+		return index;
+
+	if (priv->wps.session_enable) {
+		dev_dbg(adapter->dev,
+			"info: return success directly in WPS period\n");
+		return index;
+	}
+
+	if (mwifiex_is_network_compatible_for_wapi(priv, bss_desc)) {
+		dev_dbg(adapter->dev, "info: return success for WAPI AP\n");
+		return index;
+	}
+
+	if (bss_desc->bss_mode == mode) {
+		if (mwifiex_is_network_compatible_for_no_sec(priv, bss_desc)) {
+			/* No security */
+			return index;
+		} else if (mwifiex_is_network_compatible_for_static_wep(priv,
+								bss_desc)) {
+			/* Static WEP enabled */
+			dev_dbg(adapter->dev, "info: Disable 11n in WEP mode.\n");
+			bss_desc->disable_11n = true;
+			return index;
+		} else if (mwifiex_is_network_compatible_for_wpa(priv, bss_desc,
+								 index)) {
+			/* WPA enabled */
+			if (((priv->adapter->config_bands & BAND_GN
+			      || priv->adapter->config_bands & BAND_AN)
+			      && bss_desc->bcn_ht_cap)
+			      && !mwifiex_is_wpa_oui_present(bss_desc,
+					CIPHER_SUITE_CCMP)) {
+
+				if (mwifiex_is_wpa_oui_present(bss_desc,
+					    CIPHER_SUITE_TKIP)) {
+					dev_dbg(adapter->dev,
+						"info: Disable 11n if AES "
+						"is not supported by AP\n");
+					bss_desc->disable_11n = true;
+				} else {
+					return -1;
+				}
+			}
+			return index;
+		} else if (mwifiex_is_network_compatible_for_wpa2(priv,
+							bss_desc, index)) {
+			/* WPA2 enabled */
+			if (((priv->adapter->config_bands & BAND_GN
+			      || priv->adapter->config_bands & BAND_AN)
+			      && bss_desc->bcn_ht_cap)
+			      && !mwifiex_is_rsn_oui_present(bss_desc,
+					CIPHER_SUITE_CCMP)) {
+
+				if (mwifiex_is_rsn_oui_present(bss_desc,
+					    CIPHER_SUITE_TKIP)) {
+					dev_dbg(adapter->dev,
+						"info: Disable 11n if AES "
+						"is not supported by AP\n");
+					bss_desc->disable_11n = true;
+				} else {
+					return -1;
+				}
+			}
+			return index;
+		} else if (mwifiex_is_network_compatible_for_adhoc_aes(priv,
+								bss_desc)) {
+			/* Ad-hoc AES enabled */
+			return index;
+		} else if (mwifiex_is_network_compatible_for_dynamic_wep(priv,
+							bss_desc, index)) {
+			/* Dynamic WEP enabled */
+			return index;
+		}
+
+		/* Security doesn't match */
+		dev_dbg(adapter->dev, "info: %s: failed: index=%d "
+		       "wpa_ie=%#x wpa2_ie=%#x WEP=%s WPA=%s WPA2=%s EncMode"
+		       "=%#x privacy=%#x\n",
+		       __func__, index,
+		       (bss_desc->bcn_wpa_ie) ?
+		       (*(bss_desc->bcn_wpa_ie)).vend_hdr.
+		       element_id : 0,
+		       (bss_desc->bcn_rsn_ie) ?
+		       (*(bss_desc->bcn_rsn_ie)).ieee_hdr.
+		       element_id : 0,
+		       (priv->sec_info.wep_status ==
+				MWIFIEX_802_11_WEP_ENABLED) ? "e" : "d",
+		       (priv->sec_info.wpa_enabled) ? "e" : "d",
+		       (priv->sec_info.wpa2_enabled) ? "e" : "d",
+		       priv->sec_info.encryption_mode, bss_desc->privacy);
+		return -1;
+	}
+
+	/* Mode doesn't match */
+	return -1;
+}
+
+/*
+ * This function finds the best SSID in the scan list.
+ *
+ * It searches the scan table for the best SSID that also matches the current
+ * adapter network preference (mode, security etc.).
+ */
+static s32
+mwifiex_find_best_network_in_list(struct mwifiex_private *priv)
+{
+	struct mwifiex_adapter *adapter = priv->adapter;
+	u32 mode = priv->bss_mode;
+	s32 best_net = -1;
+	s32 best_rssi = 0;
+	u32 i;
+
+	dev_dbg(adapter->dev, "info: num of BSSIDs = %d\n",
+				adapter->num_in_scan_table);
+
+	for (i = 0; i < adapter->num_in_scan_table; i++) {
+		switch (mode) {
+		case NL80211_IFTYPE_STATION:
+		case NL80211_IFTYPE_ADHOC:
+			if (mwifiex_is_network_compatible(priv, i, mode) >= 0) {
+				if (SCAN_RSSI(adapter->scan_table[i].rssi) >
+				    best_rssi) {
+					best_rssi = SCAN_RSSI(adapter->
+							  scan_table[i].rssi);
+					best_net = i;
+				}
+			}
+			break;
+		case NL80211_IFTYPE_UNSPECIFIED:
+		default:
+			if (SCAN_RSSI(adapter->scan_table[i].rssi) >
+			    best_rssi) {
+				best_rssi = SCAN_RSSI(adapter->scan_table[i].
+						      rssi);
+				best_net = i;
+			}
+			break;
+		}
+	}
+
+	return best_net;
+}
+
+/*
+ * This function creates a channel list for the driver to scan, based
+ * on region/band information.
+ *
+ * This routine is used for any scan that is not provided with a
+ * specific channel list to scan.
+ */
+static void
+mwifiex_scan_create_channel_list(struct mwifiex_private *priv,
+				const struct mwifiex_user_scan_cfg
+				*user_scan_in,
+				struct mwifiex_chan_scan_param_set
+				*scan_chan_list,
+				u8 filtered_scan)
+{
+	enum ieee80211_band band;
+	struct ieee80211_supported_band *sband;
+	struct ieee80211_channel *ch;
+	struct mwifiex_adapter *adapter = priv->adapter;
+	int chan_idx = 0, i;
+	u8 scan_type;
+
+	for (band = 0; (band < IEEE80211_NUM_BANDS) ; band++) {
+
+		if (!priv->wdev->wiphy->bands[band])
+			continue;
+
+		sband = priv->wdev->wiphy->bands[band];
+
+		for (i = 0; (i < sband->n_channels) ; i++, chan_idx++) {
+			ch = &sband->channels[i];
+			if (ch->flags & IEEE80211_CHAN_DISABLED)
+				continue;
+			scan_chan_list[chan_idx].radio_type = band;
+			scan_type = ch->flags & IEEE80211_CHAN_PASSIVE_SCAN;
+			if (user_scan_in &&
+				user_scan_in->chan_list[0].scan_time)
+				scan_chan_list[chan_idx].max_scan_time =
+					cpu_to_le16((u16) user_scan_in->
+					chan_list[0].scan_time);
+			else if (scan_type == MWIFIEX_SCAN_TYPE_PASSIVE)
+				scan_chan_list[chan_idx].max_scan_time =
+					cpu_to_le16(adapter->passive_scan_time);
+			else
+				scan_chan_list[chan_idx].max_scan_time =
+					cpu_to_le16(adapter->active_scan_time);
+			if (scan_type == MWIFIEX_SCAN_TYPE_PASSIVE)
+				scan_chan_list[chan_idx].chan_scan_mode_bitmap
+					|= MWIFIEX_PASSIVE_SCAN;
+			else
+				scan_chan_list[chan_idx].chan_scan_mode_bitmap
+					&= ~MWIFIEX_PASSIVE_SCAN;
+			scan_chan_list[chan_idx].chan_number =
+							(u32) ch->hw_value;
+			if (filtered_scan) {
+				scan_chan_list[chan_idx].max_scan_time =
+				cpu_to_le16(adapter->specific_scan_time);
+				scan_chan_list[chan_idx].chan_scan_mode_bitmap
+					|= MWIFIEX_DISABLE_CHAN_FILT;
+			}
+		}
+
+	}
+}
+
+/*
+ * This function constructs and sends multiple scan config commands to
+ * the firmware.
+ *
+ * Previous routines in the code flow have created a scan command configuration
+ * with any requested TLVs.  This function splits the channel TLV into maximum
+ * channels supported per scan lists and sends the portion of the channel TLV,
+ * along with the other TLVs, to the firmware.
+ */
+static int
+mwifiex_scan_channel_list(struct mwifiex_private *priv,
+			  u32 max_chan_per_scan, u8 filtered_scan,
+			  struct mwifiex_scan_cmd_config *scan_cfg_out,
+			  struct mwifiex_ie_types_chan_list_param_set
+			  *chan_tlv_out,
+			  struct mwifiex_chan_scan_param_set *scan_chan_list)
+{
+	int ret = 0;
+	struct mwifiex_chan_scan_param_set *tmp_chan_list;
+	struct mwifiex_chan_scan_param_set *start_chan;
+
+	u32 tlv_idx;
+	u32 total_scan_time;
+	u32 done_early;
+
+	if (!scan_cfg_out || !chan_tlv_out || !scan_chan_list) {
+		dev_dbg(priv->adapter->dev,
+			"info: Scan: Null detect: %p, %p, %p\n",
+		       scan_cfg_out, chan_tlv_out, scan_chan_list);
+		return -1;
+	}
+
+	chan_tlv_out->header.type = cpu_to_le16(TLV_TYPE_CHANLIST);
+
+	/* Set the temp channel struct pointer to the start of the desired
+	   list */
+	tmp_chan_list = scan_chan_list;
+
+	/* Loop through the desired channel list, sending a new firmware scan
+	   commands for each max_chan_per_scan channels (or for 1,6,11
+	   individually if configured accordingly) */
+	while (tmp_chan_list->chan_number) {
+
+		tlv_idx = 0;
+		total_scan_time = 0;
+		chan_tlv_out->header.len = 0;
+		start_chan = tmp_chan_list;
+		done_early = false;
+
+		/*
+		 * Construct the Channel TLV for the scan command.  Continue to
+		 * insert channel TLVs until:
+		 *   - the tlv_idx hits the maximum configured per scan command
+		 *   - the next channel to insert is 0 (end of desired channel
+		 *     list)
+		 *   - done_early is set (controlling individual scanning of
+		 *     1,6,11)
+		 */
+		while (tlv_idx < max_chan_per_scan
+		       && tmp_chan_list->chan_number && !done_early) {
+
+			dev_dbg(priv->adapter->dev,
+				"info: Scan: Chan(%3d), Radio(%d),"
+				" Mode(%d, %d), Dur(%d)\n",
+			       tmp_chan_list->chan_number,
+			       tmp_chan_list->radio_type,
+			       tmp_chan_list->chan_scan_mode_bitmap
+			       & MWIFIEX_PASSIVE_SCAN,
+			       (tmp_chan_list->chan_scan_mode_bitmap
+			       & MWIFIEX_DISABLE_CHAN_FILT) >> 1,
+			       le16_to_cpu(tmp_chan_list->max_scan_time));
+
+			/* Copy the current channel TLV to the command being
+			   prepared */
+			memcpy(chan_tlv_out->chan_scan_param + tlv_idx,
+			       tmp_chan_list,
+			       sizeof(chan_tlv_out->chan_scan_param));
+
+			/* Increment the TLV header length by the size
+			   appended */
+			chan_tlv_out->header.len =
+			cpu_to_le16(le16_to_cpu(chan_tlv_out->header.len) +
+			(sizeof(chan_tlv_out->chan_scan_param)));
+
+			/*
+			 * The tlv buffer length is set to the number of bytes
+			 * of the between the channel tlv pointer and the start
+			 * of the tlv buffer.  This compensates for any TLVs
+			 * that were appended before the channel list.
+			 */
+			scan_cfg_out->tlv_buf_len = (u32) ((u8 *) chan_tlv_out -
+							scan_cfg_out->tlv_buf);
+
+			/* Add the size of the channel tlv header and the data
+			   length */
+			scan_cfg_out->tlv_buf_len +=
+				(sizeof(chan_tlv_out->header)
+				 + le16_to_cpu(chan_tlv_out->header.len));
+
+			/* Increment the index to the channel tlv we are
+			   constructing */
+			tlv_idx++;
+
+			/* Count the total scan time per command */
+			total_scan_time +=
+				le16_to_cpu(tmp_chan_list->max_scan_time);
+
+			done_early = false;
+
+			/* Stop the loop if the *current* channel is in the
+			   1,6,11 set and we are not filtering on a BSSID
+			   or SSID. */
+			if (!filtered_scan && (tmp_chan_list->chan_number == 1
+				|| tmp_chan_list->chan_number == 6
+				|| tmp_chan_list->chan_number == 11))
+				done_early = true;
+
+			/* Increment the tmp pointer to the next channel to
+			   be scanned */
+			tmp_chan_list++;
+
+			/* Stop the loop if the *next* channel is in the 1,6,11
+			   set.  This will cause it to be the only channel
+			   scanned on the next interation */
+			if (!filtered_scan && (tmp_chan_list->chan_number == 1
+				|| tmp_chan_list->chan_number == 6
+				|| tmp_chan_list->chan_number == 11))
+				done_early = true;
+		}
+
+		/* The total scan time should be less than scan command timeout
+		   value */
+		if (total_scan_time > MWIFIEX_MAX_TOTAL_SCAN_TIME) {
+			dev_err(priv->adapter->dev, "total scan time %dms"
+				" is over limit (%dms), scan skipped\n",
+				total_scan_time, MWIFIEX_MAX_TOTAL_SCAN_TIME);
+			ret = -1;
+			break;
+		}
+
+		priv->adapter->scan_channels = start_chan;
+
+		/* Send the scan command to the firmware with the specified
+		   cfg */
+		ret = mwifiex_send_cmd_async(priv, HostCmd_CMD_802_11_SCAN,
+					     HostCmd_ACT_GEN_SET, 0,
+					     scan_cfg_out);
+		if (ret)
+			break;
+	}
+
+	if (ret)
+		return -1;
+
+	return 0;
+}
+
+/*
+ * This function constructs a scan command configuration structure to use
+ * in scan commands.
+ *
+ * Application layer or other functions can invoke network scanning
+ * with a scan configuration supplied in a user scan configuration structure.
+ * This structure is used as the basis of one or many scan command configuration
+ * commands that are sent to the command processing module and eventually to the
+ * firmware.
+ *
+ * This function creates a scan command configuration structure  based on the
+ * following user supplied parameters (if present):
+ *      - SSID filter
+ *      - BSSID filter
+ *      - Number of Probes to be sent
+ *      - Channel list
+ *
+ * If the SSID or BSSID filter is not present, the filter is disabled/cleared.
+ * If the number of probes is not set, adapter default setting is used.
+ */
+static void
+mwifiex_scan_setup_scan_config(struct mwifiex_private *priv,
+			       const struct mwifiex_user_scan_cfg *user_scan_in,
+			       struct mwifiex_scan_cmd_config *scan_cfg_out,
+			       struct mwifiex_ie_types_chan_list_param_set
+			       **chan_list_out,
+			       struct mwifiex_chan_scan_param_set
+			       *scan_chan_list,
+			       u8 *max_chan_per_scan, u8 *filtered_scan,
+			       u8 *scan_current_only)
+{
+	struct mwifiex_adapter *adapter = priv->adapter;
+	struct mwifiex_ie_types_num_probes *num_probes_tlv;
+	struct mwifiex_ie_types_wildcard_ssid_params *wildcard_ssid_tlv;
+	struct mwifiex_ie_types_rates_param_set *rates_tlv;
+	const u8 zero_mac[ETH_ALEN] = { 0, 0, 0, 0, 0, 0 };
+	u8 *tlv_pos;
+	u32 num_probes;
+	u32 ssid_len;
+	u32 chan_idx;
+	u32 scan_type;
+	u16 scan_dur;
+	u8 channel;
+	u8 radio_type;
+	u32 ssid_idx;
+	u8 ssid_filter;
+	u8 rates[MWIFIEX_SUPPORTED_RATES];
+	u32 rates_size;
+	struct mwifiex_ie_types_htcap *ht_cap;
+
+	/* The tlv_buf_len is calculated for each scan command.  The TLVs added
+	   in this routine will be preserved since the routine that sends the
+	   command will append channelTLVs at *chan_list_out.  The difference
+	   between the *chan_list_out and the tlv_buf start will be used to
+	   calculate the size of anything we add in this routine. */
+	scan_cfg_out->tlv_buf_len = 0;
+
+	/* Running tlv pointer.  Assigned to chan_list_out at end of function
+	   so later routines know where channels can be added to the command
+	   buf */
+	tlv_pos = scan_cfg_out->tlv_buf;
+
+	/* Initialize the scan as un-filtered; the flag is later set to TRUE
+	   below if a SSID or BSSID filter is sent in the command */
+	*filtered_scan = false;
+
+	/* Initialize the scan as not being only on the current channel.  If
+	   the channel list is customized, only contains one channel, and is
+	   the active channel, this is set true and data flow is not halted. */
+	*scan_current_only = false;
+
+	if (user_scan_in) {
+
+		/* Default the ssid_filter flag to TRUE, set false under
+		   certain wildcard conditions and qualified by the existence
+		   of an SSID list before marking the scan as filtered */
+		ssid_filter = true;
+
+		/* Set the BSS type scan filter, use Adapter setting if
+		   unset */
+		scan_cfg_out->bss_mode =
+			(user_scan_in->bss_mode ? (u8) user_scan_in->
+			 bss_mode : (u8) adapter->scan_mode);
+
+		/* Set the number of probes to send, use Adapter setting
+		   if unset */
+		num_probes =
+			(user_scan_in->num_probes ? user_scan_in->
+			 num_probes : adapter->scan_probes);
+
+		/*
+		 * Set the BSSID filter to the incoming configuration,
+		 * if non-zero.  If not set, it will remain disabled
+		 * (all zeros).
+		 */
+		memcpy(scan_cfg_out->specific_bssid,
+		       user_scan_in->specific_bssid,
+		       sizeof(scan_cfg_out->specific_bssid));
+
+		for (ssid_idx = 0;
+		     ((ssid_idx < ARRAY_SIZE(user_scan_in->ssid_list))
+		      && (*user_scan_in->ssid_list[ssid_idx].ssid
+			  || user_scan_in->ssid_list[ssid_idx].max_len));
+		     ssid_idx++) {
+
+			ssid_len = strlen(user_scan_in->ssid_list[ssid_idx].
+					  ssid) + 1;
+
+			wildcard_ssid_tlv =
+				(struct mwifiex_ie_types_wildcard_ssid_params *)
+				tlv_pos;
+			wildcard_ssid_tlv->header.type =
+				cpu_to_le16(TLV_TYPE_WILDCARDSSID);
+			wildcard_ssid_tlv->header.len = cpu_to_le16(
+				(u16) (ssid_len + sizeof(wildcard_ssid_tlv->
+							 max_ssid_length)));
+			wildcard_ssid_tlv->max_ssid_length =
+				user_scan_in->ssid_list[ssid_idx].max_len;
+
+			memcpy(wildcard_ssid_tlv->ssid,
+			       user_scan_in->ssid_list[ssid_idx].ssid,
+			       ssid_len);
+
+			tlv_pos += (sizeof(wildcard_ssid_tlv->header)
+				+ le16_to_cpu(wildcard_ssid_tlv->header.len));
+
+			dev_dbg(adapter->dev, "info: scan: ssid_list[%d]: %s, %d\n",
+				ssid_idx, wildcard_ssid_tlv->ssid,
+				wildcard_ssid_tlv->max_ssid_length);
+
+			/* Empty wildcard ssid with a maxlen will match many or
+			   potentially all SSIDs (maxlen == 32), therefore do
+			   not treat the scan as
+			   filtered. */
+			if (!ssid_len && wildcard_ssid_tlv->max_ssid_length)
+				ssid_filter = false;
+
+		}
+
+		/*
+		 *  The default number of channels sent in the command is low to
+		 *  ensure the response buffer from the firmware does not
+		 *  truncate scan results.  That is not an issue with an SSID
+		 *  or BSSID filter applied to the scan results in the firmware.
+		 */
+		if ((ssid_idx && ssid_filter)
+		    || memcmp(scan_cfg_out->specific_bssid, &zero_mac,
+			      sizeof(zero_mac)))
+			*filtered_scan = true;
+	} else {
+		scan_cfg_out->bss_mode = (u8) adapter->scan_mode;
+		num_probes = adapter->scan_probes;
+	}
+
+	/*
+	 *  If a specific BSSID or SSID is used, the number of channels in the
+	 *  scan command will be increased to the absolute maximum.
+	 */
+	if (*filtered_scan)
+		*max_chan_per_scan = MWIFIEX_MAX_CHANNELS_PER_SPECIFIC_SCAN;
+	else
+		*max_chan_per_scan = MWIFIEX_CHANNELS_PER_SCAN_CMD;
+
+	/* If the input config or adapter has the number of Probes set,
+	   add tlv */
+	if (num_probes) {
+
+		dev_dbg(adapter->dev, "info: scan: num_probes = %d\n",
+						num_probes);
+
+		num_probes_tlv = (struct mwifiex_ie_types_num_probes *) tlv_pos;
+		num_probes_tlv->header.type = cpu_to_le16(TLV_TYPE_NUMPROBES);
+		num_probes_tlv->header.len =
+			cpu_to_le16(sizeof(num_probes_tlv->num_probes));
+		num_probes_tlv->num_probes = cpu_to_le16((u16) num_probes);
+
+		tlv_pos += sizeof(num_probes_tlv->header) +
+			le16_to_cpu(num_probes_tlv->header.len);
+
+	}
+
+	/* Append rates tlv */
+	memset(rates, 0, sizeof(rates));
+
+	rates_size = mwifiex_get_supported_rates(priv, rates);
+
+	rates_tlv = (struct mwifiex_ie_types_rates_param_set *) tlv_pos;
+	rates_tlv->header.type = cpu_to_le16(WLAN_EID_SUPP_RATES);
+	rates_tlv->header.len = cpu_to_le16((u16) rates_size);
+	memcpy(rates_tlv->rates, rates, rates_size);
+	tlv_pos += sizeof(rates_tlv->header) + rates_size;
+
+	dev_dbg(adapter->dev, "info: SCAN_CMD: Rates size = %d\n", rates_size);
+
+	if (ISSUPP_11NENABLED(priv->adapter->fw_cap_info)
+	    && (priv->adapter->config_bands & BAND_GN
+		|| priv->adapter->config_bands & BAND_AN)) {
+		ht_cap = (struct mwifiex_ie_types_htcap *) tlv_pos;
+		memset(ht_cap, 0, sizeof(struct mwifiex_ie_types_htcap));
+		ht_cap->header.type = cpu_to_le16(WLAN_EID_HT_CAPABILITY);
+		ht_cap->header.len =
+				cpu_to_le16(sizeof(struct ieee80211_ht_cap));
+		radio_type =
+			mwifiex_band_to_radio_type(priv->adapter->config_bands);
+		mwifiex_fill_cap_info(priv, radio_type, ht_cap);
+		tlv_pos += sizeof(struct mwifiex_ie_types_htcap);
+	}
+
+	/* Append vendor specific IE TLV */
+	mwifiex_cmd_append_vsie_tlv(priv, MWIFIEX_VSIE_MASK_SCAN, &tlv_pos);
+
+	/*
+	 * Set the output for the channel TLV to the address in the tlv buffer
+	 *   past any TLVs that were added in this function (SSID, num_probes).
+	 *   Channel TLVs will be added past this for each scan command,
+	 *   preserving the TLVs that were previously added.
+	 */
+	*chan_list_out =
+		(struct mwifiex_ie_types_chan_list_param_set *) tlv_pos;
+
+	if (user_scan_in && user_scan_in->chan_list[0].chan_number) {
+
+		dev_dbg(adapter->dev, "info: Scan: Using supplied channel list\n");
+
+		for (chan_idx = 0;
+		     chan_idx < MWIFIEX_USER_SCAN_CHAN_MAX
+		     && user_scan_in->chan_list[chan_idx].chan_number;
+		     chan_idx++) {
+
+			channel = user_scan_in->chan_list[chan_idx].chan_number;
+			(scan_chan_list + chan_idx)->chan_number = channel;
+
+			radio_type =
+				user_scan_in->chan_list[chan_idx].radio_type;
+			(scan_chan_list + chan_idx)->radio_type = radio_type;
+
+			scan_type = user_scan_in->chan_list[chan_idx].scan_type;
+
+			if (scan_type == MWIFIEX_SCAN_TYPE_PASSIVE)
+				(scan_chan_list +
+				 chan_idx)->chan_scan_mode_bitmap
+					|= MWIFIEX_PASSIVE_SCAN;
+			else
+				(scan_chan_list +
+				 chan_idx)->chan_scan_mode_bitmap
+					&= ~MWIFIEX_PASSIVE_SCAN;
+
+			if (user_scan_in->chan_list[chan_idx].scan_time) {
+				scan_dur = (u16) user_scan_in->
+					chan_list[chan_idx].scan_time;
+			} else {
+				if (scan_type == MWIFIEX_SCAN_TYPE_PASSIVE)
+					scan_dur = adapter->passive_scan_time;
+				else if (*filtered_scan)
+					scan_dur = adapter->specific_scan_time;
+				else
+					scan_dur = adapter->active_scan_time;
+			}
+
+			(scan_chan_list + chan_idx)->min_scan_time =
+				cpu_to_le16(scan_dur);
+			(scan_chan_list + chan_idx)->max_scan_time =
+				cpu_to_le16(scan_dur);
+		}
+
+		/* Check if we are only scanning the current channel */
+		if ((chan_idx == 1)
+		    && (user_scan_in->chan_list[0].chan_number
+			== priv->curr_bss_params.bss_descriptor.channel)) {
+			*scan_current_only = true;
+			dev_dbg(adapter->dev,
+				"info: Scan: Scanning current channel only\n");
+		}
+
+	} else {
+		dev_dbg(adapter->dev,
+				"info: Scan: Creating full region channel list\n");
+		mwifiex_scan_create_channel_list(priv, user_scan_in,
+						 scan_chan_list,
+						 *filtered_scan);
+	}
+}
+
+/*
+ * This function inspects the scan response buffer for pointers to
+ * expected TLVs.
+ *
+ * TLVs can be included at the end of the scan response BSS information.
+ *
+ * Data in the buffer is parsed pointers to TLVs that can potentially
+ * be passed back in the response.
+ */
+static void
+mwifiex_ret_802_11_scan_get_tlv_ptrs(struct mwifiex_adapter *adapter,
+				     struct mwifiex_ie_types_data *tlv,
+				     u32 tlv_buf_size, u32 req_tlv_type,
+				     struct mwifiex_ie_types_data **tlv_data)
+{
+	struct mwifiex_ie_types_data *current_tlv;
+	u32 tlv_buf_left;
+	u32 tlv_type;
+	u32 tlv_len;
+
+	current_tlv = tlv;
+	tlv_buf_left = tlv_buf_size;
+	*tlv_data = NULL;
+
+	dev_dbg(adapter->dev, "info: SCAN_RESP: tlv_buf_size = %d\n",
+						tlv_buf_size);
+
+	while (tlv_buf_left >= sizeof(struct mwifiex_ie_types_header)) {
+
+		tlv_type = le16_to_cpu(current_tlv->header.type);
+		tlv_len = le16_to_cpu(current_tlv->header.len);
+
+		if (sizeof(tlv->header) + tlv_len > tlv_buf_left) {
+			dev_err(adapter->dev, "SCAN_RESP: TLV buffer corrupt\n");
+			break;
+		}
+
+		if (req_tlv_type == tlv_type) {
+			switch (tlv_type) {
+			case TLV_TYPE_TSFTIMESTAMP:
+				dev_dbg(adapter->dev, "info: SCAN_RESP: TSF "
+					"timestamp TLV, len = %d\n", tlv_len);
+				*tlv_data = (struct mwifiex_ie_types_data *)
+					current_tlv;
+				break;
+			case TLV_TYPE_CHANNELBANDLIST:
+				dev_dbg(adapter->dev, "info: SCAN_RESP: channel"
+					" band list TLV, len = %d\n", tlv_len);
+				*tlv_data = (struct mwifiex_ie_types_data *)
+					current_tlv;
+				break;
+			default:
+				dev_err(adapter->dev,
+					"SCAN_RESP: unhandled TLV = %d\n",
+				       tlv_type);
+				/* Give up, this seems corrupted */
+				return;
+			}
+		}
+
+		if (*tlv_data)
+			break;
+
+
+		tlv_buf_left -= (sizeof(tlv->header) + tlv_len);
+		current_tlv =
+			(struct mwifiex_ie_types_data *) (current_tlv->data +
+							  tlv_len);
+
+	}			/* while */
+}
+
+/*
+ * This function interprets a BSS scan response returned from the firmware.
+ *
+ * The various fixed fields and IEs are parsed and passed back for a BSS
+ * probe response or beacon from scan command. Information is recorded as
+ * needed in the scan table for that entry.
+ *
+ * The following IE types are recognized and parsed -
+ *      - SSID
+ *      - Supported rates
+ *      - FH parameters set
+ *      - DS parameters set
+ *      - CF parameters set
+ *      - IBSS parameters set
+ *      - ERP information
+ *      - Extended supported rates
+ *      - Vendor specific (221)
+ *      - RSN IE
+ *      - WAPI IE
+ *      - HT capability
+ *      - HT operation
+ *      - BSS Coexistence 20/40
+ *      - Extended capability
+ *      - Overlapping BSS scan parameters
+ */
+static int
+mwifiex_interpret_bss_desc_with_ie(struct mwifiex_adapter *adapter,
+				   struct mwifiex_bssdescriptor *bss_entry,
+				   u8 **beacon_info, u32 *bytes_left)
+{
+	int ret = 0;
+	u8 element_id;
+	struct ieee_types_fh_param_set *fh_param_set;
+	struct ieee_types_ds_param_set *ds_param_set;
+	struct ieee_types_cf_param_set *cf_param_set;
+	struct ieee_types_ibss_param_set *ibss_param_set;
+	__le16 beacon_interval;
+	__le16 capabilities;
+	u8 *current_ptr;
+	u8 *rate;
+	u8 element_len;
+	u16 total_ie_len;
+	u8 bytes_to_copy;
+	u8 rate_size;
+	u16 beacon_size;
+	u8 found_data_rate_ie;
+	u32 bytes_left_for_current_beacon;
+	struct ieee_types_vendor_specific *vendor_ie;
+	const u8 wpa_oui[4] = { 0x00, 0x50, 0xf2, 0x01 };
+	const u8 wmm_oui[4] = { 0x00, 0x50, 0xf2, 0x02 };
+
+	found_data_rate_ie = false;
+	rate_size = 0;
+	beacon_size = 0;
+
+	if (*bytes_left >= sizeof(beacon_size)) {
+		/* Extract & convert beacon size from the command buffer */
+		memcpy(&beacon_size, *beacon_info, sizeof(beacon_size));
+		*bytes_left -= sizeof(beacon_size);
+		*beacon_info += sizeof(beacon_size);
+	}
+
+	if (!beacon_size || beacon_size > *bytes_left) {
+		*beacon_info += *bytes_left;
+		*bytes_left = 0;
+		return -1;
+	}
+
+	/* Initialize the current working beacon pointer for this BSS
+	   iteration */
+	current_ptr = *beacon_info;
+
+	/* Advance the return beacon pointer past the current beacon */
+	*beacon_info += beacon_size;
+	*bytes_left -= beacon_size;
+
+	bytes_left_for_current_beacon = beacon_size;
+
+	memcpy(bss_entry->mac_address, current_ptr, ETH_ALEN);
+	dev_dbg(adapter->dev, "info: InterpretIE: AP MAC Addr: %pM\n",
+						bss_entry->mac_address);
+
+	current_ptr += ETH_ALEN;
+	bytes_left_for_current_beacon -= ETH_ALEN;
+
+	if (bytes_left_for_current_beacon < 12) {
+		dev_err(adapter->dev, "InterpretIE: not enough bytes left\n");
+		return -1;
+	}
+
+	/*
+	 * Next 4 fields are RSSI, time stamp, beacon interval,
+	 *   and capability information
+	 */
+
+	/* RSSI is 1 byte long */
+	bss_entry->rssi = (s32) (*current_ptr);
+	dev_dbg(adapter->dev, "info: InterpretIE: RSSI=%02X\n", *current_ptr);
+	current_ptr += 1;
+	bytes_left_for_current_beacon -= 1;
+
+	/*
+	 *  The RSSI is not part of the beacon/probe response.  After we have
+	 *    advanced current_ptr past the RSSI field, save the remaining
+	 *    data for use at the application layer
+	 */
+	bss_entry->beacon_buf = current_ptr;
+	bss_entry->beacon_buf_size = bytes_left_for_current_beacon;
+
+	/* Time stamp is 8 bytes long */
+	memcpy(bss_entry->time_stamp, current_ptr, 8);
+	current_ptr += 8;
+	bytes_left_for_current_beacon -= 8;
+
+	/* Beacon interval is 2 bytes long */
+	memcpy(&beacon_interval, current_ptr, 2);
+	bss_entry->beacon_period = le16_to_cpu(beacon_interval);
+	current_ptr += 2;
+	bytes_left_for_current_beacon -= 2;
+
+	/* Capability information is 2 bytes long */
+	memcpy(&capabilities, current_ptr, 2);
+	dev_dbg(adapter->dev, "info: InterpretIE: capabilities=0x%X\n",
+	       capabilities);
+	bss_entry->cap_info_bitmap = le16_to_cpu(capabilities);
+	current_ptr += 2;
+	bytes_left_for_current_beacon -= 2;
+
+	/* Rest of the current buffer are IE's */
+	dev_dbg(adapter->dev, "info: InterpretIE: IELength for this AP = %d\n",
+	       bytes_left_for_current_beacon);
+
+	if (bss_entry->cap_info_bitmap & WLAN_CAPABILITY_PRIVACY) {
+		dev_dbg(adapter->dev, "info: InterpretIE: AP WEP enabled\n");
+		bss_entry->privacy = MWIFIEX_802_11_PRIV_FILTER_8021X_WEP;
+	} else {
+		bss_entry->privacy = MWIFIEX_802_11_PRIV_FILTER_ACCEPT_ALL;
+	}
+
+	if (bss_entry->cap_info_bitmap & WLAN_CAPABILITY_IBSS)
+		bss_entry->bss_mode = NL80211_IFTYPE_ADHOC;
+	else
+		bss_entry->bss_mode = NL80211_IFTYPE_STATION;
+
+
+	/* Process variable IE */
+	while (bytes_left_for_current_beacon >= 2) {
+		element_id = *current_ptr;
+		element_len = *(current_ptr + 1);
+		total_ie_len = element_len + sizeof(struct ieee_types_header);
+
+		if (bytes_left_for_current_beacon < total_ie_len) {
+			dev_err(adapter->dev, "err: InterpretIE: in processing"
+				" IE, bytes left < IE length\n");
+			bytes_left_for_current_beacon = 0;
+			ret = -1;
+			continue;
+		}
+		switch (element_id) {
+		case WLAN_EID_SSID:
+			bss_entry->ssid.ssid_len = element_len;
+			memcpy(bss_entry->ssid.ssid, (current_ptr + 2),
+			       element_len);
+			dev_dbg(adapter->dev, "info: InterpretIE: ssid: %-32s\n",
+			       bss_entry->ssid.ssid);
+			break;
+
+		case WLAN_EID_SUPP_RATES:
+			memcpy(bss_entry->data_rates, current_ptr + 2,
+			       element_len);
+			memcpy(bss_entry->supported_rates, current_ptr + 2,
+			       element_len);
+			rate_size = element_len;
+			found_data_rate_ie = true;
+			break;
+
+		case WLAN_EID_FH_PARAMS:
+			fh_param_set =
+				(struct ieee_types_fh_param_set *) current_ptr;
+			memcpy(&bss_entry->phy_param_set.fh_param_set,
+			       fh_param_set,
+			       sizeof(struct ieee_types_fh_param_set));
+			break;
+
+		case WLAN_EID_DS_PARAMS:
+			ds_param_set =
+				(struct ieee_types_ds_param_set *) current_ptr;
+
+			bss_entry->channel = ds_param_set->current_chan;
+
+			memcpy(&bss_entry->phy_param_set.ds_param_set,
+			       ds_param_set,
+			       sizeof(struct ieee_types_ds_param_set));
+			break;
+
+		case WLAN_EID_CF_PARAMS:
+			cf_param_set =
+				(struct ieee_types_cf_param_set *) current_ptr;
+			memcpy(&bss_entry->ss_param_set.cf_param_set,
+			       cf_param_set,
+			       sizeof(struct ieee_types_cf_param_set));
+			break;
+
+		case WLAN_EID_IBSS_PARAMS:
+			ibss_param_set =
+				(struct ieee_types_ibss_param_set *)
+				current_ptr;
+			memcpy(&bss_entry->ss_param_set.ibss_param_set,
+			       ibss_param_set,
+			       sizeof(struct ieee_types_ibss_param_set));
+			break;
+
+		case WLAN_EID_ERP_INFO:
+			bss_entry->erp_flags = *(current_ptr + 2);
+			break;
+
+		case WLAN_EID_EXT_SUPP_RATES:
+			/*
+			 * Only process extended supported rate
+			 * if data rate is already found.
+			 * Data rate IE should come before
+			 * extended supported rate IE
+			 */
+			if (found_data_rate_ie) {
+				if ((element_len + rate_size) >
+				    MWIFIEX_SUPPORTED_RATES)
+					bytes_to_copy =
+						(MWIFIEX_SUPPORTED_RATES -
+						 rate_size);
+				else
+					bytes_to_copy = element_len;
+
+				rate = (u8 *) bss_entry->data_rates;
+				rate += rate_size;
+				memcpy(rate, current_ptr + 2, bytes_to_copy);
+
+				rate = (u8 *) bss_entry->supported_rates;
+				rate += rate_size;
+				memcpy(rate, current_ptr + 2, bytes_to_copy);
+			}
+			break;
+
+		case WLAN_EID_VENDOR_SPECIFIC:
+			vendor_ie = (struct ieee_types_vendor_specific *)
+					current_ptr;
+
+			if (!memcmp
+			    (vendor_ie->vend_hdr.oui, wpa_oui,
+			     sizeof(wpa_oui))) {
+				bss_entry->bcn_wpa_ie =
+					(struct ieee_types_vendor_specific *)
+					current_ptr;
+				bss_entry->wpa_offset = (u16) (current_ptr -
+							bss_entry->beacon_buf);
+			} else if (!memcmp(vendor_ie->vend_hdr.oui, wmm_oui,
+				    sizeof(wmm_oui))) {
+				if (total_ie_len ==
+				    sizeof(struct ieee_types_wmm_parameter)
+				    || total_ie_len ==
+				    sizeof(struct ieee_types_wmm_info))
+					/*
+					 * Only accept and copy the WMM IE if
+					 * it matches the size expected for the
+					 * WMM Info IE or the WMM Parameter IE.
+					 */
+					memcpy((u8 *) &bss_entry->wmm_ie,
+					       current_ptr, total_ie_len);
+			}
+			break;
+		case WLAN_EID_RSN:
+			bss_entry->bcn_rsn_ie =
+				(struct ieee_types_generic *) current_ptr;
+			bss_entry->rsn_offset = (u16) (current_ptr -
+							bss_entry->beacon_buf);
+			break;
+		case WLAN_EID_BSS_AC_ACCESS_DELAY:
+			bss_entry->bcn_wapi_ie =
+				(struct ieee_types_generic *) current_ptr;
+			bss_entry->wapi_offset = (u16) (current_ptr -
+							bss_entry->beacon_buf);
+			break;
+		case WLAN_EID_HT_CAPABILITY:
+			bss_entry->bcn_ht_cap = (struct ieee80211_ht_cap *)
+					(current_ptr +
+					sizeof(struct ieee_types_header));
+			bss_entry->ht_cap_offset = (u16) (current_ptr +
+					sizeof(struct ieee_types_header) -
+					bss_entry->beacon_buf);
+			break;
+		case WLAN_EID_HT_INFORMATION:
+			bss_entry->bcn_ht_info = (struct ieee80211_ht_info *)
+					(current_ptr +
+					sizeof(struct ieee_types_header));
+			bss_entry->ht_info_offset = (u16) (current_ptr +
+					sizeof(struct ieee_types_header) -
+					bss_entry->beacon_buf);
+			break;
+		case WLAN_EID_BSS_COEX_2040:
+			bss_entry->bcn_bss_co_2040 = (u8 *) (current_ptr +
+					sizeof(struct ieee_types_header));
+			bss_entry->bss_co_2040_offset = (u16) (current_ptr +
+					sizeof(struct ieee_types_header) -
+						bss_entry->beacon_buf);
+			break;
+		case WLAN_EID_EXT_CAPABILITY:
+			bss_entry->bcn_ext_cap = (u8 *) (current_ptr +
+					sizeof(struct ieee_types_header));
+			bss_entry->ext_cap_offset = (u16) (current_ptr +
+					sizeof(struct ieee_types_header) -
+					bss_entry->beacon_buf);
+			break;
+		case WLAN_EID_OVERLAP_BSS_SCAN_PARAM:
+			bss_entry->bcn_obss_scan =
+				(struct ieee_types_obss_scan_param *)
+				current_ptr;
+			bss_entry->overlap_bss_offset = (u16) (current_ptr -
+							bss_entry->beacon_buf);
+			break;
+		default:
+			break;
+		}
+
+		current_ptr += element_len + 2;
+
+		/* Need to account for IE ID and IE Len */
+		bytes_left_for_current_beacon -= (element_len + 2);
+
+	}	/* while (bytes_left_for_current_beacon > 2) */
+	return ret;
+}
+
+/*
+ * This function adjusts the pointers used in beacon buffers to reflect
+ * shifts.
+ *
+ * The memory allocated for beacon buffers is of fixed sizes where all the
+ * saved beacons must be stored. New beacons are added in the free portion
+ * of this memory, space permitting; while duplicate beacon buffers are
+ * placed at the same start location. However, since duplicate beacon
+ * buffers may not match the size of the old one, all the following buffers
+ * in the memory must be shifted to either make space, or to fill up freed
+ * up space.
+ *
+ * This function is used to update the beacon buffer pointers that are past
+ * an existing beacon buffer that is updated with a new one of different
+ * size. The pointers are shifted by a fixed amount, either forward or
+ * backward.
+ *
+ * the following pointers in every affected beacon buffers are changed, if
+ * present -
+ *      - WPA IE pointer
+ *      - RSN IE pointer
+ *      - WAPI IE pointer
+ *      - HT capability IE pointer
+ *      - HT information IE pointer
+ *      - BSS coexistence 20/40 IE pointer
+ *      - Extended capability IE pointer
+ *      - Overlapping BSS scan parameter IE pointer
+ */
+static void
+mwifiex_adjust_beacon_buffer_ptrs(struct mwifiex_private *priv, u8 advance,
+				  u8 *bcn_store, u32 rem_bcn_size,
+				  u32 num_of_ent)
+{
+	struct mwifiex_adapter *adapter = priv->adapter;
+	u32 adj_idx;
+	for (adj_idx = 0; adj_idx < num_of_ent; adj_idx++) {
+		if (adapter->scan_table[adj_idx].beacon_buf > bcn_store) {
+
+			if (advance)
+				adapter->scan_table[adj_idx].beacon_buf +=
+					rem_bcn_size;
+			else
+				adapter->scan_table[adj_idx].beacon_buf -=
+					rem_bcn_size;
+
+			if (adapter->scan_table[adj_idx].bcn_wpa_ie)
+				adapter->scan_table[adj_idx].bcn_wpa_ie =
+				(struct ieee_types_vendor_specific *)
+				(adapter->scan_table[adj_idx].beacon_buf +
+				 adapter->scan_table[adj_idx].wpa_offset);
+			if (adapter->scan_table[adj_idx].bcn_rsn_ie)
+				adapter->scan_table[adj_idx].bcn_rsn_ie =
+				(struct ieee_types_generic *)
+				(adapter->scan_table[adj_idx].beacon_buf +
+				 adapter->scan_table[adj_idx].rsn_offset);
+			if (adapter->scan_table[adj_idx].bcn_wapi_ie)
+				adapter->scan_table[adj_idx].bcn_wapi_ie =
+				(struct ieee_types_generic *)
+				(adapter->scan_table[adj_idx].beacon_buf +
+				 adapter->scan_table[adj_idx].wapi_offset);
+			if (adapter->scan_table[adj_idx].bcn_ht_cap)
+				adapter->scan_table[adj_idx].bcn_ht_cap =
+				(struct ieee80211_ht_cap *)
+				(adapter->scan_table[adj_idx].beacon_buf +
+				 adapter->scan_table[adj_idx].ht_cap_offset);
+
+			if (adapter->scan_table[adj_idx].bcn_ht_info)
+				adapter->scan_table[adj_idx].bcn_ht_info =
+				(struct ieee80211_ht_info *)
+				(adapter->scan_table[adj_idx].beacon_buf +
+				 adapter->scan_table[adj_idx].ht_info_offset);
+			if (adapter->scan_table[adj_idx].bcn_bss_co_2040)
+				adapter->scan_table[adj_idx].bcn_bss_co_2040 =
+				(u8 *)
+				(adapter->scan_table[adj_idx].beacon_buf +
+			       adapter->scan_table[adj_idx].bss_co_2040_offset);
+			if (adapter->scan_table[adj_idx].bcn_ext_cap)
+				adapter->scan_table[adj_idx].bcn_ext_cap =
+				(u8 *)
+				(adapter->scan_table[adj_idx].beacon_buf +
+				 adapter->scan_table[adj_idx].ext_cap_offset);
+			if (adapter->scan_table[adj_idx].bcn_obss_scan)
+				adapter->scan_table[adj_idx].bcn_obss_scan =
+				(struct ieee_types_obss_scan_param *)
+				(adapter->scan_table[adj_idx].beacon_buf +
+			       adapter->scan_table[adj_idx].overlap_bss_offset);
+		}
+	}
+}
+
+/*
+ * This function updates the pointers used in beacon buffer for given bss
+ * descriptor to reflect shifts
+ *
+ * Following pointers are updated
+ *      - WPA IE pointer
+ *      - RSN IE pointer
+ *      - WAPI IE pointer
+ *      - HT capability IE pointer
+ *      - HT information IE pointer
+ *      - BSS coexistence 20/40 IE pointer
+ *      - Extended capability IE pointer
+ *      - Overlapping BSS scan parameter IE pointer
+ */
+static void
+mwifiex_update_beacon_buffer_ptrs(struct mwifiex_bssdescriptor *beacon)
+{
+	if (beacon->bcn_wpa_ie)
+		beacon->bcn_wpa_ie = (struct ieee_types_vendor_specific *)
+			(beacon->beacon_buf + beacon->wpa_offset);
+	if (beacon->bcn_rsn_ie)
+		beacon->bcn_rsn_ie = (struct ieee_types_generic *)
+			(beacon->beacon_buf + beacon->rsn_offset);
+	if (beacon->bcn_wapi_ie)
+		beacon->bcn_wapi_ie = (struct ieee_types_generic *)
+			(beacon->beacon_buf + beacon->wapi_offset);
+	if (beacon->bcn_ht_cap)
+		beacon->bcn_ht_cap = (struct ieee80211_ht_cap *)
+			(beacon->beacon_buf + beacon->ht_cap_offset);
+	if (beacon->bcn_ht_info)
+		beacon->bcn_ht_info = (struct ieee80211_ht_info *)
+			(beacon->beacon_buf + beacon->ht_info_offset);
+	if (beacon->bcn_bss_co_2040)
+		beacon->bcn_bss_co_2040 = (u8 *) (beacon->beacon_buf +
+			beacon->bss_co_2040_offset);
+	if (beacon->bcn_ext_cap)
+		beacon->bcn_ext_cap = (u8 *) (beacon->beacon_buf +
+			beacon->ext_cap_offset);
+	if (beacon->bcn_obss_scan)
+		beacon->bcn_obss_scan = (struct ieee_types_obss_scan_param *)
+			(beacon->beacon_buf + beacon->overlap_bss_offset);
+}
+
+/*
+ * This function stores a beacon or probe response for a BSS returned
+ * in the scan.
+ *
+ * This stores a new scan response or an update for a previous scan response.
+ * New entries need to verify that they do not exceed the total amount of
+ * memory allocated for the table.
+ *
+ * Replacement entries need to take into consideration the amount of space
+ * currently allocated for the beacon/probe response and adjust the entry
+ * as needed.
+ *
+ * A small amount of extra pad (SCAN_BEACON_ENTRY_PAD) is generally reserved
+ * for an entry in case it is a beacon since a probe response for the
+ * network will by larger per the standard.  This helps to reduce the
+ * amount of memory copying to fit a new probe response into an entry
+ * already occupied by a network's previously stored beacon.
+ */
+static void
+mwifiex_ret_802_11_scan_store_beacon(struct mwifiex_private *priv,
+				     u32 beacon_idx, u32 num_of_ent,
+				     struct mwifiex_bssdescriptor *new_beacon)
+{
+	struct mwifiex_adapter *adapter = priv->adapter;
+	u8 *bcn_store;
+	u32 new_bcn_size;
+	u32 old_bcn_size;
+	u32 bcn_space;
+
+	if (adapter->scan_table[beacon_idx].beacon_buf) {
+
+		new_bcn_size = new_beacon->beacon_buf_size;
+		old_bcn_size = adapter->scan_table[beacon_idx].beacon_buf_size;
+		bcn_space = adapter->scan_table[beacon_idx].beacon_buf_size_max;
+		bcn_store = adapter->scan_table[beacon_idx].beacon_buf;
+
+		/* Set the max to be the same as current entry unless changed
+		   below */
+		new_beacon->beacon_buf_size_max = bcn_space;
+		if (new_bcn_size == old_bcn_size) {
+			/*
+			 * Beacon is the same size as the previous entry.
+			 *   Replace the previous contents with the scan result
+			 */
+			memcpy(bcn_store, new_beacon->beacon_buf,
+			       new_beacon->beacon_buf_size);
+
+		} else if (new_bcn_size <= bcn_space) {
+			/*
+			 * New beacon size will fit in the amount of space
+			 *   we have previously allocated for it
+			 */
+
+			/* Copy the new beacon buffer entry over the old one */
+			memcpy(bcn_store, new_beacon->beacon_buf, new_bcn_size);
+
+			/*
+			 *  If the old beacon size was less than the maximum
+			 *  we had alloted for the entry, and the new entry
+			 *  is even smaller, reset the max size to the old
+			 *  beacon entry and compress the storage space
+			 *  (leaving a new pad space of (old_bcn_size -
+			 *  new_bcn_size).
+			 */
+			if (old_bcn_size < bcn_space
+			    && new_bcn_size <= old_bcn_size) {
+				/*
+				 * Old Beacon size is smaller than the alloted
+				 * storage size. Shrink the alloted storage
+				 * space.
+				 */
+				dev_dbg(adapter->dev, "info: AppControl:"
+					" smaller duplicate beacon "
+				       "(%d), old = %d, new = %d, space = %d,"
+				       "left = %d\n",
+				       beacon_idx, old_bcn_size, new_bcn_size,
+				       bcn_space,
+				       (int)(sizeof(adapter->bcn_buf) -
+					(adapter->bcn_buf_end -
+					 adapter->bcn_buf)));
+
+				/*
+				 *  memmove (since the memory overlaps) the
+				 *  data after the beacon we just stored to the
+				 *  end of the current beacon.  This cleans up
+				 *  any unused space the old larger beacon was
+				 *  using in the buffer
+				 */
+				memmove(bcn_store + old_bcn_size,
+					bcn_store + bcn_space,
+					adapter->bcn_buf_end - (bcn_store +
+								   bcn_space));
+
+				/*
+				 * Decrement the end pointer by the difference
+				 * between the old larger size and the new
+				 * smaller size since we are using less space
+				 * due to the new beacon being smaller
+				 */
+				adapter->bcn_buf_end -=
+					(bcn_space - old_bcn_size);
+
+				/* Set the maximum storage size to the old
+				   beacon size */
+				new_beacon->beacon_buf_size_max = old_bcn_size;
+
+				/* Adjust beacon buffer pointers that are past
+				   the current */
+				mwifiex_adjust_beacon_buffer_ptrs(priv, 0,
+					bcn_store, (bcn_space - old_bcn_size),
+					num_of_ent);
+			}
+		} else if (adapter->bcn_buf_end + (new_bcn_size - bcn_space)
+			   < (adapter->bcn_buf + sizeof(adapter->bcn_buf))) {
+			/*
+			 * Beacon is larger than space previously allocated
+			 * (bcn_space) and there is enough space left in the
+			 * beaconBuffer to store the additional data
+			 */
+			dev_dbg(adapter->dev, "info: AppControl:"
+				" larger duplicate beacon (%d), "
+			       "old = %d, new = %d, space = %d, left = %d\n",
+			       beacon_idx, old_bcn_size, new_bcn_size,
+			       bcn_space,
+			       (int)(sizeof(adapter->bcn_buf) -
+				(adapter->bcn_buf_end -
+				 adapter->bcn_buf)));
+
+			/*
+			 * memmove (since the memory overlaps) the data
+			 *  after the beacon we just stored to the end of
+			 *  the current beacon.  This moves the data for
+			 *  the beacons after this further in memory to
+			 *  make space for the new larger beacon we are
+			 *  about to copy in.
+			 */
+			memmove(bcn_store + new_bcn_size,
+				bcn_store + bcn_space,
+				adapter->bcn_buf_end - (bcn_store + bcn_space));
+
+			/* Copy the new beacon buffer entry over the old one */
+			memcpy(bcn_store, new_beacon->beacon_buf, new_bcn_size);
+
+			/* Move the beacon end pointer by the amount of new
+			   beacon data we are adding */
+			adapter->bcn_buf_end += (new_bcn_size - bcn_space);
+
+			/*
+			 * This entry is bigger than the alloted max space
+			 *  previously reserved.  Increase the max space to
+			 *  be equal to the new beacon size
+			 */
+			new_beacon->beacon_buf_size_max = new_bcn_size;
+
+			/* Adjust beacon buffer pointers that are past the
+			   current */
+			mwifiex_adjust_beacon_buffer_ptrs(priv, 1, bcn_store,
+						(new_bcn_size - bcn_space),
+						num_of_ent);
+		} else {
+			/*
+			 * Beacon is larger than the previously allocated space,
+			 * but there is not enough free space to store the
+			 * additional data.
+			 */
+			dev_err(adapter->dev, "AppControl: larger duplicate "
+				" beacon (%d), old = %d new = %d, space = %d,"
+				" left = %d\n", beacon_idx, old_bcn_size,
+				new_bcn_size, bcn_space,
+				(int)(sizeof(adapter->bcn_buf) -
+				(adapter->bcn_buf_end - adapter->bcn_buf)));
+
+			/* Storage failure, keep old beacon intact */
+			new_beacon->beacon_buf_size = old_bcn_size;
+			if (new_beacon->bcn_wpa_ie)
+				new_beacon->wpa_offset =
+					adapter->scan_table[beacon_idx].
+					wpa_offset;
+			if (new_beacon->bcn_rsn_ie)
+				new_beacon->rsn_offset =
+					adapter->scan_table[beacon_idx].
+					rsn_offset;
+			if (new_beacon->bcn_wapi_ie)
+				new_beacon->wapi_offset =
+					adapter->scan_table[beacon_idx].
+					wapi_offset;
+			if (new_beacon->bcn_ht_cap)
+				new_beacon->ht_cap_offset =
+					adapter->scan_table[beacon_idx].
+					ht_cap_offset;
+			if (new_beacon->bcn_ht_info)
+				new_beacon->ht_info_offset =
+					adapter->scan_table[beacon_idx].
+					ht_info_offset;
+			if (new_beacon->bcn_bss_co_2040)
+				new_beacon->bss_co_2040_offset =
+					adapter->scan_table[beacon_idx].
+					bss_co_2040_offset;
+			if (new_beacon->bcn_ext_cap)
+				new_beacon->ext_cap_offset =
+					adapter->scan_table[beacon_idx].
+					ext_cap_offset;
+			if (new_beacon->bcn_obss_scan)
+				new_beacon->overlap_bss_offset =
+					adapter->scan_table[beacon_idx].
+					overlap_bss_offset;
+		}
+		/* Point the new entry to its permanent storage space */
+		new_beacon->beacon_buf = bcn_store;
+		mwifiex_update_beacon_buffer_ptrs(new_beacon);
+	} else {
+		/*
+		 * No existing beacon data exists for this entry, check to see
+		 *   if we can fit it in the remaining space
+		 */
+		if (adapter->bcn_buf_end + new_beacon->beacon_buf_size +
+		    SCAN_BEACON_ENTRY_PAD < (adapter->bcn_buf +
+					     sizeof(adapter->bcn_buf))) {
+
+			/*
+			 * Copy the beacon buffer data from the local entry to
+			 * the adapter dev struct buffer space used to store
+			 * the raw beacon data for each entry in the scan table
+			 */
+			memcpy(adapter->bcn_buf_end, new_beacon->beacon_buf,
+			       new_beacon->beacon_buf_size);
+
+			/* Update the beacon ptr to point to the table save
+			   area */
+			new_beacon->beacon_buf = adapter->bcn_buf_end;
+			new_beacon->beacon_buf_size_max =
+				(new_beacon->beacon_buf_size +
+				 SCAN_BEACON_ENTRY_PAD);
+
+			mwifiex_update_beacon_buffer_ptrs(new_beacon);
+
+			/* Increment the end pointer by the size reserved */
+			adapter->bcn_buf_end += new_beacon->beacon_buf_size_max;
+
+			dev_dbg(adapter->dev, "info: AppControl: beacon[%02d]"
+				" sz=%03d, used = %04d, left = %04d\n",
+			       beacon_idx,
+			       new_beacon->beacon_buf_size,
+			       (int)(adapter->bcn_buf_end - adapter->bcn_buf),
+			       (int)(sizeof(adapter->bcn_buf) -
+				(adapter->bcn_buf_end -
+				 adapter->bcn_buf)));
+		} else {
+			/* No space for new beacon */
+			dev_dbg(adapter->dev, "info: AppControl: no space for"
+				" beacon (%d): %pM sz=%03d, left=%03d\n",
+			       beacon_idx, new_beacon->mac_address,
+			       new_beacon->beacon_buf_size,
+			       (int)(sizeof(adapter->bcn_buf) -
+				(adapter->bcn_buf_end -
+				 adapter->bcn_buf)));
+
+			/* Storage failure; clear storage records for this
+			   bcn */
+			new_beacon->beacon_buf = NULL;
+			new_beacon->beacon_buf_size = 0;
+			new_beacon->beacon_buf_size_max = 0;
+			new_beacon->bcn_wpa_ie = NULL;
+			new_beacon->wpa_offset = 0;
+			new_beacon->bcn_rsn_ie = NULL;
+			new_beacon->rsn_offset = 0;
+			new_beacon->bcn_wapi_ie = NULL;
+			new_beacon->wapi_offset = 0;
+			new_beacon->bcn_ht_cap = NULL;
+			new_beacon->ht_cap_offset = 0;
+			new_beacon->bcn_ht_info = NULL;
+			new_beacon->ht_info_offset = 0;
+			new_beacon->bcn_bss_co_2040 = NULL;
+			new_beacon->bss_co_2040_offset = 0;
+			new_beacon->bcn_ext_cap = NULL;
+			new_beacon->ext_cap_offset = 0;
+			new_beacon->bcn_obss_scan = NULL;
+			new_beacon->overlap_bss_offset = 0;
+		}
+	}
+}
+
+/*
+ * This function restores a beacon buffer of the current BSS descriptor.
+ */
+static void mwifiex_restore_curr_bcn(struct mwifiex_private *priv)
+{
+	struct mwifiex_adapter *adapter = priv->adapter;
+	struct mwifiex_bssdescriptor *curr_bss =
+		&priv->curr_bss_params.bss_descriptor;
+	unsigned long flags;
+
+	if (priv->curr_bcn_buf &&
+	    ((adapter->bcn_buf_end + priv->curr_bcn_size) <
+	     (adapter->bcn_buf + sizeof(adapter->bcn_buf)))) {
+		spin_lock_irqsave(&priv->curr_bcn_buf_lock, flags);
+
+		/* restore the current beacon buffer */
+		memcpy(adapter->bcn_buf_end, priv->curr_bcn_buf,
+		       priv->curr_bcn_size);
+		curr_bss->beacon_buf = adapter->bcn_buf_end;
+		curr_bss->beacon_buf_size = priv->curr_bcn_size;
+		adapter->bcn_buf_end += priv->curr_bcn_size;
+
+		/* adjust the pointers in the current BSS descriptor */
+		if (curr_bss->bcn_wpa_ie)
+			curr_bss->bcn_wpa_ie =
+				(struct ieee_types_vendor_specific *)
+				(curr_bss->beacon_buf +
+				 curr_bss->wpa_offset);
+
+		if (curr_bss->bcn_rsn_ie)
+			curr_bss->bcn_rsn_ie = (struct ieee_types_generic *)
+				(curr_bss->beacon_buf +
+				 curr_bss->rsn_offset);
+
+		if (curr_bss->bcn_ht_cap)
+			curr_bss->bcn_ht_cap = (struct ieee80211_ht_cap *)
+				(curr_bss->beacon_buf +
+				 curr_bss->ht_cap_offset);
+
+		if (curr_bss->bcn_ht_info)
+			curr_bss->bcn_ht_info = (struct ieee80211_ht_info *)
+				(curr_bss->beacon_buf +
+				 curr_bss->ht_info_offset);
+
+		if (curr_bss->bcn_bss_co_2040)
+			curr_bss->bcn_bss_co_2040 =
+				(u8 *) (curr_bss->beacon_buf +
+				 curr_bss->bss_co_2040_offset);
+
+		if (curr_bss->bcn_ext_cap)
+			curr_bss->bcn_ext_cap = (u8 *) (curr_bss->beacon_buf +
+				 curr_bss->ext_cap_offset);
+
+		if (curr_bss->bcn_obss_scan)
+			curr_bss->bcn_obss_scan =
+				(struct ieee_types_obss_scan_param *)
+				(curr_bss->beacon_buf +
+				 curr_bss->overlap_bss_offset);
+
+		spin_unlock_irqrestore(&priv->curr_bcn_buf_lock, flags);
+
+		dev_dbg(adapter->dev, "info: current beacon restored %d\n",
+		       priv->curr_bcn_size);
+	} else {
+		dev_warn(adapter->dev,
+			"curr_bcn_buf not saved or bcn_buf has no space\n");
+	}
+}
+
+/*
+ * This function post processes the scan table after a new scan command has
+ * completed.
+ *
+ * It inspects each entry of the scan table and tries to find an entry that
+ * matches with our current associated/joined network from the scan. If
+ * one is found, the stored copy of the BSS descriptor of our current network
+ * is updated.
+ *
+ * It also debug dumps the current scan table contents after processing is over.
+ */
+static void
+mwifiex_process_scan_results(struct mwifiex_private *priv)
+{
+	struct mwifiex_adapter *adapter = priv->adapter;
+	s32 j;
+	u32 i;
+	unsigned long flags;
+
+	if (priv->media_connected) {
+
+		j = mwifiex_find_ssid_in_list(priv, &priv->curr_bss_params.
+					      bss_descriptor.ssid,
+					      priv->curr_bss_params.
+					      bss_descriptor.mac_address,
+					      priv->bss_mode);
+
+		if (j >= 0) {
+			spin_lock_irqsave(&priv->curr_bcn_buf_lock, flags);
+			priv->curr_bss_params.bss_descriptor.bcn_wpa_ie = NULL;
+			priv->curr_bss_params.bss_descriptor.wpa_offset = 0;
+			priv->curr_bss_params.bss_descriptor.bcn_rsn_ie = NULL;
+			priv->curr_bss_params.bss_descriptor.rsn_offset = 0;
+			priv->curr_bss_params.bss_descriptor.bcn_wapi_ie = NULL;
+			priv->curr_bss_params.bss_descriptor.wapi_offset = 0;
+			priv->curr_bss_params.bss_descriptor.bcn_ht_cap = NULL;
+			priv->curr_bss_params.bss_descriptor.ht_cap_offset =
+				0;
+			priv->curr_bss_params.bss_descriptor.bcn_ht_info = NULL;
+			priv->curr_bss_params.bss_descriptor.ht_info_offset =
+				0;
+			priv->curr_bss_params.bss_descriptor.bcn_bss_co_2040 =
+				NULL;
+			priv->curr_bss_params.bss_descriptor.
+				bss_co_2040_offset = 0;
+			priv->curr_bss_params.bss_descriptor.bcn_ext_cap = NULL;
+			priv->curr_bss_params.bss_descriptor.ext_cap_offset = 0;
+			priv->curr_bss_params.bss_descriptor.
+				bcn_obss_scan = NULL;
+			priv->curr_bss_params.bss_descriptor.
+				overlap_bss_offset = 0;
+			priv->curr_bss_params.bss_descriptor.beacon_buf = NULL;
+			priv->curr_bss_params.bss_descriptor.beacon_buf_size =
+				0;
+			priv->curr_bss_params.bss_descriptor.
+				beacon_buf_size_max = 0;
+
+			dev_dbg(adapter->dev, "info: Found current ssid/bssid"
+				" in list @ index #%d\n", j);
+			/* Make a copy of current BSSID descriptor */
+			memcpy(&priv->curr_bss_params.bss_descriptor,
+			       &adapter->scan_table[j],
+			       sizeof(priv->curr_bss_params.bss_descriptor));
+
+			mwifiex_save_curr_bcn(priv);
+			spin_unlock_irqrestore(&priv->curr_bcn_buf_lock, flags);
+
+		} else {
+			mwifiex_restore_curr_bcn(priv);
+		}
+	}
+
+	for (i = 0; i < adapter->num_in_scan_table; i++)
+		dev_dbg(adapter->dev, "info: scan:(%02d) %pM "
+		       "RSSI[%03d], SSID[%s]\n",
+		       i, adapter->scan_table[i].mac_address,
+		       (s32) adapter->scan_table[i].rssi,
+		       adapter->scan_table[i].ssid.ssid);
+}
+
+/*
+ * This function converts radio type scan parameter to a band configuration
+ * to be used in join command.
+ */
+static u8
+mwifiex_radio_type_to_band(u8 radio_type)
+{
+	switch (radio_type) {
+	case HostCmd_SCAN_RADIO_TYPE_A:
+		return BAND_A;
+	case HostCmd_SCAN_RADIO_TYPE_BG:
+	default:
+		return BAND_G;
+	}
+}
+
+/*
+ * This function deletes a specific indexed entry from the scan table.
+ *
+ * This also compacts the remaining entries and adjusts any buffering
+ * of beacon/probe response data if needed.
+ */
+static void
+mwifiex_scan_delete_table_entry(struct mwifiex_private *priv, s32 table_idx)
+{
+	struct mwifiex_adapter *adapter = priv->adapter;
+	u32 del_idx;
+	u32 beacon_buf_adj;
+	u8 *beacon_buf;
+
+	/*
+	 * Shift the saved beacon buffer data for the scan table back over the
+	 *   entry being removed.  Update the end of buffer pointer.  Save the
+	 *   deleted buffer allocation size for pointer adjustments for entries
+	 *   compacted after the deleted index.
+	 */
+	beacon_buf_adj = adapter->scan_table[table_idx].beacon_buf_size_max;
+
+	dev_dbg(adapter->dev, "info: Scan: Delete Entry %d, beacon buffer "
+		"removal = %d bytes\n", table_idx, beacon_buf_adj);
+
+	/* Check if the table entry had storage allocated for its beacon */
+	if (beacon_buf_adj) {
+		beacon_buf = adapter->scan_table[table_idx].beacon_buf;
+
+		/*
+		 * Remove the entry's buffer space, decrement the table end
+		 * pointer by the amount we are removing
+		 */
+		adapter->bcn_buf_end -= beacon_buf_adj;
+
+		dev_dbg(adapter->dev, "info: scan: delete entry %d,"
+			" compact data: %p <- %p (sz = %d)\n",
+		       table_idx, beacon_buf,
+		       beacon_buf + beacon_buf_adj,
+		       (int)(adapter->bcn_buf_end - beacon_buf));
+
+		/*
+		 * Compact data storage.  Copy all data after the deleted
+		 * entry's end address (beacon_buf + beacon_buf_adj) back
+		 * to the original start address (beacon_buf).
+		 *
+		 * Scan table entries affected by the move will have their
+		 * entry pointer adjusted below.
+		 *
+		 * Use memmove since the dest/src memory regions overlap.
+		 */
+		memmove(beacon_buf, beacon_buf + beacon_buf_adj,
+			adapter->bcn_buf_end - beacon_buf);
+	}
+
+	dev_dbg(adapter->dev,
+		"info: Scan: Delete Entry %d, num_in_scan_table = %d\n",
+	       table_idx, adapter->num_in_scan_table);
+
+	/* Shift all of the entries after the table_idx back by one, compacting
+	   the table and removing the requested entry */
+	for (del_idx = table_idx; (del_idx + 1) < adapter->num_in_scan_table;
+	     del_idx++) {
+		/* Copy the next entry over this one */
+		memcpy(adapter->scan_table + del_idx,
+		       adapter->scan_table + del_idx + 1,
+		       sizeof(struct mwifiex_bssdescriptor));
+
+		/*
+		 * Adjust this entry's pointer to its beacon buffer based on
+		 * the removed/compacted entry from the deleted index.  Don't
+		 * decrement if the buffer pointer is NULL (no data stored for
+		 * this entry).
+		 */
+		if (adapter->scan_table[del_idx].beacon_buf) {
+			adapter->scan_table[del_idx].beacon_buf -=
+				beacon_buf_adj;
+			if (adapter->scan_table[del_idx].bcn_wpa_ie)
+				adapter->scan_table[del_idx].bcn_wpa_ie =
+					(struct ieee_types_vendor_specific *)
+					(adapter->scan_table[del_idx].
+					 beacon_buf +
+					 adapter->scan_table[del_idx].
+					 wpa_offset);
+			if (adapter->scan_table[del_idx].bcn_rsn_ie)
+				adapter->scan_table[del_idx].bcn_rsn_ie =
+					(struct ieee_types_generic *)
+					(adapter->scan_table[del_idx].
+					 beacon_buf +
+					 adapter->scan_table[del_idx].
+					 rsn_offset);
+			if (adapter->scan_table[del_idx].bcn_wapi_ie)
+				adapter->scan_table[del_idx].bcn_wapi_ie =
+					(struct ieee_types_generic *)
+					(adapter->scan_table[del_idx].beacon_buf
+					 + adapter->scan_table[del_idx].
+					 wapi_offset);
+			if (adapter->scan_table[del_idx].bcn_ht_cap)
+				adapter->scan_table[del_idx].bcn_ht_cap =
+					(struct ieee80211_ht_cap *)
+					(adapter->scan_table[del_idx].beacon_buf
+					 + adapter->scan_table[del_idx].
+					  ht_cap_offset);
+
+			if (adapter->scan_table[del_idx].bcn_ht_info)
+				adapter->scan_table[del_idx].bcn_ht_info =
+					(struct ieee80211_ht_info *)
+					(adapter->scan_table[del_idx].beacon_buf
+					 + adapter->scan_table[del_idx].
+					  ht_info_offset);
+			if (adapter->scan_table[del_idx].bcn_bss_co_2040)
+				adapter->scan_table[del_idx].bcn_bss_co_2040 =
+					(u8 *)
+					(adapter->scan_table[del_idx].beacon_buf
+					 + adapter->scan_table[del_idx].
+					   bss_co_2040_offset);
+			if (adapter->scan_table[del_idx].bcn_ext_cap)
+				adapter->scan_table[del_idx].bcn_ext_cap =
+					(u8 *)
+					(adapter->scan_table[del_idx].beacon_buf
+					 + adapter->scan_table[del_idx].
+					     ext_cap_offset);
+			if (adapter->scan_table[del_idx].bcn_obss_scan)
+				adapter->scan_table[del_idx].
+					bcn_obss_scan =
+					(struct ieee_types_obss_scan_param *)
+					(adapter->scan_table[del_idx].beacon_buf
+					 + adapter->scan_table[del_idx].
+					     overlap_bss_offset);
+		}
+	}
+
+	/* The last entry is invalid now that it has been deleted or moved
+	   back */
+	memset(adapter->scan_table + adapter->num_in_scan_table - 1,
+	       0x00, sizeof(struct mwifiex_bssdescriptor));
+
+	adapter->num_in_scan_table--;
+}
+
+/*
+ * This function deletes all occurrences of a given SSID from the scan table.
+ *
+ * This iterates through the scan table and deletes all entries that match
+ * the given SSID. It also compacts the remaining scan table entries.
+ */
+static int
+mwifiex_scan_delete_ssid_table_entry(struct mwifiex_private *priv,
+				     struct mwifiex_802_11_ssid *del_ssid)
+{
+	s32 table_idx = -1;
+
+	dev_dbg(priv->adapter->dev, "info: scan: delete ssid entry: %-32s\n",
+			del_ssid->ssid);
+
+	/* If the requested SSID is found in the table, delete it.  Then keep
+	   searching the table for multiple entires for the SSID until no
+	   more are found */
+	while ((table_idx = mwifiex_find_ssid_in_list(priv, del_ssid, NULL,
+					NL80211_IFTYPE_UNSPECIFIED)) >= 0) {
+		dev_dbg(priv->adapter->dev,
+			"info: Scan: Delete SSID Entry: Found Idx = %d\n",
+		       table_idx);
+		mwifiex_scan_delete_table_entry(priv, table_idx);
+	}
+
+	return table_idx == -1 ? -1 : 0;
+}
+
+/*
+ * This is an internal function used to start a scan based on an input
+ * configuration.
+ *
+ * This uses the input user scan configuration information when provided in
+ * order to send the appropriate scan commands to firmware to populate or
+ * update the internal driver scan table.
+ */
+int mwifiex_scan_networks(struct mwifiex_private *priv,
+			  const struct mwifiex_user_scan_cfg *user_scan_in)
+{
+	int ret = 0;
+	struct mwifiex_adapter *adapter = priv->adapter;
+	struct cmd_ctrl_node *cmd_node;
+	union mwifiex_scan_cmd_config_tlv *scan_cfg_out;
+	struct mwifiex_ie_types_chan_list_param_set *chan_list_out;
+	u32 buf_size;
+	struct mwifiex_chan_scan_param_set *scan_chan_list;
+	u8 keep_previous_scan;
+	u8 filtered_scan;
+	u8 scan_current_chan_only;
+	u8 max_chan_per_scan;
+	unsigned long flags;
+
+	if (adapter->scan_processing) {
+		dev_dbg(adapter->dev, "cmd: Scan already in process...\n");
+		return ret;
+	}
+
+	spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags);
+	adapter->scan_processing = true;
+	spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags);
+
+	if (priv->scan_block) {
+		dev_dbg(adapter->dev,
+			"cmd: Scan is blocked during association...\n");
+		return ret;
+	}
+
+	scan_cfg_out = kzalloc(sizeof(union mwifiex_scan_cmd_config_tlv),
+					GFP_KERNEL);
+	if (!scan_cfg_out) {
+		dev_err(adapter->dev, "failed to alloc scan_cfg_out\n");
+		return -ENOMEM;
+	}
+
+	buf_size = sizeof(struct mwifiex_chan_scan_param_set) *
+			MWIFIEX_USER_SCAN_CHAN_MAX;
+	scan_chan_list = kzalloc(buf_size, GFP_KERNEL);
+	if (!scan_chan_list) {
+		dev_err(adapter->dev, "failed to alloc scan_chan_list\n");
+		kfree(scan_cfg_out);
+		return -ENOMEM;
+	}
+
+	keep_previous_scan = false;
+
+	mwifiex_scan_setup_scan_config(priv, user_scan_in,
+				       &scan_cfg_out->config, &chan_list_out,
+				       scan_chan_list, &max_chan_per_scan,
+				       &filtered_scan, &scan_current_chan_only);
+
+	if (user_scan_in)
+		keep_previous_scan = user_scan_in->keep_previous_scan;
+
+
+	if (!keep_previous_scan) {
+		memset(adapter->scan_table, 0x00,
+		       sizeof(struct mwifiex_bssdescriptor) * IW_MAX_AP);
+		adapter->num_in_scan_table = 0;
+		adapter->bcn_buf_end = adapter->bcn_buf;
+	}
+
+	ret = mwifiex_scan_channel_list(priv, max_chan_per_scan, filtered_scan,
+					&scan_cfg_out->config, chan_list_out,
+					scan_chan_list);
+
+	/* Get scan command from scan_pending_q and put to cmd_pending_q */
+	if (!ret) {
+		spin_lock_irqsave(&adapter->scan_pending_q_lock, flags);
+		if (!list_empty(&adapter->scan_pending_q)) {
+			cmd_node = list_first_entry(&adapter->scan_pending_q,
+						struct cmd_ctrl_node, list);
+			list_del(&cmd_node->list);
+			spin_unlock_irqrestore(&adapter->scan_pending_q_lock,
+									flags);
+			mwifiex_insert_cmd_to_pending_q(adapter, cmd_node,
+							true);
+		} else {
+			spin_unlock_irqrestore(&adapter->scan_pending_q_lock,
+					       flags);
+		}
+	} else {
+		spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags);
+		adapter->scan_processing = true;
+		spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags);
+	}
+
+	kfree(scan_cfg_out);
+	kfree(scan_chan_list);
+	return ret;
+}
+
+/*
+ * This function prepares a scan command to be sent to the firmware.
+ *
+ * This uses the scan command configuration sent to the command processing
+ * module in command preparation stage to configure a scan command structure
+ * to send to firmware.
+ *
+ * The fixed fields specifying the BSS type and BSSID filters as well as a
+ * variable number/length of TLVs are sent in the command to firmware.
+ *
+ * Preparation also includes -
+ *      - Setting command ID, and proper size
+ *      - Ensuring correct endian-ness
+ */
+int mwifiex_cmd_802_11_scan(struct host_cmd_ds_command *cmd, void *data_buf)
+{
+	struct host_cmd_ds_802_11_scan *scan_cmd = &cmd->params.scan;
+	struct mwifiex_scan_cmd_config *scan_cfg;
+
+	scan_cfg = (struct mwifiex_scan_cmd_config *) data_buf;
+
+	/* Set fixed field variables in scan command */
+	scan_cmd->bss_mode = scan_cfg->bss_mode;
+	memcpy(scan_cmd->bssid, scan_cfg->specific_bssid,
+	       sizeof(scan_cmd->bssid));
+	memcpy(scan_cmd->tlv_buffer, scan_cfg->tlv_buf, scan_cfg->tlv_buf_len);
+
+	cmd->command = cpu_to_le16(HostCmd_CMD_802_11_SCAN);
+
+	/* Size is equal to the sizeof(fixed portions) + the TLV len + header */
+	cmd->size = cpu_to_le16((u16) (sizeof(scan_cmd->bss_mode)
+					  + sizeof(scan_cmd->bssid)
+					  + scan_cfg->tlv_buf_len + S_DS_GEN));
+
+	return 0;
+}
+
+/*
+ * This function handles the command response of scan.
+ *
+ * The response buffer for the scan command has the following
+ * memory layout:
+ *
+ *      .-------------------------------------------------------------.
+ *      |  Header (4 * sizeof(t_u16)):  Standard command response hdr |
+ *      .-------------------------------------------------------------.
+ *      |  BufSize (t_u16) : sizeof the BSS Description data          |
+ *      .-------------------------------------------------------------.
+ *      |  NumOfSet (t_u8) : Number of BSS Descs returned             |
+ *      .-------------------------------------------------------------.
+ *      |  BSSDescription data (variable, size given in BufSize)      |
+ *      .-------------------------------------------------------------.
+ *      |  TLV data (variable, size calculated using Header->Size,    |
+ *      |            BufSize and sizeof the fixed fields above)       |
+ *      .-------------------------------------------------------------.
+ */
+int mwifiex_ret_802_11_scan(struct mwifiex_private *priv,
+			    struct host_cmd_ds_command *resp)
+{
+	int ret = 0;
+	struct mwifiex_adapter *adapter = priv->adapter;
+	struct cmd_ctrl_node *cmd_node;
+	struct host_cmd_ds_802_11_scan_rsp *scan_rsp;
+	struct mwifiex_bssdescriptor *bss_new_entry = NULL;
+	struct mwifiex_ie_types_data *tlv_data;
+	struct mwifiex_ie_types_tsf_timestamp *tsf_tlv;
+	u8 *bss_info;
+	u32 scan_resp_size;
+	u32 bytes_left;
+	u32 num_in_table;
+	u32 bss_idx;
+	u32 idx;
+	u32 tlv_buf_size;
+	long long tsf_val;
+	struct mwifiex_chan_freq_power *cfp;
+	struct mwifiex_ie_types_chan_band_list_param_set *chan_band_tlv;
+	struct chan_band_param_set *chan_band;
+	u8 band;
+	u8 is_bgscan_resp;
+	unsigned long flags;
+
+	is_bgscan_resp = (le16_to_cpu(resp->command)
+		== HostCmd_CMD_802_11_BG_SCAN_QUERY);
+	if (is_bgscan_resp)
+		scan_rsp = &resp->params.bg_scan_query_resp.scan_resp;
+	else
+		scan_rsp = &resp->params.scan_resp;
+
+
+	if (scan_rsp->number_of_sets > IW_MAX_AP) {
+		dev_err(adapter->dev, "SCAN_RESP: too many AP returned (%d)\n",
+		       scan_rsp->number_of_sets);
+		ret = -1;
+		goto done;
+	}
+
+	bytes_left = le16_to_cpu(scan_rsp->bss_descript_size);
+	dev_dbg(adapter->dev, "info: SCAN_RESP: bss_descript_size %d\n",
+						bytes_left);
+
+	scan_resp_size = le16_to_cpu(resp->size);
+
+	dev_dbg(adapter->dev,
+		"info: SCAN_RESP: returned %d APs before parsing\n",
+	       scan_rsp->number_of_sets);
+
+	num_in_table = adapter->num_in_scan_table;
+	bss_info = scan_rsp->bss_desc_and_tlv_buffer;
+
+	/*
+	 * The size of the TLV buffer is equal to the entire command response
+	 *   size (scan_resp_size) minus the fixed fields (sizeof()'s), the
+	 *   BSS Descriptions (bss_descript_size as bytesLef) and the command
+	 *   response header (S_DS_GEN)
+	 */
+	tlv_buf_size = scan_resp_size - (bytes_left
+					 + sizeof(scan_rsp->bss_descript_size)
+					 + sizeof(scan_rsp->number_of_sets)
+					 + S_DS_GEN);
+
+	tlv_data = (struct mwifiex_ie_types_data *) (scan_rsp->
+						 bss_desc_and_tlv_buffer +
+						 bytes_left);
+
+	/* Search the TLV buffer space in the scan response for any valid
+	   TLVs */
+	mwifiex_ret_802_11_scan_get_tlv_ptrs(adapter, tlv_data, tlv_buf_size,
+					     TLV_TYPE_TSFTIMESTAMP,
+					     (struct mwifiex_ie_types_data **)
+					     &tsf_tlv);
+
+	/* Search the TLV buffer space in the scan response for any valid
+	   TLVs */
+	mwifiex_ret_802_11_scan_get_tlv_ptrs(adapter, tlv_data, tlv_buf_size,
+					     TLV_TYPE_CHANNELBANDLIST,
+					     (struct mwifiex_ie_types_data **)
+					     &chan_band_tlv);
+
+	/*
+	 *  Process each scan response returned (scan_rsp->number_of_sets).
+	 *  Save the information in the bss_new_entry and then insert into the
+	 *  driver scan table either as an update to an existing entry
+	 *  or as an addition at the end of the table
+	 */
+	bss_new_entry = kzalloc(sizeof(struct mwifiex_bssdescriptor),
+				GFP_KERNEL);
+	if (!bss_new_entry) {
+		dev_err(adapter->dev, " failed to alloc bss_new_entry\n");
+		return -ENOMEM;
+	}
+
+	for (idx = 0; idx < scan_rsp->number_of_sets && bytes_left; idx++) {
+		/* Zero out the bss_new_entry we are about to store info in */
+		memset(bss_new_entry, 0x00,
+		       sizeof(struct mwifiex_bssdescriptor));
+
+		if (mwifiex_interpret_bss_desc_with_ie(adapter, bss_new_entry,
+							&bss_info,
+							&bytes_left)) {
+			/* Error parsing/interpreting scan response, skipped */
+			dev_err(adapter->dev, "SCAN_RESP: "
+			       "mwifiex_interpret_bss_desc_with_ie "
+			       "returned ERROR\n");
+			continue;
+		}
+
+		/* Process the data fields and IEs returned for this BSS */
+		dev_dbg(adapter->dev, "info: SCAN_RESP: BSSID = %pM\n",
+		       bss_new_entry->mac_address);
+
+		/* Search the scan table for the same bssid */
+		for (bss_idx = 0; bss_idx < num_in_table; bss_idx++) {
+			if (memcmp(bss_new_entry->mac_address,
+				adapter->scan_table[bss_idx].mac_address,
+				sizeof(bss_new_entry->mac_address))) {
+				continue;
+			}
+			/*
+			 * If the SSID matches as well, it is a
+			 * duplicate of this entry.  Keep the bss_idx
+			 * set to this entry so we replace the old
+			 * contents in the table
+			 */
+			if ((bss_new_entry->ssid.ssid_len
+				== adapter->scan_table[bss_idx]. ssid.ssid_len)
+					&& (!memcmp(bss_new_entry->ssid.ssid,
+					adapter->scan_table[bss_idx].ssid.ssid,
+					bss_new_entry->ssid.ssid_len))) {
+				dev_dbg(adapter->dev, "info: SCAN_RESP:"
+					" duplicate of index: %d\n", bss_idx);
+				break;
+			}
+		}
+		/*
+		 * If the bss_idx is equal to the number of entries in
+		 * the table, the new entry was not a duplicate; append
+		 * it to the scan table
+		 */
+		if (bss_idx == num_in_table) {
+			/* Range check the bss_idx, keep it limited to
+			   the last entry */
+			if (bss_idx == IW_MAX_AP)
+				bss_idx--;
+			else
+				num_in_table++;
+		}
+
+		/*
+		 * Save the beacon/probe response returned for later application
+		 * retrieval.  Duplicate beacon/probe responses are updated if
+		 * possible
+		 */
+		mwifiex_ret_802_11_scan_store_beacon(priv, bss_idx,
+						num_in_table, bss_new_entry);
+		/*
+		 * If the TSF TLV was appended to the scan results, save this
+		 * entry's TSF value in the networkTSF field.The networkTSF is
+		 * the firmware's TSF value at the time the beacon or probe
+		 * response was received.
+		 */
+		if (tsf_tlv) {
+			memcpy(&tsf_val, &tsf_tlv->tsf_data[idx * TSF_DATA_SIZE]
+					, sizeof(tsf_val));
+			memcpy(&bss_new_entry->network_tsf, &tsf_val,
+					sizeof(bss_new_entry->network_tsf));
+		}
+		band = BAND_G;
+		if (chan_band_tlv) {
+			chan_band = &chan_band_tlv->chan_band_param[idx];
+			band = mwifiex_radio_type_to_band(chan_band->radio_type
+					& (BIT(0) | BIT(1)));
+		}
+
+		/* Save the band designation for this entry for use in join */
+		bss_new_entry->bss_band = band;
+		cfp = mwifiex_get_cfp_by_band_and_channel_from_cfg80211(priv,
+					(u8) bss_new_entry->bss_band,
+					(u16)bss_new_entry->channel);
+
+		if (cfp)
+			bss_new_entry->freq = cfp->freq;
+		else
+			bss_new_entry->freq = 0;
+
+		/* Copy the locally created bss_new_entry to the scan table */
+		memcpy(&adapter->scan_table[bss_idx], bss_new_entry,
+		       sizeof(adapter->scan_table[bss_idx]));
+
+	}
+
+	dev_dbg(adapter->dev,
+		"info: SCAN_RESP: Scanned %2d APs, %d valid, %d total\n",
+	       scan_rsp->number_of_sets,
+	       num_in_table - adapter->num_in_scan_table, num_in_table);
+
+	/* Update the total number of BSSIDs in the scan table */
+	adapter->num_in_scan_table = num_in_table;
+
+	spin_lock_irqsave(&adapter->scan_pending_q_lock, flags);
+	if (list_empty(&adapter->scan_pending_q)) {
+		spin_unlock_irqrestore(&adapter->scan_pending_q_lock, flags);
+		spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags);
+		adapter->scan_processing = false;
+		spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags);
+		/*
+		 * Process the resulting scan table:
+		 *   - Remove any bad ssids
+		 *   - Update our current BSS information from scan data
+		 */
+		mwifiex_process_scan_results(priv);
+
+		/* Need to indicate IOCTL complete */
+		if (adapter->curr_cmd->wait_q_enabled) {
+			adapter->cmd_wait_q.status = 0;
+			mwifiex_complete_cmd(adapter);
+		}
+		if (priv->report_scan_result)
+			priv->report_scan_result = false;
+		if (priv->scan_pending_on_block) {
+			priv->scan_pending_on_block = false;
+			up(&priv->async_sem);
+		}
+
+	} else {
+		/* Get scan command from scan_pending_q and put to
+		   cmd_pending_q */
+		cmd_node = list_first_entry(&adapter->scan_pending_q,
+					    struct cmd_ctrl_node, list);
+		list_del(&cmd_node->list);
+		spin_unlock_irqrestore(&adapter->scan_pending_q_lock, flags);
+
+		mwifiex_insert_cmd_to_pending_q(adapter, cmd_node, true);
+	}
+
+done:
+	kfree((u8 *) bss_new_entry);
+	return ret;
+}
+
+/*
+ * This function prepares command for background scan query.
+ *
+ * Preparation includes -
+ *      - Setting command ID and proper size
+ *      - Setting background scan flush parameter
+ *      - Ensuring correct endian-ness
+ */
+int mwifiex_cmd_802_11_bg_scan_query(struct host_cmd_ds_command *cmd)
+{
+	struct host_cmd_ds_802_11_bg_scan_query *bg_query =
+		&cmd->params.bg_scan_query;
+
+	cmd->command = cpu_to_le16(HostCmd_CMD_802_11_BG_SCAN_QUERY);
+	cmd->size = cpu_to_le16(sizeof(struct host_cmd_ds_802_11_bg_scan_query)
+				+ S_DS_GEN);
+
+	bg_query->flush = 1;
+
+	return 0;
+}
+
+/*
+ * This function finds a SSID in the scan table.
+ *
+ * A BSSID may optionally be provided to qualify the SSID.
+ * For non-Auto mode, further check is made to make sure the
+ * BSS found in the scan table is compatible with the current
+ * settings of the driver.
+ */
+s32
+mwifiex_find_ssid_in_list(struct mwifiex_private *priv,
+			  struct mwifiex_802_11_ssid *ssid, u8 *bssid,
+			  u32 mode)
+{
+	struct mwifiex_adapter *adapter = priv->adapter;
+	s32 net = -1, j;
+	u8 best_rssi = 0;
+	u32 i;
+
+	dev_dbg(adapter->dev, "info: num of entries in table = %d\n",
+	       adapter->num_in_scan_table);
+
+	/*
+	 * Loop through the table until the maximum is reached or until a match
+	 *   is found based on the bssid field comparison
+	 */
+	for (i = 0;
+	     i < adapter->num_in_scan_table && (!bssid || (bssid && net < 0));
+	     i++) {
+		if (!mwifiex_ssid_cmp(&adapter->scan_table[i].ssid, ssid) &&
+		    (!bssid
+		     || !memcmp(adapter->scan_table[i].mac_address, bssid,
+				ETH_ALEN))
+		    &&
+		    (mwifiex_get_cfp_by_band_and_channel_from_cfg80211
+		     (priv, (u8) adapter->scan_table[i].bss_band,
+		      (u16) adapter->scan_table[i].channel))) {
+			switch (mode) {
+			case NL80211_IFTYPE_STATION:
+			case NL80211_IFTYPE_ADHOC:
+				j = mwifiex_is_network_compatible(priv, i,
+								  mode);
+
+				if (j >= 0) {
+					if (SCAN_RSSI
+					    (adapter->scan_table[i].rssi) >
+					    best_rssi) {
+						best_rssi = SCAN_RSSI(adapter->
+								  scan_table
+								  [i].rssi);
+						net = i;
+					}
+				} else {
+					if (net == -1)
+						net = j;
+				}
+				break;
+			case NL80211_IFTYPE_UNSPECIFIED:
+			default:
+				/*
+				 * Do not check compatibility if the mode
+				 * requested is Auto/Unknown.  Allows generic
+				 * find to work without verifying against the
+				 * Adapter security settings
+				 */
+				if (SCAN_RSSI(adapter->scan_table[i].rssi) >
+				    best_rssi) {
+					best_rssi = SCAN_RSSI(adapter->
+							  scan_table[i].rssi);
+					net = i;
+				}
+				break;
+			}
+		}
+	}
+
+	return net;
+}
+
+/*
+ * This function finds a specific compatible BSSID in the scan list.
+ *
+ * This function loops through the scan table looking for a compatible
+ * match. If a BSSID matches, but the BSS is found to be not compatible
+ * the function ignores it and continues to search through the rest of
+ * the entries in case there is an AP with multiple SSIDs assigned to
+ * the same BSSID.
+ */
+s32
+mwifiex_find_bssid_in_list(struct mwifiex_private *priv, u8 *bssid,
+			   u32 mode)
+{
+	struct mwifiex_adapter *adapter = priv->adapter;
+	s32 net = -1;
+	u32 i;
+
+	if (!bssid)
+		return -1;
+
+	dev_dbg(adapter->dev, "info: FindBSSID: Num of BSSIDs = %d\n",
+	       adapter->num_in_scan_table);
+
+	/*
+	 * Look through the scan table for a compatible match. The ret return
+	 *   variable will be equal to the index in the scan table (greater
+	 *   than zero) if the network is compatible.  The loop will continue
+	 *   past a matched bssid that is not compatible in case there is an
+	 *   AP with multiple SSIDs assigned to the same BSSID
+	 */
+	for (i = 0; net < 0 && i < adapter->num_in_scan_table; i++) {
+		if (!memcmp
+		    (adapter->scan_table[i].mac_address, bssid, ETH_ALEN)
+			&& mwifiex_get_cfp_by_band_and_channel_from_cfg80211
+								(priv,
+							    (u8) adapter->
+							    scan_table[i].
+							    bss_band,
+							    (u16) adapter->
+							    scan_table[i].
+							    channel)) {
+			switch (mode) {
+			case NL80211_IFTYPE_STATION:
+			case NL80211_IFTYPE_ADHOC:
+				net = mwifiex_is_network_compatible(priv, i,
+								    mode);
+				break;
+			default:
+				net = i;
+				break;
+			}
+		}
+	}
+
+	return net;
+}
+
+/*
+ * This function inserts scan command node to the scan pending queue.
+ */
+void
+mwifiex_queue_scan_cmd(struct mwifiex_private *priv,
+		       struct cmd_ctrl_node *cmd_node)
+{
+	struct mwifiex_adapter *adapter = priv->adapter;
+	unsigned long flags;
+
+	cmd_node->wait_q_enabled = true;
+	spin_lock_irqsave(&adapter->scan_pending_q_lock, flags);
+	list_add_tail(&cmd_node->list, &adapter->scan_pending_q);
+	spin_unlock_irqrestore(&adapter->scan_pending_q_lock, flags);
+}
+
+/*
+ * This function finds an AP with specific ssid in the scan list.
+ */
+int mwifiex_find_best_network(struct mwifiex_private *priv,
+			      struct mwifiex_ssid_bssid *req_ssid_bssid)
+{
+	struct mwifiex_adapter *adapter = priv->adapter;
+	struct mwifiex_bssdescriptor *req_bss;
+	s32 i;
+
+	memset(req_ssid_bssid, 0, sizeof(struct mwifiex_ssid_bssid));
+
+	i = mwifiex_find_best_network_in_list(priv);
+
+	if (i >= 0) {
+		req_bss = &adapter->scan_table[i];
+		memcpy(&req_ssid_bssid->ssid, &req_bss->ssid,
+		       sizeof(struct mwifiex_802_11_ssid));
+		memcpy((u8 *) &req_ssid_bssid->bssid,
+		       (u8 *) &req_bss->mac_address, ETH_ALEN);
+
+		/* Make sure we are in the right mode */
+		if (priv->bss_mode == NL80211_IFTYPE_UNSPECIFIED)
+			priv->bss_mode = req_bss->bss_mode;
+	}
+
+	if (!req_ssid_bssid->ssid.ssid_len)
+		return -1;
+
+	dev_dbg(adapter->dev, "info: Best network found = [%s], "
+	       "[%pM]\n", req_ssid_bssid->ssid.ssid,
+	       req_ssid_bssid->bssid);
+
+	return 0;
+}
+
+/*
+ * This function sends a scan command for all available channels to the
+ * firmware, filtered on a specific SSID.
+ */
+static int mwifiex_scan_specific_ssid(struct mwifiex_private *priv,
+				      struct mwifiex_802_11_ssid *req_ssid)
+{
+	struct mwifiex_adapter *adapter = priv->adapter;
+	int ret = 0;
+	struct mwifiex_user_scan_cfg *scan_cfg;
+
+	if (!req_ssid)
+		return -1;
+
+	if (adapter->scan_processing) {
+		dev_dbg(adapter->dev, "cmd: Scan already in process...\n");
+		return ret;
+	}
+
+	if (priv->scan_block) {
+		dev_dbg(adapter->dev,
+			"cmd: Scan is blocked during association...\n");
+		return ret;
+	}
+
+	mwifiex_scan_delete_ssid_table_entry(priv, req_ssid);
+
+	scan_cfg = kzalloc(sizeof(struct mwifiex_user_scan_cfg), GFP_KERNEL);
+	if (!scan_cfg) {
+		dev_err(adapter->dev, "failed to alloc scan_cfg\n");
+		return -ENOMEM;
+	}
+
+	memcpy(scan_cfg->ssid_list[0].ssid, req_ssid->ssid,
+	       req_ssid->ssid_len);
+	scan_cfg->keep_previous_scan = true;
+
+	ret = mwifiex_scan_networks(priv, scan_cfg);
+
+	kfree(scan_cfg);
+	return ret;
+}
+
+/*
+ * Sends IOCTL request to start a scan.
+ *
+ * This function allocates the IOCTL request buffer, fills it
+ * with requisite parameters and calls the IOCTL handler.
+ *
+ * Scan command can be issued for both normal scan and specific SSID
+ * scan, depending upon whether an SSID is provided or not.
+ */
+int mwifiex_request_scan(struct mwifiex_private *priv,
+			 struct mwifiex_802_11_ssid *req_ssid)
+{
+	int ret;
+
+	if (down_interruptible(&priv->async_sem)) {
+		dev_err(priv->adapter->dev, "%s: acquire semaphore\n",
+						__func__);
+		return -1;
+	}
+	priv->scan_pending_on_block = true;
+
+	priv->adapter->cmd_wait_q.condition = false;
+
+	if (req_ssid && req_ssid->ssid_len != 0)
+		/* Specific SSID scan */
+		ret = mwifiex_scan_specific_ssid(priv, req_ssid);
+	else
+		/* Normal scan */
+		ret = mwifiex_scan_networks(priv, NULL);
+
+	if (!ret)
+		ret = mwifiex_wait_queue_complete(priv->adapter);
+
+	if (ret == -1) {
+		priv->scan_pending_on_block = false;
+		up(&priv->async_sem);
+	}
+
+	return ret;
+}
+
+/*
+ * This function appends the vendor specific IE TLV to a buffer.
+ */
+int
+mwifiex_cmd_append_vsie_tlv(struct mwifiex_private *priv,
+			    u16 vsie_mask, u8 **buffer)
+{
+	int id, ret_len = 0;
+	struct mwifiex_ie_types_vendor_param_set *vs_param_set;
+
+	if (!buffer)
+		return 0;
+	if (!(*buffer))
+		return 0;
+
+	/*
+	 * Traverse through the saved vendor specific IE array and append
+	 * the selected(scan/assoc/adhoc) IE as TLV to the command
+	 */
+	for (id = 0; id < MWIFIEX_MAX_VSIE_NUM; id++) {
+		if (priv->vs_ie[id].mask & vsie_mask) {
+			vs_param_set =
+				(struct mwifiex_ie_types_vendor_param_set *)
+				*buffer;
+			vs_param_set->header.type =
+				cpu_to_le16(TLV_TYPE_PASSTHROUGH);
+			vs_param_set->header.len =
+				cpu_to_le16((((u16) priv->vs_ie[id].ie[1])
+				& 0x00FF) + 2);
+			memcpy(vs_param_set->ie, priv->vs_ie[id].ie,
+			       le16_to_cpu(vs_param_set->header.len));
+			*buffer += le16_to_cpu(vs_param_set->header.len) +
+				   sizeof(struct mwifiex_ie_types_header);
+			ret_len += le16_to_cpu(vs_param_set->header.len) +
+				   sizeof(struct mwifiex_ie_types_header);
+		}
+	}
+	return ret_len;
+}
+
+/*
+ * This function saves a beacon buffer of the current BSS descriptor.
+ *
+ * The current beacon buffer is saved so that it can be restored in the
+ * following cases that makes the beacon buffer not to contain the current
+ * ssid's beacon buffer.
+ *      - The current ssid was not found somehow in the last scan.
+ *      - The current ssid was the last entry of the scan table and overloaded.
+ */
+void
+mwifiex_save_curr_bcn(struct mwifiex_private *priv)
+{
+	struct mwifiex_bssdescriptor *curr_bss =
+		&priv->curr_bss_params.bss_descriptor;
+
+	if (!curr_bss->beacon_buf_size)
+		return;
+
+	/* allocate beacon buffer at 1st time; or if it's size has changed */
+	if (!priv->curr_bcn_buf ||
+			priv->curr_bcn_size != curr_bss->beacon_buf_size) {
+		priv->curr_bcn_size = curr_bss->beacon_buf_size;
+
+		kfree(priv->curr_bcn_buf);
+		priv->curr_bcn_buf = kzalloc(curr_bss->beacon_buf_size,
+						GFP_KERNEL);
+		if (!priv->curr_bcn_buf) {
+			dev_err(priv->adapter->dev,
+					"failed to alloc curr_bcn_buf\n");
+			return;
+		}
+	}
+
+	memcpy(priv->curr_bcn_buf, curr_bss->beacon_buf,
+		curr_bss->beacon_buf_size);
+	dev_dbg(priv->adapter->dev, "info: current beacon saved %d\n",
+		priv->curr_bcn_size);
+}
+
+/*
+ * This function frees the current BSS descriptor beacon buffer.
+ */
+void
+mwifiex_free_curr_bcn(struct mwifiex_private *priv)
+{
+	kfree(priv->curr_bcn_buf);
+	priv->curr_bcn_buf = NULL;
+}
diff -druN linux-2.6.39-libre/drivers/net/wireless/mwifiex/sdio.c linux-3.0-rc7-libre/drivers/net/wireless/mwifiex/sdio.c
--- linux-2.6.39-libre/drivers/net/wireless/mwifiex/sdio.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/net/wireless/mwifiex/sdio.c	2011-07-21 06:57:22.000000000 -0400
@@ -0,0 +1,1754 @@
+/*
+ * Marvell Wireless LAN device driver: SDIO specific handling
+ *
+ * Copyright (C) 2011, Marvell International Ltd.
+ *
+ * This software file (the "File") is distributed by Marvell International
+ * Ltd. under the terms of the GNU General Public License Version 2, June 1991
+ * (the "License").  You may use, redistribute and/or modify this File in
+ * accordance with the terms and conditions of the License, a copy of which
+ * is available by writing to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
+ * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
+ *
+ * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
+ * ARE EXPRESSLY DISCLAIMED.  The License provides additional details about
+ * this warranty disclaimer.
+ */
+
+#include <linux/firmware.h>
+
+#include "decl.h"
+#include "ioctl.h"
+#include "util.h"
+#include "fw.h"
+#include "main.h"
+#include "wmm.h"
+#include "11n.h"
+#include "sdio.h"
+
+
+#define SDIO_VERSION	"1.0"
+
+static struct mwifiex_if_ops sdio_ops;
+
+static struct semaphore add_remove_card_sem;
+
+/*
+ * SDIO probe.
+ *
+ * This function probes an mwifiex device and registers it. It allocates
+ * the card structure, enables SDIO function number and initiates the
+ * device registration and initialization procedure by adding a logical
+ * interface.
+ */
+static int
+mwifiex_sdio_probe(struct sdio_func *func, const struct sdio_device_id *id)
+{
+	int ret;
+	struct sdio_mmc_card *card = NULL;
+
+	pr_debug("info: vendor=0x%4.04X device=0x%4.04X class=%d function=%d\n",
+	       func->vendor, func->device, func->class, func->num);
+
+	card = kzalloc(sizeof(struct sdio_mmc_card), GFP_KERNEL);
+	if (!card) {
+		pr_err("%s: failed to alloc memory\n", __func__);
+		return -ENOMEM;
+	}
+
+	card->func = func;
+
+	func->card->quirks |= MMC_QUIRK_BLKSZ_FOR_BYTE_MODE;
+
+	sdio_claim_host(func);
+	ret = sdio_enable_func(func);
+	sdio_release_host(func);
+
+	if (ret) {
+		pr_err("%s: failed to enable function\n", __func__);
+		kfree(card);
+		return -EIO;
+	}
+
+	if (mwifiex_add_card(card, &add_remove_card_sem, &sdio_ops)) {
+		pr_err("%s: add card failed\n", __func__);
+		kfree(card);
+		sdio_claim_host(func);
+		ret = sdio_disable_func(func);
+		sdio_release_host(func);
+		ret = -1;
+	}
+
+	return ret;
+}
+
+/*
+ * SDIO remove.
+ *
+ * This function removes the interface and frees up the card structure.
+ */
+static void
+mwifiex_sdio_remove(struct sdio_func *func)
+{
+	struct sdio_mmc_card *card;
+
+	pr_debug("info: SDIO func num=%d\n", func->num);
+
+	if (func) {
+		card = sdio_get_drvdata(func);
+		if (card) {
+			mwifiex_remove_card(card->adapter,
+					&add_remove_card_sem);
+			kfree(card);
+		}
+	}
+}
+
+/*
+ * SDIO suspend.
+ *
+ * Kernel needs to suspend all functions separately. Therefore all
+ * registered functions must have drivers with suspend and resume
+ * methods. Failing that the kernel simply removes the whole card.
+ *
+ * If already not suspended, this function allocates and sends a host
+ * sleep activate request to the firmware and turns off the traffic.
+ */
+static int mwifiex_sdio_suspend(struct device *dev)
+{
+	struct sdio_func *func = dev_to_sdio_func(dev);
+	struct sdio_mmc_card *card;
+	struct mwifiex_adapter *adapter;
+	mmc_pm_flag_t pm_flag = 0;
+	int hs_actived = 0;
+	int i;
+	int ret = 0;
+
+	if (func) {
+		pm_flag = sdio_get_host_pm_caps(func);
+		pr_debug("cmd: %s: suspend: PM flag = 0x%x\n",
+		       sdio_func_id(func), pm_flag);
+		if (!(pm_flag & MMC_PM_KEEP_POWER)) {
+			pr_err("%s: cannot remain alive while host is"
+				" suspended\n", sdio_func_id(func));
+			return -ENOSYS;
+		}
+
+		card = sdio_get_drvdata(func);
+		if (!card || !card->adapter) {
+			pr_err("suspend: invalid card or adapter\n");
+			return 0;
+		}
+	} else {
+		pr_err("suspend: sdio_func is not specified\n");
+		return 0;
+	}
+
+	adapter = card->adapter;
+
+	/* Enable the Host Sleep */
+	hs_actived = mwifiex_enable_hs(adapter);
+	if (hs_actived) {
+		pr_debug("cmd: suspend with MMC_PM_KEEP_POWER\n");
+		ret = sdio_set_host_pm_flags(func, MMC_PM_KEEP_POWER);
+	}
+
+	/* Indicate device suspended */
+	adapter->is_suspended = true;
+
+	for (i = 0; i < adapter->priv_num; i++)
+		netif_carrier_off(adapter->priv[i]->netdev);
+
+	return ret;
+}
+
+/*
+ * SDIO resume.
+ *
+ * Kernel needs to suspend all functions separately. Therefore all
+ * registered functions must have drivers with suspend and resume
+ * methods. Failing that the kernel simply removes the whole card.
+ *
+ * If already not resumed, this function turns on the traffic and
+ * sends a host sleep cancel request to the firmware.
+ */
+static int mwifiex_sdio_resume(struct device *dev)
+{
+	struct sdio_func *func = dev_to_sdio_func(dev);
+	struct sdio_mmc_card *card;
+	struct mwifiex_adapter *adapter;
+	mmc_pm_flag_t pm_flag = 0;
+	int i;
+
+	if (func) {
+		pm_flag = sdio_get_host_pm_caps(func);
+		card = sdio_get_drvdata(func);
+		if (!card || !card->adapter) {
+			pr_err("resume: invalid card or adapter\n");
+			return 0;
+		}
+	} else {
+		pr_err("resume: sdio_func is not specified\n");
+		return 0;
+	}
+
+	adapter = card->adapter;
+
+	if (!adapter->is_suspended) {
+		dev_warn(adapter->dev, "device already resumed\n");
+		return 0;
+	}
+
+	adapter->is_suspended = false;
+
+	for (i = 0; i < adapter->priv_num; i++)
+		if (adapter->priv[i]->media_connected)
+			netif_carrier_on(adapter->priv[i]->netdev);
+
+	/* Disable Host Sleep */
+	mwifiex_cancel_hs(mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_STA),
+			  MWIFIEX_ASYNC_CMD);
+
+	return 0;
+}
+
+/* Device ID for SD8787 */
+#define SDIO_DEVICE_ID_MARVELL_8787   (0x9119)
+
+/* WLAN IDs */
+static const struct sdio_device_id mwifiex_ids[] = {
+	{SDIO_DEVICE(SDIO_VENDOR_ID_MARVELL, SDIO_DEVICE_ID_MARVELL_8787)},
+	{},
+};
+
+MODULE_DEVICE_TABLE(sdio, mwifiex_ids);
+
+static const struct dev_pm_ops mwifiex_sdio_pm_ops = {
+	.suspend = mwifiex_sdio_suspend,
+	.resume = mwifiex_sdio_resume,
+};
+
+static struct sdio_driver mwifiex_sdio = {
+	.name = "mwifiex_sdio",
+	.id_table = mwifiex_ids,
+	.probe = mwifiex_sdio_probe,
+	.remove = mwifiex_sdio_remove,
+	.drv = {
+		.owner = THIS_MODULE,
+		.pm = &mwifiex_sdio_pm_ops,
+	}
+};
+
+/*
+ * This function writes data into SDIO card register.
+ */
+static int
+mwifiex_write_reg(struct mwifiex_adapter *adapter, u32 reg, u32 data)
+{
+	struct sdio_mmc_card *card = adapter->card;
+	int ret = -1;
+
+	sdio_claim_host(card->func);
+	sdio_writeb(card->func, (u8) data, reg, &ret);
+	sdio_release_host(card->func);
+
+	return ret;
+}
+
+/*
+ * This function reads data from SDIO card register.
+ */
+static int
+mwifiex_read_reg(struct mwifiex_adapter *adapter, u32 reg, u32 *data)
+{
+	struct sdio_mmc_card *card = adapter->card;
+	int ret = -1;
+	u8 val;
+
+	sdio_claim_host(card->func);
+	val = sdio_readb(card->func, reg, &ret);
+	sdio_release_host(card->func);
+
+	*data = val;
+
+	return ret;
+}
+
+/*
+ * This function writes multiple data into SDIO card memory.
+ *
+ * This does not work in suspended mode.
+ */
+static int
+mwifiex_write_data_sync(struct mwifiex_adapter *adapter,
+			u8 *buffer, u32 pkt_len, u32 port)
+{
+	struct sdio_mmc_card *card = adapter->card;
+	int ret = -1;
+	u8 blk_mode =
+		(port & MWIFIEX_SDIO_BYTE_MODE_MASK) ? BYTE_MODE : BLOCK_MODE;
+	u32 blk_size = (blk_mode == BLOCK_MODE) ? MWIFIEX_SDIO_BLOCK_SIZE : 1;
+	u32 blk_cnt =
+		(blk_mode ==
+		 BLOCK_MODE) ? (pkt_len /
+				MWIFIEX_SDIO_BLOCK_SIZE) : pkt_len;
+	u32 ioport = (port & MWIFIEX_SDIO_IO_PORT_MASK);
+
+	if (adapter->is_suspended) {
+		dev_err(adapter->dev,
+			"%s: not allowed while suspended\n", __func__);
+		return -1;
+	}
+
+	sdio_claim_host(card->func);
+
+	if (!sdio_writesb(card->func, ioport, buffer, blk_cnt * blk_size))
+		ret = 0;
+
+	sdio_release_host(card->func);
+
+	return ret;
+}
+
+/*
+ * This function reads multiple data from SDIO card memory.
+ */
+static int mwifiex_read_data_sync(struct mwifiex_adapter *adapter, u8 *buffer,
+				  u32 len, u32 port, u8 claim)
+{
+	struct sdio_mmc_card *card = adapter->card;
+	int ret = -1;
+	u8 blk_mode =
+		(port & MWIFIEX_SDIO_BYTE_MODE_MASK) ? BYTE_MODE : BLOCK_MODE;
+	u32 blk_size = (blk_mode == BLOCK_MODE) ? MWIFIEX_SDIO_BLOCK_SIZE : 1;
+	u32 blk_cnt =
+		(blk_mode ==
+		 BLOCK_MODE) ? (len / MWIFIEX_SDIO_BLOCK_SIZE) : len;
+	u32 ioport = (port & MWIFIEX_SDIO_IO_PORT_MASK);
+
+	if (claim)
+		sdio_claim_host(card->func);
+
+	if (!sdio_readsb(card->func, buffer, ioport, blk_cnt * blk_size))
+		ret = 0;
+
+	if (claim)
+		sdio_release_host(card->func);
+
+	return ret;
+}
+
+/*
+ * This function wakes up the card.
+ *
+ * A host power up command is written to the card configuration
+ * register to wake up the card.
+ */
+static int mwifiex_pm_wakeup_card(struct mwifiex_adapter *adapter)
+{
+	dev_dbg(adapter->dev, "event: wakeup device...\n");
+
+	return mwifiex_write_reg(adapter, CONFIGURATION_REG, HOST_POWER_UP);
+}
+
+/*
+ * This function is called after the card has woken up.
+ *
+ * The card configuration register is reset.
+ */
+static int mwifiex_pm_wakeup_card_complete(struct mwifiex_adapter *adapter)
+{
+	dev_dbg(adapter->dev, "cmd: wakeup device completed\n");
+
+	return mwifiex_write_reg(adapter, CONFIGURATION_REG, 0);
+}
+
+/*
+ * This function initializes the IO ports.
+ *
+ * The following operations are performed -
+ *      - Read the IO ports (0, 1 and 2)
+ *      - Set host interrupt Reset-To-Read to clear
+ *      - Set auto re-enable interrupt
+ */
+static int mwifiex_init_sdio_ioport(struct mwifiex_adapter *adapter)
+{
+	u32 reg;
+
+	adapter->ioport = 0;
+
+	/* Read the IO port */
+	if (!mwifiex_read_reg(adapter, IO_PORT_0_REG, &reg))
+		adapter->ioport |= (reg & 0xff);
+	else
+		return -1;
+
+	if (!mwifiex_read_reg(adapter, IO_PORT_1_REG, &reg))
+		adapter->ioport |= ((reg & 0xff) << 8);
+	else
+		return -1;
+
+	if (!mwifiex_read_reg(adapter, IO_PORT_2_REG, &reg))
+		adapter->ioport |= ((reg & 0xff) << 16);
+	else
+		return -1;
+
+	pr_debug("info: SDIO FUNC1 IO port: %#x\n", adapter->ioport);
+
+	/* Set Host interrupt reset to read to clear */
+	if (!mwifiex_read_reg(adapter, HOST_INT_RSR_REG, &reg))
+		mwifiex_write_reg(adapter, HOST_INT_RSR_REG,
+				  reg | SDIO_INT_MASK);
+	else
+		return -1;
+
+	/* Dnld/Upld ready set to auto reset */
+	if (!mwifiex_read_reg(adapter, CARD_MISC_CFG_REG, &reg))
+		mwifiex_write_reg(adapter, CARD_MISC_CFG_REG,
+				  reg | AUTO_RE_ENABLE_INT);
+	else
+		return -1;
+
+	return 0;
+}
+
+/*
+ * This function sends data to the card.
+ */
+static int mwifiex_write_data_to_card(struct mwifiex_adapter *adapter,
+				      u8 *payload, u32 pkt_len, u32 port)
+{
+	u32 i = 0;
+	int ret;
+
+	do {
+		ret = mwifiex_write_data_sync(adapter, payload, pkt_len, port);
+		if (ret) {
+			i++;
+			dev_err(adapter->dev, "host_to_card, write iomem"
+					" (%d) failed: %d\n", i, ret);
+			if (mwifiex_write_reg(adapter,
+					CONFIGURATION_REG, 0x04))
+				dev_err(adapter->dev, "write CFG reg failed\n");
+
+			ret = -1;
+			if (i > MAX_WRITE_IOMEM_RETRY)
+				return ret;
+		}
+	} while (ret == -1);
+
+	return ret;
+}
+
+/*
+ * This function gets the read port.
+ *
+ * If control port bit is set in MP read bitmap, the control port
+ * is returned, otherwise the current read port is returned and
+ * the value is increased (provided it does not reach the maximum
+ * limit, in which case it is reset to 1)
+ */
+static int mwifiex_get_rd_port(struct mwifiex_adapter *adapter, u8 *port)
+{
+	struct sdio_mmc_card *card = adapter->card;
+	u16 rd_bitmap = card->mp_rd_bitmap;
+
+	dev_dbg(adapter->dev, "data: mp_rd_bitmap=0x%04x\n", rd_bitmap);
+
+	if (!(rd_bitmap & (CTRL_PORT_MASK | DATA_PORT_MASK)))
+		return -1;
+
+	if (card->mp_rd_bitmap & CTRL_PORT_MASK) {
+		card->mp_rd_bitmap &= (u16) (~CTRL_PORT_MASK);
+		*port = CTRL_PORT;
+		dev_dbg(adapter->dev, "data: port=%d mp_rd_bitmap=0x%04x\n",
+		       *port, card->mp_rd_bitmap);
+	} else {
+		if (card->mp_rd_bitmap & (1 << card->curr_rd_port)) {
+			card->mp_rd_bitmap &=
+				(u16) (~(1 << card->curr_rd_port));
+			*port = card->curr_rd_port;
+
+			if (++card->curr_rd_port == MAX_PORT)
+				card->curr_rd_port = 1;
+		} else {
+			return -1;
+		}
+
+		dev_dbg(adapter->dev,
+			"data: port=%d mp_rd_bitmap=0x%04x -> 0x%04x\n",
+		       *port, rd_bitmap, card->mp_rd_bitmap);
+	}
+	return 0;
+}
+
+/*
+ * This function gets the write port for data.
+ *
+ * The current write port is returned if available and the value is
+ * increased (provided it does not reach the maximum limit, in which
+ * case it is reset to 1)
+ */
+static int mwifiex_get_wr_port_data(struct mwifiex_adapter *adapter, u8 *port)
+{
+	struct sdio_mmc_card *card = adapter->card;
+	u16 wr_bitmap = card->mp_wr_bitmap;
+
+	dev_dbg(adapter->dev, "data: mp_wr_bitmap=0x%04x\n", wr_bitmap);
+
+	if (!(wr_bitmap & card->mp_data_port_mask))
+		return -1;
+
+	if (card->mp_wr_bitmap & (1 << card->curr_wr_port)) {
+		card->mp_wr_bitmap &= (u16) (~(1 << card->curr_wr_port));
+		*port = card->curr_wr_port;
+		if (++card->curr_wr_port == card->mp_end_port)
+			card->curr_wr_port = 1;
+	} else {
+		adapter->data_sent = true;
+		return -EBUSY;
+	}
+
+	if (*port == CTRL_PORT) {
+		dev_err(adapter->dev, "invalid data port=%d cur port=%d"
+				" mp_wr_bitmap=0x%04x -> 0x%04x\n",
+				*port, card->curr_wr_port, wr_bitmap,
+				card->mp_wr_bitmap);
+		return -1;
+	}
+
+	dev_dbg(adapter->dev, "data: port=%d mp_wr_bitmap=0x%04x -> 0x%04x\n",
+	       *port, wr_bitmap, card->mp_wr_bitmap);
+
+	return 0;
+}
+
+/*
+ * This function polls the card status.
+ */
+static int
+mwifiex_sdio_poll_card_status(struct mwifiex_adapter *adapter, u8 bits)
+{
+	u32 tries;
+	u32 cs;
+
+	for (tries = 0; tries < MAX_POLL_TRIES; tries++) {
+		if (mwifiex_read_reg(adapter, CARD_STATUS_REG, &cs))
+			break;
+		else if ((cs & bits) == bits)
+			return 0;
+
+		udelay(10);
+	}
+
+	dev_err(adapter->dev, "poll card status failed, tries = %d\n",
+	       tries);
+	return -1;
+}
+
+/*
+ * This function reads the firmware status.
+ */
+static int
+mwifiex_sdio_read_fw_status(struct mwifiex_adapter *adapter, u16 *dat)
+{
+	u32 fws0, fws1;
+
+	if (mwifiex_read_reg(adapter, CARD_FW_STATUS0_REG, &fws0))
+		return -1;
+
+	if (mwifiex_read_reg(adapter, CARD_FW_STATUS1_REG, &fws1))
+		return -1;
+
+	*dat = (u16) ((fws1 << 8) | fws0);
+
+	return 0;
+}
+
+/*
+ * This function disables the host interrupt.
+ *
+ * The host interrupt mask is read, the disable bit is reset and
+ * written back to the card host interrupt mask register.
+ */
+static int mwifiex_sdio_disable_host_int(struct mwifiex_adapter *adapter)
+{
+	u32 host_int_mask;
+
+	/* Read back the host_int_mask register */
+	if (mwifiex_read_reg(adapter, HOST_INT_MASK_REG, &host_int_mask))
+		return -1;
+
+	/* Update with the mask and write back to the register */
+	host_int_mask &= ~HOST_INT_DISABLE;
+
+	if (mwifiex_write_reg(adapter, HOST_INT_MASK_REG, host_int_mask)) {
+		dev_err(adapter->dev, "disable host interrupt failed\n");
+		return -1;
+	}
+
+	return 0;
+}
+
+/*
+ * This function enables the host interrupt.
+ *
+ * The host interrupt enable mask is written to the card
+ * host interrupt mask register.
+ */
+static int mwifiex_sdio_enable_host_int(struct mwifiex_adapter *adapter)
+{
+	/* Simply write the mask to the register */
+	if (mwifiex_write_reg(adapter, HOST_INT_MASK_REG, HOST_INT_ENABLE)) {
+		dev_err(adapter->dev, "enable host interrupt failed\n");
+		return -1;
+	}
+	return 0;
+}
+
+/*
+ * This function sends a data buffer to the card.
+ */
+static int mwifiex_sdio_card_to_host(struct mwifiex_adapter *adapter,
+				     u32 *type, u8 *buffer,
+				     u32 npayload, u32 ioport)
+{
+	int ret;
+	u32 nb;
+
+	if (!buffer) {
+		dev_err(adapter->dev, "%s: buffer is NULL\n", __func__);
+		return -1;
+	}
+
+	ret = mwifiex_read_data_sync(adapter, buffer, npayload, ioport, 1);
+
+	if (ret) {
+		dev_err(adapter->dev, "%s: read iomem failed: %d\n", __func__,
+				ret);
+		return -1;
+	}
+
+	nb = le16_to_cpu(*(__le16 *) (buffer));
+	if (nb > npayload) {
+		dev_err(adapter->dev, "%s: invalid packet, nb=%d, npayload=%d\n",
+				__func__, nb, npayload);
+		return -1;
+	}
+
+	*type = le16_to_cpu(*(__le16 *) (buffer + 2));
+
+	return ret;
+}
+
+/*
+ * This function downloads the firmware to the card.
+ *
+ * Firmware is downloaded to the card in blocks. Every block download
+ * is tested for CRC errors, and retried a number of times before
+ * returning failure.
+ */
+static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter,
+				    struct mwifiex_fw_image *fw)
+{
+	int ret;
+	u8 *firmware = fw->fw_buf;
+	u32 firmware_len = fw->fw_len;
+	u32 offset = 0;
+	u32 base0, base1;
+	u8 *fwbuf;
+	u16 len = 0;
+	u32 txlen, tx_blocks = 0, tries;
+	u32 i = 0;
+
+	if (!firmware_len) {
+		dev_err(adapter->dev, "firmware image not found!"
+				" Terminating download\n");
+		return -1;
+	}
+
+	dev_dbg(adapter->dev, "info: downloading FW image (%d bytes)\n",
+			firmware_len);
+
+	/* Assume that the allocated buffer is 8-byte aligned */
+	fwbuf = kzalloc(MWIFIEX_UPLD_SIZE, GFP_KERNEL);
+	if (!fwbuf) {
+		dev_err(adapter->dev, "unable to alloc buffer for firmware."
+				" Terminating download\n");
+		return -ENOMEM;
+	}
+
+	/* Perform firmware data transfer */
+	do {
+		/* The host polls for the DN_LD_CARD_RDY and CARD_IO_READY
+		   bits */
+		ret = mwifiex_sdio_poll_card_status(adapter, CARD_IO_READY |
+						    DN_LD_CARD_RDY);
+		if (ret) {
+			dev_err(adapter->dev, "FW download with helper:"
+					" poll status timeout @ %d\n", offset);
+			goto done;
+		}
+
+		/* More data? */
+		if (offset >= firmware_len)
+			break;
+
+		for (tries = 0; tries < MAX_POLL_TRIES; tries++) {
+			ret = mwifiex_read_reg(adapter, HOST_F1_RD_BASE_0,
+					       &base0);
+			if (ret) {
+				dev_err(adapter->dev, "dev BASE0 register read"
+					" failed: base0=0x%04X(%d). Terminating "
+				       "download\n", base0, base0);
+				goto done;
+			}
+			ret = mwifiex_read_reg(adapter, HOST_F1_RD_BASE_1,
+					       &base1);
+			if (ret) {
+				dev_err(adapter->dev, "dev BASE1 register read"
+					" failed: base1=0x%04X(%d). Terminating "
+				       "download\n", base1, base1);
+				goto done;
+			}
+			len = (u16) (((base1 & 0xff) << 8) | (base0 & 0xff));
+
+			if (len)
+				break;
+
+			udelay(10);
+		}
+
+		if (!len) {
+			break;
+		} else if (len > MWIFIEX_UPLD_SIZE) {
+			dev_err(adapter->dev, "FW download failed @ %d,"
+				" invalid length %d\n", offset, len);
+			ret = -1;
+			goto done;
+		}
+
+		txlen = len;
+
+		if (len & BIT(0)) {
+			i++;
+			if (i > MAX_WRITE_IOMEM_RETRY) {
+				dev_err(adapter->dev, "FW download failed @"
+					" %d, over max retry count\n", offset);
+				ret = -1;
+				goto done;
+			}
+			dev_err(adapter->dev, "CRC indicated by the helper:"
+			       " len = 0x%04X, txlen = %d\n", len, txlen);
+			len &= ~BIT(0);
+			/* Setting this to 0 to resend from same offset */
+			txlen = 0;
+		} else {
+			i = 0;
+
+			/* Set blocksize to transfer - checking for last
+			   block */
+			if (firmware_len - offset < txlen)
+				txlen = firmware_len - offset;
+
+			tx_blocks = (txlen + MWIFIEX_SDIO_BLOCK_SIZE -
+					1) / MWIFIEX_SDIO_BLOCK_SIZE;
+
+			/* Copy payload to buffer */
+			memmove(fwbuf, &firmware[offset], txlen);
+		}
+
+		ret = mwifiex_write_data_sync(adapter, fwbuf, tx_blocks *
+					      MWIFIEX_SDIO_BLOCK_SIZE,
+					      adapter->ioport);
+		if (ret) {
+			dev_err(adapter->dev, "FW download, write iomem (%d)"
+					" failed @ %d\n", i, offset);
+			if (mwifiex_write_reg(adapter, CONFIGURATION_REG, 0x04))
+				dev_err(adapter->dev, "write CFG reg failed\n");
+
+			ret = -1;
+			goto done;
+		}
+
+		offset += txlen;
+	} while (true);
+
+	dev_dbg(adapter->dev, "info: FW download over, size %d bytes\n",
+						offset);
+
+	ret = 0;
+done:
+	kfree(fwbuf);
+	return ret;
+}
+
+/*
+ * This function checks the firmware status in card.
+ *
+ * The winner interface is also determined by this function.
+ */
+static int mwifiex_check_fw_status(struct mwifiex_adapter *adapter,
+				   u32 poll_num, int *winner)
+{
+	int ret = 0;
+	u16 firmware_stat;
+	u32 tries;
+	u32 winner_status;
+
+	/* Wait for firmware initialization event */
+	for (tries = 0; tries < poll_num; tries++) {
+		ret = mwifiex_sdio_read_fw_status(adapter, &firmware_stat);
+		if (ret)
+			continue;
+		if (firmware_stat == FIRMWARE_READY) {
+			ret = 0;
+			break;
+		} else {
+			mdelay(100);
+			ret = -1;
+		}
+	}
+
+	if (winner && ret) {
+		if (mwifiex_read_reg
+		    (adapter, CARD_FW_STATUS0_REG, &winner_status))
+			winner_status = 0;
+
+		if (winner_status)
+			*winner = 0;
+		else
+			*winner = 1;
+	}
+	return ret;
+}
+
+/*
+ * This function reads the interrupt status from card.
+ */
+static void mwifiex_interrupt_status(struct mwifiex_adapter *adapter)
+{
+	struct sdio_mmc_card *card = adapter->card;
+	u32 sdio_ireg;
+	unsigned long flags;
+
+	if (mwifiex_read_data_sync(adapter, card->mp_regs, MAX_MP_REGS,
+				   REG_PORT | MWIFIEX_SDIO_BYTE_MODE_MASK,
+				   0)) {
+		dev_err(adapter->dev, "read mp_regs failed\n");
+		return;
+	}
+
+	sdio_ireg = card->mp_regs[HOST_INTSTATUS_REG];
+	if (sdio_ireg) {
+		/*
+		 * DN_LD_HOST_INT_STATUS and/or UP_LD_HOST_INT_STATUS
+		 * Clear the interrupt status register
+		 */
+		dev_dbg(adapter->dev, "int: sdio_ireg = %#x\n", sdio_ireg);
+		spin_lock_irqsave(&adapter->int_lock, flags);
+		adapter->int_status |= sdio_ireg;
+		spin_unlock_irqrestore(&adapter->int_lock, flags);
+	}
+}
+
+/*
+ * SDIO interrupt handler.
+ *
+ * This function reads the interrupt status from firmware and assigns
+ * the main process in workqueue which will handle the interrupt.
+ */
+static void
+mwifiex_sdio_interrupt(struct sdio_func *func)
+{
+	struct mwifiex_adapter *adapter;
+	struct sdio_mmc_card *card;
+
+	card = sdio_get_drvdata(func);
+	if (!card || !card->adapter) {
+		pr_debug("int: func=%p card=%p adapter=%p\n",
+		       func, card, card ? card->adapter : NULL);
+		return;
+	}
+	adapter = card->adapter;
+
+	if (adapter->surprise_removed)
+		return;
+
+	if (!adapter->pps_uapsd_mode && adapter->ps_state == PS_STATE_SLEEP)
+		adapter->ps_state = PS_STATE_AWAKE;
+
+	mwifiex_interrupt_status(adapter);
+	queue_work(adapter->workqueue, &adapter->main_work);
+}
+
+/*
+ * This function decodes a received packet.
+ *
+ * Based on the type, the packet is treated as either a data, or
+ * a command response, or an event, and the correct handler
+ * function is invoked.
+ */
+static int mwifiex_decode_rx_packet(struct mwifiex_adapter *adapter,
+				    struct sk_buff *skb, u32 upld_typ)
+{
+	u8 *cmd_buf;
+
+	skb_pull(skb, INTF_HEADER_LEN);
+
+	switch (upld_typ) {
+	case MWIFIEX_TYPE_DATA:
+		dev_dbg(adapter->dev, "info: --- Rx: Data packet ---\n");
+		mwifiex_handle_rx_packet(adapter, skb);
+		break;
+
+	case MWIFIEX_TYPE_CMD:
+		dev_dbg(adapter->dev, "info: --- Rx: Cmd Response ---\n");
+		/* take care of curr_cmd = NULL case */
+		if (!adapter->curr_cmd) {
+			cmd_buf = adapter->upld_buf;
+
+			if (adapter->ps_state == PS_STATE_SLEEP_CFM)
+				mwifiex_process_sleep_confirm_resp(adapter,
+							skb->data, skb->len);
+
+			memcpy(cmd_buf, skb->data, min_t(u32,
+				       MWIFIEX_SIZE_OF_CMD_BUFFER, skb->len));
+
+			dev_kfree_skb_any(skb);
+		} else {
+			adapter->cmd_resp_received = true;
+			adapter->curr_cmd->resp_skb = skb;
+		}
+		break;
+
+	case MWIFIEX_TYPE_EVENT:
+		dev_dbg(adapter->dev, "info: --- Rx: Event ---\n");
+		adapter->event_cause = *(u32 *) skb->data;
+
+		skb_pull(skb, MWIFIEX_EVENT_HEADER_LEN);
+
+		if ((skb->len > 0) && (skb->len  < MAX_EVENT_SIZE))
+			memcpy(adapter->event_body, skb->data, skb->len);
+
+		/* event cause has been saved to adapter->event_cause */
+		adapter->event_received = true;
+		adapter->event_skb = skb;
+
+		break;
+
+	default:
+		dev_err(adapter->dev, "unknown upload type %#x\n", upld_typ);
+		dev_kfree_skb_any(skb);
+		break;
+	}
+
+	return 0;
+}
+
+/*
+ * This function transfers received packets from card to driver, performing
+ * aggregation if required.
+ *
+ * For data received on control port, or if aggregation is disabled, the
+ * received buffers are uploaded as separate packets. However, if aggregation
+ * is enabled and required, the buffers are copied onto an aggregation buffer,
+ * provided there is space left, processed and finally uploaded.
+ */
+static int mwifiex_sdio_card_to_host_mp_aggr(struct mwifiex_adapter *adapter,
+					     struct sk_buff *skb, u8 port)
+{
+	struct sdio_mmc_card *card = adapter->card;
+	s32 f_do_rx_aggr = 0;
+	s32 f_do_rx_cur = 0;
+	s32 f_aggr_cur = 0;
+	struct sk_buff *skb_deaggr;
+	u32 pind;
+	u32 pkt_len, pkt_type = 0;
+	u8 *curr_ptr;
+	u32 rx_len = skb->len;
+
+	if (port == CTRL_PORT) {
+		/* Read the command Resp without aggr */
+		dev_dbg(adapter->dev, "info: %s: no aggregation for cmd "
+				"response\n", __func__);
+
+		f_do_rx_cur = 1;
+		goto rx_curr_single;
+	}
+
+	if (!card->mpa_rx.enabled) {
+		dev_dbg(adapter->dev, "info: %s: rx aggregation disabled\n",
+						__func__);
+
+		f_do_rx_cur = 1;
+		goto rx_curr_single;
+	}
+
+	if (card->mp_rd_bitmap & (~((u16) CTRL_PORT_MASK))) {
+		/* Some more data RX pending */
+		dev_dbg(adapter->dev, "info: %s: not last packet\n", __func__);
+
+		if (MP_RX_AGGR_IN_PROGRESS(card)) {
+			if (MP_RX_AGGR_BUF_HAS_ROOM(card, skb->len)) {
+				f_aggr_cur = 1;
+			} else {
+				/* No room in Aggr buf, do rx aggr now */
+				f_do_rx_aggr = 1;
+				f_do_rx_cur = 1;
+			}
+		} else {
+			/* Rx aggr not in progress */
+			f_aggr_cur = 1;
+		}
+
+	} else {
+		/* No more data RX pending */
+		dev_dbg(adapter->dev, "info: %s: last packet\n", __func__);
+
+		if (MP_RX_AGGR_IN_PROGRESS(card)) {
+			f_do_rx_aggr = 1;
+			if (MP_RX_AGGR_BUF_HAS_ROOM(card, skb->len))
+				f_aggr_cur = 1;
+			else
+				/* No room in Aggr buf, do rx aggr now */
+				f_do_rx_cur = 1;
+		} else {
+			f_do_rx_cur = 1;
+		}
+	}
+
+	if (f_aggr_cur) {
+		dev_dbg(adapter->dev, "info: current packet aggregation\n");
+		/* Curr pkt can be aggregated */
+		MP_RX_AGGR_SETUP(card, skb, port);
+
+		if (MP_RX_AGGR_PKT_LIMIT_REACHED(card) ||
+		    MP_RX_AGGR_PORT_LIMIT_REACHED(card)) {
+			dev_dbg(adapter->dev, "info: %s: aggregated packet "
+					"limit reached\n", __func__);
+			/* No more pkts allowed in Aggr buf, rx it */
+			f_do_rx_aggr = 1;
+		}
+	}
+
+	if (f_do_rx_aggr) {
+		/* do aggr RX now */
+		dev_dbg(adapter->dev, "info: do_rx_aggr: num of packets: %d\n",
+		       card->mpa_rx.pkt_cnt);
+
+		if (mwifiex_read_data_sync(adapter, card->mpa_rx.buf,
+					   card->mpa_rx.buf_len,
+					   (adapter->ioport | 0x1000 |
+					    (card->mpa_rx.ports << 4)) +
+					   card->mpa_rx.start_port, 1))
+			return -1;
+
+		curr_ptr = card->mpa_rx.buf;
+
+		for (pind = 0; pind < card->mpa_rx.pkt_cnt; pind++) {
+
+			/* get curr PKT len & type */
+			pkt_len = *(u16 *) &curr_ptr[0];
+			pkt_type = *(u16 *) &curr_ptr[2];
+
+			/* copy pkt to deaggr buf */
+			skb_deaggr = card->mpa_rx.skb_arr[pind];
+
+			if ((pkt_type == MWIFIEX_TYPE_DATA) && (pkt_len <=
+					 card->mpa_rx.len_arr[pind])) {
+
+				memcpy(skb_deaggr->data, curr_ptr, pkt_len);
+
+				skb_trim(skb_deaggr, pkt_len);
+
+				/* Process de-aggr packet */
+				mwifiex_decode_rx_packet(adapter, skb_deaggr,
+							 pkt_type);
+			} else {
+				dev_err(adapter->dev, "wrong aggr pkt:"
+					" type=%d len=%d max_len=%d\n",
+					pkt_type, pkt_len,
+					card->mpa_rx.len_arr[pind]);
+				dev_kfree_skb_any(skb_deaggr);
+			}
+			curr_ptr += card->mpa_rx.len_arr[pind];
+		}
+		MP_RX_AGGR_BUF_RESET(card);
+	}
+
+rx_curr_single:
+	if (f_do_rx_cur) {
+		dev_dbg(adapter->dev, "info: RX: port: %d, rx_len: %d\n",
+			port, rx_len);
+
+		if (mwifiex_sdio_card_to_host(adapter, &pkt_type,
+					      skb->data, skb->len,
+					      adapter->ioport + port))
+			return -1;
+
+		mwifiex_decode_rx_packet(adapter, skb, pkt_type);
+	}
+
+	return 0;
+}
+
+/*
+ * This function checks the current interrupt status.
+ *
+ * The following interrupts are checked and handled by this function -
+ *      - Data sent
+ *      - Command sent
+ *      - Packets received
+ *
+ * Since the firmware does not generate download ready interrupt if the
+ * port updated is command port only, command sent interrupt checking
+ * should be done manually, and for every SDIO interrupt.
+ *
+ * In case of Rx packets received, the packets are uploaded from card to
+ * host and processed accordingly.
+ */
+static int mwifiex_process_int_status(struct mwifiex_adapter *adapter)
+{
+	struct sdio_mmc_card *card = adapter->card;
+	int ret = 0;
+	u8 sdio_ireg;
+	struct sk_buff *skb;
+	u8 port = CTRL_PORT;
+	u32 len_reg_l, len_reg_u;
+	u32 rx_blocks;
+	u16 rx_len;
+	unsigned long flags;
+
+	spin_lock_irqsave(&adapter->int_lock, flags);
+	sdio_ireg = adapter->int_status;
+	adapter->int_status = 0;
+	spin_unlock_irqrestore(&adapter->int_lock, flags);
+
+	if (!sdio_ireg)
+		return ret;
+
+	if (sdio_ireg & DN_LD_HOST_INT_STATUS) {
+		card->mp_wr_bitmap = ((u16) card->mp_regs[WR_BITMAP_U]) << 8;
+		card->mp_wr_bitmap |= (u16) card->mp_regs[WR_BITMAP_L];
+		dev_dbg(adapter->dev, "int: DNLD: wr_bitmap=0x%04x\n",
+				card->mp_wr_bitmap);
+		if (adapter->data_sent &&
+		    (card->mp_wr_bitmap & card->mp_data_port_mask)) {
+			dev_dbg(adapter->dev,
+				"info:  <--- Tx DONE Interrupt --->\n");
+			adapter->data_sent = false;
+		}
+	}
+
+	/* As firmware will not generate download ready interrupt if the port
+	   updated is command port only, cmd_sent should be done for any SDIO
+	   interrupt. */
+	if (adapter->cmd_sent) {
+		/* Check if firmware has attach buffer at command port and
+		   update just that in wr_bit_map. */
+		card->mp_wr_bitmap |=
+			(u16) card->mp_regs[WR_BITMAP_L] & CTRL_PORT_MASK;
+		if (card->mp_wr_bitmap & CTRL_PORT_MASK)
+			adapter->cmd_sent = false;
+	}
+
+	dev_dbg(adapter->dev, "info: cmd_sent=%d data_sent=%d\n",
+	       adapter->cmd_sent, adapter->data_sent);
+	if (sdio_ireg & UP_LD_HOST_INT_STATUS) {
+		card->mp_rd_bitmap = ((u16) card->mp_regs[RD_BITMAP_U]) << 8;
+		card->mp_rd_bitmap |= (u16) card->mp_regs[RD_BITMAP_L];
+		dev_dbg(adapter->dev, "int: UPLD: rd_bitmap=0x%04x\n",
+				card->mp_rd_bitmap);
+
+		while (true) {
+			ret = mwifiex_get_rd_port(adapter, &port);
+			if (ret) {
+				dev_dbg(adapter->dev,
+					"info: no more rd_port available\n");
+				break;
+			}
+			len_reg_l = RD_LEN_P0_L + (port << 1);
+			len_reg_u = RD_LEN_P0_U + (port << 1);
+			rx_len = ((u16) card->mp_regs[len_reg_u]) << 8;
+			rx_len |= (u16) card->mp_regs[len_reg_l];
+			dev_dbg(adapter->dev, "info: RX: port=%d rx_len=%u\n",
+					port, rx_len);
+			rx_blocks =
+				(rx_len + MWIFIEX_SDIO_BLOCK_SIZE -
+				 1) / MWIFIEX_SDIO_BLOCK_SIZE;
+			if (rx_len <= INTF_HEADER_LEN
+			    || (rx_blocks * MWIFIEX_SDIO_BLOCK_SIZE) >
+			    MWIFIEX_RX_DATA_BUF_SIZE) {
+				dev_err(adapter->dev, "invalid rx_len=%d\n",
+						rx_len);
+				return -1;
+			}
+			rx_len = (u16) (rx_blocks * MWIFIEX_SDIO_BLOCK_SIZE);
+
+			skb = dev_alloc_skb(rx_len);
+
+			if (!skb) {
+				dev_err(adapter->dev, "%s: failed to alloc skb",
+								__func__);
+				return -1;
+			}
+
+			skb_put(skb, rx_len);
+
+			dev_dbg(adapter->dev, "info: rx_len = %d skb->len = %d\n",
+					rx_len, skb->len);
+
+			if (mwifiex_sdio_card_to_host_mp_aggr(adapter, skb,
+							      port)) {
+				u32 cr = 0;
+
+				dev_err(adapter->dev, "card_to_host_mpa failed:"
+						" int status=%#x\n", sdio_ireg);
+				if (mwifiex_read_reg(adapter,
+						     CONFIGURATION_REG, &cr))
+					dev_err(adapter->dev,
+							"read CFG reg failed\n");
+
+				dev_dbg(adapter->dev,
+						"info: CFG reg val = %d\n", cr);
+				if (mwifiex_write_reg(adapter,
+						      CONFIGURATION_REG,
+						      (cr | 0x04)))
+					dev_err(adapter->dev,
+							"write CFG reg failed\n");
+
+				dev_dbg(adapter->dev, "info: write success\n");
+				if (mwifiex_read_reg(adapter,
+						     CONFIGURATION_REG, &cr))
+					dev_err(adapter->dev,
+							"read CFG reg failed\n");
+
+				dev_dbg(adapter->dev,
+						"info: CFG reg val =%x\n", cr);
+				dev_kfree_skb_any(skb);
+				return -1;
+			}
+		}
+	}
+
+	return 0;
+}
+
+/*
+ * This function aggregates transmission buffers in driver and downloads
+ * the aggregated packet to card.
+ *
+ * The individual packets are aggregated by copying into an aggregation
+ * buffer and then downloaded to the card. Previous unsent packets in the
+ * aggregation buffer are pre-copied first before new packets are added.
+ * Aggregation is done till there is space left in the aggregation buffer,
+ * or till new packets are available.
+ *
+ * The function will only download the packet to the card when aggregation
+ * stops, otherwise it will just aggregate the packet in aggregation buffer
+ * and return.
+ */
+static int mwifiex_host_to_card_mp_aggr(struct mwifiex_adapter *adapter,
+					u8 *payload, u32 pkt_len, u8 port,
+					u32 next_pkt_len)
+{
+	struct sdio_mmc_card *card = adapter->card;
+	int ret = 0;
+	s32 f_send_aggr_buf = 0;
+	s32 f_send_cur_buf = 0;
+	s32 f_precopy_cur_buf = 0;
+	s32 f_postcopy_cur_buf = 0;
+
+	if ((!card->mpa_tx.enabled) || (port == CTRL_PORT)) {
+		dev_dbg(adapter->dev, "info: %s: tx aggregation disabled\n",
+						__func__);
+
+		f_send_cur_buf = 1;
+		goto tx_curr_single;
+	}
+
+	if (next_pkt_len) {
+		/* More pkt in TX queue */
+		dev_dbg(adapter->dev, "info: %s: more packets in queue.\n",
+						__func__);
+
+		if (MP_TX_AGGR_IN_PROGRESS(card)) {
+			if (!MP_TX_AGGR_PORT_LIMIT_REACHED(card) &&
+			    MP_TX_AGGR_BUF_HAS_ROOM(card, pkt_len)) {
+				f_precopy_cur_buf = 1;
+
+				if (!(card->mp_wr_bitmap &
+						(1 << card->curr_wr_port))
+						|| !MP_TX_AGGR_BUF_HAS_ROOM(
+							card, next_pkt_len))
+					f_send_aggr_buf = 1;
+			} else {
+				/* No room in Aggr buf, send it */
+				f_send_aggr_buf = 1;
+
+				if (MP_TX_AGGR_PORT_LIMIT_REACHED(card) ||
+				    !(card->mp_wr_bitmap &
+				      (1 << card->curr_wr_port)))
+					f_send_cur_buf = 1;
+				else
+					f_postcopy_cur_buf = 1;
+			}
+		} else {
+			if (MP_TX_AGGR_BUF_HAS_ROOM(card, pkt_len)
+			    && (card->mp_wr_bitmap & (1 << card->curr_wr_port)))
+				f_precopy_cur_buf = 1;
+			else
+				f_send_cur_buf = 1;
+		}
+	} else {
+		/* Last pkt in TX queue */
+		dev_dbg(adapter->dev, "info: %s: Last packet in Tx Queue.\n",
+						__func__);
+
+		if (MP_TX_AGGR_IN_PROGRESS(card)) {
+			/* some packs in Aggr buf already */
+			f_send_aggr_buf = 1;
+
+			if (MP_TX_AGGR_BUF_HAS_ROOM(card, pkt_len))
+				f_precopy_cur_buf = 1;
+			else
+				/* No room in Aggr buf, send it */
+				f_send_cur_buf = 1;
+		} else {
+			f_send_cur_buf = 1;
+		}
+	}
+
+	if (f_precopy_cur_buf) {
+		dev_dbg(adapter->dev, "data: %s: precopy current buffer\n",
+						__func__);
+		MP_TX_AGGR_BUF_PUT(card, payload, pkt_len, port);
+
+		if (MP_TX_AGGR_PKT_LIMIT_REACHED(card) ||
+		    MP_TX_AGGR_PORT_LIMIT_REACHED(card))
+			/* No more pkts allowed in Aggr buf, send it */
+			f_send_aggr_buf = 1;
+	}
+
+	if (f_send_aggr_buf) {
+		dev_dbg(adapter->dev, "data: %s: send aggr buffer: %d %d\n",
+				__func__,
+				card->mpa_tx.start_port, card->mpa_tx.ports);
+		ret = mwifiex_write_data_to_card(adapter, card->mpa_tx.buf,
+						 card->mpa_tx.buf_len,
+						 (adapter->ioport | 0x1000 |
+						 (card->mpa_tx.ports << 4)) +
+						  card->mpa_tx.start_port);
+
+		MP_TX_AGGR_BUF_RESET(card);
+	}
+
+tx_curr_single:
+	if (f_send_cur_buf) {
+		dev_dbg(adapter->dev, "data: %s: send current buffer %d\n",
+						__func__, port);
+		ret = mwifiex_write_data_to_card(adapter, payload, pkt_len,
+						 adapter->ioport + port);
+	}
+
+	if (f_postcopy_cur_buf) {
+		dev_dbg(adapter->dev, "data: %s: postcopy current buffer\n",
+						__func__);
+		MP_TX_AGGR_BUF_PUT(card, payload, pkt_len, port);
+	}
+
+	return ret;
+}
+
+/*
+ * This function downloads data from driver to card.
+ *
+ * Both commands and data packets are transferred to the card by this
+ * function.
+ *
+ * This function adds the SDIO specific header to the front of the buffer
+ * before transferring. The header contains the length of the packet and
+ * the type. The firmware handles the packets based upon this set type.
+ */
+static int mwifiex_sdio_host_to_card(struct mwifiex_adapter *adapter,
+				     u8 type, u8 *payload, u32 pkt_len,
+				     struct mwifiex_tx_param *tx_param)
+{
+	struct sdio_mmc_card *card = adapter->card;
+	int ret;
+	u32 buf_block_len;
+	u32 blk_size;
+	u8 port = CTRL_PORT;
+
+	/* Allocate buffer and copy payload */
+	blk_size = MWIFIEX_SDIO_BLOCK_SIZE;
+	buf_block_len = (pkt_len + blk_size - 1) / blk_size;
+	*(u16 *) &payload[0] = (u16) pkt_len;
+	*(u16 *) &payload[2] = type;
+
+	/*
+	 * This is SDIO specific header
+	 *  u16 length,
+	 *  u16 type (MWIFIEX_TYPE_DATA = 0, MWIFIEX_TYPE_CMD = 1,
+	 *  MWIFIEX_TYPE_EVENT = 3)
+	 */
+	if (type == MWIFIEX_TYPE_DATA) {
+		ret = mwifiex_get_wr_port_data(adapter, &port);
+		if (ret) {
+			dev_err(adapter->dev, "%s: no wr_port available\n",
+						__func__);
+			return ret;
+		}
+	} else {
+		adapter->cmd_sent = true;
+		/* Type must be MWIFIEX_TYPE_CMD */
+
+		if (pkt_len <= INTF_HEADER_LEN ||
+		    pkt_len > MWIFIEX_UPLD_SIZE)
+			dev_err(adapter->dev, "%s: payload=%p, nb=%d\n",
+					__func__, payload, pkt_len);
+	}
+
+	/* Transfer data to card */
+	pkt_len = buf_block_len * blk_size;
+
+	if (tx_param)
+		ret = mwifiex_host_to_card_mp_aggr(adapter, payload, pkt_len,
+				port, tx_param->next_pkt_len);
+	else
+		ret = mwifiex_host_to_card_mp_aggr(adapter, payload, pkt_len,
+				port, 0);
+
+	if (ret) {
+		if (type == MWIFIEX_TYPE_CMD)
+			adapter->cmd_sent = false;
+		if (type == MWIFIEX_TYPE_DATA)
+			adapter->data_sent = false;
+	} else {
+		if (type == MWIFIEX_TYPE_DATA) {
+			if (!(card->mp_wr_bitmap & (1 << card->curr_wr_port)))
+				adapter->data_sent = true;
+			else
+				adapter->data_sent = false;
+		}
+	}
+
+	return ret;
+}
+
+/*
+ * This function allocates the MPA Tx and Rx buffers.
+ */
+static int mwifiex_alloc_sdio_mpa_buffers(struct mwifiex_adapter *adapter,
+				   u32 mpa_tx_buf_size, u32 mpa_rx_buf_size)
+{
+	struct sdio_mmc_card *card = adapter->card;
+	int ret = 0;
+
+	card->mpa_tx.buf = kzalloc(mpa_tx_buf_size, GFP_KERNEL);
+	if (!card->mpa_tx.buf) {
+		dev_err(adapter->dev, "could not alloc buffer for MP-A TX\n");
+		ret = -1;
+		goto error;
+	}
+
+	card->mpa_tx.buf_size = mpa_tx_buf_size;
+
+	card->mpa_rx.buf = kzalloc(mpa_rx_buf_size, GFP_KERNEL);
+	if (!card->mpa_rx.buf) {
+		dev_err(adapter->dev, "could not alloc buffer for MP-A RX\n");
+		ret = -1;
+		goto error;
+	}
+
+	card->mpa_rx.buf_size = mpa_rx_buf_size;
+
+error:
+	if (ret) {
+		kfree(card->mpa_tx.buf);
+		kfree(card->mpa_rx.buf);
+	}
+
+	return ret;
+}
+
+/*
+ * This function unregisters the SDIO device.
+ *
+ * The SDIO IRQ is released, the function is disabled and driver
+ * data is set to null.
+ */
+static void
+mwifiex_unregister_dev(struct mwifiex_adapter *adapter)
+{
+	struct sdio_mmc_card *card = adapter->card;
+
+	if (adapter->card) {
+		/* Release the SDIO IRQ */
+		sdio_claim_host(card->func);
+		sdio_release_irq(card->func);
+		sdio_disable_func(card->func);
+		sdio_release_host(card->func);
+		sdio_set_drvdata(card->func, NULL);
+	}
+}
+
+/*
+ * This function registers the SDIO device.
+ *
+ * SDIO IRQ is claimed, block size is set and driver data is initialized.
+ */
+static int mwifiex_register_dev(struct mwifiex_adapter *adapter)
+{
+	int ret = 0;
+	struct sdio_mmc_card *card = adapter->card;
+	struct sdio_func *func = card->func;
+
+	/* save adapter pointer in card */
+	card->adapter = adapter;
+
+	sdio_claim_host(func);
+
+	/* Request the SDIO IRQ */
+	ret = sdio_claim_irq(func, mwifiex_sdio_interrupt);
+	if (ret) {
+		pr_err("claim irq failed: ret=%d\n", ret);
+		goto disable_func;
+	}
+
+	/* Set block size */
+	ret = sdio_set_block_size(card->func, MWIFIEX_SDIO_BLOCK_SIZE);
+	if (ret) {
+		pr_err("cannot set SDIO block size\n");
+		ret = -1;
+		goto release_irq;
+	}
+
+	sdio_release_host(func);
+	sdio_set_drvdata(func, card);
+
+	adapter->dev = &func->dev;
+
+	return 0;
+
+release_irq:
+	sdio_release_irq(func);
+disable_func:
+	sdio_disable_func(func);
+	sdio_release_host(func);
+	adapter->card = NULL;
+
+	return -1;
+}
+
+/*
+ * This function initializes the SDIO driver.
+ *
+ * The following initializations steps are followed -
+ *      - Read the Host interrupt status register to acknowledge
+ *        the first interrupt got from bootloader
+ *      - Disable host interrupt mask register
+ *      - Get SDIO port
+ *      - Get revision ID
+ *      - Initialize SDIO variables in card
+ *      - Allocate MP registers
+ *      - Allocate MPA Tx and Rx buffers
+ */
+static int mwifiex_init_sdio(struct mwifiex_adapter *adapter)
+{
+	struct sdio_mmc_card *card = adapter->card;
+	int ret;
+	u32 sdio_ireg;
+
+	/*
+	 * Read the HOST_INT_STATUS_REG for ACK the first interrupt got
+	 * from the bootloader. If we don't do this we get a interrupt
+	 * as soon as we register the irq.
+	 */
+	mwifiex_read_reg(adapter, HOST_INTSTATUS_REG, &sdio_ireg);
+
+	/* Disable host interrupt mask register for SDIO */
+	mwifiex_sdio_disable_host_int(adapter);
+
+	/* Get SDIO ioport */
+	mwifiex_init_sdio_ioport(adapter);
+
+	/* Get revision ID */
+#define REV_ID_REG	0x5c
+	mwifiex_read_reg(adapter, REV_ID_REG, &adapter->revision_id);
+
+	/* Initialize SDIO variables in card */
+	card->mp_rd_bitmap = 0;
+	card->mp_wr_bitmap = 0;
+	card->curr_rd_port = 1;
+	card->curr_wr_port = 1;
+
+	card->mp_data_port_mask = DATA_PORT_MASK;
+
+	card->mpa_tx.buf_len = 0;
+	card->mpa_tx.pkt_cnt = 0;
+	card->mpa_tx.start_port = 0;
+
+	card->mpa_tx.enabled = 0;
+	card->mpa_tx.pkt_aggr_limit = SDIO_MP_AGGR_DEF_PKT_LIMIT;
+
+	card->mpa_rx.buf_len = 0;
+	card->mpa_rx.pkt_cnt = 0;
+	card->mpa_rx.start_port = 0;
+
+	card->mpa_rx.enabled = 0;
+	card->mpa_rx.pkt_aggr_limit = SDIO_MP_AGGR_DEF_PKT_LIMIT;
+
+	/* Allocate buffers for SDIO MP-A */
+	card->mp_regs = kzalloc(MAX_MP_REGS, GFP_KERNEL);
+	if (!card->mp_regs) {
+		dev_err(adapter->dev, "failed to alloc mp_regs\n");
+		return -ENOMEM;
+	}
+
+	ret = mwifiex_alloc_sdio_mpa_buffers(adapter,
+					     SDIO_MP_TX_AGGR_DEF_BUF_SIZE,
+					     SDIO_MP_RX_AGGR_DEF_BUF_SIZE);
+	if (ret) {
+		dev_err(adapter->dev, "failed to alloc sdio mp-a buffers\n");
+		kfree(card->mp_regs);
+		return -1;
+	}
+
+	return ret;
+}
+
+/*
+ * This function resets the MPA Tx and Rx buffers.
+ */
+static void mwifiex_cleanup_mpa_buf(struct mwifiex_adapter *adapter)
+{
+	struct sdio_mmc_card *card = adapter->card;
+
+	MP_TX_AGGR_BUF_RESET(card);
+	MP_RX_AGGR_BUF_RESET(card);
+}
+
+/*
+ * This function cleans up the allocated card buffers.
+ *
+ * The following are freed by this function -
+ *      - MP registers
+ *      - MPA Tx buffer
+ *      - MPA Rx buffer
+ */
+static void mwifiex_cleanup_sdio(struct mwifiex_adapter *adapter)
+{
+	struct sdio_mmc_card *card = adapter->card;
+
+	kfree(card->mp_regs);
+	kfree(card->mpa_tx.buf);
+	kfree(card->mpa_rx.buf);
+}
+
+/*
+ * This function updates the MP end port in card.
+ */
+static void
+mwifiex_update_mp_end_port(struct mwifiex_adapter *adapter, u16 port)
+{
+	struct sdio_mmc_card *card = adapter->card;
+	int i;
+
+	card->mp_end_port = port;
+
+	card->mp_data_port_mask = DATA_PORT_MASK;
+
+	for (i = 1; i <= MAX_PORT - card->mp_end_port; i++)
+		card->mp_data_port_mask &= ~(1 << (MAX_PORT - i));
+
+	card->curr_wr_port = 1;
+
+	dev_dbg(adapter->dev, "cmd: mp_end_port %d, data port mask 0x%x\n",
+	       port, card->mp_data_port_mask);
+}
+
+static struct mwifiex_if_ops sdio_ops = {
+	.init_if = mwifiex_init_sdio,
+	.cleanup_if = mwifiex_cleanup_sdio,
+	.check_fw_status = mwifiex_check_fw_status,
+	.prog_fw = mwifiex_prog_fw_w_helper,
+	.register_dev = mwifiex_register_dev,
+	.unregister_dev = mwifiex_unregister_dev,
+	.enable_int = mwifiex_sdio_enable_host_int,
+	.process_int_status = mwifiex_process_int_status,
+	.host_to_card = mwifiex_sdio_host_to_card,
+	.wakeup = mwifiex_pm_wakeup_card,
+	.wakeup_complete = mwifiex_pm_wakeup_card_complete,
+
+	/* SDIO specific */
+	.update_mp_end_port = mwifiex_update_mp_end_port,
+	.cleanup_mpa_buf = mwifiex_cleanup_mpa_buf,
+};
+
+/*
+ * This function initializes the SDIO driver.
+ *
+ * This initiates the semaphore and registers the device with
+ * SDIO bus.
+ */
+static int
+mwifiex_sdio_init_module(void)
+{
+	sema_init(&add_remove_card_sem, 1);
+
+	return sdio_register_driver(&mwifiex_sdio);
+}
+
+/*
+ * This function cleans up the SDIO driver.
+ *
+ * The following major steps are followed for cleanup -
+ *      - Resume the device if its suspended
+ *      - Disconnect the device if connected
+ *      - Shutdown the firmware
+ *      - Unregister the device from SDIO bus.
+ */
+static void
+mwifiex_sdio_cleanup_module(void)
+{
+	struct mwifiex_adapter *adapter = g_adapter;
+	int i;
+
+	if (down_interruptible(&add_remove_card_sem))
+		goto exit_sem_err;
+
+	if (!adapter || !adapter->priv_num)
+		goto exit;
+
+	if (adapter->is_suspended)
+		mwifiex_sdio_resume(adapter->dev);
+
+	for (i = 0; i < adapter->priv_num; i++)
+		if ((GET_BSS_ROLE(adapter->priv[i]) == MWIFIEX_BSS_ROLE_STA) &&
+		    adapter->priv[i]->media_connected)
+			mwifiex_deauthenticate(adapter->priv[i], NULL);
+
+	if (!adapter->surprise_removed)
+		mwifiex_init_shutdown_fw(mwifiex_get_priv(adapter,
+							  MWIFIEX_BSS_ROLE_ANY),
+					 MWIFIEX_FUNC_SHUTDOWN);
+
+exit:
+	up(&add_remove_card_sem);
+
+exit_sem_err:
+	sdio_unregister_driver(&mwifiex_sdio);
+}
+
+module_init(mwifiex_sdio_init_module);
+module_exit(mwifiex_sdio_cleanup_module);
+
+MODULE_AUTHOR("Marvell International Ltd.");
+MODULE_DESCRIPTION("Marvell WiFi-Ex SDIO Driver version " SDIO_VERSION);
+MODULE_VERSION(SDIO_VERSION);
+MODULE_LICENSE("GPL v2");
+/*(DEBLOBBED)*/
diff -druN linux-2.6.39-libre/drivers/net/wireless/mwifiex/sdio.h linux-3.0-rc7-libre/drivers/net/wireless/mwifiex/sdio.h
--- linux-2.6.39-libre/drivers/net/wireless/mwifiex/sdio.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/net/wireless/mwifiex/sdio.h	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,305 @@
+/*
+ * Marvell Wireless LAN device driver: SDIO specific definitions
+ *
+ * Copyright (C) 2011, Marvell International Ltd.
+ *
+ * This software file (the "File") is distributed by Marvell International
+ * Ltd. under the terms of the GNU General Public License Version 2, June 1991
+ * (the "License").  You may use, redistribute and/or modify this File in
+ * accordance with the terms and conditions of the License, a copy of which
+ * is available by writing to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
+ * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
+ *
+ * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
+ * ARE EXPRESSLY DISCLAIMED.  The License provides additional details about
+ * this warranty disclaimer.
+ */
+
+#ifndef	_MWIFIEX_SDIO_H
+#define	_MWIFIEX_SDIO_H
+
+
+#include <linux/mmc/sdio.h>
+#include <linux/mmc/sdio_ids.h>
+#include <linux/mmc/sdio_func.h>
+#include <linux/mmc/card.h>
+
+#include "main.h"
+
+#define BLOCK_MODE	1
+#define BYTE_MODE	0
+
+#define REG_PORT			0
+#define RD_BITMAP_L			0x04
+#define RD_BITMAP_U			0x05
+#define WR_BITMAP_L			0x06
+#define WR_BITMAP_U			0x07
+#define RD_LEN_P0_L			0x08
+#define RD_LEN_P0_U			0x09
+
+#define MWIFIEX_SDIO_IO_PORT_MASK		0xfffff
+
+#define MWIFIEX_SDIO_BYTE_MODE_MASK	0x80000000
+
+#define CTRL_PORT			0
+#define CTRL_PORT_MASK			0x0001
+#define DATA_PORT_MASK			0xfffe
+
+#define MAX_MP_REGS			64
+#define MAX_PORT			16
+
+#define SDIO_MP_AGGR_DEF_PKT_LIMIT	8
+
+#define SDIO_MP_TX_AGGR_DEF_BUF_SIZE        (4096)	/* 4K */
+
+/* Multi port RX aggregation buffer size */
+#define SDIO_MP_RX_AGGR_DEF_BUF_SIZE        (4096)	/* 4K */
+
+/* Misc. Config Register : Auto Re-enable interrupts */
+#define AUTO_RE_ENABLE_INT              BIT(4)
+
+/* Host Control Registers */
+/* Host Control Registers : I/O port 0 */
+#define IO_PORT_0_REG			0x78
+/* Host Control Registers : I/O port 1 */
+#define IO_PORT_1_REG			0x79
+/* Host Control Registers : I/O port 2 */
+#define IO_PORT_2_REG			0x7A
+
+/* Host Control Registers : Configuration */
+#define CONFIGURATION_REG		0x00
+/* Host Control Registers : Host without Command 53 finish host*/
+#define HOST_TO_CARD_EVENT       (0x1U << 3)
+/* Host Control Registers : Host without Command 53 finish host */
+#define HOST_WO_CMD53_FINISH_HOST	(0x1U << 2)
+/* Host Control Registers : Host power up */
+#define HOST_POWER_UP			(0x1U << 1)
+/* Host Control Registers : Host power down */
+#define HOST_POWER_DOWN			(0x1U << 0)
+
+/* Host Control Registers : Host interrupt mask */
+#define HOST_INT_MASK_REG		0x02
+/* Host Control Registers : Upload host interrupt mask */
+#define UP_LD_HOST_INT_MASK		(0x1U)
+/* Host Control Registers : Download host interrupt mask */
+#define DN_LD_HOST_INT_MASK		(0x2U)
+/* Enable Host interrupt mask */
+#define HOST_INT_ENABLE	(UP_LD_HOST_INT_MASK | DN_LD_HOST_INT_MASK)
+/* Disable Host interrupt mask */
+#define	HOST_INT_DISABLE		0xff
+
+/* Host Control Registers : Host interrupt status */
+#define HOST_INTSTATUS_REG		0x03
+/* Host Control Registers : Upload host interrupt status */
+#define UP_LD_HOST_INT_STATUS		(0x1U)
+/* Host Control Registers : Download host interrupt status */
+#define DN_LD_HOST_INT_STATUS		(0x2U)
+
+/* Host Control Registers : Host interrupt RSR */
+#define HOST_INT_RSR_REG		0x01
+/* Host Control Registers : Upload host interrupt RSR */
+#define UP_LD_HOST_INT_RSR		(0x1U)
+#define SDIO_INT_MASK			0x3F
+
+/* Host Control Registers : Host interrupt status */
+#define HOST_INT_STATUS_REG		0x28
+/* Host Control Registers : Upload CRC error */
+#define UP_LD_CRC_ERR			(0x1U << 2)
+/* Host Control Registers : Upload restart */
+#define UP_LD_RESTART                   (0x1U << 1)
+/* Host Control Registers : Download restart */
+#define DN_LD_RESTART                   (0x1U << 0)
+
+/* Card Control Registers : Card status register */
+#define CARD_STATUS_REG                 0x30
+/* Card Control Registers : Card I/O ready */
+#define CARD_IO_READY                   (0x1U << 3)
+/* Card Control Registers : CIS card ready */
+#define CIS_CARD_RDY                    (0x1U << 2)
+/* Card Control Registers : Upload card ready */
+#define UP_LD_CARD_RDY                  (0x1U << 1)
+/* Card Control Registers : Download card ready */
+#define DN_LD_CARD_RDY                  (0x1U << 0)
+
+/* Card Control Registers : Host interrupt mask register */
+#define HOST_INTERRUPT_MASK_REG         0x34
+/* Card Control Registers : Host power interrupt mask */
+#define HOST_POWER_INT_MASK             (0x1U << 3)
+/* Card Control Registers : Abort card interrupt mask */
+#define ABORT_CARD_INT_MASK             (0x1U << 2)
+/* Card Control Registers : Upload card interrupt mask */
+#define UP_LD_CARD_INT_MASK             (0x1U << 1)
+/* Card Control Registers : Download card interrupt mask */
+#define DN_LD_CARD_INT_MASK             (0x1U << 0)
+
+/* Card Control Registers : Card interrupt status register */
+#define CARD_INTERRUPT_STATUS_REG       0x38
+/* Card Control Registers : Power up interrupt */
+#define POWER_UP_INT                    (0x1U << 4)
+/* Card Control Registers : Power down interrupt */
+#define POWER_DOWN_INT                  (0x1U << 3)
+
+/* Card Control Registers : Card interrupt RSR register */
+#define CARD_INTERRUPT_RSR_REG          0x3c
+/* Card Control Registers : Power up RSR */
+#define POWER_UP_RSR                    (0x1U << 4)
+/* Card Control Registers : Power down RSR */
+#define POWER_DOWN_RSR                  (0x1U << 3)
+
+/* Card Control Registers : Miscellaneous Configuration Register */
+#define CARD_MISC_CFG_REG               0x6C
+
+/* Host F1 read base 0 */
+#define HOST_F1_RD_BASE_0		0x0040
+/* Host F1 read base 1 */
+#define HOST_F1_RD_BASE_1		0x0041
+/* Host F1 card ready */
+#define HOST_F1_CARD_RDY		0x0020
+
+/* Firmware status 0 register */
+#define CARD_FW_STATUS0_REG		0x60
+/* Firmware status 1 register */
+#define CARD_FW_STATUS1_REG		0x61
+/* Rx length register */
+#define CARD_RX_LEN_REG			0x62
+/* Rx unit register */
+#define CARD_RX_UNIT_REG		0x63
+
+/* Event header len w/o 4 bytes of interface header */
+#define MWIFIEX_EVENT_HEADER_LEN           4
+
+/* Max retry number of CMD53 write */
+#define MAX_WRITE_IOMEM_RETRY		2
+
+/* SDIO Tx aggregation in progress ? */
+#define MP_TX_AGGR_IN_PROGRESS(a) (a->mpa_tx.pkt_cnt > 0)
+
+/* SDIO Tx aggregation buffer room for next packet ? */
+#define MP_TX_AGGR_BUF_HAS_ROOM(a, len) ((a->mpa_tx.buf_len+len)	\
+						<= a->mpa_tx.buf_size)
+
+/* Copy current packet (SDIO Tx aggregation buffer) to SDIO buffer */
+#define MP_TX_AGGR_BUF_PUT(a, payload, pkt_len, port) do {		\
+	memmove(&a->mpa_tx.buf[a->mpa_tx.buf_len],			\
+			payload, pkt_len);				\
+	a->mpa_tx.buf_len += pkt_len;					\
+	if (!a->mpa_tx.pkt_cnt)						\
+		a->mpa_tx.start_port = port;				\
+	if (a->mpa_tx.start_port <= port)				\
+		a->mpa_tx.ports |= (1<<(a->mpa_tx.pkt_cnt));		\
+	else								\
+		a->mpa_tx.ports |= (1<<(a->mpa_tx.pkt_cnt+1+(MAX_PORT -	\
+						a->mp_end_port)));	\
+	a->mpa_tx.pkt_cnt++;						\
+} while (0);
+
+/* SDIO Tx aggregation limit ? */
+#define MP_TX_AGGR_PKT_LIMIT_REACHED(a)					\
+			(a->mpa_tx.pkt_cnt == a->mpa_tx.pkt_aggr_limit)
+
+/* SDIO Tx aggregation port limit ? */
+#define MP_TX_AGGR_PORT_LIMIT_REACHED(a) ((a->curr_wr_port <		\
+			a->mpa_tx.start_port) && (((MAX_PORT -		\
+			a->mpa_tx.start_port) + a->curr_wr_port) >=	\
+				SDIO_MP_AGGR_DEF_PKT_LIMIT))
+
+/* Reset SDIO Tx aggregation buffer parameters */
+#define MP_TX_AGGR_BUF_RESET(a) do {					\
+	a->mpa_tx.pkt_cnt = 0;						\
+	a->mpa_tx.buf_len = 0;						\
+	a->mpa_tx.ports = 0;						\
+	a->mpa_tx.start_port = 0;					\
+} while (0);
+
+/* SDIO Rx aggregation limit ? */
+#define MP_RX_AGGR_PKT_LIMIT_REACHED(a)					\
+			(a->mpa_rx.pkt_cnt == a->mpa_rx.pkt_aggr_limit)
+
+/* SDIO Tx aggregation port limit ? */
+#define MP_RX_AGGR_PORT_LIMIT_REACHED(a) ((a->curr_rd_port <		\
+			a->mpa_rx.start_port) && (((MAX_PORT -		\
+			a->mpa_rx.start_port) + a->curr_rd_port) >=	\
+			SDIO_MP_AGGR_DEF_PKT_LIMIT))
+
+/* SDIO Rx aggregation in progress ? */
+#define MP_RX_AGGR_IN_PROGRESS(a) (a->mpa_rx.pkt_cnt > 0)
+
+/* SDIO Rx aggregation buffer room for next packet ? */
+#define MP_RX_AGGR_BUF_HAS_ROOM(a, rx_len)				\
+			((a->mpa_rx.buf_len+rx_len) <= a->mpa_rx.buf_size)
+
+/* Prepare to copy current packet from card to SDIO Rx aggregation buffer */
+#define MP_RX_AGGR_SETUP(a, skb, port) do {				\
+	a->mpa_rx.buf_len += skb->len;					\
+	if (!a->mpa_rx.pkt_cnt)						\
+		a->mpa_rx.start_port = port;				\
+	if (a->mpa_rx.start_port <= port)				\
+		a->mpa_rx.ports |= (1<<(a->mpa_rx.pkt_cnt));		\
+	else								\
+		a->mpa_rx.ports |= (1<<(a->mpa_rx.pkt_cnt+1));		\
+	a->mpa_rx.skb_arr[a->mpa_rx.pkt_cnt] = skb;			\
+	a->mpa_rx.len_arr[a->mpa_rx.pkt_cnt] = skb->len;		\
+	a->mpa_rx.pkt_cnt++;						\
+} while (0);
+
+/* Reset SDIO Rx aggregation buffer parameters */
+#define MP_RX_AGGR_BUF_RESET(a) do {					\
+	a->mpa_rx.pkt_cnt = 0;						\
+	a->mpa_rx.buf_len = 0;						\
+	a->mpa_rx.ports = 0;						\
+	a->mpa_rx.start_port = 0;					\
+} while (0);
+
+
+/* data structure for SDIO MPA TX */
+struct mwifiex_sdio_mpa_tx {
+	/* multiport tx aggregation buffer pointer */
+	u8 *buf;
+	u32 buf_len;
+	u32 pkt_cnt;
+	u16 ports;
+	u16 start_port;
+	u8 enabled;
+	u32 buf_size;
+	u32 pkt_aggr_limit;
+};
+
+struct mwifiex_sdio_mpa_rx {
+	u8 *buf;
+	u32 buf_len;
+	u32 pkt_cnt;
+	u16 ports;
+	u16 start_port;
+
+	struct sk_buff *skb_arr[SDIO_MP_AGGR_DEF_PKT_LIMIT];
+	u32 len_arr[SDIO_MP_AGGR_DEF_PKT_LIMIT];
+
+	u8 enabled;
+	u32 buf_size;
+	u32 pkt_aggr_limit;
+};
+
+int mwifiex_bus_register(void);
+void mwifiex_bus_unregister(void);
+
+struct sdio_mmc_card {
+	struct sdio_func *func;
+	struct mwifiex_adapter *adapter;
+
+	u16 mp_rd_bitmap;
+	u16 mp_wr_bitmap;
+
+	u16 mp_end_port;
+	u16 mp_data_port_mask;
+
+	u8 curr_rd_port;
+	u8 curr_wr_port;
+
+	u8 *mp_regs;
+
+	struct mwifiex_sdio_mpa_tx mpa_tx;
+	struct mwifiex_sdio_mpa_rx mpa_rx;
+};
+#endif /* _MWIFIEX_SDIO_H */
diff -druN linux-2.6.39-libre/drivers/net/wireless/mwifiex/sta_cmd.c linux-3.0-rc7-libre/drivers/net/wireless/mwifiex/sta_cmd.c
--- linux-2.6.39-libre/drivers/net/wireless/mwifiex/sta_cmd.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/net/wireless/mwifiex/sta_cmd.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,1219 @@
+/*
+ * Marvell Wireless LAN device driver: station command handling
+ *
+ * Copyright (C) 2011, Marvell International Ltd.
+ *
+ * This software file (the "File") is distributed by Marvell International
+ * Ltd. under the terms of the GNU General Public License Version 2, June 1991
+ * (the "License").  You may use, redistribute and/or modify this File in
+ * accordance with the terms and conditions of the License, a copy of which
+ * is available by writing to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
+ * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
+ *
+ * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
+ * ARE EXPRESSLY DISCLAIMED.  The License provides additional details about
+ * this warranty disclaimer.
+ */
+
+#include "decl.h"
+#include "ioctl.h"
+#include "util.h"
+#include "fw.h"
+#include "main.h"
+#include "wmm.h"
+#include "11n.h"
+
+/*
+ * This function prepares command to set/get RSSI information.
+ *
+ * Preparation includes -
+ *      - Setting command ID, action and proper size
+ *      - Setting data/beacon average factors
+ *      - Resetting SNR/NF/RSSI values in private structure
+ *      - Ensuring correct endian-ness
+ */
+static int
+mwifiex_cmd_802_11_rssi_info(struct mwifiex_private *priv,
+			     struct host_cmd_ds_command *cmd, u16 cmd_action)
+{
+	cmd->command = cpu_to_le16(HostCmd_CMD_RSSI_INFO);
+	cmd->size = cpu_to_le16(sizeof(struct host_cmd_ds_802_11_rssi_info) +
+				S_DS_GEN);
+	cmd->params.rssi_info.action = cpu_to_le16(cmd_action);
+	cmd->params.rssi_info.ndata = cpu_to_le16(priv->data_avg_factor);
+	cmd->params.rssi_info.nbcn = cpu_to_le16(priv->bcn_avg_factor);
+
+	/* Reset SNR/NF/RSSI values in private structure */
+	priv->data_rssi_last = 0;
+	priv->data_nf_last = 0;
+	priv->data_rssi_avg = 0;
+	priv->data_nf_avg = 0;
+	priv->bcn_rssi_last = 0;
+	priv->bcn_nf_last = 0;
+	priv->bcn_rssi_avg = 0;
+	priv->bcn_nf_avg = 0;
+
+	return 0;
+}
+
+/*
+ * This function prepares command to set MAC control.
+ *
+ * Preparation includes -
+ *      - Setting command ID, action and proper size
+ *      - Ensuring correct endian-ness
+ */
+static int mwifiex_cmd_mac_control(struct mwifiex_private *priv,
+				   struct host_cmd_ds_command *cmd,
+				   u16 cmd_action, void *data_buf)
+{
+	struct host_cmd_ds_mac_control *mac_ctrl = &cmd->params.mac_ctrl;
+	u16 action = *((u16 *) data_buf);
+
+	if (cmd_action != HostCmd_ACT_GEN_SET) {
+		dev_err(priv->adapter->dev,
+			"mac_control: only support set cmd\n");
+		return -1;
+	}
+
+	cmd->command = cpu_to_le16(HostCmd_CMD_MAC_CONTROL);
+	cmd->size =
+		cpu_to_le16(sizeof(struct host_cmd_ds_mac_control) + S_DS_GEN);
+	mac_ctrl->action = cpu_to_le16(action);
+
+	return 0;
+}
+
+/*
+ * This function prepares command to set/get SNMP MIB.
+ *
+ * Preparation includes -
+ *      - Setting command ID, action and proper size
+ *      - Setting SNMP MIB OID number and value
+ *        (as required)
+ *      - Ensuring correct endian-ness
+ *
+ * The following SNMP MIB OIDs are supported -
+ *      - FRAG_THRESH_I     : Fragmentation threshold
+ *      - RTS_THRESH_I      : RTS threshold
+ *      - SHORT_RETRY_LIM_I : Short retry limit
+ *      - DOT11D_I          : 11d support
+ */
+static int mwifiex_cmd_802_11_snmp_mib(struct mwifiex_private *priv,
+				       struct host_cmd_ds_command *cmd,
+				       u16 cmd_action, u32 cmd_oid,
+				       void *data_buf)
+{
+	struct host_cmd_ds_802_11_snmp_mib *snmp_mib = &cmd->params.smib;
+	u32 ul_temp;
+
+	dev_dbg(priv->adapter->dev, "cmd: SNMP_CMD: cmd_oid = 0x%x\n", cmd_oid);
+	cmd->command = cpu_to_le16(HostCmd_CMD_802_11_SNMP_MIB);
+	cmd->size = cpu_to_le16(sizeof(struct host_cmd_ds_802_11_snmp_mib)
+		- 1 + S_DS_GEN);
+
+	if (cmd_action == HostCmd_ACT_GEN_GET) {
+		snmp_mib->query_type = cpu_to_le16(HostCmd_ACT_GEN_GET);
+		snmp_mib->buf_size = cpu_to_le16(MAX_SNMP_BUF_SIZE);
+		cmd->size = cpu_to_le16(le16_to_cpu(cmd->size)
+			+ MAX_SNMP_BUF_SIZE);
+	}
+
+	switch (cmd_oid) {
+	case FRAG_THRESH_I:
+		snmp_mib->oid = cpu_to_le16((u16) FRAG_THRESH_I);
+		if (cmd_action == HostCmd_ACT_GEN_SET) {
+			snmp_mib->query_type = cpu_to_le16(HostCmd_ACT_GEN_SET);
+			snmp_mib->buf_size = cpu_to_le16(sizeof(u16));
+			ul_temp = *((u32 *) data_buf);
+			*((__le16 *) (snmp_mib->value)) =
+				cpu_to_le16((u16) ul_temp);
+			cmd->size = cpu_to_le16(le16_to_cpu(cmd->size)
+				+ sizeof(u16));
+		}
+		break;
+	case RTS_THRESH_I:
+		snmp_mib->oid = cpu_to_le16((u16) RTS_THRESH_I);
+		if (cmd_action == HostCmd_ACT_GEN_SET) {
+			snmp_mib->query_type = cpu_to_le16(HostCmd_ACT_GEN_SET);
+			snmp_mib->buf_size = cpu_to_le16(sizeof(u16));
+			ul_temp = *((u32 *) data_buf);
+			*(__le16 *) (snmp_mib->value) =
+				cpu_to_le16((u16) ul_temp);
+			cmd->size = cpu_to_le16(le16_to_cpu(cmd->size)
+				+ sizeof(u16));
+		}
+		break;
+
+	case SHORT_RETRY_LIM_I:
+		snmp_mib->oid = cpu_to_le16((u16) SHORT_RETRY_LIM_I);
+		if (cmd_action == HostCmd_ACT_GEN_SET) {
+			snmp_mib->query_type = cpu_to_le16(HostCmd_ACT_GEN_SET);
+			snmp_mib->buf_size = cpu_to_le16(sizeof(u16));
+			ul_temp = (*(u32 *) data_buf);
+			*((__le16 *) (snmp_mib->value)) =
+				cpu_to_le16((u16) ul_temp);
+			cmd->size = cpu_to_le16(le16_to_cpu(cmd->size)
+				+ sizeof(u16));
+		}
+		break;
+	case DOT11D_I:
+		snmp_mib->oid = cpu_to_le16((u16) DOT11D_I);
+		if (cmd_action == HostCmd_ACT_GEN_SET) {
+			snmp_mib->query_type = cpu_to_le16(HostCmd_ACT_GEN_SET);
+			snmp_mib->buf_size = cpu_to_le16(sizeof(u16));
+			ul_temp = *(u32 *) data_buf;
+			*((__le16 *) (snmp_mib->value)) =
+				cpu_to_le16((u16) ul_temp);
+			cmd->size = cpu_to_le16(le16_to_cpu(cmd->size)
+				+ sizeof(u16));
+		}
+		break;
+	default:
+		break;
+	}
+	dev_dbg(priv->adapter->dev,
+		"cmd: SNMP_CMD: Action=0x%x, OID=0x%x, OIDSize=0x%x,"
+		" Value=0x%x\n",
+	       cmd_action, cmd_oid, le16_to_cpu(snmp_mib->buf_size),
+	       le16_to_cpu(*(__le16 *) snmp_mib->value));
+	return 0;
+}
+
+/*
+ * This function prepares command to get log.
+ *
+ * Preparation includes -
+ *      - Setting command ID and proper size
+ *      - Ensuring correct endian-ness
+ */
+static int
+mwifiex_cmd_802_11_get_log(struct host_cmd_ds_command *cmd)
+{
+	cmd->command = cpu_to_le16(HostCmd_CMD_802_11_GET_LOG);
+	cmd->size = cpu_to_le16(sizeof(struct host_cmd_ds_802_11_get_log) +
+				S_DS_GEN);
+	return 0;
+}
+
+/*
+ * This function prepares command to set/get Tx data rate configuration.
+ *
+ * Preparation includes -
+ *      - Setting command ID, action and proper size
+ *      - Setting configuration index, rate scope and rate drop pattern
+ *        parameters (as required)
+ *      - Ensuring correct endian-ness
+ */
+static int mwifiex_cmd_tx_rate_cfg(struct mwifiex_private *priv,
+				   struct host_cmd_ds_command *cmd,
+				   u16 cmd_action, void *data_buf)
+{
+	struct host_cmd_ds_tx_rate_cfg *rate_cfg = &cmd->params.tx_rate_cfg;
+	struct mwifiex_rate_scope *rate_scope;
+	struct mwifiex_rate_drop_pattern *rate_drop;
+	u16 *pbitmap_rates = (u16 *) data_buf;
+
+	u32 i;
+
+	cmd->command = cpu_to_le16(HostCmd_CMD_TX_RATE_CFG);
+
+	rate_cfg->action = cpu_to_le16(cmd_action);
+	rate_cfg->cfg_index = 0;
+
+	rate_scope = (struct mwifiex_rate_scope *) ((u8 *) rate_cfg +
+		      sizeof(struct host_cmd_ds_tx_rate_cfg));
+	rate_scope->type = cpu_to_le16(TLV_TYPE_RATE_SCOPE);
+	rate_scope->length = cpu_to_le16(sizeof(struct mwifiex_rate_scope) -
+			sizeof(struct mwifiex_ie_types_header));
+	if (pbitmap_rates != NULL) {
+		rate_scope->hr_dsss_rate_bitmap = cpu_to_le16(pbitmap_rates[0]);
+		rate_scope->ofdm_rate_bitmap = cpu_to_le16(pbitmap_rates[1]);
+		for (i = 0;
+		     i < sizeof(rate_scope->ht_mcs_rate_bitmap) / sizeof(u16);
+		     i++)
+			rate_scope->ht_mcs_rate_bitmap[i] =
+				cpu_to_le16(pbitmap_rates[2 + i]);
+	} else {
+		rate_scope->hr_dsss_rate_bitmap =
+			cpu_to_le16(priv->bitmap_rates[0]);
+		rate_scope->ofdm_rate_bitmap =
+			cpu_to_le16(priv->bitmap_rates[1]);
+		for (i = 0;
+		     i < sizeof(rate_scope->ht_mcs_rate_bitmap) / sizeof(u16);
+		     i++)
+			rate_scope->ht_mcs_rate_bitmap[i] =
+				cpu_to_le16(priv->bitmap_rates[2 + i]);
+	}
+
+	rate_drop = (struct mwifiex_rate_drop_pattern *) ((u8 *) rate_scope +
+			sizeof(struct mwifiex_rate_scope));
+	rate_drop->type = cpu_to_le16(TLV_TYPE_RATE_DROP_CONTROL);
+	rate_drop->length = cpu_to_le16(sizeof(rate_drop->rate_drop_mode));
+	rate_drop->rate_drop_mode = 0;
+
+	cmd->size =
+		cpu_to_le16(S_DS_GEN + sizeof(struct host_cmd_ds_tx_rate_cfg) +
+			    sizeof(struct mwifiex_rate_scope) +
+			    sizeof(struct mwifiex_rate_drop_pattern));
+
+	return 0;
+}
+
+/*
+ * This function prepares command to set/get Tx power configuration.
+ *
+ * Preparation includes -
+ *      - Setting command ID, action and proper size
+ *      - Setting Tx power mode, power group TLV
+ *        (as required)
+ *      - Ensuring correct endian-ness
+ */
+static int mwifiex_cmd_tx_power_cfg(struct host_cmd_ds_command *cmd,
+				    u16 cmd_action, void *data_buf)
+{
+	struct mwifiex_types_power_group *pg_tlv;
+	struct host_cmd_ds_txpwr_cfg *txp;
+	struct host_cmd_ds_txpwr_cfg *cmd_txp_cfg = &cmd->params.txp_cfg;
+
+	cmd->command = cpu_to_le16(HostCmd_CMD_TXPWR_CFG);
+	cmd->size =
+		cpu_to_le16(S_DS_GEN + sizeof(struct host_cmd_ds_txpwr_cfg));
+	switch (cmd_action) {
+	case HostCmd_ACT_GEN_SET:
+		txp = (struct host_cmd_ds_txpwr_cfg *) data_buf;
+		if (txp->mode) {
+			pg_tlv = (struct mwifiex_types_power_group
+				  *) ((unsigned long) data_buf +
+				     sizeof(struct host_cmd_ds_txpwr_cfg));
+			memmove(cmd_txp_cfg, data_buf,
+				sizeof(struct host_cmd_ds_txpwr_cfg) +
+				sizeof(struct mwifiex_types_power_group) +
+				pg_tlv->length);
+
+			pg_tlv = (struct mwifiex_types_power_group *) ((u8 *)
+				  cmd_txp_cfg +
+				  sizeof(struct host_cmd_ds_txpwr_cfg));
+			cmd->size = cpu_to_le16(le16_to_cpu(cmd->size) +
+				  sizeof(struct mwifiex_types_power_group) +
+				  pg_tlv->length);
+		} else {
+			memmove(cmd_txp_cfg, data_buf,
+				sizeof(struct host_cmd_ds_txpwr_cfg));
+		}
+		cmd_txp_cfg->action = cpu_to_le16(cmd_action);
+		break;
+	case HostCmd_ACT_GEN_GET:
+		cmd_txp_cfg->action = cpu_to_le16(cmd_action);
+		break;
+	}
+
+	return 0;
+}
+
+/*
+ * This function prepares command to set Host Sleep configuration.
+ *
+ * Preparation includes -
+ *      - Setting command ID and proper size
+ *      - Setting Host Sleep action, conditions, ARP filters
+ *        (as required)
+ *      - Ensuring correct endian-ness
+ */
+static int mwifiex_cmd_802_11_hs_cfg(struct mwifiex_private *priv,
+				     struct host_cmd_ds_command *cmd,
+				     u16 cmd_action,
+				     struct mwifiex_hs_config_param *data_buf)
+{
+	struct mwifiex_adapter *adapter = priv->adapter;
+	struct host_cmd_ds_802_11_hs_cfg_enh *hs_cfg = &cmd->params.opt_hs_cfg;
+	u16 hs_activate = false;
+
+	if (data_buf == NULL)
+		/* New Activate command */
+		hs_activate = true;
+	cmd->command = cpu_to_le16(HostCmd_CMD_802_11_HS_CFG_ENH);
+
+	if (!hs_activate &&
+	    (data_buf->conditions
+	    != cpu_to_le32(HOST_SLEEP_CFG_CANCEL))
+	    && ((adapter->arp_filter_size > 0)
+		&& (adapter->arp_filter_size <= ARP_FILTER_MAX_BUF_SIZE))) {
+		dev_dbg(adapter->dev,
+			"cmd: Attach %d bytes ArpFilter to HSCfg cmd\n",
+		       adapter->arp_filter_size);
+		memcpy(((u8 *) hs_cfg) +
+		       sizeof(struct host_cmd_ds_802_11_hs_cfg_enh),
+		       adapter->arp_filter, adapter->arp_filter_size);
+		cmd->size = cpu_to_le16(adapter->arp_filter_size +
+				    sizeof(struct host_cmd_ds_802_11_hs_cfg_enh)
+				    + S_DS_GEN);
+	} else {
+		cmd->size = cpu_to_le16(S_DS_GEN + sizeof(struct
+					   host_cmd_ds_802_11_hs_cfg_enh));
+	}
+	if (hs_activate) {
+		hs_cfg->action = cpu_to_le16(HS_ACTIVATE);
+		hs_cfg->params.hs_activate.resp_ctrl = RESP_NEEDED;
+	} else {
+		hs_cfg->action = cpu_to_le16(HS_CONFIGURE);
+		hs_cfg->params.hs_config.conditions = data_buf->conditions;
+		hs_cfg->params.hs_config.gpio = data_buf->gpio;
+		hs_cfg->params.hs_config.gap = data_buf->gap;
+		dev_dbg(adapter->dev,
+			"cmd: HS_CFG_CMD: condition:0x%x gpio:0x%x gap:0x%x\n",
+		       hs_cfg->params.hs_config.conditions,
+		       hs_cfg->params.hs_config.gpio,
+		       hs_cfg->params.hs_config.gap);
+	}
+
+	return 0;
+}
+
+/*
+ * This function prepares command to set/get MAC address.
+ *
+ * Preparation includes -
+ *      - Setting command ID, action and proper size
+ *      - Setting MAC address (for SET only)
+ *      - Ensuring correct endian-ness
+ */
+static int mwifiex_cmd_802_11_mac_address(struct mwifiex_private *priv,
+					  struct host_cmd_ds_command *cmd,
+					  u16 cmd_action)
+{
+	cmd->command = cpu_to_le16(HostCmd_CMD_802_11_MAC_ADDRESS);
+	cmd->size = cpu_to_le16(sizeof(struct host_cmd_ds_802_11_mac_address) +
+				S_DS_GEN);
+	cmd->result = 0;
+
+	cmd->params.mac_addr.action = cpu_to_le16(cmd_action);
+
+	if (cmd_action == HostCmd_ACT_GEN_SET)
+		memcpy(cmd->params.mac_addr.mac_addr, priv->curr_addr,
+		       ETH_ALEN);
+	return 0;
+}
+
+/*
+ * This function prepares command to set MAC multicast address.
+ *
+ * Preparation includes -
+ *      - Setting command ID, action and proper size
+ *      - Setting MAC multicast address
+ *      - Ensuring correct endian-ness
+ */
+static int mwifiex_cmd_mac_multicast_adr(struct host_cmd_ds_command *cmd,
+					 u16 cmd_action, void *data_buf)
+{
+	struct mwifiex_multicast_list *mcast_list =
+		(struct mwifiex_multicast_list *) data_buf;
+	struct host_cmd_ds_mac_multicast_adr *mcast_addr = &cmd->params.mc_addr;
+
+	cmd->size = cpu_to_le16(sizeof(struct host_cmd_ds_mac_multicast_adr) +
+				S_DS_GEN);
+	cmd->command = cpu_to_le16(HostCmd_CMD_MAC_MULTICAST_ADR);
+
+	mcast_addr->action = cpu_to_le16(cmd_action);
+	mcast_addr->num_of_adrs =
+		cpu_to_le16((u16) mcast_list->num_multicast_addr);
+	memcpy(mcast_addr->mac_list, mcast_list->mac_list,
+	       mcast_list->num_multicast_addr * ETH_ALEN);
+
+	return 0;
+}
+
+/*
+ * This function prepares command to deauthenticate.
+ *
+ * Preparation includes -
+ *      - Setting command ID and proper size
+ *      - Setting AP MAC address and reason code
+ *      - Ensuring correct endian-ness
+ */
+static int mwifiex_cmd_802_11_deauthenticate(struct mwifiex_private *priv,
+					     struct host_cmd_ds_command *cmd,
+					     void *data_buf)
+{
+	struct host_cmd_ds_802_11_deauthenticate *deauth = &cmd->params.deauth;
+
+	cmd->command = cpu_to_le16(HostCmd_CMD_802_11_DEAUTHENTICATE);
+	cmd->size = cpu_to_le16(sizeof(struct host_cmd_ds_802_11_deauthenticate)
+				+ S_DS_GEN);
+
+	/* Set AP MAC address */
+	memcpy(deauth->mac_addr, (u8 *) data_buf, ETH_ALEN);
+
+	dev_dbg(priv->adapter->dev, "cmd: Deauth: %pM\n", deauth->mac_addr);
+
+	deauth->reason_code = cpu_to_le16(WLAN_REASON_DEAUTH_LEAVING);
+
+	return 0;
+}
+
+/*
+ * This function prepares command to stop Ad-Hoc network.
+ *
+ * Preparation includes -
+ *      - Setting command ID and proper size
+ *      - Ensuring correct endian-ness
+ */
+static int mwifiex_cmd_802_11_ad_hoc_stop(struct host_cmd_ds_command *cmd)
+{
+	cmd->command = cpu_to_le16(HostCmd_CMD_802_11_AD_HOC_STOP);
+	cmd->size = cpu_to_le16(S_DS_GEN);
+	return 0;
+}
+
+/*
+ * This function sets WEP key(s) to key parameter TLV(s).
+ *
+ * Multi-key parameter TLVs are supported, so we can send multiple
+ * WEP keys in a single buffer.
+ */
+static int
+mwifiex_set_keyparamset_wep(struct mwifiex_private *priv,
+			    struct mwifiex_ie_type_key_param_set *key_param_set,
+			    u16 *key_param_len)
+{
+	int cur_key_param_len;
+	u8 i;
+
+	/* Multi-key_param_set TLV is supported */
+	for (i = 0; i < NUM_WEP_KEYS; i++) {
+		if ((priv->wep_key[i].key_length == WLAN_KEY_LEN_WEP40) ||
+		    (priv->wep_key[i].key_length == WLAN_KEY_LEN_WEP104)) {
+			key_param_set->type =
+				cpu_to_le16(TLV_TYPE_KEY_MATERIAL);
+/* Key_param_set WEP fixed length */
+#define KEYPARAMSET_WEP_FIXED_LEN 8
+			key_param_set->length = cpu_to_le16((u16)
+					(priv->wep_key[i].
+					 key_length +
+					 KEYPARAMSET_WEP_FIXED_LEN));
+			key_param_set->key_type_id =
+				cpu_to_le16(KEY_TYPE_ID_WEP);
+			key_param_set->key_info =
+				cpu_to_le16(KEY_ENABLED | KEY_UNICAST |
+					    KEY_MCAST);
+			key_param_set->key_len =
+				cpu_to_le16(priv->wep_key[i].key_length);
+			/* Set WEP key index */
+			key_param_set->key[0] = i;
+			/* Set default Tx key flag */
+			if (i ==
+			    (priv->
+			     wep_key_curr_index & HostCmd_WEP_KEY_INDEX_MASK))
+				key_param_set->key[1] = 1;
+			else
+				key_param_set->key[1] = 0;
+			memmove(&key_param_set->key[2],
+				priv->wep_key[i].key_material,
+				priv->wep_key[i].key_length);
+
+			cur_key_param_len = priv->wep_key[i].key_length +
+				KEYPARAMSET_WEP_FIXED_LEN +
+				sizeof(struct mwifiex_ie_types_header);
+			*key_param_len += (u16) cur_key_param_len;
+			key_param_set =
+				(struct mwifiex_ie_type_key_param_set *)
+						((u8 *)key_param_set +
+						cur_key_param_len);
+		} else if (!priv->wep_key[i].key_length) {
+			continue;
+		} else {
+			dev_err(priv->adapter->dev,
+				"key%d Length = %d is incorrect\n",
+			       (i + 1), priv->wep_key[i].key_length);
+			return -1;
+		}
+	}
+
+	return 0;
+}
+
+/*
+ * This function prepares command to set/get/reset network key(s).
+ *
+ * Preparation includes -
+ *      - Setting command ID, action and proper size
+ *      - Setting WEP keys, WAPI keys or WPA keys along with required
+ *        encryption (TKIP, AES) (as required)
+ *      - Ensuring correct endian-ness
+ */
+static int mwifiex_cmd_802_11_key_material(struct mwifiex_private *priv,
+					   struct host_cmd_ds_command *cmd,
+					   u16 cmd_action,
+					   u32 cmd_oid, void *data_buf)
+{
+	struct host_cmd_ds_802_11_key_material *key_material =
+		&cmd->params.key_material;
+	struct mwifiex_ds_encrypt_key *enc_key =
+		(struct mwifiex_ds_encrypt_key *) data_buf;
+	u16 key_param_len = 0;
+	int ret = 0;
+	const u8 bc_mac[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
+
+	cmd->command = cpu_to_le16(HostCmd_CMD_802_11_KEY_MATERIAL);
+	key_material->action = cpu_to_le16(cmd_action);
+
+	if (cmd_action == HostCmd_ACT_GEN_GET) {
+		cmd->size =
+			cpu_to_le16(sizeof(key_material->action) + S_DS_GEN);
+		return ret;
+	}
+
+	if (!enc_key) {
+		memset(&key_material->key_param_set, 0,
+		       (NUM_WEP_KEYS *
+			sizeof(struct mwifiex_ie_type_key_param_set)));
+		ret = mwifiex_set_keyparamset_wep(priv,
+						  &key_material->key_param_set,
+						  &key_param_len);
+		cmd->size = cpu_to_le16(key_param_len +
+				    sizeof(key_material->action) + S_DS_GEN);
+		return ret;
+	} else
+		memset(&key_material->key_param_set, 0,
+		       sizeof(struct mwifiex_ie_type_key_param_set));
+	if (enc_key->is_wapi_key) {
+		dev_dbg(priv->adapter->dev, "info: Set WAPI Key\n");
+		key_material->key_param_set.key_type_id =
+			cpu_to_le16(KEY_TYPE_ID_WAPI);
+		if (cmd_oid == KEY_INFO_ENABLED)
+			key_material->key_param_set.key_info =
+				cpu_to_le16(KEY_ENABLED);
+		else
+			key_material->key_param_set.key_info =
+				cpu_to_le16(!KEY_ENABLED);
+
+		key_material->key_param_set.key[0] = enc_key->key_index;
+		if (!priv->sec_info.wapi_key_on)
+			key_material->key_param_set.key[1] = 1;
+		else
+			/* set 0 when re-key */
+			key_material->key_param_set.key[1] = 0;
+
+		if (0 != memcmp(enc_key->mac_addr, bc_mac, sizeof(bc_mac))) {
+			/* WAPI pairwise key: unicast */
+			key_material->key_param_set.key_info |=
+				cpu_to_le16(KEY_UNICAST);
+		} else {	/* WAPI group key: multicast */
+			key_material->key_param_set.key_info |=
+				cpu_to_le16(KEY_MCAST);
+			priv->sec_info.wapi_key_on = true;
+		}
+
+		key_material->key_param_set.type =
+			cpu_to_le16(TLV_TYPE_KEY_MATERIAL);
+		key_material->key_param_set.key_len =
+			cpu_to_le16(WAPI_KEY_LEN);
+		memcpy(&key_material->key_param_set.key[2],
+		       enc_key->key_material, enc_key->key_len);
+		memcpy(&key_material->key_param_set.key[2 + enc_key->key_len],
+		       enc_key->wapi_rxpn, WAPI_RXPN_LEN);
+		key_material->key_param_set.length =
+			cpu_to_le16(WAPI_KEY_LEN + KEYPARAMSET_FIXED_LEN);
+
+		key_param_len = (WAPI_KEY_LEN + KEYPARAMSET_FIXED_LEN) +
+				 sizeof(struct mwifiex_ie_types_header);
+		cmd->size = cpu_to_le16(key_param_len +
+				sizeof(key_material->action) + S_DS_GEN);
+		return ret;
+	}
+	if (enc_key->key_len == WLAN_KEY_LEN_CCMP) {
+		dev_dbg(priv->adapter->dev, "cmd: WPA_AES\n");
+		key_material->key_param_set.key_type_id =
+			cpu_to_le16(KEY_TYPE_ID_AES);
+		if (cmd_oid == KEY_INFO_ENABLED)
+			key_material->key_param_set.key_info =
+				cpu_to_le16(KEY_ENABLED);
+		else
+			key_material->key_param_set.key_info =
+				cpu_to_le16(!KEY_ENABLED);
+
+		if (enc_key->key_index & MWIFIEX_KEY_INDEX_UNICAST)
+				/* AES pairwise key: unicast */
+			key_material->key_param_set.key_info |=
+				cpu_to_le16(KEY_UNICAST);
+		else		/* AES group key: multicast */
+			key_material->key_param_set.key_info |=
+				cpu_to_le16(KEY_MCAST);
+	} else if (enc_key->key_len == WLAN_KEY_LEN_TKIP) {
+		dev_dbg(priv->adapter->dev, "cmd: WPA_TKIP\n");
+		key_material->key_param_set.key_type_id =
+			cpu_to_le16(KEY_TYPE_ID_TKIP);
+		key_material->key_param_set.key_info =
+			cpu_to_le16(KEY_ENABLED);
+
+		if (enc_key->key_index & MWIFIEX_KEY_INDEX_UNICAST)
+				/* TKIP pairwise key: unicast */
+			key_material->key_param_set.key_info |=
+				cpu_to_le16(KEY_UNICAST);
+		else		/* TKIP group key: multicast */
+			key_material->key_param_set.key_info |=
+				cpu_to_le16(KEY_MCAST);
+	}
+
+	if (key_material->key_param_set.key_type_id) {
+		key_material->key_param_set.type =
+			cpu_to_le16(TLV_TYPE_KEY_MATERIAL);
+		key_material->key_param_set.key_len =
+			cpu_to_le16((u16) enc_key->key_len);
+		memcpy(key_material->key_param_set.key, enc_key->key_material,
+		       enc_key->key_len);
+		key_material->key_param_set.length =
+			cpu_to_le16((u16) enc_key->key_len +
+				    KEYPARAMSET_FIXED_LEN);
+
+		key_param_len = (u16) (enc_key->key_len + KEYPARAMSET_FIXED_LEN)
+				      + sizeof(struct mwifiex_ie_types_header);
+
+		cmd->size = cpu_to_le16(key_param_len +
+				    sizeof(key_material->action) + S_DS_GEN);
+	}
+
+	return ret;
+}
+
+/*
+ * This function prepares command to set/get 11d domain information.
+ *
+ * Preparation includes -
+ *      - Setting command ID, action and proper size
+ *      - Setting domain information fields (for SET only)
+ *      - Ensuring correct endian-ness
+ */
+static int mwifiex_cmd_802_11d_domain_info(struct mwifiex_private *priv,
+					   struct host_cmd_ds_command *cmd,
+					   u16 cmd_action)
+{
+	struct mwifiex_adapter *adapter = priv->adapter;
+	struct host_cmd_ds_802_11d_domain_info *domain_info =
+		&cmd->params.domain_info;
+	struct mwifiex_ietypes_domain_param_set *domain =
+		&domain_info->domain;
+	u8 no_of_triplet = adapter->domain_reg.no_of_triplet;
+
+	dev_dbg(adapter->dev, "info: 11D: no_of_triplet=0x%x\n", no_of_triplet);
+
+	cmd->command = cpu_to_le16(HostCmd_CMD_802_11D_DOMAIN_INFO);
+	domain_info->action = cpu_to_le16(cmd_action);
+	if (cmd_action == HostCmd_ACT_GEN_GET) {
+		cmd->size = cpu_to_le16(sizeof(domain_info->action) + S_DS_GEN);
+		return 0;
+	}
+
+	/* Set domain info fields */
+	domain->header.type = cpu_to_le16(WLAN_EID_COUNTRY);
+	memcpy(domain->country_code, adapter->domain_reg.country_code,
+			sizeof(domain->country_code));
+
+	domain->header.len = cpu_to_le16((no_of_triplet *
+				sizeof(struct ieee80211_country_ie_triplet)) +
+				sizeof(domain->country_code));
+
+	if (no_of_triplet) {
+		memcpy(domain->triplet, adapter->domain_reg.triplet,
+				no_of_triplet *
+				sizeof(struct ieee80211_country_ie_triplet));
+
+		cmd->size = cpu_to_le16(sizeof(domain_info->action) +
+				le16_to_cpu(domain->header.len) +
+				sizeof(struct mwifiex_ie_types_header)
+				+ S_DS_GEN);
+	} else {
+		cmd->size = cpu_to_le16(sizeof(domain_info->action) + S_DS_GEN);
+	}
+
+	return 0;
+}
+
+/*
+ * This function prepares command to set/get RF channel.
+ *
+ * Preparation includes -
+ *      - Setting command ID, action and proper size
+ *      - Setting RF type and current RF channel (for SET only)
+ *      - Ensuring correct endian-ness
+ */
+static int mwifiex_cmd_802_11_rf_channel(struct mwifiex_private *priv,
+					 struct host_cmd_ds_command *cmd,
+					 u16 cmd_action, void *data_buf)
+{
+	struct host_cmd_ds_802_11_rf_channel *rf_chan =
+		&cmd->params.rf_channel;
+	uint16_t rf_type = le16_to_cpu(rf_chan->rf_type);
+
+	cmd->command = cpu_to_le16(HostCmd_CMD_802_11_RF_CHANNEL);
+	cmd->size = cpu_to_le16(sizeof(struct host_cmd_ds_802_11_rf_channel)
+				+ S_DS_GEN);
+
+	if (cmd_action == HostCmd_ACT_GEN_SET) {
+		if ((priv->adapter->adhoc_start_band & BAND_A)
+		    || (priv->adapter->adhoc_start_band & BAND_AN))
+			rf_chan->rf_type =
+				cpu_to_le16(HostCmd_SCAN_RADIO_TYPE_A);
+
+		rf_type = le16_to_cpu(rf_chan->rf_type);
+		SET_SECONDARYCHAN(rf_type, priv->adapter->chan_offset);
+		rf_chan->current_channel = cpu_to_le16(*((u16 *) data_buf));
+	}
+	rf_chan->action = cpu_to_le16(cmd_action);
+	return 0;
+}
+
+/*
+ * This function prepares command to set/get IBSS coalescing status.
+ *
+ * Preparation includes -
+ *      - Setting command ID, action and proper size
+ *      - Setting status to enable or disable (for SET only)
+ *      - Ensuring correct endian-ness
+ */
+static int mwifiex_cmd_ibss_coalescing_status(struct host_cmd_ds_command *cmd,
+					      u16 cmd_action, void *data_buf)
+{
+	struct host_cmd_ds_802_11_ibss_status *ibss_coal =
+		&(cmd->params.ibss_coalescing);
+	u16 enable = 0;
+
+	cmd->command = cpu_to_le16(HostCmd_CMD_802_11_IBSS_COALESCING_STATUS);
+	cmd->size = cpu_to_le16(sizeof(struct host_cmd_ds_802_11_ibss_status) +
+				S_DS_GEN);
+	cmd->result = 0;
+	ibss_coal->action = cpu_to_le16(cmd_action);
+
+	switch (cmd_action) {
+	case HostCmd_ACT_GEN_SET:
+		if (data_buf != NULL)
+			enable = *(u16 *) data_buf;
+		ibss_coal->enable = cpu_to_le16(enable);
+		break;
+
+		/* In other case.. Nothing to do */
+	case HostCmd_ACT_GEN_GET:
+	default:
+		break;
+	}
+
+	return 0;
+}
+
+/*
+ * This function prepares command to set/get register value.
+ *
+ * Preparation includes -
+ *      - Setting command ID, action and proper size
+ *      - Setting register offset (for both GET and SET) and
+ *        register value (for SET only)
+ *      - Ensuring correct endian-ness
+ *
+ * The following type of registers can be accessed with this function -
+ *      - MAC register
+ *      - BBP register
+ *      - RF register
+ *      - PMIC register
+ *      - CAU register
+ *      - EEPROM
+ */
+static int mwifiex_cmd_reg_access(struct host_cmd_ds_command *cmd,
+				  u16 cmd_action, void *data_buf)
+{
+	struct mwifiex_ds_reg_rw *reg_rw;
+
+	reg_rw = (struct mwifiex_ds_reg_rw *) data_buf;
+	switch (le16_to_cpu(cmd->command)) {
+	case HostCmd_CMD_MAC_REG_ACCESS:
+	{
+		struct host_cmd_ds_mac_reg_access *mac_reg;
+
+		cmd->size = cpu_to_le16(sizeof(*mac_reg) + S_DS_GEN);
+		mac_reg = (struct host_cmd_ds_mac_reg_access *) &cmd->
+			params.mac_reg;
+		mac_reg->action = cpu_to_le16(cmd_action);
+		mac_reg->offset =
+			cpu_to_le16((u16) le32_to_cpu(reg_rw->offset));
+		mac_reg->value = reg_rw->value;
+		break;
+	}
+	case HostCmd_CMD_BBP_REG_ACCESS:
+	{
+		struct host_cmd_ds_bbp_reg_access *bbp_reg;
+
+		cmd->size = cpu_to_le16(sizeof(*bbp_reg) + S_DS_GEN);
+		bbp_reg = (struct host_cmd_ds_bbp_reg_access *) &cmd->
+			params.bbp_reg;
+		bbp_reg->action = cpu_to_le16(cmd_action);
+		bbp_reg->offset =
+			cpu_to_le16((u16) le32_to_cpu(reg_rw->offset));
+		bbp_reg->value = (u8) le32_to_cpu(reg_rw->value);
+		break;
+	}
+	case HostCmd_CMD_RF_REG_ACCESS:
+	{
+		struct host_cmd_ds_rf_reg_access *rf_reg;
+
+		cmd->size = cpu_to_le16(sizeof(*rf_reg) + S_DS_GEN);
+		rf_reg = (struct host_cmd_ds_rf_reg_access *) &cmd->
+			params.rf_reg;
+		rf_reg->action = cpu_to_le16(cmd_action);
+		rf_reg->offset =
+			cpu_to_le16((u16) le32_to_cpu(reg_rw->offset));
+		rf_reg->value = (u8) le32_to_cpu(reg_rw->value);
+		break;
+	}
+	case HostCmd_CMD_PMIC_REG_ACCESS:
+	{
+		struct host_cmd_ds_pmic_reg_access *pmic_reg;
+
+		cmd->size = cpu_to_le16(sizeof(*pmic_reg) + S_DS_GEN);
+		pmic_reg = (struct host_cmd_ds_pmic_reg_access *) &cmd->
+				params.pmic_reg;
+		pmic_reg->action = cpu_to_le16(cmd_action);
+		pmic_reg->offset =
+			cpu_to_le16((u16) le32_to_cpu(reg_rw->offset));
+		pmic_reg->value = (u8) le32_to_cpu(reg_rw->value);
+		break;
+	}
+	case HostCmd_CMD_CAU_REG_ACCESS:
+	{
+		struct host_cmd_ds_rf_reg_access *cau_reg;
+
+		cmd->size = cpu_to_le16(sizeof(*cau_reg) + S_DS_GEN);
+		cau_reg = (struct host_cmd_ds_rf_reg_access *) &cmd->
+				params.rf_reg;
+		cau_reg->action = cpu_to_le16(cmd_action);
+		cau_reg->offset =
+			cpu_to_le16((u16) le32_to_cpu(reg_rw->offset));
+		cau_reg->value = (u8) le32_to_cpu(reg_rw->value);
+		break;
+	}
+	case HostCmd_CMD_802_11_EEPROM_ACCESS:
+	{
+		struct mwifiex_ds_read_eeprom *rd_eeprom =
+			(struct mwifiex_ds_read_eeprom *) data_buf;
+		struct host_cmd_ds_802_11_eeprom_access *cmd_eeprom =
+			(struct host_cmd_ds_802_11_eeprom_access *)
+			&cmd->params.eeprom;
+
+		cmd->size = cpu_to_le16(sizeof(*cmd_eeprom) + S_DS_GEN);
+		cmd_eeprom->action = cpu_to_le16(cmd_action);
+		cmd_eeprom->offset = rd_eeprom->offset;
+		cmd_eeprom->byte_count = rd_eeprom->byte_count;
+		cmd_eeprom->value = 0;
+		break;
+	}
+	default:
+		return -1;
+	}
+
+	return 0;
+}
+
+/*
+ * This function prepares the commands before sending them to the firmware.
+ *
+ * This is a generic function which calls specific command preparation
+ * routines based upon the command number.
+ */
+int mwifiex_sta_prepare_cmd(struct mwifiex_private *priv, uint16_t cmd_no,
+			    u16 cmd_action, u32 cmd_oid,
+			    void *data_buf, void *cmd_buf)
+{
+	struct host_cmd_ds_command *cmd_ptr =
+		(struct host_cmd_ds_command *) cmd_buf;
+	int ret = 0;
+
+	/* Prepare command */
+	switch (cmd_no) {
+	case HostCmd_CMD_GET_HW_SPEC:
+		ret = mwifiex_cmd_get_hw_spec(priv, cmd_ptr);
+		break;
+	case HostCmd_CMD_MAC_CONTROL:
+		ret = mwifiex_cmd_mac_control(priv, cmd_ptr, cmd_action,
+					      data_buf);
+		break;
+	case HostCmd_CMD_802_11_MAC_ADDRESS:
+		ret = mwifiex_cmd_802_11_mac_address(priv, cmd_ptr,
+						     cmd_action);
+		break;
+	case HostCmd_CMD_MAC_MULTICAST_ADR:
+		ret = mwifiex_cmd_mac_multicast_adr(cmd_ptr, cmd_action,
+						    data_buf);
+		break;
+	case HostCmd_CMD_TX_RATE_CFG:
+		ret = mwifiex_cmd_tx_rate_cfg(priv, cmd_ptr, cmd_action,
+					      data_buf);
+		break;
+	case HostCmd_CMD_TXPWR_CFG:
+		ret = mwifiex_cmd_tx_power_cfg(cmd_ptr, cmd_action,
+					       data_buf);
+		break;
+	case HostCmd_CMD_802_11_PS_MODE_ENH:
+		ret = mwifiex_cmd_enh_power_mode(priv, cmd_ptr, cmd_action,
+						 (uint16_t)cmd_oid, data_buf);
+		break;
+	case HostCmd_CMD_802_11_HS_CFG_ENH:
+		ret = mwifiex_cmd_802_11_hs_cfg(priv, cmd_ptr, cmd_action,
+				(struct mwifiex_hs_config_param *) data_buf);
+		break;
+	case HostCmd_CMD_802_11_SCAN:
+		ret = mwifiex_cmd_802_11_scan(cmd_ptr, data_buf);
+		break;
+	case HostCmd_CMD_802_11_BG_SCAN_QUERY:
+		ret = mwifiex_cmd_802_11_bg_scan_query(cmd_ptr);
+		break;
+	case HostCmd_CMD_802_11_ASSOCIATE:
+		ret = mwifiex_cmd_802_11_associate(priv, cmd_ptr, data_buf);
+		break;
+	case HostCmd_CMD_802_11_DEAUTHENTICATE:
+		ret = mwifiex_cmd_802_11_deauthenticate(priv, cmd_ptr,
+							data_buf);
+		break;
+	case HostCmd_CMD_802_11_AD_HOC_START:
+		ret = mwifiex_cmd_802_11_ad_hoc_start(priv, cmd_ptr,
+						      data_buf);
+		break;
+	case HostCmd_CMD_802_11_GET_LOG:
+		ret = mwifiex_cmd_802_11_get_log(cmd_ptr);
+		break;
+	case HostCmd_CMD_802_11_AD_HOC_JOIN:
+		ret = mwifiex_cmd_802_11_ad_hoc_join(priv, cmd_ptr,
+						     data_buf);
+		break;
+	case HostCmd_CMD_802_11_AD_HOC_STOP:
+		ret = mwifiex_cmd_802_11_ad_hoc_stop(cmd_ptr);
+		break;
+	case HostCmd_CMD_RSSI_INFO:
+		ret = mwifiex_cmd_802_11_rssi_info(priv, cmd_ptr, cmd_action);
+		break;
+	case HostCmd_CMD_802_11_SNMP_MIB:
+		ret = mwifiex_cmd_802_11_snmp_mib(priv, cmd_ptr, cmd_action,
+						  cmd_oid, data_buf);
+		break;
+	case HostCmd_CMD_802_11_TX_RATE_QUERY:
+		cmd_ptr->command =
+			cpu_to_le16(HostCmd_CMD_802_11_TX_RATE_QUERY);
+		cmd_ptr->size =
+			cpu_to_le16(sizeof(struct host_cmd_ds_tx_rate_query) +
+				    S_DS_GEN);
+		priv->tx_rate = 0;
+		ret = 0;
+		break;
+	case HostCmd_CMD_VERSION_EXT:
+		cmd_ptr->command = cpu_to_le16(cmd_no);
+		cmd_ptr->params.verext.version_str_sel =
+			(u8) (*((u32 *) data_buf));
+		memcpy(&cmd_ptr->params, data_buf,
+		       sizeof(struct host_cmd_ds_version_ext));
+		cmd_ptr->size =
+			cpu_to_le16(sizeof(struct host_cmd_ds_version_ext) +
+				    S_DS_GEN);
+		ret = 0;
+		break;
+	case HostCmd_CMD_802_11_RF_CHANNEL:
+		ret = mwifiex_cmd_802_11_rf_channel(priv, cmd_ptr, cmd_action,
+						    data_buf);
+		break;
+	case HostCmd_CMD_FUNC_INIT:
+		if (priv->adapter->hw_status == MWIFIEX_HW_STATUS_RESET)
+			priv->adapter->hw_status = MWIFIEX_HW_STATUS_READY;
+		cmd_ptr->command = cpu_to_le16(cmd_no);
+		cmd_ptr->size = cpu_to_le16(S_DS_GEN);
+		break;
+	case HostCmd_CMD_FUNC_SHUTDOWN:
+		priv->adapter->hw_status = MWIFIEX_HW_STATUS_RESET;
+		cmd_ptr->command = cpu_to_le16(cmd_no);
+		cmd_ptr->size = cpu_to_le16(S_DS_GEN);
+		break;
+	case HostCmd_CMD_11N_ADDBA_REQ:
+		ret = mwifiex_cmd_11n_addba_req(cmd_ptr, data_buf);
+		break;
+	case HostCmd_CMD_11N_DELBA:
+		ret = mwifiex_cmd_11n_delba(cmd_ptr, data_buf);
+		break;
+	case HostCmd_CMD_11N_ADDBA_RSP:
+		ret = mwifiex_cmd_11n_addba_rsp_gen(priv, cmd_ptr, data_buf);
+		break;
+	case HostCmd_CMD_802_11_KEY_MATERIAL:
+		ret = mwifiex_cmd_802_11_key_material(priv, cmd_ptr,
+						cmd_action, cmd_oid,
+						data_buf);
+		break;
+	case HostCmd_CMD_802_11D_DOMAIN_INFO:
+		ret = mwifiex_cmd_802_11d_domain_info(priv, cmd_ptr,
+						cmd_action);
+		break;
+	case HostCmd_CMD_RECONFIGURE_TX_BUFF:
+		ret = mwifiex_cmd_recfg_tx_buf(priv, cmd_ptr, cmd_action,
+					       data_buf);
+		break;
+	case HostCmd_CMD_AMSDU_AGGR_CTRL:
+		ret = mwifiex_cmd_amsdu_aggr_ctrl(cmd_ptr, cmd_action,
+						  data_buf);
+		break;
+	case HostCmd_CMD_11N_CFG:
+		ret = mwifiex_cmd_11n_cfg(cmd_ptr, cmd_action,
+					  data_buf);
+		break;
+	case HostCmd_CMD_WMM_GET_STATUS:
+		dev_dbg(priv->adapter->dev,
+			"cmd: WMM: WMM_GET_STATUS cmd sent\n");
+		cmd_ptr->command = cpu_to_le16(HostCmd_CMD_WMM_GET_STATUS);
+		cmd_ptr->size =
+			cpu_to_le16(sizeof(struct host_cmd_ds_wmm_get_status) +
+				    S_DS_GEN);
+		ret = 0;
+		break;
+	case HostCmd_CMD_802_11_IBSS_COALESCING_STATUS:
+		ret = mwifiex_cmd_ibss_coalescing_status(cmd_ptr, cmd_action,
+							 data_buf);
+		break;
+	case HostCmd_CMD_MAC_REG_ACCESS:
+	case HostCmd_CMD_BBP_REG_ACCESS:
+	case HostCmd_CMD_RF_REG_ACCESS:
+	case HostCmd_CMD_PMIC_REG_ACCESS:
+	case HostCmd_CMD_CAU_REG_ACCESS:
+	case HostCmd_CMD_802_11_EEPROM_ACCESS:
+		ret = mwifiex_cmd_reg_access(cmd_ptr, cmd_action, data_buf);
+		break;
+	case HostCmd_CMD_SET_BSS_MODE:
+		cmd_ptr->command = cpu_to_le16(cmd_no);
+		if (priv->bss_mode == NL80211_IFTYPE_ADHOC)
+			cmd_ptr->params.bss_mode.con_type =
+				CONNECTION_TYPE_ADHOC;
+		else if (priv->bss_mode == NL80211_IFTYPE_STATION)
+			cmd_ptr->params.bss_mode.con_type =
+				CONNECTION_TYPE_INFRA;
+		cmd_ptr->size = cpu_to_le16(sizeof(struct
+				host_cmd_ds_set_bss_mode) + S_DS_GEN);
+		ret = 0;
+		break;
+	default:
+		dev_err(priv->adapter->dev,
+			"PREP_CMD: unknown cmd- %#x\n", cmd_no);
+		ret = -1;
+		break;
+	}
+	return ret;
+}
+
+/*
+ * This function issues commands to initialize firmware.
+ *
+ * This is called after firmware download to bring the card to
+ * working state.
+ *
+ * The following commands are issued sequentially -
+ *      - Function init (for first interface only)
+ *      - Read MAC address (for first interface only)
+ *      - Reconfigure Tx buffer size (for first interface only)
+ *      - Enable auto deep sleep (for first interface only)
+ *      - Get Tx rate
+ *      - Get Tx power
+ *      - Set IBSS coalescing status
+ *      - Set AMSDU aggregation control
+ *      - Set 11d control
+ *      - Set MAC control (this must be the last command to initialize firmware)
+ */
+int mwifiex_sta_init_cmd(struct mwifiex_private *priv, u8 first_sta)
+{
+	int ret;
+	u16 enable = true;
+	struct mwifiex_ds_11n_amsdu_aggr_ctrl amsdu_aggr_ctrl;
+	struct mwifiex_ds_auto_ds auto_ds;
+	enum state_11d_t state_11d;
+
+	if (first_sta) {
+
+		ret = mwifiex_send_cmd_async(priv, HostCmd_CMD_FUNC_INIT,
+					     HostCmd_ACT_GEN_SET, 0, NULL);
+		if (ret)
+			return -1;
+		/* Read MAC address from HW */
+		ret = mwifiex_send_cmd_async(priv, HostCmd_CMD_GET_HW_SPEC,
+					     HostCmd_ACT_GEN_GET, 0, NULL);
+		if (ret)
+			return -1;
+
+		/* Reconfigure tx buf size */
+		ret = mwifiex_send_cmd_async(priv,
+					     HostCmd_CMD_RECONFIGURE_TX_BUFF,
+					     HostCmd_ACT_GEN_SET, 0,
+					     &priv->adapter->tx_buf_size);
+		if (ret)
+			return -1;
+
+		/* Enable IEEE PS by default */
+		priv->adapter->ps_mode = MWIFIEX_802_11_POWER_MODE_PSP;
+		ret = mwifiex_send_cmd_async(priv,
+					     HostCmd_CMD_802_11_PS_MODE_ENH,
+					     EN_AUTO_PS, BITMAP_STA_PS, NULL);
+		if (ret)
+			return -1;
+	}
+
+	/* get tx rate */
+	ret = mwifiex_send_cmd_async(priv, HostCmd_CMD_TX_RATE_CFG,
+				     HostCmd_ACT_GEN_GET, 0, NULL);
+	if (ret)
+		return -1;
+	priv->data_rate = 0;
+
+	/* get tx power */
+	ret = mwifiex_send_cmd_async(priv, HostCmd_CMD_TXPWR_CFG,
+				     HostCmd_ACT_GEN_GET, 0, NULL);
+	if (ret)
+		return -1;
+
+	/* set ibss coalescing_status */
+	ret = mwifiex_send_cmd_async(priv,
+				     HostCmd_CMD_802_11_IBSS_COALESCING_STATUS,
+				     HostCmd_ACT_GEN_SET, 0, &enable);
+	if (ret)
+		return -1;
+
+	memset(&amsdu_aggr_ctrl, 0, sizeof(amsdu_aggr_ctrl));
+	amsdu_aggr_ctrl.enable = true;
+	/* Send request to firmware */
+	ret = mwifiex_send_cmd_async(priv, HostCmd_CMD_AMSDU_AGGR_CTRL,
+				     HostCmd_ACT_GEN_SET, 0,
+				     (void *) &amsdu_aggr_ctrl);
+	if (ret)
+		return -1;
+	/* MAC Control must be the last command in init_fw */
+	/* set MAC Control */
+	ret = mwifiex_send_cmd_async(priv, HostCmd_CMD_MAC_CONTROL,
+				     HostCmd_ACT_GEN_SET, 0,
+				     &priv->curr_pkt_filter);
+	if (ret)
+		return -1;
+
+	if (first_sta) {
+		/* Enable auto deep sleep */
+		auto_ds.auto_ds = DEEP_SLEEP_ON;
+		auto_ds.idle_time = DEEP_SLEEP_IDLE_TIME;
+		ret = mwifiex_send_cmd_async(priv,
+					     HostCmd_CMD_802_11_PS_MODE_ENH,
+					     EN_AUTO_PS, BITMAP_AUTO_DS,
+					     &auto_ds);
+		if (ret)
+			return -1;
+	}
+
+	/* Send cmd to FW to enable/disable 11D function */
+	state_11d = ENABLE_11D;
+	ret = mwifiex_send_cmd_async(priv, HostCmd_CMD_802_11_SNMP_MIB,
+				     HostCmd_ACT_GEN_SET, DOT11D_I, &state_11d);
+	if (ret)
+		dev_err(priv->adapter->dev, "11D: failed to enable 11D\n");
+
+	/* set last_init_cmd */
+	priv->adapter->last_init_cmd = HostCmd_CMD_802_11_SNMP_MIB;
+	ret = -EINPROGRESS;
+
+	return ret;
+}
diff -druN linux-2.6.39-libre/drivers/net/wireless/mwifiex/sta_cmdresp.c linux-3.0-rc7-libre/drivers/net/wireless/mwifiex/sta_cmdresp.c
--- linux-2.6.39-libre/drivers/net/wireless/mwifiex/sta_cmdresp.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/net/wireless/mwifiex/sta_cmdresp.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,972 @@
+/*
+ * Marvell Wireless LAN device driver: station command response handling
+ *
+ * Copyright (C) 2011, Marvell International Ltd.
+ *
+ * This software file (the "File") is distributed by Marvell International
+ * Ltd. under the terms of the GNU General Public License Version 2, June 1991
+ * (the "License").  You may use, redistribute and/or modify this File in
+ * accordance with the terms and conditions of the License, a copy of which
+ * is available by writing to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
+ * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
+ *
+ * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
+ * ARE EXPRESSLY DISCLAIMED.  The License provides additional details about
+ * this warranty disclaimer.
+ */
+
+#include "decl.h"
+#include "ioctl.h"
+#include "util.h"
+#include "fw.h"
+#include "main.h"
+#include "wmm.h"
+#include "11n.h"
+
+
+/*
+ * This function handles the command response error case.
+ *
+ * For scan response error, the function cancels all the pending
+ * scan commands and generates an event to inform the applications
+ * of the scan completion.
+ *
+ * For Power Save command failure, we do not retry enter PS
+ * command in case of Ad-hoc mode.
+ *
+ * For all other response errors, the current command buffer is freed
+ * and returned to the free command queue.
+ */
+static void
+mwifiex_process_cmdresp_error(struct mwifiex_private *priv,
+			      struct host_cmd_ds_command *resp)
+{
+	struct cmd_ctrl_node *cmd_node = NULL, *tmp_node;
+	struct mwifiex_adapter *adapter = priv->adapter;
+	struct host_cmd_ds_802_11_ps_mode_enh *pm;
+	unsigned long flags;
+
+	dev_err(adapter->dev, "CMD_RESP: cmd %#x error, result=%#x\n",
+			resp->command, resp->result);
+
+	if (adapter->curr_cmd->wait_q_enabled)
+		adapter->cmd_wait_q.status = -1;
+
+	switch (le16_to_cpu(resp->command)) {
+	case HostCmd_CMD_802_11_PS_MODE_ENH:
+		pm = &resp->params.psmode_enh;
+		dev_err(adapter->dev, "PS_MODE_ENH cmd failed: "
+					"result=0x%x action=0x%X\n",
+				resp->result, le16_to_cpu(pm->action));
+		/* We do not re-try enter-ps command in ad-hoc mode. */
+		if (le16_to_cpu(pm->action) == EN_AUTO_PS &&
+			(le16_to_cpu(pm->params.ps_bitmap) & BITMAP_STA_PS) &&
+				priv->bss_mode == NL80211_IFTYPE_ADHOC)
+			adapter->ps_mode = MWIFIEX_802_11_POWER_MODE_CAM;
+
+		break;
+	case HostCmd_CMD_802_11_SCAN:
+		/* Cancel all pending scan command */
+		spin_lock_irqsave(&adapter->scan_pending_q_lock, flags);
+		list_for_each_entry_safe(cmd_node, tmp_node,
+					 &adapter->scan_pending_q, list) {
+			list_del(&cmd_node->list);
+			spin_unlock_irqrestore(&adapter->scan_pending_q_lock,
+					       flags);
+			mwifiex_insert_cmd_to_free_q(adapter, cmd_node);
+			spin_lock_irqsave(&adapter->scan_pending_q_lock, flags);
+		}
+		spin_unlock_irqrestore(&adapter->scan_pending_q_lock, flags);
+
+		spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags);
+		adapter->scan_processing = false;
+		spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags);
+		if (priv->report_scan_result)
+			priv->report_scan_result = false;
+		if (priv->scan_pending_on_block) {
+			priv->scan_pending_on_block = false;
+			up(&priv->async_sem);
+		}
+		break;
+
+	case HostCmd_CMD_MAC_CONTROL:
+		break;
+
+	default:
+		break;
+	}
+	/* Handling errors here */
+	mwifiex_insert_cmd_to_free_q(adapter, adapter->curr_cmd);
+
+	spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags);
+	adapter->curr_cmd = NULL;
+	spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags);
+}
+
+/*
+ * This function handles the command response of get RSSI info.
+ *
+ * Handling includes changing the header fields into CPU format
+ * and saving the following parameters in driver -
+ *      - Last data and beacon RSSI value
+ *      - Average data and beacon RSSI value
+ *      - Last data and beacon NF value
+ *      - Average data and beacon NF value
+ *
+ * The parameters are send to the application as well, along with
+ * calculated SNR values.
+ */
+static int mwifiex_ret_802_11_rssi_info(struct mwifiex_private *priv,
+					struct host_cmd_ds_command *resp,
+					void *data_buf)
+{
+	struct host_cmd_ds_802_11_rssi_info_rsp *rssi_info_rsp =
+		&resp->params.rssi_info_rsp;
+	struct mwifiex_ds_get_signal *signal;
+
+	priv->data_rssi_last = le16_to_cpu(rssi_info_rsp->data_rssi_last);
+	priv->data_nf_last = le16_to_cpu(rssi_info_rsp->data_nf_last);
+
+	priv->data_rssi_avg = le16_to_cpu(rssi_info_rsp->data_rssi_avg);
+	priv->data_nf_avg = le16_to_cpu(rssi_info_rsp->data_nf_avg);
+
+	priv->bcn_rssi_last = le16_to_cpu(rssi_info_rsp->bcn_rssi_last);
+	priv->bcn_nf_last = le16_to_cpu(rssi_info_rsp->bcn_nf_last);
+
+	priv->bcn_rssi_avg = le16_to_cpu(rssi_info_rsp->bcn_rssi_avg);
+	priv->bcn_nf_avg = le16_to_cpu(rssi_info_rsp->bcn_nf_avg);
+
+	/* Need to indicate IOCTL complete */
+	if (data_buf) {
+		signal = (struct mwifiex_ds_get_signal *) data_buf;
+		memset(signal, 0, sizeof(struct mwifiex_ds_get_signal));
+
+		signal->selector = ALL_RSSI_INFO_MASK;
+
+		/* RSSI */
+		signal->bcn_rssi_last = priv->bcn_rssi_last;
+		signal->bcn_rssi_avg = priv->bcn_rssi_avg;
+		signal->data_rssi_last = priv->data_rssi_last;
+		signal->data_rssi_avg = priv->data_rssi_avg;
+
+		/* SNR */
+		signal->bcn_snr_last =
+			CAL_SNR(priv->bcn_rssi_last, priv->bcn_nf_last);
+		signal->bcn_snr_avg =
+			CAL_SNR(priv->bcn_rssi_avg, priv->bcn_nf_avg);
+		signal->data_snr_last =
+			CAL_SNR(priv->data_rssi_last, priv->data_nf_last);
+		signal->data_snr_avg =
+			CAL_SNR(priv->data_rssi_avg, priv->data_nf_avg);
+
+		/* NF */
+		signal->bcn_nf_last = priv->bcn_nf_last;
+		signal->bcn_nf_avg = priv->bcn_nf_avg;
+		signal->data_nf_last = priv->data_nf_last;
+		signal->data_nf_avg = priv->data_nf_avg;
+	}
+
+	return 0;
+}
+
+/*
+ * This function handles the command response of set/get SNMP
+ * MIB parameters.
+ *
+ * Handling includes changing the header fields into CPU format
+ * and saving the parameter in driver.
+ *
+ * The following parameters are supported -
+ *      - Fragmentation threshold
+ *      - RTS threshold
+ *      - Short retry limit
+ */
+static int mwifiex_ret_802_11_snmp_mib(struct mwifiex_private *priv,
+				       struct host_cmd_ds_command *resp,
+				       void *data_buf)
+{
+	struct host_cmd_ds_802_11_snmp_mib *smib = &resp->params.smib;
+	u16 oid = le16_to_cpu(smib->oid);
+	u16 query_type = le16_to_cpu(smib->query_type);
+	u32 ul_temp;
+
+	dev_dbg(priv->adapter->dev, "info: SNMP_RESP: oid value = %#x,"
+			" query_type = %#x, buf size = %#x\n",
+			oid, query_type, le16_to_cpu(smib->buf_size));
+	if (query_type == HostCmd_ACT_GEN_GET) {
+		ul_temp = le16_to_cpu(*((__le16 *) (smib->value)));
+		if (data_buf)
+			*(u32 *)data_buf = ul_temp;
+		switch (oid) {
+		case FRAG_THRESH_I:
+			dev_dbg(priv->adapter->dev,
+				"info: SNMP_RESP: FragThsd =%u\n", ul_temp);
+			break;
+		case RTS_THRESH_I:
+			dev_dbg(priv->adapter->dev,
+				"info: SNMP_RESP: RTSThsd =%u\n", ul_temp);
+			break;
+		case SHORT_RETRY_LIM_I:
+			dev_dbg(priv->adapter->dev,
+				"info: SNMP_RESP: TxRetryCount=%u\n", ul_temp);
+			break;
+		default:
+			break;
+		}
+	}
+
+	return 0;
+}
+
+/*
+ * This function handles the command response of get log request
+ *
+ * Handling includes changing the header fields into CPU format
+ * and sending the received parameters to application.
+ */
+static int mwifiex_ret_get_log(struct mwifiex_private *priv,
+			       struct host_cmd_ds_command *resp,
+			       void *data_buf)
+{
+	struct host_cmd_ds_802_11_get_log *get_log =
+		(struct host_cmd_ds_802_11_get_log *) &resp->params.get_log;
+	struct mwifiex_ds_get_stats *stats;
+
+	if (data_buf) {
+		stats = (struct mwifiex_ds_get_stats *) data_buf;
+		stats->mcast_tx_frame = le32_to_cpu(get_log->mcast_tx_frame);
+		stats->failed = le32_to_cpu(get_log->failed);
+		stats->retry = le32_to_cpu(get_log->retry);
+		stats->multi_retry = le32_to_cpu(get_log->multi_retry);
+		stats->frame_dup = le32_to_cpu(get_log->frame_dup);
+		stats->rts_success = le32_to_cpu(get_log->rts_success);
+		stats->rts_failure = le32_to_cpu(get_log->rts_failure);
+		stats->ack_failure = le32_to_cpu(get_log->ack_failure);
+		stats->rx_frag = le32_to_cpu(get_log->rx_frag);
+		stats->mcast_rx_frame = le32_to_cpu(get_log->mcast_rx_frame);
+		stats->fcs_error = le32_to_cpu(get_log->fcs_error);
+		stats->tx_frame = le32_to_cpu(get_log->tx_frame);
+		stats->wep_icv_error[0] =
+			le32_to_cpu(get_log->wep_icv_err_cnt[0]);
+		stats->wep_icv_error[1] =
+			le32_to_cpu(get_log->wep_icv_err_cnt[1]);
+		stats->wep_icv_error[2] =
+			le32_to_cpu(get_log->wep_icv_err_cnt[2]);
+		stats->wep_icv_error[3] =
+			le32_to_cpu(get_log->wep_icv_err_cnt[3]);
+	}
+
+	return 0;
+}
+
+/*
+ * This function handles the command response of set/get Tx rate
+ * configurations.
+ *
+ * Handling includes changing the header fields into CPU format
+ * and saving the following parameters in driver -
+ *      - DSSS rate bitmap
+ *      - OFDM rate bitmap
+ *      - HT MCS rate bitmaps
+ *
+ * Based on the new rate bitmaps, the function re-evaluates if
+ * auto data rate has been activated. If not, it sends another
+ * query to the firmware to get the current Tx data rate and updates
+ * the driver value.
+ */
+static int mwifiex_ret_tx_rate_cfg(struct mwifiex_private *priv,
+				   struct host_cmd_ds_command *resp,
+				   void *data_buf)
+{
+	struct mwifiex_rate_cfg *ds_rate;
+	struct host_cmd_ds_tx_rate_cfg *rate_cfg = &resp->params.tx_rate_cfg;
+	struct mwifiex_rate_scope *rate_scope;
+	struct mwifiex_ie_types_header *head;
+	u16 tlv, tlv_buf_len;
+	u8 *tlv_buf;
+	u32 i;
+	int ret = 0;
+
+	tlv_buf = (u8 *) ((u8 *) rate_cfg) +
+			sizeof(struct host_cmd_ds_tx_rate_cfg);
+	tlv_buf_len = *(u16 *) (tlv_buf + sizeof(u16));
+
+	while (tlv_buf && tlv_buf_len > 0) {
+		tlv = (*tlv_buf);
+		tlv = tlv | (*(tlv_buf + 1) << 8);
+
+		switch (tlv) {
+		case TLV_TYPE_RATE_SCOPE:
+			rate_scope = (struct mwifiex_rate_scope *) tlv_buf;
+			priv->bitmap_rates[0] =
+				le16_to_cpu(rate_scope->hr_dsss_rate_bitmap);
+			priv->bitmap_rates[1] =
+				le16_to_cpu(rate_scope->ofdm_rate_bitmap);
+			for (i = 0;
+			     i <
+			     sizeof(rate_scope->ht_mcs_rate_bitmap) /
+			     sizeof(u16); i++)
+				priv->bitmap_rates[2 + i] =
+					le16_to_cpu(rate_scope->
+						    ht_mcs_rate_bitmap[i]);
+			break;
+			/* Add RATE_DROP tlv here */
+		}
+
+		head = (struct mwifiex_ie_types_header *) tlv_buf;
+		tlv_buf += le16_to_cpu(head->len) + sizeof(*head);
+		tlv_buf_len -= le16_to_cpu(head->len);
+	}
+
+	priv->is_data_rate_auto = mwifiex_is_rate_auto(priv);
+
+	if (priv->is_data_rate_auto)
+		priv->data_rate = 0;
+	else
+		ret = mwifiex_send_cmd_async(priv,
+					  HostCmd_CMD_802_11_TX_RATE_QUERY,
+					  HostCmd_ACT_GEN_GET, 0, NULL);
+
+	if (data_buf) {
+		ds_rate = (struct mwifiex_rate_cfg *) data_buf;
+		if (le16_to_cpu(rate_cfg->action) == HostCmd_ACT_GEN_GET) {
+			if (priv->is_data_rate_auto) {
+				ds_rate->is_rate_auto = 1;
+			} else {
+				ds_rate->rate = mwifiex_get_rate_index(priv->
+							       bitmap_rates,
+							       sizeof(priv->
+							       bitmap_rates));
+				if (ds_rate->rate >=
+				    MWIFIEX_RATE_BITMAP_OFDM0
+				    && ds_rate->rate <=
+				    MWIFIEX_RATE_BITMAP_OFDM7)
+					ds_rate->rate -=
+						(MWIFIEX_RATE_BITMAP_OFDM0 -
+						 MWIFIEX_RATE_INDEX_OFDM0);
+				if (ds_rate->rate >=
+				    MWIFIEX_RATE_BITMAP_MCS0
+				    && ds_rate->rate <=
+				    MWIFIEX_RATE_BITMAP_MCS127)
+					ds_rate->rate -=
+						(MWIFIEX_RATE_BITMAP_MCS0 -
+						 MWIFIEX_RATE_INDEX_MCS0);
+			}
+		}
+	}
+
+	return ret;
+}
+
+/*
+ * This function handles the command response of get Tx power level.
+ *
+ * Handling includes saving the maximum and minimum Tx power levels
+ * in driver, as well as sending the values to user.
+ */
+static int mwifiex_get_power_level(struct mwifiex_private *priv, void *data_buf)
+{
+	int length, max_power = -1, min_power = -1;
+	struct mwifiex_types_power_group *pg_tlv_hdr;
+	struct mwifiex_power_group *pg;
+
+	if (data_buf) {
+		pg_tlv_hdr =
+			(struct mwifiex_types_power_group *) ((u8 *) data_buf
+					+ sizeof(struct host_cmd_ds_txpwr_cfg));
+		pg = (struct mwifiex_power_group *) ((u8 *) pg_tlv_hdr +
+				sizeof(struct mwifiex_types_power_group));
+		length = pg_tlv_hdr->length;
+		if (length > 0) {
+			max_power = pg->power_max;
+			min_power = pg->power_min;
+			length -= sizeof(struct mwifiex_power_group);
+		}
+		while (length) {
+			pg++;
+			if (max_power < pg->power_max)
+				max_power = pg->power_max;
+
+			if (min_power > pg->power_min)
+				min_power = pg->power_min;
+
+			length -= sizeof(struct mwifiex_power_group);
+		}
+		if (pg_tlv_hdr->length > 0) {
+			priv->min_tx_power_level = (u8) min_power;
+			priv->max_tx_power_level = (u8) max_power;
+		}
+	} else {
+		return -1;
+	}
+
+	return 0;
+}
+
+/*
+ * This function handles the command response of set/get Tx power
+ * configurations.
+ *
+ * Handling includes changing the header fields into CPU format
+ * and saving the current Tx power level in driver.
+ */
+static int mwifiex_ret_tx_power_cfg(struct mwifiex_private *priv,
+				    struct host_cmd_ds_command *resp,
+				    void *data_buf)
+{
+	struct mwifiex_adapter *adapter = priv->adapter;
+	struct host_cmd_ds_txpwr_cfg *txp_cfg = &resp->params.txp_cfg;
+	struct mwifiex_types_power_group *pg_tlv_hdr;
+	struct mwifiex_power_group *pg;
+	u16 action = le16_to_cpu(txp_cfg->action);
+
+	switch (action) {
+	case HostCmd_ACT_GEN_GET:
+		{
+			pg_tlv_hdr =
+				(struct mwifiex_types_power_group *) ((u8 *)
+						txp_cfg +
+						sizeof
+						(struct
+						 host_cmd_ds_txpwr_cfg));
+			pg = (struct mwifiex_power_group *) ((u8 *)
+						pg_tlv_hdr +
+						sizeof(struct
+						mwifiex_types_power_group));
+			if (adapter->hw_status ==
+			    MWIFIEX_HW_STATUS_INITIALIZING)
+				mwifiex_get_power_level(priv, txp_cfg);
+			priv->tx_power_level = (u16) pg->power_min;
+			break;
+		}
+	case HostCmd_ACT_GEN_SET:
+		if (le32_to_cpu(txp_cfg->mode)) {
+			pg_tlv_hdr =
+				(struct mwifiex_types_power_group *) ((u8 *)
+						txp_cfg +
+						sizeof
+						(struct
+						 host_cmd_ds_txpwr_cfg));
+			pg = (struct mwifiex_power_group *) ((u8 *) pg_tlv_hdr
+						+
+						sizeof(struct
+						mwifiex_types_power_group));
+			if (pg->power_max == pg->power_min)
+				priv->tx_power_level = (u16) pg->power_min;
+		}
+		break;
+	default:
+		dev_err(adapter->dev, "CMD_RESP: unknown cmd action %d\n",
+				action);
+		return 0;
+	}
+	dev_dbg(adapter->dev,
+		"info: Current TxPower Level = %d, Max Power=%d, Min Power=%d\n",
+	       priv->tx_power_level, priv->max_tx_power_level,
+	       priv->min_tx_power_level);
+
+	return 0;
+}
+
+/*
+ * This function handles the command response of set/get MAC address.
+ *
+ * Handling includes saving the MAC address in driver.
+ */
+static int mwifiex_ret_802_11_mac_address(struct mwifiex_private *priv,
+					  struct host_cmd_ds_command *resp)
+{
+	struct host_cmd_ds_802_11_mac_address *cmd_mac_addr =
+		&resp->params.mac_addr;
+
+	memcpy(priv->curr_addr, cmd_mac_addr->mac_addr, ETH_ALEN);
+
+	dev_dbg(priv->adapter->dev,
+		"info: set mac address: %pM\n", priv->curr_addr);
+
+	return 0;
+}
+
+/*
+ * This function handles the command response of set/get MAC multicast
+ * address.
+ */
+static int mwifiex_ret_mac_multicast_adr(struct mwifiex_private *priv,
+					 struct host_cmd_ds_command *resp)
+{
+	return 0;
+}
+
+/*
+ * This function handles the command response of get Tx rate query.
+ *
+ * Handling includes changing the header fields into CPU format
+ * and saving the Tx rate and HT information parameters in driver.
+ *
+ * Both rate configuration and current data rate can be retrieved
+ * with this request.
+ */
+static int mwifiex_ret_802_11_tx_rate_query(struct mwifiex_private *priv,
+					    struct host_cmd_ds_command *resp)
+{
+	priv->tx_rate = resp->params.tx_rate.tx_rate;
+	priv->tx_htinfo = resp->params.tx_rate.ht_info;
+	if (!priv->is_data_rate_auto)
+		priv->data_rate =
+			mwifiex_index_to_data_rate(priv->tx_rate,
+						   priv->tx_htinfo);
+
+	return 0;
+}
+
+/*
+ * This function handles the command response of a deauthenticate
+ * command.
+ *
+ * If the deauthenticated MAC matches the current BSS MAC, the connection
+ * state is reset.
+ */
+static int mwifiex_ret_802_11_deauthenticate(struct mwifiex_private *priv,
+					     struct host_cmd_ds_command *resp)
+{
+	struct mwifiex_adapter *adapter = priv->adapter;
+
+	adapter->dbg.num_cmd_deauth++;
+	if (!memcmp(resp->params.deauth.mac_addr,
+		    &priv->curr_bss_params.bss_descriptor.mac_address,
+		    sizeof(resp->params.deauth.mac_addr)))
+		mwifiex_reset_connect_state(priv);
+
+	return 0;
+}
+
+/*
+ * This function handles the command response of ad-hoc stop.
+ *
+ * The function resets the connection state in driver.
+ */
+static int mwifiex_ret_802_11_ad_hoc_stop(struct mwifiex_private *priv,
+					  struct host_cmd_ds_command *resp)
+{
+	mwifiex_reset_connect_state(priv);
+	return 0;
+}
+
+/*
+ * This function handles the command response of set/get key material.
+ *
+ * Handling includes updating the driver parameters to reflect the
+ * changes.
+ */
+static int mwifiex_ret_802_11_key_material(struct mwifiex_private *priv,
+					   struct host_cmd_ds_command *resp)
+{
+	struct host_cmd_ds_802_11_key_material *key =
+		&resp->params.key_material;
+
+	if (le16_to_cpu(key->action) == HostCmd_ACT_GEN_SET) {
+		if ((le16_to_cpu(key->key_param_set.key_info) & KEY_MCAST)) {
+			dev_dbg(priv->adapter->dev, "info: key: GTK is set\n");
+			priv->wpa_is_gtk_set = true;
+			priv->scan_block = false;
+		}
+	}
+
+	memset(priv->aes_key.key_param_set.key, 0,
+	       sizeof(key->key_param_set.key));
+	priv->aes_key.key_param_set.key_len = key->key_param_set.key_len;
+	memcpy(priv->aes_key.key_param_set.key, key->key_param_set.key,
+	       le16_to_cpu(priv->aes_key.key_param_set.key_len));
+
+	return 0;
+}
+
+/*
+ * This function handles the command response of get 11d domain information.
+ */
+static int mwifiex_ret_802_11d_domain_info(struct mwifiex_private *priv,
+					   struct host_cmd_ds_command *resp)
+{
+	struct host_cmd_ds_802_11d_domain_info_rsp *domain_info =
+		&resp->params.domain_info_resp;
+	struct mwifiex_ietypes_domain_param_set *domain = &domain_info->domain;
+	u16 action = le16_to_cpu(domain_info->action);
+	u8 no_of_triplet;
+
+	no_of_triplet = (u8) ((le16_to_cpu(domain->header.len) -
+					IEEE80211_COUNTRY_STRING_LEN) /
+				sizeof(struct ieee80211_country_ie_triplet));
+
+	dev_dbg(priv->adapter->dev, "info: 11D Domain Info Resp:"
+			" no_of_triplet=%d\n", no_of_triplet);
+
+	if (no_of_triplet > MWIFIEX_MAX_TRIPLET_802_11D) {
+		dev_warn(priv->adapter->dev,
+			"11D: invalid number of triplets %d "
+			"returned!!\n", no_of_triplet);
+		return -1;
+	}
+
+	switch (action) {
+	case HostCmd_ACT_GEN_SET:  /* Proc Set Action */
+		break;
+	case HostCmd_ACT_GEN_GET:
+		break;
+	default:
+		dev_err(priv->adapter->dev,
+			"11D: invalid action:%d\n", domain_info->action);
+		return -1;
+	}
+
+	return 0;
+}
+
+/*
+ * This function handles the command response of get RF channel.
+ *
+ * Handling includes changing the header fields into CPU format
+ * and saving the new channel in driver.
+ */
+static int mwifiex_ret_802_11_rf_channel(struct mwifiex_private *priv,
+					 struct host_cmd_ds_command *resp,
+					 void *data_buf)
+{
+	struct host_cmd_ds_802_11_rf_channel *rf_channel =
+		&resp->params.rf_channel;
+	u16 new_channel = le16_to_cpu(rf_channel->current_channel);
+
+	if (priv->curr_bss_params.bss_descriptor.channel != new_channel) {
+		dev_dbg(priv->adapter->dev, "cmd: Channel Switch: %d to %d\n",
+		       priv->curr_bss_params.bss_descriptor.channel,
+		       new_channel);
+		/* Update the channel again */
+		priv->curr_bss_params.bss_descriptor.channel = new_channel;
+	}
+	if (data_buf)
+		*((u16 *)data_buf) = new_channel;
+
+	return 0;
+}
+
+/*
+ * This function handles the command response of get extended version.
+ *
+ * Handling includes forming the extended version string and sending it
+ * to application.
+ */
+static int mwifiex_ret_ver_ext(struct mwifiex_private *priv,
+			       struct host_cmd_ds_command *resp,
+			       void *data_buf)
+{
+	struct host_cmd_ds_version_ext *ver_ext = &resp->params.verext;
+	struct host_cmd_ds_version_ext *version_ext;
+
+	if (data_buf) {
+		version_ext = (struct host_cmd_ds_version_ext *)data_buf;
+		version_ext->version_str_sel = ver_ext->version_str_sel;
+		memcpy(version_ext->version_str, ver_ext->version_str,
+		       sizeof(char) * 128);
+		memcpy(priv->version_str, ver_ext->version_str, 128);
+	}
+	return 0;
+}
+
+/*
+ * This function handles the command response of register access.
+ *
+ * The register value and offset are returned to the user. For EEPROM
+ * access, the byte count is also returned.
+ */
+static int mwifiex_ret_reg_access(u16 type, struct host_cmd_ds_command *resp,
+				  void *data_buf)
+{
+	struct mwifiex_ds_reg_rw *reg_rw;
+	struct mwifiex_ds_read_eeprom *eeprom;
+
+	if (data_buf) {
+		reg_rw = (struct mwifiex_ds_reg_rw *) data_buf;
+		eeprom = (struct mwifiex_ds_read_eeprom *) data_buf;
+		switch (type) {
+		case HostCmd_CMD_MAC_REG_ACCESS:
+			{
+				struct host_cmd_ds_mac_reg_access *reg;
+				reg = (struct host_cmd_ds_mac_reg_access *)
+					&resp->params.mac_reg;
+				reg_rw->offset = cpu_to_le32(
+					(u32) le16_to_cpu(reg->offset));
+				reg_rw->value = reg->value;
+				break;
+			}
+		case HostCmd_CMD_BBP_REG_ACCESS:
+			{
+				struct host_cmd_ds_bbp_reg_access *reg;
+				reg = (struct host_cmd_ds_bbp_reg_access *)
+					&resp->params.bbp_reg;
+				reg_rw->offset = cpu_to_le32(
+					(u32) le16_to_cpu(reg->offset));
+				reg_rw->value = cpu_to_le32((u32) reg->value);
+				break;
+			}
+
+		case HostCmd_CMD_RF_REG_ACCESS:
+			{
+				struct host_cmd_ds_rf_reg_access *reg;
+				reg = (struct host_cmd_ds_rf_reg_access *)
+					&resp->params.rf_reg;
+				reg_rw->offset = cpu_to_le32(
+					(u32) le16_to_cpu(reg->offset));
+				reg_rw->value = cpu_to_le32((u32) reg->value);
+				break;
+			}
+		case HostCmd_CMD_PMIC_REG_ACCESS:
+			{
+				struct host_cmd_ds_pmic_reg_access *reg;
+				reg = (struct host_cmd_ds_pmic_reg_access *)
+					&resp->params.pmic_reg;
+				reg_rw->offset = cpu_to_le32(
+					(u32) le16_to_cpu(reg->offset));
+				reg_rw->value = cpu_to_le32((u32) reg->value);
+				break;
+			}
+		case HostCmd_CMD_CAU_REG_ACCESS:
+			{
+				struct host_cmd_ds_rf_reg_access *reg;
+				reg = (struct host_cmd_ds_rf_reg_access *)
+					&resp->params.rf_reg;
+				reg_rw->offset = cpu_to_le32(
+					(u32) le16_to_cpu(reg->offset));
+				reg_rw->value = cpu_to_le32((u32) reg->value);
+				break;
+			}
+		case HostCmd_CMD_802_11_EEPROM_ACCESS:
+			{
+				struct host_cmd_ds_802_11_eeprom_access
+					*cmd_eeprom =
+					(struct host_cmd_ds_802_11_eeprom_access
+					 *) &resp->params.eeprom;
+				pr_debug("info: EEPROM read len=%x\n",
+				       cmd_eeprom->byte_count);
+				if (le16_to_cpu(eeprom->byte_count) <
+						le16_to_cpu(
+						cmd_eeprom->byte_count)) {
+					eeprom->byte_count = cpu_to_le16(0);
+					pr_debug("info: EEPROM read "
+							"length is too big\n");
+					return -1;
+				}
+				eeprom->offset = cmd_eeprom->offset;
+				eeprom->byte_count = cmd_eeprom->byte_count;
+				if (le16_to_cpu(eeprom->byte_count) > 0)
+					memcpy(&eeprom->value,
+					       &cmd_eeprom->value,
+					       le16_to_cpu(eeprom->byte_count));
+
+				break;
+			}
+		default:
+			return -1;
+		}
+	}
+	return 0;
+}
+
+/*
+ * This function handles the command response of get IBSS coalescing status.
+ *
+ * If the received BSSID is different than the current one, the current BSSID,
+ * beacon interval, ATIM window and ERP information are updated, along with
+ * changing the ad-hoc state accordingly.
+ */
+static int mwifiex_ret_ibss_coalescing_status(struct mwifiex_private *priv,
+					      struct host_cmd_ds_command *resp)
+{
+	struct host_cmd_ds_802_11_ibss_status *ibss_coal_resp =
+		&(resp->params.ibss_coalescing);
+	u8 zero_mac[ETH_ALEN] = { 0, 0, 0, 0, 0, 0 };
+
+	if (le16_to_cpu(ibss_coal_resp->action) == HostCmd_ACT_GEN_SET)
+		return 0;
+
+	dev_dbg(priv->adapter->dev,
+		"info: new BSSID %pM\n", ibss_coal_resp->bssid);
+
+	/* If rsp has NULL BSSID, Just return..... No Action */
+	if (!memcmp(ibss_coal_resp->bssid, zero_mac, ETH_ALEN)) {
+		dev_warn(priv->adapter->dev, "new BSSID is NULL\n");
+		return 0;
+	}
+
+	/* If BSSID is diff, modify current BSS parameters */
+	if (memcmp(priv->curr_bss_params.bss_descriptor.mac_address,
+		   ibss_coal_resp->bssid, ETH_ALEN)) {
+		/* BSSID */
+		memcpy(priv->curr_bss_params.bss_descriptor.mac_address,
+		       ibss_coal_resp->bssid, ETH_ALEN);
+
+		/* Beacon Interval */
+		priv->curr_bss_params.bss_descriptor.beacon_period
+			= le16_to_cpu(ibss_coal_resp->beacon_interval);
+
+		/* ERP Information */
+		priv->curr_bss_params.bss_descriptor.erp_flags =
+			(u8) le16_to_cpu(ibss_coal_resp->use_g_rate_protect);
+
+		priv->adhoc_state = ADHOC_COALESCED;
+	}
+
+	return 0;
+}
+
+/*
+ * This function handles the command responses.
+ *
+ * This is a generic function, which calls command specific
+ * response handlers based on the command ID.
+ */
+int mwifiex_process_sta_cmdresp(struct mwifiex_private *priv,
+				u16 cmdresp_no, void *cmd_buf)
+{
+	int ret = 0;
+	struct mwifiex_adapter *adapter = priv->adapter;
+	struct host_cmd_ds_command *resp =
+		(struct host_cmd_ds_command *) cmd_buf;
+	void *data_buf = adapter->curr_cmd->data_buf;
+
+	/* If the command is not successful, cleanup and return failure */
+	if (resp->result != HostCmd_RESULT_OK) {
+		mwifiex_process_cmdresp_error(priv, resp);
+		return -1;
+	}
+	/* Command successful, handle response */
+	switch (cmdresp_no) {
+	case HostCmd_CMD_GET_HW_SPEC:
+		ret = mwifiex_ret_get_hw_spec(priv, resp);
+		break;
+	case HostCmd_CMD_MAC_CONTROL:
+		break;
+	case HostCmd_CMD_802_11_MAC_ADDRESS:
+		ret = mwifiex_ret_802_11_mac_address(priv, resp);
+		break;
+	case HostCmd_CMD_MAC_MULTICAST_ADR:
+		ret = mwifiex_ret_mac_multicast_adr(priv, resp);
+		break;
+	case HostCmd_CMD_TX_RATE_CFG:
+		ret = mwifiex_ret_tx_rate_cfg(priv, resp, data_buf);
+		break;
+	case HostCmd_CMD_802_11_SCAN:
+		ret = mwifiex_ret_802_11_scan(priv, resp);
+		adapter->curr_cmd->wait_q_enabled = false;
+		break;
+	case HostCmd_CMD_802_11_BG_SCAN_QUERY:
+		ret = mwifiex_ret_802_11_scan(priv, resp);
+		dev_dbg(adapter->dev,
+			"info: CMD_RESP: BG_SCAN result is ready!\n");
+		break;
+	case HostCmd_CMD_TXPWR_CFG:
+		ret = mwifiex_ret_tx_power_cfg(priv, resp, data_buf);
+		break;
+	case HostCmd_CMD_802_11_PS_MODE_ENH:
+		ret = mwifiex_ret_enh_power_mode(priv, resp, data_buf);
+		break;
+	case HostCmd_CMD_802_11_HS_CFG_ENH:
+		ret = mwifiex_ret_802_11_hs_cfg(priv, resp);
+		break;
+	case HostCmd_CMD_802_11_ASSOCIATE:
+		ret = mwifiex_ret_802_11_associate(priv, resp);
+		break;
+	case HostCmd_CMD_802_11_DEAUTHENTICATE:
+		ret = mwifiex_ret_802_11_deauthenticate(priv, resp);
+		break;
+	case HostCmd_CMD_802_11_AD_HOC_START:
+	case HostCmd_CMD_802_11_AD_HOC_JOIN:
+		ret = mwifiex_ret_802_11_ad_hoc(priv, resp);
+		break;
+	case HostCmd_CMD_802_11_AD_HOC_STOP:
+		ret = mwifiex_ret_802_11_ad_hoc_stop(priv, resp);
+		break;
+	case HostCmd_CMD_802_11_GET_LOG:
+		ret = mwifiex_ret_get_log(priv, resp, data_buf);
+		break;
+	case HostCmd_CMD_RSSI_INFO:
+		ret = mwifiex_ret_802_11_rssi_info(priv, resp, data_buf);
+		break;
+	case HostCmd_CMD_802_11_SNMP_MIB:
+		ret = mwifiex_ret_802_11_snmp_mib(priv, resp, data_buf);
+		break;
+	case HostCmd_CMD_802_11_TX_RATE_QUERY:
+		ret = mwifiex_ret_802_11_tx_rate_query(priv, resp);
+		break;
+	case HostCmd_CMD_802_11_RF_CHANNEL:
+		ret = mwifiex_ret_802_11_rf_channel(priv, resp, data_buf);
+		break;
+	case HostCmd_CMD_VERSION_EXT:
+		ret = mwifiex_ret_ver_ext(priv, resp, data_buf);
+		break;
+	case HostCmd_CMD_FUNC_INIT:
+	case HostCmd_CMD_FUNC_SHUTDOWN:
+		break;
+	case HostCmd_CMD_802_11_KEY_MATERIAL:
+		ret = mwifiex_ret_802_11_key_material(priv, resp);
+		break;
+	case HostCmd_CMD_802_11D_DOMAIN_INFO:
+		ret = mwifiex_ret_802_11d_domain_info(priv, resp);
+		break;
+	case HostCmd_CMD_11N_ADDBA_REQ:
+		ret = mwifiex_ret_11n_addba_req(priv, resp);
+		break;
+	case HostCmd_CMD_11N_DELBA:
+		ret = mwifiex_ret_11n_delba(priv, resp);
+		break;
+	case HostCmd_CMD_11N_ADDBA_RSP:
+		ret = mwifiex_ret_11n_addba_resp(priv, resp);
+		break;
+	case HostCmd_CMD_RECONFIGURE_TX_BUFF:
+		adapter->tx_buf_size = (u16) le16_to_cpu(resp->params.
+							     tx_buf.buff_size);
+		adapter->tx_buf_size = (adapter->tx_buf_size /
+						MWIFIEX_SDIO_BLOCK_SIZE) *
+						MWIFIEX_SDIO_BLOCK_SIZE;
+		adapter->curr_tx_buf_size = adapter->tx_buf_size;
+		dev_dbg(adapter->dev,
+			"cmd: max_tx_buf_size=%d, tx_buf_size=%d\n",
+		       adapter->max_tx_buf_size, adapter->tx_buf_size);
+
+		if (adapter->if_ops.update_mp_end_port)
+			adapter->if_ops.update_mp_end_port(adapter,
+					le16_to_cpu(resp->
+						params.
+						tx_buf.
+						mp_end_port));
+		break;
+	case HostCmd_CMD_AMSDU_AGGR_CTRL:
+		ret = mwifiex_ret_amsdu_aggr_ctrl(resp, data_buf);
+		break;
+	case HostCmd_CMD_WMM_GET_STATUS:
+		ret = mwifiex_ret_wmm_get_status(priv, resp);
+		break;
+	case HostCmd_CMD_802_11_IBSS_COALESCING_STATUS:
+		ret = mwifiex_ret_ibss_coalescing_status(priv, resp);
+		break;
+	case HostCmd_CMD_MAC_REG_ACCESS:
+	case HostCmd_CMD_BBP_REG_ACCESS:
+	case HostCmd_CMD_RF_REG_ACCESS:
+	case HostCmd_CMD_PMIC_REG_ACCESS:
+	case HostCmd_CMD_CAU_REG_ACCESS:
+	case HostCmd_CMD_802_11_EEPROM_ACCESS:
+		ret = mwifiex_ret_reg_access(cmdresp_no, resp, data_buf);
+		break;
+	case HostCmd_CMD_SET_BSS_MODE:
+		break;
+	case HostCmd_CMD_11N_CFG:
+		ret = mwifiex_ret_11n_cfg(resp, data_buf);
+		break;
+	default:
+		dev_err(adapter->dev, "CMD_RESP: unknown cmd response %#x\n",
+		       resp->command);
+		break;
+	}
+
+	return ret;
+}
diff -druN linux-2.6.39-libre/drivers/net/wireless/mwifiex/sta_event.c linux-3.0-rc7-libre/drivers/net/wireless/mwifiex/sta_event.c
--- linux-2.6.39-libre/drivers/net/wireless/mwifiex/sta_event.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/net/wireless/mwifiex/sta_event.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,406 @@
+/*
+ * Marvell Wireless LAN device driver: station event handling
+ *
+ * Copyright (C) 2011, Marvell International Ltd.
+ *
+ * This software file (the "File") is distributed by Marvell International
+ * Ltd. under the terms of the GNU General Public License Version 2, June 1991
+ * (the "License").  You may use, redistribute and/or modify this File in
+ * accordance with the terms and conditions of the License, a copy of which
+ * is available by writing to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
+ * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
+ *
+ * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
+ * ARE EXPRESSLY DISCLAIMED.  The License provides additional details about
+ * this warranty disclaimer.
+ */
+
+#include "decl.h"
+#include "ioctl.h"
+#include "util.h"
+#include "fw.h"
+#include "main.h"
+#include "wmm.h"
+#include "11n.h"
+
+/*
+ * This function resets the connection state.
+ *
+ * The function is invoked after receiving a disconnect event from firmware,
+ * and performs the following actions -
+ *      - Set media status to disconnected
+ *      - Clean up Tx and Rx packets
+ *      - Resets SNR/NF/RSSI value in driver
+ *      - Resets security configurations in driver
+ *      - Enables auto data rate
+ *      - Saves the previous SSID and BSSID so that they can
+ *        be used for re-association, if required
+ *      - Erases current SSID and BSSID information
+ *      - Sends a disconnect event to upper layers/applications.
+ */
+void
+mwifiex_reset_connect_state(struct mwifiex_private *priv)
+{
+	struct mwifiex_adapter *adapter = priv->adapter;
+
+	if (!priv->media_connected)
+		return;
+
+	dev_dbg(adapter->dev, "info: handles disconnect event\n");
+
+	priv->media_connected = false;
+
+	priv->scan_block = false;
+
+	/* Free Tx and Rx packets, report disconnect to upper layer */
+	mwifiex_clean_txrx(priv);
+
+	/* Reset SNR/NF/RSSI values */
+	priv->data_rssi_last = 0;
+	priv->data_nf_last = 0;
+	priv->data_rssi_avg = 0;
+	priv->data_nf_avg = 0;
+	priv->bcn_rssi_last = 0;
+	priv->bcn_nf_last = 0;
+	priv->bcn_rssi_avg = 0;
+	priv->bcn_nf_avg = 0;
+	priv->rxpd_rate = 0;
+	priv->rxpd_htinfo = 0;
+	priv->sec_info.wpa_enabled = false;
+	priv->sec_info.wpa2_enabled = false;
+	priv->wpa_ie_len = 0;
+
+	priv->sec_info.wapi_enabled = false;
+	priv->wapi_ie_len = 0;
+	priv->sec_info.wapi_key_on = false;
+
+	priv->sec_info.encryption_mode = 0;
+
+	/* Enable auto data rate */
+	priv->is_data_rate_auto = true;
+	priv->data_rate = 0;
+
+	if (priv->bss_mode == NL80211_IFTYPE_ADHOC) {
+		priv->adhoc_state = ADHOC_IDLE;
+		priv->adhoc_is_link_sensed = false;
+	}
+
+	/*
+	 * Memorize the previous SSID and BSSID so
+	 * it could be used for re-assoc
+	 */
+
+	dev_dbg(adapter->dev, "info: previous SSID=%s, SSID len=%u\n",
+	       priv->prev_ssid.ssid, priv->prev_ssid.ssid_len);
+
+	dev_dbg(adapter->dev, "info: current SSID=%s, SSID len=%u\n",
+	       priv->curr_bss_params.bss_descriptor.ssid.ssid,
+	       priv->curr_bss_params.bss_descriptor.ssid.ssid_len);
+
+	memcpy(&priv->prev_ssid,
+	       &priv->curr_bss_params.bss_descriptor.ssid,
+	       sizeof(struct mwifiex_802_11_ssid));
+
+	memcpy(priv->prev_bssid,
+	       priv->curr_bss_params.bss_descriptor.mac_address, ETH_ALEN);
+
+	/* Need to erase the current SSID and BSSID info */
+	memset(&priv->curr_bss_params, 0x00, sizeof(priv->curr_bss_params));
+
+	adapter->tx_lock_flag = false;
+	adapter->pps_uapsd_mode = false;
+
+	if (adapter->num_cmd_timeout && adapter->curr_cmd)
+		return;
+	priv->media_connected = false;
+	if (!priv->disconnect) {
+		priv->disconnect = 1;
+		dev_dbg(adapter->dev, "info: successfully disconnected from"
+				" %pM: reason code %d\n", priv->cfg_bssid,
+				WLAN_REASON_DEAUTH_LEAVING);
+		cfg80211_disconnected(priv->netdev,
+				WLAN_REASON_DEAUTH_LEAVING, NULL, 0,
+				GFP_KERNEL);
+		queue_work(priv->workqueue, &priv->cfg_workqueue);
+	}
+	if (!netif_queue_stopped(priv->netdev))
+		netif_stop_queue(priv->netdev);
+	if (netif_carrier_ok(priv->netdev))
+		netif_carrier_off(priv->netdev);
+	/* Reset wireless stats signal info */
+	priv->w_stats.qual.level = 0;
+	priv->w_stats.qual.noise = 0;
+}
+
+/*
+ * This function handles events generated by firmware.
+ *
+ * This is a generic function and handles all events.
+ *
+ * Event specific routines are called by this function based
+ * upon the generated event cause.
+ *
+ * For the following events, the function just forwards them to upper
+ * layers, optionally recording the change -
+ *      - EVENT_LINK_SENSED
+ *      - EVENT_MIC_ERR_UNICAST
+ *      - EVENT_MIC_ERR_MULTICAST
+ *      - EVENT_PORT_RELEASE
+ *      - EVENT_RSSI_LOW
+ *      - EVENT_SNR_LOW
+ *      - EVENT_MAX_FAIL
+ *      - EVENT_RSSI_HIGH
+ *      - EVENT_SNR_HIGH
+ *      - EVENT_DATA_RSSI_LOW
+ *      - EVENT_DATA_SNR_LOW
+ *      - EVENT_DATA_RSSI_HIGH
+ *      - EVENT_DATA_SNR_HIGH
+ *      - EVENT_LINK_QUALITY
+ *      - EVENT_PRE_BEACON_LOST
+ *      - EVENT_IBSS_COALESCED
+ *      - EVENT_WEP_ICV_ERR
+ *      - EVENT_BW_CHANGE
+ *      - EVENT_HOSTWAKE_STAIE
+  *
+ * For the following events, no action is taken -
+ *      - EVENT_MIB_CHANGED
+ *      - EVENT_INIT_DONE
+ *      - EVENT_DUMMY_HOST_WAKEUP_SIGNAL
+ *
+ * Rest of the supported events requires driver handling -
+ *      - EVENT_DEAUTHENTICATED
+ *      - EVENT_DISASSOCIATED
+ *      - EVENT_LINK_LOST
+ *      - EVENT_PS_SLEEP
+ *      - EVENT_PS_AWAKE
+ *      - EVENT_DEEP_SLEEP_AWAKE
+ *      - EVENT_HS_ACT_REQ
+ *      - EVENT_ADHOC_BCN_LOST
+ *      - EVENT_BG_SCAN_REPORT
+ *      - EVENT_WMM_STATUS_CHANGE
+ *      - EVENT_ADDBA
+ *      - EVENT_DELBA
+ *      - EVENT_BA_STREAM_TIEMOUT
+ *      - EVENT_AMSDU_AGGR_CTRL
+ */
+int mwifiex_process_sta_event(struct mwifiex_private *priv)
+{
+	struct mwifiex_adapter *adapter = priv->adapter;
+	int ret = 0;
+	u32 eventcause = adapter->event_cause;
+
+	switch (eventcause) {
+	case EVENT_DUMMY_HOST_WAKEUP_SIGNAL:
+		dev_err(adapter->dev, "invalid EVENT: DUMMY_HOST_WAKEUP_SIGNAL,"
+				" ignoring it\n");
+		break;
+	case EVENT_LINK_SENSED:
+		dev_dbg(adapter->dev, "event: LINK_SENSED\n");
+		if (!netif_carrier_ok(priv->netdev))
+			netif_carrier_on(priv->netdev);
+		if (netif_queue_stopped(priv->netdev))
+			netif_wake_queue(priv->netdev);
+		break;
+
+	case EVENT_DEAUTHENTICATED:
+		dev_dbg(adapter->dev, "event: Deauthenticated\n");
+		adapter->dbg.num_event_deauth++;
+		if (priv->media_connected)
+			mwifiex_reset_connect_state(priv);
+		break;
+
+	case EVENT_DISASSOCIATED:
+		dev_dbg(adapter->dev, "event: Disassociated\n");
+		adapter->dbg.num_event_disassoc++;
+		if (priv->media_connected)
+			mwifiex_reset_connect_state(priv);
+		break;
+
+	case EVENT_LINK_LOST:
+		dev_dbg(adapter->dev, "event: Link lost\n");
+		adapter->dbg.num_event_link_lost++;
+		if (priv->media_connected)
+			mwifiex_reset_connect_state(priv);
+		break;
+
+	case EVENT_PS_SLEEP:
+		dev_dbg(adapter->dev, "info: EVENT: SLEEP\n");
+
+		adapter->ps_state = PS_STATE_PRE_SLEEP;
+
+		mwifiex_check_ps_cond(adapter);
+		break;
+
+	case EVENT_PS_AWAKE:
+		dev_dbg(adapter->dev, "info: EVENT: AWAKE\n");
+		if (!adapter->pps_uapsd_mode &&
+			priv->media_connected &&
+			adapter->sleep_period.period) {
+				adapter->pps_uapsd_mode = true;
+				dev_dbg(adapter->dev,
+					"event: PPS/UAPSD mode activated\n");
+		}
+		adapter->tx_lock_flag = false;
+		if (adapter->pps_uapsd_mode && adapter->gen_null_pkt) {
+			if (mwifiex_check_last_packet_indication(priv)) {
+				if (!adapter->data_sent) {
+					if (!mwifiex_send_null_packet(priv,
+					MWIFIEX_TxPD_POWER_MGMT_NULL_PACKET
+					|
+					MWIFIEX_TxPD_POWER_MGMT_LAST_PACKET))
+						adapter->ps_state =
+							PS_STATE_SLEEP;
+					return 0;
+				}
+			}
+		}
+		adapter->ps_state = PS_STATE_AWAKE;
+		adapter->pm_wakeup_card_req = false;
+		adapter->pm_wakeup_fw_try = false;
+
+		break;
+
+	case EVENT_DEEP_SLEEP_AWAKE:
+		adapter->if_ops.wakeup_complete(adapter);
+		dev_dbg(adapter->dev, "event: DS_AWAKE\n");
+		if (adapter->is_deep_sleep)
+			adapter->is_deep_sleep = false;
+		break;
+
+	case EVENT_HS_ACT_REQ:
+		dev_dbg(adapter->dev, "event: HS_ACT_REQ\n");
+		ret = mwifiex_send_cmd_async(priv,
+					     HostCmd_CMD_802_11_HS_CFG_ENH,
+					     0, 0, NULL);
+		break;
+
+	case EVENT_MIC_ERR_UNICAST:
+		dev_dbg(adapter->dev, "event: UNICAST MIC ERROR\n");
+		break;
+
+	case EVENT_MIC_ERR_MULTICAST:
+		dev_dbg(adapter->dev, "event: MULTICAST MIC ERROR\n");
+		break;
+	case EVENT_MIB_CHANGED:
+	case EVENT_INIT_DONE:
+		break;
+
+	case EVENT_ADHOC_BCN_LOST:
+		dev_dbg(adapter->dev, "event: ADHOC_BCN_LOST\n");
+		priv->adhoc_is_link_sensed = false;
+		mwifiex_clean_txrx(priv);
+		if (!netif_queue_stopped(priv->netdev))
+			netif_stop_queue(priv->netdev);
+		if (netif_carrier_ok(priv->netdev))
+			netif_carrier_off(priv->netdev);
+		break;
+
+	case EVENT_BG_SCAN_REPORT:
+		dev_dbg(adapter->dev, "event: BGS_REPORT\n");
+		/* Clear the previous scan result */
+		memset(adapter->scan_table, 0x00,
+		       sizeof(struct mwifiex_bssdescriptor) * IW_MAX_AP);
+		adapter->num_in_scan_table = 0;
+		adapter->bcn_buf_end = adapter->bcn_buf;
+		ret = mwifiex_send_cmd_async(priv,
+					     HostCmd_CMD_802_11_BG_SCAN_QUERY,
+					     HostCmd_ACT_GEN_GET, 0, NULL);
+		break;
+
+	case EVENT_PORT_RELEASE:
+		dev_dbg(adapter->dev, "event: PORT RELEASE\n");
+		break;
+
+	case EVENT_WMM_STATUS_CHANGE:
+		dev_dbg(adapter->dev, "event: WMM status changed\n");
+		ret = mwifiex_send_cmd_async(priv, HostCmd_CMD_WMM_GET_STATUS,
+					     0, 0, NULL);
+		break;
+
+	case EVENT_RSSI_LOW:
+		dev_dbg(adapter->dev, "event: Beacon RSSI_LOW\n");
+		break;
+	case EVENT_SNR_LOW:
+		dev_dbg(adapter->dev, "event: Beacon SNR_LOW\n");
+		break;
+	case EVENT_MAX_FAIL:
+		dev_dbg(adapter->dev, "event: MAX_FAIL\n");
+		break;
+	case EVENT_RSSI_HIGH:
+		dev_dbg(adapter->dev, "event: Beacon RSSI_HIGH\n");
+		break;
+	case EVENT_SNR_HIGH:
+		dev_dbg(adapter->dev, "event: Beacon SNR_HIGH\n");
+		break;
+	case EVENT_DATA_RSSI_LOW:
+		dev_dbg(adapter->dev, "event: Data RSSI_LOW\n");
+		break;
+	case EVENT_DATA_SNR_LOW:
+		dev_dbg(adapter->dev, "event: Data SNR_LOW\n");
+		break;
+	case EVENT_DATA_RSSI_HIGH:
+		dev_dbg(adapter->dev, "event: Data RSSI_HIGH\n");
+		break;
+	case EVENT_DATA_SNR_HIGH:
+		dev_dbg(adapter->dev, "event: Data SNR_HIGH\n");
+		break;
+	case EVENT_LINK_QUALITY:
+		dev_dbg(adapter->dev, "event: Link Quality\n");
+		break;
+	case EVENT_PRE_BEACON_LOST:
+		dev_dbg(adapter->dev, "event: Pre-Beacon Lost\n");
+		break;
+	case EVENT_IBSS_COALESCED:
+		dev_dbg(adapter->dev, "event: IBSS_COALESCED\n");
+		ret = mwifiex_send_cmd_async(priv,
+				HostCmd_CMD_802_11_IBSS_COALESCING_STATUS,
+				HostCmd_ACT_GEN_GET, 0, NULL);
+		break;
+	case EVENT_ADDBA:
+		dev_dbg(adapter->dev, "event: ADDBA Request\n");
+		mwifiex_send_cmd_async(priv, HostCmd_CMD_11N_ADDBA_RSP,
+				       HostCmd_ACT_GEN_SET, 0,
+				       adapter->event_body);
+		break;
+	case EVENT_DELBA:
+		dev_dbg(adapter->dev, "event: DELBA Request\n");
+		mwifiex_11n_delete_ba_stream(priv, adapter->event_body);
+		break;
+	case EVENT_BA_STREAM_TIEMOUT:
+		dev_dbg(adapter->dev, "event:  BA Stream timeout\n");
+		mwifiex_11n_ba_stream_timeout(priv,
+					      (struct host_cmd_ds_11n_batimeout
+					       *)
+					      adapter->event_body);
+		break;
+	case EVENT_AMSDU_AGGR_CTRL:
+		dev_dbg(adapter->dev, "event:  AMSDU_AGGR_CTRL %d\n",
+		       *(u16 *) adapter->event_body);
+		adapter->tx_buf_size =
+			min(adapter->curr_tx_buf_size,
+			    le16_to_cpu(*(__le16 *) adapter->event_body));
+		dev_dbg(adapter->dev, "event: tx_buf_size %d\n",
+				adapter->tx_buf_size);
+		break;
+
+	case EVENT_WEP_ICV_ERR:
+		dev_dbg(adapter->dev, "event: WEP ICV error\n");
+		break;
+
+	case EVENT_BW_CHANGE:
+		dev_dbg(adapter->dev, "event: BW Change\n");
+		break;
+
+	case EVENT_HOSTWAKE_STAIE:
+		dev_dbg(adapter->dev, "event: HOSTWAKE_STAIE %d\n", eventcause);
+		break;
+	default:
+		dev_dbg(adapter->dev, "event: unknown event id: %#x\n",
+						eventcause);
+		break;
+	}
+
+	return ret;
+}
diff -druN linux-2.6.39-libre/drivers/net/wireless/mwifiex/sta_ioctl.c linux-3.0-rc7-libre/drivers/net/wireless/mwifiex/sta_ioctl.c
--- linux-2.6.39-libre/drivers/net/wireless/mwifiex/sta_ioctl.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/net/wireless/mwifiex/sta_ioctl.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,1593 @@
+/*
+ * Marvell Wireless LAN device driver: functions for station ioctl
+ *
+ * Copyright (C) 2011, Marvell International Ltd.
+ *
+ * This software file (the "File") is distributed by Marvell International
+ * Ltd. under the terms of the GNU General Public License Version 2, June 1991
+ * (the "License").  You may use, redistribute and/or modify this File in
+ * accordance with the terms and conditions of the License, a copy of which
+ * is available by writing to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
+ * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
+ *
+ * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
+ * ARE EXPRESSLY DISCLAIMED.  The License provides additional details about
+ * this warranty disclaimer.
+ */
+
+#include "decl.h"
+#include "ioctl.h"
+#include "util.h"
+#include "fw.h"
+#include "main.h"
+#include "wmm.h"
+#include "11n.h"
+#include "cfg80211.h"
+
+/*
+ * Copies the multicast address list from device to driver.
+ *
+ * This function does not validate the destination memory for
+ * size, and the calling function must ensure enough memory is
+ * available.
+ */
+int mwifiex_copy_mcast_addr(struct mwifiex_multicast_list *mlist,
+			    struct net_device *dev)
+{
+	int i = 0;
+	struct netdev_hw_addr *ha;
+
+	netdev_for_each_mc_addr(ha, dev)
+		memcpy(&mlist->mac_list[i++], ha->addr, ETH_ALEN);
+
+	return i;
+}
+
+/*
+ * Wait queue completion handler.
+ *
+ * This function waits on a cmd wait queue. It also cancels the pending
+ * request after waking up, in case of errors.
+ */
+int mwifiex_wait_queue_complete(struct mwifiex_adapter *adapter)
+{
+	bool cancel_flag = false;
+	int status = adapter->cmd_wait_q.status;
+
+	dev_dbg(adapter->dev, "cmd pending\n");
+	atomic_inc(&adapter->cmd_pending);
+
+	/* Status pending, wake up main process */
+	queue_work(adapter->workqueue, &adapter->main_work);
+
+	/* Wait for completion */
+	wait_event_interruptible(adapter->cmd_wait_q.wait,
+					adapter->cmd_wait_q.condition);
+	if (!adapter->cmd_wait_q.condition)
+		cancel_flag = true;
+
+	if (cancel_flag) {
+		mwifiex_cancel_pending_ioctl(adapter);
+		dev_dbg(adapter->dev, "cmd cancel\n");
+	}
+	adapter->cmd_wait_q.status = 0;
+
+	return status;
+}
+
+/*
+ * This function prepares the correct firmware command and
+ * issues it to set the multicast list.
+ *
+ * This function can be used to enable promiscuous mode, or enable all
+ * multicast packets, or to enable selective multicast.
+ */
+int mwifiex_request_set_multicast_list(struct mwifiex_private *priv,
+				struct mwifiex_multicast_list *mcast_list)
+{
+	int ret = 0;
+	u16 old_pkt_filter;
+
+	old_pkt_filter = priv->curr_pkt_filter;
+
+	if (mcast_list->mode == MWIFIEX_PROMISC_MODE) {
+		dev_dbg(priv->adapter->dev, "info: Enable Promiscuous mode\n");
+		priv->curr_pkt_filter |= HostCmd_ACT_MAC_PROMISCUOUS_ENABLE;
+		priv->curr_pkt_filter &=
+			~HostCmd_ACT_MAC_ALL_MULTICAST_ENABLE;
+	} else {
+		/* Multicast */
+		priv->curr_pkt_filter &= ~HostCmd_ACT_MAC_PROMISCUOUS_ENABLE;
+		if (mcast_list->mode == MWIFIEX_MULTICAST_MODE) {
+			dev_dbg(priv->adapter->dev,
+				"info: Enabling All Multicast!\n");
+			priv->curr_pkt_filter |=
+				HostCmd_ACT_MAC_ALL_MULTICAST_ENABLE;
+		} else {
+			priv->curr_pkt_filter &=
+				~HostCmd_ACT_MAC_ALL_MULTICAST_ENABLE;
+			if (mcast_list->num_multicast_addr) {
+				dev_dbg(priv->adapter->dev,
+					"info: Set multicast list=%d\n",
+				       mcast_list->num_multicast_addr);
+				/* Set multicast addresses to firmware */
+				if (old_pkt_filter == priv->curr_pkt_filter) {
+					/* Send request to firmware */
+					ret = mwifiex_send_cmd_async(priv,
+						HostCmd_CMD_MAC_MULTICAST_ADR,
+						HostCmd_ACT_GEN_SET, 0,
+						mcast_list);
+				} else {
+					/* Send request to firmware */
+					ret = mwifiex_send_cmd_async(priv,
+						HostCmd_CMD_MAC_MULTICAST_ADR,
+						HostCmd_ACT_GEN_SET, 0,
+						mcast_list);
+				}
+			}
+		}
+	}
+	dev_dbg(priv->adapter->dev,
+		"info: old_pkt_filter=%#x, curr_pkt_filter=%#x\n",
+	       old_pkt_filter, priv->curr_pkt_filter);
+	if (old_pkt_filter != priv->curr_pkt_filter) {
+		ret = mwifiex_send_cmd_async(priv, HostCmd_CMD_MAC_CONTROL,
+					     HostCmd_ACT_GEN_SET,
+					     0, &priv->curr_pkt_filter);
+	}
+
+	return ret;
+}
+
+/*
+ * In Ad-Hoc mode, the IBSS is created if not found in scan list.
+ * In both Ad-Hoc and infra mode, an deauthentication is performed
+ * first.
+ */
+int mwifiex_bss_start(struct mwifiex_private *priv,
+		      struct mwifiex_ssid_bssid *ssid_bssid)
+{
+	int ret;
+	struct mwifiex_adapter *adapter = priv->adapter;
+	s32 i = -1;
+
+	priv->scan_block = false;
+	if (!ssid_bssid)
+		return -1;
+
+	if (priv->bss_mode == NL80211_IFTYPE_STATION) {
+		/* Infra mode */
+		ret = mwifiex_deauthenticate(priv, NULL);
+		if (ret)
+			return ret;
+
+		/* Search for the requested SSID in the scan table */
+		if (ssid_bssid->ssid.ssid_len)
+			i = mwifiex_find_ssid_in_list(priv, &ssid_bssid->ssid,
+						NULL, NL80211_IFTYPE_STATION);
+		else
+			i = mwifiex_find_bssid_in_list(priv,
+						(u8 *) &ssid_bssid->bssid,
+						NL80211_IFTYPE_STATION);
+		if (i < 0)
+			return -1;
+
+		dev_dbg(adapter->dev,
+			"info: SSID found in scan list ... associating...\n");
+
+		/* Clear any past association response stored for
+		 * application retrieval */
+		priv->assoc_rsp_size = 0;
+		ret = mwifiex_associate(priv, &adapter->scan_table[i]);
+		if (ret)
+			return ret;
+	} else {
+		/* Adhoc mode */
+		/* If the requested SSID matches current SSID, return */
+		if (ssid_bssid->ssid.ssid_len &&
+		    (!mwifiex_ssid_cmp
+		     (&priv->curr_bss_params.bss_descriptor.ssid,
+		      &ssid_bssid->ssid)))
+			return 0;
+
+		/* Exit Adhoc mode first */
+		dev_dbg(adapter->dev, "info: Sending Adhoc Stop\n");
+		ret = mwifiex_deauthenticate(priv, NULL);
+		if (ret)
+			return ret;
+
+		priv->adhoc_is_link_sensed = false;
+
+		/* Search for the requested network in the scan table */
+		if (ssid_bssid->ssid.ssid_len)
+			i = mwifiex_find_ssid_in_list(priv,
+						      &ssid_bssid->ssid, NULL,
+						      NL80211_IFTYPE_ADHOC);
+		else
+			i = mwifiex_find_bssid_in_list(priv,
+						       (u8 *)&ssid_bssid->bssid,
+						       NL80211_IFTYPE_ADHOC);
+
+		if (i >= 0) {
+			dev_dbg(adapter->dev, "info: network found in scan"
+							" list. Joining...\n");
+			ret = mwifiex_adhoc_join(priv, &adapter->scan_table[i]);
+			if (ret)
+				return ret;
+		} else {
+			dev_dbg(adapter->dev, "info: Network not found in "
+				"the list, creating adhoc with ssid = %s\n",
+			       ssid_bssid->ssid.ssid);
+			ret = mwifiex_adhoc_start(priv, &ssid_bssid->ssid);
+			if (ret)
+				return ret;
+		}
+	}
+
+	return ret;
+}
+
+/*
+ * IOCTL request handler to set host sleep configuration.
+ *
+ * This function prepares the correct firmware command and
+ * issues it.
+ */
+int mwifiex_set_hs_params(struct mwifiex_private *priv, u16 action,
+			  int cmd_type, struct mwifiex_ds_hs_cfg *hs_cfg)
+
+{
+	struct mwifiex_adapter *adapter = priv->adapter;
+	int status = 0;
+	u32 prev_cond = 0;
+
+	if (!hs_cfg)
+		return -ENOMEM;
+
+	switch (action) {
+	case HostCmd_ACT_GEN_SET:
+		if (adapter->pps_uapsd_mode) {
+			dev_dbg(adapter->dev, "info: Host Sleep IOCTL"
+				" is blocked in UAPSD/PPS mode\n");
+			status = -1;
+			break;
+		}
+		if (hs_cfg->is_invoke_hostcmd) {
+			if (hs_cfg->conditions == HOST_SLEEP_CFG_CANCEL) {
+				if (!adapter->is_hs_configured)
+					/* Already cancelled */
+					break;
+				/* Save previous condition */
+				prev_cond = le32_to_cpu(adapter->hs_cfg
+							.conditions);
+				adapter->hs_cfg.conditions =
+						cpu_to_le32(hs_cfg->conditions);
+			} else if (hs_cfg->conditions) {
+				adapter->hs_cfg.conditions =
+						cpu_to_le32(hs_cfg->conditions);
+				adapter->hs_cfg.gpio = (u8)hs_cfg->gpio;
+				if (hs_cfg->gap)
+					adapter->hs_cfg.gap = (u8)hs_cfg->gap;
+			} else if (adapter->hs_cfg.conditions ==
+						cpu_to_le32(
+						HOST_SLEEP_CFG_CANCEL)) {
+				/* Return failure if no parameters for HS
+				   enable */
+				status = -1;
+				break;
+			}
+			if (cmd_type == MWIFIEX_SYNC_CMD)
+				status = mwifiex_send_cmd_sync(priv,
+						HostCmd_CMD_802_11_HS_CFG_ENH,
+						HostCmd_ACT_GEN_SET, 0,
+						&adapter->hs_cfg);
+			else
+				status = mwifiex_send_cmd_async(priv,
+						HostCmd_CMD_802_11_HS_CFG_ENH,
+						HostCmd_ACT_GEN_SET, 0,
+						&adapter->hs_cfg);
+			if (hs_cfg->conditions == HOST_SLEEP_CFG_CANCEL)
+				/* Restore previous condition */
+				adapter->hs_cfg.conditions =
+						cpu_to_le32(prev_cond);
+		} else {
+			adapter->hs_cfg.conditions =
+				cpu_to_le32(hs_cfg->conditions);
+			adapter->hs_cfg.gpio = (u8)hs_cfg->gpio;
+			adapter->hs_cfg.gap = (u8)hs_cfg->gap;
+		}
+		break;
+	case HostCmd_ACT_GEN_GET:
+		hs_cfg->conditions = le32_to_cpu(adapter->hs_cfg.conditions);
+		hs_cfg->gpio = adapter->hs_cfg.gpio;
+		hs_cfg->gap = adapter->hs_cfg.gap;
+		break;
+	default:
+		status = -1;
+		break;
+	}
+
+	return status;
+}
+
+/*
+ * Sends IOCTL request to cancel the existing Host Sleep configuration.
+ *
+ * This function allocates the IOCTL request buffer, fills it
+ * with requisite parameters and calls the IOCTL handler.
+ */
+int mwifiex_cancel_hs(struct mwifiex_private *priv, int cmd_type)
+{
+	struct mwifiex_ds_hs_cfg hscfg;
+
+	hscfg.conditions = HOST_SLEEP_CFG_CANCEL;
+	hscfg.is_invoke_hostcmd = true;
+
+	return mwifiex_set_hs_params(priv, HostCmd_ACT_GEN_SET,
+				    cmd_type, &hscfg);
+}
+EXPORT_SYMBOL_GPL(mwifiex_cancel_hs);
+
+/*
+ * Sends IOCTL request to cancel the existing Host Sleep configuration.
+ *
+ * This function allocates the IOCTL request buffer, fills it
+ * with requisite parameters and calls the IOCTL handler.
+ */
+int mwifiex_enable_hs(struct mwifiex_adapter *adapter)
+{
+	struct mwifiex_ds_hs_cfg hscfg;
+
+	if (adapter->hs_activated) {
+		dev_dbg(adapter->dev, "cmd: HS Already actived\n");
+		return true;
+	}
+
+	adapter->hs_activate_wait_q_woken = false;
+
+	memset(&hscfg, 0, sizeof(struct mwifiex_hs_config_param));
+	hscfg.is_invoke_hostcmd = true;
+
+	if (mwifiex_set_hs_params(mwifiex_get_priv(adapter,
+						       MWIFIEX_BSS_ROLE_STA),
+				  HostCmd_ACT_GEN_SET, MWIFIEX_SYNC_CMD,
+				  &hscfg)) {
+		dev_err(adapter->dev, "IOCTL request HS enable failed\n");
+		return false;
+	}
+
+	wait_event_interruptible(adapter->hs_activate_wait_q,
+			adapter->hs_activate_wait_q_woken);
+
+	return true;
+}
+EXPORT_SYMBOL_GPL(mwifiex_enable_hs);
+
+/*
+ * IOCTL request handler to get BSS information.
+ *
+ * This function collates the information from different driver structures
+ * to send to the user.
+ */
+int mwifiex_get_bss_info(struct mwifiex_private *priv,
+			 struct mwifiex_bss_info *info)
+{
+	struct mwifiex_adapter *adapter = priv->adapter;
+	struct mwifiex_bssdescriptor *bss_desc;
+	s32 tbl_idx;
+
+	if (!info)
+		return -1;
+
+	bss_desc = &priv->curr_bss_params.bss_descriptor;
+
+	info->bss_mode = priv->bss_mode;
+
+	memcpy(&info->ssid, &bss_desc->ssid,
+	       sizeof(struct mwifiex_802_11_ssid));
+
+	memcpy(&info->bssid, &bss_desc->mac_address, ETH_ALEN);
+
+	info->bss_chan = bss_desc->channel;
+
+	info->region_code = adapter->region_code;
+
+	/* Scan table index if connected */
+	info->scan_table_idx = 0;
+	if (priv->media_connected) {
+		tbl_idx =
+			mwifiex_find_ssid_in_list(priv, &bss_desc->ssid,
+						  bss_desc->mac_address,
+						  priv->bss_mode);
+		if (tbl_idx >= 0)
+			info->scan_table_idx = tbl_idx;
+	}
+
+	info->media_connected = priv->media_connected;
+
+	info->max_power_level = priv->max_tx_power_level;
+	info->min_power_level = priv->min_tx_power_level;
+
+	info->adhoc_state = priv->adhoc_state;
+
+	info->bcn_nf_last = priv->bcn_nf_last;
+
+	if (priv->sec_info.wep_status == MWIFIEX_802_11_WEP_ENABLED)
+		info->wep_status = true;
+	else
+		info->wep_status = false;
+
+	info->is_hs_configured = adapter->is_hs_configured;
+	info->is_deep_sleep = adapter->is_deep_sleep;
+
+	return 0;
+}
+
+/*
+ * The function sets band configurations.
+ *
+ * it performs extra checks to make sure the Ad-Hoc
+ * band and channel are compatible. Otherwise it returns an error.
+ *
+ */
+int mwifiex_set_radio_band_cfg(struct mwifiex_private *priv,
+			       struct mwifiex_ds_band_cfg *radio_cfg)
+{
+	struct mwifiex_adapter *adapter = priv->adapter;
+	u8 infra_band, adhoc_band;
+	u32 adhoc_channel;
+
+	infra_band = (u8) radio_cfg->config_bands;
+	adhoc_band = (u8) radio_cfg->adhoc_start_band;
+	adhoc_channel = radio_cfg->adhoc_channel;
+
+	/* SET Infra band */
+	if ((infra_band | adapter->fw_bands) & ~adapter->fw_bands)
+		return -1;
+
+	adapter->config_bands = infra_band;
+
+	/* SET Ad-hoc Band */
+	if ((adhoc_band | adapter->fw_bands) & ~adapter->fw_bands)
+		return -1;
+
+	if (adhoc_band)
+		adapter->adhoc_start_band = adhoc_band;
+	adapter->chan_offset = (u8) radio_cfg->sec_chan_offset;
+	/*
+	 * If no adhoc_channel is supplied verify if the existing adhoc
+	 * channel compiles with new adhoc_band
+	 */
+	if (!adhoc_channel) {
+		if (!mwifiex_get_cfp_by_band_and_channel_from_cfg80211
+		     (priv, adapter->adhoc_start_band,
+		     priv->adhoc_channel)) {
+			/* Pass back the default channel */
+			radio_cfg->adhoc_channel = DEFAULT_AD_HOC_CHANNEL;
+			if ((adapter->adhoc_start_band & BAND_A)
+			    || (adapter->adhoc_start_band & BAND_AN))
+				radio_cfg->adhoc_channel =
+					DEFAULT_AD_HOC_CHANNEL_A;
+		}
+	} else {	/* Retrurn error if adhoc_band and
+			   adhoc_channel combination is invalid */
+		if (!mwifiex_get_cfp_by_band_and_channel_from_cfg80211
+		    (priv, adapter->adhoc_start_band, (u16) adhoc_channel))
+			return -1;
+		priv->adhoc_channel = (u8) adhoc_channel;
+	}
+	if ((adhoc_band & BAND_GN) || (adhoc_band & BAND_AN))
+		adapter->adhoc_11n_enabled = true;
+	else
+		adapter->adhoc_11n_enabled = false;
+
+	return 0;
+}
+
+/*
+ * IOCTL request handler to set/get active channel.
+ *
+ * This function performs validity checking on channel/frequency
+ * compatibility and returns failure if not valid.
+ */
+int mwifiex_bss_set_channel(struct mwifiex_private *priv,
+			    struct mwifiex_chan_freq_power *chan)
+{
+	struct mwifiex_adapter *adapter = priv->adapter;
+	struct mwifiex_chan_freq_power *cfp = NULL;
+
+	if (!chan)
+		return -1;
+
+	if (!chan->channel && !chan->freq)
+		return -1;
+	if (adapter->adhoc_start_band & BAND_AN)
+		adapter->adhoc_start_band = BAND_G | BAND_B | BAND_GN;
+	else if (adapter->adhoc_start_band & BAND_A)
+		adapter->adhoc_start_band = BAND_G | BAND_B;
+	if (chan->channel) {
+		if (chan->channel <= MAX_CHANNEL_BAND_BG)
+			cfp = mwifiex_get_cfp_by_band_and_channel_from_cfg80211
+					(priv, 0, (u16) chan->channel);
+		if (!cfp) {
+			cfp = mwifiex_get_cfp_by_band_and_channel_from_cfg80211
+					(priv, BAND_A, (u16) chan->channel);
+			if (cfp) {
+				if (adapter->adhoc_11n_enabled)
+					adapter->adhoc_start_band = BAND_A
+						| BAND_AN;
+				else
+					adapter->adhoc_start_band = BAND_A;
+			}
+		}
+	} else {
+		if (chan->freq <= MAX_FREQUENCY_BAND_BG)
+			cfp = mwifiex_get_cfp_by_band_and_freq_from_cfg80211(
+							priv, 0, chan->freq);
+		if (!cfp) {
+			cfp = mwifiex_get_cfp_by_band_and_freq_from_cfg80211
+						  (priv, BAND_A, chan->freq);
+			if (cfp) {
+				if (adapter->adhoc_11n_enabled)
+					adapter->adhoc_start_band = BAND_A
+						| BAND_AN;
+				else
+					adapter->adhoc_start_band = BAND_A;
+			}
+		}
+	}
+	if (!cfp || !cfp->channel) {
+		dev_err(adapter->dev, "invalid channel/freq\n");
+		return -1;
+	}
+	priv->adhoc_channel = (u8) cfp->channel;
+	chan->channel = cfp->channel;
+	chan->freq = cfp->freq;
+
+	return 0;
+}
+
+/*
+ * IOCTL request handler to set/get Ad-Hoc channel.
+ *
+ * This function prepares the correct firmware command and
+ * issues it to set or get the ad-hoc channel.
+ */
+static int mwifiex_bss_ioctl_ibss_channel(struct mwifiex_private *priv,
+					  u16 action, u16 *channel)
+{
+	if (action == HostCmd_ACT_GEN_GET) {
+		if (!priv->media_connected) {
+			*channel = priv->adhoc_channel;
+			return 0;
+		}
+	} else {
+		priv->adhoc_channel = (u8) *channel;
+	}
+
+	return mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_RF_CHANNEL,
+				    action, 0, channel);
+}
+
+/*
+ * IOCTL request handler to find a particular BSS.
+ *
+ * The BSS can be searched with either a BSSID or a SSID. If none of
+ * these are provided, just the best BSS (best RSSI) is returned.
+ */
+int mwifiex_bss_ioctl_find_bss(struct mwifiex_private *priv,
+			       struct mwifiex_ssid_bssid *ssid_bssid)
+{
+	struct mwifiex_adapter *adapter = priv->adapter;
+	struct mwifiex_bssdescriptor *bss_desc;
+	u8 zero_mac[ETH_ALEN] = { 0, 0, 0, 0, 0, 0 };
+	u8 mac[ETH_ALEN];
+	int i = 0;
+
+	if (memcmp(ssid_bssid->bssid, zero_mac, sizeof(zero_mac))) {
+		i = mwifiex_find_bssid_in_list(priv,
+					       (u8 *) ssid_bssid->bssid,
+					       priv->bss_mode);
+		if (i < 0) {
+			memcpy(mac, ssid_bssid->bssid, sizeof(mac));
+			dev_err(adapter->dev, "cannot find bssid %pM\n", mac);
+			return -1;
+		}
+		bss_desc = &adapter->scan_table[i];
+		memcpy(&ssid_bssid->ssid, &bss_desc->ssid,
+				sizeof(struct mwifiex_802_11_ssid));
+	} else if (ssid_bssid->ssid.ssid_len) {
+		i = mwifiex_find_ssid_in_list(priv, &ssid_bssid->ssid, NULL,
+					      priv->bss_mode);
+		if (i < 0) {
+			dev_err(adapter->dev, "cannot find ssid %s\n",
+					ssid_bssid->ssid.ssid);
+			return -1;
+		}
+		bss_desc = &adapter->scan_table[i];
+		memcpy(ssid_bssid->bssid, bss_desc->mac_address, ETH_ALEN);
+	} else {
+		return mwifiex_find_best_network(priv, ssid_bssid);
+	}
+
+	return 0;
+}
+
+/*
+ * IOCTL request handler to change Ad-Hoc channel.
+ *
+ * This function allocates the IOCTL request buffer, fills it
+ * with requisite parameters and calls the IOCTL handler.
+ *
+ * The function follows the following steps to perform the change -
+ *      - Get current IBSS information
+ *      - Get current channel
+ *      - If no change is required, return
+ *      - If not connected, change channel and return
+ *      - If connected,
+ *          - Disconnect
+ *          - Change channel
+ *          - Perform specific SSID scan with same SSID
+ *          - Start/Join the IBSS
+ */
+int
+mwifiex_drv_change_adhoc_chan(struct mwifiex_private *priv, int channel)
+{
+	int ret;
+	struct mwifiex_bss_info bss_info;
+	struct mwifiex_ssid_bssid ssid_bssid;
+	u16 curr_chan = 0;
+
+	memset(&bss_info, 0, sizeof(bss_info));
+
+	/* Get BSS information */
+	if (mwifiex_get_bss_info(priv, &bss_info))
+		return -1;
+
+	/* Get current channel */
+	ret = mwifiex_bss_ioctl_ibss_channel(priv, HostCmd_ACT_GEN_GET,
+					     &curr_chan);
+
+	if (curr_chan == channel) {
+		ret = 0;
+		goto done;
+	}
+	dev_dbg(priv->adapter->dev, "cmd: updating channel from %d to %d\n",
+			curr_chan, channel);
+
+	if (!bss_info.media_connected) {
+		ret = 0;
+		goto done;
+	}
+
+	/* Do disonnect */
+	memset(&ssid_bssid, 0, ETH_ALEN);
+	ret = mwifiex_deauthenticate(priv, ssid_bssid.bssid);
+
+	ret = mwifiex_bss_ioctl_ibss_channel(priv, HostCmd_ACT_GEN_SET,
+					     (u16 *) &channel);
+
+	/* Do specific SSID scanning */
+	if (mwifiex_request_scan(priv, &bss_info.ssid)) {
+		ret = -1;
+		goto done;
+	}
+	/* Start/Join Adhoc network */
+	memset(&ssid_bssid, 0, sizeof(struct mwifiex_ssid_bssid));
+	memcpy(&ssid_bssid.ssid, &bss_info.ssid,
+	       sizeof(struct mwifiex_802_11_ssid));
+
+	ret = mwifiex_bss_start(priv, &ssid_bssid);
+done:
+	return ret;
+}
+
+/*
+ * IOCTL request handler to get rate.
+ *
+ * This function prepares the correct firmware command and
+ * issues it to get the current rate if it is connected,
+ * otherwise, the function returns the lowest supported rate
+ * for the band.
+ */
+static int mwifiex_rate_ioctl_get_rate_value(struct mwifiex_private *priv,
+					     struct mwifiex_rate_cfg *rate_cfg)
+{
+	struct mwifiex_adapter *adapter = priv->adapter;
+
+	rate_cfg->is_rate_auto = priv->is_data_rate_auto;
+	if (!priv->media_connected) {
+		switch (adapter->config_bands) {
+		case BAND_B:
+			/* Return the lowest supported rate for B band */
+			rate_cfg->rate = supported_rates_b[0] & 0x7f;
+			break;
+		case BAND_G:
+		case BAND_G | BAND_GN:
+			/* Return the lowest supported rate for G band */
+			rate_cfg->rate = supported_rates_g[0] & 0x7f;
+			break;
+		case BAND_B | BAND_G:
+		case BAND_A | BAND_B | BAND_G:
+		case BAND_A | BAND_B:
+		case BAND_A | BAND_B | BAND_G | BAND_AN | BAND_GN:
+		case BAND_B | BAND_G | BAND_GN:
+			/* Return the lowest supported rate for BG band */
+			rate_cfg->rate = supported_rates_bg[0] & 0x7f;
+			break;
+		case BAND_A:
+		case BAND_A | BAND_G:
+		case BAND_A | BAND_G | BAND_AN | BAND_GN:
+		case BAND_A | BAND_AN:
+			/* Return the lowest supported rate for A band */
+			rate_cfg->rate = supported_rates_a[0] & 0x7f;
+			break;
+		case BAND_GN:
+			/* Return the lowest supported rate for N band */
+			rate_cfg->rate = supported_rates_n[0] & 0x7f;
+			break;
+		default:
+			dev_warn(adapter->dev, "invalid band %#x\n",
+			       adapter->config_bands);
+			break;
+		}
+	} else {
+		return mwifiex_send_cmd_sync(priv,
+					    HostCmd_CMD_802_11_TX_RATE_QUERY,
+					    HostCmd_ACT_GEN_GET, 0, NULL);
+	}
+
+	return 0;
+}
+
+/*
+ * IOCTL request handler to set rate.
+ *
+ * This function prepares the correct firmware command and
+ * issues it to set the current rate.
+ *
+ * The function also performs validation checking on the supplied value.
+ */
+static int mwifiex_rate_ioctl_set_rate_value(struct mwifiex_private *priv,
+					     struct mwifiex_rate_cfg *rate_cfg)
+{
+	u8 rates[MWIFIEX_SUPPORTED_RATES];
+	u8 *rate;
+	int rate_index, ret;
+	u16 bitmap_rates[MAX_BITMAP_RATES_SIZE];
+	u32 i;
+	struct mwifiex_adapter *adapter = priv->adapter;
+
+	if (rate_cfg->is_rate_auto) {
+		memset(bitmap_rates, 0, sizeof(bitmap_rates));
+		/* Support all HR/DSSS rates */
+		bitmap_rates[0] = 0x000F;
+		/* Support all OFDM rates */
+		bitmap_rates[1] = 0x00FF;
+		/* Support all HT-MCSs rate */
+		for (i = 0; i < ARRAY_SIZE(priv->bitmap_rates) - 3; i++)
+			bitmap_rates[i + 2] = 0xFFFF;
+		bitmap_rates[9] = 0x3FFF;
+	} else {
+		memset(rates, 0, sizeof(rates));
+		mwifiex_get_active_data_rates(priv, rates);
+		rate = rates;
+		for (i = 0; (rate[i] && i < MWIFIEX_SUPPORTED_RATES); i++) {
+			dev_dbg(adapter->dev, "info: rate=%#x wanted=%#x\n",
+				rate[i], rate_cfg->rate);
+			if ((rate[i] & 0x7f) == (rate_cfg->rate & 0x7f))
+				break;
+		}
+		if (!rate[i] || (i == MWIFIEX_SUPPORTED_RATES)) {
+			dev_err(adapter->dev, "fixed data rate %#x is out "
+			       "of range\n", rate_cfg->rate);
+			return -1;
+		}
+		memset(bitmap_rates, 0, sizeof(bitmap_rates));
+
+		rate_index = mwifiex_data_rate_to_index(rate_cfg->rate);
+
+		/* Only allow b/g rates to be set */
+		if (rate_index >= MWIFIEX_RATE_INDEX_HRDSSS0 &&
+		    rate_index <= MWIFIEX_RATE_INDEX_HRDSSS3) {
+			bitmap_rates[0] = 1 << rate_index;
+		} else {
+			rate_index -= 1; /* There is a 0x00 in the table */
+			if (rate_index >= MWIFIEX_RATE_INDEX_OFDM0 &&
+			    rate_index <= MWIFIEX_RATE_INDEX_OFDM7)
+				bitmap_rates[1] = 1 << (rate_index -
+						   MWIFIEX_RATE_INDEX_OFDM0);
+		}
+	}
+
+	ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_TX_RATE_CFG,
+				    HostCmd_ACT_GEN_SET, 0, bitmap_rates);
+
+	return ret;
+}
+
+/*
+ * IOCTL request handler to set/get rate.
+ *
+ * This function can be used to set/get either the rate value or the
+ * rate index.
+ */
+static int mwifiex_rate_ioctl_cfg(struct mwifiex_private *priv,
+				  struct mwifiex_rate_cfg *rate_cfg)
+{
+	int status;
+
+	if (!rate_cfg)
+		return -1;
+
+	if (rate_cfg->action == HostCmd_ACT_GEN_GET)
+		status = mwifiex_rate_ioctl_get_rate_value(priv, rate_cfg);
+	else
+		status = mwifiex_rate_ioctl_set_rate_value(priv, rate_cfg);
+
+	return status;
+}
+
+/*
+ * Sends IOCTL request to get the data rate.
+ *
+ * This function allocates the IOCTL request buffer, fills it
+ * with requisite parameters and calls the IOCTL handler.
+ */
+int mwifiex_drv_get_data_rate(struct mwifiex_private *priv,
+			      struct mwifiex_rate_cfg *rate)
+{
+	int ret;
+
+	memset(rate, 0, sizeof(struct mwifiex_rate_cfg));
+	rate->action = HostCmd_ACT_GEN_GET;
+	ret = mwifiex_rate_ioctl_cfg(priv, rate);
+
+	if (!ret) {
+		if (rate && rate->is_rate_auto)
+			rate->rate = mwifiex_index_to_data_rate(priv->tx_rate,
+							priv->tx_htinfo);
+		else if (rate)
+			rate->rate = priv->data_rate;
+	} else {
+		ret = -1;
+	}
+
+	return ret;
+}
+
+/*
+ * IOCTL request handler to set tx power configuration.
+ *
+ * This function prepares the correct firmware command and
+ * issues it.
+ *
+ * For non-auto power mode, all the following power groups are set -
+ *      - Modulation class HR/DSSS
+ *      - Modulation class OFDM
+ *      - Modulation class HTBW20
+ *      - Modulation class HTBW40
+ */
+int mwifiex_set_tx_power(struct mwifiex_private *priv,
+			 struct mwifiex_power_cfg *power_cfg)
+{
+	int ret;
+	struct host_cmd_ds_txpwr_cfg *txp_cfg;
+	struct mwifiex_types_power_group *pg_tlv;
+	struct mwifiex_power_group *pg;
+	u8 *buf;
+	u16 dbm = 0;
+
+	if (!power_cfg->is_power_auto) {
+		dbm = (u16) power_cfg->power_level;
+		if ((dbm < priv->min_tx_power_level) ||
+		    (dbm > priv->max_tx_power_level)) {
+			dev_err(priv->adapter->dev, "txpower value %d dBm"
+					" is out of range (%d dBm-%d dBm)\n",
+					dbm, priv->min_tx_power_level,
+					priv->max_tx_power_level);
+			return -1;
+		}
+	}
+	buf = kzalloc(MWIFIEX_SIZE_OF_CMD_BUFFER, GFP_KERNEL);
+	if (!buf) {
+		dev_err(priv->adapter->dev, "%s: failed to alloc cmd buffer\n",
+				__func__);
+		return -ENOMEM;
+	}
+
+	txp_cfg = (struct host_cmd_ds_txpwr_cfg *) buf;
+	txp_cfg->action = cpu_to_le16(HostCmd_ACT_GEN_SET);
+	if (!power_cfg->is_power_auto) {
+		txp_cfg->mode = cpu_to_le32(1);
+		pg_tlv = (struct mwifiex_types_power_group *) (buf +
+				sizeof(struct host_cmd_ds_txpwr_cfg));
+		pg_tlv->type = TLV_TYPE_POWER_GROUP;
+		pg_tlv->length = 4 * sizeof(struct mwifiex_power_group);
+		pg = (struct mwifiex_power_group *) (buf +
+				sizeof(struct host_cmd_ds_txpwr_cfg) +
+				sizeof(struct mwifiex_types_power_group));
+		/* Power group for modulation class HR/DSSS */
+		pg->first_rate_code = 0x00;
+		pg->last_rate_code = 0x03;
+		pg->modulation_class = MOD_CLASS_HR_DSSS;
+		pg->power_step = 0;
+		pg->power_min = (s8) dbm;
+		pg->power_max = (s8) dbm;
+		pg++;
+		/* Power group for modulation class OFDM */
+		pg->first_rate_code = 0x00;
+		pg->last_rate_code = 0x07;
+		pg->modulation_class = MOD_CLASS_OFDM;
+		pg->power_step = 0;
+		pg->power_min = (s8) dbm;
+		pg->power_max = (s8) dbm;
+		pg++;
+		/* Power group for modulation class HTBW20 */
+		pg->first_rate_code = 0x00;
+		pg->last_rate_code = 0x20;
+		pg->modulation_class = MOD_CLASS_HT;
+		pg->power_step = 0;
+		pg->power_min = (s8) dbm;
+		pg->power_max = (s8) dbm;
+		pg->ht_bandwidth = HT_BW_20;
+		pg++;
+		/* Power group for modulation class HTBW40 */
+		pg->first_rate_code = 0x00;
+		pg->last_rate_code = 0x20;
+		pg->modulation_class = MOD_CLASS_HT;
+		pg->power_step = 0;
+		pg->power_min = (s8) dbm;
+		pg->power_max = (s8) dbm;
+		pg->ht_bandwidth = HT_BW_40;
+	}
+	ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_TXPWR_CFG,
+				    HostCmd_ACT_GEN_SET, 0, buf);
+
+	kfree(buf);
+	return ret;
+}
+
+/*
+ * IOCTL request handler to get power save mode.
+ *
+ * This function prepares the correct firmware command and
+ * issues it.
+ */
+int mwifiex_drv_set_power(struct mwifiex_private *priv, u32 *ps_mode)
+{
+	int ret;
+	struct mwifiex_adapter *adapter = priv->adapter;
+	u16 sub_cmd;
+
+	if (*ps_mode)
+		adapter->ps_mode = MWIFIEX_802_11_POWER_MODE_PSP;
+	else
+		adapter->ps_mode = MWIFIEX_802_11_POWER_MODE_CAM;
+	sub_cmd = (*ps_mode) ? EN_AUTO_PS : DIS_AUTO_PS;
+	ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_PS_MODE_ENH,
+				    sub_cmd, BITMAP_STA_PS, NULL);
+	if ((!ret) && (sub_cmd == DIS_AUTO_PS))
+		ret = mwifiex_send_cmd_async(priv,
+				HostCmd_CMD_802_11_PS_MODE_ENH, GET_PS,
+				0, NULL);
+
+	return ret;
+}
+
+/*
+ * IOCTL request handler to set/reset WPA IE.
+ *
+ * The supplied WPA IE is treated as a opaque buffer. Only the first field
+ * is checked to determine WPA version. If buffer length is zero, the existing
+ * WPA IE is reset.
+ */
+static int mwifiex_set_wpa_ie_helper(struct mwifiex_private *priv,
+				     u8 *ie_data_ptr, u16 ie_len)
+{
+	if (ie_len) {
+		if (ie_len > sizeof(priv->wpa_ie)) {
+			dev_err(priv->adapter->dev,
+				"failed to copy WPA IE, too big\n");
+			return -1;
+		}
+		memcpy(priv->wpa_ie, ie_data_ptr, ie_len);
+		priv->wpa_ie_len = (u8) ie_len;
+		dev_dbg(priv->adapter->dev, "cmd: Set Wpa_ie_len=%d IE=%#x\n",
+				priv->wpa_ie_len, priv->wpa_ie[0]);
+
+		if (priv->wpa_ie[0] == WLAN_EID_WPA) {
+			priv->sec_info.wpa_enabled = true;
+		} else if (priv->wpa_ie[0] == WLAN_EID_RSN) {
+			priv->sec_info.wpa2_enabled = true;
+		} else {
+			priv->sec_info.wpa_enabled = false;
+			priv->sec_info.wpa2_enabled = false;
+		}
+	} else {
+		memset(priv->wpa_ie, 0, sizeof(priv->wpa_ie));
+		priv->wpa_ie_len = 0;
+		dev_dbg(priv->adapter->dev, "info: reset wpa_ie_len=%d IE=%#x\n",
+			priv->wpa_ie_len, priv->wpa_ie[0]);
+		priv->sec_info.wpa_enabled = false;
+		priv->sec_info.wpa2_enabled = false;
+	}
+
+	return 0;
+}
+
+/*
+ * IOCTL request handler to set/reset WAPI IE.
+ *
+ * The supplied WAPI IE is treated as a opaque buffer. Only the first field
+ * is checked to internally enable WAPI. If buffer length is zero, the existing
+ * WAPI IE is reset.
+ */
+static int mwifiex_set_wapi_ie(struct mwifiex_private *priv,
+			       u8 *ie_data_ptr, u16 ie_len)
+{
+	if (ie_len) {
+		if (ie_len > sizeof(priv->wapi_ie)) {
+			dev_dbg(priv->adapter->dev,
+				"info: failed to copy WAPI IE, too big\n");
+			return -1;
+		}
+		memcpy(priv->wapi_ie, ie_data_ptr, ie_len);
+		priv->wapi_ie_len = ie_len;
+		dev_dbg(priv->adapter->dev, "cmd: Set wapi_ie_len=%d IE=%#x\n",
+				priv->wapi_ie_len, priv->wapi_ie[0]);
+
+		if (priv->wapi_ie[0] == WLAN_EID_BSS_AC_ACCESS_DELAY)
+			priv->sec_info.wapi_enabled = true;
+	} else {
+		memset(priv->wapi_ie, 0, sizeof(priv->wapi_ie));
+		priv->wapi_ie_len = ie_len;
+		dev_dbg(priv->adapter->dev,
+			"info: Reset wapi_ie_len=%d IE=%#x\n",
+		       priv->wapi_ie_len, priv->wapi_ie[0]);
+		priv->sec_info.wapi_enabled = false;
+	}
+	return 0;
+}
+
+/*
+ * IOCTL request handler to set WAPI key.
+ *
+ * This function prepares the correct firmware command and
+ * issues it.
+ */
+static int mwifiex_sec_ioctl_set_wapi_key(struct mwifiex_private *priv,
+			       struct mwifiex_ds_encrypt_key *encrypt_key)
+{
+
+	return mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_KEY_MATERIAL,
+				    HostCmd_ACT_GEN_SET, KEY_INFO_ENABLED,
+				    encrypt_key);
+}
+
+/*
+ * IOCTL request handler to set WEP network key.
+ *
+ * This function prepares the correct firmware command and
+ * issues it, after validation checks.
+ */
+static int mwifiex_sec_ioctl_set_wep_key(struct mwifiex_private *priv,
+			      struct mwifiex_ds_encrypt_key *encrypt_key)
+{
+	int ret;
+	struct mwifiex_wep_key *wep_key;
+	int index;
+
+	if (priv->wep_key_curr_index >= NUM_WEP_KEYS)
+		priv->wep_key_curr_index = 0;
+	wep_key = &priv->wep_key[priv->wep_key_curr_index];
+	index = encrypt_key->key_index;
+	if (encrypt_key->key_disable) {
+		priv->sec_info.wep_status = MWIFIEX_802_11_WEP_DISABLED;
+	} else if (!encrypt_key->key_len) {
+		/* Copy the required key as the current key */
+		wep_key = &priv->wep_key[index];
+		if (!wep_key->key_length) {
+			dev_err(priv->adapter->dev,
+				"key not set, so cannot enable it\n");
+			return -1;
+		}
+		priv->wep_key_curr_index = (u16) index;
+		priv->sec_info.wep_status = MWIFIEX_802_11_WEP_ENABLED;
+	} else {
+		wep_key = &priv->wep_key[index];
+		memset(wep_key, 0, sizeof(struct mwifiex_wep_key));
+		/* Copy the key in the driver */
+		memcpy(wep_key->key_material,
+		       encrypt_key->key_material,
+		       encrypt_key->key_len);
+		wep_key->key_index = index;
+		wep_key->key_length = encrypt_key->key_len;
+		priv->sec_info.wep_status = MWIFIEX_802_11_WEP_ENABLED;
+	}
+	if (wep_key->key_length) {
+		/* Send request to firmware */
+		ret = mwifiex_send_cmd_async(priv,
+					     HostCmd_CMD_802_11_KEY_MATERIAL,
+					     HostCmd_ACT_GEN_SET, 0, NULL);
+		if (ret)
+			return ret;
+	}
+	if (priv->sec_info.wep_status == MWIFIEX_802_11_WEP_ENABLED)
+		priv->curr_pkt_filter |= HostCmd_ACT_MAC_WEP_ENABLE;
+	else
+		priv->curr_pkt_filter &= ~HostCmd_ACT_MAC_WEP_ENABLE;
+
+	ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_MAC_CONTROL,
+				    HostCmd_ACT_GEN_SET, 0,
+				    &priv->curr_pkt_filter);
+
+	return ret;
+}
+
+/*
+ * IOCTL request handler to set WPA key.
+ *
+ * This function prepares the correct firmware command and
+ * issues it, after validation checks.
+ *
+ * Current driver only supports key length of up to 32 bytes.
+ *
+ * This function can also be used to disable a currently set key.
+ */
+static int mwifiex_sec_ioctl_set_wpa_key(struct mwifiex_private *priv,
+			      struct mwifiex_ds_encrypt_key *encrypt_key)
+{
+	int ret;
+	u8 remove_key = false;
+	struct host_cmd_ds_802_11_key_material *ibss_key;
+
+	/* Current driver only supports key length of up to 32 bytes */
+	if (encrypt_key->key_len > WLAN_MAX_KEY_LEN) {
+		dev_err(priv->adapter->dev, "key length too long\n");
+		return -1;
+	}
+
+	if (priv->bss_mode == NL80211_IFTYPE_ADHOC) {
+		/*
+		 * IBSS/WPA-None uses only one key (Group) for both receiving
+		 * and sending unicast and multicast packets.
+		 */
+		/* Send the key as PTK to firmware */
+		encrypt_key->key_index = MWIFIEX_KEY_INDEX_UNICAST;
+		ret = mwifiex_send_cmd_async(priv,
+					HostCmd_CMD_802_11_KEY_MATERIAL,
+					HostCmd_ACT_GEN_SET, KEY_INFO_ENABLED,
+					encrypt_key);
+		if (ret)
+			return ret;
+
+		ibss_key = &priv->aes_key;
+		memset(ibss_key, 0,
+		       sizeof(struct host_cmd_ds_802_11_key_material));
+		/* Copy the key in the driver */
+		memcpy(ibss_key->key_param_set.key, encrypt_key->key_material,
+		       encrypt_key->key_len);
+		memcpy(&ibss_key->key_param_set.key_len, &encrypt_key->key_len,
+		       sizeof(ibss_key->key_param_set.key_len));
+		ibss_key->key_param_set.key_type_id
+			= cpu_to_le16(KEY_TYPE_ID_TKIP);
+		ibss_key->key_param_set.key_info = cpu_to_le16(KEY_ENABLED);
+
+		/* Send the key as GTK to firmware */
+		encrypt_key->key_index = ~MWIFIEX_KEY_INDEX_UNICAST;
+	}
+
+	if (!encrypt_key->key_index)
+		encrypt_key->key_index = MWIFIEX_KEY_INDEX_UNICAST;
+
+	if (remove_key)
+		ret = mwifiex_send_cmd_sync(priv,
+				       HostCmd_CMD_802_11_KEY_MATERIAL,
+				       HostCmd_ACT_GEN_SET, !(KEY_INFO_ENABLED),
+				       encrypt_key);
+	else
+		ret = mwifiex_send_cmd_sync(priv,
+					HostCmd_CMD_802_11_KEY_MATERIAL,
+					HostCmd_ACT_GEN_SET, KEY_INFO_ENABLED,
+					encrypt_key);
+
+	return ret;
+}
+
+/*
+ * IOCTL request handler to set/get network keys.
+ *
+ * This is a generic key handling function which supports WEP, WPA
+ * and WAPI.
+ */
+static int
+mwifiex_sec_ioctl_encrypt_key(struct mwifiex_private *priv,
+			      struct mwifiex_ds_encrypt_key *encrypt_key)
+{
+	int status;
+
+	if (encrypt_key->is_wapi_key)
+		status = mwifiex_sec_ioctl_set_wapi_key(priv, encrypt_key);
+	else if (encrypt_key->key_len > WLAN_KEY_LEN_WEP104)
+		status = mwifiex_sec_ioctl_set_wpa_key(priv, encrypt_key);
+	else
+		status = mwifiex_sec_ioctl_set_wep_key(priv, encrypt_key);
+	return status;
+}
+
+/*
+ * This function returns the driver version.
+ */
+int
+mwifiex_drv_get_driver_version(struct mwifiex_adapter *adapter, char *version,
+			       int max_len)
+{
+	union {
+		u32 l;
+		u8 c[4];
+	} ver;
+	char fw_ver[32];
+
+	ver.l = adapter->fw_release_number;
+	sprintf(fw_ver, "%u.%u.%u.p%u", ver.c[2], ver.c[1], ver.c[0], ver.c[3]);
+
+	snprintf(version, max_len, driver_version, fw_ver);
+
+	dev_dbg(adapter->dev, "info: MWIFIEX VERSION: %s\n", version);
+
+	return 0;
+}
+
+/*
+ * Sends IOCTL request to get signal information.
+ *
+ * This function allocates the IOCTL request buffer, fills it
+ * with requisite parameters and calls the IOCTL handler.
+ */
+int mwifiex_get_signal_info(struct mwifiex_private *priv,
+			    struct mwifiex_ds_get_signal *signal)
+{
+	int status;
+
+	signal->selector = ALL_RSSI_INFO_MASK;
+
+	/* Signal info can be obtained only if connected */
+	if (!priv->media_connected) {
+		dev_dbg(priv->adapter->dev,
+			"info: Can not get signal in disconnected state\n");
+		return -1;
+	}
+
+	status = mwifiex_send_cmd_sync(priv, HostCmd_CMD_RSSI_INFO,
+				       HostCmd_ACT_GEN_GET, 0, signal);
+
+	if (!status) {
+		if (signal->selector & BCN_RSSI_AVG_MASK)
+			priv->w_stats.qual.level = signal->bcn_rssi_avg;
+		if (signal->selector & BCN_NF_AVG_MASK)
+			priv->w_stats.qual.noise = signal->bcn_nf_avg;
+	}
+
+	return status;
+}
+
+/*
+ * Sends IOCTL request to set encoding parameters.
+ *
+ * This function allocates the IOCTL request buffer, fills it
+ * with requisite parameters and calls the IOCTL handler.
+ */
+int mwifiex_set_encode(struct mwifiex_private *priv, const u8 *key,
+			int key_len, u8 key_index, int disable)
+{
+	struct mwifiex_ds_encrypt_key encrypt_key;
+
+	memset(&encrypt_key, 0, sizeof(struct mwifiex_ds_encrypt_key));
+	encrypt_key.key_len = key_len;
+	if (!disable) {
+		encrypt_key.key_index = key_index;
+		if (key_len)
+			memcpy(encrypt_key.key_material, key, key_len);
+	} else {
+		encrypt_key.key_disable = true;
+	}
+
+	return mwifiex_sec_ioctl_encrypt_key(priv, &encrypt_key);
+}
+
+/*
+ * Sends IOCTL request to get extended version.
+ *
+ * This function allocates the IOCTL request buffer, fills it
+ * with requisite parameters and calls the IOCTL handler.
+ */
+int
+mwifiex_get_ver_ext(struct mwifiex_private *priv)
+{
+	struct mwifiex_ver_ext ver_ext;
+
+	memset(&ver_ext, 0, sizeof(struct host_cmd_ds_version_ext));
+	if (mwifiex_send_cmd_sync(priv, HostCmd_CMD_VERSION_EXT,
+				    HostCmd_ACT_GEN_GET, 0, &ver_ext))
+		return -1;
+
+	return 0;
+}
+
+/*
+ * Sends IOCTL request to get statistics information.
+ *
+ * This function allocates the IOCTL request buffer, fills it
+ * with requisite parameters and calls the IOCTL handler.
+ */
+int
+mwifiex_get_stats_info(struct mwifiex_private *priv,
+		       struct mwifiex_ds_get_stats *log)
+{
+	int ret;
+
+	ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_GET_LOG,
+				    HostCmd_ACT_GEN_GET, 0, log);
+
+	if (!ret) {
+		priv->w_stats.discard.fragment = log->fcs_error;
+		priv->w_stats.discard.retries = log->retry;
+		priv->w_stats.discard.misc = log->ack_failure;
+	}
+
+	return ret;
+}
+
+/*
+ * IOCTL request handler to read/write register.
+ *
+ * This function prepares the correct firmware command and
+ * issues it.
+ *
+ * Access to the following registers are supported -
+ *      - MAC
+ *      - BBP
+ *      - RF
+ *      - PMIC
+ *      - CAU
+ */
+static int mwifiex_reg_mem_ioctl_reg_rw(struct mwifiex_private *priv,
+					struct mwifiex_ds_reg_rw *reg_rw,
+					u16 action)
+{
+	u16 cmd_no;
+
+	switch (le32_to_cpu(reg_rw->type)) {
+	case MWIFIEX_REG_MAC:
+		cmd_no = HostCmd_CMD_MAC_REG_ACCESS;
+		break;
+	case MWIFIEX_REG_BBP:
+		cmd_no = HostCmd_CMD_BBP_REG_ACCESS;
+		break;
+	case MWIFIEX_REG_RF:
+		cmd_no = HostCmd_CMD_RF_REG_ACCESS;
+		break;
+	case MWIFIEX_REG_PMIC:
+		cmd_no = HostCmd_CMD_PMIC_REG_ACCESS;
+		break;
+	case MWIFIEX_REG_CAU:
+		cmd_no = HostCmd_CMD_CAU_REG_ACCESS;
+		break;
+	default:
+		return -1;
+	}
+
+	return mwifiex_send_cmd_sync(priv, cmd_no, action, 0, reg_rw);
+
+}
+
+/*
+ * Sends IOCTL request to write to a register.
+ *
+ * This function allocates the IOCTL request buffer, fills it
+ * with requisite parameters and calls the IOCTL handler.
+ */
+int
+mwifiex_reg_write(struct mwifiex_private *priv, u32 reg_type,
+		  u32 reg_offset, u32 reg_value)
+{
+	struct mwifiex_ds_reg_rw reg_rw;
+
+	reg_rw.type = cpu_to_le32(reg_type);
+	reg_rw.offset = cpu_to_le32(reg_offset);
+	reg_rw.value = cpu_to_le32(reg_value);
+
+	return mwifiex_reg_mem_ioctl_reg_rw(priv, &reg_rw, HostCmd_ACT_GEN_SET);
+}
+
+/*
+ * Sends IOCTL request to read from a register.
+ *
+ * This function allocates the IOCTL request buffer, fills it
+ * with requisite parameters and calls the IOCTL handler.
+ */
+int
+mwifiex_reg_read(struct mwifiex_private *priv, u32 reg_type,
+		 u32 reg_offset, u32 *value)
+{
+	int ret;
+	struct mwifiex_ds_reg_rw reg_rw;
+
+	reg_rw.type = cpu_to_le32(reg_type);
+	reg_rw.offset = cpu_to_le32(reg_offset);
+	ret = mwifiex_reg_mem_ioctl_reg_rw(priv, &reg_rw, HostCmd_ACT_GEN_GET);
+
+	if (ret)
+		goto done;
+
+	*value = le32_to_cpu(reg_rw.value);
+
+done:
+	return ret;
+}
+
+/*
+ * Sends IOCTL request to read from EEPROM.
+ *
+ * This function allocates the IOCTL request buffer, fills it
+ * with requisite parameters and calls the IOCTL handler.
+ */
+int
+mwifiex_eeprom_read(struct mwifiex_private *priv, u16 offset, u16 bytes,
+		    u8 *value)
+{
+	int ret;
+	struct mwifiex_ds_read_eeprom rd_eeprom;
+
+	rd_eeprom.offset = cpu_to_le16((u16) offset);
+	rd_eeprom.byte_count = cpu_to_le16((u16) bytes);
+
+	/* Send request to firmware */
+	ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_EEPROM_ACCESS,
+				    HostCmd_ACT_GEN_GET, 0, &rd_eeprom);
+
+	if (!ret)
+		memcpy(value, rd_eeprom.value, MAX_EEPROM_DATA);
+	return ret;
+}
+
+/*
+ * This function sets a generic IE. In addition to generic IE, it can
+ * also handle WPA, WPA2 and WAPI IEs.
+ */
+static int
+mwifiex_set_gen_ie_helper(struct mwifiex_private *priv, u8 *ie_data_ptr,
+			  u16 ie_len)
+{
+	int ret = 0;
+	struct ieee_types_vendor_header *pvendor_ie;
+	const u8 wpa_oui[] = { 0x00, 0x50, 0xf2, 0x01 };
+	const u8 wps_oui[] = { 0x00, 0x50, 0xf2, 0x04 };
+
+	/* If the passed length is zero, reset the buffer */
+	if (!ie_len) {
+		priv->gen_ie_buf_len = 0;
+		priv->wps.session_enable = false;
+
+		return 0;
+	} else if (!ie_data_ptr) {
+		return -1;
+	}
+	pvendor_ie = (struct ieee_types_vendor_header *) ie_data_ptr;
+	/* Test to see if it is a WPA IE, if not, then it is a gen IE */
+	if (((pvendor_ie->element_id == WLAN_EID_WPA)
+	     && (!memcmp(pvendor_ie->oui, wpa_oui, sizeof(wpa_oui))))
+			|| (pvendor_ie->element_id == WLAN_EID_RSN)) {
+
+		/* IE is a WPA/WPA2 IE so call set_wpa function */
+		ret = mwifiex_set_wpa_ie_helper(priv, ie_data_ptr, ie_len);
+		priv->wps.session_enable = false;
+
+		return ret;
+	} else if (pvendor_ie->element_id == WLAN_EID_BSS_AC_ACCESS_DELAY) {
+		/* IE is a WAPI IE so call set_wapi function */
+		ret = mwifiex_set_wapi_ie(priv, ie_data_ptr, ie_len);
+
+		return ret;
+	}
+	/*
+	 * Verify that the passed length is not larger than the
+	 * available space remaining in the buffer
+	 */
+	if (ie_len < (sizeof(priv->gen_ie_buf) - priv->gen_ie_buf_len)) {
+
+		/* Test to see if it is a WPS IE, if so, enable
+		 * wps session flag
+		 */
+		pvendor_ie = (struct ieee_types_vendor_header *) ie_data_ptr;
+		if ((pvendor_ie->element_id == WLAN_EID_VENDOR_SPECIFIC)
+				&& (!memcmp(pvendor_ie->oui, wps_oui,
+						sizeof(wps_oui)))) {
+			priv->wps.session_enable = true;
+			dev_dbg(priv->adapter->dev,
+				"info: WPS Session Enabled.\n");
+		}
+
+		/* Append the passed data to the end of the
+		   genIeBuffer */
+		memcpy(priv->gen_ie_buf + priv->gen_ie_buf_len, ie_data_ptr,
+									ie_len);
+		/* Increment the stored buffer length by the
+		   size passed */
+		priv->gen_ie_buf_len += ie_len;
+	} else {
+		/* Passed data does not fit in the remaining
+		   buffer space */
+		ret = -1;
+	}
+
+	/* Return 0, or -1 for error case */
+	return ret;
+}
+
+/*
+ * IOCTL request handler to set/get generic IE.
+ *
+ * In addition to various generic IEs, this function can also be
+ * used to set the ARP filter.
+ */
+static int mwifiex_misc_ioctl_gen_ie(struct mwifiex_private *priv,
+				     struct mwifiex_ds_misc_gen_ie *gen_ie,
+				     u16 action)
+{
+	struct mwifiex_adapter *adapter = priv->adapter;
+
+	switch (gen_ie->type) {
+	case MWIFIEX_IE_TYPE_GEN_IE:
+		if (action == HostCmd_ACT_GEN_GET) {
+			gen_ie->len = priv->wpa_ie_len;
+			memcpy(gen_ie->ie_data, priv->wpa_ie, gen_ie->len);
+		} else {
+			mwifiex_set_gen_ie_helper(priv, gen_ie->ie_data,
+						  (u16) gen_ie->len);
+		}
+		break;
+	case MWIFIEX_IE_TYPE_ARP_FILTER:
+		memset(adapter->arp_filter, 0, sizeof(adapter->arp_filter));
+		if (gen_ie->len > ARP_FILTER_MAX_BUF_SIZE) {
+			adapter->arp_filter_size = 0;
+			dev_err(adapter->dev, "invalid ARP filter size\n");
+			return -1;
+		} else {
+			memcpy(adapter->arp_filter, gen_ie->ie_data,
+								gen_ie->len);
+			adapter->arp_filter_size = gen_ie->len;
+		}
+		break;
+	default:
+		dev_err(adapter->dev, "invalid IE type\n");
+		return -1;
+	}
+	return 0;
+}
+
+/*
+ * Sends IOCTL request to set a generic IE.
+ *
+ * This function allocates the IOCTL request buffer, fills it
+ * with requisite parameters and calls the IOCTL handler.
+ */
+int
+mwifiex_set_gen_ie(struct mwifiex_private *priv, u8 *ie, int ie_len)
+{
+	struct mwifiex_ds_misc_gen_ie gen_ie;
+
+	if (ie_len > IW_CUSTOM_MAX)
+		return -EFAULT;
+
+	gen_ie.type = MWIFIEX_IE_TYPE_GEN_IE;
+	gen_ie.len = ie_len;
+	memcpy(gen_ie.ie_data, ie, ie_len);
+	if (mwifiex_misc_ioctl_gen_ie(priv, &gen_ie, HostCmd_ACT_GEN_SET))
+		return -EFAULT;
+
+	return 0;
+}
diff -druN linux-2.6.39-libre/drivers/net/wireless/mwifiex/sta_rx.c linux-3.0-rc7-libre/drivers/net/wireless/mwifiex/sta_rx.c
--- linux-2.6.39-libre/drivers/net/wireless/mwifiex/sta_rx.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/net/wireless/mwifiex/sta_rx.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,200 @@
+/*
+ * Marvell Wireless LAN device driver: station RX data handling
+ *
+ * Copyright (C) 2011, Marvell International Ltd.
+ *
+ * This software file (the "File") is distributed by Marvell International
+ * Ltd. under the terms of the GNU General Public License Version 2, June 1991
+ * (the "License").  You may use, redistribute and/or modify this File in
+ * accordance with the terms and conditions of the License, a copy of which
+ * is available by writing to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
+ * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
+ *
+ * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
+ * ARE EXPRESSLY DISCLAIMED.  The License provides additional details about
+ * this warranty disclaimer.
+ */
+
+#include "decl.h"
+#include "ioctl.h"
+#include "util.h"
+#include "fw.h"
+#include "main.h"
+#include "11n_aggr.h"
+#include "11n_rxreorder.h"
+
+/*
+ * This function processes the received packet and forwards it
+ * to kernel/upper layer.
+ *
+ * This function parses through the received packet and determines
+ * if it is a debug packet or normal packet.
+ *
+ * For non-debug packets, the function chops off unnecessary leading
+ * header bytes, reconstructs the packet as an ethernet frame or
+ * 802.2/llc/snap frame as required, and sends it to kernel/upper layer.
+ *
+ * The completion callback is called after processing in complete.
+ */
+int mwifiex_process_rx_packet(struct mwifiex_adapter *adapter,
+			      struct sk_buff *skb)
+{
+	int ret;
+	struct mwifiex_rxinfo *rx_info = MWIFIEX_SKB_RXCB(skb);
+	struct mwifiex_private *priv = adapter->priv[rx_info->bss_index];
+	struct rx_packet_hdr *rx_pkt_hdr;
+	struct rxpd *local_rx_pd;
+	int hdr_chop;
+	struct ethhdr *eth_hdr;
+	u8 rfc1042_eth_hdr[ETH_ALEN] = { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00 };
+
+	local_rx_pd = (struct rxpd *) (skb->data);
+
+	rx_pkt_hdr = (struct rx_packet_hdr *) ((u8 *) local_rx_pd +
+				local_rx_pd->rx_pkt_offset);
+
+	if (!memcmp(&rx_pkt_hdr->rfc1042_hdr,
+		    rfc1042_eth_hdr, sizeof(rfc1042_eth_hdr))) {
+		/*
+		 *  Replace the 803 header and rfc1042 header (llc/snap) with an
+		 *    EthernetII header, keep the src/dst and snap_type
+		 *    (ethertype).
+		 *  The firmware only passes up SNAP frames converting
+		 *    all RX Data from 802.11 to 802.2/LLC/SNAP frames.
+		 *  To create the Ethernet II, just move the src, dst address
+		 *    right before the snap_type.
+		 */
+		eth_hdr = (struct ethhdr *)
+			((u8 *) &rx_pkt_hdr->eth803_hdr
+			 + sizeof(rx_pkt_hdr->eth803_hdr) +
+			 sizeof(rx_pkt_hdr->rfc1042_hdr)
+			 - sizeof(rx_pkt_hdr->eth803_hdr.h_dest)
+			 - sizeof(rx_pkt_hdr->eth803_hdr.h_source)
+			 - sizeof(rx_pkt_hdr->rfc1042_hdr.snap_type));
+
+		memcpy(eth_hdr->h_source, rx_pkt_hdr->eth803_hdr.h_source,
+		       sizeof(eth_hdr->h_source));
+		memcpy(eth_hdr->h_dest, rx_pkt_hdr->eth803_hdr.h_dest,
+		       sizeof(eth_hdr->h_dest));
+
+		/* Chop off the rxpd + the excess memory from the 802.2/llc/snap
+		   header that was removed. */
+		hdr_chop = (u8 *) eth_hdr - (u8 *) local_rx_pd;
+	} else {
+		/* Chop off the rxpd */
+		hdr_chop = (u8 *) &rx_pkt_hdr->eth803_hdr -
+			(u8 *) local_rx_pd;
+	}
+
+	/* Chop off the leading header bytes so the it points to the start of
+	   either the reconstructed EthII frame or the 802.2/llc/snap frame */
+	skb_pull(skb, hdr_chop);
+
+	priv->rxpd_rate = local_rx_pd->rx_rate;
+
+	priv->rxpd_htinfo = local_rx_pd->ht_info;
+
+	ret = mwifiex_recv_packet(adapter, skb);
+	if (ret == -1)
+		dev_err(adapter->dev, "recv packet failed\n");
+
+	return ret;
+}
+
+/*
+ * This function processes the received buffer.
+ *
+ * The function looks into the RxPD and performs sanity tests on the
+ * received buffer to ensure its a valid packet, before processing it
+ * further. If the packet is determined to be aggregated, it is
+ * de-aggregated accordingly. Non-unicast packets are sent directly to
+ * the kernel/upper layers. Unicast packets are handed over to the
+ * Rx reordering routine if 11n is enabled.
+ *
+ * The completion callback is called after processing in complete.
+ */
+int mwifiex_process_sta_rx_packet(struct mwifiex_adapter *adapter,
+				  struct sk_buff *skb)
+{
+	int ret = 0;
+	struct rxpd *local_rx_pd;
+	struct mwifiex_rxinfo *rx_info = MWIFIEX_SKB_RXCB(skb);
+	struct rx_packet_hdr *rx_pkt_hdr;
+	u8 ta[ETH_ALEN];
+	u16 rx_pkt_type;
+	struct mwifiex_private *priv = adapter->priv[rx_info->bss_index];
+
+	local_rx_pd = (struct rxpd *) (skb->data);
+	rx_pkt_type = local_rx_pd->rx_pkt_type;
+
+	rx_pkt_hdr = (struct rx_packet_hdr *) ((u8 *) local_rx_pd +
+					local_rx_pd->rx_pkt_offset);
+
+	if ((local_rx_pd->rx_pkt_offset + local_rx_pd->rx_pkt_length) >
+	    (u16) skb->len) {
+		dev_err(adapter->dev, "wrong rx packet: len=%d,"
+			" rx_pkt_offset=%d, rx_pkt_length=%d\n", skb->len,
+		       local_rx_pd->rx_pkt_offset, local_rx_pd->rx_pkt_length);
+		priv->stats.rx_dropped++;
+		dev_kfree_skb_any(skb);
+		return ret;
+	}
+
+	if (local_rx_pd->rx_pkt_type == PKT_TYPE_AMSDU) {
+		struct sk_buff_head list;
+		struct sk_buff *rx_skb;
+
+		__skb_queue_head_init(&list);
+
+		skb_pull(skb, local_rx_pd->rx_pkt_offset);
+		skb_trim(skb, local_rx_pd->rx_pkt_length);
+
+		ieee80211_amsdu_to_8023s(skb, &list, priv->curr_addr,
+				priv->wdev->iftype, 0, false);
+
+		while (!skb_queue_empty(&list)) {
+			rx_skb = __skb_dequeue(&list);
+			ret = mwifiex_recv_packet(adapter, rx_skb);
+			if (ret == -1)
+				dev_err(adapter->dev, "Rx of A-MSDU failed");
+		}
+		return 0;
+	}
+
+	/*
+	 * If the packet is not an unicast packet then send the packet
+	 * directly to os. Don't pass thru rx reordering
+	 */
+	if (!IS_11N_ENABLED(priv) ||
+	    memcmp(priv->curr_addr, rx_pkt_hdr->eth803_hdr.h_dest, ETH_ALEN)) {
+		mwifiex_process_rx_packet(adapter, skb);
+		return ret;
+	}
+
+	if (mwifiex_queuing_ra_based(priv)) {
+		memcpy(ta, rx_pkt_hdr->eth803_hdr.h_source, ETH_ALEN);
+	} else {
+		if (rx_pkt_type != PKT_TYPE_BAR)
+			priv->rx_seq[local_rx_pd->priority] =
+						local_rx_pd->seq_num;
+		memcpy(ta, priv->curr_bss_params.bss_descriptor.mac_address,
+		       ETH_ALEN);
+	}
+
+	/* Reorder and send to OS */
+	ret = mwifiex_11n_rx_reorder_pkt(priv, local_rx_pd->seq_num,
+					     local_rx_pd->priority, ta,
+					     (u8) local_rx_pd->rx_pkt_type,
+						(void *) skb);
+
+	if (ret || (rx_pkt_type == PKT_TYPE_BAR)) {
+		if (priv && (ret == -1))
+			priv->stats.rx_dropped++;
+
+		dev_kfree_skb_any(skb);
+	}
+
+	return ret;
+}
diff -druN linux-2.6.39-libre/drivers/net/wireless/mwifiex/sta_tx.c linux-3.0-rc7-libre/drivers/net/wireless/mwifiex/sta_tx.c
--- linux-2.6.39-libre/drivers/net/wireless/mwifiex/sta_tx.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/net/wireless/mwifiex/sta_tx.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,198 @@
+/*
+ * Marvell Wireless LAN device driver: station TX data handling
+ *
+ * Copyright (C) 2011, Marvell International Ltd.
+ *
+ * This software file (the "File") is distributed by Marvell International
+ * Ltd. under the terms of the GNU General Public License Version 2, June 1991
+ * (the "License").  You may use, redistribute and/or modify this File in
+ * accordance with the terms and conditions of the License, a copy of which
+ * is available by writing to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
+ * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
+ *
+ * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
+ * ARE EXPRESSLY DISCLAIMED.  The License provides additional details about
+ * this warranty disclaimer.
+ */
+
+#include "decl.h"
+#include "ioctl.h"
+#include "util.h"
+#include "fw.h"
+#include "main.h"
+#include "wmm.h"
+
+/*
+ * This function fills the TxPD for tx packets.
+ *
+ * The Tx buffer received by this function should already have the
+ * header space allocated for TxPD.
+ *
+ * This function inserts the TxPD in between interface header and actual
+ * data and adjusts the buffer pointers accordingly.
+ *
+ * The following TxPD fields are set by this function, as required -
+ *      - BSS number
+ *      - Tx packet length and offset
+ *      - Priority
+ *      - Packet delay
+ *      - Priority specific Tx control
+ *      - Flags
+ */
+void *mwifiex_process_sta_txpd(struct mwifiex_private *priv,
+				struct sk_buff *skb)
+{
+	struct mwifiex_adapter *adapter = priv->adapter;
+	struct txpd *local_tx_pd;
+	struct mwifiex_txinfo *tx_info = MWIFIEX_SKB_TXCB(skb);
+
+	if (!skb->len) {
+		dev_err(adapter->dev, "Tx: bad packet length: %d\n",
+		       skb->len);
+		tx_info->status_code = -1;
+		return skb->data;
+	}
+
+	BUG_ON(skb_headroom(skb) < (sizeof(*local_tx_pd) + INTF_HEADER_LEN));
+	skb_push(skb, sizeof(*local_tx_pd));
+
+	local_tx_pd = (struct txpd *) skb->data;
+	memset(local_tx_pd, 0, sizeof(struct txpd));
+	local_tx_pd->bss_num = priv->bss_num;
+	local_tx_pd->bss_type = priv->bss_type;
+	local_tx_pd->tx_pkt_length = cpu_to_le16((u16) (skb->len -
+							sizeof(struct txpd)));
+
+	local_tx_pd->priority = (u8) skb->priority;
+	local_tx_pd->pkt_delay_2ms =
+		mwifiex_wmm_compute_drv_pkt_delay(priv, skb);
+
+	if (local_tx_pd->priority <
+	    ARRAY_SIZE(priv->wmm.user_pri_pkt_tx_ctrl))
+		/*
+		 * Set the priority specific tx_control field, setting of 0 will
+		 *   cause the default value to be used later in this function
+		 */
+		local_tx_pd->tx_control =
+			cpu_to_le32(priv->wmm.user_pri_pkt_tx_ctrl[local_tx_pd->
+							 priority]);
+
+	if (adapter->pps_uapsd_mode) {
+		if (mwifiex_check_last_packet_indication(priv)) {
+			adapter->tx_lock_flag = true;
+			local_tx_pd->flags =
+				MWIFIEX_TxPD_POWER_MGMT_LAST_PACKET;
+		}
+	}
+
+	/* Offset of actual data */
+	local_tx_pd->tx_pkt_offset = cpu_to_le16(sizeof(struct txpd));
+
+	/* make space for INTF_HEADER_LEN */
+	skb_push(skb, INTF_HEADER_LEN);
+
+	if (!local_tx_pd->tx_control)
+		/* TxCtrl set by user or default */
+		local_tx_pd->tx_control = cpu_to_le32(priv->pkt_tx_ctrl);
+
+	return skb->data;
+}
+
+/*
+ * This function tells firmware to send a NULL data packet.
+ *
+ * The function creates a NULL data packet with TxPD and sends to the
+ * firmware for transmission, with highest priority setting.
+ */
+int mwifiex_send_null_packet(struct mwifiex_private *priv, u8 flags)
+{
+	struct mwifiex_adapter *adapter = priv->adapter;
+	struct txpd *local_tx_pd;
+/* sizeof(struct txpd) + Interface specific header */
+#define NULL_PACKET_HDR 64
+	u32 data_len = NULL_PACKET_HDR;
+	struct sk_buff *skb;
+	int ret;
+	struct mwifiex_txinfo *tx_info = NULL;
+
+	if (adapter->surprise_removed)
+		return -1;
+
+	if (!priv->media_connected)
+		return -1;
+
+	if (adapter->data_sent)
+		return -1;
+
+	skb = dev_alloc_skb(data_len);
+	if (!skb)
+		return -1;
+
+	tx_info = MWIFIEX_SKB_TXCB(skb);
+	tx_info->bss_index = priv->bss_index;
+	skb_reserve(skb, sizeof(struct txpd) + INTF_HEADER_LEN);
+	skb_push(skb, sizeof(struct txpd));
+
+	local_tx_pd = (struct txpd *) skb->data;
+	local_tx_pd->tx_control = cpu_to_le32(priv->pkt_tx_ctrl);
+	local_tx_pd->flags = flags;
+	local_tx_pd->priority = WMM_HIGHEST_PRIORITY;
+	local_tx_pd->tx_pkt_offset = cpu_to_le16(sizeof(struct txpd));
+	local_tx_pd->bss_num = priv->bss_num;
+	local_tx_pd->bss_type = priv->bss_type;
+
+	skb_push(skb, INTF_HEADER_LEN);
+
+	ret = adapter->if_ops.host_to_card(adapter, MWIFIEX_TYPE_DATA,
+					     skb->data, skb->len, NULL);
+	switch (ret) {
+	case -EBUSY:
+		adapter->data_sent = true;
+		/* Fall through FAILURE handling */
+	case -1:
+		dev_kfree_skb_any(skb);
+		dev_err(adapter->dev, "%s: host_to_card failed: ret=%d\n",
+						__func__, ret);
+		adapter->dbg.num_tx_host_to_card_failure++;
+		break;
+	case 0:
+		dev_kfree_skb_any(skb);
+		dev_dbg(adapter->dev, "data: %s: host_to_card succeeded\n",
+						__func__);
+		adapter->tx_lock_flag = true;
+		break;
+	case -EINPROGRESS:
+		break;
+	default:
+		break;
+	}
+
+	return ret;
+}
+
+/*
+ * This function checks if we need to send last packet indication.
+ */
+u8
+mwifiex_check_last_packet_indication(struct mwifiex_private *priv)
+{
+	struct mwifiex_adapter *adapter = priv->adapter;
+	u8 ret = false;
+
+	if (!adapter->sleep_period.period)
+		return ret;
+	if (mwifiex_wmm_lists_empty(adapter))
+			ret = true;
+
+	if (ret && !adapter->cmd_sent && !adapter->curr_cmd
+	    && !is_command_pending(adapter)) {
+		adapter->delay_null_pkt = false;
+		ret = true;
+	} else {
+		ret = false;
+		adapter->delay_null_pkt = true;
+	}
+	return ret;
+}
diff -druN linux-2.6.39-libre/drivers/net/wireless/mwifiex/txrx.c linux-3.0-rc7-libre/drivers/net/wireless/mwifiex/txrx.c
--- linux-2.6.39-libre/drivers/net/wireless/mwifiex/txrx.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/net/wireless/mwifiex/txrx.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,202 @@
+/*
+ * Marvell Wireless LAN device driver: generic TX/RX data handling
+ *
+ * Copyright (C) 2011, Marvell International Ltd.
+ *
+ * This software file (the "File") is distributed by Marvell International
+ * Ltd. under the terms of the GNU General Public License Version 2, June 1991
+ * (the "License").  You may use, redistribute and/or modify this File in
+ * accordance with the terms and conditions of the License, a copy of which
+ * is available by writing to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
+ * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
+ *
+ * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
+ * ARE EXPRESSLY DISCLAIMED.  The License provides additional details about
+ * this warranty disclaimer.
+ */
+
+#include "decl.h"
+#include "ioctl.h"
+#include "util.h"
+#include "fw.h"
+#include "main.h"
+#include "wmm.h"
+
+/*
+ * This function processes the received buffer.
+ *
+ * Main responsibility of this function is to parse the RxPD to
+ * identify the correct interface this packet is headed for and
+ * forwarding it to the associated handling function, where the
+ * packet will be further processed and sent to kernel/upper layer
+ * if required.
+ */
+int mwifiex_handle_rx_packet(struct mwifiex_adapter *adapter,
+			     struct sk_buff *skb)
+{
+	struct mwifiex_private *priv =
+		mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY);
+	struct rxpd *local_rx_pd;
+	struct mwifiex_rxinfo *rx_info = MWIFIEX_SKB_RXCB(skb);
+
+	local_rx_pd = (struct rxpd *) (skb->data);
+	/* Get the BSS number from rxpd, get corresponding priv */
+	priv = mwifiex_get_priv_by_id(adapter, local_rx_pd->bss_num &
+				      BSS_NUM_MASK, local_rx_pd->bss_type);
+	if (!priv)
+		priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY);
+
+	rx_info->bss_index = priv->bss_index;
+
+	return mwifiex_process_sta_rx_packet(adapter, skb);
+}
+EXPORT_SYMBOL_GPL(mwifiex_handle_rx_packet);
+
+/*
+ * This function sends a packet to device.
+ *
+ * It processes the packet to add the TxPD, checks condition and
+ * sends the processed packet to firmware for transmission.
+ *
+ * On successful completion, the function calls the completion callback
+ * and logs the time.
+ */
+int mwifiex_process_tx(struct mwifiex_private *priv, struct sk_buff *skb,
+		       struct mwifiex_tx_param *tx_param)
+{
+	int ret = -1;
+	struct mwifiex_adapter *adapter = priv->adapter;
+	u8 *head_ptr;
+	struct txpd *local_tx_pd = NULL;
+
+	head_ptr = (u8 *) mwifiex_process_sta_txpd(priv, skb);
+	if (head_ptr) {
+		if (GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_STA)
+			local_tx_pd =
+				(struct txpd *) (head_ptr + INTF_HEADER_LEN);
+
+		ret = adapter->if_ops.host_to_card(adapter, MWIFIEX_TYPE_DATA,
+					     skb->data, skb->len, tx_param);
+	}
+
+	switch (ret) {
+	case -EBUSY:
+		if ((GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_STA) &&
+			(adapter->pps_uapsd_mode) &&
+			(adapter->tx_lock_flag)) {
+				priv->adapter->tx_lock_flag = false;
+				local_tx_pd->flags = 0;
+		}
+		dev_dbg(adapter->dev, "data: -EBUSY is returned\n");
+		break;
+	case -1:
+		adapter->data_sent = false;
+		dev_err(adapter->dev, "mwifiex_write_data_async failed: 0x%X\n",
+		       ret);
+		adapter->dbg.num_tx_host_to_card_failure++;
+		mwifiex_write_data_complete(adapter, skb, ret);
+		break;
+	case -EINPROGRESS:
+		adapter->data_sent = false;
+		break;
+	case 0:
+		mwifiex_write_data_complete(adapter, skb, ret);
+		break;
+	default:
+		break;
+	}
+
+	return ret;
+}
+
+/*
+ * Packet send completion callback handler.
+ *
+ * It either frees the buffer directly or forwards it to another
+ * completion callback which checks conditions, updates statistics,
+ * wakes up stalled traffic queue if required, and then frees the buffer.
+ */
+int mwifiex_write_data_complete(struct mwifiex_adapter *adapter,
+				struct sk_buff *skb, int status)
+{
+	struct mwifiex_private *priv, *tpriv;
+	struct mwifiex_txinfo *tx_info;
+	int i;
+
+	if (!skb)
+		return 0;
+
+	tx_info = MWIFIEX_SKB_TXCB(skb);
+	priv = mwifiex_bss_index_to_priv(adapter, tx_info->bss_index);
+	if (!priv)
+		goto done;
+
+	priv->netdev->trans_start = jiffies;
+	if (!status) {
+		priv->stats.tx_packets++;
+		priv->stats.tx_bytes += skb->len;
+	} else {
+		priv->stats.tx_errors++;
+	}
+
+	if (atomic_dec_return(&adapter->tx_pending) >= LOW_TX_PENDING)
+		goto done;
+
+	for (i = 0; i < adapter->priv_num; i++) {
+
+		tpriv = adapter->priv[i];
+
+		if ((GET_BSS_ROLE(tpriv) == MWIFIEX_BSS_ROLE_STA)
+				&& (tpriv->media_connected)) {
+			if (netif_queue_stopped(tpriv->netdev))
+				netif_wake_queue(tpriv->netdev);
+		}
+	}
+done:
+	dev_kfree_skb_any(skb);
+
+	return 0;
+}
+
+/*
+ * Packet receive completion callback handler.
+ *
+ * This function calls another completion callback handler which
+ * updates the statistics, and optionally updates the parent buffer
+ * use count before freeing the received packet.
+ */
+int mwifiex_recv_packet_complete(struct mwifiex_adapter *adapter,
+				 struct sk_buff *skb, int status)
+{
+	struct mwifiex_rxinfo *rx_info = MWIFIEX_SKB_RXCB(skb);
+	struct mwifiex_rxinfo *rx_info_parent;
+	struct mwifiex_private *priv;
+	struct sk_buff *skb_parent;
+	unsigned long flags;
+
+	priv = adapter->priv[rx_info->bss_index];
+
+	if (priv && (status == -1))
+		priv->stats.rx_dropped++;
+
+	if (rx_info->parent) {
+		skb_parent = rx_info->parent;
+		rx_info_parent = MWIFIEX_SKB_RXCB(skb_parent);
+
+		spin_lock_irqsave(&priv->rx_pkt_lock, flags);
+		--rx_info_parent->use_count;
+
+		if (!rx_info_parent->use_count) {
+			spin_unlock_irqrestore(&priv->rx_pkt_lock, flags);
+			dev_kfree_skb_any(skb_parent);
+		} else {
+			spin_unlock_irqrestore(&priv->rx_pkt_lock, flags);
+		}
+	} else {
+		dev_kfree_skb_any(skb);
+	}
+
+	return 0;
+}
diff -druN linux-2.6.39-libre/drivers/net/wireless/mwifiex/util.c linux-3.0-rc7-libre/drivers/net/wireless/mwifiex/util.c
--- linux-2.6.39-libre/drivers/net/wireless/mwifiex/util.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/net/wireless/mwifiex/util.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,202 @@
+/*
+ * Marvell Wireless LAN device driver: utility functions
+ *
+ * Copyright (C) 2011, Marvell International Ltd.
+ *
+ * This software file (the "File") is distributed by Marvell International
+ * Ltd. under the terms of the GNU General Public License Version 2, June 1991
+ * (the "License").  You may use, redistribute and/or modify this File in
+ * accordance with the terms and conditions of the License, a copy of which
+ * is available by writing to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
+ * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
+ *
+ * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
+ * ARE EXPRESSLY DISCLAIMED.  The License provides additional details about
+ * this warranty disclaimer.
+ */
+
+#include "decl.h"
+#include "ioctl.h"
+#include "util.h"
+#include "fw.h"
+#include "main.h"
+#include "wmm.h"
+#include "11n.h"
+
+/*
+ * Firmware initialization complete callback handler.
+ *
+ * This function wakes up the function waiting on the init
+ * wait queue for the firmware initialization to complete.
+ */
+int mwifiex_init_fw_complete(struct mwifiex_adapter *adapter)
+{
+
+	adapter->init_wait_q_woken = true;
+	wake_up_interruptible(&adapter->init_wait_q);
+	return 0;
+}
+
+/*
+ * Firmware shutdown complete callback handler.
+ *
+ * This function sets the hardware status to not ready and wakes up
+ * the function waiting on the init wait queue for the firmware
+ * shutdown to complete.
+ */
+int mwifiex_shutdown_fw_complete(struct mwifiex_adapter *adapter)
+{
+	adapter->hw_status = MWIFIEX_HW_STATUS_NOT_READY;
+	adapter->init_wait_q_woken = true;
+	wake_up_interruptible(&adapter->init_wait_q);
+	return 0;
+}
+
+/*
+ * This function sends init/shutdown command
+ * to firmware.
+ */
+int mwifiex_init_shutdown_fw(struct mwifiex_private *priv,
+			     u32 func_init_shutdown)
+{
+	u16 cmd;
+
+	if (func_init_shutdown == MWIFIEX_FUNC_INIT) {
+		cmd = HostCmd_CMD_FUNC_INIT;
+	} else if (func_init_shutdown == MWIFIEX_FUNC_SHUTDOWN) {
+		cmd = HostCmd_CMD_FUNC_SHUTDOWN;
+	} else {
+		dev_err(priv->adapter->dev, "unsupported parameter\n");
+		return -1;
+	}
+
+	return mwifiex_send_cmd_sync(priv, cmd, HostCmd_ACT_GEN_SET, 0, NULL);
+}
+EXPORT_SYMBOL_GPL(mwifiex_init_shutdown_fw);
+
+/*
+ * IOCTL request handler to set/get debug information.
+ *
+ * This function collates/sets the information from/to different driver
+ * structures.
+ */
+int mwifiex_get_debug_info(struct mwifiex_private *priv,
+			   struct mwifiex_debug_info *info)
+{
+	struct mwifiex_adapter *adapter = priv->adapter;
+
+	if (info) {
+		memcpy(info->packets_out,
+		       priv->wmm.packets_out,
+		       sizeof(priv->wmm.packets_out));
+		info->max_tx_buf_size = (u32) adapter->max_tx_buf_size;
+		info->tx_buf_size = (u32) adapter->tx_buf_size;
+		info->rx_tbl_num = mwifiex_get_rx_reorder_tbl(
+					priv, info->rx_tbl);
+		info->tx_tbl_num = mwifiex_get_tx_ba_stream_tbl(
+					priv, info->tx_tbl);
+		info->ps_mode = adapter->ps_mode;
+		info->ps_state = adapter->ps_state;
+		info->is_deep_sleep = adapter->is_deep_sleep;
+		info->pm_wakeup_card_req = adapter->pm_wakeup_card_req;
+		info->pm_wakeup_fw_try = adapter->pm_wakeup_fw_try;
+		info->is_hs_configured = adapter->is_hs_configured;
+		info->hs_activated = adapter->hs_activated;
+		info->num_cmd_host_to_card_failure
+			= adapter->dbg.num_cmd_host_to_card_failure;
+		info->num_cmd_sleep_cfm_host_to_card_failure
+			= adapter->dbg.num_cmd_sleep_cfm_host_to_card_failure;
+		info->num_tx_host_to_card_failure
+			= adapter->dbg.num_tx_host_to_card_failure;
+		info->num_event_deauth = adapter->dbg.num_event_deauth;
+		info->num_event_disassoc = adapter->dbg.num_event_disassoc;
+		info->num_event_link_lost = adapter->dbg.num_event_link_lost;
+		info->num_cmd_deauth = adapter->dbg.num_cmd_deauth;
+		info->num_cmd_assoc_success =
+			adapter->dbg.num_cmd_assoc_success;
+		info->num_cmd_assoc_failure =
+			adapter->dbg.num_cmd_assoc_failure;
+		info->num_tx_timeout = adapter->dbg.num_tx_timeout;
+		info->num_cmd_timeout = adapter->dbg.num_cmd_timeout;
+		info->timeout_cmd_id = adapter->dbg.timeout_cmd_id;
+		info->timeout_cmd_act = adapter->dbg.timeout_cmd_act;
+		memcpy(info->last_cmd_id, adapter->dbg.last_cmd_id,
+		       sizeof(adapter->dbg.last_cmd_id));
+		memcpy(info->last_cmd_act, adapter->dbg.last_cmd_act,
+		       sizeof(adapter->dbg.last_cmd_act));
+		info->last_cmd_index = adapter->dbg.last_cmd_index;
+		memcpy(info->last_cmd_resp_id, adapter->dbg.last_cmd_resp_id,
+		       sizeof(adapter->dbg.last_cmd_resp_id));
+		info->last_cmd_resp_index = adapter->dbg.last_cmd_resp_index;
+		memcpy(info->last_event, adapter->dbg.last_event,
+		       sizeof(adapter->dbg.last_event));
+		info->last_event_index = adapter->dbg.last_event_index;
+		info->data_sent = adapter->data_sent;
+		info->cmd_sent = adapter->cmd_sent;
+		info->cmd_resp_received = adapter->cmd_resp_received;
+	}
+
+	return 0;
+}
+
+/*
+ * This function processes the received packet before sending it to the
+ * kernel.
+ *
+ * It extracts the SKB from the received buffer and sends it to kernel.
+ * In case the received buffer does not contain the data in SKB format,
+ * the function creates a blank SKB, fills it with the data from the
+ * received buffer and then sends this new SKB to the kernel.
+ */
+int mwifiex_recv_packet(struct mwifiex_adapter *adapter, struct sk_buff *skb)
+{
+	struct mwifiex_rxinfo *rx_info;
+	struct mwifiex_private *priv;
+
+	if (!skb)
+		return -1;
+
+	rx_info = MWIFIEX_SKB_RXCB(skb);
+	priv = mwifiex_bss_index_to_priv(adapter, rx_info->bss_index);
+	if (!priv)
+		return -1;
+
+	skb->dev = priv->netdev;
+	skb->protocol = eth_type_trans(skb, priv->netdev);
+	skb->ip_summed = CHECKSUM_NONE;
+	priv->stats.rx_bytes += skb->len;
+	priv->stats.rx_packets++;
+	if (in_interrupt())
+		netif_rx(skb);
+	else
+		netif_rx_ni(skb);
+
+	return 0;
+}
+
+/*
+ * IOCTL completion callback handler.
+ *
+ * This function is called when a pending IOCTL is completed.
+ *
+ * If work queue support is enabled, the function wakes up the
+ * corresponding waiting function. Otherwise, it processes the
+ * IOCTL response and frees the response buffer.
+ */
+int mwifiex_complete_cmd(struct mwifiex_adapter *adapter)
+{
+	atomic_dec(&adapter->cmd_pending);
+	dev_dbg(adapter->dev, "cmd completed: status=%d\n",
+					adapter->cmd_wait_q.status);
+
+	adapter->cmd_wait_q.condition = true;
+
+	if (adapter->cmd_wait_q.status == -ETIMEDOUT)
+		dev_err(adapter->dev, "cmd timeout\n");
+	else
+		wake_up_interruptible(&adapter->cmd_wait_q.wait);
+
+	return 0;
+}
diff -druN linux-2.6.39-libre/drivers/net/wireless/mwifiex/util.h linux-3.0-rc7-libre/drivers/net/wireless/mwifiex/util.h
--- linux-2.6.39-libre/drivers/net/wireless/mwifiex/util.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/net/wireless/mwifiex/util.h	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,32 @@
+/*
+ * Marvell Wireless LAN device driver: utility functions
+ *
+ * Copyright (C) 2011, Marvell International Ltd.
+ *
+ * This software file (the "File") is distributed by Marvell International
+ * Ltd. under the terms of the GNU General Public License Version 2, June 1991
+ * (the "License").  You may use, redistribute and/or modify this File in
+ * accordance with the terms and conditions of the License, a copy of which
+ * is available by writing to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
+ * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
+ *
+ * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
+ * ARE EXPRESSLY DISCLAIMED.  The License provides additional details about
+ * this warranty disclaimer.
+ */
+
+#ifndef _MWIFIEX_UTIL_H_
+#define _MWIFIEX_UTIL_H_
+
+static inline struct mwifiex_rxinfo *MWIFIEX_SKB_RXCB(struct sk_buff *skb)
+{
+	return (struct mwifiex_rxinfo *)skb->cb;
+}
+
+static inline struct mwifiex_txinfo *MWIFIEX_SKB_TXCB(struct sk_buff *skb)
+{
+	return (struct mwifiex_txinfo *)skb->cb;
+}
+#endif /* !_MWIFIEX_UTIL_H_ */
diff -druN linux-2.6.39-libre/drivers/net/wireless/mwifiex/wmm.c linux-3.0-rc7-libre/drivers/net/wireless/mwifiex/wmm.c
--- linux-2.6.39-libre/drivers/net/wireless/mwifiex/wmm.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/net/wireless/mwifiex/wmm.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,1264 @@
+/*
+ * Marvell Wireless LAN device driver: WMM
+ *
+ * Copyright (C) 2011, Marvell International Ltd.
+ *
+ * This software file (the "File") is distributed by Marvell International
+ * Ltd. under the terms of the GNU General Public License Version 2, June 1991
+ * (the "License").  You may use, redistribute and/or modify this File in
+ * accordance with the terms and conditions of the License, a copy of which
+ * is available by writing to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
+ * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
+ *
+ * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
+ * ARE EXPRESSLY DISCLAIMED.  The License provides additional details about
+ * this warranty disclaimer.
+ */
+
+#include "decl.h"
+#include "ioctl.h"
+#include "util.h"
+#include "fw.h"
+#include "main.h"
+#include "wmm.h"
+#include "11n.h"
+
+
+/* Maximum value FW can accept for driver delay in packet transmission */
+#define DRV_PKT_DELAY_TO_FW_MAX   512
+
+
+#define WMM_QUEUED_PACKET_LOWER_LIMIT   180
+
+#define WMM_QUEUED_PACKET_UPPER_LIMIT   200
+
+/* Offset for TOS field in the IP header */
+#define IPTOS_OFFSET 5
+
+/* WMM information IE */
+static const u8 wmm_info_ie[] = { WLAN_EID_VENDOR_SPECIFIC, 0x07,
+	0x00, 0x50, 0xf2, 0x02,
+	0x00, 0x01, 0x00
+};
+
+static const u8 wmm_aci_to_qidx_map[] = { WMM_AC_BE,
+	WMM_AC_BK,
+	WMM_AC_VI,
+	WMM_AC_VO
+};
+
+static u8 tos_to_tid[] = {
+	/* TID DSCP_P2 DSCP_P1 DSCP_P0 WMM_AC */
+	0x01,			/* 0 1 0 AC_BK */
+	0x02,			/* 0 0 0 AC_BK */
+	0x00,			/* 0 0 1 AC_BE */
+	0x03,			/* 0 1 1 AC_BE */
+	0x04,			/* 1 0 0 AC_VI */
+	0x05,			/* 1 0 1 AC_VI */
+	0x06,			/* 1 1 0 AC_VO */
+	0x07			/* 1 1 1 AC_VO */
+};
+
+/*
+ * This table inverses the tos_to_tid operation to get a priority
+ * which is in sequential order, and can be compared.
+ * Use this to compare the priority of two different TIDs.
+ */
+static u8 tos_to_tid_inv[] = {
+	0x02,  /* from tos_to_tid[2] = 0 */
+	0x00,  /* from tos_to_tid[0] = 1 */
+	0x01,  /* from tos_to_tid[1] = 2 */
+	0x03,
+	0x04,
+	0x05,
+	0x06,
+	0x07};
+
+static u8 ac_to_tid[4][2] = { {1, 2}, {0, 3}, {4, 5}, {6, 7} };
+
+/*
+ * This function debug prints the priority parameters for a WMM AC.
+ */
+static void
+mwifiex_wmm_ac_debug_print(const struct ieee_types_wmm_ac_parameters *ac_param)
+{
+	const char *ac_str[] = { "BK", "BE", "VI", "VO" };
+
+	pr_debug("info: WMM AC_%s: ACI=%d, ACM=%d, Aifsn=%d, "
+	       "EcwMin=%d, EcwMax=%d, TxopLimit=%d\n",
+	       ac_str[wmm_aci_to_qidx_map[(ac_param->aci_aifsn_bitmap
+	       & MWIFIEX_ACI) >> 5]],
+	       (ac_param->aci_aifsn_bitmap & MWIFIEX_ACI) >> 5,
+	       (ac_param->aci_aifsn_bitmap & MWIFIEX_ACM) >> 4,
+	       ac_param->aci_aifsn_bitmap & MWIFIEX_AIFSN,
+	       ac_param->ecw_bitmap & MWIFIEX_ECW_MIN,
+	       (ac_param->ecw_bitmap & MWIFIEX_ECW_MAX) >> 4,
+	       le16_to_cpu(ac_param->tx_op_limit));
+}
+
+/*
+ * This function allocates a route address list.
+ *
+ * The function also initializes the list with the provided RA.
+ */
+static struct mwifiex_ra_list_tbl *
+mwifiex_wmm_allocate_ralist_node(struct mwifiex_adapter *adapter, u8 *ra)
+{
+	struct mwifiex_ra_list_tbl *ra_list;
+
+	ra_list = kzalloc(sizeof(struct mwifiex_ra_list_tbl), GFP_ATOMIC);
+
+	if (!ra_list) {
+		dev_err(adapter->dev, "%s: failed to alloc ra_list\n",
+						__func__);
+		return NULL;
+	}
+	INIT_LIST_HEAD(&ra_list->list);
+	skb_queue_head_init(&ra_list->skb_head);
+
+	memcpy(ra_list->ra, ra, ETH_ALEN);
+
+	ra_list->total_pkts_size = 0;
+
+	dev_dbg(adapter->dev, "info: allocated ra_list %p\n", ra_list);
+
+	return ra_list;
+}
+
+/*
+ * This function allocates and adds a RA list for all TIDs
+ * with the given RA.
+ */
+void
+mwifiex_ralist_add(struct mwifiex_private *priv, u8 *ra)
+{
+	int i;
+	struct mwifiex_ra_list_tbl *ra_list;
+	struct mwifiex_adapter *adapter = priv->adapter;
+
+	for (i = 0; i < MAX_NUM_TID; ++i) {
+		ra_list = mwifiex_wmm_allocate_ralist_node(adapter, ra);
+		dev_dbg(adapter->dev, "info: created ra_list %p\n", ra_list);
+
+		if (!ra_list)
+			break;
+
+		if (!mwifiex_queuing_ra_based(priv))
+			ra_list->is_11n_enabled = IS_11N_ENABLED(priv);
+		else
+			ra_list->is_11n_enabled = false;
+
+		dev_dbg(adapter->dev, "data: ralist %p: is_11n_enabled=%d\n",
+			ra_list, ra_list->is_11n_enabled);
+
+		list_add_tail(&ra_list->list,
+				&priv->wmm.tid_tbl_ptr[i].ra_list);
+
+		if (!priv->wmm.tid_tbl_ptr[i].ra_list_curr)
+			priv->wmm.tid_tbl_ptr[i].ra_list_curr = ra_list;
+	}
+}
+
+/*
+ * This function sets the WMM queue priorities to their default values.
+ */
+static void mwifiex_wmm_default_queue_priorities(struct mwifiex_private *priv)
+{
+	/* Default queue priorities: VO->VI->BE->BK */
+	priv->wmm.queue_priority[0] = WMM_AC_VO;
+	priv->wmm.queue_priority[1] = WMM_AC_VI;
+	priv->wmm.queue_priority[2] = WMM_AC_BE;
+	priv->wmm.queue_priority[3] = WMM_AC_BK;
+}
+
+/*
+ * This function map ACs to TIDs.
+ */
+static void
+mwifiex_wmm_queue_priorities_tid(struct mwifiex_wmm_desc *wmm)
+{
+	u8 *queue_priority = wmm->queue_priority;
+	int i;
+
+	for (i = 0; i < 4; ++i) {
+		tos_to_tid[7 - (i * 2)] = ac_to_tid[queue_priority[i]][1];
+		tos_to_tid[6 - (i * 2)] = ac_to_tid[queue_priority[i]][0];
+	}
+
+	for (i = 0; i < MAX_NUM_TID; ++i)
+		tos_to_tid_inv[tos_to_tid[i]] = (u8)i;
+
+	atomic_set(&wmm->highest_queued_prio, HIGH_PRIO_TID);
+}
+
+/*
+ * This function initializes WMM priority queues.
+ */
+void
+mwifiex_wmm_setup_queue_priorities(struct mwifiex_private *priv,
+				   struct ieee_types_wmm_parameter *wmm_ie)
+{
+	u16 cw_min, avg_back_off, tmp[4];
+	u32 i, j, num_ac;
+	u8 ac_idx;
+
+	if (!wmm_ie || !priv->wmm_enabled) {
+		/* WMM is not enabled, just set the defaults and return */
+		mwifiex_wmm_default_queue_priorities(priv);
+		return;
+	}
+
+	dev_dbg(priv->adapter->dev, "info: WMM Parameter IE: version=%d, "
+		"qos_info Parameter Set Count=%d, Reserved=%#x\n",
+		wmm_ie->vend_hdr.version, wmm_ie->qos_info_bitmap &
+		IEEE80211_WMM_IE_AP_QOSINFO_PARAM_SET_CNT_MASK,
+		wmm_ie->reserved);
+
+	for (num_ac = 0; num_ac < ARRAY_SIZE(wmm_ie->ac_params); num_ac++) {
+		cw_min = (1 << (wmm_ie->ac_params[num_ac].ecw_bitmap &
+			MWIFIEX_ECW_MIN)) - 1;
+		avg_back_off = (cw_min >> 1) +
+			(wmm_ie->ac_params[num_ac].aci_aifsn_bitmap &
+			MWIFIEX_AIFSN);
+
+		ac_idx = wmm_aci_to_qidx_map[(wmm_ie->ac_params[num_ac].
+					     aci_aifsn_bitmap &
+					     MWIFIEX_ACI) >> 5];
+		priv->wmm.queue_priority[ac_idx] = ac_idx;
+		tmp[ac_idx] = avg_back_off;
+
+		dev_dbg(priv->adapter->dev, "info: WMM: CWmax=%d CWmin=%d Avg Back-off=%d\n",
+		       (1 << ((wmm_ie->ac_params[num_ac].ecw_bitmap &
+		       MWIFIEX_ECW_MAX) >> 4)) - 1,
+		       cw_min, avg_back_off);
+		mwifiex_wmm_ac_debug_print(&wmm_ie->ac_params[num_ac]);
+	}
+
+	/* Bubble sort */
+	for (i = 0; i < num_ac; i++) {
+		for (j = 1; j < num_ac - i; j++) {
+			if (tmp[j - 1] > tmp[j]) {
+				swap(tmp[j - 1], tmp[j]);
+				swap(priv->wmm.queue_priority[j - 1],
+				     priv->wmm.queue_priority[j]);
+			} else if (tmp[j - 1] == tmp[j]) {
+				if (priv->wmm.queue_priority[j - 1]
+				    < priv->wmm.queue_priority[j])
+					swap(priv->wmm.queue_priority[j - 1],
+					     priv->wmm.queue_priority[j]);
+			}
+		}
+	}
+
+	mwifiex_wmm_queue_priorities_tid(&priv->wmm);
+}
+
+/*
+ * This function evaluates whether or not an AC is to be downgraded.
+ *
+ * In case the AC is not enabled, the highest AC is returned that is
+ * enabled and does not require admission control.
+ */
+static enum mwifiex_wmm_ac_e
+mwifiex_wmm_eval_downgrade_ac(struct mwifiex_private *priv,
+			      enum mwifiex_wmm_ac_e eval_ac)
+{
+	int down_ac;
+	enum mwifiex_wmm_ac_e ret_ac;
+	struct mwifiex_wmm_ac_status *ac_status;
+
+	ac_status = &priv->wmm.ac_status[eval_ac];
+
+	if (!ac_status->disabled)
+		/* Okay to use this AC, its enabled */
+		return eval_ac;
+
+	/* Setup a default return value of the lowest priority */
+	ret_ac = WMM_AC_BK;
+
+	/*
+	 *  Find the highest AC that is enabled and does not require
+	 *  admission control. The spec disallows downgrading to an AC,
+	 *  which is enabled due to a completed admission control.
+	 *  Unadmitted traffic is not to be sent on an AC with admitted
+	 *  traffic.
+	 */
+	for (down_ac = WMM_AC_BK; down_ac < eval_ac; down_ac++) {
+		ac_status = &priv->wmm.ac_status[down_ac];
+
+		if (!ac_status->disabled && !ac_status->flow_required)
+			/* AC is enabled and does not require admission
+			   control */
+			ret_ac = (enum mwifiex_wmm_ac_e) down_ac;
+	}
+
+	return ret_ac;
+}
+
+/*
+ * This function downgrades WMM priority queue.
+ */
+void
+mwifiex_wmm_setup_ac_downgrade(struct mwifiex_private *priv)
+{
+	int ac_val;
+
+	dev_dbg(priv->adapter->dev, "info: WMM: AC Priorities:"
+			"BK(0), BE(1), VI(2), VO(3)\n");
+
+	if (!priv->wmm_enabled) {
+		/* WMM is not enabled, default priorities */
+		for (ac_val = WMM_AC_BK; ac_val <= WMM_AC_VO; ac_val++)
+			priv->wmm.ac_down_graded_vals[ac_val] =
+				(enum mwifiex_wmm_ac_e) ac_val;
+	} else {
+		for (ac_val = WMM_AC_BK; ac_val <= WMM_AC_VO; ac_val++) {
+			priv->wmm.ac_down_graded_vals[ac_val]
+				= mwifiex_wmm_eval_downgrade_ac(priv,
+						(enum mwifiex_wmm_ac_e) ac_val);
+			dev_dbg(priv->adapter->dev, "info: WMM: AC PRIO %d maps to %d\n",
+				ac_val, priv->wmm.ac_down_graded_vals[ac_val]);
+		}
+	}
+}
+
+/*
+ * This function converts the IP TOS field to an WMM AC
+ * Queue assignment.
+ */
+static enum mwifiex_wmm_ac_e
+mwifiex_wmm_convert_tos_to_ac(struct mwifiex_adapter *adapter, u32 tos)
+{
+	/* Map of TOS UP values to WMM AC */
+	const enum mwifiex_wmm_ac_e tos_to_ac[] = { WMM_AC_BE,
+		WMM_AC_BK,
+		WMM_AC_BK,
+		WMM_AC_BE,
+		WMM_AC_VI,
+		WMM_AC_VI,
+		WMM_AC_VO,
+		WMM_AC_VO
+	};
+
+	if (tos >= ARRAY_SIZE(tos_to_ac))
+		return WMM_AC_BE;
+
+	return tos_to_ac[tos];
+}
+
+/*
+ * This function evaluates a given TID and downgrades it to a lower
+ * TID if the WMM Parameter IE received from the AP indicates that the
+ * AP is disabled (due to call admission control (ACM bit). Mapping
+ * of TID to AC is taken care of internally.
+ */
+static u8
+mwifiex_wmm_downgrade_tid(struct mwifiex_private *priv, u32 tid)
+{
+	enum mwifiex_wmm_ac_e ac, ac_down;
+	u8 new_tid;
+
+	ac = mwifiex_wmm_convert_tos_to_ac(priv->adapter, tid);
+	ac_down = priv->wmm.ac_down_graded_vals[ac];
+
+	/* Send the index to tid array, picking from the array will be
+	 * taken care by dequeuing function
+	 */
+	new_tid = ac_to_tid[ac_down][tid % 2];
+
+	return new_tid;
+}
+
+/*
+ * This function initializes the WMM state information and the
+ * WMM data path queues.
+ */
+void
+mwifiex_wmm_init(struct mwifiex_adapter *adapter)
+{
+	int i, j;
+	struct mwifiex_private *priv;
+
+	for (j = 0; j < adapter->priv_num; ++j) {
+		priv = adapter->priv[j];
+		if (!priv)
+			continue;
+
+		for (i = 0; i < MAX_NUM_TID; ++i) {
+			priv->aggr_prio_tbl[i].amsdu = tos_to_tid_inv[i];
+			priv->aggr_prio_tbl[i].ampdu_ap = tos_to_tid_inv[i];
+			priv->aggr_prio_tbl[i].ampdu_user = tos_to_tid_inv[i];
+			priv->wmm.tid_tbl_ptr[i].ra_list_curr = NULL;
+		}
+
+		priv->aggr_prio_tbl[6].amsdu
+			= priv->aggr_prio_tbl[6].ampdu_ap
+			= priv->aggr_prio_tbl[6].ampdu_user
+			= BA_STREAM_NOT_ALLOWED;
+
+		priv->aggr_prio_tbl[7].amsdu = priv->aggr_prio_tbl[7].ampdu_ap
+			= priv->aggr_prio_tbl[7].ampdu_user
+			= BA_STREAM_NOT_ALLOWED;
+
+		priv->add_ba_param.timeout = MWIFIEX_DEFAULT_BLOCK_ACK_TIMEOUT;
+		priv->add_ba_param.tx_win_size = MWIFIEX_AMPDU_DEF_TXWINSIZE;
+		priv->add_ba_param.rx_win_size = MWIFIEX_AMPDU_DEF_RXWINSIZE;
+
+		atomic_set(&priv->wmm.tx_pkts_queued, 0);
+		atomic_set(&priv->wmm.highest_queued_prio, HIGH_PRIO_TID);
+	}
+}
+
+/*
+ * This function checks if WMM Tx queue is empty.
+ */
+int
+mwifiex_wmm_lists_empty(struct mwifiex_adapter *adapter)
+{
+	int i;
+	struct mwifiex_private *priv;
+
+	for (i = 0; i < adapter->priv_num; ++i) {
+		priv = adapter->priv[i];
+		if (priv && atomic_read(&priv->wmm.tx_pkts_queued))
+				return false;
+	}
+
+	return true;
+}
+
+/*
+ * This function deletes all packets in an RA list node.
+ *
+ * The packet sent completion callback handler are called with
+ * status failure, after they are dequeued to ensure proper
+ * cleanup. The RA list node itself is freed at the end.
+ */
+static void
+mwifiex_wmm_del_pkts_in_ralist_node(struct mwifiex_private *priv,
+				    struct mwifiex_ra_list_tbl *ra_list)
+{
+	struct mwifiex_adapter *adapter = priv->adapter;
+	struct sk_buff *skb, *tmp;
+
+	skb_queue_walk_safe(&ra_list->skb_head, skb, tmp)
+		mwifiex_write_data_complete(adapter, skb, -1);
+}
+
+/*
+ * This function deletes all packets in an RA list.
+ *
+ * Each nodes in the RA list are freed individually first, and then
+ * the RA list itself is freed.
+ */
+static void
+mwifiex_wmm_del_pkts_in_ralist(struct mwifiex_private *priv,
+			       struct list_head *ra_list_head)
+{
+	struct mwifiex_ra_list_tbl *ra_list;
+
+	list_for_each_entry(ra_list, ra_list_head, list)
+		mwifiex_wmm_del_pkts_in_ralist_node(priv, ra_list);
+}
+
+/*
+ * This function deletes all packets in all RA lists.
+ */
+static void mwifiex_wmm_cleanup_queues(struct mwifiex_private *priv)
+{
+	int i;
+
+	for (i = 0; i < MAX_NUM_TID; i++)
+		mwifiex_wmm_del_pkts_in_ralist(priv, &priv->wmm.tid_tbl_ptr[i].
+						     ra_list);
+
+	atomic_set(&priv->wmm.tx_pkts_queued, 0);
+	atomic_set(&priv->wmm.highest_queued_prio, HIGH_PRIO_TID);
+}
+
+/*
+ * This function deletes all route addresses from all RA lists.
+ */
+static void mwifiex_wmm_delete_all_ralist(struct mwifiex_private *priv)
+{
+	struct mwifiex_ra_list_tbl *ra_list, *tmp_node;
+	int i;
+
+	for (i = 0; i < MAX_NUM_TID; ++i) {
+		dev_dbg(priv->adapter->dev,
+				"info: ra_list: freeing buf for tid %d\n", i);
+		list_for_each_entry_safe(ra_list, tmp_node,
+				&priv->wmm.tid_tbl_ptr[i].ra_list, list) {
+			list_del(&ra_list->list);
+			kfree(ra_list);
+		}
+
+		INIT_LIST_HEAD(&priv->wmm.tid_tbl_ptr[i].ra_list);
+
+		priv->wmm.tid_tbl_ptr[i].ra_list_curr = NULL;
+	}
+}
+
+/*
+ * This function cleans up the Tx and Rx queues.
+ *
+ * Cleanup includes -
+ *      - All packets in RA lists
+ *      - All entries in Rx reorder table
+ *      - All entries in Tx BA stream table
+ *      - MPA buffer (if required)
+ *      - All RA lists
+ */
+void
+mwifiex_clean_txrx(struct mwifiex_private *priv)
+{
+	unsigned long flags;
+
+	mwifiex_11n_cleanup_reorder_tbl(priv);
+	spin_lock_irqsave(&priv->wmm.ra_list_spinlock, flags);
+
+	mwifiex_wmm_cleanup_queues(priv);
+	mwifiex_11n_delete_all_tx_ba_stream_tbl(priv);
+
+	if (priv->adapter->if_ops.cleanup_mpa_buf)
+		priv->adapter->if_ops.cleanup_mpa_buf(priv->adapter);
+
+	mwifiex_wmm_delete_all_ralist(priv);
+	memcpy(tos_to_tid, ac_to_tid, sizeof(tos_to_tid));
+
+	spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, flags);
+}
+
+/*
+ * This function retrieves a particular RA list node, matching with the
+ * given TID and RA address.
+ */
+static struct mwifiex_ra_list_tbl *
+mwifiex_wmm_get_ralist_node(struct mwifiex_private *priv, u8 tid,
+			    u8 *ra_addr)
+{
+	struct mwifiex_ra_list_tbl *ra_list;
+
+	list_for_each_entry(ra_list, &priv->wmm.tid_tbl_ptr[tid].ra_list,
+			    list) {
+		if (!memcmp(ra_list->ra, ra_addr, ETH_ALEN))
+			return ra_list;
+	}
+
+	return NULL;
+}
+
+/*
+ * This function retrieves an RA list node for a given TID and
+ * RA address pair.
+ *
+ * If no such node is found, a new node is added first and then
+ * retrieved.
+ */
+static struct mwifiex_ra_list_tbl *
+mwifiex_wmm_get_queue_raptr(struct mwifiex_private *priv, u8 tid, u8 *ra_addr)
+{
+	struct mwifiex_ra_list_tbl *ra_list;
+
+	ra_list = mwifiex_wmm_get_ralist_node(priv, tid, ra_addr);
+	if (ra_list)
+		return ra_list;
+	mwifiex_ralist_add(priv, ra_addr);
+
+	return mwifiex_wmm_get_ralist_node(priv, tid, ra_addr);
+}
+
+/*
+ * This function checks if a particular RA list node exists in a given TID
+ * table index.
+ */
+int
+mwifiex_is_ralist_valid(struct mwifiex_private *priv,
+			struct mwifiex_ra_list_tbl *ra_list, int ptr_index)
+{
+	struct mwifiex_ra_list_tbl *rlist;
+
+	list_for_each_entry(rlist, &priv->wmm.tid_tbl_ptr[ptr_index].ra_list,
+			    list) {
+		if (rlist == ra_list)
+			return true;
+	}
+
+	return false;
+}
+
+/*
+ * This function adds a packet to WMM queue.
+ *
+ * In disconnected state the packet is immediately dropped and the
+ * packet send completion callback is called with status failure.
+ *
+ * Otherwise, the correct RA list node is located and the packet
+ * is queued at the list tail.
+ */
+void
+mwifiex_wmm_add_buf_txqueue(struct mwifiex_adapter *adapter,
+			    struct sk_buff *skb)
+{
+	struct mwifiex_txinfo *tx_info = MWIFIEX_SKB_TXCB(skb);
+	struct mwifiex_private *priv = adapter->priv[tx_info->bss_index];
+	u32 tid;
+	struct mwifiex_ra_list_tbl *ra_list;
+	u8 ra[ETH_ALEN], tid_down;
+	unsigned long flags;
+
+	if (!priv->media_connected) {
+		dev_dbg(adapter->dev, "data: drop packet in disconnect\n");
+		mwifiex_write_data_complete(adapter, skb, -1);
+		return;
+	}
+
+	tid = skb->priority;
+
+	spin_lock_irqsave(&priv->wmm.ra_list_spinlock, flags);
+
+	tid_down = mwifiex_wmm_downgrade_tid(priv, tid);
+
+	/* In case of infra as we have already created the list during
+	   association we just don't have to call get_queue_raptr, we will
+	   have only 1 raptr for a tid in case of infra */
+	if (!mwifiex_queuing_ra_based(priv)) {
+		if (!list_empty(&priv->wmm.tid_tbl_ptr[tid_down].ra_list))
+			ra_list = list_first_entry(
+				&priv->wmm.tid_tbl_ptr[tid_down].ra_list,
+				struct mwifiex_ra_list_tbl, list);
+		else
+			ra_list = NULL;
+	} else {
+		memcpy(ra, skb->data, ETH_ALEN);
+		ra_list = mwifiex_wmm_get_queue_raptr(priv, tid_down, ra);
+	}
+
+	if (!ra_list) {
+		spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, flags);
+		mwifiex_write_data_complete(adapter, skb, -1);
+		return;
+	}
+
+	skb_queue_tail(&ra_list->skb_head, skb);
+
+	ra_list->total_pkts_size += skb->len;
+
+	atomic_inc(&priv->wmm.tx_pkts_queued);
+
+	if (atomic_read(&priv->wmm.highest_queued_prio) <
+						tos_to_tid_inv[tid_down])
+		atomic_set(&priv->wmm.highest_queued_prio,
+						tos_to_tid_inv[tid_down]);
+
+	spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, flags);
+}
+
+/*
+ * This function processes the get WMM status command response from firmware.
+ *
+ * The response may contain multiple TLVs -
+ *      - AC Queue status TLVs
+ *      - Current WMM Parameter IE TLV
+ *      - Admission Control action frame TLVs
+ *
+ * This function parses the TLVs and then calls further specific functions
+ * to process any changes in the queue prioritize or state.
+ */
+int mwifiex_ret_wmm_get_status(struct mwifiex_private *priv,
+			       const struct host_cmd_ds_command *resp)
+{
+	u8 *curr = (u8 *) &resp->params.get_wmm_status;
+	uint16_t resp_len = le16_to_cpu(resp->size), tlv_len;
+	int valid = true;
+
+	struct mwifiex_ie_types_data *tlv_hdr;
+	struct mwifiex_ie_types_wmm_queue_status *tlv_wmm_qstatus;
+	struct ieee_types_wmm_parameter *wmm_param_ie = NULL;
+	struct mwifiex_wmm_ac_status *ac_status;
+
+	dev_dbg(priv->adapter->dev, "info: WMM: WMM_GET_STATUS cmdresp received: %d\n",
+			resp_len);
+
+	while ((resp_len >= sizeof(tlv_hdr->header)) && valid) {
+		tlv_hdr = (struct mwifiex_ie_types_data *) curr;
+		tlv_len = le16_to_cpu(tlv_hdr->header.len);
+
+		switch (le16_to_cpu(tlv_hdr->header.type)) {
+		case TLV_TYPE_WMMQSTATUS:
+			tlv_wmm_qstatus =
+				(struct mwifiex_ie_types_wmm_queue_status *)
+				tlv_hdr;
+			dev_dbg(priv->adapter->dev,
+				"info: CMD_RESP: WMM_GET_STATUS:"
+				" QSTATUS TLV: %d, %d, %d\n",
+			       tlv_wmm_qstatus->queue_index,
+			       tlv_wmm_qstatus->flow_required,
+			       tlv_wmm_qstatus->disabled);
+
+			ac_status = &priv->wmm.ac_status[tlv_wmm_qstatus->
+							 queue_index];
+			ac_status->disabled = tlv_wmm_qstatus->disabled;
+			ac_status->flow_required =
+				tlv_wmm_qstatus->flow_required;
+			ac_status->flow_created = tlv_wmm_qstatus->flow_created;
+			break;
+
+		case WLAN_EID_VENDOR_SPECIFIC:
+			/*
+			 * Point the regular IEEE IE 2 bytes into the Marvell IE
+			 *   and setup the IEEE IE type and length byte fields
+			 */
+
+			wmm_param_ie =
+				(struct ieee_types_wmm_parameter *) (curr +
+								    2);
+			wmm_param_ie->vend_hdr.len = (u8) tlv_len;
+			wmm_param_ie->vend_hdr.element_id =
+						WLAN_EID_VENDOR_SPECIFIC;
+
+			dev_dbg(priv->adapter->dev,
+				"info: CMD_RESP: WMM_GET_STATUS:"
+				" WMM Parameter Set Count: %d\n",
+				wmm_param_ie->qos_info_bitmap &
+				IEEE80211_WMM_IE_AP_QOSINFO_PARAM_SET_CNT_MASK);
+
+			memcpy((u8 *) &priv->curr_bss_params.bss_descriptor.
+			       wmm_ie, wmm_param_ie,
+			       wmm_param_ie->vend_hdr.len + 2);
+
+			break;
+
+		default:
+			valid = false;
+			break;
+		}
+
+		curr += (tlv_len + sizeof(tlv_hdr->header));
+		resp_len -= (tlv_len + sizeof(tlv_hdr->header));
+	}
+
+	mwifiex_wmm_setup_queue_priorities(priv, wmm_param_ie);
+	mwifiex_wmm_setup_ac_downgrade(priv);
+
+	return 0;
+}
+
+/*
+ * Callback handler from the command module to allow insertion of a WMM TLV.
+ *
+ * If the BSS we are associating to supports WMM, this function adds the
+ * required WMM Information IE to the association request command buffer in
+ * the form of a Marvell extended IEEE IE.
+ */
+u32
+mwifiex_wmm_process_association_req(struct mwifiex_private *priv,
+				    u8 **assoc_buf,
+				    struct ieee_types_wmm_parameter *wmm_ie,
+				    struct ieee80211_ht_cap *ht_cap)
+{
+	struct mwifiex_ie_types_wmm_param_set *wmm_tlv;
+	u32 ret_len = 0;
+
+	/* Null checks */
+	if (!assoc_buf)
+		return 0;
+	if (!(*assoc_buf))
+		return 0;
+
+	if (!wmm_ie)
+		return 0;
+
+	dev_dbg(priv->adapter->dev, "info: WMM: process assoc req:"
+			"bss->wmmIe=0x%x\n",
+			wmm_ie->vend_hdr.element_id);
+
+	if ((priv->wmm_required
+	     || (ht_cap && (priv->adapter->config_bands & BAND_GN
+		     || priv->adapter->config_bands & BAND_AN))
+	    )
+	    && wmm_ie->vend_hdr.element_id == WLAN_EID_VENDOR_SPECIFIC) {
+		wmm_tlv = (struct mwifiex_ie_types_wmm_param_set *) *assoc_buf;
+		wmm_tlv->header.type = cpu_to_le16((u16) wmm_info_ie[0]);
+		wmm_tlv->header.len = cpu_to_le16((u16) wmm_info_ie[1]);
+		memcpy(wmm_tlv->wmm_ie, &wmm_info_ie[2],
+			le16_to_cpu(wmm_tlv->header.len));
+		if (wmm_ie->qos_info_bitmap & IEEE80211_WMM_IE_AP_QOSINFO_UAPSD)
+			memcpy((u8 *) (wmm_tlv->wmm_ie
+					+ le16_to_cpu(wmm_tlv->header.len)
+					 - sizeof(priv->wmm_qosinfo)),
+					&priv->wmm_qosinfo,
+					sizeof(priv->wmm_qosinfo));
+
+		ret_len = sizeof(wmm_tlv->header)
+			+ le16_to_cpu(wmm_tlv->header.len);
+
+		*assoc_buf += ret_len;
+	}
+
+	return ret_len;
+}
+
+/*
+ * This function computes the time delay in the driver queues for a
+ * given packet.
+ *
+ * When the packet is received at the OS/Driver interface, the current
+ * time is set in the packet structure. The difference between the present
+ * time and that received time is computed in this function and limited
+ * based on pre-compiled limits in the driver.
+ */
+u8
+mwifiex_wmm_compute_drv_pkt_delay(struct mwifiex_private *priv,
+					const struct sk_buff *skb)
+{
+	u8 ret_val;
+	struct timeval out_tstamp, in_tstamp;
+	u32 queue_delay;
+
+	do_gettimeofday(&out_tstamp);
+	in_tstamp = ktime_to_timeval(skb->tstamp);
+
+	queue_delay = (out_tstamp.tv_sec - in_tstamp.tv_sec) * 1000;
+	queue_delay += (out_tstamp.tv_usec - in_tstamp.tv_usec) / 1000;
+
+	/*
+	 * Queue delay is passed as a uint8 in units of 2ms (ms shifted
+	 *  by 1). Min value (other than 0) is therefore 2ms, max is 510ms.
+	 *
+	 * Pass max value if queue_delay is beyond the uint8 range
+	 */
+	ret_val = (u8) (min(queue_delay, priv->wmm.drv_pkt_delay_max) >> 1);
+
+	dev_dbg(priv->adapter->dev, "data: WMM: Pkt Delay: %d ms,"
+				" %d ms sent to FW\n", queue_delay, ret_val);
+
+	return ret_val;
+}
+
+/*
+ * This function retrieves the highest priority RA list table pointer.
+ */
+static struct mwifiex_ra_list_tbl *
+mwifiex_wmm_get_highest_priolist_ptr(struct mwifiex_adapter *adapter,
+				     struct mwifiex_private **priv, int *tid)
+{
+	struct mwifiex_private *priv_tmp;
+	struct mwifiex_ra_list_tbl *ptr, *head;
+	struct mwifiex_bss_prio_node *bssprio_node, *bssprio_head;
+	struct mwifiex_tid_tbl *tid_ptr;
+	int is_list_empty;
+	unsigned long flags;
+	int i, j;
+
+	for (j = adapter->priv_num - 1; j >= 0; --j) {
+		spin_lock_irqsave(&adapter->bss_prio_tbl[j].bss_prio_lock,
+				flags);
+		is_list_empty = list_empty(&adapter->bss_prio_tbl[j]
+				.bss_prio_head);
+		spin_unlock_irqrestore(&adapter->bss_prio_tbl[j].bss_prio_lock,
+				flags);
+		if (is_list_empty)
+			continue;
+
+		if (adapter->bss_prio_tbl[j].bss_prio_cur ==
+		    (struct mwifiex_bss_prio_node *)
+		    &adapter->bss_prio_tbl[j].bss_prio_head) {
+			bssprio_node =
+				list_first_entry(&adapter->bss_prio_tbl[j]
+						 .bss_prio_head,
+						 struct mwifiex_bss_prio_node,
+						 list);
+			bssprio_head = bssprio_node;
+		} else {
+			bssprio_node = adapter->bss_prio_tbl[j].bss_prio_cur;
+			bssprio_head = bssprio_node;
+		}
+
+		do {
+			atomic_t *hqp;
+			spinlock_t *lock;
+
+			priv_tmp = bssprio_node->priv;
+			hqp = &priv_tmp->wmm.highest_queued_prio;
+			lock = &priv_tmp->wmm.ra_list_spinlock;
+
+			for (i = atomic_read(hqp); i >= LOW_PRIO_TID; --i) {
+
+				tid_ptr = &(priv_tmp)->wmm.
+					tid_tbl_ptr[tos_to_tid[i]];
+
+				spin_lock_irqsave(&tid_ptr->tid_tbl_lock,
+						  flags);
+				is_list_empty =
+					list_empty(&adapter->bss_prio_tbl[j]
+						   .bss_prio_head);
+				spin_unlock_irqrestore(&tid_ptr->tid_tbl_lock,
+						       flags);
+				if (is_list_empty)
+					continue;
+
+				/*
+				 * Always choose the next ra we transmitted
+				 * last time, this way we pick the ra's in
+				 * round robin fashion.
+				 */
+				ptr = list_first_entry(
+						&tid_ptr->ra_list_curr->list,
+						struct mwifiex_ra_list_tbl,
+						list);
+
+				head = ptr;
+				if (ptr == (struct mwifiex_ra_list_tbl *)
+						&tid_ptr->ra_list) {
+					/* Get next ra */
+					ptr = list_first_entry(&ptr->list,
+					    struct mwifiex_ra_list_tbl, list);
+					head = ptr;
+				}
+
+				do {
+					is_list_empty =
+						skb_queue_empty(&ptr->skb_head);
+					if (!is_list_empty) {
+						spin_lock_irqsave(lock, flags);
+						if (atomic_read(hqp) > i)
+							atomic_set(hqp, i);
+						spin_unlock_irqrestore(lock,
+									flags);
+						*priv = priv_tmp;
+						*tid = tos_to_tid[i];
+						return ptr;
+					}
+					/* Get next ra */
+					ptr = list_first_entry(&ptr->list,
+						 struct mwifiex_ra_list_tbl,
+						 list);
+					if (ptr ==
+					    (struct mwifiex_ra_list_tbl *)
+					    &tid_ptr->ra_list)
+						ptr = list_first_entry(
+						    &ptr->list,
+						    struct mwifiex_ra_list_tbl,
+						    list);
+				} while (ptr != head);
+			}
+
+			/* No packet at any TID for this priv. Mark as such
+			 * to skip checking TIDs for this priv (until pkt is
+			 * added).
+			 */
+			atomic_set(hqp, NO_PKT_PRIO_TID);
+
+			/* Get next bss priority node */
+			bssprio_node = list_first_entry(&bssprio_node->list,
+						struct mwifiex_bss_prio_node,
+						list);
+
+			if (bssprio_node ==
+			    (struct mwifiex_bss_prio_node *)
+			    &adapter->bss_prio_tbl[j].bss_prio_head)
+				/* Get next bss priority node */
+				bssprio_node = list_first_entry(
+						&bssprio_node->list,
+						struct mwifiex_bss_prio_node,
+						list);
+		} while (bssprio_node != bssprio_head);
+	}
+	return NULL;
+}
+
+/*
+ * This function gets the number of packets in the Tx queue of a
+ * particular RA list.
+ */
+static int
+mwifiex_num_pkts_in_txq(struct mwifiex_private *priv,
+			struct mwifiex_ra_list_tbl *ptr, int max_buf_size)
+{
+	int count = 0, total_size = 0;
+	struct sk_buff *skb, *tmp;
+
+	skb_queue_walk_safe(&ptr->skb_head, skb, tmp) {
+		total_size += skb->len;
+		if (total_size < max_buf_size)
+			++count;
+		else
+			break;
+	}
+
+	return count;
+}
+
+/*
+ * This function sends a single packet to firmware for transmission.
+ */
+static void
+mwifiex_send_single_packet(struct mwifiex_private *priv,
+			   struct mwifiex_ra_list_tbl *ptr, int ptr_index,
+			   unsigned long ra_list_flags)
+			   __releases(&priv->wmm.ra_list_spinlock)
+{
+	struct sk_buff *skb, *skb_next;
+	struct mwifiex_tx_param tx_param;
+	struct mwifiex_adapter *adapter = priv->adapter;
+	struct mwifiex_txinfo *tx_info;
+
+	if (skb_queue_empty(&ptr->skb_head)) {
+		spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock,
+				       ra_list_flags);
+		dev_dbg(adapter->dev, "data: nothing to send\n");
+		return;
+	}
+
+	skb = skb_dequeue(&ptr->skb_head);
+
+	tx_info = MWIFIEX_SKB_TXCB(skb);
+	dev_dbg(adapter->dev, "data: dequeuing the packet %p %p\n", ptr, skb);
+
+	ptr->total_pkts_size -= skb->len;
+
+	if (!skb_queue_empty(&ptr->skb_head))
+		skb_next = skb_peek(&ptr->skb_head);
+	else
+		skb_next = NULL;
+
+	spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, ra_list_flags);
+
+	tx_param.next_pkt_len = ((skb_next) ? skb_next->len +
+				sizeof(struct txpd) : 0);
+
+	if (mwifiex_process_tx(priv, skb, &tx_param) == -EBUSY) {
+		/* Queue the packet back at the head */
+		spin_lock_irqsave(&priv->wmm.ra_list_spinlock, ra_list_flags);
+
+		if (!mwifiex_is_ralist_valid(priv, ptr, ptr_index)) {
+			spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock,
+					       ra_list_flags);
+			mwifiex_write_data_complete(adapter, skb, -1);
+			return;
+		}
+
+		skb_queue_tail(&ptr->skb_head, skb);
+
+		ptr->total_pkts_size += skb->len;
+		tx_info->flags |= MWIFIEX_BUF_FLAG_REQUEUED_PKT;
+		spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock,
+				       ra_list_flags);
+	} else {
+		spin_lock_irqsave(&priv->wmm.ra_list_spinlock, ra_list_flags);
+		if (mwifiex_is_ralist_valid(priv, ptr, ptr_index)) {
+			priv->wmm.packets_out[ptr_index]++;
+			priv->wmm.tid_tbl_ptr[ptr_index].ra_list_curr = ptr;
+		}
+		adapter->bss_prio_tbl[priv->bss_priority].bss_prio_cur =
+			list_first_entry(
+				&adapter->bss_prio_tbl[priv->bss_priority]
+				.bss_prio_cur->list,
+				struct mwifiex_bss_prio_node,
+				list);
+		atomic_dec(&priv->wmm.tx_pkts_queued);
+		spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock,
+				       ra_list_flags);
+	}
+}
+
+/*
+ * This function checks if the first packet in the given RA list
+ * is already processed or not.
+ */
+static int
+mwifiex_is_ptr_processed(struct mwifiex_private *priv,
+			 struct mwifiex_ra_list_tbl *ptr)
+{
+	struct sk_buff *skb;
+	struct mwifiex_txinfo *tx_info;
+
+	if (skb_queue_empty(&ptr->skb_head))
+		return false;
+
+	skb = skb_peek(&ptr->skb_head);
+
+	tx_info = MWIFIEX_SKB_TXCB(skb);
+	if (tx_info->flags & MWIFIEX_BUF_FLAG_REQUEUED_PKT)
+		return true;
+
+	return false;
+}
+
+/*
+ * This function sends a single processed packet to firmware for
+ * transmission.
+ */
+static void
+mwifiex_send_processed_packet(struct mwifiex_private *priv,
+			      struct mwifiex_ra_list_tbl *ptr, int ptr_index,
+			      unsigned long ra_list_flags)
+				__releases(&priv->wmm.ra_list_spinlock)
+{
+	struct mwifiex_tx_param tx_param;
+	struct mwifiex_adapter *adapter = priv->adapter;
+	int ret = -1;
+	struct sk_buff *skb, *skb_next;
+	struct mwifiex_txinfo *tx_info;
+
+	if (skb_queue_empty(&ptr->skb_head)) {
+		spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock,
+				       ra_list_flags);
+		return;
+	}
+
+	skb = skb_dequeue(&ptr->skb_head);
+
+	if (!skb_queue_empty(&ptr->skb_head))
+		skb_next = skb_peek(&ptr->skb_head);
+	else
+		skb_next = NULL;
+
+	tx_info = MWIFIEX_SKB_TXCB(skb);
+
+	spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, ra_list_flags);
+	tx_param.next_pkt_len =
+		((skb_next) ? skb_next->len +
+		 sizeof(struct txpd) : 0);
+	ret = adapter->if_ops.host_to_card(adapter, MWIFIEX_TYPE_DATA,
+					   skb->data, skb->len, &tx_param);
+	switch (ret) {
+	case -EBUSY:
+		dev_dbg(adapter->dev, "data: -EBUSY is returned\n");
+		spin_lock_irqsave(&priv->wmm.ra_list_spinlock, ra_list_flags);
+
+		if (!mwifiex_is_ralist_valid(priv, ptr, ptr_index)) {
+			spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock,
+					       ra_list_flags);
+			mwifiex_write_data_complete(adapter, skb, -1);
+			return;
+		}
+
+		skb_queue_tail(&ptr->skb_head, skb);
+
+		tx_info->flags |= MWIFIEX_BUF_FLAG_REQUEUED_PKT;
+		spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock,
+				       ra_list_flags);
+		break;
+	case -1:
+		adapter->data_sent = false;
+		dev_err(adapter->dev, "host_to_card failed: %#x\n", ret);
+		adapter->dbg.num_tx_host_to_card_failure++;
+		mwifiex_write_data_complete(adapter, skb, ret);
+		break;
+	case -EINPROGRESS:
+		adapter->data_sent = false;
+	default:
+		break;
+	}
+	if (ret != -EBUSY) {
+		spin_lock_irqsave(&priv->wmm.ra_list_spinlock, ra_list_flags);
+		if (mwifiex_is_ralist_valid(priv, ptr, ptr_index)) {
+			priv->wmm.packets_out[ptr_index]++;
+			priv->wmm.tid_tbl_ptr[ptr_index].ra_list_curr = ptr;
+		}
+		adapter->bss_prio_tbl[priv->bss_priority].bss_prio_cur =
+			list_first_entry(
+				&adapter->bss_prio_tbl[priv->bss_priority]
+				.bss_prio_cur->list,
+				struct mwifiex_bss_prio_node,
+				list);
+		atomic_dec(&priv->wmm.tx_pkts_queued);
+		spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock,
+				       ra_list_flags);
+	}
+}
+
+/*
+ * This function dequeues a packet from the highest priority list
+ * and transmits it.
+ */
+static int
+mwifiex_dequeue_tx_packet(struct mwifiex_adapter *adapter)
+{
+	struct mwifiex_ra_list_tbl *ptr;
+	struct mwifiex_private *priv = NULL;
+	int ptr_index = 0;
+	u8 ra[ETH_ALEN];
+	int tid_del = 0, tid = 0;
+	unsigned long flags;
+
+	ptr = mwifiex_wmm_get_highest_priolist_ptr(adapter, &priv, &ptr_index);
+	if (!ptr)
+		return -1;
+
+	tid = mwifiex_get_tid(ptr);
+
+	dev_dbg(adapter->dev, "data: tid=%d\n", tid);
+
+	spin_lock_irqsave(&priv->wmm.ra_list_spinlock, flags);
+	if (!mwifiex_is_ralist_valid(priv, ptr, ptr_index)) {
+		spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, flags);
+		return -1;
+	}
+
+	if (mwifiex_is_ptr_processed(priv, ptr)) {
+		mwifiex_send_processed_packet(priv, ptr, ptr_index, flags);
+		/* ra_list_spinlock has been freed in
+		   mwifiex_send_processed_packet() */
+		return 0;
+	}
+
+	if (!ptr->is_11n_enabled || mwifiex_is_ba_stream_setup(priv, ptr, tid)
+	    || ((priv->sec_info.wpa_enabled
+		  || priv->sec_info.wpa2_enabled) && !priv->wpa_is_gtk_set)
+		) {
+		mwifiex_send_single_packet(priv, ptr, ptr_index, flags);
+		/* ra_list_spinlock has been freed in
+		   mwifiex_send_single_packet() */
+	} else {
+		if (mwifiex_is_ampdu_allowed(priv, tid)) {
+			if (mwifiex_space_avail_for_new_ba_stream(adapter)) {
+				mwifiex_11n_create_tx_ba_stream_tbl(priv,
+						ptr->ra, tid,
+						BA_STREAM_SETUP_INPROGRESS);
+				mwifiex_send_addba(priv, tid, ptr->ra);
+			} else if (mwifiex_find_stream_to_delete
+				   (priv, tid, &tid_del, ra)) {
+				mwifiex_11n_create_tx_ba_stream_tbl(priv,
+						ptr->ra, tid,
+						BA_STREAM_SETUP_INPROGRESS);
+				mwifiex_send_delba(priv, tid_del, ra, 1);
+			}
+		}
+/* Minimum number of AMSDU */
+#define MIN_NUM_AMSDU 2
+		if (mwifiex_is_amsdu_allowed(priv, tid) &&
+		    (mwifiex_num_pkts_in_txq(priv, ptr, adapter->tx_buf_size) >=
+		     MIN_NUM_AMSDU))
+			mwifiex_11n_aggregate_pkt(priv, ptr, INTF_HEADER_LEN,
+						  ptr_index, flags);
+			/* ra_list_spinlock has been freed in
+			   mwifiex_11n_aggregate_pkt() */
+		else
+			mwifiex_send_single_packet(priv, ptr, ptr_index, flags);
+			/* ra_list_spinlock has been freed in
+			   mwifiex_send_single_packet() */
+	}
+	return 0;
+}
+
+/*
+ * This function transmits the highest priority packet awaiting in the
+ * WMM Queues.
+ */
+void
+mwifiex_wmm_process_tx(struct mwifiex_adapter *adapter)
+{
+	do {
+		/* Check if busy */
+		if (adapter->data_sent || adapter->tx_lock_flag)
+			break;
+
+		if (mwifiex_dequeue_tx_packet(adapter))
+			break;
+	} while (!mwifiex_wmm_lists_empty(adapter));
+}
diff -druN linux-2.6.39-libre/drivers/net/wireless/mwifiex/wmm.h linux-3.0-rc7-libre/drivers/net/wireless/mwifiex/wmm.h
--- linux-2.6.39-libre/drivers/net/wireless/mwifiex/wmm.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/net/wireless/mwifiex/wmm.h	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,110 @@
+/*
+ * Marvell Wireless LAN device driver: WMM
+ *
+ * Copyright (C) 2011, Marvell International Ltd.
+ *
+ * This software file (the "File") is distributed by Marvell International
+ * Ltd. under the terms of the GNU General Public License Version 2, June 1991
+ * (the "License").  You may use, redistribute and/or modify this File in
+ * accordance with the terms and conditions of the License, a copy of which
+ * is available by writing to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
+ * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
+ *
+ * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
+ * ARE EXPRESSLY DISCLAIMED.  The License provides additional details about
+ * this warranty disclaimer.
+ */
+
+#ifndef _MWIFIEX_WMM_H_
+#define _MWIFIEX_WMM_H_
+
+enum ieee_types_wmm_aciaifsn_bitmasks {
+	MWIFIEX_AIFSN = (BIT(0) | BIT(1) | BIT(2) | BIT(3)),
+	MWIFIEX_ACM = BIT(4),
+	MWIFIEX_ACI = (BIT(5) | BIT(6)),
+};
+
+enum ieee_types_wmm_ecw_bitmasks {
+	MWIFIEX_ECW_MIN = (BIT(0) | BIT(1) | BIT(2) | BIT(3)),
+	MWIFIEX_ECW_MAX = (BIT(4) | BIT(5) | BIT(6) | BIT(7)),
+};
+
+/*
+ * This function retrieves the TID of the given RA list.
+ */
+static inline int
+mwifiex_get_tid(struct mwifiex_ra_list_tbl *ptr)
+{
+	struct sk_buff *skb;
+
+	if (skb_queue_empty(&ptr->skb_head))
+		return 0;
+
+	skb = skb_peek(&ptr->skb_head);
+
+	return skb->priority;
+}
+
+/*
+ * This function gets the length of a list.
+ */
+static inline int
+mwifiex_wmm_list_len(struct list_head *head)
+{
+	struct list_head *pos;
+	int count = 0;
+
+	list_for_each(pos, head)
+		++count;
+
+	return count;
+}
+
+/*
+ * This function checks if a RA list is empty or not.
+ */
+static inline u8
+mwifiex_wmm_is_ra_list_empty(struct list_head *ra_list_hhead)
+{
+	struct mwifiex_ra_list_tbl *ra_list;
+	int is_list_empty;
+
+	list_for_each_entry(ra_list, ra_list_hhead, list) {
+		is_list_empty = skb_queue_empty(&ra_list->skb_head);
+		if (!is_list_empty)
+			return false;
+	}
+
+	return true;
+}
+
+void mwifiex_wmm_add_buf_txqueue(struct mwifiex_adapter *adapter,
+				 struct sk_buff *skb);
+void mwifiex_ralist_add(struct mwifiex_private *priv, u8 *ra);
+
+int mwifiex_wmm_lists_empty(struct mwifiex_adapter *adapter);
+void mwifiex_wmm_process_tx(struct mwifiex_adapter *adapter);
+int mwifiex_is_ralist_valid(struct mwifiex_private *priv,
+			    struct mwifiex_ra_list_tbl *ra_list, int tid);
+
+u8 mwifiex_wmm_compute_drv_pkt_delay(struct mwifiex_private *priv,
+					     const struct sk_buff *skb);
+void mwifiex_wmm_init(struct mwifiex_adapter *adapter);
+
+extern u32 mwifiex_wmm_process_association_req(struct mwifiex_private *priv,
+						 u8 **assoc_buf,
+						 struct ieee_types_wmm_parameter
+						 *wmmie,
+						 struct ieee80211_ht_cap
+						 *htcap);
+
+void mwifiex_wmm_setup_queue_priorities(struct mwifiex_private *priv,
+					struct ieee_types_wmm_parameter
+					*wmm_ie);
+void mwifiex_wmm_setup_ac_downgrade(struct mwifiex_private *priv);
+extern int mwifiex_ret_wmm_get_status(struct mwifiex_private *priv,
+				      const struct host_cmd_ds_command *resp);
+
+#endif /* !_MWIFIEX_WMM_H_ */
diff -druN linux-2.6.39-libre/drivers/net/wireless/mwl8k.c linux-3.0-rc7-libre/drivers/net/wireless/mwl8k.c
--- linux-2.6.39-libre/drivers/net/wireless/mwl8k.c	2011-05-19 02:14:58.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/mwl8k.c	2011-07-21 06:57:26.000000000 -0400
@@ -63,6 +63,7 @@
 #define MWL8K_HIU_A2H_INTERRUPT_CLEAR_SEL	0x00000c38
 #define MWL8K_HIU_A2H_INTERRUPT_STATUS_MASK	0x00000c3c
 #define  MWL8K_A2H_INT_DUMMY			 (1 << 20)
+#define  MWL8K_A2H_INT_BA_WATCHDOG		 (1 << 14)
 #define  MWL8K_A2H_INT_CHNL_SWITCHED		 (1 << 11)
 #define  MWL8K_A2H_INT_QUEUE_EMPTY		 (1 << 10)
 #define  MWL8K_A2H_INT_RADAR_DETECT		 (1 << 7)
@@ -73,6 +74,14 @@
 #define  MWL8K_A2H_INT_RX_READY			 (1 << 1)
 #define  MWL8K_A2H_INT_TX_DONE			 (1 << 0)
 
+/* HW micro second timer register
+ * located at offset 0xA600. This
+ * will be used to timestamp tx
+ * packets.
+ */
+
+#define	MWL8K_HW_TIMER_REGISTER			0x0000a600
+
 #define MWL8K_A2H_EVENTS	(MWL8K_A2H_INT_DUMMY | \
 				 MWL8K_A2H_INT_CHNL_SWITCHED | \
 				 MWL8K_A2H_INT_QUEUE_EMPTY | \
@@ -82,10 +91,14 @@
 				 MWL8K_A2H_INT_MAC_EVENT | \
 				 MWL8K_A2H_INT_OPC_DONE | \
 				 MWL8K_A2H_INT_RX_READY | \
-				 MWL8K_A2H_INT_TX_DONE)
+				 MWL8K_A2H_INT_TX_DONE | \
+				 MWL8K_A2H_INT_BA_WATCHDOG)
 
 #define MWL8K_RX_QUEUES		1
-#define MWL8K_TX_QUEUES		4
+#define MWL8K_TX_WMM_QUEUES	4
+#define MWL8K_MAX_AMPDU_QUEUES	8
+#define MWL8K_MAX_TX_QUEUES	(MWL8K_TX_WMM_QUEUES + MWL8K_MAX_AMPDU_QUEUES)
+#define mwl8k_tx_queues(priv)	(MWL8K_TX_WMM_QUEUES + (priv)->num_ampdu_queues)
 
 struct rxd_ops {
 	int rxd_size;
@@ -134,6 +147,21 @@
 	struct sk_buff **skb;
 };
 
+enum {
+	AMPDU_NO_STREAM,
+	AMPDU_STREAM_NEW,
+	AMPDU_STREAM_IN_PROGRESS,
+	AMPDU_STREAM_ACTIVE,
+};
+
+struct mwl8k_ampdu_stream {
+	struct ieee80211_sta *sta;
+	u8 tid;
+	u8 state;
+	u8 idx;
+	u8 txq_idx; /* index of this stream in priv->txq */
+};
+
 struct mwl8k_priv {
 	struct ieee80211_hw *hw;
 	struct pci_dev *pdev;
@@ -160,6 +188,12 @@
 	u32 ap_macids_supported;
 	u32 sta_macids_supported;
 
+	/* Ampdu stream information */
+	u8 num_ampdu_queues;
+	spinlock_t stream_lock;
+	struct mwl8k_ampdu_stream ampdu[MWL8K_MAX_AMPDU_QUEUES];
+	struct work_struct watchdog_ba_handle;
+
 	/* firmware access */
 	struct mutex fw_mutex;
 	struct task_struct *fw_mutex_owner;
@@ -191,7 +225,8 @@
 	int pending_tx_pkts;
 
 	struct mwl8k_rx_queue rxq[MWL8K_RX_QUEUES];
-	struct mwl8k_tx_queue txq[MWL8K_TX_QUEUES];
+	struct mwl8k_tx_queue txq[MWL8K_MAX_TX_QUEUES];
+	u32 txq_offset[MWL8K_MAX_TX_QUEUES];
 
 	bool radio_on;
 	bool radio_short_preamble;
@@ -224,7 +259,7 @@
 	 * preserve the queue configurations so they can be restored if/when
 	 * the firmware image is swapped.
 	 */
-	struct ieee80211_tx_queue_params wmm_params[MWL8K_TX_QUEUES];
+	struct ieee80211_tx_queue_params wmm_params[MWL8K_TX_WMM_QUEUES];
 
 	/* async firmware loading state */
 	unsigned fw_state;
@@ -262,9 +297,17 @@
 #define MWL8K_VIF(_vif) ((struct mwl8k_vif *)&((_vif)->drv_priv))
 #define IEEE80211_KEY_CONF(_u8) ((struct ieee80211_key_conf *)(_u8))
 
+struct tx_traffic_info {
+	u32 start_time;
+	u32 pkts;
+};
+
+#define MWL8K_MAX_TID 8
 struct mwl8k_sta {
 	/* Index into station database. Returned by UPDATE_STADB.  */
 	u8 peer_id;
+	u8 is_ampdu_allowed;
+	struct tx_traffic_info tx_stats[MWL8K_MAX_TID];
 };
 #define MWL8K_STA(_sta) ((struct mwl8k_sta *)&((_sta)->drv_priv))
 
@@ -352,10 +395,12 @@
 #define MWL8K_CMD_ENABLE_SNIFFER	0x0150
 #define MWL8K_CMD_SET_MAC_ADDR		0x0202		/* per-vif */
 #define MWL8K_CMD_SET_RATEADAPT_MODE	0x0203
+#define MWL8K_CMD_GET_WATCHDOG_BITMAP	0x0205
 #define MWL8K_CMD_BSS_START		0x1100		/* per-vif */
 #define MWL8K_CMD_SET_NEW_STN		0x1111		/* per-vif */
 #define MWL8K_CMD_UPDATE_ENCRYPTION	0x1122		/* per-vif */
 #define MWL8K_CMD_UPDATE_STADB		0x1123
+#define MWL8K_CMD_BASTREAM		0x1125
 
 static const char *mwl8k_cmd_name(__le16 cmd, char *buf, int bufsize)
 {
@@ -395,6 +440,8 @@
 		MWL8K_CMDNAME(SET_NEW_STN);
 		MWL8K_CMDNAME(UPDATE_ENCRYPTION);
 		MWL8K_CMDNAME(UPDATE_STADB);
+		MWL8K_CMDNAME(BASTREAM);
+		MWL8K_CMDNAME(GET_WATCHDOG_BITMAP);
 	default:
 		snprintf(buf, bufsize, "0x%x", cmd);
 	}
@@ -669,7 +716,7 @@
 			       "helper image\n", pci_name(priv->pdev));
 			return rc;
 		}
-		msleep(5);
+		msleep(20);
 
 		rc = mwl8k_feed_fw_image(priv, fw->data, fw->size);
 	} else {
@@ -734,8 +781,11 @@
 		skb_pull(skb, sizeof(*tr) - hdrlen);
 }
 
+#define REDUCED_TX_HEADROOM	8
+
 static void
-mwl8k_add_dma_header(struct sk_buff *skb, int tail_pad)
+mwl8k_add_dma_header(struct mwl8k_priv *priv, struct sk_buff *skb,
+						int head_pad, int tail_pad)
 {
 	struct ieee80211_hdr *wh;
 	int hdrlen;
@@ -751,7 +801,23 @@
 	wh = (struct ieee80211_hdr *)skb->data;
 
 	hdrlen = ieee80211_hdrlen(wh->frame_control);
-	reqd_hdrlen = sizeof(*tr);
+
+	/*
+	 * Check if skb_resize is required because of
+	 * tx_headroom adjustment.
+	 */
+	if (priv->ap_fw && (hdrlen < (sizeof(struct ieee80211_cts)
+						+ REDUCED_TX_HEADROOM))) {
+		if (pskb_expand_head(skb, REDUCED_TX_HEADROOM, 0, GFP_ATOMIC)) {
+
+			wiphy_err(priv->hw->wiphy,
+					"Failed to reallocate TX buffer\n");
+			return;
+		}
+		skb->truesize += REDUCED_TX_HEADROOM;
+	}
+
+	reqd_hdrlen = sizeof(*tr) + head_pad;
 
 	if (hdrlen != reqd_hdrlen)
 		skb_push(skb, reqd_hdrlen - hdrlen);
@@ -773,12 +839,14 @@
 	tr->fwlen = cpu_to_le16(skb->len - sizeof(*tr) + tail_pad);
 }
 
-static void mwl8k_encapsulate_tx_frame(struct sk_buff *skb)
+static void mwl8k_encapsulate_tx_frame(struct mwl8k_priv *priv,
+		struct sk_buff *skb)
 {
 	struct ieee80211_hdr *wh;
 	struct ieee80211_tx_info *tx_info;
 	struct ieee80211_key_conf *key_conf;
 	int data_pad;
+	int head_pad = 0;
 
 	wh = (struct ieee80211_hdr *)skb->data;
 
@@ -790,9 +858,7 @@
 
 	/*
 	 * Make sure the packet header is in the DMA header format (4-address
-	 * without QoS), the necessary crypto padding between the header and the
-	 * payload has already been provided by mac80211, but it doesn't add tail
-	 * padding when HW crypto is enabled.
+	 * without QoS), and add head & tail padding when HW crypto is enabled.
 	 *
 	 * We have the following trailer padding requirements:
 	 * - WEP: 4 trailer bytes (ICV)
@@ -801,6 +867,7 @@
 	 */
 	data_pad = 0;
 	if (key_conf != NULL) {
+		head_pad = key_conf->iv_len;
 		switch (key_conf->cipher) {
 		case WLAN_CIPHER_SUITE_WEP40:
 		case WLAN_CIPHER_SUITE_WEP104:
@@ -814,7 +881,7 @@
 			break;
 		}
 	}
-	mwl8k_add_dma_header(skb, data_pad);
+	mwl8k_add_dma_header(priv, skb, head_pad, data_pad);
 }
 
 /*
@@ -1127,6 +1194,9 @@
 	struct mwl8k_rx_queue *rxq = priv->rxq + index;
 	int i;
 
+	if (rxq->rxd == NULL)
+		return;
+
 	for (i = 0; i < MWL8K_RX_DESCS; i++) {
 		if (rxq->buf[i].skb != NULL) {
 			pci_unmap_single(priv->pdev,
@@ -1319,7 +1389,7 @@
 	__le16 pkt_len;
 	__u8 dest_MAC_addr[ETH_ALEN];
 	__le32 next_txd_phys_addr;
-	__le32 reserved;
+	__le32 timestamp;
 	__le16 rate_info;
 	__u8 peer_id;
 	__u8 tx_frag_cnt;
@@ -1383,7 +1453,7 @@
 	struct mwl8k_priv *priv = hw->priv;
 	int i;
 
-	for (i = 0; i < MWL8K_TX_QUEUES; i++) {
+	for (i = 0; i < mwl8k_tx_queues(priv); i++) {
 		struct mwl8k_tx_queue *txq = priv->txq + i;
 		int fw_owned = 0;
 		int drv_owned = 0;
@@ -1452,9 +1522,8 @@
 
 		if (timeout) {
 			WARN_ON(priv->pending_tx_pkts);
-			if (retry) {
+			if (retry)
 				wiphy_notice(hw->wiphy, "tx rings drained\n");
-			}
 			break;
 		}
 
@@ -1484,6 +1553,41 @@
 		     MWL8K_TXD_STATUS_OK_RETRY |		\
 		     MWL8K_TXD_STATUS_OK_MORE_RETRY))
 
+static int mwl8k_tid_queue_mapping(u8 tid)
+{
+	BUG_ON(tid > 7);
+
+	switch (tid) {
+	case 0:
+	case 3:
+		return IEEE80211_AC_BE;
+		break;
+	case 1:
+	case 2:
+		return IEEE80211_AC_BK;
+		break;
+	case 4:
+	case 5:
+		return IEEE80211_AC_VI;
+		break;
+	case 6:
+	case 7:
+		return IEEE80211_AC_VO;
+		break;
+	default:
+		return -1;
+		break;
+	}
+}
+
+/* The firmware will fill in the rate information
+ * for each packet that gets queued in the hardware
+ * and these macros will interpret that info.
+ */
+
+#define RI_FORMAT(a)		  (a & 0x0001)
+#define RI_RATE_ID_MCS(a)	 ((a & 0x01f8) >> 3)
+
 static int
 mwl8k_txq_reclaim(struct ieee80211_hw *hw, int index, int limit, int force)
 {
@@ -1500,6 +1604,10 @@
 		struct sk_buff *skb;
 		struct ieee80211_tx_info *info;
 		u32 status;
+		struct ieee80211_sta *sta;
+		struct mwl8k_sta *sta_info = NULL;
+		u16 rate_info;
+		struct ieee80211_hdr *wh;
 
 		tx = txq->head;
 		tx_desc = txq->txd + tx;
@@ -1528,18 +1636,40 @@
 
 		mwl8k_remove_dma_header(skb, tx_desc->qos_control);
 
+		wh = (struct ieee80211_hdr *) skb->data;
+
 		/* Mark descriptor as unused */
 		tx_desc->pkt_phys_addr = 0;
 		tx_desc->pkt_len = 0;
 
 		info = IEEE80211_SKB_CB(skb);
+		if (ieee80211_is_data(wh->frame_control)) {
+			sta = info->control.sta;
+			if (sta) {
+				sta_info = MWL8K_STA(sta);
+				BUG_ON(sta_info == NULL);
+				rate_info = le16_to_cpu(tx_desc->rate_info);
+				/* If rate is < 6.5 Mpbs for an ht station
+				 * do not form an ampdu. If the station is a
+				 * legacy station (format = 0), do not form an
+				 * ampdu
+				 */
+				if (RI_RATE_ID_MCS(rate_info) < 1 ||
+				    RI_FORMAT(rate_info) == 0) {
+					sta_info->is_ampdu_allowed = false;
+				} else {
+					sta_info->is_ampdu_allowed = true;
+				}
+			}
+		}
+
 		ieee80211_tx_info_clear_status(info);
 
 		/* Rate control is happening in the firmware.
 		 * Ensure no tx rate is being reported.
 		 */
-                info->status.rates[0].idx = -1;
-                info->status.rates[0].count = 1;
+		info->status.rates[0].idx = -1;
+		info->status.rates[0].count = 1;
 
 		if (MWL8K_TXD_SUCCESS(status))
 			info->flags |= IEEE80211_TX_STAT_ACK;
@@ -1549,9 +1679,6 @@
 		processed++;
 	}
 
-	if (processed && priv->radio_on && !mutex_is_locked(&priv->fw_mutex))
-		ieee80211_wake_queue(hw, index);
-
 	return processed;
 }
 
@@ -1561,6 +1688,9 @@
 	struct mwl8k_priv *priv = hw->priv;
 	struct mwl8k_tx_queue *txq = priv->txq + index;
 
+	if (txq->txd == NULL)
+		return;
+
 	mwl8k_txq_reclaim(hw, index, INT_MAX, 1);
 
 	kfree(txq->skb);
@@ -1572,12 +1702,116 @@
 	txq->txd = NULL;
 }
 
+/* caller must hold priv->stream_lock when calling the stream functions */
+static struct mwl8k_ampdu_stream *
+mwl8k_add_stream(struct ieee80211_hw *hw, struct ieee80211_sta *sta, u8 tid)
+{
+	struct mwl8k_ampdu_stream *stream;
+	struct mwl8k_priv *priv = hw->priv;
+	int i;
+
+	for (i = 0; i < priv->num_ampdu_queues; i++) {
+		stream = &priv->ampdu[i];
+		if (stream->state == AMPDU_NO_STREAM) {
+			stream->sta = sta;
+			stream->state = AMPDU_STREAM_NEW;
+			stream->tid = tid;
+			stream->idx = i;
+			stream->txq_idx = MWL8K_TX_WMM_QUEUES + i;
+			wiphy_debug(hw->wiphy, "Added a new stream for %pM %d",
+				    sta->addr, tid);
+			return stream;
+		}
+	}
+	return NULL;
+}
+
+static int
+mwl8k_start_stream(struct ieee80211_hw *hw, struct mwl8k_ampdu_stream *stream)
+{
+	int ret;
+
+	/* if the stream has already been started, don't start it again */
+	if (stream->state != AMPDU_STREAM_NEW)
+		return 0;
+	ret = ieee80211_start_tx_ba_session(stream->sta, stream->tid, 0);
+	if (ret)
+		wiphy_debug(hw->wiphy, "Failed to start stream for %pM %d: "
+			    "%d\n", stream->sta->addr, stream->tid, ret);
+	else
+		wiphy_debug(hw->wiphy, "Started stream for %pM %d\n",
+			    stream->sta->addr, stream->tid);
+	return ret;
+}
+
+static void
+mwl8k_remove_stream(struct ieee80211_hw *hw, struct mwl8k_ampdu_stream *stream)
+{
+	wiphy_debug(hw->wiphy, "Remove stream for %pM %d\n", stream->sta->addr,
+		    stream->tid);
+	memset(stream, 0, sizeof(*stream));
+}
+
+static struct mwl8k_ampdu_stream *
+mwl8k_lookup_stream(struct ieee80211_hw *hw, u8 *addr, u8 tid)
+{
+	struct mwl8k_priv *priv = hw->priv;
+	int i;
+
+	for (i = 0 ; i < priv->num_ampdu_queues; i++) {
+		struct mwl8k_ampdu_stream *stream;
+		stream = &priv->ampdu[i];
+		if (stream->state == AMPDU_NO_STREAM)
+			continue;
+		if (!memcmp(stream->sta->addr, addr, ETH_ALEN) &&
+		    stream->tid == tid)
+			return stream;
+	}
+	return NULL;
+}
+
+#define MWL8K_AMPDU_PACKET_THRESHOLD 64
+static inline bool mwl8k_ampdu_allowed(struct ieee80211_sta *sta, u8 tid)
+{
+	struct mwl8k_sta *sta_info = MWL8K_STA(sta);
+	struct tx_traffic_info *tx_stats;
+
+	BUG_ON(tid >= MWL8K_MAX_TID);
+	tx_stats = &sta_info->tx_stats[tid];
+
+	return sta_info->is_ampdu_allowed &&
+		tx_stats->pkts > MWL8K_AMPDU_PACKET_THRESHOLD;
+}
+
+static inline void mwl8k_tx_count_packet(struct ieee80211_sta *sta, u8 tid)
+{
+	struct mwl8k_sta *sta_info = MWL8K_STA(sta);
+	struct tx_traffic_info *tx_stats;
+
+	BUG_ON(tid >= MWL8K_MAX_TID);
+	tx_stats = &sta_info->tx_stats[tid];
+
+	if (tx_stats->start_time == 0)
+		tx_stats->start_time = jiffies;
+
+	/* reset the packet count after each second elapses.  If the number of
+	 * packets ever exceeds the ampdu_min_traffic threshold, we will allow
+	 * an ampdu stream to be started.
+	 */
+	if (jiffies - tx_stats->start_time > HZ) {
+		tx_stats->pkts = 0;
+		tx_stats->start_time = 0;
+	} else
+		tx_stats->pkts++;
+}
+
 static void
 mwl8k_txq_xmit(struct ieee80211_hw *hw, int index, struct sk_buff *skb)
 {
 	struct mwl8k_priv *priv = hw->priv;
 	struct ieee80211_tx_info *tx_info;
 	struct mwl8k_vif *mwl8k_vif;
+	struct ieee80211_sta *sta;
 	struct ieee80211_hdr *wh;
 	struct mwl8k_tx_queue *txq;
 	struct mwl8k_tx_desc *tx;
@@ -1585,6 +1819,12 @@
 	u32 txstatus;
 	u8 txdatarate;
 	u16 qos;
+	int txpriority;
+	u8 tid = 0;
+	struct mwl8k_ampdu_stream *stream = NULL;
+	bool start_ba_session = false;
+	bool mgmtframe = false;
+	struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)skb->data;
 
 	wh = (struct ieee80211_hdr *)skb->data;
 	if (ieee80211_is_data_qos(wh->frame_control))
@@ -1592,14 +1832,18 @@
 	else
 		qos = 0;
 
+	if (ieee80211_is_mgmt(wh->frame_control))
+		mgmtframe = true;
+
 	if (priv->ap_fw)
-		mwl8k_encapsulate_tx_frame(skb);
+		mwl8k_encapsulate_tx_frame(priv, skb);
 	else
-		mwl8k_add_dma_header(skb, 0);
+		mwl8k_add_dma_header(priv, skb, 0, 0);
 
 	wh = &((struct mwl8k_dma_data *)skb->data)->wh;
 
 	tx_info = IEEE80211_SKB_CB(skb);
+	sta = tx_info->control.sta;
 	mwl8k_vif = MWL8K_VIF(tx_info->control.vif);
 
 	if (tx_info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) {
@@ -1627,12 +1871,91 @@
 			qos |= MWL8K_QOS_ACK_POLICY_NORMAL;
 	}
 
+	/* Queue ADDBA request in the respective data queue.  While setting up
+	 * the ampdu stream, mac80211 queues further packets for that
+	 * particular ra/tid pair.  However, packets piled up in the hardware
+	 * for that ra/tid pair will still go out. ADDBA request and the
+	 * related data packets going out from different queues asynchronously
+	 * will cause a shift in the receiver window which might result in
+	 * ampdu packets getting dropped at the receiver after the stream has
+	 * been setup.
+	 */
+	if (unlikely(ieee80211_is_action(wh->frame_control) &&
+	    mgmt->u.action.category == WLAN_CATEGORY_BACK &&
+	    mgmt->u.action.u.addba_req.action_code == WLAN_ACTION_ADDBA_REQ &&
+	    priv->ap_fw)) {
+		u16 capab = le16_to_cpu(mgmt->u.action.u.addba_req.capab);
+		tid = (capab & IEEE80211_ADDBA_PARAM_TID_MASK) >> 2;
+		index = mwl8k_tid_queue_mapping(tid);
+	}
+
+	txpriority = index;
+
+	if (ieee80211_is_data_qos(wh->frame_control) &&
+	    skb->protocol != cpu_to_be16(ETH_P_PAE) &&
+	    sta->ht_cap.ht_supported && priv->ap_fw) {
+		tid = qos & 0xf;
+		mwl8k_tx_count_packet(sta, tid);
+		spin_lock(&priv->stream_lock);
+		stream = mwl8k_lookup_stream(hw, sta->addr, tid);
+		if (stream != NULL) {
+			if (stream->state == AMPDU_STREAM_ACTIVE) {
+				txpriority = stream->txq_idx;
+				index = stream->txq_idx;
+			} else if (stream->state == AMPDU_STREAM_NEW) {
+				/* We get here if the driver sends us packets
+				 * after we've initiated a stream, but before
+				 * our ampdu_action routine has been called
+				 * with IEEE80211_AMPDU_TX_START to get the SSN
+				 * for the ADDBA request.  So this packet can
+				 * go out with no risk of sequence number
+				 * mismatch.  No special handling is required.
+				 */
+			} else {
+				/* Drop packets that would go out after the
+				 * ADDBA request was sent but before the ADDBA
+				 * response is received.  If we don't do this,
+				 * the recipient would probably receive it
+				 * after the ADDBA request with SSN 0.  This
+				 * will cause the recipient's BA receive window
+				 * to shift, which would cause the subsequent
+				 * packets in the BA stream to be discarded.
+				 * mac80211 queues our packets for us in this
+				 * case, so this is really just a safety check.
+				 */
+				wiphy_warn(hw->wiphy,
+					   "Cannot send packet while ADDBA "
+					   "dialog is underway.\n");
+				spin_unlock(&priv->stream_lock);
+				dev_kfree_skb(skb);
+				return;
+			}
+		} else {
+			/* Defer calling mwl8k_start_stream so that the current
+			 * skb can go out before the ADDBA request.  This
+			 * prevents sequence number mismatch at the recepient
+			 * as described above.
+			 */
+			if (mwl8k_ampdu_allowed(sta, tid)) {
+				stream = mwl8k_add_stream(hw, sta, tid);
+				if (stream != NULL)
+					start_ba_session = true;
+			}
+		}
+		spin_unlock(&priv->stream_lock);
+	}
+
 	dma = pci_map_single(priv->pdev, skb->data,
 				skb->len, PCI_DMA_TODEVICE);
 
 	if (pci_dma_mapping_error(priv->pdev, dma)) {
 		wiphy_debug(hw->wiphy,
 			    "failed to dma map skb, dropping TX frame.\n");
+		if (start_ba_session) {
+			spin_lock(&priv->stream_lock);
+			mwl8k_remove_stream(hw, stream);
+			spin_unlock(&priv->stream_lock);
+		}
 		dev_kfree_skb(skb);
 		return;
 	}
@@ -1641,12 +1964,34 @@
 
 	txq = priv->txq + index;
 
+	/* Mgmt frames that go out frequently are probe
+	 * responses. Other mgmt frames got out relatively
+	 * infrequently. Hence reserve 2 buffers so that
+	 * other mgmt frames do not get dropped due to an
+	 * already queued probe response in one of the
+	 * reserved buffers.
+	 */
+
+	if (txq->len >= MWL8K_TX_DESCS - 2) {
+		if (mgmtframe == false ||
+			txq->len == MWL8K_TX_DESCS) {
+			if (start_ba_session) {
+				spin_lock(&priv->stream_lock);
+				mwl8k_remove_stream(hw, stream);
+				spin_unlock(&priv->stream_lock);
+			}
+			spin_unlock_bh(&priv->tx_lock);
+			dev_kfree_skb(skb);
+			return;
+		}
+	}
+
 	BUG_ON(txq->skb[txq->tail] != NULL);
 	txq->skb[txq->tail] = skb;
 
 	tx = txq->txd + txq->tail;
 	tx->data_rate = txdatarate;
-	tx->tx_priority = index;
+	tx->tx_priority = txpriority;
 	tx->qos_control = cpu_to_le16(qos);
 	tx->pkt_phys_addr = cpu_to_le32(dma);
 	tx->pkt_len = cpu_to_le16(skb->len);
@@ -1655,6 +2000,11 @@
 		tx->peer_id = MWL8K_STA(tx_info->control.sta)->peer_id;
 	else
 		tx->peer_id = 0;
+
+	if (priv->ap_fw)
+		tx->timestamp = cpu_to_le32(ioread32(priv->regs +
+						MWL8K_HW_TIMER_REGISTER));
+
 	wmb();
 	tx->status = cpu_to_le32(MWL8K_TXD_STATUS_FW_OWNED | txstatus);
 
@@ -1665,12 +2015,17 @@
 	if (txq->tail == MWL8K_TX_DESCS)
 		txq->tail = 0;
 
-	if (txq->head == txq->tail)
-		ieee80211_stop_queue(hw, index);
-
 	mwl8k_tx_start(priv);
 
 	spin_unlock_bh(&priv->tx_lock);
+
+	/* Initiate the ampdu session here */
+	if (start_ba_session) {
+		spin_lock(&priv->stream_lock);
+		if (mwl8k_start_stream(hw, stream))
+			mwl8k_remove_stream(hw, stream);
+		spin_unlock(&priv->stream_lock);
+	}
 }
 
 
@@ -1868,7 +2223,7 @@
 	__u8 mcs_bitmap[16];
 	__le32 rx_queue_ptr;
 	__le32 num_tx_queues;
-	__le32 tx_queue_ptrs[MWL8K_TX_QUEUES];
+	__le32 tx_queue_ptrs[MWL8K_TX_WMM_QUEUES];
 	__le32 caps2;
 	__le32 num_tx_desc_per_queue;
 	__le32 total_rxd;
@@ -1974,8 +2329,8 @@
 	memset(cmd->perm_addr, 0xff, sizeof(cmd->perm_addr));
 	cmd->ps_cookie = cpu_to_le32(priv->cookie_dma);
 	cmd->rx_queue_ptr = cpu_to_le32(priv->rxq[0].rxd_dma);
-	cmd->num_tx_queues = cpu_to_le32(MWL8K_TX_QUEUES);
-	for (i = 0; i < MWL8K_TX_QUEUES; i++)
+	cmd->num_tx_queues = cpu_to_le32(mwl8k_tx_queues(priv));
+	for (i = 0; i < mwl8k_tx_queues(priv); i++)
 		cmd->tx_queue_ptrs[i] = cpu_to_le32(priv->txq[i].txd_dma);
 	cmd->num_tx_desc_per_queue = cpu_to_le32(MWL8K_TX_DESCS);
 	cmd->total_rxd = cpu_to_le32(MWL8K_RX_DESCS);
@@ -2017,13 +2372,16 @@
 	__le32 wcbbase2;
 	__le32 wcbbase3;
 	__le32 fw_api_version;
+	__le32 caps;
+	__le32 num_of_ampdu_queues;
+	__le32 wcbbase_ampdu[MWL8K_MAX_AMPDU_QUEUES];
 } __packed;
 
 static int mwl8k_cmd_get_hw_spec_ap(struct ieee80211_hw *hw)
 {
 	struct mwl8k_priv *priv = hw->priv;
 	struct mwl8k_cmd_get_hw_spec_ap *cmd;
-	int rc;
+	int rc, i;
 	u32 api_version;
 
 	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
@@ -2055,27 +2413,31 @@
 		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);
+		mwl8k_set_caps(hw, le32_to_cpu(cmd->caps));
 		priv->ap_macids_supported = 0x000000ff;
 		priv->sta_macids_supported = 0x00000000;
-
-		off = le32_to_cpu(cmd->wcbbase0) & 0xffff;
-		iowrite32(priv->txq[0].txd_dma, priv->sram + off);
-
+		priv->num_ampdu_queues = le32_to_cpu(cmd->num_of_ampdu_queues);
+		if (priv->num_ampdu_queues > MWL8K_MAX_AMPDU_QUEUES) {
+			wiphy_warn(hw->wiphy, "fw reported %d ampdu queues"
+				   " but we only support %d.\n",
+				   priv->num_ampdu_queues,
+				   MWL8K_MAX_AMPDU_QUEUES);
+			priv->num_ampdu_queues = MWL8K_MAX_AMPDU_QUEUES;
+		}
 		off = le32_to_cpu(cmd->rxwrptr) & 0xffff;
 		iowrite32(priv->rxq[0].rxd_dma, priv->sram + off);
 
 		off = le32_to_cpu(cmd->rxrdptr) & 0xffff;
 		iowrite32(priv->rxq[0].rxd_dma, priv->sram + off);
 
-		off = le32_to_cpu(cmd->wcbbase1) & 0xffff;
-		iowrite32(priv->txq[1].txd_dma, priv->sram + off);
-
-		off = le32_to_cpu(cmd->wcbbase2) & 0xffff;
-		iowrite32(priv->txq[2].txd_dma, priv->sram + off);
+		priv->txq_offset[0] = le32_to_cpu(cmd->wcbbase0) & 0xffff;
+		priv->txq_offset[1] = le32_to_cpu(cmd->wcbbase1) & 0xffff;
+		priv->txq_offset[2] = le32_to_cpu(cmd->wcbbase2) & 0xffff;
+		priv->txq_offset[3] = le32_to_cpu(cmd->wcbbase3) & 0xffff;
 
-		off = le32_to_cpu(cmd->wcbbase3) & 0xffff;
-		iowrite32(priv->txq[3].txd_dma, priv->sram + off);
+		for (i = 0; i < priv->num_ampdu_queues; i++)
+			priv->txq_offset[i + MWL8K_TX_WMM_QUEUES] =
+				le32_to_cpu(cmd->wcbbase_ampdu[i]) & 0xffff;
 	}
 
 done:
@@ -2098,12 +2460,21 @@
 	__le32 caps;
 	__le32 rx_queue_ptr;
 	__le32 num_tx_queues;
-	__le32 tx_queue_ptrs[MWL8K_TX_QUEUES];
+	__le32 tx_queue_ptrs[MWL8K_MAX_TX_QUEUES];
 	__le32 flags;
 	__le32 num_tx_desc_per_queue;
 	__le32 total_rxd;
 } __packed;
 
+/* If enabled, MWL8K_SET_HW_SPEC_FLAG_ENABLE_LIFE_TIME_EXPIRY will cause
+ * packets to expire 500 ms after the timestamp in the tx descriptor.  That is,
+ * the packets that are queued for more than 500ms, will be dropped in the
+ * hardware. This helps minimizing the issues caused due to head-of-line
+ * blocking where a slow client can hog the bandwidth and affect traffic to a
+ * faster client.
+ */
+#define MWL8K_SET_HW_SPEC_FLAG_ENABLE_LIFE_TIME_EXPIRY	0x00000400
+#define MWL8K_SET_HW_SPEC_FLAG_GENERATE_CCMP_HDR	0x00000200
 #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
@@ -2124,7 +2495,7 @@
 
 	cmd->ps_cookie = cpu_to_le32(priv->cookie_dma);
 	cmd->rx_queue_ptr = cpu_to_le32(priv->rxq[0].rxd_dma);
-	cmd->num_tx_queues = cpu_to_le32(MWL8K_TX_QUEUES);
+	cmd->num_tx_queues = cpu_to_le32(mwl8k_tx_queues(priv));
 
 	/*
 	 * Mac80211 stack has Q0 as highest priority and Q3 as lowest in
@@ -2132,14 +2503,16 @@
 	 * in that order. Map Q3 of mac80211 to Q0 of firmware so that the
 	 * priority is interpreted the right way in firmware.
 	 */
-	for (i = 0; i < MWL8K_TX_QUEUES; i++) {
-		int j = MWL8K_TX_QUEUES - 1 - i;
+	for (i = 0; i < mwl8k_tx_queues(priv); i++) {
+		int j = mwl8k_tx_queues(priv) - 1 - i;
 		cmd->tx_queue_ptrs[i] = cpu_to_le32(priv->txq[j].txd_dma);
 	}
 
 	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);
+				 MWL8K_SET_HW_SPEC_FLAG_HOSTFORM_BEACON |
+				 MWL8K_SET_HW_SPEC_FLAG_ENABLE_LIFE_TIME_EXPIRY |
+				 MWL8K_SET_HW_SPEC_FLAG_GENERATE_CCMP_HDR);
 	cmd->num_tx_desc_per_queue = cpu_to_le32(MWL8K_TX_DESCS);
 	cmd->total_rxd = cpu_to_le32(MWL8K_RX_DESCS);
 
@@ -2356,7 +2729,7 @@
 	__le16 bw;
 	__le16 sub_ch;
 	__le16 power_level_list[MWL8K_TX_POWER_LEVEL_TOTAL];
-} __attribute__((packed));
+} __packed;
 
 static int mwl8k_cmd_tx_power(struct ieee80211_hw *hw,
 				     struct ieee80211_conf *conf,
@@ -3123,6 +3496,65 @@
 }
 
 /*
+ * CMD_GET_WATCHDOG_BITMAP.
+ */
+struct mwl8k_cmd_get_watchdog_bitmap {
+	struct mwl8k_cmd_pkt header;
+	u8	bitmap;
+} __packed;
+
+static int mwl8k_cmd_get_watchdog_bitmap(struct ieee80211_hw *hw, u8 *bitmap)
+{
+	struct mwl8k_cmd_get_watchdog_bitmap *cmd;
+	int rc;
+
+	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
+	if (cmd == NULL)
+		return -ENOMEM;
+
+	cmd->header.code = cpu_to_le16(MWL8K_CMD_GET_WATCHDOG_BITMAP);
+	cmd->header.length = cpu_to_le16(sizeof(*cmd));
+
+	rc = mwl8k_post_cmd(hw, &cmd->header);
+	if (!rc)
+		*bitmap = cmd->bitmap;
+
+	kfree(cmd);
+
+	return rc;
+}
+
+#define INVALID_BA	0xAA
+static void mwl8k_watchdog_ba_events(struct work_struct *work)
+{
+	int rc;
+	u8 bitmap = 0, stream_index;
+	struct mwl8k_ampdu_stream *streams;
+	struct mwl8k_priv *priv =
+		container_of(work, struct mwl8k_priv, watchdog_ba_handle);
+
+	rc = mwl8k_cmd_get_watchdog_bitmap(priv->hw, &bitmap);
+	if (rc)
+		return;
+
+	if (bitmap == INVALID_BA)
+		return;
+
+	/* the bitmap is the hw queue number.  Map it to the ampdu queue. */
+	stream_index = bitmap - MWL8K_TX_WMM_QUEUES;
+
+	BUG_ON(stream_index >= priv->num_ampdu_queues);
+
+	streams = &priv->ampdu[stream_index];
+
+	if (streams->state == AMPDU_STREAM_ACTIVE)
+		ieee80211_stop_tx_ba_session(streams->sta, streams->tid);
+
+	return;
+}
+
+
+/*
  * CMD_BSS_START.
  */
 struct mwl8k_cmd_bss_start {
@@ -3151,6 +3583,152 @@
 }
 
 /*
+ * CMD_BASTREAM.
+ */
+
+/*
+ * UPSTREAM is tx direction
+ */
+#define BASTREAM_FLAG_DIRECTION_UPSTREAM	0x00
+#define BASTREAM_FLAG_IMMEDIATE_TYPE		0x01
+
+enum ba_stream_action_type {
+	MWL8K_BA_CREATE,
+	MWL8K_BA_UPDATE,
+	MWL8K_BA_DESTROY,
+	MWL8K_BA_FLUSH,
+	MWL8K_BA_CHECK,
+};
+
+
+struct mwl8k_create_ba_stream {
+	__le32	flags;
+	__le32	idle_thrs;
+	__le32	bar_thrs;
+	__le32	window_size;
+	u8	peer_mac_addr[6];
+	u8	dialog_token;
+	u8	tid;
+	u8	queue_id;
+	u8	param_info;
+	__le32	ba_context;
+	u8	reset_seq_no_flag;
+	__le16	curr_seq_no;
+	u8	sta_src_mac_addr[6];
+} __packed;
+
+struct mwl8k_destroy_ba_stream {
+	__le32	flags;
+	__le32	ba_context;
+} __packed;
+
+struct mwl8k_cmd_bastream {
+	struct mwl8k_cmd_pkt	header;
+	__le32	action;
+	union {
+		struct mwl8k_create_ba_stream	create_params;
+		struct mwl8k_destroy_ba_stream	destroy_params;
+	};
+} __packed;
+
+static int
+mwl8k_check_ba(struct ieee80211_hw *hw, struct mwl8k_ampdu_stream *stream)
+{
+	struct mwl8k_cmd_bastream *cmd;
+	int rc;
+
+	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
+	if (cmd == NULL)
+		return -ENOMEM;
+
+	cmd->header.code = cpu_to_le16(MWL8K_CMD_BASTREAM);
+	cmd->header.length = cpu_to_le16(sizeof(*cmd));
+
+	cmd->action = cpu_to_le32(MWL8K_BA_CHECK);
+
+	cmd->create_params.queue_id = stream->idx;
+	memcpy(&cmd->create_params.peer_mac_addr[0], stream->sta->addr,
+	       ETH_ALEN);
+	cmd->create_params.tid = stream->tid;
+
+	cmd->create_params.flags =
+		cpu_to_le32(BASTREAM_FLAG_IMMEDIATE_TYPE) |
+		cpu_to_le32(BASTREAM_FLAG_DIRECTION_UPSTREAM);
+
+	rc = mwl8k_post_cmd(hw, &cmd->header);
+
+	kfree(cmd);
+
+	return rc;
+}
+
+static int
+mwl8k_create_ba(struct ieee80211_hw *hw, struct mwl8k_ampdu_stream *stream,
+		u8 buf_size)
+{
+	struct mwl8k_cmd_bastream *cmd;
+	int rc;
+
+	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
+	if (cmd == NULL)
+		return -ENOMEM;
+
+
+	cmd->header.code = cpu_to_le16(MWL8K_CMD_BASTREAM);
+	cmd->header.length = cpu_to_le16(sizeof(*cmd));
+
+	cmd->action = cpu_to_le32(MWL8K_BA_CREATE);
+
+	cmd->create_params.bar_thrs = cpu_to_le32((u32)buf_size);
+	cmd->create_params.window_size = cpu_to_le32((u32)buf_size);
+	cmd->create_params.queue_id = stream->idx;
+
+	memcpy(cmd->create_params.peer_mac_addr, stream->sta->addr, ETH_ALEN);
+	cmd->create_params.tid = stream->tid;
+	cmd->create_params.curr_seq_no = cpu_to_le16(0);
+	cmd->create_params.reset_seq_no_flag = 1;
+
+	cmd->create_params.param_info =
+		(stream->sta->ht_cap.ampdu_factor &
+		 IEEE80211_HT_AMPDU_PARM_FACTOR) |
+		((stream->sta->ht_cap.ampdu_density << 2) &
+		 IEEE80211_HT_AMPDU_PARM_DENSITY);
+
+	cmd->create_params.flags =
+		cpu_to_le32(BASTREAM_FLAG_IMMEDIATE_TYPE |
+					BASTREAM_FLAG_DIRECTION_UPSTREAM);
+
+	rc = mwl8k_post_cmd(hw, &cmd->header);
+
+	wiphy_debug(hw->wiphy, "Created a BA stream for %pM : tid %d\n",
+		stream->sta->addr, stream->tid);
+	kfree(cmd);
+
+	return rc;
+}
+
+static void mwl8k_destroy_ba(struct ieee80211_hw *hw,
+			     struct mwl8k_ampdu_stream *stream)
+{
+	struct mwl8k_cmd_bastream *cmd;
+
+	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
+	if (cmd == NULL)
+		return;
+
+	cmd->header.code = cpu_to_le16(MWL8K_CMD_BASTREAM);
+	cmd->header.length = cpu_to_le16(sizeof(*cmd));
+	cmd->action = cpu_to_le32(MWL8K_BA_DESTROY);
+
+	cmd->destroy_params.ba_context = cpu_to_le32(stream->idx);
+	mwl8k_post_cmd(hw, &cmd->header);
+
+	wiphy_debug(hw->wiphy, "Deleted BA stream index %d\n", stream->idx);
+
+	kfree(cmd);
+}
+
+/*
  * CMD_SET_NEW_STN.
  */
 struct mwl8k_cmd_set_new_stn {
@@ -3274,7 +3852,7 @@
 	__u8 mac_addr[6];
 	__u8 encr_type;
 
-} __attribute__((packed));
+} __packed;
 
 struct mwl8k_cmd_set_key {
 	struct mwl8k_cmd_pkt header;
@@ -3294,7 +3872,7 @@
 	__le16 tkip_tsc_low;
 	__le32 tkip_tsc_high;
 	__u8 mac_addr[6];
-} __attribute__((packed));
+} __packed;
 
 enum {
 	MWL8K_ENCR_ENABLE,
@@ -3422,7 +4000,7 @@
 			mwl8k_vif->wep_key_conf[idx].enabled = 1;
 		}
 
-		keymlen = 0;
+		keymlen = key->keylen;
 		action = MWL8K_ENCR_SET_KEY;
 		break;
 	case WLAN_CIPHER_SUITE_TKIP:
@@ -3496,7 +4074,6 @@
 		addr = sta->addr;
 
 	if (cmd_param == SET_KEY) {
-		key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
 		rc = mwl8k_cmd_encryption_set_key(hw, vif, addr, key);
 		if (rc)
 			goto out;
@@ -3671,6 +4248,11 @@
 		tasklet_schedule(&priv->poll_rx_task);
 	}
 
+	if (status & MWL8K_A2H_INT_BA_WATCHDOG) {
+		status &= ~MWL8K_A2H_INT_BA_WATCHDOG;
+		ieee80211_queue_work(hw, &priv->watchdog_ba_handle);
+	}
+
 	if (status)
 		iowrite32(~status, priv->regs + MWL8K_HIU_A2H_INTERRUPT_STATUS);
 
@@ -3699,7 +4281,7 @@
 
 	spin_lock_bh(&priv->tx_lock);
 
-	for (i = 0; i < MWL8K_TX_QUEUES; i++)
+	for (i = 0; i < mwl8k_tx_queues(priv); i++)
 		limit -= mwl8k_txq_reclaim(hw, i, limit, 0);
 
 	if (!priv->pending_tx_pkts && priv->tx_wait != NULL) {
@@ -3774,6 +4356,8 @@
 
 	/* Enable interrupts */
 	iowrite32(MWL8K_A2H_EVENTS, priv->regs + MWL8K_HIU_A2H_INTERRUPT_MASK);
+	iowrite32(MWL8K_A2H_EVENTS,
+		  priv->regs + MWL8K_HIU_A2H_INTERRUPT_STATUS_MASK);
 
 	rc = mwl8k_fw_lock(hw);
 	if (!rc) {
@@ -3829,6 +4413,7 @@
 
 	/* Stop finalize join worker */
 	cancel_work_sync(&priv->finalize_join_worker);
+	cancel_work_sync(&priv->watchdog_ba_handle);
 	if (priv->beacon_skb != NULL)
 		dev_kfree_skb(priv->beacon_skb);
 
@@ -3837,7 +4422,7 @@
 	tasklet_disable(&priv->poll_rx_task);
 
 	/* Return all skbs to mac80211 */
-	for (i = 0; i < MWL8K_TX_QUEUES; i++)
+	for (i = 0; i < mwl8k_tx_queues(priv); i++)
 		mwl8k_txq_reclaim(hw, i, INT_MAX, 1);
 }
 
@@ -3958,9 +4543,12 @@
 		conf->power_level = 18;
 
 	if (priv->ap_fw) {
-		rc = mwl8k_cmd_tx_power(hw, conf, conf->power_level);
-		if (rc)
-			goto out;
+
+		if (conf->flags & IEEE80211_CONF_CHANGE_POWER) {
+			rc = mwl8k_cmd_tx_power(hw, conf, conf->power_level);
+			if (rc)
+				goto out;
+		}
 
 		rc = mwl8k_cmd_rf_antenna(hw, MWL8K_RF_ANTENNA_RX, 0x3);
 		if (rc)
@@ -3987,7 +4575,7 @@
 			   struct ieee80211_bss_conf *info, u32 changed)
 {
 	struct mwl8k_priv *priv = hw->priv;
-	u32 ap_legacy_rates;
+	u32 ap_legacy_rates = 0;
 	u8 ap_mcs_rates[16];
 	int rc;
 
@@ -4312,6 +4900,8 @@
 		ret = mwl8k_cmd_update_stadb_add(hw, vif, sta);
 		if (ret >= 0) {
 			MWL8K_STA(sta)->peer_id = ret;
+			if (sta->ht_cap.ht_supported)
+				MWL8K_STA(sta)->is_ampdu_allowed = true;
 			ret = 0;
 		}
 
@@ -4335,14 +4925,14 @@
 
 	rc = mwl8k_fw_lock(hw);
 	if (!rc) {
-		BUG_ON(queue > MWL8K_TX_QUEUES - 1);
+		BUG_ON(queue > MWL8K_TX_WMM_QUEUES - 1);
 		memcpy(&priv->wmm_params[queue], params, sizeof(*params));
 
 		if (!priv->wmm_enabled)
 			rc = mwl8k_cmd_set_wmm_mode(hw, 1);
 
 		if (!rc) {
-			int q = MWL8K_TX_QUEUES - 1 - queue;
+			int q = MWL8K_TX_WMM_QUEUES - 1 - queue;
 			rc = mwl8k_cmd_set_edca_params(hw, q,
 						       params->cw_min,
 						       params->cw_max,
@@ -4378,21 +4968,118 @@
 	return 0;
 }
 
+#define MAX_AMPDU_ATTEMPTS 5
+
 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,
 		   u8 buf_size)
 {
+
+	int i, rc = 0;
+	struct mwl8k_priv *priv = hw->priv;
+	struct mwl8k_ampdu_stream *stream;
+	u8 *addr = sta->addr;
+
+	if (!(hw->flags & IEEE80211_HW_AMPDU_AGGREGATION))
+		return -ENOTSUPP;
+
+	spin_lock(&priv->stream_lock);
+	stream = mwl8k_lookup_stream(hw, addr, tid);
+
 	switch (action) {
 	case IEEE80211_AMPDU_RX_START:
 	case IEEE80211_AMPDU_RX_STOP:
-		if (!(hw->flags & IEEE80211_HW_AMPDU_AGGREGATION))
-			return -ENOTSUPP;
-		return 0;
+		break;
+	case IEEE80211_AMPDU_TX_START:
+		/* By the time we get here the hw queues may contain outgoing
+		 * packets for this RA/TID that are not part of this BA
+		 * session.  The hw will assign sequence numbers to these
+		 * packets as they go out.  So if we query the hw for its next
+		 * sequence number and use that for the SSN here, it may end up
+		 * being wrong, which will lead to sequence number mismatch at
+		 * the recipient.  To avoid this, we reset the sequence number
+		 * to O for the first MPDU in this BA stream.
+		 */
+		*ssn = 0;
+		if (stream == NULL) {
+			/* This means that somebody outside this driver called
+			 * ieee80211_start_tx_ba_session.  This is unexpected
+			 * because we do our own rate control.  Just warn and
+			 * move on.
+			 */
+			wiphy_warn(hw->wiphy, "Unexpected call to %s.  "
+				   "Proceeding anyway.\n", __func__);
+			stream = mwl8k_add_stream(hw, sta, tid);
+		}
+		if (stream == NULL) {
+			wiphy_debug(hw->wiphy, "no free AMPDU streams\n");
+			rc = -EBUSY;
+			break;
+		}
+		stream->state = AMPDU_STREAM_IN_PROGRESS;
+
+		/* Release the lock before we do the time consuming stuff */
+		spin_unlock(&priv->stream_lock);
+		for (i = 0; i < MAX_AMPDU_ATTEMPTS; i++) {
+			rc = mwl8k_check_ba(hw, stream);
+
+			if (!rc)
+				break;
+			/*
+			 * HW queues take time to be flushed, give them
+			 * sufficient time
+			 */
+
+			msleep(1000);
+		}
+		spin_lock(&priv->stream_lock);
+		if (rc) {
+			wiphy_err(hw->wiphy, "Stream for tid %d busy after %d"
+				" attempts\n", tid, MAX_AMPDU_ATTEMPTS);
+			mwl8k_remove_stream(hw, stream);
+			rc = -EBUSY;
+			break;
+		}
+		ieee80211_start_tx_ba_cb_irqsafe(vif, addr, tid);
+		break;
+	case IEEE80211_AMPDU_TX_STOP:
+		if (stream == NULL)
+			break;
+		if (stream->state == AMPDU_STREAM_ACTIVE) {
+			spin_unlock(&priv->stream_lock);
+			mwl8k_destroy_ba(hw, stream);
+			spin_lock(&priv->stream_lock);
+		}
+		mwl8k_remove_stream(hw, stream);
+		ieee80211_stop_tx_ba_cb_irqsafe(vif, addr, tid);
+		break;
+	case IEEE80211_AMPDU_TX_OPERATIONAL:
+		BUG_ON(stream == NULL);
+		BUG_ON(stream->state != AMPDU_STREAM_IN_PROGRESS);
+		spin_unlock(&priv->stream_lock);
+		rc = mwl8k_create_ba(hw, stream, buf_size);
+		spin_lock(&priv->stream_lock);
+		if (!rc)
+			stream->state = AMPDU_STREAM_ACTIVE;
+		else {
+			spin_unlock(&priv->stream_lock);
+			mwl8k_destroy_ba(hw, stream);
+			spin_lock(&priv->stream_lock);
+			wiphy_debug(hw->wiphy,
+				"Failed adding stream for sta %pM tid %d\n",
+				addr, tid);
+			mwl8k_remove_stream(hw, stream);
+		}
+		break;
+
 	default:
-		return -ENOTSUPP;
+		rc = -ENOTSUPP;
 	}
+
+	spin_unlock(&priv->stream_lock);
+	return rc;
 }
 
 static const struct ieee80211_ops mwl8k_ops = {
@@ -4441,7 +5128,7 @@
 	MWL8366,
 };
 
-#define MWL8K_8366_AP_FW_API 1
+#define MWL8K_8366_AP_FW_API 2
 #define _MWL8K_8366_AP_FW(api) "/*(DEBLOBBED)*/"
 #define MWL8K_8366_AP_FW(api) _MWL8K_8366_AP_FW(api)
 
@@ -4601,6 +5288,23 @@
 	return rc;
 }
 
+static int mwl8k_init_txqs(struct ieee80211_hw *hw)
+{
+	struct mwl8k_priv *priv = hw->priv;
+	int rc = 0;
+	int i;
+
+	for (i = 0; i < mwl8k_tx_queues(priv); i++) {
+		rc = mwl8k_txq_init(hw, i);
+		if (rc)
+			break;
+		if (priv->ap_fw)
+			iowrite32(priv->txq[i].txd_dma,
+				  priv->sram + priv->txq_offset[i]);
+	}
+	return rc;
+}
+
 /* initialize hw after successfully loading a firmware image */
 static int mwl8k_probe_hw(struct ieee80211_hw *hw)
 {
@@ -4628,17 +5332,26 @@
 		goto err_stop_firmware;
 	rxq_refill(hw, 0, INT_MAX);
 
-	for (i = 0; i < MWL8K_TX_QUEUES; i++) {
-		rc = mwl8k_txq_init(hw, i);
+	/* For the sta firmware, we need to know the dma addresses of tx queues
+	 * before sending MWL8K_CMD_GET_HW_SPEC.  So we must initialize them
+	 * prior to issuing this command.  But for the AP case, we learn the
+	 * total number of queues from the result CMD_GET_HW_SPEC, so for this
+	 * case we must initialize the tx queues after.
+	 */
+	priv->num_ampdu_queues = 0;
+	if (!priv->ap_fw) {
+		rc = mwl8k_init_txqs(hw);
 		if (rc)
 			goto err_free_queues;
 	}
 
 	iowrite32(0, priv->regs + MWL8K_HIU_A2H_INTERRUPT_STATUS);
 	iowrite32(0, priv->regs + MWL8K_HIU_A2H_INTERRUPT_MASK);
-	iowrite32(MWL8K_A2H_INT_TX_DONE | MWL8K_A2H_INT_RX_READY,
+	iowrite32(MWL8K_A2H_INT_TX_DONE|MWL8K_A2H_INT_RX_READY|
+		  MWL8K_A2H_INT_BA_WATCHDOG,
 		  priv->regs + MWL8K_HIU_A2H_INTERRUPT_CLEAR_SEL);
-	iowrite32(0xffffffff, priv->regs + MWL8K_HIU_A2H_INTERRUPT_STATUS_MASK);
+	iowrite32(MWL8K_A2H_INT_OPC_DONE,
+		  priv->regs + MWL8K_HIU_A2H_INTERRUPT_STATUS_MASK);
 
 	rc = request_irq(priv->pdev->irq, mwl8k_interrupt,
 			 IRQF_SHARED, MWL8K_NAME, hw);
@@ -4647,6 +5360,8 @@
 		goto err_free_queues;
 	}
 
+	memset(priv->ampdu, 0, sizeof(priv->ampdu));
+
 	/*
 	 * Temporarily enable interrupts.  Initial firmware host
 	 * commands use interrupts and avoid polling.  Disable
@@ -4658,6 +5373,8 @@
 	if (priv->ap_fw) {
 		rc = mwl8k_cmd_get_hw_spec_ap(hw);
 		if (!rc)
+			rc = mwl8k_init_txqs(hw);
+		if (!rc)
 			rc = mwl8k_cmd_set_hw_spec(hw);
 	} else {
 		rc = mwl8k_cmd_get_hw_spec_sta(hw);
@@ -4699,7 +5416,7 @@
 	free_irq(priv->pdev->irq, hw);
 
 err_free_queues:
-	for (i = 0; i < MWL8K_TX_QUEUES; i++)
+	for (i = 0; i < mwl8k_tx_queues(priv); i++)
 		mwl8k_txq_deinit(hw, i);
 	mwl8k_rxq_deinit(hw, 0);
 
@@ -4721,7 +5438,7 @@
 	mwl8k_stop(hw);
 	mwl8k_rxq_deinit(hw, 0);
 
-	for (i = 0; i < MWL8K_TX_QUEUES; i++)
+	for (i = 0; i < mwl8k_tx_queues(priv); i++)
 		mwl8k_txq_deinit(hw, i);
 
 	rc = mwl8k_init_firmware(hw, fw_image, false);
@@ -4740,7 +5457,7 @@
 	if (rc)
 		goto fail;
 
-	for (i = 0; i < MWL8K_TX_QUEUES; i++) {
+	for (i = 0; i < MWL8K_TX_WMM_QUEUES; i++) {
 		rc = mwl8k_conf_tx(hw, i, &priv->wmm_params[i]);
 		if (rc)
 			goto fail;
@@ -4772,9 +5489,11 @@
 	hw->extra_tx_headroom =
 		sizeof(struct mwl8k_dma_data) - sizeof(struct ieee80211_cts);
 
+	hw->extra_tx_headroom -= priv->ap_fw ? REDUCED_TX_HEADROOM : 0;
+
 	hw->channel_change_time = 10;
 
-	hw->queues = MWL8K_TX_QUEUES;
+	hw->queues = MWL8K_TX_WMM_QUEUES;
 
 	/* Set rssi values to dBm */
 	hw->flags |= IEEE80211_HW_SIGNAL_DBM | IEEE80211_HW_HAS_RATE_CONTROL;
@@ -4790,6 +5509,8 @@
 
 	/* Finalize join worker */
 	INIT_WORK(&priv->finalize_join_worker, mwl8k_finalize_join_worker);
+	/* Handle watchdog ba events */
+	INIT_WORK(&priv->watchdog_ba_handle, mwl8k_watchdog_ba_events);
 
 	/* TX reclaim and RX tasklets.  */
 	tasklet_init(&priv->poll_tx_task, mwl8k_tx_poll, (unsigned long)hw);
@@ -4809,6 +5530,8 @@
 
 	spin_lock_init(&priv->tx_lock);
 
+	spin_lock_init(&priv->stream_lock);
+
 	priv->tx_wait = NULL;
 
 	rc = mwl8k_probe_hw(hw);
@@ -4830,7 +5553,7 @@
 	return 0;
 
 err_unprobe_hw:
-	for (i = 0; i < MWL8K_TX_QUEUES; i++)
+	for (i = 0; i < mwl8k_tx_queues(priv); i++)
 		mwl8k_txq_deinit(hw, i);
 	mwl8k_rxq_deinit(hw, 0);
 
@@ -4989,10 +5712,10 @@
 	mwl8k_hw_reset(priv);
 
 	/* Return all skbs to mac80211 */
-	for (i = 0; i < MWL8K_TX_QUEUES; i++)
+	for (i = 0; i < mwl8k_tx_queues(priv); i++)
 		mwl8k_txq_reclaim(hw, i, INT_MAX, 1);
 
-	for (i = 0; i < MWL8K_TX_QUEUES; i++)
+	for (i = 0; i < mwl8k_tx_queues(priv); i++)
 		mwl8k_txq_deinit(hw, i);
 
 	mwl8k_rxq_deinit(hw, 0);
diff -druN linux-2.6.39-libre/drivers/net/wireless/orinoco/orinoco_cs.c linux-3.0-rc7-libre/drivers/net/wireless/orinoco/orinoco_cs.c
--- linux-2.6.39-libre/drivers/net/wireless/orinoco/orinoco_cs.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/orinoco/orinoco_cs.c	2011-07-11 19:51:52.000000000 -0400
@@ -237,7 +237,7 @@
 /* Module initialization					    */
 /********************************************************************/
 
-static struct pcmcia_device_id orinoco_cs_ids[] = {
+static const struct pcmcia_device_id orinoco_cs_ids[] = {
 	PCMCIA_DEVICE_MANF_CARD(0x0101, 0x0777), /* 3Com AirConnect PCI 777A */
 	PCMCIA_DEVICE_MANF_CARD(0x0156, 0x0002), /* Lucent Orinoco and old Intersil */
 	PCMCIA_DEVICE_MANF_CARD(0x016b, 0x0001), /* Ericsson WLAN Card C11 */
diff -druN linux-2.6.39-libre/drivers/net/wireless/orinoco/spectrum_cs.c linux-3.0-rc7-libre/drivers/net/wireless/orinoco/spectrum_cs.c
--- linux-2.6.39-libre/drivers/net/wireless/orinoco/spectrum_cs.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/orinoco/spectrum_cs.c	2011-07-11 19:51:52.000000000 -0400
@@ -301,7 +301,7 @@
 /* Module initialization					    */
 /********************************************************************/
 
-static struct pcmcia_device_id spectrum_cs_ids[] = {
+static const struct pcmcia_device_id spectrum_cs_ids[] = {
 	PCMCIA_DEVICE_MANF_CARD(0x026c, 0x0001), /* Symbol Spectrum24 LA4137 */
 	PCMCIA_DEVICE_MANF_CARD(0x0104, 0x0001), /* Socket Communications CF */
 	PCMCIA_DEVICE_PROD_ID12("Intel", "PRO/Wireless LAN PC Card", 0x816cc815, 0x6fbf459a), /* 2011B, not 2011 */
diff -druN linux-2.6.39-libre/drivers/net/wireless/p54/eeprom.c linux-3.0-rc7-libre/drivers/net/wireless/p54/eeprom.c
--- linux-2.6.39-libre/drivers/net/wireless/p54/eeprom.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/p54/eeprom.c	2011-07-11 19:51:52.000000000 -0400
@@ -491,7 +491,7 @@
 		struct pda_rssi_cal_entry *cal = (void *) &data[offset];
 
 		for (i = 0; i < entries; i++) {
-			u16 freq;
+			u16 freq = 0;
 			switch (i) {
 			case IEEE80211_BAND_2GHZ:
 				freq = 2437;
diff -druN linux-2.6.39-libre/drivers/net/wireless/p54/fwio.c linux-3.0-rc7-libre/drivers/net/wireless/p54/fwio.c
--- linux-2.6.39-libre/drivers/net/wireless/p54/fwio.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/p54/fwio.c	2011-07-11 19:51:52.000000000 -0400
@@ -727,3 +727,34 @@
 	p54_tx(priv, skb);
 	return 0;
 }
+
+int p54_set_groupfilter(struct p54_common *priv)
+{
+	struct p54_group_address_table *grp;
+	struct sk_buff *skb;
+	bool on = false;
+
+	skb = p54_alloc_skb(priv, P54_HDR_FLAG_CONTROL_OPSET, sizeof(*grp),
+			    P54_CONTROL_TYPE_GROUP_ADDRESS_TABLE, GFP_KERNEL);
+	if (!skb)
+		return -ENOMEM;
+
+	grp = (struct p54_group_address_table *)skb_put(skb, sizeof(*grp));
+
+	on = !(priv->filter_flags & FIF_ALLMULTI) &&
+	     (priv->mc_maclist_num > 0 &&
+	      priv->mc_maclist_num <= MC_FILTER_ADDRESS_NUM);
+
+	if (on) {
+		grp->filter_enable = cpu_to_le16(1);
+		grp->num_address = cpu_to_le16(priv->mc_maclist_num);
+		memcpy(grp->mac_list, priv->mc_maclist, sizeof(grp->mac_list));
+	} else {
+		grp->filter_enable = cpu_to_le16(0);
+		grp->num_address = cpu_to_le16(0);
+		memset(grp->mac_list, 0, sizeof(grp->mac_list));
+	}
+
+	p54_tx(priv, skb);
+	return 0;
+}
diff -druN linux-2.6.39-libre/drivers/net/wireless/p54/lmac.h linux-3.0-rc7-libre/drivers/net/wireless/p54/lmac.h
--- linux-2.6.39-libre/drivers/net/wireless/p54/lmac.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/p54/lmac.h	2011-07-11 19:51:52.000000000 -0400
@@ -540,6 +540,7 @@
 int p54_setup_mac(struct p54_common *priv);
 int p54_set_ps(struct p54_common *priv);
 int p54_fetch_statistics(struct p54_common *priv);
+int p54_set_groupfilter(struct p54_common *priv);
 
 /* e/v DCF setup */
 int p54_set_edcf(struct p54_common *priv);
diff -druN linux-2.6.39-libre/drivers/net/wireless/p54/main.c linux-3.0-rc7-libre/drivers/net/wireless/p54/main.c
--- linux-2.6.39-libre/drivers/net/wireless/p54/main.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/p54/main.c	2011-07-11 19:51:52.000000000 -0400
@@ -308,6 +308,31 @@
 	return ret;
 }
 
+static u64 p54_prepare_multicast(struct ieee80211_hw *dev,
+				 struct netdev_hw_addr_list *mc_list)
+{
+	struct p54_common *priv = dev->priv;
+	struct netdev_hw_addr *ha;
+	int i;
+
+	BUILD_BUG_ON(ARRAY_SIZE(priv->mc_maclist) !=
+		ARRAY_SIZE(((struct p54_group_address_table *)NULL)->mac_list));
+	/*
+	 * The first entry is reserved for the global broadcast MAC.
+	 * Otherwise the firmware will drop it and ARP will no longer work.
+	 */
+	i = 1;
+	priv->mc_maclist_num = netdev_hw_addr_list_count(mc_list) + i;
+	netdev_hw_addr_list_for_each(ha, mc_list) {
+		memcpy(&priv->mc_maclist[i], ha->addr, ETH_ALEN);
+		i++;
+		if (i >= ARRAY_SIZE(priv->mc_maclist))
+			break;
+	}
+
+	return 1; /* update */
+}
+
 static void p54_configure_filter(struct ieee80211_hw *dev,
 				 unsigned int changed_flags,
 				 unsigned int *total_flags,
@@ -316,12 +341,16 @@
 	struct p54_common *priv = dev->priv;
 
 	*total_flags &= FIF_PROMISC_IN_BSS |
+			FIF_ALLMULTI |
 			FIF_OTHER_BSS;
 
 	priv->filter_flags = *total_flags;
 
 	if (changed_flags & (FIF_PROMISC_IN_BSS | FIF_OTHER_BSS))
 		p54_setup_mac(priv);
+
+	if (changed_flags & FIF_ALLMULTI || multicast)
+		p54_set_groupfilter(priv);
 }
 
 static int p54_conf_tx(struct ieee80211_hw *dev, u16 queue,
@@ -591,6 +620,7 @@
 	.config			= p54_config,
 	.flush			= p54_flush,
 	.bss_info_changed	= p54_bss_info_changed,
+	.prepare_multicast	= p54_prepare_multicast,
 	.configure_filter	= p54_configure_filter,
 	.conf_tx		= p54_conf_tx,
 	.get_stats		= p54_get_stats,
@@ -660,6 +690,7 @@
 	init_completion(&priv->beacon_comp);
 	INIT_DELAYED_WORK(&priv->work, p54_work);
 
+	memset(&priv->mc_maclist[0], ~0, ETH_ALEN);
 	return dev;
 }
 EXPORT_SYMBOL_GPL(p54_init_common);
diff -druN linux-2.6.39-libre/drivers/net/wireless/p54/p54.h linux-3.0-rc7-libre/drivers/net/wireless/p54/p54.h
--- linux-2.6.39-libre/drivers/net/wireless/p54/p54.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/p54/p54.h	2011-07-11 19:51:52.000000000 -0400
@@ -211,8 +211,10 @@
 	/* BBP/MAC state */
 	u8 mac_addr[ETH_ALEN];
 	u8 bssid[ETH_ALEN];
+	u8 mc_maclist[4][ETH_ALEN];
 	u16 wakeup_timer;
 	unsigned int filter_flags;
+	int mc_maclist_num;
 	int mode;
 	u32 tsf_low32, tsf_high32;
 	u32 basic_rate_mask;
diff -druN linux-2.6.39-libre/drivers/net/wireless/p54/p54pci.c linux-3.0-rc7-libre/drivers/net/wireless/p54/p54pci.c
--- linux-2.6.39-libre/drivers/net/wireless/p54/p54pci.c	2011-05-19 02:15:15.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/p54/p54pci.c	2011-07-21 06:57:35.000000000 -0400
@@ -331,10 +331,9 @@
 	struct p54p_ring_control *ring_control = priv->ring_control;
 	struct p54p_desc *desc;
 	dma_addr_t mapping;
-	u32 device_idx, idx, i;
+	u32 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);
 
diff -druN linux-2.6.39-libre/drivers/net/wireless/p54/p54usb.c linux-3.0-rc7-libre/drivers/net/wireless/p54/p54usb.c
--- linux-2.6.39-libre/drivers/net/wireless/p54/p54usb.c	2011-05-19 02:15:21.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/p54/p54usb.c	2011-07-21 06:57:39.000000000 -0400
@@ -81,6 +81,7 @@
 	{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, 0xc501)},	/* Zoom Wireless-G 4410 */
 	{USB_DEVICE(0x083a, 0xf503)},	/* Accton FD7050E ver 1010ec  */
 	{USB_DEVICE(0x0846, 0x4240)},	/* Netgear WG111 (v2) */
 	{USB_DEVICE(0x0915, 0x2000)},	/* Cohiba Proto board */
diff -druN linux-2.6.39-libre/drivers/net/wireless/ray_cs.c linux-3.0-rc7-libre/drivers/net/wireless/ray_cs.c
--- linux-2.6.39-libre/drivers/net/wireless/ray_cs.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/ray_cs.c	2011-07-11 19:51:52.000000000 -0400
@@ -2781,7 +2781,7 @@
 };
 #endif
 
-static struct pcmcia_device_id ray_ids[] = {
+static const struct pcmcia_device_id ray_ids[] = {
 	PCMCIA_DEVICE_MANF_CARD(0x01a6, 0x0000),
 	PCMCIA_DEVICE_NULL,
 };
diff -druN linux-2.6.39-libre/drivers/net/wireless/rndis_wlan.c linux-3.0-rc7-libre/drivers/net/wireless/rndis_wlan.c
--- linux-2.6.39-libre/drivers/net/wireless/rndis_wlan.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/rndis_wlan.c	2011-07-11 19:51:52.000000000 -0400
@@ -2830,7 +2830,8 @@
 						req_ie_len, resp_ie,
 						resp_ie_len, 0, GFP_KERNEL);
 		else
-			cfg80211_roamed(usbdev->net, bssid, req_ie, req_ie_len,
+			cfg80211_roamed(usbdev->net, NULL, bssid,
+					req_ie, req_ie_len,
 					resp_ie, resp_ie_len, GFP_KERNEL);
 	} else if (priv->infra_mode == NDIS_80211_INFRA_ADHOC)
 		cfg80211_ibss_joined(usbdev->net, bssid, GFP_KERNEL);
diff -druN linux-2.6.39-libre/drivers/net/wireless/rt2x00/Kconfig linux-3.0-rc7-libre/drivers/net/wireless/rt2x00/Kconfig
--- linux-2.6.39-libre/drivers/net/wireless/rt2x00/Kconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/rt2x00/Kconfig	2011-07-11 19:51:52.000000000 -0400
@@ -59,7 +59,6 @@
 	select RT2800_LIB
 	select RT2X00_LIB_PCI if PCI
 	select RT2X00_LIB_SOC if RALINK_RT288X || RALINK_RT305X
-	select RT2X00_LIB_HT
 	select RT2X00_LIB_FIRMWARE
 	select RT2X00_LIB_CRYPTO
 	select CRC_CCITT
@@ -74,17 +73,13 @@
 if RT2800PCI
 
 config RT2800PCI_RT33XX
-	bool "rt2800pci - Include support for rt33xx devices (EXPERIMENTAL)"
-	depends on EXPERIMENTAL
-	default n
+	bool "rt2800pci - Include support for rt33xx devices"
+	default y
 	---help---
 	  This adds support for rt33xx wireless chipset family to the
 	  rt2800pci driver.
 	  Supported chips: RT3390
 
-	  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 devices (EXPERIMENTAL)"
 	depends on EXPERIMENTAL
@@ -98,17 +93,14 @@
 	  intended for testers and developers.
 
 config RT2800PCI_RT53XX
-       bool "rt2800-pci - Include support for rt53xx devices (EXPERIMENTAL)"
+       bool "rt2800pci - Include support for rt53xx devices (EXPERIMENTAL)"
        depends on EXPERIMENTAL
-       default n
+       default y
        ---help---
          This adds support for rt53xx wireless chipset family to the
          rt2800pci driver.
          Supported chips: RT5390
 
-         Support for these devices is non-functional at the moment and is
-         intended for testers and developers.
-
 endif
 
 config RT2500USB
@@ -140,7 +132,6 @@
 	depends on USB
 	select RT2800_LIB
 	select RT2X00_LIB_USB
-	select RT2X00_LIB_HT
 	select RT2X00_LIB_FIRMWARE
 	select RT2X00_LIB_CRYPTO
 	select CRC_CCITT
@@ -153,17 +144,13 @@
 if RT2800USB
 
 config RT2800USB_RT33XX
-	bool "rt2800usb - Include support for rt33xx devices (EXPERIMENTAL)"
-	depends on EXPERIMENTAL
-	default n
+	bool "rt2800usb - Include support for rt33xx devices"
+	default y
 	---help---
 	  This adds support for rt33xx wireless chipset family to the
 	  rt2800usb driver.
 	  Supported chips: RT3370
 
-	  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 devices (EXPERIMENTAL)"
 	depends on EXPERIMENTAL
@@ -176,6 +163,14 @@
 	  Support for these devices is non-functional at the moment and is
 	  intended for testers and developers.
 
+config RT2800USB_RT53XX
+       bool "rt2800usb - Include support for rt53xx devices (EXPERIMENTAL)"
+       depends on EXPERIMENTAL
+       ---help---
+         This adds support for rt53xx wireless chipset family to the
+         rt2800pci driver.
+         Supported chips: RT5370
+
 config RT2800USB_UNKNOWN
 	bool "rt2800usb - Include support for unknown (USB) devices"
 	default n
@@ -207,9 +202,6 @@
 config RT2X00_LIB
 	tristate
 
-config RT2X00_LIB_HT
-	boolean
-
 config RT2X00_LIB_FIRMWARE
 	boolean
 	select FW_LOADER
diff -druN linux-2.6.39-libre/drivers/net/wireless/rt2x00/Makefile linux-3.0-rc7-libre/drivers/net/wireless/rt2x00/Makefile
--- linux-2.6.39-libre/drivers/net/wireless/rt2x00/Makefile	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/rt2x00/Makefile	2011-07-11 19:51:52.000000000 -0400
@@ -7,7 +7,6 @@
 rt2x00lib-$(CONFIG_RT2X00_LIB_CRYPTO)	+= rt2x00crypto.o
 rt2x00lib-$(CONFIG_RT2X00_LIB_FIRMWARE)	+= rt2x00firmware.o
 rt2x00lib-$(CONFIG_RT2X00_LIB_LEDS)	+= rt2x00leds.o
-rt2x00lib-$(CONFIG_RT2X00_LIB_HT)	+= rt2x00ht.o
 
 obj-$(CONFIG_RT2X00_LIB)		+= rt2x00lib.o
 obj-$(CONFIG_RT2X00_LIB_PCI)		+= rt2x00pci.o
diff -druN linux-2.6.39-libre/drivers/net/wireless/rt2x00/rt2400pci.c linux-3.0-rc7-libre/drivers/net/wireless/rt2x00/rt2400pci.c
--- linux-2.6.39-libre/drivers/net/wireless/rt2x00/rt2400pci.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/rt2x00/rt2400pci.c	2011-07-11 19:51:52.000000000 -0400
@@ -1314,8 +1314,8 @@
 	}
 }
 
-static void rt2400pci_enable_interrupt(struct rt2x00_dev *rt2x00dev,
-				       struct rt2x00_field32 irq_field)
+static inline void rt2400pci_enable_interrupt(struct rt2x00_dev *rt2x00dev,
+					      struct rt2x00_field32 irq_field)
 {
 	u32 reg;
 
@@ -1368,8 +1368,10 @@
 static void rt2400pci_rxdone_tasklet(unsigned long data)
 {
 	struct rt2x00_dev *rt2x00dev = (struct rt2x00_dev *)data;
-	rt2x00pci_rxdone(rt2x00dev);
-	rt2400pci_enable_interrupt(rt2x00dev, CSR8_RXDONE);
+	if (rt2x00pci_rxdone(rt2x00dev))
+		tasklet_schedule(&rt2x00dev->rxdone_tasklet);
+	else
+		rt2400pci_enable_interrupt(rt2x00dev, CSR8_RXDONE);
 }
 
 static irqreturn_t rt2400pci_interrupt(int irq, void *dev_instance)
@@ -1534,13 +1536,13 @@
 	 * Detect if this device has an hardware controlled radio.
 	 */
 	if (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_HARDWARE_RADIO))
-		__set_bit(CONFIG_SUPPORT_HW_BUTTON, &rt2x00dev->flags);
+		__set_bit(CAPABILITY_HW_BUTTON, &rt2x00dev->cap_flags);
 
 	/*
 	 * Check if the BBP tuning should be enabled.
 	 */
 	if (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RX_AGCVGC_TUNING))
-		__set_bit(DRIVER_SUPPORT_LINK_TUNING, &rt2x00dev->flags);
+		__set_bit(CAPABILITY_LINK_TUNING, &rt2x00dev->cap_flags);
 
 	return 0;
 }
@@ -1638,9 +1640,9 @@
 	/*
 	 * This device requires the atim queue and DMA-mapped skbs.
 	 */
-	__set_bit(DRIVER_REQUIRE_ATIM_QUEUE, &rt2x00dev->flags);
-	__set_bit(DRIVER_REQUIRE_DMA, &rt2x00dev->flags);
-	__set_bit(DRIVER_REQUIRE_SW_SEQNO, &rt2x00dev->flags);
+	__set_bit(REQUIRE_ATIM_QUEUE, &rt2x00dev->cap_flags);
+	__set_bit(REQUIRE_DMA, &rt2x00dev->cap_flags);
+	__set_bit(REQUIRE_SW_SEQNO, &rt2x00dev->cap_flags);
 
 	/*
 	 * Set the rssi offset.
@@ -1718,6 +1720,9 @@
 	.tx_last_beacon		= rt2400pci_tx_last_beacon,
 	.rfkill_poll		= rt2x00mac_rfkill_poll,
 	.flush			= rt2x00mac_flush,
+	.set_antenna		= rt2x00mac_set_antenna,
+	.get_antenna		= rt2x00mac_get_antenna,
+	.get_ringparam		= rt2x00mac_get_ringparam,
 };
 
 static const struct rt2x00lib_ops rt2400pci_rt2x00_ops = {
@@ -1738,6 +1743,7 @@
 	.start_queue		= rt2400pci_start_queue,
 	.kick_queue		= rt2400pci_kick_queue,
 	.stop_queue		= rt2400pci_stop_queue,
+	.flush_queue		= rt2x00pci_flush_queue,
 	.write_tx_desc		= rt2400pci_write_tx_desc,
 	.write_beacon		= rt2400pci_write_beacon,
 	.fill_rxdone		= rt2400pci_fill_rxdone,
@@ -1799,10 +1805,11 @@
  * RT2400pci module information.
  */
 static DEFINE_PCI_DEVICE_TABLE(rt2400pci_device_table) = {
-	{ PCI_DEVICE(0x1814, 0x0101), PCI_DEVICE_DATA(&rt2400pci_ops) },
+	{ PCI_DEVICE(0x1814, 0x0101) },
 	{ 0, }
 };
 
+
 MODULE_AUTHOR(DRV_PROJECT);
 MODULE_VERSION(DRV_VERSION);
 MODULE_DESCRIPTION("Ralink RT2400 PCI & PCMCIA Wireless LAN driver.");
@@ -1810,10 +1817,16 @@
 MODULE_DEVICE_TABLE(pci, rt2400pci_device_table);
 MODULE_LICENSE("GPL");
 
+static int rt2400pci_probe(struct pci_dev *pci_dev,
+			   const struct pci_device_id *id)
+{
+	return rt2x00pci_probe(pci_dev, &rt2400pci_ops);
+}
+
 static struct pci_driver rt2400pci_driver = {
 	.name		= KBUILD_MODNAME,
 	.id_table	= rt2400pci_device_table,
-	.probe		= rt2x00pci_probe,
+	.probe		= rt2400pci_probe,
 	.remove		= __devexit_p(rt2x00pci_remove),
 	.suspend	= rt2x00pci_suspend,
 	.resume		= rt2x00pci_resume,
diff -druN linux-2.6.39-libre/drivers/net/wireless/rt2x00/rt2500pci.c linux-3.0-rc7-libre/drivers/net/wireless/rt2x00/rt2500pci.c
--- linux-2.6.39-libre/drivers/net/wireless/rt2x00/rt2500pci.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/rt2x00/rt2500pci.c	2011-07-11 19:51:52.000000000 -0400
@@ -1446,8 +1446,8 @@
 	}
 }
 
-static void rt2500pci_enable_interrupt(struct rt2x00_dev *rt2x00dev,
-				       struct rt2x00_field32 irq_field)
+static inline void rt2500pci_enable_interrupt(struct rt2x00_dev *rt2x00dev,
+					      struct rt2x00_field32 irq_field)
 {
 	u32 reg;
 
@@ -1500,8 +1500,10 @@
 static void rt2500pci_rxdone_tasklet(unsigned long data)
 {
 	struct rt2x00_dev *rt2x00dev = (struct rt2x00_dev *)data;
-	rt2x00pci_rxdone(rt2x00dev);
-	rt2500pci_enable_interrupt(rt2x00dev, CSR8_RXDONE);
+	if (rt2x00pci_rxdone(rt2x00dev))
+		tasklet_schedule(&rt2x00dev->rxdone_tasklet);
+	else
+		rt2500pci_enable_interrupt(rt2x00dev, CSR8_RXDONE);
 }
 
 static irqreturn_t rt2500pci_interrupt(int irq, void *dev_instance)
@@ -1685,14 +1687,14 @@
 	 * Detect if this device has an hardware controlled radio.
 	 */
 	if (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_HARDWARE_RADIO))
-		__set_bit(CONFIG_SUPPORT_HW_BUTTON, &rt2x00dev->flags);
+		__set_bit(CAPABILITY_HW_BUTTON, &rt2x00dev->cap_flags);
 
 	/*
 	 * Check if the BBP tuning should be enabled.
 	 */
 	rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC, &eeprom);
 	if (!rt2x00_get_field16(eeprom, EEPROM_NIC_DYN_BBP_TUNE))
-		__set_bit(DRIVER_SUPPORT_LINK_TUNING, &rt2x00dev->flags);
+		__set_bit(CAPABILITY_LINK_TUNING, &rt2x00dev->cap_flags);
 
 	/*
 	 * Read the RSSI <-> dBm offset information.
@@ -1956,9 +1958,9 @@
 	/*
 	 * This device requires the atim queue and DMA-mapped skbs.
 	 */
-	__set_bit(DRIVER_REQUIRE_ATIM_QUEUE, &rt2x00dev->flags);
-	__set_bit(DRIVER_REQUIRE_DMA, &rt2x00dev->flags);
-	__set_bit(DRIVER_REQUIRE_SW_SEQNO, &rt2x00dev->flags);
+	__set_bit(REQUIRE_ATIM_QUEUE, &rt2x00dev->cap_flags);
+	__set_bit(REQUIRE_DMA, &rt2x00dev->cap_flags);
+	__set_bit(REQUIRE_SW_SEQNO, &rt2x00dev->cap_flags);
 
 	/*
 	 * Set the rssi offset.
@@ -2011,6 +2013,9 @@
 	.tx_last_beacon		= rt2500pci_tx_last_beacon,
 	.rfkill_poll		= rt2x00mac_rfkill_poll,
 	.flush			= rt2x00mac_flush,
+	.set_antenna		= rt2x00mac_set_antenna,
+	.get_antenna		= rt2x00mac_get_antenna,
+	.get_ringparam		= rt2x00mac_get_ringparam,
 };
 
 static const struct rt2x00lib_ops rt2500pci_rt2x00_ops = {
@@ -2031,6 +2036,7 @@
 	.start_queue		= rt2500pci_start_queue,
 	.kick_queue		= rt2500pci_kick_queue,
 	.stop_queue		= rt2500pci_stop_queue,
+	.flush_queue		= rt2x00pci_flush_queue,
 	.write_tx_desc		= rt2500pci_write_tx_desc,
 	.write_beacon		= rt2500pci_write_beacon,
 	.fill_rxdone		= rt2500pci_fill_rxdone,
@@ -2092,7 +2098,7 @@
  * RT2500pci module information.
  */
 static DEFINE_PCI_DEVICE_TABLE(rt2500pci_device_table) = {
-	{ PCI_DEVICE(0x1814, 0x0201), PCI_DEVICE_DATA(&rt2500pci_ops) },
+	{ PCI_DEVICE(0x1814, 0x0201) },
 	{ 0, }
 };
 
@@ -2103,10 +2109,16 @@
 MODULE_DEVICE_TABLE(pci, rt2500pci_device_table);
 MODULE_LICENSE("GPL");
 
+static int rt2500pci_probe(struct pci_dev *pci_dev,
+			   const struct pci_device_id *id)
+{
+	return rt2x00pci_probe(pci_dev, &rt2500pci_ops);
+}
+
 static struct pci_driver rt2500pci_driver = {
 	.name		= KBUILD_MODNAME,
 	.id_table	= rt2500pci_device_table,
-	.probe		= rt2x00pci_probe,
+	.probe		= rt2500pci_probe,
 	.remove		= __devexit_p(rt2x00pci_remove),
 	.suspend	= rt2x00pci_suspend,
 	.resume		= rt2x00pci_resume,
diff -druN linux-2.6.39-libre/drivers/net/wireless/rt2x00/rt2500usb.c linux-3.0-rc7-libre/drivers/net/wireless/rt2x00/rt2500usb.c
--- linux-2.6.39-libre/drivers/net/wireless/rt2x00/rt2500usb.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/rt2x00/rt2500usb.c	2011-07-11 19:51:52.000000000 -0400
@@ -1519,7 +1519,7 @@
 	 * Detect if this device has an hardware controlled radio.
 	 */
 	if (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_HARDWARE_RADIO))
-		__set_bit(CONFIG_SUPPORT_HW_BUTTON, &rt2x00dev->flags);
+		__set_bit(CAPABILITY_HW_BUTTON, &rt2x00dev->cap_flags);
 
 	/*
 	 * Read the RSSI <-> dBm offset information.
@@ -1790,14 +1790,14 @@
 	/*
 	 * This device requires the atim queue
 	 */
-	__set_bit(DRIVER_REQUIRE_ATIM_QUEUE, &rt2x00dev->flags);
-	__set_bit(DRIVER_REQUIRE_BEACON_GUARD, &rt2x00dev->flags);
+	__set_bit(REQUIRE_ATIM_QUEUE, &rt2x00dev->cap_flags);
+	__set_bit(REQUIRE_BEACON_GUARD, &rt2x00dev->cap_flags);
 	if (!modparam_nohwcrypt) {
-		__set_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags);
-		__set_bit(DRIVER_REQUIRE_COPY_IV, &rt2x00dev->flags);
+		__set_bit(CAPABILITY_HW_CRYPTO, &rt2x00dev->cap_flags);
+		__set_bit(REQUIRE_COPY_IV, &rt2x00dev->cap_flags);
 	}
-	__set_bit(DRIVER_SUPPORT_WATCHDOG, &rt2x00dev->flags);
-	__set_bit(DRIVER_REQUIRE_SW_SEQNO, &rt2x00dev->flags);
+	__set_bit(REQUIRE_SW_SEQNO, &rt2x00dev->cap_flags);
+	__set_bit(REQUIRE_PS_AUTOWAKE, &rt2x00dev->cap_flags);
 
 	/*
 	 * Set the rssi offset.
@@ -1824,6 +1824,9 @@
 	.conf_tx		= rt2x00mac_conf_tx,
 	.rfkill_poll		= rt2x00mac_rfkill_poll,
 	.flush			= rt2x00mac_flush,
+	.set_antenna		= rt2x00mac_set_antenna,
+	.get_antenna		= rt2x00mac_get_antenna,
+	.get_ringparam		= rt2x00mac_get_ringparam,
 };
 
 static const struct rt2x00lib_ops rt2500usb_rt2x00_ops = {
@@ -1905,58 +1908,54 @@
  */
 static struct usb_device_id rt2500usb_device_table[] = {
 	/* ASUS */
-	{ USB_DEVICE(0x0b05, 0x1706), USB_DEVICE_DATA(&rt2500usb_ops) },
-	{ USB_DEVICE(0x0b05, 0x1707), USB_DEVICE_DATA(&rt2500usb_ops) },
+	{ USB_DEVICE(0x0b05, 0x1706) },
+	{ USB_DEVICE(0x0b05, 0x1707) },
 	/* Belkin */
-	{ USB_DEVICE(0x050d, 0x7050), USB_DEVICE_DATA(&rt2500usb_ops) },
-	{ USB_DEVICE(0x050d, 0x7051), USB_DEVICE_DATA(&rt2500usb_ops) },
-	{ USB_DEVICE(0x050d, 0x705a), USB_DEVICE_DATA(&rt2500usb_ops) },
+	{ USB_DEVICE(0x050d, 0x7050) },
+	{ USB_DEVICE(0x050d, 0x7051) },
 	/* Cisco Systems */
-	{ USB_DEVICE(0x13b1, 0x000d), USB_DEVICE_DATA(&rt2500usb_ops) },
-	{ USB_DEVICE(0x13b1, 0x0011), USB_DEVICE_DATA(&rt2500usb_ops) },
-	{ USB_DEVICE(0x13b1, 0x001a), USB_DEVICE_DATA(&rt2500usb_ops) },
-	/* CNet */
-	{ USB_DEVICE(0x1371, 0x9022), USB_DEVICE_DATA(&rt2500usb_ops) },
+	{ USB_DEVICE(0x13b1, 0x000d) },
+	{ USB_DEVICE(0x13b1, 0x0011) },
+	{ USB_DEVICE(0x13b1, 0x001a) },
 	/* Conceptronic */
-	{ USB_DEVICE(0x14b2, 0x3c02), USB_DEVICE_DATA(&rt2500usb_ops) },
+	{ USB_DEVICE(0x14b2, 0x3c02) },
 	/* D-LINK */
-	{ USB_DEVICE(0x2001, 0x3c00), USB_DEVICE_DATA(&rt2500usb_ops) },
+	{ USB_DEVICE(0x2001, 0x3c00) },
 	/* Gigabyte */
-	{ USB_DEVICE(0x1044, 0x8001), USB_DEVICE_DATA(&rt2500usb_ops) },
-	{ USB_DEVICE(0x1044, 0x8007), USB_DEVICE_DATA(&rt2500usb_ops) },
+	{ USB_DEVICE(0x1044, 0x8001) },
+	{ USB_DEVICE(0x1044, 0x8007) },
 	/* Hercules */
-	{ USB_DEVICE(0x06f8, 0xe000), USB_DEVICE_DATA(&rt2500usb_ops) },
+	{ USB_DEVICE(0x06f8, 0xe000) },
 	/* Melco */
-	{ USB_DEVICE(0x0411, 0x005e), USB_DEVICE_DATA(&rt2500usb_ops) },
-	{ USB_DEVICE(0x0411, 0x0066), USB_DEVICE_DATA(&rt2500usb_ops) },
-	{ USB_DEVICE(0x0411, 0x0067), USB_DEVICE_DATA(&rt2500usb_ops) },
-	{ USB_DEVICE(0x0411, 0x008b), USB_DEVICE_DATA(&rt2500usb_ops) },
-	{ USB_DEVICE(0x0411, 0x0097), USB_DEVICE_DATA(&rt2500usb_ops) },
+	{ USB_DEVICE(0x0411, 0x005e) },
+	{ USB_DEVICE(0x0411, 0x0066) },
+	{ USB_DEVICE(0x0411, 0x0067) },
+	{ USB_DEVICE(0x0411, 0x008b) },
+	{ USB_DEVICE(0x0411, 0x0097) },
 	/* MSI */
-	{ USB_DEVICE(0x0db0, 0x6861), USB_DEVICE_DATA(&rt2500usb_ops) },
-	{ USB_DEVICE(0x0db0, 0x6865), USB_DEVICE_DATA(&rt2500usb_ops) },
-	{ USB_DEVICE(0x0db0, 0x6869), USB_DEVICE_DATA(&rt2500usb_ops) },
+	{ USB_DEVICE(0x0db0, 0x6861) },
+	{ USB_DEVICE(0x0db0, 0x6865) },
+	{ USB_DEVICE(0x0db0, 0x6869) },
 	/* Ralink */
-	{ USB_DEVICE(0x148f, 0x1706), USB_DEVICE_DATA(&rt2500usb_ops) },
-	{ USB_DEVICE(0x148f, 0x2570), USB_DEVICE_DATA(&rt2500usb_ops) },
-	{ USB_DEVICE(0x148f, 0x2573), USB_DEVICE_DATA(&rt2500usb_ops) },
-	{ USB_DEVICE(0x148f, 0x9020), USB_DEVICE_DATA(&rt2500usb_ops) },
+	{ USB_DEVICE(0x148f, 0x1706) },
+	{ USB_DEVICE(0x148f, 0x2570) },
+	{ USB_DEVICE(0x148f, 0x9020) },
 	/* Sagem */
-	{ USB_DEVICE(0x079b, 0x004b), USB_DEVICE_DATA(&rt2500usb_ops) },
+	{ USB_DEVICE(0x079b, 0x004b) },
 	/* Siemens */
-	{ USB_DEVICE(0x0681, 0x3c06), USB_DEVICE_DATA(&rt2500usb_ops) },
+	{ USB_DEVICE(0x0681, 0x3c06) },
 	/* SMC */
-	{ USB_DEVICE(0x0707, 0xee13), USB_DEVICE_DATA(&rt2500usb_ops) },
+	{ USB_DEVICE(0x0707, 0xee13) },
 	/* Spairon */
-	{ USB_DEVICE(0x114b, 0x0110), USB_DEVICE_DATA(&rt2500usb_ops) },
+	{ USB_DEVICE(0x114b, 0x0110) },
 	/* SURECOM */
-	{ USB_DEVICE(0x0769, 0x11f3), USB_DEVICE_DATA(&rt2500usb_ops) },
+	{ USB_DEVICE(0x0769, 0x11f3) },
 	/* Trust */
-	{ USB_DEVICE(0x0eb0, 0x9020), USB_DEVICE_DATA(&rt2500usb_ops) },
+	{ USB_DEVICE(0x0eb0, 0x9020) },
 	/* VTech */
-	{ USB_DEVICE(0x0f88, 0x3012), USB_DEVICE_DATA(&rt2500usb_ops) },
+	{ USB_DEVICE(0x0f88, 0x3012) },
 	/* Zinwell */
-	{ USB_DEVICE(0x5a57, 0x0260), USB_DEVICE_DATA(&rt2500usb_ops) },
+	{ USB_DEVICE(0x5a57, 0x0260) },
 	{ 0, }
 };
 
@@ -1967,10 +1966,16 @@
 MODULE_DEVICE_TABLE(usb, rt2500usb_device_table);
 MODULE_LICENSE("GPL");
 
+static int rt2500usb_probe(struct usb_interface *usb_intf,
+			   const struct usb_device_id *id)
+{
+	return rt2x00usb_probe(usb_intf, &rt2500usb_ops);
+}
+
 static struct usb_driver rt2500usb_driver = {
 	.name		= KBUILD_MODNAME,
 	.id_table	= rt2500usb_device_table,
-	.probe		= rt2x00usb_probe,
+	.probe		= rt2500usb_probe,
 	.disconnect	= rt2x00usb_disconnect,
 	.suspend	= rt2x00usb_suspend,
 	.resume		= rt2x00usb_resume,
diff -druN linux-2.6.39-libre/drivers/net/wireless/rt2x00/rt2800.h linux-3.0-rc7-libre/drivers/net/wireless/rt2x00/rt2800.h
--- linux-2.6.39-libre/drivers/net/wireless/rt2x00/rt2800.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/rt2x00/rt2800.h	2011-07-11 19:51:52.000000000 -0400
@@ -51,6 +51,7 @@
  * RF3320 2.4G 1T1R(RT3350/RT3370/RT3390)
  * RF3322 2.4G 2T2R(RT3352/RT3371/RT3372/RT3391/RT3392)
  * RF3853 2.4G/5G 3T3R(RT3883/RT3563/RT3573/RT3593/RT3662)
+ * RF5370 2.4G 1T1R
  * RF5390 2.4G 1T1R
  */
 #define RF2820				0x0001
@@ -66,6 +67,7 @@
 #define RF3320				0x000b
 #define RF3322				0x000c
 #define RF3853				0x000d
+#define RF5370				0x5370
 #define RF5390				0x5390
 
 /*
@@ -2104,6 +2106,59 @@
 #define EEPROM_TXPOWER_BG_2		FIELD16(0xff00)
 
 /*
+ * EEPROM temperature compensation boundaries 802.11BG
+ * MINUS4: If the actual TSSI is below this boundary, tx power needs to be
+ *         reduced by (agc_step * -4)
+ * MINUS3: If the actual TSSI is below this boundary, tx power needs to be
+ *         reduced by (agc_step * -3)
+ */
+#define EEPROM_TSSI_BOUND_BG1		0x0037
+#define EEPROM_TSSI_BOUND_BG1_MINUS4	FIELD16(0x00ff)
+#define EEPROM_TSSI_BOUND_BG1_MINUS3	FIELD16(0xff00)
+
+/*
+ * EEPROM temperature compensation boundaries 802.11BG
+ * MINUS2: If the actual TSSI is below this boundary, tx power needs to be
+ *         reduced by (agc_step * -2)
+ * MINUS1: If the actual TSSI is below this boundary, tx power needs to be
+ *         reduced by (agc_step * -1)
+ */
+#define EEPROM_TSSI_BOUND_BG2		0x0038
+#define EEPROM_TSSI_BOUND_BG2_MINUS2	FIELD16(0x00ff)
+#define EEPROM_TSSI_BOUND_BG2_MINUS1	FIELD16(0xff00)
+
+/*
+ * EEPROM temperature compensation boundaries 802.11BG
+ * REF: Reference TSSI value, no tx power changes needed
+ * PLUS1: If the actual TSSI is above this boundary, tx power needs to be
+ *        increased by (agc_step * 1)
+ */
+#define EEPROM_TSSI_BOUND_BG3		0x0039
+#define EEPROM_TSSI_BOUND_BG3_REF	FIELD16(0x00ff)
+#define EEPROM_TSSI_BOUND_BG3_PLUS1	FIELD16(0xff00)
+
+/*
+ * EEPROM temperature compensation boundaries 802.11BG
+ * PLUS2: If the actual TSSI is above this boundary, tx power needs to be
+ *        increased by (agc_step * 2)
+ * PLUS3: If the actual TSSI is above this boundary, tx power needs to be
+ *        increased by (agc_step * 3)
+ */
+#define EEPROM_TSSI_BOUND_BG4		0x003a
+#define EEPROM_TSSI_BOUND_BG4_PLUS2	FIELD16(0x00ff)
+#define EEPROM_TSSI_BOUND_BG4_PLUS3	FIELD16(0xff00)
+
+/*
+ * EEPROM temperature compensation boundaries 802.11BG
+ * PLUS4: If the actual TSSI is above this boundary, tx power needs to be
+ *        increased by (agc_step * 4)
+ * AGC_STEP: Temperature compensation step.
+ */
+#define EEPROM_TSSI_BOUND_BG5		0x003b
+#define EEPROM_TSSI_BOUND_BG5_PLUS4	FIELD16(0x00ff)
+#define EEPROM_TSSI_BOUND_BG5_AGC_STEP	FIELD16(0xff00)
+
+/*
  * EEPROM TXPOWER 802.11A
  */
 #define EEPROM_TXPOWER_A1		0x003c
@@ -2113,6 +2168,59 @@
 #define EEPROM_TXPOWER_A_2		FIELD16(0xff00)
 
 /*
+ * EEPROM temperature compensation boundaries 802.11A
+ * MINUS4: If the actual TSSI is below this boundary, tx power needs to be
+ *         reduced by (agc_step * -4)
+ * MINUS3: If the actual TSSI is below this boundary, tx power needs to be
+ *         reduced by (agc_step * -3)
+ */
+#define EEPROM_TSSI_BOUND_A1		0x006a
+#define EEPROM_TSSI_BOUND_A1_MINUS4	FIELD16(0x00ff)
+#define EEPROM_TSSI_BOUND_A1_MINUS3	FIELD16(0xff00)
+
+/*
+ * EEPROM temperature compensation boundaries 802.11A
+ * MINUS2: If the actual TSSI is below this boundary, tx power needs to be
+ *         reduced by (agc_step * -2)
+ * MINUS1: If the actual TSSI is below this boundary, tx power needs to be
+ *         reduced by (agc_step * -1)
+ */
+#define EEPROM_TSSI_BOUND_A2		0x006b
+#define EEPROM_TSSI_BOUND_A2_MINUS2	FIELD16(0x00ff)
+#define EEPROM_TSSI_BOUND_A2_MINUS1	FIELD16(0xff00)
+
+/*
+ * EEPROM temperature compensation boundaries 802.11A
+ * REF: Reference TSSI value, no tx power changes needed
+ * PLUS1: If the actual TSSI is above this boundary, tx power needs to be
+ *        increased by (agc_step * 1)
+ */
+#define EEPROM_TSSI_BOUND_A3		0x006c
+#define EEPROM_TSSI_BOUND_A3_REF	FIELD16(0x00ff)
+#define EEPROM_TSSI_BOUND_A3_PLUS1	FIELD16(0xff00)
+
+/*
+ * EEPROM temperature compensation boundaries 802.11A
+ * PLUS2: If the actual TSSI is above this boundary, tx power needs to be
+ *        increased by (agc_step * 2)
+ * PLUS3: If the actual TSSI is above this boundary, tx power needs to be
+ *        increased by (agc_step * 3)
+ */
+#define EEPROM_TSSI_BOUND_A4		0x006d
+#define EEPROM_TSSI_BOUND_A4_PLUS2	FIELD16(0x00ff)
+#define EEPROM_TSSI_BOUND_A4_PLUS3	FIELD16(0xff00)
+
+/*
+ * EEPROM temperature compensation boundaries 802.11A
+ * PLUS4: If the actual TSSI is above this boundary, tx power needs to be
+ *        increased by (agc_step * 4)
+ * AGC_STEP: Temperature compensation step.
+ */
+#define EEPROM_TSSI_BOUND_A5		0x006e
+#define EEPROM_TSSI_BOUND_A5_PLUS4	FIELD16(0x00ff)
+#define EEPROM_TSSI_BOUND_A5_AGC_STEP	FIELD16(0xff00)
+
+/*
  * EEPROM TXPOWER by rate: tx power per tx rate for HT20 mode
  */
 #define EEPROM_TXPOWER_BYRATE		0x006f
diff -druN linux-2.6.39-libre/drivers/net/wireless/rt2x00/rt2800lib.c linux-3.0-rc7-libre/drivers/net/wireless/rt2x00/rt2800lib.c
--- linux-2.6.39-libre/drivers/net/wireless/rt2x00/rt2800lib.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/rt2x00/rt2800lib.c	2011-07-11 19:51:52.000000000 -0400
@@ -687,6 +687,9 @@
 		mcs = real_mcs;
 	}
 
+	if (aggr == 1 || ampdu == 1)
+		__set_bit(TXDONE_AMPDU, &txdesc.flags);
+
 	/*
 	 * Ralink has a retry mechanism using a global fallback
 	 * table. We setup this fallback table to try the immediate
@@ -727,34 +730,20 @@
 	struct data_queue *queue;
 	struct queue_entry *entry;
 	u32 reg;
-	u8 pid;
-	int i;
+	u8 qid;
 
-	/*
-	 * TX_STA_FIFO is a stack of X entries, hence read TX_STA_FIFO
-	 * at most X times and also stop processing once the TX_STA_FIFO_VALID
-	 * flag is not set anymore.
-	 *
-	 * The legacy drivers use X=TX_RING_SIZE but state in a comment
-	 * that the TX_STA_FIFO stack has a size of 16. We stick to our
-	 * tx ring size for now.
-	 */
-	for (i = 0; i < rt2x00dev->ops->tx->entry_num; i++) {
-		rt2800_register_read(rt2x00dev, TX_STA_FIFO, &reg);
-		if (!rt2x00_get_field32(reg, TX_STA_FIFO_VALID))
-			break;
+	while (kfifo_get(&rt2x00dev->txstatus_fifo, &reg)) {
 
-		/*
-		 * Skip this entry when it contains an invalid
-		 * queue identication number.
+		/* TX_STA_FIFO_PID_QUEUE is a 2-bit field, thus
+		 * qid is guaranteed to be one of the TX QIDs
 		 */
-		pid = rt2x00_get_field32(reg, TX_STA_FIFO_PID_QUEUE);
-		if (pid >= QID_RX)
-			continue;
-
-		queue = rt2x00queue_get_tx_queue(rt2x00dev, pid);
-		if (unlikely(!queue))
+		qid = rt2x00_get_field32(reg, TX_STA_FIFO_PID_QUEUE);
+		queue = rt2x00queue_get_tx_queue(rt2x00dev, qid);
+		if (unlikely(!queue)) {
+			WARNING(rt2x00dev, "Got TX status for an unavailable "
+					   "queue %u, dropping\n", qid);
 			continue;
+		}
 
 		/*
 		 * Inside each queue, we process each entry in a chronological
@@ -946,25 +935,49 @@
 	unsigned int ledmode =
 		rt2x00_get_field16(led->rt2x00dev->led_mcu_reg,
 				   EEPROM_FREQ_LED_MODE);
+	u32 reg;
 
-	if (led->type == LED_TYPE_RADIO) {
-		rt2800_mcu_request(led->rt2x00dev, MCU_LED, 0xff, ledmode,
-				      enabled ? 0x20 : 0);
-	} else if (led->type == LED_TYPE_ASSOC) {
-		rt2800_mcu_request(led->rt2x00dev, MCU_LED, 0xff, ledmode,
-				      enabled ? (bg_mode ? 0x60 : 0xa0) : 0x20);
-	} else if (led->type == LED_TYPE_QUALITY) {
-		/*
-		 * The brightness is divided into 6 levels (0 - 5),
-		 * The specs tell us the following levels:
-		 *	0, 1 ,3, 7, 15, 31
-		 * to determine the level in a simple way we can simply
-		 * work with bitshifting:
-		 *	(1 << level) - 1
-		 */
-		rt2800_mcu_request(led->rt2x00dev, MCU_LED_STRENGTH, 0xff,
-				      (1 << brightness / (LED_FULL / 6)) - 1,
-				      polarity);
+	/* Check for SoC (SOC devices don't support MCU requests) */
+	if (rt2x00_is_soc(led->rt2x00dev)) {
+		rt2800_register_read(led->rt2x00dev, LED_CFG, &reg);
+
+		/* Set LED Polarity */
+		rt2x00_set_field32(&reg, LED_CFG_LED_POLAR, polarity);
+
+		/* Set LED Mode */
+		if (led->type == LED_TYPE_RADIO) {
+			rt2x00_set_field32(&reg, LED_CFG_G_LED_MODE,
+					   enabled ? 3 : 0);
+		} else if (led->type == LED_TYPE_ASSOC) {
+			rt2x00_set_field32(&reg, LED_CFG_Y_LED_MODE,
+					   enabled ? 3 : 0);
+		} else if (led->type == LED_TYPE_QUALITY) {
+			rt2x00_set_field32(&reg, LED_CFG_R_LED_MODE,
+					   enabled ? 3 : 0);
+		}
+
+		rt2800_register_write(led->rt2x00dev, LED_CFG, reg);
+
+	} else {
+		if (led->type == LED_TYPE_RADIO) {
+			rt2800_mcu_request(led->rt2x00dev, MCU_LED, 0xff, ledmode,
+					      enabled ? 0x20 : 0);
+		} else if (led->type == LED_TYPE_ASSOC) {
+			rt2800_mcu_request(led->rt2x00dev, MCU_LED, 0xff, ledmode,
+					      enabled ? (bg_mode ? 0x60 : 0xa0) : 0x20);
+		} else if (led->type == LED_TYPE_QUALITY) {
+			/*
+			 * The brightness is divided into 6 levels (0 - 5),
+			 * The specs tell us the following levels:
+			 *	0, 1 ,3, 7, 15, 31
+			 * to determine the level in a simple way we can simply
+			 * work with bitshifting:
+			 *	(1 << level) - 1
+			 */
+			rt2800_mcu_request(led->rt2x00dev, MCU_LED_STRENGTH, 0xff,
+					      (1 << brightness / (LED_FULL / 6)) - 1,
+					      polarity);
+		}
 	}
 }
 
@@ -1218,6 +1231,25 @@
 		rt2800_register_read(rt2x00dev, BCN_TIME_CFG, &reg);
 		rt2x00_set_field32(&reg, BCN_TIME_CFG_TSF_SYNC, conf->sync);
 		rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg);
+
+		if (conf->sync == TSF_SYNC_AP_NONE) {
+			/*
+			 * Tune beacon queue transmit parameters for AP mode
+			 */
+			rt2800_register_read(rt2x00dev, TBTT_SYNC_CFG, &reg);
+			rt2x00_set_field32(&reg, TBTT_SYNC_CFG_BCN_CWMIN, 0);
+			rt2x00_set_field32(&reg, TBTT_SYNC_CFG_BCN_AIFSN, 1);
+			rt2x00_set_field32(&reg, TBTT_SYNC_CFG_BCN_EXP_WIN, 32);
+			rt2x00_set_field32(&reg, TBTT_SYNC_CFG_TBTT_ADJUST, 0);
+			rt2800_register_write(rt2x00dev, TBTT_SYNC_CFG, reg);
+		} else {
+			rt2800_register_read(rt2x00dev, TBTT_SYNC_CFG, &reg);
+			rt2x00_set_field32(&reg, TBTT_SYNC_CFG_BCN_CWMIN, 4);
+			rt2x00_set_field32(&reg, TBTT_SYNC_CFG_BCN_AIFSN, 2);
+			rt2x00_set_field32(&reg, TBTT_SYNC_CFG_BCN_EXP_WIN, 32);
+			rt2x00_set_field32(&reg, TBTT_SYNC_CFG_TBTT_ADJUST, 16);
+			rt2800_register_write(rt2x00dev, TBTT_SYNC_CFG, reg);
+		}
 	}
 
 	if (flags & CONFIG_UPDATE_MAC) {
@@ -1608,7 +1640,6 @@
 					 struct channel_info *info)
 {
 	u8 rfcsr;
-	u16 eeprom;
 
 	rt2800_rfcsr_write(rt2x00dev, 8, rf->rf1);
 	rt2800_rfcsr_write(rt2x00dev, 9, rf->rf3);
@@ -1638,11 +1669,10 @@
 		rt2x00_set_field8(&rfcsr, RFCSR17_CODE, rt2x00dev->freq_offset);
 	rt2800_rfcsr_write(rt2x00dev, 17, rfcsr);
 
-	rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF1, &eeprom);
 	if (rf->channel <= 14) {
 		int idx = rf->channel-1;
 
-		if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF1_BT_COEXIST)) {
+		if (test_bit(CAPABILITY_BT_COEXIST, &rt2x00dev->cap_flags)) {
 			if (rt2x00_rt_rev_gte(rt2x00dev, RT5390, REV_RT5390F)) {
 				/* r55/r59 value array of channel 1~14 */
 				static const char r55_bt_rev[] = {0x83, 0x83,
@@ -1721,7 +1751,8 @@
 	    rt2x00_rf(rt2x00dev, RF3052) ||
 	    rt2x00_rf(rt2x00dev, RF3320))
 		rt2800_config_channel_rf3xxx(rt2x00dev, conf, rf, info);
-	else if (rt2x00_rf(rt2x00dev, RF5390))
+	else if (rt2x00_rf(rt2x00dev, RF5370) ||
+		 rt2x00_rf(rt2x00dev, RF5390))
 		rt2800_config_channel_rf53xx(rt2x00dev, conf, rf, info);
 	else
 		rt2800_config_channel_rf2xxx(rt2x00dev, conf, rf, info);
@@ -1736,8 +1767,8 @@
 
 	if (rf->channel <= 14) {
 		if (!rt2x00_rt(rt2x00dev, RT5390)) {
-			if (test_bit(CONFIG_EXTERNAL_LNA_BG,
-				     &rt2x00dev->flags)) {
+			if (test_bit(CAPABILITY_EXTERNAL_LNA_BG,
+				     &rt2x00dev->cap_flags)) {
 				rt2800_bbp_write(rt2x00dev, 82, 0x62);
 				rt2800_bbp_write(rt2x00dev, 75, 0x46);
 			} else {
@@ -1748,7 +1779,7 @@
 	} else {
 		rt2800_bbp_write(rt2x00dev, 82, 0xf2);
 
-		if (test_bit(CONFIG_EXTERNAL_LNA_A, &rt2x00dev->flags))
+		if (test_bit(CAPABILITY_EXTERNAL_LNA_A, &rt2x00dev->cap_flags))
 			rt2800_bbp_write(rt2x00dev, 75, 0x46);
 		else
 			rt2800_bbp_write(rt2x00dev, 75, 0x50);
@@ -1813,17 +1844,131 @@
 	rt2800_register_read(rt2x00dev, CH_BUSY_STA_SEC, &reg);
 }
 
+static int rt2800_get_gain_calibration_delta(struct rt2x00_dev *rt2x00dev)
+{
+	u8 tssi_bounds[9];
+	u8 current_tssi;
+	u16 eeprom;
+	u8 step;
+	int i;
+
+	/*
+	 * Read TSSI boundaries for temperature compensation from
+	 * the EEPROM.
+	 *
+	 * Array idx               0    1    2    3    4    5    6    7    8
+	 * Matching Delta value   -4   -3   -2   -1    0   +1   +2   +3   +4
+	 * Example TSSI bounds  0xF0 0xD0 0xB5 0xA0 0x88 0x45 0x25 0x15 0x00
+	 */
+	if (rt2x00dev->curr_band == IEEE80211_BAND_2GHZ) {
+		rt2x00_eeprom_read(rt2x00dev, EEPROM_TSSI_BOUND_BG1, &eeprom);
+		tssi_bounds[0] = rt2x00_get_field16(eeprom,
+					EEPROM_TSSI_BOUND_BG1_MINUS4);
+		tssi_bounds[1] = rt2x00_get_field16(eeprom,
+					EEPROM_TSSI_BOUND_BG1_MINUS3);
+
+		rt2x00_eeprom_read(rt2x00dev, EEPROM_TSSI_BOUND_BG2, &eeprom);
+		tssi_bounds[2] = rt2x00_get_field16(eeprom,
+					EEPROM_TSSI_BOUND_BG2_MINUS2);
+		tssi_bounds[3] = rt2x00_get_field16(eeprom,
+					EEPROM_TSSI_BOUND_BG2_MINUS1);
+
+		rt2x00_eeprom_read(rt2x00dev, EEPROM_TSSI_BOUND_BG3, &eeprom);
+		tssi_bounds[4] = rt2x00_get_field16(eeprom,
+					EEPROM_TSSI_BOUND_BG3_REF);
+		tssi_bounds[5] = rt2x00_get_field16(eeprom,
+					EEPROM_TSSI_BOUND_BG3_PLUS1);
+
+		rt2x00_eeprom_read(rt2x00dev, EEPROM_TSSI_BOUND_BG4, &eeprom);
+		tssi_bounds[6] = rt2x00_get_field16(eeprom,
+					EEPROM_TSSI_BOUND_BG4_PLUS2);
+		tssi_bounds[7] = rt2x00_get_field16(eeprom,
+					EEPROM_TSSI_BOUND_BG4_PLUS3);
+
+		rt2x00_eeprom_read(rt2x00dev, EEPROM_TSSI_BOUND_BG5, &eeprom);
+		tssi_bounds[8] = rt2x00_get_field16(eeprom,
+					EEPROM_TSSI_BOUND_BG5_PLUS4);
+
+		step = rt2x00_get_field16(eeprom,
+					  EEPROM_TSSI_BOUND_BG5_AGC_STEP);
+	} else {
+		rt2x00_eeprom_read(rt2x00dev, EEPROM_TSSI_BOUND_A1, &eeprom);
+		tssi_bounds[0] = rt2x00_get_field16(eeprom,
+					EEPROM_TSSI_BOUND_A1_MINUS4);
+		tssi_bounds[1] = rt2x00_get_field16(eeprom,
+					EEPROM_TSSI_BOUND_A1_MINUS3);
+
+		rt2x00_eeprom_read(rt2x00dev, EEPROM_TSSI_BOUND_A2, &eeprom);
+		tssi_bounds[2] = rt2x00_get_field16(eeprom,
+					EEPROM_TSSI_BOUND_A2_MINUS2);
+		tssi_bounds[3] = rt2x00_get_field16(eeprom,
+					EEPROM_TSSI_BOUND_A2_MINUS1);
+
+		rt2x00_eeprom_read(rt2x00dev, EEPROM_TSSI_BOUND_A3, &eeprom);
+		tssi_bounds[4] = rt2x00_get_field16(eeprom,
+					EEPROM_TSSI_BOUND_A3_REF);
+		tssi_bounds[5] = rt2x00_get_field16(eeprom,
+					EEPROM_TSSI_BOUND_A3_PLUS1);
+
+		rt2x00_eeprom_read(rt2x00dev, EEPROM_TSSI_BOUND_A4, &eeprom);
+		tssi_bounds[6] = rt2x00_get_field16(eeprom,
+					EEPROM_TSSI_BOUND_A4_PLUS2);
+		tssi_bounds[7] = rt2x00_get_field16(eeprom,
+					EEPROM_TSSI_BOUND_A4_PLUS3);
+
+		rt2x00_eeprom_read(rt2x00dev, EEPROM_TSSI_BOUND_A5, &eeprom);
+		tssi_bounds[8] = rt2x00_get_field16(eeprom,
+					EEPROM_TSSI_BOUND_A5_PLUS4);
+
+		step = rt2x00_get_field16(eeprom,
+					  EEPROM_TSSI_BOUND_A5_AGC_STEP);
+	}
+
+	/*
+	 * Check if temperature compensation is supported.
+	 */
+	if (tssi_bounds[4] == 0xff)
+		return 0;
+
+	/*
+	 * Read current TSSI (BBP 49).
+	 */
+	rt2800_bbp_read(rt2x00dev, 49, &current_tssi);
+
+	/*
+	 * Compare TSSI value (BBP49) with the compensation boundaries
+	 * from the EEPROM and increase or decrease tx power.
+	 */
+	for (i = 0; i <= 3; i++) {
+		if (current_tssi > tssi_bounds[i])
+			break;
+	}
+
+	if (i == 4) {
+		for (i = 8; i >= 5; i--) {
+			if (current_tssi < tssi_bounds[i])
+				break;
+		}
+	}
+
+	return (i - 4) * step;
+}
+
 static int rt2800_get_txpower_bw_comp(struct rt2x00_dev *rt2x00dev,
 				      enum ieee80211_band band)
 {
 	u16 eeprom;
 	u8 comp_en;
 	u8 comp_type;
-	int comp_value;
+	int comp_value = 0;
 
 	rt2x00_eeprom_read(rt2x00dev, EEPROM_TXPOWER_DELTA, &eeprom);
 
-	if (eeprom == 0xffff)
+	/*
+	 * HT40 compensation not required.
+	 */
+	if (eeprom == 0xffff ||
+	    !test_bit(CONFIG_CHANNEL_HT40, &rt2x00dev->flags))
 		return 0;
 
 	if (band == IEEE80211_BAND_2GHZ) {
@@ -1853,11 +1998,9 @@
 	return comp_value;
 }
 
-static u8 rt2800_compesate_txpower(struct rt2x00_dev *rt2x00dev,
-				     int is_rate_b,
-				     enum ieee80211_band band,
-				     int power_level,
-				     u8 txpower)
+static u8 rt2800_compensate_txpower(struct rt2x00_dev *rt2x00dev, int is_rate_b,
+				   enum ieee80211_band band, int power_level,
+				   u8 txpower, int delta)
 {
 	u32 reg;
 	u16 eeprom;
@@ -1865,15 +2008,11 @@
 	u8 eirp_txpower;
 	u8 eirp_txpower_criterion;
 	u8 reg_limit;
-	int bw_comp = 0;
 
 	if (!((band == IEEE80211_BAND_5GHZ) && is_rate_b))
 		return txpower;
 
-	if (test_bit(CONFIG_CHANNEL_HT40, &rt2x00dev->flags))
-		bw_comp = rt2800_get_txpower_bw_comp(rt2x00dev, band);
-
-	if (test_bit(CONFIG_SUPPORT_POWER_LIMIT, &rt2x00dev->flags)) {
+	if (test_bit(CAPABILITY_POWER_LIMIT, &rt2x00dev->cap_flags)) {
 		/*
 		 * Check if eirp txpower exceed txpower_limit.
 		 * We use OFDM 6M as criterion and its eirp txpower
@@ -1895,18 +2034,19 @@
 						 EEPROM_EIRP_MAX_TX_POWER_5GHZ);
 
 		eirp_txpower = eirp_txpower_criterion + (txpower - criterion) +
-				       (is_rate_b ? 4 : 0) + bw_comp;
+			       (is_rate_b ? 4 : 0) + delta;
 
 		reg_limit = (eirp_txpower > power_level) ?
 					(eirp_txpower - power_level) : 0;
 	} else
 		reg_limit = 0;
 
-	return txpower + bw_comp - reg_limit;
+	return txpower + delta - reg_limit;
 }
 
 static void rt2800_config_txpower(struct rt2x00_dev *rt2x00dev,
-				  struct ieee80211_conf *conf)
+				  enum ieee80211_band band,
+				  int power_level)
 {
 	u8 txpower;
 	u16 eeprom;
@@ -1914,8 +2054,17 @@
 	u32 reg;
 	u8 r1;
 	u32 offset;
-	enum ieee80211_band band = conf->channel->band;
-	int power_level = conf->power_level;
+	int delta;
+
+	/*
+	 * Calculate HT40 compensation delta
+	 */
+	delta = rt2800_get_txpower_bw_comp(rt2x00dev, band);
+
+	/*
+	 * calculate temperature compensation delta
+	 */
+	delta += rt2800_get_gain_calibration_delta(rt2x00dev);
 
 	/*
 	 * set to normal bbp tx power control mode: +/- 0dBm
@@ -1944,8 +2093,8 @@
 		 */
 		txpower = rt2x00_get_field16(eeprom,
 					     EEPROM_TXPOWER_BYRATE_RATE0);
-		txpower = rt2800_compesate_txpower(rt2x00dev, is_rate_b, band,
-					     power_level, txpower);
+		txpower = rt2800_compensate_txpower(rt2x00dev, is_rate_b, band,
+					     power_level, txpower, delta);
 		rt2x00_set_field32(&reg, TX_PWR_CFG_RATE0, txpower);
 
 		/*
@@ -1955,8 +2104,8 @@
 		 */
 		txpower = rt2x00_get_field16(eeprom,
 					     EEPROM_TXPOWER_BYRATE_RATE1);
-		txpower = rt2800_compesate_txpower(rt2x00dev, is_rate_b, band,
-					     power_level, txpower);
+		txpower = rt2800_compensate_txpower(rt2x00dev, is_rate_b, band,
+					     power_level, txpower, delta);
 		rt2x00_set_field32(&reg, TX_PWR_CFG_RATE1, txpower);
 
 		/*
@@ -1966,8 +2115,8 @@
 		 */
 		txpower = rt2x00_get_field16(eeprom,
 					     EEPROM_TXPOWER_BYRATE_RATE2);
-		txpower = rt2800_compesate_txpower(rt2x00dev, is_rate_b, band,
-					     power_level, txpower);
+		txpower = rt2800_compensate_txpower(rt2x00dev, is_rate_b, band,
+					     power_level, txpower, delta);
 		rt2x00_set_field32(&reg, TX_PWR_CFG_RATE2, txpower);
 
 		/*
@@ -1977,8 +2126,8 @@
 		 */
 		txpower = rt2x00_get_field16(eeprom,
 					     EEPROM_TXPOWER_BYRATE_RATE3);
-		txpower = rt2800_compesate_txpower(rt2x00dev, is_rate_b, band,
-					     power_level, txpower);
+		txpower = rt2800_compensate_txpower(rt2x00dev, is_rate_b, band,
+					     power_level, txpower, delta);
 		rt2x00_set_field32(&reg, TX_PWR_CFG_RATE3, txpower);
 
 		/* read the next four txpower values */
@@ -1993,8 +2142,8 @@
 		 */
 		txpower = rt2x00_get_field16(eeprom,
 					     EEPROM_TXPOWER_BYRATE_RATE0);
-		txpower = rt2800_compesate_txpower(rt2x00dev, is_rate_b, band,
-					     power_level, txpower);
+		txpower = rt2800_compensate_txpower(rt2x00dev, is_rate_b, band,
+					     power_level, txpower, delta);
 		rt2x00_set_field32(&reg, TX_PWR_CFG_RATE4, txpower);
 
 		/*
@@ -2004,8 +2153,8 @@
 		 */
 		txpower = rt2x00_get_field16(eeprom,
 					     EEPROM_TXPOWER_BYRATE_RATE1);
-		txpower = rt2800_compesate_txpower(rt2x00dev, is_rate_b, band,
-					     power_level, txpower);
+		txpower = rt2800_compensate_txpower(rt2x00dev, is_rate_b, band,
+					     power_level, txpower, delta);
 		rt2x00_set_field32(&reg, TX_PWR_CFG_RATE5, txpower);
 
 		/*
@@ -2015,8 +2164,8 @@
 		 */
 		txpower = rt2x00_get_field16(eeprom,
 					     EEPROM_TXPOWER_BYRATE_RATE2);
-		txpower = rt2800_compesate_txpower(rt2x00dev, is_rate_b, band,
-					     power_level, txpower);
+		txpower = rt2800_compensate_txpower(rt2x00dev, is_rate_b, band,
+					     power_level, txpower, delta);
 		rt2x00_set_field32(&reg, TX_PWR_CFG_RATE6, txpower);
 
 		/*
@@ -2026,8 +2175,8 @@
 		 */
 		txpower = rt2x00_get_field16(eeprom,
 					     EEPROM_TXPOWER_BYRATE_RATE3);
-		txpower = rt2800_compesate_txpower(rt2x00dev, is_rate_b, band,
-					     power_level, txpower);
+		txpower = rt2800_compensate_txpower(rt2x00dev, is_rate_b, band,
+					     power_level, txpower, delta);
 		rt2x00_set_field32(&reg, TX_PWR_CFG_RATE7, txpower);
 
 		rt2800_register_write(rt2x00dev, offset, reg);
@@ -2037,6 +2186,13 @@
 	}
 }
 
+void rt2800_gain_calibration(struct rt2x00_dev *rt2x00dev)
+{
+	rt2800_config_txpower(rt2x00dev, rt2x00dev->curr_band,
+			      rt2x00dev->tx_power);
+}
+EXPORT_SYMBOL_GPL(rt2800_gain_calibration);
+
 static void rt2800_config_retry_limit(struct rt2x00_dev *rt2x00dev,
 				      struct rt2x00lib_conf *libconf)
 {
@@ -2090,10 +2246,12 @@
 	if (flags & IEEE80211_CONF_CHANGE_CHANNEL) {
 		rt2800_config_channel(rt2x00dev, libconf->conf,
 				      &libconf->rf, &libconf->channel);
-		rt2800_config_txpower(rt2x00dev, libconf->conf);
+		rt2800_config_txpower(rt2x00dev, libconf->conf->channel->band,
+				      libconf->conf->power_level);
 	}
 	if (flags & IEEE80211_CONF_CHANGE_POWER)
-		rt2800_config_txpower(rt2x00dev, libconf->conf);
+		rt2800_config_txpower(rt2x00dev, libconf->conf->channel->band,
+				      libconf->conf->power_level);
 	if (flags & IEEE80211_CONF_CHANGE_RETRY_LIMITS)
 		rt2800_config_retry_limit(rt2x00dev, libconf);
 	if (flags & IEEE80211_CONF_CHANGE_PS)
@@ -2254,7 +2412,7 @@
 	} else if (rt2800_is_305x_soc(rt2x00dev)) {
 		rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000400);
 		rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x00000000);
-		rt2800_register_write(rt2x00dev, TX_SW_CFG2, 0x0000001f);
+		rt2800_register_write(rt2x00dev, TX_SW_CFG2, 0x00000030);
 	} else if (rt2x00_rt(rt2x00dev, RT5390)) {
 		rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000404);
 		rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x00080606);
@@ -2758,8 +2916,7 @@
 		ant = (div_mode == 3) ? 1 : 0;
 
 		/* check if this is a Bluetooth combo card */
-		rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF1, &eeprom);
-		if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF1_BT_COEXIST)) {
+		if (test_bit(CAPABILITY_BT_COEXIST, &rt2x00dev->cap_flags)) {
 			u32 reg;
 
 			rt2800_register_read(rt2x00dev, GPIO_CTRL_CFG, &reg);
@@ -3155,8 +3312,8 @@
 		    rt2x00_rt_rev_lt(rt2x00dev, RT3071, REV_RT3071E) ||
 		    rt2x00_rt_rev_lt(rt2x00dev, RT3090, REV_RT3090E) ||
 		    rt2x00_rt_rev_lt(rt2x00dev, RT3390, REV_RT3390E)) {
-			if (!test_bit(CONFIG_EXTERNAL_LNA_BG,
-				      &rt2x00dev->flags))
+			if (!test_bit(CAPABILITY_EXTERNAL_LNA_BG,
+				      &rt2x00dev->cap_flags))
 				rt2x00_set_field8(&rfcsr, RFCSR17_R, 1);
 		}
 		rt2x00_eeprom_read(rt2x00dev, EEPROM_TXMIXER_GAIN_BG, &eeprom);
@@ -3530,6 +3687,7 @@
 	    !rt2x00_rf(rt2x00dev, RF3022) &&
 	    !rt2x00_rf(rt2x00dev, RF3052) &&
 	    !rt2x00_rf(rt2x00dev, RF3320) &&
+	    !rt2x00_rf(rt2x00dev, RF5370) &&
 	    !rt2x00_rf(rt2x00dev, RF5390)) {
 		ERROR(rt2x00dev, "Invalid RF chipset detected.\n");
 		return -ENODEV;
@@ -3568,26 +3726,30 @@
 	}
 
 	/*
-	 * Read frequency offset and RF programming sequence.
-	 */
-	rt2x00_eeprom_read(rt2x00dev, EEPROM_FREQ, &eeprom);
-	rt2x00dev->freq_offset = rt2x00_get_field16(eeprom, EEPROM_FREQ_OFFSET);
-
-	/*
-	 * Read external LNA informations.
+	 * Determine external LNA informations.
 	 */
-	rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF1, &eeprom);
-
 	if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF1_EXTERNAL_LNA_5G))
-		__set_bit(CONFIG_EXTERNAL_LNA_A, &rt2x00dev->flags);
+		__set_bit(CAPABILITY_EXTERNAL_LNA_A, &rt2x00dev->cap_flags);
 	if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF1_EXTERNAL_LNA_2G))
-		__set_bit(CONFIG_EXTERNAL_LNA_BG, &rt2x00dev->flags);
+		__set_bit(CAPABILITY_EXTERNAL_LNA_BG, &rt2x00dev->cap_flags);
 
 	/*
 	 * Detect if this device has an hardware controlled radio.
 	 */
 	if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF1_HW_RADIO))
-		__set_bit(CONFIG_SUPPORT_HW_BUTTON, &rt2x00dev->flags);
+		__set_bit(CAPABILITY_HW_BUTTON, &rt2x00dev->cap_flags);
+
+	/*
+	 * Detect if this device has Bluetooth co-existence.
+	 */
+	if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF1_BT_COEXIST))
+		__set_bit(CAPABILITY_BT_COEXIST, &rt2x00dev->cap_flags);
+
+	/*
+	 * Read frequency offset and RF programming sequence.
+	 */
+	rt2x00_eeprom_read(rt2x00dev, EEPROM_FREQ, &eeprom);
+	rt2x00dev->freq_offset = rt2x00_get_field16(eeprom, EEPROM_FREQ_OFFSET);
 
 	/*
 	 * Store led settings, for correct led behaviour.
@@ -3597,7 +3759,7 @@
 	rt2800_init_led(rt2x00dev, &rt2x00dev->led_assoc, LED_TYPE_ASSOC);
 	rt2800_init_led(rt2x00dev, &rt2x00dev->led_qual, LED_TYPE_QUALITY);
 
-	rt2x00_eeprom_read(rt2x00dev, EEPROM_FREQ, &rt2x00dev->led_mcu_reg);
+	rt2x00dev->led_mcu_reg = eeprom;
 #endif /* CONFIG_RT2X00_LIB_LEDS */
 
 	/*
@@ -3607,7 +3769,7 @@
 
 	if (rt2x00_get_field16(eeprom, EEPROM_EIRP_MAX_TX_POWER_2GHZ) <
 					EIRP_MAX_TX_POWER_LIMIT)
-		__set_bit(CONFIG_SUPPORT_POWER_LIMIT, &rt2x00dev->flags);
+		__set_bit(CAPABILITY_POWER_LIMIT, &rt2x00dev->cap_flags);
 
 	return 0;
 }
@@ -3828,6 +3990,7 @@
 		   rt2x00_rf(rt2x00dev, RF3021) ||
 		   rt2x00_rf(rt2x00dev, RF3022) ||
 		   rt2x00_rf(rt2x00dev, RF3320) ||
+		   rt2x00_rf(rt2x00dev, RF5370) ||
 		   rt2x00_rf(rt2x00dev, RF5390)) {
 		spec->num_channels = 14;
 		spec->channels = rf_vals_3x;
diff -druN linux-2.6.39-libre/drivers/net/wireless/rt2x00/rt2800lib.h linux-3.0-rc7-libre/drivers/net/wireless/rt2x00/rt2800lib.h
--- linux-2.6.39-libre/drivers/net/wireless/rt2x00/rt2800lib.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/rt2x00/rt2800lib.h	2011-07-11 19:51:52.000000000 -0400
@@ -181,6 +181,7 @@
 void rt2800_reset_tuner(struct rt2x00_dev *rt2x00dev, struct link_qual *qual);
 void rt2800_link_tuner(struct rt2x00_dev *rt2x00dev, struct link_qual *qual,
 		       const u32 count);
+void rt2800_gain_calibration(struct rt2x00_dev *rt2x00dev);
 
 int rt2800_enable_radio(struct rt2x00_dev *rt2x00dev);
 void rt2800_disable_radio(struct rt2x00_dev *rt2x00dev);
diff -druN linux-2.6.39-libre/drivers/net/wireless/rt2x00/rt2800pci.c linux-3.0-rc7-libre/drivers/net/wireless/rt2x00/rt2800pci.c
--- linux-2.6.39-libre/drivers/net/wireless/rt2x00/rt2800pci.c	2011-05-19 02:15:42.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/rt2x00/rt2800pci.c	2011-07-21 06:57:58.000000000 -0400
@@ -66,7 +66,7 @@
 		return;
 
 	for (i = 0; i < 200; i++) {
-		rt2800_register_read(rt2x00dev, H2M_MAILBOX_CID, &reg);
+		rt2x00pci_register_read(rt2x00dev, H2M_MAILBOX_CID, &reg);
 
 		if ((rt2x00_get_field32(reg, H2M_MAILBOX_CID_CMD0) == token) ||
 		    (rt2x00_get_field32(reg, H2M_MAILBOX_CID_CMD1) == token) ||
@@ -80,8 +80,8 @@
 	if (i == 200)
 		ERROR(rt2x00dev, "MCU request failed, no response from hardware\n");
 
-	rt2800_register_write(rt2x00dev, H2M_MAILBOX_STATUS, ~0);
-	rt2800_register_write(rt2x00dev, H2M_MAILBOX_CID, ~0);
+	rt2x00pci_register_write(rt2x00dev, H2M_MAILBOX_STATUS, ~0);
+	rt2x00pci_register_write(rt2x00dev, H2M_MAILBOX_CID, ~0);
 }
 
 #if defined(CONFIG_RALINK_RT288X) || defined(CONFIG_RALINK_RT305X)
@@ -105,7 +105,7 @@
 	struct rt2x00_dev *rt2x00dev = eeprom->data;
 	u32 reg;
 
-	rt2800_register_read(rt2x00dev, E2PROM_CSR, &reg);
+	rt2x00pci_register_read(rt2x00dev, E2PROM_CSR, &reg);
 
 	eeprom->reg_data_in = !!rt2x00_get_field32(reg, E2PROM_CSR_DATA_IN);
 	eeprom->reg_data_out = !!rt2x00_get_field32(reg, E2PROM_CSR_DATA_OUT);
@@ -127,7 +127,7 @@
 	rt2x00_set_field32(&reg, E2PROM_CSR_CHIP_SELECT,
 			   !!eeprom->reg_chip_select);
 
-	rt2800_register_write(rt2x00dev, E2PROM_CSR, reg);
+	rt2x00pci_register_write(rt2x00dev, E2PROM_CSR, reg);
 }
 
 static void rt2800pci_read_eeprom_pci(struct rt2x00_dev *rt2x00dev)
@@ -135,7 +135,7 @@
 	struct eeprom_93cx6 eeprom;
 	u32 reg;
 
-	rt2800_register_read(rt2x00dev, E2PROM_CSR, &reg);
+	rt2x00pci_register_read(rt2x00dev, E2PROM_CSR, &reg);
 
 	eeprom.data = rt2x00dev;
 	eeprom.register_read = rt2800pci_eepromregister_read;
@@ -195,9 +195,9 @@
 
 	switch (queue->qid) {
 	case QID_RX:
-		rt2800_register_read(rt2x00dev, MAC_SYS_CTRL, &reg);
+		rt2x00pci_register_read(rt2x00dev, MAC_SYS_CTRL, &reg);
 		rt2x00_set_field32(&reg, MAC_SYS_CTRL_ENABLE_RX, 1);
-		rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, reg);
+		rt2x00pci_register_write(rt2x00dev, MAC_SYS_CTRL, reg);
 		break;
 	case QID_BEACON:
 		/*
@@ -207,15 +207,15 @@
 		tasklet_enable(&rt2x00dev->tbtt_tasklet);
 		tasklet_enable(&rt2x00dev->pretbtt_tasklet);
 
-		rt2800_register_read(rt2x00dev, BCN_TIME_CFG, &reg);
+		rt2x00pci_register_read(rt2x00dev, BCN_TIME_CFG, &reg);
 		rt2x00_set_field32(&reg, BCN_TIME_CFG_TSF_TICKING, 1);
 		rt2x00_set_field32(&reg, BCN_TIME_CFG_TBTT_ENABLE, 1);
 		rt2x00_set_field32(&reg, BCN_TIME_CFG_BEACON_GEN, 1);
-		rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg);
+		rt2x00pci_register_write(rt2x00dev, BCN_TIME_CFG, reg);
 
-		rt2800_register_read(rt2x00dev, INT_TIMER_EN, &reg);
+		rt2x00pci_register_read(rt2x00dev, INT_TIMER_EN, &reg);
 		rt2x00_set_field32(&reg, INT_TIMER_EN_PRE_TBTT_TIMER, 1);
-		rt2800_register_write(rt2x00dev, INT_TIMER_EN, reg);
+		rt2x00pci_register_write(rt2x00dev, INT_TIMER_EN, reg);
 		break;
 	default:
 		break;
@@ -233,11 +233,13 @@
 	case QID_AC_BE:
 	case QID_AC_BK:
 		entry = rt2x00queue_get_entry(queue, Q_INDEX);
-		rt2800_register_write(rt2x00dev, TX_CTX_IDX(queue->qid), entry->entry_idx);
+		rt2x00pci_register_write(rt2x00dev, TX_CTX_IDX(queue->qid),
+					 entry->entry_idx);
 		break;
 	case QID_MGMT:
 		entry = rt2x00queue_get_entry(queue, Q_INDEX);
-		rt2800_register_write(rt2x00dev, TX_CTX_IDX(5), entry->entry_idx);
+		rt2x00pci_register_write(rt2x00dev, TX_CTX_IDX(5),
+					 entry->entry_idx);
 		break;
 	default:
 		break;
@@ -251,20 +253,20 @@
 
 	switch (queue->qid) {
 	case QID_RX:
-		rt2800_register_read(rt2x00dev, MAC_SYS_CTRL, &reg);
+		rt2x00pci_register_read(rt2x00dev, MAC_SYS_CTRL, &reg);
 		rt2x00_set_field32(&reg, MAC_SYS_CTRL_ENABLE_RX, 0);
-		rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, reg);
+		rt2x00pci_register_write(rt2x00dev, MAC_SYS_CTRL, reg);
 		break;
 	case QID_BEACON:
-		rt2800_register_read(rt2x00dev, BCN_TIME_CFG, &reg);
+		rt2x00pci_register_read(rt2x00dev, BCN_TIME_CFG, &reg);
 		rt2x00_set_field32(&reg, BCN_TIME_CFG_TSF_TICKING, 0);
 		rt2x00_set_field32(&reg, BCN_TIME_CFG_TBTT_ENABLE, 0);
 		rt2x00_set_field32(&reg, BCN_TIME_CFG_BEACON_GEN, 0);
-		rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg);
+		rt2x00pci_register_write(rt2x00dev, BCN_TIME_CFG, reg);
 
-		rt2800_register_read(rt2x00dev, INT_TIMER_EN, &reg);
+		rt2x00pci_register_read(rt2x00dev, INT_TIMER_EN, &reg);
 		rt2x00_set_field32(&reg, INT_TIMER_EN_PRE_TBTT_TIMER, 0);
-		rt2800_register_write(rt2x00dev, INT_TIMER_EN, reg);
+		rt2x00pci_register_write(rt2x00dev, INT_TIMER_EN, reg);
 
 		/*
 		 * Wait for tbtt tasklets to finish.
@@ -295,19 +297,19 @@
 	 */
 	reg = 0;
 	rt2x00_set_field32(&reg, PBF_SYS_CTRL_HOST_RAM_WRITE, 1);
-	rt2800_register_write(rt2x00dev, PBF_SYS_CTRL, reg);
+	rt2x00pci_register_write(rt2x00dev, PBF_SYS_CTRL, reg);
 
 	/*
 	 * Write firmware to device.
 	 */
-	rt2800_register_multiwrite(rt2x00dev, FIRMWARE_IMAGE_BASE,
-				   data, len);
+	rt2x00pci_register_multiwrite(rt2x00dev, FIRMWARE_IMAGE_BASE,
+				      data, len);
 
-	rt2800_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00000);
-	rt2800_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00001);
+	rt2x00pci_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00000);
+	rt2x00pci_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00001);
 
-	rt2800_register_write(rt2x00dev, H2M_BBP_AGENT, 0);
-	rt2800_register_write(rt2x00dev, H2M_MAILBOX_CSR, 0);
+	rt2x00pci_register_write(rt2x00dev, H2M_BBP_AGENT, 0);
+	rt2x00pci_register_write(rt2x00dev, H2M_MAILBOX_CSR, 0);
 
 	return 0;
 }
@@ -351,7 +353,7 @@
 		 * Set RX IDX in register to inform hardware that we have
 		 * handled this entry and it is available for reuse again.
 		 */
-		rt2800_register_write(rt2x00dev, RX_CRX_IDX,
+		rt2x00pci_register_write(rt2x00dev, RX_CRX_IDX,
 				      entry->entry_idx);
 	} else {
 		rt2x00_desc_read(entry_priv->desc, 1, &word);
@@ -369,45 +371,51 @@
 	 * Initialize registers.
 	 */
 	entry_priv = rt2x00dev->tx[0].entries[0].priv_data;
-	rt2800_register_write(rt2x00dev, TX_BASE_PTR0, entry_priv->desc_dma);
-	rt2800_register_write(rt2x00dev, TX_MAX_CNT0, rt2x00dev->tx[0].limit);
-	rt2800_register_write(rt2x00dev, TX_CTX_IDX0, 0);
-	rt2800_register_write(rt2x00dev, TX_DTX_IDX0, 0);
+	rt2x00pci_register_write(rt2x00dev, TX_BASE_PTR0, entry_priv->desc_dma);
+	rt2x00pci_register_write(rt2x00dev, TX_MAX_CNT0,
+				 rt2x00dev->tx[0].limit);
+	rt2x00pci_register_write(rt2x00dev, TX_CTX_IDX0, 0);
+	rt2x00pci_register_write(rt2x00dev, TX_DTX_IDX0, 0);
 
 	entry_priv = rt2x00dev->tx[1].entries[0].priv_data;
-	rt2800_register_write(rt2x00dev, TX_BASE_PTR1, entry_priv->desc_dma);
-	rt2800_register_write(rt2x00dev, TX_MAX_CNT1, rt2x00dev->tx[1].limit);
-	rt2800_register_write(rt2x00dev, TX_CTX_IDX1, 0);
-	rt2800_register_write(rt2x00dev, TX_DTX_IDX1, 0);
+	rt2x00pci_register_write(rt2x00dev, TX_BASE_PTR1, entry_priv->desc_dma);
+	rt2x00pci_register_write(rt2x00dev, TX_MAX_CNT1,
+				 rt2x00dev->tx[1].limit);
+	rt2x00pci_register_write(rt2x00dev, TX_CTX_IDX1, 0);
+	rt2x00pci_register_write(rt2x00dev, TX_DTX_IDX1, 0);
 
 	entry_priv = rt2x00dev->tx[2].entries[0].priv_data;
-	rt2800_register_write(rt2x00dev, TX_BASE_PTR2, entry_priv->desc_dma);
-	rt2800_register_write(rt2x00dev, TX_MAX_CNT2, rt2x00dev->tx[2].limit);
-	rt2800_register_write(rt2x00dev, TX_CTX_IDX2, 0);
-	rt2800_register_write(rt2x00dev, TX_DTX_IDX2, 0);
+	rt2x00pci_register_write(rt2x00dev, TX_BASE_PTR2, entry_priv->desc_dma);
+	rt2x00pci_register_write(rt2x00dev, TX_MAX_CNT2,
+				 rt2x00dev->tx[2].limit);
+	rt2x00pci_register_write(rt2x00dev, TX_CTX_IDX2, 0);
+	rt2x00pci_register_write(rt2x00dev, TX_DTX_IDX2, 0);
 
 	entry_priv = rt2x00dev->tx[3].entries[0].priv_data;
-	rt2800_register_write(rt2x00dev, TX_BASE_PTR3, entry_priv->desc_dma);
-	rt2800_register_write(rt2x00dev, TX_MAX_CNT3, rt2x00dev->tx[3].limit);
-	rt2800_register_write(rt2x00dev, TX_CTX_IDX3, 0);
-	rt2800_register_write(rt2x00dev, TX_DTX_IDX3, 0);
+	rt2x00pci_register_write(rt2x00dev, TX_BASE_PTR3, entry_priv->desc_dma);
+	rt2x00pci_register_write(rt2x00dev, TX_MAX_CNT3,
+				 rt2x00dev->tx[3].limit);
+	rt2x00pci_register_write(rt2x00dev, TX_CTX_IDX3, 0);
+	rt2x00pci_register_write(rt2x00dev, TX_DTX_IDX3, 0);
 
 	entry_priv = rt2x00dev->rx->entries[0].priv_data;
-	rt2800_register_write(rt2x00dev, RX_BASE_PTR, entry_priv->desc_dma);
-	rt2800_register_write(rt2x00dev, RX_MAX_CNT, rt2x00dev->rx[0].limit);
-	rt2800_register_write(rt2x00dev, RX_CRX_IDX, rt2x00dev->rx[0].limit - 1);
-	rt2800_register_write(rt2x00dev, RX_DRX_IDX, 0);
+	rt2x00pci_register_write(rt2x00dev, RX_BASE_PTR, entry_priv->desc_dma);
+	rt2x00pci_register_write(rt2x00dev, RX_MAX_CNT,
+				 rt2x00dev->rx[0].limit);
+	rt2x00pci_register_write(rt2x00dev, RX_CRX_IDX,
+				 rt2x00dev->rx[0].limit - 1);
+	rt2x00pci_register_write(rt2x00dev, RX_DRX_IDX, 0);
 
 	/*
 	 * Enable global DMA configuration
 	 */
-	rt2800_register_read(rt2x00dev, WPDMA_GLO_CFG, &reg);
+	rt2x00pci_register_read(rt2x00dev, WPDMA_GLO_CFG, &reg);
 	rt2x00_set_field32(&reg, WPDMA_GLO_CFG_ENABLE_TX_DMA, 0);
 	rt2x00_set_field32(&reg, WPDMA_GLO_CFG_ENABLE_RX_DMA, 0);
 	rt2x00_set_field32(&reg, WPDMA_GLO_CFG_TX_WRITEBACK_DONE, 1);
-	rt2800_register_write(rt2x00dev, WPDMA_GLO_CFG, reg);
+	rt2x00pci_register_write(rt2x00dev, WPDMA_GLO_CFG, reg);
 
-	rt2800_register_write(rt2x00dev, DELAY_INT_CFG, 0);
+	rt2x00pci_register_write(rt2x00dev, DELAY_INT_CFG, 0);
 
 	return 0;
 }
@@ -427,8 +435,8 @@
 	 * should clear the register to assure a clean state.
 	 */
 	if (state == STATE_RADIO_IRQ_ON) {
-		rt2800_register_read(rt2x00dev, INT_SOURCE_CSR, &reg);
-		rt2800_register_write(rt2x00dev, INT_SOURCE_CSR, reg);
+		rt2x00pci_register_read(rt2x00dev, INT_SOURCE_CSR, &reg);
+		rt2x00pci_register_write(rt2x00dev, INT_SOURCE_CSR, reg);
 
 		/*
 		 * Enable tasklets. The beacon related tasklets are
@@ -440,7 +448,7 @@
 	}
 
 	spin_lock_irqsave(&rt2x00dev->irqmask_lock, flags);
-	rt2800_register_read(rt2x00dev, INT_MASK_CSR, &reg);
+	rt2x00pci_register_read(rt2x00dev, INT_MASK_CSR, &reg);
 	rt2x00_set_field32(&reg, INT_MASK_CSR_RXDELAYINT, 0);
 	rt2x00_set_field32(&reg, INT_MASK_CSR_TXDELAYINT, 0);
 	rt2x00_set_field32(&reg, INT_MASK_CSR_RX_DONE, mask);
@@ -459,7 +467,7 @@
 	rt2x00_set_field32(&reg, INT_MASK_CSR_GPTIMER, 0);
 	rt2x00_set_field32(&reg, INT_MASK_CSR_RX_COHERENT, 0);
 	rt2x00_set_field32(&reg, INT_MASK_CSR_TX_COHERENT, 0);
-	rt2800_register_write(rt2x00dev, INT_MASK_CSR, reg);
+	rt2x00pci_register_write(rt2x00dev, INT_MASK_CSR, reg);
 	spin_unlock_irqrestore(&rt2x00dev->irqmask_lock, flags);
 
 	if (state == STATE_RADIO_IRQ_OFF) {
@@ -480,7 +488,7 @@
 	/*
 	 * Reset DMA indexes
 	 */
-	rt2800_register_read(rt2x00dev, WPDMA_RST_IDX, &reg);
+	rt2x00pci_register_read(rt2x00dev, WPDMA_RST_IDX, &reg);
 	rt2x00_set_field32(&reg, WPDMA_RST_IDX_DTX_IDX0, 1);
 	rt2x00_set_field32(&reg, WPDMA_RST_IDX_DTX_IDX1, 1);
 	rt2x00_set_field32(&reg, WPDMA_RST_IDX_DTX_IDX2, 1);
@@ -488,26 +496,26 @@
 	rt2x00_set_field32(&reg, WPDMA_RST_IDX_DTX_IDX4, 1);
 	rt2x00_set_field32(&reg, WPDMA_RST_IDX_DTX_IDX5, 1);
 	rt2x00_set_field32(&reg, WPDMA_RST_IDX_DRX_IDX0, 1);
-	rt2800_register_write(rt2x00dev, WPDMA_RST_IDX, reg);
+	rt2x00pci_register_write(rt2x00dev, WPDMA_RST_IDX, reg);
 
-	rt2800_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00000e1f);
-	rt2800_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00000e00);
+	rt2x00pci_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00000e1f);
+	rt2x00pci_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00000e00);
 
 	if (rt2x00_rt(rt2x00dev, RT5390)) {
-		rt2800_register_read(rt2x00dev, AUX_CTRL, &reg);
+		rt2x00pci_register_read(rt2x00dev, AUX_CTRL, &reg);
 		rt2x00_set_field32(&reg, AUX_CTRL_FORCE_PCIE_CLK, 1);
 		rt2x00_set_field32(&reg, AUX_CTRL_WAKE_PCIE_EN, 1);
-		rt2800_register_write(rt2x00dev, AUX_CTRL, reg);
+		rt2x00pci_register_write(rt2x00dev, AUX_CTRL, reg);
 	}
 
-	rt2800_register_write(rt2x00dev, PWR_PIN_CFG, 0x00000003);
+	rt2x00pci_register_write(rt2x00dev, PWR_PIN_CFG, 0x00000003);
 
-	rt2800_register_read(rt2x00dev, MAC_SYS_CTRL, &reg);
+	rt2x00pci_register_read(rt2x00dev, MAC_SYS_CTRL, &reg);
 	rt2x00_set_field32(&reg, MAC_SYS_CTRL_RESET_CSR, 1);
 	rt2x00_set_field32(&reg, MAC_SYS_CTRL_RESET_BBP, 1);
-	rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, reg);
+	rt2x00pci_register_write(rt2x00dev, MAC_SYS_CTRL, reg);
 
-	rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, 0x00000000);
+	rt2x00pci_register_write(rt2x00dev, MAC_SYS_CTRL, 0x00000000);
 
 	return 0;
 }
@@ -525,8 +533,8 @@
 {
 	if (rt2x00_is_soc(rt2x00dev)) {
 		rt2800_disable_radio(rt2x00dev);
-		rt2800_register_write(rt2x00dev, PWR_PIN_CFG, 0);
-		rt2800_register_write(rt2x00dev, TX_PIN_CFG, 0);
+		rt2x00pci_register_write(rt2x00dev, PWR_PIN_CFG, 0);
+		rt2x00pci_register_write(rt2x00dev, TX_PIN_CFG, 0);
 	}
 }
 
@@ -537,8 +545,10 @@
 		rt2800_mcu_request(rt2x00dev, MCU_WAKEUP, TOKEN_WAKUP, 0, 0x02);
 		rt2800pci_mcu_status(rt2x00dev, TOKEN_WAKUP);
 	} else if (state == STATE_SLEEP) {
-		rt2800_register_write(rt2x00dev, H2M_MAILBOX_STATUS, 0xffffffff);
-		rt2800_register_write(rt2x00dev, H2M_MAILBOX_CID, 0xffffffff);
+		rt2x00pci_register_write(rt2x00dev, H2M_MAILBOX_STATUS,
+					 0xffffffff);
+		rt2x00pci_register_write(rt2x00dev, H2M_MAILBOX_CID,
+					 0xffffffff);
 		rt2800_mcu_request(rt2x00dev, MCU_SLEEP, 0x01, 0xff, 0x01);
 	}
 
@@ -717,12 +727,13 @@
 	rt2800_config(rt2x00dev, &libconf, IEEE80211_CONF_CHANGE_PS);
 }
 
-static void rt2800pci_txdone(struct rt2x00_dev *rt2x00dev)
+static bool rt2800pci_txdone(struct rt2x00_dev *rt2x00dev)
 {
 	struct data_queue *queue;
 	struct queue_entry *entry;
 	u32 status;
 	u8 qid;
+	int max_tx_done = 16;
 
 	while (kfifo_get(&rt2x00dev->txstatus_fifo, &status)) {
 		qid = rt2x00_get_field32(status, TX_STA_FIFO_PID_QUEUE);
@@ -759,11 +770,16 @@
 
 		entry = rt2x00queue_get_entry(queue, Q_INDEX_DONE);
 		rt2800_txdone_entry(entry, status);
+
+		if (--max_tx_done == 0)
+			break;
 	}
+
+	return !max_tx_done;
 }
 
-static void rt2800pci_enable_interrupt(struct rt2x00_dev *rt2x00dev,
-				       struct rt2x00_field32 irq_field)
+static inline void rt2800pci_enable_interrupt(struct rt2x00_dev *rt2x00dev,
+					      struct rt2x00_field32 irq_field)
 {
 	u32 reg;
 
@@ -772,15 +788,17 @@
 	 * access needs locking.
 	 */
 	spin_lock_irq(&rt2x00dev->irqmask_lock);
-	rt2800_register_read(rt2x00dev, INT_MASK_CSR, &reg);
+	rt2x00pci_register_read(rt2x00dev, INT_MASK_CSR, &reg);
 	rt2x00_set_field32(&reg, irq_field, 1);
-	rt2800_register_write(rt2x00dev, INT_MASK_CSR, reg);
+	rt2x00pci_register_write(rt2x00dev, INT_MASK_CSR, reg);
 	spin_unlock_irq(&rt2x00dev->irqmask_lock);
 }
 
 static void rt2800pci_txstatus_tasklet(unsigned long data)
 {
-	rt2800pci_txdone((struct rt2x00_dev *)data);
+	struct rt2x00_dev *rt2x00dev = (struct rt2x00_dev *)data;
+	if (rt2800pci_txdone(rt2x00dev))
+		tasklet_schedule(&rt2x00dev->txstatus_tasklet);
 
 	/*
 	 * No need to enable the tx status interrupt here as we always
@@ -806,8 +824,10 @@
 static void rt2800pci_rxdone_tasklet(unsigned long data)
 {
 	struct rt2x00_dev *rt2x00dev = (struct rt2x00_dev *)data;
-	rt2x00pci_rxdone(rt2x00dev);
-	rt2800pci_enable_interrupt(rt2x00dev, INT_MASK_CSR_RX_DONE);
+	if (rt2x00pci_rxdone(rt2x00dev))
+		tasklet_schedule(&rt2x00dev->rxdone_tasklet);
+	else
+		rt2800pci_enable_interrupt(rt2x00dev, INT_MASK_CSR_RX_DONE);
 }
 
 static void rt2800pci_autowake_tasklet(unsigned long data)
@@ -841,7 +861,7 @@
 	 * need to lock the kfifo.
 	 */
 	for (i = 0; i < rt2x00dev->ops->tx->entry_num; i++) {
-		rt2800_register_read(rt2x00dev, TX_STA_FIFO, &status);
+		rt2x00pci_register_read(rt2x00dev, TX_STA_FIFO, &status);
 
 		if (!rt2x00_get_field32(status, TX_STA_FIFO_VALID))
 			break;
@@ -863,8 +883,8 @@
 	u32 reg, mask;
 
 	/* Read status and ACK all interrupts */
-	rt2800_register_read(rt2x00dev, INT_SOURCE_CSR, &reg);
-	rt2800_register_write(rt2x00dev, INT_SOURCE_CSR, reg);
+	rt2x00pci_register_read(rt2x00dev, INT_SOURCE_CSR, &reg);
+	rt2x00pci_register_write(rt2x00dev, INT_SOURCE_CSR, reg);
 
 	if (!reg)
 		return IRQ_NONE;
@@ -904,9 +924,9 @@
 	 * the tasklet will reenable the appropriate interrupts.
 	 */
 	spin_lock(&rt2x00dev->irqmask_lock);
-	rt2800_register_read(rt2x00dev, INT_MASK_CSR, &reg);
+	rt2x00pci_register_read(rt2x00dev, INT_MASK_CSR, &reg);
 	reg &= mask;
-	rt2800_register_write(rt2x00dev, INT_MASK_CSR, reg);
+	rt2x00pci_register_write(rt2x00dev, INT_MASK_CSR, reg);
 	spin_unlock(&rt2x00dev->irqmask_lock);
 
 	return IRQ_HANDLED;
@@ -956,28 +976,28 @@
 	 * This device has multiple filters for control frames
 	 * and has a separate filter for PS Poll frames.
 	 */
-	__set_bit(DRIVER_SUPPORT_CONTROL_FILTERS, &rt2x00dev->flags);
-	__set_bit(DRIVER_SUPPORT_CONTROL_FILTER_PSPOLL, &rt2x00dev->flags);
+	__set_bit(CAPABILITY_CONTROL_FILTERS, &rt2x00dev->cap_flags);
+	__set_bit(CAPABILITY_CONTROL_FILTER_PSPOLL, &rt2x00dev->cap_flags);
 
 	/*
 	 * This device has a pre tbtt interrupt and thus fetches
 	 * a new beacon directly prior to transmission.
 	 */
-	__set_bit(DRIVER_SUPPORT_PRE_TBTT_INTERRUPT, &rt2x00dev->flags);
+	__set_bit(CAPABILITY_PRE_TBTT_INTERRUPT, &rt2x00dev->cap_flags);
 
 	/*
 	 * This device requires firmware.
 	 */
 	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);
-	__set_bit(DRIVER_REQUIRE_TXSTATUS_FIFO, &rt2x00dev->flags);
-	__set_bit(DRIVER_REQUIRE_TASKLET_CONTEXT, &rt2x00dev->flags);
+		__set_bit(REQUIRE_FIRMWARE, &rt2x00dev->cap_flags);
+	__set_bit(REQUIRE_DMA, &rt2x00dev->cap_flags);
+	__set_bit(REQUIRE_L2PAD, &rt2x00dev->cap_flags);
+	__set_bit(REQUIRE_TXSTATUS_FIFO, &rt2x00dev->cap_flags);
+	__set_bit(REQUIRE_TASKLET_CONTEXT, &rt2x00dev->cap_flags);
 	if (!modparam_nohwcrypt)
-		__set_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags);
-	__set_bit(DRIVER_SUPPORT_LINK_TUNING, &rt2x00dev->flags);
-	__set_bit(DRIVER_REQUIRE_HT_TX_DESC, &rt2x00dev->flags);
+		__set_bit(CAPABILITY_HW_CRYPTO, &rt2x00dev->cap_flags);
+	__set_bit(CAPABILITY_LINK_TUNING, &rt2x00dev->cap_flags);
+	__set_bit(REQUIRE_HT_TX_DESC, &rt2x00dev->cap_flags);
 
 	/*
 	 * Set the rssi offset.
@@ -1008,6 +1028,7 @@
 	.ampdu_action		= rt2800_ampdu_action,
 	.flush			= rt2x00mac_flush,
 	.get_survey		= rt2800_get_survey,
+	.get_ringparam		= rt2x00mac_get_ringparam,
 };
 
 static const struct rt2800_ops rt2800pci_rt2800_ops = {
@@ -1043,9 +1064,11 @@
 	.link_stats		= rt2800_link_stats,
 	.reset_tuner		= rt2800_reset_tuner,
 	.link_tuner		= rt2800_link_tuner,
+	.gain_calibration	= rt2800_gain_calibration,
 	.start_queue		= rt2800pci_start_queue,
 	.kick_queue		= rt2800pci_kick_queue,
 	.stop_queue		= rt2800pci_stop_queue,
+	.flush_queue		= rt2x00pci_flush_queue,
 	.write_tx_desc		= rt2800pci_write_tx_desc,
 	.write_tx_data		= rt2800_write_tx_data,
 	.write_beacon		= rt2800_write_beacon,
@@ -1105,36 +1128,36 @@
  */
 #ifdef CONFIG_PCI
 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(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(0x1432, 0x7708), PCI_DEVICE_DATA(&rt2800pci_ops) },
-	{ PCI_DEVICE(0x1432, 0x7727), PCI_DEVICE_DATA(&rt2800pci_ops) },
-	{ PCI_DEVICE(0x1432, 0x7728), PCI_DEVICE_DATA(&rt2800pci_ops) },
-	{ PCI_DEVICE(0x1432, 0x7738), PCI_DEVICE_DATA(&rt2800pci_ops) },
-	{ PCI_DEVICE(0x1432, 0x7748), PCI_DEVICE_DATA(&rt2800pci_ops) },
-	{ PCI_DEVICE(0x1432, 0x7758), PCI_DEVICE_DATA(&rt2800pci_ops) },
-	{ PCI_DEVICE(0x1432, 0x7768), PCI_DEVICE_DATA(&rt2800pci_ops) },
-	{ PCI_DEVICE(0x1462, 0x891a), PCI_DEVICE_DATA(&rt2800pci_ops) },
-	{ PCI_DEVICE(0x1a3b, 0x1059), PCI_DEVICE_DATA(&rt2800pci_ops) },
+	{ PCI_DEVICE(0x1814, 0x0601) },
+	{ PCI_DEVICE(0x1814, 0x0681) },
+	{ PCI_DEVICE(0x1814, 0x0701) },
+	{ PCI_DEVICE(0x1814, 0x0781) },
+	{ PCI_DEVICE(0x1814, 0x3090) },
+	{ PCI_DEVICE(0x1814, 0x3091) },
+	{ PCI_DEVICE(0x1814, 0x3092) },
+	{ PCI_DEVICE(0x1432, 0x7708) },
+	{ PCI_DEVICE(0x1432, 0x7727) },
+	{ PCI_DEVICE(0x1432, 0x7728) },
+	{ PCI_DEVICE(0x1432, 0x7738) },
+	{ PCI_DEVICE(0x1432, 0x7748) },
+	{ PCI_DEVICE(0x1432, 0x7758) },
+	{ PCI_DEVICE(0x1432, 0x7768) },
+	{ PCI_DEVICE(0x1462, 0x891a) },
+	{ PCI_DEVICE(0x1a3b, 0x1059) },
 #ifdef CONFIG_RT2800PCI_RT33XX
-	{ PCI_DEVICE(0x1814, 0x3390), PCI_DEVICE_DATA(&rt2800pci_ops) },
+	{ PCI_DEVICE(0x1814, 0x3390) },
 #endif
 #ifdef CONFIG_RT2800PCI_RT35XX
-	{ PCI_DEVICE(0x1432, 0x7711), PCI_DEVICE_DATA(&rt2800pci_ops) },
-	{ PCI_DEVICE(0x1432, 0x7722), PCI_DEVICE_DATA(&rt2800pci_ops) },
-	{ PCI_DEVICE(0x1814, 0x3060), PCI_DEVICE_DATA(&rt2800pci_ops) },
-	{ PCI_DEVICE(0x1814, 0x3062), PCI_DEVICE_DATA(&rt2800pci_ops) },
-	{ PCI_DEVICE(0x1814, 0x3562), PCI_DEVICE_DATA(&rt2800pci_ops) },
-	{ PCI_DEVICE(0x1814, 0x3592), PCI_DEVICE_DATA(&rt2800pci_ops) },
-	{ PCI_DEVICE(0x1814, 0x3593), PCI_DEVICE_DATA(&rt2800pci_ops) },
+	{ PCI_DEVICE(0x1432, 0x7711) },
+	{ PCI_DEVICE(0x1432, 0x7722) },
+	{ PCI_DEVICE(0x1814, 0x3060) },
+	{ PCI_DEVICE(0x1814, 0x3062) },
+	{ PCI_DEVICE(0x1814, 0x3562) },
+	{ PCI_DEVICE(0x1814, 0x3592) },
+	{ PCI_DEVICE(0x1814, 0x3593) },
 #endif
 #ifdef CONFIG_RT2800PCI_RT53XX
-	{ PCI_DEVICE(0x1814, 0x5390), PCI_DEVICE_DATA(&rt2800pci_ops) },
+	{ PCI_DEVICE(0x1814, 0x5390) },
 #endif
 	{ 0, }
 };
@@ -1170,10 +1193,16 @@
 #endif /* CONFIG_RALINK_RT288X || CONFIG_RALINK_RT305X */
 
 #ifdef CONFIG_PCI
+static int rt2800pci_probe(struct pci_dev *pci_dev,
+			   const struct pci_device_id *id)
+{
+	return rt2x00pci_probe(pci_dev, &rt2800pci_ops);
+}
+
 static struct pci_driver rt2800pci_driver = {
 	.name		= KBUILD_MODNAME,
 	.id_table	= rt2800pci_device_table,
-	.probe		= rt2x00pci_probe,
+	.probe		= rt2800pci_probe,
 	.remove		= __devexit_p(rt2x00pci_remove),
 	.suspend	= rt2x00pci_suspend,
 	.resume		= rt2x00pci_resume,
diff -druN linux-2.6.39-libre/drivers/net/wireless/rt2x00/rt2800usb.c linux-3.0-rc7-libre/drivers/net/wireless/rt2x00/rt2800usb.c
--- linux-2.6.39-libre/drivers/net/wireless/rt2x00/rt2800usb.c	2011-05-19 02:15:49.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/rt2x00/rt2800usb.c	2011-07-21 06:58:02.000000000 -0400
@@ -59,16 +59,16 @@
 
 	switch (queue->qid) {
 	case QID_RX:
-		rt2800_register_read(rt2x00dev, MAC_SYS_CTRL, &reg);
+		rt2x00usb_register_read(rt2x00dev, MAC_SYS_CTRL, &reg);
 		rt2x00_set_field32(&reg, MAC_SYS_CTRL_ENABLE_RX, 1);
-		rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, reg);
+		rt2x00usb_register_write(rt2x00dev, MAC_SYS_CTRL, reg);
 		break;
 	case QID_BEACON:
-		rt2800_register_read(rt2x00dev, BCN_TIME_CFG, &reg);
+		rt2x00usb_register_read(rt2x00dev, BCN_TIME_CFG, &reg);
 		rt2x00_set_field32(&reg, BCN_TIME_CFG_TSF_TICKING, 1);
 		rt2x00_set_field32(&reg, BCN_TIME_CFG_TBTT_ENABLE, 1);
 		rt2x00_set_field32(&reg, BCN_TIME_CFG_BEACON_GEN, 1);
-		rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg);
+		rt2x00usb_register_write(rt2x00dev, BCN_TIME_CFG, reg);
 		break;
 	default:
 		break;
@@ -82,16 +82,16 @@
 
 	switch (queue->qid) {
 	case QID_RX:
-		rt2800_register_read(rt2x00dev, MAC_SYS_CTRL, &reg);
+		rt2x00usb_register_read(rt2x00dev, MAC_SYS_CTRL, &reg);
 		rt2x00_set_field32(&reg, MAC_SYS_CTRL_ENABLE_RX, 0);
-		rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, reg);
+		rt2x00usb_register_write(rt2x00dev, MAC_SYS_CTRL, reg);
 		break;
 	case QID_BEACON:
-		rt2800_register_read(rt2x00dev, BCN_TIME_CFG, &reg);
+		rt2x00usb_register_read(rt2x00dev, BCN_TIME_CFG, &reg);
 		rt2x00_set_field32(&reg, BCN_TIME_CFG_TSF_TICKING, 0);
 		rt2x00_set_field32(&reg, BCN_TIME_CFG_TBTT_ENABLE, 0);
 		rt2x00_set_field32(&reg, BCN_TIME_CFG_BEACON_GEN, 0);
-		rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg);
+		rt2x00usb_register_write(rt2x00dev, BCN_TIME_CFG, reg);
 		break;
 	default:
 		break;
@@ -99,6 +99,63 @@
 }
 
 /*
+ * test if there is an entry in any TX queue for which DMA is done
+ * but the TX status has not been returned yet
+ */
+static bool rt2800usb_txstatus_pending(struct rt2x00_dev *rt2x00dev)
+{
+	struct data_queue *queue;
+
+	tx_queue_for_each(rt2x00dev, queue) {
+		if (rt2x00queue_get_entry(queue, Q_INDEX_DMA_DONE) !=
+		    rt2x00queue_get_entry(queue, Q_INDEX_DONE))
+			return true;
+	}
+	return false;
+}
+
+static bool rt2800usb_tx_sta_fifo_read_completed(struct rt2x00_dev *rt2x00dev,
+						 int urb_status, u32 tx_status)
+{
+	if (urb_status) {
+		WARNING(rt2x00dev, "rt2x00usb_register_read_async failed: %d\n", urb_status);
+		return false;
+	}
+
+	/* try to read all TX_STA_FIFO entries before scheduling txdone_work */
+	if (rt2x00_get_field32(tx_status, TX_STA_FIFO_VALID)) {
+		if (!kfifo_put(&rt2x00dev->txstatus_fifo, &tx_status)) {
+			WARNING(rt2x00dev, "TX status FIFO overrun, "
+				"drop tx status report.\n");
+			queue_work(rt2x00dev->workqueue, &rt2x00dev->txdone_work);
+		} else
+			return true;
+	} else if (!kfifo_is_empty(&rt2x00dev->txstatus_fifo)) {
+		queue_work(rt2x00dev->workqueue, &rt2x00dev->txdone_work);
+	} else if (rt2800usb_txstatus_pending(rt2x00dev)) {
+		mod_timer(&rt2x00dev->txstatus_timer, jiffies + msecs_to_jiffies(2));
+	}
+
+	return false;
+}
+
+static void rt2800usb_tx_dma_done(struct queue_entry *entry)
+{
+	struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
+
+	rt2x00usb_register_read_async(rt2x00dev, TX_STA_FIFO,
+				      rt2800usb_tx_sta_fifo_read_completed);
+}
+
+static void rt2800usb_tx_sta_fifo_timeout(unsigned long data)
+{
+	struct rt2x00_dev *rt2x00dev = (struct rt2x00_dev *)data;
+
+	rt2x00usb_register_read_async(rt2x00dev, TX_STA_FIFO,
+				      rt2800usb_tx_sta_fifo_read_completed);
+}
+
+/*
  * Firmware functions
  */
 static char *rt2800usb_get_firmware_name(struct rt2x00_dev *rt2x00dev)
@@ -129,11 +186,11 @@
 	/*
 	 * Write firmware to device.
 	 */
-	rt2800_register_multiwrite(rt2x00dev, FIRMWARE_IMAGE_BASE,
-				   data + offset, length);
+	rt2x00usb_register_multiwrite(rt2x00dev, FIRMWARE_IMAGE_BASE,
+				      data + offset, length);
 
-	rt2800_register_write(rt2x00dev, H2M_MAILBOX_CID, ~0);
-	rt2800_register_write(rt2x00dev, H2M_MAILBOX_STATUS, ~0);
+	rt2x00usb_register_write(rt2x00dev, H2M_MAILBOX_CID, ~0);
+	rt2x00usb_register_write(rt2x00dev, H2M_MAILBOX_STATUS, ~0);
 
 	/*
 	 * Send firmware request to device to load firmware,
@@ -148,7 +205,7 @@
 	}
 
 	msleep(10);
-	rt2800_register_write(rt2x00dev, H2M_MAILBOX_CSR, 0);
+	rt2x00usb_register_write(rt2x00dev, H2M_MAILBOX_CSR, 0);
 
 	return 0;
 }
@@ -166,22 +223,22 @@
 	if (rt2800_wait_csr_ready(rt2x00dev))
 		return -EBUSY;
 
-	rt2800_register_read(rt2x00dev, PBF_SYS_CTRL, &reg);
-	rt2800_register_write(rt2x00dev, PBF_SYS_CTRL, reg & ~0x00002000);
+	rt2x00usb_register_read(rt2x00dev, PBF_SYS_CTRL, &reg);
+	rt2x00usb_register_write(rt2x00dev, PBF_SYS_CTRL, reg & ~0x00002000);
 
-	rt2800_register_write(rt2x00dev, PWR_PIN_CFG, 0x00000003);
+	rt2x00usb_register_write(rt2x00dev, PWR_PIN_CFG, 0x00000003);
 
-	rt2800_register_read(rt2x00dev, MAC_SYS_CTRL, &reg);
+	rt2x00usb_register_read(rt2x00dev, MAC_SYS_CTRL, &reg);
 	rt2x00_set_field32(&reg, MAC_SYS_CTRL_RESET_CSR, 1);
 	rt2x00_set_field32(&reg, MAC_SYS_CTRL_RESET_BBP, 1);
-	rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, reg);
+	rt2x00usb_register_write(rt2x00dev, MAC_SYS_CTRL, reg);
 
-	rt2800_register_write(rt2x00dev, USB_DMA_CFG, 0x00000000);
+	rt2x00usb_register_write(rt2x00dev, USB_DMA_CFG, 0x00000000);
 
 	rt2x00usb_vendor_request_sw(rt2x00dev, USB_DEVICE_MODE, 0,
 				    USB_MODE_RESET, REGISTER_TIMEOUT);
 
-	rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, 0x00000000);
+	rt2x00usb_register_write(rt2x00dev, MAC_SYS_CTRL, 0x00000000);
 
 	return 0;
 }
@@ -193,7 +250,7 @@
 	if (unlikely(rt2800_wait_wpdma_ready(rt2x00dev)))
 		return -EIO;
 
-	rt2800_register_read(rt2x00dev, USB_DMA_CFG, &reg);
+	rt2x00usb_register_read(rt2x00dev, USB_DMA_CFG, &reg);
 	rt2x00_set_field32(&reg, USB_DMA_CFG_PHY_CLEAR, 0);
 	rt2x00_set_field32(&reg, USB_DMA_CFG_RX_BULK_AGG_EN, 0);
 	rt2x00_set_field32(&reg, USB_DMA_CFG_RX_BULK_AGG_TIMEOUT, 128);
@@ -206,7 +263,7 @@
 			    / 1024) - 3);
 	rt2x00_set_field32(&reg, USB_DMA_CFG_RX_BULK_EN, 1);
 	rt2x00_set_field32(&reg, USB_DMA_CFG_TX_BULK_EN, 1);
-	rt2800_register_write(rt2x00dev, USB_DMA_CFG, reg);
+	rt2x00usb_register_write(rt2x00dev, USB_DMA_CFG, reg);
 
 	return rt2800_enable_radio(rt2x00dev);
 }
@@ -282,12 +339,12 @@
 	unsigned int i;
 	u32 reg;
 
-	rt2800_register_read(rt2x00dev, TXRXQ_PCNT, &reg);
+	rt2x00usb_register_read(rt2x00dev, TXRXQ_PCNT, &reg);
 	if (rt2x00_get_field32(reg, TXRXQ_PCNT_TX0Q)) {
 		WARNING(rt2x00dev, "TX HW queue 0 timed out,"
 			" invoke forced kick\n");
 
-		rt2800_register_write(rt2x00dev, PBF_CFG, 0xf40012);
+		rt2x00usb_register_write(rt2x00dev, PBF_CFG, 0xf40012);
 
 		for (i = 0; i < 10; i++) {
 			udelay(10);
@@ -295,15 +352,15 @@
 				break;
 		}
 
-		rt2800_register_write(rt2x00dev, PBF_CFG, 0xf40006);
+		rt2x00usb_register_write(rt2x00dev, PBF_CFG, 0xf40006);
 	}
 
-	rt2800_register_read(rt2x00dev, TXRXQ_PCNT, &reg);
+	rt2x00usb_register_read(rt2x00dev, TXRXQ_PCNT, &reg);
 	if (rt2x00_get_field32(reg, TXRXQ_PCNT_TX1Q)) {
 		WARNING(rt2x00dev, "TX HW queue 1 timed out,"
 			" invoke forced kick\n");
 
-		rt2800_register_write(rt2x00dev, PBF_CFG, 0xf4000a);
+		rt2x00usb_register_write(rt2x00dev, PBF_CFG, 0xf4000a);
 
 		for (i = 0; i < 10; i++) {
 			udelay(10);
@@ -311,7 +368,7 @@
 				break;
 		}
 
-		rt2800_register_write(rt2x00dev, PBF_CFG, 0xf40006);
+		rt2x00usb_register_write(rt2x00dev, PBF_CFG, 0xf40006);
 	}
 
 	rt2x00usb_watchdog(rt2x00dev);
@@ -420,13 +477,24 @@
 		while (!rt2x00queue_empty(queue)) {
 			entry = rt2x00queue_get_entry(queue, Q_INDEX_DONE);
 
-			if (test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags) ||
-			    !test_bit(ENTRY_DATA_IO_FAILED, &entry->flags))
+			if (test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags))
+				break;
+			if (test_bit(ENTRY_DATA_IO_FAILED, &entry->flags))
+				rt2x00lib_txdone_noinfo(entry, TXDONE_FAILURE);
+			else if (rt2x00queue_status_timeout(entry))
+				rt2x00lib_txdone_noinfo(entry, TXDONE_UNKNOWN);
+			else
 				break;
-
-			rt2x00lib_txdone_noinfo(entry, TXDONE_FAILURE);
 		}
 	}
+
+	/*
+	 * The hw may delay sending the packet after DMA complete
+	 * if the medium is busy, thus the TX_STA_FIFO entry is
+	 * also delayed -> use a timer to retrieve it.
+	 */
+	if (rt2800usb_txstatus_pending(rt2x00dev))
+		mod_timer(&rt2x00dev->txstatus_timer, jiffies + msecs_to_jiffies(2));
 }
 
 /*
@@ -553,19 +621,24 @@
 	 * This device has multiple filters for control frames
 	 * and has a separate filter for PS Poll frames.
 	 */
-	__set_bit(DRIVER_SUPPORT_CONTROL_FILTERS, &rt2x00dev->flags);
-	__set_bit(DRIVER_SUPPORT_CONTROL_FILTER_PSPOLL, &rt2x00dev->flags);
+	__set_bit(CAPABILITY_CONTROL_FILTERS, &rt2x00dev->cap_flags);
+	__set_bit(CAPABILITY_CONTROL_FILTER_PSPOLL, &rt2x00dev->cap_flags);
 
 	/*
 	 * This device requires firmware.
 	 */
-	__set_bit(DRIVER_REQUIRE_FIRMWARE, &rt2x00dev->flags);
-	__set_bit(DRIVER_REQUIRE_L2PAD, &rt2x00dev->flags);
+	__set_bit(REQUIRE_FIRMWARE, &rt2x00dev->cap_flags);
+	__set_bit(REQUIRE_L2PAD, &rt2x00dev->cap_flags);
 	if (!modparam_nohwcrypt)
-		__set_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags);
-	__set_bit(DRIVER_SUPPORT_LINK_TUNING, &rt2x00dev->flags);
-	__set_bit(DRIVER_SUPPORT_WATCHDOG, &rt2x00dev->flags);
-	__set_bit(DRIVER_REQUIRE_HT_TX_DESC, &rt2x00dev->flags);
+		__set_bit(CAPABILITY_HW_CRYPTO, &rt2x00dev->cap_flags);
+	__set_bit(CAPABILITY_LINK_TUNING, &rt2x00dev->cap_flags);
+	__set_bit(REQUIRE_HT_TX_DESC, &rt2x00dev->cap_flags);
+	__set_bit(REQUIRE_TXSTATUS_FIFO, &rt2x00dev->cap_flags);
+	__set_bit(REQUIRE_PS_AUTOWAKE, &rt2x00dev->cap_flags);
+
+	setup_timer(&rt2x00dev->txstatus_timer,
+		    rt2800usb_tx_sta_fifo_timeout,
+		    (unsigned long) rt2x00dev);
 
 	/*
 	 * Set the rssi offset.
@@ -602,6 +675,7 @@
 	.ampdu_action		= rt2800_ampdu_action,
 	.flush			= rt2x00mac_flush,
 	.get_survey		= rt2800_get_survey,
+	.get_ringparam		= rt2x00mac_get_ringparam,
 };
 
 static const struct rt2800_ops rt2800usb_rt2800_ops = {
@@ -630,11 +704,13 @@
 	.link_stats		= rt2800_link_stats,
 	.reset_tuner		= rt2800_reset_tuner,
 	.link_tuner		= rt2800_link_tuner,
+	.gain_calibration	= rt2800_gain_calibration,
 	.watchdog		= rt2800usb_watchdog,
 	.start_queue		= rt2800usb_start_queue,
 	.kick_queue		= rt2x00usb_kick_queue,
 	.stop_queue		= rt2800usb_stop_queue,
 	.flush_queue		= rt2x00usb_flush_queue,
+	.tx_dma_done		= rt2800usb_tx_dma_done,
 	.write_tx_desc		= rt2800usb_write_tx_desc,
 	.write_tx_data		= rt2800usb_write_tx_data,
 	.write_beacon		= rt2800_write_beacon,
@@ -695,294 +771,340 @@
  */
 static struct usb_device_id rt2800usb_device_table[] = {
 	/* 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) },
+	{ USB_DEVICE(0x07b8, 0x2870) },
+	{ USB_DEVICE(0x07b8, 0x2770) },
+	{ USB_DEVICE(0x07b8, 0x3070) },
+	{ USB_DEVICE(0x07b8, 0x3071) },
+	{ USB_DEVICE(0x07b8, 0x3072) },
+	{ USB_DEVICE(0x1482, 0x3c09) },
 	/* AirTies */
-	{ USB_DEVICE(0x1eda, 0x2310), USB_DEVICE_DATA(&rt2800usb_ops) },
+	{ USB_DEVICE(0x1eda, 0x2012) },
+	{ USB_DEVICE(0x1eda, 0x2310) },
 	/* 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, 0x2070) },
+	{ USB_DEVICE(0x8516, 0x2770) },
+	{ USB_DEVICE(0x8516, 0x2870) },
+	{ USB_DEVICE(0x8516, 0x3070) },
+	{ USB_DEVICE(0x8516, 0x3071) },
+	{ USB_DEVICE(0x8516, 0x3072) },
+	/* Alpha Networks */
+	{ USB_DEVICE(0x14b2, 0x3c06) },
+	{ USB_DEVICE(0x14b2, 0x3c07) },
+	{ USB_DEVICE(0x14b2, 0x3c09) },
+	{ USB_DEVICE(0x14b2, 0x3c12) },
+	{ USB_DEVICE(0x14b2, 0x3c23) },
+	{ USB_DEVICE(0x14b2, 0x3c25) },
+	{ USB_DEVICE(0x14b2, 0x3c27) },
+	{ USB_DEVICE(0x14b2, 0x3c28) },
+	{ USB_DEVICE(0x14b2, 0x3c2c) },
 	/* Amit */
-	{ USB_DEVICE(0x15c5, 0x0008), USB_DEVICE_DATA(&rt2800usb_ops) },
+	{ USB_DEVICE(0x15c5, 0x0008) },
 	/* Askey */
-	{ USB_DEVICE(0x1690, 0x0740), USB_DEVICE_DATA(&rt2800usb_ops) },
+	{ USB_DEVICE(0x1690, 0x0740) },
 	/* 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, 0x1784), USB_DEVICE_DATA(&rt2800usb_ops) },
-	{ USB_DEVICE(0x1761, 0x0b05), USB_DEVICE_DATA(&rt2800usb_ops) },
+	{ USB_DEVICE(0x0b05, 0x1731) },
+	{ USB_DEVICE(0x0b05, 0x1732) },
+	{ USB_DEVICE(0x0b05, 0x1742) },
+	{ USB_DEVICE(0x0b05, 0x1784) },
+	{ USB_DEVICE(0x1761, 0x0b05) },
 	/* AzureWave */
-	{ USB_DEVICE(0x13d3, 0x3247), USB_DEVICE_DATA(&rt2800usb_ops) },
-	{ USB_DEVICE(0x13d3, 0x3273), USB_DEVICE_DATA(&rt2800usb_ops) },
-	{ USB_DEVICE(0x13d3, 0x3305), USB_DEVICE_DATA(&rt2800usb_ops) },
-	{ USB_DEVICE(0x13d3, 0x3307), USB_DEVICE_DATA(&rt2800usb_ops) },
-	{ USB_DEVICE(0x13d3, 0x3321), USB_DEVICE_DATA(&rt2800usb_ops) },
+	{ USB_DEVICE(0x13d3, 0x3247) },
+	{ USB_DEVICE(0x13d3, 0x3273) },
+	{ USB_DEVICE(0x13d3, 0x3305) },
+	{ USB_DEVICE(0x13d3, 0x3307) },
+	{ USB_DEVICE(0x13d3, 0x3321) },
 	/* 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, 0x825b), USB_DEVICE_DATA(&rt2800usb_ops) },
-	{ USB_DEVICE(0x050d, 0x935a), USB_DEVICE_DATA(&rt2800usb_ops) },
-	{ USB_DEVICE(0x050d, 0x935b), USB_DEVICE_DATA(&rt2800usb_ops) },
+	{ USB_DEVICE(0x050d, 0x8053) },
+	{ USB_DEVICE(0x050d, 0x805c) },
+	{ USB_DEVICE(0x050d, 0x815c) },
+	{ USB_DEVICE(0x050d, 0x825b) },
+	{ USB_DEVICE(0x050d, 0x935a) },
+	{ USB_DEVICE(0x050d, 0x935b) },
 	/* Buffalo */
-	{ USB_DEVICE(0x0411, 0x00e8), USB_DEVICE_DATA(&rt2800usb_ops) },
-	{ USB_DEVICE(0x0411, 0x016f), 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, 0x3c09), 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) },
-	{ USB_DEVICE(0x14b2, 0x3c28), USB_DEVICE_DATA(&rt2800usb_ops) },
+	{ USB_DEVICE(0x0411, 0x00e8) },
+	{ USB_DEVICE(0x0411, 0x016f) },
+	{ USB_DEVICE(0x0411, 0x01a2) },
 	/* Corega */
-	{ 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(0x18c5, 0x0012), USB_DEVICE_DATA(&rt2800usb_ops) },
+	{ USB_DEVICE(0x07aa, 0x002f) },
+	{ USB_DEVICE(0x07aa, 0x003c) },
+	{ USB_DEVICE(0x07aa, 0x003f) },
+	{ USB_DEVICE(0x18c5, 0x0012) },
 	/* D-Link */
-	{ USB_DEVICE(0x07d1, 0x3c09), USB_DEVICE_DATA(&rt2800usb_ops) },
-	{ USB_DEVICE(0x07d1, 0x3c0a), 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, 0x3c16), USB_DEVICE_DATA(&rt2800usb_ops) },
+	{ USB_DEVICE(0x07d1, 0x3c09) },
+	{ USB_DEVICE(0x07d1, 0x3c0a) },
+	{ USB_DEVICE(0x07d1, 0x3c0d) },
+	{ USB_DEVICE(0x07d1, 0x3c0e) },
+	{ USB_DEVICE(0x07d1, 0x3c0f) },
+	{ USB_DEVICE(0x07d1, 0x3c11) },
+	{ USB_DEVICE(0x07d1, 0x3c16) },
 	/* Draytek */
-	{ USB_DEVICE(0x07fa, 0x7712), USB_DEVICE_DATA(&rt2800usb_ops) },
+	{ USB_DEVICE(0x07fa, 0x7712) },
 	/* 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) },
+	{ USB_DEVICE(0x7392, 0x7711) },
+	{ USB_DEVICE(0x7392, 0x7717) },
+	{ USB_DEVICE(0x7392, 0x7718) },
 	/* Encore */
-	{ USB_DEVICE(0x203d, 0x1480), USB_DEVICE_DATA(&rt2800usb_ops) },
-	{ USB_DEVICE(0x203d, 0x14a9), USB_DEVICE_DATA(&rt2800usb_ops) },
+	{ USB_DEVICE(0x203d, 0x1480) },
+	{ USB_DEVICE(0x203d, 0x14a9) },
 	/* EnGenius */
-	{ USB_DEVICE(0x1740, 0x9701), USB_DEVICE_DATA(&rt2800usb_ops) },
-	{ USB_DEVICE(0x1740, 0x9702), USB_DEVICE_DATA(&rt2800usb_ops) },
-	{ USB_DEVICE(0x1740, 0x9703), USB_DEVICE_DATA(&rt2800usb_ops) },
-	{ USB_DEVICE(0x1740, 0x9705), USB_DEVICE_DATA(&rt2800usb_ops) },
-	{ USB_DEVICE(0x1740, 0x9706), USB_DEVICE_DATA(&rt2800usb_ops) },
-	{ USB_DEVICE(0x1740, 0x9707), USB_DEVICE_DATA(&rt2800usb_ops) },
-	{ USB_DEVICE(0x1740, 0x9708), USB_DEVICE_DATA(&rt2800usb_ops) },
-	{ USB_DEVICE(0x1740, 0x9709), USB_DEVICE_DATA(&rt2800usb_ops) },
+	{ USB_DEVICE(0x1740, 0x9701) },
+	{ USB_DEVICE(0x1740, 0x9702) },
+	{ USB_DEVICE(0x1740, 0x9703) },
+	{ USB_DEVICE(0x1740, 0x9705) },
+	{ USB_DEVICE(0x1740, 0x9706) },
+	{ USB_DEVICE(0x1740, 0x9707) },
+	{ USB_DEVICE(0x1740, 0x9708) },
+	{ USB_DEVICE(0x1740, 0x9709) },
+	/* Gemtek */
+	{ USB_DEVICE(0x15a9, 0x0012) },
 	/* Gigabyte */
-	{ USB_DEVICE(0x1044, 0x800b), USB_DEVICE_DATA(&rt2800usb_ops) },
-	{ USB_DEVICE(0x1044, 0x800d), USB_DEVICE_DATA(&rt2800usb_ops) },
+	{ USB_DEVICE(0x1044, 0x800b) },
+	{ USB_DEVICE(0x1044, 0x800d) },
 	/* 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) },
-	{ USB_DEVICE(0x0e66, 0x0013), USB_DEVICE_DATA(&rt2800usb_ops) },
-	{ USB_DEVICE(0x0e66, 0x0017), USB_DEVICE_DATA(&rt2800usb_ops) },
-	{ USB_DEVICE(0x0e66, 0x0018), USB_DEVICE_DATA(&rt2800usb_ops) },
+	{ USB_DEVICE(0x0e66, 0x0001) },
+	{ USB_DEVICE(0x0e66, 0x0003) },
+	{ USB_DEVICE(0x0e66, 0x0009) },
+	{ USB_DEVICE(0x0e66, 0x000b) },
+	{ USB_DEVICE(0x0e66, 0x0013) },
+	{ USB_DEVICE(0x0e66, 0x0017) },
+	{ USB_DEVICE(0x0e66, 0x0018) },
 	/* I-O DATA */
-	{ 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) },
+	{ USB_DEVICE(0x04bb, 0x0945) },
+	{ USB_DEVICE(0x04bb, 0x0947) },
+	{ USB_DEVICE(0x04bb, 0x0948) },
 	/* Linksys */
-	{ USB_DEVICE(0x1737, 0x0070), USB_DEVICE_DATA(&rt2800usb_ops) },
-	{ USB_DEVICE(0x1737, 0x0071), USB_DEVICE_DATA(&rt2800usb_ops) },
+	{ USB_DEVICE(0x13b1, 0x0031) },
+	{ USB_DEVICE(0x1737, 0x0070) },
+	{ USB_DEVICE(0x1737, 0x0071) },
 	/* 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) },
-	{ USB_DEVICE(0x0789, 0x0166), USB_DEVICE_DATA(&rt2800usb_ops) },
+	{ USB_DEVICE(0x0789, 0x0162) },
+	{ USB_DEVICE(0x0789, 0x0163) },
+	{ USB_DEVICE(0x0789, 0x0164) },
+	{ USB_DEVICE(0x0789, 0x0166) },
 	/* Motorola */
-	{ USB_DEVICE(0x100d, 0x9031), USB_DEVICE_DATA(&rt2800usb_ops) },
+	{ USB_DEVICE(0x100d, 0x9031) },
 	/* 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, 0x3871), USB_DEVICE_DATA(&rt2800usb_ops) },
-	{ USB_DEVICE(0x0db0, 0x6899), USB_DEVICE_DATA(&rt2800usb_ops) },
-	{ USB_DEVICE(0x0db0, 0x821a), USB_DEVICE_DATA(&rt2800usb_ops) },
-	{ USB_DEVICE(0x0db0, 0x822a), USB_DEVICE_DATA(&rt2800usb_ops) },
-	{ USB_DEVICE(0x0db0, 0x822b), USB_DEVICE_DATA(&rt2800usb_ops) },
-	{ USB_DEVICE(0x0db0, 0x822c), 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, 0x871b), USB_DEVICE_DATA(&rt2800usb_ops) },
-	{ USB_DEVICE(0x0db0, 0x871c), USB_DEVICE_DATA(&rt2800usb_ops) },
-	{ USB_DEVICE(0x0db0, 0x899a), USB_DEVICE_DATA(&rt2800usb_ops) },
+	{ USB_DEVICE(0x0db0, 0x3820) },
+	{ USB_DEVICE(0x0db0, 0x3821) },
+	{ USB_DEVICE(0x0db0, 0x3822) },
+	{ USB_DEVICE(0x0db0, 0x3870) },
+	{ USB_DEVICE(0x0db0, 0x3871) },
+	{ USB_DEVICE(0x0db0, 0x6899) },
+	{ USB_DEVICE(0x0db0, 0x821a) },
+	{ USB_DEVICE(0x0db0, 0x822a) },
+	{ USB_DEVICE(0x0db0, 0x822b) },
+	{ USB_DEVICE(0x0db0, 0x822c) },
+	{ USB_DEVICE(0x0db0, 0x870a) },
+	{ USB_DEVICE(0x0db0, 0x871a) },
+	{ USB_DEVICE(0x0db0, 0x871b) },
+	{ USB_DEVICE(0x0db0, 0x871c) },
+	{ USB_DEVICE(0x0db0, 0x899a) },
 	/* Para */
-	{ USB_DEVICE(0x20b8, 0x8888), USB_DEVICE_DATA(&rt2800usb_ops) },
+	{ USB_DEVICE(0x20b8, 0x8888) },
 	/* Pegatron */
-	{ USB_DEVICE(0x1d4d, 0x000c), USB_DEVICE_DATA(&rt2800usb_ops) },
-	{ USB_DEVICE(0x1d4d, 0x000e), USB_DEVICE_DATA(&rt2800usb_ops) },
-	{ USB_DEVICE(0x1d4d, 0x0011), USB_DEVICE_DATA(&rt2800usb_ops) },
+	{ USB_DEVICE(0x1d4d, 0x000c) },
+	{ USB_DEVICE(0x1d4d, 0x000e) },
+	{ USB_DEVICE(0x1d4d, 0x0011) },
 	/* Philips */
-	{ USB_DEVICE(0x0471, 0x200f), USB_DEVICE_DATA(&rt2800usb_ops) },
+	{ USB_DEVICE(0x0471, 0x200f) },
 	/* Planex */
-	{ USB_DEVICE(0x2019, 0xab25), USB_DEVICE_DATA(&rt2800usb_ops) },
-	{ USB_DEVICE(0x2019, 0xed06), USB_DEVICE_DATA(&rt2800usb_ops) },
+	{ USB_DEVICE(0x2019, 0xab25) },
+	{ USB_DEVICE(0x2019, 0xed06) },
 	/* Quanta */
-	{ USB_DEVICE(0x1a32, 0x0304), USB_DEVICE_DATA(&rt2800usb_ops) },
+	{ USB_DEVICE(0x1a32, 0x0304) },
 	/* 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, 0x2070) },
+	{ USB_DEVICE(0x148f, 0x2770) },
+	{ USB_DEVICE(0x148f, 0x2870) },
+	{ USB_DEVICE(0x148f, 0x3070) },
+	{ USB_DEVICE(0x148f, 0x3071) },
+	{ USB_DEVICE(0x148f, 0x3072) },
 	/* Samsung */
-	{ USB_DEVICE(0x04e8, 0x2018), USB_DEVICE_DATA(&rt2800usb_ops) },
+	{ USB_DEVICE(0x04e8, 0x2018) },
 	/* Siemens */
-	{ USB_DEVICE(0x129b, 0x1828), USB_DEVICE_DATA(&rt2800usb_ops) },
+	{ USB_DEVICE(0x129b, 0x1828) },
 	/* 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, 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, 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, 0x0017) },
+	{ USB_DEVICE(0x0df6, 0x002b) },
+	{ USB_DEVICE(0x0df6, 0x002c) },
+	{ USB_DEVICE(0x0df6, 0x002d) },
+	{ USB_DEVICE(0x0df6, 0x0039) },
+	{ USB_DEVICE(0x0df6, 0x003b) },
+	{ USB_DEVICE(0x0df6, 0x003d) },
+	{ USB_DEVICE(0x0df6, 0x003e) },
+	{ USB_DEVICE(0x0df6, 0x003f) },
+	{ USB_DEVICE(0x0df6, 0x0040) },
+	{ USB_DEVICE(0x0df6, 0x0042) },
+	{ USB_DEVICE(0x0df6, 0x0047) },
+	{ USB_DEVICE(0x0df6, 0x0048) },
+	{ USB_DEVICE(0x0df6, 0x0051) },
+	{ USB_DEVICE(0x0df6, 0x005f) },
 	/* 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, 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, 0xa703), USB_DEVICE_DATA(&rt2800usb_ops) },
-	{ USB_DEVICE(0x083a, 0xb522), USB_DEVICE_DATA(&rt2800usb_ops) },
+	{ USB_DEVICE(0x083a, 0x6618) },
+	{ USB_DEVICE(0x083a, 0x7511) },
+	{ USB_DEVICE(0x083a, 0x7512) },
+	{ USB_DEVICE(0x083a, 0x7522) },
+	{ USB_DEVICE(0x083a, 0x8522) },
+	{ USB_DEVICE(0x083a, 0xa618) },
+	{ USB_DEVICE(0x083a, 0xa701) },
+	{ USB_DEVICE(0x083a, 0xa702) },
+	{ USB_DEVICE(0x083a, 0xa703) },
+	{ USB_DEVICE(0x083a, 0xb522) },
 	/* Sparklan */
-	{ USB_DEVICE(0x15a9, 0x0006), USB_DEVICE_DATA(&rt2800usb_ops) },
+	{ USB_DEVICE(0x15a9, 0x0006) },
 	/* Sweex */
-	{ USB_DEVICE(0x177f, 0x0302), USB_DEVICE_DATA(&rt2800usb_ops) },
-	/* U-Media*/
-	{ USB_DEVICE(0x157e, 0x300e), USB_DEVICE_DATA(&rt2800usb_ops) },
+	{ USB_DEVICE(0x177f, 0x0302) },
+	/* U-Media */
+	{ USB_DEVICE(0x157e, 0x300e) },
+	{ USB_DEVICE(0x157e, 0x3013) },
 	/* ZCOM */
-	{ USB_DEVICE(0x0cde, 0x0022), USB_DEVICE_DATA(&rt2800usb_ops) },
-	{ USB_DEVICE(0x0cde, 0x0025), USB_DEVICE_DATA(&rt2800usb_ops) },
+	{ USB_DEVICE(0x0cde, 0x0022) },
+	{ USB_DEVICE(0x0cde, 0x0025) },
 	/* 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, 0x5257), USB_DEVICE_DATA(&rt2800usb_ops) },
+	{ USB_DEVICE(0x5a57, 0x0280) },
+	{ USB_DEVICE(0x5a57, 0x0282) },
+	{ USB_DEVICE(0x5a57, 0x0283) },
+	{ USB_DEVICE(0x5a57, 0x5257) },
 	/* Zyxel */
-	{ USB_DEVICE(0x0586, 0x3416), USB_DEVICE_DATA(&rt2800usb_ops) },
+	{ USB_DEVICE(0x0586, 0x3416) },
+	{ USB_DEVICE(0x0586, 0x3418) },
+	{ USB_DEVICE(0x0586, 0x341e) },
+	{ USB_DEVICE(0x0586, 0x343e) },
 #ifdef CONFIG_RT2800USB_RT33XX
 	/* Ralink */
-	{ USB_DEVICE(0x148f, 0x3370), USB_DEVICE_DATA(&rt2800usb_ops) },
-	{ USB_DEVICE(0x148f, 0x8070), USB_DEVICE_DATA(&rt2800usb_ops) },
+	{ USB_DEVICE(0x148f, 0x3370) },
+	{ USB_DEVICE(0x148f, 0x8070) },
 	/* Sitecom */
-	{ USB_DEVICE(0x0df6, 0x0050), USB_DEVICE_DATA(&rt2800usb_ops) },
+	{ USB_DEVICE(0x0df6, 0x0050) },
 #endif
 #ifdef CONFIG_RT2800USB_RT35XX
 	/* Allwin */
-	{ USB_DEVICE(0x8516, 0x3572), USB_DEVICE_DATA(&rt2800usb_ops) },
+	{ USB_DEVICE(0x8516, 0x3572) },
 	/* Askey */
-	{ USB_DEVICE(0x1690, 0x0744), USB_DEVICE_DATA(&rt2800usb_ops) },
+	{ USB_DEVICE(0x1690, 0x0744) },
 	/* Cisco */
-	{ USB_DEVICE(0x167b, 0x4001), USB_DEVICE_DATA(&rt2800usb_ops) },
+	{ USB_DEVICE(0x167b, 0x4001) },
 	/* EnGenius */
-	{ USB_DEVICE(0x1740, 0x9801), USB_DEVICE_DATA(&rt2800usb_ops) },
+	{ USB_DEVICE(0x1740, 0x9801) },
 	/* I-O DATA */
-	{ USB_DEVICE(0x04bb, 0x0944), USB_DEVICE_DATA(&rt2800usb_ops) },
+	{ USB_DEVICE(0x04bb, 0x0944) },
+	/* Linksys */
+	{ USB_DEVICE(0x13b1, 0x002f) },
+	{ USB_DEVICE(0x1737, 0x0079) },
 	/* Ralink */
-	{ USB_DEVICE(0x148f, 0x3572), USB_DEVICE_DATA(&rt2800usb_ops) },
+	{ USB_DEVICE(0x148f, 0x3572) },
 	/* Sitecom */
-	{ USB_DEVICE(0x0df6, 0x0041), USB_DEVICE_DATA(&rt2800usb_ops) },
+	{ USB_DEVICE(0x0df6, 0x0041) },
 	/* Toshiba */
-	{ USB_DEVICE(0x0930, 0x0a07), USB_DEVICE_DATA(&rt2800usb_ops) },
+	{ USB_DEVICE(0x0930, 0x0a07) },
 	/* Zinwell */
-	{ USB_DEVICE(0x5a57, 0x0284), USB_DEVICE_DATA(&rt2800usb_ops) },
+	{ USB_DEVICE(0x5a57, 0x0284) },
+#endif
+#ifdef CONFIG_RT2800USB_RT53XX
+	/* Azurewave */
+	{ USB_DEVICE(0x13d3, 0x3329) },
+	{ USB_DEVICE(0x13d3, 0x3365) },
+	/* Ralink */
+	{ USB_DEVICE(0x148f, 0x5370) },
+	{ USB_DEVICE(0x148f, 0x5372) },
 #endif
 #ifdef CONFIG_RT2800USB_UNKNOWN
 	/*
 	 * Unclear what kind of devices these are (they aren't supported by the
 	 * vendor linux driver).
 	 */
+	/* Abocom */
+	{ USB_DEVICE(0x07b8, 0x3073) },
+	{ USB_DEVICE(0x07b8, 0x3074) },
+	/* Alpha Networks */
+	{ USB_DEVICE(0x14b2, 0x3c08) },
+	{ USB_DEVICE(0x14b2, 0x3c11) },
 	/* Amigo */
-	{ USB_DEVICE(0x0e0b, 0x9031), USB_DEVICE_DATA(&rt2800usb_ops) },
-	{ USB_DEVICE(0x0e0b, 0x9041), USB_DEVICE_DATA(&rt2800usb_ops) },
+	{ USB_DEVICE(0x0e0b, 0x9031) },
+	{ USB_DEVICE(0x0e0b, 0x9041) },
 	/* ASUS */
-	{ USB_DEVICE(0x0b05, 0x1760), USB_DEVICE_DATA(&rt2800usb_ops) },
-	{ USB_DEVICE(0x0b05, 0x1761), USB_DEVICE_DATA(&rt2800usb_ops) },
-	{ USB_DEVICE(0x0b05, 0x1790), USB_DEVICE_DATA(&rt2800usb_ops) },
+	{ USB_DEVICE(0x0b05, 0x166a) },
+	{ USB_DEVICE(0x0b05, 0x1760) },
+	{ USB_DEVICE(0x0b05, 0x1761) },
+	{ USB_DEVICE(0x0b05, 0x1790) },
+	{ USB_DEVICE(0x0b05, 0x179d) },
 	/* AzureWave */
-	{ USB_DEVICE(0x13d3, 0x3262), USB_DEVICE_DATA(&rt2800usb_ops) },
-	{ USB_DEVICE(0x13d3, 0x3284), USB_DEVICE_DATA(&rt2800usb_ops) },
-	{ USB_DEVICE(0x13d3, 0x3322), USB_DEVICE_DATA(&rt2800usb_ops) },
+	{ USB_DEVICE(0x13d3, 0x3262) },
+	{ USB_DEVICE(0x13d3, 0x3284) },
+	{ USB_DEVICE(0x13d3, 0x3322) },
 	/* Belkin */
-	{ USB_DEVICE(0x050d, 0x825a), USB_DEVICE_DATA(&rt2800usb_ops) },
+	{ USB_DEVICE(0x050d, 0x1003) },
+	{ USB_DEVICE(0x050d, 0x825a) },
 	/* 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) },
+	{ USB_DEVICE(0x0411, 0x012e) },
+	{ USB_DEVICE(0x0411, 0x0148) },
+	{ USB_DEVICE(0x0411, 0x0150) },
+	{ USB_DEVICE(0x0411, 0x015d) },
 	/* 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) },
+	{ USB_DEVICE(0x07aa, 0x0041) },
+	{ USB_DEVICE(0x07aa, 0x0042) },
+	{ USB_DEVICE(0x18c5, 0x0008) },
 	/* 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, 0x3c17), USB_DEVICE_DATA(&rt2800usb_ops) },
+	{ USB_DEVICE(0x07d1, 0x3c0b) },
+	{ USB_DEVICE(0x07d1, 0x3c13) },
+	{ USB_DEVICE(0x07d1, 0x3c15) },
+	{ USB_DEVICE(0x07d1, 0x3c17) },
+	{ USB_DEVICE(0x2001, 0x3c17) },
 	/* Edimax */
-	{ USB_DEVICE(0x7392, 0x4085), USB_DEVICE_DATA(&rt2800usb_ops) },
+	{ USB_DEVICE(0x7392, 0x4085) },
+	{ USB_DEVICE(0x7392, 0x7722) },
 	/* Encore */
-	{ USB_DEVICE(0x203d, 0x14a1), USB_DEVICE_DATA(&rt2800usb_ops) },
+	{ USB_DEVICE(0x203d, 0x14a1) },
 	/* Gemtek */
-	{ USB_DEVICE(0x15a9, 0x0010), USB_DEVICE_DATA(&rt2800usb_ops) },
+	{ USB_DEVICE(0x15a9, 0x0010) },
 	/* Gigabyte */
-	{ USB_DEVICE(0x1044, 0x800c), USB_DEVICE_DATA(&rt2800usb_ops) },
+	{ USB_DEVICE(0x1044, 0x800c) },
+	/* Huawei */
+	{ USB_DEVICE(0x148f, 0xf101) },
+	/* I-O DATA */
+	{ USB_DEVICE(0x04bb, 0x094b) },
 	/* LevelOne */
-	{ USB_DEVICE(0x1740, 0x0605), USB_DEVICE_DATA(&rt2800usb_ops) },
-	{ USB_DEVICE(0x1740, 0x0615), USB_DEVICE_DATA(&rt2800usb_ops) },
+	{ USB_DEVICE(0x1740, 0x0605) },
+	{ USB_DEVICE(0x1740, 0x0615) },
 	/* Linksys */
-	{ 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) },
+	{ USB_DEVICE(0x1737, 0x0077) },
+	{ USB_DEVICE(0x1737, 0x0078) },
+	/* Logitec */
+	{ USB_DEVICE(0x0789, 0x0168) },
+	{ USB_DEVICE(0x0789, 0x0169) },
 	/* Motorola */
-	{ USB_DEVICE(0x100d, 0x9032), USB_DEVICE_DATA(&rt2800usb_ops) },
+	{ USB_DEVICE(0x100d, 0x9032) },
 	/* Ovislink */
-	{ USB_DEVICE(0x1b75, 0x3071), USB_DEVICE_DATA(&rt2800usb_ops) },
-	{ USB_DEVICE(0x1b75, 0x3072), USB_DEVICE_DATA(&rt2800usb_ops) },
+	{ USB_DEVICE(0x1b75, 0x3071) },
+	{ USB_DEVICE(0x1b75, 0x3072) },
 	/* Pegatron */
-	{ USB_DEVICE(0x05a6, 0x0101), USB_DEVICE_DATA(&rt2800usb_ops) },
-	{ USB_DEVICE(0x1d4d, 0x0002), USB_DEVICE_DATA(&rt2800usb_ops) },
-	{ USB_DEVICE(0x1d4d, 0x0010), USB_DEVICE_DATA(&rt2800usb_ops) },
+	{ USB_DEVICE(0x05a6, 0x0101) },
+	{ USB_DEVICE(0x1d4d, 0x0002) },
+	{ USB_DEVICE(0x1d4d, 0x0010) },
 	/* Planex */
-	{ USB_DEVICE(0x2019, 0x5201), USB_DEVICE_DATA(&rt2800usb_ops) },
-	{ USB_DEVICE(0x2019, 0xab24), USB_DEVICE_DATA(&rt2800usb_ops) },
+	{ USB_DEVICE(0x2019, 0x5201) },
+	{ USB_DEVICE(0x2019, 0xab24) },
 	/* Qcom */
-	{ USB_DEVICE(0x18e8, 0x6259), USB_DEVICE_DATA(&rt2800usb_ops) },
+	{ USB_DEVICE(0x18e8, 0x6259) },
+	/* RadioShack */
+	{ USB_DEVICE(0x08b9, 0x1197) },
+	/* Sitecom */
+	{ USB_DEVICE(0x0df6, 0x003c) },
+	{ USB_DEVICE(0x0df6, 0x004a) },
+	{ USB_DEVICE(0x0df6, 0x004d) },
+	{ USB_DEVICE(0x0df6, 0x0053) },
+	{ USB_DEVICE(0x0df6, 0x0060) },
+	{ USB_DEVICE(0x0df6, 0x0062) },
 	/* SMC */
-	{ USB_DEVICE(0x083a, 0xa512), USB_DEVICE_DATA(&rt2800usb_ops) },
-	{ USB_DEVICE(0x083a, 0xc522), USB_DEVICE_DATA(&rt2800usb_ops) },
-	{ USB_DEVICE(0x083a, 0xd522), USB_DEVICE_DATA(&rt2800usb_ops) },
-	{ USB_DEVICE(0x083a, 0xf511), USB_DEVICE_DATA(&rt2800usb_ops) },
+	{ USB_DEVICE(0x083a, 0xa512) },
+	{ USB_DEVICE(0x083a, 0xc522) },
+	{ USB_DEVICE(0x083a, 0xd522) },
+	{ USB_DEVICE(0x083a, 0xf511) },
 	/* Sweex */
-	{ USB_DEVICE(0x177f, 0x0153), USB_DEVICE_DATA(&rt2800usb_ops) },
-	{ USB_DEVICE(0x177f, 0x0313), USB_DEVICE_DATA(&rt2800usb_ops) },
+	{ USB_DEVICE(0x177f, 0x0153) },
+	{ USB_DEVICE(0x177f, 0x0313) },
 	/* Zyxel */
-	{ USB_DEVICE(0x0586, 0x341a), USB_DEVICE_DATA(&rt2800usb_ops) },
+	{ USB_DEVICE(0x0586, 0x341a) },
 #endif
 	{ 0, }
 };
@@ -995,10 +1117,16 @@
 /*(DEBLOBBED)*/
 MODULE_LICENSE("GPL");
 
+static int rt2800usb_probe(struct usb_interface *usb_intf,
+			   const struct usb_device_id *id)
+{
+	return rt2x00usb_probe(usb_intf, &rt2800usb_ops);
+}
+
 static struct usb_driver rt2800usb_driver = {
 	.name		= KBUILD_MODNAME,
 	.id_table	= rt2800usb_device_table,
-	.probe		= rt2x00usb_probe,
+	.probe		= rt2800usb_probe,
 	.disconnect	= rt2x00usb_disconnect,
 	.suspend	= rt2x00usb_suspend,
 	.resume		= rt2x00usb_resume,
diff -druN linux-2.6.39-libre/drivers/net/wireless/rt2x00/rt2x00config.c linux-3.0-rc7-libre/drivers/net/wireless/rt2x00/rt2x00config.c
--- linux-2.6.39-libre/drivers/net/wireless/rt2x00/rt2x00config.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/rt2x00/rt2x00config.c	2011-07-11 19:51:52.000000000 -0400
@@ -100,6 +100,10 @@
 	erp.basic_rates = bss_conf->basic_rates;
 	erp.beacon_int = bss_conf->beacon_int;
 
+	/* Update the AID, this is needed for dynamic PS support */
+	rt2x00dev->aid = bss_conf->assoc ? bss_conf->aid : 0;
+	rt2x00dev->last_beacon = bss_conf->timestamp;
+
 	/* Update global beacon interval time, this is needed for PS support */
 	rt2x00dev->beacon_int = bss_conf->beacon_int;
 
@@ -109,15 +113,6 @@
 	rt2x00dev->ops->lib->config_erp(rt2x00dev, &erp, changed);
 }
 
-static inline
-enum antenna rt2x00lib_config_antenna_check(enum antenna current_ant,
-					    enum antenna default_ant)
-{
-	if (current_ant != ANTENNA_SW_DIVERSITY)
-		return current_ant;
-	return (default_ant != ANTENNA_SW_DIVERSITY) ? default_ant : ANTENNA_B;
-}
-
 void rt2x00lib_config_antenna(struct rt2x00_dev *rt2x00dev,
 			      struct antenna_setup config)
 {
@@ -126,19 +121,35 @@
 	struct antenna_setup *active = &rt2x00dev->link.ant.active;
 
 	/*
-	 * Failsafe: Make sure we are not sending the
-	 * ANTENNA_SW_DIVERSITY state to the driver.
-	 * If that happens, fallback to hardware defaults,
-	 * or our own default.
+	 * When the caller tries to send the SW diversity,
+	 * we must update the ANTENNA_RX_DIVERSITY flag to
+	 * enable the antenna diversity in the link tuner.
+	 *
+	 * Secondly, we must guarentee we never send the
+	 * software antenna diversity command to the driver.
 	 */
-	if (!(ant->flags & ANTENNA_RX_DIVERSITY))
-		config.rx = rt2x00lib_config_antenna_check(config.rx, def->rx);
-	else if (config.rx == ANTENNA_SW_DIVERSITY)
+	if (!(ant->flags & ANTENNA_RX_DIVERSITY)) {
+		if (config.rx == ANTENNA_SW_DIVERSITY) {
+			ant->flags |= ANTENNA_RX_DIVERSITY;
+
+			if (def->rx == ANTENNA_SW_DIVERSITY)
+				config.rx = ANTENNA_B;
+			else
+				config.rx = def->rx;
+		}
+	} else if (config.rx == ANTENNA_SW_DIVERSITY)
 		config.rx = active->rx;
 
-	if (!(ant->flags & ANTENNA_TX_DIVERSITY))
-		config.tx = rt2x00lib_config_antenna_check(config.tx, def->tx);
-	else if (config.tx == ANTENNA_SW_DIVERSITY)
+	if (!(ant->flags & ANTENNA_TX_DIVERSITY)) {
+		if (config.tx == ANTENNA_SW_DIVERSITY) {
+			ant->flags |= ANTENNA_TX_DIVERSITY;
+
+			if (def->tx == ANTENNA_SW_DIVERSITY)
+				config.tx = ANTENNA_B;
+			else
+				config.tx = def->tx;
+		}
+	} else if (config.tx == ANTENNA_SW_DIVERSITY)
 		config.tx = active->tx;
 
 	/*
@@ -163,12 +174,43 @@
 		rt2x00queue_start_queue(rt2x00dev->rx);
 }
 
+static u16 rt2x00ht_center_channel(struct rt2x00_dev *rt2x00dev,
+				   struct ieee80211_conf *conf)
+{
+	struct hw_mode_spec *spec = &rt2x00dev->spec;
+	int center_channel;
+	u16 i;
+
+	/*
+	 * Initialize center channel to current channel.
+	 */
+	center_channel = spec->channels[conf->channel->hw_value].channel;
+
+	/*
+	 * Adjust center channel to HT40+ and HT40- operation.
+	 */
+	if (conf_is_ht40_plus(conf))
+		center_channel += 2;
+	else if (conf_is_ht40_minus(conf))
+		center_channel -= (center_channel == 14) ? 1 : 2;
+
+	for (i = 0; i < spec->num_channels; i++)
+		if (spec->channels[i].channel == center_channel)
+			return i;
+
+	WARN_ON(1);
+	return conf->channel->hw_value;
+}
+
 void rt2x00lib_config(struct rt2x00_dev *rt2x00dev,
 		      struct ieee80211_conf *conf,
 		      unsigned int ieee80211_flags)
 {
 	struct rt2x00lib_conf libconf;
 	u16 hw_value;
+	u16 autowake_timeout;
+	u16 beacon_int;
+	u16 beacon_diff;
 
 	memset(&libconf, 0, sizeof(libconf));
 
@@ -176,10 +218,10 @@
 
 	if (ieee80211_flags & IEEE80211_CONF_CHANGE_CHANNEL) {
 		if (conf_is_ht40(conf)) {
-			__set_bit(CONFIG_CHANNEL_HT40, &rt2x00dev->flags);
+			set_bit(CONFIG_CHANNEL_HT40, &rt2x00dev->flags);
 			hw_value = rt2x00ht_center_channel(rt2x00dev, conf);
 		} else {
-			__clear_bit(CONFIG_CHANNEL_HT40, &rt2x00dev->flags);
+			clear_bit(CONFIG_CHANNEL_HT40, &rt2x00dev->flags);
 			hw_value = conf->channel->hw_value;
 		}
 
@@ -192,6 +234,10 @@
 		       sizeof(libconf.channel));
 	}
 
+	if (test_bit(REQUIRE_PS_AUTOWAKE, &rt2x00dev->cap_flags) &&
+	    (ieee80211_flags & IEEE80211_CONF_CHANGE_PS))
+		cancel_delayed_work_sync(&rt2x00dev->autowakeup_work);
+
 	/*
 	 * Start configuration.
 	 */
@@ -204,6 +250,27 @@
 	if (ieee80211_flags & IEEE80211_CONF_CHANGE_CHANNEL)
 		rt2x00link_reset_tuner(rt2x00dev, false);
 
+	if (test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags) &&
+	    test_bit(REQUIRE_PS_AUTOWAKE, &rt2x00dev->cap_flags) &&
+	    (ieee80211_flags & IEEE80211_CONF_CHANGE_PS) &&
+	    (conf->flags & IEEE80211_CONF_PS)) {
+		beacon_diff = (long)jiffies - (long)rt2x00dev->last_beacon;
+		beacon_int = msecs_to_jiffies(rt2x00dev->beacon_int);
+
+		if (beacon_diff > beacon_int)
+			beacon_diff = 0;
+
+		autowake_timeout = (conf->max_sleep_period * beacon_int) - beacon_diff;
+		queue_delayed_work(rt2x00dev->workqueue,
+				   &rt2x00dev->autowakeup_work,
+				   autowake_timeout - 15);
+	}
+
+	if (conf->flags & IEEE80211_CONF_PS)
+		set_bit(CONFIG_POWERSAVING, &rt2x00dev->flags);
+	else
+		clear_bit(CONFIG_POWERSAVING, &rt2x00dev->flags);
+
 	rt2x00dev->curr_band = conf->channel->band;
 	rt2x00dev->curr_freq = conf->channel->center_freq;
 	rt2x00dev->tx_power = conf->power_level;
diff -druN linux-2.6.39-libre/drivers/net/wireless/rt2x00/rt2x00crypto.c linux-3.0-rc7-libre/drivers/net/wireless/rt2x00/rt2x00crypto.c
--- linux-2.6.39-libre/drivers/net/wireless/rt2x00/rt2x00crypto.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/rt2x00/rt2x00crypto.c	2011-07-11 19:51:52.000000000 -0400
@@ -52,7 +52,7 @@
 	struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(entry->skb);
 	struct ieee80211_key_conf *hw_key = tx_info->control.hw_key;
 
-	if (!test_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags) || !hw_key)
+	if (!test_bit(CAPABILITY_HW_CRYPTO, &rt2x00dev->cap_flags) || !hw_key)
 		return;
 
 	__set_bit(ENTRY_TXD_ENCRYPT, &txdesc->flags);
@@ -80,7 +80,7 @@
 	struct ieee80211_key_conf *key = tx_info->control.hw_key;
 	unsigned int overhead = 0;
 
-	if (!test_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags) || !key)
+	if (!test_bit(CAPABILITY_HW_CRYPTO, &rt2x00dev->cap_flags) || !key)
 		return overhead;
 
 	/*
diff -druN linux-2.6.39-libre/drivers/net/wireless/rt2x00/rt2x00debug.c linux-3.0-rc7-libre/drivers/net/wireless/rt2x00/rt2x00debug.c
--- linux-2.6.39-libre/drivers/net/wireless/rt2x00/rt2x00debug.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/rt2x00/rt2x00debug.c	2011-07-11 19:51:52.000000000 -0400
@@ -63,7 +63,8 @@
 	 * - driver folder
 	 *   - driver file
 	 *   - chipset file
-	 *   - device flags file
+	 *   - device state flags file
+	 *   - device capability flags file
 	 *   - register folder
 	 *     - csr offset/value files
 	 *     - eeprom offset/value files
@@ -78,6 +79,7 @@
 	struct dentry *driver_entry;
 	struct dentry *chipset_entry;
 	struct dentry *dev_flags;
+	struct dentry *cap_flags;
 	struct dentry *register_folder;
 	struct dentry *csr_off_entry;
 	struct dentry *csr_val_entry;
@@ -553,6 +555,35 @@
 	.llseek		= default_llseek,
 };
 
+static ssize_t rt2x00debug_read_cap_flags(struct file *file,
+					  char __user *buf,
+					  size_t length,
+					  loff_t *offset)
+{
+	struct rt2x00debug_intf *intf =	file->private_data;
+	char line[16];
+	size_t size;
+
+	if (*offset)
+		return 0;
+
+	size = sprintf(line, "0x%.8x\n", (unsigned int)intf->rt2x00dev->cap_flags);
+
+	if (copy_to_user(buf, line, size))
+		return -EFAULT;
+
+	*offset += size;
+	return size;
+}
+
+static const struct file_operations rt2x00debug_fop_cap_flags = {
+	.owner		= THIS_MODULE,
+	.read		= rt2x00debug_read_cap_flags,
+	.open		= rt2x00debug_file_open,
+	.release	= rt2x00debug_file_release,
+	.llseek		= default_llseek,
+};
+
 static struct dentry *rt2x00debug_create_file_driver(const char *name,
 						     struct rt2x00debug_intf
 						     *intf,
@@ -568,7 +599,6 @@
 	blob->data = data;
 	data += sprintf(data, "driver:\t%s\n", intf->rt2x00dev->ops->name);
 	data += sprintf(data, "version:\t%s\n", DRV_VERSION);
-	data += sprintf(data, "compiled:\t%s %s\n", __DATE__, __TIME__);
 	blob->size = strlen(blob->data);
 
 	return debugfs_create_blob(name, S_IRUSR, intf->driver_folder, blob);
@@ -653,6 +683,12 @@
 	if (IS_ERR(intf->dev_flags) || !intf->dev_flags)
 		goto exit;
 
+	intf->cap_flags = debugfs_create_file("cap_flags", S_IRUSR,
+					      intf->driver_folder, intf,
+					      &rt2x00debug_fop_cap_flags);
+	if (IS_ERR(intf->cap_flags) || !intf->cap_flags)
+		goto exit;
+
 	intf->register_folder =
 	    debugfs_create_dir("register", intf->driver_folder);
 	if (IS_ERR(intf->register_folder) || !intf->register_folder)
@@ -706,7 +742,7 @@
 				intf, &rt2x00debug_fop_queue_stats);
 
 #ifdef CONFIG_RT2X00_LIB_CRYPTO
-	if (test_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags))
+	if (test_bit(CAPABILITY_HW_CRYPTO, &rt2x00dev->cap_flags))
 		intf->crypto_stats_entry =
 		    debugfs_create_file("crypto", S_IRUGO, intf->queue_folder,
 					intf, &rt2x00debug_fop_crypto_stats);
@@ -744,6 +780,7 @@
 	debugfs_remove(intf->csr_off_entry);
 	debugfs_remove(intf->register_folder);
 	debugfs_remove(intf->dev_flags);
+	debugfs_remove(intf->cap_flags);
 	debugfs_remove(intf->chipset_entry);
 	debugfs_remove(intf->driver_entry);
 	debugfs_remove(intf->driver_folder);
diff -druN linux-2.6.39-libre/drivers/net/wireless/rt2x00/rt2x00dev.c linux-3.0-rc7-libre/drivers/net/wireless/rt2x00/rt2x00dev.c
--- linux-2.6.39-libre/drivers/net/wireless/rt2x00/rt2x00dev.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/rt2x00/rt2x00dev.c	2011-07-11 19:51:52.000000000 -0400
@@ -27,6 +27,7 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/slab.h>
+#include <linux/log2.h>
 
 #include "rt2x00.h"
 #include "rt2x00lib.h"
@@ -70,6 +71,7 @@
 	 */
 	rt2x00queue_start_queues(rt2x00dev);
 	rt2x00link_start_tuner(rt2x00dev);
+	rt2x00link_start_agc(rt2x00dev);
 
 	/*
 	 * Start watchdog monitoring.
@@ -92,6 +94,7 @@
 	/*
 	 * Stop all queues
 	 */
+	rt2x00link_stop_agc(rt2x00dev);
 	rt2x00link_stop_tuner(rt2x00dev);
 	rt2x00queue_stop_queues(rt2x00dev);
 	rt2x00queue_flush_queues(rt2x00dev, true);
@@ -138,6 +141,19 @@
 					    rt2x00dev);
 }
 
+static void rt2x00lib_autowakeup(struct work_struct *work)
+{
+	struct rt2x00_dev *rt2x00dev =
+	    container_of(work, struct rt2x00_dev, autowakeup_work.work);
+
+	if (!test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags))
+		return;
+
+	if (rt2x00dev->ops->lib->set_device_state(rt2x00dev, STATE_AWAKE))
+		ERROR(rt2x00dev, "Device failed to wakeup.\n");
+	clear_bit(CONFIG_POWERSAVING, &rt2x00dev->flags);
+}
+
 /*
  * Interrupt context handlers.
  */
@@ -197,7 +213,7 @@
 	 * here as they will fetch the next beacon directly prior to
 	 * transmission.
 	 */
-	if (test_bit(DRIVER_SUPPORT_PRE_TBTT_INTERRUPT, &rt2x00dev->flags))
+	if (test_bit(CAPABILITY_PRE_TBTT_INTERRUPT, &rt2x00dev->cap_flags))
 		return;
 
 	/* fetch next beacon */
@@ -222,7 +238,7 @@
 void rt2x00lib_dmastart(struct queue_entry *entry)
 {
 	set_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags);
-	rt2x00queue_index_inc(entry->queue, Q_INDEX);
+	rt2x00queue_index_inc(entry, Q_INDEX);
 }
 EXPORT_SYMBOL_GPL(rt2x00lib_dmastart);
 
@@ -230,7 +246,7 @@
 {
 	set_bit(ENTRY_DATA_STATUS_PENDING, &entry->flags);
 	clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags);
-	rt2x00queue_index_inc(entry->queue, Q_INDEX_DMA_DONE);
+	rt2x00queue_index_inc(entry, Q_INDEX_DMA_DONE);
 }
 EXPORT_SYMBOL_GPL(rt2x00lib_dmadone);
 
@@ -268,7 +284,7 @@
 	/*
 	 * Remove L2 padding which was added during
 	 */
-	if (test_bit(DRIVER_REQUIRE_L2PAD, &rt2x00dev->flags))
+	if (test_bit(REQUIRE_L2PAD, &rt2x00dev->cap_flags))
 		rt2x00queue_remove_l2pad(entry->skb, header_length);
 
 	/*
@@ -277,7 +293,7 @@
 	 * mac80211 will expect the same data to be present it the
 	 * frame as it was passed to us.
 	 */
-	if (test_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags))
+	if (test_bit(CAPABILITY_HW_CRYPTO, &rt2x00dev->cap_flags))
 		rt2x00crypto_tx_insert_iv(entry->skb, header_length);
 
 	/*
@@ -350,10 +366,14 @@
 	 * which would allow the rc algorithm to better decide on
 	 * which rates are suitable.
 	 */
-	if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) {
+	if (test_bit(TXDONE_AMPDU, &txdesc->flags) ||
+	    tx_info->flags & IEEE80211_TX_CTL_AMPDU) {
 		tx_info->flags |= IEEE80211_TX_STAT_AMPDU;
 		tx_info->status.ampdu_len = 1;
 		tx_info->status.ampdu_ack_len = success ? 1 : 0;
+
+		if (!success)
+			tx_info->flags |= IEEE80211_TX_STAT_AMPDU_NO_BACK;
 	}
 
 	if (rate_flags & IEEE80211_TX_RC_USE_RTS_CTS) {
@@ -370,7 +390,7 @@
 	 * send the status report back.
 	 */
 	if (!(skbdesc_flags & SKBDESC_NOT_MAC80211)) {
-		if (test_bit(DRIVER_REQUIRE_TASKLET_CONTEXT, &rt2x00dev->flags))
+		if (test_bit(REQUIRE_TASKLET_CONTEXT, &rt2x00dev->cap_flags))
 			ieee80211_tx_status(rt2x00dev->hw, entry->skb);
 		else
 			ieee80211_tx_status_ni(rt2x00dev->hw, entry->skb);
@@ -385,7 +405,7 @@
 
 	rt2x00dev->ops->lib->clear_entry(entry);
 
-	rt2x00queue_index_inc(entry->queue, Q_INDEX_DONE);
+	rt2x00queue_index_inc(entry, Q_INDEX_DONE);
 
 	/*
 	 * If the data queue was below the threshold before the txdone
@@ -409,6 +429,77 @@
 }
 EXPORT_SYMBOL_GPL(rt2x00lib_txdone_noinfo);
 
+static u8 *rt2x00lib_find_ie(u8 *data, unsigned int len, u8 ie)
+{
+	struct ieee80211_mgmt *mgmt = (void *)data;
+	u8 *pos, *end;
+
+	pos = (u8 *)mgmt->u.beacon.variable;
+	end = data + len;
+	while (pos < end) {
+		if (pos + 2 + pos[1] > end)
+			return NULL;
+
+		if (pos[0] == ie)
+			return pos;
+
+		pos += 2 + pos[1];
+	}
+
+	return NULL;
+}
+
+static void rt2x00lib_rxdone_check_ps(struct rt2x00_dev *rt2x00dev,
+				      struct sk_buff *skb,
+				      struct rxdone_entry_desc *rxdesc)
+{
+	struct ieee80211_hdr *hdr = (void *) skb->data;
+	struct ieee80211_tim_ie *tim_ie;
+	u8 *tim;
+	u8 tim_len;
+	bool cam;
+
+	/* If this is not a beacon, or if mac80211 has no powersaving
+	 * configured, or if the device is already in powersaving mode
+	 * we can exit now. */
+	if (likely(!ieee80211_is_beacon(hdr->frame_control) ||
+		   !(rt2x00dev->hw->conf.flags & IEEE80211_CONF_PS)))
+		return;
+
+	/* min. beacon length + FCS_LEN */
+	if (skb->len <= 40 + FCS_LEN)
+		return;
+
+	/* and only beacons from the associated BSSID, please */
+	if (!(rxdesc->dev_flags & RXDONE_MY_BSS) ||
+	    !rt2x00dev->aid)
+		return;
+
+	rt2x00dev->last_beacon = jiffies;
+
+	tim = rt2x00lib_find_ie(skb->data, skb->len - FCS_LEN, WLAN_EID_TIM);
+	if (!tim)
+		return;
+
+	if (tim[1] < sizeof(*tim_ie))
+		return;
+
+	tim_len = tim[1];
+	tim_ie = (struct ieee80211_tim_ie *) &tim[2];
+
+	/* Check whenever the PHY can be turned off again. */
+
+	/* 1. What about buffered unicast traffic for our AID? */
+	cam = ieee80211_check_tim(tim_ie, tim_len, rt2x00dev->aid);
+
+	/* 2. Maybe the AP wants to send multicast/broadcast data? */
+	cam |= (tim_ie->bitmap_ctrl & 0x01);
+
+	if (!cam && !test_bit(CONFIG_POWERSAVING, &rt2x00dev->flags))
+		rt2x00lib_config(rt2x00dev, &rt2x00dev->hw->conf,
+				 IEEE80211_CONF_CHANGE_PS);
+}
+
 static int rt2x00lib_rxdone_read_signal(struct rt2x00_dev *rt2x00dev,
 					struct rxdone_entry_desc *rxdesc)
 {
@@ -511,8 +602,6 @@
 		 (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);
@@ -526,6 +615,12 @@
 		rxdesc.flags |= RX_FLAG_HT;
 
 	/*
+	 * Check if this is a beacon, and more frames have been
+	 * buffered while we were in powersaving mode.
+	 */
+	rt2x00lib_rxdone_check_ps(rt2x00dev, entry->skb, &rxdesc);
+
+	/*
 	 * Update extra components
 	 */
 	rt2x00link_update_stats(rt2x00dev, entry->skb, &rxdesc);
@@ -554,7 +649,7 @@
 
 submit_entry:
 	entry->flags = 0;
-	rt2x00queue_index_inc(entry->queue, Q_INDEX_DONE);
+	rt2x00queue_index_inc(entry, Q_INDEX_DONE);
 	if (test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags) &&
 	    test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags))
 		rt2x00dev->ops->lib->clear_entry(entry);
@@ -801,23 +896,28 @@
 	/*
 	 * Take TX headroom required for alignment into account.
 	 */
-	if (test_bit(DRIVER_REQUIRE_L2PAD, &rt2x00dev->flags))
+	if (test_bit(REQUIRE_L2PAD, &rt2x00dev->cap_flags))
 		rt2x00dev->hw->extra_tx_headroom += RT2X00_L2PAD_SIZE;
-	else if (test_bit(DRIVER_REQUIRE_DMA, &rt2x00dev->flags))
+	else if (test_bit(REQUIRE_DMA, &rt2x00dev->cap_flags))
 		rt2x00dev->hw->extra_tx_headroom += RT2X00_ALIGN_SIZE;
 
 	/*
 	 * Allocate tx status FIFO for driver use.
 	 */
-	if (test_bit(DRIVER_REQUIRE_TXSTATUS_FIFO, &rt2x00dev->flags)) {
+	if (test_bit(REQUIRE_TXSTATUS_FIFO, &rt2x00dev->cap_flags)) {
 		/*
-		 * Allocate txstatus fifo and tasklet, we use a size of 512
-		 * for the kfifo which is big enough to store 512/4=128 tx
-		 * status reports. In the worst case (tx status for all tx
-		 * queues gets reported before we've got a chance to handle
-		 * them) 24*4=384 tx status reports need to be cached.
+		 * Allocate the txstatus fifo. In the worst case the tx
+		 * status fifo has to hold the tx status of all entries
+		 * in all tx queues. Hence, calculate the kfifo size as
+		 * tx_queues * entry_num and round up to the nearest
+		 * power of 2.
 		 */
-		status = kfifo_alloc(&rt2x00dev->txstatus_fifo, 512,
+		int kfifo_size =
+			roundup_pow_of_two(rt2x00dev->ops->tx_queues *
+					   rt2x00dev->ops->tx->entry_num *
+					   sizeof(u32));
+
+		status = kfifo_alloc(&rt2x00dev->txstatus_fifo, kfifo_size,
 				     GFP_KERNEL);
 		if (status)
 			return status;
@@ -1007,6 +1107,7 @@
 	}
 
 	INIT_WORK(&rt2x00dev->intf_work, rt2x00lib_intf_scheduled);
+	INIT_DELAYED_WORK(&rt2x00dev->autowakeup_work, rt2x00lib_autowakeup);
 
 	/*
 	 * Let the driver probe the device to detect the capabilities.
@@ -1062,7 +1163,9 @@
 	 * Stop all work.
 	 */
 	cancel_work_sync(&rt2x00dev->intf_work);
+	cancel_delayed_work_sync(&rt2x00dev->autowakeup_work);
 	if (rt2x00_is_usb(rt2x00dev)) {
+		del_timer_sync(&rt2x00dev->txstatus_timer);
 		cancel_work_sync(&rt2x00dev->rxdone_work);
 		cancel_work_sync(&rt2x00dev->txdone_work);
 	}
diff -druN linux-2.6.39-libre/drivers/net/wireless/rt2x00/rt2x00firmware.c linux-3.0-rc7-libre/drivers/net/wireless/rt2x00/rt2x00firmware.c
--- linux-2.6.39-libre/drivers/net/wireless/rt2x00/rt2x00firmware.c	2011-05-19 02:15:26.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/rt2x00/rt2x00firmware.c	2011-07-21 06:57:43.000000000 -0400
@@ -99,7 +99,7 @@
 {
 	int retval;
 
-	if (!test_bit(DRIVER_REQUIRE_FIRMWARE, &rt2x00dev->flags))
+	if (!test_bit(REQUIRE_FIRMWARE, &rt2x00dev->cap_flags))
 		return 0;
 
 	if (!rt2x00dev->fw) {
diff -druN linux-2.6.39-libre/drivers/net/wireless/rt2x00/rt2x00.h linux-3.0-rc7-libre/drivers/net/wireless/rt2x00/rt2x00.h
--- linux-2.6.39-libre/drivers/net/wireless/rt2x00/rt2x00.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/rt2x00/rt2x00.h	2011-07-11 19:51:52.000000000 -0400
@@ -37,6 +37,7 @@
 #include <linux/etherdevice.h>
 #include <linux/input-polldev.h>
 #include <linux/kfifo.h>
+#include <linux/timer.h>
 
 #include <net/mac80211.h>
 
@@ -348,6 +349,11 @@
 	 * to bring the device/driver back into the desired state.
 	 */
 	struct delayed_work watchdog_work;
+
+	/*
+	 * Work structure for scheduling periodic AGC adjustments.
+	 */
+	struct delayed_work agc_work;
 };
 
 enum rt2x00_delayed_flags {
@@ -556,6 +562,7 @@
 			     struct link_qual *qual);
 	void (*link_tuner) (struct rt2x00_dev *rt2x00dev,
 			    struct link_qual *qual, const u32 count);
+	void (*gain_calibration) (struct rt2x00_dev *rt2x00dev);
 
 	/*
 	 * Data queue handlers.
@@ -564,7 +571,8 @@
 	void (*start_queue) (struct data_queue *queue);
 	void (*kick_queue) (struct data_queue *queue);
 	void (*stop_queue) (struct data_queue *queue);
-	void (*flush_queue) (struct data_queue *queue);
+	void (*flush_queue) (struct data_queue *queue, bool drop);
+	void (*tx_dma_done) (struct queue_entry *entry);
 
 	/*
 	 * TX control handlers
@@ -637,11 +645,11 @@
 };
 
 /*
- * rt2x00 device flags
+ * rt2x00 state flags
  */
-enum rt2x00_flags {
+enum rt2x00_state_flags {
 	/*
-	 * Device state flags
+	 * Device flags
 	 */
 	DEVICE_STATE_PRESENT,
 	DEVICE_STATE_REGISTERED_HW,
@@ -651,40 +659,47 @@
 	DEVICE_STATE_SCANNING,
 
 	/*
-	 * Driver requirements
+	 * Driver configuration
 	 */
-	DRIVER_REQUIRE_FIRMWARE,
-	DRIVER_REQUIRE_BEACON_GUARD,
-	DRIVER_REQUIRE_ATIM_QUEUE,
-	DRIVER_REQUIRE_DMA,
-	DRIVER_REQUIRE_COPY_IV,
-	DRIVER_REQUIRE_L2PAD,
-	DRIVER_REQUIRE_TXSTATUS_FIFO,
-	DRIVER_REQUIRE_TASKLET_CONTEXT,
-	DRIVER_REQUIRE_SW_SEQNO,
-	DRIVER_REQUIRE_HT_TX_DESC,
+	CONFIG_CHANNEL_HT40,
+	CONFIG_POWERSAVING,
+};
 
+/*
+ * rt2x00 capability flags
+ */
+enum rt2x00_capability_flags {
 	/*
-	 * Driver features
+	 * Requirements
 	 */
-	CONFIG_SUPPORT_HW_BUTTON,
-	CONFIG_SUPPORT_HW_CRYPTO,
-	CONFIG_SUPPORT_POWER_LIMIT,
-	DRIVER_SUPPORT_CONTROL_FILTERS,
-	DRIVER_SUPPORT_CONTROL_FILTER_PSPOLL,
-	DRIVER_SUPPORT_PRE_TBTT_INTERRUPT,
-	DRIVER_SUPPORT_LINK_TUNING,
-	DRIVER_SUPPORT_WATCHDOG,
+	REQUIRE_FIRMWARE,
+	REQUIRE_BEACON_GUARD,
+	REQUIRE_ATIM_QUEUE,
+	REQUIRE_DMA,
+	REQUIRE_COPY_IV,
+	REQUIRE_L2PAD,
+	REQUIRE_TXSTATUS_FIFO,
+	REQUIRE_TASKLET_CONTEXT,
+	REQUIRE_SW_SEQNO,
+	REQUIRE_HT_TX_DESC,
+	REQUIRE_PS_AUTOWAKE,
 
 	/*
-	 * Driver configuration
+	 * Capabilities
 	 */
-	CONFIG_FRAME_TYPE,
-	CONFIG_RF_SEQUENCE,
-	CONFIG_EXTERNAL_LNA_A,
-	CONFIG_EXTERNAL_LNA_BG,
-	CONFIG_DOUBLE_ANTENNA,
-	CONFIG_CHANNEL_HT40,
+	CAPABILITY_HW_BUTTON,
+	CAPABILITY_HW_CRYPTO,
+	CAPABILITY_POWER_LIMIT,
+	CAPABILITY_CONTROL_FILTERS,
+	CAPABILITY_CONTROL_FILTER_PSPOLL,
+	CAPABILITY_PRE_TBTT_INTERRUPT,
+	CAPABILITY_LINK_TUNING,
+	CAPABILITY_FRAME_TYPE,
+	CAPABILITY_RF_SEQUENCE,
+	CAPABILITY_EXTERNAL_LNA_A,
+	CAPABILITY_EXTERNAL_LNA_BG,
+	CAPABILITY_DOUBLE_ANTENNA,
+	CAPABILITY_BT_COEXIST,
 };
 
 /*
@@ -733,13 +748,20 @@
 #endif /* CONFIG_RT2X00_LIB_LEDS */
 
 	/*
-	 * Device flags.
-	 * In these flags the current status and some
-	 * of the device capabilities are stored.
+	 * Device state flags.
+	 * In these flags the current status is stored.
+	 * Access to these flags should occur atomically.
 	 */
 	unsigned long flags;
 
 	/*
+	 * Device capabiltiy flags.
+	 * In these flags the device/driver capabilities are stored.
+	 * Access to these flags should occur non-atomically.
+	 */
+	unsigned long cap_flags;
+
+	/*
 	 * Device information, Bus IRQ and name (PCI, SoC)
 	 */
 	int irq;
@@ -855,10 +877,20 @@
 	u8 calibration[2];
 
 	/*
+	 * Association id.
+	 */
+	u16 aid;
+
+	/*
 	 * Beacon interval.
 	 */
 	u16 beacon_int;
 
+	/**
+	 * Timestamp of last received beacon
+	 */
+	unsigned long last_beacon;
+
 	/*
 	 * Low level statistics which will have
 	 * to be kept up to date while device is running.
@@ -887,6 +919,11 @@
 	struct work_struct txdone_work;
 
 	/*
+	 * Powersaving work
+	 */
+	struct delayed_work autowakeup_work;
+
+	/*
 	 * Data queue arrays for RX, TX, Beacon and ATIM.
 	 */
 	unsigned int data_queues;
@@ -906,6 +943,11 @@
 	DECLARE_KFIFO_PTR(txstatus_fifo, u32);
 
 	/*
+	 * Timer to ensure tx status reports are read (rt2800usb).
+	 */
+	struct timer_list txstatus_timer;
+
+	/*
 	 * Tasklet for processing tx status reports (rt2800pci).
 	 */
 	struct tasklet_struct txstatus_tasklet;
@@ -1230,6 +1272,10 @@
 		      const struct ieee80211_tx_queue_params *params);
 void rt2x00mac_rfkill_poll(struct ieee80211_hw *hw);
 void rt2x00mac_flush(struct ieee80211_hw *hw, bool drop);
+int rt2x00mac_set_antenna(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant);
+int rt2x00mac_get_antenna(struct ieee80211_hw *hw, u32 *tx_ant, u32 *rx_ant);
+void rt2x00mac_get_ringparam(struct ieee80211_hw *hw,
+			     u32 *tx, u32 *tx_max, u32 *rx, u32 *rx_max);
 
 /*
  * Driver allocation handlers.
diff -druN linux-2.6.39-libre/drivers/net/wireless/rt2x00/rt2x00ht.c linux-3.0-rc7-libre/drivers/net/wireless/rt2x00/rt2x00ht.c
--- linux-2.6.39-libre/drivers/net/wireless/rt2x00/rt2x00ht.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/rt2x00/rt2x00ht.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,133 +0,0 @@
-/*
-	Copyright (C) 2004 - 2009 Ivo van Doorn <IvDoorn@gmail.com>
-	<http://rt2x00.serialmonkey.com>
-
-	This program is free software; you can redistribute it and/or modify
-	it under the terms of the GNU General Public License as published by
-	the Free Software Foundation; either version 2 of the License, or
-	(at your option) any later version.
-
-	This program is distributed in the hope that it will be useful,
-	but WITHOUT ANY WARRANTY; without even the implied warranty of
-	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-	GNU General Public License for more details.
-
-	You should have received a copy of the GNU General Public License
-	along with this program; if not, write to the
-	Free Software Foundation, Inc.,
-	59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-/*
-	Module: rt2x00lib
-	Abstract: rt2x00 HT specific routines.
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-
-#include "rt2x00.h"
-#include "rt2x00lib.h"
-
-void rt2x00ht_create_tx_descriptor(struct queue_entry *entry,
-				   struct txentry_desc *txdesc,
-				   const struct rt2x00_rate *hwrate)
-{
-	struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(entry->skb);
-	struct ieee80211_tx_rate *txrate = &tx_info->control.rates[0];
-	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)entry->skb->data;
-
-	if (tx_info->control.sta)
-		txdesc->u.ht.mpdu_density =
-		    tx_info->control.sta->ht_cap.ampdu_density;
-
-	txdesc->u.ht.ba_size = 7;	/* FIXME: What value is needed? */
-
-	txdesc->u.ht.stbc =
-	    (tx_info->flags & IEEE80211_TX_CTL_STBC) >> IEEE80211_TX_CTL_STBC_SHIFT;
-
-	/*
-	 * If IEEE80211_TX_RC_MCS is set txrate->idx just contains the
-	 * mcs rate to be used
-	 */
-	if (txrate->flags & IEEE80211_TX_RC_MCS) {
-		txdesc->u.ht.mcs = txrate->idx;
-
-		/*
-		 * MIMO PS should be set to 1 for STA's using dynamic SM PS
-		 * when using more then one tx stream (>MCS7).
-		 */
-		if (tx_info->control.sta && txdesc->u.ht.mcs > 7 &&
-		    ((tx_info->control.sta->ht_cap.cap &
-		      IEEE80211_HT_CAP_SM_PS) >>
-		     IEEE80211_HT_CAP_SM_PS_SHIFT) ==
-		    WLAN_HT_CAP_SM_PS_DYNAMIC)
-			__set_bit(ENTRY_TXD_HT_MIMO_PS, &txdesc->flags);
-	} else {
-		txdesc->u.ht.mcs = rt2x00_get_rate_mcs(hwrate->mcs);
-		if (txrate->flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE)
-			txdesc->u.ht.mcs |= 0x08;
-	}
-
-	/*
-	 * This frame is eligible for an AMPDU, however, don't aggregate
-	 * frames that are intended to probe a specific tx rate.
-	 */
-	if (tx_info->flags & IEEE80211_TX_CTL_AMPDU &&
-	    !(tx_info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE))
-		__set_bit(ENTRY_TXD_HT_AMPDU, &txdesc->flags);
-
-	/*
-	 * Set 40Mhz mode if necessary (for legacy rates this will
-	 * duplicate the frame to both channels).
-	 */
-	if (txrate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH ||
-	    txrate->flags & IEEE80211_TX_RC_DUP_DATA)
-		__set_bit(ENTRY_TXD_HT_BW_40, &txdesc->flags);
-	if (txrate->flags & IEEE80211_TX_RC_SHORT_GI)
-		__set_bit(ENTRY_TXD_HT_SHORT_GI, &txdesc->flags);
-
-	/*
-	 * Determine IFS values
-	 * - Use TXOP_BACKOFF for management frames
-	 * - Use TXOP_SIFS for fragment bursts
-	 * - Use TXOP_HTTXOP for everything else
-	 *
-	 * Note: rt2800 devices won't use CTS protection (if used)
-	 * for frames not transmitted with TXOP_HTTXOP
-	 */
-	if (ieee80211_is_mgmt(hdr->frame_control))
-		txdesc->u.ht.txop = TXOP_BACKOFF;
-	else if (!(tx_info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT))
-		txdesc->u.ht.txop = TXOP_SIFS;
-	else
-		txdesc->u.ht.txop = TXOP_HTTXOP;
-}
-
-u16 rt2x00ht_center_channel(struct rt2x00_dev *rt2x00dev,
-			    struct ieee80211_conf *conf)
-{
-	struct hw_mode_spec *spec = &rt2x00dev->spec;
-	int center_channel;
-	u16 i;
-
-	/*
-	 * Initialize center channel to current channel.
-	 */
-	center_channel = spec->channels[conf->channel->hw_value].channel;
-
-	/*
-	 * Adjust center channel to HT40+ and HT40- operation.
-	 */
-	if (conf_is_ht40_plus(conf))
-		center_channel += 2;
-	else if (conf_is_ht40_minus(conf))
-		center_channel -= (center_channel == 14) ? 1 : 2;
-
-	for (i = 0; i < spec->num_channels; i++)
-		if (spec->channels[i].channel == center_channel)
-			return i;
-
-	WARN_ON(1);
-	return conf->channel->hw_value;
-}
diff -druN linux-2.6.39-libre/drivers/net/wireless/rt2x00/rt2x00lib.h linux-3.0-rc7-libre/drivers/net/wireless/rt2x00/rt2x00lib.h
--- linux-2.6.39-libre/drivers/net/wireless/rt2x00/rt2x00lib.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/rt2x00/rt2x00lib.h	2011-07-11 19:51:52.000000000 -0400
@@ -32,6 +32,7 @@
  */
 #define WATCHDOG_INTERVAL	round_jiffies_relative(HZ)
 #define LINK_TUNE_INTERVAL	round_jiffies_relative(HZ)
+#define AGC_INTERVAL		round_jiffies_relative(4 * HZ)
 
 /*
  * rt2x00_rate: Per rate device information
@@ -119,16 +120,6 @@
 void rt2x00queue_align_frame(struct sk_buff *skb);
 
 /**
- * rt2x00queue_align_payload - Align 802.11 payload to 4-byte boundary
- * @skb: The skb to align
- * @header_length: Length of 802.11 header
- *
- * Align the 802.11 payload to a 4-byte boundary, this could
- * mean the header is not aligned properly though.
- */
-void rt2x00queue_align_payload(struct sk_buff *skb, unsigned int header_length);
-
-/**
  * rt2x00queue_insert_l2pad - Align 802.11 header & payload to 4-byte boundary
  * @skb: The skb to align
  * @header_length: Length of 802.11 header
@@ -184,14 +175,14 @@
 
 /**
  * rt2x00queue_index_inc - Index incrementation function
- * @queue: Queue (&struct data_queue) to perform the action on.
+ * @entry: Queue entry (&struct queue_entry) to perform the action on.
  * @index: Index type (&enum queue_index) to perform the action on.
  *
- * This function will increase the requested index on the queue,
+ * This function will increase the requested index on the entry's queue,
  * it will grab the appropriate locks and handle queue overflow events by
  * resetting the index to the start of the queue.
  */
-void rt2x00queue_index_inc(struct data_queue *queue, enum queue_index index);
+void rt2x00queue_index_inc(struct queue_entry *entry, enum queue_index index);
 
 /**
  * rt2x00queue_init_queues - Initialize all data queues
@@ -281,6 +272,18 @@
 void rt2x00link_stop_watchdog(struct rt2x00_dev *rt2x00dev);
 
 /**
+ * rt2x00link_start_agc - Start periodic gain calibration
+ * @rt2x00dev: Pointer to &struct rt2x00_dev.
+ */
+void rt2x00link_start_agc(struct rt2x00_dev *rt2x00dev);
+
+/**
+ * rt2x00link_stop_agc - Stop periodic gain calibration
+ * @rt2x00dev: Pointer to &struct rt2x00_dev.
+ */
+void rt2x00link_stop_agc(struct rt2x00_dev *rt2x00dev);
+
+/**
  * rt2x00link_register - Initialize link tuning & watchdog functionality
  * @rt2x00dev: Pointer to &struct rt2x00_dev.
  *
@@ -385,41 +388,17 @@
 #endif /* CONFIG_RT2X00_LIB_CRYPTO */
 
 /*
- * HT handlers.
- */
-#ifdef CONFIG_RT2X00_LIB_HT
-void rt2x00ht_create_tx_descriptor(struct queue_entry *entry,
-				   struct txentry_desc *txdesc,
-				   const struct rt2x00_rate *hwrate);
-
-u16 rt2x00ht_center_channel(struct rt2x00_dev *rt2x00dev,
-			    struct ieee80211_conf *conf);
-#else
-static inline void rt2x00ht_create_tx_descriptor(struct queue_entry *entry,
-						 struct txentry_desc *txdesc,
-						 const struct rt2x00_rate *hwrate)
-{
-}
-
-static inline u16 rt2x00ht_center_channel(struct rt2x00_dev *rt2x00dev,
-					  struct ieee80211_conf *conf)
-{
-	return conf->channel->hw_value;
-}
-#endif /* CONFIG_RT2X00_LIB_HT */
-
-/*
  * RFkill handlers.
  */
 static inline void rt2x00rfkill_register(struct rt2x00_dev *rt2x00dev)
 {
-	if (test_bit(CONFIG_SUPPORT_HW_BUTTON, &rt2x00dev->flags))
+	if (test_bit(CAPABILITY_HW_BUTTON, &rt2x00dev->cap_flags))
 		wiphy_rfkill_start_polling(rt2x00dev->hw->wiphy);
 }
 
 static inline void rt2x00rfkill_unregister(struct rt2x00_dev *rt2x00dev)
 {
-	if (test_bit(CONFIG_SUPPORT_HW_BUTTON, &rt2x00dev->flags))
+	if (test_bit(CAPABILITY_HW_BUTTON, &rt2x00dev->cap_flags))
 		wiphy_rfkill_stop_polling(rt2x00dev->hw->wiphy);
 }
 
diff -druN linux-2.6.39-libre/drivers/net/wireless/rt2x00/rt2x00link.c linux-3.0-rc7-libre/drivers/net/wireless/rt2x00/rt2x00link.c
--- linux-2.6.39-libre/drivers/net/wireless/rt2x00/rt2x00link.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/rt2x00/rt2x00link.c	2011-07-11 19:51:52.000000000 -0400
@@ -192,17 +192,7 @@
 	/*
 	 * Determine if software diversity is enabled for
 	 * either the TX or RX antenna (or both).
-	 * Always perform this check since within the link
-	 * tuner interval the configuration might have changed.
 	 */
-	ant->flags &= ~ANTENNA_RX_DIVERSITY;
-	ant->flags &= ~ANTENNA_TX_DIVERSITY;
-
-	if (rt2x00dev->default_ant.rx == ANTENNA_SW_DIVERSITY)
-		ant->flags |= ANTENNA_RX_DIVERSITY;
-	if (rt2x00dev->default_ant.tx == ANTENNA_SW_DIVERSITY)
-		ant->flags |= ANTENNA_TX_DIVERSITY;
-
 	if (!(ant->flags & ANTENNA_RX_DIVERSITY) &&
 	    !(ant->flags & ANTENNA_TX_DIVERSITY)) {
 		ant->flags = 0;
@@ -383,7 +373,7 @@
 	 * do not support link tuning at all, while other devices can disable
 	 * the feature from the EEPROM.
 	 */
-	if (test_bit(DRIVER_SUPPORT_LINK_TUNING, &rt2x00dev->flags))
+	if (test_bit(CAPABILITY_LINK_TUNING, &rt2x00dev->cap_flags))
 		rt2x00dev->ops->lib->link_tuner(rt2x00dev, qual, link->count);
 
 	/*
@@ -413,12 +403,11 @@
 {
 	struct link *link = &rt2x00dev->link;
 
-	if (!test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags) ||
-	    !test_bit(DRIVER_SUPPORT_WATCHDOG, &rt2x00dev->flags))
-		return;
-
-	ieee80211_queue_delayed_work(rt2x00dev->hw,
-				     &link->watchdog_work, WATCHDOG_INTERVAL);
+	if (test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags) &&
+	    rt2x00dev->ops->lib->watchdog)
+		ieee80211_queue_delayed_work(rt2x00dev->hw,
+					     &link->watchdog_work,
+					     WATCHDOG_INTERVAL);
 }
 
 void rt2x00link_stop_watchdog(struct rt2x00_dev *rt2x00dev)
@@ -447,8 +436,46 @@
 					     WATCHDOG_INTERVAL);
 }
 
+void rt2x00link_start_agc(struct rt2x00_dev *rt2x00dev)
+{
+	struct link *link = &rt2x00dev->link;
+
+	if (test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags) &&
+	    rt2x00dev->ops->lib->gain_calibration)
+		ieee80211_queue_delayed_work(rt2x00dev->hw,
+					     &link->agc_work,
+					     AGC_INTERVAL);
+}
+
+void rt2x00link_stop_agc(struct rt2x00_dev *rt2x00dev)
+{
+	cancel_delayed_work_sync(&rt2x00dev->link.agc_work);
+}
+
+static void rt2x00link_agc(struct work_struct *work)
+{
+	struct rt2x00_dev *rt2x00dev =
+	    container_of(work, struct rt2x00_dev, link.agc_work.work);
+	struct link *link = &rt2x00dev->link;
+
+	/*
+	 * When the radio is shutting down we should
+	 * immediately cease the watchdog monitoring.
+	 */
+	if (!test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags))
+		return;
+
+	rt2x00dev->ops->lib->gain_calibration(rt2x00dev);
+
+	if (test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags))
+		ieee80211_queue_delayed_work(rt2x00dev->hw,
+					     &link->agc_work,
+					     AGC_INTERVAL);
+}
+
 void rt2x00link_register(struct rt2x00_dev *rt2x00dev)
 {
+	INIT_DELAYED_WORK(&rt2x00dev->link.agc_work, rt2x00link_agc);
 	INIT_DELAYED_WORK(&rt2x00dev->link.watchdog_work, rt2x00link_watchdog);
 	INIT_DELAYED_WORK(&rt2x00dev->link.work, rt2x00link_tuner);
 }
diff -druN linux-2.6.39-libre/drivers/net/wireless/rt2x00/rt2x00mac.c linux-3.0-rc7-libre/drivers/net/wireless/rt2x00/rt2x00mac.c
--- linux-2.6.39-libre/drivers/net/wireless/rt2x00/rt2x00mac.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/rt2x00/rt2x00mac.c	2011-07-11 19:51:52.000000000 -0400
@@ -119,7 +119,7 @@
 	 * Use the ATIM queue if appropriate and present.
 	 */
 	if (tx_info->flags & IEEE80211_TX_CTL_SEND_AFTER_DTIM &&
-	    test_bit(DRIVER_REQUIRE_ATIM_QUEUE, &rt2x00dev->flags))
+	    test_bit(REQUIRE_ATIM_QUEUE, &rt2x00dev->cap_flags))
 		qid = QID_ATIM;
 
 	queue = rt2x00queue_get_tx_queue(rt2x00dev, qid);
@@ -158,7 +158,7 @@
 	return;
 
  exit_fail:
-	ieee80211_stop_queue(rt2x00dev->hw, qid);
+	rt2x00queue_pause_queue(queue);
 	dev_kfree_skb_any(skb);
 }
 EXPORT_SYMBOL_GPL(rt2x00mac_tx);
@@ -411,11 +411,11 @@
 	 * of different types, but has no a separate filter for PS Poll frames,
 	 * FIF_CONTROL flag implies FIF_PSPOLL.
 	 */
-	if (!test_bit(DRIVER_SUPPORT_CONTROL_FILTERS, &rt2x00dev->flags)) {
+	if (!test_bit(CAPABILITY_CONTROL_FILTERS, &rt2x00dev->cap_flags)) {
 		if (*total_flags & FIF_CONTROL || *total_flags & FIF_PSPOLL)
 			*total_flags |= FIF_CONTROL | FIF_PSPOLL;
 	}
-	if (!test_bit(DRIVER_SUPPORT_CONTROL_FILTER_PSPOLL, &rt2x00dev->flags)) {
+	if (!test_bit(CAPABILITY_CONTROL_FILTER_PSPOLL, &rt2x00dev->cap_flags)) {
 		if (*total_flags & FIF_CONTROL)
 			*total_flags |= FIF_PSPOLL;
 	}
@@ -496,7 +496,7 @@
 
 	if (!test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags))
 		return 0;
-	else if (!test_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags))
+	else if (!test_bit(CAPABILITY_HW_CRYPTO, &rt2x00dev->cap_flags))
 		return -EOPNOTSUPP;
 	else if (key->keylen > 32)
 		return -ENOSPC;
@@ -562,7 +562,7 @@
 void rt2x00mac_sw_scan_start(struct ieee80211_hw *hw)
 {
 	struct rt2x00_dev *rt2x00dev = hw->priv;
-	__set_bit(DEVICE_STATE_SCANNING, &rt2x00dev->flags);
+	set_bit(DEVICE_STATE_SCANNING, &rt2x00dev->flags);
 	rt2x00link_stop_tuner(rt2x00dev);
 }
 EXPORT_SYMBOL_GPL(rt2x00mac_sw_scan_start);
@@ -570,7 +570,7 @@
 void rt2x00mac_sw_scan_complete(struct ieee80211_hw *hw)
 {
 	struct rt2x00_dev *rt2x00dev = hw->priv;
-	__clear_bit(DEVICE_STATE_SCANNING, &rt2x00dev->flags);
+	clear_bit(DEVICE_STATE_SCANNING, &rt2x00dev->flags);
 	rt2x00link_start_tuner(rt2x00dev);
 }
 EXPORT_SYMBOL_GPL(rt2x00mac_sw_scan_complete);
@@ -737,3 +737,84 @@
 		rt2x00queue_flush_queue(queue, drop);
 }
 EXPORT_SYMBOL_GPL(rt2x00mac_flush);
+
+int rt2x00mac_set_antenna(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant)
+{
+	struct rt2x00_dev *rt2x00dev = hw->priv;
+	struct link_ant *ant = &rt2x00dev->link.ant;
+	struct antenna_setup *def = &rt2x00dev->default_ant;
+	struct antenna_setup setup;
+
+	// The antenna value is not supposed to be 0,
+	// or exceed the maximum number of antenna's.
+	if (!tx_ant || (tx_ant & ~3) || !rx_ant || (rx_ant & ~3))
+		return -EINVAL;
+
+	// When the client tried to configure the antenna to or from
+	// diversity mode, we must reset the default antenna as well
+	// as that controls the diversity switch.
+	if (ant->flags & ANTENNA_TX_DIVERSITY && tx_ant != 3)
+		ant->flags &= ~ANTENNA_TX_DIVERSITY;
+	if (ant->flags & ANTENNA_RX_DIVERSITY && rx_ant != 3)
+		ant->flags &= ~ANTENNA_RX_DIVERSITY;
+
+	// If diversity is being enabled, check if we need hardware
+	// or software diversity. In the latter case, reset the value,
+	// and make sure we update the antenna flags to have the
+	// link tuner pick up the diversity tuning.
+	if (tx_ant == 3 && def->tx == ANTENNA_SW_DIVERSITY) {
+		tx_ant = ANTENNA_SW_DIVERSITY;
+		ant->flags |= ANTENNA_TX_DIVERSITY;
+	}
+
+	if (rx_ant == 3 && def->rx == ANTENNA_SW_DIVERSITY) {
+		rx_ant = ANTENNA_SW_DIVERSITY;
+		ant->flags |= ANTENNA_RX_DIVERSITY;
+	}
+
+	setup.tx = tx_ant;
+	setup.rx = rx_ant;
+
+	rt2x00lib_config_antenna(rt2x00dev, setup);
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(rt2x00mac_set_antenna);
+
+int rt2x00mac_get_antenna(struct ieee80211_hw *hw, u32 *tx_ant, u32 *rx_ant)
+{
+	struct rt2x00_dev *rt2x00dev = hw->priv;
+	struct link_ant *ant = &rt2x00dev->link.ant;
+	struct antenna_setup *active = &rt2x00dev->link.ant.active;
+
+	// When software diversity is active, we must report this to the
+	// client and not the current active antenna state.
+	if (ant->flags & ANTENNA_TX_DIVERSITY)
+		*tx_ant = ANTENNA_HW_DIVERSITY;
+	else
+		*tx_ant = active->tx;
+
+	if (ant->flags & ANTENNA_RX_DIVERSITY)
+		*rx_ant = ANTENNA_HW_DIVERSITY;
+	else
+		*rx_ant = active->rx;
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(rt2x00mac_get_antenna);
+
+void rt2x00mac_get_ringparam(struct ieee80211_hw *hw,
+			     u32 *tx, u32 *tx_max, u32 *rx, u32 *rx_max)
+{
+	struct rt2x00_dev *rt2x00dev = hw->priv;
+	struct data_queue *queue;
+
+	tx_queue_for_each(rt2x00dev, queue) {
+		*tx += queue->length;
+		*tx_max += queue->limit;
+	}
+
+	*rx = rt2x00dev->rx->length;
+	*rx_max = rt2x00dev->rx->limit;
+}
+EXPORT_SYMBOL_GPL(rt2x00mac_get_ringparam);
diff -druN linux-2.6.39-libre/drivers/net/wireless/rt2x00/rt2x00pci.c linux-3.0-rc7-libre/drivers/net/wireless/rt2x00/rt2x00pci.c
--- linux-2.6.39-libre/drivers/net/wireless/rt2x00/rt2x00pci.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/rt2x00/rt2x00pci.c	2011-07-11 19:51:52.000000000 -0400
@@ -60,14 +60,15 @@
 }
 EXPORT_SYMBOL_GPL(rt2x00pci_regbusy_read);
 
-void rt2x00pci_rxdone(struct rt2x00_dev *rt2x00dev)
+bool rt2x00pci_rxdone(struct rt2x00_dev *rt2x00dev)
 {
 	struct data_queue *queue = rt2x00dev->rx;
 	struct queue_entry *entry;
 	struct queue_entry_priv_pci *entry_priv;
 	struct skb_frame_desc *skbdesc;
+	int max_rx = 16;
 
-	while (1) {
+	while (--max_rx) {
 		entry = rt2x00queue_get_entry(queue, Q_INDEX);
 		entry_priv = entry->priv_data;
 
@@ -93,9 +94,20 @@
 		 */
 		rt2x00lib_rxdone(entry);
 	}
+
+	return !max_rx;
 }
 EXPORT_SYMBOL_GPL(rt2x00pci_rxdone);
 
+void rt2x00pci_flush_queue(struct data_queue *queue, bool drop)
+{
+	unsigned int i;
+
+	for (i = 0; !rt2x00queue_empty(queue) && i < 10; i++)
+		msleep(10);
+}
+EXPORT_SYMBOL_GPL(rt2x00pci_flush_queue);
+
 /*
  * Device initialization handlers.
  */
@@ -239,9 +251,8 @@
 	return -ENOMEM;
 }
 
-int rt2x00pci_probe(struct pci_dev *pci_dev, const struct pci_device_id *id)
+int rt2x00pci_probe(struct pci_dev *pci_dev, const struct rt2x00_ops *ops)
 {
-	struct rt2x00_ops *ops = (struct rt2x00_ops *)id->driver_data;
 	struct ieee80211_hw *hw;
 	struct rt2x00_dev *rt2x00dev;
 	int retval;
diff -druN linux-2.6.39-libre/drivers/net/wireless/rt2x00/rt2x00pci.h linux-3.0-rc7-libre/drivers/net/wireless/rt2x00/rt2x00pci.h
--- linux-2.6.39-libre/drivers/net/wireless/rt2x00/rt2x00pci.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/rt2x00/rt2x00pci.h	2011-07-11 19:51:52.000000000 -0400
@@ -101,8 +101,21 @@
 /**
  * rt2x00pci_rxdone - Handle RX done events
  * @rt2x00dev: Device pointer, see &struct rt2x00_dev.
+ *
+ * Returns true if there are still rx frames pending and false if all
+ * pending rx frames were processed.
  */
-void rt2x00pci_rxdone(struct rt2x00_dev *rt2x00dev);
+bool rt2x00pci_rxdone(struct rt2x00_dev *rt2x00dev);
+
+/**
+ * rt2x00pci_flush_queue - Flush data queue
+ * @queue: Data queue to stop
+ * @drop: True to drop all pending frames.
+ *
+ * This will wait for a maximum of 100ms, waiting for the queues
+ * to become empty.
+ */
+void rt2x00pci_flush_queue(struct data_queue *queue, bool drop);
 
 /*
  * Device initialization handlers.
@@ -113,7 +126,7 @@
 /*
  * PCI driver handlers.
  */
-int rt2x00pci_probe(struct pci_dev *pci_dev, const struct pci_device_id *id);
+int rt2x00pci_probe(struct pci_dev *pci_dev, const struct rt2x00_ops *ops);
 void rt2x00pci_remove(struct pci_dev *pci_dev);
 #ifdef CONFIG_PM
 int rt2x00pci_suspend(struct pci_dev *pci_dev, pm_message_t state);
diff -druN linux-2.6.39-libre/drivers/net/wireless/rt2x00/rt2x00queue.c linux-3.0-rc7-libre/drivers/net/wireless/rt2x00/rt2x00queue.c
--- linux-2.6.39-libre/drivers/net/wireless/rt2x00/rt2x00queue.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/rt2x00/rt2x00queue.c	2011-07-11 19:51:52.000000000 -0400
@@ -60,7 +60,7 @@
 	 * at least 8 bytes bytes available in headroom for IV/EIV
 	 * and 8 bytes for ICV data as tailroon.
 	 */
-	if (test_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags)) {
+	if (test_bit(CAPABILITY_HW_CRYPTO, &rt2x00dev->cap_flags)) {
 		head_size += 8;
 		tail_size += 8;
 	}
@@ -86,7 +86,7 @@
 	memset(skbdesc, 0, sizeof(*skbdesc));
 	skbdesc->entry = entry;
 
-	if (test_bit(DRIVER_REQUIRE_DMA, &rt2x00dev->flags)) {
+	if (test_bit(REQUIRE_DMA, &rt2x00dev->cap_flags)) {
 		skbdesc->skb_dma = dma_map_single(rt2x00dev->dev,
 						  skb->data,
 						  skb->len,
@@ -148,19 +148,6 @@
 	skb_trim(skb, frame_length);
 }
 
-void rt2x00queue_align_payload(struct sk_buff *skb, unsigned int header_length)
-{
-	unsigned int frame_length = skb->len;
-	unsigned int align = ALIGN_SIZE(skb, header_length);
-
-	if (!align)
-		return;
-
-	skb_push(skb, align);
-	memmove(skb->data, skb->data + align, frame_length);
-	skb_trim(skb, frame_length);
-}
-
 void rt2x00queue_insert_l2pad(struct sk_buff *skb, unsigned int header_length)
 {
 	unsigned int payload_length = skb->len - header_length;
@@ -226,7 +213,7 @@
 
 	__set_bit(ENTRY_TXD_GENERATE_SEQ, &txdesc->flags);
 
-	if (!test_bit(DRIVER_REQUIRE_SW_SEQNO, &entry->queue->rt2x00dev->flags))
+	if (!test_bit(REQUIRE_SW_SEQNO, &entry->queue->rt2x00dev->cap_flags))
 		return;
 
 	/*
@@ -315,6 +302,85 @@
 	}
 }
 
+static void rt2x00queue_create_tx_descriptor_ht(struct queue_entry *entry,
+						struct txentry_desc *txdesc,
+						const struct rt2x00_rate *hwrate)
+{
+	struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(entry->skb);
+	struct ieee80211_tx_rate *txrate = &tx_info->control.rates[0];
+	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)entry->skb->data;
+
+	if (tx_info->control.sta)
+		txdesc->u.ht.mpdu_density =
+		    tx_info->control.sta->ht_cap.ampdu_density;
+
+	txdesc->u.ht.ba_size = 7;	/* FIXME: What value is needed? */
+
+	/*
+	 * Only one STBC stream is supported for now.
+	 */
+	if (tx_info->flags & IEEE80211_TX_CTL_STBC)
+		txdesc->u.ht.stbc = 1;
+
+	/*
+	 * If IEEE80211_TX_RC_MCS is set txrate->idx just contains the
+	 * mcs rate to be used
+	 */
+	if (txrate->flags & IEEE80211_TX_RC_MCS) {
+		txdesc->u.ht.mcs = txrate->idx;
+
+		/*
+		 * MIMO PS should be set to 1 for STA's using dynamic SM PS
+		 * when using more then one tx stream (>MCS7).
+		 */
+		if (tx_info->control.sta && txdesc->u.ht.mcs > 7 &&
+		    ((tx_info->control.sta->ht_cap.cap &
+		      IEEE80211_HT_CAP_SM_PS) >>
+		     IEEE80211_HT_CAP_SM_PS_SHIFT) ==
+		    WLAN_HT_CAP_SM_PS_DYNAMIC)
+			__set_bit(ENTRY_TXD_HT_MIMO_PS, &txdesc->flags);
+	} else {
+		txdesc->u.ht.mcs = rt2x00_get_rate_mcs(hwrate->mcs);
+		if (txrate->flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE)
+			txdesc->u.ht.mcs |= 0x08;
+	}
+
+	/*
+	 * This frame is eligible for an AMPDU, however, don't aggregate
+	 * frames that are intended to probe a specific tx rate.
+	 */
+	if (tx_info->flags & IEEE80211_TX_CTL_AMPDU &&
+	    !(tx_info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE))
+		__set_bit(ENTRY_TXD_HT_AMPDU, &txdesc->flags);
+
+	/*
+	 * Set 40Mhz mode if necessary (for legacy rates this will
+	 * duplicate the frame to both channels).
+	 */
+	if (txrate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH ||
+	    txrate->flags & IEEE80211_TX_RC_DUP_DATA)
+		__set_bit(ENTRY_TXD_HT_BW_40, &txdesc->flags);
+	if (txrate->flags & IEEE80211_TX_RC_SHORT_GI)
+		__set_bit(ENTRY_TXD_HT_SHORT_GI, &txdesc->flags);
+
+	/*
+	 * Determine IFS values
+	 * - Use TXOP_BACKOFF for management frames except beacons
+	 * - Use TXOP_SIFS for fragment bursts
+	 * - Use TXOP_HTTXOP for everything else
+	 *
+	 * Note: rt2800 devices won't use CTS protection (if used)
+	 * for frames not transmitted with TXOP_HTTXOP
+	 */
+	if (ieee80211_is_mgmt(hdr->frame_control) &&
+	    !ieee80211_is_beacon(hdr->frame_control))
+		txdesc->u.ht.txop = TXOP_BACKOFF;
+	else if (!(tx_info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT))
+		txdesc->u.ht.txop = TXOP_SIFS;
+	else
+		txdesc->u.ht.txop = TXOP_HTTXOP;
+}
+
 static void rt2x00queue_create_tx_descriptor(struct queue_entry *entry,
 					     struct txentry_desc *txdesc)
 {
@@ -409,8 +475,8 @@
 	rt2x00crypto_create_tx_descriptor(entry, txdesc);
 	rt2x00queue_create_tx_descriptor_seq(entry, txdesc);
 
-	if (test_bit(DRIVER_REQUIRE_HT_TX_DESC, &rt2x00dev->flags))
-		rt2x00ht_create_tx_descriptor(entry, txdesc, hwrate);
+	if (test_bit(REQUIRE_HT_TX_DESC, &rt2x00dev->cap_flags))
+		rt2x00queue_create_tx_descriptor_ht(entry, txdesc, hwrate);
 	else
 		rt2x00queue_create_tx_descriptor_plcp(entry, txdesc, hwrate);
 }
@@ -449,7 +515,7 @@
 	/*
 	 * Map the skb to DMA.
 	 */
-	if (test_bit(DRIVER_REQUIRE_DMA, &rt2x00dev->flags))
+	if (test_bit(REQUIRE_DMA, &rt2x00dev->cap_flags))
 		rt2x00queue_map_txskb(entry);
 
 	return 0;
@@ -495,8 +561,11 @@
 	struct skb_frame_desc *skbdesc;
 	u8 rate_idx, rate_flags;
 
-	if (unlikely(rt2x00queue_full(queue)))
+	if (unlikely(rt2x00queue_full(queue))) {
+		ERROR(queue->rt2x00dev,
+		      "Dropping frame due to full tx queue %d.\n", queue->qid);
 		return -ENOBUFS;
+	}
 
 	if (unlikely(test_and_set_bit(ENTRY_OWNER_DEVICE_DATA,
 				      &entry->flags))) {
@@ -539,7 +608,7 @@
 	 */
 	if (test_bit(ENTRY_TXD_ENCRYPT, &txdesc.flags) &&
 	    !test_bit(ENTRY_TXD_ENCRYPT_IV, &txdesc.flags)) {
-		if (test_bit(DRIVER_REQUIRE_COPY_IV, &queue->rt2x00dev->flags))
+		if (test_bit(REQUIRE_COPY_IV, &queue->rt2x00dev->cap_flags))
 			rt2x00crypto_tx_copy_iv(skb, &txdesc);
 		else
 			rt2x00crypto_tx_remove_iv(skb, &txdesc);
@@ -553,9 +622,9 @@
 	 * PCI and USB devices, while header alignment only is valid
 	 * for PCI devices.
 	 */
-	if (test_bit(DRIVER_REQUIRE_L2PAD, &queue->rt2x00dev->flags))
+	if (test_bit(REQUIRE_L2PAD, &queue->rt2x00dev->cap_flags))
 		rt2x00queue_insert_l2pad(entry->skb, txdesc.header_length);
-	else if (test_bit(DRIVER_REQUIRE_DMA, &queue->rt2x00dev->flags))
+	else if (test_bit(REQUIRE_DMA, &queue->rt2x00dev->cap_flags))
 		rt2x00queue_align_frame(entry->skb);
 
 	/*
@@ -571,7 +640,7 @@
 
 	set_bit(ENTRY_DATA_PENDING, &entry->flags);
 
-	rt2x00queue_index_inc(queue, Q_INDEX);
+	rt2x00queue_index_inc(entry, Q_INDEX);
 	rt2x00queue_write_tx_descriptor(entry, &txdesc);
 	rt2x00queue_kick_tx_queue(queue, &txdesc);
 
@@ -660,10 +729,12 @@
 	return ret;
 }
 
-void rt2x00queue_for_each_entry(struct data_queue *queue,
+bool rt2x00queue_for_each_entry(struct data_queue *queue,
 				enum queue_index start,
 				enum queue_index end,
-				void (*fn)(struct queue_entry *entry))
+				void *data,
+				bool (*fn)(struct queue_entry *entry,
+					   void *data))
 {
 	unsigned long irqflags;
 	unsigned int index_start;
@@ -674,7 +745,7 @@
 		ERROR(queue->rt2x00dev,
 		      "Entry requested from invalid index range (%d - %d)\n",
 		      start, end);
-		return;
+		return true;
 	}
 
 	/*
@@ -693,15 +764,23 @@
 	 * send out all frames in the correct order.
 	 */
 	if (index_start < index_end) {
-		for (i = index_start; i < index_end; i++)
-			fn(&queue->entries[i]);
+		for (i = index_start; i < index_end; i++) {
+			if (fn(&queue->entries[i], data))
+				return true;
+		}
 	} else {
-		for (i = index_start; i < queue->limit; i++)
-			fn(&queue->entries[i]);
+		for (i = index_start; i < queue->limit; i++) {
+			if (fn(&queue->entries[i], data))
+				return true;
+		}
 
-		for (i = 0; i < index_end; i++)
-			fn(&queue->entries[i]);
+		for (i = 0; i < index_end; i++) {
+			if (fn(&queue->entries[i], data))
+				return true;
+		}
 	}
+
+	return false;
 }
 EXPORT_SYMBOL_GPL(rt2x00queue_for_each_entry);
 
@@ -727,8 +806,9 @@
 }
 EXPORT_SYMBOL_GPL(rt2x00queue_get_entry);
 
-void rt2x00queue_index_inc(struct data_queue *queue, enum queue_index index)
+void rt2x00queue_index_inc(struct queue_entry *entry, enum queue_index index)
 {
+	struct data_queue *queue = entry->queue;
 	unsigned long irqflags;
 
 	if (unlikely(index >= Q_INDEX_MAX)) {
@@ -743,7 +823,7 @@
 	if (queue->index[index] >= queue->limit)
 		queue->index[index] = 0;
 
-	queue->last_action[index] = jiffies;
+	entry->last_action = jiffies;
 
 	if (index == Q_INDEX) {
 		queue->length++;
@@ -848,7 +928,6 @@
 
 void rt2x00queue_flush_queue(struct data_queue *queue, bool drop)
 {
-	unsigned int i;
 	bool started;
 	bool tx_queue =
 		(queue->qid == QID_AC_VO) ||
@@ -883,20 +962,12 @@
 	}
 
 	/*
-	 * Check if driver supports flushing, we can only guarantee
-	 * full support for flushing if the driver is able
-	 * to cancel all pending frames (drop = true).
-	 */
-	if (drop && queue->rt2x00dev->ops->lib->flush_queue)
-		queue->rt2x00dev->ops->lib->flush_queue(queue);
-
-	/*
-	 * When we don't want to drop any frames, or when
-	 * the driver doesn't fully flush the queue correcly,
-	 * we must wait for the queue to become empty.
+	 * Check if driver supports flushing, if that is the case we can
+	 * defer the flushing to the driver. Otherwise we must use the
+	 * alternative which just waits for the queue to become empty.
 	 */
-	for (i = 0; !rt2x00queue_empty(queue) && i < 100; i++)
-		msleep(10);
+	if (likely(queue->rt2x00dev->ops->lib->flush_queue))
+		queue->rt2x00dev->ops->lib->flush_queue(queue, drop);
 
 	/*
 	 * The queue flush has failed...
@@ -969,10 +1040,8 @@
 	queue->count = 0;
 	queue->length = 0;
 
-	for (i = 0; i < Q_INDEX_MAX; i++) {
+	for (i = 0; i < Q_INDEX_MAX; i++)
 		queue->index[i] = 0;
-		queue->last_action[i] = jiffies;
-	}
 
 	spin_unlock_irqrestore(&queue->index_lock, irqflags);
 }
@@ -1079,7 +1148,7 @@
 	if (status)
 		goto exit;
 
-	if (test_bit(DRIVER_REQUIRE_ATIM_QUEUE, &rt2x00dev->flags)) {
+	if (test_bit(REQUIRE_ATIM_QUEUE, &rt2x00dev->cap_flags)) {
 		status = rt2x00queue_alloc_entries(rt2x00dev->atim,
 						   rt2x00dev->ops->atim);
 		if (status)
@@ -1131,7 +1200,7 @@
 	struct data_queue *queue;
 	enum data_queue_qid qid;
 	unsigned int req_atim =
-	    !!test_bit(DRIVER_REQUIRE_ATIM_QUEUE, &rt2x00dev->flags);
+	    !!test_bit(REQUIRE_ATIM_QUEUE, &rt2x00dev->cap_flags);
 
 	/*
 	 * We need the following queues:
diff -druN linux-2.6.39-libre/drivers/net/wireless/rt2x00/rt2x00queue.h linux-3.0-rc7-libre/drivers/net/wireless/rt2x00/rt2x00queue.h
--- linux-2.6.39-libre/drivers/net/wireless/rt2x00/rt2x00queue.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/rt2x00/rt2x00queue.h	2011-07-11 19:51:52.000000000 -0400
@@ -217,6 +217,7 @@
 	TXDONE_FALLBACK,
 	TXDONE_FAILURE,
 	TXDONE_EXCESSIVE_RETRY,
+	TXDONE_AMPDU,
 };
 
 /**
@@ -363,6 +364,7 @@
  * struct queue_entry: Entry inside the &struct data_queue
  *
  * @flags: Entry flags, see &enum queue_entry_flags.
+ * @last_action: Timestamp of last change.
  * @queue: The data queue (&struct data_queue) to which this entry belongs.
  * @skb: The buffer which is currently being transmitted (for TX queue),
  *	or used to directly receive data in (for RX queue).
@@ -372,6 +374,7 @@
  */
 struct queue_entry {
 	unsigned long flags;
+	unsigned long last_action;
 
 	struct data_queue *queue;
 
@@ -462,7 +465,6 @@
 	unsigned short threshold;
 	unsigned short length;
 	unsigned short index[Q_INDEX_MAX];
-	unsigned long last_action[Q_INDEX_MAX];
 
 	unsigned short txop;
 	unsigned short aifs;
@@ -579,16 +581,22 @@
  * @queue: Pointer to @data_queue
  * @start: &enum queue_index Pointer to start index
  * @end: &enum queue_index Pointer to end index
+ * @data: Data to pass to the callback function
  * @fn: The function to call for each &struct queue_entry
  *
  * This will walk through all entries in the queue, in chronological
  * order. This means it will start at the current @start pointer
  * and will walk through the queue until it reaches the @end pointer.
+ *
+ * If fn returns true for an entry rt2x00queue_for_each_entry will stop
+ * processing and return true as well.
  */
-void rt2x00queue_for_each_entry(struct data_queue *queue,
+bool rt2x00queue_for_each_entry(struct data_queue *queue,
 				enum queue_index start,
 				enum queue_index end,
-				void (*fn)(struct queue_entry *entry));
+				void *data,
+				bool (*fn)(struct queue_entry *entry,
+					   void *data));
 
 /**
  * rt2x00queue_empty - Check if the queue is empty.
@@ -628,22 +636,24 @@
 
 /**
  * rt2x00queue_status_timeout - Check if a timeout occurred for STATUS reports
- * @queue: Queue to check.
+ * @entry: Queue entry to check.
  */
-static inline int rt2x00queue_status_timeout(struct data_queue *queue)
+static inline int rt2x00queue_status_timeout(struct queue_entry *entry)
 {
-	return time_after(queue->last_action[Q_INDEX_DMA_DONE],
-			  queue->last_action[Q_INDEX_DONE] + (HZ / 10));
+	if (!test_bit(ENTRY_DATA_STATUS_PENDING, &entry->flags))
+		return false;
+	return time_after(jiffies, entry->last_action + msecs_to_jiffies(100));
 }
 
 /**
- * rt2x00queue_timeout - Check if a timeout occurred for DMA transfers
- * @queue: Queue to check.
+ * rt2x00queue_dma_timeout - Check if a timeout occurred for DMA transfers
+ * @entry: Queue entry to check.
  */
-static inline int rt2x00queue_dma_timeout(struct data_queue *queue)
+static inline int rt2x00queue_dma_timeout(struct queue_entry *entry)
 {
-	return time_after(queue->last_action[Q_INDEX],
-			  queue->last_action[Q_INDEX_DMA_DONE] + (HZ / 10));
+	if (!test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags))
+		return false;
+	return time_after(jiffies, entry->last_action + msecs_to_jiffies(100));
 }
 
 /**
diff -druN linux-2.6.39-libre/drivers/net/wireless/rt2x00/rt2x00usb.c linux-3.0-rc7-libre/drivers/net/wireless/rt2x00/rt2x00usb.c
--- linux-2.6.39-libre/drivers/net/wireless/rt2x00/rt2x00usb.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/rt2x00/rt2x00usb.c	2011-07-11 19:51:52.000000000 -0400
@@ -165,6 +165,59 @@
 }
 EXPORT_SYMBOL_GPL(rt2x00usb_regbusy_read);
 
+
+struct rt2x00_async_read_data {
+	__le32 reg;
+	struct usb_ctrlrequest cr;
+	struct rt2x00_dev *rt2x00dev;
+	bool (*callback)(struct rt2x00_dev *, int, u32);
+};
+
+static void rt2x00usb_register_read_async_cb(struct urb *urb)
+{
+	struct rt2x00_async_read_data *rd = urb->context;
+	if (rd->callback(rd->rt2x00dev, urb->status, le32_to_cpu(rd->reg))) {
+		if (usb_submit_urb(urb, GFP_ATOMIC) < 0)
+			kfree(rd);
+	} else
+		kfree(rd);
+}
+
+void rt2x00usb_register_read_async(struct rt2x00_dev *rt2x00dev,
+				   const unsigned int offset,
+				   bool (*callback)(struct rt2x00_dev*, int, u32))
+{
+	struct usb_device *usb_dev = to_usb_device_intf(rt2x00dev->dev);
+	struct urb *urb;
+	struct rt2x00_async_read_data *rd;
+
+	rd = kmalloc(sizeof(*rd), GFP_ATOMIC);
+	if (!rd)
+		return;
+
+	urb = usb_alloc_urb(0, GFP_ATOMIC);
+	if (!urb) {
+		kfree(rd);
+		return;
+	}
+
+	rd->rt2x00dev = rt2x00dev;
+	rd->callback = callback;
+	rd->cr.bRequestType = USB_VENDOR_REQUEST_IN;
+	rd->cr.bRequest = USB_MULTI_READ;
+	rd->cr.wValue = 0;
+	rd->cr.wIndex = cpu_to_le16(offset);
+	rd->cr.wLength = cpu_to_le16(sizeof(u32));
+
+	usb_fill_control_urb(urb, usb_dev, usb_rcvctrlpipe(usb_dev, 0),
+			     (unsigned char *)(&rd->cr), &rd->reg, sizeof(rd->reg),
+			     rt2x00usb_register_read_async_cb, rd);
+	if (usb_submit_urb(urb, GFP_ATOMIC) < 0)
+		kfree(rd);
+	usb_free_urb(urb);
+}
+EXPORT_SYMBOL_GPL(rt2x00usb_register_read_async);
+
 /*
  * TX data handlers.
  */
@@ -212,6 +265,9 @@
 	if (!test_and_clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags))
 		return;
 
+	if (rt2x00dev->ops->lib->tx_dma_done)
+		rt2x00dev->ops->lib->tx_dma_done(entry);
+
 	/*
 	 * Report the frame as DMA done
 	 */
@@ -227,10 +283,12 @@
 	 * Schedule the delayed work for reading the TX status
 	 * from the device.
 	 */
-	queue_work(rt2x00dev->workqueue, &rt2x00dev->txdone_work);
+	if (!test_bit(REQUIRE_TXSTATUS_FIFO, &rt2x00dev->cap_flags) ||
+	    !kfifo_is_empty(&rt2x00dev->txstatus_fifo))
+		queue_work(rt2x00dev->workqueue, &rt2x00dev->txdone_work);
 }
 
-static void rt2x00usb_kick_tx_entry(struct queue_entry *entry)
+static bool rt2x00usb_kick_tx_entry(struct queue_entry *entry, void* data)
 {
 	struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
 	struct usb_device *usb_dev = to_usb_device_intf(rt2x00dev->dev);
@@ -240,7 +298,7 @@
 
 	if (!test_and_clear_bit(ENTRY_DATA_PENDING, &entry->flags) ||
 	    test_bit(ENTRY_DATA_STATUS_PENDING, &entry->flags))
-		return;
+		return false;
 
 	/*
 	 * USB devices cannot blindly pass the skb->len as the
@@ -261,6 +319,8 @@
 		set_bit(ENTRY_DATA_IO_FAILED, &entry->flags);
 		rt2x00lib_dmadone(entry);
 	}
+
+	return false;
 }
 
 /*
@@ -323,7 +383,7 @@
 	queue_work(rt2x00dev->workqueue, &rt2x00dev->rxdone_work);
 }
 
-static void rt2x00usb_kick_rx_entry(struct queue_entry *entry)
+static bool rt2x00usb_kick_rx_entry(struct queue_entry *entry, void* data)
 {
 	struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
 	struct usb_device *usb_dev = to_usb_device_intf(rt2x00dev->dev);
@@ -332,7 +392,7 @@
 
 	if (test_and_set_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags) ||
 	    test_bit(ENTRY_DATA_STATUS_PENDING, &entry->flags))
-		return;
+		return false;
 
 	rt2x00lib_dmastart(entry);
 
@@ -348,6 +408,8 @@
 		set_bit(ENTRY_DATA_IO_FAILED, &entry->flags);
 		rt2x00lib_dmadone(entry);
 	}
+
+	return false;
 }
 
 void rt2x00usb_kick_queue(struct data_queue *queue)
@@ -358,12 +420,18 @@
 	case QID_AC_BE:
 	case QID_AC_BK:
 		if (!rt2x00queue_empty(queue))
-			rt2x00queue_for_each_entry(queue, Q_INDEX_DONE, Q_INDEX,
+			rt2x00queue_for_each_entry(queue,
+						   Q_INDEX_DONE,
+						   Q_INDEX,
+						   NULL,
 						   rt2x00usb_kick_tx_entry);
 		break;
 	case QID_RX:
 		if (!rt2x00queue_full(queue))
-			rt2x00queue_for_each_entry(queue, Q_INDEX_DONE, Q_INDEX,
+			rt2x00queue_for_each_entry(queue,
+						   Q_INDEX_DONE,
+						   Q_INDEX,
+						   NULL,
 						   rt2x00usb_kick_rx_entry);
 		break;
 	default:
@@ -372,14 +440,14 @@
 }
 EXPORT_SYMBOL_GPL(rt2x00usb_kick_queue);
 
-static void rt2x00usb_flush_entry(struct queue_entry *entry)
+static bool rt2x00usb_flush_entry(struct queue_entry *entry, void* data)
 {
 	struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
 	struct queue_entry_priv_usb *entry_priv = entry->priv_data;
 	struct queue_entry_priv_usb_bcn *bcn_priv = entry->priv_data;
 
 	if (!test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags))
-		return;
+		return false;
 
 	usb_kill_urb(entry_priv->urb);
 
@@ -387,17 +455,20 @@
 	 * Kill guardian urb (if required by driver).
 	 */
 	if ((entry->queue->qid == QID_BEACON) &&
-	    (test_bit(DRIVER_REQUIRE_BEACON_GUARD, &rt2x00dev->flags)))
+	    (test_bit(REQUIRE_BEACON_GUARD, &rt2x00dev->cap_flags)))
 		usb_kill_urb(bcn_priv->guardian_urb);
+
+	return false;
 }
 
-void rt2x00usb_flush_queue(struct data_queue *queue)
+void rt2x00usb_flush_queue(struct data_queue *queue, bool drop)
 {
 	struct work_struct *completion;
 	unsigned int i;
 
-	rt2x00queue_for_each_entry(queue, Q_INDEX_DONE, Q_INDEX,
-				   rt2x00usb_flush_entry);
+	if (drop)
+		rt2x00queue_for_each_entry(queue, Q_INDEX_DONE, Q_INDEX, NULL,
+					   rt2x00usb_flush_entry);
 
 	/*
 	 * Obtain the queue completion handler
@@ -416,7 +487,7 @@
 		return;
 	}
 
-	for (i = 0; i < 20; i++) {
+	for (i = 0; i < 10; i++) {
 		/*
 		 * Check if the driver is already done, otherwise we
 		 * have to sleep a little while to give the driver/hw
@@ -456,15 +527,31 @@
 	queue_work(queue->rt2x00dev->workqueue, &queue->rt2x00dev->txdone_work);
 }
 
+static int rt2x00usb_status_timeout(struct data_queue *queue)
+{
+	struct queue_entry *entry;
+
+	entry = rt2x00queue_get_entry(queue, Q_INDEX_DONE);
+	return rt2x00queue_status_timeout(entry);
+}
+
+static int rt2x00usb_dma_timeout(struct data_queue *queue)
+{
+	struct queue_entry *entry;
+
+	entry = rt2x00queue_get_entry(queue, Q_INDEX_DMA_DONE);
+	return rt2x00queue_dma_timeout(entry);
+}
+
 void rt2x00usb_watchdog(struct rt2x00_dev *rt2x00dev)
 {
 	struct data_queue *queue;
 
 	tx_queue_for_each(rt2x00dev, queue) {
 		if (!rt2x00queue_empty(queue)) {
-			if (rt2x00queue_dma_timeout(queue))
+			if (rt2x00usb_dma_timeout(queue))
 				rt2x00usb_watchdog_tx_dma(queue);
-			if (rt2x00queue_status_timeout(queue))
+			if (rt2x00usb_status_timeout(queue))
 				rt2x00usb_watchdog_tx_status(queue);
 		}
 	}
@@ -489,7 +576,7 @@
 	entry->flags = 0;
 
 	if (entry->queue->qid == QID_RX)
-		rt2x00usb_kick_rx_entry(entry);
+		rt2x00usb_kick_rx_entry(entry, NULL);
 }
 EXPORT_SYMBOL_GPL(rt2x00usb_clear_entry);
 
@@ -583,7 +670,7 @@
 	 * then we are done.
 	 */
 	if (queue->qid != QID_BEACON ||
-	    !test_bit(DRIVER_REQUIRE_BEACON_GUARD, &rt2x00dev->flags))
+	    !test_bit(REQUIRE_BEACON_GUARD, &rt2x00dev->cap_flags))
 		return 0;
 
 	for (i = 0; i < queue->limit; i++) {
@@ -618,7 +705,7 @@
 	 * then we are done.
 	 */
 	if (queue->qid != QID_BEACON ||
-	    !test_bit(DRIVER_REQUIRE_BEACON_GUARD, &rt2x00dev->flags))
+	    !test_bit(REQUIRE_BEACON_GUARD, &rt2x00dev->cap_flags))
 		return;
 
 	for (i = 0; i < queue->limit; i++) {
@@ -707,10 +794,9 @@
 }
 
 int rt2x00usb_probe(struct usb_interface *usb_intf,
-		    const struct usb_device_id *id)
+		    const struct rt2x00_ops *ops)
 {
 	struct usb_device *usb_dev = interface_to_usbdev(usb_intf);
-	struct rt2x00_ops *ops = (struct rt2x00_ops *)id->driver_info;
 	struct ieee80211_hw *hw;
 	struct rt2x00_dev *rt2x00dev;
 	int retval;
@@ -735,6 +821,7 @@
 
 	INIT_WORK(&rt2x00dev->rxdone_work, rt2x00usb_work_rxdone);
 	INIT_WORK(&rt2x00dev->txdone_work, rt2x00usb_work_txdone);
+	init_timer(&rt2x00dev->txstatus_timer);
 
 	retval = rt2x00usb_alloc_reg(rt2x00dev);
 	if (retval)
diff -druN linux-2.6.39-libre/drivers/net/wireless/rt2x00/rt2x00usb.h linux-3.0-rc7-libre/drivers/net/wireless/rt2x00/rt2x00usb.h
--- linux-2.6.39-libre/drivers/net/wireless/rt2x00/rt2x00usb.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/rt2x00/rt2x00usb.h	2011-07-11 19:51:52.000000000 -0400
@@ -35,12 +35,6 @@
 })
 
 /*
- * This variable should be used with the
- * usb_driver structure initialization.
- */
-#define USB_DEVICE_DATA(__ops)	.driver_info = (kernel_ulong_t)(__ops)
-
-/*
  * For USB vendor requests we need to pass a timeout
  * time in ms, for this we use the REGISTER_TIMEOUT,
  * however when loading firmware a higher value is
@@ -345,6 +339,23 @@
 			   const struct rt2x00_field32 field,
 			   u32 *reg);
 
+/**
+ * rt2x00usb_register_read_async - Asynchronously read 32bit register word
+ * @rt2x00dev: Device pointer, see &struct rt2x00_dev.
+ * @offset: Register offset
+ * @callback: Functon to call when read completes.
+ *
+ * Submit a control URB to read a 32bit register. This safe to
+ * be called from atomic context.  The callback will be called
+ * when the URB completes. Otherwise the function is similar
+ * to rt2x00usb_register_read().
+ * When the callback function returns false, the memory will be cleaned up,
+ * when it returns true, the urb will be fired again.
+ */
+void rt2x00usb_register_read_async(struct rt2x00_dev *rt2x00dev,
+				   const unsigned int offset,
+				   bool (*callback)(struct rt2x00_dev*, int, u32));
+
 /*
  * Radio handlers
  */
@@ -389,11 +400,13 @@
 /**
  * rt2x00usb_flush_queue - Flush data queue
  * @queue: Data queue to stop
+ * @drop: True to drop all pending frames.
  *
- * This will walk through all entries of the queue and kill all
- * URB's which were send to the device.
+ * This will walk through all entries of the queue and will optionally
+ * kill all URB's which were send to the device, or at least wait until
+ * they have been returned from the device..
  */
-void rt2x00usb_flush_queue(struct data_queue *queue);
+void rt2x00usb_flush_queue(struct data_queue *queue, bool drop);
 
 /**
  * rt2x00usb_watchdog - Watchdog for USB communication
@@ -416,7 +429,7 @@
  * USB driver handlers.
  */
 int rt2x00usb_probe(struct usb_interface *usb_intf,
-		    const struct usb_device_id *id);
+		    const struct rt2x00_ops *ops);
 void rt2x00usb_disconnect(struct usb_interface *usb_intf);
 #ifdef CONFIG_PM
 int rt2x00usb_suspend(struct usb_interface *usb_intf, pm_message_t state);
diff -druN linux-2.6.39-libre/drivers/net/wireless/rt2x00/rt61pci.c linux-3.0-rc7-libre/drivers/net/wireless/rt2x00/rt61pci.c
--- linux-2.6.39-libre/drivers/net/wireless/rt2x00/rt61pci.c	2011-05-19 02:15:32.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/rt2x00/rt61pci.c	2011-07-21 06:57:49.000000000 -0400
@@ -683,7 +683,7 @@
 
 	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));
+			  !test_bit(CAPABILITY_FRAME_TYPE, &rt2x00dev->cap_flags));
 
 	/*
 	 * Configure the RX antenna.
@@ -811,10 +811,10 @@
 
 	if (rt2x00dev->curr_band == IEEE80211_BAND_5GHZ) {
 		sel = antenna_sel_a;
-		lna = test_bit(CONFIG_EXTERNAL_LNA_A, &rt2x00dev->flags);
+		lna = test_bit(CAPABILITY_EXTERNAL_LNA_A, &rt2x00dev->cap_flags);
 	} else {
 		sel = antenna_sel_bg;
-		lna = test_bit(CONFIG_EXTERNAL_LNA_BG, &rt2x00dev->flags);
+		lna = test_bit(CAPABILITY_EXTERNAL_LNA_BG, &rt2x00dev->cap_flags);
 	}
 
 	for (i = 0; i < ARRAY_SIZE(antenna_sel_a); i++)
@@ -834,7 +834,7 @@
 	else if (rt2x00_rf(rt2x00dev, RF2527))
 		rt61pci_config_antenna_2x(rt2x00dev, ant);
 	else if (rt2x00_rf(rt2x00dev, RF2529)) {
-		if (test_bit(CONFIG_DOUBLE_ANTENNA, &rt2x00dev->flags))
+		if (test_bit(CAPABILITY_DOUBLE_ANTENNA, &rt2x00dev->cap_flags))
 			rt61pci_config_antenna_2x(rt2x00dev, ant);
 		else
 			rt61pci_config_antenna_2529(rt2x00dev, ant);
@@ -848,13 +848,13 @@
 	short lna_gain = 0;
 
 	if (libconf->conf->channel->band == IEEE80211_BAND_2GHZ) {
-		if (test_bit(CONFIG_EXTERNAL_LNA_BG, &rt2x00dev->flags))
+		if (test_bit(CAPABILITY_EXTERNAL_LNA_BG, &rt2x00dev->cap_flags))
 			lna_gain += 14;
 
 		rt2x00_eeprom_read(rt2x00dev, EEPROM_RSSI_OFFSET_BG, &eeprom);
 		lna_gain -= rt2x00_get_field16(eeprom, EEPROM_RSSI_OFFSET_BG_1);
 	} else {
-		if (test_bit(CONFIG_EXTERNAL_LNA_A, &rt2x00dev->flags))
+		if (test_bit(CAPABILITY_EXTERNAL_LNA_A, &rt2x00dev->cap_flags))
 			lna_gain += 14;
 
 		rt2x00_eeprom_read(rt2x00dev, EEPROM_RSSI_OFFSET_A, &eeprom);
@@ -1050,14 +1050,14 @@
 	if (rt2x00dev->curr_band == IEEE80211_BAND_5GHZ) {
 		low_bound = 0x28;
 		up_bound = 0x48;
-		if (test_bit(CONFIG_EXTERNAL_LNA_A, &rt2x00dev->flags)) {
+		if (test_bit(CAPABILITY_EXTERNAL_LNA_A, &rt2x00dev->cap_flags)) {
 			low_bound += 0x10;
 			up_bound += 0x10;
 		}
 	} else {
 		low_bound = 0x20;
 		up_bound = 0x40;
-		if (test_bit(CONFIG_EXTERNAL_LNA_BG, &rt2x00dev->flags)) {
+		if (test_bit(CAPABILITY_EXTERNAL_LNA_BG, &rt2x00dev->cap_flags)) {
 			low_bound += 0x10;
 			up_bound += 0x10;
 		}
@@ -2260,8 +2260,8 @@
 	rt61pci_config(rt2x00dev, &libconf, IEEE80211_CONF_CHANGE_PS);
 }
 
-static void rt61pci_enable_interrupt(struct rt2x00_dev *rt2x00dev,
-				     struct rt2x00_field32 irq_field)
+static inline void rt61pci_enable_interrupt(struct rt2x00_dev *rt2x00dev,
+					    struct rt2x00_field32 irq_field)
 {
 	u32 reg;
 
@@ -2313,8 +2313,10 @@
 static void rt61pci_rxdone_tasklet(unsigned long data)
 {
 	struct rt2x00_dev *rt2x00dev = (struct rt2x00_dev *)data;
-	rt2x00pci_rxdone(rt2x00dev);
-	rt61pci_enable_interrupt(rt2x00dev, INT_MASK_CSR_RXDONE);
+	if (rt2x00pci_rxdone(rt2x00dev))
+		rt2x00pci_rxdone(rt2x00dev);
+	else
+		rt61pci_enable_interrupt(rt2x00dev, INT_MASK_CSR_RXDONE);
 }
 
 static void rt61pci_autowake_tasklet(unsigned long data)
@@ -2535,7 +2537,7 @@
 	 * Determine number of antennas.
 	 */
 	if (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_NUM) == 2)
-		__set_bit(CONFIG_DOUBLE_ANTENNA, &rt2x00dev->flags);
+		__set_bit(CAPABILITY_DOUBLE_ANTENNA, &rt2x00dev->cap_flags);
 
 	/*
 	 * Identify default antenna configuration.
@@ -2549,20 +2551,20 @@
 	 * Read the Frame type.
 	 */
 	if (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_FRAME_TYPE))
-		__set_bit(CONFIG_FRAME_TYPE, &rt2x00dev->flags);
+		__set_bit(CAPABILITY_FRAME_TYPE, &rt2x00dev->cap_flags);
 
 	/*
 	 * Detect if this device has a hardware controlled radio.
 	 */
 	if (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_HARDWARE_RADIO))
-		__set_bit(CONFIG_SUPPORT_HW_BUTTON, &rt2x00dev->flags);
+		__set_bit(CAPABILITY_HW_BUTTON, &rt2x00dev->cap_flags);
 
 	/*
 	 * Read frequency offset and RF programming sequence.
 	 */
 	rt2x00_eeprom_read(rt2x00dev, EEPROM_FREQ, &eeprom);
 	if (rt2x00_get_field16(eeprom, EEPROM_FREQ_SEQ))
-		__set_bit(CONFIG_RF_SEQUENCE, &rt2x00dev->flags);
+		__set_bit(CAPABILITY_RF_SEQUENCE, &rt2x00dev->cap_flags);
 
 	rt2x00dev->freq_offset = rt2x00_get_field16(eeprom, EEPROM_FREQ_OFFSET);
 
@@ -2572,9 +2574,9 @@
 	rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC, &eeprom);
 
 	if (rt2x00_get_field16(eeprom, EEPROM_NIC_EXTERNAL_LNA_A))
-		__set_bit(CONFIG_EXTERNAL_LNA_A, &rt2x00dev->flags);
+		__set_bit(CAPABILITY_EXTERNAL_LNA_A, &rt2x00dev->cap_flags);
 	if (rt2x00_get_field16(eeprom, EEPROM_NIC_EXTERNAL_LNA_BG))
-		__set_bit(CONFIG_EXTERNAL_LNA_BG, &rt2x00dev->flags);
+		__set_bit(CAPABILITY_EXTERNAL_LNA_BG, &rt2x00dev->cap_flags);
 
 	/*
 	 * When working with a RF2529 chip without double antenna,
@@ -2582,7 +2584,7 @@
 	 * eeprom word.
 	 */
 	if (rt2x00_rf(rt2x00dev, RF2529) &&
-	    !test_bit(CONFIG_DOUBLE_ANTENNA, &rt2x00dev->flags)) {
+	    !test_bit(CAPABILITY_DOUBLE_ANTENNA, &rt2x00dev->cap_flags)) {
 		rt2x00dev->default_ant.rx =
 		    ANTENNA_A + rt2x00_get_field16(eeprom, EEPROM_NIC_RX_FIXED);
 		rt2x00dev->default_ant.tx =
@@ -2797,7 +2799,7 @@
 	spec->supported_bands = SUPPORT_BAND_2GHZ;
 	spec->supported_rates = SUPPORT_RATE_CCK | SUPPORT_RATE_OFDM;
 
-	if (!test_bit(CONFIG_RF_SEQUENCE, &rt2x00dev->flags)) {
+	if (!test_bit(CAPABILITY_RF_SEQUENCE, &rt2x00dev->cap_flags)) {
 		spec->num_channels = 14;
 		spec->channels = rf_vals_noseq;
 	} else {
@@ -2867,16 +2869,16 @@
 	 * This device has multiple filters for control frames,
 	 * but has no a separate filter for PS Poll frames.
 	 */
-	__set_bit(DRIVER_SUPPORT_CONTROL_FILTERS, &rt2x00dev->flags);
+	__set_bit(CAPABILITY_CONTROL_FILTERS, &rt2x00dev->cap_flags);
 
 	/*
 	 * This device requires firmware and DMA mapped skbs.
 	 */
-	__set_bit(DRIVER_REQUIRE_FIRMWARE, &rt2x00dev->flags);
-	__set_bit(DRIVER_REQUIRE_DMA, &rt2x00dev->flags);
+	__set_bit(REQUIRE_FIRMWARE, &rt2x00dev->cap_flags);
+	__set_bit(REQUIRE_DMA, &rt2x00dev->cap_flags);
 	if (!modparam_nohwcrypt)
-		__set_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags);
-	__set_bit(DRIVER_SUPPORT_LINK_TUNING, &rt2x00dev->flags);
+		__set_bit(CAPABILITY_HW_CRYPTO, &rt2x00dev->cap_flags);
+	__set_bit(CAPABILITY_LINK_TUNING, &rt2x00dev->cap_flags);
 
 	/*
 	 * Set the rssi offset.
@@ -2977,6 +2979,9 @@
 	.get_tsf		= rt61pci_get_tsf,
 	.rfkill_poll		= rt2x00mac_rfkill_poll,
 	.flush			= rt2x00mac_flush,
+	.set_antenna		= rt2x00mac_set_antenna,
+	.get_antenna		= rt2x00mac_get_antenna,
+	.get_ringparam		= rt2x00mac_get_ringparam,
 };
 
 static const struct rt2x00lib_ops rt61pci_rt2x00_ops = {
@@ -3001,6 +3006,7 @@
 	.start_queue		= rt61pci_start_queue,
 	.kick_queue		= rt61pci_kick_queue,
 	.stop_queue		= rt61pci_stop_queue,
+	.flush_queue		= rt2x00pci_flush_queue,
 	.write_tx_desc		= rt61pci_write_tx_desc,
 	.write_beacon		= rt61pci_write_beacon,
 	.clear_beacon		= rt61pci_clear_beacon,
@@ -3058,11 +3064,11 @@
  */
 static DEFINE_PCI_DEVICE_TABLE(rt61pci_device_table) = {
 	/* RT2561s */
-	{ PCI_DEVICE(0x1814, 0x0301), PCI_DEVICE_DATA(&rt61pci_ops) },
+	{ PCI_DEVICE(0x1814, 0x0301) },
 	/* RT2561 v2 */
-	{ PCI_DEVICE(0x1814, 0x0302), PCI_DEVICE_DATA(&rt61pci_ops) },
+	{ PCI_DEVICE(0x1814, 0x0302) },
 	/* RT2661 */
-	{ PCI_DEVICE(0x1814, 0x0401), PCI_DEVICE_DATA(&rt61pci_ops) },
+	{ PCI_DEVICE(0x1814, 0x0401) },
 	{ 0, }
 };
 
@@ -3075,10 +3081,16 @@
 /*(DEBLOBBED)*/
 MODULE_LICENSE("GPL");
 
+static int rt61pci_probe(struct pci_dev *pci_dev,
+			 const struct pci_device_id *id)
+{
+	return rt2x00pci_probe(pci_dev, &rt61pci_ops);
+}
+
 static struct pci_driver rt61pci_driver = {
 	.name		= KBUILD_MODNAME,
 	.id_table	= rt61pci_device_table,
-	.probe		= rt2x00pci_probe,
+	.probe		= rt61pci_probe,
 	.remove		= __devexit_p(rt2x00pci_remove),
 	.suspend	= rt2x00pci_suspend,
 	.resume		= rt2x00pci_resume,
diff -druN linux-2.6.39-libre/drivers/net/wireless/rt2x00/rt73usb.c linux-3.0-rc7-libre/drivers/net/wireless/rt2x00/rt73usb.c
--- linux-2.6.39-libre/drivers/net/wireless/rt2x00/rt73usb.c	2011-05-19 02:15:38.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/rt2x00/rt73usb.c	2011-07-21 06:57:54.000000000 -0400
@@ -595,7 +595,7 @@
 	switch (ant->rx) {
 	case ANTENNA_HW_DIVERSITY:
 		rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA_CONTROL, 2);
-		temp = !test_bit(CONFIG_FRAME_TYPE, &rt2x00dev->flags)
+		temp = !test_bit(CAPABILITY_FRAME_TYPE, &rt2x00dev->cap_flags)
 		       && (rt2x00dev->curr_band != IEEE80211_BAND_5GHZ);
 		rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END, temp);
 		break;
@@ -636,7 +636,7 @@
 
 	rt2x00_set_field8(&r3, BBP_R3_SMART_MODE, 0);
 	rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END,
-			  !test_bit(CONFIG_FRAME_TYPE, &rt2x00dev->flags));
+			  !test_bit(CAPABILITY_FRAME_TYPE, &rt2x00dev->cap_flags));
 
 	/*
 	 * Configure the RX antenna.
@@ -709,10 +709,10 @@
 
 	if (rt2x00dev->curr_band == IEEE80211_BAND_5GHZ) {
 		sel = antenna_sel_a;
-		lna = test_bit(CONFIG_EXTERNAL_LNA_A, &rt2x00dev->flags);
+		lna = test_bit(CAPABILITY_EXTERNAL_LNA_A, &rt2x00dev->cap_flags);
 	} else {
 		sel = antenna_sel_bg;
-		lna = test_bit(CONFIG_EXTERNAL_LNA_BG, &rt2x00dev->flags);
+		lna = test_bit(CAPABILITY_EXTERNAL_LNA_BG, &rt2x00dev->cap_flags);
 	}
 
 	for (i = 0; i < ARRAY_SIZE(antenna_sel_a); i++)
@@ -740,7 +740,7 @@
 	short lna_gain = 0;
 
 	if (libconf->conf->channel->band == IEEE80211_BAND_2GHZ) {
-		if (test_bit(CONFIG_EXTERNAL_LNA_BG, &rt2x00dev->flags))
+		if (test_bit(CAPABILITY_EXTERNAL_LNA_BG, &rt2x00dev->cap_flags))
 			lna_gain += 14;
 
 		rt2x00_eeprom_read(rt2x00dev, EEPROM_RSSI_OFFSET_BG, &eeprom);
@@ -930,7 +930,7 @@
 		low_bound = 0x28;
 		up_bound = 0x48;
 
-		if (test_bit(CONFIG_EXTERNAL_LNA_A, &rt2x00dev->flags)) {
+		if (test_bit(CAPABILITY_EXTERNAL_LNA_A, &rt2x00dev->cap_flags)) {
 			low_bound += 0x10;
 			up_bound += 0x10;
 		}
@@ -946,7 +946,7 @@
 			up_bound = 0x1c;
 		}
 
-		if (test_bit(CONFIG_EXTERNAL_LNA_BG, &rt2x00dev->flags)) {
+		if (test_bit(CAPABILITY_EXTERNAL_LNA_BG, &rt2x00dev->cap_flags)) {
 			low_bound += 0x14;
 			up_bound += 0x10;
 		}
@@ -1661,7 +1661,7 @@
 	}
 
 	if (rt2x00dev->curr_band == IEEE80211_BAND_5GHZ) {
-		if (test_bit(CONFIG_EXTERNAL_LNA_A, &rt2x00dev->flags)) {
+		if (test_bit(CAPABILITY_EXTERNAL_LNA_A, &rt2x00dev->cap_flags)) {
 			if (lna == 3 || lna == 2)
 				offset += 10;
 		} else {
@@ -1899,13 +1899,13 @@
 	 * Read the Frame type.
 	 */
 	if (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_FRAME_TYPE))
-		__set_bit(CONFIG_FRAME_TYPE, &rt2x00dev->flags);
+		__set_bit(CAPABILITY_FRAME_TYPE, &rt2x00dev->cap_flags);
 
 	/*
 	 * Detect if this device has an hardware controlled radio.
 	 */
 	if (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_HARDWARE_RADIO))
-		__set_bit(CONFIG_SUPPORT_HW_BUTTON, &rt2x00dev->flags);
+		__set_bit(CAPABILITY_HW_BUTTON, &rt2x00dev->cap_flags);
 
 	/*
 	 * Read frequency offset.
@@ -1919,8 +1919,8 @@
 	rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC, &eeprom);
 
 	if (rt2x00_get_field16(eeprom, EEPROM_NIC_EXTERNAL_LNA)) {
-		__set_bit(CONFIG_EXTERNAL_LNA_A, &rt2x00dev->flags);
-		__set_bit(CONFIG_EXTERNAL_LNA_BG, &rt2x00dev->flags);
+		__set_bit(CAPABILITY_EXTERNAL_LNA_A, &rt2x00dev->cap_flags);
+		__set_bit(CAPABILITY_EXTERNAL_LNA_BG, &rt2x00dev->cap_flags);
 	}
 
 	/*
@@ -2200,16 +2200,16 @@
 	 * This device has multiple filters for control frames,
 	 * but has no a separate filter for PS Poll frames.
 	 */
-	__set_bit(DRIVER_SUPPORT_CONTROL_FILTERS, &rt2x00dev->flags);
+	__set_bit(CAPABILITY_CONTROL_FILTERS, &rt2x00dev->cap_flags);
 
 	/*
 	 * This device requires firmware.
 	 */
-	__set_bit(DRIVER_REQUIRE_FIRMWARE, &rt2x00dev->flags);
+	__set_bit(REQUIRE_FIRMWARE, &rt2x00dev->cap_flags);
 	if (!modparam_nohwcrypt)
-		__set_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags);
-	__set_bit(DRIVER_SUPPORT_LINK_TUNING, &rt2x00dev->flags);
-	__set_bit(DRIVER_SUPPORT_WATCHDOG, &rt2x00dev->flags);
+		__set_bit(CAPABILITY_HW_CRYPTO, &rt2x00dev->cap_flags);
+	__set_bit(CAPABILITY_LINK_TUNING, &rt2x00dev->cap_flags);
+	__set_bit(REQUIRE_PS_AUTOWAKE, &rt2x00dev->cap_flags);
 
 	/*
 	 * Set the rssi offset.
@@ -2311,6 +2311,9 @@
 	.get_tsf		= rt73usb_get_tsf,
 	.rfkill_poll		= rt2x00mac_rfkill_poll,
 	.flush			= rt2x00mac_flush,
+	.set_antenna		= rt2x00mac_set_antenna,
+	.get_antenna		= rt2x00mac_get_antenna,
+	.get_ringparam		= rt2x00mac_get_ringparam,
 };
 
 static const struct rt2x00lib_ops rt73usb_rt2x00_ops = {
@@ -2389,114 +2392,113 @@
  */
 static struct usb_device_id rt73usb_device_table[] = {
 	/* AboCom */
-	{ USB_DEVICE(0x07b8, 0xb21b), USB_DEVICE_DATA(&rt73usb_ops) },
-	{ USB_DEVICE(0x07b8, 0xb21c), USB_DEVICE_DATA(&rt73usb_ops) },
-	{ USB_DEVICE(0x07b8, 0xb21d), USB_DEVICE_DATA(&rt73usb_ops) },
-	{ USB_DEVICE(0x07b8, 0xb21e), USB_DEVICE_DATA(&rt73usb_ops) },
-	{ USB_DEVICE(0x07b8, 0xb21f), USB_DEVICE_DATA(&rt73usb_ops) },
+	{ USB_DEVICE(0x07b8, 0xb21b) },
+	{ USB_DEVICE(0x07b8, 0xb21c) },
+	{ USB_DEVICE(0x07b8, 0xb21d) },
+	{ USB_DEVICE(0x07b8, 0xb21e) },
+	{ USB_DEVICE(0x07b8, 0xb21f) },
 	/* AL */
-	{ USB_DEVICE(0x14b2, 0x3c10), USB_DEVICE_DATA(&rt73usb_ops) },
+	{ USB_DEVICE(0x14b2, 0x3c10) },
 	/* Amigo */
-	{ USB_DEVICE(0x148f, 0x9021), USB_DEVICE_DATA(&rt73usb_ops) },
-	{ USB_DEVICE(0x0eb0, 0x9021), USB_DEVICE_DATA(&rt73usb_ops) },
+	{ USB_DEVICE(0x148f, 0x9021) },
+	{ USB_DEVICE(0x0eb0, 0x9021) },
 	/* AMIT  */
-	{ USB_DEVICE(0x18c5, 0x0002), USB_DEVICE_DATA(&rt73usb_ops) },
+	{ USB_DEVICE(0x18c5, 0x0002) },
 	/* Askey */
-	{ USB_DEVICE(0x1690, 0x0722), USB_DEVICE_DATA(&rt73usb_ops) },
+	{ USB_DEVICE(0x1690, 0x0722) },
 	/* ASUS */
-	{ USB_DEVICE(0x0b05, 0x1723), USB_DEVICE_DATA(&rt73usb_ops) },
-	{ USB_DEVICE(0x0b05, 0x1724), USB_DEVICE_DATA(&rt73usb_ops) },
+	{ USB_DEVICE(0x0b05, 0x1723) },
+	{ USB_DEVICE(0x0b05, 0x1724) },
 	/* Belkin */
-	{ USB_DEVICE(0x050d, 0x7050), USB_DEVICE_DATA(&rt73usb_ops) },
-	{ USB_DEVICE(0x050d, 0x705a), USB_DEVICE_DATA(&rt73usb_ops) },
-	{ USB_DEVICE(0x050d, 0x905b), USB_DEVICE_DATA(&rt73usb_ops) },
-	{ USB_DEVICE(0x050d, 0x905c), USB_DEVICE_DATA(&rt73usb_ops) },
+	{ USB_DEVICE(0x050d, 0x705a) },
+	{ USB_DEVICE(0x050d, 0x905b) },
+	{ USB_DEVICE(0x050d, 0x905c) },
 	/* Billionton */
-	{ USB_DEVICE(0x1631, 0xc019), USB_DEVICE_DATA(&rt73usb_ops) },
-	{ USB_DEVICE(0x08dd, 0x0120), USB_DEVICE_DATA(&rt73usb_ops) },
+	{ USB_DEVICE(0x1631, 0xc019) },
+	{ USB_DEVICE(0x08dd, 0x0120) },
 	/* 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) },
-	{ USB_DEVICE(0x0411, 0x0137), USB_DEVICE_DATA(&rt73usb_ops) },
+	{ USB_DEVICE(0x0411, 0x00d8) },
+	{ USB_DEVICE(0x0411, 0x00d9) },
+	{ USB_DEVICE(0x0411, 0x00f4) },
+	{ USB_DEVICE(0x0411, 0x0116) },
+	{ USB_DEVICE(0x0411, 0x0119) },
+	{ USB_DEVICE(0x0411, 0x0137) },
 	/* CEIVA */
-	{ USB_DEVICE(0x178d, 0x02be), USB_DEVICE_DATA(&rt73usb_ops) },
+	{ USB_DEVICE(0x178d, 0x02be) },
 	/* CNet */
-	{ USB_DEVICE(0x1371, 0x9022), USB_DEVICE_DATA(&rt73usb_ops) },
-	{ USB_DEVICE(0x1371, 0x9032), USB_DEVICE_DATA(&rt73usb_ops) },
+	{ USB_DEVICE(0x1371, 0x9022) },
+	{ USB_DEVICE(0x1371, 0x9032) },
 	/* Conceptronic */
-	{ USB_DEVICE(0x14b2, 0x3c22), USB_DEVICE_DATA(&rt73usb_ops) },
+	{ USB_DEVICE(0x14b2, 0x3c22) },
 	/* Corega */
-	{ USB_DEVICE(0x07aa, 0x002e), USB_DEVICE_DATA(&rt73usb_ops) },
+	{ USB_DEVICE(0x07aa, 0x002e) },
 	/* D-Link */
-	{ USB_DEVICE(0x07d1, 0x3c03), USB_DEVICE_DATA(&rt73usb_ops) },
-	{ USB_DEVICE(0x07d1, 0x3c04), USB_DEVICE_DATA(&rt73usb_ops) },
-	{ USB_DEVICE(0x07d1, 0x3c06), USB_DEVICE_DATA(&rt73usb_ops) },
-	{ USB_DEVICE(0x07d1, 0x3c07), USB_DEVICE_DATA(&rt73usb_ops) },
+	{ USB_DEVICE(0x07d1, 0x3c03) },
+	{ USB_DEVICE(0x07d1, 0x3c04) },
+	{ USB_DEVICE(0x07d1, 0x3c06) },
+	{ USB_DEVICE(0x07d1, 0x3c07) },
 	/* Edimax */
-	{ USB_DEVICE(0x7392, 0x7318), USB_DEVICE_DATA(&rt73usb_ops) },
-	{ USB_DEVICE(0x7392, 0x7618), USB_DEVICE_DATA(&rt73usb_ops) },
+	{ USB_DEVICE(0x7392, 0x7318) },
+	{ USB_DEVICE(0x7392, 0x7618) },
 	/* EnGenius */
-	{ USB_DEVICE(0x1740, 0x3701), USB_DEVICE_DATA(&rt73usb_ops) },
+	{ USB_DEVICE(0x1740, 0x3701) },
 	/* Gemtek */
-	{ USB_DEVICE(0x15a9, 0x0004), USB_DEVICE_DATA(&rt73usb_ops) },
+	{ USB_DEVICE(0x15a9, 0x0004) },
 	/* Gigabyte */
-	{ USB_DEVICE(0x1044, 0x8008), USB_DEVICE_DATA(&rt73usb_ops) },
-	{ USB_DEVICE(0x1044, 0x800a), USB_DEVICE_DATA(&rt73usb_ops) },
+	{ USB_DEVICE(0x1044, 0x8008) },
+	{ USB_DEVICE(0x1044, 0x800a) },
 	/* Huawei-3Com */
-	{ USB_DEVICE(0x1472, 0x0009), USB_DEVICE_DATA(&rt73usb_ops) },
+	{ USB_DEVICE(0x1472, 0x0009) },
 	/* Hercules */
-	{ USB_DEVICE(0x06f8, 0xe002), USB_DEVICE_DATA(&rt73usb_ops) },
-	{ USB_DEVICE(0x06f8, 0xe010), USB_DEVICE_DATA(&rt73usb_ops) },
-	{ USB_DEVICE(0x06f8, 0xe020), USB_DEVICE_DATA(&rt73usb_ops) },
+	{ USB_DEVICE(0x06f8, 0xe002) },
+	{ USB_DEVICE(0x06f8, 0xe010) },
+	{ USB_DEVICE(0x06f8, 0xe020) },
 	/* Linksys */
-	{ USB_DEVICE(0x13b1, 0x0020), USB_DEVICE_DATA(&rt73usb_ops) },
-	{ USB_DEVICE(0x13b1, 0x0023), USB_DEVICE_DATA(&rt73usb_ops) },
-	{ USB_DEVICE(0x13b1, 0x0028), USB_DEVICE_DATA(&rt73usb_ops) },
+	{ USB_DEVICE(0x13b1, 0x0020) },
+	{ USB_DEVICE(0x13b1, 0x0023) },
+	{ USB_DEVICE(0x13b1, 0x0028) },
 	/* MSI */
-	{ USB_DEVICE(0x0db0, 0x4600), USB_DEVICE_DATA(&rt73usb_ops) },
-	{ USB_DEVICE(0x0db0, 0x6877), USB_DEVICE_DATA(&rt73usb_ops) },
-	{ USB_DEVICE(0x0db0, 0x6874), USB_DEVICE_DATA(&rt73usb_ops) },
-	{ USB_DEVICE(0x0db0, 0xa861), USB_DEVICE_DATA(&rt73usb_ops) },
-	{ USB_DEVICE(0x0db0, 0xa874), USB_DEVICE_DATA(&rt73usb_ops) },
+	{ USB_DEVICE(0x0db0, 0x4600) },
+	{ USB_DEVICE(0x0db0, 0x6877) },
+	{ USB_DEVICE(0x0db0, 0x6874) },
+	{ USB_DEVICE(0x0db0, 0xa861) },
+	{ USB_DEVICE(0x0db0, 0xa874) },
 	/* Ovislink */
-	{ USB_DEVICE(0x1b75, 0x7318), USB_DEVICE_DATA(&rt73usb_ops) },
+	{ USB_DEVICE(0x1b75, 0x7318) },
 	/* Ralink */
-	{ USB_DEVICE(0x04bb, 0x093d), USB_DEVICE_DATA(&rt73usb_ops) },
-	{ USB_DEVICE(0x148f, 0x2573), USB_DEVICE_DATA(&rt73usb_ops) },
-	{ USB_DEVICE(0x148f, 0x2671), USB_DEVICE_DATA(&rt73usb_ops) },
-	{ USB_DEVICE(0x0812, 0x3101), USB_DEVICE_DATA(&rt73usb_ops) },
+	{ USB_DEVICE(0x04bb, 0x093d) },
+	{ USB_DEVICE(0x148f, 0x2573) },
+	{ USB_DEVICE(0x148f, 0x2671) },
+	{ USB_DEVICE(0x0812, 0x3101) },
 	/* Qcom */
-	{ USB_DEVICE(0x18e8, 0x6196), USB_DEVICE_DATA(&rt73usb_ops) },
-	{ USB_DEVICE(0x18e8, 0x6229), USB_DEVICE_DATA(&rt73usb_ops) },
-	{ USB_DEVICE(0x18e8, 0x6238), USB_DEVICE_DATA(&rt73usb_ops) },
+	{ USB_DEVICE(0x18e8, 0x6196) },
+	{ USB_DEVICE(0x18e8, 0x6229) },
+	{ USB_DEVICE(0x18e8, 0x6238) },
 	/* Samsung */
-	{ USB_DEVICE(0x04e8, 0x4471), USB_DEVICE_DATA(&rt73usb_ops) },
+	{ USB_DEVICE(0x04e8, 0x4471) },
 	/* Senao */
-	{ USB_DEVICE(0x1740, 0x7100), USB_DEVICE_DATA(&rt73usb_ops) },
+	{ USB_DEVICE(0x1740, 0x7100) },
 	/* Sitecom */
-	{ USB_DEVICE(0x0df6, 0x0024), USB_DEVICE_DATA(&rt73usb_ops) },
-	{ USB_DEVICE(0x0df6, 0x0027), USB_DEVICE_DATA(&rt73usb_ops) },
-	{ USB_DEVICE(0x0df6, 0x002f), USB_DEVICE_DATA(&rt73usb_ops) },
-	{ USB_DEVICE(0x0df6, 0x90ac), USB_DEVICE_DATA(&rt73usb_ops) },
-	{ USB_DEVICE(0x0df6, 0x9712), USB_DEVICE_DATA(&rt73usb_ops) },
+	{ USB_DEVICE(0x0df6, 0x0024) },
+	{ USB_DEVICE(0x0df6, 0x0027) },
+	{ USB_DEVICE(0x0df6, 0x002f) },
+	{ USB_DEVICE(0x0df6, 0x90ac) },
+	{ USB_DEVICE(0x0df6, 0x9712) },
 	/* Surecom */
-	{ USB_DEVICE(0x0769, 0x31f3), USB_DEVICE_DATA(&rt73usb_ops) },
+	{ USB_DEVICE(0x0769, 0x31f3) },
 	/* Tilgin */
-	{ USB_DEVICE(0x6933, 0x5001), USB_DEVICE_DATA(&rt73usb_ops) },
+	{ USB_DEVICE(0x6933, 0x5001) },
 	/* Philips */
-	{ USB_DEVICE(0x0471, 0x200a), USB_DEVICE_DATA(&rt73usb_ops) },
+	{ USB_DEVICE(0x0471, 0x200a) },
 	/* Planex */
-	{ USB_DEVICE(0x2019, 0xab01), USB_DEVICE_DATA(&rt73usb_ops) },
-	{ USB_DEVICE(0x2019, 0xab50), USB_DEVICE_DATA(&rt73usb_ops) },
+	{ USB_DEVICE(0x2019, 0xab01) },
+	{ USB_DEVICE(0x2019, 0xab50) },
 	/* WideTell */
-	{ USB_DEVICE(0x7167, 0x3840), USB_DEVICE_DATA(&rt73usb_ops) },
+	{ USB_DEVICE(0x7167, 0x3840) },
 	/* Zcom */
-	{ USB_DEVICE(0x0cde, 0x001c), USB_DEVICE_DATA(&rt73usb_ops) },
+	{ USB_DEVICE(0x0cde, 0x001c) },
 	/* ZyXEL */
-	{ USB_DEVICE(0x0586, 0x3415), USB_DEVICE_DATA(&rt73usb_ops) },
+	{ USB_DEVICE(0x0586, 0x3415) },
 	{ 0, }
 };
 
@@ -2508,10 +2510,16 @@
 /*(DEBLOBBED)*/
 MODULE_LICENSE("GPL");
 
+static int rt73usb_probe(struct usb_interface *usb_intf,
+			 const struct usb_device_id *id)
+{
+	return rt2x00usb_probe(usb_intf, &rt73usb_ops);
+}
+
 static struct usb_driver rt73usb_driver = {
 	.name		= KBUILD_MODNAME,
 	.id_table	= rt73usb_device_table,
-	.probe		= rt2x00usb_probe,
+	.probe		= rt73usb_probe,
 	.disconnect	= rt2x00usb_disconnect,
 	.suspend	= rt2x00usb_suspend,
 	.resume		= rt2x00usb_resume,
diff -druN linux-2.6.39-libre/drivers/net/wireless/rtlwifi/base.c linux-3.0-rc7-libre/drivers/net/wireless/rtlwifi/base.c
--- linux-2.6.39-libre/drivers/net/wireless/rtlwifi/base.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/rtlwifi/base.c	2011-07-11 19:51:52.000000000 -0400
@@ -50,8 +50,9 @@
  *3) functions called by core.c
  *4) wq & timer callback functions
  *5) frame process functions
- *6) sysfs functions
- *7) ...
+ *6) IOT functions
+ *7) sysfs functions
+ *8) ...
  */
 
 /*********************************************************
@@ -59,7 +60,7 @@
  * mac80211 init functions
  *
  *********************************************************/
-static struct ieee80211_channel rtl_channeltable[] = {
+static struct ieee80211_channel rtl_channeltable_2g[] = {
 	{.center_freq = 2412, .hw_value = 1,},
 	{.center_freq = 2417, .hw_value = 2,},
 	{.center_freq = 2422, .hw_value = 3,},
@@ -76,7 +77,34 @@
 	{.center_freq = 2484, .hw_value = 14,},
 };
 
-static struct ieee80211_rate rtl_ratetable[] = {
+static struct ieee80211_channel rtl_channeltable_5g[] = {
+	{.center_freq = 5180, .hw_value = 36,},
+	{.center_freq = 5200, .hw_value = 40,},
+	{.center_freq = 5220, .hw_value = 44,},
+	{.center_freq = 5240, .hw_value = 48,},
+	{.center_freq = 5260, .hw_value = 52,},
+	{.center_freq = 5280, .hw_value = 56,},
+	{.center_freq = 5300, .hw_value = 60,},
+	{.center_freq = 5320, .hw_value = 64,},
+	{.center_freq = 5500, .hw_value = 100,},
+	{.center_freq = 5520, .hw_value = 104,},
+	{.center_freq = 5540, .hw_value = 108,},
+	{.center_freq = 5560, .hw_value = 112,},
+	{.center_freq = 5580, .hw_value = 116,},
+	{.center_freq = 5600, .hw_value = 120,},
+	{.center_freq = 5620, .hw_value = 124,},
+	{.center_freq = 5640, .hw_value = 128,},
+	{.center_freq = 5660, .hw_value = 132,},
+	{.center_freq = 5680, .hw_value = 136,},
+	{.center_freq = 5700, .hw_value = 140,},
+	{.center_freq = 5745, .hw_value = 149,},
+	{.center_freq = 5765, .hw_value = 153,},
+	{.center_freq = 5785, .hw_value = 157,},
+	{.center_freq = 5805, .hw_value = 161,},
+	{.center_freq = 5825, .hw_value = 165,},
+};
+
+static struct ieee80211_rate rtl_ratetable_2g[] = {
 	{.bitrate = 10, .hw_value = 0x00,},
 	{.bitrate = 20, .hw_value = 0x01,},
 	{.bitrate = 55, .hw_value = 0x02,},
@@ -91,18 +119,57 @@
 	{.bitrate = 540, .hw_value = 0x0b,},
 };
 
+static struct ieee80211_rate rtl_ratetable_5g[] = {
+	{.bitrate = 60, .hw_value = 0x04,},
+	{.bitrate = 90, .hw_value = 0x05,},
+	{.bitrate = 120, .hw_value = 0x06,},
+	{.bitrate = 180, .hw_value = 0x07,},
+	{.bitrate = 240, .hw_value = 0x08,},
+	{.bitrate = 360, .hw_value = 0x09,},
+	{.bitrate = 480, .hw_value = 0x0a,},
+	{.bitrate = 540, .hw_value = 0x0b,},
+};
+
 static const struct ieee80211_supported_band rtl_band_2ghz = {
 	.band = IEEE80211_BAND_2GHZ,
 
-	.channels = rtl_channeltable,
-	.n_channels = ARRAY_SIZE(rtl_channeltable),
+	.channels = rtl_channeltable_2g,
+	.n_channels = ARRAY_SIZE(rtl_channeltable_2g),
 
-	.bitrates = rtl_ratetable,
-	.n_bitrates = ARRAY_SIZE(rtl_ratetable),
+	.bitrates = rtl_ratetable_2g,
+	.n_bitrates = ARRAY_SIZE(rtl_ratetable_2g),
 
 	.ht_cap = {0},
 };
 
+static struct ieee80211_supported_band rtl_band_5ghz = {
+	.band = IEEE80211_BAND_5GHZ,
+
+	.channels = rtl_channeltable_5g,
+	.n_channels = ARRAY_SIZE(rtl_channeltable_5g),
+
+	.bitrates = rtl_ratetable_5g,
+	.n_bitrates = ARRAY_SIZE(rtl_ratetable_5g),
+
+	.ht_cap = {0},
+};
+
+static const u8 tid_to_ac[] = {
+	2, /* IEEE80211_AC_BE */
+	3, /* IEEE80211_AC_BK */
+	3, /* IEEE80211_AC_BK */
+	2, /* IEEE80211_AC_BE */
+	1, /* IEEE80211_AC_VI */
+	1, /* IEEE80211_AC_VI */
+	0, /* IEEE80211_AC_VO */
+	0, /* IEEE80211_AC_VO */
+};
+
+u8 rtl_tid_to_ac(struct ieee80211_hw *hw, u8 tid)
+{
+	return tid_to_ac[tid];
+}
+
 static void _rtl_init_hw_ht_capab(struct ieee80211_hw *hw,
 				  struct ieee80211_sta_ht_cap *ht_cap)
 {
@@ -115,6 +182,9 @@
 	    IEEE80211_HT_CAP_SGI_20 |
 	    IEEE80211_HT_CAP_DSSSCCK40 | IEEE80211_HT_CAP_MAX_AMSDU;
 
+	if (rtlpriv->rtlhal.disable_amsdu_8k)
+		ht_cap->cap &= ~IEEE80211_HT_CAP_MAX_AMSDU;
+
 	/*
 	 *Maximum length of AMPDU that the STA can receive.
 	 *Length = 2 ^ (13 + max_ampdu_length_exp) - 1 (octets)
@@ -159,37 +229,99 @@
 
 static void _rtl_init_mac80211(struct ieee80211_hw *hw)
 {
+	struct rtl_priv *rtlpriv = rtl_priv(hw);
+	struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
 	struct rtl_mac *rtlmac = rtl_mac(rtl_priv(hw));
 	struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
 	struct ieee80211_supported_band *sband;
 
-	/* <1> use  mac->bands as mem for hw->wiphy->bands */
-	sband = &(rtlmac->bands[IEEE80211_BAND_2GHZ]);
 
-	/*
-	 * <2> set hw->wiphy->bands[IEEE80211_BAND_2GHZ]
-	 * to default value(1T1R)
-	 */
-	memcpy(&(rtlmac->bands[IEEE80211_BAND_2GHZ]), &rtl_band_2ghz,
-	       sizeof(struct ieee80211_supported_band));
+	if (rtlhal->macphymode == SINGLEMAC_SINGLEPHY && rtlhal->bandset ==
+	    BAND_ON_BOTH) {
+		/* 1: 2.4 G bands */
+		/* <1> use  mac->bands as mem for hw->wiphy->bands */
+		sband = &(rtlmac->bands[IEEE80211_BAND_2GHZ]);
 
-	/* <3> init ht cap base on ant_num */
-	_rtl_init_hw_ht_capab(hw, &sband->ht_cap);
+		/* <2> set hw->wiphy->bands[IEEE80211_BAND_2GHZ]
+		 * to default value(1T1R) */
+		memcpy(&(rtlmac->bands[IEEE80211_BAND_2GHZ]), &rtl_band_2ghz,
+				sizeof(struct ieee80211_supported_band));
 
-	/* <4> set mac->sband to wiphy->sband */
-	hw->wiphy->bands[IEEE80211_BAND_2GHZ] = sband;
+		/* <3> init ht cap base on ant_num */
+		_rtl_init_hw_ht_capab(hw, &sband->ht_cap);
+
+		/* <4> set mac->sband to wiphy->sband */
+		hw->wiphy->bands[IEEE80211_BAND_2GHZ] = sband;
+
+		/* 2: 5 G bands */
+		/* <1> use  mac->bands as mem for hw->wiphy->bands */
+		sband = &(rtlmac->bands[IEEE80211_BAND_5GHZ]);
+
+		/* <2> set hw->wiphy->bands[IEEE80211_BAND_5GHZ]
+		 * to default value(1T1R) */
+		memcpy(&(rtlmac->bands[IEEE80211_BAND_5GHZ]), &rtl_band_5ghz,
+				sizeof(struct ieee80211_supported_band));
+
+		/* <3> init ht cap base on ant_num */
+		_rtl_init_hw_ht_capab(hw, &sband->ht_cap);
 
+		/* <4> set mac->sband to wiphy->sband */
+		hw->wiphy->bands[IEEE80211_BAND_5GHZ] = sband;
+	} else {
+		if (rtlhal->current_bandtype == BAND_ON_2_4G) {
+			/* <1> use  mac->bands as mem for hw->wiphy->bands */
+			sband = &(rtlmac->bands[IEEE80211_BAND_2GHZ]);
+
+			/* <2> set hw->wiphy->bands[IEEE80211_BAND_2GHZ]
+			 * to default value(1T1R) */
+			memcpy(&(rtlmac->bands[IEEE80211_BAND_2GHZ]),
+				 &rtl_band_2ghz,
+				 sizeof(struct ieee80211_supported_band));
+
+			/* <3> init ht cap base on ant_num */
+			_rtl_init_hw_ht_capab(hw, &sband->ht_cap);
+
+			/* <4> set mac->sband to wiphy->sband */
+			hw->wiphy->bands[IEEE80211_BAND_2GHZ] = sband;
+		} else if (rtlhal->current_bandtype == BAND_ON_5G) {
+			/* <1> use  mac->bands as mem for hw->wiphy->bands */
+			sband = &(rtlmac->bands[IEEE80211_BAND_5GHZ]);
+
+			/* <2> set hw->wiphy->bands[IEEE80211_BAND_5GHZ]
+			 * to default value(1T1R) */
+			memcpy(&(rtlmac->bands[IEEE80211_BAND_5GHZ]),
+				 &rtl_band_5ghz,
+				 sizeof(struct ieee80211_supported_band));
+
+			/* <3> init ht cap base on ant_num */
+			_rtl_init_hw_ht_capab(hw, &sband->ht_cap);
+
+			/* <4> set mac->sband to wiphy->sband */
+			hw->wiphy->bands[IEEE80211_BAND_5GHZ] = sband;
+		} else {
+			RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG,
+				 ("Err BAND %d\n",
+				 rtlhal->current_bandtype));
+		}
+	}
 	/* <5> set hw caps */
 	hw->flags = IEEE80211_HW_SIGNAL_DBM |
 	    IEEE80211_HW_RX_INCLUDES_FCS |
-	    IEEE80211_HW_BEACON_FILTER | IEEE80211_HW_AMPDU_AGGREGATION | /*PS*/
-	    /*IEEE80211_HW_SUPPORTS_PS | */
-	    /*IEEE80211_HW_PS_NULLFUNC_STACK | */
-	    /*IEEE80211_HW_SUPPORTS_DYNAMIC_PS | */
+	    IEEE80211_HW_BEACON_FILTER |
+	    IEEE80211_HW_AMPDU_AGGREGATION |
 	    IEEE80211_HW_REPORTS_TX_ACK_STATUS | 0;
 
+	/* swlps or hwlps has been set in diff chip in init_sw_vars */
+	if (rtlpriv->psc.swctrl_lps)
+		hw->flags |= IEEE80211_HW_SUPPORTS_PS |
+			IEEE80211_HW_PS_NULLFUNC_STACK |
+			/* IEEE80211_HW_SUPPORTS_DYNAMIC_PS | */
+			0;
+
 	hw->wiphy->interface_modes =
-	    BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_ADHOC);
+	    BIT(NL80211_IFTYPE_AP) |
+	    BIT(NL80211_IFTYPE_STATION) |
+	    BIT(NL80211_IFTYPE_ADHOC);
 
 	hw->wiphy->rts_threshold = 2347;
 
@@ -199,9 +331,10 @@
 	/* TODO: Correct this value for our hw */
 	/* TODO: define these hard code value */
 	hw->channel_change_time = 100;
-	hw->max_listen_interval = 5;
+	hw->max_listen_interval = 10;
 	hw->max_rate_tries = 4;
 	/* hw->max_rates = 1; */
+	hw->sta_data_size = sizeof(struct rtl_sta_info);
 
 	/* <6> mac address */
 	if (is_valid_ether_addr(rtlefuse->dev_addr)) {
@@ -230,6 +363,10 @@
 			  (void *)rtl_watchdog_wq_callback);
 	INIT_DELAYED_WORK(&rtlpriv->works.ips_nic_off_wq,
 			  (void *)rtl_ips_nic_off_wq_callback);
+	INIT_DELAYED_WORK(&rtlpriv->works.ps_work,
+			  (void *)rtl_swlps_wq_callback);
+	INIT_DELAYED_WORK(&rtlpriv->works.ps_rfon_wq,
+			  (void *)rtl_swlps_rfon_wq_callback);
 
 }
 
@@ -241,6 +378,8 @@
 
 	cancel_delayed_work(&rtlpriv->works.watchdog_wq);
 	cancel_delayed_work(&rtlpriv->works.ips_nic_off_wq);
+	cancel_delayed_work(&rtlpriv->works.ps_work);
+	cancel_delayed_work(&rtlpriv->works.ps_rfon_wq);
 }
 
 void rtl_init_rfkill(struct ieee80211_hw *hw)
@@ -251,14 +390,16 @@
 	bool blocked;
 	u8 valid = 0;
 
-	radio_state = rtlpriv->cfg->ops->radio_onoff_checking(hw, &valid);
+	/*set init state to on */
+	rtlpriv->rfkill.rfkill_state = 1;
+	wiphy_rfkill_set_hw_state(hw->wiphy, 0);
 
-	/*set init state to that of switch */
-	rtlpriv->rfkill.rfkill_state = radio_state;
-	printk(KERN_INFO "rtlwifi: wireless switch is %s\n",
-	       rtlpriv->rfkill.rfkill_state ? "on" : "off");
+	radio_state = rtlpriv->cfg->ops->radio_onoff_checking(hw, &valid);
 
 	if (valid) {
+		printk(KERN_INFO "rtlwifi: wireless switch is %s\n",
+				rtlpriv->rfkill.rfkill_state ? "on" : "off");
+
 		rtlpriv->rfkill.rfkill_state = radio_state;
 
 		blocked = (rtlpriv->rfkill.rfkill_state == 1) ? 0 : 1;
@@ -308,6 +449,8 @@
 	spin_lock_init(&rtlpriv->locks.rf_ps_lock);
 	spin_lock_init(&rtlpriv->locks.rf_lock);
 	spin_lock_init(&rtlpriv->locks.lps_lock);
+	spin_lock_init(&rtlpriv->locks.waitq_lock);
+	spin_lock_init(&rtlpriv->locks.cck_and_rw_pagea_lock);
 
 	rtlmac->link_state = MAC80211_NOLINK;
 
@@ -327,12 +470,6 @@
 	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
 
 	rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_RCR, (u8 *) (&mac->rx_conf));
-	rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_MGT_FILTER,
-				      (u8 *) (&mac->rx_mgt_filter));
-	rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_CTRL_FILTER,
-				      (u8 *) (&mac->rx_ctrl_filter));
-	rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_DATA_FILTER,
-				      (u8 *) (&mac->rx_data_filter));
 }
 
 /*********************************************************
@@ -359,28 +496,40 @@
 }
 
 static void _rtl_query_shortgi(struct ieee80211_hw *hw,
+			       struct ieee80211_sta *sta,
 			       struct rtl_tcb_desc *tcb_desc,
 			       struct ieee80211_tx_info *info)
 {
 	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
 	u8 rate_flag = info->control.rates[0].flags;
-
+	u8 sgi_40 = 0, sgi_20 = 0, bw_40 = 0;
 	tcb_desc->use_shortgi = false;
 
-	if (!mac->ht_enable)
+	if (sta == NULL)
 		return;
 
-	if (!mac->sgi_40 && !mac->sgi_20)
+	sgi_40 = sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40;
+	sgi_20 = sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20;
+
+	if (!(sta->ht_cap.ht_supported))
 		return;
 
-	if ((mac->bw_40 == true) && mac->sgi_40)
+	if (!sgi_40 && !sgi_20)
+		return;
+
+	if (mac->opmode == NL80211_IFTYPE_STATION)
+		bw_40 = mac->bw_40;
+	else if (mac->opmode == NL80211_IFTYPE_AP ||
+		mac->opmode == NL80211_IFTYPE_ADHOC)
+		bw_40 = sta->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40;
+
+	if ((bw_40 == true) && sgi_40)
 		tcb_desc->use_shortgi = true;
-	else if ((mac->bw_40 == false) && mac->sgi_20)
+	else if ((bw_40 == false) && sgi_20)
 		tcb_desc->use_shortgi = true;
 
 	if (!(rate_flag & IEEE80211_TX_RC_SHORT_GI))
 		tcb_desc->use_shortgi = false;
-
 }
 
 static void _rtl_query_protection_mode(struct ieee80211_hw *hw,
@@ -408,19 +557,25 @@
 		tcb_desc->rts_enable = true;
 		tcb_desc->rts_rate = rtlpriv->cfg->maps[RTL_RC_OFDM_RATE24M];
 	}
-
 }
 
 static void _rtl_txrate_selectmode(struct ieee80211_hw *hw,
+				   struct ieee80211_sta *sta,
 				   struct rtl_tcb_desc *tcb_desc)
 {
 	struct rtl_priv *rtlpriv = rtl_priv(hw);
 	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+	struct rtl_sta_info *sta_entry = NULL;
+	u8 ratr_index = 7;
 
+	if (sta) {
+		sta_entry = (struct rtl_sta_info *) sta->drv_priv;
+		ratr_index = sta_entry->ratr_index;
+	}
 	if (!tcb_desc->disable_ratefallback || !tcb_desc->use_driver_rate) {
-		if (mac->opmode == NL80211_IFTYPE_STATION)
+		if (mac->opmode == NL80211_IFTYPE_STATION) {
 			tcb_desc->ratr_index = 0;
-		else if (mac->opmode == NL80211_IFTYPE_ADHOC) {
+		} else if (mac->opmode == NL80211_IFTYPE_ADHOC) {
 			if (tcb_desc->multicast || tcb_desc->broadcast) {
 				tcb_desc->hw_rate =
 				    rtlpriv->cfg->maps[RTL_RC_CCK_RATE2M];
@@ -428,36 +583,61 @@
 			} else {
 				/* TODO */
 			}
+			tcb_desc->ratr_index = ratr_index;
+		} else if (mac->opmode == NL80211_IFTYPE_AP) {
+			tcb_desc->ratr_index = ratr_index;
 		}
 	}
 
 	if (rtlpriv->dm.useramask) {
 		/* TODO we will differentiate adhoc and station futrue  */
-		tcb_desc->mac_id = 0;
+		if (mac->opmode == NL80211_IFTYPE_STATION) {
+			tcb_desc->mac_id = 0;
 
-		if ((mac->mode == WIRELESS_MODE_N_24G) ||
-		    (mac->mode == WIRELESS_MODE_N_5G)) {
-			tcb_desc->ratr_index = RATR_INX_WIRELESS_NGB;
-		} else if (mac->mode & WIRELESS_MODE_G) {
-			tcb_desc->ratr_index = RATR_INX_WIRELESS_GB;
-		} else if (mac->mode & WIRELESS_MODE_B) {
-			tcb_desc->ratr_index = RATR_INX_WIRELESS_B;
+			if (mac->mode == WIRELESS_MODE_N_24G)
+				tcb_desc->ratr_index = RATR_INX_WIRELESS_NGB;
+			else if (mac->mode == WIRELESS_MODE_N_5G)
+				tcb_desc->ratr_index = RATR_INX_WIRELESS_NG;
+			else if (mac->mode & WIRELESS_MODE_G)
+				tcb_desc->ratr_index = RATR_INX_WIRELESS_GB;
+			else if (mac->mode & WIRELESS_MODE_B)
+				tcb_desc->ratr_index = RATR_INX_WIRELESS_B;
+			else if (mac->mode & WIRELESS_MODE_A)
+				tcb_desc->ratr_index = RATR_INX_WIRELESS_G;
+		} else if (mac->opmode == NL80211_IFTYPE_AP ||
+			mac->opmode == NL80211_IFTYPE_ADHOC) {
+			if (NULL != sta) {
+				if (sta->aid > 0)
+					tcb_desc->mac_id = sta->aid + 1;
+				else
+					tcb_desc->mac_id = 1;
+			} else {
+				tcb_desc->mac_id = 0;
+			}
 		}
 	}
 
 }
 
 static void _rtl_query_bandwidth_mode(struct ieee80211_hw *hw,
+				      struct ieee80211_sta *sta,
 				      struct rtl_tcb_desc *tcb_desc)
 {
 	struct rtl_priv *rtlpriv = rtl_priv(hw);
 	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
 
 	tcb_desc->packet_bw = false;
-
-	if (!mac->bw_40 || !mac->ht_enable)
+	if (!sta)
 		return;
-
+	if (mac->opmode == NL80211_IFTYPE_AP ||
+	    mac->opmode == NL80211_IFTYPE_ADHOC) {
+		if (!(sta->ht_cap.ht_supported) ||
+		    !(sta->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40))
+			return;
+	} else if (mac->opmode == NL80211_IFTYPE_STATION) {
+		if (!mac->bw_40 || !(sta->ht_cap.ht_supported))
+			return;
+	}
 	if (tcb_desc->multicast || tcb_desc->broadcast)
 		return;
 
@@ -484,22 +664,21 @@
 
 void rtl_get_tcb_desc(struct ieee80211_hw *hw,
 		      struct ieee80211_tx_info *info,
+		      struct ieee80211_sta *sta,
 		      struct sk_buff *skb, struct rtl_tcb_desc *tcb_desc)
 {
 	struct rtl_priv *rtlpriv = rtl_priv(hw);
 	struct rtl_mac *rtlmac = rtl_mac(rtl_priv(hw));
-	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)(skb->data);
+	struct ieee80211_hdr *hdr = rtl_get_hdr(skb);
 	struct ieee80211_rate *txrate;
 	__le16 fc = hdr->frame_control;
 
-	memset(tcb_desc, 0, sizeof(struct rtl_tcb_desc));
+	txrate = ieee80211_get_tx_rate(hw, info);
+	tcb_desc->hw_rate = txrate->hw_value;
 
 	if (ieee80211_is_data(fc)) {
-		txrate = ieee80211_get_tx_rate(hw, info);
-		tcb_desc->hw_rate = txrate->hw_value;
-
 		/*
-		 *we set data rate RTL_RC_CCK_RATE1M
+		 *we set data rate INX 0
 		 *in rtl_rc.c   if skb is special data or
 		 *mgt which need low data rate.
 		 */
@@ -508,12 +687,11 @@
 		 *So tcb_desc->hw_rate is just used for
 		 *special data and mgt frames
 		 */
-		if (tcb_desc->hw_rate < rtlpriv->cfg->maps[RTL_RC_CCK_RATE11M]) {
+		if (info->control.rates[0].idx == 0 &&
+				ieee80211_is_nullfunc(fc)) {
 			tcb_desc->use_driver_rate = true;
-			tcb_desc->ratr_index = 7;
+			tcb_desc->ratr_index = RATR_INX_WIRELESS_MC;
 
-			tcb_desc->hw_rate =
-			    rtlpriv->cfg->maps[RTL_RC_CCK_RATE1M];
 			tcb_desc->disable_ratefallback = 1;
 		} else {
 			/*
@@ -523,7 +701,7 @@
 			 *and N rate will all be controlled by FW
 			 *when tcb_desc->use_driver_rate = false
 			 */
-			if (rtlmac->ht_enable) {
+			if (sta && (sta->ht_cap.ht_supported)) {
 				tcb_desc->hw_rate = _rtl_get_highest_n_rate(hw);
 			} else {
 				if (rtlmac->mode == WIRELESS_MODE_B) {
@@ -541,43 +719,25 @@
 		else if (is_broadcast_ether_addr(ieee80211_get_DA(hdr)))
 			tcb_desc->broadcast = 1;
 
-		_rtl_txrate_selectmode(hw, tcb_desc);
-		_rtl_query_bandwidth_mode(hw, tcb_desc);
+		_rtl_txrate_selectmode(hw, sta, tcb_desc);
+		_rtl_query_bandwidth_mode(hw, sta, tcb_desc);
 		_rtl_qurey_shortpreamble_mode(hw, tcb_desc, info);
-		_rtl_query_shortgi(hw, tcb_desc, info);
+		_rtl_query_shortgi(hw, sta, tcb_desc, info);
 		_rtl_query_protection_mode(hw, tcb_desc, info);
 	} else {
 		tcb_desc->use_driver_rate = true;
-		tcb_desc->ratr_index = 7;
+		tcb_desc->ratr_index = RATR_INX_WIRELESS_MC;
 		tcb_desc->disable_ratefallback = 1;
 		tcb_desc->mac_id = 0;
-
-		tcb_desc->hw_rate = rtlpriv->cfg->maps[RTL_RC_CCK_RATE1M];
+		tcb_desc->packet_bw = false;
 	}
 }
 EXPORT_SYMBOL(rtl_get_tcb_desc);
 
-bool rtl_tx_mgmt_proc(struct ieee80211_hw *hw, struct sk_buff *skb)
-{
-	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
-	struct rtl_priv *rtlpriv = rtl_priv(hw);
-	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)(skb->data);
-	__le16 fc = hdr->frame_control;
-
-	if (ieee80211_is_auth(fc)) {
-		RT_TRACE(rtlpriv, COMP_SEND, DBG_DMESG, ("MAC80211_LINKING\n"));
-		rtl_ips_nic_on(hw);
-
-		mac->link_state = MAC80211_LINKING;
-	}
-
-	return true;
-}
-
 bool rtl_action_proc(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx)
 {
 	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
-	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)(skb->data);
+	struct ieee80211_hdr *hdr = rtl_get_hdr(skb);
 	struct rtl_priv *rtlpriv = rtl_priv(hw);
 	__le16 fc = hdr->frame_control;
 	u8 *act = (u8 *) (((u8 *) skb->data + MAC80211_3ADDR_LEN));
@@ -622,22 +782,20 @@
 u8 rtl_is_special_data(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx)
 {
 	struct rtl_priv *rtlpriv = rtl_priv(hw);
-	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)(skb->data);
 	struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
-	__le16 fc = hdr->frame_control;
+	__le16 fc = rtl_get_fc(skb);
 	u16 ether_type;
 	u8 mac_hdr_len = ieee80211_get_hdrlen_from_skb(skb);
 	const struct iphdr *ip;
 
 	if (!ieee80211_is_data(fc))
-		goto end;
+		return false;
 
-	if (ieee80211_is_nullfunc(fc))
-		return true;
 
 	ip = (struct iphdr *)((u8 *) skb->data + mac_hdr_len +
 			      SNAP_SIZE + PROTOC_TYPE_SIZE);
 	ether_type = *(u16 *) ((u8 *) skb->data + mac_hdr_len + SNAP_SIZE);
+	/*	ether_type = ntohs(ether_type); */
 
 	if (ETH_P_IP == ether_type) {
 		if (IPPROTO_UDP == ip->protocol) {
@@ -686,7 +844,6 @@
 		return true;
 	}
 
-end:
 	return false;
 }
 
@@ -695,61 +852,92 @@
  * functions called by core.c
  *
  *********************************************************/
-int rtl_tx_agg_start(struct ieee80211_hw *hw, const u8 *ra, u16 tid, u16 *ssn)
+int rtl_tx_agg_start(struct ieee80211_hw *hw,
+		struct ieee80211_sta *sta, u16 tid, u16 *ssn)
 {
 	struct rtl_priv *rtlpriv = rtl_priv(hw);
 	struct rtl_tid_data *tid_data;
 	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+	struct rtl_sta_info *sta_entry = NULL;
 
-	RT_TRACE(rtlpriv, COMP_SEND, DBG_DMESG,
-		 ("on ra = %pM tid = %d\n", ra, tid));
+	if (sta == NULL)
+		return -EINVAL;
 
 	if (unlikely(tid >= MAX_TID_COUNT))
 		return -EINVAL;
 
-	if (mac->tids[tid].agg.agg_state != RTL_AGG_OFF) {
-		RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
-			 ("Start AGG when state is not RTL_AGG_OFF !\n"));
+	sta_entry = (struct rtl_sta_info *)sta->drv_priv;
+	if (!sta_entry)
 		return -ENXIO;
-	}
-
-	tid_data = &mac->tids[tid];
-	*ssn = SEQ_TO_SN(tid_data->seq_number);
+	tid_data = &sta_entry->tids[tid];
 
 	RT_TRACE(rtlpriv, COMP_SEND, DBG_DMESG,
-		 ("HW queue is empty tid:%d\n", tid));
-	tid_data->agg.agg_state = RTL_AGG_ON;
+		 ("on ra = %pM tid = %d seq:%d\n", sta->addr, tid,
+		 tid_data->seq_number));
 
-	ieee80211_start_tx_ba_cb_irqsafe(mac->vif, ra, tid);
+	*ssn = tid_data->seq_number;
+	tid_data->agg.agg_state = RTL_AGG_START;
+
+	ieee80211_start_tx_ba_cb_irqsafe(mac->vif, sta->addr, tid);
 
 	return 0;
 }
 
-int rtl_tx_agg_stop(struct ieee80211_hw *hw, const u8 * ra, u16 tid)
+int rtl_tx_agg_stop(struct ieee80211_hw *hw,
+		struct ieee80211_sta *sta, u16 tid)
 {
-	int ssn = -1;
 	struct rtl_priv *rtlpriv = rtl_priv(hw);
 	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
 	struct rtl_tid_data *tid_data;
+	struct rtl_sta_info *sta_entry = NULL;
 
-	if (!ra) {
+	if (sta == NULL)
+		return -EINVAL;
+
+	if (!sta->addr) {
 		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("ra = NULL\n"));
 		return -EINVAL;
 	}
 
+	RT_TRACE(rtlpriv, COMP_SEND, DBG_DMESG,
+		 ("on ra = %pM tid = %d\n", sta->addr, tid));
+
 	if (unlikely(tid >= MAX_TID_COUNT))
 		return -EINVAL;
 
-	if (mac->tids[tid].agg.agg_state != RTL_AGG_ON)
-		RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
-			 ("Stopping AGG while state not ON or starting\n"));
+	sta_entry = (struct rtl_sta_info *)sta->drv_priv;
+	tid_data = &sta_entry->tids[tid];
+	sta_entry->tids[tid].agg.agg_state = RTL_AGG_STOP;
 
-	tid_data = &mac->tids[tid];
-	ssn = (tid_data->seq_number & IEEE80211_SCTL_SEQ) >> 4;
+	ieee80211_stop_tx_ba_cb_irqsafe(mac->vif, sta->addr, tid);
 
-	mac->tids[tid].agg.agg_state = RTL_AGG_OFF;
+	return 0;
+}
 
-	ieee80211_stop_tx_ba_cb_irqsafe(mac->vif, ra, tid);
+int rtl_tx_agg_oper(struct ieee80211_hw *hw,
+		struct ieee80211_sta *sta, u16 tid)
+{
+	struct rtl_priv *rtlpriv = rtl_priv(hw);
+	struct rtl_tid_data *tid_data;
+	struct rtl_sta_info *sta_entry = NULL;
+
+	if (sta == NULL)
+		return -EINVAL;
+
+	if (!sta->addr) {
+		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("ra = NULL\n"));
+		return -EINVAL;
+	}
+
+	RT_TRACE(rtlpriv, COMP_SEND, DBG_DMESG,
+		 ("on ra = %pM tid = %d\n", sta->addr, tid));
+
+	if (unlikely(tid >= MAX_TID_COUNT))
+		return -EINVAL;
+
+	sta_entry = (struct rtl_sta_info *)sta->drv_priv;
+	tid_data = &sta_entry->tids[tid];
+	sta_entry->tids[tid].agg.agg_state = RTL_AGG_OPERATIONAL;
 
 	return 0;
 }
@@ -768,18 +956,16 @@
 	struct rtl_priv *rtlpriv = rtl_priv(hw);
 	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
 	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
-
 	bool busytraffic = false;
 	bool higher_busytraffic = false;
 	bool higher_busyrxtraffic = false;
-	bool higher_busytxtraffic = false;
-
-	u8 idx = 0;
+	u8 idx, tid;
 	u32 rx_cnt_inp4eriod = 0;
 	u32 tx_cnt_inp4eriod = 0;
 	u32 aver_rx_cnt_inperiod = 0;
 	u32 aver_tx_cnt_inperiod = 0;
-
+	u32 aver_tidtx_inperiod[MAX_TID_COUNT] = {0};
+	u32 tidtx_inp4eriod[MAX_TID_COUNT] = {0};
 	bool enter_ps = false;
 
 	if (is_hal_stop(rtlhal))
@@ -793,9 +979,6 @@
 		mac->cnt_after_linked = 0;
 	}
 
-	/* <2> DM */
-	rtlpriv->cfg->ops->dm_watchdog(hw);
-
 	/*
 	 *<3> to check if traffic busy, if
 	 * busytraffic we don't change channel
@@ -834,8 +1017,27 @@
 			/* Extremely high Rx data. */
 			if (aver_rx_cnt_inperiod > 5000)
 				higher_busyrxtraffic = true;
+		}
+
+		/* check every tid's tx traffic */
+		for (tid = 0; tid <= 7; tid++) {
+			for (idx = 0; idx <= 2; idx++)
+				rtlpriv->link_info.tidtx_in4period[tid][idx] =
+				  rtlpriv->link_info.tidtx_in4period[tid]
+				  [idx + 1];
+			rtlpriv->link_info.tidtx_in4period[tid][3] =
+				rtlpriv->link_info.tidtx_inperiod[tid];
+
+			for (idx = 0; idx <= 3; idx++)
+				tidtx_inp4eriod[tid] +=
+				  rtlpriv->link_info.tidtx_in4period[tid][idx];
+			aver_tidtx_inperiod[tid] = tidtx_inp4eriod[tid] / 4;
+			if (aver_tidtx_inperiod[tid] > 5000)
+				rtlpriv->link_info.higher_busytxtraffic[tid] =
+						   true;
 			else
-				higher_busytxtraffic = false;
+				rtlpriv->link_info.higher_busytxtraffic[tid] =
+						   false;
 		}
 
 		if (((rtlpriv->link_info.num_rx_inperiod +
@@ -854,11 +1056,15 @@
 
 	rtlpriv->link_info.num_rx_inperiod = 0;
 	rtlpriv->link_info.num_tx_inperiod = 0;
+	for (tid = 0; tid <= 7; tid++)
+		rtlpriv->link_info.tidtx_inperiod[tid] = 0;
 
 	rtlpriv->link_info.busytraffic = busytraffic;
 	rtlpriv->link_info.higher_busytraffic = higher_busytraffic;
 	rtlpriv->link_info.higher_busyrxtraffic = higher_busyrxtraffic;
 
+	/* <3> DM */
+	rtlpriv->cfg->ops->dm_watchdog(hw);
 }
 
 void rtl_watch_dog_timer_callback(unsigned long data)
@@ -875,6 +1081,268 @@
 
 /*********************************************************
  *
+ * frame process functions
+ *
+ *********************************************************/
+u8 *rtl_find_ie(u8 *data, unsigned int len, u8 ie)
+{
+	struct ieee80211_mgmt *mgmt = (void *)data;
+	u8 *pos, *end;
+
+	pos = (u8 *)mgmt->u.beacon.variable;
+	end = data + len;
+	while (pos < end) {
+		if (pos + 2 + pos[1] > end)
+			return NULL;
+
+		if (pos[0] == ie)
+			return pos;
+
+		pos += 2 + pos[1];
+	}
+	return NULL;
+}
+
+/* when we use 2 rx ants we send IEEE80211_SMPS_OFF */
+/* when we use 1 rx ant we send IEEE80211_SMPS_STATIC */
+static struct sk_buff *rtl_make_smps_action(struct ieee80211_hw *hw,
+		enum ieee80211_smps_mode smps, u8 *da, u8 *bssid)
+{
+	struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
+	struct sk_buff *skb;
+	struct ieee80211_mgmt *action_frame;
+
+	/* 27 = header + category + action + smps mode */
+	skb = dev_alloc_skb(27 + hw->extra_tx_headroom);
+	if (!skb)
+		return NULL;
+
+	skb_reserve(skb, hw->extra_tx_headroom);
+	action_frame = (void *)skb_put(skb, 27);
+	memset(action_frame, 0, 27);
+	memcpy(action_frame->da, da, ETH_ALEN);
+	memcpy(action_frame->sa, rtlefuse->dev_addr, ETH_ALEN);
+	memcpy(action_frame->bssid, bssid, ETH_ALEN);
+	action_frame->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
+						  IEEE80211_STYPE_ACTION);
+	action_frame->u.action.category = WLAN_CATEGORY_HT;
+	action_frame->u.action.u.ht_smps.action = WLAN_HT_ACTION_SMPS;
+	switch (smps) {
+	case IEEE80211_SMPS_AUTOMATIC:/* 0 */
+	case IEEE80211_SMPS_NUM_MODES:/* 4 */
+		WARN_ON(1);
+	case IEEE80211_SMPS_OFF:/* 1 */ /*MIMO_PS_NOLIMIT*/
+		action_frame->u.action.u.ht_smps.smps_control =
+				WLAN_HT_SMPS_CONTROL_DISABLED;/* 0 */
+		break;
+	case IEEE80211_SMPS_STATIC:/* 2 */ /*MIMO_PS_STATIC*/
+		action_frame->u.action.u.ht_smps.smps_control =
+				WLAN_HT_SMPS_CONTROL_STATIC;/* 1 */
+		break;
+	case IEEE80211_SMPS_DYNAMIC:/* 3 */ /*MIMO_PS_DYNAMIC*/
+		action_frame->u.action.u.ht_smps.smps_control =
+				WLAN_HT_SMPS_CONTROL_DYNAMIC;/* 3 */
+		break;
+	}
+
+	return skb;
+}
+
+int rtl_send_smps_action(struct ieee80211_hw *hw,
+		struct ieee80211_sta *sta, u8 *da, u8 *bssid,
+		enum ieee80211_smps_mode smps)
+{
+	struct rtl_priv *rtlpriv = rtl_priv(hw);
+	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+	struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
+	struct sk_buff *skb = rtl_make_smps_action(hw, smps, da, bssid);
+	struct rtl_tcb_desc tcb_desc;
+	memset(&tcb_desc, 0, sizeof(struct rtl_tcb_desc));
+
+	if (rtlpriv->mac80211.act_scanning)
+		goto err_free;
+
+	if (!sta)
+		goto err_free;
+
+	if (unlikely(is_hal_stop(rtlhal) || ppsc->rfpwr_state != ERFON))
+		goto err_free;
+
+	if (!test_bit(RTL_STATUS_INTERFACE_START, &rtlpriv->status))
+		goto err_free;
+
+	/* this is a type = mgmt * stype = action frame */
+	if (skb) {
+		struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+		struct rtl_sta_info *sta_entry =
+			(struct rtl_sta_info *) sta->drv_priv;
+		sta_entry->mimo_ps = smps;
+		rtlpriv->cfg->ops->update_rate_tbl(hw, sta, 0);
+
+		info->control.rates[0].idx = 0;
+		info->control.sta = sta;
+		info->band = hw->conf.channel->band;
+		rtlpriv->intf_ops->adapter_tx(hw, skb, &tcb_desc);
+	}
+err_free:
+	return 0;
+}
+
+/*********************************************************
+ *
+ * IOT functions
+ *
+ *********************************************************/
+static bool rtl_chk_vendor_ouisub(struct ieee80211_hw *hw,
+		struct octet_string vendor_ie)
+{
+	struct rtl_priv *rtlpriv = rtl_priv(hw);
+	bool matched = false;
+	static u8 athcap_1[] = { 0x00, 0x03, 0x7F };
+	static u8 athcap_2[] = { 0x00, 0x13, 0x74 };
+	static u8 broadcap_1[] = { 0x00, 0x10, 0x18 };
+	static u8 broadcap_2[] = { 0x00, 0x0a, 0xf7 };
+	static u8 broadcap_3[] = { 0x00, 0x05, 0xb5 };
+	static u8 racap[] = { 0x00, 0x0c, 0x43 };
+	static u8 ciscocap[] = { 0x00, 0x40, 0x96 };
+	static u8 marvcap[] = { 0x00, 0x50, 0x43 };
+
+	if (memcmp(vendor_ie.octet, athcap_1, 3) == 0 ||
+		memcmp(vendor_ie.octet, athcap_2, 3) == 0) {
+		rtlpriv->mac80211.vendor = PEER_ATH;
+		matched = true;
+	} else if (memcmp(vendor_ie.octet, broadcap_1, 3) == 0 ||
+		memcmp(vendor_ie.octet, broadcap_2, 3) == 0 ||
+		memcmp(vendor_ie.octet, broadcap_3, 3) == 0) {
+		rtlpriv->mac80211.vendor = PEER_BROAD;
+		matched = true;
+	} else if (memcmp(vendor_ie.octet, racap, 3) == 0) {
+		rtlpriv->mac80211.vendor = PEER_RAL;
+		matched = true;
+	} else if (memcmp(vendor_ie.octet, ciscocap, 3) == 0) {
+		rtlpriv->mac80211.vendor = PEER_CISCO;
+		matched = true;
+	} else if (memcmp(vendor_ie.octet, marvcap, 3) == 0) {
+		rtlpriv->mac80211.vendor = PEER_MARV;
+		matched = true;
+	}
+
+	return matched;
+}
+
+static bool rtl_find_221_ie(struct ieee80211_hw *hw, u8 *data,
+		unsigned int len)
+{
+	struct ieee80211_mgmt *mgmt = (void *)data;
+	struct octet_string vendor_ie;
+	u8 *pos, *end;
+
+	pos = (u8 *)mgmt->u.beacon.variable;
+	end = data + len;
+	while (pos < end) {
+		if (pos[0] == 221) {
+			vendor_ie.length = pos[1];
+			vendor_ie.octet = &pos[2];
+			if (rtl_chk_vendor_ouisub(hw, vendor_ie))
+				return true;
+		}
+
+		if (pos + 2 + pos[1] > end)
+			return false;
+
+		pos += 2 + pos[1];
+	}
+	return false;
+}
+
+void rtl_recognize_peer(struct ieee80211_hw *hw, u8 *data, unsigned int len)
+{
+	struct rtl_priv *rtlpriv = rtl_priv(hw);
+	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+	struct ieee80211_hdr *hdr = (void *)data;
+	u32 vendor = PEER_UNKNOWN;
+
+	static u8 ap3_1[3] = { 0x00, 0x14, 0xbf };
+	static u8 ap3_2[3] = { 0x00, 0x1a, 0x70 };
+	static u8 ap3_3[3] = { 0x00, 0x1d, 0x7e };
+	static u8 ap4_1[3] = { 0x00, 0x90, 0xcc };
+	static u8 ap4_2[3] = { 0x00, 0x0e, 0x2e };
+	static u8 ap4_3[3] = { 0x00, 0x18, 0x02 };
+	static u8 ap4_4[3] = { 0x00, 0x17, 0x3f };
+	static u8 ap4_5[3] = { 0x00, 0x1c, 0xdf };
+	static u8 ap5_1[3] = { 0x00, 0x1c, 0xf0 };
+	static u8 ap5_2[3] = { 0x00, 0x21, 0x91 };
+	static u8 ap5_3[3] = { 0x00, 0x24, 0x01 };
+	static u8 ap5_4[3] = { 0x00, 0x15, 0xe9 };
+	static u8 ap5_5[3] = { 0x00, 0x17, 0x9A };
+	static u8 ap5_6[3] = { 0x00, 0x18, 0xE7 };
+	static u8 ap6_1[3] = { 0x00, 0x17, 0x94 };
+	static u8 ap7_1[3] = { 0x00, 0x14, 0xa4 };
+
+	if (mac->opmode != NL80211_IFTYPE_STATION)
+		return;
+
+	if (mac->link_state == MAC80211_NOLINK) {
+		mac->vendor = PEER_UNKNOWN;
+		return;
+	}
+
+	if (mac->cnt_after_linked > 2)
+		return;
+
+	/* check if this really is a beacon */
+	if (!ieee80211_is_beacon(hdr->frame_control))
+		return;
+
+	/* min. beacon length + FCS_LEN */
+	if (len <= 40 + FCS_LEN)
+		return;
+
+	/* and only beacons from the associated BSSID, please */
+	if (compare_ether_addr(hdr->addr3, rtlpriv->mac80211.bssid))
+		return;
+
+	if (rtl_find_221_ie(hw, data, len))
+		vendor = mac->vendor;
+
+	if ((memcmp(mac->bssid, ap5_1, 3) == 0) ||
+		(memcmp(mac->bssid, ap5_2, 3) == 0) ||
+		(memcmp(mac->bssid, ap5_3, 3) == 0) ||
+		(memcmp(mac->bssid, ap5_4, 3) == 0) ||
+		(memcmp(mac->bssid, ap5_5, 3) == 0) ||
+		(memcmp(mac->bssid, ap5_6, 3) == 0) ||
+		vendor == PEER_ATH) {
+		vendor = PEER_ATH;
+		RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, ("=>ath find\n"));
+	} else if ((memcmp(mac->bssid, ap4_4, 3) == 0) ||
+		(memcmp(mac->bssid, ap4_5, 3) == 0) ||
+		(memcmp(mac->bssid, ap4_1, 3) == 0) ||
+		(memcmp(mac->bssid, ap4_2, 3) == 0) ||
+		(memcmp(mac->bssid, ap4_3, 3) == 0) ||
+		vendor == PEER_RAL) {
+		RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, ("=>ral findn\n"));
+		vendor = PEER_RAL;
+	} else if (memcmp(mac->bssid, ap6_1, 3) == 0 ||
+		vendor == PEER_CISCO) {
+		vendor = PEER_CISCO;
+		RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, ("=>cisco find\n"));
+	} else if ((memcmp(mac->bssid, ap3_1, 3) == 0) ||
+		(memcmp(mac->bssid, ap3_2, 3) == 0) ||
+		(memcmp(mac->bssid, ap3_3, 3) == 0) ||
+		vendor == PEER_BROAD) {
+		RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, ("=>broad find\n"));
+		vendor = PEER_BROAD;
+	} else if (memcmp(mac->bssid, ap7_1, 3) == 0 ||
+		vendor == PEER_MARV) {
+		vendor = PEER_MARV;
+		RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, ("=>marv find\n"));
+	}
+
+	mac->vendor = vendor;
+}
+
+/*********************************************************
+ *
  * sysfs functions
  *
  *********************************************************/
@@ -940,12 +1408,13 @@
 	if (rtl_rate_control_register())
 		printk(KERN_ERR "rtlwifi: Unable to register rtl_rc,"
 		       "use default RC !!\n");
+
 	return 0;
 }
 
 static void __exit rtl_core_module_exit(void)
 {
-	 /*RC*/
+	/*RC*/
 	rtl_rate_control_unregister();
 }
 
diff -druN linux-2.6.39-libre/drivers/net/wireless/rtlwifi/base.h linux-3.0-rc7-libre/drivers/net/wireless/rtlwifi/base.h
--- linux-2.6.39-libre/drivers/net/wireless/rtlwifi/base.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/rtlwifi/base.h	2011-07-11 19:51:52.000000000 -0400
@@ -24,13 +24,26 @@
  * Hsinchu 300, Taiwan.
  *
  * Larry Finger <Larry.Finger@lwfinger.net>
+ *
  *****************************************************************************/
 
 #ifndef __RTL_BASE_H__
 #define __RTL_BASE_H__
 
+enum ap_peer {
+	PEER_UNKNOWN = 0,
+	PEER_RTL = 1,
+	PEER_RTL_92SE = 2,
+	PEER_BROAD = 3,
+	PEER_RAL = 4,
+	PEER_ATH = 5,
+	PEER_CISCO = 6,
+	PEER_MARV = 7,
+	PEER_AIRGO = 9,
+	PEER_MAX = 10,
+} ;
+
 #define RTL_DUMMY_OFFSET	0
-#define RTL_RX_DESC_SIZE	24
 #define RTL_DUMMY_UNIT		8
 #define RTL_TX_DUMMY_SIZE	(RTL_DUMMY_OFFSET * RTL_DUMMY_UNIT)
 #define RTL_TX_DESC_SIZE	32
@@ -53,6 +66,14 @@
 #define FRAME_OFFSET_SEQUENCE		22
 #define FRAME_OFFSET_ADDRESS4		24
 
+#define SET_80211_HDR_FRAME_CONTROL(_hdr, _val)		\
+	WRITEEF2BYTE(_hdr, _val)
+#define SET_80211_HDR_TYPE_AND_SUBTYPE(_hdr, _val)	\
+	WRITEEF1BYTE(_hdr, _val)
+#define SET_80211_HDR_PWR_MGNT(_hdr, _val)		\
+	SET_BITS_TO_LE_2BYTE(_hdr, 12, 1, _val)
+#define SET_80211_HDR_TO_DS(_hdr, _val)			\
+	SET_BITS_TO_LE_2BYTE(_hdr, 8, 1, _val)
 
 #define SET_80211_PS_POLL_AID(_hdr, _val)		\
 	(*(u16 *)((u8 *)(_hdr) + 2) = le16_to_cpu(_val))
@@ -64,11 +85,27 @@
 #define SET_80211_HDR_DURATION(_hdr, _val)	\
 	(*(u16 *)((u8 *)(_hdr) + FRAME_OFFSET_DURATION) = le16_to_cpu(_val))
 #define SET_80211_HDR_ADDRESS1(_hdr, _val)	\
-	memcpy((u8 *)(_hdr)+FRAME_OFFSET_ADDRESS1, (u8*)(_val), ETH_ALEN)
+	CP_MACADDR((u8 *)(_hdr)+FRAME_OFFSET_ADDRESS1, (u8 *)(_val))
 #define SET_80211_HDR_ADDRESS2(_hdr, _val)	\
-	memcpy((u8 *)(_hdr) + FRAME_OFFSET_ADDRESS2, (u8 *)(_val), ETH_ALEN)
+	CP_MACADDR((u8 *)(_hdr)+FRAME_OFFSET_ADDRESS2, (u8 *)(_val))
 #define SET_80211_HDR_ADDRESS3(_hdr, _val)	\
-	memcpy((u8 *)(_hdr)+FRAME_OFFSET_ADDRESS3, (u8 *)(_val), ETH_ALEN)
+	CP_MACADDR((u8 *)(_hdr)+FRAME_OFFSET_ADDRESS3, (u8 *)(_val))
+#define SET_80211_HDR_FRAGMENT_SEQUENCE(_hdr, _val)  \
+	WRITEEF2BYTE((u8 *)(_hdr)+FRAME_OFFSET_SEQUENCE, _val)
+
+#define SET_BEACON_PROBE_RSP_TIME_STAMP_LOW(__phdr, __val)	\
+	WRITEEF4BYTE(((u8 *)(__phdr)) + 24, __val)
+#define SET_BEACON_PROBE_RSP_TIME_STAMP_HIGH(__phdr, __val) \
+	WRITEEF4BYTE(((u8 *)(__phdr)) + 28, __val)
+#define SET_BEACON_PROBE_RSP_BEACON_INTERVAL(__phdr, __val) \
+	WRITEEF2BYTE(((u8 *)(__phdr)) + 32, __val)
+#define GET_BEACON_PROBE_RSP_CAPABILITY_INFO(__phdr)		\
+	READEF2BYTE(((u8 *)(__phdr)) + 34)
+#define SET_BEACON_PROBE_RSP_CAPABILITY_INFO(__phdr, __val) \
+	WRITEEF2BYTE(((u8 *)(__phdr)) + 34, __val)
+#define MASK_BEACON_PROBE_RSP_CAPABILITY_INFO(__phdr, __val) \
+	SET_BEACON_PROBE_RSP_CAPABILITY_INFO(__phdr, \
+	(GET_BEACON_PROBE_RSP_CAPABILITY_INFO(__phdr) & (~(__val))))
 
 int rtl_init_core(struct ieee80211_hw *hw);
 void rtl_deinit_core(struct ieee80211_hw *hw);
@@ -80,18 +117,27 @@
 void rtl_deinit_deferred_work(struct ieee80211_hw *hw);
 
 bool rtl_action_proc(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx);
-bool rtl_tx_mgmt_proc(struct ieee80211_hw *hw, struct sk_buff *skb);
 u8 rtl_is_special_data(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx);
 
 void rtl_watch_dog_timer_callback(unsigned long data);
-int rtl_tx_agg_start(struct ieee80211_hw *hw, const u8 *ra,
+int rtl_tx_agg_start(struct ieee80211_hw *hw, struct ieee80211_sta *sta,
 		     u16 tid, u16 *ssn);
-int rtl_tx_agg_stop(struct ieee80211_hw *hw, const u8 *ra, u16 tid);
+int rtl_tx_agg_stop(struct ieee80211_hw *hw, struct ieee80211_sta *sta,
+		    u16 tid);
+int rtl_tx_agg_oper(struct ieee80211_hw *hw, struct ieee80211_sta *sta,
+		    u16 tid);
 void rtl_watchdog_wq_callback(void *data);
 
 void rtl_get_tcb_desc(struct ieee80211_hw *hw,
 		      struct ieee80211_tx_info *info,
+		      struct ieee80211_sta *sta,
 		      struct sk_buff *skb, struct rtl_tcb_desc *tcb_desc);
 
+int rtl_send_smps_action(struct ieee80211_hw *hw,
+		struct ieee80211_sta *sta, u8 *da, u8 *bssid,
+		enum ieee80211_smps_mode smps);
+u8 *rtl_find_ie(u8 *data, unsigned int len, u8 ie);
+void rtl_recognize_peer(struct ieee80211_hw *hw, u8 *data, unsigned int len);
+u8 rtl_tid_to_ac(struct ieee80211_hw *hw, u8 tid);
 extern struct attribute_group rtl_attribute_group;
 #endif
diff -druN linux-2.6.39-libre/drivers/net/wireless/rtlwifi/cam.c linux-3.0-rc7-libre/drivers/net/wireless/rtlwifi/cam.c
--- linux-2.6.39-libre/drivers/net/wireless/rtlwifi/cam.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/rtlwifi/cam.c	2011-07-11 19:51:52.000000000 -0400
@@ -23,6 +23,8 @@
  * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
  * Hsinchu 300, Taiwan.
  *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
  *****************************************************************************/
 
 #include "wifi.h"
@@ -49,7 +51,7 @@
 	u32 target_content = 0;
 	u8 entry_i;
 
-	RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
+	RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD,
 		 ("key_cont_128:\n %x:%x:%x:%x:%x:%x\n",
 		  key_cont_128[0], key_cont_128[1],
 		  key_cont_128[2], key_cont_128[3],
@@ -68,15 +70,13 @@
 			rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[RWCAM],
 					target_command);
 
-			RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
-				 ("rtl_cam_program_entry(): "
-				  "WRITE %x: %x\n",
+			RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD,
+				 ("WRITE %x: %x\n",
 				  rtlpriv->cfg->maps[WCAMI], target_content));
-			RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
+			RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD,
 				 ("The Key ID is %d\n", entry_no));
-			RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
-				 ("rtl_cam_program_entry(): "
-				  "WRITE %x: %x\n",
+			RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD,
+				 ("WRITE %x: %x\n",
 				  rtlpriv->cfg->maps[RWCAM], target_command));
 
 		} else if (entry_i == 1) {
@@ -91,12 +91,10 @@
 			rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[RWCAM],
 					target_command);
 
-			RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
-				 ("rtl_cam_program_entry(): WRITE A4: %x\n",
-				  target_content));
-			RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
-				 ("rtl_cam_program_entry(): WRITE A0: %x\n",
-				  target_command));
+			RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD,
+				 ("WRITE A4: %x\n", target_content));
+			RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD,
+				 ("WRITE A0: %x\n", target_command));
 
 		} else {
 
@@ -113,16 +111,14 @@
 					target_command);
 			udelay(100);
 
-			RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
-				 ("rtl_cam_program_entry(): WRITE A4: %x\n",
-				  target_content));
-			RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
-				 ("rtl_cam_program_entry(): WRITE A0: %x\n",
-				  target_command));
+			RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD,
+				 ("WRITE A4: %x\n", target_content));
+			RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD,
+				 ("WRITE A0: %x\n", target_command));
 		}
 	}
 
-	RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
+	RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD,
 		 ("after set key, usconfig:%x\n", us_config));
 }
 
@@ -289,3 +285,71 @@
 
 }
 EXPORT_SYMBOL(rtl_cam_empty_entry);
+
+u8 rtl_cam_get_free_entry(struct ieee80211_hw *hw, u8 *sta_addr)
+{
+	struct rtl_priv *rtlpriv = rtl_priv(hw);
+	u32 bitmap = (rtlpriv->sec.hwsec_cam_bitmap) >> 4;
+	u8 entry_idx = 0;
+	u8 i, *addr;
+
+	if (NULL == sta_addr) {
+		RT_TRACE(rtlpriv, COMP_SEC, DBG_EMERG,
+			("sta_addr is NULL.\n"));
+		return TOTAL_CAM_ENTRY;
+	}
+	/* Does STA already exist? */
+	for (i = 4; i < TOTAL_CAM_ENTRY; i++) {
+		addr = rtlpriv->sec.hwsec_cam_sta_addr[i];
+		if (memcmp(addr, sta_addr, ETH_ALEN) == 0)
+			return i;
+	}
+	/* Get a free CAM entry. */
+	for (entry_idx = 4; entry_idx < TOTAL_CAM_ENTRY; entry_idx++) {
+		if ((bitmap & BIT(0)) == 0) {
+			RT_TRACE(rtlpriv, COMP_SEC, DBG_EMERG,
+				("-----hwsec_cam_bitmap: 0x%x entry_idx=%d\n",
+				 rtlpriv->sec.hwsec_cam_bitmap, entry_idx));
+			rtlpriv->sec.hwsec_cam_bitmap |= BIT(0) << entry_idx;
+			memcpy(rtlpriv->sec.hwsec_cam_sta_addr[entry_idx],
+			       sta_addr, ETH_ALEN);
+			return entry_idx;
+		}
+		bitmap = bitmap >> 1;
+	}
+	return TOTAL_CAM_ENTRY;
+}
+EXPORT_SYMBOL(rtl_cam_get_free_entry);
+
+void rtl_cam_del_entry(struct ieee80211_hw *hw, u8 *sta_addr)
+{
+	struct rtl_priv *rtlpriv = rtl_priv(hw);
+	u32 bitmap;
+	u8 i, *addr;
+
+	if (NULL == sta_addr) {
+		RT_TRACE(rtlpriv, COMP_SEC, DBG_EMERG,
+			("sta_addr is NULL.\n"));
+	}
+
+	if ((sta_addr[0]|sta_addr[1]|sta_addr[2]|sta_addr[3]|\
+				sta_addr[4]|sta_addr[5]) == 0) {
+		RT_TRACE(rtlpriv, COMP_SEC, DBG_EMERG,
+			("sta_addr is 00:00:00:00:00:00.\n"));
+		return;
+	}
+	/* Does STA already exist? */
+	for (i = 4; i < TOTAL_CAM_ENTRY; i++) {
+		addr = rtlpriv->sec.hwsec_cam_sta_addr[i];
+		bitmap = (rtlpriv->sec.hwsec_cam_bitmap) >> i;
+		if (((bitmap & BIT(0)) == BIT(0)) &&
+		    (memcmp(addr, sta_addr, ETH_ALEN) == 0)) {
+			/* Remove from HW Security CAM */
+			memset(rtlpriv->sec.hwsec_cam_sta_addr[i], 0, ETH_ALEN);
+			rtlpriv->sec.hwsec_cam_bitmap &= ~(BIT(0) << i);
+			printk(KERN_INFO "&&&&&&&&&del entry %d\n", i);
+		}
+	}
+	return;
+}
+EXPORT_SYMBOL(rtl_cam_del_entry);
diff -druN linux-2.6.39-libre/drivers/net/wireless/rtlwifi/cam.h linux-3.0-rc7-libre/drivers/net/wireless/rtlwifi/cam.h
--- linux-2.6.39-libre/drivers/net/wireless/rtlwifi/cam.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/rtlwifi/cam.h	2011-07-11 19:51:52.000000000 -0400
@@ -23,12 +23,13 @@
  * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
  * Hsinchu 300, Taiwan.
  *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
  *****************************************************************************/
 
 #ifndef __RTL_CAM_H_
 #define __RTL_CAM_H_
 
-#define TOTAL_CAM_ENTRY					32
 #define CAM_CONTENT_COUNT				8
 
 #define CFG_DEFAULT_KEY					BIT(5)
@@ -49,5 +50,7 @@
 void rtl_cam_mark_invalid(struct ieee80211_hw *hw, u8 uc_index);
 void rtl_cam_empty_entry(struct ieee80211_hw *hw, u8 uc_index);
 void rtl_cam_reset_sec_info(struct ieee80211_hw *hw);
+u8 rtl_cam_get_free_entry(struct ieee80211_hw *hw, u8 *sta_addr);
+void rtl_cam_del_entry(struct ieee80211_hw *hw, u8 *sta_addr);
 
 #endif
diff -druN linux-2.6.39-libre/drivers/net/wireless/rtlwifi/core.c linux-3.0-rc7-libre/drivers/net/wireless/rtlwifi/core.c
--- linux-2.6.39-libre/drivers/net/wireless/rtlwifi/core.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/rtlwifi/core.c	2011-07-11 19:51:52.000000000 -0400
@@ -24,6 +24,7 @@
  * Hsinchu 300, Taiwan.
  *
  * Larry Finger <Larry.Finger@lwfinger.net>
+ *
  *****************************************************************************/
 
 #include "wifi.h"
@@ -35,7 +36,7 @@
 /*mutex for start & stop is must here. */
 static int rtl_op_start(struct ieee80211_hw *hw)
 {
-	int err = 0;
+	int err;
 	struct rtl_priv *rtlpriv = rtl_priv(hw);
 	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
 
@@ -45,10 +46,8 @@
 		return 0;
 	mutex_lock(&rtlpriv->locks.conf_mutex);
 	err = rtlpriv->intf_ops->adapter_start(hw);
-	if (err)
-		goto out;
-	rtl_watch_dog_timer_callback((unsigned long)hw);
-out:
+	if (!err)
+		rtl_watch_dog_timer_callback((unsigned long)hw);
 	mutex_unlock(&rtlpriv->locks.conf_mutex);
 	return err;
 }
@@ -72,6 +71,7 @@
 
 	mac->link_state = MAC80211_NOLINK;
 	memset(mac->bssid, 0, 6);
+	mac->vendor = PEER_UNKNOWN;
 
 	/*reset sec info */
 	rtl_cam_reset_sec_info(hw);
@@ -87,6 +87,8 @@
 	struct rtl_priv *rtlpriv = rtl_priv(hw);
 	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
 	struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
+	struct rtl_tcb_desc tcb_desc;
+	memset(&tcb_desc, 0, sizeof(struct rtl_tcb_desc));
 
 	if (unlikely(is_hal_stop(rtlhal) || ppsc->rfpwr_state != ERFON))
 		goto err_free;
@@ -94,8 +96,8 @@
 	if (!test_bit(RTL_STATUS_INTERFACE_START, &rtlpriv->status))
 		goto err_free;
 
-
-	rtlpriv->intf_ops->adapter_tx(hw, skb);
+	if (!rtlpriv->intf_ops->waitq_insert(hw, skb))
+		rtlpriv->intf_ops->adapter_tx(hw, skb, &tcb_desc);
 
 	return;
 
@@ -136,10 +138,26 @@
 
 		mac->link_state = MAC80211_LINKED;
 		rtlpriv->cfg->ops->set_bcn_reg(hw);
+		if (rtlpriv->rtlhal.current_bandtype == BAND_ON_2_4G)
+			mac->basic_rates = 0xfff;
+		else
+			mac->basic_rates = 0xff0;
+		rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_BASIC_RATE,
+				(u8 *) (&mac->basic_rates));
+
 		break;
 	case NL80211_IFTYPE_AP:
 		RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD,
 			 ("NL80211_IFTYPE_AP\n"));
+
+		mac->link_state = MAC80211_LINKED;
+		rtlpriv->cfg->ops->set_bcn_reg(hw);
+		if (rtlpriv->rtlhal.current_bandtype == BAND_ON_2_4G)
+			mac->basic_rates = 0xfff;
+		else
+			mac->basic_rates = 0xff0;
+		rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_BASIC_RATE,
+				(u8 *) (&mac->basic_rates));
 		break;
 	default:
 		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
@@ -186,13 +204,12 @@
 	mac->vif = NULL;
 	mac->link_state = MAC80211_NOLINK;
 	memset(mac->bssid, 0, 6);
+	mac->vendor = PEER_UNKNOWN;
 	mac->opmode = NL80211_IFTYPE_UNSPECIFIED;
 	rtlpriv->cfg->ops->set_network_type(hw, mac->opmode);
-
 	mutex_unlock(&rtlpriv->locks.conf_mutex);
 }
 
-
 static int rtl_op_config(struct ieee80211_hw *hw, u32 changed)
 {
 	struct rtl_priv *rtlpriv = rtl_priv(hw);
@@ -224,10 +241,25 @@
 
 	/*For LPS */
 	if (changed & IEEE80211_CONF_CHANGE_PS) {
-		if (conf->flags & IEEE80211_CONF_PS)
-			rtl_lps_enter(hw);
-		else
-			rtl_lps_leave(hw);
+		cancel_delayed_work(&rtlpriv->works.ps_work);
+		cancel_delayed_work(&rtlpriv->works.ps_rfon_wq);
+		if (conf->flags & IEEE80211_CONF_PS) {
+			rtlpriv->psc.sw_ps_enabled = true;
+			/* sleep here is must, or we may recv the beacon and
+			 * cause mac80211 into wrong ps state, this will cause
+			 * power save nullfunc send fail, and further cause
+			 * pkt loss, So sleep must quickly but not immediatly
+			 * because that will cause nullfunc send by mac80211
+			 * fail, and cause pkt loss, we have tested that 5mA
+			 * is worked very well */
+			if (!rtlpriv->psc.multi_buffered)
+				queue_delayed_work(rtlpriv->works.rtl_wq,
+						&rtlpriv->works.ps_work,
+						MSECS(5));
+		} else {
+			rtl_swlps_rf_awake(hw);
+			rtlpriv->psc.sw_ps_enabled = false;
+		}
 	}
 
 	if (changed & IEEE80211_CONF_CHANGE_RETRY_LIMITS) {
@@ -259,7 +291,7 @@
 		case NL80211_CHAN_NO_HT:
 			/* SC */
 			mac->cur_40_prime_sc =
-			    PRIME_CHNL_OFFSET_DONT_CARE;
+				PRIME_CHNL_OFFSET_DONT_CARE;
 			rtlphy->current_chan_bw = HT_CHANNEL_WIDTH_20;
 			mac->bw_40 = false;
 			break;
@@ -267,7 +299,7 @@
 			/* SC */
 			mac->cur_40_prime_sc = PRIME_CHNL_OFFSET_UPPER;
 			rtlphy->current_chan_bw =
-			    HT_CHANNEL_WIDTH_20_40;
+				HT_CHANNEL_WIDTH_20_40;
 			mac->bw_40 = true;
 
 			/*wide channel */
@@ -278,7 +310,7 @@
 			/* SC */
 			mac->cur_40_prime_sc = PRIME_CHNL_OFFSET_LOWER;
 			rtlphy->current_chan_bw =
-			    HT_CHANNEL_WIDTH_20_40;
+				HT_CHANNEL_WIDTH_20_40;
 			mac->bw_40 = true;
 
 			/*wide channel */
@@ -288,16 +320,29 @@
 		default:
 			mac->bw_40 = false;
 			RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-				 ("switch case not processed\n"));
+					("switch case not processed\n"));
 			break;
 		}
 
 		if (wide_chan <= 0)
 			wide_chan = 1;
+
+		/* In scanning, before we go offchannel we may send a ps=1 null
+		 * to AP, and then we may send a ps = 0 null to AP quickly, but
+		 * first null may have caused AP to put lots of packet to hw tx
+		 * buffer. These packets must be tx'd before we go off channel
+		 * so we must delay more time to let AP flush these packets
+		 * before going offchannel, or dis-association or delete BA will
+		 * happen by AP
+		 */
+		if (rtlpriv->mac80211.offchan_deley) {
+			rtlpriv->mac80211.offchan_deley = false;
+			mdelay(50);
+		}
 		rtlphy->current_channel = wide_chan;
 
-		rtlpriv->cfg->ops->set_channel_access(hw);
 		rtlpriv->cfg->ops->switch_channel(hw);
+		rtlpriv->cfg->ops->set_channel_access(hw);
 		rtlpriv->cfg->ops->set_bw_mode(hw,
 					       hw->conf.channel_type);
 	}
@@ -345,27 +390,28 @@
 		}
 	}
 
-	if (changed_flags & FIF_BCN_PRBRESP_PROMISC) {
-		/*
-		 *TODO: BIT(5) is probe response BIT(8) is beacon
-		 *TODO: Use define for BIT(5) and BIT(8)
-		 */
-		if (*new_flags & FIF_BCN_PRBRESP_PROMISC)
-			mac->rx_mgt_filter |= (BIT(5) | BIT(8));
-		else
-			mac->rx_mgt_filter &= ~(BIT(5) | BIT(8));
+	/* if ssid not set to hw don't check bssid
+	 * here just used for linked scanning, & linked
+	 * and nolink check bssid is set in set network_type */
+	if ((changed_flags & FIF_BCN_PRBRESP_PROMISC) &&
+		(mac->link_state >= MAC80211_LINKED)) {
+		if (mac->opmode != NL80211_IFTYPE_AP) {
+			if (*new_flags & FIF_BCN_PRBRESP_PROMISC) {
+				rtlpriv->cfg->ops->set_chk_bssid(hw, false);
+			} else {
+				rtlpriv->cfg->ops->set_chk_bssid(hw, true);
+			}
+		}
 	}
 
 	if (changed_flags & FIF_CONTROL) {
 		if (*new_flags & FIF_CONTROL) {
 			mac->rx_conf |= rtlpriv->cfg->maps[MAC_RCR_ACF];
-			mac->rx_ctrl_filter |= RTL_SUPPORTED_CTRL_FILTER;
 
 			RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD,
 				 ("Enable receive control frame.\n"));
 		} else {
 			mac->rx_conf &= ~rtlpriv->cfg->maps[MAC_RCR_ACF];
-			mac->rx_ctrl_filter &= ~RTL_SUPPORTED_CTRL_FILTER;
 			RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD,
 				 ("Disable receive control frame.\n"));
 		}
@@ -382,14 +428,54 @@
 				 ("Disable receive other BSS's frame.\n"));
 		}
 	}
-
-	rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RCR, (u8 *) (&mac->rx_conf));
-	rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_MGT_FILTER,
-				      (u8 *) (&mac->rx_mgt_filter));
-	rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_CTRL_FILTER,
-				      (u8 *) (&mac->rx_ctrl_filter));
 }
+static int rtl_op_sta_add(struct ieee80211_hw *hw,
+			 struct ieee80211_vif *vif,
+			 struct ieee80211_sta *sta)
+{
+	struct rtl_priv *rtlpriv = rtl_priv(hw);
+	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+	struct rtl_sta_info *sta_entry;
+
+	if (sta) {
+		sta_entry = (struct rtl_sta_info *) sta->drv_priv;
+		if (rtlhal->current_bandtype == BAND_ON_2_4G) {
+			sta_entry->wireless_mode = WIRELESS_MODE_G;
+			if (sta->supp_rates[0] <= 0xf)
+				sta_entry->wireless_mode = WIRELESS_MODE_B;
+			if (sta->ht_cap.ht_supported == true)
+				sta_entry->wireless_mode = WIRELESS_MODE_N_24G;
+		} else if (rtlhal->current_bandtype == BAND_ON_5G) {
+			sta_entry->wireless_mode = WIRELESS_MODE_A;
+			if (sta->ht_cap.ht_supported == true)
+				sta_entry->wireless_mode = WIRELESS_MODE_N_24G;
+		}
 
+		/* I found some times mac80211 give wrong supp_rates for adhoc*/
+		if (rtlpriv->mac80211.opmode == NL80211_IFTYPE_ADHOC)
+			sta_entry->wireless_mode = WIRELESS_MODE_G;
+
+		RT_TRACE(rtlpriv, COMP_MAC80211, DBG_DMESG,
+			("Add sta addr is "MAC_FMT"\n", MAC_ARG(sta->addr)));
+		rtlpriv->cfg->ops->update_rate_tbl(hw, sta, 0);
+	}
+	return 0;
+}
+static int rtl_op_sta_remove(struct ieee80211_hw *hw,
+				struct ieee80211_vif *vif,
+				struct ieee80211_sta *sta)
+{
+	struct rtl_priv *rtlpriv = rtl_priv(hw);
+	struct rtl_sta_info *sta_entry;
+	if (sta) {
+		RT_TRACE(rtlpriv, COMP_MAC80211, DBG_DMESG,
+			("Remove sta addr is "MAC_FMT"\n", MAC_ARG(sta->addr)));
+		sta_entry = (struct rtl_sta_info *) sta->drv_priv;
+		sta_entry->wireless_mode = 0;
+		sta_entry->ratr_index = 0;
+	}
+	return 0;
+}
 static int _rtl_get_hal_qnum(u16 queue)
 {
 	int qnum;
@@ -446,19 +532,18 @@
 			     struct ieee80211_bss_conf *bss_conf, u32 changed)
 {
 	struct rtl_priv *rtlpriv = rtl_priv(hw);
+	struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
 	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
 	struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
+	struct ieee80211_sta *sta = NULL;
 
 	mutex_lock(&rtlpriv->locks.conf_mutex);
-
 	if ((vif->type == NL80211_IFTYPE_ADHOC) ||
 	    (vif->type == NL80211_IFTYPE_AP) ||
 	    (vif->type == NL80211_IFTYPE_MESH_POINT)) {
-
 		if ((changed & BSS_CHANGED_BEACON) ||
 		    (changed & BSS_CHANGED_BEACON_ENABLED &&
 		     bss_conf->enable_beacon)) {
-
 			if (mac->beacon_enabled == 0) {
 				RT_TRACE(rtlpriv, COMP_MAC80211, DBG_DMESG,
 					 ("BSS_CHANGED_BEACON_ENABLED\n"));
@@ -470,8 +555,13 @@
 						rtlpriv->cfg->maps
 						[RTL_IBSS_INT_MASKS],
 						0);
+
+				if (rtlpriv->cfg->ops->linked_set_reg)
+					rtlpriv->cfg->ops->linked_set_reg(hw);
 			}
-		} else {
+		}
+		if ((changed & BSS_CHANGED_BEACON_ENABLED &&
+			!bss_conf->enable_beacon)) {
 			if (mac->beacon_enabled == 1) {
 				RT_TRACE(rtlpriv, COMP_MAC80211, DBG_DMESG,
 					 ("ADHOC DISABLE BEACON\n"));
@@ -482,7 +572,6 @@
 						[RTL_IBSS_INT_MASKS]);
 			}
 		}
-
 		if (changed & BSS_CHANGED_BEACON_INT) {
 			RT_TRACE(rtlpriv, COMP_BEACON, DBG_TRACE,
 				 ("BSS_CHANGED_BEACON_INT\n"));
@@ -494,11 +583,25 @@
 	/*TODO: reference to enum ieee80211_bss_change */
 	if (changed & BSS_CHANGED_ASSOC) {
 		if (bss_conf->assoc) {
+			/* we should reset all sec info & cam
+			 * before set cam after linked, we should not
+			 * reset in disassoc, that will cause tkip->wep
+			 * fail because some flag will be wrong */
+			/* reset sec info */
+			rtl_cam_reset_sec_info(hw);
+			/* reset cam to fix wep fail issue
+			 * when change from wpa to wep */
+			rtl_cam_reset_all_entry(hw);
+
 			mac->link_state = MAC80211_LINKED;
 			mac->cnt_after_linked = 0;
 			mac->assoc_id = bss_conf->aid;
 			memcpy(mac->bssid, bss_conf->bssid, 6);
 
+			if (rtlpriv->cfg->ops->linked_set_reg)
+				rtlpriv->cfg->ops->linked_set_reg(hw);
+			if (mac->opmode == NL80211_IFTYPE_STATION && sta)
+				rtlpriv->cfg->ops->update_rate_tbl(hw, sta, 0);
 			RT_TRACE(rtlpriv, COMP_MAC80211, DBG_DMESG,
 				 ("BSS_CHANGED_ASSOC\n"));
 		} else {
@@ -507,9 +610,7 @@
 
 			mac->link_state = MAC80211_NOLINK;
 			memset(mac->bssid, 0, 6);
-
-			/* reset sec info */
-			rtl_cam_reset_sec_info(hw);
+			mac->vendor = PEER_UNKNOWN;
 
 			RT_TRACE(rtlpriv, COMP_MAC80211, DBG_DMESG,
 				 ("BSS_CHANGED_UN_ASSOC\n"));
@@ -546,14 +647,10 @@
 	}
 
 	if (changed & BSS_CHANGED_HT) {
-		struct ieee80211_sta *sta = NULL;
-
 		RT_TRACE(rtlpriv, COMP_MAC80211, DBG_TRACE,
 			 ("BSS_CHANGED_HT\n"));
-
 		rcu_read_lock();
-		sta = ieee80211_find_sta(mac->vif, mac->bssid);
-
+		sta = get_sta(hw, vif, (u8 *)bss_conf->bssid);
 		if (sta) {
 			if (sta->ht_cap.ampdu_density >
 			    mac->current_ampdu_density)
@@ -575,9 +672,7 @@
 	}
 
 	if (changed & BSS_CHANGED_BSSID) {
-		struct ieee80211_sta *sta = NULL;
 		u32 basic_rates;
-		u8 i;
 
 		rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_BSSID,
 					      (u8 *) bss_conf->bssid);
@@ -585,96 +680,65 @@
 		RT_TRACE(rtlpriv, COMP_MAC80211, DBG_DMESG,
 			 (MAC_FMT "\n", MAC_ARG(bss_conf->bssid)));
 
+		mac->vendor = PEER_UNKNOWN;
 		memcpy(mac->bssid, bss_conf->bssid, 6);
-		if (is_valid_ether_addr(bss_conf->bssid)) {
-			switch (vif->type) {
-			case NL80211_IFTYPE_UNSPECIFIED:
-				break;
-			case NL80211_IFTYPE_ADHOC:
-				break;
-			case NL80211_IFTYPE_STATION:
-				break;
-			case NL80211_IFTYPE_AP:
-				break;
-			default:
-				RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-					 ("switch case not process\n"));
-				break;
-			}
-			rtlpriv->cfg->ops->set_network_type(hw, vif->type);
-		} else
-			rtlpriv->cfg->ops->set_network_type(hw,
-					NL80211_IFTYPE_UNSPECIFIED);
-
-		memset(mac->mcs, 0, 16);
-		mac->ht_enable = false;
-		mac->sgi_40 = false;
-		mac->sgi_20 = false;
-
-		if (!bss_conf->use_short_slot)
-			mac->mode = WIRELESS_MODE_B;
-		else
-			mac->mode = WIRELESS_MODE_G;
+		rtlpriv->cfg->ops->set_network_type(hw, vif->type);
 
 		rcu_read_lock();
-		sta = ieee80211_find_sta(mac->vif, mac->bssid);
-
-		if (sta) {
-			if (sta->ht_cap.ht_supported) {
-				mac->mode = WIRELESS_MODE_N_24G;
-				mac->ht_enable = true;
-			}
+		sta = get_sta(hw, vif, (u8 *)bss_conf->bssid);
+		if (!sta) {
+			rcu_read_unlock();
+			goto out;
+		}
 
-			if (mac->ht_enable) {
-				u16 ht_cap = sta->ht_cap.cap;
-				memcpy(mac->mcs, (u8 *) (&sta->ht_cap.mcs), 16);
+		if (rtlhal->current_bandtype == BAND_ON_5G) {
+			mac->mode = WIRELESS_MODE_A;
+		} else {
+			if (sta->supp_rates[0] <= 0xf)
+				mac->mode = WIRELESS_MODE_B;
+			else
+				mac->mode = WIRELESS_MODE_G;
+		}
 
-				for (i = 0; i < 16; i++)
-					RT_TRACE(rtlpriv, COMP_MAC80211,
-						 DBG_LOUD, ("%x ",
-							    mac->mcs[i]));
-				RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD,
-					 ("\n"));
+		if (sta->ht_cap.ht_supported) {
+			if (rtlhal->current_bandtype == BAND_ON_2_4G)
+				mac->mode = WIRELESS_MODE_N_24G;
+			else
+				mac->mode = WIRELESS_MODE_N_5G;
+		}
 
-				if (ht_cap & IEEE80211_HT_CAP_SGI_40)
-					mac->sgi_40 = true;
+		/* just station need it, because ibss & ap mode will
+		 * set in sta_add, and will be NULL here */
+		if (mac->opmode == NL80211_IFTYPE_STATION) {
+			struct rtl_sta_info *sta_entry;
+			sta_entry = (struct rtl_sta_info *) sta->drv_priv;
+			sta_entry->wireless_mode = mac->mode;
+		}
 
-				if (ht_cap & IEEE80211_HT_CAP_SGI_20)
-					mac->sgi_20 = true;
+		if (sta->ht_cap.ht_supported) {
+			mac->ht_enable = true;
 
-				/*
-				 * for cisco 1252 bw20 it's wrong
-				 * if (ht_cap &
-				 *     IEEE80211_HT_CAP_SUP_WIDTH_20_40) {
-				 *	mac->bw_40 = true;
-				 * }
-				 */
-			}
+			/*
+			 * for cisco 1252 bw20 it's wrong
+			 * if (ht_cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) {
+			 *	mac->bw_40 = true;
+			 * }
+			 * */
 		}
-		rcu_read_unlock();
 
-		/*mac80211 just give us CCK rates any time
-		 *So we add G rate in basic rates when
-		 not in B mode*/
 		if (changed & BSS_CHANGED_BASIC_RATES) {
-			if (mac->mode == WIRELESS_MODE_B)
-				basic_rates = bss_conf->basic_rates | 0x00f;
+			/* for 5G must << RATE_6M_INDEX=4,
+			 * because 5G have no cck rate*/
+			if (rtlhal->current_bandtype == BAND_ON_5G)
+				basic_rates = sta->supp_rates[1] << 4;
 			else
-				basic_rates = bss_conf->basic_rates | 0xff0;
-
-			if (!vif)
-				goto out;
+				basic_rates = sta->supp_rates[0];
 
 			mac->basic_rates = basic_rates;
 			rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_BASIC_RATE,
 					(u8 *) (&basic_rates));
-
-			if (rtlpriv->dm.useramask)
-				rtlpriv->cfg->ops->update_rate_mask(hw, 0);
-			else
-				rtlpriv->cfg->ops->update_rate_table(hw);
-
 		}
+		rcu_read_unlock();
 	}
 
 	/*
@@ -719,7 +783,7 @@
 {
 	struct rtl_priv *rtlpriv = rtl_priv(hw);
 	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
-	u8 bibss = (mac->opmode == NL80211_IFTYPE_ADHOC) ? 1 : 0;;
+	u8 bibss = (mac->opmode == NL80211_IFTYPE_ADHOC) ? 1 : 0;
 
 	mac->tsf = tsf;
 	rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_CORRECT_TSF, (u8 *) (&bibss));
@@ -760,16 +824,17 @@
 	case IEEE80211_AMPDU_TX_START:
 		RT_TRACE(rtlpriv, COMP_MAC80211, DBG_TRACE,
 			 ("IEEE80211_AMPDU_TX_START: TID:%d\n", tid));
-		return rtl_tx_agg_start(hw, sta->addr, tid, ssn);
+		return rtl_tx_agg_start(hw, sta, tid, ssn);
 		break;
 	case IEEE80211_AMPDU_TX_STOP:
 		RT_TRACE(rtlpriv, COMP_MAC80211, DBG_TRACE,
 			 ("IEEE80211_AMPDU_TX_STOP: TID:%d\n", tid));
-		return rtl_tx_agg_stop(hw, sta->addr, tid);
+		return rtl_tx_agg_stop(hw, sta, tid);
 		break;
 	case IEEE80211_AMPDU_TX_OPERATIONAL:
 		RT_TRACE(rtlpriv, COMP_MAC80211, DBG_TRACE,
 			 ("IEEE80211_AMPDU_TX_OPERATIONAL:TID:%d\n", tid));
+		rtl_tx_agg_oper(hw, sta, tid);
 		break;
 	case IEEE80211_AMPDU_RX_START:
 		RT_TRACE(rtlpriv, COMP_MAC80211, DBG_TRACE,
@@ -799,8 +864,12 @@
 	if (mac->link_state == MAC80211_LINKED) {
 		rtl_lps_leave(hw);
 		mac->link_state = MAC80211_LINKED_SCANNING;
-	} else
+	} else {
 		rtl_ips_nic_on(hw);
+	}
+
+	/* Dual mac */
+	rtlpriv->rtlhal.load_imrandiqk_setting_for2g = false;
 
 	rtlpriv->cfg->ops->led_control(hw, LED_CTL_SITE_SURVEY);
 	rtlpriv->cfg->ops->scan_operation_backup(hw, SCAN_OPT_BACKUP);
@@ -812,22 +881,19 @@
 	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
 
 	RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, ("\n"));
-
-	rtlpriv->cfg->ops->scan_operation_backup(hw, SCAN_OPT_RESTORE);
 	mac->act_scanning = false;
+	/* Dual mac */
+	rtlpriv->rtlhal.load_imrandiqk_setting_for2g = false;
+
 	if (mac->link_state == MAC80211_LINKED_SCANNING) {
 		mac->link_state = MAC80211_LINKED;
-
-		/* fix fwlps issue */
-		rtlpriv->cfg->ops->set_network_type(hw, mac->opmode);
-
-		if (rtlpriv->dm.useramask)
-			rtlpriv->cfg->ops->update_rate_mask(hw, 0);
-		else
-			rtlpriv->cfg->ops->update_rate_table(hw);
-
+		if (mac->opmode == NL80211_IFTYPE_STATION) {
+			/* fix fwlps issue */
+			rtlpriv->cfg->ops->set_network_type(hw, mac->opmode);
+		}
 	}
 
+	rtlpriv->cfg->ops->scan_operation_backup(hw, SCAN_OPT_RESTORE);
 }
 
 static int rtl_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
@@ -858,49 +924,73 @@
 	rtl_ips_nic_on(hw);
 	mutex_lock(&rtlpriv->locks.conf_mutex);
 	/* <1> get encryption alg */
+
 	switch (key->cipher) {
 	case WLAN_CIPHER_SUITE_WEP40:
 		key_type = WEP40_ENCRYPTION;
 		RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, ("alg:WEP40\n"));
-		rtlpriv->sec.use_defaultkey = true;
 		break;
 	case WLAN_CIPHER_SUITE_WEP104:
 		RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
 			 ("alg:WEP104\n"));
 		key_type = WEP104_ENCRYPTION;
-		rtlpriv->sec.use_defaultkey = true;
 		break;
 	case WLAN_CIPHER_SUITE_TKIP:
 		key_type = TKIP_ENCRYPTION;
 		RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, ("alg:TKIP\n"));
-		if (mac->opmode == NL80211_IFTYPE_ADHOC)
-			rtlpriv->sec.use_defaultkey = true;
 		break;
 	case WLAN_CIPHER_SUITE_CCMP:
 		key_type = AESCCMP_ENCRYPTION;
 		RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, ("alg:CCMP\n"));
-		if (mac->opmode == NL80211_IFTYPE_ADHOC)
-			rtlpriv->sec.use_defaultkey = true;
 		break;
 	default:
 		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
 			 ("alg_err:%x!!!!:\n", key->cipher));
 		goto out_unlock;
 	}
+	if (key_type == WEP40_ENCRYPTION ||
+			key_type == WEP104_ENCRYPTION ||
+			mac->opmode == NL80211_IFTYPE_ADHOC)
+		rtlpriv->sec.use_defaultkey = true;
+
 	/* <2> get key_idx */
 	key_idx = (u8) (key->keyidx);
 	if (key_idx > 3)
 		goto out_unlock;
 	/* <3> if pairwise key enable_hw_sec */
 	group_key = !(key->flags & IEEE80211_KEY_FLAG_PAIRWISE);
-	if ((!group_key) || (mac->opmode == NL80211_IFTYPE_ADHOC) ||
-	    rtlpriv->sec.pairwise_enc_algorithm == NO_ENCRYPTION) {
-		if (rtlpriv->sec.pairwise_enc_algorithm == NO_ENCRYPTION &&
-		    (key_type == WEP40_ENCRYPTION ||
-		     key_type == WEP104_ENCRYPTION))
-			wep_only = true;
-		rtlpriv->sec.pairwise_enc_algorithm = key_type;
-		rtlpriv->cfg->ops->enable_hw_sec(hw);
+
+	/* wep always be group key, but there are two conditions:
+	 * 1) wep only: is just for wep enc, in this condition
+	 * rtlpriv->sec.pairwise_enc_algorithm == NO_ENCRYPTION
+	 * will be true & enable_hw_sec will be set when wep
+	 * ke setting.
+	 * 2) wep(group) + AES(pairwise): some AP like cisco
+	 * may use it, in this condition enable_hw_sec will not
+	 * be set when wep key setting */
+	/* we must reset sec_info after lingked before set key,
+	 * or some flag will be wrong*/
+	if (mac->opmode == NL80211_IFTYPE_AP) {
+		if (!group_key || key_type == WEP40_ENCRYPTION ||
+			key_type == WEP104_ENCRYPTION) {
+			if (group_key)
+				wep_only = true;
+			rtlpriv->cfg->ops->enable_hw_sec(hw);
+		}
+	} else {
+		if ((!group_key) || (mac->opmode == NL80211_IFTYPE_ADHOC) ||
+		     rtlpriv->sec.pairwise_enc_algorithm == NO_ENCRYPTION) {
+			if (rtlpriv->sec.pairwise_enc_algorithm ==
+			    NO_ENCRYPTION &&
+			    (key_type == WEP40_ENCRYPTION ||
+			    key_type == WEP104_ENCRYPTION))
+				wep_only = true;
+			rtlpriv->sec.pairwise_enc_algorithm = key_type;
+			RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
+				("set enable_hw_sec, key_type:%x(OPEN:0 WEP40:1"
+				" TKIP:2 AES:4 WEP104:5)\n", key_type));
+			rtlpriv->cfg->ops->enable_hw_sec(hw);
+		}
 	}
 	/* <4> set key based on cmd */
 	switch (cmd) {
@@ -932,6 +1022,7 @@
 			if (!sta) {
 				RT_ASSERT(false, ("pairwise key withnot"
 						  "mac_addr\n"));
+
 				err = -EOPNOTSUPP;
 				goto out_unlock;
 			}
@@ -959,6 +1050,10 @@
 		RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
 			 ("disable key delete one entry\n"));
 		/*set local buf about wep key. */
+		if (mac->opmode == NL80211_IFTYPE_AP) {
+			if (sta)
+				rtl_cam_del_entry(hw, sta->addr);
+		}
 		memset(rtlpriv->sec.key_buf[key_idx], 0, key->keylen);
 		rtlpriv->sec.key_len[key_idx] = 0;
 		memcpy(mac_addr, zero_addr, ETH_ALEN);
@@ -1011,6 +1106,18 @@
 	mutex_unlock(&rtlpriv->locks.conf_mutex);
 }
 
+/* this function is called by mac80211 to flush tx buffer
+ * before switch channle or power save, or tx buffer packet
+ * maybe send after offchannel or rf sleep, this may cause
+ * dis-association by AP */
+static void rtl_op_flush(struct ieee80211_hw *hw, bool drop)
+{
+	struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+	if (rtlpriv->intf_ops->flush)
+		rtlpriv->intf_ops->flush(hw, drop);
+}
+
 const struct ieee80211_ops rtl_ops = {
 	.start = rtl_op_start,
 	.stop = rtl_op_stop,
@@ -1019,6 +1126,8 @@
 	.remove_interface = rtl_op_remove_interface,
 	.config = rtl_op_config,
 	.configure_filter = rtl_op_configure_filter,
+	.sta_add = rtl_op_sta_add,
+	.sta_remove = rtl_op_sta_remove,
 	.set_key = rtl_op_set_key,
 	.conf_tx = rtl_op_conf_tx,
 	.bss_info_changed = rtl_op_bss_info_changed,
@@ -1030,4 +1139,5 @@
 	.sw_scan_start = rtl_op_sw_scan_start,
 	.sw_scan_complete = rtl_op_sw_scan_complete,
 	.rfkill_poll = rtl_op_rfkill_poll,
+	.flush = rtl_op_flush,
 };
diff -druN linux-2.6.39-libre/drivers/net/wireless/rtlwifi/core.h linux-3.0-rc7-libre/drivers/net/wireless/rtlwifi/core.h
--- linux-2.6.39-libre/drivers/net/wireless/rtlwifi/core.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/rtlwifi/core.h	2011-07-11 19:51:52.000000000 -0400
@@ -24,6 +24,7 @@
  * Hsinchu 300, Taiwan.
  *
  * Larry Finger <Larry.Finger@lwfinger.net>
+ *
  *****************************************************************************/
 
 #ifndef __RTL_CORE_H__
diff -druN linux-2.6.39-libre/drivers/net/wireless/rtlwifi/efuse.c linux-3.0-rc7-libre/drivers/net/wireless/rtlwifi/efuse.c
--- linux-2.6.39-libre/drivers/net/wireless/rtlwifi/efuse.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/rtlwifi/efuse.c	2011-07-11 19:51:52.000000000 -0400
@@ -52,8 +52,6 @@
 	{11, 0, 0, 28}
 };
 
-static void read_efuse_byte(struct ieee80211_hw *hw, u16 _offset,
-					u8 *pbuf);
 static void efuse_shadow_read_1byte(struct ieee80211_hw *hw, u16 offset,
 				    u8 *value);
 static void efuse_shadow_read_2byte(struct ieee80211_hw *hw, u16 offset,
@@ -79,7 +77,7 @@
 					u8 *targetdata);
 static u8 efuse_word_enable_data_write(struct ieee80211_hw *hw,
 				       u16 efuse_addr, u8 word_en, u8 *data);
-static void efuse_power_switch(struct ieee80211_hw *hw, u8 bwrite,
+static void efuse_power_switch(struct ieee80211_hw *hw, u8 write,
 					u8 pwrstate);
 static u16 efuse_get_current_size(struct ieee80211_hw *hw);
 static u8 efuse_calculate_word_cnts(u8 word_en);
@@ -115,8 +113,10 @@
 	u8 bytetemp;
 	u8 temp;
 	u32 k = 0;
+	const u32 efuse_len =
+		rtlpriv->cfg->maps[EFUSE_REAL_CONTENT_SIZE];
 
-	if (address < EFUSE_REAL_CONTENT_LEN) {
+	if (address < efuse_len) {
 		temp = address & 0xFF;
 		rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL] + 1,
 			       temp);
@@ -158,11 +158,13 @@
 	u8 bytetemp;
 	u8 temp;
 	u32 k = 0;
+	const u32 efuse_len =
+		rtlpriv->cfg->maps[EFUSE_REAL_CONTENT_SIZE];
 
 	RT_TRACE(rtlpriv, COMP_EFUSE, DBG_LOUD,
 		 ("Addr=%x Data =%x\n", address, value));
 
-	if (address < EFUSE_REAL_CONTENT_LEN) {
+	if (address < efuse_len) {
 		rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL], value);
 
 		temp = address & 0xFF;
@@ -198,7 +200,7 @@
 
 }
 
-static void read_efuse_byte(struct ieee80211_hw *hw, u16 _offset, u8 *pbuf)
+void read_efuse_byte(struct ieee80211_hw *hw, u16 _offset, u8 *pbuf)
 {
 	struct rtl_priv *rtlpriv = rtl_priv(hw);
 	u32 value32;
@@ -233,26 +235,45 @@
 {
 	struct rtl_priv *rtlpriv = rtl_priv(hw);
 	struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
-	u8 efuse_tbl[EFUSE_MAP_LEN];
+	u8 *efuse_tbl;
 	u8 rtemp8[1];
 	u16 efuse_addr = 0;
 	u8 offset, wren;
 	u16 i;
 	u16 j;
-	u16 efuse_word[EFUSE_MAX_SECTION][EFUSE_MAX_WORD_UNIT];
+	const u16 efuse_max_section =
+		rtlpriv->cfg->maps[EFUSE_MAX_SECTION_MAP];
+	const u32 efuse_len =
+		rtlpriv->cfg->maps[EFUSE_REAL_CONTENT_SIZE];
+	u16 **efuse_word;
 	u16 efuse_utilized = 0;
 	u8 efuse_usage;
 
-	if ((_offset + _size_byte) > EFUSE_MAP_LEN) {
+	if ((_offset + _size_byte) > rtlpriv->cfg->maps[EFUSE_HWSET_MAX_SIZE]) {
 		RT_TRACE(rtlpriv, COMP_EFUSE, DBG_LOUD,
 			 ("read_efuse(): Invalid offset(%#x) with read "
 			  "bytes(%#x)!!\n", _offset, _size_byte));
 		return;
 	}
 
-	for (i = 0; i < EFUSE_MAX_SECTION; i++)
+	/* allocate memory for efuse_tbl and efuse_word */
+	efuse_tbl = kmalloc(rtlpriv->cfg->maps[EFUSE_HWSET_MAX_SIZE] *
+			    sizeof(u8), GFP_ATOMIC);
+	if (!efuse_tbl)
+		return;
+	efuse_word = kmalloc(EFUSE_MAX_WORD_UNIT * sizeof(u16 *), GFP_ATOMIC);
+	if (!efuse_word)
+		goto done;
+	for (i = 0; i < EFUSE_MAX_WORD_UNIT; i++) {
+		efuse_word[i] = kmalloc(efuse_max_section * sizeof(u16),
+					GFP_ATOMIC);
+		if (!efuse_word[i])
+			goto done;
+	}
+
+	for (i = 0; i < efuse_max_section; i++)
 		for (j = 0; j < EFUSE_MAX_WORD_UNIT; j++)
-			efuse_word[i][j] = 0xFFFF;
+			efuse_word[j][i] = 0xFFFF;
 
 	read_efuse_byte(hw, efuse_addr, rtemp8);
 	if (*rtemp8 != 0xFF) {
@@ -262,10 +283,10 @@
 		efuse_addr++;
 	}
 
-	while ((*rtemp8 != 0xFF) && (efuse_addr < EFUSE_REAL_CONTENT_LEN)) {
+	while ((*rtemp8 != 0xFF) && (efuse_addr < efuse_len)) {
 		offset = ((*rtemp8 >> 4) & 0x0f);
 
-		if (offset < EFUSE_MAX_SECTION) {
+		if (offset < efuse_max_section) {
 			wren = (*rtemp8 & 0x0f);
 			RTPRINT(rtlpriv, FEEPROM, EFUSE_READ_ALL,
 				("offset-%d Worden=%x\n", offset, wren));
@@ -279,9 +300,10 @@
 					read_efuse_byte(hw, efuse_addr, rtemp8);
 					efuse_addr++;
 					efuse_utilized++;
-					efuse_word[offset][i] = (*rtemp8 & 0xff);
+					efuse_word[i][offset] =
+							 (*rtemp8 & 0xff);
 
-					if (efuse_addr >= EFUSE_REAL_CONTENT_LEN)
+					if (efuse_addr >= efuse_len)
 						break;
 
 					RTPRINT(rtlpriv, FEEPROM,
@@ -291,10 +313,10 @@
 					read_efuse_byte(hw, efuse_addr, rtemp8);
 					efuse_addr++;
 					efuse_utilized++;
-					efuse_word[offset][i] |=
+					efuse_word[i][offset] |=
 					    (((u16)*rtemp8 << 8) & 0xff00);
 
-					if (efuse_addr >= EFUSE_REAL_CONTENT_LEN)
+					if (efuse_addr >= efuse_len)
 						break;
 				}
 
@@ -305,18 +327,18 @@
 		RTPRINT(rtlpriv, FEEPROM, EFUSE_READ_ALL,
 			("Addr=%d\n", efuse_addr));
 		read_efuse_byte(hw, efuse_addr, rtemp8);
-		if (*rtemp8 != 0xFF && (efuse_addr < 512)) {
+		if (*rtemp8 != 0xFF && (efuse_addr < efuse_len)) {
 			efuse_utilized++;
 			efuse_addr++;
 		}
 	}
 
-	for (i = 0; i < EFUSE_MAX_SECTION; i++) {
+	for (i = 0; i < efuse_max_section; i++) {
 		for (j = 0; j < EFUSE_MAX_WORD_UNIT; j++) {
 			efuse_tbl[(i * 8) + (j * 2)] =
-			    (efuse_word[i][j] & 0xff);
+			    (efuse_word[j][i] & 0xff);
 			efuse_tbl[(i * 8) + ((j * 2) + 1)] =
-			    ((efuse_word[i][j] >> 8) & 0xff);
+			    ((efuse_word[j][i] >> 8) & 0xff);
 		}
 	}
 
@@ -324,12 +346,17 @@
 		pbuf[i] = efuse_tbl[_offset + i];
 
 	rtlefuse->efuse_usedbytes = efuse_utilized;
-	efuse_usage = (u8)((efuse_utilized * 100) / EFUSE_REAL_CONTENT_LEN);
+	efuse_usage = (u8) ((efuse_utilized * 100) / efuse_len);
 	rtlefuse->efuse_usedpercentage = efuse_usage;
 	rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_EFUSE_BYTES,
 				      (u8 *)&efuse_utilized);
 	rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_EFUSE_USAGE,
 				      (u8 *)&efuse_usage);
+done:
+	for (i = 0; i < EFUSE_MAX_WORD_UNIT; i++)
+		kfree(efuse_word[i]);
+	kfree(efuse_word);
+	kfree(efuse_tbl);
 }
 
 bool efuse_shadow_update_chk(struct ieee80211_hw *hw)
@@ -338,11 +365,11 @@
 	struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
 	u8 section_idx, i, Base;
 	u16 words_need = 0, hdr_num = 0, totalbytes, efuse_used;
-	bool bwordchanged, bresult = true;
+	bool wordchanged, result = true;
 
 	for (section_idx = 0; section_idx < 16; section_idx++) {
 		Base = section_idx * 8;
-		bwordchanged = false;
+		wordchanged = false;
 
 		for (i = 0; i < 8; i = i + 2) {
 			if ((rtlefuse->efuse_map[EFUSE_INIT_MAP][Base + i] !=
@@ -351,11 +378,11 @@
 			     rtlefuse->efuse_map[EFUSE_MODIFY_MAP][Base + i +
 								   1])) {
 				words_need++;
-				bwordchanged = true;
+				wordchanged = true;
 			}
 		}
 
-		if (bwordchanged == true)
+		if (wordchanged == true)
 			hdr_num++;
 	}
 
@@ -364,14 +391,14 @@
 
 	if ((totalbytes + efuse_used) >=
 	    (EFUSE_MAX_SIZE - EFUSE_OOB_PROTECT_BYTES))
-		bresult = false;
+		result = false;
 
 	RT_TRACE(rtlpriv, COMP_EFUSE, DBG_LOUD,
 		 ("efuse_shadow_update_chk(): totalbytes(%#x), "
 		  "hdr_num(%#x), words_need(%#x), efuse_used(%d)\n",
 		  totalbytes, hdr_num, words_need, efuse_used));
 
-	return bresult;
+	return result;
 }
 
 void efuse_shadow_read(struct ieee80211_hw *hw, u8 type,
@@ -394,7 +421,7 @@
 	else if (type == 2)
 		efuse_shadow_write_2byte(hw, offset, (u16) value);
 	else if (type == 4)
-		efuse_shadow_write_4byte(hw, offset, (u32) value);
+		efuse_shadow_write_4byte(hw, offset, value);
 
 }
 
@@ -478,9 +505,10 @@
 	struct rtl_priv *rtlpriv = rtl_priv(hw);
 	struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
 
-	if (rtlefuse->autoload_failflag == true) {
-		memset(&rtlefuse->efuse_map[EFUSE_INIT_MAP][0], 0xFF, 128);
-	} else
+	if (rtlefuse->autoload_failflag == true)
+		memset(&rtlefuse->efuse_map[EFUSE_INIT_MAP][0], 0xFF,
+			rtlpriv->cfg->maps[EFUSE_HWSET_MAX_SIZE]);
+	else
 		efuse_read_all_map(hw, &rtlefuse->efuse_map[EFUSE_INIT_MAP][0]);
 
 	memcpy(&rtlefuse->efuse_map[EFUSE_MODIFY_MAP][0],
@@ -572,7 +600,7 @@
 {
 	struct rtl_priv *rtlpriv = rtl_priv(hw);
 	u8 tmpidx = 0;
-	int bresult;
+	int result;
 
 	rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL] + 1,
 		       (u8) (addr & 0xff));
@@ -592,19 +620,18 @@
 
 	if (tmpidx < 100) {
 		*data = rtl_read_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL]);
-		bresult = true;
+		result = true;
 	} else {
 		*data = 0xff;
-		bresult = false;
+		result = false;
 	}
-	return bresult;
+	return result;
 }
 
 static int efuse_one_byte_write(struct ieee80211_hw *hw, u16 addr, u8 data)
 {
 	struct rtl_priv *rtlpriv = rtl_priv(hw);
 	u8 tmpidx = 0;
-	bool bresult;
 
 	RT_TRACE(rtlpriv, COMP_EFUSE, DBG_LOUD,
 		 ("Addr = %x Data=%x\n", addr, data));
@@ -626,17 +653,16 @@
 	}
 
 	if (tmpidx < 100)
-		bresult = true;
-	else
-		bresult = false;
+		return true;
 
-	return bresult;
+	return false;
 }
 
 static void efuse_read_all_map(struct ieee80211_hw *hw, u8 * efuse)
 {
+	struct rtl_priv *rtlpriv = rtl_priv(hw);
 	efuse_power_switch(hw, false, true);
-	read_efuse(hw, 0, 128, efuse);
+	read_efuse(hw, 0, rtlpriv->cfg->maps[EFUSE_HWSET_MAX_SIZE], efuse);
 	efuse_power_switch(hw, false, false);
 }
 
@@ -644,7 +670,7 @@
 				u8 efuse_data, u8 offset, u8 *tmpdata,
 				u8 *readstate)
 {
-	bool bdataempty = true;
+	bool dataempty = true;
 	u8 hoffset;
 	u8 tmpidx;
 	u8 hworden;
@@ -660,13 +686,13 @@
 			    &efuse_data)) {
 				tmpdata[tmpidx] = efuse_data;
 				if (efuse_data != 0xff)
-					bdataempty = true;
+					dataempty = true;
 			}
 		}
 
-		if (bdataempty == true)
+		if (dataempty == true) {
 			*readstate = PG_STATE_DATA;
-		else {
+		} else {
 			*efuse_addr = *efuse_addr + (word_cnts * 2) + 1;
 			*readstate = PG_STATE_HEADER;
 		}
@@ -680,12 +706,9 @@
 static int efuse_pg_packet_read(struct ieee80211_hw *hw, u8 offset, u8 *data)
 {
 	u8 readstate = PG_STATE_HEADER;
-
-	bool bcontinual = true;
-
+	bool continual = true;
 	u8 efuse_data, word_cnts = 0;
 	u16 efuse_addr = 0;
-	u8 hworden = 0;
 	u8 tmpdata[8];
 
 	if (data == NULL)
@@ -696,7 +719,7 @@
 	memset(data, 0xff, PGPKT_DATA_SIZE * sizeof(u8));
 	memset(tmpdata, 0xff, PGPKT_DATA_SIZE * sizeof(u8));
 
-	while (bcontinual && (efuse_addr < EFUSE_MAX_SIZE)) {
+	while (continual && (efuse_addr < EFUSE_MAX_SIZE)) {
 		if (readstate & PG_STATE_HEADER) {
 			if (efuse_one_byte_read(hw, efuse_addr, &efuse_data)
 			    && (efuse_data != 0xFF))
@@ -705,9 +728,9 @@
 						      offset, tmpdata,
 						      &readstate);
 			else
-				bcontinual = false;
+				continual = false;
 		} else if (readstate & PG_STATE_DATA) {
-			efuse_word_enable_data_read(hworden, tmpdata, data);
+			efuse_word_enable_data_read(0, tmpdata, data);
 			efuse_addr = efuse_addr + (word_cnts * 2) + 1;
 			readstate = PG_STATE_HEADER;
 		}
@@ -725,13 +748,13 @@
 }
 
 static void efuse_write_data_case1(struct ieee80211_hw *hw, u16 *efuse_addr,
-			u8 efuse_data, u8 offset, int *bcontinual,
+			u8 efuse_data, u8 offset, int *continual,
 			u8 *write_state, struct pgpkt_struct *target_pkt,
-			int *repeat_times, int *bresult, u8 word_en)
+			int *repeat_times, int *result, u8 word_en)
 {
 	struct rtl_priv *rtlpriv = rtl_priv(hw);
 	struct pgpkt_struct tmp_pkt;
-	int bdataempty = true;
+	bool dataempty = true;
 	u8 originaldata[8 * sizeof(u8)];
 	u8 badworden = 0x0F;
 	u8 match_word_en, tmp_word_en;
@@ -751,10 +774,10 @@
 			u16 address = *efuse_addr + 1 + tmpindex;
 			if (efuse_one_byte_read(hw, address,
 			     &efuse_data) && (efuse_data != 0xFF))
-				bdataempty = false;
+				dataempty = false;
 		}
 
-		if (bdataempty == false) {
+		if (dataempty == false) {
 			*efuse_addr = *efuse_addr + (tmp_word_cnts * 2) + 1;
 			*write_state = PG_STATE_HEADER;
 		} else {
@@ -799,24 +822,25 @@
 					tmp_word_en &= (~BIT(1));
 
 				if ((target_pkt->word_en & BIT(2)) ^
-					(match_word_en & BIT(2)))
+				     (match_word_en & BIT(2)))
 					tmp_word_en &= (~BIT(2));
 
 				if ((target_pkt->word_en & BIT(3)) ^
-				    (match_word_en & BIT(3)))
+				     (match_word_en & BIT(3)))
 					tmp_word_en &= (~BIT(3));
 
 				if ((tmp_word_en & 0x0F) != 0x0F) {
 					*efuse_addr = efuse_get_current_size(hw);
 					target_pkt->offset = offset;
 					target_pkt->word_en = tmp_word_en;
-				} else
-					*bcontinual = false;
+				} else {
+					*continual = false;
+				}
 				*write_state = PG_STATE_HEADER;
 				*repeat_times += 1;
 				if (*repeat_times > EFUSE_REPEAT_THRESHOLD_) {
-					*bcontinual = false;
-					*bresult = false;
+					*continual = false;
+					*result = false;
 				}
 			} else {
 				*efuse_addr += (2 * tmp_word_cnts) + 1;
@@ -830,9 +854,9 @@
 }
 
 static void efuse_write_data_case2(struct ieee80211_hw *hw, u16 *efuse_addr,
-				   int *bcontinual, u8 *write_state,
+				   int *continual, u8 *write_state,
 				   struct pgpkt_struct target_pkt,
-				   int *repeat_times, int *bresult)
+				   int *repeat_times, int *result)
 {
 	struct rtl_priv *rtlpriv = rtl_priv(hw);
 	struct pgpkt_struct tmp_pkt;
@@ -846,14 +870,14 @@
 	efuse_one_byte_write(hw, *efuse_addr, pg_header);
 	efuse_one_byte_read(hw, *efuse_addr, &tmp_header);
 
-	if (tmp_header == pg_header)
+	if (tmp_header == pg_header) {
 		*write_state = PG_STATE_DATA;
-	else if (tmp_header == 0xFF) {
+	} else if (tmp_header == 0xFF) {
 		*write_state = PG_STATE_HEADER;
 		*repeat_times += 1;
 		if (*repeat_times > EFUSE_REPEAT_THRESHOLD_) {
-			*bcontinual = false;
-			*bresult = false;
+			*continual = false;
+			*result = false;
 		}
 	} else {
 		tmp_pkt.offset = (tmp_header >> 4) & 0x0F;
@@ -875,17 +899,19 @@
 						      reorg_worden,
 						      originaldata);
 				*efuse_addr = efuse_get_current_size(hw);
-			 } else
+			} else {
 				*efuse_addr = *efuse_addr + (tmp_word_cnts * 2)
 					      + 1;
-		} else
+			}
+		} else {
 			*efuse_addr = *efuse_addr + (tmp_word_cnts * 2) + 1;
+		}
 
 		*write_state = PG_STATE_HEADER;
 		*repeat_times += 1;
 		if (*repeat_times > EFUSE_REPEAT_THRESHOLD_) {
-			*bcontinual = false;
-			*bresult = false;
+			*continual = false;
+			*result = false;
 		}
 
 		RTPRINT(rtlpriv, FEEPROM, EFUSE_PG,
@@ -899,7 +925,7 @@
 	struct rtl_priv *rtlpriv = rtl_priv(hw);
 	struct pgpkt_struct target_pkt;
 	u8 write_state = PG_STATE_HEADER;
-	int bcontinual = true, bdataempty = true, bresult = true;
+	int continual = true, dataempty = true, result = true;
 	u16 efuse_addr = 0;
 	u8 efuse_data;
 	u8 target_word_cnts = 0;
@@ -923,11 +949,11 @@
 
 	RTPRINT(rtlpriv, FEEPROM, EFUSE_PG, ("efuse Power ON\n"));
 
-	while (bcontinual && (efuse_addr <
+	while (continual && (efuse_addr <
 	       (EFUSE_MAX_SIZE - EFUSE_OOB_PROTECT_BYTES))) {
 
 		if (write_state == PG_STATE_HEADER) {
-			bdataempty = true;
+			dataempty = true;
 			badworden = 0x0F;
 			RTPRINT(rtlpriv, FEEPROM, EFUSE_PG,
 				("efuse PG_STATE_HEADER\n"));
@@ -936,32 +962,30 @@
 			    (efuse_data != 0xFF))
 				efuse_write_data_case1(hw, &efuse_addr,
 						       efuse_data, offset,
-						       &bcontinual,
+						       &continual,
 						       &write_state, &target_pkt,
-						       &repeat_times, &bresult,
+						       &repeat_times, &result,
 						       word_en);
 			else
 				efuse_write_data_case2(hw, &efuse_addr,
-						       &bcontinual,
+						       &continual,
 						       &write_state,
 						       target_pkt,
 						       &repeat_times,
-						       &bresult);
+						       &result);
 
 		} else if (write_state == PG_STATE_DATA) {
 			RTPRINT(rtlpriv, FEEPROM, EFUSE_PG,
 				("efuse PG_STATE_DATA\n"));
-			badworden = 0x0f;
 			badworden =
 			    efuse_word_enable_data_write(hw, efuse_addr + 1,
 							 target_pkt.word_en,
 							 target_pkt.data);
 
 			if ((badworden & 0x0F) == 0x0F) {
-				bcontinual = false;
+				continual = false;
 			} else {
-				efuse_addr =
-				    efuse_addr + (2 * target_word_cnts) + 1;
+				efuse_addr += (2 * target_word_cnts) + 1;
 
 				target_pkt.offset = offset;
 				target_pkt.word_en = badworden;
@@ -971,8 +995,8 @@
 				write_state = PG_STATE_HEADER;
 				repeat_times++;
 				if (repeat_times > EFUSE_REPEAT_THRESHOLD_) {
-					bcontinual = false;
-					bresult = false;
+					continual = false;
+					result = false;
 				}
 				RTPRINT(rtlpriv, FEEPROM, EFUSE_PG,
 					("efuse PG_STATE_HEADER-3\n"));
@@ -1072,13 +1096,15 @@
 	return badworden;
 }
 
-static void efuse_power_switch(struct ieee80211_hw *hw, u8 bwrite, u8 pwrstate)
+static void efuse_power_switch(struct ieee80211_hw *hw, u8 write, u8 pwrstate)
 {
 	struct rtl_priv *rtlpriv = rtl_priv(hw);
+	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
 	u8 tempval;
 	u16 tmpV16;
 
-	if (pwrstate == true) {
+	if (pwrstate && (rtlhal->hw_type !=
+		HARDWARE_TYPE_RTL8192SE)) {
 		tmpV16 = rtl_read_word(rtlpriv,
 				       rtlpriv->cfg->maps[SYS_ISO_CTRL]);
 		if (!(tmpV16 & rtlpriv->cfg->maps[EFUSE_PWC_EV12V])) {
@@ -1106,20 +1132,29 @@
 		}
 	}
 
-	if (pwrstate == true) {
-		if (bwrite == true) {
+	if (pwrstate) {
+		if (write) {
 			tempval = rtl_read_byte(rtlpriv,
 						rtlpriv->cfg->maps[EFUSE_TEST] +
 						3);
-			tempval &= 0x0F;
-			tempval |= (VOLTAGE_V25 << 4);
+
+			if (rtlhal->hw_type != HARDWARE_TYPE_RTL8192SE) {
+				tempval &= 0x0F;
+				tempval |= (VOLTAGE_V25 << 4);
+			}
+
 			rtl_write_byte(rtlpriv,
 				       rtlpriv->cfg->maps[EFUSE_TEST] + 3,
 				       (tempval | 0x80));
 		}
 
+		if (rtlhal->hw_type == HARDWARE_TYPE_RTL8192SE) {
+			rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CLK],
+						0x03);
+		}
+
 	} else {
-		if (bwrite == true) {
+		if (write) {
 			tempval = rtl_read_byte(rtlpriv,
 						rtlpriv->cfg->maps[EFUSE_TEST] +
 						3);
@@ -1128,18 +1163,23 @@
 				       (tempval & 0x7F));
 		}
 
+		if (rtlhal->hw_type == HARDWARE_TYPE_RTL8192SE) {
+			rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CLK],
+						0x02);
+		}
+
 	}
 
 }
 
 static u16 efuse_get_current_size(struct ieee80211_hw *hw)
 {
-	int bcontinual = true;
+	int continual = true;
 	u16 efuse_addr = 0;
 	u8 hoffset, hworden;
 	u8 efuse_data, word_cnts;
 
-	while (bcontinual && efuse_one_byte_read(hw, efuse_addr, &efuse_data)
+	while (continual && efuse_one_byte_read(hw, efuse_addr, &efuse_data)
 	       && (efuse_addr < EFUSE_MAX_SIZE)) {
 		if (efuse_data != 0xFF) {
 			hoffset = (efuse_data >> 4) & 0x0F;
@@ -1147,7 +1187,7 @@
 			word_cnts = efuse_calculate_word_cnts(hworden);
 			efuse_addr = efuse_addr + (word_cnts * 2) + 1;
 		} else {
-			bcontinual = false;
+			continual = false;
 		}
 	}
 
diff -druN linux-2.6.39-libre/drivers/net/wireless/rtlwifi/efuse.h linux-3.0-rc7-libre/drivers/net/wireless/rtlwifi/efuse.h
--- linux-2.6.39-libre/drivers/net/wireless/rtlwifi/efuse.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/rtlwifi/efuse.h	2011-07-11 19:51:52.000000000 -0400
@@ -30,9 +30,10 @@
 #ifndef __RTL_EFUSE_H_
 #define __RTL_EFUSE_H_
 
+#define EFUSE_IC_ID_OFFSET		506
+
 #define EFUSE_REAL_CONTENT_LEN		512
 #define EFUSE_MAP_LEN			128
-#define EFUSE_MAX_SECTION		16
 #define EFUSE_MAX_WORD_UNIT		4
 
 #define EFUSE_INIT_MAP			0
@@ -52,6 +53,7 @@
 #define _PRE_EXECUTE_READ_CMD_
 
 #define EFUSE_REPEAT_THRESHOLD_		3
+#define EFUSE_ERROE_HANDLE		1
 
 struct efuse_map {
 	u8 offset;
@@ -103,6 +105,7 @@
 	u8 tx_power_g[14];
 };
 
+extern void read_efuse_byte(struct ieee80211_hw *hw, u16 _offset, u8 *pbuf);
 extern void efuse_initialize(struct ieee80211_hw *hw);
 extern u8 efuse_read_1byte(struct ieee80211_hw *hw, u16 address);
 extern void efuse_write_1byte(struct ieee80211_hw *hw, u16 address, u8 value);
diff -druN linux-2.6.39-libre/drivers/net/wireless/rtlwifi/Kconfig linux-3.0-rc7-libre/drivers/net/wireless/rtlwifi/Kconfig
--- linux-2.6.39-libre/drivers/net/wireless/rtlwifi/Kconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/rtlwifi/Kconfig	2011-07-11 19:51:52.000000000 -0400
@@ -10,6 +10,17 @@
 
 	If you choose to build it as a module, it will be called rtl8192ce
 
+config RTL8192SE
+	tristate "Realtek RTL8192SE/RTL8191SE PCIe Wireless Network Adapter"
+	depends on MAC80211 && EXPERIMENTAL
+	select FW_LOADER
+	select RTLWIFI
+	---help---
+	This is the driver for Realtek RTL8192SE/RTL8191SE 802.11n PCIe
+	wireless network adapters.
+
+	If you choose to build it as a module, it will be called rtl8192se
+
 config RTL8192CU
 	tristate "Realtek RTL8192CU/RTL8188CU USB Wireless Network Adapter"
 	depends on MAC80211 && USB && EXPERIMENTAL
@@ -24,10 +35,10 @@
 
 config RTLWIFI
 	tristate
-	depends on RTL8192CE || RTL8192CU
+	depends on RTL8192CE || RTL8192CU || RTL8192SE
 	default m
 
 config RTL8192C_COMMON
 	tristate
-	depends on RTL8192CE || RTL8192CU
+	depends on RTL8192CE || RTL8192CU || RTL8192SE
 	default m
diff -druN linux-2.6.39-libre/drivers/net/wireless/rtlwifi/Makefile linux-3.0-rc7-libre/drivers/net/wireless/rtlwifi/Makefile
--- linux-2.6.39-libre/drivers/net/wireless/rtlwifi/Makefile	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/rtlwifi/Makefile	2011-07-11 19:51:52.000000000 -0400
@@ -22,5 +22,6 @@
 obj-$(CONFIG_RTL8192C_COMMON)	+= rtl8192c/
 obj-$(CONFIG_RTL8192CE)		+= rtl8192ce/
 obj-$(CONFIG_RTL8192CU)		+= rtl8192cu/
+obj-$(CONFIG_RTL8192SE)		+= rtl8192se/
 
 ccflags-y += -D__CHECK_ENDIAN__
diff -druN linux-2.6.39-libre/drivers/net/wireless/rtlwifi/pci.c linux-3.0-rc7-libre/drivers/net/wireless/rtlwifi/pci.c
--- linux-2.6.39-libre/drivers/net/wireless/rtlwifi/pci.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/rtlwifi/pci.c	2011-07-11 19:51:52.000000000 -0400
@@ -32,6 +32,7 @@
 #include "pci.h"
 #include "base.h"
 #include "ps.h"
+#include "efuse.h"
 
 static const u16 pcibridge_vendors[PCI_BRIDGE_VENDOR_MAX] = {
 	INTEL_VENDOR_ID,
@@ -40,6 +41,31 @@
 	SIS_VENDOR_ID
 };
 
+static const u8 ac_to_hwq[] = {
+	VO_QUEUE,
+	VI_QUEUE,
+	BE_QUEUE,
+	BK_QUEUE
+};
+
+static u8 _rtl_mac_to_hwqueue(struct ieee80211_hw *hw,
+		       struct sk_buff *skb)
+{
+	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+	__le16 fc = rtl_get_fc(skb);
+	u8 queue_index = skb_get_queue_mapping(skb);
+
+	if (unlikely(ieee80211_is_beacon(fc)))
+		return BEACON_QUEUE;
+	if (ieee80211_is_mgmt(fc))
+		return MGNT_QUEUE;
+	if (rtlhal->hw_type == HARDWARE_TYPE_RTL8192SE)
+		if (ieee80211_is_nullfunc(fc))
+			return HIGH_QUEUE;
+
+	return ac_to_hwq[queue_index];
+}
+
 /* Update PCI dependent default settings*/
 static void _rtl_pci_update_default_setting(struct ieee80211_hw *hw)
 {
@@ -48,6 +74,7 @@
 	struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
 	struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
 	u8 pcibridge_vendor = pcipriv->ndis_adapter.pcibridge_vendor;
+	u8 init_aspm;
 
 	ppsc->reg_rfps_level = 0;
 	ppsc->support_aspm = 0;
@@ -125,7 +152,7 @@
 			bool support_backdoor = true;
 			ppsc->support_aspm = support_aspm;
 
-			/*if(priv->oem_id == RT_CID_TOSHIBA &&
+			/*if (priv->oem_id == RT_CID_TOSHIBA &&
 			   !priv->ndis_adapter.amd_l1_patch)
 			   support_backdoor = false; */
 
@@ -145,6 +172,13 @@
 			 ("switch case not process\n"));
 		break;
 	}
+
+	/* toshiba aspm issue, toshiba will set aspm selfly
+	 * so we should not set aspm in driver */
+	pci_read_config_byte(rtlpci->pdev, 0x80, &init_aspm);
+	if (rtlpriv->rtlhal.hw_type == HARDWARE_TYPE_RTL8192SE &&
+		init_aspm == 0x43)
+		ppsc->support_aspm = false;
 }
 
 static bool _rtl_pci_platform_switch_device_pci_aspm(
@@ -152,28 +186,28 @@
 			u8 value)
 {
 	struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
-	bool bresult = false;
+	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
 
-	value |= 0x40;
+	if (rtlhal->hw_type != HARDWARE_TYPE_RTL8192SE)
+		value |= 0x40;
 
 	pci_write_config_byte(rtlpci->pdev, 0x80, value);
 
-	return bresult;
+	return false;
 }
 
 /*When we set 0x01 to enable clk request. Set 0x0 to disable clk req.*/
 static bool _rtl_pci_switch_clk_req(struct ieee80211_hw *hw, u8 value)
 {
 	struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
-	u8 buffer;
-	bool bresult = false;
-
-	buffer = value;
+	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
 
 	pci_write_config_byte(rtlpci->pdev, 0x81, value);
-	bresult = true;
 
-	return bresult;
+	if (rtlhal->hw_type == HARDWARE_TYPE_RTL8192SE)
+		udelay(100);
+
+	return true;
 }
 
 /*Disable RTL8192SE ASPM & Disable Pci Bridge ASPM*/
@@ -191,6 +225,10 @@
 	u16 pcibridge_linkctrlreg = pcipriv->ndis_adapter.
 				pcibridge_linkctrlreg;
 	u16 aspmlevel = 0;
+	u8 tmp_u1b = 0;
+
+	if (!ppsc->support_aspm)
+		return;
 
 	if (pcibridge_vendor == PCI_BRIDGE_VENDOR_UNKNOWN) {
 		RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE,
@@ -204,11 +242,8 @@
 		_rtl_pci_switch_clk_req(hw, 0x0);
 	}
 
-	if (1) {
-		/*for promising device will in L0 state after an I/O. */
-		u8 tmp_u1b;
-		pci_read_config_byte(rtlpci->pdev, 0x80, &tmp_u1b);
-	}
+	/*for promising device will in L0 state after an I/O. */
+	pci_read_config_byte(rtlpci->pdev, 0x80, &tmp_u1b);
 
 	/*Set corresponding value. */
 	aspmlevel |= BIT(0) | BIT(1);
@@ -224,7 +259,6 @@
 	rtl_pci_raw_write_port_uchar(PCI_CONF_DATA, pcibridge_linkctrlreg);
 
 	udelay(50);
-
 }
 
 /*
@@ -249,6 +283,9 @@
 	u8 u_pcibridge_aspmsetting;
 	u8 u_device_aspmsetting;
 
+	if (!ppsc->support_aspm)
+		return;
+
 	if (pcibridge_vendor == PCI_BRIDGE_VENDOR_UNKNOWN) {
 		RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE,
 			 ("PCI(Bridge) UNKNOWN.\n"));
@@ -293,7 +330,7 @@
 					     RT_RF_OFF_LEVL_CLK_REQ) ? 1 : 0);
 		RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_CLK_REQ);
 	}
-	udelay(200);
+	udelay(100);
 }
 
 static bool rtl_pci_get_amd_l1_patch(struct ieee80211_hw *hw)
@@ -330,13 +367,13 @@
 	u8 capabilityoffset = pcipriv->ndis_adapter.pcibridge_pciehdr_offset;
 	u32 pcicfg_addrport = pcipriv->ndis_adapter.pcicfg_addrport;
 	u8 linkctrl_reg;
-	u8 num4bBytes;
+	u8 num4bbytes;
 
-	num4bBytes = (capabilityoffset + 0x10) / 4;
+	num4bbytes = (capabilityoffset + 0x10) / 4;
 
 	/*Read  Link Control Register */
 	rtl_pci_raw_write_port_ulong(PCI_CONF_ADDRESS,
-				     pcicfg_addrport + (num4bBytes << 2));
+				     pcicfg_addrport + (num4bbytes << 2));
 	rtl_pci_raw_read_port_uchar(PCI_CONF_DATA, &linkctrl_reg);
 
 	pcipriv->ndis_adapter.pcibridge_linkctrlreg = linkctrl_reg;
@@ -369,7 +406,7 @@
 	pci_write_config_byte(pdev, 0x70f, tmp);
 }
 
-static void _rtl_pci_initialize_adapter_common(struct ieee80211_hw *hw)
+static void rtl_pci_init_aspm(struct ieee80211_hw *hw)
 {
 	struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
 
@@ -383,52 +420,6 @@
 
 }
 
-static void rtl_pci_init_aspm(struct ieee80211_hw *hw)
-{
-	struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
-
-	/*close ASPM for AMD defaultly */
-	rtlpci->const_amdpci_aspm = 0;
-
-	/*
-	 * ASPM PS mode.
-	 * 0 - Disable ASPM,
-	 * 1 - Enable ASPM without Clock Req,
-	 * 2 - Enable ASPM with Clock Req,
-	 * 3 - Always Enable ASPM with Clock Req,
-	 * 4 - Always Enable ASPM without Clock Req.
-	 * set defult to RTL8192CE:3 RTL8192E:2
-	 * */
-	rtlpci->const_pci_aspm = 3;
-
-	/*Setting for PCI-E device */
-	rtlpci->const_devicepci_aspm_setting = 0x03;
-
-	/*Setting for PCI-E bridge */
-	rtlpci->const_hostpci_aspm_setting = 0x02;
-
-	/*
-	 * In Hw/Sw Radio Off situation.
-	 * 0 - Default,
-	 * 1 - From ASPM setting without low Mac Pwr,
-	 * 2 - From ASPM setting with low Mac Pwr,
-	 * 3 - Bus D3
-	 * set default to RTL8192CE:0 RTL8192SE:2
-	 */
-	rtlpci->const_hwsw_rfoff_d3 = 0;
-
-	/*
-	 * This setting works for those device with
-	 * backdoor ASPM setting such as EPHY setting.
-	 * 0 - Not support ASPM,
-	 * 1 - Support ASPM,
-	 * 2 - According to chipset.
-	 */
-	rtlpci->const_support_pciaspm = 1;
-
-	_rtl_pci_initialize_adapter_common(hw);
-}
-
 static void _rtl_pci_io_handler_init(struct device *dev,
 				     struct ieee80211_hw *hw)
 {
@@ -450,6 +441,90 @@
 {
 }
 
+static bool _rtl_update_earlymode_info(struct ieee80211_hw *hw,
+		struct sk_buff *skb, struct rtl_tcb_desc *tcb_desc, u8 tid)
+{
+	struct rtl_priv *rtlpriv = rtl_priv(hw);
+	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+	u8 additionlen = FCS_LEN;
+	struct sk_buff *next_skb;
+
+	/* here open is 4, wep/tkip is 8, aes is 12*/
+	if (info->control.hw_key)
+		additionlen += info->control.hw_key->icv_len;
+
+	/* The most skb num is 6 */
+	tcb_desc->empkt_num = 0;
+	spin_lock_bh(&rtlpriv->locks.waitq_lock);
+	skb_queue_walk(&rtlpriv->mac80211.skb_waitq[tid], next_skb) {
+		struct ieee80211_tx_info *next_info;
+
+		next_info = IEEE80211_SKB_CB(next_skb);
+		if (next_info->flags & IEEE80211_TX_CTL_AMPDU) {
+			tcb_desc->empkt_len[tcb_desc->empkt_num] =
+				next_skb->len + additionlen;
+			tcb_desc->empkt_num++;
+		} else {
+			break;
+		}
+
+		if (skb_queue_is_last(&rtlpriv->mac80211.skb_waitq[tid],
+				      next_skb))
+			break;
+
+		if (tcb_desc->empkt_num >= 5)
+			break;
+	}
+	spin_unlock_bh(&rtlpriv->locks.waitq_lock);
+
+	return true;
+}
+
+/* just for early mode now */
+static void _rtl_pci_tx_chk_waitq(struct ieee80211_hw *hw)
+{
+	struct rtl_priv *rtlpriv = rtl_priv(hw);
+	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+	struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+	struct sk_buff *skb = NULL;
+	struct ieee80211_tx_info *info = NULL;
+	int tid; /* should be int */
+
+	if (!rtlpriv->rtlhal.earlymode_enable)
+		return;
+
+	/* we juse use em for BE/BK/VI/VO */
+	for (tid = 7; tid >= 0; tid--) {
+		u8 hw_queue = ac_to_hwq[rtl_tid_to_ac(hw, tid)];
+		struct rtl8192_tx_ring *ring = &rtlpci->tx_ring[hw_queue];
+		while (!mac->act_scanning &&
+		       rtlpriv->psc.rfpwr_state == ERFON) {
+			struct rtl_tcb_desc tcb_desc;
+			memset(&tcb_desc, 0, sizeof(struct rtl_tcb_desc));
+
+			spin_lock_bh(&rtlpriv->locks.waitq_lock);
+			if (!skb_queue_empty(&mac->skb_waitq[tid]) &&
+			   (ring->entries - skb_queue_len(&ring->queue) > 5)) {
+				skb = skb_dequeue(&mac->skb_waitq[tid]);
+			} else {
+				spin_unlock_bh(&rtlpriv->locks.waitq_lock);
+				break;
+			}
+			spin_unlock_bh(&rtlpriv->locks.waitq_lock);
+
+			/* Some macaddr can't do early mode. like
+			 * multicast/broadcast/no_qos data */
+			info = IEEE80211_SKB_CB(skb);
+			if (info->flags & IEEE80211_TX_CTL_AMPDU)
+				_rtl_update_earlymode_info(hw, skb,
+							   &tcb_desc, tid);
+
+			rtlpriv->intf_ops->adapter_tx(hw, skb, &tcb_desc);
+		}
+	}
+}
+
+
 static void _rtl_pci_tx_isr(struct ieee80211_hw *hw, int prio)
 {
 	struct rtl_priv *rtlpriv = rtl_priv(hw);
@@ -461,6 +536,8 @@
 		struct rtl_tx_desc *entry = &ring->desc[ring->idx];
 		struct sk_buff *skb;
 		struct ieee80211_tx_info *info;
+		__le16 fc;
+		u8 tid;
 
 		u8 own = (u8) rtlpriv->cfg->ops->get_desc((u8 *) entry, true,
 							  HW_DESC_OWN);
@@ -481,6 +558,10 @@
 						      HW_DESC_TXBUFF_ADDR),
 				 skb->len, PCI_DMA_TODEVICE);
 
+		/* remove early mode header */
+		if (rtlpriv->rtlhal.earlymode_enable)
+			skb_pull(skb, EM_HDR_LEN);
+
 		RT_TRACE(rtlpriv, (COMP_INTR | COMP_SEND), DBG_TRACE,
 			 ("new ring->idx:%d, "
 			  "free: skb_queue_len:%d, free: seq:%x\n",
@@ -488,6 +569,30 @@
 			  skb_queue_len(&ring->queue),
 			  *(u16 *) (skb->data + 22)));
 
+		if (prio == TXCMD_QUEUE) {
+			dev_kfree_skb(skb);
+			goto tx_status_ok;
+
+		}
+
+		/* for sw LPS, just after NULL skb send out, we can
+		 * sure AP kown we are sleeped, our we should not let
+		 * rf to sleep*/
+		fc = rtl_get_fc(skb);
+		if (ieee80211_is_nullfunc(fc)) {
+			if (ieee80211_has_pm(fc)) {
+				rtlpriv->mac80211.offchan_deley = true;
+				rtlpriv->psc.state_inap = 1;
+			} else {
+				rtlpriv->psc.state_inap = 0;
+			}
+		}
+
+		/* update tid tx pkt num */
+		tid = rtl_get_tid(skb);
+		if (tid <= 7)
+			rtlpriv->link_info.tidtx_inperiod[tid]++;
+
 		info = IEEE80211_SKB_CB(skb);
 		ieee80211_tx_info_clear_status(info);
 
@@ -510,7 +615,7 @@
 					skb_get_queue_mapping
 					(skb));
 		}
-
+tx_status_ok:
 		skb = NULL;
 	}
 
@@ -564,6 +669,14 @@
 							 &rx_status,
 							 (u8 *) pdesc, skb);
 
+			new_skb = dev_alloc_skb(rtlpci->rxbuffersize);
+			if (unlikely(!new_skb)) {
+				RT_TRACE(rtlpriv, (COMP_INTR | COMP_RECV),
+					 DBG_DMESG,
+					 ("can't alloc skb for rx\n"));
+				goto done;
+			}
+
 			pci_unmap_single(rtlpci->pdev,
 					 *((dma_addr_t *) skb->cb),
 					 rtlpci->rxbuffersize,
@@ -582,23 +695,21 @@
 			 *skb_trim(skb, skb->len - 4);
 			 */
 
-			hdr = (struct ieee80211_hdr *)(skb->data);
-			fc = hdr->frame_control;
+			hdr = rtl_get_hdr(skb);
+			fc = rtl_get_fc(skb);
 
-			if (!stats.crc) {
+			if (!stats.crc && !stats.hwerror) {
 				memcpy(IEEE80211_SKB_RXCB(skb), &rx_status,
 				       sizeof(rx_status));
 
-				if (is_broadcast_ether_addr(hdr->addr1))
+				if (is_broadcast_ether_addr(hdr->addr1)) {
 					;/*TODO*/
-				else {
-					if (is_multicast_ether_addr(hdr->addr1))
-						;/*TODO*/
-					else {
-						unicast = true;
-						rtlpriv->stats.rxbytesunicast +=
-						    skb->len;
-					}
+				} else if (is_multicast_ether_addr(hdr->addr1)) {
+					;/*TODO*/
+				} else {
+					unicast = true;
+					rtlpriv->stats.rxbytesunicast +=
+					    skb->len;
 				}
 
 				rtl_is_special_data(hw, skb, false);
@@ -612,28 +723,38 @@
 						    num_rx_inperiod++;
 				}
 
-				if (unlikely(!rtl_action_proc(hw, skb,
-				    false))) {
+				/* for sw lps */
+				rtl_swlps_beacon(hw, (void *)skb->data,
+						 skb->len);
+				rtl_recognize_peer(hw, (void *)skb->data,
+						   skb->len);
+				if ((rtlpriv->mac80211.opmode ==
+				     NL80211_IFTYPE_AP) &&
+				    (rtlpriv->rtlhal.current_bandtype ==
+				     BAND_ON_2_4G) &&
+				     (ieee80211_is_beacon(fc) ||
+				     ieee80211_is_probe_resp(fc))) {
 					dev_kfree_skb_any(skb);
 				} else {
-					struct sk_buff *uskb = NULL;
-					u8 *pdata;
-					uskb = dev_alloc_skb(skb->len + 128);
-					if (!uskb) {
-						RT_TRACE(rtlpriv,
-							(COMP_INTR | COMP_RECV),
-							DBG_EMERG,
-							("can't alloc rx skb\n"));
-						goto done;
-					}
-					memcpy(IEEE80211_SKB_RXCB(uskb),
-							&rx_status,
-							sizeof(rx_status));
-					pdata = (u8 *)skb_put(uskb, skb->len);
-					memcpy(pdata, skb->data, skb->len);
-					dev_kfree_skb_any(skb);
+					if (unlikely(!rtl_action_proc(hw, skb,
+					    false))) {
+						dev_kfree_skb_any(skb);
+					} else {
+						struct sk_buff *uskb = NULL;
+						u8 *pdata;
+						uskb = dev_alloc_skb(skb->len
+								     + 128);
+						memcpy(IEEE80211_SKB_RXCB(uskb),
+						       &rx_status,
+						       sizeof(rx_status));
+						pdata = (u8 *)skb_put(uskb,
+							skb->len);
+						memcpy(pdata, skb->data,
+						       skb->len);
+						dev_kfree_skb_any(skb);
 
-					ieee80211_rx_irqsafe(hw, uskb);
+						ieee80211_rx_irqsafe(hw, uskb);
+					}
 				}
 			} else {
 				dev_kfree_skb_any(skb);
@@ -645,15 +766,7 @@
 				rtl_lps_leave(hw);
 			}
 
-			new_skb = dev_alloc_skb(rtlpci->rxbuffersize);
-			if (unlikely(!new_skb)) {
-				RT_TRACE(rtlpriv, (COMP_INTR | COMP_RECV),
-					 DBG_EMERG,
-					 ("can't alloc skb for rx\n"));
-				goto done;
-			}
 			skb = new_skb;
-			/*skb->dev = dev; */
 
 			rtlpci->rx_ring[rx_queue_idx].rx_buf[rtlpci->
 							     rx_ring
@@ -666,7 +779,7 @@
 
 		}
 done:
-		bufferaddress = (u32)(*((dma_addr_t *) skb->cb));
+		bufferaddress = (*((dma_addr_t *)skb->cb));
 		tmp_one = 1;
 		rtlpriv->cfg->ops->set_desc((u8 *) pdesc, false,
 					    HW_DESC_RXBUFF_ADDR,
@@ -695,6 +808,7 @@
 	struct ieee80211_hw *hw = dev_id;
 	struct rtl_priv *rtlpriv = rtl_priv(hw);
 	struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
 	unsigned long flags;
 	u32 inta = 0;
 	u32 intb = 0;
@@ -781,23 +895,36 @@
 		_rtl_pci_tx_isr(hw, VO_QUEUE);
 	}
 
+	if (rtlhal->hw_type == HARDWARE_TYPE_RTL8192SE) {
+		if (inta & rtlpriv->cfg->maps[RTL_IMR_COMDOK]) {
+			rtlpriv->link_info.num_tx_inperiod++;
+
+			RT_TRACE(rtlpriv, COMP_INTR, DBG_TRACE,
+					("CMD TX OK interrupt!\n"));
+			_rtl_pci_tx_isr(hw, TXCMD_QUEUE);
+		}
+	}
+
 	/*<2> Rx related */
 	if (inta & rtlpriv->cfg->maps[RTL_IMR_ROK]) {
 		RT_TRACE(rtlpriv, COMP_INTR, DBG_TRACE, ("Rx ok interrupt!\n"));
-		tasklet_schedule(&rtlpriv->works.irq_tasklet);
+		_rtl_pci_rx_interrupt(hw);
 	}
 
 	if (unlikely(inta & rtlpriv->cfg->maps[RTL_IMR_RDU])) {
 		RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
 			 ("rx descriptor unavailable!\n"));
-		tasklet_schedule(&rtlpriv->works.irq_tasklet);
+		_rtl_pci_rx_interrupt(hw);
 	}
 
 	if (unlikely(inta & rtlpriv->cfg->maps[RTL_IMR_RXFOVW])) {
 		RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, ("rx overflow !\n"));
-		tasklet_schedule(&rtlpriv->works.irq_tasklet);
+		_rtl_pci_rx_interrupt(hw);
 	}
 
+	if (rtlpriv->rtlhal.earlymode_enable)
+		tasklet_schedule(&rtlpriv->works.irq_tasklet);
+
 	spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock, flags);
 	return IRQ_HANDLED;
 
@@ -808,7 +935,7 @@
 
 static void _rtl_pci_irq_tasklet(struct ieee80211_hw *hw)
 {
-	_rtl_pci_rx_interrupt(hw);
+	_rtl_pci_tx_chk_waitq(hw);
 }
 
 static void _rtl_pci_prepare_bcn_tasklet(struct ieee80211_hw *hw)
@@ -816,14 +943,15 @@
 	struct rtl_priv *rtlpriv = rtl_priv(hw);
 	struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
 	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
-	struct rtl8192_tx_ring *ring = &rtlpci->tx_ring[BEACON_QUEUE];
+	struct rtl8192_tx_ring *ring = NULL;
 	struct ieee80211_hdr *hdr = NULL;
 	struct ieee80211_tx_info *info = NULL;
 	struct sk_buff *pskb = NULL;
 	struct rtl_tx_desc *pdesc = NULL;
-	unsigned int queue_index;
+	struct rtl_tcb_desc tcb_desc;
 	u8 temp_one = 1;
 
+	memset(&tcb_desc, 0, sizeof(struct rtl_tcb_desc));
 	ring = &rtlpci->tx_ring[BEACON_QUEUE];
 	pskb = __skb_dequeue(&ring->queue);
 	if (pskb)
@@ -833,14 +961,11 @@
 	pskb = ieee80211_beacon_get(hw, mac->vif);
 	if (pskb == NULL)
 		return;
-	hdr = (struct ieee80211_hdr *)(pskb->data);
+	hdr = rtl_get_hdr(pskb);
 	info = IEEE80211_SKB_CB(pskb);
-
-	queue_index = BEACON_QUEUE;
-
 	pdesc = &ring->desc[0];
 	rtlpriv->cfg->ops->fill_tx_desc(hw, hdr, (u8 *) pdesc,
-					info, pskb, queue_index);
+		info, pskb, BEACON_QUEUE, &tcb_desc);
 
 	__skb_queue_tail(&ring->queue, pskb);
 
@@ -882,7 +1007,6 @@
 	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
 	struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
 	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
-	struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
 
 	rtlpci->up_first_time = true;
 	rtlpci->being_init_adapter = false;
@@ -890,31 +1014,20 @@
 	rtlhal->hw = hw;
 	rtlpci->pdev = pdev;
 
-	ppsc->inactiveps = false;
-	ppsc->leisure_ps = true;
-	ppsc->fwctrl_lps = true;
-	ppsc->reg_fwctrl_lps = 3;
-	ppsc->reg_max_lps_awakeintvl = 5;
-
-	if (ppsc->reg_fwctrl_lps == 1)
-		ppsc->fwctrl_psmode = FW_PS_MIN_MODE;
-	else if (ppsc->reg_fwctrl_lps == 2)
-		ppsc->fwctrl_psmode = FW_PS_MAX_MODE;
-	else if (ppsc->reg_fwctrl_lps == 3)
-		ppsc->fwctrl_psmode = FW_PS_DTIM_MODE;
-
 	/*Tx/Rx related var */
 	_rtl_pci_init_trx_var(hw);
 
-	 /*IBSS*/ mac->beacon_interval = 100;
+	/*IBSS*/ mac->beacon_interval = 100;
 
-	 /*AMPDU*/ mac->min_space_cfg = 0;
+	/*AMPDU*/
+	mac->min_space_cfg = 0;
 	mac->max_mss_density = 0;
 	/*set sane AMPDU defaults */
 	mac->current_ampdu_density = 7;
 	mac->current_ampdu_factor = 3;
 
-	 /*QOS*/ rtlpci->acm_method = eAcmWay2_SW;
+	/*QOS*/
+	rtlpci->acm_method = eAcmWay2_SW;
 
 	/*task */
 	tasklet_init(&rtlpriv->works.irq_tasklet,
@@ -955,7 +1068,8 @@
 		 ("queue:%d, ring_addr:%p\n", prio, ring));
 
 	for (i = 0; i < entries; i++) {
-		nextdescaddress = (u32) dma + ((i + 1) % entries) *
+		nextdescaddress = (u32) dma +
+					      ((i + 1) % entries) *
 					      sizeof(*ring);
 
 		rtlpriv->cfg->ops->set_desc((u8 *)&(ring[i]),
@@ -999,6 +1113,13 @@
 
 		rtlpci->rx_ring[rx_queue_idx].idx = 0;
 
+		/* If amsdu_8k is disabled, set buffersize to 4096. This
+		 * change will reduce memory fragmentation.
+		 */
+		if (rtlpci->rxbuffersize > 4096 &&
+		    rtlpriv->rtlhal.disable_amsdu_8k)
+			rtlpci->rxbuffersize = 4096;
+
 		for (i = 0; i < rtlpci->rxringcount; i++) {
 			struct sk_buff *skb =
 			    dev_alloc_skb(rtlpci->rxbuffersize);
@@ -1020,7 +1141,7 @@
 					   rtlpci->rxbuffersize,
 					   PCI_DMA_FROMDEVICE);
 
-			bufferaddress = (u32)(*((dma_addr_t *)skb->cb));
+			bufferaddress = (*((dma_addr_t *)skb->cb));
 			rtlpriv->cfg->ops->set_desc((u8 *)entry, false,
 						    HW_DESC_RXBUFF_ADDR,
 						    (u8 *)&bufferaddress);
@@ -1203,72 +1324,73 @@
 	return 0;
 }
 
-static unsigned int _rtl_mac_to_hwqueue(__le16 fc,
-		unsigned int mac80211_queue_index)
+static bool rtl_pci_tx_chk_waitq_insert(struct ieee80211_hw *hw,
+					struct sk_buff *skb)
 {
-	unsigned int hw_queue_index;
+	struct rtl_priv *rtlpriv = rtl_priv(hw);
+	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+	struct ieee80211_sta *sta = info->control.sta;
+	struct rtl_sta_info *sta_entry = NULL;
+	u8 tid = rtl_get_tid(skb);
 
-	if (unlikely(ieee80211_is_beacon(fc))) {
-		hw_queue_index = BEACON_QUEUE;
-		goto out;
-	}
+	if (!sta)
+		return false;
+	sta_entry = (struct rtl_sta_info *)sta->drv_priv;
 
-	if (ieee80211_is_mgmt(fc)) {
-		hw_queue_index = MGNT_QUEUE;
-		goto out;
-	}
+	if (!rtlpriv->rtlhal.earlymode_enable)
+		return false;
+	if (sta_entry->tids[tid].agg.agg_state != RTL_AGG_OPERATIONAL)
+		return false;
+	if (_rtl_mac_to_hwqueue(hw, skb) > VO_QUEUE)
+		return false;
+	if (tid > 7)
+		return false;
 
-	switch (mac80211_queue_index) {
-	case 0:
-		hw_queue_index = VO_QUEUE;
-		break;
-	case 1:
-		hw_queue_index = VI_QUEUE;
-		break;
-	case 2:
-		hw_queue_index = BE_QUEUE;;
-		break;
-	case 3:
-		hw_queue_index = BK_QUEUE;
-		break;
-	default:
-		hw_queue_index = BE_QUEUE;
-		RT_ASSERT(false, ("QSLT_BE queue, skb_queue:%d\n",
-				  mac80211_queue_index));
-		break;
-	}
+	/* maybe every tid should be checked */
+	if (!rtlpriv->link_info.higher_busytxtraffic[tid])
+		return false;
 
-out:
-	return hw_queue_index;
+	spin_lock_bh(&rtlpriv->locks.waitq_lock);
+	skb_queue_tail(&rtlpriv->mac80211.skb_waitq[tid], skb);
+	spin_unlock_bh(&rtlpriv->locks.waitq_lock);
+
+	return true;
 }
 
-static int rtl_pci_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
+static int rtl_pci_tx(struct ieee80211_hw *hw, struct sk_buff *skb,
+		struct rtl_tcb_desc *ptcb_desc)
 {
 	struct rtl_priv *rtlpriv = rtl_priv(hw);
-	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+	struct rtl_sta_info *sta_entry = NULL;
 	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+	struct ieee80211_sta *sta = info->control.sta;
 	struct rtl8192_tx_ring *ring;
 	struct rtl_tx_desc *pdesc;
 	u8 idx;
-	unsigned int queue_index, hw_queue;
+	u8 hw_queue = _rtl_mac_to_hwqueue(hw, skb);
 	unsigned long flags;
-	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)(skb->data);
-	__le16 fc = hdr->frame_control;
+	struct ieee80211_hdr *hdr = rtl_get_hdr(skb);
+	__le16 fc = rtl_get_fc(skb);
 	u8 *pda_addr = hdr->addr1;
 	struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
 	/*ssn */
-	u8 *qc = NULL;
 	u8 tid = 0;
 	u16 seq_number = 0;
 	u8 own;
 	u8 temp_one = 1;
 
-	if (ieee80211_is_mgmt(fc))
-		rtl_tx_mgmt_proc(hw, skb);
-	rtl_action_proc(hw, skb, true);
+	if (ieee80211_is_auth(fc)) {
+		RT_TRACE(rtlpriv, COMP_SEND, DBG_DMESG, ("MAC80211_LINKING\n"));
+		rtl_ips_nic_on(hw);
+	}
 
-	queue_index = skb_get_queue_mapping(skb);
-	hw_queue = _rtl_mac_to_hwqueue(fc, queue_index);
+	if (rtlpriv->psc.sw_ps_enabled) {
+		if (ieee80211_is_data(fc) && !ieee80211_is_nullfunc(fc) &&
+			!ieee80211_has_pm(fc))
+			hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_PM);
+	}
+
+	rtl_action_proc(hw, skb, true);
 
 	if (is_multicast_ether_addr(pda_addr))
 		rtlpriv->stats.txbytesmulticast += skb->len;
@@ -1278,7 +1400,6 @@
 		rtlpriv->stats.txbytesunicast += skb->len;
 
 	spin_lock_irqsave(&rtlpriv->locks.irq_th_lock, flags);
-
 	ring = &rtlpci->tx_ring[hw_queue];
 	if (hw_queue != BEACON_QUEUE)
 		idx = (ring->idx + skb_queue_len(&ring->queue)) %
@@ -1301,43 +1422,30 @@
 		return skb->len;
 	}
 
-	/*
-	 *if(ieee80211_is_nullfunc(fc)) {
-	 *      spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock, flags);
-	 *      return 1;
-	 *}
-	 */
-
 	if (ieee80211_is_data_qos(fc)) {
-		qc = ieee80211_get_qos_ctl(hdr);
-		tid = qc[0] & IEEE80211_QOS_CTL_TID_MASK;
-
-		seq_number = mac->tids[tid].seq_number;
-		seq_number &= IEEE80211_SCTL_SEQ;
-		/*
-		 *hdr->seq_ctrl = hdr->seq_ctrl &
-		 *cpu_to_le16(IEEE80211_SCTL_FRAG);
-		 *hdr->seq_ctrl |= cpu_to_le16(seq_number);
-		 */
+		tid = rtl_get_tid(skb);
+		if (sta) {
+			sta_entry = (struct rtl_sta_info *)sta->drv_priv;
+			seq_number = (le16_to_cpu(hdr->seq_ctrl) &
+				      IEEE80211_SCTL_SEQ) >> 4;
+			seq_number += 1;
 
-		seq_number += 1;
+			if (!ieee80211_has_morefrags(hdr->frame_control))
+				sta_entry->tids[tid].seq_number = seq_number;
+		}
 	}
 
 	if (ieee80211_is_data(fc))
 		rtlpriv->cfg->ops->led_control(hw, LED_CTL_TX);
 
-	rtlpriv->cfg->ops->fill_tx_desc(hw, hdr, (u8 *) pdesc,
-					info, skb, hw_queue);
+	rtlpriv->cfg->ops->fill_tx_desc(hw, hdr, (u8 *)pdesc,
+			info, skb, hw_queue, ptcb_desc);
 
 	__skb_queue_tail(&ring->queue, skb);
 
-	rtlpriv->cfg->ops->set_desc((u8 *) pdesc, true,
+	rtlpriv->cfg->ops->set_desc((u8 *)pdesc, true,
 				    HW_DESC_OWN, (u8 *)&temp_one);
 
-	if (!ieee80211_has_morefrags(hdr->frame_control)) {
-		if (qc)
-			mac->tids[tid].seq_number = seq_number;
-	}
 
 	if ((ring->entries - skb_queue_len(&ring->queue)) < 2 &&
 	    hw_queue != BEACON_QUEUE) {
@@ -1359,6 +1467,35 @@
 	return 0;
 }
 
+static void rtl_pci_flush(struct ieee80211_hw *hw, bool drop)
+{
+	struct rtl_priv *rtlpriv = rtl_priv(hw);
+	struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
+	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+	u16 i = 0;
+	int queue_id;
+	struct rtl8192_tx_ring *ring;
+
+	for (queue_id = RTL_PCI_MAX_TX_QUEUE_COUNT - 1; queue_id >= 0;) {
+		u32 queue_len;
+		ring = &pcipriv->dev.tx_ring[queue_id];
+		queue_len = skb_queue_len(&ring->queue);
+		if (queue_len == 0 || queue_id == BEACON_QUEUE ||
+			queue_id == TXCMD_QUEUE) {
+			queue_id--;
+			continue;
+		} else {
+			msleep(20);
+			i++;
+		}
+
+		/* we just wait 1s for all queues */
+		if (rtlpriv->psc.rfpwr_state == ERFOFF ||
+			is_hal_stop(rtlhal) || i >= 200)
+			return;
+	}
+}
+
 static void rtl_pci_deinit(struct ieee80211_hw *hw)
 {
 	struct rtl_priv *rtlpriv = rtl_priv(hw);
@@ -1477,13 +1614,26 @@
 	struct pci_dev *bridge_pdev = pdev->bus->self;
 	u16 venderid;
 	u16 deviceid;
+	u8 revisionid;
 	u16 irqline;
 	u8 tmp;
 
+	pcipriv->ndis_adapter.pcibridge_vendor = PCI_BRIDGE_VENDOR_UNKNOWN;
 	venderid = pdev->vendor;
 	deviceid = pdev->device;
+	pci_read_config_byte(pdev, 0x8, &revisionid);
 	pci_read_config_word(pdev, 0x3C, &irqline);
 
+	/* PCI ID 0x10ec:0x8192 occurs for both RTL8192E, which uses
+	 * r8192e_pci, and RTL8192SE, which uses this driver. If the
+	 * revision ID is RTL_PCI_REVISION_ID_8192PCIE (0x01), then
+	 * the correct driver is r8192e_pci, thus this routine should
+	 * return false.
+	 */
+	if (deviceid == RTL_PCI_8192SE_DID &&
+	    revisionid == RTL_PCI_REVISION_ID_8192PCIE)
+		return false;
+
 	if (deviceid == RTL_PCI_8192_DID ||
 	    deviceid == RTL_PCI_0044_DID ||
 	    deviceid == RTL_PCI_0047_DID ||
@@ -1492,7 +1642,7 @@
 	    deviceid == RTL_PCI_8173_DID ||
 	    deviceid == RTL_PCI_8172_DID ||
 	    deviceid == RTL_PCI_8171_DID) {
-		switch (pdev->revision) {
+		switch (revisionid) {
 		case RTL_PCI_REVISION_ID_8192PCIE:
 			RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
 				 ("8192 PCI-E is found - "
@@ -1521,6 +1671,12 @@
 		RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
 			 ("8192C PCI-E is found - "
 			  "vid/did=%x/%x\n", venderid, deviceid));
+	} else if (deviceid == RTL_PCI_8192DE_DID ||
+		   deviceid == RTL_PCI_8192DE_DID2) {
+		rtlhal->hw_type = HARDWARE_TYPE_RTL8192DE;
+		RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
+			 ("8192D PCI-E is found - "
+			  "vid/did=%x/%x\n", venderid, deviceid));
 	} else {
 		RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
 			 ("Err: Unknown device -"
@@ -1529,6 +1685,25 @@
 		rtlhal->hw_type = RTL_DEFAULT_HARDWARE_TYPE;
 	}
 
+	if (rtlhal->hw_type == HARDWARE_TYPE_RTL8192DE) {
+		if (revisionid == 0 || revisionid == 1) {
+			if (revisionid == 0) {
+				RT_TRACE(rtlpriv, COMP_INIT,
+					 DBG_LOUD, ("Find 92DE MAC0.\n"));
+				rtlhal->interfaceindex = 0;
+			} else if (revisionid == 1) {
+				RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
+					("Find 92DE MAC1.\n"));
+				rtlhal->interfaceindex = 1;
+			}
+		} else {
+			RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
+				("Unknown device - "
+				"VendorID/DeviceID=%x/%x, Revision=%x\n",
+				venderid, deviceid, revisionid));
+			rtlhal->interfaceindex = 0;
+		}
+	}
 	/*find bus info */
 	pcipriv->ndis_adapter.busnumber = pdev->bus->number;
 	pcipriv->ndis_adapter.devnumber = PCI_SLOT(pdev->devfn);
@@ -1554,12 +1729,12 @@
 		    PCI_SLOT(bridge_pdev->devfn);
 		pcipriv->ndis_adapter.pcibridge_funcnum =
 		    PCI_FUNC(bridge_pdev->devfn);
-		pcipriv->ndis_adapter.pcibridge_pciehdr_offset =
-		    pci_pcie_cap(bridge_pdev);
 		pcipriv->ndis_adapter.pcicfg_addrport =
 		    (pcipriv->ndis_adapter.pcibridge_busnum << 16) |
 		    (pcipriv->ndis_adapter.pcibridge_devnum << 11) |
 		    (pcipriv->ndis_adapter.pcibridge_funcnum << 8) | (1 << 31);
+		pcipriv->ndis_adapter.pcibridge_pciehdr_offset =
+		    pci_pcie_cap(bridge_pdev);
 		pcipriv->ndis_adapter.num4bytes =
 		    (pcipriv->ndis_adapter.pcibridge_pciehdr_offset + 0x10) / 4;
 
@@ -1642,6 +1817,11 @@
 	pcipriv = (void *)rtlpriv->priv;
 	pcipriv->dev.pdev = pdev;
 
+	/* init cfg & intf_ops */
+	rtlpriv->rtlhal.interface = INTF_PCI;
+	rtlpriv->cfg = (struct rtl_hal_cfg *)(id->driver_data);
+	rtlpriv->intf_ops = &rtl_pci_ops;
+
 	/*
 	 *init dbgp flags before all
 	 *other functions, because we will
@@ -1659,13 +1839,14 @@
 		return err;
 	}
 
-	pmem_start = pci_resource_start(pdev, 2);
-	pmem_len = pci_resource_len(pdev, 2);
-	pmem_flags = pci_resource_flags(pdev, 2);
+	pmem_start = pci_resource_start(pdev, rtlpriv->cfg->bar_id);
+	pmem_len = pci_resource_len(pdev, rtlpriv->cfg->bar_id);
+	pmem_flags = pci_resource_flags(pdev, rtlpriv->cfg->bar_id);
 
 	/*shared mem start */
 	rtlpriv->io.pci_mem_start =
-			(unsigned long)pci_iomap(pdev, 2, pmem_len);
+			(unsigned long)pci_iomap(pdev,
+			rtlpriv->cfg->bar_id, pmem_len);
 	if (rtlpriv->io.pci_mem_start == 0) {
 		RT_ASSERT(false, ("Can't map PCI mem\n"));
 		goto fail2;
@@ -1684,13 +1865,9 @@
 	pci_write_config_byte(pdev, 0x04, 0x06);
 	pci_write_config_byte(pdev, 0x04, 0x07);
 
-	/* init cfg & intf_ops */
-	rtlpriv->rtlhal.interface = INTF_PCI;
-	rtlpriv->cfg = (struct rtl_hal_cfg *)(id->driver_data);
-	rtlpriv->intf_ops = &rtl_pci_ops;
-
 	/* find adapter */
-	_rtl_pci_find_adapter(pdev, hw);
+	if (!_rtl_pci_find_adapter(pdev, hw))
+		goto fail3;
 
 	/* Init IO handler */
 	_rtl_pci_io_handler_init(&pdev->dev, hw);
@@ -1806,7 +1983,6 @@
 
 	rtl_pci_deinit(hw);
 	rtl_deinit_core(hw);
-	rtlpriv->cfg->ops->deinit_sw_leds(hw);
 	_rtl_pci_io_handler_release(hw);
 	rtlpriv->cfg->ops->deinit_sw_vars(hw);
 
@@ -1821,6 +1997,9 @@
 	}
 
 	pci_disable_device(pdev);
+
+	rtl_pci_disable_aspm(hw);
+
 	pci_set_drvdata(pdev, NULL);
 
 	ieee80211_free_hw(hw);
@@ -1844,10 +2023,15 @@
 ****************************************/
 int rtl_pci_suspend(struct pci_dev *pdev, pm_message_t state)
 {
+	struct ieee80211_hw *hw = pci_get_drvdata(pdev);
+	struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+	rtlpriv->cfg->ops->hw_suspend(hw);
+	rtl_deinit_rfkill(hw);
+
 	pci_save_state(pdev);
 	pci_disable_device(pdev);
 	pci_set_power_state(pdev, PCI_D3hot);
-
 	return 0;
 }
 EXPORT_SYMBOL(rtl_pci_suspend);
@@ -1855,6 +2039,8 @@
 int rtl_pci_resume(struct pci_dev *pdev)
 {
 	int ret;
+	struct ieee80211_hw *hw = pci_get_drvdata(pdev);
+	struct rtl_priv *rtlpriv = rtl_priv(hw);
 
 	pci_set_power_state(pdev, PCI_D0);
 	ret = pci_enable_device(pdev);
@@ -1865,15 +2051,20 @@
 
 	pci_restore_state(pdev);
 
+	rtlpriv->cfg->ops->hw_resume(hw);
+	rtl_init_rfkill(hw);
 	return 0;
 }
 EXPORT_SYMBOL(rtl_pci_resume);
 
 struct rtl_intf_ops rtl_pci_ops = {
+	.read_efuse_byte = read_efuse_byte,
 	.adapter_start = rtl_pci_start,
 	.adapter_stop = rtl_pci_stop,
 	.adapter_tx = rtl_pci_tx,
+	.flush = rtl_pci_flush,
 	.reset_trx_ring = rtl_pci_reset_trx_ring,
+	.waitq_insert = rtl_pci_tx_chk_waitq_insert,
 
 	.disable_aspm = rtl_pci_disable_aspm,
 	.enable_aspm = rtl_pci_enable_aspm,
diff -druN linux-2.6.39-libre/drivers/net/wireless/rtlwifi/pci.h linux-3.0-rc7-libre/drivers/net/wireless/rtlwifi/pci.h
--- linux-2.6.39-libre/drivers/net/wireless/rtlwifi/pci.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/rtlwifi/pci.h	2011-07-11 19:51:52.000000000 -0400
@@ -102,8 +102,8 @@
 #define RTL_PCI_8191CE_DID	0x8177	/*8192ce */
 #define RTL_PCI_8188CE_DID	0x8176	/*8192ce */
 #define RTL_PCI_8192CU_DID	0x8191	/*8192ce */
-#define RTL_PCI_8192DE_DID	0x092D	/*8192ce */
-#define RTL_PCI_8192DU_DID	0x092D	/*8192ce */
+#define RTL_PCI_8192DE_DID	0x8193	/*8192de */
+#define RTL_PCI_8192DE_DID2	0x002B	/*92DE*/
 
 /*8192 support 16 pages of IO registers*/
 #define RTL_MEM_MAPPED_IO_RANGE_8190PCI		0x1000
@@ -129,6 +129,11 @@
 	PCI_BRIDGE_VENDOR_MAX,
 };
 
+struct rtl_pci_capabilities_header {
+	u8 capability_id;
+	u8 next;
+};
+
 struct rtl_rx_desc {
 	u32 dword[8];
 } __packed;
@@ -161,7 +166,9 @@
 
 	bool driver_is_goingto_unload;
 	bool up_first_time;
+	bool first_init;
 	bool being_init_adapter;
+	bool init_ready;
 	bool irq_enabled;
 
 	/*Tx */
@@ -192,11 +199,14 @@
 	u8 const_devicepci_aspm_setting;
 	/*If it supports ASPM, Offset[560h] = 0x40,
 	   otherwise Offset[560h] = 0x00. */
-	bool b_support_aspm;
-	bool b_support_backdoor;
+	bool support_aspm;
+	bool support_backdoor;
 
 	/*QOS & EDCA */
 	enum acm_method acm_method;
+
+	u16 shortretry_limit;
+	u16 longretry_limit;
 };
 
 struct mp_adapter {
@@ -227,6 +237,7 @@
 	struct rtl_pci dev;
 	struct mp_adapter ndis_adapter;
 	struct rtl_led_ctl ledctl;
+	struct bt_coexist_info bt_coexist;
 };
 
 #define rtl_pcipriv(hw)		(((struct rtl_pci_priv *)(rtl_priv(hw))->priv))
diff -druN linux-2.6.39-libre/drivers/net/wireless/rtlwifi/ps.c linux-3.0-rc7-libre/drivers/net/wireless/rtlwifi/ps.c
--- linux-2.6.39-libre/drivers/net/wireless/rtlwifi/ps.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/rtlwifi/ps.c	2011-07-11 19:51:52.000000000 -0400
@@ -36,7 +36,6 @@
 	struct rtl_priv *rtlpriv = rtl_priv(hw);
 	struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
 	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
-	bool init_status = true;
 
 	/*<1> reset trx ring */
 	if (rtlhal->interface == INTF_PCI)
@@ -49,7 +48,6 @@
 	/*<2> Enable Adapter */
 	rtlpriv->cfg->ops->hw_init(hw);
 	RT_CLEAR_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC);
-	/*init_status = false; */
 
 	/*<3> Enable Interrupt */
 	rtlpriv->cfg->ops->enable_interrupt(hw);
@@ -57,13 +55,12 @@
 	/*<enable timer> */
 	rtl_watch_dog_timer_callback((unsigned long)hw);
 
-	return init_status;
+	return true;
 }
 EXPORT_SYMBOL(rtl_ps_enable_nic);
 
 bool rtl_ps_disable_nic(struct ieee80211_hw *hw)
 {
-	bool status = true;
 	struct rtl_priv *rtlpriv = rtl_priv(hw);
 
 	/*<1> Stop all timer */
@@ -75,7 +72,7 @@
 	/*<3> Disable Adapter */
 	rtlpriv->cfg->ops->hw_disable(hw);
 
-	return status;
+	return true;
 }
 EXPORT_SYMBOL(rtl_ps_disable_nic);
 
@@ -193,12 +190,13 @@
 
 	ppsc->swrf_processing = true;
 
-	if (ppsc->inactive_pwrstate == ERFON && rtlhal->interface == INTF_PCI) {
+	if (ppsc->inactive_pwrstate == ERFON &&
+	    rtlhal->interface == INTF_PCI) {
 		if ((ppsc->reg_rfps_level & RT_RF_OFF_LEVL_ASPM) &&
-		    RT_IN_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_ASPM) &&
+		    RT_IN_PS_LEVEL(ppsc, RT_PS_LEVEL_ASPM) &&
 		    rtlhal->interface == INTF_PCI) {
 			rtlpriv->intf_ops->disable_aspm(hw);
-			RT_CLEAR_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_ASPM);
+			RT_CLEAR_PS_LEVEL(ppsc, RT_PS_LEVEL_ASPM);
 		}
 	}
 
@@ -207,9 +205,10 @@
 
 	if (ppsc->inactive_pwrstate == ERFOFF &&
 	    rtlhal->interface == INTF_PCI) {
-		if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_ASPM) {
+		if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_ASPM &&
+			!RT_IN_PS_LEVEL(ppsc, RT_PS_LEVEL_ASPM)) {
 			rtlpriv->intf_ops->enable_aspm(hw);
-			RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_ASPM);
+			RT_SET_PS_LEVEL(ppsc, RT_PS_LEVEL_ASPM);
 		}
 	}
 
@@ -233,6 +232,9 @@
 		return;
 	}
 
+	if (mac->link_state > MAC80211_NOLINK)
+		return;
+
 	if (is_hal_stop(rtlhal))
 		return;
 
@@ -284,10 +286,14 @@
 void rtl_ips_nic_on(struct ieee80211_hw *hw)
 {
 	struct rtl_priv *rtlpriv = rtl_priv(hw);
+	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
 	struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
 	enum rf_pwrstate rtstate;
 	unsigned long flags;
 
+	if (mac->opmode != NL80211_IFTYPE_STATION)
+		return;
+
 	spin_lock_irqsave(&rtlpriv->locks.ips_lock, flags);
 
 	if (ppsc->inactiveps) {
@@ -370,8 +376,7 @@
 	 *   mode and set RPWM to turn RF on.
 	 */
 
-	if ((ppsc->fwctrl_lps) && (ppsc->leisure_ps) &&
-	     ppsc->report_linked) {
+	if ((ppsc->fwctrl_lps) && ppsc->report_linked) {
 		bool fw_current_inps;
 		if (ppsc->dot11_psmode == EACTIVE) {
 			RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
@@ -425,7 +430,7 @@
 	struct rtl_priv *rtlpriv = rtl_priv(hw);
 	unsigned long flag;
 
-	if (!(ppsc->fwctrl_lps && ppsc->leisure_ps))
+	if (!ppsc->fwctrl_lps)
 		return;
 
 	if (rtlpriv->sec.being_setkey)
@@ -446,17 +451,16 @@
 
 	spin_lock_irqsave(&rtlpriv->locks.lps_lock, flag);
 
-	if (ppsc->leisure_ps) {
-		/* Idle for a while if we connect to AP a while ago. */
-		if (mac->cnt_after_linked >= 2) {
-			if (ppsc->dot11_psmode == EACTIVE) {
-				RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
+	/* Idle for a while if we connect to AP a while ago. */
+	if (mac->cnt_after_linked >= 2) {
+		if (ppsc->dot11_psmode == EACTIVE) {
+			RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
 					("Enter 802.11 power save mode...\n"));
 
-				rtl_lps_set_psmode(hw, EAUTOPS);
-			}
+			rtl_lps_set_psmode(hw, EAUTOPS);
 		}
 	}
+
 	spin_unlock_irqrestore(&rtlpriv->locks.lps_lock, flag);
 }
 
@@ -470,17 +474,17 @@
 
 	spin_lock_irqsave(&rtlpriv->locks.lps_lock, flag);
 
-	if (ppsc->fwctrl_lps && ppsc->leisure_ps) {
+	if (ppsc->fwctrl_lps) {
 		if (ppsc->dot11_psmode != EACTIVE) {
 
 			/*FIX ME */
 			rtlpriv->cfg->ops->enable_interrupt(hw);
 
 			if (ppsc->reg_rfps_level & RT_RF_LPS_LEVEL_ASPM &&
-			    RT_IN_PS_LEVEL(ppsc, RT_RF_LPS_LEVEL_ASPM) &&
+			    RT_IN_PS_LEVEL(ppsc, RT_PS_LEVEL_ASPM) &&
 			    rtlhal->interface == INTF_PCI) {
 				rtlpriv->intf_ops->disable_aspm(hw);
-				RT_CLEAR_PS_LEVEL(ppsc, RT_RF_LPS_LEVEL_ASPM);
+				RT_CLEAR_PS_LEVEL(ppsc, RT_PS_LEVEL_ASPM);
 			}
 
 			RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
@@ -491,3 +495,214 @@
 	}
 	spin_unlock_irqrestore(&rtlpriv->locks.lps_lock, flag);
 }
+
+/* For sw LPS*/
+void rtl_swlps_beacon(struct ieee80211_hw *hw, void *data, unsigned int len)
+{
+	struct rtl_priv *rtlpriv = rtl_priv(hw);
+	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+	struct ieee80211_hdr *hdr = (void *) data;
+	struct ieee80211_tim_ie *tim_ie;
+	u8 *tim;
+	u8 tim_len;
+	bool u_buffed;
+	bool m_buffed;
+
+	if (mac->opmode != NL80211_IFTYPE_STATION)
+		return;
+
+	if (!rtlpriv->psc.swctrl_lps)
+		return;
+
+	if (rtlpriv->mac80211.link_state != MAC80211_LINKED)
+		return;
+
+	if (!rtlpriv->psc.sw_ps_enabled)
+		return;
+
+	if (rtlpriv->psc.fwctrl_lps)
+		return;
+
+	if (likely(!(hw->conf.flags & IEEE80211_CONF_PS)))
+		return;
+
+	/* check if this really is a beacon */
+	if (!ieee80211_is_beacon(hdr->frame_control))
+		return;
+
+	/* min. beacon length + FCS_LEN */
+	if (len <= 40 + FCS_LEN)
+		return;
+
+	/* and only beacons from the associated BSSID, please */
+	if (compare_ether_addr(hdr->addr3, rtlpriv->mac80211.bssid))
+		return;
+
+	rtlpriv->psc.last_beacon = jiffies;
+
+	tim = rtl_find_ie(data, len - FCS_LEN, WLAN_EID_TIM);
+	if (!tim)
+		return;
+
+	if (tim[1] < sizeof(*tim_ie))
+		return;
+
+	tim_len = tim[1];
+	tim_ie = (struct ieee80211_tim_ie *) &tim[2];
+
+	if (!WARN_ON_ONCE(!hw->conf.ps_dtim_period))
+		rtlpriv->psc.dtim_counter = tim_ie->dtim_count;
+
+	/* Check whenever the PHY can be turned off again. */
+
+	/* 1. What about buffered unicast traffic for our AID? */
+	u_buffed = ieee80211_check_tim(tim_ie, tim_len,
+				       rtlpriv->mac80211.assoc_id);
+
+	/* 2. Maybe the AP wants to send multicast/broadcast data? */
+	m_buffed = tim_ie->bitmap_ctrl & 0x01;
+	rtlpriv->psc.multi_buffered = m_buffed;
+
+	/* unicast will process by mac80211 through
+	 * set ~IEEE80211_CONF_PS, So we just check
+	 * multicast frames here */
+	if (!m_buffed) {
+		/* back to low-power land. and delay is
+		 * prevent null power save frame tx fail */
+		queue_delayed_work(rtlpriv->works.rtl_wq,
+				&rtlpriv->works.ps_work, MSECS(5));
+	} else {
+		RT_TRACE(rtlpriv, COMP_POWER, DBG_DMESG, ("u_bufferd: %x, "
+				"m_buffered: %x\n", u_buffed, m_buffed));
+	}
+}
+
+void rtl_swlps_rf_awake(struct ieee80211_hw *hw)
+{
+	struct rtl_priv *rtlpriv = rtl_priv(hw);
+	struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
+	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+	unsigned long flag;
+
+	if (!rtlpriv->psc.swctrl_lps)
+		return;
+	if (mac->link_state != MAC80211_LINKED)
+		return;
+
+	if (ppsc->reg_rfps_level & RT_RF_LPS_LEVEL_ASPM &&
+		RT_IN_PS_LEVEL(ppsc, RT_PS_LEVEL_ASPM)) {
+		rtlpriv->intf_ops->disable_aspm(hw);
+		RT_CLEAR_PS_LEVEL(ppsc, RT_PS_LEVEL_ASPM);
+	}
+
+	spin_lock_irqsave(&rtlpriv->locks.lps_lock, flag);
+	rtl_ps_set_rf_state(hw, ERFON, RF_CHANGE_BY_PS, false);
+	spin_unlock_irqrestore(&rtlpriv->locks.lps_lock, flag);
+}
+
+void rtl_swlps_rfon_wq_callback(void *data)
+{
+	struct rtl_works *rtlworks =
+	    container_of_dwork_rtl(data, struct rtl_works, ps_rfon_wq);
+	struct ieee80211_hw *hw = rtlworks->hw;
+
+	rtl_swlps_rf_awake(hw);
+}
+
+void rtl_swlps_rf_sleep(struct ieee80211_hw *hw)
+{
+	struct rtl_priv *rtlpriv = rtl_priv(hw);
+	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+	struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
+	unsigned long flag;
+	u8 sleep_intv;
+
+	if (!rtlpriv->psc.sw_ps_enabled)
+		return;
+
+	if ((rtlpriv->sec.being_setkey) ||
+	    (mac->opmode == NL80211_IFTYPE_ADHOC))
+		return;
+
+	/*sleep after linked 10s, to let DHCP and 4-way handshake ok enough!! */
+	if ((mac->link_state != MAC80211_LINKED) || (mac->cnt_after_linked < 5))
+		return;
+
+	if (rtlpriv->link_info.busytraffic)
+		return;
+
+	spin_lock_irqsave(&rtlpriv->locks.rf_ps_lock, flag);
+	if (rtlpriv->psc.rfchange_inprogress) {
+		spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock, flag);
+		return;
+	}
+	spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock, flag);
+
+	spin_lock_irqsave(&rtlpriv->locks.lps_lock, flag);
+	rtl_ps_set_rf_state(hw, ERFSLEEP, RF_CHANGE_BY_PS, false);
+	spin_unlock_irqrestore(&rtlpriv->locks.lps_lock, flag);
+
+	if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_ASPM &&
+		!RT_IN_PS_LEVEL(ppsc, RT_PS_LEVEL_ASPM)) {
+		rtlpriv->intf_ops->enable_aspm(hw);
+		RT_SET_PS_LEVEL(ppsc, RT_PS_LEVEL_ASPM);
+	}
+
+	/* here is power save alg, when this beacon is DTIM
+	 * we will set sleep time to dtim_period * n;
+	 * when this beacon is not DTIM, we will set sleep
+	 * time to sleep_intv = rtlpriv->psc.dtim_counter or
+	 * MAX_SW_LPS_SLEEP_INTV(default set to 5) */
+
+	if (rtlpriv->psc.dtim_counter == 0) {
+		if (hw->conf.ps_dtim_period == 1)
+			sleep_intv = hw->conf.ps_dtim_period * 2;
+		else
+			sleep_intv = hw->conf.ps_dtim_period;
+	} else {
+		sleep_intv = rtlpriv->psc.dtim_counter;
+	}
+
+	if (sleep_intv > MAX_SW_LPS_SLEEP_INTV)
+		sleep_intv = MAX_SW_LPS_SLEEP_INTV;
+
+	/* this print should always be dtim_conter = 0 &
+	 * sleep  = dtim_period, that meaons, we should
+	 * awake before every dtim */
+	RT_TRACE(rtlpriv, COMP_POWER, DBG_DMESG,
+		 ("dtim_counter:%x will sleep :%d"
+		 " beacon_intv\n", rtlpriv->psc.dtim_counter, sleep_intv));
+
+	/* we tested that 40ms is enough for sw & hw sw delay */
+	queue_delayed_work(rtlpriv->works.rtl_wq, &rtlpriv->works.ps_rfon_wq,
+			MSECS(sleep_intv * mac->vif->bss_conf.beacon_int - 40));
+}
+
+
+void rtl_swlps_wq_callback(void *data)
+{
+	struct rtl_works *rtlworks = container_of_dwork_rtl(data,
+				     struct rtl_works,
+				     ps_work);
+	struct ieee80211_hw *hw = rtlworks->hw;
+	struct rtl_priv *rtlpriv = rtl_priv(hw);
+	bool ps = false;
+
+	ps = (hw->conf.flags & IEEE80211_CONF_PS);
+
+	/* we can sleep after ps null send ok */
+	if (rtlpriv->psc.state_inap) {
+		rtl_swlps_rf_sleep(hw);
+
+		if (rtlpriv->psc.state && !ps) {
+			rtlpriv->psc.sleep_ms = jiffies_to_msecs(jiffies -
+					rtlpriv->psc.last_action);
+		}
+
+		if (ps)
+			rtlpriv->psc.last_slept = jiffies;
+
+		rtlpriv->psc.last_action = jiffies;
+		rtlpriv->psc.state = ps;
+	}
+}
diff -druN linux-2.6.39-libre/drivers/net/wireless/rtlwifi/ps.h linux-3.0-rc7-libre/drivers/net/wireless/rtlwifi/ps.h
--- linux-2.6.39-libre/drivers/net/wireless/rtlwifi/ps.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/rtlwifi/ps.h	2011-07-11 19:51:52.000000000 -0400
@@ -30,6 +30,8 @@
 #ifndef __REALTEK_RTL_PCI_PS_H__
 #define __REALTEK_RTL_PCI_PS_H__
 
+#define MAX_SW_LPS_SLEEP_INTV	5
+
 bool rtl_ps_set_rf_state(struct ieee80211_hw *hw,
 			 enum rf_pwrstate state_toset, u32 changesource,
 			 bool protect_or_not);
@@ -40,4 +42,11 @@
 void rtl_ips_nic_off_wq_callback(void *data);
 void rtl_lps_enter(struct ieee80211_hw *hw);
 void rtl_lps_leave(struct ieee80211_hw *hw);
+
+void rtl_swlps_beacon(struct ieee80211_hw *hw, void *data, unsigned int len);
+void rtl_swlps_wq_callback(void *data);
+void rtl_swlps_rfon_wq_callback(void *data);
+void rtl_swlps_rf_awake(struct ieee80211_hw *hw);
+void rtl_swlps_rf_sleep(struct ieee80211_hw *hw);
+
 #endif
diff -druN linux-2.6.39-libre/drivers/net/wireless/rtlwifi/rc.c linux-3.0-rc7-libre/drivers/net/wireless/rtlwifi/rc.c
--- linux-2.6.39-libre/drivers/net/wireless/rtlwifi/rc.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/rtlwifi/rc.c	2011-07-11 19:51:52.000000000 -0400
@@ -38,17 +38,14 @@
  *CCK11M or OFDM_54M based on wireless mode.
  */
 static u8 _rtl_rc_get_highest_rix(struct rtl_priv *rtlpriv,
+				  struct ieee80211_sta *sta,
 				  struct sk_buff *skb, bool not_data)
 {
 	struct rtl_mac *rtlmac = rtl_mac(rtlpriv);
-
-	/*
-	 *mgt use 1M, although we have check it
-	 *before this function use rate_control_send_low,
-	 *we still check it here
-	 */
-	if (not_data)
-		return rtlpriv->cfg->maps[RTL_RC_CCK_RATE1M];
+	struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
+	struct rtl_phy *rtlphy = &(rtlpriv->phy);
+	struct rtl_sta_info *sta_entry = NULL;
+	u8 wireless_mode = 0;
 
 	/*
 	 *this rate is no use for true rate, firmware
@@ -57,35 +54,78 @@
 	 *2.in rtl_get_tcb_desc when we check rate is
 	 *      1M we will not use FW rate but user rate.
 	 */
-	if (rtl_is_special_data(rtlpriv->mac80211.hw, skb, true)) {
-		return rtlpriv->cfg->maps[RTL_RC_CCK_RATE1M];
+	if (rtlmac->opmode == NL80211_IFTYPE_AP ||
+		rtlmac->opmode == NL80211_IFTYPE_ADHOC) {
+		if (sta) {
+			sta_entry = (struct rtl_sta_info *) sta->drv_priv;
+			wireless_mode = sta_entry->wireless_mode;
+		} else {
+			return 0;
+		}
 	} else {
-		if (rtlmac->mode == WIRELESS_MODE_B)
-			return rtlpriv->cfg->maps[RTL_RC_CCK_RATE11M];
-		else
-			return rtlpriv->cfg->maps[RTL_RC_OFDM_RATE54M];
+		wireless_mode = rtlmac->mode;
+	}
+
+	if (rtl_is_special_data(rtlpriv->mac80211.hw, skb, true) ||
+			not_data) {
+		return 0;
+	} else {
+		if (rtlhal->current_bandtype == BAND_ON_2_4G) {
+			if (wireless_mode == WIRELESS_MODE_B) {
+				return B_MODE_MAX_RIX;
+			} else if (wireless_mode == WIRELESS_MODE_G) {
+				return G_MODE_MAX_RIX;
+			} else {
+				if (get_rf_type(rtlphy) != RF_2T2R)
+					return N_MODE_MCS7_RIX;
+				else
+					return N_MODE_MCS15_RIX;
+			}
+		} else {
+			if (wireless_mode == WIRELESS_MODE_A) {
+				return A_MODE_MAX_RIX;
+			} else {
+				if (get_rf_type(rtlphy) != RF_2T2R)
+					return N_MODE_MCS7_RIX;
+				else
+					return N_MODE_MCS15_RIX;
+			}
+		}
 	}
 }
 
 static void _rtl_rc_rate_set_series(struct rtl_priv *rtlpriv,
+				    struct ieee80211_sta *sta,
 				    struct ieee80211_tx_rate *rate,
 				    struct ieee80211_tx_rate_control *txrc,
-				    u8 tries, u8 rix, int rtsctsenable,
+				    u8 tries, char rix, int rtsctsenable,
 				    bool not_data)
 {
 	struct rtl_mac *mac = rtl_mac(rtlpriv);
+	u8 sgi_20 = 0, sgi_40 = 0;
 
+	if (sta) {
+		sgi_20 = sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20;
+		sgi_40 = sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40;
+	}
 	rate->count = tries;
-	rate->idx = (rix > 0x2) ? rix : 0x2;
+	rate->idx = rix >= 0x00 ? rix : 0x00;
 
 	if (!not_data) {
 		if (txrc->short_preamble)
 			rate->flags |= IEEE80211_TX_RC_USE_SHORT_PREAMBLE;
-		if (mac->bw_40)
-			rate->flags |= IEEE80211_TX_RC_40_MHZ_WIDTH;
-		if (mac->sgi_20 || mac->sgi_40)
+		if (mac->opmode == NL80211_IFTYPE_AP ||
+			mac->opmode == NL80211_IFTYPE_ADHOC) {
+			if (sta && (sta->ht_cap.cap &
+			    IEEE80211_HT_CAP_SUP_WIDTH_20_40))
+				rate->flags |= IEEE80211_TX_RC_40_MHZ_WIDTH;
+		} else {
+			if (mac->bw_40)
+				rate->flags |= IEEE80211_TX_RC_40_MHZ_WIDTH;
+		}
+		if (sgi_20 || sgi_40)
 			rate->flags |= IEEE80211_TX_RC_SHORT_GI;
-		if (mac->ht_enable)
+		if (sta && sta->ht_cap.ht_supported)
 			rate->flags |= IEEE80211_TX_RC_MCS;
 	}
 }
@@ -97,39 +137,39 @@
 	struct sk_buff *skb = txrc->skb;
 	struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
 	struct ieee80211_tx_rate *rates = tx_info->control.rates;
-	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
-	__le16 fc = hdr->frame_control;
+	__le16 fc = rtl_get_fc(skb);
 	u8 try_per_rate, i, rix;
 	bool not_data = !ieee80211_is_data(fc);
 
 	if (rate_control_send_low(sta, priv_sta, txrc))
 		return;
 
-	rix = _rtl_rc_get_highest_rix(rtlpriv, skb, not_data);
-
+	rix = _rtl_rc_get_highest_rix(rtlpriv, sta, skb, not_data);
 	try_per_rate = 1;
-	_rtl_rc_rate_set_series(rtlpriv, &rates[0], txrc,
+	_rtl_rc_rate_set_series(rtlpriv, sta, &rates[0], txrc,
 				try_per_rate, rix, 1, not_data);
 
 	if (!not_data) {
 		for (i = 1; i < 4; i++)
-			_rtl_rc_rate_set_series(rtlpriv, &rates[i],
+			_rtl_rc_rate_set_series(rtlpriv, sta, &rates[i],
 						txrc, i, (rix - i), 1,
 						not_data);
 	}
 }
 
-static bool _rtl_tx_aggr_check(struct rtl_priv *rtlpriv, u16 tid)
+static bool _rtl_tx_aggr_check(struct rtl_priv *rtlpriv,
+		struct rtl_sta_info *sta_entry, u16 tid)
 {
 	struct rtl_mac *mac = rtl_mac(rtlpriv);
 
 	if (mac->act_scanning)
 		return false;
 
-	if (mac->cnt_after_linked < 3)
+	if (mac->opmode == NL80211_IFTYPE_STATION &&
+		mac->cnt_after_linked < 3)
 		return false;
 
-	if (mac->tids[tid].agg.agg_state == RTL_AGG_OFF)
+	if (sta_entry->tids[tid].agg.agg_state == RTL_AGG_STOP)
 		return true;
 
 	return false;
@@ -143,11 +183,9 @@
 {
 	struct rtl_priv *rtlpriv = ppriv;
 	struct rtl_mac *mac = rtl_mac(rtlpriv);
-	struct ieee80211_hdr *hdr;
-	__le16 fc;
-
-	hdr = (struct ieee80211_hdr *)skb->data;
-	fc = hdr->frame_control;
+	struct ieee80211_hdr *hdr = rtl_get_hdr(skb);
+	__le16 fc = rtl_get_fc(skb);
+	struct rtl_sta_info *sta_entry;
 
 	if (!priv_sta || !ieee80211_is_data(fc))
 		return;
@@ -159,17 +197,21 @@
 	    || is_broadcast_ether_addr(ieee80211_get_DA(hdr)))
 		return;
 
-	/* Check if aggregation has to be enabled for this tid */
-	if (conf_is_ht(&mac->hw->conf) &&
-	    !(skb->protocol == cpu_to_be16(ETH_P_PAE))) {
-		if (ieee80211_is_data_qos(fc)) {
-			u8 *qc, tid;
-
-			qc = ieee80211_get_qos_ctl(hdr);
-			tid = qc[0] & 0xf;
-
-			if (_rtl_tx_aggr_check(rtlpriv, tid))
-				ieee80211_start_tx_ba_session(sta, tid, 5000);
+	if (sta) {
+		/* Check if aggregation has to be enabled for this tid */
+		sta_entry = (struct rtl_sta_info *) sta->drv_priv;
+		if ((sta->ht_cap.ht_supported == true) &&
+				!(skb->protocol == cpu_to_be16(ETH_P_PAE))) {
+			if (ieee80211_is_data_qos(fc)) {
+				u8 tid = rtl_get_tid(skb);
+				if (_rtl_tx_aggr_check(rtlpriv, sta_entry,
+				    tid)) {
+					sta_entry->tids[tid].agg.agg_state =
+							 RTL_AGG_PROGRESS;
+					ieee80211_start_tx_ba_session(sta,
+								 tid, 5000);
+				}
+			}
 		}
 	}
 }
@@ -178,43 +220,6 @@
 			  struct ieee80211_supported_band *sband,
 			  struct ieee80211_sta *sta, void *priv_sta)
 {
-	struct rtl_priv *rtlpriv = ppriv;
-	struct rtl_mac *mac = rtl_mac(rtlpriv);
-	u8 is_ht = conf_is_ht(&mac->hw->conf);
-
-	if ((mac->opmode == NL80211_IFTYPE_STATION) ||
-	    (mac->opmode == NL80211_IFTYPE_MESH_POINT) ||
-	    (mac->opmode == NL80211_IFTYPE_ADHOC)) {
-
-		switch (sband->band) {
-		case IEEE80211_BAND_2GHZ:
-			rtlpriv->rate_priv->cur_ratetab_idx =
-			    RATR_INX_WIRELESS_G;
-			if (is_ht)
-				rtlpriv->rate_priv->cur_ratetab_idx =
-				    RATR_INX_WIRELESS_NGB;
-			break;
-		case IEEE80211_BAND_5GHZ:
-			rtlpriv->rate_priv->cur_ratetab_idx =
-			    RATR_INX_WIRELESS_A;
-			if (is_ht)
-				rtlpriv->rate_priv->cur_ratetab_idx =
-				    RATR_INX_WIRELESS_NGB;
-			break;
-		default:
-			RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
-				 ("Invalid band\n"));
-			rtlpriv->rate_priv->cur_ratetab_idx =
-			    RATR_INX_WIRELESS_NGB;
-			break;
-		}
-
-		RT_TRACE(rtlpriv, COMP_RATE, DBG_DMESG,
-			 ("Choosing rate table index: %d\n",
-			  rtlpriv->rate_priv->cur_ratetab_idx));
-
-	}
-
 }
 
 static void rtl_rate_update(void *ppriv,
@@ -223,49 +228,6 @@
 			    u32 changed,
 			    enum nl80211_channel_type oper_chan_type)
 {
-	struct rtl_priv *rtlpriv = ppriv;
-	struct rtl_mac *mac = rtl_mac(rtlpriv);
-	struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
-	bool oper_cw40 = false, oper_sgi40;
-	bool local_cw40 = mac->bw_40;
-	bool local_sgi40 = mac->sgi_40;
-	u8 is_ht = conf_is_ht(&mac->hw->conf);
-
-	if (changed & IEEE80211_RC_HT_CHANGED) {
-		if (mac->opmode != NL80211_IFTYPE_STATION)
-			return;
-
-		if (rtlhal->hw->conf.channel_type == NL80211_CHAN_HT40MINUS ||
-		    rtlhal->hw->conf.channel_type == NL80211_CHAN_HT40PLUS)
-			oper_cw40 = true;
-
-		oper_sgi40 = mac->sgi_40;
-
-		if ((local_cw40 != oper_cw40) || (local_sgi40 != oper_sgi40)) {
-			switch (sband->band) {
-			case IEEE80211_BAND_2GHZ:
-				rtlpriv->rate_priv->cur_ratetab_idx =
-				    RATR_INX_WIRELESS_G;
-				if (is_ht)
-					rtlpriv->rate_priv->cur_ratetab_idx =
-					    RATR_INX_WIRELESS_NGB;
-				break;
-			case IEEE80211_BAND_5GHZ:
-				rtlpriv->rate_priv->cur_ratetab_idx =
-				    RATR_INX_WIRELESS_A;
-				if (is_ht)
-					rtlpriv->rate_priv->cur_ratetab_idx =
-					    RATR_INX_WIRELESS_NGB;
-				break;
-			default:
-				RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-					 ("Invalid band\n"));
-				rtlpriv->rate_priv->cur_ratetab_idx =
-				    RATR_INX_WIRELESS_NGB;
-				break;
-			}
-		}
-	}
 }
 
 static void *rtl_rate_alloc(struct ieee80211_hw *hw,
diff -druN linux-2.6.39-libre/drivers/net/wireless/rtlwifi/rc.h linux-3.0-rc7-libre/drivers/net/wireless/rtlwifi/rc.h
--- linux-2.6.39-libre/drivers/net/wireless/rtlwifi/rc.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/rtlwifi/rc.h	2011-07-11 19:51:52.000000000 -0400
@@ -30,8 +30,15 @@
 #ifndef __RTL_RC_H__
 #define __RTL_RC_H__
 
+#define B_MODE_MAX_RIX 3
+#define G_MODE_MAX_RIX 11
+#define A_MODE_MAX_RIX 7
+
+/* in mac80211 mcs0-mcs15 is idx0-idx15*/
+#define N_MODE_MCS7_RIX 7
+#define N_MODE_MCS15_RIX 15
+
 struct rtl_rate_priv {
-	u8 cur_ratetab_idx;
 	u8 ht_cap;
 };
 
diff -druN linux-2.6.39-libre/drivers/net/wireless/rtlwifi/regd.c linux-3.0-rc7-libre/drivers/net/wireless/rtlwifi/regd.c
--- linux-2.6.39-libre/drivers/net/wireless/rtlwifi/regd.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/rtlwifi/regd.c	2011-07-11 19:51:52.000000000 -0400
@@ -66,31 +66,83 @@
 	NL80211_RRF_PASSIVE_SCAN | \
 	NL80211_RRF_NO_OFDM)
 
+/* 5G chan 36 - chan 64*/
+#define RTL819x_5GHZ_5150_5350	\
+	REG_RULE(5150-10, 5350+10, 40, 0, 30, \
+	NL80211_RRF_PASSIVE_SCAN | \
+	NL80211_RRF_NO_IBSS)
+
+/* 5G chan 100 - chan 165*/
+#define RTL819x_5GHZ_5470_5850	\
+	REG_RULE(5470-10, 5850+10, 40, 0, 30, \
+	NL80211_RRF_PASSIVE_SCAN | \
+	NL80211_RRF_NO_IBSS)
+
+/* 5G chan 149 - chan 165*/
+#define RTL819x_5GHZ_5725_5850	\
+	REG_RULE(5725-10, 5850+10, 40, 0, 30, \
+	NL80211_RRF_PASSIVE_SCAN | \
+	NL80211_RRF_NO_IBSS)
+
+#define RTL819x_5GHZ_ALL	\
+	(RTL819x_5GHZ_5150_5350, RTL819x_5GHZ_5470_5850)
+
 static const struct ieee80211_regdomain rtl_regdom_11 = {
 	.n_reg_rules = 1,
 	.alpha2 = "99",
 	.reg_rules = {
 		      RTL819x_2GHZ_CH01_11,
-	}
+		      }
 };
 
-static const struct ieee80211_regdomain rtl_regdom_global = {
+static const struct ieee80211_regdomain rtl_regdom_12_13 = {
+	.n_reg_rules = 2,
+	.alpha2 = "99",
+	.reg_rules = {
+		      RTL819x_2GHZ_CH01_11,
+			  RTL819x_2GHZ_CH12_13,
+		      }
+};
+
+static const struct ieee80211_regdomain rtl_regdom_no_midband = {
 	.n_reg_rules = 3,
 	.alpha2 = "99",
 	.reg_rules = {
 		      RTL819x_2GHZ_CH01_11,
-		      RTL819x_2GHZ_CH12_13,
-		      RTL819x_2GHZ_CH14,
-	}
+			  RTL819x_5GHZ_5150_5350,
+			  RTL819x_5GHZ_5725_5850,
+		      }
 };
 
-static const struct ieee80211_regdomain rtl_regdom_world = {
-	.n_reg_rules = 2,
+static const struct ieee80211_regdomain rtl_regdom_60_64 = {
+	.n_reg_rules = 3,
 	.alpha2 = "99",
 	.reg_rules = {
 		      RTL819x_2GHZ_CH01_11,
-		      RTL819x_2GHZ_CH12_13,
-	}
+			  RTL819x_2GHZ_CH12_13,
+			  RTL819x_5GHZ_5725_5850,
+		      }
+};
+
+static const struct ieee80211_regdomain rtl_regdom_14_60_64 = {
+	.n_reg_rules = 4,
+	.alpha2 = "99",
+	.reg_rules = {
+		      RTL819x_2GHZ_CH01_11,
+			  RTL819x_2GHZ_CH12_13,
+			  RTL819x_2GHZ_CH14,
+			  RTL819x_5GHZ_5725_5850,
+		      }
+};
+
+static const struct ieee80211_regdomain rtl_regdom_14 = {
+	.n_reg_rules = 3,
+	.alpha2 = "99",
+	.reg_rules = {
+		      RTL819x_2GHZ_CH01_11,
+			  RTL819x_2GHZ_CH12_13,
+			  RTL819x_2GHZ_CH14,
+		      }
 };
 
 static bool _rtl_is_radar_freq(u16 center_freq)
@@ -162,6 +214,8 @@
 	u32 bandwidth = 0;
 	int r;
 
+	if (!wiphy->bands[IEEE80211_BAND_2GHZ])
+		return;
 	sband = wiphy->bands[IEEE80211_BAND_2GHZ];
 
 	/*
@@ -292,25 +346,26 @@
 {
 	switch (reg->country_code) {
 	case COUNTRY_CODE_FCC:
+		return &rtl_regdom_no_midband;
 	case COUNTRY_CODE_IC:
 		return &rtl_regdom_11;
 	case COUNTRY_CODE_ETSI:
+	case COUNTRY_CODE_TELEC_NETGEAR:
+		return &rtl_regdom_60_64;
 	case COUNTRY_CODE_SPAIN:
 	case COUNTRY_CODE_FRANCE:
 	case COUNTRY_CODE_ISRAEL:
-	case COUNTRY_CODE_TELEC_NETGEAR:
-		return &rtl_regdom_world;
+	case COUNTRY_CODE_WORLD_WIDE_13:
+		return &rtl_regdom_12_13;
 	case COUNTRY_CODE_MKK:
 	case COUNTRY_CODE_MKK1:
 	case COUNTRY_CODE_TELEC:
 	case COUNTRY_CODE_MIC:
-		return &rtl_regdom_global;
+		return &rtl_regdom_14_60_64;
 	case COUNTRY_CODE_GLOBAL_DOMAIN:
-		return &rtl_regdom_global;
-	case COUNTRY_CODE_WORLD_WIDE_13:
-		return &rtl_regdom_world;
+		return &rtl_regdom_14;
 	default:
-		return &rtl_regdom_world;
+		return &rtl_regdom_no_midband;
 	}
 }
 
@@ -323,9 +378,11 @@
 	const struct ieee80211_regdomain *regd;
 
 	wiphy->reg_notifier = reg_notifier;
+
 	wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY;
 	wiphy->flags &= ~WIPHY_FLAG_STRICT_REGULATORY;
 	wiphy->flags &= ~WIPHY_FLAG_DISABLE_BEACON_HINTS;
+
 	regd = _rtl_regdomain_select(reg);
 	wiphy_apply_custom_regulatory(wiphy, regd);
 	_rtl_reg_apply_radar_flags(wiphy);
@@ -355,8 +412,8 @@
 	if (wiphy == NULL || &rtlpriv->regd == NULL)
 		return -EINVAL;
 
-	/* force the channel plan to world wide 13 */
-	rtlpriv->regd.country_code = COUNTRY_CODE_WORLD_WIDE_13;
+	/* init country_code from efuse channel plan */
+	rtlpriv->regd.country_code = rtlpriv->efuse.channel_plan;
 
 	RT_TRACE(rtlpriv, COMP_REGD, DBG_TRACE,
 		 (KERN_DEBUG "rtl: EEPROM regdomain: 0x%0x\n",
@@ -373,8 +430,8 @@
 	country = _rtl_regd_find_country(rtlpriv->regd.country_code);
 
 	if (country) {
-		rtlpriv->regd.alpha2[0] = country->isoName[0];
-		rtlpriv->regd.alpha2[1] = country->isoName[1];
+		rtlpriv->regd.alpha2[0] = country->iso_name[0];
+		rtlpriv->regd.alpha2[1] = country->iso_name[1];
 	} else {
 		rtlpriv->regd.alpha2[0] = '0';
 		rtlpriv->regd.alpha2[1] = '0';
diff -druN linux-2.6.39-libre/drivers/net/wireless/rtlwifi/regd.h linux-3.0-rc7-libre/drivers/net/wireless/rtlwifi/regd.h
--- linux-2.6.39-libre/drivers/net/wireless/rtlwifi/regd.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/rtlwifi/regd.h	2011-07-11 19:51:52.000000000 -0400
@@ -32,7 +32,7 @@
 
 struct country_code_to_enum_rd {
 	u16 countrycode;
-	const char *isoName;
+	const char *iso_name;
 };
 
 enum country_code_type_t {
diff -druN linux-2.6.39-libre/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c linux-3.0-rc7-libre/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c
--- linux-2.6.39-libre/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c	2011-07-11 19:51:52.000000000 -0400
@@ -28,10 +28,26 @@
  *****************************************************************************/
 
 #include "dm_common.h"
+#include "phy_common.h"
+#include "../pci.h"
+#include "../base.h"
 
 struct dig_t dm_digtable;
 static struct ps_t dm_pstable;
 
+#define BT_RSSI_STATE_NORMAL_POWER	BIT_OFFSET_LEN_MASK_32(0, 1)
+#define BT_RSSI_STATE_AMDPU_OFF		BIT_OFFSET_LEN_MASK_32(1, 1)
+#define BT_RSSI_STATE_SPECIAL_LOW	BIT_OFFSET_LEN_MASK_32(2, 1)
+#define BT_RSSI_STATE_BG_EDCA_LOW	BIT_OFFSET_LEN_MASK_32(3, 1)
+#define BT_RSSI_STATE_TXPOWER_LOW	BIT_OFFSET_LEN_MASK_32(4, 1)
+
+#define RTLPRIV			(struct rtl_priv *)
+#define GET_UNDECORATED_AVERAGE_RSSI(_priv)	\
+	((RTLPRIV(_priv))->mac80211.opmode == \
+			     NL80211_IFTYPE_ADHOC) ?	\
+	((RTLPRIV(_priv))->dm.entry_min_undecoratedsmoothed_pwdb) : \
+	((RTLPRIV(_priv))->dm.undecorated_smoothed_pwdb)
+
 static const u32 ofdmswing_table[OFDM_TABLE_SIZE] = {
 	0x7f8001fe,
 	0x788001e2,
@@ -304,7 +320,7 @@
 
 static void rtl92c_dm_initial_gain_multi_sta(struct ieee80211_hw *hw)
 {
-	static u8 binitialized; /* initialized to false */
+	static u8 initialized; /* initialized to false */
 	struct rtl_priv *rtlpriv = rtl_priv(hw);
 	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
 	long rssi_strength = rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb;
@@ -315,11 +331,11 @@
 
 	if ((multi_sta == false) || (dm_digtable.cursta_connectctate !=
 				     DIG_STA_DISCONNECT)) {
-		binitialized = false;
+		initialized = false;
 		dm_digtable.dig_ext_port_stage = DIG_EXT_PORT_STAGE_MAX;
 		return;
-	} else if (binitialized == false) {
-		binitialized = true;
+	} else if (initialized == false) {
+		initialized = true;
 		dm_digtable.dig_ext_port_stage = DIG_EXT_PORT_STAGE_0;
 		dm_digtable.cur_igvalue = 0x20;
 		rtl92c_dm_write_dig(hw);
@@ -461,10 +477,7 @@
 	if (mac->act_scanning == true)
 		return;
 
-	if ((mac->link_state > MAC80211_NOLINK) &&
-	    (mac->link_state < MAC80211_LINKED))
-		dm_digtable.cursta_connectctate = DIG_STA_BEFORE_CONNECT;
-	else if (mac->link_state >= MAC80211_LINKED)
+	if (mac->link_state >= MAC80211_LINKED)
 		dm_digtable.cursta_connectctate = DIG_STA_CONNECT;
 	else
 		dm_digtable.cursta_connectctate = DIG_STA_DISCONNECT;
@@ -562,23 +575,42 @@
 static void rtl92c_dm_check_edca_turbo(struct ieee80211_hw *hw)
 {
 	struct rtl_priv *rtlpriv = rtl_priv(hw);
+	struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
 	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+
 	static u64 last_txok_cnt;
 	static u64 last_rxok_cnt;
-	u64 cur_txok_cnt;
-	u64 cur_rxok_cnt;
+	static u32 last_bt_edca_ul;
+	static u32 last_bt_edca_dl;
+	u64 cur_txok_cnt = 0;
+	u64 cur_rxok_cnt = 0;
 	u32 edca_be_ul = 0x5ea42b;
 	u32 edca_be_dl = 0x5ea42b;
+	bool bt_change_edca = false;
 
-	if (mac->opmode == NL80211_IFTYPE_ADHOC)
-		goto dm_checkedcaturbo_exit;
+	if ((last_bt_edca_ul != rtlpcipriv->bt_coexist.bt_edca_ul) ||
+	    (last_bt_edca_dl != rtlpcipriv->bt_coexist.bt_edca_dl)) {
+		rtlpriv->dm.current_turbo_edca = false;
+		last_bt_edca_ul = rtlpcipriv->bt_coexist.bt_edca_ul;
+		last_bt_edca_dl = rtlpcipriv->bt_coexist.bt_edca_dl;
+	}
+
+	if (rtlpcipriv->bt_coexist.bt_edca_ul != 0) {
+		edca_be_ul = rtlpcipriv->bt_coexist.bt_edca_ul;
+		bt_change_edca = true;
+	}
+
+	if (rtlpcipriv->bt_coexist.bt_edca_dl != 0) {
+		edca_be_ul = rtlpcipriv->bt_coexist.bt_edca_dl;
+		bt_change_edca = true;
+	}
 
 	if (mac->link_state != MAC80211_LINKED) {
 		rtlpriv->dm.current_turbo_edca = false;
 		return;
 	}
 
-	if (!mac->ht_enable) {	/*FIX MERGE */
+	if ((!mac->ht_enable) && (!rtlpcipriv->bt_coexist.bt_coexistence)) {
 		if (!(edca_be_ul & 0xffff0000))
 			edca_be_ul |= 0x005e0000;
 
@@ -586,10 +618,12 @@
 			edca_be_dl |= 0x005e0000;
 	}
 
-	if ((!rtlpriv->dm.is_any_nonbepkts) &&
-	    (!rtlpriv->dm.disable_framebursting)) {
+	if ((bt_change_edca) || ((!rtlpriv->dm.is_any_nonbepkts) &&
+	     (!rtlpriv->dm.disable_framebursting))) {
+
 		cur_txok_cnt = rtlpriv->stats.txbytesunicast - last_txok_cnt;
 		cur_rxok_cnt = rtlpriv->stats.rxbytesunicast - last_rxok_cnt;
+
 		if (cur_rxok_cnt > 4 * cur_txok_cnt) {
 			if (!rtlpriv->dm.is_cur_rdlstate ||
 			    !rtlpriv->dm.current_turbo_edca) {
@@ -618,7 +652,6 @@
 		}
 	}
 
-dm_checkedcaturbo_exit:
 	rtlpriv->dm.is_any_nonbepkts = false;
 	last_txok_cnt = rtlpriv->stats.txbytesunicast;
 	last_rxok_cnt = rtlpriv->stats.rxbytesunicast;
@@ -633,14 +666,14 @@
 	struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
 	u8 thermalvalue, delta, delta_lck, delta_iqk;
 	long ele_a, ele_d, temp_cck, val_x, value32;
-	long val_y, ele_c;
-	u8 ofdm_index[2], cck_index, ofdm_index_old[2], cck_index_old;
+	long val_y, ele_c = 0;
+	u8 ofdm_index[2], cck_index = 0, ofdm_index_old[2], cck_index_old = 0;
 	int i;
 	bool is2t = IS_92C_SERIAL(rtlhal->version);
 	u8 txpwr_level[2] = {0, 0};
 	u8 ofdm_min_index = 6, rf;
 
-	rtlpriv->dm.txpower_trackingInit = true;
+	rtlpriv->dm.txpower_trackinginit = true;
 	RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
 		 ("rtl92c_dm_txpower_tracking_callback_thermalmeter\n"));
 
@@ -683,7 +716,6 @@
 			for (i = 0; i < OFDM_TABLE_LENGTH; i++) {
 				if (ele_d == (ofdmswing_table[i] &
 				    MASKOFDM_D)) {
-					ofdm_index_old[1] = (u8) i;
 
 					RT_TRACE(rtlpriv, COMP_POWER_TRACKING,
 					   DBG_LOUD,
@@ -1062,7 +1094,7 @@
 	struct rtl_priv *rtlpriv = rtl_priv(hw);
 
 	rtlpriv->dm.txpower_tracking = true;
-	rtlpriv->dm.txpower_trackingInit = false;
+	rtlpriv->dm.txpower_trackinginit = false;
 
 	RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
 		 ("pMgntInfo->txpower_tracking = %d\n",
@@ -1132,6 +1164,7 @@
 	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
 	struct rate_adaptive *p_ra = &(rtlpriv->ra);
 	u32 low_rssithresh_for_ra, high_rssithresh_for_ra;
+	struct ieee80211_sta *sta = NULL;
 
 	if (is_hal_stop(rtlhal)) {
 		RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD,
@@ -1145,8 +1178,8 @@
 		return;
 	}
 
-	if (mac->link_state == MAC80211_LINKED) {
-
+	if (mac->link_state == MAC80211_LINKED &&
+	    mac->opmode == NL80211_IFTYPE_STATION) {
 		switch (p_ra->pre_ratr_state) {
 		case DM_RATR_STA_HIGH:
 			high_rssithresh_for_ra = 50;
@@ -1185,10 +1218,13 @@
 				 ("PreState = %d, CurState = %d\n",
 				  p_ra->pre_ratr_state, p_ra->ratr_state));
 
-			rtlpriv->cfg->ops->update_rate_mask(hw,
+			rcu_read_lock();
+			sta = ieee80211_find_sta(mac->vif, mac->bssid);
+			rtlpriv->cfg->ops->update_rate_tbl(hw, sta,
 					p_ra->ratr_state);
 
 			p_ra->pre_ratr_state = p_ra->ratr_state;
+			rcu_read_unlock();
 		}
 	}
 }
@@ -1202,51 +1238,6 @@
 	dm_pstable.rssi_val_min = 0;
 }
 
-static void rtl92c_dm_1r_cca(struct ieee80211_hw *hw)
-{
-	struct rtl_priv *rtlpriv = rtl_priv(hw);
-	struct rtl_phy *rtlphy = &(rtlpriv->phy);
-
-	if (dm_pstable.rssi_val_min != 0) {
-		if (dm_pstable.pre_ccastate == CCA_2R) {
-			if (dm_pstable.rssi_val_min >= 35)
-				dm_pstable.cur_ccasate = CCA_1R;
-			else
-				dm_pstable.cur_ccasate = CCA_2R;
-		} else {
-			if (dm_pstable.rssi_val_min <= 30)
-				dm_pstable.cur_ccasate = CCA_2R;
-			else
-				dm_pstable.cur_ccasate = CCA_1R;
-		}
-	} else {
-		dm_pstable.cur_ccasate = CCA_MAX;
-	}
-
-	if (dm_pstable.pre_ccastate != dm_pstable.cur_ccasate) {
-		if (dm_pstable.cur_ccasate == CCA_1R) {
-			if (get_rf_type(rtlphy) == RF_2T2R) {
-				rtl_set_bbreg(hw, ROFDM0_TRXPATHENABLE,
-					      MASKBYTE0, 0x13);
-				rtl_set_bbreg(hw, 0xe70, MASKBYTE3, 0x20);
-			} else {
-				rtl_set_bbreg(hw, ROFDM0_TRXPATHENABLE,
-					      MASKBYTE0, 0x23);
-				rtl_set_bbreg(hw, 0xe70, 0x7fc00000, 0x10c);
-			}
-		} else {
-			rtl_set_bbreg(hw, ROFDM0_TRXPATHENABLE, MASKBYTE0,
-				      0x33);
-			rtl_set_bbreg(hw, 0xe70, MASKBYTE3, 0x63);
-		}
-		dm_pstable.pre_ccastate = dm_pstable.cur_ccasate;
-	}
-
-	RT_TRACE(rtlpriv, DBG_LOUD, DBG_LOUD, ("CCAStage = %s\n",
-					       (dm_pstable.cur_ccasate ==
-						0) ? "1RCCA" : "2RCCA"));
-}
-
 void rtl92c_dm_rf_saving(struct ieee80211_hw *hw, u8 bforce_in_normal)
 {
 	static u8 initialize;
@@ -1352,7 +1343,9 @@
 	}
 
 	if (IS_92C_SERIAL(rtlhal->version))
-		rtl92c_dm_1r_cca(hw);
+		;/* rtl92c_dm_1r_cca(hw); */
+	else
+		rtl92c_dm_rf_saving(hw, false);
 }
 
 void rtl92c_dm_init(struct ieee80211_hw *hw)
@@ -1369,6 +1362,84 @@
 }
 EXPORT_SYMBOL(rtl92c_dm_init);
 
+void rtl92c_dm_dynamic_txpower(struct ieee80211_hw *hw)
+{
+	struct rtl_priv *rtlpriv = rtl_priv(hw);
+	struct rtl_phy *rtlphy = &(rtlpriv->phy);
+	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+	long undecorated_smoothed_pwdb;
+
+	if (!rtlpriv->dm.dynamic_txpower_enable)
+		return;
+
+	if (rtlpriv->dm.dm_flag & HAL_DM_HIPWR_DISABLE) {
+		rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL;
+		return;
+	}
+
+	if ((mac->link_state < MAC80211_LINKED) &&
+	    (rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb == 0)) {
+		RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE,
+			 ("Not connected to any\n"));
+
+		rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL;
+
+		rtlpriv->dm.last_dtp_lvl = TXHIGHPWRLEVEL_NORMAL;
+		return;
+	}
+
+	if (mac->link_state >= MAC80211_LINKED) {
+		if (mac->opmode == NL80211_IFTYPE_ADHOC) {
+			undecorated_smoothed_pwdb =
+			    rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb;
+			RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
+				 ("AP Client PWDB = 0x%lx\n",
+				  undecorated_smoothed_pwdb));
+		} else {
+			undecorated_smoothed_pwdb =
+			    rtlpriv->dm.undecorated_smoothed_pwdb;
+			RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
+				 ("STA Default Port PWDB = 0x%lx\n",
+				  undecorated_smoothed_pwdb));
+		}
+	} else {
+		undecorated_smoothed_pwdb =
+		    rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb;
+
+		RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
+			 ("AP Ext Port PWDB = 0x%lx\n",
+			  undecorated_smoothed_pwdb));
+	}
+
+	if (undecorated_smoothed_pwdb >= TX_POWER_NEAR_FIELD_THRESH_LVL2) {
+		rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_LEVEL1;
+		RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
+			 ("TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x0)\n"));
+	} else if ((undecorated_smoothed_pwdb <
+		    (TX_POWER_NEAR_FIELD_THRESH_LVL2 - 3)) &&
+		   (undecorated_smoothed_pwdb >=
+		    TX_POWER_NEAR_FIELD_THRESH_LVL1)) {
+
+		rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_LEVEL1;
+		RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
+			 ("TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x10)\n"));
+	} else if (undecorated_smoothed_pwdb <
+		   (TX_POWER_NEAR_FIELD_THRESH_LVL1 - 5)) {
+		rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL;
+		RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
+			 ("TXHIGHPWRLEVEL_NORMAL\n"));
+	}
+
+	if ((rtlpriv->dm.dynamic_txhighpower_lvl != rtlpriv->dm.last_dtp_lvl)) {
+		RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
+			 ("PHY_SetTxPowerLevel8192S() Channel = %d\n",
+			  rtlphy->current_channel));
+		rtl92c_phy_set_txpower_level(hw, rtlphy->current_channel);
+	}
+
+	rtlpriv->dm.last_dtp_lvl = rtlpriv->dm.dynamic_txhighpower_lvl;
+}
+
 void rtl92c_dm_watchdog(struct ieee80211_hw *hw)
 {
 	struct rtl_priv *rtlpriv = rtl_priv(hw);
@@ -1388,11 +1459,321 @@
 		rtl92c_dm_dig(hw);
 		rtl92c_dm_false_alarm_counter_statistics(hw);
 		rtl92c_dm_dynamic_bb_powersaving(hw);
-		rtlpriv->cfg->ops->dm_dynamic_txpower(hw);
+		rtl92c_dm_dynamic_txpower(hw);
 		rtl92c_dm_check_txpower_tracking(hw);
 		rtl92c_dm_refresh_rate_adaptive_mask(hw);
+		rtl92c_dm_bt_coexist(hw);
 		rtl92c_dm_check_edca_turbo(hw);
-
 	}
 }
 EXPORT_SYMBOL(rtl92c_dm_watchdog);
+
+u8 rtl92c_bt_rssi_state_change(struct ieee80211_hw *hw)
+{
+	struct rtl_priv *rtlpriv = rtl_priv(hw);
+	struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
+	long undecorated_smoothed_pwdb;
+	u8 curr_bt_rssi_state = 0x00;
+
+	if (rtlpriv->mac80211.link_state == MAC80211_LINKED) {
+		undecorated_smoothed_pwdb =
+				 GET_UNDECORATED_AVERAGE_RSSI(rtlpriv);
+	} else {
+		if (rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb == 0)
+			undecorated_smoothed_pwdb = 100;
+		else
+			undecorated_smoothed_pwdb =
+				rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb;
+	}
+
+	/* Check RSSI to determine HighPower/NormalPower state for
+	 * BT coexistence. */
+	if (undecorated_smoothed_pwdb >= 67)
+		curr_bt_rssi_state &= (~BT_RSSI_STATE_NORMAL_POWER);
+	else if (undecorated_smoothed_pwdb < 62)
+		curr_bt_rssi_state |= BT_RSSI_STATE_NORMAL_POWER;
+
+	/* Check RSSI to determine AMPDU setting for BT coexistence. */
+	if (undecorated_smoothed_pwdb >= 40)
+		curr_bt_rssi_state &= (~BT_RSSI_STATE_AMDPU_OFF);
+	else if (undecorated_smoothed_pwdb <= 32)
+		curr_bt_rssi_state |= BT_RSSI_STATE_AMDPU_OFF;
+
+	/* Marked RSSI state. It will be used to determine BT coexistence
+	 * setting later. */
+	if (undecorated_smoothed_pwdb < 35)
+		curr_bt_rssi_state |=  BT_RSSI_STATE_SPECIAL_LOW;
+	else
+		curr_bt_rssi_state &= (~BT_RSSI_STATE_SPECIAL_LOW);
+
+	/* Set Tx Power according to BT status. */
+	if (undecorated_smoothed_pwdb >= 30)
+		curr_bt_rssi_state |=  BT_RSSI_STATE_TXPOWER_LOW;
+	else if (undecorated_smoothed_pwdb < 25)
+		curr_bt_rssi_state &= (~BT_RSSI_STATE_TXPOWER_LOW);
+
+	/* Check BT state related to BT_Idle in B/G mode. */
+	if (undecorated_smoothed_pwdb < 15)
+		curr_bt_rssi_state |=  BT_RSSI_STATE_BG_EDCA_LOW;
+	else
+		curr_bt_rssi_state &= (~BT_RSSI_STATE_BG_EDCA_LOW);
+
+	if (curr_bt_rssi_state != rtlpcipriv->bt_coexist.bt_rssi_state) {
+		rtlpcipriv->bt_coexist.bt_rssi_state = curr_bt_rssi_state;
+		return true;
+	} else {
+		return false;
+	}
+}
+EXPORT_SYMBOL(rtl92c_bt_rssi_state_change);
+
+static bool rtl92c_bt_state_change(struct ieee80211_hw *hw)
+{
+	struct rtl_priv *rtlpriv = rtl_priv(hw);
+	struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
+
+	u32 polling, ratio_tx, ratio_pri;
+	u32 bt_tx, bt_pri;
+	u8 bt_state;
+	u8 cur_service_type;
+
+	if (rtlpriv->mac80211.link_state < MAC80211_LINKED)
+		return false;
+
+	bt_state = rtl_read_byte(rtlpriv, 0x4fd);
+	bt_tx = rtl_read_dword(rtlpriv, 0x488);
+	bt_tx = bt_tx & 0x00ffffff;
+	bt_pri = rtl_read_dword(rtlpriv, 0x48c);
+	bt_pri = bt_pri & 0x00ffffff;
+	polling = rtl_read_dword(rtlpriv, 0x490);
+
+	if (bt_tx == 0xffffffff && bt_pri == 0xffffffff &&
+	    polling == 0xffffffff && bt_state == 0xff)
+		return false;
+
+	bt_state &= BIT_OFFSET_LEN_MASK_32(0, 1);
+	if (bt_state != rtlpcipriv->bt_coexist.bt_cur_state) {
+		rtlpcipriv->bt_coexist.bt_cur_state = bt_state;
+
+		if (rtlpcipriv->bt_coexist.reg_bt_sco == 3) {
+			rtlpcipriv->bt_coexist.bt_service = BT_IDLE;
+
+			bt_state = bt_state |
+			  ((rtlpcipriv->bt_coexist.bt_ant_isolation == 1) ?
+			  0 : BIT_OFFSET_LEN_MASK_32(1, 1)) |
+			  BIT_OFFSET_LEN_MASK_32(2, 1);
+			rtl_write_byte(rtlpriv, 0x4fd, bt_state);
+		}
+		return true;
+	}
+
+	ratio_tx = bt_tx * 1000 / polling;
+	ratio_pri = bt_pri * 1000 / polling;
+	rtlpcipriv->bt_coexist.ratio_tx = ratio_tx;
+	rtlpcipriv->bt_coexist.ratio_pri = ratio_pri;
+
+	if (bt_state && rtlpcipriv->bt_coexist.reg_bt_sco == 3) {
+
+		if ((ratio_tx < 30)  && (ratio_pri < 30))
+			cur_service_type = BT_IDLE;
+		else if ((ratio_pri > 110) && (ratio_pri < 250))
+			cur_service_type = BT_SCO;
+		else if ((ratio_tx >= 200) && (ratio_pri >= 200))
+			cur_service_type = BT_BUSY;
+		else if ((ratio_tx >= 350) && (ratio_tx < 500))
+			cur_service_type = BT_OTHERBUSY;
+		else if (ratio_tx >= 500)
+			cur_service_type = BT_PAN;
+		else
+			cur_service_type = BT_OTHER_ACTION;
+
+		if (cur_service_type != rtlpcipriv->bt_coexist.bt_service) {
+			rtlpcipriv->bt_coexist.bt_service = cur_service_type;
+			bt_state = bt_state |
+			   ((rtlpcipriv->bt_coexist.bt_ant_isolation == 1) ?
+			   0 : BIT_OFFSET_LEN_MASK_32(1, 1)) |
+			   ((rtlpcipriv->bt_coexist.bt_service != BT_IDLE) ?
+			   0 : BIT_OFFSET_LEN_MASK_32(2, 1));
+
+			/* Add interrupt migration when bt is not ini
+			 * idle state (no traffic). */
+			if (rtlpcipriv->bt_coexist.bt_service != BT_IDLE) {
+				rtl_write_word(rtlpriv, 0x504, 0x0ccc);
+				rtl_write_byte(rtlpriv, 0x506, 0x54);
+				rtl_write_byte(rtlpriv, 0x507, 0x54);
+			} else {
+				rtl_write_byte(rtlpriv, 0x506, 0x00);
+				rtl_write_byte(rtlpriv, 0x507, 0x00);
+			}
+
+			rtl_write_byte(rtlpriv, 0x4fd, bt_state);
+			return true;
+		}
+	}
+
+	return false;
+
+}
+
+static bool rtl92c_bt_wifi_connect_change(struct ieee80211_hw *hw)
+{
+	struct rtl_priv *rtlpriv = rtl_priv(hw);
+	static bool media_connect;
+
+	if (rtlpriv->mac80211.link_state < MAC80211_LINKED) {
+		media_connect = false;
+	} else {
+		if (!media_connect) {
+			media_connect = true;
+			return true;
+		}
+		media_connect = true;
+	}
+
+	return false;
+}
+
+static void rtl92c_bt_set_normal(struct ieee80211_hw *hw)
+{
+	struct rtl_priv *rtlpriv = rtl_priv(hw);
+	struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
+
+
+	if (rtlpcipriv->bt_coexist.bt_service == BT_OTHERBUSY) {
+		rtlpcipriv->bt_coexist.bt_edca_ul = 0x5ea72b;
+		rtlpcipriv->bt_coexist.bt_edca_dl = 0x5ea72b;
+	} else if (rtlpcipriv->bt_coexist.bt_service == BT_BUSY) {
+		rtlpcipriv->bt_coexist.bt_edca_ul = 0x5eb82f;
+		rtlpcipriv->bt_coexist.bt_edca_dl = 0x5eb82f;
+	} else if (rtlpcipriv->bt_coexist.bt_service == BT_SCO) {
+		if (rtlpcipriv->bt_coexist.ratio_tx > 160) {
+			rtlpcipriv->bt_coexist.bt_edca_ul = 0x5ea72f;
+			rtlpcipriv->bt_coexist.bt_edca_dl = 0x5ea72f;
+		} else {
+			rtlpcipriv->bt_coexist.bt_edca_ul = 0x5ea32b;
+			rtlpcipriv->bt_coexist.bt_edca_dl = 0x5ea42b;
+		}
+	} else {
+		rtlpcipriv->bt_coexist.bt_edca_ul = 0;
+		rtlpcipriv->bt_coexist.bt_edca_dl = 0;
+	}
+
+	if ((rtlpcipriv->bt_coexist.bt_service != BT_IDLE) &&
+	     (rtlpriv->mac80211.mode == WIRELESS_MODE_G ||
+	     (rtlpriv->mac80211.mode == (WIRELESS_MODE_G | WIRELESS_MODE_B))) &&
+	     (rtlpcipriv->bt_coexist.bt_rssi_state &
+	     BT_RSSI_STATE_BG_EDCA_LOW)) {
+		rtlpcipriv->bt_coexist.bt_edca_ul = 0x5eb82b;
+		rtlpcipriv->bt_coexist.bt_edca_dl = 0x5eb82b;
+	}
+}
+
+static void rtl92c_bt_ant_isolation(struct ieee80211_hw *hw)
+{
+	struct rtl_priv *rtlpriv = rtl_priv(hw);
+	struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
+
+
+	/* Only enable HW BT coexist when BT in "Busy" state. */
+	if (rtlpriv->mac80211.vendor == PEER_CISCO &&
+	    rtlpcipriv->bt_coexist.bt_service == BT_OTHER_ACTION) {
+		rtl_write_byte(rtlpriv, REG_GPIO_MUXCFG, 0xa0);
+	} else {
+		if ((rtlpcipriv->bt_coexist.bt_service == BT_BUSY) &&
+		    (rtlpcipriv->bt_coexist.bt_rssi_state &
+		     BT_RSSI_STATE_NORMAL_POWER)) {
+			rtl_write_byte(rtlpriv, REG_GPIO_MUXCFG, 0xa0);
+		} else if ((rtlpcipriv->bt_coexist.bt_service ==
+			    BT_OTHER_ACTION) && (rtlpriv->mac80211.mode <
+			    WIRELESS_MODE_N_24G) &&
+			    (rtlpcipriv->bt_coexist.bt_rssi_state &
+			    BT_RSSI_STATE_SPECIAL_LOW)) {
+			rtl_write_byte(rtlpriv, REG_GPIO_MUXCFG, 0xa0);
+		} else if (rtlpcipriv->bt_coexist.bt_service == BT_PAN) {
+			rtl_write_byte(rtlpriv, REG_GPIO_MUXCFG, 0x00);
+		} else {
+			rtl_write_byte(rtlpriv, REG_GPIO_MUXCFG, 0x00);
+		}
+	}
+
+	if (rtlpcipriv->bt_coexist.bt_service == BT_PAN)
+		rtl_write_dword(rtlpriv, REG_GPIO_PIN_CTRL, 0x10100);
+	else
+		rtl_write_dword(rtlpriv, REG_GPIO_PIN_CTRL, 0x0);
+
+	if (rtlpcipriv->bt_coexist.bt_rssi_state &
+	    BT_RSSI_STATE_NORMAL_POWER) {
+		rtl92c_bt_set_normal(hw);
+	} else {
+		rtlpcipriv->bt_coexist.bt_edca_ul = 0;
+		rtlpcipriv->bt_coexist.bt_edca_dl = 0;
+	}
+
+	if (rtlpcipriv->bt_coexist.bt_service != BT_IDLE) {
+		rtlpriv->cfg->ops->set_rfreg(hw,
+				 RF90_PATH_A,
+				 0x1e,
+				 0xf0, 0xf);
+	} else {
+		rtlpriv->cfg->ops->set_rfreg(hw,
+		     RF90_PATH_A, 0x1e, 0xf0,
+		     rtlpcipriv->bt_coexist.bt_rfreg_origin_1e);
+	}
+
+	if (!rtlpriv->dm.dynamic_txpower_enable) {
+		if (rtlpcipriv->bt_coexist.bt_service != BT_IDLE) {
+			if (rtlpcipriv->bt_coexist.bt_rssi_state &
+				BT_RSSI_STATE_TXPOWER_LOW) {
+				rtlpriv->dm.dynamic_txhighpower_lvl =
+							TXHIGHPWRLEVEL_BT2;
+			} else {
+				rtlpriv->dm.dynamic_txhighpower_lvl =
+					TXHIGHPWRLEVEL_BT1;
+			}
+		} else {
+			rtlpriv->dm.dynamic_txhighpower_lvl =
+				TXHIGHPWRLEVEL_NORMAL;
+		}
+		rtl92c_phy_set_txpower_level(hw,
+			rtlpriv->phy.current_channel);
+	}
+}
+
+static void rtl92c_check_bt_change(struct ieee80211_hw *hw)
+{
+	struct rtl_priv *rtlpriv = rtl_priv(hw);
+	struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
+
+	if (rtlpcipriv->bt_coexist.bt_cur_state) {
+		if (rtlpcipriv->bt_coexist.bt_ant_isolation)
+			rtl92c_bt_ant_isolation(hw);
+	} else {
+		rtl_write_byte(rtlpriv, REG_GPIO_MUXCFG, 0x00);
+		rtlpriv->cfg->ops->set_rfreg(hw, RF90_PATH_A, 0x1e, 0xf0,
+				rtlpcipriv->bt_coexist.bt_rfreg_origin_1e);
+
+		rtlpcipriv->bt_coexist.bt_edca_ul = 0;
+		rtlpcipriv->bt_coexist.bt_edca_dl = 0;
+	}
+}
+
+void rtl92c_dm_bt_coexist(struct ieee80211_hw *hw)
+{
+	struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
+
+	bool wifi_connect_change;
+	bool bt_state_change;
+	bool rssi_state_change;
+
+	if ((rtlpcipriv->bt_coexist.bt_coexistence) &&
+	     (rtlpcipriv->bt_coexist.bt_coexist_type == BT_CSR_BC4)) {
+
+		wifi_connect_change = rtl92c_bt_wifi_connect_change(hw);
+		bt_state_change = rtl92c_bt_state_change(hw);
+		rssi_state_change = rtl92c_bt_rssi_state_change(hw);
+
+		if (wifi_connect_change || bt_state_change || rssi_state_change)
+			rtl92c_check_bt_change(hw);
+	}
+}
+EXPORT_SYMBOL(rtl92c_dm_bt_coexist);
diff -druN linux-2.6.39-libre/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.h linux-3.0-rc7-libre/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.h
--- linux-2.6.39-libre/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.h	2011-07-11 19:51:52.000000000 -0400
@@ -200,5 +200,7 @@
 void rtl92c_phy_ap_calibrate(struct ieee80211_hw *hw, char delta);
 void rtl92c_phy_lc_calibrate(struct ieee80211_hw *hw);
 void rtl92c_phy_iq_calibrate(struct ieee80211_hw *hw, bool recovery);
+void rtl92c_dm_dynamic_txpower(struct ieee80211_hw *hw);
+void rtl92c_dm_bt_coexist(struct ieee80211_hw *hw);
 
 #endif
diff -druN linux-2.6.39-libre/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c linux-3.0-rc7-libre/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c
--- linux-2.6.39-libre/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c	2011-05-19 02:15:56.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c	2011-07-11 19:51:52.000000000 -0400
@@ -171,7 +171,6 @@
 static int _rtl92c_fw_free_to_go(struct ieee80211_hw *hw)
 {
 	struct rtl_priv *rtlpriv = rtl_priv(hw);
-	int err = -EIO;
 	u32 counter = 0;
 	u32 value32;
 
@@ -184,7 +183,7 @@
 		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
 			 ("chksum report faill ! REG_MCUFWDL:0x%08x .\n",
 			  value32));
-		goto exit;
+		return -EIO;
 	}
 
 	RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE,
@@ -204,8 +203,7 @@
 				 ("Polling FW ready success!!"
 				 " REG_MCUFWDL:0x%08x .\n",
 				 value32));
-			err = 0;
-			goto exit;
+			return 0;
 		}
 
 		mdelay(FW_8192C_POLLING_DELAY);
@@ -214,9 +212,7 @@
 
 	RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
 		 ("Polling FW ready fail!! REG_MCUFWDL:0x%08x .\n", value32));
-
-exit:
-	return err;
+	return -EIO;
 }
 
 int rtl92c_download_fw(struct ieee80211_hw *hw)
@@ -226,32 +222,16 @@
 	struct rtl92c_firmware_header *pfwheader;
 	u8 *pfwdata;
 	u32 fwsize;
-	int err;
 	enum version_8192c version = rtlhal->version;
-	const struct firmware *firmware;
 
-	printk(KERN_INFO "rtl8192cu: Loading firmware file %s\n",
+	printk(KERN_INFO "rtl8192c: Loading firmware file %s\n",
 	       rtlpriv->cfg->fw_name);
-	err = reject_firmware(&firmware, rtlpriv->cfg->fw_name,
-			       rtlpriv->io.dev);
-	if (err) {
-		printk(KERN_ERR "rtl8192cu: Firmware loading failed\n");
-		return 1;
-	}
-
-	if (firmware->size > 0x4000) {
-		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-			 ("Firmware is too big!\n"));
-		release_firmware(firmware);
+	if (!rtlhal->pfirmware)
 		return 1;
-	}
-
-	memcpy(rtlhal->pfirmware, firmware->data, firmware->size);
-	fwsize = firmware->size;
-	release_firmware(firmware);
 
 	pfwheader = (struct rtl92c_firmware_header *)rtlhal->pfirmware;
 	pfwdata = (u8 *) rtlhal->pfirmware;
+	fwsize = rtlhal->fwsize;
 
 	if (IS_FW_HEADER_EXIST(pfwheader)) {
 		RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG,
@@ -267,8 +247,7 @@
 	_rtl92c_write_fw(hw, version, pfwdata, fwsize);
 	_rtl92c_enable_fw_download(hw, false);
 
-	err = _rtl92c_fw_free_to_go(hw);
-	if (err) {
+	if (_rtl92c_fw_free_to_go(hw)) {
 		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
 			 ("Firmware is not ready to run!\n"));
 	} else {
@@ -300,10 +279,9 @@
 	struct rtl_priv *rtlpriv = rtl_priv(hw);
 	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
 	u8 boxnum;
-	u16 box_reg, box_extreg;
+	u16 box_reg = 0, box_extreg = 0;
 	u8 u1b_tmp;
 	bool isfw_read = false;
-	u8 buf_index = 0;
 	bool bwrite_sucess = false;
 	u8 wait_h2c_limmit = 100;
 	u8 wait_writeh2c_limmit = 100;
@@ -414,7 +392,7 @@
 		case 1:
 			boxcontent[0] &= ~(BIT(7));
 			memcpy((u8 *) (boxcontent) + 1,
-			       p_cmdbuffer + buf_index, 1);
+			       p_cmdbuffer, 1);
 
 			for (idx = 0; idx < 4; idx++) {
 				rtl_write_byte(rtlpriv, box_reg + idx,
@@ -424,7 +402,7 @@
 		case 2:
 			boxcontent[0] &= ~(BIT(7));
 			memcpy((u8 *) (boxcontent) + 1,
-			       p_cmdbuffer + buf_index, 2);
+			       p_cmdbuffer, 2);
 
 			for (idx = 0; idx < 4; idx++) {
 				rtl_write_byte(rtlpriv, box_reg + idx,
@@ -434,7 +412,7 @@
 		case 3:
 			boxcontent[0] &= ~(BIT(7));
 			memcpy((u8 *) (boxcontent) + 1,
-			       p_cmdbuffer + buf_index, 3);
+			       p_cmdbuffer, 3);
 
 			for (idx = 0; idx < 4; idx++) {
 				rtl_write_byte(rtlpriv, box_reg + idx,
@@ -444,9 +422,9 @@
 		case 4:
 			boxcontent[0] |= (BIT(7));
 			memcpy((u8 *) (boxextcontent),
-			       p_cmdbuffer + buf_index, 2);
+			       p_cmdbuffer, 2);
 			memcpy((u8 *) (boxcontent) + 1,
-			       p_cmdbuffer + buf_index + 2, 2);
+			       p_cmdbuffer + 2, 2);
 
 			for (idx = 0; idx < 2; idx++) {
 				rtl_write_byte(rtlpriv, box_extreg + idx,
@@ -461,9 +439,9 @@
 		case 5:
 			boxcontent[0] |= (BIT(7));
 			memcpy((u8 *) (boxextcontent),
-			       p_cmdbuffer + buf_index, 2);
+			       p_cmdbuffer, 2);
 			memcpy((u8 *) (boxcontent) + 1,
-			       p_cmdbuffer + buf_index + 2, 3);
+			       p_cmdbuffer + 2, 3);
 
 			for (idx = 0; idx < 2; idx++) {
 				rtl_write_byte(rtlpriv, box_extreg + idx,
@@ -561,6 +539,39 @@
 }
 EXPORT_SYMBOL(rtl92c_set_fw_pwrmode_cmd);
 
+static bool _rtl92c_cmd_send_packet(struct ieee80211_hw *hw,
+				struct sk_buff *skb)
+{
+	struct rtl_priv *rtlpriv = rtl_priv(hw);
+	struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+	struct rtl8192_tx_ring *ring;
+	struct rtl_tx_desc *pdesc;
+	u8 own;
+	unsigned long flags;
+	struct sk_buff *pskb = NULL;
+
+	ring = &rtlpci->tx_ring[BEACON_QUEUE];
+
+	pskb = __skb_dequeue(&ring->queue);
+	if (pskb)
+		kfree_skb(pskb);
+
+	spin_lock_irqsave(&rtlpriv->locks.irq_th_lock, flags);
+
+	pdesc = &ring->desc[0];
+	own = (u8) rtlpriv->cfg->ops->get_desc((u8 *) pdesc, true, HW_DESC_OWN);
+
+	rtlpriv->cfg->ops->fill_tx_cmddesc(hw, (u8 *) pdesc, 1, 1, skb);
+
+	__skb_queue_tail(&ring->queue, skb);
+
+	spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock, flags);
+
+	rtlpriv->cfg->ops->tx_polling(hw, BEACON_QUEUE);
+
+	return true;
+}
+
 #define BEACON_PG		0 /*->1*/
 #define PSPOLL_PG		2
 #define NULL_PG			3
@@ -678,7 +689,7 @@
 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 };
 
-void rtl92c_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool b_dl_finished)
+void rtl92c_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool dl_finished)
 {
 	struct rtl_priv *rtlpriv = rtl_priv(hw);
 	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
@@ -687,12 +698,12 @@
 	u32 totalpacketlen;
 	bool rtstatus;
 	u8 u1RsvdPageLoc[3] = {0};
-	bool b_dlok = false;
+	bool dlok = false;
 
 	u8 *beacon;
-	u8 *p_pspoll;
+	u8 *pspoll;
 	u8 *nullfunc;
-	u8 *p_probersp;
+	u8 *probersp;
 	/*---------------------------------------------------------
 				(1) beacon
 	---------------------------------------------------------*/
@@ -703,10 +714,10 @@
 	/*-------------------------------------------------------
 				(2) ps-poll
 	--------------------------------------------------------*/
-	p_pspoll = &reserved_page_packet[PSPOLL_PG * 128];
-	SET_80211_PS_POLL_AID(p_pspoll, (mac->assoc_id | 0xc000));
-	SET_80211_PS_POLL_BSSID(p_pspoll, mac->bssid);
-	SET_80211_PS_POLL_TA(p_pspoll, mac->mac_addr);
+	pspoll = &reserved_page_packet[PSPOLL_PG * 128];
+	SET_80211_PS_POLL_AID(pspoll, (mac->assoc_id | 0xc000));
+	SET_80211_PS_POLL_BSSID(pspoll, mac->bssid);
+	SET_80211_PS_POLL_TA(pspoll, mac->mac_addr);
 
 	SET_H2CCMD_RSVDPAGE_LOC_PSPOLL(u1RsvdPageLoc, PSPOLL_PG);
 
@@ -723,10 +734,10 @@
 	/*---------------------------------------------------------
 				(4) probe response
 	----------------------------------------------------------*/
-	p_probersp = &reserved_page_packet[PROBERSP_PG * 128];
-	SET_80211_HDR_ADDRESS1(p_probersp, mac->bssid);
-	SET_80211_HDR_ADDRESS2(p_probersp, mac->mac_addr);
-	SET_80211_HDR_ADDRESS3(p_probersp, mac->bssid);
+	probersp = &reserved_page_packet[PROBERSP_PG * 128];
+	SET_80211_HDR_ADDRESS1(probersp, mac->bssid);
+	SET_80211_HDR_ADDRESS2(probersp, mac->mac_addr);
+	SET_80211_HDR_ADDRESS3(probersp, mac->bssid);
 
 	SET_H2CCMD_RSVDPAGE_LOC_PROBE_RSP(u1RsvdPageLoc, PROBERSP_PG);
 
@@ -744,12 +755,12 @@
 	memcpy((u8 *) skb_put(skb, totalpacketlen),
 	       &reserved_page_packet, totalpacketlen);
 
-	rtstatus = rtlpriv->cfg->ops->cmd_send_packet(hw, skb);
+	rtstatus = _rtl92c_cmd_send_packet(hw, skb);
 
 	if (rtstatus)
-		b_dlok = true;
+		dlok = true;
 
-	if (b_dlok) {
+	if (dlok) {
 		RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
 			 ("Set RSVD page location to Fw.\n"));
 		RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG,
diff -druN linux-2.6.39-libre/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.h linux-3.0-rc7-libre/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.h
--- linux-2.6.39-libre/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.h	2011-07-11 19:51:52.000000000 -0400
@@ -27,8 +27,8 @@
  *
  *****************************************************************************/
 
-#ifndef __RTL92C__FW__H__
-#define __RTL92C__FW__H__
+#ifndef __RTL92C__FW__COMMON__H__
+#define __RTL92C__FW__COMMON__H__
 
 #define FW_8192C_SIZE				0x3000
 #define FW_8192C_START_ADDRESS			0x1000
diff -druN linux-2.6.39-libre/drivers/net/wireless/rtlwifi/rtl8192c/phy_common.c linux-3.0-rc7-libre/drivers/net/wireless/rtlwifi/rtl8192c/phy_common.c
--- linux-2.6.39-libre/drivers/net/wireless/rtlwifi/rtl8192c/phy_common.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/rtlwifi/rtl8192c/phy_common.c	2011-07-11 19:51:52.000000000 -0400
@@ -78,27 +78,29 @@
 	RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), bitmask(%#x),"
 					       " data(%#x)\n", regaddr, bitmask,
 					       data));
+
 }
 EXPORT_SYMBOL(rtl92c_phy_set_bb_reg);
 
 u32 _rtl92c_phy_fw_rf_serial_read(struct ieee80211_hw *hw,
-					 enum radio_path rfpath, u32 offset)
+				  enum radio_path rfpath, u32 offset)
 {
 	RT_ASSERT(false, ("deprecated!\n"));
 	return 0;
+
 }
 EXPORT_SYMBOL(_rtl92c_phy_fw_rf_serial_read);
 
 void _rtl92c_phy_fw_rf_serial_write(struct ieee80211_hw *hw,
-					   enum radio_path rfpath, u32 offset,
-					   u32 data)
+				    enum radio_path rfpath, u32 offset,
+				    u32 data)
 {
 	RT_ASSERT(false, ("deprecated!\n"));
 }
 EXPORT_SYMBOL(_rtl92c_phy_fw_rf_serial_write);
 
 u32 _rtl92c_phy_rf_serial_read(struct ieee80211_hw *hw,
-				      enum radio_path rfpath, u32 offset)
+			       enum radio_path rfpath, u32 offset)
 {
 	struct rtl_priv *rtlpriv = rtl_priv(hw);
 	struct rtl_phy *rtlphy = &(rtlpriv->phy);
@@ -149,8 +151,8 @@
 EXPORT_SYMBOL(_rtl92c_phy_rf_serial_read);
 
 void _rtl92c_phy_rf_serial_write(struct ieee80211_hw *hw,
-					enum radio_path rfpath, u32 offset,
-					u32 data)
+				 enum radio_path rfpath, u32 offset,
+				 u32 data)
 {
 	u32 data_and_addr;
 	u32 newoffset;
@@ -197,6 +199,7 @@
 	rtl_set_bbreg(hw, 0xe80, 0x0c000000, 0x2);
 	rtl_set_bbreg(hw, 0xe88, 0x0c000000, 0x2);
 }
+
 bool rtl92c_phy_rf_config(struct ieee80211_hw *hw)
 {
 	struct rtl_priv *rtlpriv = rtl_priv(hw);
@@ -241,13 +244,14 @@
 	rtlphy->cck_high_power = (bool) (rtl_get_bbreg(hw,
 						RFPGA0_XA_HSSIPARAMETER2,
 						0x200));
+
 	return true;
 }
 EXPORT_SYMBOL(_rtl92c_phy_bb8192c_config_parafile);
 
 void _rtl92c_store_pwrIndex_diffrate_offset(struct ieee80211_hw *hw,
-						   u32 regaddr, u32 bitmask,
-						   u32 data)
+					    u32 regaddr, u32 bitmask,
+					    u32 data)
 {
 	struct rtl_priv *rtlpriv = rtl_priv(hw);
 	struct rtl_phy *rtlphy = &(rtlpriv->phy);
@@ -317,61 +321,48 @@
 	}
 	if (regaddr == RTXAGC_B_RATE54_24) {
 		rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][9] = data;
-
 		RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
 			 ("MCSTxPowerLevelOriginalOffset[%d][9] = 0x%x\n",
 			  rtlphy->pwrgroup_cnt,
 			  rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][9]));
 	}
-
 	if (regaddr == RTXAGC_B_CCK1_55_MCS32) {
 		rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][14] = data;
-
 		RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
 			 ("MCSTxPowerLevelOriginalOffset[%d][14] = 0x%x\n",
 			  rtlphy->pwrgroup_cnt,
 			  rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][14]));
 	}
-
 	if (regaddr == RTXAGC_B_CCK11_A_CCK2_11 && bitmask == 0x000000ff) {
 		rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][15] = data;
-
 		RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
 			 ("MCSTxPowerLevelOriginalOffset[%d][15] = 0x%x\n",
 			  rtlphy->pwrgroup_cnt,
 			  rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][15]));
 	}
-
 	if (regaddr == RTXAGC_B_MCS03_MCS00) {
 		rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][10] = data;
-
 		RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
 			 ("MCSTxPowerLevelOriginalOffset[%d][10] = 0x%x\n",
 			  rtlphy->pwrgroup_cnt,
 			  rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][10]));
 	}
-
 	if (regaddr == RTXAGC_B_MCS07_MCS04) {
 		rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][11] = data;
-
 		RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
 			 ("MCSTxPowerLevelOriginalOffset[%d][11] = 0x%x\n",
 			  rtlphy->pwrgroup_cnt,
 			  rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][11]));
 	}
-
 	if (regaddr == RTXAGC_B_MCS11_MCS08) {
 		rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][12] = data;
-
 		RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
 			 ("MCSTxPowerLevelOriginalOffset[%d][12] = 0x%x\n",
 			  rtlphy->pwrgroup_cnt,
 			  rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][12]));
 	}
-
 	if (regaddr == RTXAGC_B_MCS15_MCS12) {
 		rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][13] = data;
-
 		RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
 			 ("MCSTxPowerLevelOriginalOffset[%d][13] = 0x%x\n",
 			  rtlphy->pwrgroup_cnt,
@@ -583,6 +574,7 @@
 
 	rtlphy->cur_cck_txpwridx = cckpowerlevel[0];
 	rtlphy->cur_ofdm24g_txpwridx = ofdmpowerlevel[0];
+
 }
 
 void rtl92c_phy_set_txpower_level(struct ieee80211_hw *hw, u8 channel)
@@ -611,7 +603,6 @@
 	struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
 	u8 idx;
 	u8 rf_path;
-
 	u8 ccktxpwridx = _rtl92c_phy_dbm_to_txpwr_Idx(hw,
 						      WIRELESS_MODE_B,
 						      power_indbm);
@@ -639,11 +630,6 @@
 }
 EXPORT_SYMBOL(rtl92c_phy_update_txpower_dbm);
 
-void rtl92c_phy_set_beacon_hw_reg(struct ieee80211_hw *hw, u16 beaconinterval)
-{
-}
-EXPORT_SYMBOL(rtl92c_phy_set_beacon_hw_reg);
-
 u8 _rtl92c_phy_dbm_to_txpwr_Idx(struct ieee80211_hw *hw,
 				enum wireless_mode wirelessmode,
 				long power_indbm)
@@ -741,9 +727,9 @@
 	if (rtlphy->set_bwmode_inprogress)
 		return;
 	rtlphy->set_bwmode_inprogress = true;
-	if ((!is_hal_stop(rtlhal)) && !(RT_CANNOT_IO(hw)))
+	if ((!is_hal_stop(rtlhal)) && !(RT_CANNOT_IO(hw))) {
 		rtlpriv->cfg->ops->phy_set_bw_mode_callback(hw);
-	else {
+	} else {
 		RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
 			 ("FALSE driver sleep or unload\n"));
 		rtlphy->set_bwmode_inprogress = false;
@@ -773,8 +759,9 @@
 				mdelay(delay);
 			else
 				continue;
-		} else
+		} else {
 			rtlphy->sw_chnl_inprogress = false;
+		}
 		break;
 	} while (true);
 	RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, ("<==\n"));
@@ -811,9 +798,32 @@
 }
 EXPORT_SYMBOL(rtl92c_phy_sw_chnl);
 
-static bool _rtl92c_phy_sw_chnl_step_by_step(struct ieee80211_hw *hw,
-					     u8 channel, u8 *stage, u8 *step,
-					     u32 *delay)
+static bool _rtl92c_phy_set_sw_chnl_cmdarray(struct swchnlcmd *cmdtable,
+					     u32 cmdtableidx, u32 cmdtablesz,
+					     enum swchnlcmd_id cmdid,
+					     u32 para1, u32 para2, u32 msdelay)
+{
+	struct swchnlcmd *pcmd;
+
+	if (cmdtable == NULL) {
+		RT_ASSERT(false, ("cmdtable cannot be NULL.\n"));
+		return false;
+	}
+
+	if (cmdtableidx >= cmdtablesz)
+		return false;
+
+	pcmd = cmdtable + cmdtableidx;
+	pcmd->cmdid = cmdid;
+	pcmd->para1 = para1;
+	pcmd->para2 = para2;
+	pcmd->msdelay = msdelay;
+	return true;
+}
+
+bool _rtl92c_phy_sw_chnl_step_by_step(struct ieee80211_hw *hw,
+				      u8 channel, u8 *stage, u8 *step,
+				      u32 *delay)
 {
 	struct rtl_priv *rtlpriv = rtl_priv(hw);
 	struct rtl_phy *rtlphy = &(rtlpriv->phy);
@@ -917,29 +927,6 @@
 	return false;
 }
 
-static bool _rtl92c_phy_set_sw_chnl_cmdarray(struct swchnlcmd *cmdtable,
-					     u32 cmdtableidx, u32 cmdtablesz,
-					     enum swchnlcmd_id cmdid,
-					     u32 para1, u32 para2, u32 msdelay)
-{
-	struct swchnlcmd *pcmd;
-
-	if (cmdtable == NULL) {
-		RT_ASSERT(false, ("cmdtable cannot be NULL.\n"));
-		return false;
-	}
-
-	if (cmdtableidx >= cmdtablesz)
-		return false;
-
-	pcmd = cmdtable + cmdtableidx;
-	pcmd->cmdid = cmdid;
-	pcmd->para1 = para1;
-	pcmd->para2 = para2;
-	pcmd->msdelay = msdelay;
-	return true;
-}
-
 bool rtl8192_phy_check_is_legal_rfpath(struct ieee80211_hw *hw, u32 rfpath)
 {
 	return true;
@@ -1002,13 +989,13 @@
 	reg_ebc = rtl_get_bbreg(hw, 0xebc, MASKDWORD);
 	reg_ec4 = rtl_get_bbreg(hw, 0xec4, MASKDWORD);
 	reg_ecc = rtl_get_bbreg(hw, 0xecc, MASKDWORD);
+
 	if (!(reg_eac & BIT(31)) &&
 	    (((reg_eb4 & 0x03FF0000) >> 16) != 0x142) &&
 	    (((reg_ebc & 0x03FF0000) >> 16) != 0x42))
 		result |= 0x01;
 	else
 		return result;
-
 	if (!(reg_eac & BIT(30)) &&
 	    (((reg_ec4 & 0x03FF0000) >> 16) != 0x132) &&
 	    (((reg_ecc & 0x03FF0000) >> 16) != 0x36))
@@ -1023,9 +1010,9 @@
 	u32 oldval_0, x, tx0_a, reg;
 	long y, tx0_c;
 
-	if (final_candidate == 0xFF)
+	if (final_candidate == 0xFF) {
 		return;
-	else if (iqk_ok) {
+	} else if (iqk_ok) {
 		oldval_0 = (rtl_get_bbreg(hw, ROFDM0_XATXIQIMBALANCE,
 					  MASKDWORD) >> 22) & 0x3FF;
 		x = result[final_candidate][0];
@@ -1063,9 +1050,9 @@
 	u32 oldval_1, x, tx1_a, reg;
 	long y, tx1_c;
 
-	if (final_candidate == 0xFF)
+	if (final_candidate == 0xFF) {
 		return;
-	else if (iqk_ok) {
+	} else if (iqk_ok) {
 		oldval_1 = (rtl_get_bbreg(hw, ROFDM0_XBTXIQIMBALANCE,
 					  MASKDWORD) >> 22) & 0x3FF;
 		x = result[final_candidate][4];
@@ -1282,6 +1269,7 @@
 						   RFPGA0_XA_HSSIPARAMETER1,
 						   BIT(8));
 	}
+
 	if (!rtlphy->rfpi_enable)
 		_rtl92c_phy_pi_mode_switch(hw, true);
 	if (t == 0) {
@@ -1317,9 +1305,10 @@
 					0x3FF0000) >> 16;
 			break;
 		} else if (i == (retrycount - 1) && patha_ok == 0x01)
+
 			result[t][0] = (rtl_get_bbreg(hw, 0xe94,
 						      MASKDWORD) & 0x3FF0000) >>
-						      16;
+			    16;
 		result[t][1] =
 		    (rtl_get_bbreg(hw, 0xe9c, MASKDWORD) & 0x3FF0000) >> 16;
 
@@ -1375,8 +1364,7 @@
 static void _rtl92c_phy_ap_calibrate(struct ieee80211_hw *hw,
 				     char delta, bool is2t)
 {
-	/* This routine is deliberately dummied out for later fixes */
-#if 0
+#if 0 /* This routine is deliberately dummied out for later fixes */
 	struct rtl_priv *rtlpriv = rtl_priv(hw);
 	struct rtl_phy *rtlphy = &(rtlpriv->phy);
 	struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
@@ -1434,7 +1422,7 @@
 		0x04db25a4, 0x0b1b25a4
 	};
 
-	u32 apk_offset[PATH_NUM] = { 0xb68, 0xb6c };
+	const u32 apk_offset[PATH_NUM] = { 0xb68, 0xb6c };
 
 	u32 apk_normal_offset[PATH_NUM] = { 0xb28, 0xb98 };
 
@@ -1463,13 +1451,15 @@
 		0x00050006
 	};
 
-	const u32 apk_result[PATH_NUM][APK_BB_REG_NUM];
+	u32 apk_result[PATH_NUM][APK_BB_REG_NUM];
 
 	long bb_offset, delta_v, delta_offset;
 
 	if (!is2t)
 		pathbound = 1;
 
+	return;
+
 	for (index = 0; index < PATH_NUM; index++) {
 		apk_offset[index] = apk_normal_offset[index];
 		apk_value[index] = apk_normal_value[index];
@@ -1730,8 +1720,7 @@
 			       0x08));
 
 	}
-
-	rtlphy->apk_done = true;
+	rtlphy->b_apk_done = true;
 #endif
 }
 
@@ -1758,6 +1747,7 @@
 			rtl_set_bbreg(hw, RFPGA0_XA_RFINTERFACEOE, 0x300, 0x1);
 
 	}
+
 }
 
 #undef IQK_ADDA_REG_NUM
diff -druN linux-2.6.39-libre/drivers/net/wireless/rtlwifi/rtl8192c/phy_common.h linux-3.0-rc7-libre/drivers/net/wireless/rtlwifi/rtl8192c/phy_common.h
--- linux-2.6.39-libre/drivers/net/wireless/rtlwifi/rtl8192c/phy_common.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/rtlwifi/rtl8192c/phy_common.h	2011-07-11 19:51:52.000000000 -0400
@@ -27,8 +27,8 @@
  *
  *****************************************************************************/
 
-#ifndef __RTL92C_PHY_H__
-#define __RTL92C_PHY_H__
+#ifndef __RTL92C_PHY_COMMON_H__
+#define __RTL92C_PHY_COMMON_H__
 
 #define MAX_PRECMD_CNT			16
 #define MAX_RFDEPENDCMD_CNT		16
@@ -39,6 +39,7 @@
 #define RT_CANNOT_IO(hw)		false
 #define HIGHPOWER_RADIOA_ARRAYLEN	22
 
+#define IQK_ADDA_REG_NUM		16
 #define MAX_TOLERANCE			5
 #define	IQK_DELAY_TIME			1
 
@@ -56,6 +57,7 @@
 #define IQK_ADDA_REG_NUM		16
 #define IQK_MAC_REG_NUM			4
 
+#define IQK_DELAY_TIME			1
 #define RF90_PATH_MAX			2
 
 #define CT_OFFSET_MAC_ADDR		0X16
@@ -77,6 +79,7 @@
 
 #define RTL92C_MAX_PATH_NUM		2
 #define LLT_LAST_ENTRY_OF_TX_PKT_BUFFER	255
+
 enum swchnlcmd_id {
 	CMDID_END,
 	CMDID_SET_TXPOWEROWER_LEVEL,
@@ -184,45 +187,41 @@
 	u32 mcs_original_offset[4][16];
 };
 
-extern u32 rtl92c_phy_query_bb_reg(struct ieee80211_hw *hw,
+u32 rtl92c_phy_query_bb_reg(struct ieee80211_hw *hw,
 				   u32 regaddr, u32 bitmask);
-extern void rtl92c_phy_set_bb_reg(struct ieee80211_hw *hw,
+void rtl92c_phy_set_bb_reg(struct ieee80211_hw *hw,
 				  u32 regaddr, u32 bitmask, u32 data);
-extern u32 rtl92c_phy_query_rf_reg(struct ieee80211_hw *hw,
+u32 rtl92c_phy_query_rf_reg(struct ieee80211_hw *hw,
 				   enum radio_path rfpath, u32 regaddr,
 				   u32 bitmask);
-extern void rtl92c_phy_set_rf_reg(struct ieee80211_hw *hw,
-				  enum radio_path rfpath, u32 regaddr,
-				  u32 bitmask, u32 data);
-extern bool rtl92c_phy_mac_config(struct ieee80211_hw *hw);
-extern bool rtl92c_phy_bb_config(struct ieee80211_hw *hw);
-extern bool rtl92c_phy_rf_config(struct ieee80211_hw *hw);
-extern bool rtl92c_phy_config_rf_with_feaderfile(struct ieee80211_hw *hw,
+bool rtl92c_phy_mac_config(struct ieee80211_hw *hw);
+bool rtl92c_phy_bb_config(struct ieee80211_hw *hw);
+bool rtl92c_phy_rf_config(struct ieee80211_hw *hw);
+bool rtl92c_phy_config_rf_with_feaderfile(struct ieee80211_hw *hw,
 						 enum radio_path rfpath);
-extern void rtl92c_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw);
-extern void rtl92c_phy_get_txpower_level(struct ieee80211_hw *hw,
+void rtl92c_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw);
+void rtl92c_phy_get_txpower_level(struct ieee80211_hw *hw,
 					 long *powerlevel);
-extern void rtl92c_phy_set_txpower_level(struct ieee80211_hw *hw, u8 channel);
-extern bool rtl92c_phy_update_txpower_dbm(struct ieee80211_hw *hw,
+void rtl92c_phy_set_txpower_level(struct ieee80211_hw *hw, u8 channel);
+bool rtl92c_phy_update_txpower_dbm(struct ieee80211_hw *hw,
 					  long power_indbm);
-extern void rtl92c_phy_scan_operation_backup(struct ieee80211_hw *hw,
+void rtl92c_phy_scan_operation_backup(struct ieee80211_hw *hw,
 					     u8 operation);
-extern void rtl92c_phy_set_bw_mode_callback(struct ieee80211_hw *hw);
-extern void rtl92c_phy_set_bw_mode(struct ieee80211_hw *hw,
+void rtl92c_phy_set_bw_mode(struct ieee80211_hw *hw,
 				   enum nl80211_channel_type ch_type);
-extern void rtl92c_phy_sw_chnl_callback(struct ieee80211_hw *hw);
-extern u8 rtl92c_phy_sw_chnl(struct ieee80211_hw *hw);
-extern void rtl92c_phy_iq_calibrate(struct ieee80211_hw *hw, bool b_recovery);
-extern void rtl92c_phy_set_beacon_hw_reg(struct ieee80211_hw *hw,
+void rtl92c_phy_sw_chnl_callback(struct ieee80211_hw *hw);
+u8 rtl92c_phy_sw_chnl(struct ieee80211_hw *hw);
+void rtl92c_phy_iq_calibrate(struct ieee80211_hw *hw, bool b_recovery);
+void rtl92c_phy_set_beacon_hw_reg(struct ieee80211_hw *hw,
 					 u16 beaconinterval);
 void rtl92c_phy_ap_calibrate(struct ieee80211_hw *hw, char delta);
 void rtl92c_phy_lc_calibrate(struct ieee80211_hw *hw);
 void rtl92c_phy_set_rfpath_switch(struct ieee80211_hw *hw, bool bmain);
 bool rtl92c_phy_config_rf_with_headerfile(struct ieee80211_hw *hw,
 					  enum radio_path rfpath);
-extern bool rtl8192_phy_check_is_legal_rfpath(struct ieee80211_hw *hw,
+bool rtl8192_phy_check_is_legal_rfpath(struct ieee80211_hw *hw,
 					      u32 rfpath);
-extern bool rtl92c_phy_set_rf_power_state(struct ieee80211_hw *hw,
+bool rtl92c_phy_set_rf_power_state(struct ieee80211_hw *hw,
 					  enum rf_pwrstate rfpwr_state);
 void rtl92ce_phy_set_rf_on(struct ieee80211_hw *hw);
 void rtl92c_phy_set_io(struct ieee80211_hw *hw);
@@ -235,12 +234,25 @@
 				enum wireless_mode wirelessmode,
 				long power_indbm);
 void _rtl92c_phy_init_bb_rf_register_definition(struct ieee80211_hw *hw);
-static bool _rtl92c_phy_set_sw_chnl_cmdarray(struct swchnlcmd *cmdtable,
-					     u32 cmdtableidx, u32 cmdtablesz,
-					     enum swchnlcmd_id cmdid, u32 para1,
-					     u32 para2, u32 msdelay);
-static bool _rtl92c_phy_sw_chnl_step_by_step(struct ieee80211_hw *hw,
-					     u8 channel, u8 *stage, u8 *step,
-					     u32 *delay);
+void _rtl92c_phy_set_rf_sleep(struct ieee80211_hw *hw);
+bool _rtl92c_phy_sw_chnl_step_by_step(struct ieee80211_hw *hw,
+				      u8 channel, u8 *stage, u8 *step,
+				      u32 *delay);
+u8 rtl92c_bt_rssi_state_change(struct ieee80211_hw *hw);
+u32 _rtl92c_phy_fw_rf_serial_read(struct ieee80211_hw *hw,
+				  enum radio_path rfpath, u32 offset);
+void _rtl92c_phy_fw_rf_serial_write(struct ieee80211_hw *hw,
+				    enum radio_path rfpath, u32 offset,
+				    u32 data);
+u32 _rtl92c_phy_rf_serial_read(struct ieee80211_hw *hw,
+			       enum radio_path rfpath, u32 offset);
+void _rtl92c_phy_rf_serial_write(struct ieee80211_hw *hw,
+				 enum radio_path rfpath, u32 offset,
+				 u32 data);
+bool _rtl92c_phy_bb8192c_config_parafile(struct ieee80211_hw *hw);
+void _rtl92c_store_pwrIndex_diffrate_offset(struct ieee80211_hw *hw,
+					    u32 regaddr, u32 bitmask,
+					    u32 data);
+bool rtl92c_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype);
 
 #endif
diff -druN linux-2.6.39-libre/drivers/net/wireless/rtlwifi/rtl8192ce/def.h linux-3.0-rc7-libre/drivers/net/wireless/rtlwifi/rtl8192ce/def.h
--- linux-2.6.39-libre/drivers/net/wireless/rtlwifi/rtl8192ce/def.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/rtlwifi/rtl8192ce/def.h	2011-07-11 19:51:52.000000000 -0400
@@ -121,19 +121,6 @@
 #define CHIP_92C			0x01
 #define CHIP_88C			0x00
 
-/* Add vendor information into chip version definition.
- * Add UMC B-Cut and RTL8723 chip info definition.
- *
- * BIT 7	Reserved
- * BIT 6	UMC BCut
- * BIT 5	Manufacturer(TSMC/UMC)
- * BIT 4	TEST/NORMAL
- * BIT 3	8723 Version
- * BIT 2	8723?
- * BIT 1	1T2R?
- * BIT 0	88C/92C
-*/
-
 enum version_8192c {
 	VERSION_A_CHIP_92C = 0x01,
 	VERSION_A_CHIP_88C = 0x00,
@@ -280,20 +267,6 @@
 	u8 *p_cmdbuffer;
 };
 
-static inline u8 _rtl92c_get_chnl_group(u8 chnl)
-{
-	u8 group = 0;
-
-	if (chnl < 3)
-		group = 0;
-	else if (chnl < 9)
-		group = 1;
-	else
-		group = 2;
-
-	return group;
-}
-
 /* NOTE: reference to rtl8192c_rates struct */
 static inline int _rtl92c_rate_mapping(struct ieee80211_hw *hw, bool isHT,
 				       u8 desc_rate, bool first_ampdu)
diff -druN linux-2.6.39-libre/drivers/net/wireless/rtlwifi/rtl8192ce/dm.c linux-3.0-rc7-libre/drivers/net/wireless/rtlwifi/rtl8192ce/dm.c
--- linux-2.6.39-libre/drivers/net/wireless/rtlwifi/rtl8192ce/dm.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/rtlwifi/rtl8192ce/dm.c	2011-07-11 19:51:52.000000000 -0400
@@ -29,10 +29,12 @@
 
 #include "../wifi.h"
 #include "../base.h"
+#include "../pci.h"
 #include "reg.h"
 #include "def.h"
 #include "phy.h"
 #include "dm.h"
+#include "../rtl8192c/fw_common.h"
 
 void rtl92ce_dm_dynamic_txpower(struct ieee80211_hw *hw)
 {
diff -druN linux-2.6.39-libre/drivers/net/wireless/rtlwifi/rtl8192ce/dm.h linux-3.0-rc7-libre/drivers/net/wireless/rtlwifi/rtl8192ce/dm.h
--- linux-2.6.39-libre/drivers/net/wireless/rtlwifi/rtl8192ce/dm.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/rtlwifi/rtl8192ce/dm.h	2011-07-11 19:51:52.000000000 -0400
@@ -192,6 +192,7 @@
 void rtl92c_dm_check_txpower_tracking(struct ieee80211_hw *hw);
 void rtl92c_dm_init_rate_adaptive_mask(struct ieee80211_hw *hw);
 void rtl92c_dm_rf_saving(struct ieee80211_hw *hw, u8 bforce_in_normal);
+void rtl92c_dm_bt_coexist(struct ieee80211_hw *hw);
 void rtl92ce_dm_dynamic_txpower(struct ieee80211_hw *hw);
 
 #endif
diff -druN linux-2.6.39-libre/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c linux-3.0-rc7-libre/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c
--- linux-2.6.39-libre/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c	2011-07-11 19:51:52.000000000 -0400
@@ -30,12 +30,14 @@
 #include "../wifi.h"
 #include "../efuse.h"
 #include "../base.h"
+#include "../regd.h"
 #include "../cam.h"
 #include "../ps.h"
 #include "../pci.h"
 #include "reg.h"
 #include "def.h"
 #include "phy.h"
+#include "../rtl8192c/fw_common.h"
 #include "dm.h"
 #include "led.h"
 #include "hw.h"
@@ -137,15 +139,6 @@
 
 		break;
 		}
-	case HW_VAR_MGT_FILTER:
-		*((u16 *) (val)) = rtl_read_word(rtlpriv, REG_RXFLTMAP0);
-		break;
-	case HW_VAR_CTRL_FILTER:
-		*((u16 *) (val)) = rtl_read_word(rtlpriv, REG_RXFLTMAP1);
-		break;
-	case HW_VAR_DATA_FILTER:
-		*((u16 *) (val)) = rtl_read_word(rtlpriv, REG_RXFLTMAP2);
-		break;
 	default:
 		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
 			 ("switch case not process\n"));
@@ -156,6 +149,7 @@
 void rtl92ce_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
 {
 	struct rtl_priv *rtlpriv = rtl_priv(hw);
+	struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
 	struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
 	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
 	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
@@ -178,7 +172,7 @@
 			rate_cfg |= 0x01;
 			rtl_write_byte(rtlpriv, REG_RRSR, rate_cfg & 0xff);
 			rtl_write_byte(rtlpriv, REG_RRSR + 1,
-				       (rate_cfg >> 8)&0xff);
+				       (rate_cfg >> 8) & 0xff);
 			while (rate_cfg > 0x1) {
 				rate_cfg = (rate_cfg >> 1);
 				rate_index++;
@@ -276,13 +270,19 @@
 			break;
 		}
 	case HW_VAR_AMPDU_FACTOR:{
-			u8 regtoset_normal[4] = { 0x41, 0xa8, 0x72, 0xb9 };
+			u8 regtoset_normal[4] = {0x41, 0xa8, 0x72, 0xb9};
+			u8 regtoset_bt[4] = {0x31, 0x74, 0x42, 0x97};
 
 			u8 factor_toset;
 			u8 *p_regtoset = NULL;
 			u8 index = 0;
 
-			p_regtoset = regtoset_normal;
+			if ((rtlpcipriv->bt_coexist.bt_coexistence) &&
+			    (rtlpcipriv->bt_coexist.bt_coexist_type ==
+			    BT_CSR_BC4))
+				p_regtoset = regtoset_bt;
+			else
+				p_regtoset = regtoset_normal;
 
 			factor_toset = *((u8 *) val);
 			if (factor_toset <= 3) {
@@ -317,45 +317,7 @@
 		}
 	case HW_VAR_AC_PARAM:{
 			u8 e_aci = *((u8 *) val);
-			u32 u4b_ac_param;
-			u16 cw_min = le16_to_cpu(mac->ac[e_aci].cw_min);
-			u16 cw_max = le16_to_cpu(mac->ac[e_aci].cw_max);
-			u16 tx_op = le16_to_cpu(mac->ac[e_aci].tx_op);
-
-			u4b_ac_param = (u32) mac->ac[e_aci].aifs;
-			u4b_ac_param |= ((u32)cw_min
-					 & 0xF) << AC_PARAM_ECW_MIN_OFFSET;
-			u4b_ac_param |= ((u32)cw_max &
-					 0xF) << AC_PARAM_ECW_MAX_OFFSET;
-			u4b_ac_param |= (u32)tx_op << AC_PARAM_TXOP_OFFSET;
-
-			RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD,
-				 ("queue:%x, ac_param:%x\n", e_aci,
-				  u4b_ac_param));
-
-			switch (e_aci) {
-			case AC1_BK:
-				rtl_write_dword(rtlpriv, REG_EDCA_BK_PARAM,
-						u4b_ac_param);
-				break;
-			case AC0_BE:
-				rtl_write_dword(rtlpriv, REG_EDCA_BE_PARAM,
-						u4b_ac_param);
-				break;
-			case AC2_VI:
-				rtl_write_dword(rtlpriv, REG_EDCA_VI_PARAM,
-						u4b_ac_param);
-				break;
-			case AC3_VO:
-				rtl_write_dword(rtlpriv, REG_EDCA_VO_PARAM,
-						u4b_ac_param);
-				break;
-			default:
-				RT_ASSERT(false,
-				  ("SetHwReg8185(): invalid aci: %d !\n",
-				   e_aci));
-				break;
-			}
+			rtl92c_dm_init_edca_turbo(hw);
 
 			if (rtlpci->acm_method != eAcmWay2_SW)
 				rtlpriv->cfg->ops->set_hw_reg(hw,
@@ -526,9 +488,6 @@
 	case HW_VAR_CORRECT_TSF:{
 			u8 btype_ibss = ((u8 *) (val))[0];
 
-			/*btype_ibss = (mac->opmode == NL80211_IFTYPE_ADHOC) ?
-					1 : 0;*/
-
 			if (btype_ibss == true)
 				_rtl92ce_stop_tx_beacon(hw);
 
@@ -537,7 +496,7 @@
 			rtl_write_dword(rtlpriv, REG_TSFTR,
 					(u32) (mac->tsf & 0xffffffff));
 			rtl_write_dword(rtlpriv, REG_TSFTR + 4,
-					(u32) ((mac->tsf >> 32)&0xffffffff));
+					(u32) ((mac->tsf >> 32) & 0xffffffff));
 
 			_rtl92ce_set_bcn_ctrl_reg(hw, BIT(3), 0);
 
@@ -547,15 +506,6 @@
 			break;
 
 		}
-	case HW_VAR_MGT_FILTER:
-		rtl_write_word(rtlpriv, REG_RXFLTMAP0, *(u16 *) val);
-		break;
-	case HW_VAR_CTRL_FILTER:
-		rtl_write_word(rtlpriv, REG_RXFLTMAP1, *(u16 *) val);
-		break;
-	case HW_VAR_DATA_FILTER:
-		rtl_write_word(rtlpriv, REG_RXFLTMAP2, *(u16 *) val);
-		break;
 	default:
 		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("switch case "
 							"not process\n"));
@@ -679,12 +629,12 @@
 		rtl92ce_sw_led_on(hw, pLed0);
 	else
 		rtl92ce_sw_led_off(hw, pLed0);
-
 }
 
 static bool _rtl92ce_init_mac(struct ieee80211_hw *hw)
 {
 	struct rtl_priv *rtlpriv = rtl_priv(hw);
+	struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
 	struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
 	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
 
@@ -693,9 +643,22 @@
 	u16 retry;
 
 	rtl_write_byte(rtlpriv, REG_RSV_CTRL, 0x00);
+	if (rtlpcipriv->bt_coexist.bt_coexistence) {
+		u32 value32;
+		value32 = rtl_read_dword(rtlpriv, REG_APS_FSMCO);
+		value32 |= (SOP_ABG | SOP_AMB | XOP_BTCK);
+		rtl_write_dword(rtlpriv, REG_APS_FSMCO, value32);
+	}
 	rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x2b);
 	rtl_write_byte(rtlpriv, REG_AFE_XTAL_CTRL, 0x0F);
 
+	if (rtlpcipriv->bt_coexist.bt_coexistence) {
+		u32 u4b_tmp = rtl_read_dword(rtlpriv, REG_AFE_XTAL_CTRL);
+
+		u4b_tmp &= (~0x00024800);
+		rtl_write_dword(rtlpriv, REG_AFE_XTAL_CTRL, u4b_tmp);
+	}
+
 	bytetmp = rtl_read_byte(rtlpriv, REG_APS_FSMCO + 1) | BIT(0);
 	udelay(2);
 
@@ -726,10 +689,15 @@
 	rtl_write_byte(rtlpriv, REG_SYS_ISO_CTRL + 1, 0x82);
 	udelay(2);
 
+	if (rtlpcipriv->bt_coexist.bt_coexistence) {
+		bytetmp = rtl_read_byte(rtlpriv, REG_AFE_XTAL_CTRL+2) & 0xfd;
+		rtl_write_byte(rtlpriv, REG_AFE_XTAL_CTRL+2, bytetmp);
+	}
+
 	rtl_write_word(rtlpriv, REG_CR, 0x2ff);
 
 	if (_rtl92ce_llt_table_init(hw) == false)
-		return false;;
+		return false;
 
 	rtl_write_dword(rtlpriv, REG_HISR, 0xffffffff);
 	rtl_write_byte(rtlpriv, REG_HISRE, 0xff);
@@ -786,13 +754,14 @@
 
 	rtl_write_dword(rtlpriv, REG_MCUTST_1, 0x0);
 
-	return true;;
+	return true;
 }
 
 static void _rtl92ce_hw_configure(struct ieee80211_hw *hw)
 {
 	struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
 	struct rtl_priv *rtlpriv = rtl_priv(hw);
+	struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
 	u8 reg_bw_opmode;
 	u32 reg_ratr, reg_prsr;
 
@@ -824,7 +793,11 @@
 	rtl_write_dword(rtlpriv, REG_RARFRC, 0x01000000);
 	rtl_write_dword(rtlpriv, REG_RARFRC + 4, 0x07060504);
 
-	rtl_write_dword(rtlpriv, REG_AGGLEN_LMT, 0xb972a841);
+	if ((rtlpcipriv->bt_coexist.bt_coexistence) &&
+	    (rtlpcipriv->bt_coexist.bt_coexist_type == BT_CSR_BC4))
+		rtl_write_dword(rtlpriv, REG_AGGLEN_LMT, 0x97427431);
+	else
+		rtl_write_dword(rtlpriv, REG_AGGLEN_LMT, 0xb972a841);
 
 	rtl_write_byte(rtlpriv, REG_ATIMWND, 0x2);
 
@@ -840,11 +813,20 @@
 	rtl_write_byte(rtlpriv, REG_PIFS, 0x1C);
 	rtl_write_byte(rtlpriv, REG_AGGR_BREAK_TIME, 0x16);
 
-	rtl_write_word(rtlpriv, REG_NAV_PROT_LEN, 0x0020);
-
-	rtl_write_word(rtlpriv, REG_NAV_PROT_LEN, 0x0020);
+	if ((rtlpcipriv->bt_coexist.bt_coexistence) &&
+	    (rtlpcipriv->bt_coexist.bt_coexist_type == BT_CSR_BC4)) {
+		rtl_write_word(rtlpriv, REG_NAV_PROT_LEN, 0x0020);
+		rtl_write_word(rtlpriv, REG_PROT_MODE_CTRL, 0x0402);
+	} else {
+		rtl_write_word(rtlpriv, REG_NAV_PROT_LEN, 0x0020);
+		rtl_write_word(rtlpriv, REG_NAV_PROT_LEN, 0x0020);
+	}
 
-	rtl_write_dword(rtlpriv, REG_FAST_EDCA_CTRL, 0x086666);
+	if ((rtlpcipriv->bt_coexist.bt_coexistence) &&
+	     (rtlpcipriv->bt_coexist.bt_coexist_type == BT_CSR_BC4))
+		rtl_write_dword(rtlpriv, REG_FAST_EDCA_CTRL, 0x03086666);
+	else
+		rtl_write_dword(rtlpriv, REG_FAST_EDCA_CTRL, 0x086666);
 
 	rtl_write_byte(rtlpriv, REG_ACKTO, 0x40);
 
@@ -948,8 +930,8 @@
 	}
 
 	rtlhal->last_hmeboxnum = 0;
-	rtl92ce_phy_mac_config(hw);
-	rtl92ce_phy_bb_config(hw);
+	rtl92c_phy_mac_config(hw);
+	rtl92c_phy_bb_config(hw);
 	rtlphy->rf_mode = RF_OP_BY_SW_3WIRE;
 	rtl92c_phy_rf_config(hw);
 	rtlphy->rfreg_chnlval[0] = rtl_get_rfreg(hw, (enum radio_path)0,
@@ -962,15 +944,20 @@
 	_rtl92ce_hw_configure(hw);
 	rtl_cam_reset_all_entry(hw);
 	rtl92ce_enable_hw_security_config(hw);
+
 	ppsc->rfpwr_state = ERFON;
+
 	rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_ETHER_ADDR, mac->mac_addr);
 	_rtl92ce_enable_aspm_back_door(hw);
 	rtlpriv->intf_ops->enable_aspm(hw);
+
+	rtl8192ce_bt_hw_init(hw);
+
 	if (ppsc->rfpwr_state == ERFON) {
 		rtl92c_phy_set_rfpath_switch(hw, 1);
-		if (iqk_initialized)
+		if (iqk_initialized) {
 			rtl92c_phy_iq_calibrate(hw, true);
-		else {
+		} else {
 			rtl92c_phy_iq_calibrate(hw, false);
 			iqk_initialized = true;
 		}
@@ -1128,75 +1115,62 @@
 	return 0;
 }
 
-static void _rtl92ce_set_check_bssid(struct ieee80211_hw *hw,
-				     enum nl80211_iftype type)
+void rtl92ce_set_check_bssid(struct ieee80211_hw *hw, bool check_bssid)
 {
 	struct rtl_priv *rtlpriv = rtl_priv(hw);
 	u32 reg_rcr = rtl_read_dword(rtlpriv, REG_RCR);
-	u8 filterout_non_associated_bssid = false;
 
-	switch (type) {
-	case NL80211_IFTYPE_ADHOC:
-	case NL80211_IFTYPE_STATION:
-		filterout_non_associated_bssid = true;
-		break;
-	case NL80211_IFTYPE_UNSPECIFIED:
-	case NL80211_IFTYPE_AP:
-	default:
-		break;
-	}
+	if (rtlpriv->psc.rfpwr_state != ERFON)
+		return;
 
-	if (filterout_non_associated_bssid == true) {
+	if (check_bssid == true) {
 		reg_rcr |= (RCR_CBSSID_DATA | RCR_CBSSID_BCN);
 		rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RCR,
 					      (u8 *) (&reg_rcr));
 		_rtl92ce_set_bcn_ctrl_reg(hw, 0, BIT(4));
-	} else if (filterout_non_associated_bssid == false) {
+	} else if (check_bssid == false) {
 		reg_rcr &= (~(RCR_CBSSID_DATA | RCR_CBSSID_BCN));
 		_rtl92ce_set_bcn_ctrl_reg(hw, BIT(4), 0);
 		rtlpriv->cfg->ops->set_hw_reg(hw,
 					      HW_VAR_RCR, (u8 *) (&reg_rcr));
 	}
+
 }
 
 int rtl92ce_set_network_type(struct ieee80211_hw *hw, enum nl80211_iftype type)
 {
+	struct rtl_priv *rtlpriv = rtl_priv(hw);
+
 	if (_rtl92ce_set_media_status(hw, type))
 		return -EOPNOTSUPP;
-	_rtl92ce_set_check_bssid(hw, type);
+
+	if (rtlpriv->mac80211.link_state == MAC80211_LINKED) {
+		if (type != NL80211_IFTYPE_AP)
+			rtl92ce_set_check_bssid(hw, true);
+	} else {
+		rtl92ce_set_check_bssid(hw, false);
+	}
+
 	return 0;
 }
 
+/* don't set REG_EDCA_BE_PARAM here because mac80211 will send pkt when scan */
 void rtl92ce_set_qos(struct ieee80211_hw *hw, int aci)
 {
 	struct rtl_priv *rtlpriv = rtl_priv(hw);
-	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
-	u32 u4b_ac_param;
-	u16 cw_min = le16_to_cpu(mac->ac[aci].cw_min);
-	u16 cw_max = le16_to_cpu(mac->ac[aci].cw_max);
-	u16 tx_op = le16_to_cpu(mac->ac[aci].tx_op);
-
 	rtl92c_dm_init_edca_turbo(hw);
-	u4b_ac_param = (u32) mac->ac[aci].aifs;
-	u4b_ac_param |= (u32) ((cw_min & 0xF) << AC_PARAM_ECW_MIN_OFFSET);
-	u4b_ac_param |= (u32) ((cw_max & 0xF) << AC_PARAM_ECW_MAX_OFFSET);
-	u4b_ac_param |= (u32) (tx_op << AC_PARAM_TXOP_OFFSET);
-	RT_TRACE(rtlpriv, COMP_QOS, DBG_DMESG,
-		 ("queue:%x, ac_param:%x aifs:%x cwmin:%x cwmax:%x txop:%x\n",
-		  aci, u4b_ac_param, mac->ac[aci].aifs, cw_min,
-		  cw_max, tx_op));
 	switch (aci) {
 	case AC1_BK:
-		rtl_write_dword(rtlpriv, REG_EDCA_BK_PARAM, u4b_ac_param);
+		rtl_write_dword(rtlpriv, REG_EDCA_BK_PARAM, 0xa44f);
 		break;
 	case AC0_BE:
-		rtl_write_dword(rtlpriv, REG_EDCA_BE_PARAM, u4b_ac_param);
+		/* rtl_write_dword(rtlpriv, REG_EDCA_BE_PARAM, u4b_ac_param); */
 		break;
 	case AC2_VI:
-		rtl_write_dword(rtlpriv, REG_EDCA_VI_PARAM, u4b_ac_param);
+		rtl_write_dword(rtlpriv, REG_EDCA_VI_PARAM, 0x5e4322);
 		break;
 	case AC3_VO:
-		rtl_write_dword(rtlpriv, REG_EDCA_VO_PARAM, u4b_ac_param);
+		rtl_write_dword(rtlpriv, REG_EDCA_VO_PARAM, 0x2f3222);
 		break;
 	default:
 		RT_ASSERT(false, ("invalid aci: %d !\n", aci));
@@ -1227,8 +1201,10 @@
 static void _rtl92ce_poweroff_adapter(struct ieee80211_hw *hw)
 {
 	struct rtl_priv *rtlpriv = rtl_priv(hw);
+	struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
 	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
 	u8 u1b_tmp;
+	u32 u4b_tmp;
 
 	rtlpriv->intf_ops->enable_aspm(hw);
 	rtl_write_byte(rtlpriv, REG_TXPAUSE, 0xFF);
@@ -1243,13 +1219,27 @@
 	rtl_write_byte(rtlpriv, REG_MCUFWDL, 0x00);
 	rtl_write_dword(rtlpriv, REG_GPIO_PIN_CTRL, 0x00000000);
 	u1b_tmp = rtl_read_byte(rtlpriv, REG_GPIO_PIN_CTRL);
-	rtl_write_dword(rtlpriv, REG_GPIO_PIN_CTRL, 0x00FF0000 |
-			(u1b_tmp << 8));
+	if ((rtlpcipriv->bt_coexist.bt_coexistence) &&
+	     ((rtlpcipriv->bt_coexist.bt_coexist_type == BT_CSR_BC4) ||
+	     (rtlpcipriv->bt_coexist.bt_coexist_type == BT_CSR_BC8))) {
+		rtl_write_dword(rtlpriv, REG_GPIO_PIN_CTRL, 0x00F30000 |
+				(u1b_tmp << 8));
+	} else {
+		rtl_write_dword(rtlpriv, REG_GPIO_PIN_CTRL, 0x00FF0000 |
+				(u1b_tmp << 8));
+	}
 	rtl_write_word(rtlpriv, REG_GPIO_IO_SEL, 0x0790);
 	rtl_write_word(rtlpriv, REG_LEDCFG0, 0x8080);
 	rtl_write_byte(rtlpriv, REG_AFE_PLL_CTRL, 0x80);
 	rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x23);
-	rtl_write_byte(rtlpriv, REG_AFE_XTAL_CTRL, 0x0e);
+	if (rtlpcipriv->bt_coexist.bt_coexistence) {
+		u4b_tmp = rtl_read_dword(rtlpriv, REG_AFE_XTAL_CTRL);
+		u4b_tmp |= 0x03824800;
+		rtl_write_dword(rtlpriv, REG_AFE_XTAL_CTRL, u4b_tmp);
+	} else {
+		rtl_write_dword(rtlpriv, REG_AFE_XTAL_CTRL, 0x0e);
+	}
+
 	rtl_write_byte(rtlpriv, REG_RSV_CTRL, 0x0e);
 	rtl_write_byte(rtlpriv, REG_APS_FSMCO + 1, 0x10);
 }
@@ -1327,6 +1317,7 @@
 
 	RT_TRACE(rtlpriv, COMP_INTR, DBG_LOUD,
 		 ("add_msr:%x, rm_msr:%x\n", add_msr, rm_msr));
+
 	if (add_msr)
 		rtlpci->irq_mask[0] |= add_msr;
 	if (rm_msr)
@@ -1582,7 +1573,7 @@
 			 ("RTL819X Not boot from eeprom, check it !!"));
 	}
 
-	RT_PRINT_DATA(rtlpriv, COMP_INIT, DBG_LOUD, ("MAP\n"),
+	RT_PRINT_DATA(rtlpriv, COMP_INIT, DBG_DMESG, ("MAP\n"),
 		      hwinfo, HWSET_MAX_SIZE);
 
 	eeprom_id = *((u16 *)&hwinfo[0]);
@@ -1610,6 +1601,10 @@
 					     rtlefuse->autoload_failflag,
 					     hwinfo);
 
+	rtl8192ce_read_bt_coexist_info_from_hwpg(hw,
+						 rtlefuse->autoload_failflag,
+						 hwinfo);
+
 	rtlefuse->eeprom_channelplan = *(u8 *)&hwinfo[EEPROM_CHANNELPLAN];
 	rtlefuse->eeprom_version = *(u16 *)&hwinfo[EEPROM_VERSION];
 	rtlefuse->txpwr_fromeprom = true;
@@ -1618,6 +1613,9 @@
 	RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
 		 ("EEPROM Customer ID: 0x%2x\n", rtlefuse->eeprom_oemid));
 
+	/* set channel paln to world wide 13 */
+	rtlefuse->channel_plan = COUNTRY_CODE_WORLD_WIDE_13;
+
 	if (rtlhal->oem_id == RT_CID_DEFAULT) {
 		switch (rtlefuse->eeprom_oemid) {
 		case EEPROM_CID_DEFAULT:
@@ -1701,30 +1699,36 @@
 	} else {
 		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("Autoload ERR!!\n"));
 	}
-
 	_rtl92ce_hal_customized_behavior(hw);
 }
 
-void rtl92ce_update_hal_rate_table(struct ieee80211_hw *hw)
+static void rtl92ce_update_hal_rate_table(struct ieee80211_hw *hw,
+		struct ieee80211_sta *sta)
 {
 	struct rtl_priv *rtlpriv = rtl_priv(hw);
+	struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
 	struct rtl_phy *rtlphy = &(rtlpriv->phy);
 	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
-
-	u32 ratr_value = (u32) mac->basic_rates;
-	u8 *mcsrate = mac->mcs;
+	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+	u32 ratr_value;
 	u8 ratr_index = 0;
 	u8 nmode = mac->ht_enable;
-	u8 mimo_ps = 1;
+	u8 mimo_ps = IEEE80211_SMPS_OFF;
 	u16 shortgi_rate;
 	u32 tmp_ratr_value;
 	u8 curtxbw_40mhz = mac->bw_40;
-	u8 curshortgi_40mhz = mac->sgi_40;
-	u8 curshortgi_20mhz = mac->sgi_20;
+	u8 curshortgi_40mhz = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40) ?
+			       1 : 0;
+	u8 curshortgi_20mhz = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20) ?
+			       1 : 0;
 	enum wireless_mode wirelessmode = mac->mode;
 
-	ratr_value |= ((*(u16 *) (mcsrate))) << 12;
-
+	if (rtlhal->current_bandtype == BAND_ON_5G)
+		ratr_value = sta->supp_rates[1] << 4;
+	else
+		ratr_value = sta->supp_rates[0];
+	ratr_value |= (sta->ht_cap.mcs.rx_mask[1] << 20 |
+			sta->ht_cap.mcs.rx_mask[0] << 12);
 	switch (wirelessmode) {
 	case WIRELESS_MODE_B:
 		if (ratr_value & 0x0000000c)
@@ -1738,7 +1742,7 @@
 	case WIRELESS_MODE_N_24G:
 	case WIRELESS_MODE_N_5G:
 		nmode = 1;
-		if (mimo_ps == 0) {
+		if (mimo_ps == IEEE80211_SMPS_STATIC) {
 			ratr_value &= 0x0007F005;
 		} else {
 			u32 ratr_mask;
@@ -1761,10 +1765,19 @@
 		break;
 	}
 
-	ratr_value &= 0x0FFFFFFF;
+	if ((rtlpcipriv->bt_coexist.bt_coexistence) &&
+	    (rtlpcipriv->bt_coexist.bt_coexist_type == BT_CSR_BC4) &&
+	    (rtlpcipriv->bt_coexist.bt_cur_state) &&
+	    (rtlpcipriv->bt_coexist.bt_ant_isolation) &&
+	    ((rtlpcipriv->bt_coexist.bt_service == BT_SCO) ||
+	    (rtlpcipriv->bt_coexist.bt_service == BT_BUSY)))
+		ratr_value &= 0x0fffcfc0;
+	else
+		ratr_value &= 0x0FFFFFFF;
 
-	if (nmode && ((curtxbw_40mhz && curshortgi_40mhz) || (!curtxbw_40mhz &&
-		       curshortgi_20mhz))) {
+	if (nmode && ((curtxbw_40mhz &&
+			 curshortgi_40mhz) || (!curtxbw_40mhz &&
+					       curshortgi_20mhz))) {
 
 		ratr_value |= 0x10000000;
 		tmp_ratr_value = (ratr_value >> 12);
@@ -1784,24 +1797,42 @@
 		 ("%x\n", rtl_read_dword(rtlpriv, REG_ARFR0)));
 }
 
-void rtl92ce_update_hal_rate_mask(struct ieee80211_hw *hw, u8 rssi_level)
+static void rtl92ce_update_hal_rate_mask(struct ieee80211_hw *hw,
+		struct ieee80211_sta *sta, u8 rssi_level)
 {
 	struct rtl_priv *rtlpriv = rtl_priv(hw);
 	struct rtl_phy *rtlphy = &(rtlpriv->phy);
 	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
-	u32 ratr_bitmap = (u32) mac->basic_rates;
-	u8 *p_mcsrate = mac->mcs;
+	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+	struct rtl_sta_info *sta_entry = NULL;
+	u32 ratr_bitmap;
 	u8 ratr_index;
-	u8 curtxbw_40mhz = mac->bw_40;
-	u8 curshortgi_40mhz = mac->sgi_40;
-	u8 curshortgi_20mhz = mac->sgi_20;
-	enum wireless_mode wirelessmode = mac->mode;
+	u8 curtxbw_40mhz = (sta->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40)
+				? 1 : 0;
+	u8 curshortgi_40mhz = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40) ?
+				1 : 0;
+	u8 curshortgi_20mhz = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20) ?
+				1 : 0;
+	enum wireless_mode wirelessmode = 0;
 	bool shortgi = false;
 	u8 rate_mask[5];
 	u8 macid = 0;
-	u8 mimops = 1;
+	u8 mimo_ps = IEEE80211_SMPS_OFF;
 
-	ratr_bitmap |= (p_mcsrate[1] << 20) | (p_mcsrate[0] << 12);
+	sta_entry = (struct rtl_sta_info *) sta->drv_priv;
+	wirelessmode = sta_entry->wireless_mode;
+	if (mac->opmode == NL80211_IFTYPE_STATION)
+		curtxbw_40mhz = mac->bw_40;
+	else if (mac->opmode == NL80211_IFTYPE_AP ||
+		mac->opmode == NL80211_IFTYPE_ADHOC)
+		macid = sta->aid + 1;
+
+	if (rtlhal->current_bandtype == BAND_ON_5G)
+		ratr_bitmap = sta->supp_rates[1] << 4;
+	else
+		ratr_bitmap = sta->supp_rates[0];
+	ratr_bitmap |= (sta->ht_cap.mcs.rx_mask[1] << 20 |
+			sta->ht_cap.mcs.rx_mask[0] << 12);
 	switch (wirelessmode) {
 	case WIRELESS_MODE_B:
 		ratr_index = RATR_INX_WIRELESS_B;
@@ -1828,7 +1859,7 @@
 	case WIRELESS_MODE_N_5G:
 		ratr_index = RATR_INX_WIRELESS_NGB;
 
-		if (mimops == 0) {
+		if (mimo_ps == IEEE80211_SMPS_STATIC) {
 			if (rssi_level == 1)
 				ratr_bitmap &= 0x00070000;
 			else if (rssi_level == 2)
@@ -1892,8 +1923,8 @@
 	}
 	RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG,
 		 ("ratr_bitmap :%x\n", ratr_bitmap));
-	*(u32 *)&rate_mask = (ratr_bitmap & 0x0fffffff) |
-				       (ratr_index << 28);
+	*(u32 *)&rate_mask = EF4BYTE((ratr_bitmap & 0x0fffffff) |
+				     (ratr_index << 28));
 	rate_mask[4] = macid | (shortgi ? 0x20 : 0x00) | 0x80;
 	RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG, ("Rate_index:%x, "
 						 "ratr_val:%x, %x:%x:%x:%x:%x\n",
@@ -1902,6 +1933,20 @@
 						 rate_mask[2], rate_mask[3],
 						 rate_mask[4]));
 	rtl92c_fill_h2c_cmd(hw, H2C_RA_MASK, 5, rate_mask);
+
+	if (macid != 0)
+		sta_entry->ratr_index = ratr_index;
+}
+
+void rtl92ce_update_hal_rate_tbl(struct ieee80211_hw *hw,
+		struct ieee80211_sta *sta, u8 rssi_level)
+{
+	struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+	if (rtlpriv->dm.useramask)
+		rtl92ce_update_hal_rate_mask(hw, sta, rssi_level);
+	else
+		rtl92ce_update_hal_rate_table(hw, sta);
 }
 
 void rtl92ce_update_channel_access_setting(struct ieee80211_hw *hw)
@@ -1919,7 +1964,7 @@
 	rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SIFS, (u8 *)&sifs_timer);
 }
 
-bool rtl92ce_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 * valid)
+bool rtl92ce_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 *valid)
 {
 	struct rtl_priv *rtlpriv = rtl_priv(hw);
 	struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
@@ -1929,7 +1974,7 @@
 	bool actuallyset = false;
 	unsigned long flag;
 
-	if ((rtlpci->up_first_time == 1) || (rtlpci->being_init_adapter))
+	if (rtlpci->being_init_adapter)
 		return false;
 
 	if (ppsc->swrf_processing)
@@ -1946,12 +1991,6 @@
 
 	cur_rfstate = ppsc->rfpwr_state;
 
-	if ((ppsc->reg_rfps_level & RT_RF_OFF_LEVL_ASPM) &&
-	    RT_IN_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_ASPM)) {
-		rtlpriv->intf_ops->disable_aspm(hw);
-		RT_CLEAR_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_ASPM);
-	}
-
 	rtl_write_byte(rtlpriv, REG_MAC_PINMUX_CFG, rtl_read_byte(rtlpriv,
 		       REG_MAC_PINMUX_CFG)&~(BIT(3)));
 
@@ -1976,38 +2015,13 @@
 	}
 
 	if (actuallyset) {
-		if (e_rfpowerstate_toset == ERFON) {
-			if ((ppsc->reg_rfps_level & RT_RF_OFF_LEVL_ASPM) &&
-			    RT_IN_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_ASPM)) {
-				rtlpriv->intf_ops->disable_aspm(hw);
-				RT_CLEAR_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_ASPM);
-			}
-		}
-
 		spin_lock_irqsave(&rtlpriv->locks.rf_ps_lock, flag);
 		ppsc->rfchange_inprogress = false;
 		spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock, flag);
-
-		if (e_rfpowerstate_toset == ERFOFF) {
-			if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_ASPM) {
-				rtlpriv->intf_ops->enable_aspm(hw);
-				RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_ASPM);
-			}
-		}
-
-	} else if (e_rfpowerstate_toset == ERFOFF || cur_rfstate == ERFOFF) {
+	} else {
 		if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_HALT_NIC)
 			RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC);
 
-		if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_ASPM) {
-			rtlpriv->intf_ops->enable_aspm(hw);
-			RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_ASPM);
-		}
-
-		spin_lock_irqsave(&rtlpriv->locks.rf_ps_lock, flag);
-		ppsc->rfchange_inprogress = false;
-		spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock, flag);
-	} else {
 		spin_lock_irqsave(&rtlpriv->locks.rf_ps_lock, flag);
 		ppsc->rfchange_inprogress = false;
 		spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock, flag);
@@ -2086,15 +2100,31 @@
 				macaddr = cam_const_broad;
 				entry_id = key_index;
 			} else {
+				if (mac->opmode == NL80211_IFTYPE_AP) {
+					entry_id = rtl_cam_get_free_entry(hw,
+								 p_macaddr);
+					if (entry_id >=  TOTAL_CAM_ENTRY) {
+						RT_TRACE(rtlpriv, COMP_SEC,
+						     DBG_EMERG,
+						     ("Can not find free hw"
+						     " security cam entry\n"));
+						return;
+					}
+				} else {
+					entry_id = CAM_PAIRWISE_KEY_POSITION;
+				}
+
 				key_index = PAIRWISE_KEYIDX;
-				entry_id = CAM_PAIRWISE_KEY_POSITION;
 				is_pairwise = true;
 			}
 		}
 
 		if (rtlpriv->sec.key_len[key_index] == 0) {
 			RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
-				 ("delete one entry\n"));
+				 ("delete one entry, entry_id is %d\n",
+				 entry_id));
+			if (mac->opmode == NL80211_IFTYPE_AP)
+				rtl_cam_del_entry(hw, p_macaddr);
 			rtl_cam_delete_one_entry(hw, p_macaddr, entry_id);
 		} else {
 			RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD,
@@ -2146,3 +2176,132 @@
 		}
 	}
 }
+
+static void rtl8192ce_bt_var_init(struct ieee80211_hw *hw)
+{
+	struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
+
+	rtlpcipriv->bt_coexist.bt_coexistence =
+			rtlpcipriv->bt_coexist.eeprom_bt_coexist;
+	rtlpcipriv->bt_coexist.bt_ant_num =
+			rtlpcipriv->bt_coexist.eeprom_bt_ant_num;
+	rtlpcipriv->bt_coexist.bt_coexist_type =
+			rtlpcipriv->bt_coexist.eeprom_bt_type;
+
+	if (rtlpcipriv->bt_coexist.reg_bt_iso == 2)
+		rtlpcipriv->bt_coexist.bt_ant_isolation =
+			rtlpcipriv->bt_coexist.eeprom_bt_ant_isolation;
+	else
+		rtlpcipriv->bt_coexist.bt_ant_isolation =
+			rtlpcipriv->bt_coexist.reg_bt_iso;
+
+	rtlpcipriv->bt_coexist.bt_radio_shared_type =
+			rtlpcipriv->bt_coexist.eeprom_bt_radio_shared;
+
+	if (rtlpcipriv->bt_coexist.bt_coexistence) {
+
+		if (rtlpcipriv->bt_coexist.reg_bt_sco == 1)
+			rtlpcipriv->bt_coexist.bt_service = BT_OTHER_ACTION;
+		else if (rtlpcipriv->bt_coexist.reg_bt_sco == 2)
+			rtlpcipriv->bt_coexist.bt_service = BT_SCO;
+		else if (rtlpcipriv->bt_coexist.reg_bt_sco == 4)
+			rtlpcipriv->bt_coexist.bt_service = BT_BUSY;
+		else if (rtlpcipriv->bt_coexist.reg_bt_sco == 5)
+			rtlpcipriv->bt_coexist.bt_service = BT_OTHERBUSY;
+		else
+			rtlpcipriv->bt_coexist.bt_service = BT_IDLE;
+
+		rtlpcipriv->bt_coexist.bt_edca_ul = 0;
+		rtlpcipriv->bt_coexist.bt_edca_dl = 0;
+		rtlpcipriv->bt_coexist.bt_rssi_state = 0xff;
+	}
+}
+
+void rtl8192ce_read_bt_coexist_info_from_hwpg(struct ieee80211_hw *hw,
+					      bool auto_load_fail, u8 *hwinfo)
+{
+	struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
+	u8 value;
+
+	if (!auto_load_fail) {
+		rtlpcipriv->bt_coexist.eeprom_bt_coexist =
+					((hwinfo[RF_OPTION1] & 0xe0) >> 5);
+		value = hwinfo[RF_OPTION4];
+		rtlpcipriv->bt_coexist.eeprom_bt_type = ((value & 0xe) >> 1);
+		rtlpcipriv->bt_coexist.eeprom_bt_ant_num = (value & 0x1);
+		rtlpcipriv->bt_coexist.eeprom_bt_ant_isolation =
+							 ((value & 0x10) >> 4);
+		rtlpcipriv->bt_coexist.eeprom_bt_radio_shared =
+							 ((value & 0x20) >> 5);
+	} else {
+		rtlpcipriv->bt_coexist.eeprom_bt_coexist = 0;
+		rtlpcipriv->bt_coexist.eeprom_bt_type = BT_2WIRE;
+		rtlpcipriv->bt_coexist.eeprom_bt_ant_num = ANT_X2;
+		rtlpcipriv->bt_coexist.eeprom_bt_ant_isolation = 0;
+		rtlpcipriv->bt_coexist.eeprom_bt_radio_shared = BT_RADIO_SHARED;
+	}
+
+	rtl8192ce_bt_var_init(hw);
+}
+
+void rtl8192ce_bt_reg_init(struct ieee80211_hw *hw)
+{
+	struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
+
+	/* 0:Low, 1:High, 2:From Efuse. */
+	rtlpcipriv->bt_coexist.reg_bt_iso = 2;
+	/* 0:Idle, 1:None-SCO, 2:SCO, 3:From Counter. */
+	rtlpcipriv->bt_coexist.reg_bt_sco = 3;
+	/* 0:Disable BT control A-MPDU, 1:Enable BT control A-MPDU. */
+	rtlpcipriv->bt_coexist.reg_bt_sco = 0;
+}
+
+
+void rtl8192ce_bt_hw_init(struct ieee80211_hw *hw)
+{
+	struct rtl_priv *rtlpriv = rtl_priv(hw);
+	struct rtl_phy *rtlphy = &(rtlpriv->phy);
+	struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
+
+	u8 u1_tmp;
+
+	if (rtlpcipriv->bt_coexist.bt_coexistence &&
+	    ((rtlpcipriv->bt_coexist.bt_coexist_type == BT_CSR_BC4) ||
+	      rtlpcipriv->bt_coexist.bt_coexist_type == BT_CSR_BC8)) {
+
+		if (rtlpcipriv->bt_coexist.bt_ant_isolation)
+			rtl_write_byte(rtlpriv, REG_GPIO_MUXCFG, 0xa0);
+
+		u1_tmp = rtl_read_byte(rtlpriv, 0x4fd) &
+			 BIT_OFFSET_LEN_MASK_32(0, 1);
+		u1_tmp = u1_tmp |
+			 ((rtlpcipriv->bt_coexist.bt_ant_isolation == 1) ?
+			 0 : BIT_OFFSET_LEN_MASK_32(1, 1)) |
+			 ((rtlpcipriv->bt_coexist.bt_service == BT_SCO) ?
+			 0 : BIT_OFFSET_LEN_MASK_32(2, 1));
+		rtl_write_byte(rtlpriv, 0x4fd, u1_tmp);
+
+		rtl_write_dword(rtlpriv, REG_BT_COEX_TABLE+4, 0xaaaa9aaa);
+		rtl_write_dword(rtlpriv, REG_BT_COEX_TABLE+8, 0xffbd0040);
+		rtl_write_dword(rtlpriv, REG_BT_COEX_TABLE+0xc, 0x40000010);
+
+		/* Config to 1T1R. */
+		if (rtlphy->rf_type == RF_1T1R) {
+			u1_tmp = rtl_read_byte(rtlpriv, ROFDM0_TRXPATHENABLE);
+			u1_tmp &= ~(BIT_OFFSET_LEN_MASK_32(1, 1));
+			rtl_write_byte(rtlpriv, ROFDM0_TRXPATHENABLE, u1_tmp);
+
+			u1_tmp = rtl_read_byte(rtlpriv, ROFDM1_TRXPATHENABLE);
+			u1_tmp &= ~(BIT_OFFSET_LEN_MASK_32(1, 1));
+			rtl_write_byte(rtlpriv, ROFDM1_TRXPATHENABLE, u1_tmp);
+		}
+	}
+}
+
+void rtl92ce_suspend(struct ieee80211_hw *hw)
+{
+}
+
+void rtl92ce_resume(struct ieee80211_hw *hw)
+{
+}
diff -druN linux-2.6.39-libre/drivers/net/wireless/rtlwifi/rtl8192ce/hw.h linux-3.0-rc7-libre/drivers/net/wireless/rtlwifi/rtl8192ce/hw.h
--- linux-2.6.39-libre/drivers/net/wireless/rtlwifi/rtl8192ce/hw.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/rtlwifi/rtl8192ce/hw.h	2011-07-11 19:51:52.000000000 -0400
@@ -30,7 +30,18 @@
 #ifndef __RTL92CE_HW_H__
 #define __RTL92CE_HW_H__
 
-#define H2C_RA_MASK	6
+static inline u8 _rtl92c_get_chnl_group(u8 chnl)
+{
+	u8 group;
+
+	if (chnl < 3)
+		group = 0;
+	else if (chnl < 9)
+		group = 1;
+	else
+		group = 2;
+	return group;
+}
 
 void rtl92ce_get_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val);
 void rtl92ce_read_eeprom_info(struct ieee80211_hw *hw);
@@ -41,28 +52,27 @@
 void rtl92ce_enable_interrupt(struct ieee80211_hw *hw);
 void rtl92ce_disable_interrupt(struct ieee80211_hw *hw);
 int rtl92ce_set_network_type(struct ieee80211_hw *hw, enum nl80211_iftype type);
+void rtl92ce_set_check_bssid(struct ieee80211_hw *hw, bool check_bssid);
 void rtl92ce_set_qos(struct ieee80211_hw *hw, int aci);
 void rtl92ce_set_beacon_related_registers(struct ieee80211_hw *hw);
 void rtl92ce_set_beacon_interval(struct ieee80211_hw *hw);
 void rtl92ce_update_interrupt_mask(struct ieee80211_hw *hw,
 				   u32 add_msr, u32 rm_msr);
 void rtl92ce_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val);
-void rtl92ce_update_hal_rate_table(struct ieee80211_hw *hw);
-void rtl92ce_update_hal_rate_mask(struct ieee80211_hw *hw, u8 rssi_level);
+void rtl92ce_update_hal_rate_tbl(struct ieee80211_hw *hw,
+				 struct ieee80211_sta *sta, u8 rssi_level);
 void rtl92ce_update_channel_access_setting(struct ieee80211_hw *hw);
 bool rtl92ce_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 *valid);
 void rtl92ce_enable_hw_security_config(struct ieee80211_hw *hw);
 void rtl92ce_set_key(struct ieee80211_hw *hw, u32 key_index,
 		     u8 *p_macaddr, bool is_group, u8 enc_algo,
 		     bool is_wepkey, bool clear_all);
-bool _rtl92ce_phy_config_mac_with_headerfile(struct ieee80211_hw *hw);
-void rtl92c_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool b_dl_finished);
-void rtl92c_set_fw_pwrmode_cmd(struct ieee80211_hw *hw, u8 mode);
-void rtl92c_set_fw_joinbss_report_cmd(struct ieee80211_hw *hw, u8 mstatus);
-int rtl92c_download_fw(struct ieee80211_hw *hw);
-void rtl92c_firmware_selfreset(struct ieee80211_hw *hw);
-void rtl92c_fill_h2c_cmd(struct ieee80211_hw *hw,
-			 u8 element_id, u32 cmd_len, u8 *p_cmdbuffer);
-bool rtl92ce_phy_mac_config(struct ieee80211_hw *hw);
+
+void rtl8192ce_read_bt_coexist_info_from_hwpg(struct ieee80211_hw *hw,
+			bool autoload_fail, u8 *hwinfo);
+void rtl8192ce_bt_reg_init(struct ieee80211_hw *hw);
+void rtl8192ce_bt_hw_init(struct ieee80211_hw *hw);
+void rtl92ce_suspend(struct ieee80211_hw *hw);
+void rtl92ce_resume(struct ieee80211_hw *hw);
 
 #endif
diff -druN linux-2.6.39-libre/drivers/net/wireless/rtlwifi/rtl8192ce/led.c linux-3.0-rc7-libre/drivers/net/wireless/rtlwifi/rtl8192ce/led.c
--- linux-2.6.39-libre/drivers/net/wireless/rtlwifi/rtl8192ce/led.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/rtlwifi/rtl8192ce/led.c	2011-07-11 19:51:52.000000000 -0400
@@ -32,6 +32,14 @@
 #include "reg.h"
 #include "led.h"
 
+static void _rtl92ce_init_led(struct ieee80211_hw *hw,
+			      struct rtl_led *pled, enum rtl_led_pin ledpin)
+{
+	pled->hw = hw;
+	pled->ledpin = ledpin;
+	pled->ledon = false;
+}
+
 void rtl92ce_sw_led_on(struct ieee80211_hw *hw, struct rtl_led *pled)
 {
 	u8 ledcfg;
@@ -97,13 +105,12 @@
 
 void rtl92ce_init_sw_leds(struct ieee80211_hw *hw)
 {
+	struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
+	_rtl92ce_init_led(hw, &(pcipriv->ledctl.sw_led0), LED_PIN_LED0);
+	_rtl92ce_init_led(hw, &(pcipriv->ledctl.sw_led1), LED_PIN_LED1);
 }
 
-void rtl92ce_deinit_sw_leds(struct ieee80211_hw *hw)
-{
-}
-
-void _rtl92ce_sw_led_control(struct ieee80211_hw *hw,
+static void _rtl92ce_sw_led_control(struct ieee80211_hw *hw,
 				    enum led_ctl_mode ledaction)
 {
 	struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
@@ -138,7 +145,7 @@
 	     ledaction == LED_CTL_POWER_ON)) {
 		return;
 	}
-	RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD, ("ledaction %d,\n",
+	RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD, ("ledaction %d.\n",
 				ledaction));
 	_rtl92ce_sw_led_control(hw, ledaction);
 }
diff -druN linux-2.6.39-libre/drivers/net/wireless/rtlwifi/rtl8192ce/led.h linux-3.0-rc7-libre/drivers/net/wireless/rtlwifi/rtl8192ce/led.h
--- linux-2.6.39-libre/drivers/net/wireless/rtlwifi/rtl8192ce/led.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/rtlwifi/rtl8192ce/led.h	2011-07-11 19:51:52.000000000 -0400
@@ -31,11 +31,8 @@
 #define __RTL92CE_LED_H__
 
 void rtl92ce_init_sw_leds(struct ieee80211_hw *hw);
-void rtl92ce_deinit_sw_leds(struct ieee80211_hw *hw);
 void rtl92ce_sw_led_on(struct ieee80211_hw *hw, struct rtl_led *pled);
 void rtl92ce_sw_led_off(struct ieee80211_hw *hw, struct rtl_led *pled);
 void rtl92ce_led_control(struct ieee80211_hw *hw, enum led_ctl_mode ledaction);
-void _rtl92ce_sw_led_control(struct ieee80211_hw *hw,
-				    enum led_ctl_mode ledaction);
 
 #endif
diff -druN linux-2.6.39-libre/drivers/net/wireless/rtlwifi/rtl8192ce/phy.c linux-3.0-rc7-libre/drivers/net/wireless/rtlwifi/rtl8192ce/phy.c
--- linux-2.6.39-libre/drivers/net/wireless/rtlwifi/rtl8192ce/phy.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/rtlwifi/rtl8192ce/phy.c	2011-07-11 19:51:52.000000000 -0400
@@ -38,7 +38,9 @@
 #include "dm.h"
 #include "table.h"
 
-u32 rtl92ce_phy_query_rf_reg(struct ieee80211_hw *hw,
+static bool _rtl92c_phy_config_mac_with_headerfile(struct ieee80211_hw *hw);
+
+u32 rtl92c_phy_query_rf_reg(struct ieee80211_hw *hw,
 			    enum radio_path rfpath, u32 regaddr, u32 bitmask)
 {
 	struct rtl_priv *rtlpriv = rtl_priv(hw);
@@ -73,9 +75,47 @@
 	return readback_value;
 }
 
+bool rtl92c_phy_mac_config(struct ieee80211_hw *hw)
+{
+	struct rtl_priv *rtlpriv = rtl_priv(hw);
+	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+	bool is92c = IS_92C_SERIAL(rtlhal->version);
+	bool rtstatus = _rtl92c_phy_config_mac_with_headerfile(hw);
+
+	if (is92c)
+		rtl_write_byte(rtlpriv, 0x14, 0x71);
+	return rtstatus;
+}
+
+bool rtl92c_phy_bb_config(struct ieee80211_hw *hw)
+{
+	bool rtstatus = true;
+	struct rtl_priv *rtlpriv = rtl_priv(hw);
+	u16 regval;
+	u32 regvaldw;
+	u8 reg_hwparafile = 1;
+
+	_rtl92c_phy_init_bb_rf_register_definition(hw);
+	regval = rtl_read_word(rtlpriv, REG_SYS_FUNC_EN);
+	rtl_write_word(rtlpriv, REG_SYS_FUNC_EN,
+		       regval | BIT(13) | BIT(0) | BIT(1));
+	rtl_write_byte(rtlpriv, REG_AFE_PLL_CTRL, 0x83);
+	rtl_write_byte(rtlpriv, REG_AFE_PLL_CTRL + 1, 0xdb);
+	rtl_write_byte(rtlpriv, REG_RF_CTRL, RF_EN | RF_RSTB | RF_SDMRSTB);
+	rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN,
+		       FEN_PPLL | FEN_PCIEA | FEN_DIO_PCIE |
+		       FEN_BB_GLB_RSTn | FEN_BBRSTB);
+	rtl_write_byte(rtlpriv, REG_AFE_XTAL_CTRL + 1, 0x80);
+	regvaldw = rtl_read_dword(rtlpriv, REG_LEDCFG0);
+	rtl_write_dword(rtlpriv, REG_LEDCFG0, regvaldw | BIT(23));
+	if (reg_hwparafile == 1)
+		rtstatus = _rtl92c_phy_bb8192c_config_parafile(hw);
+	return rtstatus;
+}
+
 void rtl92ce_phy_set_rf_reg(struct ieee80211_hw *hw,
-			   enum radio_path rfpath,
-			   u32 regaddr, u32 bitmask, u32 data)
+			    enum radio_path rfpath,
+			    u32 regaddr, u32 bitmask, u32 data)
 {
 	struct rtl_priv *rtlpriv = rtl_priv(hw);
 	struct rtl_phy *rtlphy = &(rtlpriv->phy);
@@ -121,45 +161,7 @@
 					       bitmask, data, rfpath));
 }
 
-bool rtl92ce_phy_mac_config(struct ieee80211_hw *hw)
-{
-	struct rtl_priv *rtlpriv = rtl_priv(hw);
-	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
-	bool is92c = IS_92C_SERIAL(rtlhal->version);
-	bool rtstatus = _rtl92ce_phy_config_mac_with_headerfile(hw);
-
-	if (is92c)
-		rtl_write_byte(rtlpriv, 0x14, 0x71);
-	return rtstatus;
-}
-
-bool rtl92ce_phy_bb_config(struct ieee80211_hw *hw)
-{
-	bool rtstatus = true;
-	struct rtl_priv *rtlpriv = rtl_priv(hw);
-	u16 regval;
-	u32 regvaldw;
-	u8 reg_hwparafile = 1;
-
-	_rtl92c_phy_init_bb_rf_register_definition(hw);
-	regval = rtl_read_word(rtlpriv, REG_SYS_FUNC_EN);
-	rtl_write_word(rtlpriv, REG_SYS_FUNC_EN,
-		       regval | BIT(13) | BIT(0) | BIT(1));
-	rtl_write_byte(rtlpriv, REG_AFE_PLL_CTRL, 0x83);
-	rtl_write_byte(rtlpriv, REG_AFE_PLL_CTRL + 1, 0xdb);
-	rtl_write_byte(rtlpriv, REG_RF_CTRL, RF_EN | RF_RSTB | RF_SDMRSTB);
-	rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN,
-		       FEN_PPLL | FEN_PCIEA | FEN_DIO_PCIE |
-		       FEN_BB_GLB_RSTn | FEN_BBRSTB);
-	rtl_write_byte(rtlpriv, REG_AFE_XTAL_CTRL + 1, 0x80);
-	regvaldw = rtl_read_dword(rtlpriv, REG_LEDCFG0);
-	rtl_write_dword(rtlpriv, REG_LEDCFG0, regvaldw | BIT(23));
-	if (reg_hwparafile == 1)
-		rtstatus = _rtl92c_phy_bb8192c_config_parafile(hw);
-	return rtstatus;
-}
-
-bool _rtl92ce_phy_config_mac_with_headerfile(struct ieee80211_hw *hw)
+static bool _rtl92c_phy_config_mac_with_headerfile(struct ieee80211_hw *hw)
 {
 	struct rtl_priv *rtlpriv = rtl_priv(hw);
 	u32 i;
@@ -177,7 +179,7 @@
 }
 
 bool _rtl92ce_phy_config_bb_with_headerfile(struct ieee80211_hw *hw,
-						  u8 configtype)
+					    u8 configtype)
 {
 	int i;
 	u32 *phy_regarray_table;
@@ -236,7 +238,7 @@
 }
 
 bool _rtl92ce_phy_config_bb_with_pgheaderfile(struct ieee80211_hw *hw,
-						    u8 configtype)
+					      u8 configtype)
 {
 	struct rtl_priv *rtlpriv = rtl_priv(hw);
 	int i;
@@ -274,7 +276,7 @@
 	return true;
 }
 
-bool rtl92ce_phy_config_rf_with_headerfile(struct ieee80211_hw *hw,
+bool rtl92c_phy_config_rf_with_headerfile(struct ieee80211_hw *hw,
 					  enum radio_path rfpath)
 {
 
@@ -378,8 +380,10 @@
 		  rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20 ?
 		  "20MHz" : "40MHz"))
 
-	    if (is_hal_stop(rtlhal))
+	if (is_hal_stop(rtlhal)) {
+		rtlphy->set_bwmode_inprogress = false;
 		return;
+	}
 
 	reg_bw_opmode = rtl_read_byte(rtlpriv, REG_BWOPMODE);
 	reg_prsr_rsc = rtl_read_byte(rtlpriv, REG_RRSR + 2);
@@ -389,16 +393,13 @@
 		reg_bw_opmode |= BW_OPMODE_20MHZ;
 		rtl_write_byte(rtlpriv, REG_BWOPMODE, reg_bw_opmode);
 		break;
-
 	case HT_CHANNEL_WIDTH_20_40:
 		reg_bw_opmode &= ~BW_OPMODE_20MHZ;
 		rtl_write_byte(rtlpriv, REG_BWOPMODE, reg_bw_opmode);
-
 		reg_prsr_rsc =
 		    (reg_prsr_rsc & 0x90) | (mac->cur_40_prime_sc << 5);
 		rtl_write_byte(rtlpriv, REG_RRSR + 2, reg_prsr_rsc);
 		break;
-
 	default:
 		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
 			 ("unknown bandwidth: %#X\n", rtlphy->current_chan_bw));
@@ -414,10 +415,12 @@
 	case HT_CHANNEL_WIDTH_20_40:
 		rtl_set_bbreg(hw, RFPGA0_RFMOD, BRFMOD, 0x1);
 		rtl_set_bbreg(hw, RFPGA1_RFMOD, BRFMOD, 0x1);
+
 		rtl_set_bbreg(hw, RCCK0_SYSTEM, BCCK_SIDEBAND,
 			      (mac->cur_40_prime_sc >> 1));
 		rtl_set_bbreg(hw, ROFDM1_LSTF, 0xC00, mac->cur_40_prime_sc);
 		rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER2, BIT(10), 0);
+
 		rtl_set_bbreg(hw, 0x818, (BIT(26) | BIT(27)),
 			      (mac->cur_40_prime_sc ==
 			       HAL_PRIME_CHNL_OFFSET_LOWER) ? 2 : 1);
@@ -427,7 +430,7 @@
 			 ("unknown bandwidth: %#X\n", rtlphy->current_chan_bw));
 		break;
 	}
-	rtl92c_phy_rf6052_set_bandwidth(hw, rtlphy->current_chan_bw);
+	rtl92ce_phy_rf6052_set_bandwidth(hw, rtlphy->current_chan_bw);
 	rtlphy->set_bwmode_inprogress = false;
 	RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, ("<==\n"));
 }
@@ -477,6 +480,36 @@
 	}
 }
 
+static void _rtl92ce_phy_set_rf_sleep(struct ieee80211_hw *hw)
+{
+	u32 u4b_tmp;
+	u8 delay = 5;
+	struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+	rtl_write_byte(rtlpriv, REG_TXPAUSE, 0xFF);
+	rtl_set_rfreg(hw, RF90_PATH_A, 0x00, RFREG_OFFSET_MASK, 0x00);
+	rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x40);
+	u4b_tmp = rtl_get_rfreg(hw, RF90_PATH_A, 0, RFREG_OFFSET_MASK);
+	while (u4b_tmp != 0 && delay > 0) {
+		rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x0);
+		rtl_set_rfreg(hw, RF90_PATH_A, 0x00, RFREG_OFFSET_MASK, 0x00);
+		rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x40);
+		u4b_tmp = rtl_get_rfreg(hw, RF90_PATH_A, 0, RFREG_OFFSET_MASK);
+		delay--;
+	}
+	if (delay == 0) {
+		rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x00);
+		rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2);
+		rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3);
+		rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00);
+		RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE,
+			 ("Switch RF timeout !!!.\n"));
+		return;
+	}
+	rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2);
+	rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x22);
+}
+
 static bool _rtl92ce_phy_set_rf_power_state(struct ieee80211_hw *hw,
 					    enum rf_pwrstate rfpwr_state)
 {
@@ -523,33 +556,6 @@
 			break;
 		}
 	case ERFOFF:{
-			for (queue_id = 0, i = 0;
-			     queue_id < RTL_PCI_MAX_TX_QUEUE_COUNT;) {
-				ring = &pcipriv->dev.tx_ring[queue_id];
-				if (skb_queue_len(&ring->queue) == 0 ||
-				    queue_id == BEACON_QUEUE) {
-					queue_id++;
-					continue;
-				} else {
-					RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
-						 ("eRf Off/Sleep: %d times "
-						  "TcbBusyQueue[%d] "
-						  "=%d before doze!\n", (i + 1),
-						  queue_id,
-						  skb_queue_len(&ring->queue)));
-					udelay(10);
-					i++;
-				}
-				if (i >= MAX_DOZE_WAITING_TIMES_9x) {
-					RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
-						 ("\nERFOFF: %d times "
-						  "TcbBusyQueue[%d] = %d !\n",
-						  MAX_DOZE_WAITING_TIMES_9x,
-						  queue_id,
-						  skb_queue_len(&ring->queue)));
-					break;
-				}
-			}
 			if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_HALT_NIC) {
 				RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
 					 ("IPS Set eRf nic disable\n"));
@@ -581,6 +587,7 @@
 						  "TcbBusyQueue[%d] =%d before "
 						  "doze!\n", (i + 1), queue_id,
 						  skb_queue_len(&ring->queue)));
+
 					udelay(10);
 					i++;
 				}
@@ -599,7 +606,7 @@
 				  jiffies_to_msecs(jiffies -
 						   ppsc->last_awake_jiffies)));
 			ppsc->last_sleep_jiffies = jiffies;
-			_rtl92c_phy_set_rf_sleep(hw);
+			_rtl92ce_phy_set_rf_sleep(hw);
 			break;
 		}
 	default:
@@ -614,10 +621,11 @@
 	return bresult;
 }
 
-bool rtl92ce_phy_set_rf_power_state(struct ieee80211_hw *hw,
+bool rtl92c_phy_set_rf_power_state(struct ieee80211_hw *hw,
 				   enum rf_pwrstate rfpwr_state)
 {
 	struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
+
 	bool bresult = false;
 
 	if (rfpwr_state == ppsc->rfpwr_state)
diff -druN linux-2.6.39-libre/drivers/net/wireless/rtlwifi/rtl8192ce/phy.h linux-3.0-rc7-libre/drivers/net/wireless/rtlwifi/rtl8192ce/phy.h
--- linux-2.6.39-libre/drivers/net/wireless/rtlwifi/rtl8192ce/phy.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/rtlwifi/rtl8192ce/phy.h	2011-07-11 19:51:52.000000000 -0400
@@ -39,6 +39,7 @@
 #define RT_CANNOT_IO(hw)		false
 #define HIGHPOWER_RADIOA_ARRAYLEN	22
 
+#define IQK_ADDA_REG_NUM		16
 #define MAX_TOLERANCE			5
 #define	IQK_DELAY_TIME			1
 
@@ -56,6 +57,8 @@
 #define IQK_ADDA_REG_NUM		16
 #define IQK_MAC_REG_NUM			4
 
+#define IQK_DELAY_TIME			1
+
 #define RF90_PATH_MAX			2
 
 #define CT_OFFSET_MAC_ADDR		0X16
@@ -76,7 +79,7 @@
 #define CT_OFFSET_CUSTOMER_ID		0x7F
 
 #define RTL92C_MAX_PATH_NUM		2
-#define LLT_LAST_ENTRY_OF_TX_PKT_BUFFER	255
+
 enum swchnlcmd_id {
 	CMDID_END,
 	CMDID_SET_TXPOWEROWER_LEVEL,
@@ -184,43 +187,44 @@
 	u32 mcs_original_offset[4][16];
 };
 
-extern u32 rtl92c_phy_query_bb_reg(struct ieee80211_hw *hw,
+bool rtl92c_phy_bb_config(struct ieee80211_hw *hw);
+u32 rtl92c_phy_query_bb_reg(struct ieee80211_hw *hw,
 				   u32 regaddr, u32 bitmask);
-extern void rtl92c_phy_set_bb_reg(struct ieee80211_hw *hw,
+void rtl92c_phy_set_bb_reg(struct ieee80211_hw *hw,
 				  u32 regaddr, u32 bitmask, u32 data);
-extern u32 rtl92c_phy_query_rf_reg(struct ieee80211_hw *hw,
+u32 rtl92c_phy_query_rf_reg(struct ieee80211_hw *hw,
 				   enum radio_path rfpath, u32 regaddr,
 				   u32 bitmask);
 extern void rtl92ce_phy_set_rf_reg(struct ieee80211_hw *hw,
-				  enum radio_path rfpath, u32 regaddr,
-				  u32 bitmask, u32 data);
-extern bool rtl92c_phy_mac_config(struct ieee80211_hw *hw);
+				   enum radio_path rfpath, u32 regaddr,
+				   u32 bitmask, u32 data);
+bool rtl92c_phy_mac_config(struct ieee80211_hw *hw);
 bool rtl92ce_phy_bb_config(struct ieee80211_hw *hw);
-extern bool rtl92c_phy_rf_config(struct ieee80211_hw *hw);
-extern bool rtl92c_phy_config_rf_with_feaderfile(struct ieee80211_hw *hw,
+bool rtl92c_phy_rf_config(struct ieee80211_hw *hw);
+bool rtl92c_phy_config_rf_with_feaderfile(struct ieee80211_hw *hw,
 						 enum radio_path rfpath);
-extern void rtl92c_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw);
-extern void rtl92c_phy_get_txpower_level(struct ieee80211_hw *hw,
+void rtl92c_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw);
+void rtl92c_phy_get_txpower_level(struct ieee80211_hw *hw,
 					 long *powerlevel);
-extern void rtl92c_phy_set_txpower_level(struct ieee80211_hw *hw, u8 channel);
-extern bool rtl92c_phy_update_txpower_dbm(struct ieee80211_hw *hw,
+void rtl92c_phy_set_txpower_level(struct ieee80211_hw *hw, u8 channel);
+bool rtl92c_phy_update_txpower_dbm(struct ieee80211_hw *hw,
 					  long power_indbm);
-extern void rtl92c_phy_scan_operation_backup(struct ieee80211_hw *hw,
+void rtl92c_phy_scan_operation_backup(struct ieee80211_hw *hw,
 					     u8 operation);
-extern void rtl92c_phy_set_bw_mode_callback(struct ieee80211_hw *hw);
-extern void rtl92c_phy_set_bw_mode(struct ieee80211_hw *hw,
+void rtl92c_phy_set_bw_mode(struct ieee80211_hw *hw,
 				   enum nl80211_channel_type ch_type);
-extern void rtl92c_phy_sw_chnl_callback(struct ieee80211_hw *hw);
-extern u8 rtl92c_phy_sw_chnl(struct ieee80211_hw *hw);
-extern void rtl92c_phy_iq_calibrate(struct ieee80211_hw *hw, bool b_recovery);
-extern void rtl92c_phy_set_beacon_hw_reg(struct ieee80211_hw *hw,
+void rtl92c_phy_sw_chnl_callback(struct ieee80211_hw *hw);
+u8 rtl92c_phy_sw_chnl(struct ieee80211_hw *hw);
+void rtl92c_phy_iq_calibrate(struct ieee80211_hw *hw, bool b_recovery);
+void rtl92c_phy_set_beacon_hw_reg(struct ieee80211_hw *hw,
 					 u16 beaconinterval);
 void rtl92c_phy_ap_calibrate(struct ieee80211_hw *hw, char delta);
 void rtl92c_phy_lc_calibrate(struct ieee80211_hw *hw);
+void _rtl92ce_phy_lc_calibrate(struct ieee80211_hw *hw, bool is2t);
 void rtl92c_phy_set_rfpath_switch(struct ieee80211_hw *hw, bool bmain);
 bool rtl92c_phy_config_rf_with_headerfile(struct ieee80211_hw *hw,
 					  enum radio_path rfpath);
-extern bool rtl8192_phy_check_is_legal_rfpath(struct ieee80211_hw *hw,
+bool rtl8192_phy_check_is_legal_rfpath(struct ieee80211_hw *hw,
 					      u32 rfpath);
 bool rtl92c_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype);
 bool rtl92ce_phy_set_rf_power_state(struct ieee80211_hw *hw,
@@ -237,9 +241,6 @@
 void _rtl92c_phy_rf_serial_write(struct ieee80211_hw *hw,
 					enum radio_path rfpath, u32 offset,
 					u32 data);
-void _rtl92c_store_pwrIndex_diffrate_offset(struct ieee80211_hw *hw,
-						   u32 regaddr, u32 bitmask,
-						   u32 data);
 void _rtl92c_phy_fw_rf_serial_write(struct ieee80211_hw *hw,
 					   enum radio_path rfpath, u32 offset,
 					   u32 data);
@@ -250,5 +251,12 @@
 void _rtl92c_phy_init_bb_rf_register_definition(struct ieee80211_hw *hw);
 bool _rtl92c_phy_bb8192c_config_parafile(struct ieee80211_hw *hw);
 void _rtl92c_phy_set_rf_sleep(struct ieee80211_hw *hw);
+bool rtl92c_phy_set_rf_power_state(struct ieee80211_hw *hw,
+				   enum rf_pwrstate rfpwr_state);
+bool _rtl92ce_phy_config_bb_with_headerfile(struct ieee80211_hw *hw,
+					    u8 configtype);
+bool _rtl92ce_phy_config_bb_with_pgheaderfile(struct ieee80211_hw *hw,
+					      u8 configtype);
+void rtl92ce_phy_set_bw_mode_callback(struct ieee80211_hw *hw);
 
 #endif
diff -druN linux-2.6.39-libre/drivers/net/wireless/rtlwifi/rtl8192ce/reg.h linux-3.0-rc7-libre/drivers/net/wireless/rtlwifi/rtl8192ce/reg.h
--- linux-2.6.39-libre/drivers/net/wireless/rtlwifi/rtl8192ce/reg.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/rtlwifi/rtl8192ce/reg.h	2011-07-11 19:51:52.000000000 -0400
@@ -72,6 +72,7 @@
 #define REG_GPIO_IO_SEL_2			0x0062
 /* RTL8723 WIFI/BT/GPS Multi-Function control source. */
 #define REG_MULTI_FUNC_CTRL			0x0068
+
 #define REG_MCUFWDL				0x0080
 
 #define REG_HMEBOX_EXT_0			0x0088
@@ -542,7 +543,7 @@
 #define	IMR_OCPINT				BIT(1)
 #define	IMR_WLANOFF				BIT(0)
 
-#define	HWSET_MAX_SIZE				128
+#define EFUSE_REAL_CONTENT_LEN			512
 
 #define	EEPROM_DEFAULT_TSSI			0x0
 #define EEPROM_DEFAULT_TXPOWERDIFF		0x0
@@ -656,6 +657,7 @@
 #define	STOPBE					BIT(1)
 #define	STOPBK					BIT(0)
 
+#define	RCR_APPFCS				BIT(31)
 #define	RCR_APP_FCS				BIT(31)
 #define	RCR_APP_MIC				BIT(30)
 #define	RCR_APP_ICV				BIT(29)
@@ -688,6 +690,7 @@
 
 #define REG_USB_INFO				0xFE17
 #define REG_USB_SPECIAL_OPTION			0xFE55
+
 #define REG_USB_DMA_AGG_TO			0xFE5B
 #define REG_USB_AGG_TO				0xFE5C
 #define REG_USB_AGG_TH				0xFE5D
@@ -775,7 +778,6 @@
 
 #define	BOOT_FROM_EEPROM			BIT(4)
 #define	EEPROM_EN				BIT(5)
-#define	EEPROMSEL				BOOT_FROM_EEPROM
 
 #define AFE_BGEN				BIT(0)
 #define AFE_MBEN				BIT(1)
@@ -901,28 +903,7 @@
 #define BD_PKG_SEL				BIT(25)
 #define BD_HCI_SEL				BIT(26)
 #define TYPE_ID					BIT(27)
-
-/* REG_GPIO_OUTSTS (For RTL8723 only) */
-#define	EFS_HCI_SEL				(BIT(0)|BIT(1))
-#define	PAD_HCI_SEL				(BIT(2)|BIT(3))
-#define	HCI_SEL					(BIT(4)|BIT(5))
-#define	PKG_SEL_HCI				BIT(6)
-#define	FEN_GPS					BIT(7)
-#define	FEN_BT					BIT(8)
-#define	FEN_WL					BIT(9)
-#define	FEN_PCI					BIT(10)
-#define	FEN_USB					BIT(11)
-#define	BTRF_HWPDN_N				BIT(12)
-#define	WLRF_HWPDN_N				BIT(13)
-#define	PDN_BT_N				BIT(14)
-#define	PDN_GPS_N				BIT(15)
-#define	BT_CTL_HWPDN				BIT(16)
-#define	GPS_CTL_HWPDN				BIT(17)
-#define	PPHY_SUSB				BIT(20)
-#define	UPHY_SUSB				BIT(21)
-#define	PCI_SUSEN				BIT(22)
-#define	USB_SUSEN				BIT(23)
-#define	RF_RL_ID			(BIT(31) | BIT(30) | BIT(29) | BIT(28))
+#define	RF_RL_ID		(BIT(31) | BIT(30) | BIT(29) | BIT(28))
 
 #define CHIP_VER_RTL_MASK			0xF000
 #define CHIP_VER_RTL_SHIFT			12
@@ -1077,6 +1058,7 @@
 #define _RARF_RC8(x)				(((x) & 0x1F) << 24)
 
 #define AC_PARAM_TXOP_OFFSET			16
+#define AC_PARAM_TXOP_LIMIT_OFFSET		16
 #define AC_PARAM_ECW_MAX_OFFSET			12
 #define AC_PARAM_ECW_MIN_OFFSET			8
 #define AC_PARAM_AIFS_OFFSET			0
@@ -1221,33 +1203,11 @@
 #define EPROM_CMD_CONFIG			0x3
 #define EPROM_CMD_LOAD				1
 
-#define	HWSET_MAX_SIZE_92S		HWSET_MAX_SIZE
-
-#define	HAL_8192C_HW_GPIO_WPS_BIT		BIT(2)
+#define	HWSET_MAX_SIZE_92S			HWSET_MAX_SIZE
 
-/* REG_MULTI_FUNC_CTRL(For RTL8723 Only) */
-/* Enable GPIO[9] as WiFi HW PDn source */
 #define	WL_HWPDN_EN				BIT(0)
-/* WiFi HW PDn polarity control */
-#define	WL_HWPDN_SL				BIT(1)
-/* WiFi function enable */
-#define	WL_FUNC_EN				BIT(2)
-/* Enable GPIO[9] as WiFi RF HW PDn source */
-#define	WL_HWROF_EN				BIT(3)
-/* Enable GPIO[11] as BT HW PDn source */
-#define	BT_HWPDN_EN				BIT(16)
-/* BT HW PDn polarity control */
-#define	BT_HWPDN_SL				BIT(17)
-/* BT function enable */
-#define	BT_FUNC_EN				BIT(18)
-/* Enable GPIO[11] as BT/GPS RF HW PDn source */
-#define	BT_HWROF_EN				BIT(19)
-/* Enable GPIO[10] as GPS HW PDn source */
-#define	GPS_HWPDN_EN				BIT(20)
-/* GPS HW PDn polarity control */
-#define	GPS_HWPDN_SL				BIT(21)
-/* GPS function enable */
-#define	GPS_FUNC_EN				BIT(22)
+
+#define	HAL_8192C_HW_GPIO_WPS_BIT		BIT(2)
 
 #define	RPMAC_RESET				0x100
 #define	RPMAC_TXSTART				0x104
diff -druN linux-2.6.39-libre/drivers/net/wireless/rtlwifi/rtl8192ce/rf.c linux-3.0-rc7-libre/drivers/net/wireless/rtlwifi/rtl8192ce/rf.c
--- linux-2.6.39-libre/drivers/net/wireless/rtlwifi/rtl8192ce/rf.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/rtlwifi/rtl8192ce/rf.c	2011-07-11 19:51:52.000000000 -0400
@@ -34,9 +34,9 @@
 #include "rf.h"
 #include "dm.h"
 
-static bool _rtl92c_phy_rf6052_config_parafile(struct ieee80211_hw *hw);
+static bool _rtl92ce_phy_rf6052_config_parafile(struct ieee80211_hw *hw);
 
-void rtl92c_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw, u8 bandwidth)
+void rtl92ce_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw, u8 bandwidth)
 {
 	struct rtl_priv *rtlpriv = rtl_priv(hw);
 	struct rtl_phy *rtlphy = &(rtlpriv->phy);
@@ -62,7 +62,7 @@
 }
 
 void rtl92ce_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw,
-				       u8 *ppowerlevel)
+					u8 *ppowerlevel)
 {
 	struct rtl_priv *rtlpriv = rtl_priv(hw);
 	struct rtl_phy *rtlphy = &(rtlpriv->phy);
@@ -128,8 +128,7 @@
 
 	tmpval = tx_agc[RF90_PATH_A] >> 8;
 
-	if (mac->mode == WIRELESS_MODE_B)
-		tmpval = tmpval & 0xff00ffff;
+	tmpval = tmpval & 0xff00ffff;
 
 	rtl_set_bbreg(hw, RTXAGC_B_CCK11_A_CCK2_11, 0xffffff00, tmpval);
 
@@ -202,7 +201,7 @@
 	struct rtl_priv *rtlpriv = rtl_priv(hw);
 	struct rtl_phy *rtlphy = &(rtlpriv->phy);
 	struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
-	u8 i, chnlgroup, pwr_diff_limit[4];
+	u8 i, chnlgroup = 0, pwr_diff_limit[4];
 	u32 writeVal, customer_limit, rf;
 
 	for (rf = 0; rf < 2; rf++) {
@@ -440,16 +439,17 @@
 	else
 		rtlphy->num_total_rfpath = 2;
 
-	return _rtl92c_phy_rf6052_config_parafile(hw);
+	return _rtl92ce_phy_rf6052_config_parafile(hw);
+
 }
 
-static bool _rtl92c_phy_rf6052_config_parafile(struct ieee80211_hw *hw)
+static bool _rtl92ce_phy_rf6052_config_parafile(struct ieee80211_hw *hw)
 {
 	struct rtl_priv *rtlpriv = rtl_priv(hw);
 	struct rtl_phy *rtlphy = &(rtlpriv->phy);
-	u32 u4_regvalue;
+	u32 u4_regvalue = 0;
 	u8 rfpath;
-	bool rtstatus;
+	bool rtstatus = true;
 	struct bb_reg_def *pphyreg;
 
 	for (rfpath = 0; rfpath < rtlphy->num_total_rfpath; rfpath++) {
@@ -484,12 +484,12 @@
 
 		switch (rfpath) {
 		case RF90_PATH_A:
-			rtstatus = rtl92ce_phy_config_rf_with_headerfile(hw,
-					(enum radio_path) rfpath);
+			rtstatus = rtl92c_phy_config_rf_with_headerfile(hw,
+						(enum radio_path)rfpath);
 			break;
 		case RF90_PATH_B:
-			rtstatus = rtl92ce_phy_config_rf_with_headerfile(hw,
-					(enum radio_path) rfpath);
+			rtstatus = rtl92c_phy_config_rf_with_headerfile(hw,
+						(enum radio_path)rfpath);
 			break;
 		case RF90_PATH_C:
 			break;
diff -druN linux-2.6.39-libre/drivers/net/wireless/rtlwifi/rtl8192ce/rf.h linux-3.0-rc7-libre/drivers/net/wireless/rtlwifi/rtl8192ce/rf.h
--- linux-2.6.39-libre/drivers/net/wireless/rtlwifi/rtl8192ce/rf.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/rtlwifi/rtl8192ce/rf.h	2011-07-11 19:51:52.000000000 -0400
@@ -34,14 +34,11 @@
 #define RF6052_MAX_REG			0x3F
 #define RF6052_MAX_PATH			2
 
-extern void rtl92c_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw,
-					    u8 bandwidth);
-extern void rtl92c_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw,
-					      u8 *ppowerlevel);
-extern void rtl92c_phy_rf6052_set_ofdm_txpower(struct ieee80211_hw *hw,
-					       u8 *ppowerlevel, u8 channel);
-bool rtl92ce_phy_rf6052_config(struct ieee80211_hw *hw);
-bool rtl92ce_phy_config_rf_with_headerfile(struct ieee80211_hw *hw,
-					  enum radio_path rfpath);
-
+extern void rtl92ce_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw,
+					     u8 bandwidth);
+extern void rtl92ce_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw,
+					       u8 *ppowerlevel);
+extern void rtl92ce_phy_rf6052_set_ofdm_txpower(struct ieee80211_hw *hw,
+						u8 *ppowerlevel, u8 channel);
+extern bool rtl92ce_phy_rf6052_config(struct ieee80211_hw *hw);
 #endif
diff -druN linux-2.6.39-libre/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c linux-3.0-rc7-libre/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c
--- linux-2.6.39-libre/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c	2011-05-19 02:15:58.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c	2011-07-21 06:58:05.000000000 -0400
@@ -42,10 +42,58 @@
 #include "trx.h"
 #include "led.h"
 
+static void rtl92c_init_aspm_vars(struct ieee80211_hw *hw)
+{
+	struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+
+	/*close ASPM for AMD defaultly */
+	rtlpci->const_amdpci_aspm = 0;
+
+	/*
+	 * ASPM PS mode.
+	 * 0 - Disable ASPM,
+	 * 1 - Enable ASPM without Clock Req,
+	 * 2 - Enable ASPM with Clock Req,
+	 * 3 - Alwyas Enable ASPM with Clock Req,
+	 * 4 - Always Enable ASPM without Clock Req.
+	 * set defult to RTL8192CE:3 RTL8192E:2
+	 * */
+	rtlpci->const_pci_aspm = 3;
+
+	/*Setting for PCI-E device */
+	rtlpci->const_devicepci_aspm_setting = 0x03;
+
+	/*Setting for PCI-E bridge */
+	rtlpci->const_hostpci_aspm_setting = 0x02;
+
+	/*
+	 * In Hw/Sw Radio Off situation.
+	 * 0 - Default,
+	 * 1 - From ASPM setting without low Mac Pwr,
+	 * 2 - From ASPM setting with low Mac Pwr,
+	 * 3 - Bus D3
+	 * set default to RTL8192CE:0 RTL8192SE:2
+	 */
+	rtlpci->const_hwsw_rfoff_d3 = 0;
+
+	/*
+	 * This setting works for those device with
+	 * backdoor ASPM setting such as EPHY setting.
+	 * 0 - Not support ASPM,
+	 * 1 - Support ASPM,
+	 * 2 - According to chipset.
+	 */
+	rtlpci->const_support_pciaspm = 1;
+}
+
 int rtl92c_init_sw_vars(struct ieee80211_hw *hw)
 {
+	int err;
 	struct rtl_priv *rtlpriv = rtl_priv(hw);
 	struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+	const struct firmware *firmware;
+
+	rtl8192ce_bt_reg_init(hw);
 
 	rtlpriv->dm.dm_initialgain_enable = 1;
 	rtlpriv->dm.dm_flag = 0;
@@ -53,7 +101,12 @@
 	rtlpriv->dm.thermalvalue = 0;
 	rtlpci->transmit_config = CFENDFORM | BIT(12) | BIT(13);
 
-	rtlpci->receive_config = (RCR_APP_FCS |
+	/* compatible 5G band 88ce just 2.4G band & smsp */
+	rtlpriv->rtlhal.current_bandtype = BAND_ON_2_4G;
+	rtlpriv->rtlhal.bandset = BAND_ON_2_4G;
+	rtlpriv->rtlhal.macphymode = SINGLEMAC_SINGLEPHY;
+
+	rtlpci->receive_config = (RCR_APPFCS |
 				  RCR_AMF |
 				  RCR_ADF |
 				  RCR_APP_MIC |
@@ -76,13 +129,49 @@
 
 	rtlpci->irq_mask[1] = (u32) (IMR_CPWM | IMR_C2HCMD | 0);
 
-	rtlpriv->rtlhal.pfirmware = (u8 *) vmalloc(0x4000);
+	/* for LPS & IPS */
+	rtlpriv->psc.inactiveps = rtlpriv->cfg->mod_params->inactiveps;
+	rtlpriv->psc.swctrl_lps = rtlpriv->cfg->mod_params->swctrl_lps;
+	rtlpriv->psc.fwctrl_lps = rtlpriv->cfg->mod_params->fwctrl_lps;
+	rtlpriv->psc.reg_fwctrl_lps = 3;
+	rtlpriv->psc.reg_max_lps_awakeintvl = 5;
+	/* for ASPM, you can close aspm through
+	 * set const_support_pciaspm = 0 */
+	rtl92c_init_aspm_vars(hw);
+
+	if (rtlpriv->psc.reg_fwctrl_lps == 1)
+		rtlpriv->psc.fwctrl_psmode = FW_PS_MIN_MODE;
+	else if (rtlpriv->psc.reg_fwctrl_lps == 2)
+		rtlpriv->psc.fwctrl_psmode = FW_PS_MAX_MODE;
+	else if (rtlpriv->psc.reg_fwctrl_lps == 3)
+		rtlpriv->psc.fwctrl_psmode = FW_PS_DTIM_MODE;
+
+	/* for firmware buf */
+	rtlpriv->rtlhal.pfirmware = vzalloc(0x4000);
 	if (!rtlpriv->rtlhal.pfirmware) {
 		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
 			 ("Can't alloc buffer for fw.\n"));
 		return 1;
 	}
 
+	/* request fw */
+	err = reject_firmware(&firmware, rtlpriv->cfg->fw_name,
+			rtlpriv->io.dev);
+	if (err) {
+		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
+			 ("Failed to request firmware!\n"));
+		return 1;
+	}
+	if (firmware->size > 0x4000) {
+		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
+			 ("Firmware is too big!\n"));
+		release_firmware(firmware);
+		return 1;
+	}
+	memcpy(rtlpriv->rtlhal.pfirmware, firmware->data, firmware->size);
+	rtlpriv->rtlhal.fwsize = firmware->size;
+	release_firmware(firmware);
+
 	return 0;
 }
 
@@ -103,17 +192,19 @@
 	.interrupt_recognized = rtl92ce_interrupt_recognized,
 	.hw_init = rtl92ce_hw_init,
 	.hw_disable = rtl92ce_card_disable,
+	.hw_suspend = rtl92ce_suspend,
+	.hw_resume = rtl92ce_resume,
 	.enable_interrupt = rtl92ce_enable_interrupt,
 	.disable_interrupt = rtl92ce_disable_interrupt,
 	.set_network_type = rtl92ce_set_network_type,
+	.set_chk_bssid = rtl92ce_set_check_bssid,
 	.set_qos = rtl92ce_set_qos,
 	.set_bcn_reg = rtl92ce_set_beacon_related_registers,
 	.set_bcn_intv = rtl92ce_set_beacon_interval,
 	.update_interrupt_mask = rtl92ce_update_interrupt_mask,
 	.get_hw_reg = rtl92ce_get_hw_reg,
 	.set_hw_reg = rtl92ce_set_hw_reg,
-	.update_rate_table = rtl92ce_update_hal_rate_table,
-	.update_rate_mask = rtl92ce_update_hal_rate_mask,
+	.update_rate_tbl = rtl92ce_update_hal_rate_tbl,
 	.fill_tx_desc = rtl92ce_tx_fill_desc,
 	.fill_tx_cmddesc = rtl92ce_tx_fill_cmddesc,
 	.query_rx_desc = rtl92ce_rx_query_desc,
@@ -123,7 +214,7 @@
 	.switch_channel = rtl92c_phy_sw_chnl,
 	.dm_watchdog = rtl92c_dm_watchdog,
 	.scan_operation_backup = rtl92c_phy_scan_operation_backup,
-	.set_rf_power_state = rtl92ce_phy_set_rf_power_state,
+	.set_rf_power_state = rtl92c_phy_set_rf_power_state,
 	.led_control = rtl92ce_led_control,
 	.set_desc = rtl92ce_set_desc,
 	.get_desc = rtl92ce_get_desc,
@@ -131,12 +222,10 @@
 	.enable_hw_sec = rtl92ce_enable_hw_security_config,
 	.set_key = rtl92ce_set_key,
 	.init_sw_leds = rtl92ce_init_sw_leds,
-	.deinit_sw_leds = rtl92ce_deinit_sw_leds,
 	.get_bbreg = rtl92c_phy_query_bb_reg,
 	.set_bbreg = rtl92c_phy_set_bb_reg,
-	.get_rfreg = rtl92ce_phy_query_rf_reg,
 	.set_rfreg = rtl92ce_phy_set_rf_reg,
-	.cmd_send_packet = _rtl92c_cmd_send_packet,
+	.get_rfreg = rtl92c_phy_query_rf_reg,
 	.phy_rf6052_config = rtl92ce_phy_rf6052_config,
 	.phy_rf6052_set_cck_txpower = rtl92ce_phy_rf6052_set_cck_txpower,
 	.phy_rf6052_set_ofdm_txpower = rtl92ce_phy_rf6052_set_ofdm_txpower,
@@ -148,10 +237,15 @@
 };
 
 static struct rtl_mod_params rtl92ce_mod_params = {
-	.sw_crypto = 0,
+	.sw_crypto = false,
+	.inactiveps = true,
+	.swctrl_lps = false,
+	.fwctrl_lps = true,
 };
 
 static struct rtl_hal_cfg rtl92ce_hal_cfg = {
+	.bar_id = 2,
+	.write_readback = true,
 	.name = "rtl92c_pci",
 	.fw_name = "/*(DEBLOBBED)*/",
 	.ops = &rtl8192ce_hal_ops,
@@ -175,6 +269,8 @@
 	.maps[EFUSE_LOADER_CLK_EN] = LOADER_CLK_EN,
 	.maps[EFUSE_ANA8M] = EFUSE_ANA8M,
 	.maps[EFUSE_HWSET_MAX_SIZE] = HWSET_MAX_SIZE,
+	.maps[EFUSE_MAX_SECTION_MAP] = EFUSE_MAX_SECTION,
+	.maps[EFUSE_REAL_CONTENT_SIZE] = EFUSE_REAL_CONTENT_LEN,
 
 	.maps[RWCAM] = REG_CAMCMD,
 	.maps[WCAMI] = REG_CAMWRITE,
@@ -239,7 +335,7 @@
 	.maps[RTL_RC_HT_RATEMCS15] = DESC92C_RATEMCS15,
 };
 
-static struct pci_device_id rtl92ce_pci_ids[] __devinitdata = {
+DEFINE_PCI_DEVICE_TABLE(rtl92ce_pci_ids) = {
 	{RTL_PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8191, rtl92ce_hal_cfg)},
 	{RTL_PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8178, rtl92ce_hal_cfg)},
 	{RTL_PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8177, rtl92ce_hal_cfg)},
@@ -257,7 +353,13 @@
 /*(DEBLOBBED)*/
 
 module_param_named(swenc, rtl92ce_mod_params.sw_crypto, bool, 0444);
+module_param_named(ips, rtl92ce_mod_params.inactiveps, bool, 0444);
+module_param_named(swlps, rtl92ce_mod_params.swctrl_lps, bool, 0444);
+module_param_named(fwlps, rtl92ce_mod_params.fwctrl_lps, bool, 0444);
 MODULE_PARM_DESC(swenc, "using hardware crypto (default 0 [hardware])\n");
+MODULE_PARM_DESC(ips, "using no link power save (default 1 is open)\n");
+MODULE_PARM_DESC(fwlps, "using linked fw control power save "
+		 "(default 1 is open)\n");
 
 static struct pci_driver rtl92ce_driver = {
 	.name = KBUILD_MODNAME,
diff -druN linux-2.6.39-libre/drivers/net/wireless/rtlwifi/rtl8192ce/sw.h linux-3.0-rc7-libre/drivers/net/wireless/rtlwifi/rtl8192ce/sw.h
--- linux-2.6.39-libre/drivers/net/wireless/rtlwifi/rtl8192ce/sw.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/rtlwifi/rtl8192ce/sw.h	2011-07-11 19:51:52.000000000 -0400
@@ -33,19 +33,9 @@
 int rtl92c_init_sw_vars(struct ieee80211_hw *hw);
 void rtl92c_deinit_sw_vars(struct ieee80211_hw *hw);
 void rtl92c_init_var_map(struct ieee80211_hw *hw);
-bool _rtl92c_cmd_send_packet(struct ieee80211_hw *hw,
-			     struct sk_buff *skb);
-void rtl92ce_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw,
-					u8 *ppowerlevel);
-void rtl92ce_phy_rf6052_set_ofdm_txpower(struct ieee80211_hw *hw,
-					 u8 *ppowerlevel, u8 channel);
 bool _rtl92ce_phy_config_bb_with_headerfile(struct ieee80211_hw *hw,
-						  u8 configtype);
+					    u8 configtype);
 bool _rtl92ce_phy_config_bb_with_pgheaderfile(struct ieee80211_hw *hw,
-						    u8 configtype);
-void _rtl92ce_phy_lc_calibrate(struct ieee80211_hw *hw, bool is2t);
-u32 rtl92ce_phy_query_rf_reg(struct ieee80211_hw *hw,
-			    enum radio_path rfpath, u32 regaddr, u32 bitmask);
-void rtl92ce_phy_set_bw_mode_callback(struct ieee80211_hw *hw);
+					      u8 configtype);
 
 #endif
diff -druN linux-2.6.39-libre/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c linux-3.0-rc7-libre/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c
--- linux-2.6.39-libre/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c	2011-07-11 19:51:52.000000000 -0400
@@ -36,42 +36,16 @@
 #include "trx.h"
 #include "led.h"
 
-static enum rtl_desc_qsel _rtl92ce_map_hwqueue_to_fwqueue(__le16 fc,
-							  unsigned int
-							  skb_queue)
+static u8 _rtl92ce_map_hwqueue_to_fwqueue(struct sk_buff *skb, u8 hw_queue)
 {
-	enum rtl_desc_qsel qsel;
-
-	if (unlikely(ieee80211_is_beacon(fc))) {
-		qsel = QSLT_BEACON;
-		return qsel;
-	}
+	__le16 fc = rtl_get_fc(skb);
 
-	if (ieee80211_is_mgmt(fc)) {
-		qsel = QSLT_MGNT;
-		return qsel;
-	}
+	if (unlikely(ieee80211_is_beacon(fc)))
+		return QSLT_BEACON;
+	if (ieee80211_is_mgmt(fc))
+		return QSLT_MGNT;
 
-	switch (skb_queue) {
-	case VO_QUEUE:
-		qsel = QSLT_VO;
-		break;
-	case VI_QUEUE:
-		qsel = QSLT_VI;
-		break;
-	case BE_QUEUE:
-		qsel = QSLT_BE;
-		break;
-	case BK_QUEUE:
-		qsel = QSLT_BK;
-		break;
-	default:
-		qsel = QSLT_BE;
-		RT_ASSERT(false, ("BE queue, skb_queue:%d,"
-				  " set qsel = 0x%X\n", skb_queue, QSLT_BE));
-		break;
-	}
-	return qsel;
+	return skb->priority;
 }
 
 static int _rtl92ce_rate_mapping(bool isht, u8 desc_rate, bool first_ampdu)
@@ -255,6 +229,7 @@
 	u8 evm, pwdb_all, rf_rx_num = 0;
 	u8 i, max_spatial_stream;
 	u32 rssi, total_rssi = 0;
+	bool in_powersavemode = false;
 	bool is_cck_rate;
 
 	is_cck_rate = RX_HAL_IS_CCK_RATE(pdesc);
@@ -270,9 +245,13 @@
 		u8 report, cck_highpwr;
 		cck_buf = (struct phy_sts_cck_8192s_t *)p_drvinfo;
 
-		cck_highpwr = (u8) rtl_get_bbreg(hw,
-					 RFPGA0_XA_HSSIPARAMETER2,
-					 BIT(9));
+		if (!in_powersavemode)
+			cck_highpwr = (u8) rtl_get_bbreg(hw,
+						 RFPGA0_XA_HSSIPARAMETER2,
+						 BIT(9));
+		else
+			cck_highpwr = false;
+
 		if (!cck_highpwr) {
 			u8 cck_agc_rpt = cck_buf->cck_agc_rpt;
 			report = cck_buf->cck_agc_rpt & 0xc0;
@@ -398,6 +377,7 @@
 
 		if (rtlpriv->stats.ui_rssi.total_num++ >=
 		    PHY_RSSI_SLID_WIN_MAX) {
+
 			rtlpriv->stats.ui_rssi.total_num =
 			    PHY_RSSI_SLID_WIN_MAX;
 			last_rssi =
@@ -424,10 +404,6 @@
 	if (!pstats->is_cck && pstats->packet_toself) {
 		for (rfpath = RF90_PATH_A; rfpath < rtlphy->num_total_rfpath;
 		     rfpath++) {
-
-			if (!rtl8192_phy_check_is_legal_rfpath(hw, rfpath))
-				continue;
-
 			if (rtlpriv->stats.rx_rssi_percentage[rfpath] == 0) {
 				rtlpriv->stats.rx_rssi_percentage[rfpath] =
 				    pstats->rx_mimo_signalstrength[rfpath];
@@ -723,7 +699,7 @@
 void rtl92ce_tx_fill_desc(struct ieee80211_hw *hw,
 			  struct ieee80211_hdr *hdr, u8 *pdesc_tx,
 			  struct ieee80211_tx_info *info, struct sk_buff *skb,
-			  unsigned int queue_index)
+			  u8 hw_queue, struct rtl_tcb_desc *tcb_desc)
 {
 	struct rtl_priv *rtlpriv = rtl_priv(hw);
 	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
@@ -732,16 +708,9 @@
 	bool defaultadapter = true;
 	struct ieee80211_sta *sta;
 	u8 *pdesc = (u8 *) pdesc_tx;
-	struct rtl_tcb_desc tcb_desc;
-	u8 *qc = ieee80211_get_qos_ctl(hdr);
-	u8 tid = qc[0] & IEEE80211_QOS_CTL_TID_MASK;
 	u16 seq_number;
 	__le16 fc = hdr->frame_control;
-	u8 rate_flag = info->control.rates[0].flags;
-
-	enum rtl_desc_qsel fw_qsel =
-	    _rtl92ce_map_hwqueue_to_fwqueue(fc, queue_index);
-
+	u8 fw_qsel = _rtl92ce_map_hwqueue_to_fwqueue(skb, hw_queue);
 	bool firstseg = ((hdr->seq_ctrl &
 			  cpu_to_le16(IEEE80211_SCTL_FRAG)) == 0);
 
@@ -751,56 +720,68 @@
 	dma_addr_t mapping = pci_map_single(rtlpci->pdev,
 					    skb->data, skb->len,
 					    PCI_DMA_TODEVICE);
+	u8 bw_40 = 0;
+
+	rcu_read_lock();
+	sta = get_sta(hw, mac->vif, mac->bssid);
+	if (mac->opmode == NL80211_IFTYPE_STATION) {
+		bw_40 = mac->bw_40;
+	} else if (mac->opmode == NL80211_IFTYPE_AP ||
+		mac->opmode == NL80211_IFTYPE_ADHOC) {
+		if (sta)
+			bw_40 = sta->ht_cap.cap &
+				IEEE80211_HT_CAP_SUP_WIDTH_20_40;
+	}
 
 	seq_number = (le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_SEQ) >> 4;
 
-	rtl_get_tcb_desc(hw, info, skb, &tcb_desc);
+	rtl_get_tcb_desc(hw, info, sta, skb, tcb_desc);
 
 	CLEAR_PCI_TX_DESC_CONTENT(pdesc, sizeof(struct tx_desc_92c));
 
+	if (ieee80211_is_nullfunc(fc) || ieee80211_is_ctl(fc)) {
+		firstseg = true;
+		lastseg = true;
+	}
 	if (firstseg) {
 		SET_TX_DESC_OFFSET(pdesc, USB_HWDESC_HEADER_LEN);
 
-		SET_TX_DESC_TX_RATE(pdesc, tcb_desc.hw_rate);
+		SET_TX_DESC_TX_RATE(pdesc, tcb_desc->hw_rate);
 
-		if (tcb_desc.use_shortgi || tcb_desc.use_shortpreamble)
+		if (tcb_desc->use_shortgi || tcb_desc->use_shortpreamble)
 			SET_TX_DESC_DATA_SHORTGI(pdesc, 1);
 
-		if (mac->tids[tid].agg.agg_state == RTL_AGG_ON &&
-		    info->flags & IEEE80211_TX_CTL_AMPDU) {
+		if (info->flags & IEEE80211_TX_CTL_AMPDU) {
 			SET_TX_DESC_AGG_BREAK(pdesc, 1);
 			SET_TX_DESC_MAX_AGG_NUM(pdesc, 0x14);
 		}
 		SET_TX_DESC_SEQ(pdesc, seq_number);
 
-		SET_TX_DESC_RTS_ENABLE(pdesc, ((tcb_desc.rts_enable &&
-						!tcb_desc.
+		SET_TX_DESC_RTS_ENABLE(pdesc, ((tcb_desc->rts_enable &&
+						!tcb_desc->
 						cts_enable) ? 1 : 0));
 		SET_TX_DESC_HW_RTS_ENABLE(pdesc,
-					  ((tcb_desc.rts_enable
-					    || tcb_desc.cts_enable) ? 1 : 0));
-		SET_TX_DESC_CTS2SELF(pdesc, ((tcb_desc.cts_enable) ? 1 : 0));
-		SET_TX_DESC_RTS_STBC(pdesc, ((tcb_desc.rts_stbc) ? 1 : 0));
+					  ((tcb_desc->rts_enable
+					    || tcb_desc->cts_enable) ? 1 : 0));
+		SET_TX_DESC_CTS2SELF(pdesc, ((tcb_desc->cts_enable) ? 1 : 0));
+		SET_TX_DESC_RTS_STBC(pdesc, ((tcb_desc->rts_stbc) ? 1 : 0));
 
-		SET_TX_DESC_RTS_RATE(pdesc, tcb_desc.rts_rate);
+		SET_TX_DESC_RTS_RATE(pdesc, tcb_desc->rts_rate);
 		SET_TX_DESC_RTS_BW(pdesc, 0);
-		SET_TX_DESC_RTS_SC(pdesc, tcb_desc.rts_sc);
+		SET_TX_DESC_RTS_SC(pdesc, tcb_desc->rts_sc);
 		SET_TX_DESC_RTS_SHORT(pdesc,
-				      ((tcb_desc.rts_rate <= DESC92C_RATE54M) ?
-				      (tcb_desc.rts_use_shortpreamble ? 1 : 0)
-				      : (tcb_desc.rts_use_shortgi ? 1 : 0)));
+				      ((tcb_desc->rts_rate <= DESC92C_RATE54M) ?
+				       (tcb_desc->rts_use_shortpreamble ? 1 : 0)
+				       : (tcb_desc->rts_use_shortgi ? 1 : 0)));
 
-		if (mac->bw_40) {
-			if (tcb_desc.packet_bw) {
+		if (bw_40) {
+			if (tcb_desc->packet_bw) {
 				SET_TX_DESC_DATA_BW(pdesc, 1);
 				SET_TX_DESC_TX_SUB_CARRIER(pdesc, 3);
 			} else {
 				SET_TX_DESC_DATA_BW(pdesc, 0);
-
-				if (rate_flag & IEEE80211_TX_RC_DUP_DATA) {
-					SET_TX_DESC_TX_SUB_CARRIER(pdesc,
-							mac->cur_40_prime_sc);
-				}
+				SET_TX_DESC_TX_SUB_CARRIER(pdesc,
+						 mac->cur_40_prime_sc);
 			}
 		} else {
 			SET_TX_DESC_DATA_BW(pdesc, 0);
@@ -810,13 +791,10 @@
 		SET_TX_DESC_LINIP(pdesc, 0);
 		SET_TX_DESC_PKT_SIZE(pdesc, (u16) skb->len);
 
-		rcu_read_lock();
-		sta = ieee80211_find_sta(mac->vif, mac->bssid);
 		if (sta) {
 			u8 ampdu_density = sta->ht_cap.ampdu_density;
 			SET_TX_DESC_AMPDU_DENSITY(pdesc, ampdu_density);
 		}
-		rcu_read_unlock();
 
 		if (info->control.hw_key) {
 			struct ieee80211_key_conf *keyconf =
@@ -844,7 +822,7 @@
 		SET_TX_DESC_DATA_RATE_FB_LIMIT(pdesc, 0x1F);
 		SET_TX_DESC_RTS_RATE_FB_LIMIT(pdesc, 0xF);
 		SET_TX_DESC_DISABLE_FB(pdesc, 0);
-		SET_TX_DESC_USE_RATE(pdesc, tcb_desc.use_driver_rate ? 1 : 0);
+		SET_TX_DESC_USE_RATE(pdesc, tcb_desc->use_driver_rate ? 1 : 0);
 
 		if (ieee80211_is_data_qos(fc)) {
 			if (mac->rdg_en) {
@@ -855,24 +833,24 @@
 			}
 		}
 	}
+	rcu_read_unlock();
 
 	SET_TX_DESC_FIRST_SEG(pdesc, (firstseg ? 1 : 0));
 	SET_TX_DESC_LAST_SEG(pdesc, (lastseg ? 1 : 0));
 
 	SET_TX_DESC_TX_BUFFER_SIZE(pdesc, (u16) skb->len);
 
-	SET_TX_DESC_TX_BUFFER_ADDRESS(pdesc, cpu_to_le32(mapping));
+	SET_TX_DESC_TX_BUFFER_ADDRESS(pdesc, mapping);
 
 	if (rtlpriv->dm.useramask) {
-		SET_TX_DESC_RATE_ID(pdesc, tcb_desc.ratr_index);
-		SET_TX_DESC_MACID(pdesc, tcb_desc.mac_id);
+		SET_TX_DESC_RATE_ID(pdesc, tcb_desc->ratr_index);
+		SET_TX_DESC_MACID(pdesc, tcb_desc->mac_id);
 	} else {
-		SET_TX_DESC_RATE_ID(pdesc, 0xC + tcb_desc.ratr_index);
-		SET_TX_DESC_MACID(pdesc, tcb_desc.ratr_index);
+		SET_TX_DESC_RATE_ID(pdesc, 0xC + tcb_desc->ratr_index);
+		SET_TX_DESC_MACID(pdesc, tcb_desc->ratr_index);
 	}
 
-	if ((!ieee80211_is_data_qos(fc)) && ppsc->leisure_ps &&
-	    ppsc->fwctrl_lps) {
+	if ((!ieee80211_is_data_qos(fc)) && ppsc->fwctrl_lps) {
 		SET_TX_DESC_HWSEQ_EN(pdesc, 1);
 		SET_TX_DESC_PKT_ID(pdesc, 8);
 
@@ -923,7 +901,7 @@
 
 	SET_TX_DESC_TX_BUFFER_SIZE(pdesc, (u16) (skb->len));
 
-	SET_TX_DESC_TX_BUFFER_ADDRESS(pdesc, cpu_to_le32(mapping));
+	SET_TX_DESC_TX_BUFFER_ADDRESS(pdesc, mapping);
 
 	SET_TX_DESC_RATE_ID(pdesc, 7);
 	SET_TX_DESC_MACID(pdesc, 0);
@@ -1021,7 +999,7 @@
 	return ret;
 }
 
-void rtl92ce_tx_polling(struct ieee80211_hw *hw, unsigned int hw_queue)
+void rtl92ce_tx_polling(struct ieee80211_hw *hw, u8 hw_queue)
 {
 	struct rtl_priv *rtlpriv = rtl_priv(hw);
 	if (hw_queue == BEACON_QUEUE) {
@@ -1032,35 +1010,3 @@
 	}
 }
 
-bool _rtl92c_cmd_send_packet(struct ieee80211_hw *hw,
-			     struct sk_buff *skb)
-{
-	struct rtl_priv *rtlpriv = rtl_priv(hw);
-	struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
-	struct rtl8192_tx_ring *ring;
-	struct rtl_tx_desc *pdesc;
-	u8 own;
-	unsigned long flags;
-	struct sk_buff *pskb = NULL;
-
-	ring = &rtlpci->tx_ring[BEACON_QUEUE];
-
-	spin_lock_irqsave(&rtlpriv->locks.irq_th_lock, flags);
-
-	pskb = __skb_dequeue(&ring->queue);
-	if (pskb)
-		kfree_skb(pskb);
-
-	pdesc = &ring->desc[0];
-	own = (u8) rtlpriv->cfg->ops->get_desc((u8 *) pdesc, true, HW_DESC_OWN);
-
-	rtlpriv->cfg->ops->fill_tx_cmddesc(hw, (u8 *) pdesc, 1, 1, skb);
-
-	__skb_queue_tail(&ring->queue, skb);
-
-	spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock, flags);
-
-	rtlpriv->cfg->ops->tx_polling(hw, BEACON_QUEUE);
-
-	return true;
-}
diff -druN linux-2.6.39-libre/drivers/net/wireless/rtlwifi/rtl8192ce/trx.h linux-3.0-rc7-libre/drivers/net/wireless/rtlwifi/rtl8192ce/trx.h
--- linux-2.6.39-libre/drivers/net/wireless/rtlwifi/rtl8192ce/trx.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/rtlwifi/rtl8192ce/trx.h	2011-07-11 19:51:52.000000000 -0400
@@ -532,9 +532,9 @@
 #define CLEAR_PCI_TX_DESC_CONTENT(__pdesc, _size)	\
 do {							\
 	if (_size > TX_DESC_NEXT_DESC_OFFSET)		\
-		memset((void *)__pdesc, 0, TX_DESC_NEXT_DESC_OFFSET);	\
+		memset(__pdesc, 0, TX_DESC_NEXT_DESC_OFFSET);	\
 	else						\
-		memset((void *)__pdesc, 0, _size);	\
+		memset(__pdesc, 0, _size);	\
 } while (0);
 
 #define RX_HAL_IS_CCK_RATE(_pdesc)\
@@ -724,17 +724,16 @@
 void rtl92ce_tx_fill_desc(struct ieee80211_hw *hw,
 			  struct ieee80211_hdr *hdr,
 			  u8 *pdesc, struct ieee80211_tx_info *info,
-			  struct sk_buff *skb, unsigned int qsel);
+			  struct sk_buff *skb, u8 hw_queue,
+			  struct rtl_tcb_desc *ptcb_desc);
 bool rtl92ce_rx_query_desc(struct ieee80211_hw *hw,
 			   struct rtl_stats *stats,
 			   struct ieee80211_rx_status *rx_status,
 			   u8 *pdesc, struct sk_buff *skb);
 void rtl92ce_set_desc(u8 *pdesc, bool istx, u8 desc_name, u8 *val);
 u32 rtl92ce_get_desc(u8 *pdesc, bool istx, u8 desc_name);
-void rtl92ce_tx_polling(struct ieee80211_hw *hw, unsigned int hw_queue);
+void rtl92ce_tx_polling(struct ieee80211_hw *hw, u8 hw_queue);
 void rtl92ce_tx_fill_cmddesc(struct ieee80211_hw *hw, u8 *pdesc,
 			     bool b_firstseg, bool b_lastseg,
 			     struct sk_buff *skb);
-bool _rtl92c_cmd_send_packet(struct ieee80211_hw *hw, struct sk_buff *skb);
-
 #endif
diff -druN linux-2.6.39-libre/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c linux-3.0-rc7-libre/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c
--- linux-2.6.39-libre/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c	2011-07-11 19:51:52.000000000 -0400
@@ -39,6 +39,7 @@
 #include "mac.h"
 #include "dm.h"
 #include "hw.h"
+#include "../rtl8192ce/hw.h"
 #include "trx.h"
 #include "led.h"
 #include "table.h"
@@ -605,10 +606,10 @@
 	if (!IS_NORMAL_CHIP(rtlhal->version))
 		return;
 	tmp_u1b = rtl_read_byte(rtlpriv, REG_9346CR);
-	rtlefuse->epromtype = (tmp_u1b & EEPROMSEL) ?
+	rtlefuse->epromtype = (tmp_u1b & BOOT_FROM_EEPROM) ?
 			       EEPROM_93C46 : EEPROM_BOOT_EFUSE;
 	RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, ("Boot from %s\n",
-		 (tmp_u1b & EEPROMSEL) ? "EERROM" : "EFUSE"));
+		 (tmp_u1b & BOOT_FROM_EEPROM) ? "EERROM" : "EFUSE"));
 	rtlefuse->autoload_failflag = (tmp_u1b & EEPROM_EN) ? false : true;
 	RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("Autoload %s\n",
 		 (tmp_u1b & EEPROM_EN) ? "OK!!" : "ERR!!"));
@@ -921,7 +922,7 @@
 					       u8 out_ep_num,
 					       u8 queue_sel)
 {
-	u8	hq_sele;
+	u8 hq_sele = 0;
 	struct rtl_priv *rtlpriv = rtl_priv(hw);
 
 	switch (out_ep_num) {
@@ -977,7 +978,7 @@
 	struct rtl_priv *rtlpriv = rtl_priv(hw);
 	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
 
-	mac->rx_conf = (RCR_APM | RCR_AM | RCR_ADF | RCR_AB | RCR_APP_FCS |
+	mac->rx_conf = (RCR_APM | RCR_AM | RCR_ADF | RCR_AB | RCR_APPFCS |
 		      RCR_APP_ICV | RCR_AMF | RCR_HTC_LOC_CTRL |
 		      RCR_APP_MIC | RCR_APP_PHYSTS | RCR_ACRC32);
 	rtl_write_dword(rtlpriv, REG_RCR, mac->rx_conf);
@@ -2182,7 +2183,9 @@
 	}
 }
 
-void rtl92cu_update_hal_rate_table(struct ieee80211_hw *hw)
+void rtl92cu_update_hal_rate_table(struct ieee80211_hw *hw,
+				   struct ieee80211_sta *sta,
+				   u8 rssi_level)
 {
 	struct rtl_priv *rtlpriv = rtl_priv(hw);
 	struct rtl_phy *rtlphy = &(rtlpriv->phy);
diff -druN linux-2.6.39-libre/drivers/net/wireless/rtlwifi/rtl8192cu/hw.h linux-3.0-rc7-libre/drivers/net/wireless/rtlwifi/rtl8192cu/hw.h
--- linux-2.6.39-libre/drivers/net/wireless/rtlwifi/rtl8192cu/hw.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/rtlwifi/rtl8192cu/hw.h	2011-07-11 19:51:52.000000000 -0400
@@ -98,13 +98,14 @@
 				   u32 add_msr, u32 rm_msr);
 void rtl92cu_get_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val);
 void rtl92cu_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val);
-void rtl92cu_update_hal_rate_table(struct ieee80211_hw *hw);
+void rtl92cu_update_hal_rate_table(struct ieee80211_hw *hw,
+				   struct ieee80211_sta *sta,
+				   u8 rssi_level);
 void rtl92cu_update_hal_rate_mask(struct ieee80211_hw *hw, u8 rssi_level);
 
 void rtl92cu_update_channel_access_setting(struct ieee80211_hw *hw);
 bool rtl92cu_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 * valid);
 void rtl92cu_set_check_bssid(struct ieee80211_hw *hw, bool check_bssid);
-u8 _rtl92c_get_chnl_group(u8 chnl);
 int rtl92c_download_fw(struct ieee80211_hw *hw);
 void rtl92c_set_fw_pwrmode_cmd(struct ieee80211_hw *hw, u8 mode);
 void rtl92c_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool dl_finished);
diff -druN linux-2.6.39-libre/drivers/net/wireless/rtlwifi/rtl8192cu/phy.c linux-3.0-rc7-libre/drivers/net/wireless/rtlwifi/rtl8192cu/phy.c
--- linux-2.6.39-libre/drivers/net/wireless/rtlwifi/rtl8192cu/phy.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/rtlwifi/rtl8192cu/phy.c	2011-07-11 19:51:52.000000000 -0400
@@ -38,7 +38,7 @@
 #include "table.h"
 
 u32 rtl92cu_phy_query_rf_reg(struct ieee80211_hw *hw,
-			    enum radio_path rfpath, u32 regaddr, u32 bitmask)
+			     enum radio_path rfpath, u32 regaddr, u32 bitmask)
 {
 	struct rtl_priv *rtlpriv = rtl_priv(hw);
 	u32 original_value, readback_value, bitshift;
@@ -64,8 +64,8 @@
 }
 
 void rtl92cu_phy_set_rf_reg(struct ieee80211_hw *hw,
-			   enum radio_path rfpath,
-			   u32 regaddr, u32 bitmask, u32 data)
+			    enum radio_path rfpath,
+			    u32 regaddr, u32 bitmask, u32 data)
 {
 	struct rtl_priv *rtlpriv = rtl_priv(hw);
 	struct rtl_phy *rtlphy = &(rtlpriv->phy);
@@ -163,7 +163,7 @@
 }
 
 bool _rtl92cu_phy_config_bb_with_headerfile(struct ieee80211_hw *hw,
-						  u8 configtype)
+					    u8 configtype)
 {
 	int i;
 	u32 *phy_regarray_table;
@@ -223,7 +223,7 @@
 }
 
 bool _rtl92cu_phy_config_bb_with_pgheaderfile(struct ieee80211_hw *hw,
-						    u8 configtype)
+					      u8 configtype)
 {
 	struct rtl_priv *rtlpriv = rtl_priv(hw);
 	struct rtl_phy *rtlphy = &(rtlpriv->phy);
@@ -459,7 +459,7 @@
 	}
 }
 
-bool _rtl92cu_phy_set_rf_power_state(struct ieee80211_hw *hw,
+static bool _rtl92cu_phy_set_rf_power_state(struct ieee80211_hw *hw,
 					    enum rf_pwrstate rfpwr_state)
 {
 	struct rtl_priv *rtlpriv = rtl_priv(hw);
@@ -595,7 +595,7 @@
 }
 
 bool rtl92cu_phy_set_rf_power_state(struct ieee80211_hw *hw,
-				   enum rf_pwrstate rfpwr_state)
+				    enum rf_pwrstate rfpwr_state)
 {
 	struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
 	bool bresult = false;
diff -druN linux-2.6.39-libre/drivers/net/wireless/rtlwifi/rtl8192cu/phy.h linux-3.0-rc7-libre/drivers/net/wireless/rtlwifi/rtl8192cu/phy.h
--- linux-2.6.39-libre/drivers/net/wireless/rtlwifi/rtl8192cu/phy.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/rtlwifi/rtl8192cu/phy.h	2011-07-11 19:51:52.000000000 -0400
@@ -34,3 +34,17 @@
 void rtl92c_phy_set_io(struct ieee80211_hw *hw);
 bool _rtl92cu_phy_config_mac_with_headerfile(struct ieee80211_hw *hw);
 bool rtl92cu_phy_bb_config(struct ieee80211_hw *hw);
+u32 rtl92cu_phy_query_rf_reg(struct ieee80211_hw *hw,
+			     enum radio_path rfpath, u32 regaddr, u32 bitmask);
+void rtl92cu_phy_set_rf_reg(struct ieee80211_hw *hw,
+			    enum radio_path rfpath,
+			    u32 regaddr, u32 bitmask, u32 data);
+bool rtl92cu_phy_mac_config(struct ieee80211_hw *hw);
+bool _rtl92cu_phy_config_bb_with_pgheaderfile(struct ieee80211_hw *hw,
+					      u8 configtype);
+void _rtl92cu_phy_lc_calibrate(struct ieee80211_hw *hw, bool is2t);
+bool _rtl92cu_phy_config_bb_with_headerfile(struct ieee80211_hw *hw,
+					    u8 configtype);
+void rtl92cu_phy_set_bw_mode_callback(struct ieee80211_hw *hw);
+bool rtl92cu_phy_set_rf_power_state(struct ieee80211_hw *hw,
+				    enum rf_pwrstate rfpwr_state);
diff -druN linux-2.6.39-libre/drivers/net/wireless/rtlwifi/rtl8192cu/rf.c linux-3.0-rc7-libre/drivers/net/wireless/rtlwifi/rtl8192cu/rf.c
--- linux-2.6.39-libre/drivers/net/wireless/rtlwifi/rtl8192cu/rf.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/rtlwifi/rtl8192cu/rf.c	2011-07-11 19:51:52.000000000 -0400
@@ -62,7 +62,7 @@
 }
 
 void rtl92cu_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw,
-				       u8 *ppowerlevel)
+					u8 *ppowerlevel)
 {
 	struct rtl_priv *rtlpriv = rtl_priv(hw);
 	struct rtl_phy *rtlphy = &(rtlpriv->phy);
@@ -389,7 +389,7 @@
 }
 
 void rtl92cu_phy_rf6052_set_ofdm_txpower(struct ieee80211_hw *hw,
-					u8 *ppowerlevel, u8 channel)
+					 u8 *ppowerlevel, u8 channel)
 {
 	u32 writeVal[2], powerBase0[2], powerBase1[2];
 	u8 index = 0;
diff -druN linux-2.6.39-libre/drivers/net/wireless/rtlwifi/rtl8192cu/rf.h linux-3.0-rc7-libre/drivers/net/wireless/rtlwifi/rtl8192cu/rf.h
--- linux-2.6.39-libre/drivers/net/wireless/rtlwifi/rtl8192cu/rf.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/rtlwifi/rtl8192cu/rf.h	2011-07-11 19:51:52.000000000 -0400
@@ -43,5 +43,9 @@
 bool rtl92cu_phy_rf6052_config(struct ieee80211_hw *hw);
 bool rtl92cu_phy_config_rf_with_headerfile(struct ieee80211_hw *hw,
 					  enum radio_path rfpath);
+void rtl92cu_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw,
+					u8 *ppowerlevel);
+void rtl92cu_phy_rf6052_set_ofdm_txpower(struct ieee80211_hw *hw,
+					 u8 *ppowerlevel, u8 channel);
 
 #endif
diff -druN linux-2.6.39-libre/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c linux-3.0-rc7-libre/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c
--- linux-2.6.39-libre/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c	2011-05-19 02:16:00.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c	2011-07-21 06:58:07.000000000 -0400
@@ -53,6 +53,8 @@
 static int rtl92cu_init_sw_vars(struct ieee80211_hw *hw)
 {
 	struct rtl_priv *rtlpriv = rtl_priv(hw);
+	const struct firmware *firmware;
+	int err;
 
 	rtlpriv->dm.dm_initialgain_enable = 1;
 	rtlpriv->dm.dm_flag = 0;
@@ -64,6 +66,24 @@
 			 ("Can't alloc buffer for fw.\n"));
 		return 1;
 	}
+	/* request fw */
+	err = reject_firmware(&firmware, rtlpriv->cfg->fw_name,
+			rtlpriv->io.dev);
+	if (err) {
+		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
+			 ("Failed to request firmware!\n"));
+		return 1;
+	}
+	if (firmware->size > 0x4000) {
+		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
+			 ("Firmware is too big!\n"));
+		release_firmware(firmware);
+		return 1;
+	}
+	memcpy(rtlpriv->rtlhal.pfirmware, firmware->data, firmware->size);
+	rtlpriv->rtlhal.fwsize = firmware->size;
+	release_firmware(firmware);
+
 	return 0;
 }
 
@@ -94,7 +114,7 @@
 	.update_interrupt_mask = rtl92cu_update_interrupt_mask,
 	.get_hw_reg = rtl92cu_get_hw_reg,
 	.set_hw_reg = rtl92cu_set_hw_reg,
-	.update_rate_table = rtl92cu_update_hal_rate_table,
+	.update_rate_tbl = rtl92cu_update_hal_rate_table,
 	.update_rate_mask = rtl92cu_update_hal_rate_mask,
 	.fill_tx_desc = rtl92cu_tx_fill_desc,
 	.fill_fake_txdesc = rtl92cu_fill_fake_txdesc,
diff -druN linux-2.6.39-libre/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c linux-3.0-rc7-libre/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c
--- linux-2.6.39-libre/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c	2011-07-11 19:51:52.000000000 -0400
@@ -372,7 +372,7 @@
 	__le16 fc;
 	struct ieee80211_hdr *hdr;
 
-	memset(rx_status, 0, sizeof(rx_status));
+	memset(rx_status, 0, sizeof(*rx_status));
 	rxdesc	= skb->data;
 	skb_len	= skb->len;
 	drvinfo_len = (GET_RX_DESC_DRVINFO_SIZE(rxdesc) * RTL_RX_DRV_INFO_UNIT);
@@ -434,7 +434,7 @@
 		 "0x%02X\n", fc, (u32)hdr->addr1[0], (u32)hdr->addr1[1],
 		 (u32)hdr->addr1[2], (u32)hdr->addr1[3], (u32)hdr->addr1[4],
 		 (u32)hdr->addr1[5]));
-	memcpy(IEEE80211_SKB_RXCB(skb), &rx_status, sizeof(rx_status));
+	memcpy(IEEE80211_SKB_RXCB(skb), rx_status, sizeof(*rx_status));
 	ieee80211_rx_irqsafe(hw, skb);
 }
 
@@ -498,14 +498,14 @@
 void rtl92cu_tx_fill_desc(struct ieee80211_hw *hw,
 			  struct ieee80211_hdr *hdr, u8 *pdesc_tx,
 			  struct ieee80211_tx_info *info, struct sk_buff *skb,
-			  unsigned int queue_index)
+			  u8 queue_index,
+			  struct rtl_tcb_desc *tcb_desc)
 {
 	struct rtl_priv *rtlpriv = rtl_priv(hw);
 	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
 	struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
 	bool defaultadapter = true;
-	struct ieee80211_sta *sta;
-	struct rtl_tcb_desc tcb_desc;
+	struct ieee80211_sta *sta = info->control.sta = info->control.sta;
 	u8 *qc = ieee80211_get_qos_ctl(hdr);
 	u8 tid = qc[0] & IEEE80211_QOS_CTL_TID_MASK;
 	u16 seq_number;
@@ -517,15 +517,15 @@
 	u8 *txdesc;
 
 	seq_number = (le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_SEQ) >> 4;
-	rtl_get_tcb_desc(hw, info, skb, &tcb_desc);
+	rtl_get_tcb_desc(hw, info, sta, skb, tcb_desc);
 	txdesc = (u8 *)skb_push(skb, RTL_TX_HEADER_SIZE);
 	memset(txdesc, 0, RTL_TX_HEADER_SIZE);
 	SET_TX_DESC_PKT_SIZE(txdesc, pktlen);
 	SET_TX_DESC_LINIP(txdesc, 0);
 	SET_TX_DESC_PKT_OFFSET(txdesc, RTL_DUMMY_OFFSET);
 	SET_TX_DESC_OFFSET(txdesc, RTL_TX_HEADER_SIZE);
-	SET_TX_DESC_TX_RATE(txdesc, tcb_desc.hw_rate);
-	if (tcb_desc.use_shortgi || tcb_desc.use_shortpreamble)
+	SET_TX_DESC_TX_RATE(txdesc, tcb_desc->hw_rate);
+	if (tcb_desc->use_shortgi || tcb_desc->use_shortpreamble)
 		SET_TX_DESC_DATA_SHORTGI(txdesc, 1);
 	if (mac->tids[tid].agg.agg_state == RTL_AGG_ON &&
 		    info->flags & IEEE80211_TX_CTL_AMPDU) {
@@ -535,21 +535,21 @@
 		SET_TX_DESC_AGG_BREAK(txdesc, 1);
 	}
 	SET_TX_DESC_SEQ(txdesc, seq_number);
-	SET_TX_DESC_RTS_ENABLE(txdesc, ((tcb_desc.rts_enable &&
-			       !tcb_desc.cts_enable) ? 1 : 0));
-	SET_TX_DESC_HW_RTS_ENABLE(txdesc, ((tcb_desc.rts_enable ||
-				  tcb_desc.cts_enable) ? 1 : 0));
-	SET_TX_DESC_CTS2SELF(txdesc, ((tcb_desc.cts_enable) ? 1 : 0));
-	SET_TX_DESC_RTS_STBC(txdesc, ((tcb_desc.rts_stbc) ? 1 : 0));
-	SET_TX_DESC_RTS_RATE(txdesc, tcb_desc.rts_rate);
+	SET_TX_DESC_RTS_ENABLE(txdesc, ((tcb_desc->rts_enable &&
+			       !tcb_desc->cts_enable) ? 1 : 0));
+	SET_TX_DESC_HW_RTS_ENABLE(txdesc, ((tcb_desc->rts_enable ||
+				  tcb_desc->cts_enable) ? 1 : 0));
+	SET_TX_DESC_CTS2SELF(txdesc, ((tcb_desc->cts_enable) ? 1 : 0));
+	SET_TX_DESC_RTS_STBC(txdesc, ((tcb_desc->rts_stbc) ? 1 : 0));
+	SET_TX_DESC_RTS_RATE(txdesc, tcb_desc->rts_rate);
 	SET_TX_DESC_RTS_BW(txdesc, 0);
-	SET_TX_DESC_RTS_SC(txdesc, tcb_desc.rts_sc);
+	SET_TX_DESC_RTS_SC(txdesc, tcb_desc->rts_sc);
 	SET_TX_DESC_RTS_SHORT(txdesc,
-			      ((tcb_desc.rts_rate <= DESC92C_RATE54M) ?
-			       (tcb_desc.rts_use_shortpreamble ? 1 : 0)
-			       : (tcb_desc.rts_use_shortgi ? 1 : 0)));
+			      ((tcb_desc->rts_rate <= DESC92C_RATE54M) ?
+			       (tcb_desc->rts_use_shortpreamble ? 1 : 0)
+			       : (tcb_desc->rts_use_shortgi ? 1 : 0)));
 	if (mac->bw_40) {
-		if (tcb_desc.packet_bw) {
+		if (tcb_desc->packet_bw) {
 			SET_TX_DESC_DATA_BW(txdesc, 1);
 			SET_TX_DESC_DATA_SC(txdesc, 3);
 		} else {
@@ -590,7 +590,7 @@
 	SET_TX_DESC_DATA_RATE_FB_LIMIT(txdesc, 0x1F);
 	SET_TX_DESC_RTS_RATE_FB_LIMIT(txdesc, 0xF);
 	SET_TX_DESC_DISABLE_FB(txdesc, 0);
-	SET_TX_DESC_USE_RATE(txdesc, tcb_desc.use_driver_rate ? 1 : 0);
+	SET_TX_DESC_USE_RATE(txdesc, tcb_desc->use_driver_rate ? 1 : 0);
 	if (ieee80211_is_data_qos(fc)) {
 		if (mac->rdg_en) {
 			RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE,
@@ -600,11 +600,11 @@
 		}
 	}
 	if (rtlpriv->dm.useramask) {
-		SET_TX_DESC_RATE_ID(txdesc, tcb_desc.ratr_index);
-		SET_TX_DESC_MACID(txdesc, tcb_desc.mac_id);
+		SET_TX_DESC_RATE_ID(txdesc, tcb_desc->ratr_index);
+		SET_TX_DESC_MACID(txdesc, tcb_desc->mac_id);
 	} else {
-		SET_TX_DESC_RATE_ID(txdesc, 0xC + tcb_desc.ratr_index);
-		SET_TX_DESC_MACID(txdesc, tcb_desc.ratr_index);
+		SET_TX_DESC_RATE_ID(txdesc, 0xC + tcb_desc->ratr_index);
+		SET_TX_DESC_MACID(txdesc, tcb_desc->ratr_index);
 	}
 	if ((!ieee80211_is_data_qos(fc)) && ppsc->leisure_ps &&
 	      ppsc->fwctrl_lps) {
diff -druN linux-2.6.39-libre/drivers/net/wireless/rtlwifi/rtl8192cu/trx.h linux-3.0-rc7-libre/drivers/net/wireless/rtlwifi/rtl8192cu/trx.h
--- linux-2.6.39-libre/drivers/net/wireless/rtlwifi/rtl8192cu/trx.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/rtlwifi/rtl8192cu/trx.h	2011-07-11 19:51:52.000000000 -0400
@@ -37,6 +37,8 @@
 #define RTL92C_SIZE_MAX_RX_BUFFER		15360   /* 8192 */
 #define RX_DRV_INFO_SIZE_UNIT			8
 
+#define RTL_AGG_ON				1
+
 enum usb_rx_agg_mode {
 	USB_RX_AGG_DISABLE,
 	USB_RX_AGG_DMA,
@@ -419,7 +421,8 @@
 void rtl92cu_tx_fill_desc(struct ieee80211_hw *hw,
 			  struct ieee80211_hdr *hdr, u8 *pdesc_tx,
 			  struct ieee80211_tx_info *info, struct sk_buff *skb,
-			  unsigned int queue_index);
+			  u8 queue_index,
+			  struct rtl_tcb_desc *tcb_desc);
 void rtl92cu_fill_fake_txdesc(struct ieee80211_hw *hw, u8 * pDesc,
 			      u32 buffer_len, bool bIsPsPoll);
 void rtl92cu_tx_fill_cmddesc(struct ieee80211_hw *hw,
diff -druN linux-2.6.39-libre/drivers/net/wireless/rtlwifi/rtl8192se/def.h linux-3.0-rc7-libre/drivers/net/wireless/rtlwifi/rtl8192se/def.h
--- linux-2.6.39-libre/drivers/net/wireless/rtlwifi/rtl8192se/def.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/net/wireless/rtlwifi/rtl8192se/def.h	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,598 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2009-2010  Realtek Corporation.
+ *
+ * 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:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+#ifndef __REALTEK_92S_DEF_H__
+#define __REALTEK_92S_DEF_H__
+
+#define RX_MPDU_QUEUE				0
+#define RX_CMD_QUEUE				1
+#define RX_MAX_QUEUE				2
+
+#define DESC92S_RATE1M				0x00
+#define DESC92S_RATE2M				0x01
+#define DESC92S_RATE5_5M			0x02
+#define DESC92S_RATE11M				0x03
+#define DESC92S_RATE6M				0x04
+#define DESC92S_RATE9M				0x05
+#define DESC92S_RATE12M				0x06
+#define DESC92S_RATE18M				0x07
+#define DESC92S_RATE24M				0x08
+#define DESC92S_RATE36M				0x09
+#define DESC92S_RATE48M				0x0a
+#define DESC92S_RATE54M				0x0b
+#define DESC92S_RATEMCS0			0x0c
+#define DESC92S_RATEMCS1			0x0d
+#define DESC92S_RATEMCS2			0x0e
+#define DESC92S_RATEMCS3			0x0f
+#define DESC92S_RATEMCS4			0x10
+#define DESC92S_RATEMCS5			0x11
+#define DESC92S_RATEMCS6			0x12
+#define DESC92S_RATEMCS7			0x13
+#define DESC92S_RATEMCS8			0x14
+#define DESC92S_RATEMCS9			0x15
+#define DESC92S_RATEMCS10			0x16
+#define DESC92S_RATEMCS11			0x17
+#define DESC92S_RATEMCS12			0x18
+#define DESC92S_RATEMCS13			0x19
+#define DESC92S_RATEMCS14			0x1a
+#define DESC92S_RATEMCS15			0x1b
+#define DESC92S_RATEMCS15_SG			0x1c
+#define DESC92S_RATEMCS32			0x20
+
+#define SHORT_SLOT_TIME				9
+#define NON_SHORT_SLOT_TIME			20
+
+/* Rx smooth factor */
+#define	RX_SMOOTH_FACTOR			20
+
+/* Queue Select Value in TxDesc */
+#define QSLT_BK					0x2
+#define QSLT_BE					0x0
+#define QSLT_VI					0x5
+#define QSLT_VO					0x6
+#define QSLT_BEACON				0x10
+#define QSLT_HIGH				0x11
+#define QSLT_MGNT				0x12
+#define QSLT_CMD				0x13
+
+#define	PHY_RSSI_SLID_WIN_MAX			100
+#define	PHY_LINKQUALITY_SLID_WIN_MAX		20
+#define	PHY_BEACON_RSSI_SLID_WIN_MAX		10
+
+/* Tx Desc */
+#define TX_DESC_SIZE_RTL8192S			(16 * 4)
+#define TX_CMDDESC_SIZE_RTL8192S		(16 * 4)
+
+/* Define a macro that takes a le32 word, converts it to host ordering,
+ * right shifts by a specified count, creates a mask of the specified
+ * bit count, and extracts that number of bits.
+ */
+
+#define SHIFT_AND_MASK_LE(__pdesc, __shift, __mask)		\
+	((le32_to_cpu(*(((__le32 *)(__pdesc)))) >> (__shift)) &	\
+	BIT_LEN_MASK_32(__mask))
+
+/* Define a macro that clears a bit field in an le32 word and
+ * sets the specified value into that bit field. The resulting
+ * value remains in le32 ordering; however, it is properly converted
+ * to host ordering for the clear and set operations before conversion
+ * back to le32.
+ */
+
+#define SET_BITS_OFFSET_LE(__pdesc, __shift, __len, __val)	\
+	(*(__le32 *)(__pdesc) =					\
+	(cpu_to_le32((le32_to_cpu(*((__le32 *)(__pdesc))) &	\
+	(~(BIT_OFFSET_LEN_MASK_32((__shift), __len)))) |	\
+	(((u32)(__val) & BIT_LEN_MASK_32(__len)) << (__shift)))));
+
+/* macros to read/write various fields in RX or TX descriptors */
+
+/* Dword 0 */
+#define SET_TX_DESC_PKT_SIZE(__pdesc, __val)			\
+	SET_BITS_OFFSET_LE(__pdesc, 0, 16, __val)
+#define SET_TX_DESC_OFFSET(__pdesc, __val)			\
+	SET_BITS_OFFSET_LE(__pdesc, 16, 8, __val)
+#define SET_TX_DESC_TYPE(__pdesc, __val)			\
+	SET_BITS_OFFSET_LE(__pdesc, 24, 2, __val)
+#define SET_TX_DESC_LAST_SEG(__pdesc, __val)			\
+	SET_BITS_OFFSET_LE(__pdesc, 26, 1, __val)
+#define SET_TX_DESC_FIRST_SEG(__pdesc, __val)			\
+	SET_BITS_OFFSET_LE(__pdesc, 27, 1, __val)
+#define SET_TX_DESC_LINIP(__pdesc, __val)			\
+	SET_BITS_OFFSET_LE(__pdesc, 28, 1, __val)
+#define SET_TX_DESC_AMSDU(__pdesc, __val)			\
+	SET_BITS_OFFSET_LE(__pdesc, 29, 1, __val)
+#define SET_TX_DESC_GREEN_FIELD(__pdesc, __val)			\
+	SET_BITS_OFFSET_LE(__pdesc, 30, 1, __val)
+#define SET_TX_DESC_OWN(__pdesc, __val)				\
+	SET_BITS_OFFSET_LE(__pdesc, 31, 1, __val)
+
+#define GET_TX_DESC_OWN(__pdesc)				\
+	SHIFT_AND_MASK_LE(__pdesc, 31, 1)
+
+/* Dword 1 */
+#define SET_TX_DESC_MACID(__pdesc, __val)			\
+	SET_BITS_OFFSET_LE(__pdesc + 4, 0, 5, __val)
+#define SET_TX_DESC_MORE_DATA(__pdesc, __val)			\
+	SET_BITS_OFFSET_LE(__pdesc + 4, 5, 1, __val)
+#define SET_TX_DESC_MORE_FRAG(__pdesc, __val)			\
+	SET_BITS_OFFSET_LE(__pdesc + 4, 6, 1, __val)
+#define SET_TX_DESC_PIFS(__pdesc, __val)			\
+	SET_BITS_OFFSET_LE(__pdesc + 4, 7, 1, __val)
+#define SET_TX_DESC_QUEUE_SEL(__pdesc, __val)			\
+	SET_BITS_OFFSET_LE(__pdesc + 4, 8, 5, __val)
+#define SET_TX_DESC_ACK_POLICY(__pdesc, __val)			\
+	SET_BITS_OFFSET_LE(__pdesc + 4, 13, 2, __val)
+#define SET_TX_DESC_NO_ACM(__pdesc, __val)			\
+	SET_BITS_OFFSET_LE(__pdesc + 4, 15, 1, __val)
+#define SET_TX_DESC_NON_QOS(__pdesc, __val)			\
+	SET_BITS_OFFSET_LE(__pdesc + 4, 16, 1, __val)
+#define SET_TX_DESC_KEY_ID(__pdesc, __val)			\
+	SET_BITS_OFFSET_LE(__pdesc + 4, 17, 2, __val)
+#define SET_TX_DESC_OUI(__pdesc, __val)				\
+	SET_BITS_OFFSET_LE(__pdesc + 4, 19, 1, __val)
+#define SET_TX_DESC_PKT_TYPE(__pdesc, __val)			\
+	SET_BITS_OFFSET_LE(__pdesc + 4, 20, 1, __val)
+#define SET_TX_DESC_EN_DESC_ID(__pdesc, __val)			\
+	SET_BITS_OFFSET_LE(__pdesc + 4, 21, 1, __val)
+#define SET_TX_DESC_SEC_TYPE(__pdesc, __val)			\
+	SET_BITS_OFFSET_LE(__pdesc + 4, 22, 2, __val)
+#define SET_TX_DESC_WDS(__pdesc, __val)				\
+	SET_BITS_OFFSET_LE(__pdesc + 4, 24, 1, __val)
+#define SET_TX_DESC_HTC(__pdesc, __val)				\
+	SET_BITS_OFFSET_LE(__pdesc + 4, 25, 1, __val)
+#define SET_TX_DESC_PKT_OFFSET(__pdesc, __val)			\
+	SET_BITS_OFFSET_LE(__pdesc + 4, 26, 5, __val)
+#define SET_TX_DESC_HWPC(__pdesc, __val)			\
+	SET_BITS_OFFSET_LE(__pdesc + 4, 27, 1, __val)
+
+/* Dword 2 */
+#define SET_TX_DESC_DATA_RETRY_LIMIT(__pdesc, __val)		\
+	SET_BITS_OFFSET_LE(__pdesc + 8, 0, 6, __val)
+#define SET_TX_DESC_RETRY_LIMIT_ENABLE(__pdesc, __val)		\
+	SET_BITS_OFFSET_LE(__pdesc + 8, 6, 1, __val)
+#define SET_TX_DESC_TSFL(__pdesc, __val)			\
+	SET_BITS_OFFSET_LE(__pdesc + 8, 7, 5, __val)
+#define SET_TX_DESC_RTS_RETRY_COUNT(__pdesc, __val)		\
+	SET_BITS_OFFSET_LE(__pdesc + 8, 12, 6, __val)
+#define SET_TX_DESC_DATA_RETRY_COUNT(__pdesc, __val)		\
+	SET_BITS_OFFSET_LE(__pdesc + 8, 18, 6, __val)
+#define	SET_TX_DESC_RSVD_MACID(__pdesc, __val)			\
+	SET_BITS_OFFSET_LE(((__pdesc) + 8), 24, 5, __val)
+#define SET_TX_DESC_AGG_ENABLE(__pdesc, __val)			\
+	SET_BITS_OFFSET_LE(__pdesc + 8, 29, 1, __val)
+#define SET_TX_DESC_AGG_BREAK(__pdesc, __val)			\
+	SET_BITS_OFFSET_LE(__pdesc + 8, 30, 1, __val)
+#define SET_TX_DESC_OWN_MAC(__pdesc, __val)			\
+	SET_BITS_OFFSET_LE(__pdesc + 8, 31, 1, __val)
+
+/* Dword 3 */
+#define SET_TX_DESC_NEXT_HEAP_PAGE(__pdesc, __val)		\
+	SET_BITS_OFFSET_LE(__pdesc + 12, 0, 8, __val)
+#define SET_TX_DESC_TAIL_PAGE(__pdesc, __val)			\
+	SET_BITS_OFFSET_LE(__pdesc + 12, 8, 8, __val)
+#define SET_TX_DESC_SEQ(__pdesc, __val)				\
+	SET_BITS_OFFSET_LE(__pdesc + 12, 16, 12, __val)
+#define SET_TX_DESC_FRAG(__pdesc, __val)			\
+	SET_BITS_OFFSET_LE(__pdesc + 12, 28, 4, __val)
+
+/* Dword 4 */
+#define SET_TX_DESC_RTS_RATE(__pdesc, __val)			\
+	SET_BITS_OFFSET_LE(__pdesc + 16, 0, 6, __val)
+#define SET_TX_DESC_DISABLE_RTS_FB(__pdesc, __val)		\
+	SET_BITS_OFFSET_LE(__pdesc + 16, 6, 1, __val)
+#define SET_TX_DESC_RTS_RATE_FB_LIMIT(__pdesc, __val)		\
+	SET_BITS_OFFSET_LE(__pdesc + 16, 7, 4, __val)
+#define SET_TX_DESC_CTS_ENABLE(__pdesc, __val)			\
+	SET_BITS_OFFSET_LE(__pdesc + 16, 11, 1, __val)
+#define SET_TX_DESC_RTS_ENABLE(__pdesc, __val)			\
+	SET_BITS_OFFSET_LE(__pdesc + 16, 12, 1, __val)
+#define SET_TX_DESC_RA_BRSR_ID(__pdesc, __val)			\
+	SET_BITS_OFFSET_LE(__pdesc + 16, 13, 3, __val)
+#define SET_TX_DESC_TXHT(__pdesc, __val)			\
+	SET_BITS_OFFSET_LE(__pdesc + 16, 16, 1, __val)
+#define SET_TX_DESC_TX_SHORT(__pdesc, __val)			\
+	SET_BITS_OFFSET_LE(__pdesc + 16, 17, 1, __val)
+#define SET_TX_DESC_TX_BANDWIDTH(__pdesc, __val)		\
+	SET_BITS_OFFSET_LE(__pdesc + 16, 18, 1, __val)
+#define SET_TX_DESC_TX_SUB_CARRIER(__pdesc, __val)		\
+	SET_BITS_OFFSET_LE(__pdesc + 16, 19, 2, __val)
+#define SET_TX_DESC_TX_STBC(__pdesc, __val)			\
+	SET_BITS_OFFSET_LE(__pdesc + 16, 21, 2, __val)
+#define SET_TX_DESC_TX_REVERSE_DIRECTION(__pdesc, __val)	\
+	SET_BITS_OFFSET_LE(__pdesc + 16, 23, 1, __val)
+#define SET_TX_DESC_RTS_HT(__pdesc, __val)			\
+	SET_BITS_OFFSET_LE(__pdesc + 16, 24, 1, __val)
+#define SET_TX_DESC_RTS_SHORT(__pdesc, __val)			\
+	SET_BITS_OFFSET_LE(__pdesc + 16, 25, 1, __val)
+#define SET_TX_DESC_RTS_BANDWIDTH(__pdesc, __val)		\
+	SET_BITS_OFFSET_LE(__pdesc + 16, 26, 1, __val)
+#define SET_TX_DESC_RTS_SUB_CARRIER(__pdesc, __val)		\
+	SET_BITS_OFFSET_LE(__pdesc + 16, 27, 2, __val)
+#define SET_TX_DESC_RTS_STBC(__pdesc, __val)			\
+	SET_BITS_OFFSET_LE(__pdesc + 16, 29, 2, __val)
+#define SET_TX_DESC_USER_RATE(__pdesc, __val)			\
+	SET_BITS_OFFSET_LE(__pdesc + 16, 31, 1, __val)
+
+/* Dword 5 */
+#define SET_TX_DESC_PACKET_ID(__pdesc, __val)			\
+	SET_BITS_OFFSET_LE(__pdesc + 20, 0, 9, __val)
+#define SET_TX_DESC_TX_RATE(__pdesc, __val)			\
+	SET_BITS_OFFSET_LE(__pdesc + 20, 9, 6, __val)
+#define SET_TX_DESC_DISABLE_FB(__pdesc, __val)			\
+	SET_BITS_OFFSET_LE(__pdesc + 20, 15, 1, __val)
+#define SET_TX_DESC_DATA_RATE_FB_LIMIT(__pdesc, __val)		\
+	SET_BITS_OFFSET_LE(__pdesc + 20, 16, 5, __val)
+#define SET_TX_DESC_TX_AGC(__pdesc, __val)			\
+	SET_BITS_OFFSET_LE(__pdesc + 20, 21, 11, __val)
+
+/* Dword 6 */
+#define SET_TX_DESC_IP_CHECK_SUM(__pdesc, __val)		\
+	SET_BITS_OFFSET_LE(__pdesc + 24, 0, 16, __val)
+#define SET_TX_DESC_TCP_CHECK_SUM(__pdesc, __val)		\
+	SET_BITS_OFFSET_LE(__pdesc + 24, 16, 16, __val)
+
+/* Dword 7 */
+#define SET_TX_DESC_TX_BUFFER_SIZE(__pdesc, __val)		\
+	SET_BITS_OFFSET_LE(__pdesc + 28, 0, 16, __val)
+#define SET_TX_DESC_IP_HEADER_OFFSET(__pdesc, __val)		\
+	SET_BITS_OFFSET_LE(__pdesc + 28, 16, 8, __val)
+#define SET_TX_DESC_TCP_ENABLE(__pdesc, __val)			\
+	SET_BITS_OFFSET_LE(__pdesc + 28, 31, 1, __val)
+
+/* Dword 8 */
+#define SET_TX_DESC_TX_BUFFER_ADDRESS(__pdesc, __val)		\
+	SET_BITS_OFFSET_LE(__pdesc + 32, 0, 32, __val)
+#define GET_TX_DESC_TX_BUFFER_ADDRESS(__pdesc)			\
+	SHIFT_AND_MASK_LE(__pdesc + 32, 0, 32)
+
+/* Dword 9 */
+#define SET_TX_DESC_NEXT_DESC_ADDRESS(__pdesc, __val)		\
+	SET_BITS_OFFSET_LE(__pdesc + 36, 0, 32, __val)
+
+/* Because the PCI Tx descriptors are chaied at the
+ * initialization and all the NextDescAddresses in
+ * these descriptors cannot not be cleared (,or
+ * driver/HW cannot find the next descriptor), the
+ * offset 36 (NextDescAddresses) is reserved when
+ * the desc is cleared. */
+#define	TX_DESC_NEXT_DESC_OFFSET			36
+#define CLEAR_PCI_TX_DESC_CONTENT(__pdesc, _size)		\
+do {								\
+	if (_size > TX_DESC_NEXT_DESC_OFFSET)			\
+		memset(__pdesc, 0, TX_DESC_NEXT_DESC_OFFSET);	\
+	else							\
+		memset(__pdesc, 0, _size);			\
+} while (0);
+
+/* Rx Desc */
+#define RX_STATUS_DESC_SIZE				24
+#define RX_DRV_INFO_SIZE_UNIT				8
+
+/* DWORD 0 */
+#define SET_RX_STATUS_DESC_PKT_LEN(__pdesc, __val)		\
+	SET_BITS_OFFSET_LE(__pdesc, 0, 14, __val)
+#define SET_RX_STATUS_DESC_CRC32(__pdesc, __val)		\
+	SET_BITS_OFFSET_LE(__pdesc, 14, 1, __val)
+#define SET_RX_STATUS_DESC_ICV(__pdesc, __val)			\
+	SET_BITS_OFFSET_LE(__pdesc, 15, 1, __val)
+#define SET_RX_STATUS_DESC_DRVINFO_SIZE(__pdesc, __val)		\
+	SET_BITS_OFFSET_LE(__pdesc, 16, 4, __val)
+#define SET_RX_STATUS_DESC_SECURITY(__pdesc, __val)		\
+	SET_BITS_OFFSET_LE(__pdesc, 20, 3, __val)
+#define SET_RX_STATUS_DESC_QOS(__pdesc, __val)			\
+	SET_BITS_OFFSET_LE(__pdesc, 23, 1, __val)
+#define SET_RX_STATUS_DESC_SHIFT(__pdesc, __val)		\
+	SET_BITS_OFFSET_LE(__pdesc, 24, 2, __val)
+#define SET_RX_STATUS_DESC_PHY_STATUS(__pdesc, __val)		\
+	SET_BITS_OFFSET_LE(__pdesc, 26, 1, __val)
+#define SET_RX_STATUS_DESC_SWDEC(__pdesc, __val)		\
+	SET_BITS_OFFSET_LE(__pdesc, 27, 1, __val)
+#define SET_RX_STATUS_DESC_LAST_SEG(__pdesc, __val)		\
+	SET_BITS_OFFSET_LE(__pdesc, 28, 1, __val)
+#define SET_RX_STATUS_DESC_FIRST_SEG(__pdesc, __val)		\
+	SET_BITS_OFFSET_LE(__pdesc, 29, 1, __val)
+#define SET_RX_STATUS_DESC_EOR(__pdesc, __val)			\
+	SET_BITS_OFFSET_LE(__pdesc, 30, 1, __val)
+#define SET_RX_STATUS_DESC_OWN(__pdesc, __val)			\
+	SET_BITS_OFFSET_LE(__pdesc, 31, 1, __val)
+
+#define GET_RX_STATUS_DESC_PKT_LEN(__pdesc)			\
+	SHIFT_AND_MASK_LE(__pdesc, 0, 14)
+#define GET_RX_STATUS_DESC_CRC32(__pdesc)			\
+	SHIFT_AND_MASK_LE(__pdesc, 14, 1)
+#define GET_RX_STATUS_DESC_ICV(__pdesc)				\
+	SHIFT_AND_MASK_LE(__pdesc, 15, 1)
+#define GET_RX_STATUS_DESC_DRVINFO_SIZE(__pdesc)		\
+	SHIFT_AND_MASK_LE(__pdesc, 16, 4)
+#define GET_RX_STATUS_DESC_SECURITY(__pdesc)			\
+	SHIFT_AND_MASK_LE(__pdesc, 20, 3)
+#define GET_RX_STATUS_DESC_QOS(__pdesc)				\
+	SHIFT_AND_MASK_LE(__pdesc, 23, 1)
+#define GET_RX_STATUS_DESC_SHIFT(__pdesc)			\
+	SHIFT_AND_MASK_LE(__pdesc, 24, 2)
+#define GET_RX_STATUS_DESC_PHY_STATUS(__pdesc)			\
+	SHIFT_AND_MASK_LE(__pdesc, 26, 1)
+#define GET_RX_STATUS_DESC_SWDEC(__pdesc)			\
+	SHIFT_AND_MASK_LE(__pdesc, 27, 1)
+#define GET_RX_STATUS_DESC_LAST_SEG(__pdesc)			\
+	SHIFT_AND_MASK_LE(__pdesc, 28, 1)
+#define GET_RX_STATUS_DESC_FIRST_SEG(__pdesc)			\
+	SHIFT_AND_MASK_LE(__pdesc, 29, 1)
+#define GET_RX_STATUS_DESC_EOR(__pdesc)				\
+	SHIFT_AND_MASK_LE(__pdesc, 30, 1)
+#define GET_RX_STATUS_DESC_OWN(__pdesc)				\
+	SHIFT_AND_MASK_LE(__pdesc, 31, 1)
+
+/* DWORD 1 */
+#define SET_RX_STATUS_DESC_MACID(__pdesc, __val)		\
+	SET_BITS_OFFSET_LE(__pdesc + 4, 0, 5, __val)
+#define SET_RX_STATUS_DESC_TID(__pdesc, __val)			\
+	SET_BITS_OFFSET_LE(__pdesc + 4, 5, 4, __val)
+#define SET_RX_STATUS_DESC_PAGGR(__pdesc, __val)		\
+	SET_BITS_OFFSET_LE(__pdesc + 4, 14, 1, __val)
+#define SET_RX_STATUS_DESC_FAGGR(__pdesc, __val)		\
+	SET_BITS_OFFSET_LE(__pdesc + 4, 15, 1, __val)
+#define SET_RX_STATUS_DESC_A1_FIT(__pdesc, __val)		\
+	SET_BITS_OFFSET_LE(__pdesc + 4, 16, 4, __val)
+#define SET_RX_STATUS_DESC_A2_FIT(__pdesc, __val)		\
+	SET_BITS_OFFSET_LE(__pdesc + 4, 20, 4, __val)
+#define SET_RX_STATUS_DESC_PAM(__pdesc, __val)			\
+	SET_BITS_OFFSET_LE(__pdesc + 4, 24, 1, __val)
+#define SET_RX_STATUS_DESC_PWR(__pdesc, __val)			\
+	SET_BITS_OFFSET_LE(__pdesc + 4, 25, 1, __val)
+#define SET_RX_STATUS_DESC_MOREDATA(__pdesc, __val)		\
+	SET_BITS_OFFSET_LE(__pdesc + 4, 26, 1, __val)
+#define SET_RX_STATUS_DESC_MOREFRAG(__pdesc, __val)		\
+	SET_BITS_OFFSET_LE(__pdesc + 4, 27, 1, __val)
+#define SET_RX_STATUS_DESC_TYPE(__pdesc, __val)			\
+	SET_BITS_OFFSET_LE(__pdesc + 4, 28, 2, __val)
+#define SET_RX_STATUS_DESC_MC(__pdesc, __val)			\
+	SET_BITS_OFFSET_LE(__pdesc + 4, 30, 1, __val)
+#define SET_RX_STATUS_DESC_BC(__pdesc, __val)			\
+	SET_BITS_OFFSET_LE(__pdesc + 4, 31, 1, __val)
+
+#define GET_RX_STATUS_DEC_MACID(__pdesc)			\
+	SHIFT_AND_MASK_LE(__pdesc + 4, 0, 5)
+#define GET_RX_STATUS_DESC_TID(__pdesc)				\
+	SHIFT_AND_MASK_LE(__pdesc + 4, 5, 4)
+#define GET_RX_STATUS_DESC_PAGGR(__pdesc)			\
+	SHIFT_AND_MASK_LE(__pdesc + 4, 14, 1)
+#define GET_RX_STATUS_DESC_FAGGR(__pdesc)			\
+	SHIFT_AND_MASK_LE(__pdesc + 4, 15, 1)
+#define GET_RX_STATUS_DESC_A1_FIT(__pdesc)			\
+	SHIFT_AND_MASK_LE(__pdesc + 4, 16, 4)
+#define GET_RX_STATUS_DESC_A2_FIT(__pdesc)			\
+	SHIFT_AND_MASK_LE(__pdesc + 4, 20, 4)
+#define GET_RX_STATUS_DESC_PAM(__pdesc)				\
+	SHIFT_AND_MASK_LE(__pdesc + 4, 24, 1)
+#define GET_RX_STATUS_DESC_PWR(__pdesc)				\
+	SHIFT_AND_MASK_LE(__pdesc + 4, 25, 1)
+#define GET_RX_STATUS_DESC_MORE_DATA(__pdesc)			\
+	SHIFT_AND_MASK_LE(__pdesc + 4, 26, 1)
+#define GET_RX_STATUS_DESC_MORE_FRAG(__pdesc)			\
+	SHIFT_AND_MASK_LE(__pdesc + 4, 27, 1)
+#define GET_RX_STATUS_DESC_TYPE(__pdesc)			\
+	SHIFT_AND_MASK_LE(__pdesc + 4, 28, 2)
+#define GET_RX_STATUS_DESC_MC(__pdesc)				\
+	SHIFT_AND_MASK_LE(__pdesc + 4, 30, 1)
+#define GET_RX_STATUS_DESC_BC(__pdesc)				\
+	SHIFT_AND_MASK_LE(__pdesc + 4, 31, 1)
+
+/* DWORD 2 */
+#define SET_RX_STATUS_DESC_SEQ(__pdesc, __val)			\
+	SET_BITS_OFFSET_LE(__pdesc + 8, 0, 12, __val)
+#define SET_RX_STATUS_DESC_FRAG(__pdesc, __val)			\
+	SET_BITS_OFFSET_LE(__pdesc + 8, 12, 4, __val)
+#define SET_RX_STATUS_DESC_NEXT_PKTLEN(__pdesc, __val)		\
+	SET_BITS_OFFSET_LE(__pdesc + 8, 16, 8, __val)
+#define SET_RX_STATUS_DESC_NEXT_IND(__pdesc, __val)		\
+	SET_BITS_OFFSET_LE(__pdesc + 8, 30, 1, __val)
+
+#define GET_RX_STATUS_DESC_SEQ(__pdesc)				\
+	SHIFT_AND_MASK_LE(__pdesc + 8, 0, 12)
+#define GET_RX_STATUS_DESC_FRAG(__pdesc)			\
+	SHIFT_AND_MASK_LE(__pdesc + 8, 12, 4)
+#define GET_RX_STATUS_DESC_NEXT_PKTLEN(__pdesc)			\
+	SHIFT_AND_MASK_LE(__pdesc + 8, 16, 8)
+#define GET_RX_STATUS_DESC_NEXT_IND(__pdesc)			\
+	SHIFT_AND_MASK_LE(__pdesc + 8, 30, 1)
+
+/* DWORD 3 */
+#define SET_RX_STATUS_DESC_RX_MCS(__pdesc, __val)		\
+	SET_BITS_OFFSET_LE(__pdesc + 12, 0, 6, __val)
+#define SET_RX_STATUS_DESC_RX_HT(__pdesc, __val)		\
+	SET_BITS_OFFSET_LE(__pdesc + 12, 6, 1, __val)
+#define SET_RX_STATUS_DESC_AMSDU(__pdesc, __val)		\
+	SET_BITS_OFFSET_LE(__pdesc + 12, 7, 1, __val)
+#define SET_RX_STATUS_DESC_SPLCP(__pdesc, __val)		\
+	SET_BITS_OFFSET_LE(__pdesc + 12, 8, 1, __val)
+#define SET_RX_STATUS_DESC_BW(__pdesc, __val)			\
+	SET_BITS_OFFSET_LE(__pdesc + 12, 9, 1, __val)
+#define SET_RX_STATUS_DESC_HTC(__pdesc, __val)			\
+	SET_BITS_OFFSET_LE(__pdesc + 12, 10, 1, __val)
+#define SET_RX_STATUS_DESC_TCP_CHK_RPT(__pdesc, __val)		\
+	SET_BITS_OFFSET_LE(__pdesc + 12, 11, 1, __val)
+#define SET_RX_STATUS_DESC_IP_CHK_RPT(__pdesc, __val)		\
+	SET_BITS_OFFSET_LE(__pdesc + 12, 12, 1, __val)
+#define SET_RX_STATUS_DESC_TCP_CHK_VALID(__pdesc, __val)	\
+	SET_BITS_OFFSET_LE(__pdesc + 12, 13, 1, __val)
+#define SET_RX_STATUS_DESC_HWPC_ERR(__pdesc, __val)		\
+	SET_BITS_OFFSET_LE(__pdesc + 12, 14, 1, __val)
+#define SET_RX_STATUS_DESC_HWPC_IND(__pdesc, __val)		\
+	SET_BITS_OFFSET_LE(__pdesc + 12, 15, 1, __val)
+#define SET_RX_STATUS_DESC_IV0(__pdesc, __val)			\
+	SET_BITS_OFFSET_LE(__pdesc + 12, 16, 16, __val)
+
+#define GET_RX_STATUS_DESC_RX_MCS(__pdesc)			\
+	SHIFT_AND_MASK_LE(__pdesc + 12, 0, 6)
+#define GET_RX_STATUS_DESC_RX_HT(__pdesc)			\
+	SHIFT_AND_MASK_LE(__pdesc + 12, 6, 1)
+#define GET_RX_STATUS_DESC_AMSDU(__pdesc)			\
+	SHIFT_AND_MASK_LE(__pdesc + 12, 7, 1)
+#define GET_RX_STATUS_DESC_SPLCP(__pdesc)			\
+	SHIFT_AND_MASK_LE(__pdesc + 12, 8, 1)
+#define GET_RX_STATUS_DESC_BW(__pdesc)				\
+	SHIFT_AND_MASK_LE(__pdesc + 12, 9, 1)
+#define GET_RX_STATUS_DESC_HTC(__pdesc)				\
+	SHIFT_AND_MASK_LE(__pdesc + 12, 10, 1)
+#define GET_RX_STATUS_DESC_TCP_CHK_RPT(__pdesc)			\
+	SHIFT_AND_MASK_LE(__pdesc + 12, 11, 1)
+#define GET_RX_STATUS_DESC_IP_CHK_RPT(__pdesc)			\
+	SHIFT_AND_MASK_LE(__pdesc + 12, 12, 1)
+#define GET_RX_STATUS_DESC_TCP_CHK_VALID(__pdesc)		\
+	SHIFT_AND_MASK_LE(__pdesc + 12, 13, 1)
+#define GET_RX_STATUS_DESC_HWPC_ERR(__pdesc)			\
+	SHIFT_AND_MASK_LE(__pdesc + 12, 14, 1)
+#define GET_RX_STATUS_DESC_HWPC_IND(__pdesc)			\
+	SHIFT_AND_MASK_LE(__pdesc + 12, 15, 1)
+#define GET_RX_STATUS_DESC_IV0(__pdesc)				\
+	SHIFT_AND_MASK_LE(__pdesc + 12, 16, 16)
+
+/* DWORD 4 */
+#define SET_RX_STATUS_DESC_IV1(__pdesc, __val)			\
+	SET_BITS_OFFSET_LE(__pdesc + 16, 0, 32, __val)
+#define GET_RX_STATUS_DESC_IV1(__pdesc)				\
+	SHIFT_AND_MASK_LE(__pdesc + 16, 0, 32)
+
+/* DWORD 5 */
+#define SET_RX_STATUS_DESC_TSFL(__pdesc, __val)			\
+	SET_BITS_OFFSET_LE(__pdesc + 20, 0, 32, __val)
+#define GET_RX_STATUS_DESC_TSFL(__pdesc)			\
+	SHIFT_AND_MASK_LE(__pdesc + 20, 0, 32)
+
+/* DWORD 6 */
+#define SET_RX_STATUS__DESC_BUFF_ADDR(__pdesc, __val)	\
+	SET_BITS_OFFSET_LE(__pdesc + 24, 0, 32, __val)
+
+#define RX_HAL_IS_CCK_RATE(_pdesc)\
+	(GET_RX_STATUS_DESC_RX_MCS(_pdesc) == DESC92S_RATE1M ||	\
+	 GET_RX_STATUS_DESC_RX_MCS(_pdesc) == DESC92S_RATE2M ||	\
+	 GET_RX_STATUS_DESC_RX_MCS(_pdesc) == DESC92S_RATE5_5M ||\
+	 GET_RX_STATUS_DESC_RX_MCS(_pdesc) == DESC92S_RATE11M)
+
+enum rf_optype {
+	RF_OP_BY_SW_3WIRE = 0,
+	RF_OP_BY_FW,
+	RF_OP_MAX
+};
+
+enum ic_inferiority {
+	IC_INFERIORITY_A = 0,
+	IC_INFERIORITY_B = 1,
+};
+
+enum fwcmd_iotype {
+	/* For DIG DM */
+	FW_CMD_DIG_ENABLE = 0,
+	FW_CMD_DIG_DISABLE = 1,
+	FW_CMD_DIG_HALT = 2,
+	FW_CMD_DIG_RESUME = 3,
+	/* For High Power DM */
+	FW_CMD_HIGH_PWR_ENABLE = 4,
+	FW_CMD_HIGH_PWR_DISABLE = 5,
+	/* For Rate adaptive DM */
+	FW_CMD_RA_RESET = 6,
+	FW_CMD_RA_ACTIVE = 7,
+	FW_CMD_RA_REFRESH_N = 8,
+	FW_CMD_RA_REFRESH_BG = 9,
+	FW_CMD_RA_INIT = 10,
+	/* For FW supported IQK */
+	FW_CMD_IQK_INIT = 11,
+	/* Tx power tracking switch,
+	 * MP driver only */
+	FW_CMD_TXPWR_TRACK_ENABLE = 12,
+	/* Tx power tracking switch,
+	 * MP driver only */
+	FW_CMD_TXPWR_TRACK_DISABLE = 13,
+	/* Tx power tracking with thermal
+	 * indication, for Normal driver */
+	FW_CMD_TXPWR_TRACK_THERMAL = 14,
+	FW_CMD_PAUSE_DM_BY_SCAN = 15,
+	FW_CMD_RESUME_DM_BY_SCAN = 16,
+	FW_CMD_RA_REFRESH_N_COMB = 17,
+	FW_CMD_RA_REFRESH_BG_COMB = 18,
+	FW_CMD_ANTENNA_SW_ENABLE = 19,
+	FW_CMD_ANTENNA_SW_DISABLE = 20,
+	/* Tx Status report for CCX from FW */
+	FW_CMD_TX_FEEDBACK_CCX_ENABLE = 21,
+	/* Indifate firmware that driver
+	 * enters LPS, For PS-Poll issue */
+	FW_CMD_LPS_ENTER = 22,
+	/* Indicate firmware that driver
+	 * leave LPS*/
+	FW_CMD_LPS_LEAVE = 23,
+	/* Set DIG mode to signal strength */
+	FW_CMD_DIG_MODE_SS = 24,
+	/* Set DIG mode to false alarm. */
+	FW_CMD_DIG_MODE_FA = 25,
+	FW_CMD_ADD_A2_ENTRY = 26,
+	FW_CMD_CTRL_DM_BY_DRIVER = 27,
+	FW_CMD_CTRL_DM_BY_DRIVER_NEW = 28,
+	FW_CMD_PAPE_CONTROL = 29,
+	FW_CMD_IQK_ENABLE = 30,
+};
+
+/*
+ * Driver info contain PHY status
+ * and other variabel size info
+ * PHY Status content as below
+ */
+struct  rx_fwinfo {
+	/* DWORD 0 */
+	u8 gain_trsw[4];
+	/* DWORD 1 */
+	u8 pwdb_all;
+	u8 cfosho[4];
+	/* DWORD 2 */
+	u8 cfotail[4];
+	/* DWORD 3 */
+	s8 rxevm[2];
+	s8 rxsnr[4];
+	/* DWORD 4 */
+	u8 pdsnr[2];
+	/* DWORD 5 */
+	u8 csi_current[2];
+	u8 csi_target[2];
+	/* DWORD 6 */
+	u8 sigevm;
+	u8 max_ex_pwr;
+	u8 ex_intf_flag:1;
+	u8 sgi_en:1;
+	u8 rxsc:2;
+	u8 reserve:4;
+};
+
+struct phy_sts_cck_8192s_t {
+	u8 adc_pwdb_x[4];
+	u8 sq_rpt;
+	u8 cck_agc_rpt;
+};
+
+#endif
+
diff -druN linux-2.6.39-libre/drivers/net/wireless/rtlwifi/rtl8192se/dm.c linux-3.0-rc7-libre/drivers/net/wireless/rtlwifi/rtl8192se/dm.c
--- linux-2.6.39-libre/drivers/net/wireless/rtlwifi/rtl8192se/dm.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/net/wireless/rtlwifi/rtl8192se/dm.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,733 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2009-2010  Realtek Corporation.
+ *
+ * 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:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+
+#include "../wifi.h"
+#include "../base.h"
+#include "reg.h"
+#include "def.h"
+#include "phy.h"
+#include "dm.h"
+#include "fw.h"
+
+struct dig_t digtable;
+static const u32 edca_setting_dl[PEER_MAX] = {
+	0xa44f,		/* 0 UNKNOWN */
+	0x5ea44f,	/* 1 REALTEK_90 */
+	0x5ea44f,	/* 2 REALTEK_92SE */
+	0xa630,		/* 3 BROAD	*/
+	0xa44f,		/* 4 RAL */
+	0xa630,		/* 5 ATH */
+	0xa630,		/* 6 CISCO */
+	0xa42b,		/* 7 MARV */
+};
+
+static const u32 edca_setting_dl_gmode[PEER_MAX] = {
+	0x4322,		/* 0 UNKNOWN */
+	0xa44f,		/* 1 REALTEK_90 */
+	0x5ea44f,	/* 2 REALTEK_92SE */
+	0xa42b,		/* 3 BROAD */
+	0x5e4322,	/* 4 RAL */
+	0x4322,		/* 5 ATH */
+	0xa430,		/* 6 CISCO */
+	0x5ea44f,	/* 7 MARV */
+};
+
+static const u32 edca_setting_ul[PEER_MAX] = {
+	0x5e4322,	/* 0 UNKNOWN */
+	0xa44f,		/* 1 REALTEK_90 */
+	0x5ea44f,	/* 2 REALTEK_92SE */
+	0x5ea322,	/* 3 BROAD */
+	0x5ea422,	/* 4 RAL */
+	0x5ea322,	/* 5 ATH */
+	0x3ea44f,	/* 6 CISCO */
+	0x5ea44f,	/* 7 MARV */
+};
+
+static void _rtl92s_dm_check_edca_turbo(struct ieee80211_hw *hw)
+{
+	struct rtl_priv *rtlpriv = rtl_priv(hw);
+	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+
+	static u64 last_txok_cnt;
+	static u64 last_rxok_cnt;
+	u64 cur_txok_cnt = 0;
+	u64 cur_rxok_cnt = 0;
+
+	u32 edca_be_ul = edca_setting_ul[mac->vendor];
+	u32 edca_be_dl = edca_setting_dl[mac->vendor];
+	u32 edca_gmode = edca_setting_dl_gmode[mac->vendor];
+
+	if (mac->link_state != MAC80211_LINKED) {
+		rtlpriv->dm.current_turbo_edca = false;
+		goto dm_checkedcaturbo_exit;
+	}
+
+	if ((!rtlpriv->dm.is_any_nonbepkts) &&
+	    (!rtlpriv->dm.disable_framebursting)) {
+		cur_txok_cnt = rtlpriv->stats.txbytesunicast - last_txok_cnt;
+		cur_rxok_cnt = rtlpriv->stats.rxbytesunicast - last_rxok_cnt;
+
+		if (rtlpriv->phy.rf_type == RF_1T2R) {
+			if (cur_txok_cnt > 4 * cur_rxok_cnt) {
+				/* Uplink TP is present. */
+				if (rtlpriv->dm.is_cur_rdlstate ||
+					!rtlpriv->dm.current_turbo_edca) {
+					rtl_write_dword(rtlpriv, EDCAPARA_BE,
+							edca_be_ul);
+					rtlpriv->dm.is_cur_rdlstate = false;
+				}
+			} else {/* Balance TP is present. */
+				if (!rtlpriv->dm.is_cur_rdlstate ||
+					!rtlpriv->dm.current_turbo_edca) {
+					if (mac->mode == WIRELESS_MODE_G ||
+					    mac->mode == WIRELESS_MODE_B)
+						rtl_write_dword(rtlpriv,
+								EDCAPARA_BE,
+								edca_gmode);
+					else
+						rtl_write_dword(rtlpriv,
+								EDCAPARA_BE,
+								edca_be_dl);
+					rtlpriv->dm.is_cur_rdlstate = true;
+				}
+			}
+			rtlpriv->dm.current_turbo_edca = true;
+		} else {
+			if (cur_rxok_cnt > 4 * cur_txok_cnt) {
+				if (!rtlpriv->dm.is_cur_rdlstate ||
+					!rtlpriv->dm.current_turbo_edca) {
+					if (mac->mode == WIRELESS_MODE_G ||
+					    mac->mode == WIRELESS_MODE_B)
+						rtl_write_dword(rtlpriv,
+								EDCAPARA_BE,
+								edca_gmode);
+					else
+						rtl_write_dword(rtlpriv,
+								EDCAPARA_BE,
+								edca_be_dl);
+					rtlpriv->dm.is_cur_rdlstate = true;
+				}
+			} else {
+				if (rtlpriv->dm.is_cur_rdlstate ||
+					!rtlpriv->dm.current_turbo_edca) {
+					rtl_write_dword(rtlpriv, EDCAPARA_BE,
+							edca_be_ul);
+					rtlpriv->dm.is_cur_rdlstate = false;
+				}
+			}
+			rtlpriv->dm.current_turbo_edca = true;
+		}
+	} else {
+		if (rtlpriv->dm.current_turbo_edca) {
+			u8 tmp = AC0_BE;
+			rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_AC_PARAM,
+						      (u8 *)(&tmp));
+			rtlpriv->dm.current_turbo_edca = false;
+		}
+	}
+
+dm_checkedcaturbo_exit:
+	rtlpriv->dm.is_any_nonbepkts = false;
+	last_txok_cnt = rtlpriv->stats.txbytesunicast;
+	last_rxok_cnt = rtlpriv->stats.rxbytesunicast;
+}
+
+static void _rtl92s_dm_txpowertracking_callback_thermalmeter(
+					struct ieee80211_hw *hw)
+{
+	struct rtl_priv *rtlpriv = rtl_priv(hw);
+	struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
+	u8 thermalvalue = 0;
+
+	rtlpriv->dm.txpower_trackinginit = true;
+
+	thermalvalue = (u8)rtl_get_rfreg(hw, RF90_PATH_A, RF_T_METER, 0x1f);
+
+	RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
+		 ("Readback Thermal Meter = 0x%x pre thermal meter 0x%x "
+		  "eeprom_thermalmeter 0x%x\n", thermalvalue,
+		  rtlpriv->dm.thermalvalue, rtlefuse->eeprom_thermalmeter));
+
+	if (thermalvalue) {
+		rtlpriv->dm.thermalvalue = thermalvalue;
+		rtl92s_phy_set_fw_cmd(hw, FW_CMD_TXPWR_TRACK_THERMAL);
+	}
+
+	rtlpriv->dm.txpowercount = 0;
+}
+
+static void _rtl92s_dm_check_txpowertracking_thermalmeter(
+					struct ieee80211_hw *hw)
+{
+	struct rtl_priv *rtlpriv = rtl_priv(hw);
+	struct rtl_phy *rtlphy = &(rtlpriv->phy);
+	static u8 tm_trigger;
+	u8 tx_power_checkcnt = 5;
+
+	/* 2T2R TP issue */
+	if (rtlphy->rf_type == RF_2T2R)
+		return;
+
+	if (!rtlpriv->dm.txpower_tracking)
+		return;
+
+	if (rtlpriv->dm.txpowercount <= tx_power_checkcnt) {
+		rtlpriv->dm.txpowercount++;
+		return;
+	}
+
+	if (!tm_trigger) {
+		rtl_set_rfreg(hw, RF90_PATH_A, RF_T_METER,
+			      RFREG_OFFSET_MASK, 0x60);
+		tm_trigger = 1;
+	} else {
+		_rtl92s_dm_txpowertracking_callback_thermalmeter(hw);
+		tm_trigger = 0;
+	}
+}
+
+static void _rtl92s_dm_refresh_rateadaptive_mask(struct ieee80211_hw *hw)
+{
+	struct rtl_priv *rtlpriv = rtl_priv(hw);
+	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+	struct rate_adaptive *ra = &(rtlpriv->ra);
+
+	u32 low_rssi_thresh = 0;
+	u32 middle_rssi_thresh = 0;
+	u32 high_rssi_thresh = 0;
+	u8 rssi_level;
+	struct ieee80211_sta *sta = NULL;
+
+	if (is_hal_stop(rtlhal))
+		return;
+
+	if (!rtlpriv->dm.useramask)
+		return;
+
+	if (!rtlpriv->dm.inform_fw_driverctrldm) {
+		rtl92s_phy_set_fw_cmd(hw, FW_CMD_CTRL_DM_BY_DRIVER);
+		rtlpriv->dm.inform_fw_driverctrldm = true;
+	}
+
+	rcu_read_lock();
+	if (mac->opmode == NL80211_IFTYPE_STATION)
+		sta = get_sta(hw, mac->vif, mac->bssid);
+	if ((mac->link_state == MAC80211_LINKED) &&
+	    (mac->opmode == NL80211_IFTYPE_STATION)) {
+		switch (ra->pre_ratr_state) {
+		case DM_RATR_STA_HIGH:
+			high_rssi_thresh = 40;
+			middle_rssi_thresh = 30;
+			low_rssi_thresh = 20;
+			break;
+		case DM_RATR_STA_MIDDLE:
+			high_rssi_thresh = 44;
+			middle_rssi_thresh = 30;
+			low_rssi_thresh = 20;
+			break;
+		case DM_RATR_STA_LOW:
+			high_rssi_thresh = 44;
+			middle_rssi_thresh = 34;
+			low_rssi_thresh = 20;
+			break;
+		case DM_RATR_STA_ULTRALOW:
+			high_rssi_thresh = 44;
+			middle_rssi_thresh = 34;
+			low_rssi_thresh = 24;
+			break;
+		default:
+			high_rssi_thresh = 44;
+			middle_rssi_thresh = 34;
+			low_rssi_thresh = 24;
+			break;
+		}
+
+		if (rtlpriv->dm.undecorated_smoothed_pwdb >
+		    (long)high_rssi_thresh) {
+			ra->ratr_state = DM_RATR_STA_HIGH;
+			rssi_level = 1;
+		} else if (rtlpriv->dm.undecorated_smoothed_pwdb >
+			   (long)middle_rssi_thresh) {
+			ra->ratr_state = DM_RATR_STA_LOW;
+			rssi_level = 3;
+		} else if (rtlpriv->dm.undecorated_smoothed_pwdb >
+			   (long)low_rssi_thresh) {
+			ra->ratr_state = DM_RATR_STA_LOW;
+			rssi_level = 5;
+		} else {
+			ra->ratr_state = DM_RATR_STA_ULTRALOW;
+			rssi_level = 6;
+		}
+
+		if (ra->pre_ratr_state != ra->ratr_state) {
+			RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD, ("RSSI = %ld "
+				"RSSI_LEVEL = %d PreState = %d, CurState = %d\n",
+				rtlpriv->dm.undecorated_smoothed_pwdb,
+				ra->ratr_state,
+				ra->pre_ratr_state, ra->ratr_state));
+
+			rtlpriv->cfg->ops->update_rate_tbl(hw, sta,
+							   ra->ratr_state);
+			ra->pre_ratr_state = ra->ratr_state;
+		}
+	}
+	rcu_read_unlock();
+}
+
+static void _rtl92s_dm_switch_baseband_mrc(struct ieee80211_hw *hw)
+{
+	struct rtl_priv *rtlpriv = rtl_priv(hw);
+	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+	struct rtl_phy *rtlphy = &(rtlpriv->phy);
+	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+	bool current_mrc;
+	bool enable_mrc = true;
+	long tmpentry_maxpwdb = 0;
+	u8 rssi_a = 0;
+	u8 rssi_b = 0;
+
+	if (is_hal_stop(rtlhal))
+		return;
+
+	if ((rtlphy->rf_type == RF_1T1R) || (rtlphy->rf_type == RF_2T2R))
+		return;
+
+	rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_MRC, (u8 *)(&current_mrc));
+
+	if (mac->link_state >= MAC80211_LINKED) {
+		if (rtlpriv->dm.undecorated_smoothed_pwdb > tmpentry_maxpwdb) {
+			rssi_a = rtlpriv->stats.rx_rssi_percentage[RF90_PATH_A];
+			rssi_b = rtlpriv->stats.rx_rssi_percentage[RF90_PATH_B];
+		}
+	}
+
+	/* MRC settings would NOT affect TP on Wireless B mode. */
+	if (mac->mode != WIRELESS_MODE_B) {
+		if ((rssi_a == 0) && (rssi_b == 0)) {
+			enable_mrc = true;
+		} else if (rssi_b > 30) {
+			/* Turn on B-Path */
+			enable_mrc = true;
+		} else if (rssi_b < 5) {
+			/* Turn off B-path  */
+			enable_mrc = false;
+		/* Take care of RSSI differentiation. */
+		} else if (rssi_a > 15 && (rssi_a >= rssi_b)) {
+			if ((rssi_a - rssi_b) > 15)
+				/* Turn off B-path  */
+				enable_mrc = false;
+			else if ((rssi_a - rssi_b) < 10)
+				/* Turn on B-Path */
+				enable_mrc = true;
+			else
+				enable_mrc = current_mrc;
+		} else {
+			/* Turn on B-Path */
+			enable_mrc = true;
+		}
+	}
+
+	/* Update MRC settings if needed. */
+	if (enable_mrc != current_mrc)
+		rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_MRC,
+					      (u8 *)&enable_mrc);
+
+}
+
+void rtl92s_dm_init_edca_turbo(struct ieee80211_hw *hw)
+{
+	struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+	rtlpriv->dm.current_turbo_edca = false;
+	rtlpriv->dm.is_any_nonbepkts = false;
+	rtlpriv->dm.is_cur_rdlstate = false;
+}
+
+static void _rtl92s_dm_init_rate_adaptive_mask(struct ieee80211_hw *hw)
+{
+	struct rtl_priv *rtlpriv = rtl_priv(hw);
+	struct rate_adaptive *ra = &(rtlpriv->ra);
+
+	ra->ratr_state = DM_RATR_STA_MAX;
+	ra->pre_ratr_state = DM_RATR_STA_MAX;
+
+	if (rtlpriv->dm.dm_type == DM_TYPE_BYDRIVER)
+		rtlpriv->dm.useramask = true;
+	else
+		rtlpriv->dm.useramask = false;
+
+	rtlpriv->dm.useramask = false;
+	rtlpriv->dm.inform_fw_driverctrldm = false;
+}
+
+static void _rtl92s_dm_init_txpowertracking_thermalmeter(
+				struct ieee80211_hw *hw)
+{
+	struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+	rtlpriv->dm.txpower_tracking = true;
+	rtlpriv->dm.txpowercount = 0;
+	rtlpriv->dm.txpower_trackinginit = false;
+}
+
+static void _rtl92s_dm_false_alarm_counter_statistics(struct ieee80211_hw *hw)
+{
+	struct rtl_priv *rtlpriv = rtl_priv(hw);
+	struct false_alarm_statistics *falsealm_cnt = &(rtlpriv->falsealm_cnt);
+	u32 ret_value;
+
+	ret_value = rtl_get_bbreg(hw, ROFDM_PHYCOUNTER1, MASKDWORD);
+	falsealm_cnt->cnt_parity_fail = ((ret_value & 0xffff0000) >> 16);
+
+	ret_value = rtl_get_bbreg(hw, ROFDM_PHYCOUNTER2, MASKDWORD);
+	falsealm_cnt->cnt_rate_illegal = (ret_value & 0xffff);
+	falsealm_cnt->cnt_crc8_fail = ((ret_value & 0xffff0000) >> 16);
+	ret_value = rtl_get_bbreg(hw, ROFDM_PHYCOUNTER3, MASKDWORD);
+	falsealm_cnt->cnt_mcs_fail = (ret_value & 0xffff);
+
+	falsealm_cnt->cnt_ofdm_fail = falsealm_cnt->cnt_parity_fail +
+		falsealm_cnt->cnt_rate_illegal + falsealm_cnt->cnt_crc8_fail +
+		falsealm_cnt->cnt_mcs_fail;
+
+	/* read CCK false alarm */
+	ret_value = rtl_get_bbreg(hw, 0xc64, MASKDWORD);
+	falsealm_cnt->cnt_cck_fail = (ret_value & 0xffff);
+	falsealm_cnt->cnt_all =	falsealm_cnt->cnt_ofdm_fail +
+		falsealm_cnt->cnt_cck_fail;
+}
+
+static void rtl92s_backoff_enable_flag(struct ieee80211_hw *hw)
+{
+	struct rtl_priv *rtlpriv = rtl_priv(hw);
+	struct false_alarm_statistics *falsealm_cnt = &(rtlpriv->falsealm_cnt);
+
+	if (falsealm_cnt->cnt_all > digtable.fa_highthresh) {
+		if ((digtable.backoff_val - 6) <
+			digtable.backoffval_range_min)
+			digtable.backoff_val = digtable.backoffval_range_min;
+		else
+			digtable.backoff_val -= 6;
+	} else if (falsealm_cnt->cnt_all < digtable.fa_lowthresh) {
+		if ((digtable.backoff_val + 6) >
+			digtable.backoffval_range_max)
+			digtable.backoff_val =
+				 digtable.backoffval_range_max;
+		else
+			digtable.backoff_val += 6;
+	}
+}
+
+static void _rtl92s_dm_initial_gain_sta_beforeconnect(struct ieee80211_hw *hw)
+{
+	struct rtl_priv *rtlpriv = rtl_priv(hw);
+	struct false_alarm_statistics *falsealm_cnt = &(rtlpriv->falsealm_cnt);
+	static u8 initialized, force_write;
+	u8 initial_gain = 0;
+
+	if ((digtable.pre_sta_connectstate == digtable.cur_sta_connectstate) ||
+		(digtable.cur_sta_connectstate == DIG_STA_BEFORE_CONNECT)) {
+		if (digtable.cur_sta_connectstate == DIG_STA_BEFORE_CONNECT) {
+			if (rtlpriv->psc.rfpwr_state != ERFON)
+				return;
+
+			if (digtable.backoff_enable_flag == true)
+				rtl92s_backoff_enable_flag(hw);
+			else
+				digtable.backoff_val = DM_DIG_BACKOFF;
+
+			if ((digtable.rssi_val + 10 - digtable.backoff_val) >
+				digtable.rx_gain_range_max)
+				digtable.cur_igvalue =
+						digtable.rx_gain_range_max;
+			else if ((digtable.rssi_val + 10 - digtable.backoff_val)
+				 < digtable.rx_gain_range_min)
+				digtable.cur_igvalue =
+						digtable.rx_gain_range_min;
+			else
+				digtable.cur_igvalue = digtable.rssi_val + 10 -
+						digtable.backoff_val;
+
+			if (falsealm_cnt->cnt_all > 10000)
+				digtable.cur_igvalue =
+					 (digtable.cur_igvalue > 0x33) ?
+					 digtable.cur_igvalue : 0x33;
+
+			if (falsealm_cnt->cnt_all > 16000)
+				digtable.cur_igvalue =
+						 digtable.rx_gain_range_max;
+		/* connected -> connected or disconnected -> disconnected  */
+		} else {
+			/* Firmware control DIG, do nothing in driver dm */
+			return;
+		}
+		/* disconnected -> connected or connected ->
+		 * disconnected or beforeconnect->(dis)connected */
+	} else {
+		/* Enable FW DIG */
+		digtable.dig_ext_port_stage = DIG_EXT_PORT_STAGE_MAX;
+		rtl92s_phy_set_fw_cmd(hw, FW_CMD_DIG_ENABLE);
+
+		digtable.backoff_val = DM_DIG_BACKOFF;
+		digtable.cur_igvalue = rtlpriv->phy.default_initialgain[0];
+		digtable.pre_igvalue = 0;
+		return;
+	}
+
+	/* Forced writing to prevent from fw-dig overwriting. */
+	if (digtable.pre_igvalue != rtl_get_bbreg(hw, ROFDM0_XAAGCCORE1,
+						  MASKBYTE0))
+		force_write = 1;
+
+	if ((digtable.pre_igvalue != digtable.cur_igvalue) ||
+	    !initialized || force_write) {
+		/* Disable FW DIG */
+		rtl92s_phy_set_fw_cmd(hw, FW_CMD_DIG_DISABLE);
+
+		initial_gain = (u8)digtable.cur_igvalue;
+
+		/* Set initial gain. */
+		rtl_set_bbreg(hw, ROFDM0_XAAGCCORE1, MASKBYTE0, initial_gain);
+		rtl_set_bbreg(hw, ROFDM0_XBAGCCORE1, MASKBYTE0, initial_gain);
+		digtable.pre_igvalue = digtable.cur_igvalue;
+		initialized = 1;
+		force_write = 0;
+	}
+}
+
+static void _rtl92s_dm_ctrl_initgain_bytwoport(struct ieee80211_hw *hw)
+{
+	struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+	if (rtlpriv->mac80211.act_scanning)
+		return;
+
+	/* Decide the current status and if modify initial gain or not */
+	if (rtlpriv->mac80211.link_state >= MAC80211_LINKED ||
+	    rtlpriv->mac80211.opmode == NL80211_IFTYPE_ADHOC)
+		digtable.cur_sta_connectstate = DIG_STA_CONNECT;
+	else
+		digtable.cur_sta_connectstate = DIG_STA_DISCONNECT;
+
+	digtable.rssi_val = rtlpriv->dm.undecorated_smoothed_pwdb;
+
+	/* Change dig mode to rssi */
+	if (digtable.cur_sta_connectstate != DIG_STA_DISCONNECT) {
+		if (digtable.dig_twoport_algorithm ==
+		    DIG_TWO_PORT_ALGO_FALSE_ALARM) {
+			digtable.dig_twoport_algorithm = DIG_TWO_PORT_ALGO_RSSI;
+			rtl92s_phy_set_fw_cmd(hw, FW_CMD_DIG_MODE_SS);
+		}
+	}
+
+	_rtl92s_dm_false_alarm_counter_statistics(hw);
+	_rtl92s_dm_initial_gain_sta_beforeconnect(hw);
+
+	digtable.pre_sta_connectstate = digtable.cur_sta_connectstate;
+}
+
+static void _rtl92s_dm_ctrl_initgain_byrssi(struct ieee80211_hw *hw)
+{
+	struct rtl_priv *rtlpriv = rtl_priv(hw);
+	struct rtl_phy *rtlphy = &(rtlpriv->phy);
+
+	/* 2T2R TP issue */
+	if (rtlphy->rf_type == RF_2T2R)
+		return;
+
+	if (!rtlpriv->dm.dm_initialgain_enable)
+		return;
+
+	if (digtable.dig_enable_flag == false)
+		return;
+
+	_rtl92s_dm_ctrl_initgain_bytwoport(hw);
+}
+
+static void _rtl92s_dm_dynamic_txpower(struct ieee80211_hw *hw)
+{
+	struct rtl_priv *rtlpriv = rtl_priv(hw);
+	struct rtl_phy *rtlphy = &(rtlpriv->phy);
+	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+	long undecorated_smoothed_pwdb;
+	long txpwr_threshold_lv1, txpwr_threshold_lv2;
+
+	/* 2T2R TP issue */
+	if (rtlphy->rf_type == RF_2T2R)
+		return;
+
+	if (!rtlpriv->dm.dynamic_txpower_enable ||
+	    rtlpriv->dm.dm_flag & HAL_DM_HIPWR_DISABLE) {
+		rtlpriv->dm.dynamic_txhighpower_lvl = TX_HIGHPWR_LEVEL_NORMAL;
+		return;
+	}
+
+	if ((mac->link_state < MAC80211_LINKED) &&
+	    (rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb == 0)) {
+		RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE,
+			 ("Not connected to any\n"));
+
+		rtlpriv->dm.dynamic_txhighpower_lvl = TX_HIGHPWR_LEVEL_NORMAL;
+
+		rtlpriv->dm.last_dtp_lvl = TX_HIGHPWR_LEVEL_NORMAL;
+		return;
+	}
+
+	if (mac->link_state >= MAC80211_LINKED) {
+		if (mac->opmode == NL80211_IFTYPE_ADHOC) {
+			undecorated_smoothed_pwdb =
+			    rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb;
+			RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
+				 ("AP Client PWDB = 0x%lx\n",
+				  undecorated_smoothed_pwdb));
+		} else {
+			undecorated_smoothed_pwdb =
+			    rtlpriv->dm.undecorated_smoothed_pwdb;
+			RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
+				 ("STA Default Port PWDB = 0x%lx\n",
+				  undecorated_smoothed_pwdb));
+		}
+	} else {
+		undecorated_smoothed_pwdb =
+		    rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb;
+
+		RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
+			 ("AP Ext Port PWDB = 0x%lx\n",
+			  undecorated_smoothed_pwdb));
+	}
+
+	txpwr_threshold_lv2 = TX_POWER_NEAR_FIELD_THRESH_LVL2;
+	txpwr_threshold_lv1 = TX_POWER_NEAR_FIELD_THRESH_LVL1;
+
+	if (rtl_get_bbreg(hw, 0xc90, MASKBYTE0) == 1)
+		rtlpriv->dm.dynamic_txhighpower_lvl = TX_HIGHPWR_LEVEL_NORMAL;
+	else if (undecorated_smoothed_pwdb >= txpwr_threshold_lv2)
+		rtlpriv->dm.dynamic_txhighpower_lvl = TX_HIGHPWR_LEVEL_NORMAL2;
+	else if ((undecorated_smoothed_pwdb < (txpwr_threshold_lv2 - 3)) &&
+		(undecorated_smoothed_pwdb >= txpwr_threshold_lv1))
+		rtlpriv->dm.dynamic_txhighpower_lvl = TX_HIGHPWR_LEVEL_NORMAL1;
+	else if (undecorated_smoothed_pwdb < (txpwr_threshold_lv1 - 3))
+		rtlpriv->dm.dynamic_txhighpower_lvl = TX_HIGHPWR_LEVEL_NORMAL;
+
+	if ((rtlpriv->dm.dynamic_txhighpower_lvl != rtlpriv->dm.last_dtp_lvl))
+		rtl92s_phy_set_txpower(hw, rtlphy->current_channel);
+
+	rtlpriv->dm.last_dtp_lvl = rtlpriv->dm.dynamic_txhighpower_lvl;
+}
+
+static void _rtl92s_dm_init_dig(struct ieee80211_hw *hw)
+{
+	struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+	/* Disable DIG scheme now.*/
+	digtable.dig_enable_flag = true;
+	digtable.backoff_enable_flag = true;
+
+	if ((rtlpriv->dm.dm_type == DM_TYPE_BYDRIVER) &&
+	    (hal_get_firmwareversion(rtlpriv) >= 0x3c))
+		digtable.dig_algorithm = DIG_ALGO_BY_TOW_PORT;
+	else
+		digtable.dig_algorithm =
+			 DIG_ALGO_BEFORE_CONNECT_BY_RSSI_AND_ALARM;
+
+	digtable.dig_twoport_algorithm = DIG_TWO_PORT_ALGO_RSSI;
+	digtable.dig_ext_port_stage = DIG_EXT_PORT_STAGE_MAX;
+	/* off=by real rssi value, on=by digtable.rssi_val for new dig */
+	digtable.dig_dbgmode = DM_DBG_OFF;
+	digtable.dig_slgorithm_switch = 0;
+
+	/* 2007/10/04 MH Define init gain threshol. */
+	digtable.dig_state = DM_STA_DIG_MAX;
+	digtable.dig_highpwrstate = DM_STA_DIG_MAX;
+
+	digtable.cur_sta_connectstate = DIG_STA_DISCONNECT;
+	digtable.pre_sta_connectstate = DIG_STA_DISCONNECT;
+	digtable.cur_ap_connectstate = DIG_AP_DISCONNECT;
+	digtable.pre_ap_connectstate = DIG_AP_DISCONNECT;
+
+	digtable.rssi_lowthresh = DM_DIG_THRESH_LOW;
+	digtable.rssi_highthresh = DM_DIG_THRESH_HIGH;
+
+	digtable.fa_lowthresh = DM_FALSEALARM_THRESH_LOW;
+	digtable.fa_highthresh = DM_FALSEALARM_THRESH_HIGH;
+
+	digtable.rssi_highpower_lowthresh = DM_DIG_HIGH_PWR_THRESH_LOW;
+	digtable.rssi_highpower_highthresh = DM_DIG_HIGH_PWR_THRESH_HIGH;
+
+	/* for dig debug rssi value */
+	digtable.rssi_val = 50;
+	digtable.backoff_val = DM_DIG_BACKOFF;
+	digtable.rx_gain_range_max = DM_DIG_MAX;
+
+	digtable.rx_gain_range_min = DM_DIG_MIN;
+
+	digtable.backoffval_range_max = DM_DIG_BACKOFF_MAX;
+	digtable.backoffval_range_min = DM_DIG_BACKOFF_MIN;
+}
+
+static void _rtl92s_dm_init_dynamic_txpower(struct ieee80211_hw *hw)
+{
+	struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+	if ((hal_get_firmwareversion(rtlpriv) >= 60) &&
+	    (rtlpriv->dm.dm_type == DM_TYPE_BYDRIVER))
+		rtlpriv->dm.dynamic_txpower_enable = true;
+	else
+		rtlpriv->dm.dynamic_txpower_enable = false;
+
+	rtlpriv->dm.last_dtp_lvl = TX_HIGHPWR_LEVEL_NORMAL;
+	rtlpriv->dm.dynamic_txhighpower_lvl = TX_HIGHPWR_LEVEL_NORMAL;
+}
+
+void rtl92s_dm_init(struct ieee80211_hw *hw)
+{
+	struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+	rtlpriv->dm.dm_type = DM_TYPE_BYDRIVER;
+	rtlpriv->dm.undecorated_smoothed_pwdb = -1;
+
+	_rtl92s_dm_init_dynamic_txpower(hw);
+	rtl92s_dm_init_edca_turbo(hw);
+	_rtl92s_dm_init_rate_adaptive_mask(hw);
+	_rtl92s_dm_init_txpowertracking_thermalmeter(hw);
+	_rtl92s_dm_init_dig(hw);
+
+	rtl_write_dword(rtlpriv, WFM5, FW_CCA_CHK_ENABLE);
+}
+
+void rtl92s_dm_watchdog(struct ieee80211_hw *hw)
+{
+	_rtl92s_dm_check_edca_turbo(hw);
+	_rtl92s_dm_check_txpowertracking_thermalmeter(hw);
+	_rtl92s_dm_ctrl_initgain_byrssi(hw);
+	_rtl92s_dm_dynamic_txpower(hw);
+	_rtl92s_dm_refresh_rateadaptive_mask(hw);
+	_rtl92s_dm_switch_baseband_mrc(hw);
+}
+
diff -druN linux-2.6.39-libre/drivers/net/wireless/rtlwifi/rtl8192se/dm.h linux-3.0-rc7-libre/drivers/net/wireless/rtlwifi/rtl8192se/dm.h
--- linux-2.6.39-libre/drivers/net/wireless/rtlwifi/rtl8192se/dm.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/net/wireless/rtlwifi/rtl8192se/dm.h	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,164 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2009-2010  Realtek Corporation.
+ *
+ * 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:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+#ifndef	__RTL_92S_DM_H__
+#define __RTL_92S_DM_H__
+
+struct dig_t {
+	u8 dig_enable_flag;
+	u8 dig_algorithm;
+	u8 dig_twoport_algorithm;
+	u8 dig_ext_port_stage;
+	u8 dig_dbgmode;
+	u8 dig_slgorithm_switch;
+
+	long rssi_lowthresh;
+	long rssi_highthresh;
+
+	u32 fa_lowthresh;
+	u32 fa_highthresh;
+
+	long rssi_highpower_lowthresh;
+	long rssi_highpower_highthresh;
+
+	u8 dig_state;
+	u8 dig_highpwrstate;
+	u8 cur_sta_connectstate;
+	u8 pre_sta_connectstate;
+	u8 cur_ap_connectstate;
+	u8 pre_ap_connectstate;
+
+	u8 cur_pd_thstate;
+	u8 pre_pd_thstate;
+	u8 cur_cs_ratiostate;
+	u8 pre_cs_ratiostate;
+
+	u32 pre_igvalue;
+	u32	cur_igvalue;
+
+	u8 backoff_enable_flag;
+	char backoff_val;
+	char backoffval_range_max;
+	char backoffval_range_min;
+	u8 rx_gain_range_max;
+	u8 rx_gain_range_min;
+
+	long rssi_val;
+};
+
+enum dm_dig_alg {
+	DIG_ALGO_BY_FALSE_ALARM = 0,
+	DIG_ALGO_BY_RSSI	= 1,
+	DIG_ALGO_BEFORE_CONNECT_BY_RSSI_AND_ALARM = 2,
+	DIG_ALGO_BY_TOW_PORT = 3,
+	DIG_ALGO_MAX
+};
+
+enum dm_dig_two_port_alg {
+	DIG_TWO_PORT_ALGO_RSSI = 0,
+	DIG_TWO_PORT_ALGO_FALSE_ALARM = 1,
+};
+
+enum dm_dig_dbg {
+	DM_DBG_OFF = 0,
+	DM_DBG_ON = 1,
+	DM_DBG_MAX
+};
+
+enum dm_dig_sta {
+	DM_STA_DIG_OFF = 0,
+	DM_STA_DIG_ON,
+	DM_STA_DIG_MAX
+};
+
+enum dm_dig_connect {
+	DIG_STA_DISCONNECT = 0,
+	DIG_STA_CONNECT = 1,
+	DIG_STA_BEFORE_CONNECT = 2,
+	DIG_AP_DISCONNECT = 3,
+	DIG_AP_CONNECT = 4,
+	DIG_AP_ADD_STATION = 5,
+	DIG_CONNECT_MAX
+};
+
+enum dm_dig_ext_port_alg {
+	DIG_EXT_PORT_STAGE_0 = 0,
+	DIG_EXT_PORT_STAGE_1 = 1,
+	DIG_EXT_PORT_STAGE_2 = 2,
+	DIG_EXT_PORT_STAGE_3 = 3,
+	DIG_EXT_PORT_STAGE_MAX = 4,
+};
+
+enum dm_ratr_sta {
+	DM_RATR_STA_HIGH = 0,
+	DM_RATR_STA_MIDDLEHIGH = 1,
+	DM_RATR_STA_MIDDLE = 2,
+	DM_RATR_STA_MIDDLELOW = 3,
+	DM_RATR_STA_LOW = 4,
+	DM_RATR_STA_ULTRALOW = 5,
+	DM_RATR_STA_MAX
+};
+
+#define DM_TYPE_BYFW			0
+#define DM_TYPE_BYDRIVER		1
+
+#define	TX_HIGH_PWR_LEVEL_NORMAL	0
+#define	TX_HIGH_PWR_LEVEL_LEVEL1	1
+#define	TX_HIGH_PWR_LEVEL_LEVEL2	2
+
+#define	HAL_DM_DIG_DISABLE		BIT(0)	/* Disable Dig */
+#define	HAL_DM_HIPWR_DISABLE		BIT(1)	/* Disable High Power */
+
+#define	TX_HIGHPWR_LEVEL_NORMAL		0
+#define	TX_HIGHPWR_LEVEL_NORMAL1	1
+#define	TX_HIGHPWR_LEVEL_NORMAL2	2
+
+#define	TX_POWER_NEAR_FIELD_THRESH_LVL2	74
+#define	TX_POWER_NEAR_FIELD_THRESH_LVL1	67
+
+#define DM_DIG_THRESH_HIGH		40
+#define DM_DIG_THRESH_LOW		35
+#define	DM_FALSEALARM_THRESH_LOW	40
+#define	DM_FALSEALARM_THRESH_HIGH	1000
+#define	DM_DIG_HIGH_PWR_THRESH_HIGH	75
+#define	DM_DIG_HIGH_PWR_THRESH_LOW	70
+#define	DM_DIG_BACKOFF			12
+#define	DM_DIG_MAX			0x3e
+#define	DM_DIG_MIN			0x1c
+#define	DM_DIG_MIN_Netcore		0x12
+#define	DM_DIG_BACKOFF_MAX		12
+#define	DM_DIG_BACKOFF_MIN		-4
+
+extern struct dig_t digtable;
+
+void rtl92s_dm_watchdog(struct ieee80211_hw *hw);
+void rtl92s_dm_init(struct ieee80211_hw *hw);
+void rtl92s_dm_init_edca_turbo(struct ieee80211_hw *hw);
+
+#endif
+
diff -druN linux-2.6.39-libre/drivers/net/wireless/rtlwifi/rtl8192se/fw.c linux-3.0-rc7-libre/drivers/net/wireless/rtlwifi/rtl8192se/fw.c
--- linux-2.6.39-libre/drivers/net/wireless/rtlwifi/rtl8192se/fw.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/net/wireless/rtlwifi/rtl8192se/fw.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,654 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2009-2010  Realtek Corporation.
+ *
+ * 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:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+
+#include "../wifi.h"
+#include "../pci.h"
+#include "../base.h"
+#include "reg.h"
+#include "def.h"
+#include "fw.h"
+
+static void _rtl92s_fw_set_rqpn(struct ieee80211_hw *hw)
+{
+	struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+	rtl_write_dword(rtlpriv, RQPN, 0xffffffff);
+	rtl_write_dword(rtlpriv, RQPN + 4, 0xffffffff);
+	rtl_write_byte(rtlpriv, RQPN + 8, 0xff);
+	rtl_write_byte(rtlpriv, RQPN + 0xB, 0x80);
+}
+
+static bool _rtl92s_firmware_enable_cpu(struct ieee80211_hw *hw)
+{
+	struct rtl_priv *rtlpriv = rtl_priv(hw);
+	u32 ichecktime = 200;
+	u16 tmpu2b;
+	u8 tmpu1b, cpustatus = 0;
+
+	_rtl92s_fw_set_rqpn(hw);
+
+	/* Enable CPU. */
+	tmpu1b = rtl_read_byte(rtlpriv, SYS_CLKR);
+	/* AFE source */
+	rtl_write_byte(rtlpriv, SYS_CLKR, (tmpu1b | SYS_CPU_CLKSEL));
+
+	tmpu2b = rtl_read_word(rtlpriv, REG_SYS_FUNC_EN);
+	rtl_write_word(rtlpriv, REG_SYS_FUNC_EN, (tmpu2b | FEN_CPUEN));
+
+	/* Polling IMEM Ready after CPU has refilled. */
+	do {
+		cpustatus = rtl_read_byte(rtlpriv, TCR);
+		if (cpustatus & IMEM_RDY) {
+			RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
+				("IMEM Ready after CPU has refilled.\n"));
+			break;
+		}
+
+		udelay(100);
+	} while (ichecktime--);
+
+	if (!(cpustatus & IMEM_RDY))
+		return false;
+
+	return true;
+}
+
+static enum fw_status _rtl92s_firmware_get_nextstatus(
+		enum fw_status fw_currentstatus)
+{
+	enum fw_status	next_fwstatus = 0;
+
+	switch (fw_currentstatus) {
+	case FW_STATUS_INIT:
+		next_fwstatus = FW_STATUS_LOAD_IMEM;
+		break;
+	case FW_STATUS_LOAD_IMEM:
+		next_fwstatus = FW_STATUS_LOAD_EMEM;
+		break;
+	case FW_STATUS_LOAD_EMEM:
+		next_fwstatus = FW_STATUS_LOAD_DMEM;
+		break;
+	case FW_STATUS_LOAD_DMEM:
+		next_fwstatus = FW_STATUS_READY;
+		break;
+	default:
+		break;
+	}
+
+	return next_fwstatus;
+}
+
+static u8 _rtl92s_firmware_header_map_rftype(struct ieee80211_hw *hw)
+{
+	struct rtl_priv *rtlpriv = rtl_priv(hw);
+	struct rtl_phy *rtlphy = &(rtlpriv->phy);
+
+	switch (rtlphy->rf_type) {
+	case RF_1T1R:
+		return 0x11;
+		break;
+	case RF_1T2R:
+		return 0x12;
+		break;
+	case RF_2T2R:
+		return 0x22;
+		break;
+	default:
+		RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG,
+			 ("Unknown RF type(%x)\n",
+			 rtlphy->rf_type));
+		break;
+	}
+	return 0x22;
+}
+
+static void _rtl92s_firmwareheader_priveupdate(struct ieee80211_hw *hw,
+		struct fw_priv *pfw_priv)
+{
+	/* Update RF types for RATR settings. */
+	pfw_priv->rf_config = _rtl92s_firmware_header_map_rftype(hw);
+}
+
+
+
+static bool _rtl92s_cmd_send_packet(struct ieee80211_hw *hw,
+		struct sk_buff *skb, u8 last)
+{
+	struct rtl_priv *rtlpriv = rtl_priv(hw);
+	struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+	struct rtl8192_tx_ring *ring;
+	struct rtl_tx_desc *pdesc;
+	unsigned long flags;
+	u8 idx = 0;
+
+	ring = &rtlpci->tx_ring[TXCMD_QUEUE];
+
+	spin_lock_irqsave(&rtlpriv->locks.irq_th_lock, flags);
+
+	idx = (ring->idx + skb_queue_len(&ring->queue)) % ring->entries;
+	pdesc = &ring->desc[idx];
+	rtlpriv->cfg->ops->fill_tx_cmddesc(hw, (u8 *)pdesc, 1, 1, skb);
+	__skb_queue_tail(&ring->queue, skb);
+
+	spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock, flags);
+
+	return true;
+}
+
+static bool _rtl92s_firmware_downloadcode(struct ieee80211_hw *hw,
+		u8 *code_virtual_address, u32 buffer_len)
+{
+	struct rtl_priv *rtlpriv = rtl_priv(hw);
+	struct sk_buff *skb;
+	struct rtl_tcb_desc *tcb_desc;
+	unsigned char *seg_ptr;
+	u16 frag_threshold = MAX_FIRMWARE_CODE_SIZE;
+	u16 frag_length, frag_offset = 0;
+	u16 extra_descoffset = 0;
+	u8 last_inipkt = 0;
+
+	_rtl92s_fw_set_rqpn(hw);
+
+	if (buffer_len >= MAX_FIRMWARE_CODE_SIZE) {
+		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
+			("Size over FIRMWARE_CODE_SIZE!\n"));
+
+		return false;
+	}
+
+	extra_descoffset = 0;
+
+	do {
+		if ((buffer_len - frag_offset) > frag_threshold) {
+			frag_length = frag_threshold + extra_descoffset;
+		} else {
+			frag_length = (u16)(buffer_len - frag_offset +
+					    extra_descoffset);
+			last_inipkt = 1;
+		}
+
+		/* Allocate skb buffer to contain firmware */
+		/* info and tx descriptor info. */
+		skb = dev_alloc_skb(frag_length);
+		skb_reserve(skb, extra_descoffset);
+		seg_ptr = (u8 *)skb_put(skb, (u32)(frag_length -
+					extra_descoffset));
+		memcpy(seg_ptr, code_virtual_address + frag_offset,
+		       (u32)(frag_length - extra_descoffset));
+
+		tcb_desc = (struct rtl_tcb_desc *)(skb->cb);
+		tcb_desc->queue_index = TXCMD_QUEUE;
+		tcb_desc->cmd_or_init = DESC_PACKET_TYPE_INIT;
+		tcb_desc->last_inipkt = last_inipkt;
+
+		_rtl92s_cmd_send_packet(hw, skb, last_inipkt);
+
+		frag_offset += (frag_length - extra_descoffset);
+
+	} while (frag_offset < buffer_len);
+
+	rtl_write_byte(rtlpriv, TP_POLL, TPPOLL_CQ);
+
+	return true ;
+}
+
+static bool _rtl92s_firmware_checkready(struct ieee80211_hw *hw,
+		u8 loadfw_status)
+{
+	struct rtl_priv *rtlpriv = rtl_priv(hw);
+	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+	struct rt_firmware *firmware = (struct rt_firmware *)rtlhal->pfirmware;
+	u32 tmpu4b;
+	u8 cpustatus = 0;
+	short pollingcnt = 1000;
+	bool rtstatus = true;
+
+	RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("LoadStaus(%d)\n",
+		 loadfw_status));
+
+	firmware->fwstatus = (enum fw_status)loadfw_status;
+
+	switch (loadfw_status) {
+	case FW_STATUS_LOAD_IMEM:
+		/* Polling IMEM code done. */
+		do {
+			cpustatus = rtl_read_byte(rtlpriv, TCR);
+			if (cpustatus & IMEM_CODE_DONE)
+				break;
+			udelay(5);
+		} while (pollingcnt--);
+
+		if (!(cpustatus & IMEM_CHK_RPT) || (pollingcnt <= 0)) {
+			RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
+				 ("FW_STATUS_LOAD_IMEM"
+				 " FAIL CPU, Status=%x\r\n", cpustatus));
+			goto status_check_fail;
+		}
+		break;
+
+	case FW_STATUS_LOAD_EMEM:
+		/* Check Put Code OK and Turn On CPU */
+		/* Polling EMEM code done. */
+		do {
+			cpustatus = rtl_read_byte(rtlpriv, TCR);
+			if (cpustatus & EMEM_CODE_DONE)
+				break;
+			udelay(5);
+		} while (pollingcnt--);
+
+		if (!(cpustatus & EMEM_CHK_RPT) || (pollingcnt <= 0)) {
+			RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
+				 ("FW_STATUS_LOAD_EMEM"
+				 " FAIL CPU, Status=%x\r\n", cpustatus));
+			goto status_check_fail;
+		}
+
+		/* Turn On CPU */
+		rtstatus = _rtl92s_firmware_enable_cpu(hw);
+		if (rtstatus != true) {
+			RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
+				 ("Enable CPU fail!\n"));
+			goto status_check_fail;
+		}
+		break;
+
+	case FW_STATUS_LOAD_DMEM:
+		/* Polling DMEM code done */
+		do {
+			cpustatus = rtl_read_byte(rtlpriv, TCR);
+			if (cpustatus & DMEM_CODE_DONE)
+				break;
+			udelay(5);
+		} while (pollingcnt--);
+
+		if (!(cpustatus & DMEM_CODE_DONE) || (pollingcnt <= 0)) {
+			RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
+				 ("Polling  DMEM code done"
+				 " fail ! cpustatus(%#x)\n", cpustatus));
+			goto status_check_fail;
+		}
+
+		RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
+			 ("DMEM code download success,"
+			" cpustatus(%#x)\n", cpustatus));
+
+		/* Prevent Delay too much and being scheduled out */
+		/* Polling Load Firmware ready */
+		pollingcnt = 2000;
+		do {
+			cpustatus = rtl_read_byte(rtlpriv, TCR);
+			if (cpustatus & FWRDY)
+				break;
+			udelay(40);
+		} while (pollingcnt--);
+
+		RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
+			 ("Polling Load Firmware ready,"
+			" cpustatus(%x)\n",	cpustatus));
+
+		if (((cpustatus & LOAD_FW_READY) != LOAD_FW_READY) ||
+		    (pollingcnt <= 0)) {
+			RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
+				 ("Polling Load Firmware"
+				" ready fail ! cpustatus(%x)\n", cpustatus));
+			goto status_check_fail;
+		}
+
+		/* If right here, we can set TCR/RCR to desired value  */
+		/* and config MAC lookback mode to normal mode */
+		tmpu4b = rtl_read_dword(rtlpriv, TCR);
+		rtl_write_dword(rtlpriv, TCR, (tmpu4b & (~TCR_ICV)));
+
+		tmpu4b = rtl_read_dword(rtlpriv, RCR);
+		rtl_write_dword(rtlpriv, RCR, (tmpu4b | RCR_APPFCS |
+				RCR_APP_ICV | RCR_APP_MIC));
+
+		RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
+			 ("Current RCR settings(%#x)\n", tmpu4b));
+
+		/* Set to normal mode. */
+		rtl_write_byte(rtlpriv, LBKMD_SEL, LBK_NORMAL);
+		break;
+
+	default:
+		RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG,
+			 ("Unknown status check!\n"));
+		rtstatus = false;
+		break;
+	}
+
+status_check_fail:
+	RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("loadfw_status(%d), "
+		 "rtstatus(%x)\n", loadfw_status, rtstatus));
+	return rtstatus;
+}
+
+int rtl92s_download_fw(struct ieee80211_hw *hw)
+{
+	struct rtl_priv *rtlpriv = rtl_priv(hw);
+	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+	struct rt_firmware *firmware = NULL;
+	struct fw_hdr *pfwheader;
+	struct fw_priv *pfw_priv = NULL;
+	u8 *puc_mappedfile = NULL;
+	u32 ul_filelength = 0;
+	u32 file_length = 0;
+	u8 fwhdr_size = RT_8192S_FIRMWARE_HDR_SIZE;
+	u8 fwstatus = FW_STATUS_INIT;
+	bool rtstatus = true;
+
+	if (!rtlhal->pfirmware)
+		return 1;
+
+	firmware = (struct rt_firmware *)rtlhal->pfirmware;
+	firmware->fwstatus = FW_STATUS_INIT;
+
+	puc_mappedfile = firmware->sz_fw_tmpbuffer;
+	file_length = firmware->sz_fw_tmpbufferlen;
+
+	/* 1. Retrieve FW header. */
+	firmware->pfwheader = (struct fw_hdr *) puc_mappedfile;
+	pfwheader = firmware->pfwheader;
+	firmware->firmwareversion =  byte(pfwheader->version, 0);
+	firmware->pfwheader->fwpriv.hci_sel = 1;/* pcie */
+
+	RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("signature:%x, version:"
+		 "%x, size:%x,"
+		 "imemsize:%x, sram size:%x\n", pfwheader->signature,
+		 pfwheader->version, pfwheader->dmem_size,
+		 pfwheader->img_imem_size, pfwheader->img_sram_size));
+
+	/* 2. Retrieve IMEM image. */
+	if ((pfwheader->img_imem_size == 0) || (pfwheader->img_imem_size >
+	    sizeof(firmware->fw_imem))) {
+		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
+			("memory for data image is less than IMEM required\n"));
+		goto fail;
+	} else {
+		puc_mappedfile += fwhdr_size;
+
+		memcpy(firmware->fw_imem, puc_mappedfile,
+		       pfwheader->img_imem_size);
+		firmware->fw_imem_len = pfwheader->img_imem_size;
+	}
+
+	/* 3. Retriecve EMEM image. */
+	if (pfwheader->img_sram_size > sizeof(firmware->fw_emem)) {
+		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
+			("memory for data image is less than EMEM required\n"));
+		goto fail;
+	} else {
+		puc_mappedfile += firmware->fw_imem_len;
+
+		memcpy(firmware->fw_emem, puc_mappedfile,
+		       pfwheader->img_sram_size);
+		firmware->fw_emem_len = pfwheader->img_sram_size;
+	}
+
+	/* 4. download fw now */
+	fwstatus = _rtl92s_firmware_get_nextstatus(firmware->fwstatus);
+	while (fwstatus != FW_STATUS_READY) {
+		/* Image buffer redirection. */
+		switch (fwstatus) {
+		case FW_STATUS_LOAD_IMEM:
+			puc_mappedfile = firmware->fw_imem;
+			ul_filelength = firmware->fw_imem_len;
+			break;
+		case FW_STATUS_LOAD_EMEM:
+			puc_mappedfile = firmware->fw_emem;
+			ul_filelength = firmware->fw_emem_len;
+			break;
+		case FW_STATUS_LOAD_DMEM:
+			/* Partial update the content of header private. */
+			pfwheader = firmware->pfwheader;
+			pfw_priv = &pfwheader->fwpriv;
+			_rtl92s_firmwareheader_priveupdate(hw, pfw_priv);
+			puc_mappedfile = (u8 *)(firmware->pfwheader) +
+					RT_8192S_FIRMWARE_HDR_EXCLUDE_PRI_SIZE;
+			ul_filelength = fwhdr_size -
+					RT_8192S_FIRMWARE_HDR_EXCLUDE_PRI_SIZE;
+			break;
+		default:
+			RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
+					("Unexpected Download step!!\n"));
+			goto fail;
+			break;
+		}
+
+		/* <2> Download image file */
+		rtstatus = _rtl92s_firmware_downloadcode(hw, puc_mappedfile,
+				ul_filelength);
+
+		if (rtstatus != true) {
+			RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("fail!\n"));
+			goto fail;
+		}
+
+		/* <3> Check whether load FW process is ready */
+		rtstatus = _rtl92s_firmware_checkready(hw, fwstatus);
+		if (rtstatus != true) {
+			RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("fail!\n"));
+			goto fail;
+		}
+
+		fwstatus = _rtl92s_firmware_get_nextstatus(firmware->fwstatus);
+	}
+
+	return rtstatus;
+fail:
+	return 0;
+}
+
+static u32 _rtl92s_fill_h2c_cmd(struct sk_buff *skb, u32 h2cbufferlen,
+				u32 cmd_num, u32 *pelement_id, u32 *pcmd_len,
+				u8 **pcmb_buffer, u8 *cmd_start_seq)
+{
+	u32 totallen = 0, len = 0, tx_desclen = 0;
+	u32 pre_continueoffset = 0;
+	u8 *ph2c_buffer;
+	u8 i = 0;
+
+	do {
+		/* 8 - Byte aligment */
+		len = H2C_TX_CMD_HDR_LEN + N_BYTE_ALIGMENT(pcmd_len[i], 8);
+
+		/* Buffer length is not enough */
+		if (h2cbufferlen < totallen + len + tx_desclen)
+			break;
+
+		/* Clear content */
+		ph2c_buffer = (u8 *)skb_put(skb, (u32)len);
+		memset((ph2c_buffer + totallen + tx_desclen), 0, len);
+
+		/* CMD len */
+		SET_BITS_TO_LE_4BYTE((ph2c_buffer + totallen + tx_desclen),
+				      0, 16, pcmd_len[i]);
+
+		/* CMD ID */
+		SET_BITS_TO_LE_4BYTE((ph2c_buffer + totallen + tx_desclen),
+				      16, 8, pelement_id[i]);
+
+		/* CMD Sequence */
+		*cmd_start_seq = *cmd_start_seq % 0x80;
+		SET_BITS_TO_LE_4BYTE((ph2c_buffer + totallen + tx_desclen),
+				      24, 7, *cmd_start_seq);
+		++*cmd_start_seq;
+
+		/* Copy memory */
+		memcpy((ph2c_buffer + totallen + tx_desclen +
+			H2C_TX_CMD_HDR_LEN), pcmb_buffer[i], pcmd_len[i]);
+
+		/* CMD continue */
+		/* set the continue in prevoius cmd. */
+		if (i < cmd_num - 1)
+			SET_BITS_TO_LE_4BYTE((ph2c_buffer + pre_continueoffset),
+					      31, 1, 1);
+
+		pre_continueoffset = totallen;
+
+		totallen += len;
+	} while (++i < cmd_num);
+
+	return totallen;
+}
+
+static u32 _rtl92s_get_h2c_cmdlen(u32 h2cbufferlen, u32 cmd_num, u32 *pcmd_len)
+{
+	u32 totallen = 0, len = 0, tx_desclen = 0;
+	u8 i = 0;
+
+	do {
+		/* 8 - Byte aligment */
+		len = H2C_TX_CMD_HDR_LEN + N_BYTE_ALIGMENT(pcmd_len[i], 8);
+
+		/* Buffer length is not enough */
+		if (h2cbufferlen < totallen + len + tx_desclen)
+			break;
+
+		totallen += len;
+	} while (++i < cmd_num);
+
+	return totallen + tx_desclen;
+}
+
+static bool _rtl92s_firmware_set_h2c_cmd(struct ieee80211_hw *hw, u8 h2c_cmd,
+					 u8 *pcmd_buffer)
+{
+	struct rtl_priv *rtlpriv = rtl_priv(hw);
+	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+	struct rtl_tcb_desc *cb_desc;
+	struct sk_buff *skb;
+	u32	element_id = 0;
+	u32	cmd_len = 0;
+	u32	len;
+
+	switch (h2c_cmd) {
+	case FW_H2C_SETPWRMODE:
+		element_id = H2C_SETPWRMODE_CMD ;
+		cmd_len = sizeof(struct h2c_set_pwrmode_parm);
+		break;
+	case FW_H2C_JOINBSSRPT:
+		element_id = H2C_JOINBSSRPT_CMD;
+		cmd_len = sizeof(struct h2c_joinbss_rpt_parm);
+		break;
+	case FW_H2C_WOWLAN_UPDATE_GTK:
+		element_id = H2C_WOWLAN_UPDATE_GTK_CMD;
+		cmd_len = sizeof(struct h2c_wpa_two_way_parm);
+		break;
+	case FW_H2C_WOWLAN_UPDATE_IV:
+		element_id = H2C_WOWLAN_UPDATE_IV_CMD;
+		cmd_len = sizeof(unsigned long long);
+		break;
+	case FW_H2C_WOWLAN_OFFLOAD:
+		element_id = H2C_WOWLAN_FW_OFFLOAD;
+		cmd_len = sizeof(u8);
+		break;
+	default:
+		break;
+	}
+
+	len = _rtl92s_get_h2c_cmdlen(MAX_TRANSMIT_BUFFER_SIZE, 1, &cmd_len);
+	skb = dev_alloc_skb(len);
+	cb_desc = (struct rtl_tcb_desc *)(skb->cb);
+	cb_desc->queue_index = TXCMD_QUEUE;
+	cb_desc->cmd_or_init = DESC_PACKET_TYPE_NORMAL;
+	cb_desc->last_inipkt = false;
+
+	_rtl92s_fill_h2c_cmd(skb, MAX_TRANSMIT_BUFFER_SIZE, 1, &element_id,
+			&cmd_len, &pcmd_buffer,	&rtlhal->h2c_txcmd_seq);
+	_rtl92s_cmd_send_packet(hw, skb, false);
+	rtlpriv->cfg->ops->tx_polling(hw, TXCMD_QUEUE);
+
+	return true;
+}
+
+void rtl92s_set_fw_pwrmode_cmd(struct ieee80211_hw *hw, u8 Mode)
+{
+	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+	struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
+	struct h2c_set_pwrmode_parm	pwrmode;
+	u16 max_wakeup_period = 0;
+
+	pwrmode.mode = Mode;
+	pwrmode.flag_low_traffic_en = 0;
+	pwrmode.flag_lpnav_en = 0;
+	pwrmode.flag_rf_low_snr_en = 0;
+	pwrmode.flag_dps_en = 0;
+	pwrmode.bcn_rx_en = 0;
+	pwrmode.bcn_to = 0;
+	SET_BITS_TO_LE_2BYTE((u8 *)(&pwrmode) + 8, 0, 16,
+			mac->vif->bss_conf.beacon_int);
+	pwrmode.app_itv = 0;
+	pwrmode.awake_bcn_itvl = ppsc->reg_max_lps_awakeintvl;
+	pwrmode.smart_ps = 1;
+	pwrmode.bcn_pass_period = 10;
+
+	/* Set beacon pass count */
+	if (pwrmode.mode == FW_PS_MIN_MODE)
+		max_wakeup_period = mac->vif->bss_conf.beacon_int;
+	else if (pwrmode.mode == FW_PS_MAX_MODE)
+		max_wakeup_period = mac->vif->bss_conf.beacon_int *
+			mac->vif->bss_conf.dtim_period;
+
+	if (max_wakeup_period >= 500)
+		pwrmode.bcn_pass_cnt = 1;
+	else if ((max_wakeup_period >= 300) && (max_wakeup_period < 500))
+		pwrmode.bcn_pass_cnt = 2;
+	else if ((max_wakeup_period >= 200) && (max_wakeup_period < 300))
+		pwrmode.bcn_pass_cnt = 3;
+	else if ((max_wakeup_period >= 20) && (max_wakeup_period < 200))
+		pwrmode.bcn_pass_cnt = 5;
+	else
+		pwrmode.bcn_pass_cnt = 1;
+
+	_rtl92s_firmware_set_h2c_cmd(hw, FW_H2C_SETPWRMODE, (u8 *)&pwrmode);
+
+}
+
+void rtl92s_set_fw_joinbss_report_cmd(struct ieee80211_hw *hw,
+		u8 mstatus, u8 ps_qosinfo)
+{
+	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+	struct h2c_joinbss_rpt_parm joinbss_rpt;
+
+	joinbss_rpt.opmode = mstatus;
+	joinbss_rpt.ps_qos_info = ps_qosinfo;
+	joinbss_rpt.bssid[0] = mac->bssid[0];
+	joinbss_rpt.bssid[1] = mac->bssid[1];
+	joinbss_rpt.bssid[2] = mac->bssid[2];
+	joinbss_rpt.bssid[3] = mac->bssid[3];
+	joinbss_rpt.bssid[4] = mac->bssid[4];
+	joinbss_rpt.bssid[5] = mac->bssid[5];
+	SET_BITS_TO_LE_2BYTE((u8 *)(&joinbss_rpt) + 8, 0, 16,
+			mac->vif->bss_conf.beacon_int);
+	SET_BITS_TO_LE_2BYTE((u8 *)(&joinbss_rpt) + 10, 0, 16, mac->assoc_id);
+
+	_rtl92s_firmware_set_h2c_cmd(hw, FW_H2C_JOINBSSRPT, (u8 *)&joinbss_rpt);
+}
+
diff -druN linux-2.6.39-libre/drivers/net/wireless/rtlwifi/rtl8192se/fw.h linux-3.0-rc7-libre/drivers/net/wireless/rtlwifi/rtl8192se/fw.h
--- linux-2.6.39-libre/drivers/net/wireless/rtlwifi/rtl8192se/fw.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/net/wireless/rtlwifi/rtl8192se/fw.h	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,375 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2009-2010  Realtek Corporation.
+ *
+ * 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:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+#ifndef __REALTEK_FIRMWARE92S_H__
+#define __REALTEK_FIRMWARE92S_H__
+
+#define RTL8190_MAX_FIRMWARE_CODE_SIZE		64000
+#define RTL8190_CPU_START_OFFSET		0x80
+/* Firmware Local buffer size. 64k */
+#define	MAX_FIRMWARE_CODE_SIZE			0xFF00
+
+#define	RT_8192S_FIRMWARE_HDR_SIZE		80
+#define RT_8192S_FIRMWARE_HDR_EXCLUDE_PRI_SIZE	32
+
+/* support till 64 bit bus width OS */
+#define MAX_DEV_ADDR_SIZE			8
+#define MAX_FIRMWARE_INFORMATION_SIZE		32
+#define MAX_802_11_HEADER_LENGTH		(40 + \
+						MAX_FIRMWARE_INFORMATION_SIZE)
+#define ENCRYPTION_MAX_OVERHEAD			128
+#define MAX_FRAGMENT_COUNT			8
+#define MAX_TRANSMIT_BUFFER_SIZE		(1600 + \
+						(MAX_802_11_HEADER_LENGTH + \
+						ENCRYPTION_MAX_OVERHEAD) *\
+						MAX_FRAGMENT_COUNT)
+
+#define H2C_TX_CMD_HDR_LEN			8
+
+/* The following DM control code are for Reg0x364, */
+#define	FW_DIG_ENABLE_CTL			BIT(0)
+#define	FW_HIGH_PWR_ENABLE_CTL			BIT(1)
+#define	FW_SS_CTL				BIT(2)
+#define	FW_RA_INIT_CTL				BIT(3)
+#define	FW_RA_BG_CTL				BIT(4)
+#define	FW_RA_N_CTL				BIT(5)
+#define	FW_PWR_TRK_CTL				BIT(6)
+#define	FW_IQK_CTL				BIT(7)
+#define	FW_FA_CTL				BIT(8)
+#define	FW_DRIVER_CTRL_DM_CTL			BIT(9)
+#define	FW_PAPE_CTL_BY_SW_HW			BIT(10)
+#define	FW_DISABLE_ALL_DM			0
+#define	FW_PWR_TRK_PARAM_CLR			0x0000ffff
+#define	FW_RA_PARAM_CLR				0xffff0000
+
+enum desc_packet_type {
+	DESC_PACKET_TYPE_INIT = 0,
+	DESC_PACKET_TYPE_NORMAL = 1,
+};
+
+/* 8-bytes alignment required */
+struct fw_priv {
+	/* --- long word 0 ---- */
+	/* 0x12: CE product, 0x92: IT product */
+	u8 signature_0;
+	/* 0x87: CE product, 0x81: IT product */
+	u8 signature_1;
+	/* 0x81: PCI-AP, 01:PCIe, 02: 92S-U,
+	 * 0x82: USB-AP, 0x12: 72S-U, 03:SDIO */
+	u8 hci_sel;
+	/* the same value as reigster value  */
+	u8 chip_version;
+	/* customer  ID low byte */
+	u8 customer_id_0;
+	/* customer  ID high byte */
+	u8 customer_id_1;
+	/* 0x11:  1T1R, 0x12: 1T2R,
+	 * 0x92: 1T2R turbo, 0x22: 2T2R */
+	u8 rf_config;
+	/* 4: 4EP, 6: 6EP, 11: 11EP */
+	u8 usb_ep_num;
+
+	/* --- long word 1 ---- */
+	/* regulatory class bit map 0 */
+	u8 regulatory_class_0;
+	/* regulatory class bit map 1 */
+	u8 regulatory_class_1;
+	/* regulatory class bit map 2 */
+	u8 regulatory_class_2;
+	/* regulatory class bit map 3 */
+	u8 regulatory_class_3;
+	/* 0:SWSI, 1:HWSI, 2:HWPI */
+	u8 rfintfs;
+	u8 def_nettype;
+	u8 rsvd010;
+	u8 rsvd011;
+
+	/* --- long word 2 ---- */
+	/* 0x00: normal, 0x03: MACLBK, 0x01: PHYLBK */
+	u8 lbk_mode;
+	/* 1: for MP use, 0: for normal
+	 * driver (to be discussed) */
+	u8 mp_mode;
+	u8 rsvd020;
+	u8 rsvd021;
+	u8 rsvd022;
+	u8 rsvd023;
+	u8 rsvd024;
+	u8 rsvd025;
+
+	/* --- long word 3 ---- */
+	/* QoS enable */
+	u8 qos_en;
+	/* 40MHz BW enable */
+	/* 4181 convert AMSDU to AMPDU, 0: disable */
+	u8 bw_40mhz_en;
+	u8 amsdu2ampdu_en;
+	/* 11n AMPDU enable */
+	u8 ampdu_en;
+	/* FW offloads, 0: driver handles */
+	u8 rate_control_offload;
+	/* FW offloads, 0: driver handles */
+	u8 aggregation_offload;
+	u8 rsvd030;
+	u8 rsvd031;
+
+	/* --- long word 4 ---- */
+	/* 1. FW offloads, 0: driver handles */
+	u8 beacon_offload;
+	/* 2. FW offloads, 0: driver handles */
+	u8 mlme_offload;
+	/* 3. FW offloads, 0: driver handles */
+	u8 hwpc_offload;
+	/* 4. FW offloads, 0: driver handles */
+	u8 tcp_checksum_offload;
+	/* 5. FW offloads, 0: driver handles */
+	u8 tcp_offload;
+	/* 6. FW offloads, 0: driver handles */
+	u8 ps_control_offload;
+	/* 7. FW offloads, 0: driver handles */
+	u8 wwlan_offload;
+	u8 rsvd040;
+
+	/* --- long word 5 ---- */
+	/* tcp tx packet length low byte */
+	u8 tcp_tx_frame_len_L;
+	/* tcp tx packet length high byte */
+	u8 tcp_tx_frame_len_H;
+	/* tcp rx packet length low byte */
+	u8 tcp_rx_frame_len_L;
+	/* tcp rx packet length high byte */
+	u8 tcp_rx_frame_len_H;
+	u8 rsvd050;
+	u8 rsvd051;
+	u8 rsvd052;
+	u8 rsvd053;
+};
+
+/* 8-byte alinment required */
+struct fw_hdr {
+
+	/* --- LONG WORD 0 ---- */
+	u16 signature;
+	/* 0x8000 ~ 0x8FFF for FPGA version,
+	 * 0x0000 ~ 0x7FFF for ASIC version, */
+	u16 version;
+	/* define the size of boot loader */
+	u32 dmem_size;
+
+
+	/* --- LONG WORD 1 ---- */
+	/* define the size of FW in IMEM */
+	u32 img_imem_size;
+	/* define the size of FW in SRAM */
+	u32 img_sram_size;
+
+	/* --- LONG WORD 2 ---- */
+	/* define the size of DMEM variable */
+	u32 fw_priv_size;
+	u32 rsvd0;
+
+	/* --- LONG WORD 3 ---- */
+	u32 rsvd1;
+	u32 rsvd2;
+
+	struct fw_priv fwpriv;
+
+} ;
+
+enum fw_status {
+	FW_STATUS_INIT = 0,
+	FW_STATUS_LOAD_IMEM = 1,
+	FW_STATUS_LOAD_EMEM = 2,
+	FW_STATUS_LOAD_DMEM = 3,
+	FW_STATUS_READY = 4,
+};
+
+struct rt_firmware {
+	struct fw_hdr *pfwheader;
+	enum fw_status fwstatus;
+	u16 firmwareversion;
+	u8 fw_imem[RTL8190_MAX_FIRMWARE_CODE_SIZE];
+	u8 fw_emem[RTL8190_MAX_FIRMWARE_CODE_SIZE];
+	u32 fw_imem_len;
+	u32 fw_emem_len;
+	u8 sz_fw_tmpbuffer[164000];
+	u32 sz_fw_tmpbufferlen;
+	u16 cmdpacket_fragthresold;
+};
+
+struct h2c_set_pwrmode_parm {
+	u8 mode;
+	u8 flag_low_traffic_en;
+	u8 flag_lpnav_en;
+	u8 flag_rf_low_snr_en;
+	/* 1: dps, 0: 32k */
+	u8 flag_dps_en;
+	u8 bcn_rx_en;
+	u8 bcn_pass_cnt;
+	/* beacon TO (ms). ¡§=0¡¨ no limit. */
+	u8 bcn_to;
+	u16	bcn_itv;
+	/* only for VOIP mode. */
+	u8 app_itv;
+	u8 awake_bcn_itvl;
+	u8 smart_ps;
+	/* unit: 100 ms */
+	u8 bcn_pass_period;
+};
+
+struct h2c_joinbss_rpt_parm {
+	u8 opmode;
+	u8 ps_qos_info;
+	u8 bssid[6];
+	u16 bcnitv;
+	u16 aid;
+} ;
+
+struct h2c_wpa_ptk {
+	/* EAPOL-Key Key Confirmation Key (KCK) */
+	u8 kck[16];
+	/* EAPOL-Key Key Encryption Key (KEK) */
+	u8 kek[16];
+	/* Temporal Key 1 (TK1) */
+	u8 tk1[16];
+	union {
+		/* Temporal Key 2 (TK2) */
+		u8 tk2[16];
+		struct {
+			u8 tx_mic_key[8];
+			u8 rx_mic_key[8];
+		} athu;
+	} u;
+};
+
+struct h2c_wpa_two_way_parm {
+	/* algorithm TKIP or AES */
+	u8 pairwise_en_alg;
+	u8 group_en_alg;
+	struct h2c_wpa_ptk wpa_ptk_value;
+} ;
+
+enum h2c_cmd {
+	FW_H2C_SETPWRMODE = 0,
+	FW_H2C_JOINBSSRPT = 1,
+	FW_H2C_WOWLAN_UPDATE_GTK = 2,
+	FW_H2C_WOWLAN_UPDATE_IV = 3,
+	FW_H2C_WOWLAN_OFFLOAD = 4,
+};
+
+enum fw_h2c_cmd {
+	H2C_READ_MACREG_CMD,				/*0*/
+	H2C_WRITE_MACREG_CMD,
+	H2C_READBB_CMD,
+	H2C_WRITEBB_CMD,
+	H2C_READRF_CMD,
+	H2C_WRITERF_CMD,				/*5*/
+	H2C_READ_EEPROM_CMD,
+	H2C_WRITE_EEPROM_CMD,
+	H2C_READ_EFUSE_CMD,
+	H2C_WRITE_EFUSE_CMD,
+	H2C_READ_CAM_CMD,				/*10*/
+	H2C_WRITE_CAM_CMD,
+	H2C_SETBCNITV_CMD,
+	H2C_SETMBIDCFG_CMD,
+	H2C_JOINBSS_CMD,
+	H2C_DISCONNECT_CMD,				/*15*/
+	H2C_CREATEBSS_CMD,
+	H2C_SETOPMode_CMD,
+	H2C_SITESURVEY_CMD,
+	H2C_SETAUTH_CMD,
+	H2C_SETKEY_CMD,					/*20*/
+	H2C_SETSTAKEY_CMD,
+	H2C_SETASSOCSTA_CMD,
+	H2C_DELASSOCSTA_CMD,
+	H2C_SETSTAPWRSTATE_CMD,
+	H2C_SETBASICRATE_CMD,				/*25*/
+	H2C_GETBASICRATE_CMD,
+	H2C_SETDATARATE_CMD,
+	H2C_GETDATARATE_CMD,
+	H2C_SETPHYINFO_CMD,
+	H2C_GETPHYINFO_CMD,				/*30*/
+	H2C_SETPHY_CMD,
+	H2C_GETPHY_CMD,
+	H2C_READRSSI_CMD,
+	H2C_READGAIN_CMD,
+	H2C_SETATIM_CMD,				/*35*/
+	H2C_SETPWRMODE_CMD,
+	H2C_JOINBSSRPT_CMD,
+	H2C_SETRATABLE_CMD,
+	H2C_GETRATABLE_CMD,
+	H2C_GETCCXREPORT_CMD,				/*40*/
+	H2C_GETDTMREPORT_CMD,
+	H2C_GETTXRATESTATICS_CMD,
+	H2C_SETUSBSUSPEND_CMD,
+	H2C_SETH2CLBK_CMD,
+	H2C_TMP1,					/*45*/
+	H2C_WOWLAN_UPDATE_GTK_CMD,
+	H2C_WOWLAN_FW_OFFLOAD,
+	H2C_TMP2,
+	H2C_TMP3,
+	H2C_WOWLAN_UPDATE_IV_CMD,			/*50*/
+	H2C_TMP4,
+	MAX_H2CCMD					/*52*/
+};
+
+/* The following macros are used for FW
+ * CMD map and parameter updated. */
+#define FW_CMD_IO_CLR(rtlpriv, _Bit)				\
+	do {							\
+		udelay(1000);					\
+		rtlpriv->rtlhal.fwcmd_iomap &= (~_Bit);		\
+	} while (0);
+
+#define FW_CMD_IO_UPDATE(rtlpriv, _val)				\
+	rtlpriv->rtlhal.fwcmd_iomap = _val;
+
+#define FW_CMD_IO_SET(rtlpriv, _val)				\
+	do {							\
+		rtl_write_word(rtlpriv, LBUS_MON_ADDR, (u16)_val);	\
+		FW_CMD_IO_UPDATE(rtlpriv, _val);		\
+	} while (0);
+
+#define FW_CMD_PARA_SET(rtlpriv, _val)				\
+	do {							\
+		rtl_write_dword(rtlpriv, LBUS_ADDR_MASK, _val);	\
+		rtlpriv->rtlhal.fwcmd_ioparam = _val;		\
+	} while (0);
+
+#define FW_CMD_IO_QUERY(rtlpriv)				\
+	(u16)(rtlpriv->rtlhal.fwcmd_iomap)
+#define FW_CMD_IO_PARA_QUERY(rtlpriv)				\
+	((u32)(rtlpriv->rtlhal.fwcmd_ioparam))
+
+int rtl92s_download_fw(struct ieee80211_hw *hw);
+void rtl92s_set_fw_pwrmode_cmd(struct ieee80211_hw *hw, u8 mode);
+void rtl92s_set_fw_joinbss_report_cmd(struct ieee80211_hw *hw,
+				      u8 mstatus, u8 ps_qosinfo);
+
+#endif
+
diff -druN linux-2.6.39-libre/drivers/net/wireless/rtlwifi/rtl8192se/hw.c linux-3.0-rc7-libre/drivers/net/wireless/rtlwifi/rtl8192se/hw.c
--- linux-2.6.39-libre/drivers/net/wireless/rtlwifi/rtl8192se/hw.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/net/wireless/rtlwifi/rtl8192se/hw.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,2512 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2009-2010  Realtek Corporation.
+ *
+ * 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:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+
+#include "../wifi.h"
+#include "../efuse.h"
+#include "../base.h"
+#include "../regd.h"
+#include "../cam.h"
+#include "../ps.h"
+#include "../pci.h"
+#include "reg.h"
+#include "def.h"
+#include "phy.h"
+#include "dm.h"
+#include "fw.h"
+#include "led.h"
+#include "hw.h"
+
+void rtl92se_get_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
+{
+	struct rtl_priv *rtlpriv = rtl_priv(hw);
+	struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
+	struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+
+	switch (variable) {
+	case HW_VAR_RCR: {
+			*((u32 *) (val)) = rtlpci->receive_config;
+			break;
+		}
+	case HW_VAR_RF_STATE: {
+			*((enum rf_pwrstate *)(val)) = ppsc->rfpwr_state;
+			break;
+		}
+	case HW_VAR_FW_PSMODE_STATUS: {
+			*((bool *) (val)) = ppsc->fw_current_inpsmode;
+			break;
+		}
+	case HW_VAR_CORRECT_TSF: {
+			u64 tsf;
+			u32 *ptsf_low = (u32 *)&tsf;
+			u32 *ptsf_high = ((u32 *)&tsf) + 1;
+
+			*ptsf_high = rtl_read_dword(rtlpriv, (TSFR + 4));
+			*ptsf_low = rtl_read_dword(rtlpriv, TSFR);
+
+			*((u64 *) (val)) = tsf;
+
+			break;
+		}
+	case HW_VAR_MRC: {
+			*((bool *)(val)) = rtlpriv->dm.current_mrc_switch;
+			break;
+		}
+	default: {
+			RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
+				 ("switch case not process\n"));
+			break;
+		}
+	}
+}
+
+void rtl92se_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
+{
+	struct rtl_priv *rtlpriv = rtl_priv(hw);
+	struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+	struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
+	struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
+
+	switch (variable) {
+	case HW_VAR_ETHER_ADDR:{
+			rtl_write_dword(rtlpriv, IDR0, ((u32 *)(val))[0]);
+			rtl_write_word(rtlpriv, IDR4, ((u16 *)(val + 4))[0]);
+			break;
+		}
+	case HW_VAR_BASIC_RATE:{
+			u16 rate_cfg = ((u16 *) val)[0];
+			u8 rate_index = 0;
+
+			if (rtlhal->version == VERSION_8192S_ACUT)
+				rate_cfg = rate_cfg & 0x150;
+			else
+				rate_cfg = rate_cfg & 0x15f;
+
+			rate_cfg |= 0x01;
+
+			rtl_write_byte(rtlpriv, RRSR, rate_cfg & 0xff);
+			rtl_write_byte(rtlpriv, RRSR + 1,
+				       (rate_cfg >> 8) & 0xff);
+
+			while (rate_cfg > 0x1) {
+				rate_cfg = (rate_cfg >> 1);
+				rate_index++;
+			}
+			rtl_write_byte(rtlpriv, INIRTSMCS_SEL, rate_index);
+
+			break;
+		}
+	case HW_VAR_BSSID:{
+			rtl_write_dword(rtlpriv, BSSIDR, ((u32 *)(val))[0]);
+			rtl_write_word(rtlpriv, BSSIDR + 4,
+				       ((u16 *)(val + 4))[0]);
+			break;
+		}
+	case HW_VAR_SIFS:{
+			rtl_write_byte(rtlpriv, SIFS_OFDM, val[0]);
+			rtl_write_byte(rtlpriv, SIFS_OFDM + 1, val[1]);
+			break;
+		}
+	case HW_VAR_SLOT_TIME:{
+			u8 e_aci;
+
+			RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD,
+				 ("HW_VAR_SLOT_TIME %x\n", val[0]));
+
+			rtl_write_byte(rtlpriv, SLOT_TIME, val[0]);
+
+			for (e_aci = 0; e_aci < AC_MAX; e_aci++) {
+				rtlpriv->cfg->ops->set_hw_reg(hw,
+						HW_VAR_AC_PARAM,
+						(u8 *)(&e_aci));
+			}
+			break;
+		}
+	case HW_VAR_ACK_PREAMBLE:{
+			u8 reg_tmp;
+			u8 short_preamble = (bool) (*(u8 *) val);
+			reg_tmp = (mac->cur_40_prime_sc) << 5;
+			if (short_preamble)
+				reg_tmp |= 0x80;
+
+			rtl_write_byte(rtlpriv, RRSR + 2, reg_tmp);
+			break;
+		}
+	case HW_VAR_AMPDU_MIN_SPACE:{
+			u8 min_spacing_to_set;
+			u8 sec_min_space;
+
+			min_spacing_to_set = *((u8 *)val);
+			if (min_spacing_to_set <= 7) {
+				if (rtlpriv->sec.pairwise_enc_algorithm ==
+				    NO_ENCRYPTION)
+					sec_min_space = 0;
+				else
+					sec_min_space = 1;
+
+				if (min_spacing_to_set < sec_min_space)
+					min_spacing_to_set = sec_min_space;
+				if (min_spacing_to_set > 5)
+					min_spacing_to_set = 5;
+
+				mac->min_space_cfg =
+						((mac->min_space_cfg & 0xf8) |
+						min_spacing_to_set);
+
+				*val = min_spacing_to_set;
+
+				RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD,
+					 ("Set HW_VAR_AMPDU_MIN_SPACE: %#x\n",
+					  mac->min_space_cfg));
+
+				rtl_write_byte(rtlpriv, AMPDU_MIN_SPACE,
+					       mac->min_space_cfg);
+			}
+			break;
+		}
+	case HW_VAR_SHORTGI_DENSITY:{
+			u8 density_to_set;
+
+			density_to_set = *((u8 *) val);
+			mac->min_space_cfg = rtlpriv->rtlhal.minspace_cfg;
+			mac->min_space_cfg |= (density_to_set << 3);
+
+			RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD,
+				 ("Set HW_VAR_SHORTGI_DENSITY: %#x\n",
+				  mac->min_space_cfg));
+
+			rtl_write_byte(rtlpriv, AMPDU_MIN_SPACE,
+				       mac->min_space_cfg);
+
+			break;
+		}
+	case HW_VAR_AMPDU_FACTOR:{
+			u8 factor_toset;
+			u8 regtoset;
+			u8 factorlevel[18] = {
+				2, 4, 4, 7, 7, 13, 13,
+				13, 2, 7, 7, 13, 13,
+				15, 15, 15, 15, 0};
+			u8 index = 0;
+
+			factor_toset = *((u8 *) val);
+			if (factor_toset <= 3) {
+				factor_toset = (1 << (factor_toset + 2));
+				if (factor_toset > 0xf)
+					factor_toset = 0xf;
+
+				for (index = 0; index < 17; index++) {
+					if (factorlevel[index] > factor_toset)
+						factorlevel[index] =
+								 factor_toset;
+				}
+
+				for (index = 0; index < 8; index++) {
+					regtoset = ((factorlevel[index * 2]) |
+						    (factorlevel[index *
+						    2 + 1] << 4));
+					rtl_write_byte(rtlpriv,
+						       AGGLEN_LMT_L + index,
+						       regtoset);
+				}
+
+				regtoset = ((factorlevel[16]) |
+					    (factorlevel[17] << 4));
+				rtl_write_byte(rtlpriv, AGGLEN_LMT_H, regtoset);
+
+				RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD,
+					 ("Set HW_VAR_AMPDU_FACTOR: %#x\n",
+					  factor_toset));
+			}
+			break;
+		}
+	case HW_VAR_AC_PARAM:{
+			u8 e_aci = *((u8 *) val);
+			rtl92s_dm_init_edca_turbo(hw);
+
+			if (rtlpci->acm_method != eAcmWay2_SW)
+				rtlpriv->cfg->ops->set_hw_reg(hw,
+						 HW_VAR_ACM_CTRL,
+						 (u8 *)(&e_aci));
+			break;
+		}
+	case HW_VAR_ACM_CTRL:{
+			u8 e_aci = *((u8 *) val);
+			union aci_aifsn *p_aci_aifsn = (union aci_aifsn *)(&(
+							mac->ac[0].aifs));
+			u8 acm = p_aci_aifsn->f.acm;
+			u8 acm_ctrl = rtl_read_byte(rtlpriv, AcmHwCtrl);
+
+			acm_ctrl = acm_ctrl | ((rtlpci->acm_method == 2) ?
+				   0x0 : 0x1);
+
+			if (acm) {
+				switch (e_aci) {
+				case AC0_BE:
+					acm_ctrl |= AcmHw_BeqEn;
+					break;
+				case AC2_VI:
+					acm_ctrl |= AcmHw_ViqEn;
+					break;
+				case AC3_VO:
+					acm_ctrl |= AcmHw_VoqEn;
+					break;
+				default:
+					RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
+						 ("HW_VAR_ACM_CTRL acm set "
+						  "failed: eACI is %d\n", acm));
+					break;
+				}
+			} else {
+				switch (e_aci) {
+				case AC0_BE:
+					acm_ctrl &= (~AcmHw_BeqEn);
+					break;
+				case AC2_VI:
+					acm_ctrl &= (~AcmHw_ViqEn);
+					break;
+				case AC3_VO:
+					acm_ctrl &= (~AcmHw_BeqEn);
+					break;
+				default:
+					RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
+						 ("switch case not process\n"));
+					break;
+				}
+			}
+
+			RT_TRACE(rtlpriv, COMP_QOS, DBG_TRACE,
+				 ("HW_VAR_ACM_CTRL Write 0x%X\n", acm_ctrl));
+			rtl_write_byte(rtlpriv, AcmHwCtrl, acm_ctrl);
+			break;
+		}
+	case HW_VAR_RCR:{
+			rtl_write_dword(rtlpriv, RCR, ((u32 *) (val))[0]);
+			rtlpci->receive_config = ((u32 *) (val))[0];
+			break;
+		}
+	case HW_VAR_RETRY_LIMIT:{
+			u8 retry_limit = ((u8 *) (val))[0];
+
+			rtl_write_word(rtlpriv, RETRY_LIMIT,
+				       retry_limit << RETRY_LIMIT_SHORT_SHIFT |
+				       retry_limit << RETRY_LIMIT_LONG_SHIFT);
+			break;
+		}
+	case HW_VAR_DUAL_TSF_RST: {
+			break;
+		}
+	case HW_VAR_EFUSE_BYTES: {
+			rtlefuse->efuse_usedbytes = *((u16 *) val);
+			break;
+		}
+	case HW_VAR_EFUSE_USAGE: {
+			rtlefuse->efuse_usedpercentage = *((u8 *) val);
+			break;
+		}
+	case HW_VAR_IO_CMD: {
+			break;
+		}
+	case HW_VAR_WPA_CONFIG: {
+			rtl_write_byte(rtlpriv, REG_SECR, *((u8 *) val));
+			break;
+		}
+	case HW_VAR_SET_RPWM:{
+			break;
+		}
+	case HW_VAR_H2C_FW_PWRMODE:{
+			break;
+		}
+	case HW_VAR_FW_PSMODE_STATUS: {
+			ppsc->fw_current_inpsmode = *((bool *) val);
+			break;
+		}
+	case HW_VAR_H2C_FW_JOINBSSRPT:{
+			break;
+		}
+	case HW_VAR_AID:{
+			break;
+		}
+	case HW_VAR_CORRECT_TSF:{
+			break;
+		}
+	case HW_VAR_MRC: {
+			bool bmrc_toset = *((bool *)val);
+			u8 u1bdata = 0;
+
+			if (bmrc_toset) {
+				rtl_set_bbreg(hw, ROFDM0_TRXPATHENABLE,
+					      MASKBYTE0, 0x33);
+				u1bdata = (u8)rtl_get_bbreg(hw,
+						ROFDM1_TRXPATHENABLE,
+						MASKBYTE0);
+				rtl_set_bbreg(hw, ROFDM1_TRXPATHENABLE,
+					      MASKBYTE0,
+					      ((u1bdata & 0xf0) | 0x03));
+				u1bdata = (u8)rtl_get_bbreg(hw,
+						ROFDM0_TRXPATHENABLE,
+						MASKBYTE1);
+				rtl_set_bbreg(hw, ROFDM0_TRXPATHENABLE,
+					      MASKBYTE1,
+					      (u1bdata | 0x04));
+
+				/* Update current settings. */
+				rtlpriv->dm.current_mrc_switch = bmrc_toset;
+			} else {
+				rtl_set_bbreg(hw, ROFDM0_TRXPATHENABLE,
+					      MASKBYTE0, 0x13);
+				u1bdata = (u8)rtl_get_bbreg(hw,
+						 ROFDM1_TRXPATHENABLE,
+						 MASKBYTE0);
+				rtl_set_bbreg(hw, ROFDM1_TRXPATHENABLE,
+					      MASKBYTE0,
+					      ((u1bdata & 0xf0) | 0x01));
+				u1bdata = (u8)rtl_get_bbreg(hw,
+						ROFDM0_TRXPATHENABLE,
+						MASKBYTE1);
+				rtl_set_bbreg(hw, ROFDM0_TRXPATHENABLE,
+					      MASKBYTE1, (u1bdata & 0xfb));
+
+				/* Update current settings. */
+				rtlpriv->dm.current_mrc_switch = bmrc_toset;
+			}
+
+			break;
+		}
+	default:
+		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
+			 ("switch case not process\n"));
+		break;
+	}
+
+}
+
+void rtl92se_enable_hw_security_config(struct ieee80211_hw *hw)
+{
+	struct rtl_priv *rtlpriv = rtl_priv(hw);
+	u8 sec_reg_value = 0x0;
+
+	RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("PairwiseEncAlgorithm = %d "
+		 "GroupEncAlgorithm = %d\n",
+		 rtlpriv->sec.pairwise_enc_algorithm,
+		 rtlpriv->sec.group_enc_algorithm));
+
+	if (rtlpriv->cfg->mod_params->sw_crypto || rtlpriv->sec.use_sw_sec) {
+		RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
+			 ("not open hw encryption\n"));
+		return;
+	}
+
+	sec_reg_value = SCR_TXENCENABLE | SCR_RXENCENABLE;
+
+	if (rtlpriv->sec.use_defaultkey) {
+		sec_reg_value |= SCR_TXUSEDK;
+		sec_reg_value |= SCR_RXUSEDK;
+	}
+
+	RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, ("The SECR-value %x\n",
+			sec_reg_value));
+
+	rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_WPA_CONFIG, &sec_reg_value);
+
+}
+
+static u8 _rtl92ce_halset_sysclk(struct ieee80211_hw *hw, u8 data)
+{
+	struct rtl_priv *rtlpriv = rtl_priv(hw);
+	u8 waitcount = 100;
+	bool bresult = false;
+	u8 tmpvalue;
+
+	rtl_write_byte(rtlpriv, SYS_CLKR + 1, data);
+
+	/* Wait the MAC synchronized. */
+	udelay(400);
+
+	/* Check if it is set ready. */
+	tmpvalue = rtl_read_byte(rtlpriv, SYS_CLKR + 1);
+	bresult = ((tmpvalue & BIT(7)) == (data & BIT(7)));
+
+	if ((data & (BIT(6) | BIT(7))) == false) {
+		waitcount = 100;
+		tmpvalue = 0;
+
+		while (1) {
+			waitcount--;
+
+			tmpvalue = rtl_read_byte(rtlpriv, SYS_CLKR + 1);
+			if ((tmpvalue & BIT(6)))
+				break;
+
+			printk(KERN_ERR "wait for BIT(6) return value %x\n",
+			       tmpvalue);
+			if (waitcount == 0)
+				break;
+
+			udelay(10);
+		}
+
+		if (waitcount == 0)
+			bresult = false;
+		else
+			bresult = true;
+	}
+
+	return bresult;
+}
+
+void rtl8192se_gpiobit3_cfg_inputmode(struct ieee80211_hw *hw)
+{
+	struct rtl_priv *rtlpriv = rtl_priv(hw);
+	u8 u1tmp;
+
+	/* The following config GPIO function */
+	rtl_write_byte(rtlpriv, MAC_PINMUX_CFG, (GPIOMUX_EN | GPIOSEL_GPIO));
+	u1tmp = rtl_read_byte(rtlpriv, GPIO_IO_SEL);
+
+	/* config GPIO3 to input */
+	u1tmp &= HAL_8192S_HW_GPIO_OFF_MASK;
+	rtl_write_byte(rtlpriv, GPIO_IO_SEL, u1tmp);
+
+}
+
+static u8 _rtl92se_rf_onoff_detect(struct ieee80211_hw *hw)
+{
+	struct rtl_priv *rtlpriv = rtl_priv(hw);
+	u8 u1tmp;
+	u8 retval = ERFON;
+
+	/* The following config GPIO function */
+	rtl_write_byte(rtlpriv, MAC_PINMUX_CFG, (GPIOMUX_EN | GPIOSEL_GPIO));
+	u1tmp = rtl_read_byte(rtlpriv, GPIO_IO_SEL);
+
+	/* config GPIO3 to input */
+	u1tmp &= HAL_8192S_HW_GPIO_OFF_MASK;
+	rtl_write_byte(rtlpriv, GPIO_IO_SEL, u1tmp);
+
+	/* On some of the platform, driver cannot read correct
+	 * value without delay between Write_GPIO_SEL and Read_GPIO_IN */
+	mdelay(10);
+
+	/* check GPIO3 */
+	u1tmp = rtl_read_byte(rtlpriv, GPIO_IN);
+	retval = (u1tmp & HAL_8192S_HW_GPIO_OFF_BIT) ? ERFON : ERFOFF;
+
+	return retval;
+}
+
+static void _rtl92se_macconfig_before_fwdownload(struct ieee80211_hw *hw)
+{
+	struct rtl_priv *rtlpriv = rtl_priv(hw);
+	struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+	struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
+
+	u8 i;
+	u8 tmpu1b;
+	u16 tmpu2b;
+	u8 pollingcnt = 20;
+
+	if (rtlpci->first_init) {
+		/* Reset PCIE Digital */
+		tmpu1b = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1);
+		tmpu1b &= 0xFE;
+		rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1, tmpu1b);
+		udelay(1);
+		rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1, tmpu1b | BIT(0));
+	}
+
+	/* Switch to SW IO control */
+	tmpu1b = rtl_read_byte(rtlpriv, (SYS_CLKR + 1));
+	if (tmpu1b & BIT(7)) {
+		tmpu1b &= ~(BIT(6) | BIT(7));
+
+		/* Set failed, return to prevent hang. */
+		if (!_rtl92ce_halset_sysclk(hw, tmpu1b))
+			return;
+	}
+
+	rtl_write_byte(rtlpriv, AFE_PLL_CTRL, 0x0);
+	udelay(50);
+	rtl_write_byte(rtlpriv, LDOA15_CTRL, 0x34);
+	udelay(50);
+
+	/* Clear FW RPWM for FW control LPS.*/
+	rtl_write_byte(rtlpriv, RPWM, 0x0);
+
+	/* Reset MAC-IO and CPU and Core Digital BIT(10)/11/15 */
+	tmpu1b = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1);
+	tmpu1b &= 0x73;
+	rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1, tmpu1b);
+	/* wait for BIT 10/11/15 to pull high automatically!! */
+	mdelay(1);
+
+	rtl_write_byte(rtlpriv, CMDR, 0);
+	rtl_write_byte(rtlpriv, TCR, 0);
+
+	/* Data sheet not define 0x562!!! Copy from WMAC!!!!! */
+	tmpu1b = rtl_read_byte(rtlpriv, 0x562);
+	tmpu1b |= 0x08;
+	rtl_write_byte(rtlpriv, 0x562, tmpu1b);
+	tmpu1b &= ~(BIT(3));
+	rtl_write_byte(rtlpriv, 0x562, tmpu1b);
+
+	/* Enable AFE clock source */
+	tmpu1b = rtl_read_byte(rtlpriv, AFE_XTAL_CTRL);
+	rtl_write_byte(rtlpriv, AFE_XTAL_CTRL, (tmpu1b | 0x01));
+	/* Delay 1.5ms */
+	mdelay(2);
+	tmpu1b = rtl_read_byte(rtlpriv, AFE_XTAL_CTRL + 1);
+	rtl_write_byte(rtlpriv, AFE_XTAL_CTRL + 1, (tmpu1b & 0xfb));
+
+	/* Enable AFE Macro Block's Bandgap */
+	tmpu1b = rtl_read_byte(rtlpriv, AFE_MISC);
+	rtl_write_byte(rtlpriv, AFE_MISC, (tmpu1b | BIT(0)));
+	mdelay(1);
+
+	/* Enable AFE Mbias */
+	tmpu1b = rtl_read_byte(rtlpriv, AFE_MISC);
+	rtl_write_byte(rtlpriv, AFE_MISC, (tmpu1b | 0x02));
+	mdelay(1);
+
+	/* Enable LDOA15 block	*/
+	tmpu1b = rtl_read_byte(rtlpriv, LDOA15_CTRL);
+	rtl_write_byte(rtlpriv, LDOA15_CTRL, (tmpu1b | BIT(0)));
+
+	/* Set Digital Vdd to Retention isolation Path. */
+	tmpu2b = rtl_read_word(rtlpriv, REG_SYS_ISO_CTRL);
+	rtl_write_word(rtlpriv, REG_SYS_ISO_CTRL, (tmpu2b | BIT(11)));
+
+	/* For warm reboot NIC disappera bug. */
+	tmpu2b = rtl_read_word(rtlpriv, REG_SYS_FUNC_EN);
+	rtl_write_word(rtlpriv, REG_SYS_FUNC_EN, (tmpu2b | BIT(13)));
+
+	rtl_write_byte(rtlpriv, REG_SYS_ISO_CTRL + 1, 0x68);
+
+	/* Enable AFE PLL Macro Block */
+	/* We need to delay 100u before enabling PLL. */
+	udelay(200);
+	tmpu1b = rtl_read_byte(rtlpriv, AFE_PLL_CTRL);
+	rtl_write_byte(rtlpriv, AFE_PLL_CTRL, (tmpu1b | BIT(0) | BIT(4)));
+
+	/* for divider reset  */
+	udelay(100);
+	rtl_write_byte(rtlpriv, AFE_PLL_CTRL, (tmpu1b | BIT(0) |
+		       BIT(4) | BIT(6)));
+	udelay(10);
+	rtl_write_byte(rtlpriv, AFE_PLL_CTRL, (tmpu1b | BIT(0) | BIT(4)));
+	udelay(10);
+
+	/* Enable MAC 80MHZ clock  */
+	tmpu1b = rtl_read_byte(rtlpriv, AFE_PLL_CTRL + 1);
+	rtl_write_byte(rtlpriv, AFE_PLL_CTRL + 1, (tmpu1b | BIT(0)));
+	mdelay(1);
+
+	/* Release isolation AFE PLL & MD */
+	rtl_write_byte(rtlpriv, REG_SYS_ISO_CTRL, 0xA6);
+
+	/* Enable MAC clock */
+	tmpu2b = rtl_read_word(rtlpriv, SYS_CLKR);
+	rtl_write_word(rtlpriv, SYS_CLKR, (tmpu2b | BIT(12) | BIT(11)));
+
+	/* Enable Core digital and enable IOREG R/W */
+	tmpu2b = rtl_read_word(rtlpriv, REG_SYS_FUNC_EN);
+	rtl_write_word(rtlpriv, REG_SYS_FUNC_EN, (tmpu2b | BIT(11)));
+
+	tmpu1b = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1);
+	rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1, tmpu1b & ~(BIT(7)));
+
+	/* enable REG_EN */
+	rtl_write_word(rtlpriv, REG_SYS_FUNC_EN, (tmpu2b | BIT(11) | BIT(15)));
+
+	/* Switch the control path. */
+	tmpu2b = rtl_read_word(rtlpriv, SYS_CLKR);
+	rtl_write_word(rtlpriv, SYS_CLKR, (tmpu2b & (~BIT(2))));
+
+	tmpu1b = rtl_read_byte(rtlpriv, (SYS_CLKR + 1));
+	tmpu1b = ((tmpu1b | BIT(7)) & (~BIT(6)));
+	if (!_rtl92ce_halset_sysclk(hw, tmpu1b))
+		return; /* Set failed, return to prevent hang. */
+
+	rtl_write_word(rtlpriv, CMDR, 0x07FC);
+
+	/* MH We must enable the section of code to prevent load IMEM fail. */
+	/* Load MAC register from WMAc temporarily We simulate macreg. */
+	/* txt HW will provide MAC txt later  */
+	rtl_write_byte(rtlpriv, 0x6, 0x30);
+	rtl_write_byte(rtlpriv, 0x49, 0xf0);
+
+	rtl_write_byte(rtlpriv, 0x4b, 0x81);
+
+	rtl_write_byte(rtlpriv, 0xb5, 0x21);
+
+	rtl_write_byte(rtlpriv, 0xdc, 0xff);
+	rtl_write_byte(rtlpriv, 0xdd, 0xff);
+	rtl_write_byte(rtlpriv, 0xde, 0xff);
+	rtl_write_byte(rtlpriv, 0xdf, 0xff);
+
+	rtl_write_byte(rtlpriv, 0x11a, 0x00);
+	rtl_write_byte(rtlpriv, 0x11b, 0x00);
+
+	for (i = 0; i < 32; i++)
+		rtl_write_byte(rtlpriv, INIMCS_SEL + i, 0x1b);
+
+	rtl_write_byte(rtlpriv, 0x236, 0xff);
+
+	rtl_write_byte(rtlpriv, 0x503, 0x22);
+
+	if (ppsc->support_aspm && !ppsc->support_backdoor)
+		rtl_write_byte(rtlpriv, 0x560, 0x40);
+	else
+		rtl_write_byte(rtlpriv, 0x560, 0x00);
+
+	rtl_write_byte(rtlpriv, DBG_PORT, 0x91);
+
+	/* Set RX Desc Address */
+	rtl_write_dword(rtlpriv, RDQDA, rtlpci->rx_ring[RX_MPDU_QUEUE].dma);
+	rtl_write_dword(rtlpriv, RCDA, rtlpci->rx_ring[RX_CMD_QUEUE].dma);
+
+	/* Set TX Desc Address */
+	rtl_write_dword(rtlpriv, TBKDA, rtlpci->tx_ring[BK_QUEUE].dma);
+	rtl_write_dword(rtlpriv, TBEDA, rtlpci->tx_ring[BE_QUEUE].dma);
+	rtl_write_dword(rtlpriv, TVIDA, rtlpci->tx_ring[VI_QUEUE].dma);
+	rtl_write_dword(rtlpriv, TVODA, rtlpci->tx_ring[VO_QUEUE].dma);
+	rtl_write_dword(rtlpriv, TBDA, rtlpci->tx_ring[BEACON_QUEUE].dma);
+	rtl_write_dword(rtlpriv, TCDA, rtlpci->tx_ring[TXCMD_QUEUE].dma);
+	rtl_write_dword(rtlpriv, TMDA, rtlpci->tx_ring[MGNT_QUEUE].dma);
+	rtl_write_dword(rtlpriv, THPDA, rtlpci->tx_ring[HIGH_QUEUE].dma);
+	rtl_write_dword(rtlpriv, HDA, rtlpci->tx_ring[HCCA_QUEUE].dma);
+
+	rtl_write_word(rtlpriv, CMDR, 0x37FC);
+
+	/* To make sure that TxDMA can ready to download FW. */
+	/* We should reset TxDMA if IMEM RPT was not ready. */
+	do {
+		tmpu1b = rtl_read_byte(rtlpriv, TCR);
+		if ((tmpu1b & TXDMA_INIT_VALUE) == TXDMA_INIT_VALUE)
+			break;
+
+		udelay(5);
+	} while (pollingcnt--);
+
+	if (pollingcnt <= 0) {
+		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
+			 ("Polling TXDMA_INIT_VALUE "
+			 "timeout!! Current TCR(%#x)\n", tmpu1b));
+		tmpu1b = rtl_read_byte(rtlpriv, CMDR);
+		rtl_write_byte(rtlpriv, CMDR, tmpu1b & (~TXDMA_EN));
+		udelay(2);
+		/* Reset TxDMA */
+		rtl_write_byte(rtlpriv, CMDR, tmpu1b | TXDMA_EN);
+	}
+
+	/* After MACIO reset,we must refresh LED state. */
+	if ((ppsc->rfoff_reason == RF_CHANGE_BY_IPS) ||
+	   (ppsc->rfoff_reason == 0)) {
+		struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
+		struct rtl_led *pLed0 = &(pcipriv->ledctl.sw_led0);
+		enum rf_pwrstate rfpwr_state_toset;
+		rfpwr_state_toset = _rtl92se_rf_onoff_detect(hw);
+
+		if (rfpwr_state_toset == ERFON)
+			rtl92se_sw_led_on(hw, pLed0);
+	}
+}
+
+static void _rtl92se_macconfig_after_fwdownload(struct ieee80211_hw *hw)
+{
+	struct rtl_priv *rtlpriv = rtl_priv(hw);
+	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+	struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
+	struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+	u8 i;
+	u16 tmpu2b;
+
+	/* 1. System Configure Register (Offset: 0x0000 - 0x003F) */
+
+	/* 2. Command Control Register (Offset: 0x0040 - 0x004F) */
+	/* Turn on 0x40 Command register */
+	rtl_write_word(rtlpriv, CMDR, (BBRSTN | BB_GLB_RSTN |
+			SCHEDULE_EN | MACRXEN | MACTXEN | DDMA_EN | FW2HW_EN |
+			RXDMA_EN | TXDMA_EN | HCI_RXDMA_EN | HCI_TXDMA_EN));
+
+	/* Set TCR TX DMA pre 2 FULL enable bit	*/
+	rtl_write_dword(rtlpriv, TCR, rtl_read_dword(rtlpriv, TCR) |
+			TXDMAPRE2FULL);
+
+	/* Set RCR	*/
+	rtl_write_dword(rtlpriv, RCR, rtlpci->receive_config);
+
+	/* 3. MACID Setting Register (Offset: 0x0050 - 0x007F) */
+
+	/* 4. Timing Control Register  (Offset: 0x0080 - 0x009F) */
+	/* Set CCK/OFDM SIFS */
+	/* CCK SIFS shall always be 10us. */
+	rtl_write_word(rtlpriv, SIFS_CCK, 0x0a0a);
+	rtl_write_word(rtlpriv, SIFS_OFDM, 0x1010);
+
+	/* Set AckTimeout */
+	rtl_write_byte(rtlpriv, ACK_TIMEOUT, 0x40);
+
+	/* Beacon related */
+	rtl_write_word(rtlpriv, BCN_INTERVAL, 100);
+	rtl_write_word(rtlpriv, ATIMWND, 2);
+
+	/* 5. FIFO Control Register (Offset: 0x00A0 - 0x015F) */
+	/* 5.1 Initialize Number of Reserved Pages in Firmware Queue */
+	/* Firmware allocate now, associate with FW internal setting.!!! */
+
+	/* 5.2 Setting TX/RX page size 0/1/2/3/4=64/128/256/512/1024 */
+	/* 5.3 Set driver info, we only accept PHY status now. */
+	/* 5.4 Set RXDMA arbitration to control RXDMA/MAC/FW R/W for RXFIFO  */
+	rtl_write_byte(rtlpriv, RXDMA, rtl_read_byte(rtlpriv, RXDMA) | BIT(6));
+
+	/* 6. Adaptive Control Register  (Offset: 0x0160 - 0x01CF) */
+	/* Set RRSR to all legacy rate and HT rate
+	 * CCK rate is supported by default.
+	 * CCK rate will be filtered out only when associated
+	 * AP does not support it.
+	 * Only enable ACK rate to OFDM 24M
+	 * Disable RRSR for CCK rate in A-Cut	*/
+
+	if (rtlhal->version == VERSION_8192S_ACUT)
+		rtl_write_byte(rtlpriv, RRSR, 0xf0);
+	else if (rtlhal->version == VERSION_8192S_BCUT)
+		rtl_write_byte(rtlpriv, RRSR, 0xff);
+	rtl_write_byte(rtlpriv, RRSR + 1, 0x01);
+	rtl_write_byte(rtlpriv, RRSR + 2, 0x00);
+
+	/* A-Cut IC do not support CCK rate. We forbid ARFR to */
+	/* fallback to CCK rate */
+	for (i = 0; i < 8; i++) {
+		/*Disable RRSR for CCK rate in A-Cut */
+		if (rtlhal->version == VERSION_8192S_ACUT)
+			rtl_write_dword(rtlpriv, ARFR0 + i * 4, 0x1f0ff0f0);
+	}
+
+	/* Different rate use different AMPDU size */
+	/* MCS32/ MCS15_SG use max AMPDU size 15*2=30K */
+	rtl_write_byte(rtlpriv, AGGLEN_LMT_H, 0x0f);
+	/* MCS0/1/2/3 use max AMPDU size 4*2=8K */
+	rtl_write_word(rtlpriv, AGGLEN_LMT_L, 0x7442);
+	/* MCS4/5 use max AMPDU size 8*2=16K 6/7 use 10*2=20K */
+	rtl_write_word(rtlpriv, AGGLEN_LMT_L + 2, 0xddd7);
+	/* MCS8/9 use max AMPDU size 8*2=16K 10/11 use 10*2=20K */
+	rtl_write_word(rtlpriv, AGGLEN_LMT_L + 4, 0xd772);
+	/* MCS12/13/14/15 use max AMPDU size 15*2=30K */
+	rtl_write_word(rtlpriv, AGGLEN_LMT_L + 6, 0xfffd);
+
+	/* Set Data / Response auto rate fallack retry count */
+	rtl_write_dword(rtlpriv, DARFRC, 0x04010000);
+	rtl_write_dword(rtlpriv, DARFRC + 4, 0x09070605);
+	rtl_write_dword(rtlpriv, RARFRC, 0x04010000);
+	rtl_write_dword(rtlpriv, RARFRC + 4, 0x09070605);
+
+	/* 7. EDCA Setting Register (Offset: 0x01D0 - 0x01FF) */
+	/* Set all rate to support SG */
+	rtl_write_word(rtlpriv, SG_RATE, 0xFFFF);
+
+	/* 8. WMAC, BA, and CCX related Register (Offset: 0x0200 - 0x023F) */
+	/* Set NAV protection length */
+	rtl_write_word(rtlpriv, NAV_PROT_LEN, 0x0080);
+	/* CF-END Threshold */
+	rtl_write_byte(rtlpriv, CFEND_TH, 0xFF);
+	/* Set AMPDU minimum space */
+	rtl_write_byte(rtlpriv, AMPDU_MIN_SPACE, 0x07);
+	/* Set TXOP stall control for several queue/HI/BCN/MGT/ */
+	rtl_write_byte(rtlpriv, TXOP_STALL_CTRL, 0x00);
+
+	/* 9. Security Control Register (Offset: 0x0240 - 0x025F) */
+	/* 10. Power Save Control Register (Offset: 0x0260 - 0x02DF) */
+	/* 11. General Purpose Register (Offset: 0x02E0 - 0x02FF) */
+	/* 12. Host Interrupt Status Register (Offset: 0x0300 - 0x030F) */
+	/* 13. Test Mode and Debug Control Register (Offset: 0x0310 - 0x034F) */
+
+	/* 14. Set driver info, we only accept PHY status now. */
+	rtl_write_byte(rtlpriv, RXDRVINFO_SZ, 4);
+
+	/* 15. For EEPROM R/W Workaround */
+	/* 16. For EFUSE to share REG_SYS_FUNC_EN with EEPROM!!! */
+	tmpu2b = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN);
+	rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, tmpu2b | BIT(13));
+	tmpu2b = rtl_read_byte(rtlpriv, REG_SYS_ISO_CTRL);
+	rtl_write_byte(rtlpriv, REG_SYS_ISO_CTRL, tmpu2b & (~BIT(8)));
+
+	/* 17. For EFUSE */
+	/* We may R/W EFUSE in EEPROM mode */
+	if (rtlefuse->epromtype == EEPROM_BOOT_EFUSE) {
+		u8	tempval;
+
+		tempval = rtl_read_byte(rtlpriv, REG_SYS_ISO_CTRL + 1);
+		tempval &= 0xFE;
+		rtl_write_byte(rtlpriv, REG_SYS_ISO_CTRL + 1, tempval);
+
+		/* Change Program timing */
+		rtl_write_byte(rtlpriv, REG_EFUSE_CTRL + 3, 0x72);
+		RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, ("EFUSE CONFIG OK\n"));
+	}
+
+	RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, ("OK\n"));
+
+}
+
+static void _rtl92se_hw_configure(struct ieee80211_hw *hw)
+{
+	struct rtl_priv *rtlpriv = rtl_priv(hw);
+	struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+	struct rtl_phy *rtlphy = &(rtlpriv->phy);
+	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+
+	u8 reg_bw_opmode = 0;
+	u32 reg_ratr = 0, reg_rrsr = 0;
+	u8 regtmp = 0;
+
+	reg_bw_opmode = BW_OPMODE_20MHZ;
+	reg_ratr = RATE_ALL_CCK | RATE_ALL_OFDM_AG | RATE_ALL_OFDM_1SS |
+				RATE_ALL_OFDM_2SS;
+	reg_rrsr = RATE_ALL_CCK | RATE_ALL_OFDM_AG;
+
+	regtmp = rtl_read_byte(rtlpriv, INIRTSMCS_SEL);
+	reg_rrsr = ((reg_rrsr & 0x000fffff) << 8) | regtmp;
+	rtl_write_dword(rtlpriv, INIRTSMCS_SEL, reg_rrsr);
+	rtl_write_byte(rtlpriv, BW_OPMODE, reg_bw_opmode);
+
+	/* Set Retry Limit here */
+	rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RETRY_LIMIT,
+			(u8 *)(&rtlpci->shortretry_limit));
+
+	rtl_write_byte(rtlpriv, MLT, 0x8f);
+
+	/* For Min Spacing configuration. */
+	switch (rtlphy->rf_type) {
+	case RF_1T2R:
+	case RF_1T1R:
+		rtlhal->minspace_cfg = (MAX_MSS_DENSITY_1T << 3);
+		break;
+	case RF_2T2R:
+	case RF_2T2R_GREEN:
+		rtlhal->minspace_cfg = (MAX_MSS_DENSITY_2T << 3);
+		break;
+	}
+	rtl_write_byte(rtlpriv, AMPDU_MIN_SPACE, rtlhal->minspace_cfg);
+}
+
+int rtl92se_hw_init(struct ieee80211_hw *hw)
+{
+	struct rtl_priv *rtlpriv = rtl_priv(hw);
+	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+	struct rtl_phy *rtlphy = &(rtlpriv->phy);
+	struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+	struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
+	u8 tmp_byte = 0;
+
+	bool rtstatus = true;
+	u8 tmp_u1b;
+	int err = false;
+	u8 i;
+	int wdcapra_add[] = {
+		EDCAPARA_BE, EDCAPARA_BK,
+		EDCAPARA_VI, EDCAPARA_VO};
+	u8 secr_value = 0x0;
+
+	rtlpci->being_init_adapter = true;
+
+	rtlpriv->intf_ops->disable_aspm(hw);
+
+	/* 1. MAC Initialize */
+	/* Before FW download, we have to set some MAC register */
+	_rtl92se_macconfig_before_fwdownload(hw);
+
+	rtlhal->version = (enum version_8192s)((rtl_read_dword(rtlpriv,
+			PMC_FSM) >> 16) & 0xF);
+
+	rtl8192se_gpiobit3_cfg_inputmode(hw);
+
+	/* 2. download firmware */
+	rtstatus = rtl92s_download_fw(hw);
+	if (!rtstatus) {
+		RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
+			 ("Failed to download FW. "
+			 "Init HW without FW now.., Please copy FW into"
+			 "/lib/firmware/rtlwifi\n"));
+		rtlhal->fw_ready = false;
+	} else {
+		rtlhal->fw_ready = true;
+	}
+
+	/* After FW download, we have to reset MAC register */
+	_rtl92se_macconfig_after_fwdownload(hw);
+
+	/*Retrieve default FW Cmd IO map. */
+	rtlhal->fwcmd_iomap =	rtl_read_word(rtlpriv, LBUS_MON_ADDR);
+	rtlhal->fwcmd_ioparam = rtl_read_dword(rtlpriv, LBUS_ADDR_MASK);
+
+	/* 3. Initialize MAC/PHY Config by MACPHY_reg.txt */
+	if (rtl92s_phy_mac_config(hw) != true) {
+		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("MAC Config failed\n"));
+		return rtstatus;
+	}
+
+	/* Make sure BB/RF write OK. We should prevent enter IPS. radio off. */
+	/* We must set flag avoid BB/RF config period later!! */
+	rtl_write_dword(rtlpriv, CMDR, 0x37FC);
+
+	/* 4. Initialize BB After MAC Config PHY_reg.txt, AGC_Tab.txt */
+	if (rtl92s_phy_bb_config(hw) != true) {
+		RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG, ("BB Config failed\n"));
+		return rtstatus;
+	}
+
+	/* 5. Initiailze RF RAIO_A.txt RF RAIO_B.txt */
+	/* Before initalizing RF. We can not use FW to do RF-R/W. */
+
+	rtlphy->rf_mode = RF_OP_BY_SW_3WIRE;
+
+	/* RF Power Save */
+#if 0
+	/* H/W or S/W RF OFF before sleep. */
+	if (rtlpriv->psc.rfoff_reason > RF_CHANGE_BY_PS) {
+		u32 rfoffreason = rtlpriv->psc.rfoff_reason;
+
+		rtlpriv->psc.rfoff_reason = RF_CHANGE_BY_INIT;
+		rtlpriv->psc.rfpwr_state = ERFON;
+		rtl_ps_set_rf_state(hw, ERFOFF, rfoffreason, true);
+	} else {
+		/* gpio radio on/off is out of adapter start */
+		if (rtlpriv->psc.hwradiooff == false) {
+			rtlpriv->psc.rfpwr_state = ERFON;
+			rtlpriv->psc.rfoff_reason = 0;
+		}
+	}
+#endif
+
+	/* Before RF-R/W we must execute the IO from Scott's suggestion. */
+	rtl_write_byte(rtlpriv, AFE_XTAL_CTRL + 1, 0xDB);
+	if (rtlhal->version == VERSION_8192S_ACUT)
+		rtl_write_byte(rtlpriv, SPS1_CTRL + 3, 0x07);
+	else
+		rtl_write_byte(rtlpriv, RF_CTRL, 0x07);
+
+	if (rtl92s_phy_rf_config(hw) != true) {
+		RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, ("RF Config failed\n"));
+		return rtstatus;
+	}
+
+	/* After read predefined TXT, we must set BB/MAC/RF
+	 * register as our requirement */
+
+	rtlphy->rfreg_chnlval[0] = rtl92s_phy_query_rf_reg(hw,
+							   (enum radio_path)0,
+							   RF_CHNLBW,
+							   RFREG_OFFSET_MASK);
+	rtlphy->rfreg_chnlval[1] = rtl92s_phy_query_rf_reg(hw,
+							   (enum radio_path)1,
+							   RF_CHNLBW,
+							   RFREG_OFFSET_MASK);
+
+	/*---- Set CCK and OFDM Block "ON"----*/
+	rtl_set_bbreg(hw, RFPGA0_RFMOD, BCCKEN, 0x1);
+	rtl_set_bbreg(hw, RFPGA0_RFMOD, BOFDMEN, 0x1);
+
+	/*3 Set Hardware(Do nothing now) */
+	_rtl92se_hw_configure(hw);
+
+	/* Read EEPROM TX power index and PHY_REG_PG.txt to capture correct */
+	/* TX power index for different rate set. */
+	/* Get original hw reg values */
+	rtl92s_phy_get_hw_reg_originalvalue(hw);
+	/* Write correct tx power index */
+	rtl92s_phy_set_txpower(hw, rtlphy->current_channel);
+
+	/* We must set MAC address after firmware download. */
+	for (i = 0; i < 6; i++)
+		rtl_write_byte(rtlpriv, MACIDR0 + i, rtlefuse->dev_addr[i]);
+
+	/* EEPROM R/W workaround */
+	tmp_u1b = rtl_read_byte(rtlpriv, MAC_PINMUX_CFG);
+	rtl_write_byte(rtlpriv, MAC_PINMUX_CFG, tmp_u1b & (~BIT(3)));
+
+	rtl_write_byte(rtlpriv, 0x4d, 0x0);
+
+	if (hal_get_firmwareversion(rtlpriv) >= 0x49) {
+		tmp_byte = rtl_read_byte(rtlpriv, FW_RSVD_PG_CRTL) & (~BIT(4));
+		tmp_byte = tmp_byte | BIT(5);
+		rtl_write_byte(rtlpriv, FW_RSVD_PG_CRTL, tmp_byte);
+		rtl_write_dword(rtlpriv, TXDESC_MSK, 0xFFFFCFFF);
+	}
+
+	/* We enable high power and RA related mechanism after NIC
+	 * initialized. */
+	rtl92s_phy_set_fw_cmd(hw, FW_CMD_RA_INIT);
+
+	/* Add to prevent ASPM bug. */
+	/* Always enable hst and NIC clock request. */
+	rtl92s_phy_switch_ephy_parameter(hw);
+
+	/* Security related
+	 * 1. Clear all H/W keys.
+	 * 2. Enable H/W encryption/decryption. */
+	rtl_cam_reset_all_entry(hw);
+	secr_value |= SCR_TXENCENABLE;
+	secr_value |= SCR_RXENCENABLE;
+	secr_value |= SCR_NOSKMC;
+	rtl_write_byte(rtlpriv, REG_SECR, secr_value);
+
+	for (i = 0; i < 4; i++)
+		rtl_write_dword(rtlpriv, wdcapra_add[i], 0x5e4322);
+
+	if (rtlphy->rf_type == RF_1T2R) {
+		bool mrc2set = true;
+		/* Turn on B-Path */
+		rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_MRC, (u8 *)&mrc2set);
+	}
+
+	rtlpriv->cfg->ops->led_control(hw, LED_CTL_POWER_ON);
+	rtl92s_dm_init(hw);
+	rtlpci->being_init_adapter = false;
+
+	return err;
+}
+
+void rtl92se_set_mac_addr(struct rtl_io *io, const u8 * addr)
+{
+}
+
+void rtl92se_set_check_bssid(struct ieee80211_hw *hw, bool check_bssid)
+{
+	struct rtl_priv *rtlpriv = rtl_priv(hw);
+	struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+	u32 reg_rcr = rtlpci->receive_config;
+
+	if (rtlpriv->psc.rfpwr_state != ERFON)
+		return;
+
+	if (check_bssid == true) {
+		reg_rcr |= (RCR_CBSSID);
+		rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RCR, (u8 *)(&reg_rcr));
+	} else if (check_bssid == false) {
+		reg_rcr &= (~RCR_CBSSID);
+		rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RCR, (u8 *)(&reg_rcr));
+	}
+
+}
+
+static int _rtl92se_set_media_status(struct ieee80211_hw *hw,
+				     enum nl80211_iftype type)
+{
+	struct rtl_priv *rtlpriv = rtl_priv(hw);
+	u8 bt_msr = rtl_read_byte(rtlpriv, MSR);
+	enum led_ctl_mode ledaction = LED_CTL_NO_LINK;
+	u32 temp;
+	bt_msr &= ~MSR_LINK_MASK;
+
+	switch (type) {
+	case NL80211_IFTYPE_UNSPECIFIED:
+		bt_msr |= (MSR_LINK_NONE << MSR_LINK_SHIFT);
+		ledaction = LED_CTL_LINK;
+		RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
+			 ("Set Network type to NO LINK!\n"));
+		break;
+	case NL80211_IFTYPE_ADHOC:
+		bt_msr |= (MSR_LINK_ADHOC << MSR_LINK_SHIFT);
+		RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
+			 ("Set Network type to Ad Hoc!\n"));
+		break;
+	case NL80211_IFTYPE_STATION:
+		bt_msr |= (MSR_LINK_MANAGED << MSR_LINK_SHIFT);
+		ledaction = LED_CTL_LINK;
+		RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
+			 ("Set Network type to STA!\n"));
+		break;
+	case NL80211_IFTYPE_AP:
+		bt_msr |= (MSR_LINK_MASTER << MSR_LINK_SHIFT);
+		RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
+			 ("Set Network type to AP!\n"));
+		break;
+	default:
+		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
+			 ("Network type %d not support!\n", type));
+		return 1;
+		break;
+
+	}
+
+	rtl_write_byte(rtlpriv, (MSR), bt_msr);
+
+	temp = rtl_read_dword(rtlpriv, TCR);
+	rtl_write_dword(rtlpriv, TCR, temp & (~BIT(8)));
+	rtl_write_dword(rtlpriv, TCR, temp | BIT(8));
+
+
+	return 0;
+}
+
+/* HW_VAR_MEDIA_STATUS & HW_VAR_CECHK_BSSID */
+int rtl92se_set_network_type(struct ieee80211_hw *hw, enum nl80211_iftype type)
+{
+	struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+	if (_rtl92se_set_media_status(hw, type))
+		return -EOPNOTSUPP;
+
+	if (rtlpriv->mac80211.link_state == MAC80211_LINKED) {
+		if (type != NL80211_IFTYPE_AP)
+			rtl92se_set_check_bssid(hw, true);
+	} else {
+		rtl92se_set_check_bssid(hw, false);
+	}
+
+	return 0;
+}
+
+/* don't set REG_EDCA_BE_PARAM here because mac80211 will send pkt when scan */
+void rtl92se_set_qos(struct ieee80211_hw *hw, int aci)
+{
+	struct rtl_priv *rtlpriv = rtl_priv(hw);
+	rtl92s_dm_init_edca_turbo(hw);
+
+	switch (aci) {
+	case AC1_BK:
+		rtl_write_dword(rtlpriv, EDCAPARA_BK, 0xa44f);
+		break;
+	case AC0_BE:
+		/* rtl_write_dword(rtlpriv, EDCAPARA_BE, u4b_ac_param); */
+		break;
+	case AC2_VI:
+		rtl_write_dword(rtlpriv, EDCAPARA_VI, 0x5e4322);
+		break;
+	case AC3_VO:
+		rtl_write_dword(rtlpriv, EDCAPARA_VO, 0x2f3222);
+		break;
+	default:
+		RT_ASSERT(false, ("invalid aci: %d !\n", aci));
+		break;
+	}
+}
+
+void rtl92se_enable_interrupt(struct ieee80211_hw *hw)
+{
+	struct rtl_priv *rtlpriv = rtl_priv(hw);
+	struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+
+	rtl_write_dword(rtlpriv, INTA_MASK, rtlpci->irq_mask[0]);
+	/* Support Bit 32-37(Assign as Bit 0-5) interrupt setting now */
+	rtl_write_dword(rtlpriv, INTA_MASK + 4, rtlpci->irq_mask[1] & 0x3F);
+
+	rtlpci->irq_enabled = true;
+}
+
+void rtl92se_disable_interrupt(struct ieee80211_hw *hw)
+{
+	struct rtl_priv *rtlpriv = rtl_priv(hw);
+	struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+
+	rtl_write_dword(rtlpriv, INTA_MASK, 0);
+	rtl_write_dword(rtlpriv, INTA_MASK + 4, 0);
+
+	rtlpci->irq_enabled = false;
+}
+
+
+static u8 _rtl92s_set_sysclk(struct ieee80211_hw *hw, u8 data)
+{
+	struct rtl_priv *rtlpriv = rtl_priv(hw);
+	u8 waitcnt = 100;
+	bool result = false;
+	u8 tmp;
+
+	rtl_write_byte(rtlpriv, SYS_CLKR + 1, data);
+
+	/* Wait the MAC synchronized. */
+	udelay(400);
+
+	/* Check if it is set ready. */
+	tmp = rtl_read_byte(rtlpriv, SYS_CLKR + 1);
+	result = ((tmp & BIT(7)) == (data & BIT(7)));
+
+	if ((data & (BIT(6) | BIT(7))) == false) {
+		waitcnt = 100;
+		tmp = 0;
+
+		while (1) {
+			waitcnt--;
+			tmp = rtl_read_byte(rtlpriv, SYS_CLKR + 1);
+
+			if ((tmp & BIT(6)))
+				break;
+
+			printk(KERN_ERR "wait for BIT(6) return value %x\n",
+			       tmp);
+
+			if (waitcnt == 0)
+				break;
+			udelay(10);
+		}
+
+		if (waitcnt == 0)
+			result = false;
+		else
+			result = true;
+	}
+
+	return result;
+}
+
+static void _rtl92s_phy_set_rfhalt(struct ieee80211_hw *hw)
+{
+	struct rtl_priv *rtlpriv = rtl_priv(hw);
+	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+	struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
+	u8 u1btmp;
+
+	if (rtlhal->driver_going2unload)
+		rtl_write_byte(rtlpriv, 0x560, 0x0);
+
+	/* Power save for BB/RF */
+	u1btmp = rtl_read_byte(rtlpriv, LDOV12D_CTRL);
+	u1btmp |= BIT(0);
+	rtl_write_byte(rtlpriv, LDOV12D_CTRL, u1btmp);
+	rtl_write_byte(rtlpriv, SPS1_CTRL, 0x0);
+	rtl_write_byte(rtlpriv, TXPAUSE, 0xFF);
+	rtl_write_word(rtlpriv, CMDR, 0x57FC);
+	udelay(100);
+	rtl_write_word(rtlpriv, CMDR, 0x77FC);
+	rtl_write_byte(rtlpriv, PHY_CCA, 0x0);
+	udelay(10);
+	rtl_write_word(rtlpriv, CMDR, 0x37FC);
+	udelay(10);
+	rtl_write_word(rtlpriv, CMDR, 0x77FC);
+	udelay(10);
+	rtl_write_word(rtlpriv, CMDR, 0x57FC);
+	rtl_write_word(rtlpriv, CMDR, 0x0000);
+
+	if (rtlhal->driver_going2unload) {
+		u1btmp = rtl_read_byte(rtlpriv, (REG_SYS_FUNC_EN + 1));
+		u1btmp &= ~(BIT(0));
+		rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1, u1btmp);
+	}
+
+	u1btmp = rtl_read_byte(rtlpriv, (SYS_CLKR + 1));
+
+	/* Add description. After switch control path. register
+	 * after page1 will be invisible. We can not do any IO
+	 * for register>0x40. After resume&MACIO reset, we need
+	 * to remember previous reg content. */
+	if (u1btmp & BIT(7)) {
+		u1btmp &= ~(BIT(6) | BIT(7));
+		if (!_rtl92s_set_sysclk(hw, u1btmp)) {
+			printk(KERN_ERR "Switch ctrl path fail\n");
+			return;
+		}
+	}
+
+	/* Power save for MAC */
+	if (ppsc->rfoff_reason == RF_CHANGE_BY_IPS  &&
+		!rtlhal->driver_going2unload) {
+		/* enable LED function */
+		rtl_write_byte(rtlpriv, 0x03, 0xF9);
+	/* SW/HW radio off or halt adapter!! For example S3/S4 */
+	} else {
+		/* LED function disable. Power range is about 8mA now. */
+		/* if write 0xF1 disconnet_pci power
+		 *	 ifconfig wlan0 down power are both high 35:70 */
+		/* if write oxF9 disconnet_pci power
+		 * ifconfig wlan0 down power are both low  12:45*/
+		rtl_write_byte(rtlpriv, 0x03, 0xF9);
+	}
+
+	rtl_write_byte(rtlpriv, SYS_CLKR + 1, 0x70);
+	rtl_write_byte(rtlpriv, AFE_PLL_CTRL + 1, 0x68);
+	rtl_write_byte(rtlpriv,  AFE_PLL_CTRL, 0x00);
+	rtl_write_byte(rtlpriv, LDOA15_CTRL, 0x34);
+	rtl_write_byte(rtlpriv, AFE_XTAL_CTRL, 0x0E);
+	RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC);
+
+}
+
+static void _rtl92se_gen_refreshledstate(struct ieee80211_hw *hw)
+{
+	struct rtl_priv *rtlpriv = rtl_priv(hw);
+	struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+	struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
+	struct rtl_led *pLed0 = &(pcipriv->ledctl.sw_led0);
+
+	if (rtlpci->up_first_time == 1)
+		return;
+
+	if (rtlpriv->psc.rfoff_reason == RF_CHANGE_BY_IPS)
+		rtl92se_sw_led_on(hw, pLed0);
+	else
+		rtl92se_sw_led_off(hw, pLed0);
+}
+
+
+static void _rtl92se_power_domain_init(struct ieee80211_hw *hw)
+{
+	struct rtl_priv *rtlpriv = rtl_priv(hw);
+	u16 tmpu2b;
+	u8 tmpu1b;
+
+	rtlpriv->psc.pwrdomain_protect = true;
+
+	tmpu1b = rtl_read_byte(rtlpriv, (SYS_CLKR + 1));
+	if (tmpu1b & BIT(7)) {
+		tmpu1b &= ~(BIT(6) | BIT(7));
+		if (!_rtl92s_set_sysclk(hw, tmpu1b)) {
+			rtlpriv->psc.pwrdomain_protect = false;
+			return;
+		}
+	}
+
+	rtl_write_byte(rtlpriv, AFE_PLL_CTRL, 0x0);
+	rtl_write_byte(rtlpriv, LDOA15_CTRL, 0x34);
+
+	/* Reset MAC-IO and CPU and Core Digital BIT10/11/15 */
+	tmpu1b = rtl_read_byte(rtlpriv, SYS_FUNC_EN + 1);
+
+	/* If IPS we need to turn LED on. So we not
+	 * not disable BIT 3/7 of reg3. */
+	if (rtlpriv->psc.rfoff_reason & (RF_CHANGE_BY_IPS | RF_CHANGE_BY_HW))
+		tmpu1b &= 0xFB;
+	else
+		tmpu1b &= 0x73;
+
+	rtl_write_byte(rtlpriv, SYS_FUNC_EN + 1, tmpu1b);
+	/* wait for BIT 10/11/15 to pull high automatically!! */
+	mdelay(1);
+
+	rtl_write_byte(rtlpriv, CMDR, 0);
+	rtl_write_byte(rtlpriv, TCR, 0);
+
+	/* Data sheet not define 0x562!!! Copy from WMAC!!!!! */
+	tmpu1b = rtl_read_byte(rtlpriv, 0x562);
+	tmpu1b |= 0x08;
+	rtl_write_byte(rtlpriv, 0x562, tmpu1b);
+	tmpu1b &= ~(BIT(3));
+	rtl_write_byte(rtlpriv, 0x562, tmpu1b);
+
+	/* Enable AFE clock source */
+	tmpu1b = rtl_read_byte(rtlpriv, AFE_XTAL_CTRL);
+	rtl_write_byte(rtlpriv, AFE_XTAL_CTRL, (tmpu1b | 0x01));
+	/* Delay 1.5ms */
+	udelay(1500);
+	tmpu1b = rtl_read_byte(rtlpriv, AFE_XTAL_CTRL + 1);
+	rtl_write_byte(rtlpriv, AFE_XTAL_CTRL + 1, (tmpu1b & 0xfb));
+
+	/* Enable AFE Macro Block's Bandgap */
+	tmpu1b = rtl_read_byte(rtlpriv, AFE_MISC);
+	rtl_write_byte(rtlpriv, AFE_MISC, (tmpu1b | BIT(0)));
+	mdelay(1);
+
+	/* Enable AFE Mbias */
+	tmpu1b = rtl_read_byte(rtlpriv, AFE_MISC);
+	rtl_write_byte(rtlpriv, AFE_MISC, (tmpu1b | 0x02));
+	mdelay(1);
+
+	/* Enable LDOA15 block */
+	tmpu1b = rtl_read_byte(rtlpriv, LDOA15_CTRL);
+	rtl_write_byte(rtlpriv, LDOA15_CTRL, (tmpu1b | BIT(0)));
+
+	/* Set Digital Vdd to Retention isolation Path. */
+	tmpu2b = rtl_read_word(rtlpriv, SYS_ISO_CTRL);
+	rtl_write_word(rtlpriv, SYS_ISO_CTRL, (tmpu2b | BIT(11)));
+
+
+	/* For warm reboot NIC disappera bug. */
+	tmpu2b = rtl_read_word(rtlpriv, SYS_FUNC_EN);
+	rtl_write_word(rtlpriv, SYS_FUNC_EN, (tmpu2b | BIT(13)));
+
+	rtl_write_byte(rtlpriv, SYS_ISO_CTRL + 1, 0x68);
+
+	/* Enable AFE PLL Macro Block */
+	tmpu1b = rtl_read_byte(rtlpriv, AFE_PLL_CTRL);
+	rtl_write_byte(rtlpriv, AFE_PLL_CTRL, (tmpu1b | BIT(0) | BIT(4)));
+	/* Enable MAC 80MHZ clock */
+	tmpu1b = rtl_read_byte(rtlpriv, AFE_PLL_CTRL + 1);
+	rtl_write_byte(rtlpriv, AFE_PLL_CTRL + 1, (tmpu1b | BIT(0)));
+	mdelay(1);
+
+	/* Release isolation AFE PLL & MD */
+	rtl_write_byte(rtlpriv, SYS_ISO_CTRL, 0xA6);
+
+	/* Enable MAC clock */
+	tmpu2b = rtl_read_word(rtlpriv, SYS_CLKR);
+	rtl_write_word(rtlpriv, SYS_CLKR, (tmpu2b | BIT(12) | BIT(11)));
+
+	/* Enable Core digital and enable IOREG R/W */
+	tmpu2b = rtl_read_word(rtlpriv, SYS_FUNC_EN);
+	rtl_write_word(rtlpriv, SYS_FUNC_EN, (tmpu2b | BIT(11)));
+	/* enable REG_EN */
+	rtl_write_word(rtlpriv, SYS_FUNC_EN, (tmpu2b | BIT(11) | BIT(15)));
+
+	/* Switch the control path. */
+	tmpu2b = rtl_read_word(rtlpriv, SYS_CLKR);
+	rtl_write_word(rtlpriv, SYS_CLKR, (tmpu2b & (~BIT(2))));
+
+	tmpu1b = rtl_read_byte(rtlpriv, (SYS_CLKR + 1));
+	tmpu1b = ((tmpu1b | BIT(7)) & (~BIT(6)));
+	if (!_rtl92s_set_sysclk(hw, tmpu1b)) {
+		rtlpriv->psc.pwrdomain_protect = false;
+		return;
+	}
+
+	rtl_write_word(rtlpriv, CMDR, 0x37FC);
+
+	/* After MACIO reset,we must refresh LED state. */
+	_rtl92se_gen_refreshledstate(hw);
+
+	rtlpriv->psc.pwrdomain_protect = false;
+}
+
+void rtl92se_card_disable(struct ieee80211_hw *hw)
+{
+	struct rtl_priv *rtlpriv = rtl_priv(hw);
+	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+	struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+	struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
+	enum nl80211_iftype opmode;
+	u8 wait = 30;
+
+	rtlpriv->intf_ops->enable_aspm(hw);
+
+	if (rtlpci->driver_is_goingto_unload ||
+		ppsc->rfoff_reason > RF_CHANGE_BY_PS)
+		rtlpriv->cfg->ops->led_control(hw, LED_CTL_POWER_OFF);
+
+	/* we should chnge GPIO to input mode
+	 * this will drop away current about 25mA*/
+	rtl8192se_gpiobit3_cfg_inputmode(hw);
+
+	/* this is very important for ips power save */
+	while (wait-- >= 10 && rtlpriv->psc.pwrdomain_protect) {
+		if (rtlpriv->psc.pwrdomain_protect)
+			mdelay(20);
+		else
+			break;
+	}
+
+	mac->link_state = MAC80211_NOLINK;
+	opmode = NL80211_IFTYPE_UNSPECIFIED;
+	_rtl92se_set_media_status(hw, opmode);
+
+	_rtl92s_phy_set_rfhalt(hw);
+	udelay(100);
+}
+
+void rtl92se_interrupt_recognized(struct ieee80211_hw *hw, u32 *p_inta,
+			     u32 *p_intb)
+{
+	struct rtl_priv *rtlpriv = rtl_priv(hw);
+	struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+
+	*p_inta = rtl_read_dword(rtlpriv, ISR) & rtlpci->irq_mask[0];
+	rtl_write_dword(rtlpriv, ISR, *p_inta);
+
+	*p_intb = rtl_read_dword(rtlpriv, ISR + 4) & rtlpci->irq_mask[1];
+	rtl_write_dword(rtlpriv, ISR + 4, *p_intb);
+}
+
+void rtl92se_set_beacon_related_registers(struct ieee80211_hw *hw)
+{
+	struct rtl_priv *rtlpriv = rtl_priv(hw);
+	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+	u16 bcntime_cfg = 0;
+	u16 bcn_cw = 6, bcn_ifs = 0xf;
+	u16 atim_window = 2;
+
+	/* ATIM Window (in unit of TU). */
+	rtl_write_word(rtlpriv, ATIMWND, atim_window);
+
+	/* Beacon interval (in unit of TU). */
+	rtl_write_word(rtlpriv, BCN_INTERVAL, mac->beacon_interval);
+
+	/* DrvErlyInt (in unit of TU). (Time to send
+	 * interrupt to notify driver to change
+	 * beacon content) */
+	rtl_write_word(rtlpriv, BCN_DRV_EARLY_INT, 10 << 4);
+
+	/* BcnDMATIM(in unit of us). Indicates the
+	 * time before TBTT to perform beacon queue DMA  */
+	rtl_write_word(rtlpriv, BCN_DMATIME, 256);
+
+	/* Force beacon frame transmission even
+	 * after receiving beacon frame from
+	 * other ad hoc STA */
+	rtl_write_byte(rtlpriv, BCN_ERR_THRESH, 100);
+
+	/* Beacon Time Configuration */
+	if (mac->opmode == NL80211_IFTYPE_ADHOC)
+		bcntime_cfg |= (bcn_cw << BCN_TCFG_CW_SHIFT);
+
+	/* TODO: bcn_ifs may required to be changed on ASIC */
+	bcntime_cfg |= bcn_ifs << BCN_TCFG_IFS;
+
+	/*for beacon changed */
+	rtl92s_phy_set_beacon_hwreg(hw, mac->beacon_interval);
+}
+
+void rtl92se_set_beacon_interval(struct ieee80211_hw *hw)
+{
+	struct rtl_priv *rtlpriv = rtl_priv(hw);
+	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+	u16 bcn_interval = mac->beacon_interval;
+
+	/* Beacon interval (in unit of TU). */
+	rtl_write_word(rtlpriv, BCN_INTERVAL, bcn_interval);
+	/* 2008.10.24 added by tynli for beacon changed. */
+	rtl92s_phy_set_beacon_hwreg(hw, bcn_interval);
+}
+
+void rtl92se_update_interrupt_mask(struct ieee80211_hw *hw,
+		u32 add_msr, u32 rm_msr)
+{
+	struct rtl_priv *rtlpriv = rtl_priv(hw);
+	struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+
+	RT_TRACE(rtlpriv, COMP_INTR, DBG_LOUD,
+		 ("add_msr:%x, rm_msr:%x\n", add_msr, rm_msr));
+
+	if (add_msr)
+		rtlpci->irq_mask[0] |= add_msr;
+
+	if (rm_msr)
+		rtlpci->irq_mask[0] &= (~rm_msr);
+
+	rtl92se_disable_interrupt(hw);
+	rtl92se_enable_interrupt(hw);
+}
+
+static void _rtl8192se_get_IC_Inferiority(struct ieee80211_hw *hw)
+{
+	struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
+	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+	u8 efuse_id;
+
+	rtlhal->ic_class = IC_INFERIORITY_A;
+
+	/* Only retrieving while using EFUSE. */
+	if ((rtlefuse->epromtype == EEPROM_BOOT_EFUSE) &&
+		!rtlefuse->autoload_failflag) {
+		efuse_id = efuse_read_1byte(hw, EFUSE_IC_ID_OFFSET);
+
+		if (efuse_id == 0xfe)
+			rtlhal->ic_class = IC_INFERIORITY_B;
+	}
+}
+
+static void _rtl92se_read_adapter_info(struct ieee80211_hw *hw)
+{
+	struct rtl_priv *rtlpriv = rtl_priv(hw);
+	struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
+	struct rtl_phy *rtlphy = &(rtlpriv->phy);
+	u16 i, usvalue;
+	u16	eeprom_id;
+	u8 tempval;
+	u8 hwinfo[HWSET_MAX_SIZE_92S];
+	u8 rf_path, index;
+
+	if (rtlefuse->epromtype == EEPROM_93C46) {
+		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
+			 ("RTL819X Not boot from eeprom, check it !!"));
+	} else if (rtlefuse->epromtype == EEPROM_BOOT_EFUSE) {
+		rtl_efuse_shadow_map_update(hw);
+
+		memcpy((void *)hwinfo, (void *)
+			&rtlefuse->efuse_map[EFUSE_INIT_MAP][0],
+			HWSET_MAX_SIZE_92S);
+	}
+
+	RT_PRINT_DATA(rtlpriv, COMP_INIT, DBG_DMESG, ("MAP\n"),
+		      hwinfo, HWSET_MAX_SIZE_92S);
+
+	eeprom_id = *((u16 *)&hwinfo[0]);
+	if (eeprom_id != RTL8190_EEPROM_ID) {
+		RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
+			 ("EEPROM ID(%#x) is invalid!!\n", eeprom_id));
+		rtlefuse->autoload_failflag = true;
+	} else {
+		RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("Autoload OK\n"));
+		rtlefuse->autoload_failflag = false;
+	}
+
+	if (rtlefuse->autoload_failflag == true)
+		return;
+
+	_rtl8192se_get_IC_Inferiority(hw);
+
+	/* Read IC Version && Channel Plan */
+	/* VID, DID	 SE	0xA-D */
+	rtlefuse->eeprom_vid = *(u16 *)&hwinfo[EEPROM_VID];
+	rtlefuse->eeprom_did = *(u16 *)&hwinfo[EEPROM_DID];
+	rtlefuse->eeprom_svid = *(u16 *)&hwinfo[EEPROM_SVID];
+	rtlefuse->eeprom_smid = *(u16 *)&hwinfo[EEPROM_SMID];
+	rtlefuse->eeprom_version = *(u16 *)&hwinfo[EEPROM_VERSION];
+
+	RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
+			("EEPROMId = 0x%4x\n", eeprom_id));
+	RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
+			("EEPROM VID = 0x%4x\n", rtlefuse->eeprom_vid));
+	RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
+			("EEPROM DID = 0x%4x\n", rtlefuse->eeprom_did));
+	RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
+			("EEPROM SVID = 0x%4x\n", rtlefuse->eeprom_svid));
+	RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
+			("EEPROM SMID = 0x%4x\n", rtlefuse->eeprom_smid));
+
+	for (i = 0; i < 6; i += 2) {
+		usvalue = *(u16 *)&hwinfo[EEPROM_MAC_ADDR + i];
+		*((u16 *) (&rtlefuse->dev_addr[i])) = usvalue;
+	}
+
+	for (i = 0; i < 6; i++)
+		rtl_write_byte(rtlpriv, MACIDR0 + i, rtlefuse->dev_addr[i]);
+
+	RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
+		 (MAC_FMT "\n", MAC_ARG(rtlefuse->dev_addr)));
+
+	/* Get Tx Power Level by Channel */
+	/* Read Tx power of Channel 1 ~ 14 from EEPROM. */
+	/* 92S suupport RF A & B */
+	for (rf_path = 0; rf_path < 2; rf_path++) {
+		for (i = 0; i < 3; i++) {
+			/* Read CCK RF A & B Tx power  */
+			rtlefuse->eeprom_chnlarea_txpwr_cck[rf_path][i] =
+			hwinfo[EEPROM_TXPOWERBASE + rf_path * 3 + i];
+
+			/* Read OFDM RF A & B Tx power for 1T */
+			rtlefuse->eeprom_chnlarea_txpwr_ht40_1s[rf_path][i] =
+			hwinfo[EEPROM_TXPOWERBASE + 6 + rf_path * 3 + i];
+
+			/* Read OFDM RF A & B Tx power for 2T */
+			rtlefuse->eeprom_chnlarea_txpwr_ht40_2sdiif[rf_path][i]
+				 = hwinfo[EEPROM_TXPOWERBASE + 12 +
+				   rf_path * 3 + i];
+		}
+	}
+
+	for (rf_path = 0; rf_path < 2; rf_path++)
+		for (i = 0; i < 3; i++)
+			RTPRINT(rtlpriv, FINIT, INIT_EEPROM,
+				("RF(%d) EEPROM CCK Area(%d) = 0x%x\n", rf_path,
+				i, rtlefuse->eeprom_chnlarea_txpwr_cck
+					[rf_path][i]));
+	for (rf_path = 0; rf_path < 2; rf_path++)
+		for (i = 0; i < 3; i++)
+			RTPRINT(rtlpriv, FINIT, INIT_EEPROM,
+				("RF(%d) EEPROM HT40 1S Area(%d) = 0x%x\n",
+				 rf_path, i,
+				 rtlefuse->eeprom_chnlarea_txpwr_ht40_1s
+						[rf_path][i]));
+	for (rf_path = 0; rf_path < 2; rf_path++)
+		for (i = 0; i < 3; i++)
+			RTPRINT(rtlpriv, FINIT, INIT_EEPROM,
+				("RF(%d) EEPROM HT40 2S Diff Area(%d) = 0x%x\n",
+				 rf_path, i,
+				 rtlefuse->eeprom_chnlarea_txpwr_ht40_2sdiif
+					[rf_path][i]));
+
+	for (rf_path = 0; rf_path < 2; rf_path++) {
+
+		/* Assign dedicated channel tx power */
+		for (i = 0; i < 14; i++)	{
+			/* channel 1~3 use the same Tx Power Level. */
+			if (i < 3)
+				index = 0;
+			/* Channel 4-8 */
+			else if (i < 8)
+				index = 1;
+			/* Channel 9-14 */
+			else
+				index = 2;
+
+			/* Record A & B CCK /OFDM - 1T/2T Channel area
+			 * tx power */
+			rtlefuse->txpwrlevel_cck[rf_path][i]  =
+				rtlefuse->eeprom_chnlarea_txpwr_cck
+							[rf_path][index];
+			rtlefuse->txpwrlevel_ht40_1s[rf_path][i]  =
+				rtlefuse->eeprom_chnlarea_txpwr_ht40_1s
+							[rf_path][index];
+			rtlefuse->txpwrlevel_ht40_2s[rf_path][i]  =
+				rtlefuse->eeprom_chnlarea_txpwr_ht40_2sdiif
+							[rf_path][index];
+		}
+
+		for (i = 0; i < 14; i++) {
+			RTPRINT(rtlpriv, FINIT, INIT_TxPower,
+				("RF(%d)-Ch(%d) [CCK / HT40_1S / HT40_2S] = "
+				 "[0x%x / 0x%x / 0x%x]\n", rf_path, i,
+				 rtlefuse->txpwrlevel_cck[rf_path][i],
+				 rtlefuse->txpwrlevel_ht40_1s[rf_path][i],
+				 rtlefuse->txpwrlevel_ht40_2s[rf_path][i]));
+		}
+	}
+
+	for (rf_path = 0; rf_path < 2; rf_path++) {
+		for (i = 0; i < 3; i++) {
+			/* Read Power diff limit. */
+			rtlefuse->eeprom_pwrgroup[rf_path][i] =
+				hwinfo[EEPROM_TXPWRGROUP + rf_path * 3 + i];
+		}
+	}
+
+	for (rf_path = 0; rf_path < 2; rf_path++) {
+		/* Fill Pwr group */
+		for (i = 0; i < 14; i++) {
+			/* Chanel 1-3 */
+			if (i < 3)
+				index = 0;
+			/* Channel 4-8 */
+			else if (i < 8)
+				index = 1;
+			/* Channel 9-13 */
+			else
+				index = 2;
+
+			rtlefuse->pwrgroup_ht20[rf_path][i] =
+				(rtlefuse->eeprom_pwrgroup[rf_path][index] &
+				0xf);
+			rtlefuse->pwrgroup_ht40[rf_path][i] =
+				((rtlefuse->eeprom_pwrgroup[rf_path][index] &
+				0xf0) >> 4);
+
+			RTPRINT(rtlpriv, FINIT, INIT_TxPower,
+				("RF-%d pwrgroup_ht20[%d] = 0x%x\n",
+				 rf_path, i,
+				 rtlefuse->pwrgroup_ht20[rf_path][i]));
+			RTPRINT(rtlpriv, FINIT, INIT_TxPower,
+				("RF-%d pwrgroup_ht40[%d] = 0x%x\n",
+				 rf_path, i,
+				 rtlefuse->pwrgroup_ht40[rf_path][i]));
+			}
+	}
+
+	for (i = 0; i < 14; i++) {
+		/* Read tx power difference between HT OFDM 20/40 MHZ */
+		/* channel 1-3 */
+		if (i < 3)
+			index = 0;
+		/* Channel 4-8 */
+		else if (i < 8)
+			index = 1;
+		/* Channel 9-14 */
+		else
+			index = 2;
+
+		tempval = (*(u8 *)&hwinfo[EEPROM_TX_PWR_HT20_DIFF +
+			   index]) & 0xff;
+		rtlefuse->txpwr_ht20diff[RF90_PATH_A][i] = (tempval & 0xF);
+		rtlefuse->txpwr_ht20diff[RF90_PATH_B][i] =
+						 ((tempval >> 4) & 0xF);
+
+		/* Read OFDM<->HT tx power diff */
+		/* Channel 1-3 */
+		if (i < 3)
+			index = 0;
+		/* Channel 4-8 */
+		else if (i < 8)
+			index = 0x11;
+		/* Channel 9-14 */
+		else
+			index = 1;
+
+		tempval = (*(u8 *)&hwinfo[EEPROM_TX_PWR_OFDM_DIFF + index])
+				  & 0xff;
+		rtlefuse->txpwr_legacyhtdiff[RF90_PATH_A][i] =
+				 (tempval & 0xF);
+		rtlefuse->txpwr_legacyhtdiff[RF90_PATH_B][i] =
+				 ((tempval >> 4) & 0xF);
+
+		tempval = (*(u8 *)&hwinfo[TX_PWR_SAFETY_CHK]);
+		rtlefuse->txpwr_safetyflag = (tempval & 0x01);
+	}
+
+	rtlefuse->eeprom_regulatory = 0;
+	if (rtlefuse->eeprom_version >= 2) {
+		/* BIT(0)~2 */
+		if (rtlefuse->eeprom_version >= 4)
+			rtlefuse->eeprom_regulatory =
+				 (hwinfo[EEPROM_REGULATORY] & 0x7);
+		else /* BIT(0) */
+			rtlefuse->eeprom_regulatory =
+				 (hwinfo[EEPROM_REGULATORY] & 0x1);
+	}
+	RTPRINT(rtlpriv, FINIT, INIT_TxPower,
+		("eeprom_regulatory = 0x%x\n", rtlefuse->eeprom_regulatory));
+
+	for (i = 0; i < 14; i++)
+		RTPRINT(rtlpriv, FINIT, INIT_TxPower,
+			("RF-A Ht20 to HT40 Diff[%d] = 0x%x\n", i,
+			 rtlefuse->txpwr_ht20diff[RF90_PATH_A][i]));
+	for (i = 0; i < 14; i++)
+		RTPRINT(rtlpriv, FINIT, INIT_TxPower,
+			("RF-A Legacy to Ht40 Diff[%d] = 0x%x\n", i,
+			 rtlefuse->txpwr_legacyhtdiff[RF90_PATH_A][i]));
+	for (i = 0; i < 14; i++)
+		RTPRINT(rtlpriv, FINIT, INIT_TxPower,
+			("RF-B Ht20 to HT40 Diff[%d] = 0x%x\n", i,
+			 rtlefuse->txpwr_ht20diff[RF90_PATH_B][i]));
+	for (i = 0; i < 14; i++)
+		RTPRINT(rtlpriv, FINIT, INIT_TxPower,
+			("RF-B Legacy to HT40 Diff[%d] = 0x%x\n", i,
+			 rtlefuse->txpwr_legacyhtdiff[RF90_PATH_B][i]));
+
+	RTPRINT(rtlpriv, FINIT, INIT_TxPower, ("TxPwrSafetyFlag = %d\n",
+		rtlefuse->txpwr_safetyflag));
+
+	/* Read RF-indication and Tx Power gain
+	 * index diff of legacy to HT OFDM rate. */
+	tempval = (*(u8 *)&hwinfo[EEPROM_RFIND_POWERDIFF]) & 0xff;
+	rtlefuse->eeprom_txpowerdiff = tempval;
+	rtlefuse->legacy_httxpowerdiff =
+		rtlefuse->txpwr_legacyhtdiff[RF90_PATH_A][0];
+
+	RTPRINT(rtlpriv, FINIT, INIT_TxPower, ("TxPowerDiff = %#x\n",
+		rtlefuse->eeprom_txpowerdiff));
+
+	/* Get TSSI value for each path. */
+	usvalue = *(u16 *)&hwinfo[EEPROM_TSSI_A];
+	rtlefuse->eeprom_tssi[RF90_PATH_A] = (u8)((usvalue & 0xff00) >> 8);
+	usvalue = *(u8 *)&hwinfo[EEPROM_TSSI_B];
+	rtlefuse->eeprom_tssi[RF90_PATH_B] = (u8)(usvalue & 0xff);
+
+	RTPRINT(rtlpriv, FINIT, INIT_TxPower, ("TSSI_A = 0x%x, TSSI_B = 0x%x\n",
+		 rtlefuse->eeprom_tssi[RF90_PATH_A],
+		 rtlefuse->eeprom_tssi[RF90_PATH_B]));
+
+	/* Read antenna tx power offset of B/C/D to A  from EEPROM */
+	/* and read ThermalMeter from EEPROM */
+	tempval = *(u8 *)&hwinfo[EEPROM_THERMALMETER];
+	rtlefuse->eeprom_thermalmeter = tempval;
+	RTPRINT(rtlpriv, FINIT, INIT_TxPower, ("thermalmeter = 0x%x\n",
+		rtlefuse->eeprom_thermalmeter));
+
+	/* ThermalMeter, BIT(0)~3 for RFIC1, BIT(4)~7 for RFIC2 */
+	rtlefuse->thermalmeter[0] = (rtlefuse->eeprom_thermalmeter & 0x1f);
+	rtlefuse->tssi_13dbm = rtlefuse->eeprom_thermalmeter * 100;
+
+	/* Read CrystalCap from EEPROM */
+	tempval = (*(u8 *)&hwinfo[EEPROM_CRYSTALCAP]) >> 4;
+	rtlefuse->eeprom_crystalcap = tempval;
+	/* CrystalCap, BIT(12)~15 */
+	rtlefuse->crystalcap = rtlefuse->eeprom_crystalcap;
+
+	/* Read IC Version && Channel Plan */
+	/* Version ID, Channel plan */
+	rtlefuse->eeprom_channelplan = *(u8 *)&hwinfo[EEPROM_CHANNELPLAN];
+	rtlefuse->txpwr_fromeprom = true;
+	RTPRINT(rtlpriv, FINIT, INIT_TxPower, ("EEPROM ChannelPlan = 0x%4x\n",
+		rtlefuse->eeprom_channelplan));
+
+	/* Read Customer ID or Board Type!!! */
+	tempval = *(u8 *)&hwinfo[EEPROM_BOARDTYPE];
+	/* Change RF type definition */
+	if (tempval == 0)
+		rtlphy->rf_type = RF_2T2R;
+	else if (tempval == 1)
+		rtlphy->rf_type = RF_1T2R;
+	else if (tempval == 2)
+		rtlphy->rf_type = RF_1T2R;
+	else if (tempval == 3)
+		rtlphy->rf_type = RF_1T1R;
+
+	/* 1T2R but 1SS (1x1 receive combining) */
+	rtlefuse->b1x1_recvcombine = false;
+	if (rtlphy->rf_type == RF_1T2R) {
+		tempval = rtl_read_byte(rtlpriv, 0x07);
+		if (!(tempval & BIT(0))) {
+			rtlefuse->b1x1_recvcombine = true;
+			RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
+				("RF_TYPE=1T2R but only 1SS\n"));
+		}
+	}
+	rtlefuse->b1ss_support = rtlefuse->b1x1_recvcombine;
+	rtlefuse->eeprom_oemid = *(u8 *)&hwinfo[EEPROM_CUSTOMID];
+
+	RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("EEPROM Customer ID: 0x%2x",
+			rtlefuse->eeprom_oemid));
+
+	/* set channel paln to world wide 13 */
+	rtlefuse->channel_plan = COUNTRY_CODE_WORLD_WIDE_13;
+}
+
+void rtl92se_read_eeprom_info(struct ieee80211_hw *hw)
+{
+	struct rtl_priv *rtlpriv = rtl_priv(hw);
+	struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
+	u8 tmp_u1b = 0;
+
+	tmp_u1b = rtl_read_byte(rtlpriv, EPROM_CMD);
+
+	if (tmp_u1b & BIT(4)) {
+		RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, ("Boot from EEPROM\n"));
+		rtlefuse->epromtype = EEPROM_93C46;
+	} else {
+		RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, ("Boot from EFUSE\n"));
+		rtlefuse->epromtype = EEPROM_BOOT_EFUSE;
+	}
+
+	if (tmp_u1b & BIT(5)) {
+		RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("Autoload OK\n"));
+		rtlefuse->autoload_failflag = false;
+		_rtl92se_read_adapter_info(hw);
+	} else {
+		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("Autoload ERR!!\n"));
+		rtlefuse->autoload_failflag = true;
+	}
+}
+
+static void rtl92se_update_hal_rate_table(struct ieee80211_hw *hw,
+					  struct ieee80211_sta *sta)
+{
+	struct rtl_priv *rtlpriv = rtl_priv(hw);
+	struct rtl_phy *rtlphy = &(rtlpriv->phy);
+	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+	u32 ratr_value;
+	u8 ratr_index = 0;
+	u8 nmode = mac->ht_enable;
+	u8 mimo_ps = IEEE80211_SMPS_OFF;
+	u16 shortgi_rate = 0;
+	u32 tmp_ratr_value = 0;
+	u8 curtxbw_40mhz = mac->bw_40;
+	u8 curshortgi_40mhz = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40) ?
+				1 : 0;
+	u8 curshortgi_20mhz = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20) ?
+				1 : 0;
+	enum wireless_mode wirelessmode = mac->mode;
+
+	if (rtlhal->current_bandtype == BAND_ON_5G)
+		ratr_value = sta->supp_rates[1] << 4;
+	else
+		ratr_value = sta->supp_rates[0];
+	ratr_value |= (sta->ht_cap.mcs.rx_mask[1] << 20 |
+			sta->ht_cap.mcs.rx_mask[0] << 12);
+	switch (wirelessmode) {
+	case WIRELESS_MODE_B:
+		ratr_value &= 0x0000000D;
+		break;
+	case WIRELESS_MODE_G:
+		ratr_value &= 0x00000FF5;
+		break;
+	case WIRELESS_MODE_N_24G:
+	case WIRELESS_MODE_N_5G:
+		nmode = 1;
+		if (mimo_ps == IEEE80211_SMPS_STATIC) {
+			ratr_value &= 0x0007F005;
+		} else {
+			u32 ratr_mask;
+
+			if (get_rf_type(rtlphy) == RF_1T2R ||
+			    get_rf_type(rtlphy) == RF_1T1R) {
+				if (curtxbw_40mhz)
+					ratr_mask = 0x000ff015;
+				else
+					ratr_mask = 0x000ff005;
+			} else {
+				if (curtxbw_40mhz)
+					ratr_mask = 0x0f0ff015;
+				else
+					ratr_mask = 0x0f0ff005;
+			}
+
+			ratr_value &= ratr_mask;
+		}
+		break;
+	default:
+		if (rtlphy->rf_type == RF_1T2R)
+			ratr_value &= 0x000ff0ff;
+		else
+			ratr_value &= 0x0f0ff0ff;
+
+		break;
+	}
+
+	if (rtlpriv->rtlhal.version >= VERSION_8192S_BCUT)
+		ratr_value &= 0x0FFFFFFF;
+	else if (rtlpriv->rtlhal.version == VERSION_8192S_ACUT)
+		ratr_value &= 0x0FFFFFF0;
+
+	if (nmode && ((curtxbw_40mhz &&
+			 curshortgi_40mhz) || (!curtxbw_40mhz &&
+						 curshortgi_20mhz))) {
+
+		ratr_value |= 0x10000000;
+		tmp_ratr_value = (ratr_value >> 12);
+
+		for (shortgi_rate = 15; shortgi_rate > 0; shortgi_rate--) {
+			if ((1 << shortgi_rate) & tmp_ratr_value)
+				break;
+		}
+
+		shortgi_rate = (shortgi_rate << 12) | (shortgi_rate << 8) |
+		    (shortgi_rate << 4) | (shortgi_rate);
+
+		rtl_write_byte(rtlpriv, SG_RATE, shortgi_rate);
+	}
+
+	rtl_write_dword(rtlpriv, ARFR0 + ratr_index * 4, ratr_value);
+	if (ratr_value & 0xfffff000)
+		rtl92s_phy_set_fw_cmd(hw, FW_CMD_RA_REFRESH_N);
+	else
+		rtl92s_phy_set_fw_cmd(hw, FW_CMD_RA_REFRESH_BG);
+
+	RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG,
+		 ("%x\n", rtl_read_dword(rtlpriv, ARFR0)));
+}
+
+static void rtl92se_update_hal_rate_mask(struct ieee80211_hw *hw,
+					 struct ieee80211_sta *sta,
+					 u8 rssi_level)
+{
+	struct rtl_priv *rtlpriv = rtl_priv(hw);
+	struct rtl_phy *rtlphy = &(rtlpriv->phy);
+	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+	struct rtl_sta_info *sta_entry = NULL;
+	u32 ratr_bitmap;
+	u8 ratr_index = 0;
+	u8 curtxbw_40mhz = (sta->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40)
+				? 1 : 0;
+	u8 curshortgi_40mhz = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40) ?
+				1 : 0;
+	u8 curshortgi_20mhz = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20) ?
+				1 : 0;
+	enum wireless_mode wirelessmode = 0;
+	bool shortgi = false;
+	u32 ratr_value = 0;
+	u8 shortgi_rate = 0;
+	u32 mask = 0;
+	u32 band = 0;
+	bool bmulticast = false;
+	u8 macid = 0;
+	u8 mimo_ps = IEEE80211_SMPS_OFF;
+
+	sta_entry = (struct rtl_sta_info *) sta->drv_priv;
+	wirelessmode = sta_entry->wireless_mode;
+	if (mac->opmode == NL80211_IFTYPE_STATION)
+		curtxbw_40mhz = mac->bw_40;
+	else if (mac->opmode == NL80211_IFTYPE_AP ||
+		mac->opmode == NL80211_IFTYPE_ADHOC)
+		macid = sta->aid + 1;
+
+	if (rtlhal->current_bandtype == BAND_ON_5G)
+		ratr_bitmap = sta->supp_rates[1] << 4;
+	else
+		ratr_bitmap = sta->supp_rates[0];
+	ratr_bitmap |= (sta->ht_cap.mcs.rx_mask[1] << 20 |
+			sta->ht_cap.mcs.rx_mask[0] << 12);
+	switch (wirelessmode) {
+	case WIRELESS_MODE_B:
+		band |= WIRELESS_11B;
+		ratr_index = RATR_INX_WIRELESS_B;
+		if (ratr_bitmap & 0x0000000c)
+			ratr_bitmap &= 0x0000000d;
+		else
+			ratr_bitmap &= 0x0000000f;
+		break;
+	case WIRELESS_MODE_G:
+		band |= (WIRELESS_11G | WIRELESS_11B);
+		ratr_index = RATR_INX_WIRELESS_GB;
+
+		if (rssi_level == 1)
+			ratr_bitmap &= 0x00000f00;
+		else if (rssi_level == 2)
+			ratr_bitmap &= 0x00000ff0;
+		else
+			ratr_bitmap &= 0x00000ff5;
+		break;
+	case WIRELESS_MODE_A:
+		band |= WIRELESS_11A;
+		ratr_index = RATR_INX_WIRELESS_A;
+		ratr_bitmap &= 0x00000ff0;
+		break;
+	case WIRELESS_MODE_N_24G:
+	case WIRELESS_MODE_N_5G:
+		band |= (WIRELESS_11N | WIRELESS_11G | WIRELESS_11B);
+		ratr_index = RATR_INX_WIRELESS_NGB;
+
+		if (mimo_ps == IEEE80211_SMPS_STATIC) {
+			if (rssi_level == 1)
+				ratr_bitmap &= 0x00070000;
+			else if (rssi_level == 2)
+				ratr_bitmap &= 0x0007f000;
+			else
+				ratr_bitmap &= 0x0007f005;
+		} else {
+			if (rtlphy->rf_type == RF_1T2R ||
+				rtlphy->rf_type == RF_1T1R) {
+				if (rssi_level == 1) {
+						ratr_bitmap &= 0x000f0000;
+				} else if (rssi_level == 3) {
+					ratr_bitmap &= 0x000fc000;
+				} else if (rssi_level == 5) {
+						ratr_bitmap &= 0x000ff000;
+				} else {
+					if (curtxbw_40mhz)
+						ratr_bitmap &= 0x000ff015;
+					else
+						ratr_bitmap &= 0x000ff005;
+				}
+			} else {
+				if (rssi_level == 1) {
+					ratr_bitmap &= 0x0f8f0000;
+				} else if (rssi_level == 3) {
+					ratr_bitmap &= 0x0f8fc000;
+				} else if (rssi_level == 5) {
+					ratr_bitmap &= 0x0f8ff000;
+				} else {
+					if (curtxbw_40mhz)
+						ratr_bitmap &= 0x0f8ff015;
+					else
+						ratr_bitmap &= 0x0f8ff005;
+				}
+			}
+		}
+
+		if ((curtxbw_40mhz && curshortgi_40mhz) ||
+		    (!curtxbw_40mhz && curshortgi_20mhz)) {
+			if (macid == 0)
+				shortgi = true;
+			else if (macid == 1)
+				shortgi = false;
+		}
+		break;
+	default:
+		band |= (WIRELESS_11N | WIRELESS_11G | WIRELESS_11B);
+		ratr_index = RATR_INX_WIRELESS_NGB;
+
+		if (rtlphy->rf_type == RF_1T2R)
+			ratr_bitmap &= 0x000ff0ff;
+		else
+			ratr_bitmap &= 0x0f8ff0ff;
+		break;
+	}
+
+	if (rtlpriv->rtlhal.version >= VERSION_8192S_BCUT)
+		ratr_bitmap &= 0x0FFFFFFF;
+	else if (rtlpriv->rtlhal.version == VERSION_8192S_ACUT)
+		ratr_bitmap &= 0x0FFFFFF0;
+
+	if (shortgi) {
+		ratr_bitmap |= 0x10000000;
+		/* Get MAX MCS available. */
+		ratr_value = (ratr_bitmap >> 12);
+		for (shortgi_rate = 15; shortgi_rate > 0; shortgi_rate--) {
+			if ((1 << shortgi_rate) & ratr_value)
+				break;
+		}
+
+		shortgi_rate = (shortgi_rate << 12) | (shortgi_rate << 8) |
+			(shortgi_rate << 4) | (shortgi_rate);
+		rtl_write_byte(rtlpriv, SG_RATE, shortgi_rate);
+	}
+
+	mask |= (bmulticast ? 1 : 0) << 9 | (macid & 0x1f) << 4 | (band & 0xf);
+
+	RT_TRACE(rtlpriv, COMP_RATR, DBG_TRACE, ("mask = %x, bitmap = %x\n",
+			mask, ratr_bitmap));
+	rtl_write_dword(rtlpriv, 0x2c4, ratr_bitmap);
+	rtl_write_dword(rtlpriv, WFM5, (FW_RA_UPDATE_MASK | (mask << 8)));
+
+	if (macid != 0)
+		sta_entry->ratr_index = ratr_index;
+}
+
+void rtl92se_update_hal_rate_tbl(struct ieee80211_hw *hw,
+		struct ieee80211_sta *sta, u8 rssi_level)
+{
+	struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+	if (rtlpriv->dm.useramask)
+		rtl92se_update_hal_rate_mask(hw, sta, rssi_level);
+	else
+		rtl92se_update_hal_rate_table(hw, sta);
+}
+
+void rtl92se_update_channel_access_setting(struct ieee80211_hw *hw)
+{
+	struct rtl_priv *rtlpriv = rtl_priv(hw);
+	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+	u16 sifs_timer;
+
+	rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SLOT_TIME,
+				      (u8 *)&mac->slot_time);
+	sifs_timer = 0x0e0e;
+	rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SIFS, (u8 *)&sifs_timer);
+
+}
+
+/* this ifunction is for RFKILL, it's different with windows,
+ * because UI will disable wireless when GPIO Radio Off.
+ * And here we not check or Disable/Enable ASPM like windows*/
+bool rtl92se_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 *valid)
+{
+	struct rtl_priv *rtlpriv = rtl_priv(hw);
+	struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
+	struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+	enum rf_pwrstate rfpwr_toset, cur_rfstate;
+	unsigned long flag = 0;
+	bool actuallyset = false;
+	bool turnonbypowerdomain = false;
+
+	/* just 8191se can check gpio before firstup, 92c/92d have fixed it */
+	if ((rtlpci->up_first_time == 1) || (rtlpci->being_init_adapter))
+		return false;
+
+	if (ppsc->swrf_processing)
+		return false;
+
+	spin_lock_irqsave(&rtlpriv->locks.rf_ps_lock, flag);
+	if (ppsc->rfchange_inprogress) {
+		spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock, flag);
+		return false;
+	} else {
+		ppsc->rfchange_inprogress = true;
+		spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock, flag);
+	}
+
+	cur_rfstate = ppsc->rfpwr_state;
+
+	/* because after _rtl92s_phy_set_rfhalt, all power
+	 * closed, so we must open some power for GPIO check,
+	 * or we will always check GPIO RFOFF here,
+	 * And we should close power after GPIO check */
+	if (RT_IN_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC)) {
+		_rtl92se_power_domain_init(hw);
+		turnonbypowerdomain = true;
+	}
+
+	rfpwr_toset = _rtl92se_rf_onoff_detect(hw);
+
+	if ((ppsc->hwradiooff == true) && (rfpwr_toset == ERFON)) {
+		RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
+			 ("RFKILL-HW Radio ON, RF ON\n"));
+
+		rfpwr_toset = ERFON;
+		ppsc->hwradiooff = false;
+		actuallyset = true;
+	} else if ((ppsc->hwradiooff == false) && (rfpwr_toset == ERFOFF)) {
+		RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
+			 ("RFKILL-HW Radio OFF, RF OFF\n"));
+
+		rfpwr_toset = ERFOFF;
+		ppsc->hwradiooff = true;
+		actuallyset = true;
+	}
+
+	if (actuallyset) {
+		spin_lock_irqsave(&rtlpriv->locks.rf_ps_lock, flag);
+		ppsc->rfchange_inprogress = false;
+		spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock, flag);
+
+	/* this not include ifconfig wlan0 down case */
+	/* } else if (rfpwr_toset == ERFOFF || cur_rfstate == ERFOFF) { */
+	} else {
+		/* because power_domain_init may be happen when
+		 * _rtl92s_phy_set_rfhalt, this will open some powers
+		 * and cause current increasing about 40 mA for ips,
+		 * rfoff and ifconfig down, so we set
+		 * _rtl92s_phy_set_rfhalt again here */
+		if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_HALT_NIC &&
+			turnonbypowerdomain) {
+			_rtl92s_phy_set_rfhalt(hw);
+			RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC);
+		}
+
+		spin_lock_irqsave(&rtlpriv->locks.rf_ps_lock, flag);
+		ppsc->rfchange_inprogress = false;
+		spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock, flag);
+	}
+
+	*valid = 1;
+	return !ppsc->hwradiooff;
+
+}
+
+/* Is_wepkey just used for WEP used as group & pairwise key
+ * if pairwise is AES ang group is WEP Is_wepkey == false.*/
+void rtl92se_set_key(struct ieee80211_hw *hw, u32 key_index, u8 *p_macaddr,
+	bool is_group, u8 enc_algo, bool is_wepkey, bool clear_all)
+{
+	struct rtl_priv *rtlpriv = rtl_priv(hw);
+	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+	struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
+	u8 *macaddr = p_macaddr;
+
+	u32 entry_id = 0;
+	bool is_pairwise = false;
+
+	static u8 cam_const_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}
+	};
+	static u8 cam_const_broad[] = {
+		0xff, 0xff, 0xff, 0xff, 0xff, 0xff
+	};
+
+	if (clear_all) {
+		u8 idx = 0;
+		u8 cam_offset = 0;
+		u8 clear_number = 5;
+
+		RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, ("clear_all\n"));
+
+		for (idx = 0; idx < clear_number; idx++) {
+			rtl_cam_mark_invalid(hw, cam_offset + idx);
+			rtl_cam_empty_entry(hw, cam_offset + idx);
+
+			if (idx < 5) {
+				memset(rtlpriv->sec.key_buf[idx], 0,
+				       MAX_KEY_LEN);
+				rtlpriv->sec.key_len[idx] = 0;
+			}
+		}
+
+	} else {
+		switch (enc_algo) {
+		case WEP40_ENCRYPTION:
+			enc_algo = CAM_WEP40;
+			break;
+		case WEP104_ENCRYPTION:
+			enc_algo = CAM_WEP104;
+			break;
+		case TKIP_ENCRYPTION:
+			enc_algo = CAM_TKIP;
+			break;
+		case AESCCMP_ENCRYPTION:
+			enc_algo = CAM_AES;
+			break;
+		default:
+			RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
+					("switch case not process\n"));
+			enc_algo = CAM_TKIP;
+			break;
+		}
+
+		if (is_wepkey || rtlpriv->sec.use_defaultkey) {
+			macaddr = cam_const_addr[key_index];
+			entry_id = key_index;
+		} else {
+			if (is_group) {
+				macaddr = cam_const_broad;
+				entry_id = key_index;
+			} else {
+				if (mac->opmode == NL80211_IFTYPE_AP) {
+					entry_id = rtl_cam_get_free_entry(hw,
+								 p_macaddr);
+					if (entry_id >=  TOTAL_CAM_ENTRY) {
+						RT_TRACE(rtlpriv,
+						   COMP_SEC, DBG_EMERG,
+						   ("Can not find free hw"
+						   " security cam entry\n"));
+						return;
+					}
+				} else {
+					entry_id = CAM_PAIRWISE_KEY_POSITION;
+				}
+
+				key_index = PAIRWISE_KEYIDX;
+				is_pairwise = true;
+			}
+		}
+
+		if (rtlpriv->sec.key_len[key_index] == 0) {
+			RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
+				 ("delete one entry, entry_id is %d\n",
+				 entry_id));
+			if (mac->opmode == NL80211_IFTYPE_AP)
+				rtl_cam_del_entry(hw, p_macaddr);
+			rtl_cam_delete_one_entry(hw, p_macaddr, entry_id);
+		} else {
+			RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD,
+				 ("The insert KEY length is %d\n",
+				  rtlpriv->sec.key_len[PAIRWISE_KEYIDX]));
+			RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD,
+				 ("The insert KEY  is %x %x\n",
+				  rtlpriv->sec.key_buf[0][0],
+				  rtlpriv->sec.key_buf[0][1]));
+
+			RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
+				 ("add one entry\n"));
+			if (is_pairwise) {
+				RT_PRINT_DATA(rtlpriv, COMP_SEC, DBG_LOUD,
+				      "Pairwiase Key content :",
+				       rtlpriv->sec.pairwise_key,
+				       rtlpriv->sec.key_len[PAIRWISE_KEYIDX]);
+
+				RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
+					 ("set Pairwiase key\n"));
+
+				rtl_cam_add_one_entry(hw, macaddr, key_index,
+					entry_id, enc_algo,
+					CAM_CONFIG_NO_USEDK,
+					rtlpriv->sec.key_buf[key_index]);
+			} else {
+				RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
+					 ("set group key\n"));
+
+				if (mac->opmode == NL80211_IFTYPE_ADHOC) {
+					rtl_cam_add_one_entry(hw,
+						rtlefuse->dev_addr,
+						PAIRWISE_KEYIDX,
+						CAM_PAIRWISE_KEY_POSITION,
+						enc_algo, CAM_CONFIG_NO_USEDK,
+						rtlpriv->sec.key_buf[entry_id]);
+				}
+
+				rtl_cam_add_one_entry(hw, macaddr, key_index,
+					      entry_id, enc_algo,
+					      CAM_CONFIG_NO_USEDK,
+					      rtlpriv->sec.key_buf[entry_id]);
+			}
+
+		}
+	}
+}
+
+void rtl92se_suspend(struct ieee80211_hw *hw)
+{
+	struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+
+	rtlpci->up_first_time = true;
+}
+
+void rtl92se_resume(struct ieee80211_hw *hw)
+{
+	struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+	u32 val;
+
+	pci_read_config_dword(rtlpci->pdev, 0x40, &val);
+	if ((val & 0x0000ff00) != 0)
+		pci_write_config_dword(rtlpci->pdev, 0x40,
+			val & 0xffff00ff);
+}
diff -druN linux-2.6.39-libre/drivers/net/wireless/rtlwifi/rtl8192se/hw.h linux-3.0-rc7-libre/drivers/net/wireless/rtlwifi/rtl8192se/hw.h
--- linux-2.6.39-libre/drivers/net/wireless/rtlwifi/rtl8192se/hw.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/net/wireless/rtlwifi/rtl8192se/hw.h	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,79 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2009-2010  Realtek Corporation.
+ *
+ * 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:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+#ifndef __REALTEK_PCI92SE_HW_H__
+#define __REALTEK_PCI92SE_HW_H__
+
+#define MSR_LINK_MANAGED   2
+#define MSR_LINK_NONE      0
+#define MSR_LINK_SHIFT     0
+#define MSR_LINK_ADHOC     1
+#define MSR_LINK_MASTER    3
+
+enum WIRELESS_NETWORK_TYPE {
+	WIRELESS_11B = 1,
+	WIRELESS_11G = 2,
+	WIRELESS_11A = 4,
+	WIRELESS_11N = 8
+};
+
+void rtl92se_get_hw_reg(struct ieee80211_hw *hw,
+			u8 variable, u8 *val);
+void rtl92se_read_eeprom_info(struct ieee80211_hw *hw);
+void rtl92se_interrupt_recognized(struct ieee80211_hw *hw,
+				  u32 *inta, u32 *intb);
+int rtl92se_hw_init(struct ieee80211_hw *hw);
+void rtl92se_card_disable(struct ieee80211_hw *hw);
+void rtl92se_enable_interrupt(struct ieee80211_hw *hw);
+void rtl92se_disable_interrupt(struct ieee80211_hw *hw);
+int rtl92se_set_network_type(struct ieee80211_hw *hw,
+			     enum nl80211_iftype type);
+void rtl92se_set_check_bssid(struct ieee80211_hw *hw, bool check_bssid);
+void rtl92se_set_mac_addr(struct rtl_io *io, const u8 * addr);
+void rtl92se_set_qos(struct ieee80211_hw *hw, int aci);
+void rtl92se_set_beacon_related_registers(struct ieee80211_hw *hw);
+void rtl92se_set_beacon_interval(struct ieee80211_hw *hw);
+void rtl92se_update_interrupt_mask(struct ieee80211_hw *hw,
+				   u32 add_msr, u32 rm_msr);
+void rtl92se_set_hw_reg(struct ieee80211_hw *hw, u8 variable,
+			u8 *val);
+void rtl92se_update_hal_rate_tbl(struct ieee80211_hw *hw,
+		struct ieee80211_sta *sta, u8 rssi_level);
+void rtl92se_update_channel_access_setting(struct ieee80211_hw *hw);
+bool rtl92se_gpio_radio_on_off_checking(struct ieee80211_hw *hw,
+					u8 *valid);
+void rtl8192se_gpiobit3_cfg_inputmode(struct ieee80211_hw *hw);
+void rtl92se_enable_hw_security_config(struct ieee80211_hw *hw);
+void rtl92se_set_key(struct ieee80211_hw *hw,
+		     u32 key_index, u8 *macaddr, bool is_group,
+		     u8 enc_algo, bool is_wepkey, bool clear_all);
+void rtl92se_suspend(struct ieee80211_hw *hw);
+void rtl92se_resume(struct ieee80211_hw *hw);
+
+#endif
+
diff -druN linux-2.6.39-libre/drivers/net/wireless/rtlwifi/rtl8192se/led.c linux-3.0-rc7-libre/drivers/net/wireless/rtlwifi/rtl8192se/led.c
--- linux-2.6.39-libre/drivers/net/wireless/rtlwifi/rtl8192se/led.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/net/wireless/rtlwifi/rtl8192se/led.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,149 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2009-2010  Realtek Corporation.
+ *
+ * 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:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+
+#include "../wifi.h"
+#include "../pci.h"
+#include "reg.h"
+#include "led.h"
+
+static void _rtl92se_init_led(struct ieee80211_hw *hw,
+			      struct rtl_led *pled, enum rtl_led_pin ledpin)
+{
+	pled->hw = hw;
+	pled->ledpin = ledpin;
+	pled->ledon = false;
+}
+
+void rtl92se_init_sw_leds(struct ieee80211_hw *hw)
+{
+	struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
+	_rtl92se_init_led(hw, &(pcipriv->ledctl.sw_led0), LED_PIN_LED0);
+	_rtl92se_init_led(hw, &(pcipriv->ledctl.sw_led1), LED_PIN_LED1);
+}
+
+void rtl92se_sw_led_on(struct ieee80211_hw *hw, struct rtl_led *pled)
+{
+	u8 ledcfg;
+	struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+	RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD,
+		 ("LedAddr:%X ledpin=%d\n", LEDCFG, pled->ledpin));
+
+	ledcfg = rtl_read_byte(rtlpriv, LEDCFG);
+
+	switch (pled->ledpin) {
+	case LED_PIN_GPIO0:
+		break;
+	case LED_PIN_LED0:
+		rtl_write_byte(rtlpriv, LEDCFG, ledcfg & 0xf0);
+		break;
+	case LED_PIN_LED1:
+		rtl_write_byte(rtlpriv, LEDCFG, ledcfg & 0x0f);
+		break;
+	default:
+		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
+			 ("switch case not process\n"));
+		break;
+	}
+	pled->ledon = true;
+}
+
+void rtl92se_sw_led_off(struct ieee80211_hw *hw, struct rtl_led *pled)
+{
+	struct rtl_priv *rtlpriv = rtl_priv(hw);
+	struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
+	u8 ledcfg;
+
+	RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD,
+		 ("LedAddr:%X ledpin=%d\n", LEDCFG, pled->ledpin));
+
+	ledcfg = rtl_read_byte(rtlpriv, LEDCFG);
+
+	switch (pled->ledpin) {
+	case LED_PIN_GPIO0:
+		break;
+	case LED_PIN_LED0:
+		ledcfg &= 0xf0;
+		if (pcipriv->ledctl.led_opendrain == true)
+			rtl_write_byte(rtlpriv, LEDCFG, (ledcfg | BIT(1)));
+		else
+			rtl_write_byte(rtlpriv, LEDCFG, (ledcfg | BIT(3)));
+		break;
+	case LED_PIN_LED1:
+		ledcfg &= 0x0f;
+		rtl_write_byte(rtlpriv, LEDCFG, (ledcfg | BIT(3)));
+		break;
+	default:
+		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
+			 ("switch case not process\n"));
+		break;
+	}
+	pled->ledon = false;
+}
+
+static void _rtl92se_sw_led_control(struct ieee80211_hw *hw,
+				    enum led_ctl_mode ledaction)
+{
+	struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
+	struct rtl_led *pLed0 = &(pcipriv->ledctl.sw_led0);
+	switch (ledaction) {
+	case LED_CTL_POWER_ON:
+	case LED_CTL_LINK:
+	case LED_CTL_NO_LINK:
+		rtl92se_sw_led_on(hw, pLed0);
+		break;
+	case LED_CTL_POWER_OFF:
+		rtl92se_sw_led_off(hw, pLed0);
+		break;
+	default:
+		break;
+	}
+}
+
+void rtl92se_led_control(struct ieee80211_hw *hw, enum led_ctl_mode ledaction)
+{
+	struct rtl_priv *rtlpriv = rtl_priv(hw);
+	struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
+
+	if ((ppsc->rfoff_reason > RF_CHANGE_BY_PS) &&
+	    (ledaction == LED_CTL_TX ||
+	    ledaction == LED_CTL_RX ||
+	    ledaction == LED_CTL_SITE_SURVEY ||
+	    ledaction == LED_CTL_LINK ||
+	    ledaction == LED_CTL_NO_LINK ||
+	    ledaction == LED_CTL_START_TO_LINK ||
+	    ledaction == LED_CTL_POWER_ON)) {
+		return;
+	}
+	RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD, ("ledaction %d,\n",
+		 ledaction));
+
+	_rtl92se_sw_led_control(hw, ledaction);
+}
+
diff -druN linux-2.6.39-libre/drivers/net/wireless/rtlwifi/rtl8192se/led.h linux-3.0-rc7-libre/drivers/net/wireless/rtlwifi/rtl8192se/led.h
--- linux-2.6.39-libre/drivers/net/wireless/rtlwifi/rtl8192se/led.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/net/wireless/rtlwifi/rtl8192se/led.h	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,37 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2009-2010  Realtek Corporation.
+ *
+ * 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:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+#ifndef __REALTEK_PCI92SE_LED_H__
+#define __REALTEK_PCI92SE_LED_H__
+
+void rtl92se_init_sw_leds(struct ieee80211_hw *hw);
+void rtl92se_sw_led_on(struct ieee80211_hw *hw,	struct rtl_led *pled);
+void rtl92se_sw_led_off(struct ieee80211_hw *hw, struct rtl_led *pled);
+void rtl92se_led_control(struct ieee80211_hw *hw, enum led_ctl_mode ledaction);
+
+#endif
diff -druN linux-2.6.39-libre/drivers/net/wireless/rtlwifi/rtl8192se/Makefile linux-3.0-rc7-libre/drivers/net/wireless/rtlwifi/rtl8192se/Makefile
--- linux-2.6.39-libre/drivers/net/wireless/rtlwifi/rtl8192se/Makefile	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/net/wireless/rtlwifi/rtl8192se/Makefile	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,15 @@
+rtl8192se-objs :=		\
+		dm.o		\
+		fw.o		\
+		hw.o		\
+		led.o		\
+		phy.o		\
+		rf.o		\
+		sw.o		\
+		table.o		\
+		trx.o
+
+obj-$(CONFIG_RTL8192SE) += rtl8192se.o
+
+ccflags-y += -D__CHECK_ENDIAN__
+
diff -druN linux-2.6.39-libre/drivers/net/wireless/rtlwifi/rtl8192se/phy.c linux-3.0-rc7-libre/drivers/net/wireless/rtlwifi/rtl8192se/phy.c
--- linux-2.6.39-libre/drivers/net/wireless/rtlwifi/rtl8192se/phy.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/net/wireless/rtlwifi/rtl8192se/phy.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,1740 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2009-2010  Realtek Corporation.
+ *
+ * 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:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+
+#include "../wifi.h"
+#include "../pci.h"
+#include "../ps.h"
+#include "reg.h"
+#include "def.h"
+#include "phy.h"
+#include "rf.h"
+#include "dm.h"
+#include "fw.h"
+#include "hw.h"
+#include "table.h"
+
+static u32 _rtl92s_phy_calculate_bit_shift(u32 bitmask)
+{
+	u32 i;
+
+	for (i = 0; i <= 31; i++) {
+		if (((bitmask >> i) & 0x1) == 1)
+			break;
+	}
+
+	return i;
+}
+
+u32 rtl92s_phy_query_bb_reg(struct ieee80211_hw *hw, u32 regaddr, u32 bitmask)
+{
+	struct rtl_priv *rtlpriv = rtl_priv(hw);
+	u32 returnvalue = 0, originalvalue, bitshift;
+
+	RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), bitmask(%#x)\n",
+			regaddr, bitmask));
+
+	originalvalue = rtl_read_dword(rtlpriv, regaddr);
+	bitshift = _rtl92s_phy_calculate_bit_shift(bitmask);
+	returnvalue = (originalvalue & bitmask) >> bitshift;
+
+	RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
+		 ("BBR MASK=0x%x Addr[0x%x]=0x%x\n",
+		 bitmask, regaddr, originalvalue));
+
+	return returnvalue;
+
+}
+
+void rtl92s_phy_set_bb_reg(struct ieee80211_hw *hw, u32 regaddr, u32 bitmask,
+			   u32 data)
+{
+	struct rtl_priv *rtlpriv = rtl_priv(hw);
+	u32 originalvalue, bitshift;
+
+	RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), bitmask(%#x),"
+			" data(%#x)\n", regaddr, bitmask, data));
+
+	if (bitmask != MASKDWORD) {
+		originalvalue = rtl_read_dword(rtlpriv, regaddr);
+		bitshift = _rtl92s_phy_calculate_bit_shift(bitmask);
+		data = ((originalvalue & (~bitmask)) | (data << bitshift));
+	}
+
+	rtl_write_dword(rtlpriv, regaddr, data);
+
+	RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), bitmask(%#x),"
+			" data(%#x)\n",	regaddr, bitmask, data));
+
+}
+
+static u32 _rtl92s_phy_rf_serial_read(struct ieee80211_hw *hw,
+				      enum radio_path rfpath, u32 offset)
+{
+
+	struct rtl_priv *rtlpriv = rtl_priv(hw);
+	struct rtl_phy *rtlphy = &(rtlpriv->phy);
+	struct bb_reg_def *pphyreg = &rtlphy->phyreg_def[rfpath];
+	u32 newoffset;
+	u32 tmplong, tmplong2;
+	u8 rfpi_enable = 0;
+	u32 retvalue = 0;
+
+	offset &= 0x3f;
+	newoffset = offset;
+
+	tmplong = rtl_get_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, MASKDWORD);
+
+	if (rfpath == RF90_PATH_A)
+		tmplong2 = tmplong;
+	else
+		tmplong2 = rtl_get_bbreg(hw, pphyreg->rfhssi_para2, MASKDWORD);
+
+	tmplong2 = (tmplong2 & (~BLSSI_READADDRESS)) | (newoffset << 23) |
+			BLSSI_READEDGE;
+
+	rtl_set_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, MASKDWORD,
+		      tmplong & (~BLSSI_READEDGE));
+
+	mdelay(1);
+
+	rtl_set_bbreg(hw, pphyreg->rfhssi_para2, MASKDWORD, tmplong2);
+	mdelay(1);
+
+	rtl_set_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, MASKDWORD, tmplong |
+		      BLSSI_READEDGE);
+	mdelay(1);
+
+	if (rfpath == RF90_PATH_A)
+		rfpi_enable = (u8)rtl_get_bbreg(hw, RFPGA0_XA_HSSIPARAMETER1,
+						BIT(8));
+	else if (rfpath == RF90_PATH_B)
+		rfpi_enable = (u8)rtl_get_bbreg(hw, RFPGA0_XB_HSSIPARAMETER1,
+						BIT(8));
+
+	if (rfpi_enable)
+		retvalue = rtl_get_bbreg(hw, pphyreg->rflssi_readbackpi,
+					 BLSSI_READBACK_DATA);
+	else
+		retvalue = rtl_get_bbreg(hw, pphyreg->rflssi_readback,
+					 BLSSI_READBACK_DATA);
+
+	retvalue = rtl_get_bbreg(hw, pphyreg->rflssi_readback,
+				 BLSSI_READBACK_DATA);
+
+	RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("RFR-%d Addr[0x%x]=0x%x\n",
+		 rfpath, pphyreg->rflssi_readback, retvalue));
+
+	return retvalue;
+
+}
+
+static void _rtl92s_phy_rf_serial_write(struct ieee80211_hw *hw,
+					enum radio_path rfpath, u32 offset,
+					u32 data)
+{
+	struct rtl_priv *rtlpriv = rtl_priv(hw);
+	struct rtl_phy *rtlphy = &(rtlpriv->phy);
+	struct bb_reg_def *pphyreg = &rtlphy->phyreg_def[rfpath];
+	u32 data_and_addr = 0;
+	u32 newoffset;
+
+	offset &= 0x3f;
+	newoffset = offset;
+
+	data_and_addr = ((newoffset << 20) | (data & 0x000fffff)) & 0x0fffffff;
+	rtl_set_bbreg(hw, pphyreg->rf3wire_offset, MASKDWORD, data_and_addr);
+
+	RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("RFW-%d Addr[0x%x]=0x%x\n",
+		 rfpath, pphyreg->rf3wire_offset, data_and_addr));
+}
+
+
+u32 rtl92s_phy_query_rf_reg(struct ieee80211_hw *hw, enum radio_path rfpath,
+			    u32 regaddr, u32 bitmask)
+{
+	struct rtl_priv *rtlpriv = rtl_priv(hw);
+	u32 original_value, readback_value, bitshift;
+	unsigned long flags;
+
+	RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), rfpath(%#x), "
+		 "bitmask(%#x)\n", regaddr, rfpath, bitmask));
+
+	spin_lock_irqsave(&rtlpriv->locks.rf_lock, flags);
+
+	original_value = _rtl92s_phy_rf_serial_read(hw, rfpath, regaddr);
+
+	bitshift = _rtl92s_phy_calculate_bit_shift(bitmask);
+	readback_value = (original_value & bitmask) >> bitshift;
+
+	spin_unlock_irqrestore(&rtlpriv->locks.rf_lock, flags);
+
+	RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), rfpath(%#x), "
+		 "bitmask(%#x), original_value(%#x)\n", regaddr, rfpath,
+		 bitmask, original_value));
+
+	return readback_value;
+}
+
+void rtl92s_phy_set_rf_reg(struct ieee80211_hw *hw, enum radio_path rfpath,
+			   u32 regaddr, u32 bitmask, u32 data)
+{
+	struct rtl_priv *rtlpriv = rtl_priv(hw);
+	struct rtl_phy *rtlphy = &(rtlpriv->phy);
+	u32 original_value, bitshift;
+	unsigned long flags;
+
+	if (!((rtlphy->rf_pathmap >> rfpath) & 0x1))
+		return;
+
+	RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), bitmask(%#x),"
+		 " data(%#x), rfpath(%#x)\n", regaddr, bitmask, data, rfpath));
+
+	spin_lock_irqsave(&rtlpriv->locks.rf_lock, flags);
+
+	if (bitmask != RFREG_OFFSET_MASK) {
+		original_value = _rtl92s_phy_rf_serial_read(hw, rfpath,
+							    regaddr);
+		bitshift = _rtl92s_phy_calculate_bit_shift(bitmask);
+		data = ((original_value & (~bitmask)) | (data << bitshift));
+	}
+
+	_rtl92s_phy_rf_serial_write(hw, rfpath, regaddr, data);
+
+	spin_unlock_irqrestore(&rtlpriv->locks.rf_lock, flags);
+
+	RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), bitmask(%#x), "
+		 "data(%#x), rfpath(%#x)\n", regaddr, bitmask, data, rfpath));
+
+}
+
+void rtl92s_phy_scan_operation_backup(struct ieee80211_hw *hw,
+				      u8 operation)
+{
+	struct rtl_priv *rtlpriv = rtl_priv(hw);
+	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+
+	if (!is_hal_stop(rtlhal)) {
+		switch (operation) {
+		case SCAN_OPT_BACKUP:
+			rtl92s_phy_set_fw_cmd(hw, FW_CMD_PAUSE_DM_BY_SCAN);
+			break;
+		case SCAN_OPT_RESTORE:
+			rtl92s_phy_set_fw_cmd(hw, FW_CMD_RESUME_DM_BY_SCAN);
+			break;
+		default:
+			RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
+				 ("Unknown operation.\n"));
+			break;
+		}
+	}
+}
+
+void rtl92s_phy_set_bw_mode(struct ieee80211_hw *hw,
+			    enum nl80211_channel_type ch_type)
+{
+	struct rtl_priv *rtlpriv = rtl_priv(hw);
+	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+	struct rtl_phy *rtlphy = &(rtlpriv->phy);
+	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+	u8 reg_bw_opmode;
+	u8 reg_prsr_rsc;
+
+	RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, ("Switch to %s bandwidth\n",
+		  rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20 ?
+		  "20MHz" : "40MHz"));
+
+	if (rtlphy->set_bwmode_inprogress)
+		return;
+	if (is_hal_stop(rtlhal))
+		return;
+
+	rtlphy->set_bwmode_inprogress = true;
+
+	reg_bw_opmode = rtl_read_byte(rtlpriv, BW_OPMODE);
+	reg_prsr_rsc = rtl_read_byte(rtlpriv, RRSR + 2);
+
+	switch (rtlphy->current_chan_bw) {
+	case HT_CHANNEL_WIDTH_20:
+		reg_bw_opmode |= BW_OPMODE_20MHZ;
+		rtl_write_byte(rtlpriv, BW_OPMODE, reg_bw_opmode);
+		break;
+	case HT_CHANNEL_WIDTH_20_40:
+		reg_bw_opmode &= ~BW_OPMODE_20MHZ;
+		rtl_write_byte(rtlpriv, BW_OPMODE, reg_bw_opmode);
+		break;
+	default:
+		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
+			 ("unknown bandwidth: %#X\n",
+			 rtlphy->current_chan_bw));
+		break;
+	}
+
+	switch (rtlphy->current_chan_bw) {
+	case HT_CHANNEL_WIDTH_20:
+		rtl_set_bbreg(hw, RFPGA0_RFMOD, BRFMOD, 0x0);
+		rtl_set_bbreg(hw, RFPGA1_RFMOD, BRFMOD, 0x0);
+
+		if (rtlhal->version >= VERSION_8192S_BCUT)
+			rtl_write_byte(rtlpriv, RFPGA0_ANALOGPARAMETER2, 0x58);
+		break;
+	case HT_CHANNEL_WIDTH_20_40:
+		rtl_set_bbreg(hw, RFPGA0_RFMOD, BRFMOD, 0x1);
+		rtl_set_bbreg(hw, RFPGA1_RFMOD, BRFMOD, 0x1);
+
+		rtl_set_bbreg(hw, RCCK0_SYSTEM, BCCK_SIDEBAND,
+				(mac->cur_40_prime_sc >> 1));
+		rtl_set_bbreg(hw, ROFDM1_LSTF, 0xC00, mac->cur_40_prime_sc);
+
+		if (rtlhal->version >= VERSION_8192S_BCUT)
+			rtl_write_byte(rtlpriv, RFPGA0_ANALOGPARAMETER2, 0x18);
+		break;
+	default:
+		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
+			 ("unknown bandwidth: %#X\n", rtlphy->current_chan_bw));
+		break;
+	}
+
+	rtl92s_phy_rf6052_set_bandwidth(hw, rtlphy->current_chan_bw);
+	rtlphy->set_bwmode_inprogress = false;
+	RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, ("<==\n"));
+}
+
+static bool _rtl92s_phy_set_sw_chnl_cmdarray(struct swchnlcmd *cmdtable,
+		u32 cmdtableidx, u32 cmdtablesz, enum swchnlcmd_id cmdid,
+		u32 para1, u32 para2, u32 msdelay)
+{
+	struct swchnlcmd *pcmd;
+
+	if (cmdtable == NULL) {
+		RT_ASSERT(false, ("cmdtable cannot be NULL.\n"));
+		return false;
+	}
+
+	if (cmdtableidx >= cmdtablesz)
+		return false;
+
+	pcmd = cmdtable + cmdtableidx;
+	pcmd->cmdid = cmdid;
+	pcmd->para1 = para1;
+	pcmd->para2 = para2;
+	pcmd->msdelay = msdelay;
+
+	return true;
+}
+
+static bool _rtl92s_phy_sw_chnl_step_by_step(struct ieee80211_hw *hw,
+	     u8 channel, u8 *stage, u8 *step, u32 *delay)
+{
+	struct rtl_priv *rtlpriv = rtl_priv(hw);
+	struct rtl_phy *rtlphy = &(rtlpriv->phy);
+	struct swchnlcmd precommoncmd[MAX_PRECMD_CNT];
+	u32 precommoncmdcnt;
+	struct swchnlcmd postcommoncmd[MAX_POSTCMD_CNT];
+	u32 postcommoncmdcnt;
+	struct swchnlcmd rfdependcmd[MAX_RFDEPENDCMD_CNT];
+	u32 rfdependcmdcnt;
+	struct swchnlcmd *currentcmd = NULL;
+	u8 rfpath;
+	u8 num_total_rfpath = rtlphy->num_total_rfpath;
+
+	precommoncmdcnt = 0;
+	_rtl92s_phy_set_sw_chnl_cmdarray(precommoncmd, precommoncmdcnt++,
+			MAX_PRECMD_CNT, CMDID_SET_TXPOWEROWER_LEVEL, 0, 0, 0);
+	_rtl92s_phy_set_sw_chnl_cmdarray(precommoncmd, precommoncmdcnt++,
+			MAX_PRECMD_CNT, CMDID_END, 0, 0, 0);
+
+	postcommoncmdcnt = 0;
+
+	_rtl92s_phy_set_sw_chnl_cmdarray(postcommoncmd, postcommoncmdcnt++,
+			MAX_POSTCMD_CNT, CMDID_END, 0, 0, 0);
+
+	rfdependcmdcnt = 0;
+
+	RT_ASSERT((channel >= 1 && channel <= 14),
+		  ("illegal channel for Zebra: %d\n", channel));
+
+	_rtl92s_phy_set_sw_chnl_cmdarray(rfdependcmd, rfdependcmdcnt++,
+					 MAX_RFDEPENDCMD_CNT, CMDID_RF_WRITEREG,
+					 RF_CHNLBW, channel, 10);
+
+	_rtl92s_phy_set_sw_chnl_cmdarray(rfdependcmd, rfdependcmdcnt++,
+			MAX_RFDEPENDCMD_CNT, CMDID_END, 0, 0, 0);
+
+	do {
+		switch (*stage) {
+		case 0:
+			currentcmd = &precommoncmd[*step];
+			break;
+		case 1:
+			currentcmd = &rfdependcmd[*step];
+			break;
+		case 2:
+			currentcmd = &postcommoncmd[*step];
+			break;
+		}
+
+		if (currentcmd->cmdid == CMDID_END) {
+			if ((*stage) == 2) {
+				return true;
+			} else {
+				(*stage)++;
+				(*step) = 0;
+				continue;
+			}
+		}
+
+		switch (currentcmd->cmdid) {
+		case CMDID_SET_TXPOWEROWER_LEVEL:
+			rtl92s_phy_set_txpower(hw, channel);
+			break;
+		case CMDID_WRITEPORT_ULONG:
+			rtl_write_dword(rtlpriv, currentcmd->para1,
+					currentcmd->para2);
+			break;
+		case CMDID_WRITEPORT_USHORT:
+			rtl_write_word(rtlpriv, currentcmd->para1,
+				       (u16)currentcmd->para2);
+			break;
+		case CMDID_WRITEPORT_UCHAR:
+			rtl_write_byte(rtlpriv, currentcmd->para1,
+				       (u8)currentcmd->para2);
+			break;
+		case CMDID_RF_WRITEREG:
+			for (rfpath = 0; rfpath < num_total_rfpath; rfpath++) {
+				rtlphy->rfreg_chnlval[rfpath] =
+					 ((rtlphy->rfreg_chnlval[rfpath] &
+					 0xfffffc00) | currentcmd->para2);
+				rtl_set_rfreg(hw, (enum radio_path)rfpath,
+					      currentcmd->para1,
+					      RFREG_OFFSET_MASK,
+					      rtlphy->rfreg_chnlval[rfpath]);
+			}
+			break;
+		default:
+			RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
+				 ("switch case not process\n"));
+			break;
+		}
+
+		break;
+	} while (true);
+
+	(*delay) = currentcmd->msdelay;
+	(*step)++;
+	return false;
+}
+
+u8 rtl92s_phy_sw_chnl(struct ieee80211_hw *hw)
+{
+	struct rtl_priv *rtlpriv = rtl_priv(hw);
+	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+	struct rtl_phy *rtlphy = &(rtlpriv->phy);
+	u32 delay;
+	bool ret;
+
+	RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE,
+		 ("switch to channel%d\n",
+		 rtlphy->current_channel));
+
+	if (rtlphy->sw_chnl_inprogress)
+		return 0;
+
+	if (rtlphy->set_bwmode_inprogress)
+		return 0;
+
+	if (is_hal_stop(rtlhal))
+		return 0;
+
+	rtlphy->sw_chnl_inprogress = true;
+	rtlphy->sw_chnl_stage = 0;
+	rtlphy->sw_chnl_step = 0;
+
+	do {
+		if (!rtlphy->sw_chnl_inprogress)
+			break;
+
+		ret = _rtl92s_phy_sw_chnl_step_by_step(hw,
+				 rtlphy->current_channel,
+				 &rtlphy->sw_chnl_stage,
+				 &rtlphy->sw_chnl_step, &delay);
+		if (!ret) {
+			if (delay > 0)
+				mdelay(delay);
+			else
+				continue;
+		} else {
+			rtlphy->sw_chnl_inprogress = false;
+		}
+		break;
+	} while (true);
+
+	rtlphy->sw_chnl_inprogress = false;
+
+	RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, ("<==\n"));
+
+	return 1;
+}
+
+static void _rtl92se_phy_set_rf_sleep(struct ieee80211_hw *hw)
+{
+	struct rtl_priv *rtlpriv = rtl_priv(hw);
+	u8 u1btmp;
+
+	u1btmp = rtl_read_byte(rtlpriv, LDOV12D_CTRL);
+	u1btmp |= BIT(0);
+
+	rtl_write_byte(rtlpriv, LDOV12D_CTRL, u1btmp);
+	rtl_write_byte(rtlpriv, SPS1_CTRL, 0x0);
+	rtl_write_byte(rtlpriv, TXPAUSE, 0xFF);
+	rtl_write_word(rtlpriv, CMDR, 0x57FC);
+	udelay(100);
+
+	rtl_write_word(rtlpriv, CMDR, 0x77FC);
+	rtl_write_byte(rtlpriv, PHY_CCA, 0x0);
+	udelay(10);
+
+	rtl_write_word(rtlpriv, CMDR, 0x37FC);
+	udelay(10);
+
+	rtl_write_word(rtlpriv, CMDR, 0x77FC);
+	udelay(10);
+
+	rtl_write_word(rtlpriv, CMDR, 0x57FC);
+
+	/* we should chnge GPIO to input mode
+	 * this will drop away current about 25mA*/
+	rtl8192se_gpiobit3_cfg_inputmode(hw);
+}
+
+bool rtl92s_phy_set_rf_power_state(struct ieee80211_hw *hw,
+				   enum rf_pwrstate rfpwr_state)
+{
+	struct rtl_priv *rtlpriv = rtl_priv(hw);
+	struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
+	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+	struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
+	bool bresult = true;
+	u8 i, queue_id;
+	struct rtl8192_tx_ring *ring = NULL;
+
+	if (rfpwr_state == ppsc->rfpwr_state)
+		return false;
+
+	ppsc->set_rfpowerstate_inprogress = true;
+
+	switch (rfpwr_state) {
+	case ERFON:{
+			if ((ppsc->rfpwr_state == ERFOFF) &&
+			    RT_IN_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC)) {
+
+				bool rtstatus;
+				u32 InitializeCount = 0;
+				do {
+					InitializeCount++;
+					RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
+						 ("IPS Set eRf nic enable\n"));
+					rtstatus = rtl_ps_enable_nic(hw);
+				} while ((rtstatus != true) &&
+					 (InitializeCount < 10));
+
+				RT_CLEAR_PS_LEVEL(ppsc,
+						  RT_RF_OFF_LEVL_HALT_NIC);
+			} else {
+				RT_TRACE(rtlpriv, COMP_POWER, DBG_DMESG,
+					 ("awake, sleeped:%d ms "
+					"state_inap:%x\n",
+					jiffies_to_msecs(jiffies -
+					ppsc->last_sleep_jiffies),
+					rtlpriv->psc.state_inap));
+				ppsc->last_awake_jiffies = jiffies;
+				rtl_write_word(rtlpriv, CMDR, 0x37FC);
+				rtl_write_byte(rtlpriv, TXPAUSE, 0x00);
+				rtl_write_byte(rtlpriv, PHY_CCA, 0x3);
+			}
+
+			if (mac->link_state == MAC80211_LINKED)
+				rtlpriv->cfg->ops->led_control(hw,
+							 LED_CTL_LINK);
+			else
+				rtlpriv->cfg->ops->led_control(hw,
+							 LED_CTL_NO_LINK);
+			break;
+		}
+	case ERFOFF:{
+			if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_HALT_NIC) {
+				RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
+					 ("IPS Set eRf nic disable\n"));
+				rtl_ps_disable_nic(hw);
+				RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC);
+			} else {
+				if (ppsc->rfoff_reason == RF_CHANGE_BY_IPS)
+					rtlpriv->cfg->ops->led_control(hw,
+							 LED_CTL_NO_LINK);
+				else
+					rtlpriv->cfg->ops->led_control(hw,
+							 LED_CTL_POWER_OFF);
+			}
+			break;
+		}
+	case ERFSLEEP:
+			if (ppsc->rfpwr_state == ERFOFF)
+				break;
+
+			for (queue_id = 0, i = 0;
+			     queue_id < RTL_PCI_MAX_TX_QUEUE_COUNT;) {
+				ring = &pcipriv->dev.tx_ring[queue_id];
+				if (skb_queue_len(&ring->queue) == 0 ||
+					queue_id == BEACON_QUEUE) {
+					queue_id++;
+					continue;
+				} else {
+					RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
+						 ("eRf Off/Sleep: "
+						 "%d times TcbBusyQueue[%d] = "
+						 "%d before doze!\n",
+						 (i + 1), queue_id,
+						 skb_queue_len(&ring->queue)));
+
+					udelay(10);
+					i++;
+				}
+
+				if (i >= MAX_DOZE_WAITING_TIMES_9x) {
+					RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
+						 ("\nERFOFF: %d times"
+						 "TcbBusyQueue[%d] = %d !\n",
+						 MAX_DOZE_WAITING_TIMES_9x,
+						 queue_id,
+						 skb_queue_len(&ring->queue)));
+					break;
+				}
+			}
+
+			RT_TRACE(rtlpriv, COMP_POWER, DBG_DMESG,
+				 ("Set ERFSLEEP awaked:%d ms\n",
+				 jiffies_to_msecs(jiffies -
+				 ppsc->last_awake_jiffies)));
+
+			RT_TRACE(rtlpriv, COMP_POWER, DBG_DMESG,
+				 ("sleep awaked:%d ms "
+				"state_inap:%x\n", jiffies_to_msecs(jiffies -
+				ppsc->last_awake_jiffies),
+				rtlpriv->psc.state_inap));
+			ppsc->last_sleep_jiffies = jiffies;
+			_rtl92se_phy_set_rf_sleep(hw);
+	    break;
+	default:
+		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
+			 ("switch case not process\n"));
+		bresult = false;
+		break;
+	}
+
+	if (bresult)
+		ppsc->rfpwr_state = rfpwr_state;
+
+	ppsc->set_rfpowerstate_inprogress = false;
+
+	return bresult;
+}
+
+static bool _rtl92s_phy_config_rfpa_bias_current(struct ieee80211_hw *hw,
+						 enum radio_path rfpath)
+{
+	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+	bool rtstatus = true;
+	u32 tmpval = 0;
+
+	/* If inferiority IC, we have to increase the PA bias current */
+	if (rtlhal->ic_class != IC_INFERIORITY_A) {
+		tmpval = rtl92s_phy_query_rf_reg(hw, rfpath, RF_IPA, 0xf);
+		rtl92s_phy_set_rf_reg(hw, rfpath, RF_IPA, 0xf, tmpval + 1);
+	}
+
+	return rtstatus;
+}
+
+static void _rtl92s_store_pwrindex_diffrate_offset(struct ieee80211_hw *hw,
+		u32 reg_addr, u32 bitmask, u32 data)
+{
+	struct rtl_priv *rtlpriv = rtl_priv(hw);
+	struct rtl_phy *rtlphy = &(rtlpriv->phy);
+
+	if (reg_addr == RTXAGC_RATE18_06)
+		rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][0] =
+									 data;
+	if (reg_addr == RTXAGC_RATE54_24)
+		rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][1] =
+									 data;
+	if (reg_addr == RTXAGC_CCK_MCS32)
+		rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][6] =
+									 data;
+	if (reg_addr == RTXAGC_MCS03_MCS00)
+		rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][2] =
+									 data;
+	if (reg_addr == RTXAGC_MCS07_MCS04)
+		rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][3] =
+									 data;
+	if (reg_addr == RTXAGC_MCS11_MCS08)
+		rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][4] =
+									 data;
+	if (reg_addr == RTXAGC_MCS15_MCS12) {
+		rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][5] =
+									 data;
+		rtlphy->pwrgroup_cnt++;
+	}
+}
+
+static void _rtl92s_phy_init_register_definition(struct ieee80211_hw *hw)
+{
+	struct rtl_priv *rtlpriv = rtl_priv(hw);
+	struct rtl_phy *rtlphy = &(rtlpriv->phy);
+
+	/*RF Interface Sowrtware Control */
+	rtlphy->phyreg_def[RF90_PATH_A].rfintfs = RFPGA0_XAB_RFINTERFACESW;
+	rtlphy->phyreg_def[RF90_PATH_B].rfintfs = RFPGA0_XAB_RFINTERFACESW;
+	rtlphy->phyreg_def[RF90_PATH_C].rfintfs = RFPGA0_XCD_RFINTERFACESW;
+	rtlphy->phyreg_def[RF90_PATH_D].rfintfs = RFPGA0_XCD_RFINTERFACESW;
+
+	/* RF Interface Readback Value */
+	rtlphy->phyreg_def[RF90_PATH_A].rfintfi = RFPGA0_XAB_RFINTERFACERB;
+	rtlphy->phyreg_def[RF90_PATH_B].rfintfi = RFPGA0_XAB_RFINTERFACERB;
+	rtlphy->phyreg_def[RF90_PATH_C].rfintfi = RFPGA0_XCD_RFINTERFACERB;
+	rtlphy->phyreg_def[RF90_PATH_D].rfintfi = RFPGA0_XCD_RFINTERFACERB;
+
+	/* RF Interface Output (and Enable) */
+	rtlphy->phyreg_def[RF90_PATH_A].rfintfo = RFPGA0_XA_RFINTERFACEOE;
+	rtlphy->phyreg_def[RF90_PATH_B].rfintfo = RFPGA0_XB_RFINTERFACEOE;
+	rtlphy->phyreg_def[RF90_PATH_C].rfintfo = RFPGA0_XC_RFINTERFACEOE;
+	rtlphy->phyreg_def[RF90_PATH_D].rfintfo = RFPGA0_XD_RFINTERFACEOE;
+
+	/* RF Interface (Output and)  Enable */
+	rtlphy->phyreg_def[RF90_PATH_A].rfintfe = RFPGA0_XA_RFINTERFACEOE;
+	rtlphy->phyreg_def[RF90_PATH_B].rfintfe = RFPGA0_XB_RFINTERFACEOE;
+	rtlphy->phyreg_def[RF90_PATH_C].rfintfe = RFPGA0_XC_RFINTERFACEOE;
+	rtlphy->phyreg_def[RF90_PATH_D].rfintfe = RFPGA0_XD_RFINTERFACEOE;
+
+	/* Addr of LSSI. Wirte RF register by driver */
+	rtlphy->phyreg_def[RF90_PATH_A].rf3wire_offset =
+						 RFPGA0_XA_LSSIPARAMETER;
+	rtlphy->phyreg_def[RF90_PATH_B].rf3wire_offset =
+						 RFPGA0_XB_LSSIPARAMETER;
+	rtlphy->phyreg_def[RF90_PATH_C].rf3wire_offset =
+						 RFPGA0_XC_LSSIPARAMETER;
+	rtlphy->phyreg_def[RF90_PATH_D].rf3wire_offset =
+						 RFPGA0_XD_LSSIPARAMETER;
+
+	/* RF parameter */
+	rtlphy->phyreg_def[RF90_PATH_A].rflssi_select = RFPGA0_XAB_RFPARAMETER;
+	rtlphy->phyreg_def[RF90_PATH_B].rflssi_select = RFPGA0_XAB_RFPARAMETER;
+	rtlphy->phyreg_def[RF90_PATH_C].rflssi_select = RFPGA0_XCD_RFPARAMETER;
+	rtlphy->phyreg_def[RF90_PATH_D].rflssi_select = RFPGA0_XCD_RFPARAMETER;
+
+	/* Tx AGC Gain Stage (same for all path. Should we remove this?) */
+	rtlphy->phyreg_def[RF90_PATH_A].rftxgain_stage = RFPGA0_TXGAINSTAGE;
+	rtlphy->phyreg_def[RF90_PATH_B].rftxgain_stage = RFPGA0_TXGAINSTAGE;
+	rtlphy->phyreg_def[RF90_PATH_C].rftxgain_stage = RFPGA0_TXGAINSTAGE;
+	rtlphy->phyreg_def[RF90_PATH_D].rftxgain_stage = RFPGA0_TXGAINSTAGE;
+
+	/* Tranceiver A~D HSSI Parameter-1 */
+	rtlphy->phyreg_def[RF90_PATH_A].rfhssi_para1 = RFPGA0_XA_HSSIPARAMETER1;
+	rtlphy->phyreg_def[RF90_PATH_B].rfhssi_para1 = RFPGA0_XB_HSSIPARAMETER1;
+	rtlphy->phyreg_def[RF90_PATH_C].rfhssi_para1 = RFPGA0_XC_HSSIPARAMETER1;
+	rtlphy->phyreg_def[RF90_PATH_D].rfhssi_para1 = RFPGA0_XD_HSSIPARAMETER1;
+
+	/* Tranceiver A~D HSSI Parameter-2 */
+	rtlphy->phyreg_def[RF90_PATH_A].rfhssi_para2 = RFPGA0_XA_HSSIPARAMETER2;
+	rtlphy->phyreg_def[RF90_PATH_B].rfhssi_para2 = RFPGA0_XB_HSSIPARAMETER2;
+	rtlphy->phyreg_def[RF90_PATH_C].rfhssi_para2 = RFPGA0_XC_HSSIPARAMETER2;
+	rtlphy->phyreg_def[RF90_PATH_D].rfhssi_para2 = RFPGA0_XD_HSSIPARAMETER2;
+
+	/* RF switch Control */
+	rtlphy->phyreg_def[RF90_PATH_A].rfswitch_control =
+						 RFPGA0_XAB_SWITCHCONTROL;
+	rtlphy->phyreg_def[RF90_PATH_B].rfswitch_control =
+						 RFPGA0_XAB_SWITCHCONTROL;
+	rtlphy->phyreg_def[RF90_PATH_C].rfswitch_control =
+						 RFPGA0_XCD_SWITCHCONTROL;
+	rtlphy->phyreg_def[RF90_PATH_D].rfswitch_control =
+						 RFPGA0_XCD_SWITCHCONTROL;
+
+	/* AGC control 1  */
+	rtlphy->phyreg_def[RF90_PATH_A].rfagc_control1 = ROFDM0_XAAGCCORE1;
+	rtlphy->phyreg_def[RF90_PATH_B].rfagc_control1 = ROFDM0_XBAGCCORE1;
+	rtlphy->phyreg_def[RF90_PATH_C].rfagc_control1 = ROFDM0_XCAGCCORE1;
+	rtlphy->phyreg_def[RF90_PATH_D].rfagc_control1 = ROFDM0_XDAGCCORE1;
+
+	/* AGC control 2  */
+	rtlphy->phyreg_def[RF90_PATH_A].rfagc_control2 = ROFDM0_XAAGCCORE2;
+	rtlphy->phyreg_def[RF90_PATH_B].rfagc_control2 = ROFDM0_XBAGCCORE2;
+	rtlphy->phyreg_def[RF90_PATH_C].rfagc_control2 = ROFDM0_XCAGCCORE2;
+	rtlphy->phyreg_def[RF90_PATH_D].rfagc_control2 = ROFDM0_XDAGCCORE2;
+
+	/* RX AFE control 1  */
+	rtlphy->phyreg_def[RF90_PATH_A].rfrxiq_imbalance =
+						 ROFDM0_XARXIQIMBALANCE;
+	rtlphy->phyreg_def[RF90_PATH_B].rfrxiq_imbalance =
+						 ROFDM0_XBRXIQIMBALANCE;
+	rtlphy->phyreg_def[RF90_PATH_C].rfrxiq_imbalance =
+						 ROFDM0_XCRXIQIMBALANCE;
+	rtlphy->phyreg_def[RF90_PATH_D].rfrxiq_imbalance =
+						 ROFDM0_XDRXIQIMBALANCE;
+
+	/* RX AFE control 1   */
+	rtlphy->phyreg_def[RF90_PATH_A].rfrx_afe = ROFDM0_XARXAFE;
+	rtlphy->phyreg_def[RF90_PATH_B].rfrx_afe = ROFDM0_XBRXAFE;
+	rtlphy->phyreg_def[RF90_PATH_C].rfrx_afe = ROFDM0_XCRXAFE;
+	rtlphy->phyreg_def[RF90_PATH_D].rfrx_afe = ROFDM0_XDRXAFE;
+
+	/* Tx AFE control 1  */
+	rtlphy->phyreg_def[RF90_PATH_A].rftxiq_imbalance =
+						 ROFDM0_XATXIQIMBALANCE;
+	rtlphy->phyreg_def[RF90_PATH_B].rftxiq_imbalance =
+						 ROFDM0_XBTXIQIMBALANCE;
+	rtlphy->phyreg_def[RF90_PATH_C].rftxiq_imbalance =
+						 ROFDM0_XCTXIQIMBALANCE;
+	rtlphy->phyreg_def[RF90_PATH_D].rftxiq_imbalance =
+						 ROFDM0_XDTXIQIMBALANCE;
+
+	/* Tx AFE control 2  */
+	rtlphy->phyreg_def[RF90_PATH_A].rftx_afe = ROFDM0_XATXAFE;
+	rtlphy->phyreg_def[RF90_PATH_B].rftx_afe = ROFDM0_XBTXAFE;
+	rtlphy->phyreg_def[RF90_PATH_C].rftx_afe = ROFDM0_XCTXAFE;
+	rtlphy->phyreg_def[RF90_PATH_D].rftx_afe = ROFDM0_XDTXAFE;
+
+	/* Tranceiver LSSI Readback */
+	rtlphy->phyreg_def[RF90_PATH_A].rflssi_readback =
+			 RFPGA0_XA_LSSIREADBACK;
+	rtlphy->phyreg_def[RF90_PATH_B].rflssi_readback =
+			 RFPGA0_XB_LSSIREADBACK;
+	rtlphy->phyreg_def[RF90_PATH_C].rflssi_readback =
+			 RFPGA0_XC_LSSIREADBACK;
+	rtlphy->phyreg_def[RF90_PATH_D].rflssi_readback =
+			 RFPGA0_XD_LSSIREADBACK;
+
+	/* Tranceiver LSSI Readback PI mode  */
+	rtlphy->phyreg_def[RF90_PATH_A].rflssi_readbackpi =
+			 TRANSCEIVERA_HSPI_READBACK;
+	rtlphy->phyreg_def[RF90_PATH_B].rflssi_readbackpi =
+			 TRANSCEIVERB_HSPI_READBACK;
+}
+
+
+static bool _rtl92s_phy_config_bb(struct ieee80211_hw *hw, u8 configtype)
+{
+	int i;
+	u32 *phy_reg_table;
+	u32 *agc_table;
+	u16 phy_reg_len, agc_len;
+
+	agc_len = AGCTAB_ARRAYLENGTH;
+	agc_table = rtl8192seagctab_array;
+	/* Default RF_type: 2T2R */
+	phy_reg_len = PHY_REG_2T2RARRAYLENGTH;
+	phy_reg_table = rtl8192sephy_reg_2t2rarray;
+
+	if (configtype == BASEBAND_CONFIG_PHY_REG) {
+		for (i = 0; i < phy_reg_len; i = i + 2) {
+			if (phy_reg_table[i] == 0xfe)
+				mdelay(50);
+			else if (phy_reg_table[i] == 0xfd)
+				mdelay(5);
+			else if (phy_reg_table[i] == 0xfc)
+				mdelay(1);
+			else if (phy_reg_table[i] == 0xfb)
+				udelay(50);
+			else if (phy_reg_table[i] == 0xfa)
+				udelay(5);
+			else if (phy_reg_table[i] == 0xf9)
+				udelay(1);
+
+			/* Add delay for ECS T20 & LG malow platform, */
+			udelay(1);
+
+			rtl92s_phy_set_bb_reg(hw, phy_reg_table[i], MASKDWORD,
+					phy_reg_table[i + 1]);
+		}
+	} else if (configtype == BASEBAND_CONFIG_AGC_TAB) {
+		for (i = 0; i < agc_len; i = i + 2) {
+			rtl92s_phy_set_bb_reg(hw, agc_table[i], MASKDWORD,
+					agc_table[i + 1]);
+
+			/* Add delay for ECS T20 & LG malow platform */
+			udelay(1);
+		}
+	}
+
+	return true;
+}
+
+static bool _rtl92s_phy_set_bb_to_diff_rf(struct ieee80211_hw *hw,
+					  u8 configtype)
+{
+	struct rtl_priv *rtlpriv = rtl_priv(hw);
+	struct rtl_phy *rtlphy = &(rtlpriv->phy);
+	u32 *phy_regarray2xtxr_table;
+	u16 phy_regarray2xtxr_len;
+	int i;
+
+	if (rtlphy->rf_type == RF_1T1R) {
+		phy_regarray2xtxr_table = rtl8192sephy_changeto_1t1rarray;
+		phy_regarray2xtxr_len = PHY_CHANGETO_1T1RARRAYLENGTH;
+	} else if (rtlphy->rf_type == RF_1T2R) {
+		phy_regarray2xtxr_table = rtl8192sephy_changeto_1t2rarray;
+		phy_regarray2xtxr_len = PHY_CHANGETO_1T2RARRAYLENGTH;
+	} else {
+		return false;
+	}
+
+	if (configtype == BASEBAND_CONFIG_PHY_REG) {
+		for (i = 0; i < phy_regarray2xtxr_len; i = i + 3) {
+			if (phy_regarray2xtxr_table[i] == 0xfe)
+				mdelay(50);
+			else if (phy_regarray2xtxr_table[i] == 0xfd)
+				mdelay(5);
+			else if (phy_regarray2xtxr_table[i] == 0xfc)
+				mdelay(1);
+			else if (phy_regarray2xtxr_table[i] == 0xfb)
+				udelay(50);
+			else if (phy_regarray2xtxr_table[i] == 0xfa)
+				udelay(5);
+			else if (phy_regarray2xtxr_table[i] == 0xf9)
+				udelay(1);
+
+			rtl92s_phy_set_bb_reg(hw, phy_regarray2xtxr_table[i],
+				phy_regarray2xtxr_table[i + 1],
+				phy_regarray2xtxr_table[i + 2]);
+		}
+	}
+
+	return true;
+}
+
+static bool _rtl92s_phy_config_bb_with_pg(struct ieee80211_hw *hw,
+					  u8 configtype)
+{
+	int i;
+	u32 *phy_table_pg;
+	u16 phy_pg_len;
+
+	phy_pg_len = PHY_REG_ARRAY_PGLENGTH;
+	phy_table_pg = rtl8192sephy_reg_array_pg;
+
+	if (configtype == BASEBAND_CONFIG_PHY_REG) {
+		for (i = 0; i < phy_pg_len; i = i + 3) {
+			if (phy_table_pg[i] == 0xfe)
+				mdelay(50);
+			else if (phy_table_pg[i] == 0xfd)
+				mdelay(5);
+			else if (phy_table_pg[i] == 0xfc)
+				mdelay(1);
+			else if (phy_table_pg[i] == 0xfb)
+				udelay(50);
+			else if (phy_table_pg[i] == 0xfa)
+				udelay(5);
+			else if (phy_table_pg[i] == 0xf9)
+				udelay(1);
+
+			_rtl92s_store_pwrindex_diffrate_offset(hw,
+					phy_table_pg[i],
+					phy_table_pg[i + 1],
+					phy_table_pg[i + 2]);
+			rtl92s_phy_set_bb_reg(hw, phy_table_pg[i],
+					phy_table_pg[i + 1],
+					phy_table_pg[i + 2]);
+		}
+	}
+
+	return true;
+}
+
+static bool _rtl92s_phy_bb_config_parafile(struct ieee80211_hw *hw)
+{
+	struct rtl_priv *rtlpriv = rtl_priv(hw);
+	struct rtl_phy *rtlphy = &(rtlpriv->phy);
+	struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
+	bool rtstatus = true;
+
+	/* 1. Read PHY_REG.TXT BB INIT!! */
+	/* We will separate as 1T1R/1T2R/1T2R_GREEN/2T2R */
+	if (rtlphy->rf_type == RF_1T2R || rtlphy->rf_type == RF_2T2R ||
+	    rtlphy->rf_type == RF_1T1R || rtlphy->rf_type == RF_2T2R_GREEN) {
+		rtstatus = _rtl92s_phy_config_bb(hw, BASEBAND_CONFIG_PHY_REG);
+
+		if (rtlphy->rf_type != RF_2T2R &&
+		    rtlphy->rf_type != RF_2T2R_GREEN)
+			/* so we should reconfig BB reg with the right
+			 * PHY parameters. */
+			rtstatus = _rtl92s_phy_set_bb_to_diff_rf(hw,
+						BASEBAND_CONFIG_PHY_REG);
+	} else {
+		rtstatus = false;
+	}
+
+	if (rtstatus != true) {
+		RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG,
+			 ("Write BB Reg Fail!!"));
+		goto phy_BB8190_Config_ParaFile_Fail;
+	}
+
+	/* 2. If EEPROM or EFUSE autoload OK, We must config by
+	 *    PHY_REG_PG.txt */
+	if (rtlefuse->autoload_failflag == false) {
+		rtlphy->pwrgroup_cnt = 0;
+
+		rtstatus = _rtl92s_phy_config_bb_with_pg(hw,
+						 BASEBAND_CONFIG_PHY_REG);
+	}
+	if (rtstatus != true) {
+		RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG,
+			 ("_rtl92s_phy_bb_config_parafile(): "
+			 "BB_PG Reg Fail!!"));
+		goto phy_BB8190_Config_ParaFile_Fail;
+	}
+
+	/* 3. BB AGC table Initialization */
+	rtstatus = _rtl92s_phy_config_bb(hw, BASEBAND_CONFIG_AGC_TAB);
+
+	if (rtstatus != true) {
+		printk(KERN_ERR  "_rtl92s_phy_bb_config_parafile(): "
+		       "AGC Table Fail\n");
+		goto phy_BB8190_Config_ParaFile_Fail;
+	}
+
+	/* Check if the CCK HighPower is turned ON. */
+	/* This is used to calculate PWDB. */
+	rtlphy->cck_high_power = (bool)(rtl92s_phy_query_bb_reg(hw,
+			RFPGA0_XA_HSSIPARAMETER2, 0x200));
+
+phy_BB8190_Config_ParaFile_Fail:
+	return rtstatus;
+}
+
+u8 rtl92s_phy_config_rf(struct ieee80211_hw *hw, enum radio_path rfpath)
+{
+	struct rtl_priv *rtlpriv = rtl_priv(hw);
+	struct rtl_phy *rtlphy = &(rtlpriv->phy);
+	int i;
+	bool rtstatus = true;
+	u32 *radio_a_table;
+	u32 *radio_b_table;
+	u16 radio_a_tblen, radio_b_tblen;
+
+	radio_a_tblen = RADIOA_1T_ARRAYLENGTH;
+	radio_a_table = rtl8192seradioa_1t_array;
+
+	/* Using Green mode array table for RF_2T2R_GREEN */
+	if (rtlphy->rf_type == RF_2T2R_GREEN) {
+		radio_b_table = rtl8192seradiob_gm_array;
+		radio_b_tblen = RADIOB_GM_ARRAYLENGTH;
+	} else {
+		radio_b_table = rtl8192seradiob_array;
+		radio_b_tblen = RADIOB_ARRAYLENGTH;
+	}
+
+	RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("Radio No %x\n", rfpath));
+	rtstatus = true;
+
+	switch (rfpath) {
+	case RF90_PATH_A:
+		for (i = 0; i < radio_a_tblen; i = i + 2) {
+			if (radio_a_table[i] == 0xfe)
+				/* Delay specific ms. Only RF configuration
+				 * requires delay. */
+				mdelay(50);
+			else if (radio_a_table[i] == 0xfd)
+				mdelay(5);
+			else if (radio_a_table[i] == 0xfc)
+				mdelay(1);
+			else if (radio_a_table[i] == 0xfb)
+				udelay(50);
+			else if (radio_a_table[i] == 0xfa)
+				udelay(5);
+			else if (radio_a_table[i] == 0xf9)
+				udelay(1);
+			else
+				rtl92s_phy_set_rf_reg(hw, rfpath,
+						      radio_a_table[i],
+						      MASK20BITS,
+						      radio_a_table[i + 1]);
+
+			/* Add delay for ECS T20 & LG malow platform */
+			udelay(1);
+		}
+
+		/* PA Bias current for inferiority IC */
+		_rtl92s_phy_config_rfpa_bias_current(hw, rfpath);
+		break;
+	case RF90_PATH_B:
+		for (i = 0; i < radio_b_tblen; i = i + 2) {
+			if (radio_b_table[i] == 0xfe)
+				/* Delay specific ms. Only RF configuration
+				 * requires delay.*/
+				mdelay(50);
+			else if (radio_b_table[i] == 0xfd)
+				mdelay(5);
+			else if (radio_b_table[i] == 0xfc)
+				mdelay(1);
+			else if (radio_b_table[i] == 0xfb)
+				udelay(50);
+			else if (radio_b_table[i] == 0xfa)
+				udelay(5);
+			else if (radio_b_table[i] == 0xf9)
+				udelay(1);
+			else
+				rtl92s_phy_set_rf_reg(hw, rfpath,
+						      radio_b_table[i],
+						      MASK20BITS,
+						      radio_b_table[i + 1]);
+
+			/* Add delay for ECS T20 & LG malow platform */
+			udelay(1);
+		}
+		break;
+	case RF90_PATH_C:
+		;
+		break;
+	case RF90_PATH_D:
+		;
+		break;
+	default:
+		break;
+	}
+
+	return rtstatus;
+}
+
+
+bool rtl92s_phy_mac_config(struct ieee80211_hw *hw)
+{
+	struct rtl_priv *rtlpriv = rtl_priv(hw);
+	u32 i;
+	u32 arraylength;
+	u32 *ptraArray;
+
+	arraylength = MAC_2T_ARRAYLENGTH;
+	ptraArray = rtl8192semac_2t_array;
+
+	for (i = 0; i < arraylength; i = i + 2)
+		rtl_write_byte(rtlpriv, ptraArray[i], (u8)ptraArray[i + 1]);
+
+	return true;
+}
+
+
+bool rtl92s_phy_bb_config(struct ieee80211_hw *hw)
+{
+	struct rtl_priv *rtlpriv = rtl_priv(hw);
+	struct rtl_phy *rtlphy = &(rtlpriv->phy);
+	bool rtstatus = true;
+	u8 pathmap, index, rf_num = 0;
+	u8 path1, path2;
+
+	_rtl92s_phy_init_register_definition(hw);
+
+	/* Config BB and AGC */
+	rtstatus = _rtl92s_phy_bb_config_parafile(hw);
+
+
+	/* Check BB/RF confiuration setting. */
+	/* We only need to configure RF which is turned on. */
+	path1 = (u8)(rtl92s_phy_query_bb_reg(hw, RFPGA0_TXINFO, 0xf));
+	mdelay(10);
+	path2 = (u8)(rtl92s_phy_query_bb_reg(hw, ROFDM0_TRXPATHENABLE, 0xf));
+	pathmap = path1 | path2;
+
+	rtlphy->rf_pathmap = pathmap;
+	for (index = 0; index < 4; index++) {
+		if ((pathmap >> index) & 0x1)
+			rf_num++;
+	}
+
+	if ((rtlphy->rf_type == RF_1T1R && rf_num != 1) ||
+	    (rtlphy->rf_type == RF_1T2R && rf_num != 2) ||
+	    (rtlphy->rf_type == RF_2T2R && rf_num != 2) ||
+	    (rtlphy->rf_type == RF_2T2R_GREEN && rf_num != 2)) {
+		RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG,
+			 ("RF_Type(%x) does not match "
+			 "RF_Num(%x)!!\n", rtlphy->rf_type, rf_num));
+		RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG,
+			 ("path1 0x%x, path2 0x%x, pathmap "
+			  "0x%x\n", path1, path2, pathmap));
+	}
+
+	return rtstatus;
+}
+
+bool rtl92s_phy_rf_config(struct ieee80211_hw *hw)
+{
+	struct rtl_priv *rtlpriv = rtl_priv(hw);
+	struct rtl_phy *rtlphy = &(rtlpriv->phy);
+
+	/* Initialize general global value */
+	if (rtlphy->rf_type == RF_1T1R)
+		rtlphy->num_total_rfpath = 1;
+	else
+		rtlphy->num_total_rfpath = 2;
+
+	/* Config BB and RF */
+	return rtl92s_phy_rf6052_config(hw);
+}
+
+void rtl92s_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw)
+{
+	struct rtl_priv *rtlpriv = rtl_priv(hw);
+	struct rtl_phy *rtlphy = &(rtlpriv->phy);
+
+	/* read rx initial gain */
+	rtlphy->default_initialgain[0] = rtl_get_bbreg(hw,
+			ROFDM0_XAAGCCORE1, MASKBYTE0);
+	rtlphy->default_initialgain[1] = rtl_get_bbreg(hw,
+			ROFDM0_XBAGCCORE1, MASKBYTE0);
+	rtlphy->default_initialgain[2] = rtl_get_bbreg(hw,
+			ROFDM0_XCAGCCORE1, MASKBYTE0);
+	rtlphy->default_initialgain[3] = rtl_get_bbreg(hw,
+			ROFDM0_XDAGCCORE1, MASKBYTE0);
+	RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("Default initial gain "
+		 "(c50=0x%x, c58=0x%x, c60=0x%x, c68=0x%x)\n",
+		 rtlphy->default_initialgain[0],
+		 rtlphy->default_initialgain[1],
+		 rtlphy->default_initialgain[2],
+		 rtlphy->default_initialgain[3]));
+
+	/* read framesync */
+	rtlphy->framesync = rtl_get_bbreg(hw, ROFDM0_RXDETECTOR3, MASKBYTE0);
+	rtlphy->framesync_c34 = rtl_get_bbreg(hw, ROFDM0_RXDETECTOR2,
+					      MASKDWORD);
+	RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
+		 ("Default framesync (0x%x) = 0x%x\n",
+		 ROFDM0_RXDETECTOR3, rtlphy->framesync));
+
+}
+
+static void _rtl92s_phy_get_txpower_index(struct ieee80211_hw *hw, u8 channel,
+					  u8 *cckpowerlevel, u8 *ofdmpowerLevel)
+{
+	struct rtl_priv *rtlpriv = rtl_priv(hw);
+	struct rtl_phy *rtlphy = &(rtlpriv->phy);
+	struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
+	u8 index = (channel - 1);
+
+	/* 1. CCK */
+	/* RF-A */
+	cckpowerlevel[0] = rtlefuse->txpwrlevel_cck[0][index];
+	/* RF-B */
+	cckpowerlevel[1] = rtlefuse->txpwrlevel_cck[1][index];
+
+	/* 2. OFDM for 1T or 2T */
+	if (rtlphy->rf_type == RF_1T2R || rtlphy->rf_type == RF_1T1R) {
+		/* Read HT 40 OFDM TX power */
+		ofdmpowerLevel[0] = rtlefuse->txpwrlevel_ht40_1s[0][index];
+		ofdmpowerLevel[1] = rtlefuse->txpwrlevel_ht40_1s[1][index];
+	} else if (rtlphy->rf_type == RF_2T2R) {
+		/* Read HT 40 OFDM TX power */
+		ofdmpowerLevel[0] = rtlefuse->txpwrlevel_ht40_2s[0][index];
+		ofdmpowerLevel[1] = rtlefuse->txpwrlevel_ht40_2s[1][index];
+	}
+}
+
+static void _rtl92s_phy_ccxpower_indexcheck(struct ieee80211_hw *hw,
+		u8 channel, u8 *cckpowerlevel, u8 *ofdmpowerlevel)
+{
+	struct rtl_priv *rtlpriv = rtl_priv(hw);
+	struct rtl_phy *rtlphy = &(rtlpriv->phy);
+
+	rtlphy->cur_cck_txpwridx = cckpowerlevel[0];
+	rtlphy->cur_ofdm24g_txpwridx = ofdmpowerlevel[0];
+}
+
+void rtl92s_phy_set_txpower(struct ieee80211_hw *hw, u8	channel)
+{
+	struct rtl_priv *rtlpriv = rtl_priv(hw);
+	struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
+	/* [0]:RF-A, [1]:RF-B */
+	u8 cckpowerlevel[2], ofdmpowerLevel[2];
+
+	if (rtlefuse->txpwr_fromeprom == false)
+		return;
+
+	/* Mainly we use RF-A Tx Power to write the Tx Power registers,
+	 * but the RF-B Tx Power must be calculated by the antenna diff.
+	 * So we have to rewrite Antenna gain offset register here.
+	 * Please refer to BB register 0x80c
+	 * 1. For CCK.
+	 * 2. For OFDM 1T or 2T */
+	_rtl92s_phy_get_txpower_index(hw, channel, &cckpowerlevel[0],
+			&ofdmpowerLevel[0]);
+
+	RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
+			("Channel-%d, cckPowerLevel (A / B) = "
+			"0x%x / 0x%x,   ofdmPowerLevel (A / B) = 0x%x / 0x%x\n",
+			channel, cckpowerlevel[0], cckpowerlevel[1],
+			ofdmpowerLevel[0], ofdmpowerLevel[1]));
+
+	_rtl92s_phy_ccxpower_indexcheck(hw, channel, &cckpowerlevel[0],
+			&ofdmpowerLevel[0]);
+
+	rtl92s_phy_rf6052_set_ccktxpower(hw, cckpowerlevel[0]);
+	rtl92s_phy_rf6052_set_ofdmtxpower(hw, &ofdmpowerLevel[0], channel);
+
+}
+
+void rtl92s_phy_chk_fwcmd_iodone(struct ieee80211_hw *hw)
+{
+	struct rtl_priv *rtlpriv = rtl_priv(hw);
+	u16 pollingcnt = 10000;
+	u32 tmpvalue;
+
+	/* Make sure that CMD IO has be accepted by FW. */
+	do {
+		udelay(10);
+
+		tmpvalue = rtl_read_dword(rtlpriv, WFM5);
+		if (tmpvalue == 0)
+			break;
+	} while (--pollingcnt);
+
+	if (pollingcnt == 0)
+		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("Set FW Cmd fail!!\n"));
+}
+
+
+static void _rtl92s_phy_set_fwcmd_io(struct ieee80211_hw *hw)
+{
+	struct rtl_priv *rtlpriv = rtl_priv(hw);
+	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+	struct rtl_phy *rtlphy = &(rtlpriv->phy);
+	u32 input, current_aid = 0;
+
+	if (is_hal_stop(rtlhal))
+		return;
+
+	/* We re-map RA related CMD IO to combinational ones */
+	/* if FW version is v.52 or later. */
+	switch (rtlhal->current_fwcmd_io) {
+	case FW_CMD_RA_REFRESH_N:
+		rtlhal->current_fwcmd_io = FW_CMD_RA_REFRESH_N_COMB;
+		break;
+	case FW_CMD_RA_REFRESH_BG:
+		rtlhal->current_fwcmd_io = FW_CMD_RA_REFRESH_BG_COMB;
+		break;
+	default:
+		break;
+	}
+
+	switch (rtlhal->current_fwcmd_io) {
+	case FW_CMD_RA_RESET:
+		RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG,
+			 ("FW_CMD_RA_RESET\n"));
+		rtl_write_dword(rtlpriv, WFM5, FW_RA_RESET);
+		rtl92s_phy_chk_fwcmd_iodone(hw);
+		break;
+	case FW_CMD_RA_ACTIVE:
+		RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG,
+			 ("FW_CMD_RA_ACTIVE\n"));
+		rtl_write_dword(rtlpriv, WFM5, FW_RA_ACTIVE);
+		rtl92s_phy_chk_fwcmd_iodone(hw);
+		break;
+	case FW_CMD_RA_REFRESH_N:
+		RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG,
+			 ("FW_CMD_RA_REFRESH_N\n"));
+		input = FW_RA_REFRESH;
+		rtl_write_dword(rtlpriv, WFM5, input);
+		rtl92s_phy_chk_fwcmd_iodone(hw);
+		rtl_write_dword(rtlpriv, WFM5, FW_RA_ENABLE_RSSI_MASK);
+		rtl92s_phy_chk_fwcmd_iodone(hw);
+		break;
+	case FW_CMD_RA_REFRESH_BG:
+		RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG,
+			 ("FW_CMD_RA_REFRESH_BG\n"));
+		rtl_write_dword(rtlpriv, WFM5, FW_RA_REFRESH);
+		rtl92s_phy_chk_fwcmd_iodone(hw);
+		rtl_write_dword(rtlpriv, WFM5, FW_RA_DISABLE_RSSI_MASK);
+		rtl92s_phy_chk_fwcmd_iodone(hw);
+		break;
+	case FW_CMD_RA_REFRESH_N_COMB:
+		RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG,
+			 ("FW_CMD_RA_REFRESH_N_COMB\n"));
+		input = FW_RA_IOT_N_COMB;
+		rtl_write_dword(rtlpriv, WFM5, input);
+		rtl92s_phy_chk_fwcmd_iodone(hw);
+		break;
+	case FW_CMD_RA_REFRESH_BG_COMB:
+		RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG,
+			 ("FW_CMD_RA_REFRESH_BG_COMB\n"));
+		input = FW_RA_IOT_BG_COMB;
+		rtl_write_dword(rtlpriv, WFM5, input);
+		rtl92s_phy_chk_fwcmd_iodone(hw);
+		break;
+	case FW_CMD_IQK_ENABLE:
+		RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG,
+			 ("FW_CMD_IQK_ENABLE\n"));
+		rtl_write_dword(rtlpriv, WFM5, FW_IQK_ENABLE);
+		rtl92s_phy_chk_fwcmd_iodone(hw);
+		break;
+	case FW_CMD_PAUSE_DM_BY_SCAN:
+		/* Lower initial gain */
+		rtl_set_bbreg(hw, ROFDM0_XAAGCCORE1, MASKBYTE0, 0x17);
+		rtl_set_bbreg(hw, ROFDM0_XBAGCCORE1, MASKBYTE0, 0x17);
+		/* CCA threshold */
+		rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2, 0x40);
+		break;
+	case FW_CMD_RESUME_DM_BY_SCAN:
+		/* CCA threshold */
+		rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2, 0xcd);
+		rtl92s_phy_set_txpower(hw, rtlphy->current_channel);
+		break;
+	case FW_CMD_HIGH_PWR_DISABLE:
+		if (rtlpriv->dm.dm_flag & HAL_DM_HIPWR_DISABLE)
+			break;
+
+		/* Lower initial gain */
+		rtl_set_bbreg(hw, ROFDM0_XAAGCCORE1, MASKBYTE0, 0x17);
+		rtl_set_bbreg(hw, ROFDM0_XBAGCCORE1, MASKBYTE0, 0x17);
+		/* CCA threshold */
+		rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2, 0x40);
+		break;
+	case FW_CMD_HIGH_PWR_ENABLE:
+		if ((rtlpriv->dm.dm_flag & HAL_DM_HIPWR_DISABLE) ||
+			(rtlpriv->dm.dynamic_txpower_enable == true))
+			break;
+
+		/* CCA threshold */
+		rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2, 0xcd);
+		break;
+	case FW_CMD_LPS_ENTER:
+		RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG,
+			 ("FW_CMD_LPS_ENTER\n"));
+		current_aid = rtlpriv->mac80211.assoc_id;
+		rtl_write_dword(rtlpriv, WFM5, (FW_LPS_ENTER |
+				((current_aid | 0xc000) << 8)));
+		rtl92s_phy_chk_fwcmd_iodone(hw);
+		/* FW set TXOP disable here, so disable EDCA
+		 * turbo mode until driver leave LPS */
+		break;
+	case FW_CMD_LPS_LEAVE:
+		RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG,
+			 ("FW_CMD_LPS_LEAVE\n"));
+		rtl_write_dword(rtlpriv, WFM5, FW_LPS_LEAVE);
+		rtl92s_phy_chk_fwcmd_iodone(hw);
+		break;
+	case FW_CMD_ADD_A2_ENTRY:
+		RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG,
+			 ("FW_CMD_ADD_A2_ENTRY\n"));
+		rtl_write_dword(rtlpriv, WFM5, FW_ADD_A2_ENTRY);
+		rtl92s_phy_chk_fwcmd_iodone(hw);
+		break;
+	case FW_CMD_CTRL_DM_BY_DRIVER:
+		RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
+			 ("FW_CMD_CTRL_DM_BY_DRIVER\n"));
+		rtl_write_dword(rtlpriv, WFM5, FW_CTRL_DM_BY_DRIVER);
+		rtl92s_phy_chk_fwcmd_iodone(hw);
+		break;
+
+	default:
+		break;
+	}
+
+	rtl92s_phy_chk_fwcmd_iodone(hw);
+
+	/* Clear FW CMD operation flag. */
+	rtlhal->set_fwcmd_inprogress = false;
+}
+
+bool rtl92s_phy_set_fw_cmd(struct ieee80211_hw *hw, enum fwcmd_iotype fw_cmdio)
+{
+	struct rtl_priv *rtlpriv = rtl_priv(hw);
+	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+	struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
+	u32	fw_param = FW_CMD_IO_PARA_QUERY(rtlpriv);
+	u16	fw_cmdmap = FW_CMD_IO_QUERY(rtlpriv);
+	bool bPostProcessing = false;
+
+	RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
+			("Set FW Cmd(%#x), set_fwcmd_inprogress(%d)\n",
+			fw_cmdio, rtlhal->set_fwcmd_inprogress));
+
+	do {
+		/* We re-map to combined FW CMD ones if firmware version */
+		/* is v.53 or later. */
+		switch (fw_cmdio) {
+		case FW_CMD_RA_REFRESH_N:
+			fw_cmdio = FW_CMD_RA_REFRESH_N_COMB;
+			break;
+		case FW_CMD_RA_REFRESH_BG:
+			fw_cmdio = FW_CMD_RA_REFRESH_BG_COMB;
+			break;
+		default:
+			break;
+		}
+
+		/* If firmware version is v.62 or later,
+		 * use FW_CMD_IO_SET for FW_CMD_CTRL_DM_BY_DRIVER */
+		if (hal_get_firmwareversion(rtlpriv) >= 0x3E) {
+			if (fw_cmdio == FW_CMD_CTRL_DM_BY_DRIVER)
+				fw_cmdio = FW_CMD_CTRL_DM_BY_DRIVER_NEW;
+		}
+
+
+		/* We shall revise all FW Cmd IO into Reg0x364
+		 * DM map table in the future. */
+		switch (fw_cmdio) {
+		case FW_CMD_RA_INIT:
+			RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, ("RA init!!\n"));
+			fw_cmdmap |= FW_RA_INIT_CTL;
+			FW_CMD_IO_SET(rtlpriv, fw_cmdmap);
+			/* Clear control flag to sync with FW. */
+			FW_CMD_IO_CLR(rtlpriv, FW_RA_INIT_CTL);
+			break;
+		case FW_CMD_DIG_DISABLE:
+			RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
+				 ("Set DIG disable!!\n"));
+			fw_cmdmap &= ~FW_DIG_ENABLE_CTL;
+			FW_CMD_IO_SET(rtlpriv, fw_cmdmap);
+			break;
+		case FW_CMD_DIG_ENABLE:
+		case FW_CMD_DIG_RESUME:
+			if (!(rtlpriv->dm.dm_flag & HAL_DM_DIG_DISABLE)) {
+				RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
+					("Set DIG enable or resume!!\n"));
+				fw_cmdmap |= (FW_DIG_ENABLE_CTL | FW_SS_CTL);
+				FW_CMD_IO_SET(rtlpriv, fw_cmdmap);
+			}
+			break;
+		case FW_CMD_DIG_HALT:
+			RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
+				 ("Set DIG halt!!\n"));
+			fw_cmdmap &= ~(FW_DIG_ENABLE_CTL | FW_SS_CTL);
+			FW_CMD_IO_SET(rtlpriv, fw_cmdmap);
+			break;
+		case FW_CMD_TXPWR_TRACK_THERMAL: {
+			u8	thermalval = 0;
+			fw_cmdmap |= FW_PWR_TRK_CTL;
+
+			/* Clear FW parameter in terms of thermal parts. */
+			fw_param &= FW_PWR_TRK_PARAM_CLR;
+
+			thermalval = rtlpriv->dm.thermalvalue;
+			fw_param |= ((thermalval << 24) |
+				     (rtlefuse->thermalmeter[0] << 16));
+
+			RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
+				 ("Set TxPwr tracking!! "
+				 "FwCmdMap(%#x), FwParam(%#x)\n",
+				 fw_cmdmap, fw_param));
+
+			FW_CMD_PARA_SET(rtlpriv, fw_param);
+			FW_CMD_IO_SET(rtlpriv, fw_cmdmap);
+
+			/* Clear control flag to sync with FW. */
+			FW_CMD_IO_CLR(rtlpriv, FW_PWR_TRK_CTL);
+			}
+			break;
+		/* The following FW CMDs are only compatible to
+		 * v.53 or later. */
+		case FW_CMD_RA_REFRESH_N_COMB:
+			fw_cmdmap |= FW_RA_N_CTL;
+
+			/* Clear RA BG mode control. */
+			fw_cmdmap &= ~(FW_RA_BG_CTL | FW_RA_INIT_CTL);
+
+			/* Clear FW parameter in terms of RA parts. */
+			fw_param &= FW_RA_PARAM_CLR;
+
+			RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
+				 ("[FW CMD] [New Version] "
+				 "Set RA/IOT Comb in n mode!! FwCmdMap(%#x), "
+				 "FwParam(%#x)\n", fw_cmdmap, fw_param));
+
+			FW_CMD_PARA_SET(rtlpriv, fw_param);
+			FW_CMD_IO_SET(rtlpriv, fw_cmdmap);
+
+			/* Clear control flag to sync with FW. */
+			FW_CMD_IO_CLR(rtlpriv, FW_RA_N_CTL);
+			break;
+		case FW_CMD_RA_REFRESH_BG_COMB:
+			fw_cmdmap |= FW_RA_BG_CTL;
+
+			/* Clear RA n-mode control. */
+			fw_cmdmap &= ~(FW_RA_N_CTL | FW_RA_INIT_CTL);
+			/* Clear FW parameter in terms of RA parts. */
+			fw_param &= FW_RA_PARAM_CLR;
+
+			FW_CMD_PARA_SET(rtlpriv, fw_param);
+			FW_CMD_IO_SET(rtlpriv, fw_cmdmap);
+
+			/* Clear control flag to sync with FW. */
+			FW_CMD_IO_CLR(rtlpriv, FW_RA_BG_CTL);
+			break;
+		case FW_CMD_IQK_ENABLE:
+			fw_cmdmap |= FW_IQK_CTL;
+			FW_CMD_IO_SET(rtlpriv, fw_cmdmap);
+			/* Clear control flag to sync with FW. */
+			FW_CMD_IO_CLR(rtlpriv, FW_IQK_CTL);
+			break;
+		/* The following FW CMD is compatible to v.62 or later.  */
+		case FW_CMD_CTRL_DM_BY_DRIVER_NEW:
+			fw_cmdmap |= FW_DRIVER_CTRL_DM_CTL;
+			FW_CMD_IO_SET(rtlpriv, fw_cmdmap);
+			break;
+		/*  The followed FW Cmds needs post-processing later. */
+		case FW_CMD_RESUME_DM_BY_SCAN:
+			fw_cmdmap |= (FW_DIG_ENABLE_CTL |
+				      FW_HIGH_PWR_ENABLE_CTL |
+				      FW_SS_CTL);
+
+			if (rtlpriv->dm.dm_flag & HAL_DM_DIG_DISABLE ||
+				!digtable.dig_enable_flag)
+				fw_cmdmap &= ~FW_DIG_ENABLE_CTL;
+
+			if ((rtlpriv->dm.dm_flag & HAL_DM_HIPWR_DISABLE) ||
+			    (rtlpriv->dm.dynamic_txpower_enable == true))
+				fw_cmdmap &= ~FW_HIGH_PWR_ENABLE_CTL;
+
+			if ((digtable.dig_ext_port_stage ==
+			    DIG_EXT_PORT_STAGE_0) ||
+			    (digtable.dig_ext_port_stage ==
+			    DIG_EXT_PORT_STAGE_1))
+				fw_cmdmap &= ~FW_DIG_ENABLE_CTL;
+
+			FW_CMD_IO_SET(rtlpriv, fw_cmdmap);
+			bPostProcessing = true;
+			break;
+		case FW_CMD_PAUSE_DM_BY_SCAN:
+			fw_cmdmap &= ~(FW_DIG_ENABLE_CTL |
+				       FW_HIGH_PWR_ENABLE_CTL |
+				       FW_SS_CTL);
+			FW_CMD_IO_SET(rtlpriv, fw_cmdmap);
+			bPostProcessing = true;
+			break;
+		case FW_CMD_HIGH_PWR_DISABLE:
+			fw_cmdmap &= ~FW_HIGH_PWR_ENABLE_CTL;
+			FW_CMD_IO_SET(rtlpriv, fw_cmdmap);
+			bPostProcessing = true;
+			break;
+		case FW_CMD_HIGH_PWR_ENABLE:
+			if (!(rtlpriv->dm.dm_flag & HAL_DM_HIPWR_DISABLE) &&
+				(rtlpriv->dm.dynamic_txpower_enable != true)) {
+				fw_cmdmap |= (FW_HIGH_PWR_ENABLE_CTL |
+					      FW_SS_CTL);
+				FW_CMD_IO_SET(rtlpriv, fw_cmdmap);
+				bPostProcessing = true;
+			}
+			break;
+		case FW_CMD_DIG_MODE_FA:
+			fw_cmdmap |= FW_FA_CTL;
+			FW_CMD_IO_SET(rtlpriv, fw_cmdmap);
+			break;
+		case FW_CMD_DIG_MODE_SS:
+			fw_cmdmap &= ~FW_FA_CTL;
+			FW_CMD_IO_SET(rtlpriv, fw_cmdmap);
+			break;
+		case FW_CMD_PAPE_CONTROL:
+			RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD,
+				 ("[FW CMD] Set PAPE Control\n"));
+			fw_cmdmap &= ~FW_PAPE_CTL_BY_SW_HW;
+
+			FW_CMD_IO_SET(rtlpriv, fw_cmdmap);
+			break;
+		default:
+			/* Pass to original FW CMD processing callback
+			 * routine. */
+			bPostProcessing = true;
+			break;
+		}
+	} while (false);
+
+	/* We shall post processing these FW CMD if
+	 * variable bPostProcessing is set. */
+	if (bPostProcessing && !rtlhal->set_fwcmd_inprogress) {
+		rtlhal->set_fwcmd_inprogress = true;
+		/* Update current FW Cmd for callback use. */
+		rtlhal->current_fwcmd_io = fw_cmdio;
+	} else {
+		return false;
+	}
+
+	_rtl92s_phy_set_fwcmd_io(hw);
+	return true;
+}
+
+static	void _rtl92s_phy_check_ephy_switchready(struct ieee80211_hw *hw)
+{
+	struct rtl_priv *rtlpriv = rtl_priv(hw);
+	u32	delay = 100;
+	u8	regu1;
+
+	regu1 = rtl_read_byte(rtlpriv, 0x554);
+	while ((regu1 & BIT(5)) && (delay > 0)) {
+		regu1 = rtl_read_byte(rtlpriv, 0x554);
+		delay--;
+		/* We delay only 50us to prevent
+		 * being scheduled out. */
+		udelay(50);
+	}
+}
+
+void rtl92s_phy_switch_ephy_parameter(struct ieee80211_hw *hw)
+{
+	struct rtl_priv *rtlpriv = rtl_priv(hw);
+	struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
+
+	/* The way to be capable to switch clock request
+	 * when the PG setting does not support clock request.
+	 * This is the backdoor solution to switch clock
+	 * request before ASPM or D3. */
+	rtl_write_dword(rtlpriv, 0x540, 0x73c11);
+	rtl_write_dword(rtlpriv, 0x548, 0x2407c);
+
+	/* Switch EPHY parameter!!!! */
+	rtl_write_word(rtlpriv, 0x550, 0x1000);
+	rtl_write_byte(rtlpriv, 0x554, 0x20);
+	_rtl92s_phy_check_ephy_switchready(hw);
+
+	rtl_write_word(rtlpriv, 0x550, 0xa0eb);
+	rtl_write_byte(rtlpriv, 0x554, 0x3e);
+	_rtl92s_phy_check_ephy_switchready(hw);
+
+	rtl_write_word(rtlpriv, 0x550, 0xff80);
+	rtl_write_byte(rtlpriv, 0x554, 0x39);
+	_rtl92s_phy_check_ephy_switchready(hw);
+
+	/* Delay L1 enter time */
+	if (ppsc->support_aspm && !ppsc->support_backdoor)
+		rtl_write_byte(rtlpriv, 0x560, 0x40);
+	else
+		rtl_write_byte(rtlpriv, 0x560, 0x00);
+
+}
+
+void rtl92s_phy_set_beacon_hwreg(struct ieee80211_hw *hw, u16 BeaconInterval)
+{
+	struct rtl_priv *rtlpriv = rtl_priv(hw);
+	rtl_write_dword(rtlpriv, WFM5, 0xF1000000 | (BeaconInterval << 8));
+}
diff -druN linux-2.6.39-libre/drivers/net/wireless/rtlwifi/rtl8192se/phy.h linux-3.0-rc7-libre/drivers/net/wireless/rtlwifi/rtl8192se/phy.h
--- linux-2.6.39-libre/drivers/net/wireless/rtlwifi/rtl8192se/phy.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/net/wireless/rtlwifi/rtl8192se/phy.h	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,101 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2009-2010  Realtek Corporation.
+ *
+ * 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:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+#ifndef __RTL92S_PHY_H__
+#define __RTL92S_PHY_H__
+
+#define MAX_TXPWR_IDX_NMODE_92S		63
+#define MAX_DOZE_WAITING_TIMES_9x	64
+
+/* 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
+
+#define RF90_PATH_MAX			4
+
+enum version_8192s {
+	VERSION_8192S_ACUT,
+	VERSION_8192S_BCUT,
+	VERSION_8192S_CCUT
+};
+
+enum swchnlcmd_id {
+	CMDID_END,
+	CMDID_SET_TXPOWEROWER_LEVEL,
+	CMDID_BBREGWRITE10,
+	CMDID_WRITEPORT_ULONG,
+	CMDID_WRITEPORT_USHORT,
+	CMDID_WRITEPORT_UCHAR,
+	CMDID_RF_WRITEREG,
+};
+
+struct swchnlcmd {
+	enum swchnlcmd_id cmdid;
+	u32 para1;
+	u32 para2;
+	u32 msdelay;
+};
+
+enum baseband_config_type {
+	/* Radio Path A */
+	BASEBAND_CONFIG_PHY_REG = 0,
+	/* Radio Path B */
+	BASEBAND_CONFIG_AGC_TAB = 1,
+};
+
+#define hal_get_firmwareversion(rtlpriv) \
+	(((struct rt_firmware *)(rtlpriv->rtlhal.pfirmware))->firmwareversion)
+
+u32 rtl92s_phy_query_bb_reg(struct ieee80211_hw *hw, u32 regaddr, u32 bitmask);
+void rtl92s_phy_set_bb_reg(struct ieee80211_hw *hw, u32 regaddr, u32 bitmask,
+			   u32 data);
+void rtl92s_phy_scan_operation_backup(struct ieee80211_hw *hw, u8 operation);
+u32 rtl92s_phy_query_rf_reg(struct ieee80211_hw *hw, enum radio_path rfpath,
+			    u32 regaddr, u32 bitmask);
+void rtl92s_phy_set_rf_reg(struct ieee80211_hw *hw,	enum radio_path rfpath,
+			   u32 regaddr, u32 bitmask, u32 data);
+void rtl92s_phy_set_bw_mode(struct ieee80211_hw *hw,
+			    enum nl80211_channel_type ch_type);
+u8 rtl92s_phy_sw_chnl(struct ieee80211_hw *hw);
+bool rtl92s_phy_set_rf_power_state(struct ieee80211_hw *hw,
+				   enum rf_pwrstate rfpower_state);
+bool rtl92s_phy_mac_config(struct ieee80211_hw *hw);
+void rtl92s_phy_switch_ephy_parameter(struct ieee80211_hw *hw);
+bool rtl92s_phy_bb_config(struct ieee80211_hw *hw);
+bool rtl92s_phy_rf_config(struct ieee80211_hw *hw);
+void rtl92s_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw);
+void rtl92s_phy_set_txpower(struct ieee80211_hw *hw, u8	channel);
+bool rtl92s_phy_set_fw_cmd(struct ieee80211_hw *hw, enum fwcmd_iotype fwcmd_io);
+void rtl92s_phy_chk_fwcmd_iodone(struct ieee80211_hw *hw);
+void rtl92s_phy_set_beacon_hwreg(struct ieee80211_hw *hw, u16 beaconinterval);
+u8 rtl92s_phy_config_rf(struct ieee80211_hw *hw, enum radio_path rfpath) ;
+
+#endif
+
diff -druN linux-2.6.39-libre/drivers/net/wireless/rtlwifi/rtl8192se/reg.h linux-3.0-rc7-libre/drivers/net/wireless/rtlwifi/rtl8192se/reg.h
--- linux-2.6.39-libre/drivers/net/wireless/rtlwifi/rtl8192se/reg.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/net/wireless/rtlwifi/rtl8192se/reg.h	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,1188 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2009-2010  Realtek Corporation.
+ *
+ * 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:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+#ifndef __REALTEK_92S_REG_H__
+#define __REALTEK_92S_REG_H__
+
+/* 1. System Configuration Registers  */
+#define	REG_SYS_ISO_CTRL			0x0000
+#define	REG_SYS_FUNC_EN				0x0002
+#define	PMC_FSM					0x0004
+#define	SYS_CLKR				0x0008
+#define	EPROM_CMD				0x000A
+#define	EE_VPD					0x000C
+#define	AFE_MISC				0x0010
+#define	SPS0_CTRL				0x0011
+#define	SPS1_CTRL				0x0018
+#define	RF_CTRL					0x001F
+#define	LDOA15_CTRL				0x0020
+#define	LDOV12D_CTRL				0x0021
+#define	LDOHCI12_CTRL				0x0022
+#define	LDO_USB_SDIO				0x0023
+#define	LPLDO_CTRL				0x0024
+#define	AFE_XTAL_CTRL				0x0026
+#define	AFE_PLL_CTRL				0x0028
+#define	REG_EFUSE_CTRL				0x0030
+#define	REG_EFUSE_TEST				0x0034
+#define	PWR_DATA				0x0038
+#define	DBG_PORT				0x003A
+#define	DPS_TIMER				0x003C
+#define	RCLK_MON				0x003E
+
+/* 2. Command Control Registers	  */
+#define	CMDR					0x0040
+#define	TXPAUSE					0x0042
+#define	LBKMD_SEL				0x0043
+#define	TCR					0x0044
+#define	RCR					0x0048
+#define	MSR					0x004C
+#define	SYSF_CFG				0x004D
+#define	RX_PKY_LIMIT				0x004E
+#define	MBIDCTRL				0x004F
+
+/* 3. MACID Setting Registers	 */
+#define	MACIDR					0x0050
+#define	MACIDR0					0x0050
+#define	MACIDR4					0x0054
+#define	BSSIDR					0x0058
+#define	HWVID					0x005E
+#define	MAR					0x0060
+#define	MBIDCAMCONTENT				0x0068
+#define	MBIDCAMCFG				0x0070
+#define	BUILDTIME				0x0074
+#define	BUILDUSER				0x0078
+
+#define	IDR0					MACIDR0
+#define	IDR4					MACIDR4
+
+/* 4. Timing Control Registers	 */
+#define	TSFR					0x0080
+#define	SLOT_TIME				0x0089
+#define	USTIME					0x008A
+#define	SIFS_CCK				0x008C
+#define	SIFS_OFDM				0x008E
+#define	PIFS_TIME				0x0090
+#define	ACK_TIMEOUT				0x0091
+#define	EIFSTR					0x0092
+#define	BCN_INTERVAL				0x0094
+#define	ATIMWND					0x0096
+#define	BCN_DRV_EARLY_INT			0x0098
+#define	BCN_DMATIME				0x009A
+#define	BCN_ERR_THRESH				0x009C
+#define	MLT					0x009D
+#define	RSVD_MAC_TUNE_US			0x009E
+
+/* 5. FIFO Control Registers	  */
+#define RQPN					0x00A0
+#define	RQPN1					0x00A0
+#define	RQPN2					0x00A1
+#define	RQPN3					0x00A2
+#define	RQPN4					0x00A3
+#define	RQPN5					0x00A4
+#define	RQPN6					0x00A5
+#define	RQPN7					0x00A6
+#define	RQPN8					0x00A7
+#define	RQPN9					0x00A8
+#define	RQPN10					0x00A9
+#define	LD_RQPN					0x00AB
+#define	RXFF_BNDY				0x00AC
+#define	RXRPT_BNDY				0x00B0
+#define	TXPKTBUF_PGBNDY				0x00B4
+#define	PBP					0x00B5
+#define	RXDRVINFO_SZ				0x00B6
+#define	TXFF_STATUS				0x00B7
+#define	RXFF_STATUS				0x00B8
+#define	TXFF_EMPTY_TH				0x00B9
+#define	SDIO_RX_BLKSZ				0x00BC
+#define	RXDMA					0x00BD
+#define	RXPKT_NUM				0x00BE
+#define	C2HCMD_UDT_SIZE				0x00C0
+#define	C2HCMD_UDT_ADDR				0x00C2
+#define	FIFOPAGE1				0x00C4
+#define	FIFOPAGE2				0x00C8
+#define	FIFOPAGE3				0x00CC
+#define	FIFOPAGE4				0x00D0
+#define	FIFOPAGE5				0x00D4
+#define	FW_RSVD_PG_CRTL				0x00D8
+#define	RXDMA_AGG_PG_TH				0x00D9
+#define	TXDESC_MSK				0x00DC
+#define	TXRPTFF_RDPTR				0x00E0
+#define	TXRPTFF_WTPTR				0x00E4
+#define	C2HFF_RDPTR				0x00E8
+#define	C2HFF_WTPTR				0x00EC
+#define	RXFF0_RDPTR				0x00F0
+#define	RXFF0_WTPTR				0x00F4
+#define	RXFF1_RDPTR				0x00F8
+#define	RXFF1_WTPTR				0x00FC
+#define	RXRPT0_RDPTR				0x0100
+#define	RXRPT0_WTPTR				0x0104
+#define	RXRPT1_RDPTR				0x0108
+#define	RXRPT1_WTPTR				0x010C
+#define	RX0_UDT_SIZE				0x0110
+#define	RX1PKTNUM				0x0114
+#define	RXFILTERMAP				0x0116
+#define	RXFILTERMAP_GP1				0x0118
+#define	RXFILTERMAP_GP2				0x011A
+#define	RXFILTERMAP_GP3				0x011C
+#define	BCNQ_CTRL				0x0120
+#define	MGTQ_CTRL				0x0124
+#define	HIQ_CTRL				0x0128
+#define	VOTID7_CTRL				0x012c
+#define	VOTID6_CTRL				0x0130
+#define	VITID5_CTRL				0x0134
+#define	VITID4_CTRL				0x0138
+#define	BETID3_CTRL				0x013c
+#define	BETID0_CTRL				0x0140
+#define	BKTID2_CTRL				0x0144
+#define	BKTID1_CTRL				0x0148
+#define	CMDQ_CTRL				0x014c
+#define	TXPKT_NUM_CTRL				0x0150
+#define	TXQ_PGADD				0x0152
+#define	TXFF_PG_NUM				0x0154
+#define	TRXDMA_STATUS				0x0156
+
+/* 6. Adaptive Control Registers   */
+#define	INIMCS_SEL				0x0160
+#define	TX_RATE_REG				INIMCS_SEL
+#define	INIRTSMCS_SEL				0x0180
+#define	RRSR					0x0181
+#define	ARFR0					0x0184
+#define	ARFR1					0x0188
+#define	ARFR2					0x018C
+#define	ARFR3					0x0190
+#define	ARFR4					0x0194
+#define	ARFR5					0x0198
+#define	ARFR6					0x019C
+#define	ARFR7					0x01A0
+#define	AGGLEN_LMT_H				0x01A7
+#define	AGGLEN_LMT_L				0x01A8
+#define	DARFRC					0x01B0
+#define	RARFRC					0x01B8
+#define	MCS_TXAGC				0x01C0
+#define	CCK_TXAGC				0x01C8
+
+/* 7. EDCA Setting Registers */
+#define	EDCAPARA_VO				0x01D0
+#define	EDCAPARA_VI				0x01D4
+#define	EDCAPARA_BE				0x01D8
+#define	EDCAPARA_BK				0x01DC
+#define	BCNTCFG					0x01E0
+#define	CWRR					0x01E2
+#define	ACMAVG					0x01E4
+#define	AcmHwCtrl				0x01E7
+#define	VO_ADMTM				0x01E8
+#define	VI_ADMTM				0x01EC
+#define	BE_ADMTM				0x01F0
+#define	RETRY_LIMIT				0x01F4
+#define	SG_RATE					0x01F6
+
+/* 8. WMAC, BA and CCX related Register. */
+#define	NAV_CTRL				0x0200
+#define	BW_OPMODE				0x0203
+#define	BACAMCMD				0x0204
+#define	BACAMCONTENT				0x0208
+
+/* the 0x2xx register WMAC definition */
+#define	LBDLY					0x0210
+#define	FWDLY					0x0211
+#define	HWPC_RX_CTRL				0x0218
+#define	MQIR					0x0220
+#define	MAIR					0x0222
+#define	MSIR					0x0224
+#define	CLM_RESULT				0x0227
+#define	NHM_RPI_CNT				0x0228
+#define	RXERR_RPT				0x0230
+#define	NAV_PROT_LEN				0x0234
+#define	CFEND_TH				0x0236
+#define	AMPDU_MIN_SPACE				0x0237
+#define	TXOP_STALL_CTRL				0x0238
+
+/* 9. Security Control Registers */
+#define	REG_RWCAM				0x0240
+#define	REG_WCAMI				0x0244
+#define	REG_RCAMO				0x0248
+#define	REG_CAMDBG				0x024C
+#define	REG_SECR				0x0250
+
+/* 10. Power Save Control Registers */
+#define	WOW_CTRL				0x0260
+#define	PSSTATUS				0x0261
+#define	PSSWITCH				0x0262
+#define	MIMOPS_WAIT_PERIOD			0x0263
+#define	LPNAV_CTRL				0x0264
+#define	WFM0					0x0270
+#define	WFM1					0x0280
+#define	WFM2					0x0290
+#define	WFM3					0x02A0
+#define	WFM4					0x02B0
+#define	WFM5					0x02C0
+#define	WFCRC					0x02D0
+#define	FW_RPT_REG				0x02c4
+
+/* 11. General Purpose Registers */
+#define	PSTIME					0x02E0
+#define	TIMER0					0x02E4
+#define	TIMER1					0x02E8
+#define	GPIO_CTRL				0x02EC
+#define	GPIO_IN					0x02EC
+#define	GPIO_OUT				0x02ED
+#define	GPIO_IO_SEL				0x02EE
+#define	GPIO_MOD				0x02EF
+#define	GPIO_INTCTRL				0x02F0
+#define	MAC_PINMUX_CFG				0x02F1
+#define	LEDCFG					0x02F2
+#define	PHY_REG					0x02F3
+#define	PHY_REG_DATA				0x02F4
+#define	REG_EFUSE_CLK				0x02F8
+
+/* 12. Host Interrupt Status Registers */
+#define	INTA_MASK				0x0300
+#define	ISR					0x0308
+
+/* 13. Test Mode and Debug Control Registers */
+#define	DBG_PORT_SWITCH				0x003A
+#define	BIST					0x0310
+#define	DBS					0x0314
+#define	CPUINST					0x0318
+#define	CPUCAUSE				0x031C
+#define	LBUS_ERR_ADDR				0x0320
+#define	LBUS_ERR_CMD				0x0324
+#define	LBUS_ERR_DATA_L				0x0328
+#define	LBUS_ERR_DATA_H				0x032C
+#define	LX_EXCEPTION_ADDR			0x0330
+#define	WDG_CTRL				0x0334
+#define	INTMTU					0x0338
+#define	INTM					0x033A
+#define	FDLOCKTURN0				0x033C
+#define	FDLOCKTURN1				0x033D
+#define	TRXPKTBUF_DBG_DATA			0x0340
+#define	TRXPKTBUF_DBG_CTRL			0x0348
+#define	DPLL					0x034A
+#define	CBUS_ERR_ADDR				0x0350
+#define	CBUS_ERR_CMD				0x0354
+#define	CBUS_ERR_DATA_L				0x0358
+#define	CBUS_ERR_DATA_H				0x035C
+#define	USB_SIE_INTF_ADDR			0x0360
+#define	USB_SIE_INTF_WD				0x0361
+#define	USB_SIE_INTF_RD				0x0362
+#define	USB_SIE_INTF_CTRL			0x0363
+#define LBUS_MON_ADDR				0x0364
+#define LBUS_ADDR_MASK				0x0368
+
+/* Boundary is 0x37F */
+
+/* 14. PCIE config register */
+#define	TP_POLL					0x0500
+#define	PM_CTRL					0x0502
+#define	PCIF					0x0503
+
+#define	THPDA					0x0514
+#define	TMDA					0x0518
+#define	TCDA					0x051C
+#define	HDA					0x0520
+#define	TVODA					0x0524
+#define	TVIDA					0x0528
+#define	TBEDA					0x052C
+#define	TBKDA					0x0530
+#define	TBDA					0x0534
+#define	RCDA					0x0538
+#define	RDQDA					0x053C
+#define	DBI_WDATA				0x0540
+#define	DBI_RDATA				0x0544
+#define	DBI_CTRL				0x0548
+#define	MDIO_DATA				0x0550
+#define	MDIO_CTRL				0x0554
+#define	PCI_RPWM				0x0561
+#define	PCI_CPWM				0x0563
+
+/* Config register	(Offset 0x800-) */
+#define	PHY_CCA					0x803
+
+/* Min Spacing related settings. */
+#define	MAX_MSS_DENSITY_2T			0x13
+#define	MAX_MSS_DENSITY_1T			0x0A
+
+/* Rx DMA Control related settings */
+#define	RXDMA_AGG_EN				BIT(7)
+
+#define	RPWM					PCI_RPWM
+
+/* Regsiter Bit and Content definition  */
+
+#define	ISO_MD2PP				BIT(0)
+#define	ISO_PA2PCIE				BIT(3)
+#define	ISO_PLL2MD				BIT(4)
+#define	ISO_PWC_DV2RP				BIT(11)
+#define	ISO_PWC_RV2RP				BIT(12)
+
+
+#define	FEN_MREGEN				BIT(15)
+#define	FEN_DCORE				BIT(11)
+#define	FEN_CPUEN				BIT(10)
+
+#define	PAD_HWPD_IDN				BIT(22)
+
+#define	SYS_CLKSEL_80M				BIT(0)
+#define	SYS_PS_CLKSEL				BIT(1)
+#define	SYS_CPU_CLKSEL				BIT(2)
+#define	SYS_MAC_CLK_EN				BIT(11)
+#define	SYS_SWHW_SEL				BIT(14)
+#define	SYS_FWHW_SEL				BIT(15)
+
+#define	CmdEEPROM_En				BIT(5)
+#define	CmdEERPOMSEL				BIT(4)
+#define	Cmd9346CR_9356SEL			BIT(4)
+
+#define	AFE_MBEN				BIT(1)
+#define	AFE_BGEN				BIT(0)
+
+#define	SPS1_SWEN				BIT(1)
+#define	SPS1_LDEN				BIT(0)
+
+#define	RF_EN					BIT(0)
+#define	RF_RSTB					BIT(1)
+#define	RF_SDMRSTB				BIT(2)
+
+#define	LDA15_EN				BIT(0)
+
+#define	LDV12_EN				BIT(0)
+#define	LDV12_SDBY				BIT(1)
+
+#define	XTAL_GATE_AFE				BIT(10)
+
+#define	APLL_EN					BIT(0)
+
+#define	AFR_CardBEn				BIT(0)
+#define	AFR_CLKRUN_SEL				BIT(1)
+#define	AFR_FuncRegEn				BIT(2)
+
+#define	APSDOFF_STATUS				BIT(15)
+#define	APSDOFF					BIT(14)
+#define	BBRSTN					BIT(13)
+#define	BB_GLB_RSTN				BIT(12)
+#define	SCHEDULE_EN				BIT(10)
+#define	MACRXEN					BIT(9)
+#define	MACTXEN					BIT(8)
+#define	DDMA_EN					BIT(7)
+#define	FW2HW_EN				BIT(6)
+#define	RXDMA_EN				BIT(5)
+#define	TXDMA_EN				BIT(4)
+#define	HCI_RXDMA_EN				BIT(3)
+#define	HCI_TXDMA_EN				BIT(2)
+
+#define	StopHCCA				BIT(6)
+#define	StopHigh				BIT(5)
+#define	StopMgt					BIT(4)
+#define	StopVO					BIT(3)
+#define	StopVI					BIT(2)
+#define	StopBE					BIT(1)
+#define	StopBK					BIT(0)
+
+#define	LBK_NORMAL				0x00
+#define	LBK_MAC_LB				(BIT(0) | BIT(1) | BIT(3))
+#define	LBK_MAC_DLB				(BIT(0) | BIT(1))
+#define	LBK_DMA_LB				(BIT(0) | BIT(1) | BIT(2))
+
+#define	TCP_OFDL_EN				BIT(25)
+#define	HWPC_TX_EN				BIT(24)
+#define	TXDMAPRE2FULL				BIT(23)
+#define	DISCW					BIT(20)
+#define	TCRICV					BIT(19)
+#define	CfendForm				BIT(17)
+#define	TCRCRC					BIT(16)
+#define	FAKE_IMEM_EN				BIT(15)
+#define	TSFRST					BIT(9)
+#define	TSFEN					BIT(8)
+#define	FWALLRDY				(BIT(0) | BIT(1) | BIT(2) | \
+						BIT(3) | BIT(4) | BIT(5) | \
+						BIT(6) | BIT(7))
+#define	FWRDY					BIT(7)
+#define	BASECHG					BIT(6)
+#define	IMEM					BIT(5)
+#define	DMEM_CODE_DONE				BIT(4)
+#define	EXT_IMEM_CHK_RPT			BIT(3)
+#define	EXT_IMEM_CODE_DONE			BIT(2)
+#define	IMEM_CHK_RPT				BIT(1)
+#define	IMEM_CODE_DONE				BIT(0)
+#define	IMEM_CODE_DONE				BIT(0)
+#define	IMEM_CHK_RPT				BIT(1)
+#define	EMEM_CODE_DONE				BIT(2)
+#define	EMEM_CHK_RPT				BIT(3)
+#define	DMEM_CODE_DONE				BIT(4)
+#define	IMEM_RDY				BIT(5)
+#define	BASECHG					BIT(6)
+#define	FWRDY					BIT(7)
+#define	LOAD_FW_READY				(IMEM_CODE_DONE | \
+						IMEM_CHK_RPT | \
+						EMEM_CODE_DONE | \
+						EMEM_CHK_RPT | \
+						DMEM_CODE_DONE | \
+						IMEM_RDY | \
+						BASECHG | \
+						FWRDY)
+#define	TCR_TSFEN				BIT(8)
+#define	TCR_TSFRST				BIT(9)
+#define	TCR_FAKE_IMEM_EN			BIT(15)
+#define	TCR_CRC					BIT(16)
+#define	TCR_ICV					BIT(19)
+#define	TCR_DISCW				BIT(20)
+#define	TCR_HWPC_TX_EN				BIT(24)
+#define	TCR_TCP_OFDL_EN				BIT(25)
+#define	TXDMA_INIT_VALUE			(IMEM_CHK_RPT | \
+						EXT_IMEM_CHK_RPT)
+
+#define	RCR_APPFCS				BIT(31)
+#define	RCR_DIS_ENC_2BYTE			BIT(30)
+#define	RCR_DIS_AES_2BYTE			BIT(29)
+#define	RCR_HTC_LOC_CTRL			BIT(28)
+#define	RCR_ENMBID				BIT(27)
+#define	RCR_RX_TCPOFDL_EN			BIT(26)
+#define	RCR_APP_PHYST_RXFF			BIT(25)
+#define	RCR_APP_PHYST_STAFF			BIT(24)
+#define	RCR_CBSSID				BIT(23)
+#define	RCR_APWRMGT				BIT(22)
+#define	RCR_ADD3				BIT(21)
+#define	RCR_AMF					BIT(20)
+#define	RCR_ACF					BIT(19)
+#define	RCR_ADF					BIT(18)
+#define	RCR_APP_MIC				BIT(17)
+#define	RCR_APP_ICV				BIT(16)
+#define	RCR_RXFTH				BIT(13)
+#define	RCR_AICV				BIT(12)
+#define	RCR_RXDESC_LK_EN			BIT(11)
+#define	RCR_APP_BA_SSN				BIT(6)
+#define	RCR_ACRC32				BIT(5)
+#define	RCR_RXSHFT_EN				BIT(4)
+#define	RCR_AB					BIT(3)
+#define	RCR_AM					BIT(2)
+#define	RCR_APM					BIT(1)
+#define	RCR_AAP					BIT(0)
+#define	RCR_MXDMA_OFFSET			8
+#define	RCR_FIFO_OFFSET				13
+
+
+#define MSR_LINK_MASK				((1 << 0) | (1 << 1))
+#define MSR_LINK_MANAGED			2
+#define MSR_LINK_NONE				0
+#define MSR_LINK_SHIFT				0
+#define MSR_LINK_ADHOC				1
+#define MSR_LINK_MASTER				3
+#define	MSR_NOLINK				0x00
+#define	MSR_ADHOC				0x01
+#define	MSR_INFRA				0x02
+#define	MSR_AP					0x03
+
+#define	ENUART					BIT(7)
+#define	ENJTAG					BIT(3)
+#define	BTMODE					(BIT(2) | BIT(1))
+#define	ENBT					BIT(0)
+
+#define	ENMBID					BIT(7)
+#define	BCNUM					(BIT(6) | BIT(5) | BIT(4))
+
+#define	USTIME_EDCA				0xFF00
+#define	USTIME_TSF				0x00FF
+
+#define	SIFS_TRX				0xFF00
+#define	SIFS_CTX				0x00FF
+
+#define	ENSWBCN					BIT(15)
+#define	DRVERLY_TU				0x0FF0
+#define	DRVERLY_US				0x000F
+#define	BCN_TCFG_CW_SHIFT			8
+#define	BCN_TCFG_IFS				0
+
+#define	RRSR_RSC_OFFSET				21
+#define	RRSR_SHORT_OFFSET			23
+#define	RRSR_RSC_BW_40M				0x600000
+#define	RRSR_RSC_UPSUBCHNL			0x400000
+#define	RRSR_RSC_LOWSUBCHNL			0x200000
+#define	RRSR_SHORT				0x800000
+#define	RRSR_1M					BIT(0)
+#define	RRSR_2M					BIT(1)
+#define	RRSR_5_5M				BIT(2)
+#define	RRSR_11M				BIT(3)
+#define	RRSR_6M					BIT(4)
+#define	RRSR_9M					BIT(5)
+#define	RRSR_12M				BIT(6)
+#define	RRSR_18M				BIT(7)
+#define	RRSR_24M				BIT(8)
+#define	RRSR_36M				BIT(9)
+#define	RRSR_48M				BIT(10)
+#define	RRSR_54M				BIT(11)
+#define	RRSR_MCS0				BIT(12)
+#define	RRSR_MCS1				BIT(13)
+#define	RRSR_MCS2				BIT(14)
+#define	RRSR_MCS3				BIT(15)
+#define	RRSR_MCS4				BIT(16)
+#define	RRSR_MCS5				BIT(17)
+#define	RRSR_MCS6				BIT(18)
+#define	RRSR_MCS7				BIT(19)
+#define	BRSR_AckShortPmb			BIT(23)
+
+#define	RATR_1M					0x00000001
+#define	RATR_2M					0x00000002
+#define	RATR_55M				0x00000004
+#define	RATR_11M				0x00000008
+#define	RATR_6M					0x00000010
+#define	RATR_9M					0x00000020
+#define	RATR_12M				0x00000040
+#define	RATR_18M				0x00000080
+#define	RATR_24M				0x00000100
+#define	RATR_36M				0x00000200
+#define	RATR_48M				0x00000400
+#define	RATR_54M				0x00000800
+#define	RATR_MCS0				0x00001000
+#define	RATR_MCS1				0x00002000
+#define	RATR_MCS2				0x00004000
+#define	RATR_MCS3				0x00008000
+#define	RATR_MCS4				0x00010000
+#define	RATR_MCS5				0x00020000
+#define	RATR_MCS6				0x00040000
+#define	RATR_MCS7				0x00080000
+#define	RATR_MCS8				0x00100000
+#define	RATR_MCS9				0x00200000
+#define	RATR_MCS10				0x00400000
+#define	RATR_MCS11				0x00800000
+#define	RATR_MCS12				0x01000000
+#define	RATR_MCS13				0x02000000
+#define	RATR_MCS14				0x04000000
+#define	RATR_MCS15				0x08000000
+
+#define	RATE_ALL_CCK				(RATR_1M | RATR_2M | \
+						RATR_55M | RATR_11M)
+#define	RATE_ALL_OFDM_AG			(RATR_6M | RATR_9M | \
+						RATR_12M | RATR_18M | \
+						RATR_24M | RATR_36M | \
+						RATR_48M | RATR_54M)
+#define	RATE_ALL_OFDM_1SS			(RATR_MCS0 | RATR_MCS1 | \
+						RATR_MCS2 | RATR_MCS3 | \
+						RATR_MCS4 | RATR_MCS5 | \
+						RATR_MCS6 | RATR_MCS7)
+#define	RATE_ALL_OFDM_2SS			(RATR_MCS8 | RATR_MCS9 | \
+						RATR_MCS10 | RATR_MCS11 | \
+						RATR_MCS12 | RATR_MCS13 | \
+						RATR_MCS14 | RATR_MCS15)
+
+#define	AC_PARAM_TXOP_LIMIT_OFFSET		16
+#define	AC_PARAM_ECW_MAX_OFFSET			12
+#define	AC_PARAM_ECW_MIN_OFFSET			8
+#define	AC_PARAM_AIFS_OFFSET			0
+
+#define	AcmHw_HwEn				BIT(0)
+#define	AcmHw_BeqEn				BIT(1)
+#define	AcmHw_ViqEn				BIT(2)
+#define	AcmHw_VoqEn				BIT(3)
+#define	AcmHw_BeqStatus				BIT(4)
+#define	AcmHw_ViqStatus				BIT(5)
+#define	AcmHw_VoqStatus				BIT(6)
+
+#define	RETRY_LIMIT_SHORT_SHIFT			8
+#define	RETRY_LIMIT_LONG_SHIFT			0
+
+#define	NAV_UPPER_EN				BIT(16)
+#define	NAV_UPPER				0xFF00
+#define	NAV_RTSRST				0xFF
+
+#define	BW_OPMODE_20MHZ				BIT(2)
+#define	BW_OPMODE_5G				BIT(1)
+#define	BW_OPMODE_11J				BIT(0)
+
+#define	RXERR_RPT_RST				BIT(27)
+#define	RXERR_OFDM_PPDU				0
+#define	RXERR_OFDM_FALSE_ALARM			1
+#define	RXERR_OFDM_MPDU_OK			2
+#define	RXERR_OFDM_MPDU_FAIL			3
+#define	RXERR_CCK_PPDU				4
+#define	RXERR_CCK_FALSE_ALARM			5
+#define	RXERR_CCK_MPDU_OK			6
+#define	RXERR_CCK_MPDU_FAIL			7
+#define	RXERR_HT_PPDU				8
+#define	RXERR_HT_FALSE_ALARM			9
+#define	RXERR_HT_MPDU_TOTAL			10
+#define	RXERR_HT_MPDU_OK			11
+#define	RXERR_HT_MPDU_FAIL			12
+#define	RXERR_RX_FULL_DROP			15
+
+#define	SCR_TXUSEDK				BIT(0)
+#define	SCR_RXUSEDK				BIT(1)
+#define	SCR_TXENCENABLE				BIT(2)
+#define	SCR_RXENCENABLE				BIT(3)
+#define	SCR_SKBYA2				BIT(4)
+#define	SCR_NOSKMC				BIT(5)
+
+#define	CAM_VALID				BIT(15)
+#define	CAM_NOTVALID				0x0000
+#define	CAM_USEDK				BIT(5)
+
+#define	CAM_NONE				0x0
+#define	CAM_WEP40				0x01
+#define	CAM_TKIP				0x02
+#define	CAM_AES					0x04
+#define	CAM_WEP104				0x05
+
+#define	TOTAL_CAM_ENTRY				32
+#define	HALF_CAM_ENTRY				16
+
+#define	CAM_WRITE				BIT(16)
+#define	CAM_READ				0x00000000
+#define	CAM_POLLINIG				BIT(31)
+
+#define	WOW_PMEN				BIT(0)
+#define	WOW_WOMEN				BIT(1)
+#define	WOW_MAGIC				BIT(2)
+#define	WOW_UWF					BIT(3)
+
+#define	GPIOMUX_EN				BIT(3)
+#define	GPIOSEL_GPIO				0
+#define	GPIOSEL_PHYDBG				1
+#define	GPIOSEL_BT				2
+#define	GPIOSEL_WLANDBG				3
+#define	GPIOSEL_GPIO_MASK			(~(BIT(0)|BIT(1)))
+
+#define	HST_RDBUSY				BIT(0)
+#define	CPU_WTBUSY				BIT(1)
+
+#define	IMR8190_DISABLED			0x0
+#define	IMR_CPUERR				BIT(5)
+#define	IMR_ATIMEND				BIT(4)
+#define	IMR_TBDOK				BIT(3)
+#define	IMR_TBDER				BIT(2)
+#define	IMR_BCNDMAINT8				BIT(1)
+#define	IMR_BCNDMAINT7				BIT(0)
+#define	IMR_BCNDMAINT6				BIT(31)
+#define	IMR_BCNDMAINT5				BIT(30)
+#define	IMR_BCNDMAINT4				BIT(29)
+#define	IMR_BCNDMAINT3				BIT(28)
+#define	IMR_BCNDMAINT2				BIT(27)
+#define	IMR_BCNDMAINT1				BIT(26)
+#define	IMR_BCNDOK8				BIT(25)
+#define	IMR_BCNDOK7				BIT(24)
+#define	IMR_BCNDOK6				BIT(23)
+#define	IMR_BCNDOK5				BIT(22)
+#define	IMR_BCNDOK4				BIT(21)
+#define	IMR_BCNDOK3				BIT(20)
+#define	IMR_BCNDOK2				BIT(19)
+#define	IMR_BCNDOK1				BIT(18)
+#define	IMR_TIMEOUT2				BIT(17)
+#define	IMR_TIMEOUT1				BIT(16)
+#define	IMR_TXFOVW				BIT(15)
+#define	IMR_PSTIMEOUT				BIT(14)
+#define	IMR_BCNINT				BIT(13)
+#define	IMR_RXFOVW				BIT(12)
+#define	IMR_RDU					BIT(11)
+#define	IMR_RXCMDOK				BIT(10)
+#define	IMR_BDOK				BIT(9)
+#define	IMR_HIGHDOK				BIT(8)
+#define	IMR_COMDOK				BIT(7)
+#define	IMR_MGNTDOK				BIT(6)
+#define	IMR_HCCADOK				BIT(5)
+#define	IMR_BKDOK				BIT(4)
+#define	IMR_BEDOK				BIT(3)
+#define	IMR_VIDOK				BIT(2)
+#define	IMR_VODOK				BIT(1)
+#define	IMR_ROK					BIT(0)
+
+#define	TPPOLL_BKQ				BIT(0)
+#define	TPPOLL_BEQ				BIT(1)
+#define	TPPOLL_VIQ				BIT(2)
+#define	TPPOLL_VOQ				BIT(3)
+#define	TPPOLL_BQ				BIT(4)
+#define	TPPOLL_CQ				BIT(5)
+#define	TPPOLL_MQ				BIT(6)
+#define	TPPOLL_HQ				BIT(7)
+#define	TPPOLL_HCCAQ				BIT(8)
+#define	TPPOLL_STOPBK				BIT(9)
+#define	TPPOLL_STOPBE				BIT(10)
+#define	TPPOLL_STOPVI				BIT(11)
+#define	TPPOLL_STOPVO				BIT(12)
+#define	TPPOLL_STOPMGT				BIT(13)
+#define	TPPOLL_STOPHIGH				BIT(14)
+#define	TPPOLL_STOPHCCA				BIT(15)
+#define	TPPOLL_SHIFT				8
+
+#define	CCX_CMD_CLM_ENABLE			BIT(0)
+#define	CCX_CMD_NHM_ENABLE			BIT(1)
+#define	CCX_CMD_FUNCTION_ENABLE			BIT(8)
+#define	CCX_CMD_IGNORE_CCA			BIT(9)
+#define	CCX_CMD_IGNORE_TXON			BIT(10)
+#define	CCX_CLM_RESULT_READY			BIT(16)
+#define	CCX_NHM_RESULT_READY			BIT(16)
+#define	CCX_CMD_RESET				0x0
+
+
+#define	HWSET_MAX_SIZE_92S			128
+#define EFUSE_MAX_SECTION			16
+#define EFUSE_REAL_CONTENT_LEN			512
+
+#define RTL8190_EEPROM_ID			0x8129
+#define EEPROM_HPON				0x02
+#define EEPROM_CLK				0x06
+#define EEPROM_TESTR				0x08
+
+#define EEPROM_VID				0x0A
+#define EEPROM_DID				0x0C
+#define EEPROM_SVID				0x0E
+#define EEPROM_SMID				0x10
+
+#define EEPROM_MAC_ADDR				0x12
+#define EEPROM_NODE_ADDRESS_BYTE_0		0x12
+
+#define EEPROM_PWDIFF				0x54
+
+#define EEPROM_TXPOWERBASE			0x50
+#define	EEPROM_TX_PWR_INDEX_RANGE		28
+
+#define EEPROM_TX_PWR_HT20_DIFF			0x62
+#define DEFAULT_HT20_TXPWR_DIFF			2
+#define EEPROM_TX_PWR_OFDM_DIFF			0x65
+
+#define	EEPROM_TXPWRGROUP			0x67
+#define EEPROM_REGULATORY			0x6D
+
+#define TX_PWR_SAFETY_CHK			0x6D
+#define EEPROM_TXPWINDEX_CCK_24G		0x5D
+#define EEPROM_TXPWINDEX_OFDM_24G		0x6B
+#define EEPROM_HT2T_CH1_A			0x6c
+#define EEPROM_HT2T_CH7_A			0x6d
+#define EEPROM_HT2T_CH13_A			0x6e
+#define EEPROM_HT2T_CH1_B			0x6f
+#define EEPROM_HT2T_CH7_B			0x70
+#define EEPROM_HT2T_CH13_B			0x71
+
+#define EEPROM_TSSI_A				0x74
+#define EEPROM_TSSI_B				0x75
+
+#define	EEPROM_RFIND_POWERDIFF			0x76
+#define	EEPROM_DEFAULT_LEGACYHTTXPOWERDIFF	0x3
+
+#define EEPROM_THERMALMETER			0x77
+#define	EEPROM_BLUETOOTH_COEXIST		0x78
+#define	EEPROM_BLUETOOTH_TYPE			0x4f
+
+#define	EEPROM_OPTIONAL				0x78
+#define	EEPROM_WOWLAN				0x78
+
+#define EEPROM_CRYSTALCAP			0x79
+#define EEPROM_CHANNELPLAN			0x7B
+#define EEPROM_VERSION				0x7C
+#define	EEPROM_CUSTOMID				0x7A
+#define EEPROM_BOARDTYPE			0x7E
+
+#define	EEPROM_CHANNEL_PLAN_FCC			0x0
+#define	EEPROM_CHANNEL_PLAN_IC			0x1
+#define	EEPROM_CHANNEL_PLAN_ETSI		0x2
+#define	EEPROM_CHANNEL_PLAN_SPAIN		0x3
+#define	EEPROM_CHANNEL_PLAN_FRANCE		0x4
+#define	EEPROM_CHANNEL_PLAN_MKK			0x5
+#define	EEPROM_CHANNEL_PLAN_MKK1		0x6
+#define	EEPROM_CHANNEL_PLAN_ISRAEL		0x7
+#define	EEPROM_CHANNEL_PLAN_TELEC		0x8
+#define	EEPROM_CHANNEL_PLAN_GLOBAL_DOMAIN	0x9
+#define	EEPROM_CHANNEL_PLAN_WORLD_WIDE_13	0xA
+#define	EEPROM_CHANNEL_PLAN_NCC			0xB
+#define	EEPROM_CHANNEL_PLAN_BY_HW_MASK		0x80
+
+#define	FW_DIG_DISABLE				0xfd00cc00
+#define	FW_DIG_ENABLE				0xfd000000
+#define	FW_DIG_HALT				0xfd000001
+#define	FW_DIG_RESUME				0xfd000002
+#define	FW_HIGH_PWR_DISABLE			0xfd000008
+#define	FW_HIGH_PWR_ENABLE			0xfd000009
+#define	FW_ADD_A2_ENTRY				0xfd000016
+#define	FW_TXPWR_TRACK_ENABLE			0xfd000017
+#define	FW_TXPWR_TRACK_DISABLE			0xfd000018
+#define	FW_TXPWR_TRACK_THERMAL			0xfd000019
+#define	FW_TXANT_SWITCH_ENABLE			0xfd000023
+#define	FW_TXANT_SWITCH_DISABLE			0xfd000024
+#define	FW_RA_INIT				0xfd000026
+#define	FW_CTRL_DM_BY_DRIVER			0Xfd00002a
+#define	FW_RA_IOT_BG_COMB			0xfd000030
+#define	FW_RA_IOT_N_COMB			0xfd000031
+#define	FW_RA_REFRESH				0xfd0000a0
+#define	FW_RA_UPDATE_MASK			0xfd0000a2
+#define	FW_RA_DISABLE				0xfd0000a4
+#define	FW_RA_ACTIVE				0xfd0000a6
+#define	FW_RA_DISABLE_RSSI_MASK			0xfd0000ac
+#define	FW_RA_ENABLE_RSSI_MASK			0xfd0000ad
+#define	FW_RA_RESET				0xfd0000af
+#define	FW_DM_DISABLE				0xfd00aa00
+#define	FW_IQK_ENABLE				0xf0000020
+#define	FW_IQK_SUCCESS				0x0000dddd
+#define	FW_IQK_FAIL				0x0000ffff
+#define	FW_OP_FAILURE				0xffffffff
+#define	FW_TX_FEEDBACK_NONE			0xfb000000
+#define	FW_TX_FEEDBACK_DTM_ENABLE		(FW_TX_FEEDBACK_NONE | 0x1)
+#define	FW_TX_FEEDBACK_CCX_ENABL		(FW_TX_FEEDBACK_NONE | 0x2)
+#define	FW_BB_RESET_ENABLE			0xff00000d
+#define	FW_BB_RESET_DISABLE			0xff00000e
+#define	FW_CCA_CHK_ENABLE			0xff000011
+#define	FW_CCK_RESET_CNT			0xff000013
+#define	FW_LPS_ENTER				0xfe000010
+#define	FW_LPS_LEAVE				0xfe000011
+#define	FW_INDIRECT_READ			0xf2000000
+#define	FW_INDIRECT_WRITE			0xf2000001
+#define	FW_CHAN_SET				0xf3000001
+
+#define RFPC					0x5F
+#define RCR_9356SEL				BIT(6)
+#define TCR_LRL_OFFSET				0
+#define TCR_SRL_OFFSET				8
+#define TCR_MXDMA_OFFSET			21
+#define TCR_SAT					BIT(24)
+#define RCR_MXDMA_OFFSET			8
+#define RCR_FIFO_OFFSET				13
+#define RCR_OnlyErlPkt				BIT(31)
+#define CWR					0xDC
+#define RETRYCTR				0xDE
+
+#define CPU_GEN_SYSTEM_RESET			0x00000001
+
+#define	CCX_COMMAND_REG				0x890
+#define	CLM_PERIOD_REG				0x894
+#define	NHM_PERIOD_REG				0x896
+
+#define	NHM_THRESHOLD0				0x898
+#define	NHM_THRESHOLD1				0x899
+#define	NHM_THRESHOLD2				0x89A
+#define	NHM_THRESHOLD3				0x89B
+#define	NHM_THRESHOLD4				0x89C
+#define	NHM_THRESHOLD5				0x89D
+#define	NHM_THRESHOLD6				0x89E
+#define	CLM_RESULT_REG				0x8D0
+#define	NHM_RESULT_REG				0x8D4
+#define	NHM_RPI_COUNTER0			0x8D8
+#define	NHM_RPI_COUNTER1			0x8D9
+#define	NHM_RPI_COUNTER2			0x8DA
+#define	NHM_RPI_COUNTER3			0x8DB
+#define	NHM_RPI_COUNTER4			0x8DC
+#define	NHM_RPI_COUNTER5			0x8DD
+#define	NHM_RPI_COUNTER6			0x8DE
+#define	NHM_RPI_COUNTER7			0x8DF
+
+#define	HAL_8192S_HW_GPIO_OFF_BIT		BIT(3)
+#define	HAL_8192S_HW_GPIO_OFF_MASK		0xF7
+#define	HAL_8192S_HW_GPIO_WPS_BIT		BIT(4)
+
+#define	RPMAC_RESET				0x100
+#define	RPMAC_TXSTART				0x104
+#define	RPMAC_TXLEGACYSIG			0x108
+#define	RPMAC_TXHTSIG1				0x10c
+#define	RPMAC_TXHTSIG2				0x110
+#define	RPMAC_PHYDEBUG				0x114
+#define	RPMAC_TXPACKETNNM			0x118
+#define	RPMAC_TXIDLE				0x11c
+#define	RPMAC_TXMACHEADER0			0x120
+#define	RPMAC_TXMACHEADER1			0x124
+#define	RPMAC_TXMACHEADER2			0x128
+#define	RPMAC_TXMACHEADER3			0x12c
+#define	RPMAC_TXMACHEADER4			0x130
+#define	RPMAC_TXMACHEADER5			0x134
+#define	RPMAC_TXDATATYPE			0x138
+#define	RPMAC_TXRANDOMSEED			0x13c
+#define	RPMAC_CCKPLCPPREAMBLE			0x140
+#define	RPMAC_CCKPLCPHEADER			0x144
+#define	RPMAC_CCKCRC16				0x148
+#define	RPMAC_OFDMRXCRC32OK			0x170
+#define	RPMAC_OFDMRXCRC32ER			0x174
+#define	RPMAC_OFDMRXPARITYER			0x178
+#define	RPMAC_OFDMRXCRC8ER			0x17c
+#define	RPMAC_CCKCRXRC16ER			0x180
+#define	RPMAC_CCKCRXRC32ER			0x184
+#define	RPMAC_CCKCRXRC32OK			0x188
+#define	RPMAC_TXSTATUS				0x18c
+
+#define	RF_BB_CMD_ADDR				0x02c0
+#define	RF_BB_CMD_DATA				0x02c4
+
+#define	RFPGA0_RFMOD				0x800
+
+#define	RFPGA0_TXINFO				0x804
+#define	RFPGA0_PSDFUNCTION			0x808
+
+#define	RFPGA0_TXGAINSTAGE			0x80c
+
+#define	RFPGA0_RFTIMING1			0x810
+#define	RFPGA0_RFTIMING2			0x814
+#define	RFPGA0_XA_HSSIPARAMETER1		0x820
+#define	RFPGA0_XA_HSSIPARAMETER2		0x824
+#define	RFPGA0_XB_HSSIPARAMETER1		0x828
+#define	RFPGA0_XB_HSSIPARAMETER2		0x82c
+#define	RFPGA0_XC_HSSIPARAMETER1		0x830
+#define	RFPGA0_XC_HSSIPARAMETER2		0x834
+#define	RFPGA0_XD_HSSIPARAMETER1		0x838
+#define	RFPGA0_XD_HSSIPARAMETER2		0x83c
+#define	RFPGA0_XA_LSSIPARAMETER			0x840
+#define	RFPGA0_XB_LSSIPARAMETER			0x844
+#define	RFPGA0_XC_LSSIPARAMETER			0x848
+#define	RFPGA0_XD_LSSIPARAMETER			0x84c
+
+#define	RFPGA0_RFWAKEUP_PARAMETER		0x850
+#define	RFPGA0_RFSLEEPUP_PARAMETER		0x854
+
+#define	RFPGA0_XAB_SWITCHCONTROL		0x858
+#define	RFPGA0_XCD_SWITCHCONTROL		0x85c
+
+#define	RFPGA0_XA_RFINTERFACEOE			0x860
+#define	RFPGA0_XB_RFINTERFACEOE			0x864
+#define	RFPGA0_XC_RFINTERFACEOE			0x868
+#define	RFPGA0_XD_RFINTERFACEOE			0x86c
+
+#define	RFPGA0_XAB_RFINTERFACESW		0x870
+#define	RFPGA0_XCD_RFINTERFACESW		0x874
+
+#define	RFPGA0_XAB_RFPARAMETER			0x878
+#define	RFPGA0_XCD_RFPARAMETER			0x87c
+
+#define	RFPGA0_ANALOGPARAMETER1			0x880
+#define	RFPGA0_ANALOGPARAMETER2			0x884
+#define	RFPGA0_ANALOGPARAMETER3			0x888
+#define	RFPGA0_ANALOGPARAMETER4			0x88c
+
+#define	RFPGA0_XA_LSSIREADBACK			0x8a0
+#define	RFPGA0_XB_LSSIREADBACK			0x8a4
+#define	RFPGA0_XC_LSSIREADBACK			0x8a8
+#define	RFPGA0_XD_LSSIREADBACK			0x8ac
+
+#define	RFPGA0_PSDREPORT			0x8b4
+#define	TRANSCEIVERA_HSPI_READBACK		0x8b8
+#define	TRANSCEIVERB_HSPI_READBACK		0x8bc
+#define	RFPGA0_XAB_RFINTERFACERB		0x8e0
+#define	RFPGA0_XCD_RFINTERFACERB		0x8e4
+#define	RFPGA1_RFMOD				0x900
+
+#define	RFPGA1_TXBLOCK				0x904
+#define	RFPGA1_DEBUGSELECT			0x908
+#define	RFPGA1_TXINFO				0x90c
+
+#define	RCCK0_SYSTEM				0xa00
+
+#define	RCCK0_AFESETTING			0xa04
+#define	RCCK0_CCA				0xa08
+
+#define	RCCK0_RXAGC1				0xa0c
+#define	RCCK0_RXAGC2				0xa10
+
+#define	RCCK0_RXHP				0xa14
+
+#define	RCCK0_DSPPARAMETER1			0xa18
+#define	RCCK0_DSPPARAMETER2			0xa1c
+
+#define	RCCK0_TXFILTER1				0xa20
+#define	RCCK0_TXFILTER2				0xa24
+#define	RCCK0_DEBUGPORT				0xa28
+#define	RCCK0_FALSEALARMREPORT			0xa2c
+#define	RCCK0_TRSSIREPORT			0xa50
+#define	RCCK0_RXREPORT				0xa54
+#define	RCCK0_FACOUNTERLOWER			0xa5c
+#define	RCCK0_FACOUNTERUPPER			0xa58
+
+#define	ROFDM0_LSTF				0xc00
+
+#define	ROFDM0_TRXPATHENABLE			0xc04
+#define	ROFDM0_TRMUXPAR				0xc08
+#define	ROFDM0_TRSWISOLATION			0xc0c
+
+#define	ROFDM0_XARXAFE				0xc10
+#define	ROFDM0_XARXIQIMBALANCE			0xc14
+#define	ROFDM0_XBRXAFE				0xc18
+#define	ROFDM0_XBRXIQIMBALANCE			0xc1c
+#define	ROFDM0_XCRXAFE				0xc20
+#define	ROFDM0_XCRXIQIMBALANCE			0xc24
+#define	ROFDM0_XDRXAFE				0xc28
+#define	ROFDM0_XDRXIQIMBALANCE			0xc2c
+
+#define	ROFDM0_RXDETECTOR1			0xc30
+#define	ROFDM0_RXDETECTOR2			0xc34
+#define	ROFDM0_RXDETECTOR3			0xc38
+#define	ROFDM0_RXDETECTOR4			0xc3c
+
+#define	ROFDM0_RXDSP				0xc40
+#define	ROFDM0_CFO_AND_DAGC			0xc44
+#define	ROFDM0_CCADROP_THRESHOLD		0xc48
+#define	ROFDM0_ECCA_THRESHOLD			0xc4c
+
+#define	ROFDM0_XAAGCCORE1			0xc50
+#define	ROFDM0_XAAGCCORE2			0xc54
+#define	ROFDM0_XBAGCCORE1			0xc58
+#define	ROFDM0_XBAGCCORE2			0xc5c
+#define	ROFDM0_XCAGCCORE1			0xc60
+#define	ROFDM0_XCAGCCORE2			0xc64
+#define	ROFDM0_XDAGCCORE1			0xc68
+#define	ROFDM0_XDAGCCORE2			0xc6c
+
+#define	ROFDM0_AGCPARAMETER1			0xc70
+#define	ROFDM0_AGCPARAMETER2			0xc74
+#define	ROFDM0_AGCRSSITABLE			0xc78
+#define	ROFDM0_HTSTFAGC				0xc7c
+
+#define	ROFDM0_XATXIQIMBALANCE			0xc80
+#define	ROFDM0_XATXAFE				0xc84
+#define	ROFDM0_XBTXIQIMBALANCE			0xc88
+#define	ROFDM0_XBTXAFE				0xc8c
+#define	ROFDM0_XCTXIQIMBALANCE			0xc90
+#define	ROFDM0_XCTXAFE				0xc94
+#define	ROFDM0_XDTXIQIMBALANCE			0xc98
+#define	ROFDM0_XDTXAFE				0xc9c
+
+#define	ROFDM0_RXHP_PARAMETER			0xce0
+#define	ROFDM0_TXPSEUDO_NOISE_WGT		0xce4
+#define	ROFDM0_FRAME_SYNC			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	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_TRXMESAURE1			0xd34
+#define	ROFDM1_INTF_DET				0xd3c
+#define	ROFDM1_PSEUDO_NOISESTATEAB		0xd50
+#define	ROFDM1_PSEUDO_NOISESTATECD		0xd54
+#define	ROFDM1_RX_PSEUDO_NOISE_WGT		0xd58
+
+#define	ROFDM_PHYCOUNTER1			0xda0
+#define	ROFDM_PHYCOUNTER2			0xda4
+#define	ROFDM_PHYCOUNTER3			0xda8
+
+#define	ROFDM_SHORT_CFOAB			0xdac
+#define	ROFDM_SHORT_CFOCD			0xdb0
+#define	ROFDM_LONG_CFOAB			0xdb4
+#define	ROFDM_LONG_CFOCD			0xdb8
+#define	ROFDM_TAIL_CFOAB			0xdbc
+#define	ROFDM_TAIL_CFOCD			0xdc0
+#define	ROFDM_PW_MEASURE1			0xdc4
+#define	ROFDM_PW_MEASURE2			0xdc8
+#define	ROFDM_BW_REPORT				0xdcc
+#define	ROFDM_AGC_REPORT			0xdd0
+#define	ROFDM_RXSNR				0xdd4
+#define	ROFDM_RXEVMCSI				0xdd8
+#define	ROFDM_SIG_REPORT			0xddc
+
+
+#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
+
+
+#define	RF_AC					0x00
+#define	RF_IQADJ_G1				0x01
+#define	RF_IQADJ_G2				0x02
+#define	RF_POW_TRSW				0x05
+#define	RF_GAIN_RX				0x06
+#define	RF_GAIN_TX				0x07
+#define	RF_TXM_IDAC				0x08
+#define	RF_BS_IQGEN				0x0F
+
+#define	RF_MODE1				0x10
+#define	RF_MODE2				0x11
+#define	RF_RX_AGC_HP				0x12
+#define	RF_TX_AGC				0x13
+#define	RF_BIAS					0x14
+#define	RF_IPA					0x15
+#define	RF_POW_ABILITY				0x17
+#define	RF_MODE_AG				0x18
+#define	RF_CHANNEL				0x18
+#define	RF_CHNLBW				0x18
+#define	RF_TOP					0x19
+#define	RF_RX_G1				0x1A
+#define	RF_RX_G2				0x1B
+#define	RF_RX_BB2				0x1C
+#define	RF_RX_BB1				0x1D
+#define	RF_RCK1					0x1E
+#define	RF_RCK2					0x1F
+
+#define	RF_TX_G1				0x20
+#define	RF_TX_G2				0x21
+#define	RF_TX_G3				0x22
+#define	RF_TX_BB1				0x23
+#define	RF_T_METER				0x24
+#define	RF_SYN_G1				0x25
+#define	RF_SYN_G2				0x26
+#define	RF_SYN_G3				0x27
+#define	RF_SYN_G4				0x28
+#define	RF_SYN_G5				0x29
+#define	RF_SYN_G6				0x2A
+#define	RF_SYN_G7				0x2B
+#define	RF_SYN_G8				0x2C
+
+#define	RF_RCK_OS				0x30
+#define	RF_TXPA_G1				0x31
+#define	RF_TXPA_G2				0x32
+#define	RF_TXPA_G3				0x33
+
+#define	BRFMOD					0x1
+#define	BCCKEN					0x1000000
+#define	BOFDMEN					0x2000000
+
+#define	BXBTXAGC				0xf00
+#define	BXCTXAGC				0xf000
+#define	BXDTXAGC				0xf0000
+
+#define	B3WIRE_DATALENGTH			0x800
+#define	B3WIRE_ADDRESSLENGTH			0x400
+
+#define	BRFSI_RFENV				0x10
+
+#define	BLSSI_READADDRESS			0x7f800000
+#define	BLSSI_READEDGE				0x80000000
+#define	BLSSI_READBACK_DATA			0xfffff
+
+#define	BADCLKPHASE				0x4000000
+
+#define	BCCK_SIDEBAND				0x10
+
+#define	BTX_AGCRATECCK				0x7f00
+
+#define	MASKBYTE0				0xff
+#define	MASKBYTE1				0xff00
+#define	MASKBYTE2				0xff0000
+#define	MASKBYTE3				0xff000000
+#define	MASKHWORD				0xffff0000
+#define	MASKLWORD				0x0000ffff
+#define	MASKDWORD				0xffffffff
+
+#define	MAKS12BITS				0xfffff
+#define	MASK20BITS				0xfffff
+#define RFREG_OFFSET_MASK			0xfffff
+
+#endif
diff -druN linux-2.6.39-libre/drivers/net/wireless/rtlwifi/rtl8192se/rf.c linux-3.0-rc7-libre/drivers/net/wireless/rtlwifi/rtl8192se/rf.c
--- linux-2.6.39-libre/drivers/net/wireless/rtlwifi/rtl8192se/rf.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/net/wireless/rtlwifi/rtl8192se/rf.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,546 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2009-2010  Realtek Corporation.
+ *
+ * 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:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+
+#include "../wifi.h"
+#include "reg.h"
+#include "def.h"
+#include "phy.h"
+#include "rf.h"
+#include "dm.h"
+
+
+static void _rtl92s_get_powerbase(struct ieee80211_hw *hw, u8 *p_pwrlevel,
+				  u8 chnl, u32 *ofdmbase, u32 *mcsbase,
+				  u8 *p_final_pwridx)
+{
+	struct rtl_priv *rtlpriv = rtl_priv(hw);
+	struct rtl_phy *rtlphy = &(rtlpriv->phy);
+	struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
+	u32 pwrbase0, pwrbase1;
+	u8 legacy_pwrdiff = 0, ht20_pwrdiff = 0;
+	u8 i, pwrlevel[4];
+
+	for (i = 0; i < 2; i++)
+		pwrlevel[i] = p_pwrlevel[i];
+
+	/* We only care about the path A for legacy. */
+	if (rtlefuse->eeprom_version < 2) {
+		pwrbase0 = pwrlevel[0] + (rtlefuse->legacy_httxpowerdiff & 0xf);
+	} else if (rtlefuse->eeprom_version >= 2) {
+		legacy_pwrdiff = rtlefuse->txpwr_legacyhtdiff
+						[RF90_PATH_A][chnl - 1];
+
+		/* For legacy OFDM, tx pwr always > HT OFDM pwr.
+		 * We do not care Path B
+		 * legacy OFDM pwr diff. NO BB register
+		 * to notify HW. */
+		pwrbase0 = pwrlevel[0] + legacy_pwrdiff;
+	}
+
+	pwrbase0 = (pwrbase0 << 24) | (pwrbase0 << 16) | (pwrbase0 << 8) |
+		    pwrbase0;
+	*ofdmbase = pwrbase0;
+
+	/* MCS rates */
+	if (rtlefuse->eeprom_version >= 2) {
+		/* Check HT20 to HT40 diff	*/
+		if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20) {
+			for (i = 0; i < 2; i++) {
+				/* rf-A, rf-B */
+				/* HT 20<->40 pwr diff */
+				ht20_pwrdiff = rtlefuse->txpwr_ht20diff
+							[i][chnl - 1];
+
+				if (ht20_pwrdiff < 8) /* 0~+7 */
+					pwrlevel[i] += ht20_pwrdiff;
+				else /* index8-15=-8~-1 */
+					pwrlevel[i] -= (16 - ht20_pwrdiff);
+			}
+		}
+	}
+
+	/* use index of rf-A */
+	pwrbase1 = pwrlevel[0];
+	pwrbase1 = (pwrbase1 << 24) | (pwrbase1 << 16) | (pwrbase1 << 8) |
+				pwrbase1;
+	*mcsbase = pwrbase1;
+
+	/* The following is for Antenna
+	 * diff from Ant-B to Ant-A */
+	p_final_pwridx[0] = pwrlevel[0];
+	p_final_pwridx[1] = pwrlevel[1];
+
+	switch (rtlefuse->eeprom_regulatory) {
+	case 3:
+		/* The following is for calculation
+		 * of the power diff for Ant-B to Ant-A. */
+		if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40) {
+			p_final_pwridx[0] += rtlefuse->pwrgroup_ht40
+						[RF90_PATH_A][
+						chnl - 1];
+			p_final_pwridx[1] += rtlefuse->pwrgroup_ht40
+						[RF90_PATH_B][
+						chnl - 1];
+		} else {
+			p_final_pwridx[0] += rtlefuse->pwrgroup_ht20
+						[RF90_PATH_A][
+						chnl - 1];
+			p_final_pwridx[1] += rtlefuse->pwrgroup_ht20
+						[RF90_PATH_B][
+						chnl - 1];
+		}
+		break;
+	default:
+		break;
+	}
+
+	if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40) {
+		RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, ("40MHz finalpwr_idx "
+			"(A / B) = 0x%x / 0x%x\n", p_final_pwridx[0],
+			p_final_pwridx[1]));
+	} else {
+		RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, ("20MHz finalpwr_idx "
+			"(A / B) = 0x%x / 0x%x\n", p_final_pwridx[0],
+			 p_final_pwridx[1]));
+	}
+}
+
+static void _rtl92s_set_antennadiff(struct ieee80211_hw *hw,
+				    u8 *p_final_pwridx)
+{
+	struct rtl_priv *rtlpriv = rtl_priv(hw);
+	struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
+	struct rtl_phy *rtlphy = &(rtlpriv->phy);
+	char ant_pwr_diff = 0;
+	u32	u4reg_val = 0;
+
+	if (rtlphy->rf_type == RF_2T2R) {
+		ant_pwr_diff = p_final_pwridx[1] - p_final_pwridx[0];
+
+		/* range is from 7~-8,
+		 * index = 0x0~0xf */
+		if (ant_pwr_diff > 7)
+			ant_pwr_diff = 7;
+		if (ant_pwr_diff < -8)
+			ant_pwr_diff = -8;
+
+		RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
+			 ("Antenna Diff from RF-B "
+			"to RF-A = %d (0x%x)\n", ant_pwr_diff,
+			 ant_pwr_diff & 0xf));
+
+		ant_pwr_diff &= 0xf;
+	}
+
+	/* Antenna TX power difference */
+	rtlefuse->antenna_txpwdiff[2] = 0;/* RF-D, don't care */
+	rtlefuse->antenna_txpwdiff[1] = 0;/* RF-C, don't care */
+	rtlefuse->antenna_txpwdiff[0] = (u8)(ant_pwr_diff);	/* RF-B */
+
+	u4reg_val = rtlefuse->antenna_txpwdiff[2] << 8 |
+				rtlefuse->antenna_txpwdiff[1] << 4 |
+				rtlefuse->antenna_txpwdiff[0];
+
+	rtl_set_bbreg(hw, RFPGA0_TXGAINSTAGE, (BXBTXAGC | BXCTXAGC | BXDTXAGC),
+		      u4reg_val);
+
+	RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
+		 ("Write BCD-Diff(0x%x) = 0x%x\n",
+		 RFPGA0_TXGAINSTAGE, u4reg_val));
+}
+
+static void _rtl92s_get_txpower_writeval_byregulatory(struct ieee80211_hw *hw,
+						      u8 chnl, u8 index,
+						      u32 pwrbase0,
+						      u32 pwrbase1,
+						      u32 *p_outwrite_val)
+{
+	struct rtl_priv *rtlpriv = rtl_priv(hw);
+	struct rtl_phy *rtlphy = &(rtlpriv->phy);
+	struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
+	u8 i, chnlgroup, pwrdiff_limit[4];
+	u32 writeval, customer_limit;
+
+	/* Index 0 & 1= legacy OFDM, 2-5=HT_MCS rate */
+	switch (rtlefuse->eeprom_regulatory) {
+	case 0:
+		/* Realtek better performance increase power diff
+		 * defined by Realtek for large power */
+		chnlgroup = 0;
+
+		writeval = rtlphy->mcs_txpwrlevel_origoffset
+				[chnlgroup][index] +
+				((index < 2) ? pwrbase0 : pwrbase1);
+
+		RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
+			 ("RTK better performance, "
+			 "writeval = 0x%x\n", writeval));
+		break;
+	case 1:
+		/* Realtek regulatory increase power diff defined
+		 * by Realtek for regulatory */
+		if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40) {
+			writeval = ((index < 2) ? pwrbase0 : pwrbase1);
+
+			RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
+				 ("Realtek regulatory, "
+				 "40MHz, writeval = 0x%x\n", writeval));
+		} else {
+			if (rtlphy->pwrgroup_cnt == 1)
+				chnlgroup = 0;
+
+			if (rtlphy->pwrgroup_cnt >= 3) {
+				if (chnl <= 3)
+					chnlgroup = 0;
+				else if (chnl >= 4 && chnl <= 8)
+					chnlgroup = 1;
+				else if (chnl > 8)
+					chnlgroup = 2;
+				if (rtlphy->pwrgroup_cnt == 4)
+					chnlgroup++;
+			}
+
+			writeval = rtlphy->mcs_txpwrlevel_origoffset
+					[chnlgroup][index]
+					+ ((index < 2) ?
+					pwrbase0 : pwrbase1);
+
+			RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
+				 ("Realtek regulatory, "
+				 "20MHz, writeval = 0x%x\n", writeval));
+		}
+		break;
+	case 2:
+		/* Better regulatory don't increase any power diff */
+		writeval = ((index < 2) ? pwrbase0 : pwrbase1);
+		RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
+			 ("Better regulatory, "
+			 "writeval = 0x%x\n", writeval));
+		break;
+	case 3:
+		/* Customer defined power diff. increase power diff
+		  defined by customer. */
+		chnlgroup = 0;
+
+		if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40) {
+			RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
+				("customer's limit, 40MHz = 0x%x\n",
+				rtlefuse->pwrgroup_ht40
+				[RF90_PATH_A][chnl - 1]));
+		} else {
+			RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
+				("customer's limit, 20MHz = 0x%x\n",
+				rtlefuse->pwrgroup_ht20
+				[RF90_PATH_A][chnl - 1]));
+		}
+
+		for (i = 0; i < 4; i++) {
+			pwrdiff_limit[i] =
+				(u8)((rtlphy->mcs_txpwrlevel_origoffset
+				[chnlgroup][index] & (0x7f << (i * 8)))
+				>> (i * 8));
+
+			if (rtlphy->current_chan_bw ==
+			    HT_CHANNEL_WIDTH_20_40) {
+				if (pwrdiff_limit[i] >
+				    rtlefuse->pwrgroup_ht40
+				    [RF90_PATH_A][chnl - 1]) {
+					pwrdiff_limit[i] =
+					  rtlefuse->pwrgroup_ht20
+					  [RF90_PATH_A][chnl - 1];
+				}
+			} else {
+				if (pwrdiff_limit[i] >
+				    rtlefuse->pwrgroup_ht20
+				    [RF90_PATH_A][chnl - 1]) {
+					pwrdiff_limit[i] =
+					    rtlefuse->pwrgroup_ht20
+					    [RF90_PATH_A][chnl - 1];
+				}
+			}
+		}
+
+		customer_limit = (pwrdiff_limit[3] << 24) |
+				(pwrdiff_limit[2] << 16) |
+				(pwrdiff_limit[1] << 8) |
+				(pwrdiff_limit[0]);
+		RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
+			 ("Customer's limit = 0x%x\n",
+			 customer_limit));
+
+		writeval = customer_limit + ((index < 2) ?
+					     pwrbase0 : pwrbase1);
+		RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
+			 ("Customer, writeval = "
+			 "0x%x\n", writeval));
+		break;
+	default:
+		chnlgroup = 0;
+		writeval = rtlphy->mcs_txpwrlevel_origoffset[chnlgroup][index] +
+				((index < 2) ? pwrbase0 : pwrbase1);
+		RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
+			 ("RTK better performance, "
+			 "writeval = 0x%x\n", writeval));
+		break;
+	}
+
+	if (rtlpriv->dm.dynamic_txhighpower_lvl == TX_HIGH_PWR_LEVEL_LEVEL1)
+		writeval = 0x10101010;
+	else if (rtlpriv->dm.dynamic_txhighpower_lvl ==
+		 TX_HIGH_PWR_LEVEL_LEVEL2)
+		writeval = 0x0;
+
+	*p_outwrite_val = writeval;
+
+}
+
+static void _rtl92s_write_ofdm_powerreg(struct ieee80211_hw *hw,
+					u8 index, u32 val)
+{
+	struct rtl_priv *rtlpriv = rtl_priv(hw);
+	struct rtl_phy *rtlphy = &(rtlpriv->phy);
+	struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
+	u16 regoffset[6] = {0xe00, 0xe04, 0xe10, 0xe14, 0xe18, 0xe1c};
+	u8 i, rfa_pwr[4];
+	u8 rfa_lower_bound = 0, rfa_upper_bound = 0, rf_pwr_diff = 0;
+	u32 writeval = val;
+
+	/* If path A and Path B coexist, we must limit Path A tx power.
+	 * Protect Path B pwr over or under flow. We need to calculate
+	 * upper and lower bound of path A tx power. */
+	if (rtlphy->rf_type == RF_2T2R) {
+		rf_pwr_diff = rtlefuse->antenna_txpwdiff[0];
+
+		/* Diff=-8~-1 */
+		if (rf_pwr_diff >= 8) {
+			/* Prevent underflow!! */
+			rfa_lower_bound = 0x10 - rf_pwr_diff;
+		/* if (rf_pwr_diff >= 0) Diff = 0-7 */
+		} else {
+			rfa_upper_bound = RF6052_MAX_TX_PWR - rf_pwr_diff;
+		}
+	}
+
+	for (i = 0; i < 4; i++) {
+		rfa_pwr[i] = (u8)((writeval & (0x7f << (i * 8))) >> (i * 8));
+		if (rfa_pwr[i]  > RF6052_MAX_TX_PWR)
+			rfa_pwr[i]  = RF6052_MAX_TX_PWR;
+
+		/* If path A and Path B coexist, we must limit Path A tx power.
+		 * Protect Path B pwr over or under flow. We need to calculate
+		 * upper and lower bound of path A tx power. */
+		if (rtlphy->rf_type == RF_2T2R) {
+			/* Diff=-8~-1 */
+			if (rf_pwr_diff >= 8) {
+				/* Prevent underflow!! */
+				if (rfa_pwr[i] < rfa_lower_bound)
+					rfa_pwr[i] = rfa_lower_bound;
+			/* Diff = 0-7 */
+			} else if (rf_pwr_diff >= 1) {
+				/* Prevent overflow */
+				if (rfa_pwr[i] > rfa_upper_bound)
+					rfa_pwr[i] = rfa_upper_bound;
+			}
+		}
+
+	}
+
+	writeval = (rfa_pwr[3] << 24) | (rfa_pwr[2] << 16) | (rfa_pwr[1] << 8) |
+				rfa_pwr[0];
+
+	rtl_set_bbreg(hw, regoffset[index], 0x7f7f7f7f, writeval);
+}
+
+void rtl92s_phy_rf6052_set_ofdmtxpower(struct ieee80211_hw *hw,
+				       u8 *p_pwrlevel, u8 chnl)
+{
+	u32 writeval, pwrbase0, pwrbase1;
+	u8 index = 0;
+	u8 finalpwr_idx[4];
+
+	_rtl92s_get_powerbase(hw, p_pwrlevel, chnl, &pwrbase0, &pwrbase1,
+			&finalpwr_idx[0]);
+	_rtl92s_set_antennadiff(hw, &finalpwr_idx[0]);
+
+	for (index = 0; index < 6; index++) {
+		_rtl92s_get_txpower_writeval_byregulatory(hw, chnl, index,
+				pwrbase0, pwrbase1, &writeval);
+
+		_rtl92s_write_ofdm_powerreg(hw, index, writeval);
+	}
+}
+
+void rtl92s_phy_rf6052_set_ccktxpower(struct ieee80211_hw *hw, u8 pwrlevel)
+{
+	struct rtl_priv *rtlpriv = rtl_priv(hw);
+	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+	struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
+	u32 txagc = 0;
+	bool dont_inc_cck_or_turboscanoff = false;
+
+	if (((rtlefuse->eeprom_version >= 2) &&
+	      (rtlefuse->txpwr_safetyflag == 1)) ||
+	      ((rtlefuse->eeprom_version >= 2) &&
+	      (rtlefuse->eeprom_regulatory != 0)))
+		dont_inc_cck_or_turboscanoff = true;
+
+	if (mac->act_scanning == true) {
+		txagc = 0x3f;
+		if (dont_inc_cck_or_turboscanoff)
+			txagc = pwrlevel;
+	} else {
+		txagc = pwrlevel;
+
+		if (rtlpriv->dm.dynamic_txhighpower_lvl ==
+		    TX_HIGH_PWR_LEVEL_LEVEL1)
+			txagc = 0x10;
+		else if (rtlpriv->dm.dynamic_txhighpower_lvl ==
+			TX_HIGH_PWR_LEVEL_LEVEL2)
+			txagc = 0x0;
+	}
+
+	if (txagc > RF6052_MAX_TX_PWR)
+		txagc = RF6052_MAX_TX_PWR;
+
+	rtl_set_bbreg(hw, RTXAGC_CCK_MCS32, BTX_AGCRATECCK, txagc);
+
+}
+
+bool rtl92s_phy_rf6052_config(struct ieee80211_hw *hw)
+{
+	struct rtl_priv *rtlpriv = rtl_priv(hw);
+	struct rtl_phy *rtlphy = &(rtlpriv->phy);
+	u32 u4reg_val = 0;
+	u8 rfpath;
+	bool rtstatus = true;
+	struct bb_reg_def *pphyreg;
+
+	/* Initialize RF */
+	for (rfpath = 0; rfpath < rtlphy->num_total_rfpath; rfpath++) {
+
+		pphyreg = &rtlphy->phyreg_def[rfpath];
+
+		/* Store original RFENV control type */
+		switch (rfpath) {
+		case RF90_PATH_A:
+		case RF90_PATH_C:
+			u4reg_val = rtl92s_phy_query_bb_reg(hw,
+							    pphyreg->rfintfs,
+							    BRFSI_RFENV);
+			break;
+		case RF90_PATH_B:
+		case RF90_PATH_D:
+			u4reg_val = rtl92s_phy_query_bb_reg(hw,
+							    pphyreg->rfintfs,
+							    BRFSI_RFENV << 16);
+			break;
+		}
+
+		/* Set RF_ENV enable */
+		rtl92s_phy_set_bb_reg(hw, pphyreg->rfintfe,
+				      BRFSI_RFENV << 16, 0x1);
+
+		/* Set RF_ENV output high */
+		rtl92s_phy_set_bb_reg(hw, pphyreg->rfintfo, BRFSI_RFENV, 0x1);
+
+		/* Set bit number of Address and Data for RF register */
+		rtl92s_phy_set_bb_reg(hw, pphyreg->rfhssi_para2,
+				B3WIRE_ADDRESSLENGTH, 0x0);
+		rtl92s_phy_set_bb_reg(hw, pphyreg->rfhssi_para2,
+				B3WIRE_DATALENGTH, 0x0);
+
+		/* Initialize RF fom connfiguration file */
+		switch (rfpath) {
+		case RF90_PATH_A:
+			rtstatus = rtl92s_phy_config_rf(hw,
+						(enum radio_path)rfpath);
+			break;
+		case RF90_PATH_B:
+			rtstatus = rtl92s_phy_config_rf(hw,
+						(enum radio_path)rfpath);
+			break;
+		case RF90_PATH_C:
+			break;
+		case RF90_PATH_D:
+			break;
+		}
+
+		/* Restore RFENV control type */
+		switch (rfpath) {
+		case RF90_PATH_A:
+		case RF90_PATH_C:
+			rtl92s_phy_set_bb_reg(hw, pphyreg->rfintfs, BRFSI_RFENV,
+					      u4reg_val);
+			break;
+		case RF90_PATH_B:
+		case RF90_PATH_D:
+			rtl92s_phy_set_bb_reg(hw, pphyreg->rfintfs,
+					      BRFSI_RFENV << 16,
+					      u4reg_val);
+			break;
+		}
+
+		if (rtstatus != true) {
+			printk(KERN_ERR "Radio[%d] Fail!!", rfpath);
+			goto fail;
+		}
+
+	}
+
+	return rtstatus;
+
+fail:
+	return rtstatus;
+}
+
+void rtl92s_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw, u8 bandwidth)
+{
+	struct rtl_priv *rtlpriv = rtl_priv(hw);
+	struct rtl_phy *rtlphy = &(rtlpriv->phy);
+
+	switch (bandwidth) {
+	case HT_CHANNEL_WIDTH_20:
+		rtlphy->rfreg_chnlval[0] = ((rtlphy->rfreg_chnlval[0] &
+					   0xfffff3ff) | 0x0400);
+		rtl_set_rfreg(hw, RF90_PATH_A, RF_CHNLBW, RFREG_OFFSET_MASK,
+					rtlphy->rfreg_chnlval[0]);
+		break;
+	case HT_CHANNEL_WIDTH_20_40:
+		rtlphy->rfreg_chnlval[0] = ((rtlphy->rfreg_chnlval[0] &
+					    0xfffff3ff));
+		rtl_set_rfreg(hw, RF90_PATH_A, RF_CHNLBW, RFREG_OFFSET_MASK,
+					rtlphy->rfreg_chnlval[0]);
+		break;
+	default:
+		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
+			 ("unknown bandwidth: %#X\n",
+			 bandwidth));
+		break;
+	}
+}
diff -druN linux-2.6.39-libre/drivers/net/wireless/rtlwifi/rtl8192se/rf.h linux-3.0-rc7-libre/drivers/net/wireless/rtlwifi/rtl8192se/rf.h
--- linux-2.6.39-libre/drivers/net/wireless/rtlwifi/rtl8192se/rf.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/net/wireless/rtlwifi/rtl8192se/rf.h	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,43 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2009-2010  Realtek Corporation.
+ *
+ * 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:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+#ifndef __INC_RTL92S_RF_H
+#define __INC_RTL92S_RF_H
+
+#define	RF6052_MAX_TX_PWR	0x3F
+
+void rtl92s_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw,
+				     u8 bandwidth);
+bool rtl92s_phy_rf6052_config(struct ieee80211_hw *hw) ;
+void rtl92s_phy_rf6052_set_ccktxpower(struct ieee80211_hw *hw,
+				      u8 powerlevel);
+void rtl92s_phy_rf6052_set_ofdmtxpower(struct ieee80211_hw *hw,
+				       u8 *p_pwrlevel, u8 chnl);
+
+#endif
+
diff -druN linux-2.6.39-libre/drivers/net/wireless/rtlwifi/rtl8192se/sw.c linux-3.0-rc7-libre/drivers/net/wireless/rtlwifi/rtl8192se/sw.c
--- linux-2.6.39-libre/drivers/net/wireless/rtlwifi/rtl8192se/sw.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/net/wireless/rtlwifi/rtl8192se/sw.c	2011-07-21 06:58:09.000000000 -0400
@@ -0,0 +1,423 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2009-2010  Realtek Corporation.
+ *
+ * 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:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+
+#include <linux/vmalloc.h>
+
+#include "../wifi.h"
+#include "../core.h"
+#include "../pci.h"
+#include "reg.h"
+#include "def.h"
+#include "phy.h"
+#include "dm.h"
+#include "fw.h"
+#include "hw.h"
+#include "sw.h"
+#include "trx.h"
+#include "led.h"
+
+static void rtl92s_init_aspm_vars(struct ieee80211_hw *hw)
+{
+	struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+
+	/*close ASPM for AMD defaultly */
+	rtlpci->const_amdpci_aspm = 0;
+
+	/*
+	 * ASPM PS mode.
+	 * 0 - Disable ASPM,
+	 * 1 - Enable ASPM without Clock Req,
+	 * 2 - Enable ASPM with Clock Req,
+	 * 3 - Alwyas Enable ASPM with Clock Req,
+	 * 4 - Always Enable ASPM without Clock Req.
+	 * set defult to RTL8192CE:3 RTL8192E:2
+	 * */
+	rtlpci->const_pci_aspm = 2;
+
+	/*Setting for PCI-E device */
+	rtlpci->const_devicepci_aspm_setting = 0x03;
+
+	/*Setting for PCI-E bridge */
+	rtlpci->const_hostpci_aspm_setting = 0x02;
+
+	/*
+	 * In Hw/Sw Radio Off situation.
+	 * 0 - Default,
+	 * 1 - From ASPM setting without low Mac Pwr,
+	 * 2 - From ASPM setting with low Mac Pwr,
+	 * 3 - Bus D3
+	 * set default to RTL8192CE:0 RTL8192SE:2
+	 */
+	rtlpci->const_hwsw_rfoff_d3 = 2;
+
+	/*
+	 * This setting works for those device with
+	 * backdoor ASPM setting such as EPHY setting.
+	 * 0 - Not support ASPM,
+	 * 1 - Support ASPM,
+	 * 2 - According to chipset.
+	 */
+	rtlpci->const_support_pciaspm = 2;
+}
+
+static int rtl92s_init_sw_vars(struct ieee80211_hw *hw)
+{
+	struct rtl_priv *rtlpriv = rtl_priv(hw);
+	struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+	const struct firmware *firmware;
+	struct rt_firmware *pfirmware = NULL;
+	int err = 0;
+	u16 earlyrxthreshold = 7;
+
+	rtlpriv->dm.dm_initialgain_enable = 1;
+	rtlpriv->dm.dm_flag = 0;
+	rtlpriv->dm.disable_framebursting = 0;
+	rtlpriv->dm.thermalvalue = 0;
+	rtlpriv->dm.useramask = true;
+
+	/* compatible 5G band 91se just 2.4G band & smsp */
+	rtlpriv->rtlhal.current_bandtype = BAND_ON_2_4G;
+	rtlpriv->rtlhal.bandset = BAND_ON_2_4G;
+	rtlpriv->rtlhal.macphymode = SINGLEMAC_SINGLEPHY;
+
+	rtlpci->transmit_config = 0;
+
+	rtlpci->receive_config =
+			RCR_APPFCS |
+			RCR_APWRMGT |
+			/*RCR_ADD3 |*/
+			RCR_AMF	|
+			RCR_ADF |
+			RCR_APP_MIC |
+			RCR_APP_ICV |
+			RCR_AICV |
+			/* Accept ICV error, CRC32 Error */
+			RCR_ACRC32 |
+			RCR_AB |
+			/* Accept Broadcast, Multicast */
+			RCR_AM	|
+			/* Accept Physical match */
+			RCR_APM |
+			/* Accept Destination Address packets */
+			/*RCR_AAP |*/
+			RCR_APP_PHYST_STAFF |
+			/* Accept PHY status */
+			RCR_APP_PHYST_RXFF |
+			(earlyrxthreshold << RCR_FIFO_OFFSET);
+
+	rtlpci->irq_mask[0] = (u32)
+			(IMR_ROK |
+			IMR_VODOK |
+			IMR_VIDOK |
+			IMR_BEDOK |
+			IMR_BKDOK |
+			IMR_HCCADOK |
+			IMR_MGNTDOK |
+			IMR_COMDOK |
+			IMR_HIGHDOK |
+			IMR_BDOK |
+			IMR_RXCMDOK |
+			/*IMR_TIMEOUT0 |*/
+			IMR_RDU |
+			IMR_RXFOVW	|
+			IMR_BCNINT
+			/*| IMR_TXFOVW*/
+			/*| IMR_TBDOK |
+			IMR_TBDER*/);
+
+	rtlpci->irq_mask[1] = (u32) 0;
+
+	rtlpci->shortretry_limit = 0x30;
+	rtlpci->longretry_limit = 0x30;
+
+	rtlpci->first_init = true;
+
+	/* for LPS & IPS */
+	rtlpriv->psc.inactiveps = rtlpriv->cfg->mod_params->inactiveps;
+	rtlpriv->psc.swctrl_lps = rtlpriv->cfg->mod_params->swctrl_lps;
+	rtlpriv->psc.fwctrl_lps = rtlpriv->cfg->mod_params->fwctrl_lps;
+	rtlpriv->psc.reg_fwctrl_lps = 3;
+	rtlpriv->psc.reg_max_lps_awakeintvl = 5;
+	/* for ASPM, you can close aspm through
+	 * set const_support_pciaspm = 0 */
+	rtl92s_init_aspm_vars(hw);
+
+	if (rtlpriv->psc.reg_fwctrl_lps == 1)
+		rtlpriv->psc.fwctrl_psmode = FW_PS_MIN_MODE;
+	else if (rtlpriv->psc.reg_fwctrl_lps == 2)
+		rtlpriv->psc.fwctrl_psmode = FW_PS_MAX_MODE;
+	else if (rtlpriv->psc.reg_fwctrl_lps == 3)
+		rtlpriv->psc.fwctrl_psmode = FW_PS_DTIM_MODE;
+
+	/* for firmware buf */
+	rtlpriv->rtlhal.pfirmware = vzalloc(sizeof(struct rt_firmware));
+	if (!rtlpriv->rtlhal.pfirmware) {
+		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
+			 ("Can't alloc buffer for fw.\n"));
+		return 1;
+	}
+
+	printk(KERN_INFO "rtl8192se: Driver for Realtek RTL8192SE/RTL8191SE\n"
+	       "           Loading firmware %s\n", rtlpriv->cfg->fw_name);
+	/* request fw */
+	err = reject_firmware(&firmware, rtlpriv->cfg->fw_name,
+			rtlpriv->io.dev);
+	if (err) {
+		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
+			 ("Failed to request firmware!\n"));
+		return 1;
+	}
+	if (firmware->size > sizeof(struct rt_firmware)) {
+		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
+			 ("Firmware is too big!\n"));
+		release_firmware(firmware);
+		return 1;
+	}
+
+	pfirmware = (struct rt_firmware *)rtlpriv->rtlhal.pfirmware;
+	memcpy(pfirmware->sz_fw_tmpbuffer, firmware->data, firmware->size);
+	pfirmware->sz_fw_tmpbufferlen = firmware->size;
+	release_firmware(firmware);
+
+	return err;
+}
+
+static void rtl92s_deinit_sw_vars(struct ieee80211_hw *hw)
+{
+	struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+	if (rtlpriv->rtlhal.pfirmware) {
+		vfree(rtlpriv->rtlhal.pfirmware);
+		rtlpriv->rtlhal.pfirmware = NULL;
+	}
+}
+
+static struct rtl_hal_ops rtl8192se_hal_ops = {
+	.init_sw_vars = rtl92s_init_sw_vars,
+	.deinit_sw_vars = rtl92s_deinit_sw_vars,
+	.read_eeprom_info = rtl92se_read_eeprom_info,
+	.interrupt_recognized = rtl92se_interrupt_recognized,
+	.hw_init = rtl92se_hw_init,
+	.hw_disable = rtl92se_card_disable,
+	.hw_suspend = rtl92se_suspend,
+	.hw_resume = rtl92se_resume,
+	.enable_interrupt = rtl92se_enable_interrupt,
+	.disable_interrupt = rtl92se_disable_interrupt,
+	.set_network_type = rtl92se_set_network_type,
+	.set_chk_bssid = rtl92se_set_check_bssid,
+	.set_qos = rtl92se_set_qos,
+	.set_bcn_reg = rtl92se_set_beacon_related_registers,
+	.set_bcn_intv = rtl92se_set_beacon_interval,
+	.update_interrupt_mask = rtl92se_update_interrupt_mask,
+	.get_hw_reg = rtl92se_get_hw_reg,
+	.set_hw_reg = rtl92se_set_hw_reg,
+	.update_rate_tbl = rtl92se_update_hal_rate_tbl,
+	.fill_tx_desc = rtl92se_tx_fill_desc,
+	.fill_tx_cmddesc = rtl92se_tx_fill_cmddesc,
+	.query_rx_desc = rtl92se_rx_query_desc,
+	.set_channel_access = rtl92se_update_channel_access_setting,
+	.radio_onoff_checking = rtl92se_gpio_radio_on_off_checking,
+	.set_bw_mode = rtl92s_phy_set_bw_mode,
+	.switch_channel = rtl92s_phy_sw_chnl,
+	.dm_watchdog = rtl92s_dm_watchdog,
+	.scan_operation_backup = rtl92s_phy_scan_operation_backup,
+	.set_rf_power_state = rtl92s_phy_set_rf_power_state,
+	.led_control = rtl92se_led_control,
+	.set_desc = rtl92se_set_desc,
+	.get_desc = rtl92se_get_desc,
+	.tx_polling = rtl92se_tx_polling,
+	.enable_hw_sec = rtl92se_enable_hw_security_config,
+	.set_key = rtl92se_set_key,
+	.init_sw_leds = rtl92se_init_sw_leds,
+	.get_bbreg = rtl92s_phy_query_bb_reg,
+	.set_bbreg = rtl92s_phy_set_bb_reg,
+	.get_rfreg = rtl92s_phy_query_rf_reg,
+	.set_rfreg = rtl92s_phy_set_rf_reg,
+};
+
+static struct rtl_mod_params rtl92se_mod_params = {
+	.sw_crypto = false,
+	.inactiveps = true,
+	.swctrl_lps = true,
+	.fwctrl_lps = false,
+};
+
+/* Because memory R/W bursting will cause system hang/crash
+ * for 92se, so we don't read back after every write action */
+static struct rtl_hal_cfg rtl92se_hal_cfg = {
+	.bar_id = 1,
+	.write_readback = false,
+	.name = "rtl92s_pci",
+	.fw_name = "/*(DEBLOBBED)*/",
+	.ops = &rtl8192se_hal_ops,
+	.mod_params = &rtl92se_mod_params,
+
+	.maps[SYS_ISO_CTRL] = REG_SYS_ISO_CTRL,
+	.maps[SYS_FUNC_EN] = REG_SYS_FUNC_EN,
+	.maps[SYS_CLK] = SYS_CLKR,
+	.maps[MAC_RCR_AM] = RCR_AM,
+	.maps[MAC_RCR_AB] = RCR_AB,
+	.maps[MAC_RCR_ACRC32] = RCR_ACRC32,
+	.maps[MAC_RCR_ACF] = RCR_ACF,
+	.maps[MAC_RCR_AAP] = RCR_AAP,
+
+	.maps[EFUSE_TEST] = REG_EFUSE_TEST,
+	.maps[EFUSE_CTRL] = REG_EFUSE_CTRL,
+	.maps[EFUSE_CLK] = REG_EFUSE_CLK,
+	.maps[EFUSE_CLK_CTRL] = REG_EFUSE_CTRL,
+	.maps[EFUSE_PWC_EV12V] = 0, /* nouse for 8192se */
+	.maps[EFUSE_FEN_ELDR] = 0, /* nouse for 8192se */
+	.maps[EFUSE_LOADER_CLK_EN] = 0,/* nouse for 8192se */
+	.maps[EFUSE_ANA8M] = EFUSE_ANA8M,
+	.maps[EFUSE_HWSET_MAX_SIZE] = HWSET_MAX_SIZE_92S,
+	.maps[EFUSE_MAX_SECTION_MAP] = EFUSE_MAX_SECTION,
+	.maps[EFUSE_REAL_CONTENT_SIZE] = EFUSE_REAL_CONTENT_LEN,
+
+	.maps[RWCAM] = REG_RWCAM,
+	.maps[WCAMI] = REG_WCAMI,
+	.maps[RCAMO] = REG_RCAMO,
+	.maps[CAMDBG] = REG_CAMDBG,
+	.maps[SECR] = REG_SECR,
+	.maps[SEC_CAM_NONE] = CAM_NONE,
+	.maps[SEC_CAM_WEP40] = CAM_WEP40,
+	.maps[SEC_CAM_TKIP] = CAM_TKIP,
+	.maps[SEC_CAM_AES] = CAM_AES,
+	.maps[SEC_CAM_WEP104] = CAM_WEP104,
+
+	.maps[RTL_IMR_BCNDMAINT6] = IMR_BCNDMAINT6,
+	.maps[RTL_IMR_BCNDMAINT5] = IMR_BCNDMAINT5,
+	.maps[RTL_IMR_BCNDMAINT4] = IMR_BCNDMAINT4,
+	.maps[RTL_IMR_BCNDMAINT3] = IMR_BCNDMAINT3,
+	.maps[RTL_IMR_BCNDMAINT2] = IMR_BCNDMAINT2,
+	.maps[RTL_IMR_BCNDMAINT1] = IMR_BCNDMAINT1,
+	.maps[RTL_IMR_BCNDOK8] = IMR_BCNDOK8,
+	.maps[RTL_IMR_BCNDOK7] = IMR_BCNDOK7,
+	.maps[RTL_IMR_BCNDOK6] = IMR_BCNDOK6,
+	.maps[RTL_IMR_BCNDOK5] = IMR_BCNDOK5,
+	.maps[RTL_IMR_BCNDOK4] = IMR_BCNDOK4,
+	.maps[RTL_IMR_BCNDOK3] = IMR_BCNDOK3,
+	.maps[RTL_IMR_BCNDOK2] = IMR_BCNDOK2,
+	.maps[RTL_IMR_BCNDOK1] = IMR_BCNDOK1,
+	.maps[RTL_IMR_TIMEOUT2] = IMR_TIMEOUT2,
+	.maps[RTL_IMR_TIMEOUT1] = IMR_TIMEOUT1,
+
+	.maps[RTL_IMR_TXFOVW] = IMR_TXFOVW,
+	.maps[RTL_IMR_PSTIMEOUT] = IMR_PSTIMEOUT,
+	.maps[RTL_IMR_BcnInt] = IMR_BCNINT,
+	.maps[RTL_IMR_RXFOVW] = IMR_RXFOVW,
+	.maps[RTL_IMR_RDU] = IMR_RDU,
+	.maps[RTL_IMR_ATIMEND] = IMR_ATIMEND,
+	.maps[RTL_IMR_BDOK] = IMR_BDOK,
+	.maps[RTL_IMR_MGNTDOK] = IMR_MGNTDOK,
+	.maps[RTL_IMR_TBDER] = IMR_TBDER,
+	.maps[RTL_IMR_HIGHDOK] = IMR_HIGHDOK,
+	.maps[RTL_IMR_COMDOK] = IMR_COMDOK,
+	.maps[RTL_IMR_TBDOK] = IMR_TBDOK,
+	.maps[RTL_IMR_BKDOK] = IMR_BKDOK,
+	.maps[RTL_IMR_BEDOK] = IMR_BEDOK,
+	.maps[RTL_IMR_VIDOK] = IMR_VIDOK,
+	.maps[RTL_IMR_VODOK] = IMR_VODOK,
+	.maps[RTL_IMR_ROK] = IMR_ROK,
+	.maps[RTL_IBSS_INT_MASKS] = (IMR_BCNINT | IMR_TBDOK | IMR_TBDER),
+
+	.maps[RTL_RC_CCK_RATE1M] = DESC92S_RATE1M,
+	.maps[RTL_RC_CCK_RATE2M] = DESC92S_RATE2M,
+	.maps[RTL_RC_CCK_RATE5_5M] = DESC92S_RATE5_5M,
+	.maps[RTL_RC_CCK_RATE11M] = DESC92S_RATE11M,
+	.maps[RTL_RC_OFDM_RATE6M] = DESC92S_RATE6M,
+	.maps[RTL_RC_OFDM_RATE9M] = DESC92S_RATE9M,
+	.maps[RTL_RC_OFDM_RATE12M] = DESC92S_RATE12M,
+	.maps[RTL_RC_OFDM_RATE18M] = DESC92S_RATE18M,
+	.maps[RTL_RC_OFDM_RATE24M] = DESC92S_RATE24M,
+	.maps[RTL_RC_OFDM_RATE36M] = DESC92S_RATE36M,
+	.maps[RTL_RC_OFDM_RATE48M] = DESC92S_RATE48M,
+	.maps[RTL_RC_OFDM_RATE54M] = DESC92S_RATE54M,
+
+	.maps[RTL_RC_HT_RATEMCS7] = DESC92S_RATEMCS7,
+	.maps[RTL_RC_HT_RATEMCS15] = DESC92S_RATEMCS15,
+};
+
+static struct pci_device_id rtl92se_pci_ids[] __devinitdata = {
+	{RTL_PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8192, rtl92se_hal_cfg)},
+	{RTL_PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8171, rtl92se_hal_cfg)},
+	{RTL_PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8172, rtl92se_hal_cfg)},
+	{RTL_PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8173, rtl92se_hal_cfg)},
+	{RTL_PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8174, rtl92se_hal_cfg)},
+	{},
+};
+
+MODULE_DEVICE_TABLE(pci, rtl92se_pci_ids);
+
+MODULE_AUTHOR("lizhaoming	<chaoming_li@realsil.com.cn>");
+MODULE_AUTHOR("Realtek WlanFAE	<wlanfae@realtek.com>");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Realtek 8192S/8191S 802.11n PCI wireless");
+/*(DEBLOBBED)*/
+
+module_param_named(swenc, rtl92se_mod_params.sw_crypto, bool, 0444);
+module_param_named(ips, rtl92se_mod_params.inactiveps, bool, 0444);
+module_param_named(swlps, rtl92se_mod_params.swctrl_lps, bool, 0444);
+module_param_named(fwlps, rtl92se_mod_params.fwctrl_lps, bool, 0444);
+MODULE_PARM_DESC(swenc, "using hardware crypto (default 0 [hardware])\n");
+MODULE_PARM_DESC(ips, "using no link power save (default 1 is open)\n");
+MODULE_PARM_DESC(swlps, "using linked sw control power save (default 1 is "
+		 "open)\n");
+
+
+static struct pci_driver rtl92se_driver = {
+	.name = KBUILD_MODNAME,
+	.id_table = rtl92se_pci_ids,
+	.probe = rtl_pci_probe,
+	.remove = rtl_pci_disconnect,
+
+#ifdef CONFIG_PM
+	.suspend = rtl_pci_suspend,
+	.resume = rtl_pci_resume,
+#endif
+
+};
+
+static int __init rtl92se_module_init(void)
+{
+	int ret = 0;
+
+	ret = pci_register_driver(&rtl92se_driver);
+	if (ret)
+		RT_ASSERT(false, (": No device found\n"));
+
+	return ret;
+}
+
+static void __exit rtl92se_module_exit(void)
+{
+	pci_unregister_driver(&rtl92se_driver);
+}
+
+module_init(rtl92se_module_init);
+module_exit(rtl92se_module_exit);
diff -druN linux-2.6.39-libre/drivers/net/wireless/rtlwifi/rtl8192se/sw.h linux-3.0-rc7-libre/drivers/net/wireless/rtlwifi/rtl8192se/sw.h
--- linux-2.6.39-libre/drivers/net/wireless/rtlwifi/rtl8192se/sw.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/net/wireless/rtlwifi/rtl8192se/sw.h	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,36 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2009-2010  Realtek Corporation.
+ *
+ * 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:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ *****************************************************************************/
+#ifndef __REALTEK_PCI92SE_SW_H__
+#define __REALTEK_PCI92SE_SW_H__
+
+#define EFUSE_MAX_SECTION	16
+
+int rtl92se_init_sw(struct ieee80211_hw *hw);
+void rtl92se_deinit_sw(struct ieee80211_hw *hw);
+void rtl92se_init_var_map(struct ieee80211_hw *hw);
+
+#endif
diff -druN linux-2.6.39-libre/drivers/net/wireless/rtlwifi/rtl8192se/table.c linux-3.0-rc7-libre/drivers/net/wireless/rtlwifi/rtl8192se/table.c
--- linux-2.6.39-libre/drivers/net/wireless/rtlwifi/rtl8192se/table.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/net/wireless/rtlwifi/rtl8192se/table.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,634 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2009-2010  Realtek Corporation.
+ *
+ * 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:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ * Created on  2010/ 5/18,  1:41
+ *****************************************************************************/
+
+#include "table.h"
+
+u32 rtl8192sephy_reg_2t2rarray[PHY_REG_2T2RARRAYLENGTH] = {
+	0x01c, 0x07000000,
+	0x800, 0x00040000,
+	0x804, 0x00008003,
+	0x808, 0x0000fc00,
+	0x80c, 0x0000000a,
+	0x810, 0x10005088,
+	0x814, 0x020c3d10,
+	0x818, 0x00200185,
+	0x81c, 0x00000000,
+	0x820, 0x01000000,
+	0x824, 0x00390004,
+	0x828, 0x01000000,
+	0x82c, 0x00390004,
+	0x830, 0x00000004,
+	0x834, 0x00690200,
+	0x838, 0x00000004,
+	0x83c, 0x00690200,
+	0x840, 0x00010000,
+	0x844, 0x00010000,
+	0x848, 0x00000000,
+	0x84c, 0x00000000,
+	0x850, 0x00000000,
+	0x854, 0x00000000,
+	0x858, 0x48484848,
+	0x85c, 0x65a965a9,
+	0x860, 0x0f7f0130,
+	0x864, 0x0f7f0130,
+	0x868, 0x0f7f0130,
+	0x86c, 0x0f7f0130,
+	0x870, 0x03000700,
+	0x874, 0x03000300,
+	0x878, 0x00020002,
+	0x87c, 0x004f0201,
+	0x880, 0xa8300ac1,
+	0x884, 0x00000058,
+	0x888, 0x00000008,
+	0x88c, 0x00000004,
+	0x890, 0x00000000,
+	0x894, 0xfffffffe,
+	0x898, 0x40302010,
+	0x89c, 0x00706050,
+	0x8b0, 0x00000000,
+	0x8e0, 0x00000000,
+	0x8e4, 0x00000000,
+	0xe00, 0x30333333,
+	0xe04, 0x2a2d2e2f,
+	0xe08, 0x00003232,
+	0xe10, 0x30333333,
+	0xe14, 0x2a2d2e2f,
+	0xe18, 0x30333333,
+	0xe1c, 0x2a2d2e2f,
+	0xe30, 0x01007c00,
+	0xe34, 0x01004800,
+	0xe38, 0x1000dc1f,
+	0xe3c, 0x10008c1f,
+	0xe40, 0x021400a0,
+	0xe44, 0x281600a0,
+	0xe48, 0xf8000001,
+	0xe4c, 0x00002910,
+	0xe50, 0x01007c00,
+	0xe54, 0x01004800,
+	0xe58, 0x1000dc1f,
+	0xe5c, 0x10008c1f,
+	0xe60, 0x021400a0,
+	0xe64, 0x281600a0,
+	0xe6c, 0x00002910,
+	0xe70, 0x31ed92fb,
+	0xe74, 0x361536fb,
+	0xe78, 0x361536fb,
+	0xe7c, 0x361536fb,
+	0xe80, 0x361536fb,
+	0xe84, 0x000d92fb,
+	0xe88, 0x000d92fb,
+	0xe8c, 0x31ed92fb,
+	0xed0, 0x31ed92fb,
+	0xed4, 0x31ed92fb,
+	0xed8, 0x000d92fb,
+	0xedc, 0x000d92fb,
+	0xee0, 0x000d92fb,
+	0xee4, 0x015e5448,
+	0xee8, 0x21555448,
+	0x900, 0x00000000,
+	0x904, 0x00000023,
+	0x908, 0x00000000,
+	0x90c, 0x01121313,
+	0xa00, 0x00d047c8,
+	0xa04, 0x80ff0008,
+	0xa08, 0x8ccd8300,
+	0xa0c, 0x2e62120f,
+	0xa10, 0x9500bb78,
+	0xa14, 0x11144028,
+	0xa18, 0x00881117,
+	0xa1c, 0x89140f00,
+	0xa20, 0x1a1b0000,
+	0xa24, 0x090e1317,
+	0xa28, 0x00000204,
+	0xa2c, 0x10d30000,
+	0xc00, 0x40071d40,
+	0xc04, 0x00a05633,
+	0xc08, 0x000000e4,
+	0xc0c, 0x6c6c6c6c,
+	0xc10, 0x08800000,
+	0xc14, 0x40000100,
+	0xc18, 0x08000000,
+	0xc1c, 0x40000100,
+	0xc20, 0x08000000,
+	0xc24, 0x40000100,
+	0xc28, 0x08000000,
+	0xc2c, 0x40000100,
+	0xc30, 0x6de9ac44,
+	0xc34, 0x469652cf,
+	0xc38, 0x49795994,
+	0xc3c, 0x0a979764,
+	0xc40, 0x1f7c403f,
+	0xc44, 0x000100b7,
+	0xc48, 0xec020000,
+	0xc4c, 0x007f037f,
+	0xc50, 0x69543420,
+	0xc54, 0x433c0094,
+	0xc58, 0x69543420,
+	0xc5c, 0x433c0094,
+	0xc60, 0x69543420,
+	0xc64, 0x433c0094,
+	0xc68, 0x69543420,
+	0xc6c, 0x433c0094,
+	0xc70, 0x2c7f000d,
+	0xc74, 0x0186155b,
+	0xc78, 0x0000001f,
+	0xc7c, 0x00b91612,
+	0xc80, 0x40000100,
+	0xc84, 0x20f60000,
+	0xc88, 0x20000080,
+	0xc8c, 0x20200000,
+	0xc90, 0x40000100,
+	0xc94, 0x00000000,
+	0xc98, 0x40000100,
+	0xc9c, 0x00000000,
+	0xca0, 0x00492492,
+	0xca4, 0x00000000,
+	0xca8, 0x00000000,
+	0xcac, 0x00000000,
+	0xcb0, 0x00000000,
+	0xcb4, 0x00000000,
+	0xcb8, 0x00000000,
+	0xcbc, 0x28000000,
+	0xcc0, 0x00000000,
+	0xcc4, 0x00000000,
+	0xcc8, 0x00000000,
+	0xccc, 0x00000000,
+	0xcd0, 0x00000000,
+	0xcd4, 0x00000000,
+	0xcd8, 0x64b22427,
+	0xcdc, 0x00766932,
+	0xce0, 0x00222222,
+	0xce4, 0x00000000,
+	0xce8, 0x37644302,
+	0xcec, 0x2f97d40c,
+	0xd00, 0x00000750,
+	0xd04, 0x00000403,
+	0xd08, 0x0000907f,
+	0xd0c, 0x00000001,
+	0xd10, 0xa0633333,
+	0xd14, 0x33333c63,
+	0xd18, 0x6a8f5b6b,
+	0xd1c, 0x00000000,
+	0xd20, 0x00000000,
+	0xd24, 0x00000000,
+	0xd28, 0x00000000,
+	0xd2c, 0xcc979975,
+	0xd30, 0x00000000,
+	0xd34, 0x00000000,
+	0xd38, 0x00000000,
+	0xd3c, 0x00027293,
+	0xd40, 0x00000000,
+	0xd44, 0x00000000,
+	0xd48, 0x00000000,
+	0xd50, 0x6437140a,
+	0xd54, 0x024dbd02,
+	0xd58, 0x00000000,
+	0xd5c, 0x30032064,
+	0xd60, 0x4653de68,
+	0xd64, 0x00518a3c,
+	0xd68, 0x00002101,
+	0xf14, 0x00000003,
+	0xf4c, 0x00000000,
+	0xf00, 0x00000300,
+};
+
+u32 rtl8192sephy_changeto_1t1rarray[PHY_CHANGETO_1T1RARRAYLENGTH] = {
+	0x844, 0xffffffff, 0x00010000,
+	0x804, 0x0000000f, 0x00000001,
+	0x824, 0x00f0000f, 0x00300004,
+	0x82c, 0x00f0000f, 0x00100002,
+	0x870, 0x04000000, 0x00000001,
+	0x864, 0x00000400, 0x00000000,
+	0x878, 0x000f000f, 0x00000002,
+	0xe74, 0x0f000000, 0x00000002,
+	0xe78, 0x0f000000, 0x00000002,
+	0xe7c, 0x0f000000, 0x00000002,
+	0xe80, 0x0f000000, 0x00000002,
+	0x90c, 0x000000ff, 0x00000011,
+	0xc04, 0x000000ff, 0x00000011,
+	0xd04, 0x0000000f, 0x00000001,
+	0x1f4, 0xffff0000, 0x00007777,
+	0x234, 0xf8000000, 0x0000000a,
+};
+
+u32 rtl8192sephy_changeto_1t2rarray[PHY_CHANGETO_1T2RARRAYLENGTH] = {
+	0x804, 0x0000000f, 0x00000003,
+	0x824, 0x00f0000f, 0x00300004,
+	0x82c, 0x00f0000f, 0x00300002,
+	0x870, 0x04000000, 0x00000001,
+	0x864, 0x00000400, 0x00000000,
+	0x878, 0x000f000f, 0x00000002,
+	0xe74, 0x0f000000, 0x00000002,
+	0xe78, 0x0f000000, 0x00000002,
+	0xe7c, 0x0f000000, 0x00000002,
+	0xe80, 0x0f000000, 0x00000002,
+	0x90c, 0x000000ff, 0x00000011,
+	0xc04, 0x000000ff, 0x00000033,
+	0xd04, 0x0000000f, 0x00000003,
+	0x1f4, 0xffff0000, 0x00007777,
+	0x234, 0xf8000000, 0x0000000a,
+};
+
+u32 rtl8192sephy_reg_array_pg[PHY_REG_ARRAY_PGLENGTH] = {
+	0xe00, 0xffffffff, 0x06090909,
+	0xe04, 0xffffffff, 0x00030406,
+	0xe08, 0x0000ff00, 0x00000000,
+	0xe10, 0xffffffff, 0x0a0c0d0e,
+	0xe14, 0xffffffff, 0x04070809,
+	0xe18, 0xffffffff, 0x0a0c0d0e,
+	0xe1c, 0xffffffff, 0x04070809,
+	0xe00, 0xffffffff, 0x04040404,
+	0xe04, 0xffffffff, 0x00020204,
+	0xe08, 0x0000ff00, 0x00000000,
+	0xe10, 0xffffffff, 0x02040404,
+	0xe14, 0xffffffff, 0x00000002,
+	0xe18, 0xffffffff, 0x02040404,
+	0xe1c, 0xffffffff, 0x00000002,
+	0xe00, 0xffffffff, 0x04040404,
+	0xe04, 0xffffffff, 0x00020204,
+	0xe08, 0x0000ff00, 0x00000000,
+	0xe10, 0xffffffff, 0x02040404,
+	0xe14, 0xffffffff, 0x00000002,
+	0xe18, 0xffffffff, 0x02040404,
+	0xe1c, 0xffffffff, 0x00000002,
+	0xe00, 0xffffffff, 0x02020202,
+	0xe04, 0xffffffff, 0x00020202,
+	0xe08, 0x0000ff00, 0x00000000,
+	0xe10, 0xffffffff, 0x02020202,
+	0xe14, 0xffffffff, 0x00000002,
+	0xe18, 0xffffffff, 0x02020202,
+	0xe1c, 0xffffffff, 0x00000002,
+};
+
+u32 rtl8192seradioa_1t_array[RADIOA_1T_ARRAYLENGTH] = {
+	0x000, 0x00030159,
+	0x001, 0x00030250,
+	0x002, 0x00010000,
+	0x010, 0x0008000f,
+	0x011, 0x000231fc,
+	0x010, 0x000c000f,
+	0x011, 0x0003f9f8,
+	0x010, 0x0002000f,
+	0x011, 0x00020101,
+	0x014, 0x0001093e,
+	0x014, 0x0009093e,
+	0x015, 0x0000f8f4,
+	0x017, 0x000f6500,
+	0x01a, 0x00013056,
+	0x01b, 0x00060000,
+	0x01c, 0x00000300,
+	0x01e, 0x00031059,
+	0x021, 0x00054000,
+	0x022, 0x0000083c,
+	0x023, 0x00001558,
+	0x024, 0x00000060,
+	0x025, 0x00022583,
+	0x026, 0x0000f200,
+	0x027, 0x000eacf1,
+	0x028, 0x0009bd54,
+	0x029, 0x00004582,
+	0x02a, 0x00000001,
+	0x02b, 0x00021334,
+	0x02a, 0x00000000,
+	0x02b, 0x0000000a,
+	0x02a, 0x00000001,
+	0x02b, 0x00000808,
+	0x02b, 0x00053333,
+	0x02c, 0x0000000c,
+	0x02a, 0x00000002,
+	0x02b, 0x00000808,
+	0x02b, 0x0005b333,
+	0x02c, 0x0000000d,
+	0x02a, 0x00000003,
+	0x02b, 0x00000808,
+	0x02b, 0x00063333,
+	0x02c, 0x0000000d,
+	0x02a, 0x00000004,
+	0x02b, 0x00000808,
+	0x02b, 0x0006b333,
+	0x02c, 0x0000000d,
+	0x02a, 0x00000005,
+	0x02b, 0x00000709,
+	0x02b, 0x00053333,
+	0x02c, 0x0000000d,
+	0x02a, 0x00000006,
+	0x02b, 0x00000709,
+	0x02b, 0x0005b333,
+	0x02c, 0x0000000d,
+	0x02a, 0x00000007,
+	0x02b, 0x00000709,
+	0x02b, 0x00063333,
+	0x02c, 0x0000000d,
+	0x02a, 0x00000008,
+	0x02b, 0x00000709,
+	0x02b, 0x0006b333,
+	0x02c, 0x0000000d,
+	0x02a, 0x00000009,
+	0x02b, 0x0000060a,
+	0x02b, 0x00053333,
+	0x02c, 0x0000000d,
+	0x02a, 0x0000000a,
+	0x02b, 0x0000060a,
+	0x02b, 0x0005b333,
+	0x02c, 0x0000000d,
+	0x02a, 0x0000000b,
+	0x02b, 0x0000060a,
+	0x02b, 0x00063333,
+	0x02c, 0x0000000d,
+	0x02a, 0x0000000c,
+	0x02b, 0x0000060a,
+	0x02b, 0x0006b333,
+	0x02c, 0x0000000d,
+	0x02a, 0x0000000d,
+	0x02b, 0x0000050b,
+	0x02b, 0x00053333,
+	0x02c, 0x0000000d,
+	0x02a, 0x0000000e,
+	0x02b, 0x0000050b,
+	0x02b, 0x00066623,
+	0x02c, 0x0000001a,
+	0x02a, 0x000e4000,
+	0x030, 0x00020000,
+	0x031, 0x000b9631,
+	0x032, 0x0000130d,
+	0x033, 0x00000187,
+	0x013, 0x00019e6c,
+	0x013, 0x00015e94,
+	0x000, 0x00010159,
+	0x018, 0x0000f401,
+	0x0fe, 0x00000000,
+	0x01e, 0x0003105b,
+	0x0fe, 0x00000000,
+	0x000, 0x00030159,
+	0x010, 0x0004000f,
+	0x011, 0x000203f9,
+};
+
+u32 rtl8192seradiob_array[RADIOB_ARRAYLENGTH] = {
+	0x000, 0x00030159,
+	0x001, 0x00001041,
+	0x002, 0x00011000,
+	0x005, 0x00080fc0,
+	0x007, 0x000fc803,
+	0x013, 0x00017cb0,
+	0x013, 0x00011cc0,
+	0x013, 0x0000dc60,
+	0x013, 0x00008c60,
+	0x013, 0x00004450,
+	0x013, 0x00000020,
+};
+
+u32 rtl8192seradiob_gm_array[RADIOB_GM_ARRAYLENGTH] = {
+	0x000, 0x00030159,
+	0x001, 0x00001041,
+	0x002, 0x00011000,
+	0x005, 0x00080fc0,
+	0x007, 0x000fc803,
+};
+
+u32 rtl8192semac_2t_array[MAC_2T_ARRAYLENGTH] = {
+	0x020, 0x00000035,
+	0x048, 0x0000000e,
+	0x049, 0x000000f0,
+	0x04a, 0x00000077,
+	0x04b, 0x00000083,
+	0x0b5, 0x00000021,
+	0x0dc, 0x000000ff,
+	0x0dd, 0x000000ff,
+	0x0de, 0x000000ff,
+	0x0df, 0x000000ff,
+	0x116, 0x00000000,
+	0x117, 0x00000000,
+	0x118, 0x00000000,
+	0x119, 0x00000000,
+	0x11a, 0x00000000,
+	0x11b, 0x00000000,
+	0x11c, 0x00000000,
+	0x11d, 0x00000000,
+	0x160, 0x0000000b,
+	0x161, 0x0000000b,
+	0x162, 0x0000000b,
+	0x163, 0x0000000b,
+	0x164, 0x0000000b,
+	0x165, 0x0000000b,
+	0x166, 0x0000000b,
+	0x167, 0x0000000b,
+	0x168, 0x0000000b,
+	0x169, 0x0000000b,
+	0x16a, 0x0000000b,
+	0x16b, 0x0000000b,
+	0x16c, 0x0000000b,
+	0x16d, 0x0000000b,
+	0x16e, 0x0000000b,
+	0x16f, 0x0000000b,
+	0x170, 0x0000000b,
+	0x171, 0x0000000b,
+	0x172, 0x0000000b,
+	0x173, 0x0000000b,
+	0x174, 0x0000000b,
+	0x175, 0x0000000b,
+	0x176, 0x0000000b,
+	0x177, 0x0000000b,
+	0x178, 0x0000000b,
+	0x179, 0x0000000b,
+	0x17a, 0x0000000b,
+	0x17b, 0x0000000b,
+	0x17c, 0x0000000b,
+	0x17d, 0x0000000b,
+	0x17e, 0x0000000b,
+	0x17f, 0x0000000b,
+	0x236, 0x0000000c,
+	0x503, 0x00000022,
+	0x560, 0x00000000,
+};
+
+u32 rtl8192seagctab_array[AGCTAB_ARRAYLENGTH] = {
+	0xc78, 0x7f000001,
+	0xc78, 0x7f010001,
+	0xc78, 0x7e020001,
+	0xc78, 0x7d030001,
+	0xc78, 0x7c040001,
+	0xc78, 0x7b050001,
+	0xc78, 0x7a060001,
+	0xc78, 0x79070001,
+	0xc78, 0x78080001,
+	0xc78, 0x77090001,
+	0xc78, 0x760a0001,
+	0xc78, 0x750b0001,
+	0xc78, 0x740c0001,
+	0xc78, 0x730d0001,
+	0xc78, 0x720e0001,
+	0xc78, 0x710f0001,
+	0xc78, 0x70100001,
+	0xc78, 0x6f110001,
+	0xc78, 0x6f120001,
+	0xc78, 0x6e130001,
+	0xc78, 0x6d140001,
+	0xc78, 0x6d150001,
+	0xc78, 0x6c160001,
+	0xc78, 0x6b170001,
+	0xc78, 0x6a180001,
+	0xc78, 0x6a190001,
+	0xc78, 0x691a0001,
+	0xc78, 0x681b0001,
+	0xc78, 0x671c0001,
+	0xc78, 0x661d0001,
+	0xc78, 0x651e0001,
+	0xc78, 0x641f0001,
+	0xc78, 0x63200001,
+	0xc78, 0x4c210001,
+	0xc78, 0x4b220001,
+	0xc78, 0x4a230001,
+	0xc78, 0x49240001,
+	0xc78, 0x48250001,
+	0xc78, 0x47260001,
+	0xc78, 0x46270001,
+	0xc78, 0x45280001,
+	0xc78, 0x44290001,
+	0xc78, 0x2c2a0001,
+	0xc78, 0x2b2b0001,
+	0xc78, 0x2a2c0001,
+	0xc78, 0x292d0001,
+	0xc78, 0x282e0001,
+	0xc78, 0x272f0001,
+	0xc78, 0x26300001,
+	0xc78, 0x25310001,
+	0xc78, 0x24320001,
+	0xc78, 0x23330001,
+	0xc78, 0x22340001,
+	0xc78, 0x09350001,
+	0xc78, 0x08360001,
+	0xc78, 0x07370001,
+	0xc78, 0x06380001,
+	0xc78, 0x05390001,
+	0xc78, 0x043a0001,
+	0xc78, 0x033b0001,
+	0xc78, 0x023c0001,
+	0xc78, 0x013d0001,
+	0xc78, 0x003e0001,
+	0xc78, 0x003f0001,
+	0xc78, 0x7f400001,
+	0xc78, 0x7f410001,
+	0xc78, 0x7e420001,
+	0xc78, 0x7d430001,
+	0xc78, 0x7c440001,
+	0xc78, 0x7b450001,
+	0xc78, 0x7a460001,
+	0xc78, 0x79470001,
+	0xc78, 0x78480001,
+	0xc78, 0x77490001,
+	0xc78, 0x764a0001,
+	0xc78, 0x754b0001,
+	0xc78, 0x744c0001,
+	0xc78, 0x734d0001,
+	0xc78, 0x724e0001,
+	0xc78, 0x714f0001,
+	0xc78, 0x70500001,
+	0xc78, 0x6f510001,
+	0xc78, 0x6f520001,
+	0xc78, 0x6e530001,
+	0xc78, 0x6d540001,
+	0xc78, 0x6d550001,
+	0xc78, 0x6c560001,
+	0xc78, 0x6b570001,
+	0xc78, 0x6a580001,
+	0xc78, 0x6a590001,
+	0xc78, 0x695a0001,
+	0xc78, 0x685b0001,
+	0xc78, 0x675c0001,
+	0xc78, 0x665d0001,
+	0xc78, 0x655e0001,
+	0xc78, 0x645f0001,
+	0xc78, 0x63600001,
+	0xc78, 0x4c610001,
+	0xc78, 0x4b620001,
+	0xc78, 0x4a630001,
+	0xc78, 0x49640001,
+	0xc78, 0x48650001,
+	0xc78, 0x47660001,
+	0xc78, 0x46670001,
+	0xc78, 0x45680001,
+	0xc78, 0x44690001,
+	0xc78, 0x2c6a0001,
+	0xc78, 0x2b6b0001,
+	0xc78, 0x2a6c0001,
+	0xc78, 0x296d0001,
+	0xc78, 0x286e0001,
+	0xc78, 0x276f0001,
+	0xc78, 0x26700001,
+	0xc78, 0x25710001,
+	0xc78, 0x24720001,
+	0xc78, 0x23730001,
+	0xc78, 0x22740001,
+	0xc78, 0x09750001,
+	0xc78, 0x08760001,
+	0xc78, 0x07770001,
+	0xc78, 0x06780001,
+	0xc78, 0x05790001,
+	0xc78, 0x047a0001,
+	0xc78, 0x037b0001,
+	0xc78, 0x027c0001,
+	0xc78, 0x017d0001,
+	0xc78, 0x007e0001,
+	0xc78, 0x007f0001,
+	0xc78, 0x3000001e,
+	0xc78, 0x3001001e,
+	0xc78, 0x3002001e,
+	0xc78, 0x3003001e,
+	0xc78, 0x3004001e,
+	0xc78, 0x3405001e,
+	0xc78, 0x3806001e,
+	0xc78, 0x3e07001e,
+	0xc78, 0x3e08001e,
+	0xc78, 0x4409001e,
+	0xc78, 0x460a001e,
+	0xc78, 0x480b001e,
+	0xc78, 0x480c001e,
+	0xc78, 0x4e0d001e,
+	0xc78, 0x560e001e,
+	0xc78, 0x5a0f001e,
+	0xc78, 0x5e10001e,
+	0xc78, 0x6211001e,
+	0xc78, 0x6c12001e,
+	0xc78, 0x7213001e,
+	0xc78, 0x7214001e,
+	0xc78, 0x7215001e,
+	0xc78, 0x7216001e,
+	0xc78, 0x7217001e,
+	0xc78, 0x7218001e,
+	0xc78, 0x7219001e,
+	0xc78, 0x721a001e,
+	0xc78, 0x721b001e,
+	0xc78, 0x721c001e,
+	0xc78, 0x721d001e,
+	0xc78, 0x721e001e,
+	0xc78, 0x721f001e,
+};
+
diff -druN linux-2.6.39-libre/drivers/net/wireless/rtlwifi/rtl8192se/table.h linux-3.0-rc7-libre/drivers/net/wireless/rtlwifi/rtl8192se/table.h
--- linux-2.6.39-libre/drivers/net/wireless/rtlwifi/rtl8192se/table.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/net/wireless/rtlwifi/rtl8192se/table.h	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,49 @@
+/******************************************************************************
+ * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You 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:
+ * wlanfae <wlanfae@realtek.com>
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ ******************************************************************************/
+#ifndef __INC_HAL8192SE_FW_IMG_H
+#define __INC_HAL8192SE_FW_IMG_H
+
+#include <linux/types.h>
+
+/*Created on  2010/ 4/12,  5:56*/
+
+#define PHY_REG_2T2RARRAYLENGTH 372
+extern u32 rtl8192sephy_reg_2t2rarray[PHY_REG_2T2RARRAYLENGTH];
+#define PHY_CHANGETO_1T1RARRAYLENGTH 48
+extern u32 rtl8192sephy_changeto_1t1rarray[PHY_CHANGETO_1T1RARRAYLENGTH];
+#define PHY_CHANGETO_1T2RARRAYLENGTH 45
+extern u32 rtl8192sephy_changeto_1t2rarray[PHY_CHANGETO_1T2RARRAYLENGTH];
+#define PHY_REG_ARRAY_PGLENGTH 84
+extern u32 rtl8192sephy_reg_array_pg[PHY_REG_ARRAY_PGLENGTH];
+#define RADIOA_1T_ARRAYLENGTH 202
+extern u32 rtl8192seradioa_1t_array[RADIOA_1T_ARRAYLENGTH];
+#define RADIOB_ARRAYLENGTH 22
+extern u32 rtl8192seradiob_array[RADIOB_ARRAYLENGTH];
+#define RADIOB_GM_ARRAYLENGTH 10
+extern u32 rtl8192seradiob_gm_array[RADIOB_GM_ARRAYLENGTH];
+#define MAC_2T_ARRAYLENGTH 106
+extern u32 rtl8192semac_2t_array[MAC_2T_ARRAYLENGTH];
+#define AGCTAB_ARRAYLENGTH 320
+extern u32 rtl8192seagctab_array[AGCTAB_ARRAYLENGTH];
+
+#endif
+
diff -druN linux-2.6.39-libre/drivers/net/wireless/rtlwifi/rtl8192se/trx.c linux-3.0-rc7-libre/drivers/net/wireless/rtlwifi/rtl8192se/trx.c
--- linux-2.6.39-libre/drivers/net/wireless/rtlwifi/rtl8192se/trx.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/net/wireless/rtlwifi/rtl8192se/trx.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,976 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2009-2010  Realtek Corporation.
+ *
+ * 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:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+
+#include "../wifi.h"
+#include "../pci.h"
+#include "../base.h"
+#include "reg.h"
+#include "def.h"
+#include "phy.h"
+#include "fw.h"
+#include "trx.h"
+#include "led.h"
+
+static u8 _rtl92se_map_hwqueue_to_fwqueue(struct sk_buff *skb,	u8 skb_queue)
+{
+	__le16 fc = rtl_get_fc(skb);
+
+	if (unlikely(ieee80211_is_beacon(fc)))
+		return QSLT_BEACON;
+	if (ieee80211_is_mgmt(fc))
+		return QSLT_MGNT;
+	if (ieee80211_is_nullfunc(fc))
+		return QSLT_HIGH;
+
+	return skb->priority;
+}
+
+static int _rtl92se_rate_mapping(bool isht, u8 desc_rate, bool first_ampdu)
+{
+	int rate_idx = 0;
+
+	if (first_ampdu) {
+		if (false == isht) {
+			switch (desc_rate) {
+			case DESC92S_RATE1M:
+				rate_idx = 0;
+				break;
+			case DESC92S_RATE2M:
+				rate_idx = 1;
+				break;
+			case DESC92S_RATE5_5M:
+				rate_idx = 2;
+				break;
+			case DESC92S_RATE11M:
+				rate_idx = 3;
+				break;
+			case DESC92S_RATE6M:
+				rate_idx = 4;
+				break;
+			case DESC92S_RATE9M:
+				rate_idx = 5;
+				break;
+			case DESC92S_RATE12M:
+				rate_idx = 6;
+				break;
+			case DESC92S_RATE18M:
+				rate_idx = 7;
+				break;
+			case DESC92S_RATE24M:
+				rate_idx = 8;
+				break;
+			case DESC92S_RATE36M:
+				rate_idx = 9;
+				break;
+			case DESC92S_RATE48M:
+				rate_idx = 10;
+				break;
+			case DESC92S_RATE54M:
+				rate_idx = 11;
+				break;
+			default:
+				rate_idx = 0;
+				break;
+			}
+		} else {
+			rate_idx = 11;
+		}
+
+		return rate_idx;
+	}
+
+	switch (desc_rate) {
+	case DESC92S_RATE1M:
+		rate_idx = 0;
+		break;
+	case DESC92S_RATE2M:
+		rate_idx = 1;
+		break;
+	case DESC92S_RATE5_5M:
+		rate_idx = 2;
+		break;
+	case DESC92S_RATE11M:
+		rate_idx = 3;
+		break;
+	case DESC92S_RATE6M:
+		rate_idx = 4;
+		break;
+	case DESC92S_RATE9M:
+		rate_idx = 5;
+		break;
+	case DESC92S_RATE12M:
+		rate_idx = 6;
+		break;
+	case DESC92S_RATE18M:
+		rate_idx = 7;
+		break;
+	case DESC92S_RATE24M:
+		rate_idx = 8;
+		break;
+	case DESC92S_RATE36M:
+		rate_idx = 9;
+		break;
+	case DESC92S_RATE48M:
+		rate_idx = 10;
+		break;
+	case DESC92S_RATE54M:
+		rate_idx = 11;
+		break;
+	default:
+		rate_idx = 11;
+		break;
+	}
+	return rate_idx;
+}
+
+static u8 _rtl92s_query_rxpwrpercentage(char antpower)
+{
+	if ((antpower <= -100) || (antpower >= 20))
+		return 0;
+	else if (antpower >= 0)
+		return 100;
+	else
+		return 100 + antpower;
+}
+
+static u8 _rtl92s_evm_db_to_percentage(char value)
+{
+	char ret_val;
+	ret_val = value;
+
+	if (ret_val >= 0)
+		ret_val = 0;
+
+	if (ret_val <= -33)
+		ret_val = -33;
+
+	ret_val = 0 - ret_val;
+	ret_val *= 3;
+
+	if (ret_val == 99)
+		ret_val = 100;
+
+	return ret_val;
+}
+
+static long _rtl92se_translate_todbm(struct ieee80211_hw *hw,
+				     u8 signal_strength_index)
+{
+	long signal_power;
+
+	signal_power = (long)((signal_strength_index + 1) >> 1);
+	signal_power -= 95;
+	return signal_power;
+}
+
+static long _rtl92se_signal_scale_mapping(struct ieee80211_hw *hw,
+		long currsig)
+{
+	long retsig = 0;
+
+	/* Step 1. Scale mapping. */
+	if (currsig > 47)
+		retsig = 100;
+	else if (currsig > 14 && currsig <= 47)
+		retsig = 100 - ((47 - currsig) * 3) / 2;
+	else if (currsig > 2 && currsig <= 14)
+		retsig = 48 - ((14 - currsig) * 15) / 7;
+	else if (currsig >= 0)
+		retsig = currsig * 9 + 1;
+
+	return retsig;
+}
+
+
+static void _rtl92se_query_rxphystatus(struct ieee80211_hw *hw,
+				       struct rtl_stats *pstats, u8 *pdesc,
+				       struct rx_fwinfo *p_drvinfo,
+				       bool packet_match_bssid,
+				       bool packet_toself,
+				       bool packet_beacon)
+{
+	struct rtl_priv *rtlpriv = rtl_priv(hw);
+	struct phy_sts_cck_8192s_t *cck_buf;
+	s8 rx_pwr_all = 0, rx_pwr[4];
+	u8 rf_rx_num = 0, evm, pwdb_all;
+	u8 i, max_spatial_stream;
+	u32 rssi, total_rssi = 0;
+	bool in_powersavemode = false;
+	bool is_cck_rate;
+
+	is_cck_rate = RX_HAL_IS_CCK_RATE(pdesc);
+	pstats->packet_matchbssid = packet_match_bssid;
+	pstats->packet_toself = packet_toself;
+	pstats->is_cck = is_cck_rate;
+	pstats->packet_beacon = packet_beacon;
+	pstats->is_cck = is_cck_rate;
+	pstats->rx_mimo_signalquality[0] = -1;
+	pstats->rx_mimo_signalquality[1] = -1;
+
+	if (is_cck_rate) {
+		u8 report, cck_highpwr;
+		cck_buf = (struct phy_sts_cck_8192s_t *)p_drvinfo;
+
+		if (!in_powersavemode)
+			cck_highpwr = (u8) rtl_get_bbreg(hw,
+						RFPGA0_XA_HSSIPARAMETER2,
+						0x200);
+		else
+			cck_highpwr = false;
+
+		if (!cck_highpwr) {
+			u8 cck_agc_rpt = cck_buf->cck_agc_rpt;
+			report = cck_buf->cck_agc_rpt & 0xc0;
+			report = report >> 6;
+			switch (report) {
+			case 0x3:
+				rx_pwr_all = -40 - (cck_agc_rpt & 0x3e);
+				break;
+			case 0x2:
+				rx_pwr_all = -20 - (cck_agc_rpt & 0x3e);
+				break;
+			case 0x1:
+				rx_pwr_all = -2 - (cck_agc_rpt & 0x3e);
+				break;
+			case 0x0:
+				rx_pwr_all = 14 - (cck_agc_rpt & 0x3e);
+				break;
+			}
+		} else {
+			u8 cck_agc_rpt = cck_buf->cck_agc_rpt;
+			report = p_drvinfo->cfosho[0] & 0x60;
+			report = report >> 5;
+			switch (report) {
+			case 0x3:
+				rx_pwr_all = -40 - ((cck_agc_rpt & 0x1f) << 1);
+				break;
+			case 0x2:
+				rx_pwr_all = -20 - ((cck_agc_rpt & 0x1f) << 1);
+				break;
+			case 0x1:
+				rx_pwr_all = -2 - ((cck_agc_rpt & 0x1f) << 1);
+				break;
+			case 0x0:
+				rx_pwr_all = 14 - ((cck_agc_rpt & 0x1f) << 1);
+				break;
+			}
+		}
+
+		pwdb_all = _rtl92s_query_rxpwrpercentage(rx_pwr_all);
+
+		/* CCK gain is smaller than OFDM/MCS gain,  */
+		/* so we add gain diff by experiences, the val is 6 */
+		pwdb_all += 6;
+		if (pwdb_all > 100)
+			pwdb_all = 100;
+		/* modify the offset to make the same gain index with OFDM. */
+		if (pwdb_all > 34 && pwdb_all <= 42)
+			pwdb_all -= 2;
+		else if (pwdb_all > 26 && pwdb_all <= 34)
+			pwdb_all -= 6;
+		else if (pwdb_all > 14 && pwdb_all <= 26)
+			pwdb_all -= 8;
+		else if (pwdb_all > 4 && pwdb_all <= 14)
+			pwdb_all -= 4;
+
+		pstats->rx_pwdb_all = pwdb_all;
+		pstats->recvsignalpower = rx_pwr_all;
+
+		if (packet_match_bssid) {
+			u8 sq;
+			if (pstats->rx_pwdb_all > 40) {
+				sq = 100;
+			} else {
+				sq = cck_buf->sq_rpt;
+				if (sq > 64)
+					sq = 0;
+				else if (sq < 20)
+					sq = 100;
+				else
+					sq = ((64 - sq) * 100) / 44;
+			}
+
+			pstats->signalquality = sq;
+			pstats->rx_mimo_signalquality[0] = sq;
+			pstats->rx_mimo_signalquality[1] = -1;
+		}
+	} else {
+		rtlpriv->dm.rfpath_rxenable[0] =
+		    rtlpriv->dm.rfpath_rxenable[1] = true;
+		for (i = RF90_PATH_A; i < RF90_PATH_MAX; i++) {
+			if (rtlpriv->dm.rfpath_rxenable[i])
+				rf_rx_num++;
+
+			rx_pwr[i] = ((p_drvinfo->gain_trsw[i] &
+				    0x3f) * 2) - 110;
+			rssi = _rtl92s_query_rxpwrpercentage(rx_pwr[i]);
+			total_rssi += rssi;
+			rtlpriv->stats.rx_snr_db[i] =
+					 (long)(p_drvinfo->rxsnr[i] / 2);
+
+			if (packet_match_bssid)
+				pstats->rx_mimo_signalstrength[i] = (u8) rssi;
+		}
+
+		rx_pwr_all = ((p_drvinfo->pwdb_all >> 1) & 0x7f) - 110;
+		pwdb_all = _rtl92s_query_rxpwrpercentage(rx_pwr_all);
+		pstats->rx_pwdb_all = pwdb_all;
+		pstats->rxpower = rx_pwr_all;
+		pstats->recvsignalpower = rx_pwr_all;
+
+		if (GET_RX_STATUS_DESC_RX_HT(pdesc) &&
+			GET_RX_STATUS_DESC_RX_MCS(pdesc) >= DESC92S_RATEMCS8 &&
+		    GET_RX_STATUS_DESC_RX_MCS(pdesc) <= DESC92S_RATEMCS15)
+			max_spatial_stream = 2;
+		else
+			max_spatial_stream = 1;
+
+		for (i = 0; i < max_spatial_stream; i++) {
+			evm = _rtl92s_evm_db_to_percentage(p_drvinfo->rxevm[i]);
+
+			if (packet_match_bssid) {
+				if (i == 0)
+					pstats->signalquality = (u8)(evm &
+								 0xff);
+				pstats->rx_mimo_signalquality[i] =
+							 (u8) (evm & 0xff);
+			}
+		}
+	}
+
+	if (is_cck_rate)
+		pstats->signalstrength = (u8)(_rtl92se_signal_scale_mapping(hw,
+					 pwdb_all));
+	else if (rf_rx_num != 0)
+		pstats->signalstrength = (u8) (_rtl92se_signal_scale_mapping(hw,
+				total_rssi /= rf_rx_num));
+}
+
+static void _rtl92se_process_ui_rssi(struct ieee80211_hw *hw,
+				     struct rtl_stats *pstats)
+{
+	struct rtl_priv *rtlpriv = rtl_priv(hw);
+	struct rtl_phy *rtlphy = &(rtlpriv->phy);
+	u8 rfpath;
+	u32 last_rssi, tmpval;
+
+	if (pstats->packet_toself || pstats->packet_beacon) {
+		rtlpriv->stats.rssi_calculate_cnt++;
+
+		if (rtlpriv->stats.ui_rssi.total_num++ >=
+		    PHY_RSSI_SLID_WIN_MAX) {
+			rtlpriv->stats.ui_rssi.total_num =
+					 PHY_RSSI_SLID_WIN_MAX;
+			last_rssi = rtlpriv->stats.ui_rssi.elements[
+				rtlpriv->stats.ui_rssi.index];
+			rtlpriv->stats.ui_rssi.total_val -= last_rssi;
+		}
+
+		rtlpriv->stats.ui_rssi.total_val += pstats->signalstrength;
+		rtlpriv->stats.ui_rssi.elements[rtlpriv->stats.ui_rssi.index++]
+			 = pstats->signalstrength;
+
+		if (rtlpriv->stats.ui_rssi.index >= PHY_RSSI_SLID_WIN_MAX)
+			rtlpriv->stats.ui_rssi.index = 0;
+
+		tmpval = rtlpriv->stats.ui_rssi.total_val /
+			rtlpriv->stats.ui_rssi.total_num;
+		rtlpriv->stats.signal_strength = _rtl92se_translate_todbm(hw,
+								(u8) tmpval);
+		pstats->rssi = rtlpriv->stats.signal_strength;
+	}
+
+	if (!pstats->is_cck && pstats->packet_toself) {
+		for (rfpath = RF90_PATH_A; rfpath < rtlphy->num_total_rfpath;
+		     rfpath++) {
+			if (rtlpriv->stats.rx_rssi_percentage[rfpath] == 0) {
+				rtlpriv->stats.rx_rssi_percentage[rfpath] =
+				    pstats->rx_mimo_signalstrength[rfpath];
+
+			}
+
+			if (pstats->rx_mimo_signalstrength[rfpath] >
+			    rtlpriv->stats.rx_rssi_percentage[rfpath]) {
+				rtlpriv->stats.rx_rssi_percentage[rfpath] =
+				    ((rtlpriv->stats.rx_rssi_percentage[rfpath]
+				    * (RX_SMOOTH_FACTOR - 1)) +
+				    (pstats->rx_mimo_signalstrength[rfpath])) /
+				    (RX_SMOOTH_FACTOR);
+
+				rtlpriv->stats.rx_rssi_percentage[rfpath] =
+				    rtlpriv->stats.rx_rssi_percentage[rfpath]
+				    + 1;
+			} else {
+				rtlpriv->stats.rx_rssi_percentage[rfpath] =
+				    ((rtlpriv->stats.rx_rssi_percentage[rfpath]
+				    * (RX_SMOOTH_FACTOR - 1)) +
+				    (pstats->rx_mimo_signalstrength[rfpath])) /
+				    (RX_SMOOTH_FACTOR);
+			}
+
+		}
+	}
+}
+
+static void _rtl92se_update_rxsignalstatistics(struct ieee80211_hw *hw,
+					       struct rtl_stats *pstats)
+{
+	struct rtl_priv *rtlpriv = rtl_priv(hw);
+	int weighting = 0;
+
+	if (rtlpriv->stats.recv_signal_power == 0)
+		rtlpriv->stats.recv_signal_power = pstats->recvsignalpower;
+
+	if (pstats->recvsignalpower > rtlpriv->stats.recv_signal_power)
+		weighting = 5;
+	else if (pstats->recvsignalpower < rtlpriv->stats.recv_signal_power)
+		weighting = (-5);
+
+	rtlpriv->stats.recv_signal_power = (rtlpriv->stats.recv_signal_power * 5
+					   + pstats->recvsignalpower +
+					   weighting) / 6;
+}
+
+static void _rtl92se_process_pwdb(struct ieee80211_hw *hw,
+				  struct rtl_stats *pstats)
+{
+	struct rtl_priv *rtlpriv = rtl_priv(hw);
+	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+	long undec_sm_pwdb = 0;
+
+	if (mac->opmode == NL80211_IFTYPE_ADHOC) {
+		return;
+	} else {
+		undec_sm_pwdb =
+		    rtlpriv->dm.undecorated_smoothed_pwdb;
+	}
+
+	if (pstats->packet_toself || pstats->packet_beacon) {
+		if (undec_sm_pwdb < 0)
+			undec_sm_pwdb = pstats->rx_pwdb_all;
+
+		if (pstats->rx_pwdb_all > (u32) undec_sm_pwdb) {
+			undec_sm_pwdb =
+			    (((undec_sm_pwdb) *
+			    (RX_SMOOTH_FACTOR - 1)) +
+			    (pstats->rx_pwdb_all)) / (RX_SMOOTH_FACTOR);
+
+			undec_sm_pwdb = undec_sm_pwdb + 1;
+		} else {
+			undec_sm_pwdb = (((undec_sm_pwdb) *
+			      (RX_SMOOTH_FACTOR - 1)) + (pstats->rx_pwdb_all)) /
+			      (RX_SMOOTH_FACTOR);
+		}
+
+		rtlpriv->dm.undecorated_smoothed_pwdb = undec_sm_pwdb;
+		_rtl92se_update_rxsignalstatistics(hw, pstats);
+	}
+}
+
+static void rtl_92s_process_streams(struct ieee80211_hw *hw,
+				    struct rtl_stats *pstats)
+{
+	struct rtl_priv *rtlpriv = rtl_priv(hw);
+	u32 stream;
+
+	for (stream = 0; stream < 2; stream++) {
+		if (pstats->rx_mimo_signalquality[stream] != -1) {
+			if (rtlpriv->stats.rx_evm_percentage[stream] == 0) {
+				rtlpriv->stats.rx_evm_percentage[stream] =
+				    pstats->rx_mimo_signalquality[stream];
+			}
+
+			rtlpriv->stats.rx_evm_percentage[stream] =
+			    ((rtlpriv->stats.rx_evm_percentage[stream] *
+					(RX_SMOOTH_FACTOR - 1)) +
+			     (pstats->rx_mimo_signalquality[stream] *
+					1)) / (RX_SMOOTH_FACTOR);
+		}
+	}
+}
+
+static void _rtl92se_process_ui_link_quality(struct ieee80211_hw *hw,
+					     struct rtl_stats *pstats)
+{
+	struct rtl_priv *rtlpriv = rtl_priv(hw);
+	u32 last_evm = 0, tmpval;
+
+	if (pstats->signalquality != 0) {
+		if (pstats->packet_toself || pstats->packet_beacon) {
+
+			if (rtlpriv->stats.ui_link_quality.total_num++ >=
+			    PHY_LINKQUALITY_SLID_WIN_MAX) {
+				rtlpriv->stats.ui_link_quality.total_num =
+				    PHY_LINKQUALITY_SLID_WIN_MAX;
+				last_evm =
+				    rtlpriv->stats.ui_link_quality.elements[
+				    rtlpriv->stats.ui_link_quality.index];
+				rtlpriv->stats.ui_link_quality.total_val -=
+				    last_evm;
+			}
+
+			rtlpriv->stats.ui_link_quality.total_val +=
+			    pstats->signalquality;
+			rtlpriv->stats.ui_link_quality.elements[
+				rtlpriv->stats.ui_link_quality.index++] =
+			    pstats->signalquality;
+
+			if (rtlpriv->stats.ui_link_quality.index >=
+			    PHY_LINKQUALITY_SLID_WIN_MAX)
+				rtlpriv->stats.ui_link_quality.index = 0;
+
+			tmpval = rtlpriv->stats.ui_link_quality.total_val /
+			    rtlpriv->stats.ui_link_quality.total_num;
+			rtlpriv->stats.signal_quality = tmpval;
+
+			rtlpriv->stats.last_sigstrength_inpercent = tmpval;
+
+			rtl_92s_process_streams(hw, pstats);
+
+		}
+	}
+}
+
+static void _rtl92se_process_phyinfo(struct ieee80211_hw *hw,
+				     u8 *buffer,
+				     struct rtl_stats *pcurrent_stats)
+{
+
+	if (!pcurrent_stats->packet_matchbssid &&
+	    !pcurrent_stats->packet_beacon)
+		return;
+
+	_rtl92se_process_ui_rssi(hw, pcurrent_stats);
+	_rtl92se_process_pwdb(hw, pcurrent_stats);
+	_rtl92se_process_ui_link_quality(hw, pcurrent_stats);
+}
+
+static void _rtl92se_translate_rx_signal_stuff(struct ieee80211_hw *hw,
+		struct sk_buff *skb, struct rtl_stats *pstats,
+		u8 *pdesc, struct rx_fwinfo *p_drvinfo)
+{
+	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+	struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
+
+	struct ieee80211_hdr *hdr;
+	u8 *tmp_buf;
+	u8 *praddr;
+	u8 *psaddr;
+	__le16 fc;
+	u16 type, cfc;
+	bool packet_matchbssid, packet_toself, packet_beacon;
+
+	tmp_buf = skb->data + pstats->rx_drvinfo_size + pstats->rx_bufshift;
+
+	hdr = (struct ieee80211_hdr *)tmp_buf;
+	fc = hdr->frame_control;
+	cfc = le16_to_cpu(fc);
+	type = WLAN_FC_GET_TYPE(fc);
+	praddr = hdr->addr1;
+	psaddr = hdr->addr2;
+
+	packet_matchbssid = ((IEEE80211_FTYPE_CTL != type) &&
+	     (!compare_ether_addr(mac->bssid, (cfc & IEEE80211_FCTL_TODS) ?
+			hdr->addr1 : (cfc & IEEE80211_FCTL_FROMDS) ?
+			hdr->addr2 : hdr->addr3)) && (!pstats->hwerror) &&
+			(!pstats->crc) && (!pstats->icv));
+
+	packet_toself = packet_matchbssid &&
+	    (!compare_ether_addr(praddr, rtlefuse->dev_addr));
+
+	if (ieee80211_is_beacon(fc))
+		packet_beacon = true;
+
+	_rtl92se_query_rxphystatus(hw, pstats, pdesc, p_drvinfo,
+			packet_matchbssid, packet_toself, packet_beacon);
+	_rtl92se_process_phyinfo(hw, tmp_buf, pstats);
+}
+
+bool rtl92se_rx_query_desc(struct ieee80211_hw *hw, struct rtl_stats *stats,
+			   struct ieee80211_rx_status *rx_status, u8 *pdesc,
+			   struct sk_buff *skb)
+{
+	struct rx_fwinfo *p_drvinfo;
+	u32 phystatus = (u32)GET_RX_STATUS_DESC_PHY_STATUS(pdesc);
+
+	stats->length = (u16)GET_RX_STATUS_DESC_PKT_LEN(pdesc);
+	stats->rx_drvinfo_size = (u8)GET_RX_STATUS_DESC_DRVINFO_SIZE(pdesc) * 8;
+	stats->rx_bufshift = (u8)(GET_RX_STATUS_DESC_SHIFT(pdesc) & 0x03);
+	stats->icv = (u16)GET_RX_STATUS_DESC_ICV(pdesc);
+	stats->crc = (u16)GET_RX_STATUS_DESC_CRC32(pdesc);
+	stats->hwerror = (u16)(stats->crc | stats->icv);
+	stats->decrypted = !GET_RX_STATUS_DESC_SWDEC(pdesc);
+
+	stats->rate = (u8)GET_RX_STATUS_DESC_RX_MCS(pdesc);
+	stats->shortpreamble = (u16)GET_RX_STATUS_DESC_SPLCP(pdesc);
+	stats->isampdu = (bool)(GET_RX_STATUS_DESC_PAGGR(pdesc) == 1);
+	stats->timestamp_low = GET_RX_STATUS_DESC_TSFL(pdesc);
+	stats->rx_is40Mhzpacket = (bool)GET_RX_STATUS_DESC_BW(pdesc);
+
+	if (stats->hwerror)
+		return false;
+
+	rx_status->freq = hw->conf.channel->center_freq;
+	rx_status->band = hw->conf.channel->band;
+
+	if (GET_RX_STATUS_DESC_CRC32(pdesc))
+		rx_status->flag |= RX_FLAG_FAILED_FCS_CRC;
+
+	if (!GET_RX_STATUS_DESC_SWDEC(pdesc))
+		rx_status->flag |= RX_FLAG_DECRYPTED;
+
+	if (GET_RX_STATUS_DESC_BW(pdesc))
+		rx_status->flag |= RX_FLAG_40MHZ;
+
+	if (GET_RX_STATUS_DESC_RX_HT(pdesc))
+		rx_status->flag |= RX_FLAG_HT;
+
+	rx_status->flag |= RX_FLAG_MACTIME_MPDU;
+
+	if (stats->decrypted)
+		rx_status->flag |= RX_FLAG_DECRYPTED;
+
+	rx_status->rate_idx = _rtl92se_rate_mapping((bool)
+			GET_RX_STATUS_DESC_RX_HT(pdesc),
+			(u8)GET_RX_STATUS_DESC_RX_MCS(pdesc),
+			(bool)GET_RX_STATUS_DESC_PAGGR(pdesc));
+
+
+	rx_status->mactime = GET_RX_STATUS_DESC_TSFL(pdesc);
+	if (phystatus == true) {
+		p_drvinfo = (struct rx_fwinfo *)(skb->data +
+						 stats->rx_bufshift);
+		_rtl92se_translate_rx_signal_stuff(hw, skb, stats, pdesc,
+						   p_drvinfo);
+	}
+
+	/*rx_status->qual = stats->signal; */
+	rx_status->signal = stats->rssi + 10;
+	/*rx_status->noise = -stats->noise; */
+
+	return true;
+}
+
+void rtl92se_tx_fill_desc(struct ieee80211_hw *hw,
+		struct ieee80211_hdr *hdr, u8 *pdesc_tx,
+		struct ieee80211_tx_info *info, struct sk_buff *skb,
+		u8 hw_queue, struct rtl_tcb_desc *ptcb_desc)
+{
+	struct rtl_priv *rtlpriv = rtl_priv(hw);
+	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+	struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+	struct ieee80211_sta *sta = info->control.sta;
+	u8 *pdesc = (u8 *) pdesc_tx;
+	u16 seq_number;
+	__le16 fc = hdr->frame_control;
+	u8 reserved_macid = 0;
+	u8 fw_qsel = _rtl92se_map_hwqueue_to_fwqueue(skb, hw_queue);
+	bool firstseg = (!(hdr->seq_ctrl & cpu_to_le16(IEEE80211_SCTL_FRAG)));
+	bool lastseg = (!(hdr->frame_control &
+			cpu_to_le16(IEEE80211_FCTL_MOREFRAGS)));
+	dma_addr_t mapping = pci_map_single(rtlpci->pdev, skb->data, skb->len,
+		    PCI_DMA_TODEVICE);
+	u8 bw_40 = 0;
+
+	if (mac->opmode == NL80211_IFTYPE_STATION) {
+		bw_40 = mac->bw_40;
+	} else if (mac->opmode == NL80211_IFTYPE_AP ||
+		mac->opmode == NL80211_IFTYPE_ADHOC) {
+		if (sta)
+			bw_40 = sta->ht_cap.cap &
+				    IEEE80211_HT_CAP_SUP_WIDTH_20_40;
+	}
+
+	seq_number = (le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_SEQ) >> 4;
+
+	rtl_get_tcb_desc(hw, info, sta, skb, ptcb_desc);
+
+	CLEAR_PCI_TX_DESC_CONTENT(pdesc, TX_DESC_SIZE_RTL8192S);
+
+	if (firstseg) {
+		if (rtlpriv->dm.useramask) {
+			/* set txdesc macId */
+			if (ptcb_desc->mac_id < 32) {
+				SET_TX_DESC_MACID(pdesc, ptcb_desc->mac_id);
+				reserved_macid |= ptcb_desc->mac_id;
+			}
+		}
+		SET_TX_DESC_RSVD_MACID(pdesc, reserved_macid);
+
+		SET_TX_DESC_TXHT(pdesc, ((ptcb_desc->hw_rate >=
+				 DESC92S_RATEMCS0) ? 1 : 0));
+
+		if (rtlhal->version == VERSION_8192S_ACUT) {
+			if (ptcb_desc->hw_rate == DESC92S_RATE1M ||
+				ptcb_desc->hw_rate  == DESC92S_RATE2M ||
+				ptcb_desc->hw_rate == DESC92S_RATE5_5M ||
+				ptcb_desc->hw_rate == DESC92S_RATE11M) {
+				ptcb_desc->hw_rate = DESC92S_RATE12M;
+			}
+		}
+
+		SET_TX_DESC_TX_RATE(pdesc, ptcb_desc->hw_rate);
+
+		if (ptcb_desc->use_shortgi || ptcb_desc->use_shortpreamble)
+			SET_TX_DESC_TX_SHORT(pdesc, 0);
+
+		/* Aggregation related */
+		if (info->flags & IEEE80211_TX_CTL_AMPDU)
+			SET_TX_DESC_AGG_ENABLE(pdesc, 1);
+
+		/* For AMPDU, we must insert SSN into TX_DESC */
+		SET_TX_DESC_SEQ(pdesc, seq_number);
+
+		/* Protection mode related */
+		/* For 92S, if RTS/CTS are set, HW will execute RTS. */
+		/* We choose only one protection mode to execute */
+		SET_TX_DESC_RTS_ENABLE(pdesc, ((ptcb_desc->rts_enable &&
+				!ptcb_desc->cts_enable) ? 1 : 0));
+		SET_TX_DESC_CTS_ENABLE(pdesc, ((ptcb_desc->cts_enable) ?
+				       1 : 0));
+		SET_TX_DESC_RTS_STBC(pdesc, ((ptcb_desc->rts_stbc) ? 1 : 0));
+
+		SET_TX_DESC_RTS_RATE(pdesc, ptcb_desc->rts_rate);
+		SET_TX_DESC_RTS_BANDWIDTH(pdesc, 0);
+		SET_TX_DESC_RTS_SUB_CARRIER(pdesc, ptcb_desc->rts_sc);
+		SET_TX_DESC_RTS_SHORT(pdesc, ((ptcb_desc->rts_rate <=
+		       DESC92S_RATE54M) ?
+		       (ptcb_desc->rts_use_shortpreamble ? 1 : 0)
+		       : (ptcb_desc->rts_use_shortgi ? 1 : 0)));
+
+
+		/* Set Bandwidth and sub-channel settings. */
+		if (bw_40) {
+			if (ptcb_desc->packet_bw) {
+				SET_TX_DESC_TX_BANDWIDTH(pdesc, 1);
+				/* use duplicated mode */
+				SET_TX_DESC_TX_SUB_CARRIER(pdesc, 0);
+			} else {
+				SET_TX_DESC_TX_BANDWIDTH(pdesc, 0);
+				SET_TX_DESC_TX_SUB_CARRIER(pdesc,
+						   mac->cur_40_prime_sc);
+			}
+		} else {
+			SET_TX_DESC_TX_BANDWIDTH(pdesc, 0);
+			SET_TX_DESC_TX_SUB_CARRIER(pdesc, 0);
+		}
+
+		/* 3 Fill necessary field in First Descriptor */
+		/*DWORD 0*/
+		SET_TX_DESC_LINIP(pdesc, 0);
+		SET_TX_DESC_OFFSET(pdesc, 32);
+		SET_TX_DESC_PKT_SIZE(pdesc, (u16) skb->len);
+
+		/*DWORD 1*/
+		SET_TX_DESC_RA_BRSR_ID(pdesc, ptcb_desc->ratr_index);
+
+		/* Fill security related */
+		if (info->control.hw_key) {
+			struct ieee80211_key_conf *keyconf;
+
+			keyconf = info->control.hw_key;
+			switch (keyconf->cipher) {
+			case WLAN_CIPHER_SUITE_WEP40:
+			case WLAN_CIPHER_SUITE_WEP104:
+				SET_TX_DESC_SEC_TYPE(pdesc, 0x1);
+				break;
+			case WLAN_CIPHER_SUITE_TKIP:
+				SET_TX_DESC_SEC_TYPE(pdesc, 0x2);
+				break;
+			case WLAN_CIPHER_SUITE_CCMP:
+				SET_TX_DESC_SEC_TYPE(pdesc, 0x3);
+				break;
+			default:
+				SET_TX_DESC_SEC_TYPE(pdesc, 0x0);
+				break;
+
+			}
+		}
+
+		/* Set Packet ID */
+		SET_TX_DESC_PACKET_ID(pdesc, 0);
+
+		/* We will assign magement queue to BK. */
+		SET_TX_DESC_QUEUE_SEL(pdesc, fw_qsel);
+
+		/* Alwasy enable all rate fallback range */
+		SET_TX_DESC_DATA_RATE_FB_LIMIT(pdesc, 0x1F);
+
+		/* Fix: I don't kown why hw use 6.5M to tx when set it */
+		SET_TX_DESC_USER_RATE(pdesc,
+				      ptcb_desc->use_driver_rate ? 1 : 0);
+
+		/* Set NON_QOS bit. */
+		if (!ieee80211_is_data_qos(fc))
+			SET_TX_DESC_NON_QOS(pdesc, 1);
+
+	}
+
+	/* Fill fields that are required to be initialized
+	 * in all of the descriptors */
+	/*DWORD 0 */
+	SET_TX_DESC_FIRST_SEG(pdesc, (firstseg ? 1 : 0));
+	SET_TX_DESC_LAST_SEG(pdesc, (lastseg ? 1 : 0));
+
+	/* DWORD 7 */
+	SET_TX_DESC_TX_BUFFER_SIZE(pdesc, (u16) skb->len);
+
+	/* DOWRD 8 */
+	SET_TX_DESC_TX_BUFFER_ADDRESS(pdesc, cpu_to_le32(mapping));
+
+	RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE, ("\n"));
+}
+
+void rtl92se_tx_fill_cmddesc(struct ieee80211_hw *hw, u8 *pdesc,
+	bool firstseg, bool lastseg, struct sk_buff *skb)
+{
+	struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+	struct rtl_tcb_desc *tcb_desc = (struct rtl_tcb_desc *)(skb->cb);
+
+	dma_addr_t mapping = pci_map_single(rtlpci->pdev, skb->data, skb->len,
+			PCI_DMA_TODEVICE);
+
+    /* Clear all status	*/
+	CLEAR_PCI_TX_DESC_CONTENT(pdesc, TX_CMDDESC_SIZE_RTL8192S);
+
+	/* This bit indicate this packet is used for FW download. */
+	if (tcb_desc->cmd_or_init == DESC_PACKET_TYPE_INIT) {
+		/* For firmware downlaod we only need to set LINIP */
+		SET_TX_DESC_LINIP(pdesc, tcb_desc->last_inipkt);
+
+		/* 92SE must set as 1 for firmware download HW DMA error */
+		SET_TX_DESC_FIRST_SEG(pdesc, 1);
+		SET_TX_DESC_LAST_SEG(pdesc, 1);
+
+		/* 92SE need not to set TX packet size when firmware download */
+		SET_TX_DESC_PKT_SIZE(pdesc, (u16)(skb->len));
+		SET_TX_DESC_TX_BUFFER_SIZE(pdesc, (u16)(skb->len));
+		SET_TX_DESC_TX_BUFFER_ADDRESS(pdesc, cpu_to_le32(mapping));
+
+		SET_TX_DESC_OWN(pdesc, 1);
+	} else { /* H2C Command Desc format (Host TXCMD) */
+		/* 92SE must set as 1 for firmware download HW DMA error */
+		SET_TX_DESC_FIRST_SEG(pdesc, 1);
+		SET_TX_DESC_LAST_SEG(pdesc, 1);
+
+		SET_TX_DESC_OFFSET(pdesc, 0x20);
+
+		/* Buffer size + command header */
+		SET_TX_DESC_PKT_SIZE(pdesc, (u16)(skb->len));
+		/* Fixed queue of H2C command */
+		SET_TX_DESC_QUEUE_SEL(pdesc, 0x13);
+
+		SET_BITS_TO_LE_4BYTE(skb->data, 24, 7, rtlhal->h2c_txcmd_seq);
+
+		SET_TX_DESC_TX_BUFFER_SIZE(pdesc, (u16)(skb->len));
+		SET_TX_DESC_TX_BUFFER_ADDRESS(pdesc, cpu_to_le32(mapping));
+
+		SET_TX_DESC_OWN(pdesc, 1);
+
+	}
+}
+
+void rtl92se_set_desc(u8 *pdesc, bool istx, u8 desc_name, u8 *val)
+{
+	if (istx == true) {
+		switch (desc_name) {
+		case HW_DESC_OWN:
+			SET_TX_DESC_OWN(pdesc, 1);
+			break;
+		case HW_DESC_TX_NEXTDESC_ADDR:
+			SET_TX_DESC_NEXT_DESC_ADDRESS(pdesc, *(u32 *) val);
+			break;
+		default:
+			RT_ASSERT(false, ("ERR txdesc :%d not process\n",
+				  desc_name));
+			break;
+		}
+	} else {
+		switch (desc_name) {
+		case HW_DESC_RXOWN:
+			SET_RX_STATUS_DESC_OWN(pdesc, 1);
+			break;
+		case HW_DESC_RXBUFF_ADDR:
+			SET_RX_STATUS__DESC_BUFF_ADDR(pdesc, *(u32 *) val);
+			break;
+		case HW_DESC_RXPKT_LEN:
+			SET_RX_STATUS_DESC_PKT_LEN(pdesc, *(u32 *) val);
+			break;
+		case HW_DESC_RXERO:
+			SET_RX_STATUS_DESC_EOR(pdesc, 1);
+			break;
+		default:
+			RT_ASSERT(false, ("ERR rxdesc :%d not process\n",
+				  desc_name));
+			break;
+		}
+	}
+}
+
+u32 rtl92se_get_desc(u8 *desc, bool istx, u8 desc_name)
+{
+	u32 ret = 0;
+
+	if (istx == true) {
+		switch (desc_name) {
+		case HW_DESC_OWN:
+			ret = GET_TX_DESC_OWN(desc);
+			break;
+		case HW_DESC_TXBUFF_ADDR:
+			ret = GET_TX_DESC_TX_BUFFER_ADDRESS(desc);
+			break;
+		default:
+			RT_ASSERT(false, ("ERR txdesc :%d not process\n",
+				  desc_name));
+			break;
+		}
+	} else {
+		switch (desc_name) {
+		case HW_DESC_OWN:
+			ret = GET_RX_STATUS_DESC_OWN(desc);
+			break;
+		case HW_DESC_RXPKT_LEN:
+			ret = GET_RX_STATUS_DESC_PKT_LEN(desc);
+			break;
+		default:
+			RT_ASSERT(false, ("ERR rxdesc :%d not process\n",
+				  desc_name));
+			break;
+		}
+	}
+	return ret;
+}
+
+void rtl92se_tx_polling(struct ieee80211_hw *hw, u8 hw_queue)
+{
+	struct rtl_priv *rtlpriv = rtl_priv(hw);
+	rtl_write_word(rtlpriv, TP_POLL, BIT(0) << (hw_queue));
+}
diff -druN linux-2.6.39-libre/drivers/net/wireless/rtlwifi/rtl8192se/trx.h linux-3.0-rc7-libre/drivers/net/wireless/rtlwifi/rtl8192se/trx.h
--- linux-2.6.39-libre/drivers/net/wireless/rtlwifi/rtl8192se/trx.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/net/wireless/rtlwifi/rtl8192se/trx.h	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,45 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2009-2010  Realtek Corporation.
+ *
+ * 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:
+ * wlanfae <wlanfae@realtek.com>
+ * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
+ * Hsinchu 300, Taiwan.
+ *
+ * Larry Finger <Larry.Finger@lwfinger.net>
+ *
+ *****************************************************************************/
+#ifndef __REALTEK_PCI92SE_TRX_H__
+#define __REALTEK_PCI92SE_TRX_H__
+
+void rtl92se_tx_fill_desc(struct ieee80211_hw *hw, struct ieee80211_hdr *hdr,
+			  u8 *pdesc, struct ieee80211_tx_info *info,
+			  struct sk_buff *skb, u8 hw_queue,
+			  struct rtl_tcb_desc *ptcb_desc);
+void rtl92se_tx_fill_cmddesc(struct ieee80211_hw *hw, u8 *pdesc, bool firstseg,
+			     bool lastseg, struct sk_buff *skb);
+bool rtl92se_rx_query_desc(struct ieee80211_hw *hw, struct rtl_stats *stats,
+			   struct ieee80211_rx_status *rx_status, u8 *pdesc,
+			   struct sk_buff *skb);
+void rtl92se_set_desc(u8 *pdesc, bool istx, u8 desc_name, u8 *val);
+u32 rtl92se_get_desc(u8 *pdesc, bool istx, u8 desc_name);
+void rtl92se_tx_polling(struct ieee80211_hw *hw, u8 hw_queue);
+
+#endif
diff -druN linux-2.6.39-libre/drivers/net/wireless/rtlwifi/usb.c linux-3.0-rc7-libre/drivers/net/wireless/rtlwifi/usb.c
--- linux-2.6.39-libre/drivers/net/wireless/rtlwifi/usb.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/rtlwifi/usb.c	2011-07-11 19:51:52.000000000 -0400
@@ -852,6 +852,7 @@
 	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
 	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
 	struct rtl_tx_desc *pdesc = NULL;
+	struct rtl_tcb_desc tcb_desc;
 	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)(skb->data);
 	__le16 fc = hdr->frame_control;
 	u8 *pda_addr = hdr->addr1;
@@ -860,8 +861,17 @@
 	u8 tid = 0;
 	u16 seq_number = 0;
 
-	if (ieee80211_is_mgmt(fc))
-		rtl_tx_mgmt_proc(hw, skb);
+	if (ieee80211_is_auth(fc)) {
+		RT_TRACE(rtlpriv, COMP_SEND, DBG_DMESG, ("MAC80211_LINKING\n"));
+		rtl_ips_nic_on(hw);
+	}
+
+	if (rtlpriv->psc.sw_ps_enabled) {
+		if (ieee80211_is_data(fc) && !ieee80211_is_nullfunc(fc) &&
+		    !ieee80211_has_pm(fc))
+			hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_PM);
+	}
+
 	rtl_action_proc(hw, skb, true);
 	if (is_multicast_ether_addr(pda_addr))
 		rtlpriv->stats.txbytesmulticast += skb->len;
@@ -878,7 +888,7 @@
 		seq_number <<= 4;
 	}
 	rtlpriv->cfg->ops->fill_tx_desc(hw, hdr, (u8 *)pdesc, info, skb,
-					hw_queue);
+					hw_queue, &tcb_desc);
 	if (!ieee80211_has_morefrags(hdr->frame_control)) {
 		if (qc)
 			mac->tids[tid].seq_number = seq_number;
@@ -887,7 +897,8 @@
 		rtlpriv->cfg->ops->led_control(hw, LED_CTL_TX);
 }
 
-static int rtl_usb_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
+static int rtl_usb_tx(struct ieee80211_hw *hw, struct sk_buff *skb,
+		      struct rtl_tcb_desc *dummy)
 {
 	struct rtl_usb *rtlusb = rtl_usbdev(rtl_usbpriv(hw));
 	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
diff -druN linux-2.6.39-libre/drivers/net/wireless/rtlwifi/usb.h linux-3.0-rc7-libre/drivers/net/wireless/rtlwifi/usb.h
--- linux-2.6.39-libre/drivers/net/wireless/rtlwifi/usb.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/rtlwifi/usb.h	2011-07-11 19:51:52.000000000 -0400
@@ -31,6 +31,8 @@
 #include <linux/usb.h>
 #include <linux/skbuff.h>
 
+#define RTL_RX_DESC_SIZE		24
+
 #define RTL_USB_DEVICE(vend, prod, cfg) \
 	.match_flags = USB_DEVICE_ID_MATCH_DEVICE, \
 	.idVendor = (vend), \
diff -druN linux-2.6.39-libre/drivers/net/wireless/rtlwifi/wifi.h linux-3.0-rc7-libre/drivers/net/wireless/rtlwifi/wifi.h
--- linux-2.6.39-libre/drivers/net/wireless/rtlwifi/wifi.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/rtlwifi/wifi.h	2011-07-11 19:51:52.000000000 -0400
@@ -68,6 +68,8 @@
 #define QBSS_LOAD_SIZE				5
 #define MAX_WMMELE_LENGTH			64
 
+#define TOTAL_CAM_ENTRY				32
+
 /*slot time for 11g. */
 #define RTL_SLOT_TIME_9				9
 #define RTL_SLOT_TIME_20			20
@@ -94,8 +96,10 @@
 #define	CHANNEL_GROUP_MAX_5G		9
 #define CHANNEL_MAX_NUMBER_2G		14
 #define AVG_THERMAL_NUM			8
+#define MAX_TID_COUNT			9
 
 /* for early mode */
+#define FCS_LEN				4
 #define EM_HDR_LEN			8
 enum intf_type {
 	INTF_PCI = 0,
@@ -159,6 +163,8 @@
 (IS_HARDWARE_TYPE_8192DE(rtlhal) || IS_HARDWARE_TYPE_8192DU(rtlhal))
 #define	IS_HARDWARE_TYPE_8723(rtlhal)			\
 (IS_HARDWARE_TYPE_8723E(rtlhal) || IS_HARDWARE_TYPE_8723U(rtlhal))
+#define IS_HARDWARE_TYPE_8723U(rtlhal)			\
+	(rtlhal->hw_type == HARDWARE_TYPE_RTL8723U)
 
 enum scan_operation_backup_opt {
 	SCAN_OPT_BACKUP = 0,
@@ -297,6 +303,9 @@
 	HW_VAR_DATA_FILTER,
 };
 
+#define HWSET_MAX_SIZE				128
+#define EFUSE_MAX_SECTION			16
+
 enum _RT_MEDIA_STATUS {
 	RT_MEDIA_DISCONNECT = 0,
 	RT_MEDIA_CONNECT = 1
@@ -766,7 +775,7 @@
 #define IQK_MATRIX_REG_NUM	8
 #define IQK_MATRIX_SETTINGS_NUM	(1 + 24 + 21)
 struct iqk_matrix_regs {
-	bool b_iqk_done;
+	bool iqk_done;
 	long value[1][IQK_MATRIX_REG_NUM];
 };
 
@@ -843,6 +852,7 @@
 	bool apk_done;
 	u32 reg_rf3c[2];	/* pathA / pathB  */
 
+	/* bfsync */
 	u8 framesync;
 	u32 framesync_c34;
 
@@ -852,6 +862,10 @@
 };
 
 #define MAX_TID_COUNT				9
+#define RTL_AGG_STOP				0
+#define RTL_AGG_PROGRESS			1
+#define RTL_AGG_START				2
+#define RTL_AGG_OPERATIONAL			3
 #define RTL_AGG_OFF				0
 #define RTL_AGG_ON				1
 #define RTL_AGG_EMPTYING_HW_QUEUE_ADDBA		2
@@ -871,6 +885,13 @@
 	struct rtl_ht_agg agg;
 };
 
+struct rtl_sta_info {
+	u8 ratr_index;
+	u8 wireless_mode;
+	u8 mimo_ps;
+	struct rtl_tid_data tids[MAX_TID_COUNT];
+} __packed;
+
 struct rtl_priv;
 struct rtl_io {
 	struct device *dev;
@@ -894,6 +915,7 @@
 	u32(*read32_sync) (struct rtl_priv *rtlpriv, u32 addr);
 	int (*readN_sync) (struct rtl_priv *rtlpriv, u32 addr, u16 len,
 			    u8 *pdata);
+
 };
 
 struct rtl_mac {
@@ -916,6 +938,8 @@
 	int n_channels;
 	int n_bitrates;
 
+	bool offchan_deley;
+
 	/*filters */
 	u32 rx_conf;
 	u16 rx_mgt_filter;
@@ -1032,7 +1056,9 @@
 	enum rt_enc_alg pairwise_enc_algorithm;
 	/*Encryption Algorithm for Brocast/Multicast */
 	enum rt_enc_alg group_enc_algorithm;
-
+	/*Cam Entry Bitmap */
+	u32 hwsec_cam_bitmap;
+	u8 hwsec_cam_sta_addr[TOTAL_CAM_ENTRY][ETH_ALEN];
 	/*local Key buffer, indx 0 is for
 	   pairwise key 1-4 is for agoup key. */
 	u8 key_buf[KEY_BUF_SIZE][MAX_KEY_LEN];
@@ -1053,7 +1079,7 @@
 	bool current_turbo_edca;
 	bool is_any_nonbepkts;	/*out dm */
 	bool is_cur_rdlstate;
-	bool txpower_trackingInit;
+	bool txpower_trackinginit;
 	bool disable_framebursting;
 	bool cck_inch14;
 	bool txpower_tracking;
@@ -1079,7 +1105,6 @@
 	bool disable_tx_int;
 	char ofdm_index[2];
 	char cck_index;
-	u8 power_index_backup[6];
 };
 
 #define	EFUSE_MAX_LOGICAL_SIZE			256
@@ -1175,6 +1200,7 @@
 	 * otherwise Offset[560h] = 0x00.
 	 * */
 	bool support_aspm;
+
 	bool support_backdoor;
 
 	/*for LPS */
@@ -1201,7 +1227,6 @@
 
 	/*just for PCIE ASPM */
 	u8 const_amdpci_aspm;
-
 	bool pwrdown_mode;
 
 	enum rf_pwrstate inactive_pwrstate;
@@ -1282,6 +1307,10 @@
 	bool busytraffic;
 	bool higher_busytraffic;
 	bool higher_busyrxtraffic;
+
+	u32 tidtx_in4period[MAX_TID_COUNT][4];
+	u32 tidtx_inperiod[MAX_TID_COUNT];
+	bool higher_busytxtraffic[MAX_TID_COUNT];
 };
 
 struct rtl_tcb_desc {
@@ -1344,13 +1373,15 @@
 				       u32 add_msr, u32 rm_msr);
 	void (*get_hw_reg) (struct ieee80211_hw *hw, u8 variable, u8 *val);
 	void (*set_hw_reg) (struct ieee80211_hw *hw, u8 variable, u8 *val);
-	void (*update_rate_table) (struct ieee80211_hw *hw);
+	void (*update_rate_tbl) (struct ieee80211_hw *hw,
+			      struct ieee80211_sta *sta, u8 rssi_level);
 	void (*update_rate_mask) (struct ieee80211_hw *hw, u8 rssi_level);
 	void (*fill_tx_desc) (struct ieee80211_hw *hw,
 			      struct ieee80211_hdr *hdr, u8 *pdesc_tx,
 			      struct ieee80211_tx_info *info,
-			      struct sk_buff *skb, unsigned int queue_index);
-	void (*fill_fake_txdesc) (struct ieee80211_hw *hw, u8 * pDesc,
+			      struct sk_buff *skb, u8 hw_queue,
+			      struct rtl_tcb_desc *ptcb_desc);
+	void (*fill_fake_txdesc) (struct ieee80211_hw *hw, u8 *pDesc,
 				  u32 buffer_len, bool bIsPsPoll);
 	void (*fill_tx_cmddesc) (struct ieee80211_hw *hw, u8 *pdesc,
 				 bool firstseg, bool lastseg,
@@ -1370,10 +1401,10 @@
 			     enum led_ctl_mode ledaction);
 	void (*set_desc) (u8 *pdesc, bool istx, u8 desc_name, u8 *val);
 	u32 (*get_desc) (u8 *pdesc, bool istx, u8 desc_name);
-	void (*tx_polling) (struct ieee80211_hw *hw, unsigned int hw_queue);
+	void (*tx_polling) (struct ieee80211_hw *hw, u8 hw_queue);
 	void (*enable_hw_sec) (struct ieee80211_hw *hw);
 	void (*set_key) (struct ieee80211_hw *hw, u32 key_index,
-			 u8 *p_macaddr, bool is_group, u8 enc_algo,
+			 u8 *macaddr, bool is_group, u8 enc_algo,
 			 bool is_wepkey, bool clear_all);
 	void (*init_sw_leds) (struct ieee80211_hw *hw);
 	void (*deinit_sw_leds) (struct ieee80211_hw *hw);
@@ -1384,6 +1415,7 @@
 			  u32 regaddr, u32 bitmask);
 	void (*set_rfreg) (struct ieee80211_hw *hw, enum radio_path rfpath,
 			   u32 regaddr, u32 bitmask, u32 data);
+	void (*linked_set_reg) (struct ieee80211_hw *hw);
 	bool (*phy_rf6052_config) (struct ieee80211_hw *hw);
 	void (*phy_rf6052_set_cck_txpower) (struct ieee80211_hw *hw,
 					    u8 *powerlevel);
@@ -1404,7 +1436,9 @@
 	int (*adapter_start) (struct ieee80211_hw *hw);
 	void (*adapter_stop) (struct ieee80211_hw *hw);
 
-	int (*adapter_tx) (struct ieee80211_hw *hw, struct sk_buff *skb);
+	int (*adapter_tx) (struct ieee80211_hw *hw, struct sk_buff *skb,
+			struct rtl_tcb_desc *ptcb_desc);
+	void (*flush)(struct ieee80211_hw *hw, bool drop);
 	int (*reset_trx_ring) (struct ieee80211_hw *hw);
 	bool (*waitq_insert) (struct ieee80211_hw *hw, struct sk_buff *skb);
 
@@ -1418,6 +1452,15 @@
 struct rtl_mod_params {
 	/* default: 0 = using hardware encryption */
 	int sw_crypto;
+
+	/* default: 1 = using no linked power save */
+	bool inactiveps;
+
+	/* default: 1 = using linked sw power save */
+	bool swctrl_lps;
+
+	/* default: 1 = using linked fw power save */
+	bool fwctrl_lps;
 };
 
 struct rtl_hal_usbint_cfg {
@@ -1445,6 +1488,7 @@
 
 struct rtl_hal_cfg {
 	u8 bar_id;
+	bool write_readback;
 	char *name;
 	char *fw_name;
 	struct rtl_hal_ops *ops;
@@ -1469,7 +1513,6 @@
 	spinlock_t rf_lock;
 	spinlock_t lps_lock;
 	spinlock_t waitq_lock;
-	spinlock_t tx_urb_lock;
 
 	/*Dual mac*/
 	spinlock_t cck_and_rw_pagea_lock;
@@ -1621,19 +1664,19 @@
 	u32 bt_edca_ul;
 	u32 bt_edca_dl;
 
-	bool b_init_set;
-	bool b_bt_busy_traffic;
-	bool b_bt_traffic_mode_set;
-	bool b_bt_non_traffic_mode_set;
+	bool init_set;
+	bool bt_busy_traffic;
+	bool bt_traffic_mode_set;
+	bool bt_non_traffic_mode_set;
 
-	bool b_fw_coexist_all_off;
-	bool b_sw_coexist_all_off;
+	bool fw_coexist_all_off;
+	bool sw_coexist_all_off;
 	u32 current_state;
 	u32 previous_state;
 	u8 bt_pre_rssi_state;
 
-	u8 b_reg_bt_iso;
-	u8 b_reg_bt_sco;
+	u8 reg_bt_iso;
+	u8 reg_bt_sco;
 
 };
 
@@ -1653,13 +1696,23 @@
 #define EF4BYTE(_val)		\
 	(le32_to_cpu(_val))
 
+/* Read data from memory */
+#define READEF1BYTE(_ptr)	\
+	EF1BYTE(*((u8 *)(_ptr)))
 /* Read le16 data from memory and convert to host ordering */
 #define READEF2BYTE(_ptr)	\
 	EF2BYTE(*((u16 *)(_ptr)))
+#define READEF4BYTE(_ptr)	\
+	EF4BYTE(*((u32 *)(_ptr)))
 
+/* Write data to memory */
+#define WRITEEF1BYTE(_ptr, _val)	\
+	(*((u8 *)(_ptr))) = EF1BYTE(_val)
 /* Write le16 data to memory in host ordering */
 #define WRITEEF2BYTE(_ptr, _val)	\
 	(*((u16 *)(_ptr))) = EF2BYTE(_val)
+#define WRITEEF4BYTE(_ptr, _val)	\
+	(*((u16 *)(_ptr))) = EF2BYTE(_val)
 
 /* Create a bit mask
  * Examples:
@@ -1698,6 +1751,25 @@
 #define LE_P1BYTE_TO_HOST_1BYTE(__pstart) \
 	(EF1BYTE(*((u8 *)(__pstart))))
 
+/*Description:
+Translate subfield (continuous bits in little-endian) of 4-byte
+value to host byte ordering.*/
+#define LE_BITS_TO_4BYTE(__pstart, __bitoffset, __bitlen) \
+	( \
+		(LE_P4BYTE_TO_HOST_4BYTE(__pstart) >> (__bitoffset))  & \
+		BIT_LEN_MASK_32(__bitlen) \
+	)
+#define LE_BITS_TO_2BYTE(__pstart, __bitoffset, __bitlen) \
+	( \
+		(LE_P2BYTE_TO_HOST_2BYTE(__pstart) >> (__bitoffset)) & \
+		BIT_LEN_MASK_16(__bitlen) \
+	)
+#define LE_BITS_TO_1BYTE(__pstart, __bitoffset, __bitlen) \
+	( \
+		(LE_P1BYTE_TO_HOST_1BYTE(__pstart) >> (__bitoffset)) & \
+		BIT_LEN_MASK_8(__bitlen) \
+	)
+
 /* Description:
  * Mask subfield (continuous bits in little-endian) of 4-byte value
  * and return the result in 4-byte value in host byte ordering.
@@ -1721,6 +1793,18 @@
 /* Description:
  * Set subfield of little-endian 4-byte value to specified value.
  */
+#define SET_BITS_TO_LE_4BYTE(__pstart, __bitoffset, __bitlen, __val) \
+	*((u32 *)(__pstart)) = EF4BYTE \
+	( \
+		LE_BITS_CLEARED_TO_4BYTE(__pstart, __bitoffset, __bitlen) | \
+		((((u32)__val) & BIT_LEN_MASK_32(__bitlen)) << (__bitoffset)) \
+	);
+#define SET_BITS_TO_LE_2BYTE(__pstart, __bitoffset, __bitlen, __val) \
+	*((u16 *)(__pstart)) = EF2BYTE \
+	( \
+		LE_BITS_CLEARED_TO_2BYTE(__pstart, __bitoffset, __bitlen) | \
+		((((u16)__val) & BIT_LEN_MASK_16(__bitlen)) << (__bitoffset)) \
+	);
 #define SET_BITS_TO_LE_1BYTE(__pstart, __bitoffset, __bitlen, __val) \
 	*((u8 *)(__pstart)) = EF1BYTE \
 	( \
@@ -1728,12 +1812,16 @@
 		((((u8)__val) & BIT_LEN_MASK_8(__bitlen)) << (__bitoffset)) \
 	);
 
+#define	N_BYTE_ALIGMENT(__value, __aligment) ((__aligment == 1) ? \
+	(__value) : (((__value + __aligment - 1) / __aligment) * __aligment))
+
 /****************************************
 	mem access macro define end
 ****************************************/
 
 #define byte(x, n) ((x >> (8 * n)) & 0xff)
 
+#define packet_get_type(_packet) (EF1BYTE((_packet).octet[0]) & 0xFC)
 #define RTL_WATCH_DOG_TIME	2000
 #define MSECS(t)		msecs_to_jiffies(t)
 #define WLAN_FC_GET_VERS(fc)	(le16_to_cpu(fc) & IEEE80211_FCTL_VERS)
@@ -1768,6 +1856,15 @@
 #define container_of_dwork_rtl(x, y, z) \
 	container_of(container_of(x, struct delayed_work, work), y, z)
 
+#define FILL_OCTET_STRING(_os, _octet, _len)	\
+		(_os).octet = (u8 *)(_octet);		\
+		(_os).length = (_len);
+
+#define CP_MACADDR(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])
+
 static inline u8 rtl_read_byte(struct rtl_priv *rtlpriv, u32 addr)
 {
 	return rtlpriv->io.read8_sync(rtlpriv, addr);
@@ -1786,17 +1883,26 @@
 static inline void rtl_write_byte(struct rtl_priv *rtlpriv, u32 addr, u8 val8)
 {
 	rtlpriv->io.write8_async(rtlpriv, addr, val8);
+
+	if (rtlpriv->cfg->write_readback)
+		rtlpriv->io.read8_sync(rtlpriv, addr);
 }
 
 static inline void rtl_write_word(struct rtl_priv *rtlpriv, u32 addr, u16 val16)
 {
 	rtlpriv->io.write16_async(rtlpriv, addr, val16);
+
+	if (rtlpriv->cfg->write_readback)
+		rtlpriv->io.read16_sync(rtlpriv, addr);
 }
 
 static inline void rtl_write_dword(struct rtl_priv *rtlpriv,
 				   u32 addr, u32 val32)
 {
 	rtlpriv->io.write32_async(rtlpriv, addr, val32);
+
+	if (rtlpriv->cfg->write_readback)
+		rtlpriv->io.read32_sync(rtlpriv, addr);
 }
 
 static inline u32 rtl_get_bbreg(struct ieee80211_hw *hw,
@@ -1855,4 +1961,31 @@
 	return rtlphy->rf_type;
 }
 
+static inline struct ieee80211_hdr *rtl_get_hdr(struct sk_buff *skb)
+{
+	return (struct ieee80211_hdr *)(skb->data);
+}
+
+static inline __le16 rtl_get_fc(struct sk_buff *skb)
+{
+	return rtl_get_hdr(skb)->frame_control;
+}
+
+static inline u16 rtl_get_tid_h(struct ieee80211_hdr *hdr)
+{
+	return (ieee80211_get_qos_ctl(hdr))[0] & IEEE80211_QOS_CTL_TID_MASK;
+}
+
+static inline u16 rtl_get_tid(struct sk_buff *skb)
+{
+	return rtl_get_tid_h(rtl_get_hdr(skb));
+}
+
+static inline struct ieee80211_sta *get_sta(struct ieee80211_hw *hw,
+					    struct ieee80211_vif *vif,
+					    u8 *bssid)
+{
+	return ieee80211_find_sta(vif, bssid);
+}
+
 #endif
diff -druN linux-2.6.39-libre/drivers/net/wireless/wl1251/cmd.h linux-3.0-rc7-libre/drivers/net/wireless/wl1251/cmd.h
--- linux-2.6.39-libre/drivers/net/wireless/wl1251/cmd.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/wl1251/cmd.h	2011-07-11 19:51:52.000000000 -0400
@@ -313,8 +313,8 @@
 } __packed;
 
 enum wl1251_cmd_ps_mode {
-	STATION_ACTIVE_MODE,
-	STATION_POWER_SAVE_MODE
+	CHIP_ACTIVE_MODE,
+	CHIP_POWER_SAVE_MODE
 };
 
 struct wl1251_cmd_ps_params {
diff -druN linux-2.6.39-libre/drivers/net/wireless/wl1251/event.c linux-3.0-rc7-libre/drivers/net/wireless/wl1251/event.c
--- linux-2.6.39-libre/drivers/net/wireless/wl1251/event.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/wl1251/event.c	2011-07-11 19:51:52.000000000 -0400
@@ -68,14 +68,16 @@
 	if (vector & BSS_LOSE_EVENT_ID) {
 		wl1251_debug(DEBUG_EVENT, "BSS_LOSE_EVENT");
 
-		if (wl->psm_requested && wl->psm) {
+		if (wl->psm_requested &&
+		    wl->station_mode != STATION_ACTIVE_MODE) {
 			ret = wl1251_ps_set_mode(wl, STATION_ACTIVE_MODE);
 			if (ret < 0)
 				return ret;
 		}
 	}
 
-	if (vector & SYNCHRONIZATION_TIMEOUT_EVENT_ID && wl->psm) {
+	if (vector & SYNCHRONIZATION_TIMEOUT_EVENT_ID &&
+	    wl->station_mode != STATION_ACTIVE_MODE) {
 		wl1251_debug(DEBUG_EVENT, "SYNCHRONIZATION_TIMEOUT_EVENT");
 
 		/* indicate to the stack, that beacons have been lost */
diff -druN linux-2.6.39-libre/drivers/net/wireless/wl1251/main.c linux-3.0-rc7-libre/drivers/net/wireless/wl1251/main.c
--- linux-2.6.39-libre/drivers/net/wireless/wl1251/main.c	2011-05-19 02:16:13.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/wl1251/main.c	2011-07-21 06:58:19.000000000 -0400
@@ -497,7 +497,7 @@
 	wl->rx_last_id = 0;
 	wl->next_tx_complete = 0;
 	wl->elp = false;
-	wl->psm = 0;
+	wl->station_mode = STATION_ACTIVE_MODE;
 	wl->tx_queue_stopped = false;
 	wl->power_level = WL1251_DEFAULT_POWER_LEVEL;
 	wl->rssi_thold = 0;
@@ -632,10 +632,26 @@
 
 		wl->psm_requested = false;
 
-		if (wl->psm) {
+		if (wl->station_mode != STATION_ACTIVE_MODE) {
+			ret = wl1251_ps_set_mode(wl, STATION_ACTIVE_MODE);
+			if (ret < 0)
+				goto out_sleep;
+		}
+	}
+
+	if (changed & IEEE80211_CONF_CHANGE_IDLE) {
+		if (conf->flags & IEEE80211_CONF_IDLE) {
+			ret = wl1251_ps_set_mode(wl, STATION_IDLE);
+			if (ret < 0)
+				goto out_sleep;
+		} else {
 			ret = wl1251_ps_set_mode(wl, STATION_ACTIVE_MODE);
 			if (ret < 0)
 				goto out_sleep;
+			ret = wl1251_join(wl, wl->bss_type, wl->channel,
+					  wl->beacon_int, wl->dtim_period);
+			if (ret < 0)
+				goto out_sleep;
 		}
 	}
 
@@ -1384,7 +1400,7 @@
 	wl->rx_config = WL1251_DEFAULT_RX_CONFIG;
 	wl->rx_filter = WL1251_DEFAULT_RX_FILTER;
 	wl->elp = false;
-	wl->psm = 0;
+	wl->station_mode = STATION_ACTIVE_MODE;
 	wl->psm_requested = false;
 	wl->tx_queue_stopped = false;
 	wl->power_level = WL1251_DEFAULT_POWER_LEVEL;
diff -druN linux-2.6.39-libre/drivers/net/wireless/wl1251/ps.c linux-3.0-rc7-libre/drivers/net/wireless/wl1251/ps.c
--- linux-2.6.39-libre/drivers/net/wireless/wl1251/ps.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/wl1251/ps.c	2011-07-11 19:51:52.000000000 -0400
@@ -39,7 +39,7 @@
 
 	mutex_lock(&wl->mutex);
 
-	if (wl->elp || !wl->psm)
+	if (wl->elp || wl->station_mode == STATION_ACTIVE_MODE)
 		goto out;
 
 	wl1251_debug(DEBUG_PSM, "chip to elp");
@@ -57,7 +57,7 @@
 {
 	unsigned long delay;
 
-	if (wl->psm) {
+	if (wl->station_mode != STATION_ACTIVE_MODE) {
 		delay = msecs_to_jiffies(ELP_ENTRY_DELAY);
 		ieee80211_queue_delayed_work(wl->hw, &wl->elp_work, delay);
 	}
@@ -104,7 +104,7 @@
 	return 0;
 }
 
-int wl1251_ps_set_mode(struct wl1251 *wl, enum wl1251_cmd_ps_mode mode)
+int wl1251_ps_set_mode(struct wl1251 *wl, enum wl1251_station_mode mode)
 {
 	int ret;
 
@@ -128,15 +128,24 @@
 		if (ret < 0)
 			return ret;
 
-		ret = wl1251_cmd_ps_mode(wl, STATION_POWER_SAVE_MODE);
+		ret = wl1251_cmd_ps_mode(wl, CHIP_POWER_SAVE_MODE);
 		if (ret < 0)
 			return ret;
 
 		ret = wl1251_acx_sleep_auth(wl, WL1251_PSM_ELP);
 		if (ret < 0)
 			return ret;
+		break;
+	case STATION_IDLE:
+		wl1251_debug(DEBUG_PSM, "entering idle");
 
-		wl->psm = 1;
+		ret = wl1251_acx_sleep_auth(wl, WL1251_PSM_ELP);
+		if (ret < 0)
+			return ret;
+
+		ret = wl1251_cmd_template_set(wl, CMD_DISCONNECT, NULL, 0);
+		if (ret < 0)
+			return ret;
 		break;
 	case STATION_ACTIVE_MODE:
 	default:
@@ -163,13 +172,13 @@
 		if (ret < 0)
 			return ret;
 
-		ret = wl1251_cmd_ps_mode(wl, STATION_ACTIVE_MODE);
+		ret = wl1251_cmd_ps_mode(wl, CHIP_ACTIVE_MODE);
 		if (ret < 0)
 			return ret;
 
-		wl->psm = 0;
 		break;
 	}
+	wl->station_mode = mode;
 
 	return ret;
 }
diff -druN linux-2.6.39-libre/drivers/net/wireless/wl1251/ps.h linux-3.0-rc7-libre/drivers/net/wireless/wl1251/ps.h
--- linux-2.6.39-libre/drivers/net/wireless/wl1251/ps.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/wl1251/ps.h	2011-07-11 19:51:52.000000000 -0400
@@ -26,7 +26,7 @@
 #include "wl1251.h"
 #include "acx.h"
 
-int wl1251_ps_set_mode(struct wl1251 *wl, enum wl1251_cmd_ps_mode mode);
+int wl1251_ps_set_mode(struct wl1251 *wl, enum wl1251_station_mode mode);
 void wl1251_ps_elp_sleep(struct wl1251 *wl);
 int wl1251_ps_elp_wakeup(struct wl1251 *wl);
 void wl1251_elp_work(struct work_struct *work);
diff -druN linux-2.6.39-libre/drivers/net/wireless/wl1251/wl1251.h linux-3.0-rc7-libre/drivers/net/wireless/wl1251/wl1251.h
--- linux-2.6.39-libre/drivers/net/wireless/wl1251/wl1251.h	2011-05-19 02:16:15.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/wl1251/wl1251.h	2011-07-21 06:58:21.000000000 -0400
@@ -129,6 +129,12 @@
 	PART_TABLE_LEN
 };
 
+enum wl1251_station_mode {
+	STATION_ACTIVE_MODE,
+	STATION_POWER_SAVE_MODE,
+	STATION_IDLE,
+};
+
 struct wl1251_partition {
 	u32 size;
 	u32 start;
@@ -358,8 +364,7 @@
 
 	struct delayed_work elp_work;
 
-	/* we can be in psm, but not in elp, we have to differentiate */
-	bool psm;
+	enum wl1251_station_mode station_mode;
 
 	/* PSM mode requested */
 	bool psm_requested;
diff -druN linux-2.6.39-libre/drivers/net/wireless/wl12xx/acx.c linux-3.0-rc7-libre/drivers/net/wireless/wl12xx/acx.c
--- linux-2.6.39-libre/drivers/net/wireless/wl12xx/acx.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/wl12xx/acx.c	2011-07-11 19:51:52.000000000 -0400
@@ -325,12 +325,19 @@
 	return ret;
 }
 
-int wl1271_acx_rts_threshold(struct wl1271 *wl, u16 rts_threshold)
+int wl1271_acx_rts_threshold(struct wl1271 *wl, u32 rts_threshold)
 {
 	struct acx_rts_threshold *rts;
 	int ret;
 
-	wl1271_debug(DEBUG_ACX, "acx rts threshold");
+	/*
+	 * If the RTS threshold is not configured or out of range, use the
+	 * default value.
+	 */
+	if (rts_threshold > IEEE80211_MAX_RTS_THRESHOLD)
+		rts_threshold = wl->conf.rx.rts_threshold;
+
+	wl1271_debug(DEBUG_ACX, "acx rts threshold: %d", rts_threshold);
 
 	rts = kzalloc(sizeof(*rts), GFP_KERNEL);
 	if (!rts) {
@@ -338,7 +345,7 @@
 		goto out;
 	}
 
-	rts->threshold = cpu_to_le16(rts_threshold);
+	rts->threshold = cpu_to_le16((u16)rts_threshold);
 
 	ret = wl1271_cmd_configure(wl, DOT11_RTS_THRESHOLD, rts, sizeof(*rts));
 	if (ret < 0) {
@@ -540,13 +547,13 @@
 	return ret;
 }
 
-int wl1271_acx_sg_cfg(struct wl1271 *wl)
+int wl1271_acx_sta_sg_cfg(struct wl1271 *wl)
 {
-	struct acx_bt_wlan_coex_param *param;
+	struct acx_sta_bt_wlan_coex_param *param;
 	struct conf_sg_settings *c = &wl->conf.sg;
 	int i, ret;
 
-	wl1271_debug(DEBUG_ACX, "acx sg cfg");
+	wl1271_debug(DEBUG_ACX, "acx sg sta cfg");
 
 	param = kzalloc(sizeof(*param), GFP_KERNEL);
 	if (!param) {
@@ -555,8 +562,38 @@
 	}
 
 	/* BT-WLAN coext parameters */
-	for (i = 0; i < CONF_SG_PARAMS_MAX; i++)
-		param->params[i] = cpu_to_le32(c->params[i]);
+	for (i = 0; i < CONF_SG_STA_PARAMS_MAX; i++)
+		param->params[i] = cpu_to_le32(c->sta_params[i]);
+	param->param_idx = CONF_SG_PARAMS_ALL;
+
+	ret = wl1271_cmd_configure(wl, ACX_SG_CFG, param, sizeof(*param));
+	if (ret < 0) {
+		wl1271_warning("failed to set sg config: %d", ret);
+		goto out;
+	}
+
+out:
+	kfree(param);
+	return ret;
+}
+
+int wl1271_acx_ap_sg_cfg(struct wl1271 *wl)
+{
+	struct acx_ap_bt_wlan_coex_param *param;
+	struct conf_sg_settings *c = &wl->conf.sg;
+	int i, ret;
+
+	wl1271_debug(DEBUG_ACX, "acx sg ap cfg");
+
+	param = kzalloc(sizeof(*param), GFP_KERNEL);
+	if (!param) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	/* BT-WLAN coext parameters */
+	for (i = 0; i < CONF_SG_AP_PARAMS_MAX; i++)
+		param->params[i] = cpu_to_le32(c->ap_params[i]);
 	param->param_idx = CONF_SG_PARAMS_ALL;
 
 	ret = wl1271_cmd_configure(wl, ACX_SG_CFG, param, sizeof(*param));
@@ -804,7 +841,8 @@
 	struct acx_ap_rate_policy *acx;
 	int ret = 0;
 
-	wl1271_debug(DEBUG_ACX, "acx ap rate policy");
+	wl1271_debug(DEBUG_ACX, "acx ap rate policy %d rates 0x%x",
+		     idx, c->enabled_rates);
 
 	acx = kzalloc(sizeof(*acx), GFP_KERNEL);
 	if (!acx) {
@@ -898,12 +936,19 @@
 	return ret;
 }
 
-int wl1271_acx_frag_threshold(struct wl1271 *wl, u16 frag_threshold)
+int wl1271_acx_frag_threshold(struct wl1271 *wl, u32 frag_threshold)
 {
 	struct acx_frag_threshold *acx;
 	int ret = 0;
 
-	wl1271_debug(DEBUG_ACX, "acx frag threshold");
+	/*
+	 * If the fragmentation is not configured or out of range, use the
+	 * default value.
+	 */
+	if (frag_threshold > IEEE80211_MAX_FRAG_THRESHOLD)
+		frag_threshold = wl->conf.tx.frag_threshold;
+
+	wl1271_debug(DEBUG_ACX, "acx frag threshold: %d", frag_threshold);
 
 	acx = kzalloc(sizeof(*acx), GFP_KERNEL);
 
@@ -912,7 +957,7 @@
 		goto out;
 	}
 
-	acx->frag_threshold = cpu_to_le16(frag_threshold);
+	acx->frag_threshold = cpu_to_le16((u16)frag_threshold);
 	ret = wl1271_cmd_configure(wl, ACX_FRAG_CFG, acx, sizeof(*acx));
 	if (ret < 0) {
 		wl1271_warning("Setting of frag threshold failed: %d", ret);
@@ -954,6 +999,7 @@
 int wl1271_acx_ap_mem_cfg(struct wl1271 *wl)
 {
 	struct wl1271_acx_ap_config_memory *mem_conf;
+	struct conf_memory_settings *mem;
 	int ret;
 
 	wl1271_debug(DEBUG_ACX, "wl1271 mem cfg");
@@ -964,11 +1010,21 @@
 		goto out;
 	}
 
+	if (wl->chip.id == CHIP_ID_1283_PG20)
+		/*
+		 * FIXME: The 128x AP FW does not yet support dynamic memory.
+		 * Use the base memory configuration for 128x for now. This
+		 * should be fine tuned in the future.
+		 */
+		mem = &wl->conf.mem_wl128x;
+	else
+		mem = &wl->conf.mem_wl127x;
+
 	/* memory config */
-	mem_conf->num_stations = wl->conf.mem.num_stations;
-	mem_conf->rx_mem_block_num = wl->conf.mem.rx_block_num;
-	mem_conf->tx_min_mem_block_num = wl->conf.mem.tx_min_block_num;
-	mem_conf->num_ssid_profiles = wl->conf.mem.ssid_profiles;
+	mem_conf->num_stations = mem->num_stations;
+	mem_conf->rx_mem_block_num = mem->rx_block_num;
+	mem_conf->tx_min_mem_block_num = mem->tx_min_block_num;
+	mem_conf->num_ssid_profiles = mem->ssid_profiles;
 	mem_conf->total_tx_descriptors = cpu_to_le32(ACX_TX_DESCRIPTORS);
 
 	ret = wl1271_cmd_configure(wl, ACX_MEM_CFG, mem_conf,
@@ -986,6 +1042,7 @@
 int wl1271_acx_sta_mem_cfg(struct wl1271 *wl)
 {
 	struct wl1271_acx_sta_config_memory *mem_conf;
+	struct conf_memory_settings *mem;
 	int ret;
 
 	wl1271_debug(DEBUG_ACX, "wl1271 mem cfg");
@@ -996,16 +1053,21 @@
 		goto out;
 	}
 
+	if (wl->chip.id == CHIP_ID_1283_PG20)
+		mem = &wl->conf.mem_wl128x;
+	else
+		mem = &wl->conf.mem_wl127x;
+
 	/* memory config */
-	mem_conf->num_stations = wl->conf.mem.num_stations;
-	mem_conf->rx_mem_block_num = wl->conf.mem.rx_block_num;
-	mem_conf->tx_min_mem_block_num = wl->conf.mem.tx_min_block_num;
-	mem_conf->num_ssid_profiles = wl->conf.mem.ssid_profiles;
+	mem_conf->num_stations = mem->num_stations;
+	mem_conf->rx_mem_block_num = mem->rx_block_num;
+	mem_conf->tx_min_mem_block_num = mem->tx_min_block_num;
+	mem_conf->num_ssid_profiles = mem->ssid_profiles;
 	mem_conf->total_tx_descriptors = cpu_to_le32(ACX_TX_DESCRIPTORS);
-	mem_conf->dyn_mem_enable = wl->conf.mem.dynamic_memory;
-	mem_conf->tx_free_req = wl->conf.mem.min_req_tx_blocks;
-	mem_conf->rx_free_req = wl->conf.mem.min_req_rx_blocks;
-	mem_conf->tx_min = wl->conf.mem.tx_min;
+	mem_conf->dyn_mem_enable = mem->dynamic_memory;
+	mem_conf->tx_free_req = mem->min_req_tx_blocks;
+	mem_conf->rx_free_req = mem->min_req_rx_blocks;
+	mem_conf->tx_min = mem->tx_min;
 
 	ret = wl1271_cmd_configure(wl, ACX_MEM_CFG, mem_conf,
 				   sizeof(*mem_conf));
@@ -1019,6 +1081,32 @@
 	return ret;
 }
 
+int wl1271_acx_host_if_cfg_bitmap(struct wl1271 *wl, u32 host_cfg_bitmap)
+{
+	struct wl1271_acx_host_config_bitmap *bitmap_conf;
+	int ret;
+
+	bitmap_conf = kzalloc(sizeof(*bitmap_conf), GFP_KERNEL);
+	if (!bitmap_conf) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	bitmap_conf->host_cfg_bitmap = cpu_to_le32(host_cfg_bitmap);
+
+	ret = wl1271_cmd_configure(wl, ACX_HOST_IF_CFG_BITMAP,
+				   bitmap_conf, sizeof(*bitmap_conf));
+	if (ret < 0) {
+		wl1271_warning("wl1271 bitmap config opt failed: %d", ret);
+		goto out;
+	}
+
+out:
+	kfree(bitmap_conf);
+
+	return ret;
+}
+
 int wl1271_acx_init_mem_config(struct wl1271 *wl)
 {
 	int ret;
@@ -1567,3 +1655,68 @@
 	kfree(acx);
 	return ret;
 }
+
+int wl1271_acx_set_ap_beacon_filter(struct wl1271 *wl, bool enable)
+{
+	struct acx_ap_beacon_filter *acx = NULL;
+	int ret;
+
+	wl1271_debug(DEBUG_ACX, "acx set ap beacon filter: %d", enable);
+
+	acx = kzalloc(sizeof(*acx), GFP_KERNEL);
+	if (!acx)
+		return -ENOMEM;
+
+	acx->enable = enable ? 1 : 0;
+
+	ret = wl1271_cmd_configure(wl, ACX_AP_BEACON_FILTER_OPT,
+				   acx, sizeof(*acx));
+	if (ret < 0) {
+		wl1271_warning("acx set ap beacon filter failed: %d", ret);
+		goto out;
+	}
+
+out:
+	kfree(acx);
+	return ret;
+}
+
+int wl1271_acx_fm_coex(struct wl1271 *wl)
+{
+	struct wl1271_acx_fm_coex *acx;
+	int ret;
+
+	wl1271_debug(DEBUG_ACX, "acx fm coex setting");
+
+	acx = kzalloc(sizeof(*acx), GFP_KERNEL);
+	if (!acx) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	acx->enable = wl->conf.fm_coex.enable;
+	acx->swallow_period = wl->conf.fm_coex.swallow_period;
+	acx->n_divider_fref_set_1 = wl->conf.fm_coex.n_divider_fref_set_1;
+	acx->n_divider_fref_set_2 = wl->conf.fm_coex.n_divider_fref_set_2;
+	acx->m_divider_fref_set_1 =
+		cpu_to_le16(wl->conf.fm_coex.m_divider_fref_set_1);
+	acx->m_divider_fref_set_2 =
+		cpu_to_le16(wl->conf.fm_coex.m_divider_fref_set_2);
+	acx->coex_pll_stabilization_time =
+		cpu_to_le32(wl->conf.fm_coex.coex_pll_stabilization_time);
+	acx->ldo_stabilization_time =
+		cpu_to_le16(wl->conf.fm_coex.ldo_stabilization_time);
+	acx->fm_disturbed_band_margin =
+		wl->conf.fm_coex.fm_disturbed_band_margin;
+	acx->swallow_clk_diff = wl->conf.fm_coex.swallow_clk_diff;
+
+	ret = wl1271_cmd_configure(wl, ACX_FM_COEX_CFG, acx, sizeof(*acx));
+	if (ret < 0) {
+		wl1271_warning("acx fm coex setting failed: %d", ret);
+		goto out;
+	}
+
+out:
+	kfree(acx);
+	return ret;
+}
diff -druN linux-2.6.39-libre/drivers/net/wireless/wl12xx/acx.h linux-3.0-rc7-libre/drivers/net/wireless/wl12xx/acx.h
--- linux-2.6.39-libre/drivers/net/wireless/wl12xx/acx.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/wl12xx/acx.h	2011-07-11 19:51:52.000000000 -0400
@@ -303,7 +303,6 @@
 	struct acx_header header;
 
 	u8 enable;
-
 	/*
 	 * The number of beacons without the unicast TIM
 	 * bit set that the firmware buffers before
@@ -370,14 +369,23 @@
 	u8 pad[3];
 } __packed;
 
-struct acx_bt_wlan_coex_param {
+struct acx_sta_bt_wlan_coex_param {
 	struct acx_header header;
 
-	__le32 params[CONF_SG_PARAMS_MAX];
+	__le32 params[CONF_SG_STA_PARAMS_MAX];
+	u8 param_idx;
+	u8 padding[3];
+} __packed;
+
+struct acx_ap_bt_wlan_coex_param {
+	struct acx_header header;
+
+	__le32 params[CONF_SG_AP_PARAMS_MAX];
 	u8 param_idx;
 	u8 padding[3];
 } __packed;
 
+
 struct acx_dco_itrim_params {
 	struct acx_header header;
 
@@ -939,6 +947,16 @@
 	u8 padding;
 } __packed;
 
+#define HOST_IF_CFG_RX_FIFO_ENABLE     BIT(0)
+#define HOST_IF_CFG_TX_EXTRA_BLKS_SWAP BIT(1)
+#define HOST_IF_CFG_TX_PAD_TO_SDIO_BLK BIT(3)
+
+struct wl1271_acx_host_config_bitmap {
+	struct acx_header header;
+
+	__le32 host_cfg_bitmap;
+} __packed;
+
 enum {
 	WL1271_ACX_TRIG_TYPE_LEVEL = 0,
 	WL1271_ACX_TRIG_TYPE_EDGE,
@@ -1162,6 +1180,72 @@
 	u8 padding1[2];
 } __packed;
 
+struct acx_ap_beacon_filter {
+	struct acx_header header;
+
+	u8 enable;
+	u8 pad[3];
+} __packed;
+
+/*
+ * ACX_FM_COEX_CFG
+ * set the FM co-existence parameters.
+ */
+struct wl1271_acx_fm_coex {
+	struct acx_header header;
+	/* enable(1) / disable(0) the FM Coex feature */
+	u8 enable;
+	/*
+	 * Swallow period used in COEX PLL swallowing mechanism.
+	 * 0xFF = use FW default
+	 */
+	u8 swallow_period;
+	/*
+	 * The N divider used in COEX PLL swallowing mechanism for Fref of
+	 * 38.4/19.2 Mhz. 0xFF = use FW default
+	 */
+	u8 n_divider_fref_set_1;
+	/*
+	 * The N divider used in COEX PLL swallowing mechanism for Fref of
+	 * 26/52 Mhz. 0xFF = use FW default
+	 */
+	u8 n_divider_fref_set_2;
+	/*
+	 * The M divider used in COEX PLL swallowing mechanism for Fref of
+	 * 38.4/19.2 Mhz. 0xFFFF = use FW default
+	 */
+	__le16 m_divider_fref_set_1;
+	/*
+	 * The M divider used in COEX PLL swallowing mechanism for Fref of
+	 * 26/52 Mhz. 0xFFFF = use FW default
+	 */
+	__le16 m_divider_fref_set_2;
+	/*
+	 * The time duration in uSec required for COEX PLL to stabilize.
+	 * 0xFFFFFFFF = use FW default
+	 */
+	__le32 coex_pll_stabilization_time;
+	/*
+	 * The time duration in uSec required for LDO to stabilize.
+	 * 0xFFFFFFFF = use FW default
+	 */
+	__le16 ldo_stabilization_time;
+	/*
+	 * The disturbed frequency band margin around the disturbed frequency
+	 * center (single sided).
+	 * For example, if 2 is configured, the following channels will be
+	 * considered disturbed channel:
+	 *   80 +- 0.1 MHz, 91 +- 0.1 MHz, 98 +- 0.1 MHz, 102 +- 0.1 MH
+	 * 0xFF = use FW default
+	 */
+	u8 fm_disturbed_band_margin;
+	/*
+	 * The swallow clock difference of the swallowing mechanism.
+	 * 0xFF = use FW default
+	 */
+	u8 swallow_clk_diff;
+} __packed;
+
 enum {
 	ACX_WAKE_UP_CONDITIONS      = 0x0002,
 	ACX_MEM_CFG                 = 0x0003,
@@ -1180,6 +1264,7 @@
 	ACX_TID_CFG                 = 0x001A,
 	ACX_PS_RX_STREAMING         = 0x001B,
 	ACX_BEACON_FILTER_OPT       = 0x001F,
+	ACX_AP_BEACON_FILTER_OPT    = 0x0020,
 	ACX_NOISE_HIST              = 0x0021,
 	ACX_HDK_VERSION             = 0x0022, /* ??? */
 	ACX_PD_THRESHOLD            = 0x0023,
@@ -1191,6 +1276,7 @@
 	ACX_BCN_DTIM_OPTIONS        = 0x0031,
 	ACX_SG_ENABLE               = 0x0032,
 	ACX_SG_CFG                  = 0x0033,
+	ACX_FM_COEX_CFG             = 0x0034,
 	ACX_BEACON_FILTER_TABLE     = 0x0038,
 	ACX_ARP_IP_FILTER           = 0x0039,
 	ACX_ROAMING_STATISTICS_TBL  = 0x003B,
@@ -1247,13 +1333,14 @@
 int wl1271_acx_group_address_tbl(struct wl1271 *wl, bool enable,
 				 void *mc_list, u32 mc_list_len);
 int wl1271_acx_service_period_timeout(struct wl1271 *wl);
-int wl1271_acx_rts_threshold(struct wl1271 *wl, u16 rts_threshold);
+int wl1271_acx_rts_threshold(struct wl1271 *wl, u32 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, bool enable);
 int wl1271_acx_sg_enable(struct wl1271 *wl, bool enable);
-int wl1271_acx_sg_cfg(struct wl1271 *wl);
+int wl1271_acx_sta_sg_cfg(struct wl1271 *wl);
+int wl1271_acx_ap_sg_cfg(struct wl1271 *wl);
 int wl1271_acx_cca_threshold(struct wl1271 *wl);
 int wl1271_acx_bcn_dtim_options(struct wl1271 *wl);
 int wl1271_acx_aid(struct wl1271 *wl, u16 aid);
@@ -1270,11 +1357,12 @@
 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, u16 frag_threshold);
+int wl1271_acx_frag_threshold(struct wl1271 *wl, u32 frag_threshold);
 int wl1271_acx_tx_config_options(struct wl1271 *wl);
 int wl1271_acx_ap_mem_cfg(struct wl1271 *wl);
 int wl1271_acx_sta_mem_cfg(struct wl1271 *wl);
 int wl1271_acx_init_mem_config(struct wl1271 *wl);
+int wl1271_acx_host_if_cfg_bitmap(struct wl1271 *wl, u32 host_cfg_bitmap);
 int wl1271_acx_init_rx_interrupt(struct wl1271 *wl);
 int wl1271_acx_smart_reflex(struct wl1271 *wl);
 int wl1271_acx_bet_enable(struct wl1271 *wl, bool enable);
@@ -1299,5 +1387,7 @@
 int wl1271_acx_max_tx_retry(struct wl1271 *wl);
 int wl1271_acx_config_ps(struct wl1271 *wl);
 int wl1271_acx_set_inconnection_sta(struct wl1271 *wl, u8 *addr);
+int wl1271_acx_set_ap_beacon_filter(struct wl1271 *wl, bool enable);
+int wl1271_acx_fm_coex(struct wl1271 *wl);
 
 #endif /* __WL1271_ACX_H__ */
diff -druN linux-2.6.39-libre/drivers/net/wireless/wl12xx/boot.c linux-3.0-rc7-libre/drivers/net/wireless/wl12xx/boot.c
--- linux-2.6.39-libre/drivers/net/wireless/wl12xx/boot.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/wl12xx/boot.c	2011-07-11 19:51:52.000000000 -0400
@@ -22,6 +22,7 @@
  */
 
 #include <linux/slab.h>
+#include <linux/wl12xx.h>
 
 #include "acx.h"
 #include "reg.h"
@@ -243,33 +244,57 @@
 	if (wl->nvs == NULL)
 		return -ENODEV;
 
-	/*
-	 * FIXME: the LEGACY NVS image support (NVS's missing the 5GHz band
-	 * configurations) can be removed when those NVS files stop floating
-	 * around.
-	 */
-	if (wl->nvs_len == sizeof(struct wl1271_nvs_file) ||
-	    wl->nvs_len == WL1271_INI_LEGACY_NVS_FILE_SIZE) {
-		/* for now 11a is unsupported in AP mode */
-		if (wl->bss_type != BSS_TYPE_AP_BSS &&
-		    wl->nvs->general_params.dual_mode_select)
-			wl->enable_11a = true;
-	}
+	if (wl->chip.id == CHIP_ID_1283_PG20) {
+		struct wl128x_nvs_file *nvs = (struct wl128x_nvs_file *)wl->nvs;
 
-	if (wl->nvs_len != sizeof(struct wl1271_nvs_file) &&
-	    (wl->nvs_len != WL1271_INI_LEGACY_NVS_FILE_SIZE ||
-	     wl->enable_11a)) {
-		wl1271_error("nvs size is not as expected: %zu != %zu",
-			     wl->nvs_len, sizeof(struct wl1271_nvs_file));
-		kfree(wl->nvs);
-		wl->nvs = NULL;
-		wl->nvs_len = 0;
-		return -EILSEQ;
-	}
+		if (wl->nvs_len == sizeof(struct wl128x_nvs_file)) {
+			if (nvs->general_params.dual_mode_select)
+				wl->enable_11a = true;
+		} else {
+			wl1271_error("nvs size is not as expected: %zu != %zu",
+				     wl->nvs_len,
+				     sizeof(struct wl128x_nvs_file));
+			kfree(wl->nvs);
+			wl->nvs = NULL;
+			wl->nvs_len = 0;
+			return -EILSEQ;
+		}
 
-	/* only the first part of the NVS needs to be uploaded */
-	nvs_len = sizeof(wl->nvs->nvs);
-	nvs_ptr = (u8 *)wl->nvs->nvs;
+		/* only the first part of the NVS needs to be uploaded */
+		nvs_len = sizeof(nvs->nvs);
+		nvs_ptr = (u8 *)nvs->nvs;
+
+	} else {
+		struct wl1271_nvs_file *nvs =
+			(struct wl1271_nvs_file *)wl->nvs;
+		/*
+		 * FIXME: the LEGACY NVS image support (NVS's missing the 5GHz
+		 * band configurations) can be removed when those NVS files stop
+		 * floating around.
+		 */
+		if (wl->nvs_len == sizeof(struct wl1271_nvs_file) ||
+		    wl->nvs_len == WL1271_INI_LEGACY_NVS_FILE_SIZE) {
+			/* for now 11a is unsupported in AP mode */
+			if (wl->bss_type != BSS_TYPE_AP_BSS &&
+			    nvs->general_params.dual_mode_select)
+				wl->enable_11a = true;
+		}
+
+		if (wl->nvs_len != sizeof(struct wl1271_nvs_file) &&
+		    (wl->nvs_len != WL1271_INI_LEGACY_NVS_FILE_SIZE ||
+		     wl->enable_11a)) {
+			wl1271_error("nvs size is not as expected: %zu != %zu",
+				wl->nvs_len, sizeof(struct wl1271_nvs_file));
+			kfree(wl->nvs);
+			wl->nvs = NULL;
+			wl->nvs_len = 0;
+			return -EILSEQ;
+		}
+
+		/* only the first part of the NVS needs to be uploaded */
+		nvs_len = sizeof(nvs->nvs);
+		nvs_ptr = (u8 *) nvs->nvs;
+	}
 
 	/* update current MAC address to NVS */
 	nvs_ptr[11] = wl->mac_addr[0];
@@ -319,10 +344,13 @@
 	/*
 	 * We've reached the first zero length, the first NVS table
 	 * is located at an aligned offset which is at least 7 bytes further.
+	 * NOTE: The wl->nvs->nvs element must be first, in order to
+	 * simplify the casting, we assume it is at the beginning of
+	 * the wl->nvs structure.
 	 */
-	nvs_ptr = (u8 *)wl->nvs->nvs +
-			ALIGN(nvs_ptr - (u8 *)wl->nvs->nvs + 7, 4);
-	nvs_len -= nvs_ptr - (u8 *)wl->nvs->nvs;
+	nvs_ptr = (u8 *)wl->nvs +
+			ALIGN(nvs_ptr - (u8 *)wl->nvs + 7, 4);
+	nvs_len -= nvs_ptr - (u8 *)wl->nvs;
 
 	/* Now we must set the partition correctly */
 	wl1271_set_partition(wl, &part_table[PART_WORK]);
@@ -450,10 +478,14 @@
 		DISCONNECT_EVENT_COMPLETE_ID |
 		RSSI_SNR_TRIGGER_0_EVENT_ID |
 		PSPOLL_DELIVERY_FAILURE_EVENT_ID |
-		SOFT_GEMINI_SENSE_EVENT_ID;
+		SOFT_GEMINI_SENSE_EVENT_ID |
+		PERIODIC_SCAN_REPORT_EVENT_ID |
+		PERIODIC_SCAN_COMPLETE_EVENT_ID;
 
 	if (wl->bss_type == BSS_TYPE_AP_BSS)
 		wl->event_mask |= STA_REMOVE_COMPLETE_EVENT_ID;
+	else
+		wl->event_mask |= DUMMY_PACKET_EVENT_ID;
 
 	ret = wl1271_event_unmask(wl);
 	if (ret < 0) {
@@ -493,24 +525,159 @@
 		wl->quirks |= WL12XX_QUIRK_END_OF_TRANSACTION;
 }
 
-/* uploads NVS and firmware */
-int wl1271_load_firmware(struct wl1271 *wl)
+static int wl128x_switch_tcxo_to_fref(struct wl1271 *wl)
 {
-	int ret = 0;
-	u32 tmp, clk, pause;
+	u16 spare_reg;
+
+	/* Mask bits [2] & [8:4] in the sys_clk_cfg register */
+	spare_reg = wl1271_top_reg_read(wl, WL_SPARE_REG);
+	if (spare_reg == 0xFFFF)
+		return -EFAULT;
+	spare_reg |= (BIT(3) | BIT(5) | BIT(6));
+	wl1271_top_reg_write(wl, WL_SPARE_REG, spare_reg);
+
+	/* Enable FREF_CLK_REQ & mux MCS and coex PLLs to FREF */
+	wl1271_top_reg_write(wl, SYS_CLK_CFG_REG,
+			     WL_CLK_REQ_TYPE_PG2 | MCS_PLL_CLK_SEL_FREF);
+
+	/* Delay execution for 15msec, to let the HW settle */
+	mdelay(15);
+
+	return 0;
+}
+
+static bool wl128x_is_tcxo_valid(struct wl1271 *wl)
+{
+	u16 tcxo_detection;
+
+	tcxo_detection = wl1271_top_reg_read(wl, TCXO_CLK_DETECT_REG);
+	if (tcxo_detection & TCXO_DET_FAILED)
+		return false;
+
+	return true;
+}
+
+static bool wl128x_is_fref_valid(struct wl1271 *wl)
+{
+	u16 fref_detection;
+
+	fref_detection = wl1271_top_reg_read(wl, FREF_CLK_DETECT_REG);
+	if (fref_detection & FREF_CLK_DETECT_FAIL)
+		return false;
+
+	return true;
+}
+
+static int wl128x_manually_configure_mcs_pll(struct wl1271 *wl)
+{
+	wl1271_top_reg_write(wl, MCS_PLL_M_REG, MCS_PLL_M_REG_VAL);
+	wl1271_top_reg_write(wl, MCS_PLL_N_REG, MCS_PLL_N_REG_VAL);
+	wl1271_top_reg_write(wl, MCS_PLL_CONFIG_REG, MCS_PLL_CONFIG_REG_VAL);
+
+	return 0;
+}
+
+static int wl128x_configure_mcs_pll(struct wl1271 *wl, int clk)
+{
+	u16 spare_reg;
+	u16 pll_config;
+	u8 input_freq;
+
+	/* Mask bits [3:1] in the sys_clk_cfg register */
+	spare_reg = wl1271_top_reg_read(wl, WL_SPARE_REG);
+	if (spare_reg == 0xFFFF)
+		return -EFAULT;
+	spare_reg |= BIT(2);
+	wl1271_top_reg_write(wl, WL_SPARE_REG, spare_reg);
+
+	/* Handle special cases of the TCXO clock */
+	if (wl->tcxo_clock == WL12XX_TCXOCLOCK_16_8 ||
+	    wl->tcxo_clock == WL12XX_TCXOCLOCK_33_6)
+		return wl128x_manually_configure_mcs_pll(wl);
+
+	/* Set the input frequency according to the selected clock source */
+	input_freq = (clk & 1) + 1;
+
+	pll_config = wl1271_top_reg_read(wl, MCS_PLL_CONFIG_REG);
+	if (pll_config == 0xFFFF)
+		return -EFAULT;
+	pll_config |= (input_freq << MCS_SEL_IN_FREQ_SHIFT);
+	pll_config |= MCS_PLL_ENABLE_HP;
+	wl1271_top_reg_write(wl, MCS_PLL_CONFIG_REG, pll_config);
+
+	return 0;
+}
+
+/*
+ * WL128x has two clocks input - TCXO and FREF.
+ * TCXO is the main clock of the device, while FREF is used to sync
+ * between the GPS and the cellular modem.
+ * In cases where TCXO is 32.736MHz or 16.368MHz, the FREF will be used
+ * as the WLAN/BT main clock.
+ */
+static int wl128x_boot_clk(struct wl1271 *wl, int *selected_clock)
+{
+	u16 sys_clk_cfg;
+
+	/* For XTAL-only modes, FREF will be used after switching from TCXO */
+	if (wl->ref_clock == WL12XX_REFCLOCK_26_XTAL ||
+	    wl->ref_clock == WL12XX_REFCLOCK_38_XTAL) {
+		if (!wl128x_switch_tcxo_to_fref(wl))
+			return -EINVAL;
+		goto fref_clk;
+	}
+
+	/* Query the HW, to determine which clock source we should use */
+	sys_clk_cfg = wl1271_top_reg_read(wl, SYS_CLK_CFG_REG);
+	if (sys_clk_cfg == 0xFFFF)
+		return -EINVAL;
+	if (sys_clk_cfg & PRCM_CM_EN_MUX_WLAN_FREF)
+		goto fref_clk;
+
+	/* If TCXO is either 32.736MHz or 16.368MHz, switch to FREF */
+	if (wl->tcxo_clock == WL12XX_TCXOCLOCK_16_368 ||
+	    wl->tcxo_clock == WL12XX_TCXOCLOCK_32_736) {
+		if (!wl128x_switch_tcxo_to_fref(wl))
+			return -EINVAL;
+		goto fref_clk;
+	}
+
+	/* TCXO clock is selected */
+	if (!wl128x_is_tcxo_valid(wl))
+		return -EINVAL;
+	*selected_clock = wl->tcxo_clock;
+	goto config_mcs_pll;
+
+fref_clk:
+	/* FREF clock is selected */
+	if (!wl128x_is_fref_valid(wl))
+		return -EINVAL;
+	*selected_clock = wl->ref_clock;
+
+config_mcs_pll:
+	return wl128x_configure_mcs_pll(wl, *selected_clock);
+}
+
+static int wl127x_boot_clk(struct wl1271 *wl)
+{
+	u32 pause;
+	u32 clk;
 
 	wl1271_boot_hw_version(wl);
 
-	if (wl->ref_clock == 0 || wl->ref_clock == 2 || wl->ref_clock == 4)
+	if (wl->ref_clock == CONF_REF_CLK_19_2_E ||
+	    wl->ref_clock == CONF_REF_CLK_38_4_E ||
+	    wl->ref_clock == CONF_REF_CLK_38_4_M_XTAL)
 		/* ref clk: 19.2/38.4/38.4-XTAL */
 		clk = 0x3;
-	else if (wl->ref_clock == 1 || wl->ref_clock == 3)
+	else if (wl->ref_clock == CONF_REF_CLK_26_E ||
+		 wl->ref_clock == CONF_REF_CLK_52_E)
 		/* ref clk: 26/52 */
 		clk = 0x5;
 	else
 		return -EINVAL;
 
-	if (wl->ref_clock != 0) {
+	if (wl->ref_clock != CONF_REF_CLK_19_2_E) {
 		u16 val;
 		/* Set clock type (open drain) */
 		val = wl1271_top_reg_read(wl, OCP_REG_CLK_TYPE);
@@ -540,6 +707,26 @@
 	pause |= WU_COUNTER_PAUSE_VAL;
 	wl1271_write32(wl, WU_COUNTER_PAUSE, pause);
 
+	return 0;
+}
+
+/* uploads NVS and firmware */
+int wl1271_load_firmware(struct wl1271 *wl)
+{
+	int ret = 0;
+	u32 tmp, clk;
+	int selected_clock = -1;
+
+	if (wl->chip.id == CHIP_ID_1283_PG20) {
+		ret = wl128x_boot_clk(wl, &selected_clock);
+		if (ret < 0)
+			goto out;
+	} else {
+		ret = wl127x_boot_clk(wl);
+		if (ret < 0)
+			goto out;
+	}
+
 	/* Continue the ELP wake up sequence */
 	wl1271_write32(wl, WELP_ARM_COMMAND, WELP_ARM_COMMAND_VAL);
 	udelay(500);
@@ -555,7 +742,12 @@
 
 	wl1271_debug(DEBUG_BOOT, "clk2 0x%x", clk);
 
-	clk |= (wl->ref_clock << 1) << 4;
+	if (wl->chip.id == CHIP_ID_1283_PG20) {
+		clk |= ((selected_clock & 0x3) << 1) << 4;
+	} else {
+		clk |= (wl->ref_clock << 1) << 4;
+	}
+
 	wl1271_write32(wl, DRPW_SCRATCH_START, clk);
 
 	wl1271_set_partition(wl, &part_table[PART_WORK]);
@@ -585,16 +777,12 @@
 	/* 6. read the EEPROM parameters */
 	tmp = wl1271_read32(wl, SCR_PAD2);
 
-	ret = wl1271_boot_write_irq_polarity(wl);
-	if (ret < 0)
-		goto out;
-
-	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) */
 
+	if (wl->chip.id == CHIP_ID_1283_PG20)
+		wl1271_top_reg_write(wl, SDIO_IO_DS, wl->conf.hci_io_ds);
+
 	ret = wl1271_boot_upload_firmware(wl);
 	if (ret < 0)
 		goto out;
@@ -618,6 +806,13 @@
 	if (ret < 0)
 		goto out;
 
+	ret = wl1271_boot_write_irq_polarity(wl);
+	if (ret < 0)
+		goto out;
+
+	wl1271_write32(wl, ACX_REG_INTERRUPT_MASK,
+		       WL1271_ACX_ALL_EVENTS_VECTOR);
+
 	/* Enable firmware interrupts now */
 	wl1271_boot_enable_interrupts(wl);
 
diff -druN linux-2.6.39-libre/drivers/net/wireless/wl12xx/boot.h linux-3.0-rc7-libre/drivers/net/wireless/wl12xx/boot.h
--- linux-2.6.39-libre/drivers/net/wireless/wl12xx/boot.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/wl12xx/boot.h	2011-07-11 19:51:52.000000000 -0400
@@ -74,4 +74,56 @@
 #define FREF_CLK_POLARITY_BITS 0xfffff8ff
 #define CLK_REQ_OUTN_SEL       0x700
 
+/* PLL configuration algorithm for wl128x */
+#define SYS_CLK_CFG_REG              0x2200
+/* Bit[0]   -  0-TCXO,  1-FREF */
+#define MCS_PLL_CLK_SEL_FREF         BIT(0)
+/* Bit[3:2] - 01-TCXO, 10-FREF */
+#define WL_CLK_REQ_TYPE_FREF         BIT(3)
+#define WL_CLK_REQ_TYPE_PG2          (BIT(3) | BIT(2))
+/* Bit[4]   -  0-TCXO,  1-FREF */
+#define PRCM_CM_EN_MUX_WLAN_FREF     BIT(4)
+
+#define TCXO_ILOAD_INT_REG           0x2264
+#define TCXO_CLK_DETECT_REG          0x2266
+
+#define TCXO_DET_FAILED              BIT(4)
+
+#define FREF_ILOAD_INT_REG           0x2084
+#define FREF_CLK_DETECT_REG          0x2086
+#define FREF_CLK_DETECT_FAIL         BIT(4)
+
+/* Use this reg for masking during driver access */
+#define WL_SPARE_REG                 0x2320
+#define WL_SPARE_VAL                 BIT(2)
+/* Bit[6:5:3] -  mask wl write SYS_CLK_CFG[8:5:2:4] */
+#define WL_SPARE_MASK_8526           (BIT(6) | BIT(5) | BIT(3))
+
+#define PLL_LOCK_COUNTERS_REG        0xD8C
+#define PLL_LOCK_COUNTERS_COEX       0x0F
+#define PLL_LOCK_COUNTERS_MCS        0xF0
+#define MCS_PLL_OVERRIDE_REG         0xD90
+#define MCS_PLL_CONFIG_REG           0xD92
+#define MCS_SEL_IN_FREQ_MASK         0x0070
+#define MCS_SEL_IN_FREQ_SHIFT        4
+#define MCS_PLL_CONFIG_REG_VAL       0x73
+#define MCS_PLL_ENABLE_HP            (BIT(0) | BIT(1))
+
+#define MCS_PLL_M_REG                0xD94
+#define MCS_PLL_N_REG                0xD96
+#define MCS_PLL_M_REG_VAL            0xC8
+#define MCS_PLL_N_REG_VAL            0x07
+
+#define SDIO_IO_DS                   0xd14
+
+/* SDIO/wSPI DS configuration values */
+enum {
+	HCI_IO_DS_8MA = 0,
+	HCI_IO_DS_4MA = 1, /* default */
+	HCI_IO_DS_6MA = 2,
+	HCI_IO_DS_2MA = 3,
+};
+
+/* end PLL configuration algorithm for wl128x */
+
 #endif
diff -druN linux-2.6.39-libre/drivers/net/wireless/wl12xx/cmd.c linux-3.0-rc7-libre/drivers/net/wireless/wl12xx/cmd.c
--- linux-2.6.39-libre/drivers/net/wireless/wl12xx/cmd.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/wl12xx/cmd.c	2011-07-11 19:51:52.000000000 -0400
@@ -76,7 +76,7 @@
 		if (time_after(jiffies, timeout)) {
 			wl1271_error("command complete timeout");
 			ret = -ETIMEDOUT;
-			goto out;
+			goto fail;
 		}
 
 		poll_count++;
@@ -96,21 +96,25 @@
 	status = le16_to_cpu(cmd->status);
 	if (status != CMD_STATUS_SUCCESS) {
 		wl1271_error("command execute failure %d", status);
-		ieee80211_queue_work(wl->hw, &wl->recovery_work);
 		ret = -EIO;
+		goto fail;
 	}
 
 	wl1271_write32(wl, ACX_REG_INTERRUPT_ACK,
 		       WL1271_ACX_INTR_CMD_COMPLETE);
+	return 0;
 
-out:
+fail:
+	WARN_ON(1);
+	ieee80211_queue_work(wl->hw, &wl->recovery_work);
 	return ret;
 }
 
 int wl1271_cmd_general_parms(struct wl1271 *wl)
 {
 	struct wl1271_general_parms_cmd *gen_parms;
-	struct wl1271_ini_general_params *gp = &wl->nvs->general_params;
+	struct wl1271_ini_general_params *gp =
+		&((struct wl1271_nvs_file *)wl->nvs)->general_params;
 	bool answer = false;
 	int ret;
 
@@ -128,6 +132,52 @@
 	if (gp->tx_bip_fem_auto_detect)
 		answer = true;
 
+	/* Override the REF CLK from the NVS with the one from platform data */
+	gen_parms->general_params.ref_clock = wl->ref_clock;
+
+	ret = wl1271_cmd_test(wl, gen_parms, sizeof(*gen_parms), answer);
+	if (ret < 0) {
+		wl1271_warning("CMD_INI_FILE_GENERAL_PARAM failed");
+		goto out;
+	}
+
+	gp->tx_bip_fem_manufacturer =
+		gen_parms->general_params.tx_bip_fem_manufacturer;
+
+	wl1271_debug(DEBUG_CMD, "FEM autodetect: %s, manufacturer: %d\n",
+		     answer ? "auto" : "manual", gp->tx_bip_fem_manufacturer);
+
+out:
+	kfree(gen_parms);
+	return ret;
+}
+
+int wl128x_cmd_general_parms(struct wl1271 *wl)
+{
+	struct wl128x_general_parms_cmd *gen_parms;
+	struct wl128x_ini_general_params *gp =
+		&((struct wl128x_nvs_file *)wl->nvs)->general_params;
+	bool answer = false;
+	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;
+
+	memcpy(&gen_parms->general_params, gp, sizeof(*gp));
+
+	if (gp->tx_bip_fem_auto_detect)
+		answer = true;
+
+	/* Replace REF and TCXO CLKs with the ones from platform data */
+	gen_parms->general_params.ref_clock = wl->ref_clock;
+	gen_parms->general_params.tcxo_ref_clock = wl->tcxo_clock;
+
 	ret = wl1271_cmd_test(wl, gen_parms, sizeof(*gen_parms), answer);
 	if (ret < 0) {
 		wl1271_warning("CMD_INI_FILE_GENERAL_PARAM failed");
@@ -147,8 +197,9 @@
 
 int wl1271_cmd_radio_parms(struct wl1271 *wl)
 {
+	struct wl1271_nvs_file *nvs = (struct wl1271_nvs_file *)wl->nvs;
 	struct wl1271_radio_parms_cmd *radio_parms;
-	struct wl1271_ini_general_params *gp = &wl->nvs->general_params;
+	struct wl1271_ini_general_params *gp = &nvs->general_params;
 	int ret;
 
 	if (!wl->nvs)
@@ -161,18 +212,18 @@
 	radio_parms->test.id = TEST_CMD_INI_FILE_RADIO_PARAM;
 
 	/* 2.4GHz parameters */
-	memcpy(&radio_parms->static_params_2, &wl->nvs->stat_radio_params_2,
+	memcpy(&radio_parms->static_params_2, &nvs->stat_radio_params_2,
 	       sizeof(struct wl1271_ini_band_params_2));
 	memcpy(&radio_parms->dyn_params_2,
-	       &wl->nvs->dyn_radio_params_2[gp->tx_bip_fem_manufacturer].params,
+	       &nvs->dyn_radio_params_2[gp->tx_bip_fem_manufacturer].params,
 	       sizeof(struct wl1271_ini_fem_params_2));
 
 	/* 5GHz parameters */
 	memcpy(&radio_parms->static_params_5,
-	       &wl->nvs->stat_radio_params_5,
+	       &nvs->stat_radio_params_5,
 	       sizeof(struct wl1271_ini_band_params_5));
 	memcpy(&radio_parms->dyn_params_5,
-	       &wl->nvs->dyn_radio_params_5[gp->tx_bip_fem_manufacturer].params,
+	       &nvs->dyn_radio_params_5[gp->tx_bip_fem_manufacturer].params,
 	       sizeof(struct wl1271_ini_fem_params_5));
 
 	wl1271_dump(DEBUG_CMD, "TEST_CMD_INI_FILE_RADIO_PARAM: ",
@@ -186,6 +237,50 @@
 	return ret;
 }
 
+int wl128x_cmd_radio_parms(struct wl1271 *wl)
+{
+	struct wl128x_nvs_file *nvs = (struct wl128x_nvs_file *)wl->nvs;
+	struct wl128x_radio_parms_cmd *radio_parms;
+	struct wl128x_ini_general_params *gp = &nvs->general_params;
+	int ret;
+
+	if (!wl->nvs)
+		return -ENODEV;
+
+	radio_parms = kzalloc(sizeof(*radio_parms), GFP_KERNEL);
+	if (!radio_parms)
+		return -ENOMEM;
+
+	radio_parms->test.id = TEST_CMD_INI_FILE_RADIO_PARAM;
+
+	/* 2.4GHz parameters */
+	memcpy(&radio_parms->static_params_2, &nvs->stat_radio_params_2,
+	       sizeof(struct wl128x_ini_band_params_2));
+	memcpy(&radio_parms->dyn_params_2,
+	       &nvs->dyn_radio_params_2[gp->tx_bip_fem_manufacturer].params,
+	       sizeof(struct wl128x_ini_fem_params_2));
+
+	/* 5GHz parameters */
+	memcpy(&radio_parms->static_params_5,
+	       &nvs->stat_radio_params_5,
+	       sizeof(struct wl128x_ini_band_params_5));
+	memcpy(&radio_parms->dyn_params_5,
+	       &nvs->dyn_radio_params_5[gp->tx_bip_fem_manufacturer].params,
+	       sizeof(struct wl128x_ini_fem_params_5));
+
+	radio_parms->fem_vendor_and_options = nvs->fem_vendor_and_options;
+
+	wl1271_dump(DEBUG_CMD, "TEST_CMD_INI_FILE_RADIO_PARAM: ",
+		    radio_parms, sizeof(*radio_parms));
+
+	ret = wl1271_cmd_test(wl, radio_parms, sizeof(*radio_parms), 0);
+	if (ret < 0)
+		wl1271_warning("CMD_INI_FILE_RADIO_PARAM failed");
+
+	kfree(radio_parms);
+	return ret;
+}
+
 int wl1271_cmd_ext_radio_parms(struct wl1271 *wl)
 {
 	struct wl1271_ext_radio_parms_cmd *ext_radio_parms;
diff -druN linux-2.6.39-libre/drivers/net/wireless/wl12xx/cmd.h linux-3.0-rc7-libre/drivers/net/wireless/wl12xx/cmd.h
--- linux-2.6.39-libre/drivers/net/wireless/wl12xx/cmd.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/wl12xx/cmd.h	2011-07-11 19:51:52.000000000 -0400
@@ -32,7 +32,9 @@
 int wl1271_cmd_send(struct wl1271 *wl, u16 id, void *buf, size_t len,
 		    size_t res_len);
 int wl1271_cmd_general_parms(struct wl1271 *wl);
+int wl128x_cmd_general_parms(struct wl1271 *wl);
 int wl1271_cmd_radio_parms(struct wl1271 *wl);
+int wl128x_cmd_radio_parms(struct wl1271 *wl);
 int wl1271_cmd_ext_radio_parms(struct wl1271 *wl);
 int wl1271_cmd_join(struct wl1271 *wl, u8 bss_type);
 int wl1271_cmd_test(struct wl1271 *wl, void *buf, size_t buf_len, u8 answer);
@@ -415,6 +417,21 @@
 	u8 padding[3];
 } __packed;
 
+struct wl128x_general_parms_cmd {
+	struct wl1271_cmd_header header;
+
+	struct wl1271_cmd_test_header test;
+
+	struct wl128x_ini_general_params general_params;
+
+	u8 sr_debug_table[WL1271_INI_MAX_SMART_REFLEX_PARAM];
+	u8 sr_sen_n_p;
+	u8 sr_sen_n_p_gain;
+	u8 sr_sen_nrn;
+	u8 sr_sen_prn;
+	u8 padding[3];
+} __packed;
+
 struct wl1271_radio_parms_cmd {
 	struct wl1271_cmd_header header;
 
@@ -431,6 +448,23 @@
 	u8 padding3[2];
 } __packed;
 
+struct wl128x_radio_parms_cmd {
+	struct wl1271_cmd_header header;
+
+	struct wl1271_cmd_test_header test;
+
+	/* Static radio parameters */
+	struct wl128x_ini_band_params_2 static_params_2;
+	struct wl128x_ini_band_params_5 static_params_5;
+
+	u8 fem_vendor_and_options;
+
+	/* Dynamic radio parameters */
+	struct wl128x_ini_fem_params_2 dyn_params_2;
+	u8 padding2;
+	struct wl128x_ini_fem_params_5 dyn_params_5;
+} __packed;
+
 struct wl1271_ext_radio_parms_cmd {
 	struct wl1271_cmd_header header;
 
diff -druN linux-2.6.39-libre/drivers/net/wireless/wl12xx/conf.h linux-3.0-rc7-libre/drivers/net/wireless/wl12xx/conf.h
--- linux-2.6.39-libre/drivers/net/wireless/wl12xx/conf.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/wl12xx/conf.h	2011-07-11 19:51:52.000000000 -0400
@@ -396,12 +396,43 @@
 	CONF_SG_TEMP_PARAM_3,
 	CONF_SG_TEMP_PARAM_4,
 	CONF_SG_TEMP_PARAM_5,
-	CONF_SG_PARAMS_MAX,
+
+	/*
+	 * AP beacon miss
+	 *
+	 * Range: 0 - 255
+	 */
+	CONF_SG_AP_BEACON_MISS_TX,
+
+	/*
+	 * AP RX window length
+	 *
+	 * Range: 0 - 50
+	 */
+	CONF_SG_RX_WINDOW_LENGTH,
+
+	/*
+	 * AP connection protection time
+	 *
+	 * Range: 0 - 5000
+	 */
+	CONF_SG_AP_CONNECTION_PROTECTION_TIME,
+
+	CONF_SG_TEMP_PARAM_6,
+	CONF_SG_TEMP_PARAM_7,
+	CONF_SG_TEMP_PARAM_8,
+	CONF_SG_TEMP_PARAM_9,
+	CONF_SG_TEMP_PARAM_10,
+
+	CONF_SG_STA_PARAMS_MAX = CONF_SG_TEMP_PARAM_5 + 1,
+	CONF_SG_AP_PARAMS_MAX = CONF_SG_TEMP_PARAM_10 + 1,
+
 	CONF_SG_PARAMS_ALL = 0xff
 };
 
 struct conf_sg_settings {
-	u32 params[CONF_SG_PARAMS_MAX];
+	u32 sta_params[CONF_SG_STA_PARAMS_MAX];
+	u32 ap_params[CONF_SG_AP_PARAMS_MAX];
 	u8 state;
 };
 
@@ -509,6 +540,12 @@
 	CONF_HW_BIT_RATE_36MBPS | CONF_HW_BIT_RATE_48MBPS |      \
 	CONF_HW_BIT_RATE_54MBPS)
 
+#define CONF_TX_OFDM_RATES (CONF_HW_BIT_RATE_6MBPS |             \
+	CONF_HW_BIT_RATE_12MBPS | CONF_HW_BIT_RATE_24MBPS |      \
+	CONF_HW_BIT_RATE_36MBPS | CONF_HW_BIT_RATE_48MBPS |      \
+	CONF_HW_BIT_RATE_54MBPS)
+
+
 /*
  * Default rates for management traffic when operating in AP mode. This
  * should be configured according to the basic rate set of the AP
@@ -516,6 +553,13 @@
 #define CONF_TX_AP_DEFAULT_MGMT_RATES  (CONF_HW_BIT_RATE_1MBPS | \
 	CONF_HW_BIT_RATE_2MBPS | CONF_HW_BIT_RATE_5_5MBPS)
 
+/*
+ * Default rates for working as IBSS. use 11b rates
+ */
+#define CONF_TX_IBSS_DEFAULT_RATES  (CONF_HW_BIT_RATE_1MBPS |       \
+		CONF_HW_BIT_RATE_2MBPS | CONF_HW_BIT_RATE_5_5MBPS | \
+		CONF_HW_BIT_RATE_11MBPS);
+
 struct conf_tx_rate_class {
 
 	/*
@@ -667,22 +711,6 @@
 	struct conf_tx_ac_category ac_conf[CONF_TX_MAX_AC_COUNT];
 
 	/*
-	 * Configuration for rate classes in AP-mode. These rate classes
-	 * are for the AC TX queues
-	 */
-	struct conf_tx_rate_class ap_rc_conf[CONF_TX_MAX_AC_COUNT];
-
-	/*
-	 * Management TX rate class for AP-mode.
-	 */
-	struct conf_tx_rate_class ap_mgmt_conf;
-
-	/*
-	 * Broadcast TX rate class for AP-mode.
-	 */
-	struct conf_tx_rate_class ap_bcst_conf;
-
-	/*
 	 * AP-mode - allow this number of TX retries to a station before an
 	 * event is triggered from FW.
 	 */
@@ -1004,7 +1032,9 @@
 	CONF_REF_CLK_19_2_E,
 	CONF_REF_CLK_26_E,
 	CONF_REF_CLK_38_4_E,
-	CONF_REF_CLK_52_E
+	CONF_REF_CLK_52_E,
+	CONF_REF_CLK_38_4_M_XTAL,
+	CONF_REF_CLK_26_M_XTAL,
 };
 
 enum single_dual_band_enum {
@@ -1018,15 +1048,6 @@
 #define CONF_NUMBER_OF_CHANNELS_2_4 14
 #define CONF_NUMBER_OF_CHANNELS_5   35
 
-struct conf_radio_parms {
-	/*
-	 * FEM parameter set to use
-	 *
-	 * Range: 0 or 1
-	 */
-	u8 fem;
-};
-
 struct conf_itrim_settings {
 	/* enable dco itrim */
 	u8 enable;
@@ -1126,6 +1147,29 @@
 
 };
 
+struct conf_sched_scan_settings {
+	/* minimum time to wait on the channel for active scans (in TUs) */
+	u16 min_dwell_time_active;
+
+	/* maximum time to wait on the channel for active scans (in TUs) */
+	u16 max_dwell_time_active;
+
+	/* time to wait on the channel for passive scans (in TUs) */
+	u32 dwell_time_passive;
+
+	/* time to wait on the channel for DFS scans (in TUs) */
+	u32 dwell_time_dfs;
+
+	/* number of probe requests to send on each channel in active scans */
+	u8 num_probe_reqs;
+
+	/* RSSI threshold to be used for filtering */
+	s8 rssi_threshold;
+
+	/* SNR threshold to be used for filtering */
+	s8 snr_threshold;
+};
+
 /* these are number of channels on the band divided by two, rounded up */
 #define CONF_TX_PWR_COMPENSATION_LEN_2 7
 #define CONF_TX_PWR_COMPENSATION_LEN_5 18
@@ -1191,6 +1235,19 @@
 	u8 tx_min;
 };
 
+struct conf_fm_coex {
+	u8 enable;
+	u8 swallow_period;
+	u8 n_divider_fref_set_1;
+	u8 n_divider_fref_set_2;
+	u16 m_divider_fref_set_1;
+	u16 m_divider_fref_set_2;
+	u32 coex_pll_stabilization_time;
+	u16 ldo_stabilization_time;
+	u8 fm_disturbed_band_margin;
+	u8 swallow_clk_diff;
+};
+
 struct conf_drv_settings {
 	struct conf_sg_settings sg;
 	struct conf_rx_settings rx;
@@ -1200,9 +1257,13 @@
 	struct conf_pm_config_settings pm_config;
 	struct conf_roam_trigger_settings roam_trigger;
 	struct conf_scan_settings scan;
+	struct conf_sched_scan_settings sched_scan;
 	struct conf_rf_settings rf;
 	struct conf_ht_setting ht;
-	struct conf_memory_settings mem;
+	struct conf_memory_settings mem_wl127x;
+	struct conf_memory_settings mem_wl128x;
+	struct conf_fm_coex fm_coex;
+	u8 hci_io_ds;
 };
 
 #endif
diff -druN linux-2.6.39-libre/drivers/net/wireless/wl12xx/debugfs.c linux-3.0-rc7-libre/drivers/net/wireless/wl12xx/debugfs.c
--- linux-2.6.39-libre/drivers/net/wireless/wl12xx/debugfs.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/wl12xx/debugfs.c	2011-07-11 19:51:52.000000000 -0400
@@ -267,7 +267,7 @@
 	}
 	buf[len] = '\0';
 
-	ret = strict_strtoul(buf, 0, &value);
+	ret = kstrtoul(buf, 0, &value);
 	if (ret < 0) {
 		wl1271_warning("illegal value in gpio_power");
 		return -EINVAL;
@@ -291,6 +291,242 @@
 	.llseek = default_llseek,
 };
 
+static ssize_t start_recovery_write(struct file *file,
+				    const char __user *user_buf,
+				    size_t count, loff_t *ppos)
+{
+	struct wl1271 *wl = file->private_data;
+
+	mutex_lock(&wl->mutex);
+	ieee80211_queue_work(wl->hw, &wl->recovery_work);
+	mutex_unlock(&wl->mutex);
+
+	return count;
+}
+
+static const struct file_operations start_recovery_ops = {
+	.write = start_recovery_write,
+	.open = wl1271_open_file_generic,
+	.llseek = default_llseek,
+};
+
+static ssize_t driver_state_read(struct file *file, char __user *user_buf,
+				 size_t count, loff_t *ppos)
+{
+	struct wl1271 *wl = file->private_data;
+	int res = 0;
+	char buf[1024];
+
+	mutex_lock(&wl->mutex);
+
+#define DRIVER_STATE_PRINT(x, fmt)   \
+	(res += scnprintf(buf + res, sizeof(buf) - res,\
+			  #x " = " fmt "\n", wl->x))
+
+#define DRIVER_STATE_PRINT_LONG(x) DRIVER_STATE_PRINT(x, "%ld")
+#define DRIVER_STATE_PRINT_INT(x)  DRIVER_STATE_PRINT(x, "%d")
+#define DRIVER_STATE_PRINT_STR(x)  DRIVER_STATE_PRINT(x, "%s")
+#define DRIVER_STATE_PRINT_LHEX(x) DRIVER_STATE_PRINT(x, "0x%lx")
+#define DRIVER_STATE_PRINT_HEX(x)  DRIVER_STATE_PRINT(x, "0x%x")
+
+	DRIVER_STATE_PRINT_INT(tx_blocks_available);
+	DRIVER_STATE_PRINT_INT(tx_allocated_blocks);
+	DRIVER_STATE_PRINT_INT(tx_frames_cnt);
+	DRIVER_STATE_PRINT_LHEX(tx_frames_map[0]);
+	DRIVER_STATE_PRINT_INT(tx_queue_count);
+	DRIVER_STATE_PRINT_INT(tx_packets_count);
+	DRIVER_STATE_PRINT_INT(tx_results_count);
+	DRIVER_STATE_PRINT_LHEX(flags);
+	DRIVER_STATE_PRINT_INT(tx_blocks_freed[0]);
+	DRIVER_STATE_PRINT_INT(tx_blocks_freed[1]);
+	DRIVER_STATE_PRINT_INT(tx_blocks_freed[2]);
+	DRIVER_STATE_PRINT_INT(tx_blocks_freed[3]);
+	DRIVER_STATE_PRINT_INT(tx_security_last_seq);
+	DRIVER_STATE_PRINT_INT(rx_counter);
+	DRIVER_STATE_PRINT_INT(session_counter);
+	DRIVER_STATE_PRINT_INT(state);
+	DRIVER_STATE_PRINT_INT(bss_type);
+	DRIVER_STATE_PRINT_INT(channel);
+	DRIVER_STATE_PRINT_HEX(rate_set);
+	DRIVER_STATE_PRINT_HEX(basic_rate_set);
+	DRIVER_STATE_PRINT_HEX(basic_rate);
+	DRIVER_STATE_PRINT_INT(band);
+	DRIVER_STATE_PRINT_INT(beacon_int);
+	DRIVER_STATE_PRINT_INT(psm_entry_retry);
+	DRIVER_STATE_PRINT_INT(ps_poll_failures);
+	DRIVER_STATE_PRINT_HEX(filters);
+	DRIVER_STATE_PRINT_HEX(rx_config);
+	DRIVER_STATE_PRINT_HEX(rx_filter);
+	DRIVER_STATE_PRINT_INT(power_level);
+	DRIVER_STATE_PRINT_INT(rssi_thold);
+	DRIVER_STATE_PRINT_INT(last_rssi_event);
+	DRIVER_STATE_PRINT_INT(sg_enabled);
+	DRIVER_STATE_PRINT_INT(enable_11a);
+	DRIVER_STATE_PRINT_INT(noise);
+	DRIVER_STATE_PRINT_LHEX(ap_hlid_map[0]);
+	DRIVER_STATE_PRINT_INT(last_tx_hlid);
+	DRIVER_STATE_PRINT_INT(ba_support);
+	DRIVER_STATE_PRINT_HEX(ba_rx_bitmap);
+	DRIVER_STATE_PRINT_HEX(ap_fw_ps_map);
+	DRIVER_STATE_PRINT_LHEX(ap_ps_map);
+	DRIVER_STATE_PRINT_HEX(quirks);
+	DRIVER_STATE_PRINT_HEX(irq);
+	DRIVER_STATE_PRINT_HEX(ref_clock);
+	DRIVER_STATE_PRINT_HEX(tcxo_clock);
+	DRIVER_STATE_PRINT_HEX(hw_pg_ver);
+	DRIVER_STATE_PRINT_HEX(platform_quirks);
+	DRIVER_STATE_PRINT_HEX(chip.id);
+	DRIVER_STATE_PRINT_STR(chip.fw_ver_str);
+	DRIVER_STATE_PRINT_INT(sched_scanning);
+
+#undef DRIVER_STATE_PRINT_INT
+#undef DRIVER_STATE_PRINT_LONG
+#undef DRIVER_STATE_PRINT_HEX
+#undef DRIVER_STATE_PRINT_LHEX
+#undef DRIVER_STATE_PRINT_STR
+#undef DRIVER_STATE_PRINT
+
+	mutex_unlock(&wl->mutex);
+
+	return simple_read_from_buffer(user_buf, count, ppos, buf, res);
+}
+
+static const struct file_operations driver_state_ops = {
+	.read = driver_state_read,
+	.open = wl1271_open_file_generic,
+	.llseek = default_llseek,
+};
+
+static ssize_t dtim_interval_read(struct file *file, char __user *user_buf,
+				  size_t count, loff_t *ppos)
+{
+	struct wl1271 *wl = file->private_data;
+	u8 value;
+
+	if (wl->conf.conn.wake_up_event == CONF_WAKE_UP_EVENT_DTIM ||
+	    wl->conf.conn.wake_up_event == CONF_WAKE_UP_EVENT_N_DTIM)
+		value = wl->conf.conn.listen_interval;
+	else
+		value = 0;
+
+	return wl1271_format_buffer(user_buf, count, ppos, "%d\n", value);
+}
+
+static ssize_t dtim_interval_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;
+
+	len = min(count, sizeof(buf) - 1);
+	if (copy_from_user(buf, user_buf, len))
+		return -EFAULT;
+	buf[len] = '\0';
+
+	ret = kstrtoul(buf, 0, &value);
+	if (ret < 0) {
+		wl1271_warning("illegal value for dtim_interval");
+		return -EINVAL;
+	}
+
+	if (value < 1 || value > 10) {
+		wl1271_warning("dtim value is not in valid range");
+		return -ERANGE;
+	}
+
+	mutex_lock(&wl->mutex);
+
+	wl->conf.conn.listen_interval = value;
+	/* for some reason there are different event types for 1 and >1 */
+	if (value == 1)
+		wl->conf.conn.wake_up_event = CONF_WAKE_UP_EVENT_DTIM;
+	else
+		wl->conf.conn.wake_up_event = CONF_WAKE_UP_EVENT_N_DTIM;
+
+	/*
+	 * we don't reconfigure ACX_WAKE_UP_CONDITIONS now, so it will only
+	 * take effect on the next time we enter psm.
+	 */
+	mutex_unlock(&wl->mutex);
+	return count;
+}
+
+static const struct file_operations dtim_interval_ops = {
+	.read = dtim_interval_read,
+	.write = dtim_interval_write,
+	.open = wl1271_open_file_generic,
+	.llseek = default_llseek,
+};
+
+static ssize_t beacon_interval_read(struct file *file, char __user *user_buf,
+				    size_t count, loff_t *ppos)
+{
+	struct wl1271 *wl = file->private_data;
+	u8 value;
+
+	if (wl->conf.conn.wake_up_event == CONF_WAKE_UP_EVENT_BEACON ||
+	    wl->conf.conn.wake_up_event == CONF_WAKE_UP_EVENT_N_BEACONS)
+		value = wl->conf.conn.listen_interval;
+	else
+		value = 0;
+
+	return wl1271_format_buffer(user_buf, count, ppos, "%d\n", value);
+}
+
+static ssize_t beacon_interval_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;
+
+	len = min(count, sizeof(buf) - 1);
+	if (copy_from_user(buf, user_buf, len))
+		return -EFAULT;
+	buf[len] = '\0';
+
+	ret = kstrtoul(buf, 0, &value);
+	if (ret < 0) {
+		wl1271_warning("illegal value for beacon_interval");
+		return -EINVAL;
+	}
+
+	if (value < 1 || value > 255) {
+		wl1271_warning("beacon interval value is not in valid range");
+		return -ERANGE;
+	}
+
+	mutex_lock(&wl->mutex);
+
+	wl->conf.conn.listen_interval = value;
+	/* for some reason there are different event types for 1 and >1 */
+	if (value == 1)
+		wl->conf.conn.wake_up_event = CONF_WAKE_UP_EVENT_BEACON;
+	else
+		wl->conf.conn.wake_up_event = CONF_WAKE_UP_EVENT_N_BEACONS;
+
+	/*
+	 * we don't reconfigure ACX_WAKE_UP_CONDITIONS now, so it will only
+	 * take effect on the next time we enter psm.
+	 */
+	mutex_unlock(&wl->mutex);
+	return count;
+}
+
+static const struct file_operations beacon_interval_ops = {
+	.read = beacon_interval_read,
+	.write = beacon_interval_write,
+	.open = wl1271_open_file_generic,
+	.llseek = default_llseek,
+};
+
 static int wl1271_debugfs_add_files(struct wl1271 *wl,
 				     struct dentry *rootdir)
 {
@@ -399,6 +635,10 @@
 	DEBUGFS_ADD(excessive_retries, rootdir);
 
 	DEBUGFS_ADD(gpio_power, rootdir);
+	DEBUGFS_ADD(start_recovery, rootdir);
+	DEBUGFS_ADD(driver_state, rootdir);
+	DEBUGFS_ADD(dtim_interval, rootdir);
+	DEBUGFS_ADD(beacon_interval, rootdir);
 
 	return 0;
 
diff -druN linux-2.6.39-libre/drivers/net/wireless/wl12xx/event.c linux-3.0-rc7-libre/drivers/net/wireless/wl12xx/event.c
--- linux-2.6.39-libre/drivers/net/wireless/wl12xx/event.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/wl12xx/event.c	2011-07-11 19:51:52.000000000 -0400
@@ -33,6 +33,7 @@
 {
 	struct delayed_work *dwork;
 	struct wl1271 *wl;
+	int ret;
 
 	dwork = container_of(work, struct delayed_work, work);
 	wl = container_of(dwork, struct wl1271, pspoll_work);
@@ -55,8 +56,13 @@
 	 * delivery failure occurred, and no-one changed state since, so
 	 * we should go back to powersave.
 	 */
+	ret = wl1271_ps_elp_wakeup(wl);
+	if (ret < 0)
+		goto out;
+
 	wl1271_ps_set_mode(wl, STATION_POWER_SAVE_MODE, wl->basic_rate, true);
 
+	wl1271_ps_elp_sleep(wl);
 out:
 	mutex_unlock(&wl->mutex);
 };
@@ -132,8 +138,10 @@
 		if (ret < 0)
 			break;
 
-		/* go to extremely low power mode */
-		wl1271_ps_elp_sleep(wl);
+		if (wl->ps_compl) {
+			complete(wl->ps_compl);
+			wl->ps_compl = NULL;
+		}
 		break;
 	default:
 		break;
@@ -187,6 +195,22 @@
 		wl1271_scan_stm(wl);
 	}
 
+	if (vector & PERIODIC_SCAN_REPORT_EVENT_ID) {
+		wl1271_debug(DEBUG_EVENT, "PERIODIC_SCAN_REPORT_EVENT "
+			     "(status 0x%0x)", mbox->scheduled_scan_status);
+
+		wl1271_scan_sched_scan_results(wl);
+	}
+
+	if (vector & PERIODIC_SCAN_COMPLETE_EVENT_ID) {
+		wl1271_debug(DEBUG_EVENT, "PERIODIC_SCAN_COMPLETE_EVENT "
+			     "(status 0x%0x)", mbox->scheduled_scan_status);
+		if (wl->sched_scanning) {
+			wl1271_scan_sched_scan_stop(wl);
+			ieee80211_sched_scan_stopped(wl->hw);
+		}
+	}
+
 	/* disable dynamic PS when requested by the firmware */
 	if (vector & SOFT_GEMINI_SENSE_EVENT_ID &&
 	    wl->bss_type == BSS_TYPE_STA_BSS) {
@@ -228,6 +252,12 @@
 			wl1271_event_rssi_trigger(wl, mbox);
 	}
 
+	if ((vector & DUMMY_PACKET_EVENT_ID) && !is_ap) {
+		wl1271_debug(DEBUG_EVENT, "DUMMY_PACKET_ID_EVENT_ID");
+		if (wl->vif)
+			wl1271_tx_dummy_packet(wl);
+	}
+
 	if (wl->vif && beacon_loss)
 		ieee80211_connection_loss(wl->vif);
 
diff -druN linux-2.6.39-libre/drivers/net/wireless/wl12xx/event.h linux-3.0-rc7-libre/drivers/net/wireless/wl12xx/event.h
--- linux-2.6.39-libre/drivers/net/wireless/wl12xx/event.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/wl12xx/event.h	2011-07-11 19:51:52.000000000 -0400
@@ -59,7 +59,10 @@
 	BSS_LOSE_EVENT_ID			 = BIT(18),
 	REGAINED_BSS_EVENT_ID			 = BIT(19),
 	ROAMING_TRIGGER_MAX_TX_RETRY_EVENT_ID	 = BIT(20),
-	STA_REMOVE_COMPLETE_EVENT_ID		 = BIT(21), /* AP */
+	/* STA: dummy paket for dynamic mem blocks */
+	DUMMY_PACKET_EVENT_ID                    = BIT(21),
+	/* AP: STA remove complete */
+	STA_REMOVE_COMPLETE_EVENT_ID             = BIT(21),
 	SOFT_GEMINI_SENSE_EVENT_ID		 = BIT(22),
 	SOFT_GEMINI_PREDICTION_EVENT_ID		 = BIT(23),
 	SOFT_GEMINI_AVALANCHE_EVENT_ID		 = BIT(24),
diff -druN linux-2.6.39-libre/drivers/net/wireless/wl12xx/ini.h linux-3.0-rc7-libre/drivers/net/wireless/wl12xx/ini.h
--- linux-2.6.39-libre/drivers/net/wireless/wl12xx/ini.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/wl12xx/ini.h	2011-07-11 19:51:52.000000000 -0400
@@ -41,6 +41,28 @@
 	u8 srf3[WL1271_INI_MAX_SMART_REFLEX_PARAM];
 } __packed;
 
+#define WL128X_INI_MAX_SETTINGS_PARAM 4
+
+struct wl128x_ini_general_params {
+	u8 ref_clock;
+	u8 settling_time;
+	u8 clk_valid_on_wakeup;
+	u8 tcxo_ref_clock;
+	u8 tcxo_settling_time;
+	u8 tcxo_valid_on_wakeup;
+	u8 tcxo_ldo_voltage;
+	u8 xtal_itrim_val;
+	u8 platform_conf;
+	u8 dual_mode_select;
+	u8 tx_bip_fem_auto_detect;
+	u8 tx_bip_fem_manufacturer;
+	u8 general_settings[WL128X_INI_MAX_SETTINGS_PARAM];
+	u8 sr_state;
+	u8 srf1[WL1271_INI_MAX_SMART_REFLEX_PARAM];
+	u8 srf2[WL1271_INI_MAX_SMART_REFLEX_PARAM];
+	u8 srf3[WL1271_INI_MAX_SMART_REFLEX_PARAM];
+} __packed;
+
 #define WL1271_INI_RSSI_PROCESS_COMPENS_SIZE 15
 
 struct wl1271_ini_band_params_2 {
@@ -49,9 +71,16 @@
 	u8 rx_rssi_process_compens[WL1271_INI_RSSI_PROCESS_COMPENS_SIZE];
 } __packed;
 
-#define WL1271_INI_RATE_GROUP_COUNT 6
 #define WL1271_INI_CHANNEL_COUNT_2 14
 
+struct wl128x_ini_band_params_2 {
+	u8 rx_trace_insertion_loss;
+	u8 tx_trace_loss[WL1271_INI_CHANNEL_COUNT_2];
+	u8 rx_rssi_process_compens[WL1271_INI_RSSI_PROCESS_COMPENS_SIZE];
+} __packed;
+
+#define WL1271_INI_RATE_GROUP_COUNT 6
+
 struct wl1271_ini_fem_params_2 {
 	__le16 tx_bip_ref_pd_voltage;
 	u8 tx_bip_ref_power;
@@ -68,6 +97,28 @@
 	u8 normal_to_degraded_high_thr;
 } __packed;
 
+#define WL128X_INI_RATE_GROUP_COUNT 7
+/* low and high temperatures */
+#define WL128X_INI_PD_VS_TEMPERATURE_RANGES 2
+
+struct wl128x_ini_fem_params_2 {
+	__le16 tx_bip_ref_pd_voltage;
+	u8 tx_bip_ref_power;
+	u8 tx_bip_ref_offset;
+	u8 tx_per_rate_pwr_limits_normal[WL128X_INI_RATE_GROUP_COUNT];
+	u8 tx_per_rate_pwr_limits_degraded[WL128X_INI_RATE_GROUP_COUNT];
+	u8 tx_per_rate_pwr_limits_extreme[WL128X_INI_RATE_GROUP_COUNT];
+	u8 tx_per_chan_pwr_limits_11b[WL1271_INI_CHANNEL_COUNT_2];
+	u8 tx_per_chan_pwr_limits_ofdm[WL1271_INI_CHANNEL_COUNT_2];
+	u8 tx_pd_vs_rate_offsets[WL128X_INI_RATE_GROUP_COUNT];
+	u8 tx_ibias[WL128X_INI_RATE_GROUP_COUNT + 1];
+	u8 tx_pd_vs_chan_offsets[WL1271_INI_CHANNEL_COUNT_2];
+	u8 tx_pd_vs_temperature[WL128X_INI_PD_VS_TEMPERATURE_RANGES];
+	u8 rx_fem_insertion_loss;
+	u8 degraded_low_to_normal_thr;
+	u8 normal_to_degraded_high_thr;
+} __packed;
+
 #define WL1271_INI_CHANNEL_COUNT_5 35
 #define WL1271_INI_SUB_BAND_COUNT_5 7
 
@@ -77,6 +128,12 @@
 	u8 rx_rssi_process_compens[WL1271_INI_RSSI_PROCESS_COMPENS_SIZE];
 } __packed;
 
+struct wl128x_ini_band_params_5 {
+	u8 rx_trace_insertion_loss[WL1271_INI_SUB_BAND_COUNT_5];
+	u8 tx_trace_loss[WL1271_INI_CHANNEL_COUNT_5];
+	u8 rx_rssi_process_compens[WL1271_INI_RSSI_PROCESS_COMPENS_SIZE];
+} __packed;
+
 struct wl1271_ini_fem_params_5 {
 	__le16 tx_bip_ref_pd_voltage[WL1271_INI_SUB_BAND_COUNT_5];
 	u8 tx_bip_ref_power[WL1271_INI_SUB_BAND_COUNT_5];
@@ -92,6 +149,23 @@
 	u8 normal_to_degraded_high_thr;
 } __packed;
 
+struct wl128x_ini_fem_params_5 {
+	__le16 tx_bip_ref_pd_voltage[WL1271_INI_SUB_BAND_COUNT_5];
+	u8 tx_bip_ref_power[WL1271_INI_SUB_BAND_COUNT_5];
+	u8 tx_bip_ref_offset[WL1271_INI_SUB_BAND_COUNT_5];
+	u8 tx_per_rate_pwr_limits_normal[WL128X_INI_RATE_GROUP_COUNT];
+	u8 tx_per_rate_pwr_limits_degraded[WL128X_INI_RATE_GROUP_COUNT];
+	u8 tx_per_rate_pwr_limits_extreme[WL128X_INI_RATE_GROUP_COUNT];
+	u8 tx_per_chan_pwr_limits_ofdm[WL1271_INI_CHANNEL_COUNT_5];
+	u8 tx_pd_vs_rate_offsets[WL128X_INI_RATE_GROUP_COUNT];
+	u8 tx_ibias[WL128X_INI_RATE_GROUP_COUNT];
+	u8 tx_pd_vs_chan_offsets[WL1271_INI_CHANNEL_COUNT_5];
+	u8 tx_pd_vs_temperature[WL1271_INI_SUB_BAND_COUNT_5 *
+		WL128X_INI_PD_VS_TEMPERATURE_RANGES];
+	u8 rx_fem_insertion_loss[WL1271_INI_SUB_BAND_COUNT_5];
+	u8 degraded_low_to_normal_thr;
+	u8 normal_to_degraded_high_thr;
+} __packed;
 
 /* NVS data structure */
 #define WL1271_INI_NVS_SECTION_SIZE		     468
@@ -100,7 +174,7 @@
 #define WL1271_INI_LEGACY_NVS_FILE_SIZE              800
 
 struct wl1271_nvs_file {
-	/* NVS section */
+	/* NVS section - must be first! */
 	u8 nvs[WL1271_INI_NVS_SECTION_SIZE];
 
 	/* INI section */
@@ -120,4 +194,24 @@
 	} dyn_radio_params_5[WL1271_INI_FEM_MODULE_COUNT];
 } __packed;
 
+struct wl128x_nvs_file {
+	/* NVS section - must be first! */
+	u8 nvs[WL1271_INI_NVS_SECTION_SIZE];
+
+	/* INI section */
+	struct wl128x_ini_general_params general_params;
+	u8 fem_vendor_and_options;
+	struct wl128x_ini_band_params_2 stat_radio_params_2;
+	u8 padding2;
+	struct {
+		struct wl128x_ini_fem_params_2 params;
+		u8 padding;
+	} dyn_radio_params_2[WL1271_INI_FEM_MODULE_COUNT];
+	struct wl128x_ini_band_params_5 stat_radio_params_5;
+	u8 padding3;
+	struct {
+		struct wl128x_ini_fem_params_5 params;
+		u8 padding;
+	} dyn_radio_params_5[WL1271_INI_FEM_MODULE_COUNT];
+} __packed;
 #endif
diff -druN linux-2.6.39-libre/drivers/net/wireless/wl12xx/init.c linux-3.0-rc7-libre/drivers/net/wireless/wl12xx/init.c
--- linux-2.6.39-libre/drivers/net/wireless/wl12xx/init.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/wl12xx/init.c	2011-07-11 19:51:52.000000000 -0400
@@ -31,6 +31,7 @@
 #include "cmd.h"
 #include "reg.h"
 #include "tx.h"
+#include "io.h"
 
 int wl1271_sta_init_templates_config(struct wl1271 *wl)
 {
@@ -257,7 +258,7 @@
 	if (ret < 0)
 		return ret;
 
-	ret = wl1271_acx_rts_threshold(wl, wl->conf.rx.rts_threshold);
+	ret = wl1271_acx_rts_threshold(wl, wl->hw->wiphy->rts_threshold);
 	if (ret < 0)
 		return ret;
 
@@ -284,7 +285,10 @@
 {
 	int ret;
 
-	ret = wl1271_acx_sg_cfg(wl);
+	if (wl->bss_type == BSS_TYPE_AP_BSS)
+		ret = wl1271_acx_ap_sg_cfg(wl);
+	else
+		ret = wl1271_acx_sta_sg_cfg(wl);
 	if (ret < 0)
 		return ret;
 
@@ -321,9 +325,11 @@
 {
 	int ret;
 
-	ret = wl1271_cmd_ext_radio_parms(wl);
-	if (ret < 0)
-		return ret;
+	if (wl->chip.id != CHIP_ID_1283_PG20) {
+		ret = wl1271_cmd_ext_radio_parms(wl);
+		if (ret < 0)
+			return ret;
+	}
 
 	/* PS config */
 	ret = wl1271_acx_config_ps(wl);
@@ -348,8 +354,8 @@
 	if (ret < 0)
 		return ret;
 
-	/* Bluetooth WLAN coexistence */
-	ret = wl1271_init_pta(wl);
+	/* FM WLAN coexistence */
+	ret = wl1271_acx_fm_coex(wl);
 	if (ret < 0)
 		return ret;
 
@@ -407,7 +413,7 @@
 
 static int wl1271_ap_hw_init(struct wl1271 *wl)
 {
-	int ret, i;
+	int ret;
 
 	ret = wl1271_ap_init_templates_config(wl);
 	if (ret < 0)
@@ -418,23 +424,7 @@
 	if (ret < 0)
 		return ret;
 
-	/* Configure initial TX rate classes */
-	for (i = 0; i < wl->conf.tx.ac_conf_count; i++) {
-		ret = wl1271_acx_ap_rate_policy(wl,
-				&wl->conf.tx.ap_rc_conf[i], i);
-		if (ret < 0)
-			return ret;
-	}
-
-	ret = wl1271_acx_ap_rate_policy(wl,
-					&wl->conf.tx.ap_mgmt_conf,
-					ACX_TX_AP_MODE_MGMT_RATE);
-	if (ret < 0)
-		return ret;
-
-	ret = wl1271_acx_ap_rate_policy(wl,
-					&wl->conf.tx.ap_bcst_conf,
-					ACX_TX_AP_MODE_BCST_RATE);
+	ret = wl1271_init_ap_rates(wl);
 	if (ret < 0)
 		return ret;
 
@@ -449,7 +439,7 @@
 	return 0;
 }
 
-static int wl1271_ap_hw_init_post_mem(struct wl1271 *wl)
+int wl1271_ap_init_templates(struct wl1271 *wl)
 {
 	int ret;
 
@@ -465,6 +455,70 @@
 	if (ret < 0)
 		return ret;
 
+	/*
+	 * when operating as AP we want to receive external beacons for
+	 * configuring ERP protection.
+	 */
+	ret = wl1271_acx_set_ap_beacon_filter(wl, false);
+	if (ret < 0)
+		return ret;
+
+	return 0;
+}
+
+static int wl1271_ap_hw_init_post_mem(struct wl1271 *wl)
+{
+	return wl1271_ap_init_templates(wl);
+}
+
+int wl1271_init_ap_rates(struct wl1271 *wl)
+{
+	int i, ret;
+	struct conf_tx_rate_class rc;
+	u32 supported_rates;
+
+	wl1271_debug(DEBUG_AP, "AP basic rate set: 0x%x", wl->basic_rate_set);
+
+	if (wl->basic_rate_set == 0)
+		return -EINVAL;
+
+	rc.enabled_rates = wl->basic_rate_set;
+	rc.long_retry_limit = 10;
+	rc.short_retry_limit = 10;
+	rc.aflags = 0;
+	ret = wl1271_acx_ap_rate_policy(wl, &rc, ACX_TX_AP_MODE_MGMT_RATE);
+	if (ret < 0)
+		return ret;
+
+	/* use the min basic rate for AP broadcast/multicast */
+	rc.enabled_rates = wl1271_tx_min_rate_get(wl);
+	rc.short_retry_limit = 10;
+	rc.long_retry_limit = 10;
+	rc.aflags = 0;
+	ret = wl1271_acx_ap_rate_policy(wl, &rc, ACX_TX_AP_MODE_BCST_RATE);
+	if (ret < 0)
+		return ret;
+
+	/*
+	 * If the basic rates contain OFDM rates, use OFDM only
+	 * rates for unicast TX as well. Else use all supported rates.
+	 */
+	if ((wl->basic_rate_set & CONF_TX_OFDM_RATES))
+		supported_rates = CONF_TX_OFDM_RATES;
+	else
+		supported_rates = CONF_TX_AP_ENABLED_RATES;
+
+	/* configure unicast TX rate classes */
+	for (i = 0; i < wl->conf.tx.ac_conf_count; i++) {
+		rc.enabled_rates = supported_rates;
+		rc.short_retry_limit = 10;
+		rc.long_retry_limit = 10;
+		rc.aflags = 0;
+		ret = wl1271_acx_ap_rate_policy(wl, &rc, i);
+		if (ret < 0)
+			return ret;
+	}
+
 	return 0;
 }
 
@@ -504,6 +558,27 @@
 	return ret;
 }
 
+int wl1271_chip_specific_init(struct wl1271 *wl)
+{
+	int ret = 0;
+
+	if (wl->chip.id == CHIP_ID_1283_PG20) {
+		u32 host_cfg_bitmap = HOST_IF_CFG_RX_FIFO_ENABLE;
+
+		if (wl->quirks & WL12XX_QUIRK_BLOCKSIZE_ALIGNMENT)
+			/* Enable SDIO padding */
+			host_cfg_bitmap |= HOST_IF_CFG_TX_PAD_TO_SDIO_BLK;
+
+		/* Must be before wl1271_acx_init_mem_config() */
+		ret = wl1271_acx_host_if_cfg_bitmap(wl, host_cfg_bitmap);
+		if (ret < 0)
+			goto out;
+	}
+out:
+	return ret;
+}
+
+
 int wl1271_hw_init(struct wl1271 *wl)
 {
 	struct conf_tx_ac_category *conf_ac;
@@ -511,11 +586,22 @@
 	int ret, i;
 	bool is_ap = (wl->bss_type == BSS_TYPE_AP_BSS);
 
-	ret = wl1271_cmd_general_parms(wl);
+	if (wl->chip.id == CHIP_ID_1283_PG20)
+		ret = wl128x_cmd_general_parms(wl);
+	else
+		ret = wl1271_cmd_general_parms(wl);
 	if (ret < 0)
 		return ret;
 
-	ret = wl1271_cmd_radio_parms(wl);
+	if (wl->chip.id == CHIP_ID_1283_PG20)
+		ret = wl128x_cmd_radio_parms(wl);
+	else
+		ret = wl1271_cmd_radio_parms(wl);
+	if (ret < 0)
+		return ret;
+
+	/* Chip-specific init */
+	ret = wl1271_chip_specific_init(wl);
 	if (ret < 0)
 		return ret;
 
@@ -528,6 +614,11 @@
 	if (ret < 0)
 		return ret;
 
+	/* Bluetooth WLAN coexistence */
+	ret = wl1271_init_pta(wl);
+	if (ret < 0)
+		return ret;
+
 	/* Default memory configuration */
 	ret = wl1271_acx_init_mem_config(wl);
 	if (ret < 0)
@@ -567,7 +658,7 @@
 		goto out_free_memmap;
 
 	/* Default fragmentation threshold */
-	ret = wl1271_acx_frag_threshold(wl, wl->conf.tx.frag_threshold);
+	ret = wl1271_acx_frag_threshold(wl, wl->hw->wiphy->frag_threshold);
 	if (ret < 0)
 		goto out_free_memmap;
 
diff -druN linux-2.6.39-libre/drivers/net/wireless/wl12xx/init.h linux-3.0-rc7-libre/drivers/net/wireless/wl12xx/init.h
--- linux-2.6.39-libre/drivers/net/wireless/wl12xx/init.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/wl12xx/init.h	2011-07-11 19:51:52.000000000 -0400
@@ -31,6 +31,9 @@
 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_chip_specific_init(struct wl1271 *wl);
 int wl1271_hw_init(struct wl1271 *wl);
+int wl1271_init_ap_rates(struct wl1271 *wl);
+int wl1271_ap_init_templates(struct wl1271 *wl);
 
 #endif
diff -druN linux-2.6.39-libre/drivers/net/wireless/wl12xx/io.c linux-3.0-rc7-libre/drivers/net/wireless/wl12xx/io.c
--- linux-2.6.39-libre/drivers/net/wireless/wl12xx/io.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/wl12xx/io.c	2011-07-11 19:51:52.000000000 -0400
@@ -29,6 +29,7 @@
 #include "wl12xx.h"
 #include "wl12xx_80211.h"
 #include "io.h"
+#include "tx.h"
 
 #define OCP_CMD_LOOP  32
 
@@ -43,6 +44,16 @@
 #define OCP_STATUS_REQ_FAILED 0x20000
 #define OCP_STATUS_RESP_ERROR 0x30000
 
+bool wl1271_set_block_size(struct wl1271 *wl)
+{
+	if (wl->if_ops->set_block_size) {
+		wl->if_ops->set_block_size(wl, WL12XX_BUS_BLOCK_SIZE);
+		return true;
+	}
+
+	return false;
+}
+
 void wl1271_disable_interrupts(struct wl1271 *wl)
 {
 	wl->if_ops->disable_irq(wl);
diff -druN linux-2.6.39-libre/drivers/net/wireless/wl12xx/io.h linux-3.0-rc7-libre/drivers/net/wireless/wl12xx/io.h
--- linux-2.6.39-libre/drivers/net/wireless/wl12xx/io.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/wl12xx/io.h	2011-07-11 19:51:52.000000000 -0400
@@ -169,5 +169,8 @@
 struct ieee80211_hw *wl1271_alloc_hw(void);
 int wl1271_free_hw(struct wl1271 *wl);
 irqreturn_t wl1271_irq(int irq, void *data);
+bool wl1271_set_block_size(struct wl1271 *wl);
+int wl1271_tx_dummy_packet(struct wl1271 *wl);
+void wl1271_configure_filters(struct wl1271 *wl, unsigned int filters);
 
 #endif
diff -druN linux-2.6.39-libre/drivers/net/wireless/wl12xx/Kconfig linux-3.0-rc7-libre/drivers/net/wireless/wl12xx/Kconfig
--- linux-2.6.39-libre/drivers/net/wireless/wl12xx/Kconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/wl12xx/Kconfig	2011-07-11 19:51:52.000000000 -0400
@@ -3,7 +3,7 @@
 	depends on MAC80211 && EXPERIMENTAL
 	---help---
 	  This will enable TI wl12xx driver support for the following chips:
-	  wl1271 and wl1273.
+	  wl1271, wl1273, wl1281 and wl1283.
 	  The drivers make use of the mac80211 stack.
 
 config WL12XX
diff -druN linux-2.6.39-libre/drivers/net/wireless/wl12xx/main.c linux-3.0-rc7-libre/drivers/net/wireless/wl12xx/main.c
--- linux-2.6.39-libre/drivers/net/wireless/wl12xx/main.c	2011-05-19 02:16:15.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/wl12xx/main.c	2011-07-21 06:58:21.000000000 -0400
@@ -30,6 +30,7 @@
 #include <linux/vmalloc.h>
 #include <linux/platform_device.h>
 #include <linux/slab.h>
+#include <linux/wl12xx.h>
 
 #include "wl12xx.h"
 #include "wl12xx_80211.h"
@@ -50,11 +51,11 @@
 
 static struct conf_drv_settings default_conf = {
 	.sg = {
-		.params = {
+		.sta_params = {
 			[CONF_SG_BT_PER_THRESHOLD]                  = 7500,
 			[CONF_SG_HV3_MAX_OVERRIDE]                  = 0,
 			[CONF_SG_BT_NFS_SAMPLE_INTERVAL]            = 400,
-			[CONF_SG_BT_LOAD_RATIO]                     = 50,
+			[CONF_SG_BT_LOAD_RATIO]                     = 200,
 			[CONF_SG_AUTO_PS_MODE]                      = 1,
 			[CONF_SG_AUTO_SCAN_PROBE_REQ]               = 170,
 			[CONF_SG_ACTIVE_SCAN_DURATION_FACTOR_HV3]   = 50,
@@ -100,6 +101,61 @@
 			[CONF_SG_DHCP_TIME]                         = 5000,
 			[CONF_SG_ACTIVE_SCAN_DURATION_FACTOR_A2DP]  = 100,
 		},
+		.ap_params = {
+			[CONF_SG_BT_PER_THRESHOLD]                  = 7500,
+			[CONF_SG_HV3_MAX_OVERRIDE]                  = 0,
+			[CONF_SG_BT_NFS_SAMPLE_INTERVAL]            = 400,
+			[CONF_SG_BT_LOAD_RATIO]                     = 50,
+			[CONF_SG_AUTO_PS_MODE]                      = 1,
+			[CONF_SG_AUTO_SCAN_PROBE_REQ]               = 170,
+			[CONF_SG_ACTIVE_SCAN_DURATION_FACTOR_HV3]   = 50,
+			[CONF_SG_ANTENNA_CONFIGURATION]             = 0,
+			[CONF_SG_BEACON_MISS_PERCENT]               = 60,
+			[CONF_SG_RATE_ADAPT_THRESH]                 = 64,
+			[CONF_SG_RATE_ADAPT_SNR]                    = 1,
+			[CONF_SG_WLAN_PS_BT_ACL_MASTER_MIN_BR]      = 10,
+			[CONF_SG_WLAN_PS_BT_ACL_MASTER_MAX_BR]      = 25,
+			[CONF_SG_WLAN_PS_MAX_BT_ACL_MASTER_BR]      = 25,
+			[CONF_SG_WLAN_PS_BT_ACL_SLAVE_MIN_BR]       = 20,
+			[CONF_SG_WLAN_PS_BT_ACL_SLAVE_MAX_BR]       = 25,
+			[CONF_SG_WLAN_PS_MAX_BT_ACL_SLAVE_BR]       = 25,
+			[CONF_SG_WLAN_PS_BT_ACL_MASTER_MIN_EDR]     = 7,
+			[CONF_SG_WLAN_PS_BT_ACL_MASTER_MAX_EDR]     = 25,
+			[CONF_SG_WLAN_PS_MAX_BT_ACL_MASTER_EDR]     = 25,
+			[CONF_SG_WLAN_PS_BT_ACL_SLAVE_MIN_EDR]      = 8,
+			[CONF_SG_WLAN_PS_BT_ACL_SLAVE_MAX_EDR]      = 25,
+			[CONF_SG_WLAN_PS_MAX_BT_ACL_SLAVE_EDR]      = 25,
+			[CONF_SG_RXT]                               = 1200,
+			[CONF_SG_TXT]                               = 1000,
+			[CONF_SG_ADAPTIVE_RXT_TXT]                  = 1,
+			[CONF_SG_PS_POLL_TIMEOUT]                   = 10,
+			[CONF_SG_UPSD_TIMEOUT]                      = 10,
+			[CONF_SG_WLAN_ACTIVE_BT_ACL_MASTER_MIN_EDR] = 7,
+			[CONF_SG_WLAN_ACTIVE_BT_ACL_MASTER_MAX_EDR] = 15,
+			[CONF_SG_WLAN_ACTIVE_MAX_BT_ACL_MASTER_EDR] = 15,
+			[CONF_SG_WLAN_ACTIVE_BT_ACL_SLAVE_MIN_EDR]  = 8,
+			[CONF_SG_WLAN_ACTIVE_BT_ACL_SLAVE_MAX_EDR]  = 20,
+			[CONF_SG_WLAN_ACTIVE_MAX_BT_ACL_SLAVE_EDR]  = 15,
+			[CONF_SG_WLAN_ACTIVE_BT_ACL_MIN_BR]         = 20,
+			[CONF_SG_WLAN_ACTIVE_BT_ACL_MAX_BR]         = 50,
+			[CONF_SG_WLAN_ACTIVE_MAX_BT_ACL_BR]         = 10,
+			[CONF_SG_PASSIVE_SCAN_DURATION_FACTOR_HV3]  = 200,
+			[CONF_SG_PASSIVE_SCAN_DURATION_FACTOR_A2DP] = 800,
+			[CONF_SG_PASSIVE_SCAN_A2DP_BT_TIME]         = 75,
+			[CONF_SG_PASSIVE_SCAN_A2DP_WLAN_TIME]       = 15,
+			[CONF_SG_HV3_MAX_SERVED]                    = 6,
+			[CONF_SG_DHCP_TIME]                         = 5000,
+			[CONF_SG_ACTIVE_SCAN_DURATION_FACTOR_A2DP]  = 100,
+			[CONF_SG_TEMP_PARAM_1]                      = 0,
+			[CONF_SG_TEMP_PARAM_2]                      = 0,
+			[CONF_SG_TEMP_PARAM_3]                      = 0,
+			[CONF_SG_TEMP_PARAM_4]                      = 0,
+			[CONF_SG_TEMP_PARAM_5]                      = 0,
+			[CONF_SG_AP_BEACON_MISS_TX]                 = 3,
+			[CONF_SG_RX_WINDOW_LENGTH]                  = 6,
+			[CONF_SG_AP_CONNECTION_PROTECTION_TIME]     = 50,
+			[CONF_SG_TEMP_PARAM_6]                      = 1,
+		},
 		.state = CONF_SG_PROTECTIVE,
 	},
 	.rx = {
@@ -107,7 +163,7 @@
 		.packet_detection_threshold  = 0,
 		.ps_poll_timeout             = 15,
 		.upsd_timeout                = 15,
-		.rts_threshold               = 2347,
+		.rts_threshold               = IEEE80211_MAX_RTS_THRESHOLD,
 		.rx_cca_threshold            = 0,
 		.irq_blk_threshold           = 0xFFFF,
 		.irq_pkt_threshold           = 0,
@@ -153,44 +209,6 @@
 				.tx_op_limit = 1504,
 			},
 		},
-		.ap_rc_conf                  = {
-			[0] = {
-				.enabled_rates = CONF_TX_AP_ENABLED_RATES,
-				.short_retry_limit = 10,
-				.long_retry_limit = 10,
-				.aflags      = 0,
-			},
-			[1] = {
-				.enabled_rates = CONF_TX_AP_ENABLED_RATES,
-				.short_retry_limit = 10,
-				.long_retry_limit = 10,
-				.aflags      = 0,
-			},
-			[2] = {
-				.enabled_rates = CONF_TX_AP_ENABLED_RATES,
-				.short_retry_limit = 10,
-				.long_retry_limit = 10,
-				.aflags      = 0,
-			},
-			[3] = {
-				.enabled_rates = CONF_TX_AP_ENABLED_RATES,
-				.short_retry_limit = 10,
-				.long_retry_limit = 10,
-				.aflags      = 0,
-			},
-		},
-		.ap_mgmt_conf = {
-			.enabled_rates       = CONF_TX_AP_DEFAULT_MGMT_RATES,
-			.short_retry_limit   = 10,
-			.long_retry_limit    = 10,
-			.aflags              = 0,
-		},
-		.ap_bcst_conf = {
-			.enabled_rates       = CONF_HW_BIT_RATE_1MBPS,
-			.short_retry_limit   = 10,
-			.long_retry_limit    = 10,
-			.aflags              = 0,
-		},
 		.ap_max_tx_retries = 100,
 		.tid_conf_count = 4,
 		.tid_conf = {
@@ -239,12 +257,16 @@
 		.wake_up_event               = CONF_WAKE_UP_EVENT_DTIM,
 		.listen_interval             = 1,
 		.bcn_filt_mode               = CONF_BCN_FILT_MODE_ENABLED,
-		.bcn_filt_ie_count           = 1,
+		.bcn_filt_ie_count           = 2,
 		.bcn_filt_ie = {
 			[0] = {
 				.ie          = WLAN_EID_CHANNEL_SWITCH,
 				.rule        = CONF_BCN_RULE_PASS_ON_APPEARANCE,
-			}
+			},
+			[1] = {
+				.ie          = WLAN_EID_HT_INFORMATION,
+				.rule        = CONF_BCN_RULE_PASS_ON_CHANGE,
+			},
 		},
 		.synch_fail_thold            = 10,
 		.bss_lose_timeout            = 100,
@@ -254,9 +276,9 @@
 		.ps_poll_threshold           = 10,
 		.ps_poll_recovery_period     = 700,
 		.bet_enable                  = CONF_BET_MODE_ENABLE,
-		.bet_max_consecutive         = 10,
+		.bet_max_consecutive         = 50,
 		.psm_entry_retries           = 5,
-		.psm_exit_retries            = 255,
+		.psm_exit_retries            = 16,
 		.psm_entry_nullfunc_retries  = 3,
 		.psm_entry_hangover_period   = 1,
 		.keep_alive_interval         = 55000,
@@ -284,6 +306,16 @@
 		.max_dwell_time_passive       = 100000,
 		.num_probe_reqs               = 2,
 	},
+	.sched_scan = {
+		/* sched_scan requires dwell times in TU instead of TU/1000 */
+		.min_dwell_time_active = 8,
+		.max_dwell_time_active = 30,
+		.dwell_time_passive    = 100,
+		.dwell_time_dfs        = 150,
+		.num_probe_reqs        = 2,
+		.rssi_threshold        = -90,
+		.snr_threshold         = 0,
+	},
 	.rf = {
 		.tx_per_channel_power_compensation_2 = {
 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
@@ -298,19 +330,43 @@
 		.tx_ba_win_size = 64,
 		.inactivity_timeout = 10000,
 	},
-	.mem = {
+	.mem_wl127x = {
 		.num_stations                 = 1,
 		.ssid_profiles                = 1,
 		.rx_block_num                 = 70,
 		.tx_min_block_num             = 40,
-		.dynamic_memory               = 0,
+		.dynamic_memory               = 1,
 		.min_req_tx_blocks            = 100,
 		.min_req_rx_blocks            = 22,
 		.tx_min                       = 27,
-	}
+	},
+	.mem_wl128x = {
+		.num_stations                 = 1,
+		.ssid_profiles                = 1,
+		.rx_block_num                 = 40,
+		.tx_min_block_num             = 40,
+		.dynamic_memory               = 1,
+		.min_req_tx_blocks            = 45,
+		.min_req_rx_blocks            = 22,
+		.tx_min                       = 27,
+	},
+	.fm_coex = {
+		.enable                       = true,
+		.swallow_period               = 5,
+		.n_divider_fref_set_1         = 0xff,       /* default */
+		.n_divider_fref_set_2         = 12,
+		.m_divider_fref_set_1         = 148,
+		.m_divider_fref_set_2         = 0xffff,     /* default */
+		.coex_pll_stabilization_time  = 0xffffffff, /* default */
+		.ldo_stabilization_time       = 0xffff,     /* default */
+		.fm_disturbed_band_margin     = 0xff,       /* default */
+		.swallow_clk_diff             = 0xff,       /* default */
+	},
+	.hci_io_ds = HCI_IO_DS_6MA,
 };
 
-static void __wl1271_op_remove_interface(struct wl1271 *wl);
+static void __wl1271_op_remove_interface(struct wl1271 *wl,
+					 bool reset_tx_queues);
 static void wl1271_free_ap_keys(struct wl1271 *wl);
 
 
@@ -329,6 +385,7 @@
 	},
 };
 
+static DEFINE_MUTEX(wl_list_mutex);
 static LIST_HEAD(wl_list);
 
 static int wl1271_dev_notify(struct notifier_block *me, unsigned long what,
@@ -359,10 +416,12 @@
 		return NOTIFY_DONE;
 
 	wl_temp = hw->priv;
+	mutex_lock(&wl_list_mutex);
 	list_for_each_entry(wl, &wl_list, list) {
 		if (wl == wl_temp)
 			break;
 	}
+	mutex_unlock(&wl_list_mutex);
 	if (wl != wl_temp)
 		return NOTIFY_DONE;
 
@@ -438,15 +497,30 @@
 	struct conf_tx_tid *conf_tid;
 	int ret, i;
 
-	ret = wl1271_cmd_general_parms(wl);
+	if (wl->chip.id == CHIP_ID_1283_PG20)
+		ret = wl128x_cmd_general_parms(wl);
+	else
+		ret = wl1271_cmd_general_parms(wl);
 	if (ret < 0)
 		return ret;
 
-	ret = wl1271_cmd_radio_parms(wl);
+	if (wl->chip.id == CHIP_ID_1283_PG20)
+		ret = wl128x_cmd_radio_parms(wl);
+	else
+		ret = wl1271_cmd_radio_parms(wl);
 	if (ret < 0)
 		return ret;
 
-	ret = wl1271_cmd_ext_radio_parms(wl);
+	if (wl->chip.id != CHIP_ID_1283_PG20) {
+		ret = wl1271_cmd_ext_radio_parms(wl);
+		if (ret < 0)
+			return ret;
+	}
+	if (ret < 0)
+		return ret;
+
+	/* Chip-specific initializations */
+	ret = wl1271_chip_specific_init(wl);
 	if (ret < 0)
 		return ret;
 
@@ -477,6 +551,11 @@
 	if (ret < 0)
 		goto out_free_memmap;
 
+	/* FM WLAN coexistence */
+	ret = wl1271_acx_fm_coex(wl);
+	if (ret < 0)
+		goto out_free_memmap;
+
 	/* Energy detection */
 	ret = wl1271_init_energy_detection(wl);
 	if (ret < 0)
@@ -593,15 +672,17 @@
 {
 	struct wl1271_fw_common_status *status = &full_status->common;
 	struct timespec ts;
-	u32 total = 0;
+	u32 old_tx_blk_count = wl->tx_blocks_available;
+	u32 freed_blocks = 0;
 	int i;
 
-	if (wl->bss_type == BSS_TYPE_AP_BSS)
+	if (wl->bss_type == BSS_TYPE_AP_BSS) {
 		wl1271_raw_read(wl, FW_STATUS_ADDR, status,
 				sizeof(struct wl1271_fw_ap_status), false);
-	else
+	} else {
 		wl1271_raw_read(wl, FW_STATUS_ADDR, status,
 				sizeof(struct wl1271_fw_sta_status), false);
+	}
 
 	wl1271_debug(DEBUG_IRQ, "intr: 0x%x (fw_rx_counter = %d, "
 		     "drv_rx_counter = %d, tx_results_counter = %d)",
@@ -612,22 +693,37 @@
 
 	/* update number of available TX blocks */
 	for (i = 0; i < NUM_TX_QUEUES; i++) {
-		u32 cnt = le32_to_cpu(status->tx_released_blks[i]) -
-			wl->tx_blocks_freed[i];
+		freed_blocks += le32_to_cpu(status->tx_released_blks[i]) -
+				wl->tx_blocks_freed[i];
 
 		wl->tx_blocks_freed[i] =
 			le32_to_cpu(status->tx_released_blks[i]);
-		wl->tx_blocks_available += cnt;
-		total += cnt;
 	}
 
-	/* if more blocks are available now, tx work can be scheduled */
-	if (total)
-		clear_bit(WL1271_FLAG_FW_TX_BUSY, &wl->flags);
+	wl->tx_allocated_blocks -= freed_blocks;
 
-	/* for AP update num of allocated TX blocks per link and ps status */
-	if (wl->bss_type == BSS_TYPE_AP_BSS)
+	if (wl->bss_type == BSS_TYPE_AP_BSS) {
+		/* Update num of allocated TX blocks per link and ps status */
 		wl1271_irq_update_links_status(wl, &full_status->ap);
+		wl->tx_blocks_available += freed_blocks;
+	} else {
+		int avail = full_status->sta.tx_total - wl->tx_allocated_blocks;
+
+		/*
+		 * The FW might change the total number of TX memblocks before
+		 * we get a notification about blocks being released. Thus, the
+		 * available blocks calculation might yield a temporary result
+		 * which is lower than the actual available blocks. Keeping in
+		 * mind that only blocks that were allocated can be moved from
+		 * TX to RX, tx_blocks_available should never decrease here.
+		 */
+		wl->tx_blocks_available = max((int)wl->tx_blocks_available,
+					      avail);
+	}
+
+	/* if more blocks are available now, tx work can be scheduled */
+	if (wl->tx_blocks_available > old_tx_blk_count)
+		clear_bit(WL1271_FLAG_FW_TX_BUSY, &wl->flags);
 
 	/* update the host-chipset time offset */
 	getnstimeofday(&ts);
@@ -674,6 +770,13 @@
 	set_bit(WL1271_FLAG_TX_PENDING, &wl->flags);
 	cancel_work_sync(&wl->tx_work);
 
+	/*
+	 * In case edge triggered interrupt must be used, we cannot iterate
+	 * more than once without introducing race conditions with the hardirq.
+	 */
+	if (wl->platform_quirks & WL12XX_PLATFORM_QUIRK_EDGE_IRQ)
+		loopcount = 1;
+
 	mutex_lock(&wl->mutex);
 
 	wl1271_debug(DEBUG_IRQ, "IRQ work");
@@ -785,11 +888,17 @@
 
 	switch (wl->bss_type) {
 	case BSS_TYPE_AP_BSS:
-		fw_name = WL1271_AP_FW_NAME;
+		if (wl->chip.id == CHIP_ID_1283_PG20)
+			fw_name = WL128X_AP_FW_NAME;
+		else
+			fw_name = WL127X_AP_FW_NAME;
 		break;
 	case BSS_TYPE_IBSS:
 	case BSS_TYPE_STA_BSS:
-		fw_name = WL1271_FW_NAME;
+		if (wl->chip.id == CHIP_ID_1283_PG20)
+			fw_name = WL128X_FW_NAME;
+		else
+			fw_name	= WL1271_FW_NAME;
 		break;
 	default:
 		wl1271_error("no compatible firmware for bss_type %d",
@@ -838,14 +947,14 @@
 	const struct firmware *fw;
 	int ret;
 
-	ret = reject_firmware(&fw, WL1271_NVS_NAME, wl1271_wl_to_dev(wl));
+	ret = reject_firmware(&fw, WL12XX_NVS_NAME, wl1271_wl_to_dev(wl));
 
 	if (ret < 0) {
 		wl1271_error("could not get nvs file: %d", ret);
 		return ret;
 	}
 
-	wl->nvs = kmemdup(fw->data, sizeof(struct wl1271_nvs_file), GFP_KERNEL);
+	wl->nvs = kmemdup(fw->data, fw->size, GFP_KERNEL);
 
 	if (!wl->nvs) {
 		wl1271_error("could not allocate memory for the nvs file");
@@ -871,15 +980,30 @@
 	if (wl->state != WL1271_STATE_ON)
 		goto out;
 
-	wl1271_info("Hardware recovery in progress.");
+	wl1271_info("Hardware recovery in progress. FW ver: %s pc: 0x%x",
+		    wl->chip.fw_ver_str, wl1271_read32(wl, SCR_PAD4));
 
 	if (test_bit(WL1271_FLAG_STA_ASSOCIATED, &wl->flags))
 		ieee80211_connection_loss(wl->vif);
 
+	/* Prevent spurious TX during FW restart */
+	ieee80211_stop_queues(wl->hw);
+
+	if (wl->sched_scanning) {
+		ieee80211_sched_scan_stopped(wl->hw);
+		wl->sched_scanning = false;
+	}
+
 	/* reboot the chipset */
-	__wl1271_op_remove_interface(wl);
+	__wl1271_op_remove_interface(wl, false);
 	ieee80211_restart_hw(wl->hw);
 
+	/*
+	 * Its safe to enable TX now - the queues are stopped after a request
+	 * to restart the HW.
+	 */
+	ieee80211_wake_queues(wl->hw);
+
 out:
 	mutex_unlock(&wl->mutex);
 }
@@ -950,10 +1074,25 @@
 		wl1271_debug(DEBUG_BOOT, "chip id 0x%x (1271 PG20)",
 			     wl->chip.id);
 
+		/* end-of-transaction flag should be set in wl127x AP mode */
+		if (wl->bss_type == BSS_TYPE_AP_BSS)
+			wl->quirks |= WL12XX_QUIRK_END_OF_TRANSACTION;
+
+		ret = wl1271_setup(wl);
+		if (ret < 0)
+			goto out;
+		break;
+	case CHIP_ID_1283_PG20:
+		wl1271_debug(DEBUG_BOOT, "chip id 0x%x (1283 PG20)",
+			     wl->chip.id);
+
 		ret = wl1271_setup(wl);
 		if (ret < 0)
 			goto out;
+		if (wl1271_set_block_size(wl))
+			wl->quirks |= WL12XX_QUIRK_BLOCKSIZE_ALIGNMENT;
 		break;
+	case CHIP_ID_1283_PG10:
 	default:
 		wl1271_warning("unsupported chip id: 0x%x", wl->chip.id);
 		ret = -ENODEV;
@@ -978,6 +1117,24 @@
 	return ret;
 }
 
+static unsigned int wl1271_get_fw_ver_quirks(struct wl1271 *wl)
+{
+	unsigned int quirks = 0;
+	unsigned int *fw_ver = wl->chip.fw_ver;
+
+	/* Only for wl127x */
+	if ((fw_ver[FW_VER_CHIP] == FW_VER_CHIP_WL127X) &&
+	    /* Check STA version */
+	    (((fw_ver[FW_VER_IF_TYPE] == FW_VER_IF_TYPE_STA) &&
+	      (fw_ver[FW_VER_MINOR] < FW_VER_MINOR_1_SPARE_STA_MIN)) ||
+	     /* Check AP version */
+	     ((fw_ver[FW_VER_IF_TYPE] == FW_VER_IF_TYPE_AP) &&
+	      (fw_ver[FW_VER_MINOR] < FW_VER_MINOR_1_SPARE_AP_MIN))))
+		quirks |= WL12XX_QUIRK_USE_2_SPARE_BLOCKS;
+
+	return quirks;
+}
+
 int wl1271_plt_start(struct wl1271 *wl)
 {
 	int retries = WL1271_BOOT_RETRIES;
@@ -1013,6 +1170,9 @@
 		wl->state = WL1271_STATE_PLT;
 		wl1271_notice("firmware booted in PLT mode (%s)",
 			      wl->chip.fw_ver_str);
+
+		/* Check if any quirks are needed with older fw versions */
+		wl->quirks |= wl1271_get_fw_ver_quirks(wl);
 		goto out;
 
 irq_disable:
@@ -1040,7 +1200,7 @@
 	return ret;
 }
 
-int __wl1271_plt_stop(struct wl1271 *wl)
+static int __wl1271_plt_stop(struct wl1271 *wl)
 {
 	int ret = 0;
 
@@ -1124,10 +1284,219 @@
 	spin_unlock_irqrestore(&wl->wl_lock, flags);
 }
 
+int wl1271_tx_dummy_packet(struct wl1271 *wl)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&wl->wl_lock, flags);
+	set_bit(WL1271_FLAG_DUMMY_PACKET_PENDING, &wl->flags);
+	wl->tx_queue_count++;
+	spin_unlock_irqrestore(&wl->wl_lock, flags);
+
+	/* The FW is low on RX memory blocks, so send the dummy packet asap */
+	if (!test_bit(WL1271_FLAG_FW_TX_BUSY, &wl->flags))
+		wl1271_tx_work_locked(wl);
+
+	/*
+	 * If the FW TX is busy, TX work will be scheduled by the threaded
+	 * interrupt handler function
+	 */
+	return 0;
+}
+
+/*
+ * The size of the dummy packet should be at least 1400 bytes. However, in
+ * order to minimize the number of bus transactions, aligning it to 512 bytes
+ * boundaries could be beneficial, performance wise
+ */
+#define TOTAL_TX_DUMMY_PACKET_SIZE (ALIGN(1400, 512))
+
+static struct sk_buff *wl12xx_alloc_dummy_packet(struct wl1271 *wl)
+{
+	struct sk_buff *skb;
+	struct ieee80211_hdr_3addr *hdr;
+	unsigned int dummy_packet_size;
+
+	dummy_packet_size = TOTAL_TX_DUMMY_PACKET_SIZE -
+			    sizeof(struct wl1271_tx_hw_descr) - sizeof(*hdr);
+
+	skb = dev_alloc_skb(TOTAL_TX_DUMMY_PACKET_SIZE);
+	if (!skb) {
+		wl1271_warning("Failed to allocate a dummy packet skb");
+		return NULL;
+	}
+
+	skb_reserve(skb, sizeof(struct wl1271_tx_hw_descr));
+
+	hdr = (struct ieee80211_hdr_3addr *) skb_put(skb, sizeof(*hdr));
+	memset(hdr, 0, sizeof(*hdr));
+	hdr->frame_control = cpu_to_le16(IEEE80211_FTYPE_DATA |
+					 IEEE80211_STYPE_NULLFUNC |
+					 IEEE80211_FCTL_TODS);
+
+	memset(skb_put(skb, dummy_packet_size), 0, dummy_packet_size);
+
+	/* Dummy packets require the TID to be management */
+	skb->priority = WL1271_TID_MGMT;
+
+	/* Initialize all fields that might be used */
+	skb_set_queue_mapping(skb, 0);
+	memset(IEEE80211_SKB_CB(skb), 0, sizeof(struct ieee80211_tx_info));
+
+	return skb;
+}
+
+
 static struct notifier_block wl1271_dev_notifier = {
 	.notifier_call = wl1271_dev_notify,
 };
 
+#ifdef CONFIG_PM
+static int wl1271_configure_suspend(struct wl1271 *wl)
+{
+	int ret;
+
+	if (wl->bss_type != BSS_TYPE_STA_BSS)
+		return 0;
+
+	mutex_lock(&wl->mutex);
+
+	ret = wl1271_ps_elp_wakeup(wl);
+	if (ret < 0)
+		goto out_unlock;
+
+	/* enter psm if needed*/
+	if (!test_bit(WL1271_FLAG_PSM, &wl->flags)) {
+		DECLARE_COMPLETION_ONSTACK(compl);
+
+		wl->ps_compl = &compl;
+		ret = wl1271_ps_set_mode(wl, STATION_POWER_SAVE_MODE,
+				   wl->basic_rate, true);
+		if (ret < 0)
+			goto out_sleep;
+
+		/* we must unlock here so we will be able to get events */
+		wl1271_ps_elp_sleep(wl);
+		mutex_unlock(&wl->mutex);
+
+		ret = wait_for_completion_timeout(
+			&compl, msecs_to_jiffies(WL1271_PS_COMPLETE_TIMEOUT));
+		if (ret <= 0) {
+			wl1271_warning("couldn't enter ps mode!");
+			ret = -EBUSY;
+			goto out;
+		}
+
+		/* take mutex again, and wakeup */
+		mutex_lock(&wl->mutex);
+
+		ret = wl1271_ps_elp_wakeup(wl);
+		if (ret < 0)
+			goto out_unlock;
+	}
+out_sleep:
+	wl1271_ps_elp_sleep(wl);
+out_unlock:
+	mutex_unlock(&wl->mutex);
+out:
+	return ret;
+
+}
+
+static void wl1271_configure_resume(struct wl1271 *wl)
+{
+	int ret;
+
+	if (wl->bss_type != BSS_TYPE_STA_BSS)
+		return;
+
+	mutex_lock(&wl->mutex);
+	ret = wl1271_ps_elp_wakeup(wl);
+	if (ret < 0)
+		goto out;
+
+	/* exit psm if it wasn't configured */
+	if (!test_bit(WL1271_FLAG_PSM_REQUESTED, &wl->flags))
+		wl1271_ps_set_mode(wl, STATION_ACTIVE_MODE,
+				   wl->basic_rate, true);
+
+	wl1271_ps_elp_sleep(wl);
+out:
+	mutex_unlock(&wl->mutex);
+}
+
+static int wl1271_op_suspend(struct ieee80211_hw *hw,
+			    struct cfg80211_wowlan *wow)
+{
+	struct wl1271 *wl = hw->priv;
+	wl1271_debug(DEBUG_MAC80211, "mac80211 suspend wow=%d", !!wow);
+	wl->wow_enabled = !!wow;
+	if (wl->wow_enabled) {
+		int ret;
+		ret = wl1271_configure_suspend(wl);
+		if (ret < 0) {
+			wl1271_warning("couldn't prepare device to suspend");
+			return ret;
+		}
+		/* flush any remaining work */
+		wl1271_debug(DEBUG_MAC80211, "flushing remaining works");
+		flush_delayed_work(&wl->scan_complete_work);
+
+		/*
+		 * disable and re-enable interrupts in order to flush
+		 * the threaded_irq
+		 */
+		wl1271_disable_interrupts(wl);
+
+		/*
+		 * set suspended flag to avoid triggering a new threaded_irq
+		 * work. no need for spinlock as interrupts are disabled.
+		 */
+		set_bit(WL1271_FLAG_SUSPENDED, &wl->flags);
+
+		wl1271_enable_interrupts(wl);
+		flush_work(&wl->tx_work);
+		flush_delayed_work(&wl->pspoll_work);
+		flush_delayed_work(&wl->elp_work);
+	}
+	return 0;
+}
+
+static int wl1271_op_resume(struct ieee80211_hw *hw)
+{
+	struct wl1271 *wl = hw->priv;
+	wl1271_debug(DEBUG_MAC80211, "mac80211 resume wow=%d",
+		     wl->wow_enabled);
+
+	/*
+	 * re-enable irq_work enqueuing, and call irq_work directly if
+	 * there is a pending work.
+	 */
+	if (wl->wow_enabled) {
+		struct wl1271 *wl = hw->priv;
+		unsigned long flags;
+		bool run_irq_work = false;
+
+		spin_lock_irqsave(&wl->wl_lock, flags);
+		clear_bit(WL1271_FLAG_SUSPENDED, &wl->flags);
+		if (test_and_clear_bit(WL1271_FLAG_PENDING_WORK, &wl->flags))
+			run_irq_work = true;
+		spin_unlock_irqrestore(&wl->wl_lock, flags);
+
+		if (run_irq_work) {
+			wl1271_debug(DEBUG_MAC80211,
+				     "run postponed irq_work directly");
+			wl1271_irq(0, wl);
+			wl1271_enable_interrupts(wl);
+		}
+
+		wl1271_configure_resume(wl);
+	}
+
+	return 0;
+}
+#endif
+
 static int wl1271_op_start(struct ieee80211_hw *hw)
 {
 	wl1271_debug(DEBUG_MAC80211, "mac80211 start");
@@ -1174,6 +1543,16 @@
 		goto out;
 	}
 
+	/*
+	 * in some very corner case HW recovery scenarios its possible to
+	 * get here before __wl1271_op_remove_interface is complete, so
+	 * opt out if that is the case.
+	 */
+	if (test_bit(WL1271_FLAG_IF_INITIALIZED, &wl->flags)) {
+		ret = -EBUSY;
+		goto out;
+	}
+
 	switch (vif->type) {
 	case NL80211_IFTYPE_STATION:
 		wl->bss_type = BSS_TYPE_STA_BSS;
@@ -1242,6 +1621,7 @@
 
 	wl->vif = vif;
 	wl->state = WL1271_STATE_ON;
+	set_bit(WL1271_FLAG_IF_INITIALIZED, &wl->flags);
 	wl1271_info("firmware booted (%s)", wl->chip.fw_ver_str);
 
 	/* update hw/fw version info in wiphy struct */
@@ -1249,6 +1629,9 @@
 	strncpy(wiphy->fw_version, wl->chip.fw_ver_str,
 		sizeof(wiphy->fw_version));
 
+	/* Check if any quirks are needed with older fw versions */
+	wl->quirks |= wl1271_get_fw_ver_quirks(wl);
+
 	/*
 	 * Now we know if 11a is supported (info from the NVS), so disable
 	 * 11a channels if not supported
@@ -1262,23 +1645,30 @@
 out:
 	mutex_unlock(&wl->mutex);
 
+	mutex_lock(&wl_list_mutex);
 	if (!ret)
 		list_add(&wl->list, &wl_list);
+	mutex_unlock(&wl_list_mutex);
 
 	return ret;
 }
 
-static void __wl1271_op_remove_interface(struct wl1271 *wl)
+static void __wl1271_op_remove_interface(struct wl1271 *wl,
+					 bool reset_tx_queues)
 {
 	int i;
 
 	wl1271_debug(DEBUG_MAC80211, "mac80211 remove interface");
 
+	/* because of hardware recovery, we may get here twice */
+	if (wl->state != WL1271_STATE_ON)
+		return;
+
 	wl1271_info("down");
 
+	mutex_lock(&wl_list_mutex);
 	list_del(&wl->list);
-
-	WARN_ON(wl->state != WL1271_STATE_ON);
+	mutex_unlock(&wl_list_mutex);
 
 	/* enable dyn ps just in case (if left on due to fw crash etc) */
 	if (wl->bss_type == BSS_TYPE_STA_BSS)
@@ -1286,12 +1676,15 @@
 
 	if (wl->scan.state != WL1271_SCAN_STATE_IDLE) {
 		wl->scan.state = WL1271_SCAN_STATE_IDLE;
-		kfree(wl->scan.scanned_ch);
-		wl->scan.scanned_ch = NULL;
+		memset(wl->scan.scanned_ch, 0, sizeof(wl->scan.scanned_ch));
 		wl->scan.req = NULL;
 		ieee80211_scan_completed(wl->hw, true);
 	}
 
+	/*
+	 * this must be before the cancel_work calls below, so that the work
+	 * functions don't perform further work.
+	 */
 	wl->state = WL1271_STATE_OFF;
 
 	mutex_unlock(&wl->mutex);
@@ -1307,7 +1700,7 @@
 	mutex_lock(&wl->mutex);
 
 	/* let's notify MAC80211 about the remaining pending TX frames */
-	wl1271_tx_reset(wl);
+	wl1271_tx_reset(wl, reset_tx_queues);
 	wl1271_power_off(wl);
 
 	memset(wl->bssid, 0, ETH_ALEN);
@@ -1321,6 +1714,7 @@
 	wl->psm_entry_retry = 0;
 	wl->power_level = WL1271_DEFAULT_POWER_LEVEL;
 	wl->tx_blocks_available = 0;
+	wl->tx_allocated_blocks = 0;
 	wl->tx_results_count = 0;
 	wl->tx_packets_count = 0;
 	wl->tx_security_last_seq = 0;
@@ -1328,13 +1722,20 @@
 	wl->time_offset = 0;
 	wl->session_counter = 0;
 	wl->rate_set = CONF_TX_RATE_MASK_BASIC;
-	wl->flags = 0;
 	wl->vif = NULL;
 	wl->filters = 0;
 	wl1271_free_ap_keys(wl);
 	memset(wl->ap_hlid_map, 0, sizeof(wl->ap_hlid_map));
 	wl->ap_fw_ps_map = 0;
 	wl->ap_ps_map = 0;
+	wl->sched_scanning = false;
+
+	/*
+	 * this is performed after the cancel_work calls and the associated
+	 * mutex_lock, so that wl1271_op_add_interface does not accidentally
+	 * get executed before all these vars have been reset.
+	 */
+	wl->flags = 0;
 
 	for (i = 0; i < NUM_TX_QUEUES; i++)
 		wl->tx_blocks_freed[i] = 0;
@@ -1361,14 +1762,14 @@
 	 */
 	if (wl->vif) {
 		WARN_ON(wl->vif != vif);
-		__wl1271_op_remove_interface(wl);
+		__wl1271_op_remove_interface(wl, true);
 	}
 
 	mutex_unlock(&wl->mutex);
 	cancel_work_sync(&wl->recovery_work);
 }
 
-static void wl1271_configure_filters(struct wl1271 *wl, unsigned int filters)
+void wl1271_configure_filters(struct wl1271 *wl, unsigned int filters)
 {
 	wl1271_set_default_filters(wl);
 
@@ -1431,10 +1832,10 @@
 	 * One of the side effects of the JOIN command is that is clears
 	 * WPA/WPA2 keys from the chipset. Performing a JOIN while associated
 	 * to a WPA/WPA2 access point will therefore kill the data-path.
-	 * Currently there is no supported scenario for JOIN during
-	 * association - if it becomes a supported scenario, the WPA/WPA2 keys
-	 * must be handled somehow.
-	 *
+	 * Currently the only valid scenario for JOIN during association
+	 * is on roaming, in which case we will also be given new keys.
+	 * Keep the below message for now, unless it starts bothering
+	 * users who really like to roam a lot :)
 	 */
 	if (test_bit(WL1271_FLAG_STA_ASSOCIATED, &wl->flags))
 		wl1271_info("JOIN while associated.");
@@ -1490,7 +1891,7 @@
 	clear_bit(WL1271_FLAG_JOINED, &wl->flags);
 	memset(wl->bssid, 0, ETH_ALEN);
 
-	/* stop filterting packets based on bssid */
+	/* stop filtering packets based on bssid */
 	wl1271_configure_filters(wl, FIF_OTHER_BSS);
 
 out:
@@ -1530,6 +1931,13 @@
 		wl->session_counter++;
 		if (wl->session_counter >= SESSION_COUNTER_MAX)
 			wl->session_counter = 0;
+
+		/* The current firmware only supports sched_scan in idle */
+		if (wl->sched_scanning) {
+			wl1271_scan_sched_scan_stop(wl);
+			ieee80211_sched_scan_stopped(wl->hw);
+		}
+
 		ret = wl1271_dummy_join(wl);
 		if (ret < 0)
 			goto out;
@@ -1569,7 +1977,12 @@
 	mutex_lock(&wl->mutex);
 
 	if (unlikely(wl->state == WL1271_STATE_OFF)) {
-		ret = -EAGAIN;
+		/* we support configuring the channel and band while off */
+		if ((changed & IEEE80211_CONF_CHANGE_CHANNEL)) {
+			wl->band = conf->channel->band;
+			wl->channel = channel;
+		}
+
 		goto out;
 	}
 
@@ -2077,6 +2490,60 @@
 	return ret;
 }
 
+static int wl1271_op_sched_scan_start(struct ieee80211_hw *hw,
+				      struct ieee80211_vif *vif,
+				      struct cfg80211_sched_scan_request *req,
+				      struct ieee80211_sched_scan_ies *ies)
+{
+	struct wl1271 *wl = hw->priv;
+	int ret;
+
+	wl1271_debug(DEBUG_MAC80211, "wl1271_op_sched_scan_start");
+
+	mutex_lock(&wl->mutex);
+
+	ret = wl1271_ps_elp_wakeup(wl);
+	if (ret < 0)
+		goto out;
+
+	ret = wl1271_scan_sched_scan_config(wl, req, ies);
+	if (ret < 0)
+		goto out_sleep;
+
+	ret = wl1271_scan_sched_scan_start(wl);
+	if (ret < 0)
+		goto out_sleep;
+
+	wl->sched_scanning = true;
+
+out_sleep:
+	wl1271_ps_elp_sleep(wl);
+out:
+	mutex_unlock(&wl->mutex);
+	return ret;
+}
+
+static void wl1271_op_sched_scan_stop(struct ieee80211_hw *hw,
+				      struct ieee80211_vif *vif)
+{
+	struct wl1271 *wl = hw->priv;
+	int ret;
+
+	wl1271_debug(DEBUG_MAC80211, "wl1271_op_sched_scan_stop");
+
+	mutex_lock(&wl->mutex);
+
+	ret = wl1271_ps_elp_wakeup(wl);
+	if (ret < 0)
+		goto out;
+
+	wl1271_scan_sched_scan_stop(wl);
+
+	wl1271_ps_elp_sleep(wl);
+out:
+	mutex_unlock(&wl->mutex);
+}
+
 static int wl1271_op_set_frag_threshold(struct ieee80211_hw *hw, u32 value)
 {
 	struct wl1271 *wl = hw->priv;
@@ -2093,7 +2560,7 @@
 	if (ret < 0)
 		goto out;
 
-	ret = wl1271_acx_frag_threshold(wl, (u16)value);
+	ret = wl1271_acx_frag_threshold(wl, value);
 	if (ret < 0)
 		wl1271_warning("wl1271_op_set_frag_threshold failed: %d", ret);
 
@@ -2121,7 +2588,7 @@
 	if (ret < 0)
 		goto out;
 
-	ret = wl1271_acx_rts_threshold(wl, (u16) value);
+	ret = wl1271_acx_rts_threshold(wl, value);
 	if (ret < 0)
 		wl1271_warning("wl1271_op_set_rts_threshold failed: %d", ret);
 
@@ -2136,20 +2603,24 @@
 static int wl1271_ssid_set(struct wl1271 *wl, struct sk_buff *skb,
 			    int offset)
 {
-	u8 *ptr = skb->data + offset;
+	u8 ssid_len;
+	const u8 *ptr = cfg80211_find_ie(WLAN_EID_SSID, skb->data + offset,
+					 skb->len - offset);
 
-	/* find the location of the ssid in the beacon */
-	while (ptr < skb->data + skb->len) {
-		if (ptr[0] == WLAN_EID_SSID) {
-			wl->ssid_len = ptr[1];
-			memcpy(wl->ssid, ptr+2, wl->ssid_len);
-			return 0;
-		}
-		ptr += (ptr[1] + 2);
+	if (!ptr) {
+		wl1271_error("No SSID in IEs!");
+		return -ENOENT;
 	}
 
-	wl1271_error("No SSID in IEs!\n");
-	return -ENOENT;
+	ssid_len = ptr[1];
+	if (ssid_len > IEEE80211_MAX_SSID_LEN) {
+		wl1271_error("SSID is too long!");
+		return -EINVAL;
+	}
+
+	wl->ssid_len = ssid_len;
+	memcpy(wl->ssid, ptr+2, ssid_len);
+	return 0;
 }
 
 static int wl1271_bss_erp_info_changed(struct wl1271 *wl,
@@ -2264,24 +2735,19 @@
 
 	if ((changed & BSS_CHANGED_BASIC_RATES)) {
 		u32 rates = bss_conf->basic_rates;
-		struct conf_tx_rate_class mgmt_rc;
 
 		wl->basic_rate_set = wl1271_tx_enabled_rates_get(wl, rates);
 		wl->basic_rate = wl1271_tx_min_rate_get(wl);
-		wl1271_debug(DEBUG_AP, "basic rates: 0x%x",
-			     wl->basic_rate_set);
 
-		/* update the AP management rate policy with the new rates */
-		mgmt_rc.enabled_rates = wl->basic_rate_set;
-		mgmt_rc.long_retry_limit = 10;
-		mgmt_rc.short_retry_limit = 10;
-		mgmt_rc.aflags = 0;
-		ret = wl1271_acx_ap_rate_policy(wl, &mgmt_rc,
-						ACX_TX_AP_MODE_MGMT_RATE);
+		ret = wl1271_init_ap_rates(wl);
 		if (ret < 0) {
-			wl1271_error("AP mgmt policy change failed %d", ret);
+			wl1271_error("AP rate policy change failed %d", ret);
 			goto out;
 		}
+
+		ret = wl1271_ap_init_templates(wl);
+		if (ret < 0)
+			goto out;
 	}
 
 	ret = wl1271_bss_beacon_info_changed(wl, vif, bss_conf, changed);
@@ -2314,6 +2780,24 @@
 		}
 	}
 
+	if (changed & BSS_CHANGED_IBSS) {
+		wl1271_debug(DEBUG_ADHOC, "ibss_joined: %d",
+			     bss_conf->ibss_joined);
+
+		if (bss_conf->ibss_joined) {
+			u32 rates = bss_conf->basic_rates;
+			wl->basic_rate_set = wl1271_tx_enabled_rates_get(wl,
+									 rates);
+			wl->basic_rate = wl1271_tx_min_rate_get(wl);
+
+			/* by default, use 11b rates */
+			wl->rate_set = CONF_TX_IBSS_DEFAULT_RATES;
+			ret = wl1271_acx_sta_rate_policies(wl);
+			if (ret < 0)
+				goto out;
+		}
+	}
+
 	ret = wl1271_bss_erp_info_changed(wl, bss_conf, changed);
 	if (ret < 0)
 		goto out;
@@ -2503,8 +2987,10 @@
 			}
 		} else {
 			/* use defaults when not associated */
+			bool was_assoc =
+			    !!test_and_clear_bit(WL1271_FLAG_STA_ASSOCIATED,
+						 &wl->flags);
 			clear_bit(WL1271_FLAG_STA_STATE_SENT, &wl->flags);
-			clear_bit(WL1271_FLAG_STA_ASSOCIATED, &wl->flags);
 			wl->aid = 0;
 
 			/* free probe-request template */
@@ -2530,8 +3016,10 @@
 				goto out;
 
 			/* restore the bssid filter and go to dummy bssid */
-			wl1271_unjoin(wl);
-			wl1271_dummy_join(wl);
+			if (was_assoc) {
+				wl1271_unjoin(wl);
+				wl1271_dummy_join(wl);
+			}
 		}
 	}
 
@@ -2650,32 +3138,31 @@
 		conf_tid->ack_policy = CONF_ACK_POLICY_LEGACY;
 		conf_tid->apsd_conf[0] = 0;
 		conf_tid->apsd_conf[1] = 0;
-	} else {
-		ret = wl1271_ps_elp_wakeup(wl);
-		if (ret < 0)
-			goto out;
+		goto out;
+	}
 
-		/*
-		 * the txop is confed in units of 32us by the mac80211,
-		 * we need us
-		 */
-		ret = wl1271_acx_ac_cfg(wl, wl1271_tx_get_queue(queue),
-					params->cw_min, params->cw_max,
-					params->aifs, params->txop << 5);
-		if (ret < 0)
-			goto out_sleep;
+	ret = wl1271_ps_elp_wakeup(wl);
+	if (ret < 0)
+		goto out;
 
-		ret = wl1271_acx_tid_cfg(wl, wl1271_tx_get_queue(queue),
-					 CONF_CHANNEL_TYPE_EDCF,
-					 wl1271_tx_get_queue(queue),
-					 ps_scheme, CONF_ACK_POLICY_LEGACY,
-					 0, 0);
-		if (ret < 0)
-			goto out_sleep;
+	/*
+	 * the txop is confed in units of 32us by the mac80211,
+	 * we need us
+	 */
+	ret = wl1271_acx_ac_cfg(wl, wl1271_tx_get_queue(queue),
+				params->cw_min, params->cw_max,
+				params->aifs, params->txop << 5);
+	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),
+				 ps_scheme, CONF_ACK_POLICY_LEGACY,
+				 0, 0);
 
 out_sleep:
-		wl1271_ps_elp_sleep(wl);
-	}
+	wl1271_ps_elp_sleep(wl);
 
 out:
 	mutex_unlock(&wl->mutex);
@@ -2847,10 +3334,11 @@
 	return ret;
 }
 
-int wl1271_op_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
-			   enum ieee80211_ampdu_mlme_action action,
-			   struct ieee80211_sta *sta, u16 tid, u16 *ssn,
-			   u8 buf_size)
+static int wl1271_op_ampdu_action(struct ieee80211_hw *hw,
+				  struct ieee80211_vif *vif,
+				  enum ieee80211_ampdu_mlme_action action,
+				  struct ieee80211_sta *sta, u16 tid, u16 *ssn,
+				  u8 buf_size)
 {
 	struct wl1271 *wl = hw->priv;
 	int ret;
@@ -2907,6 +3395,28 @@
 	return ret;
 }
 
+static bool wl1271_tx_frames_pending(struct ieee80211_hw *hw)
+{
+	struct wl1271 *wl = hw->priv;
+	bool ret = false;
+
+	mutex_lock(&wl->mutex);
+
+	if (unlikely(wl->state == WL1271_STATE_OFF))
+		goto out;
+
+	/* packets are considered pending if in the TX queue or the FW */
+	ret = (wl->tx_queue_count > 0) || (wl->tx_frames_cnt > 0);
+
+	/* the above is appropriate for STA mode for PS purposes */
+	WARN_ON(wl->bss_type != BSS_TYPE_STA_BSS);
+
+out:
+	mutex_unlock(&wl->mutex);
+
+	return ret;
+}
+
 /* can't be const, mac80211 writes to this */
 static struct ieee80211_rate wl1271_rates[] = {
 	{ .bitrate = 10,
@@ -3003,7 +3513,8 @@
 
 #ifdef CONFIG_WL12XX_HT
 #define WL12XX_HT_CAP { \
-	.cap = IEEE80211_HT_CAP_GRN_FLD | IEEE80211_HT_CAP_SGI_20, \
+	.cap = IEEE80211_HT_CAP_GRN_FLD | IEEE80211_HT_CAP_SGI_20 | \
+	       (1 << IEEE80211_HT_CAP_RX_STBC_SHIFT), \
 	.ht_supported = true, \
 	.ampdu_factor = IEEE80211_HT_MAX_AMPDU_8K, \
 	.ampdu_density = IEEE80211_HT_MPDU_DENSITY_8, \
@@ -3142,12 +3653,18 @@
 	.stop = wl1271_op_stop,
 	.add_interface = wl1271_op_add_interface,
 	.remove_interface = wl1271_op_remove_interface,
+#ifdef CONFIG_PM
+	.suspend = wl1271_op_suspend,
+	.resume = wl1271_op_resume,
+#endif
 	.config = wl1271_op_config,
 	.prepare_multicast = wl1271_op_prepare_multicast,
 	.configure_filter = wl1271_op_configure_filter,
 	.tx = wl1271_op_tx,
 	.set_key = wl1271_op_set_key,
 	.hw_scan = wl1271_op_hw_scan,
+	.sched_scan_start = wl1271_op_sched_scan_start,
+	.sched_scan_stop = wl1271_op_sched_scan_stop,
 	.bss_info_changed = wl1271_op_bss_info_changed,
 	.set_frag_threshold = wl1271_op_set_frag_threshold,
 	.set_rts_threshold = wl1271_op_set_rts_threshold,
@@ -3157,6 +3674,7 @@
 	.sta_add = wl1271_op_sta_add,
 	.sta_remove = wl1271_op_sta_remove,
 	.ampdu_action = wl1271_op_ampdu_action,
+	.tx_frames_pending = wl1271_tx_frames_pending,
 	CFG80211_TESTMODE_CMD(wl1271_tm_cmd)
 };
 
@@ -3207,8 +3725,7 @@
 	unsigned long res;
 	int ret;
 
-	ret = strict_strtoul(buf, 10, &res);
-
+	ret = kstrtoul(buf, 10, &res);
 	if (ret < 0) {
 		wl1271_warning("incorrect value written to bt_coex_mode");
 		return count;
@@ -3273,7 +3790,11 @@
 
 	ret = wl1271_fetch_nvs(wl);
 	if (ret == 0) {
-		u8 *nvs_ptr = (u8 *)wl->nvs->nvs;
+		/* NOTE: The wl->nvs->nvs element must be first, in
+		 * order to simplify the casting, we assume it is at
+		 * the beginning of the wl->nvs structure.
+		 */
+		u8 *nvs_ptr = (u8 *)wl->nvs;
 
 		wl->mac_addr[0] = nvs_ptr[11];
 		wl->mac_addr[1] = nvs_ptr[10];
@@ -3342,6 +3863,7 @@
 		IEEE80211_HW_CONNECTION_MONITOR |
 		IEEE80211_HW_SUPPORTS_CQM_RSSI |
 		IEEE80211_HW_REPORTS_TX_ACK_STATUS |
+		IEEE80211_HW_SPECTRUM_MGMT |
 		IEEE80211_HW_AP_LINK_PS;
 
 	wl->hw->wiphy->cipher_suites = cipher_suites;
@@ -3358,6 +3880,10 @@
 	wl->hw->wiphy->max_scan_ie_len = WL1271_CMD_TEMPL_MAX_SIZE -
 			sizeof(struct ieee80211_header);
 
+	/* make sure all our channels fit in the scanned_ch bitmask */
+	BUILD_BUG_ON(ARRAY_SIZE(wl1271_channels) +
+		     ARRAY_SIZE(wl1271_channels_5ghz) >
+		     WL1271_MAX_CHANNELS);
 	/*
 	 * We keep local copies of the band structs because we need to
 	 * modify them on a per-device basis.
@@ -3458,6 +3984,8 @@
 	wl->ap_ps_map = 0;
 	wl->ap_fw_ps_map = 0;
 	wl->quirks = 0;
+	wl->platform_quirks = 0;
+	wl->sched_scanning = false;
 
 	memset(wl->tx_frames_map, 0, sizeof(wl->tx_frames_map));
 	for (i = 0; i < ACX_TX_DESCRIPTORS; i++)
@@ -3478,11 +4006,17 @@
 		goto err_hw;
 	}
 
+	wl->dummy_packet = wl12xx_alloc_dummy_packet(wl);
+	if (!wl->dummy_packet) {
+		ret = -ENOMEM;
+		goto err_aggr;
+	}
+
 	/* Register platform device */
 	ret = platform_device_register(wl->plat_dev);
 	if (ret) {
 		wl1271_error("couldn't register platform device");
-		goto err_aggr;
+		goto err_dummy_packet;
 	}
 	dev_set_drvdata(&wl->plat_dev->dev, wl);
 
@@ -3508,6 +4042,9 @@
 err_platform:
 	platform_device_unregister(wl->plat_dev);
 
+err_dummy_packet:
+	dev_kfree_skb(wl->dummy_packet);
+
 err_aggr:
 	free_pages((unsigned long)wl->aggr_buf, order);
 
@@ -3527,6 +4064,7 @@
 int wl1271_free_hw(struct wl1271 *wl)
 {
 	platform_device_unregister(wl->plat_dev);
+	dev_kfree_skb(wl->dummy_packet);
 	free_pages((unsigned long)wl->aggr_buf,
 			get_order(WL1271_AGGR_BUFFER_SIZE));
 	kfree(wl->plat_dev);
diff -druN linux-2.6.39-libre/drivers/net/wireless/wl12xx/ps.c linux-3.0-rc7-libre/drivers/net/wireless/wl12xx/ps.c
--- linux-2.6.39-libre/drivers/net/wireless/wl12xx/ps.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/wl12xx/ps.c	2011-07-11 19:51:52.000000000 -0400
@@ -43,6 +43,10 @@
 	if (unlikely(wl->state == WL1271_STATE_OFF))
 		goto out;
 
+	/* our work might have been already cancelled */
+	if (unlikely(!test_bit(WL1271_FLAG_ELP_REQUESTED, &wl->flags)))
+		goto out;
+
 	if (test_bit(WL1271_FLAG_IN_ELP, &wl->flags) ||
 	    (!test_bit(WL1271_FLAG_PSM, &wl->flags) &&
 	     !test_bit(WL1271_FLAG_IDLE, &wl->flags)))
@@ -61,12 +65,16 @@
 /* Routines to toggle sleep mode while in ELP */
 void wl1271_ps_elp_sleep(struct wl1271 *wl)
 {
-	if (test_bit(WL1271_FLAG_PSM, &wl->flags) ||
-	    test_bit(WL1271_FLAG_IDLE, &wl->flags)) {
-		cancel_delayed_work(&wl->elp_work);
-		ieee80211_queue_delayed_work(wl->hw, &wl->elp_work,
-					     msecs_to_jiffies(ELP_ENTRY_DELAY));
-	}
+	/* we shouldn't get consecutive sleep requests */
+	if (WARN_ON(test_and_set_bit(WL1271_FLAG_ELP_REQUESTED, &wl->flags)))
+		return;
+
+	if (!test_bit(WL1271_FLAG_PSM, &wl->flags) &&
+	    !test_bit(WL1271_FLAG_IDLE, &wl->flags))
+		return;
+
+	ieee80211_queue_delayed_work(wl->hw, &wl->elp_work,
+				     msecs_to_jiffies(ELP_ENTRY_DELAY));
 }
 
 int wl1271_ps_elp_wakeup(struct wl1271 *wl)
@@ -77,6 +85,16 @@
 	u32 start_time = jiffies;
 	bool pending = false;
 
+	/*
+	 * we might try to wake up even if we didn't go to sleep
+	 * before (e.g. on boot)
+	 */
+	if (!test_and_clear_bit(WL1271_FLAG_ELP_REQUESTED, &wl->flags))
+		return 0;
+
+	/* don't cancel_sync as it might contend for a mutex and deadlock */
+	cancel_delayed_work(&wl->elp_work);
+
 	if (!test_bit(WL1271_FLAG_IN_ELP, &wl->flags))
 		return 0;
 
@@ -149,9 +167,6 @@
 	case STATION_ACTIVE_MODE:
 	default:
 		wl1271_debug(DEBUG_PSM, "leaving psm");
-		ret = wl1271_ps_elp_wakeup(wl);
-		if (ret < 0)
-			return ret;
 
 		/* disable beacon early termination */
 		ret = wl1271_acx_bet_enable(wl, false);
diff -druN linux-2.6.39-libre/drivers/net/wireless/wl12xx/ps.h linux-3.0-rc7-libre/drivers/net/wireless/wl12xx/ps.h
--- linux-2.6.39-libre/drivers/net/wireless/wl12xx/ps.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/wl12xx/ps.h	2011-07-11 19:51:52.000000000 -0400
@@ -35,4 +35,6 @@
 void wl1271_ps_link_start(struct wl1271 *wl, u8 hlid, bool clean_queues);
 void wl1271_ps_link_end(struct wl1271 *wl, u8 hlid);
 
+#define WL1271_PS_COMPLETE_TIMEOUT 500
+
 #endif /* __WL1271_PS_H__ */
diff -druN linux-2.6.39-libre/drivers/net/wireless/wl12xx/reg.h linux-3.0-rc7-libre/drivers/net/wireless/wl12xx/reg.h
--- linux-2.6.39-libre/drivers/net/wireless/wl12xx/reg.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/wl12xx/reg.h	2011-07-11 19:51:52.000000000 -0400
@@ -207,6 +207,8 @@
 
 #define CHIP_ID_1271_PG10              (0x4030101)
 #define CHIP_ID_1271_PG20              (0x4030111)
+#define CHIP_ID_1283_PG10              (0x05030101)
+#define CHIP_ID_1283_PG20              (0x05030111)
 
 #define ENABLE                         (REGISTERS_BASE + 0x5450)
 
@@ -452,24 +454,11 @@
 #define HI_CFG_UART_TX_OUT_GPIO_14  0x00000200
 #define HI_CFG_UART_TX_OUT_GPIO_7   0x00000400
 
-/*
- * NOTE: USE_ACTIVE_HIGH compilation flag should be defined in makefile
- *       for platforms using active high interrupt level
- */
-#ifdef USE_ACTIVE_HIGH
 #define HI_CFG_DEF_VAL              \
 	(HI_CFG_UART_ENABLE |        \
 	HI_CFG_RST232_ENABLE |      \
 	HI_CFG_CLOCK_REQ_SELECT |   \
 	HI_CFG_HOST_INT_ENABLE)
-#else
-#define HI_CFG_DEF_VAL              \
-	(HI_CFG_UART_ENABLE |        \
-	HI_CFG_RST232_ENABLE |      \
-	HI_CFG_CLOCK_REQ_SELECT |   \
-	HI_CFG_HOST_INT_ENABLE)
-
-#endif
 
 #define REF_FREQ_19_2                       0
 #define REF_FREQ_26_0                       1
diff -druN linux-2.6.39-libre/drivers/net/wireless/wl12xx/rx.c linux-3.0-rc7-libre/drivers/net/wireless/wl12xx/rx.c
--- linux-2.6.39-libre/drivers/net/wireless/wl12xx/rx.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/wl12xx/rx.c	2011-07-11 19:51:52.000000000 -0400
@@ -48,18 +48,14 @@
 			     struct ieee80211_rx_status *status,
 			     u8 beacon)
 {
-	enum ieee80211_band desc_band;
-
 	memset(status, 0, sizeof(struct ieee80211_rx_status));
 
-	status->band = wl->band;
-
 	if ((desc->flags & WL1271_RX_DESC_BAND_MASK) == WL1271_RX_DESC_BAND_BG)
-		desc_band = IEEE80211_BAND_2GHZ;
+		status->band = IEEE80211_BAND_2GHZ;
 	else
-		desc_band = IEEE80211_BAND_5GHZ;
+		status->band = IEEE80211_BAND_5GHZ;
 
-	status->rate_idx = wl1271_rate_to_idx(desc->rate, desc_band);
+	status->rate_idx = wl1271_rate_to_idx(desc->rate, status->band);
 
 #ifdef CONFIG_WL12XX_HT
 	/* 11n support */
@@ -76,15 +72,19 @@
 	 */
 	wl->noise = desc->rssi - (desc->snr >> 1);
 
-	status->freq = ieee80211_channel_to_frequency(desc->channel, desc_band);
+	status->freq = ieee80211_channel_to_frequency(desc->channel,
+						      status->band);
 
 	if (desc->flags & WL1271_RX_DESC_ENCRYPT_MASK) {
-		status->flag |= RX_FLAG_IV_STRIPPED | RX_FLAG_MMIC_STRIPPED;
+		u8 desc_err_code = desc->status & WL1271_RX_DESC_STATUS_MASK;
 
-		if (likely(!(desc->status & WL1271_RX_DESC_DECRYPT_FAIL)))
-			status->flag |= RX_FLAG_DECRYPTED;
-		if (unlikely(desc->status & WL1271_RX_DESC_MIC_FAIL))
+		status->flag |= RX_FLAG_IV_STRIPPED | RX_FLAG_MMIC_STRIPPED |
+				RX_FLAG_DECRYPTED;
+
+		if (unlikely(desc_err_code == WL1271_RX_DESC_MIC_FAIL)) {
 			status->flag |= RX_FLAG_MMIC_ERROR;
+			wl1271_warning("Michael MIC error");
+		}
 	}
 }
 
@@ -103,6 +103,25 @@
 	if (unlikely(wl->state == WL1271_STATE_PLT))
 		return -EINVAL;
 
+	/* the data read starts with the descriptor */
+	desc = (struct wl1271_rx_descriptor *) data;
+
+	switch (desc->status & WL1271_RX_DESC_STATUS_MASK) {
+	/* discard corrupted packets */
+	case WL1271_RX_DESC_DRIVER_RX_Q_FAIL:
+	case WL1271_RX_DESC_DECRYPT_FAIL:
+		wl1271_warning("corrupted packet in RX with status: 0x%x",
+			       desc->status & WL1271_RX_DESC_STATUS_MASK);
+		return -EINVAL;
+	case WL1271_RX_DESC_SUCCESS:
+	case WL1271_RX_DESC_MIC_FAIL:
+		break;
+	default:
+		wl1271_error("invalid RX descriptor status: 0x%x",
+			     desc->status & WL1271_RX_DESC_STATUS_MASK);
+		return -EINVAL;
+	}
+
 	skb = __dev_alloc_skb(length, GFP_KERNEL);
 	if (!skb) {
 		wl1271_error("Couldn't allocate RX frame");
@@ -112,9 +131,6 @@
 	buf = skb_put(skb, length);
 	memcpy(buf, data, length);
 
-	/* the data read starts with the descriptor */
-	desc = (struct wl1271_rx_descriptor *) buf;
-
 	/* now we pull the descriptor out of the buffer */
 	skb_pull(skb, sizeof(*desc));
 
@@ -124,7 +140,8 @@
 
 	wl1271_rx_status(wl, desc, IEEE80211_SKB_RXCB(skb), beacon);
 
-	wl1271_debug(DEBUG_RX, "rx skb 0x%p: %d B %s", skb, skb->len,
+	wl1271_debug(DEBUG_RX, "rx skb 0x%p: %d B %s", skb,
+		     skb->len - desc->pad_len,
 		     beacon ? "beacon" : "");
 
 	skb_trim(skb, skb->len - desc->pad_len);
@@ -163,18 +180,25 @@
 			break;
 		}
 
-		/*
-		 * Choose the block we want to read
-		 * For aggregated packets, only the first memory block should
-		 * be retrieved. The FW takes care of the rest.
-		 */
-		mem_block = wl1271_rx_get_mem_block(status, drv_rx_counter);
-		wl->rx_mem_pool_addr.addr = (mem_block << 8) +
-			le32_to_cpu(wl_mem_map->packet_memory_pool_start);
-		wl->rx_mem_pool_addr.addr_extra =
-			wl->rx_mem_pool_addr.addr + 4;
-		wl1271_write(wl, WL1271_SLV_REG_DATA, &wl->rx_mem_pool_addr,
-				sizeof(wl->rx_mem_pool_addr), false);
+		if (wl->chip.id != CHIP_ID_1283_PG20) {
+			/*
+			 * Choose the block we want to read
+			 * For aggregated packets, only the first memory block
+			 * should be retrieved. The FW takes care of the rest.
+			 */
+			mem_block = wl1271_rx_get_mem_block(status,
+							    drv_rx_counter);
+
+			wl->rx_mem_pool_addr.addr = (mem_block << 8) +
+			   le32_to_cpu(wl_mem_map->packet_memory_pool_start);
+
+			wl->rx_mem_pool_addr.addr_extra =
+				wl->rx_mem_pool_addr.addr + 4;
+
+			wl1271_write(wl, WL1271_SLV_REG_DATA,
+				     &wl->rx_mem_pool_addr,
+				     sizeof(wl->rx_mem_pool_addr), false);
+		}
 
 		/* Read all available packets at once */
 		wl1271_read(wl, WL1271_SLV_MEM_DATA, wl->aggr_buf,
diff -druN linux-2.6.39-libre/drivers/net/wireless/wl12xx/scan.c linux-3.0-rc7-libre/drivers/net/wireless/wl12xx/scan.c
--- linux-2.6.39-libre/drivers/net/wireless/wl12xx/scan.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/wl12xx/scan.c	2011-07-11 19:51:52.000000000 -0400
@@ -48,8 +48,7 @@
 		goto out;
 
 	wl->scan.state = WL1271_SCAN_STATE_IDLE;
-	kfree(wl->scan.scanned_ch);
-	wl->scan.scanned_ch = NULL;
+	memset(wl->scan.scanned_ch, 0, sizeof(wl->scan.scanned_ch));
 	wl->scan.req = NULL;
 	ieee80211_scan_completed(wl->hw, false);
 
@@ -87,7 +86,7 @@
 
 		flags = req->channels[i]->flags;
 
-		if (!wl->scan.scanned_ch[i] &&
+		if (!test_bit(i, wl->scan.scanned_ch) &&
 		    !(flags & IEEE80211_CHAN_DISABLED) &&
 		    ((!!(flags & IEEE80211_CHAN_PASSIVE_SCAN)) == passive) &&
 		    (req->channels[i]->band == band)) {
@@ -124,7 +123,7 @@
 			memset(&channels[j].bssid_msb, 0xff, 2);
 
 			/* Mark the channels we already used */
-			wl->scan.scanned_ch[i] = true;
+			set_bit(i, wl->scan.scanned_ch);
 
 			j++;
 		}
@@ -291,6 +290,12 @@
 int wl1271_scan(struct wl1271 *wl, const u8 *ssid, size_t ssid_len,
 		struct cfg80211_scan_request *req)
 {
+	/*
+	 * cfg80211 should guarantee that we don't get more channels
+	 * than what we have registered.
+	 */
+	BUG_ON(req->n_channels > WL1271_MAX_CHANNELS);
+
 	if (wl->scan.state != WL1271_SCAN_STATE_IDLE)
 		return -EBUSY;
 
@@ -304,10 +309,8 @@
 	}
 
 	wl->scan.req = req;
+	memset(wl->scan.scanned_ch, 0, sizeof(wl->scan.scanned_ch));
 
-	wl->scan.scanned_ch = kcalloc(req->n_channels,
-				      sizeof(*wl->scan.scanned_ch),
-				      GFP_KERNEL);
 	/* we assume failure so that timeout scenarios are handled correctly */
 	wl->scan.failed = true;
 	ieee80211_queue_delayed_work(wl->hw, &wl->scan_complete_work,
@@ -317,3 +320,263 @@
 
 	return 0;
 }
+
+static int
+wl1271_scan_get_sched_scan_channels(struct wl1271 *wl,
+				    struct cfg80211_sched_scan_request *req,
+				    struct conn_scan_ch_params *channels,
+				    u32 band, bool radar, bool passive,
+				    int start)
+{
+	struct conf_sched_scan_settings *c = &wl->conf.sched_scan;
+	int i, j;
+	u32 flags;
+	bool force_passive = !req->n_ssids;
+
+	for (i = 0, j = start;
+	     i < req->n_channels && j < MAX_CHANNELS_ALL_BANDS;
+	     i++) {
+		flags = req->channels[i]->flags;
+
+		if (force_passive)
+			flags |= IEEE80211_CHAN_PASSIVE_SCAN;
+
+		if ((req->channels[i]->band == band) &&
+		    !(flags & IEEE80211_CHAN_DISABLED) &&
+		    (!!(flags & IEEE80211_CHAN_RADAR) == radar) &&
+		    /* if radar is set, we ignore the passive flag */
+		    (radar ||
+		     !!(flags & IEEE80211_CHAN_PASSIVE_SCAN) == passive)) {
+			wl1271_debug(DEBUG_SCAN, "band %d, center_freq %d ",
+				     req->channels[i]->band,
+				     req->channels[i]->center_freq);
+			wl1271_debug(DEBUG_SCAN, "hw_value %d, flags %X",
+				     req->channels[i]->hw_value,
+				     req->channels[i]->flags);
+			wl1271_debug(DEBUG_SCAN, "max_power %d",
+				     req->channels[i]->max_power);
+
+			if (flags & IEEE80211_CHAN_RADAR) {
+				channels[j].flags |= SCAN_CHANNEL_FLAGS_DFS;
+				channels[j].passive_duration =
+					cpu_to_le16(c->dwell_time_dfs);
+			}
+			else if (flags & IEEE80211_CHAN_PASSIVE_SCAN) {
+				channels[j].passive_duration =
+					cpu_to_le16(c->dwell_time_passive);
+			} else {
+				channels[j].min_duration =
+					cpu_to_le16(c->min_dwell_time_active);
+				channels[j].max_duration =
+					cpu_to_le16(c->max_dwell_time_active);
+			}
+			channels[j].tx_power_att = req->channels[i]->max_power;
+			channels[j].channel = req->channels[i]->hw_value;
+
+			j++;
+		}
+	}
+
+	return j - start;
+}
+
+static int
+wl1271_scan_sched_scan_channels(struct wl1271 *wl,
+				struct cfg80211_sched_scan_request *req,
+				struct wl1271_cmd_sched_scan_config *cfg)
+{
+	int idx = 0;
+
+	cfg->passive[0] =
+		wl1271_scan_get_sched_scan_channels(wl, req, cfg->channels,
+						    IEEE80211_BAND_2GHZ,
+						    false, true, idx);
+	idx += cfg->passive[0];
+
+	cfg->active[0] =
+		wl1271_scan_get_sched_scan_channels(wl, req, cfg->channels,
+						    IEEE80211_BAND_2GHZ,
+						    false, false, idx);
+	/*
+	 * 5GHz channels always start at position 14, not immediately
+	 * after the last 2.4GHz channel
+	 */
+	idx = 14;
+
+	cfg->passive[1] =
+		wl1271_scan_get_sched_scan_channels(wl, req, cfg->channels,
+						    IEEE80211_BAND_5GHZ,
+						    false, true, idx);
+	idx += cfg->passive[1];
+
+	cfg->dfs =
+		wl1271_scan_get_sched_scan_channels(wl, req, cfg->channels,
+						    IEEE80211_BAND_5GHZ,
+						    true, true, idx);
+	idx += cfg->dfs;
+
+	cfg->active[1] =
+		wl1271_scan_get_sched_scan_channels(wl, req, cfg->channels,
+						    IEEE80211_BAND_5GHZ,
+						    false, false, idx);
+	idx += cfg->active[1];
+
+	wl1271_debug(DEBUG_SCAN, "    2.4GHz: active %d passive %d",
+		     cfg->active[0], cfg->passive[0]);
+	wl1271_debug(DEBUG_SCAN, "    5GHz: active %d passive %d",
+		     cfg->active[1], cfg->passive[1]);
+	wl1271_debug(DEBUG_SCAN, "    DFS: %d", cfg->dfs);
+
+	return idx;
+}
+
+int wl1271_scan_sched_scan_config(struct wl1271 *wl,
+				  struct cfg80211_sched_scan_request *req,
+				  struct ieee80211_sched_scan_ies *ies)
+{
+	struct wl1271_cmd_sched_scan_config *cfg = NULL;
+	struct conf_sched_scan_settings *c = &wl->conf.sched_scan;
+	int i, total_channels, ret;
+	bool force_passive = !req->n_ssids;
+
+	wl1271_debug(DEBUG_CMD, "cmd sched_scan scan config");
+
+	cfg = kzalloc(sizeof(*cfg), GFP_KERNEL);
+	if (!cfg)
+		return -ENOMEM;
+
+	cfg->rssi_threshold = c->rssi_threshold;
+	cfg->snr_threshold  = c->snr_threshold;
+	cfg->n_probe_reqs = c->num_probe_reqs;
+	/* cycles set to 0 it means infinite (until manually stopped) */
+	cfg->cycles = 0;
+	/* report APs when at least 1 is found */
+	cfg->report_after = 1;
+	/* don't stop scanning automatically when something is found */
+	cfg->terminate = 0;
+	cfg->tag = WL1271_SCAN_DEFAULT_TAG;
+	/* don't filter on BSS type */
+	cfg->bss_type = SCAN_BSS_TYPE_ANY;
+	/* currently NL80211 supports only a single interval */
+	for (i = 0; i < SCAN_MAX_CYCLE_INTERVALS; i++)
+		cfg->intervals[i] = cpu_to_le32(req->interval);
+
+	if (!force_passive && req->ssids[0].ssid_len && req->ssids[0].ssid) {
+		cfg->filter_type = SCAN_SSID_FILTER_SPECIFIC;
+		cfg->ssid_len = req->ssids[0].ssid_len;
+		memcpy(cfg->ssid, req->ssids[0].ssid,
+		       req->ssids[0].ssid_len);
+	} else {
+		cfg->filter_type = SCAN_SSID_FILTER_ANY;
+		cfg->ssid_len = 0;
+	}
+
+	total_channels = wl1271_scan_sched_scan_channels(wl, req, cfg);
+	if (total_channels == 0) {
+		wl1271_error("scan channel list is empty");
+		ret = -EINVAL;
+		goto out;
+	}
+
+	if (!force_passive && cfg->active[0]) {
+		ret = wl1271_cmd_build_probe_req(wl, req->ssids[0].ssid,
+						 req->ssids[0].ssid_len,
+						 ies->ie[IEEE80211_BAND_2GHZ],
+						 ies->len[IEEE80211_BAND_2GHZ],
+						 IEEE80211_BAND_2GHZ);
+		if (ret < 0) {
+			wl1271_error("2.4GHz PROBE request template failed");
+			goto out;
+		}
+	}
+
+	if (!force_passive && cfg->active[1]) {
+		ret = wl1271_cmd_build_probe_req(wl,  req->ssids[0].ssid,
+						 req->ssids[0].ssid_len,
+						 ies->ie[IEEE80211_BAND_5GHZ],
+						 ies->len[IEEE80211_BAND_5GHZ],
+						 IEEE80211_BAND_5GHZ);
+		if (ret < 0) {
+			wl1271_error("5GHz PROBE request template failed");
+			goto out;
+		}
+	}
+
+	wl1271_dump(DEBUG_SCAN, "SCAN_CFG: ", cfg, sizeof(*cfg));
+
+	ret = wl1271_cmd_send(wl, CMD_CONNECTION_SCAN_CFG, cfg,
+			      sizeof(*cfg), 0);
+	if (ret < 0) {
+		wl1271_error("SCAN configuration failed");
+		goto out;
+	}
+out:
+	kfree(cfg);
+	return ret;
+}
+
+int wl1271_scan_sched_scan_start(struct wl1271 *wl)
+{
+	struct wl1271_cmd_sched_scan_start *start;
+	int ret = 0;
+
+	wl1271_debug(DEBUG_CMD, "cmd periodic scan start");
+
+	if (wl->bss_type != BSS_TYPE_STA_BSS)
+		return -EOPNOTSUPP;
+
+	if (!test_bit(WL1271_FLAG_IDLE, &wl->flags))
+		return -EBUSY;
+
+	start = kzalloc(sizeof(*start), GFP_KERNEL);
+	if (!start)
+		return -ENOMEM;
+
+	start->tag = WL1271_SCAN_DEFAULT_TAG;
+
+	ret = wl1271_cmd_send(wl, CMD_START_PERIODIC_SCAN, start,
+			      sizeof(*start), 0);
+	if (ret < 0) {
+		wl1271_error("failed to send scan start command");
+		goto out_free;
+	}
+
+out_free:
+	kfree(start);
+	return ret;
+}
+
+void wl1271_scan_sched_scan_results(struct wl1271 *wl)
+{
+	wl1271_debug(DEBUG_SCAN, "got periodic scan results");
+
+	ieee80211_sched_scan_results(wl->hw);
+}
+
+void wl1271_scan_sched_scan_stop(struct wl1271 *wl)
+{
+	struct wl1271_cmd_sched_scan_stop *stop;
+	int ret = 0;
+
+	wl1271_debug(DEBUG_CMD, "cmd periodic scan stop");
+
+	/* FIXME: what to do if alloc'ing to stop fails? */
+	stop = kzalloc(sizeof(*stop), GFP_KERNEL);
+	if (!stop) {
+		wl1271_error("failed to alloc memory to send sched scan stop");
+		return;
+	}
+
+	stop->tag = WL1271_SCAN_DEFAULT_TAG;
+
+	ret = wl1271_cmd_send(wl, CMD_STOP_PERIODIC_SCAN, stop,
+			      sizeof(*stop), 0);
+	if (ret < 0) {
+		wl1271_error("failed to send sched scan stop command");
+		goto out_free;
+	}
+	wl->sched_scanning = false;
+
+out_free:
+	kfree(stop);
+}
diff -druN linux-2.6.39-libre/drivers/net/wireless/wl12xx/scan.h linux-3.0-rc7-libre/drivers/net/wireless/wl12xx/scan.h
--- linux-2.6.39-libre/drivers/net/wireless/wl12xx/scan.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/wl12xx/scan.h	2011-07-11 19:51:52.000000000 -0400
@@ -33,6 +33,12 @@
 				const u8 *ie, size_t ie_len, u8 band);
 void wl1271_scan_stm(struct wl1271 *wl);
 void wl1271_scan_complete_work(struct work_struct *work);
+int wl1271_scan_sched_scan_config(struct wl1271 *wl,
+				     struct cfg80211_sched_scan_request *req,
+				     struct ieee80211_sched_scan_ies *ies);
+int wl1271_scan_sched_scan_start(struct wl1271 *wl);
+void wl1271_scan_sched_scan_stop(struct wl1271 *wl);
+void wl1271_scan_sched_scan_results(struct wl1271 *wl);
 
 #define WL1271_SCAN_MAX_CHANNELS       24
 #define WL1271_SCAN_DEFAULT_TAG        1
@@ -106,4 +112,115 @@
 	__le32 timeout;
 } __packed;
 
+#define MAX_CHANNELS_ALL_BANDS 41
+#define SCAN_MAX_CYCLE_INTERVALS 16
+#define SCAN_MAX_BANDS 3
+
+enum {
+	SCAN_CHANNEL_TYPE_2GHZ_PASSIVE,
+	SCAN_CHANNEL_TYPE_2GHZ_ACTIVE,
+	SCAN_CHANNEL_TYPE_5GHZ_PASSIVE,
+	SCAN_CHANNEL_TYPE_5GHZ_ACTIVE,
+	SCAN_CHANNEL_TYPE_5GHZ_DFS,
+};
+
+enum {
+	SCAN_SSID_FILTER_ANY      = 0,
+	SCAN_SSID_FILTER_SPECIFIC = 1,
+	SCAN_SSID_FILTER_LIST     = 2,
+	SCAN_SSID_FILTER_DISABLED = 3
+};
+
+enum {
+	SCAN_BSS_TYPE_INDEPENDENT,
+	SCAN_BSS_TYPE_INFRASTRUCTURE,
+	SCAN_BSS_TYPE_ANY,
+};
+
+#define SCAN_CHANNEL_FLAGS_DFS		BIT(0)
+#define SCAN_CHANNEL_FLAGS_DFS_ENABLED	BIT(1)
+
+struct conn_scan_ch_params {
+	__le16 min_duration;
+	__le16 max_duration;
+	__le16 passive_duration;
+
+	u8  channel;
+	u8  tx_power_att;
+
+	/* bit 0: DFS channel; bit 1: DFS enabled */
+	u8  flags;
+
+	u8  padding[3];
+} __packed;
+
+struct wl1271_cmd_sched_scan_config {
+	struct wl1271_cmd_header header;
+
+	__le32 intervals[SCAN_MAX_CYCLE_INTERVALS];
+
+	s8 rssi_threshold; /* for filtering (in dBm) */
+	s8 snr_threshold;  /* for filtering (in dB) */
+
+	u8 cycles;       /* maximum number of scan cycles */
+	u8 report_after; /* report when this number of results are received */
+	u8 terminate;    /* stop scanning after reporting */
+
+	u8 tag;
+	u8 bss_type; /* for filtering */
+	u8 filter_type;
+
+	u8 ssid_len;     /* For SCAN_SSID_FILTER_SPECIFIC */
+	u8 ssid[IW_ESSID_MAX_SIZE];
+
+	u8 n_probe_reqs; /* Number of probes requests per channel */
+
+	u8 passive[SCAN_MAX_BANDS];
+	u8 active[SCAN_MAX_BANDS];
+
+	u8 dfs;
+
+	u8 padding[3];
+
+	struct conn_scan_ch_params channels[MAX_CHANNELS_ALL_BANDS];
+} __packed;
+
+
+#define SCHED_SCAN_MAX_SSIDS 8
+
+enum {
+	SCAN_SSID_TYPE_PUBLIC = 0,
+	SCAN_SSID_TYPE_HIDDEN = 1,
+};
+
+struct wl1271_ssid {
+	u8 type;
+	u8 len;
+	u8 ssid[IW_ESSID_MAX_SIZE];
+	/* u8 padding[2]; */
+} __packed;
+
+struct wl1271_cmd_sched_scan_ssid_list {
+	struct wl1271_cmd_header header;
+
+	u8 n_ssids;
+	struct wl1271_ssid ssids[SCHED_SCAN_MAX_SSIDS];
+	u8 padding[3];
+} __packed;
+
+struct wl1271_cmd_sched_scan_start {
+	struct wl1271_cmd_header header;
+
+	u8 tag;
+	u8 padding[3];
+} __packed;
+
+struct wl1271_cmd_sched_scan_stop {
+	struct wl1271_cmd_header header;
+
+	u8 tag;
+	u8 padding[3];
+} __packed;
+
+
 #endif /* __WL1271_SCAN_H__ */
diff -druN linux-2.6.39-libre/drivers/net/wireless/wl12xx/sdio.c linux-3.0-rc7-libre/drivers/net/wireless/wl12xx/sdio.c
--- linux-2.6.39-libre/drivers/net/wireless/wl12xx/sdio.c	2011-05-19 02:16:19.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/wl12xx/sdio.c	2011-07-21 06:58:24.000000000 -0400
@@ -51,6 +51,13 @@
 };
 MODULE_DEVICE_TABLE(sdio, wl1271_devices);
 
+static void wl1271_sdio_set_block_size(struct wl1271 *wl, unsigned int blksz)
+{
+	sdio_claim_host(wl->if_priv);
+	sdio_set_block_size(wl->if_priv, blksz);
+	sdio_release_host(wl->if_priv);
+}
+
 static inline struct sdio_func *wl_to_func(struct wl1271 *wl)
 {
 	return wl->if_priv;
@@ -75,6 +82,16 @@
 		complete(wl->elp_compl);
 		wl->elp_compl = NULL;
 	}
+
+	if (test_bit(WL1271_FLAG_SUSPENDED, &wl->flags)) {
+		/* don't enqueue a work right now. mark it as pending */
+		set_bit(WL1271_FLAG_PENDING_WORK, &wl->flags);
+		wl1271_debug(DEBUG_IRQ, "should not enqueue work");
+		disable_irq_nosync(wl->irq);
+		pm_wakeup_event(wl1271_sdio_wl_to_dev(wl), 0);
+		spin_unlock_irqrestore(&wl->wl_lock, flags);
+		return IRQ_HANDLED;
+	}
 	spin_unlock_irqrestore(&wl->wl_lock, flags);
 
 	return IRQ_WAKE_THREAD;
@@ -203,7 +220,8 @@
 	.power		= wl1271_sdio_set_power,
 	.dev		= wl1271_sdio_wl_to_dev,
 	.enable_irq	= wl1271_sdio_enable_interrupts,
-	.disable_irq	= wl1271_sdio_disable_interrupts
+	.disable_irq	= wl1271_sdio_disable_interrupts,
+	.set_block_size = wl1271_sdio_set_block_size,
 };
 
 static int __devinit wl1271_probe(struct sdio_func *func,
@@ -212,6 +230,8 @@
 	struct ieee80211_hw *hw;
 	const struct wl12xx_platform_data *wlan_data;
 	struct wl1271 *wl;
+	unsigned long irqflags;
+	mmc_pm_flag_t mmcflags;
 	int ret;
 
 	/* We are only able to handle the wlan function */
@@ -230,6 +250,9 @@
 	/* Grab access to FN0 for ELP reg. */
 	func->card->quirks |= MMC_QUIRK_LENIENT_FN0;
 
+	/* Use block mode for transferring over one block size of data */
+	func->card->quirks |= MMC_QUIRK_BLKSZ_FOR_BYTE_MODE;
+
 	wlan_data = wl12xx_get_platform_data();
 	if (IS_ERR(wlan_data)) {
 		ret = PTR_ERR(wlan_data);
@@ -239,17 +262,34 @@
 
 	wl->irq = wlan_data->irq;
 	wl->ref_clock = wlan_data->board_ref_clock;
+	wl->tcxo_clock = wlan_data->board_tcxo_clock;
+	wl->platform_quirks = wlan_data->platform_quirks;
+
+	if (wl->platform_quirks & WL12XX_PLATFORM_QUIRK_EDGE_IRQ)
+		irqflags = IRQF_TRIGGER_RISING;
+	else
+		irqflags = IRQF_TRIGGER_HIGH | IRQF_ONESHOT;
 
 	ret = request_threaded_irq(wl->irq, wl1271_hardirq, wl1271_irq,
-				   IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
+				   irqflags,
 				   DRIVER_NAME, wl);
 	if (ret < 0) {
 		wl1271_error("request_irq() failed: %d", ret);
 		goto out_free;
 	}
 
+	enable_irq_wake(wl->irq);
+	device_init_wakeup(wl1271_sdio_wl_to_dev(wl), 1);
+
 	disable_irq(wl->irq);
 
+	/* if sdio can keep power while host is suspended, enable wow */
+	mmcflags = sdio_get_host_pm_caps(func);
+	wl1271_debug(DEBUG_SDIO, "sdio PM caps = 0x%x", mmcflags);
+
+	if (mmcflags & MMC_PM_KEEP_POWER)
+		hw->wiphy->wowlan.flags = WIPHY_WOWLAN_ANY;
+
 	ret = wl1271_init_ieee80211(wl);
 	if (ret)
 		goto out_irq;
@@ -284,19 +324,61 @@
 	pm_runtime_get_noresume(&func->dev);
 
 	wl1271_unregister_hw(wl);
+	device_init_wakeup(wl1271_sdio_wl_to_dev(wl), 0);
+	disable_irq_wake(wl->irq);
 	free_irq(wl->irq, wl);
 	wl1271_free_hw(wl);
 }
 
+#ifdef CONFIG_PM
 static int wl1271_suspend(struct device *dev)
 {
 	/* Tell MMC/SDIO core it's OK to power down the card
 	 * (if it isn't already), but not to remove it completely */
-	return 0;
+	struct sdio_func *func = dev_to_sdio_func(dev);
+	struct wl1271 *wl = sdio_get_drvdata(func);
+	mmc_pm_flag_t sdio_flags;
+	int ret = 0;
+
+	wl1271_debug(DEBUG_MAC80211, "wl1271 suspend. wow_enabled: %d",
+		     wl->wow_enabled);
+
+	/* check whether sdio should keep power */
+	if (wl->wow_enabled) {
+		sdio_flags = sdio_get_host_pm_caps(func);
+
+		if (!(sdio_flags & MMC_PM_KEEP_POWER)) {
+			wl1271_error("can't keep power while host "
+				     "is suspended");
+			ret = -EINVAL;
+			goto out;
+		}
+
+		/* keep power while host suspended */
+		ret = sdio_set_host_pm_flags(func, MMC_PM_KEEP_POWER);
+		if (ret) {
+			wl1271_error("error while trying to keep power");
+			goto out;
+		}
+
+		/* release host */
+		sdio_release_host(func);
+	}
+out:
+	return ret;
 }
 
 static int wl1271_resume(struct device *dev)
 {
+	struct sdio_func *func = dev_to_sdio_func(dev);
+	struct wl1271 *wl = sdio_get_drvdata(func);
+
+	wl1271_debug(DEBUG_MAC80211, "wl1271 resume");
+	if (wl->wow_enabled) {
+		/* claim back host */
+		sdio_claim_host(func);
+	}
+
 	return 0;
 }
 
@@ -304,15 +386,18 @@
 	.suspend	= wl1271_suspend,
 	.resume		= wl1271_resume,
 };
+#endif
 
 static struct sdio_driver wl1271_sdio_driver = {
 	.name		= "wl1271_sdio",
 	.id_table	= wl1271_devices,
 	.probe		= wl1271_probe,
 	.remove		= __devexit_p(wl1271_remove),
+#ifdef CONFIG_PM
 	.drv = {
 		.pm = &wl1271_sdio_pm_ops,
 	},
+#endif
 };
 
 static int __init wl1271_init(void)
diff -druN linux-2.6.39-libre/drivers/net/wireless/wl12xx/sdio_test.c linux-3.0-rc7-libre/drivers/net/wireless/wl12xx/sdio_test.c
--- linux-2.6.39-libre/drivers/net/wireless/wl12xx/sdio_test.c	2011-05-19 02:16:19.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/wl12xx/sdio_test.c	2011-07-21 06:58:24.000000000 -0400
@@ -189,7 +189,12 @@
 	const struct firmware *fw;
 	int ret;
 
-	ret = reject_firmware(&fw, WL1271_FW_NAME, wl1271_wl_to_dev(wl));
+	if (wl->chip.id == CHIP_ID_1283_PG20)
+		ret = reject_firmware(&fw, WL128X_FW_NAME,
+				       wl1271_wl_to_dev(wl));
+	else
+		ret = reject_firmware(&fw, WL1271_FW_NAME,
+				       wl1271_wl_to_dev(wl));
 
 	if (ret < 0) {
 		wl1271_error("could not get firmware: %d", ret);
@@ -227,14 +232,14 @@
 	const struct firmware *fw;
 	int ret;
 
-	ret = reject_firmware(&fw, WL1271_NVS_NAME, wl1271_wl_to_dev(wl));
+	ret = reject_firmware(&fw, WL12XX_NVS_NAME, wl1271_wl_to_dev(wl));
 
 	if (ret < 0) {
 		wl1271_error("could not get nvs file: %d", ret);
 		return ret;
 	}
 
-	wl->nvs = kmemdup(fw->data, sizeof(struct wl1271_nvs_file), GFP_KERNEL);
+	wl->nvs = kmemdup(fw->data, fw->size, GFP_KERNEL);
 
 	if (!wl->nvs) {
 		wl1271_error("could not allocate memory for the nvs file");
@@ -288,6 +293,11 @@
 		wl1271_notice("chip id 0x%x (1271 PG20)",
 				wl->chip.id);
 		break;
+	case CHIP_ID_1283_PG20:
+		wl1271_notice("chip id 0x%x (1283 PG20)",
+				wl->chip.id);
+		break;
+	case CHIP_ID_1283_PG10:
 	default:
 		wl1271_warning("unsupported chip id: 0x%x", wl->chip.id);
 		return -ENODEV;
@@ -407,6 +417,9 @@
 	/* Grab access to FN0 for ELP reg. */
 	func->card->quirks |= MMC_QUIRK_LENIENT_FN0;
 
+	/* Use block mode for transferring over one block size of data */
+	func->card->quirks |= MMC_QUIRK_BLKSZ_FOR_BYTE_MODE;
+
 	wlan_data = wl12xx_get_platform_data();
 	if (IS_ERR(wlan_data)) {
 		ret = PTR_ERR(wlan_data);
@@ -416,6 +429,7 @@
 
 	wl->irq = wlan_data->irq;
 	wl->ref_clock = wlan_data->board_ref_clock;
+	wl->tcxo_clock = wlan_data->board_tcxo_clock;
 
 	sdio_set_drvdata(func, wl_test);
 
diff -druN linux-2.6.39-libre/drivers/net/wireless/wl12xx/spi.c linux-3.0-rc7-libre/drivers/net/wireless/wl12xx/spi.c
--- linux-2.6.39-libre/drivers/net/wireless/wl12xx/spi.c	2011-05-19 02:16:21.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/wl12xx/spi.c	2011-07-21 06:58:26.000000000 -0400
@@ -355,7 +355,8 @@
 	.power		= wl1271_spi_set_power,
 	.dev		= wl1271_spi_wl_to_dev,
 	.enable_irq	= wl1271_spi_enable_interrupts,
-	.disable_irq	= wl1271_spi_disable_interrupts
+	.disable_irq	= wl1271_spi_disable_interrupts,
+	.set_block_size = NULL,
 };
 
 static int __devinit wl1271_probe(struct spi_device *spi)
@@ -363,6 +364,7 @@
 	struct wl12xx_platform_data *pdata;
 	struct ieee80211_hw *hw;
 	struct wl1271 *wl;
+	unsigned long irqflags;
 	int ret;
 
 	pdata = spi->dev.platform_data;
@@ -400,6 +402,13 @@
 	}
 
 	wl->ref_clock = pdata->board_ref_clock;
+	wl->tcxo_clock = pdata->board_tcxo_clock;
+	wl->platform_quirks = pdata->platform_quirks;
+
+	if (wl->platform_quirks & WL12XX_PLATFORM_QUIRK_EDGE_IRQ)
+		irqflags = IRQF_TRIGGER_RISING;
+	else
+		irqflags = IRQF_TRIGGER_HIGH | IRQF_ONESHOT;
 
 	wl->irq = spi->irq;
 	if (wl->irq < 0) {
@@ -409,7 +418,7 @@
 	}
 
 	ret = request_threaded_irq(wl->irq, wl1271_hardirq, wl1271_irq,
-				   IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
+				   irqflags,
 				   DRIVER_NAME, wl);
 	if (ret < 0) {
 		wl1271_error("request_irq() failed: %d", ret);
diff -druN linux-2.6.39-libre/drivers/net/wireless/wl12xx/testmode.c linux-3.0-rc7-libre/drivers/net/wireless/wl12xx/testmode.c
--- linux-2.6.39-libre/drivers/net/wireless/wl12xx/testmode.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/wl12xx/testmode.c	2011-07-11 19:51:52.000000000 -0400
@@ -27,6 +27,7 @@
 
 #include "wl12xx.h"
 #include "acx.h"
+#include "reg.h"
 
 #define WL1271_TM_MAX_DATA_LENGTH 1024
 
@@ -204,7 +205,10 @@
 
 	kfree(wl->nvs);
 
-	if (len != sizeof(struct wl1271_nvs_file))
+	if ((wl->chip.id == CHIP_ID_1283_PG20) &&
+	    (len != sizeof(struct wl128x_nvs_file)))
+		return -EINVAL;
+	else if (len != sizeof(struct wl1271_nvs_file))
 		return -EINVAL;
 
 	wl->nvs = kzalloc(len, GFP_KERNEL);
diff -druN linux-2.6.39-libre/drivers/net/wireless/wl12xx/tx.c linux-3.0-rc7-libre/drivers/net/wireless/wl12xx/tx.c
--- linux-2.6.39-libre/drivers/net/wireless/wl12xx/tx.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/wl12xx/tx.c	2011-07-11 19:51:52.000000000 -0400
@@ -65,11 +65,36 @@
 static void wl1271_free_tx_id(struct wl1271 *wl, int id)
 {
 	if (__test_and_clear_bit(id, wl->tx_frames_map)) {
+		if (unlikely(wl->tx_frames_cnt == ACX_TX_DESCRIPTORS))
+			clear_bit(WL1271_FLAG_FW_TX_BUSY, &wl->flags);
+
 		wl->tx_frames[id] = NULL;
 		wl->tx_frames_cnt--;
 	}
 }
 
+static int wl1271_tx_update_filters(struct wl1271 *wl,
+						 struct sk_buff *skb)
+{
+	struct ieee80211_hdr *hdr;
+
+	hdr = (struct ieee80211_hdr *)(skb->data +
+				       sizeof(struct wl1271_tx_hw_descr));
+
+	/*
+	 * stop bssid-based filtering before transmitting authentication
+	 * requests. this way the hw will never drop authentication
+	 * responses coming from BSSIDs it isn't familiar with (e.g. on
+	 * roaming)
+	 */
+	if (!ieee80211_is_auth(hdr->frame_control))
+		return 0;
+
+	wl1271_configure_filters(wl, FIF_OTHER_BSS);
+
+	return wl1271_acx_rx_config(wl, wl->rx_config, wl->rx_filter);
+}
+
 static void wl1271_tx_ap_update_inconnection_sta(struct wl1271 *wl,
 						 struct sk_buff *skb)
 {
@@ -127,13 +152,29 @@
 	}
 }
 
+static unsigned int wl12xx_calc_packet_alignment(struct wl1271 *wl,
+						unsigned int packet_length)
+{
+	if (wl->quirks & WL12XX_QUIRK_BLOCKSIZE_ALIGNMENT)
+		return ALIGN(packet_length, WL12XX_BUS_BLOCK_SIZE);
+	else
+		return ALIGN(packet_length, WL1271_TX_ALIGN_TO);
+}
+
 static int wl1271_tx_allocate(struct wl1271 *wl, struct sk_buff *skb, u32 extra,
 				u32 buf_offset, u8 hlid)
 {
 	struct wl1271_tx_hw_descr *desc;
 	u32 total_len = skb->len + sizeof(struct wl1271_tx_hw_descr) + extra;
+	u32 len;
 	u32 total_blocks;
 	int id, ret = -EBUSY;
+	u32 spare_blocks;
+
+	if (unlikely(wl->quirks & WL12XX_QUIRK_USE_2_SPARE_BLOCKS))
+		spare_blocks = 2;
+	else
+		spare_blocks = 1;
 
 	if (buf_offset + total_len > WL1271_AGGR_BUFFER_SIZE)
 		return -EAGAIN;
@@ -145,17 +186,27 @@
 
 	/* approximate the number of blocks required for this packet
 	   in the firmware */
-	total_blocks = total_len + TX_HW_BLOCK_SIZE - 1;
-	total_blocks = total_blocks / TX_HW_BLOCK_SIZE + TX_HW_BLOCK_SPARE;
+	len = wl12xx_calc_packet_alignment(wl, total_len);
+
+	total_blocks = (len + TX_HW_BLOCK_SIZE - 1) / TX_HW_BLOCK_SIZE +
+		spare_blocks;
+
 	if (total_blocks <= wl->tx_blocks_available) {
 		desc = (struct wl1271_tx_hw_descr *)skb_push(
 			skb, total_len - skb->len);
 
-		desc->extra_mem_blocks = TX_HW_BLOCK_SPARE;
-		desc->total_mem_blocks = total_blocks;
+		/* HW descriptor fields change between wl127x and wl128x */
+		if (wl->chip.id == CHIP_ID_1283_PG20) {
+			desc->wl128x_mem.total_mem_blocks = total_blocks;
+		} else {
+			desc->wl127x_mem.extra_blocks = spare_blocks;
+			desc->wl127x_mem.total_mem_blocks = total_blocks;
+		}
+
 		desc->id = id;
 
 		wl->tx_blocks_available -= total_blocks;
+		wl->tx_allocated_blocks += total_blocks;
 
 		if (wl->bss_type == BSS_TYPE_AP_BSS)
 			wl->links[hlid].allocated_blks += total_blocks;
@@ -172,13 +223,18 @@
 	return ret;
 }
 
+static bool wl12xx_is_dummy_packet(struct wl1271 *wl, struct sk_buff *skb)
+{
+	return wl->dummy_packet == skb;
+}
+
 static void wl1271_tx_fill_hdr(struct wl1271 *wl, struct sk_buff *skb,
 			      u32 extra, struct ieee80211_tx_info *control,
 			      u8 hlid)
 {
 	struct timespec ts;
 	struct wl1271_tx_hw_descr *desc;
-	int pad, ac, rate_idx;
+	int aligned_len, ac, rate_idx;
 	s64 hosttime;
 	u16 tx_attr;
 
@@ -202,12 +258,25 @@
 	else
 		desc->life_time = cpu_to_le16(TX_HW_AP_MODE_PKT_LIFETIME_TU);
 
-	/* configure the tx attributes */
-	tx_attr = wl->session_counter << TX_HW_ATTR_OFST_SESSION_COUNTER;
-
-	/* queue (we use same identifiers for tid's and ac's */
+	/* queue */
 	ac = wl1271_tx_get_queue(skb_get_queue_mapping(skb));
-	desc->tid = ac;
+	desc->tid = skb->priority;
+
+	if (wl12xx_is_dummy_packet(wl, skb)) {
+		/*
+		 * FW expects the dummy packet to have an invalid session id -
+		 * any session id that is different than the one set in the join
+		 */
+		tx_attr = ((~wl->session_counter) <<
+			   TX_HW_ATTR_OFST_SESSION_COUNTER) &
+			   TX_HW_ATTR_SESSION_COUNTER;
+
+		tx_attr |= TX_HW_ATTR_TX_DUMMY_REQ;
+	} else {
+		/* configure the tx attributes */
+		tx_attr =
+			wl->session_counter << TX_HW_ATTR_OFST_SESSION_COUNTER;
+	}
 
 	if (wl->bss_type != BSS_TYPE_AP_BSS) {
 		desc->aid = hlid;
@@ -237,20 +306,37 @@
 	tx_attr |= rate_idx << TX_HW_ATTR_OFST_RATE_POLICY;
 	desc->reserved = 0;
 
-	/* align the length (and store in terms of words) */
-	pad = ALIGN(skb->len, WL1271_TX_ALIGN_TO);
-	desc->length = cpu_to_le16(pad >> 2);
+	aligned_len = wl12xx_calc_packet_alignment(wl, skb->len);
 
-	/* calculate number of padding bytes */
-	pad = pad - skb->len;
-	tx_attr |= pad << TX_HW_ATTR_OFST_LAST_WORD_PAD;
+	if (wl->chip.id == CHIP_ID_1283_PG20) {
+		desc->wl128x_mem.extra_bytes = aligned_len - skb->len;
+		desc->length = cpu_to_le16(aligned_len >> 2);
 
-	desc->tx_attr = cpu_to_le16(tx_attr);
+		wl1271_debug(DEBUG_TX, "tx_fill_hdr: hlid: %d "
+			     "tx_attr: 0x%x len: %d life: %d mem: %d",
+			     desc->hlid, tx_attr,
+			     le16_to_cpu(desc->length),
+			     le16_to_cpu(desc->life_time),
+			     desc->wl128x_mem.total_mem_blocks);
+	} else {
+		int pad;
 
-	wl1271_debug(DEBUG_TX, "tx_fill_hdr: pad: %d hlid: %d "
-		"tx_attr: 0x%x len: %d life: %d mem: %d", pad, desc->hlid,
-		le16_to_cpu(desc->tx_attr), le16_to_cpu(desc->length),
-		le16_to_cpu(desc->life_time), desc->total_mem_blocks);
+		/* Store the aligned length in terms of words */
+		desc->length = cpu_to_le16(aligned_len >> 2);
+
+		/* calculate number of padding bytes */
+		pad = aligned_len - skb->len;
+		tx_attr |= pad << TX_HW_ATTR_OFST_LAST_WORD_PAD;
+
+		wl1271_debug(DEBUG_TX, "tx_fill_hdr: pad: %d hlid: %d "
+			     "tx_attr: 0x%x len: %d life: %d mem: %d", pad,
+			     desc->hlid, tx_attr,
+			     le16_to_cpu(desc->length),
+			     le16_to_cpu(desc->life_time),
+			     desc->wl127x_mem.total_mem_blocks);
+	}
+
+	desc->tx_attr = cpu_to_le16(tx_attr);
 }
 
 /* caller must hold wl->mutex */
@@ -300,19 +386,29 @@
 	if (wl->bss_type == BSS_TYPE_AP_BSS) {
 		wl1271_tx_ap_update_inconnection_sta(wl, skb);
 		wl1271_tx_regulate_link(wl, hlid);
+	} else {
+		wl1271_tx_update_filters(wl, skb);
 	}
 
 	wl1271_tx_fill_hdr(wl, skb, extra, info, hlid);
 
 	/*
-	 * The length of each packet is stored in terms of words. Thus, we must
-	 * pad the skb data to make sure its length is aligned.
-	 * The number of padding bytes is computed and set in wl1271_tx_fill_hdr
+	 * The length of each packet is stored in terms of
+	 * words. Thus, we must pad the skb data to make sure its
+	 * length is aligned.  The number of padding bytes is computed
+	 * and set in wl1271_tx_fill_hdr.
+	 * In special cases, we want to align to a specific block size
+	 * (eg. for wl128x with SDIO we align to 256).
 	 */
-	total_len = ALIGN(skb->len, WL1271_TX_ALIGN_TO);
+	total_len = wl12xx_calc_packet_alignment(wl, skb->len);
+
 	memcpy(wl->aggr_buf + buf_offset, skb->data, skb->len);
 	memset(wl->aggr_buf + buf_offset + skb->len, 0, total_len - skb->len);
 
+	/* Revert side effects in the dummy packet skb, so it can be reused */
+	if (wl12xx_is_dummy_packet(wl, skb))
+		skb_pull(skb, sizeof(struct wl1271_tx_hw_descr));
+
 	return total_len;
 }
 
@@ -425,10 +521,23 @@
 
 static struct sk_buff *wl1271_skb_dequeue(struct wl1271 *wl)
 {
+	unsigned long flags;
+	struct sk_buff *skb = NULL;
+
 	if (wl->bss_type == BSS_TYPE_AP_BSS)
-		return wl1271_ap_skb_dequeue(wl);
+		skb = wl1271_ap_skb_dequeue(wl);
+	else
+		skb = wl1271_sta_skb_dequeue(wl);
 
-	return wl1271_sta_skb_dequeue(wl);
+	if (!skb &&
+	    test_and_clear_bit(WL1271_FLAG_DUMMY_PACKET_PENDING, &wl->flags)) {
+		skb = wl->dummy_packet;
+		spin_lock_irqsave(&wl->wl_lock, flags);
+		wl->tx_queue_count--;
+		spin_unlock_irqrestore(&wl->wl_lock, flags);
+	}
+
+	return skb;
 }
 
 static void wl1271_skb_queue_head(struct wl1271 *wl, struct sk_buff *skb)
@@ -436,7 +545,9 @@
 	unsigned long flags;
 	int q = wl1271_tx_get_queue(skb_get_queue_mapping(skb));
 
-	if (wl->bss_type == BSS_TYPE_AP_BSS) {
+	if (wl12xx_is_dummy_packet(wl, skb)) {
+		set_bit(WL1271_FLAG_DUMMY_PACKET_PENDING, &wl->flags);
+	} else if (wl->bss_type == BSS_TYPE_AP_BSS) {
 		u8 hlid = wl1271_tx_get_hlid(skb);
 		skb_queue_head(&wl->links[hlid].tx_queue[q], skb);
 
@@ -454,22 +565,14 @@
 void wl1271_tx_work_locked(struct wl1271 *wl)
 {
 	struct sk_buff *skb;
-	bool woken_up = false;
 	u32 buf_offset = 0;
 	bool sent_packets = false;
 	int ret;
 
 	if (unlikely(wl->state == WL1271_STATE_OFF))
-		goto out;
+		return;
 
 	while ((skb = wl1271_skb_dequeue(wl))) {
-		if (!woken_up) {
-			ret = wl1271_ps_elp_wakeup(wl);
-			if (ret < 0)
-				goto out_ack;
-			woken_up = true;
-		}
-
 		ret = wl1271_prepare_tx_frame(wl, skb, buf_offset);
 		if (ret == -EAGAIN) {
 			/*
@@ -516,18 +619,22 @@
 
 		wl1271_handle_tx_low_watermark(wl);
 	}
-
-out:
-	if (woken_up)
-		wl1271_ps_elp_sleep(wl);
 }
 
 void wl1271_tx_work(struct work_struct *work)
 {
 	struct wl1271 *wl = container_of(work, struct wl1271, tx_work);
+	int ret;
 
 	mutex_lock(&wl->mutex);
+	ret = wl1271_ps_elp_wakeup(wl);
+	if (ret < 0)
+		goto out;
+
 	wl1271_tx_work_locked(wl);
+
+	wl1271_ps_elp_sleep(wl);
+out:
 	mutex_unlock(&wl->mutex);
 }
 
@@ -549,6 +656,11 @@
 	skb = wl->tx_frames[id];
 	info = IEEE80211_SKB_CB(skb);
 
+	if (wl12xx_is_dummy_packet(wl, skb)) {
+		wl1271_free_tx_id(wl, id);
+		return;
+	}
+
 	/* update the TX status info */
 	if (result->status == TX_SUCCESS) {
 		if (!(info->flags & IEEE80211_TX_CTL_NO_ACK))
@@ -657,8 +769,8 @@
 	wl1271_handle_tx_low_watermark(wl);
 }
 
-/* caller must hold wl->mutex */
-void wl1271_tx_reset(struct wl1271 *wl)
+/* caller must hold wl->mutex and TX must be stopped */
+void wl1271_tx_reset(struct wl1271 *wl, bool reset_tx_queues)
 {
 	int i;
 	struct sk_buff *skb;
@@ -678,10 +790,13 @@
 			while ((skb = skb_dequeue(&wl->tx_queue[i]))) {
 				wl1271_debug(DEBUG_TX, "freeing skb 0x%p",
 					     skb);
-				info = IEEE80211_SKB_CB(skb);
-				info->status.rates[0].idx = -1;
-				info->status.rates[0].count = 0;
-				ieee80211_tx_status(wl->hw, skb);
+
+				if (!wl12xx_is_dummy_packet(wl, skb)) {
+					info = IEEE80211_SKB_CB(skb);
+					info->status.rates[0].idx = -1;
+					info->status.rates[0].count = 0;
+					ieee80211_tx_status(wl->hw, skb);
+				}
 			}
 		}
 	}
@@ -691,8 +806,10 @@
 	/*
 	 * Make sure the driver is at a consistent state, in case this
 	 * function is called from a context other than interface removal.
+	 * This call will always wake the TX queues.
 	 */
-	wl1271_handle_tx_low_watermark(wl);
+	if (reset_tx_queues)
+		wl1271_handle_tx_low_watermark(wl);
 
 	for (i = 0; i < ACX_TX_DESCRIPTORS; i++) {
 		if (wl->tx_frames[i] == NULL)
@@ -702,21 +819,27 @@
 		wl1271_free_tx_id(wl, i);
 		wl1271_debug(DEBUG_TX, "freeing skb 0x%p", skb);
 
-		/* Remove private headers before passing the skb to mac80211 */
-		info = IEEE80211_SKB_CB(skb);
-		skb_pull(skb, sizeof(struct wl1271_tx_hw_descr));
-		if (info->control.hw_key &&
-		    info->control.hw_key->cipher == WLAN_CIPHER_SUITE_TKIP) {
-			int hdrlen = ieee80211_get_hdrlen_from_skb(skb);
-			memmove(skb->data + WL1271_TKIP_IV_SPACE, skb->data,
-				hdrlen);
-			skb_pull(skb, WL1271_TKIP_IV_SPACE);
-		}
+		if (!wl12xx_is_dummy_packet(wl, skb)) {
+			/*
+			 * Remove private headers before passing the skb to
+			 * mac80211
+			 */
+			info = IEEE80211_SKB_CB(skb);
+			skb_pull(skb, sizeof(struct wl1271_tx_hw_descr));
+			if (info->control.hw_key &&
+			    info->control.hw_key->cipher ==
+			    WLAN_CIPHER_SUITE_TKIP) {
+				int hdrlen = ieee80211_get_hdrlen_from_skb(skb);
+				memmove(skb->data + WL1271_TKIP_IV_SPACE,
+					skb->data, hdrlen);
+				skb_pull(skb, WL1271_TKIP_IV_SPACE);
+			}
 
-		info->status.rates[0].idx = -1;
-		info->status.rates[0].count = 0;
+			info->status.rates[0].idx = -1;
+			info->status.rates[0].count = 0;
 
-		ieee80211_tx_status(wl->hw, skb);
+			ieee80211_tx_status(wl->hw, skb);
+		}
 	}
 }
 
diff -druN linux-2.6.39-libre/drivers/net/wireless/wl12xx/tx.h linux-3.0-rc7-libre/drivers/net/wireless/wl12xx/tx.h
--- linux-2.6.39-libre/drivers/net/wireless/wl12xx/tx.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/wl12xx/tx.h	2011-07-11 19:51:52.000000000 -0400
@@ -25,7 +25,6 @@
 #ifndef __TX_H__
 #define __TX_H__
 
-#define TX_HW_BLOCK_SPARE                2
 #define TX_HW_BLOCK_SIZE                 252
 
 #define TX_HW_MGMT_PKT_LIFETIME_TU       2000
@@ -41,6 +40,7 @@
 					  BIT(8) | BIT(9))
 #define TX_HW_ATTR_LAST_WORD_PAD         (BIT(10) | BIT(11))
 #define TX_HW_ATTR_TX_CMPLT_REQ          BIT(12)
+#define TX_HW_ATTR_TX_DUMMY_REQ          BIT(13)
 
 #define TX_HW_ATTR_OFST_SAVE_RETRIES     0
 #define TX_HW_ATTR_OFST_HEADER_PAD       1
@@ -55,20 +55,60 @@
 #define WL1271_TX_ALIGN_TO 4
 #define WL1271_TKIP_IV_SPACE 4
 
+/* Used for management frames and dummy packets */
+#define WL1271_TID_MGMT 7
+
+struct wl127x_tx_mem {
+	/*
+	 * Number of extra memory blocks to allocate for this packet
+	 * in addition to the number of blocks derived from the packet
+	 * length.
+	 */
+	u8 extra_blocks;
+	/*
+	 * Total number of memory blocks allocated by the host for
+	 * this packet. Must be equal or greater than the actual
+	 * blocks number allocated by HW.
+	 */
+	u8 total_mem_blocks;
+} __packed;
+
+struct wl128x_tx_mem {
+	/*
+	 * Total number of memory blocks allocated by the host for
+	 * this packet.
+	 */
+	u8 total_mem_blocks;
+	/*
+	 * Number of extra bytes, at the end of the frame. the host
+	 * uses this padding to complete each frame to integer number
+	 * of SDIO blocks.
+	 */
+	u8 extra_bytes;
+} __packed;
+
+/*
+ * On wl128x based devices, when TX packets are aggregated, each packet
+ * size must be aligned to the SDIO block size. The maximum block size
+ * is bounded by the type of the padded bytes field that is sent to the
+ * FW. Currently the type is u8, so the maximum block size is 256 bytes.
+ */
+#define WL12XX_BUS_BLOCK_SIZE min(512u,	\
+	    (1u << (8 * sizeof(((struct wl128x_tx_mem *) 0)->extra_bytes))))
+
 struct wl1271_tx_hw_descr {
 	/* Length of packet in words, including descriptor+header+data */
 	__le16 length;
-	/* Number of extra memory blocks to allocate for this packet in
-	   addition to the number of blocks derived from the packet length */
-	u8 extra_mem_blocks;
-	/* Total number of memory blocks allocated by the host for this packet.
-	   Must be equal or greater than the actual blocks number allocated by
-	   HW!! */
-	u8 total_mem_blocks;
+	union {
+		struct wl127x_tx_mem wl127x_mem;
+		struct wl128x_tx_mem wl128x_mem;
+	} __packed;
 	/* Device time (in us) when the packet arrived to the driver */
 	__le32 start_time;
-	/* Max delay in TUs until transmission. The last device time the
-	   packet can be transmitted is: startTime+(1024*LifeTime) */
+	/*
+	 * Max delay in TUs until transmission. The last device time the
+	 * packet can be transmitted is: start_time + (1024 * life_time)
+	 */
 	__le16 life_time;
 	/* Bitwise fields - see TX_ATTR... definitions above. */
 	__le16 tx_attr;
@@ -145,7 +185,7 @@
 void wl1271_tx_work(struct work_struct *work);
 void wl1271_tx_work_locked(struct wl1271 *wl);
 void wl1271_tx_complete(struct wl1271 *wl);
-void wl1271_tx_reset(struct wl1271 *wl);
+void wl1271_tx_reset(struct wl1271 *wl, bool reset_tx_queues);
 void wl1271_tx_flush(struct wl1271 *wl);
 u8 wl1271_rate_to_idx(int rate, enum ieee80211_band band);
 u32 wl1271_tx_enabled_rates_get(struct wl1271 *wl, u32 rate_set);
diff -druN linux-2.6.39-libre/drivers/net/wireless/wl12xx/wl12xx.h linux-3.0-rc7-libre/drivers/net/wireless/wl12xx/wl12xx.h
--- linux-2.6.39-libre/drivers/net/wireless/wl12xx/wl12xx.h	2011-05-19 02:16:17.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/wl12xx/wl12xx.h	2011-07-21 06:58:23.000000000 -0400
@@ -131,9 +131,16 @@
 
 
 #define WL1271_FW_NAME "/*(DEBLOBBED)*/"
-#define WL1271_AP_FW_NAME "/*(DEBLOBBED)*/"
+#define WL128X_FW_NAME "/*(DEBLOBBED)*/"
+#define WL127X_AP_FW_NAME "/*(DEBLOBBED)*/"
+#define WL128X_AP_FW_NAME "/*(DEBLOBBED)*/"
 
-#define WL1271_NVS_NAME "/*(DEBLOBBED)*/"
+/*
+ * wl127x and wl128x are using the same NVS file name. However, the
+ * ini parameters between them are different.  The driver validates
+ * the correct NVS size in wl1271_boot_upload_nvs().
+ */
+#define WL12XX_NVS_NAME "/*(DEBLOBBED)*/"
 
 #define WL1271_TX_SECURITY_LO16(s) ((u16)((s) & 0xffff))
 #define WL1271_TX_SECURITY_HI32(s) ((u32)(((s) >> 16) & 0xffffffff))
@@ -200,13 +207,29 @@
 
 struct wl1271;
 
-#define WL12XX_NUM_FW_VER 5
+enum {
+	FW_VER_CHIP,
+	FW_VER_IF_TYPE,
+	FW_VER_MAJOR,
+	FW_VER_SUBTYPE,
+	FW_VER_MINOR,
+
+	NUM_FW_VER
+};
+
+#define FW_VER_CHIP_WL127X 6
+#define FW_VER_CHIP_WL128X 7
+
+#define FW_VER_IF_TYPE_STA 1
+#define FW_VER_IF_TYPE_AP  2
+
+#define FW_VER_MINOR_1_SPARE_STA_MIN 58
+#define FW_VER_MINOR_1_SPARE_AP_MIN  47
 
-/* FIXME: I'm not sure about this structure name */
 struct wl1271_chip {
 	u32 id;
 	char fw_ver_str[ETHTOOL_BUSINFO_LEN];
-	unsigned int fw_ver[WL12XX_NUM_FW_VER];
+	unsigned int fw_ver[NUM_FW_VER];
 };
 
 struct wl1271_stats {
@@ -261,6 +284,8 @@
 	u8  tx_total;
 	u8  reserved1;
 	__le16 reserved2;
+	/* Total structure size is 68 bytes */
+	u32 padding;
 } __packed;
 
 struct wl1271_fw_full_status {
@@ -277,9 +302,10 @@
 	u32 addr_extra;
 };
 
+#define WL1271_MAX_CHANNELS 64
 struct wl1271_scan {
 	struct cfg80211_scan_request *req;
-	bool *scanned_ch;
+	unsigned long scanned_ch[BITS_TO_LONGS(WL1271_MAX_CHANNELS)];
 	bool failed;
 	u8 state;
 	u8 ssid[IW_ESSID_MAX_SIZE+1];
@@ -297,6 +323,7 @@
 	struct device* (*dev)(struct wl1271 *wl);
 	void (*enable_irq)(struct wl1271 *wl);
 	void (*disable_irq)(struct wl1271 *wl);
+	void (*set_block_size) (struct wl1271 *wl, unsigned int blksz);
 };
 
 #define MAX_NUM_KEYS 14
@@ -319,15 +346,19 @@
 	WL1271_FLAG_TX_QUEUE_STOPPED,
 	WL1271_FLAG_TX_PENDING,
 	WL1271_FLAG_IN_ELP,
+	WL1271_FLAG_ELP_REQUESTED,
 	WL1271_FLAG_PSM,
 	WL1271_FLAG_PSM_REQUESTED,
 	WL1271_FLAG_IRQ_RUNNING,
 	WL1271_FLAG_IDLE,
-	WL1271_FLAG_IDLE_REQUESTED,
 	WL1271_FLAG_PSPOLL_FAILURE,
 	WL1271_FLAG_STA_STATE_SENT,
 	WL1271_FLAG_FW_TX_BUSY,
-	WL1271_FLAG_AP_STARTED
+	WL1271_FLAG_AP_STARTED,
+	WL1271_FLAG_IF_INITIALIZED,
+	WL1271_FLAG_DUMMY_PACKET_PENDING,
+	WL1271_FLAG_SUSPENDED,
+	WL1271_FLAG_PENDING_WORK,
 };
 
 struct wl1271_link {
@@ -371,7 +402,7 @@
 	u8 *fw;
 	size_t fw_len;
 	u8 fw_bss_type;
-	struct wl1271_nvs_file *nvs;
+	void *nvs;
 	size_t nvs_len;
 
 	s8 hw_pg_ver;
@@ -389,6 +420,7 @@
 	/* Accounting for allocated / available TX blocks on HW */
 	u32 tx_blocks_freed[NUM_TX_QUEUES];
 	u32 tx_blocks_available;
+	u32 tx_allocated_blocks;
 	u32 tx_results_count;
 
 	/* Transmitted TX packets counter for chipset interface */
@@ -430,6 +462,9 @@
 	/* Intermediate buffer, used for packet aggregation */
 	u8 *aggr_buf;
 
+	/* Reusable dummy packet template */
+	struct sk_buff *dummy_packet;
+
 	/* Network stack work  */
 	struct work_struct netstack_work;
 
@@ -446,6 +481,8 @@
 	struct wl1271_scan scan;
 	struct delayed_work scan_complete_work;
 
+	bool sched_scanning;
+
 	/* probe-req template for the current AP */
 	struct sk_buff *probereq;
 
@@ -476,6 +513,7 @@
 	unsigned int rx_filter;
 
 	struct completion *elp_compl;
+	struct completion *ps_compl;
 	struct delayed_work elp_work;
 	struct delayed_work pspoll_work;
 
@@ -527,6 +565,14 @@
 	bool ba_support;
 	u8 ba_rx_bitmap;
 
+	int tcxo_clock;
+
+	/*
+	 * wowlan trigger was configured during suspend.
+	 * (currently, only "ANY" trigger is supported)
+	 */
+	bool wow_enabled;
+
 	/*
 	 * AP-mode - links indexed by HLID. The global and broadcast links
 	 * are always active.
@@ -544,6 +590,9 @@
 
 	/* Quirks of specific hardware revisions */
 	unsigned int quirks;
+
+	/* Platform limitations */
+	unsigned int platform_quirks;
 };
 
 struct wl1271_station {
@@ -576,6 +625,15 @@
 /* Quirks */
 
 /* Each RX/TX transaction requires an end-of-transaction transfer */
-#define WL12XX_QUIRK_END_OF_TRANSACTION	BIT(0)
+#define WL12XX_QUIRK_END_OF_TRANSACTION		BIT(0)
+
+/*
+ * Older firmwares use 2 spare TX blocks
+ * (for STA < 6.1.3.50.58 or for AP < 6.2.0.0.47)
+ */
+#define WL12XX_QUIRK_USE_2_SPARE_BLOCKS		BIT(1)
+
+/* WL128X requires aggregated packets to be aligned to the SDIO block size */
+#define WL12XX_QUIRK_BLOCKSIZE_ALIGNMENT	BIT(2)
 
 #endif
diff -druN linux-2.6.39-libre/drivers/net/wireless/wl3501_cs.c linux-3.0-rc7-libre/drivers/net/wireless/wl3501_cs.c
--- linux-2.6.39-libre/drivers/net/wireless/wl3501_cs.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/wl3501_cs.c	2011-07-11 19:51:52.000000000 -0400
@@ -2000,7 +2000,7 @@
 }
 
 
-static struct pcmcia_device_id wl3501_ids[] = {
+static const struct pcmcia_device_id wl3501_ids[] = {
 	PCMCIA_DEVICE_MANF_CARD(0xd601, 0x0001),
 	PCMCIA_DEVICE_NULL
 };
diff -druN linux-2.6.39-libre/drivers/net/wireless/zd1211rw/zd_chip.c linux-3.0-rc7-libre/drivers/net/wireless/zd1211rw/zd_chip.c
--- linux-2.6.39-libre/drivers/net/wireless/zd1211rw/zd_chip.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/zd1211rw/zd_chip.c	2011-07-11 19:51:52.000000000 -0400
@@ -557,7 +557,7 @@
 	return r;
 }
 
-/* CR157 can be optionally patched by the EEPROM for original ZD1211 */
+/* ZD_CR157 can be optionally patched by the EEPROM for original ZD1211 */
 static int patch_cr157(struct zd_chip *chip)
 {
 	int r;
@@ -571,7 +571,7 @@
 		return r;
 
 	dev_dbg_f(zd_chip_dev(chip), "patching value %x\n", value >> 8);
-	return zd_iowrite32_locked(chip, value >> 8, CR157);
+	return zd_iowrite32_locked(chip, value >> 8, ZD_CR157);
 }
 
 /*
@@ -593,8 +593,8 @@
 int zd_chip_generic_patch_6m_band(struct zd_chip *chip, int channel)
 {
 	struct zd_ioreq16 ioreqs[] = {
-		{ CR128, 0x14 }, { CR129, 0x12 }, { CR130, 0x10 },
-		{ CR47,  0x1e },
+		{ ZD_CR128, 0x14 }, { ZD_CR129, 0x12 }, { ZD_CR130, 0x10 },
+		{ ZD_CR47,  0x1e },
 	};
 
 	/* FIXME: Channel 11 is not the edge for all regulatory domains. */
@@ -608,69 +608,69 @@
 static int zd1211_hw_reset_phy(struct zd_chip *chip)
 {
 	static const struct zd_ioreq16 ioreqs[] = {
-		{ CR0,   0x0a }, { CR1,   0x06 }, { CR2,   0x26 },
-		{ CR3,   0x38 }, { CR4,   0x80 }, { CR9,   0xa0 },
-		{ CR10,  0x81 }, { CR11,  0x00 }, { CR12,  0x7f },
-		{ CR13,  0x8c }, { CR14,  0x80 }, { CR15,  0x3d },
-		{ CR16,  0x20 }, { CR17,  0x1e }, { CR18,  0x0a },
-		{ CR19,  0x48 }, { CR20,  0x0c }, { CR21,  0x0c },
-		{ CR22,  0x23 }, { CR23,  0x90 }, { CR24,  0x14 },
-		{ CR25,  0x40 }, { CR26,  0x10 }, { CR27,  0x19 },
-		{ CR28,  0x7f }, { CR29,  0x80 }, { CR30,  0x4b },
-		{ CR31,  0x60 }, { CR32,  0x43 }, { CR33,  0x08 },
-		{ CR34,  0x06 }, { CR35,  0x0a }, { CR36,  0x00 },
-		{ CR37,  0x00 }, { CR38,  0x38 }, { CR39,  0x0c },
-		{ CR40,  0x84 }, { CR41,  0x2a }, { CR42,  0x80 },
-		{ CR43,  0x10 }, { CR44,  0x12 }, { CR46,  0xff },
-		{ CR47,  0x1E }, { CR48,  0x26 }, { CR49,  0x5b },
-		{ CR64,  0xd0 }, { CR65,  0x04 }, { CR66,  0x58 },
-		{ CR67,  0xc9 }, { CR68,  0x88 }, { CR69,  0x41 },
-		{ CR70,  0x23 }, { CR71,  0x10 }, { CR72,  0xff },
-		{ CR73,  0x32 }, { CR74,  0x30 }, { CR75,  0x65 },
-		{ CR76,  0x41 }, { CR77,  0x1b }, { CR78,  0x30 },
-		{ CR79,  0x68 }, { CR80,  0x64 }, { CR81,  0x64 },
-		{ CR82,  0x00 }, { CR83,  0x00 }, { CR84,  0x00 },
-		{ CR85,  0x02 }, { CR86,  0x00 }, { CR87,  0x00 },
-		{ CR88,  0xff }, { CR89,  0xfc }, { CR90,  0x00 },
-		{ CR91,  0x00 }, { CR92,  0x00 }, { CR93,  0x08 },
-		{ CR94,  0x00 }, { CR95,  0x00 }, { CR96,  0xff },
-		{ CR97,  0xe7 }, { CR98,  0x00 }, { CR99,  0x00 },
-		{ CR100, 0x00 }, { CR101, 0xae }, { CR102, 0x02 },
-		{ CR103, 0x00 }, { CR104, 0x03 }, { CR105, 0x65 },
-		{ CR106, 0x04 }, { CR107, 0x00 }, { CR108, 0x0a },
-		{ CR109, 0xaa }, { CR110, 0xaa }, { CR111, 0x25 },
-		{ CR112, 0x25 }, { CR113, 0x00 }, { CR119, 0x1e },
-		{ CR125, 0x90 }, { CR126, 0x00 }, { CR127, 0x00 },
+		{ ZD_CR0,   0x0a }, { ZD_CR1,   0x06 }, { ZD_CR2,   0x26 },
+		{ ZD_CR3,   0x38 }, { ZD_CR4,   0x80 }, { ZD_CR9,   0xa0 },
+		{ ZD_CR10,  0x81 }, { ZD_CR11,  0x00 }, { ZD_CR12,  0x7f },
+		{ ZD_CR13,  0x8c }, { ZD_CR14,  0x80 }, { ZD_CR15,  0x3d },
+		{ ZD_CR16,  0x20 }, { ZD_CR17,  0x1e }, { ZD_CR18,  0x0a },
+		{ ZD_CR19,  0x48 }, { ZD_CR20,  0x0c }, { ZD_CR21,  0x0c },
+		{ ZD_CR22,  0x23 }, { ZD_CR23,  0x90 }, { ZD_CR24,  0x14 },
+		{ ZD_CR25,  0x40 }, { ZD_CR26,  0x10 }, { ZD_CR27,  0x19 },
+		{ ZD_CR28,  0x7f }, { ZD_CR29,  0x80 }, { ZD_CR30,  0x4b },
+		{ ZD_CR31,  0x60 }, { ZD_CR32,  0x43 }, { ZD_CR33,  0x08 },
+		{ ZD_CR34,  0x06 }, { ZD_CR35,  0x0a }, { ZD_CR36,  0x00 },
+		{ ZD_CR37,  0x00 }, { ZD_CR38,  0x38 }, { ZD_CR39,  0x0c },
+		{ ZD_CR40,  0x84 }, { ZD_CR41,  0x2a }, { ZD_CR42,  0x80 },
+		{ ZD_CR43,  0x10 }, { ZD_CR44,  0x12 }, { ZD_CR46,  0xff },
+		{ ZD_CR47,  0x1E }, { ZD_CR48,  0x26 }, { ZD_CR49,  0x5b },
+		{ ZD_CR64,  0xd0 }, { ZD_CR65,  0x04 }, { ZD_CR66,  0x58 },
+		{ ZD_CR67,  0xc9 }, { ZD_CR68,  0x88 }, { ZD_CR69,  0x41 },
+		{ ZD_CR70,  0x23 }, { ZD_CR71,  0x10 }, { ZD_CR72,  0xff },
+		{ ZD_CR73,  0x32 }, { ZD_CR74,  0x30 }, { ZD_CR75,  0x65 },
+		{ ZD_CR76,  0x41 }, { ZD_CR77,  0x1b }, { ZD_CR78,  0x30 },
+		{ ZD_CR79,  0x68 }, { ZD_CR80,  0x64 }, { ZD_CR81,  0x64 },
+		{ ZD_CR82,  0x00 }, { ZD_CR83,  0x00 }, { ZD_CR84,  0x00 },
+		{ ZD_CR85,  0x02 }, { ZD_CR86,  0x00 }, { ZD_CR87,  0x00 },
+		{ ZD_CR88,  0xff }, { ZD_CR89,  0xfc }, { ZD_CR90,  0x00 },
+		{ ZD_CR91,  0x00 }, { ZD_CR92,  0x00 }, { ZD_CR93,  0x08 },
+		{ ZD_CR94,  0x00 }, { ZD_CR95,  0x00 }, { ZD_CR96,  0xff },
+		{ ZD_CR97,  0xe7 }, { ZD_CR98,  0x00 }, { ZD_CR99,  0x00 },
+		{ ZD_CR100, 0x00 }, { ZD_CR101, 0xae }, { ZD_CR102, 0x02 },
+		{ ZD_CR103, 0x00 }, { ZD_CR104, 0x03 }, { ZD_CR105, 0x65 },
+		{ ZD_CR106, 0x04 }, { ZD_CR107, 0x00 }, { ZD_CR108, 0x0a },
+		{ ZD_CR109, 0xaa }, { ZD_CR110, 0xaa }, { ZD_CR111, 0x25 },
+		{ ZD_CR112, 0x25 }, { ZD_CR113, 0x00 }, { ZD_CR119, 0x1e },
+		{ ZD_CR125, 0x90 }, { ZD_CR126, 0x00 }, { ZD_CR127, 0x00 },
 		{ },
-		{ CR5,   0x00 }, { CR6,   0x00 }, { CR7,   0x00 },
-		{ CR8,   0x00 }, { CR9,   0x20 }, { CR12,  0xf0 },
-		{ CR20,  0x0e }, { CR21,  0x0e }, { CR27,  0x10 },
-		{ CR44,  0x33 }, { CR47,  0x1E }, { CR83,  0x24 },
-		{ CR84,  0x04 }, { CR85,  0x00 }, { CR86,  0x0C },
-		{ CR87,  0x12 }, { CR88,  0x0C }, { CR89,  0x00 },
-		{ CR90,  0x10 }, { CR91,  0x08 }, { CR93,  0x00 },
-		{ CR94,  0x01 }, { CR95,  0x00 }, { CR96,  0x50 },
-		{ CR97,  0x37 }, { CR98,  0x35 }, { CR101, 0x13 },
-		{ CR102, 0x27 }, { CR103, 0x27 }, { CR104, 0x18 },
-		{ CR105, 0x12 }, { CR109, 0x27 }, { CR110, 0x27 },
-		{ CR111, 0x27 }, { CR112, 0x27 }, { CR113, 0x27 },
-		{ CR114, 0x27 }, { CR115, 0x26 }, { CR116, 0x24 },
-		{ CR117, 0xfc }, { CR118, 0xfa }, { CR120, 0x4f },
-		{ CR125, 0xaa }, { CR127, 0x03 }, { CR128, 0x14 },
-		{ CR129, 0x12 }, { CR130, 0x10 }, { CR131, 0x0C },
-		{ CR136, 0xdf }, { CR137, 0x40 }, { CR138, 0xa0 },
-		{ CR139, 0xb0 }, { CR140, 0x99 }, { CR141, 0x82 },
-		{ CR142, 0x54 }, { CR143, 0x1c }, { CR144, 0x6c },
-		{ CR147, 0x07 }, { CR148, 0x4c }, { CR149, 0x50 },
-		{ CR150, 0x0e }, { CR151, 0x18 }, { CR160, 0xfe },
-		{ CR161, 0xee }, { CR162, 0xaa }, { CR163, 0xfa },
-		{ CR164, 0xfa }, { CR165, 0xea }, { CR166, 0xbe },
-		{ CR167, 0xbe }, { CR168, 0x6a }, { CR169, 0xba },
-		{ CR170, 0xba }, { CR171, 0xba },
-		/* Note: CR204 must lead the CR203 */
-		{ CR204, 0x7d },
+		{ ZD_CR5,   0x00 }, { ZD_CR6,   0x00 }, { ZD_CR7,   0x00 },
+		{ ZD_CR8,   0x00 }, { ZD_CR9,   0x20 }, { ZD_CR12,  0xf0 },
+		{ ZD_CR20,  0x0e }, { ZD_CR21,  0x0e }, { ZD_CR27,  0x10 },
+		{ ZD_CR44,  0x33 }, { ZD_CR47,  0x1E }, { ZD_CR83,  0x24 },
+		{ ZD_CR84,  0x04 }, { ZD_CR85,  0x00 }, { ZD_CR86,  0x0C },
+		{ ZD_CR87,  0x12 }, { ZD_CR88,  0x0C }, { ZD_CR89,  0x00 },
+		{ ZD_CR90,  0x10 }, { ZD_CR91,  0x08 }, { ZD_CR93,  0x00 },
+		{ ZD_CR94,  0x01 }, { ZD_CR95,  0x00 }, { ZD_CR96,  0x50 },
+		{ ZD_CR97,  0x37 }, { ZD_CR98,  0x35 }, { ZD_CR101, 0x13 },
+		{ ZD_CR102, 0x27 }, { ZD_CR103, 0x27 }, { ZD_CR104, 0x18 },
+		{ ZD_CR105, 0x12 }, { ZD_CR109, 0x27 }, { ZD_CR110, 0x27 },
+		{ ZD_CR111, 0x27 }, { ZD_CR112, 0x27 }, { ZD_CR113, 0x27 },
+		{ ZD_CR114, 0x27 }, { ZD_CR115, 0x26 }, { ZD_CR116, 0x24 },
+		{ ZD_CR117, 0xfc }, { ZD_CR118, 0xfa }, { ZD_CR120, 0x4f },
+		{ ZD_CR125, 0xaa }, { ZD_CR127, 0x03 }, { ZD_CR128, 0x14 },
+		{ ZD_CR129, 0x12 }, { ZD_CR130, 0x10 }, { ZD_CR131, 0x0C },
+		{ ZD_CR136, 0xdf }, { ZD_CR137, 0x40 }, { ZD_CR138, 0xa0 },
+		{ ZD_CR139, 0xb0 }, { ZD_CR140, 0x99 }, { ZD_CR141, 0x82 },
+		{ ZD_CR142, 0x54 }, { ZD_CR143, 0x1c }, { ZD_CR144, 0x6c },
+		{ ZD_CR147, 0x07 }, { ZD_CR148, 0x4c }, { ZD_CR149, 0x50 },
+		{ ZD_CR150, 0x0e }, { ZD_CR151, 0x18 }, { ZD_CR160, 0xfe },
+		{ ZD_CR161, 0xee }, { ZD_CR162, 0xaa }, { ZD_CR163, 0xfa },
+		{ ZD_CR164, 0xfa }, { ZD_CR165, 0xea }, { ZD_CR166, 0xbe },
+		{ ZD_CR167, 0xbe }, { ZD_CR168, 0x6a }, { ZD_CR169, 0xba },
+		{ ZD_CR170, 0xba }, { ZD_CR171, 0xba },
+		/* Note: ZD_CR204 must lead the ZD_CR203 */
+		{ ZD_CR204, 0x7d },
 		{ },
-		{ CR203, 0x30 },
+		{ ZD_CR203, 0x30 },
 	};
 
 	int r, t;
@@ -697,62 +697,62 @@
 static int zd1211b_hw_reset_phy(struct zd_chip *chip)
 {
 	static const struct zd_ioreq16 ioreqs[] = {
-		{ CR0,   0x14 }, { CR1,   0x06 }, { CR2,   0x26 },
-		{ CR3,   0x38 }, { CR4,   0x80 }, { CR9,   0xe0 },
-		{ CR10,  0x81 },
-		/* power control { { CR11,  1 << 6 }, */
-		{ CR11,  0x00 },
-		{ CR12,  0xf0 }, { CR13,  0x8c }, { CR14,  0x80 },
-		{ CR15,  0x3d }, { CR16,  0x20 }, { CR17,  0x1e },
-		{ CR18,  0x0a }, { CR19,  0x48 },
-		{ CR20,  0x10 }, /* Org:0x0E, ComTrend:RalLink AP */
-		{ CR21,  0x0e }, { CR22,  0x23 }, { CR23,  0x90 },
-		{ CR24,  0x14 }, { CR25,  0x40 }, { CR26,  0x10 },
-		{ CR27,  0x10 }, { CR28,  0x7f }, { CR29,  0x80 },
-		{ CR30,  0x4b }, /* ASIC/FWT, no jointly decoder */
-		{ CR31,  0x60 }, { CR32,  0x43 }, { CR33,  0x08 },
-		{ CR34,  0x06 }, { CR35,  0x0a }, { CR36,  0x00 },
-		{ CR37,  0x00 }, { CR38,  0x38 }, { CR39,  0x0c },
-		{ CR40,  0x84 }, { CR41,  0x2a }, { CR42,  0x80 },
-		{ CR43,  0x10 }, { CR44,  0x33 }, { CR46,  0xff },
-		{ CR47,  0x1E }, { CR48,  0x26 }, { CR49,  0x5b },
-		{ CR64,  0xd0 }, { CR65,  0x04 }, { CR66,  0x58 },
-		{ CR67,  0xc9 }, { CR68,  0x88 }, { CR69,  0x41 },
-		{ CR70,  0x23 }, { CR71,  0x10 }, { CR72,  0xff },
-		{ CR73,  0x32 }, { CR74,  0x30 }, { CR75,  0x65 },
-		{ CR76,  0x41 }, { CR77,  0x1b }, { CR78,  0x30 },
-		{ CR79,  0xf0 }, { CR80,  0x64 }, { CR81,  0x64 },
-		{ CR82,  0x00 }, { CR83,  0x24 }, { CR84,  0x04 },
-		{ CR85,  0x00 }, { CR86,  0x0c }, { CR87,  0x12 },
-		{ CR88,  0x0c }, { CR89,  0x00 }, { CR90,  0x58 },
-		{ CR91,  0x04 }, { CR92,  0x00 }, { CR93,  0x00 },
-		{ CR94,  0x01 },
-		{ CR95,  0x20 }, /* ZD1211B */
-		{ CR96,  0x50 }, { CR97,  0x37 }, { CR98,  0x35 },
-		{ CR99,  0x00 }, { CR100, 0x01 }, { CR101, 0x13 },
-		{ CR102, 0x27 }, { CR103, 0x27 }, { CR104, 0x18 },
-		{ CR105, 0x12 }, { CR106, 0x04 }, { CR107, 0x00 },
-		{ CR108, 0x0a }, { CR109, 0x27 }, { CR110, 0x27 },
-		{ CR111, 0x27 }, { CR112, 0x27 }, { CR113, 0x27 },
-		{ CR114, 0x27 }, { CR115, 0x26 }, { CR116, 0x24 },
-		{ CR117, 0xfc }, { CR118, 0xfa }, { CR119, 0x1e },
-		{ CR125, 0x90 }, { CR126, 0x00 }, { CR127, 0x00 },
-		{ CR128, 0x14 }, { CR129, 0x12 }, { CR130, 0x10 },
-		{ CR131, 0x0c }, { CR136, 0xdf }, { CR137, 0xa0 },
-		{ CR138, 0xa8 }, { CR139, 0xb4 }, { CR140, 0x98 },
-		{ CR141, 0x82 }, { CR142, 0x53 }, { CR143, 0x1c },
-		{ CR144, 0x6c }, { CR147, 0x07 }, { CR148, 0x40 },
-		{ CR149, 0x40 }, /* Org:0x50 ComTrend:RalLink AP */
-		{ CR150, 0x14 }, /* Org:0x0E ComTrend:RalLink AP */
-		{ CR151, 0x18 }, { CR159, 0x70 }, { CR160, 0xfe },
-		{ CR161, 0xee }, { CR162, 0xaa }, { CR163, 0xfa },
-		{ CR164, 0xfa }, { CR165, 0xea }, { CR166, 0xbe },
-		{ CR167, 0xbe }, { CR168, 0x6a }, { CR169, 0xba },
-		{ CR170, 0xba }, { CR171, 0xba },
-		/* Note: CR204 must lead the CR203 */
-		{ CR204, 0x7d },
+		{ ZD_CR0,   0x14 }, { ZD_CR1,   0x06 }, { ZD_CR2,   0x26 },
+		{ ZD_CR3,   0x38 }, { ZD_CR4,   0x80 }, { ZD_CR9,   0xe0 },
+		{ ZD_CR10,  0x81 },
+		/* power control { { ZD_CR11,  1 << 6 }, */
+		{ ZD_CR11,  0x00 },
+		{ ZD_CR12,  0xf0 }, { ZD_CR13,  0x8c }, { ZD_CR14,  0x80 },
+		{ ZD_CR15,  0x3d }, { ZD_CR16,  0x20 }, { ZD_CR17,  0x1e },
+		{ ZD_CR18,  0x0a }, { ZD_CR19,  0x48 },
+		{ ZD_CR20,  0x10 }, /* Org:0x0E, ComTrend:RalLink AP */
+		{ ZD_CR21,  0x0e }, { ZD_CR22,  0x23 }, { ZD_CR23,  0x90 },
+		{ ZD_CR24,  0x14 }, { ZD_CR25,  0x40 }, { ZD_CR26,  0x10 },
+		{ ZD_CR27,  0x10 }, { ZD_CR28,  0x7f }, { ZD_CR29,  0x80 },
+		{ ZD_CR30,  0x4b }, /* ASIC/FWT, no jointly decoder */
+		{ ZD_CR31,  0x60 }, { ZD_CR32,  0x43 }, { ZD_CR33,  0x08 },
+		{ ZD_CR34,  0x06 }, { ZD_CR35,  0x0a }, { ZD_CR36,  0x00 },
+		{ ZD_CR37,  0x00 }, { ZD_CR38,  0x38 }, { ZD_CR39,  0x0c },
+		{ ZD_CR40,  0x84 }, { ZD_CR41,  0x2a }, { ZD_CR42,  0x80 },
+		{ ZD_CR43,  0x10 }, { ZD_CR44,  0x33 }, { ZD_CR46,  0xff },
+		{ ZD_CR47,  0x1E }, { ZD_CR48,  0x26 }, { ZD_CR49,  0x5b },
+		{ ZD_CR64,  0xd0 }, { ZD_CR65,  0x04 }, { ZD_CR66,  0x58 },
+		{ ZD_CR67,  0xc9 }, { ZD_CR68,  0x88 }, { ZD_CR69,  0x41 },
+		{ ZD_CR70,  0x23 }, { ZD_CR71,  0x10 }, { ZD_CR72,  0xff },
+		{ ZD_CR73,  0x32 }, { ZD_CR74,  0x30 }, { ZD_CR75,  0x65 },
+		{ ZD_CR76,  0x41 }, { ZD_CR77,  0x1b }, { ZD_CR78,  0x30 },
+		{ ZD_CR79,  0xf0 }, { ZD_CR80,  0x64 }, { ZD_CR81,  0x64 },
+		{ ZD_CR82,  0x00 }, { ZD_CR83,  0x24 }, { ZD_CR84,  0x04 },
+		{ ZD_CR85,  0x00 }, { ZD_CR86,  0x0c }, { ZD_CR87,  0x12 },
+		{ ZD_CR88,  0x0c }, { ZD_CR89,  0x00 }, { ZD_CR90,  0x58 },
+		{ ZD_CR91,  0x04 }, { ZD_CR92,  0x00 }, { ZD_CR93,  0x00 },
+		{ ZD_CR94,  0x01 },
+		{ ZD_CR95,  0x20 }, /* ZD1211B */
+		{ ZD_CR96,  0x50 }, { ZD_CR97,  0x37 }, { ZD_CR98,  0x35 },
+		{ ZD_CR99,  0x00 }, { ZD_CR100, 0x01 }, { ZD_CR101, 0x13 },
+		{ ZD_CR102, 0x27 }, { ZD_CR103, 0x27 }, { ZD_CR104, 0x18 },
+		{ ZD_CR105, 0x12 }, { ZD_CR106, 0x04 }, { ZD_CR107, 0x00 },
+		{ ZD_CR108, 0x0a }, { ZD_CR109, 0x27 }, { ZD_CR110, 0x27 },
+		{ ZD_CR111, 0x27 }, { ZD_CR112, 0x27 }, { ZD_CR113, 0x27 },
+		{ ZD_CR114, 0x27 }, { ZD_CR115, 0x26 }, { ZD_CR116, 0x24 },
+		{ ZD_CR117, 0xfc }, { ZD_CR118, 0xfa }, { ZD_CR119, 0x1e },
+		{ ZD_CR125, 0x90 }, { ZD_CR126, 0x00 }, { ZD_CR127, 0x00 },
+		{ ZD_CR128, 0x14 }, { ZD_CR129, 0x12 }, { ZD_CR130, 0x10 },
+		{ ZD_CR131, 0x0c }, { ZD_CR136, 0xdf }, { ZD_CR137, 0xa0 },
+		{ ZD_CR138, 0xa8 }, { ZD_CR139, 0xb4 }, { ZD_CR140, 0x98 },
+		{ ZD_CR141, 0x82 }, { ZD_CR142, 0x53 }, { ZD_CR143, 0x1c },
+		{ ZD_CR144, 0x6c }, { ZD_CR147, 0x07 }, { ZD_CR148, 0x40 },
+		{ ZD_CR149, 0x40 }, /* Org:0x50 ComTrend:RalLink AP */
+		{ ZD_CR150, 0x14 }, /* Org:0x0E ComTrend:RalLink AP */
+		{ ZD_CR151, 0x18 }, { ZD_CR159, 0x70 }, { ZD_CR160, 0xfe },
+		{ ZD_CR161, 0xee }, { ZD_CR162, 0xaa }, { ZD_CR163, 0xfa },
+		{ ZD_CR164, 0xfa }, { ZD_CR165, 0xea }, { ZD_CR166, 0xbe },
+		{ ZD_CR167, 0xbe }, { ZD_CR168, 0x6a }, { ZD_CR169, 0xba },
+		{ ZD_CR170, 0xba }, { ZD_CR171, 0xba },
+		/* Note: ZD_CR204 must lead the ZD_CR203 */
+		{ ZD_CR204, 0x7d },
 		{},
-		{ CR203, 0x30 },
+		{ ZD_CR203, 0x30 },
 	};
 
 	int r, t;
@@ -1200,24 +1200,24 @@
 static int update_pwr_int(struct zd_chip *chip, u8 channel)
 {
 	u8 value = chip->pwr_int_values[channel - 1];
-	return zd_iowrite16_locked(chip, value, CR31);
+	return zd_iowrite16_locked(chip, value, ZD_CR31);
 }
 
 static int update_pwr_cal(struct zd_chip *chip, u8 channel)
 {
 	u8 value = chip->pwr_cal_values[channel-1];
-	return zd_iowrite16_locked(chip, value, CR68);
+	return zd_iowrite16_locked(chip, value, ZD_CR68);
 }
 
 static int update_ofdm_cal(struct zd_chip *chip, u8 channel)
 {
 	struct zd_ioreq16 ioreqs[3];
 
-	ioreqs[0].addr = CR67;
+	ioreqs[0].addr = ZD_CR67;
 	ioreqs[0].value = chip->ofdm_cal_values[OFDM_36M_INDEX][channel-1];
-	ioreqs[1].addr = CR66;
+	ioreqs[1].addr = ZD_CR66;
 	ioreqs[1].value = chip->ofdm_cal_values[OFDM_48M_INDEX][channel-1];
-	ioreqs[2].addr = CR65;
+	ioreqs[2].addr = ZD_CR65;
 	ioreqs[2].value = chip->ofdm_cal_values[OFDM_54M_INDEX][channel-1];
 
 	return zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));
@@ -1236,9 +1236,9 @@
 		return r;
 	if (zd_chip_is_zd1211b(chip)) {
 		static const struct zd_ioreq16 ioreqs[] = {
-			{ CR69, 0x28 },
+			{ ZD_CR69, 0x28 },
 			{},
-			{ CR69, 0x2a },
+			{ ZD_CR69, 0x2a },
 		};
 
 		r = update_ofdm_cal(chip, channel);
@@ -1269,7 +1269,7 @@
 	if (r)
 		return r;
 	dev_dbg_f(zd_chip_dev(chip), "patching value %x\n", value & 0xff);
-	return zd_iowrite16_locked(chip, value & 0xff, CR47);
+	return zd_iowrite16_locked(chip, value & 0xff, ZD_CR47);
 }
 
 int zd_chip_set_channel(struct zd_chip *chip, u8 channel)
@@ -1505,9 +1505,9 @@
 int zd_rfwrite_cr_locked(struct zd_chip *chip, u32 value)
 {
 	const struct zd_ioreq16 ioreqs[] = {
-		{ CR244, (value >> 16) & 0xff },
-		{ CR243, (value >>  8) & 0xff },
-		{ CR242,  value        & 0xff },
+		{ ZD_CR244, (value >> 16) & 0xff },
+		{ ZD_CR243, (value >>  8) & 0xff },
+		{ ZD_CR242,  value        & 0xff },
 	};
 	ZD_ASSERT(mutex_is_locked(&chip->mutex));
 	return zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));
diff -druN linux-2.6.39-libre/drivers/net/wireless/zd1211rw/zd_chip.h linux-3.0-rc7-libre/drivers/net/wireless/zd1211rw/zd_chip.h
--- linux-2.6.39-libre/drivers/net/wireless/zd1211rw/zd_chip.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/zd1211rw/zd_chip.h	2011-07-11 19:51:52.000000000 -0400
@@ -61,277 +61,288 @@
 #define FWRAW_DATA(offset) ((zd_addr_t)(FW_START + (offset)))
 
 /* 8-bit hardware registers */
-#define CR0   CTL_REG(0x0000)
-#define CR1   CTL_REG(0x0004)
-#define CR2   CTL_REG(0x0008)
-#define CR3   CTL_REG(0x000C)
+#define ZD_CR0   CTL_REG(0x0000)
+#define ZD_CR1   CTL_REG(0x0004)
+#define ZD_CR2   CTL_REG(0x0008)
+#define ZD_CR3   CTL_REG(0x000C)
 
-#define CR5   CTL_REG(0x0010)
+#define ZD_CR5   CTL_REG(0x0010)
 /*	bit 5: if set short preamble used
  *	bit 6: filter band - Japan channel 14 on, else off
  */
-#define CR6   CTL_REG(0x0014)
-#define CR7   CTL_REG(0x0018)
-#define CR8   CTL_REG(0x001C)
+#define ZD_CR6   CTL_REG(0x0014)
+#define ZD_CR7   CTL_REG(0x0018)
+#define ZD_CR8   CTL_REG(0x001C)
 
-#define CR4   CTL_REG(0x0020)
+#define ZD_CR4   CTL_REG(0x0020)
 
-#define CR9   CTL_REG(0x0024)
-/*	bit 2: antenna switch (together with CR10) */
-#define CR10  CTL_REG(0x0028)
-/*	bit 1: antenna switch (together with CR9)
- *	RF2959 controls with CR11 radion on and off
+#define ZD_CR9   CTL_REG(0x0024)
+/*	bit 2: antenna switch (together with ZD_CR10) */
+#define ZD_CR10  CTL_REG(0x0028)
+/*	bit 1: antenna switch (together with ZD_CR9)
+ *	RF2959 controls with ZD_CR11 radion on and off
  */
-#define CR11  CTL_REG(0x002C)
+#define ZD_CR11  CTL_REG(0x002C)
 /*	bit 6:  TX power control for OFDM
- *	RF2959 controls with CR10 radio on and off
+ *	RF2959 controls with ZD_CR10 radio on and off
  */
-#define CR12  CTL_REG(0x0030)
-#define CR13  CTL_REG(0x0034)
-#define CR14  CTL_REG(0x0038)
-#define CR15  CTL_REG(0x003C)
-#define CR16  CTL_REG(0x0040)
-#define CR17  CTL_REG(0x0044)
-#define CR18  CTL_REG(0x0048)
-#define CR19  CTL_REG(0x004C)
-#define CR20  CTL_REG(0x0050)
-#define CR21  CTL_REG(0x0054)
-#define CR22  CTL_REG(0x0058)
-#define CR23  CTL_REG(0x005C)
-#define CR24  CTL_REG(0x0060)	/* CCA threshold */
-#define CR25  CTL_REG(0x0064)
-#define CR26  CTL_REG(0x0068)
-#define CR27  CTL_REG(0x006C)
-#define CR28  CTL_REG(0x0070)
-#define CR29  CTL_REG(0x0074)
-#define CR30  CTL_REG(0x0078)
-#define CR31  CTL_REG(0x007C)	/* TX power control for RF in CCK mode */
-#define CR32  CTL_REG(0x0080)
-#define CR33  CTL_REG(0x0084)
-#define CR34  CTL_REG(0x0088)
-#define CR35  CTL_REG(0x008C)
-#define CR36  CTL_REG(0x0090)
-#define CR37  CTL_REG(0x0094)
-#define CR38  CTL_REG(0x0098)
-#define CR39  CTL_REG(0x009C)
-#define CR40  CTL_REG(0x00A0)
-#define CR41  CTL_REG(0x00A4)
-#define CR42  CTL_REG(0x00A8)
-#define CR43  CTL_REG(0x00AC)
-#define CR44  CTL_REG(0x00B0)
-#define CR45  CTL_REG(0x00B4)
-#define CR46  CTL_REG(0x00B8)
-#define CR47  CTL_REG(0x00BC)	/* CCK baseband gain
-	                         * (patch value might be in EEPROM)
-				 */
-#define CR48  CTL_REG(0x00C0)
-#define CR49  CTL_REG(0x00C4)
-#define CR50  CTL_REG(0x00C8)
-#define CR51  CTL_REG(0x00CC)	/* TX power control for RF in 6-36M modes */
-#define CR52  CTL_REG(0x00D0)	/* TX power control for RF in 48M mode */
-#define CR53  CTL_REG(0x00D4)	/* TX power control for RF in 54M mode */
-#define CR54  CTL_REG(0x00D8)
-#define CR55  CTL_REG(0x00DC)
-#define CR56  CTL_REG(0x00E0)
-#define CR57  CTL_REG(0x00E4)
-#define CR58  CTL_REG(0x00E8)
-#define CR59  CTL_REG(0x00EC)
-#define CR60  CTL_REG(0x00F0)
-#define CR61  CTL_REG(0x00F4)
-#define CR62  CTL_REG(0x00F8)
-#define CR63  CTL_REG(0x00FC)
-#define CR64  CTL_REG(0x0100)
-#define CR65  CTL_REG(0x0104) /* OFDM 54M calibration */
-#define CR66  CTL_REG(0x0108) /* OFDM 48M calibration */
-#define CR67  CTL_REG(0x010C) /* OFDM 36M calibration */
-#define CR68  CTL_REG(0x0110) /* CCK calibration */
-#define CR69  CTL_REG(0x0114)
-#define CR70  CTL_REG(0x0118)
-#define CR71  CTL_REG(0x011C)
-#define CR72  CTL_REG(0x0120)
-#define CR73  CTL_REG(0x0124)
-#define CR74  CTL_REG(0x0128)
-#define CR75  CTL_REG(0x012C)
-#define CR76  CTL_REG(0x0130)
-#define CR77  CTL_REG(0x0134)
-#define CR78  CTL_REG(0x0138)
-#define CR79  CTL_REG(0x013C)
-#define CR80  CTL_REG(0x0140)
-#define CR81  CTL_REG(0x0144)
-#define CR82  CTL_REG(0x0148)
-#define CR83  CTL_REG(0x014C)
-#define CR84  CTL_REG(0x0150)
-#define CR85  CTL_REG(0x0154)
-#define CR86  CTL_REG(0x0158)
-#define CR87  CTL_REG(0x015C)
-#define CR88  CTL_REG(0x0160)
-#define CR89  CTL_REG(0x0164)
-#define CR90  CTL_REG(0x0168)
-#define CR91  CTL_REG(0x016C)
-#define CR92  CTL_REG(0x0170)
-#define CR93  CTL_REG(0x0174)
-#define CR94  CTL_REG(0x0178)
-#define CR95  CTL_REG(0x017C)
-#define CR96  CTL_REG(0x0180)
-#define CR97  CTL_REG(0x0184)
-#define CR98  CTL_REG(0x0188)
-#define CR99  CTL_REG(0x018C)
-#define CR100 CTL_REG(0x0190)
-#define CR101 CTL_REG(0x0194)
-#define CR102 CTL_REG(0x0198)
-#define CR103 CTL_REG(0x019C)
-#define CR104 CTL_REG(0x01A0)
-#define CR105 CTL_REG(0x01A4)
-#define CR106 CTL_REG(0x01A8)
-#define CR107 CTL_REG(0x01AC)
-#define CR108 CTL_REG(0x01B0)
-#define CR109 CTL_REG(0x01B4)
-#define CR110 CTL_REG(0x01B8)
-#define CR111 CTL_REG(0x01BC)
-#define CR112 CTL_REG(0x01C0)
-#define CR113 CTL_REG(0x01C4)
-#define CR114 CTL_REG(0x01C8)
-#define CR115 CTL_REG(0x01CC)
-#define CR116 CTL_REG(0x01D0)
-#define CR117 CTL_REG(0x01D4)
-#define CR118 CTL_REG(0x01D8)
-#define CR119 CTL_REG(0x01DC)
-#define CR120 CTL_REG(0x01E0)
-#define CR121 CTL_REG(0x01E4)
-#define CR122 CTL_REG(0x01E8)
-#define CR123 CTL_REG(0x01EC)
-#define CR124 CTL_REG(0x01F0)
-#define CR125 CTL_REG(0x01F4)
-#define CR126 CTL_REG(0x01F8)
-#define CR127 CTL_REG(0x01FC)
-#define CR128 CTL_REG(0x0200)
-#define CR129 CTL_REG(0x0204)
-#define CR130 CTL_REG(0x0208)
-#define CR131 CTL_REG(0x020C)
-#define CR132 CTL_REG(0x0210)
-#define CR133 CTL_REG(0x0214)
-#define CR134 CTL_REG(0x0218)
-#define CR135 CTL_REG(0x021C)
-#define CR136 CTL_REG(0x0220)
-#define CR137 CTL_REG(0x0224)
-#define CR138 CTL_REG(0x0228)
-#define CR139 CTL_REG(0x022C)
-#define CR140 CTL_REG(0x0230)
-#define CR141 CTL_REG(0x0234)
-#define CR142 CTL_REG(0x0238)
-#define CR143 CTL_REG(0x023C)
-#define CR144 CTL_REG(0x0240)
-#define CR145 CTL_REG(0x0244)
-#define CR146 CTL_REG(0x0248)
-#define CR147 CTL_REG(0x024C)
-#define CR148 CTL_REG(0x0250)
-#define CR149 CTL_REG(0x0254)
-#define CR150 CTL_REG(0x0258)
-#define CR151 CTL_REG(0x025C)
-#define CR152 CTL_REG(0x0260)
-#define CR153 CTL_REG(0x0264)
-#define CR154 CTL_REG(0x0268)
-#define CR155 CTL_REG(0x026C)
-#define CR156 CTL_REG(0x0270)
-#define CR157 CTL_REG(0x0274)
-#define CR158 CTL_REG(0x0278)
-#define CR159 CTL_REG(0x027C)
-#define CR160 CTL_REG(0x0280)
-#define CR161 CTL_REG(0x0284)
-#define CR162 CTL_REG(0x0288)
-#define CR163 CTL_REG(0x028C)
-#define CR164 CTL_REG(0x0290)
-#define CR165 CTL_REG(0x0294)
-#define CR166 CTL_REG(0x0298)
-#define CR167 CTL_REG(0x029C)
-#define CR168 CTL_REG(0x02A0)
-#define CR169 CTL_REG(0x02A4)
-#define CR170 CTL_REG(0x02A8)
-#define CR171 CTL_REG(0x02AC)
-#define CR172 CTL_REG(0x02B0)
-#define CR173 CTL_REG(0x02B4)
-#define CR174 CTL_REG(0x02B8)
-#define CR175 CTL_REG(0x02BC)
-#define CR176 CTL_REG(0x02C0)
-#define CR177 CTL_REG(0x02C4)
-#define CR178 CTL_REG(0x02C8)
-#define CR179 CTL_REG(0x02CC)
-#define CR180 CTL_REG(0x02D0)
-#define CR181 CTL_REG(0x02D4)
-#define CR182 CTL_REG(0x02D8)
-#define CR183 CTL_REG(0x02DC)
-#define CR184 CTL_REG(0x02E0)
-#define CR185 CTL_REG(0x02E4)
-#define CR186 CTL_REG(0x02E8)
-#define CR187 CTL_REG(0x02EC)
-#define CR188 CTL_REG(0x02F0)
-#define CR189 CTL_REG(0x02F4)
-#define CR190 CTL_REG(0x02F8)
-#define CR191 CTL_REG(0x02FC)
-#define CR192 CTL_REG(0x0300)
-#define CR193 CTL_REG(0x0304)
-#define CR194 CTL_REG(0x0308)
-#define CR195 CTL_REG(0x030C)
-#define CR196 CTL_REG(0x0310)
-#define CR197 CTL_REG(0x0314)
-#define CR198 CTL_REG(0x0318)
-#define CR199 CTL_REG(0x031C)
-#define CR200 CTL_REG(0x0320)
-#define CR201 CTL_REG(0x0324)
-#define CR202 CTL_REG(0x0328)
-#define CR203 CTL_REG(0x032C)	/* I2C bus template value & flash control */
-#define CR204 CTL_REG(0x0330)
-#define CR205 CTL_REG(0x0334)
-#define CR206 CTL_REG(0x0338)
-#define CR207 CTL_REG(0x033C)
-#define CR208 CTL_REG(0x0340)
-#define CR209 CTL_REG(0x0344)
-#define CR210 CTL_REG(0x0348)
-#define CR211 CTL_REG(0x034C)
-#define CR212 CTL_REG(0x0350)
-#define CR213 CTL_REG(0x0354)
-#define CR214 CTL_REG(0x0358)
-#define CR215 CTL_REG(0x035C)
-#define CR216 CTL_REG(0x0360)
-#define CR217 CTL_REG(0x0364)
-#define CR218 CTL_REG(0x0368)
-#define CR219 CTL_REG(0x036C)
-#define CR220 CTL_REG(0x0370)
-#define CR221 CTL_REG(0x0374)
-#define CR222 CTL_REG(0x0378)
-#define CR223 CTL_REG(0x037C)
-#define CR224 CTL_REG(0x0380)
-#define CR225 CTL_REG(0x0384)
-#define CR226 CTL_REG(0x0388)
-#define CR227 CTL_REG(0x038C)
-#define CR228 CTL_REG(0x0390)
-#define CR229 CTL_REG(0x0394)
-#define CR230 CTL_REG(0x0398)
-#define CR231 CTL_REG(0x039C)
-#define CR232 CTL_REG(0x03A0)
-#define CR233 CTL_REG(0x03A4)
-#define CR234 CTL_REG(0x03A8)
-#define CR235 CTL_REG(0x03AC)
-#define CR236 CTL_REG(0x03B0)
+#define ZD_CR12  CTL_REG(0x0030)
+#define ZD_CR13  CTL_REG(0x0034)
+#define ZD_CR14  CTL_REG(0x0038)
+#define ZD_CR15  CTL_REG(0x003C)
+#define ZD_CR16  CTL_REG(0x0040)
+#define ZD_CR17  CTL_REG(0x0044)
+#define ZD_CR18  CTL_REG(0x0048)
+#define ZD_CR19  CTL_REG(0x004C)
+#define ZD_CR20  CTL_REG(0x0050)
+#define ZD_CR21  CTL_REG(0x0054)
+#define ZD_CR22  CTL_REG(0x0058)
+#define ZD_CR23  CTL_REG(0x005C)
+#define ZD_CR24  CTL_REG(0x0060)	/* CCA threshold */
+#define ZD_CR25  CTL_REG(0x0064)
+#define ZD_CR26  CTL_REG(0x0068)
+#define ZD_CR27  CTL_REG(0x006C)
+#define ZD_CR28  CTL_REG(0x0070)
+#define ZD_CR29  CTL_REG(0x0074)
+#define ZD_CR30  CTL_REG(0x0078)
+#define ZD_CR31  CTL_REG(0x007C)	/* TX power control for RF in
+					 * CCK mode
+					 */
+#define ZD_CR32  CTL_REG(0x0080)
+#define ZD_CR33  CTL_REG(0x0084)
+#define ZD_CR34  CTL_REG(0x0088)
+#define ZD_CR35  CTL_REG(0x008C)
+#define ZD_CR36  CTL_REG(0x0090)
+#define ZD_CR37  CTL_REG(0x0094)
+#define ZD_CR38  CTL_REG(0x0098)
+#define ZD_CR39  CTL_REG(0x009C)
+#define ZD_CR40  CTL_REG(0x00A0)
+#define ZD_CR41  CTL_REG(0x00A4)
+#define ZD_CR42  CTL_REG(0x00A8)
+#define ZD_CR43  CTL_REG(0x00AC)
+#define ZD_CR44  CTL_REG(0x00B0)
+#define ZD_CR45  CTL_REG(0x00B4)
+#define ZD_CR46  CTL_REG(0x00B8)
+#define ZD_CR47  CTL_REG(0x00BC)	/* CCK baseband gain
+					 * (patch value might be in EEPROM)
+					 */
+#define ZD_CR48  CTL_REG(0x00C0)
+#define ZD_CR49  CTL_REG(0x00C4)
+#define ZD_CR50  CTL_REG(0x00C8)
+#define ZD_CR51  CTL_REG(0x00CC)	/* TX power control for RF in
+					 * 6-36M modes
+					 */
+#define ZD_CR52  CTL_REG(0x00D0)	/* TX power control for RF in
+					 * 48M mode
+					 */
+#define ZD_CR53  CTL_REG(0x00D4)	/* TX power control for RF in
+					 * 54M mode
+					 */
+#define ZD_CR54  CTL_REG(0x00D8)
+#define ZD_CR55  CTL_REG(0x00DC)
+#define ZD_CR56  CTL_REG(0x00E0)
+#define ZD_CR57  CTL_REG(0x00E4)
+#define ZD_CR58  CTL_REG(0x00E8)
+#define ZD_CR59  CTL_REG(0x00EC)
+#define ZD_CR60  CTL_REG(0x00F0)
+#define ZD_CR61  CTL_REG(0x00F4)
+#define ZD_CR62  CTL_REG(0x00F8)
+#define ZD_CR63  CTL_REG(0x00FC)
+#define ZD_CR64  CTL_REG(0x0100)
+#define ZD_CR65  CTL_REG(0x0104) /* OFDM 54M calibration */
+#define ZD_CR66  CTL_REG(0x0108) /* OFDM 48M calibration */
+#define ZD_CR67  CTL_REG(0x010C) /* OFDM 36M calibration */
+#define ZD_CR68  CTL_REG(0x0110) /* CCK calibration */
+#define ZD_CR69  CTL_REG(0x0114)
+#define ZD_CR70  CTL_REG(0x0118)
+#define ZD_CR71  CTL_REG(0x011C)
+#define ZD_CR72  CTL_REG(0x0120)
+#define ZD_CR73  CTL_REG(0x0124)
+#define ZD_CR74  CTL_REG(0x0128)
+#define ZD_CR75  CTL_REG(0x012C)
+#define ZD_CR76  CTL_REG(0x0130)
+#define ZD_CR77  CTL_REG(0x0134)
+#define ZD_CR78  CTL_REG(0x0138)
+#define ZD_CR79  CTL_REG(0x013C)
+#define ZD_CR80  CTL_REG(0x0140)
+#define ZD_CR81  CTL_REG(0x0144)
+#define ZD_CR82  CTL_REG(0x0148)
+#define ZD_CR83  CTL_REG(0x014C)
+#define ZD_CR84  CTL_REG(0x0150)
+#define ZD_CR85  CTL_REG(0x0154)
+#define ZD_CR86  CTL_REG(0x0158)
+#define ZD_CR87  CTL_REG(0x015C)
+#define ZD_CR88  CTL_REG(0x0160)
+#define ZD_CR89  CTL_REG(0x0164)
+#define ZD_CR90  CTL_REG(0x0168)
+#define ZD_CR91  CTL_REG(0x016C)
+#define ZD_CR92  CTL_REG(0x0170)
+#define ZD_CR93  CTL_REG(0x0174)
+#define ZD_CR94  CTL_REG(0x0178)
+#define ZD_CR95  CTL_REG(0x017C)
+#define ZD_CR96  CTL_REG(0x0180)
+#define ZD_CR97  CTL_REG(0x0184)
+#define ZD_CR98  CTL_REG(0x0188)
+#define ZD_CR99  CTL_REG(0x018C)
+#define ZD_CR100 CTL_REG(0x0190)
+#define ZD_CR101 CTL_REG(0x0194)
+#define ZD_CR102 CTL_REG(0x0198)
+#define ZD_CR103 CTL_REG(0x019C)
+#define ZD_CR104 CTL_REG(0x01A0)
+#define ZD_CR105 CTL_REG(0x01A4)
+#define ZD_CR106 CTL_REG(0x01A8)
+#define ZD_CR107 CTL_REG(0x01AC)
+#define ZD_CR108 CTL_REG(0x01B0)
+#define ZD_CR109 CTL_REG(0x01B4)
+#define ZD_CR110 CTL_REG(0x01B8)
+#define ZD_CR111 CTL_REG(0x01BC)
+#define ZD_CR112 CTL_REG(0x01C0)
+#define ZD_CR113 CTL_REG(0x01C4)
+#define ZD_CR114 CTL_REG(0x01C8)
+#define ZD_CR115 CTL_REG(0x01CC)
+#define ZD_CR116 CTL_REG(0x01D0)
+#define ZD_CR117 CTL_REG(0x01D4)
+#define ZD_CR118 CTL_REG(0x01D8)
+#define ZD_CR119 CTL_REG(0x01DC)
+#define ZD_CR120 CTL_REG(0x01E0)
+#define ZD_CR121 CTL_REG(0x01E4)
+#define ZD_CR122 CTL_REG(0x01E8)
+#define ZD_CR123 CTL_REG(0x01EC)
+#define ZD_CR124 CTL_REG(0x01F0)
+#define ZD_CR125 CTL_REG(0x01F4)
+#define ZD_CR126 CTL_REG(0x01F8)
+#define ZD_CR127 CTL_REG(0x01FC)
+#define ZD_CR128 CTL_REG(0x0200)
+#define ZD_CR129 CTL_REG(0x0204)
+#define ZD_CR130 CTL_REG(0x0208)
+#define ZD_CR131 CTL_REG(0x020C)
+#define ZD_CR132 CTL_REG(0x0210)
+#define ZD_CR133 CTL_REG(0x0214)
+#define ZD_CR134 CTL_REG(0x0218)
+#define ZD_CR135 CTL_REG(0x021C)
+#define ZD_CR136 CTL_REG(0x0220)
+#define ZD_CR137 CTL_REG(0x0224)
+#define ZD_CR138 CTL_REG(0x0228)
+#define ZD_CR139 CTL_REG(0x022C)
+#define ZD_CR140 CTL_REG(0x0230)
+#define ZD_CR141 CTL_REG(0x0234)
+#define ZD_CR142 CTL_REG(0x0238)
+#define ZD_CR143 CTL_REG(0x023C)
+#define ZD_CR144 CTL_REG(0x0240)
+#define ZD_CR145 CTL_REG(0x0244)
+#define ZD_CR146 CTL_REG(0x0248)
+#define ZD_CR147 CTL_REG(0x024C)
+#define ZD_CR148 CTL_REG(0x0250)
+#define ZD_CR149 CTL_REG(0x0254)
+#define ZD_CR150 CTL_REG(0x0258)
+#define ZD_CR151 CTL_REG(0x025C)
+#define ZD_CR152 CTL_REG(0x0260)
+#define ZD_CR153 CTL_REG(0x0264)
+#define ZD_CR154 CTL_REG(0x0268)
+#define ZD_CR155 CTL_REG(0x026C)
+#define ZD_CR156 CTL_REG(0x0270)
+#define ZD_CR157 CTL_REG(0x0274)
+#define ZD_CR158 CTL_REG(0x0278)
+#define ZD_CR159 CTL_REG(0x027C)
+#define ZD_CR160 CTL_REG(0x0280)
+#define ZD_CR161 CTL_REG(0x0284)
+#define ZD_CR162 CTL_REG(0x0288)
+#define ZD_CR163 CTL_REG(0x028C)
+#define ZD_CR164 CTL_REG(0x0290)
+#define ZD_CR165 CTL_REG(0x0294)
+#define ZD_CR166 CTL_REG(0x0298)
+#define ZD_CR167 CTL_REG(0x029C)
+#define ZD_CR168 CTL_REG(0x02A0)
+#define ZD_CR169 CTL_REG(0x02A4)
+#define ZD_CR170 CTL_REG(0x02A8)
+#define ZD_CR171 CTL_REG(0x02AC)
+#define ZD_CR172 CTL_REG(0x02B0)
+#define ZD_CR173 CTL_REG(0x02B4)
+#define ZD_CR174 CTL_REG(0x02B8)
+#define ZD_CR175 CTL_REG(0x02BC)
+#define ZD_CR176 CTL_REG(0x02C0)
+#define ZD_CR177 CTL_REG(0x02C4)
+#define ZD_CR178 CTL_REG(0x02C8)
+#define ZD_CR179 CTL_REG(0x02CC)
+#define ZD_CR180 CTL_REG(0x02D0)
+#define ZD_CR181 CTL_REG(0x02D4)
+#define ZD_CR182 CTL_REG(0x02D8)
+#define ZD_CR183 CTL_REG(0x02DC)
+#define ZD_CR184 CTL_REG(0x02E0)
+#define ZD_CR185 CTL_REG(0x02E4)
+#define ZD_CR186 CTL_REG(0x02E8)
+#define ZD_CR187 CTL_REG(0x02EC)
+#define ZD_CR188 CTL_REG(0x02F0)
+#define ZD_CR189 CTL_REG(0x02F4)
+#define ZD_CR190 CTL_REG(0x02F8)
+#define ZD_CR191 CTL_REG(0x02FC)
+#define ZD_CR192 CTL_REG(0x0300)
+#define ZD_CR193 CTL_REG(0x0304)
+#define ZD_CR194 CTL_REG(0x0308)
+#define ZD_CR195 CTL_REG(0x030C)
+#define ZD_CR196 CTL_REG(0x0310)
+#define ZD_CR197 CTL_REG(0x0314)
+#define ZD_CR198 CTL_REG(0x0318)
+#define ZD_CR199 CTL_REG(0x031C)
+#define ZD_CR200 CTL_REG(0x0320)
+#define ZD_CR201 CTL_REG(0x0324)
+#define ZD_CR202 CTL_REG(0x0328)
+#define ZD_CR203 CTL_REG(0x032C)	/* I2C bus template value & flash
+					 * control
+					 */
+#define ZD_CR204 CTL_REG(0x0330)
+#define ZD_CR205 CTL_REG(0x0334)
+#define ZD_CR206 CTL_REG(0x0338)
+#define ZD_CR207 CTL_REG(0x033C)
+#define ZD_CR208 CTL_REG(0x0340)
+#define ZD_CR209 CTL_REG(0x0344)
+#define ZD_CR210 CTL_REG(0x0348)
+#define ZD_CR211 CTL_REG(0x034C)
+#define ZD_CR212 CTL_REG(0x0350)
+#define ZD_CR213 CTL_REG(0x0354)
+#define ZD_CR214 CTL_REG(0x0358)
+#define ZD_CR215 CTL_REG(0x035C)
+#define ZD_CR216 CTL_REG(0x0360)
+#define ZD_CR217 CTL_REG(0x0364)
+#define ZD_CR218 CTL_REG(0x0368)
+#define ZD_CR219 CTL_REG(0x036C)
+#define ZD_CR220 CTL_REG(0x0370)
+#define ZD_CR221 CTL_REG(0x0374)
+#define ZD_CR222 CTL_REG(0x0378)
+#define ZD_CR223 CTL_REG(0x037C)
+#define ZD_CR224 CTL_REG(0x0380)
+#define ZD_CR225 CTL_REG(0x0384)
+#define ZD_CR226 CTL_REG(0x0388)
+#define ZD_CR227 CTL_REG(0x038C)
+#define ZD_CR228 CTL_REG(0x0390)
+#define ZD_CR229 CTL_REG(0x0394)
+#define ZD_CR230 CTL_REG(0x0398)
+#define ZD_CR231 CTL_REG(0x039C)
+#define ZD_CR232 CTL_REG(0x03A0)
+#define ZD_CR233 CTL_REG(0x03A4)
+#define ZD_CR234 CTL_REG(0x03A8)
+#define ZD_CR235 CTL_REG(0x03AC)
+#define ZD_CR236 CTL_REG(0x03B0)
 
-#define CR240 CTL_REG(0x03C0)
-/*	bit 7:  host-controlled RF register writes
- * CR241-CR245: for hardware controlled writing of RF bits, not needed for
- *              USB
+#define ZD_CR240 CTL_REG(0x03C0)
+/*             bit 7: host-controlled RF register writes
+ * ZD_CR241-ZD_CR245: for hardware controlled writing of RF bits, not needed for
+ *                    USB
  */
-#define CR241 CTL_REG(0x03C4)
-#define CR242 CTL_REG(0x03C8)
-#define CR243 CTL_REG(0x03CC)
-#define CR244 CTL_REG(0x03D0)
-#define CR245 CTL_REG(0x03D4)
+#define ZD_CR241 CTL_REG(0x03C4)
+#define ZD_CR242 CTL_REG(0x03C8)
+#define ZD_CR243 CTL_REG(0x03CC)
+#define ZD_CR244 CTL_REG(0x03D0)
+#define ZD_CR245 CTL_REG(0x03D4)
 
-#define CR251 CTL_REG(0x03EC)	/* only used for activation and deactivation of
-				 * Airoha RFs AL2230 and AL7230B
-				 */
-#define CR252 CTL_REG(0x03F0)
-#define CR253 CTL_REG(0x03F4)
-#define CR254 CTL_REG(0x03F8)
-#define CR255 CTL_REG(0x03FC)
+#define ZD_CR251 CTL_REG(0x03EC)	/* only used for activation and
+					 * deactivation of Airoha RFs AL2230
+					 * and AL7230B
+					 */
+#define ZD_CR252 CTL_REG(0x03F0)
+#define ZD_CR253 CTL_REG(0x03F4)
+#define ZD_CR254 CTL_REG(0x03F8)
+#define ZD_CR255 CTL_REG(0x03FC)
 
 #define CR_MAX_PHY_REG 255
 
diff -druN linux-2.6.39-libre/drivers/net/wireless/zd1211rw/zd_rf_al2230.c linux-3.0-rc7-libre/drivers/net/wireless/zd1211rw/zd_rf_al2230.c
--- linux-2.6.39-libre/drivers/net/wireless/zd1211rw/zd_rf_al2230.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/zd1211rw/zd_rf_al2230.c	2011-07-11 19:51:52.000000000 -0400
@@ -61,31 +61,31 @@
 };
 
 static const struct zd_ioreq16 zd1211b_ioreqs_shared_1[] = {
-	{ CR240, 0x57 }, { CR9,   0xe0 },
+	{ ZD_CR240, 0x57 }, { ZD_CR9,   0xe0 },
 };
 
 static const struct zd_ioreq16 ioreqs_init_al2230s[] = {
-	{ CR47,   0x1e }, /* MARK_002 */
-	{ CR106,  0x22 },
-	{ CR107,  0x2a }, /* MARK_002 */
-	{ CR109,  0x13 }, /* MARK_002 */
-	{ CR118,  0xf8 }, /* MARK_002 */
-	{ CR119,  0x12 }, { CR122,  0xe0 },
-	{ CR128,  0x10 }, /* MARK_001 from 0xe->0x10 */
-	{ CR129,  0x0e }, /* MARK_001 from 0xd->0x0e */
-	{ CR130,  0x10 }, /* MARK_001 from 0xb->0x0d */
+	{ ZD_CR47,   0x1e }, /* MARK_002 */
+	{ ZD_CR106,  0x22 },
+	{ ZD_CR107,  0x2a }, /* MARK_002 */
+	{ ZD_CR109,  0x13 }, /* MARK_002 */
+	{ ZD_CR118,  0xf8 }, /* MARK_002 */
+	{ ZD_CR119,  0x12 }, { ZD_CR122,  0xe0 },
+	{ ZD_CR128,  0x10 }, /* MARK_001 from 0xe->0x10 */
+	{ ZD_CR129,  0x0e }, /* MARK_001 from 0xd->0x0e */
+	{ ZD_CR130,  0x10 }, /* MARK_001 from 0xb->0x0d */
 };
 
 static int zd1211b_al2230_finalize_rf(struct zd_chip *chip)
 {
 	int r;
 	static const struct zd_ioreq16 ioreqs[] = {
-		{ CR80,  0x30 }, { CR81,  0x30 }, { CR79,  0x58 },
-		{ CR12,  0xf0 }, { CR77,  0x1b }, { CR78,  0x58 },
-		{ CR203, 0x06 },
+		{ ZD_CR80,  0x30 }, { ZD_CR81,  0x30 }, { ZD_CR79,  0x58 },
+		{ ZD_CR12,  0xf0 }, { ZD_CR77,  0x1b }, { ZD_CR78,  0x58 },
+		{ ZD_CR203, 0x06 },
 		{ },
 
-		{ CR240, 0x80 },
+		{ ZD_CR240, 0x80 },
 	};
 
 	r = zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));
@@ -94,12 +94,12 @@
 
 	/* related to antenna selection? */
 	if (chip->new_phy_layout) {
-		r = zd_iowrite16_locked(chip, 0xe1, CR9);
+		r = zd_iowrite16_locked(chip, 0xe1, ZD_CR9);
 		if (r)
 			return r;
 	}
 
-	return zd_iowrite16_locked(chip, 0x06, CR203);
+	return zd_iowrite16_locked(chip, 0x06, ZD_CR203);
 }
 
 static int zd1211_al2230_init_hw(struct zd_rf *rf)
@@ -108,40 +108,40 @@
 	struct zd_chip *chip = zd_rf_to_chip(rf);
 
 	static const struct zd_ioreq16 ioreqs_init[] = {
-		{ CR15,   0x20 }, { CR23,   0x40 }, { CR24,  0x20 },
-		{ CR26,   0x11 }, { CR28,   0x3e }, { CR29,  0x00 },
-		{ CR44,   0x33 }, { CR106,  0x2a }, { CR107, 0x1a },
-		{ CR109,  0x09 }, { CR110,  0x27 }, { CR111, 0x2b },
-		{ CR112,  0x2b }, { CR119,  0x0a }, { CR10,  0x89 },
+		{ ZD_CR15,   0x20 }, { ZD_CR23,   0x40 }, { ZD_CR24,  0x20 },
+		{ ZD_CR26,   0x11 }, { ZD_CR28,   0x3e }, { ZD_CR29,  0x00 },
+		{ ZD_CR44,   0x33 }, { ZD_CR106,  0x2a }, { ZD_CR107, 0x1a },
+		{ ZD_CR109,  0x09 }, { ZD_CR110,  0x27 }, { ZD_CR111, 0x2b },
+		{ ZD_CR112,  0x2b }, { ZD_CR119,  0x0a }, { ZD_CR10,  0x89 },
 		/* for newest (3rd cut) AL2300 */
-		{ CR17,   0x28 },
-		{ CR26,   0x93 }, { CR34,   0x30 },
+		{ ZD_CR17,   0x28 },
+		{ ZD_CR26,   0x93 }, { ZD_CR34,   0x30 },
 		/* for newest (3rd cut) AL2300 */
-		{ CR35,   0x3e },
-		{ CR41,   0x24 }, { CR44,   0x32 },
+		{ ZD_CR35,   0x3e },
+		{ ZD_CR41,   0x24 }, { ZD_CR44,   0x32 },
 		/* for newest (3rd cut) AL2300 */
-		{ CR46,   0x96 },
-		{ CR47,   0x1e }, { CR79,   0x58 }, { CR80,  0x30 },
-		{ CR81,   0x30 }, { CR87,   0x0a }, { CR89,  0x04 },
-		{ CR92,   0x0a }, { CR99,   0x28 }, { CR100, 0x00 },
-		{ CR101,  0x13 }, { CR102,  0x27 }, { CR106, 0x24 },
-		{ CR107,  0x2a }, { CR109,  0x09 }, { CR110, 0x13 },
-		{ CR111,  0x1f }, { CR112,  0x1f }, { CR113, 0x27 },
-		{ CR114,  0x27 },
+		{ ZD_CR46,   0x96 },
+		{ ZD_CR47,   0x1e }, { ZD_CR79,   0x58 }, { ZD_CR80,  0x30 },
+		{ ZD_CR81,   0x30 }, { ZD_CR87,   0x0a }, { ZD_CR89,  0x04 },
+		{ ZD_CR92,   0x0a }, { ZD_CR99,   0x28 }, { ZD_CR100, 0x00 },
+		{ ZD_CR101,  0x13 }, { ZD_CR102,  0x27 }, { ZD_CR106, 0x24 },
+		{ ZD_CR107,  0x2a }, { ZD_CR109,  0x09 }, { ZD_CR110, 0x13 },
+		{ ZD_CR111,  0x1f }, { ZD_CR112,  0x1f }, { ZD_CR113, 0x27 },
+		{ ZD_CR114,  0x27 },
 		/* for newest (3rd cut) AL2300 */
-		{ CR115,  0x24 },
-		{ CR116,  0x24 }, { CR117,  0xf4 }, { CR118, 0xfc },
-		{ CR119,  0x10 }, { CR120,  0x4f }, { CR121, 0x77 },
-		{ CR122,  0xe0 }, { CR137,  0x88 }, { CR252, 0xff },
-		{ CR253,  0xff },
+		{ ZD_CR115,  0x24 },
+		{ ZD_CR116,  0x24 }, { ZD_CR117,  0xf4 }, { ZD_CR118, 0xfc },
+		{ ZD_CR119,  0x10 }, { ZD_CR120,  0x4f }, { ZD_CR121, 0x77 },
+		{ ZD_CR122,  0xe0 }, { ZD_CR137,  0x88 }, { ZD_CR252, 0xff },
+		{ ZD_CR253,  0xff },
 	};
 
 	static const struct zd_ioreq16 ioreqs_pll[] = {
 		/* shdnb(PLL_ON)=0 */
-		{ CR251,  0x2f },
+		{ ZD_CR251,  0x2f },
 		/* shdnb(PLL_ON)=1 */
-		{ CR251,  0x3f },
-		{ CR138,  0x28 }, { CR203,  0x06 },
+		{ ZD_CR251,  0x3f },
+		{ ZD_CR138,  0x28 }, { ZD_CR203,  0x06 },
 	};
 
 	static const u32 rv1[] = {
@@ -161,7 +161,7 @@
 		0x0805b6,
 		0x011687,
 		0x000688,
-		0x0403b9, /* external control TX power (CR31) */
+		0x0403b9, /* external control TX power (ZD_CR31) */
 		0x00dbba,
 		0x00099b,
 		0x0bdffc,
@@ -221,52 +221,54 @@
 	struct zd_chip *chip = zd_rf_to_chip(rf);
 
 	static const struct zd_ioreq16 ioreqs1[] = {
-		{ CR10,  0x89 }, { CR15,  0x20 },
-		{ CR17,  0x2B }, /* for newest(3rd cut) AL2230 */
-		{ CR23,  0x40 }, { CR24,  0x20 }, { CR26,  0x93 },
-		{ CR28,  0x3e }, { CR29,  0x00 },
-		{ CR33,  0x28 }, /* 5621 */
-		{ CR34,  0x30 },
-		{ CR35,  0x3e }, /* for newest(3rd cut) AL2230 */
-		{ CR41,  0x24 }, { CR44,  0x32 },
-		{ CR46,  0x99 }, /* for newest(3rd cut) AL2230 */
-		{ CR47,  0x1e },
+		{ ZD_CR10,  0x89 }, { ZD_CR15,  0x20 },
+		{ ZD_CR17,  0x2B }, /* for newest(3rd cut) AL2230 */
+		{ ZD_CR23,  0x40 }, { ZD_CR24,  0x20 }, { ZD_CR26,  0x93 },
+		{ ZD_CR28,  0x3e }, { ZD_CR29,  0x00 },
+		{ ZD_CR33,  0x28 }, /* 5621 */
+		{ ZD_CR34,  0x30 },
+		{ ZD_CR35,  0x3e }, /* for newest(3rd cut) AL2230 */
+		{ ZD_CR41,  0x24 }, { ZD_CR44,  0x32 },
+		{ ZD_CR46,  0x99 }, /* for newest(3rd cut) AL2230 */
+		{ ZD_CR47,  0x1e },
 
 		/* ZD1211B 05.06.10 */
-		{ CR48,  0x06 }, { CR49,  0xf9 }, { CR51,  0x01 },
-		{ CR52,  0x80 }, { CR53,  0x7e }, { CR65,  0x00 },
-		{ CR66,  0x00 }, { CR67,  0x00 }, { CR68,  0x00 },
-		{ CR69,  0x28 },
+		{ ZD_CR48,  0x06 }, { ZD_CR49,  0xf9 }, { ZD_CR51,  0x01 },
+		{ ZD_CR52,  0x80 }, { ZD_CR53,  0x7e }, { ZD_CR65,  0x00 },
+		{ ZD_CR66,  0x00 }, { ZD_CR67,  0x00 }, { ZD_CR68,  0x00 },
+		{ ZD_CR69,  0x28 },
 
-		{ CR79,  0x58 }, { CR80,  0x30 }, { CR81,  0x30 },
-		{ CR87,  0x0a }, { CR89,  0x04 },
-		{ CR91,  0x00 }, /* 5621 */
-		{ CR92,  0x0a },
-		{ CR98,  0x8d }, /* 4804,  for 1212 new algorithm */
-		{ CR99,  0x00 }, /* 5621 */
-		{ CR101, 0x13 }, { CR102, 0x27 },
-		{ CR106, 0x24 }, /* for newest(3rd cut) AL2230 */
-		{ CR107, 0x2a },
-		{ CR109, 0x13 }, /* 4804, for 1212 new algorithm */
-		{ CR110, 0x1f }, /* 4804, for 1212 new algorithm */
-		{ CR111, 0x1f }, { CR112, 0x1f }, { CR113, 0x27 },
-		{ CR114, 0x27 },
-		{ CR115, 0x26 }, /* 24->26 at 4902 for newest(3rd cut) AL2230 */
-		{ CR116, 0x24 },
-		{ CR117, 0xfa }, /* for 1211b */
-		{ CR118, 0xfa }, /* for 1211b */
-		{ CR119, 0x10 },
-		{ CR120, 0x4f },
-		{ CR121, 0x6c }, /* for 1211b */
-		{ CR122, 0xfc }, /* E0->FC at 4902 */
-		{ CR123, 0x57 }, /* 5623 */
-		{ CR125, 0xad }, /* 4804, for 1212 new algorithm */
-		{ CR126, 0x6c }, /* 5614 */
-		{ CR127, 0x03 }, /* 4804, for 1212 new algorithm */
-		{ CR137, 0x50 }, /* 5614 */
-		{ CR138, 0xa8 },
-		{ CR144, 0xac }, /* 5621 */
-		{ CR150, 0x0d }, { CR252, 0x34 }, { CR253, 0x34 },
+		{ ZD_CR79,  0x58 }, { ZD_CR80,  0x30 }, { ZD_CR81,  0x30 },
+		{ ZD_CR87,  0x0a }, { ZD_CR89,  0x04 },
+		{ ZD_CR91,  0x00 }, /* 5621 */
+		{ ZD_CR92,  0x0a },
+		{ ZD_CR98,  0x8d }, /* 4804,  for 1212 new algorithm */
+		{ ZD_CR99,  0x00 }, /* 5621 */
+		{ ZD_CR101, 0x13 }, { ZD_CR102, 0x27 },
+		{ ZD_CR106, 0x24 }, /* for newest(3rd cut) AL2230 */
+		{ ZD_CR107, 0x2a },
+		{ ZD_CR109, 0x13 }, /* 4804, for 1212 new algorithm */
+		{ ZD_CR110, 0x1f }, /* 4804, for 1212 new algorithm */
+		{ ZD_CR111, 0x1f }, { ZD_CR112, 0x1f }, { ZD_CR113, 0x27 },
+		{ ZD_CR114, 0x27 },
+		{ ZD_CR115, 0x26 }, /* 24->26 at 4902 for newest(3rd cut)
+				     * AL2230
+				     */
+		{ ZD_CR116, 0x24 },
+		{ ZD_CR117, 0xfa }, /* for 1211b */
+		{ ZD_CR118, 0xfa }, /* for 1211b */
+		{ ZD_CR119, 0x10 },
+		{ ZD_CR120, 0x4f },
+		{ ZD_CR121, 0x6c }, /* for 1211b */
+		{ ZD_CR122, 0xfc }, /* E0->FC at 4902 */
+		{ ZD_CR123, 0x57 }, /* 5623 */
+		{ ZD_CR125, 0xad }, /* 4804, for 1212 new algorithm */
+		{ ZD_CR126, 0x6c }, /* 5614 */
+		{ ZD_CR127, 0x03 }, /* 4804, for 1212 new algorithm */
+		{ ZD_CR137, 0x50 }, /* 5614 */
+		{ ZD_CR138, 0xa8 },
+		{ ZD_CR144, 0xac }, /* 5621 */
+		{ ZD_CR150, 0x0d }, { ZD_CR252, 0x34 }, { ZD_CR253, 0x34 },
 	};
 
 	static const u32 rv1[] = {
@@ -284,7 +286,7 @@
 		0x6da010, /* Reg6 update for MP versio */
 		0xe36280, /* Modified by jxiao for Bor-Chin on 2004/08/02 */
 		0x116000,
-		0x9dc020, /* External control TX power (CR31) */
+		0x9dc020, /* External control TX power (ZD_CR31) */
 		0x5ddb00, /* RegA update for MP version */
 		0xd99000, /* RegB update for MP version */
 		0x3ffbd0, /* RegC update for MP version */
@@ -295,8 +297,8 @@
 	};
 
 	static const struct zd_ioreq16 ioreqs2[] = {
-		{ CR251, 0x2f }, /* shdnb(PLL_ON)=0 */
-		{ CR251, 0x7f }, /* shdnb(PLL_ON)=1 */
+		{ ZD_CR251, 0x2f }, /* shdnb(PLL_ON)=0 */
+		{ ZD_CR251, 0x7f }, /* shdnb(PLL_ON)=1 */
 	};
 
 	static const u32 rv3[] = {
@@ -308,7 +310,7 @@
 
 	static const struct zd_ioreq16 ioreqs3[] = {
 		/* related to 6M band edge patching, happens unconditionally */
-		{ CR128, 0x14 }, { CR129, 0x12 }, { CR130, 0x10 },
+		{ ZD_CR128, 0x14 }, { ZD_CR129, 0x12 }, { ZD_CR130, 0x10 },
 	};
 
 	r = zd_iowrite16a_locked(chip, zd1211b_ioreqs_shared_1,
@@ -361,8 +363,8 @@
 	const u32 *rv = zd1211_al2230_table[channel-1];
 	struct zd_chip *chip = zd_rf_to_chip(rf);
 	static const struct zd_ioreq16 ioreqs[] = {
-		{ CR138, 0x28 },
-		{ CR203, 0x06 },
+		{ ZD_CR138, 0x28 },
+		{ ZD_CR203, 0x06 },
 	};
 
 	r = zd_rfwritev_locked(chip, rv, 3, RF_RV_BITS);
@@ -393,8 +395,8 @@
 {
 	struct zd_chip *chip = zd_rf_to_chip(rf);
 	static const struct zd_ioreq16 ioreqs[] = {
-		{ CR11,  0x00 },
-		{ CR251, 0x3f },
+		{ ZD_CR11,  0x00 },
+		{ ZD_CR251, 0x3f },
 	};
 
 	return zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));
@@ -404,8 +406,8 @@
 {
 	struct zd_chip *chip = zd_rf_to_chip(rf);
 	static const struct zd_ioreq16 ioreqs[] = {
-		{ CR11,  0x00 },
-		{ CR251, 0x7f },
+		{ ZD_CR11,  0x00 },
+		{ ZD_CR251, 0x7f },
 	};
 
 	return zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));
@@ -415,8 +417,8 @@
 {
 	struct zd_chip *chip = zd_rf_to_chip(rf);
 	static const struct zd_ioreq16 ioreqs[] = {
-		{ CR11,  0x04 },
-		{ CR251, 0x2f },
+		{ ZD_CR11,  0x04 },
+		{ ZD_CR251, 0x2f },
 	};
 
 	return zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));
diff -druN linux-2.6.39-libre/drivers/net/wireless/zd1211rw/zd_rf_al7230b.c linux-3.0-rc7-libre/drivers/net/wireless/zd1211rw/zd_rf_al7230b.c
--- linux-2.6.39-libre/drivers/net/wireless/zd1211rw/zd_rf_al7230b.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/zd1211rw/zd_rf_al7230b.c	2011-07-11 19:51:52.000000000 -0400
@@ -68,19 +68,19 @@
 };
 
 static const struct zd_ioreq16 ioreqs_sw[] = {
-	{ CR128, 0x14 }, { CR129, 0x12 }, { CR130, 0x10 },
-	{ CR38,  0x38 }, { CR136, 0xdf },
+	{ ZD_CR128, 0x14 }, { ZD_CR129, 0x12 }, { ZD_CR130, 0x10 },
+	{ ZD_CR38,  0x38 }, { ZD_CR136, 0xdf },
 };
 
 static int zd1211b_al7230b_finalize(struct zd_chip *chip)
 {
 	int r;
 	static const struct zd_ioreq16 ioreqs[] = {
-		{ CR80,  0x30 }, { CR81,  0x30 }, { CR79,  0x58 },
-		{ CR12,  0xf0 }, { CR77,  0x1b }, { CR78,  0x58 },
-		{ CR203, 0x04 },
+		{ ZD_CR80,  0x30 }, { ZD_CR81,  0x30 }, { ZD_CR79,  0x58 },
+		{ ZD_CR12,  0xf0 }, { ZD_CR77,  0x1b }, { ZD_CR78,  0x58 },
+		{ ZD_CR203, 0x04 },
 		{ },
-		{ CR240, 0x80 },
+		{ ZD_CR240, 0x80 },
 	};
 
 	r = zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));
@@ -89,12 +89,12 @@
 
 	if (chip->new_phy_layout) {
 		/* antenna selection? */
-		r = zd_iowrite16_locked(chip, 0xe5, CR9);
+		r = zd_iowrite16_locked(chip, 0xe5, ZD_CR9);
 		if (r)
 			return r;
 	}
 
-	return zd_iowrite16_locked(chip, 0x04, CR203);
+	return zd_iowrite16_locked(chip, 0x04, ZD_CR203);
 }
 
 static int zd1211_al7230b_init_hw(struct zd_rf *rf)
@@ -106,66 +106,66 @@
 	 * specified */
 	static const struct zd_ioreq16 ioreqs_1[] = {
 		/* This one is 7230-specific, and happens before the rest */
-		{ CR240,  0x57 },
+		{ ZD_CR240,  0x57 },
 		{ },
 
-		{ CR15,   0x20 }, { CR23,   0x40 }, { CR24,  0x20 },
-		{ CR26,   0x11 }, { CR28,   0x3e }, { CR29,  0x00 },
-		{ CR44,   0x33 },
+		{ ZD_CR15,   0x20 }, { ZD_CR23,   0x40 }, { ZD_CR24,  0x20 },
+		{ ZD_CR26,   0x11 }, { ZD_CR28,   0x3e }, { ZD_CR29,  0x00 },
+		{ ZD_CR44,   0x33 },
 		/* This value is different for 7230 (was: 0x2a) */
-		{ CR106,  0x22 },
-		{ CR107,  0x1a }, { CR109,  0x09 }, { CR110,  0x27 },
-		{ CR111,  0x2b }, { CR112,  0x2b }, { CR119,  0x0a },
+		{ ZD_CR106,  0x22 },
+		{ ZD_CR107,  0x1a }, { ZD_CR109,  0x09 }, { ZD_CR110,  0x27 },
+		{ ZD_CR111,  0x2b }, { ZD_CR112,  0x2b }, { ZD_CR119,  0x0a },
 		/* This happened further down in AL2230,
 		 * and the value changed (was: 0xe0) */
-		{ CR122,  0xfc },
-		{ CR10,   0x89 },
+		{ ZD_CR122,  0xfc },
+		{ ZD_CR10,   0x89 },
 		/* for newest (3rd cut) AL2300 */
-		{ CR17,   0x28 },
-		{ CR26,   0x93 }, { CR34,   0x30 },
+		{ ZD_CR17,   0x28 },
+		{ ZD_CR26,   0x93 }, { ZD_CR34,   0x30 },
 		/* for newest (3rd cut) AL2300 */
-		{ CR35,   0x3e },
-		{ CR41,   0x24 }, { CR44,   0x32 },
+		{ ZD_CR35,   0x3e },
+		{ ZD_CR41,   0x24 }, { ZD_CR44,   0x32 },
 		/* for newest (3rd cut) AL2300 */
-		{ CR46,   0x96 },
-		{ CR47,   0x1e }, { CR79,   0x58 }, { CR80,  0x30 },
-		{ CR81,   0x30 }, { CR87,   0x0a }, { CR89,  0x04 },
-		{ CR92,   0x0a }, { CR99,   0x28 },
+		{ ZD_CR46,   0x96 },
+		{ ZD_CR47,   0x1e }, { ZD_CR79,   0x58 }, { ZD_CR80,  0x30 },
+		{ ZD_CR81,   0x30 }, { ZD_CR87,   0x0a }, { ZD_CR89,  0x04 },
+		{ ZD_CR92,   0x0a }, { ZD_CR99,   0x28 },
 		/* This value is different for 7230 (was: 0x00) */
-		{ CR100,  0x02 },
-		{ CR101,  0x13 }, { CR102,  0x27 },
+		{ ZD_CR100,  0x02 },
+		{ ZD_CR101,  0x13 }, { ZD_CR102,  0x27 },
 		/* This value is different for 7230 (was: 0x24) */
-		{ CR106,  0x22 },
+		{ ZD_CR106,  0x22 },
 		/* This value is different for 7230 (was: 0x2a) */
-		{ CR107,  0x3f },
-		{ CR109,  0x09 },
+		{ ZD_CR107,  0x3f },
+		{ ZD_CR109,  0x09 },
 		/* This value is different for 7230 (was: 0x13) */
-		{ CR110,  0x1f },
-		{ CR111,  0x1f }, { CR112,  0x1f }, { CR113, 0x27 },
-		{ CR114,  0x27 },
+		{ ZD_CR110,  0x1f },
+		{ ZD_CR111,  0x1f }, { ZD_CR112,  0x1f }, { ZD_CR113, 0x27 },
+		{ ZD_CR114,  0x27 },
 		/* for newest (3rd cut) AL2300 */
-		{ CR115,  0x24 },
+		{ ZD_CR115,  0x24 },
 		/* This value is different for 7230 (was: 0x24) */
-		{ CR116,  0x3f },
+		{ ZD_CR116,  0x3f },
 		/* This value is different for 7230 (was: 0xf4) */
-		{ CR117,  0xfa },
-		{ CR118,  0xfc }, { CR119,  0x10 }, { CR120, 0x4f },
-		{ CR121,  0x77 }, { CR137,  0x88 },
+		{ ZD_CR117,  0xfa },
+		{ ZD_CR118,  0xfc }, { ZD_CR119,  0x10 }, { ZD_CR120, 0x4f },
+		{ ZD_CR121,  0x77 }, { ZD_CR137,  0x88 },
 		/* This one is 7230-specific */
-		{ CR138,  0xa8 },
+		{ ZD_CR138,  0xa8 },
 		/* This value is different for 7230 (was: 0xff) */
-		{ CR252,  0x34 },
+		{ ZD_CR252,  0x34 },
 		/* This value is different for 7230 (was: 0xff) */
-		{ CR253,  0x34 },
+		{ ZD_CR253,  0x34 },
 
 		/* PLL_OFF */
-		{ CR251, 0x2f },
+		{ ZD_CR251, 0x2f },
 	};
 
 	static const struct zd_ioreq16 ioreqs_2[] = {
-		{ CR251, 0x3f }, /* PLL_ON */
-		{ CR128, 0x14 }, { CR129, 0x12 }, { CR130, 0x10 },
-		{ CR38,  0x38 }, { CR136, 0xdf },
+		{ ZD_CR251, 0x3f }, /* PLL_ON */
+		{ ZD_CR128, 0x14 }, { ZD_CR129, 0x12 }, { ZD_CR130, 0x10 },
+		{ ZD_CR38,  0x38 }, { ZD_CR136, 0xdf },
 	};
 
 	r = zd_iowrite16a_locked(chip, ioreqs_1, ARRAY_SIZE(ioreqs_1));
@@ -192,10 +192,10 @@
 	if (r)
 		return r;
 
-	r = zd_iowrite16_locked(chip, 0x06, CR203);
+	r = zd_iowrite16_locked(chip, 0x06, ZD_CR203);
 	if (r)
 		return r;
-	r = zd_iowrite16_locked(chip, 0x80, CR240);
+	r = zd_iowrite16_locked(chip, 0x80, ZD_CR240);
 	if (r)
 		return r;
 
@@ -208,79 +208,79 @@
 	struct zd_chip *chip = zd_rf_to_chip(rf);
 
 	static const struct zd_ioreq16 ioreqs_1[] = {
-		{ CR240, 0x57 }, { CR9,   0x9 },
+		{ ZD_CR240, 0x57 }, { ZD_CR9,   0x9 },
 		{ },
-		{ CR10,  0x8b }, { CR15,  0x20 },
-		{ CR17,  0x2B }, /* for newest (3rd cut) AL2230 */
-		{ CR20,  0x10 }, /* 4N25->Stone Request */
-		{ CR23,  0x40 }, { CR24,  0x20 }, { CR26,  0x93 },
-		{ CR28,  0x3e }, { CR29,  0x00 },
-		{ CR33,  0x28 }, /* 5613 */
-		{ CR34,  0x30 },
-		{ CR35,  0x3e }, /* for newest (3rd cut) AL2230 */
-		{ CR41,  0x24 }, { CR44,  0x32 },
-		{ CR46,  0x99 }, /* for newest (3rd cut) AL2230 */
-		{ CR47,  0x1e },
+		{ ZD_CR10,  0x8b }, { ZD_CR15,  0x20 },
+		{ ZD_CR17,  0x2B }, /* for newest (3rd cut) AL2230 */
+		{ ZD_CR20,  0x10 }, /* 4N25->Stone Request */
+		{ ZD_CR23,  0x40 }, { ZD_CR24,  0x20 }, { ZD_CR26,  0x93 },
+		{ ZD_CR28,  0x3e }, { ZD_CR29,  0x00 },
+		{ ZD_CR33,  0x28 }, /* 5613 */
+		{ ZD_CR34,  0x30 },
+		{ ZD_CR35,  0x3e }, /* for newest (3rd cut) AL2230 */
+		{ ZD_CR41,  0x24 }, { ZD_CR44,  0x32 },
+		{ ZD_CR46,  0x99 }, /* for newest (3rd cut) AL2230 */
+		{ ZD_CR47,  0x1e },
 
 		/* ZD1215 5610 */
-		{ CR48,  0x00 }, { CR49,  0x00 }, { CR51,  0x01 },
-		{ CR52,  0x80 }, { CR53,  0x7e }, { CR65,  0x00 },
-		{ CR66,  0x00 }, { CR67,  0x00 }, { CR68,  0x00 },
-		{ CR69,  0x28 },
+		{ ZD_CR48,  0x00 }, { ZD_CR49,  0x00 }, { ZD_CR51,  0x01 },
+		{ ZD_CR52,  0x80 }, { ZD_CR53,  0x7e }, { ZD_CR65,  0x00 },
+		{ ZD_CR66,  0x00 }, { ZD_CR67,  0x00 }, { ZD_CR68,  0x00 },
+		{ ZD_CR69,  0x28 },
 
-		{ CR79,  0x58 }, { CR80,  0x30 }, { CR81,  0x30 },
-		{ CR87,  0x0A }, { CR89,  0x04 },
-		{ CR90,  0x58 }, /* 5112 */
-		{ CR91,  0x00 }, /* 5613 */
-		{ CR92,  0x0a },
-		{ CR98,  0x8d }, /* 4804, for 1212 new algorithm */
-		{ CR99,  0x00 }, { CR100, 0x02 }, { CR101, 0x13 },
-		{ CR102, 0x27 },
-		{ CR106, 0x20 }, /* change to 0x24 for AL7230B */
-		{ CR109, 0x13 }, /* 4804, for 1212 new algorithm */
-		{ CR112, 0x1f },
+		{ ZD_CR79,  0x58 }, { ZD_CR80,  0x30 }, { ZD_CR81,  0x30 },
+		{ ZD_CR87,  0x0A }, { ZD_CR89,  0x04 },
+		{ ZD_CR90,  0x58 }, /* 5112 */
+		{ ZD_CR91,  0x00 }, /* 5613 */
+		{ ZD_CR92,  0x0a },
+		{ ZD_CR98,  0x8d }, /* 4804, for 1212 new algorithm */
+		{ ZD_CR99,  0x00 }, { ZD_CR100, 0x02 }, { ZD_CR101, 0x13 },
+		{ ZD_CR102, 0x27 },
+		{ ZD_CR106, 0x20 }, /* change to 0x24 for AL7230B */
+		{ ZD_CR109, 0x13 }, /* 4804, for 1212 new algorithm */
+		{ ZD_CR112, 0x1f },
 	};
 
 	static const struct zd_ioreq16 ioreqs_new_phy[] = {
-		{ CR107, 0x28 },
-		{ CR110, 0x1f }, /* 5127, 0x13->0x1f */
-		{ CR111, 0x1f }, /* 0x13 to 0x1f for AL7230B */
-		{ CR116, 0x2a }, { CR118, 0xfa }, { CR119, 0x12 },
-		{ CR121, 0x6c }, /* 5613 */
+		{ ZD_CR107, 0x28 },
+		{ ZD_CR110, 0x1f }, /* 5127, 0x13->0x1f */
+		{ ZD_CR111, 0x1f }, /* 0x13 to 0x1f for AL7230B */
+		{ ZD_CR116, 0x2a }, { ZD_CR118, 0xfa }, { ZD_CR119, 0x12 },
+		{ ZD_CR121, 0x6c }, /* 5613 */
 	};
 
 	static const struct zd_ioreq16 ioreqs_old_phy[] = {
-		{ CR107, 0x24 },
-		{ CR110, 0x13 }, /* 5127, 0x13->0x1f */
-		{ CR111, 0x13 }, /* 0x13 to 0x1f for AL7230B */
-		{ CR116, 0x24 }, { CR118, 0xfc }, { CR119, 0x11 },
-		{ CR121, 0x6a }, /* 5613 */
+		{ ZD_CR107, 0x24 },
+		{ ZD_CR110, 0x13 }, /* 5127, 0x13->0x1f */
+		{ ZD_CR111, 0x13 }, /* 0x13 to 0x1f for AL7230B */
+		{ ZD_CR116, 0x24 }, { ZD_CR118, 0xfc }, { ZD_CR119, 0x11 },
+		{ ZD_CR121, 0x6a }, /* 5613 */
 	};
 
 	static const struct zd_ioreq16 ioreqs_2[] = {
-		{ CR113, 0x27 }, { CR114, 0x27 }, { CR115, 0x24 },
-		{ CR117, 0xfa }, { CR120, 0x4f },
-		{ CR122, 0xfc }, /* E0->FCh at 4901 */
-		{ CR123, 0x57 }, /* 5613 */
-		{ CR125, 0xad }, /* 4804, for 1212 new algorithm */
-		{ CR126, 0x6c }, /* 5613 */
-		{ CR127, 0x03 }, /* 4804, for 1212 new algorithm */
-		{ CR130, 0x10 },
-		{ CR131, 0x00 }, /* 5112 */
-		{ CR137, 0x50 }, /* 5613 */
-		{ CR138, 0xa8 }, /* 5112 */
-		{ CR144, 0xac }, /* 5613 */
-		{ CR148, 0x40 }, /* 5112 */
-		{ CR149, 0x40 }, /* 4O07, 50->40 */
-		{ CR150, 0x1a }, /* 5112, 0C->1A */
-		{ CR252, 0x34 }, { CR253, 0x34 },
-		{ CR251, 0x2f }, /* PLL_OFF */
+		{ ZD_CR113, 0x27 }, { ZD_CR114, 0x27 }, { ZD_CR115, 0x24 },
+		{ ZD_CR117, 0xfa }, { ZD_CR120, 0x4f },
+		{ ZD_CR122, 0xfc }, /* E0->FCh at 4901 */
+		{ ZD_CR123, 0x57 }, /* 5613 */
+		{ ZD_CR125, 0xad }, /* 4804, for 1212 new algorithm */
+		{ ZD_CR126, 0x6c }, /* 5613 */
+		{ ZD_CR127, 0x03 }, /* 4804, for 1212 new algorithm */
+		{ ZD_CR130, 0x10 },
+		{ ZD_CR131, 0x00 }, /* 5112 */
+		{ ZD_CR137, 0x50 }, /* 5613 */
+		{ ZD_CR138, 0xa8 }, /* 5112 */
+		{ ZD_CR144, 0xac }, /* 5613 */
+		{ ZD_CR148, 0x40 }, /* 5112 */
+		{ ZD_CR149, 0x40 }, /* 4O07, 50->40 */
+		{ ZD_CR150, 0x1a }, /* 5112, 0C->1A */
+		{ ZD_CR252, 0x34 }, { ZD_CR253, 0x34 },
+		{ ZD_CR251, 0x2f }, /* PLL_OFF */
 	};
 
 	static const struct zd_ioreq16 ioreqs_3[] = {
-		{ CR251, 0x7f }, /* PLL_ON */
-		{ CR128, 0x14 }, { CR129, 0x12 }, { CR130, 0x10 },
-		{ CR38,  0x38 }, { CR136, 0xdf },
+		{ ZD_CR251, 0x7f }, /* PLL_ON */
+		{ ZD_CR128, 0x14 }, { ZD_CR129, 0x12 }, { ZD_CR130, 0x10 },
+		{ ZD_CR38,  0x38 }, { ZD_CR136, 0xdf },
 	};
 
 	r = zd_iowrite16a_locked(chip, ioreqs_1, ARRAY_SIZE(ioreqs_1));
@@ -331,16 +331,16 @@
 
 	static const struct zd_ioreq16 ioreqs[] = {
 		/* PLL_ON */
-		{ CR251, 0x3f },
-		{ CR203, 0x06 }, { CR240, 0x08 },
+		{ ZD_CR251, 0x3f },
+		{ ZD_CR203, 0x06 }, { ZD_CR240, 0x08 },
 	};
 
-	r = zd_iowrite16_locked(chip, 0x57, CR240);
+	r = zd_iowrite16_locked(chip, 0x57, ZD_CR240);
 	if (r)
 		return r;
 
 	/* PLL_OFF */
-	r = zd_iowrite16_locked(chip, 0x2f, CR251);
+	r = zd_iowrite16_locked(chip, 0x2f, ZD_CR251);
 	if (r)
 		return r;
 
@@ -376,15 +376,15 @@
 	const u32 *rv = chan_rv[channel-1];
 	struct zd_chip *chip = zd_rf_to_chip(rf);
 
-	r = zd_iowrite16_locked(chip, 0x57, CR240);
+	r = zd_iowrite16_locked(chip, 0x57, ZD_CR240);
 	if (r)
 		return r;
-	r = zd_iowrite16_locked(chip, 0xe4, CR9);
+	r = zd_iowrite16_locked(chip, 0xe4, ZD_CR9);
 	if (r)
 		return r;
 
 	/* PLL_OFF */
-	r = zd_iowrite16_locked(chip, 0x2f, CR251);
+	r = zd_iowrite16_locked(chip, 0x2f, ZD_CR251);
 	if (r)
 		return r;
 	r = zd_rfwritev_cr_locked(chip, std_rv, ARRAY_SIZE(std_rv));
@@ -410,7 +410,7 @@
 	if (r)
 		return r;
 
-	r = zd_iowrite16_locked(chip, 0x7f, CR251);
+	r = zd_iowrite16_locked(chip, 0x7f, ZD_CR251);
 	if (r)
 		return r;
 
@@ -421,8 +421,8 @@
 {
 	struct zd_chip *chip = zd_rf_to_chip(rf);
 	static const struct zd_ioreq16 ioreqs[] = {
-		{ CR11,  0x00 },
-		{ CR251, 0x3f },
+		{ ZD_CR11,  0x00 },
+		{ ZD_CR251, 0x3f },
 	};
 
 	return zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));
@@ -432,8 +432,8 @@
 {
 	struct zd_chip *chip = zd_rf_to_chip(rf);
 	static const struct zd_ioreq16 ioreqs[] = {
-		{ CR11,  0x00 },
-		{ CR251, 0x7f },
+		{ ZD_CR11,  0x00 },
+		{ ZD_CR251, 0x7f },
 	};
 
 	return zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));
@@ -443,8 +443,8 @@
 {
 	struct zd_chip *chip = zd_rf_to_chip(rf);
 	static const struct zd_ioreq16 ioreqs[] = {
-		{ CR11,  0x04 },
-		{ CR251, 0x2f },
+		{ ZD_CR11,  0x04 },
+		{ ZD_CR251, 0x2f },
 	};
 
 	return zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));
@@ -456,7 +456,7 @@
 {
 	struct zd_chip *chip = zd_rf_to_chip(rf);
 	struct zd_ioreq16 ioreqs[] = {
-		{ CR128, 0x14 }, { CR129, 0x12 },
+		{ ZD_CR128, 0x14 }, { ZD_CR129, 0x12 },
 	};
 
 	/* FIXME: Channel 11 is not the edge for all regulatory domains. */
diff -druN linux-2.6.39-libre/drivers/net/wireless/zd1211rw/zd_rf.h linux-3.0-rc7-libre/drivers/net/wireless/zd1211rw/zd_rf.h
--- linux-2.6.39-libre/drivers/net/wireless/zd1211rw/zd_rf.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/zd1211rw/zd_rf.h	2011-07-11 19:51:52.000000000 -0400
@@ -55,7 +55,7 @@
 	 * defaults to 1 (yes) */
 	u8 update_channel_int:1;
 
-	/* whether CR47 should be patched from the EEPROM, if the appropriate
+	/* whether ZD_CR47 should be patched from the EEPROM, if the appropriate
 	 * flag is set in the POD. The vendor driver suggests that this should
 	 * be done for all RF's, but a bug in their code prevents but their
 	 * HW_OverWritePhyRegFromE2P() routine from ever taking effect. */
diff -druN linux-2.6.39-libre/drivers/net/wireless/zd1211rw/zd_rf_rf2959.c linux-3.0-rc7-libre/drivers/net/wireless/zd1211rw/zd_rf_rf2959.c
--- linux-2.6.39-libre/drivers/net/wireless/zd1211rw/zd_rf_rf2959.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/zd1211rw/zd_rf_rf2959.c	2011-07-11 19:51:52.000000000 -0400
@@ -152,44 +152,44 @@
 	struct zd_chip *chip = zd_rf_to_chip(rf);
 
 	static const struct zd_ioreq16 ioreqs[] = {
-		{ CR2,   0x1E }, { CR9,   0x20 }, { CR10,  0x89 },
-		{ CR11,  0x00 }, { CR15,  0xD0 }, { CR17,  0x68 },
-		{ CR19,  0x4a }, { CR20,  0x0c }, { CR21,  0x0E },
-		{ CR23,  0x48 },
+		{ ZD_CR2,   0x1E }, { ZD_CR9,   0x20 }, { ZD_CR10,  0x89 },
+		{ ZD_CR11,  0x00 }, { ZD_CR15,  0xD0 }, { ZD_CR17,  0x68 },
+		{ ZD_CR19,  0x4a }, { ZD_CR20,  0x0c }, { ZD_CR21,  0x0E },
+		{ ZD_CR23,  0x48 },
 		/* normal size for cca threshold */
-		{ CR24,  0x14 },
-		/* { CR24,  0x20 }, */
-		{ CR26,  0x90 }, { CR27,  0x30 }, { CR29,  0x20 },
-		{ CR31,  0xb2 }, { CR32,  0x43 }, { CR33,  0x28 },
-		{ CR38,  0x30 }, { CR34,  0x0f }, { CR35,  0xF0 },
-		{ CR41,  0x2a }, { CR46,  0x7F }, { CR47,  0x1E },
-		{ CR51,  0xc5 }, { CR52,  0xc5 }, { CR53,  0xc5 },
-		{ CR79,  0x58 }, { CR80,  0x30 }, { CR81,  0x30 },
-		{ CR82,  0x00 }, { CR83,  0x24 }, { CR84,  0x04 },
-		{ CR85,  0x00 }, { CR86,  0x10 }, { CR87,  0x2A },
-		{ CR88,  0x10 }, { CR89,  0x24 }, { CR90,  0x18 },
-		/* { CR91,  0x18 }, */
+		{ ZD_CR24,  0x14 },
+		/* { ZD_CR24,  0x20 }, */
+		{ ZD_CR26,  0x90 }, { ZD_CR27,  0x30 }, { ZD_CR29,  0x20 },
+		{ ZD_CR31,  0xb2 }, { ZD_CR32,  0x43 }, { ZD_CR33,  0x28 },
+		{ ZD_CR38,  0x30 }, { ZD_CR34,  0x0f }, { ZD_CR35,  0xF0 },
+		{ ZD_CR41,  0x2a }, { ZD_CR46,  0x7F }, { ZD_CR47,  0x1E },
+		{ ZD_CR51,  0xc5 }, { ZD_CR52,  0xc5 }, { ZD_CR53,  0xc5 },
+		{ ZD_CR79,  0x58 }, { ZD_CR80,  0x30 }, { ZD_CR81,  0x30 },
+		{ ZD_CR82,  0x00 }, { ZD_CR83,  0x24 }, { ZD_CR84,  0x04 },
+		{ ZD_CR85,  0x00 }, { ZD_CR86,  0x10 }, { ZD_CR87,  0x2A },
+		{ ZD_CR88,  0x10 }, { ZD_CR89,  0x24 }, { ZD_CR90,  0x18 },
+		/* { ZD_CR91,  0x18 }, */
 		/* should solve continuous CTS frame problems */
-		{ CR91,  0x00 },
-		{ CR92,  0x0a }, { CR93,  0x00 }, { CR94,  0x01 },
-		{ CR95,  0x00 }, { CR96,  0x40 }, { CR97,  0x37 },
-		{ CR98,  0x05 }, { CR99,  0x28 }, { CR100, 0x00 },
-		{ CR101, 0x13 }, { CR102, 0x27 }, { CR103, 0x27 },
-		{ CR104, 0x18 }, { CR105, 0x12 },
+		{ ZD_CR91,  0x00 },
+		{ ZD_CR92,  0x0a }, { ZD_CR93,  0x00 }, { ZD_CR94,  0x01 },
+		{ ZD_CR95,  0x00 }, { ZD_CR96,  0x40 }, { ZD_CR97,  0x37 },
+		{ ZD_CR98,  0x05 }, { ZD_CR99,  0x28 }, { ZD_CR100, 0x00 },
+		{ ZD_CR101, 0x13 }, { ZD_CR102, 0x27 }, { ZD_CR103, 0x27 },
+		{ ZD_CR104, 0x18 }, { ZD_CR105, 0x12 },
 		/* normal size */
-		{ CR106, 0x1a },
-		/* { CR106, 0x22 }, */
-		{ CR107, 0x24 }, { CR108, 0x0a }, { CR109, 0x13 },
-		{ CR110, 0x2F }, { CR111, 0x27 }, { CR112, 0x27 },
-		{ CR113, 0x27 }, { CR114, 0x27 }, { CR115, 0x40 },
-		{ CR116, 0x40 }, { CR117, 0xF0 }, { CR118, 0xF0 },
-		{ CR119, 0x16 },
+		{ ZD_CR106, 0x1a },
+		/* { ZD_CR106, 0x22 }, */
+		{ ZD_CR107, 0x24 }, { ZD_CR108, 0x0a }, { ZD_CR109, 0x13 },
+		{ ZD_CR110, 0x2F }, { ZD_CR111, 0x27 }, { ZD_CR112, 0x27 },
+		{ ZD_CR113, 0x27 }, { ZD_CR114, 0x27 }, { ZD_CR115, 0x40 },
+		{ ZD_CR116, 0x40 }, { ZD_CR117, 0xF0 }, { ZD_CR118, 0xF0 },
+		{ ZD_CR119, 0x16 },
 		/* no TX continuation */
-		{ CR122, 0x00 },
-		/* { CR122, 0xff }, */
-		{ CR127, 0x03 }, { CR131, 0x08 }, { CR138, 0x28 },
-		{ CR148, 0x44 }, { CR150, 0x10 }, { CR169, 0xBB },
-		{ CR170, 0xBB },
+		{ ZD_CR122, 0x00 },
+		/* { ZD_CR122, 0xff }, */
+		{ ZD_CR127, 0x03 }, { ZD_CR131, 0x08 }, { ZD_CR138, 0x28 },
+		{ ZD_CR148, 0x44 }, { ZD_CR150, 0x10 }, { ZD_CR169, 0xBB },
+		{ ZD_CR170, 0xBB },
 	};
 
 	static const u32 rv[] = {
@@ -210,7 +210,7 @@
 		 */
 		0x294128, /* internal power */
 		/* 0x28252c, */ /* External control TX power */
-		/* CR31_CCK, CR51_6-36M, CR52_48M, CR53_54M */
+		/* ZD_CR31_CCK, ZD_CR51_6-36M, ZD_CR52_48M, ZD_CR53_54M */
 		0x2c0000,
 		0x300000,
 		0x340000,  /* REG13(0xD) */
@@ -245,8 +245,8 @@
 static int rf2959_switch_radio_on(struct zd_rf *rf)
 {
 	static const struct zd_ioreq16 ioreqs[] = {
-		{ CR10, 0x89 },
-		{ CR11, 0x00 },
+		{ ZD_CR10, 0x89 },
+		{ ZD_CR11, 0x00 },
 	};
 	struct zd_chip *chip = zd_rf_to_chip(rf);
 
@@ -256,8 +256,8 @@
 static int rf2959_switch_radio_off(struct zd_rf *rf)
 {
 	static const struct zd_ioreq16 ioreqs[] = {
-		{ CR10, 0x15 },
-		{ CR11, 0x81 },
+		{ ZD_CR10, 0x15 },
+		{ ZD_CR11, 0x81 },
 	};
 	struct zd_chip *chip = zd_rf_to_chip(rf);
 
diff -druN linux-2.6.39-libre/drivers/net/wireless/zd1211rw/zd_rf_uw2453.c linux-3.0-rc7-libre/drivers/net/wireless/zd1211rw/zd_rf_uw2453.c
--- linux-2.6.39-libre/drivers/net/wireless/zd1211rw/zd_rf_uw2453.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/zd1211rw/zd_rf_uw2453.c	2011-07-11 19:51:52.000000000 -0400
@@ -314,42 +314,44 @@
 	struct zd_chip *chip = zd_rf_to_chip(rf);
 
 	static const struct zd_ioreq16 ioreqs[] = {
-		{ CR10,  0x89 }, { CR15,  0x20 },
-		{ CR17,  0x28 }, /* 6112 no change */
-		{ CR23,  0x38 }, { CR24,  0x20 }, { CR26,  0x93 },
-		{ CR27,  0x15 }, { CR28,  0x3e }, { CR29,  0x00 },
-		{ CR33,  0x28 }, { CR34,  0x30 },
-		{ CR35,  0x43 }, /* 6112 3e->43 */
-		{ CR41,  0x24 }, { CR44,  0x32 },
-		{ CR46,  0x92 }, /* 6112 96->92 */
-		{ CR47,  0x1e },
-		{ CR48,  0x04 }, /* 5602 Roger */
-		{ CR49,  0xfa }, { CR79,  0x58 }, { CR80,  0x30 },
-		{ CR81,  0x30 }, { CR87,  0x0a }, { CR89,  0x04 },
-		{ CR91,  0x00 }, { CR92,  0x0a }, { CR98,  0x8d },
-		{ CR99,  0x28 }, { CR100, 0x02 },
-		{ CR101, 0x09 }, /* 6112 13->1f 6220 1f->13 6407 13->9 */
-		{ CR102, 0x27 },
-		{ CR106, 0x1c }, /* 5d07 5112 1f->1c 6220 1c->1f 6221 1f->1c */
-		{ CR107, 0x1c }, /* 6220 1c->1a 5221 1a->1c */
-		{ CR109, 0x13 },
-		{ CR110, 0x1f }, /* 6112 13->1f 6221 1f->13 6407 13->0x09 */
-		{ CR111, 0x13 }, { CR112, 0x1f }, { CR113, 0x27 },
-		{ CR114, 0x23 }, /* 6221 27->23 */
-		{ CR115, 0x24 }, /* 6112 24->1c 6220 1c->24 */
-		{ CR116, 0x24 }, /* 6220 1c->24 */
-		{ CR117, 0xfa }, /* 6112 fa->f8 6220 f8->f4 6220 f4->fa */
-		{ CR118, 0xf0 }, /* 5d07 6112 f0->f2 6220 f2->f0 */
-		{ CR119, 0x1a }, /* 6112 1a->10 6220 10->14 6220 14->1a */
-		{ CR120, 0x4f },
-		{ CR121, 0x1f }, /* 6220 4f->1f */
-		{ CR122, 0xf0 }, { CR123, 0x57 }, { CR125, 0xad },
-		{ CR126, 0x6c }, { CR127, 0x03 },
-		{ CR128, 0x14 }, /* 6302 12->11 */
-		{ CR129, 0x12 }, /* 6301 10->0f */
-		{ CR130, 0x10 }, { CR137, 0x50 }, { CR138, 0xa8 },
-		{ CR144, 0xac }, { CR146, 0x20 }, { CR252, 0xff },
-		{ CR253, 0xff },
+		{ ZD_CR10,  0x89 }, { ZD_CR15,  0x20 },
+		{ ZD_CR17,  0x28 }, /* 6112 no change */
+		{ ZD_CR23,  0x38 }, { ZD_CR24,  0x20 }, { ZD_CR26,  0x93 },
+		{ ZD_CR27,  0x15 }, { ZD_CR28,  0x3e }, { ZD_CR29,  0x00 },
+		{ ZD_CR33,  0x28 }, { ZD_CR34,  0x30 },
+		{ ZD_CR35,  0x43 }, /* 6112 3e->43 */
+		{ ZD_CR41,  0x24 }, { ZD_CR44,  0x32 },
+		{ ZD_CR46,  0x92 }, /* 6112 96->92 */
+		{ ZD_CR47,  0x1e },
+		{ ZD_CR48,  0x04 }, /* 5602 Roger */
+		{ ZD_CR49,  0xfa }, { ZD_CR79,  0x58 }, { ZD_CR80,  0x30 },
+		{ ZD_CR81,  0x30 }, { ZD_CR87,  0x0a }, { ZD_CR89,  0x04 },
+		{ ZD_CR91,  0x00 }, { ZD_CR92,  0x0a }, { ZD_CR98,  0x8d },
+		{ ZD_CR99,  0x28 }, { ZD_CR100, 0x02 },
+		{ ZD_CR101, 0x09 }, /* 6112 13->1f 6220 1f->13 6407 13->9 */
+		{ ZD_CR102, 0x27 },
+		{ ZD_CR106, 0x1c }, /* 5d07 5112 1f->1c 6220 1c->1f
+				     * 6221 1f->1c
+				     */
+		{ ZD_CR107, 0x1c }, /* 6220 1c->1a 5221 1a->1c */
+		{ ZD_CR109, 0x13 },
+		{ ZD_CR110, 0x1f }, /* 6112 13->1f 6221 1f->13 6407 13->0x09 */
+		{ ZD_CR111, 0x13 }, { ZD_CR112, 0x1f }, { ZD_CR113, 0x27 },
+		{ ZD_CR114, 0x23 }, /* 6221 27->23 */
+		{ ZD_CR115, 0x24 }, /* 6112 24->1c 6220 1c->24 */
+		{ ZD_CR116, 0x24 }, /* 6220 1c->24 */
+		{ ZD_CR117, 0xfa }, /* 6112 fa->f8 6220 f8->f4 6220 f4->fa */
+		{ ZD_CR118, 0xf0 }, /* 5d07 6112 f0->f2 6220 f2->f0 */
+		{ ZD_CR119, 0x1a }, /* 6112 1a->10 6220 10->14 6220 14->1a */
+		{ ZD_CR120, 0x4f },
+		{ ZD_CR121, 0x1f }, /* 6220 4f->1f */
+		{ ZD_CR122, 0xf0 }, { ZD_CR123, 0x57 }, { ZD_CR125, 0xad },
+		{ ZD_CR126, 0x6c }, { ZD_CR127, 0x03 },
+		{ ZD_CR128, 0x14 }, /* 6302 12->11 */
+		{ ZD_CR129, 0x12 }, /* 6301 10->0f */
+		{ ZD_CR130, 0x10 }, { ZD_CR137, 0x50 }, { ZD_CR138, 0xa8 },
+		{ ZD_CR144, 0xac }, { ZD_CR146, 0x20 }, { ZD_CR252, 0xff },
+		{ ZD_CR253, 0xff },
 	};
 
 	static const u32 rv[] = {
@@ -433,7 +435,7 @@
 	 * the one that produced a lock. */
 	UW2453_PRIV(rf)->config = found_config + 1;
 
-	return zd_iowrite16_locked(chip, 0x06, CR203);
+	return zd_iowrite16_locked(chip, 0x06, ZD_CR203);
 }
 
 static int uw2453_set_channel(struct zd_rf *rf, u8 channel)
@@ -445,8 +447,8 @@
 	struct zd_chip *chip = zd_rf_to_chip(rf);
 
 	static const struct zd_ioreq16 ioreqs[] = {
-		{ CR80,  0x30 }, { CR81,  0x30 }, { CR79,  0x58 },
-		{ CR12,  0xf0 }, { CR77,  0x1b }, { CR78,  0x58 },
+		{ ZD_CR80,  0x30 }, { ZD_CR81,  0x30 }, { ZD_CR79,  0x58 },
+		{ ZD_CR12,  0xf0 }, { ZD_CR77,  0x1b }, { ZD_CR78,  0x58 },
 	};
 
 	r = uw2453_synth_set_channel(chip, channel, autocal);
@@ -474,7 +476,7 @@
 	if (r)
 		return r;
 
-	return zd_iowrite16_locked(chip, 0x06, CR203);
+	return zd_iowrite16_locked(chip, 0x06, ZD_CR203);
 }
 
 static int uw2453_switch_radio_on(struct zd_rf *rf)
@@ -482,7 +484,7 @@
 	int r;
 	struct zd_chip *chip = zd_rf_to_chip(rf);
 	struct zd_ioreq16 ioreqs[] = {
-		{ CR11,  0x00 }, { CR251, 0x3f },
+		{ ZD_CR11,  0x00 }, { ZD_CR251, 0x3f },
 	};
 
 	/* enter RXTX mode */
@@ -501,7 +503,7 @@
 	int r;
 	struct zd_chip *chip = zd_rf_to_chip(rf);
 	static const struct zd_ioreq16 ioreqs[] = {
-		{ CR11,  0x04 }, { CR251, 0x2f },
+		{ ZD_CR11,  0x04 }, { ZD_CR251, 0x2f },
 	};
 
 	/* enter IDLE mode */
diff -druN linux-2.6.39-libre/drivers/net/wireless/zd1211rw/zd_usb.c linux-3.0-rc7-libre/drivers/net/wireless/zd1211rw/zd_usb.c
--- linux-2.6.39-libre/drivers/net/wireless/zd1211rw/zd_usb.c	2011-05-19 02:16:27.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/zd1211rw/zd_usb.c	2011-07-21 06:58:31.000000000 -0400
@@ -1528,6 +1528,31 @@
 module_init(usb_init);
 module_exit(usb_exit);
 
+static int zd_ep_regs_out_msg(struct usb_device *udev, void *data, int len,
+			      int *actual_length, int timeout)
+{
+	/* In USB 2.0 mode EP_REGS_OUT endpoint is interrupt type. However in
+	 * USB 1.1 mode endpoint is bulk. Select correct type URB by endpoint
+	 * descriptor.
+	 */
+	struct usb_host_endpoint *ep;
+	unsigned int pipe;
+
+	pipe = usb_sndintpipe(udev, EP_REGS_OUT);
+	ep = usb_pipe_endpoint(udev, pipe);
+	if (!ep)
+		return -EINVAL;
+
+	if (usb_endpoint_xfer_int(&ep->desc)) {
+		return usb_interrupt_msg(udev, pipe, data, len,
+					 actual_length, timeout);
+	} else {
+		pipe = usb_sndbulkpipe(udev, EP_REGS_OUT);
+		return usb_bulk_msg(udev, pipe, data, len, actual_length,
+				    timeout);
+	}
+}
+
 static int usb_int_regs_length(unsigned int count)
 {
 	return sizeof(struct usb_int_regs) + count * sizeof(struct reg_data);
@@ -1643,15 +1668,14 @@
 
 	udev = zd_usb_to_usbdev(usb);
 	prepare_read_regs_int(usb);
-	r = usb_interrupt_msg(udev, usb_sndintpipe(udev, EP_REGS_OUT),
-			      req, req_len, &actual_req_len, 50 /* ms */);
+	r = zd_ep_regs_out_msg(udev, req, req_len, &actual_req_len, 50 /*ms*/);
 	if (r) {
 		dev_dbg_f(zd_usb_dev(usb),
-			"error in usb_interrupt_msg(). Error number %d\n", r);
+			"error in zd_ep_regs_out_msg(). Error number %d\n", r);
 		goto error;
 	}
 	if (req_len != actual_req_len) {
-		dev_dbg_f(zd_usb_dev(usb), "error in usb_interrupt_msg()\n"
+		dev_dbg_f(zd_usb_dev(usb), "error in zd_ep_regs_out_msg()\n"
 			" req_len %d != actual_req_len %d\n",
 			req_len, actual_req_len);
 		r = -EIO;
@@ -1813,9 +1837,17 @@
 		rw->value = cpu_to_le16(ioreqs[i].value);
 	}
 
-	usb_fill_int_urb(urb, udev, usb_sndintpipe(udev, EP_REGS_OUT),
-			 req, req_len, iowrite16v_urb_complete, usb,
-			 ep->desc.bInterval);
+	/* In USB 2.0 mode endpoint is interrupt type. However in USB 1.1 mode
+	 * endpoint is bulk. Select correct type URB by endpoint descriptor.
+	 */
+	if (usb_endpoint_xfer_int(&ep->desc))
+		usb_fill_int_urb(urb, udev, usb_sndintpipe(udev, EP_REGS_OUT),
+				 req, req_len, iowrite16v_urb_complete, usb,
+				 ep->desc.bInterval);
+	else
+		usb_fill_bulk_urb(urb, udev, usb_sndbulkpipe(udev, EP_REGS_OUT),
+				  req, req_len, iowrite16v_urb_complete, usb);
+
 	urb->transfer_flags |= URB_FREE_BUFFER;
 
 	/* Submit previous URB */
@@ -1888,10 +1920,10 @@
 
 	dev_dbg_f(zd_usb_dev(usb), "value %#09x bits %d\n", value, bits);
 
-	r = zd_usb_ioread16(usb, &bit_value_template, CR203);
+	r = zd_usb_ioread16(usb, &bit_value_template, ZD_CR203);
 	if (r) {
 		dev_dbg_f(zd_usb_dev(usb),
-			"error %d: Couldn't read CR203\n", r);
+			"error %d: Couldn't read ZD_CR203\n", r);
 		return r;
 	}
 	bit_value_template &= ~(RF_IF_LE|RF_CLK|RF_DATA);
@@ -1919,15 +1951,14 @@
 	}
 
 	udev = zd_usb_to_usbdev(usb);
-	r = usb_interrupt_msg(udev, usb_sndintpipe(udev, EP_REGS_OUT),
-			      req, req_len, &actual_req_len, 50 /* ms */);
+	r = zd_ep_regs_out_msg(udev, req, req_len, &actual_req_len, 50 /*ms*/);
 	if (r) {
 		dev_dbg_f(zd_usb_dev(usb),
-			"error in usb_interrupt_msg(). Error number %d\n", r);
+			"error in zd_ep_regs_out_msg(). Error number %d\n", r);
 		goto out;
 	}
 	if (req_len != actual_req_len) {
-		dev_dbg_f(zd_usb_dev(usb), "error in usb_interrupt_msg()"
+		dev_dbg_f(zd_usb_dev(usb), "error in zd_ep_regs_out_msg()"
 			" req_len %d != actual_req_len %d\n",
 			req_len, actual_req_len);
 		r = -EIO;
diff -druN linux-2.6.39-libre/drivers/net/wireless/zd1211rw/zd_usb.h linux-3.0-rc7-libre/drivers/net/wireless/zd1211rw/zd_usb.h
--- linux-2.6.39-libre/drivers/net/wireless/zd1211rw/zd_usb.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/wireless/zd1211rw/zd_usb.h	2011-07-11 19:51:52.000000000 -0400
@@ -109,7 +109,7 @@
 	__le16 bits;
 	/* RF2595: 24 */
 	__le16 bit_values[0];
-	/* (CR203 & ~(RF_IF_LE | RF_CLK | RF_DATA)) | (bit ? RF_DATA : 0) */
+	/* (ZD_CR203 & ~(RF_IF_LE | RF_CLK | RF_DATA)) | (bit ? RF_DATA : 0) */
 } __packed;
 
 /* USB interrupt */
diff -druN linux-2.6.39-libre/drivers/net/xen-netback/common.h linux-3.0-rc7-libre/drivers/net/xen-netback/common.h
--- linux-2.6.39-libre/drivers/net/xen-netback/common.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/xen-netback/common.h	2011-07-11 19:51:52.000000000 -0400
@@ -73,9 +73,6 @@
 	struct vm_struct *tx_comms_area;
 	struct vm_struct *rx_comms_area;
 
-	/* Flags that must not be set in dev->features */
-	u32 features_disabled;
-
 	/* Frontend feature information. */
 	u8 can_sg:1;
 	u8 gso:1;
@@ -109,8 +106,8 @@
 	wait_queue_head_t waiting_to_free;
 };
 
-#define XEN_NETIF_TX_RING_SIZE __RING_SIZE((struct xen_netif_tx_sring *)0, PAGE_SIZE)
-#define XEN_NETIF_RX_RING_SIZE __RING_SIZE((struct xen_netif_rx_sring *)0, PAGE_SIZE)
+#define XEN_NETIF_TX_RING_SIZE __CONST_RING_SIZE(xen_netif_tx, PAGE_SIZE)
+#define XEN_NETIF_RX_RING_SIZE __CONST_RING_SIZE(xen_netif_rx, PAGE_SIZE)
 
 struct xenvif *xenvif_alloc(struct device *parent,
 			    domid_t domid,
diff -druN linux-2.6.39-libre/drivers/net/xen-netback/interface.c linux-3.0-rc7-libre/drivers/net/xen-netback/interface.c
--- linux-2.6.39-libre/drivers/net/xen-netback/interface.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/xen-netback/interface.c	2011-07-11 19:51:52.000000000 -0400
@@ -165,69 +165,18 @@
 	return 0;
 }
 
-static void xenvif_set_features(struct xenvif *vif)
-{
-	struct net_device *dev = vif->dev;
-	u32 features = dev->features;
-
-	if (vif->can_sg)
-		features |= NETIF_F_SG;
-	if (vif->gso || vif->gso_prefix)
-		features |= NETIF_F_TSO;
-	if (vif->csum)
-		features |= NETIF_F_IP_CSUM;
-
-	features &= ~(vif->features_disabled);
-
-	if (!(features & NETIF_F_SG) && dev->mtu > ETH_DATA_LEN)
-		dev->mtu = ETH_DATA_LEN;
-
-	dev->features = features;
-}
-
-static int xenvif_set_tx_csum(struct net_device *dev, u32 data)
-{
-	struct xenvif *vif = netdev_priv(dev);
-	if (data) {
-		if (!vif->csum)
-			return -EOPNOTSUPP;
-		vif->features_disabled &= ~NETIF_F_IP_CSUM;
-	} else {
-		vif->features_disabled |= NETIF_F_IP_CSUM;
-	}
-
-	xenvif_set_features(vif);
-	return 0;
-}
-
-static int xenvif_set_sg(struct net_device *dev, u32 data)
+static u32 xenvif_fix_features(struct net_device *dev, u32 features)
 {
 	struct xenvif *vif = netdev_priv(dev);
-	if (data) {
-		if (!vif->can_sg)
-			return -EOPNOTSUPP;
-		vif->features_disabled &= ~NETIF_F_SG;
-	} else {
-		vif->features_disabled |= NETIF_F_SG;
-	}
-
-	xenvif_set_features(vif);
-	return 0;
-}
 
-static int xenvif_set_tso(struct net_device *dev, u32 data)
-{
-	struct xenvif *vif = netdev_priv(dev);
-	if (data) {
-		if (!vif->gso && !vif->gso_prefix)
-			return -EOPNOTSUPP;
-		vif->features_disabled &= ~NETIF_F_TSO;
-	} else {
-		vif->features_disabled |= NETIF_F_TSO;
-	}
+	if (!vif->can_sg)
+		features &= ~NETIF_F_SG;
+	if (!vif->gso && !vif->gso_prefix)
+		features &= ~NETIF_F_TSO;
+	if (!vif->csum)
+		features &= ~NETIF_F_IP_CSUM;
 
-	xenvif_set_features(vif);
-	return 0;
+	return features;
 }
 
 static const struct xenvif_stat {
@@ -274,12 +223,6 @@
 }
 
 static struct ethtool_ops xenvif_ethtool_ops = {
-	.get_tx_csum	= ethtool_op_get_tx_csum,
-	.set_tx_csum	= xenvif_set_tx_csum,
-	.get_sg		= ethtool_op_get_sg,
-	.set_sg		= xenvif_set_sg,
-	.get_tso	= ethtool_op_get_tso,
-	.set_tso	= xenvif_set_tso,
 	.get_link	= ethtool_op_get_link,
 
 	.get_sset_count = xenvif_get_sset_count,
@@ -293,6 +236,7 @@
 	.ndo_open	= xenvif_open,
 	.ndo_stop	= xenvif_close,
 	.ndo_change_mtu	= xenvif_change_mtu,
+	.ndo_fix_features = xenvif_fix_features,
 };
 
 struct xenvif *xenvif_alloc(struct device *parent, domid_t domid,
@@ -331,7 +275,8 @@
 	vif->credit_timeout.expires = jiffies;
 
 	dev->netdev_ops	= &xenvif_netdev_ops;
-	xenvif_set_features(vif);
+	dev->hw_features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO;
+	dev->features = dev->hw_features;
 	SET_ETHTOOL_OPS(dev, &xenvif_ethtool_ops);
 
 	dev->tx_queue_len = XENVIF_QUEUE_LENGTH;
@@ -367,8 +312,6 @@
 	if (vif->irq)
 		return 0;
 
-	xenvif_set_features(vif);
-
 	err = xen_netbk_map_frontend_rings(vif, tx_ring_ref, rx_ring_ref);
 	if (err < 0)
 		goto err;
@@ -384,9 +327,12 @@
 	xenvif_get(vif);
 
 	rtnl_lock();
-	netif_carrier_on(vif->dev);
 	if (netif_running(vif->dev))
 		xenvif_up(vif);
+	if (!vif->can_sg && vif->dev->mtu > ETH_DATA_LEN)
+		dev_set_mtu(vif->dev, ETH_DATA_LEN);
+	netdev_update_features(vif->dev);
+	netif_carrier_on(vif->dev);
 	rtnl_unlock();
 
 	return 0;
diff -druN linux-2.6.39-libre/drivers/net/xen-netback/xenbus.c linux-3.0-rc7-libre/drivers/net/xen-netback/xenbus.c
--- linux-2.6.39-libre/drivers/net/xen-netback/xenbus.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/xen-netback/xenbus.c	2011-07-11 19:51:52.000000000 -0400
@@ -26,7 +26,7 @@
 	struct xenvif *vif;
 	enum xenbus_state frontend_state;
 	struct xenbus_watch hotplug_status_watch;
-	int have_hotplug_status_watch:1;
+	u8 have_hotplug_status_watch:1;
 };
 
 static int connect_rings(struct backend_info *);
diff -druN linux-2.6.39-libre/drivers/net/xen-netfront.c linux-3.0-rc7-libre/drivers/net/xen-netfront.c
--- linux-2.6.39-libre/drivers/net/xen-netfront.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/net/xen-netfront.c	2011-07-11 19:51:52.000000000 -0400
@@ -1140,6 +1140,42 @@
 	gnttab_free_grant_references(np->gref_rx_head);
 }
 
+static u32 xennet_fix_features(struct net_device *dev, u32 features)
+{
+	struct netfront_info *np = netdev_priv(dev);
+	int val;
+
+	if (features & NETIF_F_SG) {
+		if (xenbus_scanf(XBT_NIL, np->xbdev->otherend, "feature-sg",
+				 "%d", &val) < 0)
+			val = 0;
+
+		if (!val)
+			features &= ~NETIF_F_SG;
+	}
+
+	if (features & NETIF_F_TSO) {
+		if (xenbus_scanf(XBT_NIL, np->xbdev->otherend,
+				 "feature-gso-tcpv4", "%d", &val) < 0)
+			val = 0;
+
+		if (!val)
+			features &= ~NETIF_F_TSO;
+	}
+
+	return features;
+}
+
+static int xennet_set_features(struct net_device *dev, u32 features)
+{
+	if (!(features & NETIF_F_SG) && dev->mtu > ETH_DATA_LEN) {
+		netdev_info(dev, "Reducing MTU because no SG offload");
+		dev->mtu = ETH_DATA_LEN;
+	}
+
+	return 0;
+}
+
 static const struct net_device_ops xennet_netdev_ops = {
 	.ndo_open            = xennet_open,
 	.ndo_uninit          = xennet_uninit,
@@ -1148,6 +1184,8 @@
 	.ndo_change_mtu	     = xennet_change_mtu,
 	.ndo_set_mac_address = eth_mac_addr,
 	.ndo_validate_addr   = eth_validate_addr,
+	.ndo_fix_features    = xennet_fix_features,
+	.ndo_set_features    = xennet_set_features,
 };
 
 static struct net_device * __devinit xennet_create_dev(struct xenbus_device *dev)
@@ -1209,7 +1247,17 @@
 	netdev->netdev_ops	= &xennet_netdev_ops;
 
 	netif_napi_add(netdev, &np->napi, xennet_poll, 64);
-	netdev->features        = NETIF_F_IP_CSUM;
+	netdev->features        = NETIF_F_IP_CSUM | NETIF_F_RXCSUM |
+				  NETIF_F_GSO_ROBUST;
+	netdev->hw_features	= NETIF_F_IP_CSUM | NETIF_F_SG | NETIF_F_TSO;
+
+	/*
+         * Assume that all hw features are available for now. This set
+         * will be adjusted by the call to netdev_update_features() in
+         * xennet_connect() which is the earliest point where we can
+         * negotiate with the backend regarding supported features.
+         */
+	netdev->features |= netdev->hw_features;
 
 	SET_ETHTOOL_OPS(netdev, &xennet_ethtool_ops);
 	SET_NETDEV_DEV(netdev, &dev->dev);
@@ -1416,8 +1464,7 @@
 		goto fail;
 
 	err = bind_evtchn_to_irqhandler(info->evtchn, xennet_interrupt,
-					IRQF_SAMPLE_RANDOM, netdev->name,
-					netdev);
+					0, netdev->name, netdev);
 	if (err < 0)
 		goto fail;
 	netdev->irq = err;
@@ -1510,54 +1557,6 @@
 	return err;
 }
 
-static int xennet_set_sg(struct net_device *dev, u32 data)
-{
-	if (data) {
-		struct netfront_info *np = netdev_priv(dev);
-		int val;
-
-		if (xenbus_scanf(XBT_NIL, np->xbdev->otherend, "feature-sg",
-				 "%d", &val) < 0)
-			val = 0;
-		if (!val)
-			return -ENOSYS;
-	} else if (dev->mtu > ETH_DATA_LEN)
-		dev->mtu = ETH_DATA_LEN;
-
-	return ethtool_op_set_sg(dev, data);
-}
-
-static int xennet_set_tso(struct net_device *dev, u32 data)
-{
-	if (data) {
-		struct netfront_info *np = netdev_priv(dev);
-		int val;
-
-		if (xenbus_scanf(XBT_NIL, np->xbdev->otherend,
-				 "feature-gso-tcpv4", "%d", &val) < 0)
-			val = 0;
-		if (!val)
-			return -ENOSYS;
-	}
-
-	return ethtool_op_set_tso(dev, data);
-}
-
-static void xennet_set_features(struct net_device *dev)
-{
-	/* Turn off all GSO bits except ROBUST. */
-	dev->features &= ~NETIF_F_GSO_MASK;
-	dev->features |= NETIF_F_GSO_ROBUST;
-	xennet_set_sg(dev, 0);
-
-	/* We need checksum offload to enable scatter/gather and TSO. */
-	if (!(dev->features & NETIF_F_IP_CSUM))
-		return;
-
-	if (!xennet_set_sg(dev, 1))
-		xennet_set_tso(dev, 1);
-}
-
 static int xennet_connect(struct net_device *dev)
 {
 	struct netfront_info *np = netdev_priv(dev);
@@ -1582,7 +1581,9 @@
 	if (err)
 		return err;
 
-	xennet_set_features(dev);
+	rtnl_lock();
+	netdev_update_features(dev);
+	rtnl_unlock();
 
 	spin_lock_bh(&np->rx_lock);
 	spin_lock_irq(&np->tx_lock);
@@ -1710,9 +1711,6 @@
 
 static const struct ethtool_ops xennet_ethtool_ops =
 {
-	.set_tx_csum = ethtool_op_set_tx_csum,
-	.set_sg = xennet_set_sg,
-	.set_tso = xennet_set_tso,
 	.get_link = ethtool_op_get_link,
 
 	.get_sset_count = xennet_get_sset_count,
diff -druN linux-2.6.39-libre/drivers/of/fdt.c linux-3.0-rc7-libre/drivers/of/fdt.c
--- linux-2.6.39-libre/drivers/of/fdt.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/of/fdt.c	2011-07-11 19:51:52.000000000 -0400
@@ -670,7 +670,7 @@
 
 	pr_debug("search \"chosen\", depth: %d, uname: %s\n", depth, uname);
 
-	if (depth != 1 ||
+	if (depth != 1 || !data ||
 	    (strcmp(uname, "chosen") != 0 && strcmp(uname, "chosen@0") != 0))
 		return 0;
 
@@ -679,16 +679,16 @@
 	/* Retrieve 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));
+		strlcpy(data, 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);
+		strlcpy(data, CONFIG_CMDLINE, COMMAND_LINE_SIZE);
 #endif /* CONFIG_CMDLINE */
 
-	pr_debug("Command line is: %s\n", cmd_line);
+	pr_debug("Command line is: %s\n", (char*)data);
 
 	/* break now */
 	return 1;
diff -druN linux-2.6.39-libre/drivers/of/irq.c linux-3.0-rc7-libre/drivers/of/irq.c
--- linux-2.6.39-libre/drivers/of/irq.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/of/irq.c	2011-07-11 19:51:52.000000000 -0400
@@ -56,7 +56,7 @@
  * Returns a pointer to the interrupt parent node, or NULL if the interrupt
  * parent could not be determined.
  */
-static struct device_node *of_irq_find_parent(struct device_node *child)
+struct device_node *of_irq_find_parent(struct device_node *child)
 {
 	struct device_node *p;
 	const __be32 *parp;
diff -druN linux-2.6.39-libre/drivers/oprofile/buffer_sync.c linux-3.0-rc7-libre/drivers/oprofile/buffer_sync.c
--- linux-2.6.39-libre/drivers/oprofile/buffer_sync.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/oprofile/buffer_sync.c	2011-07-11 19:51:52.000000000 -0400
@@ -141,6 +141,13 @@
 	.notifier_call = module_load_notify,
 };
 
+static void free_all_tasks(void)
+{
+	/* make sure we don't leak task structs */
+	process_task_mortuary();
+	process_task_mortuary();
+}
+
 int sync_start(void)
 {
 	int err;
@@ -148,8 +155,6 @@
 	if (!zalloc_cpumask_var(&marked_cpus, GFP_KERNEL))
 		return -ENOMEM;
 
-	mutex_lock(&buffer_mutex);
-
 	err = task_handoff_register(&task_free_nb);
 	if (err)
 		goto out1;
@@ -166,7 +171,6 @@
 	start_cpu_work();
 
 out:
-	mutex_unlock(&buffer_mutex);
 	return err;
 out4:
 	profile_event_unregister(PROFILE_MUNMAP, &munmap_nb);
@@ -174,6 +178,7 @@
 	profile_event_unregister(PROFILE_TASK_EXIT, &task_exit_nb);
 out2:
 	task_handoff_unregister(&task_free_nb);
+	free_all_tasks();
 out1:
 	free_cpumask_var(marked_cpus);
 	goto out;
@@ -182,20 +187,16 @@
 
 void sync_stop(void)
 {
-	/* flush buffers */
-	mutex_lock(&buffer_mutex);
 	end_cpu_work();
 	unregister_module_notifier(&module_load_nb);
 	profile_event_unregister(PROFILE_MUNMAP, &munmap_nb);
 	profile_event_unregister(PROFILE_TASK_EXIT, &task_exit_nb);
 	task_handoff_unregister(&task_free_nb);
-	mutex_unlock(&buffer_mutex);
-	flush_cpu_work();
+	barrier();			/* do all of the above first */
 
-	/* make sure we don't leak task structs */
-	process_task_mortuary();
-	process_task_mortuary();
+	flush_cpu_work();
 
+	free_all_tasks();
 	free_cpumask_var(marked_cpus);
 }
 
diff -druN linux-2.6.39-libre/drivers/oprofile/event_buffer.h linux-3.0-rc7-libre/drivers/oprofile/event_buffer.h
--- linux-2.6.39-libre/drivers/oprofile/event_buffer.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/oprofile/event_buffer.h	2011-07-11 19:51:52.000000000 -0400
@@ -11,7 +11,7 @@
 #define EVENT_BUFFER_H
 
 #include <linux/types.h>
-#include <asm/mutex.h>
+#include <linux/mutex.h>
 
 int alloc_event_buffer(void);
 
diff -druN linux-2.6.39-libre/drivers/oprofile/oprof.c linux-3.0-rc7-libre/drivers/oprofile/oprof.c
--- linux-2.6.39-libre/drivers/oprofile/oprof.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/oprofile/oprof.c	2011-07-11 19:51:52.000000000 -0400
@@ -14,7 +14,7 @@
 #include <linux/moduleparam.h>
 #include <linux/workqueue.h>
 #include <linux/time.h>
-#include <asm/mutex.h>
+#include <linux/mutex.h>
 
 #include "oprof.h"
 #include "event_buffer.h"
diff -druN linux-2.6.39-libre/drivers/parport/parport_cs.c linux-3.0-rc7-libre/drivers/parport/parport_cs.c
--- linux-2.6.39-libre/drivers/parport/parport_cs.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/parport/parport_cs.c	2011-07-11 19:51:52.000000000 -0400
@@ -178,7 +178,7 @@
 } /* parport_cs_release */
 
 
-static struct pcmcia_device_id parport_ids[] = {
+static const struct pcmcia_device_id parport_ids[] = {
 	PCMCIA_DEVICE_FUNC_ID(3),
 	PCMCIA_MFC_DEVICE_PROD_ID12(1,"Elan","Serial+Parallel Port: SP230",0x3beb8cf2,0xdb9e58bc),
 	PCMCIA_DEVICE_MANF_CARD(0x0137, 0x0003),
diff -druN linux-2.6.39-libre/drivers/parport/parport_ip32.c linux-3.0-rc7-libre/drivers/parport/parport_ip32.c
--- linux-2.6.39-libre/drivers/parport/parport_ip32.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/parport/parport_ip32.c	2011-07-11 19:51:52.000000000 -0400
@@ -2203,7 +2203,6 @@
 static int __init parport_ip32_init(void)
 {
 	pr_info(PPIP32 "SGI IP32 built-in parallel port driver v0.6\n");
-	pr_debug1(PPIP32 "Compiled on %s, %s\n", __DATE__, __TIME__);
 	this_port = parport_ip32_probe_port();
 	return IS_ERR(this_port) ? PTR_ERR(this_port) : 0;
 }
diff -druN linux-2.6.39-libre/drivers/parport/parport_pc.c linux-3.0-rc7-libre/drivers/parport/parport_pc.c
--- linux-2.6.39-libre/drivers/parport/parport_pc.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/parport/parport_pc.c	2011-07-11 19:51:52.000000000 -0400
@@ -1621,7 +1621,7 @@
 	u8 origval, r;
 	if (verbose_probing)
 		printk(KERN_DEBUG "IT8705 Super-IO detection, now testing port 2E ...\n");
-	if (!request_region(0x2e, 2, __func__))
+	if (!request_muxed_region(0x2e, 2, __func__))
 		return;
 	origval = inb(0x2e);		/* Save original value */
 	outb(0x87, 0x2e);
diff -druN linux-2.6.39-libre/drivers/pci/access.c linux-3.0-rc7-libre/drivers/pci/access.c
--- linux-2.6.39-libre/drivers/pci/access.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/pci/access.c	2011-07-11 19:51:52.000000000 -0400
@@ -143,33 +143,41 @@
 	__remove_wait_queue(&pci_ucfg_wait, &wait);
 }
 
+/* Returns 0 on success, negative values indicate error. */
 #define PCI_USER_READ_CONFIG(size,type)					\
 int pci_user_read_config_##size						\
 	(struct pci_dev *dev, int pos, type *val)			\
 {									\
 	int ret = 0;							\
 	u32 data = -1;							\
-	if (PCI_##size##_BAD) return PCIBIOS_BAD_REGISTER_NUMBER;	\
+	if (PCI_##size##_BAD)						\
+		return -EINVAL;						\
 	raw_spin_lock_irq(&pci_lock);				\
 	if (unlikely(dev->block_ucfg_access)) pci_wait_ucfg(dev);	\
 	ret = dev->bus->ops->read(dev->bus, dev->devfn,			\
 					pos, sizeof(type), &data);	\
 	raw_spin_unlock_irq(&pci_lock);				\
 	*val = (type)data;						\
+	if (ret > 0)							\
+		ret = -EINVAL;						\
 	return ret;							\
 }
 
+/* Returns 0 on success, negative values indicate error. */
 #define PCI_USER_WRITE_CONFIG(size,type)				\
 int pci_user_write_config_##size					\
 	(struct pci_dev *dev, int pos, type val)			\
 {									\
 	int ret = -EIO;							\
-	if (PCI_##size##_BAD) return PCIBIOS_BAD_REGISTER_NUMBER;	\
+	if (PCI_##size##_BAD)						\
+		return -EINVAL;						\
 	raw_spin_lock_irq(&pci_lock);				\
 	if (unlikely(dev->block_ucfg_access)) pci_wait_ucfg(dev);	\
 	ret = dev->bus->ops->write(dev->bus, dev->devfn,		\
 					pos, sizeof(type), val);	\
 	raw_spin_unlock_irq(&pci_lock);				\
+	if (ret > 0)							\
+		ret = -EINVAL;						\
 	return ret;							\
 }
 
@@ -197,6 +205,8 @@
  * This code has to spin since there is no other notification from the PCI
  * hardware. Since the VPD is often implemented by serial attachment to an
  * EEPROM, it may take many milliseconds to complete.
+ *
+ * Returns 0 on success, negative values indicate error.
  */
 static int pci_vpd_pci22_wait(struct pci_dev *dev)
 {
@@ -212,7 +222,7 @@
 	for (;;) {
 		ret = pci_user_read_config_word(dev, vpd->cap + PCI_VPD_ADDR,
 						&status);
-		if (ret)
+		if (ret < 0)
 			return ret;
 
 		if ((status & PCI_VPD_ADDR_F) == vpd->flag) {
@@ -324,6 +334,8 @@
 		vpd->busy = true;
 		vpd->flag = 0;
 		ret = pci_vpd_pci22_wait(dev);
+		if (ret < 0)
+			break;
 
 		pos += sizeof(u32);
 	}
diff -druN linux-2.6.39-libre/drivers/pci/bus.c linux-3.0-rc7-libre/drivers/pci/bus.c
--- linux-2.6.39-libre/drivers/pci/bus.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/pci/bus.c	2011-07-11 19:51:52.000000000 -0400
@@ -163,12 +163,6 @@
 
 	bus->is_added = 1;
 
-	retval = device_create_file(&bus->dev, &dev_attr_cpuaffinity);
-	if (retval)
-		return retval;
-
-	retval = device_create_file(&bus->dev, &dev_attr_cpulistaffinity);
-
 	/* Create legacy_io and legacy_mem files for this bus */
 	pci_create_legacy_files(bus);
 
diff -druN linux-2.6.39-libre/drivers/pci/dmar.c linux-3.0-rc7-libre/drivers/pci/dmar.c
--- linux-2.6.39-libre/drivers/pci/dmar.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/pci/dmar.c	2011-07-11 19:51:52.000000000 -0400
@@ -698,12 +698,7 @@
 	{
 #ifdef CONFIG_INTR_REMAP
 		struct acpi_table_dmar *dmar;
-		/*
-		 * for now we will disable dma-remapping when interrupt
-		 * remapping is enabled.
-		 * When support for queued invalidation for IOTLB invalidation
-		 * is added, we will not need this any more.
-		 */
+
 		dmar = (struct acpi_table_dmar *) dmar_tbl;
 		if (ret && cpu_has_x2apic && dmar->flags & 0x1)
 			printk(KERN_INFO
diff -druN linux-2.6.39-libre/drivers/pci/hotplug/acpiphp_glue.c linux-3.0-rc7-libre/drivers/pci/hotplug/acpiphp_glue.c
--- linux-2.6.39-libre/drivers/pci/hotplug/acpiphp_glue.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/pci/hotplug/acpiphp_glue.c	2011-07-11 19:51:52.000000000 -0400
@@ -827,6 +827,13 @@
 	acpiphp_set_hpp_values(bus);
 	acpiphp_set_acpi_region(slot);
 	pci_enable_bridges(bus);
+
+	list_for_each_entry(dev, &bus->devices, bus_list) {
+		/* Assume that newly added devices are powered on already. */
+		if (!dev->is_added)
+			dev->current_state = PCI_D0;
+	}
+
 	pci_bus_add_devices(bus);
 
 	list_for_each_entry(func, &slot->funcs, sibling) {
diff -druN linux-2.6.39-libre/drivers/pci/hotplug/pcihp_slot.c linux-3.0-rc7-libre/drivers/pci/hotplug/pcihp_slot.c
--- linux-2.6.39-libre/drivers/pci/hotplug/pcihp_slot.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/pci/hotplug/pcihp_slot.c	2011-07-11 19:51:52.000000000 -0400
@@ -158,6 +158,47 @@
 	 */
 }
 
+/* Program PCIE MaxPayload setting on device: ensure parent maxpayload <= device */
+static int pci_set_payload(struct pci_dev *dev)
+{
+       int pos, ppos;
+       u16 pctl, psz;
+       u16 dctl, dsz, dcap, dmax;
+       struct pci_dev *parent;
+
+       parent = dev->bus->self;
+       pos = pci_find_capability(dev, PCI_CAP_ID_EXP);
+       if (!pos)
+               return 0;
+
+       /* Read Device MaxPayload capability and setting */
+       pci_read_config_word(dev, pos + PCI_EXP_DEVCTL, &dctl);
+       pci_read_config_word(dev, pos + PCI_EXP_DEVCAP, &dcap);
+       dsz = (dctl & PCI_EXP_DEVCTL_PAYLOAD) >> 5;
+       dmax = (dcap & PCI_EXP_DEVCAP_PAYLOAD);
+
+       /* Read Parent MaxPayload setting */
+       ppos = pci_find_capability(parent, PCI_CAP_ID_EXP);
+       if (!ppos)
+               return 0;
+       pci_read_config_word(parent, ppos + PCI_EXP_DEVCTL, &pctl);
+       psz = (pctl &  PCI_EXP_DEVCTL_PAYLOAD) >> 5;
+
+       /* If parent payload > device max payload -> error
+        * If parent payload > device payload -> set speed
+        * If parent payload <= device payload -> do nothing
+        */
+       if (psz > dmax)
+               return -1;
+       else if (psz > dsz) {
+               dev_info(&dev->dev, "Setting MaxPayload to %d\n", 128 << psz);
+               pci_write_config_word(dev, pos + PCI_EXP_DEVCTL,
+                                     (dctl & ~PCI_EXP_DEVCTL_PAYLOAD) +
+                                     (psz << 5));
+       }
+       return 0;
+}
+
 void pci_configure_slot(struct pci_dev *dev)
 {
 	struct pci_dev *cdev;
@@ -169,6 +210,10 @@
 			(dev->class >> 8) == PCI_CLASS_BRIDGE_PCI)))
 		return;
 
+       ret = pci_set_payload(dev);
+       if (ret)
+               dev_warn(&dev->dev, "could not set device max payload\n");
+
 	memset(&hpp, 0, sizeof(hpp));
 	ret = pci_get_hp_params(dev, &hpp);
 	if (ret)
diff -druN linux-2.6.39-libre/drivers/pci/intel-iommu.c linux-3.0-rc7-libre/drivers/pci/intel-iommu.c
--- linux-2.6.39-libre/drivers/pci/intel-iommu.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/pci/intel-iommu.c	2011-07-11 19:51:52.000000000 -0400
@@ -39,6 +39,7 @@
 #include <linux/syscore_ops.h>
 #include <linux/tboot.h>
 #include <linux/dmi.h>
+#include <linux/pci-ats.h>
 #include <asm/cacheflush.h>
 #include <asm/iommu.h>
 #include "pci.h"
@@ -46,6 +47,8 @@
 #define ROOT_SIZE		VTD_PAGE_SIZE
 #define CONTEXT_SIZE		VTD_PAGE_SIZE
 
+#define IS_BRIDGE_HOST_DEVICE(pdev) \
+			    ((pdev->class >> 8) == PCI_CLASS_BRIDGE_HOST)
 #define IS_GFX_DEVICE(pdev) ((pdev->class >> 16) == PCI_BASE_CLASS_DISPLAY)
 #define IS_ISA_DEVICE(pdev) ((pdev->class >> 8) == PCI_CLASS_BRIDGE_ISA)
 #define IS_AZALIA(pdev) ((pdev)->vendor == 0x8086 && (pdev)->device == 0x3a3e)
@@ -115,6 +118,11 @@
 	return (pfn + level_size(level) - 1) & level_mask(level);
 }
 
+static inline unsigned long lvl_to_nr_pages(unsigned int lvl)
+{
+	return  1 << ((lvl - 1) * LEVEL_STRIDE);
+}
+
 /* VT-d pages must always be _smaller_ than MM pages. Otherwise things
    are never going to work. */
 static inline unsigned long dma_to_mm_pfn(unsigned long dma_pfn)
@@ -142,6 +150,12 @@
 static int rwbf_quirk;
 
 /*
+ * set to 1 to panic kernel if can't successfully enable VT-d
+ * (used when kernel is launched w/ TXT)
+ */
+static int force_on = 0;
+
+/*
  * 0: Present
  * 1-11: Reserved
  * 12-63: Context Ptr (12 - (haw-1))
@@ -337,6 +351,9 @@
 	int		iommu_coherency;/* indicate coherency of iommu access */
 	int		iommu_snooping; /* indicate snooping control feature*/
 	int		iommu_count;	/* reference count of iommu */
+	int		iommu_superpage;/* Level of superpages supported:
+					   0 == 4KiB (no superpages), 1 == 2MiB,
+					   2 == 1GiB, 3 == 512GiB, 4 == 1TiB */
 	spinlock_t	iommu_lock;	/* protect iommu set in domain */
 	u64		max_addr;	/* maximum mapped address */
 };
@@ -386,6 +403,7 @@
 static int dmar_map_gfx = 1;
 static int dmar_forcedac;
 static int intel_iommu_strict;
+static int intel_iommu_superpage = 1;
 
 #define DUMMY_DEVICE_DOMAIN_INFO ((struct device_domain_info *)(-1))
 static DEFINE_SPINLOCK(device_domain_lock);
@@ -416,6 +434,10 @@
 			printk(KERN_INFO
 				"Intel-IOMMU: disable batched IOTLB flush\n");
 			intel_iommu_strict = 1;
+		} else if (!strncmp(str, "sp_off", 6)) {
+			printk(KERN_INFO
+				"Intel-IOMMU: disable supported super page\n");
+			intel_iommu_superpage = 0;
 		}
 
 		str += strcspn(str, ",");
@@ -554,11 +576,32 @@
 	}
 }
 
+static void domain_update_iommu_superpage(struct dmar_domain *domain)
+{
+	int i, mask = 0xf;
+
+	if (!intel_iommu_superpage) {
+		domain->iommu_superpage = 0;
+		return;
+	}
+
+	domain->iommu_superpage = 4; /* 1TiB */
+
+	for_each_set_bit(i, &domain->iommu_bmp, g_num_of_iommus) {
+		mask |= cap_super_page_val(g_iommus[i]->cap);
+		if (!mask) {
+			break;
+		}
+	}
+	domain->iommu_superpage = fls(mask);
+}
+
 /* Some capabilities may be different across iommus */
 static void domain_update_iommu_cap(struct dmar_domain *domain)
 {
 	domain_update_iommu_coherency(domain);
 	domain_update_iommu_snooping(domain);
+	domain_update_iommu_superpage(domain);
 }
 
 static struct intel_iommu *device_to_iommu(int segment, u8 bus, u8 devfn)
@@ -688,23 +731,31 @@
 }
 
 static struct dma_pte *pfn_to_dma_pte(struct dmar_domain *domain,
-				      unsigned long pfn)
+				      unsigned long pfn, int large_level)
 {
 	int addr_width = agaw_to_width(domain->agaw) - VTD_PAGE_SHIFT;
 	struct dma_pte *parent, *pte = NULL;
 	int level = agaw_to_level(domain->agaw);
-	int offset;
+	int offset, target_level;
 
 	BUG_ON(!domain->pgd);
 	BUG_ON(addr_width < BITS_PER_LONG && pfn >> addr_width);
 	parent = domain->pgd;
 
+	/* Search pte */
+	if (!large_level)
+		target_level = 1;
+	else
+		target_level = large_level;
+
 	while (level > 0) {
 		void *tmp_page;
 
 		offset = pfn_level_offset(pfn, level);
 		pte = &parent[offset];
-		if (level == 1)
+		if (!large_level && (pte->val & DMA_PTE_LARGE_PAGE))
+			break;
+		if (level == target_level)
 			break;
 
 		if (!dma_pte_present(pte)) {
@@ -732,10 +783,11 @@
 	return pte;
 }
 
+
 /* return address's pte at specific level */
 static struct dma_pte *dma_pfn_level_pte(struct dmar_domain *domain,
 					 unsigned long pfn,
-					 int level)
+					 int level, int *large_page)
 {
 	struct dma_pte *parent, *pte = NULL;
 	int total = agaw_to_level(domain->agaw);
@@ -748,8 +800,16 @@
 		if (level == total)
 			return pte;
 
-		if (!dma_pte_present(pte))
+		if (!dma_pte_present(pte)) {
+			*large_page = total;
 			break;
+		}
+
+		if (pte->val & DMA_PTE_LARGE_PAGE) {
+			*large_page = total;
+			return pte;
+		}
+
 		parent = phys_to_virt(dma_pte_addr(pte));
 		total--;
 	}
@@ -762,6 +822,7 @@
 				unsigned long last_pfn)
 {
 	int addr_width = agaw_to_width(domain->agaw) - VTD_PAGE_SHIFT;
+	unsigned int large_page = 1;
 	struct dma_pte *first_pte, *pte;
 
 	BUG_ON(addr_width < BITS_PER_LONG && start_pfn >> addr_width);
@@ -770,14 +831,15 @@
 
 	/* we don't need lock here; nobody else touches the iova range */
 	do {
-		first_pte = pte = dma_pfn_level_pte(domain, start_pfn, 1);
+		large_page = 1;
+		first_pte = pte = dma_pfn_level_pte(domain, start_pfn, 1, &large_page);
 		if (!pte) {
-			start_pfn = align_to_level(start_pfn + 1, 2);
+			start_pfn = align_to_level(start_pfn + 1, large_page + 1);
 			continue;
 		}
-		do { 
+		do {
 			dma_clear_pte(pte);
-			start_pfn++;
+			start_pfn += lvl_to_nr_pages(large_page);
 			pte++;
 		} while (start_pfn <= last_pfn && !first_pte_in_page(pte));
 
@@ -797,6 +859,7 @@
 	int total = agaw_to_level(domain->agaw);
 	int level;
 	unsigned long tmp;
+	int large_page = 2;
 
 	BUG_ON(addr_width < BITS_PER_LONG && start_pfn >> addr_width);
 	BUG_ON(addr_width < BITS_PER_LONG && last_pfn >> addr_width);
@@ -812,7 +875,10 @@
 			return;
 
 		do {
-			first_pte = pte = dma_pfn_level_pte(domain, tmp, level);
+			large_page = level;
+			first_pte = pte = dma_pfn_level_pte(domain, tmp, level, &large_page);
+			if (large_page > level)
+				level = large_page + 1;
 			if (!pte) {
 				tmp = align_to_level(tmp + 1, level + 1);
 				continue;
@@ -1396,6 +1462,7 @@
 	else
 		domain->iommu_snooping = 0;
 
+	domain->iommu_superpage = fls(cap_super_page_val(iommu->cap));
 	domain->iommu_count = 1;
 	domain->nid = iommu->node;
 
@@ -1416,6 +1483,10 @@
 	if (!domain)
 		return;
 
+	/* Flush any lazy unmaps that may reference this domain */
+	if (!intel_iommu_strict)
+		flush_unmaps_timeout(0);
+
 	domain_remove_dev_info(domain);
 	/* destroy iovas */
 	put_iova_domain(&domain->iovad);
@@ -1647,6 +1718,34 @@
 	return PAGE_ALIGN(host_addr + size) >> VTD_PAGE_SHIFT;
 }
 
+/* Return largest possible superpage level for a given mapping */
+static inline int hardware_largepage_caps(struct dmar_domain *domain,
+					  unsigned long iov_pfn,
+					  unsigned long phy_pfn,
+					  unsigned long pages)
+{
+	int support, level = 1;
+	unsigned long pfnmerge;
+
+	support = domain->iommu_superpage;
+
+	/* To use a large page, the virtual *and* physical addresses
+	   must be aligned to 2MiB/1GiB/etc. Lower bits set in either
+	   of them will mean we have to use smaller pages. So just
+	   merge them and check both at once. */
+	pfnmerge = iov_pfn | phy_pfn;
+
+	while (support && !(pfnmerge & ~VTD_STRIDE_MASK)) {
+		pages >>= VTD_STRIDE_SHIFT;
+		if (!pages)
+			break;
+		pfnmerge >>= VTD_STRIDE_SHIFT;
+		level++;
+		support--;
+	}
+	return level;
+}
+
 static int __domain_mapping(struct dmar_domain *domain, unsigned long iov_pfn,
 			    struct scatterlist *sg, unsigned long phys_pfn,
 			    unsigned long nr_pages, int prot)
@@ -1655,6 +1754,8 @@
 	phys_addr_t uninitialized_var(pteval);
 	int addr_width = agaw_to_width(domain->agaw) - VTD_PAGE_SHIFT;
 	unsigned long sg_res;
+	unsigned int largepage_lvl = 0;
+	unsigned long lvl_pages = 0;
 
 	BUG_ON(addr_width < BITS_PER_LONG && (iov_pfn + nr_pages - 1) >> addr_width);
 
@@ -1670,7 +1771,7 @@
 		pteval = ((phys_addr_t)phys_pfn << VTD_PAGE_SHIFT) | prot;
 	}
 
-	while (nr_pages--) {
+	while (nr_pages > 0) {
 		uint64_t tmp;
 
 		if (!sg_res) {
@@ -1678,11 +1779,21 @@
 			sg->dma_address = ((dma_addr_t)iov_pfn << VTD_PAGE_SHIFT) + sg->offset;
 			sg->dma_length = sg->length;
 			pteval = page_to_phys(sg_page(sg)) | prot;
+			phys_pfn = pteval >> VTD_PAGE_SHIFT;
 		}
+
 		if (!pte) {
-			first_pte = pte = pfn_to_dma_pte(domain, iov_pfn);
+			largepage_lvl = hardware_largepage_caps(domain, iov_pfn, phys_pfn, sg_res);
+
+			first_pte = pte = pfn_to_dma_pte(domain, iov_pfn, largepage_lvl);
 			if (!pte)
 				return -ENOMEM;
+			/* It is large page*/
+			if (largepage_lvl > 1)
+				pteval |= DMA_PTE_LARGE_PAGE;
+			else
+				pteval &= ~(uint64_t)DMA_PTE_LARGE_PAGE;
+
 		}
 		/* We don't need lock here, nobody else
 		 * touches the iova range
@@ -1698,16 +1809,38 @@
 			}
 			WARN_ON(1);
 		}
+
+		lvl_pages = lvl_to_nr_pages(largepage_lvl);
+
+		BUG_ON(nr_pages < lvl_pages);
+		BUG_ON(sg_res < lvl_pages);
+
+		nr_pages -= lvl_pages;
+		iov_pfn += lvl_pages;
+		phys_pfn += lvl_pages;
+		pteval += lvl_pages * VTD_PAGE_SIZE;
+		sg_res -= lvl_pages;
+
+		/* If the next PTE would be the first in a new page, then we
+		   need to flush the cache on the entries we've just written.
+		   And then we'll need to recalculate 'pte', so clear it and
+		   let it get set again in the if (!pte) block above.
+
+		   If we're done (!nr_pages) we need to flush the cache too.
+
+		   Also if we've been setting superpages, we may need to
+		   recalculate 'pte' and switch back to smaller pages for the
+		   end of the mapping, if the trailing size is not enough to
+		   use another superpage (i.e. sg_res < lvl_pages). */
 		pte++;
-		if (!nr_pages || first_pte_in_page(pte)) {
+		if (!nr_pages || first_pte_in_page(pte) ||
+		    (largepage_lvl > 1 && sg_res < lvl_pages)) {
 			domain_flush_cache(domain, first_pte,
 					   (void *)pte - (void *)first_pte);
 			pte = NULL;
 		}
-		iov_pfn++;
-		pteval += VTD_PAGE_SIZE;
-		sg_res--;
-		if (!sg_res)
+
+		if (!sg_res && nr_pages)
 			sg = sg_next(sg);
 	}
 	return 0;
@@ -2015,7 +2148,7 @@
 	if (pdev->dev.archdata.iommu == DUMMY_DEVICE_DOMAIN_INFO)
 		return 0;
 	return iommu_prepare_identity_map(pdev, rmrr->base_address,
-		rmrr->end_address + 1);
+		rmrr->end_address);
 }
 
 #ifdef CONFIG_DMAR_FLOPPY_WA
@@ -2029,7 +2162,7 @@
 		return;
 
 	printk(KERN_INFO "IOMMU: Prepare 0-16MiB unity mapping for LPC\n");
-	ret = iommu_prepare_identity_map(pdev, 0, 16*1024*1024);
+	ret = iommu_prepare_identity_map(pdev, 0, 16*1024*1024 - 1);
 
 	if (ret)
 		printk(KERN_ERR "IOMMU: Failed to create 0-16MiB identity map; "
@@ -2105,10 +2238,10 @@
 	if (likely(!iommu_identity_mapping))
 		return 0;
 
+	info = pdev->dev.archdata.iommu;
+	if (info && info != DUMMY_DEVICE_DOMAIN_INFO)
+		return (info->domain == si_domain);
 
-	list_for_each_entry(info, &si_domain->devices, link)
-		if (info->dev == pdev)
-			return 1;
 	return 0;
 }
 
@@ -2186,8 +2319,19 @@
 	 * Assume that they will -- if they turn out not to be, then we can 
 	 * take them out of the 1:1 domain later.
 	 */
-	if (!startup)
-		return pdev->dma_mask > DMA_BIT_MASK(32);
+	if (!startup) {
+		/*
+		 * If the device's dma_mask is less than the system's memory
+		 * size then this is not a candidate for identity mapping.
+		 */
+		u64 dma_mask = pdev->dma_mask;
+
+		if (pdev->dev.coherent_dma_mask &&
+		    pdev->dev.coherent_dma_mask < dma_mask)
+			dma_mask = pdev->dev.coherent_dma_mask;
+
+		return dma_mask >= dma_get_required_mask(&pdev->dev);
+	}
 
 	return 1;
 }
@@ -2202,6 +2346,9 @@
 		return -EFAULT;
 
 	for_each_pci_dev(pdev) {
+		/* Skip Host/PCI Bridge devices */
+		if (IS_BRIDGE_HOST_DEVICE(pdev))
+			continue;
 		if (iommu_should_identity_map(pdev, 1)) {
 			printk(KERN_INFO "IOMMU: %s identity mapping for device %s\n",
 			       hw ? "hardware" : "software", pci_name(pdev));
@@ -2217,7 +2364,7 @@
 	return 0;
 }
 
-static int __init init_dmars(int force_on)
+static int __init init_dmars(void)
 {
 	struct dmar_drhd_unit *drhd;
 	struct dmar_rmrr_unit *rmrr;
@@ -2591,8 +2738,7 @@
 	iommu = domain_get_iommu(domain);
 	size = aligned_nrpages(paddr, size);
 
-	iova = intel_alloc_iova(hwdev, domain, dma_to_mm_pfn(size),
-				pdev->dma_mask);
+	iova = intel_alloc_iova(hwdev, domain, dma_to_mm_pfn(size), dma_mask);
 	if (!iova)
 		goto error;
 
@@ -3117,7 +3263,17 @@
 		if (iommu->qi)
 			dmar_reenable_qi(iommu);
 
-	for_each_active_iommu(iommu, drhd) {
+	for_each_iommu(iommu, drhd) {
+		if (drhd->ignored) {
+			/*
+			 * we always have to disable PMRs or DMA may fail on
+			 * this device
+			 */
+			if (force_on)
+				iommu_disable_protect_mem_regions(iommu);
+			continue;
+		}
+	
 		iommu_flush_write_buffer(iommu);
 
 		iommu_set_root_entry(iommu);
@@ -3126,7 +3282,8 @@
 					   DMA_CCMD_GLOBAL_INVL);
 		iommu->flush.flush_iotlb(iommu, 0, 0, 0,
 					 DMA_TLB_GLOBAL_FLUSH);
-		iommu_enable_translation(iommu);
+		if (iommu_enable_translation(iommu))
+			return 1;
 		iommu_disable_protect_mem_regions(iommu);
 	}
 
@@ -3193,7 +3350,10 @@
 	unsigned long flag;
 
 	if (init_iommu_hw()) {
-		WARN(1, "IOMMU setup failed, DMAR can not resume!\n");
+		if (force_on)
+			panic("tboot: IOMMU setup failed, DMAR can not resume!\n");
+		else
+			WARN(1, "IOMMU setup failed, DMAR can not resume!\n");
 		return;
 	}
 
@@ -3228,7 +3388,7 @@
 }
 
 #else
-static inline int init_iommu_pm_ops(void) { }
+static inline void init_iommu_pm_ops(void) {}
 #endif	/* CONFIG_PM */
 
 /*
@@ -3270,7 +3430,6 @@
 int __init intel_iommu_init(void)
 {
 	int ret = 0;
-	int force_on = 0;
 
 	/* VT-d is required for a TXT/tboot launch, so enforce that */
 	force_on = tboot_force_iommu();
@@ -3308,7 +3467,7 @@
 
 	init_no_remapping_devices();
 
-	ret = init_dmars(force_on);
+	ret = init_dmars();
 	if (ret) {
 		if (force_on)
 			panic("tboot: Failed to initialize DMARs\n");
@@ -3379,8 +3538,8 @@
 	spin_lock_irqsave(&device_domain_lock, flags);
 	list_for_each_safe(entry, tmp, &domain->devices) {
 		info = list_entry(entry, struct device_domain_info, link);
-		/* No need to compare PCI domain; it has to be the same */
-		if (info->bus == pdev->bus->number &&
+		if (info->segment == pci_domain_nr(pdev->bus) &&
+		    info->bus == pdev->bus->number &&
 		    info->devfn == pdev->devfn) {
 			list_del(&info->link);
 			list_del(&info->global);
@@ -3418,10 +3577,13 @@
 		domain_update_iommu_cap(domain);
 		spin_unlock_irqrestore(&domain->iommu_lock, tmp_flags);
 
-		spin_lock_irqsave(&iommu->lock, tmp_flags);
-		clear_bit(domain->id, iommu->domain_ids);
-		iommu->domains[domain->id] = NULL;
-		spin_unlock_irqrestore(&iommu->lock, tmp_flags);
+		if (!(domain->flags & DOMAIN_FLAG_VIRTUAL_MACHINE) &&
+		    !(domain->flags & DOMAIN_FLAG_STATIC_IDENTITY)) {
+			spin_lock_irqsave(&iommu->lock, tmp_flags);
+			clear_bit(domain->id, iommu->domain_ids);
+			iommu->domains[domain->id] = NULL;
+			spin_unlock_irqrestore(&iommu->lock, tmp_flags);
+		}
 	}
 
 	spin_unlock_irqrestore(&device_domain_lock, flags);
@@ -3504,6 +3666,7 @@
 	domain->iommu_count = 0;
 	domain->iommu_coherency = 0;
 	domain->iommu_snooping = 0;
+	domain->iommu_superpage = 0;
 	domain->max_addr = 0;
 	domain->nid = -1;
 
@@ -3719,7 +3882,7 @@
 	struct dma_pte *pte;
 	u64 phys = 0;
 
-	pte = pfn_to_dma_pte(dmar_domain, iova >> VTD_PAGE_SHIFT);
+	pte = pfn_to_dma_pte(dmar_domain, iova >> VTD_PAGE_SHIFT, 0);
 	if (pte)
 		phys = dma_pte_addr(pte);
 
diff -druN linux-2.6.39-libre/drivers/pci/iova.c linux-3.0-rc7-libre/drivers/pci/iova.c
--- linux-2.6.39-libre/drivers/pci/iova.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/pci/iova.c	2011-07-11 19:51:52.000000000 -0400
@@ -63,8 +63,16 @@
 	curr = iovad->cached32_node;
 	cached_iova = container_of(curr, struct iova, node);
 
-	if (free->pfn_lo >= cached_iova->pfn_lo)
-		iovad->cached32_node = rb_next(&free->node);
+	if (free->pfn_lo >= cached_iova->pfn_lo) {
+		struct rb_node *node = rb_next(&free->node);
+		struct iova *iova = container_of(node, struct iova, node);
+
+		/* only cache if it's below 32bit pfn */
+		if (node && iova->pfn_lo < iovad->dma_32bit_pfn)
+			iovad->cached32_node = node;
+		else
+			iovad->cached32_node = NULL;
+	}
 }
 
 /* Computes the padding size required, to make the
diff -druN linux-2.6.39-libre/drivers/pci/iov.c linux-3.0-rc7-libre/drivers/pci/iov.c
--- linux-2.6.39-libre/drivers/pci/iov.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/pci/iov.c	2011-07-11 19:51:52.000000000 -0400
@@ -13,6 +13,7 @@
 #include <linux/mutex.h>
 #include <linux/string.h>
 #include <linux/delay.h>
+#include <linux/pci-ats.h>
 #include "pci.h"
 
 #define VIRTFN_ID_LEN	16
diff -druN linux-2.6.39-libre/drivers/pci/Makefile linux-3.0-rc7-libre/drivers/pci/Makefile
--- linux-2.6.39-libre/drivers/pci/Makefile	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/pci/Makefile	2011-07-11 19:51:52.000000000 -0400
@@ -51,6 +51,7 @@
 obj-$(CONFIG_MN10300) += setup-bus.o
 obj-$(CONFIG_MICROBLAZE) += setup-bus.o
 obj-$(CONFIG_TILE) += setup-bus.o setup-irq.o
+obj-$(CONFIG_SPARC_LEON) += setup-bus.o setup-irq.o
 
 #
 # ACPI Related PCI FW Functions
diff -druN linux-2.6.39-libre/drivers/pci/pci-acpi.c linux-3.0-rc7-libre/drivers/pci/pci-acpi.c
--- linux-2.6.39-libre/drivers/pci/pci-acpi.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/pci/pci-acpi.c	2011-07-11 19:51:52.000000000 -0400
@@ -195,6 +195,8 @@
 		return PCI_D2;
 	case ACPI_STATE_D3:
 		return PCI_D3hot;
+	case ACPI_STATE_D3_COLD:
+		return PCI_D3cold;
 	}
 	return PCI_POWER_ERROR;
 }
diff -druN linux-2.6.39-libre/drivers/pci/pci.c linux-3.0-rc7-libre/drivers/pci/pci.c
--- linux-2.6.39-libre/drivers/pci/pci.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/pci/pci.c	2011-07-11 19:51:52.000000000 -0400
@@ -830,7 +830,7 @@
 		dev_err(&dev->dev, "buffer not found in %s\n", __func__);
 		return -ENOMEM;
 	}
-	cap = (u16 *)&save_state->data[0];
+	cap = (u16 *)&save_state->cap.data[0];
 
 	pci_read_config_word(dev, pos + PCI_EXP_FLAGS, &flags);
 
@@ -863,7 +863,7 @@
 	pos = pci_find_capability(dev, PCI_CAP_ID_EXP);
 	if (!save_state || pos <= 0)
 		return;
-	cap = (u16 *)&save_state->data[0];
+	cap = (u16 *)&save_state->cap.data[0];
 
 	pci_read_config_word(dev, pos + PCI_EXP_FLAGS, &flags);
 
@@ -899,7 +899,8 @@
 		return -ENOMEM;
 	}
 
-	pci_read_config_word(dev, pos + PCI_X_CMD, (u16 *)save_state->data);
+	pci_read_config_word(dev, pos + PCI_X_CMD,
+			     (u16 *)save_state->cap.data);
 
 	return 0;
 }
@@ -914,7 +915,7 @@
 	pos = pci_find_capability(dev, PCI_CAP_ID_PCIX);
 	if (!save_state || pos <= 0)
 		return;
-	cap = (u16 *)&save_state->data[0];
+	cap = (u16 *)&save_state->cap.data[0];
 
 	pci_write_config_word(dev, pos + PCI_X_CMD, cap[i++]);
 }
@@ -975,6 +976,104 @@
 	dev->state_saved = false;
 }
 
+struct pci_saved_state {
+	u32 config_space[16];
+	struct pci_cap_saved_data cap[0];
+};
+
+/**
+ * pci_store_saved_state - Allocate and return an opaque struct containing
+ *			   the device saved state.
+ * @dev: PCI device that we're dealing with
+ *
+ * Rerturn NULL if no state or error.
+ */
+struct pci_saved_state *pci_store_saved_state(struct pci_dev *dev)
+{
+	struct pci_saved_state *state;
+	struct pci_cap_saved_state *tmp;
+	struct pci_cap_saved_data *cap;
+	struct hlist_node *pos;
+	size_t size;
+
+	if (!dev->state_saved)
+		return NULL;
+
+	size = sizeof(*state) + sizeof(struct pci_cap_saved_data);
+
+	hlist_for_each_entry(tmp, pos, &dev->saved_cap_space, next)
+		size += sizeof(struct pci_cap_saved_data) + tmp->cap.size;
+
+	state = kzalloc(size, GFP_KERNEL);
+	if (!state)
+		return NULL;
+
+	memcpy(state->config_space, dev->saved_config_space,
+	       sizeof(state->config_space));
+
+	cap = state->cap;
+	hlist_for_each_entry(tmp, pos, &dev->saved_cap_space, next) {
+		size_t len = sizeof(struct pci_cap_saved_data) + tmp->cap.size;
+		memcpy(cap, &tmp->cap, len);
+		cap = (struct pci_cap_saved_data *)((u8 *)cap + len);
+	}
+	/* Empty cap_save terminates list */
+
+	return state;
+}
+EXPORT_SYMBOL_GPL(pci_store_saved_state);
+
+/**
+ * pci_load_saved_state - Reload the provided save state into struct pci_dev.
+ * @dev: PCI device that we're dealing with
+ * @state: Saved state returned from pci_store_saved_state()
+ */
+int pci_load_saved_state(struct pci_dev *dev, struct pci_saved_state *state)
+{
+	struct pci_cap_saved_data *cap;
+
+	dev->state_saved = false;
+
+	if (!state)
+		return 0;
+
+	memcpy(dev->saved_config_space, state->config_space,
+	       sizeof(state->config_space));
+
+	cap = state->cap;
+	while (cap->size) {
+		struct pci_cap_saved_state *tmp;
+
+		tmp = pci_find_saved_cap(dev, cap->cap_nr);
+		if (!tmp || tmp->cap.size != cap->size)
+			return -EINVAL;
+
+		memcpy(tmp->cap.data, cap->data, tmp->cap.size);
+		cap = (struct pci_cap_saved_data *)((u8 *)cap +
+		       sizeof(struct pci_cap_saved_data) + cap->size);
+	}
+
+	dev->state_saved = true;
+	return 0;
+}
+EXPORT_SYMBOL_GPL(pci_load_saved_state);
+
+/**
+ * pci_load_and_free_saved_state - Reload the save state pointed to by state,
+ *				   and free the memory allocated for it.
+ * @dev: PCI device that we're dealing with
+ * @state: Pointer to saved state returned from pci_store_saved_state()
+ */
+int pci_load_and_free_saved_state(struct pci_dev *dev,
+				  struct pci_saved_state **state)
+{
+	int ret = pci_load_saved_state(dev, *state);
+	kfree(*state);
+	*state = NULL;
+	return ret;
+}
+EXPORT_SYMBOL_GPL(pci_load_and_free_saved_state);
+
 static int do_pci_enable_device(struct pci_dev *dev, int bars)
 {
 	int err;
@@ -1771,7 +1870,8 @@
 	if (!save_state)
 		return -ENOMEM;
 
-	save_state->cap_nr = cap;
+	save_state->cap.cap_nr = cap;
+	save_state->cap.size = size;
 	pci_add_saved_cap(dev, save_state);
 
 	return 0;
@@ -1834,6 +1934,300 @@
 	bridge->ari_enabled = 1;
 }
 
+/**
+ * pci_enable_ido - enable ID-based ordering on a device
+ * @dev: the PCI device
+ * @type: which types of IDO to enable
+ *
+ * Enable ID-based ordering on @dev.  @type can contain the bits
+ * %PCI_EXP_IDO_REQUEST and/or %PCI_EXP_IDO_COMPLETION to indicate
+ * which types of transactions are allowed to be re-ordered.
+ */
+void pci_enable_ido(struct pci_dev *dev, unsigned long type)
+{
+	int pos;
+	u16 ctrl;
+
+	pos = pci_pcie_cap(dev);
+	if (!pos)
+		return;
+
+	pci_read_config_word(dev, pos + PCI_EXP_DEVCTL2, &ctrl);
+	if (type & PCI_EXP_IDO_REQUEST)
+		ctrl |= PCI_EXP_IDO_REQ_EN;
+	if (type & PCI_EXP_IDO_COMPLETION)
+		ctrl |= PCI_EXP_IDO_CMP_EN;
+	pci_write_config_word(dev, pos + PCI_EXP_DEVCTL2, ctrl);
+}
+EXPORT_SYMBOL(pci_enable_ido);
+
+/**
+ * pci_disable_ido - disable ID-based ordering on a device
+ * @dev: the PCI device
+ * @type: which types of IDO to disable
+ */
+void pci_disable_ido(struct pci_dev *dev, unsigned long type)
+{
+	int pos;
+	u16 ctrl;
+
+	if (!pci_is_pcie(dev))
+		return;
+
+	pos = pci_pcie_cap(dev);
+	if (!pos)
+		return;
+
+	pci_read_config_word(dev, pos + PCI_EXP_DEVCTL2, &ctrl);
+	if (type & PCI_EXP_IDO_REQUEST)
+		ctrl &= ~PCI_EXP_IDO_REQ_EN;
+	if (type & PCI_EXP_IDO_COMPLETION)
+		ctrl &= ~PCI_EXP_IDO_CMP_EN;
+	pci_write_config_word(dev, pos + PCI_EXP_DEVCTL2, ctrl);
+}
+EXPORT_SYMBOL(pci_disable_ido);
+
+/**
+ * pci_enable_obff - enable optimized buffer flush/fill
+ * @dev: PCI device
+ * @type: type of signaling to use
+ *
+ * Try to enable @type OBFF signaling on @dev.  It will try using WAKE#
+ * signaling if possible, falling back to message signaling only if
+ * WAKE# isn't supported.  @type should indicate whether the PCIe link
+ * be brought out of L0s or L1 to send the message.  It should be either
+ * %PCI_EXP_OBFF_SIGNAL_ALWAYS or %PCI_OBFF_SIGNAL_L0.
+ *
+ * If your device can benefit from receiving all messages, even at the
+ * power cost of bringing the link back up from a low power state, use
+ * %PCI_EXP_OBFF_SIGNAL_ALWAYS.  Otherwise, use %PCI_OBFF_SIGNAL_L0 (the
+ * preferred type).
+ *
+ * RETURNS:
+ * Zero on success, appropriate error number on failure.
+ */
+int pci_enable_obff(struct pci_dev *dev, enum pci_obff_signal_type type)
+{
+	int pos;
+	u32 cap;
+	u16 ctrl;
+	int ret;
+
+	if (!pci_is_pcie(dev))
+		return -ENOTSUPP;
+
+	pos = pci_pcie_cap(dev);
+	if (!pos)
+		return -ENOTSUPP;
+
+	pci_read_config_dword(dev, pos + PCI_EXP_DEVCAP2, &cap);
+	if (!(cap & PCI_EXP_OBFF_MASK))
+		return -ENOTSUPP; /* no OBFF support at all */
+
+	/* Make sure the topology supports OBFF as well */
+	if (dev->bus) {
+		ret = pci_enable_obff(dev->bus->self, type);
+		if (ret)
+			return ret;
+	}
+
+	pci_read_config_word(dev, pos + PCI_EXP_DEVCTL2, &ctrl);
+	if (cap & PCI_EXP_OBFF_WAKE)
+		ctrl |= PCI_EXP_OBFF_WAKE_EN;
+	else {
+		switch (type) {
+		case PCI_EXP_OBFF_SIGNAL_L0:
+			if (!(ctrl & PCI_EXP_OBFF_WAKE_EN))
+				ctrl |= PCI_EXP_OBFF_MSGA_EN;
+			break;
+		case PCI_EXP_OBFF_SIGNAL_ALWAYS:
+			ctrl &= ~PCI_EXP_OBFF_WAKE_EN;
+			ctrl |= PCI_EXP_OBFF_MSGB_EN;
+			break;
+		default:
+			WARN(1, "bad OBFF signal type\n");
+			return -ENOTSUPP;
+		}
+	}
+	pci_write_config_word(dev, pos + PCI_EXP_DEVCTL2, ctrl);
+
+	return 0;
+}
+EXPORT_SYMBOL(pci_enable_obff);
+
+/**
+ * pci_disable_obff - disable optimized buffer flush/fill
+ * @dev: PCI device
+ *
+ * Disable OBFF on @dev.
+ */
+void pci_disable_obff(struct pci_dev *dev)
+{
+	int pos;
+	u16 ctrl;
+
+	if (!pci_is_pcie(dev))
+		return;
+
+	pos = pci_pcie_cap(dev);
+	if (!pos)
+		return;
+
+	pci_read_config_word(dev, pos + PCI_EXP_DEVCTL2, &ctrl);
+	ctrl &= ~PCI_EXP_OBFF_WAKE_EN;
+	pci_write_config_word(dev, pos + PCI_EXP_DEVCTL2, ctrl);
+}
+EXPORT_SYMBOL(pci_disable_obff);
+
+/**
+ * pci_ltr_supported - check whether a device supports LTR
+ * @dev: PCI device
+ *
+ * RETURNS:
+ * True if @dev supports latency tolerance reporting, false otherwise.
+ */
+bool pci_ltr_supported(struct pci_dev *dev)
+{
+	int pos;
+	u32 cap;
+
+	if (!pci_is_pcie(dev))
+		return false;
+
+	pos = pci_pcie_cap(dev);
+	if (!pos)
+		return false;
+
+	pci_read_config_dword(dev, pos + PCI_EXP_DEVCAP2, &cap);
+
+	return cap & PCI_EXP_DEVCAP2_LTR;
+}
+EXPORT_SYMBOL(pci_ltr_supported);
+
+/**
+ * pci_enable_ltr - enable latency tolerance reporting
+ * @dev: PCI device
+ *
+ * Enable LTR on @dev if possible, which means enabling it first on
+ * upstream ports.
+ *
+ * RETURNS:
+ * Zero on success, errno on failure.
+ */
+int pci_enable_ltr(struct pci_dev *dev)
+{
+	int pos;
+	u16 ctrl;
+	int ret;
+
+	if (!pci_ltr_supported(dev))
+		return -ENOTSUPP;
+
+	pos = pci_pcie_cap(dev);
+	if (!pos)
+		return -ENOTSUPP;
+
+	/* Only primary function can enable/disable LTR */
+	if (PCI_FUNC(dev->devfn) != 0)
+		return -EINVAL;
+
+	/* Enable upstream ports first */
+	if (dev->bus) {
+		ret = pci_enable_ltr(dev->bus->self);
+		if (ret)
+			return ret;
+	}
+
+	pci_read_config_word(dev, pos + PCI_EXP_DEVCTL2, &ctrl);
+	ctrl |= PCI_EXP_LTR_EN;
+	pci_write_config_word(dev, pos + PCI_EXP_DEVCTL2, ctrl);
+
+	return 0;
+}
+EXPORT_SYMBOL(pci_enable_ltr);
+
+/**
+ * pci_disable_ltr - disable latency tolerance reporting
+ * @dev: PCI device
+ */
+void pci_disable_ltr(struct pci_dev *dev)
+{
+	int pos;
+	u16 ctrl;
+
+	if (!pci_ltr_supported(dev))
+		return;
+
+	pos = pci_pcie_cap(dev);
+	if (!pos)
+		return;
+
+	/* Only primary function can enable/disable LTR */
+	if (PCI_FUNC(dev->devfn) != 0)
+		return;
+
+	pci_read_config_word(dev, pos + PCI_EXP_DEVCTL2, &ctrl);
+	ctrl &= ~PCI_EXP_LTR_EN;
+	pci_write_config_word(dev, pos + PCI_EXP_DEVCTL2, ctrl);
+}
+EXPORT_SYMBOL(pci_disable_ltr);
+
+static int __pci_ltr_scale(int *val)
+{
+	int scale = 0;
+
+	while (*val > 1023) {
+		*val = (*val + 31) / 32;
+		scale++;
+	}
+	return scale;
+}
+
+/**
+ * pci_set_ltr - set LTR latency values
+ * @dev: PCI device
+ * @snoop_lat_ns: snoop latency in nanoseconds
+ * @nosnoop_lat_ns: nosnoop latency in nanoseconds
+ *
+ * Figure out the scale and set the LTR values accordingly.
+ */
+int pci_set_ltr(struct pci_dev *dev, int snoop_lat_ns, int nosnoop_lat_ns)
+{
+	int pos, ret, snoop_scale, nosnoop_scale;
+	u16 val;
+
+	if (!pci_ltr_supported(dev))
+		return -ENOTSUPP;
+
+	snoop_scale = __pci_ltr_scale(&snoop_lat_ns);
+	nosnoop_scale = __pci_ltr_scale(&nosnoop_lat_ns);
+
+	if (snoop_lat_ns > PCI_LTR_VALUE_MASK ||
+	    nosnoop_lat_ns > PCI_LTR_VALUE_MASK)
+		return -EINVAL;
+
+	if ((snoop_scale > (PCI_LTR_SCALE_MASK >> PCI_LTR_SCALE_SHIFT)) ||
+	    (nosnoop_scale > (PCI_LTR_SCALE_MASK >> PCI_LTR_SCALE_SHIFT)))
+		return -EINVAL;
+
+	pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_LTR);
+	if (!pos)
+		return -ENOTSUPP;
+
+	val = (snoop_scale << PCI_LTR_SCALE_SHIFT) | snoop_lat_ns;
+	ret = pci_write_config_word(dev, pos + PCI_LTR_MAX_SNOOP_LAT, val);
+	if (ret != 4)
+		return -EIO;
+
+	val = (nosnoop_scale << PCI_LTR_SCALE_SHIFT) | nosnoop_lat_ns;
+	ret = pci_write_config_word(dev, pos + PCI_LTR_MAX_NOSNOOP_LAT, val);
+	if (ret != 4)
+		return -EIO;
+
+	return 0;
+}
+EXPORT_SYMBOL(pci_set_ltr);
+
 static int pci_acs_enable;
 
 /**
@@ -2479,6 +2873,21 @@
 	return 0;
 }
 
+/**
+ * pci_pm_reset - Put device into PCI_D3 and back into PCI_D0.
+ * @dev: Device to reset.
+ * @probe: If set, only check if the device can be reset this way.
+ *
+ * If @dev supports native PCI PM and its PCI_PM_CTRL_NO_SOFT_RESET flag is
+ * unset, it will be reinitialized internally when going from PCI_D3hot to
+ * PCI_D0.  If that's the case and the device is not in a low-power state
+ * already, force it into PCI_D3hot and back to PCI_D0, causing it to be reset.
+ *
+ * NOTE: This causes the caller to sleep for twice the device power transition
+ * cooldown period, which for the D0->D3hot and D3hot->D0 transitions is 10 ms
+ * by devault (i.e. unless the @dev's d3_delay field has a different value).
+ * Moreover, only devices in D0 can be reset by this function.
+ */
 static int pci_pm_reset(struct pci_dev *dev, int probe)
 {
 	u16 csr;
@@ -2862,11 +3271,11 @@
 }
 
 static int pci_set_vga_state_arch(struct pci_dev *dev, bool decode,
-		      unsigned int command_bits, bool change_bridge)
+		      unsigned int command_bits, u32 flags)
 {
 	if (arch_set_vga_state)
 		return arch_set_vga_state(dev, decode, command_bits,
-						change_bridge);
+						flags);
 	return 0;
 }
 
@@ -2875,31 +3284,34 @@
  * @dev: the PCI device
  * @decode: true = enable decoding, false = disable decoding
  * @command_bits: PCI_COMMAND_IO and/or PCI_COMMAND_MEMORY
- * @change_bridge: traverse ancestors and change bridges
+ * @flags: traverse ancestors and change bridges
+ * CHANGE_BRIDGE_ONLY / CHANGE_BRIDGE
  */
 int pci_set_vga_state(struct pci_dev *dev, bool decode,
-		      unsigned int command_bits, bool change_bridge)
+		      unsigned int command_bits, u32 flags)
 {
 	struct pci_bus *bus;
 	struct pci_dev *bridge;
 	u16 cmd;
 	int rc;
 
-	WARN_ON(command_bits & ~(PCI_COMMAND_IO|PCI_COMMAND_MEMORY));
+	WARN_ON((flags & PCI_VGA_STATE_CHANGE_DECODES) & (command_bits & ~(PCI_COMMAND_IO|PCI_COMMAND_MEMORY)));
 
 	/* ARCH specific VGA enables */
-	rc = pci_set_vga_state_arch(dev, decode, command_bits, change_bridge);
+	rc = pci_set_vga_state_arch(dev, decode, command_bits, flags);
 	if (rc)
 		return rc;
 
-	pci_read_config_word(dev, PCI_COMMAND, &cmd);
-	if (decode == true)
-		cmd |= command_bits;
-	else
-		cmd &= ~command_bits;
-	pci_write_config_word(dev, PCI_COMMAND, cmd);
+	if (flags & PCI_VGA_STATE_CHANGE_DECODES) {
+		pci_read_config_word(dev, PCI_COMMAND, &cmd);
+		if (decode == true)
+			cmd |= command_bits;
+		else
+			cmd &= ~command_bits;
+		pci_write_config_word(dev, PCI_COMMAND, cmd);
+	}
 
-	if (change_bridge == false)
+	if (!(flags & PCI_VGA_STATE_CHANGE_BRIDGE))
 		return 0;
 
 	bus = dev->bus;
@@ -3071,6 +3483,8 @@
 				pci_no_msi();
 			} else if (!strcmp(str, "noaer")) {
 				pci_no_aer();
+			} else if (!strncmp(str, "realloc", 7)) {
+				pci_realloc();
 			} else if (!strcmp(str, "nodomains")) {
 				pci_no_domains();
 			} else if (!strncmp(str, "cbiosize=", 9)) {
diff -druN linux-2.6.39-libre/drivers/pci/pci-driver.c linux-3.0-rc7-libre/drivers/pci/pci-driver.c
--- linux-2.6.39-libre/drivers/pci/pci-driver.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/pci/pci-driver.c	2011-07-11 19:51:52.000000000 -0400
@@ -624,7 +624,7 @@
 	 * system from the sleep state, we'll have to prevent it from signaling
 	 * wake-up.
 	 */
-	pm_runtime_resume(dev);
+	pm_runtime_get_sync(dev);
 
 	if (drv && drv->pm && drv->pm->prepare)
 		error = drv->pm->prepare(dev);
@@ -638,6 +638,8 @@
 
 	if (drv && drv->pm && drv->pm->complete)
 		drv->pm->complete(dev);
+
+	pm_runtime_put_sync(dev);
 }
 
 #else /* !CONFIG_PM_SLEEP */
diff -druN linux-2.6.39-libre/drivers/pci/pcie/aer/aerdrv.h linux-3.0-rc7-libre/drivers/pci/pcie/aer/aerdrv.h
--- linux-2.6.39-libre/drivers/pci/pcie/aer/aerdrv.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/pci/pcie/aer/aerdrv.h	2011-07-11 19:51:52.000000000 -0400
@@ -114,15 +114,6 @@
 extern void aer_print_port_info(struct pci_dev *dev, struct aer_err_info *info);
 extern irqreturn_t aer_irq(int irq, void *context);
 
-#ifdef CONFIG_ACPI
-extern int aer_osc_setup(struct pcie_device *pciedev);
-#else
-static inline int aer_osc_setup(struct pcie_device *pciedev)
-{
-	return 0;
-}
-#endif
-
 #ifdef CONFIG_ACPI_APEI
 extern int pcie_aer_get_firmware_first(struct pci_dev *pci_dev);
 #else
diff -druN linux-2.6.39-libre/drivers/pci/pcie/aer/aer_inject.c linux-3.0-rc7-libre/drivers/pci/pcie/aer/aer_inject.c
--- linux-2.6.39-libre/drivers/pci/pcie/aer/aer_inject.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/pci/pcie/aer/aer_inject.c	2011-07-11 19:51:52.000000000 -0400
@@ -326,7 +326,7 @@
 	unsigned long flags;
 	unsigned int devfn = PCI_DEVFN(einj->dev, einj->fn);
 	int pos_cap_err, rp_pos_cap_err;
-	u32 sever, cor_mask, uncor_mask, cor_mask_orig, uncor_mask_orig;
+	u32 sever, cor_mask, uncor_mask, cor_mask_orig = 0, uncor_mask_orig = 0;
 	int ret = 0;
 
 	dev = pci_get_domain_bus_and_slot((int)einj->domain, einj->bus, devfn);
diff -druN linux-2.6.39-libre/drivers/pci/pcie/aspm.c linux-3.0-rc7-libre/drivers/pci/pcie/aspm.c
--- linux-2.6.39-libre/drivers/pci/pcie/aspm.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/pci/pcie/aspm.c	2011-07-11 19:51:52.000000000 -0400
@@ -608,7 +608,7 @@
 	 * the BIOS's expectation, we'll do so once pci_enable_device() is
 	 * called.
 	 */
-	if (aspm_policy != POLICY_POWERSAVE) {
+	if (aspm_policy != POLICY_POWERSAVE || aspm_clear_state) {
 		pcie_config_aspm_path(link);
 		pcie_set_clkpm(link, policy_to_clkpm_state(link));
 	}
@@ -734,7 +734,7 @@
  * pci_disable_link_state - disable pci device's link state, so the link will
  * never enter specific states
  */
-void pci_disable_link_state(struct pci_dev *pdev, int state)
+static void __pci_disable_link_state(struct pci_dev *pdev, int state, bool sem)
 {
 	struct pci_dev *parent = pdev->bus->self;
 	struct pcie_link_state *link;
@@ -747,7 +747,8 @@
 	if (!parent || !parent->link_state)
 		return;
 
-	down_read(&pci_bus_sem);
+	if (sem)
+		down_read(&pci_bus_sem);
 	mutex_lock(&aspm_lock);
 	link = parent->link_state;
 	if (state & PCIE_LINK_STATE_L0S)
@@ -761,7 +762,19 @@
 		pcie_set_clkpm(link, 0);
 	}
 	mutex_unlock(&aspm_lock);
-	up_read(&pci_bus_sem);
+	if (sem)
+		up_read(&pci_bus_sem);
+}
+
+void pci_disable_link_state_locked(struct pci_dev *pdev, int state)
+{
+	__pci_disable_link_state(pdev, state, false);
+}
+EXPORT_SYMBOL(pci_disable_link_state_locked);
+
+void pci_disable_link_state(struct pci_dev *pdev, int state)
+{
+	__pci_disable_link_state(pdev, state, true);
 }
 EXPORT_SYMBOL(pci_disable_link_state);
 
diff -druN linux-2.6.39-libre/drivers/pci/pci.h linux-3.0-rc7-libre/drivers/pci/pci.h
--- linux-2.6.39-libre/drivers/pci/pci.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/pci/pci.h	2011-07-11 19:51:52.000000000 -0400
@@ -146,6 +146,8 @@
 static inline void pci_msi_init_pci_dev(struct pci_dev *dev) { }
 #endif
 
+extern void pci_realloc(void);
+
 static inline int pci_no_d1d2(struct pci_dev *dev)
 {
 	unsigned int parent_dstates = 0;
@@ -156,8 +158,7 @@
 
 }
 extern struct device_attribute pci_dev_attrs[];
-extern struct device_attribute dev_attr_cpuaffinity;
-extern struct device_attribute dev_attr_cpulistaffinity;
+extern struct device_attribute pcibus_dev_attrs[];
 #ifdef CONFIG_HOTPLUG
 extern struct bus_attribute pci_bus_attrs[];
 #else
@@ -250,15 +251,6 @@
 	u8 __iomem *mstate;	/* VF Migration State Array */
 };
 
-/* Address Translation Service */
-struct pci_ats {
-	int pos;	/* capability position */
-	int stu;	/* Smallest Translation Unit */
-	int qdep;	/* Invalidate Queue Depth */
-	int ref_cnt;	/* Physical Function reference count */
-	unsigned int is_enabled:1;	/* Enable bit is set */
-};
-
 #ifdef CONFIG_PCI_IOV
 extern int pci_iov_init(struct pci_dev *dev);
 extern void pci_iov_release(struct pci_dev *dev);
@@ -269,19 +261,6 @@
 extern void pci_restore_iov_state(struct pci_dev *dev);
 extern int pci_iov_bus_range(struct pci_bus *bus);
 
-extern int pci_enable_ats(struct pci_dev *dev, int ps);
-extern void pci_disable_ats(struct pci_dev *dev);
-extern int pci_ats_queue_depth(struct pci_dev *dev);
-/**
- * pci_ats_enabled - query the ATS status
- * @dev: the PCI device
- *
- * Returns 1 if ATS capability is enabled, or 0 if not.
- */
-static inline int pci_ats_enabled(struct pci_dev *dev)
-{
-	return dev->ats && dev->ats->is_enabled;
-}
 #else
 static inline int pci_iov_init(struct pci_dev *dev)
 {
@@ -304,21 +283,6 @@
 	return 0;
 }
 
-static inline int pci_enable_ats(struct pci_dev *dev, int ps)
-{
-	return -ENODEV;
-}
-static inline void pci_disable_ats(struct pci_dev *dev)
-{
-}
-static inline int pci_ats_queue_depth(struct pci_dev *dev)
-{
-	return -ENODEV;
-}
-static inline int pci_ats_enabled(struct pci_dev *dev)
-{
-	return 0;
-}
 #endif /* CONFIG_PCI_IOV */
 
 static inline resource_size_t pci_resource_alignment(struct pci_dev *dev,
diff -druN linux-2.6.39-libre/drivers/pci/pci-sysfs.c linux-3.0-rc7-libre/drivers/pci/pci-sysfs.c
--- linux-2.6.39-libre/drivers/pci/pci-sysfs.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/pci/pci-sysfs.c	2011-07-11 19:51:52.000000000 -0400
@@ -108,6 +108,40 @@
 	return len;
 }
 
+/*
+ * PCI Bus Class Devices
+ */
+static ssize_t pci_bus_show_cpuaffinity(struct device *dev,
+					int type,
+					struct device_attribute *attr,
+					char *buf)
+{
+	int ret;
+	const struct cpumask *cpumask;
+
+	cpumask = cpumask_of_pcibus(to_pci_bus(dev));
+	ret = type ?
+		cpulist_scnprintf(buf, PAGE_SIZE-2, cpumask) :
+		cpumask_scnprintf(buf, PAGE_SIZE-2, cpumask);
+	buf[ret++] = '\n';
+	buf[ret] = '\0';
+	return ret;
+}
+
+static inline ssize_t pci_bus_show_cpumaskaffinity(struct device *dev,
+					struct device_attribute *attr,
+					char *buf)
+{
+	return pci_bus_show_cpuaffinity(dev, 0, attr, buf);
+}
+
+static inline ssize_t pci_bus_show_cpulistaffinity(struct device *dev,
+					struct device_attribute *attr,
+					char *buf)
+{
+	return pci_bus_show_cpuaffinity(dev, 1, attr, buf);
+}
+
 /* show resources */
 static ssize_t
 resource_show(struct device * dev, struct device_attribute *attr, char * buf)
@@ -318,6 +352,25 @@
 		count = ret;
 	return count;
 }
+
+static ssize_t
+dev_bus_rescan_store(struct device *dev, struct device_attribute *attr,
+		 const char *buf, size_t count)
+{
+	unsigned long val;
+	struct pci_bus *bus = to_pci_bus(dev);
+
+	if (strict_strtoul(buf, 0, &val) < 0)
+		return -EINVAL;
+
+	if (val) {
+		mutex_lock(&pci_remove_rescan_mutex);
+		pci_rescan_bus(bus);
+		mutex_unlock(&pci_remove_rescan_mutex);
+	}
+	return count;
+}
+
 #endif
 
 struct device_attribute pci_dev_attrs[] = {
@@ -347,6 +400,15 @@
 	__ATTR_NULL,
 };
 
+struct device_attribute pcibus_dev_attrs[] = {
+#ifdef CONFIG_HOTPLUG
+	__ATTR(rescan, (S_IWUSR|S_IWGRP), NULL, dev_bus_rescan_store),
+#endif
+	__ATTR(cpuaffinity, S_IRUGO, pci_bus_show_cpumaskaffinity, NULL),
+	__ATTR(cpulistaffinity, S_IRUGO, pci_bus_show_cpulistaffinity, NULL),
+	__ATTR_NULL,
+};
+
 static ssize_t
 boot_vga_show(struct device *dev, struct device_attribute *attr, char *buf)
 {
diff -druN linux-2.6.39-libre/drivers/pci/probe.c linux-3.0-rc7-libre/drivers/pci/probe.c
--- linux-2.6.39-libre/drivers/pci/probe.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/pci/probe.c	2011-07-11 19:51:52.000000000 -0400
@@ -43,43 +43,6 @@
 EXPORT_SYMBOL(no_pci_devices);
 
 /*
- * PCI Bus Class Devices
- */
-static ssize_t pci_bus_show_cpuaffinity(struct device *dev,
-					int type,
-					struct device_attribute *attr,
-					char *buf)
-{
-	int ret;
-	const struct cpumask *cpumask;
-
-	cpumask = cpumask_of_pcibus(to_pci_bus(dev));
-	ret = type?
-		cpulist_scnprintf(buf, PAGE_SIZE-2, cpumask) :
-		cpumask_scnprintf(buf, PAGE_SIZE-2, cpumask);
-	buf[ret++] = '\n';
-	buf[ret] = '\0';
-	return ret;
-}
-
-static ssize_t inline pci_bus_show_cpumaskaffinity(struct device *dev,
-					struct device_attribute *attr,
-					char *buf)
-{
-	return pci_bus_show_cpuaffinity(dev, 0, attr, buf);
-}
-
-static ssize_t inline pci_bus_show_cpulistaffinity(struct device *dev,
-					struct device_attribute *attr,
-					char *buf)
-{
-	return pci_bus_show_cpuaffinity(dev, 1, attr, buf);
-}
-
-DEVICE_ATTR(cpuaffinity,     S_IRUGO, pci_bus_show_cpumaskaffinity, NULL);
-DEVICE_ATTR(cpulistaffinity, S_IRUGO, pci_bus_show_cpulistaffinity, NULL);
-
-/*
  * PCI Bus Class
  */
 static void release_pcibus_dev(struct device *dev)
@@ -95,6 +58,7 @@
 static struct class pcibus_class = {
 	.name		= "pci_bus",
 	.dev_release	= &release_pcibus_dev,
+	.dev_attrs	= pcibus_dev_attrs,
 };
 
 static int __init pcibus_class_init(void)
@@ -204,7 +168,7 @@
 		res->flags |= pci_calc_resource_flags(l) | IORESOURCE_SIZEALIGN;
 		if (type == pci_bar_io) {
 			l &= PCI_BASE_ADDRESS_IO_MASK;
-			mask = PCI_BASE_ADDRESS_IO_MASK & IO_SPACE_LIMIT;
+			mask = PCI_BASE_ADDRESS_IO_MASK & (u32) IO_SPACE_LIMIT;
 		} else {
 			l &= PCI_BASE_ADDRESS_MEM_MASK;
 			mask = (u32)PCI_BASE_ADDRESS_MEM_MASK;
@@ -1455,9 +1419,6 @@
 	error = device_register(&b->dev);
 	if (error)
 		goto class_dev_reg_err;
-	error = device_create_file(&b->dev, &dev_attr_cpuaffinity);
-	if (error)
-		goto dev_create_file_err;
 
 	/* Create legacy_io and legacy_mem files for this bus */
 	pci_create_legacy_files(b);
@@ -1468,8 +1429,6 @@
 
 	return b;
 
-dev_create_file_err:
-	device_unregister(&b->dev);
 class_dev_reg_err:
 	device_unregister(dev);
 dev_reg_err:
diff -druN linux-2.6.39-libre/drivers/pci/quirks.c linux-3.0-rc7-libre/drivers/pci/quirks.c
--- linux-2.6.39-libre/drivers/pci/quirks.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/pci/quirks.c	2011-07-11 19:51:52.000000000 -0400
@@ -606,7 +606,7 @@
 	}
 
 	pci_read_config_byte(dev, ICH6_GPIO_CNTL, &enable);
-	if (enable & ICH4_GPIO_EN) {
+	if (enable & ICH6_GPIO_EN) {
 		pci_read_config_dword(dev, ICH6_GPIOBASE, &region);
 		region &= PCI_BASE_ADDRESS_IO_MASK;
 		if (region >= PCIBIOS_MIN_IO)
@@ -681,7 +681,7 @@
 /* ICH7-10 has the same common LPC generic IO decode registers */
 static void __devinit quirk_ich7_lpc(struct pci_dev *dev)
 {
-	/* We share the common ACPI/DPIO decode with ICH6 */
+	/* We share the common ACPI/GPIO decode with ICH6 */
 	ich6_lpc_acpi_gpio(dev);
 
 	/* And have 4 ICH7+ generic decodes */
@@ -2349,8 +2349,11 @@
  */
 static void __devinit nvenet_msi_disable(struct pci_dev *dev)
 {
-	if (dmi_name_in_vendors("P5N32-SLI PREMIUM") ||
-	    dmi_name_in_vendors("P5N32-E SLI")) {
+	const char *board_name = dmi_get_system_info(DMI_BOARD_NAME);
+
+	if (board_name &&
+	    (strstr(board_name, "P5N32-SLI PREMIUM") ||
+	     strstr(board_name, "P5N32-E SLI"))) {
 		dev_info(&dev->dev,
 			 "Disabling msi for MCP55 NIC on P5N32-SLI\n");
 		dev->no_msi = 1;
@@ -2758,6 +2761,8 @@
 }
 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);
+DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_R5CE823, ricoh_mmc_fixup_r5c832);
+DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_R5CE823, ricoh_mmc_fixup_r5c832);
 #endif /*CONFIG_MMC_RICOH_MMC*/
 
 #if defined(CONFIG_DMAR) || defined(CONFIG_INTR_REMAP)
@@ -2784,6 +2789,16 @@
 DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x3c28, vtd_mask_spec_errors);
 #endif
 
+static void __devinit fixup_ti816x_class(struct pci_dev* dev)
+{
+	/* TI 816x devices do not have class code set when in PCIe boot mode */
+	if (dev->class == PCI_CLASS_NOT_DEFINED) {
+		dev_info(&dev->dev, "Setting PCI class for 816x PCIe device\n");
+		dev->class = PCI_CLASS_MULTIMEDIA_VIDEO;
+	}
+}
+DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_TI, 0xb800, fixup_ti816x_class);
+
 static void pci_do_fixups(struct pci_dev *dev, struct pci_fixup *f,
 			  struct pci_fixup *end)
 {
diff -druN linux-2.6.39-libre/drivers/pci/remove.c linux-3.0-rc7-libre/drivers/pci/remove.c
--- linux-2.6.39-libre/drivers/pci/remove.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/pci/remove.c	2011-07-11 19:51:52.000000000 -0400
@@ -73,8 +73,6 @@
 		return;
 
 	pci_remove_legacy_files(pci_bus);
-	device_remove_file(&pci_bus->dev, &dev_attr_cpuaffinity);
-	device_remove_file(&pci_bus->dev, &dev_attr_cpulistaffinity);
 	device_unregister(&pci_bus->dev);
 }
 EXPORT_SYMBOL(pci_remove_bus);
diff -druN linux-2.6.39-libre/drivers/pci/setup-bus.c linux-3.0-rc7-libre/drivers/pci/setup-bus.c
--- linux-2.6.39-libre/drivers/pci/setup-bus.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/pci/setup-bus.c	2011-07-11 19:51:52.000000000 -0400
@@ -47,6 +47,13 @@
 	(head)->next = NULL;				\
 } while (0)
 
+int pci_realloc_enable = 0;
+#define pci_realloc_enabled() pci_realloc_enable
+void pci_realloc(void)
+{
+	pci_realloc_enable = 1;
+}
+
 /**
  * add_to_list() - add a new resource tracker to the list
  * @head:	Head of the list
@@ -991,30 +998,147 @@
 	}
 }
 
+static int __init pci_bus_get_depth(struct pci_bus *bus)
+{
+	int depth = 0;
+	struct pci_dev *dev;
+
+	list_for_each_entry(dev, &bus->devices, bus_list) {
+		int ret;
+		struct pci_bus *b = dev->subordinate;
+		if (!b)
+			continue;
+
+		ret = pci_bus_get_depth(b);
+		if (ret + 1 > depth)
+			depth = ret + 1;
+	}
+
+	return depth;
+}
+static int __init pci_get_max_depth(void)
+{
+	int depth = 0;
+	struct pci_bus *bus;
+
+	list_for_each_entry(bus, &pci_root_buses, node) {
+		int ret;
+
+		ret = pci_bus_get_depth(bus);
+		if (ret > depth)
+			depth = ret;
+	}
+
+	return depth;
+}
+
+
+/*
+ * first try will not touch pci bridge res
+ * second  and later try will clear small leaf bridge res
+ * will stop till to the max  deepth if can not find good one
+ */
 void __init
 pci_assign_unassigned_resources(void)
 {
 	struct pci_bus *bus;
 	struct resource_list_x add_list; /* list of resources that
 					want additional resources */
+	int tried_times = 0;
+	enum release_type rel_type = leaf_only;
+	struct resource_list_x head, *list;
+	unsigned long type_mask = IORESOURCE_IO | IORESOURCE_MEM |
+				  IORESOURCE_PREFETCH;
+	unsigned long failed_type;
+	int max_depth = pci_get_max_depth();
+	int pci_try_num;
+
+
+	head.next = NULL;
 	add_list.next = NULL;
+
+	pci_try_num = max_depth + 1;
+	printk(KERN_DEBUG "PCI: max bus depth: %d pci_try_num: %d\n",
+		 max_depth, pci_try_num);
+
+again:
 	/* Depth first, calculate sizes and alignments of all
 	   subordinate buses. */
-	list_for_each_entry(bus, &pci_root_buses, node) {
+	list_for_each_entry(bus, &pci_root_buses, node)
 		__pci_bus_size_bridges(bus, &add_list);
-	}
 
 	/* Depth last, allocate resources and update the hardware. */
-	list_for_each_entry(bus, &pci_root_buses, node) {
-		__pci_bus_assign_resources(bus, &add_list, NULL);
-		pci_enable_bridges(bus);
-	}
+	list_for_each_entry(bus, &pci_root_buses, node)
+		__pci_bus_assign_resources(bus, &add_list, &head);
 	BUG_ON(add_list.next);
+	tried_times++;
+
+	/* any device complain? */
+	if (!head.next)
+		goto enable_and_dump;
+
+	/* don't realloc if asked to do so */
+	if (!pci_realloc_enabled()) {
+		free_list(resource_list_x, &head);
+		goto enable_and_dump;
+	}
+
+	failed_type = 0;
+	for (list = head.next; list;) {
+		failed_type |= list->flags;
+		list = list->next;
+	}
+	/*
+	 * io port are tight, don't try extra
+	 * or if reach the limit, don't want to try more
+	 */
+	failed_type &= type_mask;
+	if ((failed_type == IORESOURCE_IO) || (tried_times >= pci_try_num)) {
+		free_list(resource_list_x, &head);
+		goto enable_and_dump;
+	}
+
+	printk(KERN_DEBUG "PCI: No. %d try to assign unassigned res\n",
+			 tried_times + 1);
+
+	/* third times and later will not check if it is leaf */
+	if ((tried_times + 1) > 2)
+		rel_type = whole_subtree;
+
+	/*
+	 * Try to release leaf bridge's resources that doesn't fit resource of
+	 * child device under that bridge
+	 */
+	for (list = head.next; list;) {
+		bus = list->dev->bus;
+		pci_bus_release_bridge_resources(bus, list->flags & type_mask,
+						  rel_type);
+		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_list(resource_list_x, &head);
+
+	goto again;
+
+enable_and_dump:
+	/* Depth last, update the hardware. */
+	list_for_each_entry(bus, &pci_root_buses, node)
+		pci_enable_bridges(bus);
 
 	/* dump the resource on buses */
-	list_for_each_entry(bus, &pci_root_buses, node) {
+	list_for_each_entry(bus, &pci_root_buses, node)
 		pci_bus_dump_resources(bus);
-	}
 }
 
 void pci_assign_unassigned_bridge_resources(struct pci_dev *bridge)
diff -druN linux-2.6.39-libre/drivers/pcmcia/ds.c linux-3.0-rc7-libre/drivers/pcmcia/ds.c
--- linux-2.6.39-libre/drivers/pcmcia/ds.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/pcmcia/ds.c	2011-07-11 19:51:52.000000000 -0400
@@ -45,7 +45,7 @@
 
 static void pcmcia_check_driver(struct pcmcia_driver *p_drv)
 {
-	struct pcmcia_device_id *did = p_drv->id_table;
+	const struct pcmcia_device_id *did = p_drv->id_table;
 	unsigned int i;
 	u32 hash;
 
@@ -784,7 +784,7 @@
 
 
 static inline int pcmcia_devmatch(struct pcmcia_device *dev,
-				  struct pcmcia_device_id *did)
+				  const struct pcmcia_device_id *did)
 {
 	if (did->match_flags & PCMCIA_DEV_ID_MATCH_MANF_ID) {
 		if ((!dev->has_manf_id) || (dev->manf_id != did->manf_id))
@@ -890,7 +890,7 @@
 {
 	struct pcmcia_device *p_dev = to_pcmcia_dev(dev);
 	struct pcmcia_driver *p_drv = to_pcmcia_drv(drv);
-	struct pcmcia_device_id *did = p_drv->id_table;
+	const struct pcmcia_device_id *did = p_drv->id_table;
 	struct pcmcia_dynid *dynid;
 
 	/* match dynamic devices first */
diff -druN linux-2.6.39-libre/drivers/pcmcia/pxa2xx_vpac270.c linux-3.0-rc7-libre/drivers/pcmcia/pxa2xx_vpac270.c
--- linux-2.6.39-libre/drivers/pcmcia/pxa2xx_vpac270.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/pcmcia/pxa2xx_vpac270.c	2011-07-11 19:51:52.000000000 -0400
@@ -11,6 +11,7 @@
  *
  */
 
+#include <linux/gpio.h>
 #include <linux/module.h>
 #include <linux/platform_device.h>
 
diff -druN linux-2.6.39-libre/drivers/pcmcia/sa1100_generic.c linux-3.0-rc7-libre/drivers/pcmcia/sa1100_generic.c
--- linux-2.6.39-libre/drivers/pcmcia/sa1100_generic.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/pcmcia/sa1100_generic.c	2011-07-11 19:51:52.000000000 -0400
@@ -43,7 +43,7 @@
 
 int __init pcmcia_collie_init(struct device *dev);
 
-static int (*sa11x0_pcmcia_hw_init[])(struct device *dev) = {
+static int (*sa11x0_pcmcia_hw_init[])(struct device *dev) __devinitdata = {
 #ifdef CONFIG_SA1100_ASSABET
 	pcmcia_assabet_init,
 #endif
diff -druN linux-2.6.39-libre/drivers/platform/x86/acerhdf.c linux-3.0-rc7-libre/drivers/platform/x86/acerhdf.c
--- linux-2.6.39-libre/drivers/platform/x86/acerhdf.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/platform/x86/acerhdf.c	2011-07-11 19:51:52.000000000 -0400
@@ -35,10 +35,8 @@
 
 #include <linux/kernel.h>
 #include <linux/module.h>
-#include <linux/fs.h>
 #include <linux/dmi.h>
-#include <acpi/acpi_drivers.h>
-#include <linux/sched.h>
+#include <linux/acpi.h>
 #include <linux/thermal.h>
 #include <linux/platform_device.h>
 
diff -druN linux-2.6.39-libre/drivers/platform/x86/acer-wmi.c linux-3.0-rc7-libre/drivers/platform/x86/acer-wmi.c
--- linux-2.6.39-libre/drivers/platform/x86/acer-wmi.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/platform/x86/acer-wmi.c	2011-07-11 19:51:52.000000000 -0400
@@ -98,13 +98,26 @@
 
 static const struct key_entry acer_wmi_keymap[] = {
 	{KE_KEY, 0x01, {KEY_WLAN} },     /* WiFi */
+	{KE_KEY, 0x03, {KEY_WLAN} },     /* WiFi */
 	{KE_KEY, 0x12, {KEY_BLUETOOTH} },	/* BT */
 	{KE_KEY, 0x21, {KEY_PROG1} },    /* Backup */
 	{KE_KEY, 0x22, {KEY_PROG2} },    /* Arcade */
 	{KE_KEY, 0x23, {KEY_PROG3} },    /* P_Key */
 	{KE_KEY, 0x24, {KEY_PROG4} },    /* Social networking_Key */
+	{KE_IGNORE, 0x41, {KEY_MUTE} },
+	{KE_IGNORE, 0x42, {KEY_PREVIOUSSONG} },
+	{KE_IGNORE, 0x43, {KEY_NEXTSONG} },
+	{KE_IGNORE, 0x44, {KEY_PLAYPAUSE} },
+	{KE_IGNORE, 0x45, {KEY_STOP} },
+	{KE_IGNORE, 0x48, {KEY_VOLUMEUP} },
+	{KE_IGNORE, 0x49, {KEY_VOLUMEDOWN} },
+	{KE_IGNORE, 0x61, {KEY_SWITCHVIDEOMODE} },
+	{KE_IGNORE, 0x62, {KEY_BRIGHTNESSUP} },
+	{KE_IGNORE, 0x63, {KEY_BRIGHTNESSDOWN} },
 	{KE_KEY, 0x64, {KEY_SWITCHVIDEOMODE} },	/* Display Switch */
+	{KE_IGNORE, 0x81, {KEY_SLEEP} },
 	{KE_KEY, 0x82, {KEY_TOUCHPAD_TOGGLE} },	/* Touch Pad On/Off */
+	{KE_IGNORE, 0x83, {KEY_TOUCHPAD_TOGGLE} },
 	{KE_END, 0}
 };
 
@@ -122,6 +135,7 @@
  */
 #define ACER_WMID3_GDS_WIRELESS		(1<<0)	/* WiFi */
 #define ACER_WMID3_GDS_THREEG		(1<<6)	/* 3G */
+#define ACER_WMID3_GDS_WIMAX		(1<<7)	/* WiMAX */
 #define ACER_WMID3_GDS_BLUETOOTH	(1<<11)	/* BT */
 
 struct lm_input_params {
@@ -737,8 +751,11 @@
 
 	obj = (union acpi_object *) result.pointer;
 	if (obj && obj->type == ACPI_TYPE_BUFFER &&
-		obj->buffer.length == sizeof(u32)) {
+		(obj->buffer.length == sizeof(u32) ||
+		obj->buffer.length == sizeof(u64))) {
 		tmp = *((u32 *) obj->buffer.pointer);
+	} else if (obj->type == ACPI_TYPE_INTEGER) {
+		tmp = (u32) obj->integer.value;
 	} else {
 		tmp = 0;
 	}
@@ -866,8 +883,11 @@
 
 	obj = (union acpi_object *) out.pointer;
 	if (obj && obj->type == ACPI_TYPE_BUFFER &&
-		obj->buffer.length == sizeof(u32)) {
+		(obj->buffer.length == sizeof(u32) ||
+		obj->buffer.length == sizeof(u64))) {
 		devices = *((u32 *) obj->buffer.pointer);
+	} else if (obj->type == ACPI_TYPE_INTEGER) {
+		devices = (u32) obj->integer.value;
 	} else {
 		kfree(out.pointer);
 		return AE_ERROR;
@@ -876,7 +896,8 @@
 	dmi_walk(type_aa_dmi_decode, NULL);
 	if (!has_type_aa) {
 		interface->capability |= ACER_CAP_WIRELESS;
-		interface->capability |= ACER_CAP_THREEG;
+		if (devices & 0x40)
+			interface->capability |= ACER_CAP_THREEG;
 		if (devices & 0x10)
 			interface->capability |= ACER_CAP_BLUETOOTH;
 	}
@@ -961,10 +982,12 @@
 	 * These will all fail silently if the value given is invalid, or the
 	 * capability isn't available on the given interface
 	 */
-	set_u32(mailled, ACER_CAP_MAILLED);
-	if (!has_type_aa)
+	if (mailled >= 0)
+		set_u32(mailled, ACER_CAP_MAILLED);
+	if (!has_type_aa && threeg >= 0)
 		set_u32(threeg, ACER_CAP_THREEG);
-	set_u32(brightness, ACER_CAP_BRIGHTNESS);
+	if (brightness >= 0)
+		set_u32(brightness, ACER_CAP_BRIGHTNESS);
 }
 
 /*
@@ -1081,7 +1104,7 @@
 		return AE_ERROR;
 	}
 	if (obj->buffer.length != 8) {
-		pr_warning("Unknown buffer length %d\n", obj->buffer.length);
+		pr_warn("Unknown buffer length %d\n", obj->buffer.length);
 		kfree(obj);
 		return AE_ERROR;
 	}
@@ -1090,8 +1113,8 @@
 	kfree(obj);
 
 	if (return_value.error_code || return_value.ec_return_value)
-		pr_warning("Get Device Status failed: "
-			"0x%x - 0x%x\n", return_value.error_code,
+		pr_warn("Get Device Status failed: 0x%x - 0x%x\n",
+			return_value.error_code,
 			return_value.ec_return_value);
 	else
 		*value = !!(return_value.devices & device);
@@ -1124,6 +1147,114 @@
 	}
 }
 
+static acpi_status wmid3_set_device_status(u32 value, u16 device)
+{
+	struct wmid3_gds_return_value return_value;
+	acpi_status status;
+	union acpi_object *obj;
+	u16 devices;
+	struct wmid3_gds_input_param params = {
+		.function_num = 0x1,
+		.hotkey_number = 0x01,
+		.devices = ACER_WMID3_GDS_WIRELESS |
+				ACER_WMID3_GDS_THREEG |
+				ACER_WMID3_GDS_WIMAX |
+				ACER_WMID3_GDS_BLUETOOTH,
+	};
+	struct acpi_buffer input = {
+		sizeof(struct wmid3_gds_input_param),
+		&params
+	};
+	struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL };
+	struct acpi_buffer output2 = { ACPI_ALLOCATE_BUFFER, NULL };
+
+	status = wmi_evaluate_method(WMID_GUID3, 0, 0x2, &input, &output);
+	if (ACPI_FAILURE(status))
+		return status;
+
+	obj = output.pointer;
+
+	if (!obj)
+		return AE_ERROR;
+	else if (obj->type != ACPI_TYPE_BUFFER) {
+		kfree(obj);
+		return AE_ERROR;
+	}
+	if (obj->buffer.length != 8) {
+		pr_warning("Unknown buffer length %d\n", obj->buffer.length);
+		kfree(obj);
+		return AE_ERROR;
+	}
+
+	return_value = *((struct wmid3_gds_return_value *)obj->buffer.pointer);
+	kfree(obj);
+
+	if (return_value.error_code || return_value.ec_return_value) {
+		pr_warning("Get Current Device Status failed: "
+			"0x%x - 0x%x\n", return_value.error_code,
+			return_value.ec_return_value);
+		return status;
+	}
+
+	devices = return_value.devices;
+	params.function_num = 0x2;
+	params.hotkey_number = 0x01;
+	params.devices = (value) ? (devices | device) : (devices & ~device);
+
+	status = wmi_evaluate_method(WMID_GUID3, 0, 0x1, &input, &output2);
+	if (ACPI_FAILURE(status))
+		return status;
+
+	obj = output2.pointer;
+
+	if (!obj)
+		return AE_ERROR;
+	else if (obj->type != ACPI_TYPE_BUFFER) {
+		kfree(obj);
+		return AE_ERROR;
+	}
+	if (obj->buffer.length != 4) {
+		pr_warning("Unknown buffer length %d\n", obj->buffer.length);
+		kfree(obj);
+		return AE_ERROR;
+	}
+
+	return_value = *((struct wmid3_gds_return_value *)obj->buffer.pointer);
+	kfree(obj);
+
+	if (return_value.error_code || return_value.ec_return_value)
+		pr_warning("Set Device Status failed: "
+			"0x%x - 0x%x\n", return_value.error_code,
+			return_value.ec_return_value);
+
+	return status;
+}
+
+static acpi_status set_device_status(u32 value, u32 cap)
+{
+	if (wmi_has_guid(WMID_GUID3)) {
+		u16 device;
+
+		switch (cap) {
+		case ACER_CAP_WIRELESS:
+			device = ACER_WMID3_GDS_WIRELESS;
+			break;
+		case ACER_CAP_BLUETOOTH:
+			device = ACER_WMID3_GDS_BLUETOOTH;
+			break;
+		case ACER_CAP_THREEG:
+			device = ACER_WMID3_GDS_THREEG;
+			break;
+		default:
+			return AE_ERROR;
+		}
+		return wmid3_set_device_status(value, device);
+
+	} else {
+		return set_u32(value, cap);
+	}
+}
+
 /*
  * Rfkill devices
  */
@@ -1160,7 +1291,7 @@
 	u32 cap = (unsigned long)data;
 
 	if (rfkill_inited) {
-		status = set_u32(!blocked, cap);
+		status = set_device_status(!blocked, cap);
 		if (ACPI_FAILURE(status))
 			return -ENODEV;
 	}
@@ -1314,10 +1445,12 @@
 	union acpi_object *obj;
 	struct event_return_value return_value;
 	acpi_status status;
+	u16 device_state;
+	const struct key_entry *key;
 
 	status = wmi_get_event_data(value, &response);
 	if (status != AE_OK) {
-		pr_warning("bad event status 0x%x\n", status);
+		pr_warn("bad event status 0x%x\n", status);
 		return;
 	}
 
@@ -1326,12 +1459,12 @@
 	if (!obj)
 		return;
 	if (obj->type != ACPI_TYPE_BUFFER) {
-		pr_warning("Unknown response received %d\n", obj->type);
+		pr_warn("Unknown response received %d\n", obj->type);
 		kfree(obj);
 		return;
 	}
 	if (obj->buffer.length != 8) {
-		pr_warning("Unknown buffer length %d\n", obj->buffer.length);
+		pr_warn("Unknown buffer length %d\n", obj->buffer.length);
 		kfree(obj);
 		return;
 	}
@@ -1341,26 +1474,35 @@
 
 	switch (return_value.function) {
 	case WMID_HOTKEY_EVENT:
-		if (return_value.device_state) {
-			u16 device_state = return_value.device_state;
-			pr_debug("deivces states: 0x%x\n", device_state);
-			if (has_cap(ACER_CAP_WIRELESS))
-				rfkill_set_sw_state(wireless_rfkill,
-				!(device_state & ACER_WMID3_GDS_WIRELESS));
-			if (has_cap(ACER_CAP_BLUETOOTH))
-				rfkill_set_sw_state(bluetooth_rfkill,
-				!(device_state & ACER_WMID3_GDS_BLUETOOTH));
-			if (has_cap(ACER_CAP_THREEG))
-				rfkill_set_sw_state(threeg_rfkill,
-				!(device_state & ACER_WMID3_GDS_THREEG));
-		}
-		if (!sparse_keymap_report_event(acer_wmi_input_dev,
-				return_value.key_num, 1, true))
-			pr_warning("Unknown key number - 0x%x\n",
+		device_state = return_value.device_state;
+		pr_debug("device state: 0x%x\n", device_state);
+
+		key = sparse_keymap_entry_from_scancode(acer_wmi_input_dev,
+							return_value.key_num);
+		if (!key) {
+			pr_warn("Unknown key number - 0x%x\n",
 				return_value.key_num);
+		} else {
+			switch (key->keycode) {
+			case KEY_WLAN:
+			case KEY_BLUETOOTH:
+				if (has_cap(ACER_CAP_WIRELESS))
+					rfkill_set_sw_state(wireless_rfkill,
+						!(device_state & ACER_WMID3_GDS_WIRELESS));
+				if (has_cap(ACER_CAP_THREEG))
+					rfkill_set_sw_state(threeg_rfkill,
+						!(device_state & ACER_WMID3_GDS_THREEG));
+				if (has_cap(ACER_CAP_BLUETOOTH))
+					rfkill_set_sw_state(bluetooth_rfkill,
+						!(device_state & ACER_WMID3_GDS_BLUETOOTH));
+				break;
+			}
+			sparse_keymap_report_entry(acer_wmi_input_dev, key,
+						   1, true);
+		}
 		break;
 	default:
-		pr_warning("Unknown function number - %d - %d\n",
+		pr_warn("Unknown function number - %d - %d\n",
 			return_value.function, return_value.key_num);
 		break;
 	}
@@ -1389,7 +1531,7 @@
 		return AE_ERROR;
 	}
 	if (obj->buffer.length != 4) {
-		pr_warning("Unknown buffer length %d\n", obj->buffer.length);
+		pr_warn("Unknown buffer length %d\n", obj->buffer.length);
 		kfree(obj);
 		return AE_ERROR;
 	}
@@ -1414,11 +1556,11 @@
 	status = wmid3_set_lm_mode(&params, &return_value);
 
 	if (return_value.error_code || return_value.ec_return_value)
-		pr_warning("Enabling EC raw mode failed: "
-		       "0x%x - 0x%x\n", return_value.error_code,
-		       return_value.ec_return_value);
+		pr_warn("Enabling EC raw mode failed: 0x%x - 0x%x\n",
+			return_value.error_code,
+			return_value.ec_return_value);
 	else
-		pr_info("Enabled EC raw mode");
+		pr_info("Enabled EC raw mode\n");
 
 	return status;
 }
@@ -1437,9 +1579,9 @@
 	status = wmid3_set_lm_mode(&params, &return_value);
 
 	if (return_value.error_code || return_value.ec_return_value)
-		pr_warning("Enabling Launch Manager failed: "
-		       "0x%x - 0x%x\n", return_value.error_code,
-		       return_value.ec_return_value);
+		pr_warn("Enabling Launch Manager failed: 0x%x - 0x%x\n",
+			return_value.error_code,
+			return_value.ec_return_value);
 
 	return status;
 }
@@ -1506,8 +1648,11 @@
 
 	obj = (union acpi_object *) out.pointer;
 	if (obj && obj->type == ACPI_TYPE_BUFFER &&
-		obj->buffer.length == sizeof(u32)) {
+		(obj->buffer.length == sizeof(u32) ||
+		obj->buffer.length == sizeof(u64))) {
 		devices = *((u32 *) obj->buffer.pointer);
+	} else if (obj->type == ACPI_TYPE_INTEGER) {
+		devices = (u32) obj->integer.value;
 	}
 
 	kfree(out.pointer);
diff -druN linux-2.6.39-libre/drivers/platform/x86/asus_acpi.c linux-3.0-rc7-libre/drivers/platform/x86/asus_acpi.c
--- linux-2.6.39-libre/drivers/platform/x86/asus_acpi.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/platform/x86/asus_acpi.c	2011-07-11 19:51:52.000000000 -0400
@@ -30,6 +30,8 @@
  *
  */
 
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/slab.h>
@@ -581,8 +583,7 @@
 		if (read_acpi_int(NULL, ledname, &led_status))
 			return led_status;
 		else
-			printk(KERN_WARNING "Asus ACPI: Error reading LED "
-			       "status\n");
+			pr_warn("Error reading LED status\n");
 	}
 	return (hotk->status & ledmask) ? 1 : 0;
 }
@@ -621,8 +622,7 @@
 		led_out = !led_out;
 
 	if (!write_acpi_int(hotk->handle, ledname, led_out, NULL))
-		printk(KERN_WARNING "Asus ACPI: LED (%s) write failed\n",
-		       ledname);
+		pr_warn("LED (%s) write failed\n", ledname);
 
 	return rv;
 }
@@ -679,8 +679,7 @@
 	if (rv > 0) {
 		if (!write_acpi_int
 		    (hotk->handle, hotk->methods->mt_ledd, value, NULL))
-			printk(KERN_WARNING
-			       "Asus ACPI: LED display write failed\n");
+			pr_warn("LED display write failed\n");
 		else
 			hotk->ledd_status = (u32) value;
 	}
@@ -838,8 +837,7 @@
 	} else {
 		/* We don't have to check anything if we are here */
 		if (!read_acpi_int(NULL, hotk->methods->lcd_status, &lcd))
-			printk(KERN_WARNING
-			       "Asus ACPI: Error reading LCD status\n");
+			pr_warn("Error reading LCD status\n");
 
 		if (hotk->model == L2D)
 			lcd = ~lcd;
@@ -871,7 +869,7 @@
 			   the exact behaviour is simulated here */
 		}
 		if (ACPI_FAILURE(status))
-			printk(KERN_WARNING "Asus ACPI: Error switching LCD\n");
+			pr_warn("Error switching LCD\n");
 	}
 	return 0;
 
@@ -915,13 +913,11 @@
 	if (hotk->methods->brightness_get) {	/* SPLV/GPLV laptop */
 		if (!read_acpi_int(hotk->handle, hotk->methods->brightness_get,
 				   &value))
-			printk(KERN_WARNING
-			       "Asus ACPI: Error reading brightness\n");
+			pr_warn("Error reading brightness\n");
 	} else if (hotk->methods->brightness_status) {	/* For D1 for example */
 		if (!read_acpi_int(NULL, hotk->methods->brightness_status,
 				   &value))
-			printk(KERN_WARNING
-			       "Asus ACPI: Error reading brightness\n");
+			pr_warn("Error reading brightness\n");
 	} else			/* No GPLV method */
 		value = hotk->brightness;
 	return value;
@@ -939,8 +935,7 @@
 	if (hotk->methods->brightness_set) {
 		if (!write_acpi_int(hotk->handle, hotk->methods->brightness_set,
 				    value, NULL)) {
-			printk(KERN_WARNING
-			       "Asus ACPI: Error changing brightness\n");
+			pr_warn("Error changing brightness\n");
 			ret = -EIO;
 		}
 		goto out;
@@ -955,8 +950,7 @@
 					      NULL, NULL);
 		(value > 0) ? value-- : value++;
 		if (ACPI_FAILURE(status)) {
-			printk(KERN_WARNING
-			       "Asus ACPI: Error changing brightness\n");
+			pr_warn("Error changing brightness\n");
 			ret = -EIO;
 		}
 	}
@@ -1008,7 +1002,7 @@
 	/* no sanity check needed for now */
 	if (!write_acpi_int(hotk->handle, hotk->methods->display_set,
 			    value, NULL))
-		printk(KERN_WARNING "Asus ACPI: Error setting display\n");
+		pr_warn("Error setting display\n");
 	return;
 }
 
@@ -1021,8 +1015,7 @@
 	int value = 0;
 
 	if (!read_acpi_int(hotk->handle, hotk->methods->display_get, &value))
-		printk(KERN_WARNING
-		       "Asus ACPI: Error reading display status\n");
+		pr_warn("Error reading display status\n");
 	value &= 0x07;	/* needed for some models, shouldn't hurt others */
 	seq_printf(m, "%d\n", value);
 	return 0;
@@ -1068,7 +1061,7 @@
 	proc = proc_create_data(name, mode, acpi_device_dir(device),
 				proc_fops, acpi_driver_data(device));
 	if (!proc) {
-		printk(KERN_WARNING "  Unable to create %s fs entry\n", name);
+		pr_warn("  Unable to create %s fs entry\n", name);
 		return -1;
 	}
 	proc->uid = asus_uid;
@@ -1085,8 +1078,8 @@
 		mode = S_IFREG | S_IRUGO | S_IWUSR | S_IWGRP;
 	} else {
 		mode = S_IFREG | S_IRUSR | S_IRGRP | S_IWUSR | S_IWGRP;
-		printk(KERN_WARNING "  asus_uid and asus_gid parameters are "
-		       "deprecated, use chown and chmod instead!\n");
+		pr_warn("  asus_uid and asus_gid parameters are "
+			"deprecated, use chown and chmod instead!\n");
 	}
 
 	acpi_device_dir(device) = asus_proc_dir;
@@ -1099,8 +1092,7 @@
 		proc->uid = asus_uid;
 		proc->gid = asus_gid;
 	} else {
-		printk(KERN_WARNING "  Unable to create " PROC_INFO
-		       " fs entry\n");
+		pr_warn("  Unable to create " PROC_INFO " fs entry\n");
 	}
 
 	if (hotk->methods->mt_wled) {
@@ -1283,20 +1275,19 @@
 	 */
 	status = acpi_get_table(ACPI_SIG_DSDT, 1, &asus_info);
 	if (ACPI_FAILURE(status))
-		printk(KERN_WARNING "  Couldn't get the DSDT table header\n");
+		pr_warn("  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)) {
-		printk(KERN_ERR "  Hotkey initialization failed\n");
+		pr_err("  Hotkey initialization failed\n");
 		return -ENODEV;
 	}
 
 	/* This needs to be called for some laptops to init properly */
 	if (!read_acpi_int(hotk->handle, "BSTS", &bsts_result))
-		printk(KERN_WARNING "  Error calling BSTS\n");
+		pr_warn("  Error calling BSTS\n");
 	else if (bsts_result)
-		printk(KERN_NOTICE "  BSTS called, 0x%02x returned\n",
-		       bsts_result);
+		pr_notice("  BSTS called, 0x%02x returned\n", bsts_result);
 
 	/*
 	 * Try to match the object returned by INIT to the specific model.
@@ -1324,23 +1315,21 @@
 		if (asus_info &&
 		    strncmp(asus_info->oem_table_id, "ODEM", 4) == 0) {
 			hotk->model = P30;
-			printk(KERN_NOTICE
-			       "  Samsung P30 detected, supported\n");
+			pr_notice("  Samsung P30 detected, supported\n");
 			hotk->methods = &model_conf[hotk->model];
 			kfree(model);
 			return 0;
 		} else {
 			hotk->model = M2E;
-			printk(KERN_NOTICE "  unsupported model %s, trying "
-			       "default values\n", string);
-			printk(KERN_NOTICE
-			       "  send /proc/acpi/dsdt to the developers\n");
+			pr_notice("  unsupported model %s, trying default values\n",
+				  string);
+			pr_notice("  send /proc/acpi/dsdt to the developers\n");
 			kfree(model);
 			return -ENODEV;
 		}
 	}
 	hotk->methods = &model_conf[hotk->model];
-	printk(KERN_NOTICE "  %s model detected, supported\n", string);
+	pr_notice("  %s model detected, supported\n", string);
 
 	/* Sort of per-model blacklist */
 	if (strncmp(string, "L2B", 3) == 0)
@@ -1385,7 +1374,7 @@
 	if (hotk->device->status.present) {
 		result = asus_hotk_get_info();
 	} else {
-		printk(KERN_ERR "  Hotkey device not present, aborting\n");
+		pr_err("  Hotkey device not present, aborting\n");
 		return -EINVAL;
 	}
 
@@ -1399,8 +1388,7 @@
 	acpi_status status = AE_OK;
 	int result;
 
-	printk(KERN_NOTICE "Asus Laptop ACPI Extras version %s\n",
-	       ASUS_ACPI_VERSION);
+	pr_notice("Asus Laptop ACPI Extras version %s\n", ASUS_ACPI_VERSION);
 
 	hotk = kzalloc(sizeof(struct asus_hotk), GFP_KERNEL);
 	if (!hotk)
@@ -1428,15 +1416,14 @@
 		    acpi_evaluate_object(NULL, hotk->methods->brightness_down,
 					 NULL, NULL);
 		if (ACPI_FAILURE(status))
-			printk(KERN_WARNING "  Error changing brightness\n");
+			pr_warn("  Error changing brightness\n");
 		else {
 			status =
 			    acpi_evaluate_object(NULL,
 						 hotk->methods->brightness_up,
 						 NULL, NULL);
 			if (ACPI_FAILURE(status))
-				printk(KERN_WARNING "  Strange, error changing"
-				       " brightness\n");
+				pr_warn("  Strange, error changing brightness\n");
 		}
 	}
 
@@ -1488,7 +1475,7 @@
 
 	asus_proc_dir = proc_mkdir(PROC_ASUS, acpi_root_dir);
 	if (!asus_proc_dir) {
-		printk(KERN_ERR "Asus ACPI: Unable to create /proc entry\n");
+		pr_err("Unable to create /proc entry\n");
 		acpi_bus_unregister_driver(&asus_hotk_driver);
 		return -ENODEV;
 	}
@@ -1513,7 +1500,7 @@
 							  &asus_backlight_data,
 							  &props);
 	if (IS_ERR(asus_backlight_device)) {
-		printk(KERN_ERR "Could not register asus backlight device\n");
+		pr_err("Could not register asus backlight device\n");
 		asus_backlight_device = NULL;
 		asus_acpi_exit();
 		return -ENODEV;
diff -druN linux-2.6.39-libre/drivers/platform/x86/asus-laptop.c linux-3.0-rc7-libre/drivers/platform/x86/asus-laptop.c
--- linux-2.6.39-libre/drivers/platform/x86/asus-laptop.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/platform/x86/asus-laptop.c	2011-07-11 19:51:52.000000000 -0400
@@ -318,7 +318,7 @@
 
 	if (status != AE_OK) {
 		if (ret)
-			pr_warning("Error finding %s\n", method);
+			pr_warn("Error finding %s\n", method);
 		return -ENODEV;
 	}
 	return 0;
@@ -383,7 +383,7 @@
 	rv = acpi_evaluate_integer(asus->handle, METHOD_KBD_LIGHT_GET,
 				   &params, &kblv);
 	if (ACPI_FAILURE(rv)) {
-		pr_warning("Error reading kled level\n");
+		pr_warn("Error reading kled level\n");
 		return -ENODEV;
 	}
 	return kblv;
@@ -397,7 +397,7 @@
 		kblv = 0;
 
 	if (write_acpi_int(asus->handle, METHOD_KBD_LIGHT_SET, kblv)) {
-		pr_warning("Keyboard LED display write failed\n");
+		pr_warn("Keyboard LED display write failed\n");
 		return -EINVAL;
 	}
 	return 0;
@@ -531,7 +531,7 @@
 	rv = acpi_evaluate_integer(asus->handle, METHOD_BRIGHTNESS_GET,
 				   NULL, &value);
 	if (ACPI_FAILURE(rv))
-		pr_warning("Error reading brightness\n");
+		pr_warn("Error reading brightness\n");
 
 	return value;
 }
@@ -541,7 +541,7 @@
 	struct asus_laptop *asus = bl_get_data(bd);
 
 	if (write_acpi_int(asus->handle, METHOD_BRIGHTNESS_SET, value)) {
-		pr_warning("Error changing brightness\n");
+		pr_warn("Error changing brightness\n");
 		return -EIO;
 	}
 	return 0;
@@ -730,7 +730,7 @@
 	rv = parse_arg(buf, count, &value);
 	if (rv > 0) {
 		if (write_acpi_int(asus->handle, METHOD_LEDD, value)) {
-			pr_warning("LED display write failed\n");
+			pr_warn("LED display write failed\n");
 			return -ENODEV;
 		}
 		asus->ledd_status = (u32) value;
@@ -752,7 +752,7 @@
 	rv = acpi_evaluate_integer(asus->handle, METHOD_WL_STATUS,
 				   NULL, &status);
 	if (ACPI_FAILURE(rv)) {
-		pr_warning("Error reading Wireless status\n");
+		pr_warn("Error reading Wireless status\n");
 		return -EINVAL;
 	}
 	return !!(status & mask);
@@ -764,7 +764,7 @@
 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);
+		pr_warn("Error setting wlan status to %d\n", status);
 		return -EIO;
 	}
 	return 0;
@@ -792,7 +792,7 @@
 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);
+		pr_warn("Error setting bluetooth status to %d\n", status);
 		return -EIO;
 	}
 	return 0;
@@ -821,7 +821,7 @@
 static int asus_wimax_set(struct asus_laptop *asus, int status)
 {
 	if (write_acpi_int(asus->handle, METHOD_WIMAX, !!status)) {
-		pr_warning("Error setting wimax status to %d", status);
+		pr_warn("Error setting wimax status to %d\n", status);
 		return -EIO;
 	}
 	return 0;
@@ -850,7 +850,7 @@
 static int asus_wwan_set(struct asus_laptop *asus, int status)
 {
 	if (write_acpi_int(asus->handle, METHOD_WWAN, !!status)) {
-		pr_warning("Error setting wwan status to %d", status);
+		pr_warn("Error setting wwan status to %d\n", status);
 		return -EIO;
 	}
 	return 0;
@@ -880,7 +880,7 @@
 {
 	/* no sanity check needed for now */
 	if (write_acpi_int(asus->handle, METHOD_SWITCH_DISPLAY, value))
-		pr_warning("Error setting display\n");
+		pr_warn("Error setting display\n");
 	return;
 }
 
@@ -909,7 +909,7 @@
 static void asus_als_switch(struct asus_laptop *asus, int value)
 {
 	if (write_acpi_int(asus->handle, METHOD_ALS_CONTROL, value))
-		pr_warning("Error setting light sensor switch\n");
+		pr_warn("Error setting light sensor switch\n");
 	asus->light_switch = value;
 }
 
@@ -937,7 +937,7 @@
 static void asus_als_level(struct asus_laptop *asus, int value)
 {
 	if (write_acpi_int(asus->handle, METHOD_ALS_LEVEL, value))
-		pr_warning("Error setting light sensor level\n");
+		pr_warn("Error setting light sensor level\n");
 	asus->light_level = value;
 }
 
@@ -976,7 +976,7 @@
 	rv = acpi_evaluate_integer(asus->handle, METHOD_GPS_STATUS,
 				   NULL, &status);
 	if (ACPI_FAILURE(rv)) {
-		pr_warning("Error reading GPS status\n");
+		pr_warn("Error reading GPS status\n");
 		return -ENODEV;
 	}
 	return !!status;
@@ -1284,7 +1284,7 @@
 	 */
 	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");
+		pr_warn("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_ret(asus->handle, "INIT", 0, &buffer)) {
@@ -1296,7 +1296,7 @@
 	status =
 	    acpi_evaluate_integer(asus->handle, "BSTS", NULL, &bsts_result);
 	if (ACPI_FAILURE(status))
-		pr_warning("Error calling BSTS\n");
+		pr_warn("Error calling BSTS\n");
 	else if (bsts_result)
 		pr_notice("BSTS called, 0x%02x returned\n",
 		       (uint) bsts_result);
diff -druN linux-2.6.39-libre/drivers/platform/x86/asus-wmi.c linux-3.0-rc7-libre/drivers/platform/x86/asus-wmi.c
--- linux-2.6.39-libre/drivers/platform/x86/asus-wmi.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/platform/x86/asus-wmi.c	2011-07-11 19:51:52.000000000 -0400
@@ -425,7 +425,7 @@
 	if (asus->hotplug_slot) {
 		bus = pci_find_bus(0, 1);
 		if (!bus) {
-			pr_warning("Unable to find PCI bus 1?\n");
+			pr_warn("Unable to find PCI bus 1?\n");
 			goto out_unlock;
 		}
 
@@ -436,12 +436,12 @@
 		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");
+			pr_warn("BIOS says wireless lan is %s, "
+				"but the pci device is %s\n",
+				blocked ? "blocked" : "unblocked",
+				absent ? "absent" : "present");
+			pr_warn("skipped wireless hotplug as probably "
+				"inappropriate for this model\n");
 			goto out_unlock;
 		}
 
@@ -500,7 +500,7 @@
 						     ACPI_SYSTEM_NOTIFY,
 						     asus_rfkill_notify, asus);
 		if (ACPI_FAILURE(status))
-			pr_warning("Failed to register notify on %s\n", node);
+			pr_warn("Failed to register notify on %s\n", node);
 	} else
 		return -ENODEV;
 
@@ -1025,6 +1025,7 @@
 		return power;
 
 	memset(&props, 0, sizeof(struct backlight_properties));
+	props.type = BACKLIGHT_PLATFORM;
 	props.max_brightness = max;
 	bd = backlight_device_register(asus->driver->name,
 				       &asus->platform_device->dev, asus,
@@ -1223,7 +1224,7 @@
 /*
  * Platform device
  */
-static int __init asus_wmi_platform_init(struct asus_wmi *asus)
+static int asus_wmi_platform_init(struct asus_wmi *asus)
 {
 	int rv;
 
@@ -1583,12 +1584,12 @@
 	int ret;
 
 	if (!wmi_has_guid(ASUS_WMI_MGMT_GUID)) {
-		pr_warning("Management GUID not found\n");
+		pr_warn("Management GUID not found\n");
 		return -ENODEV;
 	}
 
 	if (wdrv->event_guid && !wmi_has_guid(wdrv->event_guid)) {
-		pr_warning("Event GUID not found\n");
+		pr_warn("Event GUID not found\n");
 		return -ENODEV;
 	}
 
diff -druN linux-2.6.39-libre/drivers/platform/x86/compal-laptop.c linux-3.0-rc7-libre/drivers/platform/x86/compal-laptop.c
--- linux-2.6.39-libre/drivers/platform/x86/compal-laptop.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/platform/x86/compal-laptop.c	2011-07-11 19:51:52.000000000 -0400
@@ -68,6 +68,8 @@
  * only enabled on a JHL90 board until it is verified that they work on the
  * other boards too.  See the extra_features variable. */
 
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
@@ -200,8 +202,8 @@
  * watching the output of address 0x4F (do an ec_transaction writing 0x33
  * into 0x4F and read a few bytes from the output, like so:
  *	u8 writeData = 0x33;
- *	ec_transaction(0x4F, &writeData, 1, buffer, 32, 0);
- * That address is labelled "fan1 table information" in the service manual.
+ *	ec_transaction(0x4F, &writeData, 1, buffer, 32);
+ * That address is labeled "fan1 table information" in the service manual.
  * It should be clear which value in 'buffer' changes). This seems to be
  * related to fan speed. It isn't a proper 'realtime' fan speed value
  * though, because physically stopping or speeding up the fan doesn't
@@ -286,7 +288,7 @@
 static void set_backlight_state(bool on)
 {
 	u8 data = on ? BACKLIGHT_STATE_ON_DATA : BACKLIGHT_STATE_OFF_DATA;
-	ec_transaction(BACKLIGHT_STATE_ADDR, &data, 1, NULL, 0, 0);
+	ec_transaction(BACKLIGHT_STATE_ADDR, &data, 1, NULL, 0);
 }
 
 
@@ -294,24 +296,24 @@
 static void pwm_enable_control(void)
 {
 	unsigned char writeData = PWM_ENABLE_DATA;
-	ec_transaction(PWM_ENABLE_ADDR, &writeData, 1, NULL, 0, 0);
+	ec_transaction(PWM_ENABLE_ADDR, &writeData, 1, NULL, 0);
 }
 
 static void pwm_disable_control(void)
 {
 	unsigned char writeData = PWM_DISABLE_DATA;
-	ec_transaction(PWM_DISABLE_ADDR, &writeData, 1, NULL, 0, 0);
+	ec_transaction(PWM_DISABLE_ADDR, &writeData, 1, NULL, 0);
 }
 
 static void set_pwm(int pwm)
 {
-	ec_transaction(PWM_ADDRESS, &pwm_lookup_table[pwm], 1, NULL, 0, 0);
+	ec_transaction(PWM_ADDRESS, &pwm_lookup_table[pwm], 1, NULL, 0);
 }
 
 static int get_fan_rpm(void)
 {
 	u8 value, data = FAN_DATA;
-	ec_transaction(FAN_ADDRESS, &data, 1, &value, 1, 0);
+	ec_transaction(FAN_ADDRESS, &data, 1, &value, 1);
 	return 100 * (int)value;
 }
 
@@ -760,16 +762,14 @@
 
 static int dmi_check_cb(const struct dmi_system_id *id)
 {
-	printk(KERN_INFO DRIVER_NAME": Identified laptop model '%s'\n",
-		id->ident);
+	pr_info("Identified laptop model '%s'\n", id->ident);
 	extra_features = false;
 	return 1;
 }
 
 static int dmi_check_cb_extra(const struct dmi_system_id *id)
 {
-	printk(KERN_INFO DRIVER_NAME": Identified laptop model '%s', "
-		"enabling extra features\n",
+	pr_info("Identified laptop model '%s', enabling extra features\n",
 		id->ident);
 	extra_features = true;
 	return 1;
@@ -956,14 +956,12 @@
 	int ret;
 
 	if (acpi_disabled) {
-		printk(KERN_ERR DRIVER_NAME": ACPI needs to be enabled for "
-						"this driver to work!\n");
+		pr_err("ACPI needs to be enabled for this driver to work!\n");
 		return -ENODEV;
 	}
 
 	if (!force && !dmi_check_system(compal_dmi_table)) {
-		printk(KERN_ERR DRIVER_NAME": Motherboard not recognized (You "
-				"could try the module's force-parameter)");
+		pr_err("Motherboard not recognized (You could try the module's force-parameter)\n");
 		return -ENODEV;
 	}
 
@@ -998,8 +996,7 @@
 	if (ret)
 		goto err_rfkill;
 
-	printk(KERN_INFO DRIVER_NAME": Driver "DRIVER_VERSION
-						" successfully loaded\n");
+	pr_info("Driver " DRIVER_VERSION " successfully loaded\n");
 	return 0;
 
 err_rfkill:
@@ -1033,8 +1030,10 @@
 	initialize_fan_control_data(data);
 
 	err = sysfs_create_group(&pdev->dev.kobj, &compal_attribute_group);
-	if (err)
+	if (err) {
+		kfree(data);
 		return err;
+	}
 
 	data->hwmon_dev = hwmon_device_register(&pdev->dev);
 	if (IS_ERR(data->hwmon_dev)) {
@@ -1064,7 +1063,7 @@
 	rfkill_destroy(wifi_rfkill);
 	rfkill_destroy(bt_rfkill);
 
-	printk(KERN_INFO DRIVER_NAME": Driver unloaded\n");
+	pr_info("Driver unloaded\n");
 }
 
 static int __devexit compal_remove(struct platform_device *pdev)
@@ -1074,8 +1073,7 @@
 	if (!extra_features)
 		return 0;
 
-	printk(KERN_INFO DRIVER_NAME": Unloading: resetting fan control "
-							"to motherboard\n");
+	pr_info("Unloading: resetting fan control to motherboard\n");
 	pwm_disable_control();
 
 	data = platform_get_drvdata(pdev);
diff -druN linux-2.6.39-libre/drivers/platform/x86/dell-laptop.c linux-3.0-rc7-libre/drivers/platform/x86/dell-laptop.c
--- linux-2.6.39-libre/drivers/platform/x86/dell-laptop.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/platform/x86/dell-laptop.c	2011-07-11 19:51:52.000000000 -0400
@@ -11,6 +11,8 @@
  *  published by the Free Software Foundation.
  */
 
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
@@ -290,12 +292,9 @@
 	dell_send_request(buffer, 17, 11);
 
 	/* If the hardware switch controls this radio, and the hardware
-	   switch is disabled, don't allow changing the software state.
-	   If the hardware switch is reported as not supported, always
-	   fire the SMI to toggle the killswitch. */
+	   switch is disabled, don't allow changing the software state */
 	if ((hwswitch_state & BIT(hwswitch_bit)) &&
-	    !(buffer->output[1] & BIT(16)) &&
-	    (buffer->output[1] & BIT(0))) {
+	    !(buffer->output[1] & BIT(16))) {
 		ret = -EINVAL;
 		goto out;
 	}
@@ -401,23 +400,6 @@
 
 static void dell_update_rfkill(struct work_struct *ignored)
 {
-	int status;
-
-	get_buffer();
-	dell_send_request(buffer, 17, 11);
-	status = buffer->output[1];
-	release_buffer();
-
-	/* if hardware rfkill is not supported, set it explicitly */
-	if (!(status & BIT(0))) {
-		if (wifi_rfkill)
-			dell_rfkill_set((void *)1, !((status & BIT(17)) >> 17));
-		if (bluetooth_rfkill)
-			dell_rfkill_set((void *)2, !((status & BIT(18)) >> 18));
-		if (wwan_rfkill)
-			dell_rfkill_set((void *)3, !((status & BIT(19)) >> 19));
-	}
-
 	if (wifi_rfkill)
 		dell_rfkill_query(wifi_rfkill, (void *)1);
 	if (bluetooth_rfkill)
@@ -434,8 +416,7 @@
 	int ret;
 
 	if (dmi_check_system(dell_blacklist)) {
-		printk(KERN_INFO "dell-laptop: Blacklisted hardware detected - "
-				"not enabling rfkill\n");
+		pr_info("Blacklisted hardware detected - not enabling rfkill\n");
 		return 0;
 	}
 
@@ -559,11 +540,11 @@
 	else
 		dell_send_request(buffer, 0, 1);
 
+	ret = buffer->output[1];
+
 out:
 	release_buffer();
-	if (ret)
-		return ret;
-	return buffer->output[1];
+	return ret;
 }
 
 static const struct backlight_ops dell_ops = {
@@ -606,7 +587,7 @@
 	dmi_walk(find_tokens, NULL);
 
 	if (!da_tokens)  {
-		printk(KERN_INFO "dell-laptop: Unable to find dmi tokens\n");
+		pr_info("Unable to find dmi tokens\n");
 		return -ENODEV;
 	}
 
@@ -636,14 +617,13 @@
 	ret = dell_setup_rfkill();
 
 	if (ret) {
-		printk(KERN_WARNING "dell-laptop: Unable to setup rfkill\n");
+		pr_warn("Unable to setup rfkill\n");
 		goto fail_rfkill;
 	}
 
 	ret = i8042_install_filter(dell_laptop_i8042_filter);
 	if (ret) {
-		printk(KERN_WARNING
-		       "dell-laptop: Unable to install key filter\n");
+		pr_warn("Unable to install key filter\n");
 		goto fail_filter;
 	}
 
diff -druN linux-2.6.39-libre/drivers/platform/x86/dell-wmi-aio.c linux-3.0-rc7-libre/drivers/platform/x86/dell-wmi-aio.c
--- linux-2.6.39-libre/drivers/platform/x86/dell-wmi-aio.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/platform/x86/dell-wmi-aio.c	2011-07-11 19:51:52.000000000 -0400
@@ -15,6 +15,7 @@
  *  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>
@@ -138,7 +139,7 @@
 
 	guid = dell_wmi_aio_find();
 	if (!guid) {
-		pr_warning("No known WMI GUID found\n");
+		pr_warn("No known WMI GUID found\n");
 		return -ENXIO;
 	}
 
diff -druN linux-2.6.39-libre/drivers/platform/x86/dell-wmi.c linux-3.0-rc7-libre/drivers/platform/x86/dell-wmi.c
--- linux-2.6.39-libre/drivers/platform/x86/dell-wmi.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/platform/x86/dell-wmi.c	2011-07-11 19:51:52.000000000 -0400
@@ -23,6 +23,8 @@
  *  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>
@@ -141,7 +143,7 @@
 
 	status = wmi_get_event_data(value, &response);
 	if (status != AE_OK) {
-		printk(KERN_INFO "dell-wmi: bad event status 0x%x\n", status);
+		pr_info("bad event status 0x%x\n", status);
 		return;
 	}
 
@@ -153,8 +155,8 @@
 		u16 *buffer_entry = (u16 *)obj->buffer.pointer;
 
 		if (dell_new_hk_type && (buffer_entry[1] != 0x10)) {
-			printk(KERN_INFO "dell-wmi: Received unknown WMI event"
-					 " (0x%x)\n", buffer_entry[1]);
+			pr_info("Received unknown WMI event (0x%x)\n",
+				buffer_entry[1]);
 			kfree(obj);
 			return;
 		}
@@ -167,8 +169,7 @@
 		key = sparse_keymap_entry_from_scancode(dell_wmi_input_dev,
 							reported_key);
 		if (!key) {
-			printk(KERN_INFO "dell-wmi: Unknown key %x pressed\n",
-				reported_key);
+			pr_info("Unknown key %x pressed\n", reported_key);
 		} else if ((key->keycode == KEY_BRIGHTNESSUP ||
 			    key->keycode == KEY_BRIGHTNESSDOWN) && acpi_video) {
 			/* Don't report brightness notifications that will also
@@ -275,7 +276,7 @@
 	acpi_status status;
 
 	if (!wmi_has_guid(DELL_EVENT_GUID)) {
-		printk(KERN_WARNING "dell-wmi: No known WMI GUID found\n");
+		pr_warn("No known WMI GUID found\n");
 		return -ENODEV;
 	}
 
@@ -290,9 +291,7 @@
 					 dell_wmi_notify, NULL);
 	if (ACPI_FAILURE(status)) {
 		dell_wmi_input_destroy();
-		printk(KERN_ERR
-			"dell-wmi: Unable to register notify handler - %d\n",
-			status);
+		pr_err("Unable to register notify handler - %d\n", status);
 		return -ENODEV;
 	}
 
diff -druN linux-2.6.39-libre/drivers/platform/x86/eeepc-laptop.c linux-3.0-rc7-libre/drivers/platform/x86/eeepc-laptop.c
--- linux-2.6.39-libre/drivers/platform/x86/eeepc-laptop.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/platform/x86/eeepc-laptop.c	2011-07-11 19:51:52.000000000 -0400
@@ -228,7 +228,7 @@
 		return -ENODEV;
 
 	if (write_acpi_int(eeepc->handle, method, value))
-		pr_warning("Error writing %s\n", method);
+		pr_warn("Error writing %s\n", method);
 	return 0;
 }
 
@@ -243,7 +243,7 @@
 		return -ENODEV;
 
 	if (read_acpi_int(eeepc->handle, method, &value))
-		pr_warning("Error reading %s\n", method);
+		pr_warn("Error reading %s\n", method);
 	return value;
 }
 
@@ -261,7 +261,7 @@
 	status = acpi_get_handle(eeepc->handle, (char *)method,
 				 handle);
 	if (status != AE_OK) {
-		pr_warning("Error finding %s\n", method);
+		pr_warn("Error finding %s\n", method);
 		return -ENODEV;
 	}
 	return 0;
@@ -417,7 +417,7 @@
 	switch (value) {
 	case 0:
 		if (eeepc->cpufv_disabled)
-			pr_warning("cpufv enabled (not officially supported "
+			pr_warn("cpufv enabled (not officially supported "
 				"on this model)\n");
 		eeepc->cpufv_disabled = false;
 		return rv;
@@ -609,7 +609,7 @@
 		bus = port->subordinate;
 
 		if (!bus) {
-			pr_warning("Unable to find PCI bus?\n");
+			pr_warn("Unable to find PCI bus 1?\n");
 			goto out_unlock;
 		}
 
@@ -621,12 +621,12 @@
 		absent = (l == 0xffffffff);
 
 		if (blocked != absent) {
-			pr_warning("BIOS says wireless lan is %s, "
-					"but the pci device is %s\n",
+			pr_warn("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");
+			pr_warn("skipped wireless hotplug as probably "
+				"inappropriate for this model\n");
 			goto out_unlock;
 		}
 
@@ -691,7 +691,8 @@
 						     eeepc_rfkill_notify,
 						     eeepc);
 		if (ACPI_FAILURE(status))
-			pr_warning("Failed to register notify on %s\n", node);
+			pr_warn("Failed to register notify on %s\n", node);
+
 		/*
 		 * Refresh pci hotplug in case the rfkill state was
 		 * changed during setup.
diff -druN linux-2.6.39-libre/drivers/platform/x86/eeepc-wmi.c linux-3.0-rc7-libre/drivers/platform/x86/eeepc-wmi.c
--- linux-2.6.39-libre/drivers/platform/x86/eeepc-wmi.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/platform/x86/eeepc-wmi.c	2011-07-11 19:51:52.000000000 -0400
@@ -84,7 +84,7 @@
 static acpi_status eeepc_wmi_parse_device(acpi_handle handle, u32 level,
 						 void *context, void **retval)
 {
-	pr_warning("Found legacy ATKD device (%s)", EEEPC_ACPI_HID);
+	pr_warn("Found legacy ATKD device (%s)\n", EEEPC_ACPI_HID);
 	*(bool *)context = true;
 	return AE_CTRL_TERMINATE;
 }
@@ -105,12 +105,12 @@
 static int eeepc_wmi_probe(struct platform_device *pdev)
 {
 	if (eeepc_wmi_check_atkd()) {
-		pr_warning("WMI device present, but legacy ATKD device is also "
-			   "present and enabled.");
-		pr_warning("You probably booted with acpi_osi=\"Linux\" or "
-			   "acpi_osi=\"!Windows 2009\"");
-		pr_warning("Can't load eeepc-wmi, use default acpi_osi "
-			   "(preferred) or eeepc-laptop");
+		pr_warn("WMI device present, but legacy ATKD device is also "
+			"present and enabled\n");
+		pr_warn("You probably booted with acpi_osi=\"Linux\" or "
+			"acpi_osi=\"!Windows 2009\"\n");
+		pr_warn("Can't load eeepc-wmi, use default acpi_osi "
+			"(preferred) or eeepc-laptop\n");
 		return -EBUSY;
 	}
 	return 0;
diff -druN linux-2.6.39-libre/drivers/platform/x86/fujitsu-laptop.c linux-3.0-rc7-libre/drivers/platform/x86/fujitsu-laptop.c
--- linux-2.6.39-libre/drivers/platform/x86/fujitsu-laptop.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/platform/x86/fujitsu-laptop.c	2011-07-11 19:51:52.000000000 -0400
@@ -56,6 +56,8 @@
  *
  */
 
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
@@ -585,8 +587,7 @@
 static void dmi_check_cb_common(const struct dmi_system_id *id)
 {
 	acpi_handle handle;
-	printk(KERN_INFO "fujitsu-laptop: Identified laptop model '%s'.\n",
-	       id->ident);
+	pr_info("Identified laptop model '%s'\n", id->ident);
 	if (use_alt_lcd_levels == -1) {
 		if (ACPI_SUCCESS(acpi_get_handle(NULL,
 				"\\_SB.PCI0.LPCB.FJEX.SBL2", &handle)))
@@ -691,11 +692,11 @@
 
 	result = acpi_bus_update_power(fujitsu->acpi_handle, &state);
 	if (result) {
-		printk(KERN_ERR "Error reading power state\n");
+		pr_err("Error reading power state\n");
 		goto err_unregister_input_dev;
 	}
 
-	printk(KERN_INFO "ACPI: %s [%s] (%s)\n",
+	pr_info("ACPI: %s [%s] (%s)\n",
 	       acpi_device_name(device), acpi_device_bid(device),
 	       !device->power.state ? "on" : "off");
 
@@ -707,7 +708,7 @@
 		if (ACPI_FAILURE
 		    (acpi_evaluate_object
 		     (device->handle, METHOD_NAME__INI, NULL, NULL)))
-			printk(KERN_ERR "_INI Method failed\n");
+			pr_err("_INI Method failed\n");
 	}
 
 	/* do config (detect defaults) */
@@ -827,7 +828,7 @@
 	error = kfifo_alloc(&fujitsu_hotkey->fifo, RINGBUFFERSIZE * sizeof(int),
 			GFP_KERNEL);
 	if (error) {
-		printk(KERN_ERR "kfifo_alloc failed\n");
+		pr_err("kfifo_alloc failed\n");
 		goto err_stop;
 	}
 
@@ -859,13 +860,13 @@
 
 	result = acpi_bus_update_power(fujitsu_hotkey->acpi_handle, &state);
 	if (result) {
-		printk(KERN_ERR "Error reading power state\n");
+		pr_err("Error reading power state\n");
 		goto err_unregister_input_dev;
 	}
 
-	printk(KERN_INFO "ACPI: %s [%s] (%s)\n",
-	       acpi_device_name(device), acpi_device_bid(device),
-	       !device->power.state ? "on" : "off");
+	pr_info("ACPI: %s [%s] (%s)\n",
+		acpi_device_name(device), acpi_device_bid(device),
+		!device->power.state ? "on" : "off");
 
 	fujitsu_hotkey->dev = device;
 
@@ -875,7 +876,7 @@
 		if (ACPI_FAILURE
 		    (acpi_evaluate_object
 		     (device->handle, METHOD_NAME__INI, NULL, NULL)))
-			printk(KERN_ERR "_INI Method failed\n");
+			pr_err("_INI Method failed\n");
 	}
 
 	i = 0;
@@ -897,8 +898,7 @@
 			call_fext_func(FUNC_RFKILL, 0x4, 0x0, 0x0);
 
 	/* Suspect this is a keymap of the application panel, print it */
-	printk(KERN_INFO "fujitsu-laptop: BTNI: [0x%x]\n",
-		call_fext_func(FUNC_BUTTONS, 0x0, 0x0, 0x0));
+	pr_info("BTNI: [0x%x]\n", call_fext_func(FUNC_BUTTONS, 0x0, 0x0, 0x0));
 
 #if defined(CONFIG_LEDS_CLASS) || defined(CONFIG_LEDS_CLASS_MODULE)
 	if (call_fext_func(FUNC_LEDS, 0x0, 0x0, 0x0) & LOGOLAMP_POWERON) {
@@ -907,8 +907,8 @@
 		if (result == 0) {
 			fujitsu_hotkey->logolamp_registered = 1;
 		} else {
-			printk(KERN_ERR "fujitsu-laptop: Could not register "
-			"LED handler for logo lamp, error %i\n", result);
+			pr_err("Could not register LED handler for logo lamp, error %i\n",
+			       result);
 		}
 	}
 
@@ -919,8 +919,8 @@
 		if (result == 0) {
 			fujitsu_hotkey->kblamps_registered = 1;
 		} else {
-			printk(KERN_ERR "fujitsu-laptop: Could not register "
-			"LED handler for keyboard lamps, error %i\n", result);
+			pr_err("Could not register LED handler for keyboard lamps, error %i\n",
+			       result);
 		}
 	}
 #endif
@@ -1169,8 +1169,7 @@
 			fujitsu->bl_device->props.power = 0;
 	}
 
-	printk(KERN_INFO "fujitsu-laptop: driver " FUJITSU_DRIVER_VERSION
-	       " successfully loaded.\n");
+	pr_info("driver " FUJITSU_DRIVER_VERSION " successfully loaded\n");
 
 	return 0;
 
@@ -1216,7 +1215,7 @@
 
 	kfree(fujitsu);
 
-	printk(KERN_INFO "fujitsu-laptop: driver unloaded.\n");
+	pr_info("driver unloaded\n");
 }
 
 module_init(fujitsu_init);
diff -druN linux-2.6.39-libre/drivers/platform/x86/hdaps.c linux-3.0-rc7-libre/drivers/platform/x86/hdaps.c
--- linux-2.6.39-libre/drivers/platform/x86/hdaps.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/platform/x86/hdaps.c	2011-07-11 19:51:52.000000000 -0400
@@ -26,6 +26,8 @@
  * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
  */
 
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/delay.h>
 #include <linux/platform_device.h>
 #include <linux/input-polldev.h>
@@ -238,7 +240,7 @@
 		     __check_latch(0x1611, 0x01))
 		goto out;
 
-	printk(KERN_DEBUG "hdaps: initial latch check good (0x%02x).\n",
+	printk(KERN_DEBUG "hdaps: initial latch check good (0x%02x)\n",
 	       __get_latch(0x1611));
 
 	outb(0x17, 0x1610);
@@ -299,7 +301,7 @@
 	if (ret)
 		return ret;
 
-	printk(KERN_INFO "hdaps: device successfully initialized.\n");
+	pr_info("device successfully initialized\n");
 	return 0;
 }
 
@@ -480,7 +482,7 @@
 /* hdaps_dmi_match - found a match.  return one, short-circuiting the hunt. */
 static int __init hdaps_dmi_match(const struct dmi_system_id *id)
 {
-	printk(KERN_INFO "hdaps: %s detected.\n", id->ident);
+	pr_info("%s detected\n", id->ident);
 	return 1;
 }
 
@@ -488,8 +490,7 @@
 static int __init hdaps_dmi_match_invert(const struct dmi_system_id *id)
 {
 	hdaps_invert = (unsigned long)id->driver_data;
-	printk(KERN_INFO "hdaps: inverting axis (%u) readings.\n",
-	       hdaps_invert);
+	pr_info("inverting axis (%u) readings\n", hdaps_invert);
 	return hdaps_dmi_match(id);
 }
 
@@ -543,7 +544,7 @@
 	int ret;
 
 	if (!dmi_check_system(hdaps_whitelist)) {
-		printk(KERN_WARNING "hdaps: supported laptop not found!\n");
+		pr_warn("supported laptop not found!\n");
 		ret = -ENODEV;
 		goto out;
 	}
@@ -595,7 +596,7 @@
 	if (ret)
 		goto out_idev;
 
-	printk(KERN_INFO "hdaps: driver successfully loaded.\n");
+	pr_info("driver successfully loaded\n");
 	return 0;
 
 out_idev:
@@ -609,7 +610,7 @@
 out_region:
 	release_region(HDAPS_LOW_PORT, HDAPS_NR_PORTS);
 out:
-	printk(KERN_WARNING "hdaps: driver init failed (ret=%d)!\n", ret);
+	pr_warn("driver init failed (ret=%d)!\n", ret);
 	return ret;
 }
 
@@ -622,7 +623,7 @@
 	platform_driver_unregister(&hdaps_driver);
 	release_region(HDAPS_LOW_PORT, HDAPS_NR_PORTS);
 
-	printk(KERN_INFO "hdaps: driver unloaded.\n");
+	pr_info("driver unloaded\n");
 }
 
 module_init(hdaps_init);
diff -druN linux-2.6.39-libre/drivers/platform/x86/hp-wmi.c linux-3.0-rc7-libre/drivers/platform/x86/hp-wmi.c
--- linux-2.6.39-libre/drivers/platform/x86/hp-wmi.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/platform/x86/hp-wmi.c	2011-07-11 19:51:52.000000000 -0400
@@ -24,6 +24,8 @@
  *  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>
@@ -54,9 +56,6 @@
 #define HPWMI_HOTKEY_QUERY 0xc
 #define HPWMI_WIRELESS2_QUERY 0x1b
 
-#define PREFIX "HP WMI: "
-#define UNIMP "Unimplemented "
-
 enum hp_wmi_radio {
 	HPWMI_WIFI = 0,
 	HPWMI_BLUETOOTH = 1,
@@ -208,6 +207,7 @@
 	};
 	struct acpi_buffer input = { sizeof(struct bios_args), &args };
 	struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL };
+	u32 rc;
 
 	if (WARN_ON(insize > sizeof(args.data)))
 		return -EINVAL;
@@ -225,14 +225,13 @@
 	}
 
 	bios_return = (struct bios_return *)obj->buffer.pointer;
+	rc = bios_return->return_code;
 
-	if (bios_return->return_code) {
-		if (bios_return->return_code != HPWMI_RET_UNKNOWN_CMDTYPE)
-			printk(KERN_WARNING PREFIX "query 0x%x returned "
-						   "error 0x%x\n",
-			       query, bios_return->return_code);
+	if (rc) {
+		if (rc != HPWMI_RET_UNKNOWN_CMDTYPE)
+			pr_warn("query 0x%x returned error 0x%x\n", query, rc);
 		kfree(obj);
-		return bios_return->return_code;
+		return rc;
 	}
 
 	if (!outsize) {
@@ -384,8 +383,7 @@
 
 		if (num >= state.count ||
 		    devstate->rfkill_id != rfkill2[i].id) {
-			printk(KERN_WARNING PREFIX "power configuration of "
-			       "the wireless devices unexpectedly changed\n");
+			pr_warn("power configuration of the wireless devices unexpectedly changed\n");
 			continue;
 		}
 
@@ -471,7 +469,7 @@
 
 	status = wmi_get_event_data(value, &response);
 	if (status != AE_OK) {
-		printk(KERN_INFO PREFIX "bad event status 0x%x\n", status);
+		pr_info("bad event status 0x%x\n", status);
 		return;
 	}
 
@@ -480,8 +478,7 @@
 	if (!obj)
 		return;
 	if (obj->type != ACPI_TYPE_BUFFER) {
-		printk(KERN_INFO "hp-wmi: Unknown response received %d\n",
-		       obj->type);
+		pr_info("Unknown response received %d\n", obj->type);
 		kfree(obj);
 		return;
 	}
@@ -498,8 +495,7 @@
 		event_id = *location;
 		event_data = *(location + 2);
 	} else {
-		printk(KERN_INFO "hp-wmi: Unknown buffer length %d\n",
-		       obj->buffer.length);
+		pr_info("Unknown buffer length %d\n", obj->buffer.length);
 		kfree(obj);
 		return;
 	}
@@ -527,8 +523,7 @@
 
 		if (!sparse_keymap_report_event(hp_wmi_input_dev,
 						key_code, 1, true))
-			printk(KERN_INFO PREFIX "Unknown key code - 0x%x\n",
-			       key_code);
+			pr_info("Unknown key code - 0x%x\n", key_code);
 		break;
 	case HPWMI_WIRELESS:
 		if (rfkill2_count) {
@@ -550,14 +545,12 @@
 					  hp_wmi_get_hw_state(HPWMI_WWAN));
 		break;
 	case HPWMI_CPU_BATTERY_THROTTLE:
-		printk(KERN_INFO PREFIX UNIMP "CPU throttle because of 3 Cell"
-		       " battery event detected\n");
+		pr_info("Unimplemented CPU throttle because of 3 Cell battery event detected\n");
 		break;
 	case HPWMI_LOCK_SWITCH:
 		break;
 	default:
-		printk(KERN_INFO PREFIX "Unknown event_id - %d - 0x%x\n",
-		       event_id, event_data);
+		pr_info("Unknown event_id - %d - 0x%x\n", event_id, event_data);
 		break;
 	}
 }
@@ -705,7 +698,7 @@
 		return err;
 
 	if (state.count > HPWMI_MAX_RFKILL2_DEVICES) {
-		printk(KERN_WARNING PREFIX "unable to parse 0x1b query output\n");
+		pr_warn("unable to parse 0x1b query output\n");
 		return -EINVAL;
 	}
 
@@ -727,14 +720,14 @@
 			name = "hp-wwan";
 			break;
 		default:
-			printk(KERN_WARNING PREFIX "unknown device type 0x%x\n",
-				 state.device[i].radio_type);
+			pr_warn("unknown device type 0x%x\n",
+				state.device[i].radio_type);
 			continue;
 		}
 
 		if (!state.device[i].vendor_id) {
-			printk(KERN_WARNING PREFIX "zero device %d while %d "
-			       "reported\n", i, state.count);
+			pr_warn("zero device %d while %d reported\n",
+				i, state.count);
 			continue;
 		}
 
@@ -755,8 +748,7 @@
 				    IS_HWBLOCKED(state.device[i].power));
 
 		if (!(state.device[i].power & HPWMI_POWER_BIOS))
-			printk(KERN_INFO PREFIX "device %s blocked by BIOS\n",
-			       name);
+			pr_info("device %s blocked by BIOS\n", name);
 
 		err = rfkill_register(rfkill);
 		if (err) {
diff -druN linux-2.6.39-libre/drivers/platform/x86/ibm_rtl.c linux-3.0-rc7-libre/drivers/platform/x86/ibm_rtl.c
--- linux-2.6.39-libre/drivers/platform/x86/ibm_rtl.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/platform/x86/ibm_rtl.c	2011-07-11 19:51:52.000000000 -0400
@@ -22,6 +22,8 @@
  *
  */
 
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/kernel.h>
 #include <linux/delay.h>
 #include <linux/module.h>
@@ -69,9 +71,10 @@
 #define RTL_SIGNATURE 0x0000005f4c54525fULL
 #define RTL_MASK      0x000000ffffffffffULL
 
-#define RTL_DEBUG(A, ...) do { \
-	if (debug) \
-		pr_info("ibm-rtl: " A, ##__VA_ARGS__ ); \
+#define RTL_DEBUG(fmt, ...)				\
+do {							\
+	if (debug)					\
+		pr_info(fmt, ##__VA_ARGS__);		\
 } while (0)
 
 static DEFINE_MUTEX(rtl_lock);
@@ -81,6 +84,19 @@
 static u8 rtl_cmd_type;
 static u8 rtl_cmd_width;
 
+#ifndef readq
+static inline __u64 readq(const volatile void __iomem *addr)
+{
+	const volatile u32 __iomem *p = addr;
+	u32 low, high;
+
+	low = readl(p);
+	high = readl(p + 1);
+
+	return low + ((u64)high << 32);
+}
+#endif
+
 static void __iomem *rtl_port_map(phys_addr_t addr, unsigned long len)
 {
 	if (rtl_cmd_type == RTL_ADDR_TYPE_MMIO)
@@ -101,7 +117,7 @@
 	int ret = 0, count = 0;
 	static u32 cmd_port_val;
 
-	RTL_DEBUG("%s(%d)\n", __FUNCTION__, value);
+	RTL_DEBUG("%s(%d)\n", __func__, value);
 
 	value = value == 1 ? RTL_CMD_ENTER_PRTM : RTL_CMD_EXIT_PRTM;
 
@@ -131,8 +147,8 @@
 		while (ioread8(&rtl_table->command)) {
 			msleep(10);
 			if (count++ > 500) {
-				pr_err("ibm-rtl: Hardware not responding to "
-					"mode switch request\n");
+				pr_err("Hardware not responding to "
+				       "mode switch request\n");
 				ret = -EIO;
 				break;
 			}
@@ -237,7 +253,7 @@
 	int ret = -ENODEV, i;
 
 	if (force)
-		pr_warning("ibm-rtl: module loaded by force\n");
+		pr_warn("module loaded by force\n");
 	/* first ensure that we are running on IBM HW */
 	else if (efi_enabled || !dmi_check_system(ibm_rtl_dmi_table))
 		return -ENODEV;
@@ -275,19 +291,19 @@
 		if ((readq(&tmp->signature) & RTL_MASK) == RTL_SIGNATURE) {
 			phys_addr_t addr;
 			unsigned int plen;
-			RTL_DEBUG("found RTL_SIGNATURE at %#llx\n", (u64)tmp);
+			RTL_DEBUG("found RTL_SIGNATURE at %p\n", tmp);
 			rtl_table = tmp;
 			/* The address, value, width and offset are platform
 			 * dependent and found in the ibm_rtl_table */
 			rtl_cmd_width = ioread8(&rtl_table->cmd_granularity);
 			rtl_cmd_type = ioread8(&rtl_table->cmd_address_type);
 			RTL_DEBUG("rtl_cmd_width = %u, rtl_cmd_type = %u\n",
-			      rtl_cmd_width, rtl_cmd_type);
+				  rtl_cmd_width, rtl_cmd_type);
 			addr = ioread32(&rtl_table->cmd_port_address);
 			RTL_DEBUG("addr = %#llx\n", (unsigned long long)addr);
 			plen = rtl_cmd_width/sizeof(char);
 			rtl_cmd_addr = rtl_port_map(addr, plen);
-			RTL_DEBUG("rtl_cmd_addr = %#llx\n", (u64)rtl_cmd_addr);
+			RTL_DEBUG("rtl_cmd_addr = %p\n", rtl_cmd_addr);
 			if (!rtl_cmd_addr) {
 				ret = -ENOMEM;
 				break;
diff -druN linux-2.6.39-libre/drivers/platform/x86/ideapad-laptop.c linux-3.0-rc7-libre/drivers/platform/x86/ideapad-laptop.c
--- linux-2.6.39-libre/drivers/platform/x86/ideapad-laptop.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/platform/x86/ideapad-laptop.c	2011-07-11 19:51:52.000000000 -0400
@@ -20,6 +20,8 @@
  *  02110-1301, USA.
  */
 
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/init.h>
diff -druN linux-2.6.39-libre/drivers/platform/x86/intel_ips.c linux-3.0-rc7-libre/drivers/platform/x86/intel_ips.c
--- linux-2.6.39-libre/drivers/platform/x86/intel_ips.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/platform/x86/intel_ips.c	2011-07-11 19:51:52.000000000 -0400
@@ -344,6 +344,19 @@
 static bool
 ips_gpu_turbo_enabled(struct ips_driver *ips);
 
+#ifndef readq
+static inline __u64 readq(const volatile void __iomem *addr)
+{
+	const volatile u32 __iomem *p = addr;
+	u32 low, high;
+
+	low = readl(p);
+	high = readl(p + 1);
+
+	return low + ((u64)high << 32);
+}
+#endif
+
 /**
  * ips_cpu_busy - is CPU busy?
  * @ips: IPS driver struct
diff -druN linux-2.6.39-libre/drivers/platform/x86/intel_menlow.c linux-3.0-rc7-libre/drivers/platform/x86/intel_menlow.c
--- linux-2.6.39-libre/drivers/platform/x86/intel_menlow.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/platform/x86/intel_menlow.c	2011-07-11 19:51:52.000000000 -0400
@@ -27,6 +27,8 @@
  *  to get/set bandwidth.
  */
 
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/init.h>
@@ -135,8 +137,7 @@
 	    acpi_evaluate_integer(handle, MEMORY_SET_BANDWIDTH, &arg_list,
 				  &temp);
 
-	printk(KERN_INFO
-	       "Bandwidth value was %ld: status is %d\n", state, status);
+	pr_info("Bandwidth value was %ld: status is %d\n", state, status);
 	if (ACPI_FAILURE(status))
 		return -EFAULT;
 
diff -druN linux-2.6.39-libre/drivers/platform/x86/intel_mid_powerbtn.c linux-3.0-rc7-libre/drivers/platform/x86/intel_mid_powerbtn.c
--- linux-2.6.39-libre/drivers/platform/x86/intel_mid_powerbtn.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/platform/x86/intel_mid_powerbtn.c	2011-07-11 19:51:52.000000000 -0400
@@ -23,58 +23,48 @@
 #include <linux/slab.h>
 #include <linux/platform_device.h>
 #include <linux/input.h>
+
 #include <asm/intel_scu_ipc.h>
 
 #define DRIVER_NAME "msic_power_btn"
 
-#define MSIC_IRQ_STAT	0x02
-  #define MSIC_IRQ_PB	(1 << 0)
-#define MSIC_PB_CONFIG	0x3e
 #define MSIC_PB_STATUS	0x3f
-  #define MSIC_PB_LEVEL (1 << 3) /* 1 - release, 0 - press */
-
-struct mfld_pb_priv {
-	struct input_dev *input;
-	unsigned int irq;
-};
+#define MSIC_PB_LEVEL	(1 << 3) /* 1 - release, 0 - press */
 
 static irqreturn_t mfld_pb_isr(int irq, void *dev_id)
 {
-	struct mfld_pb_priv *priv = dev_id;
+	struct input_dev *input = dev_id;
 	int ret;
 	u8 pbstat;
 
 	ret = intel_scu_ipc_ioread8(MSIC_PB_STATUS, &pbstat);
-	if (ret < 0)
-		return IRQ_HANDLED;
-
-	input_event(priv->input, EV_KEY, KEY_POWER, !(pbstat & MSIC_PB_LEVEL));
-	input_sync(priv->input);
+	if (ret < 0) {
+		dev_err(input->dev.parent, "Read error %d while reading"
+			       " MSIC_PB_STATUS\n", ret);
+	} else {
+		input_event(input, EV_KEY, KEY_POWER,
+			       !(pbstat & MSIC_PB_LEVEL));
+		input_sync(input);
+	}
 
 	return IRQ_HANDLED;
 }
 
 static int __devinit mfld_pb_probe(struct platform_device *pdev)
 {
-	struct mfld_pb_priv *priv;
 	struct input_dev *input;
-	int irq;
+	int irq = platform_get_irq(pdev, 0);
 	int error;
 
-	irq = platform_get_irq(pdev, 0);
 	if (irq < 0)
 		return -EINVAL;
 
-	priv = kzalloc(sizeof(struct mfld_pb_priv), GFP_KERNEL);
 	input = input_allocate_device();
-	if (!priv || !input) {
-		error = -ENOMEM;
-		goto err_free_mem;
+	if (!input) {
+		dev_err(&pdev->dev, "Input device allocation error\n");
+		return -ENOMEM;
 	}
 
-	priv->input = input;
-	priv->irq = irq;
-
 	input->name = pdev->name;
 	input->phys = "power-button/input0";
 	input->id.bustype = BUS_HOST;
@@ -82,42 +72,40 @@
 
 	input_set_capability(input, EV_KEY, KEY_POWER);
 
-	error = request_threaded_irq(priv->irq, NULL, mfld_pb_isr,
-				     0, DRIVER_NAME, priv);
+	error = request_threaded_irq(irq, NULL, mfld_pb_isr, 0,
+			DRIVER_NAME, input);
 	if (error) {
-		dev_err(&pdev->dev,
-			"unable to request irq %d for mfld power button\n",
-			irq);
-		goto err_free_mem;
+		dev_err(&pdev->dev, "Unable to request irq %d for mfld power"
+				"button\n", irq);
+		goto err_free_input;
 	}
 
 	error = input_register_device(input);
 	if (error) {
-		dev_err(&pdev->dev,
-			"unable to register input dev, error %d\n", error);
+		dev_err(&pdev->dev, "Unable to register input dev, error "
+				"%d\n", error);
 		goto err_free_irq;
 	}
 
-	platform_set_drvdata(pdev, priv);
+	platform_set_drvdata(pdev, input);
 	return 0;
 
 err_free_irq:
-	free_irq(priv->irq, priv);
-err_free_mem:
+	free_irq(irq, input);
+err_free_input:
 	input_free_device(input);
-	kfree(priv);
 	return error;
 }
 
 static int __devexit mfld_pb_remove(struct platform_device *pdev)
 {
-	struct mfld_pb_priv *priv = platform_get_drvdata(pdev);
-
-	free_irq(priv->irq, priv);
-	input_unregister_device(priv->input);
-	kfree(priv);
+	struct input_dev *input = platform_get_drvdata(pdev);
+	int irq = platform_get_irq(pdev, 0);
 
+	free_irq(irq, input);
+	input_unregister_device(input);
 	platform_set_drvdata(pdev, NULL);
+
 	return 0;
 }
 
diff -druN linux-2.6.39-libre/drivers/platform/x86/intel_mid_thermal.c linux-3.0-rc7-libre/drivers/platform/x86/intel_mid_thermal.c
--- linux-2.6.39-libre/drivers/platform/x86/intel_mid_thermal.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/platform/x86/intel_mid_thermal.c	2011-07-11 19:51:52.000000000 -0400
@@ -37,49 +37,50 @@
 #include <asm/intel_scu_ipc.h>
 
 /* Number of thermal sensors */
-#define MSIC_THERMAL_SENSORS   4
+#define MSIC_THERMAL_SENSORS	4
 
 /* ADC1 - thermal registers */
-#define MSIC_THERM_ADC1CNTL1   0x1C0
-#define MSIC_ADC_ENBL          0x10
-#define MSIC_ADC_START         0x08
+#define MSIC_THERM_ADC1CNTL1	0x1C0
+#define MSIC_ADC_ENBL		0x10
+#define MSIC_ADC_START		0x08
 
-#define MSIC_THERM_ADC1CNTL3   0x1C2
-#define MSIC_ADCTHERM_ENBL     0x04
-#define MSIC_ADCRRDATA_ENBL    0x05
-#define MSIC_CHANL_MASK_VAL    0x0F
+#define MSIC_THERM_ADC1CNTL3	0x1C2
+#define MSIC_ADCTHERM_ENBL	0x04
+#define MSIC_ADCRRDATA_ENBL	0x05
+#define MSIC_CHANL_MASK_VAL	0x0F
 
-#define MSIC_STOPBIT_MASK      16
-#define MSIC_ADCTHERM_MASK     4
-#define ADC_CHANLS_MAX         15 /* Number of ADC channels */
-#define ADC_LOOP_MAX           (ADC_CHANLS_MAX - MSIC_THERMAL_SENSORS)
+#define MSIC_STOPBIT_MASK	16
+#define MSIC_ADCTHERM_MASK	4
+/* Number of ADC channels */
+#define ADC_CHANLS_MAX		15
+#define ADC_LOOP_MAX		(ADC_CHANLS_MAX - MSIC_THERMAL_SENSORS)
 
 /* ADC channel code values */
-#define SKIN_SENSOR0_CODE      0x08
-#define SKIN_SENSOR1_CODE      0x09
-#define SYS_SENSOR_CODE                0x0A
-#define MSIC_DIE_SENSOR_CODE   0x03
+#define SKIN_SENSOR0_CODE	0x08
+#define SKIN_SENSOR1_CODE	0x09
+#define SYS_SENSOR_CODE		0x0A
+#define MSIC_DIE_SENSOR_CODE	0x03
 
-#define SKIN_THERM_SENSOR0     0
-#define SKIN_THERM_SENSOR1     1
-#define SYS_THERM_SENSOR2      2
-#define MSIC_DIE_THERM_SENSOR3 3
+#define SKIN_THERM_SENSOR0	0
+#define SKIN_THERM_SENSOR1	1
+#define SYS_THERM_SENSOR2	2
+#define MSIC_DIE_THERM_SENSOR3	3
 
 /* ADC code range */
-#define ADC_MAX                        977
-#define ADC_MIN                        162
-#define ADC_VAL0C              887
-#define ADC_VAL20C             720
-#define ADC_VAL40C             508
-#define ADC_VAL60C             315
+#define ADC_MAX			977
+#define ADC_MIN			162
+#define ADC_VAL0C		887
+#define ADC_VAL20C		720
+#define ADC_VAL40C		508
+#define ADC_VAL60C		315
 
 /* ADC base addresses */
-#define ADC_CHNL_START_ADDR    0x1C5   /* increments by 1 */
-#define ADC_DATA_START_ADDR     0x1D4   /* increments by 2 */
+#define ADC_CHNL_START_ADDR	0x1C5	/* increments by 1 */
+#define ADC_DATA_START_ADDR	0x1D4	/* increments by 2 */
 
 /* MSIC die attributes */
-#define MSIC_DIE_ADC_MIN       488
-#define MSIC_DIE_ADC_MAX       1004
+#define MSIC_DIE_ADC_MIN	488
+#define MSIC_DIE_ADC_MAX	1004
 
 /* This holds the address of the first free ADC channel,
  * among the 15 channels
@@ -87,15 +88,15 @@
 static int channel_index;
 
 struct platform_info {
-       struct platform_device *pdev;
-       struct thermal_zone_device *tzd[MSIC_THERMAL_SENSORS];
+	struct platform_device *pdev;
+	struct thermal_zone_device *tzd[MSIC_THERMAL_SENSORS];
 };
 
 struct thermal_device_info {
-       unsigned int chnl_addr;
-       int direct;
-       /* This holds the current temperature in millidegree celsius */
-       long curr_temp;
+	unsigned int chnl_addr;
+	int direct;
+	/* This holds the current temperature in millidegree celsius */
+	long curr_temp;
 };
 
 /**
@@ -106,7 +107,7 @@
  */
 static int to_msic_die_temp(uint16_t adc_val)
 {
-       return (368 * (adc_val) / 1000) - 220;
+	return (368 * (adc_val) / 1000) - 220;
 }
 
 /**
@@ -118,7 +119,7 @@
  */
 static int is_valid_adc(uint16_t adc_val, uint16_t min, uint16_t max)
 {
-       return (adc_val >= min) && (adc_val <= max);
+	return (adc_val >= min) && (adc_val <= max);
 }
 
 /**
@@ -136,35 +137,35 @@
  */
 static int adc_to_temp(int direct, uint16_t adc_val, unsigned long *tp)
 {
-       int temp;
+	int temp;
 
-       /* Direct conversion for die temperature */
-       if (direct) {
-               if (is_valid_adc(adc_val, MSIC_DIE_ADC_MIN, MSIC_DIE_ADC_MAX)) {
-                       *tp = to_msic_die_temp(adc_val) * 1000;
-                       return 0;
-               }
-               return -ERANGE;
-       }
+	/* Direct conversion for die temperature */
+	if (direct) {
+		if (is_valid_adc(adc_val, MSIC_DIE_ADC_MIN, MSIC_DIE_ADC_MAX)) {
+			*tp = to_msic_die_temp(adc_val) * 1000;
+			return 0;
+		}
+		return -ERANGE;
+	}
 
-       if (!is_valid_adc(adc_val, ADC_MIN, ADC_MAX))
-               return -ERANGE;
+	if (!is_valid_adc(adc_val, ADC_MIN, ADC_MAX))
+		return -ERANGE;
 
-       /* Linear approximation for skin temperature */
-       if (adc_val > ADC_VAL0C)
-               temp = 177 - (adc_val/5);
-       else if ((adc_val <= ADC_VAL0C) && (adc_val > ADC_VAL20C))
-               temp = 111 - (adc_val/8);
-       else if ((adc_val <= ADC_VAL20C) && (adc_val > ADC_VAL40C))
-               temp = 92 - (adc_val/10);
-       else if ((adc_val <= ADC_VAL40C) && (adc_val > ADC_VAL60C))
-               temp = 91 - (adc_val/10);
-       else
-               temp = 112 - (adc_val/6);
+	/* Linear approximation for skin temperature */
+	if (adc_val > ADC_VAL0C)
+		temp = 177 - (adc_val/5);
+	else if ((adc_val <= ADC_VAL0C) && (adc_val > ADC_VAL20C))
+		temp = 111 - (adc_val/8);
+	else if ((adc_val <= ADC_VAL20C) && (adc_val > ADC_VAL40C))
+		temp = 92 - (adc_val/10);
+	else if ((adc_val <= ADC_VAL40C) && (adc_val > ADC_VAL60C))
+		temp = 91 - (adc_val/10);
+	else
+		temp = 112 - (adc_val/6);
 
-       /* Convert temperature in celsius to milli degree celsius */
-       *tp = temp * 1000;
-       return 0;
+	/* Convert temperature in celsius to milli degree celsius */
+	*tp = temp * 1000;
+	return 0;
 }
 
 /**
@@ -178,47 +179,47 @@
  */
 static int mid_read_temp(struct thermal_zone_device *tzd, unsigned long *temp)
 {
-       struct thermal_device_info *td_info = tzd->devdata;
-       uint16_t adc_val, addr;
-       uint8_t data = 0;
-       int ret;
-       unsigned long curr_temp;
+	struct thermal_device_info *td_info = tzd->devdata;
+	uint16_t adc_val, addr;
+	uint8_t data = 0;
+	int ret;
+	unsigned long curr_temp;
 
 
-       addr = td_info->chnl_addr;
+	addr = td_info->chnl_addr;
 
-       /* Enable the msic for conversion before reading */
-       ret = intel_scu_ipc_iowrite8(MSIC_THERM_ADC1CNTL3, MSIC_ADCRRDATA_ENBL);
-       if (ret)
-               return ret;
+	/* Enable the msic for conversion before reading */
+	ret = intel_scu_ipc_iowrite8(MSIC_THERM_ADC1CNTL3, MSIC_ADCRRDATA_ENBL);
+	if (ret)
+		return ret;
 
-       /* Re-toggle the RRDATARD bit (temporary workaround) */
-       ret = intel_scu_ipc_iowrite8(MSIC_THERM_ADC1CNTL3, MSIC_ADCTHERM_ENBL);
-       if (ret)
-               return ret;
+	/* Re-toggle the RRDATARD bit (temporary workaround) */
+	ret = intel_scu_ipc_iowrite8(MSIC_THERM_ADC1CNTL3, MSIC_ADCTHERM_ENBL);
+	if (ret)
+		return ret;
 
-       /* Read the higher bits of data */
-       ret = intel_scu_ipc_ioread8(addr, &data);
-       if (ret)
-               return ret;
+	/* Read the higher bits of data */
+	ret = intel_scu_ipc_ioread8(addr, &data);
+	if (ret)
+		return ret;
 
-       /* Shift bits to accommodate the lower two data bits */
-       adc_val = (data << 2);
-       addr++;
+	/* Shift bits to accommodate the lower two data bits */
+	adc_val = (data << 2);
+	addr++;
 
-       ret = intel_scu_ipc_ioread8(addr, &data);/* Read lower bits */
-       if (ret)
-               return ret;
+	ret = intel_scu_ipc_ioread8(addr, &data);/* Read lower bits */
+	if (ret)
+		return ret;
 
-       /* Adding lower two bits to the higher bits */
-       data &= 03;
-       adc_val += data;
+	/* Adding lower two bits to the higher bits */
+	data &= 03;
+	adc_val += data;
 
-       /* Convert ADC value to temperature */
-       ret = adc_to_temp(td_info->direct, adc_val, &curr_temp);
-       if (ret == 0)
-               *temp = td_info->curr_temp = curr_temp;
-       return ret;
+	/* Convert ADC value to temperature */
+	ret = adc_to_temp(td_info->direct, adc_val, &curr_temp);
+	if (ret == 0)
+		*temp = td_info->curr_temp = curr_temp;
+	return ret;
 }
 
 /**
@@ -231,22 +232,21 @@
  */
 static int configure_adc(int val)
 {
-       int ret;
-       uint8_t data;
-
-       ret = intel_scu_ipc_ioread8(MSIC_THERM_ADC1CNTL1, &data);
-       if (ret)
-               return ret;
+	int ret;
+	uint8_t data;
 
-       if (val) {
-               /* Enable and start the ADC */
-               data |= (MSIC_ADC_ENBL | MSIC_ADC_START);
-       } else {
-               /* Just stop the ADC */
-               data &= (~MSIC_ADC_START);
-       }
+	ret = intel_scu_ipc_ioread8(MSIC_THERM_ADC1CNTL1, &data);
+	if (ret)
+		return ret;
 
-       return intel_scu_ipc_iowrite8(MSIC_THERM_ADC1CNTL1, data);
+	if (val) {
+		/* Enable and start the ADC */
+		data |= (MSIC_ADC_ENBL | MSIC_ADC_START);
+	} else {
+		/* Just stop the ADC */
+		data &= (~MSIC_ADC_START);
+	}
+	return intel_scu_ipc_iowrite8(MSIC_THERM_ADC1CNTL1, data);
 }
 
 /**
@@ -259,30 +259,30 @@
  */
 static int set_up_therm_channel(u16 base_addr)
 {
-       int ret;
+	int ret;
 
-       /* Enable all the sensor channels */
-       ret = intel_scu_ipc_iowrite8(base_addr, SKIN_SENSOR0_CODE);
-       if (ret)
-               return ret;
+	/* Enable all the sensor channels */
+	ret = intel_scu_ipc_iowrite8(base_addr, SKIN_SENSOR0_CODE);
+	if (ret)
+		return ret;
 
-       ret = intel_scu_ipc_iowrite8(base_addr + 1, SKIN_SENSOR1_CODE);
-       if (ret)
-               return ret;
+	ret = intel_scu_ipc_iowrite8(base_addr + 1, SKIN_SENSOR1_CODE);
+	if (ret)
+		return ret;
 
-       ret = intel_scu_ipc_iowrite8(base_addr + 2, SYS_SENSOR_CODE);
-       if (ret)
-               return ret;
+	ret = intel_scu_ipc_iowrite8(base_addr + 2, SYS_SENSOR_CODE);
+	if (ret)
+		return ret;
 
-       /* Since this is the last channel, set the stop bit
-          to 1 by ORing the DIE_SENSOR_CODE with 0x10 */
-       ret = intel_scu_ipc_iowrite8(base_addr + 3,
-                                       (MSIC_DIE_SENSOR_CODE | 0x10));
-       if (ret)
-               return ret;
+	/* Since this is the last channel, set the stop bit
+	 * to 1 by ORing the DIE_SENSOR_CODE with 0x10 */
+	ret = intel_scu_ipc_iowrite8(base_addr + 3,
+			(MSIC_DIE_SENSOR_CODE | 0x10));
+	if (ret)
+		return ret;
 
-       /* Enable ADC and start it */
-       return configure_adc(1);
+	/* Enable ADC and start it */
+	return configure_adc(1);
 }
 
 /**
@@ -293,13 +293,13 @@
  */
 static int reset_stopbit(uint16_t addr)
 {
-       int ret;
-       uint8_t data;
-       ret = intel_scu_ipc_ioread8(addr, &data);
-       if (ret)
-               return ret;
-       /* Set the stop bit to zero */
-       return intel_scu_ipc_iowrite8(addr, (data & 0xEF));
+	int ret;
+	uint8_t data;
+	ret = intel_scu_ipc_ioread8(addr, &data);
+	if (ret)
+		return ret;
+	/* Set the stop bit to zero */
+	return intel_scu_ipc_iowrite8(addr, (data & 0xEF));
 }
 
 /**
@@ -317,30 +317,30 @@
  */
 static int find_free_channel(void)
 {
-       int ret;
-       int i;
-       uint8_t data;
+	int ret;
+	int i;
+	uint8_t data;
 
-       /* check whether ADC is enabled */
-       ret = intel_scu_ipc_ioread8(MSIC_THERM_ADC1CNTL1, &data);
-       if (ret)
-               return ret;
+	/* check whether ADC is enabled */
+	ret = intel_scu_ipc_ioread8(MSIC_THERM_ADC1CNTL1, &data);
+	if (ret)
+		return ret;
 
-       if ((data & MSIC_ADC_ENBL) == 0)
-               return 0;
+	if ((data & MSIC_ADC_ENBL) == 0)
+		return 0;
 
-       /* ADC is already enabled; Looking for an empty channel */
-       for (i = 0; i < ADC_CHANLS_MAX; i++) {
-               ret = intel_scu_ipc_ioread8(ADC_CHNL_START_ADDR + i, &data);
-               if (ret)
-                       return ret;
+	/* ADC is already enabled; Looking for an empty channel */
+	for (i = 0; i < ADC_CHANLS_MAX; i++) {
+		ret = intel_scu_ipc_ioread8(ADC_CHNL_START_ADDR + i, &data);
+		if (ret)
+			return ret;
 
-               if (data & MSIC_STOPBIT_MASK) {
-                       ret = i;
-                       break;
-               }
-       }
-       return (ret > ADC_LOOP_MAX) ? (-EINVAL) : ret;
+		if (data & MSIC_STOPBIT_MASK) {
+			ret = i;
+			break;
+		}
+	}
+	return (ret > ADC_LOOP_MAX) ? (-EINVAL) : ret;
 }
 
 /**
@@ -351,48 +351,48 @@
  */
 static int mid_initialize_adc(struct device *dev)
 {
-       u8  data;
-       u16 base_addr;
-       int ret;
+	u8  data;
+	u16 base_addr;
+	int ret;
 
-       /*
-        * Ensure that adctherm is disabled before we
-        * initialize the ADC
-        */
-       ret = intel_scu_ipc_ioread8(MSIC_THERM_ADC1CNTL3, &data);
-       if (ret)
-               return ret;
+	/*
+	 * Ensure that adctherm is disabled before we
+	 * initialize the ADC
+	 */
+	ret = intel_scu_ipc_ioread8(MSIC_THERM_ADC1CNTL3, &data);
+	if (ret)
+		return ret;
 
-       if (data & MSIC_ADCTHERM_MASK)
-               dev_warn(dev, "ADCTHERM already set");
+	if (data & MSIC_ADCTHERM_MASK)
+		dev_warn(dev, "ADCTHERM already set");
 
-       /* Index of the first channel in which the stop bit is set */
-       channel_index = find_free_channel();
-       if (channel_index < 0) {
-               dev_err(dev, "No free ADC channels");
-               return channel_index;
-       }
+	/* Index of the first channel in which the stop bit is set */
+	channel_index = find_free_channel();
+	if (channel_index < 0) {
+		dev_err(dev, "No free ADC channels");
+		return channel_index;
+	}
 
-       base_addr = ADC_CHNL_START_ADDR + channel_index;
+	base_addr = ADC_CHNL_START_ADDR + channel_index;
 
-       if (!(channel_index == 0 || channel_index == ADC_LOOP_MAX)) {
-               /* Reset stop bit for channels other than 0 and 12 */
-               ret = reset_stopbit(base_addr);
-               if (ret)
-                       return ret;
+	if (!(channel_index == 0 || channel_index == ADC_LOOP_MAX)) {
+		/* Reset stop bit for channels other than 0 and 12 */
+		ret = reset_stopbit(base_addr);
+		if (ret)
+			return ret;
 
-               /* Index of the first free channel */
-               base_addr++;
-               channel_index++;
-       }
+		/* Index of the first free channel */
+		base_addr++;
+		channel_index++;
+	}
 
-       ret = set_up_therm_channel(base_addr);
-       if (ret) {
-               dev_err(dev, "unable to enable ADC");
-               return ret;
-       }
-       dev_dbg(dev, "ADC initialization successful");
-       return ret;
+	ret = set_up_therm_channel(base_addr);
+	if (ret) {
+		dev_err(dev, "unable to enable ADC");
+		return ret;
+	}
+	dev_dbg(dev, "ADC initialization successful");
+	return ret;
 }
 
 /**
@@ -403,18 +403,18 @@
  */
 static struct thermal_device_info *initialize_sensor(int index)
 {
-       struct thermal_device_info *td_info =
-               kzalloc(sizeof(struct thermal_device_info), GFP_KERNEL);
+	struct thermal_device_info *td_info =
+		kzalloc(sizeof(struct thermal_device_info), GFP_KERNEL);
 
-       if (!td_info)
-               return NULL;
+	if (!td_info)
+		return NULL;
 
-       /* Set the base addr of the channel for this sensor */
-       td_info->chnl_addr = ADC_DATA_START_ADDR + 2 * (channel_index + index);
-       /* Sensor 3 is direct conversion */
-       if (index == 3)
-               td_info->direct = 1;
-       return td_info;
+	/* Set the base addr of the channel for this sensor */
+	td_info->chnl_addr = ADC_DATA_START_ADDR + 2 * (channel_index + index);
+	/* Sensor 3 is direct conversion */
+	if (index == 3)
+		td_info->direct = 1;
+	return td_info;
 }
 
 /**
@@ -425,7 +425,7 @@
  */
 static int mid_thermal_resume(struct platform_device *pdev)
 {
-       return mid_initialize_adc(&pdev->dev);
+	return mid_initialize_adc(&pdev->dev);
 }
 
 /**
@@ -437,12 +437,12 @@
  */
 static int mid_thermal_suspend(struct platform_device *pdev, pm_message_t mesg)
 {
-       /*
-        * This just stops the ADC and does not disable it.
-        * temporary workaround until we have a generic ADC driver.
-        * If 0 is passed, it disables the ADC.
-        */
-       return configure_adc(0);
+	/*
+	 * This just stops the ADC and does not disable it.
+	 * temporary workaround until we have a generic ADC driver.
+	 * If 0 is passed, it disables the ADC.
+	 */
+	return configure_adc(0);
 }
 
 /**
@@ -453,16 +453,15 @@
  */
 static int read_curr_temp(struct thermal_zone_device *tzd, unsigned long *temp)
 {
-       WARN_ON(tzd == NULL);
-       return mid_read_temp(tzd, temp);
+	WARN_ON(tzd == NULL);
+	return mid_read_temp(tzd, temp);
 }
 
 /* Can't be const */
 static struct thermal_zone_device_ops tzd_ops = {
-       .get_temp = read_curr_temp,
+	.get_temp = read_curr_temp,
 };
 
-
 /**
  * mid_thermal_probe - mfld thermal initialize
  * @pdev: platform device structure
@@ -472,46 +471,45 @@
  */
 static int mid_thermal_probe(struct platform_device *pdev)
 {
-       static char *name[MSIC_THERMAL_SENSORS] = {
-               "skin0", "skin1", "sys", "msicdie"
-       };
+	static char *name[MSIC_THERMAL_SENSORS] = {
+		"skin0", "skin1", "sys", "msicdie"
+	};
 
-       int ret;
-       int i;
-       struct platform_info *pinfo;
+	int ret;
+	int i;
+	struct platform_info *pinfo;
 
-       pinfo = kzalloc(sizeof(struct platform_info), GFP_KERNEL);
-       if (!pinfo)
-               return -ENOMEM;
+	pinfo = kzalloc(sizeof(struct platform_info), GFP_KERNEL);
+	if (!pinfo)
+		return -ENOMEM;
 
-       /* Initializing the hardware */
-       ret = mid_initialize_adc(&pdev->dev);
-       if (ret) {
-               dev_err(&pdev->dev, "ADC init failed");
-               kfree(pinfo);
-               return ret;
-       }
+	/* Initializing the hardware */
+	ret = mid_initialize_adc(&pdev->dev);
+	if (ret) {
+		dev_err(&pdev->dev, "ADC init failed");
+		kfree(pinfo);
+		return ret;
+	}
 
-       /* Register each sensor with the generic thermal framework*/
-       for (i = 0; i < MSIC_THERMAL_SENSORS; i++) {
-               pinfo->tzd[i] = thermal_zone_device_register(name[i],
-                                       0, initialize_sensor(i),
-                                       &tzd_ops, 0, 0, 0, 0);
-               if (IS_ERR(pinfo->tzd[i]))
-                       goto reg_fail;
-       }
+	/* Register each sensor with the generic thermal framework*/
+	for (i = 0; i < MSIC_THERMAL_SENSORS; i++) {
+		pinfo->tzd[i] = thermal_zone_device_register(name[i],
+				0, initialize_sensor(i), &tzd_ops, 0, 0, 0, 0);
+		if (IS_ERR(pinfo->tzd[i]))
+			goto reg_fail;
+	}
 
-       pinfo->pdev = pdev;
-       platform_set_drvdata(pdev, pinfo);
-       return 0;
+	pinfo->pdev = pdev;
+	platform_set_drvdata(pdev, pinfo);
+	return 0;
 
 reg_fail:
-       ret = PTR_ERR(pinfo->tzd[i]);
-       while (--i >= 0)
-               thermal_zone_device_unregister(pinfo->tzd[i]);
-       configure_adc(0);
-       kfree(pinfo);
-       return ret;
+	ret = PTR_ERR(pinfo->tzd[i]);
+	while (--i >= 0)
+		thermal_zone_device_unregister(pinfo->tzd[i]);
+	configure_adc(0);
+	kfree(pinfo);
+	return ret;
 }
 
 /**
@@ -523,49 +521,46 @@
  */
 static int mid_thermal_remove(struct platform_device *pdev)
 {
-       int i;
-       struct platform_info *pinfo = platform_get_drvdata(pdev);
+	int i;
+	struct platform_info *pinfo = platform_get_drvdata(pdev);
 
-       for (i = 0; i < MSIC_THERMAL_SENSORS; i++)
-               thermal_zone_device_unregister(pinfo->tzd[i]);
+	for (i = 0; i < MSIC_THERMAL_SENSORS; i++)
+		thermal_zone_device_unregister(pinfo->tzd[i]);
 
-       platform_set_drvdata(pdev, NULL);
+	kfree(pinfo);
+	platform_set_drvdata(pdev, NULL);
 
-       /* Stop the ADC */
-       return configure_adc(0);
+	/* Stop the ADC */
+	return configure_adc(0);
 }
 
-/*********************************************************************
- *             Driver initialisation and finalization
- *********************************************************************/
-
 #define DRIVER_NAME "msic_sensor"
 
 static const struct platform_device_id therm_id_table[] = {
-       { DRIVER_NAME, 1 },
-       { }
+	{ DRIVER_NAME, 1 },
+	{ }
 };
 
 static struct platform_driver mid_thermal_driver = {
-       .driver = {
-               .name = DRIVER_NAME,
-               .owner = THIS_MODULE,
-       },
-       .probe = mid_thermal_probe,
-       .suspend = mid_thermal_suspend,
-       .resume = mid_thermal_resume,
-       .remove = __devexit_p(mid_thermal_remove),
-       .id_table = therm_id_table,
+	.driver = {
+		.name = DRIVER_NAME,
+		.owner = THIS_MODULE,
+	},
+	.probe = mid_thermal_probe,
+	.suspend = mid_thermal_suspend,
+	.resume = mid_thermal_resume,
+	.remove = __devexit_p(mid_thermal_remove),
+	.id_table = therm_id_table,
 };
 
 static int __init mid_thermal_module_init(void)
 {
-       return platform_driver_register(&mid_thermal_driver);
+	return platform_driver_register(&mid_thermal_driver);
 }
 
 static void __exit mid_thermal_module_exit(void)
 {
-       platform_driver_unregister(&mid_thermal_driver);
+	platform_driver_unregister(&mid_thermal_driver);
 }
 
 module_init(mid_thermal_module_init);
diff -druN linux-2.6.39-libre/drivers/platform/x86/intel_oaktrail.c linux-3.0-rc7-libre/drivers/platform/x86/intel_oaktrail.c
--- linux-2.6.39-libre/drivers/platform/x86/intel_oaktrail.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/platform/x86/intel_oaktrail.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,397 @@
+/*
+ * intel_oaktrail.c - Intel OakTrail Platform support.
+ *
+ * Copyright (C) 2010-2011 Intel Corporation
+ * Author: Yin Kangkai (kangkai.yin@intel.com)
+ *
+ * based on Compal driver, Copyright (C) 2008 Cezary Jackiewicz
+ * <cezary.jackiewicz (at) gmail.com>, based on MSI driver
+ * Copyright (C) 2006 Lennart Poettering <mzxreary (at) 0pointer (dot) 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.
+ *
+ * This driver does below things:
+ * 1. registers itself in the Linux backlight control in
+ *    /sys/class/backlight/intel_oaktrail/
+ *
+ * 2. registers in the rfkill subsystem here: /sys/class/rfkill/rfkillX/
+ *    for these components: wifi, bluetooth, wwan (3g), gps
+ *
+ * This driver might work on other products based on Oaktrail. If you
+ * want to try it you can pass force=1 as argument to the module which
+ * will force it to load even when the DMI data doesn't identify the
+ * product as compatible.
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/acpi.h>
+#include <linux/fb.h>
+#include <linux/mutex.h>
+#include <linux/err.h>
+#include <linux/i2c.h>
+#include <linux/backlight.h>
+#include <linux/platform_device.h>
+#include <linux/dmi.h>
+#include <linux/rfkill.h>
+#include <acpi/acpi_bus.h>
+#include <acpi/acpi_drivers.h>
+
+
+#define DRIVER_NAME	"intel_oaktrail"
+#define DRIVER_VERSION	"0.4ac1"
+
+/*
+ * This is the devices status address in EC space, and the control bits
+ * definition:
+ *
+ * (1 << 0):	Camera enable/disable, RW.
+ * (1 << 1):	Bluetooth enable/disable, RW.
+ * (1 << 2):	GPS enable/disable, RW.
+ * (1 << 3):	WiFi enable/disable, RW.
+ * (1 << 4):	WWAN (3G) enable/disalbe, RW.
+ * (1 << 5):	Touchscreen enable/disable, Read Only.
+ */
+#define OT_EC_DEVICE_STATE_ADDRESS	0xD6
+
+#define OT_EC_CAMERA_MASK	(1 << 0)
+#define OT_EC_BT_MASK		(1 << 1)
+#define OT_EC_GPS_MASK		(1 << 2)
+#define OT_EC_WIFI_MASK		(1 << 3)
+#define OT_EC_WWAN_MASK		(1 << 4)
+#define OT_EC_TS_MASK		(1 << 5)
+
+/*
+ * This is the address in EC space and commands used to control LCD backlight:
+ *
+ * Two steps needed to change the LCD backlight:
+ *   1. write the backlight percentage into OT_EC_BL_BRIGHTNESS_ADDRESS;
+ *   2. write OT_EC_BL_CONTROL_ON_DATA into OT_EC_BL_CONTROL_ADDRESS.
+ *
+ * To read the LCD back light, just read out the value from
+ * OT_EC_BL_BRIGHTNESS_ADDRESS.
+ *
+ * LCD backlight brightness range: 0 - 100 (OT_EC_BL_BRIGHTNESS_MAX)
+ */
+#define OT_EC_BL_BRIGHTNESS_ADDRESS	0x44
+#define OT_EC_BL_BRIGHTNESS_MAX		100
+#define OT_EC_BL_CONTROL_ADDRESS	0x3A
+#define OT_EC_BL_CONTROL_ON_DATA	0x1A
+
+
+static int force;
+module_param(force, bool, 0);
+MODULE_PARM_DESC(force, "Force driver load, ignore DMI data");
+
+static struct platform_device *oaktrail_device;
+static struct backlight_device *oaktrail_bl_device;
+static struct rfkill *bt_rfkill;
+static struct rfkill *gps_rfkill;
+static struct rfkill *wifi_rfkill;
+static struct rfkill *wwan_rfkill;
+
+
+/* rfkill */
+static int oaktrail_rfkill_set(void *data, bool blocked)
+{
+	u8 value;
+	u8 result;
+	unsigned long radio = (unsigned long) data;
+
+	ec_read(OT_EC_DEVICE_STATE_ADDRESS, &result);
+
+	if (!blocked)
+		value = (u8) (result | radio);
+	else
+		value = (u8) (result & ~radio);
+
+	ec_write(OT_EC_DEVICE_STATE_ADDRESS, value);
+
+	return 0;
+}
+
+static const struct rfkill_ops oaktrail_rfkill_ops = {
+	.set_block = oaktrail_rfkill_set,
+};
+
+static struct rfkill *oaktrail_rfkill_new(char *name, enum rfkill_type type,
+					  unsigned long mask)
+{
+	struct rfkill *rfkill_dev;
+	u8 value;
+	int err;
+
+	rfkill_dev = rfkill_alloc(name, &oaktrail_device->dev, type,
+				  &oaktrail_rfkill_ops, (void *)mask);
+	if (!rfkill_dev)
+		return ERR_PTR(-ENOMEM);
+
+	ec_read(OT_EC_DEVICE_STATE_ADDRESS, &value);
+	rfkill_init_sw_state(rfkill_dev, (value & mask) != 1);
+
+	err = rfkill_register(rfkill_dev);
+	if (err) {
+		rfkill_destroy(rfkill_dev);
+		return ERR_PTR(err);
+	}
+
+	return rfkill_dev;
+}
+
+static inline void __oaktrail_rfkill_cleanup(struct rfkill *rf)
+{
+	if (rf) {
+		rfkill_unregister(rf);
+		rfkill_destroy(rf);
+	}
+}
+
+static void oaktrail_rfkill_cleanup(void)
+{
+	__oaktrail_rfkill_cleanup(wifi_rfkill);
+	__oaktrail_rfkill_cleanup(bt_rfkill);
+	__oaktrail_rfkill_cleanup(gps_rfkill);
+	__oaktrail_rfkill_cleanup(wwan_rfkill);
+}
+
+static int oaktrail_rfkill_init(void)
+{
+	int ret;
+
+	wifi_rfkill = oaktrail_rfkill_new("oaktrail-wifi",
+					  RFKILL_TYPE_WLAN,
+					  OT_EC_WIFI_MASK);
+	if (IS_ERR(wifi_rfkill)) {
+		ret = PTR_ERR(wifi_rfkill);
+		wifi_rfkill = NULL;
+		goto cleanup;
+	}
+
+	bt_rfkill = oaktrail_rfkill_new("oaktrail-bluetooth",
+					RFKILL_TYPE_BLUETOOTH,
+					OT_EC_BT_MASK);
+	if (IS_ERR(bt_rfkill)) {
+		ret = PTR_ERR(bt_rfkill);
+		bt_rfkill = NULL;
+		goto cleanup;
+	}
+
+	gps_rfkill = oaktrail_rfkill_new("oaktrail-gps",
+					 RFKILL_TYPE_GPS,
+					 OT_EC_GPS_MASK);
+	if (IS_ERR(gps_rfkill)) {
+		ret = PTR_ERR(gps_rfkill);
+		gps_rfkill = NULL;
+		goto cleanup;
+	}
+
+	wwan_rfkill = oaktrail_rfkill_new("oaktrail-wwan",
+					  RFKILL_TYPE_WWAN,
+					  OT_EC_WWAN_MASK);
+	if (IS_ERR(wwan_rfkill)) {
+		ret = PTR_ERR(wwan_rfkill);
+		wwan_rfkill = NULL;
+		goto cleanup;
+	}
+
+	return 0;
+
+cleanup:
+	oaktrail_rfkill_cleanup();
+	return ret;
+}
+
+
+/* backlight */
+static int get_backlight_brightness(struct backlight_device *b)
+{
+	u8 value;
+	ec_read(OT_EC_BL_BRIGHTNESS_ADDRESS, &value);
+
+	return value;
+}
+
+static int set_backlight_brightness(struct backlight_device *b)
+{
+	u8 percent = (u8) b->props.brightness;
+	if (percent < 0 || percent > OT_EC_BL_BRIGHTNESS_MAX)
+		return -EINVAL;
+
+	ec_write(OT_EC_BL_BRIGHTNESS_ADDRESS, percent);
+	ec_write(OT_EC_BL_CONTROL_ADDRESS, OT_EC_BL_CONTROL_ON_DATA);
+
+	return 0;
+}
+
+static const struct backlight_ops oaktrail_bl_ops = {
+	.get_brightness = get_backlight_brightness,
+	.update_status	= set_backlight_brightness,
+};
+
+static int oaktrail_backlight_init(void)
+{
+	struct backlight_device *bd;
+	struct backlight_properties props;
+
+	memset(&props, 0, sizeof(struct backlight_properties));
+	props.type = BACKLIGHT_PLATFORM;
+	props.max_brightness = OT_EC_BL_BRIGHTNESS_MAX;
+	bd = backlight_device_register(DRIVER_NAME,
+				       &oaktrail_device->dev, NULL,
+				       &oaktrail_bl_ops,
+				       &props);
+
+	if (IS_ERR(bd)) {
+		oaktrail_bl_device = NULL;
+		pr_warning("Unable to register backlight device\n");
+		return PTR_ERR(bd);
+	}
+
+	oaktrail_bl_device = bd;
+
+	bd->props.brightness = get_backlight_brightness(bd);
+	bd->props.power = FB_BLANK_UNBLANK;
+	backlight_update_status(bd);
+
+	return 0;
+}
+
+static void oaktrail_backlight_exit(void)
+{
+	if (oaktrail_bl_device)
+		backlight_device_unregister(oaktrail_bl_device);
+}
+
+static int __devinit oaktrail_probe(struct platform_device *pdev)
+{
+	return 0;
+}
+
+static int __devexit oaktrail_remove(struct platform_device *pdev)
+{
+	return 0;
+}
+
+static struct platform_driver oaktrail_driver = {
+	.driver = {
+		.name = DRIVER_NAME,
+		.owner = THIS_MODULE,
+	},
+	.probe	= oaktrail_probe,
+	.remove	= __devexit_p(oaktrail_remove)
+};
+
+static int dmi_check_cb(const struct dmi_system_id *id)
+{
+	pr_info("Identified model '%s'\n", id->ident);
+	return 0;
+}
+
+static struct dmi_system_id __initdata oaktrail_dmi_table[] = {
+	{
+		.ident = "OakTrail platform",
+		.matches = {
+			DMI_MATCH(DMI_PRODUCT_NAME, "OakTrail platform"),
+		},
+		.callback = dmi_check_cb
+	},
+	{ }
+};
+
+static int __init oaktrail_init(void)
+{
+	int ret;
+
+	if (acpi_disabled) {
+		pr_err("ACPI needs to be enabled for this driver to work!\n");
+		return -ENODEV;
+	}
+
+	if (!force && !dmi_check_system(oaktrail_dmi_table)) {
+		pr_err("Platform not recognized (You could try the module's force-parameter)");
+		return -ENODEV;
+	}
+
+	ret = platform_driver_register(&oaktrail_driver);
+	if (ret) {
+		pr_warning("Unable to register platform driver\n");
+		goto err_driver_reg;
+	}
+
+	oaktrail_device = platform_device_alloc(DRIVER_NAME, -1);
+	if (!oaktrail_device) {
+		pr_warning("Unable to allocate platform device\n");
+		ret = -ENOMEM;
+		goto err_device_alloc;
+	}
+
+	ret = platform_device_add(oaktrail_device);
+	if (ret) {
+		pr_warning("Unable to add platform device\n");
+		goto err_device_add;
+	}
+
+	if (!acpi_video_backlight_support()) {
+		ret = oaktrail_backlight_init();
+		if (ret)
+			goto err_backlight;
+
+	} else
+		pr_info("Backlight controlled by ACPI video driver\n");
+
+	ret = oaktrail_rfkill_init();
+	if (ret) {
+		pr_warning("Setup rfkill failed\n");
+		goto err_rfkill;
+	}
+
+	pr_info("Driver "DRIVER_VERSION" successfully loaded\n");
+	return 0;
+
+err_rfkill:
+	oaktrail_backlight_exit();
+err_backlight:
+	platform_device_del(oaktrail_device);
+err_device_add:
+	platform_device_put(oaktrail_device);
+err_device_alloc:
+	platform_driver_unregister(&oaktrail_driver);
+err_driver_reg:
+
+	return ret;
+}
+
+static void __exit oaktrail_cleanup(void)
+{
+	oaktrail_backlight_exit();
+	oaktrail_rfkill_cleanup();
+	platform_device_unregister(oaktrail_device);
+	platform_driver_unregister(&oaktrail_driver);
+
+	pr_info("Driver unloaded\n");
+}
+
+module_init(oaktrail_init);
+module_exit(oaktrail_cleanup);
+
+MODULE_AUTHOR("Yin Kangkai (kangkai.yin@intel.com)");
+MODULE_DESCRIPTION("Intel Oaktrail Platform ACPI Extras");
+MODULE_VERSION(DRIVER_VERSION);
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("dmi:*:svnIntelCorporation:pnOakTrailplatform:*");
diff -druN linux-2.6.39-libre/drivers/platform/x86/intel_pmic_gpio.c linux-3.0-rc7-libre/drivers/platform/x86/intel_pmic_gpio.c
--- linux-2.6.39-libre/drivers/platform/x86/intel_pmic_gpio.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/platform/x86/intel_pmic_gpio.c	2011-07-11 19:51:52.000000000 -0400
@@ -19,6 +19,8 @@
  * Moorestown platform PMIC chip
  */
 
+#define pr_fmt(fmt) "%s: " fmt, __func__
+
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/interrupt.h>
@@ -90,8 +92,7 @@
 static int pmic_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
 {
 	if (offset > 8) {
-		printk(KERN_ERR
-			"%s: only pin 0-7 support input\n", __func__);
+		pr_err("only pin 0-7 support input\n");
 		return -1;/* we only have 8 GPIO can use as input */
 	}
 	return intel_scu_ipc_update_register(GPIO0 + offset,
@@ -116,8 +117,7 @@
 				value ? 1 << (offset - 16) : 0,
 				1 << (offset - 16));
 	else {
-		printk(KERN_ERR
-			"%s: invalid PMIC GPIO pin %d!\n", __func__, offset);
+		pr_err("invalid PMIC GPIO pin %d!\n", offset);
 		WARN_ON(1);
 	}
 
@@ -260,7 +260,7 @@
 	/* setting up SRAM mapping for GPIOINT register */
 	pg->gpiointr = ioremap_nocache(pdata->gpiointr, 8);
 	if (!pg->gpiointr) {
-		printk(KERN_ERR "%s: Can not map GPIOINT.\n", __func__);
+		pr_err("Can not map GPIOINT\n");
 		retval = -EINVAL;
 		goto err2;
 	}
@@ -281,13 +281,13 @@
 	pg->chip.dev = dev;
 	retval = gpiochip_add(&pg->chip);
 	if (retval) {
-		printk(KERN_ERR "%s: Can not add pmic gpio chip.\n", __func__);
+		pr_err("Can not add pmic gpio chip\n");
 		goto err;
 	}
 
 	retval = request_irq(pg->irq, pmic_irq_handler, 0, "pmic", pg);
 	if (retval) {
-		printk(KERN_WARNING "pmic: Interrupt request failed\n");
+		pr_warn("Interrupt request failed\n");
 		goto err;
 	}
 
diff -druN linux-2.6.39-libre/drivers/platform/x86/Kconfig linux-3.0-rc7-libre/drivers/platform/x86/Kconfig
--- linux-2.6.39-libre/drivers/platform/x86/Kconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/platform/x86/Kconfig	2011-07-11 19:51:52.000000000 -0400
@@ -39,7 +39,7 @@
 
 config ACERHDF
 	tristate "Acer Aspire One temperature and fan driver"
-	depends on THERMAL && THERMAL_HWMON && ACPI
+	depends on THERMAL && ACPI
 	---help---
 	  This is a driver for Acer Aspire One netbooks. It allows to access
 	  the temperature sensor and to control the fan.
@@ -111,7 +111,7 @@
 	  All-In-One machines.
 
 	  To compile this driver as a module, choose M here: the module will
-	  be called dell-wmi.
+	  be called dell-wmi-aio.
 
 
 config FUJITSU_LAPTOP
@@ -753,4 +753,20 @@
 	  To compile this driver as a module, choose M here: the module
 	  will be called samsung-laptop.
 
+config MXM_WMI
+       tristate "WMI support for MXM Laptop Graphics"
+       depends on ACPI_WMI
+       ---help---
+          MXM is a standard for laptop graphics cards, the WMI interface
+	  is required for switchable nvidia graphics machines
+
+config INTEL_OAKTRAIL
+	tristate "Intel Oaktrail Platform Extras"
+	depends on ACPI
+	depends on RFKILL && BACKLIGHT_CLASS_DEVICE && ACPI
+	---help---
+	  Intel Oaktrail platform need this driver to provide interfaces to
+	  enable/disable the Camera, WiFi, BT etc. devices. If in doubt, say Y
+	  here; it will only load on supported platforms.
+
 endif # X86_PLATFORM_DEVICES
diff -druN linux-2.6.39-libre/drivers/platform/x86/Makefile linux-3.0-rc7-libre/drivers/platform/x86/Makefile
--- linux-2.6.39-libre/drivers/platform/x86/Makefile	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/platform/x86/Makefile	2011-07-11 19:51:52.000000000 -0400
@@ -41,4 +41,6 @@
 obj-$(CONFIG_XO15_EBOOK)	+= xo15-ebook.o
 obj-$(CONFIG_IBM_RTL)		+= ibm_rtl.o
 obj-$(CONFIG_SAMSUNG_LAPTOP)	+= samsung-laptop.o
-obj-$(CONFIG_INTEL_MFLD_THERMAL)	+= intel_mid_thermal.o
+obj-$(CONFIG_MXM_WMI)		+= mxm-wmi.o
+obj-$(CONFIG_INTEL_MID_POWER_BUTTON)	+= intel_mid_powerbtn.o
+obj-$(CONFIG_INTEL_OAKTRAIL)	+= intel_oaktrail.o
diff -druN linux-2.6.39-libre/drivers/platform/x86/msi-laptop.c linux-3.0-rc7-libre/drivers/platform/x86/msi-laptop.c
--- linux-2.6.39-libre/drivers/platform/x86/msi-laptop.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/platform/x86/msi-laptop.c	2011-07-11 19:51:52.000000000 -0400
@@ -135,7 +135,7 @@
 	buf[1] = (u8) (level*31);
 
 	return ec_transaction(MSI_EC_COMMAND_LCD_LEVEL, buf, sizeof(buf),
-			      NULL, 0, 1);
+			      NULL, 0);
 }
 
 static int get_lcd_level(void)
@@ -144,7 +144,7 @@
 	int result;
 
 	result = ec_transaction(MSI_EC_COMMAND_LCD_LEVEL, &wdata, 1,
-				&rdata, 1, 1);
+				&rdata, 1);
 	if (result < 0)
 		return result;
 
@@ -157,7 +157,7 @@
 	int result;
 
 	result = ec_transaction(MSI_EC_COMMAND_LCD_LEVEL, &wdata, 1,
-				&rdata, 1, 1);
+				&rdata, 1);
 	if (result < 0)
 		return result;
 
@@ -172,7 +172,7 @@
 	wdata[0] = 4;
 
 	result = ec_transaction(MSI_EC_COMMAND_LCD_LEVEL, wdata, 1,
-				&rdata, 1, 1);
+				&rdata, 1);
 	if (result < 0)
 		return result;
 
@@ -180,7 +180,7 @@
 	wdata[1] = (rdata & 0xF7) | (enable ? 8 : 0);
 
 	return ec_transaction(MSI_EC_COMMAND_LCD_LEVEL, wdata, 2,
-			      NULL, 0, 1);
+			      NULL, 0);
 }
 
 static ssize_t set_device_state(const char *buf, size_t count, u8 mask)
@@ -217,7 +217,7 @@
 	u8 wdata = 0, rdata;
 	int result;
 
-	result = ec_transaction(MSI_EC_COMMAND_WIRELESS, &wdata, 1, &rdata, 1, 1);
+	result = ec_transaction(MSI_EC_COMMAND_WIRELESS, &wdata, 1, &rdata, 1);
 	if (result < 0)
 		return -1;
 
@@ -447,7 +447,7 @@
 
 static int dmi_check_cb(const struct dmi_system_id *id)
 {
-	pr_info("Identified laptop model '%s'.\n", id->ident);
+	pr_info("Identified laptop model '%s'\n", id->ident);
 	return 1;
 }
 
@@ -800,7 +800,7 @@
 	input_unregister_device(msi_laptop_input_dev);
 }
 
-static int load_scm_model_init(struct platform_device *sdev)
+static int __init load_scm_model_init(struct platform_device *sdev)
 {
 	u8 data;
 	int result;
@@ -875,8 +875,7 @@
 	/* Register backlight stuff */
 
 	if (acpi_video_backlight_support()) {
-		pr_info("Brightness ignored, must be controlled "
-		       "by ACPI video driver\n");
+		pr_info("Brightness ignored, must be controlled by ACPI video driver\n");
 	} else {
 		struct backlight_properties props;
 		memset(&props, 0, sizeof(struct backlight_properties));
@@ -930,7 +929,7 @@
 	if (auto_brightness != 2)
 		set_auto_brightness(auto_brightness);
 
-	pr_info("driver "MSI_DRIVER_VERSION" successfully loaded.\n");
+	pr_info("driver " MSI_DRIVER_VERSION " successfully loaded\n");
 
 	return 0;
 
@@ -978,7 +977,7 @@
 	if (auto_brightness != 2)
 		set_auto_brightness(1);
 
-	pr_info("driver unloaded.\n");
+	pr_info("driver unloaded\n");
 }
 
 module_init(msi_init);
diff -druN linux-2.6.39-libre/drivers/platform/x86/msi-wmi.c linux-3.0-rc7-libre/drivers/platform/x86/msi-wmi.c
--- linux-2.6.39-libre/drivers/platform/x86/msi-wmi.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/platform/x86/msi-wmi.c	2011-07-11 19:51:52.000000000 -0400
@@ -20,6 +20,7 @@
  *  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/input.h>
@@ -36,13 +37,10 @@
 MODULE_ALIAS("wmi:B6F3EEF2-3D2F-49DC-9DE3-85BCE18C62F2");
 
 #define DRV_NAME "msi-wmi"
-#define DRV_PFX DRV_NAME ": "
 
 #define MSIWMI_BIOS_GUID "551A1F84-FBDD-4125-91DB-3EA8F44F1D45"
 #define MSIWMI_EVENT_GUID "B6F3EEF2-3D2F-49DC-9DE3-85BCE18C62F2"
 
-#define dprintk(msg...) pr_debug(DRV_PFX msg)
-
 #define SCANCODE_BASE 0xD0
 #define MSI_WMI_BRIGHTNESSUP   SCANCODE_BASE
 #define MSI_WMI_BRIGHTNESSDOWN (SCANCODE_BASE + 1)
@@ -78,7 +76,7 @@
 
 	if (!obj || obj->type != ACPI_TYPE_INTEGER) {
 		if (obj) {
-			printk(KERN_ERR DRV_PFX "query block returned object "
+			pr_err("query block returned object "
 			       "type: %d - buffer length:%d\n", obj->type,
 			       obj->type == ACPI_TYPE_BUFFER ?
 			       obj->buffer.length : 0);
@@ -97,8 +95,8 @@
 
 	struct acpi_buffer input = { sizeof(int), &value };
 
-	dprintk("Going to set block of instance: %d - value: %d\n",
-		instance, value);
+	pr_debug("Going to set block of instance: %d - value: %d\n",
+		 instance, value);
 
 	status = wmi_set_block(MSIWMI_BIOS_GUID, instance, &input);
 
@@ -112,20 +110,19 @@
 	/* Instance 1 is "get backlight", cmp with DSDT */
 	err = msi_wmi_query_block(1, &ret);
 	if (err) {
-		printk(KERN_ERR DRV_PFX "Could not query backlight: %d\n", err);
+		pr_err("Could not query backlight: %d\n", err);
 		return -EINVAL;
 	}
-	dprintk("Get: Query block returned: %d\n", ret);
+	pr_debug("Get: Query block returned: %d\n", ret);
 	for (level = 0; level < ARRAY_SIZE(backlight_map); level++) {
 		if (backlight_map[level] == ret) {
-			dprintk("Current backlight level: 0x%X - index: %d\n",
-				backlight_map[level], level);
+			pr_debug("Current backlight level: 0x%X - index: %d\n",
+				 backlight_map[level], level);
 			break;
 		}
 	}
 	if (level == ARRAY_SIZE(backlight_map)) {
-		printk(KERN_ERR DRV_PFX "get: Invalid brightness value: 0x%X\n",
-		       ret);
+		pr_err("get: Invalid brightness value: 0x%X\n", ret);
 		return -EINVAL;
 	}
 	return level;
@@ -156,7 +153,7 @@
 
 	status = wmi_get_event_data(value, &response);
 	if (status != AE_OK) {
-		printk(KERN_INFO DRV_PFX "bad event status 0x%x\n", status);
+		pr_info("bad event status 0x%x\n", status);
 		return;
 	}
 
@@ -164,7 +161,7 @@
 
 	if (obj && obj->type == ACPI_TYPE_INTEGER) {
 		int eventcode = obj->integer.value;
-		dprintk("Eventcode: 0x%x\n", eventcode);
+		pr_debug("Eventcode: 0x%x\n", eventcode);
 		key = sparse_keymap_entry_from_scancode(msi_wmi_input_dev,
 				eventcode);
 		if (key) {
@@ -175,8 +172,8 @@
 			/* Ignore event if the same event happened in a 50 ms
 			   timeframe -> Key press may result in 10-20 GPEs */
 			if (ktime_to_us(diff) < 1000 * 50) {
-				dprintk("Suppressed key event 0x%X - "
-					"Last press was %lld us ago\n",
+				pr_debug("Suppressed key event 0x%X - "
+					 "Last press was %lld us ago\n",
 					 key->code, ktime_to_us(diff));
 				return;
 			}
@@ -187,17 +184,16 @@
 			(!acpi_video_backlight_support() ||
 			(key->code != MSI_WMI_BRIGHTNESSUP &&
 			key->code != MSI_WMI_BRIGHTNESSDOWN))) {
-				dprintk("Send key: 0x%X - "
-					"Input layer keycode: %d\n", key->code,
-					 key->keycode);
+				pr_debug("Send key: 0x%X - "
+					 "Input layer keycode: %d\n",
+					 key->code, key->keycode);
 				sparse_keymap_report_entry(msi_wmi_input_dev,
 						key, 1, true);
 			}
 		} else
-			printk(KERN_INFO "Unknown key pressed - %x\n",
-			       eventcode);
+			pr_info("Unknown key pressed - %x\n", eventcode);
 	} else
-		printk(KERN_INFO DRV_PFX "Unknown event received\n");
+		pr_info("Unknown event received\n");
 	kfree(response.pointer);
 }
 
@@ -238,8 +234,7 @@
 	int err;
 
 	if (!wmi_has_guid(MSIWMI_EVENT_GUID)) {
-		printk(KERN_ERR
-		       "This machine doesn't have MSI-hotkeys through WMI\n");
+		pr_err("This machine doesn't have MSI-hotkeys through WMI\n");
 		return -ENODEV;
 	}
 	err = wmi_install_notify_handler(MSIWMI_EVENT_GUID,
@@ -270,7 +265,7 @@
 
 		backlight->props.brightness = err;
 	}
-	dprintk("Event handler installed\n");
+	pr_debug("Event handler installed\n");
 
 	return 0;
 
diff -druN linux-2.6.39-libre/drivers/platform/x86/mxm-wmi.c linux-3.0-rc7-libre/drivers/platform/x86/mxm-wmi.c
--- linux-2.6.39-libre/drivers/platform/x86/mxm-wmi.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/platform/x86/mxm-wmi.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,111 @@
+/*
+ * MXM WMI driver
+ *
+ * Copyright(C) 2010 Red Hat.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <acpi/acpi_bus.h>
+#include <acpi/acpi_drivers.h>
+
+MODULE_AUTHOR("Dave Airlie");
+MODULE_DESCRIPTION("MXM WMI Driver");
+MODULE_LICENSE("GPL");
+
+#define MXM_WMMX_GUID "F6CB5C3C-9CAE-4EBD-B577-931EA32A2CC0"
+
+MODULE_ALIAS("wmi:"MXM_WMMX_GUID);
+
+#define MXM_WMMX_FUNC_MXDS 0x5344584D /* "MXDS" */
+#define MXM_WMMX_FUNC_MXMX 0x53445344 /* "MXMX" */
+
+struct mxds_args {
+	u32 func;
+	u32 args;
+	u32 xarg;
+};
+
+int mxm_wmi_call_mxds(int adapter)
+{
+	struct mxds_args args = {
+		.func = MXM_WMMX_FUNC_MXDS,
+		.args = 0,
+		.xarg = 1,
+	};
+	struct acpi_buffer input = { (acpi_size)sizeof(args), &args };
+	struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL };
+	acpi_status status;
+
+	printk("calling mux switch %d\n", adapter);
+
+	status = wmi_evaluate_method(MXM_WMMX_GUID, 0x1, adapter, &input,
+				     &output);
+
+	if (ACPI_FAILURE(status))
+		return status;
+
+	printk("mux switched %d\n", status);
+	return 0;
+			    
+}
+EXPORT_SYMBOL_GPL(mxm_wmi_call_mxds);
+
+int mxm_wmi_call_mxmx(int adapter)
+{
+	struct mxds_args args = {
+		.func = MXM_WMMX_FUNC_MXMX,
+		.args = 0,
+		.xarg = 1,
+	};
+	struct acpi_buffer input = { (acpi_size)sizeof(args), &args };
+	struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL };
+	acpi_status status;
+
+	printk("calling mux switch %d\n", adapter);
+
+	status = wmi_evaluate_method(MXM_WMMX_GUID, 0x1, adapter, &input,
+				     &output);
+
+	if (ACPI_FAILURE(status))
+		return status;
+
+	printk("mux mutex set switched %d\n", status);
+	return 0;
+			    
+}
+EXPORT_SYMBOL_GPL(mxm_wmi_call_mxmx);
+
+bool mxm_wmi_supported(void)
+{
+	bool guid_valid;
+	guid_valid = wmi_has_guid(MXM_WMMX_GUID);
+	return guid_valid;
+}
+EXPORT_SYMBOL_GPL(mxm_wmi_supported);
+
+static int __init mxm_wmi_init(void)
+{
+	return 0;
+}
+
+static void __exit mxm_wmi_exit(void)
+{
+}
+
+module_init(mxm_wmi_init);
+module_exit(mxm_wmi_exit);
diff -druN linux-2.6.39-libre/drivers/platform/x86/sony-laptop.c linux-3.0-rc7-libre/drivers/platform/x86/sony-laptop.c
--- linux-2.6.39-libre/drivers/platform/x86/sony-laptop.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/platform/x86/sony-laptop.c	2011-07-11 19:51:52.000000000 -0400
@@ -42,6 +42,8 @@
  *
  */
 
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/moduleparam.h>
@@ -70,10 +72,10 @@
 #include <linux/miscdevice.h>
 #endif
 
-#define DRV_PFX			"sony-laptop: "
-#define dprintk(msg...)		do {	\
-	if (debug)			\
-		pr_warn(DRV_PFX msg);	\
+#define dprintk(fmt, ...)			\
+do {						\
+	if (debug)				\
+		pr_warn(fmt, ##__VA_ARGS__);	\
 } while (0)
 
 #define SONY_LAPTOP_DRIVER_VERSION	"0.6"
@@ -418,7 +420,7 @@
 	error = kfifo_alloc(&sony_laptop_input.fifo,
 			    SONY_LAPTOP_BUF_SIZE, GFP_KERNEL);
 	if (error) {
-		pr_err(DRV_PFX "kfifo_alloc failed\n");
+		pr_err("kfifo_alloc failed\n");
 		goto err_dec_users;
 	}
 
@@ -702,7 +704,7 @@
 		return 0;
 	}
 
-	pr_warn(DRV_PFX "acpi_callreadfunc failed\n");
+	pr_warn("acpi_callreadfunc failed\n");
 
 	return -1;
 }
@@ -728,8 +730,7 @@
 	if (status == AE_OK) {
 		if (result != NULL) {
 			if (out_obj.type != ACPI_TYPE_INTEGER) {
-				pr_warn(DRV_PFX "acpi_evaluate_object bad "
-				       "return type\n");
+				pr_warn("acpi_evaluate_object bad return type\n");
 				return -1;
 			}
 			*result = out_obj.integer.value;
@@ -737,7 +738,7 @@
 		return 0;
 	}
 
-	pr_warn(DRV_PFX "acpi_evaluate_object failed\n");
+	pr_warn("acpi_evaluate_object failed\n");
 
 	return -1;
 }
@@ -961,7 +962,6 @@
 static int sony_nc_get_brightness_ng(struct backlight_device *bd)
 {
 	int result;
-	int *handle = (int *)bl_get_data(bd);
 	struct sony_backlight_props *sdev =
 		(struct sony_backlight_props *)bl_get_data(bd);
 
@@ -973,7 +973,6 @@
 static int sony_nc_update_status_ng(struct backlight_device *bd)
 {
 	int value, result;
-	int *handle = (int *)bl_get_data(bd);
 	struct sony_backlight_props *sdev =
 		(struct sony_backlight_props *)bl_get_data(bd);
 
@@ -1104,10 +1103,8 @@
 				}
 
 				if (!key_event->data)
-					pr_info(DRV_PFX
-							"Unknown event: 0x%x 0x%x\n",
-							key_handle,
-							ev);
+					pr_info("Unknown event: 0x%x 0x%x\n",
+						key_handle, ev);
 				else
 					sony_laptop_report_input_event(ev);
 			}
@@ -1128,7 +1125,7 @@
 	struct acpi_device_info *info;
 
 	if (ACPI_SUCCESS(acpi_get_object_info(handle, &info))) {
-		pr_warn(DRV_PFX "method: name: %4.4s, args %X\n",
+		pr_warn("method: name: %4.4s, args %X\n",
 			(char *)&info->name, info->param_count);
 
 		kfree(info);
@@ -1169,7 +1166,7 @@
 		ret = acpi_callsetfunc(sony_nc_acpi_handle, *item->acpiset,
 				       item->value, NULL);
 		if (ret < 0) {
-			pr_err(DRV_PFX "%s: %d\n", __func__, ret);
+			pr_err("%s: %d\n", __func__, ret);
 			break;
 		}
 	}
@@ -1336,12 +1333,12 @@
 
 	device_enum = (union acpi_object *) buffer.pointer;
 	if (!device_enum) {
-		pr_err(DRV_PFX "No SN06 return object.");
+		pr_err("No SN06 return object\n");
 		goto out_no_enum;
 	}
 	if (device_enum->type != ACPI_TYPE_BUFFER) {
-		pr_err(DRV_PFX "Invalid SN06 return object 0x%.2x\n",
-				device_enum->type);
+		pr_err("Invalid SN06 return object 0x%.2x\n",
+		       device_enum->type);
 		goto out_no_enum;
 	}
 
@@ -1662,7 +1659,7 @@
 						      ops, &props);
 
 	if (IS_ERR(sony_bl_props.dev)) {
-		pr_warn(DRV_PFX "unable to register backlight device\n");
+		pr_warn("unable to register backlight device\n");
 		sony_bl_props.dev = NULL;
 	} else
 		sony_bl_props.dev->props.brightness =
@@ -1682,8 +1679,7 @@
 	acpi_handle handle;
 	struct sony_nc_value *item;
 
-	pr_info(DRV_PFX "%s v%s.\n", SONY_NC_DRIVER_NAME,
-			SONY_LAPTOP_DRIVER_VERSION);
+	pr_info("%s v%s\n", SONY_NC_DRIVER_NAME, SONY_LAPTOP_DRIVER_VERSION);
 
 	sony_nc_acpi_device = device;
 	strcpy(acpi_device_class(device), "sony/hotkey");
@@ -1708,7 +1704,7 @@
 				sony_nc_acpi_handle, 1, sony_walk_callback,
 				NULL, NULL, NULL);
 		if (ACPI_FAILURE(status)) {
-			pr_warn(DRV_PFX "unable to walk acpi resources\n");
+			pr_warn("unable to walk acpi resources\n");
 			result = -ENODEV;
 			goto outpresent;
 		}
@@ -1736,13 +1732,12 @@
 	/* setup input devices and helper fifo */
 	result = sony_laptop_setup_input(device);
 	if (result) {
-		pr_err(DRV_PFX "Unable to create input devices.\n");
+		pr_err("Unable to create input devices\n");
 		goto outkbdbacklight;
 	}
 
 	if (acpi_video_backlight_support()) {
-		pr_info(DRV_PFX "brightness ignored, must be "
-		       "controlled by ACPI video driver\n");
+		pr_info("brightness ignored, must be controlled by ACPI video driver\n");
 	} else {
 		sony_nc_backlight_setup();
 	}
@@ -2265,9 +2260,9 @@
 	if (pcidev)
 		pci_dev_put(pcidev);
 
-	pr_info(DRV_PFX "detected Type%d model\n",
-			dev->model == SONYPI_DEVICE_TYPE1 ? 1 :
-			dev->model == SONYPI_DEVICE_TYPE2 ? 2 : 3);
+	pr_info("detected Type%d model\n",
+		dev->model == SONYPI_DEVICE_TYPE1 ? 1 :
+		dev->model == SONYPI_DEVICE_TYPE2 ? 2 : 3);
 }
 
 /* camera tests and poweron/poweroff */
@@ -2313,7 +2308,7 @@
 static int __sony_pic_camera_off(void)
 {
 	if (!camera) {
-		pr_warn(DRV_PFX "camera control not enabled\n");
+		pr_warn("camera control not enabled\n");
 		return -ENODEV;
 	}
 
@@ -2333,7 +2328,7 @@
 	int i, j, x;
 
 	if (!camera) {
-		pr_warn(DRV_PFX "camera control not enabled\n");
+		pr_warn("camera control not enabled\n");
 		return -ENODEV;
 	}
 
@@ -2356,7 +2351,7 @@
 	}
 
 	if (j == 0) {
-		pr_warn(DRV_PFX "failed to power on camera\n");
+		pr_warn("failed to power on camera\n");
 		return -ENODEV;
 	}
 
@@ -2412,8 +2407,7 @@
 				ITERATIONS_SHORT);
 		break;
 	default:
-		pr_err(DRV_PFX "sony_pic_camera_command invalid: %d\n",
-		       command);
+		pr_err("sony_pic_camera_command invalid: %d\n", command);
 		break;
 	}
 	mutex_unlock(&spic_dev.lock);
@@ -2819,7 +2813,7 @@
 	error =
 	 kfifo_alloc(&sonypi_compat.fifo, SONY_LAPTOP_BUF_SIZE, GFP_KERNEL);
 	if (error) {
-		pr_err(DRV_PFX "kfifo_alloc failed\n");
+		pr_err("kfifo_alloc failed\n");
 		return error;
 	}
 
@@ -2829,12 +2823,12 @@
 		sonypi_misc_device.minor = minor;
 	error = misc_register(&sonypi_misc_device);
 	if (error) {
-		pr_err(DRV_PFX "misc_register failed\n");
+		pr_err("misc_register failed\n");
 		goto err_free_kfifo;
 	}
 	if (minor == -1)
-		pr_info(DRV_PFX "device allocated minor is %d\n",
-		       sonypi_misc_device.minor);
+		pr_info("device allocated minor is %d\n",
+			sonypi_misc_device.minor);
 
 	return 0;
 
@@ -2893,8 +2887,8 @@
 			}
 			for (i = 0; i < p->interrupt_count; i++) {
 				if (!p->interrupts[i]) {
-					pr_warn(DRV_PFX "Invalid IRQ %d\n",
-							p->interrupts[i]);
+					pr_warn("Invalid IRQ %d\n",
+						p->interrupts[i]);
 					continue;
 				}
 				interrupt = kzalloc(sizeof(*interrupt),
@@ -2932,14 +2926,14 @@
 						ioport->io2.address_length);
 			}
 			else {
-				pr_err(DRV_PFX "Unknown SPIC Type, more than 2 IO Ports\n");
+				pr_err("Unknown SPIC Type, more than 2 IO Ports\n");
 				return AE_ERROR;
 			}
 			return AE_OK;
 		}
 	default:
 		dprintk("Resource %d isn't an IRQ nor an IO port\n",
-				resource->type);
+			resource->type);
 
 	case ACPI_RESOURCE_TYPE_END_TAG:
 		return AE_OK;
@@ -2960,7 +2954,7 @@
 	dprintk("Evaluating _STA\n");
 	result = acpi_bus_get_status(device);
 	if (result) {
-		pr_warn(DRV_PFX "Unable to read status\n");
+		pr_warn("Unable to read status\n");
 		goto end;
 	}
 
@@ -2976,8 +2970,7 @@
 	status = acpi_walk_resources(device->handle, METHOD_NAME__PRS,
 			sony_pic_read_possible_resource, &spic_dev);
 	if (ACPI_FAILURE(status)) {
-		pr_warn(DRV_PFX "Failure evaluating %s\n",
-				METHOD_NAME__PRS);
+		pr_warn("Failure evaluating %s\n", METHOD_NAME__PRS);
 		result = -ENODEV;
 	}
 end:
@@ -3090,7 +3083,7 @@
 
 	/* check for total failure */
 	if (ACPI_FAILURE(status)) {
-		pr_err(DRV_PFX "Error evaluating _SRS\n");
+		pr_err("Error evaluating _SRS\n");
 		result = -ENODEV;
 		goto end;
 	}
@@ -3182,7 +3175,7 @@
 	struct sony_pic_irq *irq, *tmp_irq;
 
 	if (sony_pic_disable(device)) {
-		pr_err(DRV_PFX "Couldn't disable device.\n");
+		pr_err("Couldn't disable device\n");
 		return -ENXIO;
 	}
 
@@ -3222,8 +3215,7 @@
 	struct sony_pic_ioport *io, *tmp_io;
 	struct sony_pic_irq *irq, *tmp_irq;
 
-	pr_info(DRV_PFX "%s v%s.\n", SONY_PIC_DRIVER_NAME,
-			SONY_LAPTOP_DRIVER_VERSION);
+	pr_info("%s v%s\n", SONY_PIC_DRIVER_NAME, SONY_LAPTOP_DRIVER_VERSION);
 
 	spic_dev.acpi_dev = device;
 	strcpy(acpi_device_class(device), "sony/hotkey");
@@ -3233,14 +3225,14 @@
 	/* read _PRS resources */
 	result = sony_pic_possible_resources(device);
 	if (result) {
-		pr_err(DRV_PFX "Unable to read possible resources.\n");
+		pr_err("Unable to read possible resources\n");
 		goto err_free_resources;
 	}
 
 	/* setup input devices and helper fifo */
 	result = sony_laptop_setup_input(device);
 	if (result) {
-		pr_err(DRV_PFX "Unable to create input devices.\n");
+		pr_err("Unable to create input devices\n");
 		goto err_free_resources;
 	}
 
@@ -3281,7 +3273,7 @@
 		}
 	}
 	if (!spic_dev.cur_ioport) {
-		pr_err(DRV_PFX "Failed to request_region.\n");
+		pr_err("Failed to request_region\n");
 		result = -ENODEV;
 		goto err_remove_compat;
 	}
@@ -3301,7 +3293,7 @@
 		}
 	}
 	if (!spic_dev.cur_irq) {
-		pr_err(DRV_PFX "Failed to request_irq.\n");
+		pr_err("Failed to request_irq\n");
 		result = -ENODEV;
 		goto err_release_region;
 	}
@@ -3309,7 +3301,7 @@
 	/* set resource status _SRS */
 	result = sony_pic_enable(device, spic_dev.cur_ioport, spic_dev.cur_irq);
 	if (result) {
-		pr_err(DRV_PFX "Couldn't enable device.\n");
+		pr_err("Couldn't enable device\n");
 		goto err_free_irq;
 	}
 
@@ -3418,7 +3410,7 @@
 	if (!no_spic && dmi_check_system(sonypi_dmi_table)) {
 		result = acpi_bus_register_driver(&sony_pic_driver);
 		if (result) {
-			pr_err(DRV_PFX "Unable to register SPIC driver.");
+			pr_err("Unable to register SPIC driver\n");
 			goto out;
 		}
 		spic_drv_registered = 1;
@@ -3426,7 +3418,7 @@
 
 	result = acpi_bus_register_driver(&sony_nc_driver);
 	if (result) {
-		pr_err(DRV_PFX "Unable to register SNC driver.");
+		pr_err("Unable to register SNC driver\n");
 		goto out_unregister_pic;
 	}
 
diff -druN linux-2.6.39-libre/drivers/platform/x86/tc1100-wmi.c linux-3.0-rc7-libre/drivers/platform/x86/tc1100-wmi.c
--- linux-2.6.39-libre/drivers/platform/x86/tc1100-wmi.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/platform/x86/tc1100-wmi.c	2011-07-11 19:51:52.000000000 -0400
@@ -25,6 +25,8 @@
  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  */
 
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/slab.h>
@@ -40,9 +42,6 @@
 #define TC1100_INSTANCE_WIRELESS		1
 #define TC1100_INSTANCE_JOGDIAL		2
 
-#define TC1100_LOGPREFIX "tc1100-wmi: "
-#define TC1100_INFO KERN_INFO TC1100_LOGPREFIX
-
 MODULE_AUTHOR("Jamey Hicks, Carlos Corbacho");
 MODULE_DESCRIPTION("HP Compaq TC1100 Tablet WMI Extras");
 MODULE_LICENSE("GPL");
@@ -264,7 +263,7 @@
 	if (error)
 		goto err_device_del;
 
-	printk(TC1100_INFO "HP Compaq TC1100 Tablet WMI Extras loaded\n");
+	pr_info("HP Compaq TC1100 Tablet WMI Extras loaded\n");
 	return 0;
 
  err_device_del:
diff -druN linux-2.6.39-libre/drivers/platform/x86/thinkpad_acpi.c linux-3.0-rc7-libre/drivers/platform/x86/thinkpad_acpi.c
--- linux-2.6.39-libre/drivers/platform/x86/thinkpad_acpi.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/platform/x86/thinkpad_acpi.c	2011-07-11 19:51:52.000000000 -0400
@@ -21,6 +21,8 @@
  *  02110-1301, USA.
  */
 
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #define TPACPI_VERSION "0.24"
 #define TPACPI_SYSFS_VERSION 0x020700
 
@@ -182,6 +184,10 @@
 
 	/* Misc bay events */
 	TP_HKEY_EV_OPTDRV_EJ		= 0x3006, /* opt. drive tray ejected */
+	TP_HKEY_EV_HOTPLUG_DOCK		= 0x4010, /* docked into hotplug dock
+						     or port replicator */
+	TP_HKEY_EV_HOTPLUG_UNDOCK	= 0x4011, /* undocked from hotplug
+						     dock or port replicator */
 
 	/* User-interface events */
 	TP_HKEY_EV_LID_CLOSE		= 0x5001, /* laptop lid closed */
@@ -192,6 +198,10 @@
 	TP_HKEY_EV_PEN_REMOVED		= 0x500c, /* tablet pen removed */
 	TP_HKEY_EV_BRGHT_CHANGED	= 0x5010, /* backlight control event */
 
+	/* Key-related user-interface events */
+	TP_HKEY_EV_KEY_NUMLOCK		= 0x6000, /* NumLock key pressed */
+	TP_HKEY_EV_KEY_FN		= 0x6005, /* Fn key pressed? E420 */
+
 	/* Thermal events */
 	TP_HKEY_EV_ALARM_BAT_HOT	= 0x6011, /* battery too hot */
 	TP_HKEY_EV_ALARM_BAT_XHOT	= 0x6012, /* battery critically hot */
@@ -199,6 +209,10 @@
 	TP_HKEY_EV_ALARM_SENSOR_XHOT	= 0x6022, /* sensor critically hot */
 	TP_HKEY_EV_THM_TABLE_CHANGED	= 0x6030, /* thermal table changed */
 
+	TP_HKEY_EV_UNK_6040		= 0x6040, /* Related to AC change?
+						     some sort of APM hint,
+						     W520 */
+
 	/* Misc */
 	TP_HKEY_EV_RFKILL_CHANGED	= 0x7000, /* rfkill switch changed */
 };
@@ -224,17 +238,6 @@
 
 #define TPACPI_MAX_ACPI_ARGS 3
 
-/* printk headers */
-#define TPACPI_LOG TPACPI_FILE ": "
-#define TPACPI_EMERG	KERN_EMERG	TPACPI_LOG
-#define TPACPI_ALERT	KERN_ALERT	TPACPI_LOG
-#define TPACPI_CRIT	KERN_CRIT	TPACPI_LOG
-#define TPACPI_ERR	KERN_ERR	TPACPI_LOG
-#define TPACPI_WARN	KERN_WARNING	TPACPI_LOG
-#define TPACPI_NOTICE	KERN_NOTICE	TPACPI_LOG
-#define TPACPI_INFO	KERN_INFO	TPACPI_LOG
-#define TPACPI_DEBUG	KERN_DEBUG	TPACPI_LOG
-
 /* Debugging printk groups */
 #define TPACPI_DBG_ALL		0xffff
 #define TPACPI_DBG_DISCLOSETASK	0x8000
@@ -389,34 +392,36 @@
  *  Debugging helpers
  */
 
-#define dbg_printk(a_dbg_level, format, arg...) \
-	do { if (dbg_level & (a_dbg_level)) \
-		printk(TPACPI_DEBUG "%s: " format, __func__ , ## arg); \
-	} while (0)
+#define dbg_printk(a_dbg_level, format, arg...)				\
+do {									\
+	if (dbg_level & (a_dbg_level))					\
+		printk(KERN_DEBUG pr_fmt("%s: " format),		\
+		       __func__, ##arg);				\
+} while (0)
 
 #ifdef CONFIG_THINKPAD_ACPI_DEBUG
 #define vdbg_printk dbg_printk
 static const char *str_supported(int is_supported);
 #else
-#define vdbg_printk(a_dbg_level, format, arg...) \
-	do { } while (0)
+static inline const char *str_supported(int is_supported) { return ""; }
+#define vdbg_printk(a_dbg_level, format, arg...)	\
+	no_printk(format, ##arg)
 #endif
 
 static void tpacpi_log_usertask(const char * const what)
 {
-	printk(TPACPI_DEBUG "%s: access by process with PID %d\n",
-		what, task_tgid_vnr(current));
+	printk(KERN_DEBUG pr_fmt("%s: access by process with PID %d\n"),
+	       what, task_tgid_vnr(current));
 }
 
-#define tpacpi_disclose_usertask(what, format, arg...) \
-	do { \
-		if (unlikely( \
-		    (dbg_level & TPACPI_DBG_DISCLOSETASK) && \
-		    (tpacpi_lifecycle == TPACPI_LIFE_RUNNING))) { \
-			printk(TPACPI_DEBUG "%s: PID %d: " format, \
-				what, task_tgid_vnr(current), ## arg); \
-		} \
-	} while (0)
+#define tpacpi_disclose_usertask(what, format, arg...)			\
+do {									\
+	if (unlikely((dbg_level & TPACPI_DBG_DISCLOSETASK) &&		\
+		     (tpacpi_lifecycle == TPACPI_LIFE_RUNNING))) {	\
+		printk(KERN_DEBUG pr_fmt("%s: PID %d: " format),	\
+		       what, task_tgid_vnr(current), ## arg);		\
+	}								\
+} while (0)
 
 /*
  * Quirk handling helpers
@@ -535,15 +540,6 @@
 	   "HKEY",		/* all others */
 	   );			/* 570 */
 
-TPACPI_HANDLE(vid, root, "\\_SB.PCI.AGP.VGA",	/* 570 */
-	   "\\_SB.PCI0.AGP0.VID0",	/* 600e/x, 770x */
-	   "\\_SB.PCI0.VID0",	/* 770e */
-	   "\\_SB.PCI0.VID",	/* A21e, G4x, R50e, X30, X40 */
-	   "\\_SB.PCI0.AGP.VGA",	/* X100e and a few others */
-	   "\\_SB.PCI0.AGP.VID",	/* all others */
-	   );				/* R30, R31 */
-
-
 /*************************************************************************
  * ACPI helpers
  */
@@ -563,7 +559,7 @@
 	int quiet;
 
 	if (!*fmt) {
-		printk(TPACPI_ERR "acpi_evalf() called with empty format\n");
+		pr_err("acpi_evalf() called with empty format\n");
 		return 0;
 	}
 
@@ -588,7 +584,7 @@
 			break;
 			/* add more types as needed */
 		default:
-			printk(TPACPI_ERR "acpi_evalf() called "
+			pr_err("acpi_evalf() called "
 			       "with invalid format character '%c'\n", c);
 			va_end(ap);
 			return 0;
@@ -617,13 +613,13 @@
 		break;
 		/* add more types as needed */
 	default:
-		printk(TPACPI_ERR "acpi_evalf() called "
+		pr_err("acpi_evalf() called "
 		       "with invalid format character '%c'\n", res_type);
 		return 0;
 	}
 
 	if (!success && !quiet)
-		printk(TPACPI_ERR "acpi_evalf(%s, %s, ...) failed: %s\n",
+		pr_err("acpi_evalf(%s, %s, ...) failed: %s\n",
 		       method, fmt0, acpi_format_exception(status));
 
 	return success;
@@ -767,8 +763,7 @@
 
 	rc = acpi_bus_get_device(*ibm->acpi->handle, &ibm->acpi->device);
 	if (rc < 0) {
-		printk(TPACPI_ERR "acpi_bus_get_device(%s) failed: %d\n",
-			ibm->name, rc);
+		pr_err("acpi_bus_get_device(%s) failed: %d\n", ibm->name, rc);
 		return -ENODEV;
 	}
 
@@ -781,12 +776,10 @@
 			ibm->acpi->type, dispatch_acpi_notify, ibm);
 	if (ACPI_FAILURE(status)) {
 		if (status == AE_ALREADY_EXISTS) {
-			printk(TPACPI_NOTICE
-			       "another device driver is already "
-			       "handling %s events\n", ibm->name);
+			pr_notice("another device driver is already "
+				  "handling %s events\n", ibm->name);
 		} else {
-			printk(TPACPI_ERR
-			       "acpi_install_notify_handler(%s) failed: %s\n",
+			pr_err("acpi_install_notify_handler(%s) failed: %s\n",
 			       ibm->name, acpi_format_exception(status));
 		}
 		return -ENODEV;
@@ -811,8 +804,7 @@
 
 	ibm->acpi->driver = kzalloc(sizeof(struct acpi_driver), GFP_KERNEL);
 	if (!ibm->acpi->driver) {
-		printk(TPACPI_ERR
-		       "failed to allocate memory for ibm->acpi->driver\n");
+		pr_err("failed to allocate memory for ibm->acpi->driver\n");
 		return -ENOMEM;
 	}
 
@@ -823,7 +815,7 @@
 
 	rc = acpi_bus_register_driver(ibm->acpi->driver);
 	if (rc < 0) {
-		printk(TPACPI_ERR "acpi_bus_register_driver(%s) failed: %d\n",
+		pr_err("acpi_bus_register_driver(%s) failed: %d\n",
 		       ibm->name, rc);
 		kfree(ibm->acpi->driver);
 		ibm->acpi->driver = NULL;
@@ -1081,15 +1073,14 @@
 static void tpacpi_disable_brightness_delay(void)
 {
 	if (acpi_evalf(hkey_handle, NULL, "PWMS", "qvd", 0))
-		printk(TPACPI_NOTICE
-			"ACPI backlight control delay disabled\n");
+		pr_notice("ACPI backlight control delay disabled\n");
 }
 
 static void printk_deprecated_attribute(const char * const what,
 					const char * const details)
 {
 	tpacpi_log_usertask("deprecated sysfs attribute");
-	printk(TPACPI_WARN "WARNING: sysfs attribute %s is deprecated and "
+	pr_warn("WARNING: sysfs attribute %s is deprecated and "
 		"will be removed. %s\n",
 		what, details);
 }
@@ -1264,8 +1255,7 @@
 						&tpacpi_rfk_rfkill_ops,
 						atp_rfk);
 	if (!atp_rfk || !atp_rfk->rfkill) {
-		printk(TPACPI_ERR
-			"failed to allocate memory for rfkill class\n");
+		pr_err("failed to allocate memory for rfkill class\n");
 		kfree(atp_rfk);
 		return -ENOMEM;
 	}
@@ -1275,9 +1265,8 @@
 
 	sw_status = (tp_rfkops->get_status)();
 	if (sw_status < 0) {
-		printk(TPACPI_ERR
-			"failed to read initial state for %s, error %d\n",
-			name, sw_status);
+		pr_err("failed to read initial state for %s, error %d\n",
+		       name, sw_status);
 	} else {
 		sw_state = (sw_status == TPACPI_RFK_RADIO_OFF);
 		if (set_default) {
@@ -1291,9 +1280,7 @@
 
 	res = rfkill_register(atp_rfk->rfkill);
 	if (res < 0) {
-		printk(TPACPI_ERR
-			"failed to register %s rfkill switch: %d\n",
-			name, res);
+		pr_err("failed to register %s rfkill switch: %d\n", name, res);
 		rfkill_destroy(atp_rfk->rfkill);
 		kfree(atp_rfk);
 		return res;
@@ -1301,7 +1288,7 @@
 
 	tpacpi_rfkill_switches[id] = atp_rfk;
 
-	printk(TPACPI_INFO "rfkill switch %s: radio is %sblocked\n",
+	pr_info("rfkill switch %s: radio is %sblocked\n",
 		name, (sw_state || hw_state) ? "" : "un");
 	return 0;
 }
@@ -1825,10 +1812,8 @@
 		 * broken, or really stable to begin with, so it is
 		 * best if the user upgrades the firmware anyway.
 		 */
-		printk(TPACPI_WARN
-			"WARNING: Outdated ThinkPad BIOS/EC firmware\n");
-		printk(TPACPI_WARN
-			"WARNING: This firmware may be missing critical bug "
+		pr_warn("WARNING: Outdated ThinkPad BIOS/EC firmware\n");
+		pr_warn("WARNING: This firmware may be missing critical bug "
 			"fixes and/or important features\n");
 	}
 }
@@ -2117,9 +2102,7 @@
 		(hotkey_all_mask | TPACPI_HKEY_NVRAM_KNOWN_MASK);
 
 	if (wantedmask)
-		printk(TPACPI_NOTICE
-			"required events 0x%08x not enabled!\n",
-			wantedmask);
+		pr_notice("required events 0x%08x not enabled!\n", wantedmask);
 }
 
 /*
@@ -2157,10 +2140,9 @@
 	 * a given event.
 	 */
 	if (!hotkey_mask_get() && !rc && (fwmask & ~hotkey_acpi_mask)) {
-		printk(TPACPI_NOTICE
-		       "asked for hotkey mask 0x%08x, but "
-		       "firmware forced it to 0x%08x\n",
-		       fwmask, hotkey_acpi_mask);
+		pr_notice("asked for hotkey mask 0x%08x, but "
+			  "firmware forced it to 0x%08x\n",
+			  fwmask, hotkey_acpi_mask);
 	}
 
 	if (tpacpi_lifecycle != TPACPI_LIFE_EXITING)
@@ -2184,13 +2166,11 @@
 	    (mask == 0xffff || mask == 0xffffff ||
 	     mask == 0xffffffff)) {
 		tp_warned.hotkey_mask_ff = 1;
-		printk(TPACPI_NOTICE
-		       "setting the hotkey mask to 0x%08x is likely "
-		       "not the best way to go about it\n", mask);
-		printk(TPACPI_NOTICE
-		       "please consider using the driver defaults, "
-		       "and refer to up-to-date thinkpad-acpi "
-		       "documentation\n");
+		pr_notice("setting the hotkey mask to 0x%08x is likely "
+			  "not the best way to go about it\n", mask);
+		pr_notice("please consider using the driver defaults, "
+			  "and refer to up-to-date thinkpad-acpi "
+			  "documentation\n");
 	}
 
 	/* Try to enable what the user asked for, plus whatever we need.
@@ -2574,8 +2554,7 @@
 					NULL, TPACPI_NVRAM_KTHREAD_NAME);
 			if (IS_ERR(tpacpi_hotkey_task)) {
 				tpacpi_hotkey_task = NULL;
-				printk(TPACPI_ERR
-				       "could not create kernel thread "
+				pr_err("could not create kernel thread "
 				       "for hotkey polling\n");
 			}
 		}
@@ -2583,11 +2562,10 @@
 		hotkey_poll_stop_sync();
 		if (may_warn && (poll_driver_mask || poll_user_mask) &&
 		    hotkey_poll_freq == 0) {
-			printk(TPACPI_NOTICE
-				"hot keys 0x%08x and/or events 0x%08x "
-				"require polling, which is currently "
-				"disabled\n",
-				poll_user_mask, poll_driver_mask);
+			pr_notice("hot keys 0x%08x and/or events 0x%08x "
+				  "require polling, which is currently "
+				  "disabled\n",
+				  poll_user_mask, poll_driver_mask);
 		}
 	}
 }
@@ -2811,13 +2789,13 @@
 	mutex_unlock(&hotkey_mutex);
 
 	if (rc < 0)
-		printk(TPACPI_ERR "hotkey_source_mask: failed to update the"
-			"firmware event mask!\n");
+		pr_err("hotkey_source_mask: "
+		       "failed to update the firmware event mask!\n");
 
 	if (r_ev)
-		printk(TPACPI_NOTICE "hotkey_source_mask: "
-			"some important events were disabled: "
-			"0x%04x\n", r_ev);
+		pr_notice("hotkey_source_mask: "
+			  "some important events were disabled: 0x%04x\n",
+			  r_ev);
 
 	tpacpi_disclose_usertask("hotkey_source_mask", "set to 0x%08lx\n", t);
 
@@ -3048,8 +3026,7 @@
 	if (((tp_features.hotkey_mask &&
 	      hotkey_mask_set(hotkey_orig_mask)) |
 	     hotkey_status_set(false)) != 0)
-		printk(TPACPI_ERR
-		       "failed to restore hot key mask "
+		pr_err("failed to restore hot key mask "
 		       "to BIOS defaults\n");
 }
 
@@ -3288,10 +3265,9 @@
 	   for HKEY interface version 0x100 */
 	if (acpi_evalf(hkey_handle, &hkeyv, "MHKV", "qd")) {
 		if ((hkeyv >> 8) != 1) {
-			printk(TPACPI_ERR "unknown version of the "
-			       "HKEY interface: 0x%x\n", hkeyv);
-			printk(TPACPI_ERR "please report this to %s\n",
-			       TPACPI_MAIL);
+			pr_err("unknown version of the HKEY interface: 0x%x\n",
+			       hkeyv);
+			pr_err("please report this to %s\n", TPACPI_MAIL);
 		} else {
 			/*
 			 * MHKV 0x100 in A31, R40, R40e,
@@ -3304,8 +3280,7 @@
 			/* Paranoia check AND init hotkey_all_mask */
 			if (!acpi_evalf(hkey_handle, &hotkey_all_mask,
 					"MHKA", "qd")) {
-				printk(TPACPI_ERR
-				       "missing MHKA handler, "
+				pr_err("missing MHKA handler, "
 				       "please report this to %s\n",
 				       TPACPI_MAIL);
 				/* Fallback: pre-init for FN+F3,F4,F12 */
@@ -3343,16 +3318,14 @@
 	if (dbg_wlswemul) {
 		tp_features.hotkey_wlsw = 1;
 		radiosw_state = !!tpacpi_wlsw_emulstate;
-		printk(TPACPI_INFO
-			"radio switch emulation enabled\n");
+		pr_info("radio switch emulation enabled\n");
 	} else
 #endif
 	/* Not all thinkpads have a hardware radio switch */
 	if (acpi_evalf(hkey_handle, &status, "WLSW", "qd")) {
 		tp_features.hotkey_wlsw = 1;
 		radiosw_state = !!status;
-		printk(TPACPI_INFO
-			"radio switch found; radios are %s\n",
+		pr_info("radio switch found; radios are %s\n",
 			enabled(status, 0));
 	}
 	if (tp_features.hotkey_wlsw)
@@ -3363,8 +3336,7 @@
 	if (!res && acpi_evalf(hkey_handle, &status, "MHKG", "qd")) {
 		tp_features.hotkey_tablet = 1;
 		tabletsw_state = !!(status & TP_HOTKEY_TABLET_MASK);
-		printk(TPACPI_INFO
-			"possible tablet mode switch found; "
+		pr_info("possible tablet mode switch found; "
 			"ThinkPad in %s mode\n",
 			(tabletsw_state) ? "tablet" : "laptop");
 		res = add_to_attr_set(hotkey_dev_attributes,
@@ -3382,8 +3354,7 @@
 	hotkey_keycode_map = kmalloc(TPACPI_HOTKEY_MAP_SIZE,
 					GFP_KERNEL);
 	if (!hotkey_keycode_map) {
-		printk(TPACPI_ERR
-			"failed to allocate memory for key map\n");
+		pr_err("failed to allocate memory for key map\n");
 		res = -ENOMEM;
 		goto err_exit;
 	}
@@ -3426,13 +3397,11 @@
 	 * userspace. tpacpi_detect_brightness_capabilities() must have
 	 * been called before this point  */
 	if (tp_features.bright_acpimode && acpi_video_backlight_support()) {
-		printk(TPACPI_INFO
-		       "This ThinkPad has standard ACPI backlight "
-		       "brightness control, supported by the ACPI "
-		       "video driver\n");
-		printk(TPACPI_NOTICE
-		       "Disabling thinkpad-acpi brightness events "
-		       "by default...\n");
+		pr_info("This ThinkPad has standard ACPI backlight "
+			"brightness control, supported by the ACPI "
+			"video driver\n");
+		pr_notice("Disabling thinkpad-acpi brightness events "
+			  "by default...\n");
 
 		/* Disable brightness up/down on Lenovo thinkpads when
 		 * ACPI is handling them, otherwise it is plain impossible
@@ -3539,8 +3508,7 @@
 
 	case TP_HKEY_EV_WKUP_S3_BATLOW: /* Battery on critical low level/S3 */
 	case TP_HKEY_EV_WKUP_S4_BATLOW: /* Battery on critical low level/S4 */
-		printk(TPACPI_ALERT
-			"EMERGENCY WAKEUP: battery almost empty\n");
+		pr_alert("EMERGENCY WAKEUP: battery almost empty\n");
 		/* how to auto-heal: */
 		/* 2313: woke up from S3, go to S4/S5 */
 		/* 2413: woke up from S4, go to S5 */
@@ -3551,14 +3519,40 @@
 	}
 
 	if (hotkey_wakeup_reason != TP_ACPI_WAKEUP_NONE) {
-		printk(TPACPI_INFO
-		       "woke up due to a hot-unplug "
-		       "request...\n");
+		pr_info("woke up due to a hot-unplug request...\n");
 		hotkey_wakeup_reason_notify_change();
 	}
 	return true;
 }
 
+static bool hotkey_notify_dockevent(const u32 hkey,
+				 bool *send_acpi_ev,
+				 bool *ignore_acpi_ev)
+{
+	/* 0x4000-0x4FFF: dock-related events */
+	*send_acpi_ev = true;
+	*ignore_acpi_ev = false;
+
+	switch (hkey) {
+	case TP_HKEY_EV_UNDOCK_ACK:
+		/* ACPI undock operation completed after wakeup */
+		hotkey_autosleep_ack = 1;
+		pr_info("undocked\n");
+		hotkey_wakeup_hotunplug_complete_notify_change();
+		return true;
+
+	case TP_HKEY_EV_HOTPLUG_DOCK: /* docked to port replicator */
+		pr_info("docked into hotplug port replicator\n");
+		return true;
+	case TP_HKEY_EV_HOTPLUG_UNDOCK: /* undocked from port replicator */
+		pr_info("undocked from hotplug port replicator\n");
+		return true;
+
+	default:
+		return false;
+	}
+}
+
 static bool hotkey_notify_usrevent(const u32 hkey,
 				 bool *send_acpi_ev,
 				 bool *ignore_acpi_ev)
@@ -3593,49 +3587,52 @@
 
 static void thermal_dump_all_sensors(void);
 
-static bool hotkey_notify_thermal(const u32 hkey,
+static bool hotkey_notify_6xxx(const u32 hkey,
 				 bool *send_acpi_ev,
 				 bool *ignore_acpi_ev)
 {
 	bool known = true;
 
-	/* 0x6000-0x6FFF: thermal alarms */
+	/* 0x6000-0x6FFF: thermal alarms/notices and keyboard events */
 	*send_acpi_ev = true;
 	*ignore_acpi_ev = false;
 
 	switch (hkey) {
 	case TP_HKEY_EV_THM_TABLE_CHANGED:
-		printk(TPACPI_INFO
-			"EC reports that Thermal Table has changed\n");
+		pr_info("EC reports that Thermal Table has changed\n");
 		/* recommended action: do nothing, we don't have
 		 * Lenovo ATM information */
 		return true;
 	case TP_HKEY_EV_ALARM_BAT_HOT:
-		printk(TPACPI_CRIT
-			"THERMAL ALARM: battery is too hot!\n");
+		pr_crit("THERMAL ALARM: battery is too hot!\n");
 		/* recommended action: warn user through gui */
 		break;
 	case TP_HKEY_EV_ALARM_BAT_XHOT:
-		printk(TPACPI_ALERT
-			"THERMAL EMERGENCY: battery is extremely hot!\n");
+		pr_alert("THERMAL EMERGENCY: battery is extremely hot!\n");
 		/* recommended action: immediate sleep/hibernate */
 		break;
 	case TP_HKEY_EV_ALARM_SENSOR_HOT:
-		printk(TPACPI_CRIT
-			"THERMAL ALARM: "
+		pr_crit("THERMAL ALARM: "
 			"a sensor reports something is too hot!\n");
 		/* recommended action: warn user through gui, that */
 		/* some internal component is too hot */
 		break;
 	case TP_HKEY_EV_ALARM_SENSOR_XHOT:
-		printk(TPACPI_ALERT
-			"THERMAL EMERGENCY: "
-			"a sensor reports something is extremely hot!\n");
+		pr_alert("THERMAL EMERGENCY: "
+			 "a sensor reports something is extremely hot!\n");
 		/* recommended action: immediate sleep/hibernate */
 		break;
+
+	case TP_HKEY_EV_KEY_NUMLOCK:
+	case TP_HKEY_EV_KEY_FN:
+		/* key press events, we just ignore them as long as the EC
+		 * is still reporting them in the normal keyboard stream */
+		*send_acpi_ev = false;
+		*ignore_acpi_ev = true;
+		return true;
+
 	default:
-		printk(TPACPI_ALERT
-			 "THERMAL ALERT: unknown thermal alarm received\n");
+		pr_warn("unknown possible thermal alarm or keyboard event received\n");
 		known = false;
 	}
 
@@ -3652,8 +3649,7 @@
 	bool known_ev;
 
 	if (event != 0x80) {
-		printk(TPACPI_ERR
-		       "unknown HKEY notification event %d\n", event);
+		pr_err("unknown HKEY notification event %d\n", event);
 		/* forward it to userspace, maybe it knows how to handle it */
 		acpi_bus_generate_netlink_event(
 					ibm->acpi->device->pnp.device_class,
@@ -3664,7 +3660,7 @@
 
 	while (1) {
 		if (!acpi_evalf(hkey_handle, &hkey, "MHKP", "d")) {
-			printk(TPACPI_ERR "failed to retrieve HKEY event\n");
+			pr_err("failed to retrieve HKEY event\n");
 			return;
 		}
 
@@ -3692,8 +3688,7 @@
 			switch (hkey) {
 			case TP_HKEY_EV_BAYEJ_ACK:
 				hotkey_autosleep_ack = 1;
-				printk(TPACPI_INFO
-				       "bay ejected\n");
+				pr_info("bay ejected\n");
 				hotkey_wakeup_hotunplug_complete_notify_change();
 				known_ev = true;
 				break;
@@ -3706,16 +3701,9 @@
 			}
 			break;
 		case 4:
-			/* 0x4000-0x4FFF: dock-related wakeups */
-			if (hkey == TP_HKEY_EV_UNDOCK_ACK) {
-				hotkey_autosleep_ack = 1;
-				printk(TPACPI_INFO
-				       "undocked\n");
-				hotkey_wakeup_hotunplug_complete_notify_change();
-				known_ev = true;
-			} else {
-				known_ev = false;
-			}
+			/* 0x4000-0x4FFF: dock-related events */
+			known_ev = hotkey_notify_dockevent(hkey, &send_acpi_ev,
+						&ignore_acpi_ev);
 			break;
 		case 5:
 			/* 0x5000-0x5FFF: human interface helpers */
@@ -3723,8 +3711,9 @@
 						 &ignore_acpi_ev);
 			break;
 		case 6:
-			/* 0x6000-0x6FFF: thermal alarms */
-			known_ev = hotkey_notify_thermal(hkey, &send_acpi_ev,
+			/* 0x6000-0x6FFF: thermal alarms/notices and
+			 *                keyboard events */
+			known_ev = hotkey_notify_6xxx(hkey, &send_acpi_ev,
 						 &ignore_acpi_ev);
 			break;
 		case 7:
@@ -3741,11 +3730,9 @@
 			known_ev = false;
 		}
 		if (!known_ev) {
-			printk(TPACPI_NOTICE
-			       "unhandled HKEY event 0x%04x\n", hkey);
-			printk(TPACPI_NOTICE
-			       "please report the conditions when this "
-			       "event happened to %s\n", TPACPI_MAIL);
+			pr_notice("unhandled HKEY event 0x%04x\n", hkey);
+			pr_notice("please report the conditions when this "
+				  "event happened to %s\n", TPACPI_MAIL);
 		}
 
 		/* Legacy events */
@@ -3778,8 +3765,7 @@
 
 	if (hotkey_status_set(true) < 0 ||
 	    hotkey_mask_set(hotkey_acpi_mask) < 0)
-		printk(TPACPI_ERR
-		       "error while attempting to reset the event "
+		pr_err("error while attempting to reset the event "
 		       "firmware interface\n");
 
 	tpacpi_send_radiosw_update();
@@ -3824,14 +3810,12 @@
 {
 	tpacpi_log_usertask("procfs hotkey enable/disable");
 	if (!WARN((tpacpi_lifecycle == TPACPI_LIFE_RUNNING || !enable),
-			TPACPI_WARN
-			"hotkey enable/disable functionality has been "
-			"removed from the driver.  Hotkeys are always "
-			"enabled\n"))
-		printk(TPACPI_ERR
-			"Please remove the hotkey=enable module "
-			"parameter, it is deprecated.  Hotkeys are always "
-			"enabled\n");
+		  pr_fmt("hotkey enable/disable functionality has been "
+			 "removed from the driver.  "
+			 "Hotkeys are always enabled.\n")))
+		pr_err("Please remove the hotkey=enable module "
+		       "parameter, it is deprecated.  "
+		       "Hotkeys are always enabled.\n");
 }
 
 static int hotkey_write(char *buf)
@@ -4011,8 +3995,7 @@
 	/* Order firmware to save current state to NVRAM */
 	if (!acpi_evalf(NULL, NULL, "\\BLTH", "vd",
 			TP_ACPI_BLTH_SAVE_STATE))
-		printk(TPACPI_NOTICE
-			"failed to save bluetooth state to NVRAM\n");
+		pr_notice("failed to save bluetooth state to NVRAM\n");
 	else
 		vdbg_printk(TPACPI_DBG_RFKILL,
 			"bluestooth state saved to NVRAM\n");
@@ -4051,8 +4034,7 @@
 #ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES
 	if (dbg_bluetoothemul) {
 		tp_features.bluetooth = 1;
-		printk(TPACPI_INFO
-			"bluetooth switch emulation enabled\n");
+		pr_info("bluetooth switch emulation enabled\n");
 	} else
 #endif
 	if (tp_features.bluetooth &&
@@ -4203,8 +4185,7 @@
 	/* Order firmware to save current state to NVRAM */
 	if (!acpi_evalf(NULL, NULL, "\\WGSV", "vd",
 			TP_ACPI_WGSV_SAVE_STATE))
-		printk(TPACPI_NOTICE
-			"failed to save WWAN state to NVRAM\n");
+		pr_notice("failed to save WWAN state to NVRAM\n");
 	else
 		vdbg_printk(TPACPI_DBG_RFKILL,
 			"WWAN state saved to NVRAM\n");
@@ -4241,8 +4222,7 @@
 #ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES
 	if (dbg_wwanemul) {
 		tp_features.wan = 1;
-		printk(TPACPI_INFO
-			"wwan switch emulation enabled\n");
+		pr_info("wwan switch emulation enabled\n");
 	} else
 #endif
 	if (tp_features.wan &&
@@ -4382,8 +4362,7 @@
 #ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES
 	if (dbg_uwbemul) {
 		tp_features.uwb = 1;
-		printk(TPACPI_INFO
-			"uwb switch emulation enabled\n");
+		pr_info("uwb switch emulation enabled\n");
 	} else
 #endif
 	if (tp_features.uwb &&
@@ -4444,6 +4423,15 @@
 static int video_autosw_get(void);
 static int video_autosw_set(int enable);
 
+TPACPI_HANDLE(vid, root,
+	      "\\_SB.PCI.AGP.VGA",	/* 570 */
+	      "\\_SB.PCI0.AGP0.VID0",	/* 600e/x, 770x */
+	      "\\_SB.PCI0.VID0",	/* 770e */
+	      "\\_SB.PCI0.VID",		/* A21e, G4x, R50e, X30, X40 */
+	      "\\_SB.PCI0.AGP.VGA",	/* X100e and a few others */
+	      "\\_SB.PCI0.AGP.VID",	/* all others */
+	);				/* R30, R31 */
+
 TPACPI_HANDLE(vid2, root, "\\_SB.PCI0.AGPB.VID");	/* G41 */
 
 static int __init video_init(struct ibm_init_struct *iibm)
@@ -4487,7 +4475,7 @@
 	dbg_printk(TPACPI_DBG_EXIT,
 		   "restoring original video autoswitch mode\n");
 	if (video_autosw_set(video_orig_autosw))
-		printk(TPACPI_ERR "error while trying to restore original "
+		pr_err("error while trying to restore original "
 			"video autoswitch mode\n");
 }
 
@@ -4560,8 +4548,7 @@
 		res = acpi_evalf(vid_handle, NULL,
 				 "ASWT", "vdd", status * 0x100, 0);
 		if (!autosw && video_autosw_set(autosw)) {
-			printk(TPACPI_ERR
-			       "video auto-switch left enabled due to error\n");
+			pr_err("video auto-switch left enabled due to error\n");
 			return -EIO;
 		}
 		break;
@@ -4630,8 +4617,7 @@
 		return -ENOSYS;
 	}
 	if (!autosw && video_autosw_set(autosw)) {
-		printk(TPACPI_ERR
-		       "video auto-switch left enabled due to error\n");
+		pr_err("video auto-switch left enabled due to error\n");
 		return -EIO;
 	}
 
@@ -5348,7 +5334,7 @@
 	tpacpi_leds = kzalloc(sizeof(*tpacpi_leds) * TPACPI_LED_NUMLEDS,
 			      GFP_KERNEL);
 	if (!tpacpi_leds) {
-		printk(TPACPI_ERR "Out of memory for LED data\n");
+		pr_err("Out of memory for LED data\n");
 		return -ENOMEM;
 	}
 
@@ -5367,9 +5353,8 @@
 	}
 
 #ifdef CONFIG_THINKPAD_ACPI_UNSAFE_LEDS
-	printk(TPACPI_NOTICE
-		"warning: userspace override of important "
-		"firmware LEDs is enabled\n");
+	pr_notice("warning: userspace override of important "
+		  "firmware LEDs is enabled\n");
 #endif
 	return 0;
 }
@@ -5639,17 +5624,16 @@
 	if (n <= 0)
 		return;
 
-	printk(TPACPI_NOTICE
-		"temperatures (Celsius):");
+	pr_notice("temperatures (Celsius):");
 
 	for (i = 0; i < n; i++) {
 		if (t.temp[i] != TPACPI_THERMAL_SENSOR_NA)
-			printk(KERN_CONT " %d", (int)(t.temp[i] / 1000));
+			pr_cont(" %d", (int)(t.temp[i] / 1000));
 		else
-			printk(KERN_CONT " N/A");
+			pr_cont(" N/A");
 	}
 
-	printk(KERN_CONT "\n");
+	pr_cont("\n");
 }
 
 /* sysfs temp##_input -------------------------------------------------- */
@@ -5769,14 +5753,12 @@
 		if (ta1 == 0) {
 			/* This is sheer paranoia, but we handle it anyway */
 			if (acpi_tmp7) {
-				printk(TPACPI_ERR
-				       "ThinkPad ACPI EC access misbehaving, "
+				pr_err("ThinkPad ACPI EC access misbehaving, "
 				       "falling back to ACPI TMPx access "
 				       "mode\n");
 				thermal_read_mode = TPACPI_THERMAL_ACPI_TMP07;
 			} else {
-				printk(TPACPI_ERR
-				       "ThinkPad ACPI EC access misbehaving, "
+				pr_err("ThinkPad ACPI EC access misbehaving, "
 				       "disabling thermal sensors access\n");
 				thermal_read_mode = TPACPI_THERMAL_NONE;
 			}
@@ -6129,8 +6111,8 @@
 	if (ACPI_SUCCESS(acpi_evaluate_object(handle, "_BCL", NULL, &buffer))) {
 		obj = (union acpi_object *)buffer.pointer;
 		if (!obj || (obj->type != ACPI_TYPE_PACKAGE)) {
-			printk(TPACPI_ERR "Unknown _BCL data, "
-			       "please report this to %s\n", TPACPI_MAIL);
+			pr_err("Unknown _BCL data, please report this to %s\n",
+			       TPACPI_MAIL);
 			rc = 0;
 		} else {
 			rc = obj->package.count;
@@ -6214,18 +6196,15 @@
 	switch (b) {
 	case 16:
 		bright_maxlvl = 15;
-		printk(TPACPI_INFO
-		       "detected a 16-level brightness capable ThinkPad\n");
+		pr_info("detected a 16-level brightness capable ThinkPad\n");
 		break;
 	case 8:
 	case 0:
 		bright_maxlvl = 7;
-		printk(TPACPI_INFO
-		       "detected a 8-level brightness capable ThinkPad\n");
+		pr_info("detected a 8-level brightness capable ThinkPad\n");
 		break;
 	default:
-		printk(TPACPI_ERR
-		       "Unsupported brightness interface, "
+		pr_err("Unsupported brightness interface, "
 		       "please contact %s\n", TPACPI_MAIL);
 		tp_features.bright_unkfw = 1;
 		bright_maxlvl = b - 1;
@@ -6260,22 +6239,19 @@
 
 	if (acpi_video_backlight_support()) {
 		if (brightness_enable > 1) {
-			printk(TPACPI_INFO
-			       "Standard ACPI backlight interface "
-			       "available, not loading native one.\n");
+			pr_info("Standard ACPI backlight interface "
+				"available, not loading native one\n");
 			return 1;
 		} else if (brightness_enable == 1) {
-			printk(TPACPI_WARN
-				"Cannot enable backlight brightness support, "
+			pr_warn("Cannot enable backlight brightness support, "
 				"ACPI is already handling it.  Refer to the "
-				"acpi_backlight kernel parameter\n");
+				"acpi_backlight kernel parameter.\n");
 			return 1;
 		}
 	} else if (tp_features.bright_acpimode && brightness_enable > 1) {
-		printk(TPACPI_NOTICE
-			"Standard ACPI backlight interface not "
-			"available, thinkpad_acpi native "
-			"brightness control enabled\n");
+		pr_notice("Standard ACPI backlight interface not "
+			  "available, thinkpad_acpi native "
+			  "brightness control enabled\n");
 	}
 
 	/*
@@ -6319,19 +6295,17 @@
 	if (IS_ERR(ibm_backlight_device)) {
 		int rc = PTR_ERR(ibm_backlight_device);
 		ibm_backlight_device = NULL;
-		printk(TPACPI_ERR "Could not register backlight device\n");
+		pr_err("Could not register backlight device\n");
 		return rc;
 	}
 	vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_BRGHT,
 			"brightness is supported\n");
 
 	if (quirks & TPACPI_BRGHT_Q_ASK) {
-		printk(TPACPI_NOTICE
-			"brightness: will use unverified default: "
-			"brightness_mode=%d\n", brightness_mode);
-		printk(TPACPI_NOTICE
-			"brightness: please report to %s whether it works well "
-			"or not on your ThinkPad\n", TPACPI_MAIL);
+		pr_notice("brightness: will use unverified default: "
+			  "brightness_mode=%d\n", brightness_mode);
+		pr_notice("brightness: please report to %s whether it works well "
+			  "or not on your ThinkPad\n", TPACPI_MAIL);
 	}
 
 	/* Added by mistake in early 2007.  Probably useless, but it could
@@ -6804,8 +6778,7 @@
 	rc = snd_card_create(alsa_index, alsa_id, THIS_MODULE,
 			    sizeof(struct tpacpi_alsa_data), &card);
 	if (rc < 0 || !card) {
-		printk(TPACPI_ERR
-			"Failed to create ALSA card structures: %d\n", rc);
+		pr_err("Failed to create ALSA card structures: %d\n", rc);
 		return 1;
 	}
 
@@ -6839,9 +6812,8 @@
 		ctl_vol = snd_ctl_new1(&volume_alsa_control_vol, NULL);
 		rc = snd_ctl_add(card, ctl_vol);
 		if (rc < 0) {
-			printk(TPACPI_ERR
-				"Failed to create ALSA volume control: %d\n",
-				rc);
+			pr_err("Failed to create ALSA volume control: %d\n",
+			       rc);
 			goto err_exit;
 		}
 		data->ctl_vol_id = &ctl_vol->id;
@@ -6850,8 +6822,7 @@
 	ctl_mute = snd_ctl_new1(&volume_alsa_control_mute, NULL);
 	rc = snd_ctl_add(card, ctl_mute);
 	if (rc < 0) {
-		printk(TPACPI_ERR "Failed to create ALSA mute control: %d\n",
-			rc);
+		pr_err("Failed to create ALSA mute control: %d\n", rc);
 		goto err_exit;
 	}
 	data->ctl_mute_id = &ctl_mute->id;
@@ -6859,7 +6830,7 @@
 	snd_card_set_dev(card, &tpacpi_pdev->dev);
 	rc = snd_card_register(card);
 	if (rc < 0) {
-		printk(TPACPI_ERR "Failed to register ALSA card: %d\n", rc);
+		pr_err("Failed to register ALSA card: %d\n", rc);
 		goto err_exit;
 	}
 
@@ -6915,9 +6886,8 @@
 		return -EINVAL;
 
 	if (volume_mode == TPACPI_VOL_MODE_UCMS_STEP) {
-		printk(TPACPI_ERR
-			"UCMS step volume mode not implemented, "
-			"please contact %s\n", TPACPI_MAIL);
+		pr_err("UCMS step volume mode not implemented, "
+		       "please contact %s\n", TPACPI_MAIL);
 		return 1;
 	}
 
@@ -6981,13 +6951,11 @@
 
 	rc = volume_create_alsa_mixer();
 	if (rc) {
-		printk(TPACPI_ERR
-			"Could not create the ALSA mixer interface\n");
+		pr_err("Could not create the ALSA mixer interface\n");
 		return rc;
 	}
 
-	printk(TPACPI_INFO
-		"Console audio control enabled, mode: %s\n",
+	pr_info("Console audio control enabled, mode: %s\n",
 		(volume_control_allowed) ?
 			"override (read/write)" :
 			"monitor (read only)");
@@ -7049,12 +7017,10 @@
 	if (!volume_control_allowed && tpacpi_lifecycle != TPACPI_LIFE_INIT) {
 		if (unlikely(!tp_warned.volume_ctrl_forbidden)) {
 			tp_warned.volume_ctrl_forbidden = 1;
-			printk(TPACPI_NOTICE
-				"Console audio control in monitor mode, "
-				"changes are not allowed.\n");
-			printk(TPACPI_NOTICE
-				"Use the volume_control=1 module parameter "
-				"to enable volume control\n");
+			pr_notice("Console audio control in monitor mode, "
+				  "changes are not allowed\n");
+			pr_notice("Use the volume_control=1 module parameter "
+				  "to enable volume control\n");
 		}
 		return -EPERM;
 	}
@@ -7129,8 +7095,7 @@
 
 static int __init volume_init(struct ibm_init_struct *iibm)
 {
-	printk(TPACPI_INFO
-		"volume: disabled as there is no ALSA support in this kernel\n");
+	pr_info("volume: disabled as there is no ALSA support in this kernel\n");
 
 	return 1;
 }
@@ -7337,9 +7302,8 @@
 static void fan_quirk1_setup(void)
 {
 	if (fan_control_initial_status == 0x07) {
-		printk(TPACPI_NOTICE
-		       "fan_init: initial fan status is unknown, "
-		       "assuming it is in auto mode\n");
+		pr_notice("fan_init: initial fan status is unknown, "
+			  "assuming it is in auto mode\n");
 		tp_features.fan_ctrl_status_undef = 1;
 	}
 }
@@ -7726,8 +7690,7 @@
 		if (!queue_delayed_work(tpacpi_wq, &fan_watchdog_task,
 				msecs_to_jiffies(fan_watchdog_maxinterval
 						 * 1000))) {
-			printk(TPACPI_ERR
-			       "failed to queue the fan watchdog, "
+			pr_err("failed to queue the fan watchdog, "
 			       "watchdog will not trigger\n");
 		}
 	} else
@@ -7741,11 +7704,11 @@
 	if (tpacpi_lifecycle != TPACPI_LIFE_RUNNING)
 		return;
 
-	printk(TPACPI_NOTICE "fan watchdog: enabling fan\n");
+	pr_notice("fan watchdog: enabling fan\n");
 	rc = fan_set_enable();
 	if (rc < 0) {
-		printk(TPACPI_ERR "fan watchdog: error %d while enabling fan, "
-			"will try again later...\n", -rc);
+		pr_err("fan watchdog: error %d while enabling fan, "
+		       "will try again later...\n", -rc);
 		/* reschedule for later */
 		fan_watchdog_reset();
 	}
@@ -8049,8 +8012,7 @@
 					"secondary fan support enabled\n");
 			}
 		} else {
-			printk(TPACPI_ERR
-			       "ThinkPad ACPI EC access misbehaving, "
+			pr_err("ThinkPad ACPI EC access misbehaving, "
 			       "fan status and control unavailable\n");
 			return 1;
 		}
@@ -8150,9 +8112,8 @@
 	fan_control_resume_level = 0;
 	rc = fan_get_status_safe(&fan_control_resume_level);
 	if (rc < 0)
-		printk(TPACPI_NOTICE
-			"failed to read fan level for later "
-			"restore during resume: %d\n", rc);
+		pr_notice("failed to read fan level for later "
+			  "restore during resume: %d\n", rc);
 
 	/* if it is undefined, don't attempt to restore it.
 	 * KEEP THIS LAST */
@@ -8207,13 +8168,11 @@
 		return;
 	}
 	if (do_set) {
-		printk(TPACPI_NOTICE
-			"restoring fan level to 0x%02x\n",
-			fan_control_resume_level);
+		pr_notice("restoring fan level to 0x%02x\n",
+			  fan_control_resume_level);
 		rc = fan_set_level_safe(fan_control_resume_level);
 		if (rc < 0)
-			printk(TPACPI_NOTICE
-				"failed to restore fan level: %d\n", rc);
+			pr_notice("failed to restore fan level: %d\n", rc);
 	}
 }
 
@@ -8305,8 +8264,8 @@
 
 	*rc = fan_set_level_safe(level);
 	if (*rc == -ENXIO)
-		printk(TPACPI_ERR "level command accepted for unsupported "
-		       "access mode %d", fan_control_access_mode);
+		pr_err("level command accepted for unsupported access mode %d\n",
+		       fan_control_access_mode);
 	else if (!*rc)
 		tpacpi_disclose_usertask("procfs fan",
 			"set level to %d\n", level);
@@ -8321,8 +8280,8 @@
 
 	*rc = fan_set_enable();
 	if (*rc == -ENXIO)
-		printk(TPACPI_ERR "enable command accepted for unsupported "
-		       "access mode %d", fan_control_access_mode);
+		pr_err("enable command accepted for unsupported access mode %d\n",
+		       fan_control_access_mode);
 	else if (!*rc)
 		tpacpi_disclose_usertask("procfs fan", "enable\n");
 
@@ -8336,8 +8295,8 @@
 
 	*rc = fan_set_disable();
 	if (*rc == -ENXIO)
-		printk(TPACPI_ERR "disable command accepted for unsupported "
-		       "access mode %d", fan_control_access_mode);
+		pr_err("disable command accepted for unsupported access mode %d\n",
+		       fan_control_access_mode);
 	else if (!*rc)
 		tpacpi_disclose_usertask("procfs fan", "disable\n");
 
@@ -8356,8 +8315,8 @@
 
 	*rc = fan_set_speed(speed);
 	if (*rc == -ENXIO)
-		printk(TPACPI_ERR "speed command accepted for unsupported "
-		       "access mode %d", fan_control_access_mode);
+		pr_err("speed command accepted for unsupported access mode %d\n",
+		       fan_control_access_mode);
 	else if (!*rc)
 		tpacpi_disclose_usertask("procfs fan",
 			"set speed to %d\n", speed);
@@ -8560,8 +8519,8 @@
 		if (ibm->acpi->notify) {
 			ret = setup_acpi_notify(ibm);
 			if (ret == -ENODEV) {
-				printk(TPACPI_NOTICE "disabling subdriver %s\n",
-					ibm->name);
+				pr_notice("disabling subdriver %s\n",
+					  ibm->name);
 				ret = 0;
 				goto err_out;
 			}
@@ -8583,8 +8542,7 @@
 		entry = proc_create_data(ibm->name, mode, proc_dir,
 					 &dispatch_proc_fops, ibm);
 		if (!entry) {
-			printk(TPACPI_ERR "unable to create proc entry %s\n",
-			       ibm->name);
+			pr_err("unable to create proc entry %s\n", ibm->name);
 			ret = -ENODEV;
 			goto err_out;
 		}
@@ -8683,13 +8641,11 @@
 				tp->ec_release = (ec_fw_string[4] << 8)
 						| ec_fw_string[5];
 			} else {
-				printk(TPACPI_NOTICE
-					"ThinkPad firmware release %s "
-					"doesn't match the known patterns\n",
-					ec_fw_string);
-				printk(TPACPI_NOTICE
-					"please report this to %s\n",
-					TPACPI_MAIL);
+				pr_notice("ThinkPad firmware release %s "
+					  "doesn't match the known patterns\n",
+					  ec_fw_string);
+				pr_notice("please report this to %s\n",
+					  TPACPI_MAIL);
 			}
 			break;
 		}
@@ -8733,8 +8689,7 @@
 	tpacpi_acpi_handle_locate("ec", TPACPI_ACPI_EC_HID, &ec_handle);
 	if (!ec_handle) {
 		if (is_thinkpad)
-			printk(TPACPI_ERR
-				"Not yet supported ThinkPad detected!\n");
+			pr_err("Not yet supported ThinkPad detected!\n");
 		return -ENODEV;
 	}
 
@@ -8746,10 +8701,10 @@
 
 static void __init thinkpad_acpi_init_banner(void)
 {
-	printk(TPACPI_INFO "%s v%s\n", TPACPI_DESC, TPACPI_VERSION);
-	printk(TPACPI_INFO "%s\n", TPACPI_URL);
+	pr_info("%s v%s\n", TPACPI_DESC, TPACPI_VERSION);
+	pr_info("%s\n", TPACPI_URL);
 
-	printk(TPACPI_INFO "ThinkPad BIOS %s, EC %s\n",
+	pr_info("ThinkPad BIOS %s, EC %s\n",
 		(thinkpad_id.bios_version_str) ?
 			thinkpad_id.bios_version_str : "unknown",
 		(thinkpad_id.ec_version_str) ?
@@ -8758,7 +8713,7 @@
 	BUG_ON(!thinkpad_id.vendor);
 
 	if (thinkpad_id.model_str)
-		printk(TPACPI_INFO "%s %s, model %s\n",
+		pr_info("%s %s, model %s\n",
 			(thinkpad_id.vendor == PCI_VENDOR_ID_IBM) ?
 				"IBM" : ((thinkpad_id.vendor ==
 						PCI_VENDOR_ID_LENOVO) ?
@@ -9024,8 +8979,7 @@
 
 	ret = get_thinkpad_model_data(&thinkpad_id);
 	if (ret) {
-		printk(TPACPI_ERR
-			"unable to get DMI data: %d\n", ret);
+		pr_err("unable to get DMI data: %d\n", ret);
 		thinkpad_acpi_module_exit();
 		return ret;
 	}
@@ -9051,16 +9005,14 @@
 
 	proc_dir = proc_mkdir(TPACPI_PROC_DIR, acpi_root_dir);
 	if (!proc_dir) {
-		printk(TPACPI_ERR
-		       "unable to create proc dir " TPACPI_PROC_DIR);
+		pr_err("unable to create proc dir " TPACPI_PROC_DIR "\n");
 		thinkpad_acpi_module_exit();
 		return -ENODEV;
 	}
 
 	ret = platform_driver_register(&tpacpi_pdriver);
 	if (ret) {
-		printk(TPACPI_ERR
-		       "unable to register main platform driver\n");
+		pr_err("unable to register main platform driver\n");
 		thinkpad_acpi_module_exit();
 		return ret;
 	}
@@ -9068,8 +9020,7 @@
 
 	ret = platform_driver_register(&tpacpi_hwmon_pdriver);
 	if (ret) {
-		printk(TPACPI_ERR
-		       "unable to register hwmon platform driver\n");
+		pr_err("unable to register hwmon platform driver\n");
 		thinkpad_acpi_module_exit();
 		return ret;
 	}
@@ -9082,8 +9033,7 @@
 					&tpacpi_hwmon_pdriver.driver);
 	}
 	if (ret) {
-		printk(TPACPI_ERR
-		       "unable to create sysfs driver attributes\n");
+		pr_err("unable to create sysfs driver attributes\n");
 		thinkpad_acpi_module_exit();
 		return ret;
 	}
@@ -9096,7 +9046,7 @@
 	if (IS_ERR(tpacpi_pdev)) {
 		ret = PTR_ERR(tpacpi_pdev);
 		tpacpi_pdev = NULL;
-		printk(TPACPI_ERR "unable to register platform device\n");
+		pr_err("unable to register platform device\n");
 		thinkpad_acpi_module_exit();
 		return ret;
 	}
@@ -9106,16 +9056,14 @@
 	if (IS_ERR(tpacpi_sensors_pdev)) {
 		ret = PTR_ERR(tpacpi_sensors_pdev);
 		tpacpi_sensors_pdev = NULL;
-		printk(TPACPI_ERR
-		       "unable to register hwmon platform device\n");
+		pr_err("unable to register hwmon platform device\n");
 		thinkpad_acpi_module_exit();
 		return ret;
 	}
 	ret = device_create_file(&tpacpi_sensors_pdev->dev,
 				 &dev_attr_thinkpad_acpi_pdev_name);
 	if (ret) {
-		printk(TPACPI_ERR
-		       "unable to create sysfs hwmon device attributes\n");
+		pr_err("unable to create sysfs hwmon device attributes\n");
 		thinkpad_acpi_module_exit();
 		return ret;
 	}
@@ -9124,14 +9072,14 @@
 	if (IS_ERR(tpacpi_hwmon)) {
 		ret = PTR_ERR(tpacpi_hwmon);
 		tpacpi_hwmon = NULL;
-		printk(TPACPI_ERR "unable to register hwmon device\n");
+		pr_err("unable to register hwmon device\n");
 		thinkpad_acpi_module_exit();
 		return ret;
 	}
 	mutex_init(&tpacpi_inputdev_send_mutex);
 	tpacpi_inputdev = input_allocate_device();
 	if (!tpacpi_inputdev) {
-		printk(TPACPI_ERR "unable to allocate input device\n");
+		pr_err("unable to allocate input device\n");
 		thinkpad_acpi_module_exit();
 		return -ENOMEM;
 	} else {
@@ -9163,7 +9111,7 @@
 
 	ret = input_register_device(tpacpi_inputdev);
 	if (ret < 0) {
-		printk(TPACPI_ERR "unable to register input device\n");
+		pr_err("unable to register input device\n");
 		thinkpad_acpi_module_exit();
 		return ret;
 	} else {
diff -druN linux-2.6.39-libre/drivers/platform/x86/topstar-laptop.c linux-3.0-rc7-libre/drivers/platform/x86/topstar-laptop.c
--- linux-2.6.39-libre/drivers/platform/x86/topstar-laptop.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/platform/x86/topstar-laptop.c	2011-07-11 19:51:52.000000000 -0400
@@ -194,7 +194,7 @@
 	if (ret < 0)
 		return ret;
 
-	printk(KERN_INFO "Topstar Laptop ACPI extras driver loaded\n");
+	pr_info("ACPI extras driver loaded\n");
 
 	return 0;
 }
diff -druN linux-2.6.39-libre/drivers/platform/x86/toshiba_acpi.c linux-3.0-rc7-libre/drivers/platform/x86/toshiba_acpi.c
--- linux-2.6.39-libre/drivers/platform/x86/toshiba_acpi.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/platform/x86/toshiba_acpi.c	2011-07-11 19:51:52.000000000 -0400
@@ -35,6 +35,8 @@
  *
  */
 
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #define TOSHIBA_ACPI_VERSION	"0.19"
 #define PROC_INTERFACE_VERSION	1
 
@@ -60,11 +62,6 @@
 MODULE_DESCRIPTION("Toshiba Laptop ACPI Extras Driver");
 MODULE_LICENSE("GPL");
 
-#define MY_LOGPREFIX "toshiba_acpi: "
-#define MY_ERR KERN_ERR MY_LOGPREFIX
-#define MY_NOTICE KERN_NOTICE MY_LOGPREFIX
-#define MY_INFO KERN_INFO MY_LOGPREFIX
-
 /* Toshiba ACPI method paths */
 #define METHOD_LCD_BRIGHTNESS	"\\_SB_.PCI0.VGA_.LCD_._BCM"
 #define TOSH_INTERFACE_1	"\\_SB_.VALD"
@@ -301,7 +298,7 @@
 	in[0] = 0xf100;
 	status = hci_raw(in, out);
 	if (ACPI_FAILURE(status)) {
-		printk(MY_INFO "Illumination device not available\n");
+		pr_info("Illumination device not available\n");
 		return 0;
 	}
 	in[0] = 0xf400;
@@ -320,7 +317,7 @@
 	in[0] = 0xf100;
 	status = hci_raw(in, out);
 	if (ACPI_FAILURE(status)) {
-		printk(MY_INFO "Illumination device not available\n");
+		pr_info("Illumination device not available\n");
 		return;
 	}
 
@@ -331,7 +328,7 @@
 		in[2] = 1;
 		status = hci_raw(in, out);
 		if (ACPI_FAILURE(status)) {
-			printk(MY_INFO "ACPI call for illumination failed.\n");
+			pr_info("ACPI call for illumination failed\n");
 			return;
 		}
 	} else {
@@ -341,7 +338,7 @@
 		in[2] = 0;
 		status = hci_raw(in, out);
 		if (ACPI_FAILURE(status)) {
-			printk(MY_INFO "ACPI call for illumination failed.\n");
+			pr_info("ACPI call for illumination failed.\n");
 			return;
 		}
 	}
@@ -364,7 +361,7 @@
 	in[0] = 0xf100;
 	status = hci_raw(in, out);
 	if (ACPI_FAILURE(status)) {
-		printk(MY_INFO "Illumination device not available\n");
+		pr_info("Illumination device not available\n");
 		return LED_OFF;
 	}
 
@@ -373,7 +370,7 @@
 	in[1] = 0x14e;
 	status = hci_raw(in, out);
 	if (ACPI_FAILURE(status)) {
-		printk(MY_INFO "ACPI call for illumination failed.\n");
+		pr_info("ACPI call for illumination failed.\n");
 		return LED_OFF;
 	}
 
@@ -517,7 +514,7 @@
 		seq_printf(m, "brightness_levels:       %d\n",
 			     HCI_LCD_BRIGHTNESS_LEVELS);
 	} else {
-		printk(MY_ERR "Error reading LCD brightness\n");
+		pr_err("Error reading LCD brightness\n");
 	}
 
 	return 0;
@@ -592,7 +589,7 @@
 		seq_printf(m, "crt_out:                 %d\n", is_crt);
 		seq_printf(m, "tv_out:                  %d\n", is_tv);
 	} else {
-		printk(MY_ERR "Error reading video out status\n");
+		pr_err("Error reading video out status\n");
 	}
 
 	return 0;
@@ -686,7 +683,7 @@
 		seq_printf(m, "running:                 %d\n", (value > 0));
 		seq_printf(m, "force_on:                %d\n", force_fan);
 	} else {
-		printk(MY_ERR "Error reading fan status\n");
+		pr_err("Error reading fan status\n");
 	}
 
 	return 0;
@@ -750,9 +747,9 @@
 			 * some machines where system events sporadically
 			 * become disabled. */
 			hci_write1(HCI_SYSTEM_EVENT, 1, &hci_result);
-			printk(MY_NOTICE "Re-enabled hotkeys\n");
+			pr_notice("Re-enabled hotkeys\n");
 		} else {
-			printk(MY_ERR "Error reading hotkey status\n");
+			pr_err("Error reading hotkey status\n");
 			goto end;
 		}
 	}
@@ -863,7 +860,7 @@
 
 			if (!sparse_keymap_report_event(toshiba_acpi.hotkey_dev,
 							value, 1, true)) {
-				printk(MY_INFO "Unknown key %x\n",
+				pr_info("Unknown key %x\n",
 				       value);
 			}
 		} else if (hci_result == HCI_NOT_SUPPORTED) {
@@ -871,7 +868,7 @@
 			 * some machines where system events sporadically
 			 * become disabled. */
 			hci_write1(HCI_SYSTEM_EVENT, 1, &hci_result);
-			printk(MY_NOTICE "Re-enabled hotkeys\n");
+			pr_notice("Re-enabled hotkeys\n");
 		}
 	} while (hci_result != HCI_EMPTY);
 }
@@ -883,13 +880,13 @@
 
 	status = acpi_get_handle(NULL, device, &toshiba_acpi.handle);
 	if (ACPI_FAILURE(status)) {
-		printk(MY_INFO "Unable to get notification device\n");
+		pr_info("Unable to get notification device\n");
 		return -ENODEV;
 	}
 
 	toshiba_acpi.hotkey_dev = input_allocate_device();
 	if (!toshiba_acpi.hotkey_dev) {
-		printk(MY_INFO "Unable to register input device\n");
+		pr_info("Unable to register input device\n");
 		return -ENOMEM;
 	}
 
@@ -905,21 +902,21 @@
 	status = acpi_install_notify_handler(toshiba_acpi.handle,
 				ACPI_DEVICE_NOTIFY, toshiba_acpi_notify, NULL);
 	if (ACPI_FAILURE(status)) {
-		printk(MY_INFO "Unable to install hotkey notification\n");
+		pr_info("Unable to install hotkey notification\n");
 		error = -ENODEV;
 		goto err_free_keymap;
 	}
 
 	status = acpi_evaluate_object(toshiba_acpi.handle, "ENAB", NULL, NULL);
 	if (ACPI_FAILURE(status)) {
-		printk(MY_INFO "Unable to enable hotkeys\n");
+		pr_info("Unable to enable hotkeys\n");
 		error = -ENODEV;
 		goto err_remove_notify;
 	}
 
 	error = input_register_device(toshiba_acpi.hotkey_dev);
 	if (error) {
-		printk(MY_INFO "Unable to register input device\n");
+		pr_info("Unable to register input device\n");
 		goto err_remove_notify;
 	}
 
@@ -980,17 +977,17 @@
 	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");
+			pr_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");
+			pr_info("Unable to activate hotkeys\n");
 	} else
 		return -ENODEV;
 
-	printk(MY_INFO "Toshiba Laptop ACPI Extras version %s\n",
+	pr_info("Toshiba Laptop ACPI Extras version %s\n",
 	       TOSHIBA_ACPI_VERSION);
-	printk(MY_INFO "    HCI method: %s\n", method_hci);
+	pr_info("    HCI method: %s\n", method_hci);
 
 	mutex_init(&toshiba_acpi.mutex);
 
@@ -998,7 +995,7 @@
 							      -1, NULL, 0);
 	if (IS_ERR(toshiba_acpi.p_dev)) {
 		ret = PTR_ERR(toshiba_acpi.p_dev);
-		printk(MY_ERR "unable to register platform device\n");
+		pr_err("unable to register platform device\n");
 		toshiba_acpi.p_dev = NULL;
 		toshiba_acpi_exit();
 		return ret;
@@ -1028,7 +1025,7 @@
         if (IS_ERR(toshiba_backlight_device)) {
 		ret = PTR_ERR(toshiba_backlight_device);
 
-		printk(KERN_ERR "Could not register toshiba backlight device\n");
+		pr_err("Could not register toshiba backlight device\n");
 		toshiba_backlight_device = NULL;
 		toshiba_acpi_exit();
 		return ret;
@@ -1042,14 +1039,14 @@
 						   &toshiba_rfk_ops,
 						   &toshiba_acpi);
 		if (!toshiba_acpi.bt_rfk) {
-			printk(MY_ERR "unable to allocate rfkill device\n");
+			pr_err("unable to allocate rfkill device\n");
 			toshiba_acpi_exit();
 			return -ENOMEM;
 		}
 
 		ret = rfkill_register(toshiba_acpi.bt_rfk);
 		if (ret) {
-			printk(MY_ERR "unable to register rfkill device\n");
+			pr_err("unable to register rfkill device\n");
 			rfkill_destroy(toshiba_acpi.bt_rfk);
 			toshiba_acpi_exit();
 			return ret;
diff -druN linux-2.6.39-libre/drivers/platform/x86/toshiba_bluetooth.c linux-3.0-rc7-libre/drivers/platform/x86/toshiba_bluetooth.c
--- linux-2.6.39-libre/drivers/platform/x86/toshiba_bluetooth.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/platform/x86/toshiba_bluetooth.c	2011-07-11 19:51:52.000000000 -0400
@@ -17,6 +17,8 @@
  * delivered.
  */
 
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/init.h>
@@ -70,14 +72,13 @@
 	if (!(result & 0x01))
 		return 0;
 
-	printk(KERN_INFO "toshiba_bluetooth: Re-enabling Toshiba Bluetooth\n");
+	pr_info("Re-enabling Toshiba Bluetooth\n");
 	res1 = acpi_evaluate_object(handle, "AUSB", NULL, NULL);
 	res2 = acpi_evaluate_object(handle, "BTPO", NULL, NULL);
 	if (!ACPI_FAILURE(res1) || !ACPI_FAILURE(res2))
 		return 0;
 
-	printk(KERN_WARNING "toshiba_bluetooth: Failed to re-enable "
-	       "Toshiba Bluetooth\n");
+	pr_warn("Failed to re-enable Toshiba Bluetooth\n");
 
 	return -ENODEV;
 }
@@ -107,8 +108,8 @@
 				       &bt_present);
 
 	if (!ACPI_FAILURE(status) && bt_present) {
-		printk(KERN_INFO "Detected Toshiba ACPI Bluetooth device - "
-		      "installing RFKill handler\n");
+		pr_info("Detected Toshiba ACPI Bluetooth device - "
+			"installing RFKill handler\n");
 		result = toshiba_bluetooth_enable(device->handle);
 	}
 
diff -druN linux-2.6.39-libre/drivers/platform/x86/wmi.c linux-3.0-rc7-libre/drivers/platform/x86/wmi.c
--- linux-2.6.39-libre/drivers/platform/x86/wmi.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/platform/x86/wmi.c	2011-07-11 19:51:52.000000000 -0400
@@ -486,16 +486,16 @@
 	pr_info("\tnotify_id: %02X\n", g->notify_id);
 	pr_info("\treserved: %02X\n", g->reserved);
 	pr_info("\tinstance_count: %d\n", g->instance_count);
-	pr_info("\tflags: %#x ", g->flags);
+	pr_info("\tflags: %#x", g->flags);
 	if (g->flags) {
 		if (g->flags & ACPI_WMI_EXPENSIVE)
-			pr_cont("ACPI_WMI_EXPENSIVE ");
+			pr_cont(" ACPI_WMI_EXPENSIVE");
 		if (g->flags & ACPI_WMI_METHOD)
-			pr_cont("ACPI_WMI_METHOD ");
+			pr_cont(" ACPI_WMI_METHOD");
 		if (g->flags & ACPI_WMI_STRING)
-			pr_cont("ACPI_WMI_STRING ");
+			pr_cont(" ACPI_WMI_STRING");
 		if (g->flags & ACPI_WMI_EVENT)
-			pr_cont("ACPI_WMI_EVENT ");
+			pr_cont(" ACPI_WMI_EVENT");
 	}
 	pr_cont("\n");
 
diff -druN linux-2.6.39-libre/drivers/platform/x86/xo15-ebook.c linux-3.0-rc7-libre/drivers/platform/x86/xo15-ebook.c
--- linux-2.6.39-libre/drivers/platform/x86/xo15-ebook.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/platform/x86/xo15-ebook.c	2011-07-11 19:51:52.000000000 -0400
@@ -11,6 +11,8 @@
  *  your option) any later version.
  */
 
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/init.h>
@@ -20,7 +22,6 @@
 #include <acpi/acpi_drivers.h>
 
 #define MODULE_NAME "xo15-ebook"
-#define PREFIX MODULE_NAME ": "
 
 #define XO15_EBOOK_CLASS		MODULE_NAME
 #define XO15_EBOOK_TYPE_UNKNOWN	0x00
@@ -105,7 +106,7 @@
 	class = acpi_device_class(device);
 
 	if (strcmp(hid, XO15_EBOOK_HID)) {
-		printk(KERN_ERR PREFIX "Unsupported hid [%s]\n", hid);
+		pr_err("Unsupported hid [%s]\n", hid);
 		error = -ENODEV;
 		goto err_free_input;
 	}
diff -druN linux-2.6.39-libre/drivers/power/bq27x00_battery.c linux-3.0-rc7-libre/drivers/power/bq27x00_battery.c
--- linux-2.6.39-libre/drivers/power/bq27x00_battery.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/power/bq27x00_battery.c	2011-07-11 19:51:52.000000000 -0400
@@ -4,6 +4,7 @@
  * Copyright (C) 2008 Rodolfo Giometti <giometti@linux.it>
  * Copyright (C) 2008 Eurotech S.p.A. <info@eurotech.it>
  * Copyright (C) 2010-2011 Lars-Peter Clausen <lars@metafoo.de>
+ * Copyright (C) 2011 Pali Rohár <pali.rohar@gmail.com>
  *
  * Based on a previous work by Copyright (C) 2008 Texas Instruments, Inc.
  *
@@ -76,7 +77,7 @@
 	int time_to_empty_avg;
 	int time_to_full;
 	int charge_full;
-	int charge_counter;
+	int cycle_count;
 	int capacity;
 	int flags;
 
@@ -115,7 +116,7 @@
 	POWER_SUPPLY_PROP_CHARGE_FULL,
 	POWER_SUPPLY_PROP_CHARGE_NOW,
 	POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN,
-	POWER_SUPPLY_PROP_CHARGE_COUNTER,
+	POWER_SUPPLY_PROP_CYCLE_COUNT,
 	POWER_SUPPLY_PROP_ENERGY_NOW,
 };
 
@@ -267,7 +268,7 @@
 		cache.time_to_empty_avg = bq27x00_battery_read_time(di, BQ27x00_REG_TTECP);
 		cache.time_to_full = bq27x00_battery_read_time(di, BQ27x00_REG_TTF);
 		cache.charge_full = bq27x00_battery_read_lmd(di);
-		cache.charge_counter = bq27x00_battery_read_cyct(di);
+		cache.cycle_count = bq27x00_battery_read_cyct(di);
 
 		if (!is_bq27500)
 			cache.current_now = bq27x00_read(di, BQ27x00_REG_AI, false);
@@ -496,8 +497,8 @@
 	case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN:
 		ret = bq27x00_simple_value(di->charge_design_full, val);
 		break;
-	case POWER_SUPPLY_PROP_CHARGE_COUNTER:
-		ret = bq27x00_simple_value(di->cache.charge_counter, val);
+	case POWER_SUPPLY_PROP_CYCLE_COUNT:
+		ret = bq27x00_simple_value(di->cache.cycle_count, val);
 		break;
 	case POWER_SUPPLY_PROP_ENERGY_NOW:
 		ret = bq27x00_battery_energy(di, val);
diff -druN linux-2.6.39-libre/drivers/power/ds2760_battery.c linux-3.0-rc7-libre/drivers/power/ds2760_battery.c
--- linux-2.6.39-libre/drivers/power/ds2760_battery.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/power/ds2760_battery.c	2011-07-11 19:51:52.000000000 -0400
@@ -86,7 +86,11 @@
 	920,	/* NEC */
 	1440,	/* Samsung */
 	1440,	/* BYD */
+#ifdef CONFIG_MACH_H4700
+	1800,	/* HP iPAQ hx4700 3.7V 1800mAh (359113-001) */
+#else
 	1440,	/* Lishen */
+#endif
 	1440,	/* NEC */
 	2880,	/* Samsung */
 	2880,	/* BYD */
@@ -186,7 +190,7 @@
 
 	scale[0] = di->full_active_uAh;
 	for (i = 1; i < 5; i++)
-		scale[i] = scale[i - 1] + di->raw[DS2760_ACTIVE_FULL + 2 + i];
+		scale[i] = scale[i - 1] + di->raw[DS2760_ACTIVE_FULL + 1 + i];
 
 	di->full_active_uAh = battery_interpolate(scale, di->temp_C / 10);
 	di->full_active_uAh *= 1000; /* convert to µAh */
diff -druN linux-2.6.39-libre/drivers/power/ds2780_battery.c linux-3.0-rc7-libre/drivers/power/ds2780_battery.c
--- linux-2.6.39-libre/drivers/power/ds2780_battery.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/power/ds2780_battery.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,853 @@
+/*
+ * 1-wire client/driver for the Maxim/Dallas DS2780 Stand-Alone Fuel Gauge IC
+ *
+ * Copyright (C) 2010 Indesign, LLC
+ *
+ * Author: Clifton Barnes <cabarnes@indesign-llc.com>
+ *
+ * Based on ds2760_battery and ds2782_battery drivers
+ *
+ * This program is free software; you can redistribute it 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/slab.h>
+#include <linux/param.h>
+#include <linux/pm.h>
+#include <linux/platform_device.h>
+#include <linux/power_supply.h>
+#include <linux/idr.h>
+
+#include "../w1/w1.h"
+#include "../w1/slaves/w1_ds2780.h"
+
+/* Current unit measurement in uA for a 1 milli-ohm sense resistor */
+#define DS2780_CURRENT_UNITS	1563
+/* Charge unit measurement in uAh for a 1 milli-ohm sense resistor */
+#define DS2780_CHARGE_UNITS		6250
+/* Number of bytes in user EEPROM space */
+#define DS2780_USER_EEPROM_SIZE		(DS2780_EEPROM_BLOCK0_END - \
+					DS2780_EEPROM_BLOCK0_START + 1)
+/* Number of bytes in parameter EEPROM space */
+#define DS2780_PARAM_EEPROM_SIZE	(DS2780_EEPROM_BLOCK1_END - \
+					DS2780_EEPROM_BLOCK1_START + 1)
+
+struct ds2780_device_info {
+	struct device *dev;
+	struct power_supply bat;
+	struct device *w1_dev;
+};
+
+enum current_types {
+	CURRENT_NOW,
+	CURRENT_AVG,
+};
+
+static const char model[] = "DS2780";
+static const char manufacturer[] = "Maxim/Dallas";
+
+static inline struct ds2780_device_info *to_ds2780_device_info(
+	struct power_supply *psy)
+{
+	return container_of(psy, struct ds2780_device_info, bat);
+}
+
+static inline struct power_supply *to_power_supply(struct device *dev)
+{
+	return dev_get_drvdata(dev);
+}
+
+static inline int ds2780_read8(struct device *dev, u8 *val, int addr)
+{
+	return w1_ds2780_io(dev, val, addr, sizeof(u8), 0);
+}
+
+static int ds2780_read16(struct device *dev, s16 *val, int addr)
+{
+	int ret;
+	u8 raw[2];
+
+	ret = w1_ds2780_io(dev, raw, addr, sizeof(u8) * 2, 0);
+	if (ret < 0)
+		return ret;
+
+	*val = (raw[0] << 8) | raw[1];
+
+	return 0;
+}
+
+static inline int ds2780_read_block(struct device *dev, u8 *val, int addr,
+	size_t count)
+{
+	return w1_ds2780_io(dev, val, addr, count, 0);
+}
+
+static inline int ds2780_write(struct device *dev, u8 *val, int addr,
+	size_t count)
+{
+	return w1_ds2780_io(dev, val, addr, count, 1);
+}
+
+static inline int ds2780_store_eeprom(struct device *dev, int addr)
+{
+	return w1_ds2780_eeprom_cmd(dev, addr, W1_DS2780_COPY_DATA);
+}
+
+static inline int ds2780_recall_eeprom(struct device *dev, int addr)
+{
+	return w1_ds2780_eeprom_cmd(dev, addr, W1_DS2780_RECALL_DATA);
+}
+
+static int ds2780_save_eeprom(struct ds2780_device_info *dev_info, int reg)
+{
+	int ret;
+
+	ret = ds2780_store_eeprom(dev_info->w1_dev, reg);
+	if (ret < 0)
+		return ret;
+
+	ret = ds2780_recall_eeprom(dev_info->w1_dev, reg);
+	if (ret < 0)
+		return ret;
+
+	return 0;
+}
+
+/* Set sense resistor value in mhos */
+static int ds2780_set_sense_register(struct ds2780_device_info *dev_info,
+	u8 conductance)
+{
+	int ret;
+
+	ret = ds2780_write(dev_info->w1_dev, &conductance,
+				DS2780_RSNSP_REG, sizeof(u8));
+	if (ret < 0)
+		return ret;
+
+	return ds2780_save_eeprom(dev_info, DS2780_RSNSP_REG);
+}
+
+/* Get RSGAIN value from 0 to 1.999 in steps of 0.001 */
+static int ds2780_get_rsgain_register(struct ds2780_device_info *dev_info,
+	u16 *rsgain)
+{
+	return ds2780_read16(dev_info->w1_dev, rsgain, DS2780_RSGAIN_MSB_REG);
+}
+
+/* Set RSGAIN value from 0 to 1.999 in steps of 0.001 */
+static int ds2780_set_rsgain_register(struct ds2780_device_info *dev_info,
+	u16 rsgain)
+{
+	int ret;
+	u8 raw[] = {rsgain >> 8, rsgain & 0xFF};
+
+	ret = ds2780_write(dev_info->w1_dev, raw,
+				DS2780_RSGAIN_MSB_REG, sizeof(u8) * 2);
+	if (ret < 0)
+		return ret;
+
+	return ds2780_save_eeprom(dev_info, DS2780_RSGAIN_MSB_REG);
+}
+
+static int ds2780_get_voltage(struct ds2780_device_info *dev_info,
+	int *voltage_uV)
+{
+	int ret;
+	s16 voltage_raw;
+
+	/*
+	 * The voltage value is located in 10 bits across the voltage MSB
+	 * and LSB registers in two's compliment form
+	 * Sign bit of the voltage value is in bit 7 of the voltage MSB register
+	 * Bits 9 - 3 of the voltage value are in bits 6 - 0 of the
+	 * voltage MSB register
+	 * Bits 2 - 0 of the voltage value are in bits 7 - 5 of the
+	 * voltage LSB register
+	 */
+	ret = ds2780_read16(dev_info->w1_dev, &voltage_raw,
+				DS2780_VOLT_MSB_REG);
+	if (ret < 0)
+		return ret;
+
+	/*
+	 * DS2780 reports voltage in units of 4.88mV, but the battery class
+	 * reports in units of uV, so convert by multiplying by 4880.
+	 */
+	*voltage_uV = (voltage_raw / 32) * 4880;
+	return 0;
+}
+
+static int ds2780_get_temperature(struct ds2780_device_info *dev_info,
+	int *temperature)
+{
+	int ret;
+	s16 temperature_raw;
+
+	/*
+	 * The temperature value is located in 10 bits across the temperature
+	 * MSB and LSB registers in two's compliment form
+	 * Sign bit of the temperature value is in bit 7 of the temperature
+	 * MSB register
+	 * Bits 9 - 3 of the temperature value are in bits 6 - 0 of the
+	 * temperature MSB register
+	 * Bits 2 - 0 of the temperature value are in bits 7 - 5 of the
+	 * temperature LSB register
+	 */
+	ret = ds2780_read16(dev_info->w1_dev, &temperature_raw,
+				DS2780_TEMP_MSB_REG);
+	if (ret < 0)
+		return ret;
+
+	/*
+	 * Temperature is measured in units of 0.125 degrees celcius, the
+	 * power_supply class measures temperature in tenths of degrees
+	 * celsius. The temperature value is stored as a 10 bit number, plus
+	 * sign in the upper bits of a 16 bit register.
+	 */
+	*temperature = ((temperature_raw / 32) * 125) / 100;
+	return 0;
+}
+
+static int ds2780_get_current(struct ds2780_device_info *dev_info,
+	enum current_types type, int *current_uA)
+{
+	int ret, sense_res;
+	s16 current_raw;
+	u8 sense_res_raw, reg_msb;
+
+	/*
+	 * The units of measurement for current are dependent on the value of
+	 * the sense resistor.
+	 */
+	ret = ds2780_read8(dev_info->w1_dev, &sense_res_raw, DS2780_RSNSP_REG);
+	if (ret < 0)
+		return ret;
+
+	if (sense_res_raw == 0) {
+		dev_err(dev_info->dev, "sense resistor value is 0\n");
+		return -ENXIO;
+	}
+	sense_res = 1000 / sense_res_raw;
+
+	if (type == CURRENT_NOW)
+		reg_msb = DS2780_CURRENT_MSB_REG;
+	else if (type == CURRENT_AVG)
+		reg_msb = DS2780_IAVG_MSB_REG;
+	else
+		return -EINVAL;
+
+	/*
+	 * The current value is located in 16 bits across the current MSB
+	 * and LSB registers in two's compliment form
+	 * Sign bit of the current value is in bit 7 of the current MSB register
+	 * Bits 14 - 8 of the current value are in bits 6 - 0 of the current
+	 * MSB register
+	 * Bits 7 - 0 of the current value are in bits 7 - 0 of the current
+	 * LSB register
+	 */
+	ret = ds2780_read16(dev_info->w1_dev, &current_raw, reg_msb);
+	if (ret < 0)
+		return ret;
+
+	*current_uA = current_raw * (DS2780_CURRENT_UNITS / sense_res);
+	return 0;
+}
+
+static int ds2780_get_accumulated_current(struct ds2780_device_info *dev_info,
+	int *accumulated_current)
+{
+	int ret, sense_res;
+	s16 current_raw;
+	u8 sense_res_raw;
+
+	/*
+	 * The units of measurement for accumulated current are dependent on
+	 * the value of the sense resistor.
+	 */
+	ret = ds2780_read8(dev_info->w1_dev, &sense_res_raw, DS2780_RSNSP_REG);
+	if (ret < 0)
+		return ret;
+
+	if (sense_res_raw == 0) {
+		dev_err(dev_info->dev, "sense resistor value is 0\n");
+		return -ENXIO;
+	}
+	sense_res = 1000 / sense_res_raw;
+
+	/*
+	 * The ACR value is located in 16 bits across the ACR MSB and
+	 * LSB registers
+	 * Bits 15 - 8 of the ACR value are in bits 7 - 0 of the ACR
+	 * MSB register
+	 * Bits 7 - 0 of the ACR value are in bits 7 - 0 of the ACR
+	 * LSB register
+	 */
+	ret = ds2780_read16(dev_info->w1_dev, &current_raw, DS2780_ACR_MSB_REG);
+	if (ret < 0)
+		return ret;
+
+	*accumulated_current = current_raw * (DS2780_CHARGE_UNITS / sense_res);
+	return 0;
+}
+
+static int ds2780_get_capacity(struct ds2780_device_info *dev_info,
+	int *capacity)
+{
+	int ret;
+	u8 raw;
+
+	ret = ds2780_read8(dev_info->w1_dev, &raw, DS2780_RARC_REG);
+	if (ret < 0)
+		return ret;
+
+	*capacity = raw;
+	return raw;
+}
+
+static int ds2780_get_status(struct ds2780_device_info *dev_info, int *status)
+{
+	int ret, current_uA, capacity;
+
+	ret = ds2780_get_current(dev_info, CURRENT_NOW, &current_uA);
+	if (ret < 0)
+		return ret;
+
+	ret = ds2780_get_capacity(dev_info, &capacity);
+	if (ret < 0)
+		return ret;
+
+	if (capacity == 100)
+		*status = POWER_SUPPLY_STATUS_FULL;
+	else if (current_uA == 0)
+		*status = POWER_SUPPLY_STATUS_NOT_CHARGING;
+	else if (current_uA < 0)
+		*status = POWER_SUPPLY_STATUS_DISCHARGING;
+	else
+		*status = POWER_SUPPLY_STATUS_CHARGING;
+
+	return 0;
+}
+
+static int ds2780_get_charge_now(struct ds2780_device_info *dev_info,
+	int *charge_now)
+{
+	int ret;
+	u16 charge_raw;
+
+	/*
+	 * The RAAC value is located in 16 bits across the RAAC MSB and
+	 * LSB registers
+	 * Bits 15 - 8 of the RAAC value are in bits 7 - 0 of the RAAC
+	 * MSB register
+	 * Bits 7 - 0 of the RAAC value are in bits 7 - 0 of the RAAC
+	 * LSB register
+	 */
+	ret = ds2780_read16(dev_info->w1_dev, &charge_raw, DS2780_RAAC_MSB_REG);
+	if (ret < 0)
+		return ret;
+
+	*charge_now = charge_raw * 1600;
+	return 0;
+}
+
+static int ds2780_get_control_register(struct ds2780_device_info *dev_info,
+	u8 *control_reg)
+{
+	return ds2780_read8(dev_info->w1_dev, control_reg, DS2780_CONTROL_REG);
+}
+
+static int ds2780_set_control_register(struct ds2780_device_info *dev_info,
+	u8 control_reg)
+{
+	int ret;
+
+	ret = ds2780_write(dev_info->w1_dev, &control_reg,
+				DS2780_CONTROL_REG, sizeof(u8));
+	if (ret < 0)
+		return ret;
+
+	return ds2780_save_eeprom(dev_info, DS2780_CONTROL_REG);
+}
+
+static int ds2780_battery_get_property(struct power_supply *psy,
+	enum power_supply_property psp,
+	union power_supply_propval *val)
+{
+	int ret = 0;
+	struct ds2780_device_info *dev_info = to_ds2780_device_info(psy);
+
+	switch (psp) {
+	case POWER_SUPPLY_PROP_VOLTAGE_NOW:
+		ret = ds2780_get_voltage(dev_info, &val->intval);
+		break;
+
+	case POWER_SUPPLY_PROP_TEMP:
+		ret = ds2780_get_temperature(dev_info, &val->intval);
+		break;
+
+	case POWER_SUPPLY_PROP_MODEL_NAME:
+		val->strval = model;
+		break;
+
+	case POWER_SUPPLY_PROP_MANUFACTURER:
+		val->strval = manufacturer;
+		break;
+
+	case POWER_SUPPLY_PROP_CURRENT_NOW:
+		ret = ds2780_get_current(dev_info, CURRENT_NOW, &val->intval);
+		break;
+
+	case POWER_SUPPLY_PROP_CURRENT_AVG:
+		ret = ds2780_get_current(dev_info, CURRENT_AVG, &val->intval);
+		break;
+
+	case POWER_SUPPLY_PROP_STATUS:
+		ret = ds2780_get_status(dev_info, &val->intval);
+		break;
+
+	case POWER_SUPPLY_PROP_CAPACITY:
+		ret = ds2780_get_capacity(dev_info, &val->intval);
+		break;
+
+	case POWER_SUPPLY_PROP_CHARGE_COUNTER:
+		ret = ds2780_get_accumulated_current(dev_info, &val->intval);
+		break;
+
+	case POWER_SUPPLY_PROP_CHARGE_NOW:
+		ret = ds2780_get_charge_now(dev_info, &val->intval);
+		break;
+
+	default:
+		ret = -EINVAL;
+	}
+
+	return ret;
+}
+
+static enum power_supply_property ds2780_battery_props[] = {
+	POWER_SUPPLY_PROP_STATUS,
+	POWER_SUPPLY_PROP_VOLTAGE_NOW,
+	POWER_SUPPLY_PROP_TEMP,
+	POWER_SUPPLY_PROP_MODEL_NAME,
+	POWER_SUPPLY_PROP_MANUFACTURER,
+	POWER_SUPPLY_PROP_CURRENT_NOW,
+	POWER_SUPPLY_PROP_CURRENT_AVG,
+	POWER_SUPPLY_PROP_CAPACITY,
+	POWER_SUPPLY_PROP_CHARGE_COUNTER,
+	POWER_SUPPLY_PROP_CHARGE_NOW,
+};
+
+static ssize_t ds2780_get_pmod_enabled(struct device *dev,
+	struct device_attribute *attr,
+	char *buf)
+{
+	int ret;
+	u8 control_reg;
+	struct power_supply *psy = to_power_supply(dev);
+	struct ds2780_device_info *dev_info = to_ds2780_device_info(psy);
+
+	/* Get power mode */
+	ret = ds2780_get_control_register(dev_info, &control_reg);
+	if (ret < 0)
+		return ret;
+
+	return sprintf(buf, "%d\n",
+		 !!(control_reg & DS2780_CONTROL_REG_PMOD));
+}
+
+static ssize_t ds2780_set_pmod_enabled(struct device *dev,
+	struct device_attribute *attr,
+	const char *buf,
+	size_t count)
+{
+	int ret;
+	u8 control_reg, new_setting;
+	struct power_supply *psy = to_power_supply(dev);
+	struct ds2780_device_info *dev_info = to_ds2780_device_info(psy);
+
+	/* Set power mode */
+	ret = ds2780_get_control_register(dev_info, &control_reg);
+	if (ret < 0)
+		return ret;
+
+	ret = kstrtou8(buf, 0, &new_setting);
+	if (ret < 0)
+		return ret;
+
+	if ((new_setting != 0) && (new_setting != 1)) {
+		dev_err(dev_info->dev, "Invalid pmod setting (0 or 1)\n");
+		return -EINVAL;
+	}
+
+	if (new_setting)
+		control_reg |= DS2780_CONTROL_REG_PMOD;
+	else
+		control_reg &= ~DS2780_CONTROL_REG_PMOD;
+
+	ret = ds2780_set_control_register(dev_info, control_reg);
+	if (ret < 0)
+		return ret;
+
+	return count;
+}
+
+static ssize_t ds2780_get_sense_resistor_value(struct device *dev,
+	struct device_attribute *attr,
+	char *buf)
+{
+	int ret;
+	u8 sense_resistor;
+	struct power_supply *psy = to_power_supply(dev);
+	struct ds2780_device_info *dev_info = to_ds2780_device_info(psy);
+
+	ret = ds2780_read8(dev_info->w1_dev, &sense_resistor, DS2780_RSNSP_REG);
+	if (ret < 0)
+		return ret;
+
+	ret = sprintf(buf, "%d\n", sense_resistor);
+	return ret;
+}
+
+static ssize_t ds2780_set_sense_resistor_value(struct device *dev,
+	struct device_attribute *attr,
+	const char *buf,
+	size_t count)
+{
+	int ret;
+	u8 new_setting;
+	struct power_supply *psy = to_power_supply(dev);
+	struct ds2780_device_info *dev_info = to_ds2780_device_info(psy);
+
+	ret = kstrtou8(buf, 0, &new_setting);
+	if (ret < 0)
+		return ret;
+
+	ret = ds2780_set_sense_register(dev_info, new_setting);
+	if (ret < 0)
+		return ret;
+
+	return count;
+}
+
+static ssize_t ds2780_get_rsgain_setting(struct device *dev,
+	struct device_attribute *attr,
+	char *buf)
+{
+	int ret;
+	u16 rsgain;
+	struct power_supply *psy = to_power_supply(dev);
+	struct ds2780_device_info *dev_info = to_ds2780_device_info(psy);
+
+	ret = ds2780_get_rsgain_register(dev_info, &rsgain);
+	if (ret < 0)
+		return ret;
+
+	return sprintf(buf, "%d\n", rsgain);
+}
+
+static ssize_t ds2780_set_rsgain_setting(struct device *dev,
+	struct device_attribute *attr,
+	const char *buf,
+	size_t count)
+{
+	int ret;
+	u16 new_setting;
+	struct power_supply *psy = to_power_supply(dev);
+	struct ds2780_device_info *dev_info = to_ds2780_device_info(psy);
+
+	ret = kstrtou16(buf, 0, &new_setting);
+	if (ret < 0)
+		return ret;
+
+	/* Gain can only be from 0 to 1.999 in steps of .001 */
+	if (new_setting > 1999) {
+		dev_err(dev_info->dev, "Invalid rsgain setting (0 - 1999)\n");
+		return -EINVAL;
+	}
+
+	ret = ds2780_set_rsgain_register(dev_info, new_setting);
+	if (ret < 0)
+		return ret;
+
+	return count;
+}
+
+static ssize_t ds2780_get_pio_pin(struct device *dev,
+	struct device_attribute *attr,
+	char *buf)
+{
+	int ret;
+	u8 sfr;
+	struct power_supply *psy = to_power_supply(dev);
+	struct ds2780_device_info *dev_info = to_ds2780_device_info(psy);
+
+	ret = ds2780_read8(dev_info->w1_dev, &sfr, DS2780_SFR_REG);
+	if (ret < 0)
+		return ret;
+
+	ret = sprintf(buf, "%d\n", sfr & DS2780_SFR_REG_PIOSC);
+	return ret;
+}
+
+static ssize_t ds2780_set_pio_pin(struct device *dev,
+	struct device_attribute *attr,
+	const char *buf,
+	size_t count)
+{
+	int ret;
+	u8 new_setting;
+	struct power_supply *psy = to_power_supply(dev);
+	struct ds2780_device_info *dev_info = to_ds2780_device_info(psy);
+
+	ret = kstrtou8(buf, 0, &new_setting);
+	if (ret < 0)
+		return ret;
+
+	if ((new_setting != 0) && (new_setting != 1)) {
+		dev_err(dev_info->dev, "Invalid pio_pin setting (0 or 1)\n");
+		return -EINVAL;
+	}
+
+	ret = ds2780_write(dev_info->w1_dev, &new_setting,
+				DS2780_SFR_REG, sizeof(u8));
+	if (ret < 0)
+		return ret;
+
+	return count;
+}
+
+static ssize_t ds2780_read_param_eeprom_bin(struct file *filp,
+				struct kobject *kobj,
+				struct bin_attribute *bin_attr,
+				char *buf, loff_t off, size_t count)
+{
+	struct device *dev = container_of(kobj, struct device, kobj);
+	struct power_supply *psy = to_power_supply(dev);
+	struct ds2780_device_info *dev_info = to_ds2780_device_info(psy);
+
+	count = min_t(loff_t, count,
+		DS2780_EEPROM_BLOCK1_END -
+		DS2780_EEPROM_BLOCK1_START + 1 - off);
+
+	return ds2780_read_block(dev_info->w1_dev, buf,
+				DS2780_EEPROM_BLOCK1_START + off, count);
+}
+
+static ssize_t ds2780_write_param_eeprom_bin(struct file *filp,
+				struct kobject *kobj,
+				struct bin_attribute *bin_attr,
+				char *buf, loff_t off, size_t count)
+{
+	struct device *dev = container_of(kobj, struct device, kobj);
+	struct power_supply *psy = to_power_supply(dev);
+	struct ds2780_device_info *dev_info = to_ds2780_device_info(psy);
+	int ret;
+
+	count = min_t(loff_t, count,
+		DS2780_EEPROM_BLOCK1_END -
+		DS2780_EEPROM_BLOCK1_START + 1 - off);
+
+	ret = ds2780_write(dev_info->w1_dev, buf,
+				DS2780_EEPROM_BLOCK1_START + off, count);
+	if (ret < 0)
+		return ret;
+
+	ret = ds2780_save_eeprom(dev_info, DS2780_EEPROM_BLOCK1_START);
+	if (ret < 0)
+		return ret;
+
+	return count;
+}
+
+static struct bin_attribute ds2780_param_eeprom_bin_attr = {
+	.attr = {
+		.name = "param_eeprom",
+		.mode = S_IRUGO | S_IWUSR,
+	},
+	.size = DS2780_EEPROM_BLOCK1_END - DS2780_EEPROM_BLOCK1_START + 1,
+	.read = ds2780_read_param_eeprom_bin,
+	.write = ds2780_write_param_eeprom_bin,
+};
+
+static ssize_t ds2780_read_user_eeprom_bin(struct file *filp,
+				struct kobject *kobj,
+				struct bin_attribute *bin_attr,
+				char *buf, loff_t off, size_t count)
+{
+	struct device *dev = container_of(kobj, struct device, kobj);
+	struct power_supply *psy = to_power_supply(dev);
+	struct ds2780_device_info *dev_info = to_ds2780_device_info(psy);
+
+	count = min_t(loff_t, count,
+		DS2780_EEPROM_BLOCK0_END -
+		DS2780_EEPROM_BLOCK0_START + 1 - off);
+
+	return ds2780_read_block(dev_info->w1_dev, buf,
+				DS2780_EEPROM_BLOCK0_START + off, count);
+
+}
+
+static ssize_t ds2780_write_user_eeprom_bin(struct file *filp,
+				struct kobject *kobj,
+				struct bin_attribute *bin_attr,
+				char *buf, loff_t off, size_t count)
+{
+	struct device *dev = container_of(kobj, struct device, kobj);
+	struct power_supply *psy = to_power_supply(dev);
+	struct ds2780_device_info *dev_info = to_ds2780_device_info(psy);
+	int ret;
+
+	count = min_t(loff_t, count,
+		DS2780_EEPROM_BLOCK0_END -
+		DS2780_EEPROM_BLOCK0_START + 1 - off);
+
+	ret = ds2780_write(dev_info->w1_dev, buf,
+				DS2780_EEPROM_BLOCK0_START + off, count);
+	if (ret < 0)
+		return ret;
+
+	ret = ds2780_save_eeprom(dev_info, DS2780_EEPROM_BLOCK0_START);
+	if (ret < 0)
+		return ret;
+
+	return count;
+}
+
+static struct bin_attribute ds2780_user_eeprom_bin_attr = {
+	.attr = {
+		.name = "user_eeprom",
+		.mode = S_IRUGO | S_IWUSR,
+	},
+	.size = DS2780_EEPROM_BLOCK0_END - DS2780_EEPROM_BLOCK0_START + 1,
+	.read = ds2780_read_user_eeprom_bin,
+	.write = ds2780_write_user_eeprom_bin,
+};
+
+static DEVICE_ATTR(pmod_enabled, S_IRUGO | S_IWUSR, ds2780_get_pmod_enabled,
+	ds2780_set_pmod_enabled);
+static DEVICE_ATTR(sense_resistor_value, S_IRUGO | S_IWUSR,
+	ds2780_get_sense_resistor_value, ds2780_set_sense_resistor_value);
+static DEVICE_ATTR(rsgain_setting, S_IRUGO | S_IWUSR, ds2780_get_rsgain_setting,
+	ds2780_set_rsgain_setting);
+static DEVICE_ATTR(pio_pin, S_IRUGO | S_IWUSR, ds2780_get_pio_pin,
+	ds2780_set_pio_pin);
+
+
+static struct attribute *ds2780_attributes[] = {
+	&dev_attr_pmod_enabled.attr,
+	&dev_attr_sense_resistor_value.attr,
+	&dev_attr_rsgain_setting.attr,
+	&dev_attr_pio_pin.attr,
+	NULL
+};
+
+static const struct attribute_group ds2780_attr_group = {
+	.attrs = ds2780_attributes,
+};
+
+static int __devinit ds2780_battery_probe(struct platform_device *pdev)
+{
+	int ret = 0;
+	struct ds2780_device_info *dev_info;
+
+	dev_info = kzalloc(sizeof(*dev_info), GFP_KERNEL);
+	if (!dev_info) {
+		ret = -ENOMEM;
+		goto fail;
+	}
+
+	platform_set_drvdata(pdev, dev_info);
+
+	dev_info->dev			= &pdev->dev;
+	dev_info->w1_dev		= pdev->dev.parent;
+	dev_info->bat.name		= dev_name(&pdev->dev);
+	dev_info->bat.type		= POWER_SUPPLY_TYPE_BATTERY;
+	dev_info->bat.properties	= ds2780_battery_props;
+	dev_info->bat.num_properties	= ARRAY_SIZE(ds2780_battery_props);
+	dev_info->bat.get_property	= ds2780_battery_get_property;
+
+	ret = power_supply_register(&pdev->dev, &dev_info->bat);
+	if (ret) {
+		dev_err(dev_info->dev, "failed to register battery\n");
+		goto fail_free_info;
+	}
+
+	ret = sysfs_create_group(&dev_info->bat.dev->kobj, &ds2780_attr_group);
+	if (ret) {
+		dev_err(dev_info->dev, "failed to create sysfs group\n");
+		goto fail_unregister;
+	}
+
+	ret = sysfs_create_bin_file(&dev_info->bat.dev->kobj,
+					&ds2780_param_eeprom_bin_attr);
+	if (ret) {
+		dev_err(dev_info->dev,
+				"failed to create param eeprom bin file");
+		goto fail_remove_group;
+	}
+
+	ret = sysfs_create_bin_file(&dev_info->bat.dev->kobj,
+					&ds2780_user_eeprom_bin_attr);
+	if (ret) {
+		dev_err(dev_info->dev,
+				"failed to create user eeprom bin file");
+		goto fail_remove_bin_file;
+	}
+
+	return 0;
+
+fail_remove_bin_file:
+	sysfs_remove_bin_file(&dev_info->bat.dev->kobj,
+				&ds2780_param_eeprom_bin_attr);
+fail_remove_group:
+	sysfs_remove_group(&dev_info->bat.dev->kobj, &ds2780_attr_group);
+fail_unregister:
+	power_supply_unregister(&dev_info->bat);
+fail_free_info:
+	kfree(dev_info);
+fail:
+	return ret;
+}
+
+static int __devexit ds2780_battery_remove(struct platform_device *pdev)
+{
+	struct ds2780_device_info *dev_info = platform_get_drvdata(pdev);
+
+	/* remove attributes */
+	sysfs_remove_group(&dev_info->bat.dev->kobj, &ds2780_attr_group);
+
+	power_supply_unregister(&dev_info->bat);
+
+	kfree(dev_info);
+	return 0;
+}
+
+MODULE_ALIAS("platform:ds2780-battery");
+
+static struct platform_driver ds2780_battery_driver = {
+	.driver = {
+		.name = "ds2780-battery",
+	},
+	.probe	  = ds2780_battery_probe,
+	.remove   = ds2780_battery_remove,
+};
+
+static int __init ds2780_battery_init(void)
+{
+	return platform_driver_register(&ds2780_battery_driver);
+}
+
+static void __exit ds2780_battery_exit(void)
+{
+	platform_driver_unregister(&ds2780_battery_driver);
+}
+
+module_init(ds2780_battery_init);
+module_exit(ds2780_battery_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Clifton Barnes <cabarnes@indesign-llc.com>");
+MODULE_DESCRIPTION("Maxim/Dallas DS2780 Stand-Alone Fuel Gauage IC driver");
diff -druN linux-2.6.39-libre/drivers/power/gpio-charger.c linux-3.0-rc7-libre/drivers/power/gpio-charger.c
--- linux-2.6.39-libre/drivers/power/gpio-charger.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/power/gpio-charger.c	2011-07-11 19:51:52.000000000 -0400
@@ -161,12 +161,27 @@
 	return 0;
 }
 
+#ifdef CONFIG_PM_SLEEP
+static int gpio_charger_resume(struct device *dev)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct gpio_charger *gpio_charger = platform_get_drvdata(pdev);
+
+	power_supply_changed(&gpio_charger->charger);
+
+	return 0;
+}
+#endif
+
+static SIMPLE_DEV_PM_OPS(gpio_charger_pm_ops, NULL, gpio_charger_resume);
+
 static struct platform_driver gpio_charger_driver = {
 	.probe = gpio_charger_probe,
 	.remove = __devexit_p(gpio_charger_remove),
 	.driver = {
 		.name = "gpio-charger",
 		.owner = THIS_MODULE,
+		.pm = &gpio_charger_pm_ops,
 	},
 };
 
diff -druN linux-2.6.39-libre/drivers/power/intel_mid_battery.c linux-3.0-rc7-libre/drivers/power/intel_mid_battery.c
--- linux-2.6.39-libre/drivers/power/intel_mid_battery.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/power/intel_mid_battery.c	2011-07-11 19:51:52.000000000 -0400
@@ -522,7 +522,7 @@
 	if (retval) {
 		dev_warn(pbi->dev, "%s(): ipc pmic read failed\n",
 								__func__);
-		return retval;;
+		return retval;
 	}
 
 	return 0;
diff -druN linux-2.6.39-libre/drivers/power/isp1704_charger.c linux-3.0-rc7-libre/drivers/power/isp1704_charger.c
--- linux-2.6.39-libre/drivers/power/isp1704_charger.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/power/isp1704_charger.c	2011-07-11 19:51:52.000000000 -0400
@@ -33,6 +33,7 @@
 #include <linux/usb/ulpi.h>
 #include <linux/usb/ch9.h>
 #include <linux/usb/gadget.h>
+#include <linux/power/isp1704_charger.h>
 
 /* Vendor specific Power Control register */
 #define ISP1704_PWR_CTRL		0x3d
@@ -71,6 +72,18 @@
 };
 
 /*
+ * Disable/enable the power from the isp1704 if a function for it
+ * has been provided with platform data.
+ */
+static void isp1704_charger_set_power(struct isp1704_charger *isp, bool on)
+{
+	struct isp1704_charger_data	*board = isp->dev->platform_data;
+
+	if (board->set_power)
+		board->set_power(on);
+}
+
+/*
  * Determine is the charging port DCP (dedicated charger) or CDP (Host/HUB
  * chargers).
  *
@@ -222,6 +235,9 @@
 
 	mutex_lock(&lock);
 
+	if (event != USB_EVENT_NONE)
+		isp1704_charger_set_power(isp, 1);
+
 	switch (event) {
 	case USB_EVENT_VBUS:
 		isp->online = true;
@@ -269,6 +285,8 @@
 		 */
 		if (isp->otg->gadget)
 			usb_gadget_disconnect(isp->otg->gadget);
+
+		isp1704_charger_set_power(isp, 0);
 		break;
 	case USB_EVENT_ENUMERATED:
 		if (isp->present)
@@ -394,6 +412,8 @@
 	isp->dev = &pdev->dev;
 	platform_set_drvdata(pdev, isp);
 
+	isp1704_charger_set_power(isp, 1);
+
 	ret = isp1704_test_ulpi(isp);
 	if (ret < 0)
 		goto fail1;
@@ -434,6 +454,7 @@
 
 	/* Detect charger if VBUS is valid (the cable was already plugged). */
 	ret = otg_io_read(isp->otg, ULPI_USB_INT_STS);
+	isp1704_charger_set_power(isp, 0);
 	if ((ret & ULPI_INT_VBUS_VALID) && !isp->otg->default_a) {
 		isp->event = USB_EVENT_VBUS;
 		schedule_work(&isp->work);
@@ -459,6 +480,7 @@
 	otg_unregister_notifier(isp->otg, &isp->nb);
 	power_supply_unregister(&isp->psy);
 	otg_put_transceiver(isp->otg);
+	isp1704_charger_set_power(isp, 0);
 	kfree(isp);
 
 	return 0;
diff -druN linux-2.6.39-libre/drivers/power/Kconfig linux-3.0-rc7-libre/drivers/power/Kconfig
--- linux-2.6.39-libre/drivers/power/Kconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/power/Kconfig	2011-07-11 19:51:52.000000000 -0400
@@ -68,6 +68,13 @@
 	help
 	  Say Y here to enable support for batteries with ds2760 chip.
 
+config BATTERY_DS2780
+	tristate "DS2780 battery driver"
+	select W1
+	select W1_SLAVE_DS2780
+	help
+	  Say Y here to enable support for batteries with ds2780 chip.
+
 config BATTERY_DS2782
 	tristate "DS2782/DS2786 standalone gas-gauge"
 	depends on I2C
@@ -203,6 +210,15 @@
 	  Say Y to enable support for USB Charger Detection with
 	  ISP1707/ISP1704 USB transceivers.
 
+config CHARGER_MAX8903
+	tristate "MAX8903 Battery DC-DC Charger for USB and Adapter Power"
+	depends on GENERIC_HARDIRQS
+	help
+	  Say Y to enable support for the MAX8903 DC-DC charger and sysfs.
+	  The driver supports controlling charger-enable and current-limit
+	  pins based on the status of charger connections with interrupt
+	  handlers.
+
 config CHARGER_TWL4030
 	tristate "OMAP TWL4030 BCI charger driver"
 	depends on TWL4030_CORE
diff -druN linux-2.6.39-libre/drivers/power/Makefile linux-3.0-rc7-libre/drivers/power/Makefile
--- linux-2.6.39-libre/drivers/power/Makefile	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/power/Makefile	2011-07-11 19:51:52.000000000 -0400
@@ -15,6 +15,7 @@
 obj-$(CONFIG_TEST_POWER)	+= test_power.o
 
 obj-$(CONFIG_BATTERY_DS2760)	+= ds2760_battery.o
+obj-$(CONFIG_BATTERY_DS2780)	+= ds2780_battery.o
 obj-$(CONFIG_BATTERY_DS2782)	+= ds2782_battery.o
 obj-$(CONFIG_BATTERY_PMU)	+= pmu_battery.o
 obj-$(CONFIG_BATTERY_OLPC)	+= olpc_battery.o
@@ -32,5 +33,6 @@
 obj-$(CONFIG_BATTERY_JZ4740)	+= jz4740-battery.o
 obj-$(CONFIG_BATTERY_INTEL_MID)	+= intel_mid_battery.o
 obj-$(CONFIG_CHARGER_ISP1704)	+= isp1704_charger.o
+obj-$(CONFIG_CHARGER_MAX8903)	+= max8903_charger.o
 obj-$(CONFIG_CHARGER_TWL4030)	+= twl4030_charger.o
 obj-$(CONFIG_CHARGER_GPIO)	+= gpio-charger.o
diff -druN linux-2.6.39-libre/drivers/power/max8903_charger.c linux-3.0-rc7-libre/drivers/power/max8903_charger.c
--- linux-2.6.39-libre/drivers/power/max8903_charger.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/power/max8903_charger.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,391 @@
+/*
+ * max8903_charger.c - Maxim 8903 USB/Adapter Charger Driver
+ *
+ * Copyright (C) 2011 Samsung Electronics
+ * MyungJoo Ham <myungjoo.ham@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+#include <linux/gpio.h>
+#include <linux/interrupt.h>
+#include <linux/slab.h>
+#include <linux/power_supply.h>
+#include <linux/platform_device.h>
+#include <linux/power/max8903_charger.h>
+
+struct max8903_data {
+	struct max8903_pdata *pdata;
+	struct device *dev;
+	struct power_supply psy;
+	bool fault;
+	bool usb_in;
+	bool ta_in;
+};
+
+static enum power_supply_property max8903_charger_props[] = {
+	POWER_SUPPLY_PROP_STATUS, /* Charger status output */
+	POWER_SUPPLY_PROP_ONLINE, /* External power source */
+	POWER_SUPPLY_PROP_HEALTH, /* Fault or OK */
+};
+
+static int max8903_get_property(struct power_supply *psy,
+		enum power_supply_property psp,
+		union power_supply_propval *val)
+{
+	struct max8903_data *data = container_of(psy,
+			struct max8903_data, psy);
+
+	switch (psp) {
+	case POWER_SUPPLY_PROP_STATUS:
+		val->intval = POWER_SUPPLY_STATUS_UNKNOWN;
+		if (data->pdata->chg) {
+			if (gpio_get_value(data->pdata->chg) == 0)
+				val->intval = POWER_SUPPLY_STATUS_CHARGING;
+			else if (data->usb_in || data->ta_in)
+				val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING;
+			else
+				val->intval = POWER_SUPPLY_STATUS_DISCHARGING;
+		}
+		break;
+	case POWER_SUPPLY_PROP_ONLINE:
+		val->intval = 0;
+		if (data->usb_in || data->ta_in)
+			val->intval = 1;
+		break;
+	case POWER_SUPPLY_PROP_HEALTH:
+		val->intval = POWER_SUPPLY_HEALTH_GOOD;
+		if (data->fault)
+			val->intval = POWER_SUPPLY_HEALTH_UNSPEC_FAILURE;
+		break;
+	default:
+		return -EINVAL;
+	}
+	return 0;
+}
+
+static irqreturn_t max8903_dcin(int irq, void *_data)
+{
+	struct max8903_data *data = _data;
+	struct max8903_pdata *pdata = data->pdata;
+	bool ta_in;
+	enum power_supply_type old_type;
+
+	ta_in = gpio_get_value(pdata->dok) ? false : true;
+
+	if (ta_in == data->ta_in)
+		return IRQ_HANDLED;
+
+	data->ta_in = ta_in;
+
+	/* Set Current-Limit-Mode 1:DC 0:USB */
+	if (pdata->dcm)
+		gpio_set_value(pdata->dcm, ta_in ? 1 : 0);
+
+	/* Charger Enable / Disable (cen is negated) */
+	if (pdata->cen)
+		gpio_set_value(pdata->cen, ta_in ? 0 :
+				(data->usb_in ? 0 : 1));
+
+	dev_dbg(data->dev, "TA(DC-IN) Charger %s.\n", ta_in ?
+			"Connected" : "Disconnected");
+
+	old_type = data->psy.type;
+
+	if (data->ta_in)
+		data->psy.type = POWER_SUPPLY_TYPE_MAINS;
+	else if (data->usb_in)
+		data->psy.type = POWER_SUPPLY_TYPE_USB;
+	else
+		data->psy.type = POWER_SUPPLY_TYPE_BATTERY;
+
+	if (old_type != data->psy.type)
+		power_supply_changed(&data->psy);
+
+	return IRQ_HANDLED;
+}
+
+static irqreturn_t max8903_usbin(int irq, void *_data)
+{
+	struct max8903_data *data = _data;
+	struct max8903_pdata *pdata = data->pdata;
+	bool usb_in;
+	enum power_supply_type old_type;
+
+	usb_in = gpio_get_value(pdata->uok) ? false : true;
+
+	if (usb_in == data->usb_in)
+		return IRQ_HANDLED;
+
+	data->usb_in = usb_in;
+
+	/* Do not touch Current-Limit-Mode */
+
+	/* Charger Enable / Disable (cen is negated) */
+	if (pdata->cen)
+		gpio_set_value(pdata->cen, usb_in ? 0 :
+				(data->ta_in ? 0 : 1));
+
+	dev_dbg(data->dev, "USB Charger %s.\n", usb_in ?
+			"Connected" : "Disconnected");
+
+	old_type = data->psy.type;
+
+	if (data->ta_in)
+		data->psy.type = POWER_SUPPLY_TYPE_MAINS;
+	else if (data->usb_in)
+		data->psy.type = POWER_SUPPLY_TYPE_USB;
+	else
+		data->psy.type = POWER_SUPPLY_TYPE_BATTERY;
+
+	if (old_type != data->psy.type)
+		power_supply_changed(&data->psy);
+
+	return IRQ_HANDLED;
+}
+
+static irqreturn_t max8903_fault(int irq, void *_data)
+{
+	struct max8903_data *data = _data;
+	struct max8903_pdata *pdata = data->pdata;
+	bool fault;
+
+	fault = gpio_get_value(pdata->flt) ? false : true;
+
+	if (fault == data->fault)
+		return IRQ_HANDLED;
+
+	data->fault = fault;
+
+	if (fault)
+		dev_err(data->dev, "Charger suffers a fault and stops.\n");
+	else
+		dev_err(data->dev, "Charger recovered from a fault.\n");
+
+	return IRQ_HANDLED;
+}
+
+static __devinit int max8903_probe(struct platform_device *pdev)
+{
+	struct max8903_data *data;
+	struct device *dev = &pdev->dev;
+	struct max8903_pdata *pdata = pdev->dev.platform_data;
+	int ret = 0;
+	int gpio;
+	int ta_in = 0;
+	int usb_in = 0;
+
+	data = kzalloc(sizeof(struct max8903_data), GFP_KERNEL);
+	if (data == NULL) {
+		dev_err(dev, "Cannot allocate memory.\n");
+		return -ENOMEM;
+	}
+	data->pdata = pdata;
+	data->dev = dev;
+	platform_set_drvdata(pdev, data);
+
+	if (pdata->dc_valid == false && pdata->usb_valid == false) {
+		dev_err(dev, "No valid power sources.\n");
+		ret = -EINVAL;
+		goto err;
+	}
+
+	if (pdata->dc_valid) {
+		if (pdata->dok && gpio_is_valid(pdata->dok) &&
+				pdata->dcm && gpio_is_valid(pdata->dcm)) {
+			gpio = pdata->dok; /* PULL_UPed Interrupt */
+			ta_in = gpio_get_value(gpio) ? 0 : 1;
+
+			gpio = pdata->dcm; /* Output */
+			gpio_set_value(gpio, ta_in);
+		} else {
+			dev_err(dev, "When DC is wired, DOK and DCM should"
+					" be wired as well.\n");
+			ret = -EINVAL;
+			goto err;
+		}
+	} else {
+		if (pdata->dcm) {
+			if (gpio_is_valid(pdata->dcm))
+				gpio_set_value(pdata->dcm, 0);
+			else {
+				dev_err(dev, "Invalid pin: dcm.\n");
+				ret = -EINVAL;
+				goto err;
+			}
+		}
+	}
+
+	if (pdata->usb_valid) {
+		if (pdata->uok && gpio_is_valid(pdata->uok)) {
+			gpio = pdata->uok;
+			usb_in = gpio_get_value(gpio) ? 0 : 1;
+		} else {
+			dev_err(dev, "When USB is wired, UOK should be wired."
+					"as well.\n");
+			ret = -EINVAL;
+			goto err;
+		}
+	}
+
+	if (pdata->cen) {
+		if (gpio_is_valid(pdata->cen)) {
+			gpio_set_value(pdata->cen, (ta_in || usb_in) ? 0 : 1);
+		} else {
+			dev_err(dev, "Invalid pin: cen.\n");
+			ret = -EINVAL;
+			goto err;
+		}
+	}
+
+	if (pdata->chg) {
+		if (!gpio_is_valid(pdata->chg)) {
+			dev_err(dev, "Invalid pin: chg.\n");
+			ret = -EINVAL;
+			goto err;
+		}
+	}
+
+	if (pdata->flt) {
+		if (!gpio_is_valid(pdata->flt)) {
+			dev_err(dev, "Invalid pin: flt.\n");
+			ret = -EINVAL;
+			goto err;
+		}
+	}
+
+	if (pdata->usus) {
+		if (!gpio_is_valid(pdata->usus)) {
+			dev_err(dev, "Invalid pin: usus.\n");
+			ret = -EINVAL;
+			goto err;
+		}
+	}
+
+	data->fault = false;
+	data->ta_in = ta_in;
+	data->usb_in = usb_in;
+
+	data->psy.name = "max8903_charger";
+	data->psy.type = (ta_in) ? POWER_SUPPLY_TYPE_MAINS :
+			((usb_in) ? POWER_SUPPLY_TYPE_USB :
+			 POWER_SUPPLY_TYPE_BATTERY);
+	data->psy.get_property = max8903_get_property;
+	data->psy.properties = max8903_charger_props;
+	data->psy.num_properties = ARRAY_SIZE(max8903_charger_props);
+
+	ret = power_supply_register(dev, &data->psy);
+	if (ret) {
+		dev_err(dev, "failed: power supply register.\n");
+		goto err;
+	}
+
+	if (pdata->dc_valid) {
+		ret = request_threaded_irq(gpio_to_irq(pdata->dok),
+				NULL, max8903_dcin,
+				IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING,
+				"MAX8903 DC IN", data);
+		if (ret) {
+			dev_err(dev, "Cannot request irq %d for DC (%d)\n",
+					gpio_to_irq(pdata->dok), ret);
+			goto err_psy;
+		}
+	}
+
+	if (pdata->usb_valid) {
+		ret = request_threaded_irq(gpio_to_irq(pdata->uok),
+				NULL, max8903_usbin,
+				IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING,
+				"MAX8903 USB IN", data);
+		if (ret) {
+			dev_err(dev, "Cannot request irq %d for USB (%d)\n",
+					gpio_to_irq(pdata->uok), ret);
+			goto err_dc_irq;
+		}
+	}
+
+	if (pdata->flt) {
+		ret = request_threaded_irq(gpio_to_irq(pdata->flt),
+				NULL, max8903_fault,
+				IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING,
+				"MAX8903 Fault", data);
+		if (ret) {
+			dev_err(dev, "Cannot request irq %d for Fault (%d)\n",
+					gpio_to_irq(pdata->flt), ret);
+			goto err_usb_irq;
+		}
+	}
+
+	return 0;
+
+err_usb_irq:
+	if (pdata->usb_valid)
+		free_irq(gpio_to_irq(pdata->uok), data);
+err_dc_irq:
+	if (pdata->dc_valid)
+		free_irq(gpio_to_irq(pdata->dok), data);
+err_psy:
+	power_supply_unregister(&data->psy);
+err:
+	kfree(data);
+	return ret;
+}
+
+static __devexit int max8903_remove(struct platform_device *pdev)
+{
+	struct max8903_data *data = platform_get_drvdata(pdev);
+
+	if (data) {
+		struct max8903_pdata *pdata = data->pdata;
+
+		if (pdata->flt)
+			free_irq(gpio_to_irq(pdata->flt), data);
+		if (pdata->usb_valid)
+			free_irq(gpio_to_irq(pdata->uok), data);
+		if (pdata->dc_valid)
+			free_irq(gpio_to_irq(pdata->dok), data);
+		power_supply_unregister(&data->psy);
+		kfree(data);
+	}
+
+	return 0;
+}
+
+static struct platform_driver max8903_driver = {
+	.probe	= max8903_probe,
+	.remove	= __devexit_p(max8903_remove),
+	.driver = {
+		.name	= "max8903-charger",
+		.owner	= THIS_MODULE,
+	},
+};
+
+static int __init max8903_init(void)
+{
+	return platform_driver_register(&max8903_driver);
+}
+module_init(max8903_init);
+
+static void __exit max8903_exit(void)
+{
+	platform_driver_unregister(&max8903_driver);
+}
+module_exit(max8903_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("MAX8903 Charger Driver");
+MODULE_AUTHOR("MyungJoo Ham <myungjoo.ham@samsung.com>");
+MODULE_ALIAS("max8903-charger");
diff -druN linux-2.6.39-libre/drivers/power/max8925_power.c linux-3.0-rc7-libre/drivers/power/max8925_power.c
--- linux-2.6.39-libre/drivers/power/max8925_power.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/power/max8925_power.c	2011-07-11 19:51:52.000000000 -0400
@@ -425,16 +425,11 @@
 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;
-	}
-
+	pdata = pdev->dev.platform_data;
 	if (!pdata) {
 		dev_err(&pdev->dev, "platform data isn't assigned to "
 			"power supply\n");
@@ -447,6 +442,7 @@
 	info->chip = chip;
 	info->gpm = chip->i2c;
 	info->adc = chip->adc;
+	platform_set_drvdata(pdev, info);
 
 	info->ac.name = "max8925-ac";
 	info->ac.type = POWER_SUPPLY_TYPE_MAINS;
@@ -482,8 +478,6 @@
 	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;
diff -druN linux-2.6.39-libre/drivers/power/test_power.c linux-3.0-rc7-libre/drivers/power/test_power.c
--- linux-2.6.39-libre/drivers/power/test_power.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/power/test_power.c	2011-07-11 19:51:52.000000000 -0400
@@ -3,6 +3,12 @@
  *
  * Copyright 2010  Anton Vorontsov <cbouatmailru@gmail.com>
  *
+ * Dynamic module parameter code from the Virtual Battery Driver
+ * Copyright (C) 2008 Pylone, Inc.
+ * By: Masashi YOKOTA <yokota@pylone.jp>
+ * Originally found here:
+ * http://downloads.pylone.jp/src/virtual_battery/virtual_battery-0.0.1.tar.bz2
+ *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
@@ -15,8 +21,12 @@
 #include <linux/delay.h>
 #include <linux/vermagic.h>
 
-static int test_power_ac_online = 1;
-static int test_power_battery_status = POWER_SUPPLY_STATUS_CHARGING;
+static int ac_online			= 1;
+static int battery_status		= POWER_SUPPLY_STATUS_DISCHARGING;
+static int battery_health		= POWER_SUPPLY_HEALTH_GOOD;
+static int battery_present		= 1; /* true */
+static int battery_technology		= POWER_SUPPLY_TECHNOLOGY_LION;
+static int battery_capacity		= 50;
 
 static int test_power_get_ac_property(struct power_supply *psy,
 				      enum power_supply_property psp,
@@ -24,7 +34,7 @@
 {
 	switch (psp) {
 	case POWER_SUPPLY_PROP_ONLINE:
-		val->intval = test_power_ac_online;
+		val->intval = ac_online;
 		break;
 	default:
 		return -EINVAL;
@@ -47,22 +57,30 @@
 		val->strval = UTS_RELEASE;
 		break;
 	case POWER_SUPPLY_PROP_STATUS:
-		val->intval = test_power_battery_status;
+		val->intval = battery_status;
 		break;
 	case POWER_SUPPLY_PROP_CHARGE_TYPE:
 		val->intval = POWER_SUPPLY_CHARGE_TYPE_FAST;
 		break;
 	case POWER_SUPPLY_PROP_HEALTH:
-		val->intval = POWER_SUPPLY_HEALTH_GOOD;
+		val->intval = battery_health;
+		break;
+	case POWER_SUPPLY_PROP_PRESENT:
+		val->intval = battery_present;
 		break;
 	case POWER_SUPPLY_PROP_TECHNOLOGY:
-		val->intval = POWER_SUPPLY_TECHNOLOGY_LION;
+		val->intval = battery_technology;
 		break;
 	case POWER_SUPPLY_PROP_CAPACITY_LEVEL:
 		val->intval = POWER_SUPPLY_CAPACITY_LEVEL_NORMAL;
 		break;
 	case POWER_SUPPLY_PROP_CAPACITY:
-		val->intval = 50;
+	case POWER_SUPPLY_PROP_CHARGE_NOW:
+		val->intval = battery_capacity;
+		break;
+	case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN:
+	case POWER_SUPPLY_PROP_CHARGE_FULL:
+		val->intval = 100;
 		break;
 	case POWER_SUPPLY_PROP_TIME_TO_EMPTY_AVG:
 	case POWER_SUPPLY_PROP_TIME_TO_FULL_NOW:
@@ -84,9 +102,11 @@
 	POWER_SUPPLY_PROP_STATUS,
 	POWER_SUPPLY_PROP_CHARGE_TYPE,
 	POWER_SUPPLY_PROP_HEALTH,
+	POWER_SUPPLY_PROP_PRESENT,
 	POWER_SUPPLY_PROP_TECHNOLOGY,
+	POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN,
 	POWER_SUPPLY_PROP_CHARGE_FULL,
-	POWER_SUPPLY_PROP_CHARGE_EMPTY,
+	POWER_SUPPLY_PROP_CHARGE_NOW,
 	POWER_SUPPLY_PROP_CAPACITY,
 	POWER_SUPPLY_PROP_CAPACITY_LEVEL,
 	POWER_SUPPLY_PROP_TIME_TO_EMPTY_AVG,
@@ -118,6 +138,7 @@
 	},
 };
 
+
 static int __init test_power_init(void)
 {
 	int i;
@@ -145,8 +166,8 @@
 	int i;
 
 	/* Let's see how we handle changes... */
-	test_power_ac_online = 0;
-	test_power_battery_status = POWER_SUPPLY_STATUS_DISCHARGING;
+	ac_online = 0;
+	battery_status = POWER_SUPPLY_STATUS_DISCHARGING;
 	for (i = 0; i < ARRAY_SIZE(test_power_supplies); i++)
 		power_supply_changed(&test_power_supplies[i]);
 	pr_info("%s: 'changed' event sent, sleeping for 10 seconds...\n",
@@ -158,6 +179,241 @@
 }
 module_exit(test_power_exit);
 
+
+
+#define MAX_KEYLENGTH 256
+struct battery_property_map {
+	int value;
+	char const *key;
+};
+
+static struct battery_property_map map_ac_online[] = {
+	{ 0,  "on"  },
+	{ 1,  "off" },
+	{ -1, NULL  },
+};
+
+static struct battery_property_map map_status[] = {
+	{ POWER_SUPPLY_STATUS_CHARGING,     "charging"     },
+	{ POWER_SUPPLY_STATUS_DISCHARGING,  "discharging"  },
+	{ POWER_SUPPLY_STATUS_NOT_CHARGING, "not-charging" },
+	{ POWER_SUPPLY_STATUS_FULL,         "full"         },
+	{ -1,                               NULL           },
+};
+
+static struct battery_property_map map_health[] = {
+	{ POWER_SUPPLY_HEALTH_GOOD,           "good"        },
+	{ POWER_SUPPLY_HEALTH_OVERHEAT,       "overheat"    },
+	{ POWER_SUPPLY_HEALTH_DEAD,           "dead"        },
+	{ POWER_SUPPLY_HEALTH_OVERVOLTAGE,    "overvoltage" },
+	{ POWER_SUPPLY_HEALTH_UNSPEC_FAILURE, "failure"     },
+	{ -1,                                 NULL          },
+};
+
+static struct battery_property_map map_present[] = {
+	{ 0,  "false" },
+	{ 1,  "true"  },
+	{ -1, NULL    },
+};
+
+static struct battery_property_map map_technology[] = {
+	{ POWER_SUPPLY_TECHNOLOGY_NiMH, "NiMH" },
+	{ POWER_SUPPLY_TECHNOLOGY_LION, "LION" },
+	{ POWER_SUPPLY_TECHNOLOGY_LIPO, "LIPO" },
+	{ POWER_SUPPLY_TECHNOLOGY_LiFe, "LiFe" },
+	{ POWER_SUPPLY_TECHNOLOGY_NiCd, "NiCd" },
+	{ POWER_SUPPLY_TECHNOLOGY_LiMn, "LiMn" },
+	{ -1,				NULL   },
+};
+
+
+static int map_get_value(struct battery_property_map *map, const char *key,
+				int def_val)
+{
+	char buf[MAX_KEYLENGTH];
+	int cr;
+
+	strncpy(buf, key, MAX_KEYLENGTH);
+	buf[MAX_KEYLENGTH-1] = '\0';
+
+	cr = strnlen(buf, MAX_KEYLENGTH) - 1;
+	if (buf[cr] == '\n')
+		buf[cr] = '\0';
+
+	while (map->key) {
+		if (strncasecmp(map->key, buf, MAX_KEYLENGTH) == 0)
+			return map->value;
+		map++;
+	}
+
+	return def_val;
+}
+
+
+static const char *map_get_key(struct battery_property_map *map, int value,
+				const char *def_key)
+{
+	while (map->key) {
+		if (map->value == value)
+			return map->key;
+		map++;
+	}
+
+	return def_key;
+}
+
+static int param_set_ac_online(const char *key, const struct kernel_param *kp)
+{
+	ac_online = map_get_value(map_ac_online, key, ac_online);
+	power_supply_changed(&test_power_supplies[0]);
+	return 0;
+}
+
+static int param_get_ac_online(char *buffer, const struct kernel_param *kp)
+{
+	strcpy(buffer, map_get_key(map_ac_online, ac_online, "unknown"));
+	return strlen(buffer);
+}
+
+static int param_set_battery_status(const char *key,
+					const struct kernel_param *kp)
+{
+	battery_status = map_get_value(map_status, key, battery_status);
+	power_supply_changed(&test_power_supplies[1]);
+	return 0;
+}
+
+static int param_get_battery_status(char *buffer, const struct kernel_param *kp)
+{
+	strcpy(buffer, map_get_key(map_status, battery_status, "unknown"));
+	return strlen(buffer);
+}
+
+static int param_set_battery_health(const char *key,
+					const struct kernel_param *kp)
+{
+	battery_health = map_get_value(map_health, key, battery_health);
+	power_supply_changed(&test_power_supplies[1]);
+	return 0;
+}
+
+static int param_get_battery_health(char *buffer, const struct kernel_param *kp)
+{
+	strcpy(buffer, map_get_key(map_health, battery_health, "unknown"));
+	return strlen(buffer);
+}
+
+static int param_set_battery_present(const char *key,
+					const struct kernel_param *kp)
+{
+	battery_present = map_get_value(map_present, key, battery_present);
+	power_supply_changed(&test_power_supplies[0]);
+	return 0;
+}
+
+static int param_get_battery_present(char *buffer,
+					const struct kernel_param *kp)
+{
+	strcpy(buffer, map_get_key(map_present, battery_present, "unknown"));
+	return strlen(buffer);
+}
+
+static int param_set_battery_technology(const char *key,
+					const struct kernel_param *kp)
+{
+	battery_technology = map_get_value(map_technology, key,
+						battery_technology);
+	power_supply_changed(&test_power_supplies[1]);
+	return 0;
+}
+
+static int param_get_battery_technology(char *buffer,
+					const struct kernel_param *kp)
+{
+	strcpy(buffer,
+		map_get_key(map_technology, battery_technology, "unknown"));
+	return strlen(buffer);
+}
+
+static int param_set_battery_capacity(const char *key,
+					const struct kernel_param *kp)
+{
+	int tmp;
+
+	if (1 != sscanf(key, "%d", &tmp))
+		return -EINVAL;
+
+	battery_capacity = tmp;
+	power_supply_changed(&test_power_supplies[1]);
+	return 0;
+}
+
+#define param_get_battery_capacity param_get_int
+
+
+
+static struct kernel_param_ops param_ops_ac_online = {
+	.set = param_set_ac_online,
+	.get = param_get_ac_online,
+};
+
+static struct kernel_param_ops param_ops_battery_status = {
+	.set = param_set_battery_status,
+	.get = param_get_battery_status,
+};
+
+static struct kernel_param_ops param_ops_battery_present = {
+	.set = param_set_battery_present,
+	.get = param_get_battery_present,
+};
+
+static struct kernel_param_ops param_ops_battery_technology = {
+	.set = param_set_battery_technology,
+	.get = param_get_battery_technology,
+};
+
+static struct kernel_param_ops param_ops_battery_health = {
+	.set = param_set_battery_health,
+	.get = param_get_battery_health,
+};
+
+static struct kernel_param_ops param_ops_battery_capacity = {
+	.set = param_set_battery_capacity,
+	.get = param_get_battery_capacity,
+};
+
+
+#define param_check_ac_online(name, p) __param_check(name, p, void);
+#define param_check_battery_status(name, p) __param_check(name, p, void);
+#define param_check_battery_present(name, p) __param_check(name, p, void);
+#define param_check_battery_technology(name, p) __param_check(name, p, void);
+#define param_check_battery_health(name, p) __param_check(name, p, void);
+#define param_check_battery_capacity(name, p) __param_check(name, p, void);
+
+
+module_param(ac_online, ac_online, 0644);
+MODULE_PARM_DESC(ac_online, "AC charging state <on|off>");
+
+module_param(battery_status, battery_status, 0644);
+MODULE_PARM_DESC(battery_status,
+	"battery status <charging|discharging|not-charging|full>");
+
+module_param(battery_present, battery_present, 0644);
+MODULE_PARM_DESC(battery_present,
+	"battery presence state <good|overheat|dead|overvoltage|failure>");
+
+module_param(battery_technology, battery_technology, 0644);
+MODULE_PARM_DESC(battery_technology,
+	"battery technology <NiMH|LION|LIPO|LiFe|NiCd|LiMn>");
+
+module_param(battery_health, battery_health, 0644);
+MODULE_PARM_DESC(battery_health,
+	"battery health state <good|overheat|dead|overvoltage|failure>");
+
+module_param(battery_capacity, battery_capacity, 0644);
+MODULE_PARM_DESC(battery_capacity, "battery capacity (percentage)");
+
+
 MODULE_DESCRIPTION("Power supply driver for testing");
 MODULE_AUTHOR("Anton Vorontsov <cbouatmailru@gmail.com>");
 MODULE_LICENSE("GPL");
diff -druN linux-2.6.39-libre/drivers/power/z2_battery.c linux-3.0-rc7-libre/drivers/power/z2_battery.c
--- linux-2.6.39-libre/drivers/power/z2_battery.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/power/z2_battery.c	2011-07-11 19:51:52.000000000 -0400
@@ -271,24 +271,33 @@
 }
 
 #ifdef CONFIG_PM
-static int z2_batt_suspend(struct i2c_client *client, pm_message_t state)
+static int z2_batt_suspend(struct device *dev)
 {
+	struct i2c_client *client = to_i2c_client(dev);
 	struct z2_charger *charger = i2c_get_clientdata(client);
 
 	flush_work_sync(&charger->bat_work);
 	return 0;
 }
 
-static int z2_batt_resume(struct i2c_client *client)
+static int z2_batt_resume(struct device *dev)
 {
+	struct i2c_client *client = to_i2c_client(dev);
 	struct z2_charger *charger = i2c_get_clientdata(client);
 
 	schedule_work(&charger->bat_work);
 	return 0;
 }
+
+static const struct dev_pm_ops z2_battery_pm_ops = {
+	.suspend	= z2_batt_suspend,
+	.resume		= z2_batt_resume,
+};
+
+#define	Z2_BATTERY_PM_OPS	(&z2_battery_pm_ops)
+
 #else
-#define z2_batt_suspend NULL
-#define z2_batt_resume NULL
+#define	Z2_BATTERY_PM_OPS	(NULL)
 #endif
 
 static const struct i2c_device_id z2_batt_id[] = {
@@ -301,11 +310,10 @@
 	.driver	= {
 		.name	= "z2-battery",
 		.owner	= THIS_MODULE,
+		.pm	= Z2_BATTERY_PM_OPS
 	},
 	.probe		= z2_batt_probe,
 	.remove		= z2_batt_remove,
-	.suspend	= z2_batt_suspend,
-	.resume		= z2_batt_resume,
 	.id_table	= z2_batt_id,
 };
 
diff -druN linux-2.6.39-libre/drivers/ptp/Kconfig linux-3.0-rc7-libre/drivers/ptp/Kconfig
--- linux-2.6.39-libre/drivers/ptp/Kconfig	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/ptp/Kconfig	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,75 @@
+#
+# PTP clock support configuration
+#
+
+menu "PTP clock support"
+
+comment "Enable Device Drivers -> PPS to see the PTP clock options."
+	depends on PPS=n
+
+config PTP_1588_CLOCK
+	tristate "PTP clock support"
+	depends on EXPERIMENTAL
+	depends on PPS
+	help
+	  The IEEE 1588 standard defines a method to precisely
+	  synchronize distributed clocks over Ethernet networks. The
+	  standard defines a Precision Time Protocol (PTP), which can
+	  be used to achieve synchronization within a few dozen
+	  microseconds. In addition, with the help of special hardware
+	  time stamping units, it can be possible to achieve
+	  synchronization to within a few hundred nanoseconds.
+
+	  This driver adds support for PTP clocks as character
+	  devices. If you want to use a PTP clock, then you should
+	  also enable at least one clock driver as well.
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called ptp.
+
+config PTP_1588_CLOCK_GIANFAR
+	tristate "Freescale eTSEC as PTP clock"
+	depends on PTP_1588_CLOCK
+	depends on GIANFAR
+	help
+	  This driver adds support for using the eTSEC as a PTP
+	  clock. This clock is only useful if your PTP programs are
+	  getting hardware time stamps on the PTP Ethernet packets
+	  using the SO_TIMESTAMPING API.
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called gianfar_ptp.
+
+config PTP_1588_CLOCK_IXP46X
+	tristate "Intel IXP46x as PTP clock"
+	depends on PTP_1588_CLOCK
+	depends on IXP4XX_ETH
+	help
+	  This driver adds support for using the IXP46X as a PTP
+	  clock. This clock is only useful if your PTP programs are
+	  getting hardware time stamps on the PTP Ethernet packets
+	  using the SO_TIMESTAMPING API.
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called ptp_ixp46x.
+
+comment "Enable PHYLIB and NETWORK_PHY_TIMESTAMPING to see the additional clocks."
+	depends on PTP_1588_CLOCK && (PHYLIB=n || NETWORK_PHY_TIMESTAMPING=n)
+
+config DP83640_PHY
+	tristate "Driver for the National Semiconductor DP83640 PHYTER"
+	depends on PTP_1588_CLOCK
+	depends on NETWORK_PHY_TIMESTAMPING
+	depends on PHYLIB
+	---help---
+	  Supports the DP83640 PHYTER with IEEE 1588 features.
+
+	  This driver adds support for using the DP83640 as a PTP
+	  clock. This clock is only useful if your PTP programs are
+	  getting hardware time stamps on the PTP Ethernet packets
+	  using the SO_TIMESTAMPING API.
+
+	  In order for this to work, your MAC driver must also
+	  implement the skb_tx_timetamp() function.
+
+endmenu
diff -druN linux-2.6.39-libre/drivers/ptp/Makefile linux-3.0-rc7-libre/drivers/ptp/Makefile
--- linux-2.6.39-libre/drivers/ptp/Makefile	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/ptp/Makefile	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,7 @@
+#
+# Makefile for PTP 1588 clock support.
+#
+
+ptp-y					:= ptp_clock.o ptp_chardev.o ptp_sysfs.o
+obj-$(CONFIG_PTP_1588_CLOCK)		+= ptp.o
+obj-$(CONFIG_PTP_1588_CLOCK_IXP46X)	+= ptp_ixp46x.o
diff -druN linux-2.6.39-libre/drivers/ptp/ptp_chardev.c linux-3.0-rc7-libre/drivers/ptp/ptp_chardev.c
--- linux-2.6.39-libre/drivers/ptp/ptp_chardev.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/ptp/ptp_chardev.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,160 @@
+/*
+ * PTP 1588 clock support - character device implementation.
+ *
+ * Copyright (C) 2010 OMICRON electronics GmbH
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the 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/posix-clock.h>
+#include <linux/poll.h>
+#include <linux/sched.h>
+
+#include "ptp_private.h"
+
+int ptp_open(struct posix_clock *pc, fmode_t fmode)
+{
+	return 0;
+}
+
+long ptp_ioctl(struct posix_clock *pc, unsigned int cmd, unsigned long arg)
+{
+	struct ptp_clock_caps caps;
+	struct ptp_clock_request req;
+	struct ptp_clock *ptp = container_of(pc, struct ptp_clock, clock);
+	struct ptp_clock_info *ops = ptp->info;
+	int enable, err = 0;
+
+	switch (cmd) {
+
+	case PTP_CLOCK_GETCAPS:
+		memset(&caps, 0, sizeof(caps));
+		caps.max_adj = ptp->info->max_adj;
+		caps.n_alarm = ptp->info->n_alarm;
+		caps.n_ext_ts = ptp->info->n_ext_ts;
+		caps.n_per_out = ptp->info->n_per_out;
+		caps.pps = ptp->info->pps;
+		if (copy_to_user((void __user *)arg, &caps, sizeof(caps)))
+			err = -EFAULT;
+		break;
+
+	case PTP_EXTTS_REQUEST:
+		if (copy_from_user(&req.extts, (void __user *)arg,
+				   sizeof(req.extts))) {
+			err = -EFAULT;
+			break;
+		}
+		if (req.extts.index >= ops->n_ext_ts) {
+			err = -EINVAL;
+			break;
+		}
+		req.type = PTP_CLK_REQ_EXTTS;
+		enable = req.extts.flags & PTP_ENABLE_FEATURE ? 1 : 0;
+		err = ops->enable(ops, &req, enable);
+		break;
+
+	case PTP_PEROUT_REQUEST:
+		if (copy_from_user(&req.perout, (void __user *)arg,
+				   sizeof(req.perout))) {
+			err = -EFAULT;
+			break;
+		}
+		if (req.perout.index >= ops->n_per_out) {
+			err = -EINVAL;
+			break;
+		}
+		req.type = PTP_CLK_REQ_PEROUT;
+		enable = req.perout.period.sec || req.perout.period.nsec;
+		err = ops->enable(ops, &req, enable);
+		break;
+
+	case PTP_ENABLE_PPS:
+		if (!capable(CAP_SYS_TIME))
+			return -EPERM;
+		req.type = PTP_CLK_REQ_PPS;
+		enable = arg ? 1 : 0;
+		err = ops->enable(ops, &req, enable);
+		break;
+
+	default:
+		err = -ENOTTY;
+		break;
+	}
+	return err;
+}
+
+unsigned int ptp_poll(struct posix_clock *pc, struct file *fp, poll_table *wait)
+{
+	struct ptp_clock *ptp = container_of(pc, struct ptp_clock, clock);
+
+	poll_wait(fp, &ptp->tsev_wq, wait);
+
+	return queue_cnt(&ptp->tsevq) ? POLLIN : 0;
+}
+
+ssize_t ptp_read(struct posix_clock *pc,
+		 uint rdflags, char __user *buf, size_t cnt)
+{
+	struct ptp_clock *ptp = container_of(pc, struct ptp_clock, clock);
+	struct timestamp_event_queue *queue = &ptp->tsevq;
+	struct ptp_extts_event event[PTP_BUF_TIMESTAMPS];
+	unsigned long flags;
+	size_t qcnt, i;
+
+	if (cnt % sizeof(struct ptp_extts_event) != 0)
+		return -EINVAL;
+
+	if (cnt > sizeof(event))
+		cnt = sizeof(event);
+
+	cnt = cnt / sizeof(struct ptp_extts_event);
+
+	if (mutex_lock_interruptible(&ptp->tsevq_mux))
+		return -ERESTARTSYS;
+
+	if (wait_event_interruptible(ptp->tsev_wq,
+				     ptp->defunct || queue_cnt(queue))) {
+		mutex_unlock(&ptp->tsevq_mux);
+		return -ERESTARTSYS;
+	}
+
+	if (ptp->defunct) {
+		mutex_unlock(&ptp->tsevq_mux);
+		return -ENODEV;
+	}
+
+	spin_lock_irqsave(&queue->lock, flags);
+
+	qcnt = queue_cnt(queue);
+
+	if (cnt > qcnt)
+		cnt = qcnt;
+
+	for (i = 0; i < cnt; i++) {
+		event[i] = queue->buf[queue->head];
+		queue->head = (queue->head + 1) % PTP_MAX_TIMESTAMPS;
+	}
+
+	spin_unlock_irqrestore(&queue->lock, flags);
+
+	cnt = cnt * sizeof(struct ptp_extts_event);
+
+	mutex_unlock(&ptp->tsevq_mux);
+
+	if (copy_to_user(buf, event, cnt))
+		return -EFAULT;
+
+	return cnt;
+}
diff -druN linux-2.6.39-libre/drivers/ptp/ptp_clock.c linux-3.0-rc7-libre/drivers/ptp/ptp_clock.c
--- linux-2.6.39-libre/drivers/ptp/ptp_clock.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/ptp/ptp_clock.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,343 @@
+/*
+ * PTP 1588 clock support
+ *
+ * Copyright (C) 2010 OMICRON electronics GmbH
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the 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/bitops.h>
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/posix-clock.h>
+#include <linux/pps_kernel.h>
+#include <linux/slab.h>
+#include <linux/syscalls.h>
+#include <linux/uaccess.h>
+
+#include "ptp_private.h"
+
+#define PTP_MAX_ALARMS 4
+#define PTP_MAX_CLOCKS 8
+#define PTP_PPS_DEFAULTS (PPS_CAPTUREASSERT | PPS_OFFSETASSERT)
+#define PTP_PPS_EVENT PPS_CAPTUREASSERT
+#define PTP_PPS_MODE (PTP_PPS_DEFAULTS | PPS_CANWAIT | PPS_TSFMT_TSPEC)
+
+/* private globals */
+
+static dev_t ptp_devt;
+static struct class *ptp_class;
+
+static DECLARE_BITMAP(ptp_clocks_map, PTP_MAX_CLOCKS);
+static DEFINE_MUTEX(ptp_clocks_mutex); /* protects 'ptp_clocks_map' */
+
+/* time stamp event queue operations */
+
+static inline int queue_free(struct timestamp_event_queue *q)
+{
+	return PTP_MAX_TIMESTAMPS - queue_cnt(q) - 1;
+}
+
+static void enqueue_external_timestamp(struct timestamp_event_queue *queue,
+				       struct ptp_clock_event *src)
+{
+	struct ptp_extts_event *dst;
+	unsigned long flags;
+	s64 seconds;
+	u32 remainder;
+
+	seconds = div_u64_rem(src->timestamp, 1000000000, &remainder);
+
+	spin_lock_irqsave(&queue->lock, flags);
+
+	dst = &queue->buf[queue->tail];
+	dst->index = src->index;
+	dst->t.sec = seconds;
+	dst->t.nsec = remainder;
+
+	if (!queue_free(queue))
+		queue->head = (queue->head + 1) % PTP_MAX_TIMESTAMPS;
+
+	queue->tail = (queue->tail + 1) % PTP_MAX_TIMESTAMPS;
+
+	spin_unlock_irqrestore(&queue->lock, flags);
+}
+
+static s32 scaled_ppm_to_ppb(long ppm)
+{
+	/*
+	 * The 'freq' field in the 'struct timex' is in parts per
+	 * million, but with a 16 bit binary fractional field.
+	 *
+	 * We want to calculate
+	 *
+	 *    ppb = scaled_ppm * 1000 / 2^16
+	 *
+	 * which simplifies to
+	 *
+	 *    ppb = scaled_ppm * 125 / 2^13
+	 */
+	s64 ppb = 1 + ppm;
+	ppb *= 125;
+	ppb >>= 13;
+	return (s32) ppb;
+}
+
+/* posix clock implementation */
+
+static int ptp_clock_getres(struct posix_clock *pc, struct timespec *tp)
+{
+	return 1; /* always round timer functions to one nanosecond */
+}
+
+static int ptp_clock_settime(struct posix_clock *pc, const struct timespec *tp)
+{
+	struct ptp_clock *ptp = container_of(pc, struct ptp_clock, clock);
+	return ptp->info->settime(ptp->info, tp);
+}
+
+static int ptp_clock_gettime(struct posix_clock *pc, struct timespec *tp)
+{
+	struct ptp_clock *ptp = container_of(pc, struct ptp_clock, clock);
+	return ptp->info->gettime(ptp->info, tp);
+}
+
+static int ptp_clock_adjtime(struct posix_clock *pc, struct timex *tx)
+{
+	struct ptp_clock *ptp = container_of(pc, struct ptp_clock, clock);
+	struct ptp_clock_info *ops;
+	int err = -EOPNOTSUPP;
+
+	ops = ptp->info;
+
+	if (tx->modes & ADJ_SETOFFSET) {
+		struct timespec ts;
+		ktime_t kt;
+		s64 delta;
+
+		ts.tv_sec  = tx->time.tv_sec;
+		ts.tv_nsec = tx->time.tv_usec;
+
+		if (!(tx->modes & ADJ_NANO))
+			ts.tv_nsec *= 1000;
+
+		if ((unsigned long) ts.tv_nsec >= NSEC_PER_SEC)
+			return -EINVAL;
+
+		kt = timespec_to_ktime(ts);
+		delta = ktime_to_ns(kt);
+		err = ops->adjtime(ops, delta);
+
+	} else if (tx->modes & ADJ_FREQUENCY) {
+
+		err = ops->adjfreq(ops, scaled_ppm_to_ppb(tx->freq));
+	}
+
+	return err;
+}
+
+static struct posix_clock_operations ptp_clock_ops = {
+	.owner		= THIS_MODULE,
+	.clock_adjtime	= ptp_clock_adjtime,
+	.clock_gettime	= ptp_clock_gettime,
+	.clock_getres	= ptp_clock_getres,
+	.clock_settime	= ptp_clock_settime,
+	.ioctl		= ptp_ioctl,
+	.open		= ptp_open,
+	.poll		= ptp_poll,
+	.read		= ptp_read,
+};
+
+static void delete_ptp_clock(struct posix_clock *pc)
+{
+	struct ptp_clock *ptp = container_of(pc, struct ptp_clock, clock);
+
+	mutex_destroy(&ptp->tsevq_mux);
+
+	/* Remove the clock from the bit map. */
+	mutex_lock(&ptp_clocks_mutex);
+	clear_bit(ptp->index, ptp_clocks_map);
+	mutex_unlock(&ptp_clocks_mutex);
+
+	kfree(ptp);
+}
+
+/* public interface */
+
+struct ptp_clock *ptp_clock_register(struct ptp_clock_info *info)
+{
+	struct ptp_clock *ptp;
+	int err = 0, index, major = MAJOR(ptp_devt);
+
+	if (info->n_alarm > PTP_MAX_ALARMS)
+		return ERR_PTR(-EINVAL);
+
+	/* Find a free clock slot and reserve it. */
+	err = -EBUSY;
+	mutex_lock(&ptp_clocks_mutex);
+	index = find_first_zero_bit(ptp_clocks_map, PTP_MAX_CLOCKS);
+	if (index < PTP_MAX_CLOCKS)
+		set_bit(index, ptp_clocks_map);
+	else
+		goto no_slot;
+
+	/* Initialize a clock structure. */
+	err = -ENOMEM;
+	ptp = kzalloc(sizeof(struct ptp_clock), GFP_KERNEL);
+	if (ptp == NULL)
+		goto no_memory;
+
+	ptp->clock.ops = ptp_clock_ops;
+	ptp->clock.release = delete_ptp_clock;
+	ptp->info = info;
+	ptp->devid = MKDEV(major, index);
+	ptp->index = index;
+	spin_lock_init(&ptp->tsevq.lock);
+	mutex_init(&ptp->tsevq_mux);
+	init_waitqueue_head(&ptp->tsev_wq);
+
+	/* Create a new device in our class. */
+	ptp->dev = device_create(ptp_class, NULL, ptp->devid, ptp,
+				 "ptp%d", ptp->index);
+	if (IS_ERR(ptp->dev))
+		goto no_device;
+
+	dev_set_drvdata(ptp->dev, ptp);
+
+	err = ptp_populate_sysfs(ptp);
+	if (err)
+		goto no_sysfs;
+
+	/* Register a new PPS source. */
+	if (info->pps) {
+		struct pps_source_info pps;
+		memset(&pps, 0, sizeof(pps));
+		snprintf(pps.name, PPS_MAX_NAME_LEN, "ptp%d", index);
+		pps.mode = PTP_PPS_MODE;
+		pps.owner = info->owner;
+		ptp->pps_source = pps_register_source(&pps, PTP_PPS_DEFAULTS);
+		if (!ptp->pps_source) {
+			pr_err("failed to register pps source\n");
+			goto no_pps;
+		}
+	}
+
+	/* Create a posix clock. */
+	err = posix_clock_register(&ptp->clock, ptp->devid);
+	if (err) {
+		pr_err("failed to create posix clock\n");
+		goto no_clock;
+	}
+
+	mutex_unlock(&ptp_clocks_mutex);
+	return ptp;
+
+no_clock:
+	if (ptp->pps_source)
+		pps_unregister_source(ptp->pps_source);
+no_pps:
+	ptp_cleanup_sysfs(ptp);
+no_sysfs:
+	device_destroy(ptp_class, ptp->devid);
+no_device:
+	mutex_destroy(&ptp->tsevq_mux);
+	kfree(ptp);
+no_memory:
+	clear_bit(index, ptp_clocks_map);
+no_slot:
+	mutex_unlock(&ptp_clocks_mutex);
+	return ERR_PTR(err);
+}
+EXPORT_SYMBOL(ptp_clock_register);
+
+int ptp_clock_unregister(struct ptp_clock *ptp)
+{
+	ptp->defunct = 1;
+	wake_up_interruptible(&ptp->tsev_wq);
+
+	/* Release the clock's resources. */
+	if (ptp->pps_source)
+		pps_unregister_source(ptp->pps_source);
+	ptp_cleanup_sysfs(ptp);
+	device_destroy(ptp_class, ptp->devid);
+
+	posix_clock_unregister(&ptp->clock);
+	return 0;
+}
+EXPORT_SYMBOL(ptp_clock_unregister);
+
+void ptp_clock_event(struct ptp_clock *ptp, struct ptp_clock_event *event)
+{
+	struct pps_event_time evt;
+
+	switch (event->type) {
+
+	case PTP_CLOCK_ALARM:
+		break;
+
+	case PTP_CLOCK_EXTTS:
+		enqueue_external_timestamp(&ptp->tsevq, event);
+		wake_up_interruptible(&ptp->tsev_wq);
+		break;
+
+	case PTP_CLOCK_PPS:
+		pps_get_ts(&evt);
+		pps_event(ptp->pps_source, &evt, PTP_PPS_EVENT, NULL);
+		break;
+	}
+}
+EXPORT_SYMBOL(ptp_clock_event);
+
+/* module operations */
+
+static void __exit ptp_exit(void)
+{
+	class_destroy(ptp_class);
+	unregister_chrdev_region(ptp_devt, PTP_MAX_CLOCKS);
+}
+
+static int __init ptp_init(void)
+{
+	int err;
+
+	ptp_class = class_create(THIS_MODULE, "ptp");
+	if (IS_ERR(ptp_class)) {
+		pr_err("ptp: failed to allocate class\n");
+		return PTR_ERR(ptp_class);
+	}
+
+	err = alloc_chrdev_region(&ptp_devt, 0, PTP_MAX_CLOCKS, "ptp");
+	if (err < 0) {
+		pr_err("ptp: failed to allocate device region\n");
+		goto no_region;
+	}
+
+	ptp_class->dev_attrs = ptp_dev_attrs;
+	pr_info("PTP clock support registered\n");
+	return 0;
+
+no_region:
+	class_destroy(ptp_class);
+	return err;
+}
+
+subsys_initcall(ptp_init);
+module_exit(ptp_exit);
+
+MODULE_AUTHOR("Richard Cochran <richard.cochran@omicron.at>");
+MODULE_DESCRIPTION("PTP clocks support");
+MODULE_LICENSE("GPL");
diff -druN linux-2.6.39-libre/drivers/ptp/ptp_ixp46x.c linux-3.0-rc7-libre/drivers/ptp/ptp_ixp46x.c
--- linux-2.6.39-libre/drivers/ptp/ptp_ixp46x.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/ptp/ptp_ixp46x.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,332 @@
+/*
+ * PTP 1588 clock using the IXP46X
+ *
+ * Copyright (C) 2010 OMICRON electronics GmbH
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/gpio.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+
+#include <linux/ptp_clock_kernel.h>
+#include <mach/ixp46x_ts.h>
+
+#define DRIVER		"ptp_ixp46x"
+#define N_EXT_TS	2
+#define MASTER_GPIO	8
+#define MASTER_IRQ	25
+#define SLAVE_GPIO	7
+#define SLAVE_IRQ	24
+
+struct ixp_clock {
+	struct ixp46x_ts_regs *regs;
+	struct ptp_clock *ptp_clock;
+	struct ptp_clock_info caps;
+	int exts0_enabled;
+	int exts1_enabled;
+};
+
+DEFINE_SPINLOCK(register_lock);
+
+/*
+ * Register access functions
+ */
+
+static u64 ixp_systime_read(struct ixp46x_ts_regs *regs)
+{
+	u64 ns;
+	u32 lo, hi;
+
+	lo = __raw_readl(&regs->systime_lo);
+	hi = __raw_readl(&regs->systime_hi);
+
+	ns = ((u64) hi) << 32;
+	ns |= lo;
+	ns <<= TICKS_NS_SHIFT;
+
+	return ns;
+}
+
+static void ixp_systime_write(struct ixp46x_ts_regs *regs, u64 ns)
+{
+	u32 hi, lo;
+
+	ns >>= TICKS_NS_SHIFT;
+	hi = ns >> 32;
+	lo = ns & 0xffffffff;
+
+	__raw_writel(lo, &regs->systime_lo);
+	__raw_writel(hi, &regs->systime_hi);
+}
+
+/*
+ * Interrupt service routine
+ */
+
+static irqreturn_t isr(int irq, void *priv)
+{
+	struct ixp_clock *ixp_clock = priv;
+	struct ixp46x_ts_regs *regs = ixp_clock->regs;
+	struct ptp_clock_event event;
+	u32 ack = 0, lo, hi, val;
+
+	val = __raw_readl(&regs->event);
+
+	if (val & TSER_SNS) {
+		ack |= TSER_SNS;
+		if (ixp_clock->exts0_enabled) {
+			hi = __raw_readl(&regs->asms_hi);
+			lo = __raw_readl(&regs->asms_lo);
+			event.type = PTP_CLOCK_EXTTS;
+			event.index = 0;
+			event.timestamp = ((u64) hi) << 32;
+			event.timestamp |= lo;
+			event.timestamp <<= TICKS_NS_SHIFT;
+			ptp_clock_event(ixp_clock->ptp_clock, &event);
+		}
+	}
+
+	if (val & TSER_SNM) {
+		ack |= TSER_SNM;
+		if (ixp_clock->exts1_enabled) {
+			hi = __raw_readl(&regs->amms_hi);
+			lo = __raw_readl(&regs->amms_lo);
+			event.type = PTP_CLOCK_EXTTS;
+			event.index = 1;
+			event.timestamp = ((u64) hi) << 32;
+			event.timestamp |= lo;
+			event.timestamp <<= TICKS_NS_SHIFT;
+			ptp_clock_event(ixp_clock->ptp_clock, &event);
+		}
+	}
+
+	if (val & TTIPEND)
+		ack |= TTIPEND; /* this bit seems to be always set */
+
+	if (ack) {
+		__raw_writel(ack, &regs->event);
+		return IRQ_HANDLED;
+	} else
+		return IRQ_NONE;
+}
+
+/*
+ * PTP clock operations
+ */
+
+static int ptp_ixp_adjfreq(struct ptp_clock_info *ptp, s32 ppb)
+{
+	u64 adj;
+	u32 diff, addend;
+	int neg_adj = 0;
+	struct ixp_clock *ixp_clock = container_of(ptp, struct ixp_clock, caps);
+	struct ixp46x_ts_regs *regs = ixp_clock->regs;
+
+	if (ppb < 0) {
+		neg_adj = 1;
+		ppb = -ppb;
+	}
+	addend = DEFAULT_ADDEND;
+	adj = addend;
+	adj *= ppb;
+	diff = div_u64(adj, 1000000000ULL);
+
+	addend = neg_adj ? addend - diff : addend + diff;
+
+	__raw_writel(addend, &regs->addend);
+
+	return 0;
+}
+
+static int ptp_ixp_adjtime(struct ptp_clock_info *ptp, s64 delta)
+{
+	s64 now;
+	unsigned long flags;
+	struct ixp_clock *ixp_clock = container_of(ptp, struct ixp_clock, caps);
+	struct ixp46x_ts_regs *regs = ixp_clock->regs;
+
+	spin_lock_irqsave(&register_lock, flags);
+
+	now = ixp_systime_read(regs);
+	now += delta;
+	ixp_systime_write(regs, now);
+
+	spin_unlock_irqrestore(&register_lock, flags);
+
+	return 0;
+}
+
+static int ptp_ixp_gettime(struct ptp_clock_info *ptp, struct timespec *ts)
+{
+	u64 ns;
+	u32 remainder;
+	unsigned long flags;
+	struct ixp_clock *ixp_clock = container_of(ptp, struct ixp_clock, caps);
+	struct ixp46x_ts_regs *regs = ixp_clock->regs;
+
+	spin_lock_irqsave(&register_lock, flags);
+
+	ns = ixp_systime_read(regs);
+
+	spin_unlock_irqrestore(&register_lock, flags);
+
+	ts->tv_sec = div_u64_rem(ns, 1000000000, &remainder);
+	ts->tv_nsec = remainder;
+	return 0;
+}
+
+static int ptp_ixp_settime(struct ptp_clock_info *ptp,
+			   const struct timespec *ts)
+{
+	u64 ns;
+	unsigned long flags;
+	struct ixp_clock *ixp_clock = container_of(ptp, struct ixp_clock, caps);
+	struct ixp46x_ts_regs *regs = ixp_clock->regs;
+
+	ns = ts->tv_sec * 1000000000ULL;
+	ns += ts->tv_nsec;
+
+	spin_lock_irqsave(&register_lock, flags);
+
+	ixp_systime_write(regs, ns);
+
+	spin_unlock_irqrestore(&register_lock, flags);
+
+	return 0;
+}
+
+static int ptp_ixp_enable(struct ptp_clock_info *ptp,
+			  struct ptp_clock_request *rq, int on)
+{
+	struct ixp_clock *ixp_clock = container_of(ptp, struct ixp_clock, caps);
+
+	switch (rq->type) {
+	case PTP_CLK_REQ_EXTTS:
+		switch (rq->extts.index) {
+		case 0:
+			ixp_clock->exts0_enabled = on ? 1 : 0;
+			break;
+		case 1:
+			ixp_clock->exts1_enabled = on ? 1 : 0;
+			break;
+		default:
+			return -EINVAL;
+		}
+		return 0;
+	default:
+		break;
+	}
+
+	return -EOPNOTSUPP;
+}
+
+static struct ptp_clock_info ptp_ixp_caps = {
+	.owner		= THIS_MODULE,
+	.name		= "IXP46X timer",
+	.max_adj	= 66666655,
+	.n_ext_ts	= N_EXT_TS,
+	.pps		= 0,
+	.adjfreq	= ptp_ixp_adjfreq,
+	.adjtime	= ptp_ixp_adjtime,
+	.gettime	= ptp_ixp_gettime,
+	.settime	= ptp_ixp_settime,
+	.enable		= ptp_ixp_enable,
+};
+
+/* module operations */
+
+static struct ixp_clock ixp_clock;
+
+static int setup_interrupt(int gpio)
+{
+	int irq;
+
+	gpio_line_config(gpio, IXP4XX_GPIO_IN);
+
+	irq = gpio_to_irq(gpio);
+
+	if (NO_IRQ == irq)
+		return NO_IRQ;
+
+	if (irq_set_irq_type(irq, IRQF_TRIGGER_FALLING)) {
+		pr_err("cannot set trigger type for irq %d\n", irq);
+		return NO_IRQ;
+	}
+
+	if (request_irq(irq, isr, 0, DRIVER, &ixp_clock)) {
+		pr_err("request_irq failed for irq %d\n", irq);
+		return NO_IRQ;
+	}
+
+	return irq;
+}
+
+static void __exit ptp_ixp_exit(void)
+{
+	free_irq(MASTER_IRQ, &ixp_clock);
+	free_irq(SLAVE_IRQ, &ixp_clock);
+	ptp_clock_unregister(ixp_clock.ptp_clock);
+}
+
+static int __init ptp_ixp_init(void)
+{
+	if (!cpu_is_ixp46x())
+		return -ENODEV;
+
+	ixp_clock.regs =
+		(struct ixp46x_ts_regs __iomem *) IXP4XX_TIMESYNC_BASE_VIRT;
+
+	ixp_clock.caps = ptp_ixp_caps;
+
+	ixp_clock.ptp_clock = ptp_clock_register(&ixp_clock.caps);
+
+	if (IS_ERR(ixp_clock.ptp_clock))
+		return PTR_ERR(ixp_clock.ptp_clock);
+
+	__raw_writel(DEFAULT_ADDEND, &ixp_clock.regs->addend);
+	__raw_writel(1, &ixp_clock.regs->trgt_lo);
+	__raw_writel(0, &ixp_clock.regs->trgt_hi);
+	__raw_writel(TTIPEND, &ixp_clock.regs->event);
+
+	if (MASTER_IRQ != setup_interrupt(MASTER_GPIO)) {
+		pr_err("failed to setup gpio %d as irq\n", MASTER_GPIO);
+		goto no_master;
+	}
+	if (SLAVE_IRQ != setup_interrupt(SLAVE_GPIO)) {
+		pr_err("failed to setup gpio %d as irq\n", SLAVE_GPIO);
+		goto no_slave;
+	}
+
+	return 0;
+no_slave:
+	free_irq(MASTER_IRQ, &ixp_clock);
+no_master:
+	ptp_clock_unregister(ixp_clock.ptp_clock);
+	return -ENODEV;
+}
+
+module_init(ptp_ixp_init);
+module_exit(ptp_ixp_exit);
+
+MODULE_AUTHOR("Richard Cochran <richard.cochran@omicron.at>");
+MODULE_DESCRIPTION("PTP clock using the IXP46X timer");
+MODULE_LICENSE("GPL");
diff -druN linux-2.6.39-libre/drivers/ptp/ptp_private.h linux-3.0-rc7-libre/drivers/ptp/ptp_private.h
--- linux-2.6.39-libre/drivers/ptp/ptp_private.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/ptp/ptp_private.h	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,92 @@
+/*
+ * PTP 1588 clock support - private declarations for the core module.
+ *
+ * Copyright (C) 2010 OMICRON electronics GmbH
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the 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 _PTP_PRIVATE_H_
+#define _PTP_PRIVATE_H_
+
+#include <linux/cdev.h>
+#include <linux/device.h>
+#include <linux/mutex.h>
+#include <linux/posix-clock.h>
+#include <linux/ptp_clock.h>
+#include <linux/ptp_clock_kernel.h>
+#include <linux/time.h>
+
+#define PTP_MAX_TIMESTAMPS 128
+#define PTP_BUF_TIMESTAMPS 30
+
+struct timestamp_event_queue {
+	struct ptp_extts_event buf[PTP_MAX_TIMESTAMPS];
+	int head;
+	int tail;
+	spinlock_t lock;
+};
+
+struct ptp_clock {
+	struct posix_clock clock;
+	struct device *dev;
+	struct ptp_clock_info *info;
+	dev_t devid;
+	int index; /* index into clocks.map */
+	struct pps_device *pps_source;
+	struct timestamp_event_queue tsevq; /* simple fifo for time stamps */
+	struct mutex tsevq_mux; /* one process at a time reading the fifo */
+	wait_queue_head_t tsev_wq;
+	int defunct; /* tells readers to go away when clock is being removed */
+};
+
+/*
+ * The function queue_cnt() is safe for readers to call without
+ * holding q->lock. Readers use this function to verify that the queue
+ * is nonempty before proceeding with a dequeue operation. The fact
+ * that a writer might concurrently increment the tail does not
+ * matter, since the queue remains nonempty nonetheless.
+ */
+static inline int queue_cnt(struct timestamp_event_queue *q)
+{
+	int cnt = q->tail - q->head;
+	return cnt < 0 ? PTP_MAX_TIMESTAMPS + cnt : cnt;
+}
+
+/*
+ * see ptp_chardev.c
+ */
+
+long ptp_ioctl(struct posix_clock *pc,
+	       unsigned int cmd, unsigned long arg);
+
+int ptp_open(struct posix_clock *pc, fmode_t fmode);
+
+ssize_t ptp_read(struct posix_clock *pc,
+		 uint flags, char __user *buf, size_t cnt);
+
+uint ptp_poll(struct posix_clock *pc,
+	      struct file *fp, poll_table *wait);
+
+/*
+ * see ptp_sysfs.c
+ */
+
+extern struct device_attribute ptp_dev_attrs[];
+
+int ptp_cleanup_sysfs(struct ptp_clock *ptp);
+
+int ptp_populate_sysfs(struct ptp_clock *ptp);
+
+#endif
diff -druN linux-2.6.39-libre/drivers/ptp/ptp_sysfs.c linux-3.0-rc7-libre/drivers/ptp/ptp_sysfs.c
--- linux-2.6.39-libre/drivers/ptp/ptp_sysfs.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/ptp/ptp_sysfs.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,230 @@
+/*
+ * PTP 1588 clock support - sysfs interface.
+ *
+ * Copyright (C) 2010 OMICRON electronics GmbH
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the 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/capability.h>
+
+#include "ptp_private.h"
+
+static ssize_t clock_name_show(struct device *dev,
+			       struct device_attribute *attr, char *page)
+{
+	struct ptp_clock *ptp = dev_get_drvdata(dev);
+	return snprintf(page, PAGE_SIZE-1, "%s\n", ptp->info->name);
+}
+
+#define PTP_SHOW_INT(name)						\
+static ssize_t name##_show(struct device *dev,				\
+			   struct device_attribute *attr, char *page)	\
+{									\
+	struct ptp_clock *ptp = dev_get_drvdata(dev);			\
+	return snprintf(page, PAGE_SIZE-1, "%d\n", ptp->info->name);	\
+}
+
+PTP_SHOW_INT(max_adj);
+PTP_SHOW_INT(n_alarm);
+PTP_SHOW_INT(n_ext_ts);
+PTP_SHOW_INT(n_per_out);
+PTP_SHOW_INT(pps);
+
+#define PTP_RO_ATTR(_var, _name) {				\
+	.attr	= { .name = __stringify(_name), .mode = 0444 },	\
+	.show	= _var##_show,					\
+}
+
+struct device_attribute ptp_dev_attrs[] = {
+	PTP_RO_ATTR(clock_name,	clock_name),
+	PTP_RO_ATTR(max_adj,	max_adjustment),
+	PTP_RO_ATTR(n_alarm,	n_alarms),
+	PTP_RO_ATTR(n_ext_ts,	n_external_timestamps),
+	PTP_RO_ATTR(n_per_out,	n_periodic_outputs),
+	PTP_RO_ATTR(pps,	pps_available),
+	__ATTR_NULL,
+};
+
+static ssize_t extts_enable_store(struct device *dev,
+				  struct device_attribute *attr,
+				  const char *buf, size_t count)
+{
+	struct ptp_clock *ptp = dev_get_drvdata(dev);
+	struct ptp_clock_info *ops = ptp->info;
+	struct ptp_clock_request req = { .type = PTP_CLK_REQ_EXTTS };
+	int cnt, enable;
+	int err = -EINVAL;
+
+	cnt = sscanf(buf, "%u %d", &req.extts.index, &enable);
+	if (cnt != 2)
+		goto out;
+	if (req.extts.index >= ops->n_ext_ts)
+		goto out;
+
+	err = ops->enable(ops, &req, enable ? 1 : 0);
+	if (err)
+		goto out;
+
+	return count;
+out:
+	return err;
+}
+
+static ssize_t extts_fifo_show(struct device *dev,
+			       struct device_attribute *attr, char *page)
+{
+	struct ptp_clock *ptp = dev_get_drvdata(dev);
+	struct timestamp_event_queue *queue = &ptp->tsevq;
+	struct ptp_extts_event event;
+	unsigned long flags;
+	size_t qcnt;
+	int cnt = 0;
+
+	memset(&event, 0, sizeof(event));
+
+	if (mutex_lock_interruptible(&ptp->tsevq_mux))
+		return -ERESTARTSYS;
+
+	spin_lock_irqsave(&queue->lock, flags);
+	qcnt = queue_cnt(queue);
+	if (qcnt) {
+		event = queue->buf[queue->head];
+		queue->head = (queue->head + 1) % PTP_MAX_TIMESTAMPS;
+	}
+	spin_unlock_irqrestore(&queue->lock, flags);
+
+	if (!qcnt)
+		goto out;
+
+	cnt = snprintf(page, PAGE_SIZE, "%u %lld %u\n",
+		       event.index, event.t.sec, event.t.nsec);
+out:
+	mutex_unlock(&ptp->tsevq_mux);
+	return cnt;
+}
+
+static ssize_t period_store(struct device *dev,
+			    struct device_attribute *attr,
+			    const char *buf, size_t count)
+{
+	struct ptp_clock *ptp = dev_get_drvdata(dev);
+	struct ptp_clock_info *ops = ptp->info;
+	struct ptp_clock_request req = { .type = PTP_CLK_REQ_PEROUT };
+	int cnt, enable, err = -EINVAL;
+
+	cnt = sscanf(buf, "%u %lld %u %lld %u", &req.perout.index,
+		     &req.perout.start.sec, &req.perout.start.nsec,
+		     &req.perout.period.sec, &req.perout.period.nsec);
+	if (cnt != 5)
+		goto out;
+	if (req.perout.index >= ops->n_per_out)
+		goto out;
+
+	enable = req.perout.period.sec || req.perout.period.nsec;
+	err = ops->enable(ops, &req, enable);
+	if (err)
+		goto out;
+
+	return count;
+out:
+	return err;
+}
+
+static ssize_t pps_enable_store(struct device *dev,
+				struct device_attribute *attr,
+				const char *buf, size_t count)
+{
+	struct ptp_clock *ptp = dev_get_drvdata(dev);
+	struct ptp_clock_info *ops = ptp->info;
+	struct ptp_clock_request req = { .type = PTP_CLK_REQ_PPS };
+	int cnt, enable;
+	int err = -EINVAL;
+
+	if (!capable(CAP_SYS_TIME))
+		return -EPERM;
+
+	cnt = sscanf(buf, "%d", &enable);
+	if (cnt != 1)
+		goto out;
+
+	err = ops->enable(ops, &req, enable ? 1 : 0);
+	if (err)
+		goto out;
+
+	return count;
+out:
+	return err;
+}
+
+static DEVICE_ATTR(extts_enable, 0220, NULL, extts_enable_store);
+static DEVICE_ATTR(fifo,         0444, extts_fifo_show, NULL);
+static DEVICE_ATTR(period,       0220, NULL, period_store);
+static DEVICE_ATTR(pps_enable,   0220, NULL, pps_enable_store);
+
+int ptp_cleanup_sysfs(struct ptp_clock *ptp)
+{
+	struct device *dev = ptp->dev;
+	struct ptp_clock_info *info = ptp->info;
+
+	if (info->n_ext_ts) {
+		device_remove_file(dev, &dev_attr_extts_enable);
+		device_remove_file(dev, &dev_attr_fifo);
+	}
+	if (info->n_per_out)
+		device_remove_file(dev, &dev_attr_period);
+
+	if (info->pps)
+		device_remove_file(dev, &dev_attr_pps_enable);
+
+	return 0;
+}
+
+int ptp_populate_sysfs(struct ptp_clock *ptp)
+{
+	struct device *dev = ptp->dev;
+	struct ptp_clock_info *info = ptp->info;
+	int err;
+
+	if (info->n_ext_ts) {
+		err = device_create_file(dev, &dev_attr_extts_enable);
+		if (err)
+			goto out1;
+		err = device_create_file(dev, &dev_attr_fifo);
+		if (err)
+			goto out2;
+	}
+	if (info->n_per_out) {
+		err = device_create_file(dev, &dev_attr_period);
+		if (err)
+			goto out3;
+	}
+	if (info->pps) {
+		err = device_create_file(dev, &dev_attr_pps_enable);
+		if (err)
+			goto out4;
+	}
+	return 0;
+out4:
+	if (info->n_per_out)
+		device_remove_file(dev, &dev_attr_period);
+out3:
+	if (info->n_ext_ts)
+		device_remove_file(dev, &dev_attr_fifo);
+out2:
+	if (info->n_ext_ts)
+		device_remove_file(dev, &dev_attr_extts_enable);
+out1:
+	return err;
+}
diff -druN linux-2.6.39-libre/drivers/regulator/88pm8607.c linux-3.0-rc7-libre/drivers/regulator/88pm8607.c
--- linux-2.6.39-libre/drivers/regulator/88pm8607.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/regulator/88pm8607.c	2011-07-11 19:51:52.000000000 -0400
@@ -15,7 +15,6 @@
 #include <linux/platform_device.h>
 #include <linux/regulator/driver.h>
 #include <linux/regulator/machine.h>
-#include <linux/mfd/core.h>
 #include <linux/mfd/88pm860x.h>
 
 struct pm8607_regulator_info {
@@ -399,36 +398,33 @@
 {
 	struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent);
 	struct pm8607_regulator_info *info = NULL;
-	struct regulator_init_data *pdata;
-	struct mfd_cell *cell;
+	struct regulator_init_data *pdata = pdev->dev.platform_data;
+	struct resource *res;
 	int i;
 
-	cell = pdev->dev.platform_data;
-	if (cell == NULL)
-		return -ENODEV;
-	pdata = cell->mfd_data;
-	if (pdata == NULL)
+	res = platform_get_resource(pdev, IORESOURCE_IO, 0);
+	if (res == NULL) {
+		dev_err(&pdev->dev, "No I/O resource!\n");
 		return -EINVAL;
-
+	}
 	for (i = 0; i < ARRAY_SIZE(pm8607_regulator_info); i++) {
 		info = &pm8607_regulator_info[i];
-		if (!strcmp(info->desc.name, pdata->constraints.name))
+		if (info->desc.id == res->start)
 			break;
 	}
-	if (i > ARRAY_SIZE(pm8607_regulator_info)) {
-		dev_err(&pdev->dev, "Failed to find regulator %s\n",
-			pdata->constraints.name);
+	if ((i < 0) || (i > PM8607_ID_RG_MAX)) {
+		dev_err(&pdev->dev, "Failed to find regulator %llu\n",
+			(unsigned long long)res->start);
 		return -EINVAL;
 	}
-
 	info->i2c = (chip->id == CHIP_PM8607) ? chip->client : chip->companion;
 	info->chip = chip;
 
 	/* check DVC ramp slope double */
-	if (!strcmp(info->desc.name, "BUCK3"))
-		if (info->chip->buck3_double)
-			info->slope_double = 1;
+	if ((i == PM8607_ID_BUCK3) && info->chip->buck3_double)
+		info->slope_double = 1;
 
+	/* replace driver_data with info */
 	info->regulator = regulator_register(&info->desc, &pdev->dev,
 					     pdata, info);
 	if (IS_ERR(info->regulator)) {
diff -druN linux-2.6.39-libre/drivers/regulator/ab3100.c linux-3.0-rc7-libre/drivers/regulator/ab3100.c
--- linux-2.6.39-libre/drivers/regulator/ab3100.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/regulator/ab3100.c	2011-07-11 19:51:52.000000000 -0400
@@ -17,7 +17,6 @@
 #include <linux/platform_device.h>
 #include <linux/regulator/driver.h>
 #include <linux/mfd/abx500.h>
-#include <linux/mfd/core.h>
 
 /* LDO registers and some handy masking definitions for AB3100 */
 #define AB3100_LDO_A		0x40
@@ -582,7 +581,7 @@
 
 static int __devinit ab3100_regulators_probe(struct platform_device *pdev)
 {
-	struct ab3100_platform_data *plfdata = mfd_get_data(pdev);
+	struct ab3100_platform_data *plfdata = pdev->dev.platform_data;
 	int err = 0;
 	u8 data;
 	int i;
diff -druN linux-2.6.39-libre/drivers/regulator/core.c linux-3.0-rc7-libre/drivers/regulator/core.c
--- linux-2.6.39-libre/drivers/regulator/core.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/regulator/core.c	2011-07-11 19:51:52.000000000 -0400
@@ -158,6 +158,13 @@
 	struct regulator *regulator;
 
 	list_for_each_entry(regulator, &rdev->consumer_list, list) {
+		/*
+		 * Assume consumers that didn't say anything are OK
+		 * with anything in the constraint range.
+		 */
+		if (!regulator->min_uV && !regulator->max_uV)
+			continue;
+
 		if (*max_uV > regulator->max_uV)
 			*max_uV = regulator->max_uV;
 		if (*min_uV < regulator->min_uV)
@@ -197,9 +204,9 @@
 }
 
 /* operating mode constraint check */
-static int regulator_check_mode(struct regulator_dev *rdev, int mode)
+static int regulator_mode_constrain(struct regulator_dev *rdev, int *mode)
 {
-	switch (mode) {
+	switch (*mode) {
 	case REGULATOR_MODE_FAST:
 	case REGULATOR_MODE_NORMAL:
 	case REGULATOR_MODE_IDLE:
@@ -217,11 +224,17 @@
 		rdev_err(rdev, "operation not allowed\n");
 		return -EPERM;
 	}
-	if (!(rdev->constraints->valid_modes_mask & mode)) {
-		rdev_err(rdev, "invalid mode %x\n", mode);
-		return -EINVAL;
+
+	/* The modes are bitmasks, the most power hungry modes having
+	 * the lowest values. If the requested mode isn't supported
+	 * try higher modes. */
+	while (*mode) {
+		if (rdev->constraints->valid_modes_mask & *mode)
+			return 0;
+		*mode /= 2;
 	}
-	return 0;
+
+	return -EINVAL;
 }
 
 /* dynamic regulator mode switching constraint check */
@@ -612,7 +625,7 @@
 						  output_uV, current_uA);
 
 	/* check the new mode is allowed */
-	err = regulator_check_mode(rdev, mode);
+	err = regulator_mode_constrain(rdev, &mode);
 	if (err == 0)
 		rdev->desc->ops->set_mode(rdev, mode);
 }
@@ -718,6 +731,10 @@
 			count += sprintf(buf + count, "at %d mV ", ret / 1000);
 	}
 
+	if (constraints->uV_offset)
+		count += sprintf(buf, "%dmV offset ",
+				 constraints->uV_offset / 1000);
+
 	if (constraints->min_uA && constraints->max_uA) {
 		if (constraints->min_uA == constraints->max_uA)
 			count += sprintf(buf + count, "%d mA ",
@@ -1498,13 +1515,14 @@
  */
 int regulator_force_disable(struct regulator *regulator)
 {
+	struct regulator_dev *rdev = regulator->rdev;
 	struct regulator_dev *supply_rdev = NULL;
 	int ret;
 
-	mutex_lock(&regulator->rdev->mutex);
+	mutex_lock(&rdev->mutex);
 	regulator->uA_load = 0;
-	ret = _regulator_force_disable(regulator->rdev, &supply_rdev);
-	mutex_unlock(&regulator->rdev->mutex);
+	ret = _regulator_force_disable(rdev, &supply_rdev);
+	mutex_unlock(&rdev->mutex);
 
 	if (supply_rdev)
 		regulator_disable(get_device_regulator(rdev_get_dev(supply_rdev)));
@@ -1634,6 +1652,9 @@
 
 	trace_regulator_set_voltage(rdev_get_name(rdev), min_uV, max_uV);
 
+	min_uV += rdev->constraints->uV_offset;
+	max_uV += rdev->constraints->uV_offset;
+
 	if (rdev->desc->ops->set_voltage) {
 		ret = rdev->desc->ops->set_voltage(rdev, min_uV, max_uV,
 						   &selector);
@@ -1858,18 +1879,22 @@
 
 static int _regulator_get_voltage(struct regulator_dev *rdev)
 {
-	int sel;
+	int sel, ret;
 
 	if (rdev->desc->ops->get_voltage_sel) {
 		sel = rdev->desc->ops->get_voltage_sel(rdev);
 		if (sel < 0)
 			return sel;
-		return rdev->desc->ops->list_voltage(rdev, sel);
-	}
-	if (rdev->desc->ops->get_voltage)
-		return rdev->desc->ops->get_voltage(rdev);
-	else
+		ret = rdev->desc->ops->list_voltage(rdev, sel);
+	} else if (rdev->desc->ops->get_voltage) {
+		ret = rdev->desc->ops->get_voltage(rdev);
+	} else {
 		return -EINVAL;
+	}
+
+	if (ret < 0)
+		return ret;
+	return ret - rdev->constraints->uV_offset;
 }
 
 /**
@@ -2005,7 +2030,7 @@
 	}
 
 	/* constraints check */
-	ret = regulator_check_mode(rdev, mode);
+	ret = regulator_mode_constrain(rdev, &mode);
 	if (ret < 0)
 		goto out;
 
@@ -2081,16 +2106,26 @@
 
 	mutex_lock(&rdev->mutex);
 
+	/*
+	 * first check to see if we can set modes at all, otherwise just
+	 * tell the consumer everything is OK.
+	 */
 	regulator->uA_load = uA_load;
 	ret = regulator_check_drms(rdev);
-	if (ret < 0)
+	if (ret < 0) {
+		ret = 0;
 		goto out;
-	ret = -EINVAL;
+	}
 
-	/* sanity check */
 	if (!rdev->desc->ops->get_optimum_mode)
 		goto out;
 
+	/*
+	 * we can actually do this so any errors are indicators of
+	 * potential real failure.
+	 */
+	ret = -EINVAL;
+
 	/* get output voltage */
 	output_uV = _regulator_get_voltage(rdev);
 	if (output_uV <= 0) {
@@ -2116,7 +2151,7 @@
 	mode = rdev->desc->ops->get_optimum_mode(rdev,
 						 input_uV, output_uV,
 						 total_uA_load);
-	ret = regulator_check_mode(rdev, mode);
+	ret = regulator_mode_constrain(rdev, &mode);
 	if (ret < 0) {
 		rdev_err(rdev, "failed to get optimum mode @ %d uA %d -> %d uV\n",
 			 total_uA_load, input_uV, output_uV);
@@ -2589,14 +2624,6 @@
 	if (ret < 0)
 		goto scrub;
 
-	/* set supply regulator if it exists */
-	if (init_data->supply_regulator && init_data->supply_regulator_dev) {
-		dev_err(dev,
-			"Supply regulator specified by both name and dev\n");
-		ret = -EINVAL;
-		goto scrub;
-	}
-
 	if (init_data->supply_regulator) {
 		struct regulator_dev *r;
 		int found = 0;
@@ -2621,14 +2648,6 @@
 			goto scrub;
 	}
 
-	if (init_data->supply_regulator_dev) {
-		dev_warn(dev, "Uses supply_regulator_dev instead of regulator_supply\n");
-		ret = set_supply(rdev,
-			dev_get_drvdata(init_data->supply_regulator_dev));
-		if (ret < 0)
-			goto scrub;
-	}
-
 	/* add consumers devices */
 	for (i = 0; i < init_data->num_consumer_supplies; i++) {
 		ret = set_consumer_device_supply(rdev,
diff -druN linux-2.6.39-libre/drivers/regulator/db8500-prcmu.c linux-3.0-rc7-libre/drivers/regulator/db8500-prcmu.c
--- linux-2.6.39-libre/drivers/regulator/db8500-prcmu.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/regulator/db8500-prcmu.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,550 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2010
+ *
+ * License Terms: GNU General Public License v2
+ * Authors: Sundar Iyer <sundar.iyer@stericsson.com> for ST-Ericsson
+ *          Bengt Jonsson <bengt.g.jonsson@stericsson.com> for ST-Ericsson
+ *
+ * Power domain regulators on DB8500
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/err.h>
+#include <linux/spinlock.h>
+#include <linux/platform_device.h>
+#include <linux/mfd/db8500-prcmu.h>
+#include <linux/regulator/driver.h>
+#include <linux/regulator/machine.h>
+#include <linux/regulator/db8500-prcmu.h>
+
+/*
+ * power state reference count
+ */
+static int power_state_active_cnt; /* will initialize to zero */
+static DEFINE_SPINLOCK(power_state_active_lock);
+
+static void power_state_active_enable(void)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&power_state_active_lock, flags);
+	power_state_active_cnt++;
+	spin_unlock_irqrestore(&power_state_active_lock, flags);
+}
+
+static int power_state_active_disable(void)
+{
+	int ret = 0;
+	unsigned long flags;
+
+	spin_lock_irqsave(&power_state_active_lock, flags);
+	if (power_state_active_cnt <= 0) {
+		pr_err("power state: unbalanced enable/disable calls\n");
+		ret = -EINVAL;
+		goto out;
+	}
+
+	power_state_active_cnt--;
+out:
+	spin_unlock_irqrestore(&power_state_active_lock, flags);
+	return ret;
+}
+
+/*
+ * Exported interface for CPUIdle only. This function is called when interrupts
+ * are turned off. Hence, no locking.
+ */
+int power_state_active_is_enabled(void)
+{
+	return (power_state_active_cnt > 0);
+}
+
+/**
+ * struct db8500_regulator_info - db8500 regulator information
+ * @dev: device pointer
+ * @desc: regulator description
+ * @rdev: regulator device pointer
+ * @is_enabled: status of the regulator
+ * @epod_id: id for EPOD (power domain)
+ * @is_ramret: RAM retention switch for EPOD (power domain)
+ * @operating_point: operating point (only for vape, to be removed)
+ *
+ */
+struct db8500_regulator_info {
+	struct device *dev;
+	struct regulator_desc desc;
+	struct regulator_dev *rdev;
+	bool is_enabled;
+	u16 epod_id;
+	bool is_ramret;
+	bool exclude_from_power_state;
+	unsigned int operating_point;
+};
+
+static int db8500_regulator_enable(struct regulator_dev *rdev)
+{
+	struct db8500_regulator_info *info = rdev_get_drvdata(rdev);
+
+	if (info == NULL)
+		return -EINVAL;
+
+	dev_vdbg(rdev_get_dev(rdev), "regulator-%s-enable\n",
+		info->desc.name);
+
+	info->is_enabled = true;
+	if (!info->exclude_from_power_state)
+		power_state_active_enable();
+
+	return 0;
+}
+
+static int db8500_regulator_disable(struct regulator_dev *rdev)
+{
+	struct db8500_regulator_info *info = rdev_get_drvdata(rdev);
+	int ret = 0;
+
+	if (info == NULL)
+		return -EINVAL;
+
+	dev_vdbg(rdev_get_dev(rdev), "regulator-%s-disable\n",
+		info->desc.name);
+
+	info->is_enabled = false;
+	if (!info->exclude_from_power_state)
+		ret = power_state_active_disable();
+
+	return ret;
+}
+
+static int db8500_regulator_is_enabled(struct regulator_dev *rdev)
+{
+	struct db8500_regulator_info *info = rdev_get_drvdata(rdev);
+
+	if (info == NULL)
+		return -EINVAL;
+
+	dev_vdbg(rdev_get_dev(rdev), "regulator-%s-is_enabled (is_enabled):"
+		" %i\n", info->desc.name, info->is_enabled);
+
+	return info->is_enabled;
+}
+
+/* db8500 regulator operations */
+static struct regulator_ops db8500_regulator_ops = {
+	.enable			= db8500_regulator_enable,
+	.disable		= db8500_regulator_disable,
+	.is_enabled		= db8500_regulator_is_enabled,
+};
+
+/*
+ * EPOD control
+ */
+static bool epod_on[NUM_EPOD_ID];
+static bool epod_ramret[NUM_EPOD_ID];
+
+static int enable_epod(u16 epod_id, bool ramret)
+{
+	int ret;
+
+	if (ramret) {
+		if (!epod_on[epod_id]) {
+			ret = prcmu_set_epod(epod_id, EPOD_STATE_RAMRET);
+			if (ret < 0)
+				return ret;
+		}
+		epod_ramret[epod_id] = true;
+	} else {
+		ret = prcmu_set_epod(epod_id, EPOD_STATE_ON);
+		if (ret < 0)
+			return ret;
+		epod_on[epod_id] = true;
+	}
+
+	return 0;
+}
+
+static int disable_epod(u16 epod_id, bool ramret)
+{
+	int ret;
+
+	if (ramret) {
+		if (!epod_on[epod_id]) {
+			ret = prcmu_set_epod(epod_id, EPOD_STATE_OFF);
+			if (ret < 0)
+				return ret;
+		}
+		epod_ramret[epod_id] = false;
+	} else {
+		if (epod_ramret[epod_id]) {
+			ret = prcmu_set_epod(epod_id, EPOD_STATE_RAMRET);
+			if (ret < 0)
+				return ret;
+		} else {
+			ret = prcmu_set_epod(epod_id, EPOD_STATE_OFF);
+			if (ret < 0)
+				return ret;
+		}
+		epod_on[epod_id] = false;
+	}
+
+	return 0;
+}
+
+/*
+ * Regulator switch
+ */
+static int db8500_regulator_switch_enable(struct regulator_dev *rdev)
+{
+	struct db8500_regulator_info *info = rdev_get_drvdata(rdev);
+	int ret;
+
+	if (info == NULL)
+		return -EINVAL;
+
+	dev_vdbg(rdev_get_dev(rdev), "regulator-switch-%s-enable\n",
+		info->desc.name);
+
+	ret = enable_epod(info->epod_id, info->is_ramret);
+	if (ret < 0) {
+		dev_err(rdev_get_dev(rdev),
+			"regulator-switch-%s-enable: prcmu call failed\n",
+			info->desc.name);
+		goto out;
+	}
+
+	info->is_enabled = true;
+out:
+	return ret;
+}
+
+static int db8500_regulator_switch_disable(struct regulator_dev *rdev)
+{
+	struct db8500_regulator_info *info = rdev_get_drvdata(rdev);
+	int ret;
+
+	if (info == NULL)
+		return -EINVAL;
+
+	dev_vdbg(rdev_get_dev(rdev), "regulator-switch-%s-disable\n",
+		info->desc.name);
+
+	ret = disable_epod(info->epod_id, info->is_ramret);
+	if (ret < 0) {
+		dev_err(rdev_get_dev(rdev),
+			"regulator_switch-%s-disable: prcmu call failed\n",
+			info->desc.name);
+		goto out;
+	}
+
+	info->is_enabled = 0;
+out:
+	return ret;
+}
+
+static int db8500_regulator_switch_is_enabled(struct regulator_dev *rdev)
+{
+	struct db8500_regulator_info *info = rdev_get_drvdata(rdev);
+
+	if (info == NULL)
+		return -EINVAL;
+
+	dev_vdbg(rdev_get_dev(rdev),
+		"regulator-switch-%s-is_enabled (is_enabled): %i\n",
+		info->desc.name, info->is_enabled);
+
+	return info->is_enabled;
+}
+
+static struct regulator_ops db8500_regulator_switch_ops = {
+	.enable			= db8500_regulator_switch_enable,
+	.disable		= db8500_regulator_switch_disable,
+	.is_enabled		= db8500_regulator_switch_is_enabled,
+};
+
+/*
+ * Regulator information
+ */
+static struct db8500_regulator_info
+db8500_regulator_info[DB8500_NUM_REGULATORS] = {
+	[DB8500_REGULATOR_VAPE] = {
+		.desc = {
+			.name	= "db8500-vape",
+			.id	= DB8500_REGULATOR_VAPE,
+			.ops	= &db8500_regulator_ops,
+			.type	= REGULATOR_VOLTAGE,
+			.owner	= THIS_MODULE,
+		},
+	},
+	[DB8500_REGULATOR_VARM] = {
+		.desc = {
+			.name	= "db8500-varm",
+			.id	= DB8500_REGULATOR_VARM,
+			.ops	= &db8500_regulator_ops,
+			.type	= REGULATOR_VOLTAGE,
+			.owner	= THIS_MODULE,
+		},
+	},
+	[DB8500_REGULATOR_VMODEM] = {
+		.desc = {
+			.name	= "db8500-vmodem",
+			.id	= DB8500_REGULATOR_VMODEM,
+			.ops	= &db8500_regulator_ops,
+			.type	= REGULATOR_VOLTAGE,
+			.owner	= THIS_MODULE,
+		},
+	},
+	[DB8500_REGULATOR_VPLL] = {
+		.desc = {
+			.name	= "db8500-vpll",
+			.id	= DB8500_REGULATOR_VPLL,
+			.ops	= &db8500_regulator_ops,
+			.type	= REGULATOR_VOLTAGE,
+			.owner	= THIS_MODULE,
+		},
+	},
+	[DB8500_REGULATOR_VSMPS1] = {
+		.desc = {
+			.name	= "db8500-vsmps1",
+			.id	= DB8500_REGULATOR_VSMPS1,
+			.ops	= &db8500_regulator_ops,
+			.type	= REGULATOR_VOLTAGE,
+			.owner	= THIS_MODULE,
+		},
+	},
+	[DB8500_REGULATOR_VSMPS2] = {
+		.desc = {
+			.name	= "db8500-vsmps2",
+			.id	= DB8500_REGULATOR_VSMPS2,
+			.ops	= &db8500_regulator_ops,
+			.type	= REGULATOR_VOLTAGE,
+			.owner	= THIS_MODULE,
+		},
+		.exclude_from_power_state = true,
+	},
+	[DB8500_REGULATOR_VSMPS3] = {
+		.desc = {
+			.name	= "db8500-vsmps3",
+			.id	= DB8500_REGULATOR_VSMPS3,
+			.ops	= &db8500_regulator_ops,
+			.type	= REGULATOR_VOLTAGE,
+			.owner	= THIS_MODULE,
+		},
+	},
+	[DB8500_REGULATOR_VRF1] = {
+		.desc = {
+			.name	= "db8500-vrf1",
+			.id	= DB8500_REGULATOR_VRF1,
+			.ops	= &db8500_regulator_ops,
+			.type	= REGULATOR_VOLTAGE,
+			.owner	= THIS_MODULE,
+		},
+	},
+	[DB8500_REGULATOR_SWITCH_SVAMMDSP] = {
+		.desc = {
+			.name	= "db8500-sva-mmdsp",
+			.id	= DB8500_REGULATOR_SWITCH_SVAMMDSP,
+			.ops	= &db8500_regulator_switch_ops,
+			.type	= REGULATOR_VOLTAGE,
+			.owner	= THIS_MODULE,
+		},
+		.epod_id = EPOD_ID_SVAMMDSP,
+	},
+	[DB8500_REGULATOR_SWITCH_SVAMMDSPRET] = {
+		.desc = {
+			.name	= "db8500-sva-mmdsp-ret",
+			.id	= DB8500_REGULATOR_SWITCH_SVAMMDSPRET,
+			.ops	= &db8500_regulator_switch_ops,
+			.type	= REGULATOR_VOLTAGE,
+			.owner	= THIS_MODULE,
+		},
+		.epod_id = EPOD_ID_SVAMMDSP,
+		.is_ramret = true,
+	},
+	[DB8500_REGULATOR_SWITCH_SVAPIPE] = {
+		.desc = {
+			.name	= "db8500-sva-pipe",
+			.id	= DB8500_REGULATOR_SWITCH_SVAPIPE,
+			.ops	= &db8500_regulator_switch_ops,
+			.type	= REGULATOR_VOLTAGE,
+			.owner	= THIS_MODULE,
+		},
+		.epod_id = EPOD_ID_SVAPIPE,
+	},
+	[DB8500_REGULATOR_SWITCH_SIAMMDSP] = {
+		.desc = {
+			.name	= "db8500-sia-mmdsp",
+			.id	= DB8500_REGULATOR_SWITCH_SIAMMDSP,
+			.ops	= &db8500_regulator_switch_ops,
+			.type	= REGULATOR_VOLTAGE,
+			.owner	= THIS_MODULE,
+		},
+		.epod_id = EPOD_ID_SIAMMDSP,
+	},
+	[DB8500_REGULATOR_SWITCH_SIAMMDSPRET] = {
+		.desc = {
+			.name	= "db8500-sia-mmdsp-ret",
+			.id	= DB8500_REGULATOR_SWITCH_SIAMMDSPRET,
+			.ops	= &db8500_regulator_switch_ops,
+			.type	= REGULATOR_VOLTAGE,
+			.owner	= THIS_MODULE,
+		},
+		.epod_id = EPOD_ID_SIAMMDSP,
+		.is_ramret = true,
+	},
+	[DB8500_REGULATOR_SWITCH_SIAPIPE] = {
+		.desc = {
+			.name	= "db8500-sia-pipe",
+			.id	= DB8500_REGULATOR_SWITCH_SIAPIPE,
+			.ops	= &db8500_regulator_switch_ops,
+			.type	= REGULATOR_VOLTAGE,
+			.owner	= THIS_MODULE,
+		},
+		.epod_id = EPOD_ID_SIAPIPE,
+	},
+	[DB8500_REGULATOR_SWITCH_SGA] = {
+		.desc = {
+			.name	= "db8500-sga",
+			.id	= DB8500_REGULATOR_SWITCH_SGA,
+			.ops	= &db8500_regulator_switch_ops,
+			.type	= REGULATOR_VOLTAGE,
+			.owner	= THIS_MODULE,
+		},
+		.epod_id = EPOD_ID_SGA,
+	},
+	[DB8500_REGULATOR_SWITCH_B2R2_MCDE] = {
+		.desc = {
+			.name	= "db8500-b2r2-mcde",
+			.id	= DB8500_REGULATOR_SWITCH_B2R2_MCDE,
+			.ops	= &db8500_regulator_switch_ops,
+			.type	= REGULATOR_VOLTAGE,
+			.owner	= THIS_MODULE,
+		},
+		.epod_id = EPOD_ID_B2R2_MCDE,
+	},
+	[DB8500_REGULATOR_SWITCH_ESRAM12] = {
+		.desc = {
+			.name	= "db8500-esram12",
+			.id	= DB8500_REGULATOR_SWITCH_ESRAM12,
+			.ops	= &db8500_regulator_switch_ops,
+			.type	= REGULATOR_VOLTAGE,
+			.owner	= THIS_MODULE,
+		},
+		.epod_id	= EPOD_ID_ESRAM12,
+		.is_enabled	= true,
+	},
+	[DB8500_REGULATOR_SWITCH_ESRAM12RET] = {
+		.desc = {
+			.name	= "db8500-esram12-ret",
+			.id	= DB8500_REGULATOR_SWITCH_ESRAM12RET,
+			.ops	= &db8500_regulator_switch_ops,
+			.type	= REGULATOR_VOLTAGE,
+			.owner	= THIS_MODULE,
+		},
+		.epod_id = EPOD_ID_ESRAM12,
+		.is_ramret = true,
+	},
+	[DB8500_REGULATOR_SWITCH_ESRAM34] = {
+		.desc = {
+			.name	= "db8500-esram34",
+			.id	= DB8500_REGULATOR_SWITCH_ESRAM34,
+			.ops	= &db8500_regulator_switch_ops,
+			.type	= REGULATOR_VOLTAGE,
+			.owner	= THIS_MODULE,
+		},
+		.epod_id	= EPOD_ID_ESRAM34,
+		.is_enabled	= true,
+	},
+	[DB8500_REGULATOR_SWITCH_ESRAM34RET] = {
+		.desc = {
+			.name	= "db8500-esram34-ret",
+			.id	= DB8500_REGULATOR_SWITCH_ESRAM34RET,
+			.ops	= &db8500_regulator_switch_ops,
+			.type	= REGULATOR_VOLTAGE,
+			.owner	= THIS_MODULE,
+		},
+		.epod_id = EPOD_ID_ESRAM34,
+		.is_ramret = true,
+	},
+};
+
+static int __devinit db8500_regulator_probe(struct platform_device *pdev)
+{
+	struct regulator_init_data *db8500_init_data =
+					dev_get_platdata(&pdev->dev);
+	int i, err;
+
+	/* register all regulators */
+	for (i = 0; i < ARRAY_SIZE(db8500_regulator_info); i++) {
+		struct db8500_regulator_info *info;
+		struct regulator_init_data *init_data = &db8500_init_data[i];
+
+		/* assign per-regulator data */
+		info = &db8500_regulator_info[i];
+		info->dev = &pdev->dev;
+
+		/* register with the regulator framework */
+		info->rdev = regulator_register(&info->desc, &pdev->dev,
+				init_data, info);
+		if (IS_ERR(info->rdev)) {
+			err = PTR_ERR(info->rdev);
+			dev_err(&pdev->dev, "failed to register %s: err %i\n",
+				info->desc.name, err);
+
+			/* if failing, unregister all earlier regulators */
+			while (--i >= 0) {
+				info = &db8500_regulator_info[i];
+				regulator_unregister(info->rdev);
+			}
+			return err;
+		}
+
+		dev_dbg(rdev_get_dev(info->rdev),
+			"regulator-%s-probed\n", info->desc.name);
+	}
+
+	return 0;
+}
+
+static int __exit db8500_regulator_remove(struct platform_device *pdev)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(db8500_regulator_info); i++) {
+		struct db8500_regulator_info *info;
+		info = &db8500_regulator_info[i];
+
+		dev_vdbg(rdev_get_dev(info->rdev),
+			"regulator-%s-remove\n", info->desc.name);
+
+		regulator_unregister(info->rdev);
+	}
+
+	return 0;
+}
+
+static struct platform_driver db8500_regulator_driver = {
+	.driver = {
+		.name = "db8500-prcmu-regulators",
+		.owner = THIS_MODULE,
+	},
+	.probe = db8500_regulator_probe,
+	.remove = __exit_p(db8500_regulator_remove),
+};
+
+static int __init db8500_regulator_init(void)
+{
+	return platform_driver_register(&db8500_regulator_driver);
+}
+
+static void __exit db8500_regulator_exit(void)
+{
+	platform_driver_unregister(&db8500_regulator_driver);
+}
+
+arch_initcall(db8500_regulator_init);
+module_exit(db8500_regulator_exit);
+
+MODULE_AUTHOR("STMicroelectronics/ST-Ericsson");
+MODULE_DESCRIPTION("DB8500 regulator driver");
+MODULE_LICENSE("GPL v2");
diff -druN linux-2.6.39-libre/drivers/regulator/Kconfig linux-3.0-rc7-libre/drivers/regulator/Kconfig
--- linux-2.6.39-libre/drivers/regulator/Kconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/regulator/Kconfig	2011-07-11 19:51:52.000000000 -0400
@@ -274,6 +274,13 @@
 	  This driver supports the regulators found on the ST-Ericsson mixed
 	  signal AB8500 PMIC
 
+config REGULATOR_DB8500_PRCMU
+	bool "ST-Ericsson DB8500 Voltage Domain Regulators"
+	depends on MFD_DB8500_PRCMU
+	help
+	  This driver supports the voltage domain regulators controlled by the
+	  DB8500 PRCMU
+
 config REGULATOR_TPS6586X
 	tristate "TI TPS6586X Power regulators"
 	depends on MFD_TPS6586X
@@ -290,5 +297,11 @@
 	  serial interface currently supported on the sequencer serial
 	  port controller.
 
+config REGULATOR_TPS65910
+	tristate "TI TPS65910 Power Regulator"
+	depends on MFD_TPS65910
+	help
+	  This driver supports TPS65910 voltage regulator chips.
+
 endif
 
diff -druN linux-2.6.39-libre/drivers/regulator/Makefile linux-3.0-rc7-libre/drivers/regulator/Makefile
--- linux-2.6.39-libre/drivers/regulator/Makefile	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/regulator/Makefile	2011-07-11 19:51:52.000000000 -0400
@@ -41,5 +41,7 @@
 obj-$(CONFIG_REGULATOR_88PM8607) += 88pm8607.o
 obj-$(CONFIG_REGULATOR_ISL6271A) += isl6271a-regulator.o
 obj-$(CONFIG_REGULATOR_AB8500)	+= ab8500.o
+obj-$(CONFIG_REGULATOR_DB8500_PRCMU) += db8500-prcmu.o
+obj-$(CONFIG_REGULATOR_TPS65910) += tps65910-regulator.o
 
 ccflags-$(CONFIG_REGULATOR_DEBUG) += -DDEBUG
diff -druN linux-2.6.39-libre/drivers/regulator/max8925-regulator.c linux-3.0-rc7-libre/drivers/regulator/max8925-regulator.c
--- linux-2.6.39-libre/drivers/regulator/max8925-regulator.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/regulator/max8925-regulator.c	2011-07-11 19:51:52.000000000 -0400
@@ -23,6 +23,10 @@
 #define SD1_DVM_SHIFT		5		/* SDCTL1 bit5 */
 #define SD1_DVM_EN		6		/* SDV1 bit 6 */
 
+/* bit definitions in SD & LDO control registers */
+#define OUT_ENABLE   		0x1f		/* Power U/D sequence as I2C */
+#define OUT_DISABLE		0x1e		/* Power U/D sequence as I2C */
+
 struct max8925_regulator_info {
 	struct regulator_desc	desc;
 	struct regulator_dev	*regulator;
@@ -93,8 +97,8 @@
 	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);
+				OUT_ENABLE << info->enable_bit,
+				OUT_ENABLE << info->enable_bit);
 }
 
 static int max8925_disable(struct regulator_dev *rdev)
@@ -102,7 +106,8 @@
 	struct max8925_regulator_info *info = rdev_get_drvdata(rdev);
 
 	return max8925_set_bits(info->i2c, info->enable_reg,
-				1 << info->enable_bit, 0);
+				OUT_ENABLE << info->enable_bit,
+				OUT_DISABLE << info->enable_bit);
 }
 
 static int max8925_is_enabled(struct regulator_dev *rdev)
diff -druN linux-2.6.39-libre/drivers/regulator/max8952.c linux-3.0-rc7-libre/drivers/regulator/max8952.c
--- linux-2.6.39-libre/drivers/regulator/max8952.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/regulator/max8952.c	2011-07-11 19:51:52.000000000 -0400
@@ -139,7 +139,7 @@
 	s8 vid = -1, i;
 
 	if (!gpio_is_valid(max8952->pdata->gpio_vid0) ||
-			!gpio_is_valid(max8952->pdata->gpio_vid0)) {
+			!gpio_is_valid(max8952->pdata->gpio_vid1)) {
 		/* DVS not supported */
 		return -EPERM;
 	}
diff -druN linux-2.6.39-libre/drivers/regulator/max8997.c linux-3.0-rc7-libre/drivers/regulator/max8997.c
--- linux-2.6.39-libre/drivers/regulator/max8997.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/regulator/max8997.c	2011-07-11 19:51:52.000000000 -0400
@@ -39,25 +39,28 @@
 	struct regulator_dev **rdev;
 	int ramp_delay; /* in mV/us */
 
+	bool buck1_gpiodvs;
+	bool buck2_gpiodvs;
+	bool buck5_gpiodvs;
 	u8 buck1_vol[8];
 	u8 buck2_vol[8];
 	u8 buck5_vol[8];
+	int buck125_gpios[3];
 	int buck125_gpioindex;
+	bool ignore_gpiodvs_side_effect;
 
 	u8 saved_states[MAX8997_REG_MAX];
 };
 
 static inline void max8997_set_gpio(struct max8997_data *max8997)
 {
-	struct max8997_platform_data *pdata =
-		dev_get_platdata(max8997->iodev->dev);
 	int set3 = (max8997->buck125_gpioindex) & 0x1;
 	int set2 = ((max8997->buck125_gpioindex) >> 1) & 0x1;
 	int set1 = ((max8997->buck125_gpioindex) >> 2) & 0x1;
 
-	gpio_set_value(pdata->buck125_gpios[0], set1);
-	gpio_set_value(pdata->buck125_gpios[1], set2);
-	gpio_set_value(pdata->buck125_gpios[2], set3);
+	gpio_set_value(max8997->buck125_gpios[0], set1);
+	gpio_set_value(max8997->buck125_gpios[1], set2);
+	gpio_set_value(max8997->buck125_gpios[2], set3);
 }
 
 struct voltage_map_desc {
@@ -267,7 +270,6 @@
 	default:
 		/* Not controllable or not exists */
 		return -EINVAL;
-		break;
 	}
 
 	return 0;
@@ -381,8 +383,6 @@
 static int max8997_get_voltage(struct regulator_dev *rdev)
 {
 	struct max8997_data *max8997 = rdev_get_drvdata(rdev);
-	struct max8997_platform_data *pdata =
-		dev_get_platdata(max8997->iodev->dev);
 	struct i2c_client *i2c = max8997->iodev->i2c;
 	int reg, shift, mask, ret;
 	int rid = max8997_get_rid(rdev);
@@ -392,9 +392,9 @@
 	if (ret)
 		return ret;
 
-	if ((rid == MAX8997_BUCK1 && pdata->buck1_gpiodvs) ||
-			(rid == MAX8997_BUCK2 && pdata->buck2_gpiodvs) ||
-			(rid == MAX8997_BUCK5 && pdata->buck5_gpiodvs))
+	if ((rid == MAX8997_BUCK1 && max8997->buck1_gpiodvs) ||
+			(rid == MAX8997_BUCK2 && max8997->buck2_gpiodvs) ||
+			(rid == MAX8997_BUCK5 && max8997->buck5_gpiodvs))
 		reg += max8997->buck125_gpioindex;
 
 	ret = max8997_read_reg(i2c, reg, &val);
@@ -544,7 +544,8 @@
 			rid == MAX8997_BUCK4 || rid == MAX8997_BUCK5) {
 		/* If the voltage is increasing */
 		if (org < i)
-			udelay(desc->step * (i - org) / max8997->ramp_delay);
+			udelay(DIV_ROUND_UP(desc->step * (i - org),
+						max8997->ramp_delay));
 	}
 
 	return ret;
@@ -562,8 +563,6 @@
 		u8 new_val, int *best)
 {
 	struct max8997_data *max8997 = rdev_get_drvdata(rdev);
-	struct max8997_platform_data *pdata =
-		dev_get_platdata(max8997->iodev->dev);
 	int rid = max8997_get_rid(rdev);
 	u8 *buckx_val[3];
 	bool buckx_gpiodvs[3];
@@ -590,9 +589,9 @@
 	buckx_val[0] = max8997->buck1_vol;
 	buckx_val[1] = max8997->buck2_vol;
 	buckx_val[2] = max8997->buck5_vol;
-	buckx_gpiodvs[0] = pdata->buck1_gpiodvs;
-	buckx_gpiodvs[1] = pdata->buck2_gpiodvs;
-	buckx_gpiodvs[2] = pdata->buck5_gpiodvs;
+	buckx_gpiodvs[0] = max8997->buck1_gpiodvs;
+	buckx_gpiodvs[1] = max8997->buck2_gpiodvs;
+	buckx_gpiodvs[2] = max8997->buck5_gpiodvs;
 
 	for (i = 0; i < 8; i++) {
 		int others;
@@ -641,8 +640,6 @@
 		int min_uV, int max_uV, unsigned *selector)
 {
 	struct max8997_data *max8997 = rdev_get_drvdata(rdev);
-	struct max8997_platform_data *pdata =
-		dev_get_platdata(max8997->iodev->dev);
 	int rid = max8997_get_rid(rdev);
 	const struct voltage_map_desc *desc;
 	int new_val, new_idx, damage, tmp_val, tmp_idx, tmp_dmg;
@@ -654,15 +651,15 @@
 
 	switch (rid) {
 	case MAX8997_BUCK1:
-		if (pdata->buck1_gpiodvs)
+		if (max8997->buck1_gpiodvs)
 			gpio_dvs_mode = true;
 		break;
 	case MAX8997_BUCK2:
-		if (pdata->buck2_gpiodvs)
+		if (max8997->buck2_gpiodvs)
 			gpio_dvs_mode = true;
 		break;
 	case MAX8997_BUCK5:
-		if (pdata->buck5_gpiodvs)
+		if (max8997->buck5_gpiodvs)
 			gpio_dvs_mode = true;
 		break;
 	}
@@ -696,7 +693,7 @@
 	new_idx = tmp_idx;
 	new_val = tmp_val;
 
-	if (pdata->ignore_gpiodvs_side_effect == false)
+	if (max8997->ignore_gpiodvs_side_effect == false)
 		return -EINVAL;
 
 	dev_warn(&rdev->dev, "MAX8997 GPIO-DVS Side Effect Warning: GPIO SET:"
@@ -994,6 +991,11 @@
 	i2c = max8997->iodev->i2c;
 
 	max8997->buck125_gpioindex = pdata->buck125_default_idx;
+	max8997->buck1_gpiodvs = pdata->buck1_gpiodvs;
+	max8997->buck2_gpiodvs = pdata->buck2_gpiodvs;
+	max8997->buck5_gpiodvs = pdata->buck5_gpiodvs;
+	memcpy(max8997->buck125_gpios, pdata->buck125_gpios, sizeof(int) * 3);
+	max8997->ignore_gpiodvs_side_effect = pdata->ignore_gpiodvs_side_effect;
 
 	for (i = 0; i < 8; i++) {
 		max8997->buck1_vol[i] = ret =
@@ -1033,11 +1035,11 @@
 
 	/* For the safety, set max voltage before setting up */
 	for (i = 0; i < 8; i++) {
-		max8997_update_reg(i2c, MAX8997_REG_BUCK1DVS(i + 1),
+		max8997_update_reg(i2c, MAX8997_REG_BUCK1DVS1 + i,
 				max_buck1, 0x3f);
-		max8997_update_reg(i2c, MAX8997_REG_BUCK2DVS(i + 1),
+		max8997_update_reg(i2c, MAX8997_REG_BUCK2DVS1 + i,
 				max_buck2, 0x3f);
-		max8997_update_reg(i2c, MAX8997_REG_BUCK5DVS(i + 1),
+		max8997_update_reg(i2c, MAX8997_REG_BUCK5DVS1 + i,
 				max_buck5, 0x3f);
 	}
 
@@ -1114,17 +1116,21 @@
 
 	/* Initialize all the DVS related BUCK registers */
 	for (i = 0; i < 8; i++) {
-		max8997_update_reg(i2c, MAX8997_REG_BUCK1DVS(i + 1),
+		max8997_update_reg(i2c, MAX8997_REG_BUCK1DVS1 + i,
 				max8997->buck1_vol[i],
 				0x3f);
-		max8997_update_reg(i2c, MAX8997_REG_BUCK2DVS(i + 1),
+		max8997_update_reg(i2c, MAX8997_REG_BUCK2DVS1 + i,
 				max8997->buck2_vol[i],
 				0x3f);
-		max8997_update_reg(i2c, MAX8997_REG_BUCK5DVS(i + 1),
+		max8997_update_reg(i2c, MAX8997_REG_BUCK5DVS1 + i,
 				max8997->buck5_vol[i],
 				0x3f);
 	}
 
+	/* Misc Settings */
+	max8997->ramp_delay = 10; /* set 10mV/us, which is the default */
+	max8997_write_reg(i2c, MAX8997_REG_BUCKRAMP, (0xf << 4) | 0x9);
+
 	for (i = 0; i < pdata->num_regulators; i++) {
 		const struct voltage_map_desc *desc;
 		int id = pdata->regulators[i].id;
@@ -1149,10 +1155,6 @@
 		}
 	}
 
-	/* Misc Settings */
-	max8997->ramp_delay = 10; /* set 10mV/us, which is the default */
-	max8997_write_reg(i2c, MAX8997_REG_BUCKRAMP, (0xf << 4) | 0x9);
-
 	return 0;
 err:
 	for (i = 0; i < max8997->num_regulators; i++)
diff -druN linux-2.6.39-libre/drivers/regulator/max8998.c linux-3.0-rc7-libre/drivers/regulator/max8998.c
--- linux-2.6.39-libre/drivers/regulator/max8998.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/regulator/max8998.c	2011-07-11 19:51:52.000000000 -0400
@@ -405,8 +405,8 @@
 	switch (buck) {
 	case MAX8998_BUCK1:
 		dev_dbg(max8998->dev,
-			"BUCK1, i:%d, buck1_vol1:%d, buck1_vol2:%d\n\
-			 buck1_vol3:%d, buck1_vol4:%d\n",
+			"BUCK1, i:%d, buck1_vol1:%d, buck1_vol2:%d\n"
+			"buck1_vol3:%d, buck1_vol4:%d\n",
 			i, max8998->buck1_vol[0], max8998->buck1_vol[1],
 			max8998->buck1_vol[2], max8998->buck1_vol[3]);
 
@@ -732,13 +732,15 @@
 		if (!pdata->buck1_set1) {
 			printk(KERN_ERR "MAX8998 SET1 GPIO defined as 0 !\n");
 			WARN_ON(!pdata->buck1_set1);
-			return -EIO;
+			ret = -EIO;
+			goto err_free_mem;
 		}
 		/* Check if SET2 is not equal to 0 */
 		if (!pdata->buck1_set2) {
 			printk(KERN_ERR "MAX8998 SET2 GPIO defined as 0 !\n");
 			WARN_ON(!pdata->buck1_set2);
-			return -EIO;
+			ret = -EIO;
+			goto err_free_mem;
 		}
 
 		gpio_request(pdata->buck1_set1, "MAX8998 BUCK1_SET1");
@@ -758,7 +760,7 @@
 		max8998->buck1_vol[0] = i;
 		ret = max8998_write_reg(i2c, MAX8998_REG_BUCK1_VOLTAGE1, i);
 		if (ret)
-			return ret;
+			goto err_free_mem;
 
 		/* Set predefined value for BUCK1 register 2 */
 		i = 0;
@@ -770,7 +772,7 @@
 		max8998->buck1_vol[1] = i;
 		ret = max8998_write_reg(i2c, MAX8998_REG_BUCK1_VOLTAGE2, i);
 		if (ret)
-			return ret;
+			goto err_free_mem;
 
 		/* Set predefined value for BUCK1 register 3 */
 		i = 0;
@@ -782,7 +784,7 @@
 		max8998->buck1_vol[2] = i;
 		ret = max8998_write_reg(i2c, MAX8998_REG_BUCK1_VOLTAGE3, i);
 		if (ret)
-			return ret;
+			goto err_free_mem;
 
 		/* Set predefined value for BUCK1 register 4 */
 		i = 0;
@@ -794,7 +796,7 @@
 		max8998->buck1_vol[3] = i;
 		ret = max8998_write_reg(i2c, MAX8998_REG_BUCK1_VOLTAGE4, i);
 		if (ret)
-			return ret;
+			goto err_free_mem;
 
 	}
 
@@ -803,7 +805,8 @@
 		if (!pdata->buck2_set3) {
 			printk(KERN_ERR "MAX8998 SET3 GPIO defined as 0 !\n");
 			WARN_ON(!pdata->buck2_set3);
-			return -EIO;
+			ret = -EIO;
+			goto err_free_mem;
 		}
 		gpio_request(pdata->buck2_set3, "MAX8998 BUCK2_SET3");
 		gpio_direction_output(pdata->buck2_set3,
@@ -818,7 +821,7 @@
 		max8998->buck2_vol[0] = i;
 		ret = max8998_write_reg(i2c, MAX8998_REG_BUCK2_VOLTAGE1, i);
 		if (ret)
-			return ret;
+			goto err_free_mem;
 
 		/* BUCK2 register 2 */
 		i = 0;
@@ -830,7 +833,7 @@
 		max8998->buck2_vol[1] = i;
 		ret = max8998_write_reg(i2c, MAX8998_REG_BUCK2_VOLTAGE2, i);
 		if (ret)
-			return ret;
+			goto err_free_mem;
 	}
 
 	for (i = 0; i < pdata->num_regulators; i++) {
@@ -860,6 +863,7 @@
 		if (rdev[i])
 			regulator_unregister(rdev[i]);
 
+err_free_mem:
 	kfree(max8998->rdev);
 	kfree(max8998);
 
diff -druN linux-2.6.39-libre/drivers/regulator/mc13783-regulator.c linux-3.0-rc7-libre/drivers/regulator/mc13783-regulator.c
--- linux-2.6.39-libre/drivers/regulator/mc13783-regulator.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/regulator/mc13783-regulator.c	2011-07-11 19:51:52.000000000 -0400
@@ -15,7 +15,6 @@
 #include <linux/regulator/driver.h>
 #include <linux/platform_device.h>
 #include <linux/kernel.h>
-#include <linux/mfd/core.h>
 #include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/err.h>
@@ -337,11 +336,12 @@
 {
 	struct mc13xxx_regulator_priv *priv;
 	struct mc13xxx *mc13783 = dev_get_drvdata(pdev->dev.parent);
-	struct mc13783_regulator_platform_data *pdata = mfd_get_data(pdev);
+	struct mc13783_regulator_platform_data *pdata =
+		dev_get_platdata(&pdev->dev);
 	struct mc13783_regulator_init_data *init_data;
 	int i, ret;
 
-	dev_dbg(&pdev->dev, "mc13783_regulator_probe id %d\n", pdev->id);
+	dev_dbg(&pdev->dev, "%s id %d\n", __func__, pdev->id);
 
 	priv = kzalloc(sizeof(*priv) +
 			pdata->num_regulators * sizeof(priv->regulators[0]),
@@ -381,7 +381,8 @@
 static int __devexit mc13783_regulator_remove(struct platform_device *pdev)
 {
 	struct mc13xxx_regulator_priv *priv = platform_get_drvdata(pdev);
-	struct mc13783_regulator_platform_data *pdata = mfd_get_data(pdev);
+	struct mc13783_regulator_platform_data *pdata =
+		dev_get_platdata(&pdev->dev);
 	int i;
 
 	platform_set_drvdata(pdev, NULL);
diff -druN linux-2.6.39-libre/drivers/regulator/mc13892-regulator.c linux-3.0-rc7-libre/drivers/regulator/mc13892-regulator.c
--- linux-2.6.39-libre/drivers/regulator/mc13892-regulator.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/regulator/mc13892-regulator.c	2011-07-11 19:51:52.000000000 -0400
@@ -15,7 +15,6 @@
 #include <linux/regulator/driver.h>
 #include <linux/platform_device.h>
 #include <linux/kernel.h>
-#include <linux/mfd/core.h>
 #include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/err.h>
@@ -432,7 +431,8 @@
 		int min_uV, int max_uV, unsigned *selector)
 {
 	struct mc13xxx_regulator_priv *priv = rdev_get_drvdata(rdev);
-	int hi, value, val, mask, id = rdev_get_id(rdev);
+	int hi, value, mask, id = rdev_get_id(rdev);
+	u32 valread;
 	int ret;
 
 	dev_dbg(rdev_get_dev(rdev), "%s id: %d min_uV: %d max_uV: %d\n",
@@ -448,15 +448,16 @@
 
 	mc13xxx_lock(priv->mc13xxx);
 	ret = mc13xxx_reg_read(priv->mc13xxx,
-		mc13892_regulators[id].vsel_reg, &val);
+		mc13892_regulators[id].vsel_reg, &valread);
 	if (ret)
 		goto err;
 
-	hi  = val & MC13892_SWITCHERS0_SWxHI;
-	if (value > 1375)
+	if (value > 1375000)
 		hi = 1;
-	if (value < 1100)
+	else if (value < 1100000)
 		hi = 0;
+	else
+		hi = valread & MC13892_SWITCHERS0_SWxHI;
 
 	if (hi) {
 		value = (value - 1100000) / 25000;
@@ -465,8 +466,10 @@
 		value = (value - 600000) / 25000;
 
 	mask = mc13892_regulators[id].vsel_mask | MC13892_SWITCHERS0_SWxHI;
-	ret = mc13xxx_reg_rmw(priv->mc13xxx, mc13892_regulators[id].vsel_reg,
-			mask, value << mc13892_regulators[id].vsel_shift);
+	valread = (valread & ~mask) |
+			(value << mc13892_regulators[id].vsel_shift);
+	ret = mc13xxx_reg_write(priv->mc13xxx, mc13892_regulators[id].vsel_reg,
+			valread);
 err:
 	mc13xxx_unlock(priv->mc13xxx);
 
@@ -521,7 +524,8 @@
 {
 	struct mc13xxx_regulator_priv *priv;
 	struct mc13xxx *mc13892 = dev_get_drvdata(pdev->dev.parent);
-	struct mc13xxx_regulator_platform_data *pdata = mfd_get_data(pdev);
+	struct mc13xxx_regulator_platform_data *pdata =
+		dev_get_platdata(&pdev->dev);
 	struct mc13xxx_regulator_init_data *init_data;
 	int i, ret;
 	u32 val;
@@ -595,7 +599,8 @@
 static int __devexit mc13892_regulator_remove(struct platform_device *pdev)
 {
 	struct mc13xxx_regulator_priv *priv = platform_get_drvdata(pdev);
-	struct mc13xxx_regulator_platform_data *pdata = mfd_get_data(pdev);
+	struct mc13xxx_regulator_platform_data *pdata =
+		dev_get_platdata(&pdev->dev);
 	int i;
 
 	platform_set_drvdata(pdev, NULL);
diff -druN linux-2.6.39-libre/drivers/regulator/mc13xxx-regulator-core.c linux-3.0-rc7-libre/drivers/regulator/mc13xxx-regulator-core.c
--- linux-2.6.39-libre/drivers/regulator/mc13xxx-regulator-core.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/regulator/mc13xxx-regulator-core.c	2011-07-11 19:51:52.000000000 -0400
@@ -174,7 +174,7 @@
 
 	dev_dbg(rdev_get_dev(rdev), "%s id: %d val: %d\n", __func__, id, val);
 
-	BUG_ON(val > mc13xxx_regulators[id].desc.n_voltages);
+	BUG_ON(val >= mc13xxx_regulators[id].desc.n_voltages);
 
 	return mc13xxx_regulators[id].voltages[val];
 }
diff -druN linux-2.6.39-libre/drivers/regulator/tps6105x-regulator.c linux-3.0-rc7-libre/drivers/regulator/tps6105x-regulator.c
--- linux-2.6.39-libre/drivers/regulator/tps6105x-regulator.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/regulator/tps6105x-regulator.c	2011-07-11 19:51:52.000000000 -0400
@@ -137,7 +137,7 @@
  */
 static int __devinit tps6105x_regulator_probe(struct platform_device *pdev)
 {
-	struct tps6105x *tps6105x = mfd_get_data(pdev);
+	struct tps6105x *tps6105x = dev_get_platdata(&pdev->dev);
 	struct tps6105x_platform_data *pdata = tps6105x->pdata;
 	int ret;
 
@@ -158,13 +158,14 @@
 			"failed to register regulator\n");
 		return ret;
 	}
+	platform_set_drvdata(pdev, tps6105x);
 
 	return 0;
 }
 
 static int __devexit tps6105x_regulator_remove(struct platform_device *pdev)
 {
-	struct tps6105x *tps6105x = platform_get_drvdata(pdev);
+	struct tps6105x *tps6105x = dev_get_platdata(&pdev->dev);
 	regulator_unregister(tps6105x->regulator);
 	return 0;
 }
diff -druN linux-2.6.39-libre/drivers/regulator/tps65023-regulator.c linux-3.0-rc7-libre/drivers/regulator/tps65023-regulator.c
--- linux-2.6.39-libre/drivers/regulator/tps65023-regulator.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/regulator/tps65023-regulator.c	2011-07-11 19:51:52.000000000 -0400
@@ -466,7 +466,6 @@
 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;
 	struct regulator_init_data *init_data;
 	struct regulator_dev *rdev;
@@ -499,7 +498,7 @@
 		tps->info[i] = info;
 
 		tps->desc[i].name = info->name;
-		tps->desc[i].id = desc_id++;
+		tps->desc[i].id = i;
 		tps->desc[i].n_voltages = num_voltages[i];
 		tps->desc[i].ops = (i > TPS65023_DCDC_3 ?
 					&tps65023_ldo_ops : &tps65023_dcdc_ops);
diff -druN linux-2.6.39-libre/drivers/regulator/tps6507x-regulator.c linux-3.0-rc7-libre/drivers/regulator/tps6507x-regulator.c
--- linux-2.6.39-libre/drivers/regulator/tps6507x-regulator.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/regulator/tps6507x-regulator.c	2011-07-11 19:51:52.000000000 -0400
@@ -553,7 +553,6 @@
 int tps6507x_pmic_probe(struct platform_device *pdev)
 {
 	struct tps6507x_dev *tps6507x_dev = dev_get_drvdata(pdev->dev.parent);
-	static int desc_id;
 	struct tps_info *info = &tps6507x_pmic_regs[0];
 	struct regulator_init_data *init_data;
 	struct regulator_dev *rdev;
@@ -598,7 +597,7 @@
 		}
 
 		tps->desc[i].name = info->name;
-		tps->desc[i].id = desc_id++;
+		tps->desc[i].id = i;
 		tps->desc[i].n_voltages = num_voltages[i];
 		tps->desc[i].ops = (i > TPS6507X_DCDC_3 ?
 		&tps6507x_pmic_ldo_ops : &tps6507x_pmic_dcdc_ops);
diff -druN linux-2.6.39-libre/drivers/regulator/tps65910-regulator.c linux-3.0-rc7-libre/drivers/regulator/tps65910-regulator.c
--- linux-2.6.39-libre/drivers/regulator/tps65910-regulator.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/regulator/tps65910-regulator.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,993 @@
+/*
+ * tps65910.c  --  TI tps65910
+ *
+ * Copyright 2010 Texas Instruments Inc.
+ *
+ * Author: Graeme Gregory <gg@slimlogic.co.uk>
+ * Author: Jorge Eduardo Candelaria <jedu@slimlogic.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.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/err.h>
+#include <linux/platform_device.h>
+#include <linux/regulator/driver.h>
+#include <linux/regulator/machine.h>
+#include <linux/delay.h>
+#include <linux/slab.h>
+#include <linux/gpio.h>
+#include <linux/mfd/tps65910.h>
+
+#define TPS65910_REG_VRTC		0
+#define TPS65910_REG_VIO		1
+#define TPS65910_REG_VDD1		2
+#define TPS65910_REG_VDD2		3
+#define TPS65910_REG_VDD3		4
+#define TPS65910_REG_VDIG1		5
+#define TPS65910_REG_VDIG2		6
+#define TPS65910_REG_VPLL		7
+#define TPS65910_REG_VDAC		8
+#define TPS65910_REG_VAUX1		9
+#define TPS65910_REG_VAUX2		10
+#define TPS65910_REG_VAUX33		11
+#define TPS65910_REG_VMMC		12
+
+#define TPS65911_REG_VDDCTRL		4
+#define TPS65911_REG_LDO1		5
+#define TPS65911_REG_LDO2		6
+#define TPS65911_REG_LDO3		7
+#define TPS65911_REG_LDO4		8
+#define TPS65911_REG_LDO5		9
+#define TPS65911_REG_LDO6		10
+#define TPS65911_REG_LDO7		11
+#define TPS65911_REG_LDO8		12
+
+#define TPS65910_NUM_REGULATOR		13
+#define TPS65910_SUPPLY_STATE_ENABLED	0x1
+
+/* supported VIO voltages in milivolts */
+static const u16 VIO_VSEL_table[] = {
+	1500, 1800, 2500, 3300,
+};
+
+/* VSEL tables for TPS65910 specific LDOs and dcdc's */
+
+/* supported VDD3 voltages in milivolts */
+static const u16 VDD3_VSEL_table[] = {
+	5000,
+};
+
+/* supported VDIG1 voltages in milivolts */
+static const u16 VDIG1_VSEL_table[] = {
+	1200, 1500, 1800, 2700,
+};
+
+/* supported VDIG2 voltages in milivolts */
+static const u16 VDIG2_VSEL_table[] = {
+	1000, 1100, 1200, 1800,
+};
+
+/* supported VPLL voltages in milivolts */
+static const u16 VPLL_VSEL_table[] = {
+	1000, 1100, 1800, 2500,
+};
+
+/* supported VDAC voltages in milivolts */
+static const u16 VDAC_VSEL_table[] = {
+	1800, 2600, 2800, 2850,
+};
+
+/* supported VAUX1 voltages in milivolts */
+static const u16 VAUX1_VSEL_table[] = {
+	1800, 2500, 2800, 2850,
+};
+
+/* supported VAUX2 voltages in milivolts */
+static const u16 VAUX2_VSEL_table[] = {
+	1800, 2800, 2900, 3300,
+};
+
+/* supported VAUX33 voltages in milivolts */
+static const u16 VAUX33_VSEL_table[] = {
+	1800, 2000, 2800, 3300,
+};
+
+/* supported VMMC voltages in milivolts */
+static const u16 VMMC_VSEL_table[] = {
+	1800, 2800, 3000, 3300,
+};
+
+struct tps_info {
+	const char *name;
+	unsigned min_uV;
+	unsigned max_uV;
+	u8 table_len;
+	const u16 *table;
+};
+
+static struct tps_info tps65910_regs[] = {
+	{
+		.name = "VRTC",
+	},
+	{
+		.name = "VIO",
+		.min_uV = 1500000,
+		.max_uV = 3300000,
+		.table_len = ARRAY_SIZE(VIO_VSEL_table),
+		.table = VIO_VSEL_table,
+	},
+	{
+		.name = "VDD1",
+		.min_uV = 600000,
+		.max_uV = 4500000,
+	},
+	{
+		.name = "VDD2",
+		.min_uV = 600000,
+		.max_uV = 4500000,
+	},
+	{
+		.name = "VDD3",
+		.min_uV = 5000000,
+		.max_uV = 5000000,
+		.table_len = ARRAY_SIZE(VDD3_VSEL_table),
+		.table = VDD3_VSEL_table,
+	},
+	{
+		.name = "VDIG1",
+		.min_uV = 1200000,
+		.max_uV = 2700000,
+		.table_len = ARRAY_SIZE(VDIG1_VSEL_table),
+		.table = VDIG1_VSEL_table,
+	},
+	{
+		.name = "VDIG2",
+		.min_uV = 1000000,
+		.max_uV = 1800000,
+		.table_len = ARRAY_SIZE(VDIG2_VSEL_table),
+		.table = VDIG2_VSEL_table,
+	},
+	{
+		.name = "VPLL",
+		.min_uV = 1000000,
+		.max_uV = 2500000,
+		.table_len = ARRAY_SIZE(VPLL_VSEL_table),
+		.table = VPLL_VSEL_table,
+	},
+	{
+		.name = "VDAC",
+		.min_uV = 1800000,
+		.max_uV = 2850000,
+		.table_len = ARRAY_SIZE(VDAC_VSEL_table),
+		.table = VDAC_VSEL_table,
+	},
+	{
+		.name = "VAUX1",
+		.min_uV = 1800000,
+		.max_uV = 2850000,
+		.table_len = ARRAY_SIZE(VAUX1_VSEL_table),
+		.table = VAUX1_VSEL_table,
+	},
+	{
+		.name = "VAUX2",
+		.min_uV = 1800000,
+		.max_uV = 3300000,
+		.table_len = ARRAY_SIZE(VAUX2_VSEL_table),
+		.table = VAUX2_VSEL_table,
+	},
+	{
+		.name = "VAUX33",
+		.min_uV = 1800000,
+		.max_uV = 3300000,
+		.table_len = ARRAY_SIZE(VAUX33_VSEL_table),
+		.table = VAUX33_VSEL_table,
+	},
+	{
+		.name = "VMMC",
+		.min_uV = 1800000,
+		.max_uV = 3300000,
+		.table_len = ARRAY_SIZE(VMMC_VSEL_table),
+		.table = VMMC_VSEL_table,
+	},
+};
+
+static struct tps_info tps65911_regs[] = {
+	{
+		.name = "VIO",
+		.min_uV = 1500000,
+		.max_uV = 3300000,
+		.table_len = ARRAY_SIZE(VIO_VSEL_table),
+		.table = VIO_VSEL_table,
+	},
+	{
+		.name = "VDD1",
+		.min_uV = 600000,
+		.max_uV = 4500000,
+	},
+	{
+		.name = "VDD2",
+		.min_uV = 600000,
+		.max_uV = 4500000,
+	},
+	{
+		.name = "VDDCTRL",
+		.min_uV = 600000,
+		.max_uV = 1400000,
+	},
+	{
+		.name = "LDO1",
+		.min_uV = 1000000,
+		.max_uV = 3300000,
+	},
+	{
+		.name = "LDO2",
+		.min_uV = 1000000,
+		.max_uV = 3300000,
+	},
+	{
+		.name = "LDO3",
+		.min_uV = 1000000,
+		.max_uV = 3300000,
+	},
+	{
+		.name = "LDO4",
+		.min_uV = 1000000,
+		.max_uV = 3300000,
+	},
+	{
+		.name = "LDO5",
+		.min_uV = 1000000,
+		.max_uV = 3300000,
+	},
+	{
+		.name = "LDO6",
+		.min_uV = 1000000,
+		.max_uV = 3300000,
+	},
+	{
+		.name = "LDO7",
+		.min_uV = 1000000,
+		.max_uV = 3300000,
+	},
+	{
+		.name = "LDO8",
+		.min_uV = 1000000,
+		.max_uV = 3300000,
+	},
+};
+
+struct tps65910_reg {
+	struct regulator_desc desc[TPS65910_NUM_REGULATOR];
+	struct tps65910 *mfd;
+	struct regulator_dev *rdev[TPS65910_NUM_REGULATOR];
+	struct tps_info *info[TPS65910_NUM_REGULATOR];
+	struct mutex mutex;
+	int mode;
+	int  (*get_ctrl_reg)(int);
+};
+
+static inline int tps65910_read(struct tps65910_reg *pmic, u8 reg)
+{
+	u8 val;
+	int err;
+
+	err = pmic->mfd->read(pmic->mfd, reg, 1, &val);
+	if (err)
+		return err;
+
+	return val;
+}
+
+static inline int tps65910_write(struct tps65910_reg *pmic, u8 reg, u8 val)
+{
+	return pmic->mfd->write(pmic->mfd, reg, 1, &val);
+}
+
+static int tps65910_modify_bits(struct tps65910_reg *pmic, u8 reg,
+					u8 set_mask, u8 clear_mask)
+{
+	int err, data;
+
+	mutex_lock(&pmic->mutex);
+
+	data = tps65910_read(pmic, reg);
+	if (data < 0) {
+		dev_err(pmic->mfd->dev, "Read from reg 0x%x failed\n", reg);
+		err = data;
+		goto out;
+	}
+
+	data &= ~clear_mask;
+	data |= set_mask;
+	err = tps65910_write(pmic, reg, data);
+	if (err)
+		dev_err(pmic->mfd->dev, "Write for reg 0x%x failed\n", reg);
+
+out:
+	mutex_unlock(&pmic->mutex);
+	return err;
+}
+
+static int tps65910_reg_read(struct tps65910_reg *pmic, u8 reg)
+{
+	int data;
+
+	mutex_lock(&pmic->mutex);
+
+	data = tps65910_read(pmic, reg);
+	if (data < 0)
+		dev_err(pmic->mfd->dev, "Read from reg 0x%x failed\n", reg);
+
+	mutex_unlock(&pmic->mutex);
+	return data;
+}
+
+static int tps65910_reg_write(struct tps65910_reg *pmic, u8 reg, u8 val)
+{
+	int err;
+
+	mutex_lock(&pmic->mutex);
+
+	err = tps65910_write(pmic, reg, val);
+	if (err < 0)
+		dev_err(pmic->mfd->dev, "Write for reg 0x%x failed\n", reg);
+
+	mutex_unlock(&pmic->mutex);
+	return err;
+}
+
+static int tps65910_get_ctrl_register(int id)
+{
+	switch (id) {
+	case TPS65910_REG_VRTC:
+		return TPS65910_VRTC;
+	case TPS65910_REG_VIO:
+		return TPS65910_VIO;
+	case TPS65910_REG_VDD1:
+		return TPS65910_VDD1;
+	case TPS65910_REG_VDD2:
+		return TPS65910_VDD2;
+	case TPS65910_REG_VDD3:
+		return TPS65910_VDD3;
+	case TPS65910_REG_VDIG1:
+		return TPS65910_VDIG1;
+	case TPS65910_REG_VDIG2:
+		return TPS65910_VDIG2;
+	case TPS65910_REG_VPLL:
+		return TPS65910_VPLL;
+	case TPS65910_REG_VDAC:
+		return TPS65910_VDAC;
+	case TPS65910_REG_VAUX1:
+		return TPS65910_VAUX1;
+	case TPS65910_REG_VAUX2:
+		return TPS65910_VAUX2;
+	case TPS65910_REG_VAUX33:
+		return TPS65910_VAUX33;
+	case TPS65910_REG_VMMC:
+		return TPS65910_VMMC;
+	default:
+		return -EINVAL;
+	}
+}
+
+static int tps65911_get_ctrl_register(int id)
+{
+	switch (id) {
+	case TPS65910_REG_VRTC:
+		return TPS65910_VRTC;
+	case TPS65910_REG_VIO:
+		return TPS65910_VIO;
+	case TPS65910_REG_VDD1:
+		return TPS65910_VDD1;
+	case TPS65910_REG_VDD2:
+		return TPS65910_VDD2;
+	case TPS65911_REG_VDDCTRL:
+		return TPS65911_VDDCTRL;
+	case TPS65911_REG_LDO1:
+		return TPS65911_LDO1;
+	case TPS65911_REG_LDO2:
+		return TPS65911_LDO2;
+	case TPS65911_REG_LDO3:
+		return TPS65911_LDO3;
+	case TPS65911_REG_LDO4:
+		return TPS65911_LDO4;
+	case TPS65911_REG_LDO5:
+		return TPS65911_LDO5;
+	case TPS65911_REG_LDO6:
+		return TPS65911_LDO6;
+	case TPS65911_REG_LDO7:
+		return TPS65911_LDO7;
+	case TPS65911_REG_LDO8:
+		return TPS65911_LDO8;
+	default:
+		return -EINVAL;
+	}
+}
+
+static int tps65910_is_enabled(struct regulator_dev *dev)
+{
+	struct tps65910_reg *pmic = rdev_get_drvdata(dev);
+	int reg, value, id = rdev_get_id(dev);
+
+	reg = pmic->get_ctrl_reg(id);
+	if (reg < 0)
+		return reg;
+
+	value = tps65910_reg_read(pmic, reg);
+	if (value < 0)
+		return value;
+
+	return value & TPS65910_SUPPLY_STATE_ENABLED;
+}
+
+static int tps65910_enable(struct regulator_dev *dev)
+{
+	struct tps65910_reg *pmic = rdev_get_drvdata(dev);
+	struct tps65910 *mfd = pmic->mfd;
+	int reg, id = rdev_get_id(dev);
+
+	reg = pmic->get_ctrl_reg(id);
+	if (reg < 0)
+		return reg;
+
+	return tps65910_set_bits(mfd, reg, TPS65910_SUPPLY_STATE_ENABLED);
+}
+
+static int tps65910_disable(struct regulator_dev *dev)
+{
+	struct tps65910_reg *pmic = rdev_get_drvdata(dev);
+	struct tps65910 *mfd = pmic->mfd;
+	int reg, id = rdev_get_id(dev);
+
+	reg = pmic->get_ctrl_reg(id);
+	if (reg < 0)
+		return reg;
+
+	return tps65910_clear_bits(mfd, reg, TPS65910_SUPPLY_STATE_ENABLED);
+}
+
+
+static int tps65910_set_mode(struct regulator_dev *dev, unsigned int mode)
+{
+	struct tps65910_reg *pmic = rdev_get_drvdata(dev);
+	struct tps65910 *mfd = pmic->mfd;
+	int reg, value, id = rdev_get_id(dev);
+
+	reg = pmic->get_ctrl_reg(id);
+	if (reg < 0)
+		return reg;
+
+	switch (mode) {
+	case REGULATOR_MODE_NORMAL:
+		return tps65910_modify_bits(pmic, reg, LDO_ST_ON_BIT,
+							LDO_ST_MODE_BIT);
+	case REGULATOR_MODE_IDLE:
+		value = LDO_ST_ON_BIT | LDO_ST_MODE_BIT;
+		return tps65910_set_bits(mfd, reg, value);
+	case REGULATOR_MODE_STANDBY:
+		return tps65910_clear_bits(mfd, reg, LDO_ST_ON_BIT);
+	}
+
+	return -EINVAL;
+}
+
+static unsigned int tps65910_get_mode(struct regulator_dev *dev)
+{
+	struct tps65910_reg *pmic = rdev_get_drvdata(dev);
+	int reg, value, id = rdev_get_id(dev);
+
+	reg = pmic->get_ctrl_reg(id);
+	if (reg < 0)
+		return reg;
+
+	value = tps65910_reg_read(pmic, reg);
+	if (value < 0)
+		return value;
+
+	if (value & LDO_ST_ON_BIT)
+		return REGULATOR_MODE_STANDBY;
+	else if (value & LDO_ST_MODE_BIT)
+		return REGULATOR_MODE_IDLE;
+	else
+		return REGULATOR_MODE_NORMAL;
+}
+
+static int tps65910_get_voltage_dcdc(struct regulator_dev *dev)
+{
+	struct tps65910_reg *pmic = rdev_get_drvdata(dev);
+	int id = rdev_get_id(dev), voltage = 0;
+	int opvsel = 0, srvsel = 0, vselmax = 0, mult = 0, sr = 0;
+
+	switch (id) {
+	case TPS65910_REG_VDD1:
+		opvsel = tps65910_reg_read(pmic, TPS65910_VDD1_OP);
+		mult = tps65910_reg_read(pmic, TPS65910_VDD1);
+		mult = (mult & VDD1_VGAIN_SEL_MASK) >> VDD1_VGAIN_SEL_SHIFT;
+		srvsel = tps65910_reg_read(pmic, TPS65910_VDD1_SR);
+		sr = opvsel & VDD1_OP_CMD_MASK;
+		opvsel &= VDD1_OP_SEL_MASK;
+		srvsel &= VDD1_SR_SEL_MASK;
+		vselmax = 75;
+		break;
+	case TPS65910_REG_VDD2:
+		opvsel = tps65910_reg_read(pmic, TPS65910_VDD2_OP);
+		mult = tps65910_reg_read(pmic, TPS65910_VDD2);
+		mult = (mult & VDD2_VGAIN_SEL_MASK) >> VDD2_VGAIN_SEL_SHIFT;
+		srvsel = tps65910_reg_read(pmic, TPS65910_VDD2_SR);
+		sr = opvsel & VDD2_OP_CMD_MASK;
+		opvsel &= VDD2_OP_SEL_MASK;
+		srvsel &= VDD2_SR_SEL_MASK;
+		vselmax = 75;
+		break;
+	case TPS65911_REG_VDDCTRL:
+		opvsel = tps65910_reg_read(pmic, TPS65911_VDDCTRL_OP);
+		srvsel = tps65910_reg_read(pmic, TPS65911_VDDCTRL_SR);
+		sr = opvsel & VDDCTRL_OP_CMD_MASK;
+		opvsel &= VDDCTRL_OP_SEL_MASK;
+		srvsel &= VDDCTRL_SR_SEL_MASK;
+		vselmax = 64;
+		break;
+	}
+
+	/* multiplier 0 == 1 but 2,3 normal */
+	if (!mult)
+		mult=1;
+
+	if (sr) {
+		/* normalise to valid range */
+		if (srvsel < 3)
+			srvsel = 3;
+		if (srvsel > vselmax)
+			srvsel = vselmax;
+		srvsel -= 3;
+
+		voltage = (srvsel * VDD1_2_OFFSET + VDD1_2_MIN_VOLT) * 100;
+	} else {
+
+		/* normalise to valid range*/
+		if (opvsel < 3)
+			opvsel = 3;
+		if (opvsel > vselmax)
+			opvsel = vselmax;
+		opvsel -= 3;
+
+		voltage = (opvsel * VDD1_2_OFFSET + VDD1_2_MIN_VOLT) * 100;
+	}
+
+	voltage *= mult;
+
+	return voltage;
+}
+
+static int tps65910_get_voltage(struct regulator_dev *dev)
+{
+	struct tps65910_reg *pmic = rdev_get_drvdata(dev);
+	int reg, value, id = rdev_get_id(dev), voltage = 0;
+
+	reg = pmic->get_ctrl_reg(id);
+	if (reg < 0)
+		return reg;
+
+	value = tps65910_reg_read(pmic, reg);
+	if (value < 0)
+		return value;
+
+	switch (id) {
+	case TPS65910_REG_VIO:
+	case TPS65910_REG_VDIG1:
+	case TPS65910_REG_VDIG2:
+	case TPS65910_REG_VPLL:
+	case TPS65910_REG_VDAC:
+	case TPS65910_REG_VAUX1:
+	case TPS65910_REG_VAUX2:
+	case TPS65910_REG_VAUX33:
+	case TPS65910_REG_VMMC:
+		value &= LDO_SEL_MASK;
+		value >>= LDO_SEL_SHIFT;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	voltage = pmic->info[id]->table[value] * 1000;
+
+	return voltage;
+}
+
+static int tps65910_get_voltage_vdd3(struct regulator_dev *dev)
+{
+	return 5 * 1000 * 1000;
+}
+
+static int tps65911_get_voltage(struct regulator_dev *dev)
+{
+	struct tps65910_reg *pmic = rdev_get_drvdata(dev);
+	int step_mv, id = rdev_get_id(dev);
+	u8 value, reg;
+
+	reg = pmic->get_ctrl_reg(id);
+
+	value = tps65910_reg_read(pmic, reg);
+
+	switch (id) {
+	case TPS65911_REG_LDO1:
+	case TPS65911_REG_LDO2:
+	case TPS65911_REG_LDO4:
+		value &= LDO1_SEL_MASK;
+		value >>= LDO_SEL_SHIFT;
+		/* The first 5 values of the selector correspond to 1V */
+		if (value < 5)
+			value = 0;
+		else
+			value -= 4;
+
+		step_mv = 50;
+		break;
+	case TPS65911_REG_LDO3:
+	case TPS65911_REG_LDO5:
+	case TPS65911_REG_LDO6:
+	case TPS65911_REG_LDO7:
+	case TPS65911_REG_LDO8:
+		value &= LDO3_SEL_MASK;
+		value >>= LDO_SEL_SHIFT;
+		/* The first 3 values of the selector correspond to 1V */
+		if (value < 3)
+			value = 0;
+		else
+			value -= 2;
+
+		step_mv = 100;
+		break;
+	case TPS65910_REG_VIO:
+		return pmic->info[id]->table[value] * 1000;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return (LDO_MIN_VOLT + value * step_mv) * 1000;
+}
+
+static int tps65910_set_voltage_dcdc(struct regulator_dev *dev,
+				unsigned selector)
+{
+	struct tps65910_reg *pmic = rdev_get_drvdata(dev);
+	int id = rdev_get_id(dev), vsel;
+	int dcdc_mult = 0;
+
+	switch (id) {
+	case TPS65910_REG_VDD1:
+		dcdc_mult = (selector / VDD1_2_NUM_VOLTS) + 1;
+		if (dcdc_mult == 1)
+			dcdc_mult--;
+		vsel = (selector % VDD1_2_NUM_VOLTS) + 3;
+
+		tps65910_modify_bits(pmic, TPS65910_VDD1,
+				(dcdc_mult << VDD1_VGAIN_SEL_SHIFT),
+						VDD1_VGAIN_SEL_MASK);
+		tps65910_reg_write(pmic, TPS65910_VDD1_OP, vsel);
+		break;
+	case TPS65910_REG_VDD2:
+		dcdc_mult = (selector / VDD1_2_NUM_VOLTS) + 1;
+		if (dcdc_mult == 1)
+			dcdc_mult--;
+		vsel = (selector % VDD1_2_NUM_VOLTS) + 3;
+
+		tps65910_modify_bits(pmic, TPS65910_VDD2,
+				(dcdc_mult << VDD2_VGAIN_SEL_SHIFT),
+						VDD1_VGAIN_SEL_MASK);
+		tps65910_reg_write(pmic, TPS65910_VDD2_OP, vsel);
+		break;
+	case TPS65911_REG_VDDCTRL:
+		vsel = selector;
+		tps65910_reg_write(pmic, TPS65911_VDDCTRL_OP, vsel);
+	}
+
+	return 0;
+}
+
+static int tps65910_set_voltage(struct regulator_dev *dev, unsigned selector)
+{
+	struct tps65910_reg *pmic = rdev_get_drvdata(dev);
+	int reg, id = rdev_get_id(dev);
+
+	reg = pmic->get_ctrl_reg(id);
+	if (reg < 0)
+		return reg;
+
+	switch (id) {
+	case TPS65910_REG_VIO:
+	case TPS65910_REG_VDIG1:
+	case TPS65910_REG_VDIG2:
+	case TPS65910_REG_VPLL:
+	case TPS65910_REG_VDAC:
+	case TPS65910_REG_VAUX1:
+	case TPS65910_REG_VAUX2:
+	case TPS65910_REG_VAUX33:
+	case TPS65910_REG_VMMC:
+		return tps65910_modify_bits(pmic, reg,
+				(selector << LDO_SEL_SHIFT), LDO_SEL_MASK);
+	}
+
+	return -EINVAL;
+}
+
+static int tps65911_set_voltage(struct regulator_dev *dev, unsigned selector)
+{
+	struct tps65910_reg *pmic = rdev_get_drvdata(dev);
+	int reg, id = rdev_get_id(dev);
+
+	reg = pmic->get_ctrl_reg(id);
+	if (reg < 0)
+		return reg;
+
+	switch (id) {
+	case TPS65911_REG_LDO1:
+	case TPS65911_REG_LDO2:
+	case TPS65911_REG_LDO4:
+		return tps65910_modify_bits(pmic, reg,
+				(selector << LDO_SEL_SHIFT), LDO1_SEL_MASK);
+	case TPS65911_REG_LDO3:
+	case TPS65911_REG_LDO5:
+	case TPS65911_REG_LDO6:
+	case TPS65911_REG_LDO7:
+	case TPS65911_REG_LDO8:
+	case TPS65910_REG_VIO:
+		return tps65910_modify_bits(pmic, reg,
+				(selector << LDO_SEL_SHIFT), LDO3_SEL_MASK);
+	}
+
+	return -EINVAL;
+}
+
+
+static int tps65910_list_voltage_dcdc(struct regulator_dev *dev,
+					unsigned selector)
+{
+	int volt, mult = 1, id = rdev_get_id(dev);
+
+	switch (id) {
+	case TPS65910_REG_VDD1:
+	case TPS65910_REG_VDD2:
+		mult = (selector / VDD1_2_NUM_VOLTS) + 1;
+		volt = VDD1_2_MIN_VOLT +
+				(selector % VDD1_2_NUM_VOLTS) * VDD1_2_OFFSET;
+	case TPS65911_REG_VDDCTRL:
+		volt = VDDCTRL_MIN_VOLT + (selector * VDDCTRL_OFFSET);
+	}
+
+	return  volt * 100 * mult;
+}
+
+static int tps65910_list_voltage(struct regulator_dev *dev,
+					unsigned selector)
+{
+	struct tps65910_reg *pmic = rdev_get_drvdata(dev);
+	int id = rdev_get_id(dev), voltage;
+
+	if (id < TPS65910_REG_VIO || id > TPS65910_REG_VMMC)
+		return -EINVAL;
+
+	if (selector >= pmic->info[id]->table_len)
+		return -EINVAL;
+	else
+		voltage = pmic->info[id]->table[selector] * 1000;
+
+	return voltage;
+}
+
+static int tps65911_list_voltage(struct regulator_dev *dev, unsigned selector)
+{
+	struct tps65910_reg *pmic = rdev_get_drvdata(dev);
+	int step_mv = 0, id = rdev_get_id(dev);
+
+	switch(id) {
+	case TPS65911_REG_LDO1:
+	case TPS65911_REG_LDO2:
+	case TPS65911_REG_LDO4:
+		/* The first 5 values of the selector correspond to 1V */
+		if (selector < 5)
+			selector = 0;
+		else
+			selector -= 4;
+
+		step_mv = 50;
+		break;
+	case TPS65911_REG_LDO3:
+	case TPS65911_REG_LDO5:
+	case TPS65911_REG_LDO6:
+	case TPS65911_REG_LDO7:
+	case TPS65911_REG_LDO8:
+		/* The first 3 values of the selector correspond to 1V */
+		if (selector < 3)
+			selector = 0;
+		else
+			selector -= 2;
+
+		step_mv = 100;
+		break;
+	case TPS65910_REG_VIO:
+		return pmic->info[id]->table[selector] * 1000;
+	default:
+		return -EINVAL;
+	}
+
+	return (LDO_MIN_VOLT + selector * step_mv) * 1000;
+}
+
+/* Regulator ops (except VRTC) */
+static struct regulator_ops tps65910_ops_dcdc = {
+	.is_enabled		= tps65910_is_enabled,
+	.enable			= tps65910_enable,
+	.disable		= tps65910_disable,
+	.set_mode		= tps65910_set_mode,
+	.get_mode		= tps65910_get_mode,
+	.get_voltage		= tps65910_get_voltage_dcdc,
+	.set_voltage_sel	= tps65910_set_voltage_dcdc,
+	.list_voltage		= tps65910_list_voltage_dcdc,
+};
+
+static struct regulator_ops tps65910_ops_vdd3 = {
+	.is_enabled		= tps65910_is_enabled,
+	.enable			= tps65910_enable,
+	.disable		= tps65910_disable,
+	.set_mode		= tps65910_set_mode,
+	.get_mode		= tps65910_get_mode,
+	.get_voltage		= tps65910_get_voltage_vdd3,
+	.list_voltage		= tps65910_list_voltage,
+};
+
+static struct regulator_ops tps65910_ops = {
+	.is_enabled		= tps65910_is_enabled,
+	.enable			= tps65910_enable,
+	.disable		= tps65910_disable,
+	.set_mode		= tps65910_set_mode,
+	.get_mode		= tps65910_get_mode,
+	.get_voltage		= tps65910_get_voltage,
+	.set_voltage_sel	= tps65910_set_voltage,
+	.list_voltage		= tps65910_list_voltage,
+};
+
+static struct regulator_ops tps65911_ops = {
+	.is_enabled		= tps65910_is_enabled,
+	.enable			= tps65910_enable,
+	.disable		= tps65910_disable,
+	.set_mode		= tps65910_set_mode,
+	.get_mode		= tps65910_get_mode,
+	.get_voltage		= tps65911_get_voltage,
+	.set_voltage_sel	= tps65911_set_voltage,
+	.list_voltage		= tps65911_list_voltage,
+};
+
+static __devinit int tps65910_probe(struct platform_device *pdev)
+{
+	struct tps65910 *tps65910 = dev_get_drvdata(pdev->dev.parent);
+	struct tps_info *info;
+	struct regulator_init_data *reg_data;
+	struct regulator_dev *rdev;
+	struct tps65910_reg *pmic;
+	struct tps65910_board *pmic_plat_data;
+	int i, err;
+
+	pmic_plat_data = dev_get_platdata(tps65910->dev);
+	if (!pmic_plat_data)
+		return -EINVAL;
+
+	reg_data = pmic_plat_data->tps65910_pmic_init_data;
+
+	pmic = kzalloc(sizeof(*pmic), GFP_KERNEL);
+	if (!pmic)
+		return -ENOMEM;
+
+	mutex_init(&pmic->mutex);
+	pmic->mfd = tps65910;
+	platform_set_drvdata(pdev, pmic);
+
+	/* Give control of all register to control port */
+	tps65910_set_bits(pmic->mfd, TPS65910_DEVCTRL,
+				DEVCTRL_SR_CTL_I2C_SEL_MASK);
+
+	switch(tps65910_chip_id(tps65910)) {
+	case TPS65910:
+		pmic->get_ctrl_reg = &tps65910_get_ctrl_register;
+		info = tps65910_regs;
+	case TPS65911:
+		pmic->get_ctrl_reg = &tps65911_get_ctrl_register;
+		info = tps65911_regs;
+	default:
+		pr_err("Invalid tps chip version\n");
+		return -ENODEV;
+	}
+
+	for (i = 0; i < TPS65910_NUM_REGULATOR; i++, info++, reg_data++) {
+		/* Register the regulators */
+		pmic->info[i] = info;
+
+		pmic->desc[i].name = info->name;
+		pmic->desc[i].id = i;
+		pmic->desc[i].n_voltages = info->table_len;
+
+		if (i == TPS65910_REG_VDD1 || i == TPS65910_REG_VDD2) {
+			pmic->desc[i].ops = &tps65910_ops_dcdc;
+		} else if (i == TPS65910_REG_VDD3) {
+			if (tps65910_chip_id(tps65910) == TPS65910)
+				pmic->desc[i].ops = &tps65910_ops_vdd3;
+			else
+				pmic->desc[i].ops = &tps65910_ops_dcdc;
+		} else {
+			if (tps65910_chip_id(tps65910) == TPS65910)
+				pmic->desc[i].ops = &tps65910_ops;
+			else
+				pmic->desc[i].ops = &tps65911_ops;
+		}
+
+		pmic->desc[i].type = REGULATOR_VOLTAGE;
+		pmic->desc[i].owner = THIS_MODULE;
+
+		rdev = regulator_register(&pmic->desc[i],
+				tps65910->dev, reg_data, pmic);
+		if (IS_ERR(rdev)) {
+			dev_err(tps65910->dev,
+				"failed to register %s regulator\n",
+				pdev->name);
+			err = PTR_ERR(rdev);
+			goto err;
+		}
+
+		/* Save regulator for cleanup */
+		pmic->rdev[i] = rdev;
+	}
+	return 0;
+
+err:
+	while (--i >= 0)
+		regulator_unregister(pmic->rdev[i]);
+
+	kfree(pmic);
+	return err;
+}
+
+static int __devexit tps65910_remove(struct platform_device *pdev)
+{
+	struct tps65910_reg *tps65910_reg = platform_get_drvdata(pdev);
+	int i;
+
+	for (i = 0; i < TPS65910_NUM_REGULATOR; i++)
+		regulator_unregister(tps65910_reg->rdev[i]);
+
+	kfree(tps65910_reg);
+	return 0;
+}
+
+static struct platform_driver tps65910_driver = {
+	.driver = {
+		.name = "tps65910-pmic",
+		.owner = THIS_MODULE,
+	},
+	.probe = tps65910_probe,
+	.remove = __devexit_p(tps65910_remove),
+};
+
+static int __init tps65910_init(void)
+{
+	return platform_driver_register(&tps65910_driver);
+}
+subsys_initcall(tps65910_init);
+
+static void __exit tps65910_cleanup(void)
+{
+	platform_driver_unregister(&tps65910_driver);
+}
+module_exit(tps65910_cleanup);
+
+MODULE_AUTHOR("Graeme Gregory <gg@slimlogic.co.uk>");
+MODULE_DESCRIPTION("TPS6507x voltage regulator driver");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:tps65910-pmic");
diff -druN linux-2.6.39-libre/drivers/regulator/twl-regulator.c linux-3.0-rc7-libre/drivers/regulator/twl-regulator.c
--- linux-2.6.39-libre/drivers/regulator/twl-regulator.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/regulator/twl-regulator.c	2011-07-11 19:51:52.000000000 -0400
@@ -51,8 +51,13 @@
 	u16			min_mV;
 	u16			max_mV;
 
+	u8			flags;
+
 	/* used by regulator core */
 	struct regulator_desc	desc;
+
+	/* chip specific features */
+	unsigned long 		features;
 };
 
 
@@ -70,12 +75,35 @@
 #define VREG_TRANS		1
 #define VREG_STATE		2
 #define VREG_VOLTAGE		3
+#define VREG_VOLTAGE_SMPS	4
 /* TWL6030 Misc register offsets */
 #define VREG_BC_ALL		1
 #define VREG_BC_REF		2
 #define VREG_BC_PROC		3
 #define VREG_BC_CLK_RST		4
 
+/* TWL6030 LDO register values for CFG_STATE */
+#define TWL6030_CFG_STATE_OFF	0x00
+#define TWL6030_CFG_STATE_ON	0x01
+#define TWL6030_CFG_STATE_OFF2	0x02
+#define TWL6030_CFG_STATE_SLEEP	0x03
+#define TWL6030_CFG_STATE_GRP_SHIFT	5
+#define TWL6030_CFG_STATE_APP_SHIFT	2
+#define TWL6030_CFG_STATE_APP_MASK	(0x03 << TWL6030_CFG_STATE_APP_SHIFT)
+#define TWL6030_CFG_STATE_APP(v)	(((v) & TWL6030_CFG_STATE_APP_MASK) >>\
+						TWL6030_CFG_STATE_APP_SHIFT)
+
+/* Flags for SMPS Voltage reading */
+#define SMPS_OFFSET_EN		BIT(0)
+#define SMPS_EXTENDED_EN	BIT(1)
+
+/* twl6025 SMPS EPROM values */
+#define TWL6030_SMPS_OFFSET		0xB0
+#define TWL6030_SMPS_MULT		0xB3
+#define SMPS_MULTOFFSET_SMPS4	BIT(0)
+#define SMPS_MULTOFFSET_VIO	BIT(1)
+#define SMPS_MULTOFFSET_SMPS3	BIT(6)
+
 static inline int
 twlreg_read(struct twlreg_info *info, unsigned slave_subgp, unsigned offset)
 {
@@ -118,21 +146,38 @@
 #define P2_GRP_6030	BIT(1)		/* "peripherals" */
 #define P1_GRP_6030	BIT(0)		/* CPU/Linux */
 
-static int twlreg_is_enabled(struct regulator_dev *rdev)
+static int twl4030reg_is_enabled(struct regulator_dev *rdev)
 {
 	int	state = twlreg_grp(rdev);
 
 	if (state < 0)
 		return state;
 
-	if (twl_class_is_4030())
-		state &= P1_GRP_4030;
+	return state & P1_GRP_4030;
+}
+
+static int twl6030reg_is_enabled(struct regulator_dev *rdev)
+{
+	struct twlreg_info	*info = rdev_get_drvdata(rdev);
+	int			grp = 0, val;
+
+	if (!(twl_class_is_6030() && (info->features & TWL6025_SUBCLASS)))
+		grp = twlreg_read(info, TWL_MODULE_PM_RECEIVER, VREG_GRP);
+	if (grp < 0)
+		return grp;
+
+	if (!(twl_class_is_6030() && (info->features & TWL6025_SUBCLASS)))
+		grp &= P1_GRP_6030;
 	else
-		state &= P1_GRP_6030;
-	return state;
+		grp = 1;
+
+	val = twlreg_read(info, TWL_MODULE_PM_RECEIVER, VREG_STATE);
+	val = TWL6030_CFG_STATE_APP(val);
+
+	return grp && (val == TWL6030_CFG_STATE_ON);
 }
 
-static int twlreg_enable(struct regulator_dev *rdev)
+static int twl4030reg_enable(struct regulator_dev *rdev)
 {
 	struct twlreg_info	*info = rdev_get_drvdata(rdev);
 	int			grp;
@@ -142,10 +187,7 @@
 	if (grp < 0)
 		return grp;
 
-	if (twl_class_is_4030())
-		grp |= P1_GRP_4030;
-	else
-		grp |= P1_GRP_6030;
+	grp |= P1_GRP_4030;
 
 	ret = twlreg_write(info, TWL_MODULE_PM_RECEIVER, VREG_GRP, grp);
 
@@ -154,29 +196,63 @@
 	return ret;
 }
 
-static int twlreg_disable(struct regulator_dev *rdev)
+static int twl6030reg_enable(struct regulator_dev *rdev)
+{
+	struct twlreg_info	*info = rdev_get_drvdata(rdev);
+	int			grp = 0;
+	int			ret;
+
+	if (!(twl_class_is_6030() && (info->features & TWL6025_SUBCLASS)))
+		grp = twlreg_read(info, TWL_MODULE_PM_RECEIVER, VREG_GRP);
+	if (grp < 0)
+		return grp;
+
+	ret = twlreg_write(info, TWL_MODULE_PM_RECEIVER, VREG_STATE,
+			grp << TWL6030_CFG_STATE_GRP_SHIFT |
+			TWL6030_CFG_STATE_ON);
+
+	udelay(info->delay);
+
+	return ret;
+}
+
+static int twl4030reg_disable(struct regulator_dev *rdev)
 {
 	struct twlreg_info	*info = rdev_get_drvdata(rdev);
 	int			grp;
+	int			ret;
 
 	grp = twlreg_read(info, TWL_MODULE_PM_RECEIVER, VREG_GRP);
 	if (grp < 0)
 		return grp;
 
-	if (twl_class_is_4030())
-		grp &= ~(P1_GRP_4030 | P2_GRP_4030 | P3_GRP_4030);
-	else
-		grp &= ~(P1_GRP_6030 | P2_GRP_6030 | P3_GRP_6030);
+	grp &= ~(P1_GRP_4030 | P2_GRP_4030 | P3_GRP_4030);
 
-	return twlreg_write(info, TWL_MODULE_PM_RECEIVER, VREG_GRP, grp);
+	ret = twlreg_write(info, TWL_MODULE_PM_RECEIVER, VREG_GRP, grp);
+
+	return ret;
 }
 
-static int twlreg_get_status(struct regulator_dev *rdev)
+static int twl6030reg_disable(struct regulator_dev *rdev)
 {
-	int	state = twlreg_grp(rdev);
+	struct twlreg_info	*info = rdev_get_drvdata(rdev);
+	int			grp = 0;
+	int			ret;
 
-	if (twl_class_is_6030())
-		return 0; /* FIXME return for 6030 regulator */
+	if (!(twl_class_is_6030() && (info->features & TWL6025_SUBCLASS)))
+		grp = P1_GRP_6030 | P2_GRP_6030 | P3_GRP_6030;
+
+	/* For 6030, set the off state for all grps enabled */
+	ret = twlreg_write(info, TWL_MODULE_PM_RECEIVER, VREG_STATE,
+			(grp) << TWL6030_CFG_STATE_GRP_SHIFT |
+			TWL6030_CFG_STATE_OFF);
+
+	return ret;
+}
+
+static int twl4030reg_get_status(struct regulator_dev *rdev)
+{
+	int	state = twlreg_grp(rdev);
 
 	if (state < 0)
 		return state;
@@ -190,15 +266,39 @@
 		: REGULATOR_STATUS_STANDBY;
 }
 
-static int twlreg_set_mode(struct regulator_dev *rdev, unsigned mode)
+static int twl6030reg_get_status(struct regulator_dev *rdev)
+{
+	struct twlreg_info	*info = rdev_get_drvdata(rdev);
+	int			val;
+
+	val = twlreg_grp(rdev);
+	if (val < 0)
+		return val;
+
+	val = twlreg_read(info, TWL_MODULE_PM_RECEIVER, VREG_STATE);
+
+	switch (TWL6030_CFG_STATE_APP(val)) {
+	case TWL6030_CFG_STATE_ON:
+		return REGULATOR_STATUS_NORMAL;
+
+	case TWL6030_CFG_STATE_SLEEP:
+		return REGULATOR_STATUS_STANDBY;
+
+	case TWL6030_CFG_STATE_OFF:
+	case TWL6030_CFG_STATE_OFF2:
+	default:
+		break;
+	}
+
+	return REGULATOR_STATUS_OFF;
+}
+
+static int twl4030reg_set_mode(struct regulator_dev *rdev, unsigned mode)
 {
 	struct twlreg_info	*info = rdev_get_drvdata(rdev);
 	unsigned		message;
 	int			status;
 
-	if (twl_class_is_6030())
-		return 0; /* FIXME return for 6030 regulator */
-
 	/* We can only set the mode through state machine commands... */
 	switch (mode) {
 	case REGULATOR_MODE_NORMAL:
@@ -227,6 +327,36 @@
 			message & 0xff, TWL4030_PM_MASTER_PB_WORD_LSB);
 }
 
+static int twl6030reg_set_mode(struct regulator_dev *rdev, unsigned mode)
+{
+	struct twlreg_info	*info = rdev_get_drvdata(rdev);
+	int grp = 0;
+	int val;
+
+	if (!(twl_class_is_6030() && (info->features & TWL6025_SUBCLASS)))
+		grp = twlreg_read(info, TWL_MODULE_PM_RECEIVER, VREG_GRP);
+
+	if (grp < 0)
+		return grp;
+
+	/* Compose the state register settings */
+	val = grp << TWL6030_CFG_STATE_GRP_SHIFT;
+	/* We can only set the mode through state machine commands... */
+	switch (mode) {
+	case REGULATOR_MODE_NORMAL:
+		val |= TWL6030_CFG_STATE_ON;
+		break;
+	case REGULATOR_MODE_STANDBY:
+		val |= TWL6030_CFG_STATE_SLEEP;
+		break;
+
+	default:
+		return -EINVAL;
+	}
+
+	return twlreg_write(info, TWL_MODULE_PM_RECEIVER, VREG_STATE, val);
+}
+
 /*----------------------------------------------------------------------*/
 
 /*
@@ -375,13 +505,13 @@
 	.set_voltage	= twl4030ldo_set_voltage,
 	.get_voltage	= twl4030ldo_get_voltage,
 
-	.enable		= twlreg_enable,
-	.disable	= twlreg_disable,
-	.is_enabled	= twlreg_is_enabled,
+	.enable		= twl4030reg_enable,
+	.disable	= twl4030reg_disable,
+	.is_enabled	= twl4030reg_is_enabled,
 
-	.set_mode	= twlreg_set_mode,
+	.set_mode	= twl4030reg_set_mode,
 
-	.get_status	= twlreg_get_status,
+	.get_status	= twl4030reg_get_status,
 };
 
 static int twl6030ldo_list_voltage(struct regulator_dev *rdev, unsigned index)
@@ -433,13 +563,13 @@
 	.set_voltage	= twl6030ldo_set_voltage,
 	.get_voltage	= twl6030ldo_get_voltage,
 
-	.enable		= twlreg_enable,
-	.disable	= twlreg_disable,
-	.is_enabled	= twlreg_is_enabled,
+	.enable		= twl6030reg_enable,
+	.disable	= twl6030reg_disable,
+	.is_enabled	= twl6030reg_is_enabled,
 
-	.set_mode	= twlreg_set_mode,
+	.set_mode	= twl6030reg_set_mode,
 
-	.get_status	= twlreg_get_status,
+	.get_status	= twl6030reg_get_status,
 };
 
 /*----------------------------------------------------------------------*/
@@ -461,25 +591,242 @@
 	return info->min_mV * 1000;
 }
 
-static struct regulator_ops twlfixed_ops = {
+static struct regulator_ops twl4030fixed_ops = {
 	.list_voltage	= twlfixed_list_voltage,
 
 	.get_voltage	= twlfixed_get_voltage,
 
-	.enable		= twlreg_enable,
-	.disable	= twlreg_disable,
-	.is_enabled	= twlreg_is_enabled,
+	.enable		= twl4030reg_enable,
+	.disable	= twl4030reg_disable,
+	.is_enabled	= twl4030reg_is_enabled,
 
-	.set_mode	= twlreg_set_mode,
+	.set_mode	= twl4030reg_set_mode,
 
-	.get_status	= twlreg_get_status,
+	.get_status	= twl4030reg_get_status,
+};
+
+static struct regulator_ops twl6030fixed_ops = {
+	.list_voltage	= twlfixed_list_voltage,
+
+	.get_voltage	= twlfixed_get_voltage,
+
+	.enable		= twl6030reg_enable,
+	.disable	= twl6030reg_disable,
+	.is_enabled	= twl6030reg_is_enabled,
+
+	.set_mode	= twl6030reg_set_mode,
+
+	.get_status	= twl6030reg_get_status,
 };
 
 static struct regulator_ops twl6030_fixed_resource = {
-	.enable		= twlreg_enable,
-	.disable	= twlreg_disable,
-	.is_enabled	= twlreg_is_enabled,
-	.get_status	= twlreg_get_status,
+	.enable		= twl6030reg_enable,
+	.disable	= twl6030reg_disable,
+	.is_enabled	= twl6030reg_is_enabled,
+	.get_status	= twl6030reg_get_status,
+};
+
+/*
+ * SMPS status and control
+ */
+
+static int twl6030smps_list_voltage(struct regulator_dev *rdev, unsigned index)
+{
+	struct twlreg_info	*info = rdev_get_drvdata(rdev);
+
+	int voltage = 0;
+
+	switch (info->flags) {
+	case SMPS_OFFSET_EN:
+		voltage = 100000;
+		/* fall through */
+	case 0:
+		switch (index) {
+		case 0:
+			voltage = 0;
+			break;
+		case 58:
+			voltage = 1350 * 1000;
+			break;
+		case 59:
+			voltage = 1500 * 1000;
+			break;
+		case 60:
+			voltage = 1800 * 1000;
+			break;
+		case 61:
+			voltage = 1900 * 1000;
+			break;
+		case 62:
+			voltage = 2100 * 1000;
+			break;
+		default:
+			voltage += (600000 + (12500 * (index - 1)));
+		}
+		break;
+	case SMPS_EXTENDED_EN:
+		switch (index) {
+		case 0:
+			voltage = 0;
+			break;
+		case 58:
+			voltage = 2084 * 1000;
+			break;
+		case 59:
+			voltage = 2315 * 1000;
+			break;
+		case 60:
+			voltage = 2778 * 1000;
+			break;
+		case 61:
+			voltage = 2932 * 1000;
+			break;
+		case 62:
+			voltage = 3241 * 1000;
+			break;
+		default:
+			voltage = (1852000 + (38600 * (index - 1)));
+		}
+		break;
+	case SMPS_OFFSET_EN | SMPS_EXTENDED_EN:
+		switch (index) {
+		case 0:
+			voltage = 0;
+			break;
+		case 58:
+			voltage = 4167 * 1000;
+			break;
+		case 59:
+			voltage = 2315 * 1000;
+			break;
+		case 60:
+			voltage = 2778 * 1000;
+			break;
+		case 61:
+			voltage = 2932 * 1000;
+			break;
+		case 62:
+			voltage = 3241 * 1000;
+			break;
+		default:
+			voltage = (2161000 + (38600 * (index - 1)));
+		}
+		break;
+	}
+
+	return voltage;
+}
+
+static int
+twl6030smps_set_voltage(struct regulator_dev *rdev, int min_uV, int max_uV,
+			unsigned int *selector)
+{
+	struct twlreg_info	*info = rdev_get_drvdata(rdev);
+	int	vsel = 0;
+
+	switch (info->flags) {
+	case 0:
+		if (min_uV == 0)
+			vsel = 0;
+		else if ((min_uV >= 600000) && (max_uV <= 1300000)) {
+			vsel = (min_uV - 600000) / 125;
+			if (vsel % 100)
+				vsel += 100;
+			vsel /= 100;
+			vsel++;
+		}
+		/* Values 1..57 for vsel are linear and can be calculated
+		 * values 58..62 are non linear.
+		 */
+		else if ((min_uV > 1900000) && (max_uV >= 2100000))
+			vsel = 62;
+		else if ((min_uV > 1800000) && (max_uV >= 1900000))
+			vsel = 61;
+		else if ((min_uV > 1500000) && (max_uV >= 1800000))
+			vsel = 60;
+		else if ((min_uV > 1350000) && (max_uV >= 1500000))
+			vsel = 59;
+		else if ((min_uV > 1300000) && (max_uV >= 1350000))
+			vsel = 58;
+		else
+			return -EINVAL;
+		break;
+	case SMPS_OFFSET_EN:
+		if (min_uV == 0)
+			vsel = 0;
+		else if ((min_uV >= 700000) && (max_uV <= 1420000)) {
+			vsel = (min_uV - 700000) / 125;
+			if (vsel % 100)
+				vsel += 100;
+			vsel /= 100;
+			vsel++;
+		}
+		/* Values 1..57 for vsel are linear and can be calculated
+		 * values 58..62 are non linear.
+		 */
+		else if ((min_uV > 1900000) && (max_uV >= 2100000))
+			vsel = 62;
+		else if ((min_uV > 1800000) && (max_uV >= 1900000))
+			vsel = 61;
+		else if ((min_uV > 1350000) && (max_uV >= 1800000))
+			vsel = 60;
+		else if ((min_uV > 1350000) && (max_uV >= 1500000))
+			vsel = 59;
+		else if ((min_uV > 1300000) && (max_uV >= 1350000))
+			vsel = 58;
+		else
+			return -EINVAL;
+		break;
+	case SMPS_EXTENDED_EN:
+		if (min_uV == 0)
+			vsel = 0;
+		else if ((min_uV >= 1852000) && (max_uV <= 4013600)) {
+			vsel = (min_uV - 1852000) / 386;
+			if (vsel % 100)
+				vsel += 100;
+			vsel /= 100;
+			vsel++;
+		}
+		break;
+	case SMPS_OFFSET_EN|SMPS_EXTENDED_EN:
+		if (min_uV == 0)
+			vsel = 0;
+		else if ((min_uV >= 2161000) && (max_uV <= 4321000)) {
+			vsel = (min_uV - 1852000) / 386;
+			if (vsel % 100)
+				vsel += 100;
+			vsel /= 100;
+			vsel++;
+		}
+		break;
+	}
+
+	*selector = vsel;
+
+	return twlreg_write(info, TWL_MODULE_PM_RECEIVER, VREG_VOLTAGE_SMPS,
+							vsel);
+}
+
+static int twl6030smps_get_voltage_sel(struct regulator_dev *rdev)
+{
+	struct twlreg_info	*info = rdev_get_drvdata(rdev);
+
+	return twlreg_read(info, TWL_MODULE_PM_RECEIVER, VREG_VOLTAGE_SMPS);
+}
+
+static struct regulator_ops twlsmps_ops = {
+	.list_voltage		= twl6030smps_list_voltage,
+
+	.set_voltage		= twl6030smps_set_voltage,
+	.get_voltage_sel	= twl6030smps_get_voltage_sel,
+
+	.enable			= twl6030reg_enable,
+	.disable		= twl6030reg_disable,
+	.is_enabled		= twl6030reg_is_enabled,
+
+	.set_mode		= twl6030reg_set_mode,
+
+	.get_status		= twl6030reg_get_status,
 };
 
 /*----------------------------------------------------------------------*/
@@ -487,11 +834,10 @@
 #define TWL4030_FIXED_LDO(label, offset, mVolts, num, turnon_delay, \
 			remap_conf) \
 		TWL_FIXED_LDO(label, offset, mVolts, num, turnon_delay, \
-			remap_conf, TWL4030)
-#define TWL6030_FIXED_LDO(label, offset, mVolts, num, turnon_delay, \
-			remap_conf) \
+			remap_conf, TWL4030, twl4030fixed_ops)
+#define TWL6030_FIXED_LDO(label, offset, mVolts, num, turnon_delay) \
 		TWL_FIXED_LDO(label, offset, mVolts, num, turnon_delay, \
-			remap_conf, TWL6030)
+			0x0, TWL6030, twl6030fixed_ops)
 
 #define TWL4030_ADJUSTABLE_LDO(label, offset, num, turnon_delay, remap_conf) { \
 	.base = offset, \
@@ -510,13 +856,11 @@
 		}, \
 	}
 
-#define TWL6030_ADJUSTABLE_LDO(label, offset, min_mVolts, max_mVolts, num, \
-		remap_conf) { \
+#define TWL6030_ADJUSTABLE_LDO(label, offset, min_mVolts, max_mVolts, num) { \
 	.base = offset, \
 	.id = num, \
 	.min_mV = min_mVolts, \
 	.max_mV = max_mVolts, \
-	.remap = remap_conf, \
 	.desc = { \
 		.name = #label, \
 		.id = TWL6030_REG_##label, \
@@ -527,9 +871,23 @@
 		}, \
 	}
 
+#define TWL6025_ADJUSTABLE_LDO(label, offset, min_mVolts, max_mVolts, num) { \
+	.base = offset, \
+	.id = num, \
+	.min_mV = min_mVolts, \
+	.max_mV = max_mVolts, \
+	.desc = { \
+		.name = #label, \
+		.id = TWL6025_REG_##label, \
+		.n_voltages = ((max_mVolts - min_mVolts)/100) + 1, \
+		.ops = &twl6030ldo_ops, \
+		.type = REGULATOR_VOLTAGE, \
+		.owner = THIS_MODULE, \
+		}, \
+	}
 
 #define TWL_FIXED_LDO(label, offset, mVolts, num, turnon_delay, remap_conf, \
-		family) { \
+		family, operations) { \
 	.base = offset, \
 	.id = num, \
 	.min_mV = mVolts, \
@@ -539,17 +897,16 @@
 		.name = #label, \
 		.id = family##_REG_##label, \
 		.n_voltages = 1, \
-		.ops = &twlfixed_ops, \
+		.ops = &operations, \
 		.type = REGULATOR_VOLTAGE, \
 		.owner = THIS_MODULE, \
 		}, \
 	}
 
-#define TWL6030_FIXED_RESOURCE(label, offset, num, turnon_delay, remap_conf) { \
+#define TWL6030_FIXED_RESOURCE(label, offset, num, turnon_delay) { \
 	.base = offset, \
 	.id = num, \
 	.delay = turnon_delay, \
-	.remap = remap_conf, \
 	.desc = { \
 		.name = #label, \
 		.id = TWL6030_REG_##label, \
@@ -559,6 +916,21 @@
 		}, \
 	}
 
+#define TWL6025_ADJUSTABLE_SMPS(label, offset, num) { \
+	.base = offset, \
+	.id = num, \
+	.min_mV = 600, \
+	.max_mV = 2100, \
+	.desc = { \
+		.name = #label, \
+		.id = TWL6025_REG_##label, \
+		.n_voltages = 63, \
+		.ops = &twlsmps_ops, \
+		.type = REGULATOR_VOLTAGE, \
+		.owner = THIS_MODULE, \
+		}, \
+	}
+
 /*
  * We list regulators here if systems need some level of
  * software control over them after boot.
@@ -589,19 +961,52 @@
 	/* 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, 1000, 3300, 1, 0x21),
-	TWL6030_ADJUSTABLE_LDO(VAUX2_6030, 0x58, 1000, 3300, 2, 0x21),
-	TWL6030_ADJUSTABLE_LDO(VAUX3_6030, 0x5c, 1000, 3300, 3, 0x21),
-	TWL6030_ADJUSTABLE_LDO(VMMC, 0x68, 1000, 3300, 4, 0x21),
-	TWL6030_ADJUSTABLE_LDO(VPP, 0x6c, 1000, 3300, 5, 0x21),
-	TWL6030_ADJUSTABLE_LDO(VUSIM, 0x74, 1000, 3300, 7, 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),
-	TWL6030_FIXED_RESOURCE(CLK32KG, 0x8C, 48, 0, 0x21),
+	TWL6030_ADJUSTABLE_LDO(VAUX1_6030, 0x54, 1000, 3300, 1),
+	TWL6030_ADJUSTABLE_LDO(VAUX2_6030, 0x58, 1000, 3300, 2),
+	TWL6030_ADJUSTABLE_LDO(VAUX3_6030, 0x5c, 1000, 3300, 3),
+	TWL6030_ADJUSTABLE_LDO(VMMC, 0x68, 1000, 3300, 4),
+	TWL6030_ADJUSTABLE_LDO(VPP, 0x6c, 1000, 3300, 5),
+	TWL6030_ADJUSTABLE_LDO(VUSIM, 0x74, 1000, 3300, 7),
+	TWL6030_FIXED_LDO(VANA, 0x50, 2100, 15, 0),
+	TWL6030_FIXED_LDO(VCXIO, 0x60, 1800, 16, 0),
+	TWL6030_FIXED_LDO(VDAC, 0x64, 1800, 17, 0),
+	TWL6030_FIXED_LDO(VUSB, 0x70, 3300, 18, 0),
+	TWL6030_FIXED_RESOURCE(CLK32KG, 0x8C, 48, 0),
+
+	/* 6025 are renamed compared to 6030 versions */
+	TWL6025_ADJUSTABLE_LDO(LDO2, 0x54, 1000, 3300, 1),
+	TWL6025_ADJUSTABLE_LDO(LDO4, 0x58, 1000, 3300, 2),
+	TWL6025_ADJUSTABLE_LDO(LDO3, 0x5c, 1000, 3300, 3),
+	TWL6025_ADJUSTABLE_LDO(LDO5, 0x68, 1000, 3300, 4),
+	TWL6025_ADJUSTABLE_LDO(LDO1, 0x6c, 1000, 3300, 5),
+	TWL6025_ADJUSTABLE_LDO(LDO7, 0x74, 1000, 3300, 7),
+	TWL6025_ADJUSTABLE_LDO(LDO6, 0x60, 1000, 3300, 16),
+	TWL6025_ADJUSTABLE_LDO(LDOLN, 0x64, 1000, 3300, 17),
+	TWL6025_ADJUSTABLE_LDO(LDOUSB, 0x70, 1000, 3300, 18),
+
+	TWL6025_ADJUSTABLE_SMPS(SMPS3, 0x34, 1),
+	TWL6025_ADJUSTABLE_SMPS(SMPS4, 0x10, 2),
+	TWL6025_ADJUSTABLE_SMPS(VIO, 0x16, 3),
 };
 
+static u8 twl_get_smps_offset(void)
+{
+	u8 value;
+
+	twl_i2c_read_u8(TWL_MODULE_PM_RECEIVER, &value,
+			TWL6030_SMPS_OFFSET);
+	return value;
+}
+
+static u8 twl_get_smps_mult(void)
+{
+	u8 value;
+
+	twl_i2c_read_u8(TWL_MODULE_PM_RECEIVER, &value,
+			TWL6030_SMPS_MULT);
+	return value;
+}
+
 static int __devinit twlreg_probe(struct platform_device *pdev)
 {
 	int				i;
@@ -623,6 +1028,9 @@
 	if (!initdata)
 		return -EINVAL;
 
+	/* copy the features into regulator data */
+	info->features = (unsigned long)initdata->driver_data;
+
 	/* Constrain board-specific capabilities according to what
 	 * this driver and the chip itself can actually do.
 	 */
@@ -645,6 +1053,27 @@
 		break;
 	}
 
+	switch (pdev->id) {
+	case TWL6025_REG_SMPS3:
+		if (twl_get_smps_mult() & SMPS_MULTOFFSET_SMPS3)
+			info->flags |= SMPS_EXTENDED_EN;
+		if (twl_get_smps_offset() & SMPS_MULTOFFSET_SMPS3)
+			info->flags |= SMPS_OFFSET_EN;
+		break;
+	case TWL6025_REG_SMPS4:
+		if (twl_get_smps_mult() & SMPS_MULTOFFSET_SMPS4)
+			info->flags |= SMPS_EXTENDED_EN;
+		if (twl_get_smps_offset() & SMPS_MULTOFFSET_SMPS4)
+			info->flags |= SMPS_OFFSET_EN;
+		break;
+	case TWL6025_REG_VIO:
+		if (twl_get_smps_mult() & SMPS_MULTOFFSET_VIO)
+			info->flags |= SMPS_EXTENDED_EN;
+		if (twl_get_smps_offset() & SMPS_MULTOFFSET_VIO)
+			info->flags |= SMPS_OFFSET_EN;
+		break;
+	}
+
 	rdev = regulator_register(&info->desc, &pdev->dev, initdata, info);
 	if (IS_ERR(rdev)) {
 		dev_err(&pdev->dev, "can't register %s, %ld\n",
@@ -653,7 +1082,8 @@
 	}
 	platform_set_drvdata(pdev, rdev);
 
-	twlreg_write(info, TWL_MODULE_PM_RECEIVER, VREG_REMAP,
+	if (twl_class_is_4030())
+		twlreg_write(info, TWL_MODULE_PM_RECEIVER, VREG_REMAP,
 						info->remap);
 
 	/* NOTE:  many regulators support short-circuit IRQs (presentable
diff -druN linux-2.6.39-libre/drivers/regulator/wm831x-dcdc.c linux-3.0-rc7-libre/drivers/regulator/wm831x-dcdc.c
--- linux-2.6.39-libre/drivers/regulator/wm831x-dcdc.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/regulator/wm831x-dcdc.c	2011-07-11 19:51:52.000000000 -0400
@@ -600,7 +600,6 @@
 static __devexit int wm831x_buckv_remove(struct platform_device *pdev)
 {
 	struct wm831x_dcdc *dcdc = platform_get_drvdata(pdev);
-	struct wm831x *wm831x = dcdc->wm831x;
 
 	platform_set_drvdata(pdev, NULL);
 
@@ -776,7 +775,6 @@
 static __devexit int wm831x_buckp_remove(struct platform_device *pdev)
 {
 	struct wm831x_dcdc *dcdc = platform_get_drvdata(pdev);
-	struct wm831x *wm831x = dcdc->wm831x;
 
 	platform_set_drvdata(pdev, NULL);
 
diff -druN linux-2.6.39-libre/drivers/regulator/wm8400-regulator.c linux-3.0-rc7-libre/drivers/regulator/wm8400-regulator.c
--- linux-2.6.39-libre/drivers/regulator/wm8400-regulator.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/regulator/wm8400-regulator.c	2011-07-11 19:51:52.000000000 -0400
@@ -55,7 +55,7 @@
 		return 1600000 + ((selector - 14) * 100000);
 }
 
-static int wm8400_ldo_get_voltage(struct regulator_dev *dev)
+static int wm8400_ldo_get_voltage_sel(struct regulator_dev *dev)
 {
 	struct wm8400 *wm8400 = rdev_get_drvdata(dev);
 	u16 val;
@@ -63,7 +63,7 @@
 	val = wm8400_reg_read(wm8400, WM8400_LDO1_CONTROL + rdev_get_id(dev));
 	val &= WM8400_LDO1_VSEL_MASK;
 
-	return wm8400_ldo_list_voltage(dev, val);
+	return val;
 }
 
 static int wm8400_ldo_set_voltage(struct regulator_dev *dev,
@@ -104,7 +104,7 @@
 	.enable = wm8400_ldo_enable,
 	.disable = wm8400_ldo_disable,
 	.list_voltage = wm8400_ldo_list_voltage,
-	.get_voltage = wm8400_ldo_get_voltage,
+	.get_voltage_sel = wm8400_ldo_get_voltage_sel,
 	.set_voltage = wm8400_ldo_set_voltage,
 };
 
@@ -145,7 +145,7 @@
 	return 850000 + (selector * 25000);
 }
 
-static int wm8400_dcdc_get_voltage(struct regulator_dev *dev)
+static int wm8400_dcdc_get_voltage_sel(struct regulator_dev *dev)
 {
 	struct wm8400 *wm8400 = rdev_get_drvdata(dev);
 	u16 val;
@@ -154,7 +154,7 @@
 	val = wm8400_reg_read(wm8400, WM8400_DCDC1_CONTROL_1 + offset);
 	val &= WM8400_DC1_VSEL_MASK;
 
-	return 850000 + (25000 * val);
+	return val;
 }
 
 static int wm8400_dcdc_set_voltage(struct regulator_dev *dev,
@@ -261,7 +261,7 @@
 	.enable = wm8400_dcdc_enable,
 	.disable = wm8400_dcdc_disable,
 	.list_voltage = wm8400_dcdc_list_voltage,
-	.get_voltage = wm8400_dcdc_get_voltage,
+	.get_voltage_sel = wm8400_dcdc_get_voltage_sel,
 	.set_voltage = wm8400_dcdc_set_voltage,
 	.get_mode = wm8400_dcdc_get_mode,
 	.set_mode = wm8400_dcdc_set_mode,
diff -druN linux-2.6.39-libre/drivers/rtc/class.c linux-3.0-rc7-libre/drivers/rtc/class.c
--- linux-2.6.39-libre/drivers/rtc/class.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/rtc/class.c	2011-07-11 19:51:52.000000000 -0400
@@ -41,26 +41,21 @@
  * system's wall clock; restore it on resume().
  */
 
-static struct timespec	delta;
 static time_t		oldtime;
+static struct timespec	oldts;
 
 static int rtc_suspend(struct device *dev, pm_message_t mesg)
 {
 	struct rtc_device	*rtc = to_rtc_device(dev);
 	struct rtc_time		tm;
-	struct timespec		ts = current_kernel_time();
 
 	if (strcmp(dev_name(&rtc->dev), CONFIG_RTC_HCTOSYS_DEVICE) != 0)
 		return 0;
 
 	rtc_read_time(rtc, &tm);
+	ktime_get_ts(&oldts);
 	rtc_tm_to_time(&tm, &oldtime);
 
-	/* RTC precision is 1 second; adjust delta for avg 1/2 sec err */
-	set_normalized_timespec(&delta,
-				ts.tv_sec - oldtime,
-				ts.tv_nsec - (NSEC_PER_SEC >> 1));
-
 	return 0;
 }
 
@@ -70,10 +65,12 @@
 	struct rtc_time		tm;
 	time_t			newtime;
 	struct timespec		time;
+	struct timespec		newts;
 
 	if (strcmp(dev_name(&rtc->dev), CONFIG_RTC_HCTOSYS_DEVICE) != 0)
 		return 0;
 
+	ktime_get_ts(&newts);
 	rtc_read_time(rtc, &tm);
 	if (rtc_valid_tm(&tm) != 0) {
 		pr_debug("%s:  bogus resume time\n", dev_name(&rtc->dev));
@@ -85,15 +82,13 @@
 			pr_debug("%s:  time travel!\n", dev_name(&rtc->dev));
 		return 0;
 	}
+	/* calculate the RTC time delta */
+	set_normalized_timespec(&time, newtime - oldtime, 0);
 
-	/* restore wall clock using delta against this RTC;
-	 * adjust again for avg 1/2 second RTC sampling error
-	 */
-	set_normalized_timespec(&time,
-				newtime + delta.tv_sec,
-				(NSEC_PER_SEC >> 1) + delta.tv_nsec);
-	do_settimeofday(&time);
+	/* subtract kernel time between rtc_suspend to rtc_resume */
+	time = timespec_sub(time, timespec_sub(newts, oldts));
 
+	timekeeping_inject_sleeptime(&time);
 	return 0;
 }
 
diff -druN linux-2.6.39-libre/drivers/rtc/interface.c linux-3.0-rc7-libre/drivers/rtc/interface.c
--- linux-2.6.39-libre/drivers/rtc/interface.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/rtc/interface.c	2011-07-11 19:51:52.000000000 -0400
@@ -318,7 +318,7 @@
 }
 EXPORT_SYMBOL_GPL(rtc_read_alarm);
 
-int __rtc_set_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm)
+static int __rtc_set_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm)
 {
 	struct rtc_time tm;
 	long now, scheduled;
diff -druN linux-2.6.39-libre/drivers/rtc/Kconfig linux-3.0-rc7-libre/drivers/rtc/Kconfig
--- linux-2.6.39-libre/drivers/rtc/Kconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/rtc/Kconfig	2011-07-11 19:51:52.000000000 -0400
@@ -3,10 +3,10 @@
 #
 
 config RTC_LIB
-	tristate
+	bool
 
 menuconfig RTC_CLASS
-	tristate "Real Time Clock"
+	bool "Real Time Clock"
 	default n
 	depends on !S390
 	select RTC_LIB
@@ -15,9 +15,6 @@
  	  be allowed to plug one or more RTCs to your system. You will
 	  probably want to enable one or more of the interfaces below.
 
-	  This driver can also be built as a module. If so, the module
-	  will be called rtc-core.
-
 if RTC_CLASS
 
 config RTC_HCTOSYS
@@ -128,6 +125,16 @@
 
 if I2C
 
+config RTC_DRV_88PM860X
+	tristate "Marvell 88PM860x"
+	depends on RTC_CLASS && I2C && MFD_88PM860X
+	help
+	  If you say yes here you get support for RTC function in Marvell
+	  88PM860x chips.
+
+	  This driver can also be built as a module. If so, the module
+	  will be called rtc-88pm860x.
+
 config RTC_DRV_DS1307
 	tristate "Dallas/Maxim DS1307/37/38/39/40, ST M41T00, EPSON RX-8025"
 	help
@@ -354,12 +361,39 @@
 	  This driver can also be built as a module. If so, the module
 	  will be called rtc-rx8025.
 
+config RTC_DRV_EM3027
+	tristate "EM Microelectronic EM3027"
+	help
+	  If you say yes here you get support for the EM
+	  Microelectronic EM3027 RTC chips.
+
+	  This driver can also be built as a module. If so, the module
+	  will be called rtc-em3027.
+
+config RTC_DRV_RV3029C2
+	tristate "Micro Crystal RTC"
+	help
+	  If you say yes here you get support for the Micro Crystal
+	  RV3029-C2 RTC chips.
+
+	  This driver can also be built as a module. If so, the module
+	  will be called rtc-rv3029c2.
+
 endif # I2C
 
 comment "SPI RTC drivers"
 
 if SPI_MASTER
 
+config RTC_DRV_M41T93
+        tristate "ST M41T93"
+        help
+          If you say yes here you will get support for the
+          ST M41T93 SPI RTC chip.
+
+          This driver can also be built as a module. If so, the module
+          will be called rtc-m41t93.
+
 config RTC_DRV_M41T94
 	tristate "ST M41T94"
 	help
@@ -648,6 +682,14 @@
 	  This driver can also be built as a module. If so, the module
 	  will be called "rtc-wm8350".
 
+config RTC_DRV_SPEAR
+	tristate "SPEAR ST RTC"
+	depends on PLAT_SPEAR
+	default y
+	help
+	 If you say Y here you will get support for the RTC found on
+	 spear
+
 config RTC_DRV_PCF50633
 	depends on MFD_PCF50633
 	tristate "NXP PCF50633 RTC"
@@ -877,6 +919,13 @@
          This RTC driver uses PXA RTC registers available since pxa27x
          series (RDxR, RYxR) instead of legacy RCNR, RTAR.
 
+config RTC_DRV_VT8500
+	tristate "VIA/WonderMedia 85xx SoC RTC"
+	depends on ARCH_VT8500
+	help
+	  If you say Y here you will get access to the real time clock
+	  built into your VIA VT8500 SoC or its relatives.
+
 
 config RTC_DRV_SUN4V
 	bool "SUN4V Hypervisor RTC"
@@ -995,4 +1044,20 @@
 	  This drive can also be built as a module. If so, the module
 	  will be called rtc-tegra.
 
+config RTC_DRV_TILE
+	tristate "Tilera hypervisor RTC support"
+	depends on TILE
+	help
+	  Enable support for the Linux driver side of the Tilera
+	  hypervisor's real-time clock interface.
+
+config RTC_DRV_PUV3
+	tristate "PKUnity v3 RTC support"
+	depends on ARCH_PUV3
+	help
+	  This enables support for the RTC in the PKUnity-v3 SoCs.
+
+	  This drive can also be built as a module. If so, the module
+	  will be called rtc-puv3.
+
 endif # RTC_CLASS
diff -druN linux-2.6.39-libre/drivers/rtc/Makefile linux-3.0-rc7-libre/drivers/rtc/Makefile
--- linux-2.6.39-libre/drivers/rtc/Makefile	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/rtc/Makefile	2011-07-11 19:51:52.000000000 -0400
@@ -15,6 +15,7 @@
 
 # Keep the list ordered.
 
+obj-$(CONFIG_RTC_DRV_88PM860X)  += rtc-88pm860x.o
 obj-$(CONFIG_RTC_DRV_AB3100)	+= rtc-ab3100.o
 obj-$(CONFIG_RTC_DRV_AB8500)	+= rtc-ab8500.o
 obj-$(CONFIG_RTC_DRV_AT32AP700X)+= rtc-at32ap700x.o
@@ -43,6 +44,7 @@
 obj-$(CONFIG_RTC_DRV_DS3232)	+= rtc-ds3232.o
 obj-$(CONFIG_RTC_DRV_DS3234)	+= rtc-ds3234.o
 obj-$(CONFIG_RTC_DRV_EFI)	+= rtc-efi.o
+obj-$(CONFIG_RTC_DRV_EM3027)	+= rtc-em3027.o
 obj-$(CONFIG_RTC_DRV_EP93XX)	+= rtc-ep93xx.o
 obj-$(CONFIG_RTC_DRV_FM3130)	+= rtc-fm3130.o
 obj-$(CONFIG_RTC_DRV_GENERIC)	+= rtc-generic.o
@@ -52,6 +54,7 @@
 obj-$(CONFIG_RTC_DRV_JZ4740)	+= rtc-jz4740.o
 obj-$(CONFIG_RTC_DRV_LPC32XX)	+= rtc-lpc32xx.o
 obj-$(CONFIG_RTC_DRV_M41T80)	+= rtc-m41t80.o
+obj-$(CONFIG_RTC_DRV_M41T93)	+= rtc-m41t93.o
 obj-$(CONFIG_RTC_DRV_M41T94)	+= rtc-m41t94.o
 obj-$(CONFIG_RTC_DRV_M48T35)	+= rtc-m48t35.o
 obj-$(CONFIG_RTC_DRV_M48T59)	+= rtc-m48t59.o
@@ -75,28 +78,33 @@
 obj-$(CONFIG_RTC_DRV_PL030)	+= rtc-pl030.o
 obj-$(CONFIG_RTC_DRV_PL031)	+= rtc-pl031.o
 obj-$(CONFIG_RTC_DRV_PS3)	+= rtc-ps3.o
+obj-$(CONFIG_RTC_DRV_PUV3)	+= rtc-puv3.o
 obj-$(CONFIG_RTC_DRV_PXA)	+= rtc-pxa.o
 obj-$(CONFIG_RTC_DRV_R9701)	+= rtc-r9701.o
 obj-$(CONFIG_RTC_DRV_RP5C01)	+= rtc-rp5c01.o
 obj-$(CONFIG_RTC_DRV_RS5C313)	+= rtc-rs5c313.o
 obj-$(CONFIG_RTC_DRV_RS5C348)	+= rtc-rs5c348.o
 obj-$(CONFIG_RTC_DRV_RS5C372)	+= rtc-rs5c372.o
+obj-$(CONFIG_RTC_DRV_RV3029C2)	+= rtc-rv3029c2.o
 obj-$(CONFIG_RTC_DRV_RX8025)	+= rtc-rx8025.o
 obj-$(CONFIG_RTC_DRV_RX8581)	+= rtc-rx8581.o
 obj-$(CONFIG_RTC_DRV_S35390A)	+= rtc-s35390a.o
 obj-$(CONFIG_RTC_DRV_S3C)	+= rtc-s3c.o
 obj-$(CONFIG_RTC_DRV_SA1100)	+= rtc-sa1100.o
 obj-$(CONFIG_RTC_DRV_SH)	+= rtc-sh.o
+obj-$(CONFIG_RTC_DRV_SPEAR)	+= rtc-spear.o
 obj-$(CONFIG_RTC_DRV_STARFIRE)	+= rtc-starfire.o
 obj-$(CONFIG_RTC_DRV_STK17TA8)	+= rtc-stk17ta8.o
 obj-$(CONFIG_RTC_DRV_STMP)	+= rtc-stmp3xxx.o
 obj-$(CONFIG_RTC_DRV_SUN4V)	+= rtc-sun4v.o
 obj-$(CONFIG_RTC_DRV_TEGRA)	+= rtc-tegra.o
 obj-$(CONFIG_RTC_DRV_TEST)	+= rtc-test.o
+obj-$(CONFIG_RTC_DRV_TILE)	+= rtc-tile.o
 obj-$(CONFIG_RTC_DRV_TWL4030)	+= rtc-twl.o
 obj-$(CONFIG_RTC_DRV_TX4939)	+= rtc-tx4939.o
 obj-$(CONFIG_RTC_DRV_V3020)	+= rtc-v3020.o
 obj-$(CONFIG_RTC_DRV_VR41XX)	+= rtc-vr41xx.o
+obj-$(CONFIG_RTC_DRV_VT8500)	+= rtc-vt8500.o
 obj-$(CONFIG_RTC_DRV_WM831X)	+= rtc-wm831x.o
 obj-$(CONFIG_RTC_DRV_WM8350)	+= rtc-wm8350.o
 obj-$(CONFIG_RTC_DRV_X1205)	+= rtc-x1205.o
diff -druN linux-2.6.39-libre/drivers/rtc/rtc-88pm860x.c linux-3.0-rc7-libre/drivers/rtc/rtc-88pm860x.c
--- linux-2.6.39-libre/drivers/rtc/rtc-88pm860x.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/rtc/rtc-88pm860x.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,427 @@
+/*
+ * Real Time Clock driver for Marvell 88PM860x PMIC
+ *
+ * Copyright (c) 2010 Marvell International Ltd.
+ * Author:	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/slab.h>
+#include <linux/mutex.h>
+#include <linux/rtc.h>
+#include <linux/delay.h>
+#include <linux/mfd/core.h>
+#include <linux/mfd/88pm860x.h>
+
+#define VRTC_CALIBRATION
+
+struct pm860x_rtc_info {
+	struct pm860x_chip	*chip;
+	struct i2c_client	*i2c;
+	struct rtc_device	*rtc_dev;
+	struct device		*dev;
+	struct delayed_work	calib_work;
+
+	int			irq;
+	int			vrtc;
+	int			(*sync)(unsigned int ticks);
+};
+
+#define REG_VRTC_MEAS1		0x7D
+
+#define REG0_ADDR		0xB0
+#define REG1_ADDR		0xB2
+#define REG2_ADDR		0xB4
+#define REG3_ADDR		0xB6
+
+#define REG0_DATA		0xB1
+#define REG1_DATA		0xB3
+#define REG2_DATA		0xB5
+#define REG3_DATA		0xB7
+
+/* bit definitions of Measurement Enable Register 2 (0x51) */
+#define MEAS2_VRTC		(1 << 0)
+
+/* bit definitions of RTC Register 1 (0xA0) */
+#define ALARM_EN		(1 << 3)
+#define ALARM_WAKEUP		(1 << 4)
+#define ALARM			(1 << 5)
+#define RTC1_USE_XO		(1 << 7)
+
+#define VRTC_CALIB_INTERVAL	(HZ * 60 * 10)		/* 10 minutes */
+
+static irqreturn_t rtc_update_handler(int irq, void *data)
+{
+	struct pm860x_rtc_info *info = (struct pm860x_rtc_info *)data;
+	int mask;
+
+	mask = ALARM | ALARM_WAKEUP;
+	pm860x_set_bits(info->i2c, PM8607_RTC1, mask | ALARM_EN, mask);
+	rtc_update_irq(info->rtc_dev, 1, RTC_AF);
+	return IRQ_HANDLED;
+}
+
+static int pm860x_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
+{
+	struct pm860x_rtc_info *info = dev_get_drvdata(dev);
+
+	if (enabled)
+		pm860x_set_bits(info->i2c, PM8607_RTC1, ALARM, ALARM);
+	else
+		pm860x_set_bits(info->i2c, PM8607_RTC1, ALARM, 0);
+	return 0;
+}
+
+/*
+ * Calculate the next alarm time given the requested alarm time mask
+ * and the current time.
+ */
+static void rtc_next_alarm_time(struct rtc_time *next, struct rtc_time *now,
+				struct rtc_time *alrm)
+{
+	unsigned long next_time;
+	unsigned long now_time;
+
+	next->tm_year = now->tm_year;
+	next->tm_mon = now->tm_mon;
+	next->tm_mday = now->tm_mday;
+	next->tm_hour = alrm->tm_hour;
+	next->tm_min = alrm->tm_min;
+	next->tm_sec = alrm->tm_sec;
+
+	rtc_tm_to_time(now, &now_time);
+	rtc_tm_to_time(next, &next_time);
+
+	if (next_time < now_time) {
+		/* Advance one day */
+		next_time += 60 * 60 * 24;
+		rtc_time_to_tm(next_time, next);
+	}
+}
+
+static int pm860x_rtc_read_time(struct device *dev, struct rtc_time *tm)
+{
+	struct pm860x_rtc_info *info = dev_get_drvdata(dev);
+	unsigned char buf[8];
+	unsigned long ticks, base, data;
+
+	pm860x_page_bulk_read(info->i2c, REG0_ADDR, 8, buf);
+	dev_dbg(info->dev, "%x-%x-%x-%x-%x-%x-%x-%x\n", buf[0], buf[1],
+		buf[2], buf[3], buf[4], buf[5], buf[6], buf[7]);
+	base = (buf[1] << 24) | (buf[3] << 16) | (buf[5] << 8) | buf[7];
+
+	/* load 32-bit read-only counter */
+	pm860x_bulk_read(info->i2c, PM8607_RTC_COUNTER1, 4, buf);
+	data = (buf[3] << 24) | (buf[2] << 16) | (buf[1] << 8) | buf[0];
+	ticks = base + data;
+	dev_dbg(info->dev, "get base:0x%lx, RO count:0x%lx, ticks:0x%lx\n",
+		base, data, ticks);
+
+	rtc_time_to_tm(ticks, tm);
+
+	return 0;
+}
+
+static int pm860x_rtc_set_time(struct device *dev, struct rtc_time *tm)
+{
+	struct pm860x_rtc_info *info = dev_get_drvdata(dev);
+	unsigned char buf[4];
+	unsigned long ticks, base, data;
+
+	if ((tm->tm_year < 70) || (tm->tm_year > 138)) {
+		dev_dbg(info->dev, "Set time %d out of range. "
+			"Please set time between 1970 to 2038.\n",
+			1900 + tm->tm_year);
+		return -EINVAL;
+	}
+	rtc_tm_to_time(tm, &ticks);
+
+	/* load 32-bit read-only counter */
+	pm860x_bulk_read(info->i2c, PM8607_RTC_COUNTER1, 4, buf);
+	data = (buf[3] << 24) | (buf[2] << 16) | (buf[1] << 8) | buf[0];
+	base = ticks - data;
+	dev_dbg(info->dev, "set base:0x%lx, RO count:0x%lx, ticks:0x%lx\n",
+		base, data, ticks);
+
+	pm860x_page_reg_write(info->i2c, REG0_DATA, (base >> 24) & 0xFF);
+	pm860x_page_reg_write(info->i2c, REG1_DATA, (base >> 16) & 0xFF);
+	pm860x_page_reg_write(info->i2c, REG2_DATA, (base >> 8) & 0xFF);
+	pm860x_page_reg_write(info->i2c, REG3_DATA, base & 0xFF);
+
+	if (info->sync)
+		info->sync(ticks);
+	return 0;
+}
+
+static int pm860x_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
+{
+	struct pm860x_rtc_info *info = dev_get_drvdata(dev);
+	unsigned char buf[8];
+	unsigned long ticks, base, data;
+	int ret;
+
+	pm860x_page_bulk_read(info->i2c, REG0_ADDR, 8, buf);
+	dev_dbg(info->dev, "%x-%x-%x-%x-%x-%x-%x-%x\n", buf[0], buf[1],
+		buf[2], buf[3], buf[4], buf[5], buf[6], buf[7]);
+	base = (buf[1] << 24) | (buf[3] << 16) | (buf[5] << 8) | buf[7];
+
+	pm860x_bulk_read(info->i2c, PM8607_RTC_EXPIRE1, 4, buf);
+	data = (buf[3] << 24) | (buf[2] << 16) | (buf[1] << 8) | buf[0];
+	ticks = base + data;
+	dev_dbg(info->dev, "get base:0x%lx, RO count:0x%lx, ticks:0x%lx\n",
+		base, data, ticks);
+
+	rtc_time_to_tm(ticks, &alrm->time);
+	ret = pm860x_reg_read(info->i2c, PM8607_RTC1);
+	alrm->enabled = (ret & ALARM_EN) ? 1 : 0;
+	alrm->pending = (ret & (ALARM | ALARM_WAKEUP)) ? 1 : 0;
+	return 0;
+}
+
+static int pm860x_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
+{
+	struct pm860x_rtc_info *info = dev_get_drvdata(dev);
+	struct rtc_time now_tm, alarm_tm;
+	unsigned long ticks, base, data;
+	unsigned char buf[8];
+	int mask;
+
+	pm860x_set_bits(info->i2c, PM8607_RTC1, ALARM_EN, 0);
+
+	pm860x_page_bulk_read(info->i2c, REG0_ADDR, 8, buf);
+	dev_dbg(info->dev, "%x-%x-%x-%x-%x-%x-%x-%x\n", buf[0], buf[1],
+		buf[2], buf[3], buf[4], buf[5], buf[6], buf[7]);
+	base = (buf[1] << 24) | (buf[3] << 16) | (buf[5] << 8) | buf[7];
+
+	/* load 32-bit read-only counter */
+	pm860x_bulk_read(info->i2c, PM8607_RTC_COUNTER1, 4, buf);
+	data = (buf[3] << 24) | (buf[2] << 16) | (buf[1] << 8) | buf[0];
+	ticks = base + data;
+	dev_dbg(info->dev, "get base:0x%lx, RO count:0x%lx, ticks:0x%lx\n",
+		base, data, ticks);
+
+	rtc_time_to_tm(ticks, &now_tm);
+	rtc_next_alarm_time(&alarm_tm, &now_tm, &alrm->time);
+	/* get new ticks for alarm in 24 hours */
+	rtc_tm_to_time(&alarm_tm, &ticks);
+	data = ticks - base;
+
+	buf[0] = data & 0xff;
+	buf[1] = (data >> 8) & 0xff;
+	buf[2] = (data >> 16) & 0xff;
+	buf[3] = (data >> 24) & 0xff;
+	pm860x_bulk_write(info->i2c, PM8607_RTC_EXPIRE1, 4, buf);
+	if (alrm->enabled) {
+		mask = ALARM | ALARM_WAKEUP | ALARM_EN;
+		pm860x_set_bits(info->i2c, PM8607_RTC1, mask, mask);
+	} else {
+		mask = ALARM | ALARM_WAKEUP | ALARM_EN;
+		pm860x_set_bits(info->i2c, PM8607_RTC1, mask,
+				ALARM | ALARM_WAKEUP);
+	}
+	return 0;
+}
+
+static const struct rtc_class_ops pm860x_rtc_ops = {
+	.read_time	= pm860x_rtc_read_time,
+	.set_time	= pm860x_rtc_set_time,
+	.read_alarm	= pm860x_rtc_read_alarm,
+	.set_alarm	= pm860x_rtc_set_alarm,
+	.alarm_irq_enable = pm860x_rtc_alarm_irq_enable,
+};
+
+#ifdef VRTC_CALIBRATION
+static void calibrate_vrtc_work(struct work_struct *work)
+{
+	struct pm860x_rtc_info *info = container_of(work,
+		struct pm860x_rtc_info, calib_work.work);
+	unsigned char buf[2];
+	unsigned int sum, data, mean, vrtc_set;
+	int i;
+
+	for (i = 0, sum = 0; i < 16; i++) {
+		msleep(100);
+		pm860x_bulk_read(info->i2c, REG_VRTC_MEAS1, 2, buf);
+		data = (buf[0] << 4) | buf[1];
+		data = (data * 5400) >> 12;	/* convert to mv */
+		sum += data;
+	}
+	mean = sum >> 4;
+	vrtc_set = 2700 + (info->vrtc & 0x3) * 200;
+	dev_dbg(info->dev, "mean:%d, vrtc_set:%d\n", mean, vrtc_set);
+
+	sum = pm860x_reg_read(info->i2c, PM8607_RTC_MISC1);
+	data = sum & 0x3;
+	if ((mean + 200) < vrtc_set) {
+		/* try higher voltage */
+		if (++data == 4)
+			goto out;
+		data = (sum & 0xf8) | (data & 0x3);
+		pm860x_reg_write(info->i2c, PM8607_RTC_MISC1, data);
+	} else if ((mean - 200) > vrtc_set) {
+		/* try lower voltage */
+		if (data-- == 0)
+			goto out;
+		data = (sum & 0xf8) | (data & 0x3);
+		pm860x_reg_write(info->i2c, PM8607_RTC_MISC1, data);
+	} else
+		goto out;
+	dev_dbg(info->dev, "set 0x%x to RTC_MISC1\n", data);
+	/* trigger next calibration since VRTC is updated */
+	schedule_delayed_work(&info->calib_work, VRTC_CALIB_INTERVAL);
+	return;
+out:
+	/* disable measurement */
+	pm860x_set_bits(info->i2c, PM8607_MEAS_EN2, MEAS2_VRTC, 0);
+	dev_dbg(info->dev, "finish VRTC calibration\n");
+	return;
+}
+#endif
+
+static int __devinit pm860x_rtc_probe(struct platform_device *pdev)
+{
+	struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent);
+	struct pm860x_rtc_pdata *pdata = NULL;
+	struct pm860x_rtc_info *info;
+	struct rtc_time tm;
+	unsigned long ticks = 0;
+	int ret;
+
+	pdata = pdev->dev.platform_data;
+	if (pdata == NULL)
+		dev_warn(&pdev->dev, "No platform data!\n");
+
+	info = kzalloc(sizeof(struct pm860x_rtc_info), GFP_KERNEL);
+	if (!info)
+		return -ENOMEM;
+	info->irq = platform_get_irq(pdev, 0);
+	if (info->irq < 0) {
+		dev_err(&pdev->dev, "No IRQ resource!\n");
+		ret = -EINVAL;
+		goto out;
+	}
+
+	info->chip = chip;
+	info->i2c = (chip->id == CHIP_PM8607) ? chip->client : chip->companion;
+	info->dev = &pdev->dev;
+	dev_set_drvdata(&pdev->dev, info);
+
+	ret = request_threaded_irq(info->irq, NULL, rtc_update_handler,
+				   IRQF_ONESHOT, "rtc", info);
+	if (ret < 0) {
+		dev_err(chip->dev, "Failed to request IRQ: #%d: %d\n",
+			info->irq, ret);
+		goto out;
+	}
+
+	/* set addresses of 32-bit base value for RTC time */
+	pm860x_page_reg_write(info->i2c, REG0_ADDR, REG0_DATA);
+	pm860x_page_reg_write(info->i2c, REG1_ADDR, REG1_DATA);
+	pm860x_page_reg_write(info->i2c, REG2_ADDR, REG2_DATA);
+	pm860x_page_reg_write(info->i2c, REG3_ADDR, REG3_DATA);
+
+	ret = pm860x_rtc_read_time(&pdev->dev, &tm);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "Failed to read initial time.\n");
+		goto out_rtc;
+	}
+	if ((tm.tm_year < 70) || (tm.tm_year > 138)) {
+		tm.tm_year = 70;
+		tm.tm_mon = 0;
+		tm.tm_mday = 1;
+		tm.tm_hour = 0;
+		tm.tm_min = 0;
+		tm.tm_sec = 0;
+		ret = pm860x_rtc_set_time(&pdev->dev, &tm);
+		if (ret < 0) {
+			dev_err(&pdev->dev, "Failed to set initial time.\n");
+			goto out_rtc;
+		}
+	}
+	rtc_tm_to_time(&tm, &ticks);
+	if (pdata && pdata->sync) {
+		pdata->sync(ticks);
+		info->sync = pdata->sync;
+	}
+
+	info->rtc_dev = rtc_device_register("88pm860x-rtc", &pdev->dev,
+					    &pm860x_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;
+	}
+
+	/*
+	 * enable internal XO instead of internal 3.25MHz clock since it can
+	 * free running in PMIC power-down state.
+	 */
+	pm860x_set_bits(info->i2c, PM8607_RTC1, RTC1_USE_XO, RTC1_USE_XO);
+
+#ifdef VRTC_CALIBRATION
+	/* <00> -- 2.7V, <01> -- 2.9V, <10> -- 3.1V, <11> -- 3.3V */
+	if (pdata && pdata->vrtc)
+		info->vrtc = pdata->vrtc & 0x3;
+	else
+		info->vrtc = 1;
+	pm860x_set_bits(info->i2c, PM8607_MEAS_EN2, MEAS2_VRTC, MEAS2_VRTC);
+
+	/* calibrate VRTC */
+	INIT_DELAYED_WORK(&info->calib_work, calibrate_vrtc_work);
+	schedule_delayed_work(&info->calib_work, VRTC_CALIB_INTERVAL);
+#endif	/* VRTC_CALIBRATION */
+	return 0;
+out_rtc:
+	free_irq(info->irq, info);
+out:
+	kfree(info);
+	return ret;
+}
+
+static int __devexit pm860x_rtc_remove(struct platform_device *pdev)
+{
+	struct pm860x_rtc_info *info = platform_get_drvdata(pdev);
+
+#ifdef VRTC_CALIBRATION
+	flush_scheduled_work();
+	/* disable measurement */
+	pm860x_set_bits(info->i2c, PM8607_MEAS_EN2, MEAS2_VRTC, 0);
+#endif	/* VRTC_CALIBRATION */
+
+	platform_set_drvdata(pdev, NULL);
+	rtc_device_unregister(info->rtc_dev);
+	free_irq(info->irq, info);
+	kfree(info);
+	return 0;
+}
+
+static struct platform_driver pm860x_rtc_driver = {
+	.driver		= {
+		.name	= "88pm860x-rtc",
+		.owner	= THIS_MODULE,
+	},
+	.probe		= pm860x_rtc_probe,
+	.remove		= __devexit_p(pm860x_rtc_remove),
+};
+
+static int __init pm860x_rtc_init(void)
+{
+	return platform_driver_register(&pm860x_rtc_driver);
+}
+module_init(pm860x_rtc_init);
+
+static void __exit pm860x_rtc_exit(void)
+{
+	platform_driver_unregister(&pm860x_rtc_driver);
+}
+module_exit(pm860x_rtc_exit);
+
+MODULE_DESCRIPTION("Marvell 88PM860x RTC driver");
+MODULE_AUTHOR("Haojian Zhuang <haojian.zhuang@marvell.com>");
+MODULE_LICENSE("GPL");
diff -druN linux-2.6.39-libre/drivers/rtc/rtc-dev.c linux-3.0-rc7-libre/drivers/rtc/rtc-dev.c
--- linux-2.6.39-libre/drivers/rtc/rtc-dev.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/rtc/rtc-dev.c	2011-07-11 19:51:52.000000000 -0400
@@ -421,7 +421,8 @@
 			err = ops->ioctl(rtc->dev.parent, cmd, arg);
 			if (err == -ENOIOCTLCMD)
 				err = -ENOTTY;
-		}
+		} else
+			err = -ENOTTY;
 		break;
 	}
 
diff -druN linux-2.6.39-libre/drivers/rtc/rtc-ds1307.c linux-3.0-rc7-libre/drivers/rtc/rtc-ds1307.c
--- linux-2.6.39-libre/drivers/rtc/rtc-ds1307.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/rtc/rtc-ds1307.c	2011-07-11 19:51:52.000000000 -0400
@@ -149,6 +149,7 @@
 	{ "ds1340", ds_1340 },
 	{ "ds3231", ds_3231 },
 	{ "m41t00", m41t00 },
+	{ "pt7c4338", ds_1307 },
 	{ "rx8025", rx_8025 },
 	{ }
 };
diff -druN linux-2.6.39-libre/drivers/rtc/rtc-em3027.c linux-3.0-rc7-libre/drivers/rtc/rtc-em3027.c
--- linux-2.6.39-libre/drivers/rtc/rtc-em3027.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/rtc/rtc-em3027.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,161 @@
+/*
+ * An rtc/i2c driver for the EM Microelectronic EM3027
+ * Copyright 2011 CompuLab, Ltd.
+ *
+ * Author: Mike Rapoport <mike@compulab.co.il>
+ *
+ * Based on rtc-ds1672.c by Alessandro Zummo <a.zummo@towertech.it>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/i2c.h>
+#include <linux/rtc.h>
+#include <linux/bcd.h>
+
+/* Registers */
+#define EM3027_REG_ON_OFF_CTRL	0x00
+#define EM3027_REG_IRQ_CTRL	0x01
+#define EM3027_REG_IRQ_FLAGS	0x02
+#define EM3027_REG_STATUS	0x03
+#define EM3027_REG_RST_CTRL	0x04
+
+#define EM3027_REG_WATCH_SEC	0x08
+#define EM3027_REG_WATCH_MIN	0x09
+#define EM3027_REG_WATCH_HOUR	0x0a
+#define EM3027_REG_WATCH_DATE	0x0b
+#define EM3027_REG_WATCH_DAY	0x0c
+#define EM3027_REG_WATCH_MON	0x0d
+#define EM3027_REG_WATCH_YEAR	0x0e
+
+#define EM3027_REG_ALARM_SEC	0x10
+#define EM3027_REG_ALARM_MIN	0x11
+#define EM3027_REG_ALARM_HOUR	0x12
+#define EM3027_REG_ALARM_DATE	0x13
+#define EM3027_REG_ALARM_DAY	0x14
+#define EM3027_REG_ALARM_MON	0x15
+#define EM3027_REG_ALARM_YEAR	0x16
+
+static struct i2c_driver em3027_driver;
+
+static int em3027_get_time(struct device *dev, struct rtc_time *tm)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+
+	unsigned char addr = EM3027_REG_WATCH_SEC;
+	unsigned char buf[7];
+
+	struct i2c_msg msgs[] = {
+		{client->addr, 0, 1, &addr},		/* setup read addr */
+		{client->addr, I2C_M_RD, 7, buf},	/* read time/date */
+	};
+
+	/* read time/date registers */
+	if ((i2c_transfer(client->adapter, &msgs[0], 2)) != 2) {
+		dev_err(&client->dev, "%s: read error\n", __func__);
+		return -EIO;
+	}
+
+	tm->tm_sec	= bcd2bin(buf[0]);
+	tm->tm_min	= bcd2bin(buf[1]);
+	tm->tm_hour	= bcd2bin(buf[2]);
+	tm->tm_mday	= bcd2bin(buf[3]);
+	tm->tm_wday	= bcd2bin(buf[4]);
+	tm->tm_mon	= bcd2bin(buf[5]);
+	tm->tm_year	= bcd2bin(buf[6]) + 100;
+
+	return 0;
+}
+
+static int em3027_set_time(struct device *dev, struct rtc_time *tm)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	unsigned char buf[8];
+
+	struct i2c_msg msg = {
+		client->addr, 0, 8, buf,	/* write time/date */
+	};
+
+	buf[0] = EM3027_REG_WATCH_SEC;
+	buf[1] = bin2bcd(tm->tm_sec);
+	buf[2] = bin2bcd(tm->tm_min);
+	buf[3] = bin2bcd(tm->tm_hour);
+	buf[4] = bin2bcd(tm->tm_mday);
+	buf[5] = bin2bcd(tm->tm_wday);
+	buf[6] = bin2bcd(tm->tm_mon);
+	buf[7] = bin2bcd(tm->tm_year % 100);
+
+	/* write time/date registers */
+	if ((i2c_transfer(client->adapter, &msg, 1)) != 1) {
+		dev_err(&client->dev, "%s: write error\n", __func__);
+		return -EIO;
+	}
+
+	return 0;
+}
+
+static const struct rtc_class_ops em3027_rtc_ops = {
+	.read_time = em3027_get_time,
+	.set_time = em3027_set_time,
+};
+
+static int em3027_probe(struct i2c_client *client,
+			const struct i2c_device_id *id)
+{
+	struct rtc_device *rtc;
+
+	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C))
+		return -ENODEV;
+
+	rtc = rtc_device_register(em3027_driver.driver.name, &client->dev,
+				  &em3027_rtc_ops, THIS_MODULE);
+	if (IS_ERR(rtc))
+		return PTR_ERR(rtc);
+
+	i2c_set_clientdata(client, rtc);
+
+	return 0;
+}
+
+static int em3027_remove(struct i2c_client *client)
+{
+	struct rtc_device *rtc = i2c_get_clientdata(client);
+
+	if (rtc)
+		rtc_device_unregister(rtc);
+
+	return 0;
+}
+
+static struct i2c_device_id em3027_id[] = {
+	{ "em3027", 0 },
+	{ }
+};
+
+static struct i2c_driver em3027_driver = {
+	.driver = {
+		   .name = "rtc-em3027",
+	},
+	.probe = &em3027_probe,
+	.remove = &em3027_remove,
+	.id_table = em3027_id,
+};
+
+static int __init em3027_init(void)
+{
+	return i2c_add_driver(&em3027_driver);
+}
+
+static void __exit em3027_exit(void)
+{
+	i2c_del_driver(&em3027_driver);
+}
+
+MODULE_AUTHOR("Mike Rapoport <mike@compulab.co.il>");
+MODULE_DESCRIPTION("EM Microelectronic EM3027 RTC driver");
+MODULE_LICENSE("GPL");
+
+module_init(em3027_init);
+module_exit(em3027_exit);
diff -druN linux-2.6.39-libre/drivers/rtc/rtc-m41t93.c linux-3.0-rc7-libre/drivers/rtc/rtc-m41t93.c
--- linux-2.6.39-libre/drivers/rtc/rtc-m41t93.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/rtc/rtc-m41t93.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,225 @@
+/*
+ *
+ * Driver for ST M41T93 SPI RTC
+ *
+ * (c) 2010 Nikolaus Voss, Weinmann Medical GmbH
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/bcd.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/rtc.h>
+#include <linux/spi/spi.h>
+
+#define M41T93_REG_SSEC			0
+#define M41T93_REG_ST_SEC		1
+#define M41T93_REG_MIN			2
+#define M41T93_REG_CENT_HOUR		3
+#define M41T93_REG_WDAY			4
+#define M41T93_REG_DAY			5
+#define M41T93_REG_MON			6
+#define M41T93_REG_YEAR			7
+
+
+#define M41T93_REG_ALM_HOUR_HT		0xc
+#define M41T93_REG_FLAGS		0xf
+
+#define M41T93_FLAG_ST			(1 << 7)
+#define M41T93_FLAG_OF			(1 << 2)
+#define M41T93_FLAG_BL			(1 << 4)
+#define M41T93_FLAG_HT			(1 << 6)
+
+static inline int m41t93_set_reg(struct spi_device *spi, u8 addr, u8 data)
+{
+	u8 buf[2];
+
+	/* MSB must be '1' to write */
+	buf[0] = addr | 0x80;
+	buf[1] = data;
+
+	return spi_write(spi, buf, sizeof(buf));
+}
+
+static int m41t93_set_time(struct device *dev, struct rtc_time *tm)
+{
+	struct spi_device *spi = to_spi_device(dev);
+	u8 buf[9] = {0x80};        /* write cmd + 8 data bytes */
+	u8 * const data = &buf[1]; /* ptr to first data byte */
+
+	dev_dbg(dev, "%s secs=%d, mins=%d, "
+		"hours=%d, mday=%d, mon=%d, year=%d, wday=%d\n",
+		"write", tm->tm_sec, tm->tm_min,
+		tm->tm_hour, tm->tm_mday,
+		tm->tm_mon, tm->tm_year, tm->tm_wday);
+
+	if (tm->tm_year < 100) {
+		dev_warn(&spi->dev, "unsupported date (before 2000-01-01).\n");
+		return -EINVAL;
+	}
+
+	data[M41T93_REG_SSEC]		= 0;
+	data[M41T93_REG_ST_SEC]		= bin2bcd(tm->tm_sec);
+	data[M41T93_REG_MIN]		= bin2bcd(tm->tm_min);
+	data[M41T93_REG_CENT_HOUR]	= bin2bcd(tm->tm_hour) |
+						((tm->tm_year/100-1) << 6);
+	data[M41T93_REG_DAY]		= bin2bcd(tm->tm_mday);
+	data[M41T93_REG_WDAY]		= bin2bcd(tm->tm_wday + 1);
+	data[M41T93_REG_MON]		= bin2bcd(tm->tm_mon + 1);
+	data[M41T93_REG_YEAR]		= bin2bcd(tm->tm_year % 100);
+
+	return spi_write(spi, buf, sizeof(buf));
+}
+
+
+static int m41t93_get_time(struct device *dev, struct rtc_time *tm)
+{
+	struct spi_device *spi = to_spi_device(dev);
+	const u8 start_addr = 0;
+	u8 buf[8];
+	int century_after_1900;
+	int tmp;
+	int ret = 0;
+
+	/* Check status of clock. Two states must be considered:
+	   1. halt bit (HT) is set: the clock is running but update of readout
+	      registers has been disabled due to power failure. This is normal
+	      case after poweron. Time is valid after resetting HT bit.
+	   2. oscillator fail bit (OF) is set. Oscillator has be stopped and
+	      time is invalid:
+	      a) OF can be immeditely reset.
+	      b) OF cannot be immediately reset: oscillator has to be restarted.
+	*/
+	tmp = spi_w8r8(spi, M41T93_REG_ALM_HOUR_HT);
+	if (tmp < 0)
+		return tmp;
+
+	if (tmp & M41T93_FLAG_HT) {
+		dev_dbg(&spi->dev, "HT bit is set, reenable clock update.\n");
+		m41t93_set_reg(spi, M41T93_REG_ALM_HOUR_HT,
+			       tmp & ~M41T93_FLAG_HT);
+	}
+
+	tmp = spi_w8r8(spi, M41T93_REG_FLAGS);
+	if (tmp < 0)
+		return tmp;
+
+	if (tmp & M41T93_FLAG_OF) {
+		ret = -EINVAL;
+		dev_warn(&spi->dev, "OF bit is set, resetting.\n");
+		m41t93_set_reg(spi, M41T93_REG_FLAGS, tmp & ~M41T93_FLAG_OF);
+
+		tmp = spi_w8r8(spi, M41T93_REG_FLAGS);
+		if (tmp < 0)
+			return tmp;
+		else if (tmp & M41T93_FLAG_OF) {
+			u8 reset_osc = buf[M41T93_REG_ST_SEC] | M41T93_FLAG_ST;
+
+			dev_warn(&spi->dev,
+				 "OF bit is still set, kickstarting clock.\n");
+			m41t93_set_reg(spi, M41T93_REG_ST_SEC, reset_osc);
+			reset_osc &= ~M41T93_FLAG_ST;
+			m41t93_set_reg(spi, M41T93_REG_ST_SEC, reset_osc);
+		}
+	}
+
+	if (tmp & M41T93_FLAG_BL)
+		dev_warn(&spi->dev, "BL bit is set, replace battery.\n");
+
+	/* read actual time/date */
+	tmp = spi_write_then_read(spi, &start_addr, 1, buf, sizeof(buf));
+	if (tmp < 0)
+		return tmp;
+
+	tm->tm_sec	= bcd2bin(buf[M41T93_REG_ST_SEC]);
+	tm->tm_min	= bcd2bin(buf[M41T93_REG_MIN]);
+	tm->tm_hour	= bcd2bin(buf[M41T93_REG_CENT_HOUR] & 0x3f);
+	tm->tm_mday	= bcd2bin(buf[M41T93_REG_DAY]);
+	tm->tm_mon	= bcd2bin(buf[M41T93_REG_MON]) - 1;
+	tm->tm_wday	= bcd2bin(buf[M41T93_REG_WDAY] & 0x0f) - 1;
+
+	century_after_1900 = (buf[M41T93_REG_CENT_HOUR] >> 6) + 1;
+	tm->tm_year = bcd2bin(buf[M41T93_REG_YEAR]) + century_after_1900 * 100;
+
+	dev_dbg(dev, "%s secs=%d, mins=%d, "
+		"hours=%d, mday=%d, mon=%d, year=%d, wday=%d\n",
+		"read", tm->tm_sec, tm->tm_min,
+		tm->tm_hour, tm->tm_mday,
+		tm->tm_mon, tm->tm_year, tm->tm_wday);
+
+	return ret < 0 ? ret : rtc_valid_tm(tm);
+}
+
+
+static const struct rtc_class_ops m41t93_rtc_ops = {
+	.read_time	= m41t93_get_time,
+	.set_time	= m41t93_set_time,
+};
+
+static struct spi_driver m41t93_driver;
+
+static int __devinit m41t93_probe(struct spi_device *spi)
+{
+	struct rtc_device *rtc;
+	int res;
+
+	spi->bits_per_word = 8;
+	spi_setup(spi);
+
+	res = spi_w8r8(spi, M41T93_REG_WDAY);
+	if (res < 0 || (res & 0xf8) != 0) {
+		dev_err(&spi->dev, "not found 0x%x.\n", res);
+		return -ENODEV;
+	}
+
+	rtc = rtc_device_register(m41t93_driver.driver.name,
+		&spi->dev, &m41t93_rtc_ops, THIS_MODULE);
+	if (IS_ERR(rtc))
+		return PTR_ERR(rtc);
+
+	dev_set_drvdata(&spi->dev, rtc);
+
+	return 0;
+}
+
+
+static int __devexit m41t93_remove(struct spi_device *spi)
+{
+	struct rtc_device *rtc = spi_get_drvdata(spi);
+
+	if (rtc)
+		rtc_device_unregister(rtc);
+
+	return 0;
+}
+
+static struct spi_driver m41t93_driver = {
+	.driver = {
+		.name	= "rtc-m41t93",
+		.bus	= &spi_bus_type,
+		.owner	= THIS_MODULE,
+	},
+	.probe	= m41t93_probe,
+	.remove = __devexit_p(m41t93_remove),
+};
+
+static __init int m41t93_init(void)
+{
+	return spi_register_driver(&m41t93_driver);
+}
+module_init(m41t93_init);
+
+static __exit void m41t93_exit(void)
+{
+	spi_unregister_driver(&m41t93_driver);
+}
+module_exit(m41t93_exit);
+
+MODULE_AUTHOR("Nikolaus Voss <n.voss@weinmann.de>");
+MODULE_DESCRIPTION("Driver for ST M41T93 SPI RTC");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("spi:rtc-m41t93");
diff -druN linux-2.6.39-libre/drivers/rtc/rtc-mrst.c linux-3.0-rc7-libre/drivers/rtc/rtc-mrst.c
--- linux-2.6.39-libre/drivers/rtc/rtc-mrst.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/rtc/rtc-mrst.c	2011-07-11 19:51:52.000000000 -0400
@@ -380,7 +380,7 @@
 cleanup0:
 	dev_set_drvdata(dev, NULL);
 	mrst_rtc.dev = NULL;
-	release_region(iomem->start, iomem->end + 1 - iomem->start);
+	release_mem_region(iomem->start, resource_size(iomem));
 	dev_err(dev, "rtc-mrst: unable to initialise\n");
 	return retval;
 }
@@ -406,7 +406,7 @@
 	mrst->rtc = NULL;
 
 	iomem = mrst->iomem;
-	release_region(iomem->start, iomem->end + 1 - iomem->start);
+	release_mem_region(iomem->start, resource_size(iomem));
 	mrst->iomem = NULL;
 
 	mrst->dev = NULL;
diff -druN linux-2.6.39-libre/drivers/rtc/rtc-mxc.c linux-3.0-rc7-libre/drivers/rtc/rtc-mxc.c
--- linux-2.6.39-libre/drivers/rtc/rtc-mxc.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/rtc/rtc-mxc.c	2011-07-11 19:51:52.000000000 -0400
@@ -55,12 +55,6 @@
 	{ MAX_PIE_FREQ,	RTC_SAM7_BIT },
 };
 
-/* Those are the bits from a classic RTC we want to mimic */
-#define RTC_IRQF	0x80	/* any of the following 3 is active */
-#define RTC_PF		0x40	/* Periodic interrupt */
-#define RTC_AF		0x20	/* Alarm interrupt */
-#define RTC_UF		0x10	/* Update interrupt for 1Hz RTC */
-
 #define MXC_RTC_TIME	0
 #define MXC_RTC_ALARM	1
 
diff -druN linux-2.6.39-libre/drivers/rtc/rtc-pcf50633.c linux-3.0-rc7-libre/drivers/rtc/rtc-pcf50633.c
--- linux-2.6.39-libre/drivers/rtc/rtc-pcf50633.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/rtc/rtc-pcf50633.c	2011-07-11 19:51:52.000000000 -0400
@@ -58,7 +58,6 @@
 
 struct pcf50633_rtc {
 	int alarm_enabled;
-	int second_enabled;
 	int alarm_pending;
 
 	struct pcf50633 *pcf;
@@ -143,7 +142,7 @@
 {
 	struct pcf50633_rtc *rtc;
 	struct pcf50633_time pcf_tm;
-	int second_masked, alarm_masked, ret = 0;
+	int alarm_masked, ret = 0;
 
 	rtc = dev_get_drvdata(dev);
 
@@ -162,11 +161,8 @@
 		pcf_tm.time[PCF50633_TI_SEC]);
 
 
-	second_masked = pcf50633_irq_mask_get(rtc->pcf, PCF50633_IRQ_SECOND);
 	alarm_masked = pcf50633_irq_mask_get(rtc->pcf, PCF50633_IRQ_ALARM);
 
-	if (!second_masked)
-		pcf50633_irq_mask(rtc->pcf, PCF50633_IRQ_SECOND);
 	if (!alarm_masked)
 		pcf50633_irq_mask(rtc->pcf, PCF50633_IRQ_ALARM);
 
@@ -175,8 +171,6 @@
 					     PCF50633_TI_EXTENT,
 					     &pcf_tm.time[0]);
 
-	if (!second_masked)
-		pcf50633_irq_unmask(rtc->pcf, PCF50633_IRQ_SECOND);
 	if (!alarm_masked)
 		pcf50633_irq_unmask(rtc->pcf, PCF50633_IRQ_ALARM);
 
@@ -250,15 +244,8 @@
 {
 	struct pcf50633_rtc *rtc = data;
 
-	switch (irq) {
-	case PCF50633_IRQ_ALARM:
-		rtc_update_irq(rtc->rtc_dev, 1, RTC_AF | RTC_IRQF);
-		rtc->alarm_pending = 1;
-		break;
-	case PCF50633_IRQ_SECOND:
-		rtc_update_irq(rtc->rtc_dev, 1, RTC_UF | RTC_IRQF);
-		break;
-	}
+	rtc_update_irq(rtc->rtc_dev, 1, RTC_AF | RTC_IRQF);
+	rtc->alarm_pending = 1;
 }
 
 static int __devinit pcf50633_rtc_probe(struct platform_device *pdev)
@@ -282,9 +269,6 @@
 
 	pcf50633_register_irq(rtc->pcf, PCF50633_IRQ_ALARM,
 					pcf50633_rtc_irq, rtc);
-	pcf50633_register_irq(rtc->pcf, PCF50633_IRQ_SECOND,
-					pcf50633_rtc_irq, rtc);
-
 	return 0;
 }
 
@@ -295,7 +279,6 @@
 	rtc = platform_get_drvdata(pdev);
 
 	pcf50633_free_irq(rtc->pcf, PCF50633_IRQ_ALARM);
-	pcf50633_free_irq(rtc->pcf, PCF50633_IRQ_SECOND);
 
 	rtc_device_unregister(rtc->rtc_dev);
 	kfree(rtc);
diff -druN linux-2.6.39-libre/drivers/rtc/rtc-puv3.c linux-3.0-rc7-libre/drivers/rtc/rtc-puv3.c
--- linux-2.6.39-libre/drivers/rtc/rtc-puv3.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/rtc/rtc-puv3.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,359 @@
+/*
+ * RTC driver code specific to PKUnity SoC and UniCore ISA
+ *
+ *	Maintained by GUAN Xue-tao <gxt@mprc.pku.edu.cn>
+ *	Copyright (C) 2001-2010 Guan Xuetao
+ *
+ * This program is free software; you can redistribute it 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/fs.h>
+#include <linux/string.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/interrupt.h>
+#include <linux/rtc.h>
+#include <linux/bcd.h>
+#include <linux/clk.h>
+#include <linux/log2.h>
+#include <linux/slab.h>
+#include <linux/uaccess.h>
+#include <linux/io.h>
+
+#include <asm/irq.h>
+#include <mach/hardware.h>
+
+static struct resource *puv3_rtc_mem;
+
+static int puv3_rtc_alarmno = IRQ_RTCAlarm;
+static int puv3_rtc_tickno  = IRQ_RTC;
+
+static DEFINE_SPINLOCK(puv3_rtc_pie_lock);
+
+/* IRQ Handlers */
+static irqreturn_t puv3_rtc_alarmirq(int irq, void *id)
+{
+	struct rtc_device *rdev = id;
+
+	writel(readl(RTC_RTSR) | RTC_RTSR_AL, RTC_RTSR);
+	rtc_update_irq(rdev, 1, RTC_AF | RTC_IRQF);
+	return IRQ_HANDLED;
+}
+
+static irqreturn_t puv3_rtc_tickirq(int irq, void *id)
+{
+	struct rtc_device *rdev = id;
+
+	writel(readl(RTC_RTSR) | RTC_RTSR_HZ, RTC_RTSR);
+	rtc_update_irq(rdev, 1, RTC_PF | RTC_IRQF);
+	return IRQ_HANDLED;
+}
+
+/* Update control registers */
+static void puv3_rtc_setaie(int to)
+{
+	unsigned int tmp;
+
+	pr_debug("%s: aie=%d\n", __func__, to);
+
+	tmp = readl(RTC_RTSR) & ~RTC_RTSR_ALE;
+
+	if (to)
+		tmp |= RTC_RTSR_ALE;
+
+	writel(tmp, RTC_RTSR);
+}
+
+static int puv3_rtc_setpie(struct device *dev, int enabled)
+{
+	unsigned int tmp;
+
+	pr_debug("%s: pie=%d\n", __func__, enabled);
+
+	spin_lock_irq(&puv3_rtc_pie_lock);
+	tmp = readl(RTC_RTSR) & ~RTC_RTSR_HZE;
+
+	if (enabled)
+		tmp |= RTC_RTSR_HZE;
+
+	writel(tmp, RTC_RTSR);
+	spin_unlock_irq(&puv3_rtc_pie_lock);
+
+	return 0;
+}
+
+/* Time read/write */
+static int puv3_rtc_gettime(struct device *dev, struct rtc_time *rtc_tm)
+{
+	rtc_time_to_tm(readl(RTC_RCNR), rtc_tm);
+
+	pr_debug("read time %02x.%02x.%02x %02x/%02x/%02x\n",
+		 rtc_tm->tm_year, rtc_tm->tm_mon, rtc_tm->tm_mday,
+		 rtc_tm->tm_hour, rtc_tm->tm_min, rtc_tm->tm_sec);
+
+	return 0;
+}
+
+static int puv3_rtc_settime(struct device *dev, struct rtc_time *tm)
+{
+	unsigned long rtc_count = 0;
+
+	pr_debug("set time %02d.%02d.%02d %02d/%02d/%02d\n",
+		 tm->tm_year, tm->tm_mon, tm->tm_mday,
+		 tm->tm_hour, tm->tm_min, tm->tm_sec);
+
+	rtc_tm_to_time(tm, &rtc_count);
+	writel(rtc_count, RTC_RCNR);
+
+	return 0;
+}
+
+static int puv3_rtc_getalarm(struct device *dev, struct rtc_wkalrm *alrm)
+{
+	struct rtc_time *alm_tm = &alrm->time;
+
+	rtc_time_to_tm(readl(RTC_RTAR), alm_tm);
+
+	alrm->enabled = readl(RTC_RTSR) & RTC_RTSR_ALE;
+
+	pr_debug("read alarm %02x %02x.%02x.%02x %02x/%02x/%02x\n",
+		 alrm->enabled,
+		 alm_tm->tm_year, alm_tm->tm_mon, alm_tm->tm_mday,
+		 alm_tm->tm_hour, alm_tm->tm_min, alm_tm->tm_sec);
+
+	return 0;
+}
+
+static int puv3_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm)
+{
+	struct rtc_time *tm = &alrm->time;
+	unsigned long rtcalarm_count = 0;
+
+	pr_debug("puv3_rtc_setalarm: %d, %02x/%02x/%02x %02x.%02x.%02x\n",
+		 alrm->enabled,
+		 tm->tm_mday & 0xff, tm->tm_mon & 0xff, tm->tm_year & 0xff,
+		 tm->tm_hour & 0xff, tm->tm_min & 0xff, tm->tm_sec);
+
+	rtc_tm_to_time(tm, &rtcalarm_count);
+	writel(rtcalarm_count, RTC_RTAR);
+
+	puv3_rtc_setaie(alrm->enabled);
+
+	if (alrm->enabled)
+		enable_irq_wake(puv3_rtc_alarmno);
+	else
+		disable_irq_wake(puv3_rtc_alarmno);
+
+	return 0;
+}
+
+static int puv3_rtc_proc(struct device *dev, struct seq_file *seq)
+{
+	seq_printf(seq, "periodic_IRQ\t: %s\n",
+		     (readl(RTC_RTSR) & RTC_RTSR_HZE) ? "yes" : "no");
+	return 0;
+}
+
+static int puv3_rtc_open(struct device *dev)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct rtc_device *rtc_dev = platform_get_drvdata(pdev);
+	int ret;
+
+	ret = request_irq(puv3_rtc_alarmno, puv3_rtc_alarmirq,
+			  IRQF_DISABLED,  "pkunity-rtc alarm", rtc_dev);
+
+	if (ret) {
+		dev_err(dev, "IRQ%d error %d\n", puv3_rtc_alarmno, ret);
+		return ret;
+	}
+
+	ret = request_irq(puv3_rtc_tickno, puv3_rtc_tickirq,
+			  IRQF_DISABLED,  "pkunity-rtc tick", rtc_dev);
+
+	if (ret) {
+		dev_err(dev, "IRQ%d error %d\n", puv3_rtc_tickno, ret);
+		goto tick_err;
+	}
+
+	return ret;
+
+ tick_err:
+	free_irq(puv3_rtc_alarmno, rtc_dev);
+	return ret;
+}
+
+static void puv3_rtc_release(struct device *dev)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct rtc_device *rtc_dev = platform_get_drvdata(pdev);
+
+	/* do not clear AIE here, it may be needed for wake */
+	puv3_rtc_setpie(dev, 0);
+	free_irq(puv3_rtc_alarmno, rtc_dev);
+	free_irq(puv3_rtc_tickno, rtc_dev);
+}
+
+static const struct rtc_class_ops puv3_rtcops = {
+	.open		= puv3_rtc_open,
+	.release	= puv3_rtc_release,
+	.read_time	= puv3_rtc_gettime,
+	.set_time	= puv3_rtc_settime,
+	.read_alarm	= puv3_rtc_getalarm,
+	.set_alarm	= puv3_rtc_setalarm,
+	.proc	        = puv3_rtc_proc,
+};
+
+static void puv3_rtc_enable(struct platform_device *pdev, int en)
+{
+	if (!en) {
+		writel(readl(RTC_RTSR) & ~RTC_RTSR_HZE, RTC_RTSR);
+	} else {
+		/* re-enable the device, and check it is ok */
+		if ((readl(RTC_RTSR) & RTC_RTSR_HZE) == 0) {
+			dev_info(&pdev->dev, "rtc disabled, re-enabling\n");
+			writel(readl(RTC_RTSR) | RTC_RTSR_HZE, RTC_RTSR);
+		}
+	}
+}
+
+static int puv3_rtc_remove(struct platform_device *dev)
+{
+	struct rtc_device *rtc = platform_get_drvdata(dev);
+
+	platform_set_drvdata(dev, NULL);
+	rtc_device_unregister(rtc);
+
+	puv3_rtc_setpie(&dev->dev, 0);
+	puv3_rtc_setaie(0);
+
+	release_resource(puv3_rtc_mem);
+	kfree(puv3_rtc_mem);
+
+	return 0;
+}
+
+static int puv3_rtc_probe(struct platform_device *pdev)
+{
+	struct rtc_device *rtc;
+	struct resource *res;
+	int ret;
+
+	pr_debug("%s: probe=%p\n", __func__, pdev);
+
+	/* find the IRQs */
+	puv3_rtc_tickno = platform_get_irq(pdev, 1);
+	if (puv3_rtc_tickno < 0) {
+		dev_err(&pdev->dev, "no irq for rtc tick\n");
+		return -ENOENT;
+	}
+
+	puv3_rtc_alarmno = platform_get_irq(pdev, 0);
+	if (puv3_rtc_alarmno < 0) {
+		dev_err(&pdev->dev, "no irq for alarm\n");
+		return -ENOENT;
+	}
+
+	pr_debug("PKUnity_rtc: tick irq %d, alarm irq %d\n",
+		 puv3_rtc_tickno, puv3_rtc_alarmno);
+
+	/* get the memory region */
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (res == NULL) {
+		dev_err(&pdev->dev, "failed to get memory region resource\n");
+		return -ENOENT;
+	}
+
+	puv3_rtc_mem = request_mem_region(res->start,
+					 res->end-res->start+1,
+					 pdev->name);
+
+	if (puv3_rtc_mem == NULL) {
+		dev_err(&pdev->dev, "failed to reserve memory region\n");
+		ret = -ENOENT;
+		goto err_nores;
+	}
+
+	puv3_rtc_enable(pdev, 1);
+
+	/* register RTC and exit */
+	rtc = rtc_device_register("pkunity", &pdev->dev, &puv3_rtcops,
+				  THIS_MODULE);
+
+	if (IS_ERR(rtc)) {
+		dev_err(&pdev->dev, "cannot attach rtc\n");
+		ret = PTR_ERR(rtc);
+		goto err_nortc;
+	}
+
+	/* platform setup code should have handled this; sigh */
+	if (!device_can_wakeup(&pdev->dev))
+		device_init_wakeup(&pdev->dev, 1);
+
+	platform_set_drvdata(pdev, rtc);
+	return 0;
+
+ err_nortc:
+	puv3_rtc_enable(pdev, 0);
+	release_resource(puv3_rtc_mem);
+
+ err_nores:
+	return ret;
+}
+
+#ifdef CONFIG_PM
+
+static int ticnt_save;
+
+static int puv3_rtc_suspend(struct platform_device *pdev, pm_message_t state)
+{
+	/* save RTAR for anyone using periodic interrupts */
+	ticnt_save = readl(RTC_RTAR);
+	puv3_rtc_enable(pdev, 0);
+	return 0;
+}
+
+static int puv3_rtc_resume(struct platform_device *pdev)
+{
+	puv3_rtc_enable(pdev, 1);
+	writel(ticnt_save, RTC_RTAR);
+	return 0;
+}
+#else
+#define puv3_rtc_suspend NULL
+#define puv3_rtc_resume  NULL
+#endif
+
+static struct platform_driver puv3_rtcdrv = {
+	.probe		= puv3_rtc_probe,
+	.remove		= __devexit_p(puv3_rtc_remove),
+	.suspend	= puv3_rtc_suspend,
+	.resume		= puv3_rtc_resume,
+	.driver		= {
+		.name	= "PKUnity-v3-RTC",
+		.owner	= THIS_MODULE,
+	}
+};
+
+static char __initdata banner[] = "PKUnity-v3 RTC, (c) 2009 PKUnity Co.\n";
+
+static int __init puv3_rtc_init(void)
+{
+	printk(banner);
+	return platform_driver_register(&puv3_rtcdrv);
+}
+
+static void __exit puv3_rtc_exit(void)
+{
+	platform_driver_unregister(&puv3_rtcdrv);
+}
+
+module_init(puv3_rtc_init);
+module_exit(puv3_rtc_exit);
+
+MODULE_DESCRIPTION("RTC Driver for the PKUnity v3 chip");
+MODULE_AUTHOR("Hu Dongliang");
+MODULE_LICENSE("GPL v2");
diff -druN linux-2.6.39-libre/drivers/rtc/rtc-rv3029c2.c linux-3.0-rc7-libre/drivers/rtc/rtc-rv3029c2.c
--- linux-2.6.39-libre/drivers/rtc/rtc-rv3029c2.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/rtc/rtc-rv3029c2.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,454 @@
+/*
+ * Micro Crystal RV-3029C2 rtc class driver
+ *
+ * Author: Gregory Hermant <gregory.hermant@calao-systems.com>
+ *
+ * based on previously existing rtc class drivers
+ *
+ * This program is free software; you can 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: Currently this driver only supports the bare minimum for read
+ * and write the RTC and alarms. The extra features provided by this chip
+ * (trickle charger, eeprom, T° compensation) are unavailable.
+ */
+
+#include <linux/module.h>
+#include <linux/i2c.h>
+#include <linux/bcd.h>
+#include <linux/rtc.h>
+
+/* Register map */
+/* control section */
+#define RV3029C2_ONOFF_CTRL		0x00
+#define RV3029C2_IRQ_CTRL		0x01
+#define RV3029C2_IRQ_CTRL_AIE		(1 << 0)
+#define RV3029C2_IRQ_FLAGS		0x02
+#define RV3029C2_IRQ_FLAGS_AF		(1 << 0)
+#define RV3029C2_STATUS			0x03
+#define RV3029C2_STATUS_VLOW1		(1 << 2)
+#define RV3029C2_STATUS_VLOW2		(1 << 3)
+#define RV3029C2_STATUS_SR		(1 << 4)
+#define RV3029C2_STATUS_PON		(1 << 5)
+#define RV3029C2_STATUS_EEBUSY		(1 << 7)
+#define RV3029C2_RST_CTRL		0x04
+#define RV3029C2_CONTROL_SECTION_LEN	0x05
+
+/* watch section */
+#define RV3029C2_W_SEC			0x08
+#define RV3029C2_W_MINUTES		0x09
+#define RV3029C2_W_HOURS		0x0A
+#define RV3029C2_REG_HR_12_24		(1<<6)  /* 24h/12h mode */
+#define RV3029C2_REG_HR_PM		(1<<5)  /* PM/AM bit in 12h mode */
+#define RV3029C2_W_DATE			0x0B
+#define RV3029C2_W_DAYS			0x0C
+#define RV3029C2_W_MONTHS		0x0D
+#define RV3029C2_W_YEARS		0x0E
+#define RV3029C2_WATCH_SECTION_LEN	0x07
+
+/* alarm section */
+#define RV3029C2_A_SC			0x10
+#define RV3029C2_A_MN			0x11
+#define RV3029C2_A_HR			0x12
+#define RV3029C2_A_DT			0x13
+#define RV3029C2_A_DW			0x14
+#define RV3029C2_A_MO			0x15
+#define RV3029C2_A_YR			0x16
+#define RV3029C2_ALARM_SECTION_LEN	0x07
+
+/* timer section */
+#define RV3029C2_TIMER_LOW		0x18
+#define RV3029C2_TIMER_HIGH		0x19
+
+/* temperature section */
+#define RV3029C2_TEMP_PAGE		0x20
+
+/* eeprom data section */
+#define RV3029C2_E2P_EEDATA1		0x28
+#define RV3029C2_E2P_EEDATA2		0x29
+
+/* eeprom control section */
+#define RV3029C2_CONTROL_E2P_EECTRL	0x30
+#define RV3029C2_TRICKLE_1K		(1<<0)  /*  1K resistance */
+#define RV3029C2_TRICKLE_5K		(1<<1)  /*  5K resistance */
+#define RV3029C2_TRICKLE_20K		(1<<2)  /* 20K resistance */
+#define RV3029C2_TRICKLE_80K		(1<<3)  /* 80K resistance */
+#define RV3029C2_CONTROL_E2P_XTALOFFSET	0x31
+#define RV3029C2_CONTROL_E2P_QCOEF	0x32
+#define RV3029C2_CONTROL_E2P_TURNOVER	0x33
+
+/* user ram section */
+#define RV3029C2_USR1_RAM_PAGE		0x38
+#define RV3029C2_USR1_SECTION_LEN	0x04
+#define RV3029C2_USR2_RAM_PAGE		0x3C
+#define RV3029C2_USR2_SECTION_LEN	0x04
+
+static int
+rv3029c2_i2c_read_regs(struct i2c_client *client, u8 reg, u8 *buf,
+	unsigned len)
+{
+	int ret;
+
+	if ((reg > RV3029C2_USR1_RAM_PAGE + 7) ||
+		(reg + len > RV3029C2_USR1_RAM_PAGE + 8))
+		return -EINVAL;
+
+	ret = i2c_smbus_read_i2c_block_data(client, reg, len, buf);
+	if (ret < 0)
+		return ret;
+	if (ret < len)
+		return -EIO;
+	return 0;
+}
+
+static int
+rv3029c2_i2c_write_regs(struct i2c_client *client, u8 reg, u8 const buf[],
+			unsigned len)
+{
+	if ((reg > RV3029C2_USR1_RAM_PAGE + 7) ||
+		(reg + len > RV3029C2_USR1_RAM_PAGE + 8))
+		return -EINVAL;
+
+	return i2c_smbus_write_i2c_block_data(client, reg, len, buf);
+}
+
+static int
+rv3029c2_i2c_get_sr(struct i2c_client *client, u8 *buf)
+{
+	int ret = rv3029c2_i2c_read_regs(client, RV3029C2_STATUS, buf, 1);
+
+	if (ret < 0)
+		return -EIO;
+	dev_dbg(&client->dev, "status = 0x%.2x (%d)\n", buf[0], buf[0]);
+	return 0;
+}
+
+static int
+rv3029c2_i2c_set_sr(struct i2c_client *client, u8 val)
+{
+	u8 buf[1];
+	int sr;
+
+	buf[0] = val;
+	sr = rv3029c2_i2c_write_regs(client, RV3029C2_STATUS, buf, 1);
+	dev_dbg(&client->dev, "status = 0x%.2x (%d)\n", buf[0], buf[0]);
+	if (sr < 0)
+		return -EIO;
+	return 0;
+}
+
+static int
+rv3029c2_i2c_read_time(struct i2c_client *client, struct rtc_time *tm)
+{
+	u8 buf[1];
+	int ret;
+	u8 regs[RV3029C2_WATCH_SECTION_LEN] = { 0, };
+
+	ret = rv3029c2_i2c_get_sr(client, buf);
+	if (ret < 0) {
+		dev_err(&client->dev, "%s: reading SR failed\n", __func__);
+		return -EIO;
+	}
+
+	ret = rv3029c2_i2c_read_regs(client, RV3029C2_W_SEC , regs,
+					RV3029C2_WATCH_SECTION_LEN);
+	if (ret < 0) {
+		dev_err(&client->dev, "%s: reading RTC section failed\n",
+			__func__);
+		return ret;
+	}
+
+	tm->tm_sec = bcd2bin(regs[RV3029C2_W_SEC-RV3029C2_W_SEC]);
+	tm->tm_min = bcd2bin(regs[RV3029C2_W_MINUTES-RV3029C2_W_SEC]);
+
+	/* HR field has a more complex interpretation */
+	{
+		const u8 _hr = regs[RV3029C2_W_HOURS-RV3029C2_W_SEC];
+		if (_hr & RV3029C2_REG_HR_12_24) {
+			/* 12h format */
+			tm->tm_hour = bcd2bin(_hr & 0x1f);
+			if (_hr & RV3029C2_REG_HR_PM)	/* PM flag set */
+				tm->tm_hour += 12;
+		} else /* 24h format */
+			tm->tm_hour = bcd2bin(_hr & 0x3f);
+	}
+
+	tm->tm_mday = bcd2bin(regs[RV3029C2_W_DATE-RV3029C2_W_SEC]);
+	tm->tm_mon = bcd2bin(regs[RV3029C2_W_MONTHS-RV3029C2_W_SEC]) - 1;
+	tm->tm_year = bcd2bin(regs[RV3029C2_W_YEARS-RV3029C2_W_SEC]) + 100;
+	tm->tm_wday = bcd2bin(regs[RV3029C2_W_DAYS-RV3029C2_W_SEC]) - 1;
+
+	return 0;
+}
+
+static int rv3029c2_rtc_read_time(struct device *dev, struct rtc_time *tm)
+{
+	return rv3029c2_i2c_read_time(to_i2c_client(dev), tm);
+}
+
+static int
+rv3029c2_i2c_read_alarm(struct i2c_client *client, struct rtc_wkalrm *alarm)
+{
+	struct rtc_time *const tm = &alarm->time;
+	int ret;
+	u8 regs[8];
+
+	ret = rv3029c2_i2c_get_sr(client, regs);
+	if (ret < 0) {
+		dev_err(&client->dev, "%s: reading SR failed\n", __func__);
+		return -EIO;
+	}
+
+	ret = rv3029c2_i2c_read_regs(client, RV3029C2_A_SC, regs,
+					RV3029C2_ALARM_SECTION_LEN);
+
+	if (ret < 0) {
+		dev_err(&client->dev, "%s: reading alarm section failed\n",
+			__func__);
+		return ret;
+	}
+
+	tm->tm_sec = bcd2bin(regs[RV3029C2_A_SC-RV3029C2_A_SC] & 0x7f);
+	tm->tm_min = bcd2bin(regs[RV3029C2_A_MN-RV3029C2_A_SC] & 0x7f);
+	tm->tm_hour = bcd2bin(regs[RV3029C2_A_HR-RV3029C2_A_SC] & 0x3f);
+	tm->tm_mday = bcd2bin(regs[RV3029C2_A_DT-RV3029C2_A_SC] & 0x3f);
+	tm->tm_mon = bcd2bin(regs[RV3029C2_A_MO-RV3029C2_A_SC] & 0x1f) - 1;
+	tm->tm_year = bcd2bin(regs[RV3029C2_A_YR-RV3029C2_A_SC] & 0x7f) + 100;
+	tm->tm_wday = bcd2bin(regs[RV3029C2_A_DW-RV3029C2_A_SC] & 0x07) - 1;
+
+	return 0;
+}
+
+static int
+rv3029c2_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm)
+{
+	return rv3029c2_i2c_read_alarm(to_i2c_client(dev), alarm);
+}
+
+static int rv3029c2_rtc_i2c_alarm_set_irq(struct i2c_client *client,
+					int enable)
+{
+	int ret;
+	u8 buf[1];
+
+	/* enable AIE irq */
+	ret = rv3029c2_i2c_read_regs(client, RV3029C2_IRQ_CTRL,	buf, 1);
+	if (ret < 0) {
+		dev_err(&client->dev, "can't read INT reg\n");
+		return ret;
+	}
+	if (enable)
+		buf[0] |= RV3029C2_IRQ_CTRL_AIE;
+	else
+		buf[0] &= ~RV3029C2_IRQ_CTRL_AIE;
+
+	ret = rv3029c2_i2c_write_regs(client, RV3029C2_IRQ_CTRL, buf, 1);
+	if (ret < 0) {
+		dev_err(&client->dev, "can't set INT reg\n");
+		return ret;
+	}
+
+	return 0;
+}
+
+static int rv3029c2_rtc_i2c_set_alarm(struct i2c_client *client,
+					struct rtc_wkalrm *alarm)
+{
+	struct rtc_time *const tm = &alarm->time;
+	int ret;
+	u8 regs[8];
+
+	/*
+	 * The clock has an 8 bit wide bcd-coded register (they never learn)
+	 * for the year. tm_year is an offset from 1900 and we are interested
+	 * in the 2000-2099 range, so any value less than 100 is invalid.
+	*/
+	if (tm->tm_year < 100)
+		return -EINVAL;
+
+	ret = rv3029c2_i2c_get_sr(client, regs);
+	if (ret < 0) {
+		dev_err(&client->dev, "%s: reading SR failed\n", __func__);
+		return -EIO;
+	}
+	regs[RV3029C2_A_SC-RV3029C2_A_SC] = bin2bcd(tm->tm_sec & 0x7f);
+	regs[RV3029C2_A_MN-RV3029C2_A_SC] = bin2bcd(tm->tm_min & 0x7f);
+	regs[RV3029C2_A_HR-RV3029C2_A_SC] = bin2bcd(tm->tm_hour & 0x3f);
+	regs[RV3029C2_A_DT-RV3029C2_A_SC] = bin2bcd(tm->tm_mday & 0x3f);
+	regs[RV3029C2_A_MO-RV3029C2_A_SC] = bin2bcd((tm->tm_mon & 0x1f) - 1);
+	regs[RV3029C2_A_DW-RV3029C2_A_SC] = bin2bcd((tm->tm_wday & 7) - 1);
+	regs[RV3029C2_A_YR-RV3029C2_A_SC] = bin2bcd((tm->tm_year & 0x7f) - 100);
+
+	ret = rv3029c2_i2c_write_regs(client, RV3029C2_A_SC, regs,
+					RV3029C2_ALARM_SECTION_LEN);
+	if (ret < 0)
+		return ret;
+
+	if (alarm->enabled) {
+		u8 buf[1];
+
+		/* clear AF flag */
+		ret = rv3029c2_i2c_read_regs(client, RV3029C2_IRQ_FLAGS,
+						buf, 1);
+		if (ret < 0) {
+			dev_err(&client->dev, "can't read alarm flag\n");
+			return ret;
+		}
+		buf[0] &= ~RV3029C2_IRQ_FLAGS_AF;
+		ret = rv3029c2_i2c_write_regs(client, RV3029C2_IRQ_FLAGS,
+						buf, 1);
+		if (ret < 0) {
+			dev_err(&client->dev, "can't set alarm flag\n");
+			return ret;
+		}
+		/* enable AIE irq */
+		ret = rv3029c2_rtc_i2c_alarm_set_irq(client, 1);
+		if (ret)
+			return ret;
+
+		dev_dbg(&client->dev, "alarm IRQ armed\n");
+	} else {
+		/* disable AIE irq */
+		ret = rv3029c2_rtc_i2c_alarm_set_irq(client, 1);
+		if (ret)
+			return ret;
+
+		dev_dbg(&client->dev, "alarm IRQ disabled\n");
+	}
+
+	return 0;
+}
+
+static int rv3029c2_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
+{
+	return rv3029c2_rtc_i2c_set_alarm(to_i2c_client(dev), alarm);
+}
+
+static int
+rv3029c2_i2c_set_time(struct i2c_client *client, struct rtc_time const *tm)
+{
+	u8 regs[8];
+	int ret;
+
+	/*
+	 * The clock has an 8 bit wide bcd-coded register (they never learn)
+	 * for the year. tm_year is an offset from 1900 and we are interested
+	 * in the 2000-2099 range, so any value less than 100 is invalid.
+	*/
+	if (tm->tm_year < 100)
+		return -EINVAL;
+
+	regs[RV3029C2_W_SEC-RV3029C2_W_SEC] = bin2bcd(tm->tm_sec);
+	regs[RV3029C2_W_MINUTES-RV3029C2_W_SEC] = bin2bcd(tm->tm_min);
+	regs[RV3029C2_W_HOURS-RV3029C2_W_SEC] = bin2bcd(tm->tm_hour);
+	regs[RV3029C2_W_DATE-RV3029C2_W_SEC] = bin2bcd(tm->tm_mday);
+	regs[RV3029C2_W_MONTHS-RV3029C2_W_SEC] = bin2bcd(tm->tm_mon+1);
+	regs[RV3029C2_W_DAYS-RV3029C2_W_SEC] = bin2bcd((tm->tm_wday & 7)+1);
+	regs[RV3029C2_W_YEARS-RV3029C2_W_SEC] = bin2bcd(tm->tm_year - 100);
+
+	ret = rv3029c2_i2c_write_regs(client, RV3029C2_W_SEC, regs,
+					RV3029C2_WATCH_SECTION_LEN);
+	if (ret < 0)
+		return ret;
+
+	ret = rv3029c2_i2c_get_sr(client, regs);
+	if (ret < 0) {
+		dev_err(&client->dev, "%s: reading SR failed\n", __func__);
+		return ret;
+	}
+	/* clear PON bit */
+	ret = rv3029c2_i2c_set_sr(client, (regs[0] & ~RV3029C2_STATUS_PON));
+	if (ret < 0) {
+		dev_err(&client->dev, "%s: reading SR failed\n", __func__);
+		return ret;
+	}
+
+	return 0;
+}
+
+static int rv3029c2_rtc_set_time(struct device *dev, struct rtc_time *tm)
+{
+	return rv3029c2_i2c_set_time(to_i2c_client(dev), tm);
+}
+
+static const struct rtc_class_ops rv3029c2_rtc_ops = {
+	.read_time	= rv3029c2_rtc_read_time,
+	.set_time	= rv3029c2_rtc_set_time,
+	.read_alarm	= rv3029c2_rtc_read_alarm,
+	.set_alarm	= rv3029c2_rtc_set_alarm,
+};
+
+static struct i2c_device_id rv3029c2_id[] = {
+	{ "rv3029c2", 0 },
+	{ }
+};
+MODULE_DEVICE_TABLE(i2c, rv3029c2_id);
+
+static int __devinit
+rv3029c2_probe(struct i2c_client *client, const struct i2c_device_id *id)
+{
+	struct rtc_device *rtc;
+	int rc = 0;
+	u8 buf[1];
+
+	if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_EMUL))
+		return -ENODEV;
+
+	rtc = rtc_device_register(client->name,
+				&client->dev, &rv3029c2_rtc_ops,
+				THIS_MODULE);
+
+	if (IS_ERR(rtc))
+		return PTR_ERR(rtc);
+
+	i2c_set_clientdata(client, rtc);
+
+	rc = rv3029c2_i2c_get_sr(client, buf);
+	if (rc < 0) {
+		dev_err(&client->dev, "reading status failed\n");
+		goto exit_unregister;
+	}
+
+	return 0;
+
+exit_unregister:
+	rtc_device_unregister(rtc);
+
+	return rc;
+}
+
+static int __devexit rv3029c2_remove(struct i2c_client *client)
+{
+	struct rtc_device *rtc = i2c_get_clientdata(client);
+
+	rtc_device_unregister(rtc);
+
+	return 0;
+}
+
+static struct i2c_driver rv3029c2_driver = {
+	.driver = {
+		.name = "rtc-rv3029c2",
+	},
+	.probe = rv3029c2_probe,
+	.remove = __devexit_p(rv3029c2_remove),
+	.id_table = rv3029c2_id,
+};
+
+static int __init rv3029c2_init(void)
+{
+	return i2c_add_driver(&rv3029c2_driver);
+}
+
+static void __exit rv3029c2_exit(void)
+{
+	i2c_del_driver(&rv3029c2_driver);
+}
+
+module_init(rv3029c2_init);
+module_exit(rv3029c2_exit);
+
+MODULE_AUTHOR("Gregory Hermant <gregory.hermant@calao-systems.com>");
+MODULE_DESCRIPTION("Micro Crystal RV3029C2 RTC driver");
+MODULE_LICENSE("GPL");
diff -druN linux-2.6.39-libre/drivers/rtc/rtc-spear.c linux-3.0-rc7-libre/drivers/rtc/rtc-spear.c
--- linux-2.6.39-libre/drivers/rtc/rtc-spear.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/rtc/rtc-spear.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,534 @@
+/*
+ * drivers/rtc/rtc-spear.c
+ *
+ * Copyright (C) 2010 ST Microelectronics
+ * Rajeev Kumar<rajeev-dlh.kumar@st.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/bcd.h>
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/rtc.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+
+/* RTC registers */
+#define TIME_REG		0x00
+#define DATE_REG		0x04
+#define ALARM_TIME_REG		0x08
+#define ALARM_DATE_REG		0x0C
+#define CTRL_REG		0x10
+#define STATUS_REG		0x14
+
+/* TIME_REG & ALARM_TIME_REG */
+#define SECONDS_UNITS		(0xf<<0)	/* seconds units position */
+#define SECONDS_TENS		(0x7<<4)	/* seconds tens position */
+#define MINUTES_UNITS		(0xf<<8)	/* minutes units position */
+#define MINUTES_TENS		(0x7<<12)	/* minutes tens position */
+#define HOURS_UNITS		(0xf<<16)	/* hours units position */
+#define HOURS_TENS		(0x3<<20)	/* hours tens position */
+
+/* DATE_REG & ALARM_DATE_REG */
+#define DAYS_UNITS		(0xf<<0)	/* days units position */
+#define DAYS_TENS		(0x3<<4)	/* days tens position */
+#define MONTHS_UNITS		(0xf<<8)	/* months units position */
+#define MONTHS_TENS		(0x1<<12)	/* months tens position */
+#define YEARS_UNITS		(0xf<<16)	/* years units position */
+#define YEARS_TENS		(0xf<<20)	/* years tens position */
+#define YEARS_HUNDREDS		(0xf<<24)	/* years hundereds position */
+#define YEARS_MILLENIUMS	(0xf<<28)	/* years millenium position */
+
+/* MASK SHIFT TIME_REG & ALARM_TIME_REG*/
+#define SECOND_SHIFT		0x00		/* seconds units */
+#define MINUTE_SHIFT		0x08		/* minutes units position */
+#define HOUR_SHIFT		0x10		/* hours units position */
+#define MDAY_SHIFT		0x00		/* Month day shift */
+#define MONTH_SHIFT		0x08		/* Month shift */
+#define YEAR_SHIFT		0x10		/* Year shift */
+
+#define SECOND_MASK		0x7F
+#define MIN_MASK		0x7F
+#define HOUR_MASK		0x3F
+#define DAY_MASK		0x3F
+#define MONTH_MASK		0x7F
+#define YEAR_MASK		0xFFFF
+
+/* date reg equal to time reg, for debug only */
+#define TIME_BYP		(1<<9)
+#define INT_ENABLE		(1<<31)		/* interrupt enable */
+
+/* STATUS_REG */
+#define CLK_UNCONNECTED		(1<<0)
+#define PEND_WR_TIME		(1<<2)
+#define PEND_WR_DATE		(1<<3)
+#define LOST_WR_TIME		(1<<4)
+#define LOST_WR_DATE		(1<<5)
+#define RTC_INT_MASK		(1<<31)
+#define STATUS_BUSY		(PEND_WR_TIME | PEND_WR_DATE)
+#define STATUS_FAIL		(LOST_WR_TIME | LOST_WR_DATE)
+
+struct spear_rtc_config {
+	struct clk *clk;
+	spinlock_t lock;
+	void __iomem *ioaddr;
+};
+
+static inline void spear_rtc_clear_interrupt(struct spear_rtc_config *config)
+{
+	unsigned int val;
+	unsigned long flags;
+
+	spin_lock_irqsave(&config->lock, flags);
+	val = readl(config->ioaddr + STATUS_REG);
+	val |= RTC_INT_MASK;
+	writel(val, config->ioaddr + STATUS_REG);
+	spin_unlock_irqrestore(&config->lock, flags);
+}
+
+static inline void spear_rtc_enable_interrupt(struct spear_rtc_config *config)
+{
+	unsigned int val;
+
+	val = readl(config->ioaddr + CTRL_REG);
+	if (!(val & INT_ENABLE)) {
+		spear_rtc_clear_interrupt(config);
+		val |= INT_ENABLE;
+		writel(val, config->ioaddr + CTRL_REG);
+	}
+}
+
+static inline void spear_rtc_disable_interrupt(struct spear_rtc_config *config)
+{
+	unsigned int val;
+
+	val = readl(config->ioaddr + CTRL_REG);
+	if (val & INT_ENABLE) {
+		val &= ~INT_ENABLE;
+		writel(val, config->ioaddr + CTRL_REG);
+	}
+}
+
+static inline int is_write_complete(struct spear_rtc_config *config)
+{
+	int ret = 0;
+	unsigned long flags;
+
+	spin_lock_irqsave(&config->lock, flags);
+	if ((readl(config->ioaddr + STATUS_REG)) & STATUS_FAIL)
+		ret = -EIO;
+	spin_unlock_irqrestore(&config->lock, flags);
+
+	return ret;
+}
+
+static void rtc_wait_not_busy(struct spear_rtc_config *config)
+{
+	int status, count = 0;
+	unsigned long flags;
+
+	/* Assuming BUSY may stay active for 80 msec) */
+	for (count = 0; count < 80; count++) {
+		spin_lock_irqsave(&config->lock, flags);
+		status = readl(config->ioaddr + STATUS_REG);
+		spin_unlock_irqrestore(&config->lock, flags);
+		if ((status & STATUS_BUSY) == 0)
+			break;
+		/* check status busy, after each msec */
+		msleep(1);
+	}
+}
+
+static irqreturn_t spear_rtc_irq(int irq, void *dev_id)
+{
+	struct rtc_device *rtc = (struct rtc_device *)dev_id;
+	struct spear_rtc_config *config = dev_get_drvdata(&rtc->dev);
+	unsigned long flags, events = 0;
+	unsigned int irq_data;
+
+	spin_lock_irqsave(&config->lock, flags);
+	irq_data = readl(config->ioaddr + STATUS_REG);
+	spin_unlock_irqrestore(&config->lock, flags);
+
+	if ((irq_data & RTC_INT_MASK)) {
+		spear_rtc_clear_interrupt(config);
+		events = RTC_IRQF | RTC_AF;
+		rtc_update_irq(rtc, 1, events);
+		return IRQ_HANDLED;
+	} else
+		return IRQ_NONE;
+
+}
+
+static int tm2bcd(struct rtc_time *tm)
+{
+	if (rtc_valid_tm(tm) != 0)
+		return -EINVAL;
+	tm->tm_sec = bin2bcd(tm->tm_sec);
+	tm->tm_min = bin2bcd(tm->tm_min);
+	tm->tm_hour = bin2bcd(tm->tm_hour);
+	tm->tm_mday = bin2bcd(tm->tm_mday);
+	tm->tm_mon = bin2bcd(tm->tm_mon + 1);
+	tm->tm_year = bin2bcd(tm->tm_year);
+
+	return 0;
+}
+
+static void bcd2tm(struct rtc_time *tm)
+{
+	tm->tm_sec = bcd2bin(tm->tm_sec);
+	tm->tm_min = bcd2bin(tm->tm_min);
+	tm->tm_hour = bcd2bin(tm->tm_hour);
+	tm->tm_mday = bcd2bin(tm->tm_mday);
+	tm->tm_mon = bcd2bin(tm->tm_mon) - 1;
+	/* epoch == 1900 */
+	tm->tm_year = bcd2bin(tm->tm_year);
+}
+
+/*
+ * spear_rtc_read_time - set the time
+ * @dev: rtc device in use
+ * @tm: holds date and time
+ *
+ * This function read time and date. On success it will return 0
+ * otherwise -ve error is returned.
+ */
+static int spear_rtc_read_time(struct device *dev, struct rtc_time *tm)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct rtc_device *rtc = platform_get_drvdata(pdev);
+	struct spear_rtc_config *config = dev_get_drvdata(&rtc->dev);
+	unsigned int time, date;
+
+	/* we don't report wday/yday/isdst ... */
+	rtc_wait_not_busy(config);
+
+	time = readl(config->ioaddr + TIME_REG);
+	date = readl(config->ioaddr + DATE_REG);
+	tm->tm_sec = (time >> SECOND_SHIFT) & SECOND_MASK;
+	tm->tm_min = (time >> MINUTE_SHIFT) & MIN_MASK;
+	tm->tm_hour = (time >> HOUR_SHIFT) & HOUR_MASK;
+	tm->tm_mday = (date >> MDAY_SHIFT) & DAY_MASK;
+	tm->tm_mon = (date >> MONTH_SHIFT) & MONTH_MASK;
+	tm->tm_year = (date >> YEAR_SHIFT) & YEAR_MASK;
+
+	bcd2tm(tm);
+	return 0;
+}
+
+/*
+ * spear_rtc_set_time - set the time
+ * @dev: rtc device in use
+ * @tm: holds date and time
+ *
+ * This function set time and date. On success it will return 0
+ * otherwise -ve error is returned.
+ */
+static int spear_rtc_set_time(struct device *dev, struct rtc_time *tm)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct rtc_device *rtc = platform_get_drvdata(pdev);
+	struct spear_rtc_config *config = dev_get_drvdata(&rtc->dev);
+	unsigned int time, date, err = 0;
+
+	if (tm2bcd(tm) < 0)
+		return -EINVAL;
+
+	rtc_wait_not_busy(config);
+	time = (tm->tm_sec << SECOND_SHIFT) | (tm->tm_min << MINUTE_SHIFT) |
+		(tm->tm_hour << HOUR_SHIFT);
+	date = (tm->tm_mday << MDAY_SHIFT) | (tm->tm_mon << MONTH_SHIFT) |
+		(tm->tm_year << YEAR_SHIFT);
+	writel(time, config->ioaddr + TIME_REG);
+	writel(date, config->ioaddr + DATE_REG);
+	err = is_write_complete(config);
+	if (err < 0)
+		return err;
+
+	return 0;
+}
+
+/*
+ * spear_rtc_read_alarm - read the alarm time
+ * @dev: rtc device in use
+ * @alm: holds alarm date and time
+ *
+ * This function read alarm time and date. On success it will return 0
+ * otherwise -ve error is returned.
+ */
+static int spear_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alm)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct rtc_device *rtc = platform_get_drvdata(pdev);
+	struct spear_rtc_config *config = dev_get_drvdata(&rtc->dev);
+	unsigned int time, date;
+
+	rtc_wait_not_busy(config);
+
+	time = readl(config->ioaddr + ALARM_TIME_REG);
+	date = readl(config->ioaddr + ALARM_DATE_REG);
+	alm->time.tm_sec = (time >> SECOND_SHIFT) & SECOND_MASK;
+	alm->time.tm_min = (time >> MINUTE_SHIFT) & MIN_MASK;
+	alm->time.tm_hour = (time >> HOUR_SHIFT) & HOUR_MASK;
+	alm->time.tm_mday = (date >> MDAY_SHIFT) & DAY_MASK;
+	alm->time.tm_mon = (date >> MONTH_SHIFT) & MONTH_MASK;
+	alm->time.tm_year = (date >> YEAR_SHIFT) & YEAR_MASK;
+
+	bcd2tm(&alm->time);
+	alm->enabled = readl(config->ioaddr + CTRL_REG) & INT_ENABLE;
+
+	return 0;
+}
+
+/*
+ * spear_rtc_set_alarm - set the alarm time
+ * @dev: rtc device in use
+ * @alm: holds alarm date and time
+ *
+ * This function set alarm time and date. On success it will return 0
+ * otherwise -ve error is returned.
+ */
+static int spear_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct rtc_device *rtc = platform_get_drvdata(pdev);
+	struct spear_rtc_config *config = dev_get_drvdata(&rtc->dev);
+	unsigned int time, date, err = 0;
+
+	if (tm2bcd(&alm->time) < 0)
+		return -EINVAL;
+
+	rtc_wait_not_busy(config);
+
+	time = (alm->time.tm_sec << SECOND_SHIFT) | (alm->time.tm_min <<
+			MINUTE_SHIFT) |	(alm->time.tm_hour << HOUR_SHIFT);
+	date = (alm->time.tm_mday << MDAY_SHIFT) | (alm->time.tm_mon <<
+			MONTH_SHIFT) | (alm->time.tm_year << YEAR_SHIFT);
+
+	writel(time, config->ioaddr + ALARM_TIME_REG);
+	writel(date, config->ioaddr + ALARM_DATE_REG);
+	err = is_write_complete(config);
+	if (err < 0)
+		return err;
+
+	if (alm->enabled)
+		spear_rtc_enable_interrupt(config);
+	else
+		spear_rtc_disable_interrupt(config);
+
+	return 0;
+}
+static struct rtc_class_ops spear_rtc_ops = {
+	.read_time = spear_rtc_read_time,
+	.set_time = spear_rtc_set_time,
+	.read_alarm = spear_rtc_read_alarm,
+	.set_alarm = spear_rtc_set_alarm,
+};
+
+static int __devinit spear_rtc_probe(struct platform_device *pdev)
+{
+	struct resource *res;
+	struct rtc_device *rtc;
+	struct spear_rtc_config *config;
+	unsigned int status = 0;
+	int irq;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res) {
+		dev_err(&pdev->dev, "no resource defined\n");
+		return -EBUSY;
+	}
+	if (!request_mem_region(res->start, resource_size(res), pdev->name)) {
+		dev_err(&pdev->dev, "rtc region already claimed\n");
+		return -EBUSY;
+	}
+
+	config = kzalloc(sizeof(*config), GFP_KERNEL);
+	if (!config) {
+		dev_err(&pdev->dev, "out of memory\n");
+		status = -ENOMEM;
+		goto err_release_region;
+	}
+
+	config->clk = clk_get(&pdev->dev, NULL);
+	if (IS_ERR(config->clk)) {
+		status = PTR_ERR(config->clk);
+		goto err_kfree;
+	}
+
+	status = clk_enable(config->clk);
+	if (status < 0)
+		goto err_clk_put;
+
+	config->ioaddr = ioremap(res->start, resource_size(res));
+	if (!config->ioaddr) {
+		dev_err(&pdev->dev, "ioremap fail\n");
+		status = -ENOMEM;
+		goto err_disable_clock;
+	}
+
+	spin_lock_init(&config->lock);
+
+	rtc = rtc_device_register(pdev->name, &pdev->dev, &spear_rtc_ops,
+			THIS_MODULE);
+	if (IS_ERR(rtc)) {
+		dev_err(&pdev->dev, "can't register RTC device, err %ld\n",
+				PTR_ERR(rtc));
+		status = PTR_ERR(rtc);
+		goto err_iounmap;
+	}
+
+	platform_set_drvdata(pdev, rtc);
+	dev_set_drvdata(&rtc->dev, config);
+
+	/* alarm irqs */
+	irq = platform_get_irq(pdev, 0);
+	if (irq < 0) {
+		dev_err(&pdev->dev, "no update irq?\n");
+		status = irq;
+		goto err_clear_platdata;
+	}
+
+	status = request_irq(irq, spear_rtc_irq, 0, pdev->name, rtc);
+	if (status) {
+		dev_err(&pdev->dev, "Alarm interrupt IRQ%d already \
+				claimed\n", irq);
+		goto err_clear_platdata;
+	}
+
+	if (!device_can_wakeup(&pdev->dev))
+		device_init_wakeup(&pdev->dev, 1);
+
+	return 0;
+
+err_clear_platdata:
+	platform_set_drvdata(pdev, NULL);
+	dev_set_drvdata(&rtc->dev, NULL);
+	rtc_device_unregister(rtc);
+err_iounmap:
+	iounmap(config->ioaddr);
+err_disable_clock:
+	clk_disable(config->clk);
+err_clk_put:
+	clk_put(config->clk);
+err_kfree:
+	kfree(config);
+err_release_region:
+	release_mem_region(res->start, resource_size(res));
+
+	return status;
+}
+
+static int __devexit spear_rtc_remove(struct platform_device *pdev)
+{
+	struct rtc_device *rtc = platform_get_drvdata(pdev);
+	struct spear_rtc_config *config = dev_get_drvdata(&rtc->dev);
+	int irq;
+	struct resource *res;
+
+	/* leave rtc running, but disable irqs */
+	spear_rtc_disable_interrupt(config);
+	device_init_wakeup(&pdev->dev, 0);
+	irq = platform_get_irq(pdev, 0);
+	if (irq)
+		free_irq(irq, pdev);
+	clk_disable(config->clk);
+	clk_put(config->clk);
+	iounmap(config->ioaddr);
+	kfree(config);
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (res)
+		release_mem_region(res->start, resource_size(res));
+	platform_set_drvdata(pdev, NULL);
+	dev_set_drvdata(&rtc->dev, NULL);
+	rtc_device_unregister(rtc);
+
+	return 0;
+}
+
+#ifdef CONFIG_PM
+
+static int spear_rtc_suspend(struct platform_device *pdev, pm_message_t state)
+{
+	struct rtc_device *rtc = platform_get_drvdata(pdev);
+	struct spear_rtc_config *config = dev_get_drvdata(&rtc->dev);
+	int irq;
+
+	irq = platform_get_irq(pdev, 0);
+	if (device_may_wakeup(&pdev->dev))
+		enable_irq_wake(irq);
+	else {
+		spear_rtc_disable_interrupt(config);
+		clk_disable(config->clk);
+	}
+
+	return 0;
+}
+
+static int spear_rtc_resume(struct platform_device *pdev)
+{
+	struct rtc_device *rtc = platform_get_drvdata(pdev);
+	struct spear_rtc_config *config = dev_get_drvdata(&rtc->dev);
+	int irq;
+
+	irq = platform_get_irq(pdev, 0);
+
+	if (device_may_wakeup(&pdev->dev))
+		disable_irq_wake(irq);
+	else {
+		clk_enable(config->clk);
+		spear_rtc_enable_interrupt(config);
+	}
+
+	return 0;
+}
+
+#else
+#define spear_rtc_suspend	NULL
+#define spear_rtc_resume	NULL
+#endif
+
+static void spear_rtc_shutdown(struct platform_device *pdev)
+{
+	struct rtc_device *rtc = platform_get_drvdata(pdev);
+	struct spear_rtc_config *config = dev_get_drvdata(&rtc->dev);
+
+	spear_rtc_disable_interrupt(config);
+	clk_disable(config->clk);
+}
+
+static struct platform_driver spear_rtc_driver = {
+	.probe = spear_rtc_probe,
+	.remove = __devexit_p(spear_rtc_remove),
+	.suspend = spear_rtc_suspend,
+	.resume = spear_rtc_resume,
+	.shutdown = spear_rtc_shutdown,
+	.driver = {
+		.name = "rtc-spear",
+	},
+};
+
+static int __init rtc_init(void)
+{
+	return platform_driver_register(&spear_rtc_driver);
+}
+module_init(rtc_init);
+
+static void __exit rtc_exit(void)
+{
+	platform_driver_unregister(&spear_rtc_driver);
+}
+module_exit(rtc_exit);
+
+MODULE_ALIAS("platform:rtc-spear");
+MODULE_AUTHOR("Rajeev Kumar <rajeev-dlh.kumar@st.com>");
+MODULE_DESCRIPTION("ST SPEAr Realtime Clock Driver (RTC)");
+MODULE_LICENSE("GPL");
diff -druN linux-2.6.39-libre/drivers/rtc/rtc-tile.c linux-3.0-rc7-libre/drivers/rtc/rtc-tile.c
--- linux-2.6.39-libre/drivers/rtc/rtc-tile.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/rtc/rtc-tile.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,162 @@
+/*
+ * Copyright 2011 Tilera 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, version 2.
+ *
+ *   This program is distributed in the hope that it will be useful, but
+ *   WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
+ *   NON INFRINGEMENT.  See the GNU General Public License for
+ *   more details.
+ *
+ * Tilera-specific RTC driver.
+ */
+
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/rtc.h>
+#include <linux/platform_device.h>
+
+/* Platform device pointer. */
+static struct platform_device *tile_rtc_platform_device;
+
+/*
+ * RTC read routine.  Gets time info from RTC chip via hypervisor syscall.
+ */
+static int read_rtc_time(struct device *dev, struct rtc_time *tm)
+{
+	HV_RTCTime hvtm = hv_get_rtc();
+
+	tm->tm_sec = hvtm.tm_sec;
+	tm->tm_min = hvtm.tm_min;
+	tm->tm_hour = hvtm.tm_hour;
+	tm->tm_mday = hvtm.tm_mday;
+	tm->tm_mon = hvtm.tm_mon;
+	tm->tm_year = hvtm.tm_year;
+	tm->tm_wday = 0;
+	tm->tm_yday = 0;
+	tm->tm_isdst = 0;
+
+	if (rtc_valid_tm(tm) < 0)
+		dev_warn(dev, "Read invalid date/time from RTC\n");
+
+	return 0;
+}
+
+/*
+ * RTC write routine.  Sends time info to hypervisor via syscall, to be
+ * written to RTC chip.
+ */
+static int set_rtc_time(struct device *dev, struct rtc_time *tm)
+{
+	HV_RTCTime hvtm;
+
+	hvtm.tm_sec = tm->tm_sec;
+	hvtm.tm_min = tm->tm_min;
+	hvtm.tm_hour = tm->tm_hour;
+	hvtm.tm_mday = tm->tm_mday;
+	hvtm.tm_mon = tm->tm_mon;
+	hvtm.tm_year = tm->tm_year;
+
+	hv_set_rtc(hvtm);
+
+	return 0;
+}
+
+/*
+ * RTC read/write ops.
+ */
+static const struct rtc_class_ops tile_rtc_ops = {
+	.read_time	= read_rtc_time,
+	.set_time	= set_rtc_time,
+};
+
+/*
+ * Device probe routine.
+ */
+static int __devinit tile_rtc_probe(struct platform_device *dev)
+{
+	struct rtc_device *rtc;
+
+	rtc = rtc_device_register("tile",
+				  &dev->dev, &tile_rtc_ops, THIS_MODULE);
+
+	if (IS_ERR(rtc))
+		return PTR_ERR(rtc);
+
+	platform_set_drvdata(dev, rtc);
+
+	return 0;
+}
+
+/*
+ * Device cleanup routine.
+ */
+static int __devexit tile_rtc_remove(struct platform_device *dev)
+{
+	struct rtc_device *rtc = platform_get_drvdata(dev);
+
+	if (rtc)
+		rtc_device_unregister(rtc);
+
+	platform_set_drvdata(dev, NULL);
+
+	return 0;
+}
+
+static struct platform_driver tile_rtc_platform_driver = {
+	.driver		= {
+		.name	= "rtc-tile",
+		.owner	= THIS_MODULE,
+	},
+	.probe		= tile_rtc_probe,
+	.remove		= __devexit_p(tile_rtc_remove),
+};
+
+/*
+ * Driver init routine.
+ */
+static int __init tile_rtc_driver_init(void)
+{
+	int err;
+
+	err = platform_driver_register(&tile_rtc_platform_driver);
+	if (err)
+		return err;
+
+	tile_rtc_platform_device = platform_device_alloc("rtc-tile", 0);
+	if (tile_rtc_platform_device == NULL) {
+		err = -ENOMEM;
+		goto exit_driver_unregister;
+	}
+
+	err = platform_device_add(tile_rtc_platform_device);
+	if (err)
+		goto exit_device_put;
+
+	return 0;
+
+exit_device_put:
+	platform_device_put(tile_rtc_platform_device);
+
+exit_driver_unregister:
+	platform_driver_unregister(&tile_rtc_platform_driver);
+	return err;
+}
+
+/*
+ * Driver cleanup routine.
+ */
+static void __exit tile_rtc_driver_exit(void)
+{
+	platform_driver_unregister(&tile_rtc_platform_driver);
+}
+
+module_init(tile_rtc_driver_init);
+module_exit(tile_rtc_driver_exit);
+
+MODULE_DESCRIPTION("Tilera-specific Real Time Clock Driver");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:rtc-tile");
diff -druN linux-2.6.39-libre/drivers/rtc/rtc-vt8500.c linux-3.0-rc7-libre/drivers/rtc/rtc-vt8500.c
--- linux-2.6.39-libre/drivers/rtc/rtc-vt8500.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/rtc/rtc-vt8500.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,327 @@
+/*
+ * drivers/rtc/rtc-vt8500.c
+ *
+ *  Copyright (C) 2010 Alexey Charkov <alchark@gmail.com>
+ *
+ * Based on rtc-pxa.c
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/module.h>
+#include <linux/rtc.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/bcd.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+
+/*
+ * Register definitions
+ */
+#define VT8500_RTC_TS		0x00	/* Time set */
+#define VT8500_RTC_DS		0x04	/* Date set */
+#define VT8500_RTC_AS		0x08	/* Alarm set */
+#define VT8500_RTC_CR		0x0c	/* Control */
+#define VT8500_RTC_TR		0x10	/* Time read */
+#define VT8500_RTC_DR		0x14	/* Date read */
+#define VT8500_RTC_WS		0x18	/* Write status */
+#define VT8500_RTC_CL		0x20	/* Calibration */
+#define VT8500_RTC_IS		0x24	/* Interrupt status */
+#define VT8500_RTC_ST		0x28	/* Status */
+
+#define INVALID_TIME_BIT	(1 << 31)
+
+#define DATE_CENTURY_S		19
+#define DATE_YEAR_S		11
+#define DATE_YEAR_MASK		(0xff << DATE_YEAR_S)
+#define DATE_MONTH_S		6
+#define DATE_MONTH_MASK		(0x1f << DATE_MONTH_S)
+#define DATE_DAY_MASK		0x3f
+
+#define TIME_DOW_S		20
+#define TIME_DOW_MASK		(0x07 << TIME_DOW_S)
+#define TIME_HOUR_S		14
+#define TIME_HOUR_MASK		(0x3f << TIME_HOUR_S)
+#define TIME_MIN_S		7
+#define TIME_MIN_MASK		(0x7f << TIME_MIN_S)
+#define TIME_SEC_MASK		0x7f
+
+#define ALARM_DAY_S		20
+#define ALARM_DAY_MASK		(0x3f << ALARM_DAY_S)
+
+#define ALARM_DAY_BIT		(1 << 29)
+#define ALARM_HOUR_BIT		(1 << 28)
+#define ALARM_MIN_BIT		(1 << 27)
+#define ALARM_SEC_BIT		(1 << 26)
+
+#define ALARM_ENABLE_MASK	(ALARM_DAY_BIT \
+				| ALARM_HOUR_BIT \
+				| ALARM_MIN_BIT \
+				| ALARM_SEC_BIT)
+
+#define VT8500_RTC_CR_ENABLE	(1 << 0)	/* Enable RTC */
+#define VT8500_RTC_CR_24H	(1 << 1)	/* 24h time format */
+#define VT8500_RTC_CR_SM_ENABLE	(1 << 2)	/* Enable periodic irqs */
+#define VT8500_RTC_CR_SM_SEC	(1 << 3)	/* 0: 1Hz/60, 1: 1Hz */
+#define VT8500_RTC_CR_CALIB	(1 << 4)	/* Enable calibration */
+
+struct vt8500_rtc {
+	void __iomem		*regbase;
+	struct resource		*res;
+	int			irq_alarm;
+	struct rtc_device	*rtc;
+	spinlock_t		lock;		/* Protects this structure */
+};
+
+static irqreturn_t vt8500_rtc_irq(int irq, void *dev_id)
+{
+	struct vt8500_rtc *vt8500_rtc = dev_id;
+	u32 isr;
+	unsigned long events = 0;
+
+	spin_lock(&vt8500_rtc->lock);
+
+	/* clear interrupt sources */
+	isr = readl(vt8500_rtc->regbase + VT8500_RTC_IS);
+	writel(isr, vt8500_rtc->regbase + VT8500_RTC_IS);
+
+	spin_unlock(&vt8500_rtc->lock);
+
+	if (isr & 1)
+		events |= RTC_AF | RTC_IRQF;
+
+	rtc_update_irq(vt8500_rtc->rtc, 1, events);
+
+	return IRQ_HANDLED;
+}
+
+static int vt8500_rtc_read_time(struct device *dev, struct rtc_time *tm)
+{
+	struct vt8500_rtc *vt8500_rtc = dev_get_drvdata(dev);
+	u32 date, time;
+
+	date = readl(vt8500_rtc->regbase + VT8500_RTC_DR);
+	time = readl(vt8500_rtc->regbase + VT8500_RTC_TR);
+
+	tm->tm_sec = bcd2bin(time & TIME_SEC_MASK);
+	tm->tm_min = bcd2bin((time & TIME_MIN_MASK) >> TIME_MIN_S);
+	tm->tm_hour = bcd2bin((time & TIME_HOUR_MASK) >> TIME_HOUR_S);
+	tm->tm_mday = bcd2bin(date & DATE_DAY_MASK);
+	tm->tm_mon = bcd2bin((date & DATE_MONTH_MASK) >> DATE_MONTH_S);
+	tm->tm_year = bcd2bin((date & DATE_YEAR_MASK) >> DATE_YEAR_S)
+			+ ((date >> DATE_CENTURY_S) & 1 ? 200 : 100);
+	tm->tm_wday = (time & TIME_DOW_MASK) >> TIME_DOW_S;
+
+	return 0;
+}
+
+static int vt8500_rtc_set_time(struct device *dev, struct rtc_time *tm)
+{
+	struct vt8500_rtc *vt8500_rtc = dev_get_drvdata(dev);
+
+	if (tm->tm_year < 100) {
+		dev_warn(dev, "Only years 2000-2199 are supported by the "
+			      "hardware!\n");
+		return -EINVAL;
+	}
+
+	writel((bin2bcd(tm->tm_year - 100) << DATE_YEAR_S)
+		| (bin2bcd(tm->tm_mon) << DATE_MONTH_S)
+		| (bin2bcd(tm->tm_mday)),
+		vt8500_rtc->regbase + VT8500_RTC_DS);
+	writel((bin2bcd(tm->tm_wday) << TIME_DOW_S)
+		| (bin2bcd(tm->tm_hour) << TIME_HOUR_S)
+		| (bin2bcd(tm->tm_min) << TIME_MIN_S)
+		| (bin2bcd(tm->tm_sec)),
+		vt8500_rtc->regbase + VT8500_RTC_TS);
+
+	return 0;
+}
+
+static int vt8500_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
+{
+	struct vt8500_rtc *vt8500_rtc = dev_get_drvdata(dev);
+	u32 isr, alarm;
+
+	alarm = readl(vt8500_rtc->regbase + VT8500_RTC_AS);
+	isr = readl(vt8500_rtc->regbase + VT8500_RTC_IS);
+
+	alrm->time.tm_mday = bcd2bin((alarm & ALARM_DAY_MASK) >> ALARM_DAY_S);
+	alrm->time.tm_hour = bcd2bin((alarm & TIME_HOUR_MASK) >> TIME_HOUR_S);
+	alrm->time.tm_min = bcd2bin((alarm & TIME_MIN_MASK) >> TIME_MIN_S);
+	alrm->time.tm_sec = bcd2bin((alarm & TIME_SEC_MASK));
+
+	alrm->enabled = (alarm & ALARM_ENABLE_MASK) ? 1 : 0;
+
+	alrm->pending = (isr & 1) ? 1 : 0;
+	return rtc_valid_tm(&alrm->time);
+}
+
+static int vt8500_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
+{
+	struct vt8500_rtc *vt8500_rtc = dev_get_drvdata(dev);
+
+	writel((alrm->enabled ? ALARM_ENABLE_MASK : 0)
+		| (bin2bcd(alrm->time.tm_mday) << ALARM_DAY_S)
+		| (bin2bcd(alrm->time.tm_hour) << TIME_HOUR_S)
+		| (bin2bcd(alrm->time.tm_min) << TIME_MIN_S)
+		| (bin2bcd(alrm->time.tm_sec)),
+		vt8500_rtc->regbase + VT8500_RTC_AS);
+
+	return 0;
+}
+
+static int vt8500_alarm_irq_enable(struct device *dev, unsigned int enabled)
+{
+	struct vt8500_rtc *vt8500_rtc = dev_get_drvdata(dev);
+	unsigned long tmp = readl(vt8500_rtc->regbase + VT8500_RTC_AS);
+
+	if (enabled)
+		tmp |= ALARM_ENABLE_MASK;
+	else
+		tmp &= ~ALARM_ENABLE_MASK;
+
+	writel(tmp, vt8500_rtc->regbase + VT8500_RTC_AS);
+	return 0;
+}
+
+static const struct rtc_class_ops vt8500_rtc_ops = {
+	.read_time = vt8500_rtc_read_time,
+	.set_time = vt8500_rtc_set_time,
+	.read_alarm = vt8500_rtc_read_alarm,
+	.set_alarm = vt8500_rtc_set_alarm,
+	.alarm_irq_enable = vt8500_alarm_irq_enable,
+};
+
+static int __devinit vt8500_rtc_probe(struct platform_device *pdev)
+{
+	struct vt8500_rtc *vt8500_rtc;
+	int ret;
+
+	vt8500_rtc = kzalloc(sizeof(struct vt8500_rtc), GFP_KERNEL);
+	if (!vt8500_rtc)
+		return -ENOMEM;
+
+	spin_lock_init(&vt8500_rtc->lock);
+	platform_set_drvdata(pdev, vt8500_rtc);
+
+	vt8500_rtc->res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!vt8500_rtc->res) {
+		dev_err(&pdev->dev, "No I/O memory resource defined\n");
+		ret = -ENXIO;
+		goto err_free;
+	}
+
+	vt8500_rtc->irq_alarm = platform_get_irq(pdev, 0);
+	if (vt8500_rtc->irq_alarm < 0) {
+		dev_err(&pdev->dev, "No alarm IRQ resource defined\n");
+		ret = -ENXIO;
+		goto err_free;
+	}
+
+	vt8500_rtc->res = request_mem_region(vt8500_rtc->res->start,
+					     resource_size(vt8500_rtc->res),
+					     "vt8500-rtc");
+	if (vt8500_rtc->res == NULL) {
+		dev_err(&pdev->dev, "failed to request I/O memory\n");
+		ret = -EBUSY;
+		goto err_free;
+	}
+
+	vt8500_rtc->regbase = ioremap(vt8500_rtc->res->start,
+				      resource_size(vt8500_rtc->res));
+	if (!vt8500_rtc->regbase) {
+		dev_err(&pdev->dev, "Unable to map RTC I/O memory\n");
+		ret = -EBUSY;
+		goto err_release;
+	}
+
+	/* Enable RTC and set it to 24-hour mode */
+	writel(VT8500_RTC_CR_ENABLE | VT8500_RTC_CR_24H,
+	       vt8500_rtc->regbase + VT8500_RTC_CR);
+
+	vt8500_rtc->rtc = rtc_device_register("vt8500-rtc", &pdev->dev,
+					      &vt8500_rtc_ops, THIS_MODULE);
+	if (IS_ERR(vt8500_rtc->rtc)) {
+		ret = PTR_ERR(vt8500_rtc->rtc);
+		dev_err(&pdev->dev,
+			"Failed to register RTC device -> %d\n", ret);
+		goto err_unmap;
+	}
+
+	ret = request_irq(vt8500_rtc->irq_alarm, vt8500_rtc_irq, 0,
+			  "rtc alarm", vt8500_rtc);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "can't get irq %i, err %d\n",
+			vt8500_rtc->irq_alarm, ret);
+		goto err_unreg;
+	}
+
+	return 0;
+
+err_unreg:
+	rtc_device_unregister(vt8500_rtc->rtc);
+err_unmap:
+	iounmap(vt8500_rtc->regbase);
+err_release:
+	release_mem_region(vt8500_rtc->res->start,
+			   resource_size(vt8500_rtc->res));
+err_free:
+	kfree(vt8500_rtc);
+	return ret;
+}
+
+static int __devexit vt8500_rtc_remove(struct platform_device *pdev)
+{
+	struct vt8500_rtc *vt8500_rtc = platform_get_drvdata(pdev);
+
+	free_irq(vt8500_rtc->irq_alarm, vt8500_rtc);
+
+	rtc_device_unregister(vt8500_rtc->rtc);
+
+	/* Disable alarm matching */
+	writel(0, vt8500_rtc->regbase + VT8500_RTC_IS);
+	iounmap(vt8500_rtc->regbase);
+	release_mem_region(vt8500_rtc->res->start,
+			   resource_size(vt8500_rtc->res));
+
+	kfree(vt8500_rtc);
+	platform_set_drvdata(pdev, NULL);
+
+	return 0;
+}
+
+static struct platform_driver vt8500_rtc_driver = {
+	.probe		= vt8500_rtc_probe,
+	.remove		= __devexit_p(vt8500_rtc_remove),
+	.driver		= {
+		.name	= "vt8500-rtc",
+		.owner	= THIS_MODULE,
+	},
+};
+
+static int __init vt8500_rtc_init(void)
+{
+	return platform_driver_register(&vt8500_rtc_driver);
+}
+module_init(vt8500_rtc_init);
+
+static void __exit vt8500_rtc_exit(void)
+{
+	platform_driver_unregister(&vt8500_rtc_driver);
+}
+module_exit(vt8500_rtc_exit);
+
+MODULE_AUTHOR("Alexey Charkov <alchark@gmail.com>");
+MODULE_DESCRIPTION("VIA VT8500 SoC Realtime Clock Driver (RTC)");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:vt8500-rtc");
diff -druN linux-2.6.39-libre/drivers/s390/block/dasd_alias.c linux-3.0-rc7-libre/drivers/s390/block/dasd_alias.c
--- linux-2.6.39-libre/drivers/s390/block/dasd_alias.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/s390/block/dasd_alias.c	2011-07-11 19:51:52.000000000 -0400
@@ -253,13 +253,11 @@
  */
 void dasd_alias_lcu_setup_complete(struct dasd_device *device)
 {
-	struct dasd_eckd_private *private;
 	unsigned long flags;
 	struct alias_server *server;
 	struct alias_lcu *lcu;
 	struct dasd_uid uid;
 
-	private = (struct dasd_eckd_private *) device->private;
 	device->discipline->get_uid(device, &uid);
 	lcu = NULL;
 	spin_lock_irqsave(&aliastree.lock, flags);
@@ -279,13 +277,11 @@
 
 void dasd_alias_wait_for_lcu_setup(struct dasd_device *device)
 {
-	struct dasd_eckd_private *private;
 	unsigned long flags;
 	struct alias_server *server;
 	struct alias_lcu *lcu;
 	struct dasd_uid uid;
 
-	private = (struct dasd_eckd_private *) device->private;
 	device->discipline->get_uid(device, &uid);
 	lcu = NULL;
 	spin_lock_irqsave(&aliastree.lock, flags);
diff -druN linux-2.6.39-libre/drivers/s390/block/dasd_diag.c linux-3.0-rc7-libre/drivers/s390/block/dasd_diag.c
--- linux-2.6.39-libre/drivers/s390/block/dasd_diag.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/s390/block/dasd_diag.c	2011-07-11 19:51:52.000000000 -0400
@@ -24,7 +24,7 @@
 #include <asm/debug.h>
 #include <asm/ebcdic.h>
 #include <asm/io.h>
-#include <asm/s390_ext.h>
+#include <asm/irq.h>
 #include <asm/vtoc.h>
 #include <asm/diag.h>
 
@@ -642,7 +642,7 @@
 	}
 	ASCEBC(dasd_diag_discipline.ebcname, 4);
 
-	ctl_set_bit(0, 9);
+	service_subclass_irq_register();
 	register_external_interrupt(0x2603, dasd_ext_handler);
 	dasd_diag_discipline_pointer = &dasd_diag_discipline;
 	return 0;
@@ -652,7 +652,7 @@
 dasd_diag_cleanup(void)
 {
 	unregister_external_interrupt(0x2603, dasd_ext_handler);
-	ctl_clear_bit(0, 9);
+	service_subclass_irq_unregister();
 	dasd_diag_discipline_pointer = NULL;
 }
 
diff -druN linux-2.6.39-libre/drivers/s390/block/dasd_eckd.c linux-3.0-rc7-libre/drivers/s390/block/dasd_eckd.c
--- linux-2.6.39-libre/drivers/s390/block/dasd_eckd.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/s390/block/dasd_eckd.c	2011-07-11 19:51:52.000000000 -0400
@@ -1611,10 +1611,8 @@
 
 static int dasd_eckd_start_analysis(struct dasd_block *block)
 {
-	struct dasd_eckd_private *private;
 	struct dasd_ccw_req *init_cqr;
 
-	private = (struct dasd_eckd_private *) block->base->private;
 	init_cqr = dasd_eckd_analysis_ccw(block->base);
 	if (IS_ERR(init_cqr))
 		return PTR_ERR(init_cqr);
@@ -2264,7 +2262,6 @@
 					       unsigned int blk_per_trk,
 					       unsigned int blksize)
 {
-	struct dasd_eckd_private *private;
 	unsigned long *idaws;
 	struct dasd_ccw_req *cqr;
 	struct ccw1 *ccw;
@@ -2283,7 +2280,6 @@
 	unsigned int recoffs;
 
 	basedev = block->base;
-	private = (struct dasd_eckd_private *) basedev->private;
 	if (rq_data_dir(req) == READ)
 		cmd = DASD_ECKD_CCW_READ_TRACK_DATA;
 	else if (rq_data_dir(req) == WRITE)
@@ -2556,8 +2552,7 @@
 
 	dcw = itcw_add_dcw(itcw, pfx_cmd, 0,
 		     &pfxdata, sizeof(pfxdata), total_data_size);
-
-	return rc;
+	return IS_ERR(dcw) ? PTR_ERR(dcw) : 0;
 }
 
 static struct dasd_ccw_req *dasd_eckd_build_cp_tpm_track(
@@ -2573,7 +2568,6 @@
 					       unsigned int blk_per_trk,
 					       unsigned int blksize)
 {
-	struct dasd_eckd_private *private;
 	struct dasd_ccw_req *cqr;
 	struct req_iterator iter;
 	struct bio_vec *bv;
@@ -2594,7 +2588,6 @@
 	unsigned int count, count_to_trk_end;
 
 	basedev = block->base;
-	private = (struct dasd_eckd_private *) basedev->private;
 	if (rq_data_dir(req) == READ) {
 		cmd = DASD_ECKD_CCW_READ_TRACK_DATA;
 		itcw_op = ITCW_OP_READ;
@@ -2801,7 +2794,6 @@
 					       struct dasd_block *block,
 					       struct request *req)
 {
-	struct dasd_eckd_private *private;
 	unsigned long *idaws;
 	struct dasd_device *basedev;
 	struct dasd_ccw_req *cqr;
@@ -2836,7 +2828,6 @@
 	trkcount = last_trk - first_trk + 1;
 	first_offs = 0;
 	basedev = block->base;
-	private = (struct dasd_eckd_private *) basedev->private;
 
 	if (rq_data_dir(req) == READ)
 		cmd = DASD_ECKD_CCW_READ_TRACK;
diff -druN linux-2.6.39-libre/drivers/s390/char/Kconfig linux-3.0-rc7-libre/drivers/s390/char/Kconfig
--- linux-2.6.39-libre/drivers/s390/char/Kconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/s390/char/Kconfig	2011-07-11 19:51:52.000000000 -0400
@@ -119,18 +119,6 @@
 comment "S/390 tape interface support"
 	depends on S390_TAPE
 
-config S390_TAPE_BLOCK
-	def_bool y
-	prompt "Support for tape block devices"
-	depends on S390_TAPE && BLOCK
-	help
-	  Select this option if you want to access your channel-attached tape
-	  devices using the block device interface.  This interface is similar
-	  to CD-ROM devices on other platforms.  The tapes can only be
-	  accessed read-only when using this interface.  Have a look at
-	  <file:Documentation/s390/TAPE> for further information about creating
-	  volumes for and using this interface.  It is safe to say "Y" here.
-
 comment "S/390 tape hardware support"
 	depends on S390_TAPE
 
diff -druN linux-2.6.39-libre/drivers/s390/char/Makefile linux-3.0-rc7-libre/drivers/s390/char/Makefile
--- linux-2.6.39-libre/drivers/s390/char/Makefile	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/s390/char/Makefile	2011-07-11 19:51:52.000000000 -0400
@@ -3,7 +3,7 @@
 #
 
 obj-y += ctrlchar.o keyboard.o defkeymap.o sclp.o sclp_rw.o sclp_quiesce.o \
-	 sclp_cmd.o sclp_config.o sclp_cpi_sys.o
+	 sclp_cmd.o sclp_config.o sclp_cpi_sys.o sclp_ocf.o
 
 obj-$(CONFIG_TN3270) += raw3270.o
 obj-$(CONFIG_TN3270_CONSOLE) += con3270.o
@@ -22,7 +22,6 @@
 obj-$(CONFIG_VMLOGRDR) += vmlogrdr.o
 obj-$(CONFIG_VMCP) += vmcp.o
 
-tape-$(CONFIG_S390_TAPE_BLOCK) += tape_block.o
 tape-$(CONFIG_PROC_FS) += tape_proc.o
 tape-objs := tape_core.o tape_std.o tape_char.o $(tape-y)
 obj-$(CONFIG_S390_TAPE) += tape.o tape_class.o
diff -druN linux-2.6.39-libre/drivers/s390/char/monwriter.c linux-3.0-rc7-libre/drivers/s390/char/monwriter.c
--- linux-2.6.39-libre/drivers/s390/char/monwriter.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/s390/char/monwriter.c	2011-07-11 19:51:52.000000000 -0400
@@ -97,7 +97,7 @@
 {
 	struct monwrite_hdr *monhdr = &monpriv->hdr;
 	struct mon_buf *monbuf;
-	int rc;
+	int rc = 0;
 
 	if (monhdr->datalen > MONWRITE_MAX_DATALEN ||
 	    monhdr->mon_function > MONWRITE_START_CONFIG ||
@@ -135,7 +135,7 @@
 			mon_buf_count++;
 	}
 	monpriv->current_buf = monbuf;
-	return 0;
+	return rc;
 }
 
 static int monwrite_new_data(struct mon_private *monpriv)
diff -druN linux-2.6.39-libre/drivers/s390/char/raw3270.c linux-3.0-rc7-libre/drivers/s390/char/raw3270.c
--- linux-2.6.39-libre/drivers/s390/char/raw3270.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/s390/char/raw3270.c	2011-07-11 19:51:52.000000000 -0400
@@ -598,7 +598,6 @@
 	static const unsigned char wbuf[] =
 		{ 0x00, 0x07, 0x01, 0xff, 0x03, 0x00, 0x81 };
 	struct raw3270_ua *uap;
-	unsigned short count;
 	int rc;
 
 	/*
@@ -653,7 +652,6 @@
 	if (rc)
 		return rc;
 	/* Got a Query Reply */
-	count = sizeof(rp->init_data) - rp->init_request.rescnt;
 	uap = (struct raw3270_ua *) (rp->init_data + 1);
 	/* Paranoia check. */
 	if (rp->init_data[0] != 0x88 || uap->uab.qcode != 0x81)
diff -druN linux-2.6.39-libre/drivers/s390/char/sclp.c linux-3.0-rc7-libre/drivers/s390/char/sclp.c
--- linux-2.6.39-libre/drivers/s390/char/sclp.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/s390/char/sclp.c	2011-07-11 19:51:52.000000000 -0400
@@ -19,7 +19,6 @@
 #include <linux/suspend.h>
 #include <linux/completion.h>
 #include <linux/platform_device.h>
-#include <asm/s390_ext.h>
 #include <asm/types.h>
 #include <asm/irq.h>
 
@@ -885,12 +884,12 @@
 		spin_unlock_irqrestore(&sclp_lock, flags);
 		/* Enable service-signal interruption - needs to happen
 		 * with IRQs enabled. */
-		ctl_set_bit(0, 9);
+		service_subclass_irq_register();
 		/* Wait for signal from interrupt or timeout */
 		sclp_sync_wait();
 		/* Disable service-signal interruption - needs to happen
 		 * with IRQs enabled. */
-		ctl_clear_bit(0,9);
+		service_subclass_irq_unregister();
 		spin_lock_irqsave(&sclp_lock, flags);
 		del_timer(&sclp_request_timer);
 		if (sclp_init_req.status == SCLP_REQ_DONE &&
@@ -1070,7 +1069,7 @@
 	spin_unlock_irqrestore(&sclp_lock, flags);
 	/* Enable service-signal external interruption - needs to happen with
 	 * IRQs enabled. */
-	ctl_set_bit(0, 9);
+	service_subclass_irq_register();
 	sclp_init_mask(1);
 	return 0;
 
diff -druN linux-2.6.39-libre/drivers/s390/char/sclp_config.c linux-3.0-rc7-libre/drivers/s390/char/sclp_config.c
--- linux-2.6.39-libre/drivers/s390/char/sclp_config.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/s390/char/sclp_config.c	2011-07-11 19:51:52.000000000 -0400
@@ -71,21 +71,9 @@
 
 static int __init sclp_conf_init(void)
 {
-	int rc;
-
 	INIT_WORK(&sclp_cpu_capability_work, sclp_cpu_capability_notify);
 	INIT_WORK(&sclp_cpu_change_work, sclp_cpu_change_notify);
-
-	rc = sclp_register(&sclp_conf_register);
-	if (rc)
-		return rc;
-
-	if (!(sclp_conf_register.sclp_send_mask & EVTYP_CONFMGMDATA_MASK)) {
-		pr_warning("no configuration management.\n");
-		sclp_unregister(&sclp_conf_register);
-		rc = -ENOSYS;
-	}
-	return rc;
+	return sclp_register(&sclp_conf_register);
 }
 
 __initcall(sclp_conf_init);
diff -druN linux-2.6.39-libre/drivers/s390/char/sclp.h linux-3.0-rc7-libre/drivers/s390/char/sclp.h
--- linux-2.6.39-libre/drivers/s390/char/sclp.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/s390/char/sclp.h	2011-07-11 19:51:52.000000000 -0400
@@ -28,6 +28,7 @@
 #define EVTYP_CONFMGMDATA	0x04
 #define EVTYP_SDIAS		0x1C
 #define EVTYP_ASYNC		0x0A
+#define EVTYP_OCF		0x1E
 
 #define EVTYP_OPCMD_MASK	0x80000000
 #define EVTYP_MSG_MASK		0x40000000
@@ -40,6 +41,7 @@
 #define EVTYP_CONFMGMDATA_MASK	0x10000000
 #define EVTYP_SDIAS_MASK	0x00000010
 #define EVTYP_ASYNC_MASK	0x00400000
+#define EVTYP_OCF_MASK		0x00000004
 
 #define GNRLMSGFLGS_DOM		0x8000
 #define GNRLMSGFLGS_SNDALRM	0x4000
@@ -186,4 +188,26 @@
 	(MACHINE_IS_VM) ? ASCEBC(str, nr) : ASCEBC_500(str, nr);
 }
 
+static inline struct gds_vector *
+sclp_find_gds_vector(void *start, void *end, u16 id)
+{
+	struct gds_vector *v;
+
+	for (v = start; (void *) v < end; v = (void *) v + v->length)
+		if (v->gds_id == id)
+			return v;
+	return NULL;
+}
+
+static inline struct gds_subvector *
+sclp_find_gds_subvector(void *start, void *end, u8 key)
+{
+	struct gds_subvector *sv;
+
+	for (sv = start; (void *) sv < end; sv = (void *) sv + sv->length)
+		if (sv->key == key)
+			return sv;
+	return NULL;
+}
+
 #endif	 /* __SCLP_H__ */
diff -druN linux-2.6.39-libre/drivers/s390/char/sclp_ocf.c linux-3.0-rc7-libre/drivers/s390/char/sclp_ocf.c
--- linux-2.6.39-libre/drivers/s390/char/sclp_ocf.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/s390/char/sclp_ocf.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,145 @@
+/*
+ *  drivers/s390/char/sclp_ocf.c
+ *    SCLP OCF communication parameters sysfs interface
+ *
+ *    Copyright IBM Corp. 2011
+ *    Author(s): Martin Schwidefsky <schwidefsky@de.ibm.com>
+ */
+
+#define KMSG_COMPONENT "sclp_ocf"
+#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/stat.h>
+#include <linux/device.h>
+#include <linux/string.h>
+#include <linux/ctype.h>
+#include <linux/kmod.h>
+#include <linux/timer.h>
+#include <linux/err.h>
+#include <asm/ebcdic.h>
+#include <asm/sclp.h>
+
+#include "sclp.h"
+
+#define OCF_LENGTH_HMC_NETWORK 8UL
+#define OCF_LENGTH_CPC_NAME 8UL
+
+static char hmc_network[OCF_LENGTH_HMC_NETWORK + 1];
+static char cpc_name[OCF_LENGTH_CPC_NAME + 1];
+
+static DEFINE_SPINLOCK(sclp_ocf_lock);
+static struct work_struct sclp_ocf_change_work;
+
+static struct kset *ocf_kset;
+
+static void sclp_ocf_change_notify(struct work_struct *work)
+{
+	kobject_uevent(&ocf_kset->kobj, KOBJ_CHANGE);
+}
+
+/* Handler for OCF event. Look for the CPC image name. */
+static void sclp_ocf_handler(struct evbuf_header *evbuf)
+{
+	struct gds_vector *v;
+	struct gds_subvector *sv, *netid, *cpc;
+	size_t size;
+
+	/* Find the 0x9f00 block. */
+	v = sclp_find_gds_vector(evbuf + 1, (void *) evbuf + evbuf->length,
+				 0x9f00);
+	if (!v)
+		return;
+	/* Find the 0x9f22 block inside the 0x9f00 block. */
+	v = sclp_find_gds_vector(v + 1, (void *) v + v->length, 0x9f22);
+	if (!v)
+		return;
+	/* Find the 0x81 block inside the 0x9f22 block. */
+	sv = sclp_find_gds_subvector(v + 1, (void *) v + v->length, 0x81);
+	if (!sv)
+		return;
+	/* Find the 0x01 block inside the 0x81 block. */
+	netid = sclp_find_gds_subvector(sv + 1, (void *) sv + sv->length, 1);
+	/* Find the 0x02 block inside the 0x81 block. */
+	cpc = sclp_find_gds_subvector(sv + 1, (void *) sv + sv->length, 2);
+	/* Copy network name and cpc name. */
+	spin_lock(&sclp_ocf_lock);
+	if (netid) {
+		size = min(OCF_LENGTH_HMC_NETWORK, (size_t) netid->length);
+		memcpy(hmc_network, netid + 1, size);
+		EBCASC(hmc_network, size);
+		hmc_network[size] = 0;
+	}
+	if (cpc) {
+		size = min(OCF_LENGTH_CPC_NAME, (size_t) cpc->length);
+		memcpy(cpc_name, cpc + 1, size);
+		EBCASC(cpc_name, size);
+		cpc_name[size] = 0;
+	}
+	spin_unlock(&sclp_ocf_lock);
+	schedule_work(&sclp_ocf_change_work);
+}
+
+static struct sclp_register sclp_ocf_event = {
+	.receive_mask = EVTYP_OCF_MASK,
+	.receiver_fn = sclp_ocf_handler,
+};
+
+static ssize_t cpc_name_show(struct kobject *kobj,
+			     struct kobj_attribute *attr, char *page)
+{
+	int rc;
+
+	spin_lock_irq(&sclp_ocf_lock);
+	rc = snprintf(page, PAGE_SIZE, "%s\n", cpc_name);
+	spin_unlock_irq(&sclp_ocf_lock);
+	return rc;
+}
+
+static struct kobj_attribute cpc_name_attr =
+	__ATTR(cpc_name, 0444, cpc_name_show, NULL);
+
+static ssize_t hmc_network_show(struct kobject *kobj,
+				struct kobj_attribute *attr, char *page)
+{
+	int rc;
+
+	spin_lock_irq(&sclp_ocf_lock);
+	rc = snprintf(page, PAGE_SIZE, "%s\n", hmc_network);
+	spin_unlock_irq(&sclp_ocf_lock);
+	return rc;
+}
+
+static struct kobj_attribute hmc_network_attr =
+	__ATTR(hmc_network, 0444, hmc_network_show, NULL);
+
+static struct attribute *ocf_attrs[] = {
+	&cpc_name_attr.attr,
+	&hmc_network_attr.attr,
+	NULL,
+};
+
+static struct attribute_group ocf_attr_group = {
+	.attrs = ocf_attrs,
+};
+
+static int __init ocf_init(void)
+{
+	int rc;
+
+	INIT_WORK(&sclp_ocf_change_work, sclp_ocf_change_notify);
+	ocf_kset = kset_create_and_add("ocf", NULL, firmware_kobj);
+	if (!ocf_kset)
+		return -ENOMEM;
+
+	rc = sysfs_create_group(&ocf_kset->kobj, &ocf_attr_group);
+	if (rc) {
+		kset_unregister(ocf_kset);
+		return rc;
+	}
+
+	return sclp_register(&sclp_ocf_event);
+}
+
+device_initcall(ocf_init);
diff -druN linux-2.6.39-libre/drivers/s390/char/sclp_sdias.c linux-3.0-rc7-libre/drivers/s390/char/sclp_sdias.c
--- linux-2.6.39-libre/drivers/s390/char/sclp_sdias.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/s390/char/sclp_sdias.c	2011-07-11 19:51:52.000000000 -0400
@@ -69,9 +69,6 @@
 
 static void sdias_callback(struct sclp_req *request, void *data)
 {
-	struct sdias_sccb *cbsccb;
-
-	cbsccb = (struct sdias_sccb *) request->sccb;
 	sclp_req_done = 1;
 	wake_up(&sdias_wq); /* Inform caller, that request is complete */
 	TRACE("callback done\n");
diff -druN linux-2.6.39-libre/drivers/s390/char/sclp_tty.c linux-3.0-rc7-libre/drivers/s390/char/sclp_tty.c
--- linux-2.6.39-libre/drivers/s390/char/sclp_tty.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/s390/char/sclp_tty.c	2011-07-11 19:51:52.000000000 -0400
@@ -408,118 +408,72 @@
 	return op - buf;
 }
 
-static void
-sclp_get_input(unsigned char *start, unsigned char *end)
+static void sclp_get_input(struct gds_subvector *sv)
 {
+	unsigned char *str;
 	int count;
 
-	count = end - start;
+	str = (unsigned char *) (sv + 1);
+	count = sv->length - sizeof(*sv);
 	if (sclp_tty_tolower)
-		EBC_TOLOWER(start, count);
-	count = sclp_switch_cases(start, count);
+		EBC_TOLOWER(str, count);
+	count = sclp_switch_cases(str, count);
 	/* convert EBCDIC to ASCII (modify original input in SCCB) */
-	sclp_ebcasc_str(start, count);
+	sclp_ebcasc_str(str, count);
 
 	/* transfer input to high level driver */
-	sclp_tty_input(start, count);
-}
-
-static inline struct gds_vector *
-find_gds_vector(struct gds_vector *start, struct gds_vector *end, u16 id)
-{
-	struct gds_vector *vec;
-
-	for (vec = start; vec < end; vec = (void *) vec + vec->length)
-		if (vec->gds_id == id)
-			return vec;
-	return NULL;
+	sclp_tty_input(str, count);
 }
 
-static inline struct gds_subvector *
-find_gds_subvector(struct gds_subvector *start,
-		   struct gds_subvector *end, u8 key)
+static inline void sclp_eval_selfdeftextmsg(struct gds_subvector *sv)
 {
-	struct gds_subvector *subvec;
+	void *end;
 
-	for (subvec = start; subvec < end;
-	     subvec = (void *) subvec + subvec->length)
-		if (subvec->key == key)
-			return subvec;
-	return NULL;
+	end = (void *) sv + sv->length;
+	for (sv = sv + 1; (void *) sv < end; sv = (void *) sv + sv->length)
+		if (sv->key == 0x30)
+			sclp_get_input(sv);
 }
 
-static inline void
-sclp_eval_selfdeftextmsg(struct gds_subvector *start,
-			 struct gds_subvector *end)
+static inline void sclp_eval_textcmd(struct gds_vector *v)
 {
-	struct gds_subvector *subvec;
-
-	subvec = start;
-	while (subvec < end) {
-		subvec = find_gds_subvector(subvec, end, 0x30);
-		if (!subvec)
-			break;
-		sclp_get_input((unsigned char *)(subvec + 1),
-			       (unsigned char *) subvec + subvec->length);
-		subvec = (void *) subvec + subvec->length;
-	}
-}
+	struct gds_subvector *sv;
+	void *end;
 
-static inline void
-sclp_eval_textcmd(struct gds_subvector *start,
-		  struct gds_subvector *end)
-{
-	struct gds_subvector *subvec;
+	end = (void *) v + v->length;
+	for (sv = (struct gds_subvector *) (v + 1);
+	     (void *) sv < end; sv = (void *) sv + sv->length)
+		if (sv->key == GDS_KEY_SELFDEFTEXTMSG)
+			sclp_eval_selfdeftextmsg(sv);
 
-	subvec = start;
-	while (subvec < end) {
-		subvec = find_gds_subvector(subvec, end,
-					    GDS_KEY_SELFDEFTEXTMSG);
-		if (!subvec)
-			break;
-		sclp_eval_selfdeftextmsg((struct gds_subvector *)(subvec + 1),
-					 (void *)subvec + subvec->length);
-		subvec = (void *) subvec + subvec->length;
-	}
 }
 
-static inline void
-sclp_eval_cpmsu(struct gds_vector *start, struct gds_vector *end)
+static inline void sclp_eval_cpmsu(struct gds_vector *v)
 {
-	struct gds_vector *vec;
+	void *end;
 
-	vec = start;
-	while (vec < end) {
-		vec = find_gds_vector(vec, end, GDS_ID_TEXTCMD);
-		if (!vec)
-			break;
-		sclp_eval_textcmd((struct gds_subvector *)(vec + 1),
-				  (void *) vec + vec->length);
-		vec = (void *) vec + vec->length;
-	}
+	end = (void *) v + v->length;
+	for (v = v + 1; (void *) v < end; v = (void *) v + v->length)
+		if (v->gds_id == GDS_ID_TEXTCMD)
+			sclp_eval_textcmd(v);
 }
 
 
-static inline void
-sclp_eval_mdsmu(struct gds_vector *start, void *end)
+static inline void sclp_eval_mdsmu(struct gds_vector *v)
 {
-	struct gds_vector *vec;
-
-	vec = find_gds_vector(start, end, GDS_ID_CPMSU);
-	if (vec)
-		sclp_eval_cpmsu(vec + 1, (void *) vec + vec->length);
+	v = sclp_find_gds_vector(v + 1, (void *) v + v->length, GDS_ID_CPMSU);
+	if (v)
+		sclp_eval_cpmsu(v);
 }
 
-static void
-sclp_tty_receiver(struct evbuf_header *evbuf)
+static void sclp_tty_receiver(struct evbuf_header *evbuf)
 {
-	struct gds_vector *start, *end, *vec;
+	struct gds_vector *v;
 
-	start = (struct gds_vector *)(evbuf + 1);
-	end = (void *) evbuf + evbuf->length;
-	vec = find_gds_vector(start, end, GDS_ID_MDSMU);
-	if (vec)
-		sclp_eval_mdsmu(vec + 1, (void *) vec + vec->length);
+	v = sclp_find_gds_vector(evbuf + 1, (void *) evbuf + evbuf->length,
+				 GDS_ID_MDSMU);
+	if (v)
+		sclp_eval_mdsmu(v);
 }
 
 static void
diff -druN linux-2.6.39-libre/drivers/s390/char/tape_3590.c linux-3.0-rc7-libre/drivers/s390/char/tape_3590.c
--- linux-2.6.39-libre/drivers/s390/char/tape_3590.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/s390/char/tape_3590.c	2011-07-11 19:51:52.000000000 -0400
@@ -796,10 +796,8 @@
 static int
 tape_3590_done(struct tape_device *device, struct tape_request *request)
 {
-	struct tape_3590_disc_data *disc_data;
 
 	DBF_EVENT(6, "%s done\n", tape_op_verbose[request->op]);
-	disc_data = device->discdata;
 
 	switch (request->op) {
 	case TO_BSB:
@@ -1394,17 +1392,12 @@
 static int tape_3590_crypt_error(struct tape_device *device,
 				 struct tape_request *request, struct irb *irb)
 {
-	u8 cu_rc, ekm_rc1;
+	u8 cu_rc;
 	u16 ekm_rc2;
-	u32 drv_rc;
-	const char *bus_id;
 	char *sense;
 
 	sense = ((struct tape_3590_sense *) irb->ecw)->fmt.data;
-	bus_id = dev_name(&device->cdev->dev);
 	cu_rc = sense[0];
-	drv_rc = *((u32*) &sense[5]) & 0xffffff;
-	ekm_rc1 = sense[9];
 	ekm_rc2 = *((u16*) &sense[10]);
 	if ((cu_rc == 0) && (ekm_rc2 == 0xee31))
 		/* key not defined on EKM */
@@ -1429,7 +1422,6 @@
 		     struct irb *irb)
 {
 	struct tape_3590_sense *sense;
-	int rc;
 
 #ifdef CONFIG_S390_TAPE_BLOCK
 	if (request->op == TO_BLOCK) {
@@ -1454,7 +1446,6 @@
 	 *   - "break":     basic error recovery is done
 	 *   - "goto out:": just print error message if available
 	 */
-	rc = -EIO;
 	switch (sense->rc_rqc) {
 
 	case 0x1110:
diff -druN linux-2.6.39-libre/drivers/s390/char/tape_block.c linux-3.0-rc7-libre/drivers/s390/char/tape_block.c
--- linux-2.6.39-libre/drivers/s390/char/tape_block.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/s390/char/tape_block.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,444 +0,0 @@
-/*
- *  drivers/s390/char/tape_block.c
- *    block device frontend for tape device driver
- *
- *  S390 and zSeries version
- *    Copyright (C) 2001,2003 IBM Deutschland Entwicklung GmbH, IBM Corporation
- *    Author(s): Carsten Otte <cotte@de.ibm.com>
- *		 Tuan Ngo-Anh <ngoanh@de.ibm.com>
- *		 Martin Schwidefsky <schwidefsky@de.ibm.com>
- *		 Stefan Bader <shbader@de.ibm.com>
- */
-
-#define KMSG_COMPONENT "tape"
-#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
-
-#include <linux/fs.h>
-#include <linux/module.h>
-#include <linux/blkdev.h>
-#include <linux/mutex.h>
-#include <linux/interrupt.h>
-#include <linux/buffer_head.h>
-#include <linux/kernel.h>
-
-#include <asm/debug.h>
-
-#define TAPE_DBF_AREA	tape_core_dbf
-
-#include "tape.h"
-
-#define TAPEBLOCK_MAX_SEC	100
-#define TAPEBLOCK_MIN_REQUEUE	3
-
-/*
- * 2003/11/25  Stefan Bader <shbader@de.ibm.com>
- *
- * In 2.5/2.6 the block device request function is very likely to be called
- * with disabled interrupts (e.g. generic_unplug_device). So the driver can't
- * just call any function that tries to allocate CCW requests from that con-
- * text since it might sleep. There are two choices to work around this:
- *	a) do not allocate with kmalloc but use its own memory pool
- *      b) take requests from the queue outside that context, knowing that
- *         allocation might sleep
- */
-
-/*
- * file operation structure for tape block frontend
- */
-static DEFINE_MUTEX(tape_block_mutex);
-static int tapeblock_open(struct block_device *, fmode_t);
-static int tapeblock_release(struct gendisk *, fmode_t);
-static unsigned int tapeblock_check_events(struct gendisk *, unsigned int);
-static int tapeblock_revalidate_disk(struct gendisk *);
-
-static const struct block_device_operations tapeblock_fops = {
-	.owner		 = THIS_MODULE,
-	.open		 = tapeblock_open,
-	.release	 = tapeblock_release,
-	.check_events	 = tapeblock_check_events,
-	.revalidate_disk = tapeblock_revalidate_disk,
-};
-
-static int tapeblock_major = 0;
-
-static void
-tapeblock_trigger_requeue(struct tape_device *device)
-{
-	/* Protect against rescheduling. */
-	if (atomic_cmpxchg(&device->blk_data.requeue_scheduled, 0, 1) != 0)
-		return;
-	schedule_work(&device->blk_data.requeue_task);
-}
-
-/*
- * Post finished request.
- */
-static void
-__tapeblock_end_request(struct tape_request *ccw_req, void *data)
-{
-	struct tape_device *device;
-	struct request *req;
-
-	DBF_LH(6, "__tapeblock_end_request()\n");
-
-	device = ccw_req->device;
-	req = (struct request *) data;
-	blk_end_request_all(req, (ccw_req->rc == 0) ? 0 : -EIO);
-	if (ccw_req->rc == 0)
-		/* Update position. */
-		device->blk_data.block_position =
-		  (blk_rq_pos(req) + blk_rq_sectors(req)) >> TAPEBLOCK_HSEC_S2B;
-	else
-		/* We lost the position information due to an error. */
-		device->blk_data.block_position = -1;
-	device->discipline->free_bread(ccw_req);
-	if (!list_empty(&device->req_queue) ||
-	    blk_peek_request(device->blk_data.request_queue))
-		tapeblock_trigger_requeue(device);
-}
-
-/*
- * Feed the tape device CCW queue with requests supplied in a list.
- */
-static int
-tapeblock_start_request(struct tape_device *device, struct request *req)
-{
-	struct tape_request *	ccw_req;
-	int			rc;
-
-	DBF_LH(6, "tapeblock_start_request(%p, %p)\n", device, req);
-
-	ccw_req = device->discipline->bread(device, req);
-	if (IS_ERR(ccw_req)) {
-		DBF_EVENT(1, "TBLOCK: bread failed\n");
-		blk_end_request_all(req, -EIO);
-		return PTR_ERR(ccw_req);
-	}
-	ccw_req->callback = __tapeblock_end_request;
-	ccw_req->callback_data = (void *) req;
-	ccw_req->retries = TAPEBLOCK_RETRIES;
-
-	rc = tape_do_io_async(device, ccw_req);
-	if (rc) {
-		/*
-		 * Start/enqueueing failed. No retries in
-		 * this case.
-		 */
-		blk_end_request_all(req, -EIO);
-		device->discipline->free_bread(ccw_req);
-	}
-
-	return rc;
-}
-
-/*
- * Move requests from the block device request queue to the tape device ccw
- * queue.
- */
-static void
-tapeblock_requeue(struct work_struct *work) {
-	struct tape_blk_data *	blkdat;
-	struct tape_device *	device;
-	struct request_queue *	queue;
-	int			nr_queued;
-	struct request *	req;
-	struct list_head *	l;
-	int			rc;
-
-	blkdat = container_of(work, struct tape_blk_data, requeue_task);
-	device = blkdat->device;
-	if (!device)
-		return;
-
-	spin_lock_irq(get_ccwdev_lock(device->cdev));
-	queue  = device->blk_data.request_queue;
-
-	/* Count number of requests on ccw queue. */
-	nr_queued = 0;
-	list_for_each(l, &device->req_queue)
-		nr_queued++;
-	spin_unlock(get_ccwdev_lock(device->cdev));
-
-	spin_lock_irq(&device->blk_data.request_queue_lock);
-	while (
-		blk_peek_request(queue) &&
-		nr_queued < TAPEBLOCK_MIN_REQUEUE
-	) {
-		req = blk_fetch_request(queue);
-		if (rq_data_dir(req) == WRITE) {
-			DBF_EVENT(1, "TBLOCK: Rejecting write request\n");
-			spin_unlock_irq(&device->blk_data.request_queue_lock);
-			blk_end_request_all(req, -EIO);
-			spin_lock_irq(&device->blk_data.request_queue_lock);
-			continue;
-		}
-		nr_queued++;
-		spin_unlock_irq(&device->blk_data.request_queue_lock);
-		rc = tapeblock_start_request(device, req);
-		spin_lock_irq(&device->blk_data.request_queue_lock);
-	}
-	spin_unlock_irq(&device->blk_data.request_queue_lock);
-	atomic_set(&device->blk_data.requeue_scheduled, 0);
-}
-
-/*
- * Tape request queue function. Called from ll_rw_blk.c
- */
-static void
-tapeblock_request_fn(struct request_queue *queue)
-{
-	struct tape_device *device;
-
-	device = (struct tape_device *) queue->queuedata;
-	DBF_LH(6, "tapeblock_request_fn(device=%p)\n", device);
-	BUG_ON(device == NULL);
-	tapeblock_trigger_requeue(device);
-}
-
-/*
- * This function is called for every new tapedevice
- */
-int
-tapeblock_setup_device(struct tape_device * device)
-{
-	struct tape_blk_data *	blkdat;
-	struct gendisk *	disk;
-	int			rc;
-
-	blkdat = &device->blk_data;
-	blkdat->device = device;
-	spin_lock_init(&blkdat->request_queue_lock);
-	atomic_set(&blkdat->requeue_scheduled, 0);
-
-	blkdat->request_queue = blk_init_queue(
-		tapeblock_request_fn,
-		&blkdat->request_queue_lock
-	);
-	if (!blkdat->request_queue)
-		return -ENOMEM;
-
-	rc = elevator_change(blkdat->request_queue, "noop");
-	if (rc)
-		goto cleanup_queue;
-
-	blk_queue_logical_block_size(blkdat->request_queue, TAPEBLOCK_HSEC_SIZE);
-	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);
-
-	disk = alloc_disk(1);
-	if (!disk) {
-		rc = -ENOMEM;
-		goto cleanup_queue;
-	}
-
-	disk->major = tapeblock_major;
-	disk->first_minor = device->first_minor;
-	disk->fops = &tapeblock_fops;
-	disk->private_data = tape_get_device(device);
-	disk->queue = blkdat->request_queue;
-	set_capacity(disk, 0);
-	sprintf(disk->disk_name, "btibm%d",
-		device->first_minor / TAPE_MINORS_PER_DEV);
-
-	blkdat->disk = disk;
-	blkdat->medium_changed = 1;
-	blkdat->request_queue->queuedata = tape_get_device(device);
-
-	add_disk(disk);
-
-	tape_get_device(device);
-	INIT_WORK(&blkdat->requeue_task, tapeblock_requeue);
-
-	return 0;
-
-cleanup_queue:
-	blk_cleanup_queue(blkdat->request_queue);
-	blkdat->request_queue = NULL;
-
-	return rc;
-}
-
-void
-tapeblock_cleanup_device(struct tape_device *device)
-{
-	flush_work_sync(&device->blk_data.requeue_task);
-	tape_put_device(device);
-
-	if (!device->blk_data.disk) {
-		goto cleanup_queue;
-	}
-
-	del_gendisk(device->blk_data.disk);
-	device->blk_data.disk->private_data = NULL;
-	tape_put_device(device);
-	put_disk(device->blk_data.disk);
-
-	device->blk_data.disk = NULL;
-cleanup_queue:
-	device->blk_data.request_queue->queuedata = NULL;
-	tape_put_device(device);
-
-	blk_cleanup_queue(device->blk_data.request_queue);
-	device->blk_data.request_queue = NULL;
-}
-
-/*
- * Detect number of blocks of the tape.
- * FIXME: can we extent this to detect the blocks size as well ?
- */
-static int
-tapeblock_revalidate_disk(struct gendisk *disk)
-{
-	struct tape_device *	device;
-	unsigned int		nr_of_blks;
-	int			rc;
-
-	device = (struct tape_device *) disk->private_data;
-	BUG_ON(!device);
-
-	if (!device->blk_data.medium_changed)
-		return 0;
-
-	rc = tape_mtop(device, MTFSFM, 1);
-	if (rc)
-		return rc;
-
-	rc = tape_mtop(device, MTTELL, 1);
-	if (rc < 0)
-		return rc;
-
-	pr_info("%s: Determining the size of the recorded area...\n",
-		dev_name(&device->cdev->dev));
-	DBF_LH(3, "Image file ends at %d\n", rc);
-	nr_of_blks = rc;
-
-	/* This will fail for the first file. Catch the error by checking the
-	 * position. */
-	tape_mtop(device, MTBSF, 1);
-
-	rc = tape_mtop(device, MTTELL, 1);
-	if (rc < 0)
-		return rc;
-
-	if (rc > nr_of_blks)
-		return -EINVAL;
-
-	DBF_LH(3, "Image file starts at %d\n", rc);
-	device->bof = rc;
-	nr_of_blks -= rc;
-
-	pr_info("%s: The size of the recorded area is %i blocks\n",
-		dev_name(&device->cdev->dev), nr_of_blks);
-	set_capacity(device->blk_data.disk,
-		nr_of_blks*(TAPEBLOCK_HSEC_SIZE/512));
-
-	device->blk_data.block_position = 0;
-	device->blk_data.medium_changed = 0;
-	return 0;
-}
-
-static unsigned int
-tapeblock_check_events(struct gendisk *disk, unsigned int clearing)
-{
-	struct tape_device *device;
-
-	device = (struct tape_device *) disk->private_data;
-	DBF_LH(6, "tapeblock_medium_changed(%p) = %d\n",
-		device, device->blk_data.medium_changed);
-
-	return device->blk_data.medium_changed ? DISK_EVENT_MEDIA_CHANGE : 0;
-}
-
-/*
- * Block frontend tape device open function.
- */
-static int
-tapeblock_open(struct block_device *bdev, fmode_t mode)
-{
-	struct gendisk *	disk = bdev->bd_disk;
-	struct tape_device *	device;
-	int			rc;
-
-	mutex_lock(&tape_block_mutex);
-	device = tape_get_device(disk->private_data);
-
-	if (device->required_tapemarks) {
-		DBF_EVENT(2, "TBLOCK: missing tapemarks\n");
-		pr_warning("%s: Opening the tape failed because of missing "
-			   "end-of-file marks\n", dev_name(&device->cdev->dev));
-		rc = -EPERM;
-		goto put_device;
-	}
-
-	rc = tape_open(device);
-	if (rc)
-		goto put_device;
-
-	rc = tapeblock_revalidate_disk(disk);
-	if (rc)
-		goto release;
-
-	/*
-	 * Note: The reference to <device> is hold until the release function
-	 *       is called.
-	 */
-	tape_state_set(device, TS_BLKUSE);
-	mutex_unlock(&tape_block_mutex);
-	return 0;
-
-release:
-	tape_release(device);
- put_device:
-	tape_put_device(device);
-	mutex_unlock(&tape_block_mutex);
-	return rc;
-}
-
-/*
- * Block frontend tape device release function.
- *
- * Note: One reference to the tape device was made by the open function. So
- *       we just get the pointer here and release the reference.
- */
-static int
-tapeblock_release(struct gendisk *disk, fmode_t mode)
-{
-	struct tape_device *device = disk->private_data;
- 
-	mutex_lock(&tape_block_mutex);
-	tape_state_set(device, TS_IN_USE);
-	tape_release(device);
-	tape_put_device(device);
-	mutex_unlock(&tape_block_mutex);
-
-	return 0;
-}
-
-/*
- * Initialize block device frontend.
- */
-int
-tapeblock_init(void)
-{
-	int rc;
-
-	/* Register the tape major number to the kernel */
-	rc = register_blkdev(tapeblock_major, "tBLK");
-	if (rc < 0)
-		return rc;
-
-	if (tapeblock_major == 0)
-		tapeblock_major = rc;
-	return 0;
-}
-
-/*
- * Deregister major for block device frontend
- */
-void
-tapeblock_exit(void)
-{
-	unregister_blkdev(tapeblock_major, "tBLK");
-}
diff -druN linux-2.6.39-libre/drivers/s390/char/tape_std.c linux-3.0-rc7-libre/drivers/s390/char/tape_std.c
--- linux-2.6.39-libre/drivers/s390/char/tape_std.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/s390/char/tape_std.c	2011-07-11 19:51:52.000000000 -0400
@@ -564,7 +564,6 @@
 tape_std_mtreten(struct tape_device *device, int mt_count)
 {
 	struct tape_request *request;
-	int rc;
 
 	request = tape_alloc_request(4, 0);
 	if (IS_ERR(request))
@@ -576,7 +575,7 @@
 	tape_ccw_cc(request->cpaddr + 2, NOP, 0, NULL);
 	tape_ccw_end(request->cpaddr + 3, CCW_CMD_TIC, 0, request->cpaddr);
 	/* execute it, MTRETEN rc gets ignored */
-	rc = tape_do_io_interruptible(device, request);
+	tape_do_io_interruptible(device, request);
 	tape_free_request(request);
 	return tape_mtop(device, MTREW, 1);
 }
diff -druN linux-2.6.39-libre/drivers/s390/cio/chsc.c linux-3.0-rc7-libre/drivers/s390/cio/chsc.c
--- linux-2.6.39-libre/drivers/s390/cio/chsc.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/s390/cio/chsc.c	2011-07-11 19:51:52.000000000 -0400
@@ -326,6 +326,36 @@
 	s390_process_res_acc(&link);
 }
 
+static void chsc_process_sei_chp_avail(struct chsc_sei_area *sei_area)
+{
+	struct channel_path *chp;
+	struct chp_id chpid;
+	u8 *data;
+	int num;
+
+	CIO_CRW_EVENT(4, "chsc: channel path availability information\n");
+	if (sei_area->rs != 0)
+		return;
+	data = sei_area->ccdf;
+	chp_id_init(&chpid);
+	for (num = 0; num <= __MAX_CHPID; num++) {
+		if (!chp_test_bit(data, num))
+			continue;
+		chpid.id = num;
+
+		CIO_CRW_EVENT(4, "Update information for channel path "
+			      "%x.%02x\n", chpid.cssid, chpid.id);
+		chp = chpid_to_chp(chpid);
+		if (!chp) {
+			chp_new(chpid);
+			continue;
+		}
+		mutex_lock(&chp->lock);
+		chsc_determine_base_channel_path_desc(chpid, &chp->desc);
+		mutex_unlock(&chp->lock);
+	}
+}
+
 struct chp_config_data {
 	u8 map[32];
 	u8 op;
@@ -376,9 +406,12 @@
 	case 1: /* link incident*/
 		chsc_process_sei_link_incident(sei_area);
 		break;
-	case 2: /* i/o resource accessibiliy */
+	case 2: /* i/o resource accessibility */
 		chsc_process_sei_res_acc(sei_area);
 		break;
+	case 7: /* channel-path-availability information */
+		chsc_process_sei_chp_avail(sei_area);
+		break;
 	case 8: /* channel-path-configuration notification */
 		chsc_process_sei_chp_config(sei_area);
 		break;
diff -druN linux-2.6.39-libre/drivers/s390/cio/device_fsm.c linux-3.0-rc7-libre/drivers/s390/cio/device_fsm.c
--- linux-2.6.39-libre/drivers/s390/cio/device_fsm.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/s390/cio/device_fsm.c	2011-07-11 19:51:52.000000000 -0400
@@ -408,9 +408,10 @@
 		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) != NOTIFY_OK)
+		if (ccw_device_notify(cdev, CIO_NO_PATH) != NOTIFY_OK) {
+			cdev->private->state = DEV_STATE_NOT_OPER;
 			ccw_device_sched_todo(cdev, CDEV_TODO_UNREG);
-		else
+		} else
 			ccw_device_set_disconnected(cdev);
 		cdev->private->flags.donotify = 0;
 		break;
@@ -840,9 +841,6 @@
 static void
 ccw_device_killing_irq(struct ccw_device *cdev, enum dev_event dev_event)
 {
-	struct subchannel *sch;
-
-	sch = to_subchannel(cdev->dev.parent);
 	ccw_device_set_timeout(cdev, 0);
 	/* Start delayed path verification. */
 	ccw_device_online_verify(cdev, 0);
diff -druN linux-2.6.39-libre/drivers/s390/cio/device_ops.c linux-3.0-rc7-libre/drivers/s390/cio/device_ops.c
--- linux-2.6.39-libre/drivers/s390/cio/device_ops.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/s390/cio/device_ops.c	2011-07-11 19:51:52.000000000 -0400
@@ -418,12 +418,9 @@
 int
 ccw_device_call_handler(struct ccw_device *cdev)
 {
-	struct subchannel *sch;
 	unsigned int stctl;
 	int ending_status;
 
-	sch = to_subchannel(cdev->dev.parent);
-
 	/*
 	 * we allow for the device action handler if .
 	 *  - we received ending status
diff -druN linux-2.6.39-libre/drivers/s390/cio/qdio_main.c linux-3.0-rc7-libre/drivers/s390/cio/qdio_main.c
--- linux-2.6.39-libre/drivers/s390/cio/qdio_main.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/s390/cio/qdio_main.c	2011-07-11 19:51:52.000000000 -0400
@@ -416,7 +416,7 @@
 
 	/* special handling for no target buffer empty */
 	if ((!q->is_input_q &&
-	    (q->sbal[q->first_to_check]->element[15].flags & 0xff) == 0x10)) {
+	    (q->sbal[q->first_to_check]->element[15].sflags) == 0x10)) {
 		qperf_inc(q, target_full);
 		DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "OUTFULL FTC:%02x",
 			      q->first_to_check);
@@ -427,8 +427,8 @@
 	DBF_ERROR((q->is_input_q) ? "IN:%2d" : "OUT:%2d", q->nr);
 	DBF_ERROR("FTC:%3d C:%3d", q->first_to_check, count);
 	DBF_ERROR("F14:%2x F15:%2x",
-		  q->sbal[q->first_to_check]->element[14].flags & 0xff,
-		  q->sbal[q->first_to_check]->element[15].flags & 0xff);
+		  q->sbal[q->first_to_check]->element[14].sflags,
+		  q->sbal[q->first_to_check]->element[15].sflags);
 
 	/*
 	 * Interrupts may be avoided as long as the error is present
@@ -1446,7 +1446,7 @@
 static int handle_outbound(struct qdio_q *q, unsigned int callflags,
 			   int bufnr, int count)
 {
-	unsigned char state;
+	unsigned char state = 0;
 	int used, rc = 0;
 
 	qperf_inc(q, outbound_call);
diff -druN linux-2.6.39-libre/drivers/s390/crypto/ap_bus.c linux-3.0-rc7-libre/drivers/s390/crypto/ap_bus.c
--- linux-2.6.39-libre/drivers/s390/crypto/ap_bus.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/s390/crypto/ap_bus.c	2011-07-11 19:51:52.000000000 -0400
@@ -1183,8 +1183,12 @@
 		INIT_LIST_HEAD(&ap_dev->list);
 		setup_timer(&ap_dev->timeout, ap_request_timeout,
 			    (unsigned long) ap_dev);
-		if (device_type == 0)
-			ap_probe_device_type(ap_dev);
+		if (device_type == 0) {
+			if (ap_probe_device_type(ap_dev)) {
+				kfree(ap_dev);
+				continue;
+			}
+		}
 		else
 			ap_dev->device_type = device_type;
 
diff -druN linux-2.6.39-libre/drivers/s390/kvm/kvm_virtio.c linux-3.0-rc7-libre/drivers/s390/kvm/kvm_virtio.c
--- linux-2.6.39-libre/drivers/s390/kvm/kvm_virtio.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/s390/kvm/kvm_virtio.c	2011-07-11 19:51:52.000000000 -0400
@@ -25,7 +25,6 @@
 #include <asm/kvm_para.h>
 #include <asm/kvm_virtio.h>
 #include <asm/setup.h>
-#include <asm/s390_ext.h>
 #include <asm/irq.h>
 
 #define VIRTIO_SUBCODE_64 0x0D00
@@ -441,7 +440,7 @@
 
 	INIT_WORK(&hotplug_work, hotplug_devices);
 
-	ctl_set_bit(0, 9);
+	service_subclass_irq_register();
 	register_external_interrupt(0x2603, kvm_extint_handler);
 
 	scan_devices();
diff -druN linux-2.6.39-libre/drivers/s390/net/claw.c linux-3.0-rc7-libre/drivers/s390/net/claw.c
--- linux-2.6.39-libre/drivers/s390/net/claw.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/s390/net/claw.c	2011-07-11 19:51:52.000000000 -0400
@@ -845,12 +845,10 @@
 {
 	struct chbk * p_ch;
         struct net_device  *dev;
-        struct claw_privbk *       privptr;
 
 	p_ch = (struct chbk *) data;
         dev = (struct net_device *)p_ch->ndev;
 	CLAW_DBF_TEXT(4, trace, "IRQtask");
-	privptr = (struct claw_privbk *)dev->ml_priv;
         unpack_read(dev);
         clear_bit(CLAW_BH_ACTIVE, (void *)&p_ch->flag_a);
 	CLAW_DBF_TEXT(4, trace, "TskletXt");
@@ -1026,7 +1024,6 @@
         struct net_device  *dev;
         struct claw_privbk *privptr=NULL;
 	struct sk_buff *pk_skb;
-	int	rc;
 
 	CLAW_DBF_TEXT(4, trace, "claw_wrt");
         if (p_ch->claw_state == CLAW_STOP)
@@ -1038,7 +1035,7 @@
 	    !skb_queue_empty(&p_ch->collect_queue)) {
 	  	pk_skb = claw_pack_skb(privptr);
 		while (pk_skb != NULL) {
-			rc = claw_hw_tx( pk_skb, dev,1);
+			claw_hw_tx(pk_skb, dev, 1);
 			if (privptr->write_free_count > 0) {
 	   			pk_skb = claw_pack_skb(privptr);
 			} else
@@ -1322,15 +1319,12 @@
         unsigned char                   *pDataAddress;
         struct endccw                   *pEnd;
         struct ccw1                     tempCCW;
-        struct chbk                     *p_ch;
 	struct claw_env			*p_env;
-        int                             lock;
 	struct clawph			*pk_head;
 	struct chbk			*ch;
 
 	CLAW_DBF_TEXT(4, trace, "hw_tx");
 	privptr = (struct claw_privbk *)(dev->ml_priv);
-	p_ch = (struct chbk *)&privptr->channel[WRITE_CHANNEL];
 	p_env =privptr->p_env;
 	claw_free_wrt_buf(dev);	/* Clean up free chain if posible */
         /*  scan the write queue to free any completed write packets   */
@@ -1511,12 +1505,6 @@
 
         } /* endif (p_first_ccw!=NULL)  */
         dev_kfree_skb_any(skb);
-	if (linkid==0) {
-        	lock=LOCK_NO;
-        }
-        else  {
-                lock=LOCK_YES;
-        }
         claw_strt_out_IO(dev );
         /*      if write free count is zero , set NOBUFFER       */
 	if (privptr->write_free_count==0) {
@@ -2821,15 +2809,11 @@
 {
 
 	struct claw_privbk *privptr = (struct claw_privbk *)dev->ml_priv;
-        struct ccwbk*p_first_ccw;
-	struct ccwbk*p_last_ccw;
 	struct ccwbk*p_this_ccw;
 	struct ccwbk*p_next_ccw;
 
 	CLAW_DBF_TEXT(4, trace, "freewrtb");
         /*  scan the write queue to free any completed write packets   */
-        p_first_ccw=NULL;
-        p_last_ccw=NULL;
         p_this_ccw=privptr->p_write_active_first;
         while ( (p_this_ccw!=NULL) && (p_this_ccw->header.flag!=CLAW_PENDING))
         {
@@ -3072,7 +3056,7 @@
 {
 	struct claw_privbk *priv;
 	struct net_device *ndev;
-	int	ret;
+	int ret = 0;
 
 	CLAW_DBF_TEXT_(2, setup, "%s", dev_name(&cgdev->dev));
 	priv = dev_get_drvdata(&cgdev->dev);
@@ -3095,7 +3079,7 @@
 	}
 	ccw_device_set_offline(cgdev->cdev[1]);
 	ccw_device_set_offline(cgdev->cdev[0]);
-	return 0;
+	return ret;
 }
 
 static void
diff -druN linux-2.6.39-libre/drivers/s390/net/ctcm_main.c linux-3.0-rc7-libre/drivers/s390/net/ctcm_main.c
--- linux-2.6.39-libre/drivers/s390/net/ctcm_main.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/s390/net/ctcm_main.c	2011-07-11 19:51:52.000000000 -0400
@@ -672,7 +672,6 @@
 	int ccw_idx;
 	unsigned long hi;
 	unsigned long saveflags = 0;	/* avoids compiler warning */
-	__u16 block_len;
 
 	CTCM_PR_DEBUG("Enter %s: %s, cp=%i ch=0x%p id=%s state=%s\n",
 			__func__, dev->name, smp_processor_id(), ch,
@@ -719,7 +718,6 @@
 	 */
 	atomic_inc(&skb->users);
 
-	block_len = skb->len + TH_HEADER_LENGTH + PDU_HEADER_LENGTH;
 	/*
 	 * IDAL support in CTCM is broken, so we have to
 	 * care about skb's above 2G ourselves.
diff -druN linux-2.6.39-libre/drivers/s390/net/ctcm_mpc.c linux-3.0-rc7-libre/drivers/s390/net/ctcm_mpc.c
--- linux-2.6.39-libre/drivers/s390/net/ctcm_mpc.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/s390/net/ctcm_mpc.c	2011-07-11 19:51:52.000000000 -0400
@@ -653,7 +653,6 @@
 	struct net_device *dev = rch->netdev;
 	struct ctcm_priv *priv = dev->ml_priv;
 	struct mpc_group *grp = priv->mpcg;
-	int rc = 0;
 	struct th_sweep *header;
 	struct sk_buff *sweep_skb;
 	struct channel *ch  = priv->channel[CTCM_WRITE];
@@ -665,16 +664,14 @@
 		CTCM_DBF_TEXT_(MPC_ERROR, CTC_DBF_ERROR,
 			"%s(%s): sweep_skb allocation ERROR\n",
 			CTCM_FUNTAIL, rch->id);
-		rc = -ENOMEM;
-				goto done;
+		goto done;
 	}
 
 	header = kmalloc(sizeof(struct th_sweep), gfp_type());
 
 	if (!header) {
 		dev_kfree_skb_any(sweep_skb);
-		rc = -ENOMEM;
-				goto done;
+		goto done;
 	}
 
 	header->th.th_seg	= 0x00 ;
@@ -1370,8 +1367,7 @@
 	struct net_device  *dev = arg;
 	struct ctcm_priv    *priv;
 	struct mpc_group *grp;
-	int rc = 0;
-	struct channel *wch, *rch;
+	struct channel *wch;
 
 	BUG_ON(dev == NULL);
 	CTCM_PR_DEBUG("Enter %s: %s\n",	__func__, dev->name);
@@ -1396,7 +1392,6 @@
 		fsm_deltimer(&priv->restart_timer);
 
 	wch = priv->channel[CTCM_WRITE];
-	rch = priv->channel[CTCM_READ];
 
 	switch (grp->saved_state) {
 	case MPCG_STATE_RESET:
@@ -1435,7 +1430,7 @@
 
 	if (grp->send_qllc_disc == 1) {
 		grp->send_qllc_disc = 0;
-		rc = mpc_send_qllc_discontact(dev);
+		mpc_send_qllc_discontact(dev);
 	}
 
 	/* DO NOT issue DEV_EVENT_STOP directly out of this code */
diff -druN linux-2.6.39-libre/drivers/s390/net/lcs.c linux-3.0-rc7-libre/drivers/s390/net/lcs.c
--- linux-2.6.39-libre/drivers/s390/net/lcs.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/s390/net/lcs.c	2011-07-11 19:51:52.000000000 -0400
@@ -1483,7 +1483,6 @@
 	struct lcs_channel *channel;
 	struct lcs_buffer *iob;
 	int buf_idx;
-	int rc;
 
 	channel = (struct lcs_channel *) data;
 	LCS_DBF_TEXT_(5, trace, "tlet%s", dev_name(&channel->ccwdev->dev));
@@ -1500,14 +1499,11 @@
 	channel->buf_idx = buf_idx;
 
 	if (channel->state == LCS_CH_STATE_STOPPED)
-		// FIXME: what if rc != 0 ??
-		rc = lcs_start_channel(channel);
+		lcs_start_channel(channel);
 	spin_lock_irqsave(get_ccwdev_lock(channel->ccwdev), flags);
 	if (channel->state == LCS_CH_STATE_SUSPENDED &&
-	    channel->iob[channel->io_idx].state == LCS_BUF_STATE_READY) {
-		// FIXME: what if rc != 0 ??
-		rc = __lcs_resume_channel(channel);
-	}
+	    channel->iob[channel->io_idx].state == LCS_BUF_STATE_READY)
+		__lcs_resume_channel(channel);
 	spin_unlock_irqrestore(get_ccwdev_lock(channel->ccwdev), flags);
 
 	/* Something happened on the channel. Wake up waiters. */
diff -druN linux-2.6.39-libre/drivers/s390/net/netiucv.c linux-3.0-rc7-libre/drivers/s390/net/netiucv.c
--- linux-2.6.39-libre/drivers/s390/net/netiucv.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/s390/net/netiucv.c	2011-07-11 19:51:52.000000000 -0400
@@ -1994,8 +1994,6 @@
 			   netiucv_setup_netdevice);
 	if (!dev)
 		return NULL;
-	if (dev_alloc_name(dev, dev->name) < 0)
-		goto out_netdev;
 
 	privptr = netdev_priv(dev);
 	privptr->fsm = init_fsm("netiucvdev", dev_state_names,
diff -druN linux-2.6.39-libre/drivers/s390/net/qeth_core.h linux-3.0-rc7-libre/drivers/s390/net/qeth_core.h
--- linux-2.6.39-libre/drivers/s390/net/qeth_core.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/s390/net/qeth_core.h	2011-07-11 19:51:52.000000000 -0400
@@ -361,7 +361,7 @@
 
 static inline int qeth_is_last_sbale(struct qdio_buffer_element *sbale)
 {
-	return (sbale->flags & SBAL_FLAGS_LAST_ENTRY);
+	return (sbale->eflags & SBAL_EFLAGS_LAST_ENTRY);
 }
 
 enum qeth_qdio_buffer_states {
@@ -407,12 +407,6 @@
 	int next_buf_to_init;
 } __attribute__ ((aligned(256)));
 
-/* possible types of qeth large_send support */
-enum qeth_large_send_types {
-	QETH_LARGE_SEND_NO,
-	QETH_LARGE_SEND_TSO,
-};
-
 struct qeth_qdio_out_buffer {
 	struct qdio_buffer *buffer;
 	atomic_t state;
@@ -637,6 +631,8 @@
 	__u32 csum_mask;
 	__u32 tx_csum_mask;
 	enum qeth_ipa_promisc_modes promisc_mode;
+	__u32 diagass_support;
+	__u32 hwtrap;
 };
 
 struct qeth_card_options {
@@ -645,13 +641,11 @@
 	struct qeth_ipa_info adp; /*Adapter parameters*/
 	struct qeth_routing_info route6;
 	struct qeth_ipa_info ipa6;
-	enum qeth_checksum_types checksum_type;
 	int broadcast_mode;
 	int macaddr_mode;
 	int fake_broadcast;
 	int add_hhlen;
 	int layer2;
-	enum qeth_large_send_types large_send;
 	int performance_stats;
 	int rx_sg_cb;
 	enum qeth_ipa_isolation_modes isolation;
@@ -760,6 +754,14 @@
 	rwlock_t rwlock;
 };
 
+struct qeth_trap_id {
+	__u16 lparnr;
+	char vmname[8];
+	__u8 chpid;
+	__u8 ssid;
+	__u16 devno;
+} __packed;
+
 /*some helper functions*/
 #define QETH_CARD_IFNAME(card) (((card)->dev)? (card)->dev->name : "")
 
@@ -794,6 +796,12 @@
 	list_add_tail(&entry->list, &card->qdio.in_buf_pool.entry_list);
 }
 
+static inline int qeth_is_diagass_supported(struct qeth_card *card,
+		enum qeth_diags_cmds cmd)
+{
+	return card->info.diagass_support & (__u32)cmd;
+}
+
 extern struct ccwgroup_driver qeth_l2_ccwgroup_driver;
 extern struct ccwgroup_driver qeth_l3_ccwgroup_driver;
 const char *qeth_get_cardname_short(struct qeth_card *);
@@ -879,6 +887,8 @@
 int qeth_core_ethtool_get_settings(struct net_device *, struct ethtool_cmd *);
 int qeth_set_access_ctrl_online(struct qeth_card *card);
 int qeth_hdr_chk_and_bounce(struct sk_buff *, int);
+int qeth_hw_trap(struct qeth_card *, enum qeth_diags_trap_action);
+int qeth_query_ipassists(struct qeth_card *, enum qeth_prot_versions prot);
 
 /* exports for OSN */
 int qeth_osn_assist(struct net_device *, void *, int);
diff -druN linux-2.6.39-libre/drivers/s390/net/qeth_core_main.c linux-3.0-rc7-libre/drivers/s390/net/qeth_core_main.c
--- linux-2.6.39-libre/drivers/s390/net/qeth_core_main.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/s390/net/qeth_core_main.c	2011-07-11 19:51:52.000000000 -0400
@@ -24,6 +24,7 @@
 
 #include <asm/ebcdic.h>
 #include <asm/io.h>
+#include <asm/sysinfo.h>
 
 #include "qeth_core.h"
 
@@ -349,6 +350,8 @@
 					   card->info.chpid);
 				netif_carrier_on(card->dev);
 				card->lan_online = 1;
+				if (card->info.hwtrap)
+					card->info.hwtrap = 2;
 				qeth_schedule_recovery(card);
 				return NULL;
 			case IPA_CMD_MODCCID:
@@ -887,7 +890,7 @@
 	struct sk_buff *skb;
 
 	/* is PCI flag set on buffer? */
-	if (buf->buffer->element[0].flags & 0x40)
+	if (buf->buffer->element[0].sflags & SBAL_SFLAGS0_PCI_REQ)
 		atomic_dec(&queue->set_pci_flags_count);
 
 	skb = skb_dequeue(&buf->skb_list);
@@ -903,9 +906,11 @@
 		buf->is_header[i] = 0;
 		buf->buffer->element[i].length = 0;
 		buf->buffer->element[i].addr = NULL;
-		buf->buffer->element[i].flags = 0;
+		buf->buffer->element[i].eflags = 0;
+		buf->buffer->element[i].sflags = 0;
 	}
-	buf->buffer->element[15].flags = 0;
+	buf->buffer->element[15].eflags = 0;
+	buf->buffer->element[15].sflags = 0;
 	buf->next_element_to_fill = 0;
 	atomic_set(&buf->state, QETH_QDIO_BUF_EMPTY);
 }
@@ -1039,7 +1044,6 @@
 {
 	card->options.route4.type = NO_ROUTER;
 	card->options.route6.type = NO_ROUTER;
-	card->options.checksum_type = QETH_CHECKSUM_DEFAULT;
 	card->options.broadcast_mode = QETH_TR_BROADCAST_ALLRINGS;
 	card->options.macaddr_mode = QETH_TR_MACADDR_NONCANONICAL;
 	card->options.fake_broadcast = 0;
@@ -2366,9 +2370,10 @@
 		buf->buffer->element[i].length = PAGE_SIZE;
 		buf->buffer->element[i].addr =  pool_entry->elements[i];
 		if (i == QETH_MAX_BUFFER_ELEMENTS(card) - 1)
-			buf->buffer->element[i].flags = SBAL_FLAGS_LAST_ENTRY;
+			buf->buffer->element[i].eflags = SBAL_EFLAGS_LAST_ENTRY;
 		else
-			buf->buffer->element[i].flags = 0;
+			buf->buffer->element[i].eflags = 0;
+		buf->buffer->element[i].sflags = 0;
 	}
 	return 0;
 }
@@ -2574,17 +2579,153 @@
 }
 EXPORT_SYMBOL_GPL(qeth_query_setadapterparms);
 
+static int qeth_query_ipassists_cb(struct qeth_card *card,
+		struct qeth_reply *reply, unsigned long data)
+{
+	struct qeth_ipa_cmd *cmd;
+
+	QETH_DBF_TEXT(SETUP, 2, "qipasscb");
+
+	cmd = (struct qeth_ipa_cmd *) data;
+	if (cmd->hdr.prot_version == QETH_PROT_IPV4) {
+		card->options.ipa4.supported_funcs = cmd->hdr.ipa_supported;
+		card->options.ipa4.enabled_funcs = cmd->hdr.ipa_enabled;
+	} else {
+		card->options.ipa6.supported_funcs = cmd->hdr.ipa_supported;
+		card->options.ipa6.enabled_funcs = cmd->hdr.ipa_enabled;
+	}
+	QETH_DBF_TEXT(SETUP, 2, "suppenbl");
+	QETH_DBF_TEXT_(SETUP, 2, "%x", cmd->hdr.ipa_supported);
+	QETH_DBF_TEXT_(SETUP, 2, "%x", cmd->hdr.ipa_enabled);
+	return 0;
+}
+
+int qeth_query_ipassists(struct qeth_card *card, enum qeth_prot_versions prot)
+{
+	int rc;
+	struct qeth_cmd_buffer *iob;
+
+	QETH_DBF_TEXT_(SETUP, 2, "qipassi%i", prot);
+	iob = qeth_get_ipacmd_buffer(card, IPA_CMD_QIPASSIST, prot);
+	rc = qeth_send_ipa_cmd(card, iob, qeth_query_ipassists_cb, NULL);
+	return rc;
+}
+EXPORT_SYMBOL_GPL(qeth_query_ipassists);
+
+static int qeth_query_setdiagass_cb(struct qeth_card *card,
+		struct qeth_reply *reply, unsigned long data)
+{
+	struct qeth_ipa_cmd *cmd;
+	__u16 rc;
+
+	cmd = (struct qeth_ipa_cmd *)data;
+	rc = cmd->hdr.return_code;
+	if (rc)
+		QETH_CARD_TEXT_(card, 2, "diagq:%x", rc);
+	else
+		card->info.diagass_support = cmd->data.diagass.ext;
+	return 0;
+}
+
+static int qeth_query_setdiagass(struct qeth_card *card)
+{
+	struct qeth_cmd_buffer *iob;
+	struct qeth_ipa_cmd    *cmd;
+
+	QETH_DBF_TEXT(SETUP, 2, "qdiagass");
+	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_QUERY;
+	return qeth_send_ipa_cmd(card, iob, qeth_query_setdiagass_cb, NULL);
+}
+
+static void qeth_get_trap_id(struct qeth_card *card, struct qeth_trap_id *tid)
+{
+	unsigned long info = get_zeroed_page(GFP_KERNEL);
+	struct sysinfo_2_2_2 *info222 = (struct sysinfo_2_2_2 *)info;
+	struct sysinfo_3_2_2 *info322 = (struct sysinfo_3_2_2 *)info;
+	struct ccw_dev_id ccwid;
+	int level, rc;
+
+	tid->chpid = card->info.chpid;
+	ccw_device_get_id(CARD_RDEV(card), &ccwid);
+	tid->ssid = ccwid.ssid;
+	tid->devno = ccwid.devno;
+	if (!info)
+		return;
+
+	rc = stsi(NULL, 0, 0, 0);
+	if (rc == -ENOSYS)
+		level = rc;
+	else
+		level = (((unsigned int) rc) >> 28);
+
+	if ((level >= 2) && (stsi(info222, 2, 2, 2) != -ENOSYS))
+		tid->lparnr = info222->lpar_number;
+
+	if ((level >= 3) && (stsi(info322, 3, 2, 2) != -ENOSYS)) {
+		EBCASC(info322->vm[0].name, sizeof(info322->vm[0].name));
+		memcpy(tid->vmname, info322->vm[0].name, sizeof(tid->vmname));
+	}
+	free_page(info);
+	return;
+}
+
+static int qeth_hw_trap_cb(struct qeth_card *card,
+		struct qeth_reply *reply, unsigned long data)
+{
+	struct qeth_ipa_cmd *cmd;
+	__u16 rc;
+
+	cmd = (struct qeth_ipa_cmd *)data;
+	rc = cmd->hdr.return_code;
+	if (rc)
+		QETH_CARD_TEXT_(card, 2, "trapc:%x", rc);
+	return 0;
+}
+
+int qeth_hw_trap(struct qeth_card *card, enum qeth_diags_trap_action action)
+{
+	struct qeth_cmd_buffer *iob;
+	struct qeth_ipa_cmd *cmd;
+
+	QETH_DBF_TEXT(SETUP, 2, "diagtrap");
+	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 = 80;
+	cmd->data.diagass.subcmd = QETH_DIAGS_CMD_TRAP;
+	cmd->data.diagass.type = 1;
+	cmd->data.diagass.action = action;
+	switch (action) {
+	case QETH_DIAGS_TRAP_ARM:
+		cmd->data.diagass.options = 0x0003;
+		cmd->data.diagass.ext = 0x00010000 +
+			sizeof(struct qeth_trap_id);
+		qeth_get_trap_id(card,
+			(struct qeth_trap_id *)cmd->data.diagass.cdata);
+		break;
+	case QETH_DIAGS_TRAP_DISARM:
+		cmd->data.diagass.options = 0x0001;
+		break;
+	case QETH_DIAGS_TRAP_CAPTURE:
+		break;
+	}
+	return qeth_send_ipa_cmd(card, iob, qeth_hw_trap_cb, NULL);
+}
+EXPORT_SYMBOL_GPL(qeth_hw_trap);
+
 int qeth_check_qdio_errors(struct qeth_card *card, struct qdio_buffer *buf,
 		unsigned int qdio_error, const char *dbftext)
 {
 	if (qdio_error) {
 		QETH_CARD_TEXT(card, 2, dbftext);
 		QETH_CARD_TEXT_(card, 2, " F15=%02X",
-			       buf->element[15].flags & 0xff);
+			       buf->element[15].sflags);
 		QETH_CARD_TEXT_(card, 2, " F14=%02X",
-			       buf->element[14].flags & 0xff);
+			       buf->element[14].sflags);
 		QETH_CARD_TEXT_(card, 2, " qerr=%X", qdio_error);
-		if ((buf->element[15].flags & 0xff) == 0x12) {
+		if ((buf->element[15].sflags) == 0x12) {
 			card->stats.rx_dropped++;
 			return 0;
 		} else
@@ -2660,7 +2801,7 @@
 static int qeth_handle_send_error(struct qeth_card *card,
 		struct qeth_qdio_out_buffer *buffer, unsigned int qdio_err)
 {
-	int sbalf15 = buffer->buffer->element[15].flags & 0xff;
+	int sbalf15 = buffer->buffer->element[15].sflags;
 
 	QETH_CARD_TEXT(card, 6, "hdsnderr");
 	if (card->info.type == QETH_CARD_TYPE_IQD) {
@@ -2769,8 +2910,8 @@
 
 	for (i = index; i < index + count; ++i) {
 		buf = &queue->bufs[i % QDIO_MAX_BUFFERS_PER_Q];
-		buf->buffer->element[buf->next_element_to_fill - 1].flags |=
-				SBAL_FLAGS_LAST_ENTRY;
+		buf->buffer->element[buf->next_element_to_fill - 1].eflags |=
+				SBAL_EFLAGS_LAST_ENTRY;
 
 		if (queue->card->info.type == QETH_CARD_TYPE_IQD)
 			continue;
@@ -2783,7 +2924,7 @@
 				/* it's likely that we'll go to packing
 				 * mode soon */
 				atomic_inc(&queue->set_pci_flags_count);
-				buf->buffer->element[0].flags |= 0x40;
+				buf->buffer->element[0].sflags |= SBAL_SFLAGS0_PCI_REQ;
 			}
 		} else {
 			if (!atomic_read(&queue->set_pci_flags_count)) {
@@ -2796,7 +2937,7 @@
 				 * further send was requested by the stack
 				 */
 				atomic_inc(&queue->set_pci_flags_count);
-				buf->buffer->element[0].flags |= 0x40;
+				buf->buffer->element[0].sflags |= SBAL_SFLAGS0_PCI_REQ;
 			}
 		}
 	}
@@ -3042,20 +3183,20 @@
 		if (!length) {
 			if (first_lap)
 				if (skb_shinfo(skb)->nr_frags)
-					buffer->element[element].flags =
-						SBAL_FLAGS_FIRST_FRAG;
+					buffer->element[element].eflags =
+						SBAL_EFLAGS_FIRST_FRAG;
 				else
-					buffer->element[element].flags = 0;
+					buffer->element[element].eflags = 0;
 			else
-				buffer->element[element].flags =
-				    SBAL_FLAGS_MIDDLE_FRAG;
+				buffer->element[element].eflags =
+				    SBAL_EFLAGS_MIDDLE_FRAG;
 		} else {
 			if (first_lap)
-				buffer->element[element].flags =
-				    SBAL_FLAGS_FIRST_FRAG;
+				buffer->element[element].eflags =
+				    SBAL_EFLAGS_FIRST_FRAG;
 			else
-				buffer->element[element].flags =
-				    SBAL_FLAGS_MIDDLE_FRAG;
+				buffer->element[element].eflags =
+				    SBAL_EFLAGS_MIDDLE_FRAG;
 		}
 		data += length_here;
 		element++;
@@ -3067,12 +3208,12 @@
 		buffer->element[element].addr = (char *)page_to_phys(frag->page)
 			+ frag->page_offset;
 		buffer->element[element].length = frag->size;
-		buffer->element[element].flags = SBAL_FLAGS_MIDDLE_FRAG;
+		buffer->element[element].eflags = SBAL_EFLAGS_MIDDLE_FRAG;
 		element++;
 	}
 
-	if (buffer->element[element - 1].flags)
-		buffer->element[element - 1].flags = SBAL_FLAGS_LAST_FRAG;
+	if (buffer->element[element - 1].eflags)
+		buffer->element[element - 1].eflags = SBAL_EFLAGS_LAST_FRAG;
 	*next_element_to_fill = element;
 }
 
@@ -3096,7 +3237,7 @@
 		/*fill first buffer entry only with header information */
 		buffer->element[element].addr = skb->data;
 		buffer->element[element].length = hdr_len;
-		buffer->element[element].flags = SBAL_FLAGS_FIRST_FRAG;
+		buffer->element[element].eflags = SBAL_EFLAGS_FIRST_FRAG;
 		buf->next_element_to_fill++;
 		skb->data += hdr_len;
 		skb->len  -= hdr_len;
@@ -3108,7 +3249,7 @@
 		buffer->element[element].addr = hdr;
 		buffer->element[element].length = sizeof(struct qeth_hdr) +
 							hd_len;
-		buffer->element[element].flags = SBAL_FLAGS_FIRST_FRAG;
+		buffer->element[element].eflags = SBAL_EFLAGS_FIRST_FRAG;
 		buf->is_header[element] = 1;
 		buf->next_element_to_fill++;
 	}
@@ -3903,6 +4044,7 @@
 
 static struct ccw_driver qeth_ccw_driver = {
 	.driver = {
+		.owner = THIS_MODULE,
 		.name = "qeth",
 	},
 	.ids = qeth_ids,
@@ -3984,6 +4126,15 @@
 		QETH_DBF_TEXT_(SETUP, 2, "5err%d", rc);
 		goto out;
 	}
+
+	card->options.ipa4.supported_funcs = 0;
+	card->options.adp.supported_funcs = 0;
+	card->info.diagass_support = 0;
+	qeth_query_ipassists(card, QETH_PROT_IPV4);
+	if (qeth_is_supported(card, IPA_SETADAPTERPARMS))
+		qeth_query_setadapterparms(card);
+	if (qeth_adp_supported(card, IPA_SETADP_SET_DIAG_ASSIST))
+		qeth_query_setdiagass(card);
 	return 0;
 out:
 	dev_warn(&card->gdev->dev, "The qeth device driver failed to recover "
diff -druN linux-2.6.39-libre/drivers/s390/net/qeth_core_mpc.h linux-3.0-rc7-libre/drivers/s390/net/qeth_core_mpc.h
--- linux-2.6.39-libre/drivers/s390/net/qeth_core_mpc.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/s390/net/qeth_core_mpc.h	2011-07-11 19:51:52.000000000 -0400
@@ -80,14 +80,6 @@
 	QETH_TR_BROADCAST_LOCAL    = 1,
 };
 
-/* these values match CHECKSUM_* in include/linux/skbuff.h */
-enum qeth_checksum_types {
-	SW_CHECKSUMMING = 0, /* TODO: set to bit flag used in IPA Command */
-	HW_CHECKSUMMING = 1,
-	NO_CHECKSUMMING = 2,
-};
-#define QETH_CHECKSUM_DEFAULT SW_CHECKSUMMING
-
 /*
  * Routing stuff
  */
@@ -456,6 +448,12 @@
 	QETH_DIAGS_CMD_TRACE_QUERY	= 0x0010,
 };
 
+enum qeth_diags_trap_action {
+	QETH_DIAGS_TRAP_ARM	= 0x01,
+	QETH_DIAGS_TRAP_DISARM	= 0x02,
+	QETH_DIAGS_TRAP_CAPTURE = 0x04,
+};
+
 struct qeth_ipacmd_diagass {
 	__u32  host_tod2;
 	__u32:32;
@@ -465,7 +463,8 @@
 	__u8   type;
 	__u8   action;
 	__u16  options;
-	__u32:32;
+	__u32  ext;
+	__u8   cdata[64];
 } __attribute__ ((packed));
 
 /* Header for each IPA command */
diff -druN linux-2.6.39-libre/drivers/s390/net/qeth_core_sys.c linux-3.0-rc7-libre/drivers/s390/net/qeth_core_sys.c
--- linux-2.6.39-libre/drivers/s390/net/qeth_core_sys.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/s390/net/qeth_core_sys.c	2011-07-11 19:51:52.000000000 -0400
@@ -530,6 +530,66 @@
 static DEVICE_ATTR(isolation, 0644, qeth_dev_isolation_show,
 		   qeth_dev_isolation_store);
 
+static ssize_t qeth_hw_trap_show(struct device *dev,
+				struct device_attribute *attr, char *buf)
+{
+	struct qeth_card *card = dev_get_drvdata(dev);
+
+	if (!card)
+		return -EINVAL;
+	if (card->info.hwtrap)
+		return snprintf(buf, 5, "arm\n");
+	else
+		return snprintf(buf, 8, "disarm\n");
+}
+
+static ssize_t qeth_hw_trap_store(struct device *dev,
+		struct device_attribute *attr, const char *buf, size_t count)
+{
+	struct qeth_card *card = dev_get_drvdata(dev);
+	int rc = 0;
+	char *tmp, *curtoken;
+	int state = 0;
+	curtoken = (char *)buf;
+
+	if (!card)
+		return -EINVAL;
+
+	mutex_lock(&card->conf_mutex);
+	if (card->state == CARD_STATE_SOFTSETUP || card->state == CARD_STATE_UP)
+		state = 1;
+	tmp = strsep(&curtoken, "\n");
+
+	if (!strcmp(tmp, "arm") && !card->info.hwtrap) {
+		if (state) {
+			if (qeth_is_diagass_supported(card,
+			    QETH_DIAGS_CMD_TRAP)) {
+				rc = qeth_hw_trap(card, QETH_DIAGS_TRAP_ARM);
+				if (!rc)
+					card->info.hwtrap = 1;
+			} else
+				rc = -EINVAL;
+		} else
+			card->info.hwtrap = 1;
+	} else if (!strcmp(tmp, "disarm") && card->info.hwtrap) {
+		if (state) {
+			rc = qeth_hw_trap(card, QETH_DIAGS_TRAP_DISARM);
+			if (!rc)
+				card->info.hwtrap = 0;
+		} else
+			card->info.hwtrap = 0;
+	} else if (!strcmp(tmp, "trap") && state && card->info.hwtrap)
+		rc = qeth_hw_trap(card, QETH_DIAGS_TRAP_CAPTURE);
+	else
+		rc = -EINVAL;
+
+	mutex_unlock(&card->conf_mutex);
+	return rc ? rc : count;
+}
+
+static DEVICE_ATTR(hw_trap, 0644, qeth_hw_trap_show,
+		   qeth_hw_trap_store);
+
 static ssize_t qeth_dev_blkt_show(char *buf, struct qeth_card *card, int value)
 {
 
@@ -653,6 +713,7 @@
 	&dev_attr_performance_stats.attr,
 	&dev_attr_layer2.attr,
 	&dev_attr_isolation.attr,
+	&dev_attr_hw_trap.attr,
 	NULL,
 };
 
diff -druN linux-2.6.39-libre/drivers/s390/net/qeth_l2_main.c linux-3.0-rc7-libre/drivers/s390/net/qeth_l2_main.c
--- linux-2.6.39-libre/drivers/s390/net/qeth_l2_main.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/s390/net/qeth_l2_main.c	2011-07-11 19:51:52.000000000 -0400
@@ -420,10 +420,7 @@
 		case QETH_HEADER_TYPE_LAYER2:
 			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;
+			skb->ip_summed = CHECKSUM_NONE;
 			if (skb->protocol == htons(ETH_P_802_2))
 				*((__u32 *)skb->cb) = ++card->seqno.pkt_seqno;
 			len = skb->len;
@@ -879,6 +876,7 @@
 	INIT_LIST_HEAD(&card->vid_list);
 	INIT_LIST_HEAD(&card->mc_list);
 	card->options.layer2 = 1;
+	card->info.hwtrap = 0;
 	card->discipline.start_poll = qeth_qdio_start_poll;
 	card->discipline.input_handler = (qdio_handler_t *)
 		qeth_qdio_input_handler;
@@ -997,6 +995,13 @@
 	if (card->info.type != QETH_CARD_TYPE_OSN)
 		qeth_l2_send_setmac(card, &card->dev->dev_addr[0]);
 
+	if (qeth_is_diagass_supported(card, QETH_DIAGS_CMD_TRAP)) {
+		if (card->info.hwtrap &&
+		    qeth_hw_trap(card, QETH_DIAGS_TRAP_ARM))
+			card->info.hwtrap = 0;
+	} else
+		card->info.hwtrap = 0;
+
 	card->state = CARD_STATE_HARDSETUP;
 	memset(&card->rx, 0, sizeof(struct qeth_rx));
 	qeth_print_status_message(card);
@@ -1095,6 +1100,10 @@
 	if (card->dev && netif_carrier_ok(card->dev))
 		netif_carrier_off(card->dev);
 	recover_flag = card->state;
+	if ((!recovery_mode && card->info.hwtrap) || card->info.hwtrap == 2) {
+		qeth_hw_trap(card, QETH_DIAGS_TRAP_DISARM);
+		card->info.hwtrap = 1;
+	}
 	qeth_l2_stop_card(card, recovery_mode);
 	rc  = ccw_device_set_offline(CARD_DDEV(card));
 	rc2 = ccw_device_set_offline(CARD_WDEV(card));
@@ -1160,6 +1169,8 @@
 static void qeth_l2_shutdown(struct ccwgroup_device *gdev)
 {
 	struct qeth_card *card = dev_get_drvdata(&gdev->dev);
+	if ((gdev->state == CCWGROUP_ONLINE) && card->info.hwtrap)
+		qeth_hw_trap(card, QETH_DIAGS_TRAP_DISARM);
 	qeth_qdio_clear_card(card, 0);
 	qeth_clear_qdio_buffers(card);
 }
@@ -1175,6 +1186,8 @@
 	if (gdev->state == CCWGROUP_OFFLINE)
 		return 0;
 	if (card->state == CARD_STATE_UP) {
+		if (card->info.hwtrap)
+			qeth_hw_trap(card, QETH_DIAGS_TRAP_DISARM);
 		__qeth_l2_set_offline(card->gdev, 1);
 	} else
 		__qeth_l2_set_offline(card->gdev, 0);
diff -druN linux-2.6.39-libre/drivers/s390/net/qeth_l3.h linux-3.0-rc7-libre/drivers/s390/net/qeth_l3.h
--- linux-2.6.39-libre/drivers/s390/net/qeth_l3.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/s390/net/qeth_l3.h	2011-07-11 19:51:52.000000000 -0400
@@ -62,8 +62,6 @@
 int qeth_l3_add_rxip(struct qeth_card *, enum qeth_prot_versions, const u8 *);
 void qeth_l3_del_rxip(struct qeth_card *card, enum qeth_prot_versions,
 			const u8 *);
-int qeth_l3_set_large_send(struct qeth_card *, enum qeth_large_send_types);
-int qeth_l3_set_rx_csum(struct qeth_card *, enum qeth_checksum_types);
 int qeth_l3_is_addr_covered_by_ipato(struct qeth_card *, struct qeth_ipaddr *);
 
 #endif /* __QETH_L3_H__ */
diff -druN linux-2.6.39-libre/drivers/s390/net/qeth_l3_main.c linux-3.0-rc7-libre/drivers/s390/net/qeth_l3_main.c
--- linux-2.6.39-libre/drivers/s390/net/qeth_l3_main.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/s390/net/qeth_l3_main.c	2011-07-11 19:51:52.000000000 -0400
@@ -43,33 +43,6 @@
 static int __qeth_l3_set_online(struct ccwgroup_device *, int);
 static int __qeth_l3_set_offline(struct ccwgroup_device *, int);
 
-int qeth_l3_set_large_send(struct qeth_card *card,
-		enum qeth_large_send_types type)
-{
-	int rc = 0;
-
-	card->options.large_send = type;
-	if (card->dev == NULL)
-		return 0;
-
-	if (card->options.large_send == QETH_LARGE_SEND_TSO) {
-		if (qeth_is_supported(card, IPA_OUTBOUND_TSO)) {
-			card->dev->features |= NETIF_F_TSO | NETIF_F_SG |
-					NETIF_F_IP_CSUM;
-		} else {
-			card->dev->features &= ~(NETIF_F_TSO | NETIF_F_SG |
-					NETIF_F_IP_CSUM);
-			card->options.large_send = QETH_LARGE_SEND_NO;
-			rc = -EOPNOTSUPP;
-		}
-	} else {
-		card->dev->features &= ~(NETIF_F_TSO | NETIF_F_SG |
-					NETIF_F_IP_CSUM);
-		card->options.large_send = QETH_LARGE_SEND_NO;
-	}
-	return rc;
-}
-
 static int qeth_l3_isxdigit(char *buf)
 {
 	while (*buf) {
@@ -1304,39 +1277,6 @@
 	return rc;
 }
 
-static int qeth_l3_query_ipassists_cb(struct qeth_card *card,
-		struct qeth_reply *reply, unsigned long data)
-{
-	struct qeth_ipa_cmd *cmd;
-
-	QETH_DBF_TEXT(SETUP, 2, "qipasscb");
-
-	cmd = (struct qeth_ipa_cmd *) data;
-	if (cmd->hdr.prot_version == QETH_PROT_IPV4) {
-		card->options.ipa4.supported_funcs = cmd->hdr.ipa_supported;
-		card->options.ipa4.enabled_funcs = cmd->hdr.ipa_enabled;
-	} else {
-		card->options.ipa6.supported_funcs = cmd->hdr.ipa_supported;
-		card->options.ipa6.enabled_funcs = cmd->hdr.ipa_enabled;
-	}
-	QETH_DBF_TEXT(SETUP, 2, "suppenbl");
-	QETH_DBF_TEXT_(SETUP, 2, "%x", cmd->hdr.ipa_supported);
-	QETH_DBF_TEXT_(SETUP, 2, "%x", cmd->hdr.ipa_enabled);
-	return 0;
-}
-
-static int qeth_l3_query_ipassists(struct qeth_card *card,
-				enum qeth_prot_versions prot)
-{
-	int rc;
-	struct qeth_cmd_buffer *iob;
-
-	QETH_DBF_TEXT_(SETUP, 2, "qipassi%i", prot);
-	iob = qeth_get_ipacmd_buffer(card, IPA_CMD_QIPASSIST, prot);
-	rc = qeth_send_ipa_cmd(card, iob, qeth_l3_query_ipassists_cb, NULL);
-	return rc;
-}
-
 #ifdef CONFIG_QETH_IPV6
 static int qeth_l3_softsetup_ipv6(struct qeth_card *card)
 {
@@ -1347,7 +1287,7 @@
 	if (card->info.type == QETH_CARD_TYPE_IQD)
 		goto out;
 
-	rc = qeth_l3_query_ipassists(card, QETH_PROT_IPV6);
+	rc = qeth_query_ipassists(card, QETH_PROT_IPV6);
 	if (rc) {
 		dev_err(&card->gdev->dev,
 			"Activating IPv6 support for %s failed\n",
@@ -1472,68 +1412,38 @@
 	return 0;
 }
 
-int qeth_l3_set_rx_csum(struct qeth_card *card,
-	enum qeth_checksum_types csum_type)
+int qeth_l3_set_rx_csum(struct qeth_card *card, int on)
 {
 	int rc = 0;
 
-	if (card->options.checksum_type == HW_CHECKSUMMING) {
-		if ((csum_type != HW_CHECKSUMMING) &&
-			(card->state != CARD_STATE_DOWN)) {
-			rc = qeth_l3_send_simple_setassparms(card,
-				IPA_INBOUND_CHECKSUM, IPA_CMD_ASS_STOP, 0);
-			if (rc)
-				return -EIO;
-		}
+	if (on) {
+		rc = qeth_l3_send_checksum_command(card);
+		if (rc)
+			return -EIO;
+		dev_info(&card->gdev->dev,
+			"HW Checksumming (inbound) enabled\n");
 	} else {
-		if (csum_type == HW_CHECKSUMMING) {
-			if (card->state != CARD_STATE_DOWN) {
-				if (!qeth_is_supported(card,
-				    IPA_INBOUND_CHECKSUM))
-					return -EPERM;
-				rc = qeth_l3_send_checksum_command(card);
-				if (rc)
-					return -EIO;
-			}
-		}
+		rc = qeth_l3_send_simple_setassparms(card,
+			IPA_INBOUND_CHECKSUM, IPA_CMD_ASS_STOP, 0);
+		if (rc)
+			return -EIO;
 	}
-	card->options.checksum_type = csum_type;
-	return rc;
+
+	return 0;
 }
 
 static int qeth_l3_start_ipa_checksum(struct qeth_card *card)
 {
-	int rc = 0;
-
 	QETH_CARD_TEXT(card, 3, "strtcsum");
 
-	if (card->options.checksum_type == NO_CHECKSUMMING) {
-		dev_info(&card->gdev->dev,
-			"Using no checksumming on %s.\n",
-			QETH_CARD_IFNAME(card));
-		return 0;
-	}
-	if (card->options.checksum_type == SW_CHECKSUMMING) {
-		dev_info(&card->gdev->dev,
-			"Using SW checksumming on %s.\n",
-			QETH_CARD_IFNAME(card));
-		return 0;
-	}
-	if (!qeth_is_supported(card, IPA_INBOUND_CHECKSUM)) {
-		dev_info(&card->gdev->dev,
-			"Inbound HW Checksumming not "
-			"supported on %s,\ncontinuing "
-			"using Inbound SW Checksumming\n",
-			QETH_CARD_IFNAME(card));
-		card->options.checksum_type = SW_CHECKSUMMING;
-		return 0;
+	if (card->dev->features & NETIF_F_RXCSUM) {
+		rtnl_lock();
+		/* force set_features call */
+		card->dev->features &= ~NETIF_F_RXCSUM;
+		netdev_update_features(card->dev);
+		rtnl_unlock();
 	}
-	rc = qeth_l3_send_checksum_command(card);
-	if (!rc)
-		dev_info(&card->gdev->dev,
-			"HW Checksumming (inbound) enabled\n");
-
-	return rc;
+	return 0;
 }
 
 static int qeth_l3_start_ipa_tx_checksum(struct qeth_card *card)
@@ -1580,10 +1490,8 @@
 			dev_info(&card->gdev->dev,
 				"Outbound TSO enabled\n");
 	}
-	if (rc && (card->options.large_send == QETH_LARGE_SEND_TSO)) {
-		card->options.large_send = QETH_LARGE_SEND_NO;
-		card->dev->features &= ~(NETIF_F_TSO | NETIF_F_SG);
-	}
+	if (rc)
+		card->dev->features &= ~NETIF_F_TSO;
 	return rc;
 }
 
@@ -2064,14 +1972,7 @@
 		is_vlan = 1;
 	}
 
-	switch (card->options.checksum_type) {
-	case SW_CHECKSUMMING:
-		skb->ip_summed = CHECKSUM_NONE;
-		break;
-	case NO_CHECKSUMMING:
-		skb->ip_summed = CHECKSUM_UNNECESSARY;
-		break;
-	case HW_CHECKSUMMING:
+	if (card->dev->features & NETIF_F_RXCSUM) {
 		if ((hdr->hdr.l3.ext_flags &
 		    (QETH_HDR_EXT_CSUM_HDR_REQ |
 		     QETH_HDR_EXT_CSUM_TRANSP_REQ)) ==
@@ -2080,7 +1981,8 @@
 			skb->ip_summed = CHECKSUM_UNNECESSARY;
 		else
 			skb->ip_summed = CHECKSUM_NONE;
-	}
+	} else
+		skb->ip_summed = CHECKSUM_NONE;
 
 	return is_vlan;
 }
@@ -3024,7 +2926,7 @@
 	struct qeth_qdio_out_q *queue = card->qdio.out_qs
 		[qeth_get_priority_queue(card, skb, ipv, cast_type)];
 	int tx_bytes = skb->len;
-	enum qeth_large_send_types large_send = QETH_LARGE_SEND_NO;
+	bool large_send;
 	int data_offset = -1;
 	int nr_frags;
 
@@ -3046,8 +2948,7 @@
 		card->perf_stats.outbound_start_time = qeth_get_micros();
 	}
 
-	if (skb_is_gso(skb))
-		large_send = card->options.large_send;
+	large_send = skb_is_gso(skb);
 
 	if ((card->info.type == QETH_CARD_TYPE_IQD) && (!large_send) &&
 	    (skb_shinfo(skb)->nr_frags == 0)) {
@@ -3096,7 +2997,7 @@
 	/* fix hardware limitation: as long as we do not have sbal
 	 * chaining we can not send long frag lists
 	 */
-	if (large_send == QETH_LARGE_SEND_TSO) {
+	if (large_send) {
 		if (qeth_l3_tso_elements(new_skb) + 1 > 16) {
 			if (skb_linearize(new_skb))
 				goto tx_drop;
@@ -3105,8 +3006,7 @@
 		}
 	}
 
-	if ((large_send == QETH_LARGE_SEND_TSO) &&
-	    (cast_type == RTN_UNSPEC)) {
+	if (large_send && (cast_type == RTN_UNSPEC)) {
 		hdr = (struct qeth_hdr *)skb_push(new_skb,
 						sizeof(struct qeth_hdr_tso));
 		memset(hdr, 0, sizeof(struct qeth_hdr_tso));
@@ -3141,7 +3041,7 @@
 
 	if (card->info.type != QETH_CARD_TYPE_IQD) {
 		int len;
-		if (large_send == QETH_LARGE_SEND_TSO)
+		if (large_send)
 			len = ((unsigned long)tcp_hdr(new_skb) +
 				tcp_hdr(new_skb)->doff * 4) -
 				(unsigned long)new_skb->data;
@@ -3162,7 +3062,7 @@
 		if (new_skb != skb)
 			dev_kfree_skb_any(skb);
 		if (card->options.performance_stats) {
-			if (large_send != QETH_LARGE_SEND_NO) {
+			if (large_send) {
 				card->perf_stats.large_send_bytes += tx_bytes;
 				card->perf_stats.large_send_cnt++;
 			}
@@ -3248,65 +3148,42 @@
 	return 0;
 }
 
-static u32 qeth_l3_ethtool_get_rx_csum(struct net_device *dev)
-{
-	struct qeth_card *card = dev->ml_priv;
-
-	return (card->options.checksum_type == HW_CHECKSUMMING);
-}
-
-static int qeth_l3_ethtool_set_rx_csum(struct net_device *dev, u32 data)
+static u32 qeth_l3_fix_features(struct net_device *dev, u32 features)
 {
 	struct qeth_card *card = dev->ml_priv;
-	enum qeth_checksum_types csum_type;
 
-	if (data)
-		csum_type = HW_CHECKSUMMING;
-	else
-		csum_type = SW_CHECKSUMMING;
+	if (!qeth_is_supported(card, IPA_OUTBOUND_CHECKSUM))
+		features &= ~NETIF_F_IP_CSUM;
+	if (!qeth_is_supported(card, IPA_OUTBOUND_TSO))
+		features &= ~NETIF_F_TSO;
+	if (!qeth_is_supported(card, IPA_INBOUND_CHECKSUM))
+		features &= ~NETIF_F_RXCSUM;
 
-	return qeth_l3_set_rx_csum(card, csum_type);
+	return features;
 }
 
-static int qeth_l3_ethtool_set_tso(struct net_device *dev, u32 data)
+static int qeth_l3_set_features(struct net_device *dev, u32 features)
 {
 	struct qeth_card *card = dev->ml_priv;
-	int rc = 0;
+	u32 changed = dev->features ^ features;
+	int err;
 
-	if (data) {
-		rc = qeth_l3_set_large_send(card, QETH_LARGE_SEND_TSO);
-	} else {
-		dev->features &= ~NETIF_F_TSO;
-		card->options.large_send = QETH_LARGE_SEND_NO;
-	}
-	return rc;
-}
+	if (!(changed & NETIF_F_RXCSUM))
+		return 0;
 
-static int qeth_l3_ethtool_set_tx_csum(struct net_device *dev, u32 data)
-{
-	struct qeth_card *card = dev->ml_priv;
+	if (card->state == CARD_STATE_DOWN ||
+	    card->state == CARD_STATE_RECOVER)
+		return 0;
 
-	if (data) {
-		if (qeth_is_supported(card, IPA_OUTBOUND_CHECKSUM))
-			dev->features |= NETIF_F_IP_CSUM;
-		else
-			return -EPERM;
-	} else
-		dev->features &= ~NETIF_F_IP_CSUM;
+	err = qeth_l3_set_rx_csum(card, features & NETIF_F_RXCSUM);
+	if (err)
+		dev->features = features ^ NETIF_F_RXCSUM;
 
-	return 0;
+	return err;
 }
 
 static const struct ethtool_ops qeth_l3_ethtool_ops = {
 	.get_link = ethtool_op_get_link,
-	.get_tx_csum = ethtool_op_get_tx_csum,
-	.set_tx_csum = qeth_l3_ethtool_set_tx_csum,
-	.get_rx_csum = qeth_l3_ethtool_get_rx_csum,
-	.set_rx_csum = qeth_l3_ethtool_set_rx_csum,
-	.get_sg      = ethtool_op_get_sg,
-	.set_sg      = ethtool_op_set_sg,
-	.get_tso     = ethtool_op_get_tso,
-	.set_tso     = qeth_l3_ethtool_set_tso,
 	.get_strings = qeth_core_get_strings,
 	.get_ethtool_stats = qeth_core_get_ethtool_stats,
 	.get_sset_count = qeth_core_get_sset_count,
@@ -3347,6 +3224,8 @@
 	.ndo_set_multicast_list = qeth_l3_set_multicast_list,
 	.ndo_do_ioctl	   	= qeth_l3_do_ioctl,
 	.ndo_change_mtu	   	= qeth_change_mtu,
+	.ndo_fix_features   	= qeth_l3_fix_features,
+	.ndo_set_features   	= qeth_l3_set_features,
 	.ndo_vlan_rx_register	= qeth_l3_vlan_rx_register,
 	.ndo_vlan_rx_add_vid	= qeth_l3_vlan_rx_add_vid,
 	.ndo_vlan_rx_kill_vid   = qeth_l3_vlan_rx_kill_vid,
@@ -3362,6 +3241,8 @@
 	.ndo_set_multicast_list = qeth_l3_set_multicast_list,
 	.ndo_do_ioctl	   	= qeth_l3_do_ioctl,
 	.ndo_change_mtu	   	= qeth_change_mtu,
+	.ndo_fix_features   	= qeth_l3_fix_features,
+	.ndo_set_features   	= qeth_l3_set_features,
 	.ndo_vlan_rx_register	= qeth_l3_vlan_rx_register,
 	.ndo_vlan_rx_add_vid	= qeth_l3_vlan_rx_add_vid,
 	.ndo_vlan_rx_kill_vid   = qeth_l3_vlan_rx_kill_vid,
@@ -3392,8 +3273,12 @@
 			if (!(card->info.unique_id & UNIQUE_ID_NOT_BY_CARD))
 				card->dev->dev_id = card->info.unique_id &
 							 0xffff;
-			if (!card->info.guestlan)
-				card->dev->features |= NETIF_F_GRO;
+			if (!card->info.guestlan) {
+				card->dev->hw_features = NETIF_F_SG |
+					NETIF_F_RXCSUM | NETIF_F_IP_CSUM |
+					NETIF_F_TSO;
+				card->dev->features = NETIF_F_RXCSUM;
+			}
 		}
 	} else if (card->info.type == QETH_CARD_TYPE_IQD) {
 		card->dev = alloc_netdev(0, "hsi%d", ether_setup);
@@ -3426,15 +3311,13 @@
 
 	qeth_l3_create_device_attributes(&gdev->dev);
 	card->options.layer2 = 0;
+	card->info.hwtrap = 0;
 	card->discipline.start_poll = qeth_qdio_start_poll;
 	card->discipline.input_handler = (qdio_handler_t *)
 		qeth_qdio_input_handler;
 	card->discipline.output_handler = (qdio_handler_t *)
 		qeth_qdio_output_handler;
 	card->discipline.recover = qeth_l3_recover;
-	if ((card->info.type == QETH_CARD_TYPE_OSD) ||
-	    (card->info.type == QETH_CARD_TYPE_OSX))
-		card->options.checksum_type = HW_CHECKSUMMING;
 	return 0;
 }
 
@@ -3480,13 +3363,18 @@
 		goto out_remove;
 	}
 
-	qeth_l3_query_ipassists(card, QETH_PROT_IPV4);
-
 	if (!card->dev && qeth_l3_setup_netdev(card)) {
 		rc = -ENODEV;
 		goto out_remove;
 	}
 
+	if (qeth_is_diagass_supported(card, QETH_DIAGS_CMD_TRAP)) {
+		if (card->info.hwtrap &&
+		    qeth_hw_trap(card, QETH_DIAGS_TRAP_ARM))
+			card->info.hwtrap = 0;
+	} else
+		card->info.hwtrap = 0;
+
 	card->state = CARD_STATE_HARDSETUP;
 	memset(&card->rx, 0, sizeof(struct qeth_rx));
 	qeth_print_status_message(card);
@@ -3516,7 +3404,6 @@
 		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);
@@ -3589,6 +3476,10 @@
 	if (card->dev && netif_carrier_ok(card->dev))
 		netif_carrier_off(card->dev);
 	recover_flag = card->state;
+	if ((!recovery_mode && card->info.hwtrap) || card->info.hwtrap == 2) {
+		qeth_hw_trap(card, QETH_DIAGS_TRAP_DISARM);
+		card->info.hwtrap = 1;
+	}
 	qeth_l3_stop_card(card, recovery_mode);
 	rc  = ccw_device_set_offline(CARD_DDEV(card));
 	rc2 = ccw_device_set_offline(CARD_WDEV(card));
@@ -3644,6 +3535,8 @@
 static void qeth_l3_shutdown(struct ccwgroup_device *gdev)
 {
 	struct qeth_card *card = dev_get_drvdata(&gdev->dev);
+	if ((gdev->state == CCWGROUP_ONLINE) && card->info.hwtrap)
+		qeth_hw_trap(card, QETH_DIAGS_TRAP_DISARM);
 	qeth_qdio_clear_card(card, 0);
 	qeth_clear_qdio_buffers(card);
 }
@@ -3659,6 +3552,8 @@
 	if (gdev->state == CCWGROUP_OFFLINE)
 		return 0;
 	if (card->state == CARD_STATE_UP) {
+		if (card->info.hwtrap)
+			qeth_hw_trap(card, QETH_DIAGS_TRAP_DISARM);
 		__qeth_l3_set_offline(card->gdev, 1);
 	} else
 		__qeth_l3_set_offline(card->gdev, 0);
diff -druN linux-2.6.39-libre/drivers/s390/net/qeth_l3_sys.c linux-3.0-rc7-libre/drivers/s390/net/qeth_l3_sys.c
--- linux-2.6.39-libre/drivers/s390/net/qeth_l3_sys.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/s390/net/qeth_l3_sys.c	2011-07-11 19:51:52.000000000 -0400
@@ -15,16 +15,6 @@
 #define QETH_DEVICE_ATTR(_id, _name, _mode, _show, _store) \
 struct device_attribute dev_attr_##_id = __ATTR(_name, _mode, _show, _store)
 
-static const char *qeth_l3_get_checksum_str(struct qeth_card *card)
-{
-	if (card->options.checksum_type == SW_CHECKSUMMING)
-		return "sw";
-	else if (card->options.checksum_type == HW_CHECKSUMMING)
-		return "hw";
-	else
-		return "no";
-}
-
 static ssize_t qeth_l3_dev_route_show(struct qeth_card *card,
 			struct qeth_routing_info *route, char *buf)
 {
@@ -295,51 +285,6 @@
 static DEVICE_ATTR(canonical_macaddr, 0644, qeth_l3_dev_canonical_macaddr_show,
 		   qeth_l3_dev_canonical_macaddr_store);
 
-static ssize_t qeth_l3_dev_checksum_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, "%s checksumming\n",
-			qeth_l3_get_checksum_str(card));
-}
-
-static ssize_t qeth_l3_dev_checksum_store(struct device *dev,
-		struct device_attribute *attr, const char *buf, size_t count)
-{
-	struct qeth_card *card = dev_get_drvdata(dev);
-	enum qeth_checksum_types csum_type;
-	char *tmp;
-	int rc = 0;
-
-	if (!card)
-		return -EINVAL;
-
-	mutex_lock(&card->conf_mutex);
-	tmp = strsep((char **) &buf, "\n");
-	if (!strcmp(tmp, "sw_checksumming"))
-		csum_type = SW_CHECKSUMMING;
-	else if (!strcmp(tmp, "hw_checksumming"))
-		csum_type = HW_CHECKSUMMING;
-	else if (!strcmp(tmp, "no_checksumming"))
-		csum_type = NO_CHECKSUMMING;
-	else {
-		rc = -EINVAL;
-		goto out;
-	}
-
-	rc = qeth_l3_set_rx_csum(card, csum_type);
-out:
-	mutex_unlock(&card->conf_mutex);
-	return rc ? rc : count;
-}
-
-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)
 {
@@ -402,61 +347,13 @@
 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)
-{
-	struct qeth_card *card = dev_get_drvdata(dev);
-
-	if (!card)
-		return -EINVAL;
-
-	switch (card->options.large_send) {
-	case QETH_LARGE_SEND_NO:
-		return sprintf(buf, "%s\n", "no");
-	case QETH_LARGE_SEND_TSO:
-		return sprintf(buf, "%s\n", "TSO");
-	default:
-		return sprintf(buf, "%s\n", "N/A");
-	}
-}
-
-static ssize_t qeth_l3_dev_large_send_store(struct device *dev,
-		struct device_attribute *attr, const char *buf, size_t count)
-{
-	struct qeth_card *card = dev_get_drvdata(dev);
-	enum qeth_large_send_types type;
-	int rc = 0;
-	char *tmp;
-
-	if (!card)
-		return -EINVAL;
-	tmp = strsep((char **) &buf, "\n");
-	if (!strcmp(tmp, "no"))
-		type = QETH_LARGE_SEND_NO;
-	else if (!strcmp(tmp, "TSO"))
-		type = QETH_LARGE_SEND_TSO;
-	else
-		return -EINVAL;
-
-	mutex_lock(&card->conf_mutex);
-	if (card->options.large_send != type)
-		rc = qeth_l3_set_large_send(card, type);
-	mutex_unlock(&card->conf_mutex);
-	return rc ? rc : count;
-}
-
-static DEVICE_ATTR(large_send, 0644, qeth_l3_dev_large_send_show,
-		   qeth_l3_dev_large_send_store);
-
 static struct attribute *qeth_l3_device_attrs[] = {
 	&dev_attr_route4.attr,
 	&dev_attr_route6.attr,
 	&dev_attr_fake_broadcast.attr,
 	&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 -druN linux-2.6.39-libre/drivers/s390/scsi/zfcp_fsf.c linux-3.0-rc7-libre/drivers/s390/scsi/zfcp_fsf.c
--- linux-2.6.39-libre/drivers/s390/scsi/zfcp_fsf.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/s390/scsi/zfcp_fsf.c	2011-07-11 19:51:52.000000000 -0400
@@ -640,7 +640,7 @@
 }
 
 static struct zfcp_fsf_req *zfcp_fsf_req_create(struct zfcp_qdio *qdio,
-						u32 fsf_cmd, u32 sbtype,
+						u32 fsf_cmd, u8 sbtype,
 						mempool_t *pool)
 {
 	struct zfcp_adapter *adapter = qdio->adapter;
@@ -841,7 +841,7 @@
 	if (zfcp_qdio_sbal_get(qdio))
 		goto out;
 	req = zfcp_fsf_req_create(qdio, FSF_QTCB_ABORT_FCP_CMND,
-				  SBAL_FLAGS0_TYPE_READ,
+				  SBAL_SFLAGS0_TYPE_READ,
 				  qdio->adapter->pool.scsi_abort);
 	if (IS_ERR(req)) {
 		req = NULL;
@@ -1012,7 +1012,7 @@
 		goto out;
 
 	req = zfcp_fsf_req_create(qdio, FSF_QTCB_SEND_GENERIC,
-				  SBAL_FLAGS0_TYPE_WRITE_READ, pool);
+				  SBAL_SFLAGS0_TYPE_WRITE_READ, pool);
 
 	if (IS_ERR(req)) {
 		ret = PTR_ERR(req);
@@ -1110,7 +1110,7 @@
 		goto out;
 
 	req = zfcp_fsf_req_create(qdio, FSF_QTCB_SEND_ELS,
-				  SBAL_FLAGS0_TYPE_WRITE_READ, NULL);
+				  SBAL_SFLAGS0_TYPE_WRITE_READ, NULL);
 
 	if (IS_ERR(req)) {
 		ret = PTR_ERR(req);
@@ -1156,7 +1156,7 @@
 		goto out;
 
 	req = zfcp_fsf_req_create(qdio, FSF_QTCB_EXCHANGE_CONFIG_DATA,
-				  SBAL_FLAGS0_TYPE_READ,
+				  SBAL_SFLAGS0_TYPE_READ,
 				  qdio->adapter->pool.erp_req);
 
 	if (IS_ERR(req)) {
@@ -1198,7 +1198,7 @@
 		goto out_unlock;
 
 	req = zfcp_fsf_req_create(qdio, FSF_QTCB_EXCHANGE_CONFIG_DATA,
-				  SBAL_FLAGS0_TYPE_READ, NULL);
+				  SBAL_SFLAGS0_TYPE_READ, NULL);
 
 	if (IS_ERR(req)) {
 		retval = PTR_ERR(req);
@@ -1250,7 +1250,7 @@
 		goto out;
 
 	req = zfcp_fsf_req_create(qdio, FSF_QTCB_EXCHANGE_PORT_DATA,
-				  SBAL_FLAGS0_TYPE_READ,
+				  SBAL_SFLAGS0_TYPE_READ,
 				  qdio->adapter->pool.erp_req);
 
 	if (IS_ERR(req)) {
@@ -1296,7 +1296,7 @@
 		goto out_unlock;
 
 	req = zfcp_fsf_req_create(qdio, FSF_QTCB_EXCHANGE_PORT_DATA,
-				  SBAL_FLAGS0_TYPE_READ, NULL);
+				  SBAL_SFLAGS0_TYPE_READ, NULL);
 
 	if (IS_ERR(req)) {
 		retval = PTR_ERR(req);
@@ -1412,7 +1412,7 @@
 		goto out;
 
 	req = zfcp_fsf_req_create(qdio, FSF_QTCB_OPEN_PORT_WITH_DID,
-				  SBAL_FLAGS0_TYPE_READ,
+				  SBAL_SFLAGS0_TYPE_READ,
 				  qdio->adapter->pool.erp_req);
 
 	if (IS_ERR(req)) {
@@ -1478,7 +1478,7 @@
 		goto out;
 
 	req = zfcp_fsf_req_create(qdio, FSF_QTCB_CLOSE_PORT,
-				  SBAL_FLAGS0_TYPE_READ,
+				  SBAL_SFLAGS0_TYPE_READ,
 				  qdio->adapter->pool.erp_req);
 
 	if (IS_ERR(req)) {
@@ -1553,7 +1553,7 @@
 		goto out;
 
 	req = zfcp_fsf_req_create(qdio, FSF_QTCB_OPEN_PORT_WITH_DID,
-				  SBAL_FLAGS0_TYPE_READ,
+				  SBAL_SFLAGS0_TYPE_READ,
 				  qdio->adapter->pool.erp_req);
 
 	if (IS_ERR(req)) {
@@ -1606,7 +1606,7 @@
 		goto out;
 
 	req = zfcp_fsf_req_create(qdio, FSF_QTCB_CLOSE_PORT,
-				  SBAL_FLAGS0_TYPE_READ,
+				  SBAL_SFLAGS0_TYPE_READ,
 				  qdio->adapter->pool.erp_req);
 
 	if (IS_ERR(req)) {
@@ -1698,7 +1698,7 @@
 		goto out;
 
 	req = zfcp_fsf_req_create(qdio, FSF_QTCB_CLOSE_PHYSICAL_PORT,
-				  SBAL_FLAGS0_TYPE_READ,
+				  SBAL_SFLAGS0_TYPE_READ,
 				  qdio->adapter->pool.erp_req);
 
 	if (IS_ERR(req)) {
@@ -1812,7 +1812,7 @@
 		goto out;
 
 	req = zfcp_fsf_req_create(qdio, FSF_QTCB_OPEN_LUN,
-				  SBAL_FLAGS0_TYPE_READ,
+				  SBAL_SFLAGS0_TYPE_READ,
 				  adapter->pool.erp_req);
 
 	if (IS_ERR(req)) {
@@ -1901,7 +1901,7 @@
 		goto out;
 
 	req = zfcp_fsf_req_create(qdio, FSF_QTCB_CLOSE_LUN,
-				  SBAL_FLAGS0_TYPE_READ,
+				  SBAL_SFLAGS0_TYPE_READ,
 				  qdio->adapter->pool.erp_req);
 
 	if (IS_ERR(req)) {
@@ -2161,7 +2161,7 @@
 {
 	struct zfcp_fsf_req *req;
 	struct fcp_cmnd *fcp_cmnd;
-	unsigned int sbtype = SBAL_FLAGS0_TYPE_READ;
+	u8 sbtype = SBAL_SFLAGS0_TYPE_READ;
 	int real_bytes, retval = -EIO, dix_bytes = 0;
 	struct scsi_device *sdev = scsi_cmnd->device;
 	struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(sdev);
@@ -2181,7 +2181,7 @@
 	}
 
 	if (scsi_cmnd->sc_data_direction == DMA_TO_DEVICE)
-		sbtype = SBAL_FLAGS0_TYPE_WRITE;
+		sbtype = SBAL_SFLAGS0_TYPE_WRITE;
 
 	req = zfcp_fsf_req_create(qdio, FSF_QTCB_FCP_CMND,
 				  sbtype, adapter->pool.scsi_req);
@@ -2280,7 +2280,7 @@
 		goto out;
 
 	req = zfcp_fsf_req_create(qdio, FSF_QTCB_FCP_CMND,
-				  SBAL_FLAGS0_TYPE_WRITE,
+				  SBAL_SFLAGS0_TYPE_WRITE,
 				  qdio->adapter->pool.scsi_req);
 
 	if (IS_ERR(req)) {
@@ -2328,17 +2328,18 @@
 	struct zfcp_qdio *qdio = adapter->qdio;
 	struct zfcp_fsf_req *req = NULL;
 	struct fsf_qtcb_bottom_support *bottom;
-	int direction, retval = -EIO, bytes;
+	int retval = -EIO, bytes;
+	u8 direction;
 
 	if (!(adapter->adapter_features & FSF_FEATURE_CFDC))
 		return ERR_PTR(-EOPNOTSUPP);
 
 	switch (fsf_cfdc->command) {
 	case FSF_QTCB_DOWNLOAD_CONTROL_FILE:
-		direction = SBAL_FLAGS0_TYPE_WRITE;
+		direction = SBAL_SFLAGS0_TYPE_WRITE;
 		break;
 	case FSF_QTCB_UPLOAD_CONTROL_FILE:
-		direction = SBAL_FLAGS0_TYPE_READ;
+		direction = SBAL_SFLAGS0_TYPE_READ;
 		break;
 	default:
 		return ERR_PTR(-EINVAL);
@@ -2413,7 +2414,7 @@
 		fsf_req->qdio_req.sbal_response = sbal_idx;
 		zfcp_fsf_req_complete(fsf_req);
 
-		if (likely(sbale->flags & SBAL_FLAGS_LAST_ENTRY))
+		if (likely(sbale->eflags & SBAL_EFLAGS_LAST_ENTRY))
 			break;
 	}
 }
diff -druN linux-2.6.39-libre/drivers/s390/scsi/zfcp_qdio.c linux-3.0-rc7-libre/drivers/s390/scsi/zfcp_qdio.c
--- linux-2.6.39-libre/drivers/s390/scsi/zfcp_qdio.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/s390/scsi/zfcp_qdio.c	2011-07-11 19:51:52.000000000 -0400
@@ -124,7 +124,7 @@
 
 	/* set last entry flag in current SBALE of current SBAL */
 	sbale = zfcp_qdio_sbale_curr(qdio, q_req);
-	sbale->flags |= SBAL_FLAGS_LAST_ENTRY;
+	sbale->eflags |= SBAL_EFLAGS_LAST_ENTRY;
 
 	/* don't exceed last allowed SBAL */
 	if (q_req->sbal_last == q_req->sbal_limit)
@@ -132,7 +132,7 @@
 
 	/* set chaining flag in first SBALE of current SBAL */
 	sbale = zfcp_qdio_sbale_req(qdio, q_req);
-	sbale->flags |= SBAL_FLAGS0_MORE_SBALS;
+	sbale->sflags |= SBAL_SFLAGS0_MORE_SBALS;
 
 	/* calculate index of next SBAL */
 	q_req->sbal_last++;
@@ -147,7 +147,7 @@
 
 	/* set storage-block type for new SBAL */
 	sbale = zfcp_qdio_sbale_curr(qdio, q_req);
-	sbale->flags |= q_req->sbtype;
+	sbale->sflags |= q_req->sbtype;
 
 	return sbale;
 }
@@ -177,7 +177,7 @@
 
 	/* set storage-block type for this request */
 	sbale = zfcp_qdio_sbale_req(qdio, q_req);
-	sbale->flags |= q_req->sbtype;
+	sbale->sflags |= q_req->sbtype;
 
 	for (; sg; sg = sg_next(sg)) {
 		sbale = zfcp_qdio_sbale_next(qdio, q_req);
@@ -384,7 +384,8 @@
 	for (cc = 0; cc < QDIO_MAX_BUFFERS_PER_Q; cc++) {
 		sbale = &(qdio->res_q[cc]->element[0]);
 		sbale->length = 0;
-		sbale->flags = SBAL_FLAGS_LAST_ENTRY;
+		sbale->eflags = SBAL_EFLAGS_LAST_ENTRY;
+		sbale->sflags = 0;
 		sbale->addr = NULL;
 	}
 
diff -druN linux-2.6.39-libre/drivers/s390/scsi/zfcp_qdio.h linux-3.0-rc7-libre/drivers/s390/scsi/zfcp_qdio.h
--- linux-2.6.39-libre/drivers/s390/scsi/zfcp_qdio.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/s390/scsi/zfcp_qdio.h	2011-07-11 19:51:52.000000000 -0400
@@ -67,7 +67,7 @@
  * @qdio_outb_usage: usage of outbound queue
  */
 struct zfcp_qdio_req {
-	u32	sbtype;
+	u8	sbtype;
 	u8	sbal_number;
 	u8	sbal_first;
 	u8	sbal_last;
@@ -116,7 +116,7 @@
  */
 static inline
 void zfcp_qdio_req_init(struct zfcp_qdio *qdio, struct zfcp_qdio_req *q_req,
-			unsigned long req_id, u32 sbtype, void *data, u32 len)
+			unsigned long req_id, u8 sbtype, void *data, u32 len)
 {
 	struct qdio_buffer_element *sbale;
 	int count = min(atomic_read(&qdio->req_q_free),
@@ -131,7 +131,8 @@
 
 	sbale = zfcp_qdio_sbale_req(qdio, q_req);
 	sbale->addr = (void *) req_id;
-	sbale->flags = SBAL_FLAGS0_COMMAND | sbtype;
+	sbale->eflags = 0;
+	sbale->sflags = SBAL_SFLAGS0_COMMAND | sbtype;
 
 	if (unlikely(!data))
 		return;
@@ -173,7 +174,7 @@
 	struct qdio_buffer_element *sbale;
 
 	sbale = zfcp_qdio_sbale_curr(qdio, q_req);
-	sbale->flags |= SBAL_FLAGS_LAST_ENTRY;
+	sbale->eflags |= SBAL_EFLAGS_LAST_ENTRY;
 }
 
 /**
diff -druN linux-2.6.39-libre/drivers/scsi/aacraid/linit.c linux-3.0-rc7-libre/drivers/scsi/aacraid/linit.c
--- linux-2.6.39-libre/drivers/scsi/aacraid/linit.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/scsi/aacraid/linit.c	2011-07-11 19:51:52.000000000 -0400
@@ -59,7 +59,6 @@
 #ifndef AAC_DRIVER_BRANCH
 #define AAC_DRIVER_BRANCH		""
 #endif
-#define AAC_DRIVER_BUILD_DATE		__DATE__ " " __TIME__
 #define AAC_DRIVERNAME			"aacraid"
 
 #ifdef AAC_DRIVER_BUILD
@@ -67,7 +66,7 @@
 #define str(x) _str(x)
 #define AAC_DRIVER_FULL_VERSION	AAC_DRIVER_VERSION "[" str(AAC_DRIVER_BUILD) "]" AAC_DRIVER_BRANCH
 #else
-#define AAC_DRIVER_FULL_VERSION	AAC_DRIVER_VERSION AAC_DRIVER_BRANCH " " AAC_DRIVER_BUILD_DATE
+#define AAC_DRIVER_FULL_VERSION	AAC_DRIVER_VERSION AAC_DRIVER_BRANCH
 #endif
 
 MODULE_AUTHOR("Red Hat Inc and Adaptec");
diff -druN linux-2.6.39-libre/drivers/scsi/aic7xxx/aicasm/aicasm_symbol.c linux-3.0-rc7-libre/drivers/scsi/aic7xxx/aicasm/aicasm_symbol.c
--- linux-2.6.39-libre/drivers/scsi/aic7xxx/aicasm/aicasm_symbol.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/scsi/aic7xxx/aicasm/aicasm_symbol.c	2011-07-11 19:51:52.000000000 -0400
@@ -1,5 +1,5 @@
 /*
- * Aic7xxx SCSI host adapter firmware asssembler symbol table implementation
+ * Aic7xxx SCSI host adapter firmware assembler symbol table implementation
  *
  * Copyright (c) 1997 Justin T. Gibbs.
  * Copyright (c) 2002 Adaptec Inc.
diff -druN linux-2.6.39-libre/drivers/scsi/aic7xxx/aicasm/aicasm_symbol.h linux-3.0-rc7-libre/drivers/scsi/aic7xxx/aicasm/aicasm_symbol.h
--- linux-2.6.39-libre/drivers/scsi/aic7xxx/aicasm/aicasm_symbol.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/scsi/aic7xxx/aicasm/aicasm_symbol.h	2011-07-11 19:51:52.000000000 -0400
@@ -1,5 +1,5 @@
 /*
- * Aic7xxx SCSI host adapter firmware asssembler symbol table definitions
+ * Aic7xxx SCSI host adapter firmware assembler symbol table definitions
  *
  * Copyright (c) 1997 Justin T. Gibbs.
  * Copyright (c) 2002 Adaptec Inc.
diff -druN linux-2.6.39-libre/drivers/scsi/aic94xx/aic94xx_init.c linux-3.0-rc7-libre/drivers/scsi/aic94xx/aic94xx_init.c
--- linux-2.6.39-libre/drivers/scsi/aic94xx/aic94xx_init.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/scsi/aic94xx/aic94xx_init.c	2011-07-11 19:51:52.000000000 -0400
@@ -486,7 +486,7 @@
 			flash_error_table[i].reason);
 }
 
-static DEVICE_ATTR(update_bios, S_IRUGO|S_IWUGO,
+static DEVICE_ATTR(update_bios, S_IRUGO|S_IWUSR,
 	asd_show_update_bios, asd_store_update_bios);
 
 static int asd_create_dev_attrs(struct asd_ha_struct *asd_ha)
diff -druN linux-2.6.39-libre/drivers/scsi/arcmsr/arcmsr_hba.c linux-3.0-rc7-libre/drivers/scsi/arcmsr/arcmsr_hba.c
--- linux-2.6.39-libre/drivers/scsi/arcmsr/arcmsr_hba.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/scsi/arcmsr/arcmsr_hba.c	2011-07-11 19:51:52.000000000 -0400
@@ -75,8 +75,10 @@
 MODULE_DESCRIPTION("ARECA (ARC11xx/12xx/16xx/1880) SATA/SAS RAID Host Bus Adapter");
 MODULE_LICENSE("Dual BSD/GPL");
 MODULE_VERSION(ARCMSR_DRIVER_VERSION);
-static int sleeptime = 10;
-static int retrycount = 12;
+
+#define	ARCMSR_SLEEPTIME	10
+#define	ARCMSR_RETRYCOUNT	12
+
 wait_queue_head_t wait_q;
 static int arcmsr_iop_message_xfer(struct AdapterControlBlock *acb,
 					struct scsi_cmnd *cmd);
@@ -171,24 +173,6 @@
 ****************************************************************************
 ****************************************************************************
 */
-int arcmsr_sleep_for_bus_reset(struct scsi_cmnd *cmd)
-{
-		struct Scsi_Host *shost = NULL;
-		int i, isleep;
-		shost = cmd->device->host;
-		isleep = sleeptime / 10;
-		if (isleep > 0) {
-			for (i = 0; i < isleep; i++) {
-				msleep(10000);
-			}
-		}
-
-		isleep = sleeptime % 10;
-		if (isleep > 0) {
-			msleep(isleep*1000);
-		}
-		return 0;
-}
 
 static void arcmsr_free_hbb_mu(struct AdapterControlBlock *acb)
 {
@@ -323,66 +307,64 @@
 
 	default: acb->adapter_type = ACB_ADAPTER_TYPE_A;
 	}
-}	
+}
 
 static uint8_t arcmsr_hba_wait_msgint_ready(struct AdapterControlBlock *acb)
 {
 	struct MessageUnit_A __iomem *reg = acb->pmuA;
-	uint32_t Index;
-	uint8_t Retries = 0x00;
-	do {
-		for (Index = 0; Index < 100; Index++) {
-			if (readl(&reg->outbound_intstatus) &
-					ARCMSR_MU_OUTBOUND_MESSAGE0_INT) {
-				writel(ARCMSR_MU_OUTBOUND_MESSAGE0_INT,
-					&reg->outbound_intstatus);
-				return true;
-			}
-			msleep(10);
-		}/*max 1 seconds*/
+	int i;
+
+	for (i = 0; i < 2000; i++) {
+		if (readl(&reg->outbound_intstatus) &
+				ARCMSR_MU_OUTBOUND_MESSAGE0_INT) {
+			writel(ARCMSR_MU_OUTBOUND_MESSAGE0_INT,
+				&reg->outbound_intstatus);
+			return true;
+		}
+		msleep(10);
+	} /* max 20 seconds */
 
-	} while (Retries++ < 20);/*max 20 sec*/
 	return false;
 }
 
 static uint8_t arcmsr_hbb_wait_msgint_ready(struct AdapterControlBlock *acb)
 {
 	struct MessageUnit_B *reg = acb->pmuB;
-	uint32_t Index;
-	uint8_t Retries = 0x00;
-	do {
-		for (Index = 0; Index < 100; Index++) {
-			if (readl(reg->iop2drv_doorbell)
-				& ARCMSR_IOP2DRV_MESSAGE_CMD_DONE) {
-				writel(ARCMSR_MESSAGE_INT_CLEAR_PATTERN
-					, reg->iop2drv_doorbell);
-				writel(ARCMSR_DRV2IOP_END_OF_INTERRUPT, reg->drv2iop_doorbell);
-				return true;
-			}
-			msleep(10);
-		}/*max 1 seconds*/
+	int i;
+
+	for (i = 0; i < 2000; i++) {
+		if (readl(reg->iop2drv_doorbell)
+			& ARCMSR_IOP2DRV_MESSAGE_CMD_DONE) {
+			writel(ARCMSR_MESSAGE_INT_CLEAR_PATTERN,
+					reg->iop2drv_doorbell);
+			writel(ARCMSR_DRV2IOP_END_OF_INTERRUPT,
+					reg->drv2iop_doorbell);
+			return true;
+		}
+		msleep(10);
+	} /* max 20 seconds */
 
-	} while (Retries++ < 20);/*max 20 sec*/
 	return false;
 }
 
 static uint8_t arcmsr_hbc_wait_msgint_ready(struct AdapterControlBlock *pACB)
 {
 	struct MessageUnit_C *phbcmu = (struct MessageUnit_C *)pACB->pmuC;
-	unsigned char Retries = 0x00;
-	uint32_t Index;
-	do {
-		for (Index = 0; Index < 100; Index++) {
-			if (readl(&phbcmu->outbound_doorbell) & ARCMSR_HBCMU_IOP2DRV_MESSAGE_CMD_DONE) {
-				writel(ARCMSR_HBCMU_IOP2DRV_MESSAGE_CMD_DONE_DOORBELL_CLEAR, &phbcmu->outbound_doorbell_clear);/*clear interrupt*/
-				return true;
-			}
-			/* one us delay	*/
-			msleep(10);
-		} /*max 1 seconds*/
-	} while (Retries++ < 20); /*max 20 sec*/
+	int i;
+
+	for (i = 0; i < 2000; i++) {
+		if (readl(&phbcmu->outbound_doorbell)
+				& ARCMSR_HBCMU_IOP2DRV_MESSAGE_CMD_DONE) {
+			writel(ARCMSR_HBCMU_IOP2DRV_MESSAGE_CMD_DONE_DOORBELL_CLEAR,
+				&phbcmu->outbound_doorbell_clear); /*clear interrupt*/
+			return true;
+		}
+		msleep(10);
+	} /* max 20 seconds */
+
 	return false;
 }
+
 static void arcmsr_flush_hba_cache(struct AdapterControlBlock *acb)
 {
 	struct MessageUnit_A __iomem *reg = acb->pmuA;
@@ -459,10 +441,11 @@
 	struct CommandControlBlock *ccb_tmp;
 	int i = 0, j = 0;
 	dma_addr_t cdb_phyaddr;
-	unsigned long roundup_ccbsize = 0, offset;
+	unsigned long roundup_ccbsize;
 	unsigned long max_xfer_len;
 	unsigned long max_sg_entrys;
 	uint32_t  firm_config_version;
+
 	for (i = 0; i < ARCMSR_MAX_TARGETID; i++)
 		for (j = 0; j < ARCMSR_MAX_TARGETLUN; j++)
 			acb->devstate[i][j] = ARECA_RAID_GONE;
@@ -472,23 +455,20 @@
 	firm_config_version = acb->firm_cfg_version;
 	if((firm_config_version & 0xFF) >= 3){
 		max_xfer_len = (ARCMSR_CDB_SG_PAGE_LENGTH << ((firm_config_version >> 8) & 0xFF)) * 1024;/* max 4M byte */
-		max_sg_entrys = (max_xfer_len/4096);	
+		max_sg_entrys = (max_xfer_len/4096);
 	}
 	acb->host->max_sectors = max_xfer_len/512;
 	acb->host->sg_tablesize = max_sg_entrys;
 	roundup_ccbsize = roundup(sizeof(struct CommandControlBlock) + (max_sg_entrys - 1) * sizeof(struct SG64ENTRY), 32);
-	acb->uncache_size = roundup_ccbsize * ARCMSR_MAX_FREECCB_NUM + 32;
+	acb->uncache_size = roundup_ccbsize * ARCMSR_MAX_FREECCB_NUM;
 	dma_coherent = dma_alloc_coherent(&pdev->dev, acb->uncache_size, &dma_coherent_handle, GFP_KERNEL);
 	if(!dma_coherent){
-		printk(KERN_NOTICE "arcmsr%d: dma_alloc_coherent got error \n", acb->host->host_no);
+		printk(KERN_NOTICE "arcmsr%d: dma_alloc_coherent got error\n", acb->host->host_no);
 		return -ENOMEM;
 	}
 	acb->dma_coherent = dma_coherent;
 	acb->dma_coherent_handle = dma_coherent_handle;
 	memset(dma_coherent, 0, acb->uncache_size);
-	offset = roundup((unsigned long)dma_coherent, 32) - (unsigned long)dma_coherent;
-	dma_coherent_handle = dma_coherent_handle + offset;
-	dma_coherent = (struct CommandControlBlock *)dma_coherent + offset;
 	ccb_tmp = dma_coherent;
 	acb->vir2phy_offset = (unsigned long)dma_coherent - (unsigned long)dma_coherent_handle;
 	for(i = 0; i < ARCMSR_MAX_FREECCB_NUM; i++){
@@ -2602,12 +2582,8 @@
 		if (cdb_phyaddr_hi32 != 0) {
 			struct MessageUnit_C *reg = (struct MessageUnit_C *)acb->pmuC;
 
-			if (cdb_phyaddr_hi32 != 0) {
-				unsigned char Retries = 0x00;
-				do {
-					printk(KERN_NOTICE "arcmsr%d: cdb_phyaddr_hi32=0x%x \n", acb->adapter_index, cdb_phyaddr_hi32);
-				} while (Retries++ < 100);
-			}
+			printk(KERN_NOTICE "arcmsr%d: cdb_phyaddr_hi32=0x%x\n",
+					acb->adapter_index, cdb_phyaddr_hi32);
 			writel(ARCMSR_SIGNATURE_SET_CONFIG, &reg->msgcode_rwbuffer[0]);
 			writel(cdb_phyaddr_hi32, &reg->msgcode_rwbuffer[1]);
 			writel(ARCMSR_INBOUND_MESG0_SET_CONFIG, &reg->inbound_msgaddr0);
@@ -2955,12 +2931,12 @@
 				arcmsr_hardware_reset(acb);
 				acb->acb_flags &= ~ACB_F_IOP_INITED;
 sleep_again:
-				arcmsr_sleep_for_bus_reset(cmd);
+				ssleep(ARCMSR_SLEEPTIME);
 				if ((readl(&reg->outbound_msgaddr1) & ARCMSR_OUTBOUND_MESG1_FIRMWARE_OK) == 0) {
-					printk(KERN_ERR "arcmsr%d: waiting for hw bus reset return, retry=%d \n", acb->host->host_no, retry_count);
-					if (retry_count > retrycount) {
+					printk(KERN_ERR "arcmsr%d: waiting for hw bus reset return, retry=%d\n", acb->host->host_no, retry_count);
+					if (retry_count > ARCMSR_RETRYCOUNT) {
 						acb->fw_flag = FW_DEADLOCK;
-						printk(KERN_ERR "arcmsr%d: waiting for hw bus reset return, RETRY TERMINATED!! \n", acb->host->host_no);
+						printk(KERN_ERR "arcmsr%d: waiting for hw bus reset return, RETRY TERMINATED!!\n", acb->host->host_no);
 						return FAILED;
 					}
 					retry_count++;
@@ -3025,12 +3001,12 @@
 				arcmsr_hardware_reset(acb);
 				acb->acb_flags &= ~ACB_F_IOP_INITED;
 sleep:
-				arcmsr_sleep_for_bus_reset(cmd);
+				ssleep(ARCMSR_SLEEPTIME);
 				if ((readl(&reg->host_diagnostic) & 0x04) != 0) {
-					printk(KERN_ERR "arcmsr%d: waiting for hw bus reset return, retry=%d \n", acb->host->host_no, retry_count);
-					if (retry_count > retrycount) {
+					printk(KERN_ERR "arcmsr%d: waiting for hw bus reset return, retry=%d\n", acb->host->host_no, retry_count);
+					if (retry_count > ARCMSR_RETRYCOUNT) {
 						acb->fw_flag = FW_DEADLOCK;
-						printk(KERN_ERR "arcmsr%d: waiting for hw bus reset return, RETRY TERMINATED!! \n", acb->host->host_no);
+						printk(KERN_ERR "arcmsr%d: waiting for hw bus reset return, RETRY TERMINATED!!\n", acb->host->host_no);
 						return FAILED;
 					}
 					retry_count++;
diff -druN linux-2.6.39-libre/drivers/scsi/be2iscsi/be_cmds.c linux-3.0-rc7-libre/drivers/scsi/be2iscsi/be_cmds.c
--- linux-2.6.39-libre/drivers/scsi/be2iscsi/be_cmds.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/scsi/be2iscsi/be_cmds.c	2011-07-11 19:51:52.000000000 -0400
@@ -1,5 +1,5 @@
 /**
- * Copyright (C) 2005 - 2010 ServerEngines
+ * Copyright (C) 2005 - 2011 Emulex
  * All rights reserved.
  *
  * This program is free software; you can redistribute it and/or
@@ -8,11 +8,11 @@
  * Public License is included in this distribution in the file called COPYING.
  *
  * Contact Information:
- * linux-drivers@serverengines.com
+ * linux-drivers@emulex.com
  *
- * ServerEngines
- * 209 N. Fair Oaks Ave
- * Sunnyvale, CA 94085
+ * Emulex
+ * 3333 Susan Street
+ * Costa Mesa, CA 92626
  */
 
 #include "be.h"
@@ -458,6 +458,7 @@
 	req_hdr->opcode = opcode;
 	req_hdr->subsystem = subsystem;
 	req_hdr->request_length = cpu_to_le32(cmd_len - sizeof(*req_hdr));
+	req_hdr->timeout = 120;
 }
 
 static void be_cmd_page_addrs_prepare(struct phys_addr *pages, u32 max_pages,
diff -druN linux-2.6.39-libre/drivers/scsi/be2iscsi/be_cmds.h linux-3.0-rc7-libre/drivers/scsi/be2iscsi/be_cmds.h
--- linux-2.6.39-libre/drivers/scsi/be2iscsi/be_cmds.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/scsi/be2iscsi/be_cmds.h	2011-07-11 19:51:52.000000000 -0400
@@ -1,5 +1,5 @@
 /**
- * Copyright (C) 2005 - 2010 ServerEngines
+ * Copyright (C) 2005 - 2011 Emulex
  * All rights reserved.
  *
  * This program is free software; you can redistribute it and/or
@@ -8,11 +8,11 @@
  * Public License is included in this distribution in the file called COPYING.
  *
  * Contact Information:
- * linux-drivers@serverengines.com
+ * linux-drivers@emulex.com
  *
- * ServerEngines
- * 209 N. Fair Oaks Ave
- * Sunnyvale, CA 94085
+ * Emulex
+ * 3333 Susan Street
+ * Costa Mesa, CA 92626
  */
 
 #ifndef BEISCSI_CMDS_H
diff -druN linux-2.6.39-libre/drivers/scsi/be2iscsi/be.h linux-3.0-rc7-libre/drivers/scsi/be2iscsi/be.h
--- linux-2.6.39-libre/drivers/scsi/be2iscsi/be.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/scsi/be2iscsi/be.h	2011-07-11 19:51:52.000000000 -0400
@@ -1,5 +1,5 @@
 /**
- * Copyright (C) 2005 - 2010 ServerEngines
+ * Copyright (C) 2005 - 2011 Emulex
  * All rights reserved.
  *
  * This program is free software; you can redistribute it and/or
@@ -8,11 +8,11 @@
  * Public License is included in this distribution in the file called COPYING.
  *
  * Contact Information:
- * linux-drivers@serverengines.com
+ * linux-drivers@emulex.com
  *
- * ServerEngines
- * 209 N. Fair Oaks Ave
- * Sunnyvale, CA 94085
+ * Emulex
+ * 3333 Susan Street
+ * Costa Mesa, CA 92626
  */
 
 #ifndef BEISCSI_H
diff -druN linux-2.6.39-libre/drivers/scsi/be2iscsi/be_iscsi.c linux-3.0-rc7-libre/drivers/scsi/be2iscsi/be_iscsi.c
--- linux-2.6.39-libre/drivers/scsi/be2iscsi/be_iscsi.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/scsi/be2iscsi/be_iscsi.c	2011-07-11 19:51:52.000000000 -0400
@@ -1,5 +1,5 @@
 /**
- * Copyright (C) 2005 - 2010 ServerEngines
+ * Copyright (C) 2005 - 2011 Emulex
  * All rights reserved.
  *
  * This program is free software; you can redistribute it and/or
@@ -7,15 +7,14 @@
  * as published by the Free Software Foundation.  The full GNU General
  * Public License is included in this distribution in the file called COPYING.
  *
- * Written by: Jayamohan Kallickal (jayamohank@serverengines.com)
+ * Written by: Jayamohan Kallickal (jayamohan.kallickal@emulex.com)
  *
  * Contact Information:
- * linux-drivers@serverengines.com
- *
- * ServerEngines
- * 209 N. Fair Oaks Ave
- * Sunnyvale, CA 94085
+ * linux-drivers@emulex.com
  *
+ * Emulex
+ * 3333 Susan Street
+ * Costa Mesa, CA 92626
  */
 
 #include <scsi/libiscsi.h>
diff -druN linux-2.6.39-libre/drivers/scsi/be2iscsi/be_iscsi.h linux-3.0-rc7-libre/drivers/scsi/be2iscsi/be_iscsi.h
--- linux-2.6.39-libre/drivers/scsi/be2iscsi/be_iscsi.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/scsi/be2iscsi/be_iscsi.h	2011-07-11 19:51:52.000000000 -0400
@@ -1,5 +1,5 @@
 /**
- * Copyright (C) 2005 - 2010 ServerEngines
+ * Copyright (C) 2005 - 2011 Emulex
  * All rights reserved.
  *
  * This program is free software; you can redistribute it and/or
@@ -7,15 +7,14 @@
  * as published by the Free Software Foundation.  The full GNU General
  * Public License is included in this distribution in the file called COPYING.
  *
- * Written by: Jayamohan Kallickal (jayamohank@serverengines.com)
+ * Written by: Jayamohan Kallickal (jayamohan.kallickal@emulex.com)
  *
  * Contact Information:
- * linux-drivers@serverengines.com
- *
- * ServerEngines
- * 209 N. Fair Oaks Ave
- * Sunnyvale, CA 94085
+ * linux-drivers@emulex.com
  *
+ * Emulex
+ * 3333 Susan Street
+ * Costa Mesa, CA 92626
  */
 
 #ifndef _BE_ISCSI_
diff -druN linux-2.6.39-libre/drivers/scsi/be2iscsi/be_main.c linux-3.0-rc7-libre/drivers/scsi/be2iscsi/be_main.c
--- linux-2.6.39-libre/drivers/scsi/be2iscsi/be_main.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/scsi/be2iscsi/be_main.c	2011-07-11 19:51:52.000000000 -0400
@@ -1,5 +1,5 @@
 /**
- * Copyright (C) 2005 - 2010 ServerEngines
+ * Copyright (C) 2005 - 2011 Emulex
  * All rights reserved.
  *
  * This program is free software; you can redistribute it and/or
@@ -7,16 +7,16 @@
  * as published by the Free Software Foundation.  The full GNU General
  * Public License is included in this distribution in the file called COPYING.
  *
- * Written by: Jayamohan Kallickal (jayamohank@serverengines.com)
+ * Written by: Jayamohan Kallickal (jayamohan.kallickal@emulex.com)
  *
  * Contact Information:
- * linux-drivers@serverengines.com
- *
- *  ServerEngines
- * 209 N. Fair Oaks Ave
- * Sunnyvale, CA 94085
+ * linux-drivers@emulex.com
  *
+ * Emulex
+ * 3333 Susan Street
+ * Costa Mesa, CA 92626
  */
+
 #include <linux/reboot.h>
 #include <linux/delay.h>
 #include <linux/slab.h>
@@ -420,7 +420,8 @@
 	return 0;
 
 free_kset:
-	iscsi_boot_destroy_kset(phba->boot_kset);
+	if (phba->boot_kset)
+		iscsi_boot_destroy_kset(phba->boot_kset);
 	return -ENOMEM;
 }
 
@@ -618,7 +619,7 @@
 				    + 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.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;
@@ -781,7 +782,7 @@
 	int isr;
 
 	phba = dev_id;
-	ctrl = &phba->ctrl;;
+	ctrl = &phba->ctrl;
 	isr = ioread32(ctrl->csr + CEV_ISR0_OFFSET +
 		       (PCI_FUNC(ctrl->pdev->devfn) * CEV_ISR_SIZE));
 	if (!isr)
@@ -3464,23 +3465,23 @@
 	addr = (u8 __iomem *) ((u8 __iomem *) ctrl->pcicfg +
 			PCICFG_MEMBAR_CTRL_INT_CTRL_OFFSET);
 	reg = ioread32(addr);
-	SE_DEBUG(DBG_LVL_8, "reg =x%08x\n", reg);
 
 	enabled = reg & MEMBAR_CTRL_INT_CTRL_HOSTINTR_MASK;
 	if (!enabled) {
 		reg |= MEMBAR_CTRL_INT_CTRL_HOSTINTR_MASK;
 		SE_DEBUG(DBG_LVL_8, "reg =x%08x addr=%p\n", reg, addr);
 		iowrite32(reg, addr);
-		if (!phba->msix_enabled) {
-			eq = &phwi_context->be_eq[0].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 {
-			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);
-			}
 		}
 	}
 }
@@ -4019,12 +4020,17 @@
 		hwi_write_buffer(pwrb, task);
 		break;
 	case ISCSI_OP_NOOP_OUT:
-		AMAP_SET_BITS(struct amap_iscsi_wrb, type, pwrb,
-			      INI_RD_CMD);
-		if (task->hdr->ttt == ISCSI_RESERVED_TAG)
+		if (task->hdr->ttt != ISCSI_RESERVED_TAG) {
+			AMAP_SET_BITS(struct amap_iscsi_wrb, type, pwrb,
+				      TGT_DM_CMD);
+			AMAP_SET_BITS(struct amap_iscsi_wrb, cmdsn_itt,
+				      pwrb, 0);
 			AMAP_SET_BITS(struct amap_iscsi_wrb, dmsg, pwrb, 0);
-		else
+		} 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:
@@ -4144,10 +4150,11 @@
 			    phba->ctrl.mbox_mem_alloced.size,
 			    phba->ctrl.mbox_mem_alloced.va,
 			    phba->ctrl.mbox_mem_alloced.dma);
+	if (phba->boot_kset)
+		iscsi_boot_destroy_kset(phba->boot_kset);
 	iscsi_host_remove(phba->shost);
 	pci_dev_put(phba->pcidev);
 	iscsi_host_free(phba->shost);
-	iscsi_boot_destroy_kset(phba->boot_kset);
 }
 
 static void beiscsi_msix_enable(struct beiscsi_hba *phba)
diff -druN linux-2.6.39-libre/drivers/scsi/be2iscsi/be_main.h linux-3.0-rc7-libre/drivers/scsi/be2iscsi/be_main.h
--- linux-2.6.39-libre/drivers/scsi/be2iscsi/be_main.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/scsi/be2iscsi/be_main.h	2011-07-11 19:51:52.000000000 -0400
@@ -1,5 +1,5 @@
 /**
- * Copyright (C) 2005 - 2010 ServerEngines
+ * Copyright (C) 2005 - 2011 Emulex
  * All rights reserved.
  *
  * This program is free software; you can redistribute it and/or
@@ -7,15 +7,14 @@
  * as published by the Free Software Foundation.  The full GNU General
  * Public License is included in this distribution in the file called COPYING.
  *
- * Written by: Jayamohan Kallickal (jayamohank@serverengines.com)
+ * Written by: Jayamohan Kallickal (jayamohan.kallickal@emulex.com)
  *
  * Contact Information:
- * linux-drivers@serverengines.com
- *
- * ServerEngines
- * 209 N. Fair Oaks Ave
- * Sunnyvale, CA 94085
+ * linux-drivers@emulex.com
  *
+ * Emulex
+ * 3333 Susan Street
+ * Costa Mesa, CA 92626
  */
 
 #ifndef _BEISCSI_MAIN_
@@ -35,7 +34,7 @@
 
 #include "be.h"
 #define DRV_NAME		"be2iscsi"
-#define BUILD_STR		"2.0.549.0"
+#define BUILD_STR		"2.103.298.0"
 #define BE_NAME			"ServerEngines BladeEngine2" \
 				"Linux iSCSI Driver version" BUILD_STR
 #define DRV_DESC		BE_NAME " " "Driver"
diff -druN linux-2.6.39-libre/drivers/scsi/be2iscsi/be_mgmt.c linux-3.0-rc7-libre/drivers/scsi/be2iscsi/be_mgmt.c
--- linux-2.6.39-libre/drivers/scsi/be2iscsi/be_mgmt.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/scsi/be2iscsi/be_mgmt.c	2011-07-11 19:51:52.000000000 -0400
@@ -1,5 +1,5 @@
 /**
- * Copyright (C) 2005 - 2010 ServerEngines
+ * Copyright (C) 2005 - 2011 Emulex
  * All rights reserved.
  *
  * This program is free software; you can redistribute it and/or
@@ -7,15 +7,14 @@
  * as published by the Free Software Foundation.  The full GNU General
  * Public License is included in this distribution in the file called COPYING.
  *
- * Written by: Jayamohan Kallickal (jayamohank@serverengines.com)
+ * Written by: Jayamohan Kallickal (jayamohan.kallickal@emulex.com)
  *
  * Contact Information:
- * linux-drivers@serverengines.com
- *
- * ServerEngines
- * 209 N. Fair Oaks Ave
- * Sunnyvale, CA 94085
+ * linux-drivers@emulex.com
  *
+ * Emulex
+ * 3333 Susan Street
+ * Costa Mesa, CA 92626
  */
 
 #include "be_mgmt.h"
@@ -203,8 +202,8 @@
 			   OPCODE_COMMON_ISCSI_CLEANUP, sizeof(*req));
 
 	req->chute = chute;
-	req->hdr_ring_id = 0;
-	req->data_ring_id = 0;
+	req->hdr_ring_id = cpu_to_le16(HWI_GET_DEF_HDRQ_ID(phba));
+	req->data_ring_id = cpu_to_le16(HWI_GET_DEF_BUFQ_ID(phba));
 
 	status =  be_mcc_notify_wait(phba);
 	if (status)
diff -druN linux-2.6.39-libre/drivers/scsi/be2iscsi/be_mgmt.h linux-3.0-rc7-libre/drivers/scsi/be2iscsi/be_mgmt.h
--- linux-2.6.39-libre/drivers/scsi/be2iscsi/be_mgmt.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/scsi/be2iscsi/be_mgmt.h	2011-07-11 19:51:52.000000000 -0400
@@ -1,5 +1,5 @@
 /**
- * Copyright (C) 2005 - 2010 ServerEngines
+ * Copyright (C) 2005 - 2011 Emulex
  * All rights reserved.
  *
  * This program is free software; you can redistribute it and/or
@@ -7,15 +7,14 @@
  * as published by the Free Software Foundation.  The full GNU General
  * Public License is included in this distribution in the file called COPYING.
  *
- * Written by: Jayamohan Kallickal (jayamohank@serverengines.com)
+ * Written by: Jayamohan Kallickal (jayamohan.kallickal@emulex.com)
  *
  * Contact Information:
- * linux-drivers@serverengines.com
- *
- * ServerEngines
- * 209 N. Fair Oaks Ave
- * Sunnyvale, CA 94085
+ * linux-drivers@emulex.com
  *
+ * Emulex
+ * 3333 Susan Street
+ * Costa Mesa, CA 92626
  */
 
 #ifndef _BEISCSI_MGMT_
diff -druN linux-2.6.39-libre/drivers/scsi/bfa/bfad.c linux-3.0-rc7-libre/drivers/scsi/bfa/bfad.c
--- linux-2.6.39-libre/drivers/scsi/bfa/bfad.c	2011-05-19 02:17:54.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/scsi/bfa/bfad.c	2011-07-21 06:59:51.000000000 -0400
@@ -57,9 +57,19 @@
 int		bfa_debugfs_enable = 1;
 int		msix_disable_cb = 0, msix_disable_ct = 0;
 
+/* Firmware releated */
 u32	bfi_image_ct_fc_size, bfi_image_ct_cna_size, bfi_image_cb_fc_size;
 u32     *bfi_image_ct_fc, *bfi_image_ct_cna, *bfi_image_cb_fc;
 
+#define BFAD_FW_FILE_CT_FC      "/*(DEBLOBBED)*/"
+#define BFAD_FW_FILE_CT_CNA     "/*(DEBLOBBED)*/"
+#define BFAD_FW_FILE_CB_FC      "/*(DEBLOBBED)*/"
+
+static u32 *bfad_load_fwimg(struct pci_dev *pdev);
+static void bfad_free_fwimg(void);
+static void bfad_read_firmware(struct pci_dev *pdev, u32 **bfi_image,
+		u32 *bfi_image_size, char *fw_name);
+
 static const char *msix_name_ct[] = {
 	"cpe0", "cpe1", "cpe2", "cpe3",
 	"rme0", "rme1", "rme2", "rme3",
@@ -220,6 +230,9 @@
 		if ((bfad->bfad_flags & BFAD_HAL_INIT_DONE)) {
 			bfa_sm_send_event(bfad, BFAD_E_INIT_SUCCESS);
 		} else {
+			printk(KERN_WARNING
+				"bfa %s: bfa init failed\n",
+				bfad->pci_name);
 			bfad->bfad_flags |= BFAD_HAL_INIT_FAIL;
 			bfa_sm_send_event(bfad, BFAD_E_INIT_FAILED);
 		}
@@ -989,10 +1002,6 @@
 		bfad->pport.roles |= BFA_LPORT_ROLE_FCP_IM;
 	}
 
-	/* Setup the debugfs node for this scsi_host */
-	if (bfa_debugfs_enable)
-		bfad_debugfs_init(&bfad->pport);
-
 	bfad->bfad_flags |= BFAD_CFG_PPORT_DONE;
 
 out:
@@ -1002,10 +1011,6 @@
 void
 bfad_uncfg_pport(struct bfad_s *bfad)
 {
-	/* Remove the debugfs node for this scsi_host */
-	kfree(bfad->regdata);
-	bfad_debugfs_exit(&bfad->pport);
-
 	if ((supported_fc4s & BFA_LPORT_ROLE_FCP_IM) &&
 	    (bfad->pport.roles & BFA_LPORT_ROLE_FCP_IM)) {
 		bfad_im_scsi_host_free(bfad, bfad->pport.im_port);
@@ -1387,6 +1392,10 @@
 	bfad->pport.bfad = bfad;
 	INIT_LIST_HEAD(&bfad->pbc_vport_list);
 
+	/* Setup the debugfs node for this bfad */
+	if (bfa_debugfs_enable)
+		bfad_debugfs_init(&bfad->pport);
+
 	retval = bfad_drv_init(bfad);
 	if (retval != BFA_STATUS_OK)
 		goto out_drv_init_failure;
@@ -1402,6 +1411,9 @@
 	bfa_detach(&bfad->bfa);
 	bfad_hal_mem_release(bfad);
 out_drv_init_failure:
+	/* Remove the debugfs node for this bfad */
+	kfree(bfad->regdata);
+	bfad_debugfs_exit(&bfad->pport);
 	mutex_lock(&bfad_mutex);
 	bfad_inst--;
 	list_del(&bfad->list_entry);
@@ -1443,6 +1455,10 @@
 	spin_unlock_irqrestore(&bfad->bfad_lock, flags);
 	bfad_hal_mem_release(bfad);
 
+	/* Remove the debugfs node for this bfad */
+	kfree(bfad->regdata);
+	bfad_debugfs_exit(&bfad->pport);
+
 	/* Cleaning the BFAD instance */
 	mutex_lock(&bfad_mutex);
 	bfad_inst--;
@@ -1548,7 +1564,7 @@
 }
 
 /* Firmware handling */
-u32 *
+static void
 bfad_read_firmware(struct pci_dev *pdev, u32 **bfi_image,
 		u32 *bfi_image_size, char *fw_name)
 {
@@ -1556,27 +1572,25 @@
 
 	if (reject_firmware(&fw, fw_name, &pdev->dev)) {
 		printk(KERN_ALERT "Can't locate firmware %s\n", fw_name);
-		goto error;
+		*bfi_image = NULL;
+		goto out;
 	}
 
 	*bfi_image = vmalloc(fw->size);
 	if (NULL == *bfi_image) {
 		printk(KERN_ALERT "Fail to allocate buffer for fw image "
 			"size=%x!\n", (u32) fw->size);
-		goto error;
+		goto out;
 	}
 
 	memcpy(*bfi_image, fw->data, fw->size);
 	*bfi_image_size = fw->size/sizeof(u32);
-
-	return *bfi_image;
-
-error:
-	return NULL;
+out:
+	release_firmware(fw);
 }
 
-u32 *
-bfad_get_firmware_buf(struct pci_dev *pdev)
+static u32 *
+bfad_load_fwimg(struct pci_dev *pdev)
 {
 	if (pdev->device == BFA_PCI_DEVICE_ID_CT_FC) {
 		if (bfi_image_ct_fc_size == 0)
@@ -1596,6 +1610,17 @@
 	}
 }
 
+static void
+bfad_free_fwimg(void)
+{
+	if (bfi_image_ct_fc_size && bfi_image_ct_fc)
+		vfree(bfi_image_ct_fc);
+	if (bfi_image_ct_cna_size && bfi_image_ct_cna)
+		vfree(bfi_image_ct_cna);
+	if (bfi_image_cb_fc_size && bfi_image_cb_fc)
+		vfree(bfi_image_cb_fc);
+}
+
 module_init(bfad_init);
 module_exit(bfad_exit);
 MODULE_LICENSE("GPL");
diff -druN linux-2.6.39-libre/drivers/scsi/bfa/bfad_debugfs.c linux-3.0-rc7-libre/drivers/scsi/bfa/bfad_debugfs.c
--- linux-2.6.39-libre/drivers/scsi/bfa/bfad_debugfs.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/scsi/bfa/bfad_debugfs.c	2011-07-11 19:51:52.000000000 -0400
@@ -28,10 +28,10 @@
  * mount -t debugfs none /sys/kernel/debug
  *
  * BFA Hierarchy:
- *	- bfa/host#
- * where the host number corresponds to the one under /sys/class/scsi_host/host#
+ *	- bfa/pci_dev:<pci_name>
+ * where the pci_name corresponds to the one under /sys/bus/pci/drivers/bfa
  *
- * Debugging service available per host:
+ * Debugging service available per pci_dev:
  * fwtrc:  To collect current firmware trace.
  * drvtrc: To collect current driver trace
  * fwsave: To collect last saved fw trace as a result of firmware crash.
@@ -489,11 +489,9 @@
 inline void
 bfad_debugfs_init(struct bfad_port_s *port)
 {
-	struct bfad_im_port_s *im_port = port->im_port;
-	struct bfad_s *bfad = im_port->bfad;
-	struct Scsi_Host *shost = im_port->shost;
+	struct bfad_s *bfad = port->bfad;
 	const struct bfad_debugfs_entry *file;
-	char name[16];
+	char name[64];
 	int i;
 
 	if (!bfa_debugfs_enable)
@@ -510,17 +508,15 @@
 		}
 	}
 
-	/*
-	 * Setup the host# directory for the port,
-	 * corresponds to the scsi_host num of this port.
-	 */
-	snprintf(name, sizeof(name), "host%d", shost->host_no);
+	/* Setup the pci_dev debugfs directory for the port */
+	snprintf(name, sizeof(name), "pci_dev:%s", bfad->pci_name);
 	if (!port->port_debugfs_root) {
 		port->port_debugfs_root =
 			debugfs_create_dir(name, bfa_debugfs_root);
 		if (!port->port_debugfs_root) {
 			printk(KERN_WARNING
-				"BFA host root dir creation failed\n");
+				"bfa %s: debugfs root creation failed\n",
+				bfad->pci_name);
 			goto err;
 		}
 
@@ -536,8 +532,8 @@
 							file->fops);
 			if (!bfad->bfad_dentry_files[i]) {
 				printk(KERN_WARNING
-					"BFA host%d: create %s entry failed\n",
-					shost->host_no, file->name);
+					"bfa %s: debugfs %s creation failed\n",
+					bfad->pci_name, file->name);
 				goto err;
 			}
 		}
@@ -550,8 +546,7 @@
 inline void
 bfad_debugfs_exit(struct bfad_port_s *port)
 {
-	struct bfad_im_port_s *im_port = port->im_port;
-	struct bfad_s *bfad = im_port->bfad;
+	struct bfad_s *bfad = port->bfad;
 	int i;
 
 	for (i = 0; i < ARRAY_SIZE(bfad_debugfs_files); i++) {
@@ -562,9 +557,7 @@
 	}
 
 	/*
-	 * Remove the host# directory for the port,
-	 * corresponds to the scsi_host num of this port.
-	*/
+	 * Remove the pci_dev debugfs directory for the port */
 	if (port->port_debugfs_root) {
 		debugfs_remove(port->port_debugfs_root);
 		port->port_debugfs_root = NULL;
diff -druN linux-2.6.39-libre/drivers/scsi/bfa/bfad_im.h linux-3.0-rc7-libre/drivers/scsi/bfa/bfad_im.h
--- linux-2.6.39-libre/drivers/scsi/bfa/bfad_im.h	2011-05-19 02:17:51.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/scsi/bfa/bfad_im.h	2011-07-11 19:51:52.000000000 -0400
@@ -141,29 +141,4 @@
 
 irqreturn_t bfad_intx(int irq, void *dev_id);
 
-/* Firmware releated */
-#define BFAD_FW_FILE_CT_FC      "/*(DEBLOBBED)*/"
-#define BFAD_FW_FILE_CT_CNA     "/*(DEBLOBBED)*/"
-#define BFAD_FW_FILE_CB_FC      "/*(DEBLOBBED)*/"
-
-u32 *bfad_get_firmware_buf(struct pci_dev *pdev);
-u32 *bfad_read_firmware(struct pci_dev *pdev, u32 **bfi_image,
-		u32 *bfi_image_size, char *fw_name);
-
-static inline u32 *
-bfad_load_fwimg(struct pci_dev *pdev)
-{
-	return bfad_get_firmware_buf(pdev);
-}
-
-static inline void
-bfad_free_fwimg(void)
-{
-	if (bfi_image_ct_fc_size && bfi_image_ct_fc)
-		vfree(bfi_image_ct_fc);
-	if (bfi_image_ct_cna_size && bfi_image_ct_cna)
-		vfree(bfi_image_ct_cna);
-	if (bfi_image_cb_fc_size && bfi_image_cb_fc)
-		vfree(bfi_image_cb_fc);
-}
 #endif
diff -druN linux-2.6.39-libre/drivers/scsi/bfa/bfa_ioc.c linux-3.0-rc7-libre/drivers/scsi/bfa/bfa_ioc.c
--- linux-2.6.39-libre/drivers/scsi/bfa/bfa_ioc.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/scsi/bfa/bfa_ioc.c	2011-07-11 19:51:52.000000000 -0400
@@ -56,6 +56,8 @@
 #define bfa_ioc_map_port(__ioc) ((__ioc)->ioc_hwif->ioc_map_port(__ioc))
 #define bfa_ioc_notify_fail(__ioc)              \
 			((__ioc)->ioc_hwif->ioc_notify_fail(__ioc))
+#define bfa_ioc_sync_start(__ioc)               \
+			((__ioc)->ioc_hwif->ioc_sync_start(__ioc))
 #define bfa_ioc_sync_join(__ioc)                \
 			((__ioc)->ioc_hwif->ioc_sync_join(__ioc))
 #define bfa_ioc_sync_leave(__ioc)               \
@@ -647,7 +649,7 @@
 	switch (event) {
 	case IOCPF_E_SEMLOCKED:
 		if (bfa_ioc_firmware_lock(ioc)) {
-			if (bfa_ioc_sync_complete(ioc)) {
+			if (bfa_ioc_sync_start(ioc)) {
 				iocpf->retry_count = 0;
 				bfa_ioc_sync_join(ioc);
 				bfa_fsm_set_state(iocpf, bfa_iocpf_sm_hwinit);
diff -druN linux-2.6.39-libre/drivers/scsi/bfa/bfa_ioc_cb.c linux-3.0-rc7-libre/drivers/scsi/bfa/bfa_ioc_cb.c
--- linux-2.6.39-libre/drivers/scsi/bfa/bfa_ioc_cb.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/scsi/bfa/bfa_ioc_cb.c	2011-07-11 19:51:52.000000000 -0400
@@ -32,6 +32,7 @@
 static void bfa_ioc_cb_isr_mode_set(struct bfa_ioc_s *ioc, bfa_boolean_t msix);
 static void bfa_ioc_cb_notify_fail(struct bfa_ioc_s *ioc);
 static void bfa_ioc_cb_ownership_reset(struct bfa_ioc_s *ioc);
+static bfa_boolean_t bfa_ioc_cb_sync_start(struct bfa_ioc_s *ioc);
 static void bfa_ioc_cb_sync_join(struct bfa_ioc_s *ioc);
 static void bfa_ioc_cb_sync_leave(struct bfa_ioc_s *ioc);
 static void bfa_ioc_cb_sync_ack(struct bfa_ioc_s *ioc);
@@ -53,6 +54,7 @@
 	hwif_cb.ioc_isr_mode_set = bfa_ioc_cb_isr_mode_set;
 	hwif_cb.ioc_notify_fail = bfa_ioc_cb_notify_fail;
 	hwif_cb.ioc_ownership_reset = bfa_ioc_cb_ownership_reset;
+	hwif_cb.ioc_sync_start = bfa_ioc_cb_sync_start;
 	hwif_cb.ioc_sync_join = bfa_ioc_cb_sync_join;
 	hwif_cb.ioc_sync_leave = bfa_ioc_cb_sync_leave;
 	hwif_cb.ioc_sync_ack = bfa_ioc_cb_sync_ack;
@@ -195,6 +197,15 @@
 }
 
 /*
+ * Synchronized IOC failure processing routines
+ */
+static bfa_boolean_t
+bfa_ioc_cb_sync_start(struct bfa_ioc_s *ioc)
+{
+	return bfa_ioc_cb_sync_complete(ioc);
+}
+
+/*
  * Cleanup hw semaphore and usecnt registers
  */
 static void
diff -druN linux-2.6.39-libre/drivers/scsi/bfa/bfa_ioc_ct.c linux-3.0-rc7-libre/drivers/scsi/bfa/bfa_ioc_ct.c
--- linux-2.6.39-libre/drivers/scsi/bfa/bfa_ioc_ct.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/scsi/bfa/bfa_ioc_ct.c	2011-07-11 19:51:52.000000000 -0400
@@ -41,6 +41,7 @@
 static void bfa_ioc_ct_isr_mode_set(struct bfa_ioc_s *ioc, bfa_boolean_t msix);
 static void bfa_ioc_ct_notify_fail(struct bfa_ioc_s *ioc);
 static void bfa_ioc_ct_ownership_reset(struct bfa_ioc_s *ioc);
+static bfa_boolean_t bfa_ioc_ct_sync_start(struct bfa_ioc_s *ioc);
 static void bfa_ioc_ct_sync_join(struct bfa_ioc_s *ioc);
 static void bfa_ioc_ct_sync_leave(struct bfa_ioc_s *ioc);
 static void bfa_ioc_ct_sync_ack(struct bfa_ioc_s *ioc);
@@ -62,6 +63,7 @@
 	hwif_ct.ioc_isr_mode_set = bfa_ioc_ct_isr_mode_set;
 	hwif_ct.ioc_notify_fail = bfa_ioc_ct_notify_fail;
 	hwif_ct.ioc_ownership_reset = bfa_ioc_ct_ownership_reset;
+	hwif_ct.ioc_sync_start = bfa_ioc_ct_sync_start;
 	hwif_ct.ioc_sync_join = bfa_ioc_ct_sync_join;
 	hwif_ct.ioc_sync_leave = bfa_ioc_ct_sync_leave;
 	hwif_ct.ioc_sync_ack = bfa_ioc_ct_sync_ack;
@@ -351,6 +353,30 @@
 	writel(1, ioc->ioc_regs.ioc_sem_reg);
 }
 
+static bfa_boolean_t
+bfa_ioc_ct_sync_start(struct bfa_ioc_s *ioc)
+{
+	uint32_t r32 = readl(ioc->ioc_regs.ioc_fail_sync);
+	uint32_t sync_reqd = bfa_ioc_ct_get_sync_reqd(r32);
+
+	/*
+	 * Driver load time.  If the sync required bit for this PCI fn
+	 * is set, it is due to an unclean exit by the driver for this
+	 * PCI fn in the previous incarnation. Whoever comes here first
+	 * should clean it up, no matter which PCI fn.
+	 */
+
+	if (sync_reqd & bfa_ioc_ct_sync_pos(ioc)) {
+		writel(0, ioc->ioc_regs.ioc_fail_sync);
+		writel(1, ioc->ioc_regs.ioc_usage_reg);
+		writel(BFI_IOC_UNINIT, ioc->ioc_regs.ioc_fwstate);
+		writel(BFI_IOC_UNINIT, ioc->ioc_regs.alt_ioc_fwstate);
+		return BFA_TRUE;
+	}
+
+	return bfa_ioc_ct_sync_complete(ioc);
+}
+
 /*
  * Synchronized IOC failure processing routines
  */
diff -druN linux-2.6.39-libre/drivers/scsi/bfa/bfa_ioc.h linux-3.0-rc7-libre/drivers/scsi/bfa/bfa_ioc.h
--- linux-2.6.39-libre/drivers/scsi/bfa/bfa_ioc.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/scsi/bfa/bfa_ioc.h	2011-07-11 19:51:52.000000000 -0400
@@ -263,6 +263,7 @@
 					bfa_boolean_t msix);
 	void		(*ioc_notify_fail)	(struct bfa_ioc_s *ioc);
 	void		(*ioc_ownership_reset)	(struct bfa_ioc_s *ioc);
+	bfa_boolean_t   (*ioc_sync_start)       (struct bfa_ioc_s *ioc);
 	void		(*ioc_sync_join)	(struct bfa_ioc_s *ioc);
 	void		(*ioc_sync_leave)	(struct bfa_ioc_s *ioc);
 	void		(*ioc_sync_ack)		(struct bfa_ioc_s *ioc);
diff -druN linux-2.6.39-libre/drivers/scsi/bnx2fc/bnx2fc_fcoe.c linux-3.0-rc7-libre/drivers/scsi/bnx2fc/bnx2fc_fcoe.c
--- linux-2.6.39-libre/drivers/scsi/bnx2fc/bnx2fc_fcoe.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/scsi/bnx2fc/bnx2fc_fcoe.c	2011-07-11 19:51:52.000000000 -0400
@@ -664,7 +664,7 @@
 	struct fcoe_port *port = lport_priv(lport);
 	struct bnx2fc_hba *hba = port->priv;
 	struct net_device *netdev = hba->netdev;
-	struct ethtool_cmd ecmd = { ETHTOOL_GSET };
+	struct ethtool_cmd ecmd;
 
 	if (!dev_ethtool_get_settings(netdev, &ecmd)) {
 		lport->link_supported_speeds &=
@@ -675,12 +675,15 @@
 		if (ecmd.supported & SUPPORTED_10000baseT_Full)
 			lport->link_supported_speeds |= FC_PORTSPEED_10GBIT;
 
-		if (ecmd.speed == SPEED_1000)
+		switch (ethtool_cmd_speed(&ecmd)) {
+		case SPEED_1000:
 			lport->link_speed = FC_PORTSPEED_1GBIT;
-		if (ecmd.speed == SPEED_10000)
+			break;
+		case SPEED_10000:
 			lport->link_speed = FC_PORTSPEED_10GBIT;
+			break;
+		}
 	}
-	return;
 }
 static int bnx2fc_link_ok(struct fc_lport *lport)
 {
@@ -1130,7 +1133,7 @@
 	struct net_device *phys_dev;
 
 	hba = container_of(kref, struct bnx2fc_hba, kref);
-	BNX2FC_HBA_DBG(hba->ctlr.lp, "Interface is being released\n");
+	BNX2FC_MISC_DBG("Interface is being released\n");
 
 	netdev = hba->netdev;
 	phys_dev = hba->phys_dev;
@@ -1254,20 +1257,17 @@
 static struct fc_lport *bnx2fc_if_create(struct bnx2fc_hba *hba,
 				  struct device *parent, int npiv)
 {
-	struct fc_lport		*lport = NULL;
+	struct fc_lport		*lport, *n_port;
 	struct fcoe_port	*port;
 	struct Scsi_Host	*shost;
 	struct fc_vport		*vport = dev_to_vport(parent);
 	int			rc = 0;
 
 	/* Allocate Scsi_Host structure */
-	if (!npiv) {
-		lport = libfc_host_alloc(&bnx2fc_shost_template,
-					  sizeof(struct fcoe_port));
-	} else {
-		lport = libfc_vport_create(vport,
-					   sizeof(struct fcoe_port));
-	}
+	if (!npiv)
+		lport = libfc_host_alloc(&bnx2fc_shost_template, sizeof(*port));
+	else
+		lport = libfc_vport_create(vport, sizeof(*port));
 
 	if (!lport) {
 		printk(KERN_ERR PFX "could not allocate scsi host structure\n");
@@ -1285,7 +1285,6 @@
 		goto lp_config_err;
 
 	if (npiv) {
-		vport = dev_to_vport(parent);
 		printk(KERN_ERR PFX "Setting vport names, 0x%llX 0x%llX\n",
 			vport->node_name, vport->port_name);
 		fc_set_wwnn(lport, vport->node_name);
@@ -1314,12 +1313,17 @@
 	fc_host_port_type(lport->host) = FC_PORTTYPE_UNKNOWN;
 
 	/* Allocate exchange manager */
-	if (!npiv) {
+	if (!npiv)
 		rc = bnx2fc_em_config(lport);
-		if (rc) {
-			printk(KERN_ERR PFX "Error on bnx2fc_em_config\n");
-			goto shost_err;
-		}
+	else {
+		shost = vport_to_shost(vport);
+		n_port = shost_priv(shost);
+		rc = fc_exch_mgr_list_clone(n_port, lport);
+	}
+
+	if (rc) {
+		printk(KERN_ERR PFX "Error on bnx2fc_em_config\n");
+		goto shost_err;
 	}
 
 	bnx2fc_interface_get(hba);
@@ -1352,8 +1356,6 @@
 	/* Free existing transmit skbs */
 	fcoe_clean_pending_queue(lport);
 
-	bnx2fc_interface_put(hba);
-
 	/* Free queued packets for the receive thread */
 	bnx2fc_clean_rx_queue(lport);
 
@@ -1372,6 +1374,8 @@
 
 	/* Release Scsi_Host */
 	scsi_host_put(lport->host);
+
+	bnx2fc_interface_put(hba);
 }
 
 /**
diff -druN linux-2.6.39-libre/drivers/scsi/bnx2fc/bnx2fc.h linux-3.0-rc7-libre/drivers/scsi/bnx2fc/bnx2fc.h
--- linux-2.6.39-libre/drivers/scsi/bnx2fc/bnx2fc.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/scsi/bnx2fc/bnx2fc.h	2011-07-11 19:51:52.000000000 -0400
@@ -130,7 +130,7 @@
 #define BNX2FC_TM_TIMEOUT		60	/* secs */
 #define BNX2FC_IO_TIMEOUT		20000UL	/* msecs */
 
-#define BNX2FC_WAIT_CNT			120
+#define BNX2FC_WAIT_CNT			1200
 #define BNX2FC_FW_TIMEOUT		(3 * HZ)
 #define PORT_MAX			2
 
diff -druN linux-2.6.39-libre/drivers/scsi/bnx2fc/bnx2fc_hwi.c linux-3.0-rc7-libre/drivers/scsi/bnx2fc/bnx2fc_hwi.c
--- linux-2.6.39-libre/drivers/scsi/bnx2fc/bnx2fc_hwi.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/scsi/bnx2fc/bnx2fc_hwi.c	2011-07-11 19:51:52.000000000 -0400
@@ -522,6 +522,7 @@
 	fp = fc_frame_alloc(lport, payload_len);
 	if (!fp) {
 		printk(KERN_ERR PFX "fc_frame_alloc failure\n");
+		kfree(unsol_els);
 		return;
 	}
 
@@ -547,6 +548,7 @@
 				 */
 				printk(KERN_ERR PFX "dropping ELS 0x%x\n", op);
 				kfree_skb(skb);
+				kfree(unsol_els);
 				return;
 			}
 		}
@@ -563,6 +565,7 @@
 	} else {
 		BNX2FC_HBA_DBG(lport, "fh_r_ctl = 0x%x\n", fh->fh_r_ctl);
 		kfree_skb(skb);
+		kfree(unsol_els);
 	}
 }
 
diff -druN linux-2.6.39-libre/drivers/scsi/bnx2fc/bnx2fc_io.c linux-3.0-rc7-libre/drivers/scsi/bnx2fc/bnx2fc_io.c
--- linux-2.6.39-libre/drivers/scsi/bnx2fc/bnx2fc_io.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/scsi/bnx2fc/bnx2fc_io.c	2011-07-11 19:51:52.000000000 -0400
@@ -1663,6 +1663,12 @@
 	tgt = (struct bnx2fc_rport *)&rp[1];
 
 	if (!test_bit(BNX2FC_FLAG_SESSION_READY, &tgt->flags)) {
+		if (test_bit(BNX2FC_FLAG_UPLD_REQ_COMPL, &tgt->flags))  {
+			sc_cmd->result = DID_NO_CONNECT << 16;
+			sc_cmd->scsi_done(sc_cmd);
+			return 0;
+
+		}
 		/*
 		 * Session is not offloaded yet. Let SCSI-ml retry
 		 * the command.
diff -druN linux-2.6.39-libre/drivers/scsi/bnx2i/bnx2i.h linux-3.0-rc7-libre/drivers/scsi/bnx2i/bnx2i.h
--- linux-2.6.39-libre/drivers/scsi/bnx2i/bnx2i.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/scsi/bnx2i/bnx2i.h	2011-07-11 19:51:52.000000000 -0400
@@ -66,11 +66,11 @@
 #define BD_SPLIT_SIZE			32768
 
 /* min, max & default values for SQ/RQ/CQ size, configurable via' modparam */
-#define BNX2I_SQ_WQES_MIN 		16
-#define BNX2I_570X_SQ_WQES_MAX 		128
-#define BNX2I_5770X_SQ_WQES_MAX 	512
-#define BNX2I_570X_SQ_WQES_DEFAULT 	128
-#define BNX2I_5770X_SQ_WQES_DEFAULT 	256
+#define BNX2I_SQ_WQES_MIN		16
+#define BNX2I_570X_SQ_WQES_MAX		128
+#define BNX2I_5770X_SQ_WQES_MAX		512
+#define BNX2I_570X_SQ_WQES_DEFAULT	128
+#define BNX2I_5770X_SQ_WQES_DEFAULT	128
 
 #define BNX2I_570X_CQ_WQES_MAX 		128
 #define BNX2I_5770X_CQ_WQES_MAX 	512
@@ -115,6 +115,7 @@
 #define BNX2X_MAX_CQS			8
 
 #define CNIC_ARM_CQE			1
+#define CNIC_ARM_CQE_FP			2
 #define CNIC_DISARM_CQE			0
 
 #define REG_RD(__hba, offset)				\
@@ -666,7 +667,9 @@
  *                      after HBA reset is completed by bnx2i/cnic/bnx2
  *                      modules
  * @state:              tracks offload connection state machine
- * @teardown_mode:      indicates if conn teardown is abortive or orderly
+ * @timestamp:          tracks the start time when the ep begins to connect
+ * @num_active_cmds:    tracks the number of outstanding commands for this ep
+ * @ec_shift:           the amount of shift as part of the event coal calc
  * @qp:                 QP information
  * @ids:                contains chip allocated *context id* & driver assigned
  *                      *iscsi cid*
@@ -685,6 +688,7 @@
 	u32 state;
 	unsigned long timestamp;
 	int num_active_cmds;
+	u32 ec_shift;
 
 	struct qp_info qp;
 	struct ep_handles ids;
diff -druN linux-2.6.39-libre/drivers/scsi/bnx2i/bnx2i_hwi.c linux-3.0-rc7-libre/drivers/scsi/bnx2i/bnx2i_hwi.c
--- linux-2.6.39-libre/drivers/scsi/bnx2i/bnx2i_hwi.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/scsi/bnx2i/bnx2i_hwi.c	2011-07-11 19:51:52.000000000 -0400
@@ -138,7 +138,6 @@
 	u16 next_index;
 	u32 num_active_cmds;
 
-
 	/* Coalesce CQ entries only on 10G devices */
 	if (!test_bit(BNX2I_NX2_DEV_57710, &ep->hba->cnic_dev_type))
 		return;
@@ -148,16 +147,19 @@
 	 * interrupts and other unwanted results
 	 */
 	cq_db = (struct bnx2i_5771x_cq_db *) ep->qp.cq_pgtbl_virt;
-	if (cq_db->sqn[0] && cq_db->sqn[0] != 0xFFFF)
-		return;
 
-	if (action == CNIC_ARM_CQE) {
+	if (action != CNIC_ARM_CQE_FP)
+		if (cq_db->sqn[0] && cq_db->sqn[0] != 0xFFFF)
+			return;
+
+	if (action == CNIC_ARM_CQE || action == CNIC_ARM_CQE_FP) {
 		num_active_cmds = ep->num_active_cmds;
 		if (num_active_cmds <= event_coal_min)
 			next_index = 1;
 		else
 			next_index = event_coal_min +
-				(num_active_cmds - event_coal_min) / event_coal_div;
+				     ((num_active_cmds - event_coal_min) >>
+				     ep->ec_shift);
 		if (!next_index)
 			next_index = 1;
 		cq_index = ep->qp.cqe_exp_seq_sn + next_index - 1;
@@ -1274,6 +1276,7 @@
 	iscsi_init.dummy_buffer_addr_hi =
 		(u32) ((u64) hba->dummy_buf_dma >> 32);
 
+	hba->num_ccell = hba->max_sqes >> 1;
 	hba->ctx_ccell_tasks =
 			((hba->num_ccell & 0xFFFF) | (hba->max_sqes << 16));
 	iscsi_init.num_ccells_per_conn = hba->num_ccell;
@@ -1934,7 +1937,6 @@
 			qp->cq_cons_idx++;
 		}
 	}
-	bnx2i_arm_cq_event_coalescing(bnx2i_conn->ep, CNIC_ARM_CQE);
 }
 
 /**
@@ -1948,22 +1950,23 @@
 static void bnx2i_fastpath_notification(struct bnx2i_hba *hba,
 					struct iscsi_kcqe *new_cqe_kcqe)
 {
-	struct bnx2i_conn *conn;
+	struct bnx2i_conn *bnx2i_conn;
 	u32 iscsi_cid;
 
 	iscsi_cid = new_cqe_kcqe->iscsi_conn_id;
-	conn = bnx2i_get_conn_from_id(hba, iscsi_cid);
+	bnx2i_conn = bnx2i_get_conn_from_id(hba, iscsi_cid);
 
-	if (!conn) {
+	if (!bnx2i_conn) {
 		printk(KERN_ALERT "cid #%x not valid\n", iscsi_cid);
 		return;
 	}
-	if (!conn->ep) {
+	if (!bnx2i_conn->ep) {
 		printk(KERN_ALERT "cid #%x - ep not bound\n", iscsi_cid);
 		return;
 	}
-
-	bnx2i_process_new_cqes(conn);
+	bnx2i_process_new_cqes(bnx2i_conn);
+	bnx2i_arm_cq_event_coalescing(bnx2i_conn->ep, CNIC_ARM_CQE_FP);
+	bnx2i_process_new_cqes(bnx2i_conn);
 }
 
 
diff -druN linux-2.6.39-libre/drivers/scsi/bnx2i/bnx2i_init.c linux-3.0-rc7-libre/drivers/scsi/bnx2i/bnx2i_init.c
--- linux-2.6.39-libre/drivers/scsi/bnx2i/bnx2i_init.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/scsi/bnx2i/bnx2i_init.c	2011-07-11 19:51:52.000000000 -0400
@@ -244,7 +244,7 @@
 	wait_event_interruptible_timeout(hba->eh_wait,
 					 (list_empty(&hba->ep_ofld_list) &&
 					 list_empty(&hba->ep_destroy_list)),
-					 10 * HZ);
+					 2 * HZ);
 	/* 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.
diff -druN linux-2.6.39-libre/drivers/scsi/bnx2i/bnx2i_iscsi.c linux-3.0-rc7-libre/drivers/scsi/bnx2i/bnx2i_iscsi.c
--- linux-2.6.39-libre/drivers/scsi/bnx2i/bnx2i_iscsi.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/scsi/bnx2i/bnx2i_iscsi.c	2011-07-11 19:51:52.000000000 -0400
@@ -379,6 +379,7 @@
 {
 	struct iscsi_endpoint *ep;
 	struct bnx2i_endpoint *bnx2i_ep;
+	u32 ec_div;
 
 	ep = iscsi_create_endpoint(sizeof(*bnx2i_ep));
 	if (!ep) {
@@ -393,6 +394,11 @@
 	bnx2i_ep->ep_iscsi_cid = (u16) -1;
 	bnx2i_ep->hba = hba;
 	bnx2i_ep->hba_age = hba->age;
+
+	ec_div = event_coal_div;
+	while (ec_div >>= 1)
+		bnx2i_ep->ec_shift += 1;
+
 	hba->ofld_conns_active++;
 	init_waitqueue_head(&bnx2i_ep->ofld_wait);
 	return ep;
@@ -858,7 +864,7 @@
 	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 = 20 * HZ;
+		hba->hba_shutdown_tmo = 30 * HZ;
 		hba->conn_teardown_tmo = 20 * HZ;
 		hba->conn_ctx_destroy_tmo = 6 * HZ;
 	} else {	/* 5706/5708/5709 */
@@ -1208,6 +1214,9 @@
 	struct bnx2i_cmd *cmd = task->dd_data;
 	struct iscsi_cmd *hdr = (struct iscsi_cmd *) task->hdr;
 
+	if (bnx2i_conn->ep->num_active_cmds + 1 > hba->max_sqes)
+		return -ENOMEM;
+
 	/*
 	 * If there is no scsi_cmnd this must be a mgmt task
 	 */
@@ -2156,7 +2165,7 @@
 	.change_queue_depth	= iscsi_change_queue_depth,
 	.can_queue		= 1024,
 	.max_sectors		= 127,
-	.cmd_per_lun		= 32,
+	.cmd_per_lun		= 24,
 	.this_id		= -1,
 	.use_clustering		= ENABLE_CLUSTERING,
 	.sg_tablesize		= ISCSI_MAX_BDS_PER_CMD,
diff -druN linux-2.6.39-libre/drivers/scsi/constants.c linux-3.0-rc7-libre/drivers/scsi/constants.c
--- linux-2.6.39-libre/drivers/scsi/constants.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/scsi/constants.c	2011-07-11 19:51:52.000000000 -0400
@@ -34,7 +34,7 @@
 static const char * cdb_byte0_names[] = {
 /* 00-03 */ "Test Unit Ready", "Rezero Unit/Rewind", NULL, "Request Sense",
 /* 04-07 */ "Format Unit/Medium", "Read Block Limits", NULL,
-	    "Reasssign Blocks",
+	    "Reassign Blocks",
 /* 08-0d */ "Read(6)", NULL, "Write(6)", "Seek(6)", NULL, NULL,
 /* 0e-12 */ NULL, "Read Reverse", "Write Filemarks", "Space", "Inquiry",  
 /* 13-16 */ "Verify(6)", "Recover Buffered Data", "Mode Select(6)",
@@ -772,6 +772,7 @@
 	{0x3802, "Esn - power management class event"},
 	{0x3804, "Esn - media class event"},
 	{0x3806, "Esn - device busy class event"},
+	{0x3807, "Thin Provisioning soft threshold reached"},
 
 	{0x3900, "Saving parameters not supported"},
 
diff -druN linux-2.6.39-libre/drivers/scsi/cxgbi/libcxgbi.c linux-3.0-rc7-libre/drivers/scsi/cxgbi/libcxgbi.c
--- linux-2.6.39-libre/drivers/scsi/cxgbi/libcxgbi.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/scsi/cxgbi/libcxgbi.c	2011-07-11 19:51:52.000000000 -0400
@@ -450,12 +450,13 @@
 	return csk;
 }
 
-static struct rtable *find_route_ipv4(__be32 saddr, __be32 daddr,
+static struct rtable *find_route_ipv4(struct flowi4 *fl4,
+				      __be32 saddr, __be32 daddr,
 				      __be16 sport, __be16 dport, u8 tos)
 {
 	struct rtable *rt;
 
-	rt = ip_route_output_ports(&init_net, NULL, daddr, saddr,
+	rt = ip_route_output_ports(&init_net, fl4, NULL, daddr, saddr,
 				   dport, sport, IPPROTO_TCP, tos, 0);
 	if (IS_ERR(rt))
 		return NULL;
@@ -470,6 +471,7 @@
 	struct net_device *ndev;
 	struct cxgbi_device *cdev;
 	struct rtable *rt = NULL;
+	struct flowi4 fl4;
 	struct cxgbi_sock *csk = NULL;
 	unsigned int mtu = 0;
 	int port = 0xFFFF;
@@ -482,7 +484,7 @@
 		goto err_out;
 	}
 
-	rt = find_route_ipv4(0, daddr->sin_addr.s_addr, 0, daddr->sin_port, 0);
+	rt = find_route_ipv4(&fl4, 0, daddr->sin_addr.s_addr, 0, daddr->sin_port, 0);
 	if (!rt) {
 		pr_info("no route to ipv4 0x%x, port %u.\n",
 			daddr->sin_addr.s_addr, daddr->sin_port);
@@ -531,7 +533,7 @@
 	csk->daddr.sin_addr.s_addr = daddr->sin_addr.s_addr;
 	csk->daddr.sin_port = daddr->sin_port;
 	csk->daddr.sin_family = daddr->sin_family;
-	csk->saddr.sin_addr.s_addr = rt->rt_src;
+	csk->saddr.sin_addr.s_addr = fl4.saddr;
 
 	return csk;
 
diff -druN linux-2.6.39-libre/drivers/scsi/dc395x.c linux-3.0-rc7-libre/drivers/scsi/dc395x.c
--- linux-2.6.39-libre/drivers/scsi/dc395x.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/scsi/dc395x.c	2011-07-11 19:51:52.000000000 -0400
@@ -778,8 +778,8 @@
 static void srb_waiting_insert(struct DeviceCtlBlk *dcb,
 		struct ScsiReqBlk *srb)
 {
-	dprintkdbg(DBG_0, "srb_waiting_insert: (pid#%li) <%02i-%i> srb=%p\n",
-		srb->cmd->serial_number, dcb->target_id, dcb->target_lun, srb);
+	dprintkdbg(DBG_0, "srb_waiting_insert: (0x%p) <%02i-%i> srb=%p\n",
+		srb->cmd, dcb->target_id, dcb->target_lun, srb);
 	list_add(&srb->list, &dcb->srb_waiting_list);
 }
 
@@ -787,16 +787,16 @@
 static void srb_waiting_append(struct DeviceCtlBlk *dcb,
 		struct ScsiReqBlk *srb)
 {
-	dprintkdbg(DBG_0, "srb_waiting_append: (pid#%li) <%02i-%i> srb=%p\n",
-		 srb->cmd->serial_number, dcb->target_id, dcb->target_lun, srb);
+	dprintkdbg(DBG_0, "srb_waiting_append: (0x%p) <%02i-%i> srb=%p\n",
+		 srb->cmd, dcb->target_id, dcb->target_lun, srb);
 	list_add_tail(&srb->list, &dcb->srb_waiting_list);
 }
 
 
 static void srb_going_append(struct DeviceCtlBlk *dcb, struct ScsiReqBlk *srb)
 {
-	dprintkdbg(DBG_0, "srb_going_append: (pid#%li) <%02i-%i> srb=%p\n",
-		srb->cmd->serial_number, dcb->target_id, dcb->target_lun, srb);
+	dprintkdbg(DBG_0, "srb_going_append: (0x%p) <%02i-%i> srb=%p\n",
+		srb->cmd, dcb->target_id, dcb->target_lun, srb);
 	list_add_tail(&srb->list, &dcb->srb_going_list);
 }
 
@@ -805,8 +805,8 @@
 {
 	struct ScsiReqBlk *i;
 	struct ScsiReqBlk *tmp;
-	dprintkdbg(DBG_0, "srb_going_remove: (pid#%li) <%02i-%i> srb=%p\n",
-		srb->cmd->serial_number, dcb->target_id, dcb->target_lun, srb);
+	dprintkdbg(DBG_0, "srb_going_remove: (0x%p) <%02i-%i> srb=%p\n",
+		srb->cmd, dcb->target_id, dcb->target_lun, srb);
 
 	list_for_each_entry_safe(i, tmp, &dcb->srb_going_list, list)
 		if (i == srb) {
@@ -821,8 +821,8 @@
 {
 	struct ScsiReqBlk *i;
 	struct ScsiReqBlk *tmp;
-	dprintkdbg(DBG_0, "srb_waiting_remove: (pid#%li) <%02i-%i> srb=%p\n",
-		srb->cmd->serial_number, dcb->target_id, dcb->target_lun, srb);
+	dprintkdbg(DBG_0, "srb_waiting_remove: (0x%p) <%02i-%i> srb=%p\n",
+		srb->cmd, dcb->target_id, dcb->target_lun, srb);
 
 	list_for_each_entry_safe(i, tmp, &dcb->srb_waiting_list, list)
 		if (i == srb) {
@@ -836,8 +836,8 @@
 		struct ScsiReqBlk *srb)
 {
 	dprintkdbg(DBG_0,
-		"srb_going_to_waiting_move: (pid#%li) <%02i-%i> srb=%p\n",
-		srb->cmd->serial_number, dcb->target_id, dcb->target_lun, srb);
+		"srb_going_to_waiting_move: (0x%p) <%02i-%i> srb=%p\n",
+		srb->cmd, dcb->target_id, dcb->target_lun, srb);
 	list_move(&srb->list, &dcb->srb_waiting_list);
 }
 
@@ -846,8 +846,8 @@
 		struct ScsiReqBlk *srb)
 {
 	dprintkdbg(DBG_0,
-		"srb_waiting_to_going_move: (pid#%li) <%02i-%i> srb=%p\n",
-		srb->cmd->serial_number, dcb->target_id, dcb->target_lun, srb);
+		"srb_waiting_to_going_move: (0x%p) <%02i-%i> srb=%p\n",
+		srb->cmd, dcb->target_id, dcb->target_lun, srb);
 	list_move(&srb->list, &dcb->srb_going_list);
 }
 
@@ -982,8 +982,8 @@
 {
 	int nseg;
 	enum dma_data_direction dir = cmd->sc_data_direction;
-	dprintkdbg(DBG_0, "build_srb: (pid#%li) <%02i-%i>\n",
-		cmd->serial_number, dcb->target_id, dcb->target_lun);
+	dprintkdbg(DBG_0, "build_srb: (0x%p) <%02i-%i>\n",
+		cmd, dcb->target_id, dcb->target_lun);
 
 	srb->dcb = dcb;
 	srb->cmd = cmd;
@@ -1086,8 +1086,8 @@
 	struct ScsiReqBlk *srb;
 	struct AdapterCtlBlk *acb =
 	    (struct AdapterCtlBlk *)cmd->device->host->hostdata;
-	dprintkdbg(DBG_0, "queue_command: (pid#%li) <%02i-%i> cmnd=0x%02x\n",
-		cmd->serial_number, cmd->device->id, cmd->device->lun, cmd->cmnd[0]);
+	dprintkdbg(DBG_0, "queue_command: (0x%p) <%02i-%i> cmnd=0x%02x\n",
+		cmd, cmd->device->id, cmd->device->lun, cmd->cmnd[0]);
 
 	/* Assume BAD_TARGET; will be cleared later */
 	cmd->result = DID_BAD_TARGET << 16;
@@ -1140,7 +1140,7 @@
 		/* process immediately */
 		send_srb(acb, srb);
 	}
-	dprintkdbg(DBG_1, "queue_command: (pid#%li) done\n", cmd->serial_number);
+	dprintkdbg(DBG_1, "queue_command: (0x%p) done\n", cmd);
 	return 0;
 
 complete:
@@ -1203,9 +1203,9 @@
 			dprintkl(KERN_INFO, "dump: srb=%p cmd=%p OOOPS!\n",
 				srb, srb->cmd);
 		else
-			dprintkl(KERN_INFO, "dump: srb=%p cmd=%p (pid#%li) "
+			dprintkl(KERN_INFO, "dump: srb=%p cmd=%p "
 				 "cmnd=0x%02x <%02i-%i>\n",
-				srb, srb->cmd, srb->cmd->serial_number,
+				srb, srb->cmd,
 				srb->cmd->cmnd[0], srb->cmd->device->id,
 			       	srb->cmd->device->lun);
 		printk("  sglist=%p cnt=%i idx=%i len=%zu\n",
@@ -1301,8 +1301,8 @@
 	struct AdapterCtlBlk *acb =
 		(struct AdapterCtlBlk *)cmd->device->host->hostdata;
 	dprintkl(KERN_INFO,
-		"eh_bus_reset: (pid#%li) target=<%02i-%i> cmd=%p\n",
-		cmd->serial_number, cmd->device->id, cmd->device->lun, cmd);
+		"eh_bus_reset: (0%p) target=<%02i-%i> cmd=%p\n",
+		cmd, cmd->device->id, cmd->device->lun, cmd);
 
 	if (timer_pending(&acb->waiting_timer))
 		del_timer(&acb->waiting_timer);
@@ -1368,8 +1368,8 @@
 	    (struct AdapterCtlBlk *)cmd->device->host->hostdata;
 	struct DeviceCtlBlk *dcb;
 	struct ScsiReqBlk *srb;
-	dprintkl(KERN_INFO, "eh_abort: (pid#%li) target=<%02i-%i> cmd=%p\n",
-		cmd->serial_number, cmd->device->id, cmd->device->lun, cmd);
+	dprintkl(KERN_INFO, "eh_abort: (0x%p) target=<%02i-%i> cmd=%p\n",
+		cmd, cmd->device->id, cmd->device->lun, cmd);
 
 	dcb = find_dcb(acb, cmd->device->id, cmd->device->lun);
 	if (!dcb) {
@@ -1495,8 +1495,8 @@
 	u16 s_stat2, return_code;
 	u8 s_stat, scsicommand, i, identify_message;
 	u8 *ptr;
-	dprintkdbg(DBG_0, "start_scsi: (pid#%li) <%02i-%i> srb=%p\n",
-		srb->cmd->serial_number, dcb->target_id, dcb->target_lun, srb);
+	dprintkdbg(DBG_0, "start_scsi: (0x%p) <%02i-%i> srb=%p\n",
+		dcb->target_id, dcb->target_lun, srb);
 
 	srb->tag_number = TAG_NONE;	/* acb->tag_max_num: had error read in eeprom */
 
@@ -1505,8 +1505,8 @@
 	s_stat2 = DC395x_read16(acb, TRM_S1040_SCSI_STATUS);
 #if 1
 	if (s_stat & 0x20 /* s_stat2 & 0x02000 */ ) {
-		dprintkdbg(DBG_KG, "start_scsi: (pid#%li) BUSY %02x %04x\n",
-			srb->cmd->serial_number, s_stat, s_stat2);
+		dprintkdbg(DBG_KG, "start_scsi: (0x%p) BUSY %02x %04x\n",
+			s_stat, s_stat2);
 		/*
 		 * Try anyway?
 		 *
@@ -1522,16 +1522,15 @@
 	}
 #endif
 	if (acb->active_dcb) {
-		dprintkl(KERN_DEBUG, "start_scsi: (pid#%li) Attempt to start a"
-			"command while another command (pid#%li) is active.",
-			srb->cmd->serial_number,
+		dprintkl(KERN_DEBUG, "start_scsi: (0x%p) Attempt to start a"
+			"command while another command (0x%p) is active.",
+			srb->cmd,
 			acb->active_dcb->active_srb ?
-			    acb->active_dcb->active_srb->cmd->serial_number : 0);
+			    acb->active_dcb->active_srb->cmd : 0);
 		return 1;
 	}
 	if (DC395x_read16(acb, TRM_S1040_SCSI_STATUS) & SCSIINTERRUPT) {
-		dprintkdbg(DBG_KG, "start_scsi: (pid#%li) Failed (busy)\n",
-			srb->cmd->serial_number);
+		dprintkdbg(DBG_KG, "start_scsi: (0x%p) Failed (busy)\n", srb->cmd);
 		return 1;
 	}
 	/* Allow starting of SCSI commands half a second before we allow the mid-level
@@ -1603,9 +1602,9 @@
 			tag_number++;
 		}
 		if (tag_number >= dcb->max_command) {
-			dprintkl(KERN_WARNING, "start_scsi: (pid#%li) "
+			dprintkl(KERN_WARNING, "start_scsi: (0x%p) "
 				"Out of tags target=<%02i-%i>)\n",
-				srb->cmd->serial_number, srb->cmd->device->id,
+				srb->cmd, srb->cmd->device->id,
 				srb->cmd->device->lun);
 			srb->state = SRB_READY;
 			DC395x_write16(acb, TRM_S1040_SCSI_CONTROL,
@@ -1623,8 +1622,8 @@
 #endif
 /*polling:*/
 	/* Send CDB ..command block ......... */
-	dprintkdbg(DBG_KG, "start_scsi: (pid#%li) <%02i-%i> cmnd=0x%02x tag=%i\n",
-		srb->cmd->serial_number, srb->cmd->device->id, srb->cmd->device->lun,
+	dprintkdbg(DBG_KG, "start_scsi: (0x%p) <%02i-%i> cmnd=0x%02x tag=%i\n",
+		srb->cmd, srb->cmd->device->id, srb->cmd->device->lun,
 		srb->cmd->cmnd[0], srb->tag_number);
 	if (srb->flag & AUTO_REQSENSE) {
 		DC395x_write8(acb, TRM_S1040_SCSI_FIFO, REQUEST_SENSE);
@@ -1647,8 +1646,8 @@
 		 * we caught an interrupt (must be reset or reselection ... )
 		 * : Let's process it first!
 		 */
-		dprintkdbg(DBG_0, "start_scsi: (pid#%li) <%02i-%i> Failed - busy\n",
-			srb->cmd->serial_number, dcb->target_id, dcb->target_lun);
+		dprintkdbg(DBG_0, "start_scsi: (0x%p) <%02i-%i> Failed - busy\n",
+			srb->cmd, dcb->target_id, dcb->target_lun);
 		srb->state = SRB_READY;
 		free_tag(dcb, srb);
 		srb->msg_count = 0;
@@ -1843,7 +1842,7 @@
 static void msgout_phase0(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb,
 		u16 *pscsi_status)
 {
-	dprintkdbg(DBG_0, "msgout_phase0: (pid#%li)\n", srb->cmd->serial_number);
+	dprintkdbg(DBG_0, "msgout_phase0: (0x%p)\n", srb->cmd);
 	if (srb->state & (SRB_UNEXPECT_RESEL + SRB_ABORT_SENT))
 		*pscsi_status = PH_BUS_FREE;	/*.. initial phase */
 
@@ -1857,18 +1856,18 @@
 {
 	u16 i;
 	u8 *ptr;
-	dprintkdbg(DBG_0, "msgout_phase1: (pid#%li)\n", srb->cmd->serial_number);
+	dprintkdbg(DBG_0, "msgout_phase1: (0x%p)\n", srb->cmd);
 
 	clear_fifo(acb, "msgout_phase1");
 	if (!(srb->state & SRB_MSGOUT)) {
 		srb->state |= SRB_MSGOUT;
 		dprintkl(KERN_DEBUG,
-			"msgout_phase1: (pid#%li) Phase unexpected\n",
-			srb->cmd->serial_number);	/* So what ? */
+			"msgout_phase1: (0x%p) Phase unexpected\n",
+			srb->cmd);	/* So what ? */
 	}
 	if (!srb->msg_count) {
-		dprintkdbg(DBG_0, "msgout_phase1: (pid#%li) NOP msg\n",
-			srb->cmd->serial_number);
+		dprintkdbg(DBG_0, "msgout_phase1: (0x%p) NOP msg\n",
+			srb->cmd);
 		DC395x_write8(acb, TRM_S1040_SCSI_FIFO, MSG_NOP);
 		DC395x_write16(acb, TRM_S1040_SCSI_CONTROL, DO_DATALATCH);	/* it's important for atn stop */
 		DC395x_write8(acb, TRM_S1040_SCSI_COMMAND, SCMD_FIFO_OUT);
@@ -1888,7 +1887,7 @@
 static void command_phase0(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb,
 		u16 *pscsi_status)
 {
-	dprintkdbg(DBG_0, "command_phase0: (pid#%li)\n", srb->cmd->serial_number);
+	dprintkdbg(DBG_0, "command_phase0: (0x%p)\n", srb->cmd);
 	DC395x_write16(acb, TRM_S1040_SCSI_CONTROL, DO_DATALATCH);
 }
 
@@ -1899,7 +1898,7 @@
 	struct DeviceCtlBlk *dcb;
 	u8 *ptr;
 	u16 i;
-	dprintkdbg(DBG_0, "command_phase1: (pid#%li)\n", srb->cmd->serial_number);
+	dprintkdbg(DBG_0, "command_phase1: (0x%p)\n", srb->cmd);
 
 	clear_fifo(acb, "command_phase1");
 	DC395x_write16(acb, TRM_S1040_SCSI_CONTROL, DO_CLRATN);
@@ -2041,8 +2040,8 @@
 	struct DeviceCtlBlk *dcb = srb->dcb;
 	u16 scsi_status = *pscsi_status;
 	u32 d_left_counter = 0;
-	dprintkdbg(DBG_0, "data_out_phase0: (pid#%li) <%02i-%i>\n",
-		srb->cmd->serial_number, srb->cmd->device->id, srb->cmd->device->lun);
+	dprintkdbg(DBG_0, "data_out_phase0: (0x%p) <%02i-%i>\n",
+		srb->cmd, srb->cmd->device->id, srb->cmd->device->lun);
 
 	/*
 	 * KG: We need to drain the buffers before we draw any conclusions!
@@ -2171,8 +2170,8 @@
 static void data_out_phase1(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb,
 		u16 *pscsi_status)
 {
-	dprintkdbg(DBG_0, "data_out_phase1: (pid#%li) <%02i-%i>\n",
-		srb->cmd->serial_number, srb->cmd->device->id, srb->cmd->device->lun);
+	dprintkdbg(DBG_0, "data_out_phase1: (0x%p) <%02i-%i>\n",
+		srb->cmd, srb->cmd->device->id, srb->cmd->device->lun);
 	clear_fifo(acb, "data_out_phase1");
 	/* do prepare before transfer when data out phase */
 	data_io_transfer(acb, srb, XFERDATAOUT);
@@ -2183,8 +2182,8 @@
 {
 	u16 scsi_status = *pscsi_status;
 
-	dprintkdbg(DBG_0, "data_in_phase0: (pid#%li) <%02i-%i>\n",
-		srb->cmd->serial_number, srb->cmd->device->id, srb->cmd->device->lun);
+	dprintkdbg(DBG_0, "data_in_phase0: (0x%p) <%02i-%i>\n",
+		srb->cmd, srb->cmd->device->id, srb->cmd->device->lun);
 
 	/*
 	 * KG: DataIn is much more tricky than DataOut. When the device is finished
@@ -2204,8 +2203,8 @@
 		unsigned int sc, fc;
 
 		if (scsi_status & PARITYERROR) {
-			dprintkl(KERN_INFO, "data_in_phase0: (pid#%li) "
-				"Parity Error\n", srb->cmd->serial_number);
+			dprintkl(KERN_INFO, "data_in_phase0: (0x%p) "
+				"Parity Error\n", srb->cmd);
 			srb->status |= PARITY_ERROR;
 		}
 		/*
@@ -2394,8 +2393,8 @@
 static void data_in_phase1(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb,
 		u16 *pscsi_status)
 {
-	dprintkdbg(DBG_0, "data_in_phase1: (pid#%li) <%02i-%i>\n",
-		srb->cmd->serial_number, srb->cmd->device->id, srb->cmd->device->lun);
+	dprintkdbg(DBG_0, "data_in_phase1: (0x%p) <%02i-%i>\n",
+		srb->cmd, srb->cmd->device->id, srb->cmd->device->lun);
 	data_io_transfer(acb, srb, XFERDATAIN);
 }
 
@@ -2406,8 +2405,8 @@
 	struct DeviceCtlBlk *dcb = srb->dcb;
 	u8 bval;
 	dprintkdbg(DBG_0,
-		"data_io_transfer: (pid#%li) <%02i-%i> %c len=%i, sg=(%i/%i)\n",
-		srb->cmd->serial_number, srb->cmd->device->id, srb->cmd->device->lun,
+		"data_io_transfer: (0x%p) <%02i-%i> %c len=%i, sg=(%i/%i)\n",
+		srb->cmd, srb->cmd->device->id, srb->cmd->device->lun,
 		((io_dir & DMACMD_DIR) ? 'r' : 'w'),
 		srb->total_xfer_length, srb->sg_index, srb->sg_count);
 	if (srb == acb->tmp_srb)
@@ -2579,8 +2578,8 @@
 static void status_phase0(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb,
 		u16 *pscsi_status)
 {
-	dprintkdbg(DBG_0, "status_phase0: (pid#%li) <%02i-%i>\n",
-		srb->cmd->serial_number, srb->cmd->device->id, srb->cmd->device->lun);
+	dprintkdbg(DBG_0, "status_phase0: (0x%p) <%02i-%i>\n",
+		srb->cmd, srb->cmd->device->id, srb->cmd->device->lun);
 	srb->target_status = DC395x_read8(acb, TRM_S1040_SCSI_FIFO);
 	srb->end_message = DC395x_read8(acb, TRM_S1040_SCSI_FIFO);	/* get message */
 	srb->state = SRB_COMPLETED;
@@ -2593,8 +2592,8 @@
 static void status_phase1(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb,
 		u16 *pscsi_status)
 {
-	dprintkdbg(DBG_0, "status_phase1: (pid#%li) <%02i-%i>\n",
-		srb->cmd->serial_number, srb->cmd->device->id, srb->cmd->device->lun);
+	dprintkdbg(DBG_0, "status_phase1: (0x%p) <%02i-%i>\n",
+		srb->cmd, srb->cmd->device->id, srb->cmd->device->lun);
 	srb->state = SRB_STATUS;
 	DC395x_write16(acb, TRM_S1040_SCSI_CONTROL, DO_DATALATCH);	/* it's important for atn stop */
 	DC395x_write8(acb, TRM_S1040_SCSI_COMMAND, SCMD_COMP);
@@ -2635,8 +2634,8 @@
 {
 	struct ScsiReqBlk *srb = NULL;
 	struct ScsiReqBlk *i;
-	dprintkdbg(DBG_0, "msgin_qtag: (pid#%li) tag=%i srb=%p\n",
-		   srb->cmd->serial_number, tag, srb);
+	dprintkdbg(DBG_0, "msgin_qtag: (0x%p) tag=%i srb=%p\n",
+		   srb->cmd, tag, srb);
 
 	if (!(dcb->tag_mask & (1 << tag)))
 		dprintkl(KERN_DEBUG,
@@ -2654,8 +2653,8 @@
 	if (!srb)
 		goto mingx0;
 
-	dprintkdbg(DBG_0, "msgin_qtag: (pid#%li) <%02i-%i>\n",
-		srb->cmd->serial_number, srb->dcb->target_id, srb->dcb->target_lun);
+	dprintkdbg(DBG_0, "msgin_qtag: (0x%p) <%02i-%i>\n",
+		srb->cmd, srb->dcb->target_id, srb->dcb->target_lun);
 	if (dcb->flag & ABORT_DEV_) {
 		/*srb->state = SRB_ABORT_SENT; */
 		enable_msgout_abort(acb, srb);
@@ -2865,7 +2864,7 @@
 		u16 *pscsi_status)
 {
 	struct DeviceCtlBlk *dcb = acb->active_dcb;
-	dprintkdbg(DBG_0, "msgin_phase0: (pid#%li)\n", srb->cmd->serial_number);
+	dprintkdbg(DBG_0, "msgin_phase0: (0x%p)\n", srb->cmd);
 
 	srb->msgin_buf[acb->msg_len++] = DC395x_read8(acb, TRM_S1040_SCSI_FIFO);
 	if (msgin_completed(srb->msgin_buf, acb->msg_len)) {
@@ -2931,9 +2930,9 @@
 			 * SAVE POINTER may be ignored as we have the struct
 			 * ScsiReqBlk* associated with the scsi command.
 			 */
-			dprintkdbg(DBG_0, "msgin_phase0: (pid#%li) "
+			dprintkdbg(DBG_0, "msgin_phase0: (0x%p) "
 				"SAVE POINTER rem=%i Ignore\n",
-				srb->cmd->serial_number, srb->total_xfer_length);
+				srb->cmd, srb->total_xfer_length);
 			break;
 
 		case RESTORE_POINTERS:
@@ -2941,9 +2940,9 @@
 			break;
 
 		case ABORT:
-			dprintkdbg(DBG_0, "msgin_phase0: (pid#%li) "
+			dprintkdbg(DBG_0, "msgin_phase0: (0x%p) "
 				"<%02i-%i> ABORT msg\n",
-				srb->cmd->serial_number, dcb->target_id,
+				srb->cmd, dcb->target_id,
 				dcb->target_lun);
 			dcb->flag |= ABORT_DEV_;
 			enable_msgout_abort(acb, srb);
@@ -2975,7 +2974,7 @@
 static void msgin_phase1(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb,
 		u16 *pscsi_status)
 {
-	dprintkdbg(DBG_0, "msgin_phase1: (pid#%li)\n", srb->cmd->serial_number);
+	dprintkdbg(DBG_0, "msgin_phase1: (0x%p)\n", srb->cmd);
 	clear_fifo(acb, "msgin_phase1");
 	DC395x_write32(acb, TRM_S1040_SCSI_COUNTER, 1);
 	if (!(srb->state & SRB_MSGIN)) {
@@ -3041,7 +3040,7 @@
 	}
 	srb = dcb->active_srb;
 	acb->active_dcb = NULL;
-	dprintkdbg(DBG_0, "disconnect: (pid#%li)\n", srb->cmd->serial_number);
+	dprintkdbg(DBG_0, "disconnect: (0x%p)\n", srb->cmd);
 
 	srb->scsi_phase = PH_BUS_FREE;	/* initial phase */
 	clear_fifo(acb, "disconnect");
@@ -3071,14 +3070,14 @@
 			    && srb->state != SRB_MSGOUT) {
 				srb->state = SRB_READY;
 				dprintkl(KERN_DEBUG,
-					"disconnect: (pid#%li) Unexpected\n",
-					srb->cmd->serial_number);
+					"disconnect: (0x%p) Unexpected\n",
+					srb->cmd);
 				srb->target_status = SCSI_STAT_SEL_TIMEOUT;
 				goto disc1;
 			} else {
 				/* Normal selection timeout */
-				dprintkdbg(DBG_KG, "disconnect: (pid#%li) "
-					"<%02i-%i> SelTO\n", srb->cmd->serial_number,
+				dprintkdbg(DBG_KG, "disconnect: (0x%p) "
+					"<%02i-%i> SelTO\n", srb->cmd,
 					dcb->target_id, dcb->target_lun);
 				if (srb->retry_count++ > DC395x_MAX_RETRIES
 				    || acb->scan_devices) {
@@ -3089,8 +3088,8 @@
 				free_tag(dcb, srb);
 				srb_going_to_waiting_move(dcb, srb);
 				dprintkdbg(DBG_KG,
-					"disconnect: (pid#%li) Retry\n",
-					srb->cmd->serial_number);
+					"disconnect: (0x%p) Retry\n",
+					srb->cmd);
 				waiting_set_timer(acb, HZ / 20);
 			}
 		} else if (srb->state & SRB_DISCONNECT) {
@@ -3142,9 +3141,9 @@
 		}
 		/* Why the if ? */
 		if (!acb->scan_devices) {
-			dprintkdbg(DBG_KG, "reselect: (pid#%li) <%02i-%i> "
+			dprintkdbg(DBG_KG, "reselect: (0x%p) <%02i-%i> "
 				"Arb lost but Resel win rsel=%i stat=0x%04x\n",
-				srb->cmd->serial_number, dcb->target_id,
+				srb->cmd, dcb->target_id,
 				dcb->target_lun, rsel_tar_lun_id,
 				DC395x_read16(acb, TRM_S1040_SCSI_STATUS));
 			arblostflag = 1;
@@ -3318,7 +3317,7 @@
 	enum dma_data_direction dir = cmd->sc_data_direction;
 	int ckc_only = 1;
 
-	dprintkdbg(DBG_1, "srb_done: (pid#%li) <%02i-%i>\n", srb->cmd->serial_number,
+	dprintkdbg(DBG_1, "srb_done: (0x%p) <%02i-%i>\n", srb->cmd,
 		srb->cmd->device->id, srb->cmd->device->lun);
 	dprintkdbg(DBG_SG, "srb_done: srb=%p sg=%i(%i/%i) buf=%p\n",
 		   srb, scsi_sg_count(cmd), srb->sg_index, srb->sg_count,
@@ -3497,9 +3496,9 @@
 	cmd->SCp.buffers_residual = 0;
 	if (debug_enabled(DBG_KG)) {
 		if (srb->total_xfer_length)
-			dprintkdbg(DBG_KG, "srb_done: (pid#%li) <%02i-%i> "
+			dprintkdbg(DBG_KG, "srb_done: (0x%p) <%02i-%i> "
 				"cmnd=0x%02x Missed %i bytes\n",
-				cmd->serial_number, cmd->device->id, cmd->device->lun,
+				cmd, cmd->device->id, cmd->device->lun,
 				cmd->cmnd[0], srb->total_xfer_length);
 	}
 
@@ -3508,8 +3507,8 @@
 	if (srb == acb->tmp_srb)
 		dprintkl(KERN_ERR, "srb_done: ERROR! Completed cmd with tmp_srb\n");
 	else {
-		dprintkdbg(DBG_0, "srb_done: (pid#%li) done result=0x%08x\n",
-			cmd->serial_number, cmd->result);
+		dprintkdbg(DBG_0, "srb_done: (0x%p) done result=0x%08x\n",
+			cmd, cmd->result);
 		srb_free_insert(acb, srb);
 	}
 	pci_unmap_srb(acb, srb);
@@ -3538,7 +3537,7 @@
 			p = srb->cmd;
 			dir = p->sc_data_direction;
 			result = MK_RES(0, did_flag, 0, 0);
-			printk("G:%li(%02i-%i) ", p->serial_number,
+			printk("G:%p(%02i-%i) ", p,
 			       p->device->id, p->device->lun);
 			srb_going_remove(dcb, srb);
 			free_tag(dcb, srb);
@@ -3568,7 +3567,7 @@
 			p = srb->cmd;
 
 			result = MK_RES(0, did_flag, 0, 0);
-			printk("W:%li<%02i-%i>", p->serial_number, p->device->id,
+			printk("W:%p<%02i-%i>", p, p->device->id,
 			       p->device->lun);
 			srb_waiting_remove(dcb, srb);
 			srb_free_insert(acb, srb);
@@ -3677,8 +3676,8 @@
 		struct ScsiReqBlk *srb)
 {
 	struct scsi_cmnd *cmd = srb->cmd;
-	dprintkdbg(DBG_1, "request_sense: (pid#%li) <%02i-%i>\n",
-		cmd->serial_number, cmd->device->id, cmd->device->lun);
+	dprintkdbg(DBG_1, "request_sense: (0x%p) <%02i-%i>\n",
+		cmd, cmd->device->id, cmd->device->lun);
 
 	srb->flag |= AUTO_REQSENSE;
 	srb->adapter_status = 0;
@@ -3708,8 +3707,8 @@
 
 	if (start_scsi(acb, dcb, srb)) {	/* Should only happen, if sb. else grabs the bus */
 		dprintkl(KERN_DEBUG,
-			"request_sense: (pid#%li) failed <%02i-%i>\n",
-			srb->cmd->serial_number, dcb->target_id, dcb->target_lun);
+			"request_sense: (0x%p) failed <%02i-%i>\n",
+			srb->cmd, dcb->target_id, dcb->target_lun);
 		srb_going_to_waiting_move(dcb, srb);
 		waiting_set_timer(acb, HZ / 100);
 	}
@@ -4717,13 +4716,13 @@
 				dcb->target_id, dcb->target_lun,
 				list_size(&dcb->srb_waiting_list));
                 list_for_each_entry(srb, &dcb->srb_waiting_list, list)
-			SPRINTF(" %li", srb->cmd->serial_number);
+			SPRINTF(" %p", srb->cmd);
 		if (!list_empty(&dcb->srb_going_list))
 			SPRINTF("\nDCB (%02i-%i): Going  : %i:",
 				dcb->target_id, dcb->target_lun,
 				list_size(&dcb->srb_going_list));
 		list_for_each_entry(srb, &dcb->srb_going_list, list)
-			SPRINTF(" %li", srb->cmd->serial_number);
+			SPRINTF(" %p", srb->cmd);
 		if (!list_empty(&dcb->srb_waiting_list) || !list_empty(&dcb->srb_going_list))
 			SPRINTF("\n");
 	}
diff -druN linux-2.6.39-libre/drivers/scsi/device_handler/scsi_dh_alua.c linux-3.0-rc7-libre/drivers/scsi/device_handler/scsi_dh_alua.c
--- linux-2.6.39-libre/drivers/scsi/device_handler/scsi_dh_alua.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/scsi/device_handler/scsi_dh_alua.c	2011-07-11 19:51:52.000000000 -0400
@@ -782,7 +782,7 @@
 	h->sdev = sdev;
 
 	err = alua_initialize(sdev, h);
-	if (err != SCSI_DH_OK)
+	if ((err != SCSI_DH_OK) && (err != SCSI_DH_DEV_OFFLINED))
 		goto failed;
 
 	if (!try_module_get(THIS_MODULE))
diff -druN linux-2.6.39-libre/drivers/scsi/device_handler/scsi_dh_rdac.c linux-3.0-rc7-libre/drivers/scsi/device_handler/scsi_dh_rdac.c
--- linux-2.6.39-libre/drivers/scsi/device_handler/scsi_dh_rdac.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/scsi/device_handler/scsi_dh_rdac.c	2011-07-11 19:51:52.000000000 -0400
@@ -182,14 +182,24 @@
 	struct rdac_controller	*ctlr;
 #define UNINITIALIZED_LUN	(1 << 8)
 	unsigned		lun;
+
+#define RDAC_MODE		0
+#define RDAC_MODE_AVT		1
+#define RDAC_MODE_IOSHIP	2
+	unsigned char		mode;
+
 #define RDAC_STATE_ACTIVE	0
 #define RDAC_STATE_PASSIVE	1
 	unsigned char		state;
 
 #define RDAC_LUN_UNOWNED	0
 #define RDAC_LUN_OWNED		1
-#define RDAC_LUN_AVT		2
 	char			lun_state;
+
+#define RDAC_PREFERRED		0
+#define RDAC_NON_PREFERRED	1
+	char			preferred;
+
 	unsigned char		sense[SCSI_SENSE_BUFFERSIZE];
 	union			{
 		struct c2_inquiry c2;
@@ -199,11 +209,15 @@
 	} inq;
 };
 
+static const char *mode[] = {
+	"RDAC",
+	"AVT",
+	"IOSHIP",
+};
 static const char *lun_state[] =
 {
 	"unowned",
 	"owned",
-	"owned (AVT mode)",
 };
 
 struct rdac_queue_data {
@@ -458,25 +472,33 @@
 	int err;
 	struct c9_inquiry *inqp;
 
-	h->lun_state = RDAC_LUN_UNOWNED;
 	h->state = RDAC_STATE_ACTIVE;
 	err = submit_inquiry(sdev, 0xC9, sizeof(struct c9_inquiry), h);
 	if (err == SCSI_DH_OK) {
 		inqp = &h->inq.c9;
-		if ((inqp->avte_cvp >> 7) == 0x1) {
-			/* LUN in AVT mode */
-			sdev_printk(KERN_NOTICE, sdev,
-				    "%s: AVT mode detected\n",
-				    RDAC_NAME);
-			h->lun_state = RDAC_LUN_AVT;
-		} else if ((inqp->avte_cvp & 0x1) != 0) {
-			/* LUN was owned by the controller */
+		/* detect the operating mode */
+		if ((inqp->avte_cvp >> 5) & 0x1)
+			h->mode = RDAC_MODE_IOSHIP; /* LUN in IOSHIP mode */
+		else if (inqp->avte_cvp >> 7)
+			h->mode = RDAC_MODE_AVT; /* LUN in AVT mode */
+		else
+			h->mode = RDAC_MODE; /* LUN in RDAC mode */
+
+		/* Update ownership */
+		if (inqp->avte_cvp & 0x1)
 			h->lun_state = RDAC_LUN_OWNED;
+		else {
+			h->lun_state = RDAC_LUN_UNOWNED;
+			if (h->mode == RDAC_MODE)
+				h->state = RDAC_STATE_PASSIVE;
 		}
-	}
 
-	if (h->lun_state == RDAC_LUN_UNOWNED)
-		h->state = RDAC_STATE_PASSIVE;
+		/* Update path prio*/
+		if (inqp->path_prio & 0x1)
+			h->preferred = RDAC_PREFERRED;
+		else
+			h->preferred = RDAC_NON_PREFERRED;
+	}
 
 	return err;
 }
@@ -648,12 +670,27 @@
 {
 	struct rdac_dh_data *h = get_rdac_data(sdev);
 	int err = SCSI_DH_OK;
+	int act = 0;
 
 	err = check_ownership(sdev, h);
 	if (err != SCSI_DH_OK)
 		goto done;
 
-	if (h->lun_state == RDAC_LUN_UNOWNED) {
+	switch (h->mode) {
+	case RDAC_MODE:
+		if (h->lun_state == RDAC_LUN_UNOWNED)
+			act = 1;
+		break;
+	case RDAC_MODE_IOSHIP:
+		if ((h->lun_state == RDAC_LUN_UNOWNED) &&
+		    (h->preferred == RDAC_PREFERRED))
+			act = 1;
+		break;
+	default:
+		break;
+	}
+
+	if (act) {
 		err = queue_mode_select(sdev, fn, data);
 		if (err == SCSI_DH_OK)
 			return 0;
@@ -836,8 +873,9 @@
 	spin_unlock_irqrestore(sdev->request_queue->queue_lock, flags);
 
 	sdev_printk(KERN_NOTICE, sdev,
-		    "%s: LUN %d (%s)\n",
-		    RDAC_NAME, h->lun, lun_state[(int)h->lun_state]);
+		    "%s: LUN %d (%s) (%s)\n",
+		    RDAC_NAME, h->lun, mode[(int)h->mode],
+		    lun_state[(int)h->lun_state]);
 
 	return 0;
 
diff -druN linux-2.6.39-libre/drivers/scsi/dpt_i2o.c linux-3.0-rc7-libre/drivers/scsi/dpt_i2o.c
--- linux-2.6.39-libre/drivers/scsi/dpt_i2o.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/scsi/dpt_i2o.c	2011-07-11 19:51:52.000000000 -0400
@@ -780,7 +780,7 @@
 		return FAILED;
 	}
 	pHba = (adpt_hba*) cmd->device->host->hostdata[0];
-	printk(KERN_INFO"%s: Trying to Abort cmd=%ld\n",pHba->name, cmd->serial_number);
+	printk(KERN_INFO"%s: Trying to Abort\n",pHba->name);
 	if ((dptdevice = (void*) (cmd->device->hostdata)) == NULL) {
 		printk(KERN_ERR "%s: Unable to abort: No device in cmnd\n",pHba->name);
 		return FAILED;
@@ -802,10 +802,10 @@
 			printk(KERN_INFO"%s: Abort cmd not supported\n",pHba->name);
 			return FAILED;
 		}
-		printk(KERN_INFO"%s: Abort cmd=%ld failed.\n",pHba->name, cmd->serial_number);
+		printk(KERN_INFO"%s: Abort failed.\n",pHba->name);
 		return FAILED;
 	} 
-	printk(KERN_INFO"%s: Abort cmd=%ld complete.\n",pHba->name, cmd->serial_number);
+	printk(KERN_INFO"%s: Abort complete.\n",pHba->name);
 	return SUCCESS;
 }
 
diff -druN linux-2.6.39-libre/drivers/scsi/eata.c linux-3.0-rc7-libre/drivers/scsi/eata.c
--- linux-2.6.39-libre/drivers/scsi/eata.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/scsi/eata.c	2011-07-11 19:51:52.000000000 -0400
@@ -1766,8 +1766,8 @@
 	struct mscp *cpp;
 
 	if (SCpnt->host_scribble)
-		panic("%s: qcomm, pid %ld, SCpnt %p already active.\n",
-		      ha->board_name, SCpnt->serial_number, SCpnt);
+		panic("%s: qcomm, SCpnt %p already active.\n",
+		      ha->board_name, SCpnt);
 
 	/* i is the mailbox number, look for the first free mailbox
 	   starting from last_cp_used */
@@ -1801,7 +1801,7 @@
 
 	if (do_trace)
 		scmd_printk(KERN_INFO, SCpnt,
-			"qcomm, mbox %d, pid %ld.\n", i, SCpnt->serial_number);
+			"qcomm, mbox %d.\n", i);
 
 	cpp->reqsen = 1;
 	cpp->dispri = 1;
@@ -1833,8 +1833,7 @@
 	if (do_dma(shost->io_port, cpp->cp_dma_addr, SEND_CP_DMA)) {
 		unmap_dma(i, ha);
 		SCpnt->host_scribble = NULL;
-		scmd_printk(KERN_INFO, SCpnt,
-			"qcomm, pid %ld, adapter busy.\n", SCpnt->serial_number);
+		scmd_printk(KERN_INFO, SCpnt, "qcomm, adapter busy.\n");
 		return 1;
 	}
 
@@ -1851,14 +1850,12 @@
 	unsigned int i;
 
 	if (SCarg->host_scribble == NULL) {
-		scmd_printk(KERN_INFO, SCarg,
-			"abort, pid %ld inactive.\n", SCarg->serial_number);
+		scmd_printk(KERN_INFO, SCarg, "abort, cmd inactive.\n");
 		return SUCCESS;
 	}
 
 	i = *(unsigned int *)SCarg->host_scribble;
-	scmd_printk(KERN_WARNING, SCarg,
-		"abort, mbox %d, pid %ld.\n", i, SCarg->serial_number);
+	scmd_printk(KERN_WARNING, SCarg, "abort, mbox %d.\n", i);
 
 	if (i >= shost->can_queue)
 		panic("%s: abort, invalid SCarg->host_scribble.\n", ha->board_name);
@@ -1902,8 +1899,8 @@
 		SCarg->result = DID_ABORT << 16;
 		SCarg->host_scribble = NULL;
 		ha->cp_stat[i] = FREE;
-		printk("%s, abort, mbox %d ready, DID_ABORT, pid %ld done.\n",
-		       ha->board_name, i, SCarg->serial_number);
+		printk("%s, abort, mbox %d ready, DID_ABORT, done.\n",
+		       ha->board_name, i);
 		SCarg->scsi_done(SCarg);
 		return SUCCESS;
 	}
@@ -1919,13 +1916,12 @@
 	struct Scsi_Host *shost = SCarg->device->host;
 	struct hostdata *ha = (struct hostdata *)shost->hostdata;
 
-	scmd_printk(KERN_INFO, SCarg,
-		"reset, enter, pid %ld.\n", SCarg->serial_number);
+	scmd_printk(KERN_INFO, SCarg, "reset, enter.\n");
 
 	spin_lock_irq(shost->host_lock);
 
 	if (SCarg->host_scribble == NULL)
-		printk("%s: reset, pid %ld inactive.\n", ha->board_name, SCarg->serial_number);
+		printk("%s: reset, inactive.\n", ha->board_name);
 
 	if (ha->in_reset) {
 		printk("%s: reset, exit, already in reset.\n", ha->board_name);
@@ -1964,14 +1960,14 @@
 
 		if (ha->cp_stat[i] == READY || ha->cp_stat[i] == ABORTING) {
 			ha->cp_stat[i] = ABORTING;
-			printk("%s: reset, mbox %d aborting, pid %ld.\n",
-			       ha->board_name, i, SCpnt->serial_number);
+			printk("%s: reset, mbox %d aborting.\n",
+			       ha->board_name, i);
 		}
 
 		else {
 			ha->cp_stat[i] = IN_RESET;
-			printk("%s: reset, mbox %d in reset, pid %ld.\n",
-			       ha->board_name, i, SCpnt->serial_number);
+			printk("%s: reset, mbox %d in reset.\n",
+			       ha->board_name, i);
 		}
 
 		if (SCpnt->host_scribble == NULL)
@@ -2025,8 +2021,8 @@
 			ha->cp_stat[i] = LOCKED;
 
 			printk
-			    ("%s, reset, mbox %d locked, DID_RESET, pid %ld done.\n",
-			     ha->board_name, i, SCpnt->serial_number);
+			    ("%s, reset, mbox %d locked, DID_RESET, done.\n",
+			     ha->board_name, i);
 		}
 
 		else if (ha->cp_stat[i] == ABORTING) {
@@ -2039,8 +2035,8 @@
 			ha->cp_stat[i] = FREE;
 
 			printk
-			    ("%s, reset, mbox %d aborting, DID_RESET, pid %ld done.\n",
-			     ha->board_name, i, SCpnt->serial_number);
+			    ("%s, reset, mbox %d aborting, DID_RESET, done.\n",
+			     ha->board_name, i);
 		}
 
 		else
@@ -2054,7 +2050,7 @@
 	do_trace = 0;
 
 	if (arg_done)
-		printk("%s: reset, exit, pid %ld done.\n", ha->board_name, SCarg->serial_number);
+		printk("%s: reset, exit, done.\n", ha->board_name);
 	else
 		printk("%s: reset, exit.\n", ha->board_name);
 
@@ -2238,10 +2234,10 @@
 			cpp = &ha->cp[k];
 			SCpnt = cpp->SCpnt;
 			scmd_printk(KERN_INFO, SCpnt,
-			    "%s pid %ld mb %d fc %d nr %d sec %ld ns %u"
+			    "%s mb %d fc %d nr %d sec %ld ns %u"
 			     " cur %ld s:%c r:%c rev:%c in:%c ov:%c xd %d.\n",
 			     (ihdlr ? "ihdlr" : "qcomm"),
-			     SCpnt->serial_number, k, flushcount,
+			     k, flushcount,
 			     n_ready, blk_rq_pos(SCpnt->request),
 			     blk_rq_sectors(SCpnt->request), cursec, YESNO(s),
 			     YESNO(r), YESNO(rev), YESNO(input_only),
@@ -2285,10 +2281,10 @@
 
 		if (do_dma(dev->host->io_port, cpp->cp_dma_addr, SEND_CP_DMA)) {
 			scmd_printk(KERN_INFO, SCpnt,
-			    "%s, pid %ld, mbox %d, adapter"
+			    "%s, mbox %d, adapter"
 			     " busy, will abort.\n",
 			     (ihdlr ? "ihdlr" : "qcomm"),
-			     SCpnt->serial_number, k);
+			     k);
 			ha->cp_stat[k] = ABORTING;
 			continue;
 		}
@@ -2398,12 +2394,12 @@
 		panic("%s: ihdlr, mbox %d, SCpnt == NULL.\n", ha->board_name, i);
 
 	if (SCpnt->host_scribble == NULL)
-		panic("%s: ihdlr, mbox %d, pid %ld, SCpnt %p garbled.\n", ha->board_name,
-		      i, SCpnt->serial_number, SCpnt);
+		panic("%s: ihdlr, mbox %d, SCpnt %p garbled.\n", ha->board_name,
+		      i, SCpnt);
 
 	if (*(unsigned int *)SCpnt->host_scribble != i)
-		panic("%s: ihdlr, mbox %d, pid %ld, index mismatch %d.\n",
-		      ha->board_name, i, SCpnt->serial_number,
+		panic("%s: ihdlr, mbox %d, index mismatch %d.\n",
+		      ha->board_name, i,
 		      *(unsigned int *)SCpnt->host_scribble);
 
 	sync_dma(i, ha);
@@ -2449,11 +2445,11 @@
 		if (spp->target_status && SCpnt->device->type == TYPE_DISK &&
 		    (!(tstatus == CHECK_CONDITION && ha->iocount <= 1000 &&
 		       (SCpnt->sense_buffer[2] & 0xf) == NOT_READY)))
-			printk("%s: ihdlr, target %d.%d:%d, pid %ld, "
+			printk("%s: ihdlr, target %d.%d:%d, "
 			       "target_status 0x%x, sense key 0x%x.\n",
 			       ha->board_name,
 			       SCpnt->device->channel, SCpnt->device->id,
-			       SCpnt->device->lun, SCpnt->serial_number,
+			       SCpnt->device->lun,
 			       spp->target_status, SCpnt->sense_buffer[2]);
 
 		ha->target_to[SCpnt->device->id][SCpnt->device->channel] = 0;
@@ -2522,9 +2518,9 @@
 	    do_trace || msg_byte(spp->target_status))
 #endif
 		scmd_printk(KERN_INFO, SCpnt, "ihdlr, mbox %2d, err 0x%x:%x,"
-		       " pid %ld, reg 0x%x, count %d.\n",
+		       " reg 0x%x, count %d.\n",
 		       i, spp->adapter_status, spp->target_status,
-		       SCpnt->serial_number, reg, ha->iocount);
+		       reg, ha->iocount);
 
 	unmap_dma(i, ha);
 
diff -druN linux-2.6.39-libre/drivers/scsi/eata_pio.c linux-3.0-rc7-libre/drivers/scsi/eata_pio.c
--- linux-2.6.39-libre/drivers/scsi/eata_pio.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/scsi/eata_pio.c	2011-07-11 19:51:52.000000000 -0400
@@ -372,8 +372,7 @@
 	cp->status = USED;	/* claim free slot */
 
 	DBG(DBG_QUEUE, scmd_printk(KERN_DEBUG, cmd,
-		"eata_pio_queue pid %ld, y %d\n",
-		cmd->serial_number, y));
+		"eata_pio_queue 0x%p, y %d\n", cmd, y));
 
 	cmd->scsi_done = (void *) done;
 
@@ -417,8 +416,8 @@
 	if (eata_pio_send_command(base, EATA_CMD_PIO_SEND_CP)) {
 		cmd->result = DID_BUS_BUSY << 16;
 		scmd_printk(KERN_NOTICE, cmd,
-			"eata_pio_queue pid %ld, HBA busy, "
-			"returning DID_BUS_BUSY, done.\n", cmd->serial_number);
+			"eata_pio_queue pid 0x%p, HBA busy, "
+			"returning DID_BUS_BUSY, done.\n", cmd);
 		done(cmd);
 		cp->status = FREE;
 		return 0;
@@ -432,8 +431,8 @@
 		outw(0, base + HA_RDATA);
 
 	DBG(DBG_QUEUE, scmd_printk(KERN_DEBUG, cmd,
-		"Queued base %#.4lx pid: %ld "
-		"slot %d irq %d\n", sh->base, cmd->serial_number, y, sh->irq));
+		"Queued base %#.4lx cmd: 0x%p "
+		"slot %d irq %d\n", sh->base, cmd, y, sh->irq));
 
 	return 0;
 }
@@ -445,8 +444,7 @@
 	unsigned int loop = 100;
 
 	DBG(DBG_ABNORM, scmd_printk(KERN_WARNING, cmd,
-		"eata_pio_abort called pid: %ld\n",
-		cmd->serial_number));
+		"eata_pio_abort called pid: 0x%p\n", cmd));
 
 	while (inb(cmd->device->host->base + HA_RAUXSTAT) & HA_ABUSY)
 		if (--loop == 0) {
@@ -481,8 +479,7 @@
 	struct Scsi_Host *host = cmd->device->host;
 
 	DBG(DBG_ABNORM, scmd_printk(KERN_WARNING, cmd,
-		"eata_pio_reset called pid:%ld\n",
-		cmd->serial_number));
+		"eata_pio_reset called\n"));
 
 	spin_lock_irq(host->host_lock);
 
@@ -501,7 +498,7 @@
 
 		sp = HD(cmd)->ccb[x].cmd;
 		HD(cmd)->ccb[x].status = RESET;
-		printk(KERN_WARNING "eata_pio_reset: slot %d in reset, pid %ld.\n", x, sp->serial_number);
+		printk(KERN_WARNING "eata_pio_reset: slot %d in reset.\n", x);
 
 		if (sp == NULL)
 			panic("eata_pio_reset: slot %d, sp==NULL.\n", x);
diff -druN linux-2.6.39-libre/drivers/scsi/esp_scsi.c linux-3.0-rc7-libre/drivers/scsi/esp_scsi.c
--- linux-2.6.39-libre/drivers/scsi/esp_scsi.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/scsi/esp_scsi.c	2011-07-11 19:51:52.000000000 -0400
@@ -708,8 +708,7 @@
 	tp = &esp->target[tgt];
 	lp = dev->hostdata;
 
-	list_del(&ent->list);
-	list_add(&ent->list, &esp->active_cmds);
+	list_move(&ent->list, &esp->active_cmds);
 
 	esp->active_cmd = ent;
 
@@ -1059,7 +1058,7 @@
 	esp->ops->send_dma_cmd(esp, esp->command_block_dma,
 			       2, 2, 1, ESP_CMD_DMA | ESP_CMD_TI);
 
-	/* ACK the msssage.  */
+	/* ACK the message.  */
 	scsi_esp_cmd(esp, ESP_CMD_MOK);
 
 	for (i = 0; i < ESP_RESELECT_TAG_LIMIT; i++) {
@@ -1244,8 +1243,7 @@
 		/* Now that the state is unwound properly, put back onto
 		 * the issue queue.  This command is no longer active.
 		 */
-		list_del(&ent->list);
-		list_add(&ent->list, &esp->queued_cmds);
+		list_move(&ent->list, &esp->queued_cmds);
 		esp->active_cmd = NULL;
 
 		/* Return value ignored by caller, it directly invokes
diff -druN linux-2.6.39-libre/drivers/scsi/fcoe/fcoe.c linux-3.0-rc7-libre/drivers/scsi/fcoe/fcoe.c
--- linux-2.6.39-libre/drivers/scsi/fcoe/fcoe.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/scsi/fcoe/fcoe.c	2011-07-11 19:51:52.000000000 -0400
@@ -137,6 +137,7 @@
 static int fcoe_vport_disable(struct fc_vport *, bool disable);
 static void fcoe_set_vport_symbolic_name(struct fc_vport *);
 static void fcoe_set_port_id(struct fc_lport *, u32, struct fc_frame *);
+static int fcoe_validate_vport_create(struct fc_vport *);
 
 static struct libfc_function_template fcoe_libfc_fcn_templ = {
 	.frame_send = fcoe_xmit,
@@ -381,6 +382,42 @@
 }
 
 /**
+ * fcoe_interface_release() - fcoe_port kref release function
+ * @kref: Embedded reference count in an fcoe_interface struct
+ */
+static void fcoe_interface_release(struct kref *kref)
+{
+	struct fcoe_interface *fcoe;
+	struct net_device *netdev;
+
+	fcoe = container_of(kref, struct fcoe_interface, kref);
+	netdev = fcoe->netdev;
+	/* tear-down the FCoE controller */
+	fcoe_ctlr_destroy(&fcoe->ctlr);
+	kfree(fcoe);
+	dev_put(netdev);
+	module_put(THIS_MODULE);
+}
+
+/**
+ * fcoe_interface_get() - Get a reference to a FCoE interface
+ * @fcoe: The FCoE interface to be held
+ */
+static inline void fcoe_interface_get(struct fcoe_interface *fcoe)
+{
+	kref_get(&fcoe->kref);
+}
+
+/**
+ * fcoe_interface_put() - Put a reference to a FCoE interface
+ * @fcoe: The FCoE interface to be released
+ */
+static inline void fcoe_interface_put(struct fcoe_interface *fcoe)
+{
+	kref_put(&fcoe->kref, fcoe_interface_release);
+}
+
+/**
  * fcoe_interface_cleanup() - Clean up a FCoE interface
  * @fcoe: The FCoE interface to be cleaned up
  *
@@ -392,6 +429,21 @@
 	struct fcoe_ctlr *fip = &fcoe->ctlr;
 	u8 flogi_maddr[ETH_ALEN];
 	const struct net_device_ops *ops;
+	struct fcoe_port *port = lport_priv(fcoe->ctlr.lp);
+
+	FCOE_NETDEV_DBG(netdev, "Destroying interface\n");
+
+	/* Logout of the fabric */
+	fc_fabric_logoff(fcoe->ctlr.lp);
+
+	/* Cleanup the fc_lport */
+	fc_lport_destroy(fcoe->ctlr.lp);
+
+	/* Stop the transmit retry timer */
+	del_timer_sync(&port->timer);
+
+	/* Free existing transmit skbs */
+	fcoe_clean_pending_queue(fcoe->ctlr.lp);
 
 	/*
 	 * Don't listen for Ethernet packets anymore.
@@ -414,6 +466,9 @@
 	} else
 		dev_mc_del(netdev, FIP_ALL_ENODE_MACS);
 
+	if (!is_zero_ether_addr(port->data_src_addr))
+		dev_uc_del(netdev, port->data_src_addr);
+
 	/* Tell the LLD we are done w/ FCoE */
 	ops = netdev->netdev_ops;
 	if (ops->ndo_fcoe_disable) {
@@ -421,42 +476,7 @@
 			FCOE_NETDEV_DBG(netdev, "Failed to disable FCoE"
 					" specific feature for LLD.\n");
 	}
-}
-
-/**
- * fcoe_interface_release() - fcoe_port kref release function
- * @kref: Embedded reference count in an fcoe_interface struct
- */
-static void fcoe_interface_release(struct kref *kref)
-{
-	struct fcoe_interface *fcoe;
-	struct net_device *netdev;
-
-	fcoe = container_of(kref, struct fcoe_interface, kref);
-	netdev = fcoe->netdev;
-	/* tear-down the FCoE controller */
-	fcoe_ctlr_destroy(&fcoe->ctlr);
-	kfree(fcoe);
-	dev_put(netdev);
-	module_put(THIS_MODULE);
-}
-
-/**
- * fcoe_interface_get() - Get a reference to a FCoE interface
- * @fcoe: The FCoE interface to be held
- */
-static inline void fcoe_interface_get(struct fcoe_interface *fcoe)
-{
-	kref_get(&fcoe->kref);
-}
-
-/**
- * fcoe_interface_put() - Put a reference to a FCoE interface
- * @fcoe: The FCoE interface to be released
- */
-static inline void fcoe_interface_put(struct fcoe_interface *fcoe)
-{
-	kref_put(&fcoe->kref, fcoe_interface_release);
+	fcoe_interface_put(fcoe);
 }
 
 /**
@@ -821,39 +841,9 @@
  * fcoe_if_destroy() - Tear down a SW FCoE instance
  * @lport: The local port to be destroyed
  *
- * Locking: must be called with the RTNL mutex held and RTNL mutex
- * needed to be dropped by this function since not dropping RTNL
- * would cause circular locking warning on synchronous fip worker
- * cancelling thru fcoe_interface_put invoked by this function.
- *
  */
 static void fcoe_if_destroy(struct fc_lport *lport)
 {
-	struct fcoe_port *port = lport_priv(lport);
-	struct fcoe_interface *fcoe = port->priv;
-	struct net_device *netdev = fcoe->netdev;
-
-	FCOE_NETDEV_DBG(netdev, "Destroying interface\n");
-
-	/* Logout of the fabric */
-	fc_fabric_logoff(lport);
-
-	/* Cleanup the fc_lport */
-	fc_lport_destroy(lport);
-
-	/* Stop the transmit retry timer */
-	del_timer_sync(&port->timer);
-
-	/* Free existing transmit skbs */
-	fcoe_clean_pending_queue(lport);
-
-	if (!is_zero_ether_addr(port->data_src_addr))
-		dev_uc_del(netdev, port->data_src_addr);
-	rtnl_unlock();
-
-	/* receives may not be stopped until after this */
-	fcoe_interface_put(fcoe);
-
 	/* Free queued packets for the per-CPU receive threads */
 	fcoe_percpu_clean(lport);
 
@@ -1783,23 +1773,8 @@
 	int rc = 0;
 
 	mutex_lock(&fcoe_config_mutex);
-#ifdef CONFIG_FCOE_MODULE
-	/*
-	 * Make sure the module has been initialized, and is not about to be
-	 * removed.  Module paramter sysfs files are writable before the
-	 * module_init function is called and after module_exit.
-	 */
-	if (THIS_MODULE->state != MODULE_STATE_LIVE) {
-		rc = -ENODEV;
-		goto out_nodev;
-	}
-#endif
-
-	if (!rtnl_trylock()) {
-		mutex_unlock(&fcoe_config_mutex);
-		return -ERESTARTSYS;
-	}
 
+	rtnl_lock();
 	fcoe = fcoe_hostlist_lookup_port(netdev);
 	rtnl_unlock();
 
@@ -1809,7 +1784,6 @@
 	} else
 		rc = -ENODEV;
 
-out_nodev:
 	mutex_unlock(&fcoe_config_mutex);
 	return rc;
 }
@@ -1828,22 +1802,7 @@
 	int rc = 0;
 
 	mutex_lock(&fcoe_config_mutex);
-#ifdef CONFIG_FCOE_MODULE
-	/*
-	 * Make sure the module has been initialized, and is not about to be
-	 * removed.  Module paramter sysfs files are writable before the
-	 * module_init function is called and after module_exit.
-	 */
-	if (THIS_MODULE->state != MODULE_STATE_LIVE) {
-		rc = -ENODEV;
-		goto out_nodev;
-	}
-#endif
-	if (!rtnl_trylock()) {
-		mutex_unlock(&fcoe_config_mutex);
-		return -ERESTARTSYS;
-	}
-
+	rtnl_lock();
 	fcoe = fcoe_hostlist_lookup_port(netdev);
 	rtnl_unlock();
 
@@ -1852,7 +1811,6 @@
 	else if (!fcoe_link_ok(fcoe->ctlr.lp))
 		fcoe_ctlr_link_up(&fcoe->ctlr);
 
-out_nodev:
 	mutex_unlock(&fcoe_config_mutex);
 	return rc;
 }
@@ -1868,35 +1826,22 @@
 static int fcoe_destroy(struct net_device *netdev)
 {
 	struct fcoe_interface *fcoe;
+	struct fc_lport *lport;
 	int rc = 0;
 
 	mutex_lock(&fcoe_config_mutex);
-#ifdef CONFIG_FCOE_MODULE
-	/*
-	 * Make sure the module has been initialized, and is not about to be
-	 * removed.  Module paramter sysfs files are writable before the
-	 * module_init function is called and after module_exit.
-	 */
-	if (THIS_MODULE->state != MODULE_STATE_LIVE) {
-		rc = -ENODEV;
-		goto out_nodev;
-	}
-#endif
-	if (!rtnl_trylock()) {
-		mutex_unlock(&fcoe_config_mutex);
-		return -ERESTARTSYS;
-	}
-
+	rtnl_lock();
 	fcoe = fcoe_hostlist_lookup_port(netdev);
 	if (!fcoe) {
 		rtnl_unlock();
 		rc = -ENODEV;
 		goto out_nodev;
 	}
-	fcoe_interface_cleanup(fcoe);
+	lport = fcoe->ctlr.lp;
 	list_del(&fcoe->list);
-	/* RTNL mutex is dropped by fcoe_if_destroy */
-	fcoe_if_destroy(fcoe->ctlr.lp);
+	fcoe_interface_cleanup(fcoe);
+	rtnl_unlock();
+	fcoe_if_destroy(lport);
 out_nodev:
 	mutex_unlock(&fcoe_config_mutex);
 	return rc;
@@ -1912,8 +1857,6 @@
 
 	port = container_of(work, struct fcoe_port, destroy_work);
 	mutex_lock(&fcoe_config_mutex);
-	rtnl_lock();
-	/* RTNL mutex is dropped by fcoe_if_destroy */
 	fcoe_if_destroy(port->lport);
 	mutex_unlock(&fcoe_config_mutex);
 }
@@ -1948,23 +1891,7 @@
 	struct fc_lport *lport;
 
 	mutex_lock(&fcoe_config_mutex);
-
-	if (!rtnl_trylock()) {
-		mutex_unlock(&fcoe_config_mutex);
-		return -ERESTARTSYS;
-	}
-
-#ifdef CONFIG_FCOE_MODULE
-	/*
-	 * Make sure the module has been initialized, and is not about to be
-	 * removed.  Module paramter sysfs files are writable before the
-	 * module_init function is called and after module_exit.
-	 */
-	if (THIS_MODULE->state != MODULE_STATE_LIVE) {
-		rc = -ENODEV;
-		goto out_nodev;
-	}
-#endif
+	rtnl_lock();
 
 	/* look for existing lport */
 	if (fcoe_hostlist_lookup(netdev)) {
@@ -2026,7 +1953,7 @@
 int fcoe_link_speed_update(struct fc_lport *lport)
 {
 	struct net_device *netdev = fcoe_netdev(lport);
-	struct ethtool_cmd ecmd = { ETHTOOL_GSET };
+	struct ethtool_cmd ecmd;
 
 	if (!dev_ethtool_get_settings(netdev, &ecmd)) {
 		lport->link_supported_speeds &=
@@ -2037,11 +1964,14 @@
 		if (ecmd.supported & SUPPORTED_10000baseT_Full)
 			lport->link_supported_speeds |=
 				FC_PORTSPEED_10GBIT;
-		if (ecmd.speed == SPEED_1000)
+		switch (ethtool_cmd_speed(&ecmd)) {
+		case SPEED_1000:
 			lport->link_speed = FC_PORTSPEED_1GBIT;
-		if (ecmd.speed == SPEED_10000)
+			break;
+		case SPEED_10000:
 			lport->link_speed = FC_PORTSPEED_10GBIT;
-
+			break;
+		}
 		return 0;
 	}
 	return -1;
@@ -2422,6 +2352,17 @@
 	struct fcoe_interface *fcoe = port->priv;
 	struct net_device *netdev = fcoe->netdev;
 	struct fc_lport *vn_port;
+	int rc;
+	char buf[32];
+
+	rc = fcoe_validate_vport_create(vport);
+	if (rc) {
+		wwn_to_str(vport->port_name, buf, sizeof(buf));
+		printk(KERN_ERR "fcoe: Failed to create vport, "
+			"WWPN (0x%s) already exists\n",
+			buf);
+		return rc;
+	}
 
 	mutex_lock(&fcoe_config_mutex);
 	vn_port = fcoe_if_create(fcoe, &vport->dev, 1);
@@ -2568,3 +2509,49 @@
 	if (fp && fc_frame_payload_op(fp) == ELS_FLOGI)
 		fcoe_ctlr_recv_flogi(&fcoe->ctlr, lport, fp);
 }
+
+/**
+ * fcoe_validate_vport_create() - Validate a vport before creating it
+ * @vport: NPIV port to be created
+ *
+ * This routine is meant to add validation for a vport before creating it
+ * via fcoe_vport_create().
+ * Current validations are:
+ *      - WWPN supplied is unique for given lport
+ *
+ *
+*/
+static int fcoe_validate_vport_create(struct fc_vport *vport)
+{
+	struct Scsi_Host *shost = vport_to_shost(vport);
+	struct fc_lport *n_port = shost_priv(shost);
+	struct fc_lport *vn_port;
+	int rc = 0;
+	char buf[32];
+
+	mutex_lock(&n_port->lp_mutex);
+
+	wwn_to_str(vport->port_name, buf, sizeof(buf));
+	/* Check if the wwpn is not same as that of the lport */
+	if (!memcmp(&n_port->wwpn, &vport->port_name, sizeof(u64))) {
+		FCOE_DBG("vport WWPN 0x%s is same as that of the "
+			"base port WWPN\n", buf);
+		rc = -EINVAL;
+		goto out;
+	}
+
+	/* Check if there is any existing vport with same wwpn */
+	list_for_each_entry(vn_port, &n_port->vports, list) {
+		if (!memcmp(&vn_port->wwpn, &vport->port_name, sizeof(u64))) {
+			FCOE_DBG("vport with given WWPN 0x%s already "
+			"exists\n", buf);
+			rc = -EINVAL;
+			break;
+		}
+	}
+
+out:
+	mutex_unlock(&n_port->lp_mutex);
+
+	return rc;
+}
diff -druN linux-2.6.39-libre/drivers/scsi/fcoe/fcoe_ctlr.c linux-3.0-rc7-libre/drivers/scsi/fcoe/fcoe_ctlr.c
--- linux-2.6.39-libre/drivers/scsi/fcoe/fcoe_ctlr.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/scsi/fcoe/fcoe_ctlr.c	2011-07-11 19:51:52.000000000 -0400
@@ -978,10 +978,8 @@
 	 * the FCF that answers multicast solicitations, not the others that
 	 * are sending periodic multicast advertisements.
 	 */
-	if (mtu_valid) {
-		list_del(&fcf->list);
-		list_add(&fcf->list, &fip->fcfs);
-	}
+	if (mtu_valid)
+		list_move(&fcf->list, &fip->fcfs);
 
 	/*
 	 * If this is the first validated FCF, note the time and
@@ -1175,7 +1173,9 @@
 	struct fc_lport *lport = fip->lp;
 	struct fc_lport *vn_port = NULL;
 	u32 desc_mask;
-	int is_vn_port = 0;
+	int num_vlink_desc;
+	int reset_phys_port = 0;
+	struct fip_vn_desc **vlink_desc_arr = NULL;
 
 	LIBFCOE_FIP_DBG(fip, "Clear Virtual Link received\n");
 
@@ -1185,70 +1185,73 @@
 	/*
 	 * mask of required descriptors.  Validating each one clears its bit.
 	 */
-	desc_mask = BIT(FIP_DT_MAC) | BIT(FIP_DT_NAME) | BIT(FIP_DT_VN_ID);
+	desc_mask = BIT(FIP_DT_MAC) | BIT(FIP_DT_NAME);
 
 	rlen = ntohs(fh->fip_dl_len) * FIP_BPW;
 	desc = (struct fip_desc *)(fh + 1);
+
+	/*
+	 * Actually need to subtract 'sizeof(*mp) - sizeof(*wp)' from 'rlen'
+	 * before determining max Vx_Port descriptor but a buggy FCF could have
+	 * omited either or both MAC Address and Name Identifier descriptors
+	 */
+	num_vlink_desc = rlen / sizeof(*vp);
+	if (num_vlink_desc)
+		vlink_desc_arr = kmalloc(sizeof(vp) * num_vlink_desc,
+					 GFP_ATOMIC);
+	if (!vlink_desc_arr)
+		return;
+	num_vlink_desc = 0;
+
 	while (rlen >= sizeof(*desc)) {
 		dlen = desc->fip_dlen * FIP_BPW;
 		if (dlen > rlen)
-			return;
+			goto err;
 		/* Drop CVL if there are duplicate critical descriptors */
 		if ((desc->fip_dtype < 32) &&
+		    (desc->fip_dtype != FIP_DT_VN_ID) &&
 		    !(desc_mask & 1U << desc->fip_dtype)) {
 			LIBFCOE_FIP_DBG(fip, "Duplicate Critical "
 					"Descriptors in FIP CVL\n");
-			return;
+			goto err;
 		}
 		switch (desc->fip_dtype) {
 		case FIP_DT_MAC:
 			mp = (struct fip_mac_desc *)desc;
 			if (dlen < sizeof(*mp))
-				return;
+				goto err;
 			if (compare_ether_addr(mp->fd_mac, fcf->fcf_mac))
-				return;
+				goto err;
 			desc_mask &= ~BIT(FIP_DT_MAC);
 			break;
 		case FIP_DT_NAME:
 			wp = (struct fip_wwn_desc *)desc;
 			if (dlen < sizeof(*wp))
-				return;
+				goto err;
 			if (get_unaligned_be64(&wp->fd_wwn) != fcf->switch_name)
-				return;
+				goto err;
 			desc_mask &= ~BIT(FIP_DT_NAME);
 			break;
 		case FIP_DT_VN_ID:
 			vp = (struct fip_vn_desc *)desc;
 			if (dlen < sizeof(*vp))
-				return;
-			if (compare_ether_addr(vp->fd_mac,
-					       fip->get_src_addr(lport)) == 0 &&
-			    get_unaligned_be64(&vp->fd_wwpn) == lport->wwpn &&
-			    ntoh24(vp->fd_fc_id) == lport->port_id) {
-				desc_mask &= ~BIT(FIP_DT_VN_ID);
-				break;
-			}
-			/* check if clr_vlink is for NPIV port */
-			mutex_lock(&lport->lp_mutex);
-			list_for_each_entry(vn_port, &lport->vports, list) {
-				if (compare_ether_addr(vp->fd_mac,
-				    fip->get_src_addr(vn_port)) == 0 &&
-				    (get_unaligned_be64(&vp->fd_wwpn)
-							== vn_port->wwpn) &&
-				    (ntoh24(vp->fd_fc_id) ==
-					    fc_host_port_id(vn_port->host))) {
-					desc_mask &= ~BIT(FIP_DT_VN_ID);
-					is_vn_port = 1;
-					break;
-				}
+				goto err;
+			vlink_desc_arr[num_vlink_desc++] = vp;
+			vn_port = fc_vport_id_lookup(lport,
+						      ntoh24(vp->fd_fc_id));
+			if (vn_port && (vn_port == lport)) {
+				mutex_lock(&fip->ctlr_mutex);
+				per_cpu_ptr(lport->dev_stats,
+					    get_cpu())->VLinkFailureCount++;
+				put_cpu();
+				fcoe_ctlr_reset(fip);
+				mutex_unlock(&fip->ctlr_mutex);
 			}
-			mutex_unlock(&lport->lp_mutex);
-
 			break;
 		default:
 			/* standard says ignore unknown descriptors >= 128 */
 			if (desc->fip_dtype < FIP_DT_VENDOR_BASE)
-				return;
+				goto err;
 			break;
 		}
 		desc = (struct fip_desc *)((char *)desc + dlen);
@@ -1258,26 +1261,68 @@
 	/*
 	 * reset only if all required descriptors were present and valid.
 	 */
-	if (desc_mask) {
+	if (desc_mask)
 		LIBFCOE_FIP_DBG(fip, "missing descriptors mask %x\n",
 				desc_mask);
+	else if (!num_vlink_desc) {
+		LIBFCOE_FIP_DBG(fip, "CVL: no Vx_Port descriptor found\n");
+		/*
+		 * No Vx_Port description. Clear all NPIV ports,
+		 * followed by physical port
+		 */
+		mutex_lock(&lport->lp_mutex);
+		list_for_each_entry(vn_port, &lport->vports, list)
+			fc_lport_reset(vn_port);
+		mutex_unlock(&lport->lp_mutex);
+
+		mutex_lock(&fip->ctlr_mutex);
+		per_cpu_ptr(lport->dev_stats,
+			    get_cpu())->VLinkFailureCount++;
+		put_cpu();
+		fcoe_ctlr_reset(fip);
+		mutex_unlock(&fip->ctlr_mutex);
+
+		fc_lport_reset(fip->lp);
+		fcoe_ctlr_solicit(fip, NULL);
 	} else {
+		int i;
+
 		LIBFCOE_FIP_DBG(fip, "performing Clear Virtual Link\n");
+		for (i = 0; i < num_vlink_desc; i++) {
+			vp = vlink_desc_arr[i];
+			vn_port = fc_vport_id_lookup(lport,
+						     ntoh24(vp->fd_fc_id));
+			if (!vn_port)
+				continue;
 
-		if (is_vn_port)
-			fc_lport_reset(vn_port);
-		else {
-			mutex_lock(&fip->ctlr_mutex);
-			per_cpu_ptr(lport->dev_stats,
-				    get_cpu())->VLinkFailureCount++;
-			put_cpu();
-			fcoe_ctlr_reset(fip);
-			mutex_unlock(&fip->ctlr_mutex);
+			/*
+			 * 'port_id' is already validated, check MAC address and
+			 * wwpn
+			 */
+			if (compare_ether_addr(fip->get_src_addr(vn_port),
+						vp->fd_mac) != 0 ||
+				get_unaligned_be64(&vp->fd_wwpn) !=
+							vn_port->wwpn)
+				continue;
 
+			if (vn_port == lport)
+				/*
+				 * Physical port, defer processing till all
+				 * listed NPIV ports are cleared
+				 */
+				reset_phys_port = 1;
+			else    /* NPIV port */
+				fc_lport_reset(vn_port);
+		}
+
+		if (reset_phys_port) {
 			fc_lport_reset(fip->lp);
 			fcoe_ctlr_solicit(fip, NULL);
 		}
 	}
+
+err:
+	kfree(vlink_desc_arr);
 }
 
 /**
diff -druN linux-2.6.39-libre/drivers/scsi/fcoe/fcoe.h linux-3.0-rc7-libre/drivers/scsi/fcoe/fcoe.h
--- linux-2.6.39-libre/drivers/scsi/fcoe/fcoe.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/scsi/fcoe/fcoe.h	2011-07-11 19:51:52.000000000 -0400
@@ -99,4 +99,14 @@
 			((struct fcoe_port *)lport_priv(lport))->priv)->netdev;
 }
 
+static inline void wwn_to_str(u64 wwn, char *buf, int len)
+{
+	u8 wwpn[8];
+
+	u64_to_wwn(wwn, wwpn);
+	snprintf(buf, len, "%02x%02x%02x%02x%02x%02x%02x%02x",
+		wwpn[0], wwpn[1], wwpn[2], wwpn[3],
+		wwpn[4], wwpn[5], wwpn[6], wwpn[7]);
+}
+
 #endif /* _FCOE_H_ */
diff -druN linux-2.6.39-libre/drivers/scsi/fcoe/fcoe_transport.c linux-3.0-rc7-libre/drivers/scsi/fcoe/fcoe_transport.c
--- linux-2.6.39-libre/drivers/scsi/fcoe/fcoe_transport.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/scsi/fcoe/fcoe_transport.c	2011-07-11 19:51:52.000000000 -0400
@@ -335,7 +335,7 @@
 EXPORT_SYMBOL(fcoe_transport_attach);
 
 /**
- * fcoe_transport_attach - Detaches an FCoE transport
+ * fcoe_transport_detach - Detaches an FCoE transport
  * @ft: The fcoe transport to be attached
  *
  * Returns : 0 for success
@@ -343,6 +343,7 @@
 int fcoe_transport_detach(struct fcoe_transport *ft)
 {
 	int rc = 0;
+	struct fcoe_netdev_mapping *nm = NULL, *tmp;
 
 	mutex_lock(&ft_mutex);
 	if (!ft->attached) {
@@ -352,6 +353,19 @@
 		goto out_attach;
 	}
 
+	/* remove netdev mapping for this transport as it is going away */
+	mutex_lock(&fn_mutex);
+	list_for_each_entry_safe(nm, tmp, &fcoe_netdevs, list) {
+		if (nm->ft == ft) {
+			LIBFCOE_TRANSPORT_DBG("transport %s going away, "
+				"remove its netdev mapping for %s\n",
+				ft->name, nm->netdev->name);
+			list_del(&nm->list);
+			kfree(nm);
+		}
+	}
+	mutex_unlock(&fn_mutex);
+
 	list_del(&ft->list);
 	ft->attached = false;
 	LIBFCOE_TRANSPORT_DBG("detaching transport %s\n", ft->name);
@@ -371,9 +385,9 @@
 	i = j = sprintf(buffer, "Attached FCoE transports:");
 	mutex_lock(&ft_mutex);
 	list_for_each_entry(ft, &fcoe_transports, list) {
-		i += snprintf(&buffer[i], IFNAMSIZ, "%s ", ft->name);
-		if (i >= PAGE_SIZE)
+		if (i >= PAGE_SIZE - IFNAMSIZ)
 			break;
+		i += snprintf(&buffer[i], IFNAMSIZ, "%s ", ft->name);
 	}
 	mutex_unlock(&ft_mutex);
 	if (i == j)
@@ -530,18 +544,7 @@
 	struct fcoe_transport *ft = NULL;
 	enum fip_state fip_mode = (enum fip_state)(long)kp->arg;
 
-	if (!mutex_trylock(&ft_mutex))
-		return restart_syscall();
-
-#ifdef CONFIG_LIBFCOE_MODULE
-	/*
-	 * Make sure the module has been initialized, and is not about to be
-	 * removed.  Module parameter sysfs files are writable before the
-	 * module_init function is called and after module_exit.
-	 */
-	if (THIS_MODULE->state != MODULE_STATE_LIVE)
-		goto out_nodev;
-#endif
+	mutex_lock(&ft_mutex);
 
 	netdev = fcoe_if_to_netdev(buffer);
 	if (!netdev) {
@@ -586,10 +589,7 @@
 	dev_put(netdev);
 out_nodev:
 	mutex_unlock(&ft_mutex);
-	if (rc == -ERESTARTSYS)
-		return restart_syscall();
-	else
-		return rc;
+	return rc;
 }
 
 /**
@@ -608,18 +608,7 @@
 	struct net_device *netdev = NULL;
 	struct fcoe_transport *ft = NULL;
 
-	if (!mutex_trylock(&ft_mutex))
-		return restart_syscall();
-
-#ifdef CONFIG_LIBFCOE_MODULE
-	/*
-	 * Make sure the module has been initialized, and is not about to be
-	 * removed.  Module parameter sysfs files are writable before the
-	 * module_init function is called and after module_exit.
-	 */
-	if (THIS_MODULE->state != MODULE_STATE_LIVE)
-		goto out_nodev;
-#endif
+	mutex_lock(&ft_mutex);
 
 	netdev = fcoe_if_to_netdev(buffer);
 	if (!netdev) {
@@ -645,11 +634,7 @@
 	dev_put(netdev);
 out_nodev:
 	mutex_unlock(&ft_mutex);
-
-	if (rc == -ERESTARTSYS)
-		return restart_syscall();
-	else
-		return rc;
+	return rc;
 }
 
 /**
@@ -667,18 +652,7 @@
 	struct net_device *netdev = NULL;
 	struct fcoe_transport *ft = NULL;
 
-	if (!mutex_trylock(&ft_mutex))
-		return restart_syscall();
-
-#ifdef CONFIG_LIBFCOE_MODULE
-	/*
-	 * Make sure the module has been initialized, and is not about to be
-	 * removed.  Module parameter sysfs files are writable before the
-	 * module_init function is called and after module_exit.
-	 */
-	if (THIS_MODULE->state != MODULE_STATE_LIVE)
-		goto out_nodev;
-#endif
+	mutex_lock(&ft_mutex);
 
 	netdev = fcoe_if_to_netdev(buffer);
 	if (!netdev)
@@ -716,18 +690,7 @@
 	struct net_device *netdev = NULL;
 	struct fcoe_transport *ft = NULL;
 
-	if (!mutex_trylock(&ft_mutex))
-		return restart_syscall();
-
-#ifdef CONFIG_LIBFCOE_MODULE
-	/*
-	 * Make sure the module has been initialized, and is not about to be
-	 * removed.  Module parameter sysfs files are writable before the
-	 * module_init function is called and after module_exit.
-	 */
-	if (THIS_MODULE->state != MODULE_STATE_LIVE)
-		goto out_nodev;
-#endif
+	mutex_lock(&ft_mutex);
 
 	netdev = fcoe_if_to_netdev(buffer);
 	if (!netdev)
@@ -743,10 +706,7 @@
 	dev_put(netdev);
 out_nodev:
 	mutex_unlock(&ft_mutex);
-	if (rc == -ERESTARTSYS)
-		return restart_syscall();
-	else
-		return rc;
+	return rc;
 }
 
 /**
diff -druN linux-2.6.39-libre/drivers/scsi/hpsa.c linux-3.0-rc7-libre/drivers/scsi/hpsa.c
--- linux-2.6.39-libre/drivers/scsi/hpsa.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/scsi/hpsa.c	2011-07-11 19:51:52.000000000 -0400
@@ -273,7 +273,7 @@
 			"performant" : "simple");
 }
 
-/* List of controllers which cannot be reset on kexec with reset_devices */
+/* List of controllers which cannot be hard reset on kexec with reset_devices */
 static u32 unresettable_controller[] = {
 	0x324a103C, /* Smart Array P712m */
 	0x324b103C, /* SmartArray P711m */
@@ -291,16 +291,45 @@
 	0x409D0E11, /* Smart Array 6400 EM */
 };
 
-static int ctlr_is_resettable(struct ctlr_info *h)
+/* List of controllers which cannot even be soft reset */
+static u32 soft_unresettable_controller[] = {
+	/* Exclude 640x boards.  These are two pci devices in one slot
+	 * which share a battery backed cache module.  One controls the
+	 * cache, the other accesses the cache through the one that controls
+	 * it.  If we reset the one controlling the cache, the other will
+	 * likely not be happy.  Just forbid resetting this conjoined mess.
+	 * The 640x isn't really supported by hpsa anyway.
+	 */
+	0x409C0E11, /* Smart Array 6400 */
+	0x409D0E11, /* Smart Array 6400 EM */
+};
+
+static int ctlr_is_hard_resettable(u32 board_id)
 {
 	int i;
 
 	for (i = 0; i < ARRAY_SIZE(unresettable_controller); i++)
-		if (unresettable_controller[i] == h->board_id)
+		if (unresettable_controller[i] == board_id)
+			return 0;
+	return 1;
+}
+
+static int ctlr_is_soft_resettable(u32 board_id)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(soft_unresettable_controller); i++)
+		if (soft_unresettable_controller[i] == board_id)
 			return 0;
 	return 1;
 }
 
+static int ctlr_is_resettable(u32 board_id)
+{
+	return ctlr_is_hard_resettable(board_id) ||
+		ctlr_is_soft_resettable(board_id);
+}
+
 static ssize_t host_show_resettable(struct device *dev,
 	struct device_attribute *attr, char *buf)
 {
@@ -308,7 +337,7 @@
 	struct Scsi_Host *shost = class_to_shost(dev);
 
 	h = shost_to_hba(shost);
-	return snprintf(buf, 20, "%d\n", ctlr_is_resettable(h));
+	return snprintf(buf, 20, "%d\n", ctlr_is_resettable(h->board_id));
 }
 
 static inline int is_logical_dev_addr_mode(unsigned char scsi3addr[])
@@ -929,13 +958,6 @@
 	/* nothing to do. */
 }
 
-static void hpsa_scsi_setup(struct ctlr_info *h)
-{
-	h->ndevices = 0;
-	h->scsi_host = NULL;
-	spin_lock_init(&h->devlock);
-}
-
 static void hpsa_free_sg_chain_blocks(struct ctlr_info *h)
 {
 	int i;
@@ -1006,8 +1028,7 @@
 	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)
+static void complete_scsi_command(struct CommandList *cp)
 {
 	struct scsi_cmnd *cmd;
 	struct ctlr_info *h;
@@ -1016,6 +1037,7 @@
 	unsigned char sense_key;
 	unsigned char asc;      /* additional sense code */
 	unsigned char ascq;     /* additional sense code qualifier */
+	unsigned long sense_data_size;
 
 	ei = cp->err_info;
 	cmd = (struct scsi_cmnd *) cp->scsi_cmd;
@@ -1030,10 +1052,14 @@
 	cmd->result |= ei->ScsiStatus;
 
 	/* copy the sense data whether we need to or not. */
-	memcpy(cmd->sense_buffer, ei->SenseInfo,
-		ei->SenseLen > SCSI_SENSE_BUFFERSIZE ?
-			SCSI_SENSE_BUFFERSIZE :
-			ei->SenseLen);
+	if (SCSI_SENSE_BUFFERSIZE < sizeof(ei->SenseInfo))
+		sense_data_size = SCSI_SENSE_BUFFERSIZE;
+	else
+		sense_data_size = sizeof(ei->SenseInfo);
+	if (ei->SenseLen < sense_data_size)
+		sense_data_size = ei->SenseLen;
+
+	memcpy(cmd->sense_buffer, ei->SenseInfo, sense_data_size);
 	scsi_set_resid(cmd, ei->ResidualCnt);
 
 	if (ei->CommandStatus == 0) {
@@ -1308,7 +1334,7 @@
 	int retry_count = 0;
 
 	do {
-		memset(c->err_info, 0, sizeof(c->err_info));
+		memset(c->err_info, 0, sizeof(*c->err_info));
 		hpsa_scsi_do_simple_cmd_core(h, c);
 		retry_count++;
 	} while (check_for_unit_attention(h, c) && retry_count <= 3);
@@ -1570,6 +1596,7 @@
 	"MSA2024",
 	"MSA2312",
 	"MSA2324",
+	"P2000 G3 SAS",
 	NULL,
 };
 
@@ -2558,7 +2585,8 @@
 		c->SG[0].Ext = 0; /* we are not chaining*/
 	}
 	hpsa_scsi_do_simple_cmd_core(h, c);
-	hpsa_pci_unmap(h->pdev, c, 1, PCI_DMA_BIDIRECTIONAL);
+	if (iocommand.buf_size > 0)
+		hpsa_pci_unmap(h->pdev, c, 1, PCI_DMA_BIDIRECTIONAL);
 	check_ioctl_unit_attention(h, c);
 
 	/* Copy the error information out */
@@ -2751,6 +2779,26 @@
 	}
 }
 
+static int __devinit hpsa_send_host_reset(struct ctlr_info *h,
+	unsigned char *scsi3addr, u8 reset_type)
+{
+	struct CommandList *c;
+
+	c = cmd_alloc(h);
+	if (!c)
+		return -ENOMEM;
+	fill_cmd(c, HPSA_DEVICE_RESET_MSG, h, NULL, 0, 0,
+		RAID_CTLR_LUNID, TYPE_MSG);
+	c->Request.CDB[1] = reset_type; /* fill_cmd defaults to target reset */
+	c->waiting = NULL;
+	enqueue_cmd_and_start_io(h, c);
+	/* Don't wait for completion, the reset won't complete.  Don't free
+	 * the command either.  This is the last command we will send before
+	 * re-initializing everything, so it doesn't matter and won't leak.
+	 */
+	return 0;
+}
+
 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)
@@ -2828,7 +2876,8 @@
 			c->Request.Type.Attribute = ATTR_SIMPLE;
 			c->Request.Type.Direction = XFER_NONE;
 			c->Request.Timeout = 0; /* Don't time out */
-			c->Request.CDB[0] =  0x01; /* RESET_MSG is 0x01 */
+			memset(&c->Request.CDB[0], 0, sizeof(c->Request.CDB));
+			c->Request.CDB[0] =  cmd;
 			c->Request.CDB[1] = 0x03;  /* Reset target above */
 			/* If bytes 4-7 are zero, it means reset the */
 			/* LunID device */
@@ -2936,7 +2985,7 @@
 {
 	removeQ(c);
 	if (likely(c->cmd_type == CMD_SCSI))
-		complete_scsi_command(c, 0, raw_tag);
+		complete_scsi_command(c);
 	else if (c->cmd_type == CMD_IOCTL_PEND)
 		complete(c->waiting);
 }
@@ -2994,6 +3043,63 @@
 	return next_command(h);
 }
 
+/* Some controllers, like p400, will give us one interrupt
+ * after a soft reset, even if we turned interrupts off.
+ * Only need to check for this in the hpsa_xxx_discard_completions
+ * functions.
+ */
+static int ignore_bogus_interrupt(struct ctlr_info *h)
+{
+	if (likely(!reset_devices))
+		return 0;
+
+	if (likely(h->interrupts_enabled))
+		return 0;
+
+	dev_info(&h->pdev->dev, "Received interrupt while interrupts disabled "
+		"(known firmware bug.)  Ignoring.\n");
+
+	return 1;
+}
+
+static irqreturn_t hpsa_intx_discard_completions(int irq, void *dev_id)
+{
+	struct ctlr_info *h = dev_id;
+	unsigned long flags;
+	u32 raw_tag;
+
+	if (ignore_bogus_interrupt(h))
+		return IRQ_NONE;
+
+	if (interrupt_not_for_us(h))
+		return IRQ_NONE;
+	spin_lock_irqsave(&h->lock, flags);
+	while (interrupt_pending(h)) {
+		raw_tag = get_next_completion(h);
+		while (raw_tag != FIFO_EMPTY)
+			raw_tag = next_command(h);
+	}
+	spin_unlock_irqrestore(&h->lock, flags);
+	return IRQ_HANDLED;
+}
+
+static irqreturn_t hpsa_msix_discard_completions(int irq, void *dev_id)
+{
+	struct ctlr_info *h = dev_id;
+	unsigned long flags;
+	u32 raw_tag;
+
+	if (ignore_bogus_interrupt(h))
+		return IRQ_NONE;
+
+	spin_lock_irqsave(&h->lock, flags);
+	raw_tag = get_next_completion(h);
+	while (raw_tag != FIFO_EMPTY)
+		raw_tag = next_command(h);
+	spin_unlock_irqrestore(&h->lock, flags);
+	return IRQ_HANDLED;
+}
+
 static irqreturn_t do_hpsa_intr_intx(int irq, void *dev_id)
 {
 	struct ctlr_info *h = dev_id;
@@ -3132,11 +3238,10 @@
 	return 0;
 }
 
-#define hpsa_soft_reset_controller(p) hpsa_message(p, 1, 0)
 #define hpsa_noop(p) hpsa_message(p, 3, 0)
 
 static int hpsa_controller_hard_reset(struct pci_dev *pdev,
-	void * __iomem vaddr, bool use_doorbell)
+	void * __iomem vaddr, u32 use_doorbell)
 {
 	u16 pmcsr;
 	int pos;
@@ -3147,8 +3252,7 @@
 		 * other way using the doorbell register.
 		 */
 		dev_info(&pdev->dev, "using doorbell to reset controller\n");
-		writel(DOORBELL_CTLR_RESET, vaddr + SA5_DOORBELL);
-		msleep(1000);
+		writel(use_doorbell, vaddr + SA5_DOORBELL);
 	} else { /* Try to do it the PCI power state way */
 
 		/* Quoting from the Open CISS Specification: "The Power
@@ -3179,12 +3283,63 @@
 		pmcsr &= ~PCI_PM_CTRL_STATE_MASK;
 		pmcsr |= PCI_D0;
 		pci_write_config_word(pdev, pos + PCI_PM_CTRL, pmcsr);
-
-		msleep(500);
 	}
 	return 0;
 }
 
+static __devinit void init_driver_version(char *driver_version, int len)
+{
+	memset(driver_version, 0, len);
+	strncpy(driver_version, "hpsa " HPSA_DRIVER_VERSION, len - 1);
+}
+
+static __devinit int write_driver_ver_to_cfgtable(
+	struct CfgTable __iomem *cfgtable)
+{
+	char *driver_version;
+	int i, size = sizeof(cfgtable->driver_version);
+
+	driver_version = kmalloc(size, GFP_KERNEL);
+	if (!driver_version)
+		return -ENOMEM;
+
+	init_driver_version(driver_version, size);
+	for (i = 0; i < size; i++)
+		writeb(driver_version[i], &cfgtable->driver_version[i]);
+	kfree(driver_version);
+	return 0;
+}
+
+static __devinit void read_driver_ver_from_cfgtable(
+	struct CfgTable __iomem *cfgtable, unsigned char *driver_ver)
+{
+	int i;
+
+	for (i = 0; i < sizeof(cfgtable->driver_version); i++)
+		driver_ver[i] = readb(&cfgtable->driver_version[i]);
+}
+
+static __devinit int controller_reset_failed(
+	struct CfgTable __iomem *cfgtable)
+{
+
+	char *driver_ver, *old_driver_ver;
+	int rc, size = sizeof(cfgtable->driver_version);
+
+	old_driver_ver = kmalloc(2 * size, GFP_KERNEL);
+	if (!old_driver_ver)
+		return -ENOMEM;
+	driver_ver = old_driver_ver + size;
+
+	/* After a reset, the 32 bytes of "driver version" in the cfgtable
+	 * should have been changed, otherwise we know the reset failed.
+	 */
+	init_driver_version(old_driver_ver, size);
+	read_driver_ver_from_cfgtable(cfgtable, driver_ver);
+	rc = !memcmp(driver_ver, old_driver_ver, size);
+	kfree(old_driver_ver);
+	return rc;
+}
 /* This does a hard reset of the controller using PCI power management
  * states or the using the doorbell register.
  */
@@ -3195,10 +3350,10 @@
 	u64 cfg_base_addr_index;
 	void __iomem *vaddr;
 	unsigned long paddr;
-	u32 misc_fw_support, active_transport;
+	u32 misc_fw_support;
 	int rc;
 	struct CfgTable __iomem *cfgtable;
-	bool use_doorbell;
+	u32 use_doorbell;
 	u32 board_id;
 	u16 command_register;
 
@@ -3215,20 +3370,15 @@
 	 * using the doorbell register.
 	 */
 
-	/* Exclude 640x boards.  These are two pci devices in one slot
-	 * which share a battery backed cache module.  One controls the
-	 * cache, the other accesses the cache through the one that controls
-	 * it.  If we reset the one controlling the cache, the other will
-	 * likely not be happy.  Just forbid resetting this conjoined mess.
-	 * The 640x isn't really supported by hpsa anyway.
-	 */
 	rc = hpsa_lookup_board_id(pdev, &board_id);
-	if (rc < 0) {
+	if (rc < 0 || !ctlr_is_resettable(board_id)) {
 		dev_warn(&pdev->dev, "Not resetting device.\n");
 		return -ENODEV;
 	}
-	if (board_id == 0x409C0E11 || board_id == 0x409D0E11)
-		return -ENOTSUPP;
+
+	/* if controller is soft- but not hard resettable... */
+	if (!ctlr_is_hard_resettable(board_id))
+		return -ENOTSUPP; /* try soft reset later. */
 
 	/* Save the PCI command register */
 	pci_read_config_word(pdev, 4, &command_register);
@@ -3257,10 +3407,28 @@
 		rc = -ENOMEM;
 		goto unmap_vaddr;
 	}
+	rc = write_driver_ver_to_cfgtable(cfgtable);
+	if (rc)
+		goto unmap_vaddr;
 
-	/* If reset via doorbell register is supported, use that. */
+	/* If reset via doorbell register is supported, use that.
+	 * There are two such methods.  Favor the newest method.
+	 */
 	misc_fw_support = readl(&cfgtable->misc_fw_support);
-	use_doorbell = misc_fw_support & MISC_FW_DOORBELL_RESET;
+	use_doorbell = misc_fw_support & MISC_FW_DOORBELL_RESET2;
+	if (use_doorbell) {
+		use_doorbell = DOORBELL_CTLR_RESET2;
+	} else {
+		use_doorbell = misc_fw_support & MISC_FW_DOORBELL_RESET;
+		if (use_doorbell) {
+			dev_warn(&pdev->dev, "Controller claims that "
+				"'Bit 2 doorbell reset' is "
+				"supported, but not 'bit 5 doorbell reset'.  "
+				"Firmware update is recommended.\n");
+			rc = -ENOTSUPP; /* try soft reset */
+			goto unmap_cfgtable;
+		}
+	}
 
 	rc = hpsa_controller_hard_reset(pdev, vaddr, use_doorbell);
 	if (rc)
@@ -3279,30 +3447,32 @@
 	msleep(HPSA_POST_RESET_PAUSE_MSECS);
 
 	/* Wait for board to become not ready, then ready. */
-	dev_info(&pdev->dev, "Waiting for board to become ready.\n");
+	dev_info(&pdev->dev, "Waiting for board to reset.\n");
 	rc = hpsa_wait_for_board_state(pdev, vaddr, BOARD_NOT_READY);
-	if (rc)
+	if (rc) {
 		dev_warn(&pdev->dev,
-			"failed waiting for board to become not ready\n");
+			"failed waiting for board to reset."
+			" Will try soft reset.\n");
+		rc = -ENOTSUPP; /* Not expected, but try soft reset later */
+		goto unmap_cfgtable;
+	}
 	rc = hpsa_wait_for_board_state(pdev, vaddr, BOARD_READY);
 	if (rc) {
 		dev_warn(&pdev->dev,
-			"failed waiting for board to become ready\n");
+			"failed waiting for board to become ready "
+			"after hard reset\n");
 		goto unmap_cfgtable;
 	}
-	dev_info(&pdev->dev, "board ready.\n");
 
-	/* Controller should be in simple mode at this point.  If it's not,
-	 * It means we're on one of those controllers which doesn't support
-	 * the doorbell reset method and on which the PCI power management reset
-	 * method doesn't work (P800, for example.)
-	 * In those cases, don't try to proceed, as it generally doesn't work.
-	 */
-	active_transport = readl(&cfgtable->TransportActive);
-	if (active_transport & PERFORMANT_MODE) {
-		dev_warn(&pdev->dev, "Unable to successfully reset controller,"
-			" Ignoring controller.\n");
-		rc = -ENODEV;
+	rc = controller_reset_failed(vaddr);
+	if (rc < 0)
+		goto unmap_cfgtable;
+	if (rc) {
+		dev_warn(&pdev->dev, "Unable to successfully reset "
+			"controller. Will try soft reset.\n");
+		rc = -ENOTSUPP;
+	} else {
+		dev_info(&pdev->dev, "board ready after hard reset.\n");
 	}
 
 unmap_cfgtable:
@@ -3543,6 +3713,9 @@
 		       cfg_base_addr_index) + cfg_offset, sizeof(*h->cfgtable));
 	if (!h->cfgtable)
 		return -ENOMEM;
+	rc = write_driver_ver_to_cfgtable(h->cfgtable);
+	if (rc)
+		return rc;
 	/* Find performant mode table. */
 	trans_offset = readl(&h->cfgtable->TransMethodOffset);
 	h->transtable = remap_pci_mem(pci_resource_start(h->pdev,
@@ -3777,11 +3950,12 @@
 	 * due to concerns about shared bbwc between 6402/6404 pair.
 	 */
 	if (rc == -ENOTSUPP)
-		return 0; /* just try to do the kdump anyhow. */
+		return rc; /* just try to do the kdump anyhow. */
 	if (rc)
 		return -ENODEV;
 
 	/* Now try to get the controller to respond to a no-op */
+	dev_warn(&pdev->dev, "Waiting for controller to respond to no-op\n");
 	for (i = 0; i < HPSA_POST_RESET_NOOP_RETRIES; i++) {
 		if (hpsa_noop(pdev) == 0)
 			break;
@@ -3792,18 +3966,133 @@
 	return 0;
 }
 
+static __devinit int hpsa_allocate_cmd_pool(struct ctlr_info *h)
+{
+	h->cmd_pool_bits = kzalloc(
+		DIV_ROUND_UP(h->nr_cmds, BITS_PER_LONG) *
+		sizeof(unsigned long), GFP_KERNEL);
+	h->cmd_pool = pci_alloc_consistent(h->pdev,
+		    h->nr_cmds * sizeof(*h->cmd_pool),
+		    &(h->cmd_pool_dhandle));
+	h->errinfo_pool = pci_alloc_consistent(h->pdev,
+		    h->nr_cmds * sizeof(*h->errinfo_pool),
+		    &(h->errinfo_pool_dhandle));
+	if ((h->cmd_pool_bits == NULL)
+	    || (h->cmd_pool == NULL)
+	    || (h->errinfo_pool == NULL)) {
+		dev_err(&h->pdev->dev, "out of memory in %s", __func__);
+		return -ENOMEM;
+	}
+	return 0;
+}
+
+static void hpsa_free_cmd_pool(struct ctlr_info *h)
+{
+	kfree(h->cmd_pool_bits);
+	if (h->cmd_pool)
+		pci_free_consistent(h->pdev,
+			    h->nr_cmds * sizeof(struct CommandList),
+			    h->cmd_pool, h->cmd_pool_dhandle);
+	if (h->errinfo_pool)
+		pci_free_consistent(h->pdev,
+			    h->nr_cmds * sizeof(struct ErrorInfo),
+			    h->errinfo_pool,
+			    h->errinfo_pool_dhandle);
+}
+
+static int hpsa_request_irq(struct ctlr_info *h,
+	irqreturn_t (*msixhandler)(int, void *),
+	irqreturn_t (*intxhandler)(int, void *))
+{
+	int rc;
+
+	if (h->msix_vector || h->msi_vector)
+		rc = request_irq(h->intr[h->intr_mode], msixhandler,
+				IRQF_DISABLED, h->devname, h);
+	else
+		rc = request_irq(h->intr[h->intr_mode], intxhandler,
+				IRQF_DISABLED, h->devname, h);
+	if (rc) {
+		dev_err(&h->pdev->dev, "unable to get irq %d for %s\n",
+		       h->intr[h->intr_mode], h->devname);
+		return -ENODEV;
+	}
+	return 0;
+}
+
+static int __devinit hpsa_kdump_soft_reset(struct ctlr_info *h)
+{
+	if (hpsa_send_host_reset(h, RAID_CTLR_LUNID,
+		HPSA_RESET_TYPE_CONTROLLER)) {
+		dev_warn(&h->pdev->dev, "Resetting array controller failed.\n");
+		return -EIO;
+	}
+
+	dev_info(&h->pdev->dev, "Waiting for board to soft reset.\n");
+	if (hpsa_wait_for_board_state(h->pdev, h->vaddr, BOARD_NOT_READY)) {
+		dev_warn(&h->pdev->dev, "Soft reset had no effect.\n");
+		return -1;
+	}
+
+	dev_info(&h->pdev->dev, "Board reset, awaiting READY status.\n");
+	if (hpsa_wait_for_board_state(h->pdev, h->vaddr, BOARD_READY)) {
+		dev_warn(&h->pdev->dev, "Board failed to become ready "
+			"after soft reset.\n");
+		return -1;
+	}
+
+	return 0;
+}
+
+static void hpsa_undo_allocations_after_kdump_soft_reset(struct ctlr_info *h)
+{
+	free_irq(h->intr[h->intr_mode], h);
+#ifdef CONFIG_PCI_MSI
+	if (h->msix_vector)
+		pci_disable_msix(h->pdev);
+	else if (h->msi_vector)
+		pci_disable_msi(h->pdev);
+#endif /* CONFIG_PCI_MSI */
+	hpsa_free_sg_chain_blocks(h);
+	hpsa_free_cmd_pool(h);
+	kfree(h->blockFetchTable);
+	pci_free_consistent(h->pdev, h->reply_pool_size,
+		h->reply_pool, h->reply_pool_dhandle);
+	if (h->vaddr)
+		iounmap(h->vaddr);
+	if (h->transtable)
+		iounmap(h->transtable);
+	if (h->cfgtable)
+		iounmap(h->cfgtable);
+	pci_release_regions(h->pdev);
+	kfree(h);
+}
+
 static int __devinit hpsa_init_one(struct pci_dev *pdev,
 				    const struct pci_device_id *ent)
 {
 	int dac, rc;
 	struct ctlr_info *h;
+	int try_soft_reset = 0;
+	unsigned long flags;
 
 	if (number_of_controllers == 0)
 		printk(KERN_INFO DRIVER_NAME "\n");
 
 	rc = hpsa_init_reset_devices(pdev);
-	if (rc)
-		return rc;
+	if (rc) {
+		if (rc != -ENOTSUPP)
+			return rc;
+		/* If the reset fails in a particular way (it has no way to do
+		 * a proper hard reset, so returns -ENOTSUPP) we can try to do
+		 * a soft reset once we get the controller configured up to the
+		 * point that it can accept a command.
+		 */
+		try_soft_reset = 1;
+		rc = 0;
+	}
+
+reinit_after_soft_reset:
 
 	/* 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
@@ -3847,54 +4136,82 @@
 	/* make sure the board interrupts are off */
 	h->access.set_intr_mask(h, HPSA_INTR_OFF);
 
-	if (h->msix_vector || h->msi_vector)
-		rc = request_irq(h->intr[h->intr_mode], do_hpsa_intr_msi,
-				IRQF_DISABLED, h->devname, h);
-	else
-		rc = request_irq(h->intr[h->intr_mode], do_hpsa_intr_intx,
-				IRQF_DISABLED, h->devname, h);
-	if (rc) {
-		dev_err(&pdev->dev, "unable to get irq %d for %s\n",
-		       h->intr[h->intr_mode], h->devname);
+	if (hpsa_request_irq(h, do_hpsa_intr_msi, do_hpsa_intr_intx))
 		goto clean2;
-	}
-
 	dev_info(&pdev->dev, "%s: <0x%x> at IRQ %d%s using DAC\n",
 	       h->devname, pdev->device,
 	       h->intr[h->intr_mode], dac ? "" : " not");
-
-	h->cmd_pool_bits =
-	    kmalloc(((h->nr_cmds + BITS_PER_LONG -
-		      1) / BITS_PER_LONG) * sizeof(unsigned long), GFP_KERNEL);
-	h->cmd_pool = pci_alloc_consistent(h->pdev,
-		    h->nr_cmds * sizeof(*h->cmd_pool),
-		    &(h->cmd_pool_dhandle));
-	h->errinfo_pool = pci_alloc_consistent(h->pdev,
-		    h->nr_cmds * sizeof(*h->errinfo_pool),
-		    &(h->errinfo_pool_dhandle));
-	if ((h->cmd_pool_bits == NULL)
-	    || (h->cmd_pool == NULL)
-	    || (h->errinfo_pool == NULL)) {
-		dev_err(&pdev->dev, "out of memory");
-		rc = -ENOMEM;
+	if (hpsa_allocate_cmd_pool(h))
 		goto clean4;
-	}
 	if (hpsa_allocate_sg_chain_blocks(h))
 		goto clean4;
 	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,
-	       ((h->nr_cmds + BITS_PER_LONG -
-		 1) / BITS_PER_LONG) * sizeof(unsigned long));
+	h->ndevices = 0;
+	h->scsi_host = NULL;
+	spin_lock_init(&h->devlock);
+	hpsa_put_ctlr_into_performant_mode(h);
 
-	hpsa_scsi_setup(h);
+	/* At this point, the controller is ready to take commands.
+	 * Now, if reset_devices and the hard reset didn't work, try
+	 * the soft reset and see if that works.
+	 */
+	if (try_soft_reset) {
+
+		/* This is kind of gross.  We may or may not get a completion
+		 * from the soft reset command, and if we do, then the value
+		 * from the fifo may or may not be valid.  So, we wait 10 secs
+		 * after the reset throwing away any completions we get during
+		 * that time.  Unregister the interrupt handler and register
+		 * fake ones to scoop up any residual completions.
+		 */
+		spin_lock_irqsave(&h->lock, flags);
+		h->access.set_intr_mask(h, HPSA_INTR_OFF);
+		spin_unlock_irqrestore(&h->lock, flags);
+		free_irq(h->intr[h->intr_mode], h);
+		rc = hpsa_request_irq(h, hpsa_msix_discard_completions,
+					hpsa_intx_discard_completions);
+		if (rc) {
+			dev_warn(&h->pdev->dev, "Failed to request_irq after "
+				"soft reset.\n");
+			goto clean4;
+		}
+
+		rc = hpsa_kdump_soft_reset(h);
+		if (rc)
+			/* Neither hard nor soft reset worked, we're hosed. */
+			goto clean4;
+
+		dev_info(&h->pdev->dev, "Board READY.\n");
+		dev_info(&h->pdev->dev,
+			"Waiting for stale completions to drain.\n");
+		h->access.set_intr_mask(h, HPSA_INTR_ON);
+		msleep(10000);
+		h->access.set_intr_mask(h, HPSA_INTR_OFF);
+
+		rc = controller_reset_failed(h->cfgtable);
+		if (rc)
+			dev_info(&h->pdev->dev,
+				"Soft reset appears to have failed.\n");
+
+		/* since the controller's reset, we have to go back and re-init
+		 * everything.  Easiest to just forget what we've done and do it
+		 * all over again.
+		 */
+		hpsa_undo_allocations_after_kdump_soft_reset(h);
+		try_soft_reset = 0;
+		if (rc)
+			/* don't go to clean4, we already unallocated */
+			return -ENODEV;
+
+		goto reinit_after_soft_reset;
+	}
 
 	/* 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;
@@ -3902,16 +4219,7 @@
 
 clean4:
 	hpsa_free_sg_chain_blocks(h);
-	kfree(h->cmd_pool_bits);
-	if (h->cmd_pool)
-		pci_free_consistent(h->pdev,
-			    h->nr_cmds * sizeof(struct CommandList),
-			    h->cmd_pool, h->cmd_pool_dhandle);
-	if (h->errinfo_pool)
-		pci_free_consistent(h->pdev,
-			    h->nr_cmds * sizeof(struct ErrorInfo),
-			    h->errinfo_pool,
-			    h->errinfo_pool_dhandle);
+	hpsa_free_cmd_pool(h);
 	free_irq(h->intr[h->intr_mode], h);
 clean2:
 clean1:
diff -druN linux-2.6.39-libre/drivers/scsi/hpsa_cmd.h linux-3.0-rc7-libre/drivers/scsi/hpsa_cmd.h
--- linux-2.6.39-libre/drivers/scsi/hpsa_cmd.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/scsi/hpsa_cmd.h	2011-07-11 19:51:52.000000000 -0400
@@ -101,6 +101,7 @@
 #define CFGTBL_ChangeReq        0x00000001l
 #define CFGTBL_AccCmds          0x00000001l
 #define DOORBELL_CTLR_RESET	0x00000004l
+#define DOORBELL_CTLR_RESET2	0x00000020l
 
 #define CFGTBL_Trans_Simple     0x00000002l
 #define CFGTBL_Trans_Performant 0x00000004l
@@ -256,14 +257,6 @@
 #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 DIRECT_LOOKUP_MASK (~((1 << DIRECT_LOOKUP_SHIFT) - 1))
@@ -345,6 +338,8 @@
 	u8		reserved[0x78 - 0x58];
 	u32		misc_fw_support; /* offset 0x78 */
 #define			MISC_FW_DOORBELL_RESET (0x02)
+#define			MISC_FW_DOORBELL_RESET2 (0x010)
+	u8		driver_version[32];
 };
 
 #define NUM_BLOCKFETCH_ENTRIES 8
diff -druN linux-2.6.39-libre/drivers/scsi/hpsa.h linux-3.0-rc7-libre/drivers/scsi/hpsa.h
--- linux-2.6.39-libre/drivers/scsi/hpsa.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/scsi/hpsa.h	2011-07-11 19:51:52.000000000 -0400
@@ -127,10 +127,12 @@
 };
 #define HPSA_ABORT_MSG 0
 #define HPSA_DEVICE_RESET_MSG 1
-#define HPSA_BUS_RESET_MSG 2
-#define HPSA_HOST_RESET_MSG 3
+#define HPSA_RESET_TYPE_CONTROLLER 0x00
+#define HPSA_RESET_TYPE_BUS 0x01
+#define HPSA_RESET_TYPE_TARGET 0x03
+#define HPSA_RESET_TYPE_LUN 0x04
 #define HPSA_MSG_SEND_RETRY_LIMIT 10
-#define HPSA_MSG_SEND_RETRY_INTERVAL_MSECS 1000
+#define HPSA_MSG_SEND_RETRY_INTERVAL_MSECS (10000)
 
 /* Maximum time in seconds driver will wait for command completions
  * when polling before giving up.
@@ -155,7 +157,7 @@
  * HPSA_BOARD_READY_ITERATIONS are derived from those.
  */
 #define HPSA_BOARD_READY_WAIT_SECS (120)
-#define HPSA_BOARD_NOT_READY_WAIT_SECS (10)
+#define HPSA_BOARD_NOT_READY_WAIT_SECS (100)
 #define HPSA_BOARD_READY_POLL_INTERVAL_MSECS (100)
 #define HPSA_BOARD_READY_POLL_INTERVAL \
 	((HPSA_BOARD_READY_POLL_INTERVAL_MSECS * HZ) / 1000)
@@ -212,6 +214,7 @@
 	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);
+	(void) readl(h->vaddr + SA5_REQUEST_PORT_OFFSET);
 	h->commands_outstanding++;
 	if (h->commands_outstanding > h->max_outstanding)
 		h->max_outstanding = h->commands_outstanding;
@@ -227,10 +230,12 @@
 	if (val) { /* Turn interrupts on */
 		h->interrupts_enabled = 1;
 		writel(0, h->vaddr + SA5_REPLY_INTR_MASK_OFFSET);
+		(void) readl(h->vaddr + SA5_REPLY_INTR_MASK_OFFSET);
 	} else { /* Turn them off */
 		h->interrupts_enabled = 0;
 		writel(SA5_INTR_OFF,
 			h->vaddr + SA5_REPLY_INTR_MASK_OFFSET);
+		(void) readl(h->vaddr + SA5_REPLY_INTR_MASK_OFFSET);
 	}
 }
 
@@ -239,10 +244,12 @@
 	if (val) { /* turn on interrupts */
 		h->interrupts_enabled = 1;
 		writel(0, h->vaddr + SA5_REPLY_INTR_MASK_OFFSET);
+		(void) readl(h->vaddr + SA5_REPLY_INTR_MASK_OFFSET);
 	} else {
 		h->interrupts_enabled = 0;
 		writel(SA5_PERF_INTR_OFF,
 			h->vaddr + SA5_REPLY_INTR_MASK_OFFSET);
+		(void) readl(h->vaddr + SA5_REPLY_INTR_MASK_OFFSET);
 	}
 }
 
diff -druN linux-2.6.39-libre/drivers/scsi/ibmvscsi/ibmvfc.c linux-3.0-rc7-libre/drivers/scsi/ibmvscsi/ibmvfc.c
--- linux-2.6.39-libre/drivers/scsi/ibmvscsi/ibmvfc.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/scsi/ibmvscsi/ibmvfc.c	2011-07-11 19:51:52.000000000 -0400
@@ -4306,8 +4306,8 @@
 		spin_lock_irqsave(vhost->host->host_lock, flags);
 		if (rc == H_CLOSED)
 			vio_enable_interrupts(to_vio_dev(vhost->dev));
-		else if (rc || (rc = ibmvfc_send_crq_init(vhost)) ||
-			 (rc = vio_enable_interrupts(to_vio_dev(vhost->dev)))) {
+		if (rc || (rc = ibmvfc_send_crq_init(vhost)) ||
+		    (rc = vio_enable_interrupts(to_vio_dev(vhost->dev)))) {
 			ibmvfc_link_down(vhost, IBMVFC_LINK_DEAD);
 			dev_err(vhost->dev, "Error after reset (rc=%d)\n", rc);
 		}
diff -druN linux-2.6.39-libre/drivers/scsi/ibmvscsi/ibmvscsi.c linux-3.0-rc7-libre/drivers/scsi/ibmvscsi/ibmvscsi.c
--- linux-2.6.39-libre/drivers/scsi/ibmvscsi/ibmvscsi.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/scsi/ibmvscsi/ibmvscsi.c	2011-07-11 19:51:52.000000000 -0400
@@ -1849,8 +1849,7 @@
 		rc = ibmvscsi_ops->reset_crq_queue(&hostdata->queue, hostdata);
 		if (!rc)
 			rc = ibmvscsi_ops->send_crq(hostdata, 0xC001000000000000LL, 0);
-		if (!rc)
-			rc = vio_enable_interrupts(to_vio_dev(hostdata->dev));
+		vio_enable_interrupts(to_vio_dev(hostdata->dev));
 	} else if (hostdata->reenable_crq) {
 		smp_rmb();
 		action = "enable";
diff -druN linux-2.6.39-libre/drivers/scsi/in2000.c linux-3.0-rc7-libre/drivers/scsi/in2000.c
--- linux-2.6.39-libre/drivers/scsi/in2000.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/scsi/in2000.c	2011-07-11 19:51:52.000000000 -0400
@@ -343,7 +343,7 @@
 	instance = cmd->device->host;
 	hostdata = (struct IN2000_hostdata *) instance->hostdata;
 
-	DB(DB_QUEUE_COMMAND, scmd_printk(KERN_DEBUG, cmd, "Q-%02x-%ld(", cmd->cmnd[0], cmd->serial_number))
+	DB(DB_QUEUE_COMMAND, scmd_printk(KERN_DEBUG, cmd, "Q-%02x(", cmd->cmnd[0]))
 
 /* Set up a few fields in the Scsi_Cmnd structure for our own use:
  *  - host_scribble is the pointer to the next cmd in the input queue
@@ -427,7 +427,7 @@
 
 	in2000_execute(cmd->device->host);
 
-	DB(DB_QUEUE_COMMAND, printk(")Q-%ld ", cmd->serial_number))
+	DB(DB_QUEUE_COMMAND, printk(")Q "))
 	    return 0;
 }
 
@@ -705,7 +705,7 @@
 	 * to search the input_Q again...
 	 */
 
-	DB(DB_EXECUTE, printk("%s%ld)EX-2 ", (cmd->SCp.phase) ? "d:" : "", cmd->serial_number))
+	DB(DB_EXECUTE, printk("%s)EX-2 ", (cmd->SCp.phase) ? "d:" : ""))
 
 }
 
@@ -1149,7 +1149,7 @@
 	case CSR_XFER_DONE | PHS_COMMAND:
 	case CSR_UNEXP | PHS_COMMAND:
 	case CSR_SRV_REQ | PHS_COMMAND:
-		DB(DB_INTR, printk("CMND-%02x,%ld", cmd->cmnd[0], cmd->serial_number))
+		DB(DB_INTR, printk("CMND-%02x", cmd->cmnd[0]))
 		    transfer_pio(cmd->cmnd, cmd->cmd_len, DATA_OUT_DIR, hostdata);
 		hostdata->state = S_CONNECTED;
 		break;
@@ -1191,7 +1191,7 @@
 		switch (msg) {
 
 		case COMMAND_COMPLETE:
-			DB(DB_INTR, printk("CCMP-%ld", cmd->serial_number))
+			DB(DB_INTR, printk("CCMP"))
 			    write_3393_cmd(hostdata, WD_CMD_NEGATE_ACK);
 			hostdata->state = S_PRE_CMP_DISC;
 			break;
@@ -1329,7 +1329,7 @@
 
 		write_3393(hostdata, WD_SOURCE_ID, SRCID_ER);
 		if (phs == 0x60) {
-			DB(DB_INTR, printk("SX-DONE-%ld", cmd->serial_number))
+			DB(DB_INTR, printk("SX-DONE"))
 			    cmd->SCp.Message = COMMAND_COMPLETE;
 			lun = read_3393(hostdata, WD_TARGET_LUN);
 			DB(DB_INTR, printk(":%d.%d", cmd->SCp.Status, lun))
@@ -1350,7 +1350,7 @@
 
 			in2000_execute(instance);
 		} else {
-			printk("%02x:%02x:%02x-%ld: Unknown SEL_XFER_DONE phase!!---", asr, sr, phs, cmd->serial_number);
+			printk("%02x:%02x:%02x: Unknown SEL_XFER_DONE phase!!---", asr, sr, phs);
 		}
 		break;
 
@@ -1417,7 +1417,7 @@
 			spin_unlock_irqrestore(instance->host_lock, flags);
 			return IRQ_HANDLED;
 		}
-		DB(DB_INTR, printk("UNEXP_DISC-%ld", cmd->serial_number))
+		DB(DB_INTR, printk("UNEXP_DISC"))
 		    hostdata->connected = NULL;
 		hostdata->busy[cmd->device->id] &= ~(1 << cmd->device->lun);
 		hostdata->state = S_UNCONNECTED;
@@ -1442,7 +1442,7 @@
  */
 
 		write_3393(hostdata, WD_SOURCE_ID, SRCID_ER);
-		DB(DB_INTR, printk("DISC-%ld", cmd->serial_number))
+		DB(DB_INTR, printk("DISC"))
 		    if (cmd == NULL) {
 			printk(" - Already disconnected! ");
 			hostdata->state = S_UNCONNECTED;
@@ -1575,7 +1575,6 @@
 		} else
 			hostdata->state = S_CONNECTED;
 
-		DB(DB_INTR, printk("-%ld", cmd->serial_number))
 		    break;
 
 	default:
@@ -1704,7 +1703,7 @@
 				prev->host_scribble = cmd->host_scribble;
 			cmd->host_scribble = NULL;
 			cmd->result = DID_ABORT << 16;
-			printk(KERN_WARNING "scsi%d: Abort - removing command %ld from input_Q. ", instance->host_no, cmd->serial_number);
+			printk(KERN_WARNING "scsi%d: Abort - removing command from input_Q. ", instance->host_no);
 			cmd->scsi_done(cmd);
 			return SUCCESS;
 		}
@@ -1725,7 +1724,7 @@
 
 	if (hostdata->connected == cmd) {
 
-		printk(KERN_WARNING "scsi%d: Aborting connected command %ld - ", instance->host_no, cmd->serial_number);
+		printk(KERN_WARNING "scsi%d: Aborting connected command - ", instance->host_no);
 
 		printk("sending wd33c93 ABORT command - ");
 		write_3393(hostdata, WD_CONTROL, CTRL_IDI | CTRL_EDI | CTRL_POLLED);
@@ -2228,7 +2227,7 @@
 	bp = buf;
 	*bp = '\0';
 	if (hd->proc & PR_VERSION) {
-		sprintf(tbuf, "\nVersion %s - %s. Compiled %s %s", IN2000_VERSION, IN2000_DATE, __DATE__, __TIME__);
+		sprintf(tbuf, "\nVersion %s - %s.", IN2000_VERSION, IN2000_DATE);
 		strcat(bp, tbuf);
 	}
 	if (hd->proc & PR_INFO) {
@@ -2270,7 +2269,7 @@
 		strcat(bp, "\nconnected:     ");
 		if (hd->connected) {
 			cmd = (Scsi_Cmnd *) hd->connected;
-			sprintf(tbuf, " %ld-%d:%d(%02x)", cmd->serial_number, cmd->device->id, cmd->device->lun, cmd->cmnd[0]);
+			sprintf(tbuf, " %d:%d(%02x)", cmd->device->id, cmd->device->lun, cmd->cmnd[0]);
 			strcat(bp, tbuf);
 		}
 	}
@@ -2278,7 +2277,7 @@
 		strcat(bp, "\ninput_Q:       ");
 		cmd = (Scsi_Cmnd *) hd->input_Q;
 		while (cmd) {
-			sprintf(tbuf, " %ld-%d:%d(%02x)", cmd->serial_number, cmd->device->id, cmd->device->lun, cmd->cmnd[0]);
+			sprintf(tbuf, " %d:%d(%02x)", cmd->device->id, cmd->device->lun, cmd->cmnd[0]);
 			strcat(bp, tbuf);
 			cmd = (Scsi_Cmnd *) cmd->host_scribble;
 		}
@@ -2287,7 +2286,7 @@
 		strcat(bp, "\ndisconnected_Q:");
 		cmd = (Scsi_Cmnd *) hd->disconnected_Q;
 		while (cmd) {
-			sprintf(tbuf, " %ld-%d:%d(%02x)", cmd->serial_number, cmd->device->id, cmd->device->lun, cmd->cmnd[0]);
+			sprintf(tbuf, " %d:%d(%02x)", cmd->device->id, cmd->device->lun, cmd->cmnd[0]);
 			strcat(bp, tbuf);
 			cmd = (Scsi_Cmnd *) cmd->host_scribble;
 		}
diff -druN linux-2.6.39-libre/drivers/scsi/ipr.c linux-3.0-rc7-libre/drivers/scsi/ipr.c
--- linux-2.6.39-libre/drivers/scsi/ipr.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/scsi/ipr.c	2011-07-11 19:51:52.000000000 -0400
@@ -60,6 +60,7 @@
 #include <linux/errno.h>
 #include <linux/kernel.h>
 #include <linux/slab.h>
+#include <linux/vmalloc.h>
 #include <linux/ioport.h>
 #include <linux/delay.h>
 #include <linux/pci.h>
@@ -2717,13 +2718,18 @@
 			unsigned long pci_address, u32 length)
 {
 	int bytes_copied = 0;
-	int cur_len, rc, rem_len, rem_page_len;
+	int cur_len, rc, rem_len, rem_page_len, max_dump_size;
 	__be32 *page;
 	unsigned long lock_flags = 0;
 	struct ipr_ioa_dump *ioa_dump = &ioa_cfg->dump->ioa_dump;
 
+	if (ioa_cfg->sis64)
+		max_dump_size = IPR_FMT3_MAX_IOA_DUMP_SIZE;
+	else
+		max_dump_size = IPR_FMT2_MAX_IOA_DUMP_SIZE;
+
 	while (bytes_copied < length &&
-	       (ioa_dump->hdr.len + bytes_copied) < IPR_MAX_IOA_DUMP_SIZE) {
+	       (ioa_dump->hdr.len + bytes_copied) < max_dump_size) {
 		if (ioa_dump->page_offset >= PAGE_SIZE ||
 		    ioa_dump->page_offset == 0) {
 			page = (__be32 *)__get_free_page(GFP_ATOMIC);
@@ -2885,8 +2891,8 @@
 	unsigned long lock_flags = 0;
 	struct ipr_driver_dump *driver_dump = &dump->driver_dump;
 	struct ipr_ioa_dump *ioa_dump = &dump->ioa_dump;
-	u32 num_entries, start_off, end_off;
-	u32 bytes_to_copy, bytes_copied, rc;
+	u32 num_entries, max_num_entries, start_off, end_off;
+	u32 max_dump_size, bytes_to_copy, bytes_copied, rc;
 	struct ipr_sdt *sdt;
 	int valid = 1;
 	int i;
@@ -2947,8 +2953,18 @@
 	 on entries in this table */
 	sdt = &ioa_dump->sdt;
 
+	if (ioa_cfg->sis64) {
+		max_num_entries = IPR_FMT3_NUM_SDT_ENTRIES;
+		max_dump_size = IPR_FMT3_MAX_IOA_DUMP_SIZE;
+	} else {
+		max_num_entries = IPR_FMT2_NUM_SDT_ENTRIES;
+		max_dump_size = IPR_FMT2_MAX_IOA_DUMP_SIZE;
+	}
+
+	bytes_to_copy = offsetof(struct ipr_sdt, entry) +
+			(max_num_entries * sizeof(struct ipr_sdt_entry));
 	rc = ipr_get_ldump_data_section(ioa_cfg, start_addr, (__be32 *)sdt,
-					sizeof(struct ipr_sdt) / sizeof(__be32));
+					bytes_to_copy / sizeof(__be32));
 
 	/* Smart Dump table is ready to use and the first entry is valid */
 	if (rc || ((be32_to_cpu(sdt->hdr.state) != IPR_FMT3_SDT_READY_TO_USE) &&
@@ -2964,13 +2980,20 @@
 
 	num_entries = be32_to_cpu(sdt->hdr.num_entries_used);
 
-	if (num_entries > IPR_NUM_SDT_ENTRIES)
-		num_entries = IPR_NUM_SDT_ENTRIES;
+	if (num_entries > max_num_entries)
+		num_entries = max_num_entries;
+
+	/* Update dump length to the actual data to be copied */
+	dump->driver_dump.hdr.len += sizeof(struct ipr_sdt_header);
+	if (ioa_cfg->sis64)
+		dump->driver_dump.hdr.len += num_entries * sizeof(struct ipr_sdt_entry);
+	else
+		dump->driver_dump.hdr.len += max_num_entries * sizeof(struct ipr_sdt_entry);
 
 	spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
 
 	for (i = 0; i < num_entries; i++) {
-		if (ioa_dump->hdr.len > IPR_MAX_IOA_DUMP_SIZE) {
+		if (ioa_dump->hdr.len > max_dump_size) {
 			driver_dump->hdr.status = IPR_DUMP_STATUS_QUAL_SUCCESS;
 			break;
 		}
@@ -2989,7 +3012,7 @@
 					valid = 0;
 			}
 			if (valid) {
-				if (bytes_to_copy > IPR_MAX_IOA_DUMP_SIZE) {
+				if (bytes_to_copy > max_dump_size) {
 					sdt->entry[i].flags &= ~IPR_SDT_VALID_ENTRY;
 					continue;
 				}
@@ -3044,6 +3067,7 @@
 	for (i = 0; i < dump->ioa_dump.next_page_index; i++)
 		free_page((unsigned long) dump->ioa_dump.ioa_data[i]);
 
+	vfree(dump->ioa_dump.ioa_data);
 	kfree(dump);
 	LEAVE;
 }
@@ -3835,7 +3859,7 @@
 	struct ipr_dump *dump;
 	unsigned long lock_flags = 0;
 	char *src;
-	int len;
+	int len, sdt_end;
 	size_t rc = count;
 
 	if (!capable(CAP_SYS_ADMIN))
@@ -3875,9 +3899,17 @@
 
 	off -= sizeof(dump->driver_dump);
 
-	if (count && off < offsetof(struct ipr_ioa_dump, ioa_data)) {
-		if (off + count > offsetof(struct ipr_ioa_dump, ioa_data))
-			len = offsetof(struct ipr_ioa_dump, ioa_data) - off;
+	if (ioa_cfg->sis64)
+		sdt_end = offsetof(struct ipr_ioa_dump, sdt.entry) +
+			  (be32_to_cpu(dump->ioa_dump.sdt.hdr.num_entries_used) *
+			   sizeof(struct ipr_sdt_entry));
+	else
+		sdt_end = offsetof(struct ipr_ioa_dump, sdt.entry) +
+			  (IPR_FMT2_NUM_SDT_ENTRIES * sizeof(struct ipr_sdt_entry));
+
+	if (count && off < sdt_end) {
+		if (off + count > sdt_end)
+			len = sdt_end - off;
 		else
 			len = count;
 		src = (u8 *)&dump->ioa_dump + off;
@@ -3887,7 +3919,7 @@
 		count -= len;
 	}
 
-	off -= offsetof(struct ipr_ioa_dump, ioa_data);
+	off -= sdt_end;
 
 	while (count) {
 		if ((off & PAGE_MASK) != ((off + count) & PAGE_MASK))
@@ -3916,6 +3948,7 @@
 static int ipr_alloc_dump(struct ipr_ioa_cfg *ioa_cfg)
 {
 	struct ipr_dump *dump;
+	__be32 **ioa_data;
 	unsigned long lock_flags = 0;
 
 	dump = kzalloc(sizeof(struct ipr_dump), GFP_KERNEL);
@@ -3925,6 +3958,19 @@
 		return -ENOMEM;
 	}
 
+	if (ioa_cfg->sis64)
+		ioa_data = vmalloc(IPR_FMT3_MAX_NUM_DUMP_PAGES * sizeof(__be32 *));
+	else
+		ioa_data = vmalloc(IPR_FMT2_MAX_NUM_DUMP_PAGES * sizeof(__be32 *));
+
+	if (!ioa_data) {
+		ipr_err("Dump memory allocation failed\n");
+		kfree(dump);
+		return -ENOMEM;
+	}
+
+	dump->ioa_dump.ioa_data = ioa_data;
+
 	kref_init(&dump->kref);
 	dump->ioa_cfg = ioa_cfg;
 
@@ -3932,6 +3978,7 @@
 
 	if (INACTIVE != ioa_cfg->sdt_state) {
 		spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
+		vfree(dump->ioa_dump.ioa_data);
 		kfree(dump);
 		return 0;
 	}
@@ -4953,9 +5000,35 @@
  * 	IRQ_NONE / IRQ_HANDLED
  **/
 static irqreturn_t ipr_handle_other_interrupt(struct ipr_ioa_cfg *ioa_cfg,
-					      volatile u32 int_reg)
+					      u32 int_reg)
 {
 	irqreturn_t rc = IRQ_HANDLED;
+	u32 int_mask_reg;
+
+	int_mask_reg = readl(ioa_cfg->regs.sense_interrupt_mask_reg32);
+	int_reg &= ~int_mask_reg;
+
+	/* 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 ((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);
+				return IRQ_HANDLED;
+			}
+		}
+
+		return IRQ_NONE;
+	}
 
 	if (int_reg & IPR_PCII_IOA_TRANS_TO_OPER) {
 		/* Mask the interrupt */
@@ -4968,6 +5041,13 @@
 		list_del(&ioa_cfg->reset_cmd->queue);
 		del_timer(&ioa_cfg->reset_cmd->timer);
 		ipr_reset_ioa_job(ioa_cfg->reset_cmd);
+	} else if ((int_reg & IPR_PCII_HRRQ_UPDATED) == int_reg) {
+		if (ipr_debug && printk_ratelimit())
+			dev_err(&ioa_cfg->pdev->dev,
+				"Spurious interrupt detected. 0x%08X\n", int_reg);
+		writel(IPR_PCII_HRRQ_UPDATED, ioa_cfg->regs.clr_interrupt_reg32);
+		int_reg = readl(ioa_cfg->regs.sense_interrupt_reg32);
+		return IRQ_NONE;
 	} else {
 		if (int_reg & IPR_PCII_IOA_UNIT_CHECKED)
 			ioa_cfg->ioa_unit_checked = 1;
@@ -5016,10 +5096,11 @@
 {
 	struct ipr_ioa_cfg *ioa_cfg = (struct ipr_ioa_cfg *)devp;
 	unsigned long lock_flags = 0;
-	volatile u32 int_reg, int_mask_reg;
+	u32 int_reg = 0;
 	u32 ioasc;
 	u16 cmd_index;
 	int num_hrrq = 0;
+	int irq_none = 0;
 	struct ipr_cmnd *ipr_cmd;
 	irqreturn_t rc = IRQ_NONE;
 
@@ -5031,33 +5112,6 @@
 		return IRQ_NONE;
 	}
 
-	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.
-	 * 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;
-	}
-
 	while (1) {
 		ipr_cmd = NULL;
 
@@ -5095,18 +5149,21 @@
 
 		if (ipr_cmd != NULL) {
 			/* Clear the PCI interrupt */
+			num_hrrq = 0;
 			do {
 				writel(IPR_PCII_HRRQ_UPDATED, ioa_cfg->regs.clr_interrupt_reg32);
-				int_reg = readl(ioa_cfg->regs.sense_interrupt_reg32) & ~int_mask_reg;
+				int_reg = readl(ioa_cfg->regs.sense_interrupt_reg32);
 			} while (int_reg & IPR_PCII_HRRQ_UPDATED &&
 					num_hrrq++ < IPR_MAX_HRRQ_RETRIES);
 
-			if (int_reg & IPR_PCII_HRRQ_UPDATED) {
-				ipr_isr_eh(ioa_cfg, "Error clearing HRRQ");
-				spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
-				return IRQ_HANDLED;
-			}
-
+		} else if (rc == IRQ_NONE && irq_none == 0) {
+			int_reg = readl(ioa_cfg->regs.sense_interrupt_reg32);
+			irq_none++;
+		} else if (num_hrrq == IPR_MAX_HRRQ_RETRIES &&
+			   int_reg & IPR_PCII_HRRQ_UPDATED) {
+			ipr_isr_eh(ioa_cfg, "Error clearing HRRQ");
+			spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
+			return IRQ_HANDLED;
 		} else
 			break;
 	}
@@ -5143,7 +5200,8 @@
 
 	nseg = scsi_dma_map(scsi_cmd);
 	if (nseg < 0) {
-		dev_err(&ioa_cfg->pdev->dev, "pci_map_sg failed!\n");
+		if (printk_ratelimit())
+			dev_err(&ioa_cfg->pdev->dev, "pci_map_sg failed!\n");
 		return -1;
 	}
 
@@ -5773,7 +5831,8 @@
 		}
 
 		ioarcb->cmd_pkt.flags_hi |= IPR_FLAGS_HI_NO_LINK_DESC;
-		ioarcb->cmd_pkt.flags_lo |= IPR_FLAGS_LO_DELAY_AFTER_RST;
+		if (ipr_is_gscsi(res))
+			ioarcb->cmd_pkt.flags_lo |= IPR_FLAGS_LO_DELAY_AFTER_RST;
 		ioarcb->cmd_pkt.flags_lo |= IPR_FLAGS_LO_ALIGNED_BFR;
 		ioarcb->cmd_pkt.flags_lo |= ipr_get_task_attributes(scsi_cmd);
 	}
@@ -7516,7 +7575,7 @@
 static int ipr_reset_restore_cfg_space(struct ipr_cmnd *ipr_cmd)
 {
 	struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg;
-	volatile u32 int_reg;
+	u32 int_reg;
 
 	ENTER;
 	ioa_cfg->pdev->state_saved = true;
@@ -7555,7 +7614,10 @@
 		ipr_cmd->job_step = ipr_reset_enable_ioa;
 
 		if (GET_DUMP == ioa_cfg->sdt_state) {
-			ipr_reset_start_timer(ipr_cmd, IPR_DUMP_TIMEOUT);
+			if (ioa_cfg->sis64)
+				ipr_reset_start_timer(ipr_cmd, IPR_SIS64_DUMP_TIMEOUT);
+			else
+				ipr_reset_start_timer(ipr_cmd, IPR_SIS32_DUMP_TIMEOUT);
 			ipr_cmd->job_step = ipr_reset_wait_for_dump;
 			schedule_work(&ioa_cfg->work_q);
 			return IPR_RC_JOB_RETURN;
diff -druN linux-2.6.39-libre/drivers/scsi/ipr.h linux-3.0-rc7-libre/drivers/scsi/ipr.h
--- linux-2.6.39-libre/drivers/scsi/ipr.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/scsi/ipr.h	2011-07-11 19:51:52.000000000 -0400
@@ -38,8 +38,8 @@
 /*
  * Literals
  */
-#define IPR_DRIVER_VERSION "2.5.1"
-#define IPR_DRIVER_DATE "(August 10, 2010)"
+#define IPR_DRIVER_VERSION "2.5.2"
+#define IPR_DRIVER_DATE "(April 27, 2011)"
 
 /*
  * IPR_MAX_CMD_PER_LUN: This defines the maximum number of outstanding
@@ -217,7 +217,8 @@
 #define IPR_CHECK_FOR_RESET_TIMEOUT		(HZ / 10)
 #define IPR_WAIT_FOR_BIST_TIMEOUT		(2 * HZ)
 #define IPR_PCI_RESET_TIMEOUT			(HZ / 2)
-#define IPR_DUMP_TIMEOUT			(15 * HZ)
+#define IPR_SIS32_DUMP_TIMEOUT			(15 * HZ)
+#define IPR_SIS64_DUMP_TIMEOUT			(40 * HZ)
 #define IPR_DUMP_DELAY_SECONDS			4
 #define IPR_DUMP_DELAY_TIMEOUT			(IPR_DUMP_DELAY_SECONDS * HZ)
 
@@ -285,9 +286,12 @@
 /*
  * Dump literals
  */
-#define IPR_MAX_IOA_DUMP_SIZE				(4 * 1024 * 1024)
-#define IPR_NUM_SDT_ENTRIES				511
-#define IPR_MAX_NUM_DUMP_PAGES	((IPR_MAX_IOA_DUMP_SIZE / PAGE_SIZE) + 1)
+#define IPR_FMT2_MAX_IOA_DUMP_SIZE			(4 * 1024 * 1024)
+#define IPR_FMT3_MAX_IOA_DUMP_SIZE			(32 * 1024 * 1024)
+#define IPR_FMT2_NUM_SDT_ENTRIES			511
+#define IPR_FMT3_NUM_SDT_ENTRIES			0xFFF
+#define IPR_FMT2_MAX_NUM_DUMP_PAGES	((IPR_FMT2_MAX_IOA_DUMP_SIZE / PAGE_SIZE) + 1)
+#define IPR_FMT3_MAX_NUM_DUMP_PAGES	((IPR_FMT3_MAX_IOA_DUMP_SIZE / PAGE_SIZE) + 1)
 
 /*
  * Misc literals
@@ -474,7 +478,7 @@
 
 	u8 flags_lo;
 #define IPR_FLAGS_LO_ALIGNED_BFR		0x20
-#define IPR_FLAGS_LO_DELAY_AFTER_RST	0x10
+#define IPR_FLAGS_LO_DELAY_AFTER_RST		0x10
 #define IPR_FLAGS_LO_UNTAGGED_TASK		0x00
 #define IPR_FLAGS_LO_SIMPLE_TASK		0x02
 #define IPR_FLAGS_LO_ORDERED_TASK		0x04
@@ -1164,7 +1168,7 @@
 
 struct ipr_sdt {
 	struct ipr_sdt_header hdr;
-	struct ipr_sdt_entry entry[IPR_NUM_SDT_ENTRIES];
+	struct ipr_sdt_entry entry[IPR_FMT3_NUM_SDT_ENTRIES];
 }__attribute__((packed, aligned (4)));
 
 struct ipr_uc_sdt {
@@ -1608,7 +1612,7 @@
 struct ipr_ioa_dump {
 	struct ipr_dump_entry_header hdr;
 	struct ipr_sdt sdt;
-	__be32 *ioa_data[IPR_MAX_NUM_DUMP_PAGES];
+	__be32 **ioa_data;
 	u32 reserved;
 	u32 next_page_index;
 	u32 page_offset;
diff -druN linux-2.6.39-libre/drivers/scsi/isci/firmware/create_fw.c linux-3.0-rc7-libre/drivers/scsi/isci/firmware/create_fw.c
--- linux-2.6.39-libre/drivers/scsi/isci/firmware/create_fw.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/scsi/isci/firmware/create_fw.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,99 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <string.h>
+#include <errno.h>
+#include <asm/types.h>
+#include <strings.h>
+#include <stdint.h>
+
+#include "create_fw.h"
+#include "../probe_roms.h"
+
+int write_blob(struct isci_orom *isci_orom)
+{
+	FILE *fd;
+	int err;
+	size_t count;
+
+	fd = fopen(blob_name, "w+");
+	if (!fd) {
+		perror("Open file for write failed");
+		fclose(fd);
+		return -EIO;
+	}
+
+	count = fwrite(isci_orom, sizeof(struct isci_orom), 1, fd);
+	if (count != 1) {
+		perror("Write data failed");
+		fclose(fd);
+		return -EIO;
+	}
+
+	fclose(fd);
+
+	return 0;
+}
+
+void set_binary_values(struct isci_orom *isci_orom)
+{
+	int ctrl_idx, phy_idx, port_idx;
+
+	/* setting OROM signature */
+	strncpy(isci_orom->hdr.signature, sig, strlen(sig));
+	isci_orom->hdr.version = version;
+	isci_orom->hdr.total_block_length = sizeof(struct isci_orom);
+	isci_orom->hdr.hdr_length = sizeof(struct sci_bios_oem_param_block_hdr);
+	isci_orom->hdr.num_elements = num_elements;
+
+	for (ctrl_idx = 0; ctrl_idx < 2; ctrl_idx++) {
+		isci_orom->ctrl[ctrl_idx].controller.mode_type = mode_type;
+		isci_orom->ctrl[ctrl_idx].controller.max_concurrent_dev_spin_up =
+			max_num_concurrent_dev_spin_up;
+		isci_orom->ctrl[ctrl_idx].controller.do_enable_ssc =
+			enable_ssc;
+
+		for (port_idx = 0; port_idx < 4; port_idx++)
+			isci_orom->ctrl[ctrl_idx].ports[port_idx].phy_mask =
+				phy_mask[ctrl_idx][port_idx];
+
+		for (phy_idx = 0; phy_idx < 4; phy_idx++) {
+			isci_orom->ctrl[ctrl_idx].phys[phy_idx].sas_address.high =
+				(__u32)(sas_addr[ctrl_idx][phy_idx] >> 32);
+			isci_orom->ctrl[ctrl_idx].phys[phy_idx].sas_address.low =
+				(__u32)(sas_addr[ctrl_idx][phy_idx]);
+
+			isci_orom->ctrl[ctrl_idx].phys[phy_idx].afe_tx_amp_control0 =
+				afe_tx_amp_control0;
+			isci_orom->ctrl[ctrl_idx].phys[phy_idx].afe_tx_amp_control1 =
+				afe_tx_amp_control1;
+			isci_orom->ctrl[ctrl_idx].phys[phy_idx].afe_tx_amp_control2 =
+				afe_tx_amp_control2;
+			isci_orom->ctrl[ctrl_idx].phys[phy_idx].afe_tx_amp_control3 =
+				afe_tx_amp_control3;
+		}
+	}
+}
+
+int main(void)
+{
+	int err;
+	struct isci_orom *isci_orom;
+
+	isci_orom = malloc(sizeof(struct isci_orom));
+	memset(isci_orom, 0, sizeof(struct isci_orom));
+
+	set_binary_values(isci_orom);
+
+	err = write_blob(isci_orom);
+	if (err < 0) {
+		free(isci_orom);
+		return err;
+	}
+
+	free(isci_orom);
+	return 0;
+}
diff -druN linux-2.6.39-libre/drivers/scsi/isci/firmware/create_fw.h linux-3.0-rc7-libre/drivers/scsi/isci/firmware/create_fw.h
--- linux-2.6.39-libre/drivers/scsi/isci/firmware/create_fw.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/scsi/isci/firmware/create_fw.h	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,77 @@
+#ifndef _CREATE_FW_H_
+#define _CREATE_FW_H_
+#include "../probe_roms.h"
+
+
+/* we are configuring for 2 SCUs */
+static const int num_elements = 2;
+
+/*
+ * For all defined arrays:
+ * elements 0-3 are for SCU0, ports 0-3
+ * elements 4-7 are for SCU1, ports 0-3
+ *
+ * valid configurations for one SCU are:
+ *  P0  P1  P2  P3
+ * ----------------
+ * 0xF,0x0,0x0,0x0 # 1 x4 port
+ * 0x3,0x0,0x4,0x8 # Phys 0 and 1 are a x2 port, phy 2 and phy 3 are each x1
+ *                 # ports
+ * 0x1,0x2,0xC,0x0 # Phys 0 and 1 are each x1 ports, phy 2 and phy 3 are a x2
+ *                 # port
+ * 0x3,0x0,0xC,0x0 # Phys 0 and 1 are a x2 port, phy 2 and phy 3 are a x2 port
+ * 0x1,0x2,0x4,0x8 # Each phy is a x1 port (this is the default configuration)
+ *
+ * if there is a port/phy on which you do not wish to override the default
+ * values, use the value assigned to UNINIT_PARAM (255).
+ */
+
+/* discovery mode type (port auto config mode by default ) */
+
+/*
+ * if there is a port/phy on which you do not wish to override the default
+ * values, use the value "0000000000000000". SAS address of zero's is
+ * considered invalid and will not be used.
+ */
+#ifdef MPC
+static const int mode_type = SCIC_PORT_MANUAL_CONFIGURATION_MODE;
+static const __u8 phy_mask[2][4] = { {1, 2, 4, 8},
+				     {1, 2, 4, 8} };
+static const unsigned long long sas_addr[2][4] = { { 0x5FCFFFFFF0000001ULL,
+						     0x5FCFFFFFF0000002ULL,
+						     0x5FCFFFFFF0000003ULL,
+						     0x5FCFFFFFF0000004ULL },
+						   { 0x5FCFFFFFF0000005ULL,
+						     0x5FCFFFFFF0000006ULL,
+						     0x5FCFFFFFF0000007ULL,
+						     0x5FCFFFFFF0000008ULL } };
+#else	/* APC (default) */
+static const int mode_type = SCIC_PORT_AUTOMATIC_CONFIGURATION_MODE;
+static const __u8 phy_mask[2][4];
+static const unsigned long long sas_addr[2][4] = { { 0x5FCFFFFF00000001ULL,
+						     0x5FCFFFFF00000001ULL,
+						     0x5FCFFFFF00000001ULL,
+						     0x5FCFFFFF00000001ULL },
+						   { 0x5FCFFFFF00000002ULL,
+						     0x5FCFFFFF00000002ULL,
+						     0x5FCFFFFF00000002ULL,
+						     0x5FCFFFFF00000002ULL } };
+#endif
+
+/* Maximum number of concurrent device spin up */
+static const int max_num_concurrent_dev_spin_up = 1;
+
+/* enable of ssc operation */
+static const int enable_ssc;
+
+/* AFE_TX_AMP_CONTROL */
+static const unsigned int afe_tx_amp_control0 = 0x000bdd08;
+static const unsigned int afe_tx_amp_control1 = 0x000ffc00;
+static const unsigned int afe_tx_amp_control2 = 0x000b7c09;
+static const unsigned int afe_tx_amp_control3 = 0x000afc6e;
+
+static const char blob_name[] = "isci_firmware.bin";
+static const char sig[] = "ISCUOEMB";
+static const unsigned char version = 0x10;
+
+#endif
diff -druN linux-2.6.39-libre/drivers/scsi/isci/firmware/Makefile linux-3.0-rc7-libre/drivers/scsi/isci/firmware/Makefile
--- linux-2.6.39-libre/drivers/scsi/isci/firmware/Makefile	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/scsi/isci/firmware/Makefile	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,19 @@
+# Makefile for create_fw
+#
+CC=gcc
+CFLAGS=-c -Wall -O2 -g
+LDFLAGS=
+SOURCES=create_fw.c
+OBJECTS=$(SOURCES:.cpp=.o)
+EXECUTABLE=create_fw
+
+all: $(SOURCES) $(EXECUTABLE)
+
+$(EXECUTABLE): $(OBJECTS)
+	$(CC) $(LDFLAGS) $(OBJECTS) -o $@
+
+.c.o:
+	$(CC) $(CFLAGS) $< -O $@
+
+clean:
+	rm -f *.o $(EXECUTABLE)
diff -druN linux-2.6.39-libre/drivers/scsi/isci/firmware/README linux-3.0-rc7-libre/drivers/scsi/isci/firmware/README
--- linux-2.6.39-libre/drivers/scsi/isci/firmware/README	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/scsi/isci/firmware/README	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,36 @@
+This defines the temporary binary blow we are to pass to the SCU
+driver to emulate the binary firmware that we will eventually be
+able to access via NVRAM on the SCU controller.
+
+The current size of the binary blob is expected to be 149 bytes or larger
+
+Header Types:
+0x1: Phy Masks
+0x2: Phy Gens
+0x3: SAS Addrs
+0xff: End of Data
+
+ID string - u8[12]: "#SCU MAGIC#\0"
+Version - u8: 1
+SubVersion - u8: 0
+
+Header Type - u8: 0x1
+Size - u8: 8
+Phy Mask - u32[8]
+
+Header Type - u8: 0x2
+Size - u8: 8
+Phy Gen - u32[8]
+
+Header Type - u8: 0x3
+Size - u8: 8
+Sas Addr - u64[8]
+
+Header Type - u8: 0xf
+
+
+==============================================================================
+
+Place isci_firmware.bin in /lib/firmware
+Be sure to recreate the initramfs image to include the firmware.
+
diff -druN linux-2.6.39-libre/drivers/scsi/isci/host.c linux-3.0-rc7-libre/drivers/scsi/isci/host.c
--- linux-2.6.39-libre/drivers/scsi/isci/host.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/scsi/isci/host.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,2751 @@
+/*
+ * This file is provided under a dual BSD/GPLv2 license.  When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * The full GNU General Public License is included in this distribution
+ * in the file called LICENSE.GPL.
+ *
+ * BSD LICENSE
+ *
+ * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in
+ *     the documentation and/or other materials provided with the
+ *     distribution.
+ *   * Neither the name of Intel Corporation nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include <linux/circ_buf.h>
+#include <linux/device.h>
+#include <scsi/sas.h>
+#include "host.h"
+#include "isci.h"
+#include "port.h"
+#include "host.h"
+#include "probe_roms.h"
+#include "remote_device.h"
+#include "request.h"
+#include "scu_completion_codes.h"
+#include "scu_event_codes.h"
+#include "registers.h"
+#include "scu_remote_node_context.h"
+#include "scu_task_context.h"
+
+#define SCU_CONTEXT_RAM_INIT_STALL_TIME      200
+
+#define smu_max_ports(dcc_value) \
+	(\
+		(((dcc_value) & SMU_DEVICE_CONTEXT_CAPACITY_MAX_LP_MASK) \
+		 >> SMU_DEVICE_CONTEXT_CAPACITY_MAX_LP_SHIFT) + 1 \
+	)
+
+#define smu_max_task_contexts(dcc_value)	\
+	(\
+		(((dcc_value) & SMU_DEVICE_CONTEXT_CAPACITY_MAX_TC_MASK) \
+		 >> SMU_DEVICE_CONTEXT_CAPACITY_MAX_TC_SHIFT) + 1 \
+	)
+
+#define smu_max_rncs(dcc_value) \
+	(\
+		(((dcc_value) & SMU_DEVICE_CONTEXT_CAPACITY_MAX_RNC_MASK) \
+		 >> SMU_DEVICE_CONTEXT_CAPACITY_MAX_RNC_SHIFT) + 1 \
+	)
+
+#define SCIC_SDS_CONTROLLER_PHY_START_TIMEOUT      100
+
+/**
+ *
+ *
+ * The number of milliseconds to wait while a given phy is consuming power
+ * before allowing another set of phys to consume power. Ultimately, this will
+ * be specified by OEM parameter.
+ */
+#define SCIC_SDS_CONTROLLER_POWER_CONTROL_INTERVAL 500
+
+/**
+ * NORMALIZE_PUT_POINTER() -
+ *
+ * This macro will normalize the completion queue put pointer so its value can
+ * be used as an array inde
+ */
+#define NORMALIZE_PUT_POINTER(x) \
+	((x) & SMU_COMPLETION_QUEUE_PUT_POINTER_MASK)
+
+
+/**
+ * NORMALIZE_EVENT_POINTER() -
+ *
+ * This macro will normalize the completion queue event entry so its value can
+ * be used as an index.
+ */
+#define NORMALIZE_EVENT_POINTER(x) \
+	(\
+		((x) & SMU_COMPLETION_QUEUE_GET_EVENT_POINTER_MASK) \
+		>> SMU_COMPLETION_QUEUE_GET_EVENT_POINTER_SHIFT	\
+	)
+
+/**
+ * NORMALIZE_GET_POINTER() -
+ *
+ * This macro will normalize the completion queue get pointer so its value can
+ * be used as an index into an array
+ */
+#define NORMALIZE_GET_POINTER(x) \
+	((x) & SMU_COMPLETION_QUEUE_GET_POINTER_MASK)
+
+/**
+ * NORMALIZE_GET_POINTER_CYCLE_BIT() -
+ *
+ * This macro will normalize the completion queue cycle pointer so it matches
+ * the completion queue cycle bit
+ */
+#define NORMALIZE_GET_POINTER_CYCLE_BIT(x) \
+	((SMU_CQGR_CYCLE_BIT & (x)) << (31 - SMU_COMPLETION_QUEUE_GET_CYCLE_BIT_SHIFT))
+
+/**
+ * COMPLETION_QUEUE_CYCLE_BIT() -
+ *
+ * This macro will return the cycle bit of the completion queue entry
+ */
+#define COMPLETION_QUEUE_CYCLE_BIT(x) ((x) & 0x80000000)
+
+/* Init the state machine and call the state entry function (if any) */
+void sci_init_sm(struct sci_base_state_machine *sm,
+		 const struct sci_base_state *state_table, u32 initial_state)
+{
+	sci_state_transition_t handler;
+
+	sm->initial_state_id    = initial_state;
+	sm->previous_state_id   = initial_state;
+	sm->current_state_id    = initial_state;
+	sm->state_table         = state_table;
+
+	handler = sm->state_table[initial_state].enter_state;
+	if (handler)
+		handler(sm);
+}
+
+/* Call the state exit fn, update the current state, call the state entry fn */
+void sci_change_state(struct sci_base_state_machine *sm, u32 next_state)
+{
+	sci_state_transition_t handler;
+
+	handler = sm->state_table[sm->current_state_id].exit_state;
+	if (handler)
+		handler(sm);
+
+	sm->previous_state_id = sm->current_state_id;
+	sm->current_state_id = next_state;
+
+	handler = sm->state_table[sm->current_state_id].enter_state;
+	if (handler)
+		handler(sm);
+}
+
+static bool sci_controller_completion_queue_has_entries(struct isci_host *ihost)
+{
+	u32 get_value = ihost->completion_queue_get;
+	u32 get_index = get_value & SMU_COMPLETION_QUEUE_GET_POINTER_MASK;
+
+	if (NORMALIZE_GET_POINTER_CYCLE_BIT(get_value) ==
+	    COMPLETION_QUEUE_CYCLE_BIT(ihost->completion_queue[get_index]))
+		return true;
+
+	return false;
+}
+
+static bool sci_controller_isr(struct isci_host *ihost)
+{
+	if (sci_controller_completion_queue_has_entries(ihost)) {
+		return true;
+	} else {
+		/*
+		 * we have a spurious interrupt it could be that we have already
+		 * emptied the completion queue from a previous interrupt */
+		writel(SMU_ISR_COMPLETION, &ihost->smu_registers->interrupt_status);
+
+		/*
+		 * There is a race in the hardware that could cause us not to be notified
+		 * of an interrupt completion if we do not take this step.  We will mask
+		 * then unmask the interrupts so if there is another interrupt pending
+		 * the clearing of the interrupt source we get the next interrupt message. */
+		writel(0xFF000000, &ihost->smu_registers->interrupt_mask);
+		writel(0, &ihost->smu_registers->interrupt_mask);
+	}
+
+	return false;
+}
+
+irqreturn_t isci_msix_isr(int vec, void *data)
+{
+	struct isci_host *ihost = data;
+
+	if (sci_controller_isr(ihost))
+		tasklet_schedule(&ihost->completion_tasklet);
+
+	return IRQ_HANDLED;
+}
+
+static bool sci_controller_error_isr(struct isci_host *ihost)
+{
+	u32 interrupt_status;
+
+	interrupt_status =
+		readl(&ihost->smu_registers->interrupt_status);
+	interrupt_status &= (SMU_ISR_QUEUE_ERROR | SMU_ISR_QUEUE_SUSPEND);
+
+	if (interrupt_status != 0) {
+		/*
+		 * There is an error interrupt pending so let it through and handle
+		 * in the callback */
+		return true;
+	}
+
+	/*
+	 * There is a race in the hardware that could cause us not to be notified
+	 * of an interrupt completion if we do not take this step.  We will mask
+	 * then unmask the error interrupts so if there was another interrupt
+	 * pending we will be notified.
+	 * Could we write the value of (SMU_ISR_QUEUE_ERROR | SMU_ISR_QUEUE_SUSPEND)? */
+	writel(0xff, &ihost->smu_registers->interrupt_mask);
+	writel(0, &ihost->smu_registers->interrupt_mask);
+
+	return false;
+}
+
+static void sci_controller_task_completion(struct isci_host *ihost, u32 ent)
+{
+	u32 index = SCU_GET_COMPLETION_INDEX(ent);
+	struct isci_request *ireq = ihost->reqs[index];
+
+	/* Make sure that we really want to process this IO request */
+	if (test_bit(IREQ_ACTIVE, &ireq->flags) &&
+	    ireq->io_tag != SCI_CONTROLLER_INVALID_IO_TAG &&
+	    ISCI_TAG_SEQ(ireq->io_tag) == ihost->io_request_sequence[index])
+		/* Yep this is a valid io request pass it along to the
+		 * io request handler
+		 */
+		sci_io_request_tc_completion(ireq, ent);
+}
+
+static void sci_controller_sdma_completion(struct isci_host *ihost, u32 ent)
+{
+	u32 index;
+	struct isci_request *ireq;
+	struct isci_remote_device *idev;
+
+	index = SCU_GET_COMPLETION_INDEX(ent);
+
+	switch (scu_get_command_request_type(ent)) {
+	case SCU_CONTEXT_COMMAND_REQUEST_TYPE_POST_TC:
+	case SCU_CONTEXT_COMMAND_REQUEST_TYPE_DUMP_TC:
+		ireq = ihost->reqs[index];
+		dev_warn(&ihost->pdev->dev, "%s: %x for io request %p\n",
+			 __func__, ent, ireq);
+		/* @todo For a post TC operation we need to fail the IO
+		 * request
+		 */
+		break;
+	case SCU_CONTEXT_COMMAND_REQUEST_TYPE_DUMP_RNC:
+	case SCU_CONTEXT_COMMAND_REQUEST_TYPE_OTHER_RNC:
+	case SCU_CONTEXT_COMMAND_REQUEST_TYPE_POST_RNC:
+		idev = ihost->device_table[index];
+		dev_warn(&ihost->pdev->dev, "%s: %x for device %p\n",
+			 __func__, ent, idev);
+		/* @todo For a port RNC operation we need to fail the
+		 * device
+		 */
+		break;
+	default:
+		dev_warn(&ihost->pdev->dev, "%s: unknown completion type %x\n",
+			 __func__, ent);
+		break;
+	}
+}
+
+static void sci_controller_unsolicited_frame(struct isci_host *ihost, u32 ent)
+{
+	u32 index;
+	u32 frame_index;
+
+	struct scu_unsolicited_frame_header *frame_header;
+	struct isci_phy *iphy;
+	struct isci_remote_device *idev;
+
+	enum sci_status result = SCI_FAILURE;
+
+	frame_index = SCU_GET_FRAME_INDEX(ent);
+
+	frame_header = ihost->uf_control.buffers.array[frame_index].header;
+	ihost->uf_control.buffers.array[frame_index].state = UNSOLICITED_FRAME_IN_USE;
+
+	if (SCU_GET_FRAME_ERROR(ent)) {
+		/*
+		 * / @todo If the IAF frame or SIGNATURE FIS frame has an error will
+		 * /       this cause a problem? We expect the phy initialization will
+		 * /       fail if there is an error in the frame. */
+		sci_controller_release_frame(ihost, frame_index);
+		return;
+	}
+
+	if (frame_header->is_address_frame) {
+		index = SCU_GET_PROTOCOL_ENGINE_INDEX(ent);
+		iphy = &ihost->phys[index];
+		result = sci_phy_frame_handler(iphy, frame_index);
+	} else {
+
+		index = SCU_GET_COMPLETION_INDEX(ent);
+
+		if (index == SCIC_SDS_REMOTE_NODE_CONTEXT_INVALID_INDEX) {
+			/*
+			 * This is a signature fis or a frame from a direct attached SATA
+			 * device that has not yet been created.  In either case forwared
+			 * the frame to the PE and let it take care of the frame data. */
+			index = SCU_GET_PROTOCOL_ENGINE_INDEX(ent);
+			iphy = &ihost->phys[index];
+			result = sci_phy_frame_handler(iphy, frame_index);
+		} else {
+			if (index < ihost->remote_node_entries)
+				idev = ihost->device_table[index];
+			else
+				idev = NULL;
+
+			if (idev != NULL)
+				result = sci_remote_device_frame_handler(idev, frame_index);
+			else
+				sci_controller_release_frame(ihost, frame_index);
+		}
+	}
+
+	if (result != SCI_SUCCESS) {
+		/*
+		 * / @todo Is there any reason to report some additional error message
+		 * /       when we get this failure notifiction? */
+	}
+}
+
+static void sci_controller_event_completion(struct isci_host *ihost, u32 ent)
+{
+	struct isci_remote_device *idev;
+	struct isci_request *ireq;
+	struct isci_phy *iphy;
+	u32 index;
+
+	index = SCU_GET_COMPLETION_INDEX(ent);
+
+	switch (scu_get_event_type(ent)) {
+	case SCU_EVENT_TYPE_SMU_COMMAND_ERROR:
+		/* / @todo The driver did something wrong and we need to fix the condtion. */
+		dev_err(&ihost->pdev->dev,
+			"%s: SCIC Controller 0x%p received SMU command error "
+			"0x%x\n",
+			__func__,
+			ihost,
+			ent);
+		break;
+
+	case SCU_EVENT_TYPE_SMU_PCQ_ERROR:
+	case SCU_EVENT_TYPE_SMU_ERROR:
+	case SCU_EVENT_TYPE_FATAL_MEMORY_ERROR:
+		/*
+		 * / @todo This is a hardware failure and its likely that we want to
+		 * /       reset the controller. */
+		dev_err(&ihost->pdev->dev,
+			"%s: SCIC Controller 0x%p received fatal controller "
+			"event  0x%x\n",
+			__func__,
+			ihost,
+			ent);
+		break;
+
+	case SCU_EVENT_TYPE_TRANSPORT_ERROR:
+		ireq = ihost->reqs[index];
+		sci_io_request_event_handler(ireq, ent);
+		break;
+
+	case SCU_EVENT_TYPE_PTX_SCHEDULE_EVENT:
+		switch (scu_get_event_specifier(ent)) {
+		case SCU_EVENT_SPECIFIC_SMP_RESPONSE_NO_PE:
+		case SCU_EVENT_SPECIFIC_TASK_TIMEOUT:
+			ireq = ihost->reqs[index];
+			if (ireq != NULL)
+				sci_io_request_event_handler(ireq, ent);
+			else
+				dev_warn(&ihost->pdev->dev,
+					 "%s: SCIC Controller 0x%p received "
+					 "event 0x%x for io request object "
+					 "that doesnt exist.\n",
+					 __func__,
+					 ihost,
+					 ent);
+
+			break;
+
+		case SCU_EVENT_SPECIFIC_IT_NEXUS_TIMEOUT:
+			idev = ihost->device_table[index];
+			if (idev != NULL)
+				sci_remote_device_event_handler(idev, ent);
+			else
+				dev_warn(&ihost->pdev->dev,
+					 "%s: SCIC Controller 0x%p received "
+					 "event 0x%x for remote device object "
+					 "that doesnt exist.\n",
+					 __func__,
+					 ihost,
+					 ent);
+
+			break;
+		}
+		break;
+
+	case SCU_EVENT_TYPE_BROADCAST_CHANGE:
+	/*
+	 * direct the broadcast change event to the phy first and then let
+	 * the phy redirect the broadcast change to the port object */
+	case SCU_EVENT_TYPE_ERR_CNT_EVENT:
+	/*
+	 * direct error counter event to the phy object since that is where
+	 * we get the event notification.  This is a type 4 event. */
+	case SCU_EVENT_TYPE_OSSP_EVENT:
+		index = SCU_GET_PROTOCOL_ENGINE_INDEX(ent);
+		iphy = &ihost->phys[index];
+		sci_phy_event_handler(iphy, ent);
+		break;
+
+	case SCU_EVENT_TYPE_RNC_SUSPEND_TX:
+	case SCU_EVENT_TYPE_RNC_SUSPEND_TX_RX:
+	case SCU_EVENT_TYPE_RNC_OPS_MISC:
+		if (index < ihost->remote_node_entries) {
+			idev = ihost->device_table[index];
+
+			if (idev != NULL)
+				sci_remote_device_event_handler(idev, ent);
+		} else
+			dev_err(&ihost->pdev->dev,
+				"%s: SCIC Controller 0x%p received event 0x%x "
+				"for remote device object 0x%0x that doesnt "
+				"exist.\n",
+				__func__,
+				ihost,
+				ent,
+				index);
+
+		break;
+
+	default:
+		dev_warn(&ihost->pdev->dev,
+			 "%s: SCIC Controller received unknown event code %x\n",
+			 __func__,
+			 ent);
+		break;
+	}
+}
+
+static void sci_controller_process_completions(struct isci_host *ihost)
+{
+	u32 completion_count = 0;
+	u32 ent;
+	u32 get_index;
+	u32 get_cycle;
+	u32 event_get;
+	u32 event_cycle;
+
+	dev_dbg(&ihost->pdev->dev,
+		"%s: completion queue begining get:0x%08x\n",
+		__func__,
+		ihost->completion_queue_get);
+
+	/* Get the component parts of the completion queue */
+	get_index = NORMALIZE_GET_POINTER(ihost->completion_queue_get);
+	get_cycle = SMU_CQGR_CYCLE_BIT & ihost->completion_queue_get;
+
+	event_get = NORMALIZE_EVENT_POINTER(ihost->completion_queue_get);
+	event_cycle = SMU_CQGR_EVENT_CYCLE_BIT & ihost->completion_queue_get;
+
+	while (
+		NORMALIZE_GET_POINTER_CYCLE_BIT(get_cycle)
+		== COMPLETION_QUEUE_CYCLE_BIT(ihost->completion_queue[get_index])
+		) {
+		completion_count++;
+
+		ent = ihost->completion_queue[get_index];
+
+		/* increment the get pointer and check for rollover to toggle the cycle bit */
+		get_cycle ^= ((get_index+1) & SCU_MAX_COMPLETION_QUEUE_ENTRIES) <<
+			     (SMU_COMPLETION_QUEUE_GET_CYCLE_BIT_SHIFT - SCU_MAX_COMPLETION_QUEUE_SHIFT);
+		get_index = (get_index+1) & (SCU_MAX_COMPLETION_QUEUE_ENTRIES-1);
+
+		dev_dbg(&ihost->pdev->dev,
+			"%s: completion queue entry:0x%08x\n",
+			__func__,
+			ent);
+
+		switch (SCU_GET_COMPLETION_TYPE(ent)) {
+		case SCU_COMPLETION_TYPE_TASK:
+			sci_controller_task_completion(ihost, ent);
+			break;
+
+		case SCU_COMPLETION_TYPE_SDMA:
+			sci_controller_sdma_completion(ihost, ent);
+			break;
+
+		case SCU_COMPLETION_TYPE_UFI:
+			sci_controller_unsolicited_frame(ihost, ent);
+			break;
+
+		case SCU_COMPLETION_TYPE_EVENT:
+		case SCU_COMPLETION_TYPE_NOTIFY: {
+			event_cycle ^= ((event_get+1) & SCU_MAX_EVENTS) <<
+				       (SMU_COMPLETION_QUEUE_GET_EVENT_CYCLE_BIT_SHIFT - SCU_MAX_EVENTS_SHIFT);
+			event_get = (event_get+1) & (SCU_MAX_EVENTS-1);
+
+			sci_controller_event_completion(ihost, ent);
+			break;
+		}
+		default:
+			dev_warn(&ihost->pdev->dev,
+				 "%s: SCIC Controller received unknown "
+				 "completion type %x\n",
+				 __func__,
+				 ent);
+			break;
+		}
+	}
+
+	/* Update the get register if we completed one or more entries */
+	if (completion_count > 0) {
+		ihost->completion_queue_get =
+			SMU_CQGR_GEN_BIT(ENABLE) |
+			SMU_CQGR_GEN_BIT(EVENT_ENABLE) |
+			event_cycle |
+			SMU_CQGR_GEN_VAL(EVENT_POINTER, event_get) |
+			get_cycle |
+			SMU_CQGR_GEN_VAL(POINTER, get_index);
+
+		writel(ihost->completion_queue_get,
+		       &ihost->smu_registers->completion_queue_get);
+
+	}
+
+	dev_dbg(&ihost->pdev->dev,
+		"%s: completion queue ending get:0x%08x\n",
+		__func__,
+		ihost->completion_queue_get);
+
+}
+
+static void sci_controller_error_handler(struct isci_host *ihost)
+{
+	u32 interrupt_status;
+
+	interrupt_status =
+		readl(&ihost->smu_registers->interrupt_status);
+
+	if ((interrupt_status & SMU_ISR_QUEUE_SUSPEND) &&
+	    sci_controller_completion_queue_has_entries(ihost)) {
+
+		sci_controller_process_completions(ihost);
+		writel(SMU_ISR_QUEUE_SUSPEND, &ihost->smu_registers->interrupt_status);
+	} else {
+		dev_err(&ihost->pdev->dev, "%s: status: %#x\n", __func__,
+			interrupt_status);
+
+		sci_change_state(&ihost->sm, SCIC_FAILED);
+
+		return;
+	}
+
+	/* If we dont process any completions I am not sure that we want to do this.
+	 * We are in the middle of a hardware fault and should probably be reset.
+	 */
+	writel(0, &ihost->smu_registers->interrupt_mask);
+}
+
+irqreturn_t isci_intx_isr(int vec, void *data)
+{
+	irqreturn_t ret = IRQ_NONE;
+	struct isci_host *ihost = data;
+
+	if (sci_controller_isr(ihost)) {
+		writel(SMU_ISR_COMPLETION, &ihost->smu_registers->interrupt_status);
+		tasklet_schedule(&ihost->completion_tasklet);
+		ret = IRQ_HANDLED;
+	} else if (sci_controller_error_isr(ihost)) {
+		spin_lock(&ihost->scic_lock);
+		sci_controller_error_handler(ihost);
+		spin_unlock(&ihost->scic_lock);
+		ret = IRQ_HANDLED;
+	}
+
+	return ret;
+}
+
+irqreturn_t isci_error_isr(int vec, void *data)
+{
+	struct isci_host *ihost = data;
+
+	if (sci_controller_error_isr(ihost))
+		sci_controller_error_handler(ihost);
+
+	return IRQ_HANDLED;
+}
+
+/**
+ * isci_host_start_complete() - This function is called by the core library,
+ *    through the ISCI Module, to indicate controller start status.
+ * @isci_host: This parameter specifies the ISCI host object
+ * @completion_status: This parameter specifies the completion status from the
+ *    core library.
+ *
+ */
+static void isci_host_start_complete(struct isci_host *ihost, enum sci_status completion_status)
+{
+	if (completion_status != SCI_SUCCESS)
+		dev_info(&ihost->pdev->dev,
+			"controller start timed out, continuing...\n");
+	isci_host_change_state(ihost, isci_ready);
+	clear_bit(IHOST_START_PENDING, &ihost->flags);
+	wake_up(&ihost->eventq);
+}
+
+int isci_host_scan_finished(struct Scsi_Host *shost, unsigned long time)
+{
+	struct isci_host *ihost = SHOST_TO_SAS_HA(shost)->lldd_ha;
+
+	if (test_bit(IHOST_START_PENDING, &ihost->flags))
+		return 0;
+
+	/* todo: use sas_flush_discovery once it is upstream */
+	scsi_flush_work(shost);
+
+	scsi_flush_work(shost);
+
+	dev_dbg(&ihost->pdev->dev,
+		"%s: ihost->status = %d, time = %ld\n",
+		 __func__, isci_host_get_state(ihost), time);
+
+	return 1;
+
+}
+
+/**
+ * sci_controller_get_suggested_start_timeout() - This method returns the
+ *    suggested sci_controller_start() timeout amount.  The user is free to
+ *    use any timeout value, but this method provides the suggested minimum
+ *    start timeout value.  The returned value is based upon empirical
+ *    information determined as a result of interoperability testing.
+ * @controller: the handle to the controller object for which to return the
+ *    suggested start timeout.
+ *
+ * This method returns the number of milliseconds for the suggested start
+ * operation timeout.
+ */
+static u32 sci_controller_get_suggested_start_timeout(struct isci_host *ihost)
+{
+	/* Validate the user supplied parameters. */
+	if (!ihost)
+		return 0;
+
+	/*
+	 * The suggested minimum timeout value for a controller start operation:
+	 *
+	 *     Signature FIS Timeout
+	 *   + Phy Start Timeout
+	 *   + Number of Phy Spin Up Intervals
+	 *   ---------------------------------
+	 *   Number of milliseconds for the controller start operation.
+	 *
+	 * NOTE: The number of phy spin up intervals will be equivalent
+	 *       to the number of phys divided by the number phys allowed
+	 *       per interval - 1 (once OEM parameters are supported).
+	 *       Currently we assume only 1 phy per interval. */
+
+	return SCIC_SDS_SIGNATURE_FIS_TIMEOUT
+		+ SCIC_SDS_CONTROLLER_PHY_START_TIMEOUT
+		+ ((SCI_MAX_PHYS - 1) * SCIC_SDS_CONTROLLER_POWER_CONTROL_INTERVAL);
+}
+
+static void sci_controller_enable_interrupts(struct isci_host *ihost)
+{
+	BUG_ON(ihost->smu_registers == NULL);
+	writel(0, &ihost->smu_registers->interrupt_mask);
+}
+
+void sci_controller_disable_interrupts(struct isci_host *ihost)
+{
+	BUG_ON(ihost->smu_registers == NULL);
+	writel(0xffffffff, &ihost->smu_registers->interrupt_mask);
+}
+
+static void sci_controller_enable_port_task_scheduler(struct isci_host *ihost)
+{
+	u32 port_task_scheduler_value;
+
+	port_task_scheduler_value =
+		readl(&ihost->scu_registers->peg0.ptsg.control);
+	port_task_scheduler_value |=
+		(SCU_PTSGCR_GEN_BIT(ETM_ENABLE) |
+		 SCU_PTSGCR_GEN_BIT(PTSG_ENABLE));
+	writel(port_task_scheduler_value,
+	       &ihost->scu_registers->peg0.ptsg.control);
+}
+
+static void sci_controller_assign_task_entries(struct isci_host *ihost)
+{
+	u32 task_assignment;
+
+	/*
+	 * Assign all the TCs to function 0
+	 * TODO: Do we actually need to read this register to write it back?
+	 */
+
+	task_assignment =
+		readl(&ihost->smu_registers->task_context_assignment[0]);
+
+	task_assignment |= (SMU_TCA_GEN_VAL(STARTING, 0)) |
+		(SMU_TCA_GEN_VAL(ENDING,  ihost->task_context_entries - 1)) |
+		(SMU_TCA_GEN_BIT(RANGE_CHECK_ENABLE));
+
+	writel(task_assignment,
+		&ihost->smu_registers->task_context_assignment[0]);
+
+}
+
+static void sci_controller_initialize_completion_queue(struct isci_host *ihost)
+{
+	u32 index;
+	u32 completion_queue_control_value;
+	u32 completion_queue_get_value;
+	u32 completion_queue_put_value;
+
+	ihost->completion_queue_get = 0;
+
+	completion_queue_control_value =
+		(SMU_CQC_QUEUE_LIMIT_SET(SCU_MAX_COMPLETION_QUEUE_ENTRIES - 1) |
+		 SMU_CQC_EVENT_LIMIT_SET(SCU_MAX_EVENTS - 1));
+
+	writel(completion_queue_control_value,
+	       &ihost->smu_registers->completion_queue_control);
+
+
+	/* Set the completion queue get pointer and enable the queue */
+	completion_queue_get_value = (
+		(SMU_CQGR_GEN_VAL(POINTER, 0))
+		| (SMU_CQGR_GEN_VAL(EVENT_POINTER, 0))
+		| (SMU_CQGR_GEN_BIT(ENABLE))
+		| (SMU_CQGR_GEN_BIT(EVENT_ENABLE))
+		);
+
+	writel(completion_queue_get_value,
+	       &ihost->smu_registers->completion_queue_get);
+
+	/* Set the completion queue put pointer */
+	completion_queue_put_value = (
+		(SMU_CQPR_GEN_VAL(POINTER, 0))
+		| (SMU_CQPR_GEN_VAL(EVENT_POINTER, 0))
+		);
+
+	writel(completion_queue_put_value,
+	       &ihost->smu_registers->completion_queue_put);
+
+	/* Initialize the cycle bit of the completion queue entries */
+	for (index = 0; index < SCU_MAX_COMPLETION_QUEUE_ENTRIES; index++) {
+		/*
+		 * If get.cycle_bit != completion_queue.cycle_bit
+		 * its not a valid completion queue entry
+		 * so at system start all entries are invalid */
+		ihost->completion_queue[index] = 0x80000000;
+	}
+}
+
+static void sci_controller_initialize_unsolicited_frame_queue(struct isci_host *ihost)
+{
+	u32 frame_queue_control_value;
+	u32 frame_queue_get_value;
+	u32 frame_queue_put_value;
+
+	/* Write the queue size */
+	frame_queue_control_value =
+		SCU_UFQC_GEN_VAL(QUEUE_SIZE, SCU_MAX_UNSOLICITED_FRAMES);
+
+	writel(frame_queue_control_value,
+	       &ihost->scu_registers->sdma.unsolicited_frame_queue_control);
+
+	/* Setup the get pointer for the unsolicited frame queue */
+	frame_queue_get_value = (
+		SCU_UFQGP_GEN_VAL(POINTER, 0)
+		|  SCU_UFQGP_GEN_BIT(ENABLE_BIT)
+		);
+
+	writel(frame_queue_get_value,
+	       &ihost->scu_registers->sdma.unsolicited_frame_get_pointer);
+	/* Setup the put pointer for the unsolicited frame queue */
+	frame_queue_put_value = SCU_UFQPP_GEN_VAL(POINTER, 0);
+	writel(frame_queue_put_value,
+	       &ihost->scu_registers->sdma.unsolicited_frame_put_pointer);
+}
+
+static void sci_controller_transition_to_ready(struct isci_host *ihost, enum sci_status status)
+{
+	if (ihost->sm.current_state_id == SCIC_STARTING) {
+		/*
+		 * We move into the ready state, because some of the phys/ports
+		 * may be up and operational.
+		 */
+		sci_change_state(&ihost->sm, SCIC_READY);
+
+		isci_host_start_complete(ihost, status);
+	}
+}
+
+static bool is_phy_starting(struct isci_phy *iphy)
+{
+	enum sci_phy_states state;
+
+	state = iphy->sm.current_state_id;
+	switch (state) {
+	case SCI_PHY_STARTING:
+	case SCI_PHY_SUB_INITIAL:
+	case SCI_PHY_SUB_AWAIT_SAS_SPEED_EN:
+	case SCI_PHY_SUB_AWAIT_IAF_UF:
+	case SCI_PHY_SUB_AWAIT_SAS_POWER:
+	case SCI_PHY_SUB_AWAIT_SATA_POWER:
+	case SCI_PHY_SUB_AWAIT_SATA_PHY_EN:
+	case SCI_PHY_SUB_AWAIT_SATA_SPEED_EN:
+	case SCI_PHY_SUB_AWAIT_SIG_FIS_UF:
+	case SCI_PHY_SUB_FINAL:
+		return true;
+	default:
+		return false;
+	}
+}
+
+/**
+ * sci_controller_start_next_phy - start phy
+ * @scic: controller
+ *
+ * If all the phys have been started, then attempt to transition the
+ * controller to the READY state and inform the user
+ * (sci_cb_controller_start_complete()).
+ */
+static enum sci_status sci_controller_start_next_phy(struct isci_host *ihost)
+{
+	struct sci_oem_params *oem = &ihost->oem_parameters;
+	struct isci_phy *iphy;
+	enum sci_status status;
+
+	status = SCI_SUCCESS;
+
+	if (ihost->phy_startup_timer_pending)
+		return status;
+
+	if (ihost->next_phy_to_start >= SCI_MAX_PHYS) {
+		bool is_controller_start_complete = true;
+		u32 state;
+		u8 index;
+
+		for (index = 0; index < SCI_MAX_PHYS; index++) {
+			iphy = &ihost->phys[index];
+			state = iphy->sm.current_state_id;
+
+			if (!phy_get_non_dummy_port(iphy))
+				continue;
+
+			/* The controller start operation is complete iff:
+			 * - all links have been given an opportunity to start
+			 * - have no indication of a connected device
+			 * - have an indication of a connected device and it has
+			 *   finished the link training process.
+			 */
+			if ((iphy->is_in_link_training == false && state == SCI_PHY_INITIAL) ||
+			    (iphy->is_in_link_training == false && state == SCI_PHY_STOPPED) ||
+			    (iphy->is_in_link_training == true && is_phy_starting(iphy))) {
+				is_controller_start_complete = false;
+				break;
+			}
+		}
+
+		/*
+		 * The controller has successfully finished the start process.
+		 * Inform the SCI Core user and transition to the READY state. */
+		if (is_controller_start_complete == true) {
+			sci_controller_transition_to_ready(ihost, SCI_SUCCESS);
+			sci_del_timer(&ihost->phy_timer);
+			ihost->phy_startup_timer_pending = false;
+		}
+	} else {
+		iphy = &ihost->phys[ihost->next_phy_to_start];
+
+		if (oem->controller.mode_type == SCIC_PORT_MANUAL_CONFIGURATION_MODE) {
+			if (phy_get_non_dummy_port(iphy) == NULL) {
+				ihost->next_phy_to_start++;
+
+				/* Caution recursion ahead be forwarned
+				 *
+				 * The PHY was never added to a PORT in MPC mode
+				 * so start the next phy in sequence This phy
+				 * will never go link up and will not draw power
+				 * the OEM parameters either configured the phy
+				 * incorrectly for the PORT or it was never
+				 * assigned to a PORT
+				 */
+				return sci_controller_start_next_phy(ihost);
+			}
+		}
+
+		status = sci_phy_start(iphy);
+
+		if (status == SCI_SUCCESS) {
+			sci_mod_timer(&ihost->phy_timer,
+				      SCIC_SDS_CONTROLLER_PHY_START_TIMEOUT);
+			ihost->phy_startup_timer_pending = true;
+		} else {
+			dev_warn(&ihost->pdev->dev,
+				 "%s: Controller stop operation failed "
+				 "to stop phy %d because of status "
+				 "%d.\n",
+				 __func__,
+				 ihost->phys[ihost->next_phy_to_start].phy_index,
+				 status);
+		}
+
+		ihost->next_phy_to_start++;
+	}
+
+	return status;
+}
+
+static void phy_startup_timeout(unsigned long data)
+{
+	struct sci_timer *tmr = (struct sci_timer *)data;
+	struct isci_host *ihost = container_of(tmr, typeof(*ihost), phy_timer);
+	unsigned long flags;
+	enum sci_status status;
+
+	spin_lock_irqsave(&ihost->scic_lock, flags);
+
+	if (tmr->cancel)
+		goto done;
+
+	ihost->phy_startup_timer_pending = false;
+
+	do {
+		status = sci_controller_start_next_phy(ihost);
+	} while (status != SCI_SUCCESS);
+
+done:
+	spin_unlock_irqrestore(&ihost->scic_lock, flags);
+}
+
+static u16 isci_tci_active(struct isci_host *ihost)
+{
+	return CIRC_CNT(ihost->tci_head, ihost->tci_tail, SCI_MAX_IO_REQUESTS);
+}
+
+static enum sci_status sci_controller_start(struct isci_host *ihost,
+					     u32 timeout)
+{
+	enum sci_status result;
+	u16 index;
+
+	if (ihost->sm.current_state_id != SCIC_INITIALIZED) {
+		dev_warn(&ihost->pdev->dev,
+			 "SCIC Controller start operation requested in "
+			 "invalid state\n");
+		return SCI_FAILURE_INVALID_STATE;
+	}
+
+	/* Build the TCi free pool */
+	BUILD_BUG_ON(SCI_MAX_IO_REQUESTS > 1 << sizeof(ihost->tci_pool[0]) * 8);
+	ihost->tci_head = 0;
+	ihost->tci_tail = 0;
+	for (index = 0; index < ihost->task_context_entries; index++)
+		isci_tci_free(ihost, index);
+
+	/* Build the RNi free pool */
+	sci_remote_node_table_initialize(&ihost->available_remote_nodes,
+					 ihost->remote_node_entries);
+
+	/*
+	 * Before anything else lets make sure we will not be
+	 * interrupted by the hardware.
+	 */
+	sci_controller_disable_interrupts(ihost);
+
+	/* Enable the port task scheduler */
+	sci_controller_enable_port_task_scheduler(ihost);
+
+	/* Assign all the task entries to ihost physical function */
+	sci_controller_assign_task_entries(ihost);
+
+	/* Now initialize the completion queue */
+	sci_controller_initialize_completion_queue(ihost);
+
+	/* Initialize the unsolicited frame queue for use */
+	sci_controller_initialize_unsolicited_frame_queue(ihost);
+
+	/* Start all of the ports on this controller */
+	for (index = 0; index < ihost->logical_port_entries; index++) {
+		struct isci_port *iport = &ihost->ports[index];
+
+		result = sci_port_start(iport);
+		if (result)
+			return result;
+	}
+
+	sci_controller_start_next_phy(ihost);
+
+	sci_mod_timer(&ihost->timer, timeout);
+
+	sci_change_state(&ihost->sm, SCIC_STARTING);
+
+	return SCI_SUCCESS;
+}
+
+void isci_host_scan_start(struct Scsi_Host *shost)
+{
+	struct isci_host *ihost = SHOST_TO_SAS_HA(shost)->lldd_ha;
+	unsigned long tmo = sci_controller_get_suggested_start_timeout(ihost);
+
+	set_bit(IHOST_START_PENDING, &ihost->flags);
+
+	spin_lock_irq(&ihost->scic_lock);
+	sci_controller_start(ihost, tmo);
+	sci_controller_enable_interrupts(ihost);
+	spin_unlock_irq(&ihost->scic_lock);
+}
+
+static void isci_host_stop_complete(struct isci_host *ihost, enum sci_status completion_status)
+{
+	isci_host_change_state(ihost, isci_stopped);
+	sci_controller_disable_interrupts(ihost);
+	clear_bit(IHOST_STOP_PENDING, &ihost->flags);
+	wake_up(&ihost->eventq);
+}
+
+static void sci_controller_completion_handler(struct isci_host *ihost)
+{
+	/* Empty out the completion queue */
+	if (sci_controller_completion_queue_has_entries(ihost))
+		sci_controller_process_completions(ihost);
+
+	/* Clear the interrupt and enable all interrupts again */
+	writel(SMU_ISR_COMPLETION, &ihost->smu_registers->interrupt_status);
+	/* Could we write the value of SMU_ISR_COMPLETION? */
+	writel(0xFF000000, &ihost->smu_registers->interrupt_mask);
+	writel(0, &ihost->smu_registers->interrupt_mask);
+}
+
+/**
+ * isci_host_completion_routine() - This function is the delayed service
+ *    routine that calls the sci core library's completion handler. It's
+ *    scheduled as a tasklet from the interrupt service routine when interrupts
+ *    in use, or set as the timeout function in polled mode.
+ * @data: This parameter specifies the ISCI host object
+ *
+ */
+static void isci_host_completion_routine(unsigned long data)
+{
+	struct isci_host *ihost = (struct isci_host *)data;
+	struct list_head    completed_request_list;
+	struct list_head    errored_request_list;
+	struct list_head    *current_position;
+	struct list_head    *next_position;
+	struct isci_request *request;
+	struct isci_request *next_request;
+	struct sas_task     *task;
+
+	INIT_LIST_HEAD(&completed_request_list);
+	INIT_LIST_HEAD(&errored_request_list);
+
+	spin_lock_irq(&ihost->scic_lock);
+
+	sci_controller_completion_handler(ihost);
+
+	/* Take the lists of completed I/Os from the host. */
+
+	list_splice_init(&ihost->requests_to_complete,
+			 &completed_request_list);
+
+	/* Take the list of errored I/Os from the host. */
+	list_splice_init(&ihost->requests_to_errorback,
+			 &errored_request_list);
+
+	spin_unlock_irq(&ihost->scic_lock);
+
+	/* Process any completions in the lists. */
+	list_for_each_safe(current_position, next_position,
+			   &completed_request_list) {
+
+		request = list_entry(current_position, struct isci_request,
+				     completed_node);
+		task = isci_request_access_task(request);
+
+		/* Normal notification (task_done) */
+		dev_dbg(&ihost->pdev->dev,
+			"%s: Normal - request/task = %p/%p\n",
+			__func__,
+			request,
+			task);
+
+		/* Return the task to libsas */
+		if (task != NULL) {
+
+			task->lldd_task = NULL;
+			if (!(task->task_state_flags & SAS_TASK_STATE_ABORTED)) {
+
+				/* If the task is already in the abort path,
+				* the task_done callback cannot be called.
+				*/
+				task->task_done(task);
+			}
+		}
+
+		spin_lock_irq(&ihost->scic_lock);
+		isci_free_tag(ihost, request->io_tag);
+		spin_unlock_irq(&ihost->scic_lock);
+	}
+	list_for_each_entry_safe(request, next_request, &errored_request_list,
+				 completed_node) {
+
+		task = isci_request_access_task(request);
+
+		/* Use sas_task_abort */
+		dev_warn(&ihost->pdev->dev,
+			 "%s: Error - request/task = %p/%p\n",
+			 __func__,
+			 request,
+			 task);
+
+		if (task != NULL) {
+
+			/* Put the task into the abort path if it's not there
+			 * already.
+			 */
+			if (!(task->task_state_flags & SAS_TASK_STATE_ABORTED))
+				sas_task_abort(task);
+
+		} else {
+			/* This is a case where the request has completed with a
+			 * status such that it needed further target servicing,
+			 * but the sas_task reference has already been removed
+			 * from the request.  Since it was errored, it was not
+			 * being aborted, so there is nothing to do except free
+			 * it.
+			 */
+
+			spin_lock_irq(&ihost->scic_lock);
+			/* Remove the request from the remote device's list
+			* of pending requests.
+			*/
+			list_del_init(&request->dev_node);
+			isci_free_tag(ihost, request->io_tag);
+			spin_unlock_irq(&ihost->scic_lock);
+		}
+	}
+
+}
+
+/**
+ * sci_controller_stop() - This method will stop an individual controller
+ *    object.This method will invoke the associated user callback upon
+ *    completion.  The completion callback is called when the following
+ *    conditions are met: -# the method return status is SCI_SUCCESS. -# the
+ *    controller has been quiesced. This method will ensure that all IO
+ *    requests are quiesced, phys are stopped, and all additional operation by
+ *    the hardware is halted.
+ * @controller: the handle to the controller object to stop.
+ * @timeout: This parameter specifies the number of milliseconds in which the
+ *    stop operation should complete.
+ *
+ * The controller must be in the STARTED or STOPPED state. Indicate if the
+ * controller stop method succeeded or failed in some way. SCI_SUCCESS if the
+ * stop operation successfully began. SCI_WARNING_ALREADY_IN_STATE if the
+ * controller is already in the STOPPED state. SCI_FAILURE_INVALID_STATE if the
+ * controller is not either in the STARTED or STOPPED states.
+ */
+static enum sci_status sci_controller_stop(struct isci_host *ihost, u32 timeout)
+{
+	if (ihost->sm.current_state_id != SCIC_READY) {
+		dev_warn(&ihost->pdev->dev,
+			 "SCIC Controller stop operation requested in "
+			 "invalid state\n");
+		return SCI_FAILURE_INVALID_STATE;
+	}
+
+	sci_mod_timer(&ihost->timer, timeout);
+	sci_change_state(&ihost->sm, SCIC_STOPPING);
+	return SCI_SUCCESS;
+}
+
+/**
+ * sci_controller_reset() - This method will reset the supplied core
+ *    controller regardless of the state of said controller.  This operation is
+ *    considered destructive.  In other words, all current operations are wiped
+ *    out.  No IO completions for outstanding devices occur.  Outstanding IO
+ *    requests are not aborted or completed at the actual remote device.
+ * @controller: the handle to the controller object to reset.
+ *
+ * Indicate if the controller reset method succeeded or failed in some way.
+ * SCI_SUCCESS if the reset operation successfully started. SCI_FATAL_ERROR if
+ * the controller reset operation is unable to complete.
+ */
+static enum sci_status sci_controller_reset(struct isci_host *ihost)
+{
+	switch (ihost->sm.current_state_id) {
+	case SCIC_RESET:
+	case SCIC_READY:
+	case SCIC_STOPPED:
+	case SCIC_FAILED:
+		/*
+		 * The reset operation is not a graceful cleanup, just
+		 * perform the state transition.
+		 */
+		sci_change_state(&ihost->sm, SCIC_RESETTING);
+		return SCI_SUCCESS;
+	default:
+		dev_warn(&ihost->pdev->dev,
+			 "SCIC Controller reset operation requested in "
+			 "invalid state\n");
+		return SCI_FAILURE_INVALID_STATE;
+	}
+}
+
+void isci_host_deinit(struct isci_host *ihost)
+{
+	int i;
+
+	isci_host_change_state(ihost, isci_stopping);
+	for (i = 0; i < SCI_MAX_PORTS; i++) {
+		struct isci_port *iport = &ihost->ports[i];
+		struct isci_remote_device *idev, *d;
+
+		list_for_each_entry_safe(idev, d, &iport->remote_dev_list, node) {
+			if (test_bit(IDEV_ALLOCATED, &idev->flags))
+				isci_remote_device_stop(ihost, idev);
+		}
+	}
+
+	set_bit(IHOST_STOP_PENDING, &ihost->flags);
+
+	spin_lock_irq(&ihost->scic_lock);
+	sci_controller_stop(ihost, SCIC_CONTROLLER_STOP_TIMEOUT);
+	spin_unlock_irq(&ihost->scic_lock);
+
+	wait_for_stop(ihost);
+	sci_controller_reset(ihost);
+
+	/* Cancel any/all outstanding port timers */
+	for (i = 0; i < ihost->logical_port_entries; i++) {
+		struct isci_port *iport = &ihost->ports[i];
+		del_timer_sync(&iport->timer.timer);
+	}
+
+	/* Cancel any/all outstanding phy timers */
+	for (i = 0; i < SCI_MAX_PHYS; i++) {
+		struct isci_phy *iphy = &ihost->phys[i];
+		del_timer_sync(&iphy->sata_timer.timer);
+	}
+
+	del_timer_sync(&ihost->port_agent.timer.timer);
+
+	del_timer_sync(&ihost->power_control.timer.timer);
+
+	del_timer_sync(&ihost->timer.timer);
+
+	del_timer_sync(&ihost->phy_timer.timer);
+}
+
+static void __iomem *scu_base(struct isci_host *isci_host)
+{
+	struct pci_dev *pdev = isci_host->pdev;
+	int id = isci_host->id;
+
+	return pcim_iomap_table(pdev)[SCI_SCU_BAR * 2] + SCI_SCU_BAR_SIZE * id;
+}
+
+static void __iomem *smu_base(struct isci_host *isci_host)
+{
+	struct pci_dev *pdev = isci_host->pdev;
+	int id = isci_host->id;
+
+	return pcim_iomap_table(pdev)[SCI_SMU_BAR * 2] + SCI_SMU_BAR_SIZE * id;
+}
+
+static void isci_user_parameters_get(struct sci_user_parameters *u)
+{
+	int i;
+
+	for (i = 0; i < SCI_MAX_PHYS; i++) {
+		struct sci_phy_user_params *u_phy = &u->phys[i];
+
+		u_phy->max_speed_generation = phy_gen;
+
+		/* we are not exporting these for now */
+		u_phy->align_insertion_frequency = 0x7f;
+		u_phy->in_connection_align_insertion_frequency = 0xff;
+		u_phy->notify_enable_spin_up_insertion_frequency = 0x33;
+	}
+
+	u->stp_inactivity_timeout = stp_inactive_to;
+	u->ssp_inactivity_timeout = ssp_inactive_to;
+	u->stp_max_occupancy_timeout = stp_max_occ_to;
+	u->ssp_max_occupancy_timeout = ssp_max_occ_to;
+	u->no_outbound_task_timeout = no_outbound_task_to;
+	u->max_number_concurrent_device_spin_up = max_concurr_spinup;
+}
+
+static void sci_controller_initial_state_enter(struct sci_base_state_machine *sm)
+{
+	struct isci_host *ihost = container_of(sm, typeof(*ihost), sm);
+
+	sci_change_state(&ihost->sm, SCIC_RESET);
+}
+
+static inline void sci_controller_starting_state_exit(struct sci_base_state_machine *sm)
+{
+	struct isci_host *ihost = container_of(sm, typeof(*ihost), sm);
+
+	sci_del_timer(&ihost->timer);
+}
+
+#define INTERRUPT_COALESCE_TIMEOUT_BASE_RANGE_LOWER_BOUND_NS 853
+#define INTERRUPT_COALESCE_TIMEOUT_BASE_RANGE_UPPER_BOUND_NS 1280
+#define INTERRUPT_COALESCE_TIMEOUT_MAX_US                    2700000
+#define INTERRUPT_COALESCE_NUMBER_MAX                        256
+#define INTERRUPT_COALESCE_TIMEOUT_ENCODE_MIN                7
+#define INTERRUPT_COALESCE_TIMEOUT_ENCODE_MAX                28
+
+/**
+ * sci_controller_set_interrupt_coalescence() - This method allows the user to
+ *    configure the interrupt coalescence.
+ * @controller: This parameter represents the handle to the controller object
+ *    for which its interrupt coalesce register is overridden.
+ * @coalesce_number: Used to control the number of entries in the Completion
+ *    Queue before an interrupt is generated. If the number of entries exceed
+ *    this number, an interrupt will be generated. The valid range of the input
+ *    is [0, 256]. A setting of 0 results in coalescing being disabled.
+ * @coalesce_timeout: Timeout value in microseconds. The valid range of the
+ *    input is [0, 2700000] . A setting of 0 is allowed and results in no
+ *    interrupt coalescing timeout.
+ *
+ * Indicate if the user successfully set the interrupt coalesce parameters.
+ * SCI_SUCCESS The user successfully updated the interrutp coalescence.
+ * SCI_FAILURE_INVALID_PARAMETER_VALUE The user input value is out of range.
+ */
+static enum sci_status
+sci_controller_set_interrupt_coalescence(struct isci_host *ihost,
+					 u32 coalesce_number,
+					 u32 coalesce_timeout)
+{
+	u8 timeout_encode = 0;
+	u32 min = 0;
+	u32 max = 0;
+
+	/* Check if the input parameters fall in the range. */
+	if (coalesce_number > INTERRUPT_COALESCE_NUMBER_MAX)
+		return SCI_FAILURE_INVALID_PARAMETER_VALUE;
+
+	/*
+	 *  Defined encoding for interrupt coalescing timeout:
+	 *              Value   Min      Max     Units
+	 *              -----   ---      ---     -----
+	 *              0       -        -       Disabled
+	 *              1       13.3     20.0    ns
+	 *              2       26.7     40.0
+	 *              3       53.3     80.0
+	 *              4       106.7    160.0
+	 *              5       213.3    320.0
+	 *              6       426.7    640.0
+	 *              7       853.3    1280.0
+	 *              8       1.7      2.6     us
+	 *              9       3.4      5.1
+	 *              10      6.8      10.2
+	 *              11      13.7     20.5
+	 *              12      27.3     41.0
+	 *              13      54.6     81.9
+	 *              14      109.2    163.8
+	 *              15      218.5    327.7
+	 *              16      436.9    655.4
+	 *              17      873.8    1310.7
+	 *              18      1.7      2.6     ms
+	 *              19      3.5      5.2
+	 *              20      7.0      10.5
+	 *              21      14.0     21.0
+	 *              22      28.0     41.9
+	 *              23      55.9     83.9
+	 *              24      111.8    167.8
+	 *              25      223.7    335.5
+	 *              26      447.4    671.1
+	 *              27      894.8    1342.2
+	 *              28      1.8      2.7     s
+	 *              Others Undefined */
+
+	/*
+	 * Use the table above to decide the encode of interrupt coalescing timeout
+	 * value for register writing. */
+	if (coalesce_timeout == 0)
+		timeout_encode = 0;
+	else{
+		/* make the timeout value in unit of (10 ns). */
+		coalesce_timeout = coalesce_timeout * 100;
+		min = INTERRUPT_COALESCE_TIMEOUT_BASE_RANGE_LOWER_BOUND_NS / 10;
+		max = INTERRUPT_COALESCE_TIMEOUT_BASE_RANGE_UPPER_BOUND_NS / 10;
+
+		/* get the encode of timeout for register writing. */
+		for (timeout_encode = INTERRUPT_COALESCE_TIMEOUT_ENCODE_MIN;
+		      timeout_encode <= INTERRUPT_COALESCE_TIMEOUT_ENCODE_MAX;
+		      timeout_encode++) {
+			if (min <= coalesce_timeout &&  max > coalesce_timeout)
+				break;
+			else if (coalesce_timeout >= max && coalesce_timeout < min * 2
+				 && coalesce_timeout <= INTERRUPT_COALESCE_TIMEOUT_MAX_US * 100) {
+				if ((coalesce_timeout - max) < (2 * min - coalesce_timeout))
+					break;
+				else{
+					timeout_encode++;
+					break;
+				}
+			} else {
+				max = max * 2;
+				min = min * 2;
+			}
+		}
+
+		if (timeout_encode == INTERRUPT_COALESCE_TIMEOUT_ENCODE_MAX + 1)
+			/* the value is out of range. */
+			return SCI_FAILURE_INVALID_PARAMETER_VALUE;
+	}
+
+	writel(SMU_ICC_GEN_VAL(NUMBER, coalesce_number) |
+	       SMU_ICC_GEN_VAL(TIMER, timeout_encode),
+	       &ihost->smu_registers->interrupt_coalesce_control);
+
+
+	ihost->interrupt_coalesce_number = (u16)coalesce_number;
+	ihost->interrupt_coalesce_timeout = coalesce_timeout / 100;
+
+	return SCI_SUCCESS;
+}
+
+
+static void sci_controller_ready_state_enter(struct sci_base_state_machine *sm)
+{
+	struct isci_host *ihost = container_of(sm, typeof(*ihost), sm);
+
+	/* set the default interrupt coalescence number and timeout value. */
+	sci_controller_set_interrupt_coalescence(ihost, 0x10, 250);
+}
+
+static void sci_controller_ready_state_exit(struct sci_base_state_machine *sm)
+{
+	struct isci_host *ihost = container_of(sm, typeof(*ihost), sm);
+
+	/* disable interrupt coalescence. */
+	sci_controller_set_interrupt_coalescence(ihost, 0, 0);
+}
+
+static enum sci_status sci_controller_stop_phys(struct isci_host *ihost)
+{
+	u32 index;
+	enum sci_status status;
+	enum sci_status phy_status;
+
+	status = SCI_SUCCESS;
+
+	for (index = 0; index < SCI_MAX_PHYS; index++) {
+		phy_status = sci_phy_stop(&ihost->phys[index]);
+
+		if (phy_status != SCI_SUCCESS &&
+		    phy_status != SCI_FAILURE_INVALID_STATE) {
+			status = SCI_FAILURE;
+
+			dev_warn(&ihost->pdev->dev,
+				 "%s: Controller stop operation failed to stop "
+				 "phy %d because of status %d.\n",
+				 __func__,
+				 ihost->phys[index].phy_index, phy_status);
+		}
+	}
+
+	return status;
+}
+
+static enum sci_status sci_controller_stop_ports(struct isci_host *ihost)
+{
+	u32 index;
+	enum sci_status port_status;
+	enum sci_status status = SCI_SUCCESS;
+
+	for (index = 0; index < ihost->logical_port_entries; index++) {
+		struct isci_port *iport = &ihost->ports[index];
+
+		port_status = sci_port_stop(iport);
+
+		if ((port_status != SCI_SUCCESS) &&
+		    (port_status != SCI_FAILURE_INVALID_STATE)) {
+			status = SCI_FAILURE;
+
+			dev_warn(&ihost->pdev->dev,
+				 "%s: Controller stop operation failed to "
+				 "stop port %d because of status %d.\n",
+				 __func__,
+				 iport->logical_port_index,
+				 port_status);
+		}
+	}
+
+	return status;
+}
+
+static enum sci_status sci_controller_stop_devices(struct isci_host *ihost)
+{
+	u32 index;
+	enum sci_status status;
+	enum sci_status device_status;
+
+	status = SCI_SUCCESS;
+
+	for (index = 0; index < ihost->remote_node_entries; index++) {
+		if (ihost->device_table[index] != NULL) {
+			/* / @todo What timeout value do we want to provide to this request? */
+			device_status = sci_remote_device_stop(ihost->device_table[index], 0);
+
+			if ((device_status != SCI_SUCCESS) &&
+			    (device_status != SCI_FAILURE_INVALID_STATE)) {
+				dev_warn(&ihost->pdev->dev,
+					 "%s: Controller stop operation failed "
+					 "to stop device 0x%p because of "
+					 "status %d.\n",
+					 __func__,
+					 ihost->device_table[index], device_status);
+			}
+		}
+	}
+
+	return status;
+}
+
+static void sci_controller_stopping_state_enter(struct sci_base_state_machine *sm)
+{
+	struct isci_host *ihost = container_of(sm, typeof(*ihost), sm);
+
+	/* Stop all of the components for this controller */
+	sci_controller_stop_phys(ihost);
+	sci_controller_stop_ports(ihost);
+	sci_controller_stop_devices(ihost);
+}
+
+static void sci_controller_stopping_state_exit(struct sci_base_state_machine *sm)
+{
+	struct isci_host *ihost = container_of(sm, typeof(*ihost), sm);
+
+	sci_del_timer(&ihost->timer);
+}
+
+static void sci_controller_reset_hardware(struct isci_host *ihost)
+{
+	/* Disable interrupts so we dont take any spurious interrupts */
+	sci_controller_disable_interrupts(ihost);
+
+	/* Reset the SCU */
+	writel(0xFFFFFFFF, &ihost->smu_registers->soft_reset_control);
+
+	/* Delay for 1ms to before clearing the CQP and UFQPR. */
+	udelay(1000);
+
+	/* The write to the CQGR clears the CQP */
+	writel(0x00000000, &ihost->smu_registers->completion_queue_get);
+
+	/* The write to the UFQGP clears the UFQPR */
+	writel(0, &ihost->scu_registers->sdma.unsolicited_frame_get_pointer);
+}
+
+static void sci_controller_resetting_state_enter(struct sci_base_state_machine *sm)
+{
+	struct isci_host *ihost = container_of(sm, typeof(*ihost), sm);
+
+	sci_controller_reset_hardware(ihost);
+	sci_change_state(&ihost->sm, SCIC_RESET);
+}
+
+static const struct sci_base_state sci_controller_state_table[] = {
+	[SCIC_INITIAL] = {
+		.enter_state = sci_controller_initial_state_enter,
+	},
+	[SCIC_RESET] = {},
+	[SCIC_INITIALIZING] = {},
+	[SCIC_INITIALIZED] = {},
+	[SCIC_STARTING] = {
+		.exit_state  = sci_controller_starting_state_exit,
+	},
+	[SCIC_READY] = {
+		.enter_state = sci_controller_ready_state_enter,
+		.exit_state  = sci_controller_ready_state_exit,
+	},
+	[SCIC_RESETTING] = {
+		.enter_state = sci_controller_resetting_state_enter,
+	},
+	[SCIC_STOPPING] = {
+		.enter_state = sci_controller_stopping_state_enter,
+		.exit_state = sci_controller_stopping_state_exit,
+	},
+	[SCIC_STOPPED] = {},
+	[SCIC_FAILED] = {}
+};
+
+static void sci_controller_set_default_config_parameters(struct isci_host *ihost)
+{
+	/* these defaults are overridden by the platform / firmware */
+	u16 index;
+
+	/* Default to APC mode. */
+	ihost->oem_parameters.controller.mode_type = SCIC_PORT_AUTOMATIC_CONFIGURATION_MODE;
+
+	/* Default to APC mode. */
+	ihost->oem_parameters.controller.max_concurrent_dev_spin_up = 1;
+
+	/* Default to no SSC operation. */
+	ihost->oem_parameters.controller.do_enable_ssc = false;
+
+	/* Initialize all of the port parameter information to narrow ports. */
+	for (index = 0; index < SCI_MAX_PORTS; index++) {
+		ihost->oem_parameters.ports[index].phy_mask = 0;
+	}
+
+	/* Initialize all of the phy parameter information. */
+	for (index = 0; index < SCI_MAX_PHYS; index++) {
+		/* Default to 6G (i.e. Gen 3) for now. */
+		ihost->user_parameters.phys[index].max_speed_generation = 3;
+
+		/* the frequencies cannot be 0 */
+		ihost->user_parameters.phys[index].align_insertion_frequency = 0x7f;
+		ihost->user_parameters.phys[index].in_connection_align_insertion_frequency = 0xff;
+		ihost->user_parameters.phys[index].notify_enable_spin_up_insertion_frequency = 0x33;
+
+		/*
+		 * Previous Vitesse based expanders had a arbitration issue that
+		 * is worked around by having the upper 32-bits of SAS address
+		 * with a value greater then the Vitesse company identifier.
+		 * Hence, usage of 0x5FCFFFFF. */
+		ihost->oem_parameters.phys[index].sas_address.low = 0x1 + ihost->id;
+		ihost->oem_parameters.phys[index].sas_address.high = 0x5FCFFFFF;
+	}
+
+	ihost->user_parameters.stp_inactivity_timeout = 5;
+	ihost->user_parameters.ssp_inactivity_timeout = 5;
+	ihost->user_parameters.stp_max_occupancy_timeout = 5;
+	ihost->user_parameters.ssp_max_occupancy_timeout = 20;
+	ihost->user_parameters.no_outbound_task_timeout = 20;
+}
+
+static void controller_timeout(unsigned long data)
+{
+	struct sci_timer *tmr = (struct sci_timer *)data;
+	struct isci_host *ihost = container_of(tmr, typeof(*ihost), timer);
+	struct sci_base_state_machine *sm = &ihost->sm;
+	unsigned long flags;
+
+	spin_lock_irqsave(&ihost->scic_lock, flags);
+
+	if (tmr->cancel)
+		goto done;
+
+	if (sm->current_state_id == SCIC_STARTING)
+		sci_controller_transition_to_ready(ihost, SCI_FAILURE_TIMEOUT);
+	else if (sm->current_state_id == SCIC_STOPPING) {
+		sci_change_state(sm, SCIC_FAILED);
+		isci_host_stop_complete(ihost, SCI_FAILURE_TIMEOUT);
+	} else	/* / @todo Now what do we want to do in this case? */
+		dev_err(&ihost->pdev->dev,
+			"%s: Controller timer fired when controller was not "
+			"in a state being timed.\n",
+			__func__);
+
+done:
+	spin_unlock_irqrestore(&ihost->scic_lock, flags);
+}
+
+static enum sci_status sci_controller_construct(struct isci_host *ihost,
+						void __iomem *scu_base,
+						void __iomem *smu_base)
+{
+	u8 i;
+
+	sci_init_sm(&ihost->sm, sci_controller_state_table, SCIC_INITIAL);
+
+	ihost->scu_registers = scu_base;
+	ihost->smu_registers = smu_base;
+
+	sci_port_configuration_agent_construct(&ihost->port_agent);
+
+	/* Construct the ports for this controller */
+	for (i = 0; i < SCI_MAX_PORTS; i++)
+		sci_port_construct(&ihost->ports[i], i, ihost);
+	sci_port_construct(&ihost->ports[i], SCIC_SDS_DUMMY_PORT, ihost);
+
+	/* Construct the phys for this controller */
+	for (i = 0; i < SCI_MAX_PHYS; i++) {
+		/* Add all the PHYs to the dummy port */
+		sci_phy_construct(&ihost->phys[i],
+				  &ihost->ports[SCI_MAX_PORTS], i);
+	}
+
+	ihost->invalid_phy_mask = 0;
+
+	sci_init_timer(&ihost->timer, controller_timeout);
+
+	/* Initialize the User and OEM parameters to default values. */
+	sci_controller_set_default_config_parameters(ihost);
+
+	return sci_controller_reset(ihost);
+}
+
+int sci_oem_parameters_validate(struct sci_oem_params *oem)
+{
+	int i;
+
+	for (i = 0; i < SCI_MAX_PORTS; i++)
+		if (oem->ports[i].phy_mask > SCIC_SDS_PARM_PHY_MASK_MAX)
+			return -EINVAL;
+
+	for (i = 0; i < SCI_MAX_PHYS; i++)
+		if (oem->phys[i].sas_address.high == 0 &&
+		    oem->phys[i].sas_address.low == 0)
+			return -EINVAL;
+
+	if (oem->controller.mode_type == SCIC_PORT_AUTOMATIC_CONFIGURATION_MODE) {
+		for (i = 0; i < SCI_MAX_PHYS; i++)
+			if (oem->ports[i].phy_mask != 0)
+				return -EINVAL;
+	} else if (oem->controller.mode_type == SCIC_PORT_MANUAL_CONFIGURATION_MODE) {
+		u8 phy_mask = 0;
+
+		for (i = 0; i < SCI_MAX_PHYS; i++)
+			phy_mask |= oem->ports[i].phy_mask;
+
+		if (phy_mask == 0)
+			return -EINVAL;
+	} else
+		return -EINVAL;
+
+	if (oem->controller.max_concurrent_dev_spin_up > MAX_CONCURRENT_DEVICE_SPIN_UP_COUNT)
+		return -EINVAL;
+
+	return 0;
+}
+
+static enum sci_status sci_oem_parameters_set(struct isci_host *ihost)
+{
+	u32 state = ihost->sm.current_state_id;
+
+	if (state == SCIC_RESET ||
+	    state == SCIC_INITIALIZING ||
+	    state == SCIC_INITIALIZED) {
+
+		if (sci_oem_parameters_validate(&ihost->oem_parameters))
+			return SCI_FAILURE_INVALID_PARAMETER_VALUE;
+
+		return SCI_SUCCESS;
+	}
+
+	return SCI_FAILURE_INVALID_STATE;
+}
+
+static void power_control_timeout(unsigned long data)
+{
+	struct sci_timer *tmr = (struct sci_timer *)data;
+	struct isci_host *ihost = container_of(tmr, typeof(*ihost), power_control.timer);
+	struct isci_phy *iphy;
+	unsigned long flags;
+	u8 i;
+
+	spin_lock_irqsave(&ihost->scic_lock, flags);
+
+	if (tmr->cancel)
+		goto done;
+
+	ihost->power_control.phys_granted_power = 0;
+
+	if (ihost->power_control.phys_waiting == 0) {
+		ihost->power_control.timer_started = false;
+		goto done;
+	}
+
+	for (i = 0; i < SCI_MAX_PHYS; i++) {
+
+		if (ihost->power_control.phys_waiting == 0)
+			break;
+
+		iphy = ihost->power_control.requesters[i];
+		if (iphy == NULL)
+			continue;
+
+		if (ihost->power_control.phys_granted_power >=
+		    ihost->oem_parameters.controller.max_concurrent_dev_spin_up)
+			break;
+
+		ihost->power_control.requesters[i] = NULL;
+		ihost->power_control.phys_waiting--;
+		ihost->power_control.phys_granted_power++;
+		sci_phy_consume_power_handler(iphy);
+	}
+
+	/*
+	 * It doesn't matter if the power list is empty, we need to start the
+	 * timer in case another phy becomes ready.
+	 */
+	sci_mod_timer(tmr, SCIC_SDS_CONTROLLER_POWER_CONTROL_INTERVAL);
+	ihost->power_control.timer_started = true;
+
+done:
+	spin_unlock_irqrestore(&ihost->scic_lock, flags);
+}
+
+void sci_controller_power_control_queue_insert(struct isci_host *ihost,
+					       struct isci_phy *iphy)
+{
+	BUG_ON(iphy == NULL);
+
+	if (ihost->power_control.phys_granted_power <
+	    ihost->oem_parameters.controller.max_concurrent_dev_spin_up) {
+		ihost->power_control.phys_granted_power++;
+		sci_phy_consume_power_handler(iphy);
+
+		/*
+		 * stop and start the power_control timer. When the timer fires, the
+		 * no_of_phys_granted_power will be set to 0
+		 */
+		if (ihost->power_control.timer_started)
+			sci_del_timer(&ihost->power_control.timer);
+
+		sci_mod_timer(&ihost->power_control.timer,
+				 SCIC_SDS_CONTROLLER_POWER_CONTROL_INTERVAL);
+		ihost->power_control.timer_started = true;
+
+	} else {
+		/* Add the phy in the waiting list */
+		ihost->power_control.requesters[iphy->phy_index] = iphy;
+		ihost->power_control.phys_waiting++;
+	}
+}
+
+void sci_controller_power_control_queue_remove(struct isci_host *ihost,
+					       struct isci_phy *iphy)
+{
+	BUG_ON(iphy == NULL);
+
+	if (ihost->power_control.requesters[iphy->phy_index])
+		ihost->power_control.phys_waiting--;
+
+	ihost->power_control.requesters[iphy->phy_index] = NULL;
+}
+
+#define AFE_REGISTER_WRITE_DELAY 10
+
+/* Initialize the AFE for this phy index. We need to read the AFE setup from
+ * the OEM parameters
+ */
+static void sci_controller_afe_initialization(struct isci_host *ihost)
+{
+	const struct sci_oem_params *oem = &ihost->oem_parameters;
+	struct pci_dev *pdev = ihost->pdev;
+	u32 afe_status;
+	u32 phy_id;
+
+	/* Clear DFX Status registers */
+	writel(0x0081000f, &ihost->scu_registers->afe.afe_dfx_master_control0);
+	udelay(AFE_REGISTER_WRITE_DELAY);
+
+	if (is_b0(pdev)) {
+		/* PM Rx Equalization Save, PM SPhy Rx Acknowledgement
+		 * Timer, PM Stagger Timer */
+		writel(0x0007BFFF, &ihost->scu_registers->afe.afe_pmsn_master_control2);
+		udelay(AFE_REGISTER_WRITE_DELAY);
+	}
+
+	/* Configure bias currents to normal */
+	if (is_a2(pdev))
+		writel(0x00005A00, &ihost->scu_registers->afe.afe_bias_control);
+	else if (is_b0(pdev) || is_c0(pdev))
+		writel(0x00005F00, &ihost->scu_registers->afe.afe_bias_control);
+
+	udelay(AFE_REGISTER_WRITE_DELAY);
+
+	/* Enable PLL */
+	if (is_b0(pdev) || is_c0(pdev))
+		writel(0x80040A08, &ihost->scu_registers->afe.afe_pll_control0);
+	else
+		writel(0x80040908, &ihost->scu_registers->afe.afe_pll_control0);
+
+	udelay(AFE_REGISTER_WRITE_DELAY);
+
+	/* Wait for the PLL to lock */
+	do {
+		afe_status = readl(&ihost->scu_registers->afe.afe_common_block_status);
+		udelay(AFE_REGISTER_WRITE_DELAY);
+	} while ((afe_status & 0x00001000) == 0);
+
+	if (is_a2(pdev)) {
+		/* Shorten SAS SNW lock time (RxLock timer value from 76 us to 50 us) */
+		writel(0x7bcc96ad, &ihost->scu_registers->afe.afe_pmsn_master_control0);
+		udelay(AFE_REGISTER_WRITE_DELAY);
+	}
+
+	for (phy_id = 0; phy_id < SCI_MAX_PHYS; phy_id++) {
+		const struct sci_phy_oem_params *oem_phy = &oem->phys[phy_id];
+
+		if (is_b0(pdev)) {
+			 /* Configure transmitter SSC parameters */
+			writel(0x00030000, &ihost->scu_registers->afe.scu_afe_xcvr[phy_id].afe_tx_ssc_control);
+			udelay(AFE_REGISTER_WRITE_DELAY);
+		} else if (is_c0(pdev)) {
+			 /* Configure transmitter SSC parameters */
+			writel(0x0003000, &ihost->scu_registers->afe.scu_afe_xcvr[phy_id].afe_tx_ssc_control);
+			udelay(AFE_REGISTER_WRITE_DELAY);
+
+			/*
+			 * All defaults, except the Receive Word Alignament/Comma Detect
+			 * Enable....(0xe800) */
+			writel(0x00004500, &ihost->scu_registers->afe.scu_afe_xcvr[phy_id].afe_xcvr_control0);
+			udelay(AFE_REGISTER_WRITE_DELAY);
+		} else {
+			/*
+			 * All defaults, except the Receive Word Alignament/Comma Detect
+			 * Enable....(0xe800) */
+			writel(0x00004512, &ihost->scu_registers->afe.scu_afe_xcvr[phy_id].afe_xcvr_control0);
+			udelay(AFE_REGISTER_WRITE_DELAY);
+
+			writel(0x0050100F, &ihost->scu_registers->afe.scu_afe_xcvr[phy_id].afe_xcvr_control1);
+			udelay(AFE_REGISTER_WRITE_DELAY);
+		}
+
+		/*
+		 * Power up TX and RX out from power down (PWRDNTX and PWRDNRX)
+		 * & increase TX int & ext bias 20%....(0xe85c) */
+		if (is_a2(pdev))
+			writel(0x000003F0, &ihost->scu_registers->afe.scu_afe_xcvr[phy_id].afe_channel_control);
+		else if (is_b0(pdev)) {
+			 /* Power down TX and RX (PWRDNTX and PWRDNRX) */
+			writel(0x000003D7, &ihost->scu_registers->afe.scu_afe_xcvr[phy_id].afe_channel_control);
+			udelay(AFE_REGISTER_WRITE_DELAY);
+
+			/*
+			 * Power up TX and RX out from power down (PWRDNTX and PWRDNRX)
+			 * & increase TX int & ext bias 20%....(0xe85c) */
+			writel(0x000003D4, &ihost->scu_registers->afe.scu_afe_xcvr[phy_id].afe_channel_control);
+		} else {
+			writel(0x000001E7, &ihost->scu_registers->afe.scu_afe_xcvr[phy_id].afe_channel_control);
+			udelay(AFE_REGISTER_WRITE_DELAY);
+
+			/*
+			 * Power up TX and RX out from power down (PWRDNTX and PWRDNRX)
+			 * & increase TX int & ext bias 20%....(0xe85c) */
+			writel(0x000001E4, &ihost->scu_registers->afe.scu_afe_xcvr[phy_id].afe_channel_control);
+		}
+		udelay(AFE_REGISTER_WRITE_DELAY);
+
+		if (is_a2(pdev)) {
+			/* Enable TX equalization (0xe824) */
+			writel(0x00040000, &ihost->scu_registers->afe.scu_afe_xcvr[phy_id].afe_tx_control);
+			udelay(AFE_REGISTER_WRITE_DELAY);
+		}
+
+		/*
+		 * RDPI=0x0(RX Power On), RXOOBDETPDNC=0x0, TPD=0x0(TX Power On),
+		 * RDD=0x0(RX Detect Enabled) ....(0xe800) */
+		writel(0x00004100, &ihost->scu_registers->afe.scu_afe_xcvr[phy_id].afe_xcvr_control0);
+		udelay(AFE_REGISTER_WRITE_DELAY);
+
+		/* Leave DFE/FFE on */
+		if (is_a2(pdev))
+			writel(0x3F11103F, &ihost->scu_registers->afe.scu_afe_xcvr[phy_id].afe_rx_ssc_control0);
+		else if (is_b0(pdev)) {
+			writel(0x3F11103F, &ihost->scu_registers->afe.scu_afe_xcvr[phy_id].afe_rx_ssc_control0);
+			udelay(AFE_REGISTER_WRITE_DELAY);
+			/* Enable TX equalization (0xe824) */
+			writel(0x00040000, &ihost->scu_registers->afe.scu_afe_xcvr[phy_id].afe_tx_control);
+		} else {
+			writel(0x0140DF0F, &ihost->scu_registers->afe.scu_afe_xcvr[phy_id].afe_rx_ssc_control1);
+			udelay(AFE_REGISTER_WRITE_DELAY);
+
+			writel(0x3F6F103F, &ihost->scu_registers->afe.scu_afe_xcvr[phy_id].afe_rx_ssc_control0);
+			udelay(AFE_REGISTER_WRITE_DELAY);
+
+			/* Enable TX equalization (0xe824) */
+			writel(0x00040000, &ihost->scu_registers->afe.scu_afe_xcvr[phy_id].afe_tx_control);
+		}
+
+		udelay(AFE_REGISTER_WRITE_DELAY);
+
+		writel(oem_phy->afe_tx_amp_control0,
+			&ihost->scu_registers->afe.scu_afe_xcvr[phy_id].afe_tx_amp_control0);
+		udelay(AFE_REGISTER_WRITE_DELAY);
+
+		writel(oem_phy->afe_tx_amp_control1,
+			&ihost->scu_registers->afe.scu_afe_xcvr[phy_id].afe_tx_amp_control1);
+		udelay(AFE_REGISTER_WRITE_DELAY);
+
+		writel(oem_phy->afe_tx_amp_control2,
+			&ihost->scu_registers->afe.scu_afe_xcvr[phy_id].afe_tx_amp_control2);
+		udelay(AFE_REGISTER_WRITE_DELAY);
+
+		writel(oem_phy->afe_tx_amp_control3,
+			&ihost->scu_registers->afe.scu_afe_xcvr[phy_id].afe_tx_amp_control3);
+		udelay(AFE_REGISTER_WRITE_DELAY);
+	}
+
+	/* Transfer control to the PEs */
+	writel(0x00010f00, &ihost->scu_registers->afe.afe_dfx_master_control0);
+	udelay(AFE_REGISTER_WRITE_DELAY);
+}
+
+static void sci_controller_initialize_power_control(struct isci_host *ihost)
+{
+	sci_init_timer(&ihost->power_control.timer, power_control_timeout);
+
+	memset(ihost->power_control.requesters, 0,
+	       sizeof(ihost->power_control.requesters));
+
+	ihost->power_control.phys_waiting = 0;
+	ihost->power_control.phys_granted_power = 0;
+}
+
+static enum sci_status sci_controller_initialize(struct isci_host *ihost)
+{
+	struct sci_base_state_machine *sm = &ihost->sm;
+	enum sci_status result = SCI_FAILURE;
+	unsigned long i, state, val;
+
+	if (ihost->sm.current_state_id != SCIC_RESET) {
+		dev_warn(&ihost->pdev->dev,
+			 "SCIC Controller initialize operation requested "
+			 "in invalid state\n");
+		return SCI_FAILURE_INVALID_STATE;
+	}
+
+	sci_change_state(sm, SCIC_INITIALIZING);
+
+	sci_init_timer(&ihost->phy_timer, phy_startup_timeout);
+
+	ihost->next_phy_to_start = 0;
+	ihost->phy_startup_timer_pending = false;
+
+	sci_controller_initialize_power_control(ihost);
+
+	/*
+	 * There is nothing to do here for B0 since we do not have to
+	 * program the AFE registers.
+	 * / @todo The AFE settings are supposed to be correct for the B0 but
+	 * /       presently they seem to be wrong. */
+	sci_controller_afe_initialization(ihost);
+
+
+	/* Take the hardware out of reset */
+	writel(0, &ihost->smu_registers->soft_reset_control);
+
+	/*
+	 * / @todo Provide meaningfull error code for hardware failure
+	 * result = SCI_FAILURE_CONTROLLER_HARDWARE; */
+	for (i = 100; i >= 1; i--) {
+		u32 status;
+
+		/* Loop until the hardware reports success */
+		udelay(SCU_CONTEXT_RAM_INIT_STALL_TIME);
+		status = readl(&ihost->smu_registers->control_status);
+
+		if ((status & SCU_RAM_INIT_COMPLETED) == SCU_RAM_INIT_COMPLETED)
+			break;
+	}
+	if (i == 0)
+		goto out;
+
+	/*
+	 * Determine what are the actaul device capacities that the
+	 * hardware will support */
+	val = readl(&ihost->smu_registers->device_context_capacity);
+
+	/* Record the smaller of the two capacity values */
+	ihost->logical_port_entries = min(smu_max_ports(val), SCI_MAX_PORTS);
+	ihost->task_context_entries = min(smu_max_task_contexts(val), SCI_MAX_IO_REQUESTS);
+	ihost->remote_node_entries = min(smu_max_rncs(val), SCI_MAX_REMOTE_DEVICES);
+
+	/*
+	 * Make all PEs that are unassigned match up with the
+	 * logical ports
+	 */
+	for (i = 0; i < ihost->logical_port_entries; i++) {
+		struct scu_port_task_scheduler_group_registers __iomem
+			*ptsg = &ihost->scu_registers->peg0.ptsg;
+
+		writel(i, &ptsg->protocol_engine[i]);
+	}
+
+	/* Initialize hardware PCI Relaxed ordering in DMA engines */
+	val = readl(&ihost->scu_registers->sdma.pdma_configuration);
+	val |= SCU_PDMACR_GEN_BIT(PCI_RELAXED_ORDERING_ENABLE);
+	writel(val, &ihost->scu_registers->sdma.pdma_configuration);
+
+	val = readl(&ihost->scu_registers->sdma.cdma_configuration);
+	val |= SCU_CDMACR_GEN_BIT(PCI_RELAXED_ORDERING_ENABLE);
+	writel(val, &ihost->scu_registers->sdma.cdma_configuration);
+
+	/*
+	 * Initialize the PHYs before the PORTs because the PHY registers
+	 * are accessed during the port initialization.
+	 */
+	for (i = 0; i < SCI_MAX_PHYS; i++) {
+		result = sci_phy_initialize(&ihost->phys[i],
+					    &ihost->scu_registers->peg0.pe[i].tl,
+					    &ihost->scu_registers->peg0.pe[i].ll);
+		if (result != SCI_SUCCESS)
+			goto out;
+	}
+
+	for (i = 0; i < ihost->logical_port_entries; i++) {
+		struct isci_port *iport = &ihost->ports[i];
+
+		iport->port_task_scheduler_registers = &ihost->scu_registers->peg0.ptsg.port[i];
+		iport->port_pe_configuration_register = &ihost->scu_registers->peg0.ptsg.protocol_engine[0];
+		iport->viit_registers = &ihost->scu_registers->peg0.viit[i];
+	}
+
+	result = sci_port_configuration_agent_initialize(ihost, &ihost->port_agent);
+
+ out:
+	/* Advance the controller state machine */
+	if (result == SCI_SUCCESS)
+		state = SCIC_INITIALIZED;
+	else
+		state = SCIC_FAILED;
+	sci_change_state(sm, state);
+
+	return result;
+}
+
+static enum sci_status sci_user_parameters_set(struct isci_host *ihost,
+					       struct sci_user_parameters *sci_parms)
+{
+	u32 state = ihost->sm.current_state_id;
+
+	if (state == SCIC_RESET ||
+	    state == SCIC_INITIALIZING ||
+	    state == SCIC_INITIALIZED) {
+		u16 index;
+
+		/*
+		 * Validate the user parameters.  If they are not legal, then
+		 * return a failure.
+		 */
+		for (index = 0; index < SCI_MAX_PHYS; index++) {
+			struct sci_phy_user_params *user_phy;
+
+			user_phy = &sci_parms->phys[index];
+
+			if (!((user_phy->max_speed_generation <=
+						SCIC_SDS_PARM_MAX_SPEED) &&
+			      (user_phy->max_speed_generation >
+						SCIC_SDS_PARM_NO_SPEED)))
+				return SCI_FAILURE_INVALID_PARAMETER_VALUE;
+
+			if (user_phy->in_connection_align_insertion_frequency <
+					3)
+				return SCI_FAILURE_INVALID_PARAMETER_VALUE;
+
+			if ((user_phy->in_connection_align_insertion_frequency <
+						3) ||
+			    (user_phy->align_insertion_frequency == 0) ||
+			    (user_phy->
+				notify_enable_spin_up_insertion_frequency ==
+						0))
+				return SCI_FAILURE_INVALID_PARAMETER_VALUE;
+		}
+
+		if ((sci_parms->stp_inactivity_timeout == 0) ||
+		    (sci_parms->ssp_inactivity_timeout == 0) ||
+		    (sci_parms->stp_max_occupancy_timeout == 0) ||
+		    (sci_parms->ssp_max_occupancy_timeout == 0) ||
+		    (sci_parms->no_outbound_task_timeout == 0))
+			return SCI_FAILURE_INVALID_PARAMETER_VALUE;
+
+		memcpy(&ihost->user_parameters, sci_parms, sizeof(*sci_parms));
+
+		return SCI_SUCCESS;
+	}
+
+	return SCI_FAILURE_INVALID_STATE;
+}
+
+static int sci_controller_mem_init(struct isci_host *ihost)
+{
+	struct device *dev = &ihost->pdev->dev;
+	dma_addr_t dma;
+	size_t size;
+	int err;
+
+	size = SCU_MAX_COMPLETION_QUEUE_ENTRIES * sizeof(u32);
+	ihost->completion_queue = dmam_alloc_coherent(dev, size, &dma, GFP_KERNEL);
+	if (!ihost->completion_queue)
+		return -ENOMEM;
+
+	writel(lower_32_bits(dma), &ihost->smu_registers->completion_queue_lower);
+	writel(upper_32_bits(dma), &ihost->smu_registers->completion_queue_upper);
+
+	size = ihost->remote_node_entries * sizeof(union scu_remote_node_context);
+	ihost->remote_node_context_table = dmam_alloc_coherent(dev, size, &dma,
+							       GFP_KERNEL);
+	if (!ihost->remote_node_context_table)
+		return -ENOMEM;
+
+	writel(lower_32_bits(dma), &ihost->smu_registers->remote_node_context_lower);
+	writel(upper_32_bits(dma), &ihost->smu_registers->remote_node_context_upper);
+
+	size = ihost->task_context_entries * sizeof(struct scu_task_context),
+	ihost->task_context_table = dmam_alloc_coherent(dev, size, &dma, GFP_KERNEL);
+	if (!ihost->task_context_table)
+		return -ENOMEM;
+
+	ihost->task_context_dma = dma;
+	writel(lower_32_bits(dma), &ihost->smu_registers->host_task_table_lower);
+	writel(upper_32_bits(dma), &ihost->smu_registers->host_task_table_upper);
+
+	err = sci_unsolicited_frame_control_construct(ihost);
+	if (err)
+		return err;
+
+	/*
+	 * Inform the silicon as to the location of the UF headers and
+	 * address table.
+	 */
+	writel(lower_32_bits(ihost->uf_control.headers.physical_address),
+		&ihost->scu_registers->sdma.uf_header_base_address_lower);
+	writel(upper_32_bits(ihost->uf_control.headers.physical_address),
+		&ihost->scu_registers->sdma.uf_header_base_address_upper);
+
+	writel(lower_32_bits(ihost->uf_control.address_table.physical_address),
+		&ihost->scu_registers->sdma.uf_address_table_lower);
+	writel(upper_32_bits(ihost->uf_control.address_table.physical_address),
+		&ihost->scu_registers->sdma.uf_address_table_upper);
+
+	return 0;
+}
+
+int isci_host_init(struct isci_host *ihost)
+{
+	int err = 0, i;
+	enum sci_status status;
+	struct sci_user_parameters sci_user_params;
+	struct isci_pci_info *pci_info = to_pci_info(ihost->pdev);
+
+	spin_lock_init(&ihost->state_lock);
+	spin_lock_init(&ihost->scic_lock);
+	init_waitqueue_head(&ihost->eventq);
+
+	isci_host_change_state(ihost, isci_starting);
+
+	status = sci_controller_construct(ihost, scu_base(ihost),
+					  smu_base(ihost));
+
+	if (status != SCI_SUCCESS) {
+		dev_err(&ihost->pdev->dev,
+			"%s: sci_controller_construct failed - status = %x\n",
+			__func__,
+			status);
+		return -ENODEV;
+	}
+
+	ihost->sas_ha.dev = &ihost->pdev->dev;
+	ihost->sas_ha.lldd_ha = ihost;
+
+	/*
+	 * grab initial values stored in the controller object for OEM and USER
+	 * parameters
+	 */
+	isci_user_parameters_get(&sci_user_params);
+	status = sci_user_parameters_set(ihost, &sci_user_params);
+	if (status != SCI_SUCCESS) {
+		dev_warn(&ihost->pdev->dev,
+			 "%s: sci_user_parameters_set failed\n",
+			 __func__);
+		return -ENODEV;
+	}
+
+	/* grab any OEM parameters specified in orom */
+	if (pci_info->orom) {
+		status = isci_parse_oem_parameters(&ihost->oem_parameters,
+						   pci_info->orom,
+						   ihost->id);
+		if (status != SCI_SUCCESS) {
+			dev_warn(&ihost->pdev->dev,
+				 "parsing firmware oem parameters failed\n");
+			return -EINVAL;
+		}
+	}
+
+	status = sci_oem_parameters_set(ihost);
+	if (status != SCI_SUCCESS) {
+		dev_warn(&ihost->pdev->dev,
+				"%s: sci_oem_parameters_set failed\n",
+				__func__);
+		return -ENODEV;
+	}
+
+	tasklet_init(&ihost->completion_tasklet,
+		     isci_host_completion_routine, (unsigned long)ihost);
+
+	INIT_LIST_HEAD(&ihost->requests_to_complete);
+	INIT_LIST_HEAD(&ihost->requests_to_errorback);
+
+	spin_lock_irq(&ihost->scic_lock);
+	status = sci_controller_initialize(ihost);
+	spin_unlock_irq(&ihost->scic_lock);
+	if (status != SCI_SUCCESS) {
+		dev_warn(&ihost->pdev->dev,
+			 "%s: sci_controller_initialize failed -"
+			 " status = 0x%x\n",
+			 __func__, status);
+		return -ENODEV;
+	}
+
+	err = sci_controller_mem_init(ihost);
+	if (err)
+		return err;
+
+	for (i = 0; i < SCI_MAX_PORTS; i++)
+		isci_port_init(&ihost->ports[i], ihost, i);
+
+	for (i = 0; i < SCI_MAX_PHYS; i++)
+		isci_phy_init(&ihost->phys[i], ihost, i);
+
+	for (i = 0; i < SCI_MAX_REMOTE_DEVICES; i++) {
+		struct isci_remote_device *idev = &ihost->devices[i];
+
+		INIT_LIST_HEAD(&idev->reqs_in_process);
+		INIT_LIST_HEAD(&idev->node);
+	}
+
+	for (i = 0; i < SCI_MAX_IO_REQUESTS; i++) {
+		struct isci_request *ireq;
+		dma_addr_t dma;
+
+		ireq = dmam_alloc_coherent(&ihost->pdev->dev,
+					   sizeof(struct isci_request), &dma,
+					   GFP_KERNEL);
+		if (!ireq)
+			return -ENOMEM;
+
+		ireq->tc = &ihost->task_context_table[i];
+		ireq->owning_controller = ihost;
+		spin_lock_init(&ireq->state_lock);
+		ireq->request_daddr = dma;
+		ireq->isci_host = ihost;
+		ihost->reqs[i] = ireq;
+	}
+
+	return 0;
+}
+
+void sci_controller_link_up(struct isci_host *ihost, struct isci_port *iport,
+			    struct isci_phy *iphy)
+{
+	switch (ihost->sm.current_state_id) {
+	case SCIC_STARTING:
+		sci_del_timer(&ihost->phy_timer);
+		ihost->phy_startup_timer_pending = false;
+		ihost->port_agent.link_up_handler(ihost, &ihost->port_agent,
+						  iport, iphy);
+		sci_controller_start_next_phy(ihost);
+		break;
+	case SCIC_READY:
+		ihost->port_agent.link_up_handler(ihost, &ihost->port_agent,
+						  iport, iphy);
+		break;
+	default:
+		dev_dbg(&ihost->pdev->dev,
+			"%s: SCIC Controller linkup event from phy %d in "
+			"unexpected state %d\n", __func__, iphy->phy_index,
+			ihost->sm.current_state_id);
+	}
+}
+
+void sci_controller_link_down(struct isci_host *ihost, struct isci_port *iport,
+			      struct isci_phy *iphy)
+{
+	switch (ihost->sm.current_state_id) {
+	case SCIC_STARTING:
+	case SCIC_READY:
+		ihost->port_agent.link_down_handler(ihost, &ihost->port_agent,
+						   iport, iphy);
+		break;
+	default:
+		dev_dbg(&ihost->pdev->dev,
+			"%s: SCIC Controller linkdown event from phy %d in "
+			"unexpected state %d\n",
+			__func__,
+			iphy->phy_index,
+			ihost->sm.current_state_id);
+	}
+}
+
+static bool sci_controller_has_remote_devices_stopping(struct isci_host *ihost)
+{
+	u32 index;
+
+	for (index = 0; index < ihost->remote_node_entries; index++) {
+		if ((ihost->device_table[index] != NULL) &&
+		   (ihost->device_table[index]->sm.current_state_id == SCI_DEV_STOPPING))
+			return true;
+	}
+
+	return false;
+}
+
+void sci_controller_remote_device_stopped(struct isci_host *ihost,
+					  struct isci_remote_device *idev)
+{
+	if (ihost->sm.current_state_id != SCIC_STOPPING) {
+		dev_dbg(&ihost->pdev->dev,
+			"SCIC Controller 0x%p remote device stopped event "
+			"from device 0x%p in unexpected state %d\n",
+			ihost, idev,
+			ihost->sm.current_state_id);
+		return;
+	}
+
+	if (!sci_controller_has_remote_devices_stopping(ihost))
+		sci_change_state(&ihost->sm, SCIC_STOPPED);
+}
+
+void sci_controller_post_request(struct isci_host *ihost, u32 request)
+{
+	dev_dbg(&ihost->pdev->dev, "%s[%d]: %#x\n",
+		__func__, ihost->id, request);
+
+	writel(request, &ihost->smu_registers->post_context_port);
+}
+
+struct isci_request *sci_request_by_tag(struct isci_host *ihost, u16 io_tag)
+{
+	u16 task_index;
+	u16 task_sequence;
+
+	task_index = ISCI_TAG_TCI(io_tag);
+
+	if (task_index < ihost->task_context_entries) {
+		struct isci_request *ireq = ihost->reqs[task_index];
+
+		if (test_bit(IREQ_ACTIVE, &ireq->flags)) {
+			task_sequence = ISCI_TAG_SEQ(io_tag);
+
+			if (task_sequence == ihost->io_request_sequence[task_index])
+				return ireq;
+		}
+	}
+
+	return NULL;
+}
+
+/**
+ * This method allocates remote node index and the reserves the remote node
+ *    context space for use. This method can fail if there are no more remote
+ *    node index available.
+ * @scic: This is the controller object which contains the set of
+ *    free remote node ids
+ * @sci_dev: This is the device object which is requesting the a remote node
+ *    id
+ * @node_id: This is the remote node id that is assinged to the device if one
+ *    is available
+ *
+ * enum sci_status SCI_FAILURE_OUT_OF_RESOURCES if there are no available remote
+ * node index available.
+ */
+enum sci_status sci_controller_allocate_remote_node_context(struct isci_host *ihost,
+							    struct isci_remote_device *idev,
+							    u16 *node_id)
+{
+	u16 node_index;
+	u32 remote_node_count = sci_remote_device_node_count(idev);
+
+	node_index = sci_remote_node_table_allocate_remote_node(
+		&ihost->available_remote_nodes, remote_node_count
+		);
+
+	if (node_index != SCIC_SDS_REMOTE_NODE_CONTEXT_INVALID_INDEX) {
+		ihost->device_table[node_index] = idev;
+
+		*node_id = node_index;
+
+		return SCI_SUCCESS;
+	}
+
+	return SCI_FAILURE_INSUFFICIENT_RESOURCES;
+}
+
+void sci_controller_free_remote_node_context(struct isci_host *ihost,
+					     struct isci_remote_device *idev,
+					     u16 node_id)
+{
+	u32 remote_node_count = sci_remote_device_node_count(idev);
+
+	if (ihost->device_table[node_id] == idev) {
+		ihost->device_table[node_id] = NULL;
+
+		sci_remote_node_table_release_remote_node_index(
+			&ihost->available_remote_nodes, remote_node_count, node_id
+			);
+	}
+}
+
+void sci_controller_copy_sata_response(void *response_buffer,
+				       void *frame_header,
+				       void *frame_buffer)
+{
+	/* XXX type safety? */
+	memcpy(response_buffer, frame_header, sizeof(u32));
+
+	memcpy(response_buffer + sizeof(u32),
+	       frame_buffer,
+	       sizeof(struct dev_to_host_fis) - sizeof(u32));
+}
+
+void sci_controller_release_frame(struct isci_host *ihost, u32 frame_index)
+{
+	if (sci_unsolicited_frame_control_release_frame(&ihost->uf_control, frame_index))
+		writel(ihost->uf_control.get,
+			&ihost->scu_registers->sdma.unsolicited_frame_get_pointer);
+}
+
+void isci_tci_free(struct isci_host *ihost, u16 tci)
+{
+	u16 tail = ihost->tci_tail & (SCI_MAX_IO_REQUESTS-1);
+
+	ihost->tci_pool[tail] = tci;
+	ihost->tci_tail = tail + 1;
+}
+
+static u16 isci_tci_alloc(struct isci_host *ihost)
+{
+	u16 head = ihost->tci_head & (SCI_MAX_IO_REQUESTS-1);
+	u16 tci = ihost->tci_pool[head];
+
+	ihost->tci_head = head + 1;
+	return tci;
+}
+
+static u16 isci_tci_space(struct isci_host *ihost)
+{
+	return CIRC_SPACE(ihost->tci_head, ihost->tci_tail, SCI_MAX_IO_REQUESTS);
+}
+
+u16 isci_alloc_tag(struct isci_host *ihost)
+{
+	if (isci_tci_space(ihost)) {
+		u16 tci = isci_tci_alloc(ihost);
+		u8 seq = ihost->io_request_sequence[tci];
+
+		return ISCI_TAG(seq, tci);
+	}
+
+	return SCI_CONTROLLER_INVALID_IO_TAG;
+}
+
+enum sci_status isci_free_tag(struct isci_host *ihost, u16 io_tag)
+{
+	u16 tci = ISCI_TAG_TCI(io_tag);
+	u16 seq = ISCI_TAG_SEQ(io_tag);
+
+	/* prevent tail from passing head */
+	if (isci_tci_active(ihost) == 0)
+		return SCI_FAILURE_INVALID_IO_TAG;
+
+	if (seq == ihost->io_request_sequence[tci]) {
+		ihost->io_request_sequence[tci] = (seq+1) & (SCI_MAX_SEQ-1);
+
+		isci_tci_free(ihost, tci);
+
+		return SCI_SUCCESS;
+	}
+	return SCI_FAILURE_INVALID_IO_TAG;
+}
+
+enum sci_status sci_controller_start_io(struct isci_host *ihost,
+					struct isci_remote_device *idev,
+					struct isci_request *ireq)
+{
+	enum sci_status status;
+
+	if (ihost->sm.current_state_id != SCIC_READY) {
+		dev_warn(&ihost->pdev->dev, "invalid state to start I/O");
+		return SCI_FAILURE_INVALID_STATE;
+	}
+
+	status = sci_remote_device_start_io(ihost, idev, ireq);
+	if (status != SCI_SUCCESS)
+		return status;
+
+	set_bit(IREQ_ACTIVE, &ireq->flags);
+	sci_controller_post_request(ihost, ireq->post_context);
+	return SCI_SUCCESS;
+}
+
+enum sci_status sci_controller_terminate_request(struct isci_host *ihost,
+						 struct isci_remote_device *idev,
+						 struct isci_request *ireq)
+{
+	/* terminate an ongoing (i.e. started) core IO request.  This does not
+	 * abort the IO request at the target, but rather removes the IO
+	 * request from the host controller.
+	 */
+	enum sci_status status;
+
+	if (ihost->sm.current_state_id != SCIC_READY) {
+		dev_warn(&ihost->pdev->dev,
+			 "invalid state to terminate request\n");
+		return SCI_FAILURE_INVALID_STATE;
+	}
+
+	status = sci_io_request_terminate(ireq);
+	if (status != SCI_SUCCESS)
+		return status;
+
+	/*
+	 * Utilize the original post context command and or in the POST_TC_ABORT
+	 * request sub-type.
+	 */
+	sci_controller_post_request(ihost,
+				    ireq->post_context | SCU_CONTEXT_COMMAND_REQUEST_POST_TC_ABORT);
+	return SCI_SUCCESS;
+}
+
+/**
+ * sci_controller_complete_io() - This method will perform core specific
+ *    completion operations for an IO request.  After this method is invoked,
+ *    the user should consider the IO request as invalid until it is properly
+ *    reused (i.e. re-constructed).
+ * @ihost: The handle to the controller object for which to complete the
+ *    IO request.
+ * @idev: The handle to the remote device object for which to complete
+ *    the IO request.
+ * @ireq: the handle to the io request object to complete.
+ */
+enum sci_status sci_controller_complete_io(struct isci_host *ihost,
+					   struct isci_remote_device *idev,
+					   struct isci_request *ireq)
+{
+	enum sci_status status;
+	u16 index;
+
+	switch (ihost->sm.current_state_id) {
+	case SCIC_STOPPING:
+		/* XXX: Implement this function */
+		return SCI_FAILURE;
+	case SCIC_READY:
+		status = sci_remote_device_complete_io(ihost, idev, ireq);
+		if (status != SCI_SUCCESS)
+			return status;
+
+		index = ISCI_TAG_TCI(ireq->io_tag);
+		clear_bit(IREQ_ACTIVE, &ireq->flags);
+		return SCI_SUCCESS;
+	default:
+		dev_warn(&ihost->pdev->dev, "invalid state to complete I/O");
+		return SCI_FAILURE_INVALID_STATE;
+	}
+
+}
+
+enum sci_status sci_controller_continue_io(struct isci_request *ireq)
+{
+	struct isci_host *ihost = ireq->owning_controller;
+
+	if (ihost->sm.current_state_id != SCIC_READY) {
+		dev_warn(&ihost->pdev->dev, "invalid state to continue I/O");
+		return SCI_FAILURE_INVALID_STATE;
+	}
+
+	set_bit(IREQ_ACTIVE, &ireq->flags);
+	sci_controller_post_request(ihost, ireq->post_context);
+	return SCI_SUCCESS;
+}
+
+/**
+ * sci_controller_start_task() - This method is called by the SCIC user to
+ *    send/start a framework task management request.
+ * @controller: the handle to the controller object for which to start the task
+ *    management request.
+ * @remote_device: the handle to the remote device object for which to start
+ *    the task management request.
+ * @task_request: the handle to the task request object to start.
+ */
+enum sci_task_status sci_controller_start_task(struct isci_host *ihost,
+					       struct isci_remote_device *idev,
+					       struct isci_request *ireq)
+{
+	enum sci_status status;
+
+	if (ihost->sm.current_state_id != SCIC_READY) {
+		dev_warn(&ihost->pdev->dev,
+			 "%s: SCIC Controller starting task from invalid "
+			 "state\n",
+			 __func__);
+		return SCI_TASK_FAILURE_INVALID_STATE;
+	}
+
+	status = sci_remote_device_start_task(ihost, idev, ireq);
+	switch (status) {
+	case SCI_FAILURE_RESET_DEVICE_PARTIAL_SUCCESS:
+		set_bit(IREQ_ACTIVE, &ireq->flags);
+
+		/*
+		 * We will let framework know this task request started successfully,
+		 * although core is still woring on starting the request (to post tc when
+		 * RNC is resumed.)
+		 */
+		return SCI_SUCCESS;
+	case SCI_SUCCESS:
+		set_bit(IREQ_ACTIVE, &ireq->flags);
+		sci_controller_post_request(ihost, ireq->post_context);
+		break;
+	default:
+		break;
+	}
+
+	return status;
+}
diff -druN linux-2.6.39-libre/drivers/scsi/isci/host.h linux-3.0-rc7-libre/drivers/scsi/isci/host.h
--- linux-2.6.39-libre/drivers/scsi/isci/host.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/scsi/isci/host.h	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,542 @@
+/*
+ * This file is provided under a dual BSD/GPLv2 license.  When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * The full GNU General Public License is included in this distribution
+ * in the file called LICENSE.GPL.
+ *
+ * BSD LICENSE
+ *
+ * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in
+ *     the documentation and/or other materials provided with the
+ *     distribution.
+ *   * Neither the name of Intel Corporation nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef _SCI_HOST_H_
+#define _SCI_HOST_H_
+
+#include "remote_device.h"
+#include "phy.h"
+#include "isci.h"
+#include "remote_node_table.h"
+#include "registers.h"
+#include "unsolicited_frame_control.h"
+#include "probe_roms.h"
+
+struct isci_request;
+struct scu_task_context;
+
+
+/**
+ * struct sci_power_control -
+ *
+ * This structure defines the fields for managing power control for direct
+ * attached disk devices.
+ */
+struct sci_power_control {
+	/**
+	 * This field is set when the power control timer is running and cleared when
+	 * it is not.
+	 */
+	bool timer_started;
+
+	/**
+	 * Timer to control when the directed attached disks can consume power.
+	 */
+	struct sci_timer timer;
+
+	/**
+	 * This field is used to keep track of how many phys are put into the
+	 * requesters field.
+	 */
+	u8 phys_waiting;
+
+	/**
+	 * This field is used to keep track of how many phys have been granted to consume power
+	 */
+	u8 phys_granted_power;
+
+	/**
+	 * This field is an array of phys that we are waiting on. The phys are direct
+	 * mapped into requesters via struct sci_phy.phy_index
+	 */
+	struct isci_phy *requesters[SCI_MAX_PHYS];
+
+};
+
+struct sci_port_configuration_agent;
+typedef void (*port_config_fn)(struct isci_host *,
+			       struct sci_port_configuration_agent *,
+			       struct isci_port *, struct isci_phy *);
+
+struct sci_port_configuration_agent {
+	u16 phy_configured_mask;
+	u16 phy_ready_mask;
+	struct {
+		u8 min_index;
+		u8 max_index;
+	} phy_valid_port_range[SCI_MAX_PHYS];
+	bool timer_pending;
+	port_config_fn link_up_handler;
+	port_config_fn link_down_handler;
+	struct sci_timer	timer;
+};
+
+/**
+ * isci_host - primary host/controller object
+ * @timer: timeout start/stop operations
+ * @device_table: rni (hw remote node index) to remote device lookup table
+ * @available_remote_nodes: rni allocator
+ * @power_control: manage device spin up
+ * @io_request_sequence: generation number for tci's (task contexts)
+ * @task_context_table: hw task context table
+ * @remote_node_context_table: hw remote node context table
+ * @completion_queue: hw-producer driver-consumer communication ring
+ * @completion_queue_get: tracks the driver 'head' of the ring to notify hw
+ * @logical_port_entries: min({driver|silicon}-supported-port-count)
+ * @remote_node_entries: min({driver|silicon}-supported-node-count)
+ * @task_context_entries: min({driver|silicon}-supported-task-count)
+ * @phy_timer: phy startup timer
+ * @invalid_phy_mask: if an invalid_link_up notification is reported a bit for
+ * 		      the phy index is set so further notifications are not
+ * 		      made.  Once the phy reports link up and is made part of a
+ * 		      port then this bit is cleared.
+
+ */
+struct isci_host {
+	struct sci_base_state_machine sm;
+	/* XXX can we time this externally */
+	struct sci_timer timer;
+	/* XXX drop reference module params directly */
+	struct sci_user_parameters user_parameters;
+	/* XXX no need to be a union */
+	struct sci_oem_params oem_parameters;
+	struct sci_port_configuration_agent port_agent;
+	struct isci_remote_device *device_table[SCI_MAX_REMOTE_DEVICES];
+	struct sci_remote_node_table available_remote_nodes;
+	struct sci_power_control power_control;
+	u8 io_request_sequence[SCI_MAX_IO_REQUESTS];
+	struct scu_task_context *task_context_table;
+	dma_addr_t task_context_dma;
+	union scu_remote_node_context *remote_node_context_table;
+	u32 *completion_queue;
+	u32 completion_queue_get;
+	u32 logical_port_entries;
+	u32 remote_node_entries;
+	u32 task_context_entries;
+	struct sci_unsolicited_frame_control uf_control;
+
+	/* phy startup */
+	struct sci_timer phy_timer;
+	/* XXX kill */
+	bool phy_startup_timer_pending;
+	u32 next_phy_to_start;
+	/* XXX convert to unsigned long and use bitops */
+	u8 invalid_phy_mask;
+
+	/* TODO attempt dynamic interrupt coalescing scheme */
+	u16 interrupt_coalesce_number;
+	u32 interrupt_coalesce_timeout;
+	struct smu_registers __iomem *smu_registers;
+	struct scu_registers __iomem *scu_registers;
+
+	u16 tci_head;
+	u16 tci_tail;
+	u16 tci_pool[SCI_MAX_IO_REQUESTS];
+
+	int id; /* unique within a given pci device */
+	struct isci_phy phys[SCI_MAX_PHYS];
+	struct isci_port ports[SCI_MAX_PORTS + 1]; /* includes dummy port */
+	struct sas_ha_struct sas_ha;
+
+	spinlock_t state_lock;
+	struct pci_dev *pdev;
+	enum isci_status status;
+	#define IHOST_START_PENDING 0
+	#define IHOST_STOP_PENDING 1
+	unsigned long flags;
+	wait_queue_head_t eventq;
+	struct Scsi_Host *shost;
+	struct tasklet_struct completion_tasklet;
+	struct list_head requests_to_complete;
+	struct list_head requests_to_errorback;
+	spinlock_t scic_lock;
+	struct isci_request *reqs[SCI_MAX_IO_REQUESTS];
+	struct isci_remote_device devices[SCI_MAX_REMOTE_DEVICES];
+};
+
+/**
+ * enum sci_controller_states - This enumeration depicts all the states
+ *    for the common controller state machine.
+ */
+enum sci_controller_states {
+	/**
+	 * Simply the initial state for the base controller state machine.
+	 */
+	SCIC_INITIAL = 0,
+
+	/**
+	 * This state indicates that the controller is reset.  The memory for
+	 * the controller is in it's initial state, but the controller requires
+	 * initialization.
+	 * This state is entered from the INITIAL state.
+	 * This state is entered from the RESETTING state.
+	 */
+	SCIC_RESET,
+
+	/**
+	 * This state is typically an action state that indicates the controller
+	 * is in the process of initialization.  In this state no new IO operations
+	 * are permitted.
+	 * This state is entered from the RESET state.
+	 */
+	SCIC_INITIALIZING,
+
+	/**
+	 * This state indicates that the controller has been successfully
+	 * initialized.  In this state no new IO operations are permitted.
+	 * This state is entered from the INITIALIZING state.
+	 */
+	SCIC_INITIALIZED,
+
+	/**
+	 * This state indicates the the controller is in the process of becoming
+	 * ready (i.e. starting).  In this state no new IO operations are permitted.
+	 * This state is entered from the INITIALIZED state.
+	 */
+	SCIC_STARTING,
+
+	/**
+	 * This state indicates the controller is now ready.  Thus, the user
+	 * is able to perform IO operations on the controller.
+	 * This state is entered from the STARTING state.
+	 */
+	SCIC_READY,
+
+	/**
+	 * This state is typically an action state that indicates the controller
+	 * is in the process of resetting.  Thus, the user is unable to perform
+	 * IO operations on the controller.  A reset is considered destructive in
+	 * most cases.
+	 * This state is entered from the READY state.
+	 * This state is entered from the FAILED state.
+	 * This state is entered from the STOPPED state.
+	 */
+	SCIC_RESETTING,
+
+	/**
+	 * This state indicates that the controller is in the process of stopping.
+	 * In this state no new IO operations are permitted, but existing IO
+	 * operations are allowed to complete.
+	 * This state is entered from the READY state.
+	 */
+	SCIC_STOPPING,
+
+	/**
+	 * This state indicates that the controller has successfully been stopped.
+	 * In this state no new IO operations are permitted.
+	 * This state is entered from the STOPPING state.
+	 */
+	SCIC_STOPPED,
+
+	/**
+	 * This state indicates that the controller could not successfully be
+	 * initialized.  In this state no new IO operations are permitted.
+	 * This state is entered from the INITIALIZING state.
+	 * This state is entered from the STARTING state.
+	 * This state is entered from the STOPPING state.
+	 * This state is entered from the RESETTING state.
+	 */
+	SCIC_FAILED,
+};
+
+/**
+ * struct isci_pci_info - This class represents the pci function containing the
+ *    controllers. Depending on PCI SKU, there could be up to 2 controllers in
+ *    the PCI function.
+ */
+#define SCI_MAX_MSIX_INT (SCI_NUM_MSI_X_INT*SCI_MAX_CONTROLLERS)
+
+struct isci_pci_info {
+	struct msix_entry msix_entries[SCI_MAX_MSIX_INT];
+	struct isci_host *hosts[SCI_MAX_CONTROLLERS];
+	struct isci_orom *orom;
+};
+
+static inline struct isci_pci_info *to_pci_info(struct pci_dev *pdev)
+{
+	return pci_get_drvdata(pdev);
+}
+
+#define for_each_isci_host(id, ihost, pdev) \
+	for (id = 0, ihost = to_pci_info(pdev)->hosts[id]; \
+	     id < ARRAY_SIZE(to_pci_info(pdev)->hosts) && ihost; \
+	     ihost = to_pci_info(pdev)->hosts[++id])
+
+static inline enum isci_status isci_host_get_state(struct isci_host *isci_host)
+{
+	return isci_host->status;
+}
+
+static inline void isci_host_change_state(struct isci_host *isci_host,
+					  enum isci_status status)
+{
+	unsigned long flags;
+
+	dev_dbg(&isci_host->pdev->dev,
+		"%s: isci_host = %p, state = 0x%x",
+		__func__,
+		isci_host,
+		status);
+	spin_lock_irqsave(&isci_host->state_lock, flags);
+	isci_host->status = status;
+	spin_unlock_irqrestore(&isci_host->state_lock, flags);
+
+}
+
+static inline void wait_for_start(struct isci_host *ihost)
+{
+	wait_event(ihost->eventq, !test_bit(IHOST_START_PENDING, &ihost->flags));
+}
+
+static inline void wait_for_stop(struct isci_host *ihost)
+{
+	wait_event(ihost->eventq, !test_bit(IHOST_STOP_PENDING, &ihost->flags));
+}
+
+static inline void wait_for_device_start(struct isci_host *ihost, struct isci_remote_device *idev)
+{
+	wait_event(ihost->eventq, !test_bit(IDEV_START_PENDING, &idev->flags));
+}
+
+static inline void wait_for_device_stop(struct isci_host *ihost, struct isci_remote_device *idev)
+{
+	wait_event(ihost->eventq, !test_bit(IDEV_STOP_PENDING, &idev->flags));
+}
+
+static inline struct isci_host *dev_to_ihost(struct domain_device *dev)
+{
+	return dev->port->ha->lldd_ha;
+}
+
+/* we always use protocol engine group zero */
+#define ISCI_PEG 0
+
+/* see sci_controller_io_tag_allocate|free for how seq and tci are built */
+#define ISCI_TAG(seq, tci) (((u16) (seq)) << 12 | tci)
+
+/* these are returned by the hardware, so sanitize them */
+#define ISCI_TAG_SEQ(tag) (((tag) >> 12) & (SCI_MAX_SEQ-1))
+#define ISCI_TAG_TCI(tag) ((tag) & (SCI_MAX_IO_REQUESTS-1))
+
+/* expander attached sata devices require 3 rnc slots */
+static inline int sci_remote_device_node_count(struct isci_remote_device *idev)
+{
+	struct domain_device *dev = idev->domain_dev;
+
+	if ((dev->dev_type == SATA_DEV || (dev->tproto & SAS_PROTOCOL_STP)) &&
+	    !idev->is_direct_attached)
+		return SCU_STP_REMOTE_NODE_COUNT;
+	return SCU_SSP_REMOTE_NODE_COUNT;
+}
+
+/**
+ * sci_controller_clear_invalid_phy() -
+ *
+ * This macro will clear the bit in the invalid phy mask for this controller
+ * object.  This is used to control messages reported for invalid link up
+ * notifications.
+ */
+#define sci_controller_clear_invalid_phy(controller, phy) \
+	((controller)->invalid_phy_mask &= ~(1 << (phy)->phy_index))
+
+static inline struct device *sciphy_to_dev(struct isci_phy *iphy)
+{
+
+	if (!iphy || !iphy->isci_port || !iphy->isci_port->isci_host)
+		return NULL;
+
+	return &iphy->isci_port->isci_host->pdev->dev;
+}
+
+static inline struct device *sciport_to_dev(struct isci_port *iport)
+{
+
+	if (!iport || !iport->isci_host)
+		return NULL;
+
+	return &iport->isci_host->pdev->dev;
+}
+
+static inline struct device *scirdev_to_dev(struct isci_remote_device *idev)
+{
+	if (!idev || !idev->isci_port || !idev->isci_port->isci_host)
+		return NULL;
+
+	return &idev->isci_port->isci_host->pdev->dev;
+}
+
+static inline bool is_a2(struct pci_dev *pdev)
+{
+	if (pdev->revision < 4)
+		return true;
+	return false;
+}
+
+static inline bool is_b0(struct pci_dev *pdev)
+{
+	if (pdev->revision == 4)
+		return true;
+	return false;
+}
+
+static inline bool is_c0(struct pci_dev *pdev)
+{
+	if (pdev->revision >= 5)
+		return true;
+	return false;
+}
+
+void sci_controller_post_request(struct isci_host *ihost,
+				      u32 request);
+void sci_controller_release_frame(struct isci_host *ihost,
+				       u32 frame_index);
+void sci_controller_copy_sata_response(void *response_buffer,
+					    void *frame_header,
+					    void *frame_buffer);
+enum sci_status sci_controller_allocate_remote_node_context(struct isci_host *ihost,
+								 struct isci_remote_device *idev,
+								 u16 *node_id);
+void sci_controller_free_remote_node_context(
+	struct isci_host *ihost,
+	struct isci_remote_device *idev,
+	u16 node_id);
+
+struct isci_request *sci_request_by_tag(struct isci_host *ihost,
+					     u16 io_tag);
+
+void sci_controller_power_control_queue_insert(
+	struct isci_host *ihost,
+	struct isci_phy *iphy);
+
+void sci_controller_power_control_queue_remove(
+	struct isci_host *ihost,
+	struct isci_phy *iphy);
+
+void sci_controller_link_up(
+	struct isci_host *ihost,
+	struct isci_port *iport,
+	struct isci_phy *iphy);
+
+void sci_controller_link_down(
+	struct isci_host *ihost,
+	struct isci_port *iport,
+	struct isci_phy *iphy);
+
+void sci_controller_remote_device_stopped(
+	struct isci_host *ihost,
+	struct isci_remote_device *idev);
+
+void sci_controller_copy_task_context(
+	struct isci_host *ihost,
+	struct isci_request *ireq);
+
+void sci_controller_register_setup(struct isci_host *ihost);
+
+enum sci_status sci_controller_continue_io(struct isci_request *ireq);
+int isci_host_scan_finished(struct Scsi_Host *, unsigned long);
+void isci_host_scan_start(struct Scsi_Host *);
+u16 isci_alloc_tag(struct isci_host *ihost);
+enum sci_status isci_free_tag(struct isci_host *ihost, u16 io_tag);
+void isci_tci_free(struct isci_host *ihost, u16 tci);
+
+int isci_host_init(struct isci_host *);
+
+void isci_host_init_controller_names(
+	struct isci_host *isci_host,
+	unsigned int controller_idx);
+
+void isci_host_deinit(
+	struct isci_host *);
+
+void isci_host_port_link_up(
+	struct isci_host *,
+	struct isci_port *,
+	struct isci_phy *);
+int isci_host_dev_found(struct domain_device *);
+
+void isci_host_remote_device_start_complete(
+	struct isci_host *,
+	struct isci_remote_device *,
+	enum sci_status);
+
+void sci_controller_disable_interrupts(
+	struct isci_host *ihost);
+
+enum sci_status sci_controller_start_io(
+	struct isci_host *ihost,
+	struct isci_remote_device *idev,
+	struct isci_request *ireq);
+
+enum sci_task_status sci_controller_start_task(
+	struct isci_host *ihost,
+	struct isci_remote_device *idev,
+	struct isci_request *ireq);
+
+enum sci_status sci_controller_terminate_request(
+	struct isci_host *ihost,
+	struct isci_remote_device *idev,
+	struct isci_request *ireq);
+
+enum sci_status sci_controller_complete_io(
+	struct isci_host *ihost,
+	struct isci_remote_device *idev,
+	struct isci_request *ireq);
+
+void sci_port_configuration_agent_construct(
+	struct sci_port_configuration_agent *port_agent);
+
+enum sci_status sci_port_configuration_agent_initialize(
+	struct isci_host *ihost,
+	struct sci_port_configuration_agent *port_agent);
+#endif
diff -druN linux-2.6.39-libre/drivers/scsi/isci/init.c linux-3.0-rc7-libre/drivers/scsi/isci/init.c
--- linux-2.6.39-libre/drivers/scsi/isci/init.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/scsi/isci/init.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,565 @@
+/*
+ * This file is provided under a dual BSD/GPLv2 license.  When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * The full GNU General Public License is included in this distribution
+ * in the file called LICENSE.GPL.
+ *
+ * BSD LICENSE
+ *
+ * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in
+ *     the documentation and/or other materials provided with the
+ *     distribution.
+ *   * Neither the name of Intel Corporation nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/firmware.h>
+#include <linux/efi.h>
+#include <asm/string.h>
+#include "isci.h"
+#include "task.h"
+#include "probe_roms.h"
+
+static struct scsi_transport_template *isci_transport_template;
+
+static DEFINE_PCI_DEVICE_TABLE(isci_id_table) = {
+	{ PCI_VDEVICE(INTEL, 0x1D61),},
+	{ PCI_VDEVICE(INTEL, 0x1D63),},
+	{ PCI_VDEVICE(INTEL, 0x1D65),},
+	{ PCI_VDEVICE(INTEL, 0x1D67),},
+	{ PCI_VDEVICE(INTEL, 0x1D69),},
+	{ PCI_VDEVICE(INTEL, 0x1D6B),},
+	{ PCI_VDEVICE(INTEL, 0x1D60),},
+	{ PCI_VDEVICE(INTEL, 0x1D62),},
+	{ PCI_VDEVICE(INTEL, 0x1D64),},
+	{ PCI_VDEVICE(INTEL, 0x1D66),},
+	{ PCI_VDEVICE(INTEL, 0x1D68),},
+	{ PCI_VDEVICE(INTEL, 0x1D6A),},
+	{}
+};
+
+MODULE_DEVICE_TABLE(pci, isci_id_table);
+
+/* linux isci specific settings */
+
+unsigned char no_outbound_task_to = 20;
+module_param(no_outbound_task_to, byte, 0);
+MODULE_PARM_DESC(no_outbound_task_to, "No Outbound Task Timeout (1us incr)");
+
+u16 ssp_max_occ_to = 20;
+module_param(ssp_max_occ_to, ushort, 0);
+MODULE_PARM_DESC(ssp_max_occ_to, "SSP Max occupancy timeout (100us incr)");
+
+u16 stp_max_occ_to = 5;
+module_param(stp_max_occ_to, ushort, 0);
+MODULE_PARM_DESC(stp_max_occ_to, "STP Max occupancy timeout (100us incr)");
+
+u16 ssp_inactive_to = 5;
+module_param(ssp_inactive_to, ushort, 0);
+MODULE_PARM_DESC(ssp_inactive_to, "SSP inactivity timeout (100us incr)");
+
+u16 stp_inactive_to = 5;
+module_param(stp_inactive_to, ushort, 0);
+MODULE_PARM_DESC(stp_inactive_to, "STP inactivity timeout (100us incr)");
+
+unsigned char phy_gen = 3;
+module_param(phy_gen, byte, 0);
+MODULE_PARM_DESC(phy_gen, "PHY generation (1: 1.5Gbps 2: 3.0Gbps 3: 6.0Gbps)");
+
+unsigned char max_concurr_spinup = 1;
+module_param(max_concurr_spinup, byte, 0);
+MODULE_PARM_DESC(max_concurr_spinup, "Max concurrent device spinup");
+
+static struct scsi_host_template isci_sht = {
+
+	.module				= THIS_MODULE,
+	.name				= DRV_NAME,
+	.proc_name			= DRV_NAME,
+	.queuecommand			= sas_queuecommand,
+	.target_alloc			= sas_target_alloc,
+	.slave_configure		= sas_slave_configure,
+	.slave_destroy			= sas_slave_destroy,
+	.scan_finished			= isci_host_scan_finished,
+	.scan_start			= isci_host_scan_start,
+	.change_queue_depth		= sas_change_queue_depth,
+	.change_queue_type		= sas_change_queue_type,
+	.bios_param			= sas_bios_param,
+	.can_queue			= ISCI_CAN_QUEUE_VAL,
+	.cmd_per_lun			= 1,
+	.this_id			= -1,
+	.sg_tablesize			= SG_ALL,
+	.max_sectors			= SCSI_DEFAULT_MAX_SECTORS,
+	.use_clustering			= ENABLE_CLUSTERING,
+	.eh_device_reset_handler	= sas_eh_device_reset_handler,
+	.eh_bus_reset_handler		= isci_bus_reset_handler,
+	.slave_alloc			= sas_slave_alloc,
+	.target_destroy			= sas_target_destroy,
+	.ioctl				= sas_ioctl,
+};
+
+static struct sas_domain_function_template isci_transport_ops  = {
+
+	/* The class calls these to notify the LLDD of an event. */
+	.lldd_port_formed	= isci_port_formed,
+	.lldd_port_deformed	= isci_port_deformed,
+
+	/* The class calls these when a device is found or gone. */
+	.lldd_dev_found		= isci_remote_device_found,
+	.lldd_dev_gone		= isci_remote_device_gone,
+
+	.lldd_execute_task	= isci_task_execute_task,
+	/* Task Management Functions. Must be called from process context. */
+	.lldd_abort_task	= isci_task_abort_task,
+	.lldd_abort_task_set	= isci_task_abort_task_set,
+	.lldd_clear_aca		= isci_task_clear_aca,
+	.lldd_clear_task_set	= isci_task_clear_task_set,
+	.lldd_I_T_nexus_reset	= isci_task_I_T_nexus_reset,
+	.lldd_lu_reset		= isci_task_lu_reset,
+	.lldd_query_task	= isci_task_query_task,
+
+	/* Port and Adapter management */
+	.lldd_clear_nexus_port	= isci_task_clear_nexus_port,
+	.lldd_clear_nexus_ha	= isci_task_clear_nexus_ha,
+
+	/* Phy management */
+	.lldd_control_phy	= isci_phy_control,
+};
+
+
+/******************************************************************************
+* P R O T E C T E D  M E T H O D S
+******************************************************************************/
+
+
+
+/**
+ * isci_register_sas_ha() - This method initializes various lldd
+ *    specific members of the sas_ha struct and calls the libsas
+ *    sas_register_ha() function.
+ * @isci_host: This parameter specifies the lldd specific wrapper for the
+ *    libsas sas_ha struct.
+ *
+ * This method returns an error code indicating sucess or failure. The user
+ * should check for possible memory allocation error return otherwise, a zero
+ * indicates success.
+ */
+static int isci_register_sas_ha(struct isci_host *isci_host)
+{
+	int i;
+	struct sas_ha_struct *sas_ha = &(isci_host->sas_ha);
+	struct asd_sas_phy **sas_phys;
+	struct asd_sas_port **sas_ports;
+
+	sas_phys = devm_kzalloc(&isci_host->pdev->dev,
+				SCI_MAX_PHYS * sizeof(void *),
+				GFP_KERNEL);
+	if (!sas_phys)
+		return -ENOMEM;
+
+	sas_ports = devm_kzalloc(&isci_host->pdev->dev,
+				 SCI_MAX_PORTS * sizeof(void *),
+				 GFP_KERNEL);
+	if (!sas_ports)
+		return -ENOMEM;
+
+	/*----------------- Libsas Initialization Stuff----------------------
+	 * Set various fields in the sas_ha struct:
+	 */
+
+	sas_ha->sas_ha_name = DRV_NAME;
+	sas_ha->lldd_module = THIS_MODULE;
+	sas_ha->sas_addr    = &isci_host->phys[0].sas_addr[0];
+
+	/* set the array of phy and port structs.  */
+	for (i = 0; i < SCI_MAX_PHYS; i++) {
+		sas_phys[i] = &isci_host->phys[i].sas_phy;
+		sas_ports[i] = &isci_host->ports[i].sas_port;
+	}
+
+	sas_ha->sas_phy  = sas_phys;
+	sas_ha->sas_port = sas_ports;
+	sas_ha->num_phys = SCI_MAX_PHYS;
+
+	sas_ha->lldd_queue_size = ISCI_CAN_QUEUE_VAL;
+	sas_ha->lldd_max_execute_num = 1;
+	sas_ha->strict_wide_ports = 1;
+
+	sas_register_ha(sas_ha);
+
+	return 0;
+}
+
+static ssize_t isci_show_id(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	struct Scsi_Host *shost = container_of(dev, typeof(*shost), shost_dev);
+	struct sas_ha_struct *sas_ha = SHOST_TO_SAS_HA(shost);
+	struct isci_host *ihost = container_of(sas_ha, typeof(*ihost), sas_ha);
+
+	return snprintf(buf, PAGE_SIZE, "%d\n", ihost->id);
+}
+
+static DEVICE_ATTR(isci_id, S_IRUGO, isci_show_id, NULL);
+
+static void isci_unregister(struct isci_host *isci_host)
+{
+	struct Scsi_Host *shost;
+
+	if (!isci_host)
+		return;
+
+	shost = isci_host->shost;
+	device_remove_file(&shost->shost_dev, &dev_attr_isci_id);
+
+	sas_unregister_ha(&isci_host->sas_ha);
+
+	sas_remove_host(isci_host->shost);
+	scsi_remove_host(isci_host->shost);
+	scsi_host_put(isci_host->shost);
+}
+
+static int __devinit isci_pci_init(struct pci_dev *pdev)
+{
+	int err, bar_num, bar_mask = 0;
+	void __iomem * const *iomap;
+
+	err = pcim_enable_device(pdev);
+	if (err) {
+		dev_err(&pdev->dev,
+			"failed enable PCI device %s!\n",
+			pci_name(pdev));
+		return err;
+	}
+
+	for (bar_num = 0; bar_num < SCI_PCI_BAR_COUNT; bar_num++)
+		bar_mask |= 1 << (bar_num * 2);
+
+	err = pcim_iomap_regions(pdev, bar_mask, DRV_NAME);
+	if (err)
+		return err;
+
+	iomap = pcim_iomap_table(pdev);
+	if (!iomap)
+		return -ENOMEM;
+
+	pci_set_master(pdev);
+
+	err = pci_set_dma_mask(pdev, DMA_BIT_MASK(64));
+	if (err) {
+		err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
+		if (err)
+			return err;
+	}
+
+	err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64));
+	if (err) {
+		err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
+		if (err)
+			return err;
+	}
+
+	return 0;
+}
+
+static int num_controllers(struct pci_dev *pdev)
+{
+	/* bar size alone can tell us if we are running with a dual controller
+	 * part, no need to trust revision ids that might be under broken firmware
+	 * control
+	 */
+	resource_size_t scu_bar_size = pci_resource_len(pdev, SCI_SCU_BAR*2);
+	resource_size_t smu_bar_size = pci_resource_len(pdev, SCI_SMU_BAR*2);
+
+	if (scu_bar_size >= SCI_SCU_BAR_SIZE*SCI_MAX_CONTROLLERS &&
+	    smu_bar_size >= SCI_SMU_BAR_SIZE*SCI_MAX_CONTROLLERS)
+		return SCI_MAX_CONTROLLERS;
+	else
+		return 1;
+}
+
+static int isci_setup_interrupts(struct pci_dev *pdev)
+{
+	int err, i, num_msix;
+	struct isci_host *ihost;
+	struct isci_pci_info *pci_info = to_pci_info(pdev);
+
+	/*
+	 *  Determine the number of vectors associated with this
+	 *  PCI function.
+	 */
+	num_msix = num_controllers(pdev) * SCI_NUM_MSI_X_INT;
+
+	for (i = 0; i < num_msix; i++)
+		pci_info->msix_entries[i].entry = i;
+
+	err = pci_enable_msix(pdev, pci_info->msix_entries, num_msix);
+	if (err)
+		goto intx;
+
+	for (i = 0; i < num_msix; i++) {
+		int id = i / SCI_NUM_MSI_X_INT;
+		struct msix_entry *msix = &pci_info->msix_entries[i];
+		irq_handler_t isr;
+
+		ihost = pci_info->hosts[id];
+		/* odd numbered vectors are error interrupts */
+		if (i & 1)
+			isr = isci_error_isr;
+		else
+			isr = isci_msix_isr;
+
+		err = devm_request_irq(&pdev->dev, msix->vector, isr, 0,
+				       DRV_NAME"-msix", ihost);
+		if (!err)
+			continue;
+
+		dev_info(&pdev->dev, "msix setup failed falling back to intx\n");
+		while (i--) {
+			id = i / SCI_NUM_MSI_X_INT;
+			ihost = pci_info->hosts[id];
+			msix = &pci_info->msix_entries[i];
+			devm_free_irq(&pdev->dev, msix->vector, ihost);
+		}
+		pci_disable_msix(pdev);
+		goto intx;
+	}
+	return 0;
+
+ intx:
+	for_each_isci_host(i, ihost, pdev) {
+		err = devm_request_irq(&pdev->dev, pdev->irq, isci_intx_isr,
+				       IRQF_SHARED, DRV_NAME"-intx", ihost);
+		if (err)
+			break;
+	}
+	return err;
+}
+
+static struct isci_host *isci_host_alloc(struct pci_dev *pdev, int id)
+{
+	struct isci_host *isci_host;
+	struct Scsi_Host *shost;
+	int err;
+
+	isci_host = devm_kzalloc(&pdev->dev, sizeof(*isci_host), GFP_KERNEL);
+	if (!isci_host)
+		return NULL;
+
+	isci_host->pdev = pdev;
+	isci_host->id = id;
+
+	shost = scsi_host_alloc(&isci_sht, sizeof(void *));
+	if (!shost)
+		return NULL;
+	isci_host->shost = shost;
+
+	err = isci_host_init(isci_host);
+	if (err)
+		goto err_shost;
+
+	SHOST_TO_SAS_HA(shost) = &isci_host->sas_ha;
+	isci_host->sas_ha.core.shost = shost;
+	shost->transportt = isci_transport_template;
+
+	shost->max_id = ~0;
+	shost->max_lun = ~0;
+	shost->max_cmd_len = MAX_COMMAND_SIZE;
+
+	err = scsi_add_host(shost, &pdev->dev);
+	if (err)
+		goto err_shost;
+
+	err = isci_register_sas_ha(isci_host);
+	if (err)
+		goto err_shost_remove;
+
+	err = device_create_file(&shost->shost_dev, &dev_attr_isci_id);
+	if (err)
+		goto err_unregister_ha;
+
+	return isci_host;
+
+ err_unregister_ha:
+	sas_unregister_ha(&(isci_host->sas_ha));
+ err_shost_remove:
+	scsi_remove_host(shost);
+ err_shost:
+	scsi_host_put(shost);
+
+	return NULL;
+}
+
+static int __devinit isci_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
+{
+	struct isci_pci_info *pci_info;
+	int err, i;
+	struct isci_host *isci_host;
+	const struct firmware *fw = NULL;
+	struct isci_orom *orom = NULL;
+	char *source = "(platform)";
+
+	dev_info(&pdev->dev, "driver configured for rev: %d silicon\n",
+		 pdev->revision);
+
+	pci_info = devm_kzalloc(&pdev->dev, sizeof(*pci_info), GFP_KERNEL);
+	if (!pci_info)
+		return -ENOMEM;
+	pci_set_drvdata(pdev, pci_info);
+
+	if (efi_enabled)
+		orom = isci_get_efi_var(pdev);
+
+	if (!orom)
+		orom = isci_request_oprom(pdev);
+
+	for (i = 0; orom && i < ARRAY_SIZE(orom->ctrl); i++) {
+		if (sci_oem_parameters_validate(&orom->ctrl[i])) {
+			dev_warn(&pdev->dev,
+				 "[%d]: invalid oem parameters detected, falling back to firmware\n", i);
+			devm_kfree(&pdev->dev, orom);
+			orom = NULL;
+			break;
+		}
+	}
+
+	if (!orom) {
+		source = "(firmware)";
+		orom = isci_request_firmware(pdev, fw);
+		if (!orom) {
+			/* TODO convert this to WARN_TAINT_ONCE once the
+			 * orom/efi parameter support is widely available
+			 */
+			dev_warn(&pdev->dev,
+				 "Loading user firmware failed, using default "
+				 "values\n");
+			dev_warn(&pdev->dev,
+				 "Default OEM configuration being used: 4 "
+				 "narrow ports, and default SAS Addresses\n");
+		}
+	}
+
+	if (orom)
+		dev_info(&pdev->dev,
+			 "OEM SAS parameters (version: %u.%u) loaded %s\n",
+			 (orom->hdr.version & 0xf0) >> 4,
+			 (orom->hdr.version & 0xf), source);
+
+	pci_info->orom = orom;
+
+	err = isci_pci_init(pdev);
+	if (err)
+		return err;
+
+	for (i = 0; i < num_controllers(pdev); i++) {
+		struct isci_host *h = isci_host_alloc(pdev, i);
+
+		if (!h) {
+			err = -ENOMEM;
+			goto err_host_alloc;
+		}
+		pci_info->hosts[i] = h;
+	}
+
+	err = isci_setup_interrupts(pdev);
+	if (err)
+		goto err_host_alloc;
+
+	for_each_isci_host(i, isci_host, pdev)
+		scsi_scan_host(isci_host->shost);
+
+	return 0;
+
+ err_host_alloc:
+	for_each_isci_host(i, isci_host, pdev)
+		isci_unregister(isci_host);
+	return err;
+}
+
+static void __devexit isci_pci_remove(struct pci_dev *pdev)
+{
+	struct isci_host *ihost;
+	int i;
+
+	for_each_isci_host(i, ihost, pdev) {
+		isci_unregister(ihost);
+		isci_host_deinit(ihost);
+		sci_controller_disable_interrupts(ihost);
+	}
+}
+
+static struct pci_driver isci_pci_driver = {
+	.name		= DRV_NAME,
+	.id_table	= isci_id_table,
+	.probe		= isci_pci_probe,
+	.remove		= __devexit_p(isci_pci_remove),
+};
+
+static __init int isci_init(void)
+{
+	int err;
+
+	pr_info("%s: Intel(R) C600 SAS Controller Driver\n", DRV_NAME);
+
+	isci_transport_template = sas_domain_attach_transport(&isci_transport_ops);
+	if (!isci_transport_template)
+		return -ENOMEM;
+
+	err = pci_register_driver(&isci_pci_driver);
+	if (err)
+		sas_release_transport(isci_transport_template);
+
+	return err;
+}
+
+static __exit void isci_exit(void)
+{
+	pci_unregister_driver(&isci_pci_driver);
+	sas_release_transport(isci_transport_template);
+}
+
+MODULE_LICENSE("Dual BSD/GPL");
+MODULE_FIRMWARE(ISCI_FW_NAME);
+module_init(isci_init);
+module_exit(isci_exit);
diff -druN linux-2.6.39-libre/drivers/scsi/isci/isci.h linux-3.0-rc7-libre/drivers/scsi/isci/isci.h
--- linux-2.6.39-libre/drivers/scsi/isci/isci.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/scsi/isci/isci.h	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,538 @@
+/*
+ * This file is provided under a dual BSD/GPLv2 license.  When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * The full GNU General Public License is included in this distribution
+ * in the file called LICENSE.GPL.
+ *
+ * BSD LICENSE
+ *
+ * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in
+ *     the documentation and/or other materials provided with the
+ *     distribution.
+ *   * Neither the name of Intel Corporation nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __ISCI_H__
+#define __ISCI_H__
+
+#include <linux/interrupt.h>
+#include <linux/types.h>
+
+#define DRV_NAME "isci"
+#define SCI_PCI_BAR_COUNT 2
+#define SCI_NUM_MSI_X_INT 2
+#define SCI_SMU_BAR       0
+#define SCI_SMU_BAR_SIZE  (16*1024)
+#define SCI_SCU_BAR       1
+#define SCI_SCU_BAR_SIZE  (4*1024*1024)
+#define SCI_IO_SPACE_BAR0 2
+#define SCI_IO_SPACE_BAR1 3
+#define ISCI_CAN_QUEUE_VAL 250 /* < SCI_MAX_IO_REQUESTS ? */
+#define SCIC_CONTROLLER_STOP_TIMEOUT 5000
+
+#define SCI_CONTROLLER_INVALID_IO_TAG 0xFFFF
+
+#define SCI_MAX_PHYS  (4UL)
+#define SCI_MAX_PORTS SCI_MAX_PHYS
+#define SCI_MAX_SMP_PHYS  (384) /* not silicon constrained */
+#define SCI_MAX_REMOTE_DEVICES (256UL)
+#define SCI_MAX_IO_REQUESTS (256UL)
+#define SCI_MAX_SEQ (16)
+#define SCI_MAX_MSIX_MESSAGES  (2)
+#define SCI_MAX_SCATTER_GATHER_ELEMENTS 130 /* not silicon constrained */
+#define SCI_MAX_CONTROLLERS 2
+#define SCI_MAX_DOMAINS  SCI_MAX_PORTS
+
+#define SCU_MAX_CRITICAL_NOTIFICATIONS    (384)
+#define SCU_MAX_EVENTS_SHIFT		  (7)
+#define SCU_MAX_EVENTS                    (1 << SCU_MAX_EVENTS_SHIFT)
+#define SCU_MAX_UNSOLICITED_FRAMES        (128)
+#define SCU_MAX_COMPLETION_QUEUE_SCRATCH  (128)
+#define SCU_MAX_COMPLETION_QUEUE_ENTRIES  (SCU_MAX_CRITICAL_NOTIFICATIONS \
+					   + SCU_MAX_EVENTS \
+					   + SCU_MAX_UNSOLICITED_FRAMES	\
+					   + SCI_MAX_IO_REQUESTS \
+					   + SCU_MAX_COMPLETION_QUEUE_SCRATCH)
+#define SCU_MAX_COMPLETION_QUEUE_SHIFT	  (ilog2(SCU_MAX_COMPLETION_QUEUE_ENTRIES))
+
+#define SCU_ABSOLUTE_MAX_UNSOLICITED_FRAMES (4096)
+#define SCU_UNSOLICITED_FRAME_BUFFER_SIZE   (1024)
+#define SCU_INVALID_FRAME_INDEX             (0xFFFF)
+
+#define SCU_IO_REQUEST_MAX_SGE_SIZE         (0x00FFFFFF)
+#define SCU_IO_REQUEST_MAX_TRANSFER_LENGTH  (0x00FFFFFF)
+
+static inline void check_sizes(void)
+{
+	BUILD_BUG_ON_NOT_POWER_OF_2(SCU_MAX_EVENTS);
+	BUILD_BUG_ON(SCU_MAX_UNSOLICITED_FRAMES <= 8);
+	BUILD_BUG_ON_NOT_POWER_OF_2(SCU_MAX_UNSOLICITED_FRAMES);
+	BUILD_BUG_ON_NOT_POWER_OF_2(SCU_MAX_COMPLETION_QUEUE_ENTRIES);
+	BUILD_BUG_ON(SCU_MAX_UNSOLICITED_FRAMES > SCU_ABSOLUTE_MAX_UNSOLICITED_FRAMES);
+	BUILD_BUG_ON_NOT_POWER_OF_2(SCI_MAX_IO_REQUESTS);
+	BUILD_BUG_ON_NOT_POWER_OF_2(SCI_MAX_SEQ);
+}
+
+/**
+ * enum sci_status - This is the general return status enumeration for non-IO,
+ *    non-task management related SCI interface methods.
+ *
+ *
+ */
+enum sci_status {
+	/**
+	 * This member indicates successful completion.
+	 */
+	SCI_SUCCESS = 0,
+
+	/**
+	 * This value indicates that the calling method completed successfully,
+	 * but that the IO may have completed before having it's start method
+	 * invoked.  This occurs during SAT translation for requests that do
+	 * not require an IO to the target or for any other requests that may
+	 * be completed without having to submit IO.
+	 */
+	SCI_SUCCESS_IO_COMPLETE_BEFORE_START,
+
+	/**
+	 *  This Value indicates that the SCU hardware returned an early response
+	 *  because the io request specified more data than is returned by the
+	 *  target device (mode pages, inquiry data, etc.). The completion routine
+	 *  will handle this case to get the actual number of bytes transferred.
+	 */
+	SCI_SUCCESS_IO_DONE_EARLY,
+
+	/**
+	 * This member indicates that the object for which a state change is
+	 * being requested is already in said state.
+	 */
+	SCI_WARNING_ALREADY_IN_STATE,
+
+	/**
+	 * This member indicates interrupt coalescence timer may cause SAS
+	 * specification compliance issues (i.e. SMP target mode response
+	 * frames must be returned within 1.9 milliseconds).
+	 */
+	SCI_WARNING_TIMER_CONFLICT,
+
+	/**
+	 * This field indicates a sequence of action is not completed yet. Mostly,
+	 * this status is used when multiple ATA commands are needed in a SATI translation.
+	 */
+	SCI_WARNING_SEQUENCE_INCOMPLETE,
+
+	/**
+	 * This member indicates that there was a general failure.
+	 */
+	SCI_FAILURE,
+
+	/**
+	 * This member indicates that the SCI implementation is unable to complete
+	 * an operation due to a critical flaw the prevents any further operation
+	 * (i.e. an invalid pointer).
+	 */
+	SCI_FATAL_ERROR,
+
+	/**
+	 * This member indicates the calling function failed, because the state
+	 * of the controller is in a state that prevents successful completion.
+	 */
+	SCI_FAILURE_INVALID_STATE,
+
+	/**
+	 * This member indicates the calling function failed, because there is
+	 * insufficient resources/memory to complete the request.
+	 */
+	SCI_FAILURE_INSUFFICIENT_RESOURCES,
+
+	/**
+	 * This member indicates the calling function failed, because the
+	 * controller object required for the operation can't be located.
+	 */
+	SCI_FAILURE_CONTROLLER_NOT_FOUND,
+
+	/**
+	 * This member indicates the calling function failed, because the
+	 * discovered controller type is not supported by the library.
+	 */
+	SCI_FAILURE_UNSUPPORTED_CONTROLLER_TYPE,
+
+	/**
+	 * This member indicates the calling function failed, because the
+	 * requested initialization data version isn't supported.
+	 */
+	SCI_FAILURE_UNSUPPORTED_INIT_DATA_VERSION,
+
+	/**
+	 * This member indicates the calling function failed, because the
+	 * requested configuration of SAS Phys into SAS Ports is not supported.
+	 */
+	SCI_FAILURE_UNSUPPORTED_PORT_CONFIGURATION,
+
+	/**
+	 * This member indicates the calling function failed, because the
+	 * requested protocol is not supported by the remote device, port,
+	 * or controller.
+	 */
+	SCI_FAILURE_UNSUPPORTED_PROTOCOL,
+
+	/**
+	 * This member indicates the calling function failed, because the
+	 * requested information type is not supported by the SCI implementation.
+	 */
+	SCI_FAILURE_UNSUPPORTED_INFORMATION_TYPE,
+
+	/**
+	 * This member indicates the calling function failed, because the
+	 * device already exists.
+	 */
+	SCI_FAILURE_DEVICE_EXISTS,
+
+	/**
+	 * This member indicates the calling function failed, because adding
+	 * a phy to the object is not possible.
+	 */
+	SCI_FAILURE_ADDING_PHY_UNSUPPORTED,
+
+	/**
+	 * This member indicates the calling function failed, because the
+	 * requested information type is not supported by the SCI implementation.
+	 */
+	SCI_FAILURE_UNSUPPORTED_INFORMATION_FIELD,
+
+	/**
+	 * This member indicates the calling function failed, because the SCI
+	 * implementation does not support the supplied time limit.
+	 */
+	SCI_FAILURE_UNSUPPORTED_TIME_LIMIT,
+
+	/**
+	 * This member indicates the calling method failed, because the SCI
+	 * implementation does not contain the specified Phy.
+	 */
+	SCI_FAILURE_INVALID_PHY,
+
+	/**
+	 * This member indicates the calling method failed, because the SCI
+	 * implementation does not contain the specified Port.
+	 */
+	SCI_FAILURE_INVALID_PORT,
+
+	/**
+	 * This member indicates the calling method was partly successful
+	 * The port was reset but not all phys in port are operational
+	 */
+	SCI_FAILURE_RESET_PORT_PARTIAL_SUCCESS,
+
+	/**
+	 * This member indicates that calling method failed
+	 * The port reset did not complete because none of the phys are operational
+	 */
+	SCI_FAILURE_RESET_PORT_FAILURE,
+
+	/**
+	 * This member indicates the calling method failed, because the SCI
+	 * implementation does not contain the specified remote device.
+	 */
+	SCI_FAILURE_INVALID_REMOTE_DEVICE,
+
+	/**
+	 * This member indicates the calling method failed, because the remote
+	 * device is in a bad state and requires a reset.
+	 */
+	SCI_FAILURE_REMOTE_DEVICE_RESET_REQUIRED,
+
+	/**
+	 * This member indicates the calling method failed, because the SCI
+	 * implementation does not contain or support the specified IO tag.
+	 */
+	SCI_FAILURE_INVALID_IO_TAG,
+
+	/**
+	 * This member indicates that the operation failed and the user should
+	 * check the response data associated with the IO.
+	 */
+	SCI_FAILURE_IO_RESPONSE_VALID,
+
+	/**
+	 * This member indicates that the operation failed, the failure is
+	 * controller implementation specific, and the response data associated
+	 * with the request is not valid.  You can query for the controller
+	 * specific error information via sci_controller_get_request_status()
+	 */
+	SCI_FAILURE_CONTROLLER_SPECIFIC_IO_ERR,
+
+	/**
+	 * This member indicated that the operation failed because the
+	 * user requested this IO to be terminated.
+	 */
+	SCI_FAILURE_IO_TERMINATED,
+
+	/**
+	 * This member indicates that the operation failed and the associated
+	 * request requires a SCSI abort task to be sent to the target.
+	 */
+	SCI_FAILURE_IO_REQUIRES_SCSI_ABORT,
+
+	/**
+	 * This member indicates that the operation failed because the supplied
+	 * device could not be located.
+	 */
+	SCI_FAILURE_DEVICE_NOT_FOUND,
+
+	/**
+	 * This member indicates that the operation failed because the
+	 * objects association is required and is not correctly set.
+	 */
+	SCI_FAILURE_INVALID_ASSOCIATION,
+
+	/**
+	 * This member indicates that the operation failed, because a timeout
+	 * occurred.
+	 */
+	SCI_FAILURE_TIMEOUT,
+
+	/**
+	 * This member indicates that the operation failed, because the user
+	 * specified a value that is either invalid or not supported.
+	 */
+	SCI_FAILURE_INVALID_PARAMETER_VALUE,
+
+	/**
+	 * This value indicates that the operation failed, because the number
+	 * of messages (MSI-X) is not supported.
+	 */
+	SCI_FAILURE_UNSUPPORTED_MESSAGE_COUNT,
+
+	/**
+	 * This value indicates that the method failed due to a lack of
+	 * available NCQ tags.
+	 */
+	SCI_FAILURE_NO_NCQ_TAG_AVAILABLE,
+
+	/**
+	 * This value indicates that a protocol violation has occurred on the
+	 * link.
+	 */
+	SCI_FAILURE_PROTOCOL_VIOLATION,
+
+	/**
+	 * This value indicates a failure condition that retry may help to clear.
+	 */
+	SCI_FAILURE_RETRY_REQUIRED,
+
+	/**
+	 * This field indicates the retry limit was reached when a retry is attempted
+	 */
+	SCI_FAILURE_RETRY_LIMIT_REACHED,
+
+	/**
+	 * This member indicates the calling method was partly successful.
+	 * Mostly, this status is used when a LUN_RESET issued to an expander attached
+	 * STP device in READY NCQ substate needs to have RNC suspended/resumed
+	 * before posting TC.
+	 */
+	SCI_FAILURE_RESET_DEVICE_PARTIAL_SUCCESS,
+
+	/**
+	 * This field indicates an illegal phy connection based on the routing attribute
+	 * of both expander phy attached to each other.
+	 */
+	SCI_FAILURE_ILLEGAL_ROUTING_ATTRIBUTE_CONFIGURATION,
+
+	/**
+	 * This field indicates a CONFIG ROUTE INFO command has a response with function result
+	 * INDEX DOES NOT EXIST, usually means exceeding max route index.
+	 */
+	SCI_FAILURE_EXCEED_MAX_ROUTE_INDEX,
+
+	/**
+	 * This value indicates that an unsupported PCI device ID has been
+	 * specified.  This indicates that attempts to invoke
+	 * sci_library_allocate_controller() will fail.
+	 */
+	SCI_FAILURE_UNSUPPORTED_PCI_DEVICE_ID
+
+};
+
+/**
+ * enum sci_io_status - This enumeration depicts all of the possible IO
+ *    completion status values.  Each value in this enumeration maps directly
+ *    to a value in the enum sci_status enumeration.  Please refer to that
+ *    enumeration for detailed comments concerning what the status represents.
+ *
+ * Add the API to retrieve the SCU status from the core. Check to see that the
+ * following status are properly handled: - SCI_IO_FAILURE_UNSUPPORTED_PROTOCOL
+ * - SCI_IO_FAILURE_INVALID_IO_TAG
+ */
+enum sci_io_status {
+	SCI_IO_SUCCESS                         = SCI_SUCCESS,
+	SCI_IO_FAILURE                         = SCI_FAILURE,
+	SCI_IO_SUCCESS_COMPLETE_BEFORE_START   = SCI_SUCCESS_IO_COMPLETE_BEFORE_START,
+	SCI_IO_SUCCESS_IO_DONE_EARLY           = SCI_SUCCESS_IO_DONE_EARLY,
+	SCI_IO_FAILURE_INVALID_STATE           = SCI_FAILURE_INVALID_STATE,
+	SCI_IO_FAILURE_INSUFFICIENT_RESOURCES  = SCI_FAILURE_INSUFFICIENT_RESOURCES,
+	SCI_IO_FAILURE_UNSUPPORTED_PROTOCOL    = SCI_FAILURE_UNSUPPORTED_PROTOCOL,
+	SCI_IO_FAILURE_RESPONSE_VALID          = SCI_FAILURE_IO_RESPONSE_VALID,
+	SCI_IO_FAILURE_CONTROLLER_SPECIFIC_ERR = SCI_FAILURE_CONTROLLER_SPECIFIC_IO_ERR,
+	SCI_IO_FAILURE_TERMINATED              = SCI_FAILURE_IO_TERMINATED,
+	SCI_IO_FAILURE_REQUIRES_SCSI_ABORT     = SCI_FAILURE_IO_REQUIRES_SCSI_ABORT,
+	SCI_IO_FAILURE_INVALID_PARAMETER_VALUE = SCI_FAILURE_INVALID_PARAMETER_VALUE,
+	SCI_IO_FAILURE_NO_NCQ_TAG_AVAILABLE    = SCI_FAILURE_NO_NCQ_TAG_AVAILABLE,
+	SCI_IO_FAILURE_PROTOCOL_VIOLATION      = SCI_FAILURE_PROTOCOL_VIOLATION,
+
+	SCI_IO_FAILURE_REMOTE_DEVICE_RESET_REQUIRED = SCI_FAILURE_REMOTE_DEVICE_RESET_REQUIRED,
+
+	SCI_IO_FAILURE_RETRY_REQUIRED      = SCI_FAILURE_RETRY_REQUIRED,
+	SCI_IO_FAILURE_RETRY_LIMIT_REACHED = SCI_FAILURE_RETRY_LIMIT_REACHED,
+	SCI_IO_FAILURE_INVALID_REMOTE_DEVICE = SCI_FAILURE_INVALID_REMOTE_DEVICE
+};
+
+/**
+ * enum sci_task_status - This enumeration depicts all of the possible task
+ *    completion status values.  Each value in this enumeration maps directly
+ *    to a value in the enum sci_status enumeration.  Please refer to that
+ *    enumeration for detailed comments concerning what the status represents.
+ *
+ * Check to see that the following status are properly handled:
+ */
+enum sci_task_status {
+	SCI_TASK_SUCCESS                         = SCI_SUCCESS,
+	SCI_TASK_FAILURE                         = SCI_FAILURE,
+	SCI_TASK_FAILURE_INVALID_STATE           = SCI_FAILURE_INVALID_STATE,
+	SCI_TASK_FAILURE_INSUFFICIENT_RESOURCES  = SCI_FAILURE_INSUFFICIENT_RESOURCES,
+	SCI_TASK_FAILURE_UNSUPPORTED_PROTOCOL    = SCI_FAILURE_UNSUPPORTED_PROTOCOL,
+	SCI_TASK_FAILURE_INVALID_TAG             = SCI_FAILURE_INVALID_IO_TAG,
+	SCI_TASK_FAILURE_RESPONSE_VALID          = SCI_FAILURE_IO_RESPONSE_VALID,
+	SCI_TASK_FAILURE_CONTROLLER_SPECIFIC_ERR = SCI_FAILURE_CONTROLLER_SPECIFIC_IO_ERR,
+	SCI_TASK_FAILURE_TERMINATED              = SCI_FAILURE_IO_TERMINATED,
+	SCI_TASK_FAILURE_INVALID_PARAMETER_VALUE = SCI_FAILURE_INVALID_PARAMETER_VALUE,
+
+	SCI_TASK_FAILURE_REMOTE_DEVICE_RESET_REQUIRED = SCI_FAILURE_REMOTE_DEVICE_RESET_REQUIRED,
+	SCI_TASK_FAILURE_RESET_DEVICE_PARTIAL_SUCCESS = SCI_FAILURE_RESET_DEVICE_PARTIAL_SUCCESS
+
+};
+
+/**
+ * sci_swab32_cpy - convert between scsi and scu-hardware byte format
+ * @dest: receive the 4-byte endian swapped version of src
+ * @src: word aligned source buffer
+ *
+ * scu hardware handles SSP/SMP control, response, and unidentified
+ * frames in "big endian dword" order.  Regardless of host endian this
+ * is always a swab32()-per-dword conversion of the standard definition,
+ * i.e. single byte fields swapped and multi-byte fields in little-
+ * endian
+ */
+static inline void sci_swab32_cpy(void *_dest, void *_src, ssize_t word_cnt)
+{
+	u32 *dest = _dest, *src = _src;
+
+	while (--word_cnt >= 0)
+		dest[word_cnt] = swab32(src[word_cnt]);
+}
+
+extern unsigned char no_outbound_task_to;
+extern u16 ssp_max_occ_to;
+extern u16 stp_max_occ_to;
+extern u16 ssp_inactive_to;
+extern u16 stp_inactive_to;
+extern unsigned char phy_gen;
+extern unsigned char max_concurr_spinup;
+
+irqreturn_t isci_msix_isr(int vec, void *data);
+irqreturn_t isci_intx_isr(int vec, void *data);
+irqreturn_t isci_error_isr(int vec, void *data);
+
+/*
+ * Each timer is associated with a cancellation flag that is set when
+ * del_timer() is called and checked in the timer callback function. This
+ * is needed since del_timer_sync() cannot be called with sci_lock held.
+ * For deinit however, del_timer_sync() is used without holding the lock.
+ */
+struct sci_timer {
+	struct timer_list	timer;
+	bool			cancel;
+};
+
+static inline
+void sci_init_timer(struct sci_timer *tmr, void (*fn)(unsigned long))
+{
+	tmr->timer.function = fn;
+	tmr->timer.data = (unsigned long) tmr;
+	tmr->cancel = 0;
+	init_timer(&tmr->timer);
+}
+
+static inline void sci_mod_timer(struct sci_timer *tmr, unsigned long msec)
+{
+	tmr->cancel = 0;
+	mod_timer(&tmr->timer, jiffies + msecs_to_jiffies(msec));
+}
+
+static inline void sci_del_timer(struct sci_timer *tmr)
+{
+	tmr->cancel = 1;
+	del_timer(&tmr->timer);
+}
+
+struct sci_base_state_machine {
+	const struct sci_base_state *state_table;
+	u32 initial_state_id;
+	u32 current_state_id;
+	u32 previous_state_id;
+};
+
+typedef void (*sci_state_transition_t)(struct sci_base_state_machine *sm);
+
+struct sci_base_state {
+	sci_state_transition_t enter_state;	/* Called on state entry */
+	sci_state_transition_t exit_state;	/* Called on state exit */
+};
+
+extern void sci_init_sm(struct sci_base_state_machine *sm,
+			const struct sci_base_state *state_table,
+			u32 initial_state);
+extern void sci_change_state(struct sci_base_state_machine *sm, u32 next_state);
+#endif  /* __ISCI_H__ */
diff -druN linux-2.6.39-libre/drivers/scsi/isci/Makefile linux-3.0-rc7-libre/drivers/scsi/isci/Makefile
--- linux-2.6.39-libre/drivers/scsi/isci/Makefile	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/scsi/isci/Makefile	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,8 @@
+obj-$(CONFIG_SCSI_ISCI) += isci.o
+isci-objs := init.o phy.o request.o \
+	     remote_device.o port.o \
+	     host.o task.o probe_roms.o \
+	     remote_node_context.o \
+	     remote_node_table.o \
+	     unsolicited_frame_control.o \
+	     port_config.o \
diff -druN linux-2.6.39-libre/drivers/scsi/isci/phy.c linux-3.0-rc7-libre/drivers/scsi/isci/phy.c
--- linux-2.6.39-libre/drivers/scsi/isci/phy.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/scsi/isci/phy.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,1312 @@
+/*
+ * This file is provided under a dual BSD/GPLv2 license.  When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * The full GNU General Public License is included in this distribution
+ * in the file called LICENSE.GPL.
+ *
+ * BSD LICENSE
+ *
+ * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in
+ *     the documentation and/or other materials provided with the
+ *     distribution.
+ *   * Neither the name of Intel Corporation nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "isci.h"
+#include "host.h"
+#include "phy.h"
+#include "scu_event_codes.h"
+#include "probe_roms.h"
+
+/* Maximum arbitration wait time in micro-seconds */
+#define SCIC_SDS_PHY_MAX_ARBITRATION_WAIT_TIME  (700)
+
+enum sas_linkrate sci_phy_linkrate(struct isci_phy *iphy)
+{
+	return iphy->max_negotiated_speed;
+}
+
+static enum sci_status
+sci_phy_transport_layer_initialization(struct isci_phy *iphy,
+				       struct scu_transport_layer_registers __iomem *reg)
+{
+	u32 tl_control;
+
+	iphy->transport_layer_registers = reg;
+
+	writel(SCIC_SDS_REMOTE_NODE_CONTEXT_INVALID_INDEX,
+		&iphy->transport_layer_registers->stp_rni);
+
+	/*
+	 * Hardware team recommends that we enable the STP prefetch for all
+	 * transports
+	 */
+	tl_control = readl(&iphy->transport_layer_registers->control);
+	tl_control |= SCU_TLCR_GEN_BIT(STP_WRITE_DATA_PREFETCH);
+	writel(tl_control, &iphy->transport_layer_registers->control);
+
+	return SCI_SUCCESS;
+}
+
+static enum sci_status
+sci_phy_link_layer_initialization(struct isci_phy *iphy,
+				  struct scu_link_layer_registers __iomem *reg)
+{
+	struct isci_host *ihost = iphy->owning_port->owning_controller;
+	int phy_idx = iphy->phy_index;
+	struct sci_phy_user_params *phy_user = &ihost->user_parameters.phys[phy_idx];
+	struct sci_phy_oem_params *phy_oem =
+		&ihost->oem_parameters.phys[phy_idx];
+	u32 phy_configuration;
+	struct sci_phy_cap phy_cap;
+	u32 parity_check = 0;
+	u32 parity_count = 0;
+	u32 llctl, link_rate;
+	u32 clksm_value = 0;
+
+	iphy->link_layer_registers = reg;
+
+	/* Set our IDENTIFY frame data */
+	#define SCI_END_DEVICE 0x01
+
+	writel(SCU_SAS_TIID_GEN_BIT(SMP_INITIATOR) |
+	       SCU_SAS_TIID_GEN_BIT(SSP_INITIATOR) |
+	       SCU_SAS_TIID_GEN_BIT(STP_INITIATOR) |
+	       SCU_SAS_TIID_GEN_BIT(DA_SATA_HOST) |
+	       SCU_SAS_TIID_GEN_VAL(DEVICE_TYPE, SCI_END_DEVICE),
+	       &iphy->link_layer_registers->transmit_identification);
+
+	/* Write the device SAS Address */
+	writel(0xFEDCBA98,
+	       &iphy->link_layer_registers->sas_device_name_high);
+	writel(phy_idx, &iphy->link_layer_registers->sas_device_name_low);
+
+	/* Write the source SAS Address */
+	writel(phy_oem->sas_address.high,
+		&iphy->link_layer_registers->source_sas_address_high);
+	writel(phy_oem->sas_address.low,
+		&iphy->link_layer_registers->source_sas_address_low);
+
+	/* Clear and Set the PHY Identifier */
+	writel(0, &iphy->link_layer_registers->identify_frame_phy_id);
+	writel(SCU_SAS_TIPID_GEN_VALUE(ID, phy_idx),
+		&iphy->link_layer_registers->identify_frame_phy_id);
+
+	/* Change the initial state of the phy configuration register */
+	phy_configuration =
+		readl(&iphy->link_layer_registers->phy_configuration);
+
+	/* Hold OOB state machine in reset */
+	phy_configuration |=  SCU_SAS_PCFG_GEN_BIT(OOB_RESET);
+	writel(phy_configuration,
+		&iphy->link_layer_registers->phy_configuration);
+
+	/* Configure the SNW capabilities */
+	phy_cap.all = 0;
+	phy_cap.start = 1;
+	phy_cap.gen3_no_ssc = 1;
+	phy_cap.gen2_no_ssc = 1;
+	phy_cap.gen1_no_ssc = 1;
+	if (ihost->oem_parameters.controller.do_enable_ssc == true) {
+		phy_cap.gen3_ssc = 1;
+		phy_cap.gen2_ssc = 1;
+		phy_cap.gen1_ssc = 1;
+	}
+
+	/*
+	 * The SAS specification indicates that the phy_capabilities that
+	 * are transmitted shall have an even parity.  Calculate the parity. */
+	parity_check = phy_cap.all;
+	while (parity_check != 0) {
+		if (parity_check & 0x1)
+			parity_count++;
+		parity_check >>= 1;
+	}
+
+	/*
+	 * If parity indicates there are an odd number of bits set, then
+	 * set the parity bit to 1 in the phy capabilities. */
+	if ((parity_count % 2) != 0)
+		phy_cap.parity = 1;
+
+	writel(phy_cap.all, &iphy->link_layer_registers->phy_capabilities);
+
+	/* Set the enable spinup period but disable the ability to send
+	 * notify enable spinup
+	 */
+	writel(SCU_ENSPINUP_GEN_VAL(COUNT,
+			phy_user->notify_enable_spin_up_insertion_frequency),
+		&iphy->link_layer_registers->notify_enable_spinup_control);
+
+	/* Write the ALIGN Insertion Ferequency for connected phy and
+	 * inpendent of connected state
+	 */
+	clksm_value = SCU_ALIGN_INSERTION_FREQUENCY_GEN_VAL(CONNECTED,
+			phy_user->in_connection_align_insertion_frequency);
+
+	clksm_value |= SCU_ALIGN_INSERTION_FREQUENCY_GEN_VAL(GENERAL,
+			phy_user->align_insertion_frequency);
+
+	writel(clksm_value, &iphy->link_layer_registers->clock_skew_management);
+
+	/* @todo Provide a way to write this register correctly */
+	writel(0x02108421,
+		&iphy->link_layer_registers->afe_lookup_table_control);
+
+	llctl = SCU_SAS_LLCTL_GEN_VAL(NO_OUTBOUND_TASK_TIMEOUT,
+		(u8)ihost->user_parameters.no_outbound_task_timeout);
+
+	switch (phy_user->max_speed_generation) {
+	case SCIC_SDS_PARM_GEN3_SPEED:
+		link_rate = SCU_SAS_LINK_LAYER_CONTROL_MAX_LINK_RATE_GEN3;
+		break;
+	case SCIC_SDS_PARM_GEN2_SPEED:
+		link_rate = SCU_SAS_LINK_LAYER_CONTROL_MAX_LINK_RATE_GEN2;
+		break;
+	default:
+		link_rate = SCU_SAS_LINK_LAYER_CONTROL_MAX_LINK_RATE_GEN1;
+		break;
+	}
+	llctl |= SCU_SAS_LLCTL_GEN_VAL(MAX_LINK_RATE, link_rate);
+	writel(llctl, &iphy->link_layer_registers->link_layer_control);
+
+	if (is_a2(ihost->pdev)) {
+		/* Program the max ARB time for the PHY to 700us so we inter-operate with
+		 * the PMC expander which shuts down PHYs if the expander PHY generates too
+		 * many breaks.  This time value will guarantee that the initiator PHY will
+		 * generate the break.
+		 */
+		writel(SCIC_SDS_PHY_MAX_ARBITRATION_WAIT_TIME,
+			&iphy->link_layer_registers->maximum_arbitration_wait_timer_timeout);
+	}
+
+	/* Disable link layer hang detection, rely on the OS timeout for I/O timeouts. */
+	writel(0, &iphy->link_layer_registers->link_layer_hang_detection_timeout);
+
+	/* We can exit the initial state to the stopped state */
+	sci_change_state(&iphy->sm, SCI_PHY_STOPPED);
+
+	return SCI_SUCCESS;
+}
+
+static void phy_sata_timeout(unsigned long data)
+{
+	struct sci_timer *tmr = (struct sci_timer *)data;
+	struct isci_phy *iphy = container_of(tmr, typeof(*iphy), sata_timer);
+	struct isci_host *ihost = iphy->owning_port->owning_controller;
+	unsigned long flags;
+
+	spin_lock_irqsave(&ihost->scic_lock, flags);
+
+	if (tmr->cancel)
+		goto done;
+
+	dev_dbg(sciphy_to_dev(iphy),
+		 "%s: SCIC SDS Phy 0x%p did not receive signature fis before "
+		 "timeout.\n",
+		 __func__,
+		 iphy);
+
+	sci_change_state(&iphy->sm, SCI_PHY_STARTING);
+done:
+	spin_unlock_irqrestore(&ihost->scic_lock, flags);
+}
+
+/**
+ * This method returns the port currently containing this phy. If the phy is
+ *    currently contained by the dummy port, then the phy is considered to not
+ *    be part of a port.
+ * @sci_phy: This parameter specifies the phy for which to retrieve the
+ *    containing port.
+ *
+ * This method returns a handle to a port that contains the supplied phy.
+ * NULL This value is returned if the phy is not part of a real
+ * port (i.e. it's contained in the dummy port). !NULL All other
+ * values indicate a handle/pointer to the port containing the phy.
+ */
+struct isci_port *phy_get_non_dummy_port(struct isci_phy *iphy)
+{
+	struct isci_port *iport = iphy->owning_port;
+
+	if (iport->physical_port_index == SCIC_SDS_DUMMY_PORT)
+		return NULL;
+
+	return iphy->owning_port;
+}
+
+/**
+ * This method will assign a port to the phy object.
+ * @out]: iphy This parameter specifies the phy for which to assign a port
+ *    object.
+ *
+ *
+ */
+void sci_phy_set_port(
+	struct isci_phy *iphy,
+	struct isci_port *iport)
+{
+	iphy->owning_port = iport;
+
+	if (iphy->bcn_received_while_port_unassigned) {
+		iphy->bcn_received_while_port_unassigned = false;
+		sci_port_broadcast_change_received(iphy->owning_port, iphy);
+	}
+}
+
+enum sci_status sci_phy_initialize(struct isci_phy *iphy,
+				   struct scu_transport_layer_registers __iomem *tl,
+				   struct scu_link_layer_registers __iomem *ll)
+{
+	/* Perfrom the initialization of the TL hardware */
+	sci_phy_transport_layer_initialization(iphy, tl);
+
+	/* Perofrm the initialization of the PE hardware */
+	sci_phy_link_layer_initialization(iphy, ll);
+
+	/* There is nothing that needs to be done in this state just
+	 * transition to the stopped state
+	 */
+	sci_change_state(&iphy->sm, SCI_PHY_STOPPED);
+
+	return SCI_SUCCESS;
+}
+
+/**
+ * This method assigns the direct attached device ID for this phy.
+ *
+ * @iphy The phy for which the direct attached device id is to
+ *       be assigned.
+ * @device_id The direct attached device ID to assign to the phy.
+ *       This will either be the RNi for the device or an invalid RNi if there
+ *       is no current device assigned to the phy.
+ */
+void sci_phy_setup_transport(struct isci_phy *iphy, u32 device_id)
+{
+	u32 tl_control;
+
+	writel(device_id, &iphy->transport_layer_registers->stp_rni);
+
+	/*
+	 * The read should guarantee that the first write gets posted
+	 * before the next write
+	 */
+	tl_control = readl(&iphy->transport_layer_registers->control);
+	tl_control |= SCU_TLCR_GEN_BIT(CLEAR_TCI_NCQ_MAPPING_TABLE);
+	writel(tl_control, &iphy->transport_layer_registers->control);
+}
+
+static void sci_phy_suspend(struct isci_phy *iphy)
+{
+	u32 scu_sas_pcfg_value;
+
+	scu_sas_pcfg_value =
+		readl(&iphy->link_layer_registers->phy_configuration);
+	scu_sas_pcfg_value |= SCU_SAS_PCFG_GEN_BIT(SUSPEND_PROTOCOL_ENGINE);
+	writel(scu_sas_pcfg_value,
+		&iphy->link_layer_registers->phy_configuration);
+
+	sci_phy_setup_transport(iphy, SCIC_SDS_REMOTE_NODE_CONTEXT_INVALID_INDEX);
+}
+
+void sci_phy_resume(struct isci_phy *iphy)
+{
+	u32 scu_sas_pcfg_value;
+
+	scu_sas_pcfg_value =
+		readl(&iphy->link_layer_registers->phy_configuration);
+	scu_sas_pcfg_value &= ~SCU_SAS_PCFG_GEN_BIT(SUSPEND_PROTOCOL_ENGINE);
+	writel(scu_sas_pcfg_value,
+		&iphy->link_layer_registers->phy_configuration);
+}
+
+void sci_phy_get_sas_address(struct isci_phy *iphy, struct sci_sas_address *sas)
+{
+	sas->high = readl(&iphy->link_layer_registers->source_sas_address_high);
+	sas->low = readl(&iphy->link_layer_registers->source_sas_address_low);
+}
+
+void sci_phy_get_attached_sas_address(struct isci_phy *iphy, struct sci_sas_address *sas)
+{
+	struct sas_identify_frame *iaf;
+
+	iaf = &iphy->frame_rcvd.iaf;
+	memcpy(sas, iaf->sas_addr, SAS_ADDR_SIZE);
+}
+
+void sci_phy_get_protocols(struct isci_phy *iphy, struct sci_phy_proto *proto)
+{
+	proto->all = readl(&iphy->link_layer_registers->transmit_identification);
+}
+
+enum sci_status sci_phy_start(struct isci_phy *iphy)
+{
+	enum sci_phy_states state = iphy->sm.current_state_id;
+
+	if (state != SCI_PHY_STOPPED) {
+		dev_dbg(sciphy_to_dev(iphy),
+			 "%s: in wrong state: %d\n", __func__, state);
+		return SCI_FAILURE_INVALID_STATE;
+	}
+
+	sci_change_state(&iphy->sm, SCI_PHY_STARTING);
+	return SCI_SUCCESS;
+}
+
+enum sci_status sci_phy_stop(struct isci_phy *iphy)
+{
+	enum sci_phy_states state = iphy->sm.current_state_id;
+
+	switch (state) {
+	case SCI_PHY_SUB_INITIAL:
+	case SCI_PHY_SUB_AWAIT_OSSP_EN:
+	case SCI_PHY_SUB_AWAIT_SAS_SPEED_EN:
+	case SCI_PHY_SUB_AWAIT_SAS_POWER:
+	case SCI_PHY_SUB_AWAIT_SATA_POWER:
+	case SCI_PHY_SUB_AWAIT_SATA_PHY_EN:
+	case SCI_PHY_SUB_AWAIT_SATA_SPEED_EN:
+	case SCI_PHY_SUB_AWAIT_SIG_FIS_UF:
+	case SCI_PHY_SUB_FINAL:
+	case SCI_PHY_READY:
+		break;
+	default:
+		dev_dbg(sciphy_to_dev(iphy),
+			"%s: in wrong state: %d\n", __func__, state);
+		return SCI_FAILURE_INVALID_STATE;
+	}
+
+	sci_change_state(&iphy->sm, SCI_PHY_STOPPED);
+	return SCI_SUCCESS;
+}
+
+enum sci_status sci_phy_reset(struct isci_phy *iphy)
+{
+	enum sci_phy_states state = iphy->sm.current_state_id;
+
+	if (state != SCI_PHY_READY) {
+		dev_dbg(sciphy_to_dev(iphy),
+			"%s: in wrong state: %d\n", __func__, state);
+		return SCI_FAILURE_INVALID_STATE;
+	}
+
+	sci_change_state(&iphy->sm, SCI_PHY_RESETTING);
+	return SCI_SUCCESS;
+}
+
+enum sci_status sci_phy_consume_power_handler(struct isci_phy *iphy)
+{
+	enum sci_phy_states state = iphy->sm.current_state_id;
+
+	switch (state) {
+	case SCI_PHY_SUB_AWAIT_SAS_POWER: {
+		u32 enable_spinup;
+
+		enable_spinup = readl(&iphy->link_layer_registers->notify_enable_spinup_control);
+		enable_spinup |= SCU_ENSPINUP_GEN_BIT(ENABLE);
+		writel(enable_spinup, &iphy->link_layer_registers->notify_enable_spinup_control);
+
+		/* Change state to the final state this substate machine has run to completion */
+		sci_change_state(&iphy->sm, SCI_PHY_SUB_FINAL);
+
+		return SCI_SUCCESS;
+	}
+	case SCI_PHY_SUB_AWAIT_SATA_POWER: {
+		u32 scu_sas_pcfg_value;
+
+		/* Release the spinup hold state and reset the OOB state machine */
+		scu_sas_pcfg_value =
+			readl(&iphy->link_layer_registers->phy_configuration);
+		scu_sas_pcfg_value &=
+			~(SCU_SAS_PCFG_GEN_BIT(SATA_SPINUP_HOLD) | SCU_SAS_PCFG_GEN_BIT(OOB_ENABLE));
+		scu_sas_pcfg_value |= SCU_SAS_PCFG_GEN_BIT(OOB_RESET);
+		writel(scu_sas_pcfg_value,
+			&iphy->link_layer_registers->phy_configuration);
+
+		/* Now restart the OOB operation */
+		scu_sas_pcfg_value &= ~SCU_SAS_PCFG_GEN_BIT(OOB_RESET);
+		scu_sas_pcfg_value |= SCU_SAS_PCFG_GEN_BIT(OOB_ENABLE);
+		writel(scu_sas_pcfg_value,
+			&iphy->link_layer_registers->phy_configuration);
+
+		/* Change state to the final state this substate machine has run to completion */
+		sci_change_state(&iphy->sm, SCI_PHY_SUB_AWAIT_SATA_PHY_EN);
+
+		return SCI_SUCCESS;
+	}
+	default:
+		dev_dbg(sciphy_to_dev(iphy),
+			"%s: in wrong state: %d\n", __func__, state);
+		return SCI_FAILURE_INVALID_STATE;
+	}
+}
+
+static void sci_phy_start_sas_link_training(struct isci_phy *iphy)
+{
+	/* continue the link training for the phy as if it were a SAS PHY
+	 * instead of a SATA PHY. This is done because the completion queue had a SAS
+	 * PHY DETECTED event when the state machine was expecting a SATA PHY event.
+	 */
+	u32 phy_control;
+
+	phy_control = readl(&iphy->link_layer_registers->phy_configuration);
+	phy_control |= SCU_SAS_PCFG_GEN_BIT(SATA_SPINUP_HOLD);
+	writel(phy_control,
+	       &iphy->link_layer_registers->phy_configuration);
+
+	sci_change_state(&iphy->sm, SCI_PHY_SUB_AWAIT_SAS_SPEED_EN);
+
+	iphy->protocol = SCIC_SDS_PHY_PROTOCOL_SAS;
+}
+
+static void sci_phy_start_sata_link_training(struct isci_phy *iphy)
+{
+	/* This method continues the link training for the phy as if it were a SATA PHY
+	 * instead of a SAS PHY.  This is done because the completion queue had a SATA
+	 * SPINUP HOLD event when the state machine was expecting a SAS PHY event. none
+	 */
+	sci_change_state(&iphy->sm, SCI_PHY_SUB_AWAIT_SATA_POWER);
+
+	iphy->protocol = SCIC_SDS_PHY_PROTOCOL_SATA;
+}
+
+/**
+ * sci_phy_complete_link_training - perform processing common to
+ *    all protocols upon completion of link training.
+ * @sci_phy: This parameter specifies the phy object for which link training
+ *    has completed.
+ * @max_link_rate: This parameter specifies the maximum link rate to be
+ *    associated with this phy.
+ * @next_state: This parameter specifies the next state for the phy's starting
+ *    sub-state machine.
+ *
+ */
+static void sci_phy_complete_link_training(struct isci_phy *iphy,
+					   enum sas_linkrate max_link_rate,
+					   u32 next_state)
+{
+	iphy->max_negotiated_speed = max_link_rate;
+
+	sci_change_state(&iphy->sm, next_state);
+}
+
+enum sci_status sci_phy_event_handler(struct isci_phy *iphy, u32 event_code)
+{
+	enum sci_phy_states state = iphy->sm.current_state_id;
+
+	switch (state) {
+	case SCI_PHY_SUB_AWAIT_OSSP_EN:
+		switch (scu_get_event_code(event_code)) {
+		case SCU_EVENT_SAS_PHY_DETECTED:
+			sci_phy_start_sas_link_training(iphy);
+			iphy->is_in_link_training = true;
+			break;
+		case SCU_EVENT_SATA_SPINUP_HOLD:
+			sci_phy_start_sata_link_training(iphy);
+			iphy->is_in_link_training = true;
+			break;
+		default:
+			dev_dbg(sciphy_to_dev(iphy),
+				"%s: PHY starting substate machine received "
+				"unexpected event_code %x\n",
+				__func__,
+				event_code);
+			return SCI_FAILURE;
+		}
+		return SCI_SUCCESS;
+	case SCI_PHY_SUB_AWAIT_SAS_SPEED_EN:
+		switch (scu_get_event_code(event_code)) {
+		case SCU_EVENT_SAS_PHY_DETECTED:
+			/*
+			 * Why is this being reported again by the controller?
+			 * We would re-enter this state so just stay here */
+			break;
+		case SCU_EVENT_SAS_15:
+		case SCU_EVENT_SAS_15_SSC:
+			sci_phy_complete_link_training(iphy, SAS_LINK_RATE_1_5_GBPS,
+						       SCI_PHY_SUB_AWAIT_IAF_UF);
+			break;
+		case SCU_EVENT_SAS_30:
+		case SCU_EVENT_SAS_30_SSC:
+			sci_phy_complete_link_training(iphy, SAS_LINK_RATE_3_0_GBPS,
+						       SCI_PHY_SUB_AWAIT_IAF_UF);
+			break;
+		case SCU_EVENT_SAS_60:
+		case SCU_EVENT_SAS_60_SSC:
+			sci_phy_complete_link_training(iphy, SAS_LINK_RATE_6_0_GBPS,
+						       SCI_PHY_SUB_AWAIT_IAF_UF);
+			break;
+		case SCU_EVENT_SATA_SPINUP_HOLD:
+			/*
+			 * We were doing SAS PHY link training and received a SATA PHY event
+			 * continue OOB/SN as if this were a SATA PHY */
+			sci_phy_start_sata_link_training(iphy);
+			break;
+		case SCU_EVENT_LINK_FAILURE:
+			/* Link failure change state back to the starting state */
+			sci_change_state(&iphy->sm, SCI_PHY_STARTING);
+			break;
+		default:
+			dev_warn(sciphy_to_dev(iphy),
+				 "%s: PHY starting substate machine received "
+				 "unexpected event_code %x\n",
+				 __func__, event_code);
+
+			return SCI_FAILURE;
+			break;
+		}
+		return SCI_SUCCESS;
+	case SCI_PHY_SUB_AWAIT_IAF_UF:
+		switch (scu_get_event_code(event_code)) {
+		case SCU_EVENT_SAS_PHY_DETECTED:
+			/* Backup the state machine */
+			sci_phy_start_sas_link_training(iphy);
+			break;
+		case SCU_EVENT_SATA_SPINUP_HOLD:
+			/* We were doing SAS PHY link training and received a
+			 * SATA PHY event continue OOB/SN as if this were a
+			 * SATA PHY
+			 */
+			sci_phy_start_sata_link_training(iphy);
+			break;
+		case SCU_EVENT_RECEIVED_IDENTIFY_TIMEOUT:
+		case SCU_EVENT_LINK_FAILURE:
+		case SCU_EVENT_HARD_RESET_RECEIVED:
+			/* Start the oob/sn state machine over again */
+			sci_change_state(&iphy->sm, SCI_PHY_STARTING);
+			break;
+		default:
+			dev_warn(sciphy_to_dev(iphy),
+				 "%s: PHY starting substate machine received "
+				 "unexpected event_code %x\n",
+				 __func__, event_code);
+			return SCI_FAILURE;
+		}
+		return SCI_SUCCESS;
+	case SCI_PHY_SUB_AWAIT_SAS_POWER:
+		switch (scu_get_event_code(event_code)) {
+		case SCU_EVENT_LINK_FAILURE:
+			/* Link failure change state back to the starting state */
+			sci_change_state(&iphy->sm, SCI_PHY_STARTING);
+			break;
+		default:
+			dev_warn(sciphy_to_dev(iphy),
+				"%s: PHY starting substate machine received unexpected "
+				"event_code %x\n",
+				__func__,
+				event_code);
+			return SCI_FAILURE;
+		}
+		return SCI_SUCCESS;
+	case SCI_PHY_SUB_AWAIT_SATA_POWER:
+		switch (scu_get_event_code(event_code)) {
+		case SCU_EVENT_LINK_FAILURE:
+			/* Link failure change state back to the starting state */
+			sci_change_state(&iphy->sm, SCI_PHY_STARTING);
+			break;
+		case SCU_EVENT_SATA_SPINUP_HOLD:
+			/* These events are received every 10ms and are
+			 * expected while in this state
+			 */
+			break;
+
+		case SCU_EVENT_SAS_PHY_DETECTED:
+			/* There has been a change in the phy type before OOB/SN for the
+			 * SATA finished start down the SAS link traning path.
+			 */
+			sci_phy_start_sas_link_training(iphy);
+			break;
+
+		default:
+			dev_warn(sciphy_to_dev(iphy),
+				 "%s: PHY starting substate machine received "
+				 "unexpected event_code %x\n",
+				 __func__, event_code);
+
+			return SCI_FAILURE;
+		}
+		return SCI_SUCCESS;
+	case SCI_PHY_SUB_AWAIT_SATA_PHY_EN:
+		switch (scu_get_event_code(event_code)) {
+		case SCU_EVENT_LINK_FAILURE:
+			/* Link failure change state back to the starting state */
+			sci_change_state(&iphy->sm, SCI_PHY_STARTING);
+			break;
+		case SCU_EVENT_SATA_SPINUP_HOLD:
+			/* These events might be received since we dont know how many may be in
+			 * the completion queue while waiting for power
+			 */
+			break;
+		case SCU_EVENT_SATA_PHY_DETECTED:
+			iphy->protocol = SCIC_SDS_PHY_PROTOCOL_SATA;
+
+			/* We have received the SATA PHY notification change state */
+			sci_change_state(&iphy->sm, SCI_PHY_SUB_AWAIT_SATA_SPEED_EN);
+			break;
+		case SCU_EVENT_SAS_PHY_DETECTED:
+			/* There has been a change in the phy type before OOB/SN for the
+			 * SATA finished start down the SAS link traning path.
+			 */
+			sci_phy_start_sas_link_training(iphy);
+			break;
+		default:
+			dev_warn(sciphy_to_dev(iphy),
+				 "%s: PHY starting substate machine received "
+				 "unexpected event_code %x\n",
+				 __func__,
+				 event_code);
+
+			return SCI_FAILURE;;
+		}
+		return SCI_SUCCESS;
+	case SCI_PHY_SUB_AWAIT_SATA_SPEED_EN:
+		switch (scu_get_event_code(event_code)) {
+		case SCU_EVENT_SATA_PHY_DETECTED:
+			/*
+			 * The hardware reports multiple SATA PHY detected events
+			 * ignore the extras */
+			break;
+		case SCU_EVENT_SATA_15:
+		case SCU_EVENT_SATA_15_SSC:
+			sci_phy_complete_link_training(iphy, SAS_LINK_RATE_1_5_GBPS,
+						       SCI_PHY_SUB_AWAIT_SIG_FIS_UF);
+			break;
+		case SCU_EVENT_SATA_30:
+		case SCU_EVENT_SATA_30_SSC:
+			sci_phy_complete_link_training(iphy, SAS_LINK_RATE_3_0_GBPS,
+						       SCI_PHY_SUB_AWAIT_SIG_FIS_UF);
+			break;
+		case SCU_EVENT_SATA_60:
+		case SCU_EVENT_SATA_60_SSC:
+			sci_phy_complete_link_training(iphy, SAS_LINK_RATE_6_0_GBPS,
+						       SCI_PHY_SUB_AWAIT_SIG_FIS_UF);
+			break;
+		case SCU_EVENT_LINK_FAILURE:
+			/* Link failure change state back to the starting state */
+			sci_change_state(&iphy->sm, SCI_PHY_STARTING);
+			break;
+		case SCU_EVENT_SAS_PHY_DETECTED:
+			/*
+			 * There has been a change in the phy type before OOB/SN for the
+			 * SATA finished start down the SAS link traning path. */
+			sci_phy_start_sas_link_training(iphy);
+			break;
+		default:
+			dev_warn(sciphy_to_dev(iphy),
+				 "%s: PHY starting substate machine received "
+				 "unexpected event_code %x\n",
+				 __func__, event_code);
+
+			return SCI_FAILURE;
+		}
+
+		return SCI_SUCCESS;
+	case SCI_PHY_SUB_AWAIT_SIG_FIS_UF:
+		switch (scu_get_event_code(event_code)) {
+		case SCU_EVENT_SATA_PHY_DETECTED:
+			/* Backup the state machine */
+			sci_change_state(&iphy->sm, SCI_PHY_SUB_AWAIT_SATA_SPEED_EN);
+			break;
+
+		case SCU_EVENT_LINK_FAILURE:
+			/* Link failure change state back to the starting state */
+			sci_change_state(&iphy->sm, SCI_PHY_STARTING);
+			break;
+
+		default:
+			dev_warn(sciphy_to_dev(iphy),
+				 "%s: PHY starting substate machine received "
+				 "unexpected event_code %x\n",
+				 __func__,
+				 event_code);
+
+			return SCI_FAILURE;
+		}
+		return SCI_SUCCESS;
+	case SCI_PHY_READY:
+		switch (scu_get_event_code(event_code)) {
+		case SCU_EVENT_LINK_FAILURE:
+			/* Link failure change state back to the starting state */
+			sci_change_state(&iphy->sm, SCI_PHY_STARTING);
+			break;
+		case SCU_EVENT_BROADCAST_CHANGE:
+			/* Broadcast change received. Notify the port. */
+			if (phy_get_non_dummy_port(iphy) != NULL)
+				sci_port_broadcast_change_received(iphy->owning_port, iphy);
+			else
+				iphy->bcn_received_while_port_unassigned = true;
+			break;
+		default:
+			dev_warn(sciphy_to_dev(iphy),
+				 "%sP SCIC PHY 0x%p ready state machine received "
+				 "unexpected event_code %x\n",
+				 __func__, iphy, event_code);
+			return SCI_FAILURE_INVALID_STATE;
+		}
+		return SCI_SUCCESS;
+	case SCI_PHY_RESETTING:
+		switch (scu_get_event_code(event_code)) {
+		case SCU_EVENT_HARD_RESET_TRANSMITTED:
+			/* Link failure change state back to the starting state */
+			sci_change_state(&iphy->sm, SCI_PHY_STARTING);
+			break;
+		default:
+			dev_warn(sciphy_to_dev(iphy),
+				 "%s: SCIC PHY 0x%p resetting state machine received "
+				 "unexpected event_code %x\n",
+				 __func__, iphy, event_code);
+
+			return SCI_FAILURE_INVALID_STATE;
+			break;
+		}
+		return SCI_SUCCESS;
+	default:
+		dev_dbg(sciphy_to_dev(iphy),
+			"%s: in wrong state: %d\n", __func__, state);
+		return SCI_FAILURE_INVALID_STATE;
+	}
+}
+
+enum sci_status sci_phy_frame_handler(struct isci_phy *iphy, u32 frame_index)
+{
+	enum sci_phy_states state = iphy->sm.current_state_id;
+	struct isci_host *ihost = iphy->owning_port->owning_controller;
+	enum sci_status result;
+	unsigned long flags;
+
+	switch (state) {
+	case SCI_PHY_SUB_AWAIT_IAF_UF: {
+		u32 *frame_words;
+		struct sas_identify_frame iaf;
+
+		result = sci_unsolicited_frame_control_get_header(&ihost->uf_control,
+								  frame_index,
+								  (void **)&frame_words);
+
+		if (result != SCI_SUCCESS)
+			return result;
+
+		sci_swab32_cpy(&iaf, frame_words, sizeof(iaf) / sizeof(u32));
+		if (iaf.frame_type == 0) {
+			u32 state;
+
+			spin_lock_irqsave(&iphy->sas_phy.frame_rcvd_lock, flags);
+			memcpy(&iphy->frame_rcvd.iaf, &iaf, sizeof(iaf));
+			spin_unlock_irqrestore(&iphy->sas_phy.frame_rcvd_lock, flags);
+			if (iaf.smp_tport) {
+				/* We got the IAF for an expander PHY go to the final
+				 * state since there are no power requirements for
+				 * expander phys.
+				 */
+				state = SCI_PHY_SUB_FINAL;
+			} else {
+				/* We got the IAF we can now go to the await spinup
+				 * semaphore state
+				 */
+				state = SCI_PHY_SUB_AWAIT_SAS_POWER;
+			}
+			sci_change_state(&iphy->sm, state);
+			result = SCI_SUCCESS;
+		} else
+			dev_warn(sciphy_to_dev(iphy),
+				"%s: PHY starting substate machine received "
+				"unexpected frame id %x\n",
+				__func__, frame_index);
+
+		sci_controller_release_frame(ihost, frame_index);
+		return result;
+	}
+	case SCI_PHY_SUB_AWAIT_SIG_FIS_UF: {
+		struct dev_to_host_fis *frame_header;
+		u32 *fis_frame_data;
+
+		result = sci_unsolicited_frame_control_get_header(&ihost->uf_control,
+								  frame_index,
+								  (void **)&frame_header);
+
+		if (result != SCI_SUCCESS)
+			return result;
+
+		if ((frame_header->fis_type == FIS_REGD2H) &&
+		    !(frame_header->status & ATA_BUSY)) {
+			sci_unsolicited_frame_control_get_buffer(&ihost->uf_control,
+								 frame_index,
+								 (void **)&fis_frame_data);
+
+			spin_lock_irqsave(&iphy->sas_phy.frame_rcvd_lock, flags);
+			sci_controller_copy_sata_response(&iphy->frame_rcvd.fis,
+							  frame_header,
+							  fis_frame_data);
+			spin_unlock_irqrestore(&iphy->sas_phy.frame_rcvd_lock, flags);
+
+			/* got IAF we can now go to the await spinup semaphore state */
+			sci_change_state(&iphy->sm, SCI_PHY_SUB_FINAL);
+
+			result = SCI_SUCCESS;
+		} else
+			dev_warn(sciphy_to_dev(iphy),
+				 "%s: PHY starting substate machine received "
+				 "unexpected frame id %x\n",
+				 __func__, frame_index);
+
+		/* Regardless of the result we are done with this frame with it */
+		sci_controller_release_frame(ihost, frame_index);
+
+		return result;
+	}
+	default:
+		dev_dbg(sciphy_to_dev(iphy),
+			"%s: in wrong state: %d\n", __func__, state);
+		return SCI_FAILURE_INVALID_STATE;
+	}
+
+}
+
+static void sci_phy_starting_initial_substate_enter(struct sci_base_state_machine *sm)
+{
+	struct isci_phy *iphy = container_of(sm, typeof(*iphy), sm);
+
+	/* This is just an temporary state go off to the starting state */
+	sci_change_state(&iphy->sm, SCI_PHY_SUB_AWAIT_OSSP_EN);
+}
+
+static void sci_phy_starting_await_sas_power_substate_enter(struct sci_base_state_machine *sm)
+{
+	struct isci_phy *iphy = container_of(sm, typeof(*iphy), sm);
+	struct isci_host *ihost = iphy->owning_port->owning_controller;
+
+	sci_controller_power_control_queue_insert(ihost, iphy);
+}
+
+static void sci_phy_starting_await_sas_power_substate_exit(struct sci_base_state_machine *sm)
+{
+	struct isci_phy *iphy = container_of(sm, typeof(*iphy), sm);
+	struct isci_host *ihost = iphy->owning_port->owning_controller;
+
+	sci_controller_power_control_queue_remove(ihost, iphy);
+}
+
+static void sci_phy_starting_await_sata_power_substate_enter(struct sci_base_state_machine *sm)
+{
+	struct isci_phy *iphy = container_of(sm, typeof(*iphy), sm);
+	struct isci_host *ihost = iphy->owning_port->owning_controller;
+
+	sci_controller_power_control_queue_insert(ihost, iphy);
+}
+
+static void sci_phy_starting_await_sata_power_substate_exit(struct sci_base_state_machine *sm)
+{
+	struct isci_phy *iphy = container_of(sm, typeof(*iphy), sm);
+	struct isci_host *ihost = iphy->owning_port->owning_controller;
+
+	sci_controller_power_control_queue_remove(ihost, iphy);
+}
+
+static void sci_phy_starting_await_sata_phy_substate_enter(struct sci_base_state_machine *sm)
+{
+	struct isci_phy *iphy = container_of(sm, typeof(*iphy), sm);
+
+	sci_mod_timer(&iphy->sata_timer, SCIC_SDS_SATA_LINK_TRAINING_TIMEOUT);
+}
+
+static void sci_phy_starting_await_sata_phy_substate_exit(struct sci_base_state_machine *sm)
+{
+	struct isci_phy *iphy = container_of(sm, typeof(*iphy), sm);
+
+	sci_del_timer(&iphy->sata_timer);
+}
+
+static void sci_phy_starting_await_sata_speed_substate_enter(struct sci_base_state_machine *sm)
+{
+	struct isci_phy *iphy = container_of(sm, typeof(*iphy), sm);
+
+	sci_mod_timer(&iphy->sata_timer, SCIC_SDS_SATA_LINK_TRAINING_TIMEOUT);
+}
+
+static void sci_phy_starting_await_sata_speed_substate_exit(struct sci_base_state_machine *sm)
+{
+	struct isci_phy *iphy = container_of(sm, typeof(*iphy), sm);
+
+	sci_del_timer(&iphy->sata_timer);
+}
+
+static void sci_phy_starting_await_sig_fis_uf_substate_enter(struct sci_base_state_machine *sm)
+{
+	struct isci_phy *iphy = container_of(sm, typeof(*iphy), sm);
+
+	if (sci_port_link_detected(iphy->owning_port, iphy)) {
+
+		/*
+		 * Clear the PE suspend condition so we can actually
+		 * receive SIG FIS
+		 * The hardware will not respond to the XRDY until the PE
+		 * suspend condition is cleared.
+		 */
+		sci_phy_resume(iphy);
+
+		sci_mod_timer(&iphy->sata_timer,
+			      SCIC_SDS_SIGNATURE_FIS_TIMEOUT);
+	} else
+		iphy->is_in_link_training = false;
+}
+
+static void sci_phy_starting_await_sig_fis_uf_substate_exit(struct sci_base_state_machine *sm)
+{
+	struct isci_phy *iphy = container_of(sm, typeof(*iphy), sm);
+
+	sci_del_timer(&iphy->sata_timer);
+}
+
+static void sci_phy_starting_final_substate_enter(struct sci_base_state_machine *sm)
+{
+	struct isci_phy *iphy = container_of(sm, typeof(*iphy), sm);
+
+	/* State machine has run to completion so exit out and change
+	 * the base state machine to the ready state
+	 */
+	sci_change_state(&iphy->sm, SCI_PHY_READY);
+}
+
+/**
+ *
+ * @sci_phy: This is the struct isci_phy object to stop.
+ *
+ * This method will stop the struct isci_phy object. This does not reset the
+ * protocol engine it just suspends it and places it in a state where it will
+ * not cause the end device to power up. none
+ */
+static void scu_link_layer_stop_protocol_engine(
+	struct isci_phy *iphy)
+{
+	u32 scu_sas_pcfg_value;
+	u32 enable_spinup_value;
+
+	/* Suspend the protocol engine and place it in a sata spinup hold state */
+	scu_sas_pcfg_value =
+		readl(&iphy->link_layer_registers->phy_configuration);
+	scu_sas_pcfg_value |=
+		(SCU_SAS_PCFG_GEN_BIT(OOB_RESET) |
+		 SCU_SAS_PCFG_GEN_BIT(SUSPEND_PROTOCOL_ENGINE) |
+		 SCU_SAS_PCFG_GEN_BIT(SATA_SPINUP_HOLD));
+	writel(scu_sas_pcfg_value,
+	       &iphy->link_layer_registers->phy_configuration);
+
+	/* Disable the notify enable spinup primitives */
+	enable_spinup_value = readl(&iphy->link_layer_registers->notify_enable_spinup_control);
+	enable_spinup_value &= ~SCU_ENSPINUP_GEN_BIT(ENABLE);
+	writel(enable_spinup_value, &iphy->link_layer_registers->notify_enable_spinup_control);
+}
+
+/**
+ *
+ *
+ * This method will start the OOB/SN state machine for this struct isci_phy object.
+ */
+static void scu_link_layer_start_oob(
+	struct isci_phy *iphy)
+{
+	u32 scu_sas_pcfg_value;
+
+	scu_sas_pcfg_value =
+		readl(&iphy->link_layer_registers->phy_configuration);
+	scu_sas_pcfg_value |= SCU_SAS_PCFG_GEN_BIT(OOB_ENABLE);
+	scu_sas_pcfg_value &=
+		~(SCU_SAS_PCFG_GEN_BIT(OOB_RESET) |
+		SCU_SAS_PCFG_GEN_BIT(HARD_RESET));
+	writel(scu_sas_pcfg_value,
+	       &iphy->link_layer_registers->phy_configuration);
+}
+
+/**
+ *
+ *
+ * This method will transmit a hard reset request on the specified phy. The SCU
+ * hardware requires that we reset the OOB state machine and set the hard reset
+ * bit in the phy configuration register. We then must start OOB over with the
+ * hard reset bit set.
+ */
+static void scu_link_layer_tx_hard_reset(
+	struct isci_phy *iphy)
+{
+	u32 phy_configuration_value;
+
+	/*
+	 * SAS Phys must wait for the HARD_RESET_TX event notification to transition
+	 * to the starting state. */
+	phy_configuration_value =
+		readl(&iphy->link_layer_registers->phy_configuration);
+	phy_configuration_value |=
+		(SCU_SAS_PCFG_GEN_BIT(HARD_RESET) |
+		 SCU_SAS_PCFG_GEN_BIT(OOB_RESET));
+	writel(phy_configuration_value,
+	       &iphy->link_layer_registers->phy_configuration);
+
+	/* Now take the OOB state machine out of reset */
+	phy_configuration_value |= SCU_SAS_PCFG_GEN_BIT(OOB_ENABLE);
+	phy_configuration_value &= ~SCU_SAS_PCFG_GEN_BIT(OOB_RESET);
+	writel(phy_configuration_value,
+	       &iphy->link_layer_registers->phy_configuration);
+}
+
+static void sci_phy_stopped_state_enter(struct sci_base_state_machine *sm)
+{
+	struct isci_phy *iphy = container_of(sm, typeof(*iphy), sm);
+	struct isci_port *iport = iphy->owning_port;
+	struct isci_host *ihost = iport->owning_controller;
+
+	/*
+	 * @todo We need to get to the controller to place this PE in a
+	 * reset state
+	 */
+	sci_del_timer(&iphy->sata_timer);
+
+	scu_link_layer_stop_protocol_engine(iphy);
+
+	if (iphy->sm.previous_state_id != SCI_PHY_INITIAL)
+		sci_controller_link_down(ihost, phy_get_non_dummy_port(iphy), iphy);
+}
+
+static void sci_phy_starting_state_enter(struct sci_base_state_machine *sm)
+{
+	struct isci_phy *iphy = container_of(sm, typeof(*iphy), sm);
+	struct isci_port *iport = iphy->owning_port;
+	struct isci_host *ihost = iport->owning_controller;
+
+	scu_link_layer_stop_protocol_engine(iphy);
+	scu_link_layer_start_oob(iphy);
+
+	/* We don't know what kind of phy we are going to be just yet */
+	iphy->protocol = SCIC_SDS_PHY_PROTOCOL_UNKNOWN;
+	iphy->bcn_received_while_port_unassigned = false;
+
+	if (iphy->sm.previous_state_id == SCI_PHY_READY)
+		sci_controller_link_down(ihost, phy_get_non_dummy_port(iphy), iphy);
+
+	sci_change_state(&iphy->sm, SCI_PHY_SUB_INITIAL);
+}
+
+static void sci_phy_ready_state_enter(struct sci_base_state_machine *sm)
+{
+	struct isci_phy *iphy = container_of(sm, typeof(*iphy), sm);
+	struct isci_port *iport = iphy->owning_port;
+	struct isci_host *ihost = iport->owning_controller;
+
+	sci_controller_link_up(ihost, phy_get_non_dummy_port(iphy), iphy);
+}
+
+static void sci_phy_ready_state_exit(struct sci_base_state_machine *sm)
+{
+	struct isci_phy *iphy = container_of(sm, typeof(*iphy), sm);
+
+	sci_phy_suspend(iphy);
+}
+
+static void sci_phy_resetting_state_enter(struct sci_base_state_machine *sm)
+{
+	struct isci_phy *iphy = container_of(sm, typeof(*iphy), sm);
+
+	/* The phy is being reset, therefore deactivate it from the port.  In
+	 * the resetting state we don't notify the user regarding link up and
+	 * link down notifications
+	 */
+	sci_port_deactivate_phy(iphy->owning_port, iphy, false);
+
+	if (iphy->protocol == SCIC_SDS_PHY_PROTOCOL_SAS) {
+		scu_link_layer_tx_hard_reset(iphy);
+	} else {
+		/* The SCU does not need to have a discrete reset state so
+		 * just go back to the starting state.
+		 */
+		sci_change_state(&iphy->sm, SCI_PHY_STARTING);
+	}
+}
+
+static const struct sci_base_state sci_phy_state_table[] = {
+	[SCI_PHY_INITIAL] = { },
+	[SCI_PHY_STOPPED] = {
+		.enter_state = sci_phy_stopped_state_enter,
+	},
+	[SCI_PHY_STARTING] = {
+		.enter_state = sci_phy_starting_state_enter,
+	},
+	[SCI_PHY_SUB_INITIAL] = {
+		.enter_state = sci_phy_starting_initial_substate_enter,
+	},
+	[SCI_PHY_SUB_AWAIT_OSSP_EN] = { },
+	[SCI_PHY_SUB_AWAIT_SAS_SPEED_EN] = { },
+	[SCI_PHY_SUB_AWAIT_IAF_UF] = { },
+	[SCI_PHY_SUB_AWAIT_SAS_POWER] = {
+		.enter_state = sci_phy_starting_await_sas_power_substate_enter,
+		.exit_state  = sci_phy_starting_await_sas_power_substate_exit,
+	},
+	[SCI_PHY_SUB_AWAIT_SATA_POWER] = {
+		.enter_state = sci_phy_starting_await_sata_power_substate_enter,
+		.exit_state  = sci_phy_starting_await_sata_power_substate_exit
+	},
+	[SCI_PHY_SUB_AWAIT_SATA_PHY_EN] = {
+		.enter_state = sci_phy_starting_await_sata_phy_substate_enter,
+		.exit_state  = sci_phy_starting_await_sata_phy_substate_exit
+	},
+	[SCI_PHY_SUB_AWAIT_SATA_SPEED_EN] = {
+		.enter_state = sci_phy_starting_await_sata_speed_substate_enter,
+		.exit_state  = sci_phy_starting_await_sata_speed_substate_exit
+	},
+	[SCI_PHY_SUB_AWAIT_SIG_FIS_UF] = {
+		.enter_state = sci_phy_starting_await_sig_fis_uf_substate_enter,
+		.exit_state  = sci_phy_starting_await_sig_fis_uf_substate_exit
+	},
+	[SCI_PHY_SUB_FINAL] = {
+		.enter_state = sci_phy_starting_final_substate_enter,
+	},
+	[SCI_PHY_READY] = {
+		.enter_state = sci_phy_ready_state_enter,
+		.exit_state = sci_phy_ready_state_exit,
+	},
+	[SCI_PHY_RESETTING] = {
+		.enter_state = sci_phy_resetting_state_enter,
+	},
+	[SCI_PHY_FINAL] = { },
+};
+
+void sci_phy_construct(struct isci_phy *iphy,
+			    struct isci_port *iport, u8 phy_index)
+{
+	sci_init_sm(&iphy->sm, sci_phy_state_table, SCI_PHY_INITIAL);
+
+	/* Copy the rest of the input data to our locals */
+	iphy->owning_port = iport;
+	iphy->phy_index = phy_index;
+	iphy->bcn_received_while_port_unassigned = false;
+	iphy->protocol = SCIC_SDS_PHY_PROTOCOL_UNKNOWN;
+	iphy->link_layer_registers = NULL;
+	iphy->max_negotiated_speed = SAS_LINK_RATE_UNKNOWN;
+
+	/* Create the SIGNATURE FIS Timeout timer for this phy */
+	sci_init_timer(&iphy->sata_timer, phy_sata_timeout);
+}
+
+void isci_phy_init(struct isci_phy *iphy, struct isci_host *ihost, int index)
+{
+	struct sci_oem_params *oem = &ihost->oem_parameters;
+	u64 sci_sas_addr;
+	__be64 sas_addr;
+
+	sci_sas_addr = oem->phys[index].sas_address.high;
+	sci_sas_addr <<= 32;
+	sci_sas_addr |= oem->phys[index].sas_address.low;
+	sas_addr = cpu_to_be64(sci_sas_addr);
+	memcpy(iphy->sas_addr, &sas_addr, sizeof(sas_addr));
+
+	iphy->isci_port = NULL;
+	iphy->sas_phy.enabled = 0;
+	iphy->sas_phy.id = index;
+	iphy->sas_phy.sas_addr = &iphy->sas_addr[0];
+	iphy->sas_phy.frame_rcvd = (u8 *)&iphy->frame_rcvd;
+	iphy->sas_phy.ha = &ihost->sas_ha;
+	iphy->sas_phy.lldd_phy = iphy;
+	iphy->sas_phy.enabled = 1;
+	iphy->sas_phy.class = SAS;
+	iphy->sas_phy.iproto = SAS_PROTOCOL_ALL;
+	iphy->sas_phy.tproto = 0;
+	iphy->sas_phy.type = PHY_TYPE_PHYSICAL;
+	iphy->sas_phy.role = PHY_ROLE_INITIATOR;
+	iphy->sas_phy.oob_mode = OOB_NOT_CONNECTED;
+	iphy->sas_phy.linkrate = SAS_LINK_RATE_UNKNOWN;
+	memset(&iphy->frame_rcvd, 0, sizeof(iphy->frame_rcvd));
+}
+
+
+/**
+ * isci_phy_control() - This function is one of the SAS Domain Template
+ *    functions. This is a phy management function.
+ * @phy: This parameter specifies the sphy being controlled.
+ * @func: This parameter specifies the phy control function being invoked.
+ * @buf: This parameter is specific to the phy function being invoked.
+ *
+ * status, zero indicates success.
+ */
+int isci_phy_control(struct asd_sas_phy *sas_phy,
+		     enum phy_func func,
+		     void *buf)
+{
+	int ret = 0;
+	struct isci_phy *iphy = sas_phy->lldd_phy;
+	struct isci_port *iport = iphy->isci_port;
+	struct isci_host *ihost = sas_phy->ha->lldd_ha;
+	unsigned long flags;
+
+	dev_dbg(&ihost->pdev->dev,
+		"%s: phy %p; func %d; buf %p; isci phy %p, port %p\n",
+		__func__, sas_phy, func, buf, iphy, iport);
+
+	switch (func) {
+	case PHY_FUNC_DISABLE:
+		spin_lock_irqsave(&ihost->scic_lock, flags);
+		sci_phy_stop(iphy);
+		spin_unlock_irqrestore(&ihost->scic_lock, flags);
+		break;
+
+	case PHY_FUNC_LINK_RESET:
+		spin_lock_irqsave(&ihost->scic_lock, flags);
+		sci_phy_stop(iphy);
+		sci_phy_start(iphy);
+		spin_unlock_irqrestore(&ihost->scic_lock, flags);
+		break;
+
+	case PHY_FUNC_HARD_RESET:
+		if (!iport)
+			return -ENODEV;
+
+		/* Perform the port reset. */
+		ret = isci_port_perform_hard_reset(ihost, iport, iphy);
+
+		break;
+
+	default:
+		dev_dbg(&ihost->pdev->dev,
+			   "%s: phy %p; func %d NOT IMPLEMENTED!\n",
+			   __func__, sas_phy, func);
+		ret = -ENOSYS;
+		break;
+	}
+	return ret;
+}
diff -druN linux-2.6.39-libre/drivers/scsi/isci/phy.h linux-3.0-rc7-libre/drivers/scsi/isci/phy.h
--- linux-2.6.39-libre/drivers/scsi/isci/phy.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/scsi/isci/phy.h	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,504 @@
+/*
+ * This file is provided under a dual BSD/GPLv2 license.  When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * The full GNU General Public License is included in this distribution
+ * in the file called LICENSE.GPL.
+ *
+ * BSD LICENSE
+ *
+ * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in
+ *     the documentation and/or other materials provided with the
+ *     distribution.
+ *   * Neither the name of Intel Corporation nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef _ISCI_PHY_H_
+#define _ISCI_PHY_H_
+
+#include <scsi/sas.h>
+#include <scsi/libsas.h>
+#include "isci.h"
+#include "sas.h"
+
+/* This is the timeout value for the SATA phy to wait for a SIGNATURE FIS
+ * before restarting the starting state machine.  Technically, the old parallel
+ * ATA specification required up to 30 seconds for a device to issue its
+ * signature FIS as a result of a soft reset.  Now we see that devices respond
+ * generally within 15 seconds, but we'll use 25 for now.
+ */
+#define SCIC_SDS_SIGNATURE_FIS_TIMEOUT    25000
+
+/* This is the timeout for the SATA OOB/SN because the hardware does not
+ * recognize a hot plug after OOB signal but before the SN signals.  We need to
+ * make sure after a hotplug timeout if we have not received the speed event
+ * notification from the hardware that we restart the hardware OOB state
+ * machine.
+ */
+#define SCIC_SDS_SATA_LINK_TRAINING_TIMEOUT  250
+
+enum sci_phy_protocol {
+	SCIC_SDS_PHY_PROTOCOL_UNKNOWN,
+	SCIC_SDS_PHY_PROTOCOL_SAS,
+	SCIC_SDS_PHY_PROTOCOL_SATA,
+	SCIC_SDS_MAX_PHY_PROTOCOLS
+};
+
+/**
+ * isci_phy - hba local phy infrastructure
+ * @sm:
+ * @protocol: attached device protocol
+ * @phy_index: physical index relative to the controller (0-3)
+ * @bcn_received_while_port_unassigned: bcn to report after port association
+ * @sata_timer: timeout SATA signature FIS arrival
+ */
+struct isci_phy {
+	struct sci_base_state_machine sm;
+	struct isci_port *owning_port;
+	enum sas_linkrate max_negotiated_speed;
+	enum sci_phy_protocol protocol;
+	u8 phy_index;
+	bool bcn_received_while_port_unassigned;
+	bool is_in_link_training;
+	struct sci_timer sata_timer;
+	struct scu_transport_layer_registers __iomem *transport_layer_registers;
+	struct scu_link_layer_registers __iomem *link_layer_registers;
+	struct asd_sas_phy sas_phy;
+	struct isci_port *isci_port;
+	u8 sas_addr[SAS_ADDR_SIZE];
+	union {
+		struct sas_identify_frame iaf;
+		struct dev_to_host_fis fis;
+	} frame_rcvd;
+};
+
+static inline struct isci_phy *to_iphy(struct asd_sas_phy *sas_phy)
+{
+	struct isci_phy *iphy = container_of(sas_phy, typeof(*iphy), sas_phy);
+
+	return iphy;
+}
+
+struct sci_phy_cap {
+	union {
+		struct {
+			/*
+			 * The SAS specification indicates the start bit shall
+			 * always be set to
+			 * 1.  This implementation will have the start bit set
+			 * to 0 if the PHY CAPABILITIES were either not
+			 * received or speed negotiation failed.
+			 */
+			u8 start:1;
+			u8 tx_ssc_type:1;
+			u8 res1:2;
+			u8 req_logical_linkrate:4;
+
+			u32 gen1_no_ssc:1;
+			u32 gen1_ssc:1;
+			u32 gen2_no_ssc:1;
+			u32 gen2_ssc:1;
+			u32 gen3_no_ssc:1;
+			u32 gen3_ssc:1;
+			u32 res2:17;
+			u32 parity:1;
+		};
+		u32 all;
+	};
+}  __packed;
+
+/* this data structure reflects the link layer transmit identification reg */
+struct sci_phy_proto {
+	union {
+		struct {
+			u16 _r_a:1;
+			u16 smp_iport:1;
+			u16 stp_iport:1;
+			u16 ssp_iport:1;
+			u16 _r_b:4;
+			u16 _r_c:1;
+			u16 smp_tport:1;
+			u16 stp_tport:1;
+			u16 ssp_tport:1;
+			u16 _r_d:4;
+		};
+		u16 all;
+	};
+} __packed;
+
+
+/**
+ * struct sci_phy_properties - This structure defines the properties common to
+ *    all phys that can be retrieved.
+ *
+ *
+ */
+struct sci_phy_properties {
+	/**
+	 * This field specifies the port that currently contains the
+	 * supplied phy.  This field may be set to NULL
+	 * if the phy is not currently contained in a port.
+	 */
+	struct isci_port *iport;
+
+	/**
+	 * This field specifies the link rate at which the phy is
+	 * currently operating.
+	 */
+	enum sas_linkrate negotiated_link_rate;
+
+	/**
+	 * This field specifies the index of the phy in relation to other
+	 * phys within the controller.  This index is zero relative.
+	 */
+	u8 index;
+};
+
+/**
+ * struct sci_sas_phy_properties - This structure defines the properties,
+ *    specific to a SAS phy, that can be retrieved.
+ *
+ *
+ */
+struct sci_sas_phy_properties {
+	/**
+	 * This field delineates the Identify Address Frame received
+	 * from the remote end point.
+	 */
+	struct sas_identify_frame rcvd_iaf;
+
+	/**
+	 * This field delineates the Phy capabilities structure received
+	 * from the remote end point.
+	 */
+	struct sci_phy_cap rcvd_cap;
+
+};
+
+/**
+ * struct sci_sata_phy_properties - This structure defines the properties,
+ *    specific to a SATA phy, that can be retrieved.
+ *
+ *
+ */
+struct sci_sata_phy_properties {
+	/**
+	 * This field delineates the signature FIS received from the
+	 * attached target.
+	 */
+	struct dev_to_host_fis signature_fis;
+
+	/**
+	 * This field specifies to the user if a port selector is connected
+	 * on the specified phy.
+	 */
+	bool is_port_selector_present;
+
+};
+
+/**
+ * enum sci_phy_counter_id - This enumeration depicts the various pieces of
+ *    optional information that can be retrieved for a specific phy.
+ *
+ *
+ */
+enum sci_phy_counter_id {
+	/**
+	 * This PHY information field tracks the number of frames received.
+	 */
+	SCIC_PHY_COUNTER_RECEIVED_FRAME,
+
+	/**
+	 * This PHY information field tracks the number of frames transmitted.
+	 */
+	SCIC_PHY_COUNTER_TRANSMITTED_FRAME,
+
+	/**
+	 * This PHY information field tracks the number of DWORDs received.
+	 */
+	SCIC_PHY_COUNTER_RECEIVED_FRAME_WORD,
+
+	/**
+	 * This PHY information field tracks the number of DWORDs transmitted.
+	 */
+	SCIC_PHY_COUNTER_TRANSMITTED_FRAME_DWORD,
+
+	/**
+	 * This PHY information field tracks the number of times DWORD
+	 * synchronization was lost.
+	 */
+	SCIC_PHY_COUNTER_LOSS_OF_SYNC_ERROR,
+
+	/**
+	 * This PHY information field tracks the number of received DWORDs with
+	 * running disparity errors.
+	 */
+	SCIC_PHY_COUNTER_RECEIVED_DISPARITY_ERROR,
+
+	/**
+	 * This PHY information field tracks the number of received frames with a
+	 * CRC error (not including short or truncated frames).
+	 */
+	SCIC_PHY_COUNTER_RECEIVED_FRAME_CRC_ERROR,
+
+	/**
+	 * This PHY information field tracks the number of DONE (ACK/NAK TIMEOUT)
+	 * primitives received.
+	 */
+	SCIC_PHY_COUNTER_RECEIVED_DONE_ACK_NAK_TIMEOUT,
+
+	/**
+	 * This PHY information field tracks the number of DONE (ACK/NAK TIMEOUT)
+	 * primitives transmitted.
+	 */
+	SCIC_PHY_COUNTER_TRANSMITTED_DONE_ACK_NAK_TIMEOUT,
+
+	/**
+	 * This PHY information field tracks the number of times the inactivity
+	 * timer for connections on the phy has been utilized.
+	 */
+	SCIC_PHY_COUNTER_INACTIVITY_TIMER_EXPIRED,
+
+	/**
+	 * This PHY information field tracks the number of DONE (CREDIT TIMEOUT)
+	 * primitives received.
+	 */
+	SCIC_PHY_COUNTER_RECEIVED_DONE_CREDIT_TIMEOUT,
+
+	/**
+	 * This PHY information field tracks the number of DONE (CREDIT TIMEOUT)
+	 * primitives transmitted.
+	 */
+	SCIC_PHY_COUNTER_TRANSMITTED_DONE_CREDIT_TIMEOUT,
+
+	/**
+	 * This PHY information field tracks the number of CREDIT BLOCKED
+	 * primitives received.
+	 * @note Depending on remote device implementation, credit blocks
+	 *       may occur regularly.
+	 */
+	SCIC_PHY_COUNTER_RECEIVED_CREDIT_BLOCKED,
+
+	/**
+	 * This PHY information field contains the number of short frames
+	 * received.  A short frame is simply a frame smaller then what is
+	 * allowed by either the SAS or SATA specification.
+	 */
+	SCIC_PHY_COUNTER_RECEIVED_SHORT_FRAME,
+
+	/**
+	 * This PHY information field contains the number of frames received after
+	 * credit has been exhausted.
+	 */
+	SCIC_PHY_COUNTER_RECEIVED_FRAME_WITHOUT_CREDIT,
+
+	/**
+	 * This PHY information field contains the number of frames received after
+	 * a DONE has been received.
+	 */
+	SCIC_PHY_COUNTER_RECEIVED_FRAME_AFTER_DONE,
+
+	/**
+	 * This PHY information field contains the number of times the phy
+	 * failed to achieve DWORD synchronization during speed negotiation.
+	 */
+	SCIC_PHY_COUNTER_SN_DWORD_SYNC_ERROR
+};
+
+enum sci_phy_states {
+	/**
+	 * Simply the initial state for the base domain state machine.
+	 */
+	SCI_PHY_INITIAL,
+
+	/**
+	 * This state indicates that the phy has successfully been stopped.
+	 * In this state no new IO operations are permitted on this phy.
+	 * This state is entered from the INITIAL state.
+	 * This state is entered from the STARTING state.
+	 * This state is entered from the READY state.
+	 * This state is entered from the RESETTING state.
+	 */
+	SCI_PHY_STOPPED,
+
+	/**
+	 * This state indicates that the phy is in the process of becomming
+	 * ready.  In this state no new IO operations are permitted on this phy.
+	 * This state is entered from the STOPPED state.
+	 * This state is entered from the READY state.
+	 * This state is entered from the RESETTING state.
+	 */
+	SCI_PHY_STARTING,
+
+	/**
+	 * Initial state
+	 */
+	SCI_PHY_SUB_INITIAL,
+
+	/**
+	 * Wait state for the hardware OSSP event type notification
+	 */
+	SCI_PHY_SUB_AWAIT_OSSP_EN,
+
+	/**
+	 * Wait state for the PHY speed notification
+	 */
+	SCI_PHY_SUB_AWAIT_SAS_SPEED_EN,
+
+	/**
+	 * Wait state for the IAF Unsolicited frame notification
+	 */
+	SCI_PHY_SUB_AWAIT_IAF_UF,
+
+	/**
+	 * Wait state for the request to consume power
+	 */
+	SCI_PHY_SUB_AWAIT_SAS_POWER,
+
+	/**
+	 * Wait state for request to consume power
+	 */
+	SCI_PHY_SUB_AWAIT_SATA_POWER,
+
+	/**
+	 * Wait state for the SATA PHY notification
+	 */
+	SCI_PHY_SUB_AWAIT_SATA_PHY_EN,
+
+	/**
+	 * Wait for the SATA PHY speed notification
+	 */
+	SCI_PHY_SUB_AWAIT_SATA_SPEED_EN,
+
+	/**
+	 * Wait state for the SIGNATURE FIS unsolicited frame notification
+	 */
+	SCI_PHY_SUB_AWAIT_SIG_FIS_UF,
+
+	/**
+	 * Exit state for this state machine
+	 */
+	SCI_PHY_SUB_FINAL,
+
+	/**
+	 * This state indicates the the phy is now ready.  Thus, the user
+	 * is able to perform IO operations utilizing this phy as long as it
+	 * is currently part of a valid port.
+	 * This state is entered from the STARTING state.
+	 */
+	SCI_PHY_READY,
+
+	/**
+	 * This state indicates that the phy is in the process of being reset.
+	 * In this state no new IO operations are permitted on this phy.
+	 * This state is entered from the READY state.
+	 */
+	SCI_PHY_RESETTING,
+
+	/**
+	 * Simply the final state for the base phy state machine.
+	 */
+	SCI_PHY_FINAL,
+};
+
+void sci_phy_construct(
+	struct isci_phy *iphy,
+	struct isci_port *iport,
+	u8 phy_index);
+
+struct isci_port *phy_get_non_dummy_port(struct isci_phy *iphy);
+
+void sci_phy_set_port(
+	struct isci_phy *iphy,
+	struct isci_port *iport);
+
+enum sci_status sci_phy_initialize(
+	struct isci_phy *iphy,
+	struct scu_transport_layer_registers __iomem *transport_layer_registers,
+	struct scu_link_layer_registers __iomem *link_layer_registers);
+
+enum sci_status sci_phy_start(
+	struct isci_phy *iphy);
+
+enum sci_status sci_phy_stop(
+	struct isci_phy *iphy);
+
+enum sci_status sci_phy_reset(
+	struct isci_phy *iphy);
+
+void sci_phy_resume(
+	struct isci_phy *iphy);
+
+void sci_phy_setup_transport(
+	struct isci_phy *iphy,
+	u32 device_id);
+
+enum sci_status sci_phy_event_handler(
+	struct isci_phy *iphy,
+	u32 event_code);
+
+enum sci_status sci_phy_frame_handler(
+	struct isci_phy *iphy,
+	u32 frame_index);
+
+enum sci_status sci_phy_consume_power_handler(
+	struct isci_phy *iphy);
+
+void sci_phy_get_sas_address(
+	struct isci_phy *iphy,
+	struct sci_sas_address *sas_address);
+
+void sci_phy_get_attached_sas_address(
+	struct isci_phy *iphy,
+	struct sci_sas_address *sas_address);
+
+struct sci_phy_proto;
+void sci_phy_get_protocols(
+	struct isci_phy *iphy,
+	struct sci_phy_proto *protocols);
+enum sas_linkrate sci_phy_linkrate(struct isci_phy *iphy);
+
+struct isci_host;
+void isci_phy_init(struct isci_phy *iphy, struct isci_host *ihost, int index);
+int isci_phy_control(struct asd_sas_phy *phy, enum phy_func func, void *buf);
+
+#endif /* !defined(_ISCI_PHY_H_) */
diff -druN linux-2.6.39-libre/drivers/scsi/isci/port.c linux-3.0-rc7-libre/drivers/scsi/isci/port.c
--- linux-2.6.39-libre/drivers/scsi/isci/port.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/scsi/isci/port.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,1757 @@
+/*
+ * This file is provided under a dual BSD/GPLv2 license.  When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * The full GNU General Public License is included in this distribution
+ * in the file called LICENSE.GPL.
+ *
+ * BSD LICENSE
+ *
+ * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in
+ *     the documentation and/or other materials provided with the
+ *     distribution.
+ *   * Neither the name of Intel Corporation nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "isci.h"
+#include "port.h"
+#include "request.h"
+
+#define SCIC_SDS_PORT_HARD_RESET_TIMEOUT  (1000)
+#define SCU_DUMMY_INDEX    (0xFFFF)
+
+static void isci_port_change_state(struct isci_port *iport, enum isci_status status)
+{
+	unsigned long flags;
+
+	dev_dbg(&iport->isci_host->pdev->dev,
+		"%s: iport = %p, state = 0x%x\n",
+		__func__, iport, status);
+
+	/* XXX pointless lock */
+	spin_lock_irqsave(&iport->state_lock, flags);
+	iport->status = status;
+	spin_unlock_irqrestore(&iport->state_lock, flags);
+}
+
+static void sci_port_get_protocols(struct isci_port *iport, struct sci_phy_proto *proto)
+{
+	u8 index;
+
+	proto->all = 0;
+	for (index = 0; index < SCI_MAX_PHYS; index++) {
+		struct isci_phy *iphy = iport->phy_table[index];
+
+		if (!iphy)
+			continue;
+		sci_phy_get_protocols(iphy, proto);
+	}
+}
+
+static u32 sci_port_get_phys(struct isci_port *iport)
+{
+	u32 index;
+	u32 mask;
+
+	mask = 0;
+	for (index = 0; index < SCI_MAX_PHYS; index++)
+		if (iport->phy_table[index])
+			mask |= (1 << index);
+
+	return mask;
+}
+
+/**
+ * sci_port_get_properties() - This method simply returns the properties
+ *    regarding the port, such as: physical index, protocols, sas address, etc.
+ * @port: this parameter specifies the port for which to retrieve the physical
+ *    index.
+ * @properties: This parameter specifies the properties structure into which to
+ *    copy the requested information.
+ *
+ * Indicate if the user specified a valid port. SCI_SUCCESS This value is
+ * returned if the specified port was valid. SCI_FAILURE_INVALID_PORT This
+ * value is returned if the specified port is not valid.  When this value is
+ * returned, no data is copied to the properties output parameter.
+ */
+static enum sci_status sci_port_get_properties(struct isci_port *iport,
+						struct sci_port_properties *prop)
+{
+	if (!iport || iport->logical_port_index == SCIC_SDS_DUMMY_PORT)
+		return SCI_FAILURE_INVALID_PORT;
+
+	prop->index = iport->logical_port_index;
+	prop->phy_mask = sci_port_get_phys(iport);
+	sci_port_get_sas_address(iport, &prop->local.sas_address);
+	sci_port_get_protocols(iport, &prop->local.protocols);
+	sci_port_get_attached_sas_address(iport, &prop->remote.sas_address);
+
+	return SCI_SUCCESS;
+}
+
+static void sci_port_bcn_enable(struct isci_port *iport)
+{
+	struct isci_phy *iphy;
+	u32 val;
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(iport->phy_table); i++) {
+		iphy = iport->phy_table[i];
+		if (!iphy)
+			continue;
+		val = readl(&iphy->link_layer_registers->link_layer_control);
+		/* clear the bit by writing 1. */
+		writel(val, &iphy->link_layer_registers->link_layer_control);
+	}
+}
+
+/* called under sci_lock to stabilize phy:port associations */
+void isci_port_bcn_enable(struct isci_host *ihost, struct isci_port *iport)
+{
+	int i;
+
+	clear_bit(IPORT_BCN_BLOCKED, &iport->flags);
+	wake_up(&ihost->eventq);
+
+	if (!test_and_clear_bit(IPORT_BCN_PENDING, &iport->flags))
+		return;
+
+	for (i = 0; i < ARRAY_SIZE(iport->phy_table); i++) {
+		struct isci_phy *iphy = iport->phy_table[i];
+
+		if (!iphy)
+			continue;
+
+		ihost->sas_ha.notify_port_event(&iphy->sas_phy,
+						PORTE_BROADCAST_RCVD);
+		break;
+	}
+}
+
+static void isci_port_bc_change_received(struct isci_host *ihost,
+					 struct isci_port *iport,
+					 struct isci_phy *iphy)
+{
+	if (iport && test_bit(IPORT_BCN_BLOCKED, &iport->flags)) {
+		dev_dbg(&ihost->pdev->dev,
+			"%s: disabled BCN; isci_phy = %p, sas_phy = %p\n",
+			__func__, iphy, &iphy->sas_phy);
+		set_bit(IPORT_BCN_PENDING, &iport->flags);
+		atomic_inc(&iport->event);
+		wake_up(&ihost->eventq);
+	} else {
+		dev_dbg(&ihost->pdev->dev,
+			"%s: isci_phy = %p, sas_phy = %p\n",
+			__func__, iphy, &iphy->sas_phy);
+
+		ihost->sas_ha.notify_port_event(&iphy->sas_phy,
+						PORTE_BROADCAST_RCVD);
+	}
+	sci_port_bcn_enable(iport);
+}
+
+static void isci_port_link_up(struct isci_host *isci_host,
+			      struct isci_port *iport,
+			      struct isci_phy *iphy)
+{
+	unsigned long flags;
+	struct sci_port_properties properties;
+	unsigned long success = true;
+
+	BUG_ON(iphy->isci_port != NULL);
+
+	iphy->isci_port = iport;
+
+	dev_dbg(&isci_host->pdev->dev,
+		"%s: isci_port = %p\n",
+		__func__, iport);
+
+	spin_lock_irqsave(&iphy->sas_phy.frame_rcvd_lock, flags);
+
+	isci_port_change_state(iphy->isci_port, isci_starting);
+
+	sci_port_get_properties(iport, &properties);
+
+	if (iphy->protocol == SCIC_SDS_PHY_PROTOCOL_SATA) {
+		u64 attached_sas_address;
+
+		iphy->sas_phy.oob_mode = SATA_OOB_MODE;
+		iphy->sas_phy.frame_rcvd_size = sizeof(struct dev_to_host_fis);
+
+		/*
+		 * For direct-attached SATA devices, the SCI core will
+		 * automagically assign a SAS address to the end device
+		 * for the purpose of creating a port. This SAS address
+		 * will not be the same as assigned to the PHY and needs
+		 * to be obtained from struct sci_port_properties properties.
+		 */
+		attached_sas_address = properties.remote.sas_address.high;
+		attached_sas_address <<= 32;
+		attached_sas_address |= properties.remote.sas_address.low;
+		swab64s(&attached_sas_address);
+
+		memcpy(&iphy->sas_phy.attached_sas_addr,
+		       &attached_sas_address, sizeof(attached_sas_address));
+	} else if (iphy->protocol == SCIC_SDS_PHY_PROTOCOL_SAS) {
+		iphy->sas_phy.oob_mode = SAS_OOB_MODE;
+		iphy->sas_phy.frame_rcvd_size = sizeof(struct sas_identify_frame);
+
+		/* Copy the attached SAS address from the IAF */
+		memcpy(iphy->sas_phy.attached_sas_addr,
+		       iphy->frame_rcvd.iaf.sas_addr, SAS_ADDR_SIZE);
+	} else {
+		dev_err(&isci_host->pdev->dev, "%s: unkown target\n", __func__);
+		success = false;
+	}
+
+	iphy->sas_phy.phy->negotiated_linkrate = sci_phy_linkrate(iphy);
+
+	spin_unlock_irqrestore(&iphy->sas_phy.frame_rcvd_lock, flags);
+
+	/* Notify libsas that we have an address frame, if indeed
+	 * we've found an SSP, SMP, or STP target */
+	if (success)
+		isci_host->sas_ha.notify_port_event(&iphy->sas_phy,
+						    PORTE_BYTES_DMAED);
+}
+
+
+/**
+ * isci_port_link_down() - This function is called by the sci core when a link
+ *    becomes inactive.
+ * @isci_host: This parameter specifies the isci host object.
+ * @phy: This parameter specifies the isci phy with the active link.
+ * @port: This parameter specifies the isci port with the active link.
+ *
+ */
+static void isci_port_link_down(struct isci_host *isci_host,
+				struct isci_phy *isci_phy,
+				struct isci_port *isci_port)
+{
+	struct isci_remote_device *isci_device;
+
+	dev_dbg(&isci_host->pdev->dev,
+		"%s: isci_port = %p\n", __func__, isci_port);
+
+	if (isci_port) {
+
+		/* check to see if this is the last phy on this port. */
+		if (isci_phy->sas_phy.port &&
+		    isci_phy->sas_phy.port->num_phys == 1) {
+			atomic_inc(&isci_port->event);
+			isci_port_bcn_enable(isci_host, isci_port);
+
+			/* change the state for all devices on this port.  The
+			 * next task sent to this device will be returned as
+			 * SAS_TASK_UNDELIVERED, and the scsi mid layer will
+			 * remove the target
+			 */
+			list_for_each_entry(isci_device,
+					    &isci_port->remote_dev_list,
+					    node) {
+				dev_dbg(&isci_host->pdev->dev,
+					"%s: isci_device = %p\n",
+					__func__, isci_device);
+				set_bit(IDEV_GONE, &isci_device->flags);
+			}
+		}
+		isci_port_change_state(isci_port, isci_stopping);
+	}
+
+	/* Notify libsas of the borken link, this will trigger calls to our
+	 * isci_port_deformed and isci_dev_gone functions.
+	 */
+	sas_phy_disconnected(&isci_phy->sas_phy);
+	isci_host->sas_ha.notify_phy_event(&isci_phy->sas_phy,
+					   PHYE_LOSS_OF_SIGNAL);
+
+	isci_phy->isci_port = NULL;
+
+	dev_dbg(&isci_host->pdev->dev,
+		"%s: isci_port = %p - Done\n", __func__, isci_port);
+}
+
+
+/**
+ * isci_port_ready() - This function is called by the sci core when a link
+ *    becomes ready.
+ * @isci_host: This parameter specifies the isci host object.
+ * @port: This parameter specifies the sci port with the active link.
+ *
+ */
+static void isci_port_ready(struct isci_host *isci_host, struct isci_port *isci_port)
+{
+	dev_dbg(&isci_host->pdev->dev,
+		"%s: isci_port = %p\n", __func__, isci_port);
+
+	complete_all(&isci_port->start_complete);
+	isci_port_change_state(isci_port, isci_ready);
+	return;
+}
+
+/**
+ * isci_port_not_ready() - This function is called by the sci core when a link
+ *    is not ready. All remote devices on this link will be removed if they are
+ *    in the stopping state.
+ * @isci_host: This parameter specifies the isci host object.
+ * @port: This parameter specifies the sci port with the active link.
+ *
+ */
+static void isci_port_not_ready(struct isci_host *isci_host, struct isci_port *isci_port)
+{
+	dev_dbg(&isci_host->pdev->dev,
+		"%s: isci_port = %p\n", __func__, isci_port);
+}
+
+static void isci_port_stop_complete(struct isci_host *ihost,
+				    struct isci_port *iport,
+				    enum sci_status completion_status)
+{
+	dev_dbg(&ihost->pdev->dev, "Port stop complete\n");
+}
+
+/**
+ * isci_port_hard_reset_complete() - This function is called by the sci core
+ *    when the hard reset complete notification has been received.
+ * @port: This parameter specifies the sci port with the active link.
+ * @completion_status: This parameter specifies the core status for the reset
+ *    process.
+ *
+ */
+static void isci_port_hard_reset_complete(struct isci_port *isci_port,
+					  enum sci_status completion_status)
+{
+	dev_dbg(&isci_port->isci_host->pdev->dev,
+		"%s: isci_port = %p, completion_status=%x\n",
+		     __func__, isci_port, completion_status);
+
+	/* Save the status of the hard reset from the port. */
+	isci_port->hard_reset_status = completion_status;
+
+	complete_all(&isci_port->hard_reset_complete);
+}
+
+/* This method will return a true value if the specified phy can be assigned to
+ * this port The following is a list of phys for each port that are allowed: -
+ * Port 0 - 3 2 1 0 - Port 1 -     1 - Port 2 - 3 2 - Port 3 - 3 This method
+ * doesn't preclude all configurations.  It merely ensures that a phy is part
+ * of the allowable set of phy identifiers for that port.  For example, one
+ * could assign phy 3 to port 0 and no other phys.  Please refer to
+ * sci_port_is_phy_mask_valid() for information regarding whether the
+ * phy_mask for a port can be supported. bool true if this is a valid phy
+ * assignment for the port false if this is not a valid phy assignment for the
+ * port
+ */
+bool sci_port_is_valid_phy_assignment(struct isci_port *iport, u32 phy_index)
+{
+	struct isci_host *ihost = iport->owning_controller;
+	struct sci_user_parameters *user = &ihost->user_parameters;
+
+	/* Initialize to invalid value. */
+	u32 existing_phy_index = SCI_MAX_PHYS;
+	u32 index;
+
+	if ((iport->physical_port_index == 1) && (phy_index != 1))
+		return false;
+
+	if (iport->physical_port_index == 3 && phy_index != 3)
+		return false;
+
+	if (iport->physical_port_index == 2 &&
+	    (phy_index == 0 || phy_index == 1))
+		return false;
+
+	for (index = 0; index < SCI_MAX_PHYS; index++)
+		if (iport->phy_table[index] && index != phy_index)
+			existing_phy_index = index;
+
+	/* Ensure that all of the phys in the port are capable of
+	 * operating at the same maximum link rate.
+	 */
+	if (existing_phy_index < SCI_MAX_PHYS &&
+	    user->phys[phy_index].max_speed_generation !=
+	    user->phys[existing_phy_index].max_speed_generation)
+		return false;
+
+	return true;
+}
+
+/**
+ *
+ * @sci_port: This is the port object for which to determine if the phy mask
+ *    can be supported.
+ *
+ * This method will return a true value if the port's phy mask can be supported
+ * by the SCU. The following is a list of valid PHY mask configurations for
+ * each port: - Port 0 - [[3  2] 1] 0 - Port 1 -        [1] - Port 2 - [[3] 2]
+ * - Port 3 -  [3] This method returns a boolean indication specifying if the
+ * phy mask can be supported. true if this is a valid phy assignment for the
+ * port false if this is not a valid phy assignment for the port
+ */
+static bool sci_port_is_phy_mask_valid(
+	struct isci_port *iport,
+	u32 phy_mask)
+{
+	if (iport->physical_port_index == 0) {
+		if (((phy_mask & 0x0F) == 0x0F)
+		    || ((phy_mask & 0x03) == 0x03)
+		    || ((phy_mask & 0x01) == 0x01)
+		    || (phy_mask == 0))
+			return true;
+	} else if (iport->physical_port_index == 1) {
+		if (((phy_mask & 0x02) == 0x02)
+		    || (phy_mask == 0))
+			return true;
+	} else if (iport->physical_port_index == 2) {
+		if (((phy_mask & 0x0C) == 0x0C)
+		    || ((phy_mask & 0x04) == 0x04)
+		    || (phy_mask == 0))
+			return true;
+	} else if (iport->physical_port_index == 3) {
+		if (((phy_mask & 0x08) == 0x08)
+		    || (phy_mask == 0))
+			return true;
+	}
+
+	return false;
+}
+
+/*
+ * This method retrieves a currently active (i.e. connected) phy contained in
+ * the port.  Currently, the lowest order phy that is connected is returned.
+ * This method returns a pointer to a SCIS_SDS_PHY object. NULL This value is
+ * returned if there are no currently active (i.e. connected to a remote end
+ * point) phys contained in the port. All other values specify a struct sci_phy
+ * object that is active in the port.
+ */
+static struct isci_phy *sci_port_get_a_connected_phy(struct isci_port *iport)
+{
+	u32 index;
+	struct isci_phy *iphy;
+
+	for (index = 0; index < SCI_MAX_PHYS; index++) {
+		/* Ensure that the phy is both part of the port and currently
+		 * connected to the remote end-point.
+		 */
+		iphy = iport->phy_table[index];
+		if (iphy && sci_port_active_phy(iport, iphy))
+			return iphy;
+	}
+
+	return NULL;
+}
+
+static enum sci_status sci_port_set_phy(struct isci_port *iport, struct isci_phy *iphy)
+{
+	/* Check to see if we can add this phy to a port
+	 * that means that the phy is not part of a port and that the port does
+	 * not already have a phy assinged to the phy index.
+	 */
+	if (!iport->phy_table[iphy->phy_index] &&
+	    !phy_get_non_dummy_port(iphy) &&
+	    sci_port_is_valid_phy_assignment(iport, iphy->phy_index)) {
+		/* Phy is being added in the stopped state so we are in MPC mode
+		 * make logical port index = physical port index
+		 */
+		iport->logical_port_index = iport->physical_port_index;
+		iport->phy_table[iphy->phy_index] = iphy;
+		sci_phy_set_port(iphy, iport);
+
+		return SCI_SUCCESS;
+	}
+
+	return SCI_FAILURE;
+}
+
+static enum sci_status sci_port_clear_phy(struct isci_port *iport, struct isci_phy *iphy)
+{
+	/* Make sure that this phy is part of this port */
+	if (iport->phy_table[iphy->phy_index] == iphy &&
+	    phy_get_non_dummy_port(iphy) == iport) {
+		struct isci_host *ihost = iport->owning_controller;
+
+		/* Yep it is assigned to this port so remove it */
+		sci_phy_set_port(iphy, &ihost->ports[SCI_MAX_PORTS]);
+		iport->phy_table[iphy->phy_index] = NULL;
+		return SCI_SUCCESS;
+	}
+
+	return SCI_FAILURE;
+}
+
+void sci_port_get_sas_address(struct isci_port *iport, struct sci_sas_address *sas)
+{
+	u32 index;
+
+	sas->high = 0;
+	sas->low  = 0;
+	for (index = 0; index < SCI_MAX_PHYS; index++)
+		if (iport->phy_table[index])
+			sci_phy_get_sas_address(iport->phy_table[index], sas);
+}
+
+void sci_port_get_attached_sas_address(struct isci_port *iport, struct sci_sas_address *sas)
+{
+	struct isci_phy *iphy;
+
+	/*
+	 * Ensure that the phy is both part of the port and currently
+	 * connected to the remote end-point.
+	 */
+	iphy = sci_port_get_a_connected_phy(iport);
+	if (iphy) {
+		if (iphy->protocol != SCIC_SDS_PHY_PROTOCOL_SATA) {
+			sci_phy_get_attached_sas_address(iphy, sas);
+		} else {
+			sci_phy_get_sas_address(iphy, sas);
+			sas->low += iphy->phy_index;
+		}
+	} else {
+		sas->high = 0;
+		sas->low  = 0;
+	}
+}
+
+/**
+ * sci_port_construct_dummy_rnc() - create dummy rnc for si workaround
+ *
+ * @sci_port: logical port on which we need to create the remote node context
+ * @rni: remote node index for this remote node context.
+ *
+ * This routine will construct a dummy remote node context data structure
+ * This structure will be posted to the hardware to work around a scheduler
+ * error in the hardware.
+ */
+static void sci_port_construct_dummy_rnc(struct isci_port *iport, u16 rni)
+{
+	union scu_remote_node_context *rnc;
+
+	rnc = &iport->owning_controller->remote_node_context_table[rni];
+
+	memset(rnc, 0, sizeof(union scu_remote_node_context));
+
+	rnc->ssp.remote_sas_address_hi = 0;
+	rnc->ssp.remote_sas_address_lo = 0;
+
+	rnc->ssp.remote_node_index = rni;
+	rnc->ssp.remote_node_port_width = 1;
+	rnc->ssp.logical_port_index = iport->physical_port_index;
+
+	rnc->ssp.nexus_loss_timer_enable = false;
+	rnc->ssp.check_bit = false;
+	rnc->ssp.is_valid = true;
+	rnc->ssp.is_remote_node_context = true;
+	rnc->ssp.function_number = 0;
+	rnc->ssp.arbitration_wait_time = 0;
+}
+
+/*
+ * construct a dummy task context data structure.  This
+ * structure will be posted to the hardwre to work around a scheduler error
+ * in the hardware.
+ */
+static void sci_port_construct_dummy_task(struct isci_port *iport, u16 tag)
+{
+	struct isci_host *ihost = iport->owning_controller;
+	struct scu_task_context *task_context;
+
+	task_context = &ihost->task_context_table[ISCI_TAG_TCI(tag)];
+	memset(task_context, 0, sizeof(struct scu_task_context));
+
+	task_context->initiator_request = 1;
+	task_context->connection_rate = 1;
+	task_context->logical_port_index = iport->physical_port_index;
+	task_context->protocol_type = SCU_TASK_CONTEXT_PROTOCOL_SSP;
+	task_context->task_index = ISCI_TAG_TCI(tag);
+	task_context->valid = SCU_TASK_CONTEXT_VALID;
+	task_context->context_type = SCU_TASK_CONTEXT_TYPE;
+	task_context->remote_node_index = iport->reserved_rni;
+	task_context->do_not_dma_ssp_good_response = 1;
+	task_context->task_phase = 0x01;
+}
+
+static void sci_port_destroy_dummy_resources(struct isci_port *iport)
+{
+	struct isci_host *ihost = iport->owning_controller;
+
+	if (iport->reserved_tag != SCI_CONTROLLER_INVALID_IO_TAG)
+		isci_free_tag(ihost, iport->reserved_tag);
+
+	if (iport->reserved_rni != SCU_DUMMY_INDEX)
+		sci_remote_node_table_release_remote_node_index(&ihost->available_remote_nodes,
+								     1, iport->reserved_rni);
+
+	iport->reserved_rni = SCU_DUMMY_INDEX;
+	iport->reserved_tag = SCI_CONTROLLER_INVALID_IO_TAG;
+}
+
+void sci_port_setup_transports(struct isci_port *iport, u32 device_id)
+{
+	u8 index;
+
+	for (index = 0; index < SCI_MAX_PHYS; index++) {
+		if (iport->active_phy_mask & (1 << index))
+			sci_phy_setup_transport(iport->phy_table[index], device_id);
+	}
+}
+
+static void sci_port_activate_phy(struct isci_port *iport, struct isci_phy *iphy,
+				  bool do_notify_user)
+{
+	struct isci_host *ihost = iport->owning_controller;
+
+	if (iphy->protocol != SCIC_SDS_PHY_PROTOCOL_SATA)
+		sci_phy_resume(iphy);
+
+	iport->active_phy_mask |= 1 << iphy->phy_index;
+
+	sci_controller_clear_invalid_phy(ihost, iphy);
+
+	if (do_notify_user == true)
+		isci_port_link_up(ihost, iport, iphy);
+}
+
+void sci_port_deactivate_phy(struct isci_port *iport, struct isci_phy *iphy,
+			     bool do_notify_user)
+{
+	struct isci_host *ihost = iport->owning_controller;
+
+	iport->active_phy_mask &= ~(1 << iphy->phy_index);
+
+	iphy->max_negotiated_speed = SAS_LINK_RATE_UNKNOWN;
+
+	/* Re-assign the phy back to the LP as if it were a narrow port */
+	writel(iphy->phy_index,
+		&iport->port_pe_configuration_register[iphy->phy_index]);
+
+	if (do_notify_user == true)
+		isci_port_link_down(ihost, iphy, iport);
+}
+
+static void sci_port_invalid_link_up(struct isci_port *iport, struct isci_phy *iphy)
+{
+	struct isci_host *ihost = iport->owning_controller;
+
+	/*
+	 * Check to see if we have alreay reported this link as bad and if
+	 * not go ahead and tell the SCI_USER that we have discovered an
+	 * invalid link.
+	 */
+	if ((ihost->invalid_phy_mask & (1 << iphy->phy_index)) == 0) {
+		ihost->invalid_phy_mask |= 1 << iphy->phy_index;
+		dev_warn(&ihost->pdev->dev, "Invalid link up!\n");
+	}
+}
+
+static bool is_port_ready_state(enum sci_port_states state)
+{
+	switch (state) {
+	case SCI_PORT_READY:
+	case SCI_PORT_SUB_WAITING:
+	case SCI_PORT_SUB_OPERATIONAL:
+	case SCI_PORT_SUB_CONFIGURING:
+		return true;
+	default:
+		return false;
+	}
+}
+
+/* flag dummy rnc hanling when exiting a ready state */
+static void port_state_machine_change(struct isci_port *iport,
+				      enum sci_port_states state)
+{
+	struct sci_base_state_machine *sm = &iport->sm;
+	enum sci_port_states old_state = sm->current_state_id;
+
+	if (is_port_ready_state(old_state) && !is_port_ready_state(state))
+		iport->ready_exit = true;
+
+	sci_change_state(sm, state);
+	iport->ready_exit = false;
+}
+
+/**
+ * sci_port_general_link_up_handler - phy can be assigned to port?
+ * @sci_port: sci_port object for which has a phy that has gone link up.
+ * @sci_phy: This is the struct isci_phy object that has gone link up.
+ * @do_notify_user: This parameter specifies whether to inform the user (via
+ *    sci_port_link_up()) as to the fact that a new phy as become ready.
+ *
+ * Determine if this phy can be assigned to this
+ * port . If the phy is not a valid PHY for
+ * this port then the function will notify the user. A PHY can only be
+ * part of a port if it's attached SAS ADDRESS is the same as all other PHYs in
+ * the same port. none
+ */
+static void sci_port_general_link_up_handler(struct isci_port *iport,
+						  struct isci_phy *iphy,
+						  bool do_notify_user)
+{
+	struct sci_sas_address port_sas_address;
+	struct sci_sas_address phy_sas_address;
+
+	sci_port_get_attached_sas_address(iport, &port_sas_address);
+	sci_phy_get_attached_sas_address(iphy, &phy_sas_address);
+
+	/* If the SAS address of the new phy matches the SAS address of
+	 * other phys in the port OR this is the first phy in the port,
+	 * then activate the phy and allow it to be used for operations
+	 * in this port.
+	 */
+	if ((phy_sas_address.high == port_sas_address.high &&
+	     phy_sas_address.low  == port_sas_address.low) ||
+	    iport->active_phy_mask == 0) {
+		struct sci_base_state_machine *sm = &iport->sm;
+
+		sci_port_activate_phy(iport, iphy, do_notify_user);
+		if (sm->current_state_id == SCI_PORT_RESETTING)
+			port_state_machine_change(iport, SCI_PORT_READY);
+	} else
+		sci_port_invalid_link_up(iport, iphy);
+}
+
+
+
+/**
+ * This method returns false if the port only has a single phy object assigned.
+ *     If there are no phys or more than one phy then the method will return
+ *    true.
+ * @sci_port: The port for which the wide port condition is to be checked.
+ *
+ * bool true Is returned if this is a wide ported port. false Is returned if
+ * this is a narrow port.
+ */
+static bool sci_port_is_wide(struct isci_port *iport)
+{
+	u32 index;
+	u32 phy_count = 0;
+
+	for (index = 0; index < SCI_MAX_PHYS; index++) {
+		if (iport->phy_table[index] != NULL) {
+			phy_count++;
+		}
+	}
+
+	return phy_count != 1;
+}
+
+/**
+ * This method is called by the PHY object when the link is detected. if the
+ *    port wants the PHY to continue on to the link up state then the port
+ *    layer must return true.  If the port object returns false the phy object
+ *    must halt its attempt to go link up.
+ * @sci_port: The port associated with the phy object.
+ * @sci_phy: The phy object that is trying to go link up.
+ *
+ * true if the phy object can continue to the link up condition. true Is
+ * returned if this phy can continue to the ready state. false Is returned if
+ * can not continue on to the ready state. This notification is in place for
+ * wide ports and direct attached phys.  Since there are no wide ported SATA
+ * devices this could become an invalid port configuration.
+ */
+bool sci_port_link_detected(
+	struct isci_port *iport,
+	struct isci_phy *iphy)
+{
+	if ((iport->logical_port_index != SCIC_SDS_DUMMY_PORT) &&
+	    (iphy->protocol == SCIC_SDS_PHY_PROTOCOL_SATA) &&
+	    sci_port_is_wide(iport)) {
+		sci_port_invalid_link_up(iport, iphy);
+
+		return false;
+	}
+
+	return true;
+}
+
+static void port_timeout(unsigned long data)
+{
+	struct sci_timer *tmr = (struct sci_timer *)data;
+	struct isci_port *iport = container_of(tmr, typeof(*iport), timer);
+	struct isci_host *ihost = iport->owning_controller;
+	unsigned long flags;
+	u32 current_state;
+
+	spin_lock_irqsave(&ihost->scic_lock, flags);
+
+	if (tmr->cancel)
+		goto done;
+
+	current_state = iport->sm.current_state_id;
+
+	if (current_state == SCI_PORT_RESETTING) {
+		/* if the port is still in the resetting state then the timeout
+		 * fired before the reset completed.
+		 */
+		port_state_machine_change(iport, SCI_PORT_FAILED);
+	} else if (current_state == SCI_PORT_STOPPED) {
+		/* if the port is stopped then the start request failed In this
+		 * case stay in the stopped state.
+		 */
+		dev_err(sciport_to_dev(iport),
+			"%s: SCIC Port 0x%p failed to stop before tiemout.\n",
+			__func__,
+			iport);
+	} else if (current_state == SCI_PORT_STOPPING) {
+		/* if the port is still stopping then the stop has not completed */
+		isci_port_stop_complete(iport->owning_controller,
+					iport,
+					SCI_FAILURE_TIMEOUT);
+	} else {
+		/* The port is in the ready state and we have a timer
+		 * reporting a timeout this should not happen.
+		 */
+		dev_err(sciport_to_dev(iport),
+			"%s: SCIC Port 0x%p is processing a timeout operation "
+			"in state %d.\n", __func__, iport, current_state);
+	}
+
+done:
+	spin_unlock_irqrestore(&ihost->scic_lock, flags);
+}
+
+/* --------------------------------------------------------------------------- */
+
+/**
+ * This function updates the hardwares VIIT entry for this port.
+ *
+ *
+ */
+static void sci_port_update_viit_entry(struct isci_port *iport)
+{
+	struct sci_sas_address sas_address;
+
+	sci_port_get_sas_address(iport, &sas_address);
+
+	writel(sas_address.high,
+		&iport->viit_registers->initiator_sas_address_hi);
+	writel(sas_address.low,
+		&iport->viit_registers->initiator_sas_address_lo);
+
+	/* This value get cleared just in case its not already cleared */
+	writel(0, &iport->viit_registers->reserved);
+
+	/* We are required to update the status register last */
+	writel(SCU_VIIT_ENTRY_ID_VIIT |
+	       SCU_VIIT_IPPT_INITIATOR |
+	       ((1 << iport->physical_port_index) << SCU_VIIT_ENTRY_LPVIE_SHIFT) |
+	       SCU_VIIT_STATUS_ALL_VALID,
+	       &iport->viit_registers->status);
+}
+
+enum sas_linkrate sci_port_get_max_allowed_speed(struct isci_port *iport)
+{
+	u16 index;
+	struct isci_phy *iphy;
+	enum sas_linkrate max_allowed_speed = SAS_LINK_RATE_6_0_GBPS;
+
+	/*
+	 * Loop through all of the phys in this port and find the phy with the
+	 * lowest maximum link rate. */
+	for (index = 0; index < SCI_MAX_PHYS; index++) {
+		iphy = iport->phy_table[index];
+		if (iphy && sci_port_active_phy(iport, iphy) &&
+		    iphy->max_negotiated_speed < max_allowed_speed)
+			max_allowed_speed = iphy->max_negotiated_speed;
+	}
+
+	return max_allowed_speed;
+}
+
+static void sci_port_suspend_port_task_scheduler(struct isci_port *iport)
+{
+	u32 pts_control_value;
+
+	pts_control_value = readl(&iport->port_task_scheduler_registers->control);
+	pts_control_value |= SCU_PTSxCR_GEN_BIT(SUSPEND);
+	writel(pts_control_value, &iport->port_task_scheduler_registers->control);
+}
+
+/**
+ * sci_port_post_dummy_request() - post dummy/workaround request
+ * @sci_port: port to post task
+ *
+ * Prevent the hardware scheduler from posting new requests to the front
+ * of the scheduler queue causing a starvation problem for currently
+ * ongoing requests.
+ *
+ */
+static void sci_port_post_dummy_request(struct isci_port *iport)
+{
+	struct isci_host *ihost = iport->owning_controller;
+	u16 tag = iport->reserved_tag;
+	struct scu_task_context *tc;
+	u32 command;
+
+	tc = &ihost->task_context_table[ISCI_TAG_TCI(tag)];
+	tc->abort = 0;
+
+	command = SCU_CONTEXT_COMMAND_REQUEST_TYPE_POST_TC |
+		  iport->physical_port_index << SCU_CONTEXT_COMMAND_LOGICAL_PORT_SHIFT |
+		  ISCI_TAG_TCI(tag);
+
+	sci_controller_post_request(ihost, command);
+}
+
+/**
+ * This routine will abort the dummy request.  This will alow the hardware to
+ * power down parts of the silicon to save power.
+ *
+ * @sci_port: The port on which the task must be aborted.
+ *
+ */
+static void sci_port_abort_dummy_request(struct isci_port *iport)
+{
+	struct isci_host *ihost = iport->owning_controller;
+	u16 tag = iport->reserved_tag;
+	struct scu_task_context *tc;
+	u32 command;
+
+	tc = &ihost->task_context_table[ISCI_TAG_TCI(tag)];
+	tc->abort = 1;
+
+	command = SCU_CONTEXT_COMMAND_REQUEST_POST_TC_ABORT |
+		  iport->physical_port_index << SCU_CONTEXT_COMMAND_LOGICAL_PORT_SHIFT |
+		  ISCI_TAG_TCI(tag);
+
+	sci_controller_post_request(ihost, command);
+}
+
+/**
+ *
+ * @sci_port: This is the struct isci_port object to resume.
+ *
+ * This method will resume the port task scheduler for this port object. none
+ */
+static void
+sci_port_resume_port_task_scheduler(struct isci_port *iport)
+{
+	u32 pts_control_value;
+
+	pts_control_value = readl(&iport->port_task_scheduler_registers->control);
+	pts_control_value &= ~SCU_PTSxCR_GEN_BIT(SUSPEND);
+	writel(pts_control_value, &iport->port_task_scheduler_registers->control);
+}
+
+static void sci_port_ready_substate_waiting_enter(struct sci_base_state_machine *sm)
+{
+	struct isci_port *iport = container_of(sm, typeof(*iport), sm);
+
+	sci_port_suspend_port_task_scheduler(iport);
+
+	iport->not_ready_reason = SCIC_PORT_NOT_READY_NO_ACTIVE_PHYS;
+
+	if (iport->active_phy_mask != 0) {
+		/* At least one of the phys on the port is ready */
+		port_state_machine_change(iport,
+					  SCI_PORT_SUB_OPERATIONAL);
+	}
+}
+
+static void sci_port_ready_substate_operational_enter(struct sci_base_state_machine *sm)
+{
+	u32 index;
+	struct isci_port *iport = container_of(sm, typeof(*iport), sm);
+	struct isci_host *ihost = iport->owning_controller;
+
+	isci_port_ready(ihost, iport);
+
+	for (index = 0; index < SCI_MAX_PHYS; index++) {
+		if (iport->phy_table[index]) {
+			writel(iport->physical_port_index,
+				&iport->port_pe_configuration_register[
+					iport->phy_table[index]->phy_index]);
+		}
+	}
+
+	sci_port_update_viit_entry(iport);
+
+	sci_port_resume_port_task_scheduler(iport);
+
+	/*
+	 * Post the dummy task for the port so the hardware can schedule
+	 * io correctly
+	 */
+	sci_port_post_dummy_request(iport);
+}
+
+static void sci_port_invalidate_dummy_remote_node(struct isci_port *iport)
+{
+	struct isci_host *ihost = iport->owning_controller;
+	u8 phys_index = iport->physical_port_index;
+	union scu_remote_node_context *rnc;
+	u16 rni = iport->reserved_rni;
+	u32 command;
+
+	rnc = &ihost->remote_node_context_table[rni];
+
+	rnc->ssp.is_valid = false;
+
+	/* ensure the preceding tc abort request has reached the
+	 * controller and give it ample time to act before posting the rnc
+	 * invalidate
+	 */
+	readl(&ihost->smu_registers->interrupt_status); /* flush */
+	udelay(10);
+
+	command = SCU_CONTEXT_COMMAND_POST_RNC_INVALIDATE |
+		  phys_index << SCU_CONTEXT_COMMAND_LOGICAL_PORT_SHIFT | rni;
+
+	sci_controller_post_request(ihost, command);
+}
+
+/**
+ *
+ * @object: This is the object which is cast to a struct isci_port object.
+ *
+ * This method will perform the actions required by the struct isci_port on
+ * exiting the SCI_PORT_SUB_OPERATIONAL. This function reports
+ * the port not ready and suspends the port task scheduler. none
+ */
+static void sci_port_ready_substate_operational_exit(struct sci_base_state_machine *sm)
+{
+	struct isci_port *iport = container_of(sm, typeof(*iport), sm);
+	struct isci_host *ihost = iport->owning_controller;
+
+	/*
+	 * Kill the dummy task for this port if it has not yet posted
+	 * the hardware will treat this as a NOP and just return abort
+	 * complete.
+	 */
+	sci_port_abort_dummy_request(iport);
+
+	isci_port_not_ready(ihost, iport);
+
+	if (iport->ready_exit)
+		sci_port_invalidate_dummy_remote_node(iport);
+}
+
+static void sci_port_ready_substate_configuring_enter(struct sci_base_state_machine *sm)
+{
+	struct isci_port *iport = container_of(sm, typeof(*iport), sm);
+	struct isci_host *ihost = iport->owning_controller;
+
+	if (iport->active_phy_mask == 0) {
+		isci_port_not_ready(ihost, iport);
+
+		port_state_machine_change(iport,
+					  SCI_PORT_SUB_WAITING);
+	} else if (iport->started_request_count == 0)
+		port_state_machine_change(iport,
+					  SCI_PORT_SUB_OPERATIONAL);
+}
+
+static void sci_port_ready_substate_configuring_exit(struct sci_base_state_machine *sm)
+{
+	struct isci_port *iport = container_of(sm, typeof(*iport), sm);
+
+	sci_port_suspend_port_task_scheduler(iport);
+	if (iport->ready_exit)
+		sci_port_invalidate_dummy_remote_node(iport);
+}
+
+enum sci_status sci_port_start(struct isci_port *iport)
+{
+	struct isci_host *ihost = iport->owning_controller;
+	enum sci_status status = SCI_SUCCESS;
+	enum sci_port_states state;
+	u32 phy_mask;
+
+	state = iport->sm.current_state_id;
+	if (state != SCI_PORT_STOPPED) {
+		dev_warn(sciport_to_dev(iport),
+			 "%s: in wrong state: %d\n", __func__, state);
+		return SCI_FAILURE_INVALID_STATE;
+	}
+
+	if (iport->assigned_device_count > 0) {
+		/* TODO This is a start failure operation because
+		 * there are still devices assigned to this port.
+		 * There must be no devices assigned to a port on a
+		 * start operation.
+		 */
+		return SCI_FAILURE_UNSUPPORTED_PORT_CONFIGURATION;
+	}
+
+	if (iport->reserved_rni == SCU_DUMMY_INDEX) {
+		u16 rni = sci_remote_node_table_allocate_remote_node(
+				&ihost->available_remote_nodes, 1);
+
+		if (rni != SCU_DUMMY_INDEX)
+			sci_port_construct_dummy_rnc(iport, rni);
+		else
+			status = SCI_FAILURE_INSUFFICIENT_RESOURCES;
+		iport->reserved_rni = rni;
+	}
+
+	if (iport->reserved_tag == SCI_CONTROLLER_INVALID_IO_TAG) {
+		u16 tag;
+
+		tag = isci_alloc_tag(ihost);
+		if (tag == SCI_CONTROLLER_INVALID_IO_TAG)
+			status = SCI_FAILURE_INSUFFICIENT_RESOURCES;
+		else
+			sci_port_construct_dummy_task(iport, tag);
+		iport->reserved_tag = tag;
+	}
+
+	if (status == SCI_SUCCESS) {
+		phy_mask = sci_port_get_phys(iport);
+
+		/*
+		 * There are one or more phys assigned to this port.  Make sure
+		 * the port's phy mask is in fact legal and supported by the
+		 * silicon.
+		 */
+		if (sci_port_is_phy_mask_valid(iport, phy_mask) == true) {
+			port_state_machine_change(iport,
+						  SCI_PORT_READY);
+
+			return SCI_SUCCESS;
+		}
+		status = SCI_FAILURE;
+	}
+
+	if (status != SCI_SUCCESS)
+		sci_port_destroy_dummy_resources(iport);
+
+	return status;
+}
+
+enum sci_status sci_port_stop(struct isci_port *iport)
+{
+	enum sci_port_states state;
+
+	state = iport->sm.current_state_id;
+	switch (state) {
+	case SCI_PORT_STOPPED:
+		return SCI_SUCCESS;
+	case SCI_PORT_SUB_WAITING:
+	case SCI_PORT_SUB_OPERATIONAL:
+	case SCI_PORT_SUB_CONFIGURING:
+	case SCI_PORT_RESETTING:
+		port_state_machine_change(iport,
+					  SCI_PORT_STOPPING);
+		return SCI_SUCCESS;
+	default:
+		dev_warn(sciport_to_dev(iport),
+			 "%s: in wrong state: %d\n", __func__, state);
+		return SCI_FAILURE_INVALID_STATE;
+	}
+}
+
+static enum sci_status sci_port_hard_reset(struct isci_port *iport, u32 timeout)
+{
+	enum sci_status status = SCI_FAILURE_INVALID_PHY;
+	struct isci_phy *iphy = NULL;
+	enum sci_port_states state;
+	u32 phy_index;
+
+	state = iport->sm.current_state_id;
+	if (state != SCI_PORT_SUB_OPERATIONAL) {
+		dev_warn(sciport_to_dev(iport),
+			 "%s: in wrong state: %d\n", __func__, state);
+		return SCI_FAILURE_INVALID_STATE;
+	}
+
+	/* Select a phy on which we can send the hard reset request. */
+	for (phy_index = 0; phy_index < SCI_MAX_PHYS && !iphy; phy_index++) {
+		iphy = iport->phy_table[phy_index];
+		if (iphy && !sci_port_active_phy(iport, iphy)) {
+			/*
+			 * We found a phy but it is not ready select
+			 * different phy
+			 */
+			iphy = NULL;
+		}
+	}
+
+	/* If we have a phy then go ahead and start the reset procedure */
+	if (!iphy)
+		return status;
+	status = sci_phy_reset(iphy);
+
+	if (status != SCI_SUCCESS)
+		return status;
+
+	sci_mod_timer(&iport->timer, timeout);
+	iport->not_ready_reason = SCIC_PORT_NOT_READY_HARD_RESET_REQUESTED;
+
+	port_state_machine_change(iport, SCI_PORT_RESETTING);
+	return SCI_SUCCESS;
+}
+
+/**
+ * sci_port_add_phy() -
+ * @sci_port: This parameter specifies the port in which the phy will be added.
+ * @sci_phy: This parameter is the phy which is to be added to the port.
+ *
+ * This method will add a PHY to the selected port. This method returns an
+ * enum sci_status. SCI_SUCCESS the phy has been added to the port. Any other
+ * status is a failure to add the phy to the port.
+ */
+enum sci_status sci_port_add_phy(struct isci_port *iport,
+				      struct isci_phy *iphy)
+{
+	enum sci_status status;
+	enum sci_port_states state;
+
+	state = iport->sm.current_state_id;
+	switch (state) {
+	case SCI_PORT_STOPPED: {
+		struct sci_sas_address port_sas_address;
+
+		/* Read the port assigned SAS Address if there is one */
+		sci_port_get_sas_address(iport, &port_sas_address);
+
+		if (port_sas_address.high != 0 && port_sas_address.low != 0) {
+			struct sci_sas_address phy_sas_address;
+
+			/* Make sure that the PHY SAS Address matches the SAS Address
+			 * for this port
+			 */
+			sci_phy_get_sas_address(iphy, &phy_sas_address);
+
+			if (port_sas_address.high != phy_sas_address.high ||
+			    port_sas_address.low  != phy_sas_address.low)
+				return SCI_FAILURE_UNSUPPORTED_PORT_CONFIGURATION;
+		}
+		return sci_port_set_phy(iport, iphy);
+	}
+	case SCI_PORT_SUB_WAITING:
+	case SCI_PORT_SUB_OPERATIONAL:
+		status = sci_port_set_phy(iport, iphy);
+
+		if (status != SCI_SUCCESS)
+			return status;
+
+		sci_port_general_link_up_handler(iport, iphy, true);
+		iport->not_ready_reason = SCIC_PORT_NOT_READY_RECONFIGURING;
+		port_state_machine_change(iport, SCI_PORT_SUB_CONFIGURING);
+
+		return status;
+	case SCI_PORT_SUB_CONFIGURING:
+		status = sci_port_set_phy(iport, iphy);
+
+		if (status != SCI_SUCCESS)
+			return status;
+		sci_port_general_link_up_handler(iport, iphy, true);
+
+		/* Re-enter the configuring state since this may be the last phy in
+		 * the port.
+		 */
+		port_state_machine_change(iport,
+					  SCI_PORT_SUB_CONFIGURING);
+		return SCI_SUCCESS;
+	default:
+		dev_warn(sciport_to_dev(iport),
+			 "%s: in wrong state: %d\n", __func__, state);
+		return SCI_FAILURE_INVALID_STATE;
+	}
+}
+
+/**
+ * sci_port_remove_phy() -
+ * @sci_port: This parameter specifies the port in which the phy will be added.
+ * @sci_phy: This parameter is the phy which is to be added to the port.
+ *
+ * This method will remove the PHY from the selected PORT. This method returns
+ * an enum sci_status. SCI_SUCCESS the phy has been removed from the port. Any
+ * other status is a failure to add the phy to the port.
+ */
+enum sci_status sci_port_remove_phy(struct isci_port *iport,
+					 struct isci_phy *iphy)
+{
+	enum sci_status status;
+	enum sci_port_states state;
+
+	state = iport->sm.current_state_id;
+
+	switch (state) {
+	case SCI_PORT_STOPPED:
+		return sci_port_clear_phy(iport, iphy);
+	case SCI_PORT_SUB_OPERATIONAL:
+		status = sci_port_clear_phy(iport, iphy);
+		if (status != SCI_SUCCESS)
+			return status;
+
+		sci_port_deactivate_phy(iport, iphy, true);
+		iport->not_ready_reason = SCIC_PORT_NOT_READY_RECONFIGURING;
+		port_state_machine_change(iport,
+					  SCI_PORT_SUB_CONFIGURING);
+		return SCI_SUCCESS;
+	case SCI_PORT_SUB_CONFIGURING:
+		status = sci_port_clear_phy(iport, iphy);
+
+		if (status != SCI_SUCCESS)
+			return status;
+		sci_port_deactivate_phy(iport, iphy, true);
+
+		/* Re-enter the configuring state since this may be the last phy in
+		 * the port
+		 */
+		port_state_machine_change(iport,
+					  SCI_PORT_SUB_CONFIGURING);
+		return SCI_SUCCESS;
+	default:
+		dev_warn(sciport_to_dev(iport),
+			 "%s: in wrong state: %d\n", __func__, state);
+		return SCI_FAILURE_INVALID_STATE;
+	}
+}
+
+enum sci_status sci_port_link_up(struct isci_port *iport,
+				      struct isci_phy *iphy)
+{
+	enum sci_port_states state;
+
+	state = iport->sm.current_state_id;
+	switch (state) {
+	case SCI_PORT_SUB_WAITING:
+		/* Since this is the first phy going link up for the port we
+		 * can just enable it and continue
+		 */
+		sci_port_activate_phy(iport, iphy, true);
+
+		port_state_machine_change(iport,
+					  SCI_PORT_SUB_OPERATIONAL);
+		return SCI_SUCCESS;
+	case SCI_PORT_SUB_OPERATIONAL:
+		sci_port_general_link_up_handler(iport, iphy, true);
+		return SCI_SUCCESS;
+	case SCI_PORT_RESETTING:
+		/* TODO We should  make  sure  that  the phy  that  has gone
+		 * link up is the same one on which we sent the reset.  It is
+		 * possible that the phy on which we sent  the reset is not the
+		 * one that has  gone  link up  and we  want to make sure that
+		 * phy being reset  comes  back.  Consider the case where a
+		 * reset is sent but before the hardware processes the reset it
+		 * get a link up on  the  port because of a hot plug event.
+		 * because  of  the reset request this phy will go link down
+		 * almost immediately.
+		 */
+
+		/* In the resetting state we don't notify the user regarding
+		 * link up and link down notifications.
+		 */
+		sci_port_general_link_up_handler(iport, iphy, false);
+		return SCI_SUCCESS;
+	default:
+		dev_warn(sciport_to_dev(iport),
+			 "%s: in wrong state: %d\n", __func__, state);
+		return SCI_FAILURE_INVALID_STATE;
+	}
+}
+
+enum sci_status sci_port_link_down(struct isci_port *iport,
+					struct isci_phy *iphy)
+{
+	enum sci_port_states state;
+
+	state = iport->sm.current_state_id;
+	switch (state) {
+	case SCI_PORT_SUB_OPERATIONAL:
+		sci_port_deactivate_phy(iport, iphy, true);
+
+		/* If there are no active phys left in the port, then
+		 * transition the port to the WAITING state until such time
+		 * as a phy goes link up
+		 */
+		if (iport->active_phy_mask == 0)
+			port_state_machine_change(iport,
+						  SCI_PORT_SUB_WAITING);
+		return SCI_SUCCESS;
+	case SCI_PORT_RESETTING:
+		/* In the resetting state we don't notify the user regarding
+		 * link up and link down notifications. */
+		sci_port_deactivate_phy(iport, iphy, false);
+		return SCI_SUCCESS;
+	default:
+		dev_warn(sciport_to_dev(iport),
+			 "%s: in wrong state: %d\n", __func__, state);
+		return SCI_FAILURE_INVALID_STATE;
+	}
+}
+
+enum sci_status sci_port_start_io(struct isci_port *iport,
+				  struct isci_remote_device *idev,
+				  struct isci_request *ireq)
+{
+	enum sci_port_states state;
+
+	state = iport->sm.current_state_id;
+	switch (state) {
+	case SCI_PORT_SUB_WAITING:
+		return SCI_FAILURE_INVALID_STATE;
+	case SCI_PORT_SUB_OPERATIONAL:
+		iport->started_request_count++;
+		return SCI_SUCCESS;
+	default:
+		dev_warn(sciport_to_dev(iport),
+			 "%s: in wrong state: %d\n", __func__, state);
+		return SCI_FAILURE_INVALID_STATE;
+	}
+}
+
+enum sci_status sci_port_complete_io(struct isci_port *iport,
+				     struct isci_remote_device *idev,
+				     struct isci_request *ireq)
+{
+	enum sci_port_states state;
+
+	state = iport->sm.current_state_id;
+	switch (state) {
+	case SCI_PORT_STOPPED:
+		dev_warn(sciport_to_dev(iport),
+			 "%s: in wrong state: %d\n", __func__, state);
+		return SCI_FAILURE_INVALID_STATE;
+	case SCI_PORT_STOPPING:
+		sci_port_decrement_request_count(iport);
+
+		if (iport->started_request_count == 0)
+			port_state_machine_change(iport,
+						  SCI_PORT_STOPPED);
+		break;
+	case SCI_PORT_READY:
+	case SCI_PORT_RESETTING:
+	case SCI_PORT_FAILED:
+	case SCI_PORT_SUB_WAITING:
+	case SCI_PORT_SUB_OPERATIONAL:
+		sci_port_decrement_request_count(iport);
+		break;
+	case SCI_PORT_SUB_CONFIGURING:
+		sci_port_decrement_request_count(iport);
+		if (iport->started_request_count == 0) {
+			port_state_machine_change(iport,
+						  SCI_PORT_SUB_OPERATIONAL);
+		}
+		break;
+	}
+	return SCI_SUCCESS;
+}
+
+static void sci_port_enable_port_task_scheduler(struct isci_port *iport)
+{
+	u32 pts_control_value;
+
+	 /* enable the port task scheduler in a suspended state */
+	pts_control_value = readl(&iport->port_task_scheduler_registers->control);
+	pts_control_value |= SCU_PTSxCR_GEN_BIT(ENABLE) | SCU_PTSxCR_GEN_BIT(SUSPEND);
+	writel(pts_control_value, &iport->port_task_scheduler_registers->control);
+}
+
+static void sci_port_disable_port_task_scheduler(struct isci_port *iport)
+{
+	u32 pts_control_value;
+
+	pts_control_value = readl(&iport->port_task_scheduler_registers->control);
+	pts_control_value &=
+		~(SCU_PTSxCR_GEN_BIT(ENABLE) | SCU_PTSxCR_GEN_BIT(SUSPEND));
+	writel(pts_control_value, &iport->port_task_scheduler_registers->control);
+}
+
+static void sci_port_post_dummy_remote_node(struct isci_port *iport)
+{
+	struct isci_host *ihost = iport->owning_controller;
+	u8 phys_index = iport->physical_port_index;
+	union scu_remote_node_context *rnc;
+	u16 rni = iport->reserved_rni;
+	u32 command;
+
+	rnc = &ihost->remote_node_context_table[rni];
+	rnc->ssp.is_valid = true;
+
+	command = SCU_CONTEXT_COMMAND_POST_RNC_32 |
+		  phys_index << SCU_CONTEXT_COMMAND_LOGICAL_PORT_SHIFT | rni;
+
+	sci_controller_post_request(ihost, command);
+
+	/* ensure hardware has seen the post rnc command and give it
+	 * ample time to act before sending the suspend
+	 */
+	readl(&ihost->smu_registers->interrupt_status); /* flush */
+	udelay(10);
+
+	command = SCU_CONTEXT_COMMAND_POST_RNC_SUSPEND_TX_RX |
+		  phys_index << SCU_CONTEXT_COMMAND_LOGICAL_PORT_SHIFT | rni;
+
+	sci_controller_post_request(ihost, command);
+}
+
+static void sci_port_stopped_state_enter(struct sci_base_state_machine *sm)
+{
+	struct isci_port *iport = container_of(sm, typeof(*iport), sm);
+
+	if (iport->sm.previous_state_id == SCI_PORT_STOPPING) {
+		/*
+		 * If we enter this state becasuse of a request to stop
+		 * the port then we want to disable the hardwares port
+		 * task scheduler. */
+		sci_port_disable_port_task_scheduler(iport);
+	}
+}
+
+static void sci_port_stopped_state_exit(struct sci_base_state_machine *sm)
+{
+	struct isci_port *iport = container_of(sm, typeof(*iport), sm);
+
+	/* Enable and suspend the port task scheduler */
+	sci_port_enable_port_task_scheduler(iport);
+}
+
+static void sci_port_ready_state_enter(struct sci_base_state_machine *sm)
+{
+	struct isci_port *iport = container_of(sm, typeof(*iport), sm);
+	struct isci_host *ihost = iport->owning_controller;
+	u32 prev_state;
+
+	prev_state = iport->sm.previous_state_id;
+	if (prev_state  == SCI_PORT_RESETTING)
+		isci_port_hard_reset_complete(iport, SCI_SUCCESS);
+	else
+		isci_port_not_ready(ihost, iport);
+
+	/* Post and suspend the dummy remote node context for this port. */
+	sci_port_post_dummy_remote_node(iport);
+
+	/* Start the ready substate machine */
+	port_state_machine_change(iport,
+				  SCI_PORT_SUB_WAITING);
+}
+
+static void sci_port_resetting_state_exit(struct sci_base_state_machine *sm)
+{
+	struct isci_port *iport = container_of(sm, typeof(*iport), sm);
+
+	sci_del_timer(&iport->timer);
+}
+
+static void sci_port_stopping_state_exit(struct sci_base_state_machine *sm)
+{
+	struct isci_port *iport = container_of(sm, typeof(*iport), sm);
+
+	sci_del_timer(&iport->timer);
+
+	sci_port_destroy_dummy_resources(iport);
+}
+
+static void sci_port_failed_state_enter(struct sci_base_state_machine *sm)
+{
+	struct isci_port *iport = container_of(sm, typeof(*iport), sm);
+
+	isci_port_hard_reset_complete(iport, SCI_FAILURE_TIMEOUT);
+}
+
+/* --------------------------------------------------------------------------- */
+
+static const struct sci_base_state sci_port_state_table[] = {
+	[SCI_PORT_STOPPED] = {
+		.enter_state = sci_port_stopped_state_enter,
+		.exit_state  = sci_port_stopped_state_exit
+	},
+	[SCI_PORT_STOPPING] = {
+		.exit_state  = sci_port_stopping_state_exit
+	},
+	[SCI_PORT_READY] = {
+		.enter_state = sci_port_ready_state_enter,
+	},
+	[SCI_PORT_SUB_WAITING] = {
+		.enter_state = sci_port_ready_substate_waiting_enter,
+	},
+	[SCI_PORT_SUB_OPERATIONAL] = {
+		.enter_state = sci_port_ready_substate_operational_enter,
+		.exit_state  = sci_port_ready_substate_operational_exit
+	},
+	[SCI_PORT_SUB_CONFIGURING] = {
+		.enter_state = sci_port_ready_substate_configuring_enter,
+		.exit_state  = sci_port_ready_substate_configuring_exit
+	},
+	[SCI_PORT_RESETTING] = {
+		.exit_state  = sci_port_resetting_state_exit
+	},
+	[SCI_PORT_FAILED] = {
+		.enter_state = sci_port_failed_state_enter,
+	}
+};
+
+void sci_port_construct(struct isci_port *iport, u8 index,
+			     struct isci_host *ihost)
+{
+	sci_init_sm(&iport->sm, sci_port_state_table, SCI_PORT_STOPPED);
+
+	iport->logical_port_index  = SCIC_SDS_DUMMY_PORT;
+	iport->physical_port_index = index;
+	iport->active_phy_mask     = 0;
+	iport->ready_exit	      = false;
+
+	iport->owning_controller = ihost;
+
+	iport->started_request_count = 0;
+	iport->assigned_device_count = 0;
+
+	iport->reserved_rni = SCU_DUMMY_INDEX;
+	iport->reserved_tag = SCI_CONTROLLER_INVALID_IO_TAG;
+
+	sci_init_timer(&iport->timer, port_timeout);
+
+	iport->port_task_scheduler_registers = NULL;
+
+	for (index = 0; index < SCI_MAX_PHYS; index++)
+		iport->phy_table[index] = NULL;
+}
+
+void isci_port_init(struct isci_port *iport, struct isci_host *ihost, int index)
+{
+	INIT_LIST_HEAD(&iport->remote_dev_list);
+	INIT_LIST_HEAD(&iport->domain_dev_list);
+	spin_lock_init(&iport->state_lock);
+	init_completion(&iport->start_complete);
+	iport->isci_host = ihost;
+	isci_port_change_state(iport, isci_freed);
+	atomic_set(&iport->event, 0);
+}
+
+/**
+ * isci_port_get_state() - This function gets the status of the port object.
+ * @isci_port: This parameter points to the isci_port object
+ *
+ * status of the object as a isci_status enum.
+ */
+enum isci_status isci_port_get_state(
+	struct isci_port *isci_port)
+{
+	return isci_port->status;
+}
+
+void sci_port_broadcast_change_received(struct isci_port *iport, struct isci_phy *iphy)
+{
+	struct isci_host *ihost = iport->owning_controller;
+
+	/* notify the user. */
+	isci_port_bc_change_received(ihost, iport, iphy);
+}
+
+int isci_port_perform_hard_reset(struct isci_host *ihost, struct isci_port *iport,
+				 struct isci_phy *iphy)
+{
+	unsigned long flags;
+	enum sci_status status;
+	int idx, ret = TMF_RESP_FUNC_COMPLETE;
+
+	dev_dbg(&ihost->pdev->dev, "%s: iport = %p\n",
+		__func__, iport);
+
+	init_completion(&iport->hard_reset_complete);
+
+	spin_lock_irqsave(&ihost->scic_lock, flags);
+
+	#define ISCI_PORT_RESET_TIMEOUT SCIC_SDS_SIGNATURE_FIS_TIMEOUT
+	status = sci_port_hard_reset(iport, ISCI_PORT_RESET_TIMEOUT);
+
+	spin_unlock_irqrestore(&ihost->scic_lock, flags);
+
+	if (status == SCI_SUCCESS) {
+		wait_for_completion(&iport->hard_reset_complete);
+
+		dev_dbg(&ihost->pdev->dev,
+			"%s: iport = %p; hard reset completion\n",
+			__func__, iport);
+
+		if (iport->hard_reset_status != SCI_SUCCESS)
+			ret = TMF_RESP_FUNC_FAILED;
+	} else {
+		ret = TMF_RESP_FUNC_FAILED;
+
+		dev_err(&ihost->pdev->dev,
+			"%s: iport = %p; sci_port_hard_reset call"
+			" failed 0x%x\n",
+			__func__, iport, status);
+
+	}
+
+	/* If the hard reset for the port has failed, consider this
+	 * the same as link failures on all phys in the port.
+	 */
+	if (ret != TMF_RESP_FUNC_COMPLETE) {
+
+		dev_err(&ihost->pdev->dev,
+			"%s: iport = %p; hard reset failed "
+			"(0x%x) - driving explicit link fail for all phys\n",
+			__func__, iport, iport->hard_reset_status);
+
+		/* Down all phys in the port. */
+		spin_lock_irqsave(&ihost->scic_lock, flags);
+		for (idx = 0; idx < SCI_MAX_PHYS; ++idx) {
+			struct isci_phy *iphy = iport->phy_table[idx];
+
+			if (!iphy)
+				continue;
+			sci_phy_stop(iphy);
+			sci_phy_start(iphy);
+		}
+		spin_unlock_irqrestore(&ihost->scic_lock, flags);
+	}
+	return ret;
+}
+
+/**
+ * isci_port_deformed() - This function is called by libsas when a port becomes
+ *    inactive.
+ * @phy: This parameter specifies the libsas phy with the inactive port.
+ *
+ */
+void isci_port_deformed(struct asd_sas_phy *phy)
+{
+	pr_debug("%s: sas_phy = %p\n", __func__, phy);
+}
+
+/**
+ * isci_port_formed() - This function is called by libsas when a port becomes
+ *    active.
+ * @phy: This parameter specifies the libsas phy with the active port.
+ *
+ */
+void isci_port_formed(struct asd_sas_phy *phy)
+{
+	pr_debug("%s: sas_phy = %p, sas_port = %p\n", __func__, phy, phy->port);
+}
diff -druN linux-2.6.39-libre/drivers/scsi/isci/port_config.c linux-3.0-rc7-libre/drivers/scsi/isci/port_config.c
--- linux-2.6.39-libre/drivers/scsi/isci/port_config.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/scsi/isci/port_config.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,754 @@
+/*
+ * This file is provided under a dual BSD/GPLv2 license.  When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * The full GNU General Public License is included in this distribution
+ * in the file called LICENSE.GPL.
+ *
+ * BSD LICENSE
+ *
+ * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in
+ *     the documentation and/or other materials provided with the
+ *     distribution.
+ *   * Neither the name of Intel Corporation nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "host.h"
+
+#define SCIC_SDS_MPC_RECONFIGURATION_TIMEOUT    (10)
+#define SCIC_SDS_APC_RECONFIGURATION_TIMEOUT    (10)
+#define SCIC_SDS_APC_WAIT_LINK_UP_NOTIFICATION  (100)
+
+enum SCIC_SDS_APC_ACTIVITY {
+	SCIC_SDS_APC_SKIP_PHY,
+	SCIC_SDS_APC_ADD_PHY,
+	SCIC_SDS_APC_START_TIMER,
+
+	SCIC_SDS_APC_ACTIVITY_MAX
+};
+
+/*
+ * ******************************************************************************
+ * General port configuration agent routines
+ * ****************************************************************************** */
+
+/**
+ *
+ * @address_one: A SAS Address to be compared.
+ * @address_two: A SAS Address to be compared.
+ *
+ * Compare the two SAS Address and if SAS Address One is greater than SAS
+ * Address Two then return > 0 else if SAS Address One is less than SAS Address
+ * Two return < 0 Otherwise they are the same return 0 A signed value of x > 0
+ * > y where x is returned for Address One > Address Two y is returned for
+ * Address One < Address Two 0 is returned ofr Address One = Address Two
+ */
+static s32 sci_sas_address_compare(
+	struct sci_sas_address address_one,
+	struct sci_sas_address address_two)
+{
+	if (address_one.high > address_two.high) {
+		return 1;
+	} else if (address_one.high < address_two.high) {
+		return -1;
+	} else if (address_one.low > address_two.low) {
+		return 1;
+	} else if (address_one.low < address_two.low) {
+		return -1;
+	}
+
+	/* The two SAS Address must be identical */
+	return 0;
+}
+
+/**
+ *
+ * @controller: The controller object used for the port search.
+ * @phy: The phy object to match.
+ *
+ * This routine will find a matching port for the phy.  This means that the
+ * port and phy both have the same broadcast sas address and same received sas
+ * address. The port address or the NULL if there is no matching
+ * port. port address if the port can be found to match the phy.
+ * NULL if there is no matching port for the phy.
+ */
+static struct isci_port *sci_port_configuration_agent_find_port(
+	struct isci_host *ihost,
+	struct isci_phy *iphy)
+{
+	u8 i;
+	struct sci_sas_address port_sas_address;
+	struct sci_sas_address port_attached_device_address;
+	struct sci_sas_address phy_sas_address;
+	struct sci_sas_address phy_attached_device_address;
+
+	/*
+	 * Since this phy can be a member of a wide port check to see if one or
+	 * more phys match the sent and received SAS address as this phy in which
+	 * case it should participate in the same port.
+	 */
+	sci_phy_get_sas_address(iphy, &phy_sas_address);
+	sci_phy_get_attached_sas_address(iphy, &phy_attached_device_address);
+
+	for (i = 0; i < ihost->logical_port_entries; i++) {
+		struct isci_port *iport = &ihost->ports[i];
+
+		sci_port_get_sas_address(iport, &port_sas_address);
+		sci_port_get_attached_sas_address(iport, &port_attached_device_address);
+
+		if (sci_sas_address_compare(port_sas_address, phy_sas_address) == 0 &&
+		    sci_sas_address_compare(port_attached_device_address, phy_attached_device_address) == 0)
+			return iport;
+	}
+
+	return NULL;
+}
+
+/**
+ *
+ * @controller: This is the controller object that contains the port agent
+ * @port_agent: This is the port configruation agent for the controller.
+ *
+ * This routine will validate the port configuration is correct for the SCU
+ * hardware.  The SCU hardware allows for port configurations as follows. LP0
+ * -> (PE0), (PE0, PE1), (PE0, PE1, PE2, PE3) LP1 -> (PE1) LP2 -> (PE2), (PE2,
+ * PE3) LP3 -> (PE3) enum sci_status SCI_SUCCESS the port configuration is valid for
+ * this port configuration agent. SCI_FAILURE_UNSUPPORTED_PORT_CONFIGURATION
+ * the port configuration is not valid for this port configuration agent.
+ */
+static enum sci_status sci_port_configuration_agent_validate_ports(
+	struct isci_host *ihost,
+	struct sci_port_configuration_agent *port_agent)
+{
+	struct sci_sas_address first_address;
+	struct sci_sas_address second_address;
+
+	/*
+	 * Sanity check the max ranges for all the phys the max index
+	 * is always equal to the port range index */
+	if (port_agent->phy_valid_port_range[0].max_index != 0 ||
+	    port_agent->phy_valid_port_range[1].max_index != 1 ||
+	    port_agent->phy_valid_port_range[2].max_index != 2 ||
+	    port_agent->phy_valid_port_range[3].max_index != 3)
+		return SCI_FAILURE_UNSUPPORTED_PORT_CONFIGURATION;
+
+	/*
+	 * This is a request to configure a single x4 port or at least attempt
+	 * to make all the phys into a single port */
+	if (port_agent->phy_valid_port_range[0].min_index == 0 &&
+	    port_agent->phy_valid_port_range[1].min_index == 0 &&
+	    port_agent->phy_valid_port_range[2].min_index == 0 &&
+	    port_agent->phy_valid_port_range[3].min_index == 0)
+		return SCI_SUCCESS;
+
+	/*
+	 * This is a degenerate case where phy 1 and phy 2 are assigned
+	 * to the same port this is explicitly disallowed by the hardware
+	 * unless they are part of the same x4 port and this condition was
+	 * already checked above. */
+	if (port_agent->phy_valid_port_range[2].min_index == 1) {
+		return SCI_FAILURE_UNSUPPORTED_PORT_CONFIGURATION;
+	}
+
+	/*
+	 * PE0 and PE3 can never have the same SAS Address unless they
+	 * are part of the same x4 wide port and we have already checked
+	 * for this condition. */
+	sci_phy_get_sas_address(&ihost->phys[0], &first_address);
+	sci_phy_get_sas_address(&ihost->phys[3], &second_address);
+
+	if (sci_sas_address_compare(first_address, second_address) == 0) {
+		return SCI_FAILURE_UNSUPPORTED_PORT_CONFIGURATION;
+	}
+
+	/*
+	 * PE0 and PE1 are configured into a 2x1 ports make sure that the
+	 * SAS Address for PE0 and PE2 are different since they can not be
+	 * part of the same port. */
+	if (port_agent->phy_valid_port_range[0].min_index == 0 &&
+	    port_agent->phy_valid_port_range[1].min_index == 1) {
+		sci_phy_get_sas_address(&ihost->phys[0], &first_address);
+		sci_phy_get_sas_address(&ihost->phys[2], &second_address);
+
+		if (sci_sas_address_compare(first_address, second_address) == 0) {
+			return SCI_FAILURE_UNSUPPORTED_PORT_CONFIGURATION;
+		}
+	}
+
+	/*
+	 * PE2 and PE3 are configured into a 2x1 ports make sure that the
+	 * SAS Address for PE1 and PE3 are different since they can not be
+	 * part of the same port. */
+	if (port_agent->phy_valid_port_range[2].min_index == 2 &&
+	    port_agent->phy_valid_port_range[3].min_index == 3) {
+		sci_phy_get_sas_address(&ihost->phys[1], &first_address);
+		sci_phy_get_sas_address(&ihost->phys[3], &second_address);
+
+		if (sci_sas_address_compare(first_address, second_address) == 0) {
+			return SCI_FAILURE_UNSUPPORTED_PORT_CONFIGURATION;
+		}
+	}
+
+	return SCI_SUCCESS;
+}
+
+/*
+ * ******************************************************************************
+ * Manual port configuration agent routines
+ * ****************************************************************************** */
+
+/* verify all of the phys in the same port are using the same SAS address */
+static enum sci_status
+sci_mpc_agent_validate_phy_configuration(struct isci_host *ihost,
+					      struct sci_port_configuration_agent *port_agent)
+{
+	u32 phy_mask;
+	u32 assigned_phy_mask;
+	struct sci_sas_address sas_address;
+	struct sci_sas_address phy_assigned_address;
+	u8 port_index;
+	u8 phy_index;
+
+	assigned_phy_mask = 0;
+	sas_address.high = 0;
+	sas_address.low = 0;
+
+	for (port_index = 0; port_index < SCI_MAX_PORTS; port_index++) {
+		phy_mask = ihost->oem_parameters.ports[port_index].phy_mask;
+
+		if (!phy_mask)
+			continue;
+		/*
+		 * Make sure that one or more of the phys were not already assinged to
+		 * a different port. */
+		if ((phy_mask & ~assigned_phy_mask) == 0) {
+			return SCI_FAILURE_UNSUPPORTED_PORT_CONFIGURATION;
+		}
+
+		/* Find the starting phy index for this round through the loop */
+		for (phy_index = 0; phy_index < SCI_MAX_PHYS; phy_index++) {
+			if ((phy_mask & (1 << phy_index)) == 0)
+				continue;
+			sci_phy_get_sas_address(&ihost->phys[phy_index],
+						     &sas_address);
+
+			/*
+			 * The phy_index can be used as the starting point for the
+			 * port range since the hardware starts all logical ports
+			 * the same as the PE index. */
+			port_agent->phy_valid_port_range[phy_index].min_index = port_index;
+			port_agent->phy_valid_port_range[phy_index].max_index = phy_index;
+
+			if (phy_index != port_index) {
+				return SCI_FAILURE_UNSUPPORTED_PORT_CONFIGURATION;
+			}
+
+			break;
+		}
+
+		/*
+		 * See how many additional phys are being added to this logical port.
+		 * Note: We have not moved the current phy_index so we will actually
+		 *       compare the startting phy with itself.
+		 *       This is expected and required to add the phy to the port. */
+		while (phy_index < SCI_MAX_PHYS) {
+			if ((phy_mask & (1 << phy_index)) == 0)
+				continue;
+			sci_phy_get_sas_address(&ihost->phys[phy_index],
+						     &phy_assigned_address);
+
+			if (sci_sas_address_compare(sas_address, phy_assigned_address) != 0) {
+				/*
+				 * The phy mask specified that this phy is part of the same port
+				 * as the starting phy and it is not so fail this configuration */
+				return SCI_FAILURE_UNSUPPORTED_PORT_CONFIGURATION;
+			}
+
+			port_agent->phy_valid_port_range[phy_index].min_index = port_index;
+			port_agent->phy_valid_port_range[phy_index].max_index = phy_index;
+
+			sci_port_add_phy(&ihost->ports[port_index],
+					      &ihost->phys[phy_index]);
+
+			assigned_phy_mask |= (1 << phy_index);
+		}
+
+		phy_index++;
+	}
+
+	return sci_port_configuration_agent_validate_ports(ihost, port_agent);
+}
+
+static void mpc_agent_timeout(unsigned long data)
+{
+	u8 index;
+	struct sci_timer *tmr = (struct sci_timer *)data;
+	struct sci_port_configuration_agent *port_agent;
+	struct isci_host *ihost;
+	unsigned long flags;
+	u16 configure_phy_mask;
+
+	port_agent = container_of(tmr, typeof(*port_agent), timer);
+	ihost = container_of(port_agent, typeof(*ihost), port_agent);
+
+	spin_lock_irqsave(&ihost->scic_lock, flags);
+
+	if (tmr->cancel)
+		goto done;
+
+	port_agent->timer_pending = false;
+
+	/* Find the mask of phys that are reported read but as yet unconfigured into a port */
+	configure_phy_mask = ~port_agent->phy_configured_mask & port_agent->phy_ready_mask;
+
+	for (index = 0; index < SCI_MAX_PHYS; index++) {
+		struct isci_phy *iphy = &ihost->phys[index];
+
+		if (configure_phy_mask & (1 << index)) {
+			port_agent->link_up_handler(ihost, port_agent,
+						    phy_get_non_dummy_port(iphy),
+						    iphy);
+		}
+	}
+
+done:
+	spin_unlock_irqrestore(&ihost->scic_lock, flags);
+}
+
+static void sci_mpc_agent_link_up(struct isci_host *ihost,
+				       struct sci_port_configuration_agent *port_agent,
+				       struct isci_port *iport,
+				       struct isci_phy *iphy)
+{
+	/* If the port is NULL then the phy was not assigned to a port.
+	 * This is because the phy was not given the same SAS Address as
+	 * the other PHYs in the port.
+	 */
+	if (!iport)
+		return;
+
+	port_agent->phy_ready_mask |= (1 << iphy->phy_index);
+	sci_port_link_up(iport, iphy);
+	if ((iport->active_phy_mask & (1 << iphy->phy_index)))
+		port_agent->phy_configured_mask |= (1 << iphy->phy_index);
+}
+
+/**
+ *
+ * @controller: This is the controller object that receives the link down
+ *    notification.
+ * @port: This is the port object associated with the phy.  If the is no
+ *    associated port this is an NULL.  The port is an invalid
+ *    handle only if the phy was never port of this port.  This happens when
+ *    the phy is not broadcasting the same SAS address as the other phys in the
+ *    assigned port.
+ * @phy: This is the phy object which has gone link down.
+ *
+ * This function handles the manual port configuration link down notifications.
+ * Since all ports and phys are associated at initialization time we just turn
+ * around and notifiy the port object of the link down event.  If this PHY is
+ * not associated with a port there is no action taken. Is it possible to get a
+ * link down notification from a phy that has no assocoated port?
+ */
+static void sci_mpc_agent_link_down(
+	struct isci_host *ihost,
+	struct sci_port_configuration_agent *port_agent,
+	struct isci_port *iport,
+	struct isci_phy *iphy)
+{
+	if (iport != NULL) {
+		/*
+		 * If we can form a new port from the remainder of the phys
+		 * then we want to start the timer to allow the SCI User to
+		 * cleanup old devices and rediscover the port before
+		 * rebuilding the port with the phys that remain in the ready
+		 * state.
+		 */
+		port_agent->phy_ready_mask &= ~(1 << iphy->phy_index);
+		port_agent->phy_configured_mask &= ~(1 << iphy->phy_index);
+
+		/*
+		 * Check to see if there are more phys waiting to be
+		 * configured into a port. If there are allow the SCI User
+		 * to tear down this port, if necessary, and then reconstruct
+		 * the port after the timeout.
+		 */
+		if ((port_agent->phy_configured_mask == 0x0000) &&
+		    (port_agent->phy_ready_mask != 0x0000) &&
+		    !port_agent->timer_pending) {
+			port_agent->timer_pending = true;
+
+			sci_mod_timer(&port_agent->timer,
+				      SCIC_SDS_MPC_RECONFIGURATION_TIMEOUT);
+		}
+
+		sci_port_link_down(iport, iphy);
+	}
+}
+
+/* verify phys are assigned a valid SAS address for automatic port
+ * configuration mode.
+ */
+static enum sci_status
+sci_apc_agent_validate_phy_configuration(struct isci_host *ihost,
+					      struct sci_port_configuration_agent *port_agent)
+{
+	u8 phy_index;
+	u8 port_index;
+	struct sci_sas_address sas_address;
+	struct sci_sas_address phy_assigned_address;
+
+	phy_index = 0;
+
+	while (phy_index < SCI_MAX_PHYS) {
+		port_index = phy_index;
+
+		/* Get the assigned SAS Address for the first PHY on the controller. */
+		sci_phy_get_sas_address(&ihost->phys[phy_index],
+					    &sas_address);
+
+		while (++phy_index < SCI_MAX_PHYS) {
+			sci_phy_get_sas_address(&ihost->phys[phy_index],
+						     &phy_assigned_address);
+
+			/* Verify each of the SAS address are all the same for every PHY */
+			if (sci_sas_address_compare(sas_address, phy_assigned_address) == 0) {
+				port_agent->phy_valid_port_range[phy_index].min_index = port_index;
+				port_agent->phy_valid_port_range[phy_index].max_index = phy_index;
+			} else {
+				port_agent->phy_valid_port_range[phy_index].min_index = phy_index;
+				port_agent->phy_valid_port_range[phy_index].max_index = phy_index;
+				break;
+			}
+		}
+	}
+
+	return sci_port_configuration_agent_validate_ports(ihost, port_agent);
+}
+
+static void sci_apc_agent_configure_ports(struct isci_host *ihost,
+					       struct sci_port_configuration_agent *port_agent,
+					       struct isci_phy *iphy,
+					       bool start_timer)
+{
+	u8 port_index;
+	enum sci_status status;
+	struct isci_port *iport;
+	enum SCIC_SDS_APC_ACTIVITY apc_activity = SCIC_SDS_APC_SKIP_PHY;
+
+	iport = sci_port_configuration_agent_find_port(ihost, iphy);
+
+	if (iport) {
+		if (sci_port_is_valid_phy_assignment(iport, iphy->phy_index))
+			apc_activity = SCIC_SDS_APC_ADD_PHY;
+		else
+			apc_activity = SCIC_SDS_APC_SKIP_PHY;
+	} else {
+		/*
+		 * There is no matching Port for this PHY so lets search through the
+		 * Ports and see if we can add the PHY to its own port or maybe start
+		 * the timer and wait to see if a wider port can be made.
+		 *
+		 * Note the break when we reach the condition of the port id == phy id */
+		for (port_index = port_agent->phy_valid_port_range[iphy->phy_index].min_index;
+		     port_index <= port_agent->phy_valid_port_range[iphy->phy_index].max_index;
+		     port_index++) {
+
+			iport = &ihost->ports[port_index];
+
+			/* First we must make sure that this PHY can be added to this Port. */
+			if (sci_port_is_valid_phy_assignment(iport, iphy->phy_index)) {
+				/*
+				 * Port contains a PHY with a greater PHY ID than the current
+				 * PHY that has gone link up.  This phy can not be part of any
+				 * port so skip it and move on. */
+				if (iport->active_phy_mask > (1 << iphy->phy_index)) {
+					apc_activity = SCIC_SDS_APC_SKIP_PHY;
+					break;
+				}
+
+				/*
+				 * We have reached the end of our Port list and have not found
+				 * any reason why we should not either add the PHY to the port
+				 * or wait for more phys to become active. */
+				if (iport->physical_port_index == iphy->phy_index) {
+					/*
+					 * The Port either has no active PHYs.
+					 * Consider that if the port had any active PHYs we would have
+					 * or active PHYs with
+					 * a lower PHY Id than this PHY. */
+					if (apc_activity != SCIC_SDS_APC_START_TIMER) {
+						apc_activity = SCIC_SDS_APC_ADD_PHY;
+					}
+
+					break;
+				}
+
+				/*
+				 * The current Port has no active PHYs and this PHY could be part
+				 * of this Port.  Since we dont know as yet setup to start the
+				 * timer and see if there is a better configuration. */
+				if (iport->active_phy_mask == 0) {
+					apc_activity = SCIC_SDS_APC_START_TIMER;
+				}
+			} else if (iport->active_phy_mask != 0) {
+				/*
+				 * The Port has an active phy and the current Phy can not
+				 * participate in this port so skip the PHY and see if
+				 * there is a better configuration. */
+				apc_activity = SCIC_SDS_APC_SKIP_PHY;
+			}
+		}
+	}
+
+	/*
+	 * Check to see if the start timer operations should instead map to an
+	 * add phy operation.  This is caused because we have been waiting to
+	 * add a phy to a port but could not becuase the automatic port
+	 * configuration engine had a choice of possible ports for the phy.
+	 * Since we have gone through a timeout we are going to restrict the
+	 * choice to the smallest possible port. */
+	if (
+		(start_timer == false)
+		&& (apc_activity == SCIC_SDS_APC_START_TIMER)
+		) {
+		apc_activity = SCIC_SDS_APC_ADD_PHY;
+	}
+
+	switch (apc_activity) {
+	case SCIC_SDS_APC_ADD_PHY:
+		status = sci_port_add_phy(iport, iphy);
+
+		if (status == SCI_SUCCESS) {
+			port_agent->phy_configured_mask |= (1 << iphy->phy_index);
+		}
+		break;
+
+	case SCIC_SDS_APC_START_TIMER:
+		/*
+		 * This can occur for either a link down event, or a link
+		 * up event where we cannot yet tell the port to which a
+		 * phy belongs.
+		 */
+		if (port_agent->timer_pending)
+			sci_del_timer(&port_agent->timer);
+
+		port_agent->timer_pending = true;
+		sci_mod_timer(&port_agent->timer,
+			      SCIC_SDS_APC_WAIT_LINK_UP_NOTIFICATION);
+		break;
+
+	case SCIC_SDS_APC_SKIP_PHY:
+	default:
+		/* do nothing the PHY can not be made part of a port at this time. */
+		break;
+	}
+}
+
+/**
+ * sci_apc_agent_link_up - handle apc link up events
+ * @scic: This is the controller object that receives the link up
+ *    notification.
+ * @sci_port: This is the port object associated with the phy.  If the is no
+ *    associated port this is an NULL.
+ * @sci_phy: This is the phy object which has gone link up.
+ *
+ * This method handles the automatic port configuration for link up
+ * notifications. Is it possible to get a link down notification from a phy
+ * that has no assocoated port?
+ */
+static void sci_apc_agent_link_up(struct isci_host *ihost,
+				       struct sci_port_configuration_agent *port_agent,
+				       struct isci_port *iport,
+				       struct isci_phy *iphy)
+{
+	u8 phy_index  = iphy->phy_index;
+
+	if (!iport) {
+		/* the phy is not the part of this port */
+		port_agent->phy_ready_mask |= 1 << phy_index;
+		sci_apc_agent_configure_ports(ihost, port_agent, iphy, true);
+	} else {
+		/* the phy is already the part of the port */
+		u32 port_state = iport->sm.current_state_id;
+
+		/* if the PORT'S state is resetting then the link up is from
+		 * port hard reset in this case, we need to tell the port
+		 * that link up is recieved
+		 */
+		BUG_ON(port_state != SCI_PORT_RESETTING);
+		port_agent->phy_ready_mask |= 1 << phy_index;
+		sci_port_link_up(iport, iphy);
+	}
+}
+
+/**
+ *
+ * @controller: This is the controller object that receives the link down
+ *    notification.
+ * @iport: This is the port object associated with the phy.  If the is no
+ *    associated port this is an NULL.
+ * @iphy: This is the phy object which has gone link down.
+ *
+ * This method handles the automatic port configuration link down
+ * notifications. not associated with a port there is no action taken. Is it
+ * possible to get a link down notification from a phy that has no assocoated
+ * port?
+ */
+static void sci_apc_agent_link_down(
+	struct isci_host *ihost,
+	struct sci_port_configuration_agent *port_agent,
+	struct isci_port *iport,
+	struct isci_phy *iphy)
+{
+	port_agent->phy_ready_mask &= ~(1 << iphy->phy_index);
+
+	if (!iport)
+		return;
+	if (port_agent->phy_configured_mask & (1 << iphy->phy_index)) {
+		enum sci_status status;
+
+		status = sci_port_remove_phy(iport, iphy);
+
+		if (status == SCI_SUCCESS)
+			port_agent->phy_configured_mask &= ~(1 << iphy->phy_index);
+	}
+}
+
+/* configure the phys into ports when the timer fires */
+static void apc_agent_timeout(unsigned long data)
+{
+	u32 index;
+	struct sci_timer *tmr = (struct sci_timer *)data;
+	struct sci_port_configuration_agent *port_agent;
+	struct isci_host *ihost;
+	unsigned long flags;
+	u16 configure_phy_mask;
+
+	port_agent = container_of(tmr, typeof(*port_agent), timer);
+	ihost = container_of(port_agent, typeof(*ihost), port_agent);
+
+	spin_lock_irqsave(&ihost->scic_lock, flags);
+
+	if (tmr->cancel)
+		goto done;
+
+	port_agent->timer_pending = false;
+
+	configure_phy_mask = ~port_agent->phy_configured_mask & port_agent->phy_ready_mask;
+
+	if (!configure_phy_mask)
+		return;
+
+	for (index = 0; index < SCI_MAX_PHYS; index++) {
+		if ((configure_phy_mask & (1 << index)) == 0)
+			continue;
+
+		sci_apc_agent_configure_ports(ihost, port_agent,
+						   &ihost->phys[index], false);
+	}
+
+done:
+	spin_unlock_irqrestore(&ihost->scic_lock, flags);
+}
+
+/*
+ * ******************************************************************************
+ * Public port configuration agent routines
+ * ****************************************************************************** */
+
+/**
+ *
+ *
+ * This method will construct the port configuration agent for operation. This
+ * call is universal for both manual port configuration and automatic port
+ * configuration modes.
+ */
+void sci_port_configuration_agent_construct(
+	struct sci_port_configuration_agent *port_agent)
+{
+	u32 index;
+
+	port_agent->phy_configured_mask = 0x00;
+	port_agent->phy_ready_mask = 0x00;
+
+	port_agent->link_up_handler = NULL;
+	port_agent->link_down_handler = NULL;
+
+	port_agent->timer_pending = false;
+
+	for (index = 0; index < SCI_MAX_PORTS; index++) {
+		port_agent->phy_valid_port_range[index].min_index = 0;
+		port_agent->phy_valid_port_range[index].max_index = 0;
+	}
+}
+
+enum sci_status sci_port_configuration_agent_initialize(
+	struct isci_host *ihost,
+	struct sci_port_configuration_agent *port_agent)
+{
+	enum sci_status status;
+	enum sci_port_configuration_mode mode;
+
+	mode = ihost->oem_parameters.controller.mode_type;
+
+	if (mode == SCIC_PORT_MANUAL_CONFIGURATION_MODE) {
+		status = sci_mpc_agent_validate_phy_configuration(
+				ihost, port_agent);
+
+		port_agent->link_up_handler = sci_mpc_agent_link_up;
+		port_agent->link_down_handler = sci_mpc_agent_link_down;
+
+		sci_init_timer(&port_agent->timer, mpc_agent_timeout);
+	} else {
+		status = sci_apc_agent_validate_phy_configuration(
+				ihost, port_agent);
+
+		port_agent->link_up_handler = sci_apc_agent_link_up;
+		port_agent->link_down_handler = sci_apc_agent_link_down;
+
+		sci_init_timer(&port_agent->timer, apc_agent_timeout);
+	}
+
+	return status;
+}
diff -druN linux-2.6.39-libre/drivers/scsi/isci/port.h linux-3.0-rc7-libre/drivers/scsi/isci/port.h
--- linux-2.6.39-libre/drivers/scsi/isci/port.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/scsi/isci/port.h	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,306 @@
+/*
+ * This file is provided under a dual BSD/GPLv2 license.  When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * The full GNU General Public License is included in this distribution
+ * in the file called LICENSE.GPL.
+ *
+ * BSD LICENSE
+ *
+ * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in
+ *     the documentation and/or other materials provided with the
+ *     distribution.
+ *   * Neither the name of Intel Corporation nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _ISCI_PORT_H_
+#define _ISCI_PORT_H_
+
+#include <scsi/libsas.h>
+#include "isci.h"
+#include "sas.h"
+#include "phy.h"
+
+#define SCIC_SDS_DUMMY_PORT   0xFF
+
+struct isci_phy;
+struct isci_host;
+
+enum isci_status {
+	isci_freed        = 0x00,
+	isci_starting     = 0x01,
+	isci_ready        = 0x02,
+	isci_ready_for_io = 0x03,
+	isci_stopping     = 0x04,
+	isci_stopped      = 0x05,
+};
+
+/**
+ * struct isci_port - isci direct attached sas port object
+ * @event: counts bcns and port stop events (for bcn filtering)
+ * @ready_exit: several states constitute 'ready'. When exiting ready we
+ *              need to take extra port-teardown actions that are
+ *              skipped when exiting to another 'ready' state.
+ * @logical_port_index: software port index
+ * @physical_port_index: hardware port index
+ * @active_phy_mask: identifies phy members
+ * @reserved_tag:
+ * @reserved_rni: reserver for port task scheduler workaround
+ * @started_request_count: reference count for outstanding commands
+ * @not_ready_reason: set during state transitions and notified
+ * @timer: timeout start/stop operations
+ */
+struct isci_port {
+	enum isci_status status;
+	#define IPORT_BCN_BLOCKED 0
+	#define IPORT_BCN_PENDING 1
+	unsigned long flags;
+	atomic_t event;
+	struct isci_host *isci_host;
+	struct asd_sas_port sas_port;
+	struct list_head remote_dev_list;
+	spinlock_t state_lock;
+	struct list_head domain_dev_list;
+	struct completion start_complete;
+	struct completion hard_reset_complete;
+	enum sci_status hard_reset_status;
+	struct sci_base_state_machine sm;
+	bool ready_exit;
+	u8 logical_port_index;
+	u8 physical_port_index;
+	u8 active_phy_mask;
+	u16 reserved_rni;
+	u16 reserved_tag;
+	u32 started_request_count;
+	u32 assigned_device_count;
+	u32 not_ready_reason;
+	struct isci_phy *phy_table[SCI_MAX_PHYS];
+	struct isci_host *owning_controller;
+	struct sci_timer timer;
+	struct scu_port_task_scheduler_registers __iomem *port_task_scheduler_registers;
+	/* XXX rework: only one register, no need to replicate per-port */
+	u32 __iomem *port_pe_configuration_register;
+	struct scu_viit_entry __iomem *viit_registers;
+};
+
+enum sci_port_not_ready_reason_code {
+	SCIC_PORT_NOT_READY_NO_ACTIVE_PHYS,
+	SCIC_PORT_NOT_READY_HARD_RESET_REQUESTED,
+	SCIC_PORT_NOT_READY_INVALID_PORT_CONFIGURATION,
+	SCIC_PORT_NOT_READY_RECONFIGURING,
+
+	SCIC_PORT_NOT_READY_REASON_CODE_MAX
+};
+
+struct sci_port_end_point_properties {
+	struct sci_sas_address sas_address;
+	struct sci_phy_proto protocols;
+};
+
+struct sci_port_properties {
+	u32 index;
+	struct sci_port_end_point_properties local;
+	struct sci_port_end_point_properties remote;
+	u32 phy_mask;
+};
+
+/**
+ * enum sci_port_states - This enumeration depicts all the states for the
+ *    common port state machine.
+ *
+ *
+ */
+enum sci_port_states {
+	/**
+	 * This state indicates that the port has successfully been stopped.
+	 * In this state no new IO operations are permitted.
+	 * This state is entered from the STOPPING state.
+	 */
+	SCI_PORT_STOPPED,
+
+	/**
+	 * This state indicates that the port is in the process of stopping.
+	 * In this state no new IO operations are permitted, but existing IO
+	 * operations are allowed to complete.
+	 * This state is entered from the READY state.
+	 */
+	SCI_PORT_STOPPING,
+
+	/**
+	 * This state indicates the port is now ready.  Thus, the user is
+	 * able to perform IO operations on this port.
+	 * This state is entered from the STARTING state.
+	 */
+	SCI_PORT_READY,
+
+	/**
+	 * The substate where the port is started and ready but has no
+	 * active phys.
+	 */
+	SCI_PORT_SUB_WAITING,
+
+	/**
+	 * The substate where the port is started and ready and there is
+	 * at least one phy operational.
+	 */
+	SCI_PORT_SUB_OPERATIONAL,
+
+	/**
+	 * The substate where the port is started and there was an
+	 * add/remove phy event.  This state is only used in Automatic
+	 * Port Configuration Mode (APC)
+	 */
+	SCI_PORT_SUB_CONFIGURING,
+
+	/**
+	 * This state indicates the port is in the process of performing a hard
+	 * reset.  Thus, the user is unable to perform IO operations on this
+	 * port.
+	 * This state is entered from the READY state.
+	 */
+	SCI_PORT_RESETTING,
+
+	/**
+	 * This state indicates the port has failed a reset request.  This state
+	 * is entered when a port reset request times out.
+	 * This state is entered from the RESETTING state.
+	 */
+	SCI_PORT_FAILED,
+
+
+};
+
+static inline void sci_port_decrement_request_count(struct isci_port *iport)
+{
+	if (WARN_ONCE(iport->started_request_count == 0,
+		       "%s: tried to decrement started_request_count past 0!?",
+			__func__))
+		/* pass */;
+	else
+		iport->started_request_count--;
+}
+
+#define sci_port_active_phy(port, phy) \
+	(((port)->active_phy_mask & (1 << (phy)->phy_index)) != 0)
+
+void sci_port_construct(
+	struct isci_port *iport,
+	u8 port_index,
+	struct isci_host *ihost);
+
+enum sci_status sci_port_start(struct isci_port *iport);
+enum sci_status sci_port_stop(struct isci_port *iport);
+
+enum sci_status sci_port_add_phy(
+	struct isci_port *iport,
+	struct isci_phy *iphy);
+
+enum sci_status sci_port_remove_phy(
+	struct isci_port *iport,
+	struct isci_phy *iphy);
+
+void sci_port_setup_transports(
+	struct isci_port *iport,
+	u32 device_id);
+
+void isci_port_bcn_enable(struct isci_host *, struct isci_port *);
+
+void sci_port_deactivate_phy(
+	struct isci_port *iport,
+	struct isci_phy *iphy,
+	bool do_notify_user);
+
+bool sci_port_link_detected(
+	struct isci_port *iport,
+	struct isci_phy *iphy);
+
+enum sci_status sci_port_link_up(struct isci_port *iport,
+				      struct isci_phy *iphy);
+enum sci_status sci_port_link_down(struct isci_port *iport,
+					struct isci_phy *iphy);
+
+struct isci_request;
+struct isci_remote_device;
+enum sci_status sci_port_start_io(
+	struct isci_port *iport,
+	struct isci_remote_device *idev,
+	struct isci_request *ireq);
+
+enum sci_status sci_port_complete_io(
+	struct isci_port *iport,
+	struct isci_remote_device *idev,
+	struct isci_request *ireq);
+
+enum sas_linkrate sci_port_get_max_allowed_speed(
+	struct isci_port *iport);
+
+void sci_port_broadcast_change_received(
+	struct isci_port *iport,
+	struct isci_phy *iphy);
+
+bool sci_port_is_valid_phy_assignment(
+	struct isci_port *iport,
+	u32 phy_index);
+
+void sci_port_get_sas_address(
+	struct isci_port *iport,
+	struct sci_sas_address *sas_address);
+
+void sci_port_get_attached_sas_address(
+	struct isci_port *iport,
+	struct sci_sas_address *sas_address);
+
+enum isci_status isci_port_get_state(
+	struct isci_port *isci_port);
+
+void isci_port_formed(struct asd_sas_phy *);
+void isci_port_deformed(struct asd_sas_phy *);
+
+void isci_port_init(
+	struct isci_port *port,
+	struct isci_host *host,
+	int index);
+
+int isci_port_perform_hard_reset(struct isci_host *ihost, struct isci_port *iport,
+				 struct isci_phy *iphy);
+#endif /* !defined(_ISCI_PORT_H_) */
diff -druN linux-2.6.39-libre/drivers/scsi/isci/probe_roms.c linux-3.0-rc7-libre/drivers/scsi/isci/probe_roms.c
--- linux-2.6.39-libre/drivers/scsi/isci/probe_roms.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/scsi/isci/probe_roms.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,243 @@
+/*
+ * This file is provided under a dual BSD/GPLv2 license.  When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * The full GNU General Public License is included in this distribution
+ * in the file called LICENSE.GPL.
+ */
+
+/* probe_roms - scan for oem parameters */
+
+#include <linux/kernel.h>
+#include <linux/firmware.h>
+#include <linux/uaccess.h>
+#include <linux/efi.h>
+#include <asm/probe_roms.h>
+
+#include "isci.h"
+#include "task.h"
+#include "probe_roms.h"
+
+static efi_char16_t isci_efivar_name[] = {
+	'R', 's', 't', 'S', 'c', 'u', 'O'
+};
+
+struct isci_orom *isci_request_oprom(struct pci_dev *pdev)
+{
+	void __iomem *oprom = pci_map_biosrom(pdev);
+	struct isci_orom *rom = NULL;
+	size_t len, i;
+	int j;
+	char oem_sig[4];
+	struct isci_oem_hdr oem_hdr;
+	u8 *tmp, sum;
+
+	if (!oprom)
+		return NULL;
+
+	len = pci_biosrom_size(pdev);
+	rom = devm_kzalloc(&pdev->dev, sizeof(*rom), GFP_KERNEL);
+	if (!rom) {
+		dev_warn(&pdev->dev,
+			 "Unable to allocate memory for orom\n");
+		return NULL;
+	}
+
+	for (i = 0; i < len && rom; i += ISCI_OEM_SIG_SIZE) {
+		memcpy_fromio(oem_sig, oprom + i, ISCI_OEM_SIG_SIZE);
+
+		/* we think we found the OEM table */
+		if (memcmp(oem_sig, ISCI_OEM_SIG, ISCI_OEM_SIG_SIZE) == 0) {
+			size_t copy_len;
+
+			memcpy_fromio(&oem_hdr, oprom + i, sizeof(oem_hdr));
+
+			copy_len = min(oem_hdr.len - sizeof(oem_hdr),
+				       sizeof(*rom));
+
+			memcpy_fromio(rom,
+				      oprom + i + sizeof(oem_hdr),
+				      copy_len);
+
+			/* calculate checksum */
+			tmp = (u8 *)&oem_hdr;
+			for (j = 0, sum = 0; j < sizeof(oem_hdr); j++, tmp++)
+				sum += *tmp;
+
+			tmp = (u8 *)rom;
+			for (j = 0; j < sizeof(*rom); j++, tmp++)
+				sum += *tmp;
+
+			if (sum != 0) {
+				dev_warn(&pdev->dev,
+					 "OEM table checksum failed\n");
+				continue;
+			}
+
+			/* keep going if that's not the oem param table */
+			if (memcmp(rom->hdr.signature,
+				   ISCI_ROM_SIG,
+				   ISCI_ROM_SIG_SIZE) != 0)
+				continue;
+
+			dev_info(&pdev->dev,
+				 "OEM parameter table found in OROM\n");
+			break;
+		}
+	}
+
+	if (i >= len) {
+		dev_err(&pdev->dev, "oprom parse error\n");
+		devm_kfree(&pdev->dev, rom);
+		rom = NULL;
+	}
+	pci_unmap_biosrom(oprom);
+
+	return rom;
+}
+
+enum sci_status isci_parse_oem_parameters(struct sci_oem_params *oem,
+					  struct isci_orom *orom, int scu_index)
+{
+	/* check for valid inputs */
+	if (scu_index < 0 || scu_index >= SCI_MAX_CONTROLLERS ||
+	    scu_index > orom->hdr.num_elements || !oem)
+		return -EINVAL;
+
+	*oem = orom->ctrl[scu_index];
+	return 0;
+}
+
+struct isci_orom *isci_request_firmware(struct pci_dev *pdev, const struct firmware *fw)
+{
+	struct isci_orom *orom = NULL, *data;
+	int i, j;
+
+	if (request_firmware(&fw, ISCI_FW_NAME, &pdev->dev) != 0)
+		return NULL;
+
+	if (fw->size < sizeof(*orom))
+		goto out;
+
+	data = (struct isci_orom *)fw->data;
+
+	if (strncmp(ISCI_ROM_SIG, data->hdr.signature,
+		    strlen(ISCI_ROM_SIG)) != 0)
+		goto out;
+
+	orom = devm_kzalloc(&pdev->dev, fw->size, GFP_KERNEL);
+	if (!orom)
+		goto out;
+
+	memcpy(orom, fw->data, fw->size);
+
+	if (is_c0(pdev))
+		goto out;
+
+	/*
+	 * deprecated: override default amp_control for pre-preproduction
+	 * silicon revisions
+	 */
+	for (i = 0; i < ARRAY_SIZE(orom->ctrl); i++)
+		for (j = 0; j < ARRAY_SIZE(orom->ctrl[i].phys); j++) {
+			orom->ctrl[i].phys[j].afe_tx_amp_control0 = 0xe7c03;
+			orom->ctrl[i].phys[j].afe_tx_amp_control1 = 0xe7c03;
+			orom->ctrl[i].phys[j].afe_tx_amp_control2 = 0xe7c03;
+			orom->ctrl[i].phys[j].afe_tx_amp_control3 = 0xe7c03;
+		}
+ out:
+	release_firmware(fw);
+
+	return orom;
+}
+
+static struct efi *get_efi(void)
+{
+#ifdef CONFIG_EFI
+	return &efi;
+#else
+	return NULL;
+#endif
+}
+
+struct isci_orom *isci_get_efi_var(struct pci_dev *pdev)
+{
+	efi_status_t status;
+	struct isci_orom *rom;
+	struct isci_oem_hdr *oem_hdr;
+	u8 *tmp, sum;
+	int j;
+	unsigned long data_len;
+	u8 *efi_data;
+	u32 efi_attrib = 0;
+
+	data_len = 1024;
+	efi_data = devm_kzalloc(&pdev->dev, data_len, GFP_KERNEL);
+	if (!efi_data) {
+		dev_warn(&pdev->dev,
+			 "Unable to allocate memory for EFI data\n");
+		return NULL;
+	}
+
+	rom = (struct isci_orom *)(efi_data + sizeof(struct isci_oem_hdr));
+
+	if (get_efi())
+		status = get_efi()->get_variable(isci_efivar_name,
+						 &ISCI_EFI_VENDOR_GUID,
+						 &efi_attrib,
+						 &data_len,
+						 efi_data);
+	else
+		status = EFI_NOT_FOUND;
+
+	if (status != EFI_SUCCESS) {
+		dev_warn(&pdev->dev,
+			 "Unable to obtain EFI var data for OEM parms\n");
+		return NULL;
+	}
+
+	oem_hdr = (struct isci_oem_hdr *)efi_data;
+
+	if (memcmp(oem_hdr->sig, ISCI_OEM_SIG, ISCI_OEM_SIG_SIZE) != 0) {
+		dev_warn(&pdev->dev,
+			 "Invalid OEM header signature\n");
+		return NULL;
+	}
+
+	/* calculate checksum */
+	tmp = (u8 *)efi_data;
+	for (j = 0, sum = 0; j < (sizeof(*oem_hdr) + sizeof(*rom)); j++, tmp++)
+		sum += *tmp;
+
+	if (sum != 0) {
+		dev_warn(&pdev->dev,
+			 "OEM table checksum failed\n");
+		return NULL;
+	}
+
+	if (memcmp(rom->hdr.signature,
+		   ISCI_ROM_SIG,
+		   ISCI_ROM_SIG_SIZE) != 0) {
+		dev_warn(&pdev->dev,
+			 "Invalid OEM table signature\n");
+		return NULL;
+	}
+
+	return rom;
+}
diff -druN linux-2.6.39-libre/drivers/scsi/isci/probe_roms.h linux-3.0-rc7-libre/drivers/scsi/isci/probe_roms.h
--- linux-2.6.39-libre/drivers/scsi/isci/probe_roms.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/scsi/isci/probe_roms.h	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,249 @@
+/*
+ * This file is provided under a dual BSD/GPLv2 license.  When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * The full GNU General Public License is included in this distribution
+ * in the file called LICENSE.GPL.
+ *
+ * BSD LICENSE
+ *
+ * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in
+ *     the documentation and/or other materials provided with the
+ *     distribution.
+ *   * Neither the name of Intel Corporation nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef _ISCI_PROBE_ROMS_H_
+#define _ISCI_PROBE_ROMS_H_
+
+#ifdef __KERNEL__
+#include <linux/firmware.h>
+#include <linux/pci.h>
+#include <linux/efi.h>
+#include "isci.h"
+
+#define SCIC_SDS_PARM_NO_SPEED   0
+
+/* generation 1 (i.e. 1.5 Gb/s) */
+#define SCIC_SDS_PARM_GEN1_SPEED 1
+
+/* generation 2 (i.e. 3.0 Gb/s) */
+#define SCIC_SDS_PARM_GEN2_SPEED 2
+
+/* generation 3 (i.e. 6.0 Gb/s) */
+#define SCIC_SDS_PARM_GEN3_SPEED 3
+#define SCIC_SDS_PARM_MAX_SPEED SCIC_SDS_PARM_GEN3_SPEED
+
+/* parameters that can be set by module parameters */
+struct sci_user_parameters {
+	struct sci_phy_user_params {
+		/**
+		 * This field specifies the NOTIFY (ENABLE SPIN UP) primitive
+		 * insertion frequency for this phy index.
+		 */
+		u32 notify_enable_spin_up_insertion_frequency;
+
+		/**
+		 * This method specifies the number of transmitted DWORDs within which
+		 * to transmit a single ALIGN primitive.  This value applies regardless
+		 * of what type of device is attached or connection state.  A value of
+		 * 0 indicates that no ALIGN primitives will be inserted.
+		 */
+		u16 align_insertion_frequency;
+
+		/**
+		 * This method specifies the number of transmitted DWORDs within which
+		 * to transmit 2 ALIGN primitives.  This applies for SAS connections
+		 * only.  A minimum value of 3 is required for this field.
+		 */
+		u16 in_connection_align_insertion_frequency;
+
+		/**
+		 * This field indicates the maximum speed generation to be utilized
+		 * by phys in the supplied port.
+		 * - A value of 1 indicates generation 1 (i.e. 1.5 Gb/s).
+		 * - A value of 2 indicates generation 2 (i.e. 3.0 Gb/s).
+		 * - A value of 3 indicates generation 3 (i.e. 6.0 Gb/s).
+		 */
+		u8 max_speed_generation;
+
+	} phys[SCI_MAX_PHYS];
+
+	/**
+	 * This field specifies the maximum number of direct attached devices
+	 * that can have power supplied to them simultaneously.
+	 */
+	u8 max_number_concurrent_device_spin_up;
+
+	/**
+	 * This field specifies the number of seconds to allow a phy to consume
+	 * power before yielding to another phy.
+	 *
+	 */
+	u8 phy_spin_up_delay_interval;
+
+	/**
+	 * These timer values specifies how long a link will remain open with no
+	 * activity in increments of a microsecond, it can be in increments of
+	 * 100 microseconds if the upper most bit is set.
+	 *
+	 */
+	u16 stp_inactivity_timeout;
+	u16 ssp_inactivity_timeout;
+
+	/**
+	 * These timer values specifies how long a link will remain open in increments
+	 * of 100 microseconds.
+	 *
+	 */
+	u16 stp_max_occupancy_timeout;
+	u16 ssp_max_occupancy_timeout;
+
+	/**
+	 * This timer value specifies how long a link will remain open with no
+	 * outbound traffic in increments of a microsecond.
+	 *
+	 */
+	u8 no_outbound_task_timeout;
+
+};
+
+#define SCIC_SDS_PARM_PHY_MASK_MIN 0x0
+#define SCIC_SDS_PARM_PHY_MASK_MAX 0xF
+#define MAX_CONCURRENT_DEVICE_SPIN_UP_COUNT 4
+
+struct sci_oem_params;
+int sci_oem_parameters_validate(struct sci_oem_params *oem);
+
+struct isci_orom;
+struct isci_orom *isci_request_oprom(struct pci_dev *pdev);
+enum sci_status isci_parse_oem_parameters(struct sci_oem_params *oem,
+					  struct isci_orom *orom, int scu_index);
+struct isci_orom *isci_request_firmware(struct pci_dev *pdev, const struct firmware *fw);
+struct isci_orom *isci_get_efi_var(struct pci_dev *pdev);
+
+struct isci_oem_hdr {
+	u8 sig[4];
+	u8 rev_major;
+	u8 rev_minor;
+	u16 len;
+	u8 checksum;
+	u8 reserved1;
+	u16 reserved2;
+} __attribute__ ((packed));
+
+#else
+#define SCI_MAX_PORTS 4
+#define SCI_MAX_PHYS 4
+#define SCI_MAX_CONTROLLERS 2
+#endif
+
+#define ISCI_FW_NAME		"isci/isci_firmware.bin"
+
+#define ROMSIGNATURE		0xaa55
+
+#define ISCI_OEM_SIG		"$OEM"
+#define ISCI_OEM_SIG_SIZE	4
+#define ISCI_ROM_SIG		"ISCUOEMB"
+#define ISCI_ROM_SIG_SIZE	8
+
+#define ISCI_EFI_VENDOR_GUID	\
+	EFI_GUID(0x193dfefa, 0xa445, 0x4302, 0x99, 0xd8, 0xef, 0x3a, 0xad, \
+			0x1a, 0x04, 0xc6)
+#define ISCI_EFI_VAR_NAME	"RstScuO"
+
+/* Allowed PORT configuration modes APC Automatic PORT configuration mode is
+ * defined by the OEM configuration parameters providing no PHY_MASK parameters
+ * for any PORT. i.e. There are no phys assigned to any of the ports at start.
+ * MPC Manual PORT configuration mode is defined by the OEM configuration
+ * parameters providing a PHY_MASK value for any PORT.  It is assumed that any
+ * PORT with no PHY_MASK is an invalid port and not all PHYs must be assigned.
+ * A PORT_PHY mask that assigns just a single PHY to a port and no other PHYs
+ * being assigned is sufficient to declare manual PORT configuration.
+ */
+enum sci_port_configuration_mode {
+	SCIC_PORT_MANUAL_CONFIGURATION_MODE = 0,
+	SCIC_PORT_AUTOMATIC_CONFIGURATION_MODE = 1
+};
+
+struct sci_bios_oem_param_block_hdr {
+	uint8_t signature[ISCI_ROM_SIG_SIZE];
+	uint16_t total_block_length;
+	uint8_t hdr_length;
+	uint8_t version;
+	uint8_t preboot_source;
+	uint8_t num_elements;
+	uint16_t element_length;
+	uint8_t reserved[8];
+} __attribute__ ((packed));
+
+struct sci_oem_params {
+	struct {
+		uint8_t mode_type;
+		uint8_t max_concurrent_dev_spin_up;
+		uint8_t do_enable_ssc;
+		uint8_t reserved;
+	} controller;
+
+	struct {
+		uint8_t phy_mask;
+	} ports[SCI_MAX_PORTS];
+
+	struct sci_phy_oem_params {
+		struct {
+			uint32_t high;
+			uint32_t low;
+		} sas_address;
+
+		uint32_t afe_tx_amp_control0;
+		uint32_t afe_tx_amp_control1;
+		uint32_t afe_tx_amp_control2;
+		uint32_t afe_tx_amp_control3;
+	} phys[SCI_MAX_PHYS];
+} __attribute__ ((packed));
+
+struct isci_orom {
+	struct sci_bios_oem_param_block_hdr hdr;
+	struct sci_oem_params ctrl[SCI_MAX_CONTROLLERS];
+} __attribute__ ((packed));
+
+#endif
diff -druN linux-2.6.39-libre/drivers/scsi/isci/registers.h linux-3.0-rc7-libre/drivers/scsi/isci/registers.h
--- linux-2.6.39-libre/drivers/scsi/isci/registers.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/scsi/isci/registers.h	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,1934 @@
+/*
+ * This file is provided under a dual BSD/GPLv2 license.  When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * The full GNU General Public License is included in this distribution
+ * in the file called LICENSE.GPL.
+ *
+ * BSD LICENSE
+ *
+ * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in
+ *     the documentation and/or other materials provided with the
+ *     distribution.
+ *   * Neither the name of Intel Corporation nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _SCU_REGISTERS_H_
+#define _SCU_REGISTERS_H_
+
+/**
+ * This file contains the constants and structures for the SCU memory mapped
+ *    registers.
+ *
+ *
+ */
+
+#define SCU_VIIT_ENTRY_ID_MASK         (0xC0000000)
+#define SCU_VIIT_ENTRY_ID_SHIFT        (30)
+
+#define SCU_VIIT_ENTRY_FUNCTION_MASK   (0x0FF00000)
+#define SCU_VIIT_ENTRY_FUNCTION_SHIFT  (20)
+
+#define SCU_VIIT_ENTRY_IPPTMODE_MASK   (0x0001F800)
+#define SCU_VIIT_ENTRY_IPPTMODE_SHIFT  (12)
+
+#define SCU_VIIT_ENTRY_LPVIE_MASK      (0x00000F00)
+#define SCU_VIIT_ENTRY_LPVIE_SHIFT     (8)
+
+#define SCU_VIIT_ENTRY_STATUS_MASK     (0x000000FF)
+#define SCU_VIIT_ENTRY_STATUS_SHIFT    (0)
+
+#define SCU_VIIT_ENTRY_ID_INVALID   (0 << SCU_VIIT_ENTRY_ID_SHIFT)
+#define SCU_VIIT_ENTRY_ID_VIIT      (1 << SCU_VIIT_ENTRY_ID_SHIFT)
+#define SCU_VIIT_ENTRY_ID_IIT       (2 << SCU_VIIT_ENTRY_ID_SHIFT)
+#define SCU_VIIT_ENTRY_ID_VIRT_EXP  (3 << SCU_VIIT_ENTRY_ID_SHIFT)
+
+#define SCU_VIIT_IPPT_SSP_INITIATOR (0x01 << SCU_VIIT_ENTRY_IPPTMODE_SHIFT)
+#define SCU_VIIT_IPPT_SMP_INITIATOR (0x02 << SCU_VIIT_ENTRY_IPPTMODE_SHIFT)
+#define SCU_VIIT_IPPT_STP_INITIATOR (0x04 << SCU_VIIT_ENTRY_IPPTMODE_SHIFT)
+#define SCU_VIIT_IPPT_INITIATOR	    \
+	(\
+		SCU_VIIT_IPPT_SSP_INITIATOR  \
+		| SCU_VIIT_IPPT_SMP_INITIATOR  \
+		| SCU_VIIT_IPPT_STP_INITIATOR  \
+	)
+
+#define SCU_VIIT_STATUS_RNC_VALID      (0x01 << SCU_VIIT_ENTRY_STATUS_SHIFT)
+#define SCU_VIIT_STATUS_ADDRESS_VALID  (0x02 << SCU_VIIT_ENTRY_STATUS_SHIFT)
+#define SCU_VIIT_STATUS_RNI_VALID      (0x04 << SCU_VIIT_ENTRY_STATUS_SHIFT)
+#define SCU_VIIT_STATUS_ALL_VALID      \
+	(\
+		SCU_VIIT_STATUS_RNC_VALID	\
+		| SCU_VIIT_STATUS_ADDRESS_VALID	  \
+		| SCU_VIIT_STATUS_RNI_VALID	  \
+	)
+
+#define SCU_VIIT_IPPT_SMP_TARGET    (0x10 << SCU_VIIT_ENTRY_IPPTMODE_SHIFT)
+
+/**
+ * struct scu_viit_entry - This is the SCU Virtual Initiator Table Entry
+ *
+ *
+ */
+struct scu_viit_entry {
+	/**
+	 * This must be encoded as to the type of initiator that is being constructed
+	 * for this port.
+	 */
+	u32 status;
+
+	/**
+	 * Virtual initiator high SAS Address
+	 */
+	u32 initiator_sas_address_hi;
+
+	/**
+	 * Virtual initiator low SAS Address
+	 */
+	u32 initiator_sas_address_lo;
+
+	/**
+	 * This must be 0
+	 */
+	u32 reserved;
+
+};
+
+
+/* IIT Status Defines */
+#define SCU_IIT_ENTRY_ID_MASK                (0xC0000000)
+#define SCU_IIT_ENTRY_ID_SHIFT               (30)
+
+#define SCU_IIT_ENTRY_STATUS_UPDATE_MASK     (0x20000000)
+#define SCU_IIT_ENTRY_STATUS_UPDATE_SHIFT    (29)
+
+#define SCU_IIT_ENTRY_LPI_MASK               (0x00000F00)
+#define SCU_IIT_ENTRY_LPI_SHIFT              (8)
+
+#define SCU_IIT_ENTRY_STATUS_MASK            (0x000000FF)
+#define SCU_IIT_ENTRY_STATUS_SHIFT           (0)
+
+/* IIT Remote Initiator Defines */
+#define SCU_IIT_ENTRY_REMOTE_TAG_MASK  (0x0000FFFF)
+#define SCU_IIT_ENTRY_REMOTE_TAG_SHIFT (0)
+
+#define SCU_IIT_ENTRY_REMOTE_RNC_MASK  (0x0FFF0000)
+#define SCU_IIT_ENTRY_REMOTE_RNC_SHIFT (16)
+
+#define SCU_IIT_ENTRY_ID_INVALID   (0 << SCU_IIT_ENTRY_ID_SHIFT)
+#define SCU_IIT_ENTRY_ID_VIIT      (1 << SCU_IIT_ENTRY_ID_SHIFT)
+#define SCU_IIT_ENTRY_ID_IIT       (2 << SCU_IIT_ENTRY_ID_SHIFT)
+#define SCU_IIT_ENTRY_ID_VIRT_EXP  (3 << SCU_IIT_ENTRY_ID_SHIFT)
+
+/**
+ * struct scu_iit_entry - This will be implemented later when we support
+ *    virtual functions
+ *
+ *
+ */
+struct scu_iit_entry {
+	u32 status;
+	u32 remote_initiator_sas_address_hi;
+	u32 remote_initiator_sas_address_lo;
+	u32 remote_initiator;
+
+};
+
+/* Generate a value for an SCU register */
+#define SCU_GEN_VALUE(name, value) \
+	(((value) << name ## _SHIFT) & (name ## _MASK))
+
+/*
+ * Generate a bit value for an SCU register
+ * Make sure that the register MASK is just a single bit */
+#define SCU_GEN_BIT(name) \
+	SCU_GEN_VALUE(name, ((u32)1))
+
+#define SCU_SET_BIT(name, reg_value) \
+	((reg_value) | SCU_GEN_BIT(name))
+
+#define SCU_CLEAR_BIT(name, reg_value) \
+	((reg_value)$ ~(SCU_GEN_BIT(name)))
+
+/*
+ * *****************************************************************************
+ * Unions for bitfield definitions of SCU Registers
+ * SMU Post Context Port
+ * ***************************************************************************** */
+#define SMU_POST_CONTEXT_PORT_CONTEXT_INDEX_SHIFT         (0)
+#define SMU_POST_CONTEXT_PORT_CONTEXT_INDEX_MASK          (0x00000FFF)
+#define SMU_POST_CONTEXT_PORT_LOGICAL_PORT_INDEX_SHIFT    (12)
+#define SMU_POST_CONTEXT_PORT_LOGICAL_PORT_INDEX_MASK     (0x0000F000)
+#define SMU_POST_CONTEXT_PORT_PROTOCOL_ENGINE_SHIFT       (16)
+#define SMU_POST_CONTEXT_PORT_PROTOCOL_ENGINE_MASK        (0x00030000)
+#define SMU_POST_CONTEXT_PORT_COMMAND_CONTEXT_SHIFT       (18)
+#define SMU_POST_CONTEXT_PORT_COMMAND_CONTEXT_MASK        (0x00FC0000)
+#define SMU_POST_CONTEXT_PORT_RESERVED_MASK               (0xFF000000)
+
+#define SMU_PCP_GEN_VAL(name, value) \
+	SCU_GEN_VALUE(SMU_POST_CONTEXT_PORT_ ## name, value)
+
+/* ***************************************************************************** */
+#define SMU_INTERRUPT_STATUS_COMPLETION_SHIFT       (31)
+#define SMU_INTERRUPT_STATUS_COMPLETION_MASK        (0x80000000)
+#define SMU_INTERRUPT_STATUS_QUEUE_SUSPEND_SHIFT    (1)
+#define SMU_INTERRUPT_STATUS_QUEUE_SUSPEND_MASK     (0x00000002)
+#define SMU_INTERRUPT_STATUS_QUEUE_ERROR_SHIFT      (0)
+#define SMU_INTERRUPT_STATUS_QUEUE_ERROR_MASK       (0x00000001)
+#define SMU_INTERRUPT_STATUS_RESERVED_MASK          (0x7FFFFFFC)
+
+#define SMU_ISR_GEN_BIT(name) \
+	SCU_GEN_BIT(SMU_INTERRUPT_STATUS_ ## name)
+
+#define SMU_ISR_QUEUE_ERROR   SMU_ISR_GEN_BIT(QUEUE_ERROR)
+#define SMU_ISR_QUEUE_SUSPEND SMU_ISR_GEN_BIT(QUEUE_SUSPEND)
+#define SMU_ISR_COMPLETION    SMU_ISR_GEN_BIT(COMPLETION)
+
+/* ***************************************************************************** */
+#define SMU_INTERRUPT_MASK_COMPLETION_SHIFT         (31)
+#define SMU_INTERRUPT_MASK_COMPLETION_MASK          (0x80000000)
+#define SMU_INTERRUPT_MASK_QUEUE_SUSPEND_SHIFT      (1)
+#define SMU_INTERRUPT_MASK_QUEUE_SUSPEND_MASK       (0x00000002)
+#define SMU_INTERRUPT_MASK_QUEUE_ERROR_SHIFT        (0)
+#define SMU_INTERRUPT_MASK_QUEUE_ERROR_MASK         (0x00000001)
+#define SMU_INTERRUPT_MASK_RESERVED_MASK            (0x7FFFFFFC)
+
+#define SMU_IMR_GEN_BIT(name) \
+	SCU_GEN_BIT(SMU_INTERRUPT_MASK_ ## name)
+
+#define SMU_IMR_QUEUE_ERROR   SMU_IMR_GEN_BIT(QUEUE_ERROR)
+#define SMU_IMR_QUEUE_SUSPEND SMU_IMR_GEN_BIT(QUEUE_SUSPEND)
+#define SMU_IMR_COMPLETION    SMU_IMR_GEN_BIT(COMPLETION)
+
+/* ***************************************************************************** */
+#define SMU_INTERRUPT_COALESCING_CONTROL_TIMER_SHIFT    (0)
+#define SMU_INTERRUPT_COALESCING_CONTROL_TIMER_MASK     (0x0000001F)
+#define SMU_INTERRUPT_COALESCING_CONTROL_NUMBER_SHIFT   (8)
+#define SMU_INTERRUPT_COALESCING_CONTROL_NUMBER_MASK    (0x0000FF00)
+#define SMU_INTERRUPT_COALESCING_CONTROL_RESERVED_MASK  (0xFFFF00E0)
+
+#define SMU_ICC_GEN_VAL(name, value) \
+	SCU_GEN_VALUE(SMU_INTERRUPT_COALESCING_CONTROL_ ## name, value)
+
+/* ***************************************************************************** */
+#define SMU_TASK_CONTEXT_RANGE_START_SHIFT      (0)
+#define SMU_TASK_CONTEXT_RANGE_START_MASK       (0x00000FFF)
+#define SMU_TASK_CONTEXT_RANGE_ENDING_SHIFT     (16)
+#define SMU_TASK_CONTEXT_RANGE_ENDING_MASK      (0x0FFF0000)
+#define SMU_TASK_CONTEXT_RANGE_ENABLE_SHIFT     (31)
+#define SMU_TASK_CONTEXT_RANGE_ENABLE_MASK      (0x80000000)
+#define SMU_TASK_CONTEXT_RANGE_RESERVED_MASK    (0x7000F000)
+
+#define SMU_TCR_GEN_VAL(name, value) \
+	SCU_GEN_VALUE(SMU_TASK_CONTEXT_RANGE_ ## name, value)
+
+#define SMU_TCR_GEN_BIT(name, value) \
+	SCU_GEN_BIT(SMU_TASK_CONTEXT_RANGE_ ## name)
+
+/* ***************************************************************************** */
+
+#define SMU_COMPLETION_QUEUE_PUT_POINTER_SHIFT          (0)
+#define SMU_COMPLETION_QUEUE_PUT_POINTER_MASK           (0x00003FFF)
+#define SMU_COMPLETION_QUEUE_PUT_CYCLE_BIT_SHIFT        (15)
+#define SMU_COMPLETION_QUEUE_PUT_CYCLE_BIT_MASK         (0x00008000)
+#define SMU_COMPLETION_QUEUE_PUT_EVENT_POINTER_SHIFT    (16)
+#define SMU_COMPLETION_QUEUE_PUT_EVENT_POINTER_MASK     (0x03FF0000)
+#define SMU_COMPLETION_QUEUE_PUT_EVENT_CYCLE_BIT_SHIFT  (26)
+#define SMU_COMPLETION_QUEUE_PUT_EVENT_CYCLE_BIT_MASK   (0x04000000)
+#define SMU_COMPLETION_QUEUE_PUT_RESERVED_MASK          (0xF8004000)
+
+#define SMU_CQPR_GEN_VAL(name, value) \
+	SCU_GEN_VALUE(SMU_COMPLETION_QUEUE_PUT_ ## name, value)
+
+#define SMU_CQPR_GEN_BIT(name) \
+	SCU_GEN_BIT(SMU_COMPLETION_QUEUE_PUT_ ## name)
+
+/* ***************************************************************************** */
+
+#define SMU_COMPLETION_QUEUE_GET_POINTER_SHIFT          (0)
+#define SMU_COMPLETION_QUEUE_GET_POINTER_MASK           (0x00003FFF)
+#define SMU_COMPLETION_QUEUE_GET_CYCLE_BIT_SHIFT        (15)
+#define SMU_COMPLETION_QUEUE_GET_CYCLE_BIT_MASK         (0x00008000)
+#define SMU_COMPLETION_QUEUE_GET_EVENT_POINTER_SHIFT    (16)
+#define SMU_COMPLETION_QUEUE_GET_EVENT_POINTER_MASK     (0x03FF0000)
+#define SMU_COMPLETION_QUEUE_GET_EVENT_CYCLE_BIT_SHIFT  (26)
+#define SMU_COMPLETION_QUEUE_GET_EVENT_CYCLE_BIT_MASK   (0x04000000)
+#define SMU_COMPLETION_QUEUE_GET_ENABLE_SHIFT           (30)
+#define SMU_COMPLETION_QUEUE_GET_ENABLE_MASK            (0x40000000)
+#define SMU_COMPLETION_QUEUE_GET_EVENT_ENABLE_SHIFT     (31)
+#define SMU_COMPLETION_QUEUE_GET_EVENT_ENABLE_MASK      (0x80000000)
+#define SMU_COMPLETION_QUEUE_GET_RESERVED_MASK          (0x38004000)
+
+#define SMU_CQGR_GEN_VAL(name, value) \
+	SCU_GEN_VALUE(SMU_COMPLETION_QUEUE_GET_ ## name, value)
+
+#define SMU_CQGR_GEN_BIT(name) \
+	SCU_GEN_BIT(SMU_COMPLETION_QUEUE_GET_ ## name)
+
+#define SMU_CQGR_CYCLE_BIT \
+	SMU_CQGR_GEN_BIT(CYCLE_BIT)
+
+#define SMU_CQGR_EVENT_CYCLE_BIT \
+	SMU_CQGR_GEN_BIT(EVENT_CYCLE_BIT)
+
+#define SMU_CQGR_GET_POINTER_SET(value)	\
+	SMU_CQGR_GEN_VAL(POINTER, value)
+
+
+/* ***************************************************************************** */
+#define SMU_COMPLETION_QUEUE_CONTROL_QUEUE_LIMIT_SHIFT  (0)
+#define SMU_COMPLETION_QUEUE_CONTROL_QUEUE_LIMIT_MASK   (0x00003FFF)
+#define SMU_COMPLETION_QUEUE_CONTROL_EVENT_LIMIT_SHIFT  (16)
+#define SMU_COMPLETION_QUEUE_CONTROL_EVENT_LIMIT_MASK   (0x03FF0000)
+#define SMU_COMPLETION_QUEUE_CONTROL_RESERVED_MASK      (0xFC00C000)
+
+#define SMU_CQC_GEN_VAL(name, value) \
+	SCU_GEN_VALUE(SMU_COMPLETION_QUEUE_CONTROL_ ## name, value)
+
+#define SMU_CQC_QUEUE_LIMIT_SET(value) \
+	SMU_CQC_GEN_VAL(QUEUE_LIMIT, value)
+
+#define SMU_CQC_EVENT_LIMIT_SET(value) \
+	SMU_CQC_GEN_VAL(EVENT_LIMIT, value)
+
+
+/* ***************************************************************************** */
+#define SMU_DEVICE_CONTEXT_CAPACITY_MAX_TC_SHIFT    (0)
+#define SMU_DEVICE_CONTEXT_CAPACITY_MAX_TC_MASK     (0x00000FFF)
+#define SMU_DEVICE_CONTEXT_CAPACITY_MAX_LP_SHIFT    (12)
+#define SMU_DEVICE_CONTEXT_CAPACITY_MAX_LP_MASK     (0x00007000)
+#define SMU_DEVICE_CONTEXT_CAPACITY_MAX_RNC_SHIFT   (15)
+#define SMU_DEVICE_CONTEXT_CAPACITY_MAX_RNC_MASK    (0x07FF8000)
+#define SMU_DEVICE_CONTEXT_CAPACITY_MAX_PEG_SHIFT   (27)
+#define SMU_DEVICE_CONTEXT_CAPACITY_MAX_PEG_MASK    (0x08000000)
+#define SMU_DEVICE_CONTEXT_CAPACITY_RESERVED_MASK   (0xF0000000)
+
+#define SMU_DCC_GEN_VAL(name, value) \
+	SCU_GEN_VALUE(SMU_DEVICE_CONTEXT_CAPACITY_ ## name, value)
+
+#define SMU_DCC_GET_MAX_PEG(value) \
+	(\
+		((value) & SMU_DEVICE_CONTEXT_CAPACITY_MAX_PEG_MASK) \
+		>> SMU_DEVICE_CONTEXT_CAPACITY_MAX_LP_SHIFT \
+	)
+
+#define SMU_DCC_GET_MAX_LP(value) \
+	(\
+		((value) & SMU_DEVICE_CONTEXT_CAPACITY_MAX_LP_MASK) \
+		>> SMU_DEVICE_CONTEXT_CAPACITY_MAX_LP_SHIFT \
+	)
+
+#define SMU_DCC_GET_MAX_TC(value) \
+	(\
+		((value) & SMU_DEVICE_CONTEXT_CAPACITY_MAX_TC_MASK) \
+		>> SMU_DEVICE_CONTEXT_CAPACITY_MAX_TC_SHIFT \
+	)
+
+#define SMU_DCC_GET_MAX_RNC(value) \
+	(\
+		((value) & SMU_DEVICE_CONTEXT_CAPACITY_MAX_RNC_MASK) \
+		>> SMU_DEVICE_CONTEXT_CAPACITY_MAX_RNC_SHIFT \
+	)
+
+/* -------------------------------------------------------------------------- */
+
+#define SMU_CONTROL_STATUS_TASK_CONTEXT_RANGE_ENABLE_SHIFT      (0)
+#define SMU_CONTROL_STATUS_TASK_CONTEXT_RANGE_ENABLE_MASK       (0x00000001)
+#define SMU_CONTROL_STATUS_COMPLETION_BYTE_SWAP_ENABLE_SHIFT    (1)
+#define SMU_CONTROL_STATUS_COMPLETION_BYTE_SWAP_ENABLE_MASK     (0x00000002)
+#define SMU_CONTROL_STATUS_CONTEXT_RAM_INIT_COMPLETED_SHIFT     (16)
+#define SMU_CONTROL_STATUS_CONTEXT_RAM_INIT_COMPLETED_MASK      (0x00010000)
+#define SMU_CONTROL_STATUS_SCHEDULER_RAM_INIT_COMPLETED_SHIFT   (17)
+#define SMU_CONTROL_STATUS_SCHEDULER_RAM_INIT_COMPLETED_MASK    (0x00020000)
+#define SMU_CONTROL_STATUS_RESERVED_MASK                        (0xFFFCFFFC)
+
+#define SMU_SMUCSR_GEN_BIT(name) \
+	SCU_GEN_BIT(SMU_CONTROL_STATUS_ ## name)
+
+#define SMU_SMUCSR_SCHEDULER_RAM_INIT_COMPLETED	\
+	(SMU_SMUCSR_GEN_BIT(SCHEDULER_RAM_INIT_COMPLETED))
+
+#define SMU_SMUCSR_CONTEXT_RAM_INIT_COMPLETED	\
+	(SMU_SMUCSR_GEN_BIT(CONTEXT_RAM_INIT_COMPLETED))
+
+#define SCU_RAM_INIT_COMPLETED \
+	(\
+		SMU_SMUCSR_CONTEXT_RAM_INIT_COMPLETED \
+		| SMU_SMUCSR_SCHEDULER_RAM_INIT_COMPLETED \
+	)
+
+/* -------------------------------------------------------------------------- */
+
+#define SMU_SOFTRESET_CONTROL_RESET_PEG0_PE0_SHIFT  (0)
+#define SMU_SOFTRESET_CONTROL_RESET_PEG0_PE0_MASK   (0x00000001)
+#define SMU_SOFTRESET_CONTROL_RESET_PEG0_PE1_SHIFT  (1)
+#define SMU_SOFTRESET_CONTROL_RESET_PEG0_PE1_MASK   (0x00000002)
+#define SMU_SOFTRESET_CONTROL_RESET_PEG0_PE2_SHIFT  (2)
+#define SMU_SOFTRESET_CONTROL_RESET_PEG0_PE2_MASK   (0x00000004)
+#define SMU_SOFTRESET_CONTROL_RESET_PEG0_PE3_SHIFT  (3)
+#define SMU_SOFTRESET_CONTROL_RESET_PEG0_PE3_MASK   (0x00000008)
+#define SMU_SOFTRESET_CONTROL_RESET_PEG1_PE0_SHIFT  (8)
+#define SMU_SOFTRESET_CONTROL_RESET_PEG1_PE0_MASK   (0x00000100)
+#define SMU_SOFTRESET_CONTROL_RESET_PEG1_PE1_SHIFT  (9)
+#define SMU_SOFTRESET_CONTROL_RESET_PEG1_PE1_MASK   (0x00000200)
+#define SMU_SOFTRESET_CONTROL_RESET_PEG1_PE2_SHIFT  (10)
+#define SMU_SOFTRESET_CONTROL_RESET_PEG1_PE2_MASK   (0x00000400)
+#define SMU_SOFTRESET_CONTROL_RESET_PEG1_PE3_SHIFT  (11)
+#define SMU_SOFTRESET_CONTROL_RESET_PEG1_PE3_MASK   (0x00000800)
+
+#define SMU_RESET_PROTOCOL_ENGINE(peg, pe) \
+	((1 << (pe)) << ((peg) * 8))
+
+#define SMU_RESET_PEG_PROTOCOL_ENGINES(peg) \
+	(\
+		SMU_RESET_PROTOCOL_ENGINE(peg, 0) \
+		| SMU_RESET_PROTOCOL_ENGINE(peg, 1) \
+		| SMU_RESET_PROTOCOL_ENGINE(peg, 2) \
+		| SMU_RESET_PROTOCOL_ENGINE(peg, 3) \
+	)
+
+#define SMU_RESET_ALL_PROTOCOL_ENGINES() \
+	(\
+		SMU_RESET_PEG_PROTOCOL_ENGINES(0) \
+		| SMU_RESET_PEG_PROTOCOL_ENGINES(1) \
+	)
+
+#define SMU_SOFTRESET_CONTROL_RESET_WIDE_PORT_PEG0_LP0_SHIFT  (16)
+#define SMU_SOFTRESET_CONTROL_RESET_WIDE_PORT_PEG0_LP0_MASK   (0x00010000)
+#define SMU_SOFTRESET_CONTROL_RESET_WIDE_PORT_PEG0_LP2_SHIFT  (17)
+#define SMU_SOFTRESET_CONTROL_RESET_WIDE_PORT_PEG0_LP2_MASK   (0x00020000)
+#define SMU_SOFTRESET_CONTROL_RESET_WIDE_PORT_PEG1_LP0_SHIFT  (18)
+#define SMU_SOFTRESET_CONTROL_RESET_WIDE_PORT_PEG1_LP0_MASK   (0x00040000)
+#define SMU_SOFTRESET_CONTROL_RESET_WIDE_PORT_PEG1_LP2_SHIFT  (19)
+#define SMU_SOFTRESET_CONTROL_RESET_WIDE_PORT_PEG1_LP2_MASK   (0x00080000)
+
+#define SMU_RESET_WIDE_PORT_QUEUE(peg, wide_port) \
+	((1 << ((wide_port) / 2)) << ((peg) * 2) << 16)
+
+#define SMU_SOFTRESET_CONTROL_RESET_PEG0_SHIFT      (20)
+#define SMU_SOFTRESET_CONTROL_RESET_PEG0_MASK       (0x00100000)
+#define SMU_SOFTRESET_CONTROL_RESET_PEG1_SHIFT      (21)
+#define SMU_SOFTRESET_CONTROL_RESET_PEG1_MASK       (0x00200000)
+#define SMU_SOFTRESET_CONTROL_RESET_SCU_SHIFT       (22)
+#define SMU_SOFTRESET_CONTROL_RESET_SCU_MASK        (0x00400000)
+
+/*
+ * It seems to make sense that if you are going to reset the protocol
+ * engine group that you would also reset all of the protocol engines */
+#define SMU_RESET_PROTOCOL_ENGINE_GROUP(peg) \
+	(\
+		(1 << ((peg) + 20)) \
+		| SMU_RESET_WIDE_PORT_QUEUE(peg, 0) \
+		| SMU_RESET_WIDE_PORT_QUEUE(peg, 1) \
+		| SMU_RESET_PEG_PROTOCOL_ENGINES(peg) \
+	)
+
+#define SMU_RESET_ALL_PROTOCOL_ENGINE_GROUPS() \
+	(\
+		SMU_RESET_PROTOCOL_ENGINE_GROUP(0) \
+		| SMU_RESET_PROTOCOL_ENGINE_GROUP(1) \
+	)
+
+#define SMU_RESET_SCU()  (0xFFFFFFFF)
+
+
+
+/* ***************************************************************************** */
+#define SMU_TASK_CONTEXT_ASSIGNMENT_STARTING_SHIFT              (0)
+#define SMU_TASK_CONTEXT_ASSIGNMENT_STARTING_MASK               (0x00000FFF)
+#define SMU_TASK_CONTEXT_ASSIGNMENT_ENDING_SHIFT                (16)
+#define SMU_TASK_CONTEXT_ASSIGNMENT_ENDING_MASK                 (0x0FFF0000)
+#define SMU_TASK_CONTEXT_ASSIGNMENT_RANGE_CHECK_ENABLE_SHIFT    (31)
+#define SMU_TASK_CONTEXT_ASSIGNMENT_RANGE_CHECK_ENABLE_MASK     (0x80000000)
+#define SMU_TASK_CONTEXT_ASSIGNMENT_RESERVED_MASK               (0x7000F000)
+
+#define SMU_TCA_GEN_VAL(name, value) \
+	SCU_GEN_VALUE(SMU_TASK_CONTEXT_ASSIGNMENT_ ## name, value)
+
+#define SMU_TCA_GEN_BIT(name) \
+	SCU_GEN_BIT(SMU_TASK_CONTEXT_ASSIGNMENT_ ## name)
+
+/* ***************************************************************************** */
+#define SCU_SDMA_UNSOLICITED_FRAME_QUEUE_CONTROL_QUEUE_SIZE_SHIFT   (0)
+#define SCU_SDMA_UNSOLICITED_FRAME_QUEUE_CONTROL_QUEUE_SIZE_MASK    (0x00000FFF)
+#define SCU_SDMA_UNSOLICITED_FRAME_QUEUE_CONTROL_RESERVED_MASK      (0xFFFFF000)
+
+#define SCU_UFQC_GEN_VAL(name, value) \
+	SCU_GEN_VALUE(SCU_SDMA_UNSOLICITED_FRAME_QUEUE_CONTROL_ ## name, value)
+
+#define SCU_UFQC_QUEUE_SIZE_SET(value) \
+	SCU_UFQC_GEN_VAL(QUEUE_SIZE, value)
+
+/* ***************************************************************************** */
+#define SCU_SDMA_UNSOLICITED_FRAME_QUEUE_PUT_POINTER_SHIFT      (0)
+#define SCU_SDMA_UNSOLICITED_FRAME_QUEUE_PUT_POINTER_MASK       (0x00000FFF)
+#define SCU_SDMA_UNSOLICITED_FRAME_QUEUE_PUT_CYCLE_BIT_SHIFT    (12)
+#define SCU_SDMA_UNSOLICITED_FRAME_QUEUE_PUT_CYCLE_BIT_MASK     (0x00001000)
+#define SCU_SDMA_UNSOLICITED_FRAME_QUEUE_PUT_RESERVED_MASK      (0xFFFFE000)
+
+#define SCU_UFQPP_GEN_VAL(name, value) \
+	SCU_GEN_VALUE(SCU_SDMA_UNSOLICITED_FRAME_QUEUE_PUT_ ## name, value)
+
+#define SCU_UFQPP_GEN_BIT(name)	\
+	SCU_GEN_BIT(SCU_SDMA_UNSOLICITED_FRAME_QUEUE_PUT_ ## name)
+
+/*
+ * *****************************************************************************
+ * * SDMA Registers
+ * ***************************************************************************** */
+#define SCU_SDMA_UNSOLICITED_FRAME_QUEUE_GET_POINTER_SHIFT      (0)
+#define SCU_SDMA_UNSOLICITED_FRAME_QUEUE_GET_POINTER_MASK       (0x00000FFF)
+#define SCU_SDMA_UNSOLICITED_FRAME_QUEUE_GET_CYCLE_BIT_SHIFT    (12)
+#define SCU_SDMA_UNSOLICITED_FRAME_QUEUE_GET_CYCLE_BIT_MASK     (12)
+#define SCU_SDMA_UNSOLICITED_FRAME_QUEUE_GET_ENABLE_BIT_SHIFT   (31)
+#define SCU_SDMA_UNSOLICITED_FRAME_QUEUE_GET_ENABLE_BIT_MASK    (0x80000000)
+#define SCU_SDMA_UNSOLICITED_FRAME_QUEUE_GET_RESERVED_MASK      (0x7FFFE000)
+
+#define SCU_UFQGP_GEN_VAL(name, value) \
+	SCU_GEN_VALUE(SCU_SDMA_UNSOLICITED_FRAME_QUEUE_GET_ ## name, value)
+
+#define SCU_UFQGP_GEN_BIT(name)	\
+	SCU_GEN_BIT(SCU_SDMA_UNSOLICITED_FRAME_QUEUE_GET_ ## name)
+
+#define SCU_UFQGP_CYCLE_BIT(value) \
+	SCU_UFQGP_GEN_BIT(CYCLE_BIT, value)
+
+#define SCU_UFQGP_GET_POINTER(value) \
+	SCU_UFQGP_GEN_VALUE(POINTER, value)
+
+#define SCU_UFQGP_ENABLE(value)	\
+	(SCU_UFQGP_GEN_BIT(ENABLE) | value)
+
+#define SCU_UFQGP_DISABLE(value) \
+	(~SCU_UFQGP_GEN_BIT(ENABLE) & value)
+
+#define SCU_UFQGP_VALUE(bit, value) \
+	(SCU_UFQGP_CYCLE_BIT(bit) | SCU_UFQGP_GET_POINTER(value))
+
+/* ***************************************************************************** */
+#define SCU_PDMA_CONFIGURATION_ADDRESS_MODIFIER_SHIFT                               (0)
+#define SCU_PDMA_CONFIGURATION_ADDRESS_MODIFIER_MASK                                (0x0000FFFF)
+#define SCU_PDMA_CONFIGURATION_PCI_RELAXED_ORDERING_ENABLE_SHIFT                    (16)
+#define SCU_PDMA_CONFIGURATION_PCI_RELAXED_ORDERING_ENABLE_MASK                     (0x00010000)
+#define SCU_PDMA_CONFIGURATION_PCI_NO_SNOOP_ENABLE_SHIFT                            (17)
+#define SCU_PDMA_CONFIGURATION_PCI_NO_SNOOP_ENABLE_MASK                             (0x00020000)
+#define SCU_PDMA_CONFIGURATION_BIG_ENDIAN_CONTROL_BYTE_SWAP_SHIFT                   (18)
+#define SCU_PDMA_CONFIGURATION_BIG_ENDIAN_CONTROL_BYTE_SWAP_MASK                    (0x00040000)
+#define SCU_PDMA_CONFIGURATION_BIG_ENDIAN_CONTROL_XPI_SGL_FETCH_SHIFT               (19)
+#define SCU_PDMA_CONFIGURATION_BIG_ENDIAN_CONTROL_XPI_SGL_FETCH_MASK                (0x00080000)
+#define SCU_PDMA_CONFIGURATION_BIG_ENDIAN_CONTROL_XPI_RX_HEADER_RAM_WRITE_SHIFT     (20)
+#define SCU_PDMA_CONFIGURATION_BIG_ENDIAN_CONTROL_XPI_RX_HEADER_RAM_WRITE_MASK      (0x00100000)
+#define SCU_PDMA_CONFIGURATION_BIG_ENDIAN_CONTROL_XPI_UF_ADDRESS_FETCH_SHIFT        (21)
+#define SCU_PDMA_CONFIGURATION_BIG_ENDIAN_CONTROL_XPI_UF_ADDRESS_FETCH_MASK         (0x00200000)
+#define SCU_PDMA_CONFIGURATION_ADDRESS_MODIFIER_SELECT_SHIFT                        (22)
+#define SCU_PDMA_CONFIGURATION_ADDRESS_MODIFIER_SELECT_MASK                         (0x00400000)
+#define SCU_PDMA_CONFIGURATION_RESERVED_MASK                                        (0xFF800000)
+
+#define SCU_PDMACR_GEN_VALUE(name, value) \
+	SCU_GEN_VALUE(SCU_PDMA_CONFIGURATION_ ## name, value)
+
+#define SCU_PDMACR_GEN_BIT(name) \
+	SCU_GEN_BIT(SCU_PDMA_CONFIGURATION_ ## name)
+
+#define SCU_PDMACR_BE_GEN_BIT(name) \
+	SCU_PCMACR_GEN_BIT(BIG_ENDIAN_CONTROL_ ## name)
+
+/* ***************************************************************************** */
+#define SCU_CDMA_CONFIGURATION_PCI_RELAXED_ORDERING_ENABLE_SHIFT                    (8)
+#define SCU_CDMA_CONFIGURATION_PCI_RELAXED_ORDERING_ENABLE_MASK                     (0x00000100)
+
+#define SCU_CDMACR_GEN_BIT(name) \
+	SCU_GEN_BIT(SCU_CDMA_CONFIGURATION_ ## name)
+
+/*
+ * *****************************************************************************
+ * * SCU Link Layer Registers
+ * ***************************************************************************** */
+#define SCU_LINK_LAYER_SPEED_NEGOTIATION_TIMER_VALUES_TIMEOUT_SHIFT             (0)
+#define SCU_LINK_LAYER_SPEED_NEGOTIATION_TIMER_VALUES_TIMEOUT_MASK              (0x000000FF)
+#define SCU_LINK_LAYER_SPEED_NEGOTIATION_TIMER_VALUES_LOCK_TIME_SHIFT           (8)
+#define SCU_LINK_LAYER_SPEED_NEGOTIATION_TIMER_VALUES_LOCK_TIME_MASK            (0x0000FF00)
+#define SCU_LINK_LAYER_SPEED_NEGOTIATION_TIMER_VALUES_RATE_CHANGE_DELAY_SHIFT   (16)
+#define SCU_LINK_LAYER_SPEED_NEGOTIATION_TIMER_VALUES_RATE_CHANGE_DELAY_MASK    (0x00FF0000)
+#define SCU_LINK_LAYER_SPEED_NEGOTIATION_TIMER_VALUES_DWORD_SYNC_TIMEOUT_SHIFT  (24)
+#define SCU_LINK_LAYER_SPEED_NEGOTIATION_TIMER_VALUES_DWORD_SYNC_TIMEOUT_MASK   (0xFF000000)
+#define SCU_LINK_LAYER_SPEED_NECGOIATION_TIMER_VALUES_REQUIRED_MASK             (0x00000000)
+#define SCU_LINK_LAYER_SPEED_NECGOIATION_TIMER_VALUES_DEFAULT_MASK              (0x7D00676F)
+#define SCU_LINK_LAYER_SPEED_NECGOIATION_TIMER_VALUES_RESERVED_MASK             (0x00FF0000)
+
+#define SCU_SAS_SPDTOV_GEN_VALUE(name, value) \
+	SCU_GEN_VALUE(SCU_LINK_LAYER_SPEED_NEGOTIATION_TIMER_VALUES_ ## name, value)
+
+
+#define SCU_LINK_STATUS_DWORD_SYNC_AQUIRED_SHIFT            (2)
+#define SCU_LINK_STATUS_DWORD_SYNC_AQUIRED_MASK             (0x00000004)
+#define SCU_LINK_STATUS_TRANSMIT_PORT_SELECTION_DONE_SHIFT  (4)
+#define SCU_LINK_STATUS_TRANSMIT_PORT_SELECTION_DONE_MASK   (0x00000010)
+#define SCU_LINK_STATUS_RECEIVER_CREDIT_EXHAUSTED_SHIFT     (5)
+#define SCU_LINK_STATUS_RECEIVER_CREDIT_EXHAUSTED_MASK      (0x00000020)
+#define SCU_LINK_STATUS_RESERVED_MASK                       (0xFFFFFFCD)
+
+#define SCU_SAS_LLSTA_GEN_BIT(name) \
+	SCU_GEN_BIT(SCU_LINK_STATUS_ ## name)
+
+
+/* TODO: Where is the SATA_PSELTOV register? */
+
+/*
+ * *****************************************************************************
+ * * SCU SAS Maximum Arbitration Wait Time Timeout Register
+ * ***************************************************************************** */
+#define SCU_SAS_MAX_ARBITRATION_WAIT_TIME_TIMEOUT_VALUE_SHIFT       (0)
+#define SCU_SAS_MAX_ARBITRATION_WAIT_TIME_TIMEOUT_VALUE_MASK        (0x00007FFF)
+#define SCU_SAS_MAX_ARBITRATION_WAIT_TIME_TIMEOUT_SCALE_SHIFT       (15)
+#define SCU_SAS_MAX_ARBITRATION_WAIT_TIME_TIMEOUT_SCALE_MASK        (0x00008000)
+
+#define SCU_SAS_MAWTTOV_GEN_VALUE(name, value) \
+	SCU_GEN_VALUE(SCU_SAS_MAX_ARBITRATION_WAIT_TIME_TIMEOUT_ ## name, value)
+
+#define SCU_SAS_MAWTTOV_GEN_BIT(name) \
+	SCU_GEN_BIT(SCU_SAS_MAX_ARBITRATION_WAIT_TIME_TIMEOUT_ ## name)
+
+
+/*
+ * TODO: Where is the SAS_LNKTOV regsiter?
+ * TODO: Where is the SAS_PHYTOV register? */
+
+#define SCU_SAS_TRANSMIT_IDENTIFICATION_SMP_TARGET_SHIFT            (1)
+#define SCU_SAS_TRANSMIT_IDENTIFICATION_SMP_TARGET_MASK             (0x00000002)
+#define SCU_SAS_TRANSMIT_IDENTIFICATION_STP_TARGET_SHIFT            (2)
+#define SCU_SAS_TRANSMIT_IDENTIFICATION_STP_TARGET_MASK             (0x00000004)
+#define SCU_SAS_TRANSMIT_IDENTIFICATION_SSP_TARGET_SHIFT            (3)
+#define SCU_SAS_TRANSMIT_IDENTIFICATION_SSP_TARGET_MASK             (0x00000008)
+#define SCU_SAS_TRANSMIT_IDENTIFICATION_DA_SATA_HOST_SHIFT          (8)
+#define SCU_SAS_TRANSMIT_IDENTIFICATION_DA_SATA_HOST_MASK           (0x00000100)
+#define SCU_SAS_TRANSMIT_IDENTIFICATION_SMP_INITIATOR_SHIFT         (9)
+#define SCU_SAS_TRANSMIT_IDENTIFICATION_SMP_INITIATOR_MASK          (0x00000200)
+#define SCU_SAS_TRANSMIT_IDENTIFICATION_STP_INITIATOR_SHIFT         (10)
+#define SCU_SAS_TRANSMIT_IDENTIFICATION_STP_INITIATOR_MASK          (0x00000400)
+#define SCU_SAS_TRANSMIT_IDENTIFICATION_SSP_INITIATOR_SHIFT         (11)
+#define SCU_SAS_TRANSMIT_IDENTIFICATION_SSP_INITIATOR_MASK          (0x00000800)
+#define SCU_SAS_TRANSMIT_IDENTIFICATION_REASON_CODE_SHIFT           (16)
+#define SCU_SAS_TRANSMIT_IDENTIFICATION_REASON_CODE_MASK            (0x000F0000)
+#define SCU_SAS_TRANSMIT_IDENTIFICATION_ADDRESS_FRAME_TYPE_SHIFT    (24)
+#define SCU_SAS_TRANSMIT_IDENTIFICATION_ADDRESS_FRAME_TYPE_MASK     (0x0F000000)
+#define SCU_SAS_TRANSMIT_IDENTIFICATION_DEVICE_TYPE_SHIFT           (28)
+#define SCU_SAS_TRANSMIT_IDENTIFICATION_DEVICE_TYPE_MASK            (0x70000000)
+#define SCU_SAS_TRANSMIT_IDENTIFICATION_RESERVED_MASK               (0x80F0F1F1)
+
+#define SCU_SAS_TIID_GEN_VAL(name, value) \
+	SCU_GEN_VALUE(SCU_SAS_TRANSMIT_IDENTIFICATION_ ## name, value)
+
+#define SCU_SAS_TIID_GEN_BIT(name) \
+	SCU_GEN_BIT(SCU_SAS_TRANSMIT_IDENTIFICATION_ ## name)
+
+/* SAS Identify Frame PHY Identifier Register */
+#define SCU_LINK_LAYER_IDENTIFY_FRAME_PHY_IDENTIFIER_BREAK_REPLY_CAPABLE_SHIFT      (16)
+#define SCU_LINK_LAYER_IDENTIFY_FRAME_PHY_IDENTIFIER_BREAK_REPLY_CAPABLE_MASK       (0x00010000)
+#define SCU_LINK_LAYER_IDENTIFY_FRAME_PHY_IDENTIFIER_REQUESTED_INSIDE_ZPSDS_SHIFT   (17)
+#define SCU_LINK_LAYER_IDENTIFY_FRAME_PHY_IDENTIFIER_REQUESTED_INSIDE_ZPSDS_MASK    (0x00020000)
+#define SCU_LINK_LAYER_IDENTIFY_FRAME_PHY_IDENTIFIER_INSIDE_ZPSDS_PERSISTENT_SHIFT  (18)
+#define SCU_LINK_LAYER_IDENTIFY_FRAME_PHY_IDENTIFIER_INSIDE_ZPSDS_PERSISTENT_MASK   (0x00040000)
+#define SCU_LINK_LAYER_IDENTIFY_FRAME_PHY_IDENTIFIER_ID_SHIFT                       (24)
+#define SCU_LINK_LAYER_IDENTIFY_FRAME_PHY_IDENTIFIER_ID_MASK                        (0xFF000000)
+#define SCU_LINK_LAYER_IDENTIFY_FRAME_PHY_IDENTIFIER_RESERVED_MASK                  (0x00F800FF)
+
+#define SCU_SAS_TIPID_GEN_VALUE(name, value) \
+	SCU_GEN_VALUE(SCU_LINK_LAYER_IDENTIFY_FRAME_PHY_IDENTIFIER_ ## name, value)
+
+#define SCU_SAS_TIPID_GEN_BIT(name) \
+	SCU_GEN_BIT(SCU_LINK_LAYER_IDENTIFY_FRAME_PHY_IDENTIFIER_ ## name)
+
+
+#define SCU_SAS_PHY_CONFIGURATION_TX_PARITY_CHECK_SHIFT                     (4)
+#define SCU_SAS_PHY_CONFIGURATION_TX_PARITY_CHECK_MASK                      (0x00000010)
+#define SCU_SAS_PHY_CONFIGURATION_TX_BAD_CRC_SHIFT                          (6)
+#define SCU_SAS_PHY_CONFIGURATION_TX_BAD_CRC_MASK                           (0x00000040)
+#define SCU_SAS_PHY_CONFIGURATION_DISABLE_SCRAMBLER_SHIFT                   (7)
+#define SCU_SAS_PHY_CONFIGURATION_DISABLE_SCRAMBLER_MASK                    (0x00000080)
+#define SCU_SAS_PHY_CONFIGURATION_DISABLE_DESCRAMBLER_SHIFT                 (8)
+#define SCU_SAS_PHY_CONFIGURATION_DISABLE_DESCRAMBLER_MASK                  (0x00000100)
+#define SCU_SAS_PHY_CONFIGURATION_DISABLE_CREDIT_INSERTION_SHIFT            (9)
+#define SCU_SAS_PHY_CONFIGURATION_DISABLE_CREDIT_INSERTION_MASK             (0x00000200)
+#define SCU_SAS_PHY_CONFIGURATION_SUSPEND_PROTOCOL_ENGINE_SHIFT             (11)
+#define SCU_SAS_PHY_CONFIGURATION_SUSPEND_PROTOCOL_ENGINE_MASK              (0x00000800)
+#define SCU_SAS_PHY_CONFIGURATION_SATA_SPINUP_HOLD_SHIFT                    (12)
+#define SCU_SAS_PHY_CONFIGURATION_SATA_SPINUP_HOLD_MASK                     (0x00001000)
+#define SCU_SAS_PHY_CONFIGURATION_TRANSMIT_PORT_SELECTION_SIGNAL_SHIFT      (13)
+#define SCU_SAS_PHY_CONFIGURATION_TRANSMIT_PORT_SELECTION_SIGNAL_MASK       (0x00002000)
+#define SCU_SAS_PHY_CONFIGURATION_HARD_RESET_SHIFT                          (14)
+#define SCU_SAS_PHY_CONFIGURATION_HARD_RESET_MASK                           (0x00004000)
+#define SCU_SAS_PHY_CONFIGURATION_OOB_ENABLE_SHIFT                          (15)
+#define SCU_SAS_PHY_CONFIGURATION_OOB_ENABLE_MASK                           (0x00008000)
+#define SCU_SAS_PHY_CONFIGURATION_ENABLE_FRAME_TX_INSERT_ALIGN_SHIFT        (23)
+#define SCU_SAS_PHY_CONFIGURATION_ENABLE_FRAME_TX_INSERT_ALIGN_MASK         (0x00800000)
+#define SCU_SAS_PHY_CONFIGURATION_FORWARD_IDENTIFY_FRAME_SHIFT              (27)
+#define SCU_SAS_PHY_CONFIGURATION_FORWARD_IDENTIFY_FRAME_MASK               (0x08000000)
+#define SCU_SAS_PHY_CONFIGURATION_DISABLE_BYTE_TRANSPOSE_STP_FRAME_SHIFT    (28)
+#define SCU_SAS_PHY_CONFIGURATION_DISABLE_BYTE_TRANSPOSE_STP_FRAME_MASK     (0x10000000)
+#define SCU_SAS_PHY_CONFIGURATION_OOB_RESET_SHIFT                           (29)
+#define SCU_SAS_PHY_CONFIGURATION_OOB_RESET_MASK                            (0x20000000)
+#define SCU_SAS_PHY_CONFIGURATION_THREE_IAF_ENABLE_SHIFT                    (30)
+#define SCU_SAS_PHY_CONFIGURATION_THREE_IAF_ENABLE_MASK                     (0x40000000)
+#define SCU_SAS_PHY_CONFIGURATION_OOB_ALIGN0_ENABLE_SHIFT                   (31)
+#define SCU_SAS_PHY_CONFIGURATION_OOB_ALIGN0_ENABLE_MASK                    (0x80000000)
+#define SCU_SAS_PHY_CONFIGURATION_REQUIRED_MASK                             (0x0100000F)
+#define SCU_SAS_PHY_CONFIGURATION_DEFAULT_MASK                              (0x4180100F)
+#define SCU_SAS_PHY_CONFIGURATION_RESERVED_MASK                             (0x00000000)
+
+#define SCU_SAS_PCFG_GEN_BIT(name) \
+	SCU_GEN_BIT(SCU_SAS_PHY_CONFIGURATION_ ## name)
+
+#define SCU_LINK_LAYER_ALIGN_INSERTION_FREQUENCY_GENERAL_SHIFT      (0)
+#define SCU_LINK_LAYER_ALIGN_INSERTION_FREQUENCY_GENERAL_MASK       (0x000007FF)
+#define SCU_LINK_LAYER_ALIGN_INSERTION_FREQUENCY_CONNECTED_SHIFT    (16)
+#define SCU_LINK_LAYER_ALIGN_INSERTION_FREQUENCY_CONNECTED_MASK     (0x00ff0000)
+
+#define SCU_ALIGN_INSERTION_FREQUENCY_GEN_VAL(name, value) \
+	SCU_GEN_VALUE(SCU_LINK_LAYER_ALIGN_INSERTION_FREQUENCY_##name, value)
+
+#define SCU_LINK_LAYER_ENABLE_SPINUP_CONTROL_COUNT_SHIFT    (0)
+#define SCU_LINK_LAYER_ENABLE_SPINUP_CONTROL_COUNT_MASK     (0x0003FFFF)
+#define SCU_LINK_LAYER_ENABLE_SPINUP_CONTROL_ENABLE_SHIFT   (31)
+#define SCU_LINK_LAYER_ENABLE_SPINUP_CONTROL_ENABLE_MASK    (0x80000000)
+#define SCU_LINK_LAYER_ENABLE_SPINUP_CONTROL_RESERVED_MASK  (0x7FFC0000)
+
+#define SCU_ENSPINUP_GEN_VAL(name, value) \
+	SCU_GEN_VALUE(SCU_LINK_LAYER_ENABLE_SPINUP_CONTROL_ ## name, value)
+
+#define SCU_ENSPINUP_GEN_BIT(name) \
+	SCU_GEN_BIT(SCU_LINK_LAYER_ENABLE_SPINUP_CONTROL_ ## name)
+
+
+#define SCU_LINK_LAYER_PHY_CAPABILITIES_TXSSCTYPE_SHIFT     (1)
+#define SCU_LINK_LAYER_PHY_CAPABILITIES_TXSSCTYPE_MASK      (0x00000002)
+#define SCU_LINK_LAYER_PHY_CAPABILITIES_RLLRATE_SHIFT       (4)
+#define SCU_LINK_LAYER_PHY_CAPABILITIES_RLLRATE_MASK        (0x000000F0)
+#define SCU_LINK_LAYER_PHY_CAPABILITIES_SWO15GBPS_SHIFT     (8)
+#define SCU_LINK_LAYER_PHY_CAPABILITIES_SWO15GBPS_MASK      (0x00000100)
+#define SCU_LINK_LAYER_PHY_CAPABILITIES_SW15GBPS_SHIFT      (9)
+#define SCU_LINK_LAYER_PHY_CAPABILITIES_SW15GBPS_MASK       (0x00000201)
+#define SCU_LINK_LAYER_PHY_CAPABILITIES_SWO30GBPS_SHIFT     (10)
+#define SCU_LINK_LAYER_PHY_CAPABILITIES_SWO30GBPS_MASK      (0x00000401)
+#define SCU_LINK_LAYER_PHY_CAPABILITIES_SW30GBPS_SHIFT      (11)
+#define SCU_LINK_LAYER_PHY_CAPABILITIES_SW30GBPS_MASK       (0x00000801)
+#define SCU_LINK_LAYER_PHY_CAPABILITIES_SWO60GBPS_SHIFT     (12)
+#define SCU_LINK_LAYER_PHY_CAPABILITIES_SWO60GBPS_MASK      (0x00001001)
+#define SCU_LINK_LAYER_PHY_CAPABILITIES_SW60GBPS_SHIFT      (13)
+#define SCU_LINK_LAYER_PHY_CAPABILITIES_SW60GBPS_MASK       (0x00002001)
+#define SCU_LINK_LAYER_PHY_CAPABILITIES_EVEN_PARITY_SHIFT   (31)
+#define SCU_LINK_LAYER_PHY_CAPABILITIES_EVEN_PARITY_MASK    (0x80000000)
+#define SCU_LINK_LAYER_PHY_CAPABILITIES_DEFAULT_MASK        (0x00003F01)
+#define SCU_LINK_LAYER_PHY_CAPABILITIES_REQUIRED_MASK       (0x00000001)
+#define SCU_LINK_LAYER_PHY_CAPABILITIES_RESERVED_MASK       (0x7FFFC00D)
+
+#define SCU_SAS_PHYCAP_GEN_VAL(name, value) \
+	SCU_GEN_VALUE(SCU_LINK_LAYER_PHY_CAPABILITIES_ ## name, value)
+
+#define SCU_SAS_PHYCAP_GEN_BIT(name) \
+	SCU_GEN_BIT(SCU_LINK_LAYER_PHY_CAPABILITIES_ ## name)
+
+
+#define SCU_LINK_LAYER_PHY_SOURCE_ZONE_GROUP_CONTROL_VIRTUAL_EXPANDER_PHY_ZONE_GROUP_SHIFT  (0)
+#define SCU_LINK_LAYER_PHY_SOURCE_ZONE_GROUP_CONTROL_VIRTUAL_EXPANDER_PHY_ZONE_GROUP_MASK   (0x000000FF)
+#define SCU_LINK_LAYER_PHY_SOURCE_ZONE_GROUP_CONTROL_INSIDE_SOURCE_ZONE_GROUP_SHIFT         (31)
+#define SCU_LINK_LAYER_PHY_SOURCE_ZONE_GROUP_CONTROL_INSIDE_SOURCE_ZONE_GROUP_MASK          (0x80000000)
+#define SCU_LINK_LAYER_PHY_SOURCE_ZONE_GROUP_CONTROL_RESERVED_MASK                          (0x7FFFFF00)
+
+#define SCU_PSZGCR_GEN_VAL(name, value)	\
+	SCU_GEN_VALUE(SCU_LINK_LAYER_PHY_SOURCE_ZONE_GROUP_CONTROL_ ## name, value)
+
+#define SCU_PSZGCR_GEN_BIT(name) \
+	SCU_GEN_BIT(SCU_LINK_LAYER_PHY_SOURCE_ZONE_GROUP_CONTROL_ ## name)
+
+#define SCU_PROTOCOL_ENGINE_GROUP_VIRTUAL_ZONING_EXPANDER_CONTROL_ZONE0_LOCKED_SHIFT        (1)
+#define SCU_PROTOCOL_ENGINE_GROUP_VIRTUAL_ZONING_EXPANDER_CONTROL_ZONE0_LOCKED_MASK         (0x00000002)
+#define SCU_PROTOCOL_ENGINE_GROUP_VIRTUAL_ZONING_EXPANDER_CONTROL_ZONE0_UPDATING_SHIFT      (2)
+#define SCU_PROTOCOL_ENGINE_GROUP_VIRTUAL_ZONING_EXPANDER_CONTROL_ZONE0_UPDATING_MASK       (0x00000004)
+#define SCU_PROTOCOL_ENGINE_GROUP_VIRTUAL_ZONING_EXPANDER_CONTROL_ZONE1_LOCKED_SHIFT        (4)
+#define SCU_PROTOCOL_ENGINE_GROUP_VIRTUAL_ZONING_EXPANDER_CONTROL_ZONE1_LOCKED_MASK         (0x00000010)
+#define SCU_PROTOCOL_ENGINE_GROUP_VIRTUAL_ZONING_EXPANDER_CONTROL_ZONE1_UPDATING_SHIFT      (5)
+#define SCU_PROTOCOL_ENGINE_GROUP_VIRTUAL_ZONING_EXPANDER_CONTROL_ZONE1_UPDATING_MASK       (0x00000020)
+#define SCU_PROTOCOL_ENGINE_GROUP_VIRTUAL_ZONING_EXPANDER_CONTROL_ZPT_ASSOCIATION_PE0_SHIFT (16)
+#define SCU_PROTOCOL_ENGINE_GROUP_VIRTUAL_ZONING_EXPANDER_CONTROL_ZPT_ASSOCIATION_PE0_MASK  (0x00030000)
+#define SCU_PROTOCOL_ENGINE_GROUP_VIRTUAL_ZONING_EXPANDER_CONTROL_AIP_ENABLE_PE0_SHIFT      (19)
+#define SCU_PROTOCOL_ENGINE_GROUP_VIRTUAL_ZONING_EXPANDER_CONTROL_AIP_ENABLE_PE0_MASK       (0x00080000)
+#define SCU_PROTOCOL_ENGINE_GROUP_VIRTUAL_ZONING_EXPANDER_CONTROL_ZPT_ASSOCIATION_PE1_SHIFT (20)
+#define SCU_PROTOCOL_ENGINE_GROUP_VIRTUAL_ZONING_EXPANDER_CONTROL_ZPT_ASSOCIATION_PE1_MASK  (0x00300000)
+#define SCU_PROTOCOL_ENGINE_GROUP_VIRTUAL_ZONING_EXPANDER_CONTROL_AIP_ENABLE_PE1_SHIFT      (23)
+#define SCU_PROTOCOL_ENGINE_GROUP_VIRTUAL_ZONING_EXPANDER_CONTROL_AIP_ENABLE_PE1_MASK       (0x00800000)
+#define SCU_PROTOCOL_ENGINE_GROUP_VIRTUAL_ZONING_EXPANDER_CONTROL_ZPT_ASSOCIATION_PE2_SHIFT (24)
+#define SCU_PROTOCOL_ENGINE_GROUP_VIRTUAL_ZONING_EXPANDER_CONTROL_ZPT_ASSOCIATION_PE2_MASK  (0x03000000)
+#define SCU_PROTOCOL_ENGINE_GROUP_VIRTUAL_ZONING_EXPANDER_CONTROL_AIP_ENABLE_PE2_SHIFT      (27)
+#define SCU_PROTOCOL_ENGINE_GROUP_VIRTUAL_ZONING_EXPANDER_CONTROL_AIP_ENABLE_PE2_MASK       (0x08000000)
+#define SCU_PROTOCOL_ENGINE_GROUP_VIRTUAL_ZONING_EXPANDER_CONTROL_ZPT_ASSOCIATION_PE3_SHIFT (28)
+#define SCU_PROTOCOL_ENGINE_GROUP_VIRTUAL_ZONING_EXPANDER_CONTROL_ZPT_ASSOCIATION_PE3_MASK  (0x30000000)
+#define SCU_PROTOCOL_ENGINE_GROUP_VIRTUAL_ZONING_EXPANDER_CONTROL_AIP_ENABLE_PE3_SHIFT      (31)
+#define SCU_PROTOCOL_ENGINE_GROUP_VIRTUAL_ZONING_EXPANDER_CONTROL_AIP_ENABLE_PE3_MASK       (0x80000000)
+#define SCU_PROTOCOL_ENGINE_GROUP_VIRTUAL_ZONING_EXPANDER_CONTROL_RESERVED_MASK             (0x4444FFC9)
+
+#define SCU_PEG_SCUVZECR_GEN_VAL(name, val) \
+	SCU_GEN_VALUE(SCU_PROTOCOL_ENGINE_GROUP_VIRTUAL_ZONING_EXPANDER_CONTROL_ ## name, val)
+
+#define SCU_PEG_SCUVZECR_GEN_BIT(name) \
+	SCU_GEN_BIT(SCU_PROTOCOL_ENGINE_GROUP_VIRTUAL_ZONING_EXPANDER_CONTROL_ ## name)
+
+
+/*
+ * *****************************************************************************
+ * * Port Task Scheduler registers shift and mask values
+ * ***************************************************************************** */
+#define SCU_PTSG_CONTROL_IT_NEXUS_TIMEOUT_SHIFT     (0)
+#define SCU_PTSG_CONTROL_IT_NEXUS_TIMEOUT_MASK      (0x0000FFFF)
+#define SCU_PTSG_CONTROL_TASK_TIMEOUT_SHIFT         (16)
+#define SCU_PTSG_CONTROL_TASK_TIMEOUT_MASK          (0x00FF0000)
+#define SCU_PTSG_CONTROL_PTSG_ENABLE_SHIFT          (24)
+#define SCU_PTSG_CONTROL_PTSG_ENABLE_MASK           (0x01000000)
+#define SCU_PTSG_CONTROL_ETM_ENABLE_SHIFT           (25)
+#define SCU_PTSG_CONTROL_ETM_ENABLE_MASK            (0x02000000)
+#define SCU_PTSG_CONTROL_DEFAULT_MASK               (0x00020002)
+#define SCU_PTSG_CONTROL_REQUIRED_MASK              (0x00000000)
+#define SCU_PTSG_CONTROL_RESERVED_MASK              (0xFC000000)
+
+#define SCU_PTSGCR_GEN_VAL(name, val) \
+	SCU_GEN_VALUE(SCU_PTSG_CONTROL_ ## name, val)
+
+#define SCU_PTSGCR_GEN_BIT(name) \
+	SCU_GEN_BIT(SCU_PTSG_CONTROL_ ## name)
+
+
+/* ***************************************************************************** */
+#define SCU_PTSG_REAL_TIME_CLOCK_SHIFT          (0)
+#define SCU_PTSG_REAL_TIME_CLOCK_MASK           (0x0000FFFF)
+#define SCU_PTSG_REAL_TIME_CLOCK_RESERVED_MASK  (0xFFFF0000)
+
+#define SCU_RTCR_GEN_VAL(name, val) \
+	SCU_GEN_VALUE(SCU_PTSG_ ## name, val)
+
+
+#define SCU_PTSG_REAL_TIME_CLOCK_CONTROL_PRESCALER_VALUE_SHIFT  (0)
+#define SCU_PTSG_REAL_TIME_CLOCK_CONTROL_PRESCALER_VALUE_MASK   (0x00FFFFFF)
+#define SCU_PTSG_REAL_TIME_CLOCK_CONTROL_RESERVED_MASK          (0xFF000000)
+
+#define SCU_RTCCR_GEN_VAL(name, val) \
+	SCU_GEN_VALUE(SCU_PTSG_REAL_TIME_CLOCK_CONTROL_ ## name, val)
+
+
+#define SCU_PTSG_PORT_TASK_SCHEDULER_CONTROL_SUSPEND_SHIFT  (0)
+#define SCU_PTSG_PORT_TASK_SCHEDULER_CONTROL_SUSPEND_MASK   (0x00000001)
+#define SCU_PTSG_PORT_TASK_SCHEDULER_CONTROL_ENABLE_SHIFT   (1)
+#define SCU_PTSG_PORT_TASK_SCHEDULER_CONTROL_ENABLE_MASK    (0x00000002)
+#define SCU_PTSG_PORT_TASK_SCHEDULER_CONTROL_RESERVED_MASK  (0xFFFFFFFC)
+
+#define SCU_PTSxCR_GEN_BIT(name) \
+	SCU_GEN_BIT(SCU_PTSG_PORT_TASK_SCHEDULER_CONTROL_ ## name)
+
+
+#define SCU_PTSG_PORT_TASK_SCHEDULER_STATUS_NEXT_RN_VALID_SHIFT             (0)
+#define SCU_PTSG_PORT_TASK_SCHEDULER_STATUS_NEXT_RN_VALID_MASK              (0x00000001)
+#define SCU_PTSG_PORT_TASK_SCHEDULER_STATUS_ACTIVE_RNSC_LIST_VALID_SHIFT    (1)
+#define SCU_PTSG_PORT_TASK_SCHEDULER_STATUS_ACTIVE_RNSC_LIST_VALID_MASK     (0x00000002)
+#define SCU_PTSG_PORT_TASK_SCHEDULER_STATUS_PTS_SUSPENDED_SHIFT             (2)
+#define SCU_PTSG_PORT_TASK_SCHEDULER_STATUS_PTS_SUSPENDED_MASK              (0x00000004)
+#define SCU_PTSG_PORT_TASK_SCHEDULER_STATUS_RESERVED_MASK                   (0xFFFFFFF8)
+
+#define SCU_PTSxSR_GEN_BIT(name) \
+	SCU_GEN_BIT(SCU_PTSG_PORT_TASK_SCHEDULER_STATUS_ ## name)
+
+
+/*
+ * *****************************************************************************
+ * * SGPIO Register shift and mask values
+ * ***************************************************************************** */
+#define SCU_SGPIO_CONTROL_SGPIO_ENABLE_SHIFT                    (0)
+#define SCU_SGPIO_CONTROL_SGPIO_ENABLE_MASK                     (0x00000001)
+#define SCU_SGPIO_CONTROL_SGPIO_SERIAL_CLOCK_SELECT_SHIFT       (1)
+#define SCU_SGPIO_CONTROL_SGPIO_SERIAL_CLOCK_SELECT_MASK        (0x00000002)
+#define SCU_SGPIO_CONTROL_SGPIO_SERIAL_SHIFT_WIDTH_SELECT_SHIFT (2)
+#define SCU_SGPIO_CONTROL_SGPIO_SERIAL_SHIFT_WIDTH_SELECT_MASK  (0x00000004)
+#define SCU_SGPIO_CONTROL_SGPIO_TEST_BIT_SHIFT                  (15)
+#define SCU_SGPIO_CONTROL_SGPIO_TEST_BIT_MASK                   (0x00008000)
+#define SCU_SGPIO_CONTROL_SGPIO_RESERVED_MASK                   (0xFFFF7FF8)
+
+#define SCU_SGICRx_GEN_BIT(name) \
+	SCU_GEN_BIT(SCU_SGPIO_CONTROL_SGPIO_ ## name)
+
+#define SCU_SGPIO_PROGRAMMABLE_BLINK_REGISTER_R0_SHIFT      (0)
+#define SCU_SGPIO_PROGRAMMABLE_BLINK_REGISTER_R0_MASK       (0x0000000F)
+#define SCU_SGPIO_PROGRAMMABLE_BLINK_REGISTER_R1_SHIFT      (4)
+#define SCU_SGPIO_PROGRAMMABLE_BLINK_REGISTER_R1_MASK       (0x000000F0)
+#define SCU_SGPIO_PROGRAMMABLE_BLINK_REGISTER_R2_SHIFT      (8)
+#define SCU_SGPIO_PROGRAMMABLE_BLINK_REGISTER_R2_MASK       (0x00000F00)
+#define SCU_SGPIO_PROGRAMMABLE_BLINK_REGISTER_R3_SHIFT      (12)
+#define SCU_SGPIO_PROGRAMMABLE_BLINK_REGISTER_R3_MASK       (0x0000F000)
+#define SCU_SGPIO_PROGRAMMABLE_BLINK_REGISTER_RESERVED_MASK (0xFFFF0000)
+
+#define SCU_SGPBRx_GEN_VAL(name, value)	\
+	SCU_GEN_VALUE(SCU_SGPIO_PROGRAMMABLE_BLINK_REGISTER_ ## name, value)
+
+#define SCU_SGPIO_START_DRIVE_LOWER_R0_SHIFT        (0)
+#define SCU_SGPIO_START_DRIVE_LOWER_R0_MASK         (0x00000003)
+#define SCU_SGPIO_START_DRIVE_LOWER_R1_SHIFT        (4)
+#define SCU_SGPIO_START_DRIVE_LOWER_R1_MASK         (0x00000030)
+#define SCU_SGPIO_START_DRIVE_LOWER_R2_SHIFT        (8)
+#define SCU_SGPIO_START_DRIVE_LOWER_R2_MASK         (0x00000300)
+#define SCU_SGPIO_START_DRIVE_LOWER_R3_SHIFT        (12)
+#define SCU_SGPIO_START_DRIVE_LOWER_R3_MASK         (0x00003000)
+#define SCU_SGPIO_START_DRIVE_LOWER_RESERVED_MASK   (0xFFFF8888)
+
+#define SCU_SGSDLRx_GEN_VAL(name, value) \
+	SCU_GEN_VALUE(SCU_SGPIO_START_DRIVE_LOWER_ ## name, value)
+
+#define SCU_SGPIO_START_DRIVE_UPPER_R0_SHIFT        (0)
+#define SCU_SGPIO_START_DRIVE_UPPER_R0_MASK         (0x00000003)
+#define SCU_SGPIO_START_DRIVE_UPPER_R1_SHIFT        (4)
+#define SCU_SGPIO_START_DRIVE_UPPER_R1_MASK         (0x00000030)
+#define SCU_SGPIO_START_DRIVE_UPPER_R2_SHIFT        (8)
+#define SCU_SGPIO_START_DRIVE_UPPER_R2_MASK         (0x00000300)
+#define SCU_SGPIO_START_DRIVE_UPPER_R3_SHIFT        (12)
+#define SCU_SGPIO_START_DRIVE_UPPER_R3_MASK         (0x00003000)
+#define SCU_SGPIO_START_DRIVE_UPPER_RESERVED_MASK   (0xFFFF8888)
+
+#define SCU_SGSDURx_GEN_VAL(name, value) \
+	SCU_GEN_VALUE(SCU_SGPIO_START_DRIVE_LOWER_ ## name, value)
+
+#define SCU_SGPIO_SERIAL_INPUT_DATA_LOWER_D0_SHIFT      (0)
+#define SCU_SGPIO_SERIAL_INPUT_DATA_LOWER_D0_MASK       (0x00000003)
+#define SCU_SGPIO_SERIAL_INPUT_DATA_LOWER_D1_SHIFT      (4)
+#define SCU_SGPIO_SERIAL_INPUT_DATA_LOWER_D1_MASK       (0x00000030)
+#define SCU_SGPIO_SERIAL_INPUT_DATA_LOWER_D2_SHIFT      (8)
+#define SCU_SGPIO_SERIAL_INPUT_DATA_LOWER_D2_MASK       (0x00000300)
+#define SCU_SGPIO_SERIAL_INPUT_DATA_LOWER_D3_SHIFT      (12)
+#define SCU_SGPIO_SERIAL_INPUT_DATA_LOWER_D3_MASK       (0x00003000)
+#define SCU_SGPIO_SERIAL_INPUT_DATA_LOWER_RESERVED_MASK (0xFFFF8888)
+
+#define SCU_SGSIDLRx_GEN_VAL(name, value) \
+	SCU_GEN_VALUE(SCU_SGPIO_SERIAL_INPUT_DATA_LOWER_ ## name, value)
+
+#define SCU_SGPIO_SERIAL_INPUT_DATA_UPPER_D0_SHIFT      (0)
+#define SCU_SGPIO_SERIAL_INPUT_DATA_UPPER_D0_MASK       (0x00000003)
+#define SCU_SGPIO_SERIAL_INPUT_DATA_UPPER_D1_SHIFT      (4)
+#define SCU_SGPIO_SERIAL_INPUT_DATA_UPPER_D1_MASK       (0x00000030)
+#define SCU_SGPIO_SERIAL_INPUT_DATA_UPPER_D2_SHIFT      (8)
+#define SCU_SGPIO_SERIAL_INPUT_DATA_UPPER_D2_MASK       (0x00000300)
+#define SCU_SGPIO_SERIAL_INPUT_DATA_UPPER_D3_SHIFT      (12)
+#define SCU_SGPIO_SERIAL_INPUT_DATA_UPPER_D3_MASK       (0x00003000)
+#define SCU_SGPIO_SERIAL_INPUT_DATA_UPPER_RESERVED_MASK (0xFFFF8888)
+
+#define SCU_SGSIDURx_GEN_VAL(name, value) \
+	SCU_GEN_VALUE(SCU_SGPIO_SERIAL_INPUT_DATA_LOWER_ ## name, value)
+
+#define SCU_SGPIO_VENDOR_SPECIFIC_CODE_SHIFT            (0)
+#define SCU_SGPIO_VENDOR_SPECIFIC_CODE_MASK             (0x0000000F)
+#define SCU_SGPIO_VENDOR_SPECIFIC_CODE_RESERVED_MASK    (0xFFFFFFF0)
+
+#define SCU_SGVSCR_GEN_VAL(value) \
+	SCU_GEN_VALUE(SCU_SGPIO_VENDOR_SPECIFIC_CODE ## name, value)
+
+#define SCU_SGPIO_OUPUT_DATA_SELECT_INPUT_DATA0_SHIFT           (0)
+#define SCU_SGPIO_OUPUT_DATA_SELECT_INPUT_DATA0_MASK            (0x00000003)
+#define SCU_SGPIO_OUPUT_DATA_SELECT_INVERT_INPUT_DATA0_SHIFT    (2)
+#define SCU_SGPIO_OUPUT_DATA_SELECT_INVERT_INPUT_DATA0_MASK     (0x00000004)
+#define SCU_SGPIO_OUPUT_DATA_SELECT_JOG_ENABLE_DATA0_SHIFT      (3)
+#define SCU_SGPIO_OUPUT_DATA_SELECT_JOG_ENABLE_DATA0_MASK       (0x00000008)
+#define SCU_SGPIO_OUPUT_DATA_SELECT_INPUT_DATA1_SHIFT           (4)
+#define SCU_SGPIO_OUPUT_DATA_SELECT_INPUT_DATA1_MASK            (0x00000030)
+#define SCU_SGPIO_OUPUT_DATA_SELECT_INVERT_INPUT_DATA1_SHIFT    (6)
+#define SCU_SGPIO_OUPUT_DATA_SELECT_INVERT_INPUT_DATA1_MASK     (0x00000040)
+#define SCU_SGPIO_OUPUT_DATA_SELECT_JOG_ENABLE_DATA1_SHIFT      (7)
+#define SCU_SGPIO_OUPUT_DATA_SELECT_JOG_ENABLE_DATA1_MASK       (0x00000080)
+#define SCU_SGPIO_OUPUT_DATA_SELECT_INPUT_DATA2_SHIFT           (8)
+#define SCU_SGPIO_OUPUT_DATA_SELECT_INPUT_DATA2_MASK            (0x00000300)
+#define SCU_SGPIO_OUPUT_DATA_SELECT_INVERT_INPUT_DATA2_SHIFT    (10)
+#define SCU_SGPIO_OUPUT_DATA_SELECT_INVERT_INPUT_DATA2_MASK     (0x00000400)
+#define SCU_SGPIO_OUPUT_DATA_SELECT_JOG_ENABLE_DATA2_SHIFT      (11)
+#define SCU_SGPIO_OUPUT_DATA_SELECT_JOG_ENABLE_DATA2_MASK       (0x00000800)
+#define SCU_SGPIO_OUPUT_DATA_SELECT_RESERVED_MASK               (0xFFFFF000)
+
+#define SCU_SGODSR_GEN_VAL(name, value)	\
+	SCU_GEN_VALUE(SCU_SGPIO_OUPUT_DATA_SELECT_ ## name, value)
+
+#define SCU_SGODSR_GEN_BIT(name) \
+	SCU_GEN_BIT(SCU_SGPIO_OUPUT_DATA_SELECT_ ## name)
+
+/*
+ * *****************************************************************************
+ * * SMU Registers
+ * ***************************************************************************** */
+
+/*
+ * ----------------------------------------------------------------------------
+ * SMU Registers
+ * These registers are based off of BAR0
+ *
+ * To calculate the offset for other functions use
+ *       BAR0 + FN# * SystemPageSize * 2
+ *
+ * The TCA is only accessable from FN#0 (Physical Function) and each
+ * is programmed by (BAR0 + SCU_SMU_TCA_OFFSET + (FN# * 0x04)) or
+ *    TCA0 for FN#0 is at BAR0 + 0x0400
+ *    TCA1 for FN#1 is at BAR0 + 0x0404
+ *    etc.
+ * ----------------------------------------------------------------------------
+ * Accessable to all FN#s */
+#define SCU_SMU_PCP_OFFSET          0x0000
+#define SCU_SMU_AMR_OFFSET          0x0004
+#define SCU_SMU_ISR_OFFSET          0x0010
+#define SCU_SMU_IMR_OFFSET          0x0014
+#define SCU_SMU_ICC_OFFSET          0x0018
+#define SCU_SMU_HTTLBAR_OFFSET      0x0020
+#define SCU_SMU_HTTUBAR_OFFSET      0x0024
+#define SCU_SMU_TCR_OFFSET          0x0028
+#define SCU_SMU_CQLBAR_OFFSET       0x0030
+#define SCU_SMU_CQUBAR_OFFSET       0x0034
+#define SCU_SMU_CQPR_OFFSET         0x0040
+#define SCU_SMU_CQGR_OFFSET         0x0044
+#define SCU_SMU_CQC_OFFSET          0x0048
+/* Accessable to FN#0 only */
+#define SCU_SMU_RNCLBAR_OFFSET      0x0080
+#define SCU_SMU_RNCUBAR_OFFSET      0x0084
+#define SCU_SMU_DCC_OFFSET          0x0090
+#define SCU_SMU_DFC_OFFSET          0x0094
+#define SCU_SMU_SMUCSR_OFFSET       0x0098
+#define SCU_SMU_SCUSRCR_OFFSET      0x009C
+#define SCU_SMU_SMAW_OFFSET         0x00A0
+#define SCU_SMU_SMDW_OFFSET         0x00A4
+/* Accessable to FN#0 only */
+#define SCU_SMU_TCA_OFFSET          0x0400
+/* Accessable to all FN#s */
+#define SCU_SMU_MT_MLAR0_OFFSET     0x2000
+#define SCU_SMU_MT_MUAR0_OFFSET     0x2004
+#define SCU_SMU_MT_MDR0_OFFSET      0x2008
+#define SCU_SMU_MT_VCR0_OFFSET      0x200C
+#define SCU_SMU_MT_MLAR1_OFFSET     0x2010
+#define SCU_SMU_MT_MUAR1_OFFSET     0x2014
+#define SCU_SMU_MT_MDR1_OFFSET      0x2018
+#define SCU_SMU_MT_VCR1_OFFSET      0x201C
+#define SCU_SMU_MPBA_OFFSET         0x3000
+
+/**
+ * struct smu_registers - These are the SMU registers
+ *
+ *
+ */
+struct smu_registers {
+/* 0x0000 PCP */
+	u32 post_context_port;
+/* 0x0004 AMR */
+	u32 address_modifier;
+	u32 reserved_08;
+	u32 reserved_0C;
+/* 0x0010 ISR */
+	u32 interrupt_status;
+/* 0x0014 IMR */
+	u32 interrupt_mask;
+/* 0x0018 ICC */
+	u32 interrupt_coalesce_control;
+	u32 reserved_1C;
+/* 0x0020 HTTLBAR */
+	u32 host_task_table_lower;
+/* 0x0024 HTTUBAR */
+	u32 host_task_table_upper;
+/* 0x0028 TCR */
+	u32 task_context_range;
+	u32 reserved_2C;
+/* 0x0030 CQLBAR */
+	u32 completion_queue_lower;
+/* 0x0034 CQUBAR */
+	u32 completion_queue_upper;
+	u32 reserved_38;
+	u32 reserved_3C;
+/* 0x0040 CQPR */
+	u32 completion_queue_put;
+/* 0x0044 CQGR */
+	u32 completion_queue_get;
+/* 0x0048 CQC */
+	u32 completion_queue_control;
+	u32 reserved_4C;
+	u32 reserved_5x[4];
+	u32 reserved_6x[4];
+	u32 reserved_7x[4];
+/*
+ * Accessable to FN#0 only
+ * 0x0080 RNCLBAR */
+	u32 remote_node_context_lower;
+/* 0x0084 RNCUBAR */
+	u32 remote_node_context_upper;
+	u32 reserved_88;
+	u32 reserved_8C;
+/* 0x0090 DCC */
+	u32 device_context_capacity;
+/* 0x0094 DFC */
+	u32 device_function_capacity;
+/* 0x0098 SMUCSR */
+	u32 control_status;
+/* 0x009C SCUSRCR */
+	u32 soft_reset_control;
+/* 0x00A0 SMAW */
+	u32 mmr_address_window;
+/* 0x00A4 SMDW */
+	u32 mmr_data_window;
+	u32 reserved_A8;
+	u32 reserved_AC;
+/* A whole bunch of reserved space */
+	u32 reserved_Bx[4];
+	u32 reserved_Cx[4];
+	u32 reserved_Dx[4];
+	u32 reserved_Ex[4];
+	u32 reserved_Fx[4];
+	u32 reserved_1xx[64];
+	u32 reserved_2xx[64];
+	u32 reserved_3xx[64];
+/*
+ * Accessable to FN#0 only
+ * 0x0400 TCA */
+	u32 task_context_assignment[256];
+/* MSI-X registers not included */
+};
+
+/*
+ * *****************************************************************************
+ * SDMA Registers
+ * ***************************************************************************** */
+#define SCU_SDMA_BASE               0x6000
+#define SCU_SDMA_PUFATLHAR_OFFSET   0x0000
+#define SCU_SDMA_PUFATUHAR_OFFSET   0x0004
+#define SCU_SDMA_UFLHBAR_OFFSET     0x0008
+#define SCU_SDMA_UFUHBAR_OFFSET     0x000C
+#define SCU_SDMA_UFQC_OFFSET        0x0010
+#define SCU_SDMA_UFQPP_OFFSET       0x0014
+#define SCU_SDMA_UFQGP_OFFSET       0x0018
+#define SCU_SDMA_PDMACR_OFFSET      0x001C
+#define SCU_SDMA_CDMACR_OFFSET      0x0080
+
+/**
+ * struct scu_sdma_registers - These are the SCU SDMA Registers
+ *
+ *
+ */
+struct scu_sdma_registers {
+/* 0x0000 PUFATLHAR */
+	u32 uf_address_table_lower;
+/* 0x0004 PUFATUHAR */
+	u32 uf_address_table_upper;
+/* 0x0008 UFLHBAR */
+	u32 uf_header_base_address_lower;
+/* 0x000C UFUHBAR */
+	u32 uf_header_base_address_upper;
+/* 0x0010 UFQC */
+	u32 unsolicited_frame_queue_control;
+/* 0x0014 UFQPP */
+	u32 unsolicited_frame_put_pointer;
+/* 0x0018 UFQGP */
+	u32 unsolicited_frame_get_pointer;
+/* 0x001C PDMACR */
+	u32 pdma_configuration;
+/* Reserved until offset 0x80 */
+	u32 reserved_0020_007C[0x18];
+/* 0x0080 CDMACR */
+	u32 cdma_configuration;
+/* Remainder SDMA register space */
+	u32 reserved_0084_0400[0xDF];
+
+};
+
+/*
+ * *****************************************************************************
+ * * SCU Link Registers
+ * ***************************************************************************** */
+#define SCU_PEG0_OFFSET    0x0000
+#define SCU_PEG1_OFFSET    0x8000
+
+#define SCU_TL0_OFFSET     0x0000
+#define SCU_TL1_OFFSET     0x0400
+#define SCU_TL2_OFFSET     0x0800
+#define SCU_TL3_OFFSET     0x0C00
+
+#define SCU_LL_OFFSET      0x0080
+#define SCU_LL0_OFFSET     (SCU_TL0_OFFSET + SCU_LL_OFFSET)
+#define SCU_LL1_OFFSET     (SCU_TL1_OFFSET + SCU_LL_OFFSET)
+#define SCU_LL2_OFFSET     (SCU_TL2_OFFSET + SCU_LL_OFFSET)
+#define SCU_LL3_OFFSET     (SCU_TL3_OFFSET + SCU_LL_OFFSET)
+
+/* Transport Layer Offsets (PEG + TL) */
+#define SCU_TLCR_OFFSET         0x0000
+#define SCU_TLADTR_OFFSET       0x0004
+#define SCU_TLTTMR_OFFSET       0x0008
+#define SCU_TLEECR0_OFFSET      0x000C
+#define SCU_STPTLDARNI_OFFSET   0x0010
+
+
+#define SCU_TLCR_HASH_SAS_CHECKING_ENABLE_SHIFT    (0)
+#define SCU_TLCR_HASH_SAS_CHECKING_ENABLE_MASK     (0x00000001)
+#define SCU_TLCR_CLEAR_TCI_NCQ_MAPPING_TABLE_SHIFT (1)
+#define SCU_TLCR_CLEAR_TCI_NCQ_MAPPING_TABLE_MASK  (0x00000002)
+#define SCU_TLCR_STP_WRITE_DATA_PREFETCH_SHIFT     (3)
+#define SCU_TLCR_STP_WRITE_DATA_PREFETCH_MASK      (0x00000008)
+#define SCU_TLCR_CMD_NAK_STATUS_CODE_SHIFT         (4)
+#define SCU_TLCR_CMD_NAK_STATUS_CODE_MASK          (0x00000010)
+#define SCU_TLCR_RESERVED_MASK                     (0xFFFFFFEB)
+
+#define SCU_TLCR_GEN_BIT(name) \
+	SCU_GEN_BIT(SCU_TLCR_ ## name)
+
+/**
+ * struct scu_transport_layer_registers - These are the SCU Transport Layer
+ *    registers
+ *
+ *
+ */
+struct scu_transport_layer_registers {
+	/* 0x0000 TLCR */
+	u32 control;
+	/* 0x0004 TLADTR */
+	u32 arbitration_delay_timer;
+	/* 0x0008 TLTTMR */
+	u32 timer_test_mode;
+	/* 0x000C reserved */
+	u32 reserved_0C;
+	/* 0x0010 STPTLDARNI */
+	u32 stp_rni;
+	/* 0x0014 TLFEWPORCTRL */
+	u32 tlfe_wpo_read_control;
+	/* 0x0018 TLFEWPORDATA */
+	u32 tlfe_wpo_read_data;
+	/* 0x001C RXTLSSCSR1 */
+	u32 rxtl_single_step_control_status_1;
+	/* 0x0020 RXTLSSCSR2 */
+	u32 rxtl_single_step_control_status_2;
+	/* 0x0024 AWTRDDCR */
+	u32 tlfe_awt_retry_delay_debug_control;
+	/* Remainder of TL memory space */
+	u32 reserved_0028_007F[0x16];
+
+};
+
+/* Protocol Engine Group Registers */
+#define SCU_SCUVZECRx_OFFSET        0x1080
+
+/* Link Layer Offsets (PEG + TL + LL) */
+#define SCU_SAS_SPDTOV_OFFSET       0x0000
+#define SCU_SAS_LLSTA_OFFSET        0x0004
+#define SCU_SATA_PSELTOV_OFFSET     0x0008
+#define SCU_SAS_TIMETOV_OFFSET      0x0010
+#define SCU_SAS_LOSTOT_OFFSET       0x0014
+#define SCU_SAS_LNKTOV_OFFSET       0x0018
+#define SCU_SAS_PHYTOV_OFFSET       0x001C
+#define SCU_SAS_AFERCNT_OFFSET      0x0020
+#define SCU_SAS_WERCNT_OFFSET       0x0024
+#define SCU_SAS_TIID_OFFSET         0x0028
+#define SCU_SAS_TIDNH_OFFSET        0x002C
+#define SCU_SAS_TIDNL_OFFSET        0x0030
+#define SCU_SAS_TISSAH_OFFSET       0x0034
+#define SCU_SAS_TISSAL_OFFSET       0x0038
+#define SCU_SAS_TIPID_OFFSET        0x003C
+#define SCU_SAS_TIRES2_OFFSET       0x0040
+#define SCU_SAS_ADRSTA_OFFSET       0x0044
+#define SCU_SAS_MAWTTOV_OFFSET      0x0048
+#define SCU_SAS_FRPLDFIL_OFFSET     0x0054
+#define SCU_SAS_RFCNT_OFFSET        0x0060
+#define SCU_SAS_TFCNT_OFFSET        0x0064
+#define SCU_SAS_RFDCNT_OFFSET       0x0068
+#define SCU_SAS_TFDCNT_OFFSET       0x006C
+#define SCU_SAS_LERCNT_OFFSET       0x0070
+#define SCU_SAS_RDISERRCNT_OFFSET   0x0074
+#define SCU_SAS_CRERCNT_OFFSET      0x0078
+#define SCU_STPCTL_OFFSET           0x007C
+#define SCU_SAS_PCFG_OFFSET         0x0080
+#define SCU_SAS_CLKSM_OFFSET        0x0084
+#define SCU_SAS_TXCOMWAKE_OFFSET    0x0088
+#define SCU_SAS_TXCOMINIT_OFFSET    0x008C
+#define SCU_SAS_TXCOMSAS_OFFSET     0x0090
+#define SCU_SAS_COMINIT_OFFSET      0x0094
+#define SCU_SAS_COMWAKE_OFFSET      0x0098
+#define SCU_SAS_COMSAS_OFFSET       0x009C
+#define SCU_SAS_SFERCNT_OFFSET      0x00A0
+#define SCU_SAS_CDFERCNT_OFFSET     0x00A4
+#define SCU_SAS_DNFERCNT_OFFSET     0x00A8
+#define SCU_SAS_PRSTERCNT_OFFSET    0x00AC
+#define SCU_SAS_CNTCTL_OFFSET       0x00B0
+#define SCU_SAS_SSPTOV_OFFSET       0x00B4
+#define SCU_FTCTL_OFFSET            0x00B8
+#define SCU_FRCTL_OFFSET            0x00BC
+#define SCU_FTWMRK_OFFSET           0x00C0
+#define SCU_ENSPINUP_OFFSET         0x00C4
+#define SCU_SAS_TRNTOV_OFFSET       0x00C8
+#define SCU_SAS_PHYCAP_OFFSET       0x00CC
+#define SCU_SAS_PHYCTL_OFFSET       0x00D0
+#define SCU_SAS_LLCTL_OFFSET        0x00D8
+#define SCU_AFE_XCVRCR_OFFSET       0x00DC
+#define SCU_AFE_LUTCR_OFFSET        0x00E0
+
+#define SCU_SAS_LINK_LAYER_CONTROL_MAX_LINK_RATE_SHIFT                  (0)
+#define SCU_SAS_LINK_LAYER_CONTROL_MAX_LINK_RATE_MASK                   (0x00000003)
+#define SCU_SAS_LINK_LAYER_CONTROL_MAX_LINK_RATE_GEN1                   (0)
+#define SCU_SAS_LINK_LAYER_CONTROL_MAX_LINK_RATE_GEN2                   (1)
+#define SCU_SAS_LINK_LAYER_CONTROL_MAX_LINK_RATE_GEN3                   (2)
+#define SCU_SAS_LINK_LAYER_CONTROL_BROADCAST_PRIMITIVE_SHIFT            (2)
+#define SCU_SAS_LINK_LAYER_CONTROL_BROADCAST_PRIMITIVE_MASK             (0x000003FC)
+#define SCU_SAS_LINK_LAYER_CONTROL_CLOSE_NO_ACTIVE_TASK_DISABLE_SHIFT   (16)
+#define SCU_SAS_LINK_LAYER_CONTROL_CLOSE_NO_ACTIVE_TASK_DISABLE_MASK    (0x00010000)
+#define SCU_SAS_LINK_LAYER_CONTROL_CLOSE_NO_OUTBOUND_TASK_DISABLE_SHIFT (17)
+#define SCU_SAS_LINK_LAYER_CONTROL_CLOSE_NO_OUTBOUND_TASK_DISABLE_MASK  (0x00020000)
+#define SCU_SAS_LINK_LAYER_CONTROL_NO_OUTBOUND_TASK_TIMEOUT_SHIFT       (24)
+#define SCU_SAS_LINK_LAYER_CONTROL_NO_OUTBOUND_TASK_TIMEOUT_MASK        (0xFF000000)
+#define SCU_SAS_LINK_LAYER_CONTROL_RESERVED                             (0x00FCFC00)
+
+#define SCU_SAS_LLCTL_GEN_VAL(name, value) \
+	SCU_GEN_VALUE(SCU_SAS_LINK_LAYER_CONTROL_ ## name, value)
+
+#define SCU_SAS_LLCTL_GEN_BIT(name) \
+	SCU_GEN_BIT(SCU_SAS_LINK_LAYER_CONTROL_ ## name)
+
+
+/* #define SCU_FRXHECR_DCNT_OFFSET      0x00B0 */
+#define SCU_PSZGCR_OFFSET           0x00E4
+#define SCU_SAS_RECPHYCAP_OFFSET    0x00E8
+/* #define SCU_TX_LUTSEL_OFFSET         0x00B8 */
+
+#define SCU_SAS_PTxC_OFFSET         0x00D4 /* Same offset as SAS_TCTSTM */
+
+/**
+ * struct scu_link_layer_registers - SCU Link Layer Registers
+ *
+ *
+ */
+struct scu_link_layer_registers {
+/* 0x0000 SAS_SPDTOV */
+	u32 speed_negotiation_timers;
+/* 0x0004 SAS_LLSTA */
+	u32 link_layer_status;
+/* 0x0008 SATA_PSELTOV */
+	u32 port_selector_timeout;
+	u32 reserved0C;
+/* 0x0010 SAS_TIMETOV */
+	u32 timeout_unit_value;
+/* 0x0014 SAS_RCDTOV */
+	u32 rcd_timeout;
+/* 0x0018 SAS_LNKTOV */
+	u32 link_timer_timeouts;
+/* 0x001C SAS_PHYTOV */
+	u32 sas_phy_timeouts;
+/* 0x0020 SAS_AFERCNT */
+	u32 received_address_frame_error_counter;
+/* 0x0024 SAS_WERCNT */
+	u32 invalid_dword_counter;
+/* 0x0028 SAS_TIID */
+	u32 transmit_identification;
+/* 0x002C SAS_TIDNH */
+	u32 sas_device_name_high;
+/* 0x0030 SAS_TIDNL */
+	u32 sas_device_name_low;
+/* 0x0034 SAS_TISSAH */
+	u32 source_sas_address_high;
+/* 0x0038 SAS_TISSAL */
+	u32 source_sas_address_low;
+/* 0x003C SAS_TIPID */
+	u32 identify_frame_phy_id;
+/* 0x0040 SAS_TIRES2 */
+	u32 identify_frame_reserved;
+/* 0x0044 SAS_ADRSTA */
+	u32 received_address_frame;
+/* 0x0048 SAS_MAWTTOV */
+	u32 maximum_arbitration_wait_timer_timeout;
+/* 0x004C SAS_PTxC */
+	u32 transmit_primitive;
+/* 0x0050 SAS_RORES */
+	u32 error_counter_event_notification_control;
+/* 0x0054 SAS_FRPLDFIL */
+	u32 frxq_payload_fill_threshold;
+/* 0x0058 SAS_LLHANG_TOT */
+	u32 link_layer_hang_detection_timeout;
+	u32 reserved_5C;
+/* 0x0060 SAS_RFCNT */
+	u32 received_frame_count;
+/* 0x0064 SAS_TFCNT */
+	u32 transmit_frame_count;
+/* 0x0068 SAS_RFDCNT */
+	u32 received_dword_count;
+/* 0x006C SAS_TFDCNT */
+	u32 transmit_dword_count;
+/* 0x0070 SAS_LERCNT */
+	u32 loss_of_sync_error_count;
+/* 0x0074 SAS_RDISERRCNT */
+	u32 running_disparity_error_count;
+/* 0x0078 SAS_CRERCNT */
+	u32 received_frame_crc_error_count;
+/* 0x007C STPCTL */
+	u32 stp_control;
+/* 0x0080 SAS_PCFG */
+	u32 phy_configuration;
+/* 0x0084 SAS_CLKSM */
+	u32 clock_skew_management;
+/* 0x0088 SAS_TXCOMWAKE */
+	u32 transmit_comwake_signal;
+/* 0x008C SAS_TXCOMINIT */
+	u32 transmit_cominit_signal;
+/* 0x0090 SAS_TXCOMSAS */
+	u32 transmit_comsas_signal;
+/* 0x0094 SAS_COMINIT */
+	u32 cominit_control;
+/* 0x0098 SAS_COMWAKE */
+	u32 comwake_control;
+/* 0x009C SAS_COMSAS */
+	u32 comsas_control;
+/* 0x00A0 SAS_SFERCNT */
+	u32 received_short_frame_count;
+/* 0x00A4 SAS_CDFERCNT */
+	u32 received_frame_without_credit_count;
+/* 0x00A8 SAS_DNFERCNT */
+	u32 received_frame_after_done_count;
+/* 0x00AC SAS_PRSTERCNT */
+	u32 phy_reset_problem_count;
+/* 0x00B0 SAS_CNTCTL */
+	u32 counter_control;
+/* 0x00B4 SAS_SSPTOV */
+	u32 ssp_timer_timeout_values;
+/* 0x00B8 FTCTL */
+	u32 ftx_control;
+/* 0x00BC FRCTL */
+	u32 frx_control;
+/* 0x00C0 FTWMRK */
+	u32 ftx_watermark;
+/* 0x00C4 ENSPINUP */
+	u32 notify_enable_spinup_control;
+/* 0x00C8 SAS_TRNTOV */
+	u32 sas_training_sequence_timer_values;
+/* 0x00CC SAS_PHYCAP */
+	u32 phy_capabilities;
+/* 0x00D0 SAS_PHYCTL */
+	u32 phy_control;
+	u32 reserved_d4;
+/* 0x00D8 LLCTL */
+	u32 link_layer_control;
+/* 0x00DC AFE_XCVRCR */
+	u32 afe_xcvr_control;
+/* 0x00E0 AFE_LUTCR */
+	u32 afe_lookup_table_control;
+/* 0x00E4 PSZGCR */
+	u32 phy_source_zone_group_control;
+/* 0x00E8 SAS_RECPHYCAP */
+	u32 receive_phycap;
+	u32 reserved_ec;
+/* 0x00F0 SNAFERXRSTCTL */
+	u32 speed_negotiation_afe_rx_reset_control;
+/* 0x00F4 SAS_SSIPMCTL */
+	u32 power_management_control;
+/* 0x00F8 SAS_PSPREQ_PRIM */
+	u32 sas_pm_partial_request_primitive;
+/* 0x00FC SAS_PSSREQ_PRIM */
+	u32 sas_pm_slumber_request_primitive;
+/* 0x0100 SAS_PPSACK_PRIM */
+	u32 sas_pm_ack_primitive_register;
+/* 0x0104 SAS_PSNAK_PRIM */
+	u32 sas_pm_nak_primitive_register;
+/* 0x0108 SAS_SSIPMTOV */
+	u32 sas_primitive_timeout;
+	u32 reserved_10c;
+/* 0x0110 - 0x011C PLAPRDCTRLxREG */
+	u32 pla_product_control[4];
+/* 0x0120 PLAPRDSUMREG */
+	u32 pla_product_sum;
+/* 0x0124 PLACONTROLREG */
+	u32 pla_control;
+/* Remainder of memory space 896 bytes */
+	u32 reserved_0128_037f[0x96];
+
+};
+
+/*
+ * 0x00D4 // Same offset as SAS_TCTSTM SAS_PTxC
+ *   u32   primitive_transmit_control; */
+
+/*
+ * ----------------------------------------------------------------------------
+ * SGPIO
+ * ---------------------------------------------------------------------------- */
+#define SCU_SGPIO_OFFSET         0x1400
+
+/* #define SCU_SGPIO_OFFSET         0x6000   // later moves to 0x1400 see HSD 652625 */
+#define SCU_SGPIO_SGICR_OFFSET   0x0000
+#define SCU_SGPIO_SGPBR_OFFSET   0x0004
+#define SCU_SGPIO_SGSDLR_OFFSET  0x0008
+#define SCU_SGPIO_SGSDUR_OFFSET  0x000C
+#define SCU_SGPIO_SGSIDLR_OFFSET 0x0010
+#define SCU_SGPIO_SGSIDUR_OFFSET 0x0014
+#define SCU_SGPIO_SGVSCR_OFFSET  0x0018
+/* Address from 0x0820 to 0x083C */
+#define SCU_SGPIO_SGODSR_OFFSET  0x0020
+
+/**
+ * struct scu_sgpio_registers - SCU SGPIO Registers
+ *
+ *
+ */
+struct scu_sgpio_registers {
+/* 0x0000 SGPIO_SGICR */
+	u32 interface_control;
+/* 0x0004 SGPIO_SGPBR */
+	u32 blink_rate;
+/* 0x0008 SGPIO_SGSDLR */
+	u32 start_drive_lower;
+/* 0x000C SGPIO_SGSDUR */
+	u32 start_drive_upper;
+/* 0x0010 SGPIO_SGSIDLR */
+	u32 serial_input_lower;
+/* 0x0014 SGPIO_SGSIDUR */
+	u32 serial_input_upper;
+/* 0x0018 SGPIO_SGVSCR */
+	u32 vendor_specific_code;
+/* 0x0020 SGPIO_SGODSR */
+	u32 ouput_data_select[8];
+/* Remainder of memory space 256 bytes */
+	u32 reserved_1444_14ff[0x31];
+
+};
+
+/*
+ * *****************************************************************************
+ * * Defines for VIIT entry offsets
+ * * Access additional entries by SCU_VIIT_BASE + index * 0x10
+ * ***************************************************************************** */
+#define     SCU_VIIT_BASE     0x1c00
+
+struct scu_viit_registers {
+	u32 registers[256];
+};
+
+/*
+ * *****************************************************************************
+ * * SCU PORT TASK SCHEDULER REGISTERS
+ * ***************************************************************************** */
+
+#define SCU_PTSG_BASE               0x1000
+
+#define SCU_PTSG_PTSGCR_OFFSET      0x0000
+#define SCU_PTSG_RTCR_OFFSET        0x0004
+#define SCU_PTSG_RTCCR_OFFSET       0x0008
+#define SCU_PTSG_PTS0CR_OFFSET      0x0010
+#define SCU_PTSG_PTS0SR_OFFSET      0x0014
+#define SCU_PTSG_PTS1CR_OFFSET      0x0018
+#define SCU_PTSG_PTS1SR_OFFSET      0x001C
+#define SCU_PTSG_PTS2CR_OFFSET      0x0020
+#define SCU_PTSG_PTS2SR_OFFSET      0x0024
+#define SCU_PTSG_PTS3CR_OFFSET      0x0028
+#define SCU_PTSG_PTS3SR_OFFSET      0x002C
+#define SCU_PTSG_PCSPE0CR_OFFSET    0x0030
+#define SCU_PTSG_PCSPE1CR_OFFSET    0x0034
+#define SCU_PTSG_PCSPE2CR_OFFSET    0x0038
+#define SCU_PTSG_PCSPE3CR_OFFSET    0x003C
+#define SCU_PTSG_ETMTSCCR_OFFSET    0x0040
+#define SCU_PTSG_ETMRNSCCR_OFFSET   0x0044
+
+/**
+ * struct scu_port_task_scheduler_registers - These are the control/stats pairs
+ *    for each Port Task Scheduler.
+ *
+ *
+ */
+struct scu_port_task_scheduler_registers {
+	u32 control;
+	u32 status;
+};
+
+/**
+ * struct scu_port_task_scheduler_group_registers - These are the PORT Task
+ *    Scheduler registers
+ *
+ *
+ */
+struct scu_port_task_scheduler_group_registers {
+/* 0x0000 PTSGCR */
+	u32 control;
+/* 0x0004 RTCR */
+	u32 real_time_clock;
+/* 0x0008 RTCCR */
+	u32 real_time_clock_control;
+/* 0x000C */
+	u32 reserved_0C;
+/*
+ * 0x0010 PTS0CR
+ * 0x0014 PTS0SR
+ * 0x0018 PTS1CR
+ * 0x001C PTS1SR
+ * 0x0020 PTS2CR
+ * 0x0024 PTS2SR
+ * 0x0028 PTS3CR
+ * 0x002C PTS3SR */
+	struct scu_port_task_scheduler_registers port[4];
+/*
+ * 0x0030 PCSPE0CR
+ * 0x0034 PCSPE1CR
+ * 0x0038 PCSPE2CR
+ * 0x003C PCSPE3CR */
+	u32 protocol_engine[4];
+/* 0x0040 ETMTSCCR */
+	u32 tc_scanning_interval_control;
+/* 0x0044 ETMRNSCCR */
+	u32 rnc_scanning_interval_control;
+/* Remainder of memory space 128 bytes */
+	u32 reserved_1048_107f[0x0E];
+
+};
+
+#define SCU_PTSG_SCUVZECR_OFFSET        0x003C
+
+/*
+ * *****************************************************************************
+ * * AFE REGISTERS
+ * ***************************************************************************** */
+#define SCU_AFE_MMR_BASE                  0xE000
+
+/*
+ * AFE 0 is at offset 0x0800
+ * AFE 1 is at offset 0x0900
+ * AFE 2 is at offset 0x0a00
+ * AFE 3 is at offset 0x0b00 */
+struct scu_afe_transceiver {
+	/* 0x0000 AFE_XCVR_CTRL0 */
+	u32 afe_xcvr_control0;
+	/* 0x0004 AFE_XCVR_CTRL1 */
+	u32 afe_xcvr_control1;
+	/* 0x0008 */
+	u32 reserved_0008;
+	/* 0x000c afe_dfx_rx_control0 */
+	u32 afe_dfx_rx_control0;
+	/* 0x0010 AFE_DFX_RX_CTRL1 */
+	u32 afe_dfx_rx_control1;
+	/* 0x0014 */
+	u32 reserved_0014;
+	/* 0x0018 AFE_DFX_RX_STS0 */
+	u32 afe_dfx_rx_status0;
+	/* 0x001c AFE_DFX_RX_STS1 */
+	u32 afe_dfx_rx_status1;
+	/* 0x0020 */
+	u32 reserved_0020;
+	/* 0x0024 AFE_TX_CTRL */
+	u32 afe_tx_control;
+	/* 0x0028 AFE_TX_AMP_CTRL0 */
+	u32 afe_tx_amp_control0;
+	/* 0x002c AFE_TX_AMP_CTRL1 */
+	u32 afe_tx_amp_control1;
+	/* 0x0030 AFE_TX_AMP_CTRL2 */
+	u32 afe_tx_amp_control2;
+	/* 0x0034 AFE_TX_AMP_CTRL3 */
+	u32 afe_tx_amp_control3;
+	/* 0x0038 afe_tx_ssc_control */
+	u32 afe_tx_ssc_control;
+	/* 0x003c */
+	u32 reserved_003c;
+	/* 0x0040 AFE_RX_SSC_CTRL0 */
+	u32 afe_rx_ssc_control0;
+	/* 0x0044 AFE_RX_SSC_CTRL1 */
+	u32 afe_rx_ssc_control1;
+	/* 0x0048 AFE_RX_SSC_CTRL2 */
+	u32 afe_rx_ssc_control2;
+	/* 0x004c AFE_RX_EQ_STS0 */
+	u32 afe_rx_eq_status0;
+	/* 0x0050 AFE_RX_EQ_STS1 */
+	u32 afe_rx_eq_status1;
+	/* 0x0054 AFE_RX_CDR_STS */
+	u32 afe_rx_cdr_status;
+	/* 0x0058 */
+	u32 reserved_0058;
+	/* 0x005c AFE_CHAN_CTRL */
+	u32 afe_channel_control;
+	/* 0x0060-0x006c */
+	u32 reserved_0060_006c[0x04];
+	/* 0x0070 AFE_XCVR_EC_STS0 */
+	u32 afe_xcvr_error_capture_status0;
+	/* 0x0074 AFE_XCVR_EC_STS1 */
+	u32 afe_xcvr_error_capture_status1;
+	/* 0x0078 AFE_XCVR_EC_STS2 */
+	u32 afe_xcvr_error_capture_status2;
+	/* 0x007c afe_xcvr_ec_status3 */
+	u32 afe_xcvr_error_capture_status3;
+	/* 0x0080 AFE_XCVR_EC_STS4 */
+	u32 afe_xcvr_error_capture_status4;
+	/* 0x0084 AFE_XCVR_EC_STS5 */
+	u32 afe_xcvr_error_capture_status5;
+	/* 0x0088-0x00fc */
+	u32 reserved_008c_00fc[0x1e];
+};
+
+/**
+ * struct scu_afe_registers - AFE Regsiters
+ *
+ *
+ */
+/* Uaoa AFE registers */
+struct scu_afe_registers {
+	/* 0Xe000 AFE_BIAS_CTRL */
+	u32 afe_bias_control;
+	u32 reserved_0004;
+	/* 0x0008 AFE_PLL_CTRL0 */
+	u32 afe_pll_control0;
+	/* 0x000c AFE_PLL_CTRL1 */
+	u32 afe_pll_control1;
+	/* 0x0010 AFE_PLL_CTRL2 */
+	u32 afe_pll_control2;
+	/* 0x0014 AFE_CB_STS */
+	u32 afe_common_block_status;
+	/* 0x0018-0x007c */
+	u32 reserved_18_7c[0x1a];
+	/* 0x0080 AFE_PMSN_MCTRL0 */
+	u32 afe_pmsn_master_control0;
+	/* 0x0084 AFE_PMSN_MCTRL1 */
+	u32 afe_pmsn_master_control1;
+	/* 0x0088 AFE_PMSN_MCTRL2 */
+	u32 afe_pmsn_master_control2;
+	/* 0x008C-0x00fc */
+	u32 reserved_008c_00fc[0x1D];
+	/* 0x0100 AFE_DFX_MST_CTRL0 */
+	u32 afe_dfx_master_control0;
+	/* 0x0104 AFE_DFX_MST_CTRL1 */
+	u32 afe_dfx_master_control1;
+	/* 0x0108 AFE_DFX_DCL_CTRL */
+	u32 afe_dfx_dcl_control;
+	/* 0x010c AFE_DFX_DMON_CTRL */
+	u32 afe_dfx_digital_monitor_control;
+	/* 0x0110 AFE_DFX_AMONP_CTRL */
+	u32 afe_dfx_analog_p_monitor_control;
+	/* 0x0114 AFE_DFX_AMONN_CTRL */
+	u32 afe_dfx_analog_n_monitor_control;
+	/* 0x0118 AFE_DFX_NTL_STS */
+	u32 afe_dfx_ntl_status;
+	/* 0x011c AFE_DFX_FIFO_STS0 */
+	u32 afe_dfx_fifo_status0;
+	/* 0x0120 AFE_DFX_FIFO_STS1 */
+	u32 afe_dfx_fifo_status1;
+	/* 0x0124 AFE_DFX_MPAT_CTRL */
+	u32 afe_dfx_master_pattern_control;
+	/* 0x0128 AFE_DFX_P0_CTRL */
+	u32 afe_dfx_p0_control;
+	/* 0x012c-0x01a8 AFE_DFX_P0_DRx */
+	u32 afe_dfx_p0_data[32];
+	/* 0x01ac */
+	u32 reserved_01ac;
+	/* 0x01b0-0x020c AFE_DFX_P0_IRx */
+	u32 afe_dfx_p0_instruction[24];
+	/* 0x0210 */
+	u32 reserved_0210;
+	/* 0x0214 AFE_DFX_P1_CTRL */
+	u32 afe_dfx_p1_control;
+	/* 0x0218-0x245 AFE_DFX_P1_DRx */
+	u32 afe_dfx_p1_data[16];
+	/* 0x0258-0x029c */
+	u32 reserved_0258_029c[0x12];
+	/* 0x02a0-0x02bc AFE_DFX_P1_IRx */
+	u32 afe_dfx_p1_instruction[8];
+	/* 0x02c0-0x2fc */
+	u32 reserved_02c0_02fc[0x10];
+	/* 0x0300 AFE_DFX_TX_PMSN_CTRL */
+	u32 afe_dfx_tx_pmsn_control;
+	/* 0x0304 AFE_DFX_RX_PMSN_CTRL */
+	u32 afe_dfx_rx_pmsn_control;
+	u32 reserved_0308;
+	/* 0x030c AFE_DFX_NOA_CTRL0 */
+	u32 afe_dfx_noa_control0;
+	/* 0x0310 AFE_DFX_NOA_CTRL1 */
+	u32 afe_dfx_noa_control1;
+	/* 0x0314 AFE_DFX_NOA_CTRL2 */
+	u32 afe_dfx_noa_control2;
+	/* 0x0318 AFE_DFX_NOA_CTRL3 */
+	u32 afe_dfx_noa_control3;
+	/* 0x031c AFE_DFX_NOA_CTRL4 */
+	u32 afe_dfx_noa_control4;
+	/* 0x0320 AFE_DFX_NOA_CTRL5 */
+	u32 afe_dfx_noa_control5;
+	/* 0x0324 AFE_DFX_NOA_CTRL6 */
+	u32 afe_dfx_noa_control6;
+	/* 0x0328 AFE_DFX_NOA_CTRL7 */
+	u32 afe_dfx_noa_control7;
+	/* 0x032c-0x07fc */
+	u32 reserved_032c_07fc[0x135];
+
+	/* 0x0800-0x0bfc */
+	struct scu_afe_transceiver scu_afe_xcvr[4];
+
+	/* 0x0c00-0x0ffc */
+	u32 reserved_0c00_0ffc[0x0100];
+};
+
+struct scu_protocol_engine_group_registers {
+	u32 table[0xE0];
+};
+
+
+struct scu_viit_iit {
+	u32 table[256];
+};
+
+/**
+ * Placeholder for the ZONE Partition Table information ZONING will not be
+ *    included in the 1.1 release.
+ *
+ *
+ */
+struct scu_zone_partition_table {
+	u32 table[2048];
+};
+
+/**
+ * Placeholder for the CRAM register since I am not sure if we need to
+ *    read/write to these registers as yet.
+ *
+ *
+ */
+struct scu_completion_ram {
+	u32 ram[128];
+};
+
+/**
+ * Placeholder for the FBRAM registers since I am not sure if we need to
+ *    read/write to these registers as yet.
+ *
+ *
+ */
+struct scu_frame_buffer_ram {
+	u32 ram[128];
+};
+
+#define scu_scratch_ram_SIZE_IN_DWORDS  256
+
+/**
+ * Placeholder for the scratch RAM registers.
+ *
+ *
+ */
+struct scu_scratch_ram {
+	u32 ram[scu_scratch_ram_SIZE_IN_DWORDS];
+};
+
+/**
+ * Placeholder since I am not yet sure what these registers are here for.
+ *
+ *
+ */
+struct noa_protocol_engine_partition {
+	u32 reserved[64];
+};
+
+/**
+ * Placeholder since I am not yet sure what these registers are here for.
+ *
+ *
+ */
+struct noa_hub_partition {
+	u32 reserved[64];
+};
+
+/**
+ * Placeholder since I am not yet sure what these registers are here for.
+ *
+ *
+ */
+struct noa_host_interface_partition {
+	u32 reserved[64];
+};
+
+/**
+ * struct transport_link_layer_pair - The SCU Hardware pairs up the TL
+ *    registers with the LL registers so we must place them adjcent to make the
+ *    array of registers in the PEG.
+ *
+ *
+ */
+struct transport_link_layer_pair {
+	struct scu_transport_layer_registers tl;
+	struct scu_link_layer_registers ll;
+};
+
+/**
+ * struct scu_peg_registers - SCU Protocol Engine Memory mapped register space.
+ *     These registers are unique to each protocol engine group.  There can be
+ *    at most two PEG for a single SCU part.
+ *
+ *
+ */
+struct scu_peg_registers {
+	struct transport_link_layer_pair pe[4];
+	struct scu_port_task_scheduler_group_registers ptsg;
+	struct scu_protocol_engine_group_registers peg;
+	struct scu_sgpio_registers sgpio;
+	u32 reserved_01500_1BFF[0x1C0];
+	struct scu_viit_entry viit[64];
+	struct scu_zone_partition_table zpt0;
+	struct scu_zone_partition_table zpt1;
+};
+
+/**
+ * struct scu_registers - SCU regsiters including both PEG registers if we turn
+ *    on that compile option. All of these registers are in the memory mapped
+ *    space returned from BAR1.
+ *
+ *
+ */
+struct scu_registers {
+	/* 0x0000 - PEG 0 */
+	struct scu_peg_registers peg0;
+
+	/* 0x6000 - SDMA and Miscellaneous */
+	struct scu_sdma_registers sdma;
+	struct scu_completion_ram cram;
+	struct scu_frame_buffer_ram fbram;
+	u32 reserved_6800_69FF[0x80];
+	struct noa_protocol_engine_partition noa_pe;
+	struct noa_hub_partition noa_hub;
+	struct noa_host_interface_partition noa_if;
+	u32 reserved_6d00_7fff[0x4c0];
+
+	/* 0x8000 - PEG 1 */
+	struct scu_peg_registers peg1;
+
+	/* 0xE000 - AFE Registers */
+	struct scu_afe_registers afe;
+
+	/* 0xF000 - reserved */
+	u32 reserved_f000_211fff[0x80c00];
+
+	/* 0x212000 - scratch RAM */
+	struct scu_scratch_ram scratch_ram;
+};
+
+#endif   /* _SCU_REGISTERS_HEADER_ */
diff -druN linux-2.6.39-libre/drivers/scsi/isci/remote_device.c linux-3.0-rc7-libre/drivers/scsi/isci/remote_device.c
--- linux-2.6.39-libre/drivers/scsi/isci/remote_device.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/scsi/isci/remote_device.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,1501 @@
+/*
+ * This file is provided under a dual BSD/GPLv2 license.  When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * The full GNU General Public License is included in this distribution
+ * in the file called LICENSE.GPL.
+ *
+ * BSD LICENSE
+ *
+ * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in
+ *     the documentation and/or other materials provided with the
+ *     distribution.
+ *   * Neither the name of Intel Corporation nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include <scsi/sas.h>
+#include "isci.h"
+#include "port.h"
+#include "remote_device.h"
+#include "request.h"
+#include "remote_node_context.h"
+#include "scu_event_codes.h"
+#include "task.h"
+
+/**
+ * isci_remote_device_not_ready() - This function is called by the ihost when
+ *    the remote device is not ready. We mark the isci device as ready (not
+ *    "ready_for_io") and signal the waiting proccess.
+ * @isci_host: This parameter specifies the isci host object.
+ * @isci_device: This parameter specifies the remote device
+ *
+ * sci_lock is held on entrance to this function.
+ */
+static void isci_remote_device_not_ready(struct isci_host *ihost,
+				  struct isci_remote_device *idev, u32 reason)
+{
+	struct isci_request *ireq;
+
+	dev_dbg(&ihost->pdev->dev,
+		"%s: isci_device = %p\n", __func__, idev);
+
+	switch (reason) {
+	case SCIC_REMOTE_DEVICE_NOT_READY_STOP_REQUESTED:
+		set_bit(IDEV_GONE, &idev->flags);
+		break;
+	case SCIC_REMOTE_DEVICE_NOT_READY_SATA_SDB_ERROR_FIS_RECEIVED:
+		set_bit(IDEV_IO_NCQERROR, &idev->flags);
+
+		/* Kill all outstanding requests for the device. */
+		list_for_each_entry(ireq, &idev->reqs_in_process, dev_node) {
+
+			dev_dbg(&ihost->pdev->dev,
+				"%s: isci_device = %p request = %p\n",
+				__func__, idev, ireq);
+
+			sci_controller_terminate_request(ihost,
+							  idev,
+							  ireq);
+		}
+		/* Fall through into the default case... */
+	default:
+		clear_bit(IDEV_IO_READY, &idev->flags);
+		break;
+	}
+}
+
+/**
+ * isci_remote_device_ready() - This function is called by the ihost when the
+ *    remote device is ready. We mark the isci device as ready and signal the
+ *    waiting proccess.
+ * @ihost: our valid isci_host
+ * @idev: remote device
+ *
+ */
+static void isci_remote_device_ready(struct isci_host *ihost, struct isci_remote_device *idev)
+{
+	dev_dbg(&ihost->pdev->dev,
+		"%s: idev = %p\n", __func__, idev);
+
+	clear_bit(IDEV_IO_NCQERROR, &idev->flags);
+	set_bit(IDEV_IO_READY, &idev->flags);
+	if (test_and_clear_bit(IDEV_START_PENDING, &idev->flags))
+		wake_up(&ihost->eventq);
+}
+
+/* called once the remote node context is ready to be freed.
+ * The remote device can now report that its stop operation is complete. none
+ */
+static void rnc_destruct_done(void *_dev)
+{
+	struct isci_remote_device *idev = _dev;
+
+	BUG_ON(idev->started_request_count != 0);
+	sci_change_state(&idev->sm, SCI_DEV_STOPPED);
+}
+
+static enum sci_status sci_remote_device_terminate_requests(struct isci_remote_device *idev)
+{
+	struct isci_host *ihost = idev->owning_port->owning_controller;
+	enum sci_status status  = SCI_SUCCESS;
+	u32 i;
+
+	for (i = 0; i < SCI_MAX_IO_REQUESTS; i++) {
+		struct isci_request *ireq = ihost->reqs[i];
+		enum sci_status s;
+
+		if (!test_bit(IREQ_ACTIVE, &ireq->flags) ||
+		    ireq->target_device != idev)
+			continue;
+
+		s = sci_controller_terminate_request(ihost, idev, ireq);
+		if (s != SCI_SUCCESS)
+			status = s;
+	}
+
+	return status;
+}
+
+enum sci_status sci_remote_device_stop(struct isci_remote_device *idev,
+					u32 timeout)
+{
+	struct sci_base_state_machine *sm = &idev->sm;
+	enum sci_remote_device_states state = sm->current_state_id;
+
+	switch (state) {
+	case SCI_DEV_INITIAL:
+	case SCI_DEV_FAILED:
+	case SCI_DEV_FINAL:
+	default:
+		dev_warn(scirdev_to_dev(idev), "%s: in wrong state: %d\n",
+			 __func__, state);
+		return SCI_FAILURE_INVALID_STATE;
+	case SCI_DEV_STOPPED:
+		return SCI_SUCCESS;
+	case SCI_DEV_STARTING:
+		/* device not started so there had better be no requests */
+		BUG_ON(idev->started_request_count != 0);
+		sci_remote_node_context_destruct(&idev->rnc,
+						      rnc_destruct_done, idev);
+		/* Transition to the stopping state and wait for the
+		 * remote node to complete being posted and invalidated.
+		 */
+		sci_change_state(sm, SCI_DEV_STOPPING);
+		return SCI_SUCCESS;
+	case SCI_DEV_READY:
+	case SCI_STP_DEV_IDLE:
+	case SCI_STP_DEV_CMD:
+	case SCI_STP_DEV_NCQ:
+	case SCI_STP_DEV_NCQ_ERROR:
+	case SCI_STP_DEV_AWAIT_RESET:
+	case SCI_SMP_DEV_IDLE:
+	case SCI_SMP_DEV_CMD:
+		sci_change_state(sm, SCI_DEV_STOPPING);
+		if (idev->started_request_count == 0) {
+			sci_remote_node_context_destruct(&idev->rnc,
+							      rnc_destruct_done, idev);
+			return SCI_SUCCESS;
+		} else
+			return sci_remote_device_terminate_requests(idev);
+		break;
+	case SCI_DEV_STOPPING:
+		/* All requests should have been terminated, but if there is an
+		 * attempt to stop a device already in the stopping state, then
+		 * try again to terminate.
+		 */
+		return sci_remote_device_terminate_requests(idev);
+	case SCI_DEV_RESETTING:
+		sci_change_state(sm, SCI_DEV_STOPPING);
+		return SCI_SUCCESS;
+	}
+}
+
+enum sci_status sci_remote_device_reset(struct isci_remote_device *idev)
+{
+	struct sci_base_state_machine *sm = &idev->sm;
+	enum sci_remote_device_states state = sm->current_state_id;
+
+	switch (state) {
+	case SCI_DEV_INITIAL:
+	case SCI_DEV_STOPPED:
+	case SCI_DEV_STARTING:
+	case SCI_SMP_DEV_IDLE:
+	case SCI_SMP_DEV_CMD:
+	case SCI_DEV_STOPPING:
+	case SCI_DEV_FAILED:
+	case SCI_DEV_RESETTING:
+	case SCI_DEV_FINAL:
+	default:
+		dev_warn(scirdev_to_dev(idev), "%s: in wrong state: %d\n",
+			 __func__, state);
+		return SCI_FAILURE_INVALID_STATE;
+	case SCI_DEV_READY:
+	case SCI_STP_DEV_IDLE:
+	case SCI_STP_DEV_CMD:
+	case SCI_STP_DEV_NCQ:
+	case SCI_STP_DEV_NCQ_ERROR:
+	case SCI_STP_DEV_AWAIT_RESET:
+		sci_change_state(sm, SCI_DEV_RESETTING);
+		return SCI_SUCCESS;
+	}
+}
+
+enum sci_status sci_remote_device_reset_complete(struct isci_remote_device *idev)
+{
+	struct sci_base_state_machine *sm = &idev->sm;
+	enum sci_remote_device_states state = sm->current_state_id;
+
+	if (state != SCI_DEV_RESETTING) {
+		dev_warn(scirdev_to_dev(idev), "%s: in wrong state: %d\n",
+			 __func__, state);
+		return SCI_FAILURE_INVALID_STATE;
+	}
+
+	sci_change_state(sm, SCI_DEV_READY);
+	return SCI_SUCCESS;
+}
+
+enum sci_status sci_remote_device_suspend(struct isci_remote_device *idev,
+					       u32 suspend_type)
+{
+	struct sci_base_state_machine *sm = &idev->sm;
+	enum sci_remote_device_states state = sm->current_state_id;
+
+	if (state != SCI_STP_DEV_CMD) {
+		dev_warn(scirdev_to_dev(idev), "%s: in wrong state: %d\n",
+			 __func__, state);
+		return SCI_FAILURE_INVALID_STATE;
+	}
+
+	return sci_remote_node_context_suspend(&idev->rnc,
+						    suspend_type, NULL, NULL);
+}
+
+enum sci_status sci_remote_device_frame_handler(struct isci_remote_device *idev,
+						     u32 frame_index)
+{
+	struct sci_base_state_machine *sm = &idev->sm;
+	enum sci_remote_device_states state = sm->current_state_id;
+	struct isci_host *ihost = idev->owning_port->owning_controller;
+	enum sci_status status;
+
+	switch (state) {
+	case SCI_DEV_INITIAL:
+	case SCI_DEV_STOPPED:
+	case SCI_DEV_STARTING:
+	case SCI_STP_DEV_IDLE:
+	case SCI_SMP_DEV_IDLE:
+	case SCI_DEV_FINAL:
+	default:
+		dev_warn(scirdev_to_dev(idev), "%s: in wrong state: %d\n",
+			 __func__, state);
+		/* Return the frame back to the controller */
+		sci_controller_release_frame(ihost, frame_index);
+		return SCI_FAILURE_INVALID_STATE;
+	case SCI_DEV_READY:
+	case SCI_STP_DEV_NCQ_ERROR:
+	case SCI_STP_DEV_AWAIT_RESET:
+	case SCI_DEV_STOPPING:
+	case SCI_DEV_FAILED:
+	case SCI_DEV_RESETTING: {
+		struct isci_request *ireq;
+		struct ssp_frame_hdr hdr;
+		void *frame_header;
+		ssize_t word_cnt;
+
+		status = sci_unsolicited_frame_control_get_header(&ihost->uf_control,
+								       frame_index,
+								       &frame_header);
+		if (status != SCI_SUCCESS)
+			return status;
+
+		word_cnt = sizeof(hdr) / sizeof(u32);
+		sci_swab32_cpy(&hdr, frame_header, word_cnt);
+
+		ireq = sci_request_by_tag(ihost, be16_to_cpu(hdr.tag));
+		if (ireq && ireq->target_device == idev) {
+			/* The IO request is now in charge of releasing the frame */
+			status = sci_io_request_frame_handler(ireq, frame_index);
+		} else {
+			/* We could not map this tag to a valid IO
+			 * request Just toss the frame and continue
+			 */
+			sci_controller_release_frame(ihost, frame_index);
+		}
+		break;
+	}
+	case SCI_STP_DEV_NCQ: {
+		struct dev_to_host_fis *hdr;
+
+		status = sci_unsolicited_frame_control_get_header(&ihost->uf_control,
+								       frame_index,
+								       (void **)&hdr);
+		if (status != SCI_SUCCESS)
+			return status;
+
+		if (hdr->fis_type == FIS_SETDEVBITS &&
+		    (hdr->status & ATA_ERR)) {
+			idev->not_ready_reason = SCIC_REMOTE_DEVICE_NOT_READY_SATA_SDB_ERROR_FIS_RECEIVED;
+
+			/* TODO Check sactive and complete associated IO if any. */
+			sci_change_state(sm, SCI_STP_DEV_NCQ_ERROR);
+		} else if (hdr->fis_type == FIS_REGD2H &&
+			   (hdr->status & ATA_ERR)) {
+			/*
+			 * Some devices return D2H FIS when an NCQ error is detected.
+			 * Treat this like an SDB error FIS ready reason.
+			 */
+			idev->not_ready_reason = SCIC_REMOTE_DEVICE_NOT_READY_SATA_SDB_ERROR_FIS_RECEIVED;
+			sci_change_state(&idev->sm, SCI_STP_DEV_NCQ_ERROR);
+		} else
+			status = SCI_FAILURE;
+
+		sci_controller_release_frame(ihost, frame_index);
+		break;
+	}
+	case SCI_STP_DEV_CMD:
+	case SCI_SMP_DEV_CMD:
+		/* The device does not process any UF received from the hardware while
+		 * in this state.  All unsolicited frames are forwarded to the io request
+		 * object.
+		 */
+		status = sci_io_request_frame_handler(idev->working_request, frame_index);
+		break;
+	}
+
+	return status;
+}
+
+static bool is_remote_device_ready(struct isci_remote_device *idev)
+{
+
+	struct sci_base_state_machine *sm = &idev->sm;
+	enum sci_remote_device_states state = sm->current_state_id;
+
+	switch (state) {
+	case SCI_DEV_READY:
+	case SCI_STP_DEV_IDLE:
+	case SCI_STP_DEV_CMD:
+	case SCI_STP_DEV_NCQ:
+	case SCI_STP_DEV_NCQ_ERROR:
+	case SCI_STP_DEV_AWAIT_RESET:
+	case SCI_SMP_DEV_IDLE:
+	case SCI_SMP_DEV_CMD:
+		return true;
+	default:
+		return false;
+	}
+}
+
+enum sci_status sci_remote_device_event_handler(struct isci_remote_device *idev,
+						     u32 event_code)
+{
+	struct sci_base_state_machine *sm = &idev->sm;
+	enum sci_remote_device_states state = sm->current_state_id;
+	enum sci_status status;
+
+	switch (scu_get_event_type(event_code)) {
+	case SCU_EVENT_TYPE_RNC_OPS_MISC:
+	case SCU_EVENT_TYPE_RNC_SUSPEND_TX:
+	case SCU_EVENT_TYPE_RNC_SUSPEND_TX_RX:
+		status = sci_remote_node_context_event_handler(&idev->rnc, event_code);
+		break;
+	case SCU_EVENT_TYPE_PTX_SCHEDULE_EVENT:
+		if (scu_get_event_code(event_code) == SCU_EVENT_IT_NEXUS_TIMEOUT) {
+			status = SCI_SUCCESS;
+
+			/* Suspend the associated RNC */
+			sci_remote_node_context_suspend(&idev->rnc,
+							      SCI_SOFTWARE_SUSPENSION,
+							      NULL, NULL);
+
+			dev_dbg(scirdev_to_dev(idev),
+				"%s: device: %p event code: %x: %s\n",
+				__func__, idev, event_code,
+				is_remote_device_ready(idev)
+				? "I_T_Nexus_Timeout event"
+				: "I_T_Nexus_Timeout event in wrong state");
+
+			break;
+		}
+	/* Else, fall through and treat as unhandled... */
+	default:
+		dev_dbg(scirdev_to_dev(idev),
+			"%s: device: %p event code: %x: %s\n",
+			__func__, idev, event_code,
+			is_remote_device_ready(idev)
+			? "unexpected event"
+			: "unexpected event in wrong state");
+		status = SCI_FAILURE_INVALID_STATE;
+		break;
+	}
+
+	if (status != SCI_SUCCESS)
+		return status;
+
+	if (state == SCI_STP_DEV_IDLE) {
+
+		/* We pick up suspension events to handle specifically to this
+		 * state. We resume the RNC right away.
+		 */
+		if (scu_get_event_type(event_code) == SCU_EVENT_TYPE_RNC_SUSPEND_TX ||
+		    scu_get_event_type(event_code) == SCU_EVENT_TYPE_RNC_SUSPEND_TX_RX)
+			status = sci_remote_node_context_resume(&idev->rnc, NULL, NULL);
+	}
+
+	return status;
+}
+
+static void sci_remote_device_start_request(struct isci_remote_device *idev,
+						 struct isci_request *ireq,
+						 enum sci_status status)
+{
+	struct isci_port *iport = idev->owning_port;
+
+	/* cleanup requests that failed after starting on the port */
+	if (status != SCI_SUCCESS)
+		sci_port_complete_io(iport, idev, ireq);
+	else {
+		kref_get(&idev->kref);
+		idev->started_request_count++;
+	}
+}
+
+enum sci_status sci_remote_device_start_io(struct isci_host *ihost,
+						struct isci_remote_device *idev,
+						struct isci_request *ireq)
+{
+	struct sci_base_state_machine *sm = &idev->sm;
+	enum sci_remote_device_states state = sm->current_state_id;
+	struct isci_port *iport = idev->owning_port;
+	enum sci_status status;
+
+	switch (state) {
+	case SCI_DEV_INITIAL:
+	case SCI_DEV_STOPPED:
+	case SCI_DEV_STARTING:
+	case SCI_STP_DEV_NCQ_ERROR:
+	case SCI_DEV_STOPPING:
+	case SCI_DEV_FAILED:
+	case SCI_DEV_RESETTING:
+	case SCI_DEV_FINAL:
+	default:
+		dev_warn(scirdev_to_dev(idev), "%s: in wrong state: %d\n",
+			 __func__, state);
+		return SCI_FAILURE_INVALID_STATE;
+	case SCI_DEV_READY:
+		/* attempt to start an io request for this device object. The remote
+		 * device object will issue the start request for the io and if
+		 * successful it will start the request for the port object then
+		 * increment its own request count.
+		 */
+		status = sci_port_start_io(iport, idev, ireq);
+		if (status != SCI_SUCCESS)
+			return status;
+
+		status = sci_remote_node_context_start_io(&idev->rnc, ireq);
+		if (status != SCI_SUCCESS)
+			break;
+
+		status = sci_request_start(ireq);
+		break;
+	case SCI_STP_DEV_IDLE: {
+		/* handle the start io operation for a sata device that is in
+		 * the command idle state. - Evalute the type of IO request to
+		 * be started - If its an NCQ request change to NCQ substate -
+		 * If its any other command change to the CMD substate
+		 *
+		 * If this is a softreset we may want to have a different
+		 * substate.
+		 */
+		enum sci_remote_device_states new_state;
+		struct sas_task *task = isci_request_access_task(ireq);
+
+		status = sci_port_start_io(iport, idev, ireq);
+		if (status != SCI_SUCCESS)
+			return status;
+
+		status = sci_remote_node_context_start_io(&idev->rnc, ireq);
+		if (status != SCI_SUCCESS)
+			break;
+
+		status = sci_request_start(ireq);
+		if (status != SCI_SUCCESS)
+			break;
+
+		if (task->ata_task.use_ncq)
+			new_state = SCI_STP_DEV_NCQ;
+		else {
+			idev->working_request = ireq;
+			new_state = SCI_STP_DEV_CMD;
+		}
+		sci_change_state(sm, new_state);
+		break;
+	}
+	case SCI_STP_DEV_NCQ: {
+		struct sas_task *task = isci_request_access_task(ireq);
+
+		if (task->ata_task.use_ncq) {
+			status = sci_port_start_io(iport, idev, ireq);
+			if (status != SCI_SUCCESS)
+				return status;
+
+			status = sci_remote_node_context_start_io(&idev->rnc, ireq);
+			if (status != SCI_SUCCESS)
+				break;
+
+			status = sci_request_start(ireq);
+		} else
+			return SCI_FAILURE_INVALID_STATE;
+		break;
+	}
+	case SCI_STP_DEV_AWAIT_RESET:
+		return SCI_FAILURE_REMOTE_DEVICE_RESET_REQUIRED;
+	case SCI_SMP_DEV_IDLE:
+		status = sci_port_start_io(iport, idev, ireq);
+		if (status != SCI_SUCCESS)
+			return status;
+
+		status = sci_remote_node_context_start_io(&idev->rnc, ireq);
+		if (status != SCI_SUCCESS)
+			break;
+
+		status = sci_request_start(ireq);
+		if (status != SCI_SUCCESS)
+			break;
+
+		idev->working_request = ireq;
+		sci_change_state(&idev->sm, SCI_SMP_DEV_CMD);
+		break;
+	case SCI_STP_DEV_CMD:
+	case SCI_SMP_DEV_CMD:
+		/* device is already handling a command it can not accept new commands
+		 * until this one is complete.
+		 */
+		return SCI_FAILURE_INVALID_STATE;
+	}
+
+	sci_remote_device_start_request(idev, ireq, status);
+	return status;
+}
+
+static enum sci_status common_complete_io(struct isci_port *iport,
+					  struct isci_remote_device *idev,
+					  struct isci_request *ireq)
+{
+	enum sci_status status;
+
+	status = sci_request_complete(ireq);
+	if (status != SCI_SUCCESS)
+		return status;
+
+	status = sci_port_complete_io(iport, idev, ireq);
+	if (status != SCI_SUCCESS)
+		return status;
+
+	sci_remote_device_decrement_request_count(idev);
+	return status;
+}
+
+enum sci_status sci_remote_device_complete_io(struct isci_host *ihost,
+						   struct isci_remote_device *idev,
+						   struct isci_request *ireq)
+{
+	struct sci_base_state_machine *sm = &idev->sm;
+	enum sci_remote_device_states state = sm->current_state_id;
+	struct isci_port *iport = idev->owning_port;
+	enum sci_status status;
+
+	switch (state) {
+	case SCI_DEV_INITIAL:
+	case SCI_DEV_STOPPED:
+	case SCI_DEV_STARTING:
+	case SCI_STP_DEV_IDLE:
+	case SCI_SMP_DEV_IDLE:
+	case SCI_DEV_FAILED:
+	case SCI_DEV_FINAL:
+	default:
+		dev_warn(scirdev_to_dev(idev), "%s: in wrong state: %d\n",
+			 __func__, state);
+		return SCI_FAILURE_INVALID_STATE;
+	case SCI_DEV_READY:
+	case SCI_STP_DEV_AWAIT_RESET:
+	case SCI_DEV_RESETTING:
+		status = common_complete_io(iport, idev, ireq);
+		break;
+	case SCI_STP_DEV_CMD:
+	case SCI_STP_DEV_NCQ:
+	case SCI_STP_DEV_NCQ_ERROR:
+		status = common_complete_io(iport, idev, ireq);
+		if (status != SCI_SUCCESS)
+			break;
+
+		if (ireq->sci_status == SCI_FAILURE_REMOTE_DEVICE_RESET_REQUIRED) {
+			/* This request causes hardware error, device needs to be Lun Reset.
+			 * So here we force the state machine to IDLE state so the rest IOs
+			 * can reach RNC state handler, these IOs will be completed by RNC with
+			 * status of "DEVICE_RESET_REQUIRED", instead of "INVALID STATE".
+			 */
+			sci_change_state(sm, SCI_STP_DEV_AWAIT_RESET);
+		} else if (idev->started_request_count == 0)
+			sci_change_state(sm, SCI_STP_DEV_IDLE);
+		break;
+	case SCI_SMP_DEV_CMD:
+		status = common_complete_io(iport, idev, ireq);
+		if (status != SCI_SUCCESS)
+			break;
+		sci_change_state(sm, SCI_SMP_DEV_IDLE);
+		break;
+	case SCI_DEV_STOPPING:
+		status = common_complete_io(iport, idev, ireq);
+		if (status != SCI_SUCCESS)
+			break;
+
+		if (idev->started_request_count == 0)
+			sci_remote_node_context_destruct(&idev->rnc,
+							 rnc_destruct_done,
+							 idev);
+		break;
+	}
+
+	if (status != SCI_SUCCESS)
+		dev_err(scirdev_to_dev(idev),
+			"%s: Port:0x%p Device:0x%p Request:0x%p Status:0x%x "
+			"could not complete\n", __func__, iport,
+			idev, ireq, status);
+	else
+		isci_put_device(idev);
+
+	return status;
+}
+
+static void sci_remote_device_continue_request(void *dev)
+{
+	struct isci_remote_device *idev = dev;
+
+	/* we need to check if this request is still valid to continue. */
+	if (idev->working_request)
+		sci_controller_continue_io(idev->working_request);
+}
+
+enum sci_status sci_remote_device_start_task(struct isci_host *ihost,
+						  struct isci_remote_device *idev,
+						  struct isci_request *ireq)
+{
+	struct sci_base_state_machine *sm = &idev->sm;
+	enum sci_remote_device_states state = sm->current_state_id;
+	struct isci_port *iport = idev->owning_port;
+	enum sci_status status;
+
+	switch (state) {
+	case SCI_DEV_INITIAL:
+	case SCI_DEV_STOPPED:
+	case SCI_DEV_STARTING:
+	case SCI_SMP_DEV_IDLE:
+	case SCI_SMP_DEV_CMD:
+	case SCI_DEV_STOPPING:
+	case SCI_DEV_FAILED:
+	case SCI_DEV_RESETTING:
+	case SCI_DEV_FINAL:
+	default:
+		dev_warn(scirdev_to_dev(idev), "%s: in wrong state: %d\n",
+			 __func__, state);
+		return SCI_FAILURE_INVALID_STATE;
+	case SCI_STP_DEV_IDLE:
+	case SCI_STP_DEV_CMD:
+	case SCI_STP_DEV_NCQ:
+	case SCI_STP_DEV_NCQ_ERROR:
+	case SCI_STP_DEV_AWAIT_RESET:
+		status = sci_port_start_io(iport, idev, ireq);
+		if (status != SCI_SUCCESS)
+			return status;
+
+		status = sci_remote_node_context_start_task(&idev->rnc, ireq);
+		if (status != SCI_SUCCESS)
+			goto out;
+
+		status = sci_request_start(ireq);
+		if (status != SCI_SUCCESS)
+			goto out;
+
+		/* Note: If the remote device state is not IDLE this will
+		 * replace the request that probably resulted in the task
+		 * management request.
+		 */
+		idev->working_request = ireq;
+		sci_change_state(sm, SCI_STP_DEV_CMD);
+
+		/* The remote node context must cleanup the TCi to NCQ mapping
+		 * table.  The only way to do this correctly is to either write
+		 * to the TLCR register or to invalidate and repost the RNC. In
+		 * either case the remote node context state machine will take
+		 * the correct action when the remote node context is suspended
+		 * and later resumed.
+		 */
+		sci_remote_node_context_suspend(&idev->rnc,
+				SCI_SOFTWARE_SUSPENSION, NULL, NULL);
+		sci_remote_node_context_resume(&idev->rnc,
+				sci_remote_device_continue_request,
+						    idev);
+
+	out:
+		sci_remote_device_start_request(idev, ireq, status);
+		/* We need to let the controller start request handler know that
+		 * it can't post TC yet. We will provide a callback function to
+		 * post TC when RNC gets resumed.
+		 */
+		return SCI_FAILURE_RESET_DEVICE_PARTIAL_SUCCESS;
+	case SCI_DEV_READY:
+		status = sci_port_start_io(iport, idev, ireq);
+		if (status != SCI_SUCCESS)
+			return status;
+
+		status = sci_remote_node_context_start_task(&idev->rnc, ireq);
+		if (status != SCI_SUCCESS)
+			break;
+
+		status = sci_request_start(ireq);
+		break;
+	}
+	sci_remote_device_start_request(idev, ireq, status);
+
+	return status;
+}
+
+void sci_remote_device_post_request(struct isci_remote_device *idev, u32 request)
+{
+	struct isci_port *iport = idev->owning_port;
+	u32 context;
+
+	context = request |
+		  (ISCI_PEG << SCU_CONTEXT_COMMAND_PROTOCOL_ENGINE_GROUP_SHIFT) |
+		  (iport->physical_port_index << SCU_CONTEXT_COMMAND_LOGICAL_PORT_SHIFT) |
+		  idev->rnc.remote_node_index;
+
+	sci_controller_post_request(iport->owning_controller, context);
+}
+
+/* called once the remote node context has transisitioned to a
+ * ready state.  This is the indication that the remote device object can also
+ * transition to ready.
+ */
+static void remote_device_resume_done(void *_dev)
+{
+	struct isci_remote_device *idev = _dev;
+
+	if (is_remote_device_ready(idev))
+		return;
+
+	/* go 'ready' if we are not already in a ready state */
+	sci_change_state(&idev->sm, SCI_DEV_READY);
+}
+
+static void sci_stp_remote_device_ready_idle_substate_resume_complete_handler(void *_dev)
+{
+	struct isci_remote_device *idev = _dev;
+	struct isci_host *ihost = idev->owning_port->owning_controller;
+
+	/* For NCQ operation we do not issue a isci_remote_device_not_ready().
+	 * As a result, avoid sending the ready notification.
+	 */
+	if (idev->sm.previous_state_id != SCI_STP_DEV_NCQ)
+		isci_remote_device_ready(ihost, idev);
+}
+
+static void sci_remote_device_initial_state_enter(struct sci_base_state_machine *sm)
+{
+	struct isci_remote_device *idev = container_of(sm, typeof(*idev), sm);
+
+	/* Initial state is a transitional state to the stopped state */
+	sci_change_state(&idev->sm, SCI_DEV_STOPPED);
+}
+
+/**
+ * sci_remote_device_destruct() - free remote node context and destruct
+ * @remote_device: This parameter specifies the remote device to be destructed.
+ *
+ * Remote device objects are a limited resource.  As such, they must be
+ * protected.  Thus calls to construct and destruct are mutually exclusive and
+ * non-reentrant. The return value shall indicate if the device was
+ * successfully destructed or if some failure occurred. enum sci_status This value
+ * is returned if the device is successfully destructed.
+ * SCI_FAILURE_INVALID_REMOTE_DEVICE This value is returned if the supplied
+ * device isn't valid (e.g. it's already been destoryed, the handle isn't
+ * valid, etc.).
+ */
+static enum sci_status sci_remote_device_destruct(struct isci_remote_device *idev)
+{
+	struct sci_base_state_machine *sm = &idev->sm;
+	enum sci_remote_device_states state = sm->current_state_id;
+	struct isci_host *ihost;
+
+	if (state != SCI_DEV_STOPPED) {
+		dev_warn(scirdev_to_dev(idev), "%s: in wrong state: %d\n",
+			 __func__, state);
+		return SCI_FAILURE_INVALID_STATE;
+	}
+
+	ihost = idev->owning_port->owning_controller;
+	sci_controller_free_remote_node_context(ihost, idev,
+						     idev->rnc.remote_node_index);
+	idev->rnc.remote_node_index = SCIC_SDS_REMOTE_NODE_CONTEXT_INVALID_INDEX;
+	sci_change_state(sm, SCI_DEV_FINAL);
+
+	return SCI_SUCCESS;
+}
+
+/**
+ * isci_remote_device_deconstruct() - This function frees an isci_remote_device.
+ * @ihost: This parameter specifies the isci host object.
+ * @idev: This parameter specifies the remote device to be freed.
+ *
+ */
+static void isci_remote_device_deconstruct(struct isci_host *ihost, struct isci_remote_device *idev)
+{
+	dev_dbg(&ihost->pdev->dev,
+		"%s: isci_device = %p\n", __func__, idev);
+
+	/* There should not be any outstanding io's. All paths to
+	 * here should go through isci_remote_device_nuke_requests.
+	 * If we hit this condition, we will need a way to complete
+	 * io requests in process */
+	BUG_ON(!list_empty(&idev->reqs_in_process));
+
+	sci_remote_device_destruct(idev);
+	list_del_init(&idev->node);
+	isci_put_device(idev);
+}
+
+static void sci_remote_device_stopped_state_enter(struct sci_base_state_machine *sm)
+{
+	struct isci_remote_device *idev = container_of(sm, typeof(*idev), sm);
+	struct isci_host *ihost = idev->owning_port->owning_controller;
+	u32 prev_state;
+
+	/* If we are entering from the stopping state let the SCI User know that
+	 * the stop operation has completed.
+	 */
+	prev_state = idev->sm.previous_state_id;
+	if (prev_state == SCI_DEV_STOPPING)
+		isci_remote_device_deconstruct(ihost, idev);
+
+	sci_controller_remote_device_stopped(ihost, idev);
+}
+
+static void sci_remote_device_starting_state_enter(struct sci_base_state_machine *sm)
+{
+	struct isci_remote_device *idev = container_of(sm, typeof(*idev), sm);
+	struct isci_host *ihost = idev->owning_port->owning_controller;
+
+	isci_remote_device_not_ready(ihost, idev,
+				     SCIC_REMOTE_DEVICE_NOT_READY_START_REQUESTED);
+}
+
+static void sci_remote_device_ready_state_enter(struct sci_base_state_machine *sm)
+{
+	struct isci_remote_device *idev = container_of(sm, typeof(*idev), sm);
+	struct isci_host *ihost = idev->owning_port->owning_controller;
+	struct domain_device *dev = idev->domain_dev;
+
+	if (dev->dev_type == SATA_DEV || (dev->tproto & SAS_PROTOCOL_SATA)) {
+		sci_change_state(&idev->sm, SCI_STP_DEV_IDLE);
+	} else if (dev_is_expander(dev)) {
+		sci_change_state(&idev->sm, SCI_SMP_DEV_IDLE);
+	} else
+		isci_remote_device_ready(ihost, idev);
+}
+
+static void sci_remote_device_ready_state_exit(struct sci_base_state_machine *sm)
+{
+	struct isci_remote_device *idev = container_of(sm, typeof(*idev), sm);
+	struct domain_device *dev = idev->domain_dev;
+
+	if (dev->dev_type == SAS_END_DEV) {
+		struct isci_host *ihost = idev->owning_port->owning_controller;
+
+		isci_remote_device_not_ready(ihost, idev,
+					     SCIC_REMOTE_DEVICE_NOT_READY_STOP_REQUESTED);
+	}
+}
+
+static void sci_remote_device_resetting_state_enter(struct sci_base_state_machine *sm)
+{
+	struct isci_remote_device *idev = container_of(sm, typeof(*idev), sm);
+
+	sci_remote_node_context_suspend(
+		&idev->rnc, SCI_SOFTWARE_SUSPENSION, NULL, NULL);
+}
+
+static void sci_remote_device_resetting_state_exit(struct sci_base_state_machine *sm)
+{
+	struct isci_remote_device *idev = container_of(sm, typeof(*idev), sm);
+
+	sci_remote_node_context_resume(&idev->rnc, NULL, NULL);
+}
+
+static void sci_stp_remote_device_ready_idle_substate_enter(struct sci_base_state_machine *sm)
+{
+	struct isci_remote_device *idev = container_of(sm, typeof(*idev), sm);
+
+	idev->working_request = NULL;
+	if (sci_remote_node_context_is_ready(&idev->rnc)) {
+		/*
+		 * Since the RNC is ready, it's alright to finish completion
+		 * processing (e.g. signal the remote device is ready). */
+		sci_stp_remote_device_ready_idle_substate_resume_complete_handler(idev);
+	} else {
+		sci_remote_node_context_resume(&idev->rnc,
+			sci_stp_remote_device_ready_idle_substate_resume_complete_handler,
+			idev);
+	}
+}
+
+static void sci_stp_remote_device_ready_cmd_substate_enter(struct sci_base_state_machine *sm)
+{
+	struct isci_remote_device *idev = container_of(sm, typeof(*idev), sm);
+	struct isci_host *ihost = idev->owning_port->owning_controller;
+
+	BUG_ON(idev->working_request == NULL);
+
+	isci_remote_device_not_ready(ihost, idev,
+				     SCIC_REMOTE_DEVICE_NOT_READY_SATA_REQUEST_STARTED);
+}
+
+static void sci_stp_remote_device_ready_ncq_error_substate_enter(struct sci_base_state_machine *sm)
+{
+	struct isci_remote_device *idev = container_of(sm, typeof(*idev), sm);
+	struct isci_host *ihost = idev->owning_port->owning_controller;
+
+	if (idev->not_ready_reason == SCIC_REMOTE_DEVICE_NOT_READY_SATA_SDB_ERROR_FIS_RECEIVED)
+		isci_remote_device_not_ready(ihost, idev,
+					     idev->not_ready_reason);
+}
+
+static void sci_smp_remote_device_ready_idle_substate_enter(struct sci_base_state_machine *sm)
+{
+	struct isci_remote_device *idev = container_of(sm, typeof(*idev), sm);
+	struct isci_host *ihost = idev->owning_port->owning_controller;
+
+	isci_remote_device_ready(ihost, idev);
+}
+
+static void sci_smp_remote_device_ready_cmd_substate_enter(struct sci_base_state_machine *sm)
+{
+	struct isci_remote_device *idev = container_of(sm, typeof(*idev), sm);
+	struct isci_host *ihost = idev->owning_port->owning_controller;
+
+	BUG_ON(idev->working_request == NULL);
+
+	isci_remote_device_not_ready(ihost, idev,
+				     SCIC_REMOTE_DEVICE_NOT_READY_SMP_REQUEST_STARTED);
+}
+
+static void sci_smp_remote_device_ready_cmd_substate_exit(struct sci_base_state_machine *sm)
+{
+	struct isci_remote_device *idev = container_of(sm, typeof(*idev), sm);
+
+	idev->working_request = NULL;
+}
+
+static const struct sci_base_state sci_remote_device_state_table[] = {
+	[SCI_DEV_INITIAL] = {
+		.enter_state = sci_remote_device_initial_state_enter,
+	},
+	[SCI_DEV_STOPPED] = {
+		.enter_state = sci_remote_device_stopped_state_enter,
+	},
+	[SCI_DEV_STARTING] = {
+		.enter_state = sci_remote_device_starting_state_enter,
+	},
+	[SCI_DEV_READY] = {
+		.enter_state = sci_remote_device_ready_state_enter,
+		.exit_state  = sci_remote_device_ready_state_exit
+	},
+	[SCI_STP_DEV_IDLE] = {
+		.enter_state = sci_stp_remote_device_ready_idle_substate_enter,
+	},
+	[SCI_STP_DEV_CMD] = {
+		.enter_state = sci_stp_remote_device_ready_cmd_substate_enter,
+	},
+	[SCI_STP_DEV_NCQ] = { },
+	[SCI_STP_DEV_NCQ_ERROR] = {
+		.enter_state = sci_stp_remote_device_ready_ncq_error_substate_enter,
+	},
+	[SCI_STP_DEV_AWAIT_RESET] = { },
+	[SCI_SMP_DEV_IDLE] = {
+		.enter_state = sci_smp_remote_device_ready_idle_substate_enter,
+	},
+	[SCI_SMP_DEV_CMD] = {
+		.enter_state = sci_smp_remote_device_ready_cmd_substate_enter,
+		.exit_state  = sci_smp_remote_device_ready_cmd_substate_exit,
+	},
+	[SCI_DEV_STOPPING] = { },
+	[SCI_DEV_FAILED] = { },
+	[SCI_DEV_RESETTING] = {
+		.enter_state = sci_remote_device_resetting_state_enter,
+		.exit_state  = sci_remote_device_resetting_state_exit
+	},
+	[SCI_DEV_FINAL] = { },
+};
+
+/**
+ * sci_remote_device_construct() - common construction
+ * @sci_port: SAS/SATA port through which this device is accessed.
+ * @sci_dev: remote device to construct
+ *
+ * This routine just performs benign initialization and does not
+ * allocate the remote_node_context which is left to
+ * sci_remote_device_[de]a_construct().  sci_remote_device_destruct()
+ * frees the remote_node_context(s) for the device.
+ */
+static void sci_remote_device_construct(struct isci_port *iport,
+				  struct isci_remote_device *idev)
+{
+	idev->owning_port = iport;
+	idev->started_request_count = 0;
+
+	sci_init_sm(&idev->sm, sci_remote_device_state_table, SCI_DEV_INITIAL);
+
+	sci_remote_node_context_construct(&idev->rnc,
+					       SCIC_SDS_REMOTE_NODE_CONTEXT_INVALID_INDEX);
+}
+
+/**
+ * sci_remote_device_da_construct() - construct direct attached device.
+ *
+ * The information (e.g. IAF, Signature FIS, etc.) necessary to build
+ * the device is known to the SCI Core since it is contained in the
+ * sci_phy object.  Remote node context(s) is/are a global resource
+ * allocated by this routine, freed by sci_remote_device_destruct().
+ *
+ * Returns:
+ * SCI_FAILURE_DEVICE_EXISTS - device has already been constructed.
+ * SCI_FAILURE_UNSUPPORTED_PROTOCOL - e.g. sas device attached to
+ * sata-only controller instance.
+ * SCI_FAILURE_INSUFFICIENT_RESOURCES - remote node contexts exhausted.
+ */
+static enum sci_status sci_remote_device_da_construct(struct isci_port *iport,
+						       struct isci_remote_device *idev)
+{
+	enum sci_status status;
+	struct domain_device *dev = idev->domain_dev;
+
+	sci_remote_device_construct(iport, idev);
+
+	/*
+	 * This information is request to determine how many remote node context
+	 * entries will be needed to store the remote node.
+	 */
+	idev->is_direct_attached = true;
+	status = sci_controller_allocate_remote_node_context(iport->owning_controller,
+								  idev,
+								  &idev->rnc.remote_node_index);
+
+	if (status != SCI_SUCCESS)
+		return status;
+
+	if (dev->dev_type == SAS_END_DEV || dev->dev_type == SATA_DEV ||
+	    (dev->tproto & SAS_PROTOCOL_STP) || dev_is_expander(dev))
+		/* pass */;
+	else
+		return SCI_FAILURE_UNSUPPORTED_PROTOCOL;
+
+	idev->connection_rate = sci_port_get_max_allowed_speed(iport);
+
+	/* / @todo Should I assign the port width by reading all of the phys on the port? */
+	idev->device_port_width = 1;
+
+	return SCI_SUCCESS;
+}
+
+/**
+ * sci_remote_device_ea_construct() - construct expander attached device
+ *
+ * Remote node context(s) is/are a global resource allocated by this
+ * routine, freed by sci_remote_device_destruct().
+ *
+ * Returns:
+ * SCI_FAILURE_DEVICE_EXISTS - device has already been constructed.
+ * SCI_FAILURE_UNSUPPORTED_PROTOCOL - e.g. sas device attached to
+ * sata-only controller instance.
+ * SCI_FAILURE_INSUFFICIENT_RESOURCES - remote node contexts exhausted.
+ */
+static enum sci_status sci_remote_device_ea_construct(struct isci_port *iport,
+						       struct isci_remote_device *idev)
+{
+	struct domain_device *dev = idev->domain_dev;
+	enum sci_status status;
+
+	sci_remote_device_construct(iport, idev);
+
+	status = sci_controller_allocate_remote_node_context(iport->owning_controller,
+								  idev,
+								  &idev->rnc.remote_node_index);
+	if (status != SCI_SUCCESS)
+		return status;
+
+	if (dev->dev_type == SAS_END_DEV || dev->dev_type == SATA_DEV ||
+	    (dev->tproto & SAS_PROTOCOL_STP) || dev_is_expander(dev))
+		/* pass */;
+	else
+		return SCI_FAILURE_UNSUPPORTED_PROTOCOL;
+
+	/*
+	 * For SAS-2 the physical link rate is actually a logical link
+	 * rate that incorporates multiplexing.  The SCU doesn't
+	 * incorporate multiplexing and for the purposes of the
+	 * connection the logical link rate is that same as the
+	 * physical.  Furthermore, the SAS-2 and SAS-1.1 fields overlay
+	 * one another, so this code works for both situations. */
+	idev->connection_rate = min_t(u16, sci_port_get_max_allowed_speed(iport),
+					 dev->linkrate);
+
+	/* / @todo Should I assign the port width by reading all of the phys on the port? */
+	idev->device_port_width = 1;
+
+	return SCI_SUCCESS;
+}
+
+/**
+ * sci_remote_device_start() - This method will start the supplied remote
+ *    device.  This method enables normal IO requests to flow through to the
+ *    remote device.
+ * @remote_device: This parameter specifies the device to be started.
+ * @timeout: This parameter specifies the number of milliseconds in which the
+ *    start operation should complete.
+ *
+ * An indication of whether the device was successfully started. SCI_SUCCESS
+ * This value is returned if the device was successfully started.
+ * SCI_FAILURE_INVALID_PHY This value is returned if the user attempts to start
+ * the device when there have been no phys added to it.
+ */
+static enum sci_status sci_remote_device_start(struct isci_remote_device *idev,
+						u32 timeout)
+{
+	struct sci_base_state_machine *sm = &idev->sm;
+	enum sci_remote_device_states state = sm->current_state_id;
+	enum sci_status status;
+
+	if (state != SCI_DEV_STOPPED) {
+		dev_warn(scirdev_to_dev(idev), "%s: in wrong state: %d\n",
+			 __func__, state);
+		return SCI_FAILURE_INVALID_STATE;
+	}
+
+	status = sci_remote_node_context_resume(&idev->rnc,
+						     remote_device_resume_done,
+						     idev);
+	if (status != SCI_SUCCESS)
+		return status;
+
+	sci_change_state(sm, SCI_DEV_STARTING);
+
+	return SCI_SUCCESS;
+}
+
+static enum sci_status isci_remote_device_construct(struct isci_port *iport,
+						    struct isci_remote_device *idev)
+{
+	struct isci_host *ihost = iport->isci_host;
+	struct domain_device *dev = idev->domain_dev;
+	enum sci_status status;
+
+	if (dev->parent && dev_is_expander(dev->parent))
+		status = sci_remote_device_ea_construct(iport, idev);
+	else
+		status = sci_remote_device_da_construct(iport, idev);
+
+	if (status != SCI_SUCCESS) {
+		dev_dbg(&ihost->pdev->dev, "%s: construct failed: %d\n",
+			__func__, status);
+
+		return status;
+	}
+
+	/* start the device. */
+	status = sci_remote_device_start(idev, ISCI_REMOTE_DEVICE_START_TIMEOUT);
+
+	if (status != SCI_SUCCESS)
+		dev_warn(&ihost->pdev->dev, "remote device start failed: %d\n",
+			 status);
+
+	return status;
+}
+
+void isci_remote_device_nuke_requests(struct isci_host *ihost, struct isci_remote_device *idev)
+{
+	DECLARE_COMPLETION_ONSTACK(aborted_task_completion);
+
+	dev_dbg(&ihost->pdev->dev,
+		"%s: idev = %p\n", __func__, idev);
+
+	/* Cleanup all requests pending for this device. */
+	isci_terminate_pending_requests(ihost, idev);
+
+	dev_dbg(&ihost->pdev->dev,
+		"%s: idev = %p, done\n", __func__, idev);
+}
+
+/**
+ * This function builds the isci_remote_device when a libsas dev_found message
+ *    is received.
+ * @isci_host: This parameter specifies the isci host object.
+ * @port: This parameter specifies the isci_port conected to this device.
+ *
+ * pointer to new isci_remote_device.
+ */
+static struct isci_remote_device *
+isci_remote_device_alloc(struct isci_host *ihost, struct isci_port *iport)
+{
+	struct isci_remote_device *idev;
+	int i;
+
+	for (i = 0; i < SCI_MAX_REMOTE_DEVICES; i++) {
+		idev = &ihost->devices[i];
+		if (!test_and_set_bit(IDEV_ALLOCATED, &idev->flags))
+			break;
+	}
+
+	if (i >= SCI_MAX_REMOTE_DEVICES) {
+		dev_warn(&ihost->pdev->dev, "%s: failed\n", __func__);
+		return NULL;
+	}
+
+	if (WARN_ONCE(!list_empty(&idev->reqs_in_process), "found requests in process\n"))
+		return NULL;
+
+	if (WARN_ONCE(!list_empty(&idev->node), "found non-idle remote device\n"))
+		return NULL;
+
+	return idev;
+}
+
+void isci_remote_device_release(struct kref *kref)
+{
+	struct isci_remote_device *idev = container_of(kref, typeof(*idev), kref);
+	struct isci_host *ihost = idev->isci_port->isci_host;
+
+	idev->domain_dev = NULL;
+	idev->isci_port = NULL;
+	clear_bit(IDEV_START_PENDING, &idev->flags);
+	clear_bit(IDEV_STOP_PENDING, &idev->flags);
+	clear_bit(IDEV_IO_READY, &idev->flags);
+	clear_bit(IDEV_GONE, &idev->flags);
+	clear_bit(IDEV_EH, &idev->flags);
+	smp_mb__before_clear_bit();
+	clear_bit(IDEV_ALLOCATED, &idev->flags);
+	wake_up(&ihost->eventq);
+}
+
+/**
+ * isci_remote_device_stop() - This function is called internally to stop the
+ *    remote device.
+ * @isci_host: This parameter specifies the isci host object.
+ * @isci_device: This parameter specifies the remote device.
+ *
+ * The status of the ihost request to stop.
+ */
+enum sci_status isci_remote_device_stop(struct isci_host *ihost, struct isci_remote_device *idev)
+{
+	enum sci_status status;
+	unsigned long flags;
+
+	dev_dbg(&ihost->pdev->dev,
+		"%s: isci_device = %p\n", __func__, idev);
+
+	spin_lock_irqsave(&ihost->scic_lock, flags);
+	idev->domain_dev->lldd_dev = NULL; /* disable new lookups */
+	set_bit(IDEV_GONE, &idev->flags);
+	spin_unlock_irqrestore(&ihost->scic_lock, flags);
+
+	/* Kill all outstanding requests. */
+	isci_remote_device_nuke_requests(ihost, idev);
+
+	set_bit(IDEV_STOP_PENDING, &idev->flags);
+
+	spin_lock_irqsave(&ihost->scic_lock, flags);
+	status = sci_remote_device_stop(idev, 50);
+	spin_unlock_irqrestore(&ihost->scic_lock, flags);
+
+	/* Wait for the stop complete callback. */
+	if (WARN_ONCE(status != SCI_SUCCESS, "failed to stop device\n"))
+		/* nothing to wait for */;
+	else
+		wait_for_device_stop(ihost, idev);
+
+	return status;
+}
+
+/**
+ * isci_remote_device_gone() - This function is called by libsas when a domain
+ *    device is removed.
+ * @domain_device: This parameter specifies the libsas domain device.
+ *
+ */
+void isci_remote_device_gone(struct domain_device *dev)
+{
+	struct isci_host *ihost = dev_to_ihost(dev);
+	struct isci_remote_device *idev = dev->lldd_dev;
+
+	dev_dbg(&ihost->pdev->dev,
+		"%s: domain_device = %p, isci_device = %p, isci_port = %p\n",
+		__func__, dev, idev, idev->isci_port);
+
+	isci_remote_device_stop(ihost, idev);
+}
+
+
+/**
+ * isci_remote_device_found() - This function is called by libsas when a remote
+ *    device is discovered. A remote device object is created and started. the
+ *    function then sleeps until the sci core device started message is
+ *    received.
+ * @domain_device: This parameter specifies the libsas domain device.
+ *
+ * status, zero indicates success.
+ */
+int isci_remote_device_found(struct domain_device *domain_dev)
+{
+	struct isci_host *isci_host = dev_to_ihost(domain_dev);
+	struct isci_port *isci_port;
+	struct isci_phy *isci_phy;
+	struct asd_sas_port *sas_port;
+	struct asd_sas_phy *sas_phy;
+	struct isci_remote_device *isci_device;
+	enum sci_status status;
+
+	dev_dbg(&isci_host->pdev->dev,
+		"%s: domain_device = %p\n", __func__, domain_dev);
+
+	wait_for_start(isci_host);
+
+	sas_port = domain_dev->port;
+	sas_phy = list_first_entry(&sas_port->phy_list, struct asd_sas_phy,
+				   port_phy_el);
+	isci_phy = to_iphy(sas_phy);
+	isci_port = isci_phy->isci_port;
+
+	/* we are being called for a device on this port,
+	 * so it has to come up eventually
+	 */
+	wait_for_completion(&isci_port->start_complete);
+
+	if ((isci_stopping == isci_port_get_state(isci_port)) ||
+	    (isci_stopped == isci_port_get_state(isci_port)))
+		return -ENODEV;
+
+	isci_device = isci_remote_device_alloc(isci_host, isci_port);
+	if (!isci_device)
+		return -ENODEV;
+
+	kref_init(&isci_device->kref);
+	INIT_LIST_HEAD(&isci_device->node);
+
+	spin_lock_irq(&isci_host->scic_lock);
+	isci_device->domain_dev = domain_dev;
+	isci_device->isci_port = isci_port;
+	list_add_tail(&isci_device->node, &isci_port->remote_dev_list);
+
+	set_bit(IDEV_START_PENDING, &isci_device->flags);
+	status = isci_remote_device_construct(isci_port, isci_device);
+
+	dev_dbg(&isci_host->pdev->dev,
+		"%s: isci_device = %p\n",
+		__func__, isci_device);
+
+	if (status == SCI_SUCCESS) {
+		/* device came up, advertise it to the world */
+		domain_dev->lldd_dev = isci_device;
+	} else
+		isci_put_device(isci_device);
+	spin_unlock_irq(&isci_host->scic_lock);
+
+	/* wait for the device ready callback. */
+	wait_for_device_start(isci_host, isci_device);
+
+	return status == SCI_SUCCESS ? 0 : -ENODEV;
+}
+/**
+ * isci_device_is_reset_pending() - This function will check if there is any
+ *    pending reset condition on the device.
+ * @request: This parameter is the isci_device object.
+ *
+ * true if there is a reset pending for the device.
+ */
+bool isci_device_is_reset_pending(
+	struct isci_host *isci_host,
+	struct isci_remote_device *isci_device)
+{
+	struct isci_request *isci_request;
+	struct isci_request *tmp_req;
+	bool reset_is_pending = false;
+	unsigned long flags;
+
+	dev_dbg(&isci_host->pdev->dev,
+		"%s: isci_device = %p\n", __func__, isci_device);
+
+	spin_lock_irqsave(&isci_host->scic_lock, flags);
+
+	/* Check for reset on all pending requests. */
+	list_for_each_entry_safe(isci_request, tmp_req,
+				 &isci_device->reqs_in_process, dev_node) {
+		dev_dbg(&isci_host->pdev->dev,
+			"%s: isci_device = %p request = %p\n",
+			__func__, isci_device, isci_request);
+
+		if (isci_request->ttype == io_task) {
+			struct sas_task *task = isci_request_access_task(
+				isci_request);
+
+			spin_lock(&task->task_state_lock);
+			if (task->task_state_flags & SAS_TASK_NEED_DEV_RESET)
+				reset_is_pending = true;
+			spin_unlock(&task->task_state_lock);
+		}
+	}
+
+	spin_unlock_irqrestore(&isci_host->scic_lock, flags);
+
+	dev_dbg(&isci_host->pdev->dev,
+		"%s: isci_device = %p reset_is_pending = %d\n",
+		__func__, isci_device, reset_is_pending);
+
+	return reset_is_pending;
+}
+
+/**
+ * isci_device_clear_reset_pending() - This function will clear if any pending
+ *    reset condition flags on the device.
+ * @request: This parameter is the isci_device object.
+ *
+ * true if there is a reset pending for the device.
+ */
+void isci_device_clear_reset_pending(struct isci_host *ihost, struct isci_remote_device *idev)
+{
+	struct isci_request *isci_request;
+	struct isci_request *tmp_req;
+	unsigned long flags = 0;
+
+	dev_dbg(&ihost->pdev->dev, "%s: idev=%p, ihost=%p\n",
+		 __func__, idev, ihost);
+
+	spin_lock_irqsave(&ihost->scic_lock, flags);
+
+	/* Clear reset pending on all pending requests. */
+	list_for_each_entry_safe(isci_request, tmp_req,
+				 &idev->reqs_in_process, dev_node) {
+		dev_dbg(&ihost->pdev->dev, "%s: idev = %p request = %p\n",
+			 __func__, idev, isci_request);
+
+		if (isci_request->ttype == io_task) {
+
+			unsigned long flags2;
+			struct sas_task *task = isci_request_access_task(
+				isci_request);
+
+			spin_lock_irqsave(&task->task_state_lock, flags2);
+			task->task_state_flags &= ~SAS_TASK_NEED_DEV_RESET;
+			spin_unlock_irqrestore(&task->task_state_lock, flags2);
+		}
+	}
+	spin_unlock_irqrestore(&ihost->scic_lock, flags);
+}
diff -druN linux-2.6.39-libre/drivers/scsi/isci/remote_device.h linux-3.0-rc7-libre/drivers/scsi/isci/remote_device.h
--- linux-2.6.39-libre/drivers/scsi/isci/remote_device.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/scsi/isci/remote_device.h	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,352 @@
+/*
+ * This file is provided under a dual BSD/GPLv2 license.  When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * The full GNU General Public License is included in this distribution
+ * in the file called LICENSE.GPL.
+ *
+ * BSD LICENSE
+ *
+ * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in
+ *     the documentation and/or other materials provided with the
+ *     distribution.
+ *   * Neither the name of Intel Corporation nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _ISCI_REMOTE_DEVICE_H_
+#define _ISCI_REMOTE_DEVICE_H_
+#include <scsi/libsas.h>
+#include <linux/kref.h>
+#include "scu_remote_node_context.h"
+#include "remote_node_context.h"
+#include "port.h"
+
+enum sci_remote_device_not_ready_reason_code {
+	SCIC_REMOTE_DEVICE_NOT_READY_START_REQUESTED,
+	SCIC_REMOTE_DEVICE_NOT_READY_STOP_REQUESTED,
+	SCIC_REMOTE_DEVICE_NOT_READY_SATA_REQUEST_STARTED,
+	SCIC_REMOTE_DEVICE_NOT_READY_SATA_SDB_ERROR_FIS_RECEIVED,
+	SCIC_REMOTE_DEVICE_NOT_READY_SMP_REQUEST_STARTED,
+	SCIC_REMOTE_DEVICE_NOT_READY_REASON_CODE_MAX
+};
+
+/**
+ * isci_remote_device - isci representation of a sas expander / end point
+ * @device_port_width: hw setting for number of simultaneous connections
+ * @connection_rate: per-taskcontext connection rate for this device
+ * @working_request: SATA requests have no tag we for unaccelerated
+ *                   protocols we need a method to associate unsolicited
+ *                   frames with a pending request
+ */
+struct isci_remote_device {
+	#define IDEV_START_PENDING 0
+	#define IDEV_STOP_PENDING 1
+	#define IDEV_ALLOCATED 2
+	#define IDEV_EH 3
+	#define IDEV_GONE 4
+	#define IDEV_IO_READY 5
+	#define IDEV_IO_NCQERROR 6
+	unsigned long flags;
+	struct kref kref;
+	struct isci_port *isci_port;
+	struct domain_device *domain_dev;
+	struct list_head node;
+	struct list_head reqs_in_process;
+	struct sci_base_state_machine sm;
+	u32 device_port_width;
+	enum sas_linkrate connection_rate;
+	bool is_direct_attached;
+	struct isci_port *owning_port;
+	struct sci_remote_node_context rnc;
+	/* XXX unify with device reference counting and delete */
+	u32 started_request_count;
+	struct isci_request *working_request;
+	u32 not_ready_reason;
+};
+
+#define ISCI_REMOTE_DEVICE_START_TIMEOUT 5000
+
+/* device reference routines must be called under sci_lock */
+static inline struct isci_remote_device *isci_lookup_device(struct domain_device *dev)
+{
+	struct isci_remote_device *idev = dev->lldd_dev;
+
+	if (idev && !test_bit(IDEV_GONE, &idev->flags)) {
+		kref_get(&idev->kref);
+		return idev;
+	}
+
+	return NULL;
+}
+
+void isci_remote_device_release(struct kref *kref);
+static inline void isci_put_device(struct isci_remote_device *idev)
+{
+	if (idev)
+		kref_put(&idev->kref, isci_remote_device_release);
+}
+
+enum sci_status isci_remote_device_stop(struct isci_host *ihost,
+					struct isci_remote_device *idev);
+void isci_remote_device_nuke_requests(struct isci_host *ihost,
+				      struct isci_remote_device *idev);
+void isci_remote_device_gone(struct domain_device *domain_dev);
+int isci_remote_device_found(struct domain_device *domain_dev);
+bool isci_device_is_reset_pending(struct isci_host *ihost,
+				  struct isci_remote_device *idev);
+void isci_device_clear_reset_pending(struct isci_host *ihost,
+				     struct isci_remote_device *idev);
+/**
+ * sci_remote_device_stop() - This method will stop both transmission and
+ *    reception of link activity for the supplied remote device.  This method
+ *    disables normal IO requests from flowing through to the remote device.
+ * @remote_device: This parameter specifies the device to be stopped.
+ * @timeout: This parameter specifies the number of milliseconds in which the
+ *    stop operation should complete.
+ *
+ * An indication of whether the device was successfully stopped. SCI_SUCCESS
+ * This value is returned if the transmission and reception for the device was
+ * successfully stopped.
+ */
+enum sci_status sci_remote_device_stop(
+	struct isci_remote_device *idev,
+	u32 timeout);
+
+/**
+ * sci_remote_device_reset() - This method will reset the device making it
+ *    ready for operation. This method must be called anytime the device is
+ *    reset either through a SMP phy control or a port hard reset request.
+ * @remote_device: This parameter specifies the device to be reset.
+ *
+ * This method does not actually cause the device hardware to be reset. This
+ * method resets the software object so that it will be operational after a
+ * device hardware reset completes. An indication of whether the device reset
+ * was accepted. SCI_SUCCESS This value is returned if the device reset is
+ * started.
+ */
+enum sci_status sci_remote_device_reset(
+	struct isci_remote_device *idev);
+
+/**
+ * sci_remote_device_reset_complete() - This method informs the device object
+ *    that the reset operation is complete and the device can resume operation
+ *    again.
+ * @remote_device: This parameter specifies the device which is to be informed
+ *    of the reset complete operation.
+ *
+ * An indication that the device is resuming operation. SCI_SUCCESS the device
+ * is resuming operation.
+ */
+enum sci_status sci_remote_device_reset_complete(
+	struct isci_remote_device *idev);
+
+/**
+ * enum sci_remote_device_states - This enumeration depicts all the states
+ *    for the common remote device state machine.
+ *
+ *
+ */
+enum sci_remote_device_states {
+	/**
+	 * Simply the initial state for the base remote device state machine.
+	 */
+	SCI_DEV_INITIAL,
+
+	/**
+	 * This state indicates that the remote device has successfully been
+	 * stopped.  In this state no new IO operations are permitted.
+	 * This state is entered from the INITIAL state.
+	 * This state is entered from the STOPPING state.
+	 */
+	SCI_DEV_STOPPED,
+
+	/**
+	 * This state indicates the the remote device is in the process of
+	 * becoming ready (i.e. starting).  In this state no new IO operations
+	 * are permitted.
+	 * This state is entered from the STOPPED state.
+	 */
+	SCI_DEV_STARTING,
+
+	/**
+	 * This state indicates the remote device is now ready.  Thus, the user
+	 * is able to perform IO operations on the remote device.
+	 * This state is entered from the STARTING state.
+	 */
+	SCI_DEV_READY,
+
+	/**
+	 * This is the idle substate for the stp remote device.  When there are no
+	 * active IO for the device it is is in this state.
+	 */
+	SCI_STP_DEV_IDLE,
+
+	/**
+	 * This is the command state for for the STP remote device.  This state is
+	 * entered when the device is processing a non-NCQ command.  The device object
+	 * will fail any new start IO requests until this command is complete.
+	 */
+	SCI_STP_DEV_CMD,
+
+	/**
+	 * This is the NCQ state for the STP remote device.  This state is entered
+	 * when the device is processing an NCQ reuqest.  It will remain in this state
+	 * so long as there is one or more NCQ requests being processed.
+	 */
+	SCI_STP_DEV_NCQ,
+
+	/**
+	 * This is the NCQ error state for the STP remote device.  This state is
+	 * entered when an SDB error FIS is received by the device object while in the
+	 * NCQ state.  The device object will only accept a READ LOG command while in
+	 * this state.
+	 */
+	SCI_STP_DEV_NCQ_ERROR,
+
+	/**
+	 * This is the READY substate indicates the device is waiting for the RESET task
+	 * coming to be recovered from certain hardware specific error.
+	 */
+	SCI_STP_DEV_AWAIT_RESET,
+
+	/**
+	 * This is the ready operational substate for the remote device.  This is the
+	 * normal operational state for a remote device.
+	 */
+	SCI_SMP_DEV_IDLE,
+
+	/**
+	 * This is the suspended state for the remote device.  This is the state that
+	 * the device is placed in when a RNC suspend is received by the SCU hardware.
+	 */
+	SCI_SMP_DEV_CMD,
+
+	/**
+	 * This state indicates that the remote device is in the process of
+	 * stopping.  In this state no new IO operations are permitted, but
+	 * existing IO operations are allowed to complete.
+	 * This state is entered from the READY state.
+	 * This state is entered from the FAILED state.
+	 */
+	SCI_DEV_STOPPING,
+
+	/**
+	 * This state indicates that the remote device has failed.
+	 * In this state no new IO operations are permitted.
+	 * This state is entered from the INITIALIZING state.
+	 * This state is entered from the READY state.
+	 */
+	SCI_DEV_FAILED,
+
+	/**
+	 * This state indicates the device is being reset.
+	 * In this state no new IO operations are permitted.
+	 * This state is entered from the READY state.
+	 */
+	SCI_DEV_RESETTING,
+
+	/**
+	 * Simply the final state for the base remote device state machine.
+	 */
+	SCI_DEV_FINAL,
+};
+
+static inline struct isci_remote_device *rnc_to_dev(struct sci_remote_node_context *rnc)
+{
+	struct isci_remote_device *idev;
+
+	idev = container_of(rnc, typeof(*idev), rnc);
+
+	return idev;
+}
+
+static inline bool dev_is_expander(struct domain_device *dev)
+{
+	return dev->dev_type == EDGE_DEV || dev->dev_type == FANOUT_DEV;
+}
+
+static inline void sci_remote_device_decrement_request_count(struct isci_remote_device *idev)
+{
+	/* XXX delete this voodoo when converting to the top-level device
+	 * reference count
+	 */
+	if (WARN_ONCE(idev->started_request_count == 0,
+		      "%s: tried to decrement started_request_count past 0!?",
+			__func__))
+		/* pass */;
+	else
+		idev->started_request_count--;
+}
+
+enum sci_status sci_remote_device_frame_handler(
+	struct isci_remote_device *idev,
+	u32 frame_index);
+
+enum sci_status sci_remote_device_event_handler(
+	struct isci_remote_device *idev,
+	u32 event_code);
+
+enum sci_status sci_remote_device_start_io(
+	struct isci_host *ihost,
+	struct isci_remote_device *idev,
+	struct isci_request *ireq);
+
+enum sci_status sci_remote_device_start_task(
+	struct isci_host *ihost,
+	struct isci_remote_device *idev,
+	struct isci_request *ireq);
+
+enum sci_status sci_remote_device_complete_io(
+	struct isci_host *ihost,
+	struct isci_remote_device *idev,
+	struct isci_request *ireq);
+
+enum sci_status sci_remote_device_suspend(
+	struct isci_remote_device *idev,
+	u32 suspend_type);
+
+void sci_remote_device_post_request(
+	struct isci_remote_device *idev,
+	u32 request);
+
+#endif /* !defined(_ISCI_REMOTE_DEVICE_H_) */
diff -druN linux-2.6.39-libre/drivers/scsi/isci/remote_node_context.c linux-3.0-rc7-libre/drivers/scsi/isci/remote_node_context.c
--- linux-2.6.39-libre/drivers/scsi/isci/remote_node_context.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/scsi/isci/remote_node_context.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,627 @@
+/*
+ * This file is provided under a dual BSD/GPLv2 license.  When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * The full GNU General Public License is included in this distribution
+ * in the file called LICENSE.GPL.
+ *
+ * BSD LICENSE
+ *
+ * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in
+ *     the documentation and/or other materials provided with the
+ *     distribution.
+ *   * Neither the name of Intel Corporation nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "host.h"
+#include "isci.h"
+#include "remote_device.h"
+#include "remote_node_context.h"
+#include "scu_event_codes.h"
+#include "scu_task_context.h"
+
+
+/**
+ *
+ * @sci_rnc: The RNC for which the is posted request is being made.
+ *
+ * This method will return true if the RNC is not in the initial state.  In all
+ * other states the RNC is considered active and this will return true. The
+ * destroy request of the state machine drives the RNC back to the initial
+ * state.  If the state machine changes then this routine will also have to be
+ * changed. bool true if the state machine is not in the initial state false if
+ * the state machine is in the initial state
+ */
+
+/**
+ *
+ * @sci_rnc: The state of the remote node context object to check.
+ *
+ * This method will return true if the remote node context is in a READY state
+ * otherwise it will return false bool true if the remote node context is in
+ * the ready state. false if the remote node context is not in the ready state.
+ */
+bool sci_remote_node_context_is_ready(
+	struct sci_remote_node_context *sci_rnc)
+{
+	u32 current_state = sci_rnc->sm.current_state_id;
+
+	if (current_state == SCI_RNC_READY) {
+		return true;
+	}
+
+	return false;
+}
+
+static union scu_remote_node_context *sci_rnc_by_id(struct isci_host *ihost, u16 id)
+{
+	if (id < ihost->remote_node_entries &&
+	    ihost->device_table[id])
+		return &ihost->remote_node_context_table[id];
+
+	return NULL;
+}
+
+static void sci_remote_node_context_construct_buffer(struct sci_remote_node_context *sci_rnc)
+{
+	struct isci_remote_device *idev = rnc_to_dev(sci_rnc);
+	struct domain_device *dev = idev->domain_dev;
+	int rni = sci_rnc->remote_node_index;
+	union scu_remote_node_context *rnc;
+	struct isci_host *ihost;
+	__le64 sas_addr;
+
+	ihost = idev->owning_port->owning_controller;
+	rnc = sci_rnc_by_id(ihost, rni);
+
+	memset(rnc, 0, sizeof(union scu_remote_node_context)
+		* sci_remote_device_node_count(idev));
+
+	rnc->ssp.remote_node_index = rni;
+	rnc->ssp.remote_node_port_width = idev->device_port_width;
+	rnc->ssp.logical_port_index = idev->owning_port->physical_port_index;
+
+	/* sas address is __be64, context ram format is __le64 */
+	sas_addr = cpu_to_le64(SAS_ADDR(dev->sas_addr));
+	rnc->ssp.remote_sas_address_hi = upper_32_bits(sas_addr);
+	rnc->ssp.remote_sas_address_lo = lower_32_bits(sas_addr);
+
+	rnc->ssp.nexus_loss_timer_enable = true;
+	rnc->ssp.check_bit               = false;
+	rnc->ssp.is_valid                = false;
+	rnc->ssp.is_remote_node_context  = true;
+	rnc->ssp.function_number         = 0;
+
+	rnc->ssp.arbitration_wait_time = 0;
+
+	if (dev->dev_type == SATA_DEV || (dev->tproto & SAS_PROTOCOL_STP)) {
+		rnc->ssp.connection_occupancy_timeout =
+			ihost->user_parameters.stp_max_occupancy_timeout;
+		rnc->ssp.connection_inactivity_timeout =
+			ihost->user_parameters.stp_inactivity_timeout;
+	} else {
+		rnc->ssp.connection_occupancy_timeout  =
+			ihost->user_parameters.ssp_max_occupancy_timeout;
+		rnc->ssp.connection_inactivity_timeout =
+			ihost->user_parameters.ssp_inactivity_timeout;
+	}
+
+	rnc->ssp.initial_arbitration_wait_time = 0;
+
+	/* Open Address Frame Parameters */
+	rnc->ssp.oaf_connection_rate = idev->connection_rate;
+	rnc->ssp.oaf_features = 0;
+	rnc->ssp.oaf_source_zone_group = 0;
+	rnc->ssp.oaf_more_compatibility_features = 0;
+}
+
+/**
+ *
+ * @sci_rnc:
+ * @callback:
+ * @callback_parameter:
+ *
+ * This method will setup the remote node context object so it will transition
+ * to its ready state.  If the remote node context is already setup to
+ * transition to its final state then this function does nothing. none
+ */
+static void sci_remote_node_context_setup_to_resume(
+	struct sci_remote_node_context *sci_rnc,
+	scics_sds_remote_node_context_callback callback,
+	void *callback_parameter)
+{
+	if (sci_rnc->destination_state != SCIC_SDS_REMOTE_NODE_DESTINATION_STATE_FINAL) {
+		sci_rnc->destination_state = SCIC_SDS_REMOTE_NODE_DESTINATION_STATE_READY;
+		sci_rnc->user_callback     = callback;
+		sci_rnc->user_cookie       = callback_parameter;
+	}
+}
+
+static void sci_remote_node_context_setup_to_destory(
+	struct sci_remote_node_context *sci_rnc,
+	scics_sds_remote_node_context_callback callback,
+	void *callback_parameter)
+{
+	sci_rnc->destination_state = SCIC_SDS_REMOTE_NODE_DESTINATION_STATE_FINAL;
+	sci_rnc->user_callback     = callback;
+	sci_rnc->user_cookie       = callback_parameter;
+}
+
+/**
+ *
+ *
+ * This method just calls the user callback function and then resets the
+ * callback.
+ */
+static void sci_remote_node_context_notify_user(
+	struct sci_remote_node_context *rnc)
+{
+	if (rnc->user_callback != NULL) {
+		(*rnc->user_callback)(rnc->user_cookie);
+
+		rnc->user_callback = NULL;
+		rnc->user_cookie = NULL;
+	}
+}
+
+static void sci_remote_node_context_continue_state_transitions(struct sci_remote_node_context *rnc)
+{
+	if (rnc->destination_state == SCIC_SDS_REMOTE_NODE_DESTINATION_STATE_READY)
+		sci_remote_node_context_resume(rnc, rnc->user_callback,
+						    rnc->user_cookie);
+}
+
+static void sci_remote_node_context_validate_context_buffer(struct sci_remote_node_context *sci_rnc)
+{
+	union scu_remote_node_context *rnc_buffer;
+	struct isci_remote_device *idev = rnc_to_dev(sci_rnc);
+	struct domain_device *dev = idev->domain_dev;
+	struct isci_host *ihost = idev->owning_port->owning_controller;
+
+	rnc_buffer = sci_rnc_by_id(ihost, sci_rnc->remote_node_index);
+
+	rnc_buffer->ssp.is_valid = true;
+
+	if (!idev->is_direct_attached &&
+	    (dev->dev_type == SATA_DEV || (dev->tproto & SAS_PROTOCOL_STP))) {
+		sci_remote_device_post_request(idev, SCU_CONTEXT_COMMAND_POST_RNC_96);
+	} else {
+		sci_remote_device_post_request(idev, SCU_CONTEXT_COMMAND_POST_RNC_32);
+
+		if (idev->is_direct_attached)
+			sci_port_setup_transports(idev->owning_port,
+						  sci_rnc->remote_node_index);
+	}
+}
+
+static void sci_remote_node_context_invalidate_context_buffer(struct sci_remote_node_context *sci_rnc)
+{
+	union scu_remote_node_context *rnc_buffer;
+	struct isci_remote_device *idev = rnc_to_dev(sci_rnc);
+	struct isci_host *ihost = idev->owning_port->owning_controller;
+
+	rnc_buffer = sci_rnc_by_id(ihost, sci_rnc->remote_node_index);
+
+	rnc_buffer->ssp.is_valid = false;
+
+	sci_remote_device_post_request(rnc_to_dev(sci_rnc),
+				       SCU_CONTEXT_COMMAND_POST_RNC_INVALIDATE);
+}
+
+static void sci_remote_node_context_initial_state_enter(struct sci_base_state_machine *sm)
+{
+	struct sci_remote_node_context *rnc = container_of(sm, typeof(*rnc), sm);
+
+	/* Check to see if we have gotten back to the initial state because
+	 * someone requested to destroy the remote node context object.
+	 */
+	if (sm->previous_state_id == SCI_RNC_INVALIDATING) {
+		rnc->destination_state = SCIC_SDS_REMOTE_NODE_DESTINATION_STATE_UNSPECIFIED;
+		sci_remote_node_context_notify_user(rnc);
+	}
+}
+
+static void sci_remote_node_context_posting_state_enter(struct sci_base_state_machine *sm)
+{
+	struct sci_remote_node_context *sci_rnc = container_of(sm, typeof(*sci_rnc), sm);
+
+	sci_remote_node_context_validate_context_buffer(sci_rnc);
+}
+
+static void sci_remote_node_context_invalidating_state_enter(struct sci_base_state_machine *sm)
+{
+	struct sci_remote_node_context *rnc = container_of(sm, typeof(*rnc), sm);
+
+	sci_remote_node_context_invalidate_context_buffer(rnc);
+}
+
+static void sci_remote_node_context_resuming_state_enter(struct sci_base_state_machine *sm)
+{
+	struct sci_remote_node_context *rnc = container_of(sm, typeof(*rnc), sm);
+	struct isci_remote_device *idev;
+	struct domain_device *dev;
+
+	idev = rnc_to_dev(rnc);
+	dev = idev->domain_dev;
+
+	/*
+	 * For direct attached SATA devices we need to clear the TLCR
+	 * NCQ to TCi tag mapping on the phy and in cases where we
+	 * resume because of a target reset we also need to update
+	 * the STPTLDARNI register with the RNi of the device
+	 */
+	if ((dev->dev_type == SATA_DEV || (dev->tproto & SAS_PROTOCOL_STP)) &&
+	    idev->is_direct_attached)
+		sci_port_setup_transports(idev->owning_port,
+					       rnc->remote_node_index);
+
+	sci_remote_device_post_request(idev, SCU_CONTEXT_COMMAND_POST_RNC_RESUME);
+}
+
+static void sci_remote_node_context_ready_state_enter(struct sci_base_state_machine *sm)
+{
+	struct sci_remote_node_context *rnc = container_of(sm, typeof(*rnc), sm);
+
+	rnc->destination_state = SCIC_SDS_REMOTE_NODE_DESTINATION_STATE_UNSPECIFIED;
+
+	if (rnc->user_callback)
+		sci_remote_node_context_notify_user(rnc);
+}
+
+static void sci_remote_node_context_tx_suspended_state_enter(struct sci_base_state_machine *sm)
+{
+	struct sci_remote_node_context *rnc = container_of(sm, typeof(*rnc), sm);
+
+	sci_remote_node_context_continue_state_transitions(rnc);
+}
+
+static void sci_remote_node_context_tx_rx_suspended_state_enter(struct sci_base_state_machine *sm)
+{
+	struct sci_remote_node_context *rnc = container_of(sm, typeof(*rnc), sm);
+
+	sci_remote_node_context_continue_state_transitions(rnc);
+}
+
+static const struct sci_base_state sci_remote_node_context_state_table[] = {
+	[SCI_RNC_INITIAL] = {
+		.enter_state = sci_remote_node_context_initial_state_enter,
+	},
+	[SCI_RNC_POSTING] = {
+		.enter_state = sci_remote_node_context_posting_state_enter,
+	},
+	[SCI_RNC_INVALIDATING] = {
+		.enter_state = sci_remote_node_context_invalidating_state_enter,
+	},
+	[SCI_RNC_RESUMING] = {
+		.enter_state = sci_remote_node_context_resuming_state_enter,
+	},
+	[SCI_RNC_READY] = {
+		.enter_state = sci_remote_node_context_ready_state_enter,
+	},
+	[SCI_RNC_TX_SUSPENDED] = {
+		.enter_state = sci_remote_node_context_tx_suspended_state_enter,
+	},
+	[SCI_RNC_TX_RX_SUSPENDED] = {
+		.enter_state = sci_remote_node_context_tx_rx_suspended_state_enter,
+	},
+	[SCI_RNC_AWAIT_SUSPENSION] = { },
+};
+
+void sci_remote_node_context_construct(struct sci_remote_node_context *rnc,
+					    u16 remote_node_index)
+{
+	memset(rnc, 0, sizeof(struct sci_remote_node_context));
+
+	rnc->remote_node_index = remote_node_index;
+	rnc->destination_state = SCIC_SDS_REMOTE_NODE_DESTINATION_STATE_UNSPECIFIED;
+
+	sci_init_sm(&rnc->sm, sci_remote_node_context_state_table, SCI_RNC_INITIAL);
+}
+
+enum sci_status sci_remote_node_context_event_handler(struct sci_remote_node_context *sci_rnc,
+							   u32 event_code)
+{
+	enum scis_sds_remote_node_context_states state;
+
+	state = sci_rnc->sm.current_state_id;
+	switch (state) {
+	case SCI_RNC_POSTING:
+		switch (scu_get_event_code(event_code)) {
+		case SCU_EVENT_POST_RNC_COMPLETE:
+			sci_change_state(&sci_rnc->sm, SCI_RNC_READY);
+			break;
+		default:
+			goto out;
+		}
+		break;
+	case SCI_RNC_INVALIDATING:
+		if (scu_get_event_code(event_code) == SCU_EVENT_POST_RNC_INVALIDATE_COMPLETE) {
+			if (sci_rnc->destination_state == SCIC_SDS_REMOTE_NODE_DESTINATION_STATE_FINAL)
+				state = SCI_RNC_INITIAL;
+			else
+				state = SCI_RNC_POSTING;
+			sci_change_state(&sci_rnc->sm, state);
+		} else {
+			switch (scu_get_event_type(event_code)) {
+			case SCU_EVENT_TYPE_RNC_SUSPEND_TX:
+			case SCU_EVENT_TYPE_RNC_SUSPEND_TX_RX:
+				/* We really dont care if the hardware is going to suspend
+				 * the device since it's being invalidated anyway */
+				dev_dbg(scirdev_to_dev(rnc_to_dev(sci_rnc)),
+					"%s: SCIC Remote Node Context 0x%p was "
+					"suspeneded by hardware while being "
+					"invalidated.\n", __func__, sci_rnc);
+				break;
+			default:
+				goto out;
+			}
+		}
+		break;
+	case SCI_RNC_RESUMING:
+		if (scu_get_event_code(event_code) == SCU_EVENT_POST_RCN_RELEASE) {
+			sci_change_state(&sci_rnc->sm, SCI_RNC_READY);
+		} else {
+			switch (scu_get_event_type(event_code)) {
+			case SCU_EVENT_TYPE_RNC_SUSPEND_TX:
+			case SCU_EVENT_TYPE_RNC_SUSPEND_TX_RX:
+				/* We really dont care if the hardware is going to suspend
+				 * the device since it's being resumed anyway */
+				dev_dbg(scirdev_to_dev(rnc_to_dev(sci_rnc)),
+					"%s: SCIC Remote Node Context 0x%p was "
+					"suspeneded by hardware while being resumed.\n",
+					__func__, sci_rnc);
+				break;
+			default:
+				goto out;
+			}
+		}
+		break;
+	case SCI_RNC_READY:
+		switch (scu_get_event_type(event_code)) {
+		case SCU_EVENT_TL_RNC_SUSPEND_TX:
+			sci_change_state(&sci_rnc->sm, SCI_RNC_TX_SUSPENDED);
+			sci_rnc->suspension_code = scu_get_event_specifier(event_code);
+			break;
+		case SCU_EVENT_TL_RNC_SUSPEND_TX_RX:
+			sci_change_state(&sci_rnc->sm, SCI_RNC_TX_RX_SUSPENDED);
+			sci_rnc->suspension_code = scu_get_event_specifier(event_code);
+			break;
+		default:
+			goto out;
+		}
+		break;
+	case SCI_RNC_AWAIT_SUSPENSION:
+		switch (scu_get_event_type(event_code)) {
+		case SCU_EVENT_TL_RNC_SUSPEND_TX:
+			sci_change_state(&sci_rnc->sm, SCI_RNC_TX_SUSPENDED);
+			sci_rnc->suspension_code = scu_get_event_specifier(event_code);
+			break;
+		case SCU_EVENT_TL_RNC_SUSPEND_TX_RX:
+			sci_change_state(&sci_rnc->sm, SCI_RNC_TX_RX_SUSPENDED);
+			sci_rnc->suspension_code = scu_get_event_specifier(event_code);
+			break;
+		default:
+			goto out;
+		}
+		break;
+	default:
+		dev_warn(scirdev_to_dev(rnc_to_dev(sci_rnc)),
+			 "%s: invalid state %d\n", __func__, state);
+		return SCI_FAILURE_INVALID_STATE;
+	}
+	return SCI_SUCCESS;
+
+ out:
+	dev_warn(scirdev_to_dev(rnc_to_dev(sci_rnc)),
+		 "%s: code: %#x state: %d\n", __func__, event_code, state);
+	return SCI_FAILURE;
+
+}
+
+enum sci_status sci_remote_node_context_destruct(struct sci_remote_node_context *sci_rnc,
+						      scics_sds_remote_node_context_callback cb_fn,
+						      void *cb_p)
+{
+	enum scis_sds_remote_node_context_states state;
+
+	state = sci_rnc->sm.current_state_id;
+	switch (state) {
+	case SCI_RNC_INVALIDATING:
+		sci_remote_node_context_setup_to_destory(sci_rnc, cb_fn, cb_p);
+		return SCI_SUCCESS;
+	case SCI_RNC_POSTING:
+	case SCI_RNC_RESUMING:
+	case SCI_RNC_READY:
+	case SCI_RNC_TX_SUSPENDED:
+	case SCI_RNC_TX_RX_SUSPENDED:
+	case SCI_RNC_AWAIT_SUSPENSION:
+		sci_remote_node_context_setup_to_destory(sci_rnc, cb_fn, cb_p);
+		sci_change_state(&sci_rnc->sm, SCI_RNC_INVALIDATING);
+		return SCI_SUCCESS;
+	case SCI_RNC_INITIAL:
+		dev_warn(scirdev_to_dev(rnc_to_dev(sci_rnc)),
+			 "%s: invalid state %d\n", __func__, state);
+		/* We have decided that the destruct request on the remote node context
+		 * can not fail since it is either in the initial/destroyed state or is
+		 * can be destroyed.
+		 */
+		return SCI_SUCCESS;
+	default:
+		dev_warn(scirdev_to_dev(rnc_to_dev(sci_rnc)),
+			 "%s: invalid state %d\n", __func__, state);
+		return SCI_FAILURE_INVALID_STATE;
+	}
+}
+
+enum sci_status sci_remote_node_context_suspend(struct sci_remote_node_context *sci_rnc,
+						     u32 suspend_type,
+						     scics_sds_remote_node_context_callback cb_fn,
+						     void *cb_p)
+{
+	enum scis_sds_remote_node_context_states state;
+
+	state = sci_rnc->sm.current_state_id;
+	if (state != SCI_RNC_READY) {
+		dev_warn(scirdev_to_dev(rnc_to_dev(sci_rnc)),
+			 "%s: invalid state %d\n", __func__, state);
+		return SCI_FAILURE_INVALID_STATE;
+	}
+
+	sci_rnc->user_callback   = cb_fn;
+	sci_rnc->user_cookie     = cb_p;
+	sci_rnc->suspension_code = suspend_type;
+
+	if (suspend_type == SCI_SOFTWARE_SUSPENSION) {
+		sci_remote_device_post_request(rnc_to_dev(sci_rnc),
+						    SCU_CONTEXT_COMMAND_POST_RNC_SUSPEND_TX);
+	}
+
+	sci_change_state(&sci_rnc->sm, SCI_RNC_AWAIT_SUSPENSION);
+	return SCI_SUCCESS;
+}
+
+enum sci_status sci_remote_node_context_resume(struct sci_remote_node_context *sci_rnc,
+						    scics_sds_remote_node_context_callback cb_fn,
+						    void *cb_p)
+{
+	enum scis_sds_remote_node_context_states state;
+
+	state = sci_rnc->sm.current_state_id;
+	switch (state) {
+	case SCI_RNC_INITIAL:
+		if (sci_rnc->remote_node_index == SCIC_SDS_REMOTE_NODE_CONTEXT_INVALID_INDEX)
+			return SCI_FAILURE_INVALID_STATE;
+
+		sci_remote_node_context_setup_to_resume(sci_rnc, cb_fn, cb_p);
+		sci_remote_node_context_construct_buffer(sci_rnc);
+		sci_change_state(&sci_rnc->sm, SCI_RNC_POSTING);
+		return SCI_SUCCESS;
+	case SCI_RNC_POSTING:
+	case SCI_RNC_INVALIDATING:
+	case SCI_RNC_RESUMING:
+		if (sci_rnc->destination_state != SCIC_SDS_REMOTE_NODE_DESTINATION_STATE_READY)
+			return SCI_FAILURE_INVALID_STATE;
+
+		sci_rnc->user_callback = cb_fn;
+		sci_rnc->user_cookie   = cb_p;
+		return SCI_SUCCESS;
+	case SCI_RNC_TX_SUSPENDED: {
+		struct isci_remote_device *idev = rnc_to_dev(sci_rnc);
+		struct domain_device *dev = idev->domain_dev;
+
+		sci_remote_node_context_setup_to_resume(sci_rnc, cb_fn, cb_p);
+
+		/* TODO: consider adding a resume action of NONE, INVALIDATE, WRITE_TLCR */
+		if (dev->dev_type == SAS_END_DEV || dev_is_expander(dev))
+			sci_change_state(&sci_rnc->sm, SCI_RNC_RESUMING);
+		else if (dev->dev_type == SATA_DEV || (dev->tproto & SAS_PROTOCOL_STP)) {
+			if (idev->is_direct_attached) {
+				/* @todo Fix this since I am being silly in writing to the STPTLDARNI register. */
+				sci_change_state(&sci_rnc->sm, SCI_RNC_RESUMING);
+			} else {
+				sci_change_state(&sci_rnc->sm, SCI_RNC_INVALIDATING);
+			}
+		} else
+			return SCI_FAILURE;
+		return SCI_SUCCESS;
+	}
+	case SCI_RNC_TX_RX_SUSPENDED:
+		sci_remote_node_context_setup_to_resume(sci_rnc, cb_fn, cb_p);
+		sci_change_state(&sci_rnc->sm, SCI_RNC_RESUMING);
+		return SCI_FAILURE_INVALID_STATE;
+	case SCI_RNC_AWAIT_SUSPENSION:
+		sci_remote_node_context_setup_to_resume(sci_rnc, cb_fn, cb_p);
+		return SCI_SUCCESS;
+	default:
+		dev_warn(scirdev_to_dev(rnc_to_dev(sci_rnc)),
+			 "%s: invalid state %d\n", __func__, state);
+		return SCI_FAILURE_INVALID_STATE;
+	}
+}
+
+enum sci_status sci_remote_node_context_start_io(struct sci_remote_node_context *sci_rnc,
+							     struct isci_request *ireq)
+{
+	enum scis_sds_remote_node_context_states state;
+
+	state = sci_rnc->sm.current_state_id;
+
+	switch (state) {
+	case SCI_RNC_READY:
+		return SCI_SUCCESS;
+	case SCI_RNC_TX_SUSPENDED:
+	case SCI_RNC_TX_RX_SUSPENDED:
+	case SCI_RNC_AWAIT_SUSPENSION:
+		dev_warn(scirdev_to_dev(rnc_to_dev(sci_rnc)),
+			 "%s: invalid state %d\n", __func__, state);
+		return SCI_FAILURE_REMOTE_DEVICE_RESET_REQUIRED;
+	default:
+		break;
+	}
+	dev_dbg(scirdev_to_dev(rnc_to_dev(sci_rnc)),
+		"%s: requested to start IO while still resuming, %d\n",
+		__func__, state);
+	return SCI_FAILURE_INVALID_STATE;
+}
+
+enum sci_status sci_remote_node_context_start_task(struct sci_remote_node_context *sci_rnc,
+							struct isci_request *ireq)
+{
+	enum scis_sds_remote_node_context_states state;
+
+	state = sci_rnc->sm.current_state_id;
+	switch (state) {
+	case SCI_RNC_RESUMING:
+	case SCI_RNC_READY:
+	case SCI_RNC_AWAIT_SUSPENSION:
+		return SCI_SUCCESS;
+	case SCI_RNC_TX_SUSPENDED:
+	case SCI_RNC_TX_RX_SUSPENDED:
+		sci_remote_node_context_resume(sci_rnc, NULL, NULL);
+		return SCI_SUCCESS;
+	default:
+		dev_warn(scirdev_to_dev(rnc_to_dev(sci_rnc)),
+			 "%s: invalid state %d\n", __func__, state);
+		return SCI_FAILURE_INVALID_STATE;
+	}
+}
diff -druN linux-2.6.39-libre/drivers/scsi/isci/remote_node_context.h linux-3.0-rc7-libre/drivers/scsi/isci/remote_node_context.h
--- linux-2.6.39-libre/drivers/scsi/isci/remote_node_context.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/scsi/isci/remote_node_context.h	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,224 @@
+/*
+ * This file is provided under a dual BSD/GPLv2 license.  When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * The full GNU General Public License is included in this distribution
+ * in the file called LICENSE.GPL.
+ *
+ * BSD LICENSE
+ *
+ * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in
+ *     the documentation and/or other materials provided with the
+ *     distribution.
+ *   * Neither the name of Intel Corporation nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _SCIC_SDS_REMOTE_NODE_CONTEXT_H_
+#define _SCIC_SDS_REMOTE_NODE_CONTEXT_H_
+
+/**
+ * This file contains the structures, constants, and prototypes associated with
+ *    the remote node context in the silicon.  It exists to model and manage
+ *    the remote node context in the silicon.
+ *
+ *
+ */
+
+#include "isci.h"
+
+/**
+ *
+ *
+ * This constant represents an invalid remote device id, it is used to program
+ * the STPDARNI register so the driver knows when it has received a SIGNATURE
+ * FIS from the SCU.
+ */
+#define SCIC_SDS_REMOTE_NODE_CONTEXT_INVALID_INDEX    0x0FFF
+
+#define SCU_HARDWARE_SUSPENSION  (0)
+#define SCI_SOFTWARE_SUSPENSION  (1)
+
+struct isci_request;
+struct isci_remote_device;
+struct sci_remote_node_context;
+
+typedef void (*scics_sds_remote_node_context_callback)(void *);
+
+/**
+ * This is the enumeration of the remote node context states.
+ */
+enum scis_sds_remote_node_context_states {
+	/**
+	 * This state is the initial state for a remote node context.  On a resume
+	 * request the remote node context will transition to the posting state.
+	 */
+	SCI_RNC_INITIAL,
+
+	/**
+	 * This is a transition state that posts the RNi to the hardware. Once the RNC
+	 * is posted the remote node context will be made ready.
+	 */
+	SCI_RNC_POSTING,
+
+	/**
+	 * This is a transition state that will post an RNC invalidate to the
+	 * hardware.  Once the invalidate is complete the remote node context will
+	 * transition to the posting state.
+	 */
+	SCI_RNC_INVALIDATING,
+
+	/**
+	 * This is a transition state that will post an RNC resume to the hardare.
+	 * Once the event notification of resume complete is received the remote node
+	 * context will transition to the ready state.
+	 */
+	SCI_RNC_RESUMING,
+
+	/**
+	 * This is the state that the remote node context must be in to accept io
+	 * request operations.
+	 */
+	SCI_RNC_READY,
+
+	/**
+	 * This is the state that the remote node context transitions to when it gets
+	 * a TX suspend notification from the hardware.
+	 */
+	SCI_RNC_TX_SUSPENDED,
+
+	/**
+	 * This is the state that the remote node context transitions to when it gets
+	 * a TX RX suspend notification from the hardware.
+	 */
+	SCI_RNC_TX_RX_SUSPENDED,
+
+	/**
+	 * This state is a wait state for the remote node context that waits for a
+	 * suspend notification from the hardware.  This state is entered when either
+	 * there is a request to supend the remote node context or when there is a TC
+	 * completion where the remote node will be suspended by the hardware.
+	 */
+	SCI_RNC_AWAIT_SUSPENSION
+};
+
+/**
+ *
+ *
+ * This enumeration is used to define the end destination state for the remote
+ * node context.
+ */
+enum sci_remote_node_context_destination_state {
+	SCIC_SDS_REMOTE_NODE_DESTINATION_STATE_UNSPECIFIED,
+	SCIC_SDS_REMOTE_NODE_DESTINATION_STATE_READY,
+	SCIC_SDS_REMOTE_NODE_DESTINATION_STATE_FINAL
+};
+
+/**
+ * struct sci_remote_node_context - This structure contains the data
+ *    associated with the remote node context object.  The remote node context
+ *    (RNC) object models the the remote device information necessary to manage
+ *    the silicon RNC.
+ */
+struct sci_remote_node_context {
+	/**
+	 * This field indicates the remote node index (RNI) associated with
+	 * this RNC.
+	 */
+	u16 remote_node_index;
+
+	/**
+	 * This field is the recored suspension code or the reason for the remote node
+	 * context suspension.
+	 */
+	u32 suspension_code;
+
+	/**
+	 * This field is true if the remote node context is resuming from its current
+	 * state.  This can cause an automatic resume on receiving a suspension
+	 * notification.
+	 */
+	enum sci_remote_node_context_destination_state destination_state;
+
+	/**
+	 * This field contains the callback function that the user requested to be
+	 * called when the requested state transition is complete.
+	 */
+	scics_sds_remote_node_context_callback user_callback;
+
+	/**
+	 * This field contains the parameter that is called when the user requested
+	 * state transition is completed.
+	 */
+	void *user_cookie;
+
+	/**
+	 * This field contains the data for the object's state machine.
+	 */
+	struct sci_base_state_machine sm;
+};
+
+void sci_remote_node_context_construct(struct sci_remote_node_context *rnc,
+					    u16 remote_node_index);
+
+
+bool sci_remote_node_context_is_ready(
+	struct sci_remote_node_context *sci_rnc);
+
+enum sci_status sci_remote_node_context_event_handler(struct sci_remote_node_context *sci_rnc,
+							   u32 event_code);
+enum sci_status sci_remote_node_context_destruct(struct sci_remote_node_context *sci_rnc,
+						      scics_sds_remote_node_context_callback callback,
+						      void *callback_parameter);
+enum sci_status sci_remote_node_context_suspend(struct sci_remote_node_context *sci_rnc,
+						     u32 suspend_type,
+						     scics_sds_remote_node_context_callback cb_fn,
+						     void *cb_p);
+enum sci_status sci_remote_node_context_resume(struct sci_remote_node_context *sci_rnc,
+						    scics_sds_remote_node_context_callback cb_fn,
+						    void *cb_p);
+enum sci_status sci_remote_node_context_start_task(struct sci_remote_node_context *sci_rnc,
+							struct isci_request *ireq);
+enum sci_status sci_remote_node_context_start_io(struct sci_remote_node_context *sci_rnc,
+						      struct isci_request *ireq);
+
+#endif  /* _SCIC_SDS_REMOTE_NODE_CONTEXT_H_ */
diff -druN linux-2.6.39-libre/drivers/scsi/isci/remote_node_table.c linux-3.0-rc7-libre/drivers/scsi/isci/remote_node_table.c
--- linux-2.6.39-libre/drivers/scsi/isci/remote_node_table.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/scsi/isci/remote_node_table.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,598 @@
+/*
+ * This file is provided under a dual BSD/GPLv2 license.  When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * The full GNU General Public License is included in this distribution
+ * in the file called LICENSE.GPL.
+ *
+ * BSD LICENSE
+ *
+ * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in
+ *     the documentation and/or other materials provided with the
+ *     distribution.
+ *   * Neither the name of Intel Corporation nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * This file contains the implementation of the SCIC_SDS_REMOTE_NODE_TABLE
+ *    public, protected, and private methods.
+ *
+ *
+ */
+#include "remote_node_table.h"
+#include "remote_node_context.h"
+
+/**
+ *
+ * @remote_node_table: This is the remote node index table from which the
+ *    selection will be made.
+ * @group_table_index: This is the index to the group table from which to
+ *    search for an available selection.
+ *
+ * This routine will find the bit position in absolute bit terms of the next 32
+ * + bit position.  If there are available bits in the first u32 then it is
+ * just bit position. u32 This is the absolute bit position for an available
+ * group.
+ */
+static u32 sci_remote_node_table_get_group_index(
+	struct sci_remote_node_table *remote_node_table,
+	u32 group_table_index)
+{
+	u32 dword_index;
+	u32 *group_table;
+	u32 bit_index;
+
+	group_table = remote_node_table->remote_node_groups[group_table_index];
+
+	for (dword_index = 0; dword_index < remote_node_table->group_array_size; dword_index++) {
+		if (group_table[dword_index] != 0) {
+			for (bit_index = 0; bit_index < 32; bit_index++) {
+				if ((group_table[dword_index] & (1 << bit_index)) != 0) {
+					return (dword_index * 32) + bit_index;
+				}
+			}
+		}
+	}
+
+	return SCIC_SDS_REMOTE_NODE_TABLE_INVALID_INDEX;
+}
+
+/**
+ *
+ * @out]: remote_node_table This the remote node table in which to clear the
+ *    selector.
+ * @set_index: This is the remote node selector in which the change will be
+ *    made.
+ * @group_index: This is the bit index in the table to be modified.
+ *
+ * This method will clear the group index entry in the specified group index
+ * table. none
+ */
+static void sci_remote_node_table_clear_group_index(
+	struct sci_remote_node_table *remote_node_table,
+	u32 group_table_index,
+	u32 group_index)
+{
+	u32 dword_index;
+	u32 bit_index;
+	u32 *group_table;
+
+	BUG_ON(group_table_index >= SCU_STP_REMOTE_NODE_COUNT);
+	BUG_ON(group_index >= (u32)(remote_node_table->group_array_size * 32));
+
+	dword_index = group_index / 32;
+	bit_index   = group_index % 32;
+	group_table = remote_node_table->remote_node_groups[group_table_index];
+
+	group_table[dword_index] = group_table[dword_index] & ~(1 << bit_index);
+}
+
+/**
+ *
+ * @out]: remote_node_table This the remote node table in which to set the
+ *    selector.
+ * @group_table_index: This is the remote node selector in which the change
+ *    will be made.
+ * @group_index: This is the bit position in the table to be modified.
+ *
+ * This method will set the group index bit entry in the specified gropu index
+ * table. none
+ */
+static void sci_remote_node_table_set_group_index(
+	struct sci_remote_node_table *remote_node_table,
+	u32 group_table_index,
+	u32 group_index)
+{
+	u32 dword_index;
+	u32 bit_index;
+	u32 *group_table;
+
+	BUG_ON(group_table_index >= SCU_STP_REMOTE_NODE_COUNT);
+	BUG_ON(group_index >= (u32)(remote_node_table->group_array_size * 32));
+
+	dword_index = group_index / 32;
+	bit_index   = group_index % 32;
+	group_table = remote_node_table->remote_node_groups[group_table_index];
+
+	group_table[dword_index] = group_table[dword_index] | (1 << bit_index);
+}
+
+/**
+ *
+ * @out]: remote_node_table This is the remote node table in which to modify
+ *    the remote node availability.
+ * @remote_node_index: This is the remote node index that is being returned to
+ *    the table.
+ *
+ * This method will set the remote to available in the remote node allocation
+ * table. none
+ */
+static void sci_remote_node_table_set_node_index(
+	struct sci_remote_node_table *remote_node_table,
+	u32 remote_node_index)
+{
+	u32 dword_location;
+	u32 dword_remainder;
+	u32 slot_normalized;
+	u32 slot_position;
+
+	BUG_ON(
+		(remote_node_table->available_nodes_array_size * SCIC_SDS_REMOTE_NODE_SETS_PER_DWORD)
+		<= (remote_node_index / SCU_STP_REMOTE_NODE_COUNT)
+		);
+
+	dword_location  = remote_node_index / SCIC_SDS_REMOTE_NODES_PER_DWORD;
+	dword_remainder = remote_node_index % SCIC_SDS_REMOTE_NODES_PER_DWORD;
+	slot_normalized = (dword_remainder / SCU_STP_REMOTE_NODE_COUNT) * sizeof(u32);
+	slot_position   = remote_node_index % SCU_STP_REMOTE_NODE_COUNT;
+
+	remote_node_table->available_remote_nodes[dword_location] |=
+		1 << (slot_normalized + slot_position);
+}
+
+/**
+ *
+ * @out]: remote_node_table This is the remote node table from which to clear
+ *    the available remote node bit.
+ * @remote_node_index: This is the remote node index which is to be cleared
+ *    from the table.
+ *
+ * This method clears the remote node index from the table of available remote
+ * nodes. none
+ */
+static void sci_remote_node_table_clear_node_index(
+	struct sci_remote_node_table *remote_node_table,
+	u32 remote_node_index)
+{
+	u32 dword_location;
+	u32 dword_remainder;
+	u32 slot_position;
+	u32 slot_normalized;
+
+	BUG_ON(
+		(remote_node_table->available_nodes_array_size * SCIC_SDS_REMOTE_NODE_SETS_PER_DWORD)
+		<= (remote_node_index / SCU_STP_REMOTE_NODE_COUNT)
+		);
+
+	dword_location  = remote_node_index / SCIC_SDS_REMOTE_NODES_PER_DWORD;
+	dword_remainder = remote_node_index % SCIC_SDS_REMOTE_NODES_PER_DWORD;
+	slot_normalized = (dword_remainder / SCU_STP_REMOTE_NODE_COUNT) * sizeof(u32);
+	slot_position   = remote_node_index % SCU_STP_REMOTE_NODE_COUNT;
+
+	remote_node_table->available_remote_nodes[dword_location] &=
+		~(1 << (slot_normalized + slot_position));
+}
+
+/**
+ *
+ * @out]: remote_node_table The remote node table from which the slot will be
+ *    cleared.
+ * @group_index: The index for the slot that is to be cleared.
+ *
+ * This method clears the entire table slot at the specified slot index. none
+ */
+static void sci_remote_node_table_clear_group(
+	struct sci_remote_node_table *remote_node_table,
+	u32 group_index)
+{
+	u32 dword_location;
+	u32 dword_remainder;
+	u32 dword_value;
+
+	BUG_ON(
+		(remote_node_table->available_nodes_array_size * SCIC_SDS_REMOTE_NODE_SETS_PER_DWORD)
+		<= (group_index / SCU_STP_REMOTE_NODE_COUNT)
+		);
+
+	dword_location  = group_index / SCIC_SDS_REMOTE_NODE_SETS_PER_DWORD;
+	dword_remainder = group_index % SCIC_SDS_REMOTE_NODE_SETS_PER_DWORD;
+
+	dword_value = remote_node_table->available_remote_nodes[dword_location];
+	dword_value &= ~(SCIC_SDS_REMOTE_NODE_TABLE_FULL_SLOT_VALUE << (dword_remainder * 4));
+	remote_node_table->available_remote_nodes[dword_location] = dword_value;
+}
+
+/**
+ *
+ * @remote_node_table:
+ *
+ * THis method sets an entire remote node group in the remote node table.
+ */
+static void sci_remote_node_table_set_group(
+	struct sci_remote_node_table *remote_node_table,
+	u32 group_index)
+{
+	u32 dword_location;
+	u32 dword_remainder;
+	u32 dword_value;
+
+	BUG_ON(
+		(remote_node_table->available_nodes_array_size * SCIC_SDS_REMOTE_NODE_SETS_PER_DWORD)
+		<= (group_index / SCU_STP_REMOTE_NODE_COUNT)
+		);
+
+	dword_location  = group_index / SCIC_SDS_REMOTE_NODE_SETS_PER_DWORD;
+	dword_remainder = group_index % SCIC_SDS_REMOTE_NODE_SETS_PER_DWORD;
+
+	dword_value = remote_node_table->available_remote_nodes[dword_location];
+	dword_value |= (SCIC_SDS_REMOTE_NODE_TABLE_FULL_SLOT_VALUE << (dword_remainder * 4));
+	remote_node_table->available_remote_nodes[dword_location] = dword_value;
+}
+
+/**
+ *
+ * @remote_node_table: This is the remote node table that for which the group
+ *    value is to be returned.
+ * @group_index: This is the group index to use to find the group value.
+ *
+ * This method will return the group value for the specified group index. The
+ * bit values at the specified remote node group index.
+ */
+static u8 sci_remote_node_table_get_group_value(
+	struct sci_remote_node_table *remote_node_table,
+	u32 group_index)
+{
+	u32 dword_location;
+	u32 dword_remainder;
+	u32 dword_value;
+
+	dword_location  = group_index / SCIC_SDS_REMOTE_NODE_SETS_PER_DWORD;
+	dword_remainder = group_index % SCIC_SDS_REMOTE_NODE_SETS_PER_DWORD;
+
+	dword_value = remote_node_table->available_remote_nodes[dword_location];
+	dword_value &= (SCIC_SDS_REMOTE_NODE_TABLE_FULL_SLOT_VALUE << (dword_remainder * 4));
+	dword_value = dword_value >> (dword_remainder * 4);
+
+	return (u8)dword_value;
+}
+
+/**
+ *
+ * @out]: remote_node_table The remote that which is to be initialized.
+ * @remote_node_entries: The number of entries to put in the table.
+ *
+ * This method will initialize the remote node table for use. none
+ */
+void sci_remote_node_table_initialize(
+	struct sci_remote_node_table *remote_node_table,
+	u32 remote_node_entries)
+{
+	u32 index;
+
+	/*
+	 * Initialize the raw data we could improve the speed by only initializing
+	 * those entries that we are actually going to be used */
+	memset(
+		remote_node_table->available_remote_nodes,
+		0x00,
+		sizeof(remote_node_table->available_remote_nodes)
+		);
+
+	memset(
+		remote_node_table->remote_node_groups,
+		0x00,
+		sizeof(remote_node_table->remote_node_groups)
+		);
+
+	/* Initialize the available remote node sets */
+	remote_node_table->available_nodes_array_size = (u16)
+							(remote_node_entries / SCIC_SDS_REMOTE_NODES_PER_DWORD)
+							+ ((remote_node_entries % SCIC_SDS_REMOTE_NODES_PER_DWORD) != 0);
+
+
+	/* Initialize each full DWORD to a FULL SET of remote nodes */
+	for (index = 0; index < remote_node_entries; index++) {
+		sci_remote_node_table_set_node_index(remote_node_table, index);
+	}
+
+	remote_node_table->group_array_size = (u16)
+					      (remote_node_entries / (SCU_STP_REMOTE_NODE_COUNT * 32))
+					      + ((remote_node_entries % (SCU_STP_REMOTE_NODE_COUNT * 32)) != 0);
+
+	for (index = 0; index < (remote_node_entries / SCU_STP_REMOTE_NODE_COUNT); index++) {
+		/*
+		 * These are all guaranteed to be full slot values so fill them in the
+		 * available sets of 3 remote nodes */
+		sci_remote_node_table_set_group_index(remote_node_table, 2, index);
+	}
+
+	/* Now fill in any remainders that we may find */
+	if ((remote_node_entries % SCU_STP_REMOTE_NODE_COUNT) == 2) {
+		sci_remote_node_table_set_group_index(remote_node_table, 1, index);
+	} else if ((remote_node_entries % SCU_STP_REMOTE_NODE_COUNT) == 1) {
+		sci_remote_node_table_set_group_index(remote_node_table, 0, index);
+	}
+}
+
+/**
+ *
+ * @out]: remote_node_table The remote node table from which to allocate a
+ *    remote node.
+ * @table_index: The group index that is to be used for the search.
+ *
+ * This method will allocate a single RNi from the remote node table.  The
+ * table index will determine from which remote node group table to search.
+ * This search may fail and another group node table can be specified.  The
+ * function is designed to allow a serach of the available single remote node
+ * group up to the triple remote node group.  If an entry is found in the
+ * specified table the remote node is removed and the remote node groups are
+ * updated. The RNi value or an invalid remote node context if an RNi can not
+ * be found.
+ */
+static u16 sci_remote_node_table_allocate_single_remote_node(
+	struct sci_remote_node_table *remote_node_table,
+	u32 group_table_index)
+{
+	u8 index;
+	u8 group_value;
+	u32 group_index;
+	u16 remote_node_index = SCIC_SDS_REMOTE_NODE_CONTEXT_INVALID_INDEX;
+
+	group_index = sci_remote_node_table_get_group_index(
+		remote_node_table, group_table_index);
+
+	/* We could not find an available slot in the table selector 0 */
+	if (group_index != SCIC_SDS_REMOTE_NODE_TABLE_INVALID_INDEX) {
+		group_value = sci_remote_node_table_get_group_value(
+			remote_node_table, group_index);
+
+		for (index = 0; index < SCU_STP_REMOTE_NODE_COUNT; index++) {
+			if (((1 << index) & group_value) != 0) {
+				/* We have selected a bit now clear it */
+				remote_node_index = (u16)(group_index * SCU_STP_REMOTE_NODE_COUNT
+							  + index);
+
+				sci_remote_node_table_clear_group_index(
+					remote_node_table, group_table_index, group_index
+					);
+
+				sci_remote_node_table_clear_node_index(
+					remote_node_table, remote_node_index
+					);
+
+				if (group_table_index > 0) {
+					sci_remote_node_table_set_group_index(
+						remote_node_table, group_table_index - 1, group_index
+						);
+				}
+
+				break;
+			}
+		}
+	}
+
+	return remote_node_index;
+}
+
+/**
+ *
+ * @remote_node_table: This is the remote node table from which to allocate the
+ *    remote node entries.
+ * @group_table_index: THis is the group table index which must equal two (2)
+ *    for this operation.
+ *
+ * This method will allocate three consecutive remote node context entries. If
+ * there are no remaining triple entries the function will return a failure.
+ * The remote node index that represents three consecutive remote node entries
+ * or an invalid remote node context if none can be found.
+ */
+static u16 sci_remote_node_table_allocate_triple_remote_node(
+	struct sci_remote_node_table *remote_node_table,
+	u32 group_table_index)
+{
+	u32 group_index;
+	u16 remote_node_index = SCIC_SDS_REMOTE_NODE_CONTEXT_INVALID_INDEX;
+
+	group_index = sci_remote_node_table_get_group_index(
+		remote_node_table, group_table_index);
+
+	if (group_index != SCIC_SDS_REMOTE_NODE_TABLE_INVALID_INDEX) {
+		remote_node_index = (u16)group_index * SCU_STP_REMOTE_NODE_COUNT;
+
+		sci_remote_node_table_clear_group_index(
+			remote_node_table, group_table_index, group_index
+			);
+
+		sci_remote_node_table_clear_group(
+			remote_node_table, group_index
+			);
+	}
+
+	return remote_node_index;
+}
+
+/**
+ *
+ * @remote_node_table: This is the remote node table from which the remote node
+ *    allocation is to take place.
+ * @remote_node_count: This is ther remote node count which is one of
+ *    SCU_SSP_REMOTE_NODE_COUNT(1) or SCU_STP_REMOTE_NODE_COUNT(3).
+ *
+ * This method will allocate a remote node that mataches the remote node count
+ * specified by the caller.  Valid values for remote node count is
+ * SCU_SSP_REMOTE_NODE_COUNT(1) or SCU_STP_REMOTE_NODE_COUNT(3). u16 This is
+ * the remote node index that is returned or an invalid remote node context.
+ */
+u16 sci_remote_node_table_allocate_remote_node(
+	struct sci_remote_node_table *remote_node_table,
+	u32 remote_node_count)
+{
+	u16 remote_node_index = SCIC_SDS_REMOTE_NODE_CONTEXT_INVALID_INDEX;
+
+	if (remote_node_count == SCU_SSP_REMOTE_NODE_COUNT) {
+		remote_node_index =
+			sci_remote_node_table_allocate_single_remote_node(
+				remote_node_table, 0);
+
+		if (remote_node_index == SCIC_SDS_REMOTE_NODE_CONTEXT_INVALID_INDEX) {
+			remote_node_index =
+				sci_remote_node_table_allocate_single_remote_node(
+					remote_node_table, 1);
+		}
+
+		if (remote_node_index == SCIC_SDS_REMOTE_NODE_CONTEXT_INVALID_INDEX) {
+			remote_node_index =
+				sci_remote_node_table_allocate_single_remote_node(
+					remote_node_table, 2);
+		}
+	} else if (remote_node_count == SCU_STP_REMOTE_NODE_COUNT) {
+		remote_node_index =
+			sci_remote_node_table_allocate_triple_remote_node(
+				remote_node_table, 2);
+	}
+
+	return remote_node_index;
+}
+
+/**
+ *
+ * @remote_node_table:
+ *
+ * This method will free a single remote node index back to the remote node
+ * table.  This routine will update the remote node groups
+ */
+static void sci_remote_node_table_release_single_remote_node(
+	struct sci_remote_node_table *remote_node_table,
+	u16 remote_node_index)
+{
+	u32 group_index;
+	u8 group_value;
+
+	group_index = remote_node_index / SCU_STP_REMOTE_NODE_COUNT;
+
+	group_value = sci_remote_node_table_get_group_value(remote_node_table, group_index);
+
+	/*
+	 * Assert that we are not trying to add an entry to a slot that is already
+	 * full. */
+	BUG_ON(group_value == SCIC_SDS_REMOTE_NODE_TABLE_FULL_SLOT_VALUE);
+
+	if (group_value == 0x00) {
+		/*
+		 * There are no entries in this slot so it must be added to the single
+		 * slot table. */
+		sci_remote_node_table_set_group_index(remote_node_table, 0, group_index);
+	} else if ((group_value & (group_value - 1)) == 0) {
+		/*
+		 * There is only one entry in this slot so it must be moved from the
+		 * single slot table to the dual slot table */
+		sci_remote_node_table_clear_group_index(remote_node_table, 0, group_index);
+		sci_remote_node_table_set_group_index(remote_node_table, 1, group_index);
+	} else {
+		/*
+		 * There are two entries in the slot so it must be moved from the dual
+		 * slot table to the tripple slot table. */
+		sci_remote_node_table_clear_group_index(remote_node_table, 1, group_index);
+		sci_remote_node_table_set_group_index(remote_node_table, 2, group_index);
+	}
+
+	sci_remote_node_table_set_node_index(remote_node_table, remote_node_index);
+}
+
+/**
+ *
+ * @remote_node_table: This is the remote node table to which the remote node
+ *    index is to be freed.
+ *
+ * This method will release a group of three consecutive remote nodes back to
+ * the free remote nodes.
+ */
+static void sci_remote_node_table_release_triple_remote_node(
+	struct sci_remote_node_table *remote_node_table,
+	u16 remote_node_index)
+{
+	u32 group_index;
+
+	group_index = remote_node_index / SCU_STP_REMOTE_NODE_COUNT;
+
+	sci_remote_node_table_set_group_index(
+		remote_node_table, 2, group_index
+		);
+
+	sci_remote_node_table_set_group(remote_node_table, group_index);
+}
+
+/**
+ *
+ * @remote_node_table: The remote node table to which the remote node index is
+ *    to be freed.
+ * @remote_node_count: This is the count of consecutive remote nodes that are
+ *    to be freed.
+ *
+ * This method will release the remote node index back into the remote node
+ * table free pool.
+ */
+void sci_remote_node_table_release_remote_node_index(
+	struct sci_remote_node_table *remote_node_table,
+	u32 remote_node_count,
+	u16 remote_node_index)
+{
+	if (remote_node_count == SCU_SSP_REMOTE_NODE_COUNT) {
+		sci_remote_node_table_release_single_remote_node(
+			remote_node_table, remote_node_index);
+	} else if (remote_node_count == SCU_STP_REMOTE_NODE_COUNT) {
+		sci_remote_node_table_release_triple_remote_node(
+			remote_node_table, remote_node_index);
+	}
+}
+
diff -druN linux-2.6.39-libre/drivers/scsi/isci/remote_node_table.h linux-3.0-rc7-libre/drivers/scsi/isci/remote_node_table.h
--- linux-2.6.39-libre/drivers/scsi/isci/remote_node_table.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/scsi/isci/remote_node_table.h	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,188 @@
+/*
+ * This file is provided under a dual BSD/GPLv2 license.  When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * The full GNU General Public License is included in this distribution
+ * in the file called LICENSE.GPL.
+ *
+ * BSD LICENSE
+ *
+ * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in
+ *     the documentation and/or other materials provided with the
+ *     distribution.
+ *   * Neither the name of Intel Corporation nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _SCIC_SDS_REMOTE_NODE_TABLE_H_
+#define _SCIC_SDS_REMOTE_NODE_TABLE_H_
+
+#include "isci.h"
+
+/**
+ *
+ *
+ * Remote node sets are sets of remote node index in the remtoe node table The
+ * SCU hardware requires that STP remote node entries take three consecutive
+ * remote node index so the table is arranged in sets of three. The bits are
+ * used as 0111 0111 to make a byte and the bits define the set of three remote
+ * nodes to use as a sequence.
+ */
+#define SCIC_SDS_REMOTE_NODE_SETS_PER_BYTE 2
+
+/**
+ *
+ *
+ * Since the remote node table is organized as DWORDS take the remote node sets
+ * in bytes and represent them in DWORDs. The lowest ordered bits are the ones
+ * used in case full DWORD is not being used. i.e. 0000 0000 0000 0000 0111
+ * 0111 0111 0111 // if only a single WORD is in use in the DWORD.
+ */
+#define SCIC_SDS_REMOTE_NODE_SETS_PER_DWORD \
+	(sizeof(u32) * SCIC_SDS_REMOTE_NODE_SETS_PER_BYTE)
+/**
+ *
+ *
+ * This is a count of the numeber of remote nodes that can be represented in a
+ * byte
+ */
+#define SCIC_SDS_REMOTE_NODES_PER_BYTE	\
+	(SCU_STP_REMOTE_NODE_COUNT * SCIC_SDS_REMOTE_NODE_SETS_PER_BYTE)
+
+/**
+ *
+ *
+ * This is a count of the number of remote nodes that can be represented in a
+ * DWROD
+ */
+#define SCIC_SDS_REMOTE_NODES_PER_DWORD	\
+	(sizeof(u32) * SCIC_SDS_REMOTE_NODES_PER_BYTE)
+
+/**
+ *
+ *
+ * This is the number of bits in a remote node group
+ */
+#define SCIC_SDS_REMOTE_NODES_BITS_PER_GROUP   4
+
+#define SCIC_SDS_REMOTE_NODE_TABLE_INVALID_INDEX      (0xFFFFFFFF)
+#define SCIC_SDS_REMOTE_NODE_TABLE_FULL_SLOT_VALUE    (0x07)
+#define SCIC_SDS_REMOTE_NODE_TABLE_EMPTY_SLOT_VALUE   (0x00)
+
+/**
+ *
+ *
+ * Expander attached sata remote node count
+ */
+#define SCU_STP_REMOTE_NODE_COUNT        3
+
+/**
+ *
+ *
+ * Expander or direct attached ssp remote node count
+ */
+#define SCU_SSP_REMOTE_NODE_COUNT        1
+
+/**
+ *
+ *
+ * Direct attached STP remote node count
+ */
+#define SCU_SATA_REMOTE_NODE_COUNT       1
+
+/**
+ * struct sci_remote_node_table -
+ *
+ *
+ */
+struct sci_remote_node_table {
+	/**
+	 * This field contains the array size in dwords
+	 */
+	u16 available_nodes_array_size;
+
+	/**
+	 * This field contains the array size of the
+	 */
+	u16 group_array_size;
+
+	/**
+	 * This field is the array of available remote node entries in bits.
+	 * Because of the way STP remote node data is allocated on the SCU hardware
+	 * the remote nodes must occupy three consecutive remote node context
+	 * entries.  For ease of allocation and de-allocation we have broken the
+	 * sets of three into a single nibble.  When the STP RNi is allocated all
+	 * of the bits in the nibble are cleared.  This math results in a table size
+	 * of MAX_REMOTE_NODES / CONSECUTIVE RNi ENTRIES for STP / 2 entries per byte.
+	 */
+	u32 available_remote_nodes[
+		(SCI_MAX_REMOTE_DEVICES / SCIC_SDS_REMOTE_NODES_PER_DWORD)
+		+ ((SCI_MAX_REMOTE_DEVICES % SCIC_SDS_REMOTE_NODES_PER_DWORD) != 0)];
+
+	/**
+	 * This field is the nibble selector for the above table.  There are three
+	 * possible selectors each for fast lookup when trying to find one, two or
+	 * three remote node entries.
+	 */
+	u32 remote_node_groups[
+		SCU_STP_REMOTE_NODE_COUNT][
+		(SCI_MAX_REMOTE_DEVICES / (32 * SCU_STP_REMOTE_NODE_COUNT))
+		+ ((SCI_MAX_REMOTE_DEVICES % (32 * SCU_STP_REMOTE_NODE_COUNT)) != 0)];
+
+};
+
+/* --------------------------------------------------------------------------- */
+
+void sci_remote_node_table_initialize(
+	struct sci_remote_node_table *remote_node_table,
+	u32 remote_node_entries);
+
+u16 sci_remote_node_table_allocate_remote_node(
+	struct sci_remote_node_table *remote_node_table,
+	u32 remote_node_count);
+
+void sci_remote_node_table_release_remote_node_index(
+	struct sci_remote_node_table *remote_node_table,
+	u32 remote_node_count,
+	u16 remote_node_index);
+
+#endif /* _SCIC_SDS_REMOTE_NODE_TABLE_H_ */
diff -druN linux-2.6.39-libre/drivers/scsi/isci/request.c linux-3.0-rc7-libre/drivers/scsi/isci/request.c
--- linux-2.6.39-libre/drivers/scsi/isci/request.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/scsi/isci/request.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,3391 @@
+/*
+ * This file is provided under a dual BSD/GPLv2 license.  When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * The full GNU General Public License is included in this distribution
+ * in the file called LICENSE.GPL.
+ *
+ * BSD LICENSE
+ *
+ * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in
+ *     the documentation and/or other materials provided with the
+ *     distribution.
+ *   * Neither the name of Intel Corporation nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "isci.h"
+#include "task.h"
+#include "request.h"
+#include "scu_completion_codes.h"
+#include "scu_event_codes.h"
+#include "sas.h"
+
+static struct scu_sgl_element_pair *to_sgl_element_pair(struct isci_request *ireq,
+							int idx)
+{
+	if (idx == 0)
+		return &ireq->tc->sgl_pair_ab;
+	else if (idx == 1)
+		return &ireq->tc->sgl_pair_cd;
+	else if (idx < 0)
+		return NULL;
+	else
+		return &ireq->sg_table[idx - 2];
+}
+
+static dma_addr_t to_sgl_element_pair_dma(struct isci_host *ihost,
+					  struct isci_request *ireq, u32 idx)
+{
+	u32 offset;
+
+	if (idx == 0) {
+		offset = (void *) &ireq->tc->sgl_pair_ab -
+			 (void *) &ihost->task_context_table[0];
+		return ihost->task_context_dma + offset;
+	} else if (idx == 1) {
+		offset = (void *) &ireq->tc->sgl_pair_cd -
+			 (void *) &ihost->task_context_table[0];
+		return ihost->task_context_dma + offset;
+	}
+
+	return sci_io_request_get_dma_addr(ireq, &ireq->sg_table[idx - 2]);
+}
+
+static void init_sgl_element(struct scu_sgl_element *e, struct scatterlist *sg)
+{
+	e->length = sg_dma_len(sg);
+	e->address_upper = upper_32_bits(sg_dma_address(sg));
+	e->address_lower = lower_32_bits(sg_dma_address(sg));
+	e->address_modifier = 0;
+}
+
+static void sci_request_build_sgl(struct isci_request *ireq)
+{
+	struct isci_host *ihost = ireq->isci_host;
+	struct sas_task *task = isci_request_access_task(ireq);
+	struct scatterlist *sg = NULL;
+	dma_addr_t dma_addr;
+	u32 sg_idx = 0;
+	struct scu_sgl_element_pair *scu_sg   = NULL;
+	struct scu_sgl_element_pair *prev_sg  = NULL;
+
+	if (task->num_scatter > 0) {
+		sg = task->scatter;
+
+		while (sg) {
+			scu_sg = to_sgl_element_pair(ireq, sg_idx);
+			init_sgl_element(&scu_sg->A, sg);
+			sg = sg_next(sg);
+			if (sg) {
+				init_sgl_element(&scu_sg->B, sg);
+				sg = sg_next(sg);
+			} else
+				memset(&scu_sg->B, 0, sizeof(scu_sg->B));
+
+			if (prev_sg) {
+				dma_addr = to_sgl_element_pair_dma(ihost,
+								   ireq,
+								   sg_idx);
+
+				prev_sg->next_pair_upper =
+					upper_32_bits(dma_addr);
+				prev_sg->next_pair_lower =
+					lower_32_bits(dma_addr);
+			}
+
+			prev_sg = scu_sg;
+			sg_idx++;
+		}
+	} else {	/* handle when no sg */
+		scu_sg = to_sgl_element_pair(ireq, sg_idx);
+
+		dma_addr = dma_map_single(&ihost->pdev->dev,
+					  task->scatter,
+					  task->total_xfer_len,
+					  task->data_dir);
+
+		ireq->zero_scatter_daddr = dma_addr;
+
+		scu_sg->A.length = task->total_xfer_len;
+		scu_sg->A.address_upper = upper_32_bits(dma_addr);
+		scu_sg->A.address_lower = lower_32_bits(dma_addr);
+	}
+
+	if (scu_sg) {
+		scu_sg->next_pair_upper = 0;
+		scu_sg->next_pair_lower = 0;
+	}
+}
+
+static void sci_io_request_build_ssp_command_iu(struct isci_request *ireq)
+{
+	struct ssp_cmd_iu *cmd_iu;
+	struct sas_task *task = isci_request_access_task(ireq);
+
+	cmd_iu = &ireq->ssp.cmd;
+
+	memcpy(cmd_iu->LUN, task->ssp_task.LUN, 8);
+	cmd_iu->add_cdb_len = 0;
+	cmd_iu->_r_a = 0;
+	cmd_iu->_r_b = 0;
+	cmd_iu->en_fburst = 0; /* unsupported */
+	cmd_iu->task_prio = task->ssp_task.task_prio;
+	cmd_iu->task_attr = task->ssp_task.task_attr;
+	cmd_iu->_r_c = 0;
+
+	sci_swab32_cpy(&cmd_iu->cdb, task->ssp_task.cdb,
+		       sizeof(task->ssp_task.cdb) / sizeof(u32));
+}
+
+static void sci_task_request_build_ssp_task_iu(struct isci_request *ireq)
+{
+	struct ssp_task_iu *task_iu;
+	struct sas_task *task = isci_request_access_task(ireq);
+	struct isci_tmf *isci_tmf = isci_request_access_tmf(ireq);
+
+	task_iu = &ireq->ssp.tmf;
+
+	memset(task_iu, 0, sizeof(struct ssp_task_iu));
+
+	memcpy(task_iu->LUN, task->ssp_task.LUN, 8);
+
+	task_iu->task_func = isci_tmf->tmf_code;
+	task_iu->task_tag =
+		(ireq->ttype == tmf_task) ?
+		isci_tmf->io_tag :
+		SCI_CONTROLLER_INVALID_IO_TAG;
+}
+
+/**
+ * This method is will fill in the SCU Task Context for any type of SSP request.
+ * @sci_req:
+ * @task_context:
+ *
+ */
+static void scu_ssp_reqeust_construct_task_context(
+	struct isci_request *ireq,
+	struct scu_task_context *task_context)
+{
+	dma_addr_t dma_addr;
+	struct isci_remote_device *idev;
+	struct isci_port *iport;
+
+	idev = ireq->target_device;
+	iport = idev->owning_port;
+
+	/* Fill in the TC with the its required data */
+	task_context->abort = 0;
+	task_context->priority = 0;
+	task_context->initiator_request = 1;
+	task_context->connection_rate = idev->connection_rate;
+	task_context->protocol_engine_index = ISCI_PEG;
+	task_context->logical_port_index = iport->physical_port_index;
+	task_context->protocol_type = SCU_TASK_CONTEXT_PROTOCOL_SSP;
+	task_context->valid = SCU_TASK_CONTEXT_VALID;
+	task_context->context_type = SCU_TASK_CONTEXT_TYPE;
+
+	task_context->remote_node_index = idev->rnc.remote_node_index;
+	task_context->command_code = 0;
+
+	task_context->link_layer_control = 0;
+	task_context->do_not_dma_ssp_good_response = 1;
+	task_context->strict_ordering = 0;
+	task_context->control_frame = 0;
+	task_context->timeout_enable = 0;
+	task_context->block_guard_enable = 0;
+
+	task_context->address_modifier = 0;
+
+	/* task_context->type.ssp.tag = ireq->io_tag; */
+	task_context->task_phase = 0x01;
+
+	ireq->post_context = (SCU_CONTEXT_COMMAND_REQUEST_TYPE_POST_TC |
+			      (ISCI_PEG << SCU_CONTEXT_COMMAND_PROTOCOL_ENGINE_GROUP_SHIFT) |
+			      (iport->physical_port_index <<
+			       SCU_CONTEXT_COMMAND_LOGICAL_PORT_SHIFT) |
+			      ISCI_TAG_TCI(ireq->io_tag));
+
+	/*
+	 * Copy the physical address for the command buffer to the
+	 * SCU Task Context
+	 */
+	dma_addr = sci_io_request_get_dma_addr(ireq, &ireq->ssp.cmd);
+
+	task_context->command_iu_upper = upper_32_bits(dma_addr);
+	task_context->command_iu_lower = lower_32_bits(dma_addr);
+
+	/*
+	 * Copy the physical address for the response buffer to the
+	 * SCU Task Context
+	 */
+	dma_addr = sci_io_request_get_dma_addr(ireq, &ireq->ssp.rsp);
+
+	task_context->response_iu_upper = upper_32_bits(dma_addr);
+	task_context->response_iu_lower = lower_32_bits(dma_addr);
+}
+
+/**
+ * This method is will fill in the SCU Task Context for a SSP IO request.
+ * @sci_req:
+ *
+ */
+static void scu_ssp_io_request_construct_task_context(struct isci_request *ireq,
+						      enum dma_data_direction dir,
+						      u32 len)
+{
+	struct scu_task_context *task_context = ireq->tc;
+
+	scu_ssp_reqeust_construct_task_context(ireq, task_context);
+
+	task_context->ssp_command_iu_length =
+		sizeof(struct ssp_cmd_iu) / sizeof(u32);
+	task_context->type.ssp.frame_type = SSP_COMMAND;
+
+	switch (dir) {
+	case DMA_FROM_DEVICE:
+	case DMA_NONE:
+	default:
+		task_context->task_type = SCU_TASK_TYPE_IOREAD;
+		break;
+	case DMA_TO_DEVICE:
+		task_context->task_type = SCU_TASK_TYPE_IOWRITE;
+		break;
+	}
+
+	task_context->transfer_length_bytes = len;
+
+	if (task_context->transfer_length_bytes > 0)
+		sci_request_build_sgl(ireq);
+}
+
+/**
+ * This method will fill in the SCU Task Context for a SSP Task request.  The
+ *    following important settings are utilized: -# priority ==
+ *    SCU_TASK_PRIORITY_HIGH.  This ensures that the task request is issued
+ *    ahead of other task destined for the same Remote Node. -# task_type ==
+ *    SCU_TASK_TYPE_IOREAD.  This simply indicates that a normal request type
+ *    (i.e. non-raw frame) is being utilized to perform task management. -#
+ *    control_frame == 1.  This ensures that the proper endianess is set so
+ *    that the bytes are transmitted in the right order for a task frame.
+ * @sci_req: This parameter specifies the task request object being
+ *    constructed.
+ *
+ */
+static void scu_ssp_task_request_construct_task_context(struct isci_request *ireq)
+{
+	struct scu_task_context *task_context = ireq->tc;
+
+	scu_ssp_reqeust_construct_task_context(ireq, task_context);
+
+	task_context->control_frame                = 1;
+	task_context->priority                     = SCU_TASK_PRIORITY_HIGH;
+	task_context->task_type                    = SCU_TASK_TYPE_RAW_FRAME;
+	task_context->transfer_length_bytes        = 0;
+	task_context->type.ssp.frame_type          = SSP_TASK;
+	task_context->ssp_command_iu_length =
+		sizeof(struct ssp_task_iu) / sizeof(u32);
+}
+
+/**
+ * This method is will fill in the SCU Task Context for any type of SATA
+ *    request.  This is called from the various SATA constructors.
+ * @sci_req: The general IO request object which is to be used in
+ *    constructing the SCU task context.
+ * @task_context: The buffer pointer for the SCU task context which is being
+ *    constructed.
+ *
+ * The general io request construction is complete. The buffer assignment for
+ * the command buffer is complete. none Revisit task context construction to
+ * determine what is common for SSP/SMP/STP task context structures.
+ */
+static void scu_sata_reqeust_construct_task_context(
+	struct isci_request *ireq,
+	struct scu_task_context *task_context)
+{
+	dma_addr_t dma_addr;
+	struct isci_remote_device *idev;
+	struct isci_port *iport;
+
+	idev = ireq->target_device;
+	iport = idev->owning_port;
+
+	/* Fill in the TC with the its required data */
+	task_context->abort = 0;
+	task_context->priority = SCU_TASK_PRIORITY_NORMAL;
+	task_context->initiator_request = 1;
+	task_context->connection_rate = idev->connection_rate;
+	task_context->protocol_engine_index = ISCI_PEG;
+	task_context->logical_port_index = iport->physical_port_index;
+	task_context->protocol_type = SCU_TASK_CONTEXT_PROTOCOL_STP;
+	task_context->valid = SCU_TASK_CONTEXT_VALID;
+	task_context->context_type = SCU_TASK_CONTEXT_TYPE;
+
+	task_context->remote_node_index = idev->rnc.remote_node_index;
+	task_context->command_code = 0;
+
+	task_context->link_layer_control = 0;
+	task_context->do_not_dma_ssp_good_response = 1;
+	task_context->strict_ordering = 0;
+	task_context->control_frame = 0;
+	task_context->timeout_enable = 0;
+	task_context->block_guard_enable = 0;
+
+	task_context->address_modifier = 0;
+	task_context->task_phase = 0x01;
+
+	task_context->ssp_command_iu_length =
+		(sizeof(struct host_to_dev_fis) - sizeof(u32)) / sizeof(u32);
+
+	/* Set the first word of the H2D REG FIS */
+	task_context->type.words[0] = *(u32 *)&ireq->stp.cmd;
+
+	ireq->post_context = (SCU_CONTEXT_COMMAND_REQUEST_TYPE_POST_TC |
+			      (ISCI_PEG << SCU_CONTEXT_COMMAND_PROTOCOL_ENGINE_GROUP_SHIFT) |
+			      (iport->physical_port_index <<
+			       SCU_CONTEXT_COMMAND_LOGICAL_PORT_SHIFT) |
+			      ISCI_TAG_TCI(ireq->io_tag));
+	/*
+	 * Copy the physical address for the command buffer to the SCU Task
+	 * Context. We must offset the command buffer by 4 bytes because the
+	 * first 4 bytes are transfered in the body of the TC.
+	 */
+	dma_addr = sci_io_request_get_dma_addr(ireq,
+						((char *) &ireq->stp.cmd) +
+						sizeof(u32));
+
+	task_context->command_iu_upper = upper_32_bits(dma_addr);
+	task_context->command_iu_lower = lower_32_bits(dma_addr);
+
+	/* SATA Requests do not have a response buffer */
+	task_context->response_iu_upper = 0;
+	task_context->response_iu_lower = 0;
+}
+
+static void scu_stp_raw_request_construct_task_context(struct isci_request *ireq)
+{
+	struct scu_task_context *task_context = ireq->tc;
+
+	scu_sata_reqeust_construct_task_context(ireq, task_context);
+
+	task_context->control_frame         = 0;
+	task_context->priority              = SCU_TASK_PRIORITY_NORMAL;
+	task_context->task_type             = SCU_TASK_TYPE_SATA_RAW_FRAME;
+	task_context->type.stp.fis_type     = FIS_REGH2D;
+	task_context->transfer_length_bytes = sizeof(struct host_to_dev_fis) - sizeof(u32);
+}
+
+static enum sci_status sci_stp_pio_request_construct(struct isci_request *ireq,
+							  bool copy_rx_frame)
+{
+	struct isci_stp_request *stp_req = &ireq->stp.req;
+
+	scu_stp_raw_request_construct_task_context(ireq);
+
+	stp_req->status = 0;
+	stp_req->sgl.offset = 0;
+	stp_req->sgl.set = SCU_SGL_ELEMENT_PAIR_A;
+
+	if (copy_rx_frame) {
+		sci_request_build_sgl(ireq);
+		stp_req->sgl.index = 0;
+	} else {
+		/* The user does not want the data copied to the SGL buffer location */
+		stp_req->sgl.index = -1;
+	}
+
+	return SCI_SUCCESS;
+}
+
+/**
+ *
+ * @sci_req: This parameter specifies the request to be constructed as an
+ *    optimized request.
+ * @optimized_task_type: This parameter specifies whether the request is to be
+ *    an UDMA request or a NCQ request. - A value of 0 indicates UDMA. - A
+ *    value of 1 indicates NCQ.
+ *
+ * This method will perform request construction common to all types of STP
+ * requests that are optimized by the silicon (i.e. UDMA, NCQ). This method
+ * returns an indication as to whether the construction was successful.
+ */
+static void sci_stp_optimized_request_construct(struct isci_request *ireq,
+						     u8 optimized_task_type,
+						     u32 len,
+						     enum dma_data_direction dir)
+{
+	struct scu_task_context *task_context = ireq->tc;
+
+	/* Build the STP task context structure */
+	scu_sata_reqeust_construct_task_context(ireq, task_context);
+
+	/* Copy over the SGL elements */
+	sci_request_build_sgl(ireq);
+
+	/* Copy over the number of bytes to be transfered */
+	task_context->transfer_length_bytes = len;
+
+	if (dir == DMA_TO_DEVICE) {
+		/*
+		 * The difference between the DMA IN and DMA OUT request task type
+		 * values are consistent with the difference between FPDMA READ
+		 * and FPDMA WRITE values.  Add the supplied task type parameter
+		 * to this difference to set the task type properly for this
+		 * DATA OUT (WRITE) case. */
+		task_context->task_type = optimized_task_type + (SCU_TASK_TYPE_DMA_OUT
+								 - SCU_TASK_TYPE_DMA_IN);
+	} else {
+		/*
+		 * For the DATA IN (READ) case, simply save the supplied
+		 * optimized task type. */
+		task_context->task_type = optimized_task_type;
+	}
+}
+
+
+
+static enum sci_status
+sci_io_request_construct_sata(struct isci_request *ireq,
+			       u32 len,
+			       enum dma_data_direction dir,
+			       bool copy)
+{
+	enum sci_status status = SCI_SUCCESS;
+	struct sas_task *task = isci_request_access_task(ireq);
+
+	/* check for management protocols */
+	if (ireq->ttype == tmf_task) {
+		struct isci_tmf *tmf = isci_request_access_tmf(ireq);
+
+		if (tmf->tmf_code == isci_tmf_sata_srst_high ||
+		    tmf->tmf_code == isci_tmf_sata_srst_low) {
+			scu_stp_raw_request_construct_task_context(ireq);
+			return SCI_SUCCESS;
+		} else {
+			dev_err(&ireq->owning_controller->pdev->dev,
+				"%s: Request 0x%p received un-handled SAT "
+				"management protocol 0x%x.\n",
+				__func__, ireq, tmf->tmf_code);
+
+			return SCI_FAILURE;
+		}
+	}
+
+	if (!sas_protocol_ata(task->task_proto)) {
+		dev_err(&ireq->owning_controller->pdev->dev,
+			"%s: Non-ATA protocol in SATA path: 0x%x\n",
+			__func__,
+			task->task_proto);
+		return SCI_FAILURE;
+
+	}
+
+	/* non data */
+	if (task->data_dir == DMA_NONE) {
+		scu_stp_raw_request_construct_task_context(ireq);
+		return SCI_SUCCESS;
+	}
+
+	/* NCQ */
+	if (task->ata_task.use_ncq) {
+		sci_stp_optimized_request_construct(ireq,
+							 SCU_TASK_TYPE_FPDMAQ_READ,
+							 len, dir);
+		return SCI_SUCCESS;
+	}
+
+	/* DMA */
+	if (task->ata_task.dma_xfer) {
+		sci_stp_optimized_request_construct(ireq,
+							 SCU_TASK_TYPE_DMA_IN,
+							 len, dir);
+		return SCI_SUCCESS;
+	} else /* PIO */
+		return sci_stp_pio_request_construct(ireq, copy);
+
+	return status;
+}
+
+static enum sci_status sci_io_request_construct_basic_ssp(struct isci_request *ireq)
+{
+	struct sas_task *task = isci_request_access_task(ireq);
+
+	ireq->protocol = SCIC_SSP_PROTOCOL;
+
+	scu_ssp_io_request_construct_task_context(ireq,
+						  task->data_dir,
+						  task->total_xfer_len);
+
+	sci_io_request_build_ssp_command_iu(ireq);
+
+	sci_change_state(&ireq->sm, SCI_REQ_CONSTRUCTED);
+
+	return SCI_SUCCESS;
+}
+
+enum sci_status sci_task_request_construct_ssp(
+	struct isci_request *ireq)
+{
+	/* Construct the SSP Task SCU Task Context */
+	scu_ssp_task_request_construct_task_context(ireq);
+
+	/* Fill in the SSP Task IU */
+	sci_task_request_build_ssp_task_iu(ireq);
+
+	sci_change_state(&ireq->sm, SCI_REQ_CONSTRUCTED);
+
+	return SCI_SUCCESS;
+}
+
+static enum sci_status sci_io_request_construct_basic_sata(struct isci_request *ireq)
+{
+	enum sci_status status;
+	bool copy = false;
+	struct sas_task *task = isci_request_access_task(ireq);
+
+	ireq->protocol = SCIC_STP_PROTOCOL;
+
+	copy = (task->data_dir == DMA_NONE) ? false : true;
+
+	status = sci_io_request_construct_sata(ireq,
+						task->total_xfer_len,
+						task->data_dir,
+						copy);
+
+	if (status == SCI_SUCCESS)
+		sci_change_state(&ireq->sm, SCI_REQ_CONSTRUCTED);
+
+	return status;
+}
+
+enum sci_status sci_task_request_construct_sata(struct isci_request *ireq)
+{
+	enum sci_status status = SCI_SUCCESS;
+
+	/* check for management protocols */
+	if (ireq->ttype == tmf_task) {
+		struct isci_tmf *tmf = isci_request_access_tmf(ireq);
+
+		if (tmf->tmf_code == isci_tmf_sata_srst_high ||
+		    tmf->tmf_code == isci_tmf_sata_srst_low) {
+			scu_stp_raw_request_construct_task_context(ireq);
+		} else {
+			dev_err(&ireq->owning_controller->pdev->dev,
+				"%s: Request 0x%p received un-handled SAT "
+				"Protocol 0x%x.\n",
+				__func__, ireq, tmf->tmf_code);
+
+			return SCI_FAILURE;
+		}
+	}
+
+	if (status != SCI_SUCCESS)
+		return status;
+	sci_change_state(&ireq->sm, SCI_REQ_CONSTRUCTED);
+
+	return status;
+}
+
+/**
+ * sci_req_tx_bytes - bytes transferred when reply underruns request
+ * @sci_req: request that was terminated early
+ */
+#define SCU_TASK_CONTEXT_SRAM 0x200000
+static u32 sci_req_tx_bytes(struct isci_request *ireq)
+{
+	struct isci_host *ihost = ireq->owning_controller;
+	u32 ret_val = 0;
+
+	if (readl(&ihost->smu_registers->address_modifier) == 0) {
+		void __iomem *scu_reg_base = ihost->scu_registers;
+
+		/* get the bytes of data from the Address == BAR1 + 20002Ch + (256*TCi) where
+		 *   BAR1 is the scu_registers
+		 *   0x20002C = 0x200000 + 0x2c
+		 *            = start of task context SRAM + offset of (type.ssp.data_offset)
+		 *   TCi is the io_tag of struct sci_request
+		 */
+		ret_val = readl(scu_reg_base +
+				(SCU_TASK_CONTEXT_SRAM + offsetof(struct scu_task_context, type.ssp.data_offset)) +
+				((sizeof(struct scu_task_context)) * ISCI_TAG_TCI(ireq->io_tag)));
+	}
+
+	return ret_val;
+}
+
+enum sci_status sci_request_start(struct isci_request *ireq)
+{
+	enum sci_base_request_states state;
+	struct scu_task_context *tc = ireq->tc;
+	struct isci_host *ihost = ireq->owning_controller;
+
+	state = ireq->sm.current_state_id;
+	if (state != SCI_REQ_CONSTRUCTED) {
+		dev_warn(&ihost->pdev->dev,
+			"%s: SCIC IO Request requested to start while in wrong "
+			 "state %d\n", __func__, state);
+		return SCI_FAILURE_INVALID_STATE;
+	}
+
+	tc->task_index = ISCI_TAG_TCI(ireq->io_tag);
+
+	switch (tc->protocol_type) {
+	case SCU_TASK_CONTEXT_PROTOCOL_SMP:
+	case SCU_TASK_CONTEXT_PROTOCOL_SSP:
+		/* SSP/SMP Frame */
+		tc->type.ssp.tag = ireq->io_tag;
+		tc->type.ssp.target_port_transfer_tag = 0xFFFF;
+		break;
+
+	case SCU_TASK_CONTEXT_PROTOCOL_STP:
+		/* STP/SATA Frame
+		 * tc->type.stp.ncq_tag = ireq->ncq_tag;
+		 */
+		break;
+
+	case SCU_TASK_CONTEXT_PROTOCOL_NONE:
+		/* / @todo When do we set no protocol type? */
+		break;
+
+	default:
+		/* This should never happen since we build the IO
+		 * requests */
+		break;
+	}
+
+	/* Add to the post_context the io tag value */
+	ireq->post_context |= ISCI_TAG_TCI(ireq->io_tag);
+
+	/* Everything is good go ahead and change state */
+	sci_change_state(&ireq->sm, SCI_REQ_STARTED);
+
+	return SCI_SUCCESS;
+}
+
+enum sci_status
+sci_io_request_terminate(struct isci_request *ireq)
+{
+	enum sci_base_request_states state;
+
+	state = ireq->sm.current_state_id;
+
+	switch (state) {
+	case SCI_REQ_CONSTRUCTED:
+		ireq->scu_status = SCU_TASK_DONE_TASK_ABORT;
+		ireq->sci_status = SCI_FAILURE_IO_TERMINATED;
+		sci_change_state(&ireq->sm, SCI_REQ_COMPLETED);
+		return SCI_SUCCESS;
+	case SCI_REQ_STARTED:
+	case SCI_REQ_TASK_WAIT_TC_COMP:
+	case SCI_REQ_SMP_WAIT_RESP:
+	case SCI_REQ_SMP_WAIT_TC_COMP:
+	case SCI_REQ_STP_UDMA_WAIT_TC_COMP:
+	case SCI_REQ_STP_UDMA_WAIT_D2H:
+	case SCI_REQ_STP_NON_DATA_WAIT_H2D:
+	case SCI_REQ_STP_NON_DATA_WAIT_D2H:
+	case SCI_REQ_STP_PIO_WAIT_H2D:
+	case SCI_REQ_STP_PIO_WAIT_FRAME:
+	case SCI_REQ_STP_PIO_DATA_IN:
+	case SCI_REQ_STP_PIO_DATA_OUT:
+	case SCI_REQ_STP_SOFT_RESET_WAIT_H2D_ASSERTED:
+	case SCI_REQ_STP_SOFT_RESET_WAIT_H2D_DIAG:
+	case SCI_REQ_STP_SOFT_RESET_WAIT_D2H:
+		sci_change_state(&ireq->sm, SCI_REQ_ABORTING);
+		return SCI_SUCCESS;
+	case SCI_REQ_TASK_WAIT_TC_RESP:
+		sci_change_state(&ireq->sm, SCI_REQ_ABORTING);
+		sci_change_state(&ireq->sm, SCI_REQ_COMPLETED);
+		return SCI_SUCCESS;
+	case SCI_REQ_ABORTING:
+		sci_change_state(&ireq->sm, SCI_REQ_COMPLETED);
+		return SCI_SUCCESS;
+	case SCI_REQ_COMPLETED:
+	default:
+		dev_warn(&ireq->owning_controller->pdev->dev,
+			 "%s: SCIC IO Request requested to abort while in wrong "
+			 "state %d\n",
+			 __func__,
+			 ireq->sm.current_state_id);
+		break;
+	}
+
+	return SCI_FAILURE_INVALID_STATE;
+}
+
+enum sci_status sci_request_complete(struct isci_request *ireq)
+{
+	enum sci_base_request_states state;
+	struct isci_host *ihost = ireq->owning_controller;
+
+	state = ireq->sm.current_state_id;
+	if (WARN_ONCE(state != SCI_REQ_COMPLETED,
+		      "isci: request completion from wrong state (%d)\n", state))
+		return SCI_FAILURE_INVALID_STATE;
+
+	if (ireq->saved_rx_frame_index != SCU_INVALID_FRAME_INDEX)
+		sci_controller_release_frame(ihost,
+						  ireq->saved_rx_frame_index);
+
+	/* XXX can we just stop the machine and remove the 'final' state? */
+	sci_change_state(&ireq->sm, SCI_REQ_FINAL);
+	return SCI_SUCCESS;
+}
+
+enum sci_status sci_io_request_event_handler(struct isci_request *ireq,
+						  u32 event_code)
+{
+	enum sci_base_request_states state;
+	struct isci_host *ihost = ireq->owning_controller;
+
+	state = ireq->sm.current_state_id;
+
+	if (state != SCI_REQ_STP_PIO_DATA_IN) {
+		dev_warn(&ihost->pdev->dev, "%s: (%x) in wrong state %d\n",
+			 __func__, event_code, state);
+
+		return SCI_FAILURE_INVALID_STATE;
+	}
+
+	switch (scu_get_event_specifier(event_code)) {
+	case SCU_TASK_DONE_CRC_ERR << SCU_EVENT_SPECIFIC_CODE_SHIFT:
+		/* We are waiting for data and the SCU has R_ERR the data frame.
+		 * Go back to waiting for the D2H Register FIS
+		 */
+		sci_change_state(&ireq->sm, SCI_REQ_STP_PIO_WAIT_FRAME);
+		return SCI_SUCCESS;
+	default:
+		dev_err(&ihost->pdev->dev,
+			"%s: pio request unexpected event %#x\n",
+			__func__, event_code);
+
+		/* TODO Should we fail the PIO request when we get an
+		 * unexpected event?
+		 */
+		return SCI_FAILURE;
+	}
+}
+
+/*
+ * This function copies response data for requests returning response data
+ *    instead of sense data.
+ * @sci_req: This parameter specifies the request object for which to copy
+ *    the response data.
+ */
+static void sci_io_request_copy_response(struct isci_request *ireq)
+{
+	void *resp_buf;
+	u32 len;
+	struct ssp_response_iu *ssp_response;
+	struct isci_tmf *isci_tmf = isci_request_access_tmf(ireq);
+
+	ssp_response = &ireq->ssp.rsp;
+
+	resp_buf = &isci_tmf->resp.resp_iu;
+
+	len = min_t(u32,
+		    SSP_RESP_IU_MAX_SIZE,
+		    be32_to_cpu(ssp_response->response_data_len));
+
+	memcpy(resp_buf, ssp_response->resp_data, len);
+}
+
+static enum sci_status
+request_started_state_tc_event(struct isci_request *ireq,
+			       u32 completion_code)
+{
+	struct ssp_response_iu *resp_iu;
+	u8 datapres;
+
+	/* TODO: Any SDMA return code of other than 0 is bad decode 0x003C0000
+	 * to determine SDMA status
+	 */
+	switch (SCU_GET_COMPLETION_TL_STATUS(completion_code)) {
+	case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_GOOD):
+		ireq->scu_status = SCU_TASK_DONE_GOOD;
+		ireq->sci_status = SCI_SUCCESS;
+		break;
+	case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_EARLY_RESP): {
+		/* There are times when the SCU hardware will return an early
+		 * response because the io request specified more data than is
+		 * returned by the target device (mode pages, inquiry data,
+		 * etc.).  We must check the response stats to see if this is
+		 * truly a failed request or a good request that just got
+		 * completed early.
+		 */
+		struct ssp_response_iu *resp = &ireq->ssp.rsp;
+		ssize_t word_cnt = SSP_RESP_IU_MAX_SIZE / sizeof(u32);
+
+		sci_swab32_cpy(&ireq->ssp.rsp,
+			       &ireq->ssp.rsp,
+			       word_cnt);
+
+		if (resp->status == 0) {
+			ireq->scu_status = SCU_TASK_DONE_GOOD;
+			ireq->sci_status = SCI_SUCCESS_IO_DONE_EARLY;
+		} else {
+			ireq->scu_status = SCU_TASK_DONE_CHECK_RESPONSE;
+			ireq->sci_status = SCI_FAILURE_IO_RESPONSE_VALID;
+		}
+		break;
+	}
+	case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_CHECK_RESPONSE): {
+		ssize_t word_cnt = SSP_RESP_IU_MAX_SIZE / sizeof(u32);
+
+		sci_swab32_cpy(&ireq->ssp.rsp,
+			       &ireq->ssp.rsp,
+			       word_cnt);
+
+		ireq->scu_status = SCU_TASK_DONE_CHECK_RESPONSE;
+		ireq->sci_status = SCI_FAILURE_IO_RESPONSE_VALID;
+		break;
+	}
+
+	case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_RESP_LEN_ERR):
+		/* TODO With TASK_DONE_RESP_LEN_ERR is the response frame
+		 * guaranteed to be received before this completion status is
+		 * posted?
+		 */
+		resp_iu = &ireq->ssp.rsp;
+		datapres = resp_iu->datapres;
+
+		if (datapres == 1 || datapres == 2) {
+			ireq->scu_status = SCU_TASK_DONE_CHECK_RESPONSE;
+			ireq->sci_status = SCI_FAILURE_IO_RESPONSE_VALID;
+		} else {
+			ireq->scu_status = SCU_TASK_DONE_GOOD;
+			ireq->sci_status = SCI_SUCCESS;
+		}
+		break;
+	/* only stp device gets suspended. */
+	case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_ACK_NAK_TO):
+	case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_LL_PERR):
+	case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_NAK_ERR):
+	case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_DATA_LEN_ERR):
+	case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_LL_ABORT_ERR):
+	case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_XR_WD_LEN):
+	case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_MAX_PLD_ERR):
+	case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_UNEXP_RESP):
+	case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_UNEXP_SDBFIS):
+	case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_REG_ERR):
+	case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_SDB_ERR):
+		if (ireq->protocol == SCIC_STP_PROTOCOL) {
+			ireq->scu_status = SCU_GET_COMPLETION_TL_STATUS(completion_code) >>
+					   SCU_COMPLETION_TL_STATUS_SHIFT;
+			ireq->sci_status = SCI_FAILURE_REMOTE_DEVICE_RESET_REQUIRED;
+		} else {
+			ireq->scu_status = SCU_GET_COMPLETION_TL_STATUS(completion_code) >>
+					   SCU_COMPLETION_TL_STATUS_SHIFT;
+			ireq->sci_status = SCI_FAILURE_CONTROLLER_SPECIFIC_IO_ERR;
+		}
+		break;
+
+	/* both stp/ssp device gets suspended */
+	case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_LF_ERR):
+	case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_OPEN_REJECT_WRONG_DESTINATION):
+	case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_OPEN_REJECT_RESERVED_ABANDON_1):
+	case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_OPEN_REJECT_RESERVED_ABANDON_2):
+	case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_OPEN_REJECT_RESERVED_ABANDON_3):
+	case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_OPEN_REJECT_BAD_DESTINATION):
+	case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_OPEN_REJECT_ZONE_VIOLATION):
+	case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_OPEN_REJECT_STP_RESOURCES_BUSY):
+	case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_OPEN_REJECT_PROTOCOL_NOT_SUPPORTED):
+	case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_OPEN_REJECT_CONNECTION_RATE_NOT_SUPPORTED):
+		ireq->scu_status = SCU_GET_COMPLETION_TL_STATUS(completion_code) >>
+				   SCU_COMPLETION_TL_STATUS_SHIFT;
+		ireq->sci_status = SCI_FAILURE_REMOTE_DEVICE_RESET_REQUIRED;
+		break;
+
+	/* neither ssp nor stp gets suspended. */
+	case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_NAK_CMD_ERR):
+	case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_UNEXP_XR):
+	case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_XR_IU_LEN_ERR):
+	case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_SDMA_ERR):
+	case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_OFFSET_ERR):
+	case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_EXCESS_DATA):
+	case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_SMP_RESP_TO_ERR):
+	case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_SMP_UFI_ERR):
+	case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_SMP_FRM_TYPE_ERR):
+	case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_SMP_LL_RX_ERR):
+	case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_UNEXP_DATA):
+	case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_OPEN_FAIL):
+	case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_VIIT_ENTRY_NV):
+	case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_IIT_ENTRY_NV):
+	case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_RNCNV_OUTBOUND):
+	default:
+		ireq->scu_status = SCU_GET_COMPLETION_TL_STATUS(completion_code) >>
+				   SCU_COMPLETION_TL_STATUS_SHIFT;
+		ireq->sci_status = SCI_FAILURE_CONTROLLER_SPECIFIC_IO_ERR;
+		break;
+	}
+
+	/*
+	 * TODO: This is probably wrong for ACK/NAK timeout conditions
+	 */
+
+	/* In all cases we will treat this as the completion of the IO req. */
+	sci_change_state(&ireq->sm, SCI_REQ_COMPLETED);
+	return SCI_SUCCESS;
+}
+
+static enum sci_status
+request_aborting_state_tc_event(struct isci_request *ireq,
+				u32 completion_code)
+{
+	switch (SCU_GET_COMPLETION_TL_STATUS(completion_code)) {
+	case (SCU_TASK_DONE_GOOD << SCU_COMPLETION_TL_STATUS_SHIFT):
+	case (SCU_TASK_DONE_TASK_ABORT << SCU_COMPLETION_TL_STATUS_SHIFT):
+		ireq->scu_status = SCU_TASK_DONE_TASK_ABORT;
+		ireq->sci_status = SCI_FAILURE_IO_TERMINATED;
+		sci_change_state(&ireq->sm, SCI_REQ_COMPLETED);
+		break;
+
+	default:
+		/* Unless we get some strange error wait for the task abort to complete
+		 * TODO: Should there be a state change for this completion?
+		 */
+		break;
+	}
+
+	return SCI_SUCCESS;
+}
+
+static enum sci_status ssp_task_request_await_tc_event(struct isci_request *ireq,
+						       u32 completion_code)
+{
+	switch (SCU_GET_COMPLETION_TL_STATUS(completion_code)) {
+	case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_GOOD):
+		ireq->scu_status = SCU_TASK_DONE_GOOD;
+		ireq->sci_status = SCI_SUCCESS;
+		sci_change_state(&ireq->sm, SCI_REQ_TASK_WAIT_TC_RESP);
+		break;
+	case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_ACK_NAK_TO):
+		/* Currently, the decision is to simply allow the task request
+		 * to timeout if the task IU wasn't received successfully.
+		 * There is a potential for receiving multiple task responses if
+		 * we decide to send the task IU again.
+		 */
+		dev_warn(&ireq->owning_controller->pdev->dev,
+			 "%s: TaskRequest:0x%p CompletionCode:%x - "
+			 "ACK/NAK timeout\n", __func__, ireq,
+			 completion_code);
+
+		sci_change_state(&ireq->sm, SCI_REQ_TASK_WAIT_TC_RESP);
+		break;
+	default:
+		/*
+		 * All other completion status cause the IO to be complete.
+		 * If a NAK was received, then it is up to the user to retry
+		 * the request.
+		 */
+		ireq->scu_status = SCU_NORMALIZE_COMPLETION_STATUS(completion_code);
+		ireq->sci_status = SCI_FAILURE_CONTROLLER_SPECIFIC_IO_ERR;
+		sci_change_state(&ireq->sm, SCI_REQ_COMPLETED);
+		break;
+	}
+
+	return SCI_SUCCESS;
+}
+
+static enum sci_status
+smp_request_await_response_tc_event(struct isci_request *ireq,
+				    u32 completion_code)
+{
+	switch (SCU_GET_COMPLETION_TL_STATUS(completion_code)) {
+	case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_GOOD):
+		/* In the AWAIT RESPONSE state, any TC completion is
+		 * unexpected.  but if the TC has success status, we
+		 * complete the IO anyway.
+		 */
+		ireq->scu_status = SCU_TASK_DONE_GOOD;
+		ireq->sci_status = SCI_SUCCESS;
+		sci_change_state(&ireq->sm, SCI_REQ_COMPLETED);
+		break;
+	case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_SMP_RESP_TO_ERR):
+	case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_SMP_UFI_ERR):
+	case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_SMP_FRM_TYPE_ERR):
+	case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_SMP_LL_RX_ERR):
+		/* These status has been seen in a specific LSI
+		 * expander, which sometimes is not able to send smp
+		 * response within 2 ms. This causes our hardware break
+		 * the connection and set TC completion with one of
+		 * these SMP_XXX_XX_ERR status. For these type of error,
+		 * we ask ihost user to retry the request.
+		 */
+		ireq->scu_status = SCU_TASK_DONE_SMP_RESP_TO_ERR;
+		ireq->sci_status = SCI_FAILURE_RETRY_REQUIRED;
+		sci_change_state(&ireq->sm, SCI_REQ_COMPLETED);
+		break;
+	default:
+		/* All other completion status cause the IO to be complete.  If a NAK
+		 * was received, then it is up to the user to retry the request
+		 */
+		ireq->scu_status = SCU_NORMALIZE_COMPLETION_STATUS(completion_code);
+		ireq->sci_status = SCI_FAILURE_CONTROLLER_SPECIFIC_IO_ERR;
+		sci_change_state(&ireq->sm, SCI_REQ_COMPLETED);
+		break;
+	}
+
+	return SCI_SUCCESS;
+}
+
+static enum sci_status
+smp_request_await_tc_event(struct isci_request *ireq,
+			   u32 completion_code)
+{
+	switch (SCU_GET_COMPLETION_TL_STATUS(completion_code)) {
+	case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_GOOD):
+		ireq->scu_status = SCU_TASK_DONE_GOOD;
+		ireq->sci_status = SCI_SUCCESS;
+		sci_change_state(&ireq->sm, SCI_REQ_COMPLETED);
+		break;
+	default:
+		/* All other completion status cause the IO to be
+		 * complete.  If a NAK was received, then it is up to
+		 * the user to retry the request.
+		 */
+		ireq->scu_status = SCU_NORMALIZE_COMPLETION_STATUS(completion_code);
+		ireq->sci_status = SCI_FAILURE_CONTROLLER_SPECIFIC_IO_ERR;
+		sci_change_state(&ireq->sm, SCI_REQ_COMPLETED);
+		break;
+	}
+
+	return SCI_SUCCESS;
+}
+
+static struct scu_sgl_element *pio_sgl_next(struct isci_stp_request *stp_req)
+{
+	struct scu_sgl_element *sgl;
+	struct scu_sgl_element_pair *sgl_pair;
+	struct isci_request *ireq = to_ireq(stp_req);
+	struct isci_stp_pio_sgl *pio_sgl = &stp_req->sgl;
+
+	sgl_pair = to_sgl_element_pair(ireq, pio_sgl->index);
+	if (!sgl_pair)
+		sgl = NULL;
+	else if (pio_sgl->set == SCU_SGL_ELEMENT_PAIR_A) {
+		if (sgl_pair->B.address_lower == 0 &&
+		    sgl_pair->B.address_upper == 0) {
+			sgl = NULL;
+		} else {
+			pio_sgl->set = SCU_SGL_ELEMENT_PAIR_B;
+			sgl = &sgl_pair->B;
+		}
+	} else {
+		if (sgl_pair->next_pair_lower == 0 &&
+		    sgl_pair->next_pair_upper == 0) {
+			sgl = NULL;
+		} else {
+			pio_sgl->index++;
+			pio_sgl->set = SCU_SGL_ELEMENT_PAIR_A;
+			sgl_pair = to_sgl_element_pair(ireq, pio_sgl->index);
+			sgl = &sgl_pair->A;
+		}
+	}
+
+	return sgl;
+}
+
+static enum sci_status
+stp_request_non_data_await_h2d_tc_event(struct isci_request *ireq,
+					u32 completion_code)
+{
+	switch (SCU_GET_COMPLETION_TL_STATUS(completion_code)) {
+	case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_GOOD):
+		ireq->scu_status = SCU_TASK_DONE_GOOD;
+		ireq->sci_status = SCI_SUCCESS;
+		sci_change_state(&ireq->sm, SCI_REQ_STP_NON_DATA_WAIT_D2H);
+		break;
+
+	default:
+		/* All other completion status cause the IO to be
+		 * complete.  If a NAK was received, then it is up to
+		 * the user to retry the request.
+		 */
+		ireq->scu_status = SCU_NORMALIZE_COMPLETION_STATUS(completion_code);
+		ireq->sci_status = SCI_FAILURE_CONTROLLER_SPECIFIC_IO_ERR;
+		sci_change_state(&ireq->sm, SCI_REQ_COMPLETED);
+		break;
+	}
+
+	return SCI_SUCCESS;
+}
+
+#define SCU_MAX_FRAME_BUFFER_SIZE  0x400  /* 1K is the maximum SCU frame data payload */
+
+/* transmit DATA_FIS from (current sgl + offset) for input
+ * parameter length. current sgl and offset is alreay stored in the IO request
+ */
+static enum sci_status sci_stp_request_pio_data_out_trasmit_data_frame(
+	struct isci_request *ireq,
+	u32 length)
+{
+	struct isci_stp_request *stp_req = &ireq->stp.req;
+	struct scu_task_context *task_context = ireq->tc;
+	struct scu_sgl_element_pair *sgl_pair;
+	struct scu_sgl_element *current_sgl;
+
+	/* Recycle the TC and reconstruct it for sending out DATA FIS containing
+	 * for the data from current_sgl+offset for the input length
+	 */
+	sgl_pair = to_sgl_element_pair(ireq, stp_req->sgl.index);
+	if (stp_req->sgl.set == SCU_SGL_ELEMENT_PAIR_A)
+		current_sgl = &sgl_pair->A;
+	else
+		current_sgl = &sgl_pair->B;
+
+	/* update the TC */
+	task_context->command_iu_upper = current_sgl->address_upper;
+	task_context->command_iu_lower = current_sgl->address_lower;
+	task_context->transfer_length_bytes = length;
+	task_context->type.stp.fis_type = FIS_DATA;
+
+	/* send the new TC out. */
+	return sci_controller_continue_io(ireq);
+}
+
+static enum sci_status sci_stp_request_pio_data_out_transmit_data(struct isci_request *ireq)
+{
+	struct isci_stp_request *stp_req = &ireq->stp.req;
+	struct scu_sgl_element_pair *sgl_pair;
+	struct scu_sgl_element *sgl;
+	enum sci_status status;
+	u32 offset;
+	u32 len = 0;
+
+	offset = stp_req->sgl.offset;
+	sgl_pair = to_sgl_element_pair(ireq, stp_req->sgl.index);
+	if (WARN_ONCE(!sgl_pair, "%s: null sgl element", __func__))
+		return SCI_FAILURE;
+
+	if (stp_req->sgl.set == SCU_SGL_ELEMENT_PAIR_A) {
+		sgl = &sgl_pair->A;
+		len = sgl_pair->A.length - offset;
+	} else {
+		sgl = &sgl_pair->B;
+		len = sgl_pair->B.length - offset;
+	}
+
+	if (stp_req->pio_len == 0)
+		return SCI_SUCCESS;
+
+	if (stp_req->pio_len >= len) {
+		status = sci_stp_request_pio_data_out_trasmit_data_frame(ireq, len);
+		if (status != SCI_SUCCESS)
+			return status;
+		stp_req->pio_len -= len;
+
+		/* update the current sgl, offset and save for future */
+		sgl = pio_sgl_next(stp_req);
+		offset = 0;
+	} else if (stp_req->pio_len < len) {
+		sci_stp_request_pio_data_out_trasmit_data_frame(ireq, stp_req->pio_len);
+
+		/* Sgl offset will be adjusted and saved for future */
+		offset += stp_req->pio_len;
+		sgl->address_lower += stp_req->pio_len;
+		stp_req->pio_len = 0;
+	}
+
+	stp_req->sgl.offset = offset;
+
+	return status;
+}
+
+/**
+ *
+ * @stp_request: The request that is used for the SGL processing.
+ * @data_buffer: The buffer of data to be copied.
+ * @length: The length of the data transfer.
+ *
+ * Copy the data from the buffer for the length specified to the IO reqeust SGL
+ * specified data region. enum sci_status
+ */
+static enum sci_status
+sci_stp_request_pio_data_in_copy_data_buffer(struct isci_stp_request *stp_req,
+						  u8 *data_buf, u32 len)
+{
+	struct isci_request *ireq;
+	u8 *src_addr;
+	int copy_len;
+	struct sas_task *task;
+	struct scatterlist *sg;
+	void *kaddr;
+	int total_len = len;
+
+	ireq = to_ireq(stp_req);
+	task = isci_request_access_task(ireq);
+	src_addr = data_buf;
+
+	if (task->num_scatter > 0) {
+		sg = task->scatter;
+
+		while (total_len > 0) {
+			struct page *page = sg_page(sg);
+
+			copy_len = min_t(int, total_len, sg_dma_len(sg));
+			kaddr = kmap_atomic(page, KM_IRQ0);
+			memcpy(kaddr + sg->offset, src_addr, copy_len);
+			kunmap_atomic(kaddr, KM_IRQ0);
+			total_len -= copy_len;
+			src_addr += copy_len;
+			sg = sg_next(sg);
+		}
+	} else {
+		BUG_ON(task->total_xfer_len < total_len);
+		memcpy(task->scatter, src_addr, total_len);
+	}
+
+	return SCI_SUCCESS;
+}
+
+/**
+ *
+ * @sci_req: The PIO DATA IN request that is to receive the data.
+ * @data_buffer: The buffer to copy from.
+ *
+ * Copy the data buffer to the io request data region. enum sci_status
+ */
+static enum sci_status sci_stp_request_pio_data_in_copy_data(
+	struct isci_stp_request *stp_req,
+	u8 *data_buffer)
+{
+	enum sci_status status;
+
+	/*
+	 * If there is less than 1K remaining in the transfer request
+	 * copy just the data for the transfer */
+	if (stp_req->pio_len < SCU_MAX_FRAME_BUFFER_SIZE) {
+		status = sci_stp_request_pio_data_in_copy_data_buffer(
+			stp_req, data_buffer, stp_req->pio_len);
+
+		if (status == SCI_SUCCESS)
+			stp_req->pio_len = 0;
+	} else {
+		/* We are transfering the whole frame so copy */
+		status = sci_stp_request_pio_data_in_copy_data_buffer(
+			stp_req, data_buffer, SCU_MAX_FRAME_BUFFER_SIZE);
+
+		if (status == SCI_SUCCESS)
+			stp_req->pio_len -= SCU_MAX_FRAME_BUFFER_SIZE;
+	}
+
+	return status;
+}
+
+static enum sci_status
+stp_request_pio_await_h2d_completion_tc_event(struct isci_request *ireq,
+					      u32 completion_code)
+{
+	enum sci_status status = SCI_SUCCESS;
+
+	switch (SCU_GET_COMPLETION_TL_STATUS(completion_code)) {
+	case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_GOOD):
+		ireq->scu_status = SCU_TASK_DONE_GOOD;
+		ireq->sci_status = SCI_SUCCESS;
+		sci_change_state(&ireq->sm, SCI_REQ_STP_PIO_WAIT_FRAME);
+		break;
+
+	default:
+		/* All other completion status cause the IO to be
+		 * complete.  If a NAK was received, then it is up to
+		 * the user to retry the request.
+		 */
+		ireq->scu_status = SCU_NORMALIZE_COMPLETION_STATUS(completion_code);
+		ireq->sci_status = SCI_FAILURE_CONTROLLER_SPECIFIC_IO_ERR;
+		sci_change_state(&ireq->sm, SCI_REQ_COMPLETED);
+		break;
+	}
+
+	return status;
+}
+
+static enum sci_status
+pio_data_out_tx_done_tc_event(struct isci_request *ireq,
+			      u32 completion_code)
+{
+	enum sci_status status = SCI_SUCCESS;
+	bool all_frames_transferred = false;
+	struct isci_stp_request *stp_req = &ireq->stp.req;
+
+	switch (SCU_GET_COMPLETION_TL_STATUS(completion_code)) {
+	case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_GOOD):
+		/* Transmit data */
+		if (stp_req->pio_len != 0) {
+			status = sci_stp_request_pio_data_out_transmit_data(ireq);
+			if (status == SCI_SUCCESS) {
+				if (stp_req->pio_len == 0)
+					all_frames_transferred = true;
+			}
+		} else if (stp_req->pio_len == 0) {
+			/*
+			 * this will happen if the all data is written at the
+			 * first time after the pio setup fis is received
+			 */
+			all_frames_transferred  = true;
+		}
+
+		/* all data transferred. */
+		if (all_frames_transferred) {
+			/*
+			 * Change the state to SCI_REQ_STP_PIO_DATA_IN
+			 * and wait for PIO_SETUP fis / or D2H REg fis. */
+			sci_change_state(&ireq->sm, SCI_REQ_STP_PIO_WAIT_FRAME);
+		}
+		break;
+
+	default:
+		/*
+		 * All other completion status cause the IO to be complete.
+		 * If a NAK was received, then it is up to the user to retry
+		 * the request.
+		 */
+		ireq->scu_status = SCU_NORMALIZE_COMPLETION_STATUS(completion_code);
+		ireq->sci_status = SCI_FAILURE_CONTROLLER_SPECIFIC_IO_ERR;
+		sci_change_state(&ireq->sm, SCI_REQ_COMPLETED);
+		break;
+	}
+
+	return status;
+}
+
+static enum sci_status sci_stp_request_udma_general_frame_handler(struct isci_request *ireq,
+								       u32 frame_index)
+{
+	struct isci_host *ihost = ireq->owning_controller;
+	struct dev_to_host_fis *frame_header;
+	enum sci_status status;
+	u32 *frame_buffer;
+
+	status = sci_unsolicited_frame_control_get_header(&ihost->uf_control,
+							       frame_index,
+							       (void **)&frame_header);
+
+	if ((status == SCI_SUCCESS) &&
+	    (frame_header->fis_type == FIS_REGD2H)) {
+		sci_unsolicited_frame_control_get_buffer(&ihost->uf_control,
+							      frame_index,
+							      (void **)&frame_buffer);
+
+		sci_controller_copy_sata_response(&ireq->stp.rsp,
+						       frame_header,
+						       frame_buffer);
+	}
+
+	sci_controller_release_frame(ihost, frame_index);
+
+	return status;
+}
+
+enum sci_status
+sci_io_request_frame_handler(struct isci_request *ireq,
+				  u32 frame_index)
+{
+	struct isci_host *ihost = ireq->owning_controller;
+	struct isci_stp_request *stp_req = &ireq->stp.req;
+	enum sci_base_request_states state;
+	enum sci_status status;
+	ssize_t word_cnt;
+
+	state = ireq->sm.current_state_id;
+	switch (state)  {
+	case SCI_REQ_STARTED: {
+		struct ssp_frame_hdr ssp_hdr;
+		void *frame_header;
+
+		sci_unsolicited_frame_control_get_header(&ihost->uf_control,
+							      frame_index,
+							      &frame_header);
+
+		word_cnt = sizeof(struct ssp_frame_hdr) / sizeof(u32);
+		sci_swab32_cpy(&ssp_hdr, frame_header, word_cnt);
+
+		if (ssp_hdr.frame_type == SSP_RESPONSE) {
+			struct ssp_response_iu *resp_iu;
+			ssize_t word_cnt = SSP_RESP_IU_MAX_SIZE / sizeof(u32);
+
+			sci_unsolicited_frame_control_get_buffer(&ihost->uf_control,
+								      frame_index,
+								      (void **)&resp_iu);
+
+			sci_swab32_cpy(&ireq->ssp.rsp, resp_iu, word_cnt);
+
+			resp_iu = &ireq->ssp.rsp;
+
+			if (resp_iu->datapres == 0x01 ||
+			    resp_iu->datapres == 0x02) {
+				ireq->scu_status = SCU_TASK_DONE_CHECK_RESPONSE;
+				ireq->sci_status = SCI_FAILURE_CONTROLLER_SPECIFIC_IO_ERR;
+			} else {
+				ireq->scu_status = SCU_TASK_DONE_GOOD;
+				ireq->sci_status = SCI_SUCCESS;
+			}
+		} else {
+			/* not a response frame, why did it get forwarded? */
+			dev_err(&ihost->pdev->dev,
+				"%s: SCIC IO Request 0x%p received unexpected "
+				"frame %d type 0x%02x\n", __func__, ireq,
+				frame_index, ssp_hdr.frame_type);
+		}
+
+		/*
+		 * In any case we are done with this frame buffer return it to
+		 * the controller
+		 */
+		sci_controller_release_frame(ihost, frame_index);
+
+		return SCI_SUCCESS;
+	}
+
+	case SCI_REQ_TASK_WAIT_TC_RESP:
+		sci_io_request_copy_response(ireq);
+		sci_change_state(&ireq->sm, SCI_REQ_COMPLETED);
+		sci_controller_release_frame(ihost, frame_index);
+		return SCI_SUCCESS;
+
+	case SCI_REQ_SMP_WAIT_RESP: {
+		struct smp_resp *rsp_hdr = &ireq->smp.rsp;
+		void *frame_header;
+
+		sci_unsolicited_frame_control_get_header(&ihost->uf_control,
+							      frame_index,
+							      &frame_header);
+
+		/* byte swap the header. */
+		word_cnt = SMP_RESP_HDR_SZ / sizeof(u32);
+		sci_swab32_cpy(rsp_hdr, frame_header, word_cnt);
+
+		if (rsp_hdr->frame_type == SMP_RESPONSE) {
+			void *smp_resp;
+
+			sci_unsolicited_frame_control_get_buffer(&ihost->uf_control,
+								      frame_index,
+								      &smp_resp);
+
+			word_cnt = (sizeof(struct smp_resp) - SMP_RESP_HDR_SZ) /
+				sizeof(u32);
+
+			sci_swab32_cpy(((u8 *) rsp_hdr) + SMP_RESP_HDR_SZ,
+				       smp_resp, word_cnt);
+
+			ireq->scu_status = SCU_TASK_DONE_GOOD;
+			ireq->sci_status = SCI_SUCCESS;
+			sci_change_state(&ireq->sm, SCI_REQ_SMP_WAIT_TC_COMP);
+		} else {
+			/*
+			 * This was not a response frame why did it get
+			 * forwarded?
+			 */
+			dev_err(&ihost->pdev->dev,
+				"%s: SCIC SMP Request 0x%p received unexpected "
+				"frame %d type 0x%02x\n",
+				__func__,
+				ireq,
+				frame_index,
+				rsp_hdr->frame_type);
+
+			ireq->scu_status = SCU_TASK_DONE_SMP_FRM_TYPE_ERR;
+			ireq->sci_status = SCI_FAILURE_CONTROLLER_SPECIFIC_IO_ERR;
+			sci_change_state(&ireq->sm, SCI_REQ_COMPLETED);
+		}
+
+		sci_controller_release_frame(ihost, frame_index);
+
+		return SCI_SUCCESS;
+	}
+
+	case SCI_REQ_STP_UDMA_WAIT_TC_COMP:
+		return sci_stp_request_udma_general_frame_handler(ireq,
+								       frame_index);
+
+	case SCI_REQ_STP_UDMA_WAIT_D2H:
+		/* Use the general frame handler to copy the resposne data */
+		status = sci_stp_request_udma_general_frame_handler(ireq, frame_index);
+
+		if (status != SCI_SUCCESS)
+			return status;
+
+		ireq->scu_status = SCU_TASK_DONE_CHECK_RESPONSE;
+		ireq->sci_status = SCI_FAILURE_IO_RESPONSE_VALID;
+		sci_change_state(&ireq->sm, SCI_REQ_COMPLETED);
+		return SCI_SUCCESS;
+
+	case SCI_REQ_STP_NON_DATA_WAIT_D2H: {
+		struct dev_to_host_fis *frame_header;
+		u32 *frame_buffer;
+
+		status = sci_unsolicited_frame_control_get_header(&ihost->uf_control,
+								       frame_index,
+								       (void **)&frame_header);
+
+		if (status != SCI_SUCCESS) {
+			dev_err(&ihost->pdev->dev,
+				"%s: SCIC IO Request 0x%p could not get frame "
+				"header for frame index %d, status %x\n",
+				__func__,
+				stp_req,
+				frame_index,
+				status);
+
+			return status;
+		}
+
+		switch (frame_header->fis_type) {
+		case FIS_REGD2H:
+			sci_unsolicited_frame_control_get_buffer(&ihost->uf_control,
+								      frame_index,
+								      (void **)&frame_buffer);
+
+			sci_controller_copy_sata_response(&ireq->stp.rsp,
+							       frame_header,
+							       frame_buffer);
+
+			/* The command has completed with error */
+			ireq->scu_status = SCU_TASK_DONE_CHECK_RESPONSE;
+			ireq->sci_status = SCI_FAILURE_IO_RESPONSE_VALID;
+			break;
+
+		default:
+			dev_warn(&ihost->pdev->dev,
+				 "%s: IO Request:0x%p Frame Id:%d protocol "
+				  "violation occurred\n", __func__, stp_req,
+				  frame_index);
+
+			ireq->scu_status = SCU_TASK_DONE_UNEXP_FIS;
+			ireq->sci_status = SCI_FAILURE_PROTOCOL_VIOLATION;
+			break;
+		}
+
+		sci_change_state(&ireq->sm, SCI_REQ_COMPLETED);
+
+		/* Frame has been decoded return it to the controller */
+		sci_controller_release_frame(ihost, frame_index);
+
+		return status;
+	}
+
+	case SCI_REQ_STP_PIO_WAIT_FRAME: {
+		struct sas_task *task = isci_request_access_task(ireq);
+		struct dev_to_host_fis *frame_header;
+		u32 *frame_buffer;
+
+		status = sci_unsolicited_frame_control_get_header(&ihost->uf_control,
+								       frame_index,
+								       (void **)&frame_header);
+
+		if (status != SCI_SUCCESS) {
+			dev_err(&ihost->pdev->dev,
+				"%s: SCIC IO Request 0x%p could not get frame "
+				"header for frame index %d, status %x\n",
+				__func__, stp_req, frame_index, status);
+			return status;
+		}
+
+		switch (frame_header->fis_type) {
+		case FIS_PIO_SETUP:
+			/* Get from the frame buffer the PIO Setup Data */
+			sci_unsolicited_frame_control_get_buffer(&ihost->uf_control,
+								      frame_index,
+								      (void **)&frame_buffer);
+
+			/* Get the data from the PIO Setup The SCU Hardware
+			 * returns first word in the frame_header and the rest
+			 * of the data is in the frame buffer so we need to
+			 * back up one dword
+			 */
+
+			/* transfer_count: first 16bits in the 4th dword */
+			stp_req->pio_len = frame_buffer[3] & 0xffff;
+
+			/* status: 4th byte in the 3rd dword */
+			stp_req->status = (frame_buffer[2] >> 24) & 0xff;
+
+			sci_controller_copy_sata_response(&ireq->stp.rsp,
+							       frame_header,
+							       frame_buffer);
+
+			ireq->stp.rsp.status = stp_req->status;
+
+			/* The next state is dependent on whether the
+			 * request was PIO Data-in or Data out
+			 */
+			if (task->data_dir == DMA_FROM_DEVICE) {
+				sci_change_state(&ireq->sm, SCI_REQ_STP_PIO_DATA_IN);
+			} else if (task->data_dir == DMA_TO_DEVICE) {
+				/* Transmit data */
+				status = sci_stp_request_pio_data_out_transmit_data(ireq);
+				if (status != SCI_SUCCESS)
+					break;
+				sci_change_state(&ireq->sm, SCI_REQ_STP_PIO_DATA_OUT);
+			}
+			break;
+
+		case FIS_SETDEVBITS:
+			sci_change_state(&ireq->sm, SCI_REQ_STP_PIO_WAIT_FRAME);
+			break;
+
+		case FIS_REGD2H:
+			if (frame_header->status & ATA_BUSY) {
+				/*
+				 * Now why is the drive sending a D2H Register
+				 * FIS when it is still busy?  Do nothing since
+				 * we are still in the right state.
+				 */
+				dev_dbg(&ihost->pdev->dev,
+					"%s: SCIC PIO Request 0x%p received "
+					"D2H Register FIS with BSY status "
+					"0x%x\n",
+					__func__,
+					stp_req,
+					frame_header->status);
+				break;
+			}
+
+			sci_unsolicited_frame_control_get_buffer(&ihost->uf_control,
+								      frame_index,
+								      (void **)&frame_buffer);
+
+			sci_controller_copy_sata_response(&ireq->stp.req,
+							       frame_header,
+							       frame_buffer);
+
+			ireq->scu_status = SCU_TASK_DONE_CHECK_RESPONSE;
+			ireq->sci_status = SCI_FAILURE_IO_RESPONSE_VALID;
+			sci_change_state(&ireq->sm, SCI_REQ_COMPLETED);
+			break;
+
+		default:
+			/* FIXME: what do we do here? */
+			break;
+		}
+
+		/* Frame is decoded return it to the controller */
+		sci_controller_release_frame(ihost, frame_index);
+
+		return status;
+	}
+
+	case SCI_REQ_STP_PIO_DATA_IN: {
+		struct dev_to_host_fis *frame_header;
+		struct sata_fis_data *frame_buffer;
+
+		status = sci_unsolicited_frame_control_get_header(&ihost->uf_control,
+								       frame_index,
+								       (void **)&frame_header);
+
+		if (status != SCI_SUCCESS) {
+			dev_err(&ihost->pdev->dev,
+				"%s: SCIC IO Request 0x%p could not get frame "
+				"header for frame index %d, status %x\n",
+				__func__,
+				stp_req,
+				frame_index,
+				status);
+			return status;
+		}
+
+		if (frame_header->fis_type != FIS_DATA) {
+			dev_err(&ihost->pdev->dev,
+				"%s: SCIC PIO Request 0x%p received frame %d "
+				"with fis type 0x%02x when expecting a data "
+				"fis.\n",
+				__func__,
+				stp_req,
+				frame_index,
+				frame_header->fis_type);
+
+			ireq->scu_status = SCU_TASK_DONE_GOOD;
+			ireq->sci_status = SCI_FAILURE_IO_REQUIRES_SCSI_ABORT;
+			sci_change_state(&ireq->sm, SCI_REQ_COMPLETED);
+
+			/* Frame is decoded return it to the controller */
+			sci_controller_release_frame(ihost, frame_index);
+			return status;
+		}
+
+		if (stp_req->sgl.index < 0) {
+			ireq->saved_rx_frame_index = frame_index;
+			stp_req->pio_len = 0;
+		} else {
+			sci_unsolicited_frame_control_get_buffer(&ihost->uf_control,
+								      frame_index,
+								      (void **)&frame_buffer);
+
+			status = sci_stp_request_pio_data_in_copy_data(stp_req,
+									    (u8 *)frame_buffer);
+
+			/* Frame is decoded return it to the controller */
+			sci_controller_release_frame(ihost, frame_index);
+		}
+
+		/* Check for the end of the transfer, are there more
+		 * bytes remaining for this data transfer
+		 */
+		if (status != SCI_SUCCESS || stp_req->pio_len != 0)
+			return status;
+
+		if ((stp_req->status & ATA_BUSY) == 0) {
+			ireq->scu_status = SCU_TASK_DONE_CHECK_RESPONSE;
+			ireq->sci_status = SCI_FAILURE_IO_RESPONSE_VALID;
+			sci_change_state(&ireq->sm, SCI_REQ_COMPLETED);
+		} else {
+			sci_change_state(&ireq->sm, SCI_REQ_STP_PIO_WAIT_FRAME);
+		}
+		return status;
+	}
+
+	case SCI_REQ_STP_SOFT_RESET_WAIT_D2H: {
+		struct dev_to_host_fis *frame_header;
+		u32 *frame_buffer;
+
+		status = sci_unsolicited_frame_control_get_header(&ihost->uf_control,
+								       frame_index,
+								       (void **)&frame_header);
+		if (status != SCI_SUCCESS) {
+			dev_err(&ihost->pdev->dev,
+				"%s: SCIC IO Request 0x%p could not get frame "
+				"header for frame index %d, status %x\n",
+				__func__,
+				stp_req,
+				frame_index,
+				status);
+			return status;
+		}
+
+		switch (frame_header->fis_type) {
+		case FIS_REGD2H:
+			sci_unsolicited_frame_control_get_buffer(&ihost->uf_control,
+								      frame_index,
+								      (void **)&frame_buffer);
+
+			sci_controller_copy_sata_response(&ireq->stp.rsp,
+							       frame_header,
+							       frame_buffer);
+
+			/* The command has completed with error */
+			ireq->scu_status = SCU_TASK_DONE_CHECK_RESPONSE;
+			ireq->sci_status = SCI_FAILURE_IO_RESPONSE_VALID;
+			break;
+
+		default:
+			dev_warn(&ihost->pdev->dev,
+				 "%s: IO Request:0x%p Frame Id:%d protocol "
+				 "violation occurred\n",
+				 __func__,
+				 stp_req,
+				 frame_index);
+
+			ireq->scu_status = SCU_TASK_DONE_UNEXP_FIS;
+			ireq->sci_status = SCI_FAILURE_PROTOCOL_VIOLATION;
+			break;
+		}
+
+		sci_change_state(&ireq->sm, SCI_REQ_COMPLETED);
+
+		/* Frame has been decoded return it to the controller */
+		sci_controller_release_frame(ihost, frame_index);
+
+		return status;
+	}
+	case SCI_REQ_ABORTING:
+		/*
+		 * TODO: Is it even possible to get an unsolicited frame in the
+		 * aborting state?
+		 */
+		sci_controller_release_frame(ihost, frame_index);
+		return SCI_SUCCESS;
+
+	default:
+		dev_warn(&ihost->pdev->dev,
+			 "%s: SCIC IO Request given unexpected frame %x while "
+			 "in state %d\n",
+			 __func__,
+			 frame_index,
+			 state);
+
+		sci_controller_release_frame(ihost, frame_index);
+		return SCI_FAILURE_INVALID_STATE;
+	}
+}
+
+static enum sci_status stp_request_udma_await_tc_event(struct isci_request *ireq,
+						       u32 completion_code)
+{
+	enum sci_status status = SCI_SUCCESS;
+
+	switch (SCU_GET_COMPLETION_TL_STATUS(completion_code)) {
+	case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_GOOD):
+		ireq->scu_status = SCU_TASK_DONE_GOOD;
+		ireq->sci_status = SCI_SUCCESS;
+		sci_change_state(&ireq->sm, SCI_REQ_COMPLETED);
+		break;
+	case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_UNEXP_FIS):
+	case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_REG_ERR):
+		/* We must check ther response buffer to see if the D2H
+		 * Register FIS was received before we got the TC
+		 * completion.
+		 */
+		if (ireq->stp.rsp.fis_type == FIS_REGD2H) {
+			sci_remote_device_suspend(ireq->target_device,
+				SCU_EVENT_SPECIFIC(SCU_NORMALIZE_COMPLETION_STATUS(completion_code)));
+
+			ireq->scu_status = SCU_TASK_DONE_CHECK_RESPONSE;
+			ireq->sci_status = SCI_FAILURE_IO_RESPONSE_VALID;
+			sci_change_state(&ireq->sm, SCI_REQ_COMPLETED);
+		} else {
+			/* If we have an error completion status for the
+			 * TC then we can expect a D2H register FIS from
+			 * the device so we must change state to wait
+			 * for it
+			 */
+			sci_change_state(&ireq->sm, SCI_REQ_STP_UDMA_WAIT_D2H);
+		}
+		break;
+
+	/* TODO Check to see if any of these completion status need to
+	 * wait for the device to host register fis.
+	 */
+	/* TODO We can retry the command for SCU_TASK_DONE_CMD_LL_R_ERR
+	 * - this comes only for B0
+	 */
+	case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_INV_FIS_LEN):
+	case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_MAX_PLD_ERR):
+	case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_LL_R_ERR):
+	case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_CMD_LL_R_ERR):
+	case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_CRC_ERR):
+		sci_remote_device_suspend(ireq->target_device,
+			SCU_EVENT_SPECIFIC(SCU_NORMALIZE_COMPLETION_STATUS(completion_code)));
+	/* Fall through to the default case */
+	default:
+		/* All other completion status cause the IO to be complete. */
+		ireq->scu_status = SCU_NORMALIZE_COMPLETION_STATUS(completion_code);
+		ireq->sci_status = SCI_FAILURE_CONTROLLER_SPECIFIC_IO_ERR;
+		sci_change_state(&ireq->sm, SCI_REQ_COMPLETED);
+		break;
+	}
+
+	return status;
+}
+
+static enum sci_status
+stp_request_soft_reset_await_h2d_asserted_tc_event(struct isci_request *ireq,
+						   u32 completion_code)
+{
+	switch (SCU_GET_COMPLETION_TL_STATUS(completion_code)) {
+	case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_GOOD):
+		ireq->scu_status = SCU_TASK_DONE_GOOD;
+		ireq->sci_status = SCI_SUCCESS;
+		sci_change_state(&ireq->sm, SCI_REQ_STP_SOFT_RESET_WAIT_H2D_DIAG);
+		break;
+
+	default:
+		/*
+		 * All other completion status cause the IO to be complete.
+		 * If a NAK was received, then it is up to the user to retry
+		 * the request.
+		 */
+		ireq->scu_status = SCU_NORMALIZE_COMPLETION_STATUS(completion_code);
+		ireq->sci_status = SCI_FAILURE_CONTROLLER_SPECIFIC_IO_ERR;
+		sci_change_state(&ireq->sm, SCI_REQ_COMPLETED);
+		break;
+	}
+
+	return SCI_SUCCESS;
+}
+
+static enum sci_status
+stp_request_soft_reset_await_h2d_diagnostic_tc_event(struct isci_request *ireq,
+						     u32 completion_code)
+{
+	switch (SCU_GET_COMPLETION_TL_STATUS(completion_code)) {
+	case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_GOOD):
+		ireq->scu_status = SCU_TASK_DONE_GOOD;
+		ireq->sci_status = SCI_SUCCESS;
+		sci_change_state(&ireq->sm, SCI_REQ_STP_SOFT_RESET_WAIT_D2H);
+		break;
+
+	default:
+		/* All other completion status cause the IO to be complete.  If
+		 * a NAK was received, then it is up to the user to retry the
+		 * request.
+		 */
+		ireq->scu_status = SCU_NORMALIZE_COMPLETION_STATUS(completion_code);
+		ireq->sci_status = SCI_FAILURE_CONTROLLER_SPECIFIC_IO_ERR;
+		sci_change_state(&ireq->sm, SCI_REQ_COMPLETED);
+		break;
+	}
+
+	return SCI_SUCCESS;
+}
+
+enum sci_status
+sci_io_request_tc_completion(struct isci_request *ireq,
+				  u32 completion_code)
+{
+	enum sci_base_request_states state;
+	struct isci_host *ihost = ireq->owning_controller;
+
+	state = ireq->sm.current_state_id;
+
+	switch (state) {
+	case SCI_REQ_STARTED:
+		return request_started_state_tc_event(ireq, completion_code);
+
+	case SCI_REQ_TASK_WAIT_TC_COMP:
+		return ssp_task_request_await_tc_event(ireq,
+						       completion_code);
+
+	case SCI_REQ_SMP_WAIT_RESP:
+		return smp_request_await_response_tc_event(ireq,
+							   completion_code);
+
+	case SCI_REQ_SMP_WAIT_TC_COMP:
+		return smp_request_await_tc_event(ireq, completion_code);
+
+	case SCI_REQ_STP_UDMA_WAIT_TC_COMP:
+		return stp_request_udma_await_tc_event(ireq,
+						       completion_code);
+
+	case SCI_REQ_STP_NON_DATA_WAIT_H2D:
+		return stp_request_non_data_await_h2d_tc_event(ireq,
+							       completion_code);
+
+	case SCI_REQ_STP_PIO_WAIT_H2D:
+		return stp_request_pio_await_h2d_completion_tc_event(ireq,
+								     completion_code);
+
+	case SCI_REQ_STP_PIO_DATA_OUT:
+		return pio_data_out_tx_done_tc_event(ireq, completion_code);
+
+	case SCI_REQ_STP_SOFT_RESET_WAIT_H2D_ASSERTED:
+		return stp_request_soft_reset_await_h2d_asserted_tc_event(ireq,
+									  completion_code);
+
+	case SCI_REQ_STP_SOFT_RESET_WAIT_H2D_DIAG:
+		return stp_request_soft_reset_await_h2d_diagnostic_tc_event(ireq,
+									    completion_code);
+
+	case SCI_REQ_ABORTING:
+		return request_aborting_state_tc_event(ireq,
+						       completion_code);
+
+	default:
+		dev_warn(&ihost->pdev->dev,
+			 "%s: SCIC IO Request given task completion "
+			 "notification %x while in wrong state %d\n",
+			 __func__,
+			 completion_code,
+			 state);
+		return SCI_FAILURE_INVALID_STATE;
+	}
+}
+
+/**
+ * isci_request_process_response_iu() - This function sets the status and
+ *    response iu, in the task struct, from the request object for the upper
+ *    layer driver.
+ * @sas_task: This parameter is the task struct from the upper layer driver.
+ * @resp_iu: This parameter points to the response iu of the completed request.
+ * @dev: This parameter specifies the linux device struct.
+ *
+ * none.
+ */
+static void isci_request_process_response_iu(
+	struct sas_task *task,
+	struct ssp_response_iu *resp_iu,
+	struct device *dev)
+{
+	dev_dbg(dev,
+		"%s: resp_iu = %p "
+		"resp_iu->status = 0x%x,\nresp_iu->datapres = %d "
+		"resp_iu->response_data_len = %x, "
+		"resp_iu->sense_data_len = %x\nrepsonse data: ",
+		__func__,
+		resp_iu,
+		resp_iu->status,
+		resp_iu->datapres,
+		resp_iu->response_data_len,
+		resp_iu->sense_data_len);
+
+	task->task_status.stat = resp_iu->status;
+
+	/* libsas updates the task status fields based on the response iu. */
+	sas_ssp_task_response(dev, task, resp_iu);
+}
+
+/**
+ * isci_request_set_open_reject_status() - This function prepares the I/O
+ *    completion for OPEN_REJECT conditions.
+ * @request: This parameter is the completed isci_request object.
+ * @response_ptr: This parameter specifies the service response for the I/O.
+ * @status_ptr: This parameter specifies the exec status for the I/O.
+ * @complete_to_host_ptr: This parameter specifies the action to be taken by
+ *    the LLDD with respect to completing this request or forcing an abort
+ *    condition on the I/O.
+ * @open_rej_reason: This parameter specifies the encoded reason for the
+ *    abandon-class reject.
+ *
+ * none.
+ */
+static void isci_request_set_open_reject_status(
+	struct isci_request *request,
+	struct sas_task *task,
+	enum service_response *response_ptr,
+	enum exec_status *status_ptr,
+	enum isci_completion_selection *complete_to_host_ptr,
+	enum sas_open_rej_reason open_rej_reason)
+{
+	/* Task in the target is done. */
+	set_bit(IREQ_COMPLETE_IN_TARGET, &request->flags);
+	*response_ptr                     = SAS_TASK_UNDELIVERED;
+	*status_ptr                       = SAS_OPEN_REJECT;
+	*complete_to_host_ptr             = isci_perform_normal_io_completion;
+	task->task_status.open_rej_reason = open_rej_reason;
+}
+
+/**
+ * isci_request_handle_controller_specific_errors() - This function decodes
+ *    controller-specific I/O completion error conditions.
+ * @request: This parameter is the completed isci_request object.
+ * @response_ptr: This parameter specifies the service response for the I/O.
+ * @status_ptr: This parameter specifies the exec status for the I/O.
+ * @complete_to_host_ptr: This parameter specifies the action to be taken by
+ *    the LLDD with respect to completing this request or forcing an abort
+ *    condition on the I/O.
+ *
+ * none.
+ */
+static void isci_request_handle_controller_specific_errors(
+	struct isci_remote_device *idev,
+	struct isci_request *request,
+	struct sas_task *task,
+	enum service_response *response_ptr,
+	enum exec_status *status_ptr,
+	enum isci_completion_selection *complete_to_host_ptr)
+{
+	unsigned int cstatus;
+
+	cstatus = request->scu_status;
+
+	dev_dbg(&request->isci_host->pdev->dev,
+		"%s: %p SCI_FAILURE_CONTROLLER_SPECIFIC_IO_ERR "
+		"- controller status = 0x%x\n",
+		__func__, request, cstatus);
+
+	/* Decode the controller-specific errors; most
+	 * important is to recognize those conditions in which
+	 * the target may still have a task outstanding that
+	 * must be aborted.
+	 *
+	 * Note that there are SCU completion codes being
+	 * named in the decode below for which SCIC has already
+	 * done work to handle them in a way other than as
+	 * a controller-specific completion code; these are left
+	 * in the decode below for completeness sake.
+	 */
+	switch (cstatus) {
+	case SCU_TASK_DONE_DMASETUP_DIRERR:
+	/* Also SCU_TASK_DONE_SMP_FRM_TYPE_ERR: */
+	case SCU_TASK_DONE_XFERCNT_ERR:
+		/* Also SCU_TASK_DONE_SMP_UFI_ERR: */
+		if (task->task_proto == SAS_PROTOCOL_SMP) {
+			/* SCU_TASK_DONE_SMP_UFI_ERR == Task Done. */
+			*response_ptr = SAS_TASK_COMPLETE;
+
+			/* See if the device has been/is being stopped. Note
+			 * that we ignore the quiesce state, since we are
+			 * concerned about the actual device state.
+			 */
+			if (!idev)
+				*status_ptr = SAS_DEVICE_UNKNOWN;
+			else
+				*status_ptr = SAS_ABORTED_TASK;
+
+			set_bit(IREQ_COMPLETE_IN_TARGET, &request->flags);
+
+			*complete_to_host_ptr =
+				isci_perform_normal_io_completion;
+		} else {
+			/* Task in the target is not done. */
+			*response_ptr = SAS_TASK_UNDELIVERED;
+
+			if (!idev)
+				*status_ptr = SAS_DEVICE_UNKNOWN;
+			else
+				*status_ptr = SAM_STAT_TASK_ABORTED;
+
+			clear_bit(IREQ_COMPLETE_IN_TARGET, &request->flags);
+
+			*complete_to_host_ptr =
+				isci_perform_error_io_completion;
+		}
+
+		break;
+
+	case SCU_TASK_DONE_CRC_ERR:
+	case SCU_TASK_DONE_NAK_CMD_ERR:
+	case SCU_TASK_DONE_EXCESS_DATA:
+	case SCU_TASK_DONE_UNEXP_FIS:
+	/* Also SCU_TASK_DONE_UNEXP_RESP: */
+	case SCU_TASK_DONE_VIIT_ENTRY_NV:       /* TODO - conditions? */
+	case SCU_TASK_DONE_IIT_ENTRY_NV:        /* TODO - conditions? */
+	case SCU_TASK_DONE_RNCNV_OUTBOUND:      /* TODO - conditions? */
+		/* These are conditions in which the target
+		 * has completed the task, so that no cleanup
+		 * is necessary.
+		 */
+		*response_ptr = SAS_TASK_COMPLETE;
+
+		/* See if the device has been/is being stopped. Note
+		 * that we ignore the quiesce state, since we are
+		 * concerned about the actual device state.
+		 */
+		if (!idev)
+			*status_ptr = SAS_DEVICE_UNKNOWN;
+		else
+			*status_ptr = SAS_ABORTED_TASK;
+
+		set_bit(IREQ_COMPLETE_IN_TARGET, &request->flags);
+
+		*complete_to_host_ptr = isci_perform_normal_io_completion;
+		break;
+
+
+	/* Note that the only open reject completion codes seen here will be
+	 * abandon-class codes; all others are automatically retried in the SCU.
+	 */
+	case SCU_TASK_OPEN_REJECT_WRONG_DESTINATION:
+
+		isci_request_set_open_reject_status(
+			request, task, response_ptr, status_ptr,
+			complete_to_host_ptr, SAS_OREJ_WRONG_DEST);
+		break;
+
+	case SCU_TASK_OPEN_REJECT_ZONE_VIOLATION:
+
+		/* Note - the return of AB0 will change when
+		 * libsas implements detection of zone violations.
+		 */
+		isci_request_set_open_reject_status(
+			request, task, response_ptr, status_ptr,
+			complete_to_host_ptr, SAS_OREJ_RESV_AB0);
+		break;
+
+	case SCU_TASK_OPEN_REJECT_RESERVED_ABANDON_1:
+
+		isci_request_set_open_reject_status(
+			request, task, response_ptr, status_ptr,
+			complete_to_host_ptr, SAS_OREJ_RESV_AB1);
+		break;
+
+	case SCU_TASK_OPEN_REJECT_RESERVED_ABANDON_2:
+
+		isci_request_set_open_reject_status(
+			request, task, response_ptr, status_ptr,
+			complete_to_host_ptr, SAS_OREJ_RESV_AB2);
+		break;
+
+	case SCU_TASK_OPEN_REJECT_RESERVED_ABANDON_3:
+
+		isci_request_set_open_reject_status(
+			request, task, response_ptr, status_ptr,
+			complete_to_host_ptr, SAS_OREJ_RESV_AB3);
+		break;
+
+	case SCU_TASK_OPEN_REJECT_BAD_DESTINATION:
+
+		isci_request_set_open_reject_status(
+			request, task, response_ptr, status_ptr,
+			complete_to_host_ptr, SAS_OREJ_BAD_DEST);
+		break;
+
+	case SCU_TASK_OPEN_REJECT_STP_RESOURCES_BUSY:
+
+		isci_request_set_open_reject_status(
+			request, task, response_ptr, status_ptr,
+			complete_to_host_ptr, SAS_OREJ_STP_NORES);
+		break;
+
+	case SCU_TASK_OPEN_REJECT_PROTOCOL_NOT_SUPPORTED:
+
+		isci_request_set_open_reject_status(
+			request, task, response_ptr, status_ptr,
+			complete_to_host_ptr, SAS_OREJ_EPROTO);
+		break;
+
+	case SCU_TASK_OPEN_REJECT_CONNECTION_RATE_NOT_SUPPORTED:
+
+		isci_request_set_open_reject_status(
+			request, task, response_ptr, status_ptr,
+			complete_to_host_ptr, SAS_OREJ_CONN_RATE);
+		break;
+
+	case SCU_TASK_DONE_LL_R_ERR:
+	/* Also SCU_TASK_DONE_ACK_NAK_TO: */
+	case SCU_TASK_DONE_LL_PERR:
+	case SCU_TASK_DONE_LL_SY_TERM:
+	/* Also SCU_TASK_DONE_NAK_ERR:*/
+	case SCU_TASK_DONE_LL_LF_TERM:
+	/* Also SCU_TASK_DONE_DATA_LEN_ERR: */
+	case SCU_TASK_DONE_LL_ABORT_ERR:
+	case SCU_TASK_DONE_SEQ_INV_TYPE:
+	/* Also SCU_TASK_DONE_UNEXP_XR: */
+	case SCU_TASK_DONE_XR_IU_LEN_ERR:
+	case SCU_TASK_DONE_INV_FIS_LEN:
+	/* Also SCU_TASK_DONE_XR_WD_LEN: */
+	case SCU_TASK_DONE_SDMA_ERR:
+	case SCU_TASK_DONE_OFFSET_ERR:
+	case SCU_TASK_DONE_MAX_PLD_ERR:
+	case SCU_TASK_DONE_LF_ERR:
+	case SCU_TASK_DONE_SMP_RESP_TO_ERR:  /* Escalate to dev reset? */
+	case SCU_TASK_DONE_SMP_LL_RX_ERR:
+	case SCU_TASK_DONE_UNEXP_DATA:
+	case SCU_TASK_DONE_UNEXP_SDBFIS:
+	case SCU_TASK_DONE_REG_ERR:
+	case SCU_TASK_DONE_SDB_ERR:
+	case SCU_TASK_DONE_TASK_ABORT:
+	default:
+		/* Task in the target is not done. */
+		*response_ptr = SAS_TASK_UNDELIVERED;
+		*status_ptr = SAM_STAT_TASK_ABORTED;
+
+		if (task->task_proto == SAS_PROTOCOL_SMP) {
+			set_bit(IREQ_COMPLETE_IN_TARGET, &request->flags);
+
+			*complete_to_host_ptr = isci_perform_normal_io_completion;
+		} else {
+			clear_bit(IREQ_COMPLETE_IN_TARGET, &request->flags);
+
+			*complete_to_host_ptr = isci_perform_error_io_completion;
+		}
+		break;
+	}
+}
+
+/**
+ * isci_task_save_for_upper_layer_completion() - This function saves the
+ *    request for later completion to the upper layer driver.
+ * @host: This parameter is a pointer to the host on which the the request
+ *    should be queued (either as an error or success).
+ * @request: This parameter is the completed request.
+ * @response: This parameter is the response code for the completed task.
+ * @status: This parameter is the status code for the completed task.
+ *
+ * none.
+ */
+static void isci_task_save_for_upper_layer_completion(
+	struct isci_host *host,
+	struct isci_request *request,
+	enum service_response response,
+	enum exec_status status,
+	enum isci_completion_selection task_notification_selection)
+{
+	struct sas_task *task = isci_request_access_task(request);
+
+	task_notification_selection
+		= isci_task_set_completion_status(task, response, status,
+						  task_notification_selection);
+
+	/* Tasks aborted specifically by a call to the lldd_abort_task
+	 * function should not be completed to the host in the regular path.
+	 */
+	switch (task_notification_selection) {
+
+	case isci_perform_normal_io_completion:
+
+		/* Normal notification (task_done) */
+		dev_dbg(&host->pdev->dev,
+			"%s: Normal - task = %p, response=%d (%d), status=%d (%d)\n",
+			__func__,
+			task,
+			task->task_status.resp, response,
+			task->task_status.stat, status);
+		/* Add to the completed list. */
+		list_add(&request->completed_node,
+			 &host->requests_to_complete);
+
+		/* Take the request off the device's pending request list. */
+		list_del_init(&request->dev_node);
+		break;
+
+	case isci_perform_aborted_io_completion:
+		/* No notification to libsas because this request is
+		 * already in the abort path.
+		 */
+		dev_dbg(&host->pdev->dev,
+			 "%s: Aborted - task = %p, response=%d (%d), status=%d (%d)\n",
+			 __func__,
+			 task,
+			 task->task_status.resp, response,
+			 task->task_status.stat, status);
+
+		/* Wake up whatever process was waiting for this
+		 * request to complete.
+		 */
+		WARN_ON(request->io_request_completion == NULL);
+
+		if (request->io_request_completion != NULL) {
+
+			/* Signal whoever is waiting that this
+			* request is complete.
+			*/
+			complete(request->io_request_completion);
+		}
+		break;
+
+	case isci_perform_error_io_completion:
+		/* Use sas_task_abort */
+		dev_dbg(&host->pdev->dev,
+			 "%s: Error - task = %p, response=%d (%d), status=%d (%d)\n",
+			 __func__,
+			 task,
+			 task->task_status.resp, response,
+			 task->task_status.stat, status);
+		/* Add to the aborted list. */
+		list_add(&request->completed_node,
+			 &host->requests_to_errorback);
+		break;
+
+	default:
+		dev_dbg(&host->pdev->dev,
+			 "%s: Unknown - task = %p, response=%d (%d), status=%d (%d)\n",
+			 __func__,
+			 task,
+			 task->task_status.resp, response,
+			 task->task_status.stat, status);
+
+		/* Add to the error to libsas list. */
+		list_add(&request->completed_node,
+			 &host->requests_to_errorback);
+		break;
+	}
+}
+
+static void isci_request_process_stp_response(struct sas_task *task,
+					      void *response_buffer)
+{
+	struct dev_to_host_fis *d2h_reg_fis = response_buffer;
+	struct task_status_struct *ts = &task->task_status;
+	struct ata_task_resp *resp = (void *)&ts->buf[0];
+
+	resp->frame_len = le16_to_cpu(*(__le16 *)(response_buffer + 6));
+	memcpy(&resp->ending_fis[0], response_buffer + 16, 24);
+	ts->buf_valid_size = sizeof(*resp);
+
+	/**
+	 * If the device fault bit is set in the status register, then
+	 * set the sense data and return.
+	 */
+	if (d2h_reg_fis->status & ATA_DF)
+		ts->stat = SAS_PROTO_RESPONSE;
+	else
+		ts->stat = SAM_STAT_GOOD;
+
+	ts->resp = SAS_TASK_COMPLETE;
+}
+
+static void isci_request_io_request_complete(struct isci_host *ihost,
+					     struct isci_request *request,
+					     enum sci_io_status completion_status)
+{
+	struct sas_task *task = isci_request_access_task(request);
+	struct ssp_response_iu *resp_iu;
+	void *resp_buf;
+	unsigned long task_flags;
+	struct isci_remote_device *idev = isci_lookup_device(task->dev);
+	enum service_response response       = SAS_TASK_UNDELIVERED;
+	enum exec_status status         = SAS_ABORTED_TASK;
+	enum isci_request_status request_status;
+	enum isci_completion_selection complete_to_host
+		= isci_perform_normal_io_completion;
+
+	dev_dbg(&ihost->pdev->dev,
+		"%s: request = %p, task = %p,\n"
+		"task->data_dir = %d completion_status = 0x%x\n",
+		__func__,
+		request,
+		task,
+		task->data_dir,
+		completion_status);
+
+	spin_lock(&request->state_lock);
+	request_status = request->status;
+
+	/* Decode the request status.  Note that if the request has been
+	 * aborted by a task management function, we don't care
+	 * what the status is.
+	 */
+	switch (request_status) {
+
+	case aborted:
+		/* "aborted" indicates that the request was aborted by a task
+		 * management function, since once a task management request is
+		 * perfomed by the device, the request only completes because
+		 * of the subsequent driver terminate.
+		 *
+		 * Aborted also means an external thread is explicitly managing
+		 * this request, so that we do not complete it up the stack.
+		 *
+		 * The target is still there (since the TMF was successful).
+		 */
+		set_bit(IREQ_COMPLETE_IN_TARGET, &request->flags);
+		response = SAS_TASK_COMPLETE;
+
+		/* See if the device has been/is being stopped. Note
+		 * that we ignore the quiesce state, since we are
+		 * concerned about the actual device state.
+		 */
+		if (!idev)
+			status = SAS_DEVICE_UNKNOWN;
+		else
+			status = SAS_ABORTED_TASK;
+
+		complete_to_host = isci_perform_aborted_io_completion;
+		/* This was an aborted request. */
+
+		spin_unlock(&request->state_lock);
+		break;
+
+	case aborting:
+		/* aborting means that the task management function tried and
+		 * failed to abort the request. We need to note the request
+		 * as SAS_TASK_UNDELIVERED, so that the scsi mid layer marks the
+		 * target as down.
+		 *
+		 * Aborting also means an external thread is explicitly managing
+		 * this request, so that we do not complete it up the stack.
+		 */
+		set_bit(IREQ_COMPLETE_IN_TARGET, &request->flags);
+		response = SAS_TASK_UNDELIVERED;
+
+		if (!idev)
+			/* The device has been /is being stopped. Note that
+			 * we ignore the quiesce state, since we are
+			 * concerned about the actual device state.
+			 */
+			status = SAS_DEVICE_UNKNOWN;
+		else
+			status = SAS_PHY_DOWN;
+
+		complete_to_host = isci_perform_aborted_io_completion;
+
+		/* This was an aborted request. */
+
+		spin_unlock(&request->state_lock);
+		break;
+
+	case terminating:
+
+		/* This was an terminated request.  This happens when
+		 * the I/O is being terminated because of an action on
+		 * the device (reset, tear down, etc.), and the I/O needs
+		 * to be completed up the stack.
+		 */
+		set_bit(IREQ_COMPLETE_IN_TARGET, &request->flags);
+		response = SAS_TASK_UNDELIVERED;
+
+		/* See if the device has been/is being stopped. Note
+		 * that we ignore the quiesce state, since we are
+		 * concerned about the actual device state.
+		 */
+		if (!idev)
+			status = SAS_DEVICE_UNKNOWN;
+		else
+			status = SAS_ABORTED_TASK;
+
+		complete_to_host = isci_perform_aborted_io_completion;
+
+		/* This was a terminated request. */
+
+		spin_unlock(&request->state_lock);
+		break;
+
+	case dead:
+		/* This was a terminated request that timed-out during the
+		 * termination process.  There is no task to complete to
+		 * libsas.
+		 */
+		complete_to_host = isci_perform_normal_io_completion;
+		spin_unlock(&request->state_lock);
+		break;
+
+	default:
+
+		/* The request is done from an SCU HW perspective. */
+		request->status = completed;
+
+		spin_unlock(&request->state_lock);
+
+		/* This is an active request being completed from the core. */
+		switch (completion_status) {
+
+		case SCI_IO_FAILURE_RESPONSE_VALID:
+			dev_dbg(&ihost->pdev->dev,
+				"%s: SCI_IO_FAILURE_RESPONSE_VALID (%p/%p)\n",
+				__func__,
+				request,
+				task);
+
+			if (sas_protocol_ata(task->task_proto)) {
+				resp_buf = &request->stp.rsp;
+				isci_request_process_stp_response(task,
+								  resp_buf);
+			} else if (SAS_PROTOCOL_SSP == task->task_proto) {
+
+				/* crack the iu response buffer. */
+				resp_iu = &request->ssp.rsp;
+				isci_request_process_response_iu(task, resp_iu,
+								 &ihost->pdev->dev);
+
+			} else if (SAS_PROTOCOL_SMP == task->task_proto) {
+
+				dev_err(&ihost->pdev->dev,
+					"%s: SCI_IO_FAILURE_RESPONSE_VALID: "
+					"SAS_PROTOCOL_SMP protocol\n",
+					__func__);
+
+			} else
+				dev_err(&ihost->pdev->dev,
+					"%s: unknown protocol\n", __func__);
+
+			/* use the task status set in the task struct by the
+			 * isci_request_process_response_iu call.
+			 */
+			set_bit(IREQ_COMPLETE_IN_TARGET, &request->flags);
+			response = task->task_status.resp;
+			status = task->task_status.stat;
+			break;
+
+		case SCI_IO_SUCCESS:
+		case SCI_IO_SUCCESS_IO_DONE_EARLY:
+
+			response = SAS_TASK_COMPLETE;
+			status   = SAM_STAT_GOOD;
+			set_bit(IREQ_COMPLETE_IN_TARGET, &request->flags);
+
+			if (task->task_proto == SAS_PROTOCOL_SMP) {
+				void *rsp = &request->smp.rsp;
+
+				dev_dbg(&ihost->pdev->dev,
+					"%s: SMP protocol completion\n",
+					__func__);
+
+				sg_copy_from_buffer(
+					&task->smp_task.smp_resp, 1,
+					rsp, sizeof(struct smp_resp));
+			} else if (completion_status
+				   == SCI_IO_SUCCESS_IO_DONE_EARLY) {
+
+				/* This was an SSP / STP / SATA transfer.
+				 * There is a possibility that less data than
+				 * the maximum was transferred.
+				 */
+				u32 transferred_length = sci_req_tx_bytes(request);
+
+				task->task_status.residual
+					= task->total_xfer_len - transferred_length;
+
+				/* If there were residual bytes, call this an
+				 * underrun.
+				 */
+				if (task->task_status.residual != 0)
+					status = SAS_DATA_UNDERRUN;
+
+				dev_dbg(&ihost->pdev->dev,
+					"%s: SCI_IO_SUCCESS_IO_DONE_EARLY %d\n",
+					__func__,
+					status);
+
+			} else
+				dev_dbg(&ihost->pdev->dev,
+					"%s: SCI_IO_SUCCESS\n",
+					__func__);
+
+			break;
+
+		case SCI_IO_FAILURE_TERMINATED:
+			dev_dbg(&ihost->pdev->dev,
+				"%s: SCI_IO_FAILURE_TERMINATED (%p/%p)\n",
+				__func__,
+				request,
+				task);
+
+			/* The request was terminated explicitly.  No handling
+			 * is needed in the SCSI error handler path.
+			 */
+			set_bit(IREQ_COMPLETE_IN_TARGET, &request->flags);
+			response = SAS_TASK_UNDELIVERED;
+
+			/* See if the device has been/is being stopped. Note
+			 * that we ignore the quiesce state, since we are
+			 * concerned about the actual device state.
+			 */
+			if (!idev)
+				status = SAS_DEVICE_UNKNOWN;
+			else
+				status = SAS_ABORTED_TASK;
+
+			complete_to_host = isci_perform_normal_io_completion;
+			break;
+
+		case SCI_FAILURE_CONTROLLER_SPECIFIC_IO_ERR:
+
+			isci_request_handle_controller_specific_errors(
+				idev, request, task, &response, &status,
+				&complete_to_host);
+
+			break;
+
+		case SCI_IO_FAILURE_REMOTE_DEVICE_RESET_REQUIRED:
+			/* This is a special case, in that the I/O completion
+			 * is telling us that the device needs a reset.
+			 * In order for the device reset condition to be
+			 * noticed, the I/O has to be handled in the error
+			 * handler.  Set the reset flag and cause the
+			 * SCSI error thread to be scheduled.
+			 */
+			spin_lock_irqsave(&task->task_state_lock, task_flags);
+			task->task_state_flags |= SAS_TASK_NEED_DEV_RESET;
+			spin_unlock_irqrestore(&task->task_state_lock, task_flags);
+
+			/* Fail the I/O. */
+			response = SAS_TASK_UNDELIVERED;
+			status = SAM_STAT_TASK_ABORTED;
+
+			complete_to_host = isci_perform_error_io_completion;
+			clear_bit(IREQ_COMPLETE_IN_TARGET, &request->flags);
+			break;
+
+		case SCI_FAILURE_RETRY_REQUIRED:
+
+			/* Fail the I/O so it can be retried. */
+			response = SAS_TASK_UNDELIVERED;
+			if (!idev)
+				status = SAS_DEVICE_UNKNOWN;
+			else
+				status = SAS_ABORTED_TASK;
+
+			complete_to_host = isci_perform_normal_io_completion;
+			set_bit(IREQ_COMPLETE_IN_TARGET, &request->flags);
+			break;
+
+
+		default:
+			/* Catch any otherwise unhandled error codes here. */
+			dev_dbg(&ihost->pdev->dev,
+				 "%s: invalid completion code: 0x%x - "
+				 "isci_request = %p\n",
+				 __func__, completion_status, request);
+
+			response = SAS_TASK_UNDELIVERED;
+
+			/* See if the device has been/is being stopped. Note
+			 * that we ignore the quiesce state, since we are
+			 * concerned about the actual device state.
+			 */
+			if (!idev)
+				status = SAS_DEVICE_UNKNOWN;
+			else
+				status = SAS_ABORTED_TASK;
+
+			if (SAS_PROTOCOL_SMP == task->task_proto) {
+				set_bit(IREQ_COMPLETE_IN_TARGET, &request->flags);
+				complete_to_host = isci_perform_normal_io_completion;
+			} else {
+				clear_bit(IREQ_COMPLETE_IN_TARGET, &request->flags);
+				complete_to_host = isci_perform_error_io_completion;
+			}
+			break;
+		}
+		break;
+	}
+
+	switch (task->task_proto) {
+	case SAS_PROTOCOL_SSP:
+		if (task->data_dir == DMA_NONE)
+			break;
+		if (task->num_scatter == 0)
+			/* 0 indicates a single dma address */
+			dma_unmap_single(&ihost->pdev->dev,
+					 request->zero_scatter_daddr,
+					 task->total_xfer_len, task->data_dir);
+		else  /* unmap the sgl dma addresses */
+			dma_unmap_sg(&ihost->pdev->dev, task->scatter,
+				     request->num_sg_entries, task->data_dir);
+		break;
+	case SAS_PROTOCOL_SMP: {
+		struct scatterlist *sg = &task->smp_task.smp_req;
+		struct smp_req *smp_req;
+		void *kaddr;
+
+		dma_unmap_sg(&ihost->pdev->dev, sg, 1, DMA_TO_DEVICE);
+
+		/* need to swab it back in case the command buffer is re-used */
+		kaddr = kmap_atomic(sg_page(sg), KM_IRQ0);
+		smp_req = kaddr + sg->offset;
+		sci_swab32_cpy(smp_req, smp_req, sg->length / sizeof(u32));
+		kunmap_atomic(kaddr, KM_IRQ0);
+		break;
+	}
+	default:
+		break;
+	}
+
+	/* Put the completed request on the correct list */
+	isci_task_save_for_upper_layer_completion(ihost, request, response,
+						  status, complete_to_host
+						  );
+
+	/* complete the io request to the core. */
+	sci_controller_complete_io(ihost, request->target_device, request);
+	isci_put_device(idev);
+
+	/* set terminated handle so it cannot be completed or
+	 * terminated again, and to cause any calls into abort
+	 * task to recognize the already completed case.
+	 */
+	set_bit(IREQ_TERMINATED, &request->flags);
+}
+
+static void sci_request_started_state_enter(struct sci_base_state_machine *sm)
+{
+	struct isci_request *ireq = container_of(sm, typeof(*ireq), sm);
+	struct domain_device *dev = ireq->target_device->domain_dev;
+	struct sas_task *task;
+
+	/* XXX as hch said always creating an internal sas_task for tmf
+	 * requests would simplify the driver
+	 */
+	task = ireq->ttype == io_task ? isci_request_access_task(ireq) : NULL;
+
+	/* all unaccelerated request types (non ssp or ncq) handled with
+	 * substates
+	 */
+	if (!task && dev->dev_type == SAS_END_DEV) {
+		sci_change_state(sm, SCI_REQ_TASK_WAIT_TC_COMP);
+	} else if (!task &&
+		   (isci_request_access_tmf(ireq)->tmf_code == isci_tmf_sata_srst_high ||
+		    isci_request_access_tmf(ireq)->tmf_code == isci_tmf_sata_srst_low)) {
+		sci_change_state(sm, SCI_REQ_STP_SOFT_RESET_WAIT_H2D_ASSERTED);
+	} else if (task && task->task_proto == SAS_PROTOCOL_SMP) {
+		sci_change_state(sm, SCI_REQ_SMP_WAIT_RESP);
+	} else if (task && sas_protocol_ata(task->task_proto) &&
+		   !task->ata_task.use_ncq) {
+		u32 state;
+
+		if (task->data_dir == DMA_NONE)
+			state = SCI_REQ_STP_NON_DATA_WAIT_H2D;
+		else if (task->ata_task.dma_xfer)
+			state = SCI_REQ_STP_UDMA_WAIT_TC_COMP;
+		else /* PIO */
+			state = SCI_REQ_STP_PIO_WAIT_H2D;
+
+		sci_change_state(sm, state);
+	}
+}
+
+static void sci_request_completed_state_enter(struct sci_base_state_machine *sm)
+{
+	struct isci_request *ireq = container_of(sm, typeof(*ireq), sm);
+	struct isci_host *ihost = ireq->owning_controller;
+
+	/* Tell the SCI_USER that the IO request is complete */
+	if (!test_bit(IREQ_TMF, &ireq->flags))
+		isci_request_io_request_complete(ihost, ireq,
+						 ireq->sci_status);
+	else
+		isci_task_request_complete(ihost, ireq, ireq->sci_status);
+}
+
+static void sci_request_aborting_state_enter(struct sci_base_state_machine *sm)
+{
+	struct isci_request *ireq = container_of(sm, typeof(*ireq), sm);
+
+	/* Setting the abort bit in the Task Context is required by the silicon. */
+	ireq->tc->abort = 1;
+}
+
+static void sci_stp_request_started_non_data_await_h2d_completion_enter(struct sci_base_state_machine *sm)
+{
+	struct isci_request *ireq = container_of(sm, typeof(*ireq), sm);
+
+	ireq->target_device->working_request = ireq;
+}
+
+static void sci_stp_request_started_pio_await_h2d_completion_enter(struct sci_base_state_machine *sm)
+{
+	struct isci_request *ireq = container_of(sm, typeof(*ireq), sm);
+
+	ireq->target_device->working_request = ireq;
+}
+
+static void sci_stp_request_started_soft_reset_await_h2d_asserted_completion_enter(struct sci_base_state_machine *sm)
+{
+	struct isci_request *ireq = container_of(sm, typeof(*ireq), sm);
+
+	ireq->target_device->working_request = ireq;
+}
+
+static void sci_stp_request_started_soft_reset_await_h2d_diagnostic_completion_enter(struct sci_base_state_machine *sm)
+{
+	struct isci_request *ireq = container_of(sm, typeof(*ireq), sm);
+	struct scu_task_context *tc = ireq->tc;
+	struct host_to_dev_fis *h2d_fis;
+	enum sci_status status;
+
+	/* Clear the SRST bit */
+	h2d_fis = &ireq->stp.cmd;
+	h2d_fis->control = 0;
+
+	/* Clear the TC control bit */
+	tc->control_frame = 0;
+
+	status = sci_controller_continue_io(ireq);
+	WARN_ONCE(status != SCI_SUCCESS, "isci: continue io failure\n");
+}
+
+static const struct sci_base_state sci_request_state_table[] = {
+	[SCI_REQ_INIT] = { },
+	[SCI_REQ_CONSTRUCTED] = { },
+	[SCI_REQ_STARTED] = {
+		.enter_state = sci_request_started_state_enter,
+	},
+	[SCI_REQ_STP_NON_DATA_WAIT_H2D] = {
+		.enter_state = sci_stp_request_started_non_data_await_h2d_completion_enter,
+	},
+	[SCI_REQ_STP_NON_DATA_WAIT_D2H] = { },
+	[SCI_REQ_STP_PIO_WAIT_H2D] = {
+		.enter_state = sci_stp_request_started_pio_await_h2d_completion_enter,
+	},
+	[SCI_REQ_STP_PIO_WAIT_FRAME] = { },
+	[SCI_REQ_STP_PIO_DATA_IN] = { },
+	[SCI_REQ_STP_PIO_DATA_OUT] = { },
+	[SCI_REQ_STP_UDMA_WAIT_TC_COMP] = { },
+	[SCI_REQ_STP_UDMA_WAIT_D2H] = { },
+	[SCI_REQ_STP_SOFT_RESET_WAIT_H2D_ASSERTED] = {
+		.enter_state = sci_stp_request_started_soft_reset_await_h2d_asserted_completion_enter,
+	},
+	[SCI_REQ_STP_SOFT_RESET_WAIT_H2D_DIAG] = {
+		.enter_state = sci_stp_request_started_soft_reset_await_h2d_diagnostic_completion_enter,
+	},
+	[SCI_REQ_STP_SOFT_RESET_WAIT_D2H] = { },
+	[SCI_REQ_TASK_WAIT_TC_COMP] = { },
+	[SCI_REQ_TASK_WAIT_TC_RESP] = { },
+	[SCI_REQ_SMP_WAIT_RESP] = { },
+	[SCI_REQ_SMP_WAIT_TC_COMP] = { },
+	[SCI_REQ_COMPLETED] = {
+		.enter_state = sci_request_completed_state_enter,
+	},
+	[SCI_REQ_ABORTING] = {
+		.enter_state = sci_request_aborting_state_enter,
+	},
+	[SCI_REQ_FINAL] = { },
+};
+
+static void
+sci_general_request_construct(struct isci_host *ihost,
+				   struct isci_remote_device *idev,
+				   struct isci_request *ireq)
+{
+	sci_init_sm(&ireq->sm, sci_request_state_table, SCI_REQ_INIT);
+
+	ireq->target_device = idev;
+	ireq->protocol = SCIC_NO_PROTOCOL;
+	ireq->saved_rx_frame_index = SCU_INVALID_FRAME_INDEX;
+
+	ireq->sci_status   = SCI_SUCCESS;
+	ireq->scu_status   = 0;
+	ireq->post_context = 0xFFFFFFFF;
+}
+
+static enum sci_status
+sci_io_request_construct(struct isci_host *ihost,
+			  struct isci_remote_device *idev,
+			  struct isci_request *ireq)
+{
+	struct domain_device *dev = idev->domain_dev;
+	enum sci_status status = SCI_SUCCESS;
+
+	/* Build the common part of the request */
+	sci_general_request_construct(ihost, idev, ireq);
+
+	if (idev->rnc.remote_node_index == SCIC_SDS_REMOTE_NODE_CONTEXT_INVALID_INDEX)
+		return SCI_FAILURE_INVALID_REMOTE_DEVICE;
+
+	if (dev->dev_type == SAS_END_DEV)
+		/* pass */;
+	else if (dev->dev_type == SATA_DEV || (dev->tproto & SAS_PROTOCOL_STP))
+		memset(&ireq->stp.cmd, 0, sizeof(ireq->stp.cmd));
+	else if (dev_is_expander(dev))
+		/* pass */;
+	else
+		return SCI_FAILURE_UNSUPPORTED_PROTOCOL;
+
+	memset(ireq->tc, 0, offsetof(struct scu_task_context, sgl_pair_ab));
+
+	return status;
+}
+
+enum sci_status sci_task_request_construct(struct isci_host *ihost,
+					    struct isci_remote_device *idev,
+					    u16 io_tag, struct isci_request *ireq)
+{
+	struct domain_device *dev = idev->domain_dev;
+	enum sci_status status = SCI_SUCCESS;
+
+	/* Build the common part of the request */
+	sci_general_request_construct(ihost, idev, ireq);
+
+	if (dev->dev_type == SAS_END_DEV ||
+	    dev->dev_type == SATA_DEV || (dev->tproto & SAS_PROTOCOL_STP)) {
+		set_bit(IREQ_TMF, &ireq->flags);
+		memset(ireq->tc, 0, sizeof(struct scu_task_context));
+	} else
+		status = SCI_FAILURE_UNSUPPORTED_PROTOCOL;
+
+	return status;
+}
+
+static enum sci_status isci_request_ssp_request_construct(
+	struct isci_request *request)
+{
+	enum sci_status status;
+
+	dev_dbg(&request->isci_host->pdev->dev,
+		"%s: request = %p\n",
+		__func__,
+		request);
+	status = sci_io_request_construct_basic_ssp(request);
+	return status;
+}
+
+static enum sci_status isci_request_stp_request_construct(struct isci_request *ireq)
+{
+	struct sas_task *task = isci_request_access_task(ireq);
+	struct host_to_dev_fis *fis = &ireq->stp.cmd;
+	struct ata_queued_cmd *qc = task->uldd_task;
+	enum sci_status status;
+
+	dev_dbg(&ireq->isci_host->pdev->dev,
+		"%s: ireq = %p\n",
+		__func__,
+		ireq);
+
+	memcpy(fis, &task->ata_task.fis, sizeof(struct host_to_dev_fis));
+	if (!task->ata_task.device_control_reg_update)
+		fis->flags |= 0x80;
+	fis->flags &= 0xF0;
+
+	status = sci_io_request_construct_basic_sata(ireq);
+
+	if (qc && (qc->tf.command == ATA_CMD_FPDMA_WRITE ||
+		   qc->tf.command == ATA_CMD_FPDMA_READ)) {
+		fis->sector_count = qc->tag << 3;
+		ireq->tc->type.stp.ncq_tag = qc->tag;
+	}
+
+	return status;
+}
+
+static enum sci_status
+sci_io_request_construct_smp(struct device *dev,
+			      struct isci_request *ireq,
+			      struct sas_task *task)
+{
+	struct scatterlist *sg = &task->smp_task.smp_req;
+	struct isci_remote_device *idev;
+	struct scu_task_context *task_context;
+	struct isci_port *iport;
+	struct smp_req *smp_req;
+	void *kaddr;
+	u8 req_len;
+	u32 cmd;
+
+	kaddr = kmap_atomic(sg_page(sg), KM_IRQ0);
+	smp_req = kaddr + sg->offset;
+	/*
+	 * Look at the SMP requests' header fields; for certain SAS 1.x SMP
+	 * functions under SAS 2.0, a zero request length really indicates
+	 * a non-zero default length.
+	 */
+	if (smp_req->req_len == 0) {
+		switch (smp_req->func) {
+		case SMP_DISCOVER:
+		case SMP_REPORT_PHY_ERR_LOG:
+		case SMP_REPORT_PHY_SATA:
+		case SMP_REPORT_ROUTE_INFO:
+			smp_req->req_len = 2;
+			break;
+		case SMP_CONF_ROUTE_INFO:
+		case SMP_PHY_CONTROL:
+		case SMP_PHY_TEST_FUNCTION:
+			smp_req->req_len = 9;
+			break;
+			/* Default - zero is a valid default for 2.0. */
+		}
+	}
+	req_len = smp_req->req_len;
+	sci_swab32_cpy(smp_req, smp_req, sg->length / sizeof(u32));
+	cmd = *(u32 *) smp_req;
+	kunmap_atomic(kaddr, KM_IRQ0);
+
+	if (!dma_map_sg(dev, sg, 1, DMA_TO_DEVICE))
+		return SCI_FAILURE;
+
+	ireq->protocol = SCIC_SMP_PROTOCOL;
+
+	/* byte swap the smp request. */
+
+	task_context = ireq->tc;
+
+	idev = ireq->target_device;
+	iport = idev->owning_port;
+
+	/*
+	 * Fill in the TC with the its required data
+	 * 00h
+	 */
+	task_context->priority = 0;
+	task_context->initiator_request = 1;
+	task_context->connection_rate = idev->connection_rate;
+	task_context->protocol_engine_index = ISCI_PEG;
+	task_context->logical_port_index = iport->physical_port_index;
+	task_context->protocol_type = SCU_TASK_CONTEXT_PROTOCOL_SMP;
+	task_context->abort = 0;
+	task_context->valid = SCU_TASK_CONTEXT_VALID;
+	task_context->context_type = SCU_TASK_CONTEXT_TYPE;
+
+	/* 04h */
+	task_context->remote_node_index = idev->rnc.remote_node_index;
+	task_context->command_code = 0;
+	task_context->task_type = SCU_TASK_TYPE_SMP_REQUEST;
+
+	/* 08h */
+	task_context->link_layer_control = 0;
+	task_context->do_not_dma_ssp_good_response = 1;
+	task_context->strict_ordering = 0;
+	task_context->control_frame = 1;
+	task_context->timeout_enable = 0;
+	task_context->block_guard_enable = 0;
+
+	/* 0ch */
+	task_context->address_modifier = 0;
+
+	/* 10h */
+	task_context->ssp_command_iu_length = req_len;
+
+	/* 14h */
+	task_context->transfer_length_bytes = 0;
+
+	/*
+	 * 18h ~ 30h, protocol specific
+	 * since commandIU has been build by framework at this point, we just
+	 * copy the frist DWord from command IU to this location. */
+	memcpy(&task_context->type.smp, &cmd, sizeof(u32));
+
+	/*
+	 * 40h
+	 * "For SMP you could program it to zero. We would prefer that way
+	 * so that done code will be consistent." - Venki
+	 */
+	task_context->task_phase = 0;
+
+	ireq->post_context = (SCU_CONTEXT_COMMAND_REQUEST_TYPE_POST_TC |
+			      (ISCI_PEG << SCU_CONTEXT_COMMAND_PROTOCOL_ENGINE_GROUP_SHIFT) |
+			       (iport->physical_port_index <<
+				SCU_CONTEXT_COMMAND_LOGICAL_PORT_SHIFT) |
+			      ISCI_TAG_TCI(ireq->io_tag));
+	/*
+	 * Copy the physical address for the command buffer to the SCU Task
+	 * Context command buffer should not contain command header.
+	 */
+	task_context->command_iu_upper = upper_32_bits(sg_dma_address(sg));
+	task_context->command_iu_lower = lower_32_bits(sg_dma_address(sg) + sizeof(u32));
+
+	/* SMP response comes as UF, so no need to set response IU address. */
+	task_context->response_iu_upper = 0;
+	task_context->response_iu_lower = 0;
+
+	sci_change_state(&ireq->sm, SCI_REQ_CONSTRUCTED);
+
+	return SCI_SUCCESS;
+}
+
+/*
+ * isci_smp_request_build() - This function builds the smp request.
+ * @ireq: This parameter points to the isci_request allocated in the
+ *    request construct function.
+ *
+ * SCI_SUCCESS on successfull completion, or specific failure code.
+ */
+static enum sci_status isci_smp_request_build(struct isci_request *ireq)
+{
+	struct sas_task *task = isci_request_access_task(ireq);
+	struct device *dev = &ireq->isci_host->pdev->dev;
+	enum sci_status status = SCI_FAILURE;
+
+	status = sci_io_request_construct_smp(dev, ireq, task);
+	if (status != SCI_SUCCESS)
+		dev_dbg(&ireq->isci_host->pdev->dev,
+			 "%s: failed with status = %d\n",
+			 __func__,
+			 status);
+
+	return status;
+}
+
+/**
+ * isci_io_request_build() - This function builds the io request object.
+ * @ihost: This parameter specifies the ISCI host object
+ * @request: This parameter points to the isci_request object allocated in the
+ *    request construct function.
+ * @sci_device: This parameter is the handle for the sci core's remote device
+ *    object that is the destination for this request.
+ *
+ * SCI_SUCCESS on successfull completion, or specific failure code.
+ */
+static enum sci_status isci_io_request_build(struct isci_host *ihost,
+					     struct isci_request *request,
+					     struct isci_remote_device *idev)
+{
+	enum sci_status status = SCI_SUCCESS;
+	struct sas_task *task = isci_request_access_task(request);
+
+	dev_dbg(&ihost->pdev->dev,
+		"%s: idev = 0x%p; request = %p, "
+		"num_scatter = %d\n",
+		__func__,
+		idev,
+		request,
+		task->num_scatter);
+
+	/* map the sgl addresses, if present.
+	 * libata does the mapping for sata devices
+	 * before we get the request.
+	 */
+	if (task->num_scatter &&
+	    !sas_protocol_ata(task->task_proto) &&
+	    !(SAS_PROTOCOL_SMP & task->task_proto)) {
+
+		request->num_sg_entries = dma_map_sg(
+			&ihost->pdev->dev,
+			task->scatter,
+			task->num_scatter,
+			task->data_dir
+			);
+
+		if (request->num_sg_entries == 0)
+			return SCI_FAILURE_INSUFFICIENT_RESOURCES;
+	}
+
+	status = sci_io_request_construct(ihost, idev, request);
+
+	if (status != SCI_SUCCESS) {
+		dev_dbg(&ihost->pdev->dev,
+			 "%s: failed request construct\n",
+			 __func__);
+		return SCI_FAILURE;
+	}
+
+	switch (task->task_proto) {
+	case SAS_PROTOCOL_SMP:
+		status = isci_smp_request_build(request);
+		break;
+	case SAS_PROTOCOL_SSP:
+		status = isci_request_ssp_request_construct(request);
+		break;
+	case SAS_PROTOCOL_SATA:
+	case SAS_PROTOCOL_STP:
+	case SAS_PROTOCOL_SATA | SAS_PROTOCOL_STP:
+		status = isci_request_stp_request_construct(request);
+		break;
+	default:
+		dev_dbg(&ihost->pdev->dev,
+			 "%s: unknown protocol\n", __func__);
+		return SCI_FAILURE;
+	}
+
+	return SCI_SUCCESS;
+}
+
+static struct isci_request *isci_request_from_tag(struct isci_host *ihost, u16 tag)
+{
+	struct isci_request *ireq;
+
+	ireq = ihost->reqs[ISCI_TAG_TCI(tag)];
+	ireq->io_tag = tag;
+	ireq->io_request_completion = NULL;
+	ireq->flags = 0;
+	ireq->num_sg_entries = 0;
+	INIT_LIST_HEAD(&ireq->completed_node);
+	INIT_LIST_HEAD(&ireq->dev_node);
+	isci_request_change_state(ireq, allocated);
+
+	return ireq;
+}
+
+static struct isci_request *isci_io_request_from_tag(struct isci_host *ihost,
+						     struct sas_task *task,
+						     u16 tag)
+{
+	struct isci_request *ireq;
+
+	ireq = isci_request_from_tag(ihost, tag);
+	ireq->ttype_ptr.io_task_ptr = task;
+	ireq->ttype = io_task;
+	task->lldd_task = ireq;
+
+	return ireq;
+}
+
+struct isci_request *isci_tmf_request_from_tag(struct isci_host *ihost,
+					       struct isci_tmf *isci_tmf,
+					       u16 tag)
+{
+	struct isci_request *ireq;
+
+	ireq = isci_request_from_tag(ihost, tag);
+	ireq->ttype_ptr.tmf_task_ptr = isci_tmf;
+	ireq->ttype = tmf_task;
+
+	return ireq;
+}
+
+int isci_request_execute(struct isci_host *ihost, struct isci_remote_device *idev,
+			 struct sas_task *task, u16 tag)
+{
+	enum sci_status status = SCI_FAILURE_UNSUPPORTED_PROTOCOL;
+	struct isci_request *ireq;
+	unsigned long flags;
+	int ret = 0;
+
+	/* do common allocation and init of request object. */
+	ireq = isci_io_request_from_tag(ihost, task, tag);
+
+	status = isci_io_request_build(ihost, ireq, idev);
+	if (status != SCI_SUCCESS) {
+		dev_dbg(&ihost->pdev->dev,
+			 "%s: request_construct failed - status = 0x%x\n",
+			 __func__,
+			 status);
+		return status;
+	}
+
+	spin_lock_irqsave(&ihost->scic_lock, flags);
+
+	if (test_bit(IDEV_IO_NCQERROR, &idev->flags)) {
+
+		if (isci_task_is_ncq_recovery(task)) {
+
+			/* The device is in an NCQ recovery state.  Issue the
+			 * request on the task side.  Note that it will
+			 * complete on the I/O request side because the
+			 * request was built that way (ie.
+			 * ireq->is_task_management_request is false).
+			 */
+			status = sci_controller_start_task(ihost,
+							    idev,
+							    ireq);
+		} else {
+			status = SCI_FAILURE;
+		}
+	} else {
+		/* send the request, let the core assign the IO TAG.	*/
+		status = sci_controller_start_io(ihost, idev,
+						  ireq);
+	}
+
+	if (status != SCI_SUCCESS &&
+	    status != SCI_FAILURE_REMOTE_DEVICE_RESET_REQUIRED) {
+		dev_dbg(&ihost->pdev->dev,
+			 "%s: failed request start (0x%x)\n",
+			 __func__, status);
+		spin_unlock_irqrestore(&ihost->scic_lock, flags);
+		return status;
+	}
+
+	/* Either I/O started OK, or the core has signaled that
+	 * the device needs a target reset.
+	 *
+	 * In either case, hold onto the I/O for later.
+	 *
+	 * Update it's status and add it to the list in the
+	 * remote device object.
+	 */
+	list_add(&ireq->dev_node, &idev->reqs_in_process);
+
+	if (status == SCI_SUCCESS) {
+		isci_request_change_state(ireq, started);
+	} else {
+		/* The request did not really start in the
+		 * hardware, so clear the request handle
+		 * here so no terminations will be done.
+		 */
+		set_bit(IREQ_TERMINATED, &ireq->flags);
+		isci_request_change_state(ireq, completed);
+	}
+	spin_unlock_irqrestore(&ihost->scic_lock, flags);
+
+	if (status ==
+	    SCI_FAILURE_REMOTE_DEVICE_RESET_REQUIRED) {
+		/* Signal libsas that we need the SCSI error
+		 * handler thread to work on this I/O and that
+		 * we want a device reset.
+		 */
+		spin_lock_irqsave(&task->task_state_lock, flags);
+		task->task_state_flags |= SAS_TASK_NEED_DEV_RESET;
+		spin_unlock_irqrestore(&task->task_state_lock, flags);
+
+		/* Cause this task to be scheduled in the SCSI error
+		 * handler thread.
+		 */
+		isci_execpath_callback(ihost, task,
+				       sas_task_abort);
+
+		/* Change the status, since we are holding
+		 * the I/O until it is managed by the SCSI
+		 * error handler.
+		 */
+		status = SCI_SUCCESS;
+	}
+
+	return ret;
+}
diff -druN linux-2.6.39-libre/drivers/scsi/isci/request.h linux-3.0-rc7-libre/drivers/scsi/isci/request.h
--- linux-2.6.39-libre/drivers/scsi/isci/request.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/scsi/isci/request.h	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,448 @@
+/*
+ * This file is provided under a dual BSD/GPLv2 license.  When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * The full GNU General Public License is included in this distribution
+ * in the file called LICENSE.GPL.
+ *
+ * BSD LICENSE
+ *
+ * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in
+ *     the documentation and/or other materials provided with the
+ *     distribution.
+ *   * Neither the name of Intel Corporation nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _ISCI_REQUEST_H_
+#define _ISCI_REQUEST_H_
+
+#include "isci.h"
+#include "host.h"
+#include "scu_task_context.h"
+
+/**
+ * struct isci_request_status - This enum defines the possible states of an I/O
+ *    request.
+ *
+ *
+ */
+enum isci_request_status {
+	unallocated = 0x00,
+	allocated   = 0x01,
+	started     = 0x02,
+	completed   = 0x03,
+	aborting    = 0x04,
+	aborted     = 0x05,
+	terminating = 0x06,
+	dead        = 0x07
+};
+
+enum task_type {
+	io_task  = 0,
+	tmf_task = 1
+};
+
+enum sci_request_protocol {
+	SCIC_NO_PROTOCOL,
+	SCIC_SMP_PROTOCOL,
+	SCIC_SSP_PROTOCOL,
+	SCIC_STP_PROTOCOL
+}; /* XXX remove me, use sas_task.{dev|task_proto} instead */;
+
+/**
+ * isci_stp_request - extra request infrastructure to handle pio/atapi protocol
+ * @pio_len - number of bytes requested at PIO setup
+ * @status - pio setup ending status value to tell us if we need
+ *	     to wait for another fis or if the transfer is complete.  Upon
+ *           receipt of a d2h fis this will be the status field of that fis.
+ * @sgl - track pio transfer progress as we iterate through the sgl
+ * @device_cdb_len - atapi device advertises it's transfer constraints at setup
+ */
+struct isci_stp_request {
+	u32 pio_len;
+	u8 status;
+
+	struct isci_stp_pio_sgl {
+		int index;
+		u8 set;
+		u32 offset;
+	} sgl;
+	u32 device_cdb_len;
+};
+
+struct isci_request {
+	enum isci_request_status status;
+	#define IREQ_COMPLETE_IN_TARGET 0
+	#define IREQ_TERMINATED 1
+	#define IREQ_TMF 2
+	#define IREQ_ACTIVE 3
+	unsigned long flags;
+	/* XXX kill ttype and ttype_ptr, allocate full sas_task */
+	enum task_type ttype;
+	union ttype_ptr_union {
+		struct sas_task *io_task_ptr;   /* When ttype==io_task  */
+		struct isci_tmf *tmf_task_ptr;  /* When ttype==tmf_task */
+	} ttype_ptr;
+	struct isci_host *isci_host;
+	/* For use in the requests_to_{complete|abort} lists: */
+	struct list_head completed_node;
+	/* For use in the reqs_in_process list: */
+	struct list_head dev_node;
+	spinlock_t state_lock;
+	dma_addr_t request_daddr;
+	dma_addr_t zero_scatter_daddr;
+	unsigned int num_sg_entries;
+	/* Note: "io_request_completion" is completed in two different ways
+	 * depending on whether this is a TMF or regular request.
+	 * - TMF requests are completed in the thread that started them;
+	 * - regular requests are completed in the request completion callback
+	 *   function.
+	 * This difference in operation allows the aborter of a TMF request
+	 * to be sure that once the TMF request completes, the I/O that the
+	 * TMF was aborting is guaranteed to have completed.
+	 *
+	 * XXX kill io_request_completion
+	 */
+	struct completion *io_request_completion;
+	struct sci_base_state_machine sm;
+	struct isci_host *owning_controller;
+	struct isci_remote_device *target_device;
+	u16 io_tag;
+	enum sci_request_protocol protocol;
+	u32 scu_status; /* hardware result */
+	u32 sci_status; /* upper layer disposition */
+	u32 post_context;
+	struct scu_task_context *tc;
+	/* could be larger with sg chaining */
+	#define SCU_SGL_SIZE ((SCI_MAX_SCATTER_GATHER_ELEMENTS + 1) / 2)
+	struct scu_sgl_element_pair sg_table[SCU_SGL_SIZE] __attribute__ ((aligned(32)));
+	/* This field is a pointer to the stored rx frame data.  It is used in
+	 * STP internal requests and SMP response frames.  If this field is
+	 * non-NULL the saved frame must be released on IO request completion.
+	 */
+	u32 saved_rx_frame_index;
+
+	union {
+		struct {
+			union {
+				struct ssp_cmd_iu cmd;
+				struct ssp_task_iu tmf;
+			};
+			union {
+				struct ssp_response_iu rsp;
+				u8 rsp_buf[SSP_RESP_IU_MAX_SIZE];
+			};
+		} ssp;
+		struct {
+			struct smp_resp rsp;
+		} smp;
+		struct {
+			struct isci_stp_request req;
+			struct host_to_dev_fis cmd;
+			struct dev_to_host_fis rsp;
+		} stp;
+	};
+};
+
+static inline struct isci_request *to_ireq(struct isci_stp_request *stp_req)
+{
+	struct isci_request *ireq;
+
+	ireq = container_of(stp_req, typeof(*ireq), stp.req);
+	return ireq;
+}
+
+/**
+ * enum sci_base_request_states - This enumeration depicts all the states for
+ *    the common request state machine.
+ *
+ *
+ */
+enum sci_base_request_states {
+	/*
+	 * Simply the initial state for the base request state machine.
+	 */
+	SCI_REQ_INIT,
+
+	/*
+	 * This state indicates that the request has been constructed.
+	 * This state is entered from the INITIAL state.
+	 */
+	SCI_REQ_CONSTRUCTED,
+
+	/*
+	 * This state indicates that the request has been started. This state
+	 * is entered from the CONSTRUCTED state.
+	 */
+	SCI_REQ_STARTED,
+
+	SCI_REQ_STP_UDMA_WAIT_TC_COMP,
+	SCI_REQ_STP_UDMA_WAIT_D2H,
+
+	SCI_REQ_STP_NON_DATA_WAIT_H2D,
+	SCI_REQ_STP_NON_DATA_WAIT_D2H,
+
+	SCI_REQ_STP_SOFT_RESET_WAIT_H2D_ASSERTED,
+	SCI_REQ_STP_SOFT_RESET_WAIT_H2D_DIAG,
+	SCI_REQ_STP_SOFT_RESET_WAIT_D2H,
+
+	/*
+	 * While in this state the IO request object is waiting for the TC
+	 * completion notification for the H2D Register FIS
+	 */
+	SCI_REQ_STP_PIO_WAIT_H2D,
+
+	/*
+	 * While in this state the IO request object is waiting for either a
+	 * PIO Setup FIS or a D2H register FIS.  The type of frame received is
+	 * based on the result of the prior frame and line conditions.
+	 */
+	SCI_REQ_STP_PIO_WAIT_FRAME,
+
+	/*
+	 * While in this state the IO request object is waiting for a DATA
+	 * frame from the device.
+	 */
+	SCI_REQ_STP_PIO_DATA_IN,
+
+	/*
+	 * While in this state the IO request object is waiting to transmit
+	 * the next data frame to the device.
+	 */
+	SCI_REQ_STP_PIO_DATA_OUT,
+
+	/*
+	 * The AWAIT_TC_COMPLETION sub-state indicates that the started raw
+	 * task management request is waiting for the transmission of the
+	 * initial frame (i.e. command, task, etc.).
+	 */
+	SCI_REQ_TASK_WAIT_TC_COMP,
+
+	/*
+	 * This sub-state indicates that the started task management request
+	 * is waiting for the reception of an unsolicited frame
+	 * (i.e. response IU).
+	 */
+	SCI_REQ_TASK_WAIT_TC_RESP,
+
+	/*
+	 * This sub-state indicates that the started task management request
+	 * is waiting for the reception of an unsolicited frame
+	 * (i.e. response IU).
+	 */
+	SCI_REQ_SMP_WAIT_RESP,
+
+	/*
+	 * The AWAIT_TC_COMPLETION sub-state indicates that the started SMP
+	 * request is waiting for the transmission of the initial frame
+	 * (i.e. command, task, etc.).
+	 */
+	SCI_REQ_SMP_WAIT_TC_COMP,
+
+	/*
+	 * This state indicates that the request has completed.
+	 * This state is entered from the STARTED state. This state is entered
+	 * from the ABORTING state.
+	 */
+	SCI_REQ_COMPLETED,
+
+	/*
+	 * This state indicates that the request is in the process of being
+	 * terminated/aborted.
+	 * This state is entered from the CONSTRUCTED state.
+	 * This state is entered from the STARTED state.
+	 */
+	SCI_REQ_ABORTING,
+
+	/*
+	 * Simply the final state for the base request state machine.
+	 */
+	SCI_REQ_FINAL,
+};
+
+enum sci_status sci_request_start(struct isci_request *ireq);
+enum sci_status sci_io_request_terminate(struct isci_request *ireq);
+enum sci_status
+sci_io_request_event_handler(struct isci_request *ireq,
+				  u32 event_code);
+enum sci_status
+sci_io_request_frame_handler(struct isci_request *ireq,
+				  u32 frame_index);
+enum sci_status
+sci_task_request_terminate(struct isci_request *ireq);
+extern enum sci_status
+sci_request_complete(struct isci_request *ireq);
+extern enum sci_status
+sci_io_request_tc_completion(struct isci_request *ireq, u32 code);
+
+/* XXX open code in caller */
+static inline dma_addr_t
+sci_io_request_get_dma_addr(struct isci_request *ireq, void *virt_addr)
+{
+
+	char *requested_addr = (char *)virt_addr;
+	char *base_addr = (char *)ireq;
+
+	BUG_ON(requested_addr < base_addr);
+	BUG_ON((requested_addr - base_addr) >= sizeof(*ireq));
+
+	return ireq->request_daddr + (requested_addr - base_addr);
+}
+
+/**
+ * isci_request_change_state() - This function sets the status of the request
+ *    object.
+ * @request: This parameter points to the isci_request object
+ * @status: This Parameter is the new status of the object
+ *
+ */
+static inline enum isci_request_status
+isci_request_change_state(struct isci_request *isci_request,
+			  enum isci_request_status status)
+{
+	enum isci_request_status old_state;
+	unsigned long flags;
+
+	dev_dbg(&isci_request->isci_host->pdev->dev,
+		"%s: isci_request = %p, state = 0x%x\n",
+		__func__,
+		isci_request,
+		status);
+
+	BUG_ON(isci_request == NULL);
+
+	spin_lock_irqsave(&isci_request->state_lock, flags);
+	old_state = isci_request->status;
+	isci_request->status = status;
+	spin_unlock_irqrestore(&isci_request->state_lock, flags);
+
+	return old_state;
+}
+
+/**
+ * isci_request_change_started_to_newstate() - This function sets the status of
+ *    the request object.
+ * @request: This parameter points to the isci_request object
+ * @status: This Parameter is the new status of the object
+ *
+ * state previous to any change.
+ */
+static inline enum isci_request_status
+isci_request_change_started_to_newstate(struct isci_request *isci_request,
+					struct completion *completion_ptr,
+					enum isci_request_status newstate)
+{
+	enum isci_request_status old_state;
+	unsigned long flags;
+
+	spin_lock_irqsave(&isci_request->state_lock, flags);
+
+	old_state = isci_request->status;
+
+	if (old_state == started || old_state == aborting) {
+		BUG_ON(isci_request->io_request_completion != NULL);
+
+		isci_request->io_request_completion = completion_ptr;
+		isci_request->status = newstate;
+	}
+
+	spin_unlock_irqrestore(&isci_request->state_lock, flags);
+
+	dev_dbg(&isci_request->isci_host->pdev->dev,
+		"%s: isci_request = %p, old_state = 0x%x\n",
+		__func__,
+		isci_request,
+		old_state);
+
+	return old_state;
+}
+
+/**
+ * isci_request_change_started_to_aborted() - This function sets the status of
+ *    the request object.
+ * @request: This parameter points to the isci_request object
+ * @completion_ptr: This parameter is saved as the kernel completion structure
+ *    signalled when the old request completes.
+ *
+ * state previous to any change.
+ */
+static inline enum isci_request_status
+isci_request_change_started_to_aborted(struct isci_request *isci_request,
+				       struct completion *completion_ptr)
+{
+	return isci_request_change_started_to_newstate(isci_request,
+						       completion_ptr,
+						       aborted);
+}
+
+#define isci_request_access_task(req) ((req)->ttype_ptr.io_task_ptr)
+
+#define isci_request_access_tmf(req) ((req)->ttype_ptr.tmf_task_ptr)
+
+struct isci_request *isci_tmf_request_from_tag(struct isci_host *ihost,
+					       struct isci_tmf *isci_tmf,
+					       u16 tag);
+int isci_request_execute(struct isci_host *ihost, struct isci_remote_device *idev,
+			 struct sas_task *task, u16 tag);
+void isci_terminate_pending_requests(struct isci_host *ihost,
+				     struct isci_remote_device *idev);
+enum sci_status
+sci_task_request_construct(struct isci_host *ihost,
+			    struct isci_remote_device *idev,
+			    u16 io_tag,
+			    struct isci_request *ireq);
+enum sci_status
+sci_task_request_construct_ssp(struct isci_request *ireq);
+enum sci_status
+sci_task_request_construct_sata(struct isci_request *ireq);
+void sci_smp_request_copy_response(struct isci_request *ireq);
+
+static inline int isci_task_is_ncq_recovery(struct sas_task *task)
+{
+	return (sas_protocol_ata(task->task_proto) &&
+		task->ata_task.fis.command == ATA_CMD_READ_LOG_EXT &&
+		task->ata_task.fis.lbal == ATA_LOG_SATA_NCQ);
+
+}
+
+#endif /* !defined(_ISCI_REQUEST_H_) */
diff -druN linux-2.6.39-libre/drivers/scsi/isci/sas.h linux-3.0-rc7-libre/drivers/scsi/isci/sas.h
--- linux-2.6.39-libre/drivers/scsi/isci/sas.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/scsi/isci/sas.h	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,219 @@
+/*
+ * This file is provided under a dual BSD/GPLv2 license.  When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * The full GNU General Public License is included in this distribution
+ * in the file called LICENSE.GPL.
+ *
+ * BSD LICENSE
+ *
+ * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in
+ *     the documentation and/or other materials provided with the
+ *     distribution.
+ *   * Neither the name of Intel Corporation nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _SCI_SAS_H_
+#define _SCI_SAS_H_
+
+#include <linux/kernel.h>
+
+/*
+ * SATA FIS Types These constants depict the various SATA FIS types devined in
+ * the serial ATA specification.
+ * XXX: This needs to go into <scsi/sas.h>
+ */
+#define FIS_REGH2D          0x27
+#define FIS_REGD2H          0x34
+#define FIS_SETDEVBITS      0xA1
+#define FIS_DMA_ACTIVATE    0x39
+#define FIS_DMA_SETUP       0x41
+#define FIS_BIST_ACTIVATE   0x58
+#define FIS_PIO_SETUP       0x5F
+#define FIS_DATA            0x46
+
+/**************************************************************************/
+#define SSP_RESP_IU_MAX_SIZE	280
+
+/*
+ * contents of the SSP COMMAND INFORMATION UNIT.
+ * For specific information on each of these individual fields please
+ * reference the SAS specification SSP transport layer section.
+ * XXX: This needs to go into <scsi/sas.h>
+ */
+struct ssp_cmd_iu {
+	u8 LUN[8];
+	u8 add_cdb_len:6;
+	u8 _r_a:2;
+	u8 _r_b;
+	u8 en_fburst:1;
+	u8 task_prio:4;
+	u8 task_attr:3;
+	u8 _r_c;
+
+	u8 cdb[16];
+}  __packed;
+
+/*
+ * contents of the SSP TASK INFORMATION UNIT.
+ * For specific information on each of these individual fields please
+ * reference the SAS specification SSP transport layer section.
+ * XXX: This needs to go into <scsi/sas.h>
+ */
+struct ssp_task_iu {
+	u8 LUN[8];
+	u8 _r_a;
+	u8 task_func;
+	u8 _r_b[4];
+	u16 task_tag;
+	u8 _r_c[12];
+}  __packed;
+
+
+/*
+ * struct smp_req_phy_id - This structure defines the contents of
+ *    an SMP Request that is comprised of the struct smp_request_header and a
+ *    phy identifier.
+ *    Examples: SMP_REQUEST_DISCOVER, SMP_REQUEST_REPORT_PHY_SATA.
+ *
+ * For specific information on each of these individual fields please reference
+ * the SAS specification.
+ */
+struct smp_req_phy_id {
+	u8 _r_a[4];		/* bytes 4-7 */
+
+	u8 ign_zone_grp:1;	/* byte 8 */
+	u8 _r_b:7;
+
+	u8 phy_id;		/* byte 9 */
+	u8 _r_c;		/* byte 10 */
+	u8 _r_d;		/* byte 11 */
+}  __packed;
+
+/*
+ * struct smp_req_config_route_info - This structure defines the
+ *    contents of an SMP Configure Route Information request.
+ *
+ * For specific information on each of these individual fields please reference
+ * the SAS specification.
+ */
+struct smp_req_conf_rtinfo {
+	u16 exp_change_cnt;		/* bytes 4-5 */
+	u8 exp_rt_idx_hi;		/* byte 6 */
+	u8 exp_rt_idx;			/* byte 7 */
+
+	u8 _r_a;			/* byte 8 */
+	u8 phy_id;			/* byte 9 */
+	u16 _r_b;			/* bytes 10-11 */
+
+	u8 _r_c:7;			/* byte 12 */
+	u8 dis_rt_entry:1;
+	u8 _r_d[3];			/* bytes 13-15 */
+
+	u8 rt_sas_addr[8];		/* bytes 16-23 */
+	u8 _r_e[16];			/* bytes 24-39 */
+}  __packed;
+
+/*
+ * struct smp_req_phycntl - This structure defines the contents of an
+ *    SMP Phy Controller request.
+ *
+ * For specific information on each of these individual fields please reference
+ * the SAS specification.
+ */
+struct smp_req_phycntl {
+	u16 exp_change_cnt;		/* byte 4-5 */
+
+	u8 _r_a[3];			/* bytes 6-8 */
+
+	u8 phy_id;			/* byte 9 */
+	u8 phy_op;			/* byte 10 */
+
+	u8 upd_pathway:1;		/* byte 11 */
+	u8 _r_b:7;
+
+	u8 _r_c[12];			/* byte 12-23 */
+
+	u8 att_dev_name[8];             /* byte 24-31 */
+
+	u8 _r_d:4;			/* byte 32 */
+	u8 min_linkrate:4;
+
+	u8 _r_e:4;			/* byte 33 */
+	u8 max_linkrate:4;
+
+	u8 _r_f[2];			/* byte 34-35 */
+
+	u8 pathway:4;			/* byte 36 */
+	u8 _r_g:4;
+
+	u8 _r_h[3];			/* bytes 37-39 */
+}  __packed;
+
+/*
+ * struct smp_req - This structure simply unionizes the existing request
+ *    structures into a common request type.
+ *
+ * XXX: This data structure may need to go to scsi/sas.h
+ */
+struct smp_req {
+	u8 type;		/* byte 0 */
+	u8 func;		/* byte 1 */
+	u8 alloc_resp_len;	/* byte 2 */
+	u8 req_len;		/* byte 3 */
+	u8 req_data[0];
+}  __packed;
+
+#define SMP_RESP_HDR_SZ	4
+
+/*
+ * struct sci_sas_address - This structure depicts how a SAS address is
+ *    represented by SCI.
+ * XXX convert this to u8 [SAS_ADDR_SIZE] like the rest of libsas
+ *
+ */
+struct sci_sas_address {
+	u32 high;
+	u32 low;
+};
+#endif
diff -druN linux-2.6.39-libre/drivers/scsi/isci/scu_completion_codes.h linux-3.0-rc7-libre/drivers/scsi/isci/scu_completion_codes.h
--- linux-2.6.39-libre/drivers/scsi/isci/scu_completion_codes.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/scsi/isci/scu_completion_codes.h	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,283 @@
+/*
+ * This file is provided under a dual BSD/GPLv2 license.  When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * The full GNU General Public License is included in this distribution
+ * in the file called LICENSE.GPL.
+ *
+ * BSD LICENSE
+ *
+ * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in
+ *     the documentation and/or other materials provided with the
+ *     distribution.
+ *   * Neither the name of Intel Corporation nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _SCU_COMPLETION_CODES_HEADER_
+#define _SCU_COMPLETION_CODES_HEADER_
+
+/**
+ * This file contains the constants and macros for the SCU hardware completion
+ *    codes.
+ *
+ *
+ */
+
+#define SCU_COMPLETION_TYPE_SHIFT      28
+#define SCU_COMPLETION_TYPE_MASK       0x70000000
+
+/**
+ * SCU_COMPLETION_TYPE() -
+ *
+ * This macro constructs an SCU completion type
+ */
+#define SCU_COMPLETION_TYPE(type) \
+	((u32)(type) << SCU_COMPLETION_TYPE_SHIFT)
+
+/**
+ * SCU_COMPLETION_TYPE() -
+ *
+ * These macros contain the SCU completion types SCU_COMPLETION_TYPE
+ */
+#define SCU_COMPLETION_TYPE_TASK       SCU_COMPLETION_TYPE(0)
+#define SCU_COMPLETION_TYPE_SDMA       SCU_COMPLETION_TYPE(1)
+#define SCU_COMPLETION_TYPE_UFI        SCU_COMPLETION_TYPE(2)
+#define SCU_COMPLETION_TYPE_EVENT      SCU_COMPLETION_TYPE(3)
+#define SCU_COMPLETION_TYPE_NOTIFY     SCU_COMPLETION_TYPE(4)
+
+/**
+ *
+ *
+ * These constants provide the shift and mask values for the various parts of
+ * an SCU completion code.
+ */
+#define SCU_COMPLETION_STATUS_MASK       0x0FFC0000
+#define SCU_COMPLETION_TL_STATUS_MASK    0x0FC00000
+#define SCU_COMPLETION_TL_STATUS_SHIFT   22
+#define SCU_COMPLETION_SDMA_STATUS_MASK  0x003C0000
+#define SCU_COMPLETION_PEG_MASK          0x00010000
+#define SCU_COMPLETION_PORT_MASK         0x00007000
+#define SCU_COMPLETION_PE_MASK           SCU_COMPLETION_PORT_MASK
+#define SCU_COMPLETION_PE_SHIFT          12
+#define SCU_COMPLETION_INDEX_MASK        0x00000FFF
+
+/**
+ * SCU_GET_COMPLETION_TYPE() -
+ *
+ * This macro returns the SCU completion type.
+ */
+#define SCU_GET_COMPLETION_TYPE(completion_code) \
+	((completion_code) & SCU_COMPLETION_TYPE_MASK)
+
+/**
+ * SCU_GET_COMPLETION_STATUS() -
+ *
+ * This macro returns the SCU completion status.
+ */
+#define SCU_GET_COMPLETION_STATUS(completion_code) \
+	((completion_code) & SCU_COMPLETION_STATUS_MASK)
+
+/**
+ * SCU_GET_COMPLETION_TL_STATUS() -
+ *
+ * This macro returns the transport layer completion status.
+ */
+#define SCU_GET_COMPLETION_TL_STATUS(completion_code) \
+	((completion_code) & SCU_COMPLETION_TL_STATUS_MASK)
+
+/**
+ * SCU_MAKE_COMPLETION_STATUS() -
+ *
+ * This macro takes a completion code and performs the shift and mask
+ * operations to turn it into a completion code that can be compared to a
+ * SCU_GET_COMPLETION_TL_STATUS.
+ */
+#define SCU_MAKE_COMPLETION_STATUS(completion_code) \
+	((u32)(completion_code) << SCU_COMPLETION_TL_STATUS_SHIFT)
+
+/**
+ * SCU_NORMALIZE_COMPLETION_STATUS() -
+ *
+ * This macro takes a SCU_GET_COMPLETION_TL_STATUS and normalizes it for a
+ * return code.
+ */
+#define SCU_NORMALIZE_COMPLETION_STATUS(completion_code) \
+	(\
+		((completion_code) & SCU_COMPLETION_TL_STATUS_MASK) \
+		>> SCU_COMPLETION_TL_STATUS_SHIFT \
+	)
+
+/**
+ * SCU_GET_COMPLETION_SDMA_STATUS() -
+ *
+ * This macro returns the SDMA completion status.
+ */
+#define SCU_GET_COMPLETION_SDMA_STATUS(completion_code)	\
+	((completion_code) & SCU_COMPLETION_SDMA_STATUS_MASK)
+
+/**
+ * SCU_GET_COMPLETION_PEG() -
+ *
+ * This macro returns the Protocol Engine Group from the completion code.
+ */
+#define SCU_GET_COMPLETION_PEG(completion_code)	\
+	((completion_code) & SCU_COMPLETION_PEG_MASK)
+
+/**
+ * SCU_GET_COMPLETION_PORT() -
+ *
+ * This macro reuturns the logical port index from the completion code.
+ */
+#define SCU_GET_COMPLETION_PORT(completion_code) \
+	((completion_code) & SCU_COMPLETION_PORT_MASK)
+
+/**
+ * SCU_GET_PROTOCOL_ENGINE_INDEX() -
+ *
+ * This macro returns the PE index from the completion code.
+ */
+#define SCU_GET_PROTOCOL_ENGINE_INDEX(completion_code) \
+	(((completion_code) & SCU_COMPLETION_PE_MASK) >> SCU_COMPLETION_PE_SHIFT)
+
+/**
+ * SCU_GET_COMPLETION_INDEX() -
+ *
+ * This macro returns the index of the completion which is either a TCi or an
+ * RNi depending on the completion type.
+ */
+#define SCU_GET_COMPLETION_INDEX(completion_code) \
+	((completion_code) & SCU_COMPLETION_INDEX_MASK)
+
+#define SCU_UNSOLICITED_FRAME_MASK     0x0FFF0000
+#define SCU_UNSOLICITED_FRAME_SHIFT    16
+
+/**
+ * SCU_GET_FRAME_INDEX() -
+ *
+ * This macro returns a normalized frame index from an unsolicited frame
+ * completion.
+ */
+#define SCU_GET_FRAME_INDEX(completion_code) \
+	(\
+		((completion_code) & SCU_UNSOLICITED_FRAME_MASK) \
+		>> SCU_UNSOLICITED_FRAME_SHIFT \
+	)
+
+#define SCU_UNSOLICITED_FRAME_ERROR_MASK  0x00008000
+
+/**
+ * SCU_GET_FRAME_ERROR() -
+ *
+ * This macro returns a zero (0) value if there is no frame error otherwise it
+ * returns non-zero (!0).
+ */
+#define SCU_GET_FRAME_ERROR(completion_code) \
+	((completion_code) & SCU_UNSOLICITED_FRAME_ERROR_MASK)
+
+/**
+ *
+ *
+ * These constants represent normalized completion codes which must be shifted
+ * 18 bits to match it with the hardware completion code. In a 16-bit compiler,
+ * immediate constants are 16-bit values (the size of an int). If we shift
+ * those by 18 bits, we completely lose the value. To ensure the value is a
+ * 32-bit value like we want, each immediate value must be cast to a u32.
+ */
+#define SCU_TASK_DONE_GOOD                                  ((u32)0x00)
+#define SCU_TASK_DONE_CRC_ERR                               ((u32)0x14)
+#define SCU_TASK_DONE_CHECK_RESPONSE                        ((u32)0x14)
+#define SCU_TASK_DONE_GEN_RESPONSE                          ((u32)0x15)
+#define SCU_TASK_DONE_NAK_CMD_ERR                           ((u32)0x16)
+#define SCU_TASK_DONE_CMD_LL_R_ERR                          ((u32)0x16)
+#define SCU_TASK_DONE_LL_R_ERR                              ((u32)0x17)
+#define SCU_TASK_DONE_ACK_NAK_TO                            ((u32)0x17)
+#define SCU_TASK_DONE_LL_PERR                               ((u32)0x18)
+#define SCU_TASK_DONE_LL_SY_TERM                            ((u32)0x19)
+#define SCU_TASK_DONE_NAK_ERR                               ((u32)0x19)
+#define SCU_TASK_DONE_LL_LF_TERM                            ((u32)0x1A)
+#define SCU_TASK_DONE_DATA_LEN_ERR                          ((u32)0x1A)
+#define SCU_TASK_DONE_LL_CL_TERM                            ((u32)0x1B)
+#define SCU_TASK_DONE_LL_ABORT_ERR                          ((u32)0x1B)
+#define SCU_TASK_DONE_SEQ_INV_TYPE                          ((u32)0x1C)
+#define SCU_TASK_DONE_UNEXP_XR                              ((u32)0x1C)
+#define SCU_TASK_DONE_INV_FIS_TYPE                          ((u32)0x1D)
+#define SCU_TASK_DONE_XR_IU_LEN_ERR                         ((u32)0x1D)
+#define SCU_TASK_DONE_INV_FIS_LEN                           ((u32)0x1E)
+#define SCU_TASK_DONE_XR_WD_LEN                             ((u32)0x1E)
+#define SCU_TASK_DONE_SDMA_ERR                              ((u32)0x1F)
+#define SCU_TASK_DONE_OFFSET_ERR                            ((u32)0x20)
+#define SCU_TASK_DONE_MAX_PLD_ERR                           ((u32)0x21)
+#define SCU_TASK_DONE_EXCESS_DATA                           ((u32)0x22)
+#define SCU_TASK_DONE_LF_ERR                                ((u32)0x23)
+#define SCU_TASK_DONE_UNEXP_FIS                             ((u32)0x24)
+#define SCU_TASK_DONE_UNEXP_RESP                            ((u32)0x24)
+#define SCU_TASK_DONE_EARLY_RESP                            ((u32)0x25)
+#define SCU_TASK_DONE_SMP_RESP_TO_ERR                       ((u32)0x26)
+#define SCU_TASK_DONE_DMASETUP_DIRERR                       ((u32)0x27)
+#define SCU_TASK_DONE_SMP_UFI_ERR                           ((u32)0x27)
+#define SCU_TASK_DONE_XFERCNT_ERR                           ((u32)0x28)
+#define SCU_TASK_DONE_SMP_FRM_TYPE_ERR                      ((u32)0x28)
+#define SCU_TASK_DONE_SMP_LL_RX_ERR                         ((u32)0x29)
+#define SCU_TASK_DONE_RESP_LEN_ERR                          ((u32)0x2A)
+#define SCU_TASK_DONE_UNEXP_DATA                            ((u32)0x2B)
+#define SCU_TASK_DONE_OPEN_FAIL                             ((u32)0x2C)
+#define SCU_TASK_DONE_UNEXP_SDBFIS                          ((u32)0x2D)
+#define SCU_TASK_DONE_REG_ERR                               ((u32)0x2E)
+#define SCU_TASK_DONE_SDB_ERR                               ((u32)0x2F)
+#define SCU_TASK_DONE_TASK_ABORT                            ((u32)0x30)
+#define SCU_TASK_DONE_CMD_SDMA_ERR                          ((U32)0x32)
+#define SCU_TASK_DONE_CMD_LL_ABORT_ERR                      ((U32)0x33)
+#define SCU_TASK_OPEN_REJECT_WRONG_DESTINATION              ((u32)0x34)
+#define SCU_TASK_OPEN_REJECT_RESERVED_ABANDON_1             ((u32)0x35)
+#define SCU_TASK_OPEN_REJECT_RESERVED_ABANDON_2             ((u32)0x36)
+#define SCU_TASK_OPEN_REJECT_RESERVED_ABANDON_3             ((u32)0x37)
+#define SCU_TASK_OPEN_REJECT_BAD_DESTINATION                ((u32)0x38)
+#define SCU_TASK_OPEN_REJECT_ZONE_VIOLATION                 ((u32)0x39)
+#define SCU_TASK_DONE_VIIT_ENTRY_NV                         ((u32)0x3A)
+#define SCU_TASK_DONE_IIT_ENTRY_NV                          ((u32)0x3B)
+#define SCU_TASK_DONE_RNCNV_OUTBOUND                        ((u32)0x3C)
+#define SCU_TASK_OPEN_REJECT_STP_RESOURCES_BUSY             ((u32)0x3D)
+#define SCU_TASK_OPEN_REJECT_PROTOCOL_NOT_SUPPORTED         ((u32)0x3E)
+#define SCU_TASK_OPEN_REJECT_CONNECTION_RATE_NOT_SUPPORTED  ((u32)0x3F)
+
+#endif /* _SCU_COMPLETION_CODES_HEADER_ */
diff -druN linux-2.6.39-libre/drivers/scsi/isci/scu_event_codes.h linux-3.0-rc7-libre/drivers/scsi/isci/scu_event_codes.h
--- linux-2.6.39-libre/drivers/scsi/isci/scu_event_codes.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/scsi/isci/scu_event_codes.h	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,336 @@
+/*
+ * This file is provided under a dual BSD/GPLv2 license.  When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * The full GNU General Public License is included in this distribution
+ * in the file called LICENSE.GPL.
+ *
+ * BSD LICENSE
+ *
+ * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in
+ *     the documentation and/or other materials provided with the
+ *     distribution.
+ *   * Neither the name of Intel Corporation nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __SCU_EVENT_CODES_HEADER__
+#define __SCU_EVENT_CODES_HEADER__
+
+/**
+ * This file contains the constants and macros for the SCU event codes.
+ *
+ *
+ */
+
+#define SCU_EVENT_TYPE_CODE_SHIFT      24
+#define SCU_EVENT_TYPE_CODE_MASK       0x0F000000
+
+#define SCU_EVENT_SPECIFIC_CODE_SHIFT  18
+#define SCU_EVENT_SPECIFIC_CODE_MASK   0x00FC0000
+
+#define SCU_EVENT_CODE_MASK \
+	(SCU_EVENT_TYPE_CODE_MASK | SCU_EVENT_SPECIFIC_CODE_MASK)
+
+/**
+ * SCU_EVENT_TYPE() -
+ *
+ * This macro constructs an SCU event type from the type value.
+ */
+#define SCU_EVENT_TYPE(type) \
+	((u32)(type) << SCU_EVENT_TYPE_CODE_SHIFT)
+
+/**
+ * SCU_EVENT_SPECIFIC() -
+ *
+ * This macro constructs an SCU event specifier from the code value.
+ */
+#define SCU_EVENT_SPECIFIC(code) \
+	((u32)(code) << SCU_EVENT_SPECIFIC_CODE_SHIFT)
+
+/**
+ * SCU_EVENT_MESSAGE() -
+ *
+ * This macro constructs a combines an SCU event type and SCU event specifier
+ * from the type and code values.
+ */
+#define SCU_EVENT_MESSAGE(type, code) \
+	((type) | SCU_EVENT_SPECIFIC(code))
+
+/**
+ * SCU_EVENT_TYPE() -
+ *
+ * SCU_EVENT_TYPES
+ */
+#define SCU_EVENT_TYPE_SMU_COMMAND_ERROR  SCU_EVENT_TYPE(0x08)
+#define SCU_EVENT_TYPE_SMU_PCQ_ERROR      SCU_EVENT_TYPE(0x09)
+#define SCU_EVENT_TYPE_SMU_ERROR          SCU_EVENT_TYPE(0x00)
+#define SCU_EVENT_TYPE_TRANSPORT_ERROR    SCU_EVENT_TYPE(0x01)
+#define SCU_EVENT_TYPE_BROADCAST_CHANGE   SCU_EVENT_TYPE(0x02)
+#define SCU_EVENT_TYPE_OSSP_EVENT         SCU_EVENT_TYPE(0x03)
+#define SCU_EVENT_TYPE_FATAL_MEMORY_ERROR SCU_EVENT_TYPE(0x0F)
+#define SCU_EVENT_TYPE_RNC_SUSPEND_TX     SCU_EVENT_TYPE(0x04)
+#define SCU_EVENT_TYPE_RNC_SUSPEND_TX_RX  SCU_EVENT_TYPE(0x05)
+#define SCU_EVENT_TYPE_RNC_OPS_MISC       SCU_EVENT_TYPE(0x06)
+#define SCU_EVENT_TYPE_PTX_SCHEDULE_EVENT SCU_EVENT_TYPE(0x07)
+#define SCU_EVENT_TYPE_ERR_CNT_EVENT      SCU_EVENT_TYPE(0x0A)
+
+/**
+ *
+ *
+ * SCU_EVENT_SPECIFIERS
+ */
+#define SCU_EVENT_SPECIFIER_DRIVER_SUSPEND 0x20
+#define SCU_EVENT_SPECIFIER_RNC_RELEASE    0x00
+
+/**
+ *
+ *
+ * SMU_COMMAND_EVENTS
+ */
+#define SCU_EVENT_INVALID_CONTEXT_COMMAND \
+	SCU_EVENT_MESSAGE(SCU_EVENT_TYPE_SMU_COMMAND_ERROR, 0x00)
+
+/**
+ *
+ *
+ * SMU_PCQ_EVENTS
+ */
+#define SCU_EVENT_UNCORRECTABLE_PCQ_ERROR \
+	SCU_EVENT_MESSAGE(SCU_EVENT_TYPE_SMU_PCQ_ERROR, 0x00)
+
+/**
+ *
+ *
+ * SMU_EVENTS
+ */
+#define SCU_EVENT_UNCORRECTABLE_REGISTER_WRITE \
+	SCU_EVENT_MESSAGE(SCU_EVENT_TYPE_SMU_ERROR, 0x02)
+#define SCU_EVENT_UNCORRECTABLE_REGISTER_READ \
+	SCU_EVENT_MESSAGE(SCU_EVENT_TYPE_SMU_ERROR, 0x03)
+#define SCU_EVENT_PCIE_INTERFACE_ERROR \
+	SCU_EVENT_MESSAGE(SCU_EVENT_TYPE_SMU_ERROR, 0x04)
+#define SCU_EVENT_FUNCTION_LEVEL_RESET \
+	SCU_EVENT_MESSAGE(SCU_EVENT_TYPE_SMU_ERROR, 0x05)
+
+/**
+ *
+ *
+ * TRANSPORT_LEVEL_ERRORS
+ */
+#define SCU_EVENT_ACK_NAK_TIMEOUT_ERROR	\
+	SCU_EVENT_MESSAGE(SCU_EVENT_TYPE_TRANSPORT_ERROR, 0x00)
+
+/**
+ *
+ *
+ * BROADCAST_CHANGE_EVENTS
+ */
+#define SCU_EVENT_BROADCAST_CHANGE \
+	SCU_EVENT_MESSAGE(SCU_EVENT_TYPE_BROADCAST_CHANGE, 0x01)
+#define SCU_EVENT_BROADCAST_RESERVED0 \
+	SCU_EVENT_MESSAGE(SCU_EVENT_TYPE_BROADCAST_CHANGE, 0x02)
+#define SCU_EVENT_BROADCAST_RESERVED1 \
+	SCU_EVENT_MESSAGE(SCU_EVENT_TYPE_BROADCAST_CHANGE, 0x03)
+#define SCU_EVENT_BROADCAST_SES	\
+	SCU_EVENT_MESSAGE(SCU_EVENT_TYPE_BROADCAST_CHANGE, 0x04)
+#define SCU_EVENT_BROADCAST_EXPANDER \
+	SCU_EVENT_MESSAGE(SCU_EVENT_TYPE_BROADCAST_CHANGE, 0x05)
+#define SCU_EVENT_BROADCAST_AEN	\
+	SCU_EVENT_MESSAGE(SCU_EVENT_TYPE_BROADCAST_CHANGE, 0x06)
+#define SCU_EVENT_BROADCAST_RESERVED3 \
+	SCU_EVENT_MESSAGE(SCU_EVENT_TYPE_BROADCAST_CHANGE, 0x07)
+#define SCU_EVENT_BROADCAST_RESERVED4 \
+	SCU_EVENT_MESSAGE(SCU_EVENT_TYPE_BROADCAST_CHANGE, 0x08)
+#define SCU_EVENT_PE_SUSPENDED \
+	SCU_EVENT_MESSAGE(SCU_EVENT_TYPE_BROADCAST_CHANGE, 0x09)
+
+/**
+ *
+ *
+ * OSSP_EVENTS
+ */
+#define SCU_EVENT_PORT_SELECTOR_DETECTED \
+	SCU_EVENT_MESSAGE(SCU_EVENT_TYPE_OSSP_EVENT, 0x10)
+#define SCU_EVENT_SENT_PORT_SELECTION \
+	SCU_EVENT_MESSAGE(SCU_EVENT_TYPE_OSSP_EVENT, 0x11)
+#define SCU_EVENT_HARD_RESET_TRANSMITTED \
+	SCU_EVENT_MESSAGE(SCU_EVENT_TYPE_OSSP_EVENT, 0x12)
+#define SCU_EVENT_HARD_RESET_RECEIVED \
+	SCU_EVENT_MESSAGE(SCU_EVENT_TYPE_OSSP_EVENT, 0x13)
+#define SCU_EVENT_RECEIVED_IDENTIFY_TIMEOUT \
+	SCU_EVENT_MESSAGE(SCU_EVENT_TYPE_OSSP_EVENT, 0x15)
+#define SCU_EVENT_LINK_FAILURE \
+	SCU_EVENT_MESSAGE(SCU_EVENT_TYPE_OSSP_EVENT, 0x16)
+#define SCU_EVENT_SATA_SPINUP_HOLD \
+	SCU_EVENT_MESSAGE(SCU_EVENT_TYPE_OSSP_EVENT, 0x17)
+#define SCU_EVENT_SAS_15_SSC \
+	SCU_EVENT_MESSAGE(SCU_EVENT_TYPE_OSSP_EVENT, 0x18)
+#define SCU_EVENT_SAS_15 \
+	SCU_EVENT_MESSAGE(SCU_EVENT_TYPE_OSSP_EVENT, 0x19)
+#define SCU_EVENT_SAS_30_SSC \
+	SCU_EVENT_MESSAGE(SCU_EVENT_TYPE_OSSP_EVENT, 0x1A)
+#define SCU_EVENT_SAS_30 \
+	SCU_EVENT_MESSAGE(SCU_EVENT_TYPE_OSSP_EVENT, 0x1B)
+#define SCU_EVENT_SAS_60_SSC \
+	SCU_EVENT_MESSAGE(SCU_EVENT_TYPE_OSSP_EVENT, 0x1C)
+#define SCU_EVENT_SAS_60 \
+	SCU_EVENT_MESSAGE(SCU_EVENT_TYPE_OSSP_EVENT, 0x1D)
+#define SCU_EVENT_SATA_15_SSC \
+	SCU_EVENT_MESSAGE(SCU_EVENT_TYPE_OSSP_EVENT, 0x1E)
+#define SCU_EVENT_SATA_15 \
+	SCU_EVENT_MESSAGE(SCU_EVENT_TYPE_OSSP_EVENT, 0x1F)
+#define SCU_EVENT_SATA_30_SSC \
+	SCU_EVENT_MESSAGE(SCU_EVENT_TYPE_OSSP_EVENT, 0x20)
+#define SCU_EVENT_SATA_30 \
+	SCU_EVENT_MESSAGE(SCU_EVENT_TYPE_OSSP_EVENT, 0x21)
+#define SCU_EVENT_SATA_60_SSC \
+	SCU_EVENT_MESSAGE(SCU_EVENT_TYPE_OSSP_EVENT, 0x22)
+#define SCU_EVENT_SATA_60 \
+	SCU_EVENT_MESSAGE(SCU_EVENT_TYPE_OSSP_EVENT, 0x23)
+#define SCU_EVENT_SAS_PHY_DETECTED \
+	SCU_EVENT_MESSAGE(SCU_EVENT_TYPE_OSSP_EVENT, 0x24)
+#define SCU_EVENT_SATA_PHY_DETECTED \
+	SCU_EVENT_MESSAGE(SCU_EVENT_TYPE_OSSP_EVENT, 0x25)
+
+/**
+ *
+ *
+ * FATAL_INTERNAL_MEMORY_ERROR_EVENTS
+ */
+#define SCU_EVENT_TSC_RNSC_UNCORRECTABLE_ERROR \
+	SCU_EVENT_MESSAGE(SCU_EVENT_TYPE_FATAL_MEMORY_ERROR,  0x00)
+#define SCU_EVENT_TC_RNC_UNCORRECTABLE_ERROR \
+	SCU_EVENT_MESSAGE(SCU_EVENT_TYPE_FATAL_MEMORY_ERROR,  0x01)
+#define SCU_EVENT_ZPT_UNCORRECTABLE_ERROR \
+	SCU_EVENT_MESSAGE(SCU_EVENT_TYPE_FATAL_MEMORY_ERROR,  0x02)
+
+/**
+ *
+ *
+ * REMOTE_NODE_SUSPEND_EVENTS
+ */
+#define SCU_EVENT_TL_RNC_SUSPEND_TX \
+	SCU_EVENT_MESSAGE(SCU_EVENT_TYPE_RNC_SUSPEND_TX, 0x00)
+#define SCU_EVENT_TL_RNC_SUSPEND_TX_RX \
+	SCU_EVENT_MESSAGE(SCU_EVENT_TYPE_RNC_SUSPEND_TX_RX, 0x00)
+#define SCU_EVENT_DRIVER_POST_RNC_SUSPEND_TX \
+	SCU_EVENT_MESSAGE(SCU_EVENT_TYPE_RNC_SUSPEND_TX, 0x20)
+#define SCU_EVENT_DRIVER_POST_RNC_SUSPEND_TX_RX	\
+	SCU_EVENT_MESSAGE(SCU_EVENT_TYPE_RNC_SUSPEND_TX_RX, 0x20)
+
+/**
+ *
+ *
+ * REMOTE_NODE_MISC_EVENTS
+ */
+#define SCU_EVENT_POST_RCN_RELEASE \
+	SCU_EVENT_MESSAGE(SCU_EVENT_TYPE_RNC_OPS_MISC, SCU_EVENT_SPECIFIER_RNC_RELEASE)
+#define SCU_EVENT_POST_IT_NEXUS_LOSS_TIMER_ENABLE \
+	SCU_EVENT_MESSAGE(SCU_EVENT_TYPE_RNC_OPS_MISC, 0x01)
+#define SCU_EVENT_POST_IT_NEXUS_LOSS_TIMER_DISABLE \
+	SCU_EVENT_MESSAGE(SCU_EVENT_TYPE_RNC_OPS_MISC, 0x02)
+#define SCU_EVENT_POST_RNC_COMPLETE \
+	SCU_EVENT_MESSAGE(SCU_EVENT_TYPE_RNC_OPS_MISC, 0x03)
+#define SCU_EVENT_POST_RNC_INVALIDATE_COMPLETE \
+	SCU_EVENT_MESSAGE(SCU_EVENT_TYPE_RNC_OPS_MISC, 0x04)
+
+/**
+ *
+ *
+ * ERROR_COUNT_EVENT
+ */
+#define SCU_EVENT_RX_CREDIT_BLOCKED_RECEIVED \
+	SCU_EVENT_MESSAGE(SCU_EVENT_TYPE_ERR_CNT_EVENT, 0x00)
+#define SCU_EVENT_TX_DONE_CREDIT_TIMEOUT \
+	SCU_EVENT_MESSAGE(SCU_EVENT_TYPE_ERR_CNT_EVENT, 0x01)
+#define SCU_EVENT_RX_DONE_CREDIT_TIMEOUT \
+	SCU_EVENT_MESSAGE(SCU_EVENT_TYPE_ERR_CNT_EVENT, 0x02)
+
+/**
+ * scu_get_event_type() -
+ *
+ * This macro returns the SCU event type from the event code.
+ */
+#define scu_get_event_type(event_code) \
+	((event_code) & SCU_EVENT_TYPE_CODE_MASK)
+
+/**
+ * scu_get_event_specifier() -
+ *
+ * This macro returns the SCU event specifier from the event code.
+ */
+#define scu_get_event_specifier(event_code) \
+	((event_code) & SCU_EVENT_SPECIFIC_CODE_MASK)
+
+/**
+ * scu_get_event_code() -
+ *
+ * This macro returns the combined SCU event type and SCU event specifier from
+ * the event code.
+ */
+#define scu_get_event_code(event_code) \
+	((event_code) & SCU_EVENT_CODE_MASK)
+
+
+/**
+ *
+ *
+ * PTS_SCHEDULE_EVENT
+ */
+#define SCU_EVENT_SMP_RESPONSE_NO_PE \
+	SCU_EVENT_MESSAGE(SCU_EVENT_TYPE_PTX_SCHEDULE_EVENT, 0x00)
+#define SCU_EVENT_SPECIFIC_SMP_RESPONSE_NO_PE \
+	scu_get_event_specifier(SCU_EVENT_SMP_RESPONSE_NO_PE)
+
+#define SCU_EVENT_TASK_TIMEOUT \
+	SCU_EVENT_MESSAGE(SCU_EVENT_TYPE_PTX_SCHEDULE_EVENT, 0x01)
+#define SCU_EVENT_SPECIFIC_TASK_TIMEOUT	\
+	scu_get_event_specifier(SCU_EVENT_TASK_TIMEOUT)
+
+#define SCU_EVENT_IT_NEXUS_TIMEOUT \
+	SCU_EVENT_MESSAGE(SCU_EVENT_TYPE_PTX_SCHEDULE_EVENT, 0x02)
+#define SCU_EVENT_SPECIFIC_IT_NEXUS_TIMEOUT \
+	scu_get_event_specifier(SCU_EVENT_IT_NEXUS_TIMEOUT)
+
+
+#endif /* __SCU_EVENT_CODES_HEADER__ */
diff -druN linux-2.6.39-libre/drivers/scsi/isci/scu_remote_node_context.h linux-3.0-rc7-libre/drivers/scsi/isci/scu_remote_node_context.h
--- linux-2.6.39-libre/drivers/scsi/isci/scu_remote_node_context.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/scsi/isci/scu_remote_node_context.h	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,229 @@
+/*
+ * This file is provided under a dual BSD/GPLv2 license.  When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * The full GNU General Public License is included in this distribution
+ * in the file called LICENSE.GPL.
+ *
+ * BSD LICENSE
+ *
+ * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in
+ *     the documentation and/or other materials provided with the
+ *     distribution.
+ *   * Neither the name of Intel Corporation nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __SCU_REMOTE_NODE_CONTEXT_HEADER__
+#define __SCU_REMOTE_NODE_CONTEXT_HEADER__
+
+/**
+ * This file contains the structures and constatns used by the SCU hardware to
+ *    describe a remote node context.
+ *
+ *
+ */
+
+/**
+ * struct ssp_remote_node_context - This structure contains the SCU hardware
+ *    definition for an SSP remote node.
+ *
+ *
+ */
+struct ssp_remote_node_context {
+	/* WORD 0 */
+
+	/**
+	 * This field is the remote node index assigned for this remote node. All
+	 * remote nodes must have a unique remote node index. The value of the remote
+	 * node index can not exceed the maximum number of remote nodes reported in
+	 * the SCU device context capacity register.
+	 */
+	u32 remote_node_index:12;
+	u32 reserved0_1:4;
+
+	/**
+	 * This field tells the SCU hardware how many simultaneous connections that
+	 * this remote node will support.
+	 */
+	u32 remote_node_port_width:4;
+
+	/**
+	 * This field tells the SCU hardware which logical port to associate with this
+	 * remote node.
+	 */
+	u32 logical_port_index:3;
+	u32 reserved0_2:5;
+
+	/**
+	 * This field will enable the I_T nexus loss timer for this remote node.
+	 */
+	u32 nexus_loss_timer_enable:1;
+
+	/**
+	 * This field is the for driver debug only and is not used.
+	 */
+	u32 check_bit:1;
+
+	/**
+	 * This field must be set to true when the hardware DMAs the remote node
+	 * context to the hardware SRAM.  When the remote node is being invalidated
+	 * this field must be set to false.
+	 */
+	u32 is_valid:1;
+
+	/**
+	 * This field must be set to true.
+	 */
+	u32 is_remote_node_context:1;
+
+	/* WORD 1 - 2 */
+
+	/**
+	 * This is the low word of the remote device SAS Address
+	 */
+	u32 remote_sas_address_lo;
+
+	/**
+	 * This field is the high word of the remote device SAS Address
+	 */
+	u32 remote_sas_address_hi;
+
+	/* WORD 3 */
+	/**
+	 * This field reprensets the function number assigned to this remote device.
+	 * This value must match the virtual function number that is being used to
+	 * communicate to the device.
+	 */
+	u32 function_number:8;
+	u32 reserved3_1:8;
+
+	/**
+	 * This field provides the driver a way to cheat on the arbitration wait time
+	 * for this remote node.
+	 */
+	u32 arbitration_wait_time:16;
+
+	/* WORD 4 */
+	/**
+	 * This field tells the SCU hardware how long this device may occupy the
+	 * connection before it must be closed.
+	 */
+	u32 connection_occupancy_timeout:16;
+
+	/**
+	 * This field tells the SCU hardware how long to maintain a connection when
+	 * there are no frames being transmitted on the link.
+	 */
+	u32 connection_inactivity_timeout:16;
+
+	/* WORD  5 */
+	/**
+	 * This field allows the driver to cheat on the arbitration wait time for this
+	 * remote node.
+	 */
+	u32 initial_arbitration_wait_time:16;
+
+	/**
+	 * This field is tells the hardware what to program for the connection rate in
+	 * the open address frame.  See the SAS spec for valid values.
+	 */
+	u32 oaf_connection_rate:4;
+
+	/**
+	 * This field tells the SCU hardware what to program for the features in the
+	 * open address frame.  See the SAS spec for valid values.
+	 */
+	u32 oaf_features:4;
+
+	/**
+	 * This field tells the SCU hardware what to use for the source zone group in
+	 * the open address frame.  See the SAS spec for more details on zoning.
+	 */
+	u32 oaf_source_zone_group:8;
+
+	/* WORD 6 */
+	/**
+	 * This field tells the SCU hardware what to use as the more capibilities in
+	 * the open address frame. See the SAS Spec for details.
+	 */
+	u32 oaf_more_compatibility_features;
+
+	/* WORD 7 */
+	u32 reserved7;
+
+};
+
+/**
+ * struct stp_remote_node_context - This structure contains the SCU hardware
+ *    definition for a STP remote node.
+ *
+ * STP Targets are not yet supported so this definition is a placeholder until
+ * we do support them.
+ */
+struct stp_remote_node_context {
+	/**
+	 * Placeholder data for the STP remote node.
+	 */
+	u32 data[8];
+
+};
+
+/**
+ * This union combines the SAS and SATA remote node definitions.
+ *
+ * union scu_remote_node_context
+ */
+union scu_remote_node_context {
+	/**
+	 * SSP Remote Node
+	 */
+	struct ssp_remote_node_context ssp;
+
+	/**
+	 * STP Remote Node
+	 */
+	struct stp_remote_node_context stp;
+
+};
+
+#endif /* __SCU_REMOTE_NODE_CONTEXT_HEADER__ */
diff -druN linux-2.6.39-libre/drivers/scsi/isci/scu_task_context.h linux-3.0-rc7-libre/drivers/scsi/isci/scu_task_context.h
--- linux-2.6.39-libre/drivers/scsi/isci/scu_task_context.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/scsi/isci/scu_task_context.h	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,942 @@
+/*
+ * This file is provided under a dual BSD/GPLv2 license.  When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * The full GNU General Public License is included in this distribution
+ * in the file called LICENSE.GPL.
+ *
+ * BSD LICENSE
+ *
+ * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in
+ *     the documentation and/or other materials provided with the
+ *     distribution.
+ *   * Neither the name of Intel Corporation nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _SCU_TASK_CONTEXT_H_
+#define _SCU_TASK_CONTEXT_H_
+
+/**
+ * This file contains the structures and constants for the SCU hardware task
+ *    context.
+ *
+ *
+ */
+
+
+/**
+ * enum scu_ssp_task_type - This enumberation defines the various SSP task
+ *    types the SCU hardware will accept. The definition for the various task
+ *    types the SCU hardware will accept can be found in the DS specification.
+ *
+ *
+ */
+typedef enum {
+	SCU_TASK_TYPE_IOREAD,           /* /< IO READ direction or no direction */
+	SCU_TASK_TYPE_IOWRITE,          /* /< IO Write direction */
+	SCU_TASK_TYPE_SMP_REQUEST,      /* /< SMP Request type */
+	SCU_TASK_TYPE_RESPONSE,         /* /< Driver generated response frame (targt mode) */
+	SCU_TASK_TYPE_RAW_FRAME,        /* /< Raw frame request type */
+	SCU_TASK_TYPE_PRIMITIVE         /* /< Request for a primitive to be transmitted */
+} scu_ssp_task_type;
+
+/**
+ * enum scu_sata_task_type - This enumeration defines the various SATA task
+ *    types the SCU hardware will accept. The definition for the various task
+ *    types the SCU hardware will accept can be found in the DS specification.
+ *
+ *
+ */
+typedef enum {
+	SCU_TASK_TYPE_DMA_IN,           /* /< Read request */
+	SCU_TASK_TYPE_FPDMAQ_READ,      /* /< NCQ read request */
+	SCU_TASK_TYPE_PACKET_DMA_IN,    /* /< Packet read request */
+	SCU_TASK_TYPE_SATA_RAW_FRAME,   /* /< Raw frame request */
+	RESERVED_4,
+	RESERVED_5,
+	RESERVED_6,
+	RESERVED_7,
+	SCU_TASK_TYPE_DMA_OUT,          /* /< Write request */
+	SCU_TASK_TYPE_FPDMAQ_WRITE,     /* /< NCQ write Request */
+	SCU_TASK_TYPE_PACKET_DMA_OUT    /* /< Packet write request */
+} scu_sata_task_type;
+
+
+/**
+ *
+ *
+ * SCU_CONTEXT_TYPE
+ */
+#define SCU_TASK_CONTEXT_TYPE  0
+#define SCU_RNC_CONTEXT_TYPE   1
+
+/**
+ *
+ *
+ * SCU_TASK_CONTEXT_VALIDITY
+ */
+#define SCU_TASK_CONTEXT_INVALID          0
+#define SCU_TASK_CONTEXT_VALID            1
+
+/**
+ *
+ *
+ * SCU_COMMAND_CODE
+ */
+#define SCU_COMMAND_CODE_INITIATOR_NEW_TASK   0
+#define SCU_COMMAND_CODE_ACTIVE_TASK          1
+#define SCU_COMMAND_CODE_PRIMITIVE_SEQ_TASK   2
+#define SCU_COMMAND_CODE_TARGET_RAW_FRAMES    3
+
+/**
+ *
+ *
+ * SCU_TASK_PRIORITY
+ */
+/**
+ *
+ *
+ * This priority is used when there is no priority request for this request.
+ */
+#define SCU_TASK_PRIORITY_NORMAL          0
+
+/**
+ *
+ *
+ * This priority indicates that the task should be scheduled to the head of the
+ * queue.  The task will NOT be executed if the TX is suspended for the remote
+ * node.
+ */
+#define SCU_TASK_PRIORITY_HEAD_OF_Q       1
+
+/**
+ *
+ *
+ * This priority indicates that the task will be executed before all
+ * SCU_TASK_PRIORITY_NORMAL and SCU_TASK_PRIORITY_HEAD_OF_Q tasks. The task
+ * WILL be executed if the TX is suspended for the remote node.
+ */
+#define SCU_TASK_PRIORITY_HIGH            2
+
+/**
+ *
+ *
+ * This task priority is reserved and should not be used.
+ */
+#define SCU_TASK_PRIORITY_RESERVED        3
+
+#define SCU_TASK_INITIATOR_MODE           1
+#define SCU_TASK_TARGET_MODE              0
+
+#define SCU_TASK_REGULAR                  0
+#define SCU_TASK_ABORTED                  1
+
+/* direction bit defintion */
+/**
+ *
+ *
+ * SATA_DIRECTION
+ */
+#define SCU_SATA_WRITE_DATA_DIRECTION     0
+#define SCU_SATA_READ_DATA_DIRECTION      1
+
+/**
+ *
+ *
+ * SCU_COMMAND_CONTEXT_MACROS These macros provide the mask and shift
+ * operations to construct the various SCU commands
+ */
+#define SCU_CONTEXT_COMMAND_REQUEST_TYPE_SHIFT           21
+#define SCU_CONTEXT_COMMAND_REQUEST_TYPE_MASK            0x00E00000
+#define scu_get_command_request_type(x)	\
+	((x) & SCU_CONTEXT_COMMAND_REQUEST_TYPE_MASK)
+
+#define SCU_CONTEXT_COMMAND_REQUEST_SUBTYPE_SHIFT        18
+#define SCU_CONTEXT_COMMAND_REQUEST_SUBTYPE_MASK         0x001C0000
+#define scu_get_command_request_subtype(x) \
+	((x) & SCU_CONTEXT_COMMAND_REQUEST_SUBTYPE_MASK)
+
+#define SCU_CONTEXT_COMMAND_REQUEST_FULLTYPE_MASK	 \
+	(\
+		SCU_CONTEXT_COMMAND_REQUEST_TYPE_MASK		  \
+		| SCU_CONTEXT_COMMAND_REQUEST_SUBTYPE_MASK	    \
+	)
+#define scu_get_command_request_full_type(x) \
+	((x) & SCU_CONTEXT_COMMAND_REQUEST_FULLTYPE_MASK)
+
+#define SCU_CONTEXT_COMMAND_PROTOCOL_ENGINE_GROUP_SHIFT  16
+#define SCU_CONTEXT_COMMAND_PROTOCOL_ENGINE_GROUP_MASK   0x00010000
+#define scu_get_command_protocl_engine_group(x)	\
+	((x) & SCU_CONTEXT_COMMAND_PROTOCOL_ENGINE_GROUP_MASK)
+
+#define SCU_CONTEXT_COMMAND_LOGICAL_PORT_SHIFT           12
+#define SCU_CONTEXT_COMMAND_LOGICAL_PORT_MASK            0x00007000
+#define scu_get_command_reqeust_logical_port(x)	\
+	((x) & SCU_CONTEXT_COMMAND_LOGICAL_PORT_MASK)
+
+
+#define MAKE_SCU_CONTEXT_COMMAND_TYPE(type) \
+	((u32)(type) << SCU_CONTEXT_COMMAND_REQUEST_TYPE_SHIFT)
+
+/**
+ * MAKE_SCU_CONTEXT_COMMAND_TYPE() -
+ *
+ * SCU_COMMAND_TYPES These constants provide the grouping of the different SCU
+ * command types.
+ */
+#define SCU_CONTEXT_COMMAND_REQUEST_TYPE_POST_TC    MAKE_SCU_CONTEXT_COMMAND_TYPE(0)
+#define SCU_CONTEXT_COMMAND_REQUEST_TYPE_DUMP_TC    MAKE_SCU_CONTEXT_COMMAND_TYPE(1)
+#define SCU_CONTEXT_COMMAND_REQUEST_TYPE_POST_RNC   MAKE_SCU_CONTEXT_COMMAND_TYPE(2)
+#define SCU_CONTEXT_COMMAND_REQUEST_TYPE_DUMP_RNC   MAKE_SCU_CONTEXT_COMMAND_TYPE(3)
+#define SCU_CONTEXT_COMMAND_REQUEST_TYPE_OTHER_RNC  MAKE_SCU_CONTEXT_COMMAND_TYPE(6)
+
+#define MAKE_SCU_CONTEXT_COMMAND_REQUEST(type, command)	\
+	((type) | ((command) << SCU_CONTEXT_COMMAND_REQUEST_SUBTYPE_SHIFT))
+
+/**
+ *
+ *
+ * SCU_REQUEST_TYPES These constants are the various request types that can be
+ * posted to the SCU hardware.
+ */
+#define SCU_CONTEXT_COMMAND_REQUST_POST_TC \
+	(MAKE_SCU_CONTEXT_COMMAND_REQUEST(SCU_CONTEXT_COMMAND_REQUEST_TYPE_POST_TC, 0))
+
+#define SCU_CONTEXT_COMMAND_REQUEST_POST_TC_ABORT \
+	(MAKE_SCU_CONTEXT_COMMAND_REQUEST(SCU_CONTEXT_COMMAND_REQUEST_TYPE_POST_TC, 1))
+
+#define SCU_CONTEXT_COMMAND_REQUST_DUMP_TC \
+	(MAKE_SCU_CONTEXT_COMMAND_REQUEST(SCU_CONTEXT_COMMAND_REQUEST_TYPE_DUMP_TC, 0))
+
+#define SCU_CONTEXT_COMMAND_POST_RNC_32	\
+	(MAKE_SCU_CONTEXT_COMMAND_REQUEST(SCU_CONTEXT_COMMAND_REQUEST_TYPE_POST_RNC, 0))
+
+#define SCU_CONTEXT_COMMAND_POST_RNC_96	\
+	(MAKE_SCU_CONTEXT_COMMAND_REQUEST(SCU_CONTEXT_COMMAND_REQUEST_TYPE_POST_RNC, 1))
+
+#define SCU_CONTEXT_COMMAND_POST_RNC_INVALIDATE	\
+	(MAKE_SCU_CONTEXT_COMMAND_REQUEST(SCU_CONTEXT_COMMAND_REQUEST_TYPE_POST_RNC, 2))
+
+#define SCU_CONTEXT_COMMAND_DUMP_RNC_32	\
+	(MAKE_SCU_CONTEXT_COMMAND_REQUEST(SCU_CONTEXT_COMMAND_REQUEST_TYPE_DUMP_RNC, 0))
+
+#define SCU_CONTEXT_COMMAND_DUMP_RNC_96	\
+	(MAKE_SCU_CONTEXT_COMMAND_REQUEST(SCU_CONTEXT_COMMAND_REQUEST_TYPE_DUMP_RNC, 1))
+
+#define SCU_CONTEXT_COMMAND_POST_RNC_SUSPEND_TX	\
+	(MAKE_SCU_CONTEXT_COMMAND_REQUEST(SCU_CONTEXT_COMMAND_REQUEST_TYPE_OTHER_RNC, 0))
+
+#define SCU_CONTEXT_COMMAND_POST_RNC_SUSPEND_TX_RX \
+	(MAKE_SCU_CONTEXT_COMMAND_REQUEST(SCU_CONTEXT_COMMAND_REQUEST_TYPE_OTHER_RNC, 1))
+
+#define SCU_CONTEXT_COMMAND_POST_RNC_RESUME \
+	(MAKE_SCU_CONTEXT_COMMAND_REQUEST(SCU_CONTEXT_COMMAND_REQUEST_TYPE_OTHER_RNC, 2))
+
+#define SCU_CONTEXT_IT_NEXUS_LOSS_TIMER_ENABLE \
+	(MAKE_SCU_CONTEXT_COMMAND_REQUEST(SCU_CONTEXT_COMMAND_REQUEST_TYPE_OTHER_RNC, 3))
+
+#define SCU_CONTEXT_IT_NEXUS_LOSS_TIMER_DISABLE	\
+	(MAKE_SCU_CONTEXT_COMMAND_REQUEST(SCU_CONTEXT_COMMAND_REQUEST_TYPE_OTHER_RNC, 4))
+
+/**
+ *
+ *
+ * SCU_TASK_CONTEXT_PROTOCOL SCU Task context protocol types this is uesd to
+ * program the SCU Task context protocol field in word 0x00.
+ */
+#define SCU_TASK_CONTEXT_PROTOCOL_SMP    0x00
+#define SCU_TASK_CONTEXT_PROTOCOL_SSP    0x01
+#define SCU_TASK_CONTEXT_PROTOCOL_STP    0x02
+#define SCU_TASK_CONTEXT_PROTOCOL_NONE   0x07
+
+/**
+ * struct ssp_task_context - This is the SCU hardware definition for an SSP
+ *    request.
+ *
+ *
+ */
+struct ssp_task_context {
+	/* OFFSET 0x18 */
+	u32 reserved00:24;
+	u32 frame_type:8;
+
+	/* OFFSET 0x1C */
+	u32 reserved01;
+
+	/* OFFSET 0x20 */
+	u32 fill_bytes:2;
+	u32 reserved02:6;
+	u32 changing_data_pointer:1;
+	u32 retransmit:1;
+	u32 retry_data_frame:1;
+	u32 tlr_control:2;
+	u32 reserved03:19;
+
+	/* OFFSET 0x24 */
+	u32 uiRsvd4;
+
+	/* OFFSET 0x28 */
+	u32 target_port_transfer_tag:16;
+	u32 tag:16;
+
+	/* OFFSET 0x2C */
+	u32 data_offset;
+};
+
+/**
+ * struct stp_task_context - This is the SCU hardware definition for an STP
+ *    request.
+ *
+ *
+ */
+struct stp_task_context {
+	/* OFFSET 0x18 */
+	u32 fis_type:8;
+	u32 pm_port:4;
+	u32 reserved0:3;
+	u32 control:1;
+	u32 command:8;
+	u32 features:8;
+
+	/* OFFSET 0x1C */
+	u32 reserved1;
+
+	/* OFFSET 0x20 */
+	u32 reserved2;
+
+	/* OFFSET 0x24 */
+	u32 reserved3;
+
+	/* OFFSET 0x28 */
+	u32 ncq_tag:5;
+	u32 reserved4:27;
+
+	/* OFFSET 0x2C */
+	u32 data_offset; /* TODO: What is this used for? */
+};
+
+/**
+ * struct smp_task_context - This is the SCU hardware definition for an SMP
+ *    request.
+ *
+ *
+ */
+struct smp_task_context {
+	/* OFFSET 0x18 */
+	u32 response_length:8;
+	u32 function_result:8;
+	u32 function:8;
+	u32 frame_type:8;
+
+	/* OFFSET 0x1C */
+	u32 smp_response_ufi:12;
+	u32 reserved1:20;
+
+	/* OFFSET 0x20 */
+	u32 reserved2;
+
+	/* OFFSET 0x24 */
+	u32 reserved3;
+
+	/* OFFSET 0x28 */
+	u32 reserved4;
+
+	/* OFFSET 0x2C */
+	u32 reserved5;
+};
+
+/**
+ * struct primitive_task_context - This is the SCU hardware definition used
+ *    when the driver wants to send a primitive on the link.
+ *
+ *
+ */
+struct primitive_task_context {
+	/* OFFSET 0x18 */
+	/**
+	 * This field is the control word and it must be 0.
+	 */
+	u32 control; /* /< must be set to 0 */
+
+	/* OFFSET 0x1C */
+	/**
+	 * This field specifies the primitive that is to be transmitted.
+	 */
+	u32 sequence;
+
+	/* OFFSET 0x20 */
+	u32 reserved0;
+
+	/* OFFSET 0x24 */
+	u32 reserved1;
+
+	/* OFFSET 0x28 */
+	u32 reserved2;
+
+	/* OFFSET 0x2C */
+	u32 reserved3;
+};
+
+/**
+ * The union of the protocols that can be selected in the SCU task context
+ *    field.
+ *
+ * protocol_context
+ */
+union protocol_context {
+	struct ssp_task_context ssp;
+	struct stp_task_context stp;
+	struct smp_task_context smp;
+	struct primitive_task_context primitive;
+	u32 words[6];
+};
+
+/**
+ * struct scu_sgl_element - This structure represents a single SCU defined SGL
+ *    element. SCU SGLs contain a 64 bit address with the maximum data transfer
+ *    being 24 bits in size.  The SGL can not cross a 4GB boundary.
+ *
+ * struct scu_sgl_element
+ */
+struct scu_sgl_element {
+	/**
+	 * This field is the upper 32 bits of the 64 bit physical address.
+	 */
+	u32 address_upper;
+
+	/**
+	 * This field is the lower 32 bits of the 64 bit physical address.
+	 */
+	u32 address_lower;
+
+	/**
+	 * This field is the number of bytes to transfer.
+	 */
+	u32 length:24;
+
+	/**
+	 * This field is the address modifier to be used when a virtual function is
+	 * requesting a data transfer.
+	 */
+	u32 address_modifier:8;
+
+};
+
+#define SCU_SGL_ELEMENT_PAIR_A   0
+#define SCU_SGL_ELEMENT_PAIR_B   1
+
+/**
+ * struct scu_sgl_element_pair - This structure is the SCU hardware definition
+ *    of a pair of SGL elements. The SCU hardware always works on SGL pairs.
+ *    They are refered to in the DS specification as SGL A and SGL B.  Each SGL
+ *    pair is followed by the address of the next pair.
+ *
+ *
+ */
+struct scu_sgl_element_pair {
+	/* OFFSET 0x60-0x68 */
+	/**
+	 * This field is the SGL element A of the SGL pair.
+	 */
+	struct scu_sgl_element A;
+
+	/* OFFSET 0x6C-0x74 */
+	/**
+	 * This field is the SGL element B of the SGL pair.
+	 */
+	struct scu_sgl_element B;
+
+	/* OFFSET 0x78-0x7C */
+	/**
+	 * This field is the upper 32 bits of the 64 bit address to the next SGL
+	 * element pair.
+	 */
+	u32 next_pair_upper;
+
+	/**
+	 * This field is the lower 32 bits of the 64 bit address to the next SGL
+	 * element pair.
+	 */
+	u32 next_pair_lower;
+
+};
+
+/**
+ * struct transport_snapshot - This structure is the SCU hardware scratch area
+ *    for the task context. This is set to 0 by the driver but can be read by
+ *    issuing a dump TC request to the SCU.
+ *
+ *
+ */
+struct transport_snapshot {
+	/* OFFSET 0x48 */
+	u32 xfer_rdy_write_data_length;
+
+	/* OFFSET 0x4C */
+	u32 data_offset;
+
+	/* OFFSET 0x50 */
+	u32 data_transfer_size:24;
+	u32 reserved_50_0:8;
+
+	/* OFFSET 0x54 */
+	u32 next_initiator_write_data_offset;
+
+	/* OFFSET 0x58 */
+	u32 next_initiator_write_data_xfer_size:24;
+	u32 reserved_58_0:8;
+};
+
+/**
+ * struct scu_task_context - This structure defines the contents of the SCU
+ *    silicon task context. It lays out all of the fields according to the
+ *    expected order and location for the Storage Controller unit.
+ *
+ *
+ */
+struct scu_task_context {
+	/* OFFSET 0x00 ------ */
+	/**
+	 * This field must be encoded to one of the valid SCU task priority values
+	 *    - SCU_TASK_PRIORITY_NORMAL
+	 *    - SCU_TASK_PRIORITY_HEAD_OF_Q
+	 *    - SCU_TASK_PRIORITY_HIGH
+	 */
+	u32 priority:2;
+
+	/**
+	 * This field must be set to true if this is an initiator generated request.
+	 * Until target mode is supported all task requests are initiator requests.
+	 */
+	u32 initiator_request:1;
+
+	/**
+	 * This field must be set to one of the valid connection rates valid values
+	 * are 0x8, 0x9, and 0xA.
+	 */
+	u32 connection_rate:4;
+
+	/**
+	 * This field muse be programed when generating an SMP response since the SMP
+	 * connection remains open until the SMP response is generated.
+	 */
+	u32 protocol_engine_index:3;
+
+	/**
+	 * This field must contain the logical port for the task request.
+	 */
+	u32 logical_port_index:3;
+
+	/**
+	 * This field must be set to one of the SCU_TASK_CONTEXT_PROTOCOL values
+	 *    - SCU_TASK_CONTEXT_PROTOCOL_SMP
+	 *    - SCU_TASK_CONTEXT_PROTOCOL_SSP
+	 *    - SCU_TASK_CONTEXT_PROTOCOL_STP
+	 *    - SCU_TASK_CONTEXT_PROTOCOL_NONE
+	 */
+	u32 protocol_type:3;
+
+	/**
+	 * This filed must be set to the TCi allocated for this task
+	 */
+	u32 task_index:12;
+
+	/**
+	 * This field is reserved and must be set to 0x00
+	 */
+	u32 reserved_00_0:1;
+
+	/**
+	 * For a normal task request this must be set to 0.  If this is an abort of
+	 * this task request it must be set to 1.
+	 */
+	u32 abort:1;
+
+	/**
+	 * This field must be set to true for the SCU hardware to process the task.
+	 */
+	u32 valid:1;
+
+	/**
+	 * This field must be set to SCU_TASK_CONTEXT_TYPE
+	 */
+	u32 context_type:1;
+
+	/* OFFSET 0x04 */
+	/**
+	 * This field contains the RNi that is the target of this request.
+	 */
+	u32 remote_node_index:12;
+
+	/**
+	 * This field is programmed if this is a mirrored request, which we are not
+	 * using, in which case it is the RNi for the mirrored target.
+	 */
+	u32 mirrored_node_index:12;
+
+	/**
+	 * This field is programmed with the direction of the SATA reqeust
+	 *    - SCU_SATA_WRITE_DATA_DIRECTION
+	 *    - SCU_SATA_READ_DATA_DIRECTION
+	 */
+	u32 sata_direction:1;
+
+	/**
+	 * This field is programmsed with one of the following SCU_COMMAND_CODE
+	 *    - SCU_COMMAND_CODE_INITIATOR_NEW_TASK
+	 *    - SCU_COMMAND_CODE_ACTIVE_TASK
+	 *    - SCU_COMMAND_CODE_PRIMITIVE_SEQ_TASK
+	 *    - SCU_COMMAND_CODE_TARGET_RAW_FRAMES
+	 */
+	u32 command_code:2;
+
+	/**
+	 * This field is set to true if the remote node should be suspended.
+	 * This bit is only valid for SSP & SMP target devices.
+	 */
+	u32 suspend_node:1;
+
+	/**
+	 * This field is programmed with one of the following command type codes
+	 *
+	 * For SAS requests use the scu_ssp_task_type
+	 *    - SCU_TASK_TYPE_IOREAD
+	 *    - SCU_TASK_TYPE_IOWRITE
+	 *    - SCU_TASK_TYPE_SMP_REQUEST
+	 *    - SCU_TASK_TYPE_RESPONSE
+	 *    - SCU_TASK_TYPE_RAW_FRAME
+	 *    - SCU_TASK_TYPE_PRIMITIVE
+	 *
+	 * For SATA requests use the scu_sata_task_type
+	 *    - SCU_TASK_TYPE_DMA_IN
+	 *    - SCU_TASK_TYPE_FPDMAQ_READ
+	 *    - SCU_TASK_TYPE_PACKET_DMA_IN
+	 *    - SCU_TASK_TYPE_SATA_RAW_FRAME
+	 *    - SCU_TASK_TYPE_DMA_OUT
+	 *    - SCU_TASK_TYPE_FPDMAQ_WRITE
+	 *    - SCU_TASK_TYPE_PACKET_DMA_OUT
+	 */
+	u32 task_type:4;
+
+	/* OFFSET 0x08 */
+	/**
+	 * This field is reserved and the must be set to 0x00
+	 */
+	u32 link_layer_control:8; /* presently all reserved */
+
+	/**
+	 * This field is set to true when TLR is to be enabled
+	 */
+	u32 ssp_tlr_enable:1;
+
+	/**
+	 * This is field specifies if the SCU DMAs a response frame to host
+	 * memory for good response frames when operating in target mode.
+	 */
+	u32 dma_ssp_target_good_response:1;
+
+	/**
+	 * This field indicates if the SCU should DMA the response frame to
+	 * host memory.
+	 */
+	u32 do_not_dma_ssp_good_response:1;
+
+	/**
+	 * This field is set to true when strict ordering is to be enabled
+	 */
+	u32 strict_ordering:1;
+
+	/**
+	 * This field indicates the type of endianess to be utilized for the
+	 * frame.  command, task, and response frames utilized control_frame
+	 * set to 1.
+	 */
+	u32 control_frame:1;
+
+	/**
+	 * This field is reserved and the driver should set to 0x00
+	 */
+	u32 tl_control_reserved:3;
+
+	/**
+	 * This field is set to true when the SCU hardware task timeout control is to
+	 * be enabled
+	 */
+	u32 timeout_enable:1;
+
+	/**
+	 * This field is reserved and the driver should set it to 0x00
+	 */
+	u32 pts_control_reserved:7;
+
+	/**
+	 * This field should be set to true when block guard is to be enabled
+	 */
+	u32 block_guard_enable:1;
+
+	/**
+	 * This field is reserved and the driver should set to 0x00
+	 */
+	u32 sdma_control_reserved:7;
+
+	/* OFFSET 0x0C */
+	/**
+	 * This field is the address modifier for this io request it should be
+	 * programmed with the virtual function that is making the request.
+	 */
+	u32 address_modifier:16;
+
+	/**
+	 * @todo What we support mirrored SMP response frame?
+	 */
+	u32 mirrored_protocol_engine:3;  /* mirrored protocol Engine Index */
+
+	/**
+	 * If this is a mirrored request the logical port index for the mirrored RNi
+	 * must be programmed.
+	 */
+	u32 mirrored_logical_port:4;  /* mirrored local port index */
+
+	/**
+	 * This field is reserved and the driver must set it to 0x00
+	 */
+	u32 reserved_0C_0:8;
+
+	/**
+	 * This field must be set to true if the mirrored request processing is to be
+	 * enabled.
+	 */
+	u32 mirror_request_enable:1;  /* Mirrored request Enable */
+
+	/* OFFSET 0x10 */
+	/**
+	 * This field is the command iu length in dwords
+	 */
+	u32 ssp_command_iu_length:8;
+
+	/**
+	 * This is the target TLR enable bit it must be set to 0 when creatning the
+	 * task context.
+	 */
+	u32 xfer_ready_tlr_enable:1;
+
+	/**
+	 * This field is reserved and the driver must set it to 0x00
+	 */
+	u32 reserved_10_0:7;
+
+	/**
+	 * This is the maximum burst size that the SCU hardware will send in one
+	 * connection its value is (N x 512) and N must be a multiple of 2.  If the
+	 * value is 0x00 then maximum burst size is disabled.
+	 */
+	u32 ssp_max_burst_size:16;
+
+	/* OFFSET 0x14 */
+	/**
+	 * This filed is set to the number of bytes to be transfered in the request.
+	 */
+	u32 transfer_length_bytes:24; /* In terms of bytes */
+
+	/**
+	 * This field is reserved and the driver should set it to 0x00
+	 */
+	u32 reserved_14_0:8;
+
+	/* OFFSET 0x18-0x2C */
+	/**
+	 * This union provides for the protocol specif part of the SCU Task Context.
+	 */
+	union protocol_context type;
+
+	/* OFFSET 0x30-0x34 */
+	/**
+	 * This field is the upper 32 bits of the 64 bit physical address of the
+	 * command iu buffer
+	 */
+	u32 command_iu_upper;
+
+	/**
+	 * This field is the lower 32 bits of the 64 bit physical address of the
+	 * command iu buffer
+	 */
+	u32 command_iu_lower;
+
+	/* OFFSET 0x38-0x3C */
+	/**
+	 * This field is the upper 32 bits of the 64 bit physical address of the
+	 * response iu buffer
+	 */
+	u32 response_iu_upper;
+
+	/**
+	 * This field is the lower 32 bits of the 64 bit physical address of the
+	 * response iu buffer
+	 */
+	u32 response_iu_lower;
+
+	/* OFFSET 0x40 */
+	/**
+	 * This field is set to the task phase of the SCU hardware. The driver must
+	 * set this to 0x01
+	 */
+	u32 task_phase:8;
+
+	/**
+	 * This field is set to the transport layer task status.  The driver must set
+	 * this to 0x00
+	 */
+	u32 task_status:8;
+
+	/**
+	 * This field is used during initiator write TLR
+	 */
+	u32 previous_extended_tag:4;
+
+	/**
+	 * This field is set the maximum number of retries for a STP non-data FIS
+	 */
+	u32 stp_retry_count:2;
+
+	/**
+	 * This field is reserved and the driver must set it to 0x00
+	 */
+	u32 reserved_40_1:2;
+
+	/**
+	 * This field is used by the SCU TL to determine when to take a snapshot when
+	 * tranmitting read data frames.
+	 *    - 0x00 The entire IO
+	 *    - 0x01 32k
+	 *    - 0x02 64k
+	 *    - 0x04 128k
+	 *    - 0x08 256k
+	 */
+	u32 ssp_tlr_threshold:4;
+
+	/**
+	 * This field is reserved and the driver must set it to 0x00
+	 */
+	u32 reserved_40_2:4;
+
+	/* OFFSET 0x44 */
+	u32 write_data_length; /* read only set to 0 */
+
+	/* OFFSET 0x48-0x58 */
+	struct transport_snapshot snapshot; /* read only set to 0 */
+
+	/* OFFSET 0x5C */
+	u32 block_protection_enable:1;
+	u32 block_size:2;
+	u32 block_protection_function:2;
+	u32 reserved_5C_0:9;
+	u32 active_sgl_element:2;  /* read only set to 0 */
+	u32 sgl_exhausted:1;  /* read only set to 0 */
+	u32 payload_data_transfer_error:4;  /* read only set to 0 */
+	u32 frame_buffer_offset:11; /* read only set to 0 */
+
+	/* OFFSET 0x60-0x7C */
+	/**
+	 * This field is the first SGL element pair found in the TC data structure.
+	 */
+	struct scu_sgl_element_pair sgl_pair_ab;
+	/* OFFSET 0x80-0x9C */
+	/**
+	 * This field is the second SGL element pair found in the TC data structure.
+	 */
+	struct scu_sgl_element_pair sgl_pair_cd;
+
+	/* OFFSET 0xA0-BC */
+	struct scu_sgl_element_pair sgl_snapshot_ac;
+
+	/* OFFSET 0xC0 */
+	u32 active_sgl_element_pair; /* read only set to 0 */
+
+	/* OFFSET 0xC4-0xCC */
+	u32 reserved_C4_CC[3];
+
+	/* OFFSET 0xD0 */
+	u32 intermediate_crc_value:16;
+	u32 initial_crc_seed:16;
+
+	/* OFFSET 0xD4 */
+	u32 application_tag_for_verify:16;
+	u32 application_tag_for_generate:16;
+
+	/* OFFSET 0xD8 */
+	u32 reference_tag_seed_for_verify_function;
+
+	/* OFFSET 0xDC */
+	u32 reserved_DC;
+
+	/* OFFSET 0xE0 */
+	u32 reserved_E0_0:16;
+	u32 application_tag_mask_for_generate:16;
+
+	/* OFFSET 0xE4 */
+	u32 block_protection_control:16;
+	u32 application_tag_mask_for_verify:16;
+
+	/* OFFSET 0xE8 */
+	u32 block_protection_error:8;
+	u32 reserved_E8_0:24;
+
+	/* OFFSET 0xEC */
+	u32 reference_tag_seed_for_verify;
+
+	/* OFFSET 0xF0 */
+	u32 intermediate_crc_valid_snapshot:16;
+	u32 reserved_F0_0:16;
+
+	/* OFFSET 0xF4 */
+	u32 reference_tag_seed_for_verify_function_snapshot;
+
+	/* OFFSET 0xF8 */
+	u32 snapshot_of_reserved_dword_DC_of_tc;
+
+	/* OFFSET 0xFC */
+	u32 reference_tag_seed_for_generate_function_snapshot;
+
+};
+
+#endif /* _SCU_TASK_CONTEXT_H_ */
diff -druN linux-2.6.39-libre/drivers/scsi/isci/task.c linux-3.0-rc7-libre/drivers/scsi/isci/task.c
--- linux-2.6.39-libre/drivers/scsi/isci/task.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/scsi/isci/task.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,1676 @@
+/*
+ * This file is provided under a dual BSD/GPLv2 license.  When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * The full GNU General Public License is included in this distribution
+ * in the file called LICENSE.GPL.
+ *
+ * BSD LICENSE
+ *
+ * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in
+ *     the documentation and/or other materials provided with the
+ *     distribution.
+ *   * Neither the name of Intel Corporation nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <linux/completion.h>
+#include <linux/irqflags.h>
+#include "sas.h"
+#include <scsi/libsas.h>
+#include "remote_device.h"
+#include "remote_node_context.h"
+#include "isci.h"
+#include "request.h"
+#include "task.h"
+#include "host.h"
+
+/**
+* isci_task_refuse() - complete the request to the upper layer driver in
+*     the case where an I/O needs to be completed back in the submit path.
+* @ihost: host on which the the request was queued
+* @task: request to complete
+* @response: response code for the completed task.
+* @status: status code for the completed task.
+*
+*/
+static void isci_task_refuse(struct isci_host *ihost, struct sas_task *task,
+			     enum service_response response,
+			     enum exec_status status)
+
+{
+	enum isci_completion_selection disposition;
+
+	disposition = isci_perform_normal_io_completion;
+	disposition = isci_task_set_completion_status(task, response, status,
+						      disposition);
+
+	/* Tasks aborted specifically by a call to the lldd_abort_task
+	 * function should not be completed to the host in the regular path.
+	 */
+	switch (disposition) {
+	case isci_perform_normal_io_completion:
+		/* Normal notification (task_done) */
+		dev_dbg(&ihost->pdev->dev,
+			"%s: Normal - task = %p, response=%d, "
+			"status=%d\n",
+			__func__, task, response, status);
+
+		task->lldd_task = NULL;
+
+		isci_execpath_callback(ihost, task, task->task_done);
+		break;
+
+	case isci_perform_aborted_io_completion:
+		/*
+		 * No notification because this request is already in the
+		 * abort path.
+		 */
+		dev_dbg(&ihost->pdev->dev,
+			"%s: Aborted - task = %p, response=%d, "
+			"status=%d\n",
+			__func__, task, response, status);
+		break;
+
+	case isci_perform_error_io_completion:
+		/* Use sas_task_abort */
+		dev_dbg(&ihost->pdev->dev,
+			"%s: Error - task = %p, response=%d, "
+			"status=%d\n",
+			__func__, task, response, status);
+
+		isci_execpath_callback(ihost, task, sas_task_abort);
+		break;
+
+	default:
+		dev_dbg(&ihost->pdev->dev,
+			"%s: isci task notification default case!",
+			__func__);
+		sas_task_abort(task);
+		break;
+	}
+}
+
+#define for_each_sas_task(num, task) \
+	for (; num > 0; num--,\
+	     task = list_entry(task->list.next, struct sas_task, list))
+
+
+static inline int isci_device_io_ready(struct isci_remote_device *idev,
+				       struct sas_task *task)
+{
+	return idev ? test_bit(IDEV_IO_READY, &idev->flags) ||
+		      (test_bit(IDEV_IO_NCQERROR, &idev->flags) &&
+		       isci_task_is_ncq_recovery(task))
+		    : 0;
+}
+/**
+ * isci_task_execute_task() - This function is one of the SAS Domain Template
+ *    functions. This function is called by libsas to send a task down to
+ *    hardware.
+ * @task: This parameter specifies the SAS task to send.
+ * @num: This parameter specifies the number of tasks to queue.
+ * @gfp_flags: This parameter specifies the context of this call.
+ *
+ * status, zero indicates success.
+ */
+int isci_task_execute_task(struct sas_task *task, int num, gfp_t gfp_flags)
+{
+	struct isci_host *ihost = dev_to_ihost(task->dev);
+	struct isci_remote_device *idev;
+	unsigned long flags;
+	bool io_ready;
+	u16 tag;
+
+	dev_dbg(&ihost->pdev->dev, "%s: num=%d\n", __func__, num);
+
+	for_each_sas_task(num, task) {
+		enum sci_status status = SCI_FAILURE;
+
+		spin_lock_irqsave(&ihost->scic_lock, flags);
+		idev = isci_lookup_device(task->dev);
+		io_ready = isci_device_io_ready(idev, task);
+		tag = isci_alloc_tag(ihost);
+		spin_unlock_irqrestore(&ihost->scic_lock, flags);
+
+		dev_dbg(&ihost->pdev->dev,
+			"task: %p, num: %d dev: %p idev: %p:%#lx cmd = %p\n",
+			task, num, task->dev, idev, idev ? idev->flags : 0,
+			task->uldd_task);
+
+		if (!idev) {
+			isci_task_refuse(ihost, task, SAS_TASK_UNDELIVERED,
+					 SAS_DEVICE_UNKNOWN);
+		} else if (!io_ready || tag == SCI_CONTROLLER_INVALID_IO_TAG) {
+			/* Indicate QUEUE_FULL so that the scsi midlayer
+			 * retries.
+			  */
+			isci_task_refuse(ihost, task, SAS_TASK_COMPLETE,
+					 SAS_QUEUE_FULL);
+		} else {
+			/* There is a device and it's ready for I/O. */
+			spin_lock_irqsave(&task->task_state_lock, flags);
+
+			if (task->task_state_flags & SAS_TASK_STATE_ABORTED) {
+				/* The I/O was aborted. */
+				spin_unlock_irqrestore(&task->task_state_lock,
+						       flags);
+
+				isci_task_refuse(ihost, task,
+						 SAS_TASK_UNDELIVERED,
+						 SAM_STAT_TASK_ABORTED);
+			} else {
+				task->task_state_flags |= SAS_TASK_AT_INITIATOR;
+				spin_unlock_irqrestore(&task->task_state_lock, flags);
+
+				/* build and send the request. */
+				status = isci_request_execute(ihost, idev, task, tag);
+
+				if (status != SCI_SUCCESS) {
+
+					spin_lock_irqsave(&task->task_state_lock, flags);
+					/* Did not really start this command. */
+					task->task_state_flags &= ~SAS_TASK_AT_INITIATOR;
+					spin_unlock_irqrestore(&task->task_state_lock, flags);
+
+					/* Indicate QUEUE_FULL so that the scsi
+					* midlayer retries. if the request
+					* failed for remote device reasons,
+					* it gets returned as
+					* SAS_TASK_UNDELIVERED next time
+					* through.
+					*/
+					isci_task_refuse(ihost, task,
+							 SAS_TASK_COMPLETE,
+							 SAS_QUEUE_FULL);
+				}
+			}
+		}
+		if (status != SCI_SUCCESS && tag != SCI_CONTROLLER_INVALID_IO_TAG) {
+			spin_lock_irqsave(&ihost->scic_lock, flags);
+			/* command never hit the device, so just free
+			 * the tci and skip the sequence increment
+			 */
+			isci_tci_free(ihost, ISCI_TAG_TCI(tag));
+			spin_unlock_irqrestore(&ihost->scic_lock, flags);
+		}
+		isci_put_device(idev);
+	}
+	return 0;
+}
+
+static enum sci_status isci_sata_management_task_request_build(struct isci_request *ireq)
+{
+	struct isci_tmf *isci_tmf;
+	enum sci_status status;
+
+	if (tmf_task != ireq->ttype)
+		return SCI_FAILURE;
+
+	isci_tmf = isci_request_access_tmf(ireq);
+
+	switch (isci_tmf->tmf_code) {
+
+	case isci_tmf_sata_srst_high:
+	case isci_tmf_sata_srst_low: {
+		struct host_to_dev_fis *fis = &ireq->stp.cmd;
+
+		memset(fis, 0, sizeof(*fis));
+
+		fis->fis_type  =  0x27;
+		fis->flags     &= ~0x80;
+		fis->flags     &= 0xF0;
+		if (isci_tmf->tmf_code == isci_tmf_sata_srst_high)
+			fis->control |= ATA_SRST;
+		else
+			fis->control &= ~ATA_SRST;
+		break;
+	}
+	/* other management commnd go here... */
+	default:
+		return SCI_FAILURE;
+	}
+
+	/* core builds the protocol specific request
+	 *  based on the h2d fis.
+	 */
+	status = sci_task_request_construct_sata(ireq);
+
+	return status;
+}
+
+static struct isci_request *isci_task_request_build(struct isci_host *ihost,
+						    struct isci_remote_device *idev,
+						    u16 tag, struct isci_tmf *isci_tmf)
+{
+	enum sci_status status = SCI_FAILURE;
+	struct isci_request *ireq = NULL;
+	struct domain_device *dev;
+
+	dev_dbg(&ihost->pdev->dev,
+		"%s: isci_tmf = %p\n", __func__, isci_tmf);
+
+	dev = idev->domain_dev;
+
+	/* do common allocation and init of request object. */
+	ireq = isci_tmf_request_from_tag(ihost, isci_tmf, tag);
+	if (!ireq)
+		return NULL;
+
+	/* let the core do it's construct. */
+	status = sci_task_request_construct(ihost, idev, tag,
+					     ireq);
+
+	if (status != SCI_SUCCESS) {
+		dev_warn(&ihost->pdev->dev,
+			 "%s: sci_task_request_construct failed - "
+			 "status = 0x%x\n",
+			 __func__,
+			 status);
+		return NULL;
+	}
+
+	/* XXX convert to get this from task->tproto like other drivers */
+	if (dev->dev_type == SAS_END_DEV) {
+		isci_tmf->proto = SAS_PROTOCOL_SSP;
+		status = sci_task_request_construct_ssp(ireq);
+		if (status != SCI_SUCCESS)
+			return NULL;
+	}
+
+	if (dev->dev_type == SATA_DEV || (dev->tproto & SAS_PROTOCOL_STP)) {
+		isci_tmf->proto = SAS_PROTOCOL_SATA;
+		status = isci_sata_management_task_request_build(ireq);
+
+		if (status != SCI_SUCCESS)
+			return NULL;
+	}
+	return ireq;
+}
+
+static int isci_task_execute_tmf(struct isci_host *ihost,
+				 struct isci_remote_device *idev,
+				 struct isci_tmf *tmf, unsigned long timeout_ms)
+{
+	DECLARE_COMPLETION_ONSTACK(completion);
+	enum sci_task_status status = SCI_TASK_FAILURE;
+	struct isci_request *ireq;
+	int ret = TMF_RESP_FUNC_FAILED;
+	unsigned long flags;
+	unsigned long timeleft;
+	u16 tag;
+
+	spin_lock_irqsave(&ihost->scic_lock, flags);
+	tag = isci_alloc_tag(ihost);
+	spin_unlock_irqrestore(&ihost->scic_lock, flags);
+
+	if (tag == SCI_CONTROLLER_INVALID_IO_TAG)
+		return ret;
+
+	/* sanity check, return TMF_RESP_FUNC_FAILED
+	 * if the device is not there and ready.
+	 */
+	if (!idev ||
+	    (!test_bit(IDEV_IO_READY, &idev->flags) &&
+	     !test_bit(IDEV_IO_NCQERROR, &idev->flags))) {
+		dev_dbg(&ihost->pdev->dev,
+			"%s: idev = %p not ready (%#lx)\n",
+			__func__,
+			idev, idev ? idev->flags : 0);
+		goto err_tci;
+	} else
+		dev_dbg(&ihost->pdev->dev,
+			"%s: idev = %p\n",
+			__func__, idev);
+
+	/* Assign the pointer to the TMF's completion kernel wait structure. */
+	tmf->complete = &completion;
+
+	ireq = isci_task_request_build(ihost, idev, tag, tmf);
+	if (!ireq)
+		goto err_tci;
+
+	spin_lock_irqsave(&ihost->scic_lock, flags);
+
+	/* start the TMF io. */
+	status = sci_controller_start_task(ihost, idev, ireq);
+
+	if (status != SCI_TASK_SUCCESS) {
+		dev_dbg(&ihost->pdev->dev,
+			 "%s: start_io failed - status = 0x%x, request = %p\n",
+			 __func__,
+			 status,
+			 ireq);
+		spin_unlock_irqrestore(&ihost->scic_lock, flags);
+		goto err_tci;
+	}
+
+	if (tmf->cb_state_func != NULL)
+		tmf->cb_state_func(isci_tmf_started, tmf, tmf->cb_data);
+
+	isci_request_change_state(ireq, started);
+
+	/* add the request to the remote device request list. */
+	list_add(&ireq->dev_node, &idev->reqs_in_process);
+
+	spin_unlock_irqrestore(&ihost->scic_lock, flags);
+
+	/* Wait for the TMF to complete, or a timeout. */
+	timeleft = wait_for_completion_timeout(&completion,
+					       msecs_to_jiffies(timeout_ms));
+
+	if (timeleft == 0) {
+		spin_lock_irqsave(&ihost->scic_lock, flags);
+
+		if (tmf->cb_state_func != NULL)
+			tmf->cb_state_func(isci_tmf_timed_out, tmf, tmf->cb_data);
+
+		sci_controller_terminate_request(ihost,
+						  idev,
+						  ireq);
+
+		spin_unlock_irqrestore(&ihost->scic_lock, flags);
+
+		wait_for_completion(tmf->complete);
+	}
+
+	isci_print_tmf(tmf);
+
+	if (tmf->status == SCI_SUCCESS)
+		ret =  TMF_RESP_FUNC_COMPLETE;
+	else if (tmf->status == SCI_FAILURE_IO_RESPONSE_VALID) {
+		dev_dbg(&ihost->pdev->dev,
+			"%s: tmf.status == "
+			"SCI_FAILURE_IO_RESPONSE_VALID\n",
+			__func__);
+		ret =  TMF_RESP_FUNC_COMPLETE;
+	}
+	/* Else - leave the default "failed" status alone. */
+
+	dev_dbg(&ihost->pdev->dev,
+		"%s: completed request = %p\n",
+		__func__,
+		ireq);
+
+	return ret;
+
+ err_tci:
+	spin_lock_irqsave(&ihost->scic_lock, flags);
+	isci_tci_free(ihost, ISCI_TAG_TCI(tag));
+	spin_unlock_irqrestore(&ihost->scic_lock, flags);
+
+	return ret;
+}
+
+static void isci_task_build_tmf(struct isci_tmf *tmf,
+				enum isci_tmf_function_codes code,
+				void (*tmf_sent_cb)(enum isci_tmf_cb_state,
+						    struct isci_tmf *,
+						    void *),
+				void *cb_data)
+{
+	memset(tmf, 0, sizeof(*tmf));
+
+	tmf->tmf_code      = code;
+	tmf->cb_state_func = tmf_sent_cb;
+	tmf->cb_data       = cb_data;
+}
+
+static void isci_task_build_abort_task_tmf(struct isci_tmf *tmf,
+					   enum isci_tmf_function_codes code,
+					   void (*tmf_sent_cb)(enum isci_tmf_cb_state,
+							       struct isci_tmf *,
+							       void *),
+					   struct isci_request *old_request)
+{
+	isci_task_build_tmf(tmf, code, tmf_sent_cb, old_request);
+	tmf->io_tag = old_request->io_tag;
+}
+
+/**
+ * isci_task_validate_request_to_abort() - This function checks the given I/O
+ *    against the "started" state.  If the request is still "started", it's
+ *    state is changed to aborted. NOTE: isci_host->scic_lock MUST BE HELD
+ *    BEFORE CALLING THIS FUNCTION.
+ * @isci_request: This parameter specifies the request object to control.
+ * @isci_host: This parameter specifies the ISCI host object
+ * @isci_device: This is the device to which the request is pending.
+ * @aborted_io_completion: This is a completion structure that will be added to
+ *    the request in case it is changed to aborting; this completion is
+ *    triggered when the request is fully completed.
+ *
+ * Either "started" on successful change of the task status to "aborted", or
+ * "unallocated" if the task cannot be controlled.
+ */
+static enum isci_request_status isci_task_validate_request_to_abort(
+	struct isci_request *isci_request,
+	struct isci_host *isci_host,
+	struct isci_remote_device *isci_device,
+	struct completion *aborted_io_completion)
+{
+	enum isci_request_status old_state = unallocated;
+
+	/* Only abort the task if it's in the
+	 *  device's request_in_process list
+	 */
+	if (isci_request && !list_empty(&isci_request->dev_node)) {
+		old_state = isci_request_change_started_to_aborted(
+			isci_request, aborted_io_completion);
+
+	}
+
+	return old_state;
+}
+
+/**
+* isci_request_cleanup_completed_loiterer() - This function will take care of
+*    the final cleanup on any request which has been explicitly terminated.
+* @isci_host: This parameter specifies the ISCI host object
+* @isci_device: This is the device to which the request is pending.
+* @isci_request: This parameter specifies the terminated request object.
+* @task: This parameter is the libsas I/O request.
+*/
+static void isci_request_cleanup_completed_loiterer(
+	struct isci_host          *isci_host,
+	struct isci_remote_device *isci_device,
+	struct isci_request       *isci_request,
+	struct sas_task           *task)
+{
+	unsigned long flags;
+
+	dev_dbg(&isci_host->pdev->dev,
+		"%s: isci_device=%p, request=%p, task=%p\n",
+		__func__, isci_device, isci_request, task);
+
+	if (task != NULL) {
+
+		spin_lock_irqsave(&task->task_state_lock, flags);
+		task->lldd_task = NULL;
+
+		task->task_state_flags &= ~SAS_TASK_NEED_DEV_RESET;
+
+		isci_set_task_doneflags(task);
+
+		/* If this task is not in the abort path, call task_done. */
+		if (!(task->task_state_flags & SAS_TASK_STATE_ABORTED)) {
+
+			spin_unlock_irqrestore(&task->task_state_lock, flags);
+			task->task_done(task);
+		} else
+			spin_unlock_irqrestore(&task->task_state_lock, flags);
+	}
+
+	if (isci_request != NULL) {
+		spin_lock_irqsave(&isci_host->scic_lock, flags);
+		list_del_init(&isci_request->dev_node);
+		spin_unlock_irqrestore(&isci_host->scic_lock, flags);
+	}
+}
+
+/**
+ * isci_terminate_request_core() - This function will terminate the given
+ *    request, and wait for it to complete.  This function must only be called
+ *    from a thread that can wait.  Note that the request is terminated and
+ *    completed (back to the host, if started there).
+ * @ihost: This SCU.
+ * @idev: The target.
+ * @isci_request: The I/O request to be terminated.
+ *
+ */
+static void isci_terminate_request_core(struct isci_host *ihost,
+					struct isci_remote_device *idev,
+					struct isci_request *isci_request)
+{
+	enum sci_status status      = SCI_SUCCESS;
+	bool was_terminated         = false;
+	bool needs_cleanup_handling = false;
+	enum isci_request_status request_status;
+	unsigned long     flags;
+	unsigned long     termination_completed = 1;
+	struct completion *io_request_completion;
+	struct sas_task   *task;
+
+	dev_dbg(&ihost->pdev->dev,
+		"%s: device = %p; request = %p\n",
+		__func__, idev, isci_request);
+
+	spin_lock_irqsave(&ihost->scic_lock, flags);
+
+	io_request_completion = isci_request->io_request_completion;
+
+	task = (isci_request->ttype == io_task)
+		? isci_request_access_task(isci_request)
+		: NULL;
+
+	/* Note that we are not going to control
+	 * the target to abort the request.
+	 */
+	set_bit(IREQ_COMPLETE_IN_TARGET, &isci_request->flags);
+
+	/* Make sure the request wasn't just sitting around signalling
+	 * device condition (if the request handle is NULL, then the
+	 * request completed but needed additional handling here).
+	 */
+	if (!test_bit(IREQ_TERMINATED, &isci_request->flags)) {
+		was_terminated = true;
+		needs_cleanup_handling = true;
+		status = sci_controller_terminate_request(ihost,
+							   idev,
+							   isci_request);
+	}
+	spin_unlock_irqrestore(&ihost->scic_lock, flags);
+
+	/*
+	 * The only time the request to terminate will
+	 * fail is when the io request is completed and
+	 * being aborted.
+	 */
+	if (status != SCI_SUCCESS) {
+		dev_dbg(&ihost->pdev->dev,
+			"%s: sci_controller_terminate_request"
+			" returned = 0x%x\n",
+			__func__, status);
+
+		isci_request->io_request_completion = NULL;
+
+	} else {
+		if (was_terminated) {
+			dev_dbg(&ihost->pdev->dev,
+				"%s: before completion wait (%p/%p)\n",
+				__func__, isci_request, io_request_completion);
+
+			/* Wait here for the request to complete. */
+			#define TERMINATION_TIMEOUT_MSEC 500
+			termination_completed
+				= wait_for_completion_timeout(
+				   io_request_completion,
+				   msecs_to_jiffies(TERMINATION_TIMEOUT_MSEC));
+
+			if (!termination_completed) {
+
+				/* The request to terminate has timed out.  */
+				spin_lock_irqsave(&ihost->scic_lock,
+						  flags);
+
+				/* Check for state changes. */
+				if (!test_bit(IREQ_TERMINATED, &isci_request->flags)) {
+
+					/* The best we can do is to have the
+					 * request die a silent death if it
+					 * ever really completes.
+					 *
+					 * Set the request state to "dead",
+					 * and clear the task pointer so that
+					 * an actual completion event callback
+					 * doesn't do anything.
+					 */
+					isci_request->status = dead;
+					isci_request->io_request_completion
+						= NULL;
+
+					if (isci_request->ttype == io_task) {
+
+						/* Break links with the
+						* sas_task.
+						*/
+						isci_request->ttype_ptr.io_task_ptr
+							= NULL;
+					}
+				} else
+					termination_completed = 1;
+
+				spin_unlock_irqrestore(&ihost->scic_lock,
+						       flags);
+
+				if (!termination_completed) {
+
+					dev_dbg(&ihost->pdev->dev,
+						"%s: *** Timeout waiting for "
+						"termination(%p/%p)\n",
+						__func__, io_request_completion,
+						isci_request);
+
+					/* The request can no longer be referenced
+					 * safely since it may go away if the
+					 * termination every really does complete.
+					 */
+					isci_request = NULL;
+				}
+			}
+			if (termination_completed)
+				dev_dbg(&ihost->pdev->dev,
+					"%s: after completion wait (%p/%p)\n",
+					__func__, isci_request, io_request_completion);
+		}
+
+		if (termination_completed) {
+
+			isci_request->io_request_completion = NULL;
+
+			/* Peek at the status of the request.  This will tell
+			 * us if there was special handling on the request such that it
+			 * needs to be detached and freed here.
+			 */
+			spin_lock_irqsave(&isci_request->state_lock, flags);
+			request_status = isci_request->status;
+
+			if ((isci_request->ttype == io_task) /* TMFs are in their own thread */
+			    && ((request_status == aborted)
+				|| (request_status == aborting)
+				|| (request_status == terminating)
+				|| (request_status == completed)
+				|| (request_status == dead)
+				)
+			    ) {
+
+				/* The completion routine won't free a request in
+				 * the aborted/aborting/etc. states, so we do
+				 * it here.
+				 */
+				needs_cleanup_handling = true;
+			}
+			spin_unlock_irqrestore(&isci_request->state_lock, flags);
+
+		}
+		if (needs_cleanup_handling)
+			isci_request_cleanup_completed_loiterer(
+				ihost, idev, isci_request, task);
+	}
+}
+
+/**
+ * isci_terminate_pending_requests() - This function will change the all of the
+ *    requests on the given device's state to "aborting", will terminate the
+ *    requests, and wait for them to complete.  This function must only be
+ *    called from a thread that can wait.  Note that the requests are all
+ *    terminated and completed (back to the host, if started there).
+ * @isci_host: This parameter specifies SCU.
+ * @idev: This parameter specifies the target.
+ *
+ */
+void isci_terminate_pending_requests(struct isci_host *ihost,
+				     struct isci_remote_device *idev)
+{
+	struct completion request_completion;
+	enum isci_request_status old_state;
+	unsigned long flags;
+	LIST_HEAD(list);
+
+	spin_lock_irqsave(&ihost->scic_lock, flags);
+	list_splice_init(&idev->reqs_in_process, &list);
+
+	/* assumes that isci_terminate_request_core deletes from the list */
+	while (!list_empty(&list)) {
+		struct isci_request *ireq = list_entry(list.next, typeof(*ireq), dev_node);
+
+		/* Change state to "terminating" if it is currently
+		 * "started".
+		 */
+		old_state = isci_request_change_started_to_newstate(ireq,
+								    &request_completion,
+								    terminating);
+		switch (old_state) {
+		case started:
+		case completed:
+		case aborting:
+			break;
+		default:
+			/* termination in progress, or otherwise dispositioned.
+			 * We know the request was on 'list' so should be safe
+			 * to move it back to reqs_in_process
+			 */
+			list_move(&ireq->dev_node, &idev->reqs_in_process);
+			ireq = NULL;
+			break;
+		}
+
+		if (!ireq)
+			continue;
+		spin_unlock_irqrestore(&ihost->scic_lock, flags);
+
+		init_completion(&request_completion);
+
+		dev_dbg(&ihost->pdev->dev,
+			 "%s: idev=%p request=%p; task=%p old_state=%d\n",
+			 __func__, idev, ireq,
+			ireq->ttype == io_task ? isci_request_access_task(ireq) : NULL,
+			old_state);
+
+		/* If the old_state is started:
+		 * This request was not already being aborted. If it had been,
+		 * then the aborting I/O (ie. the TMF request) would not be in
+		 * the aborting state, and thus would be terminated here.  Note
+		 * that since the TMF completion's call to the kernel function
+		 * "complete()" does not happen until the pending I/O request
+		 * terminate fully completes, we do not have to implement a
+		 * special wait here for already aborting requests - the
+		 * termination of the TMF request will force the request
+		 * to finish it's already started terminate.
+		 *
+		 * If old_state == completed:
+		 * This request completed from the SCU hardware perspective
+		 * and now just needs cleaning up in terms of freeing the
+		 * request and potentially calling up to libsas.
+		 *
+		 * If old_state == aborting:
+		 * This request has already gone through a TMF timeout, but may
+		 * not have been terminated; needs cleaning up at least.
+		 */
+		isci_terminate_request_core(ihost, idev, ireq);
+		spin_lock_irqsave(&ihost->scic_lock, flags);
+	}
+	spin_unlock_irqrestore(&ihost->scic_lock, flags);
+}
+
+/**
+ * isci_task_send_lu_reset_sas() - This function is called by of the SAS Domain
+ *    Template functions.
+ * @lun: This parameter specifies the lun to be reset.
+ *
+ * status, zero indicates success.
+ */
+static int isci_task_send_lu_reset_sas(
+	struct isci_host *isci_host,
+	struct isci_remote_device *isci_device,
+	u8 *lun)
+{
+	struct isci_tmf tmf;
+	int ret = TMF_RESP_FUNC_FAILED;
+
+	dev_dbg(&isci_host->pdev->dev,
+		"%s: isci_host = %p, isci_device = %p\n",
+		__func__, isci_host, isci_device);
+	/* Send the LUN reset to the target.  By the time the call returns,
+	 * the TMF has fully exected in the target (in which case the return
+	 * value is "TMF_RESP_FUNC_COMPLETE", or the request timed-out (or
+	 * was otherwise unable to be executed ("TMF_RESP_FUNC_FAILED").
+	 */
+	isci_task_build_tmf(&tmf, isci_tmf_ssp_lun_reset, NULL, NULL);
+
+	#define ISCI_LU_RESET_TIMEOUT_MS 2000 /* 2 second timeout. */
+	ret = isci_task_execute_tmf(isci_host, isci_device, &tmf, ISCI_LU_RESET_TIMEOUT_MS);
+
+	if (ret == TMF_RESP_FUNC_COMPLETE)
+		dev_dbg(&isci_host->pdev->dev,
+			"%s: %p: TMF_LU_RESET passed\n",
+			__func__, isci_device);
+	else
+		dev_dbg(&isci_host->pdev->dev,
+			"%s: %p: TMF_LU_RESET failed (%x)\n",
+			__func__, isci_device, ret);
+
+	return ret;
+}
+
+static int isci_task_send_lu_reset_sata(struct isci_host *ihost,
+				 struct isci_remote_device *idev, u8 *lun)
+{
+	int ret = TMF_RESP_FUNC_FAILED;
+	struct isci_tmf tmf;
+
+	/* Send the soft reset to the target */
+	#define ISCI_SRST_TIMEOUT_MS 25000 /* 25 second timeout. */
+	isci_task_build_tmf(&tmf, isci_tmf_sata_srst_high, NULL, NULL);
+
+	ret = isci_task_execute_tmf(ihost, idev, &tmf, ISCI_SRST_TIMEOUT_MS);
+
+	if (ret != TMF_RESP_FUNC_COMPLETE) {
+		dev_dbg(&ihost->pdev->dev,
+			 "%s: Assert SRST failed (%p) = %x",
+			 __func__, idev, ret);
+
+		/* Return the failure so that the LUN reset is escalated
+		 * to a target reset.
+		 */
+	}
+	return ret;
+}
+
+/**
+ * isci_task_lu_reset() - This function is one of the SAS Domain Template
+ *    functions. This is one of the Task Management functoins called by libsas,
+ *    to reset the given lun. Note the assumption that while this call is
+ *    executing, no I/O will be sent by the host to the device.
+ * @lun: This parameter specifies the lun to be reset.
+ *
+ * status, zero indicates success.
+ */
+int isci_task_lu_reset(struct domain_device *domain_device, u8 *lun)
+{
+	struct isci_host *isci_host = dev_to_ihost(domain_device);
+	struct isci_remote_device *isci_device;
+	unsigned long flags;
+	int ret;
+
+	spin_lock_irqsave(&isci_host->scic_lock, flags);
+	isci_device = isci_lookup_device(domain_device);
+	spin_unlock_irqrestore(&isci_host->scic_lock, flags);
+
+	dev_dbg(&isci_host->pdev->dev,
+		"%s: domain_device=%p, isci_host=%p; isci_device=%p\n",
+		 __func__, domain_device, isci_host, isci_device);
+
+	if (isci_device)
+		set_bit(IDEV_EH, &isci_device->flags);
+
+	/* If there is a device reset pending on any request in the
+	 * device's list, fail this LUN reset request in order to
+	 * escalate to the device reset.
+	 */
+	if (!isci_device ||
+	    isci_device_is_reset_pending(isci_host, isci_device)) {
+		dev_dbg(&isci_host->pdev->dev,
+			 "%s: No dev (%p), or "
+			 "RESET PENDING: domain_device=%p\n",
+			 __func__, isci_device, domain_device);
+		ret = TMF_RESP_FUNC_FAILED;
+		goto out;
+	}
+
+	/* Send the task management part of the reset. */
+	if (sas_protocol_ata(domain_device->tproto)) {
+		ret = isci_task_send_lu_reset_sata(isci_host, isci_device, lun);
+	} else
+		ret = isci_task_send_lu_reset_sas(isci_host, isci_device, lun);
+
+	/* If the LUN reset worked, all the I/O can now be terminated. */
+	if (ret == TMF_RESP_FUNC_COMPLETE)
+		/* Terminate all I/O now. */
+		isci_terminate_pending_requests(isci_host,
+						isci_device);
+
+ out:
+	isci_put_device(isci_device);
+	return ret;
+}
+
+
+/*	 int (*lldd_clear_nexus_port)(struct asd_sas_port *); */
+int isci_task_clear_nexus_port(struct asd_sas_port *port)
+{
+	return TMF_RESP_FUNC_FAILED;
+}
+
+
+
+int isci_task_clear_nexus_ha(struct sas_ha_struct *ha)
+{
+	return TMF_RESP_FUNC_FAILED;
+}
+
+/* Task Management Functions. Must be called from process context.	 */
+
+/**
+ * isci_abort_task_process_cb() - This is a helper function for the abort task
+ *    TMF command.  It manages the request state with respect to the successful
+ *    transmission / completion of the abort task request.
+ * @cb_state: This parameter specifies when this function was called - after
+ *    the TMF request has been started and after it has timed-out.
+ * @tmf: This parameter specifies the TMF in progress.
+ *
+ *
+ */
+static void isci_abort_task_process_cb(
+	enum isci_tmf_cb_state cb_state,
+	struct isci_tmf *tmf,
+	void *cb_data)
+{
+	struct isci_request *old_request;
+
+	old_request = (struct isci_request *)cb_data;
+
+	dev_dbg(&old_request->isci_host->pdev->dev,
+		"%s: tmf=%p, old_request=%p\n",
+		__func__, tmf, old_request);
+
+	switch (cb_state) {
+
+	case isci_tmf_started:
+		/* The TMF has been started.  Nothing to do here, since the
+		 * request state was already set to "aborted" by the abort
+		 * task function.
+		 */
+		if ((old_request->status != aborted)
+			&& (old_request->status != completed))
+			dev_dbg(&old_request->isci_host->pdev->dev,
+				"%s: Bad request status (%d): tmf=%p, old_request=%p\n",
+				__func__, old_request->status, tmf, old_request);
+		break;
+
+	case isci_tmf_timed_out:
+
+		/* Set the task's state to "aborting", since the abort task
+		 * function thread set it to "aborted" (above) in anticipation
+		 * of the task management request working correctly.  Since the
+		 * timeout has now fired, the TMF request failed.  We set the
+		 * state such that the request completion will indicate the
+		 * device is no longer present.
+		 */
+		isci_request_change_state(old_request, aborting);
+		break;
+
+	default:
+		dev_dbg(&old_request->isci_host->pdev->dev,
+			"%s: Bad cb_state (%d): tmf=%p, old_request=%p\n",
+			__func__, cb_state, tmf, old_request);
+		break;
+	}
+}
+
+/**
+ * isci_task_abort_task() - This function is one of the SAS Domain Template
+ *    functions. This function is called by libsas to abort a specified task.
+ * @task: This parameter specifies the SAS task to abort.
+ *
+ * status, zero indicates success.
+ */
+int isci_task_abort_task(struct sas_task *task)
+{
+	struct isci_host *isci_host = dev_to_ihost(task->dev);
+	DECLARE_COMPLETION_ONSTACK(aborted_io_completion);
+	struct isci_request       *old_request = NULL;
+	enum isci_request_status  old_state;
+	struct isci_remote_device *isci_device = NULL;
+	struct isci_tmf           tmf;
+	int                       ret = TMF_RESP_FUNC_FAILED;
+	unsigned long             flags;
+	bool                      any_dev_reset = false;
+
+	/* Get the isci_request reference from the task.  Note that
+	 * this check does not depend on the pending request list
+	 * in the device, because tasks driving resets may land here
+	 * after completion in the core.
+	 */
+	spin_lock_irqsave(&isci_host->scic_lock, flags);
+	spin_lock(&task->task_state_lock);
+
+	old_request = task->lldd_task;
+
+	/* If task is already done, the request isn't valid */
+	if (!(task->task_state_flags & SAS_TASK_STATE_DONE) &&
+	    (task->task_state_flags & SAS_TASK_AT_INITIATOR) &&
+	    old_request)
+		isci_device = isci_lookup_device(task->dev);
+
+	spin_unlock(&task->task_state_lock);
+	spin_unlock_irqrestore(&isci_host->scic_lock, flags);
+
+	dev_dbg(&isci_host->pdev->dev,
+		"%s: task = %p\n", __func__, task);
+
+	if (!isci_device || !old_request)
+		goto out;
+
+	set_bit(IDEV_EH, &isci_device->flags);
+
+	/* This version of the driver will fail abort requests for
+	 * SATA/STP.  Failing the abort request this way will cause the
+	 * SCSI error handler thread to escalate to LUN reset
+	 */
+	if (sas_protocol_ata(task->task_proto)) {
+		dev_dbg(&isci_host->pdev->dev,
+			    " task %p is for a STP/SATA device;"
+			    " returning TMF_RESP_FUNC_FAILED\n"
+			    " to cause a LUN reset...\n", task);
+		goto out;
+	}
+
+	dev_dbg(&isci_host->pdev->dev,
+		"%s: old_request == %p\n", __func__, old_request);
+
+	any_dev_reset = isci_device_is_reset_pending(isci_host, isci_device);
+
+	spin_lock_irqsave(&task->task_state_lock, flags);
+
+	any_dev_reset = any_dev_reset || (task->task_state_flags & SAS_TASK_NEED_DEV_RESET);
+
+	/* If the extraction of the request reference from the task
+	 * failed, then the request has been completed (or if there is a
+	 * pending reset then this abort request function must be failed
+	 * in order to escalate to the target reset).
+	 */
+	if ((old_request == NULL) || any_dev_reset) {
+
+		/* If the device reset task flag is set, fail the task
+		 * management request.  Otherwise, the original request
+		 * has completed.
+		 */
+		if (any_dev_reset) {
+
+			/* Turn off the task's DONE to make sure this
+			 * task is escalated to a target reset.
+			 */
+			task->task_state_flags &= ~SAS_TASK_STATE_DONE;
+
+			/* Make the reset happen as soon as possible. */
+			task->task_state_flags |= SAS_TASK_NEED_DEV_RESET;
+
+			spin_unlock_irqrestore(&task->task_state_lock, flags);
+
+			/* Fail the task management request in order to
+			 * escalate to the target reset.
+			 */
+			ret = TMF_RESP_FUNC_FAILED;
+
+			dev_dbg(&isci_host->pdev->dev,
+				"%s: Failing task abort in order to "
+				"escalate to target reset because\n"
+				"SAS_TASK_NEED_DEV_RESET is set for "
+				"task %p on dev %p\n",
+				__func__, task, isci_device);
+
+
+		} else {
+			/* The request has already completed and there
+			 * is nothing to do here other than to set the task
+			 * done bit, and indicate that the task abort function
+			 * was sucessful.
+			 */
+			isci_set_task_doneflags(task);
+
+			spin_unlock_irqrestore(&task->task_state_lock, flags);
+
+			ret = TMF_RESP_FUNC_COMPLETE;
+
+			dev_dbg(&isci_host->pdev->dev,
+				"%s: abort task not needed for %p\n",
+				__func__, task);
+		}
+		goto out;
+	} else {
+		spin_unlock_irqrestore(&task->task_state_lock, flags);
+	}
+
+	spin_lock_irqsave(&isci_host->scic_lock, flags);
+
+	/* Check the request status and change to "aborted" if currently
+	 * "starting"; if true then set the I/O kernel completion
+	 * struct that will be triggered when the request completes.
+	 */
+	old_state = isci_task_validate_request_to_abort(
+				old_request, isci_host, isci_device,
+				&aborted_io_completion);
+	if ((old_state != started) &&
+	    (old_state != completed) &&
+	    (old_state != aborting)) {
+
+		spin_unlock_irqrestore(&isci_host->scic_lock, flags);
+
+		/* The request was already being handled by someone else (because
+		* they got to set the state away from started).
+		*/
+		dev_dbg(&isci_host->pdev->dev,
+			"%s:  device = %p; old_request %p already being aborted\n",
+			__func__,
+			isci_device, old_request);
+		ret = TMF_RESP_FUNC_COMPLETE;
+		goto out;
+	}
+	if (task->task_proto == SAS_PROTOCOL_SMP ||
+	    test_bit(IREQ_COMPLETE_IN_TARGET, &old_request->flags)) {
+
+		spin_unlock_irqrestore(&isci_host->scic_lock, flags);
+
+		dev_dbg(&isci_host->pdev->dev,
+			"%s: SMP request (%d)"
+			" or complete_in_target (%d), thus no TMF\n",
+			__func__, (task->task_proto == SAS_PROTOCOL_SMP),
+			test_bit(IREQ_COMPLETE_IN_TARGET, &old_request->flags));
+
+		/* Set the state on the task. */
+		isci_task_all_done(task);
+
+		ret = TMF_RESP_FUNC_COMPLETE;
+
+		/* Stopping and SMP devices are not sent a TMF, and are not
+		 * reset, but the outstanding I/O request is terminated below.
+		 */
+	} else {
+		/* Fill in the tmf stucture */
+		isci_task_build_abort_task_tmf(&tmf, isci_tmf_ssp_task_abort,
+					       isci_abort_task_process_cb,
+					       old_request);
+
+		spin_unlock_irqrestore(&isci_host->scic_lock, flags);
+
+		#define ISCI_ABORT_TASK_TIMEOUT_MS 500 /* half second timeout. */
+		ret = isci_task_execute_tmf(isci_host, isci_device, &tmf,
+					    ISCI_ABORT_TASK_TIMEOUT_MS);
+
+		if (ret != TMF_RESP_FUNC_COMPLETE)
+			dev_dbg(&isci_host->pdev->dev,
+				"%s: isci_task_send_tmf failed\n",
+				__func__);
+	}
+	if (ret == TMF_RESP_FUNC_COMPLETE) {
+		set_bit(IREQ_COMPLETE_IN_TARGET, &old_request->flags);
+
+		/* Clean up the request on our side, and wait for the aborted
+		 * I/O to complete.
+		 */
+		isci_terminate_request_core(isci_host, isci_device, old_request);
+	}
+
+	/* Make sure we do not leave a reference to aborted_io_completion */
+	old_request->io_request_completion = NULL;
+ out:
+	isci_put_device(isci_device);
+	return ret;
+}
+
+/**
+ * isci_task_abort_task_set() - This function is one of the SAS Domain Template
+ *    functions. This is one of the Task Management functoins called by libsas,
+ *    to abort all task for the given lun.
+ * @d_device: This parameter specifies the domain device associated with this
+ *    request.
+ * @lun: This parameter specifies the lun associated with this request.
+ *
+ * status, zero indicates success.
+ */
+int isci_task_abort_task_set(
+	struct domain_device *d_device,
+	u8 *lun)
+{
+	return TMF_RESP_FUNC_FAILED;
+}
+
+
+/**
+ * isci_task_clear_aca() - This function is one of the SAS Domain Template
+ *    functions. This is one of the Task Management functoins called by libsas.
+ * @d_device: This parameter specifies the domain device associated with this
+ *    request.
+ * @lun: This parameter specifies the lun	 associated with this request.
+ *
+ * status, zero indicates success.
+ */
+int isci_task_clear_aca(
+	struct domain_device *d_device,
+	u8 *lun)
+{
+	return TMF_RESP_FUNC_FAILED;
+}
+
+
+
+/**
+ * isci_task_clear_task_set() - This function is one of the SAS Domain Template
+ *    functions. This is one of the Task Management functoins called by libsas.
+ * @d_device: This parameter specifies the domain device associated with this
+ *    request.
+ * @lun: This parameter specifies the lun	 associated with this request.
+ *
+ * status, zero indicates success.
+ */
+int isci_task_clear_task_set(
+	struct domain_device *d_device,
+	u8 *lun)
+{
+	return TMF_RESP_FUNC_FAILED;
+}
+
+
+/**
+ * isci_task_query_task() - This function is implemented to cause libsas to
+ *    correctly escalate the failed abort to a LUN or target reset (this is
+ *    because sas_scsi_find_task libsas function does not correctly interpret
+ *    all return codes from the abort task call).  When TMF_RESP_FUNC_SUCC is
+ *    returned, libsas turns this into a LUN reset; when FUNC_FAILED is
+ *    returned, libsas will turn this into a target reset
+ * @task: This parameter specifies the sas task being queried.
+ * @lun: This parameter specifies the lun associated with this request.
+ *
+ * status, zero indicates success.
+ */
+int isci_task_query_task(
+	struct sas_task *task)
+{
+	/* See if there is a pending device reset for this device. */
+	if (task->task_state_flags & SAS_TASK_NEED_DEV_RESET)
+		return TMF_RESP_FUNC_FAILED;
+	else
+		return TMF_RESP_FUNC_SUCC;
+}
+
+/*
+ * isci_task_request_complete() - This function is called by the sci core when
+ *    an task request completes.
+ * @ihost: This parameter specifies the ISCI host object
+ * @ireq: This parameter is the completed isci_request object.
+ * @completion_status: This parameter specifies the completion status from the
+ *    sci core.
+ *
+ * none.
+ */
+void
+isci_task_request_complete(struct isci_host *ihost,
+			   struct isci_request *ireq,
+			   enum sci_task_status completion_status)
+{
+	struct isci_tmf *tmf = isci_request_access_tmf(ireq);
+	struct completion *tmf_complete;
+
+	dev_dbg(&ihost->pdev->dev,
+		"%s: request = %p, status=%d\n",
+		__func__, ireq, completion_status);
+
+	isci_request_change_state(ireq, completed);
+
+	tmf->status = completion_status;
+	set_bit(IREQ_COMPLETE_IN_TARGET, &ireq->flags);
+
+	if (tmf->proto == SAS_PROTOCOL_SSP) {
+		memcpy(&tmf->resp.resp_iu,
+		       &ireq->ssp.rsp,
+		       SSP_RESP_IU_MAX_SIZE);
+	} else if (tmf->proto == SAS_PROTOCOL_SATA) {
+		memcpy(&tmf->resp.d2h_fis,
+		       &ireq->stp.rsp,
+		       sizeof(struct dev_to_host_fis));
+	}
+
+	/* PRINT_TMF( ((struct isci_tmf *)request->task)); */
+	tmf_complete = tmf->complete;
+
+	sci_controller_complete_io(ihost, ireq->target_device, ireq);
+	/* set the 'terminated' flag handle to make sure it cannot be terminated
+	 *  or completed again.
+	 */
+	set_bit(IREQ_TERMINATED, &ireq->flags);
+
+	isci_request_change_state(ireq, unallocated);
+	list_del_init(&ireq->dev_node);
+
+	/* The task management part completes last. */
+	complete(tmf_complete);
+}
+
+static void isci_smp_task_timedout(unsigned long _task)
+{
+	struct sas_task *task = (void *) _task;
+	unsigned long flags;
+
+	spin_lock_irqsave(&task->task_state_lock, flags);
+	if (!(task->task_state_flags & SAS_TASK_STATE_DONE))
+		task->task_state_flags |= SAS_TASK_STATE_ABORTED;
+	spin_unlock_irqrestore(&task->task_state_lock, flags);
+
+	complete(&task->completion);
+}
+
+static void isci_smp_task_done(struct sas_task *task)
+{
+	if (!del_timer(&task->timer))
+		return;
+	complete(&task->completion);
+}
+
+static struct sas_task *isci_alloc_task(void)
+{
+	struct sas_task *task = kzalloc(sizeof(*task), GFP_KERNEL);
+
+	if (task) {
+		INIT_LIST_HEAD(&task->list);
+		spin_lock_init(&task->task_state_lock);
+		task->task_state_flags = SAS_TASK_STATE_PENDING;
+		init_timer(&task->timer);
+		init_completion(&task->completion);
+	}
+
+	return task;
+}
+
+static void isci_free_task(struct isci_host *ihost, struct sas_task  *task)
+{
+	if (task) {
+		BUG_ON(!list_empty(&task->list));
+		kfree(task);
+	}
+}
+
+static int isci_smp_execute_task(struct isci_host *ihost,
+				 struct domain_device *dev, void *req,
+				 int req_size, void *resp, int resp_size)
+{
+	int res, retry;
+	struct sas_task *task = NULL;
+
+	for (retry = 0; retry < 3; retry++) {
+		task = isci_alloc_task();
+		if (!task)
+			return -ENOMEM;
+
+		task->dev = dev;
+		task->task_proto = dev->tproto;
+		sg_init_one(&task->smp_task.smp_req, req, req_size);
+		sg_init_one(&task->smp_task.smp_resp, resp, resp_size);
+
+		task->task_done = isci_smp_task_done;
+
+		task->timer.data = (unsigned long) task;
+		task->timer.function = isci_smp_task_timedout;
+		task->timer.expires = jiffies + 10*HZ;
+		add_timer(&task->timer);
+
+		res = isci_task_execute_task(task, 1, GFP_KERNEL);
+
+		if (res) {
+			del_timer(&task->timer);
+			dev_dbg(&ihost->pdev->dev,
+				"%s: executing SMP task failed:%d\n",
+				__func__, res);
+			goto ex_err;
+		}
+
+		wait_for_completion(&task->completion);
+		res = -ECOMM;
+		if ((task->task_state_flags & SAS_TASK_STATE_ABORTED)) {
+			dev_dbg(&ihost->pdev->dev,
+				"%s: smp task timed out or aborted\n",
+				__func__);
+			isci_task_abort_task(task);
+			if (!(task->task_state_flags & SAS_TASK_STATE_DONE)) {
+				dev_dbg(&ihost->pdev->dev,
+					"%s: SMP task aborted and not done\n",
+					__func__);
+				goto ex_err;
+			}
+		}
+		if (task->task_status.resp == SAS_TASK_COMPLETE &&
+		    task->task_status.stat == SAM_STAT_GOOD) {
+			res = 0;
+			break;
+		}
+		if (task->task_status.resp == SAS_TASK_COMPLETE &&
+		      task->task_status.stat == SAS_DATA_UNDERRUN) {
+			/* no error, but return the number of bytes of
+			* underrun */
+			res = task->task_status.residual;
+			break;
+		}
+		if (task->task_status.resp == SAS_TASK_COMPLETE &&
+		      task->task_status.stat == SAS_DATA_OVERRUN) {
+			res = -EMSGSIZE;
+			break;
+		} else {
+			dev_dbg(&ihost->pdev->dev,
+				"%s: task to dev %016llx response: 0x%x "
+				"status 0x%x\n", __func__,
+				SAS_ADDR(dev->sas_addr),
+				task->task_status.resp,
+				task->task_status.stat);
+			isci_free_task(ihost, task);
+			task = NULL;
+		}
+	}
+ex_err:
+	BUG_ON(retry == 3 && task != NULL);
+	isci_free_task(ihost, task);
+	return res;
+}
+
+#define DISCOVER_REQ_SIZE  16
+#define DISCOVER_RESP_SIZE 56
+
+int isci_smp_get_phy_attached_dev_type(struct isci_host *ihost,
+				       struct domain_device *dev,
+				       int phy_id, int *adt)
+{
+	struct smp_resp *disc_resp;
+	u8 *disc_req;
+	int res;
+
+	disc_resp = kzalloc(DISCOVER_RESP_SIZE, GFP_KERNEL);
+	if (!disc_resp)
+		return -ENOMEM;
+
+	disc_req = kzalloc(DISCOVER_REQ_SIZE, GFP_KERNEL);
+	if (disc_req) {
+		disc_req[0] = SMP_REQUEST;
+		disc_req[1] = SMP_DISCOVER;
+		disc_req[9] = phy_id;
+	} else {
+		kfree(disc_resp);
+		return -ENOMEM;
+	}
+	res = isci_smp_execute_task(ihost, dev, disc_req, DISCOVER_REQ_SIZE,
+				    disc_resp, DISCOVER_RESP_SIZE);
+	if (!res) {
+		if (disc_resp->result != SMP_RESP_FUNC_ACC)
+			res = disc_resp->result;
+		else
+			*adt = disc_resp->disc.attached_dev_type;
+	}
+	kfree(disc_req);
+	kfree(disc_resp);
+
+	return res;
+}
+
+static void isci_wait_for_smp_phy_reset(struct isci_remote_device *idev, int phy_num)
+{
+	struct domain_device *dev = idev->domain_dev;
+	struct isci_port *iport = idev->isci_port;
+	struct isci_host *ihost = iport->isci_host;
+	int res, iteration = 0, attached_device_type;
+	#define STP_WAIT_MSECS 25000
+	unsigned long tmo = msecs_to_jiffies(STP_WAIT_MSECS);
+	unsigned long deadline = jiffies + tmo;
+	enum {
+		SMP_PHYWAIT_PHYDOWN,
+		SMP_PHYWAIT_PHYUP,
+		SMP_PHYWAIT_DONE
+	} phy_state = SMP_PHYWAIT_PHYDOWN;
+
+	/* While there is time, wait for the phy to go away and come back */
+	while (time_is_after_jiffies(deadline) && phy_state != SMP_PHYWAIT_DONE) {
+		int event = atomic_read(&iport->event);
+
+		++iteration;
+
+		tmo = wait_event_timeout(ihost->eventq,
+					 event != atomic_read(&iport->event) ||
+					 !test_bit(IPORT_BCN_BLOCKED, &iport->flags),
+					 tmo);
+		/* link down, stop polling */
+		if (!test_bit(IPORT_BCN_BLOCKED, &iport->flags))
+			break;
+
+		dev_dbg(&ihost->pdev->dev,
+			"%s: iport %p, iteration %d,"
+			" phase %d: time_remaining %lu, bcns = %d\n",
+			__func__, iport, iteration, phy_state,
+			tmo, test_bit(IPORT_BCN_PENDING, &iport->flags));
+
+		res = isci_smp_get_phy_attached_dev_type(ihost, dev, phy_num,
+							 &attached_device_type);
+		tmo = deadline - jiffies;
+
+		if (res) {
+			dev_dbg(&ihost->pdev->dev,
+				 "%s: iteration %d, phase %d:"
+				 " SMP error=%d, time_remaining=%lu\n",
+				 __func__, iteration, phy_state, res, tmo);
+			break;
+		}
+		dev_dbg(&ihost->pdev->dev,
+			"%s: iport %p, iteration %d,"
+			" phase %d: time_remaining %lu, bcns = %d, "
+			"attdevtype = %x\n",
+			__func__, iport, iteration, phy_state,
+			tmo, test_bit(IPORT_BCN_PENDING, &iport->flags),
+			attached_device_type);
+
+		switch (phy_state) {
+		case SMP_PHYWAIT_PHYDOWN:
+			/* Has the device gone away? */
+			if (!attached_device_type)
+				phy_state = SMP_PHYWAIT_PHYUP;
+
+			break;
+
+		case SMP_PHYWAIT_PHYUP:
+			/* Has the device come back? */
+			if (attached_device_type)
+				phy_state = SMP_PHYWAIT_DONE;
+			break;
+
+		case SMP_PHYWAIT_DONE:
+			break;
+		}
+
+	}
+	dev_dbg(&ihost->pdev->dev, "%s: done\n",  __func__);
+}
+
+static int isci_reset_device(struct isci_host *ihost,
+			     struct isci_remote_device *idev)
+{
+	struct sas_phy *phy = sas_find_local_phy(idev->domain_dev);
+	struct isci_port *iport = idev->isci_port;
+	enum sci_status status;
+	unsigned long flags;
+	int rc;
+
+	dev_dbg(&ihost->pdev->dev, "%s: idev %p\n", __func__, idev);
+
+	spin_lock_irqsave(&ihost->scic_lock, flags);
+	status = sci_remote_device_reset(idev);
+	if (status != SCI_SUCCESS) {
+		spin_unlock_irqrestore(&ihost->scic_lock, flags);
+
+		dev_dbg(&ihost->pdev->dev,
+			 "%s: sci_remote_device_reset(%p) returned %d!\n",
+			 __func__, idev, status);
+
+		return TMF_RESP_FUNC_FAILED;
+	}
+	spin_unlock_irqrestore(&ihost->scic_lock, flags);
+
+	/* Make sure all pending requests are able to be fully terminated. */
+	isci_device_clear_reset_pending(ihost, idev);
+
+	/* If this is a device on an expander, disable BCN processing. */
+	if (!scsi_is_sas_phy_local(phy))
+		set_bit(IPORT_BCN_BLOCKED, &iport->flags);
+
+	rc = sas_phy_reset(phy, true);
+
+	/* Terminate in-progress I/O now. */
+	isci_remote_device_nuke_requests(ihost, idev);
+
+	/* Since all pending TCs have been cleaned, resume the RNC. */
+	spin_lock_irqsave(&ihost->scic_lock, flags);
+	status = sci_remote_device_reset_complete(idev);
+	spin_unlock_irqrestore(&ihost->scic_lock, flags);
+
+	/* If this is a device on an expander, bring the phy back up. */
+	if (!scsi_is_sas_phy_local(phy)) {
+		/* A phy reset will cause the device to go away then reappear.
+		 * Since libsas will take action on incoming BCNs (eg. remove
+		 * a device going through an SMP phy-control driven reset),
+		 * we need to wait until the phy comes back up before letting
+		 * discovery proceed in libsas.
+		 */
+		isci_wait_for_smp_phy_reset(idev, phy->number);
+
+		spin_lock_irqsave(&ihost->scic_lock, flags);
+		isci_port_bcn_enable(ihost, idev->isci_port);
+		spin_unlock_irqrestore(&ihost->scic_lock, flags);
+	}
+
+	if (status != SCI_SUCCESS) {
+		dev_dbg(&ihost->pdev->dev,
+			 "%s: sci_remote_device_reset_complete(%p) "
+			 "returned %d!\n", __func__, idev, status);
+	}
+
+	dev_dbg(&ihost->pdev->dev, "%s: idev %p complete.\n", __func__, idev);
+
+	return rc;
+}
+
+int isci_task_I_T_nexus_reset(struct domain_device *dev)
+{
+	struct isci_host *ihost = dev_to_ihost(dev);
+	struct isci_remote_device *idev;
+	unsigned long flags;
+	int ret;
+
+	spin_lock_irqsave(&ihost->scic_lock, flags);
+	idev = isci_lookup_device(dev);
+	spin_unlock_irqrestore(&ihost->scic_lock, flags);
+
+	if (!idev || !test_bit(IDEV_EH, &idev->flags)) {
+		ret = TMF_RESP_FUNC_COMPLETE;
+		goto out;
+	}
+
+	ret = isci_reset_device(ihost, idev);
+ out:
+	isci_put_device(idev);
+	return ret;
+}
+
+int isci_bus_reset_handler(struct scsi_cmnd *cmd)
+{
+	struct domain_device *dev = sdev_to_domain_dev(cmd->device);
+	struct isci_host *ihost = dev_to_ihost(dev);
+	struct isci_remote_device *idev;
+	unsigned long flags;
+	int ret;
+
+	spin_lock_irqsave(&ihost->scic_lock, flags);
+	idev = isci_lookup_device(dev);
+	spin_unlock_irqrestore(&ihost->scic_lock, flags);
+
+	if (!idev) {
+		ret = TMF_RESP_FUNC_COMPLETE;
+		goto out;
+	}
+
+	ret = isci_reset_device(ihost, idev);
+ out:
+	isci_put_device(idev);
+	return ret;
+}
diff -druN linux-2.6.39-libre/drivers/scsi/isci/task.h linux-3.0-rc7-libre/drivers/scsi/isci/task.h
--- linux-2.6.39-libre/drivers/scsi/isci/task.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/scsi/isci/task.h	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,367 @@
+/*
+ * This file is provided under a dual BSD/GPLv2 license.  When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * The full GNU General Public License is included in this distribution
+ * in the file called LICENSE.GPL.
+ *
+ * BSD LICENSE
+ *
+ * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in
+ *     the documentation and/or other materials provided with the
+ *     distribution.
+ *   * Neither the name of Intel Corporation nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef _ISCI_TASK_H_
+#define _ISCI_TASK_H_
+
+#include <scsi/sas_ata.h>
+#include "host.h"
+
+struct isci_request;
+
+/**
+ * enum isci_tmf_cb_state - This enum defines the possible states in which the
+ *    TMF callback function is invoked during the TMF execution process.
+ *
+ *
+ */
+enum isci_tmf_cb_state {
+
+	isci_tmf_init_state = 0,
+	isci_tmf_started,
+	isci_tmf_timed_out
+};
+
+/**
+ * enum isci_tmf_function_codes - This enum defines the possible preparations
+ *    of task management requests.
+ *
+ *
+ */
+enum isci_tmf_function_codes {
+
+	isci_tmf_func_none      = 0,
+	isci_tmf_ssp_task_abort = TMF_ABORT_TASK,
+	isci_tmf_ssp_lun_reset  = TMF_LU_RESET,
+	isci_tmf_sata_srst_high = TMF_LU_RESET + 0x100, /* Non SCSI */
+	isci_tmf_sata_srst_low  = TMF_LU_RESET + 0x101  /* Non SCSI */
+};
+/**
+ * struct isci_tmf - This class represents the task management object which
+ *    acts as an interface to libsas for processing task management requests
+ *
+ *
+ */
+struct isci_tmf {
+
+	struct completion *complete;
+	enum sas_protocol proto;
+	union {
+		struct ssp_response_iu resp_iu;
+		struct dev_to_host_fis d2h_fis;
+		u8 rsp_buf[SSP_RESP_IU_MAX_SIZE];
+	} resp;
+	unsigned char lun[8];
+	u16 io_tag;
+	struct isci_remote_device *device;
+	enum isci_tmf_function_codes tmf_code;
+	int status;
+
+	/* The optional callback function allows the user process to
+	 * track the TMF transmit / timeout conditions.
+	 */
+	void (*cb_state_func)(
+		enum isci_tmf_cb_state,
+		struct isci_tmf *, void *);
+	void *cb_data;
+
+};
+
+static inline void isci_print_tmf(struct isci_tmf *tmf)
+{
+	if (SAS_PROTOCOL_SATA == tmf->proto)
+		dev_dbg(&tmf->device->isci_port->isci_host->pdev->dev,
+			"%s: status = %x\n"
+			"tmf->resp.d2h_fis.status = %x\n"
+			"tmf->resp.d2h_fis.error = %x\n",
+			__func__,
+			tmf->status,
+			tmf->resp.d2h_fis.status,
+			tmf->resp.d2h_fis.error);
+	else
+		dev_dbg(&tmf->device->isci_port->isci_host->pdev->dev,
+			"%s: status = %x\n"
+			"tmf->resp.resp_iu.data_present = %x\n"
+			"tmf->resp.resp_iu.status = %x\n"
+			"tmf->resp.resp_iu.data_length = %x\n"
+			"tmf->resp.resp_iu.data[0] = %x\n"
+			"tmf->resp.resp_iu.data[1] = %x\n"
+			"tmf->resp.resp_iu.data[2] = %x\n"
+			"tmf->resp.resp_iu.data[3] = %x\n",
+			__func__,
+			tmf->status,
+			tmf->resp.resp_iu.datapres,
+			tmf->resp.resp_iu.status,
+			be32_to_cpu(tmf->resp.resp_iu.response_data_len),
+			tmf->resp.resp_iu.resp_data[0],
+			tmf->resp.resp_iu.resp_data[1],
+			tmf->resp.resp_iu.resp_data[2],
+			tmf->resp.resp_iu.resp_data[3]);
+}
+
+
+int isci_task_execute_task(
+	struct sas_task *task,
+	int num,
+	gfp_t gfp_flags);
+
+int isci_task_abort_task(
+	struct sas_task *task);
+
+int isci_task_abort_task_set(
+	struct domain_device *d_device,
+	u8 *lun);
+
+int isci_task_clear_aca(
+	struct domain_device *d_device,
+	u8 *lun);
+
+int isci_task_clear_task_set(
+	struct domain_device *d_device,
+	u8 *lun);
+
+int isci_task_query_task(
+	struct sas_task *task);
+
+int isci_task_lu_reset(
+	struct domain_device *d_device,
+	u8 *lun);
+
+int isci_task_clear_nexus_port(
+	struct asd_sas_port *port);
+
+int isci_task_clear_nexus_ha(
+	struct sas_ha_struct *ha);
+
+int isci_task_I_T_nexus_reset(
+	struct domain_device *d_device);
+
+void isci_task_request_complete(
+	struct isci_host *isci_host,
+	struct isci_request *request,
+	enum sci_task_status completion_status);
+
+u16 isci_task_ssp_request_get_io_tag_to_manage(
+	struct isci_request *request);
+
+u8 isci_task_ssp_request_get_function(
+	struct isci_request *request);
+
+
+void *isci_task_ssp_request_get_response_data_address(
+	struct isci_request *request);
+
+u32 isci_task_ssp_request_get_response_data_length(
+	struct isci_request *request);
+
+int isci_queuecommand(
+	struct scsi_cmnd *scsi_cmd,
+	void (*donefunc)(struct scsi_cmnd *));
+
+int isci_bus_reset_handler(struct scsi_cmnd *cmd);
+
+/**
+ * enum isci_completion_selection - This enum defines the possible actions to
+ *    take with respect to a given request's notification back to libsas.
+ *
+ *
+ */
+enum isci_completion_selection {
+
+	isci_perform_normal_io_completion,      /* Normal notify (task_done) */
+	isci_perform_aborted_io_completion,     /* No notification.   */
+	isci_perform_error_io_completion        /* Use sas_task_abort */
+};
+
+static inline void isci_set_task_doneflags(
+	struct sas_task *task)
+{
+	/* Since no futher action will be taken on this task,
+	 * make sure to mark it complete from the lldd perspective.
+	 */
+	task->task_state_flags |= SAS_TASK_STATE_DONE;
+	task->task_state_flags &= ~SAS_TASK_AT_INITIATOR;
+	task->task_state_flags &= ~SAS_TASK_STATE_PENDING;
+}
+/**
+ * isci_task_all_done() - This function clears the task bits to indicate the
+ *    LLDD is done with the task.
+ *
+ *
+ */
+static inline void isci_task_all_done(
+	struct sas_task *task)
+{
+	unsigned long flags;
+
+	/* Since no futher action will be taken on this task,
+	 * make sure to mark it complete from the lldd perspective.
+	 */
+	spin_lock_irqsave(&task->task_state_lock, flags);
+	isci_set_task_doneflags(task);
+	spin_unlock_irqrestore(&task->task_state_lock, flags);
+}
+
+/**
+ * isci_task_set_completion_status() - This function sets the completion status
+ *    for the request.
+ * @task: This parameter is the completed request.
+ * @response: This parameter is the response code for the completed task.
+ * @status: This parameter is the status code for the completed task.
+ *
+* @return The new notification mode for the request.
+*/
+static inline enum isci_completion_selection
+isci_task_set_completion_status(
+	struct sas_task *task,
+	enum service_response response,
+	enum exec_status status,
+	enum isci_completion_selection task_notification_selection)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&task->task_state_lock, flags);
+
+	/* If a device reset is being indicated, make sure the I/O
+	* is in the error path.
+	*/
+	if (task->task_state_flags & SAS_TASK_NEED_DEV_RESET) {
+		/* Fail the I/O to make sure it goes into the error path. */
+		response = SAS_TASK_UNDELIVERED;
+		status = SAM_STAT_TASK_ABORTED;
+
+		task_notification_selection = isci_perform_error_io_completion;
+	}
+	task->task_status.resp = response;
+	task->task_status.stat = status;
+
+	switch (task_notification_selection) {
+
+	case isci_perform_error_io_completion:
+
+		if (task->task_proto == SAS_PROTOCOL_SMP) {
+			/* There is no error escalation in the SMP case.
+			 * Convert to a normal completion to avoid the
+			 * timeout in the discovery path and to let the
+			 * next action take place quickly.
+			 */
+			task_notification_selection
+				= isci_perform_normal_io_completion;
+
+			/* Fall through to the normal case... */
+		} else {
+			/* Use sas_task_abort */
+			/* Leave SAS_TASK_STATE_DONE clear
+			 * Leave SAS_TASK_AT_INITIATOR set.
+			 */
+			break;
+		}
+
+	case isci_perform_aborted_io_completion:
+		/* This path can occur with task-managed requests as well as
+		 * requests terminated because of LUN or device resets.
+		 */
+		/* Fall through to the normal case... */
+	case isci_perform_normal_io_completion:
+		/* Normal notification (task_done) */
+		isci_set_task_doneflags(task);
+		break;
+	default:
+		WARN_ONCE(1, "unknown task_notification_selection: %d\n",
+			 task_notification_selection);
+		break;
+	}
+
+	spin_unlock_irqrestore(&task->task_state_lock, flags);
+
+	return task_notification_selection;
+
+}
+/**
+* isci_execpath_callback() - This function is called from the task
+* execute path when the task needs to callback libsas about the submit-time
+* task failure.  The callback occurs either through the task's done function
+* or through sas_task_abort.  In the case of regular non-discovery SATA/STP I/O
+* requests, libsas takes the host lock before calling execute task.  Therefore
+* in this situation the host lock must be managed before calling the func.
+*
+* @ihost: This parameter is the controller to which the I/O request was sent.
+* @task: This parameter is the I/O request.
+* @func: This parameter is the function to call in the correct context.
+* @status: This parameter is the status code for the completed task.
+*
+*/
+static inline void isci_execpath_callback(struct isci_host *ihost,
+					  struct sas_task  *task,
+					  void (*func)(struct sas_task *))
+{
+	struct domain_device *dev = task->dev;
+
+	if (dev_is_sata(dev) && task->uldd_task) {
+		unsigned long flags;
+
+		/* Since we are still in the submit path, and since
+		 * libsas takes the host lock on behalf of SATA
+		 * devices before I/O starts (in the non-discovery case),
+		 * we need to unlock before we can call the callback function.
+		 */
+		raw_local_irq_save(flags);
+		spin_unlock(dev->sata_dev.ap->lock);
+		func(task);
+		spin_lock(dev->sata_dev.ap->lock);
+		raw_local_irq_restore(flags);
+	} else
+		func(task);
+}
+#endif /* !defined(_SCI_TASK_H_) */
diff -druN linux-2.6.39-libre/drivers/scsi/isci/unsolicited_frame_control.c linux-3.0-rc7-libre/drivers/scsi/isci/unsolicited_frame_control.c
--- linux-2.6.39-libre/drivers/scsi/isci/unsolicited_frame_control.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/scsi/isci/unsolicited_frame_control.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,225 @@
+/*
+ * This file is provided under a dual BSD/GPLv2 license.  When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * The full GNU General Public License is included in this distribution
+ * in the file called LICENSE.GPL.
+ *
+ * BSD LICENSE
+ *
+ * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in
+ *     the documentation and/or other materials provided with the
+ *     distribution.
+ *   * Neither the name of Intel Corporation nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "host.h"
+#include "unsolicited_frame_control.h"
+#include "registers.h"
+
+int sci_unsolicited_frame_control_construct(struct isci_host *ihost)
+{
+	struct sci_unsolicited_frame_control *uf_control = &ihost->uf_control;
+	struct sci_unsolicited_frame *uf;
+	u32 buf_len, header_len, i;
+	dma_addr_t dma;
+	size_t size;
+	void *virt;
+
+	/*
+	 * Prepare all of the memory sizes for the UF headers, UF address
+	 * table, and UF buffers themselves.
+	 */
+	buf_len = SCU_MAX_UNSOLICITED_FRAMES * SCU_UNSOLICITED_FRAME_BUFFER_SIZE;
+	header_len = SCU_MAX_UNSOLICITED_FRAMES * sizeof(struct scu_unsolicited_frame_header);
+	size = buf_len + header_len + SCU_MAX_UNSOLICITED_FRAMES * sizeof(dma_addr_t);
+
+	/*
+	 * The Unsolicited Frame buffers are set at the start of the UF
+	 * memory descriptor entry. The headers and address table will be
+	 * placed after the buffers.
+	 */
+	virt = dmam_alloc_coherent(&ihost->pdev->dev, size, &dma, GFP_KERNEL);
+	if (!virt)
+		return -ENOMEM;
+
+	/*
+	 * Program the location of the UF header table into the SCU.
+	 * Notes:
+	 * - The address must align on a 64-byte boundary. Guaranteed to be
+	 *   on 64-byte boundary already 1KB boundary for unsolicited frames.
+	 * - Program unused header entries to overlap with the last
+	 *   unsolicited frame.  The silicon will never DMA to these unused
+	 *   headers, since we program the UF address table pointers to
+	 *   NULL.
+	 */
+	uf_control->headers.physical_address = dma + buf_len;
+	uf_control->headers.array = virt + buf_len;
+
+	/*
+	 * Program the location of the UF address table into the SCU.
+	 * Notes:
+	 * - The address must align on a 64-bit boundary. Guaranteed to be on 64
+	 *   byte boundary already due to above programming headers being on a
+	 *   64-bit boundary and headers are on a 64-bytes in size.
+	 */
+	uf_control->address_table.physical_address = dma + buf_len + header_len;
+	uf_control->address_table.array = virt + buf_len + header_len;
+	uf_control->get = 0;
+
+	/*
+	 * UF buffer requirements are:
+	 * - The last entry in the UF queue is not NULL.
+	 * - There is a power of 2 number of entries (NULL or not-NULL)
+	 *   programmed into the queue.
+	 * - Aligned on a 1KB boundary. */
+
+	/*
+	 * Program the actual used UF buffers into the UF address table and
+	 * the controller's array of UFs.
+	 */
+	for (i = 0; i < SCU_MAX_UNSOLICITED_FRAMES; i++) {
+		uf = &uf_control->buffers.array[i];
+
+		uf_control->address_table.array[i] = dma;
+
+		uf->buffer = virt;
+		uf->header = &uf_control->headers.array[i];
+		uf->state  = UNSOLICITED_FRAME_EMPTY;
+
+		/*
+		 * Increment the address of the physical and virtual memory
+		 * pointers. Everything is aligned on 1k boundary with an
+		 * increment of 1k.
+		 */
+		virt += SCU_UNSOLICITED_FRAME_BUFFER_SIZE;
+		dma += SCU_UNSOLICITED_FRAME_BUFFER_SIZE;
+	}
+
+	return 0;
+}
+
+enum sci_status sci_unsolicited_frame_control_get_header(struct sci_unsolicited_frame_control *uf_control,
+							 u32 frame_index,
+							 void **frame_header)
+{
+	if (frame_index < SCU_MAX_UNSOLICITED_FRAMES) {
+		/* Skip the first word in the frame since this is a controll word used
+		 * by the hardware.
+		 */
+		*frame_header = &uf_control->buffers.array[frame_index].header->data;
+
+		return SCI_SUCCESS;
+	}
+
+	return SCI_FAILURE_INVALID_PARAMETER_VALUE;
+}
+
+enum sci_status sci_unsolicited_frame_control_get_buffer(struct sci_unsolicited_frame_control *uf_control,
+							 u32 frame_index,
+							 void **frame_buffer)
+{
+	if (frame_index < SCU_MAX_UNSOLICITED_FRAMES) {
+		*frame_buffer = uf_control->buffers.array[frame_index].buffer;
+
+		return SCI_SUCCESS;
+	}
+
+	return SCI_FAILURE_INVALID_PARAMETER_VALUE;
+}
+
+bool sci_unsolicited_frame_control_release_frame(struct sci_unsolicited_frame_control *uf_control,
+						 u32 frame_index)
+{
+	u32 frame_get;
+	u32 frame_cycle;
+
+	frame_get   = uf_control->get & (SCU_MAX_UNSOLICITED_FRAMES - 1);
+	frame_cycle = uf_control->get & SCU_MAX_UNSOLICITED_FRAMES;
+
+	/*
+	 * In the event there are NULL entries in the UF table, we need to
+	 * advance the get pointer in order to find out if this frame should
+	 * be released (i.e. update the get pointer)
+	 */
+	while (lower_32_bits(uf_control->address_table.array[frame_get]) == 0 &&
+	       upper_32_bits(uf_control->address_table.array[frame_get]) == 0 &&
+	       frame_get < SCU_MAX_UNSOLICITED_FRAMES)
+		frame_get++;
+
+	/*
+	 * The table has a NULL entry as it's last element.  This is
+	 * illegal.
+	 */
+	BUG_ON(frame_get >= SCU_MAX_UNSOLICITED_FRAMES);
+	if (frame_index >= SCU_MAX_UNSOLICITED_FRAMES)
+		return false;
+
+	uf_control->buffers.array[frame_index].state = UNSOLICITED_FRAME_RELEASED;
+
+	if (frame_get != frame_index) {
+		/*
+		 * Frames remain in use until we advance the get pointer
+		 * so there is nothing we can do here
+		 */
+		return false;
+	}
+
+	/*
+	 * The frame index is equal to the current get pointer so we
+	 * can now free up all of the frame entries that
+	 */
+	while (uf_control->buffers.array[frame_get].state == UNSOLICITED_FRAME_RELEASED) {
+		uf_control->buffers.array[frame_get].state = UNSOLICITED_FRAME_EMPTY;
+
+		if (frame_get+1 == SCU_MAX_UNSOLICITED_FRAMES-1) {
+			frame_cycle ^= SCU_MAX_UNSOLICITED_FRAMES;
+			frame_get = 0;
+		} else
+			frame_get++;
+	}
+
+	uf_control->get = SCU_UFQGP_GEN_BIT(ENABLE_BIT) | frame_cycle | frame_get;
+
+	return true;
+}
diff -druN linux-2.6.39-libre/drivers/scsi/isci/unsolicited_frame_control.h linux-3.0-rc7-libre/drivers/scsi/isci/unsolicited_frame_control.h
--- linux-2.6.39-libre/drivers/scsi/isci/unsolicited_frame_control.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/scsi/isci/unsolicited_frame_control.h	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,278 @@
+/*
+ * This file is provided under a dual BSD/GPLv2 license.  When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * GPL LICENSE SUMMARY
+ *
+ * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ * The full GNU General Public License is included in this distribution
+ * in the file called LICENSE.GPL.
+ *
+ * BSD LICENSE
+ *
+ * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in
+ *     the documentation and/or other materials provided with the
+ *     distribution.
+ *   * Neither the name of Intel Corporation nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _SCIC_SDS_UNSOLICITED_FRAME_CONTROL_H_
+#define _SCIC_SDS_UNSOLICITED_FRAME_CONTROL_H_
+
+#include "isci.h"
+
+#define SCU_UNSOLICITED_FRAME_HEADER_DATA_DWORDS 15
+
+/**
+ * struct scu_unsolicited_frame_header -
+ *
+ * This structure delineates the format of an unsolicited frame header. The
+ * first DWORD are UF attributes defined by the silicon architecture. The data
+ * depicts actual header information received on the link.
+ */
+struct scu_unsolicited_frame_header {
+	/**
+	 * This field indicates if there is an Initiator Index Table entry with
+	 * which this header is associated.
+	 */
+	u32 iit_exists:1;
+
+	/**
+	 * This field simply indicates the protocol type (i.e. SSP, STP, SMP).
+	 */
+	u32 protocol_type:3;
+
+	/**
+	 * This field indicates if the frame is an address frame (IAF or OAF)
+	 * or if it is a information unit frame.
+	 */
+	u32 is_address_frame:1;
+
+	/**
+	 * This field simply indicates the connection rate at which the frame
+	 * was received.
+	 */
+	u32 connection_rate:4;
+
+	u32 reserved:23;
+
+	/**
+	 * This field represents the actual header data received on the link.
+	 */
+	u32 data[SCU_UNSOLICITED_FRAME_HEADER_DATA_DWORDS];
+
+};
+
+
+
+/**
+ * enum unsolicited_frame_state -
+ *
+ * This enumeration represents the current unsolicited frame state.  The
+ * controller object can not updtate the hardware unsolicited frame put pointer
+ * unless it has already processed the priror unsolicited frames.
+ */
+enum unsolicited_frame_state {
+	/**
+	 * This state is when the frame is empty and not in use.  It is
+	 * different from the released state in that the hardware could DMA
+	 * data to this frame buffer.
+	 */
+	UNSOLICITED_FRAME_EMPTY,
+
+	/**
+	 * This state is set when the frame buffer is in use by by some
+	 * object in the system.
+	 */
+	UNSOLICITED_FRAME_IN_USE,
+
+	/**
+	 * This state is set when the frame is returned to the free pool
+	 * but one or more frames prior to this one are still in use.
+	 * Once all of the frame before this one are freed it will go to
+	 * the empty state.
+	 */
+	UNSOLICITED_FRAME_RELEASED,
+
+	UNSOLICITED_FRAME_MAX_STATES
+};
+
+/**
+ * struct sci_unsolicited_frame -
+ *
+ * This is the unsolicited frame data structure it acts as the container for
+ * the current frame state, frame header and frame buffer.
+ */
+struct sci_unsolicited_frame {
+	/**
+	 * This field contains the current frame state
+	 */
+	enum unsolicited_frame_state state;
+
+	/**
+	 * This field points to the frame header data.
+	 */
+	struct scu_unsolicited_frame_header *header;
+
+	/**
+	 * This field points to the frame buffer data.
+	 */
+	void *buffer;
+
+};
+
+/**
+ * struct sci_uf_header_array -
+ *
+ * This structure contains all of the unsolicited frame header information.
+ */
+struct sci_uf_header_array {
+	/**
+	 * This field is represents a virtual pointer to the start
+	 * address of the UF address table.  The table contains
+	 * 64-bit pointers as required by the hardware.
+	 */
+	struct scu_unsolicited_frame_header *array;
+
+	/**
+	 * This field specifies the physical address location for the UF
+	 * buffer array.
+	 */
+	dma_addr_t physical_address;
+
+};
+
+/**
+ * struct sci_uf_buffer_array -
+ *
+ * This structure contains all of the unsolicited frame buffer (actual payload)
+ * information.
+ */
+struct sci_uf_buffer_array {
+	/**
+	 * This field is the unsolicited frame data its used to manage
+	 * the data for the unsolicited frame requests.  It also represents
+	 * the virtual address location that corresponds to the
+	 * physical_address field.
+	 */
+	struct sci_unsolicited_frame array[SCU_MAX_UNSOLICITED_FRAMES];
+
+	/**
+	 * This field specifies the physical address location for the UF
+	 * buffer array.
+	 */
+	dma_addr_t physical_address;
+};
+
+/**
+ * struct sci_uf_address_table_array -
+ *
+ * This object maintains all of the unsolicited frame address table specific
+ * data.  The address table is a collection of 64-bit pointers that point to
+ * 1KB buffers into which the silicon will DMA unsolicited frames.
+ */
+struct sci_uf_address_table_array {
+	/**
+	 * This field represents a virtual pointer that refers to the
+	 * starting address of the UF address table.
+	 * 64-bit pointers are required by the hardware.
+	 */
+	dma_addr_t *array;
+
+	/**
+	 * This field specifies the physical address location for the UF
+	 * address table.
+	 */
+	dma_addr_t physical_address;
+
+};
+
+/**
+ * struct sci_unsolicited_frame_control -
+ *
+ * This object contains all of the data necessary to handle unsolicited frames.
+ */
+struct sci_unsolicited_frame_control {
+	/**
+	 * This field is the software copy of the unsolicited frame queue
+	 * get pointer.  The controller object writes this value to the
+	 * hardware to let the hardware put more unsolicited frame entries.
+	 */
+	u32 get;
+
+	/**
+	 * This field contains all of the unsolicited frame header
+	 * specific fields.
+	 */
+	struct sci_uf_header_array headers;
+
+	/**
+	 * This field contains all of the unsolicited frame buffer
+	 * specific fields.
+	 */
+	struct sci_uf_buffer_array buffers;
+
+	/**
+	 * This field contains all of the unsolicited frame address table
+	 * specific fields.
+	 */
+	struct sci_uf_address_table_array address_table;
+
+};
+
+struct isci_host;
+
+int sci_unsolicited_frame_control_construct(struct isci_host *ihost);
+
+enum sci_status sci_unsolicited_frame_control_get_header(
+	struct sci_unsolicited_frame_control *uf_control,
+	u32 frame_index,
+	void **frame_header);
+
+enum sci_status sci_unsolicited_frame_control_get_buffer(
+	struct sci_unsolicited_frame_control *uf_control,
+	u32 frame_index,
+	void **frame_buffer);
+
+bool sci_unsolicited_frame_control_release_frame(
+	struct sci_unsolicited_frame_control *uf_control,
+	u32 frame_index);
+
+#endif /* _SCIC_SDS_UNSOLICITED_FRAME_CONTROL_H_ */
diff -druN linux-2.6.39-libre/drivers/scsi/Kconfig linux-3.0-rc7-libre/drivers/scsi/Kconfig
--- linux-2.6.39-libre/drivers/scsi/Kconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/scsi/Kconfig	2011-07-11 19:51:52.000000000 -0400
@@ -830,6 +830,19 @@
 	  To compile this driver as a module, choose M here: the
 	  module will be called gdth.
 
+config SCSI_ISCI
+	tristate "Intel(R) C600 Series Chipset SAS Controller"
+	depends on PCI && SCSI
+	depends on X86
+	# (temporary): known alpha quality driver
+	depends on EXPERIMENTAL
+	select SCSI_SAS_LIBSAS
+	---help---
+	  This driver supports the 6Gb/s SAS capabilities of the storage
+	  control unit found in the Intel(R) C600 series chipset.
+
+	  The experimental tag will be removed after the driver exits alpha
+
 config SCSI_GENERIC_NCR5380
 	tristate "Generic NCR5380/53c400 SCSI PIO support"
 	depends on ISA && SCSI
diff -druN linux-2.6.39-libre/drivers/scsi/libfc/fc_disc.c linux-3.0-rc7-libre/drivers/scsi/libfc/fc_disc.c
--- linux-2.6.39-libre/drivers/scsi/libfc/fc_disc.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/scsi/libfc/fc_disc.c	2011-07-11 19:51:52.000000000 -0400
@@ -205,6 +205,7 @@
 	default:
 		FC_DISC_DBG(disc, "Received an unsupported request, "
 			    "the opcode is (%x)\n", op);
+		fc_frame_free(fp);
 		break;
 	}
 }
diff -druN linux-2.6.39-libre/drivers/scsi/libfc/fc_exch.c linux-3.0-rc7-libre/drivers/scsi/libfc/fc_exch.c
--- linux-2.6.39-libre/drivers/scsi/libfc/fc_exch.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/scsi/libfc/fc_exch.c	2011-07-11 19:51:52.000000000 -0400
@@ -1434,6 +1434,7 @@
 	    (f_ctl & (FC_FC_LAST_SEQ | FC_FC_END_SEQ)) ==
 	    (FC_FC_LAST_SEQ | FC_FC_END_SEQ)) {
 		spin_lock_bh(&ep->ex_lock);
+		resp = ep->resp;
 		rc = fc_exch_done_locked(ep);
 		WARN_ON(fc_seq_exch(sp) != ep);
 		spin_unlock_bh(&ep->ex_lock);
@@ -1978,6 +1979,7 @@
 	spin_unlock_bh(&ep->ex_lock);
 	return sp;
 err:
+	fc_fcp_ddp_done(fr_fsp(fp));
 	rc = fc_exch_done_locked(ep);
 	spin_unlock_bh(&ep->ex_lock);
 	if (!rc)
diff -druN linux-2.6.39-libre/drivers/scsi/libfc/fc_fcp.c linux-3.0-rc7-libre/drivers/scsi/libfc/fc_fcp.c
--- linux-2.6.39-libre/drivers/scsi/libfc/fc_fcp.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/scsi/libfc/fc_fcp.c	2011-07-11 19:51:52.000000000 -0400
@@ -57,9 +57,6 @@
 #define FC_SRB_READ		(1 << 1)
 #define FC_SRB_WRITE		(1 << 0)
 
-/* constant added to e_d_tov timeout to get rec_tov value */
-#define REC_TOV_CONST		1
-
 /*
  * The SCp.ptr should be tested and set under the scsi_pkt_queue lock
  */
@@ -248,7 +245,7 @@
 /**
  * fc_fcp_timer_set() - Start a timer for a fcp_pkt
  * @fsp:   The FCP packet to start a timer for
- * @delay: The timeout period for the timer
+ * @delay: The timeout period in jiffies
  */
 static void fc_fcp_timer_set(struct fc_fcp_pkt *fsp, unsigned long delay)
 {
@@ -315,7 +312,7 @@
  *		       DDP related resources for a fcp_pkt
  * @fsp: The FCP packet that DDP had been used on
  */
-static void fc_fcp_ddp_done(struct fc_fcp_pkt *fsp)
+void fc_fcp_ddp_done(struct fc_fcp_pkt *fsp)
 {
 	struct fc_lport *lport;
 
@@ -335,22 +332,23 @@
 /**
  * fc_fcp_can_queue_ramp_up() - increases can_queue
  * @lport: lport to ramp up can_queue
- *
- * Locking notes: Called with Scsi_Host lock held
  */
 static void fc_fcp_can_queue_ramp_up(struct fc_lport *lport)
 {
 	struct fc_fcp_internal *si = fc_get_scsi_internal(lport);
+	unsigned long flags;
 	int can_queue;
 
+	spin_lock_irqsave(lport->host->host_lock, flags);
+
 	if (si->last_can_queue_ramp_up_time &&
 	    (time_before(jiffies, si->last_can_queue_ramp_up_time +
 			 FC_CAN_QUEUE_PERIOD)))
-		return;
+		goto unlock;
 
 	if (time_before(jiffies, si->last_can_queue_ramp_down_time +
 			FC_CAN_QUEUE_PERIOD))
-		return;
+		goto unlock;
 
 	si->last_can_queue_ramp_up_time = jiffies;
 
@@ -362,6 +360,9 @@
 	lport->host->can_queue = can_queue;
 	shost_printk(KERN_ERR, lport->host, "libfc: increased "
 		     "can_queue to %d.\n", can_queue);
+
+unlock:
+	spin_unlock_irqrestore(lport->host->host_lock, flags);
 }
 
 /**
@@ -373,18 +374,19 @@
  * commands complete or timeout, then try again with a reduced
  * can_queue. Eventually we will hit the point where we run
  * on all reserved structs.
- *
- * Locking notes: Called with Scsi_Host lock held
  */
 static void fc_fcp_can_queue_ramp_down(struct fc_lport *lport)
 {
 	struct fc_fcp_internal *si = fc_get_scsi_internal(lport);
+	unsigned long flags;
 	int can_queue;
 
+	spin_lock_irqsave(lport->host->host_lock, flags);
+
 	if (si->last_can_queue_ramp_down_time &&
 	    (time_before(jiffies, si->last_can_queue_ramp_down_time +
 			 FC_CAN_QUEUE_PERIOD)))
-		return;
+		goto unlock;
 
 	si->last_can_queue_ramp_down_time = jiffies;
 
@@ -395,6 +397,9 @@
 	lport->host->can_queue = can_queue;
 	shost_printk(KERN_ERR, lport->host, "libfc: Could not allocate frame.\n"
 		     "Reducing can_queue to %d.\n", can_queue);
+
+unlock:
+	spin_unlock_irqrestore(lport->host->host_lock, flags);
 }
 
 /*
@@ -409,16 +414,13 @@
 						  size_t len)
 {
 	struct fc_frame *fp;
-	unsigned long flags;
 
 	fp = fc_frame_alloc(lport, len);
 	if (likely(fp))
 		return fp;
 
 	/* error case */
-	spin_lock_irqsave(lport->host->host_lock, flags);
 	fc_fcp_can_queue_ramp_down(lport);
-	spin_unlock_irqrestore(lport->host->host_lock, flags);
 	return NULL;
 }
 
@@ -679,8 +681,7 @@
 		error = lport->tt.seq_send(lport, seq, fp);
 		if (error) {
 			WARN_ON(1);		/* send error should be rare */
-			fc_fcp_retry_cmd(fsp);
-			return 0;
+			return error;
 		}
 		fp = NULL;
 	}
@@ -1093,16 +1094,14 @@
 /**
  * get_fsp_rec_tov() - Helper function to get REC_TOV
  * @fsp: the FCP packet
+ *
+ * Returns rec tov in jiffies as rpriv->e_d_tov + 1 second
  */
 static inline unsigned int get_fsp_rec_tov(struct fc_fcp_pkt *fsp)
 {
-	struct fc_rport *rport;
-	struct fc_rport_libfc_priv *rpriv;
-
-	rport = fsp->rport;
-	rpriv = rport->dd_data;
+	struct fc_rport_libfc_priv *rpriv = fsp->rport->dd_data;
 
-	return rpriv->e_d_tov + REC_TOV_CONST;
+	return msecs_to_jiffies(rpriv->e_d_tov) + HZ;
 }
 
 /**
@@ -1122,7 +1121,6 @@
 	struct fc_rport_libfc_priv *rpriv;
 	const size_t len = sizeof(fsp->cdb_cmd);
 	int rc = 0;
-	unsigned int rec_tov;
 
 	if (fc_fcp_lock_pkt(fsp))
 		return 0;
@@ -1153,12 +1151,9 @@
 	fsp->seq_ptr = seq;
 	fc_fcp_pkt_hold(fsp);	/* hold for fc_fcp_pkt_destroy */
 
-	rec_tov = get_fsp_rec_tov(fsp);
-
 	setup_timer(&fsp->timer, fc_fcp_timeout, (unsigned long)fsp);
-
 	if (rpriv->flags & FC_RP_FLAGS_REC_SUPPORTED)
-		fc_fcp_timer_set(fsp, rec_tov);
+		fc_fcp_timer_set(fsp, get_fsp_rec_tov(fsp));
 
 unlock:
 	fc_fcp_unlock_pkt(fsp);
@@ -1235,16 +1230,14 @@
 {
 	struct fc_fcp_pkt *fsp = (struct fc_fcp_pkt *)data;
 	struct fc_lport *lport = fsp->lp;
-	unsigned int rec_tov;
 
 	if (lport->tt.fcp_cmd_send(lport, fsp, fc_tm_done)) {
 		if (fsp->recov_retry++ >= FC_MAX_RECOV_RETRY)
 			return;
 		if (fc_fcp_lock_pkt(fsp))
 			return;
-		rec_tov = get_fsp_rec_tov(fsp);
 		setup_timer(&fsp->timer, fc_lun_reset_send, (unsigned long)fsp);
-		fc_fcp_timer_set(fsp, rec_tov);
+		fc_fcp_timer_set(fsp, get_fsp_rec_tov(fsp));
 		fc_fcp_unlock_pkt(fsp);
 	}
 }
@@ -1536,12 +1529,11 @@
 			}
 			fc_fcp_srr(fsp, r_ctl, offset);
 		} else if (e_stat & ESB_ST_SEQ_INIT) {
-			unsigned int rec_tov = get_fsp_rec_tov(fsp);
 			/*
 			 * The remote port has the initiative, so just
 			 * keep waiting for it to complete.
 			 */
-			fc_fcp_timer_set(fsp, rec_tov);
+			fc_fcp_timer_set(fsp,  get_fsp_rec_tov(fsp));
 		} else {
 
 			/*
@@ -1680,7 +1672,8 @@
 		       FC_FCTL_REQ, 0);
 
 	rec_tov = get_fsp_rec_tov(fsp);
-	seq = lport->tt.exch_seq_send(lport, fp, fc_fcp_srr_resp, NULL,
+	seq = lport->tt.exch_seq_send(lport, fp, fc_fcp_srr_resp,
+				      fc_fcp_pkt_destroy,
 				      fsp, jiffies_to_msecs(rec_tov));
 	if (!seq)
 		goto retry;
@@ -1705,7 +1698,6 @@
 {
 	struct fc_fcp_pkt *fsp = arg;
 	struct fc_frame_header *fh;
-	unsigned int rec_tov;
 
 	if (IS_ERR(fp)) {
 		fc_fcp_srr_error(fsp, fp);
@@ -1728,12 +1720,10 @@
 		return;
 	}
 
-	fsp->recov_seq = NULL;
 	switch (fc_frame_payload_op(fp)) {
 	case ELS_LS_ACC:
 		fsp->recov_retry = 0;
-		rec_tov = get_fsp_rec_tov(fsp);
-		fc_fcp_timer_set(fsp, rec_tov);
+		fc_fcp_timer_set(fsp, get_fsp_rec_tov(fsp));
 		break;
 	case ELS_LS_RJT:
 	default:
@@ -1741,10 +1731,9 @@
 		break;
 	}
 	fc_fcp_unlock_pkt(fsp);
-	fsp->lp->tt.exch_done(seq);
 out:
+	fsp->lp->tt.exch_done(seq);
 	fc_frame_free(fp);
-	fc_fcp_pkt_release(fsp);	/* drop hold for outstanding SRR */
 }
 
 /**
@@ -1756,8 +1745,6 @@
 {
 	if (fc_fcp_lock_pkt(fsp))
 		goto out;
-	fsp->lp->tt.exch_done(fsp->recov_seq);
-	fsp->recov_seq = NULL;
 	switch (PTR_ERR(fp)) {
 	case -FC_EX_TIMEOUT:
 		if (fsp->recov_retry++ < FC_MAX_RECOV_RETRY)
@@ -1773,7 +1760,7 @@
 	}
 	fc_fcp_unlock_pkt(fsp);
 out:
-	fc_fcp_pkt_release(fsp);	/* drop hold for outstanding SRR */
+	fsp->lp->tt.exch_done(fsp->recov_seq);
 }
 
 /**
diff -druN linux-2.6.39-libre/drivers/scsi/libfc/fc_libfc.h linux-3.0-rc7-libre/drivers/scsi/libfc/fc_libfc.h
--- linux-2.6.39-libre/drivers/scsi/libfc/fc_libfc.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/scsi/libfc/fc_libfc.h	2011-07-11 19:51:52.000000000 -0400
@@ -108,6 +108,7 @@
  * Set up direct-data placement for this I/O request
  */
 void fc_fcp_ddp_setup(struct fc_fcp_pkt *fsp, u16 xid);
+void fc_fcp_ddp_done(struct fc_fcp_pkt *fsp);
 
 /*
  * Module setup functions
diff -druN linux-2.6.39-libre/drivers/scsi/libfc/fc_lport.c linux-3.0-rc7-libre/drivers/scsi/libfc/fc_lport.c
--- linux-2.6.39-libre/drivers/scsi/libfc/fc_lport.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/scsi/libfc/fc_lport.c	2011-07-11 19:51:52.000000000 -0400
@@ -1590,7 +1590,6 @@
  */
 int fc_lport_config(struct fc_lport *lport)
 {
-	INIT_LIST_HEAD(&lport->ema_list);
 	INIT_DELAYED_WORK(&lport->retry_work, fc_lport_timeout);
 	mutex_init(&lport->lp_mutex);
 
diff -druN linux-2.6.39-libre/drivers/scsi/libsas/sas_ata.c linux-3.0-rc7-libre/drivers/scsi/libsas/sas_ata.c
--- linux-2.6.39-libre/drivers/scsi/libsas/sas_ata.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/scsi/libsas/sas_ata.c	2011-07-11 19:51:52.000000000 -0400
@@ -99,19 +99,29 @@
 	struct sas_ha_struct *sas_ha;
 	enum ata_completion_errors ac;
 	unsigned long flags;
+	struct ata_link *link;
 
 	if (!qc)
 		goto qc_already_gone;
 
 	dev = qc->ap->private_data;
 	sas_ha = dev->port->ha;
+	link = &dev->sata_dev.ap->link;
 
 	spin_lock_irqsave(dev->sata_dev.ap->lock, flags);
 	if (stat->stat == SAS_PROTO_RESPONSE || stat->stat == SAM_STAT_GOOD ||
 	    ((stat->stat == SAM_STAT_CHECK_CONDITION &&
 	      dev->sata_dev.command_set == ATAPI_COMMAND_SET))) {
 		ata_tf_from_fis(resp->ending_fis, &dev->sata_dev.tf);
-		qc->err_mask |= ac_err_mask(dev->sata_dev.tf.command);
+
+		if (!link->sactive) {
+			qc->err_mask |= ac_err_mask(dev->sata_dev.tf.command);
+		} else {
+			link->eh_info.err_mask |= ac_err_mask(dev->sata_dev.tf.command);
+			if (unlikely(link->eh_info.err_mask))
+				qc->flags |= ATA_QCFLAG_FAILED;
+		}
+
 		dev->sata_dev.sstatus = resp->sstatus;
 		dev->sata_dev.serror = resp->serror;
 		dev->sata_dev.scontrol = resp->scontrol;
@@ -121,7 +131,13 @@
 			SAS_DPRINTK("%s: SAS error %x\n", __func__,
 				    stat->stat);
 			/* We saw a SAS error. Send a vague error. */
-			qc->err_mask = ac;
+			if (!link->sactive) {
+				qc->err_mask = ac;
+			} else {
+				link->eh_info.err_mask |= AC_ERR_DEV;
+				qc->flags |= ATA_QCFLAG_FAILED;
+			}
+
 			dev->sata_dev.tf.feature = 0x04; /* status err */
 			dev->sata_dev.tf.command = ATA_ERR;
 		}
@@ -279,6 +295,44 @@
 	return ret;
 }
 
+static int sas_ata_soft_reset(struct ata_link *link, unsigned int *class,
+			       unsigned long deadline)
+{
+	struct ata_port *ap = link->ap;
+	struct domain_device *dev = ap->private_data;
+	struct sas_internal *i =
+		to_sas_internal(dev->port->ha->core.shost->transportt);
+	int res = TMF_RESP_FUNC_FAILED;
+	int ret = 0;
+
+	if (i->dft->lldd_ata_soft_reset)
+		res = i->dft->lldd_ata_soft_reset(dev);
+
+	if (res != TMF_RESP_FUNC_COMPLETE) {
+		SAS_DPRINTK("%s: Unable to soft reset\n", __func__);
+		ret = -EAGAIN;
+	}
+
+	switch (dev->sata_dev.command_set) {
+	case ATA_COMMAND_SET:
+		SAS_DPRINTK("%s: Found ATA device.\n", __func__);
+		*class = ATA_DEV_ATA;
+		break;
+	case ATAPI_COMMAND_SET:
+		SAS_DPRINTK("%s: Found ATAPI device.\n", __func__);
+		*class = ATA_DEV_ATAPI;
+		break;
+	default:
+		SAS_DPRINTK("%s: Unknown SATA command set: %d.\n",
+			    __func__, dev->sata_dev.command_set);
+		*class = ATA_DEV_UNKNOWN;
+		break;
+	}
+
+	ap->cbl = ATA_CBL_SATA;
+	return ret;
+}
+
 static void sas_ata_post_internal(struct ata_queued_cmd *qc)
 {
 	if (qc->flags & ATA_QCFLAG_FAILED)
@@ -309,7 +363,7 @@
 
 static struct ata_port_operations sas_sata_ops = {
 	.prereset		= ata_std_prereset,
-	.softreset		= NULL,
+	.softreset		= sas_ata_soft_reset,
 	.hardreset		= sas_ata_hard_reset,
 	.postreset		= ata_std_postreset,
 	.error_handler		= ata_std_error_handler,
diff -druN linux-2.6.39-libre/drivers/scsi/libsas/sas_internal.h linux-3.0-rc7-libre/drivers/scsi/libsas/sas_internal.h
--- linux-2.6.39-libre/drivers/scsi/libsas/sas_internal.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/scsi/libsas/sas_internal.h	2011-07-11 19:51:52.000000000 -0400
@@ -57,7 +57,7 @@
 int  sas_init_events(struct sas_ha_struct *sas_ha);
 void sas_shutdown_queue(struct sas_ha_struct *sas_ha);
 
-void sas_deform_port(struct asd_sas_phy *phy);
+void sas_deform_port(struct asd_sas_phy *phy, int gone);
 
 void sas_porte_bytes_dmaed(struct work_struct *work);
 void sas_porte_broadcast_rcvd(struct work_struct *work);
diff -druN linux-2.6.39-libre/drivers/scsi/libsas/sas_phy.c linux-3.0-rc7-libre/drivers/scsi/libsas/sas_phy.c
--- linux-2.6.39-libre/drivers/scsi/libsas/sas_phy.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/scsi/libsas/sas_phy.c	2011-07-11 19:51:52.000000000 -0400
@@ -39,7 +39,7 @@
 	sas_begin_event(PHYE_LOSS_OF_SIGNAL, &phy->ha->event_lock,
 			&phy->phy_events_pending);
 	phy->error = 0;
-	sas_deform_port(phy);
+	sas_deform_port(phy, 1);
 }
 
 static void sas_phye_oob_done(struct work_struct *work)
@@ -66,7 +66,7 @@
 	sas_begin_event(PHYE_OOB_ERROR, &phy->ha->event_lock,
 			&phy->phy_events_pending);
 
-	sas_deform_port(phy);
+	sas_deform_port(phy, 1);
 
 	if (!port && phy->enabled && i->dft->lldd_control_phy) {
 		phy->error++;
diff -druN linux-2.6.39-libre/drivers/scsi/libsas/sas_port.c linux-3.0-rc7-libre/drivers/scsi/libsas/sas_port.c
--- linux-2.6.39-libre/drivers/scsi/libsas/sas_port.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/scsi/libsas/sas_port.c	2011-07-11 19:51:52.000000000 -0400
@@ -57,7 +57,7 @@
 
 	if (port) {
 		if (!phy_is_wideport_member(port, phy))
-			sas_deform_port(phy);
+			sas_deform_port(phy, 0);
 		else {
 			SAS_DPRINTK("%s: phy%d belongs to port%d already(%d)!\n",
 				    __func__, phy->id, phy->port->id,
@@ -153,28 +153,31 @@
  * This is called when the physical link to the other phy has been
  * lost (on this phy), in Event thread context. We cannot delay here.
  */
-void sas_deform_port(struct asd_sas_phy *phy)
+void sas_deform_port(struct asd_sas_phy *phy, int gone)
 {
 	struct sas_ha_struct *sas_ha = phy->ha;
 	struct asd_sas_port *port = phy->port;
 	struct sas_internal *si =
 		to_sas_internal(sas_ha->core.shost->transportt);
+	struct domain_device *dev;
 	unsigned long flags;
 
 	if (!port)
 		return;		  /* done by a phy event */
 
-	if (port->port_dev)
-		port->port_dev->pathways--;
+	dev = port->port_dev;
+	if (dev)
+		dev->pathways--;
 
 	if (port->num_phys == 1) {
+		if (dev && gone)
+			dev->gone = 1;
 		sas_unregister_domain_devices(port);
 		sas_port_delete(port->port);
 		port->port = NULL;
 	} else
 		sas_port_delete_phy(port->port, phy->phy);
 
-
 	if (si->dft->lldd_port_deformed)
 		si->dft->lldd_port_deformed(phy);
 
@@ -244,7 +247,7 @@
 	sas_begin_event(PORTE_LINK_RESET_ERR, &phy->ha->event_lock,
 			&phy->port_events_pending);
 
-	sas_deform_port(phy);
+	sas_deform_port(phy, 1);
 }
 
 void sas_porte_timer_event(struct work_struct *work)
@@ -256,7 +259,7 @@
 	sas_begin_event(PORTE_TIMER_EVENT, &phy->ha->event_lock,
 			&phy->port_events_pending);
 
-	sas_deform_port(phy);
+	sas_deform_port(phy, 1);
 }
 
 void sas_porte_hard_reset(struct work_struct *work)
@@ -268,7 +271,7 @@
 	sas_begin_event(PORTE_HARD_RESET, &phy->ha->event_lock,
 			&phy->port_events_pending);
 
-	sas_deform_port(phy);
+	sas_deform_port(phy, 1);
 }
 
 /* ---------- SAS port registration ---------- */
@@ -306,6 +309,6 @@
 
 	for (i = 0; i < sas_ha->num_phys; i++)
 		if (sas_ha->sas_phy[i]->port)
-			sas_deform_port(sas_ha->sas_phy[i]);
+			sas_deform_port(sas_ha->sas_phy[i], 0);
 
 }
diff -druN linux-2.6.39-libre/drivers/scsi/libsas/sas_scsi_host.c linux-3.0-rc7-libre/drivers/scsi/libsas/sas_scsi_host.c
--- linux-2.6.39-libre/drivers/scsi/libsas/sas_scsi_host.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/scsi/libsas/sas_scsi_host.c	2011-07-11 19:51:52.000000000 -0400
@@ -207,6 +207,13 @@
 		struct sas_ha_struct *sas_ha = dev->port->ha;
 		struct sas_task *task;
 
+		/* If the device fell off, no sense in issuing commands */
+		if (dev->gone) {
+			cmd->result = DID_BAD_TARGET << 16;
+			scsi_done(cmd);
+			goto out;
+		}
+
 		if (dev_is_sata(dev)) {
 			unsigned long flags;
 
@@ -216,13 +223,6 @@
 			goto out;
 		}
 
-		/* If the device fell off, no sense in issuing commands */
-		if (dev->gone) {
-			cmd->result = DID_BAD_TARGET << 16;
-			scsi_done(cmd);
-			goto out;
-		}
-
 		res = -ENOMEM;
 		task = sas_create_task(cmd, dev, GFP_ATOMIC);
 		if (!task)
diff -druN linux-2.6.39-libre/drivers/scsi/lpfc/lpfc_attr.c linux-3.0-rc7-libre/drivers/scsi/lpfc/lpfc_attr.c
--- linux-2.6.39-libre/drivers/scsi/lpfc/lpfc_attr.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/scsi/lpfc/lpfc_attr.c	2011-07-11 19:51:52.000000000 -0400
@@ -755,6 +755,73 @@
 }
 
 /**
+ * lpfc_sli4_pdev_reg_request - Request physical dev to perform a register acc
+ * @phba: lpfc_hba pointer.
+ *
+ * Description:
+ * Request SLI4 interface type-2 device to perform a physical register set
+ * access.
+ *
+ * Returns:
+ * zero for success
+ **/
+static ssize_t
+lpfc_sli4_pdev_reg_request(struct lpfc_hba *phba, uint32_t opcode)
+{
+	struct completion online_compl;
+	uint32_t reg_val;
+	int status = 0;
+	int rc;
+
+	if (!phba->cfg_enable_hba_reset)
+		return -EIO;
+
+	if ((phba->sli_rev < LPFC_SLI_REV4) ||
+	    (bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf) !=
+	     LPFC_SLI_INTF_IF_TYPE_2))
+		return -EPERM;
+
+	status = lpfc_do_offline(phba, LPFC_EVT_OFFLINE);
+
+	if (status != 0)
+		return status;
+
+	/* wait for the device to be quiesced before firmware reset */
+	msleep(100);
+
+	reg_val = readl(phba->sli4_hba.conf_regs_memmap_p +
+			LPFC_CTL_PDEV_CTL_OFFSET);
+
+	if (opcode == LPFC_FW_DUMP)
+		reg_val |= LPFC_FW_DUMP_REQUEST;
+	else if (opcode == LPFC_FW_RESET)
+		reg_val |= LPFC_CTL_PDEV_CTL_FRST;
+	else if (opcode == LPFC_DV_RESET)
+		reg_val |= LPFC_CTL_PDEV_CTL_DRST;
+
+	writel(reg_val, phba->sli4_hba.conf_regs_memmap_p +
+	       LPFC_CTL_PDEV_CTL_OFFSET);
+	/* flush */
+	readl(phba->sli4_hba.conf_regs_memmap_p + LPFC_CTL_PDEV_CTL_OFFSET);
+
+	/* delay driver action following IF_TYPE_2 reset */
+	msleep(100);
+
+	init_completion(&online_compl);
+	rc = lpfc_workq_post_event(phba, &status, &online_compl,
+				   LPFC_EVT_ONLINE);
+	if (rc == 0)
+		return -ENOMEM;
+
+	wait_for_completion(&online_compl);
+
+	if (status != 0)
+		return -EIO;
+
+	return 0;
+}
+
+/**
  * lpfc_nport_evt_cnt_show - Return the number of nport events
  * @dev: class device that is converted into a Scsi_host.
  * @attr: device attribute, not used.
@@ -848,6 +915,12 @@
 			return -EINVAL;
 		else
 			status = lpfc_do_offline(phba, LPFC_EVT_KILL);
+	else if (strncmp(buf, "dump", sizeof("dump") - 1) == 0)
+		status = lpfc_sli4_pdev_reg_request(phba, LPFC_FW_DUMP);
+	else if (strncmp(buf, "fw_reset", sizeof("fw_reset") - 1) == 0)
+		status = lpfc_sli4_pdev_reg_request(phba, LPFC_FW_RESET);
+	else if (strncmp(buf, "dv_reset", sizeof("dv_reset") - 1) == 0)
+		status = lpfc_sli4_pdev_reg_request(phba, LPFC_DV_RESET);
 	else
 		return -EINVAL;
 
@@ -1322,6 +1395,102 @@
 }
 
 /**
+ * lpfc_sriov_hw_max_virtfn_show - Return maximum number of virtual functions
+ * @dev: class converted to a Scsi_host structure.
+ * @attr: device attribute, not used.
+ * @buf: on return contains the formatted support level.
+ *
+ * Description:
+ * Returns the maximum number of virtual functions a physical function can
+ * support, 0 will be returned if called on virtual function.
+ *
+ * Returns: size of formatted string.
+ **/
+static ssize_t
+lpfc_sriov_hw_max_virtfn_show(struct device *dev,
+			      struct device_attribute *attr,
+			      char *buf)
+{
+	struct Scsi_Host *shost = class_to_shost(dev);
+	struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
+	struct lpfc_hba *phba = vport->phba;
+	struct pci_dev *pdev = phba->pcidev;
+	union  lpfc_sli4_cfg_shdr *shdr;
+	uint32_t shdr_status, shdr_add_status;
+	LPFC_MBOXQ_t *mboxq;
+	struct lpfc_mbx_get_prof_cfg *get_prof_cfg;
+	struct lpfc_rsrc_desc_pcie *desc;
+	uint32_t max_nr_virtfn;
+	uint32_t desc_count;
+	int length, rc, i;
+
+	if ((phba->sli_rev < LPFC_SLI_REV4) ||
+	    (bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf) !=
+	     LPFC_SLI_INTF_IF_TYPE_2))
+		return -EPERM;
+
+	if (!pdev->is_physfn)
+		return snprintf(buf, PAGE_SIZE, "%d\n", 0);
+
+	mboxq = (LPFC_MBOXQ_t *)mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
+	if (!mboxq)
+		return -ENOMEM;
+
+	/* get the maximum number of virtfn support by physfn */
+	length = (sizeof(struct lpfc_mbx_get_prof_cfg) -
+		  sizeof(struct lpfc_sli4_cfg_mhdr));
+	lpfc_sli4_config(phba, mboxq, LPFC_MBOX_SUBSYSTEM_COMMON,
+			 LPFC_MBOX_OPCODE_GET_PROFILE_CONFIG,
+			 length, LPFC_SLI4_MBX_EMBED);
+	shdr = (union lpfc_sli4_cfg_shdr *)
+		&mboxq->u.mqe.un.sli4_config.header.cfg_shdr;
+	bf_set(lpfc_mbox_hdr_pf_num, &shdr->request,
+	       phba->sli4_hba.iov.pf_number + 1);
+
+	get_prof_cfg = &mboxq->u.mqe.un.get_prof_cfg;
+	bf_set(lpfc_mbx_get_prof_cfg_prof_tp, &get_prof_cfg->u.request,
+	       LPFC_CFG_TYPE_CURRENT_ACTIVE);
+
+	rc = lpfc_sli_issue_mbox_wait(phba, mboxq,
+				lpfc_mbox_tmo_val(phba, MBX_SLI4_CONFIG));
+
+	if (rc != MBX_TIMEOUT) {
+		/* check return status */
+		shdr_status = bf_get(lpfc_mbox_hdr_status, &shdr->response);
+		shdr_add_status = bf_get(lpfc_mbox_hdr_add_status,
+					 &shdr->response);
+		if (shdr_status || shdr_add_status || rc)
+			goto error_out;
+
+	} else
+		goto error_out;
+
+	desc_count = get_prof_cfg->u.response.prof_cfg.rsrc_desc_count;
+
+	for (i = 0; i < LPFC_RSRC_DESC_MAX_NUM; i++) {
+		desc = (struct lpfc_rsrc_desc_pcie *)
+			&get_prof_cfg->u.response.prof_cfg.desc[i];
+		if (LPFC_RSRC_DESC_TYPE_PCIE ==
+		    bf_get(lpfc_rsrc_desc_pcie_type, desc)) {
+			max_nr_virtfn = bf_get(lpfc_rsrc_desc_pcie_nr_virtfn,
+					       desc);
+			break;
+		}
+	}
+
+	if (i < LPFC_RSRC_DESC_MAX_NUM) {
+		if (rc != MBX_TIMEOUT)
+			mempool_free(mboxq, phba->mbox_mem_pool);
+		return snprintf(buf, PAGE_SIZE, "%d\n", max_nr_virtfn);
+	}
+
+error_out:
+	if (rc != MBX_TIMEOUT)
+		mempool_free(mboxq, phba->mbox_mem_pool);
+	return -EIO;
+}
+
+/**
  * lpfc_param_show - Return a cfg attribute value in decimal
  *
  * Description:
@@ -1762,6 +1931,8 @@
 static DEVICE_ATTR(lpfc_fips_level, S_IRUGO, lpfc_fips_level_show, NULL);
 static DEVICE_ATTR(lpfc_fips_rev, S_IRUGO, lpfc_fips_rev_show, NULL);
 static DEVICE_ATTR(lpfc_dss, S_IRUGO, lpfc_dss_show, NULL);
+static DEVICE_ATTR(lpfc_sriov_hw_max_virtfn, S_IRUGO,
+		   lpfc_sriov_hw_max_virtfn_show, NULL);
 
 static char *lpfc_soft_wwn_key = "C99G71SL8032A";
 
@@ -3014,7 +3185,7 @@
  *
  * @dev: class device that is converted into a Scsi_host.
  * @attr: device attribute, not used.
- * @buf: containing the string "selective".
+ * @buf: containing enable or disable aer flag.
  * @count: unused variable.
  *
  * Description:
@@ -3098,7 +3269,7 @@
 /**
  * lpfc_aer_support_init - Set the initial adapters aer support flag
  * @phba: lpfc_hba pointer.
- * @val: link speed value.
+ * @val: enable aer or disable aer flag.
  *
  * Description:
  * If val is in a valid range [0,1], then set the adapter's initial
@@ -3137,7 +3308,7 @@
  * lpfc_aer_cleanup_state - Clean up aer state to the aer enabled device
  * @dev: class device that is converted into a Scsi_host.
  * @attr: device attribute, not used.
- * @buf: containing the string "selective".
+ * @buf: containing flag 1 for aer cleanup state.
  * @count: unused variable.
  *
  * Description:
@@ -3180,6 +3351,136 @@
 static DEVICE_ATTR(lpfc_aer_state_cleanup, S_IWUSR, NULL,
 		   lpfc_aer_cleanup_state);
 
+/**
+ * lpfc_sriov_nr_virtfn_store - Enable the adapter for sr-iov virtual functions
+ *
+ * @dev: class device that is converted into a Scsi_host.
+ * @attr: device attribute, not used.
+ * @buf: containing the string the number of vfs to be enabled.
+ * @count: unused variable.
+ *
+ * Description:
+ * When this api is called either through user sysfs, the driver shall
+ * try to enable or disable SR-IOV virtual functions according to the
+ * following:
+ *
+ * If zero virtual function has been enabled to the physical function,
+ * the driver shall invoke the pci enable virtual function api trying
+ * to enable the virtual functions. If the nr_vfn provided is greater
+ * than the maximum supported, the maximum virtual function number will
+ * be used for invoking the api; otherwise, the nr_vfn provided shall
+ * be used for invoking the api. If the api call returned success, the
+ * actual number of virtual functions enabled will be set to the driver
+ * cfg_sriov_nr_virtfn; otherwise, -EINVAL shall be returned and driver
+ * cfg_sriov_nr_virtfn remains zero.
+ *
+ * If none-zero virtual functions have already been enabled to the
+ * physical function, as reflected by the driver's cfg_sriov_nr_virtfn,
+ * -EINVAL will be returned and the driver does nothing;
+ *
+ * If the nr_vfn provided is zero and none-zero virtual functions have
+ * been enabled, as indicated by the driver's cfg_sriov_nr_virtfn, the
+ * disabling virtual function api shall be invoded to disable all the
+ * virtual functions and driver's cfg_sriov_nr_virtfn shall be set to
+ * zero. Otherwise, if zero virtual function has been enabled, do
+ * nothing.
+ *
+ * Returns:
+ * length of the buf on success if val is in range the intended mode
+ * is supported.
+ * -EINVAL if val out of range or intended mode is not supported.
+ **/
+static ssize_t
+lpfc_sriov_nr_virtfn_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;
+	struct pci_dev *pdev = phba->pcidev;
+	int val = 0, rc = -EINVAL;
+
+	/* Sanity check on user data */
+	if (!isdigit(buf[0]))
+		return -EINVAL;
+	if (sscanf(buf, "%i", &val) != 1)
+		return -EINVAL;
+	if (val < 0)
+		return -EINVAL;
+
+	/* Request disabling virtual functions */
+	if (val == 0) {
+		if (phba->cfg_sriov_nr_virtfn > 0) {
+			pci_disable_sriov(pdev);
+			phba->cfg_sriov_nr_virtfn = 0;
+		}
+		return strlen(buf);
+	}
+
+	/* Request enabling virtual functions */
+	if (phba->cfg_sriov_nr_virtfn > 0) {
+		lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
+				"3018 There are %d virtual functions "
+				"enabled on physical function.\n",
+				phba->cfg_sriov_nr_virtfn);
+		return -EEXIST;
+	}
+
+	if (val <= LPFC_MAX_VFN_PER_PFN)
+		phba->cfg_sriov_nr_virtfn = val;
+	else {
+		lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
+				"3019 Enabling %d virtual functions is not "
+				"allowed.\n", val);
+		return -EINVAL;
+	}
+
+	rc = lpfc_sli_probe_sriov_nr_virtfn(phba, phba->cfg_sriov_nr_virtfn);
+	if (rc) {
+		phba->cfg_sriov_nr_virtfn = 0;
+		rc = -EPERM;
+	} else
+		rc = strlen(buf);
+
+	return rc;
+}
+
+static int lpfc_sriov_nr_virtfn = LPFC_DEF_VFN_PER_PFN;
+module_param(lpfc_sriov_nr_virtfn, int, S_IRUGO|S_IWUSR);
+MODULE_PARM_DESC(lpfc_sriov_nr_virtfn, "Enable PCIe device SR-IOV virtual fn");
+lpfc_param_show(sriov_nr_virtfn)
+
+/**
+ * lpfc_sriov_nr_virtfn_init - Set the initial sr-iov virtual function enable
+ * @phba: lpfc_hba pointer.
+ * @val: link speed value.
+ *
+ * Description:
+ * If val is in a valid range [0,255], then set the adapter's initial
+ * cfg_sriov_nr_virtfn field. If it's greater than the maximum, the maximum
+ * number shall be used instead. It will be up to the driver's probe_one
+ * routine to determine whether the device's SR-IOV is supported or not.
+ *
+ * Returns:
+ * zero if val saved.
+ * -EINVAL val out of range
+ **/
+static int
+lpfc_sriov_nr_virtfn_init(struct lpfc_hba *phba, int val)
+{
+	if (val >= 0 && val <= LPFC_MAX_VFN_PER_PFN) {
+		phba->cfg_sriov_nr_virtfn = val;
+		return 0;
+	}
+
+	lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
+			"3017 Enabling %d virtual functions is not "
+			"allowed.\n", val);
+	return -EINVAL;
+}
+static DEVICE_ATTR(lpfc_sriov_nr_virtfn, S_IRUGO | S_IWUSR,
+		   lpfc_sriov_nr_virtfn_show, lpfc_sriov_nr_virtfn_store);
+
 /*
 # lpfc_fcp_class:  Determines FC class to use for the FCP protocol.
 # Value range is [2,3]. Default value is 3.
@@ -3497,6 +3798,7 @@
 	&dev_attr_lpfc_prot_sg_seg_cnt,
 	&dev_attr_lpfc_aer_support,
 	&dev_attr_lpfc_aer_state_cleanup,
+	&dev_attr_lpfc_sriov_nr_virtfn,
 	&dev_attr_lpfc_suppress_link_up,
 	&dev_attr_lpfc_iocb_cnt,
 	&dev_attr_iocb_hw,
@@ -3505,6 +3807,7 @@
 	&dev_attr_lpfc_fips_level,
 	&dev_attr_lpfc_fips_rev,
 	&dev_attr_lpfc_dss,
+	&dev_attr_lpfc_sriov_hw_max_virtfn,
 	NULL,
 };
 
@@ -3961,7 +4264,7 @@
 		.name = "mbox",
 		.mode = S_IRUSR | S_IWUSR,
 	},
-	.size = MAILBOX_CMD_SIZE,
+	.size = MAILBOX_SYSFS_MAX,
 	.read = sysfs_mbox_read,
 	.write = sysfs_mbox_write,
 };
@@ -4532,7 +4835,7 @@
  *
  * This function is called by the lpfc_get_cfgparam() routine to set the
  * module lpfc_log_verbose into the @phba cfg_log_verbose for use with
- * log messsage according to the module's lpfc_log_verbose parameter setting
+ * log message according to the module's lpfc_log_verbose parameter setting
  * before hba port or vport created.
  **/
 static void
@@ -4705,6 +5008,7 @@
 	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_sriov_nr_virtfn_init(phba, lpfc_sriov_nr_virtfn);
 	lpfc_suppress_link_up_init(phba, lpfc_suppress_link_up);
 	lpfc_iocb_cnt_init(phba, lpfc_iocb_cnt);
 	phba->cfg_enable_dss = 1;
diff -druN linux-2.6.39-libre/drivers/scsi/lpfc/lpfc_bsg.c linux-3.0-rc7-libre/drivers/scsi/lpfc/lpfc_bsg.c
--- linux-2.6.39-libre/drivers/scsi/lpfc/lpfc_bsg.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/scsi/lpfc/lpfc_bsg.c	2011-07-11 19:51:52.000000000 -0400
@@ -23,6 +23,7 @@
 #include <linux/pci.h>
 #include <linux/slab.h>
 #include <linux/delay.h>
+#include <linux/list.h>
 
 #include <scsi/scsi.h>
 #include <scsi/scsi_host.h>
@@ -79,8 +80,7 @@
 struct lpfc_bsg_mbox {
 	LPFC_MBOXQ_t *pmboxq;
 	MAILBOX_t *mb;
-	struct lpfc_dmabuf *rxbmp; /* for BIU diags */
-	struct lpfc_dmabufext *dmp; /* for BIU diags */
+	struct lpfc_dmabuf *dmabuffers; /* for BIU diags */
 	uint8_t *ext; /* extended mailbox data */
 	uint32_t mbOffset; /* from app */
 	uint32_t inExtWLen; /* from app */
@@ -332,6 +332,8 @@
 	cmd->ulpLe = 1;
 	cmd->ulpClass = CLASS3;
 	cmd->ulpContext = ndlp->nlp_rpi;
+	if (phba->sli_rev == LPFC_SLI_REV4)
+		cmd->ulpContext = phba->sli4_hba.rpi_ids[ndlp->nlp_rpi];
 	cmd->ulpOwner = OWN_CHIP;
 	cmdiocbq->vport = phba->pport;
 	cmdiocbq->context3 = bmp;
@@ -598,7 +600,7 @@
 	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.bmp = NULL;
 	dd_data->context_un.iocb.ndlp = ndlp;
 
 	if (phba->cfg_poll & DISABLE_FCP_RING_INT) {
@@ -1336,6 +1338,10 @@
 		}
 
 		icmd->un.ulpWord[3] = ndlp->nlp_rpi;
+		if (phba->sli_rev == LPFC_SLI_REV4)
+			icmd->ulpContext =
+				phba->sli4_hba.rpi_ids[ndlp->nlp_rpi];
+
 		/* The exchange is done, mark the entry as invalid */
 		phba->ct_ctx[tag].flags &= ~UNSOL_VALID;
 	} else
@@ -1463,11 +1469,91 @@
 }
 
 /**
- * lpfc_bsg_diag_mode - process a LPFC_BSG_VENDOR_DIAG_MODE bsg vendor command
+ * lpfc_bsg_diag_mode_enter - process preparing into device diag loopback mode
+ * @phba: Pointer to HBA context object.
  * @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.
+ * This function is responsible for preparing driver for diag loopback
+ * on device.
+ */
+static int
+lpfc_bsg_diag_mode_enter(struct lpfc_hba *phba, struct fc_bsg_job *job)
+{
+	struct lpfc_vport **vports;
+	struct Scsi_Host *shost;
+	struct lpfc_sli *psli;
+	struct lpfc_sli_ring *pring;
+	int i = 0;
+
+	psli = &phba->sli;
+	if (!psli)
+		return -ENODEV;
+
+	pring = &psli->ring[LPFC_FCP_RING];
+	if (!pring)
+		return -ENODEV;
+
+	if ((phba->link_state == LPFC_HBA_ERROR) ||
+	    (psli->sli_flag & LPFC_BLOCK_MGMT_IO) ||
+	    (!(psli->sli_flag & LPFC_SLI_ACTIVE)))
+		return -EACCES;
+
+	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);
+	}
+	return 0;
+}
+
+/**
+ * lpfc_bsg_diag_mode_exit - exit process from device diag loopback mode
+ * @phba: Pointer to HBA context object.
+ * @job: LPFC_BSG_VENDOR_DIAG_MODE
+ *
+ * This function is responsible for driver exit processing of setting up
+ * diag loopback mode on device.
+ */
+static void
+lpfc_bsg_diag_mode_exit(struct lpfc_hba *phba)
+{
+	struct Scsi_Host *shost;
+	struct lpfc_vport **vports;
+	int i;
+
+	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);
+	}
+	return;
+}
+
+/**
+ * lpfc_sli3_bsg_diag_loopback_mode - process an sli3 bsg vendor command
+ * @phba: Pointer to HBA context object.
+ * @job: LPFC_BSG_VENDOR_DIAG_MODE
+ *
+ * This function is responsible for placing an sli3  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
@@ -1475,17 +1561,11 @@
  * All of this is done in-line.
  */
 static int
-lpfc_bsg_diag_mode(struct fc_bsg_job *job)
+lpfc_sli3_bsg_diag_loopback_mode(struct lpfc_hba *phba, 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;
@@ -1494,53 +1574,33 @@
 	/* 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)) {
+	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");
+				"2738 Received DIAG MODE request size:%d "
+				"below the minimum size:%d\n",
+				job->request_len,
+				(int)(sizeof(struct fc_bsg_request) +
+				sizeof(struct diag_mode_set)));
 		rc = -EINVAL;
 		goto job_error;
 	}
 
+	rc = lpfc_bsg_diag_mode_enter(phba, job);
+	if (rc)
+		goto job_error;
+
+	/* bring the link to diagnostic mode */
 	loopback_mode = (struct diag_mode_set *)
 		job->request->rqst_data.h_vendor.vendor_cmd;
 	link_flags = loopback_mode->type;
 	timeout = loopback_mode->timeout * 100;
 
-	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);
+		goto loopback_mode_exit;
 	}
-
 	memset((void *)pmboxq, 0, sizeof(LPFC_MBOXQ_t));
 	pmboxq->u.mb.mbxCommand = MBX_DOWN_LINK;
 	pmboxq->u.mb.mbxOwner = OWN_HOST;
@@ -1594,24 +1654,416 @@
 		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_bsg_diag_mode_exit(phba);
+
+	/*
+	 * 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;
+}
+
+/**
+ * lpfc_sli4_bsg_set_link_diag_state - set sli4 link diag state
+ * @phba: Pointer to HBA context object.
+ * @diag: Flag for set link to diag or nomral operation state.
+ *
+ * This function is responsible for issuing a sli4 mailbox command for setting
+ * link to either diag state or normal operation state.
+ */
+static int
+lpfc_sli4_bsg_set_link_diag_state(struct lpfc_hba *phba, uint32_t diag)
+{
+	LPFC_MBOXQ_t *pmboxq;
+	struct lpfc_mbx_set_link_diag_state *link_diag_state;
+	uint32_t req_len, alloc_len;
+	int mbxstatus = MBX_SUCCESS, rc;
+
+	pmboxq = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
+	if (!pmboxq)
+		return -ENOMEM;
+
+	req_len = (sizeof(struct lpfc_mbx_set_link_diag_state) -
+		   sizeof(struct lpfc_sli4_cfg_mhdr));
+	alloc_len = lpfc_sli4_config(phba, pmboxq, LPFC_MBOX_SUBSYSTEM_FCOE,
+				LPFC_MBOX_OPCODE_FCOE_LINK_DIAG_STATE,
+				req_len, LPFC_SLI4_MBX_EMBED);
+	if (alloc_len != req_len) {
+		rc = -ENOMEM;
+		goto link_diag_state_set_out;
+	}
+	link_diag_state = &pmboxq->u.mqe.un.link_diag_state;
+	bf_set(lpfc_mbx_set_diag_state_link_num, &link_diag_state->u.req,
+	       phba->sli4_hba.link_state.number);
+	bf_set(lpfc_mbx_set_diag_state_link_type, &link_diag_state->u.req,
+	       phba->sli4_hba.link_state.type);
+	if (diag)
+		bf_set(lpfc_mbx_set_diag_state_diag,
+		       &link_diag_state->u.req, 1);
+	else
+		bf_set(lpfc_mbx_set_diag_state_diag,
+		       &link_diag_state->u.req, 0);
+
+	mbxstatus = lpfc_sli_issue_mbox_wait(phba, pmboxq, LPFC_MBOX_TMO);
+
+	if ((mbxstatus == MBX_SUCCESS) && (pmboxq->u.mb.mbxStatus == 0))
+		rc = 0;
+	else
+		rc = -ENODEV;
+
+link_diag_state_set_out:
+	if (pmboxq && (mbxstatus != MBX_TIMEOUT))
+		mempool_free(pmboxq, phba->mbox_mem_pool);
+
+	return rc;
+}
+
+/**
+ * lpfc_sli4_bsg_diag_loopback_mode - process an sli4 bsg vendor command
+ * @phba: Pointer to HBA context object.
+ * @job: LPFC_BSG_VENDOR_DIAG_MODE
+ *
+ * This function is responsible for placing an sli4 port into diagnostic
+ * loopback mode in order to perform a diagnostic loopback test.
+ */
+static int
+lpfc_sli4_bsg_diag_loopback_mode(struct lpfc_hba *phba, struct fc_bsg_job *job)
+{
+	struct diag_mode_set *loopback_mode;
+	uint32_t link_flags, timeout, req_len, alloc_len;
+	struct lpfc_mbx_set_link_diag_loopback *link_diag_loopback;
+	LPFC_MBOXQ_t *pmboxq = NULL;
+	int mbxstatus, i, 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,
+				"3011 Received DIAG MODE request size:%d "
+				"below the minimum size:%d\n",
+				job->request_len,
+				(int)(sizeof(struct fc_bsg_request) +
+				sizeof(struct diag_mode_set)));
+		rc = -EINVAL;
+		goto job_error;
+	}
+
+	rc = lpfc_bsg_diag_mode_enter(phba, job);
+	if (rc)
+		goto job_error;
+
+	/* bring the link to diagnostic mode */
+	loopback_mode = (struct diag_mode_set *)
+		job->request->rqst_data.h_vendor.vendor_cmd;
+	link_flags = loopback_mode->type;
+	timeout = loopback_mode->timeout * 100;
+
+	rc = lpfc_sli4_bsg_set_link_diag_state(phba, 1);
+	if (rc)
+		goto loopback_mode_exit;
+
+	/* 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);
+	}
+	/* set up loopback mode */
+	pmboxq = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
+	if (!pmboxq) {
+		rc = -ENOMEM;
+		goto loopback_mode_exit;
+	}
+	req_len = (sizeof(struct lpfc_mbx_set_link_diag_loopback) -
+		   sizeof(struct lpfc_sli4_cfg_mhdr));
+	alloc_len = lpfc_sli4_config(phba, pmboxq, LPFC_MBOX_SUBSYSTEM_FCOE,
+				LPFC_MBOX_OPCODE_FCOE_LINK_DIAG_LOOPBACK,
+				req_len, LPFC_SLI4_MBX_EMBED);
+	if (alloc_len != req_len) {
+		rc = -ENOMEM;
+		goto loopback_mode_exit;
+	}
+	link_diag_loopback = &pmboxq->u.mqe.un.link_diag_loopback;
+	bf_set(lpfc_mbx_set_diag_state_link_num,
+	       &link_diag_loopback->u.req, phba->sli4_hba.link_state.number);
+	bf_set(lpfc_mbx_set_diag_state_link_type,
+	       &link_diag_loopback->u.req, phba->sli4_hba.link_state.type);
+	if (link_flags == INTERNAL_LOOP_BACK)
+		bf_set(lpfc_mbx_set_diag_lpbk_type,
+		       &link_diag_loopback->u.req,
+		       LPFC_DIAG_LOOPBACK_TYPE_INTERNAL);
+	else
+		bf_set(lpfc_mbx_set_diag_lpbk_type,
+		       &link_diag_loopback->u.req,
+		       LPFC_DIAG_LOOPBACK_TYPE_EXTERNAL);
+
+	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);
 		}
-		lpfc_destroy_vport_work_array(phba, vports);
-	} else {
-		shost = lpfc_shost_from_vport(phba->pport);
-		scsi_unblock_requests(shost);
 	}
 
+loopback_mode_exit:
+	lpfc_bsg_diag_mode_exit(phba);
+
 	/*
 	 * Let SLI layer release mboxq if mbox command completed after timeout.
 	 */
-	if (mbxstatus != MBX_TIMEOUT)
+	if (pmboxq && (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;
+}
+
+/**
+ * lpfc_bsg_diag_loopback_mode - bsg vendor command for diag loopback mode
+ * @job: LPFC_BSG_VENDOR_DIAG_MODE
+ *
+ * This function is responsible for responding to check and dispatch bsg diag
+ * command from the user to proper driver action routines.
+ */
+static int
+lpfc_bsg_diag_loopback_mode(struct fc_bsg_job *job)
+{
+	struct Scsi_Host *shost;
+	struct lpfc_vport *vport;
+	struct lpfc_hba *phba;
+	int rc;
+
+	shost = job->shost;
+	if (!shost)
+		return -ENODEV;
+	vport = (struct lpfc_vport *)job->shost->hostdata;
+	if (!vport)
+		return -ENODEV;
+	phba = vport->phba;
+	if (!phba)
+		return -ENODEV;
+
+	if (phba->sli_rev < LPFC_SLI_REV4)
+		rc = lpfc_sli3_bsg_diag_loopback_mode(phba, job);
+	else if (bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf) ==
+		 LPFC_SLI_INTF_IF_TYPE_2)
+		rc = lpfc_sli4_bsg_diag_loopback_mode(phba, job);
+	else
+		rc = -ENODEV;
+
+	return rc;
+
+}
+
+/**
+ * lpfc_sli4_bsg_diag_mode_end - sli4 bsg vendor command for ending diag mode
+ * @job: LPFC_BSG_VENDOR_DIAG_MODE_END
+ *
+ * This function is responsible for responding to check and dispatch bsg diag
+ * command from the user to proper driver action routines.
+ */
+static int
+lpfc_sli4_bsg_diag_mode_end(struct fc_bsg_job *job)
+{
+	struct Scsi_Host *shost;
+	struct lpfc_vport *vport;
+	struct lpfc_hba *phba;
+	int rc;
+
+	shost = job->shost;
+	if (!shost)
+		return -ENODEV;
+	vport = (struct lpfc_vport *)job->shost->hostdata;
+	if (!vport)
+		return -ENODEV;
+	phba = vport->phba;
+	if (!phba)
+		return -ENODEV;
+
+	if (phba->sli_rev < LPFC_SLI_REV4)
+		return -ENODEV;
+	if (bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf) !=
+	    LPFC_SLI_INTF_IF_TYPE_2)
+		return -ENODEV;
+
+	rc = lpfc_sli4_bsg_set_link_diag_state(phba, 0);
+
+	if (!rc)
+		rc = phba->lpfc_hba_init_link(phba, MBX_NOWAIT);
+
+	return rc;
+}
+
+/**
+ * lpfc_sli4_bsg_link_diag_test - sli4 bsg vendor command for diag link test
+ * @job: LPFC_BSG_VENDOR_DIAG_LINK_TEST
+ *
+ * This function is to perform SLI4 diag link test request from the user
+ * applicaiton.
+ */
+static int
+lpfc_sli4_bsg_link_diag_test(struct fc_bsg_job *job)
+{
+	struct Scsi_Host *shost;
+	struct lpfc_vport *vport;
+	struct lpfc_hba *phba;
+	LPFC_MBOXQ_t *pmboxq;
+	struct sli4_link_diag *link_diag_test_cmd;
+	uint32_t req_len, alloc_len;
+	uint32_t timeout;
+	struct lpfc_mbx_run_link_diag_test *run_link_diag_test;
+	union lpfc_sli4_cfg_shdr *shdr;
+	uint32_t shdr_status, shdr_add_status;
+	struct diag_status *diag_status_reply;
+	int mbxstatus, rc = 0;
+
+	shost = job->shost;
+	if (!shost) {
+		rc = -ENODEV;
+		goto job_error;
+	}
+	vport = (struct lpfc_vport *)job->shost->hostdata;
+	if (!vport) {
+		rc = -ENODEV;
+		goto job_error;
+	}
+	phba = vport->phba;
+	if (!phba) {
+		rc = -ENODEV;
+		goto job_error;
+	}
+
+	if (phba->sli_rev < LPFC_SLI_REV4) {
+		rc = -ENODEV;
+		goto job_error;
+	}
+	if (bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf) !=
+	    LPFC_SLI_INTF_IF_TYPE_2) {
+		rc = -ENODEV;
+		goto job_error;
+	}
+
+	if (job->request_len < sizeof(struct fc_bsg_request) +
+	    sizeof(struct sli4_link_diag)) {
+		lpfc_printf_log(phba, KERN_WARNING, LOG_LIBDFC,
+				"3013 Received LINK DIAG TEST request "
+				" size:%d below the minimum size:%d\n",
+				job->request_len,
+				(int)(sizeof(struct fc_bsg_request) +
+				sizeof(struct sli4_link_diag)));
+		rc = -EINVAL;
+		goto job_error;
+	}
+
+	rc = lpfc_bsg_diag_mode_enter(phba, job);
+	if (rc)
+		goto job_error;
+
+	link_diag_test_cmd = (struct sli4_link_diag *)
+			 job->request->rqst_data.h_vendor.vendor_cmd;
+	timeout = link_diag_test_cmd->timeout * 100;
+
+	rc = lpfc_sli4_bsg_set_link_diag_state(phba, 1);
+
+	if (rc)
+		goto job_error;
+
+	pmboxq = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
+	if (!pmboxq) {
+		rc = -ENOMEM;
+		goto link_diag_test_exit;
+	}
+
+	req_len = (sizeof(struct lpfc_mbx_set_link_diag_state) -
+		   sizeof(struct lpfc_sli4_cfg_mhdr));
+	alloc_len = lpfc_sli4_config(phba, pmboxq, LPFC_MBOX_SUBSYSTEM_FCOE,
+				     LPFC_MBOX_OPCODE_FCOE_LINK_DIAG_STATE,
+				     req_len, LPFC_SLI4_MBX_EMBED);
+	if (alloc_len != req_len) {
+		rc = -ENOMEM;
+		goto link_diag_test_exit;
+	}
+	run_link_diag_test = &pmboxq->u.mqe.un.link_diag_test;
+	bf_set(lpfc_mbx_run_diag_test_link_num, &run_link_diag_test->u.req,
+	       phba->sli4_hba.link_state.number);
+	bf_set(lpfc_mbx_run_diag_test_link_type, &run_link_diag_test->u.req,
+	       phba->sli4_hba.link_state.type);
+	bf_set(lpfc_mbx_run_diag_test_test_id, &run_link_diag_test->u.req,
+	       link_diag_test_cmd->test_id);
+	bf_set(lpfc_mbx_run_diag_test_loops, &run_link_diag_test->u.req,
+	       link_diag_test_cmd->loops);
+	bf_set(lpfc_mbx_run_diag_test_test_ver, &run_link_diag_test->u.req,
+	       link_diag_test_cmd->test_version);
+	bf_set(lpfc_mbx_run_diag_test_err_act, &run_link_diag_test->u.req,
+	       link_diag_test_cmd->error_action);
+
+	mbxstatus = lpfc_sli_issue_mbox(phba, pmboxq, MBX_POLL);
+
+	shdr = (union lpfc_sli4_cfg_shdr *)
+		&pmboxq->u.mqe.un.sli4_config.header.cfg_shdr;
+	shdr_status = bf_get(lpfc_mbox_hdr_status, &shdr->response);
+	shdr_add_status = bf_get(lpfc_mbox_hdr_add_status, &shdr->response);
+	if (shdr_status || shdr_add_status || mbxstatus) {
+		lpfc_printf_log(phba, KERN_ERR, LOG_LIBDFC,
+				"3010 Run link diag test mailbox failed with "
+				"mbx_status x%x status x%x, add_status x%x\n",
+				mbxstatus, shdr_status, shdr_add_status);
+	}
+
+	diag_status_reply = (struct diag_status *)
+			    job->reply->reply_data.vendor_reply.vendor_rsp;
+
+	if (job->reply_len <
+	    sizeof(struct fc_bsg_request) + sizeof(struct diag_status)) {
+		lpfc_printf_log(phba, KERN_WARNING, LOG_LIBDFC,
+				"3012 Received Run link diag test reply "
+				"below minimum size (%d): reply_len:%d\n",
+				(int)(sizeof(struct fc_bsg_request) +
+				sizeof(struct diag_status)),
+				job->reply_len);
+		rc = -EINVAL;
+		goto job_error;
+	}
+
+	diag_status_reply->mbox_status = mbxstatus;
+	diag_status_reply->shdr_status = shdr_status;
+	diag_status_reply->shdr_add_status = shdr_add_status;
+
+link_diag_test_exit:
+	rc = lpfc_sli4_bsg_set_link_diag_state(phba, 0);
+
+	if (pmboxq)
 		mempool_free(pmboxq, phba->mbox_mem_pool);
 
+	lpfc_bsg_diag_mode_exit(phba);
+
 job_error:
 	/* make error code available to userspace */
 	job->reply->result = rc;
@@ -1851,6 +2303,86 @@
 }
 
 /**
+ * lpfc_bsg_dma_page_alloc - allocate a bsg mbox page sized dma buffers
+ * @phba: Pointer to HBA context object
+ *
+ * This function allocates BSG_MBOX_SIZE (4KB) page size dma buffer and.
+ * retruns the pointer to the buffer.
+ **/
+static struct lpfc_dmabuf *
+lpfc_bsg_dma_page_alloc(struct lpfc_hba *phba)
+{
+	struct lpfc_dmabuf *dmabuf;
+	struct pci_dev *pcidev = phba->pcidev;
+
+	/* allocate dma buffer struct */
+	dmabuf = kmalloc(sizeof(struct lpfc_dmabuf), GFP_KERNEL);
+	if (!dmabuf)
+		return NULL;
+
+	INIT_LIST_HEAD(&dmabuf->list);
+
+	/* now, allocate dma buffer */
+	dmabuf->virt = dma_alloc_coherent(&pcidev->dev, BSG_MBOX_SIZE,
+					  &(dmabuf->phys), GFP_KERNEL);
+
+	if (!dmabuf->virt) {
+		kfree(dmabuf);
+		return NULL;
+	}
+	memset((uint8_t *)dmabuf->virt, 0, BSG_MBOX_SIZE);
+
+	return dmabuf;
+}
+
+/**
+ * lpfc_bsg_dma_page_free - free a bsg mbox page sized dma buffer
+ * @phba: Pointer to HBA context object.
+ * @dmabuf: Pointer to the bsg mbox page sized dma buffer descriptor.
+ *
+ * This routine just simply frees a dma buffer and its associated buffer
+ * descriptor referred by @dmabuf.
+ **/
+static void
+lpfc_bsg_dma_page_free(struct lpfc_hba *phba, struct lpfc_dmabuf *dmabuf)
+{
+	struct pci_dev *pcidev = phba->pcidev;
+
+	if (!dmabuf)
+		return;
+
+	if (dmabuf->virt)
+		dma_free_coherent(&pcidev->dev, BSG_MBOX_SIZE,
+				  dmabuf->virt, dmabuf->phys);
+	kfree(dmabuf);
+	return;
+}
+
+/**
+ * lpfc_bsg_dma_page_list_free - free a list of bsg mbox page sized dma buffers
+ * @phba: Pointer to HBA context object.
+ * @dmabuf_list: Pointer to a list of bsg mbox page sized dma buffer descs.
+ *
+ * This routine just simply frees all dma buffers and their associated buffer
+ * descriptors referred by @dmabuf_list.
+ **/
+static void
+lpfc_bsg_dma_page_list_free(struct lpfc_hba *phba,
+			    struct list_head *dmabuf_list)
+{
+	struct lpfc_dmabuf *dmabuf, *next_dmabuf;
+
+	if (list_empty(dmabuf_list))
+		return;
+
+	list_for_each_entry_safe(dmabuf, next_dmabuf, dmabuf_list, list) {
+		list_del_init(&dmabuf->list);
+		lpfc_bsg_dma_page_free(phba, dmabuf);
+	}
+	return;
+}
+
+/**
  * 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
@@ -2067,7 +2599,7 @@
 }
 
 /**
- * lpfc_bsg_diag_test - with a port in loopback issues a Ct cmd to itself
+ * lpfc_bsg_diag_loopback_run - run loopback on a port by issue 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
@@ -2086,7 +2618,7 @@
  * of loopback mode.
  **/
 static int
-lpfc_bsg_diag_test(struct fc_bsg_job *job)
+lpfc_bsg_diag_loopback_run(struct fc_bsg_job *job)
 {
 	struct lpfc_vport *vport = (struct lpfc_vport *)job->shost->hostdata;
 	struct lpfc_hba *phba = vport->phba;
@@ -2411,7 +2943,7 @@
 }
 
 /**
- * lpfc_bsg_wake_mbox_wait - lpfc_bsg_issue_mbox mbox completion handler
+ * lpfc_bsg_issue_mbox_cmpl - lpfc_bsg_issue_mbox mbox completion handler
  * @phba: Pointer to HBA context object.
  * @pmboxq: Pointer to mailbox command.
  *
@@ -2422,14 +2954,13 @@
  * of the mailbox.
  **/
 void
-lpfc_bsg_wake_mbox_wait(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmboxq)
+lpfc_bsg_issue_mbox_cmpl(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmboxq)
 {
 	struct bsg_job_data *dd_data;
 	struct fc_bsg_job *job;
 	uint32_t size;
 	unsigned long flags;
-	uint8_t *to;
-	uint8_t *from;
+	uint8_t *pmb, *pmb_buf;
 
 	spin_lock_irqsave(&phba->ct_ev_lock, flags);
 	dd_data = pmboxq->context1;
@@ -2439,90 +2970,41 @@
 		return;
 	}
 
-	/* build the outgoing buffer to do an sg copy
-	 * the format is the response mailbox followed by any extended
-	 * mailbox data
+	/*
+	 * The outgoing buffer is readily referred from the dma buffer,
+	 * just need to get header part from mailboxq structure.
 	 */
-	from = (uint8_t *)&pmboxq->u.mb;
-	to = (uint8_t *)dd_data->context_un.mbox.mb;
-	memcpy(to, from, sizeof(MAILBOX_t));
-	if (pmboxq->u.mb.mbxStatus == MBX_SUCCESS) {
-		/* copy the extended data if any, count is in words */
-		if (dd_data->context_un.mbox.outExtWLen) {
-			from = (uint8_t *)dd_data->context_un.mbox.ext;
-			to += sizeof(MAILBOX_t);
-			size = dd_data->context_un.mbox.outExtWLen *
-					sizeof(uint32_t);
-			memcpy(to, from, size);
-		} else if (pmboxq->u.mb.mbxCommand == MBX_RUN_BIU_DIAG64) {
-			from = (uint8_t *)dd_data->context_un.mbox.
-						dmp->dma.virt;
-			to += sizeof(MAILBOX_t);
-			size = dd_data->context_un.mbox.dmp->size;
-			memcpy(to, from, size);
-		} else if ((phba->sli_rev == LPFC_SLI_REV4) &&
-			(pmboxq->u.mb.mbxCommand == MBX_DUMP_MEMORY)) {
-			from = (uint8_t *)dd_data->context_un.mbox.dmp->dma.
-						virt;
-			to += sizeof(MAILBOX_t);
-			size = pmboxq->u.mb.un.varWords[5];
-			memcpy(to, from, size);
-		} else if ((phba->sli_rev == LPFC_SLI_REV4) &&
-			(pmboxq->u.mb.mbxCommand == MBX_SLI4_CONFIG)) {
-			struct lpfc_mbx_nembed_cmd *nembed_sge =
-				(struct lpfc_mbx_nembed_cmd *)
-				&pmboxq->u.mb.un.varWords[0];
-
-			from = (uint8_t *)dd_data->context_un.mbox.dmp->dma.
-						virt;
-			to += sizeof(MAILBOX_t);
-			size = nembed_sge->sge[0].length;
-			memcpy(to, from, size);
-		} else if (pmboxq->u.mb.mbxCommand == MBX_READ_EVENT_LOG) {
-			from = (uint8_t *)dd_data->context_un.
-						mbox.dmp->dma.virt;
-			to += sizeof(MAILBOX_t);
-			size = dd_data->context_un.mbox.dmp->size;
-			memcpy(to, from, size);
-		}
-	}
+	pmb = (uint8_t *)&pmboxq->u.mb;
+	pmb_buf = (uint8_t *)dd_data->context_un.mbox.mb;
+	memcpy(pmb_buf, pmb, sizeof(MAILBOX_t));
 
-	from = (uint8_t *)dd_data->context_un.mbox.mb;
 	job = dd_data->context_un.mbox.set_job;
 	if (job) {
 		size = job->reply_payload.payload_len;
 		job->reply->reply_payload_rcv_len =
 			sg_copy_from_buffer(job->reply_payload.sg_list,
-					job->reply_payload.sg_cnt,
-					from, size);
-		job->reply->result = 0;
-
+					    job->reply_payload.sg_cnt,
+					    pmb_buf, size);
+		/* need to hold the lock until we set job->dd_data to NULL
+		 * to hold off the timeout handler returning to the mid-layer
+		 * while we are still processing the job.
+		 */
 		job->dd_data = NULL;
-		job->job_done(job);
+		dd_data->context_un.mbox.set_job = NULL;
+		spin_unlock_irqrestore(&phba->ct_ev_lock, flags);
+	} else {
+		dd_data->context_un.mbox.set_job = NULL;
+		spin_unlock_irqrestore(&phba->ct_ev_lock, flags);
 	}
-	dd_data->context_un.mbox.set_job = NULL;
-	/* need to hold the lock until we call job done to hold off
-	 * the timeout handler returning to the midlayer while
-	 * we are stillprocessing the job
-	 */
-	spin_unlock_irqrestore(&phba->ct_ev_lock, flags);
 
-	kfree(dd_data->context_un.mbox.mb);
 	mempool_free(dd_data->context_un.mbox.pmboxq, phba->mbox_mem_pool);
-	kfree(dd_data->context_un.mbox.ext);
-	if (dd_data->context_un.mbox.dmp) {
-		dma_free_coherent(&phba->pcidev->dev,
-			dd_data->context_un.mbox.dmp->size,
-			dd_data->context_un.mbox.dmp->dma.virt,
-			dd_data->context_un.mbox.dmp->dma.phys);
-		kfree(dd_data->context_un.mbox.dmp);
-	}
-	if (dd_data->context_un.mbox.rxbmp) {
-		lpfc_mbuf_free(phba, dd_data->context_un.mbox.rxbmp->virt,
-			dd_data->context_un.mbox.rxbmp->phys);
-		kfree(dd_data->context_un.mbox.rxbmp);
-	}
+	lpfc_bsg_dma_page_free(phba, dd_data->context_un.mbox.dmabuffers);
 	kfree(dd_data);
+
+	if (job) {
+		job->reply->result = 0;
+		job->job_done(job);
+	}
 	return;
 }
 
@@ -2617,6 +3099,1006 @@
 }
 
 /**
+ * lpfc_bsg_mbox_ext_cleanup - clean up context of multi-buffer mbox session
+ * @phba: Pointer to HBA context object.
+ *
+ * This is routine clean up and reset BSG handling of multi-buffer mbox
+ * command session.
+ **/
+static void
+lpfc_bsg_mbox_ext_session_reset(struct lpfc_hba *phba)
+{
+	if (phba->mbox_ext_buf_ctx.state == LPFC_BSG_MBOX_IDLE)
+		return;
+
+	/* free all memory, including dma buffers */
+	lpfc_bsg_dma_page_list_free(phba,
+				    &phba->mbox_ext_buf_ctx.ext_dmabuf_list);
+	lpfc_bsg_dma_page_free(phba, phba->mbox_ext_buf_ctx.mbx_dmabuf);
+	/* multi-buffer write mailbox command pass-through complete */
+	memset((char *)&phba->mbox_ext_buf_ctx, 0,
+	       sizeof(struct lpfc_mbox_ext_buf_ctx));
+	INIT_LIST_HEAD(&phba->mbox_ext_buf_ctx.ext_dmabuf_list);
+
+	return;
+}
+
+/**
+ * lpfc_bsg_issue_mbox_ext_handle_job - job handler for multi-buffer mbox cmpl
+ * @phba: Pointer to HBA context object.
+ * @pmboxq: Pointer to mailbox command.
+ *
+ * This is routine handles BSG job for mailbox commands completions with
+ * multiple external buffers.
+ **/
+static struct fc_bsg_job *
+lpfc_bsg_issue_mbox_ext_handle_job(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmboxq)
+{
+	struct bsg_job_data *dd_data;
+	struct fc_bsg_job *job;
+	uint8_t *pmb, *pmb_buf;
+	unsigned long flags;
+	uint32_t size;
+	int rc = 0;
+
+	spin_lock_irqsave(&phba->ct_ev_lock, flags);
+	dd_data = pmboxq->context1;
+	/* has the job already timed out? */
+	if (!dd_data) {
+		spin_unlock_irqrestore(&phba->ct_ev_lock, flags);
+		job = NULL;
+		goto job_done_out;
+	}
+
+	/*
+	 * The outgoing buffer is readily referred from the dma buffer,
+	 * just need to get header part from mailboxq structure.
+	 */
+	pmb = (uint8_t *)&pmboxq->u.mb;
+	pmb_buf = (uint8_t *)dd_data->context_un.mbox.mb;
+	memcpy(pmb_buf, pmb, sizeof(MAILBOX_t));
+
+	job = dd_data->context_un.mbox.set_job;
+	if (job) {
+		size = job->reply_payload.payload_len;
+		job->reply->reply_payload_rcv_len =
+			sg_copy_from_buffer(job->reply_payload.sg_list,
+					    job->reply_payload.sg_cnt,
+					    pmb_buf, size);
+		/* result for successful */
+		job->reply->result = 0;
+		job->dd_data = NULL;
+		/* need to hold the lock util we set job->dd_data to NULL
+		 * to hold off the timeout handler from midlayer to take
+		 * any action.
+		 */
+		spin_unlock_irqrestore(&phba->ct_ev_lock, flags);
+		lpfc_printf_log(phba, KERN_INFO, LOG_LIBDFC,
+				"2937 SLI_CONFIG ext-buffer maibox command "
+				"(x%x/x%x) complete bsg job done, bsize:%d\n",
+				phba->mbox_ext_buf_ctx.nembType,
+				phba->mbox_ext_buf_ctx.mboxType, size);
+	} else
+		spin_unlock_irqrestore(&phba->ct_ev_lock, flags);
+
+job_done_out:
+	if (!job)
+		lpfc_printf_log(phba, KERN_ERR, LOG_LIBDFC,
+				"2938 SLI_CONFIG ext-buffer maibox "
+				"command (x%x/x%x) failure, rc:x%x\n",
+				phba->mbox_ext_buf_ctx.nembType,
+				phba->mbox_ext_buf_ctx.mboxType, rc);
+	/* state change */
+	phba->mbox_ext_buf_ctx.state = LPFC_BSG_MBOX_DONE;
+	kfree(dd_data);
+
+	return job;
+}
+
+/**
+ * lpfc_bsg_issue_read_mbox_ext_cmpl - compl handler for multi-buffer read mbox
+ * @phba: Pointer to HBA context object.
+ * @pmboxq: Pointer to mailbox command.
+ *
+ * This is completion handler function for mailbox read commands with multiple
+ * external buffers.
+ **/
+static void
+lpfc_bsg_issue_read_mbox_ext_cmpl(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmboxq)
+{
+	struct fc_bsg_job *job;
+
+	/* handle the BSG job with mailbox command */
+	if (phba->mbox_ext_buf_ctx.state == LPFC_BSG_MBOX_ABTS)
+		pmboxq->u.mb.mbxStatus = MBXERR_ERROR;
+
+	lpfc_printf_log(phba, KERN_INFO, LOG_LIBDFC,
+			"2939 SLI_CONFIG ext-buffer rd maibox command "
+			"complete, ctxState:x%x, mbxStatus:x%x\n",
+			phba->mbox_ext_buf_ctx.state, pmboxq->u.mb.mbxStatus);
+
+	job = lpfc_bsg_issue_mbox_ext_handle_job(phba, pmboxq);
+
+	if (pmboxq->u.mb.mbxStatus || phba->mbox_ext_buf_ctx.numBuf == 1)
+		lpfc_bsg_mbox_ext_session_reset(phba);
+
+	/* free base driver mailbox structure memory */
+	mempool_free(pmboxq, phba->mbox_mem_pool);
+
+	/* complete the bsg job if we have it */
+	if (job)
+		job->job_done(job);
+
+	return;
+}
+
+/**
+ * lpfc_bsg_issue_write_mbox_ext_cmpl - cmpl handler for multi-buffer write mbox
+ * @phba: Pointer to HBA context object.
+ * @pmboxq: Pointer to mailbox command.
+ *
+ * This is completion handler function for mailbox write commands with multiple
+ * external buffers.
+ **/
+static void
+lpfc_bsg_issue_write_mbox_ext_cmpl(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmboxq)
+{
+	struct fc_bsg_job *job;
+
+	/* handle the BSG job with the mailbox command */
+	if (phba->mbox_ext_buf_ctx.state == LPFC_BSG_MBOX_ABTS)
+		pmboxq->u.mb.mbxStatus = MBXERR_ERROR;
+
+	lpfc_printf_log(phba, KERN_INFO, LOG_LIBDFC,
+			"2940 SLI_CONFIG ext-buffer wr maibox command "
+			"complete, ctxState:x%x, mbxStatus:x%x\n",
+			phba->mbox_ext_buf_ctx.state, pmboxq->u.mb.mbxStatus);
+
+	job = lpfc_bsg_issue_mbox_ext_handle_job(phba, pmboxq);
+
+	/* free all memory, including dma buffers */
+	mempool_free(pmboxq, phba->mbox_mem_pool);
+	lpfc_bsg_mbox_ext_session_reset(phba);
+
+	/* complete the bsg job if we have it */
+	if (job)
+		job->job_done(job);
+
+	return;
+}
+
+static void
+lpfc_bsg_sli_cfg_dma_desc_setup(struct lpfc_hba *phba, enum nemb_type nemb_tp,
+				uint32_t index, struct lpfc_dmabuf *mbx_dmabuf,
+				struct lpfc_dmabuf *ext_dmabuf)
+{
+	struct lpfc_sli_config_mbox *sli_cfg_mbx;
+
+	/* pointer to the start of mailbox command */
+	sli_cfg_mbx = (struct lpfc_sli_config_mbox *)mbx_dmabuf->virt;
+
+	if (nemb_tp == nemb_mse) {
+		if (index == 0) {
+			sli_cfg_mbx->un.sli_config_emb0_subsys.
+				mse[index].pa_hi =
+				putPaddrHigh(mbx_dmabuf->phys +
+					     sizeof(MAILBOX_t));
+			sli_cfg_mbx->un.sli_config_emb0_subsys.
+				mse[index].pa_lo =
+				putPaddrLow(mbx_dmabuf->phys +
+					    sizeof(MAILBOX_t));
+			lpfc_printf_log(phba, KERN_INFO, LOG_LIBDFC,
+					"2943 SLI_CONFIG(mse)[%d], "
+					"bufLen:%d, addrHi:x%x, addrLo:x%x\n",
+					index,
+					sli_cfg_mbx->un.sli_config_emb0_subsys.
+					mse[index].buf_len,
+					sli_cfg_mbx->un.sli_config_emb0_subsys.
+					mse[index].pa_hi,
+					sli_cfg_mbx->un.sli_config_emb0_subsys.
+					mse[index].pa_lo);
+		} else {
+			sli_cfg_mbx->un.sli_config_emb0_subsys.
+				mse[index].pa_hi =
+				putPaddrHigh(ext_dmabuf->phys);
+			sli_cfg_mbx->un.sli_config_emb0_subsys.
+				mse[index].pa_lo =
+				putPaddrLow(ext_dmabuf->phys);
+			lpfc_printf_log(phba, KERN_INFO, LOG_LIBDFC,
+					"2944 SLI_CONFIG(mse)[%d], "
+					"bufLen:%d, addrHi:x%x, addrLo:x%x\n",
+					index,
+					sli_cfg_mbx->un.sli_config_emb0_subsys.
+					mse[index].buf_len,
+					sli_cfg_mbx->un.sli_config_emb0_subsys.
+					mse[index].pa_hi,
+					sli_cfg_mbx->un.sli_config_emb0_subsys.
+					mse[index].pa_lo);
+		}
+	} else {
+		if (index == 0) {
+			sli_cfg_mbx->un.sli_config_emb1_subsys.
+				hbd[index].pa_hi =
+				putPaddrHigh(mbx_dmabuf->phys +
+					     sizeof(MAILBOX_t));
+			sli_cfg_mbx->un.sli_config_emb1_subsys.
+				hbd[index].pa_lo =
+				putPaddrLow(mbx_dmabuf->phys +
+					    sizeof(MAILBOX_t));
+			lpfc_printf_log(phba, KERN_INFO, LOG_LIBDFC,
+					"3007 SLI_CONFIG(hbd)[%d], "
+					"bufLen:%d, addrHi:x%x, addrLo:x%x\n",
+				index,
+				bsg_bf_get(lpfc_mbox_sli_config_ecmn_hbd_len,
+				&sli_cfg_mbx->un.
+				sli_config_emb1_subsys.hbd[index]),
+				sli_cfg_mbx->un.sli_config_emb1_subsys.
+				hbd[index].pa_hi,
+				sli_cfg_mbx->un.sli_config_emb1_subsys.
+				hbd[index].pa_lo);
+
+		} else {
+			sli_cfg_mbx->un.sli_config_emb1_subsys.
+				hbd[index].pa_hi =
+				putPaddrHigh(ext_dmabuf->phys);
+			sli_cfg_mbx->un.sli_config_emb1_subsys.
+				hbd[index].pa_lo =
+				putPaddrLow(ext_dmabuf->phys);
+			lpfc_printf_log(phba, KERN_INFO, LOG_LIBDFC,
+					"3008 SLI_CONFIG(hbd)[%d], "
+					"bufLen:%d, addrHi:x%x, addrLo:x%x\n",
+				index,
+				bsg_bf_get(lpfc_mbox_sli_config_ecmn_hbd_len,
+				&sli_cfg_mbx->un.
+				sli_config_emb1_subsys.hbd[index]),
+				sli_cfg_mbx->un.sli_config_emb1_subsys.
+				hbd[index].pa_hi,
+				sli_cfg_mbx->un.sli_config_emb1_subsys.
+				hbd[index].pa_lo);
+		}
+	}
+	return;
+}
+
+/**
+ * lpfc_bsg_sli_cfg_mse_read_cmd_ext - sli_config non-embedded mailbox cmd read
+ * @phba: Pointer to HBA context object.
+ * @mb: Pointer to a BSG mailbox object.
+ * @nemb_tp: Enumerate of non-embedded mailbox command type.
+ * @dmabuff: Pointer to a DMA buffer descriptor.
+ *
+ * This routine performs SLI_CONFIG (0x9B) read mailbox command operation with
+ * non-embedded external bufffers.
+ **/
+static int
+lpfc_bsg_sli_cfg_read_cmd_ext(struct lpfc_hba *phba, struct fc_bsg_job *job,
+			      enum nemb_type nemb_tp,
+			      struct lpfc_dmabuf *dmabuf)
+{
+	struct lpfc_sli_config_mbox *sli_cfg_mbx;
+	struct dfc_mbox_req *mbox_req;
+	struct lpfc_dmabuf *curr_dmabuf, *next_dmabuf;
+	uint32_t ext_buf_cnt, ext_buf_index;
+	struct lpfc_dmabuf *ext_dmabuf = NULL;
+	struct bsg_job_data *dd_data = NULL;
+	LPFC_MBOXQ_t *pmboxq = NULL;
+	MAILBOX_t *pmb;
+	uint8_t *pmbx;
+	int rc, i;
+
+	mbox_req =
+	   (struct dfc_mbox_req *)job->request->rqst_data.h_vendor.vendor_cmd;
+
+	/* pointer to the start of mailbox command */
+	sli_cfg_mbx = (struct lpfc_sli_config_mbox *)dmabuf->virt;
+
+	if (nemb_tp == nemb_mse) {
+		ext_buf_cnt = bsg_bf_get(lpfc_mbox_hdr_mse_cnt,
+			&sli_cfg_mbx->un.sli_config_emb0_subsys.sli_config_hdr);
+		if (ext_buf_cnt > LPFC_MBX_SLI_CONFIG_MAX_MSE) {
+			lpfc_printf_log(phba, KERN_ERR, LOG_LIBDFC,
+					"2945 Handled SLI_CONFIG(mse) rd, "
+					"ext_buf_cnt(%d) out of range(%d)\n",
+					ext_buf_cnt,
+					LPFC_MBX_SLI_CONFIG_MAX_MSE);
+			rc = -ERANGE;
+			goto job_error;
+		}
+		lpfc_printf_log(phba, KERN_INFO, LOG_LIBDFC,
+				"2941 Handled SLI_CONFIG(mse) rd, "
+				"ext_buf_cnt:%d\n", ext_buf_cnt);
+	} else {
+		/* sanity check on interface type for support */
+		if (bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf) !=
+		    LPFC_SLI_INTF_IF_TYPE_2) {
+			rc = -ENODEV;
+			goto job_error;
+		}
+		/* nemb_tp == nemb_hbd */
+		ext_buf_cnt = sli_cfg_mbx->un.sli_config_emb1_subsys.hbd_count;
+		if (ext_buf_cnt > LPFC_MBX_SLI_CONFIG_MAX_HBD) {
+			lpfc_printf_log(phba, KERN_ERR, LOG_LIBDFC,
+					"2946 Handled SLI_CONFIG(hbd) rd, "
+					"ext_buf_cnt(%d) out of range(%d)\n",
+					ext_buf_cnt,
+					LPFC_MBX_SLI_CONFIG_MAX_HBD);
+			rc = -ERANGE;
+			goto job_error;
+		}
+		lpfc_printf_log(phba, KERN_INFO, LOG_LIBDFC,
+				"2942 Handled SLI_CONFIG(hbd) rd, "
+				"ext_buf_cnt:%d\n", ext_buf_cnt);
+	}
+
+	/* reject non-embedded mailbox command with none external buffer */
+	if (ext_buf_cnt == 0) {
+		rc = -EPERM;
+		goto job_error;
+	} else if (ext_buf_cnt > 1) {
+		/* additional external read buffers */
+		for (i = 1; i < ext_buf_cnt; i++) {
+			ext_dmabuf = lpfc_bsg_dma_page_alloc(phba);
+			if (!ext_dmabuf) {
+				rc = -ENOMEM;
+				goto job_error;
+			}
+			list_add_tail(&ext_dmabuf->list,
+				      &phba->mbox_ext_buf_ctx.ext_dmabuf_list);
+		}
+	}
+
+	/* bsg tracking structure */
+	dd_data = kmalloc(sizeof(struct bsg_job_data), GFP_KERNEL);
+	if (!dd_data) {
+		rc = -ENOMEM;
+		goto job_error;
+	}
+
+	/* mailbox command structure for base driver */
+	pmboxq = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
+	if (!pmboxq) {
+		rc = -ENOMEM;
+		goto job_error;
+	}
+	memset(pmboxq, 0, sizeof(LPFC_MBOXQ_t));
+
+	/* for the first external buffer */
+	lpfc_bsg_sli_cfg_dma_desc_setup(phba, nemb_tp, 0, dmabuf, dmabuf);
+
+	/* for the rest of external buffer descriptors if any */
+	if (ext_buf_cnt > 1) {
+		ext_buf_index = 1;
+		list_for_each_entry_safe(curr_dmabuf, next_dmabuf,
+				&phba->mbox_ext_buf_ctx.ext_dmabuf_list, list) {
+			lpfc_bsg_sli_cfg_dma_desc_setup(phba, nemb_tp,
+						ext_buf_index, dmabuf,
+						curr_dmabuf);
+			ext_buf_index++;
+		}
+	}
+
+	/* construct base driver mbox command */
+	pmb = &pmboxq->u.mb;
+	pmbx = (uint8_t *)dmabuf->virt;
+	memcpy(pmb, pmbx, sizeof(*pmb));
+	pmb->mbxOwner = OWN_HOST;
+	pmboxq->vport = phba->pport;
+
+	/* multi-buffer handling context */
+	phba->mbox_ext_buf_ctx.nembType = nemb_tp;
+	phba->mbox_ext_buf_ctx.mboxType = mbox_rd;
+	phba->mbox_ext_buf_ctx.numBuf = ext_buf_cnt;
+	phba->mbox_ext_buf_ctx.mbxTag = mbox_req->extMboxTag;
+	phba->mbox_ext_buf_ctx.seqNum = mbox_req->extSeqNum;
+	phba->mbox_ext_buf_ctx.mbx_dmabuf = dmabuf;
+
+	/* callback for multi-buffer read mailbox command */
+	pmboxq->mbox_cmpl = lpfc_bsg_issue_read_mbox_ext_cmpl;
+
+	/* context fields to callback function */
+	pmboxq->context1 = dd_data;
+	dd_data->type = TYPE_MBOX;
+	dd_data->context_un.mbox.pmboxq = pmboxq;
+	dd_data->context_un.mbox.mb = (MAILBOX_t *)pmbx;
+	dd_data->context_un.mbox.set_job = job;
+	job->dd_data = dd_data;
+
+	/* state change */
+	phba->mbox_ext_buf_ctx.state = LPFC_BSG_MBOX_PORT;
+
+	rc = lpfc_sli_issue_mbox(phba, pmboxq, MBX_NOWAIT);
+	if ((rc == MBX_SUCCESS) || (rc == MBX_BUSY)) {
+		lpfc_printf_log(phba, KERN_INFO, LOG_LIBDFC,
+				"2947 Issued SLI_CONFIG ext-buffer "
+				"maibox command, rc:x%x\n", rc);
+		return 1;
+	}
+	lpfc_printf_log(phba, KERN_ERR, LOG_LIBDFC,
+			"2948 Failed to issue SLI_CONFIG ext-buffer "
+			"maibox command, rc:x%x\n", rc);
+	rc = -EPIPE;
+
+job_error:
+	if (pmboxq)
+		mempool_free(pmboxq, phba->mbox_mem_pool);
+	lpfc_bsg_dma_page_list_free(phba,
+				    &phba->mbox_ext_buf_ctx.ext_dmabuf_list);
+	kfree(dd_data);
+	phba->mbox_ext_buf_ctx.state = LPFC_BSG_MBOX_IDLE;
+	return rc;
+}
+
+/**
+ * lpfc_bsg_sli_cfg_write_cmd_ext - sli_config non-embedded mailbox cmd write
+ * @phba: Pointer to HBA context object.
+ * @mb: Pointer to a BSG mailbox object.
+ * @dmabuff: Pointer to a DMA buffer descriptor.
+ *
+ * This routine performs SLI_CONFIG (0x9B) write mailbox command operation with
+ * non-embedded external bufffers.
+ **/
+static int
+lpfc_bsg_sli_cfg_write_cmd_ext(struct lpfc_hba *phba, struct fc_bsg_job *job,
+			       enum nemb_type nemb_tp,
+			       struct lpfc_dmabuf *dmabuf)
+{
+	struct dfc_mbox_req *mbox_req;
+	struct lpfc_sli_config_mbox *sli_cfg_mbx;
+	uint32_t ext_buf_cnt;
+	struct bsg_job_data *dd_data = NULL;
+	LPFC_MBOXQ_t *pmboxq = NULL;
+	MAILBOX_t *pmb;
+	uint8_t *mbx;
+	int rc = 0, i;
+
+	mbox_req =
+	   (struct dfc_mbox_req *)job->request->rqst_data.h_vendor.vendor_cmd;
+
+	/* pointer to the start of mailbox command */
+	sli_cfg_mbx = (struct lpfc_sli_config_mbox *)dmabuf->virt;
+
+	if (nemb_tp == nemb_mse) {
+		ext_buf_cnt = bsg_bf_get(lpfc_mbox_hdr_mse_cnt,
+			&sli_cfg_mbx->un.sli_config_emb0_subsys.sli_config_hdr);
+		if (ext_buf_cnt > LPFC_MBX_SLI_CONFIG_MAX_MSE) {
+			lpfc_printf_log(phba, KERN_ERR, LOG_LIBDFC,
+					"2953 Handled SLI_CONFIG(mse) wr, "
+					"ext_buf_cnt(%d) out of range(%d)\n",
+					ext_buf_cnt,
+					LPFC_MBX_SLI_CONFIG_MAX_MSE);
+			return -ERANGE;
+		}
+		lpfc_printf_log(phba, KERN_INFO, LOG_LIBDFC,
+				"2949 Handled SLI_CONFIG(mse) wr, "
+				"ext_buf_cnt:%d\n", ext_buf_cnt);
+	} else {
+		/* sanity check on interface type for support */
+		if (bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf) !=
+		    LPFC_SLI_INTF_IF_TYPE_2)
+			return -ENODEV;
+		/* nemb_tp == nemb_hbd */
+		ext_buf_cnt = sli_cfg_mbx->un.sli_config_emb1_subsys.hbd_count;
+		if (ext_buf_cnt > LPFC_MBX_SLI_CONFIG_MAX_HBD) {
+			lpfc_printf_log(phba, KERN_ERR, LOG_LIBDFC,
+					"2954 Handled SLI_CONFIG(hbd) wr, "
+					"ext_buf_cnt(%d) out of range(%d)\n",
+					ext_buf_cnt,
+					LPFC_MBX_SLI_CONFIG_MAX_HBD);
+			return -ERANGE;
+		}
+		lpfc_printf_log(phba, KERN_INFO, LOG_LIBDFC,
+				"2950 Handled SLI_CONFIG(hbd) wr, "
+				"ext_buf_cnt:%d\n", ext_buf_cnt);
+	}
+
+	if (ext_buf_cnt == 0)
+		return -EPERM;
+
+	/* for the first external buffer */
+	lpfc_bsg_sli_cfg_dma_desc_setup(phba, nemb_tp, 0, dmabuf, dmabuf);
+
+	/* log for looking forward */
+	for (i = 1; i < ext_buf_cnt; i++) {
+		if (nemb_tp == nemb_mse)
+			lpfc_printf_log(phba, KERN_INFO, LOG_LIBDFC,
+				"2951 SLI_CONFIG(mse), buf[%d]-length:%d\n",
+				i, sli_cfg_mbx->un.sli_config_emb0_subsys.
+				mse[i].buf_len);
+		else
+			lpfc_printf_log(phba, KERN_INFO, LOG_LIBDFC,
+				"2952 SLI_CONFIG(hbd), buf[%d]-length:%d\n",
+				i, bsg_bf_get(lpfc_mbox_sli_config_ecmn_hbd_len,
+				&sli_cfg_mbx->un.sli_config_emb1_subsys.
+				hbd[i]));
+	}
+
+	/* multi-buffer handling context */
+	phba->mbox_ext_buf_ctx.nembType = nemb_tp;
+	phba->mbox_ext_buf_ctx.mboxType = mbox_wr;
+	phba->mbox_ext_buf_ctx.numBuf = ext_buf_cnt;
+	phba->mbox_ext_buf_ctx.mbxTag = mbox_req->extMboxTag;
+	phba->mbox_ext_buf_ctx.seqNum = mbox_req->extSeqNum;
+	phba->mbox_ext_buf_ctx.mbx_dmabuf = dmabuf;
+
+	if (ext_buf_cnt == 1) {
+		/* bsg tracking structure */
+		dd_data = kmalloc(sizeof(struct bsg_job_data), GFP_KERNEL);
+		if (!dd_data) {
+			rc = -ENOMEM;
+			goto job_error;
+		}
+
+		/* mailbox command structure for base driver */
+		pmboxq = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
+		if (!pmboxq) {
+			rc = -ENOMEM;
+			goto job_error;
+		}
+		memset(pmboxq, 0, sizeof(LPFC_MBOXQ_t));
+		pmb = &pmboxq->u.mb;
+		mbx = (uint8_t *)dmabuf->virt;
+		memcpy(pmb, mbx, sizeof(*pmb));
+		pmb->mbxOwner = OWN_HOST;
+		pmboxq->vport = phba->pport;
+
+		/* callback for multi-buffer read mailbox command */
+		pmboxq->mbox_cmpl = lpfc_bsg_issue_write_mbox_ext_cmpl;
+
+		/* context fields to callback function */
+		pmboxq->context1 = dd_data;
+		dd_data->type = TYPE_MBOX;
+		dd_data->context_un.mbox.pmboxq = pmboxq;
+		dd_data->context_un.mbox.mb = (MAILBOX_t *)mbx;
+		dd_data->context_un.mbox.set_job = job;
+		job->dd_data = dd_data;
+
+		/* state change */
+		phba->mbox_ext_buf_ctx.state = LPFC_BSG_MBOX_PORT;
+
+		rc = lpfc_sli_issue_mbox(phba, pmboxq, MBX_NOWAIT);
+		if ((rc == MBX_SUCCESS) || (rc == MBX_BUSY)) {
+			lpfc_printf_log(phba, KERN_INFO, LOG_LIBDFC,
+					"2955 Issued SLI_CONFIG ext-buffer "
+					"maibox command, rc:x%x\n", rc);
+			return 1;
+		}
+		lpfc_printf_log(phba, KERN_ERR, LOG_LIBDFC,
+				"2956 Failed to issue SLI_CONFIG ext-buffer "
+				"maibox command, rc:x%x\n", rc);
+		rc = -EPIPE;
+	}
+
+job_error:
+	if (pmboxq)
+		mempool_free(pmboxq, phba->mbox_mem_pool);
+	kfree(dd_data);
+
+	return rc;
+}
+
+/**
+ * lpfc_bsg_handle_sli_cfg_mbox - handle sli-cfg mailbox cmd with ext buffer
+ * @phba: Pointer to HBA context object.
+ * @mb: Pointer to a BSG mailbox object.
+ * @dmabuff: Pointer to a DMA buffer descriptor.
+ *
+ * This routine handles SLI_CONFIG (0x9B) mailbox command with non-embedded
+ * external bufffers, including both 0x9B with non-embedded MSEs and 0x9B
+ * with embedded sussystem 0x1 and opcodes with external HBDs.
+ **/
+static int
+lpfc_bsg_handle_sli_cfg_mbox(struct lpfc_hba *phba, struct fc_bsg_job *job,
+			     struct lpfc_dmabuf *dmabuf)
+{
+	struct lpfc_sli_config_mbox *sli_cfg_mbx;
+	uint32_t subsys;
+	uint32_t opcode;
+	int rc = SLI_CONFIG_NOT_HANDLED;
+
+	/* state change */
+	phba->mbox_ext_buf_ctx.state = LPFC_BSG_MBOX_HOST;
+
+	sli_cfg_mbx = (struct lpfc_sli_config_mbox *)dmabuf->virt;
+
+	if (!bsg_bf_get(lpfc_mbox_hdr_emb,
+	    &sli_cfg_mbx->un.sli_config_emb0_subsys.sli_config_hdr)) {
+		subsys = bsg_bf_get(lpfc_emb0_subcmnd_subsys,
+				    &sli_cfg_mbx->un.sli_config_emb0_subsys);
+		opcode = bsg_bf_get(lpfc_emb0_subcmnd_opcode,
+				    &sli_cfg_mbx->un.sli_config_emb0_subsys);
+		if (subsys == SLI_CONFIG_SUBSYS_FCOE) {
+			switch (opcode) {
+			case FCOE_OPCODE_READ_FCF:
+				lpfc_printf_log(phba, KERN_INFO, LOG_LIBDFC,
+						"2957 Handled SLI_CONFIG "
+						"subsys_fcoe, opcode:x%x\n",
+						opcode);
+				rc = lpfc_bsg_sli_cfg_read_cmd_ext(phba, job,
+							nemb_mse, dmabuf);
+				break;
+			case FCOE_OPCODE_ADD_FCF:
+				lpfc_printf_log(phba, KERN_INFO, LOG_LIBDFC,
+						"2958 Handled SLI_CONFIG "
+						"subsys_fcoe, opcode:x%x\n",
+						opcode);
+				rc = lpfc_bsg_sli_cfg_write_cmd_ext(phba, job,
+							nemb_mse, dmabuf);
+				break;
+			default:
+				lpfc_printf_log(phba, KERN_INFO, LOG_LIBDFC,
+						"2959 Not handled SLI_CONFIG "
+						"subsys_fcoe, opcode:x%x\n",
+						opcode);
+				rc = SLI_CONFIG_NOT_HANDLED;
+				break;
+			}
+		} else {
+			lpfc_printf_log(phba, KERN_INFO, LOG_LIBDFC,
+					"2977 Handled SLI_CONFIG "
+					"subsys:x%d, opcode:x%x\n",
+					subsys, opcode);
+			rc = SLI_CONFIG_NOT_HANDLED;
+		}
+	} else {
+		subsys = bsg_bf_get(lpfc_emb1_subcmnd_subsys,
+				    &sli_cfg_mbx->un.sli_config_emb1_subsys);
+		opcode = bsg_bf_get(lpfc_emb1_subcmnd_opcode,
+				    &sli_cfg_mbx->un.sli_config_emb1_subsys);
+		if (subsys == SLI_CONFIG_SUBSYS_COMN) {
+			switch (opcode) {
+			case COMN_OPCODE_READ_OBJECT:
+			case COMN_OPCODE_READ_OBJECT_LIST:
+				lpfc_printf_log(phba, KERN_INFO, LOG_LIBDFC,
+						"2960 Handled SLI_CONFIG "
+						"subsys_comn, opcode:x%x\n",
+						opcode);
+				rc = lpfc_bsg_sli_cfg_read_cmd_ext(phba, job,
+							nemb_hbd, dmabuf);
+				break;
+			case COMN_OPCODE_WRITE_OBJECT:
+				lpfc_printf_log(phba, KERN_INFO, LOG_LIBDFC,
+						"2961 Handled SLI_CONFIG "
+						"subsys_comn, opcode:x%x\n",
+						opcode);
+				rc = lpfc_bsg_sli_cfg_write_cmd_ext(phba, job,
+							nemb_hbd, dmabuf);
+				break;
+			default:
+				lpfc_printf_log(phba, KERN_INFO, LOG_LIBDFC,
+						"2962 Not handled SLI_CONFIG "
+						"subsys_comn, opcode:x%x\n",
+						opcode);
+				rc = SLI_CONFIG_NOT_HANDLED;
+				break;
+			}
+		} else {
+			lpfc_printf_log(phba, KERN_INFO, LOG_LIBDFC,
+					"2978 Handled SLI_CONFIG "
+					"subsys:x%d, opcode:x%x\n",
+					subsys, opcode);
+			rc = SLI_CONFIG_NOT_HANDLED;
+		}
+	}
+	return rc;
+}
+
+/**
+ * lpfc_bsg_mbox_ext_abort_req - request to abort mbox command with ext buffers
+ * @phba: Pointer to HBA context object.
+ *
+ * This routine is for requesting to abort a pass-through mailbox command with
+ * multiple external buffers due to error condition.
+ **/
+static void
+lpfc_bsg_mbox_ext_abort(struct lpfc_hba *phba)
+{
+	if (phba->mbox_ext_buf_ctx.state == LPFC_BSG_MBOX_PORT)
+		phba->mbox_ext_buf_ctx.state = LPFC_BSG_MBOX_ABTS;
+	else
+		lpfc_bsg_mbox_ext_session_reset(phba);
+	return;
+}
+
+/**
+ * lpfc_bsg_read_ebuf_get - get the next mailbox read external buffer
+ * @phba: Pointer to HBA context object.
+ * @dmabuf: Pointer to a DMA buffer descriptor.
+ *
+ * This routine extracts the next mailbox read external buffer back to
+ * user space through BSG.
+ **/
+static int
+lpfc_bsg_read_ebuf_get(struct lpfc_hba *phba, struct fc_bsg_job *job)
+{
+	struct lpfc_sli_config_mbox *sli_cfg_mbx;
+	struct lpfc_dmabuf *dmabuf;
+	uint8_t *pbuf;
+	uint32_t size;
+	uint32_t index;
+
+	index = phba->mbox_ext_buf_ctx.seqNum;
+	phba->mbox_ext_buf_ctx.seqNum++;
+
+	sli_cfg_mbx = (struct lpfc_sli_config_mbox *)
+			phba->mbox_ext_buf_ctx.mbx_dmabuf->virt;
+
+	if (phba->mbox_ext_buf_ctx.nembType == nemb_mse) {
+		size = bsg_bf_get(lpfc_mbox_sli_config_mse_len,
+			&sli_cfg_mbx->un.sli_config_emb0_subsys.mse[index]);
+		lpfc_printf_log(phba, KERN_INFO, LOG_LIBDFC,
+				"2963 SLI_CONFIG (mse) ext-buffer rd get "
+				"buffer[%d], size:%d\n", index, size);
+	} else {
+		size = bsg_bf_get(lpfc_mbox_sli_config_ecmn_hbd_len,
+			&sli_cfg_mbx->un.sli_config_emb1_subsys.hbd[index]);
+		lpfc_printf_log(phba, KERN_INFO, LOG_LIBDFC,
+				"2964 SLI_CONFIG (hbd) ext-buffer rd get "
+				"buffer[%d], size:%d\n", index, size);
+	}
+	if (list_empty(&phba->mbox_ext_buf_ctx.ext_dmabuf_list))
+		return -EPIPE;
+	dmabuf = list_first_entry(&phba->mbox_ext_buf_ctx.ext_dmabuf_list,
+				  struct lpfc_dmabuf, list);
+	list_del_init(&dmabuf->list);
+	pbuf = (uint8_t *)dmabuf->virt;
+	job->reply->reply_payload_rcv_len =
+		sg_copy_from_buffer(job->reply_payload.sg_list,
+				    job->reply_payload.sg_cnt,
+				    pbuf, size);
+
+	lpfc_bsg_dma_page_free(phba, dmabuf);
+
+	if (phba->mbox_ext_buf_ctx.seqNum == phba->mbox_ext_buf_ctx.numBuf) {
+		lpfc_printf_log(phba, KERN_INFO, LOG_LIBDFC,
+				"2965 SLI_CONFIG (hbd) ext-buffer rd mbox "
+				"command session done\n");
+		lpfc_bsg_mbox_ext_session_reset(phba);
+	}
+
+	job->reply->result = 0;
+	job->job_done(job);
+
+	return SLI_CONFIG_HANDLED;
+}
+
+/**
+ * lpfc_bsg_write_ebuf_set - set the next mailbox write external buffer
+ * @phba: Pointer to HBA context object.
+ * @dmabuf: Pointer to a DMA buffer descriptor.
+ *
+ * This routine sets up the next mailbox read external buffer obtained
+ * from user space through BSG.
+ **/
+static int
+lpfc_bsg_write_ebuf_set(struct lpfc_hba *phba, struct fc_bsg_job *job,
+			struct lpfc_dmabuf *dmabuf)
+{
+	struct lpfc_sli_config_mbox *sli_cfg_mbx;
+	struct bsg_job_data *dd_data = NULL;
+	LPFC_MBOXQ_t *pmboxq = NULL;
+	MAILBOX_t *pmb;
+	enum nemb_type nemb_tp;
+	uint8_t *pbuf;
+	uint32_t size;
+	uint32_t index;
+	int rc;
+
+	index = phba->mbox_ext_buf_ctx.seqNum;
+	phba->mbox_ext_buf_ctx.seqNum++;
+	nemb_tp = phba->mbox_ext_buf_ctx.nembType;
+
+	sli_cfg_mbx = (struct lpfc_sli_config_mbox *)
+			phba->mbox_ext_buf_ctx.mbx_dmabuf->virt;
+
+	dd_data = kmalloc(sizeof(struct bsg_job_data), GFP_KERNEL);
+	if (!dd_data) {
+		rc = -ENOMEM;
+		goto job_error;
+	}
+
+	pbuf = (uint8_t *)dmabuf->virt;
+	size = job->request_payload.payload_len;
+	sg_copy_to_buffer(job->request_payload.sg_list,
+			  job->request_payload.sg_cnt,
+			  pbuf, size);
+
+	if (phba->mbox_ext_buf_ctx.nembType == nemb_mse) {
+		lpfc_printf_log(phba, KERN_INFO, LOG_LIBDFC,
+				"2966 SLI_CONFIG (mse) ext-buffer wr set "
+				"buffer[%d], size:%d\n",
+				phba->mbox_ext_buf_ctx.seqNum, size);
+
+	} else {
+		lpfc_printf_log(phba, KERN_INFO, LOG_LIBDFC,
+				"2967 SLI_CONFIG (hbd) ext-buffer wr set "
+				"buffer[%d], size:%d\n",
+				phba->mbox_ext_buf_ctx.seqNum, size);
+
+	}
+
+	/* set up external buffer descriptor and add to external buffer list */
+	lpfc_bsg_sli_cfg_dma_desc_setup(phba, nemb_tp, index,
+					phba->mbox_ext_buf_ctx.mbx_dmabuf,
+					dmabuf);
+	list_add_tail(&dmabuf->list, &phba->mbox_ext_buf_ctx.ext_dmabuf_list);
+
+	if (phba->mbox_ext_buf_ctx.seqNum == phba->mbox_ext_buf_ctx.numBuf) {
+		lpfc_printf_log(phba, KERN_INFO, LOG_LIBDFC,
+				"2968 SLI_CONFIG ext-buffer wr all %d "
+				"ebuffers received\n",
+				phba->mbox_ext_buf_ctx.numBuf);
+		/* mailbox command structure for base driver */
+		pmboxq = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
+		if (!pmboxq) {
+			rc = -ENOMEM;
+			goto job_error;
+		}
+		memset(pmboxq, 0, sizeof(LPFC_MBOXQ_t));
+		pbuf = (uint8_t *)phba->mbox_ext_buf_ctx.mbx_dmabuf->virt;
+		pmb = &pmboxq->u.mb;
+		memcpy(pmb, pbuf, sizeof(*pmb));
+		pmb->mbxOwner = OWN_HOST;
+		pmboxq->vport = phba->pport;
+
+		/* callback for multi-buffer write mailbox command */
+		pmboxq->mbox_cmpl = lpfc_bsg_issue_write_mbox_ext_cmpl;
+
+		/* context fields to callback function */
+		pmboxq->context1 = dd_data;
+		dd_data->type = TYPE_MBOX;
+		dd_data->context_un.mbox.pmboxq = pmboxq;
+		dd_data->context_un.mbox.mb = (MAILBOX_t *)pbuf;
+		dd_data->context_un.mbox.set_job = job;
+		job->dd_data = dd_data;
+
+		/* state change */
+		phba->mbox_ext_buf_ctx.state = LPFC_BSG_MBOX_PORT;
+
+		rc = lpfc_sli_issue_mbox(phba, pmboxq, MBX_NOWAIT);
+		if ((rc == MBX_SUCCESS) || (rc == MBX_BUSY)) {
+			lpfc_printf_log(phba, KERN_INFO, LOG_LIBDFC,
+					"2969 Issued SLI_CONFIG ext-buffer "
+					"maibox command, rc:x%x\n", rc);
+			return 1;
+		}
+		lpfc_printf_log(phba, KERN_ERR, LOG_LIBDFC,
+				"2970 Failed to issue SLI_CONFIG ext-buffer "
+				"maibox command, rc:x%x\n", rc);
+		rc = -EPIPE;
+		goto job_error;
+	}
+
+	/* wait for additoinal external buffers */
+	job->reply->result = 0;
+	job->job_done(job);
+	return SLI_CONFIG_HANDLED;
+
+job_error:
+	lpfc_bsg_dma_page_free(phba, dmabuf);
+	kfree(dd_data);
+
+	return rc;
+}
+
+/**
+ * lpfc_bsg_handle_sli_cfg_ebuf - handle ext buffer with sli-cfg mailbox cmd
+ * @phba: Pointer to HBA context object.
+ * @mb: Pointer to a BSG mailbox object.
+ * @dmabuff: Pointer to a DMA buffer descriptor.
+ *
+ * This routine handles the external buffer with SLI_CONFIG (0x9B) mailbox
+ * command with multiple non-embedded external buffers.
+ **/
+static int
+lpfc_bsg_handle_sli_cfg_ebuf(struct lpfc_hba *phba, struct fc_bsg_job *job,
+			     struct lpfc_dmabuf *dmabuf)
+{
+	int rc;
+
+	lpfc_printf_log(phba, KERN_INFO, LOG_LIBDFC,
+			"2971 SLI_CONFIG buffer (type:x%x)\n",
+			phba->mbox_ext_buf_ctx.mboxType);
+
+	if (phba->mbox_ext_buf_ctx.mboxType == mbox_rd) {
+		if (phba->mbox_ext_buf_ctx.state != LPFC_BSG_MBOX_DONE) {
+			lpfc_printf_log(phba, KERN_ERR, LOG_LIBDFC,
+					"2972 SLI_CONFIG rd buffer state "
+					"mismatch:x%x\n",
+					phba->mbox_ext_buf_ctx.state);
+			lpfc_bsg_mbox_ext_abort(phba);
+			return -EPIPE;
+		}
+		rc = lpfc_bsg_read_ebuf_get(phba, job);
+		if (rc == SLI_CONFIG_HANDLED)
+			lpfc_bsg_dma_page_free(phba, dmabuf);
+	} else { /* phba->mbox_ext_buf_ctx.mboxType == mbox_wr */
+		if (phba->mbox_ext_buf_ctx.state != LPFC_BSG_MBOX_HOST) {
+			lpfc_printf_log(phba, KERN_ERR, LOG_LIBDFC,
+					"2973 SLI_CONFIG wr buffer state "
+					"mismatch:x%x\n",
+					phba->mbox_ext_buf_ctx.state);
+			lpfc_bsg_mbox_ext_abort(phba);
+			return -EPIPE;
+		}
+		rc = lpfc_bsg_write_ebuf_set(phba, job, dmabuf);
+	}
+	return rc;
+}
+
+/**
+ * lpfc_bsg_handle_sli_cfg_ext - handle sli-cfg mailbox with external buffer
+ * @phba: Pointer to HBA context object.
+ * @mb: Pointer to a BSG mailbox object.
+ * @dmabuff: Pointer to a DMA buffer descriptor.
+ *
+ * This routine checkes and handles non-embedded multi-buffer SLI_CONFIG
+ * (0x9B) mailbox commands and external buffers.
+ **/
+static int
+lpfc_bsg_handle_sli_cfg_ext(struct lpfc_hba *phba, struct fc_bsg_job *job,
+			    struct lpfc_dmabuf *dmabuf)
+{
+	struct dfc_mbox_req *mbox_req;
+	int rc;
+
+	mbox_req =
+	   (struct dfc_mbox_req *)job->request->rqst_data.h_vendor.vendor_cmd;
+
+	/* mbox command with/without single external buffer */
+	if (mbox_req->extMboxTag == 0 && mbox_req->extSeqNum == 0)
+		return SLI_CONFIG_NOT_HANDLED;
+
+	/* mbox command and first external buffer */
+	if (phba->mbox_ext_buf_ctx.state == LPFC_BSG_MBOX_IDLE) {
+		if (mbox_req->extSeqNum == 1) {
+			lpfc_printf_log(phba, KERN_INFO, LOG_LIBDFC,
+					"2974 SLI_CONFIG mailbox: tag:%d, "
+					"seq:%d\n", mbox_req->extMboxTag,
+					mbox_req->extSeqNum);
+			rc = lpfc_bsg_handle_sli_cfg_mbox(phba, job, dmabuf);
+			return rc;
+		} else
+			goto sli_cfg_ext_error;
+	}
+
+	/*
+	 * handle additional external buffers
+	 */
+
+	/* check broken pipe conditions */
+	if (mbox_req->extMboxTag != phba->mbox_ext_buf_ctx.mbxTag)
+		goto sli_cfg_ext_error;
+	if (mbox_req->extSeqNum > phba->mbox_ext_buf_ctx.numBuf)
+		goto sli_cfg_ext_error;
+	if (mbox_req->extSeqNum != phba->mbox_ext_buf_ctx.seqNum + 1)
+		goto sli_cfg_ext_error;
+
+	lpfc_printf_log(phba, KERN_INFO, LOG_LIBDFC,
+			"2975 SLI_CONFIG mailbox external buffer: "
+			"extSta:x%x, tag:%d, seq:%d\n",
+			phba->mbox_ext_buf_ctx.state, mbox_req->extMboxTag,
+			mbox_req->extSeqNum);
+	rc = lpfc_bsg_handle_sli_cfg_ebuf(phba, job, dmabuf);
+	return rc;
+
+sli_cfg_ext_error:
+	/* all other cases, broken pipe */
+	lpfc_printf_log(phba, KERN_ERR, LOG_LIBDFC,
+			"2976 SLI_CONFIG mailbox broken pipe: "
+			"ctxSta:x%x, ctxNumBuf:%d "
+			"ctxTag:%d, ctxSeq:%d, tag:%d, seq:%d\n",
+			phba->mbox_ext_buf_ctx.state,
+			phba->mbox_ext_buf_ctx.numBuf,
+			phba->mbox_ext_buf_ctx.mbxTag,
+			phba->mbox_ext_buf_ctx.seqNum,
+			mbox_req->extMboxTag, mbox_req->extSeqNum);
+
+	lpfc_bsg_mbox_ext_session_reset(phba);
+
+	return -EPIPE;
+}
+
+/**
  * 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.
@@ -2636,28 +4118,77 @@
 	LPFC_MBOXQ_t *pmboxq = NULL; /* internal mailbox queue */
 	MAILBOX_t *pmb; /* shortcut to the pmboxq mailbox */
 	/* a 4k buffer to hold the mb and extended data from/to the bsg */
-	MAILBOX_t *mb = NULL;
+	uint8_t *pmbx = NULL;
 	struct bsg_job_data *dd_data = NULL; /* bsg data tracking structure */
-	uint32_t size;
-	struct lpfc_dmabuf *rxbmp = NULL; /* for biu diag */
-	struct lpfc_dmabufext *dmp = NULL; /* for biu diag */
-	struct ulp_bde64 *rxbpl = NULL;
-	struct dfc_mbox_req *mbox_req = (struct dfc_mbox_req *)
-		job->request->rqst_data.h_vendor.vendor_cmd;
+	struct lpfc_dmabuf *dmabuf = NULL;
+	struct dfc_mbox_req *mbox_req;
+	struct READ_EVENT_LOG_VAR *rdEventLog;
+	uint32_t transmit_length, receive_length, mode;
+	struct lpfc_mbx_sli4_config *sli4_config;
+	struct lpfc_mbx_nembed_cmd *nembed_sge;
+	struct mbox_header *header;
+	struct ulp_bde64 *bde;
 	uint8_t *ext = NULL;
 	int rc = 0;
 	uint8_t *from;
+	uint32_t size;
+
 
 	/* in case no data is transferred */
 	job->reply->reply_payload_rcv_len = 0;
 
+	/* sanity check to protect driver */
+	if (job->reply_payload.payload_len > BSG_MBOX_SIZE ||
+	    job->request_payload.payload_len > BSG_MBOX_SIZE) {
+		rc = -ERANGE;
+		goto job_done;
+	}
+
+	/*
+	 * Don't allow mailbox commands to be sent when blocked or when in
+	 * the middle of discovery
+	 */
+	 if (phba->sli.sli_flag & LPFC_BLOCK_MGMT_IO) {
+		rc = -EAGAIN;
+		goto job_done;
+	}
+
+	mbox_req =
+	    (struct dfc_mbox_req *)job->request->rqst_data.h_vendor.vendor_cmd;
+
 	/* check if requested extended data lengths are valid */
-	if ((mbox_req->inExtWLen > MAILBOX_EXT_SIZE) ||
-		(mbox_req->outExtWLen > MAILBOX_EXT_SIZE)) {
+	if ((mbox_req->inExtWLen > BSG_MBOX_SIZE/sizeof(uint32_t)) ||
+	    (mbox_req->outExtWLen > BSG_MBOX_SIZE/sizeof(uint32_t))) {
 		rc = -ERANGE;
 		goto job_done;
 	}
 
+	dmabuf = lpfc_bsg_dma_page_alloc(phba);
+	if (!dmabuf || !dmabuf->virt) {
+		rc = -ENOMEM;
+		goto job_done;
+	}
+
+	/* Get the mailbox command or external buffer from BSG */
+	pmbx = (uint8_t *)dmabuf->virt;
+	size = job->request_payload.payload_len;
+	sg_copy_to_buffer(job->request_payload.sg_list,
+			  job->request_payload.sg_cnt, pmbx, size);
+
+	/* Handle possible SLI_CONFIG with non-embedded payloads */
+	if (phba->sli_rev == LPFC_SLI_REV4) {
+		rc = lpfc_bsg_handle_sli_cfg_ext(phba, job, dmabuf);
+		if (rc == SLI_CONFIG_HANDLED)
+			goto job_cont;
+		if (rc)
+			goto job_done;
+		/* SLI_CONFIG_NOT_HANDLED for other mailbox commands */
+	}
+
+	rc = lpfc_bsg_check_cmd_access(phba, (MAILBOX_t *)pmbx, vport);
+	if (rc != 0)
+		goto job_done; /* must be negative */
+
 	/* allocate our bsg tracking structure */
 	dd_data = kmalloc(sizeof(struct bsg_job_data), GFP_KERNEL);
 	if (!dd_data) {
@@ -2667,12 +4198,6 @@
 		goto job_done;
 	}
 
-	mb = kzalloc(BSG_MBOX_SIZE, GFP_KERNEL);
-	if (!mb) {
-		rc = -ENOMEM;
-		goto job_done;
-	}
-
 	pmboxq = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
 	if (!pmboxq) {
 		rc = -ENOMEM;
@@ -2680,17 +4205,8 @@
 	}
 	memset(pmboxq, 0, sizeof(LPFC_MBOXQ_t));
 
-	size = job->request_payload.payload_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)
-		goto job_done; /* must be negative */
-
 	pmb = &pmboxq->u.mb;
-	memcpy(pmb, mb, sizeof(*pmb));
+	memcpy(pmb, pmbx, sizeof(*pmb));
 	pmb->mbxOwner = OWN_HOST;
 	pmboxq->vport = vport;
 
@@ -2707,30 +4223,13 @@
 				"0x%x while in stopped state.\n",
 				pmb->mbxCommand);
 
-	/* Don't allow mailbox commands to be sent when blocked
-	 * or when in the middle of discovery
-	 */
-	if (phba->sli.sli_flag & LPFC_BLOCK_MGMT_IO) {
-		rc = -EAGAIN;
-		goto job_done;
-	}
-
 	/* extended mailbox commands will need an extended buffer */
 	if (mbox_req->inExtWLen || mbox_req->outExtWLen) {
-		ext = kzalloc(MAILBOX_EXT_SIZE, GFP_KERNEL);
-		if (!ext) {
-			rc = -ENOMEM;
-			goto job_done;
-		}
-
 		/* any data for the device? */
 		if (mbox_req->inExtWLen) {
-			from = (uint8_t *)mb;
-			from += sizeof(MAILBOX_t);
-			memcpy((uint8_t *)ext, from,
-				mbox_req->inExtWLen * sizeof(uint32_t));
+			from = pmbx;
+			ext = from + sizeof(MAILBOX_t);
 		}
-
 		pmboxq->context2 = ext;
 		pmboxq->in_ext_byte_len =
 			mbox_req->inExtWLen * sizeof(uint32_t);
@@ -2744,8 +4243,8 @@
 	 * use ours
 	 */
 	if (pmb->mbxCommand == MBX_RUN_BIU_DIAG64) {
-		uint32_t transmit_length = pmb->un.varWords[1];
-		uint32_t receive_length = pmb->un.varWords[4];
+		transmit_length = pmb->un.varWords[1];
+		receive_length = pmb->un.varWords[4];
 		/* transmit length cannot be greater than receive length or
 		 * mailbox extension size
 		 */
@@ -2754,51 +4253,21 @@
 			rc = -ERANGE;
 			goto job_done;
 		}
-
-		rxbmp = kmalloc(sizeof(struct lpfc_dmabuf), GFP_KERNEL);
-		if (!rxbmp) {
-			rc = -ENOMEM;
-			goto job_done;
-		}
-
-		rxbmp->virt = lpfc_mbuf_alloc(phba, 0, &rxbmp->phys);
-		if (!rxbmp->virt) {
-			rc = -ENOMEM;
-			goto job_done;
-		}
-
-		INIT_LIST_HEAD(&rxbmp->list);
-		rxbpl = (struct ulp_bde64 *) rxbmp->virt;
-		dmp = diag_cmd_data_alloc(phba, rxbpl, transmit_length, 0);
-		if (!dmp) {
-			rc = -ENOMEM;
-			goto job_done;
-		}
-
-		INIT_LIST_HEAD(&dmp->dma.list);
 		pmb->un.varBIUdiag.un.s2.xmit_bde64.addrHigh =
-			putPaddrHigh(dmp->dma.phys);
+			putPaddrHigh(dmabuf->phys + sizeof(MAILBOX_t));
 		pmb->un.varBIUdiag.un.s2.xmit_bde64.addrLow =
-			putPaddrLow(dmp->dma.phys);
+			putPaddrLow(dmabuf->phys + sizeof(MAILBOX_t));
 
 		pmb->un.varBIUdiag.un.s2.rcv_bde64.addrHigh =
-			putPaddrHigh(dmp->dma.phys +
-				pmb->un.varBIUdiag.un.s2.
-					xmit_bde64.tus.f.bdeSize);
+			putPaddrHigh(dmabuf->phys + sizeof(MAILBOX_t)
+			  + pmb->un.varBIUdiag.un.s2.xmit_bde64.tus.f.bdeSize);
 		pmb->un.varBIUdiag.un.s2.rcv_bde64.addrLow =
-			putPaddrLow(dmp->dma.phys +
-				pmb->un.varBIUdiag.un.s2.
-					xmit_bde64.tus.f.bdeSize);
-
-		/* copy the transmit data found in the mailbox extension area */
-		from = (uint8_t *)mb;
-		from += sizeof(MAILBOX_t);
-		memcpy((uint8_t *)dmp->dma.virt, from, transmit_length);
+			putPaddrLow(dmabuf->phys + sizeof(MAILBOX_t)
+			  + pmb->un.varBIUdiag.un.s2.xmit_bde64.tus.f.bdeSize);
 	} else if (pmb->mbxCommand == MBX_READ_EVENT_LOG) {
-		struct READ_EVENT_LOG_VAR *rdEventLog =
-			&pmb->un.varRdEventLog ;
-		uint32_t receive_length = rdEventLog->rcv_bde64.tus.f.bdeSize;
-		uint32_t mode =	 bf_get(lpfc_event_log, rdEventLog);
+		rdEventLog = &pmb->un.varRdEventLog;
+		receive_length = rdEventLog->rcv_bde64.tus.f.bdeSize;
+		mode = bf_get(lpfc_event_log, rdEventLog);
 
 		/* receive length cannot be greater than mailbox
 		 * extension size
@@ -2810,183 +4279,84 @@
 
 		/* mode zero uses a bde like biu diags command */
 		if (mode == 0) {
-
-			/* rebuild the command for sli4 using our own buffers
-			* like we do for biu diags
-			*/
-
-			rxbmp = kmalloc(sizeof(struct lpfc_dmabuf), GFP_KERNEL);
-			if (!rxbmp) {
-				rc = -ENOMEM;
-				goto job_done;
-			}
-
-			rxbmp->virt = lpfc_mbuf_alloc(phba, 0, &rxbmp->phys);
-			rxbpl = (struct ulp_bde64 *) rxbmp->virt;
-			if (rxbpl) {
-				INIT_LIST_HEAD(&rxbmp->list);
-				dmp = diag_cmd_data_alloc(phba, rxbpl,
-					receive_length, 0);
-			}
-
-			if (!dmp) {
-				rc = -ENOMEM;
-				goto job_done;
-			}
-
-			INIT_LIST_HEAD(&dmp->dma.list);
-			pmb->un.varWords[3] = putPaddrLow(dmp->dma.phys);
-			pmb->un.varWords[4] = putPaddrHigh(dmp->dma.phys);
+			pmb->un.varWords[3] = putPaddrLow(dmabuf->phys
+							+ sizeof(MAILBOX_t));
+			pmb->un.varWords[4] = putPaddrHigh(dmabuf->phys
+							+ sizeof(MAILBOX_t));
 		}
 	} else if (phba->sli_rev == LPFC_SLI_REV4) {
 		if (pmb->mbxCommand == MBX_DUMP_MEMORY) {
 			/* rebuild the command for sli4 using our own buffers
 			* like we do for biu diags
 			*/
-			uint32_t receive_length = pmb->un.varWords[2];
+			receive_length = pmb->un.varWords[2];
 			/* receive length cannot be greater than mailbox
 			 * extension size
 			 */
-			if ((receive_length == 0) ||
-				(receive_length > MAILBOX_EXT_SIZE)) {
+			if (receive_length == 0) {
 				rc = -ERANGE;
 				goto job_done;
 			}
-
-			rxbmp = kmalloc(sizeof(struct lpfc_dmabuf), GFP_KERNEL);
-			if (!rxbmp) {
-				rc = -ENOMEM;
-				goto job_done;
-			}
-
-			rxbmp->virt = lpfc_mbuf_alloc(phba, 0, &rxbmp->phys);
-			if (!rxbmp->virt) {
-				rc = -ENOMEM;
-				goto job_done;
-			}
-
-			INIT_LIST_HEAD(&rxbmp->list);
-			rxbpl = (struct ulp_bde64 *) rxbmp->virt;
-			dmp = diag_cmd_data_alloc(phba, rxbpl, receive_length,
-						0);
-			if (!dmp) {
-				rc = -ENOMEM;
-				goto job_done;
-			}
-
-			INIT_LIST_HEAD(&dmp->dma.list);
-			pmb->un.varWords[3] = putPaddrLow(dmp->dma.phys);
-			pmb->un.varWords[4] = putPaddrHigh(dmp->dma.phys);
+			pmb->un.varWords[3] = putPaddrLow(dmabuf->phys
+						+ sizeof(MAILBOX_t));
+			pmb->un.varWords[4] = putPaddrHigh(dmabuf->phys
+						+ sizeof(MAILBOX_t));
 		} else if ((pmb->mbxCommand == MBX_UPDATE_CFG) &&
 			pmb->un.varUpdateCfg.co) {
-			struct ulp_bde64 *bde =
-				(struct ulp_bde64 *)&pmb->un.varWords[4];
+			bde = (struct ulp_bde64 *)&pmb->un.varWords[4];
 
 			/* bde size cannot be greater than mailbox ext size */
 			if (bde->tus.f.bdeSize > MAILBOX_EXT_SIZE) {
 				rc = -ERANGE;
 				goto job_done;
 			}
-
-			rxbmp = kmalloc(sizeof(struct lpfc_dmabuf), GFP_KERNEL);
-			if (!rxbmp) {
-				rc = -ENOMEM;
-				goto job_done;
-			}
-
-			rxbmp->virt = lpfc_mbuf_alloc(phba, 0, &rxbmp->phys);
-			if (!rxbmp->virt) {
-				rc = -ENOMEM;
-				goto job_done;
-			}
-
-			INIT_LIST_HEAD(&rxbmp->list);
-			rxbpl = (struct ulp_bde64 *) rxbmp->virt;
-			dmp = diag_cmd_data_alloc(phba, rxbpl,
-					bde->tus.f.bdeSize, 0);
-			if (!dmp) {
-				rc = -ENOMEM;
-				goto job_done;
-			}
-
-			INIT_LIST_HEAD(&dmp->dma.list);
-			bde->addrHigh = putPaddrHigh(dmp->dma.phys);
-			bde->addrLow = putPaddrLow(dmp->dma.phys);
-
-			/* copy the transmit data found in the mailbox
-			 * extension area
-			 */
-			from = (uint8_t *)mb;
-			from += sizeof(MAILBOX_t);
-			memcpy((uint8_t *)dmp->dma.virt, from,
-				bde->tus.f.bdeSize);
+			bde->addrHigh = putPaddrHigh(dmabuf->phys
+						+ sizeof(MAILBOX_t));
+			bde->addrLow = putPaddrLow(dmabuf->phys
+						+ sizeof(MAILBOX_t));
 		} else if (pmb->mbxCommand == MBX_SLI4_CONFIG) {
-			struct lpfc_mbx_nembed_cmd *nembed_sge;
-			struct mbox_header *header;
-			uint32_t receive_length;
-
-			/* rebuild the command for sli4 using our own buffers
-			* like we do for biu diags
-			*/
-			header = (struct mbox_header *)&pmb->un.varWords[0];
-			nembed_sge = (struct lpfc_mbx_nembed_cmd *)
-				&pmb->un.varWords[0];
-			receive_length = nembed_sge->sge[0].length;
-
-			/* receive length cannot be greater than mailbox
-			 * extension size
-			 */
-			if ((receive_length == 0) ||
-				(receive_length > MAILBOX_EXT_SIZE)) {
-				rc = -ERANGE;
-				goto job_done;
-			}
-
-			rxbmp = kmalloc(sizeof(struct lpfc_dmabuf), GFP_KERNEL);
-			if (!rxbmp) {
-				rc = -ENOMEM;
-				goto job_done;
-			}
+			/* Handling non-embedded SLI_CONFIG mailbox command */
+			sli4_config = &pmboxq->u.mqe.un.sli4_config;
+			if (!bf_get(lpfc_mbox_hdr_emb,
+			    &sli4_config->header.cfg_mhdr)) {
+				/* rebuild the command for sli4 using our
+				 * own buffers like we do for biu diags
+				 */
+				header = (struct mbox_header *)
+						&pmb->un.varWords[0];
+				nembed_sge = (struct lpfc_mbx_nembed_cmd *)
+						&pmb->un.varWords[0];
+				receive_length = nembed_sge->sge[0].length;
 
-			rxbmp->virt = lpfc_mbuf_alloc(phba, 0, &rxbmp->phys);
-			if (!rxbmp->virt) {
-				rc = -ENOMEM;
-				goto job_done;
-			}
+				/* receive length cannot be greater than
+				 * mailbox extension size
+				 */
+				if ((receive_length == 0) ||
+				    (receive_length > MAILBOX_EXT_SIZE)) {
+					rc = -ERANGE;
+					goto job_done;
+				}
 
-			INIT_LIST_HEAD(&rxbmp->list);
-			rxbpl = (struct ulp_bde64 *) rxbmp->virt;
-			dmp = diag_cmd_data_alloc(phba, rxbpl, receive_length,
-						0);
-			if (!dmp) {
-				rc = -ENOMEM;
-				goto job_done;
+				nembed_sge->sge[0].pa_hi =
+						putPaddrHigh(dmabuf->phys
+						   + sizeof(MAILBOX_t));
+				nembed_sge->sge[0].pa_lo =
+						putPaddrLow(dmabuf->phys
+						   + sizeof(MAILBOX_t));
 			}
-
-			INIT_LIST_HEAD(&dmp->dma.list);
-			nembed_sge->sge[0].pa_hi = putPaddrHigh(dmp->dma.phys);
-			nembed_sge->sge[0].pa_lo = putPaddrLow(dmp->dma.phys);
-			/* copy the transmit data found in the mailbox
-			 * extension area
-			 */
-			from = (uint8_t *)mb;
-			from += sizeof(MAILBOX_t);
-			memcpy((uint8_t *)dmp->dma.virt, from,
-				header->cfg_mhdr.payload_length);
 		}
 	}
 
-	dd_data->context_un.mbox.rxbmp = rxbmp;
-	dd_data->context_un.mbox.dmp = dmp;
+	dd_data->context_un.mbox.dmabuffers = dmabuf;
 
 	/* setup wake call as IOCB callback */
-	pmboxq->mbox_cmpl = lpfc_bsg_wake_mbox_wait;
+	pmboxq->mbox_cmpl = lpfc_bsg_issue_mbox_cmpl;
 
 	/* 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.mb = (MAILBOX_t *)pmbx;
 	dd_data->context_un.mbox.set_job = job;
 	dd_data->context_un.mbox.ext = ext;
 	dd_data->context_un.mbox.mbOffset = mbox_req->mbOffset;
@@ -3003,11 +4373,11 @@
 		}
 
 		/* job finished, copy the data */
-		memcpy(mb, pmb, sizeof(*pmb));
+		memcpy(pmbx, 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);
+					    job->reply_payload.sg_cnt,
+					    pmbx, size);
 		/* not waiting mbox already done */
 		rc = 0;
 		goto job_done;
@@ -3019,22 +4389,12 @@
 
 job_done:
 	/* common exit for error or job completed inline */
-	kfree(mb);
 	if (pmboxq)
 		mempool_free(pmboxq, phba->mbox_mem_pool);
-	kfree(ext);
-	if (dmp) {
-		dma_free_coherent(&phba->pcidev->dev,
-			dmp->size, dmp->dma.virt,
-				dmp->dma.phys);
-		kfree(dmp);
-	}
-	if (rxbmp) {
-		lpfc_mbuf_free(phba, rxbmp->virt, rxbmp->phys);
-		kfree(rxbmp);
-	}
+	lpfc_bsg_dma_page_free(phba, dmabuf);
 	kfree(dd_data);
 
+job_cont:
 	return rc;
 }
 
@@ -3047,37 +4407,28 @@
 {
 	struct lpfc_vport *vport = (struct lpfc_vport *)job->shost->hostdata;
 	struct lpfc_hba *phba = vport->phba;
+	struct dfc_mbox_req *mbox_req;
 	int rc = 0;
 
-	/* in case no data is transferred */
+	/* mix-and-match backward compatibility */
 	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 != BSG_MBOX_SIZE) {
-		rc = -EINVAL;
-		goto job_error;
-	}
-
-	if (job->reply_payload.payload_len != BSG_MBOX_SIZE) {
-		rc = -EINVAL;
-		goto job_error;
-	}
-
-	if (phba->sli.sli_flag & LPFC_BLOCK_MGMT_IO) {
-		rc = -EAGAIN;
-		goto job_error;
+		lpfc_printf_log(phba, KERN_INFO, LOG_LIBDFC,
+				"2737 Mix-and-match backward compability "
+				"between MBOX_REQ old size:%d and "
+				"new request size:%d\n",
+				(int)(job->request_len -
+				      sizeof(struct fc_bsg_request)),
+				(int)sizeof(struct dfc_mbox_req));
+		mbox_req = (struct dfc_mbox_req *)
+				job->request->rqst_data.h_vendor.vendor_cmd;
+		mbox_req->extMboxTag = 0;
+		mbox_req->extSeqNum = 0;
 	}
 
 	rc = lpfc_bsg_issue_mbox(phba, job, vport);
 
-job_error:
 	if (rc == 0) {
 		/* job done */
 		job->reply->result = 0;
@@ -3386,6 +4737,7 @@
 	job->dd_data = NULL;
 	return rc;
 }
+
 /**
  * lpfc_bsg_hst_vendor - process a vendor-specific fc_bsg_job
  * @job: fc_bsg_job to handle
@@ -3407,10 +4759,16 @@
 		rc = lpfc_bsg_send_mgmt_rsp(job);
 		break;
 	case LPFC_BSG_VENDOR_DIAG_MODE:
-		rc = lpfc_bsg_diag_mode(job);
+		rc = lpfc_bsg_diag_loopback_mode(job);
 		break;
-	case LPFC_BSG_VENDOR_DIAG_TEST:
-		rc = lpfc_bsg_diag_test(job);
+	case LPFC_BSG_VENDOR_DIAG_MODE_END:
+		rc = lpfc_sli4_bsg_diag_mode_end(job);
+		break;
+	case LPFC_BSG_VENDOR_DIAG_RUN_LOOPBACK:
+		rc = lpfc_bsg_diag_loopback_run(job);
+		break;
+	case LPFC_BSG_VENDOR_LINK_DIAG_TEST:
+		rc = lpfc_sli4_bsg_link_diag_test(job);
 		break;
 	case LPFC_BSG_VENDOR_GET_MGMT_REV:
 		rc = lpfc_bsg_get_dfc_rev(job);
@@ -3529,6 +4887,8 @@
 		/* the mbox completion handler can now be run */
 		spin_unlock_irqrestore(&phba->ct_ev_lock, flags);
 		job->job_done(job);
+		if (phba->mbox_ext_buf_ctx.state == LPFC_BSG_MBOX_PORT)
+			phba->mbox_ext_buf_ctx.state = LPFC_BSG_MBOX_ABTS;
 		break;
 	case TYPE_MENLO:
 		menlo = &dd_data->context_un.menlo;
diff -druN linux-2.6.39-libre/drivers/scsi/lpfc/lpfc_bsg.h linux-3.0-rc7-libre/drivers/scsi/lpfc/lpfc_bsg.h
--- linux-2.6.39-libre/drivers/scsi/lpfc/lpfc_bsg.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/scsi/lpfc/lpfc_bsg.h	2011-07-11 19:51:52.000000000 -0400
@@ -24,15 +24,17 @@
  * 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
+#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_RUN_LOOPBACK	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
+#define LPFC_BSG_VENDOR_DIAG_MODE_END		10
+#define LPFC_BSG_VENDOR_LINK_DIAG_TEST		11
 
 struct set_ct_event {
 	uint32_t command;
@@ -67,10 +69,25 @@
 	uint32_t timeout;
 };
 
+struct sli4_link_diag {
+	uint32_t command;
+	uint32_t timeout;
+	uint32_t test_id;
+	uint32_t loops;
+	uint32_t test_version;
+	uint32_t error_action;
+};
+
 struct diag_mode_test {
 	uint32_t command;
 };
 
+struct diag_status {
+	uint32_t mbox_status;
+	uint32_t shdr_status;
+	uint32_t shdr_add_status;
+};
+
 #define LPFC_WWNN_TYPE		0
 #define LPFC_WWPN_TYPE		1
 
@@ -92,11 +109,15 @@
 };
 
 #define BSG_MBOX_SIZE 4096 /* mailbox command plus extended data */
+
+/* BSG mailbox request header */
 struct dfc_mbox_req {
 	uint32_t command;
 	uint32_t mbOffset;
 	uint32_t inExtWLen;
 	uint32_t outExtWLen;
+	uint32_t extMboxTag;
+	uint32_t extSeqNum;
 };
 
 /* Used for menlo command or menlo data. The xri is only used for menlo data */
@@ -109,3 +130,155 @@
 	uint32_t xri; /* return the xri of the iocb exchange */
 };
 
+/*
+ * macros and data structures for handling sli-config mailbox command
+ * pass-through support, this header file is shared between user and
+ * kernel spaces, note the set of macros are duplicates from lpfc_hw4.h,
+ * with macro names prefixed with bsg_, as the macros defined in
+ * lpfc_hw4.h are not accessible from user space.
+ */
+
+/* Macros to deal with bit fields. Each bit field must have 3 #defines
+ * associated with it (_SHIFT, _MASK, and _WORD).
+ * EG. For a bit field that is in the 7th bit of the "field4" field of a
+ * structure and is 2 bits in size the following #defines must exist:
+ *      struct temp {
+ *              uint32_t        field1;
+ *              uint32_t        field2;
+ *              uint32_t        field3;
+ *              uint32_t        field4;
+ *      #define example_bit_field_SHIFT         7
+ *      #define example_bit_field_MASK          0x03
+ *      #define example_bit_field_WORD          field4
+ *              uint32_t        field5;
+ *      };
+ * Then the macros below may be used to get or set the value of that field.
+ * EG. To get the value of the bit field from the above example:
+ *      struct temp t1;
+ *      value = bsg_bf_get(example_bit_field, &t1);
+ * And then to set that bit field:
+ *      bsg_bf_set(example_bit_field, &t1, 2);
+ * Or clear that bit field:
+ *      bsg_bf_set(example_bit_field, &t1, 0);
+ */
+#define bsg_bf_get_le32(name, ptr) \
+	((le32_to_cpu((ptr)->name##_WORD) >> name##_SHIFT) & name##_MASK)
+#define bsg_bf_get(name, ptr) \
+	(((ptr)->name##_WORD >> name##_SHIFT) & name##_MASK)
+#define bsg_bf_set_le32(name, ptr, value) \
+	((ptr)->name##_WORD = cpu_to_le32(((((value) & \
+	name##_MASK) << name##_SHIFT) | (le32_to_cpu((ptr)->name##_WORD) & \
+	~(name##_MASK << name##_SHIFT)))))
+#define bsg_bf_set(name, ptr, value) \
+	((ptr)->name##_WORD = ((((value) & name##_MASK) << name##_SHIFT) | \
+	((ptr)->name##_WORD & ~(name##_MASK << name##_SHIFT))))
+
+/*
+ * The sli_config structure specified here is based on the following
+ * restriction:
+ *
+ * -- SLI_CONFIG EMB=0, carrying MSEs, will carry subcommands without
+ *    carrying HBD.
+ * -- SLI_CONFIG EMB=1, not carrying MSE, will carry subcommands with or
+ *    without carrying HBDs.
+ */
+
+struct lpfc_sli_config_mse {
+	uint32_t pa_lo;
+	uint32_t pa_hi;
+	uint32_t buf_len;
+#define lpfc_mbox_sli_config_mse_len_SHIFT	0
+#define lpfc_mbox_sli_config_mse_len_MASK	0xffffff
+#define lpfc_mbox_sli_config_mse_len_WORD	buf_len
+};
+
+struct lpfc_sli_config_hbd {
+	uint32_t buf_len;
+#define lpfc_mbox_sli_config_ecmn_hbd_len_SHIFT	0
+#define lpfc_mbox_sli_config_ecmn_hbd_len_MASK	0xffffff
+#define lpfc_mbox_sli_config_ecmn_hbd_len_WORD	buf_len
+	uint32_t pa_lo;
+	uint32_t pa_hi;
+};
+
+struct lpfc_sli_config_hdr {
+	uint32_t word1;
+#define lpfc_mbox_hdr_emb_SHIFT		0
+#define lpfc_mbox_hdr_emb_MASK		0x00000001
+#define lpfc_mbox_hdr_emb_WORD		word1
+#define lpfc_mbox_hdr_mse_cnt_SHIFT	3
+#define lpfc_mbox_hdr_mse_cnt_MASK	0x0000001f
+#define lpfc_mbox_hdr_mse_cnt_WORD	word1
+	uint32_t payload_length;
+	uint32_t tag_lo;
+	uint32_t tag_hi;
+	uint32_t reserved5;
+};
+
+struct lpfc_sli_config_emb0_subsys {
+	struct lpfc_sli_config_hdr	sli_config_hdr;
+#define LPFC_MBX_SLI_CONFIG_MAX_MSE     19
+	struct lpfc_sli_config_mse	mse[LPFC_MBX_SLI_CONFIG_MAX_MSE];
+	uint32_t padding;
+	uint32_t word64;
+#define lpfc_emb0_subcmnd_opcode_SHIFT	0
+#define lpfc_emb0_subcmnd_opcode_MASK	0xff
+#define lpfc_emb0_subcmnd_opcode_WORD	word64
+#define lpfc_emb0_subcmnd_subsys_SHIFT	8
+#define lpfc_emb0_subcmnd_subsys_MASK	0xff
+#define lpfc_emb0_subcmnd_subsys_WORD	word64
+/* Subsystem FCOE (0x0C) OpCodes */
+#define SLI_CONFIG_SUBSYS_FCOE		0x0C
+#define FCOE_OPCODE_READ_FCF		0x08
+#define FCOE_OPCODE_ADD_FCF		0x09
+};
+
+struct lpfc_sli_config_emb1_subsys {
+	struct lpfc_sli_config_hdr	sli_config_hdr;
+	uint32_t word6;
+#define lpfc_emb1_subcmnd_opcode_SHIFT	0
+#define lpfc_emb1_subcmnd_opcode_MASK	0xff
+#define lpfc_emb1_subcmnd_opcode_WORD	word6
+#define lpfc_emb1_subcmnd_subsys_SHIFT	8
+#define lpfc_emb1_subcmnd_subsys_MASK	0xff
+#define lpfc_emb1_subcmnd_subsys_WORD	word6
+/* Subsystem COMN (0x01) OpCodes */
+#define SLI_CONFIG_SUBSYS_COMN		0x01
+#define COMN_OPCODE_READ_OBJECT		0xAB
+#define COMN_OPCODE_WRITE_OBJECT	0xAC
+#define COMN_OPCODE_READ_OBJECT_LIST	0xAD
+#define COMN_OPCODE_DELETE_OBJECT	0xAE
+	uint32_t timeout;
+	uint32_t request_length;
+	uint32_t word9;
+#define lpfc_subcmnd_version_SHIFT	0
+#define lpfc_subcmnd_version_MASK	0xff
+#define lpfc_subcmnd_version_WORD	word9
+	uint32_t word10;
+#define lpfc_subcmnd_ask_rd_len_SHIFT	0
+#define lpfc_subcmnd_ask_rd_len_MASK	0xffffff
+#define lpfc_subcmnd_ask_rd_len_WORD	word10
+	uint32_t rd_offset;
+	uint32_t obj_name[26];
+	uint32_t hbd_count;
+#define LPFC_MBX_SLI_CONFIG_MAX_HBD	8
+	struct lpfc_sli_config_hbd	hbd[LPFC_MBX_SLI_CONFIG_MAX_HBD];
+};
+
+struct lpfc_sli_config_mbox {
+	uint32_t word0;
+#define lpfc_mqe_status_SHIFT		16
+#define lpfc_mqe_status_MASK		0x0000FFFF
+#define lpfc_mqe_status_WORD		word0
+#define lpfc_mqe_command_SHIFT		8
+#define lpfc_mqe_command_MASK		0x000000FF
+#define lpfc_mqe_command_WORD		word0
+	union {
+		struct lpfc_sli_config_emb0_subsys sli_config_emb0_subsys;
+		struct lpfc_sli_config_emb1_subsys sli_config_emb1_subsys;
+	} un;
+};
+
+/* driver only */
+#define SLI_CONFIG_NOT_HANDLED		0
+#define SLI_CONFIG_HANDLED		1
diff -druN linux-2.6.39-libre/drivers/scsi/lpfc/lpfc_crtn.h linux-3.0-rc7-libre/drivers/scsi/lpfc/lpfc_crtn.h
--- linux-2.6.39-libre/drivers/scsi/lpfc/lpfc_crtn.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/scsi/lpfc/lpfc_crtn.h	2011-07-11 19:51:52.000000000 -0400
@@ -55,6 +55,8 @@
 void lpfc_supported_pages(struct lpfcMboxq *);
 void lpfc_pc_sli4_params(struct lpfcMboxq *);
 int lpfc_pc_sli4_params_get(struct lpfc_hba *, LPFC_MBOXQ_t *);
+int lpfc_sli4_mbox_rsrc_extent(struct lpfc_hba *, struct lpfcMboxq *,
+			   uint16_t, uint16_t, bool);
 int lpfc_get_sli4_parameters(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 *);
@@ -171,6 +173,7 @@
 void lpfc_delayed_disc_timeout_handler(struct lpfc_vport *);
 
 int lpfc_config_port_prep(struct lpfc_hba *);
+void lpfc_update_vport_wwn(struct lpfc_vport *vport);
 int lpfc_config_port_post(struct lpfc_hba *);
 int lpfc_hba_down_prep(struct lpfc_hba *);
 int lpfc_hba_down_post(struct lpfc_hba *);
@@ -365,6 +368,10 @@
 	uint32_t, uint32_t);
 extern struct lpfc_hbq_init *lpfc_hbq_defs[];
 
+/* SLI4 if_type 2 externs. */
+int lpfc_sli4_alloc_resource_identifiers(struct lpfc_hba *);
+int lpfc_sli4_dealloc_resource_identifiers(struct lpfc_hba *);
+
 /* externs BlockGuard */
 extern char *_dump_buf_data;
 extern unsigned long _dump_buf_data_order;
@@ -429,3 +436,6 @@
 void lpfc_cleanup_vports_rrqs(struct lpfc_vport *, struct lpfc_nodelist *);
 struct lpfc_node_rrq *lpfc_get_active_rrq(struct lpfc_vport *, uint16_t,
 	uint32_t);
+int lpfc_wr_object(struct lpfc_hba *, struct list_head *, uint32_t, uint32_t *);
+/* functions to support SR-IOV */
+int lpfc_sli_probe_sriov_nr_virtfn(struct lpfc_hba *, int);
diff -druN linux-2.6.39-libre/drivers/scsi/lpfc/lpfc_ct.c linux-3.0-rc7-libre/drivers/scsi/lpfc/lpfc_ct.c
--- linux-2.6.39-libre/drivers/scsi/lpfc/lpfc_ct.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/scsi/lpfc/lpfc_ct.c	2011-07-11 19:51:52.000000000 -0400
@@ -352,6 +352,8 @@
 	icmd->ulpLe = 1;
 	icmd->ulpClass = CLASS3;
 	icmd->ulpContext = ndlp->nlp_rpi;
+	if (phba->sli_rev == LPFC_SLI_REV4)
+		icmd->ulpContext = phba->sli4_hba.rpi_ids[ndlp->nlp_rpi];
 
 	if (phba->sli3_options & LPFC_SLI3_NPIV_ENABLED) {
 		/* For GEN_REQUEST64_CR, use the RPI */
diff -druN linux-2.6.39-libre/drivers/scsi/lpfc/lpfc_debugfs.c linux-3.0-rc7-libre/drivers/scsi/lpfc/lpfc_debugfs.c
--- linux-2.6.39-libre/drivers/scsi/lpfc/lpfc_debugfs.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/scsi/lpfc/lpfc_debugfs.c	2011-07-11 19:51:52.000000000 -0400
@@ -1119,172 +1119,14 @@
 }
 
 /*
+ * ---------------------------------
  * iDiag debugfs file access methods
- */
-
-/*
- * iDiag PCI config space register access methods:
- *
- * The PCI config space register accessees of read, write, read-modify-write
- * for set bits, and read-modify-write for clear bits to SLI4 PCI functions
- * are provided. In the proper SLI4 PCI function's debugfs iDiag directory,
- *
- *      /sys/kernel/debug/lpfc/fn<#>/iDiag
- *
- * the access is through the debugfs entry pciCfg:
- *
- * 1. For PCI config space register read access, there are two read methods:
- *    A) read a single PCI config space register in the size of a byte
- *    (8 bits), a word (16 bits), or a dword (32 bits); or B) browse through
- *    the 4K extended PCI config space.
- *
- *    A) Read a single PCI config space register consists of two steps:
- *
- *    Step-1: Set up PCI config space register read command, the command
- *    syntax is,
- *
- *        echo 1 <where> <count> > pciCfg
- *
- *    where, 1 is the iDiag command for PCI config space read, <where> is the
- *    offset from the beginning of the device's PCI config space to read from,
- *    and <count> is the size of PCI config space register data to read back,
- *    it will be 1 for reading a byte (8 bits), 2 for reading a word (16 bits
- *    or 2 bytes), or 4 for reading a dword (32 bits or 4 bytes).
- *
- *    Setp-2: Perform the debugfs read operation to execute the idiag command
- *    set up in Step-1,
- *
- *        cat pciCfg
- *
- *    Examples:
- *    To read PCI device's vendor-id and device-id from PCI config space,
- *
- *        echo 1 0 4 > pciCfg
- *        cat pciCfg
- *
- *    To read PCI device's currnt command from config space,
- *
- *        echo 1 4 2 > pciCfg
- *        cat pciCfg
- *
- *    B) Browse through the entire 4K extended PCI config space also consists
- *    of two steps:
- *
- *    Step-1: Set up PCI config space register browsing command, the command
- *    syntax is,
- *
- *        echo 1 0 4096 > pciCfg
- *
- *    where, 1 is the iDiag command for PCI config space read, 0 must be used
- *    as the offset for PCI config space register browse, and 4096 must be
- *    used as the count for PCI config space register browse.
- *
- *    Step-2: Repeately issue the debugfs read operation to browse through
- *    the entire PCI config space registers:
- *
- *        cat pciCfg
- *        cat pciCfg
- *        cat pciCfg
- *        ...
- *
- *    When browsing to the end of the 4K PCI config space, the browse method
- *    shall wrap around to start reading from beginning again, and again...
- *
- * 2. For PCI config space register write access, it supports a single PCI
- *    config space register write in the size of a byte (8 bits), a word
- *    (16 bits), or a dword (32 bits). The command syntax is,
- *
- *        echo 2 <where> <count> <value> > pciCfg
- *
- *    where, 2 is the iDiag command for PCI config space write, <where> is
- *    the offset from the beginning of the device's PCI config space to write
- *    into, <count> is the size of data to write into the PCI config space,
- *    it will be 1 for writing a byte (8 bits), 2 for writing a word (16 bits
- *    or 2 bytes), or 4 for writing a dword (32 bits or 4 bytes), and <value>
- *    is the data to be written into the PCI config space register at the
- *    offset.
- *
- *    Examples:
- *    To disable PCI device's interrupt assertion,
- *
- *    1) Read in device's PCI config space register command field <cmd>:
- *
- *           echo 1 4 2 > pciCfg
- *           cat pciCfg
- *
- *    2) Set bit 10 (Interrupt Disable bit) in the <cmd>:
- *
- *           <cmd> = <cmd> | (1 < 10)
- *
- *    3) Write the modified command back:
- *
- *           echo 2 4 2 <cmd> > pciCfg
- *
- * 3. For PCI config space register set bits access, it supports a single PCI
- *    config space register set bits in the size of a byte (8 bits), a word
- *    (16 bits), or a dword (32 bits). The command syntax is,
- *
- *        echo 3 <where> <count> <bitmask> > pciCfg
- *
- *    where, 3 is the iDiag command for PCI config space set bits, <where> is
- *    the offset from the beginning of the device's PCI config space to set
- *    bits into, <count> is the size of the bitmask to set into the PCI config
- *    space, it will be 1 for setting a byte (8 bits), 2 for setting a word
- *    (16 bits or 2 bytes), or 4 for setting a dword (32 bits or 4 bytes), and
- *    <bitmask> is the bitmask, indicating the bits to be set into the PCI
- *    config space register at the offset. The logic performed to the content
- *    of the PCI config space register, regval, is,
- *
- *        regval |= <bitmask>
- *
- * 4. For PCI config space register clear bits access, it supports a single
- *    PCI config space register clear bits in the size of a byte (8 bits),
- *    a word (16 bits), or a dword (32 bits). The command syntax is,
- *
- *        echo 4 <where> <count> <bitmask> > pciCfg
- *
- *    where, 4 is the iDiag command for PCI config space clear bits, <where>
- *    is the offset from the beginning of the device's PCI config space to
- *    clear bits from, <count> is the size of the bitmask to set into the PCI
- *    config space, it will be 1 for setting a byte (8 bits), 2 for setting
- *    a word(16 bits or 2 bytes), or 4 for setting a dword (32 bits or 4
- *    bytes), and <bitmask> is the bitmask, indicating the bits to be cleared
- *    from the PCI config space register at the offset. the logic performed
- *    to the content of the PCI config space register, regval, is,
- *
- *        regval &= ~<bitmask>
- *
- * Note, for all single register read, write, set bits, or clear bits access,
- * the offset (<where>) must be aligned with the size of the data:
- *
- * For data size of byte (8 bits), the offset must be aligned to the byte
- * boundary; for data size of word (16 bits), the offset must be aligned
- * to the word boundary; while for data size of dword (32 bits), the offset
- * must be aligned to the dword boundary. Otherwise, the interface will
- * return the error:
- *
- *     "-bash: echo: write error: Invalid argument".
- *
- * For example:
- *
- *     echo 1 2 4 > pciCfg
- *     -bash: echo: write error: Invalid argument
- *
- * Note also, all of the numbers in the command fields for all read, write,
- * set bits, and clear bits PCI config space register command fields can be
- * either decimal or hex.
- *
- * For example,
- *     echo 1 0 4096 > pciCfg
- *
- * will be the same as
- *     echo 1 0 0x1000 > pciCfg
+ * ---------------------------------
  *
- * And,
- *     echo 2 155 1 10 > pciCfg
+ * All access methods are through the proper SLI4 PCI function's debugfs
+ * iDiag directory:
  *
- * will be
- *     echo 2 0x9b 1 0xa > pciCfg
+ *     /sys/kernel/debug/lpfc/fn<#>/iDiag
  */
 
 /**
@@ -1331,10 +1173,10 @@
 	for (i = 0; i < LPFC_IDIAG_CMD_DATA_SIZE; i++) {
 		step_str = strsep(&pbuf, "\t ");
 		if (!step_str)
-			return 0;
+			return i;
 		idiag_cmd->data[i] = simple_strtol(step_str, NULL, 0);
 	}
-	return 0;
+	return i;
 }
 
 /**
@@ -1403,7 +1245,7 @@
  * Description:
  * This routine frees the buffer that was allocated when the debugfs file
  * was opened. It also reset the fields in the idiag command struct in the
- * case the command is not continuous browsing of the data structure.
+ * case of command for write operation.
  *
  * Returns:
  * This function returns zero.
@@ -1413,18 +1255,20 @@
 {
 	struct lpfc_debug *debug = file->private_data;
 
-	/* Read PCI config register, if not read all, clear command fields */
-	if ((debug->op == LPFC_IDIAG_OP_RD) &&
-	    (idiag.cmd.opcode == LPFC_IDIAG_CMD_PCICFG_RD))
-		if ((idiag.cmd.data[1] == sizeof(uint8_t)) ||
-		    (idiag.cmd.data[1] == sizeof(uint16_t)) ||
-		    (idiag.cmd.data[1] == sizeof(uint32_t)))
+	if (debug->op == LPFC_IDIAG_OP_WR) {
+		switch (idiag.cmd.opcode) {
+		case LPFC_IDIAG_CMD_PCICFG_WR:
+		case LPFC_IDIAG_CMD_PCICFG_ST:
+		case LPFC_IDIAG_CMD_PCICFG_CL:
+		case LPFC_IDIAG_CMD_QUEACC_WR:
+		case LPFC_IDIAG_CMD_QUEACC_ST:
+		case LPFC_IDIAG_CMD_QUEACC_CL:
 			memset(&idiag, 0, sizeof(idiag));
-
-	/* Write PCI config register, clear command fields */
-	if ((debug->op == LPFC_IDIAG_OP_WR) &&
-	    (idiag.cmd.opcode == LPFC_IDIAG_CMD_PCICFG_WR))
-		memset(&idiag, 0, sizeof(idiag));
+			break;
+		default:
+			break;
+		}
+	}
 
 	/* Free the buffers to the file operation */
 	kfree(debug->buffer);
@@ -1504,7 +1348,7 @@
 		len += snprintf(pbuffer+len, LPFC_PCI_CFG_SIZE-len,
 				"%03x: %08x\n", where, u32val);
 		break;
-	case LPFC_PCI_CFG_SIZE: /* browse all */
+	case LPFC_PCI_CFG_BROWSE: /* browse all */
 		goto pcicfg_browse;
 		break;
 	default:
@@ -1586,16 +1430,21 @@
 	debug->op = LPFC_IDIAG_OP_WR;
 
 	rc = lpfc_idiag_cmd_get(buf, nbytes, &idiag.cmd);
-	if (rc)
+	if (rc < 0)
 		return rc;
 
 	if (idiag.cmd.opcode == LPFC_IDIAG_CMD_PCICFG_RD) {
+		/* Sanity check on PCI config read command line arguments */
+		if (rc != LPFC_PCI_CFG_RD_CMD_ARG)
+			goto error_out;
 		/* Read command from PCI config space, set up command fields */
 		where = idiag.cmd.data[0];
 		count = idiag.cmd.data[1];
-		if (count == LPFC_PCI_CFG_SIZE) {
-			if (where != 0)
+		if (count == LPFC_PCI_CFG_BROWSE) {
+			if (where % sizeof(uint32_t))
 				goto error_out;
+			/* Starting offset to browse */
+			idiag.offset.last_rd = where;
 		} else if ((count != sizeof(uint8_t)) &&
 			   (count != sizeof(uint16_t)) &&
 			   (count != sizeof(uint32_t)))
@@ -1621,6 +1470,9 @@
 	} else if (idiag.cmd.opcode == LPFC_IDIAG_CMD_PCICFG_WR ||
 		   idiag.cmd.opcode == LPFC_IDIAG_CMD_PCICFG_ST ||
 		   idiag.cmd.opcode == LPFC_IDIAG_CMD_PCICFG_CL) {
+		/* Sanity check on PCI config write command line arguments */
+		if (rc != LPFC_PCI_CFG_WR_CMD_ARG)
+			goto error_out;
 		/* Write command to PCI config space, read-modify-write */
 		where = idiag.cmd.data[0];
 		count = idiag.cmd.data[1];
@@ -1753,10 +1605,12 @@
 	len += snprintf(pbuffer+len, LPFC_QUE_INFO_GET_BUF_SIZE-len,
 			"Slow-path EQ information:\n");
 	len += snprintf(pbuffer+len, LPFC_QUE_INFO_GET_BUF_SIZE-len,
-			"\tID [%02d], EQE-COUNT [%04d], "
-			"HOST-INDEX [%04x], PORT-INDEX [%04x]\n\n",
+			"\tEQID[%02d], "
+			"QE-COUNT[%04d], QE-SIZE[%04d], "
+			"HOST-INDEX[%04d], PORT-INDEX[%04d]\n\n",
 			phba->sli4_hba.sp_eq->queue_id,
 			phba->sli4_hba.sp_eq->entry_count,
+			phba->sli4_hba.sp_eq->entry_size,
 			phba->sli4_hba.sp_eq->host_index,
 			phba->sli4_hba.sp_eq->hba_index);
 
@@ -1765,10 +1619,12 @@
 			"Fast-path EQ information:\n");
 	for (fcp_qidx = 0; fcp_qidx < phba->cfg_fcp_eq_count; fcp_qidx++) {
 		len += snprintf(pbuffer+len, LPFC_QUE_INFO_GET_BUF_SIZE-len,
-				"\tID [%02d], EQE-COUNT [%04d], "
-				"HOST-INDEX [%04x], PORT-INDEX [%04x]\n",
+				"\tEQID[%02d], "
+				"QE-COUNT[%04d], QE-SIZE[%04d], "
+				"HOST-INDEX[%04d], PORT-INDEX[%04d]\n",
 				phba->sli4_hba.fp_eq[fcp_qidx]->queue_id,
 				phba->sli4_hba.fp_eq[fcp_qidx]->entry_count,
+				phba->sli4_hba.fp_eq[fcp_qidx]->entry_size,
 				phba->sli4_hba.fp_eq[fcp_qidx]->host_index,
 				phba->sli4_hba.fp_eq[fcp_qidx]->hba_index);
 	}
@@ -1776,89 +1632,102 @@
 
 	/* Get mailbox complete queue information */
 	len += snprintf(pbuffer+len, LPFC_QUE_INFO_GET_BUF_SIZE-len,
-			"Mailbox CQ information:\n");
+			"Slow-path MBX CQ information:\n");
 	len += snprintf(pbuffer+len, LPFC_QUE_INFO_GET_BUF_SIZE-len,
-			"\t\tAssociated EQ-ID [%02d]:\n",
+			"Associated EQID[%02d]:\n",
 			phba->sli4_hba.mbx_cq->assoc_qid);
 	len += snprintf(pbuffer+len, LPFC_QUE_INFO_GET_BUF_SIZE-len,
-			"\tID [%02d], CQE-COUNT [%04d], "
-			"HOST-INDEX [%04x], PORT-INDEX [%04x]\n\n",
+			"\tCQID[%02d], "
+			"QE-COUNT[%04d], QE-SIZE[%04d], "
+			"HOST-INDEX[%04d], PORT-INDEX[%04d]\n\n",
 			phba->sli4_hba.mbx_cq->queue_id,
 			phba->sli4_hba.mbx_cq->entry_count,
+			phba->sli4_hba.mbx_cq->entry_size,
 			phba->sli4_hba.mbx_cq->host_index,
 			phba->sli4_hba.mbx_cq->hba_index);
 
 	/* Get slow-path complete queue information */
 	len += snprintf(pbuffer+len, LPFC_QUE_INFO_GET_BUF_SIZE-len,
-			"Slow-path CQ information:\n");
+			"Slow-path ELS CQ information:\n");
 	len += snprintf(pbuffer+len, LPFC_QUE_INFO_GET_BUF_SIZE-len,
-			"\t\tAssociated EQ-ID [%02d]:\n",
+			"Associated EQID[%02d]:\n",
 			phba->sli4_hba.els_cq->assoc_qid);
 	len += snprintf(pbuffer+len, LPFC_QUE_INFO_GET_BUF_SIZE-len,
-			"\tID [%02d], CQE-COUNT [%04d], "
-			"HOST-INDEX [%04x], PORT-INDEX [%04x]\n\n",
+			"\tCQID [%02d], "
+			"QE-COUNT[%04d], QE-SIZE[%04d], "
+			"HOST-INDEX[%04d], PORT-INDEX[%04d]\n\n",
 			phba->sli4_hba.els_cq->queue_id,
 			phba->sli4_hba.els_cq->entry_count,
+			phba->sli4_hba.els_cq->entry_size,
 			phba->sli4_hba.els_cq->host_index,
 			phba->sli4_hba.els_cq->hba_index);
 
 	/* Get fast-path complete queue information */
 	len += snprintf(pbuffer+len, LPFC_QUE_INFO_GET_BUF_SIZE-len,
-			"Fast-path CQ information:\n");
-	for (fcp_qidx = 0; fcp_qidx < phba->cfg_fcp_eq_count; fcp_qidx++) {
+			"Fast-path FCP CQ information:\n");
+	fcp_qidx = 0;
+	do {
 		len += snprintf(pbuffer+len, LPFC_QUE_INFO_GET_BUF_SIZE-len,
-				"\t\tAssociated EQ-ID [%02d]:\n",
+				"Associated EQID[%02d]:\n",
 				phba->sli4_hba.fcp_cq[fcp_qidx]->assoc_qid);
 		len += snprintf(pbuffer+len, LPFC_QUE_INFO_GET_BUF_SIZE-len,
-		"\tID [%02d], EQE-COUNT [%04d], "
-		"HOST-INDEX [%04x], PORT-INDEX [%04x]\n",
-		phba->sli4_hba.fcp_cq[fcp_qidx]->queue_id,
-		phba->sli4_hba.fcp_cq[fcp_qidx]->entry_count,
-		phba->sli4_hba.fcp_cq[fcp_qidx]->host_index,
-		phba->sli4_hba.fcp_cq[fcp_qidx]->hba_index);
-	}
+				"\tCQID[%02d], "
+				"QE-COUNT[%04d], QE-SIZE[%04d], "
+				"HOST-INDEX[%04d], PORT-INDEX[%04d]\n",
+				phba->sli4_hba.fcp_cq[fcp_qidx]->queue_id,
+				phba->sli4_hba.fcp_cq[fcp_qidx]->entry_count,
+				phba->sli4_hba.fcp_cq[fcp_qidx]->entry_size,
+				phba->sli4_hba.fcp_cq[fcp_qidx]->host_index,
+				phba->sli4_hba.fcp_cq[fcp_qidx]->hba_index);
+	} while (++fcp_qidx < phba->cfg_fcp_eq_count);
 	len += snprintf(pbuffer+len, LPFC_QUE_INFO_GET_BUF_SIZE-len, "\n");
 
 	/* Get mailbox queue information */
 	len += snprintf(pbuffer+len, LPFC_QUE_INFO_GET_BUF_SIZE-len,
-			"Mailbox MQ information:\n");
+			"Slow-path MBX MQ information:\n");
 	len += snprintf(pbuffer+len, LPFC_QUE_INFO_GET_BUF_SIZE-len,
-			"\t\tAssociated CQ-ID [%02d]:\n",
+			"Associated CQID[%02d]:\n",
 			phba->sli4_hba.mbx_wq->assoc_qid);
 	len += snprintf(pbuffer+len, LPFC_QUE_INFO_GET_BUF_SIZE-len,
-			"\tID [%02d], MQE-COUNT [%04d], "
-			"HOST-INDEX [%04x], PORT-INDEX [%04x]\n\n",
+			"\tWQID[%02d], "
+			"QE-COUNT[%04d], QE-SIZE[%04d], "
+			"HOST-INDEX[%04d], PORT-INDEX[%04d]\n\n",
 			phba->sli4_hba.mbx_wq->queue_id,
 			phba->sli4_hba.mbx_wq->entry_count,
+			phba->sli4_hba.mbx_wq->entry_size,
 			phba->sli4_hba.mbx_wq->host_index,
 			phba->sli4_hba.mbx_wq->hba_index);
 
 	/* Get slow-path work queue information */
 	len += snprintf(pbuffer+len, LPFC_QUE_INFO_GET_BUF_SIZE-len,
-			"Slow-path WQ information:\n");
+			"Slow-path ELS WQ information:\n");
 	len += snprintf(pbuffer+len, LPFC_QUE_INFO_GET_BUF_SIZE-len,
-			"\t\tAssociated CQ-ID [%02d]:\n",
+			"Associated CQID[%02d]:\n",
 			phba->sli4_hba.els_wq->assoc_qid);
 	len += snprintf(pbuffer+len, LPFC_QUE_INFO_GET_BUF_SIZE-len,
-			"\tID [%02d], WQE-COUNT [%04d], "
-			"HOST-INDEX [%04x], PORT-INDEX [%04x]\n\n",
+			"\tWQID[%02d], "
+			"QE-COUNT[%04d], QE-SIZE[%04d], "
+			"HOST-INDEX[%04d], PORT-INDEX[%04d]\n\n",
 			phba->sli4_hba.els_wq->queue_id,
 			phba->sli4_hba.els_wq->entry_count,
+			phba->sli4_hba.els_wq->entry_size,
 			phba->sli4_hba.els_wq->host_index,
 			phba->sli4_hba.els_wq->hba_index);
 
 	/* Get fast-path work queue information */
 	len += snprintf(pbuffer+len, LPFC_QUE_INFO_GET_BUF_SIZE-len,
-			"Fast-path WQ information:\n");
+			"Fast-path FCP WQ information:\n");
 	for (fcp_qidx = 0; fcp_qidx < phba->cfg_fcp_wq_count; fcp_qidx++) {
 		len += snprintf(pbuffer+len, LPFC_QUE_INFO_GET_BUF_SIZE-len,
-				"\t\tAssociated CQ-ID [%02d]:\n",
+				"Associated CQID[%02d]:\n",
 				phba->sli4_hba.fcp_wq[fcp_qidx]->assoc_qid);
 		len += snprintf(pbuffer+len, LPFC_QUE_INFO_GET_BUF_SIZE-len,
-				"\tID [%02d], WQE-COUNT [%04d], "
-				"HOST-INDEX [%04x], PORT-INDEX [%04x]\n",
+				"\tWQID[%02d], "
+				"QE-COUNT[%04d], WQE-SIZE[%04d], "
+				"HOST-INDEX[%04d], PORT-INDEX[%04d]\n",
 				phba->sli4_hba.fcp_wq[fcp_qidx]->queue_id,
 				phba->sli4_hba.fcp_wq[fcp_qidx]->entry_count,
+				phba->sli4_hba.fcp_wq[fcp_qidx]->entry_size,
 				phba->sli4_hba.fcp_wq[fcp_qidx]->host_index,
 				phba->sli4_hba.fcp_wq[fcp_qidx]->hba_index);
 	}
@@ -1868,26 +1737,598 @@
 	len += snprintf(pbuffer+len, LPFC_QUE_INFO_GET_BUF_SIZE-len,
 			"Slow-path RQ information:\n");
 	len += snprintf(pbuffer+len, LPFC_QUE_INFO_GET_BUF_SIZE-len,
-			"\t\tAssociated CQ-ID [%02d]:\n",
+			"Associated CQID[%02d]:\n",
 			phba->sli4_hba.hdr_rq->assoc_qid);
 	len += snprintf(pbuffer+len, LPFC_QUE_INFO_GET_BUF_SIZE-len,
-			"\tID [%02d], RHQE-COUNT [%04d], "
-			"HOST-INDEX [%04x], PORT-INDEX [%04x]\n",
+			"\tHQID[%02d], "
+			"QE-COUNT[%04d], QE-SIZE[%04d], "
+			"HOST-INDEX[%04d], PORT-INDEX[%04d]\n",
 			phba->sli4_hba.hdr_rq->queue_id,
 			phba->sli4_hba.hdr_rq->entry_count,
+			phba->sli4_hba.hdr_rq->entry_size,
 			phba->sli4_hba.hdr_rq->host_index,
 			phba->sli4_hba.hdr_rq->hba_index);
 	len += snprintf(pbuffer+len, LPFC_QUE_INFO_GET_BUF_SIZE-len,
-			"\tID [%02d], RDQE-COUNT [%04d], "
-			"HOST-INDEX [%04x], PORT-INDEX [%04x]\n",
+			"\tDQID[%02d], "
+			"QE-COUNT[%04d], QE-SIZE[%04d], "
+			"HOST-INDEX[%04d], PORT-INDEX[%04d]\n",
 			phba->sli4_hba.dat_rq->queue_id,
 			phba->sli4_hba.dat_rq->entry_count,
+			phba->sli4_hba.dat_rq->entry_size,
 			phba->sli4_hba.dat_rq->host_index,
 			phba->sli4_hba.dat_rq->hba_index);
 
 	return simple_read_from_buffer(buf, nbytes, ppos, pbuffer, len);
 }
 
+/**
+ * lpfc_idiag_que_param_check - queue access command parameter sanity check
+ * @q: The pointer to queue structure.
+ * @index: The index into a queue entry.
+ * @count: The number of queue entries to access.
+ *
+ * Description:
+ * The routine performs sanity check on device queue access method commands.
+ *
+ * Returns:
+ * This function returns -EINVAL when fails the sanity check, otherwise, it
+ * returns 0.
+ **/
+static int
+lpfc_idiag_que_param_check(struct lpfc_queue *q, int index, int count)
+{
+	/* Only support single entry read or browsing */
+	if ((count != 1) && (count != LPFC_QUE_ACC_BROWSE))
+		return -EINVAL;
+	if (index > q->entry_count - 1)
+		return -EINVAL;
+	return 0;
+}
+
+/**
+ * lpfc_idiag_queacc_read_qe - read a single entry from the given queue index
+ * @pbuffer: The pointer to buffer to copy the read data into.
+ * @pque: The pointer to the queue to be read.
+ * @index: The index into the queue entry.
+ *
+ * Description:
+ * This routine reads out a single entry from the given queue's index location
+ * and copies it into the buffer provided.
+ *
+ * Returns:
+ * This function returns 0 when it fails, otherwise, it returns the length of
+ * the data read into the buffer provided.
+ **/
+static int
+lpfc_idiag_queacc_read_qe(char *pbuffer, int len, struct lpfc_queue *pque,
+			  uint32_t index)
+{
+	int offset, esize;
+	uint32_t *pentry;
+
+	if (!pbuffer || !pque)
+		return 0;
+
+	esize = pque->entry_size;
+	len += snprintf(pbuffer+len, LPFC_QUE_ACC_BUF_SIZE-len,
+			"QE-INDEX[%04d]:\n", index);
+
+	offset = 0;
+	pentry = pque->qe[index].address;
+	while (esize > 0) {
+		len += snprintf(pbuffer+len, LPFC_QUE_ACC_BUF_SIZE-len,
+				"%08x ", *pentry);
+		pentry++;
+		offset += sizeof(uint32_t);
+		esize -= sizeof(uint32_t);
+		if (esize > 0 && !(offset % (4 * sizeof(uint32_t))))
+			len += snprintf(pbuffer+len,
+					LPFC_QUE_ACC_BUF_SIZE-len, "\n");
+	}
+	len += snprintf(pbuffer+len, LPFC_QUE_ACC_BUF_SIZE-len, "\n");
+
+	return len;
+}
+
+/**
+ * lpfc_idiag_queacc_read - idiag debugfs read port queue
+ * @file: The file pointer to read from.
+ * @buf: The buffer to copy the data to.
+ * @nbytes: The number of bytes to read.
+ * @ppos: The position in the file to start reading from.
+ *
+ * Description:
+ * This routine reads data from the @phba device queue memory according to the
+ * idiag command, and copies to user @buf. Depending on the queue dump read
+ * command setup, it does either a single queue entry read or browing through
+ * all entries of the queue.
+ *
+ * Returns:
+ * This function returns the amount of data that was read (this could be less
+ * than @nbytes if the end of the file was reached) or a negative error value.
+ **/
+static ssize_t
+lpfc_idiag_queacc_read(struct file *file, char __user *buf, size_t nbytes,
+		       loff_t *ppos)
+{
+	struct lpfc_debug *debug = file->private_data;
+	uint32_t last_index, index, count;
+	struct lpfc_queue *pque = NULL;
+	char *pbuffer;
+	int len = 0;
+
+	/* This is a user read operation */
+	debug->op = LPFC_IDIAG_OP_RD;
+
+	if (!debug->buffer)
+		debug->buffer = kmalloc(LPFC_QUE_ACC_BUF_SIZE, GFP_KERNEL);
+	if (!debug->buffer)
+		return 0;
+	pbuffer = debug->buffer;
+
+	if (*ppos)
+		return 0;
+
+	if (idiag.cmd.opcode == LPFC_IDIAG_CMD_QUEACC_RD) {
+		index = idiag.cmd.data[2];
+		count = idiag.cmd.data[3];
+		pque = (struct lpfc_queue *)idiag.ptr_private;
+	} else
+		return 0;
+
+	/* Browse the queue starting from index */
+	if (count == LPFC_QUE_ACC_BROWSE)
+		goto que_browse;
+
+	/* Read a single entry from the queue */
+	len = lpfc_idiag_queacc_read_qe(pbuffer, len, pque, index);
+
+	return simple_read_from_buffer(buf, nbytes, ppos, pbuffer, len);
+
+que_browse:
+
+	/* Browse all entries from the queue */
+	last_index = idiag.offset.last_rd;
+	index = last_index;
+
+	while (len < LPFC_QUE_ACC_SIZE - pque->entry_size) {
+		len = lpfc_idiag_queacc_read_qe(pbuffer, len, pque, index);
+		index++;
+		if (index > pque->entry_count - 1)
+			break;
+	}
+
+	/* Set up the offset for next portion of pci cfg read */
+	if (index > pque->entry_count - 1)
+		index = 0;
+	idiag.offset.last_rd = index;
+
+	return simple_read_from_buffer(buf, nbytes, ppos, pbuffer, len);
+}
+
+/**
+ * lpfc_idiag_queacc_write - Syntax check and set up idiag queacc commands
+ * @file: The file pointer to read from.
+ * @buf: The buffer to copy the user data from.
+ * @nbytes: The number of bytes to get.
+ * @ppos: The position in the file to start reading from.
+ *
+ * This routine get the debugfs idiag command struct from user space and then
+ * perform the syntax check for port queue read (dump) or write (set) command
+ * accordingly. In the case of port queue read command, it sets up the command
+ * in the idiag command struct for the following debugfs read operation. In
+ * the case of port queue write operation, it executes the write operation
+ * into the port queue entry accordingly.
+ *
+ * It returns the @nbytges passing in from debugfs user space when successful.
+ * In case of error conditions, it returns proper error code back to the user
+ * space.
+ **/
+static ssize_t
+lpfc_idiag_queacc_write(struct file *file, const char __user *buf,
+			size_t nbytes, loff_t *ppos)
+{
+	struct lpfc_debug *debug = file->private_data;
+	struct lpfc_hba *phba = (struct lpfc_hba *)debug->i_private;
+	uint32_t qidx, quetp, queid, index, count, offset, value;
+	uint32_t *pentry;
+	struct lpfc_queue *pque;
+	int rc;
+
+	/* This is a user write operation */
+	debug->op = LPFC_IDIAG_OP_WR;
+
+	rc = lpfc_idiag_cmd_get(buf, nbytes, &idiag.cmd);
+	if (rc < 0)
+		return rc;
+
+	/* Get and sanity check on command feilds */
+	quetp  = idiag.cmd.data[0];
+	queid  = idiag.cmd.data[1];
+	index  = idiag.cmd.data[2];
+	count  = idiag.cmd.data[3];
+	offset = idiag.cmd.data[4];
+	value  = idiag.cmd.data[5];
+
+	/* Sanity check on command line arguments */
+	if (idiag.cmd.opcode == LPFC_IDIAG_CMD_QUEACC_WR ||
+	    idiag.cmd.opcode == LPFC_IDIAG_CMD_QUEACC_ST ||
+	    idiag.cmd.opcode == LPFC_IDIAG_CMD_QUEACC_CL) {
+		if (rc != LPFC_QUE_ACC_WR_CMD_ARG)
+			goto error_out;
+		if (count != 1)
+			goto error_out;
+	} else if (idiag.cmd.opcode == LPFC_IDIAG_CMD_QUEACC_RD) {
+		if (rc != LPFC_QUE_ACC_RD_CMD_ARG)
+			goto error_out;
+	} else
+		goto error_out;
+
+	switch (quetp) {
+	case LPFC_IDIAG_EQ:
+		/* Slow-path event queue */
+		if (phba->sli4_hba.sp_eq->queue_id == queid) {
+			/* Sanity check */
+			rc = lpfc_idiag_que_param_check(
+					phba->sli4_hba.sp_eq, index, count);
+			if (rc)
+				goto error_out;
+			idiag.ptr_private = phba->sli4_hba.sp_eq;
+			goto pass_check;
+		}
+		/* Fast-path event queue */
+		for (qidx = 0; qidx < phba->cfg_fcp_eq_count; qidx++) {
+			if (phba->sli4_hba.fp_eq[qidx]->queue_id == queid) {
+				/* Sanity check */
+				rc = lpfc_idiag_que_param_check(
+						phba->sli4_hba.fp_eq[qidx],
+						index, count);
+				if (rc)
+					goto error_out;
+				idiag.ptr_private = phba->sli4_hba.fp_eq[qidx];
+				goto pass_check;
+			}
+		}
+		goto error_out;
+		break;
+	case LPFC_IDIAG_CQ:
+		/* MBX complete queue */
+		if (phba->sli4_hba.mbx_cq->queue_id == queid) {
+			/* Sanity check */
+			rc = lpfc_idiag_que_param_check(
+					phba->sli4_hba.mbx_cq, index, count);
+			if (rc)
+				goto error_out;
+			idiag.ptr_private = phba->sli4_hba.mbx_cq;
+			goto pass_check;
+		}
+		/* ELS complete queue */
+		if (phba->sli4_hba.els_cq->queue_id == queid) {
+			/* Sanity check */
+			rc = lpfc_idiag_que_param_check(
+					phba->sli4_hba.els_cq, index, count);
+			if (rc)
+				goto error_out;
+			idiag.ptr_private = phba->sli4_hba.els_cq;
+			goto pass_check;
+		}
+		/* FCP complete queue */
+		qidx = 0;
+		do {
+			if (phba->sli4_hba.fcp_cq[qidx]->queue_id == queid) {
+				/* Sanity check */
+				rc = lpfc_idiag_que_param_check(
+						phba->sli4_hba.fcp_cq[qidx],
+						index, count);
+				if (rc)
+					goto error_out;
+				idiag.ptr_private =
+						phba->sli4_hba.fcp_cq[qidx];
+				goto pass_check;
+			}
+		} while (++qidx < phba->cfg_fcp_eq_count);
+		goto error_out;
+		break;
+	case LPFC_IDIAG_MQ:
+		/* MBX work queue */
+		if (phba->sli4_hba.mbx_wq->queue_id == queid) {
+			/* Sanity check */
+			rc = lpfc_idiag_que_param_check(
+					phba->sli4_hba.mbx_wq, index, count);
+			if (rc)
+				goto error_out;
+			idiag.ptr_private = phba->sli4_hba.mbx_wq;
+			goto pass_check;
+		}
+		break;
+	case LPFC_IDIAG_WQ:
+		/* ELS work queue */
+		if (phba->sli4_hba.els_wq->queue_id == queid) {
+			/* Sanity check */
+			rc = lpfc_idiag_que_param_check(
+					phba->sli4_hba.els_wq, index, count);
+			if (rc)
+				goto error_out;
+			idiag.ptr_private = phba->sli4_hba.els_wq;
+			goto pass_check;
+		}
+		/* FCP work queue */
+		for (qidx = 0; qidx < phba->cfg_fcp_wq_count; qidx++) {
+			if (phba->sli4_hba.fcp_wq[qidx]->queue_id == queid) {
+				/* Sanity check */
+				rc = lpfc_idiag_que_param_check(
+						phba->sli4_hba.fcp_wq[qidx],
+						index, count);
+				if (rc)
+					goto error_out;
+				idiag.ptr_private =
+					phba->sli4_hba.fcp_wq[qidx];
+				goto pass_check;
+			}
+		}
+		goto error_out;
+		break;
+	case LPFC_IDIAG_RQ:
+		/* HDR queue */
+		if (phba->sli4_hba.hdr_rq->queue_id == queid) {
+			/* Sanity check */
+			rc = lpfc_idiag_que_param_check(
+					phba->sli4_hba.hdr_rq, index, count);
+			if (rc)
+				goto error_out;
+			idiag.ptr_private = phba->sli4_hba.hdr_rq;
+			goto pass_check;
+		}
+		/* DAT queue */
+		if (phba->sli4_hba.dat_rq->queue_id == queid) {
+			/* Sanity check */
+			rc = lpfc_idiag_que_param_check(
+					phba->sli4_hba.dat_rq, index, count);
+			if (rc)
+				goto error_out;
+			idiag.ptr_private = phba->sli4_hba.dat_rq;
+			goto pass_check;
+		}
+		goto error_out;
+		break;
+	default:
+		goto error_out;
+		break;
+	}
+
+pass_check:
+
+	if (idiag.cmd.opcode == LPFC_IDIAG_CMD_QUEACC_RD) {
+		if (count == LPFC_QUE_ACC_BROWSE)
+			idiag.offset.last_rd = index;
+	}
+
+	if (idiag.cmd.opcode == LPFC_IDIAG_CMD_QUEACC_WR ||
+	    idiag.cmd.opcode == LPFC_IDIAG_CMD_QUEACC_ST ||
+	    idiag.cmd.opcode == LPFC_IDIAG_CMD_QUEACC_CL) {
+		/* Additional sanity checks on write operation */
+		pque = (struct lpfc_queue *)idiag.ptr_private;
+		if (offset > pque->entry_size/sizeof(uint32_t) - 1)
+			goto error_out;
+		pentry = pque->qe[index].address;
+		pentry += offset;
+		if (idiag.cmd.opcode == LPFC_IDIAG_CMD_QUEACC_WR)
+			*pentry = value;
+		if (idiag.cmd.opcode == LPFC_IDIAG_CMD_QUEACC_ST)
+			*pentry |= value;
+		if (idiag.cmd.opcode == LPFC_IDIAG_CMD_QUEACC_CL)
+			*pentry &= ~value;
+	}
+	return nbytes;
+
+error_out:
+	/* Clean out command structure on command error out */
+	memset(&idiag, 0, sizeof(idiag));
+	return -EINVAL;
+}
+
+/**
+ * lpfc_idiag_drbacc_read_reg - idiag debugfs read a doorbell register
+ * @phba: The pointer to hba structure.
+ * @pbuffer: The pointer to the buffer to copy the data to.
+ * @len: The lenght of bytes to copied.
+ * @drbregid: The id to doorbell registers.
+ *
+ * Description:
+ * This routine reads a doorbell register and copies its content to the
+ * user buffer pointed to by @pbuffer.
+ *
+ * Returns:
+ * This function returns the amount of data that was copied into @pbuffer.
+ **/
+static int
+lpfc_idiag_drbacc_read_reg(struct lpfc_hba *phba, char *pbuffer,
+			   int len, uint32_t drbregid)
+{
+
+	if (!pbuffer)
+		return 0;
+
+	switch (drbregid) {
+	case LPFC_DRB_EQCQ:
+		len += snprintf(pbuffer+len, LPFC_DRB_ACC_BUF_SIZE-len,
+				"EQCQ-DRB-REG: 0x%08x\n",
+				readl(phba->sli4_hba.EQCQDBregaddr));
+		break;
+	case LPFC_DRB_MQ:
+		len += snprintf(pbuffer+len, LPFC_DRB_ACC_BUF_SIZE-len,
+				"MQ-DRB-REG:   0x%08x\n",
+				readl(phba->sli4_hba.MQDBregaddr));
+		break;
+	case LPFC_DRB_WQ:
+		len += snprintf(pbuffer+len, LPFC_DRB_ACC_BUF_SIZE-len,
+				"WQ-DRB-REG:   0x%08x\n",
+				readl(phba->sli4_hba.WQDBregaddr));
+		break;
+	case LPFC_DRB_RQ:
+		len += snprintf(pbuffer+len, LPFC_DRB_ACC_BUF_SIZE-len,
+				"RQ-DRB-REG:   0x%08x\n",
+				readl(phba->sli4_hba.RQDBregaddr));
+		break;
+	default:
+		break;
+	}
+
+	return len;
+}
+
+/**
+ * lpfc_idiag_drbacc_read - idiag debugfs read port doorbell
+ * @file: The file pointer to read from.
+ * @buf: The buffer to copy the data to.
+ * @nbytes: The number of bytes to read.
+ * @ppos: The position in the file to start reading from.
+ *
+ * Description:
+ * This routine reads data from the @phba device doorbell register according
+ * to the idiag command, and copies to user @buf. Depending on the doorbell
+ * register read command setup, it does either a single doorbell register
+ * read or dump all doorbell registers.
+ *
+ * Returns:
+ * This function returns the amount of data that was read (this could be less
+ * than @nbytes if the end of the file was reached) or a negative error value.
+ **/
+static ssize_t
+lpfc_idiag_drbacc_read(struct file *file, char __user *buf, size_t nbytes,
+		       loff_t *ppos)
+{
+	struct lpfc_debug *debug = file->private_data;
+	struct lpfc_hba *phba = (struct lpfc_hba *)debug->i_private;
+	uint32_t drb_reg_id, i;
+	char *pbuffer;
+	int len = 0;
+
+	/* This is a user read operation */
+	debug->op = LPFC_IDIAG_OP_RD;
+
+	if (!debug->buffer)
+		debug->buffer = kmalloc(LPFC_DRB_ACC_BUF_SIZE, GFP_KERNEL);
+	if (!debug->buffer)
+		return 0;
+	pbuffer = debug->buffer;
+
+	if (*ppos)
+		return 0;
+
+	if (idiag.cmd.opcode == LPFC_IDIAG_CMD_DRBACC_RD)
+		drb_reg_id = idiag.cmd.data[0];
+	else
+		return 0;
+
+	if (drb_reg_id == LPFC_DRB_ACC_ALL)
+		for (i = 1; i <= LPFC_DRB_MAX; i++)
+			len = lpfc_idiag_drbacc_read_reg(phba,
+							 pbuffer, len, i);
+	else
+		len = lpfc_idiag_drbacc_read_reg(phba,
+						 pbuffer, len, drb_reg_id);
+
+	return simple_read_from_buffer(buf, nbytes, ppos, pbuffer, len);
+}
+
+/**
+ * lpfc_idiag_drbacc_write - Syntax check and set up idiag drbacc commands
+ * @file: The file pointer to read from.
+ * @buf: The buffer to copy the user data from.
+ * @nbytes: The number of bytes to get.
+ * @ppos: The position in the file to start reading from.
+ *
+ * This routine get the debugfs idiag command struct from user space and then
+ * perform the syntax check for port doorbell register read (dump) or write
+ * (set) command accordingly. In the case of port queue read command, it sets
+ * up the command in the idiag command struct for the following debugfs read
+ * operation. In the case of port doorbell register write operation, it
+ * executes the write operation into the port doorbell register accordingly.
+ *
+ * It returns the @nbytges passing in from debugfs user space when successful.
+ * In case of error conditions, it returns proper error code back to the user
+ * space.
+ **/
+static ssize_t
+lpfc_idiag_drbacc_write(struct file *file, const char __user *buf,
+			size_t nbytes, loff_t *ppos)
+{
+	struct lpfc_debug *debug = file->private_data;
+	struct lpfc_hba *phba = (struct lpfc_hba *)debug->i_private;
+	uint32_t drb_reg_id, value, reg_val;
+	void __iomem *drb_reg;
+	int rc;
+
+	/* This is a user write operation */
+	debug->op = LPFC_IDIAG_OP_WR;
+
+	rc = lpfc_idiag_cmd_get(buf, nbytes, &idiag.cmd);
+	if (rc < 0)
+		return rc;
+
+	/* Sanity check on command line arguments */
+	drb_reg_id = idiag.cmd.data[0];
+	value = idiag.cmd.data[1];
+
+	if (idiag.cmd.opcode == LPFC_IDIAG_CMD_DRBACC_WR ||
+	    idiag.cmd.opcode == LPFC_IDIAG_CMD_DRBACC_ST ||
+	    idiag.cmd.opcode == LPFC_IDIAG_CMD_DRBACC_CL) {
+		if (rc != LPFC_DRB_ACC_WR_CMD_ARG)
+			goto error_out;
+		if (drb_reg_id > LPFC_DRB_MAX)
+			goto error_out;
+	} else if (idiag.cmd.opcode == LPFC_IDIAG_CMD_DRBACC_RD) {
+		if (rc != LPFC_DRB_ACC_RD_CMD_ARG)
+			goto error_out;
+		if ((drb_reg_id > LPFC_DRB_MAX) &&
+		    (drb_reg_id != LPFC_DRB_ACC_ALL))
+			goto error_out;
+	} else
+		goto error_out;
+
+	/* Perform the write access operation */
+	if (idiag.cmd.opcode == LPFC_IDIAG_CMD_DRBACC_WR ||
+	    idiag.cmd.opcode == LPFC_IDIAG_CMD_DRBACC_ST ||
+	    idiag.cmd.opcode == LPFC_IDIAG_CMD_DRBACC_CL) {
+		switch (drb_reg_id) {
+		case LPFC_DRB_EQCQ:
+			drb_reg = phba->sli4_hba.EQCQDBregaddr;
+			break;
+		case LPFC_DRB_MQ:
+			drb_reg = phba->sli4_hba.MQDBregaddr;
+			break;
+		case LPFC_DRB_WQ:
+			drb_reg = phba->sli4_hba.WQDBregaddr;
+			break;
+		case LPFC_DRB_RQ:
+			drb_reg = phba->sli4_hba.RQDBregaddr;
+			break;
+		default:
+			goto error_out;
+		}
+
+		if (idiag.cmd.opcode == LPFC_IDIAG_CMD_DRBACC_WR)
+			reg_val = value;
+		if (idiag.cmd.opcode == LPFC_IDIAG_CMD_DRBACC_ST) {
+			reg_val = readl(drb_reg);
+			reg_val |= value;
+		}
+		if (idiag.cmd.opcode == LPFC_IDIAG_CMD_DRBACC_CL) {
+			reg_val = readl(drb_reg);
+			reg_val &= ~value;
+		}
+		writel(reg_val, drb_reg);
+		readl(drb_reg); /* flush */
+	}
+	return nbytes;
+
+error_out:
+	/* Clean out command structure on command error out */
+	memset(&idiag, 0, sizeof(idiag));
+	return -EINVAL;
+}
+
 #undef lpfc_debugfs_op_disc_trc
 static const struct file_operations lpfc_debugfs_op_disc_trc = {
 	.owner =        THIS_MODULE,
@@ -1986,6 +2427,26 @@
 	.release =      lpfc_idiag_release,
 };
 
+#undef lpfc_idiag_op_queacc
+static const struct file_operations lpfc_idiag_op_queAcc = {
+	.owner =        THIS_MODULE,
+	.open =         lpfc_idiag_open,
+	.llseek =       lpfc_debugfs_lseek,
+	.read =         lpfc_idiag_queacc_read,
+	.write =        lpfc_idiag_queacc_write,
+	.release =      lpfc_idiag_cmd_release,
+};
+
+#undef lpfc_idiag_op_drbacc
+static const struct file_operations lpfc_idiag_op_drbAcc = {
+	.owner =        THIS_MODULE,
+	.open =         lpfc_idiag_open,
+	.llseek =       lpfc_debugfs_lseek,
+	.read =         lpfc_idiag_drbacc_read,
+	.write =        lpfc_idiag_drbacc_write,
+	.release =      lpfc_idiag_cmd_release,
+};
+
 #endif
 
 /**
@@ -2261,6 +2722,32 @@
 		}
 	}
 
+	/* iDiag access PCI function queue */
+	snprintf(name, sizeof(name), "queAcc");
+	if (!phba->idiag_que_acc) {
+		phba->idiag_que_acc =
+			debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
+				phba->idiag_root, phba, &lpfc_idiag_op_queAcc);
+		if (!phba->idiag_que_acc) {
+			lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
+					 "2926 Can't create idiag debugfs\n");
+			goto debug_failed;
+		}
+	}
+
+	/* iDiag access PCI function doorbell registers */
+	snprintf(name, sizeof(name), "drbAcc");
+	if (!phba->idiag_drb_acc) {
+		phba->idiag_drb_acc =
+			debugfs_create_file(name, S_IFREG|S_IRUGO|S_IWUSR,
+				phba->idiag_root, phba, &lpfc_idiag_op_drbAcc);
+		if (!phba->idiag_drb_acc) {
+			lpfc_printf_vlog(vport, KERN_ERR, LOG_INIT,
+					 "2927 Can't create idiag debugfs\n");
+			goto debug_failed;
+		}
+	}
+
 debug_failed:
 	return;
 #endif
@@ -2339,6 +2826,16 @@
 		 * iDiag release
 		 */
 		if (phba->sli_rev == LPFC_SLI_REV4) {
+			if (phba->idiag_drb_acc) {
+				/* iDiag drbAcc */
+				debugfs_remove(phba->idiag_drb_acc);
+				phba->idiag_drb_acc = NULL;
+			}
+			if (phba->idiag_que_acc) {
+				/* iDiag queAcc */
+				debugfs_remove(phba->idiag_que_acc);
+				phba->idiag_que_acc = NULL;
+			}
 			if (phba->idiag_que_info) {
 				/* iDiag queInfo */
 				debugfs_remove(phba->idiag_que_info);
diff -druN linux-2.6.39-libre/drivers/scsi/lpfc/lpfc_debugfs.h linux-3.0-rc7-libre/drivers/scsi/lpfc/lpfc_debugfs.h
--- linux-2.6.39-libre/drivers/scsi/lpfc/lpfc_debugfs.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/scsi/lpfc/lpfc_debugfs.h	2011-07-11 19:51:52.000000000 -0400
@@ -39,13 +39,42 @@
 /* hbqinfo output buffer size */
 #define LPFC_HBQINFO_SIZE 8192
 
-/* rdPciConf output buffer size */
+/* pciConf */
+#define LPFC_PCI_CFG_BROWSE 0xffff
+#define LPFC_PCI_CFG_RD_CMD_ARG 2
+#define LPFC_PCI_CFG_WR_CMD_ARG 3
 #define LPFC_PCI_CFG_SIZE 4096
 #define LPFC_PCI_CFG_RD_BUF_SIZE (LPFC_PCI_CFG_SIZE/2)
 #define LPFC_PCI_CFG_RD_SIZE (LPFC_PCI_CFG_SIZE/4)
 
-/* queue info output buffer size */
-#define LPFC_QUE_INFO_GET_BUF_SIZE 2048
+/* queue info */
+#define LPFC_QUE_INFO_GET_BUF_SIZE 4096
+
+/* queue acc */
+#define LPFC_QUE_ACC_BROWSE 0xffff
+#define LPFC_QUE_ACC_RD_CMD_ARG 4
+#define LPFC_QUE_ACC_WR_CMD_ARG 6
+#define LPFC_QUE_ACC_BUF_SIZE 4096
+#define LPFC_QUE_ACC_SIZE (LPFC_QUE_ACC_BUF_SIZE/2)
+
+#define LPFC_IDIAG_EQ 1
+#define LPFC_IDIAG_CQ 2
+#define LPFC_IDIAG_MQ 3
+#define LPFC_IDIAG_WQ 4
+#define LPFC_IDIAG_RQ 5
+
+/* doorbell acc */
+#define LPFC_DRB_ACC_ALL 0xffff
+#define LPFC_DRB_ACC_RD_CMD_ARG 1
+#define LPFC_DRB_ACC_WR_CMD_ARG 2
+#define LPFC_DRB_ACC_BUF_SIZE 256
+
+#define LPFC_DRB_EQCQ 1
+#define LPFC_DRB_MQ   2
+#define LPFC_DRB_WQ   3
+#define LPFC_DRB_RQ   4
+
+#define LPFC_DRB_MAX  4
 
 #define SIZE_U8  sizeof(uint8_t)
 #define SIZE_U16 sizeof(uint16_t)
@@ -73,13 +102,23 @@
 	uint32_t last_rd;
 };
 
-#define LPFC_IDIAG_CMD_DATA_SIZE 4
+#define LPFC_IDIAG_CMD_DATA_SIZE 8
 struct lpfc_idiag_cmd {
 	uint32_t opcode;
 #define LPFC_IDIAG_CMD_PCICFG_RD 0x00000001
 #define LPFC_IDIAG_CMD_PCICFG_WR 0x00000002
 #define LPFC_IDIAG_CMD_PCICFG_ST 0x00000003
 #define LPFC_IDIAG_CMD_PCICFG_CL 0x00000004
+
+#define LPFC_IDIAG_CMD_QUEACC_RD 0x00000011
+#define LPFC_IDIAG_CMD_QUEACC_WR 0x00000012
+#define LPFC_IDIAG_CMD_QUEACC_ST 0x00000013
+#define LPFC_IDIAG_CMD_QUEACC_CL 0x00000014
+
+#define LPFC_IDIAG_CMD_DRBACC_RD 0x00000021
+#define LPFC_IDIAG_CMD_DRBACC_WR 0x00000022
+#define LPFC_IDIAG_CMD_DRBACC_ST 0x00000023
+#define LPFC_IDIAG_CMD_DRBACC_CL 0x00000024
 	uint32_t data[LPFC_IDIAG_CMD_DATA_SIZE];
 };
 
@@ -87,6 +126,7 @@
 	uint32_t active;
 	struct lpfc_idiag_cmd cmd;
 	struct lpfc_idiag_offset offset;
+	void *ptr_private;
 };
 #endif
 
diff -druN linux-2.6.39-libre/drivers/scsi/lpfc/lpfc_els.c linux-3.0-rc7-libre/drivers/scsi/lpfc/lpfc_els.c
--- linux-2.6.39-libre/drivers/scsi/lpfc/lpfc_els.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/scsi/lpfc/lpfc_els.c	2011-07-11 19:51:52.000000000 -0400
@@ -250,7 +250,7 @@
 		icmd->un.elsreq64.myID = vport->fc_myDID;
 
 		/* For ELS_REQUEST64_CR, use the VPI by default */
-		icmd->ulpContext = vport->vpi + phba->vpi_base;
+		icmd->ulpContext = phba->vpi_ids[vport->vpi];
 		icmd->ulpCt_h = 0;
 		/* The CT field must be 0=INVALID_RPI for the ECHO cmd */
 		if (elscmd == ELS_CMD_ECHO)
@@ -454,6 +454,7 @@
 		rc = -ENOMEM;
 		goto fail_free_dmabuf;
 	}
+
 	mboxq = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
 	if (!mboxq) {
 		rc = -ENOMEM;
@@ -670,6 +671,7 @@
 			 * Driver needs to re-reg VPI in order for f/w
 			 * to update the MAC address.
 			 */
+			lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNMAPPED_NODE);
 			lpfc_register_new_vport(phba, vport, ndlp);
 			return 0;
 	}
@@ -869,8 +871,8 @@
 		 */
 		if ((phba->hba_flag & HBA_FIP_SUPPORT) &&
 		    (phba->fcf.fcf_flag & FCF_DISCOVERY) &&
-		    (irsp->ulpStatus != IOSTAT_LOCAL_REJECT) &&
-		    (irsp->un.ulpWord[4] != IOERR_SLI_ABORTED)) {
+		    !((irsp->ulpStatus == IOSTAT_LOCAL_REJECT) &&
+		     (irsp->un.ulpWord[4] == IOERR_SLI_ABORTED))) {
 			lpfc_printf_log(phba, KERN_WARNING, LOG_FIP | LOG_ELS,
 					"2611 FLOGI failed on FCF (x%x), "
 					"status:x%x/x%x, tmo:x%x, perform "
@@ -1085,14 +1087,15 @@
 	if (sp->cmn.fcphHigh < FC_PH3)
 		sp->cmn.fcphHigh = FC_PH3;
 
-	if  ((phba->sli_rev == LPFC_SLI_REV4) &&
-	     (bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf) ==
-	      LPFC_SLI_INTF_IF_TYPE_0)) {
-		elsiocb->iocb.ulpCt_h = ((SLI4_CT_FCFI >> 1) & 1);
-		elsiocb->iocb.ulpCt_l = (SLI4_CT_FCFI & 1);
-		/* FLOGI needs to be 3 for WQE FCFI */
-		/* Set the fcfi to the fcfi we registered with */
-		elsiocb->iocb.ulpContext = phba->fcf.fcfi;
+	if  (phba->sli_rev == LPFC_SLI_REV4) {
+		if (bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf) ==
+		    LPFC_SLI_INTF_IF_TYPE_0) {
+			elsiocb->iocb.ulpCt_h = ((SLI4_CT_FCFI >> 1) & 1);
+			elsiocb->iocb.ulpCt_l = (SLI4_CT_FCFI & 1);
+			/* FLOGI needs to be 3 for WQE FCFI */
+			/* Set the fcfi to the fcfi we registered with */
+			elsiocb->iocb.ulpContext = phba->fcf.fcfi;
+		}
 	} else if (phba->sli3_options & LPFC_SLI3_NPIV_ENABLED) {
 		sp->cmn.request_multiple_Nport = 1;
 		/* For FLOGI, Let FLOGI rsp set the NPortID for VPI 0 */
@@ -4107,13 +4110,13 @@
 	pcmd += sizeof(uint32_t);
 	rrq = (struct RRQ *)pcmd;
 	rrq->rrq_exchg = be32_to_cpu(rrq->rrq_exchg);
-	rxid = be16_to_cpu(bf_get(rrq_rxid, rrq));
+	rxid = bf_get(rrq_rxid, rrq);
 
 	lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
 			"2883 Clear RRQ for SID:x%x OXID:x%x RXID:x%x"
 			" x%x x%x\n",
 			be32_to_cpu(bf_get(rrq_did, rrq)),
-			be16_to_cpu(bf_get(rrq_oxid, rrq)),
+			bf_get(rrq_oxid, rrq),
 			rxid,
 			iocb->iotag, iocb->iocb.ulpContext);
 
@@ -4121,7 +4124,7 @@
 		"Clear RRQ:  did:x%x flg:x%x exchg:x%.08x",
 		ndlp->nlp_DID, ndlp->nlp_flag, rrq->rrq_exchg);
 	if (vport->fc_myDID == be32_to_cpu(bf_get(rrq_did, rrq)))
-		xri = be16_to_cpu(bf_get(rrq_oxid, rrq));
+		xri = bf_get(rrq_oxid, rrq);
 	else
 		xri = rxid;
 	prrq = lpfc_get_active_rrq(vport, xri, ndlp->nlp_DID);
@@ -6583,6 +6586,26 @@
 {
 	struct lpfc_vport *vport;
 	unsigned long flags;
+	int i;
+
+	/* The physical ports are always vpi 0 - translate is unnecessary. */
+	if (vpi > 0) {
+		/*
+		 * Translate the physical vpi to the logical vpi.  The
+		 * vport stores the logical vpi.
+		 */
+		for (i = 0; i < phba->max_vpi; i++) {
+			if (vpi == phba->vpi_ids[i])
+				break;
+		}
+
+		if (i >= phba->max_vpi) {
+			lpfc_printf_log(phba, KERN_ERR, LOG_ELS,
+					 "2936 Could not find Vport mapped "
+					 "to vpi %d\n", vpi);
+			return NULL;
+		}
+	}
 
 	spin_lock_irqsave(&phba->hbalock, flags);
 	list_for_each_entry(vport, &phba->port_list, listentry) {
@@ -6639,8 +6662,9 @@
 			vport = phba->pport;
 		else
 			vport = lpfc_find_vport_by_vpid(phba,
-				icmd->unsli3.rcvsli3.vpi - phba->vpi_base);
+						icmd->unsli3.rcvsli3.vpi);
 	}
+
 	/* If there are no BDEs associated
 	 * with this IOCB, there is nothing to do.
 	 */
@@ -7220,7 +7244,7 @@
 		elsiocb->iocb.ulpCt_h = (SLI4_CT_VPI >> 1) & 1;
 		elsiocb->iocb.ulpCt_l = SLI4_CT_VPI & 1 ;
 		/* Set the ulpContext to the vpi */
-		elsiocb->iocb.ulpContext = vport->vpi + phba->vpi_base;
+		elsiocb->iocb.ulpContext = phba->vpi_ids[vport->vpi];
 	} else {
 		/* For FDISC, Let FDISC rsp set the NPortID for this VPI */
 		icmd->ulpCt_h = 1;
@@ -7290,8 +7314,9 @@
 	struct lpfc_vport *vport = cmdiocb->vport;
 	IOCB_t *irsp;
 	struct lpfc_nodelist *ndlp;
-	ndlp = (struct lpfc_nodelist *)cmdiocb->context1;
+	struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
 
+	ndlp = (struct lpfc_nodelist *)cmdiocb->context1;
 	irsp = &rspiocb->iocb;
 	lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_CMD,
 		"LOGO npiv cmpl:  status:x%x/x%x did:x%x",
@@ -7302,6 +7327,19 @@
 
 	/* Trigger the release of the ndlp after logo */
 	lpfc_nlp_put(ndlp);
+
+	/* NPIV LOGO completes to NPort <nlp_DID> */
+	lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
+			 "2928 NPIV LOGO completes to NPort x%x "
+			 "Data: x%x x%x x%x x%x\n",
+			 ndlp->nlp_DID, irsp->ulpStatus, irsp->un.ulpWord[4],
+			 irsp->ulpTimeout, vport->num_disc_nodes);
+
+	if (irsp->ulpStatus == IOSTAT_SUCCESS) {
+		spin_lock_irq(shost->host_lock);
+		vport->fc_flag &= ~FC_FABRIC;
+		spin_unlock_irq(shost->host_lock);
+	}
 }
 
 /**
diff -druN linux-2.6.39-libre/drivers/scsi/lpfc/lpfc.h linux-3.0-rc7-libre/drivers/scsi/lpfc/lpfc.h
--- linux-2.6.39-libre/drivers/scsi/lpfc/lpfc.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/scsi/lpfc/lpfc.h	2011-07-11 19:51:52.000000000 -0400
@@ -41,6 +41,7 @@
 		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_SGE_SIZE       0x80000000 /* Maximum data allowed in a SGE */
 #define LPFC_MAX_PROT_SG_SEG_CNT 4096	/* prot sg element count per scsi cmd*/
 #define LPFC_IOCB_LIST_CNT	2250	/* list of IOCBs for fast-path usage. */
 #define LPFC_Q_RAMP_UP_INTERVAL 120     /* lun q_depth ramp up interval */
@@ -486,6 +487,42 @@
 				     (1 << LPFC_USER_LINK_SPEED_AUTO))
 #define LPFC_LINK_SPEED_STRING "0, 1, 2, 4, 8, 10, 16"
 
+enum nemb_type {
+	nemb_mse = 1,
+	nemb_hbd
+};
+
+enum mbox_type {
+	mbox_rd = 1,
+	mbox_wr
+};
+
+enum dma_type {
+	dma_mbox = 1,
+	dma_ebuf
+};
+
+enum sta_type {
+	sta_pre_addr = 1,
+	sta_pos_addr
+};
+
+struct lpfc_mbox_ext_buf_ctx {
+	uint32_t state;
+#define LPFC_BSG_MBOX_IDLE		0
+#define LPFC_BSG_MBOX_HOST              1
+#define LPFC_BSG_MBOX_PORT		2
+#define LPFC_BSG_MBOX_DONE		3
+#define LPFC_BSG_MBOX_ABTS		4
+	enum nemb_type nembType;
+	enum mbox_type mboxType;
+	uint32_t numBuf;
+	uint32_t mbxTag;
+	uint32_t seqNum;
+	struct lpfc_dmabuf *mbx_dmabuf;
+	struct list_head ext_dmabuf_list;
+};
+
 struct lpfc_hba {
 	/* SCSI interface function jump table entries */
 	int (*lpfc_new_scsi_buf)
@@ -589,6 +626,7 @@
 
 	MAILBOX_t *mbox;
 	uint32_t *mbox_ext;
+	struct lpfc_mbox_ext_buf_ctx mbox_ext_buf_ctx;
 	uint32_t ha_copy;
 	struct _PCB *pcb;
 	struct _IOCB *IOCBs;
@@ -659,6 +697,7 @@
 	uint32_t cfg_hostmem_hgp;
 	uint32_t cfg_log_verbose;
 	uint32_t cfg_aer_support;
+	uint32_t cfg_sriov_nr_virtfn;
 	uint32_t cfg_iocb_cnt;
 	uint32_t cfg_suppress_link_up;
 #define LPFC_INITIALIZE_LINK              0	/* do normal init_link mbox */
@@ -706,7 +745,6 @@
 	uint32_t          *hbq_get;     /* Host mem address of HBQ get ptrs */
 
 	int brd_no;			/* FC board number */
-
 	char SerialNumber[32];		/* adapter Serial Number */
 	char OptionROMVersion[32];	/* adapter BIOS / Fcode version */
 	char ModelDesc[256];		/* Model Description */
@@ -778,6 +816,9 @@
 	uint16_t vpi_base;
 	uint16_t vfi_base;
 	unsigned long *vpi_bmask;	/* vpi allocation table */
+	uint16_t *vpi_ids;
+	uint16_t vpi_count;
+	struct list_head lpfc_vpi_blk_list;
 
 	/* Data structure used by fabric iocb scheduler */
 	struct list_head fabric_iocb_list;
@@ -805,6 +846,8 @@
 	struct dentry *idiag_root;
 	struct dentry *idiag_pci_cfg;
 	struct dentry *idiag_que_info;
+	struct dentry *idiag_que_acc;
+	struct dentry *idiag_drb_acc;
 #endif
 
 	/* Used for deferred freeing of ELS data buffers */
diff -druN linux-2.6.39-libre/drivers/scsi/lpfc/lpfc_hbadisc.c linux-3.0-rc7-libre/drivers/scsi/lpfc/lpfc_hbadisc.c
--- linux-2.6.39-libre/drivers/scsi/lpfc/lpfc_hbadisc.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/scsi/lpfc/lpfc_hbadisc.c	2011-07-11 19:51:52.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-2011 Emulex.  All rights reserved.           *
  * EMULEX and SLI are trademarks of Emulex.                        *
  * www.emulex.com                                                  *
  * Portions Copyright (C) 2004-2005 Christoph Hellwig              *
@@ -881,7 +881,7 @@
 	/* Clean up any firmware default rpi's */
 	mb = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
 	if (mb) {
-		lpfc_unreg_did(phba, 0xffff, 0xffffffff, mb);
+		lpfc_unreg_did(phba, 0xffff, LPFC_UNREG_ALL_DFLT_RPIS, mb);
 		mb->vport = vport;
 		mb->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
 		if (lpfc_sli_issue_mbox(phba, mb, MBX_NOWAIT)
@@ -2690,16 +2690,7 @@
 
 	memcpy((uint8_t *) &vport->fc_sparam, (uint8_t *) mp->virt,
 	       sizeof (struct serv_parm));
-	if (phba->cfg_soft_wwnn)
-		u64_to_wwn(phba->cfg_soft_wwnn,
-			   vport->fc_sparam.nodeName.u.wwn);
-	if (phba->cfg_soft_wwpn)
-		u64_to_wwn(phba->cfg_soft_wwpn,
-			   vport->fc_sparam.portName.u.wwn);
-	memcpy(&vport->fc_nodename, &vport->fc_sparam.nodeName,
-	       sizeof(vport->fc_nodename));
-	memcpy(&vport->fc_portname, &vport->fc_sparam.portName,
-	       sizeof(vport->fc_portname));
+	lpfc_update_vport_wwn(vport);
 	if (vport->port_type == LPFC_PHYSICAL_PORT) {
 		memcpy(&phba->wwnn, &vport->fc_nodename, sizeof(phba->wwnn));
 		memcpy(&phba->wwpn, &vport->fc_portname, sizeof(phba->wwnn));
@@ -3430,7 +3421,8 @@
 		return;
 	}
 
-	ndlp->nlp_rpi = mb->un.varWords[0];
+	if (phba->sli_rev < LPFC_SLI_REV4)
+		ndlp->nlp_rpi = mb->un.varWords[0];
 	ndlp->nlp_flag |= NLP_RPI_REGISTERED;
 	ndlp->nlp_type |= NLP_FABRIC;
 	lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNMAPPED_NODE);
@@ -3504,7 +3496,8 @@
 		return;
 	}
 
-	ndlp->nlp_rpi = mb->un.varWords[0];
+	if (phba->sli_rev < LPFC_SLI_REV4)
+		ndlp->nlp_rpi = mb->un.varWords[0];
 	ndlp->nlp_flag |= NLP_RPI_REGISTERED;
 	ndlp->nlp_type |= NLP_FABRIC;
 	lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNMAPPED_NODE);
@@ -3569,6 +3562,10 @@
 		"rport add:       did:x%x flg:x%x type x%x",
 		ndlp->nlp_DID, ndlp->nlp_flag, ndlp->nlp_type);
 
+	/* Don't add the remote port if unloading. */
+	if (vport->load_flag & FC_UNLOADING)
+		return;
+
 	ndlp->rport = rport = fc_remote_port_add(shost, 0, &rport_ids);
 	if (!rport || !get_device(&rport->dev)) {
 		dev_printk(KERN_WARNING, &phba->pcidev->dev,
@@ -3587,7 +3584,6 @@
 	if (ndlp->nlp_type & NLP_FCP_INITIATOR)
 		rport_ids.roles |= FC_RPORT_ROLE_FCP_INITIATOR;
 
-
 	if (rport_ids.roles !=  FC_RPORT_ROLE_UNKNOWN)
 		fc_remote_port_rolechg(rport, rport_ids.roles);
 
@@ -4102,11 +4098,16 @@
 	struct lpfc_hba *phba = vport->phba;
 	LPFC_MBOXQ_t    *mbox;
 	int rc;
+	uint16_t rpi;
 
 	if (ndlp->nlp_flag & NLP_RPI_REGISTERED) {
 		mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
 		if (mbox) {
-			lpfc_unreg_login(phba, vport->vpi, ndlp->nlp_rpi, mbox);
+			/* SLI4 ports require the physical rpi value. */
+			rpi = ndlp->nlp_rpi;
+			if (phba->sli_rev == LPFC_SLI_REV4)
+				rpi = phba->sli4_hba.rpi_ids[ndlp->nlp_rpi];
+			lpfc_unreg_login(phba, vport->vpi, rpi, mbox);
 			mbox->vport = vport;
 			mbox->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
 			rc = lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT);
@@ -4175,7 +4176,8 @@
 
 	mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
 	if (mbox) {
-		lpfc_unreg_login(phba, vport->vpi, 0xffff, mbox);
+		lpfc_unreg_login(phba, vport->vpi, LPFC_UNREG_ALL_RPIS_VPORT,
+				 mbox);
 		mbox->vport = vport;
 		mbox->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
 		mbox->context1 = NULL;
@@ -4199,7 +4201,8 @@
 
 	mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
 	if (mbox) {
-		lpfc_unreg_did(phba, vport->vpi, 0xffffffff, mbox);
+		lpfc_unreg_did(phba, vport->vpi, LPFC_UNREG_ALL_DFLT_RPIS,
+			       mbox);
 		mbox->vport = vport;
 		mbox->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
 		mbox->context1 = NULL;
@@ -4649,10 +4652,7 @@
 	if (num_sent)
 		return;
 
-	/*
-	 * For SLI3, cmpl_reg_vpi will set port_state to READY, and
-	 * continue discovery.
-	 */
+	/* Register the VPI for SLI3, NON-NPIV only. */
 	if ((phba->sli3_options & LPFC_SLI3_NPIV_ENABLED) &&
 	    !(vport->fc_flag & FC_PT2PT) &&
 	    !(vport->fc_flag & FC_RSCN_MODE) &&
@@ -4939,7 +4939,7 @@
 		if (phba->sli_rev < LPFC_SLI_REV4) {
 			if (phba->sli3_options & LPFC_SLI3_NPIV_ENABLED)
 				lpfc_issue_reg_vpi(phba, vport);
-			else  {	/* NPIV Not enabled */
+			else  {
 				lpfc_issue_clear_la(phba, vport);
 				vport->port_state = LPFC_VPORT_READY;
 			}
@@ -5065,7 +5065,8 @@
 	pmb->context1 = NULL;
 	pmb->context2 = NULL;
 
-	ndlp->nlp_rpi = mb->un.varWords[0];
+	if (phba->sli_rev < LPFC_SLI_REV4)
+		ndlp->nlp_rpi = mb->un.varWords[0];
 	ndlp->nlp_flag |= NLP_RPI_REGISTERED;
 	ndlp->nlp_type |= NLP_FABRIC;
 	lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNMAPPED_NODE);
@@ -5350,6 +5351,17 @@
 	for (i = 0; i <= phba->max_vports && vports[i] != NULL; i++) {
 		shost = lpfc_shost_from_vport(vports[i]);
 		spin_lock_irq(shost->host_lock);
+		/*
+		 * IF the CVL_RCVD bit is not set then we have sent the
+		 * flogi.
+		 * If dev_loss fires while we are waiting we do not want to
+		 * unreg the fcf.
+		 */
+		if (!(vports[i]->fc_flag & FC_VPORT_CVL_RCVD)) {
+			spin_unlock_irq(shost->host_lock);
+			ret =  1;
+			goto out;
+		}
 		list_for_each_entry(ndlp, &vports[i]->fc_nodes, nlp_listp) {
 			if (NLP_CHK_NODE_ACT(ndlp) && ndlp->rport &&
 			  (ndlp->rport->roles & FC_RPORT_ROLE_FCP_TARGET)) {
diff -druN linux-2.6.39-libre/drivers/scsi/lpfc/lpfc_hw4.h linux-3.0-rc7-libre/drivers/scsi/lpfc/lpfc_hw4.h
--- linux-2.6.39-libre/drivers/scsi/lpfc/lpfc_hw4.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/scsi/lpfc/lpfc_hw4.h	2011-07-11 19:51:52.000000000 -0400
@@ -170,6 +170,25 @@
 #define LPFC_PCI_FUNC3		3
 #define LPFC_PCI_FUNC4		4
 
+/* SLI4 interface type-2 control register offsets */
+#define LPFC_CTL_PORT_SEM_OFFSET	0x400
+#define LPFC_CTL_PORT_STA_OFFSET	0x404
+#define LPFC_CTL_PORT_CTL_OFFSET	0x408
+#define LPFC_CTL_PORT_ER1_OFFSET	0x40C
+#define LPFC_CTL_PORT_ER2_OFFSET	0x410
+#define LPFC_CTL_PDEV_CTL_OFFSET	0x414
+
+/* Some SLI4 interface type-2 PDEV_CTL register bits */
+#define LPFC_CTL_PDEV_CTL_DRST		0x00000001
+#define LPFC_CTL_PDEV_CTL_FRST		0x00000002
+#define LPFC_CTL_PDEV_CTL_DD		0x00000004
+#define LPFC_CTL_PDEV_CTL_LC		0x00000008
+#define LPFC_CTL_PDEV_CTL_FRL_ALL	0x00
+#define LPFC_CTL_PDEV_CTL_FRL_FC_FCOE	0x10
+#define LPFC_CTL_PDEV_CTL_FRL_NIC	0x20
+
+#define LPFC_FW_DUMP_REQUEST    (LPFC_CTL_PDEV_CTL_DD | LPFC_CTL_PDEV_CTL_FRST)
+
 /* Active interrupt test count */
 #define LPFC_ACT_INTR_CNT	4
 
@@ -210,9 +229,26 @@
 
 struct lpfc_sli4_flags {
 	uint32_t word0;
-#define lpfc_fip_flag_SHIFT 0
-#define lpfc_fip_flag_MASK 0x00000001
-#define lpfc_fip_flag_WORD word0
+#define lpfc_idx_rsrc_rdy_SHIFT		0
+#define lpfc_idx_rsrc_rdy_MASK		0x00000001
+#define lpfc_idx_rsrc_rdy_WORD		word0
+#define LPFC_IDX_RSRC_RDY		1
+#define lpfc_xri_rsrc_rdy_SHIFT		1
+#define lpfc_xri_rsrc_rdy_MASK		0x00000001
+#define lpfc_xri_rsrc_rdy_WORD		word0
+#define LPFC_XRI_RSRC_RDY		1
+#define lpfc_rpi_rsrc_rdy_SHIFT		2
+#define lpfc_rpi_rsrc_rdy_MASK		0x00000001
+#define lpfc_rpi_rsrc_rdy_WORD		word0
+#define LPFC_RPI_RSRC_RDY		1
+#define lpfc_vpi_rsrc_rdy_SHIFT		3
+#define lpfc_vpi_rsrc_rdy_MASK		0x00000001
+#define lpfc_vpi_rsrc_rdy_WORD		word0
+#define LPFC_VPI_RSRC_RDY		1
+#define lpfc_vfi_rsrc_rdy_SHIFT		4
+#define lpfc_vfi_rsrc_rdy_MASK		0x00000001
+#define lpfc_vfi_rsrc_rdy_WORD		word0
+#define LPFC_VFI_RSRC_RDY		1
 };
 
 struct sli4_bls_rsp {
@@ -739,6 +775,12 @@
 #define lpfc_mbox_hdr_version_SHIFT	0
 #define lpfc_mbox_hdr_version_MASK	0x000000FF
 #define lpfc_mbox_hdr_version_WORD	word9
+#define lpfc_mbox_hdr_pf_num_SHIFT	16
+#define lpfc_mbox_hdr_pf_num_MASK	0x000000FF
+#define lpfc_mbox_hdr_pf_num_WORD	word9
+#define lpfc_mbox_hdr_vh_num_SHIFT	24
+#define lpfc_mbox_hdr_vh_num_MASK	0x000000FF
+#define lpfc_mbox_hdr_vh_num_WORD	word9
 #define LPFC_Q_CREATE_VERSION_2	2
 #define LPFC_Q_CREATE_VERSION_1	1
 #define LPFC_Q_CREATE_VERSION_0	0
@@ -766,12 +808,22 @@
 	} response;
 };
 
-/* Mailbox structures */
+/* Mailbox Header structures.
+ * struct mbox_header is defined for first generation SLI4_CFG mailbox
+ * calls deployed for BE-based ports.
+ *
+ * struct sli4_mbox_header is defined for second generation SLI4
+ * ports that don't deploy the SLI4_CFG mechanism.
+ */
 struct mbox_header {
 	struct lpfc_sli4_cfg_mhdr cfg_mhdr;
 	union  lpfc_sli4_cfg_shdr cfg_shdr;
 };
 
+#define LPFC_EXTENT_LOCAL		0
+#define LPFC_TIMEOUT_DEFAULT		0
+#define LPFC_EXTENT_VERSION_DEFAULT	0
+
 /* Subsystem Definitions */
 #define LPFC_MBOX_SUBSYSTEM_COMMON	0x1
 #define LPFC_MBOX_SUBSYSTEM_FCOE	0xC
@@ -794,6 +846,13 @@
 #define LPFC_MBOX_OPCODE_QUERY_FW_CFG		0x3A
 #define LPFC_MBOX_OPCODE_FUNCTION_RESET		0x3D
 #define LPFC_MBOX_OPCODE_MQ_CREATE_EXT		0x5A
+#define LPFC_MBOX_OPCODE_GET_RSRC_EXTENT_INFO	0x9A
+#define LPFC_MBOX_OPCODE_GET_ALLOC_RSRC_EXTENT	0x9B
+#define LPFC_MBOX_OPCODE_ALLOC_RSRC_EXTENT	0x9C
+#define LPFC_MBOX_OPCODE_DEALLOC_RSRC_EXTENT	0x9D
+#define LPFC_MBOX_OPCODE_GET_FUNCTION_CONFIG    0xA0
+#define LPFC_MBOX_OPCODE_GET_PROFILE_CONFIG	0xA4
+#define LPFC_MBOX_OPCODE_WRITE_OBJECT		0xAC
 #define LPFC_MBOX_OPCODE_GET_SLI4_PARAMETERS	0xB5
 
 /* FCoE Opcodes */
@@ -808,6 +867,8 @@
 #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
+#define LPFC_MBOX_OPCODE_FCOE_LINK_DIAG_STATE		0x22
+#define LPFC_MBOX_OPCODE_FCOE_LINK_DIAG_LOOPBACK	0x23
 
 /* Mailbox command structures */
 struct eq_context {
@@ -1059,6 +1120,11 @@
 #define lpfc_rq_context_rqe_size_SHIFT	8		/* Version 1 Only */
 #define lpfc_rq_context_rqe_size_MASK	0x0000000F
 #define lpfc_rq_context_rqe_size_WORD	word0
+#define LPFC_RQE_SIZE_8		2
+#define LPFC_RQE_SIZE_16	3
+#define LPFC_RQE_SIZE_32	4
+#define LPFC_RQE_SIZE_64	5
+#define LPFC_RQE_SIZE_128	6
 #define lpfc_rq_context_page_size_SHIFT	0		/* Version 1 Only */
 #define lpfc_rq_context_page_size_MASK	0x000000FF
 #define lpfc_rq_context_page_size_WORD	word0
@@ -1205,6 +1271,187 @@
 	} u;
 };
 
+/* Start Gen 2 SLI4 Mailbox definitions: */
+
+/* Define allocate-ready Gen 2 SLI4 FCoE Resource Extent Types. */
+#define LPFC_RSC_TYPE_FCOE_VFI	0x20
+#define LPFC_RSC_TYPE_FCOE_VPI	0x21
+#define LPFC_RSC_TYPE_FCOE_RPI	0x22
+#define LPFC_RSC_TYPE_FCOE_XRI	0x23
+
+struct lpfc_mbx_get_rsrc_extent_info {
+	struct mbox_header header;
+	union {
+		struct {
+			uint32_t word4;
+#define lpfc_mbx_get_rsrc_extent_info_type_SHIFT	0
+#define lpfc_mbx_get_rsrc_extent_info_type_MASK		0x0000FFFF
+#define lpfc_mbx_get_rsrc_extent_info_type_WORD		word4
+		} req;
+		struct {
+			uint32_t word4;
+#define lpfc_mbx_get_rsrc_extent_info_cnt_SHIFT		0
+#define lpfc_mbx_get_rsrc_extent_info_cnt_MASK		0x0000FFFF
+#define lpfc_mbx_get_rsrc_extent_info_cnt_WORD		word4
+#define lpfc_mbx_get_rsrc_extent_info_size_SHIFT	16
+#define lpfc_mbx_get_rsrc_extent_info_size_MASK		0x0000FFFF
+#define lpfc_mbx_get_rsrc_extent_info_size_WORD		word4
+		} rsp;
+	} u;
+};
+
+struct lpfc_id_range {
+	uint32_t word5;
+#define lpfc_mbx_rsrc_id_word4_0_SHIFT	0
+#define lpfc_mbx_rsrc_id_word4_0_MASK	0x0000FFFF
+#define lpfc_mbx_rsrc_id_word4_0_WORD	word5
+#define lpfc_mbx_rsrc_id_word4_1_SHIFT	16
+#define lpfc_mbx_rsrc_id_word4_1_MASK	0x0000FFFF
+#define lpfc_mbx_rsrc_id_word4_1_WORD	word5
+};
+
+struct lpfc_mbx_set_link_diag_state {
+	struct mbox_header header;
+	union {
+		struct {
+			uint32_t word0;
+#define lpfc_mbx_set_diag_state_diag_SHIFT	0
+#define lpfc_mbx_set_diag_state_diag_MASK	0x00000001
+#define lpfc_mbx_set_diag_state_diag_WORD	word0
+#define lpfc_mbx_set_diag_state_link_num_SHIFT	16
+#define lpfc_mbx_set_diag_state_link_num_MASK	0x0000003F
+#define lpfc_mbx_set_diag_state_link_num_WORD	word0
+#define lpfc_mbx_set_diag_state_link_type_SHIFT 22
+#define lpfc_mbx_set_diag_state_link_type_MASK	0x00000003
+#define lpfc_mbx_set_diag_state_link_type_WORD	word0
+		} req;
+		struct {
+			uint32_t word0;
+		} rsp;
+	} u;
+};
+
+struct lpfc_mbx_set_link_diag_loopback {
+	struct mbox_header header;
+	union {
+		struct {
+			uint32_t word0;
+#define lpfc_mbx_set_diag_lpbk_type_SHIFT	0
+#define lpfc_mbx_set_diag_lpbk_type_MASK	0x00000001
+#define lpfc_mbx_set_diag_lpbk_type_WORD	word0
+#define LPFC_DIAG_LOOPBACK_TYPE_DISABLE		0x0
+#define LPFC_DIAG_LOOPBACK_TYPE_INTERNAL	0x1
+#define LPFC_DIAG_LOOPBACK_TYPE_EXTERNAL	0x2
+#define lpfc_mbx_set_diag_lpbk_link_num_SHIFT	16
+#define lpfc_mbx_set_diag_lpbk_link_num_MASK	0x0000003F
+#define lpfc_mbx_set_diag_lpbk_link_num_WORD	word0
+#define lpfc_mbx_set_diag_lpbk_link_type_SHIFT	22
+#define lpfc_mbx_set_diag_lpbk_link_type_MASK	0x00000003
+#define lpfc_mbx_set_diag_lpbk_link_type_WORD	word0
+		} req;
+		struct {
+			uint32_t word0;
+		} rsp;
+	} u;
+};
+
+struct lpfc_mbx_run_link_diag_test {
+	struct mbox_header header;
+	union {
+		struct {
+			uint32_t word0;
+#define lpfc_mbx_run_diag_test_link_num_SHIFT	16
+#define lpfc_mbx_run_diag_test_link_num_MASK	0x0000003F
+#define lpfc_mbx_run_diag_test_link_num_WORD	word0
+#define lpfc_mbx_run_diag_test_link_type_SHIFT	22
+#define lpfc_mbx_run_diag_test_link_type_MASK	0x00000003
+#define lpfc_mbx_run_diag_test_link_type_WORD	word0
+			uint32_t word1;
+#define lpfc_mbx_run_diag_test_test_id_SHIFT	0
+#define lpfc_mbx_run_diag_test_test_id_MASK	0x0000FFFF
+#define lpfc_mbx_run_diag_test_test_id_WORD	word1
+#define lpfc_mbx_run_diag_test_loops_SHIFT	16
+#define lpfc_mbx_run_diag_test_loops_MASK	0x0000FFFF
+#define lpfc_mbx_run_diag_test_loops_WORD	word1
+			uint32_t word2;
+#define lpfc_mbx_run_diag_test_test_ver_SHIFT	0
+#define lpfc_mbx_run_diag_test_test_ver_MASK	0x0000FFFF
+#define lpfc_mbx_run_diag_test_test_ver_WORD	word2
+#define lpfc_mbx_run_diag_test_err_act_SHIFT	16
+#define lpfc_mbx_run_diag_test_err_act_MASK	0x000000FF
+#define lpfc_mbx_run_diag_test_err_act_WORD	word2
+		} req;
+		struct {
+			uint32_t word0;
+		} rsp;
+	} u;
+};
+
+/*
+ * struct lpfc_mbx_alloc_rsrc_extents:
+ * A mbox is generically 256 bytes long. An SLI4_CONFIG mailbox requires
+ * 6 words of header + 4 words of shared subcommand header +
+ * 1 words of Extent-Opcode-specific header = 11 words or 44 bytes total.
+ *
+ * An embedded version of SLI4_CONFIG therefore has 256 - 44 = 212 bytes
+ * for extents payload.
+ *
+ * 212/2 (bytes per extent) = 106 extents.
+ * 106/2 (extents per word) = 53 words.
+ * lpfc_id_range id is statically size to 53.
+ *
+ * This mailbox definition is used for ALLOC or GET_ALLOCATED
+ * extent ranges.  For ALLOC, the type and cnt are required.
+ * For GET_ALLOCATED, only the type is required.
+ */
+struct lpfc_mbx_alloc_rsrc_extents {
+	struct mbox_header header;
+	union {
+		struct {
+			uint32_t word4;
+#define lpfc_mbx_alloc_rsrc_extents_type_SHIFT	0
+#define lpfc_mbx_alloc_rsrc_extents_type_MASK	0x0000FFFF
+#define lpfc_mbx_alloc_rsrc_extents_type_WORD	word4
+#define lpfc_mbx_alloc_rsrc_extents_cnt_SHIFT	16
+#define lpfc_mbx_alloc_rsrc_extents_cnt_MASK	0x0000FFFF
+#define lpfc_mbx_alloc_rsrc_extents_cnt_WORD	word4
+		} req;
+		struct {
+			uint32_t word4;
+#define lpfc_mbx_rsrc_cnt_SHIFT	0
+#define lpfc_mbx_rsrc_cnt_MASK	0x0000FFFF
+#define lpfc_mbx_rsrc_cnt_WORD	word4
+			struct lpfc_id_range id[53];
+		} rsp;
+	} u;
+};
+
+/*
+ * This is the non-embedded version of ALLOC or GET RSRC_EXTENTS. Word4 in this
+ * structure shares the same SHIFT/MASK/WORD defines provided in the
+ * mbx_alloc_rsrc_extents and mbx_get_alloc_rsrc_extents, word4, provided in
+ * the structures defined above.  This non-embedded structure provides for the
+ * maximum number of extents supported by the port.
+ */
+struct lpfc_mbx_nembed_rsrc_extent {
+	union  lpfc_sli4_cfg_shdr cfg_shdr;
+	uint32_t word4;
+	struct lpfc_id_range id;
+};
+
+struct lpfc_mbx_dealloc_rsrc_extents {
+	struct mbox_header header;
+	struct {
+		uint32_t word4;
+#define lpfc_mbx_dealloc_rsrc_extents_type_SHIFT	0
+#define lpfc_mbx_dealloc_rsrc_extents_type_MASK		0x0000FFFF
+#define lpfc_mbx_dealloc_rsrc_extents_type_WORD		word4
+	} req;
+
+};
+
+/* Start SLI4 FCoE specific mbox structures. */
+
 struct lpfc_mbx_post_hdr_tmpl {
 	struct mbox_header header;
 	uint32_t word10;
@@ -1224,7 +1471,7 @@
 
 	uint32_t word2;
 #define lpfc_sli4_sge_offset_SHIFT	0 /* Offset of buffer - Not used*/
-#define lpfc_sli4_sge_offset_MASK	0x00FFFFFF
+#define lpfc_sli4_sge_offset_MASK	0x1FFFFFFF
 #define lpfc_sli4_sge_offset_WORD	word2
 #define lpfc_sli4_sge_last_SHIFT	31 /* Last SEG in the SGL sets
 						this  flag !! */
@@ -1768,61 +2015,31 @@
 
 struct lpfc_mbx_read_config {
 	uint32_t word1;
-#define lpfc_mbx_rd_conf_max_bbc_SHIFT		0
-#define lpfc_mbx_rd_conf_max_bbc_MASK		0x000000FF
-#define lpfc_mbx_rd_conf_max_bbc_WORD		word1
-#define lpfc_mbx_rd_conf_init_bbc_SHIFT		8
-#define lpfc_mbx_rd_conf_init_bbc_MASK		0x000000FF
-#define lpfc_mbx_rd_conf_init_bbc_WORD		word1
+#define lpfc_mbx_rd_conf_extnts_inuse_SHIFT	31
+#define lpfc_mbx_rd_conf_extnts_inuse_MASK	0x00000001
+#define lpfc_mbx_rd_conf_extnts_inuse_WORD	word1
 	uint32_t word2;
-#define lpfc_mbx_rd_conf_nport_did_SHIFT	0
-#define lpfc_mbx_rd_conf_nport_did_MASK		0x00FFFFFF
-#define lpfc_mbx_rd_conf_nport_did_WORD		word2
 #define lpfc_mbx_rd_conf_topology_SHIFT		24
 #define lpfc_mbx_rd_conf_topology_MASK		0x000000FF
 #define lpfc_mbx_rd_conf_topology_WORD		word2
-	uint32_t word3;
-#define lpfc_mbx_rd_conf_ao_SHIFT		0
-#define lpfc_mbx_rd_conf_ao_MASK		0x00000001
-#define lpfc_mbx_rd_conf_ao_WORD		word3
-#define lpfc_mbx_rd_conf_bb_scn_SHIFT		8
-#define lpfc_mbx_rd_conf_bb_scn_MASK		0x0000000F
-#define lpfc_mbx_rd_conf_bb_scn_WORD		word3
-#define lpfc_mbx_rd_conf_cbb_scn_SHIFT		12
-#define lpfc_mbx_rd_conf_cbb_scn_MASK		0x0000000F
-#define lpfc_mbx_rd_conf_cbb_scn_WORD		word3
-#define lpfc_mbx_rd_conf_mc_SHIFT		29
-#define lpfc_mbx_rd_conf_mc_MASK		0x00000001
-#define lpfc_mbx_rd_conf_mc_WORD		word3
+	uint32_t rsvd_3;
 	uint32_t word4;
 #define lpfc_mbx_rd_conf_e_d_tov_SHIFT		0
 #define lpfc_mbx_rd_conf_e_d_tov_MASK		0x0000FFFF
 #define lpfc_mbx_rd_conf_e_d_tov_WORD		word4
-	uint32_t word5;
-#define lpfc_mbx_rd_conf_lp_tov_SHIFT		0
-#define lpfc_mbx_rd_conf_lp_tov_MASK		0x0000FFFF
-#define lpfc_mbx_rd_conf_lp_tov_WORD		word5
+	uint32_t rsvd_5;
 	uint32_t word6;
 #define lpfc_mbx_rd_conf_r_a_tov_SHIFT		0
 #define lpfc_mbx_rd_conf_r_a_tov_MASK		0x0000FFFF
 #define lpfc_mbx_rd_conf_r_a_tov_WORD		word6
-	uint32_t word7;
-#define lpfc_mbx_rd_conf_r_t_tov_SHIFT		0
-#define lpfc_mbx_rd_conf_r_t_tov_MASK		0x000000FF
-#define lpfc_mbx_rd_conf_r_t_tov_WORD		word7
-	uint32_t word8;
-#define lpfc_mbx_rd_conf_al_tov_SHIFT		0
-#define lpfc_mbx_rd_conf_al_tov_MASK		0x0000000F
-#define lpfc_mbx_rd_conf_al_tov_WORD		word8
+	uint32_t rsvd_7;
+	uint32_t rsvd_8;
 	uint32_t word9;
 #define lpfc_mbx_rd_conf_lmt_SHIFT		0
 #define lpfc_mbx_rd_conf_lmt_MASK		0x0000FFFF
 #define lpfc_mbx_rd_conf_lmt_WORD		word9
-	uint32_t word10;
-#define lpfc_mbx_rd_conf_max_alpa_SHIFT		0
-#define lpfc_mbx_rd_conf_max_alpa_MASK		0x000000FF
-#define lpfc_mbx_rd_conf_max_alpa_WORD		word10
-	uint32_t word11_rsvd;
+	uint32_t rsvd_10;
+	uint32_t rsvd_11;
 	uint32_t word12;
 #define lpfc_mbx_rd_conf_xri_base_SHIFT		0
 #define lpfc_mbx_rd_conf_xri_base_MASK		0x0000FFFF
@@ -1852,9 +2069,6 @@
 #define lpfc_mbx_rd_conf_vfi_count_MASK         0x0000FFFF
 #define lpfc_mbx_rd_conf_vfi_count_WORD         word15
 	uint32_t word16;
-#define lpfc_mbx_rd_conf_fcfi_base_SHIFT	0
-#define lpfc_mbx_rd_conf_fcfi_base_MASK		0x0000FFFF
-#define lpfc_mbx_rd_conf_fcfi_base_WORD		word16
 #define lpfc_mbx_rd_conf_fcfi_count_SHIFT	16
 #define lpfc_mbx_rd_conf_fcfi_count_MASK	0x0000FFFF
 #define lpfc_mbx_rd_conf_fcfi_count_WORD	word16
@@ -2108,6 +2322,8 @@
 #define sgl_pp_align_WORD			word12
 	uint32_t rsvd_13_63[51];
 };
+#define SLI4_PAGE_ALIGN(addr) (((addr)+((SLI4_PAGE_SIZE)-1)) \
+			       &(~((SLI4_PAGE_SIZE)-1)))
 
 struct lpfc_sli4_parameters {
 	uint32_t word0;
@@ -2162,6 +2378,12 @@
 #define cfg_fcoe_SHIFT				0
 #define cfg_fcoe_MASK				0x00000001
 #define cfg_fcoe_WORD				word12
+#define cfg_ext_SHIFT				1
+#define cfg_ext_MASK				0x00000001
+#define cfg_ext_WORD				word12
+#define cfg_hdrr_SHIFT				2
+#define cfg_hdrr_MASK				0x00000001
+#define cfg_hdrr_WORD				word12
 #define cfg_phwq_SHIFT				15
 #define cfg_phwq_MASK				0x00000001
 #define cfg_phwq_WORD				word12
@@ -2191,6 +2413,145 @@
 	struct lpfc_sli4_parameters sli4_parameters;
 };
 
+struct lpfc_rscr_desc_generic {
+#define LPFC_RSRC_DESC_WSIZE			18
+	uint32_t desc[LPFC_RSRC_DESC_WSIZE];
+};
+
+struct lpfc_rsrc_desc_pcie {
+	uint32_t word0;
+#define lpfc_rsrc_desc_pcie_type_SHIFT		0
+#define lpfc_rsrc_desc_pcie_type_MASK		0x000000ff
+#define lpfc_rsrc_desc_pcie_type_WORD		word0
+#define LPFC_RSRC_DESC_TYPE_PCIE		0x40
+	uint32_t word1;
+#define lpfc_rsrc_desc_pcie_pfnum_SHIFT		0
+#define lpfc_rsrc_desc_pcie_pfnum_MASK		0x000000ff
+#define lpfc_rsrc_desc_pcie_pfnum_WORD		word1
+	uint32_t reserved;
+	uint32_t word3;
+#define lpfc_rsrc_desc_pcie_sriov_sta_SHIFT	0
+#define lpfc_rsrc_desc_pcie_sriov_sta_MASK	0x000000ff
+#define lpfc_rsrc_desc_pcie_sriov_sta_WORD	word3
+#define lpfc_rsrc_desc_pcie_pf_sta_SHIFT	8
+#define lpfc_rsrc_desc_pcie_pf_sta_MASK		0x000000ff
+#define lpfc_rsrc_desc_pcie_pf_sta_WORD		word3
+#define lpfc_rsrc_desc_pcie_pf_type_SHIFT	16
+#define lpfc_rsrc_desc_pcie_pf_type_MASK	0x000000ff
+#define lpfc_rsrc_desc_pcie_pf_type_WORD	word3
+	uint32_t word4;
+#define lpfc_rsrc_desc_pcie_nr_virtfn_SHIFT	0
+#define lpfc_rsrc_desc_pcie_nr_virtfn_MASK	0x0000ffff
+#define lpfc_rsrc_desc_pcie_nr_virtfn_WORD	word4
+};
+
+struct lpfc_rsrc_desc_fcfcoe {
+	uint32_t word0;
+#define lpfc_rsrc_desc_fcfcoe_type_SHIFT	0
+#define lpfc_rsrc_desc_fcfcoe_type_MASK		0x000000ff
+#define lpfc_rsrc_desc_fcfcoe_type_WORD		word0
+#define LPFC_RSRC_DESC_TYPE_FCFCOE		0x43
+	uint32_t word1;
+#define lpfc_rsrc_desc_fcfcoe_vfnum_SHIFT	0
+#define lpfc_rsrc_desc_fcfcoe_vfnum_MASK	0x000000ff
+#define lpfc_rsrc_desc_fcfcoe_vfnum_WORD	word1
+#define lpfc_rsrc_desc_fcfcoe_pfnum_SHIFT	16
+#define lpfc_rsrc_desc_fcfcoe_pfnum_MASK        0x000007ff
+#define lpfc_rsrc_desc_fcfcoe_pfnum_WORD        word1
+	uint32_t word2;
+#define lpfc_rsrc_desc_fcfcoe_rpi_cnt_SHIFT	0
+#define lpfc_rsrc_desc_fcfcoe_rpi_cnt_MASK	0x0000ffff
+#define lpfc_rsrc_desc_fcfcoe_rpi_cnt_WORD	word2
+#define lpfc_rsrc_desc_fcfcoe_xri_cnt_SHIFT	16
+#define lpfc_rsrc_desc_fcfcoe_xri_cnt_MASK	0x0000ffff
+#define lpfc_rsrc_desc_fcfcoe_xri_cnt_WORD	word2
+	uint32_t word3;
+#define lpfc_rsrc_desc_fcfcoe_wq_cnt_SHIFT	0
+#define lpfc_rsrc_desc_fcfcoe_wq_cnt_MASK	0x0000ffff
+#define lpfc_rsrc_desc_fcfcoe_wq_cnt_WORD	word3
+#define lpfc_rsrc_desc_fcfcoe_rq_cnt_SHIFT	16
+#define lpfc_rsrc_desc_fcfcoe_rq_cnt_MASK	0x0000ffff
+#define lpfc_rsrc_desc_fcfcoe_rq_cnt_WORD	word3
+	uint32_t word4;
+#define lpfc_rsrc_desc_fcfcoe_cq_cnt_SHIFT	0
+#define lpfc_rsrc_desc_fcfcoe_cq_cnt_MASK	0x0000ffff
+#define lpfc_rsrc_desc_fcfcoe_cq_cnt_WORD	word4
+#define lpfc_rsrc_desc_fcfcoe_vpi_cnt_SHIFT	16
+#define lpfc_rsrc_desc_fcfcoe_vpi_cnt_MASK	0x0000ffff
+#define lpfc_rsrc_desc_fcfcoe_vpi_cnt_WORD	word4
+	uint32_t word5;
+#define lpfc_rsrc_desc_fcfcoe_fcfi_cnt_SHIFT	0
+#define lpfc_rsrc_desc_fcfcoe_fcfi_cnt_MASK	0x0000ffff
+#define lpfc_rsrc_desc_fcfcoe_fcfi_cnt_WORD	word5
+#define lpfc_rsrc_desc_fcfcoe_vfi_cnt_SHIFT	16
+#define lpfc_rsrc_desc_fcfcoe_vfi_cnt_MASK	0x0000ffff
+#define lpfc_rsrc_desc_fcfcoe_vfi_cnt_WORD	word5
+	uint32_t word6;
+	uint32_t word7;
+	uint32_t word8;
+	uint32_t word9;
+	uint32_t word10;
+	uint32_t word11;
+	uint32_t word12;
+	uint32_t word13;
+#define lpfc_rsrc_desc_fcfcoe_lnk_nr_SHIFT	0
+#define lpfc_rsrc_desc_fcfcoe_lnk_nr_MASK	0x0000003f
+#define lpfc_rsrc_desc_fcfcoe_lnk_nr_WORD	word13
+#define lpfc_rsrc_desc_fcfcoe_lnk_tp_SHIFT      6
+#define lpfc_rsrc_desc_fcfcoe_lnk_tp_MASK	0x00000003
+#define lpfc_rsrc_desc_fcfcoe_lnk_tp_WORD	word13
+#define lpfc_rsrc_desc_fcfcoe_lmc_SHIFT		8
+#define lpfc_rsrc_desc_fcfcoe_lmc_MASK		0x00000001
+#define lpfc_rsrc_desc_fcfcoe_lmc_WORD		word13
+#define lpfc_rsrc_desc_fcfcoe_lld_SHIFT		9
+#define lpfc_rsrc_desc_fcfcoe_lld_MASK		0x00000001
+#define lpfc_rsrc_desc_fcfcoe_lld_WORD		word13
+#define lpfc_rsrc_desc_fcfcoe_eq_cnt_SHIFT	16
+#define lpfc_rsrc_desc_fcfcoe_eq_cnt_MASK	0x0000ffff
+#define lpfc_rsrc_desc_fcfcoe_eq_cnt_WORD	word13
+};
+
+struct lpfc_func_cfg {
+#define LPFC_RSRC_DESC_MAX_NUM			2
+	uint32_t rsrc_desc_count;
+	struct lpfc_rscr_desc_generic desc[LPFC_RSRC_DESC_MAX_NUM];
+};
+
+struct lpfc_mbx_get_func_cfg {
+	struct mbox_header header;
+#define LPFC_CFG_TYPE_PERSISTENT_OVERRIDE	0x0
+#define LPFC_CFG_TYPE_FACTURY_DEFAULT		0x1
+#define LPFC_CFG_TYPE_CURRENT_ACTIVE		0x2
+	struct lpfc_func_cfg func_cfg;
+};
+
+struct lpfc_prof_cfg {
+#define LPFC_RSRC_DESC_MAX_NUM			2
+	uint32_t rsrc_desc_count;
+	struct lpfc_rscr_desc_generic desc[LPFC_RSRC_DESC_MAX_NUM];
+};
+
+struct lpfc_mbx_get_prof_cfg {
+	struct mbox_header header;
+#define LPFC_CFG_TYPE_PERSISTENT_OVERRIDE	0x0
+#define LPFC_CFG_TYPE_FACTURY_DEFAULT		0x1
+#define LPFC_CFG_TYPE_CURRENT_ACTIVE		0x2
+	union {
+		struct {
+			uint32_t word10;
+#define lpfc_mbx_get_prof_cfg_prof_id_SHIFT	0
+#define lpfc_mbx_get_prof_cfg_prof_id_MASK	0x000000ff
+#define lpfc_mbx_get_prof_cfg_prof_id_WORD	word10
+#define lpfc_mbx_get_prof_cfg_prof_tp_SHIFT	8
+#define lpfc_mbx_get_prof_cfg_prof_tp_MASK	0x00000003
+#define lpfc_mbx_get_prof_cfg_prof_tp_WORD	word10
+		} request;
+		struct {
+			struct lpfc_prof_cfg prof_cfg;
+		} response;
+	} u;
+};
+
 /* Mailbox Completion Queue Error Messages */
 #define MB_CQE_STATUS_SUCCESS 			0x0
 #define MB_CQE_STATUS_INSUFFICIENT_PRIVILEGES	0x1
@@ -2199,6 +2560,29 @@
 #define MB_CEQ_STATUS_QUEUE_FLUSHING		0x4
 #define MB_CQE_STATUS_DMA_FAILED		0x5
 
+#define LPFC_MBX_WR_CONFIG_MAX_BDE		8
+struct lpfc_mbx_wr_object {
+	struct mbox_header header;
+	union {
+		struct {
+			uint32_t word4;
+#define lpfc_wr_object_eof_SHIFT		31
+#define lpfc_wr_object_eof_MASK			0x00000001
+#define lpfc_wr_object_eof_WORD			word4
+#define lpfc_wr_object_write_length_SHIFT	0
+#define lpfc_wr_object_write_length_MASK	0x00FFFFFF
+#define lpfc_wr_object_write_length_WORD	word4
+			uint32_t write_offset;
+			uint32_t object_name[26];
+			uint32_t bde_count;
+			struct ulp_bde64 bde[LPFC_MBX_WR_CONFIG_MAX_BDE];
+		} request;
+		struct {
+			uint32_t actual_write_length;
+		} response;
+	} u;
+};
+
 /* mailbox queue entry structure */
 struct lpfc_mqe {
 	uint32_t word0;
@@ -2234,6 +2618,9 @@
 		struct lpfc_mbx_cq_destroy cq_destroy;
 		struct lpfc_mbx_wq_destroy wq_destroy;
 		struct lpfc_mbx_rq_destroy rq_destroy;
+		struct lpfc_mbx_get_rsrc_extent_info rsrc_extent_info;
+		struct lpfc_mbx_alloc_rsrc_extents alloc_rsrc_extents;
+		struct lpfc_mbx_dealloc_rsrc_extents dealloc_rsrc_extents;
 		struct lpfc_mbx_post_sgl_pages post_sgl_pages;
 		struct lpfc_mbx_nembed_cmd nembed_cmd;
 		struct lpfc_mbx_read_rev read_rev;
@@ -2245,7 +2632,13 @@
 		struct lpfc_mbx_supp_pages supp_pages;
 		struct lpfc_mbx_pc_sli4_params sli4_params;
 		struct lpfc_mbx_get_sli4_parameters get_sli4_parameters;
+		struct lpfc_mbx_set_link_diag_state link_diag_state;
+		struct lpfc_mbx_set_link_diag_loopback link_diag_loopback;
+		struct lpfc_mbx_run_link_diag_test link_diag_test;
+		struct lpfc_mbx_get_func_cfg get_func_cfg;
+		struct lpfc_mbx_get_prof_cfg get_prof_cfg;
 		struct lpfc_mbx_nop nop;
+		struct lpfc_mbx_wr_object wr_object;
 	} un;
 };
 
@@ -2451,7 +2844,7 @@
 #define SGL_ALIGN_SZ 64
 #define SGL_PAGE_SIZE 4096
 /* align SGL addr on a size boundary - adjust address up */
-#define NO_XRI  ((uint16_t)-1)
+#define NO_XRI  0xffff
 
 struct wqe_common {
 	uint32_t word6;
@@ -2491,6 +2884,9 @@
 #define wqe_reqtag_SHIFT      0
 #define wqe_reqtag_MASK       0x0000FFFF
 #define wqe_reqtag_WORD       word9
+#define wqe_temp_rpi_SHIFT    16
+#define wqe_temp_rpi_MASK     0x0000FFFF
+#define wqe_temp_rpi_WORD     word9
 #define wqe_rcvoxid_SHIFT     16
 #define wqe_rcvoxid_MASK      0x0000FFFF
 #define wqe_rcvoxid_WORD      word9
@@ -2524,7 +2920,7 @@
 #define wqe_wqes_WORD         word10
 /* Note that this field overlaps above fields */
 #define wqe_wqid_SHIFT        1
-#define wqe_wqid_MASK         0x0000007f
+#define wqe_wqid_MASK         0x00007fff
 #define wqe_wqid_WORD         word10
 #define wqe_pri_SHIFT         16
 #define wqe_pri_MASK          0x00000007
@@ -2621,7 +3017,11 @@
 	uint32_t rsvd4;
 	struct wqe_did wqe_dest;
 	struct wqe_common wqe_com; /* words 6-11 */
-	uint32_t rsvd_12_15[4];
+	uint32_t word12;
+#define wqe_rsp_temp_rpi_SHIFT    0
+#define wqe_rsp_temp_rpi_MASK     0x0000FFFF
+#define wqe_rsp_temp_rpi_WORD     word12
+	uint32_t rsvd_13_15[3];
 };
 
 struct xmit_bls_rsp64_wqe {
@@ -2784,9 +3184,28 @@
 	struct gen_req64_wqe gen_req;
 };
 
+#define LPFC_GROUP_OJECT_MAGIC_NUM		0xfeaa0001
+#define LPFC_FILE_TYPE_GROUP			0xf7
+#define LPFC_FILE_ID_GROUP			0xa2
+struct lpfc_grp_hdr {
+	uint32_t size;
+	uint32_t magic_number;
+	uint32_t word2;
+#define lpfc_grp_hdr_file_type_SHIFT	24
+#define lpfc_grp_hdr_file_type_MASK	0x000000FF
+#define lpfc_grp_hdr_file_type_WORD	word2
+#define lpfc_grp_hdr_id_SHIFT		16
+#define lpfc_grp_hdr_id_MASK		0x000000FF
+#define lpfc_grp_hdr_id_WORD		word2
+	uint8_t rev_name[128];
+};
+
 #define FCP_COMMAND 0x0
 #define FCP_COMMAND_DATA_OUT 0x1
 #define ELS_COMMAND_NON_FIP 0xC
 #define ELS_COMMAND_FIP 0xD
 #define OTHER_COMMAND 0x8
 
+#define LPFC_FW_DUMP	1
+#define LPFC_FW_RESET	2
+#define LPFC_DV_RESET	3
diff -druN linux-2.6.39-libre/drivers/scsi/lpfc/lpfc_hw.h linux-3.0-rc7-libre/drivers/scsi/lpfc/lpfc_hw.h
--- linux-2.6.39-libre/drivers/scsi/lpfc/lpfc_hw.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/scsi/lpfc/lpfc_hw.h	2011-07-11 19:51:52.000000000 -0400
@@ -64,6 +64,8 @@
 #define SLI3_IOCB_CMD_SIZE	128
 #define SLI3_IOCB_RSP_SIZE	64
 
+#define LPFC_UNREG_ALL_RPIS_VPORT	0xffff
+#define LPFC_UNREG_ALL_DFLT_RPIS	0xffffffff
 
 /* vendor ID used in SCSI netlink calls */
 #define LPFC_NL_VENDOR_ID (SCSI_NL_VID_TYPE_PCI | PCI_VENDOR_ID_EMULEX)
@@ -903,6 +905,8 @@
 #define rrq_rxid_WORD		rrq_exchg
 };
 
+#define LPFC_MAX_VFN_PER_PFN	255 /* Maximum VFs allowed per ARI */
+#define LPFC_DEF_VFN_PER_PFN	0   /* Default VFs due to platform limitation*/
 
 struct RTV_RSP {		/* Structure is in Big Endian format */
 	uint32_t ratov;
@@ -1002,7 +1006,7 @@
 #define  SLI_MGMT_GRPL     0x102	/* Get registered Port list */
 #define  SLI_MGMT_GPAT     0x110	/* Get Port attributes */
 #define  SLI_MGMT_RHBA     0x200	/* Register HBA */
-#define  SLI_MGMT_RHAT     0x201	/* Register HBA atttributes */
+#define  SLI_MGMT_RHAT     0x201	/* Register HBA attributes */
 #define  SLI_MGMT_RPRT     0x210	/* Register Port */
 #define  SLI_MGMT_RPA      0x211	/* Register Port attributes */
 #define  SLI_MGMT_DHBA     0x300	/* De-register HBA */
@@ -1199,7 +1203,9 @@
 #define PCI_DEVICE_ID_BALIUS        0xe131
 #define PCI_DEVICE_ID_PROTEUS_PF    0xe180
 #define PCI_DEVICE_ID_LANCER_FC     0xe200
+#define PCI_DEVICE_ID_LANCER_FC_VF  0xe208
 #define PCI_DEVICE_ID_LANCER_FCOE   0xe260
+#define PCI_DEVICE_ID_LANCER_FCOE_VF 0xe268
 #define PCI_DEVICE_ID_SAT_SMB       0xf011
 #define PCI_DEVICE_ID_SAT_MID       0xf015
 #define PCI_DEVICE_ID_RFLY          0xf095
@@ -3021,7 +3027,7 @@
 #define MAILBOX_EXT_SIZE	(MAILBOX_EXT_WSIZE * sizeof(uint32_t))
 #define MAILBOX_HBA_EXT_OFFSET  0x100
 /* max mbox xmit size is a page size for sysfs IO operations */
-#define MAILBOX_MAX_XMIT_SIZE   PAGE_SIZE
+#define MAILBOX_SYSFS_MAX	4096
 
 typedef union {
 	uint32_t varWords[MAILBOX_CMD_WSIZE - 1]; /* first word is type/
diff -druN linux-2.6.39-libre/drivers/scsi/lpfc/lpfc_init.c linux-3.0-rc7-libre/drivers/scsi/lpfc/lpfc_init.c
--- linux-2.6.39-libre/drivers/scsi/lpfc/lpfc_init.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/scsi/lpfc/lpfc_init.c	2011-07-21 06:59:51.000000000 -0400
@@ -30,6 +30,7 @@
 #include <linux/ctype.h>
 #include <linux/aer.h>
 #include <linux/slab.h>
+#include <linux/firmware.h>
 
 #include <scsi/scsi.h>
 #include <scsi/scsi_device.h>
@@ -211,7 +212,6 @@
 	lpfc_vpd_data = kmalloc(DMP_VPD_SIZE, GFP_KERNEL);
 	if (!lpfc_vpd_data)
 		goto out_free_mbox;
-
 	do {
 		lpfc_dump_mem(phba, pmb, offset, DMP_REGION_VPD);
 		rc = lpfc_sli_issue_mbox(phba, pmb, MBX_POLL);
@@ -309,6 +309,45 @@
 }
 
 /**
+ * lpfc_update_vport_wwn - Updates the fc_nodename, fc_portname,
+ *	cfg_soft_wwnn, cfg_soft_wwpn
+ * @vport: pointer to lpfc vport data structure.
+ *
+ *
+ * Return codes
+ *   None.
+ **/
+void
+lpfc_update_vport_wwn(struct lpfc_vport *vport)
+{
+	/* If the soft name exists then update it using the service params */
+	if (vport->phba->cfg_soft_wwnn)
+		u64_to_wwn(vport->phba->cfg_soft_wwnn,
+			   vport->fc_sparam.nodeName.u.wwn);
+	if (vport->phba->cfg_soft_wwpn)
+		u64_to_wwn(vport->phba->cfg_soft_wwpn,
+			   vport->fc_sparam.portName.u.wwn);
+
+	/*
+	 * If the name is empty or there exists a soft name
+	 * then copy the service params name, otherwise use the fc name
+	 */
+	if (vport->fc_nodename.u.wwn[0] == 0 || vport->phba->cfg_soft_wwnn)
+		memcpy(&vport->fc_nodename, &vport->fc_sparam.nodeName,
+			sizeof(struct lpfc_name));
+	else
+		memcpy(&vport->fc_sparam.nodeName, &vport->fc_nodename,
+			sizeof(struct lpfc_name));
+
+	if (vport->fc_portname.u.wwn[0] == 0 || vport->phba->cfg_soft_wwpn)
+		memcpy(&vport->fc_portname, &vport->fc_sparam.portName,
+			sizeof(struct lpfc_name));
+	else
+		memcpy(&vport->fc_sparam.portName, &vport->fc_portname,
+			sizeof(struct lpfc_name));
+}
+
+/**
  * lpfc_config_port_post - Perform lpfc initialization after config port
  * @phba: pointer to lpfc hba data structure.
  *
@@ -377,17 +416,7 @@
 	lpfc_mbuf_free(phba, mp->virt, mp->phys);
 	kfree(mp);
 	pmb->context1 = NULL;
-
-	if (phba->cfg_soft_wwnn)
-		u64_to_wwn(phba->cfg_soft_wwnn,
-			   vport->fc_sparam.nodeName.u.wwn);
-	if (phba->cfg_soft_wwpn)
-		u64_to_wwn(phba->cfg_soft_wwpn,
-			   vport->fc_sparam.portName.u.wwn);
-	memcpy(&vport->fc_nodename, &vport->fc_sparam.nodeName,
-	       sizeof (struct lpfc_name));
-	memcpy(&vport->fc_portname, &vport->fc_sparam.portName,
-	       sizeof (struct lpfc_name));
+	lpfc_update_vport_wwn(vport);
 
 	/* Update the fc_host data structures with new wwn. */
 	fc_host_node_name(shost) = wwn_to_u64(vport->fc_nodename.u.wwn);
@@ -573,7 +602,6 @@
 			/* 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);
@@ -1755,7 +1783,9 @@
 		&& descp && descp[0] != '\0')
 		return;
 
-	if (phba->lmt & LMT_10Gb)
+	if (phba->lmt & LMT_16Gb)
+		max_speed = 16;
+	else if (phba->lmt & LMT_10Gb)
 		max_speed = 10;
 	else if (phba->lmt & LMT_8Gb)
 		max_speed = 8;
@@ -1922,12 +1952,13 @@
 				"Fibre Channel Adapter"};
 		break;
 	case PCI_DEVICE_ID_LANCER_FC:
-		oneConnect = 1;
-		m = (typeof(m)){"Undefined", "PCIe", "Fibre Channel Adapter"};
+	case PCI_DEVICE_ID_LANCER_FC_VF:
+		m = (typeof(m)){"LPe16000", "PCIe", "Fibre Channel Adapter"};
 		break;
 	case PCI_DEVICE_ID_LANCER_FCOE:
+	case PCI_DEVICE_ID_LANCER_FCOE_VF:
 		oneConnect = 1;
-		m = (typeof(m)){"Undefined", "PCIe", "FCoE"};
+		m = (typeof(m)){"OCe50100", "PCIe", "FCoE"};
 		break;
 	default:
 		m = (typeof(m)){"Unknown", "", ""};
@@ -1936,7 +1967,8 @@
 
 	if (mdp && mdp[0] == '\0')
 		snprintf(mdp, 79,"%s", m.name);
-	/* oneConnect hba requires special processing, they are all initiators
+	/*
+	 * oneConnect hba requires special processing, they are all initiators
 	 * and we put the port number on the end
 	 */
 	if (descp && descp[0] == '\0') {
@@ -2656,6 +2688,7 @@
 		kfree(io);
 		phba->total_iocbq_bufs--;
 	}
+
 	spin_unlock_irq(&phba->hbalock);
 	return 0;
 }
@@ -3209,9 +3242,9 @@
 	phba->sli4_hba.link_state.logical_speed =
 			bf_get(lpfc_acqe_logical_link_speed, acqe_link);
 	lpfc_printf_log(phba, KERN_INFO, LOG_SLI,
-			"2900 Async FCoE Link event - Speed:%dGBit duplex:x%x "
-			"LA Type:x%x Port Type:%d Port Number:%d Logical "
-			"speed:%dMbps Fault:%d\n",
+			"2900 Async FC/FCoE Link event - Speed:%dGBit "
+			"duplex:x%x LA Type:x%x Port Type:%d Port Number:%d "
+			"Logical speed:%dMbps Fault:%d\n",
 			phba->sli4_hba.link_state.speed,
 			phba->sli4_hba.link_state.topology,
 			phba->sli4_hba.link_state.status,
@@ -3612,6 +3645,7 @@
 		lpfc_printf_log(phba, KERN_ERR, LOG_FIP | LOG_DISCOVERY,
 			"2718 Clear Virtual Link Received for VPI 0x%x"
 			" tag 0x%x\n", acqe_fip->index, acqe_fip->event_tag);
+
 		vport = lpfc_find_vport_by_vpid(phba,
 				acqe_fip->index - phba->vpi_base);
 		ndlp = lpfc_sli4_perform_vport_cvl(vport);
@@ -3935,6 +3969,10 @@
 	pci_try_set_mwi(pdev);
 	pci_save_state(pdev);
 
+	/* PCIe EEH recovery on powerpc platforms needs fundamental reset */
+	if (pci_find_capability(pdev, PCI_CAP_ID_EXP))
+		pdev->needs_freset = 1;
+
 	return 0;
 
 out_disable_device:
@@ -3997,6 +4035,36 @@
 }
 
 /**
+ * lpfc_sli_probe_sriov_nr_virtfn - Enable a number of sr-iov virtual functions
+ * @phba: pointer to lpfc hba data structure.
+ * @nr_vfn: number of virtual functions to be enabled.
+ *
+ * This function enables the PCI SR-IOV virtual functions to a physical
+ * function. It invokes the PCI SR-IOV api with the @nr_vfn provided to
+ * enable the number of virtual functions to the physical function. As
+ * not all devices support SR-IOV, the return code from the pci_enable_sriov()
+ * API call does not considered as an error condition for most of the device.
+ **/
+int
+lpfc_sli_probe_sriov_nr_virtfn(struct lpfc_hba *phba, int nr_vfn)
+{
+	struct pci_dev *pdev = phba->pcidev;
+	int rc;
+
+	rc = pci_enable_sriov(pdev, nr_vfn);
+	if (rc) {
+		lpfc_printf_log(phba, KERN_WARNING, LOG_INIT,
+				"2806 Failed to enable sriov on this device "
+				"with vfn number nr_vf:%d, rc:%d\n",
+				nr_vfn, rc);
+	} else
+		lpfc_printf_log(phba, KERN_WARNING, LOG_INIT,
+				"2807 Successful enable sriov on this device "
+				"with vfn number nr_vf:%d\n", nr_vfn);
+	return rc;
+}
+
+/**
  * lpfc_sli_driver_resource_setup - Setup driver internal resources for SLI3 dev.
  * @phba: pointer to lpfc hba data structure.
  *
@@ -4011,6 +4079,7 @@
 lpfc_sli_driver_resource_setup(struct lpfc_hba *phba)
 {
 	struct lpfc_sli *psli;
+	int rc;
 
 	/*
 	 * Initialize timers used by driver
@@ -4085,6 +4154,23 @@
 	if (lpfc_mem_alloc(phba, BPL_ALIGN_SZ))
 		return -ENOMEM;
 
+	/*
+	 * Enable sr-iov virtual functions if supported and configured
+	 * through the module parameter.
+	 */
+	if (phba->cfg_sriov_nr_virtfn > 0) {
+		rc = lpfc_sli_probe_sriov_nr_virtfn(phba,
+						 phba->cfg_sriov_nr_virtfn);
+		if (rc) {
+			lpfc_printf_log(phba, KERN_WARNING, LOG_INIT,
+					"2808 Requested number of SR-IOV "
+					"virtual functions (%d) is not "
+					"supported\n",
+					phba->cfg_sriov_nr_virtfn);
+			phba->cfg_sriov_nr_virtfn = 0;
+		}
+	}
+
 	return 0;
 }
 
@@ -4161,6 +4247,14 @@
 	phba->fcf.redisc_wait.data = (unsigned long)phba;
 
 	/*
+	 * Control structure for handling external multi-buffer mailbox
+	 * command pass-through.
+	 */
+	memset((uint8_t *)&phba->mbox_ext_buf_ctx, 0,
+		sizeof(struct lpfc_mbox_ext_buf_ctx));
+	INIT_LIST_HEAD(&phba->mbox_ext_buf_ctx.ext_dmabuf_list);
+
+	/*
 	 * We need to do a READ_CONFIG mailbox command here before
 	 * calling lpfc_get_cfgparam. For VFs this will report the
 	 * MAX_XRI, MAX_VPI, MAX_RPI, MAX_IOCB, and MAX_VFI settings.
@@ -4233,7 +4327,7 @@
 	spin_lock_init(&phba->sli4_hba.abts_sgl_list_lock);
 
 	/*
-	 * Initialize dirver internal slow-path work queues
+	 * Initialize driver internal slow-path work queues
 	 */
 
 	/* Driver internel slow-path CQ Event pool */
@@ -4249,6 +4343,12 @@
 	/* Receive queue CQ Event work queue list */
 	INIT_LIST_HEAD(&phba->sli4_hba.sp_unsol_work_queue);
 
+	/* Initialize extent block lists. */
+	INIT_LIST_HEAD(&phba->sli4_hba.lpfc_rpi_blk_list);
+	INIT_LIST_HEAD(&phba->sli4_hba.lpfc_xri_blk_list);
+	INIT_LIST_HEAD(&phba->sli4_hba.lpfc_vfi_blk_list);
+	INIT_LIST_HEAD(&phba->lpfc_vpi_blk_list);
+
 	/* Initialize the driver internal SLI layer lists. */
 	lpfc_sli_setup(phba);
 	lpfc_sli_queue_setup(phba);
@@ -4323,9 +4423,19 @@
 	}
 	/*
 	 * Get sli4 parameters that override parameters from Port capabilities.
-	 * If this call fails it is not a critical error so continue loading.
+	 * If this call fails, it isn't critical unless the SLI4 parameters come
+	 * back in conflict.
 	 */
-	lpfc_get_sli4_parameters(phba, mboxq);
+	rc = lpfc_get_sli4_parameters(phba, mboxq);
+	if (rc) {
+		if (phba->sli4_hba.extents_in_use &&
+		    phba->sli4_hba.rpi_hdrs_in_use) {
+			lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
+				"2999 Unsupported SLI4 Parameters "
+				"Extents and RPI headers enabled.\n");
+			goto out_free_bsmbx;
+		}
+	}
 	mempool_free(mboxq, phba->mbox_mem_pool);
 	/* Create all the SLI4 queues */
 	rc = lpfc_sli4_queue_create(phba);
@@ -4350,7 +4460,6 @@
 				"1430 Failed to initialize sgl list.\n");
 		goto out_free_sgl_list;
 	}
-
 	rc = lpfc_sli4_init_rpi_hdrs(phba);
 	if (rc) {
 		lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
@@ -4366,6 +4475,7 @@
 		lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
 				"2759 Failed allocate memory for FCF round "
 				"robin failover bmask\n");
+		rc = -ENOMEM;
 		goto out_remove_rpi_hdrs;
 	}
 
@@ -4375,6 +4485,7 @@
 		lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
 				"2572 Failed allocate memory for fast-path "
 				"per-EQ handle array\n");
+		rc = -ENOMEM;
 		goto out_free_fcf_rr_bmask;
 	}
 
@@ -4384,9 +4495,27 @@
 		lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
 				"2573 Failed allocate memory for msi-x "
 				"interrupt vector entries\n");
+		rc = -ENOMEM;
 		goto out_free_fcp_eq_hdl;
 	}
 
+	/*
+	 * Enable sr-iov virtual functions if supported and configured
+	 * through the module parameter.
+	 */
+	if (phba->cfg_sriov_nr_virtfn > 0) {
+		rc = lpfc_sli_probe_sriov_nr_virtfn(phba,
+						 phba->cfg_sriov_nr_virtfn);
+		if (rc) {
+			lpfc_printf_log(phba, KERN_WARNING, LOG_INIT,
+					"3020 Requested number of SR-IOV "
+					"virtual functions (%d) is not "
+					"supported\n",
+					phba->cfg_sriov_nr_virtfn);
+			phba->cfg_sriov_nr_virtfn = 0;
+		}
+	}
+
 	return rc;
 
 out_free_fcp_eq_hdl:
@@ -4449,6 +4578,9 @@
 	lpfc_sli4_cq_event_release_all(phba);
 	lpfc_sli4_cq_event_pool_destroy(phba);
 
+	/* Release resource identifiers. */
+	lpfc_sli4_dealloc_resource_identifiers(phba);
+
 	/* Free the bsmbx region. */
 	lpfc_destroy_bootstrap_mbox(phba);
 
@@ -4649,6 +4781,7 @@
 				"Unloading driver.\n", __func__);
 			goto out_free_iocbq;
 		}
+		iocbq_entry->sli4_lxritag = NO_XRI;
 		iocbq_entry->sli4_xritag = NO_XRI;
 
 		spin_lock_irq(&phba->hbalock);
@@ -4746,7 +4879,7 @@
 
 	els_xri_cnt = lpfc_sli4_get_els_iocb_cnt(phba);
 	lpfc_printf_log(phba, KERN_INFO, LOG_SLI,
-				"2400 lpfc_init_sgl_list els %d.\n",
+				"2400 ELS XRI count %d.\n",
 				els_xri_cnt);
 	/* Initialize and populate the sglq list per host/VF. */
 	INIT_LIST_HEAD(&phba->sli4_hba.lpfc_sgl_list);
@@ -4779,7 +4912,6 @@
 	phba->sli4_hba.scsi_xri_max =
 			phba->sli4_hba.max_cfg_param.max_xri - els_xri_cnt;
 	phba->sli4_hba.scsi_xri_cnt = 0;
-
 	phba->sli4_hba.lpfc_scsi_psb_array =
 			kzalloc((sizeof(struct lpfc_scsi_buf *) *
 			phba->sli4_hba.scsi_xri_max), GFP_KERNEL);
@@ -4802,13 +4934,6 @@
 			goto out_free_mem;
 		}
 
-		sglq_entry->sli4_xritag = lpfc_sli4_next_xritag(phba);
-		if (sglq_entry->sli4_xritag == NO_XRI) {
-			kfree(sglq_entry);
-			printk(KERN_ERR "%s: failed to allocate XRI.\n"
-				"Unloading driver.\n", __func__);
-			goto out_free_mem;
-		}
 		sglq_entry->buff_type = GEN_BUFF_TYPE;
 		sglq_entry->virt = lpfc_mbuf_alloc(phba, 0, &sglq_entry->phys);
 		if (sglq_entry->virt == NULL) {
@@ -4857,24 +4982,20 @@
 lpfc_sli4_init_rpi_hdrs(struct lpfc_hba *phba)
 {
 	int rc = 0;
-	int longs;
-	uint16_t rpi_count;
 	struct lpfc_rpi_hdr *rpi_hdr;
 
 	INIT_LIST_HEAD(&phba->sli4_hba.lpfc_rpi_hdr_list);
-
 	/*
-	 * Provision an rpi bitmask range for discovery. The total count
-	 * is the difference between max and base + 1.
+	 * If the SLI4 port supports extents, posting the rpi header isn't
+	 * required.  Set the expected maximum count and let the actual value
+	 * get set when extents are fully allocated.
 	 */
-	rpi_count = phba->sli4_hba.max_cfg_param.rpi_base +
-		    phba->sli4_hba.max_cfg_param.max_rpi - 1;
-
-	longs = ((rpi_count) + BITS_PER_LONG - 1) / BITS_PER_LONG;
-	phba->sli4_hba.rpi_bmask = kzalloc(longs * sizeof(unsigned long),
-					   GFP_KERNEL);
-	if (!phba->sli4_hba.rpi_bmask)
-		return -ENOMEM;
+	if (!phba->sli4_hba.rpi_hdrs_in_use) {
+		phba->sli4_hba.next_rpi = phba->sli4_hba.max_cfg_param.max_rpi;
+		return rc;
+	}
+	if (phba->sli4_hba.extents_in_use)
+		return -EIO;
 
 	rpi_hdr = lpfc_sli4_create_rpi_hdr(phba);
 	if (!rpi_hdr) {
@@ -4906,12 +5027,30 @@
 	uint16_t rpi_limit, curr_rpi_range;
 	struct lpfc_dmabuf *dmabuf;
 	struct lpfc_rpi_hdr *rpi_hdr;
+	uint32_t rpi_count;
+
+	/*
+	 * If the SLI4 port supports extents, posting the rpi header isn't
+	 * required.  Set the expected maximum count and let the actual value
+	 * get set when extents are fully allocated.
+	 */
+	if (!phba->sli4_hba.rpi_hdrs_in_use)
+		return NULL;
+	if (phba->sli4_hba.extents_in_use)
+		return NULL;
 
+	/* The limit on the logical index is just the max_rpi count. */
 	rpi_limit = phba->sli4_hba.max_cfg_param.rpi_base +
-		    phba->sli4_hba.max_cfg_param.max_rpi - 1;
+	phba->sli4_hba.max_cfg_param.max_rpi - 1;
 
 	spin_lock_irq(&phba->hbalock);
-	curr_rpi_range = phba->sli4_hba.next_rpi;
+	/*
+	 * Establish the starting RPI in this header block.  The starting
+	 * rpi is normalized to a zero base because the physical rpi is
+	 * port based.
+	 */
+	curr_rpi_range = phba->sli4_hba.next_rpi -
+		phba->sli4_hba.max_cfg_param.rpi_base;
 	spin_unlock_irq(&phba->hbalock);
 
 	/*
@@ -4920,8 +5059,12 @@
 	 * and to allow the full max_rpi range per port.
 	 */
 	if ((curr_rpi_range + (LPFC_RPI_HDR_COUNT - 1)) > rpi_limit)
-		return NULL;
+		rpi_count = rpi_limit - curr_rpi_range;
+	else
+		rpi_count = LPFC_RPI_HDR_COUNT;
 
+	if (!rpi_count)
+		return NULL;
 	/*
 	 * First allocate the protocol header region for the port.  The
 	 * port expects a 4KB DMA-mapped memory region that is 4K aligned.
@@ -4954,14 +5097,16 @@
 	rpi_hdr->len = LPFC_HDR_TEMPLATE_SIZE;
 	rpi_hdr->page_count = 1;
 	spin_lock_irq(&phba->hbalock);
-	rpi_hdr->start_rpi = phba->sli4_hba.next_rpi;
+
+	/* The rpi_hdr stores the logical index only. */
+	rpi_hdr->start_rpi = curr_rpi_range;
 	list_add_tail(&rpi_hdr->list, &phba->sli4_hba.lpfc_rpi_hdr_list);
 
 	/*
-	 * The next_rpi stores the next module-64 rpi value to post
-	 * in any subsequent rpi memory region postings.
+	 * The next_rpi stores the next logical module-64 rpi value used
+	 * to post physical rpis in subsequent rpi postings.
 	 */
-	phba->sli4_hba.next_rpi += LPFC_RPI_HDR_COUNT;
+	phba->sli4_hba.next_rpi += rpi_count;
 	spin_unlock_irq(&phba->hbalock);
 	return rpi_hdr;
 
@@ -4978,15 +5123,18 @@
  * @phba: pointer to lpfc hba data structure.
  *
  * This routine is invoked to remove all memory resources allocated
- * to support rpis. This routine presumes the caller has released all
- * rpis consumed by fabric or port logins and is prepared to have
- * the header pages removed.
+ * to support rpis for SLI4 ports not supporting extents. This routine
+ * presumes the caller has released all rpis consumed by fabric or port
+ * logins and is prepared to have the header pages removed.
  **/
 void
 lpfc_sli4_remove_rpi_hdrs(struct lpfc_hba *phba)
 {
 	struct lpfc_rpi_hdr *rpi_hdr, *next_rpi_hdr;
 
+	if (!phba->sli4_hba.rpi_hdrs_in_use)
+		goto exit;
+
 	list_for_each_entry_safe(rpi_hdr, next_rpi_hdr,
 				 &phba->sli4_hba.lpfc_rpi_hdr_list, list) {
 		list_del(&rpi_hdr->list);
@@ -4995,9 +5143,9 @@
 		kfree(rpi_hdr->dmabuf);
 		kfree(rpi_hdr);
 	}
-
-	phba->sli4_hba.next_rpi = phba->sli4_hba.max_cfg_param.rpi_base;
-	memset(phba->sli4_hba.rpi_bmask, 0, sizeof(*phba->sli4_hba.rpi_bmask));
+ exit:
+	/* There are no rpis available to the port now. */
+	phba->sli4_hba.next_rpi = 0;
 }
 
 /**
@@ -5484,7 +5632,8 @@
 			/* Final checks.  The port status should be clean. */
 			if (lpfc_readl(phba->sli4_hba.u.if_type2.STATUSregaddr,
 				&reg_data.word0) ||
-				bf_get(lpfc_sliport_status_err, &reg_data)) {
+				(bf_get(lpfc_sliport_status_err, &reg_data) &&
+				 !bf_get(lpfc_sliport_status_rn, &reg_data))) {
 				phba->work_status[0] =
 					readl(phba->sli4_hba.u.if_type2.
 					      ERR1regaddr);
@@ -5738,7 +5887,12 @@
 {
 	LPFC_MBOXQ_t *pmb;
 	struct lpfc_mbx_read_config *rd_config;
-	uint32_t rc = 0;
+	union  lpfc_sli4_cfg_shdr *shdr;
+	uint32_t shdr_status, shdr_add_status;
+	struct lpfc_mbx_get_func_cfg *get_func_cfg;
+	struct lpfc_rsrc_desc_fcfcoe *desc;
+	uint32_t desc_count;
+	int length, i, rc = 0;
 
 	pmb = (LPFC_MBOXQ_t *) mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
 	if (!pmb) {
@@ -5760,6 +5914,8 @@
 		rc = -EIO;
 	} else {
 		rd_config = &pmb->u.mqe.un.rd_config;
+		phba->sli4_hba.extents_in_use =
+			bf_get(lpfc_mbx_rd_conf_extnts_inuse, rd_config);
 		phba->sli4_hba.max_cfg_param.max_xri =
 			bf_get(lpfc_mbx_rd_conf_xri_count, rd_config);
 		phba->sli4_hba.max_cfg_param.xri_base =
@@ -5778,8 +5934,6 @@
 			bf_get(lpfc_mbx_rd_conf_vfi_base, rd_config);
 		phba->sli4_hba.max_cfg_param.max_fcfi =
 			bf_get(lpfc_mbx_rd_conf_fcfi_count, rd_config);
-		phba->sli4_hba.max_cfg_param.fcfi_base =
-			bf_get(lpfc_mbx_rd_conf_fcfi_base, rd_config);
 		phba->sli4_hba.max_cfg_param.max_eq =
 			bf_get(lpfc_mbx_rd_conf_eq_count, rd_config);
 		phba->sli4_hba.max_cfg_param.max_rq =
@@ -5797,11 +5951,13 @@
 				(phba->sli4_hba.max_cfg_param.max_vpi - 1) : 0;
 		phba->max_vports = phba->max_vpi;
 		lpfc_printf_log(phba, KERN_INFO, LOG_SLI,
-				"2003 cfg params XRI(B:%d M:%d), "
+				"2003 cfg params Extents? %d "
+				"XRI(B:%d M:%d), "
 				"VPI(B:%d M:%d) "
 				"VFI(B:%d M:%d) "
 				"RPI(B:%d M:%d) "
-				"FCFI(B:%d M:%d)\n",
+				"FCFI(Count:%d)\n",
+				phba->sli4_hba.extents_in_use,
 				phba->sli4_hba.max_cfg_param.xri_base,
 				phba->sli4_hba.max_cfg_param.max_xri,
 				phba->sli4_hba.max_cfg_param.vpi_base,
@@ -5810,10 +5966,11 @@
 				phba->sli4_hba.max_cfg_param.max_vfi,
 				phba->sli4_hba.max_cfg_param.rpi_base,
 				phba->sli4_hba.max_cfg_param.max_rpi,
-				phba->sli4_hba.max_cfg_param.fcfi_base,
 				phba->sli4_hba.max_cfg_param.max_fcfi);
 	}
-	mempool_free(pmb, phba->mbox_mem_pool);
+
+	if (rc)
+		goto read_cfg_out;
 
 	/* Reset the DFT_HBA_Q_DEPTH to the max xri  */
 	if (phba->cfg_hba_queue_depth >
@@ -5822,6 +5979,65 @@
 		phba->cfg_hba_queue_depth =
 			phba->sli4_hba.max_cfg_param.max_xri -
 				lpfc_sli4_get_els_iocb_cnt(phba);
+
+	if (bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf) !=
+	    LPFC_SLI_INTF_IF_TYPE_2)
+		goto read_cfg_out;
+
+	/* get the pf# and vf# for SLI4 if_type 2 port */
+	length = (sizeof(struct lpfc_mbx_get_func_cfg) -
+		  sizeof(struct lpfc_sli4_cfg_mhdr));
+	lpfc_sli4_config(phba, pmb, LPFC_MBOX_SUBSYSTEM_COMMON,
+			 LPFC_MBOX_OPCODE_GET_FUNCTION_CONFIG,
+			 length, LPFC_SLI4_MBX_EMBED);
+
+	rc = lpfc_sli_issue_mbox(phba, pmb, MBX_POLL);
+	shdr = (union lpfc_sli4_cfg_shdr *)
+				&pmb->u.mqe.un.sli4_config.header.cfg_shdr;
+	shdr_status = bf_get(lpfc_mbox_hdr_status, &shdr->response);
+	shdr_add_status = bf_get(lpfc_mbox_hdr_add_status, &shdr->response);
+	if (rc || shdr_status || shdr_add_status) {
+		lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
+				"3026 Mailbox failed , mbxCmd x%x "
+				"GET_FUNCTION_CONFIG, mbxStatus x%x\n",
+				bf_get(lpfc_mqe_command, &pmb->u.mqe),
+				bf_get(lpfc_mqe_status, &pmb->u.mqe));
+		rc = -EIO;
+		goto read_cfg_out;
+	}
+
+	/* search for fc_fcoe resrouce descriptor */
+	get_func_cfg = &pmb->u.mqe.un.get_func_cfg;
+	desc_count = get_func_cfg->func_cfg.rsrc_desc_count;
+
+	for (i = 0; i < LPFC_RSRC_DESC_MAX_NUM; i++) {
+		desc = (struct lpfc_rsrc_desc_fcfcoe *)
+			&get_func_cfg->func_cfg.desc[i];
+		if (LPFC_RSRC_DESC_TYPE_FCFCOE ==
+		    bf_get(lpfc_rsrc_desc_pcie_type, desc)) {
+			phba->sli4_hba.iov.pf_number =
+				bf_get(lpfc_rsrc_desc_fcfcoe_pfnum, desc);
+			phba->sli4_hba.iov.vf_number =
+				bf_get(lpfc_rsrc_desc_fcfcoe_vfnum, desc);
+			break;
+		}
+	}
+
+	if (i < LPFC_RSRC_DESC_MAX_NUM)
+		lpfc_printf_log(phba, KERN_INFO, LOG_SLI,
+				"3027 GET_FUNCTION_CONFIG: pf_number:%d, "
+				"vf_number:%d\n", phba->sli4_hba.iov.pf_number,
+				phba->sli4_hba.iov.vf_number);
+	else {
+		lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
+				"3028 GET_FUNCTION_CONFIG: failed to find "
+				"Resrouce Descriptor:x%x\n",
+				LPFC_RSRC_DESC_TYPE_FCFCOE);
+		rc = -EIO;
+	}
+
+read_cfg_out:
+	mempool_free(pmb, phba->mbox_mem_pool);
 	return rc;
 }
 
@@ -6226,8 +6442,10 @@
 	phba->sli4_hba.mbx_cq = NULL;
 
 	/* Release FCP response complete queue */
-	for (fcp_qidx = 0; fcp_qidx < phba->cfg_fcp_eq_count; fcp_qidx++)
+	fcp_qidx = 0;
+	do
 		lpfc_sli4_queue_free(phba->sli4_hba.fcp_cq[fcp_qidx]);
+	while (++fcp_qidx < phba->cfg_fcp_eq_count);
 	kfree(phba->sli4_hba.fcp_cq);
 	phba->sli4_hba.fcp_cq = NULL;
 
@@ -6350,16 +6568,24 @@
 			phba->sli4_hba.sp_eq->queue_id);
 
 	/* Set up fast-path FCP Response Complete Queue */
-	for (fcp_cqidx = 0; fcp_cqidx < phba->cfg_fcp_eq_count; fcp_cqidx++) {
+	fcp_cqidx = 0;
+	do {
 		if (!phba->sli4_hba.fcp_cq[fcp_cqidx]) {
 			lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
 					"0526 Fast-path FCP CQ (%d) not "
 					"allocated\n", fcp_cqidx);
 			goto out_destroy_fcp_cq;
 		}
-		rc = lpfc_cq_create(phba, phba->sli4_hba.fcp_cq[fcp_cqidx],
-				    phba->sli4_hba.fp_eq[fcp_cqidx],
-				    LPFC_WCQ, LPFC_FCP);
+		if (phba->cfg_fcp_eq_count)
+			rc = lpfc_cq_create(phba,
+					    phba->sli4_hba.fcp_cq[fcp_cqidx],
+					    phba->sli4_hba.fp_eq[fcp_cqidx],
+					    LPFC_WCQ, LPFC_FCP);
+		else
+			rc = lpfc_cq_create(phba,
+					    phba->sli4_hba.fcp_cq[fcp_cqidx],
+					    phba->sli4_hba.sp_eq,
+					    LPFC_WCQ, LPFC_FCP);
 		if (rc) {
 			lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
 					"0527 Failed setup of fast-path FCP "
@@ -6368,12 +6594,15 @@
 		}
 		lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
 				"2588 FCP CQ setup: cq[%d]-id=%d, "
-				"parent eq[%d]-id=%d\n",
+				"parent %seq[%d]-id=%d\n",
 				fcp_cqidx,
 				phba->sli4_hba.fcp_cq[fcp_cqidx]->queue_id,
+				(phba->cfg_fcp_eq_count) ? "" : "sp_",
 				fcp_cqidx,
-				phba->sli4_hba.fp_eq[fcp_cqidx]->queue_id);
-	}
+				(phba->cfg_fcp_eq_count) ?
+				   phba->sli4_hba.fp_eq[fcp_cqidx]->queue_id :
+				   phba->sli4_hba.sp_eq->queue_id);
+	} while (++fcp_cqidx < phba->cfg_fcp_eq_count);
 
 	/*
 	 * Set up all the Work Queues (WQs)
@@ -6442,7 +6671,9 @@
 				fcp_cq_index,
 				phba->sli4_hba.fcp_cq[fcp_cq_index]->queue_id);
 		/* Round robin FCP Work Queue's Completion Queue assignment */
-		fcp_cq_index = ((fcp_cq_index + 1) % phba->cfg_fcp_eq_count);
+		if (phba->cfg_fcp_eq_count)
+			fcp_cq_index = ((fcp_cq_index + 1) %
+					phba->cfg_fcp_eq_count);
 	}
 
 	/*
@@ -6824,6 +7055,8 @@
 			if (rdy_chk < 1000)
 				break;
 		}
+		/* delay driver action following IF_TYPE_2 function reset */
+		msleep(100);
 		break;
 	case LPFC_SLI_INTF_IF_TYPE_1:
 	default:
@@ -7004,7 +7237,8 @@
 		lpfc_sli4_bar0_register_memmap(phba, if_type);
 	}
 
-	if (pci_resource_start(pdev, 2)) {
+	if ((if_type == LPFC_SLI_INTF_IF_TYPE_0) &&
+	    (pci_resource_start(pdev, 2))) {
 		/*
 		 * Map SLI4 if type 0 HBA Control Register base to a kernel
 		 * virtual address and setup the registers.
@@ -7021,7 +7255,8 @@
 		lpfc_sli4_bar1_register_memmap(phba);
 	}
 
-	if (pci_resource_start(pdev, 4)) {
+	if ((if_type == LPFC_SLI_INTF_IF_TYPE_0) &&
+	    (pci_resource_start(pdev, 4))) {
 		/*
 		 * Map SLI4 if type 0 HBA Doorbell Register base to a kernel
 		 * virtual address and setup the registers.
@@ -7414,11 +7649,15 @@
 	/*
 	 * Assign MSI-X vectors to interrupt handlers
 	 */
-
-	/* The first vector must associated to slow-path handler for MQ */
-	rc = request_irq(phba->sli4_hba.msix_entries[0].vector,
-			 &lpfc_sli4_sp_intr_handler, IRQF_SHARED,
-			 LPFC_SP_DRIVER_HANDLER_NAME, phba);
+	if (vectors > 1)
+		rc = request_irq(phba->sli4_hba.msix_entries[0].vector,
+				 &lpfc_sli4_sp_intr_handler, IRQF_SHARED,
+				 LPFC_SP_DRIVER_HANDLER_NAME, phba);
+	else
+		/* All Interrupts need to be handled by one EQ */
+		rc = request_irq(phba->sli4_hba.msix_entries[0].vector,
+				 &lpfc_sli4_intr_handler, IRQF_SHARED,
+				 LPFC_DRIVER_NAME, phba);
 	if (rc) {
 		lpfc_printf_log(phba, KERN_WARNING, LOG_INIT,
 				"0485 MSI-X slow-path request_irq failed "
@@ -7760,6 +7999,7 @@
 {
 	int wait_cnt = 0;
 	LPFC_MBOXQ_t *mboxq;
+	struct pci_dev *pdev = phba->pcidev;
 
 	lpfc_stop_hba_timers(phba);
 	phba->sli4_hba.intr_enable = 0;
@@ -7799,6 +8039,10 @@
 	/* Disable PCI subsystem interrupt */
 	lpfc_sli4_disable_intr(phba);
 
+	/* Disable SR-IOV if enabled */
+	if (phba->cfg_sriov_nr_virtfn)
+		pci_disable_sriov(pdev);
+
 	/* Stop kthread signal shall trigger work_done one more time */
 	kthread_stop(phba->worker_thread);
 
@@ -7873,6 +8117,11 @@
 	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);
+
+	/* Make sure that sge_supp_len can be handled by the driver */
+	if (sli4_params->sge_supp_len > LPFC_MAX_SGE_SIZE)
+		sli4_params->sge_supp_len = LPFC_MAX_SGE_SIZE;
+
 	return rc;
 }
 
@@ -7897,6 +8146,13 @@
 	int length;
 	struct lpfc_sli4_parameters *mbx_sli4_parameters;
 
+	/*
+	 * By default, the driver assumes the SLI4 port requires RPI
+	 * header postings.  The SLI4_PARAM response will correct this
+	 * assumption.
+	 */
+	phba->sli4_hba.rpi_hdrs_in_use = 1;
+
 	/* Read the port's SLI4 Config Parameters */
 	length = (sizeof(struct lpfc_mbx_get_sli4_parameters) -
 		  sizeof(struct lpfc_sli4_cfg_mhdr));
@@ -7933,6 +8189,13 @@
 					    mbx_sli4_parameters);
 	sli4_params->sgl_pp_align = bf_get(cfg_sgl_pp_align,
 					   mbx_sli4_parameters);
+	phba->sli4_hba.extents_in_use = bf_get(cfg_ext, mbx_sli4_parameters);
+	phba->sli4_hba.rpi_hdrs_in_use = bf_get(cfg_hdrr, mbx_sli4_parameters);
+
+	/* Make sure that sge_supp_len can be handled by the driver */
+	if (sli4_params->sge_supp_len > LPFC_MAX_SGE_SIZE)
+		sli4_params->sge_supp_len = LPFC_MAX_SGE_SIZE;
+
 	return 0;
 }
 
@@ -8168,6 +8431,10 @@
 
 	lpfc_debugfs_terminate(vport);
 
+	/* Disable SR-IOV if enabled */
+	if (phba->cfg_sriov_nr_virtfn)
+		pci_disable_sriov(pdev);
+
 	/* Disable interrupt */
 	lpfc_sli_disable_intr(phba);
 
@@ -8560,6 +8827,97 @@
 }
 
 /**
+ * lpfc_write_firmware - attempt to write a firmware image to the port
+ * @phba: pointer to lpfc hba data structure.
+ * @fw: pointer to firmware image returned from reject_firmware.
+ *
+ * returns the number of bytes written if write is successful.
+ * returns a negative error value if there were errors.
+ * returns 0 if firmware matches currently active firmware on port.
+ **/
+int
+lpfc_write_firmware(struct lpfc_hba *phba, const struct firmware *fw)
+{
+	char fwrev[32];
+	struct lpfc_grp_hdr *image = (struct lpfc_grp_hdr *)fw->data;
+	struct list_head dma_buffer_list;
+	int i, rc = 0;
+	struct lpfc_dmabuf *dmabuf, *next;
+	uint32_t offset = 0, temp_offset = 0;
+
+	INIT_LIST_HEAD(&dma_buffer_list);
+	if ((image->magic_number != LPFC_GROUP_OJECT_MAGIC_NUM) ||
+	    (bf_get(lpfc_grp_hdr_file_type, image) != LPFC_FILE_TYPE_GROUP) ||
+	    (bf_get(lpfc_grp_hdr_id, image) != LPFC_FILE_ID_GROUP) ||
+	    (image->size != fw->size)) {
+		lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
+				"3022 Invalid FW image found. "
+				"Magic:%d Type:%x ID:%x\n",
+				image->magic_number,
+				bf_get(lpfc_grp_hdr_file_type, image),
+				bf_get(lpfc_grp_hdr_id, image));
+		return -EINVAL;
+	}
+	lpfc_decode_firmware_rev(phba, fwrev, 1);
+	if (strncmp(fwrev, image->rev_name, strnlen(fwrev, 16))) {
+		lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
+				"3023 Updating Firmware. Current Version:%s "
+				"New Version:%s\n",
+				fwrev, image->rev_name);
+		for (i = 0; i < LPFC_MBX_WR_CONFIG_MAX_BDE; i++) {
+			dmabuf = kzalloc(sizeof(struct lpfc_dmabuf),
+					 GFP_KERNEL);
+			if (!dmabuf) {
+				rc = -ENOMEM;
+				goto out;
+			}
+			dmabuf->virt = dma_alloc_coherent(&phba->pcidev->dev,
+							  SLI4_PAGE_SIZE,
+							  &dmabuf->phys,
+							  GFP_KERNEL);
+			if (!dmabuf->virt) {
+				kfree(dmabuf);
+				rc = -ENOMEM;
+				goto out;
+			}
+			list_add_tail(&dmabuf->list, &dma_buffer_list);
+		}
+		while (offset < fw->size) {
+			temp_offset = offset;
+			list_for_each_entry(dmabuf, &dma_buffer_list, list) {
+				if (offset + SLI4_PAGE_SIZE > fw->size) {
+					temp_offset += fw->size - offset;
+					memcpy(dmabuf->virt,
+					       fw->data + temp_offset,
+					       fw->size - offset);
+					break;
+				}
+				temp_offset += SLI4_PAGE_SIZE;
+				memcpy(dmabuf->virt, fw->data + temp_offset,
+				       SLI4_PAGE_SIZE);
+			}
+			rc = lpfc_wr_object(phba, &dma_buffer_list,
+				    (fw->size - offset), &offset);
+			if (rc) {
+				lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
+						"3024 Firmware update failed. "
+						"%d\n", rc);
+				goto out;
+			}
+		}
+		rc = offset;
+	}
+out:
+	list_for_each_entry_safe(dmabuf, next, &dma_buffer_list, list) {
+		list_del(&dmabuf->list);
+		dma_free_coherent(&phba->pcidev->dev, SLI4_PAGE_SIZE,
+				  dmabuf->virt, dmabuf->phys);
+		kfree(dmabuf);
+	}
+	return rc;
+}
+
+/**
  * lpfc_pci_probe_one_s4 - PCI probe func to reg SLI-4 device to PCI subsys
  * @pdev: pointer to PCI device
  * @pid: pointer to PCI device identifier
@@ -8586,6 +8944,10 @@
 	int error;
 	uint32_t cfg_mode, intr_mode;
 	int mcnt;
+	int adjusted_fcp_eq_count;
+	int fcp_qidx;
+	const struct firmware *fw;
+	uint8_t file_name[16];
 
 	/* Allocate memory for HBA structure */
 	phba = lpfc_hba_alloc(pdev);
@@ -8683,11 +9045,25 @@
 			error = -ENODEV;
 			goto out_free_sysfs_attr;
 		}
-		/* Default to single FCP EQ for non-MSI-X */
+		/* Default to single EQ for non-MSI-X */
 		if (phba->intr_type != MSIX)
-			phba->cfg_fcp_eq_count = 1;
-		else if (phba->sli4_hba.msix_vec_nr < phba->cfg_fcp_eq_count)
-			phba->cfg_fcp_eq_count = phba->sli4_hba.msix_vec_nr - 1;
+			adjusted_fcp_eq_count = 0;
+		else if (phba->sli4_hba.msix_vec_nr <
+					phba->cfg_fcp_eq_count + 1)
+			adjusted_fcp_eq_count = phba->sli4_hba.msix_vec_nr - 1;
+		else
+			adjusted_fcp_eq_count = phba->cfg_fcp_eq_count;
+		/* Free unused EQs */
+		for (fcp_qidx = adjusted_fcp_eq_count;
+		     fcp_qidx < phba->cfg_fcp_eq_count;
+		     fcp_qidx++) {
+			lpfc_sli4_queue_free(phba->sli4_hba.fp_eq[fcp_qidx]);
+			/* do not delete the first fcp_cq */
+			if (fcp_qidx)
+				lpfc_sli4_queue_free(
+					phba->sli4_hba.fcp_cq[fcp_qidx]);
+		}
+		phba->cfg_fcp_eq_count = adjusted_fcp_eq_count;
 		/* Set up SLI-4 HBA */
 		if (lpfc_sli4_hba_setup(phba)) {
 			lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
@@ -8726,6 +9102,14 @@
 	/* Perform post initialization setup */
 	lpfc_post_init_setup(phba);
 
+	/* check for firmware upgrade or downgrade */
+	snprintf(file_name, 16, "%s.grp", phba->ModelName);
+	error = reject_firmware(&fw, file_name, &phba->pcidev->dev);
+	if (!error) {
+		lpfc_write_firmware(phba, fw);
+		release_firmware(fw);
+	}
+
 	/* Check if there are static vports to be created. */
 	lpfc_create_static_vport(phba);
 
@@ -9493,6 +9877,10 @@
 		PCI_ANY_ID, PCI_ANY_ID, },
 	{PCI_VENDOR_ID_EMULEX, PCI_DEVICE_ID_LANCER_FCOE,
 		PCI_ANY_ID, PCI_ANY_ID, },
+	{PCI_VENDOR_ID_EMULEX, PCI_DEVICE_ID_LANCER_FC_VF,
+		PCI_ANY_ID, PCI_ANY_ID, },
+	{PCI_VENDOR_ID_EMULEX, PCI_DEVICE_ID_LANCER_FCOE_VF,
+		PCI_ANY_ID, PCI_ANY_ID, },
 	{ 0 }
 };
 
diff -druN linux-2.6.39-libre/drivers/scsi/lpfc/lpfc_mbox.c linux-3.0-rc7-libre/drivers/scsi/lpfc/lpfc_mbox.c
--- linux-2.6.39-libre/drivers/scsi/lpfc/lpfc_mbox.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/scsi/lpfc/lpfc_mbox.c	2011-07-11 19:51:52.000000000 -0400
@@ -610,7 +610,8 @@
 	mb->un.varRdSparm.un.sp64.tus.f.bdeSize = sizeof (struct serv_parm);
 	mb->un.varRdSparm.un.sp64.addrHigh = putPaddrHigh(mp->phys);
 	mb->un.varRdSparm.un.sp64.addrLow = putPaddrLow(mp->phys);
-	mb->un.varRdSparm.vpi = vpi + phba->vpi_base;
+	if (phba->sli_rev >= LPFC_SLI_REV3)
+		mb->un.varRdSparm.vpi = phba->vpi_ids[vpi];
 
 	/* save address for completion */
 	pmb->context1 = mp;
@@ -643,9 +644,10 @@
 	memset(pmb, 0, sizeof (LPFC_MBOXQ_t));
 
 	mb->un.varUnregDID.did = did;
-	if (vpi != 0xffff)
-		vpi += phba->vpi_base;
 	mb->un.varUnregDID.vpi = vpi;
+	if ((vpi != 0xffff) &&
+	    (phba->sli_rev == LPFC_SLI_REV4))
+		mb->un.varUnregDID.vpi = phba->vpi_ids[vpi];
 
 	mb->mbxCommand = MBX_UNREG_D_ID;
 	mb->mbxOwner = OWN_HOST;
@@ -738,12 +740,10 @@
 	memset(pmb, 0, sizeof (LPFC_MBOXQ_t));
 
 	mb->un.varRegLogin.rpi = 0;
-	if (phba->sli_rev == LPFC_SLI_REV4) {
-		mb->un.varRegLogin.rpi = rpi;
-		if (mb->un.varRegLogin.rpi == LPFC_RPI_ALLOC_ERROR)
-			return 1;
-	}
-	mb->un.varRegLogin.vpi = vpi + phba->vpi_base;
+	if (phba->sli_rev == LPFC_SLI_REV4)
+		mb->un.varRegLogin.rpi = phba->sli4_hba.rpi_ids[rpi];
+	if (phba->sli_rev >= LPFC_SLI_REV3)
+		mb->un.varRegLogin.vpi = phba->vpi_ids[vpi];
 	mb->un.varRegLogin.did = did;
 	mb->mbxOwner = OWN_HOST;
 	/* Get a buffer to hold NPorts Service Parameters */
@@ -757,7 +757,7 @@
 		lpfc_printf_log(phba, KERN_WARNING, LOG_MBOX,
 				"0302 REG_LOGIN: no buffers, VPI:%d DID:x%x, "
 				"rpi x%x\n", vpi, did, rpi);
-		return (1);
+		return 1;
 	}
 	INIT_LIST_HEAD(&mp->list);
 	sparam = mp->virt;
@@ -773,7 +773,7 @@
 	mb->un.varRegLogin.un.sp64.addrHigh = putPaddrHigh(mp->phys);
 	mb->un.varRegLogin.un.sp64.addrLow = putPaddrLow(mp->phys);
 
-	return (0);
+	return 0;
 }
 
 /**
@@ -789,6 +789,9 @@
  *
  * This routine prepares the mailbox command for unregistering remote port
  * login.
+ *
+ * For SLI4 ports, the rpi passed to this function must be the physical
+ * rpi value, not the logical index.
  **/
 void
 lpfc_unreg_login(struct lpfc_hba *phba, uint16_t vpi, uint32_t rpi,
@@ -799,9 +802,10 @@
 	mb = &pmb->u.mb;
 	memset(pmb, 0, sizeof (LPFC_MBOXQ_t));
 
-	mb->un.varUnregLogin.rpi = (uint16_t) rpi;
+	mb->un.varUnregLogin.rpi = rpi;
 	mb->un.varUnregLogin.rsvd1 = 0;
-	mb->un.varUnregLogin.vpi = vpi + phba->vpi_base;
+	if (phba->sli_rev >= LPFC_SLI_REV3)
+		mb->un.varUnregLogin.vpi = phba->vpi_ids[vpi];
 
 	mb->mbxCommand = MBX_UNREG_LOGIN;
 	mb->mbxOwner = OWN_HOST;
@@ -825,9 +829,16 @@
 
 	mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
 	if (mbox) {
-		lpfc_unreg_login(phba, vport->vpi,
-			vport->vpi + phba->vpi_base, mbox);
-		mbox->u.mb.un.varUnregLogin.rsvd1 = 0x4000 ;
+		/*
+		 * For SLI4 functions, the rpi field is overloaded for
+		 * the vport context unreg all.  This routine passes
+		 * 0 for the rpi field in lpfc_unreg_login for compatibility
+		 * with SLI3 and then overrides the rpi field with the
+		 * expected value for SLI4.
+		 */
+		lpfc_unreg_login(phba, vport->vpi, phba->vpi_ids[vport->vpi],
+				 mbox);
+		mbox->u.mb.un.varUnregLogin.rsvd1 = 0x4000;
 		mbox->vport = vport;
 		mbox->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
 		mbox->context1 = NULL;
@@ -865,9 +876,13 @@
 	if ((phba->sli_rev == LPFC_SLI_REV4) &&
 		!(vport->fc_flag & FC_VPORT_NEEDS_REG_VPI))
 		mb->un.varRegVpi.upd = 1;
-	mb->un.varRegVpi.vpi = vport->vpi + vport->phba->vpi_base;
+
+	mb->un.varRegVpi.vpi = phba->vpi_ids[vport->vpi];
 	mb->un.varRegVpi.sid = vport->fc_myDID;
-	mb->un.varRegVpi.vfi = vport->vfi + vport->phba->vfi_base;
+	if (phba->sli_rev == LPFC_SLI_REV4)
+		mb->un.varRegVpi.vfi = phba->sli4_hba.vfi_ids[vport->vfi];
+	else
+		mb->un.varRegVpi.vfi = vport->vfi + vport->phba->vfi_base;
 	memcpy(mb->un.varRegVpi.wwn, &vport->fc_portname,
 	       sizeof(struct lpfc_name));
 	mb->un.varRegVpi.wwn[0] = cpu_to_le32(mb->un.varRegVpi.wwn[0]);
@@ -901,10 +916,10 @@
 	MAILBOX_t *mb = &pmb->u.mb;
 	memset(pmb, 0, sizeof (LPFC_MBOXQ_t));
 
-	if (phba->sli_rev < LPFC_SLI_REV4)
-		mb->un.varUnregVpi.vpi = vpi + phba->vpi_base;
-	else
-		mb->un.varUnregVpi.sli4_vpi = vpi + phba->vpi_base;
+	if (phba->sli_rev == LPFC_SLI_REV3)
+		mb->un.varUnregVpi.vpi = phba->vpi_ids[vpi];
+	else if (phba->sli_rev >= LPFC_SLI_REV4)
+		mb->un.varUnregVpi.sli4_vpi = phba->vpi_ids[vpi];
 
 	mb->mbxCommand = MBX_UNREG_VPI;
 	mb->mbxOwner = OWN_HOST;
@@ -1735,12 +1750,12 @@
 		return length;
 	}
 
-	/* Setup for the none-embedded mbox command */
-	pcount = (PAGE_ALIGN(length))/SLI4_PAGE_SIZE;
+	/* Setup for the non-embedded mbox command */
+	pcount = (SLI4_PAGE_ALIGN(length))/SLI4_PAGE_SIZE;
 	pcount = (pcount > LPFC_SLI4_MBX_SGE_MAX_PAGES) ?
 				LPFC_SLI4_MBX_SGE_MAX_PAGES : pcount;
 	/* Allocate record for keeping SGE virtual addresses */
-	mbox->sge_array = kmalloc(sizeof(struct lpfc_mbx_nembed_sge_virt),
+	mbox->sge_array = kzalloc(sizeof(struct lpfc_mbx_nembed_sge_virt),
 				  GFP_KERNEL);
 	if (!mbox->sge_array) {
 		lpfc_printf_log(phba, KERN_ERR, LOG_MBOX,
@@ -1790,12 +1805,87 @@
 	/* The sub-header is in DMA memory, which needs endian converstion */
 	if (cfg_shdr)
 		lpfc_sli_pcimem_bcopy(cfg_shdr, cfg_shdr,
-			      sizeof(union  lpfc_sli4_cfg_shdr));
-
+				      sizeof(union  lpfc_sli4_cfg_shdr));
 	return alloc_len;
 }
 
 /**
+ * lpfc_sli4_mbox_rsrc_extent - Initialize the opcode resource extent.
+ * @phba: pointer to lpfc hba data structure.
+ * @mbox: pointer to an allocated lpfc mbox resource.
+ * @exts_count: the number of extents, if required, to allocate.
+ * @rsrc_type: the resource extent type.
+ * @emb: true if LPFC_SLI4_MBX_EMBED. false if LPFC_SLI4_MBX_NEMBED.
+ *
+ * This routine completes the subcommand header for SLI4 resource extent
+ * mailbox commands.  It is called after lpfc_sli4_config.  The caller must
+ * pass an allocated mailbox and the attributes required to initialize the
+ * mailbox correctly.
+ *
+ * Return: the actual length of the mbox command allocated.
+ **/
+int
+lpfc_sli4_mbox_rsrc_extent(struct lpfc_hba *phba, struct lpfcMboxq *mbox,
+			   uint16_t exts_count, uint16_t rsrc_type, bool emb)
+{
+	uint8_t opcode = 0;
+	struct lpfc_mbx_nembed_rsrc_extent *n_rsrc_extnt = NULL;
+	void *virtaddr = NULL;
+
+	/* Set up SLI4 ioctl command header fields */
+	if (emb == LPFC_SLI4_MBX_NEMBED) {
+		/* Get the first SGE entry from the non-embedded DMA memory */
+		virtaddr = mbox->sge_array->addr[0];
+		if (virtaddr == NULL)
+			return 1;
+		n_rsrc_extnt = (struct lpfc_mbx_nembed_rsrc_extent *) virtaddr;
+	}
+
+	/*
+	 * The resource type is common to all extent Opcodes and resides in the
+	 * same position.
+	 */
+	if (emb == LPFC_SLI4_MBX_EMBED)
+		bf_set(lpfc_mbx_alloc_rsrc_extents_type,
+		       &mbox->u.mqe.un.alloc_rsrc_extents.u.req,
+		       rsrc_type);
+	else {
+		/* This is DMA data.  Byteswap is required. */
+		bf_set(lpfc_mbx_alloc_rsrc_extents_type,
+		       n_rsrc_extnt, rsrc_type);
+		lpfc_sli_pcimem_bcopy(&n_rsrc_extnt->word4,
+				      &n_rsrc_extnt->word4,
+				      sizeof(uint32_t));
+	}
+
+	/* Complete the initialization for the particular Opcode. */
+	opcode = lpfc_sli4_mbox_opcode_get(phba, mbox);
+	switch (opcode) {
+	case LPFC_MBOX_OPCODE_ALLOC_RSRC_EXTENT:
+		if (emb == LPFC_SLI4_MBX_EMBED)
+			bf_set(lpfc_mbx_alloc_rsrc_extents_cnt,
+			       &mbox->u.mqe.un.alloc_rsrc_extents.u.req,
+			       exts_count);
+		else
+			bf_set(lpfc_mbx_alloc_rsrc_extents_cnt,
+			       n_rsrc_extnt, exts_count);
+		break;
+	case LPFC_MBOX_OPCODE_GET_ALLOC_RSRC_EXTENT:
+	case LPFC_MBOX_OPCODE_GET_RSRC_EXTENT_INFO:
+	case LPFC_MBOX_OPCODE_DEALLOC_RSRC_EXTENT:
+		/* Initialization is complete.*/
+		break;
+	default:
+		lpfc_printf_log(phba, KERN_ERR, LOG_MBOX,
+				"2929 Resource Extent Opcode x%x is "
+				"unsupported\n", opcode);
+		return 1;
+	}
+
+	return 0;
+}
+
+/**
  * lpfc_sli4_mbox_opcode_get - Get the opcode from a sli4 mailbox command
  * @phba: pointer to lpfc hba data structure.
  * @mbox: pointer to lpfc mbox command.
@@ -1939,9 +2029,12 @@
 	bf_set(lpfc_init_vfi_vr, init_vfi, 1);
 	bf_set(lpfc_init_vfi_vt, init_vfi, 1);
 	bf_set(lpfc_init_vfi_vp, init_vfi, 1);
-	bf_set(lpfc_init_vfi_vfi, init_vfi, vport->vfi + vport->phba->vfi_base);
-	bf_set(lpfc_init_vpi_vpi, init_vfi, vport->vpi + vport->phba->vpi_base);
-	bf_set(lpfc_init_vfi_fcfi, init_vfi, vport->phba->fcf.fcfi);
+	bf_set(lpfc_init_vfi_vfi, init_vfi,
+	       vport->phba->sli4_hba.vfi_ids[vport->vfi]);
+	bf_set(lpfc_init_vpi_vpi, init_vfi,
+	       vport->phba->vpi_ids[vport->vpi]);
+	bf_set(lpfc_init_vfi_fcfi, init_vfi,
+	       vport->phba->fcf.fcfi);
 }
 
 /**
@@ -1964,9 +2057,10 @@
 	reg_vfi = &mbox->u.mqe.un.reg_vfi;
 	bf_set(lpfc_mqe_command, &mbox->u.mqe, MBX_REG_VFI);
 	bf_set(lpfc_reg_vfi_vp, reg_vfi, 1);
-	bf_set(lpfc_reg_vfi_vfi, reg_vfi, vport->vfi + vport->phba->vfi_base);
+	bf_set(lpfc_reg_vfi_vfi, reg_vfi,
+	       vport->phba->sli4_hba.vfi_ids[vport->vfi]);
 	bf_set(lpfc_reg_vfi_fcfi, reg_vfi, vport->phba->fcf.fcfi);
-	bf_set(lpfc_reg_vfi_vpi, reg_vfi, vport->vpi + vport->phba->vpi_base);
+	bf_set(lpfc_reg_vfi_vpi, reg_vfi, vport->phba->vpi_ids[vport->vpi]);
 	memcpy(reg_vfi->wwn, &vport->fc_portname, sizeof(struct lpfc_name));
 	reg_vfi->wwn[0] = cpu_to_le32(reg_vfi->wwn[0]);
 	reg_vfi->wwn[1] = cpu_to_le32(reg_vfi->wwn[1]);
@@ -1997,9 +2091,9 @@
 	memset(mbox, 0, sizeof(*mbox));
 	bf_set(lpfc_mqe_command, &mbox->u.mqe, MBX_INIT_VPI);
 	bf_set(lpfc_init_vpi_vpi, &mbox->u.mqe.un.init_vpi,
-	       vpi + phba->vpi_base);
+	       phba->vpi_ids[vpi]);
 	bf_set(lpfc_init_vpi_vfi, &mbox->u.mqe.un.init_vpi,
-	       phba->pport->vfi + phba->vfi_base);
+	       phba->sli4_hba.vfi_ids[phba->pport->vfi]);
 }
 
 /**
@@ -2019,7 +2113,7 @@
 	memset(mbox, 0, sizeof(*mbox));
 	bf_set(lpfc_mqe_command, &mbox->u.mqe, MBX_UNREG_VFI);
 	bf_set(lpfc_unreg_vfi_vfi, &mbox->u.mqe.un.unreg_vfi,
-	       vport->vfi + vport->phba->vfi_base);
+	       vport->phba->sli4_hba.vfi_ids[vport->vfi]);
 }
 
 /**
@@ -2131,12 +2225,14 @@
 void
 lpfc_resume_rpi(struct lpfcMboxq *mbox, struct lpfc_nodelist *ndlp)
 {
+	struct lpfc_hba *phba = ndlp->phba;
 	struct lpfc_mbx_resume_rpi *resume_rpi;
 
 	memset(mbox, 0, sizeof(*mbox));
 	resume_rpi = &mbox->u.mqe.un.resume_rpi;
 	bf_set(lpfc_mqe_command, &mbox->u.mqe, MBX_RESUME_RPI);
-	bf_set(lpfc_resume_rpi_index, resume_rpi, ndlp->nlp_rpi);
+	bf_set(lpfc_resume_rpi_index, resume_rpi,
+	       phba->sli4_hba.rpi_ids[ndlp->nlp_rpi]);
 	bf_set(lpfc_resume_rpi_ii, resume_rpi, RESUME_INDEX_RPI);
 	resume_rpi->event_tag = ndlp->phba->fc_eventTag;
 }
diff -druN linux-2.6.39-libre/drivers/scsi/lpfc/lpfc_mem.c linux-3.0-rc7-libre/drivers/scsi/lpfc/lpfc_mem.c
--- linux-2.6.39-libre/drivers/scsi/lpfc/lpfc_mem.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/scsi/lpfc/lpfc_mem.c	2011-07-11 19:51:52.000000000 -0400
@@ -62,7 +62,6 @@
 lpfc_mem_alloc(struct lpfc_hba *phba, int align)
 {
 	struct lpfc_dma_pool *pool = &phba->lpfc_mbuf_safety_pool;
-	int longs;
 	int i;
 
 	if (phba->sli_rev == LPFC_SLI_REV4)
@@ -138,17 +137,8 @@
 		phba->lpfc_hrb_pool = NULL;
 		phba->lpfc_drb_pool = NULL;
 	}
-	/* vpi zero is reserved for the physical port so add 1 to max */
-	longs = ((phba->max_vpi + 1) + BITS_PER_LONG - 1) / BITS_PER_LONG;
-	phba->vpi_bmask = kzalloc(longs * sizeof(unsigned long), GFP_KERNEL);
-	if (!phba->vpi_bmask)
-		goto fail_free_dbq_pool;
 
 	return 0;
-
- fail_free_dbq_pool:
-	pci_pool_destroy(phba->lpfc_drb_pool);
-	phba->lpfc_drb_pool = NULL;
  fail_free_hrb_pool:
 	pci_pool_destroy(phba->lpfc_hrb_pool);
 	phba->lpfc_hrb_pool = NULL;
@@ -191,9 +181,6 @@
 	int i;
 	struct lpfc_dma_pool *pool = &phba->lpfc_mbuf_safety_pool;
 
-	/* Free VPI bitmask memory */
-	kfree(phba->vpi_bmask);
-
 	/* Free HBQ pools */
 	lpfc_sli_hbqbuf_free_all(phba);
 	if (phba->lpfc_drb_pool)
diff -druN linux-2.6.39-libre/drivers/scsi/lpfc/lpfc_nportdisc.c linux-3.0-rc7-libre/drivers/scsi/lpfc/lpfc_nportdisc.c
--- linux-2.6.39-libre/drivers/scsi/lpfc/lpfc_nportdisc.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/scsi/lpfc/lpfc_nportdisc.c	2011-07-11 19:51:52.000000000 -0400
@@ -350,11 +350,7 @@
 	ndlp->nlp_maxframe =
 		((sp->cmn.bbRcvSizeMsb & 0x0F) << 8) | sp->cmn.bbRcvSizeLsb;
 
-	/*
-	 * Need to unreg_login if we are already in one of these states and
-	 * change to NPR state. This will block the port until after the ACC
-	 * completes and the reg_login is issued and completed.
-	 */
+	/* no need to reg_login if we are already in one of these states */
 	switch (ndlp->nlp_state) {
 	case  NLP_STE_NPR_NODE:
 		if (!(ndlp->nlp_flag & NLP_NPR_ADISC))
@@ -363,9 +359,8 @@
 	case  NLP_STE_PRLI_ISSUE:
 	case  NLP_STE_UNMAPPED_NODE:
 	case  NLP_STE_MAPPED_NODE:
-		lpfc_unreg_rpi(vport, ndlp);
-		ndlp->nlp_prev_state = ndlp->nlp_state;
-		lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE);
+		lpfc_els_rsp_acc(vport, ELS_CMD_PLOGI, cmdiocb, ndlp, NULL);
+		return 1;
 	}
 
 	if ((vport->fc_flag & FC_PT2PT) &&
@@ -657,6 +652,7 @@
 	lpfc_unreg_rpi(vport, ndlp);
 	return 0;
 }
+
 /**
  * lpfc_release_rpi - Release a RPI by issuing unreg_login mailbox cmd.
  * @phba : Pointer to lpfc_hba structure.
@@ -1399,8 +1395,11 @@
 	if (mb->mbxStatus) {
 		/* RegLogin failed */
 		lpfc_printf_vlog(vport, KERN_ERR, LOG_DISCOVERY,
-				"0246 RegLogin failed Data: x%x x%x x%x\n",
-				did, mb->mbxStatus, vport->port_state);
+				"0246 RegLogin failed Data: x%x x%x x%x x%x "
+				 "x%x\n",
+				 did, mb->mbxStatus, vport->port_state,
+				 mb->un.varRegLogin.vpi,
+				 mb->un.varRegLogin.rpi);
 		/*
 		 * If RegLogin failed due to lack of HBA resources do not
 		 * retry discovery.
@@ -1424,7 +1423,10 @@
 		return ndlp->nlp_state;
 	}
 
-	ndlp->nlp_rpi = mb->un.varWords[0];
+	/* SLI4 ports have preallocated logical rpis. */
+	if (vport->phba->sli_rev < LPFC_SLI_REV4)
+		ndlp->nlp_rpi = mb->un.varWords[0];
+
 	ndlp->nlp_flag |= NLP_RPI_REGISTERED;
 
 	/* Only if we are not a fabric nport do we issue PRLI */
@@ -2025,7 +2027,9 @@
 	MAILBOX_t    *mb = &pmb->u.mb;
 
 	if (!mb->mbxStatus) {
-		ndlp->nlp_rpi = mb->un.varWords[0];
+		/* SLI4 ports have preallocated logical rpis. */
+		if (vport->phba->sli_rev < LPFC_SLI_REV4)
+			ndlp->nlp_rpi = mb->un.varWords[0];
 		ndlp->nlp_flag |= NLP_RPI_REGISTERED;
 	} else {
 		if (ndlp->nlp_flag & NLP_NODEV_REMOVE) {
diff -druN linux-2.6.39-libre/drivers/scsi/lpfc/lpfc_scsi.c linux-3.0-rc7-libre/drivers/scsi/lpfc/lpfc_scsi.c
--- linux-2.6.39-libre/drivers/scsi/lpfc/lpfc_scsi.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/scsi/lpfc/lpfc_scsi.c	2011-07-11 19:51:52.000000000 -0400
@@ -743,7 +743,14 @@
 		if (bcnt == 0)
 			continue;
 		/* Now, post the SCSI buffer list sgls as a block */
-		status = lpfc_sli4_post_scsi_sgl_block(phba, &sblist, bcnt);
+		if (!phba->sli4_hba.extents_in_use)
+			status = lpfc_sli4_post_scsi_sgl_block(phba,
+							&sblist,
+							bcnt);
+		else
+			status = lpfc_sli4_post_scsi_sgl_blk_ext(phba,
+							&sblist,
+							bcnt);
 		/* Reset SCSI buffer count for next round of posting */
 		bcnt = 0;
 		while (!list_empty(&sblist)) {
@@ -787,7 +794,7 @@
 	dma_addr_t pdma_phys_fcp_cmd;
 	dma_addr_t pdma_phys_fcp_rsp;
 	dma_addr_t pdma_phys_bpl, pdma_phys_bpl1;
-	uint16_t iotag, last_xritag = NO_XRI;
+	uint16_t iotag, last_xritag = NO_XRI, lxri = 0;
 	int status = 0, index;
 	int bcnt;
 	int non_sequential_xri = 0;
@@ -823,13 +830,15 @@
 			break;
 		}
 
-		psb->cur_iocbq.sli4_xritag = lpfc_sli4_next_xritag(phba);
-		if (psb->cur_iocbq.sli4_xritag == NO_XRI) {
+		lxri = lpfc_sli4_next_xritag(phba);
+		if (lxri == NO_XRI) {
 			pci_pool_free(phba->lpfc_scsi_dma_buf_pool,
 			      psb->data, psb->dma_handle);
 			kfree(psb);
 			break;
 		}
+		psb->cur_iocbq.sli4_lxritag = lxri;
+		psb->cur_iocbq.sli4_xritag = phba->sli4_hba.xri_ids[lxri];
 		if (last_xritag != NO_XRI
 			&& psb->cur_iocbq.sli4_xritag != (last_xritag+1)) {
 			non_sequential_xri = 1;
@@ -861,6 +870,7 @@
 		 */
 		sgl->addr_hi = cpu_to_le32(putPaddrHigh(pdma_phys_fcp_cmd));
 		sgl->addr_lo = cpu_to_le32(putPaddrLow(pdma_phys_fcp_cmd));
+		sgl->word2 = le32_to_cpu(sgl->word2);
 		bf_set(lpfc_sli4_sge_last, sgl, 0);
 		sgl->word2 = cpu_to_le32(sgl->word2);
 		sgl->sge_len = cpu_to_le32(sizeof(struct fcp_cmnd));
@@ -869,6 +879,7 @@
 		/* 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));
+		sgl->word2 = le32_to_cpu(sgl->word2);
 		bf_set(lpfc_sli4_sge_last, sgl, 1);
 		sgl->word2 = cpu_to_le32(sgl->word2);
 		sgl->sge_len = cpu_to_le32(sizeof(struct fcp_rsp));
@@ -914,7 +925,21 @@
 		}
 	}
 	if (bcnt) {
-		status = lpfc_sli4_post_scsi_sgl_block(phba, &sblist, bcnt);
+		if (!phba->sli4_hba.extents_in_use)
+			status = lpfc_sli4_post_scsi_sgl_block(phba,
+								&sblist,
+								bcnt);
+		else
+			status = lpfc_sli4_post_scsi_sgl_blk_ext(phba,
+								&sblist,
+								bcnt);
+
+		if (status) {
+			lpfc_printf_log(phba, KERN_ERR, LOG_MBOX | LOG_SLI,
+					"3021 SCSI SGL post error %d\n",
+					status);
+			bcnt = 0;
+		}
 		/* Reset SCSI buffer count for next round of posting */
 		while (!list_empty(&sblist)) {
 			list_remove_head(&sblist, psb, struct lpfc_scsi_buf,
@@ -2081,6 +2106,7 @@
 			dma_len = sg_dma_len(sgel);
 			sgl->addr_lo = cpu_to_le32(putPaddrLow(physaddr));
 			sgl->addr_hi = cpu_to_le32(putPaddrHigh(physaddr));
+			sgl->word2 = le32_to_cpu(sgl->word2);
 			if ((num_bde + 1) == nseg)
 				bf_set(lpfc_sli4_sge_last, sgl, 1);
 			else
@@ -2794,6 +2820,9 @@
 	 * of the scsi_cmnd request_buffer
 	 */
 	piocbq->iocb.ulpContext = pnode->nlp_rpi;
+	if (phba->sli_rev == LPFC_SLI_REV4)
+		piocbq->iocb.ulpContext =
+		  phba->sli4_hba.rpi_ids[pnode->nlp_rpi];
 	if (pnode->nlp_fcp_info & NLP_FCP_2_DEVICE)
 		piocbq->iocb.ulpFCP2Rcvy = 1;
 	else
@@ -2807,7 +2836,7 @@
 }
 
 /**
- * lpfc_scsi_prep_task_mgmt_cmnd - Convert SLI3 scsi TM cmd to FCP info unit
+ * lpfc_scsi_prep_task_mgmt_cmd - Convert SLI3 scsi TM cmd to FCP info unit
  * @vport: The virtual port for which this call is being executed.
  * @lpfc_cmd: Pointer to lpfc_scsi_buf data structure.
  * @lun: Logical unit number.
@@ -2851,6 +2880,10 @@
 		lpfc_fcpcmd_to_iocb(piocb->unsli3.fcp_ext.icd, fcp_cmnd);
 	piocb->ulpCommand = CMD_FCP_ICMND64_CR;
 	piocb->ulpContext = ndlp->nlp_rpi;
+	if (vport->phba->sli_rev == LPFC_SLI_REV4) {
+		piocb->ulpContext =
+		  vport->phba->sli4_hba.rpi_ids[ndlp->nlp_rpi];
+	}
 	if (ndlp->nlp_fcp_info & NLP_FCP_2_DEVICE) {
 		piocb->ulpFCP2Rcvy = 1;
 	}
@@ -3238,9 +3271,8 @@
 	if (!lpfc_cmd) {
 		lpfc_printf_vlog(vport, KERN_WARNING, LOG_FCP,
 			 "2873 SCSI Layer I/O Abort Request IO CMPL Status "
-			 "x%x ID %d "
-			 "LUN %d snum %#lx\n", ret, cmnd->device->id,
-			 cmnd->device->lun, cmnd->serial_number);
+			 "x%x ID %d LUN %d\n",
+			 ret, cmnd->device->id, cmnd->device->lun);
 		return SUCCESS;
 	}
 
@@ -3318,16 +3350,15 @@
 		lpfc_printf_vlog(vport, KERN_ERR, LOG_FCP,
 				 "0748 abort handler timed out waiting "
 				 "for abort to complete: ret %#x, ID %d, "
-				 "LUN %d, snum %#lx\n",
-				 ret, cmnd->device->id, cmnd->device->lun,
-				 cmnd->serial_number);
+				 "LUN %d\n",
+				 ret, cmnd->device->id, cmnd->device->lun);
 	}
 
  out:
 	lpfc_printf_vlog(vport, KERN_WARNING, LOG_FCP,
 			 "0749 SCSI Layer I/O Abort Request Status x%x ID %d "
-			 "LUN %d snum %#lx\n", ret, cmnd->device->id,
-			 cmnd->device->lun, cmnd->serial_number);
+			 "LUN %d\n", ret, cmnd->device->id,
+			 cmnd->device->lun);
 	return ret;
 }
 
@@ -3407,9 +3438,10 @@
 
 	lpfc_printf_vlog(vport, KERN_INFO, LOG_FCP,
 			 "0702 Issue %s to TGT %d LUN %d "
-			 "rpi x%x nlp_flag x%x\n",
+			 "rpi x%x nlp_flag x%x Data: x%x x%x\n",
 			 lpfc_taskmgmt_name(task_mgmt_cmd), tgt_id, lun_id,
-			 pnode->nlp_rpi, pnode->nlp_flag);
+			 pnode->nlp_rpi, pnode->nlp_flag, iocbq->sli4_xritag,
+			 iocbq->iocb_flag);
 
 	status = lpfc_sli_issue_iocb_wait(phba, LPFC_FCP_RING,
 					  iocbq, iocbqrsp, lpfc_cmd->timeout);
@@ -3421,10 +3453,12 @@
 			ret = FAILED;
 		lpfc_cmd->status = IOSTAT_DRIVER_REJECT;
 		lpfc_printf_vlog(vport, KERN_ERR, LOG_FCP,
-			 "0727 TMF %s to TGT %d LUN %d failed (%d, %d)\n",
+			 "0727 TMF %s to TGT %d LUN %d failed (%d, %d) "
+			 "iocb_flag x%x\n",
 			 lpfc_taskmgmt_name(task_mgmt_cmd),
 			 tgt_id, lun_id, iocbqrsp->iocb.ulpStatus,
-			 iocbqrsp->iocb.un.ulpWord[4]);
+			 iocbqrsp->iocb.un.ulpWord[4],
+			 iocbq->iocb_flag);
 	} else if (status == IOCB_BUSY)
 		ret = FAILED;
 	else
diff -druN linux-2.6.39-libre/drivers/scsi/lpfc/lpfc_sli4.h linux-3.0-rc7-libre/drivers/scsi/lpfc/lpfc_sli4.h
--- linux-2.6.39-libre/drivers/scsi/lpfc/lpfc_sli4.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/scsi/lpfc/lpfc_sli4.h	2011-07-11 19:51:52.000000000 -0400
@@ -310,7 +310,6 @@
 	uint16_t vfi_base;
 	uint16_t vfi_used;
 	uint16_t max_fcfi;
-	uint16_t fcfi_base;
 	uint16_t fcfi_used;
 	uint16_t max_eq;
 	uint16_t max_rq;
@@ -365,6 +364,11 @@
 	uint8_t rqv;
 };
 
+struct lpfc_iov {
+	uint32_t pf_number;
+	uint32_t vf_number;
+};
+
 /* SLI4 HBA data structure entries */
 struct lpfc_sli4_hba {
 	void __iomem *conf_regs_memmap_p; /* Kernel memory mapped address for
@@ -444,10 +448,13 @@
 	uint32_t intr_enable;
 	struct lpfc_bmbx bmbx;
 	struct lpfc_max_cfg_param max_cfg_param;
+	uint16_t extents_in_use; /* must allocate resource extents. */
+	uint16_t rpi_hdrs_in_use; /* must post rpi hdrs if set. */
 	uint16_t next_xri; /* last_xri - max_cfg_param.xri_base = used */
 	uint16_t next_rpi;
 	uint16_t scsi_xri_max;
 	uint16_t scsi_xri_cnt;
+	uint16_t scsi_xri_start;
 	struct list_head lpfc_free_sgl_list;
 	struct list_head lpfc_sgl_list;
 	struct lpfc_sglq **lpfc_els_sgl_array;
@@ -458,7 +465,17 @@
 	struct lpfc_sglq **lpfc_sglq_active_list;
 	struct list_head lpfc_rpi_hdr_list;
 	unsigned long *rpi_bmask;
+	uint16_t *rpi_ids;
 	uint16_t rpi_count;
+	struct list_head lpfc_rpi_blk_list;
+	unsigned long *xri_bmask;
+	uint16_t *xri_ids;
+	uint16_t xri_count;
+	struct list_head lpfc_xri_blk_list;
+	unsigned long *vfi_bmask;
+	uint16_t *vfi_ids;
+	uint16_t vfi_count;
+	struct list_head lpfc_vfi_blk_list;
 	struct lpfc_sli4_flags sli4_flags;
 	struct list_head sp_queue_event;
 	struct list_head sp_cqe_event_pool;
@@ -467,6 +484,7 @@
 	struct list_head sp_els_xri_aborted_work_queue;
 	struct list_head sp_unsol_work_queue;
 	struct lpfc_sli4_link link_state;
+	struct lpfc_iov iov;
 	spinlock_t abts_scsi_buf_list_lock; /* list of aborted SCSI IOs */
 	spinlock_t abts_sgl_list_lock; /* list of aborted els IOs */
 };
@@ -490,6 +508,7 @@
 	enum lpfc_sgl_state state;
 	struct lpfc_nodelist *ndlp; /* ndlp associated with IO */
 	uint16_t iotag;         /* pre-assigned IO tag */
+	uint16_t sli4_lxritag;  /* logical pre-assigned xri. */
 	uint16_t sli4_xritag;   /* pre-assigned XRI, (OXID) tag. */
 	struct sli4_sge *sgl;	/* pre-assigned SGL */
 	void *virt;		/* virtual address. */
@@ -504,6 +523,13 @@
 	uint32_t start_rpi;
 };
 
+struct lpfc_rsrc_blks {
+	struct list_head list;
+	uint16_t rsrc_start;
+	uint16_t rsrc_size;
+	uint16_t rsrc_used;
+};
+
 /*
  * SLI4 specific function prototypes
  */
@@ -543,8 +569,11 @@
 int lpfc_sli4_repost_scsi_sgl_list(struct lpfc_hba *);
 uint16_t lpfc_sli4_next_xritag(struct lpfc_hba *);
 int lpfc_sli4_post_async_mbox(struct lpfc_hba *);
-int lpfc_sli4_post_sgl_list(struct lpfc_hba *phba);
+int lpfc_sli4_post_els_sgl_list(struct lpfc_hba *phba);
+int lpfc_sli4_post_els_sgl_list_ext(struct lpfc_hba *phba);
 int lpfc_sli4_post_scsi_sgl_block(struct lpfc_hba *, struct list_head *, int);
+int lpfc_sli4_post_scsi_sgl_blk_ext(struct lpfc_hba *, struct list_head *,
+				    int);
 struct lpfc_cq_event *__lpfc_sli4_cq_event_alloc(struct lpfc_hba *);
 struct lpfc_cq_event *lpfc_sli4_cq_event_alloc(struct lpfc_hba *);
 void __lpfc_sli4_cq_event_release(struct lpfc_hba *, struct lpfc_cq_event *);
diff -druN linux-2.6.39-libre/drivers/scsi/lpfc/lpfc_sli.c linux-3.0-rc7-libre/drivers/scsi/lpfc/lpfc_sli.c
--- linux-2.6.39-libre/drivers/scsi/lpfc/lpfc_sli.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/scsi/lpfc/lpfc_sli.c	2011-07-11 19:51:52.000000000 -0400
@@ -65,6 +65,9 @@
 							 struct lpfc_iocbq *);
 static void lpfc_sli4_send_seq_to_ulp(struct lpfc_vport *,
 				      struct hbq_dmabuf *);
+static int lpfc_sli4_fp_handle_wcqe(struct lpfc_hba *, struct lpfc_queue *,
+				    struct lpfc_cqe *);
+
 static IOCB_t *
 lpfc_get_iocb_from_iocbq(struct lpfc_iocbq *iocbq)
 {
@@ -456,7 +459,6 @@
 	struct lpfc_iocbq * iocbq = NULL;
 
 	list_remove_head(lpfc_iocb_list, iocbq, struct lpfc_iocbq, list);
-
 	if (iocbq)
 		phba->iocb_cnt++;
 	if (phba->iocb_cnt > phba->iocb_max)
@@ -479,13 +481,10 @@
 static struct lpfc_sglq *
 __lpfc_clear_active_sglq(struct lpfc_hba *phba, uint16_t xritag)
 {
-	uint16_t adj_xri;
 	struct lpfc_sglq *sglq;
-	adj_xri = xritag - phba->sli4_hba.max_cfg_param.xri_base;
-	if (adj_xri > phba->sli4_hba.max_cfg_param.max_xri)
-		return NULL;
-	sglq = phba->sli4_hba.lpfc_sglq_active_list[adj_xri];
-	phba->sli4_hba.lpfc_sglq_active_list[adj_xri] = NULL;
+
+	sglq = phba->sli4_hba.lpfc_sglq_active_list[xritag];
+	phba->sli4_hba.lpfc_sglq_active_list[xritag] = NULL;
 	return sglq;
 }
 
@@ -504,12 +503,9 @@
 struct lpfc_sglq *
 __lpfc_get_active_sglq(struct lpfc_hba *phba, uint16_t xritag)
 {
-	uint16_t adj_xri;
 	struct lpfc_sglq *sglq;
-	adj_xri = xritag - phba->sli4_hba.max_cfg_param.xri_base;
-	if (adj_xri > phba->sli4_hba.max_cfg_param.max_xri)
-		return NULL;
-	sglq =  phba->sli4_hba.lpfc_sglq_active_list[adj_xri];
+
+	sglq =  phba->sli4_hba.lpfc_sglq_active_list[xritag];
 	return sglq;
 }
 
@@ -532,7 +528,6 @@
 __lpfc_set_rrq_active(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp,
 		uint16_t xritag, uint16_t rxid, uint16_t send_rrq)
 {
-	uint16_t adj_xri;
 	struct lpfc_node_rrq *rrq;
 	int empty;
 	uint32_t did = 0;
@@ -553,21 +548,19 @@
 	/*
 	 * set the active bit even if there is no mem available.
 	 */
-	adj_xri = xritag - phba->sli4_hba.max_cfg_param.xri_base;
-
 	if (NLP_CHK_FREE_REQ(ndlp))
 		goto out;
 
 	if (ndlp->vport && (ndlp->vport->load_flag & FC_UNLOADING))
 		goto out;
 
-	if (test_and_set_bit(adj_xri, ndlp->active_rrqs.xri_bitmap))
+	if (test_and_set_bit(xritag, ndlp->active_rrqs.xri_bitmap))
 		goto out;
 
 	rrq = mempool_alloc(phba->rrq_pool, GFP_KERNEL);
 	if (rrq) {
 		rrq->send_rrq = send_rrq;
-		rrq->xritag = xritag;
+		rrq->xritag = phba->sli4_hba.xri_ids[xritag];
 		rrq->rrq_stop_time = jiffies + HZ * (phba->fc_ratov + 1);
 		rrq->ndlp = ndlp;
 		rrq->nlp_DID = ndlp->nlp_DID;
@@ -603,7 +596,6 @@
 		    uint16_t xritag,
 		    struct lpfc_node_rrq *rrq)
 {
-	uint16_t adj_xri;
 	struct lpfc_nodelist *ndlp = NULL;
 
 	if ((rrq->vport) && NLP_CHK_NODE_ACT(rrq->ndlp))
@@ -619,8 +611,7 @@
 	if (!ndlp)
 		goto out;
 
-	adj_xri = xritag - phba->sli4_hba.max_cfg_param.xri_base;
-	if (test_and_clear_bit(adj_xri, ndlp->active_rrqs.xri_bitmap)) {
+	if (test_and_clear_bit(xritag, ndlp->active_rrqs.xri_bitmap)) {
 		rrq->send_rrq = 0;
 		rrq->xritag = 0;
 		rrq->rrq_stop_time = 0;
@@ -796,12 +787,9 @@
 lpfc_test_rrq_active(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp,
 			uint16_t  xritag)
 {
-	uint16_t adj_xri;
-
-	adj_xri = xritag - phba->sli4_hba.max_cfg_param.xri_base;
 	if (!ndlp)
 		return 0;
-	if (test_bit(adj_xri, ndlp->active_rrqs.xri_bitmap))
+	if (test_bit(xritag, ndlp->active_rrqs.xri_bitmap))
 			return 1;
 	else
 		return 0;
@@ -841,7 +829,7 @@
  * @piocb: Pointer to the iocbq.
  *
  * This function is called with hbalock held. This function
- * Gets a new driver sglq object from the sglq list. If the
+ * gets a new driver sglq object from the sglq list. If the
  * list is not empty then it is successful, it returns pointer to the newly
  * allocated sglq object else it returns NULL.
  **/
@@ -851,7 +839,6 @@
 	struct list_head *lpfc_sgl_list = &phba->sli4_hba.lpfc_sgl_list;
 	struct lpfc_sglq *sglq = NULL;
 	struct lpfc_sglq *start_sglq = NULL;
-	uint16_t adj_xri;
 	struct lpfc_scsi_buf *lpfc_cmd;
 	struct lpfc_nodelist *ndlp;
 	int found = 0;
@@ -870,8 +857,6 @@
 	while (!found) {
 		if (!sglq)
 			return NULL;
-		adj_xri = sglq->sli4_xritag -
-				phba->sli4_hba.max_cfg_param.xri_base;
 		if (lpfc_test_rrq_active(phba, ndlp, sglq->sli4_xritag)) {
 			/* This xri has an rrq outstanding for this DID.
 			 * put it back in the list and get another xri.
@@ -888,7 +873,7 @@
 		}
 		sglq->ndlp = ndlp;
 		found = 1;
-		phba->sli4_hba.lpfc_sglq_active_list[adj_xri] = sglq;
+		phba->sli4_hba.lpfc_sglq_active_list[sglq->sli4_lxritag] = sglq;
 		sglq->state = SGL_ALLOCATED;
 	}
 	return sglq;
@@ -944,7 +929,8 @@
 	if (iocbq->sli4_xritag == NO_XRI)
 		sglq = NULL;
 	else
-		sglq = __lpfc_clear_active_sglq(phba, iocbq->sli4_xritag);
+		sglq = __lpfc_clear_active_sglq(phba, iocbq->sli4_lxritag);
+
 	if (sglq)  {
 		if ((iocbq->iocb_flag & LPFC_EXCHANGE_BUSY) &&
 			(sglq->state != SGL_XRI_ABORTED)) {
@@ -971,6 +957,7 @@
 	 * Clean all volatile data fields, preserve iotag and node struct.
 	 */
 	memset((char *)iocbq + start_clean, 0, sizeof(*iocbq) - start_clean);
+	iocbq->sli4_lxritag = NO_XRI;
 	iocbq->sli4_xritag = NO_XRI;
 	list_add_tail(&iocbq->list, &phba->lpfc_iocb_list);
 }
@@ -2113,7 +2100,7 @@
 	    pmb->u.mb.mbxCommand == MBX_REG_LOGIN64 &&
 	    !pmb->u.mb.mbxStatus) {
 		rpi = pmb->u.mb.un.varWords[0];
-		vpi = pmb->u.mb.un.varRegLogin.vpi - phba->vpi_base;
+		vpi = pmb->u.mb.un.varRegLogin.vpi;
 		lpfc_unreg_login(phba, vpi, rpi, pmb);
 		pmb->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
 		rc = lpfc_sli_issue_mbox(phba, pmb, MBX_NOWAIT);
@@ -3040,7 +3027,7 @@
 	list_add_tail(&rspiocbp->list, &(pring->iocb_continueq));
 	pring->iocb_continueq_cnt++;
 
-	/* Now, determine whetehr the list is completed for processing */
+	/* Now, determine whether the list is completed for processing */
 	irsp = &rspiocbp->iocb;
 	if (irsp->ulpLe) {
 		/*
@@ -3881,8 +3868,10 @@
 	list_del_init(&phba->sli4_hba.els_cq->list);
 	for (qindx = 0; qindx < phba->cfg_fcp_wq_count; qindx++)
 		list_del_init(&phba->sli4_hba.fcp_wq[qindx]->list);
-	for (qindx = 0; qindx < phba->cfg_fcp_eq_count; qindx++)
+	qindx = 0;
+	do
 		list_del_init(&phba->sli4_hba.fcp_cq[qindx]->list);
+	while (++qindx < phba->cfg_fcp_eq_count);
 	spin_unlock_irq(&phba->hbalock);
 
 	/* Now physically reset the device */
@@ -4318,6 +4307,7 @@
 			continue;
 		} else if (rc)
 			break;
+
 		phba->link_state = LPFC_INIT_MBX_CMDS;
 		lpfc_config_port(phba, pmb);
 		rc = lpfc_sli_issue_mbox(phba, pmb, MBX_POLL);
@@ -4421,7 +4411,8 @@
 lpfc_sli_hba_setup(struct lpfc_hba *phba)
 {
 	uint32_t rc;
-	int  mode = 3;
+	int  mode = 3, i;
+	int longs;
 
 	switch (lpfc_sli_mode) {
 	case 2:
@@ -4491,6 +4482,35 @@
 	if (rc)
 		goto lpfc_sli_hba_setup_error;
 
+	/* Initialize VPIs. */
+	if (phba->sli_rev == LPFC_SLI_REV3) {
+		/*
+		 * The VPI bitmask and physical ID array are allocated
+		 * and initialized once only - at driver load.  A port
+		 * reset doesn't need to reinitialize this memory.
+		 */
+		if ((phba->vpi_bmask == NULL) && (phba->vpi_ids == NULL)) {
+			longs = (phba->max_vpi + BITS_PER_LONG) / BITS_PER_LONG;
+			phba->vpi_bmask = kzalloc(longs * sizeof(unsigned long),
+						  GFP_KERNEL);
+			if (!phba->vpi_bmask) {
+				rc = -ENOMEM;
+				goto lpfc_sli_hba_setup_error;
+			}
+
+			phba->vpi_ids = kzalloc(
+					(phba->max_vpi+1) * sizeof(uint16_t),
+					GFP_KERNEL);
+			if (!phba->vpi_ids) {
+				kfree(phba->vpi_bmask);
+				rc = -ENOMEM;
+				goto lpfc_sli_hba_setup_error;
+			}
+			for (i = 0; i < phba->max_vpi; i++)
+				phba->vpi_ids[i] = i;
+		}
+	}
+
 	/* Init HBQs */
 	if (phba->sli3_options & LPFC_SLI3_HBQ_ENABLED) {
 		rc = lpfc_sli_hbq_setup(phba);
@@ -4677,9 +4697,11 @@
 
 	lpfc_sli4_cq_release(phba->sli4_hba.mbx_cq, LPFC_QUEUE_REARM);
 	lpfc_sli4_cq_release(phba->sli4_hba.els_cq, LPFC_QUEUE_REARM);
-	for (fcp_eqidx = 0; fcp_eqidx < phba->cfg_fcp_eq_count; fcp_eqidx++)
+	fcp_eqidx = 0;
+	do
 		lpfc_sli4_cq_release(phba->sli4_hba.fcp_cq[fcp_eqidx],
 				     LPFC_QUEUE_REARM);
+	while (++fcp_eqidx < phba->cfg_fcp_eq_count);
 	lpfc_sli4_eq_release(phba->sli4_hba.sp_eq, LPFC_QUEUE_REARM);
 	for (fcp_eqidx = 0; fcp_eqidx < phba->cfg_fcp_eq_count; fcp_eqidx++)
 		lpfc_sli4_eq_release(phba->sli4_hba.fp_eq[fcp_eqidx],
@@ -4687,6 +4709,803 @@
 }
 
 /**
+ * lpfc_sli4_get_avail_extnt_rsrc - Get available resource extent count.
+ * @phba: Pointer to HBA context object.
+ * @type: The resource extent type.
+ *
+ * This function allocates all SLI4 resource identifiers.
+ **/
+static int
+lpfc_sli4_get_avail_extnt_rsrc(struct lpfc_hba *phba, uint16_t type,
+			       uint16_t *extnt_count, uint16_t *extnt_size)
+{
+	int rc = 0;
+	uint32_t length;
+	uint32_t mbox_tmo;
+	struct lpfc_mbx_get_rsrc_extent_info *rsrc_info;
+	LPFC_MBOXQ_t *mbox;
+
+	mbox = (LPFC_MBOXQ_t *) mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
+	if (!mbox)
+		return -ENOMEM;
+
+	/* Find out how many extents are available for this resource type */
+	length = (sizeof(struct lpfc_mbx_get_rsrc_extent_info) -
+		  sizeof(struct lpfc_sli4_cfg_mhdr));
+	lpfc_sli4_config(phba, mbox, LPFC_MBOX_SUBSYSTEM_COMMON,
+			 LPFC_MBOX_OPCODE_GET_RSRC_EXTENT_INFO,
+			 length, LPFC_SLI4_MBX_EMBED);
+
+	/* Send an extents count of 0 - the GET doesn't use it. */
+	rc = lpfc_sli4_mbox_rsrc_extent(phba, mbox, 0, type,
+					LPFC_SLI4_MBX_EMBED);
+	if (unlikely(rc)) {
+		rc = -EIO;
+		goto err_exit;
+	}
+
+	if (!phba->sli4_hba.intr_enable)
+		rc = lpfc_sli_issue_mbox(phba, mbox, MBX_POLL);
+	else {
+		mbox_tmo = lpfc_mbox_tmo_val(phba, MBX_SLI4_CONFIG);
+		rc = lpfc_sli_issue_mbox_wait(phba, mbox, mbox_tmo);
+	}
+	if (unlikely(rc)) {
+		rc = -EIO;
+		goto err_exit;
+	}
+
+	rsrc_info = &mbox->u.mqe.un.rsrc_extent_info;
+	if (bf_get(lpfc_mbox_hdr_status,
+		   &rsrc_info->header.cfg_shdr.response)) {
+		lpfc_printf_log(phba, KERN_ERR, LOG_MBOX | LOG_INIT,
+				"2930 Failed to get resource extents "
+				"Status 0x%x Add'l Status 0x%x\n",
+				bf_get(lpfc_mbox_hdr_status,
+				       &rsrc_info->header.cfg_shdr.response),
+				bf_get(lpfc_mbox_hdr_add_status,
+				       &rsrc_info->header.cfg_shdr.response));
+		rc = -EIO;
+		goto err_exit;
+	}
+
+	*extnt_count = bf_get(lpfc_mbx_get_rsrc_extent_info_cnt,
+			      &rsrc_info->u.rsp);
+	*extnt_size = bf_get(lpfc_mbx_get_rsrc_extent_info_size,
+			     &rsrc_info->u.rsp);
+ err_exit:
+	mempool_free(mbox, phba->mbox_mem_pool);
+	return rc;
+}
+
+/**
+ * lpfc_sli4_chk_avail_extnt_rsrc - Check for available SLI4 resource extents.
+ * @phba: Pointer to HBA context object.
+ * @type: The extent type to check.
+ *
+ * This function reads the current available extents from the port and checks
+ * if the extent count or extent size has changed since the last access.
+ * Callers use this routine post port reset to understand if there is a
+ * extent reprovisioning requirement.
+ *
+ * Returns:
+ *   -Error: error indicates problem.
+ *   1: Extent count or size has changed.
+ *   0: No changes.
+ **/
+static int
+lpfc_sli4_chk_avail_extnt_rsrc(struct lpfc_hba *phba, uint16_t type)
+{
+	uint16_t curr_ext_cnt, rsrc_ext_cnt;
+	uint16_t size_diff, rsrc_ext_size;
+	int rc = 0;
+	struct lpfc_rsrc_blks *rsrc_entry;
+	struct list_head *rsrc_blk_list = NULL;
+
+	size_diff = 0;
+	curr_ext_cnt = 0;
+	rc = lpfc_sli4_get_avail_extnt_rsrc(phba, type,
+					    &rsrc_ext_cnt,
+					    &rsrc_ext_size);
+	if (unlikely(rc))
+		return -EIO;
+
+	switch (type) {
+	case LPFC_RSC_TYPE_FCOE_RPI:
+		rsrc_blk_list = &phba->sli4_hba.lpfc_rpi_blk_list;
+		break;
+	case LPFC_RSC_TYPE_FCOE_VPI:
+		rsrc_blk_list = &phba->lpfc_vpi_blk_list;
+		break;
+	case LPFC_RSC_TYPE_FCOE_XRI:
+		rsrc_blk_list = &phba->sli4_hba.lpfc_xri_blk_list;
+		break;
+	case LPFC_RSC_TYPE_FCOE_VFI:
+		rsrc_blk_list = &phba->sli4_hba.lpfc_vfi_blk_list;
+		break;
+	default:
+		break;
+	}
+
+	list_for_each_entry(rsrc_entry, rsrc_blk_list, list) {
+		curr_ext_cnt++;
+		if (rsrc_entry->rsrc_size != rsrc_ext_size)
+			size_diff++;
+	}
+
+	if (curr_ext_cnt != rsrc_ext_cnt || size_diff != 0)
+		rc = 1;
+
+	return rc;
+}
+
+/**
+ * lpfc_sli4_cfg_post_extnts -
+ * @phba: Pointer to HBA context object.
+ * @extnt_cnt - number of available extents.
+ * @type - the extent type (rpi, xri, vfi, vpi).
+ * @emb - buffer to hold either MBX_EMBED or MBX_NEMBED operation.
+ * @mbox - pointer to the caller's allocated mailbox structure.
+ *
+ * This function executes the extents allocation request.  It also
+ * takes care of the amount of memory needed to allocate or get the
+ * allocated extents. It is the caller's responsibility to evaluate
+ * the response.
+ *
+ * Returns:
+ *   -Error:  Error value describes the condition found.
+ *   0: if successful
+ **/
+static int
+lpfc_sli4_cfg_post_extnts(struct lpfc_hba *phba, uint16_t *extnt_cnt,
+			  uint16_t type, bool *emb, LPFC_MBOXQ_t *mbox)
+{
+	int rc = 0;
+	uint32_t req_len;
+	uint32_t emb_len;
+	uint32_t alloc_len, mbox_tmo;
+
+	/* Calculate the total requested length of the dma memory */
+	req_len = *extnt_cnt * sizeof(uint16_t);
+
+	/*
+	 * Calculate the size of an embedded mailbox.  The uint32_t
+	 * accounts for extents-specific word.
+	 */
+	emb_len = sizeof(MAILBOX_t) - sizeof(struct mbox_header) -
+		sizeof(uint32_t);
+
+	/*
+	 * Presume the allocation and response will fit into an embedded
+	 * mailbox.  If not true, reconfigure to a non-embedded mailbox.
+	 */
+	*emb = LPFC_SLI4_MBX_EMBED;
+	if (req_len > emb_len) {
+		req_len = *extnt_cnt * sizeof(uint16_t) +
+			sizeof(union lpfc_sli4_cfg_shdr) +
+			sizeof(uint32_t);
+		*emb = LPFC_SLI4_MBX_NEMBED;
+	}
+
+	alloc_len = lpfc_sli4_config(phba, mbox, LPFC_MBOX_SUBSYSTEM_COMMON,
+				     LPFC_MBOX_OPCODE_ALLOC_RSRC_EXTENT,
+				     req_len, *emb);
+	if (alloc_len < req_len) {
+		lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
+			"9000 Allocated DMA memory size (x%x) is "
+			"less than the requested DMA memory "
+			"size (x%x)\n", alloc_len, req_len);
+		return -ENOMEM;
+	}
+	rc = lpfc_sli4_mbox_rsrc_extent(phba, mbox, *extnt_cnt, type, *emb);
+	if (unlikely(rc))
+		return -EIO;
+
+	if (!phba->sli4_hba.intr_enable)
+		rc = lpfc_sli_issue_mbox(phba, mbox, MBX_POLL);
+	else {
+		mbox_tmo = lpfc_mbox_tmo_val(phba, MBX_SLI4_CONFIG);
+		rc = lpfc_sli_issue_mbox_wait(phba, mbox, mbox_tmo);
+	}
+
+	if (unlikely(rc))
+		rc = -EIO;
+	return rc;
+}
+
+/**
+ * lpfc_sli4_alloc_extent - Allocate an SLI4 resource extent.
+ * @phba: Pointer to HBA context object.
+ * @type:  The resource extent type to allocate.
+ *
+ * This function allocates the number of elements for the specified
+ * resource type.
+ **/
+static int
+lpfc_sli4_alloc_extent(struct lpfc_hba *phba, uint16_t type)
+{
+	bool emb = false;
+	uint16_t rsrc_id_cnt, rsrc_cnt, rsrc_size;
+	uint16_t rsrc_id, rsrc_start, j, k;
+	uint16_t *ids;
+	int i, rc;
+	unsigned long longs;
+	unsigned long *bmask;
+	struct lpfc_rsrc_blks *rsrc_blks;
+	LPFC_MBOXQ_t *mbox;
+	uint32_t length;
+	struct lpfc_id_range *id_array = NULL;
+	void *virtaddr = NULL;
+	struct lpfc_mbx_nembed_rsrc_extent *n_rsrc;
+	struct lpfc_mbx_alloc_rsrc_extents *rsrc_ext;
+	struct list_head *ext_blk_list;
+
+	rc = lpfc_sli4_get_avail_extnt_rsrc(phba, type,
+					    &rsrc_cnt,
+					    &rsrc_size);
+	if (unlikely(rc))
+		return -EIO;
+
+	if ((rsrc_cnt == 0) || (rsrc_size == 0)) {
+		lpfc_printf_log(phba, KERN_ERR, LOG_MBOX | LOG_INIT,
+			"3009 No available Resource Extents "
+			"for resource type 0x%x: Count: 0x%x, "
+			"Size 0x%x\n", type, rsrc_cnt,
+			rsrc_size);
+		return -ENOMEM;
+	}
+
+	lpfc_printf_log(phba, KERN_INFO, LOG_MBOX | LOG_INIT,
+			"2903 Available Resource Extents "
+			"for resource type 0x%x: Count: 0x%x, "
+			"Size 0x%x\n", type, rsrc_cnt,
+			rsrc_size);
+
+	mbox = (LPFC_MBOXQ_t *) mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
+	if (!mbox)
+		return -ENOMEM;
+
+	rc = lpfc_sli4_cfg_post_extnts(phba, &rsrc_cnt, type, &emb, mbox);
+	if (unlikely(rc)) {
+		rc = -EIO;
+		goto err_exit;
+	}
+
+	/*
+	 * Figure out where the response is located.  Then get local pointers
+	 * to the response data.  The port does not guarantee to respond to
+	 * all extents counts request so update the local variable with the
+	 * allocated count from the port.
+	 */
+	if (emb == LPFC_SLI4_MBX_EMBED) {
+		rsrc_ext = &mbox->u.mqe.un.alloc_rsrc_extents;
+		id_array = &rsrc_ext->u.rsp.id[0];
+		rsrc_cnt = bf_get(lpfc_mbx_rsrc_cnt, &rsrc_ext->u.rsp);
+	} else {
+		virtaddr = mbox->sge_array->addr[0];
+		n_rsrc = (struct lpfc_mbx_nembed_rsrc_extent *) virtaddr;
+		rsrc_cnt = bf_get(lpfc_mbx_rsrc_cnt, n_rsrc);
+		id_array = &n_rsrc->id;
+	}
+
+	longs = ((rsrc_cnt * rsrc_size) + BITS_PER_LONG - 1) / BITS_PER_LONG;
+	rsrc_id_cnt = rsrc_cnt * rsrc_size;
+
+	/*
+	 * Based on the resource size and count, correct the base and max
+	 * resource values.
+	 */
+	length = sizeof(struct lpfc_rsrc_blks);
+	switch (type) {
+	case LPFC_RSC_TYPE_FCOE_RPI:
+		phba->sli4_hba.rpi_bmask = kzalloc(longs *
+						   sizeof(unsigned long),
+						   GFP_KERNEL);
+		if (unlikely(!phba->sli4_hba.rpi_bmask)) {
+			rc = -ENOMEM;
+			goto err_exit;
+		}
+		phba->sli4_hba.rpi_ids = kzalloc(rsrc_id_cnt *
+						 sizeof(uint16_t),
+						 GFP_KERNEL);
+		if (unlikely(!phba->sli4_hba.rpi_ids)) {
+			kfree(phba->sli4_hba.rpi_bmask);
+			rc = -ENOMEM;
+			goto err_exit;
+		}
+
+		/*
+		 * The next_rpi was initialized with the maximum available
+		 * count but the port may allocate a smaller number.  Catch
+		 * that case and update the next_rpi.
+		 */
+		phba->sli4_hba.next_rpi = rsrc_id_cnt;
+
+		/* Initialize local ptrs for common extent processing later. */
+		bmask = phba->sli4_hba.rpi_bmask;
+		ids = phba->sli4_hba.rpi_ids;
+		ext_blk_list = &phba->sli4_hba.lpfc_rpi_blk_list;
+		break;
+	case LPFC_RSC_TYPE_FCOE_VPI:
+		phba->vpi_bmask = kzalloc(longs *
+					  sizeof(unsigned long),
+					  GFP_KERNEL);
+		if (unlikely(!phba->vpi_bmask)) {
+			rc = -ENOMEM;
+			goto err_exit;
+		}
+		phba->vpi_ids = kzalloc(rsrc_id_cnt *
+					 sizeof(uint16_t),
+					 GFP_KERNEL);
+		if (unlikely(!phba->vpi_ids)) {
+			kfree(phba->vpi_bmask);
+			rc = -ENOMEM;
+			goto err_exit;
+		}
+
+		/* Initialize local ptrs for common extent processing later. */
+		bmask = phba->vpi_bmask;
+		ids = phba->vpi_ids;
+		ext_blk_list = &phba->lpfc_vpi_blk_list;
+		break;
+	case LPFC_RSC_TYPE_FCOE_XRI:
+		phba->sli4_hba.xri_bmask = kzalloc(longs *
+						   sizeof(unsigned long),
+						   GFP_KERNEL);
+		if (unlikely(!phba->sli4_hba.xri_bmask)) {
+			rc = -ENOMEM;
+			goto err_exit;
+		}
+		phba->sli4_hba.xri_ids = kzalloc(rsrc_id_cnt *
+						 sizeof(uint16_t),
+						 GFP_KERNEL);
+		if (unlikely(!phba->sli4_hba.xri_ids)) {
+			kfree(phba->sli4_hba.xri_bmask);
+			rc = -ENOMEM;
+			goto err_exit;
+		}
+
+		/* Initialize local ptrs for common extent processing later. */
+		bmask = phba->sli4_hba.xri_bmask;
+		ids = phba->sli4_hba.xri_ids;
+		ext_blk_list = &phba->sli4_hba.lpfc_xri_blk_list;
+		break;
+	case LPFC_RSC_TYPE_FCOE_VFI:
+		phba->sli4_hba.vfi_bmask = kzalloc(longs *
+						   sizeof(unsigned long),
+						   GFP_KERNEL);
+		if (unlikely(!phba->sli4_hba.vfi_bmask)) {
+			rc = -ENOMEM;
+			goto err_exit;
+		}
+		phba->sli4_hba.vfi_ids = kzalloc(rsrc_id_cnt *
+						 sizeof(uint16_t),
+						 GFP_KERNEL);
+		if (unlikely(!phba->sli4_hba.vfi_ids)) {
+			kfree(phba->sli4_hba.vfi_bmask);
+			rc = -ENOMEM;
+			goto err_exit;
+		}
+
+		/* Initialize local ptrs for common extent processing later. */
+		bmask = phba->sli4_hba.vfi_bmask;
+		ids = phba->sli4_hba.vfi_ids;
+		ext_blk_list = &phba->sli4_hba.lpfc_vfi_blk_list;
+		break;
+	default:
+		/* Unsupported Opcode.  Fail call. */
+		id_array = NULL;
+		bmask = NULL;
+		ids = NULL;
+		ext_blk_list = NULL;
+		goto err_exit;
+	}
+
+	/*
+	 * Complete initializing the extent configuration with the
+	 * allocated ids assigned to this function.  The bitmask serves
+	 * as an index into the array and manages the available ids.  The
+	 * array just stores the ids communicated to the port via the wqes.
+	 */
+	for (i = 0, j = 0, k = 0; i < rsrc_cnt; i++) {
+		if ((i % 2) == 0)
+			rsrc_id = bf_get(lpfc_mbx_rsrc_id_word4_0,
+					 &id_array[k]);
+		else
+			rsrc_id = bf_get(lpfc_mbx_rsrc_id_word4_1,
+					 &id_array[k]);
+
+		rsrc_blks = kzalloc(length, GFP_KERNEL);
+		if (unlikely(!rsrc_blks)) {
+			rc = -ENOMEM;
+			kfree(bmask);
+			kfree(ids);
+			goto err_exit;
+		}
+		rsrc_blks->rsrc_start = rsrc_id;
+		rsrc_blks->rsrc_size = rsrc_size;
+		list_add_tail(&rsrc_blks->list, ext_blk_list);
+		rsrc_start = rsrc_id;
+		if ((type == LPFC_RSC_TYPE_FCOE_XRI) && (j == 0))
+			phba->sli4_hba.scsi_xri_start = rsrc_start +
+				lpfc_sli4_get_els_iocb_cnt(phba);
+
+		while (rsrc_id < (rsrc_start + rsrc_size)) {
+			ids[j] = rsrc_id;
+			rsrc_id++;
+			j++;
+		}
+		/* Entire word processed.  Get next word.*/
+		if ((i % 2) == 1)
+			k++;
+	}
+ err_exit:
+	lpfc_sli4_mbox_cmd_free(phba, mbox);
+	return rc;
+}
+
+/**
+ * lpfc_sli4_dealloc_extent - Deallocate an SLI4 resource extent.
+ * @phba: Pointer to HBA context object.
+ * @type: the extent's type.
+ *
+ * This function deallocates all extents of a particular resource type.
+ * SLI4 does not allow for deallocating a particular extent range.  It
+ * is the caller's responsibility to release all kernel memory resources.
+ **/
+static int
+lpfc_sli4_dealloc_extent(struct lpfc_hba *phba, uint16_t type)
+{
+	int rc;
+	uint32_t length, mbox_tmo = 0;
+	LPFC_MBOXQ_t *mbox;
+	struct lpfc_mbx_dealloc_rsrc_extents *dealloc_rsrc;
+	struct lpfc_rsrc_blks *rsrc_blk, *rsrc_blk_next;
+
+	mbox = (LPFC_MBOXQ_t *) mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
+	if (!mbox)
+		return -ENOMEM;
+
+	/*
+	 * This function sends an embedded mailbox because it only sends the
+	 * the resource type.  All extents of this type are released by the
+	 * port.
+	 */
+	length = (sizeof(struct lpfc_mbx_dealloc_rsrc_extents) -
+		  sizeof(struct lpfc_sli4_cfg_mhdr));
+	lpfc_sli4_config(phba, mbox, LPFC_MBOX_SUBSYSTEM_COMMON,
+			 LPFC_MBOX_OPCODE_DEALLOC_RSRC_EXTENT,
+			 length, LPFC_SLI4_MBX_EMBED);
+
+	/* Send an extents count of 0 - the dealloc doesn't use it. */
+	rc = lpfc_sli4_mbox_rsrc_extent(phba, mbox, 0, type,
+					LPFC_SLI4_MBX_EMBED);
+	if (unlikely(rc)) {
+		rc = -EIO;
+		goto out_free_mbox;
+	}
+	if (!phba->sli4_hba.intr_enable)
+		rc = lpfc_sli_issue_mbox(phba, mbox, MBX_POLL);
+	else {
+		mbox_tmo = lpfc_mbox_tmo_val(phba, mbox_tmo);
+		rc = lpfc_sli_issue_mbox_wait(phba, mbox, mbox_tmo);
+	}
+	if (unlikely(rc)) {
+		rc = -EIO;
+		goto out_free_mbox;
+	}
+
+	dealloc_rsrc = &mbox->u.mqe.un.dealloc_rsrc_extents;
+	if (bf_get(lpfc_mbox_hdr_status,
+		   &dealloc_rsrc->header.cfg_shdr.response)) {
+		lpfc_printf_log(phba, KERN_ERR, LOG_MBOX | LOG_INIT,
+				"2919 Failed to release resource extents "
+				"for type %d - Status 0x%x Add'l Status 0x%x. "
+				"Resource memory not released.\n",
+				type,
+				bf_get(lpfc_mbox_hdr_status,
+				    &dealloc_rsrc->header.cfg_shdr.response),
+				bf_get(lpfc_mbox_hdr_add_status,
+				    &dealloc_rsrc->header.cfg_shdr.response));
+		rc = -EIO;
+		goto out_free_mbox;
+	}
+
+	/* Release kernel memory resources for the specific type. */
+	switch (type) {
+	case LPFC_RSC_TYPE_FCOE_VPI:
+		kfree(phba->vpi_bmask);
+		kfree(phba->vpi_ids);
+		bf_set(lpfc_vpi_rsrc_rdy, &phba->sli4_hba.sli4_flags, 0);
+		list_for_each_entry_safe(rsrc_blk, rsrc_blk_next,
+				    &phba->lpfc_vpi_blk_list, list) {
+			list_del_init(&rsrc_blk->list);
+			kfree(rsrc_blk);
+		}
+		break;
+	case LPFC_RSC_TYPE_FCOE_XRI:
+		kfree(phba->sli4_hba.xri_bmask);
+		kfree(phba->sli4_hba.xri_ids);
+		bf_set(lpfc_xri_rsrc_rdy, &phba->sli4_hba.sli4_flags, 0);
+		list_for_each_entry_safe(rsrc_blk, rsrc_blk_next,
+				    &phba->sli4_hba.lpfc_xri_blk_list, list) {
+			list_del_init(&rsrc_blk->list);
+			kfree(rsrc_blk);
+		}
+		break;
+	case LPFC_RSC_TYPE_FCOE_VFI:
+		kfree(phba->sli4_hba.vfi_bmask);
+		kfree(phba->sli4_hba.vfi_ids);
+		bf_set(lpfc_vfi_rsrc_rdy, &phba->sli4_hba.sli4_flags, 0);
+		list_for_each_entry_safe(rsrc_blk, rsrc_blk_next,
+				    &phba->sli4_hba.lpfc_vfi_blk_list, list) {
+			list_del_init(&rsrc_blk->list);
+			kfree(rsrc_blk);
+		}
+		break;
+	case LPFC_RSC_TYPE_FCOE_RPI:
+		/* RPI bitmask and physical id array are cleaned up earlier. */
+		list_for_each_entry_safe(rsrc_blk, rsrc_blk_next,
+				    &phba->sli4_hba.lpfc_rpi_blk_list, list) {
+			list_del_init(&rsrc_blk->list);
+			kfree(rsrc_blk);
+		}
+		break;
+	default:
+		break;
+	}
+
+	bf_set(lpfc_idx_rsrc_rdy, &phba->sli4_hba.sli4_flags, 0);
+
+ out_free_mbox:
+	mempool_free(mbox, phba->mbox_mem_pool);
+	return rc;
+}
+
+/**
+ * lpfc_sli4_alloc_resource_identifiers - Allocate all SLI4 resource extents.
+ * @phba: Pointer to HBA context object.
+ *
+ * This function allocates all SLI4 resource identifiers.
+ **/
+int
+lpfc_sli4_alloc_resource_identifiers(struct lpfc_hba *phba)
+{
+	int i, rc, error = 0;
+	uint16_t count, base;
+	unsigned long longs;
+
+	if (phba->sli4_hba.extents_in_use) {
+		/*
+		 * The port supports resource extents. The XRI, VPI, VFI, RPI
+		 * resource extent count must be read and allocated before
+		 * provisioning the resource id arrays.
+		 */
+		if (bf_get(lpfc_idx_rsrc_rdy, &phba->sli4_hba.sli4_flags) ==
+		    LPFC_IDX_RSRC_RDY) {
+			/*
+			 * Extent-based resources are set - the driver could
+			 * be in a port reset. Figure out if any corrective
+			 * actions need to be taken.
+			 */
+			rc = lpfc_sli4_chk_avail_extnt_rsrc(phba,
+						 LPFC_RSC_TYPE_FCOE_VFI);
+			if (rc != 0)
+				error++;
+			rc = lpfc_sli4_chk_avail_extnt_rsrc(phba,
+						 LPFC_RSC_TYPE_FCOE_VPI);
+			if (rc != 0)
+				error++;
+			rc = lpfc_sli4_chk_avail_extnt_rsrc(phba,
+						 LPFC_RSC_TYPE_FCOE_XRI);
+			if (rc != 0)
+				error++;
+			rc = lpfc_sli4_chk_avail_extnt_rsrc(phba,
+						 LPFC_RSC_TYPE_FCOE_RPI);
+			if (rc != 0)
+				error++;
+
+			/*
+			 * It's possible that the number of resources
+			 * provided to this port instance changed between
+			 * resets.  Detect this condition and reallocate
+			 * resources.  Otherwise, there is no action.
+			 */
+			if (error) {
+				lpfc_printf_log(phba, KERN_INFO,
+						LOG_MBOX | LOG_INIT,
+						"2931 Detected extent resource "
+						"change.  Reallocating all "
+						"extents.\n");
+				rc = lpfc_sli4_dealloc_extent(phba,
+						 LPFC_RSC_TYPE_FCOE_VFI);
+				rc = lpfc_sli4_dealloc_extent(phba,
+						 LPFC_RSC_TYPE_FCOE_VPI);
+				rc = lpfc_sli4_dealloc_extent(phba,
+						 LPFC_RSC_TYPE_FCOE_XRI);
+				rc = lpfc_sli4_dealloc_extent(phba,
+						 LPFC_RSC_TYPE_FCOE_RPI);
+			} else
+				return 0;
+		}
+
+		rc = lpfc_sli4_alloc_extent(phba, LPFC_RSC_TYPE_FCOE_VFI);
+		if (unlikely(rc))
+			goto err_exit;
+
+		rc = lpfc_sli4_alloc_extent(phba, LPFC_RSC_TYPE_FCOE_VPI);
+		if (unlikely(rc))
+			goto err_exit;
+
+		rc = lpfc_sli4_alloc_extent(phba, LPFC_RSC_TYPE_FCOE_RPI);
+		if (unlikely(rc))
+			goto err_exit;
+
+		rc = lpfc_sli4_alloc_extent(phba, LPFC_RSC_TYPE_FCOE_XRI);
+		if (unlikely(rc))
+			goto err_exit;
+		bf_set(lpfc_idx_rsrc_rdy, &phba->sli4_hba.sli4_flags,
+		       LPFC_IDX_RSRC_RDY);
+		return rc;
+	} else {
+		/*
+		 * The port does not support resource extents.  The XRI, VPI,
+		 * VFI, RPI resource ids were determined from READ_CONFIG.
+		 * Just allocate the bitmasks and provision the resource id
+		 * arrays.  If a port reset is active, the resources don't
+		 * need any action - just exit.
+		 */
+		if (bf_get(lpfc_idx_rsrc_rdy, &phba->sli4_hba.sli4_flags) ==
+		    LPFC_IDX_RSRC_RDY)
+			return 0;
+
+		/* RPIs. */
+		count = phba->sli4_hba.max_cfg_param.max_rpi;
+		base = phba->sli4_hba.max_cfg_param.rpi_base;
+		longs = (count + BITS_PER_LONG - 1) / BITS_PER_LONG;
+		phba->sli4_hba.rpi_bmask = kzalloc(longs *
+						   sizeof(unsigned long),
+						   GFP_KERNEL);
+		if (unlikely(!phba->sli4_hba.rpi_bmask)) {
+			rc = -ENOMEM;
+			goto err_exit;
+		}
+		phba->sli4_hba.rpi_ids = kzalloc(count *
+						 sizeof(uint16_t),
+						 GFP_KERNEL);
+		if (unlikely(!phba->sli4_hba.rpi_ids)) {
+			rc = -ENOMEM;
+			goto free_rpi_bmask;
+		}
+
+		for (i = 0; i < count; i++)
+			phba->sli4_hba.rpi_ids[i] = base + i;
+
+		/* VPIs. */
+		count = phba->sli4_hba.max_cfg_param.max_vpi;
+		base = phba->sli4_hba.max_cfg_param.vpi_base;
+		longs = (count + BITS_PER_LONG - 1) / BITS_PER_LONG;
+		phba->vpi_bmask = kzalloc(longs *
+					  sizeof(unsigned long),
+					  GFP_KERNEL);
+		if (unlikely(!phba->vpi_bmask)) {
+			rc = -ENOMEM;
+			goto free_rpi_ids;
+		}
+		phba->vpi_ids = kzalloc(count *
+					sizeof(uint16_t),
+					GFP_KERNEL);
+		if (unlikely(!phba->vpi_ids)) {
+			rc = -ENOMEM;
+			goto free_vpi_bmask;
+		}
+
+		for (i = 0; i < count; i++)
+			phba->vpi_ids[i] = base + i;
+
+		/* XRIs. */
+		count = phba->sli4_hba.max_cfg_param.max_xri;
+		base = phba->sli4_hba.max_cfg_param.xri_base;
+		longs = (count + BITS_PER_LONG - 1) / BITS_PER_LONG;
+		phba->sli4_hba.xri_bmask = kzalloc(longs *
+						   sizeof(unsigned long),
+						   GFP_KERNEL);
+		if (unlikely(!phba->sli4_hba.xri_bmask)) {
+			rc = -ENOMEM;
+			goto free_vpi_ids;
+		}
+		phba->sli4_hba.xri_ids = kzalloc(count *
+						 sizeof(uint16_t),
+						 GFP_KERNEL);
+		if (unlikely(!phba->sli4_hba.xri_ids)) {
+			rc = -ENOMEM;
+			goto free_xri_bmask;
+		}
+
+		for (i = 0; i < count; i++)
+			phba->sli4_hba.xri_ids[i] = base + i;
+
+		/* VFIs. */
+		count = phba->sli4_hba.max_cfg_param.max_vfi;
+		base = phba->sli4_hba.max_cfg_param.vfi_base;
+		longs = (count + BITS_PER_LONG - 1) / BITS_PER_LONG;
+		phba->sli4_hba.vfi_bmask = kzalloc(longs *
+						   sizeof(unsigned long),
+						   GFP_KERNEL);
+		if (unlikely(!phba->sli4_hba.vfi_bmask)) {
+			rc = -ENOMEM;
+			goto free_xri_ids;
+		}
+		phba->sli4_hba.vfi_ids = kzalloc(count *
+						 sizeof(uint16_t),
+						 GFP_KERNEL);
+		if (unlikely(!phba->sli4_hba.vfi_ids)) {
+			rc = -ENOMEM;
+			goto free_vfi_bmask;
+		}
+
+		for (i = 0; i < count; i++)
+			phba->sli4_hba.vfi_ids[i] = base + i;
+
+		/*
+		 * Mark all resources ready.  An HBA reset doesn't need
+		 * to reset the initialization.
+		 */
+		bf_set(lpfc_idx_rsrc_rdy, &phba->sli4_hba.sli4_flags,
+		       LPFC_IDX_RSRC_RDY);
+		return 0;
+	}
+
+ free_vfi_bmask:
+	kfree(phba->sli4_hba.vfi_bmask);
+ free_xri_ids:
+	kfree(phba->sli4_hba.xri_ids);
+ free_xri_bmask:
+	kfree(phba->sli4_hba.xri_bmask);
+ free_vpi_ids:
+	kfree(phba->vpi_ids);
+ free_vpi_bmask:
+	kfree(phba->vpi_bmask);
+ free_rpi_ids:
+	kfree(phba->sli4_hba.rpi_ids);
+ free_rpi_bmask:
+	kfree(phba->sli4_hba.rpi_bmask);
+ err_exit:
+	return rc;
+}
+
+/**
+ * lpfc_sli4_dealloc_resource_identifiers - Deallocate all SLI4 resource extents.
+ * @phba: Pointer to HBA context object.
+ *
+ * This function allocates the number of elements for the specified
+ * resource type.
+ **/
+int
+lpfc_sli4_dealloc_resource_identifiers(struct lpfc_hba *phba)
+{
+	if (phba->sli4_hba.extents_in_use) {
+		lpfc_sli4_dealloc_extent(phba, LPFC_RSC_TYPE_FCOE_VPI);
+		lpfc_sli4_dealloc_extent(phba, LPFC_RSC_TYPE_FCOE_RPI);
+		lpfc_sli4_dealloc_extent(phba, LPFC_RSC_TYPE_FCOE_XRI);
+		lpfc_sli4_dealloc_extent(phba, LPFC_RSC_TYPE_FCOE_VFI);
+	} else {
+		kfree(phba->vpi_bmask);
+		kfree(phba->vpi_ids);
+		bf_set(lpfc_vpi_rsrc_rdy, &phba->sli4_hba.sli4_flags, 0);
+		kfree(phba->sli4_hba.xri_bmask);
+		kfree(phba->sli4_hba.xri_ids);
+		bf_set(lpfc_xri_rsrc_rdy, &phba->sli4_hba.sli4_flags, 0);
+		kfree(phba->sli4_hba.vfi_bmask);
+		kfree(phba->sli4_hba.vfi_ids);
+		bf_set(lpfc_vfi_rsrc_rdy, &phba->sli4_hba.sli4_flags, 0);
+		bf_set(lpfc_idx_rsrc_rdy, &phba->sli4_hba.sli4_flags, 0);
+	}
+
+	return 0;
+}
+
+/**
  * lpfc_sli4_hba_setup - SLI4 device intialization PCI function
  * @phba: Pointer to HBA context object.
  *
@@ -4708,10 +5527,6 @@
 	struct lpfc_vport *vport = phba->pport;
 	struct lpfc_dmabuf *mp;
 
-	/*
-	 * TODO:  Why does this routine execute these task in a different
-	 * order from probe?
-	 */
 	/* Perform a PCI function reset to start from clean */
 	rc = lpfc_pci_function_reset(phba);
 	if (unlikely(rc))
@@ -4740,7 +5555,7 @@
 	 * to read FCoE param config regions
 	 */
 	if (lpfc_sli4_read_fcoe_params(phba, mboxq))
-		lpfc_printf_log(phba, KERN_ERR, LOG_MBOX | LOG_INIT,
+		lpfc_printf_log(phba, KERN_WARNING, LOG_MBOX | LOG_INIT,
 			"2570 Failed to read FCoE parameters\n");
 
 	/* Issue READ_REV to collect vpd and FW information. */
@@ -4769,8 +5584,7 @@
 	else
 		phba->hba_flag &= ~HBA_FIP_SUPPORT;
 
-	if (phba->sli_rev != LPFC_SLI_REV4 ||
-	    !(phba->hba_flag & HBA_FCOE_MODE)) {
+	if (phba->sli_rev != LPFC_SLI_REV4) {
 		lpfc_printf_log(phba, KERN_ERR, LOG_MBOX | LOG_SLI,
 			"0376 READ_REV Error. SLI Level %d "
 			"FCoE enabled %d\n",
@@ -4874,6 +5688,18 @@
 	phba->sli3_options |= (LPFC_SLI3_NPIV_ENABLED | LPFC_SLI3_HBQ_ENABLED);
 	spin_unlock_irq(&phba->hbalock);
 
+	/*
+	 * Allocate all resources (xri,rpi,vpi,vfi) now.  Subsequent
+	 * calls depends on these resources to complete port setup.
+	 */
+	rc = lpfc_sli4_alloc_resource_identifiers(phba);
+	if (rc) {
+		lpfc_printf_log(phba, KERN_ERR, LOG_MBOX | LOG_SLI,
+				"2920 Failed to alloc Resource IDs "
+				"rc = x%x\n", rc);
+		goto out_free_mbox;
+	}
+
 	/* Read the port's service parameters. */
 	rc = lpfc_read_sparam(phba, mboxq, vport->vpi);
 	if (rc) {
@@ -4907,35 +5733,37 @@
 		goto out_free_mbox;
 	}
 
-	if (phba->cfg_soft_wwnn)
-		u64_to_wwn(phba->cfg_soft_wwnn,
-			   vport->fc_sparam.nodeName.u.wwn);
-	if (phba->cfg_soft_wwpn)
-		u64_to_wwn(phba->cfg_soft_wwpn,
-			   vport->fc_sparam.portName.u.wwn);
-	memcpy(&vport->fc_nodename, &vport->fc_sparam.nodeName,
-	       sizeof(struct lpfc_name));
-	memcpy(&vport->fc_portname, &vport->fc_sparam.portName,
-	       sizeof(struct lpfc_name));
+	lpfc_update_vport_wwn(vport);
 
 	/* Update the fc_host data structures with new wwn. */
 	fc_host_node_name(shost) = wwn_to_u64(vport->fc_nodename.u.wwn);
 	fc_host_port_name(shost) = wwn_to_u64(vport->fc_portname.u.wwn);
 
 	/* Register SGL pool to the device using non-embedded mailbox command */
-	rc = lpfc_sli4_post_sgl_list(phba);
-	if (unlikely(rc)) {
-		lpfc_printf_log(phba, KERN_ERR, LOG_MBOX | LOG_SLI,
-				"0582 Error %d during sgl post operation\n",
-					rc);
-		rc = -ENODEV;
-		goto out_free_mbox;
+	if (!phba->sli4_hba.extents_in_use) {
+		rc = lpfc_sli4_post_els_sgl_list(phba);
+		if (unlikely(rc)) {
+			lpfc_printf_log(phba, KERN_ERR, LOG_MBOX | LOG_SLI,
+					"0582 Error %d during els sgl post "
+					"operation\n", rc);
+			rc = -ENODEV;
+			goto out_free_mbox;
+		}
+	} else {
+		rc = lpfc_sli4_post_els_sgl_list_ext(phba);
+		if (unlikely(rc)) {
+			lpfc_printf_log(phba, KERN_ERR, LOG_MBOX | LOG_SLI,
+					"2560 Error %d during els sgl post "
+					"operation\n", rc);
+			rc = -ENODEV;
+			goto out_free_mbox;
+		}
 	}
 
 	/* Register SCSI SGL pool to the device */
 	rc = lpfc_sli4_repost_scsi_sgl_list(phba);
 	if (unlikely(rc)) {
-		lpfc_printf_log(phba, KERN_WARNING, LOG_MBOX | LOG_SLI,
+		lpfc_printf_log(phba, KERN_ERR, LOG_MBOX | LOG_SLI,
 				"0383 Error %d during scsi sgl post "
 				"operation\n", rc);
 		/* Some Scsi buffers were moved to the abort scsi list */
@@ -5018,10 +5846,11 @@
 		lpfc_reg_fcfi(phba, mboxq);
 		mboxq->vport = phba->pport;
 		rc = lpfc_sli_issue_mbox(phba, mboxq, MBX_POLL);
-		if (rc == MBX_SUCCESS)
-			rc = 0;
-		else
+		if (rc != MBX_SUCCESS)
 			goto out_unset_queue;
+		rc = 0;
+		phba->fcf.fcfi = bf_get(lpfc_reg_fcfi_fcfi,
+					&mboxq->u.mqe.un.reg_fcfi);
 	}
 	/*
 	 * The port is ready, set the host's link state to LINK_DOWN
@@ -5747,10 +6576,15 @@
 	lpfc_sli_pcimem_bcopy(&mbox_rgn->mcqe, &mboxq->mcqe,
 			      sizeof(struct lpfc_mcqe));
 	mcqe_status = bf_get(lpfc_mcqe_status, &mbox_rgn->mcqe);
-
-	/* Prefix the mailbox status with range x4000 to note SLI4 status. */
+	/*
+	 * When the CQE status indicates a failure and the mailbox status
+	 * indicates success then copy the CQE status into the mailbox status
+	 * (and prefix it with x4000).
+	 */
 	if (mcqe_status != MB_CQE_STATUS_SUCCESS) {
-		bf_set(lpfc_mqe_status, mb, LPFC_MBX_ERROR_RANGE | mcqe_status);
+		if (bf_get(lpfc_mqe_status, mb) == MBX_SUCCESS)
+			bf_set(lpfc_mqe_status, mb,
+			       (LPFC_MBX_ERROR_RANGE | mcqe_status));
 		rc = MBXERR_ERROR;
 	} else
 		lpfc_sli4_swap_str(phba, mboxq);
@@ -5819,7 +6653,7 @@
 		else
 			rc = -EIO;
 		if (rc != MBX_SUCCESS)
-			lpfc_printf_log(phba, KERN_ERR, LOG_MBOX | LOG_SLI,
+			lpfc_printf_log(phba, KERN_WARNING, LOG_MBOX | LOG_SLI,
 					"(%d):2541 Mailbox command x%x "
 					"(x%x) cannot issue Data: x%x x%x\n",
 					mboxq->vport ? mboxq->vport->vpi : 0,
@@ -6307,6 +7141,7 @@
 			sgl->addr_hi = bpl->addrHigh;
 			sgl->addr_lo = bpl->addrLow;
 
+			sgl->word2 = le32_to_cpu(sgl->word2);
 			if ((i+1) == numBdes)
 				bf_set(lpfc_sli4_sge_last, sgl, 1);
 			else
@@ -6343,6 +7178,7 @@
 				cpu_to_le32(icmd->un.genreq64.bdl.addrHigh);
 			sgl->addr_lo =
 				cpu_to_le32(icmd->un.genreq64.bdl.addrLow);
+			sgl->word2 = le32_to_cpu(sgl->word2);
 			bf_set(lpfc_sli4_sge_last, sgl, 1);
 			sgl->word2 = cpu_to_le32(sgl->word2);
 			sgl->sge_len =
@@ -6402,6 +7238,7 @@
 	uint32_t els_id = LPFC_ELS_ID_DEFAULT;
 	int numBdes, i;
 	struct ulp_bde64 bde;
+	struct lpfc_nodelist *ndlp;
 
 	fip = phba->hba_flag & HBA_FIP_SUPPORT;
 	/* The fcp commands will set command type */
@@ -6447,6 +7284,7 @@
 
 	switch (iocbq->iocb.ulpCommand) {
 	case CMD_ELS_REQUEST64_CR:
+		ndlp = (struct lpfc_nodelist *)iocbq->context1;
 		if (!iocbq->iocb.ulpLe) {
 			lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
 				"2007 Only Limited Edition cmd Format"
@@ -6472,6 +7310,8 @@
 			els_id = ((iocbq->iocb_flag & LPFC_FIP_ELS_ID_MASK)
 					>> LPFC_FIP_ELS_ID_SHIFT);
 		}
+		bf_set(wqe_temp_rpi, &wqe->els_req.wqe_com,
+		       phba->sli4_hba.rpi_ids[ndlp->nlp_rpi]);
 		bf_set(wqe_els_id, &wqe->els_req.wqe_com, els_id);
 		bf_set(wqe_dbde, &wqe->els_req.wqe_com, 1);
 		bf_set(wqe_iod, &wqe->els_req.wqe_com, LPFC_WQE_IOD_READ);
@@ -6604,6 +7444,7 @@
 		command_type = OTHER_COMMAND;
 	break;
 	case CMD_XMIT_ELS_RSP64_CX:
+		ndlp = (struct lpfc_nodelist *)iocbq->context1;
 		/* words0-2 BDE memcpy */
 		/* word3 iocb=iotag32 wqe=response_payload_len */
 		wqe->xmit_els_rsp.response_payload_len = xmit_len;
@@ -6619,13 +7460,15 @@
 		       iocbq->iocb.ulpContext);
 		if (!iocbq->iocb.ulpCt_h && iocbq->iocb.ulpCt_l)
 			bf_set(wqe_ctxt_tag, &wqe->xmit_els_rsp.wqe_com,
-			       iocbq->vport->vpi + phba->vpi_base);
+			       phba->vpi_ids[iocbq->vport->vpi]);
 		bf_set(wqe_dbde, &wqe->xmit_els_rsp.wqe_com, 1);
 		bf_set(wqe_iod, &wqe->xmit_els_rsp.wqe_com, LPFC_WQE_IOD_WRITE);
 		bf_set(wqe_qosd, &wqe->xmit_els_rsp.wqe_com, 1);
 		bf_set(wqe_lenloc, &wqe->xmit_els_rsp.wqe_com,
 		       LPFC_WQE_LENLOC_WORD3);
 		bf_set(wqe_ebde_cnt, &wqe->xmit_els_rsp.wqe_com, 0);
+		bf_set(wqe_rsp_temp_rpi, &wqe->xmit_els_rsp,
+		       phba->sli4_hba.rpi_ids[ndlp->nlp_rpi]);
 		command_type = OTHER_COMMAND;
 	break;
 	case CMD_CLOSE_XRI_CN:
@@ -6724,6 +7567,7 @@
 		return IOCB_ERROR;
 	break;
 	}
+
 	bf_set(wqe_xri_tag, &wqe->generic.wqe_com, xritag);
 	bf_set(wqe_reqtag, &wqe->generic.wqe_com, iocbq->iotag);
 	wqe->generic.wqe_com.abort_tag = abort_tag;
@@ -6771,7 +7615,7 @@
 					return IOCB_BUSY;
 				}
 			} else {
-			sglq = __lpfc_sli_get_sglq(phba, piocb);
+				sglq = __lpfc_sli_get_sglq(phba, piocb);
 				if (!sglq) {
 					if (!(flag & SLI_IOCB_RET_IOCB)) {
 						__lpfc_sli_ringtx_put(phba,
@@ -6784,11 +7628,11 @@
 			}
 		}
 	} else if (piocb->iocb_flag &  LPFC_IO_FCP) {
-		sglq = NULL; /* These IO's already have an XRI and
-			      * a mapped sgl.
-			      */
+		/* These IO's already have an XRI and a mapped sgl. */
+		sglq = NULL;
 	} else {
-		/* This is a continuation of a commandi,(CX) so this
+		/*
+		 * This is a continuation of a commandi,(CX) so this
 		 * sglq is on the active list
 		 */
 		sglq = __lpfc_get_active_sglq(phba, piocb->sli4_xritag);
@@ -6797,8 +7641,8 @@
 	}
 
 	if (sglq) {
+		piocb->sli4_lxritag = sglq->sli4_lxritag;
 		piocb->sli4_xritag = sglq->sli4_xritag;
-
 		if (NO_XRI == lpfc_sli4_bpl2sgl(phba, piocb, sglq))
 			return IOCB_ERROR;
 	}
@@ -9794,7 +10638,12 @@
 		break;
 	case LPFC_WCQ:
 		while ((cqe = lpfc_sli4_cq_get(cq))) {
-			workposted |= lpfc_sli4_sp_handle_cqe(phba, cq, cqe);
+			if (cq->subtype == LPFC_FCP)
+				workposted |= lpfc_sli4_fp_handle_wcqe(phba, cq,
+								       cqe);
+			else
+				workposted |= lpfc_sli4_sp_handle_cqe(phba, cq,
+								      cqe);
 			if (!(++ecount % LPFC_GET_QE_REL_INT))
 				lpfc_sli4_cq_release(cq, LPFC_QUEUE_NOARM);
 		}
@@ -10522,8 +11371,8 @@
 	bf_set(lpfc_mbox_hdr_version, &shdr->request,
 	       phba->sli4_hba.pc_sli4_params.cqv);
 	if (phba->sli4_hba.pc_sli4_params.cqv == LPFC_Q_CREATE_VERSION_2) {
-		bf_set(lpfc_mbx_cq_create_page_size, &cq_create->u.request,
-		       (PAGE_SIZE/SLI4_PAGE_SIZE));
+		/* FW only supports 1. Should be PAGE_SIZE/SLI4_PAGE_SIZE */
+		bf_set(lpfc_mbx_cq_create_page_size, &cq_create->u.request, 1);
 		bf_set(lpfc_cq_eq_id_2, &cq_create->u.request.context,
 		       eq->queue_id);
 	} else {
@@ -10967,6 +11816,12 @@
 		       &rq_create->u.request.context,
 		       hrq->entry_count);
 		rq_create->u.request.context.buffer_size = LPFC_HDR_BUF_SIZE;
+		bf_set(lpfc_rq_context_rqe_size,
+		       &rq_create->u.request.context,
+		       LPFC_RQE_SIZE_8);
+		bf_set(lpfc_rq_context_page_size,
+		       &rq_create->u.request.context,
+		       (PAGE_SIZE/SLI4_PAGE_SIZE));
 	} else {
 		switch (hrq->entry_count) {
 		default:
@@ -11042,9 +11897,12 @@
 	       phba->sli4_hba.pc_sli4_params.rqv);
 	if (phba->sli4_hba.pc_sli4_params.rqv == LPFC_Q_CREATE_VERSION_1) {
 		bf_set(lpfc_rq_context_rqe_count_1,
-		       &rq_create->u.request.context,
-		       hrq->entry_count);
+		       &rq_create->u.request.context, hrq->entry_count);
 		rq_create->u.request.context.buffer_size = LPFC_DATA_BUF_SIZE;
+		bf_set(lpfc_rq_context_rqe_size, &rq_create->u.request.context,
+		       LPFC_RQE_SIZE_8);
+		bf_set(lpfc_rq_context_page_size, &rq_create->u.request.context,
+		       (PAGE_SIZE/SLI4_PAGE_SIZE));
 	} else {
 		switch (drq->entry_count) {
 		default:
@@ -11432,6 +12290,7 @@
 	LPFC_MBOXQ_t *mbox;
 	int rc;
 	uint32_t shdr_status, shdr_add_status;
+	uint32_t mbox_tmo;
 	union lpfc_sli4_cfg_shdr *shdr;
 
 	if (xritag == NO_XRI) {
@@ -11465,8 +12324,10 @@
 				cpu_to_le32(putPaddrHigh(pdma_phys_addr1));
 	if (!phba->sli4_hba.intr_enable)
 		rc = lpfc_sli_issue_mbox(phba, mbox, MBX_POLL);
-	else
-		rc = lpfc_sli_issue_mbox_wait(phba, mbox, LPFC_MBOX_TMO);
+	else {
+		mbox_tmo = lpfc_mbox_tmo_val(phba, MBX_SLI4_CONFIG);
+		rc = lpfc_sli_issue_mbox_wait(phba, mbox, mbox_tmo);
+	}
 	/* The IOCTL status is embedded in the mailbox subheader. */
 	shdr = (union lpfc_sli4_cfg_shdr *) &post_sgl_pages->header.cfg_shdr;
 	shdr_status = bf_get(lpfc_mbox_hdr_status, &shdr->response);
@@ -11484,6 +12345,76 @@
 }
 
 /**
+ * lpfc_sli4_init_rpi_hdrs - Post the rpi header memory region to the port
+ * @phba: pointer to lpfc hba data structure.
+ *
+ * This routine is invoked to post rpi header templates to the
+ * port for those SLI4 ports that do not support extents.  This routine
+ * posts a PAGE_SIZE memory region to the port to hold up to
+ * PAGE_SIZE modulo 64 rpi context headers.  This is an initialization routine
+ * and should be called only when interrupts are disabled.
+ *
+ * Return codes
+ *	0 - successful
+ *	-ERROR - otherwise.
+ */
+uint16_t
+lpfc_sli4_alloc_xri(struct lpfc_hba *phba)
+{
+	unsigned long xri;
+
+	/*
+	 * Fetch the next logical xri.  Because this index is logical,
+	 * the driver starts at 0 each time.
+	 */
+	spin_lock_irq(&phba->hbalock);
+	xri = find_next_zero_bit(phba->sli4_hba.xri_bmask,
+				 phba->sli4_hba.max_cfg_param.max_xri, 0);
+	if (xri >= phba->sli4_hba.max_cfg_param.max_xri) {
+		spin_unlock_irq(&phba->hbalock);
+		return NO_XRI;
+	} else {
+		set_bit(xri, phba->sli4_hba.xri_bmask);
+		phba->sli4_hba.max_cfg_param.xri_used++;
+		phba->sli4_hba.xri_count++;
+	}
+
+	spin_unlock_irq(&phba->hbalock);
+	return xri;
+}
+
+/**
+ * lpfc_sli4_free_xri - Release an xri for reuse.
+ * @phba: pointer to lpfc hba data structure.
+ *
+ * This routine is invoked to release an xri to the pool of
+ * available rpis maintained by the driver.
+ **/
+void
+__lpfc_sli4_free_xri(struct lpfc_hba *phba, int xri)
+{
+	if (test_and_clear_bit(xri, phba->sli4_hba.xri_bmask)) {
+		phba->sli4_hba.xri_count--;
+		phba->sli4_hba.max_cfg_param.xri_used--;
+	}
+}
+
+/**
+ * lpfc_sli4_free_xri - Release an xri for reuse.
+ * @phba: pointer to lpfc hba data structure.
+ *
+ * This routine is invoked to release an xri to the pool of
+ * available rpis maintained by the driver.
+ **/
+void
+lpfc_sli4_free_xri(struct lpfc_hba *phba, int xri)
+{
+	spin_lock_irq(&phba->hbalock);
+	__lpfc_sli4_free_xri(phba, xri);
+	spin_unlock_irq(&phba->hbalock);
+}
+
+/**
  * lpfc_sli4_next_xritag - Get an xritag for the io
  * @phba: Pointer to HBA context object.
  *
@@ -11496,30 +12427,23 @@
 uint16_t
 lpfc_sli4_next_xritag(struct lpfc_hba *phba)
 {
-	uint16_t xritag;
+	uint16_t xri_index;
 
-	spin_lock_irq(&phba->hbalock);
-	xritag = phba->sli4_hba.next_xri;
-	if ((xritag != (uint16_t) -1) && xritag <
-		(phba->sli4_hba.max_cfg_param.max_xri
-			+ phba->sli4_hba.max_cfg_param.xri_base)) {
-		phba->sli4_hba.next_xri++;
-		phba->sli4_hba.max_cfg_param.xri_used++;
-		spin_unlock_irq(&phba->hbalock);
-		return xritag;
-	}
-	spin_unlock_irq(&phba->hbalock);
-	lpfc_printf_log(phba, KERN_WARNING, LOG_SLI,
+	xri_index = lpfc_sli4_alloc_xri(phba);
+	if (xri_index != NO_XRI)
+		return xri_index;
+
+	lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
 			"2004 Failed to allocate XRI.last XRITAG is %d"
 			" Max XRI is %d, Used XRI is %d\n",
-			phba->sli4_hba.next_xri,
+			xri_index,
 			phba->sli4_hba.max_cfg_param.max_xri,
 			phba->sli4_hba.max_cfg_param.xri_used);
-	return -1;
+	return NO_XRI;
 }
 
 /**
- * lpfc_sli4_post_sgl_list - post a block of sgl list to the firmware.
+ * lpfc_sli4_post_els_sgl_list - post a block of ELS sgls to the port.
  * @phba: pointer to lpfc hba data structure.
  *
  * This routine is invoked to post a block of driver's sgl pages to the
@@ -11528,7 +12452,7 @@
  * stopped.
  **/
 int
-lpfc_sli4_post_sgl_list(struct lpfc_hba *phba)
+lpfc_sli4_post_els_sgl_list(struct lpfc_hba *phba)
 {
 	struct lpfc_sglq *sglq_entry;
 	struct lpfc_mbx_post_uembed_sgl_page1 *sgl;
@@ -11537,7 +12461,7 @@
 	LPFC_MBOXQ_t *mbox;
 	uint32_t reqlen, alloclen, pg_pairs;
 	uint32_t mbox_tmo;
-	uint16_t xritag_start = 0;
+	uint16_t xritag_start = 0, lxri = 0;
 	int els_xri_cnt, rc = 0;
 	uint32_t shdr_status, shdr_add_status;
 	union lpfc_sli4_cfg_shdr *shdr;
@@ -11554,11 +12478,8 @@
 		return -ENOMEM;
 	}
 	mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
-	if (!mbox) {
-		lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
-				"2560 Failed to allocate mbox cmd memory\n");
+	if (!mbox)
 		return -ENOMEM;
-	}
 
 	/* Allocate DMA memory and set up the non-embedded mailbox command */
 	alloclen = lpfc_sli4_config(phba, mbox, LPFC_MBOX_SUBSYSTEM_FCOE,
@@ -11573,15 +12494,30 @@
 		lpfc_sli4_mbox_cmd_free(phba, mbox);
 		return -ENOMEM;
 	}
-	/* Get the first SGE entry from the non-embedded DMA memory */
-	viraddr = mbox->sge_array->addr[0];
-
 	/* Set up the SGL pages in the non-embedded DMA pages */
+	viraddr = mbox->sge_array->addr[0];
 	sgl = (struct lpfc_mbx_post_uembed_sgl_page1 *)viraddr;
 	sgl_pg_pairs = &sgl->sgl_pg_pairs;
 
 	for (pg_pairs = 0; pg_pairs < els_xri_cnt; pg_pairs++) {
 		sglq_entry = phba->sli4_hba.lpfc_els_sgl_array[pg_pairs];
+
+		/*
+		 * Assign the sglq a physical xri only if the driver has not
+		 * initialized those resources.  A port reset only needs
+		 * the sglq's posted.
+		 */
+		if (bf_get(lpfc_xri_rsrc_rdy, &phba->sli4_hba.sli4_flags) !=
+		    LPFC_XRI_RSRC_RDY) {
+			lxri = lpfc_sli4_next_xritag(phba);
+			if (lxri == NO_XRI) {
+				lpfc_sli4_mbox_cmd_free(phba, mbox);
+				return -ENOMEM;
+			}
+			sglq_entry->sli4_lxritag = lxri;
+			sglq_entry->sli4_xritag = phba->sli4_hba.xri_ids[lxri];
+		}
+
 		/* Set up the sge entry */
 		sgl_pg_pairs->sgl_pg0_addr_lo =
 				cpu_to_le32(putPaddrLow(sglq_entry->phys));
@@ -11591,16 +12527,17 @@
 				cpu_to_le32(putPaddrLow(0));
 		sgl_pg_pairs->sgl_pg1_addr_hi =
 				cpu_to_le32(putPaddrHigh(0));
+
 		/* Keep the first xritag on the list */
 		if (pg_pairs == 0)
 			xritag_start = sglq_entry->sli4_xritag;
 		sgl_pg_pairs++;
 	}
+
+	/* Complete initialization and perform endian conversion. */
 	bf_set(lpfc_post_sgl_pages_xri, sgl, xritag_start);
 	bf_set(lpfc_post_sgl_pages_xricnt, sgl, els_xri_cnt);
-	/* Perform endian conversion if necessary */
 	sgl->word0 = cpu_to_le32(sgl->word0);
-
 	if (!phba->sli4_hba.intr_enable)
 		rc = lpfc_sli_issue_mbox(phba, mbox, MBX_POLL);
 	else {
@@ -11619,6 +12556,181 @@
 				shdr_status, shdr_add_status, rc);
 		rc = -ENXIO;
 	}
+
+	if (rc == 0)
+		bf_set(lpfc_xri_rsrc_rdy, &phba->sli4_hba.sli4_flags,
+		       LPFC_XRI_RSRC_RDY);
+	return rc;
+}
+
+/**
+ * lpfc_sli4_post_els_sgl_list_ext - post a block of ELS sgls to the port.
+ * @phba: pointer to lpfc hba data structure.
+ *
+ * This routine is invoked to post a block of driver's sgl pages to the
+ * HBA using non-embedded mailbox command. No Lock is held. This routine
+ * is only called when the driver is loading and after all IO has been
+ * stopped.
+ **/
+int
+lpfc_sli4_post_els_sgl_list_ext(struct lpfc_hba *phba)
+{
+	struct lpfc_sglq *sglq_entry;
+	struct lpfc_mbx_post_uembed_sgl_page1 *sgl;
+	struct sgl_page_pairs *sgl_pg_pairs;
+	void *viraddr;
+	LPFC_MBOXQ_t *mbox;
+	uint32_t reqlen, alloclen, index;
+	uint32_t mbox_tmo;
+	uint16_t rsrc_start, rsrc_size, els_xri_cnt;
+	uint16_t xritag_start = 0, lxri = 0;
+	struct lpfc_rsrc_blks *rsrc_blk;
+	int cnt, ttl_cnt, rc = 0;
+	int loop_cnt;
+	uint32_t shdr_status, shdr_add_status;
+	union lpfc_sli4_cfg_shdr *shdr;
+
+	/* The number of sgls to be posted */
+	els_xri_cnt = lpfc_sli4_get_els_iocb_cnt(phba);
+
+	reqlen = els_xri_cnt * sizeof(struct sgl_page_pairs) +
+		 sizeof(union lpfc_sli4_cfg_shdr) + sizeof(uint32_t);
+	if (reqlen > SLI4_PAGE_SIZE) {
+		lpfc_printf_log(phba, KERN_WARNING, LOG_INIT,
+				"2989 Block sgl registration required DMA "
+				"size (%d) great than a page\n", reqlen);
+		return -ENOMEM;
+	}
+
+	cnt = 0;
+	ttl_cnt = 0;
+	list_for_each_entry(rsrc_blk, &phba->sli4_hba.lpfc_xri_blk_list,
+			    list) {
+		rsrc_start = rsrc_blk->rsrc_start;
+		rsrc_size = rsrc_blk->rsrc_size;
+
+		lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
+				"3014 Working ELS Extent start %d, cnt %d\n",
+				rsrc_start, rsrc_size);
+
+		loop_cnt = min(els_xri_cnt, rsrc_size);
+		if (ttl_cnt + loop_cnt >= els_xri_cnt) {
+			loop_cnt = els_xri_cnt - ttl_cnt;
+			ttl_cnt = els_xri_cnt;
+		}
+
+		mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
+		if (!mbox)
+			return -ENOMEM;
+		/*
+		 * Allocate DMA memory and set up the non-embedded mailbox
+		 * command.
+		 */
+		alloclen = lpfc_sli4_config(phba, mbox,
+					LPFC_MBOX_SUBSYSTEM_FCOE,
+					LPFC_MBOX_OPCODE_FCOE_POST_SGL_PAGES,
+					reqlen, LPFC_SLI4_MBX_NEMBED);
+		if (alloclen < reqlen) {
+			lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
+					"2987 Allocated DMA memory size (%d) "
+					"is less than the requested DMA memory "
+					"size (%d)\n", alloclen, reqlen);
+			lpfc_sli4_mbox_cmd_free(phba, mbox);
+			return -ENOMEM;
+		}
+
+		/* Set up the SGL pages in the non-embedded DMA pages */
+		viraddr = mbox->sge_array->addr[0];
+		sgl = (struct lpfc_mbx_post_uembed_sgl_page1 *)viraddr;
+		sgl_pg_pairs = &sgl->sgl_pg_pairs;
+
+		/*
+		 * The starting resource may not begin at zero. Control
+		 * the loop variants via the block resource parameters,
+		 * but handle the sge pointers with a zero-based index
+		 * that doesn't get reset per loop pass.
+		 */
+		for (index = rsrc_start;
+		     index < rsrc_start + loop_cnt;
+		     index++) {
+			sglq_entry = phba->sli4_hba.lpfc_els_sgl_array[cnt];
+
+			/*
+			 * Assign the sglq a physical xri only if the driver
+			 * has not initialized those resources.  A port reset
+			 * only needs the sglq's posted.
+			 */
+			if (bf_get(lpfc_xri_rsrc_rdy,
+				   &phba->sli4_hba.sli4_flags) !=
+				   LPFC_XRI_RSRC_RDY) {
+				lxri = lpfc_sli4_next_xritag(phba);
+				if (lxri == NO_XRI) {
+					lpfc_sli4_mbox_cmd_free(phba, mbox);
+					rc = -ENOMEM;
+					goto err_exit;
+				}
+				sglq_entry->sli4_lxritag = lxri;
+				sglq_entry->sli4_xritag =
+						phba->sli4_hba.xri_ids[lxri];
+			}
+
+			/* Set up the sge entry */
+			sgl_pg_pairs->sgl_pg0_addr_lo =
+				cpu_to_le32(putPaddrLow(sglq_entry->phys));
+			sgl_pg_pairs->sgl_pg0_addr_hi =
+				cpu_to_le32(putPaddrHigh(sglq_entry->phys));
+			sgl_pg_pairs->sgl_pg1_addr_lo =
+				cpu_to_le32(putPaddrLow(0));
+			sgl_pg_pairs->sgl_pg1_addr_hi =
+				cpu_to_le32(putPaddrHigh(0));
+
+			/* Track the starting physical XRI for the mailbox. */
+			if (index == rsrc_start)
+				xritag_start = sglq_entry->sli4_xritag;
+			sgl_pg_pairs++;
+			cnt++;
+		}
+
+		/* Complete initialization and perform endian conversion. */
+		rsrc_blk->rsrc_used += loop_cnt;
+		bf_set(lpfc_post_sgl_pages_xri, sgl, xritag_start);
+		bf_set(lpfc_post_sgl_pages_xricnt, sgl, loop_cnt);
+		sgl->word0 = cpu_to_le32(sgl->word0);
+
+		lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
+				"3015 Post ELS Extent SGL, start %d, "
+				"cnt %d, used %d\n",
+				xritag_start, loop_cnt, rsrc_blk->rsrc_used);
+		if (!phba->sli4_hba.intr_enable)
+			rc = lpfc_sli_issue_mbox(phba, mbox, MBX_POLL);
+		else {
+			mbox_tmo = lpfc_mbox_tmo_val(phba, MBX_SLI4_CONFIG);
+			rc = lpfc_sli_issue_mbox_wait(phba, mbox, mbox_tmo);
+		}
+		shdr = (union lpfc_sli4_cfg_shdr *) &sgl->cfg_shdr;
+		shdr_status = bf_get(lpfc_mbox_hdr_status,
+				     &shdr->response);
+		shdr_add_status = bf_get(lpfc_mbox_hdr_add_status,
+					 &shdr->response);
+		if (rc != MBX_TIMEOUT)
+			lpfc_sli4_mbox_cmd_free(phba, mbox);
+		if (shdr_status || shdr_add_status || rc) {
+			lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
+					"2988 POST_SGL_BLOCK mailbox "
+					"command failed status x%x "
+					"add_status x%x mbx status x%x\n",
+					shdr_status, shdr_add_status, rc);
+			rc = -ENXIO;
+			goto err_exit;
+		}
+		if (ttl_cnt >= els_xri_cnt)
+			break;
+	}
+
+ err_exit:
+	if (rc == 0)
+		bf_set(lpfc_xri_rsrc_rdy, &phba->sli4_hba.sli4_flags,
+		       LPFC_XRI_RSRC_RDY);
 	return rc;
 }
 
@@ -11679,6 +12791,7 @@
 		lpfc_sli4_mbox_cmd_free(phba, mbox);
 		return -ENOMEM;
 	}
+
 	/* Get the first SGE entry from the non-embedded DMA memory */
 	viraddr = mbox->sge_array->addr[0];
 
@@ -11734,6 +12847,169 @@
 }
 
 /**
+ * lpfc_sli4_post_scsi_sgl_blk_ext - post a block of scsi sgls to the port.
+ * @phba: pointer to lpfc hba data structure.
+ * @sblist: pointer to scsi buffer list.
+ * @count: number of scsi buffers on the list.
+ *
+ * This routine is invoked to post a block of @count scsi sgl pages from a
+ * SCSI buffer list @sblist to the HBA using non-embedded mailbox command.
+ * No Lock is held.
+ *
+ **/
+int
+lpfc_sli4_post_scsi_sgl_blk_ext(struct lpfc_hba *phba, struct list_head *sblist,
+				int cnt)
+{
+	struct lpfc_scsi_buf *psb = NULL;
+	struct lpfc_mbx_post_uembed_sgl_page1 *sgl;
+	struct sgl_page_pairs *sgl_pg_pairs;
+	void *viraddr;
+	LPFC_MBOXQ_t *mbox;
+	uint32_t reqlen, alloclen, pg_pairs;
+	uint32_t mbox_tmo;
+	uint16_t xri_start = 0, scsi_xri_start;
+	uint16_t rsrc_range;
+	int rc = 0, avail_cnt;
+	uint32_t shdr_status, shdr_add_status;
+	dma_addr_t pdma_phys_bpl1;
+	union lpfc_sli4_cfg_shdr *shdr;
+	struct lpfc_rsrc_blks *rsrc_blk;
+	uint32_t xri_cnt = 0;
+
+	/* Calculate the total requested length of the dma memory */
+	reqlen = cnt * sizeof(struct sgl_page_pairs) +
+		 sizeof(union lpfc_sli4_cfg_shdr) + sizeof(uint32_t);
+	if (reqlen > SLI4_PAGE_SIZE) {
+		lpfc_printf_log(phba, KERN_WARNING, LOG_INIT,
+				"2932 Block sgl registration required DMA "
+				"size (%d) great than a page\n", reqlen);
+		return -ENOMEM;
+	}
+
+	/*
+	 * The use of extents requires the driver to post the sgl headers
+	 * in multiple postings to meet the contiguous resource assignment.
+	 */
+	psb = list_prepare_entry(psb, sblist, list);
+	scsi_xri_start = phba->sli4_hba.scsi_xri_start;
+	list_for_each_entry(rsrc_blk, &phba->sli4_hba.lpfc_xri_blk_list,
+			    list) {
+		rsrc_range = rsrc_blk->rsrc_start + rsrc_blk->rsrc_size;
+		if (rsrc_range < scsi_xri_start)
+			continue;
+		else if (rsrc_blk->rsrc_used >= rsrc_blk->rsrc_size)
+			continue;
+		else
+			avail_cnt = rsrc_blk->rsrc_size - rsrc_blk->rsrc_used;
+
+		reqlen = (avail_cnt * sizeof(struct sgl_page_pairs)) +
+			sizeof(union lpfc_sli4_cfg_shdr) + sizeof(uint32_t);
+		/*
+		 * Allocate DMA memory and set up the non-embedded mailbox
+		 * command. The mbox is used to post an SGL page per loop
+		 * but the DMA memory has a use-once semantic so the mailbox
+		 * is used and freed per loop pass.
+		 */
+		mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
+		if (!mbox) {
+			lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
+					"2933 Failed to allocate mbox cmd "
+					"memory\n");
+			return -ENOMEM;
+		}
+		alloclen = lpfc_sli4_config(phba, mbox,
+					LPFC_MBOX_SUBSYSTEM_FCOE,
+					LPFC_MBOX_OPCODE_FCOE_POST_SGL_PAGES,
+					reqlen,
+					LPFC_SLI4_MBX_NEMBED);
+		if (alloclen < reqlen) {
+			lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
+					"2934 Allocated DMA memory size (%d) "
+					"is less than the requested DMA memory "
+					"size (%d)\n", alloclen, reqlen);
+			lpfc_sli4_mbox_cmd_free(phba, mbox);
+			return -ENOMEM;
+		}
+
+		/* Get the first SGE entry from the non-embedded DMA memory */
+		viraddr = mbox->sge_array->addr[0];
+
+		/* Set up the SGL pages in the non-embedded DMA pages */
+		sgl = (struct lpfc_mbx_post_uembed_sgl_page1 *)viraddr;
+		sgl_pg_pairs = &sgl->sgl_pg_pairs;
+
+		/* pg_pairs tracks posted SGEs per loop iteration. */
+		pg_pairs = 0;
+		list_for_each_entry_continue(psb, sblist, list) {
+			/* Set up the sge entry */
+			sgl_pg_pairs->sgl_pg0_addr_lo =
+				cpu_to_le32(putPaddrLow(psb->dma_phys_bpl));
+			sgl_pg_pairs->sgl_pg0_addr_hi =
+				cpu_to_le32(putPaddrHigh(psb->dma_phys_bpl));
+			if (phba->cfg_sg_dma_buf_size > SGL_PAGE_SIZE)
+				pdma_phys_bpl1 = psb->dma_phys_bpl +
+					SGL_PAGE_SIZE;
+			else
+				pdma_phys_bpl1 = 0;
+			sgl_pg_pairs->sgl_pg1_addr_lo =
+				cpu_to_le32(putPaddrLow(pdma_phys_bpl1));
+			sgl_pg_pairs->sgl_pg1_addr_hi =
+				cpu_to_le32(putPaddrHigh(pdma_phys_bpl1));
+			/* Keep the first xri for this extent. */
+			if (pg_pairs == 0)
+				xri_start = psb->cur_iocbq.sli4_xritag;
+			sgl_pg_pairs++;
+			pg_pairs++;
+			xri_cnt++;
+
+			/*
+			 * Track two exit conditions - the loop has constructed
+			 * all of the caller's SGE pairs or all available
+			 * resource IDs in this extent are consumed.
+			 */
+			if ((xri_cnt == cnt) || (pg_pairs >= avail_cnt))
+				break;
+		}
+		rsrc_blk->rsrc_used += pg_pairs;
+		bf_set(lpfc_post_sgl_pages_xri, sgl, xri_start);
+		bf_set(lpfc_post_sgl_pages_xricnt, sgl, pg_pairs);
+
+		lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
+				"3016 Post SCSI Extent SGL, start %d, cnt %d "
+				"blk use %d\n",
+				xri_start, pg_pairs, rsrc_blk->rsrc_used);
+		/* Perform endian conversion if necessary */
+		sgl->word0 = cpu_to_le32(sgl->word0);
+		if (!phba->sli4_hba.intr_enable)
+			rc = lpfc_sli_issue_mbox(phba, mbox, MBX_POLL);
+		else {
+			mbox_tmo = lpfc_mbox_tmo_val(phba, MBX_SLI4_CONFIG);
+			rc = lpfc_sli_issue_mbox_wait(phba, mbox, mbox_tmo);
+		}
+		shdr = (union lpfc_sli4_cfg_shdr *) &sgl->cfg_shdr;
+		shdr_status = bf_get(lpfc_mbox_hdr_status, &shdr->response);
+		shdr_add_status = bf_get(lpfc_mbox_hdr_add_status,
+					 &shdr->response);
+		if (rc != MBX_TIMEOUT)
+			lpfc_sli4_mbox_cmd_free(phba, mbox);
+		if (shdr_status || shdr_add_status || rc) {
+			lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
+					"2935 POST_SGL_BLOCK mailbox command "
+					"failed status x%x add_status x%x "
+					"mbx status x%x\n",
+					shdr_status, shdr_add_status, rc);
+			return -ENXIO;
+		}
+
+		/* Post only what is requested. */
+		if (xri_cnt >= cnt)
+			break;
+	}
+	return rc;
+}
+
+/**
  * lpfc_fc_frame_check - Check that this frame is a valid frame to handle
  * @phba: pointer to lpfc_hba struct that the frame was received on
  * @fc_hdr: A pointer to the FC Header data (In Big Endian Format)
@@ -12123,6 +13399,28 @@
 }
 
 /**
+ * lpfc_sli4_xri_inrange - check xri is in range of xris owned by driver.
+ * @phba: Pointer to HBA context object.
+ * @xri: xri id in transaction.
+ *
+ * This function validates the xri maps to the known range of XRIs allocated an
+ * used by the driver.
+ **/
+static uint16_t
+lpfc_sli4_xri_inrange(struct lpfc_hba *phba,
+		      uint16_t xri)
+{
+	int i;
+
+	for (i = 0; i < phba->sli4_hba.max_cfg_param.max_xri; i++) {
+		if (xri == phba->sli4_hba.xri_ids[i])
+			return i;
+	}
+	return NO_XRI;
+}
+
+
+/**
  * lpfc_sli4_seq_abort_rsp - bls rsp to sequence abort
  * @phba: Pointer to HBA context object.
  * @fc_hdr: pointer to a FC frame header.
@@ -12155,9 +13453,7 @@
 				"SID:x%x\n", oxid, sid);
 		return;
 	}
-	if (rxid >= phba->sli4_hba.max_cfg_param.xri_base
-		&& rxid <= (phba->sli4_hba.max_cfg_param.max_xri
-		+ phba->sli4_hba.max_cfg_param.xri_base))
+	if (lpfc_sli4_xri_inrange(phba, rxid))
 		lpfc_set_rrq_active(phba, ndlp, rxid, oxid, 0);
 
 	/* Allocate buffer for rsp iocb */
@@ -12180,12 +13476,13 @@
 	icmd->ulpBdeCount = 0;
 	icmd->ulpLe = 1;
 	icmd->ulpClass = CLASS3;
-	icmd->ulpContext = ndlp->nlp_rpi;
+	icmd->ulpContext = phba->sli4_hba.rpi_ids[ndlp->nlp_rpi];
 	ctiocb->context1 = ndlp;
 
 	ctiocb->iocb_cmpl = NULL;
 	ctiocb->vport = phba->pport;
 	ctiocb->iocb_cmpl = lpfc_sli4_seq_abort_rsp_cmpl;
+	ctiocb->sli4_lxritag = NO_XRI;
 	ctiocb->sli4_xritag = NO_XRI;
 
 	/* If the oxid maps to the FCP XRI range or if it is out of range,
@@ -12366,8 +13663,8 @@
 		first_iocbq->iocb.ulpStatus = IOSTAT_SUCCESS;
 		first_iocbq->iocb.ulpCommand = CMD_IOCB_RCV_SEQ64_CX;
 		first_iocbq->iocb.ulpContext = be16_to_cpu(fc_hdr->fh_ox_id);
-		first_iocbq->iocb.unsli3.rcvsli3.vpi =
-					vport->vpi + vport->phba->vpi_base;
+		/* iocbq is prepped for internal consumption.  Logical vpi. */
+		first_iocbq->iocb.unsli3.rcvsli3.vpi = vport->vpi;
 		/* put the first buffer into the first IOCBq */
 		first_iocbq->context2 = &seq_dmabuf->dbuf;
 		first_iocbq->context3 = NULL;
@@ -12447,7 +13744,7 @@
 				      &phba->sli.ring[LPFC_ELS_RING],
 				      iocbq, fc_hdr->fh_r_ctl,
 				      fc_hdr->fh_type))
-		lpfc_printf_log(phba, KERN_WARNING, LOG_SLI,
+		lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
 				"2540 Ring %d handler: unexpected Rctl "
 				"x%x Type x%x received\n",
 				LPFC_ELS_RING,
@@ -12544,9 +13841,24 @@
 {
 	struct lpfc_rpi_hdr *rpi_page;
 	uint32_t rc = 0;
+	uint16_t lrpi = 0;
+
+	/* SLI4 ports that support extents do not require RPI headers. */
+	if (!phba->sli4_hba.rpi_hdrs_in_use)
+		goto exit;
+	if (phba->sli4_hba.extents_in_use)
+		return -EIO;
 
-	/* Post all rpi memory regions to the port. */
 	list_for_each_entry(rpi_page, &phba->sli4_hba.lpfc_rpi_hdr_list, list) {
+		/*
+		 * Assign the rpi headers a physical rpi only if the driver
+		 * has not initialized those resources.  A port reset only
+		 * needs the headers posted.
+		 */
+		if (bf_get(lpfc_rpi_rsrc_rdy, &phba->sli4_hba.sli4_flags) !=
+		    LPFC_RPI_RSRC_RDY)
+			rpi_page->start_rpi = phba->sli4_hba.rpi_ids[lrpi];
+
 		rc = lpfc_sli4_post_rpi_hdr(phba, rpi_page);
 		if (rc != MBX_SUCCESS) {
 			lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
@@ -12557,6 +13869,9 @@
 		}
 	}
 
+ exit:
+	bf_set(lpfc_rpi_rsrc_rdy, &phba->sli4_hba.sli4_flags,
+	       LPFC_RPI_RSRC_RDY);
 	return rc;
 }
 
@@ -12580,10 +13895,15 @@
 	LPFC_MBOXQ_t *mboxq;
 	struct lpfc_mbx_post_hdr_tmpl *hdr_tmpl;
 	uint32_t rc = 0;
-	uint32_t mbox_tmo;
 	uint32_t shdr_status, shdr_add_status;
 	union lpfc_sli4_cfg_shdr *shdr;
 
+	/* SLI4 ports that support extents do not require RPI headers. */
+	if (!phba->sli4_hba.rpi_hdrs_in_use)
+		return rc;
+	if (phba->sli4_hba.extents_in_use)
+		return -EIO;
+
 	/* The port is notified of the header region via a mailbox command. */
 	mboxq = (LPFC_MBOXQ_t *) mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
 	if (!mboxq) {
@@ -12595,16 +13915,19 @@
 
 	/* Post all rpi memory regions to the port. */
 	hdr_tmpl = &mboxq->u.mqe.un.hdr_tmpl;
-	mbox_tmo = lpfc_mbox_tmo_val(phba, MBX_SLI4_CONFIG);
 	lpfc_sli4_config(phba, mboxq, LPFC_MBOX_SUBSYSTEM_FCOE,
 			 LPFC_MBOX_OPCODE_FCOE_POST_HDR_TEMPLATE,
 			 sizeof(struct lpfc_mbx_post_hdr_tmpl) -
 			 sizeof(struct lpfc_sli4_cfg_mhdr),
 			 LPFC_SLI4_MBX_EMBED);
-	bf_set(lpfc_mbx_post_hdr_tmpl_page_cnt,
-	       hdr_tmpl, rpi_page->page_count);
+
+
+	/* Post the physical rpi to the port for this rpi header. */
 	bf_set(lpfc_mbx_post_hdr_tmpl_rpi_offset, hdr_tmpl,
 	       rpi_page->start_rpi);
+	bf_set(lpfc_mbx_post_hdr_tmpl_page_cnt,
+	       hdr_tmpl, rpi_page->page_count);
+
 	hdr_tmpl->rpi_paddr_lo = putPaddrLow(rpi_page->dmabuf->phys);
 	hdr_tmpl->rpi_paddr_hi = putPaddrHigh(rpi_page->dmabuf->phys);
 	rc = lpfc_sli_issue_mbox(phba, mboxq, MBX_POLL);
@@ -12639,22 +13962,21 @@
 int
 lpfc_sli4_alloc_rpi(struct lpfc_hba *phba)
 {
-	int rpi;
-	uint16_t max_rpi, rpi_base, rpi_limit;
-	uint16_t rpi_remaining;
+	unsigned long rpi;
+	uint16_t max_rpi, rpi_limit;
+	uint16_t rpi_remaining, lrpi = 0;
 	struct lpfc_rpi_hdr *rpi_hdr;
 
 	max_rpi = phba->sli4_hba.max_cfg_param.max_rpi;
-	rpi_base = phba->sli4_hba.max_cfg_param.rpi_base;
 	rpi_limit = phba->sli4_hba.next_rpi;
 
 	/*
-	 * The valid rpi range is not guaranteed to be zero-based.  Start
-	 * the search at the rpi_base as reported by the port.
+	 * Fetch the next logical rpi.  Because this index is logical,
+	 * the  driver starts at 0 each time.
 	 */
 	spin_lock_irq(&phba->hbalock);
-	rpi = find_next_zero_bit(phba->sli4_hba.rpi_bmask, rpi_limit, rpi_base);
-	if (rpi >= rpi_limit || rpi < rpi_base)
+	rpi = find_next_zero_bit(phba->sli4_hba.rpi_bmask, rpi_limit, 0);
+	if (rpi >= rpi_limit)
 		rpi = LPFC_RPI_ALLOC_ERROR;
 	else {
 		set_bit(rpi, phba->sli4_hba.rpi_bmask);
@@ -12664,7 +13986,7 @@
 
 	/*
 	 * Don't try to allocate more rpi header regions if the device limit
-	 * on available rpis max has been exhausted.
+	 * has been exhausted.
 	 */
 	if ((rpi == LPFC_RPI_ALLOC_ERROR) &&
 	    (phba->sli4_hba.rpi_count >= max_rpi)) {
@@ -12673,13 +13995,21 @@
 	}
 
 	/*
+	 * RPI header postings are not required for SLI4 ports capable of
+	 * extents.
+	 */
+	if (!phba->sli4_hba.rpi_hdrs_in_use) {
+		spin_unlock_irq(&phba->hbalock);
+		return rpi;
+	}
+
+	/*
 	 * If the driver is running low on rpi resources, allocate another
 	 * page now.  Note that the next_rpi value is used because
 	 * it represents how many are actually in use whereas max_rpi notes
 	 * how many are supported max by the device.
 	 */
-	rpi_remaining = phba->sli4_hba.next_rpi - rpi_base -
-		phba->sli4_hba.rpi_count;
+	rpi_remaining = phba->sli4_hba.next_rpi - phba->sli4_hba.rpi_count;
 	spin_unlock_irq(&phba->hbalock);
 	if (rpi_remaining < LPFC_RPI_LOW_WATER_MARK) {
 		rpi_hdr = lpfc_sli4_create_rpi_hdr(phba);
@@ -12688,6 +14018,8 @@
 					"2002 Error Could not grow rpi "
 					"count\n");
 		} else {
+			lrpi = rpi_hdr->start_rpi;
+			rpi_hdr->start_rpi = phba->sli4_hba.rpi_ids[lrpi];
 			lpfc_sli4_post_rpi_hdr(phba, rpi_hdr);
 		}
 	}
@@ -12737,6 +14069,8 @@
 lpfc_sli4_remove_rpis(struct lpfc_hba *phba)
 {
 	kfree(phba->sli4_hba.rpi_bmask);
+	kfree(phba->sli4_hba.rpi_ids);
+	bf_set(lpfc_rpi_rsrc_rdy, &phba->sli4_hba.sli4_flags, 0);
 }
 
 /**
@@ -13476,6 +14810,96 @@
 }
 
 /**
+ * lpfc_wr_object - write an object to the firmware
+ * @phba: HBA structure that indicates port to create a queue on.
+ * @dmabuf_list: list of dmabufs to write to the port.
+ * @size: the total byte value of the objects to write to the port.
+ * @offset: the current offset to be used to start the transfer.
+ *
+ * This routine will create a wr_object mailbox command to send to the port.
+ * the mailbox command will be constructed using the dma buffers described in
+ * @dmabuf_list to create a list of BDEs. This routine will fill in as many
+ * BDEs that the imbedded mailbox can support. The @offset variable will be
+ * used to indicate the starting offset of the transfer and will also return
+ * the offset after the write object mailbox has completed. @size is used to
+ * determine the end of the object and whether the eof bit should be set.
+ *
+ * Return 0 is successful and offset will contain the the new offset to use
+ * for the next write.
+ * Return negative value for error cases.
+ **/
+int
+lpfc_wr_object(struct lpfc_hba *phba, struct list_head *dmabuf_list,
+	       uint32_t size, uint32_t *offset)
+{
+	struct lpfc_mbx_wr_object *wr_object;
+	LPFC_MBOXQ_t *mbox;
+	int rc = 0, i = 0;
+	uint32_t shdr_status, shdr_add_status;
+	uint32_t mbox_tmo;
+	union lpfc_sli4_cfg_shdr *shdr;
+	struct lpfc_dmabuf *dmabuf;
+	uint32_t written = 0;
+
+	mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
+	if (!mbox)
+		return -ENOMEM;
+
+	lpfc_sli4_config(phba, mbox, LPFC_MBOX_SUBSYSTEM_COMMON,
+			LPFC_MBOX_OPCODE_WRITE_OBJECT,
+			sizeof(struct lpfc_mbx_wr_object) -
+			sizeof(struct lpfc_sli4_cfg_mhdr), LPFC_SLI4_MBX_EMBED);
+
+	wr_object = (struct lpfc_mbx_wr_object *)&mbox->u.mqe.un.wr_object;
+	wr_object->u.request.write_offset = *offset;
+	sprintf((uint8_t *)wr_object->u.request.object_name, "/");
+	wr_object->u.request.object_name[0] =
+		cpu_to_le32(wr_object->u.request.object_name[0]);
+	bf_set(lpfc_wr_object_eof, &wr_object->u.request, 0);
+	list_for_each_entry(dmabuf, dmabuf_list, list) {
+		if (i >= LPFC_MBX_WR_CONFIG_MAX_BDE || written >= size)
+			break;
+		wr_object->u.request.bde[i].addrLow = putPaddrLow(dmabuf->phys);
+		wr_object->u.request.bde[i].addrHigh =
+			putPaddrHigh(dmabuf->phys);
+		if (written + SLI4_PAGE_SIZE >= size) {
+			wr_object->u.request.bde[i].tus.f.bdeSize =
+				(size - written);
+			written += (size - written);
+			bf_set(lpfc_wr_object_eof, &wr_object->u.request, 1);
+		} else {
+			wr_object->u.request.bde[i].tus.f.bdeSize =
+				SLI4_PAGE_SIZE;
+			written += SLI4_PAGE_SIZE;
+		}
+		i++;
+	}
+	wr_object->u.request.bde_count = i;
+	bf_set(lpfc_wr_object_write_length, &wr_object->u.request, written);
+	if (!phba->sli4_hba.intr_enable)
+		rc = lpfc_sli_issue_mbox(phba, mbox, MBX_POLL);
+	else {
+		mbox_tmo = lpfc_mbox_tmo_val(phba, MBX_SLI4_CONFIG);
+		rc = lpfc_sli_issue_mbox_wait(phba, mbox, mbox_tmo);
+	}
+	/* The IOCTL status is embedded in the mailbox subheader. */
+	shdr = (union lpfc_sli4_cfg_shdr *) &wr_object->header.cfg_shdr;
+	shdr_status = bf_get(lpfc_mbox_hdr_status, &shdr->response);
+	shdr_add_status = bf_get(lpfc_mbox_hdr_add_status, &shdr->response);
+	if (rc != MBX_TIMEOUT)
+		mempool_free(mbox, phba->mbox_mem_pool);
+	if (shdr_status || shdr_add_status || rc) {
+		lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
+				"3025 Write Object mailbox failed with "
+				"status x%x add_status x%x, mbx status x%x\n",
+				shdr_status, shdr_add_status, rc);
+		rc = -ENXIO;
+	} else
+		*offset += wr_object->u.response.actual_write_length;
+	return rc;
+}
+
+/**
  * lpfc_cleanup_pending_mbox - Free up vport discovery mailbox commands.
  * @vport: pointer to vport data structure.
  *
@@ -13630,7 +15054,7 @@
 				 * never happen
 				 */
 				sglq = __lpfc_clear_active_sglq(phba,
-						 sglq->sli4_xritag);
+						 sglq->sli4_lxritag);
 				spin_unlock_irqrestore(&phba->hbalock, iflags);
 				lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
 					"2823 txq empty and txq_cnt is %d\n ",
@@ -13642,6 +15066,7 @@
 		/* The xri and iocb resources secured,
 		 * attempt to issue request
 		 */
+		piocbq->sli4_lxritag = sglq->sli4_lxritag;
 		piocbq->sli4_xritag = sglq->sli4_xritag;
 		if (NO_XRI == lpfc_sli4_bpl2sgl(phba, piocbq, sglq))
 			fail_msg = "to convert bpl to sgl";
diff -druN linux-2.6.39-libre/drivers/scsi/lpfc/lpfc_sli.h linux-3.0-rc7-libre/drivers/scsi/lpfc/lpfc_sli.h
--- linux-2.6.39-libre/drivers/scsi/lpfc/lpfc_sli.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/scsi/lpfc/lpfc_sli.h	2011-07-11 19:51:52.000000000 -0400
@@ -52,6 +52,7 @@
 	struct list_head clist;
 	struct list_head dlist;
 	uint16_t iotag;         /* pre-assigned IO tag */
+	uint16_t sli4_lxritag;  /* logical pre-assigned XRI. */
 	uint16_t sli4_xritag;   /* pre-assigned XRI, (OXID) tag. */
 	struct lpfc_cq_event cq_event;
 
diff -druN linux-2.6.39-libre/drivers/scsi/lpfc/lpfc_version.h linux-3.0-rc7-libre/drivers/scsi/lpfc/lpfc_version.h
--- linux-2.6.39-libre/drivers/scsi/lpfc/lpfc_version.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/scsi/lpfc/lpfc_version.h	2011-07-11 19:51:52.000000000 -0400
@@ -18,7 +18,7 @@
  * included with this package.                                     *
  *******************************************************************/
 
-#define LPFC_DRIVER_VERSION "8.3.22"
+#define LPFC_DRIVER_VERSION "8.3.23"
 #define LPFC_DRIVER_NAME		"lpfc"
 #define LPFC_SP_DRIVER_HANDLER_NAME	"lpfc:sp"
 #define LPFC_FP_DRIVER_HANDLER_NAME	"lpfc:fp"
diff -druN linux-2.6.39-libre/drivers/scsi/lpfc/lpfc_vport.c linux-3.0-rc7-libre/drivers/scsi/lpfc/lpfc_vport.c
--- linux-2.6.39-libre/drivers/scsi/lpfc/lpfc_vport.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/scsi/lpfc/lpfc_vport.c	2011-07-11 19:51:52.000000000 -0400
@@ -83,7 +83,7 @@
 static int
 lpfc_alloc_vpi(struct lpfc_hba *phba)
 {
-	int  vpi;
+	unsigned long vpi;
 
 	spin_lock_irq(&phba->hbalock);
 	/* Start at bit 1 because vpi zero is reserved for the physical port */
diff -druN linux-2.6.39-libre/drivers/scsi/Makefile linux-3.0-rc7-libre/drivers/scsi/Makefile
--- linux-2.6.39-libre/drivers/scsi/Makefile	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/scsi/Makefile	2011-07-11 19:51:52.000000000 -0400
@@ -73,6 +73,7 @@
 obj-$(CONFIG_SCSI_AIC7XXX_OLD)	+= aic7xxx_old.o
 obj-$(CONFIG_SCSI_AIC94XX)	+= aic94xx/
 obj-$(CONFIG_SCSI_PM8001)	+= pm8001/
+obj-$(CONFIG_SCSI_ISCI)		+= isci/
 obj-$(CONFIG_SCSI_IPS)		+= ips.o
 obj-$(CONFIG_SCSI_FD_MCS)	+= fd_mcs.o
 obj-$(CONFIG_SCSI_FUTURE_DOMAIN)+= fdomain.o
diff -druN linux-2.6.39-libre/drivers/scsi/megaraid/megaraid_mbox.c linux-3.0-rc7-libre/drivers/scsi/megaraid/megaraid_mbox.c
--- linux-2.6.39-libre/drivers/scsi/megaraid/megaraid_mbox.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/scsi/megaraid/megaraid_mbox.c	2011-07-11 19:51:52.000000000 -0400
@@ -2315,8 +2315,8 @@
 		// Was an abort issued for this command earlier
 		if (scb->state & SCB_ABORT) {
 			con_log(CL_ANN, (KERN_NOTICE
-			"megaraid: aborted cmd %lx[%x] completed\n",
-				scp->serial_number, scb->sno));
+			"megaraid: aborted cmd [%x] completed\n",
+				scb->sno));
 		}
 
 		/*
@@ -2472,8 +2472,8 @@
 	raid_dev	= ADAP2RAIDDEV(adapter);
 
 	con_log(CL_ANN, (KERN_WARNING
-		"megaraid: aborting-%ld cmd=%x <c=%d t=%d l=%d>\n",
-		scp->serial_number, scp->cmnd[0], SCP2CHANNEL(scp),
+		"megaraid: aborting cmd=%x <c=%d t=%d l=%d>\n",
+		scp->cmnd[0], SCP2CHANNEL(scp),
 		SCP2TARGET(scp), SCP2LUN(scp)));
 
 	// If FW has stopped responding, simply return failure
@@ -2496,9 +2496,8 @@
 			list_del_init(&scb->list);	// from completed list
 
 			con_log(CL_ANN, (KERN_WARNING
-			"megaraid: %ld:%d[%d:%d], abort from completed list\n",
-				scp->serial_number, scb->sno,
-				scb->dev_channel, scb->dev_target));
+			"megaraid: %d[%d:%d], abort from completed list\n",
+				scb->sno, scb->dev_channel, scb->dev_target));
 
 			scp->result = (DID_ABORT << 16);
 			scp->scsi_done(scp);
@@ -2527,9 +2526,8 @@
 			ASSERT(!(scb->state & SCB_ISSUED));
 
 			con_log(CL_ANN, (KERN_WARNING
-				"megaraid abort: %ld[%d:%d], driver owner\n",
-				scp->serial_number, scb->dev_channel,
-				scb->dev_target));
+				"megaraid abort: [%d:%d], driver owner\n",
+				scb->dev_channel, scb->dev_target));
 
 			scp->result = (DID_ABORT << 16);
 			scp->scsi_done(scp);
@@ -2560,25 +2558,21 @@
 
 			if (!(scb->state & SCB_ISSUED)) {
 				con_log(CL_ANN, (KERN_WARNING
-				"megaraid abort: %ld%d[%d:%d], invalid state\n",
-				scp->serial_number, scb->sno, scb->dev_channel,
-				scb->dev_target));
+				"megaraid abort: %d[%d:%d], invalid state\n",
+				scb->sno, scb->dev_channel, scb->dev_target));
 				BUG();
 			}
 			else {
 				con_log(CL_ANN, (KERN_WARNING
-				"megaraid abort: %ld:%d[%d:%d], fw owner\n",
-				scp->serial_number, scb->sno, scb->dev_channel,
-				scb->dev_target));
+				"megaraid abort: %d[%d:%d], fw owner\n",
+				scb->sno, scb->dev_channel, scb->dev_target));
 			}
 		}
 	}
 	spin_unlock_irq(&adapter->lock);
 
 	if (!found) {
-		con_log(CL_ANN, (KERN_WARNING
-			"megaraid abort: scsi cmd:%ld, do now own\n",
-			scp->serial_number));
+		con_log(CL_ANN, (KERN_WARNING "megaraid abort: do now own\n"));
 
 		// FIXME: Should there be a callback for this command?
 		return SUCCESS;
@@ -2649,9 +2643,8 @@
 		} else {
 			if (scb->scp == scp) {	// Found command
 				con_log(CL_ANN, (KERN_WARNING
-					"megaraid: %ld:%d[%d:%d], reset from pending list\n",
-					scp->serial_number, scb->sno,
-					scb->dev_channel, scb->dev_target));
+					"megaraid: %d[%d:%d], reset from pending list\n",
+					scb->sno, scb->dev_channel, scb->dev_target));
 			} else {
 				con_log(CL_ANN, (KERN_WARNING
 				"megaraid: IO packet with %d[%d:%d] being reset\n",
diff -druN linux-2.6.39-libre/drivers/scsi/megaraid/megaraid_sas_base.c linux-3.0-rc7-libre/drivers/scsi/megaraid/megaraid_sas_base.c
--- linux-2.6.39-libre/drivers/scsi/megaraid/megaraid_sas_base.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/scsi/megaraid/megaraid_sas_base.c	2011-07-11 19:51:52.000000000 -0400
@@ -18,7 +18,7 @@
  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  *
  *  FILE: megaraid_sas_base.c
- *  Version : v00.00.05.34-rc1
+ *  Version : v00.00.05.38-rc1
  *
  *  Authors: LSI Corporation
  *           Sreenivas Bagalkote
@@ -437,15 +437,18 @@
 static int
 megasas_clear_intr_ppc(struct megasas_register_set __iomem * regs)
 {
-	u32 status;
+	u32 status, mfiStatus = 0;
+
 	/*
 	 * Check if it is our interrupt
 	 */
 	status = readl(&regs->outbound_intr_status);
 
-	if (!(status & MFI_REPLY_1078_MESSAGE_INTERRUPT)) {
-		return 0;
-	}
+	if (status & MFI_REPLY_1078_MESSAGE_INTERRUPT)
+		mfiStatus = MFI_INTR_FLAG_REPLY_MESSAGE;
+
+	if (status & MFI_G2_OUTBOUND_DOORBELL_CHANGE_INTERRUPT)
+		mfiStatus |= MFI_INTR_FLAG_FIRMWARE_STATE_CHANGE;
 
 	/*
 	 * Clear the interrupt by writing back the same value
@@ -455,8 +458,9 @@
 	/* Dummy readl to force pci flush */
 	readl(&regs->outbound_doorbell_clear);
 
-	return 1;
+	return mfiStatus;
 }
+
 /**
  * megasas_fire_cmd_ppc -	Sends command to the FW
  * @frame_phys_addr :		Physical address of cmd
@@ -477,17 +481,6 @@
 }
 
 /**
- * megasas_adp_reset_ppc -	For controller reset
- * @regs:				MFI register set
- */
-static int
-megasas_adp_reset_ppc(struct megasas_instance *instance,
-			struct megasas_register_set __iomem *regs)
-{
-	return 0;
-}
-
-/**
  * megasas_check_reset_ppc -	For controller reset check
  * @regs:				MFI register set
  */
@@ -495,8 +488,12 @@
 megasas_check_reset_ppc(struct megasas_instance *instance,
 			struct megasas_register_set __iomem *regs)
 {
+	if (instance->adprecovery != MEGASAS_HBA_OPERATIONAL)
+		return 1;
+
 	return 0;
 }
+
 static struct megasas_instance_template megasas_instance_template_ppc = {
 
 	.fire_cmd = megasas_fire_cmd_ppc,
@@ -504,7 +501,7 @@
 	.disable_intr = megasas_disable_intr_ppc,
 	.clear_intr = megasas_clear_intr_ppc,
 	.read_fw_status_reg = megasas_read_fw_status_reg_ppc,
-	.adp_reset = megasas_adp_reset_ppc,
+	.adp_reset = megasas_adp_reset_xscale,
 	.check_reset = megasas_check_reset_ppc,
 	.service_isr = megasas_isr,
 	.tasklet = megasas_complete_cmd_dpc,
@@ -620,6 +617,9 @@
 megasas_check_reset_skinny(struct megasas_instance *instance,
 				struct megasas_register_set __iomem *regs)
 {
+	if (instance->adprecovery != MEGASAS_HBA_OPERATIONAL)
+		return 1;
+
 	return 0;
 }
 
@@ -1751,10 +1751,9 @@
 			list_del_init(&reset_cmd->list);
 			if (reset_cmd->scmd) {
 				reset_cmd->scmd->result = DID_RESET << 16;
-				printk(KERN_NOTICE "%d:%p reset [%02x], %#lx\n",
+				printk(KERN_NOTICE "%d:%p reset [%02x]\n",
 					reset_index, reset_cmd,
-					reset_cmd->scmd->cmnd[0],
-					reset_cmd->scmd->serial_number);
+					reset_cmd->scmd->cmnd[0]);
 
 				reset_cmd->scmd->scsi_done(reset_cmd->scmd);
 				megasas_return_cmd(instance, reset_cmd);
@@ -1879,8 +1878,8 @@
 
 	instance = (struct megasas_instance *)scmd->device->host->hostdata;
 
-	scmd_printk(KERN_NOTICE, scmd, "megasas: RESET -%ld cmd=%x retries=%x\n",
-		 scmd->serial_number, scmd->cmnd[0], scmd->retries);
+	scmd_printk(KERN_NOTICE, scmd, "megasas: RESET cmd=%x retries=%x\n",
+		 scmd->cmnd[0], scmd->retries);
 
 	if (instance->adprecovery == MEGASAS_HW_CRITICAL_ERROR) {
 		printk(KERN_ERR "megasas: cannot recover from previous reset "
@@ -2349,9 +2348,9 @@
 							cmd->frame_phys_addr ,
 							0, instance->reg_set);
 		} else if (cmd->scmd) {
-			printk(KERN_NOTICE "megasas: %p scsi cmd [%02x],%#lx"
+			printk(KERN_NOTICE "megasas: %p scsi cmd [%02x]"
 			"detected on the internal queue, issue again.\n",
-			cmd, cmd->scmd->cmnd[0], cmd->scmd->serial_number);
+			cmd, cmd->scmd->cmnd[0]);
 
 			atomic_inc(&instance->fw_outstanding);
 			instance->instancet->fire_cmd(instance,
@@ -3455,7 +3454,7 @@
 {
 	u32 max_sectors_1;
 	u32 max_sectors_2;
-	u32 tmp_sectors;
+	u32 tmp_sectors, msix_enable;
 	struct megasas_register_set __iomem *reg_set;
 	struct megasas_ctrl_info *ctrl_info;
 	unsigned long bar_list;
@@ -3508,6 +3507,13 @@
 	if (megasas_transition_to_ready(instance))
 		goto fail_ready_state;
 
+	/* Check if MSI-X is supported while in ready state */
+	msix_enable = (instance->instancet->read_fw_status_reg(reg_set) &
+		       0x4000000) >> 0x1a;
+	if (msix_enable && !msix_disable &&
+	    !pci_enable_msix(instance->pdev, &instance->msixentry, 1))
+		instance->msi_flag = 1;
+
 	/* Get operational params, sge flags, send init cmd to controller */
 	if (instance->instancet->init_adapter(instance))
 		goto fail_init_adapter;
@@ -4077,14 +4083,6 @@
 	else
 		INIT_WORK(&instance->work_init, process_fw_state_change_wq);
 
-	/* Try to enable MSI-X */
-	if ((instance->pdev->device != PCI_DEVICE_ID_LSI_SAS1078R) &&
-	    (instance->pdev->device != PCI_DEVICE_ID_LSI_SAS1078DE) &&
-	    (instance->pdev->device != PCI_DEVICE_ID_LSI_VERDE_ZCR) &&
-	    !msix_disable && !pci_enable_msix(instance->pdev,
-					      &instance->msixentry, 1))
-		instance->msi_flag = 1;
-
 	/*
 	 * Initialize MFI Firmware
 	 */
@@ -4117,6 +4115,14 @@
 	megasas_mgmt_info.max_index++;
 
 	/*
+	 * Register with SCSI mid-layer
+	 */
+	if (megasas_io_attach(instance))
+		goto fail_io_attach;
+
+	instance->unload = 0;
+
+	/*
 	 * Initiate AEN (Asynchronous Event Notification)
 	 */
 	if (megasas_start_aen(instance)) {
@@ -4124,13 +4130,6 @@
 		goto fail_start_aen;
 	}
 
-	/*
-	 * Register with SCSI mid-layer
-	 */
-	if (megasas_io_attach(instance))
-		goto fail_io_attach;
-
-	instance->unload = 0;
 	return 0;
 
       fail_start_aen:
@@ -4333,10 +4332,6 @@
 	if (megasas_set_dma_mask(pdev))
 		goto fail_set_dma_mask;
 
-	/* Now re-enable MSI-X */
-	if (instance->msi_flag)
-		pci_enable_msix(instance->pdev, &instance->msixentry, 1);
-
 	/*
 	 * Initialize MFI Firmware
 	 */
@@ -4349,6 +4344,10 @@
 	if (megasas_transition_to_ready(instance))
 		goto fail_ready_state;
 
+	/* Now re-enable MSI-X */
+	if (instance->msi_flag)
+		pci_enable_msix(instance->pdev, &instance->msixentry, 1);
+
 	switch (instance->pdev->device) {
 	case PCI_DEVICE_ID_LSI_FUSION:
 	{
@@ -4385,12 +4384,6 @@
 
 	instance->instancet->enable_intr(instance->reg_set);
 
-	/*
-	 * Initiate AEN (Asynchronous Event Notification)
-	 */
-	if (megasas_start_aen(instance))
-		printk(KERN_ERR "megasas: Start AEN failed\n");
-
 	/* Initialize the cmd completion timer */
 	if (poll_mode_io)
 		megasas_start_timer(instance, &instance->io_completion_timer,
@@ -4398,6 +4391,12 @@
 				MEGASAS_COMPLETION_TIMER_INTERVAL);
 	instance->unload = 0;
 
+	/*
+	 * Initiate AEN (Asynchronous Event Notification)
+	 */
+	if (megasas_start_aen(instance))
+		printk(KERN_ERR "megasas: Start AEN failed\n");
+
 	return 0;
 
 fail_irq:
@@ -4528,6 +4527,11 @@
 	instance->unload = 1;
 	megasas_flush_cache(instance);
 	megasas_shutdown_controller(instance, MR_DCMD_CTRL_SHUTDOWN);
+	instance->instancet->disable_intr(instance->reg_set);
+	free_irq(instance->msi_flag ? instance->msixentry.vector :
+		 instance->pdev->irq, instance);
+	if (instance->msi_flag)
+		pci_disable_msix(instance->pdev);
 }
 
 /**
diff -druN linux-2.6.39-libre/drivers/scsi/megaraid/megaraid_sas_fusion.c linux-3.0-rc7-libre/drivers/scsi/megaraid/megaraid_sas_fusion.c
--- linux-2.6.39-libre/drivers/scsi/megaraid/megaraid_sas_fusion.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/scsi/megaraid/megaraid_sas_fusion.c	2011-07-11 19:51:52.000000000 -0400
@@ -696,22 +696,6 @@
 }
 
 /*
- * megasas_return_cmd_for_smid -	Returns a cmd_fusion for a SMID
- * @instance:				Adapter soft state
- *
- */
-void
-megasas_return_cmd_for_smid(struct megasas_instance *instance, u16 smid)
-{
-	struct fusion_context *fusion;
-	struct megasas_cmd_fusion *cmd;
-
-	fusion = instance->ctrl_context;
-	cmd = fusion->cmd_list[smid - 1];
-	megasas_return_cmd_fusion(instance, cmd);
-}
-
-/*
  * megasas_get_ld_map_info -	Returns FW's ld_map structure
  * @instance:				Adapter soft state
  * @pend:				Pend the command or not
@@ -1153,7 +1137,7 @@
 	u64 start_blk = io_info->pdBlock;
 	u8 *cdb = io_request->CDB.CDB32;
 	u32 num_blocks = io_info->numBlocks;
-	u8 opcode, flagvals, groupnum, control;
+	u8 opcode = 0, flagvals = 0, groupnum = 0, control = 0;
 
 	/* Check if T10 PI (DIF) is enabled for this LD */
 	ld = MR_TargetIdToLdGet(io_info->ldTgtId, local_map_ptr);
@@ -1235,7 +1219,46 @@
 			cdb[8] = (u8)(num_blocks & 0xff);
 			cdb[7] = (u8)((num_blocks >> 8) & 0xff);
 
+			io_request->IoFlags = 10; /* Specify 10-byte cdb */
 			cdb_len = 10;
+		} else if ((cdb_len < 16) && (start_blk > 0xffffffff)) {
+			/* Convert to 16 byte CDB for large LBA's */
+			switch (cdb_len) {
+			case 6:
+				opcode = cdb[0] == READ_6 ? READ_16 : WRITE_16;
+				control = cdb[5];
+				break;
+			case 10:
+				opcode =
+					cdb[0] == READ_10 ? READ_16 : WRITE_16;
+				flagvals = cdb[1];
+				groupnum = cdb[6];
+				control = cdb[9];
+				break;
+			case 12:
+				opcode =
+					cdb[0] == READ_12 ? READ_16 : WRITE_16;
+				flagvals = cdb[1];
+				groupnum = cdb[10];
+				control = cdb[11];
+				break;
+			}
+
+			memset(cdb, 0, sizeof(io_request->CDB.CDB32));
+
+			cdb[0] = opcode;
+			cdb[1] = flagvals;
+			cdb[14] = groupnum;
+			cdb[15] = control;
+
+			/* Transfer length */
+			cdb[13] = (u8)(num_blocks & 0xff);
+			cdb[12] = (u8)((num_blocks >> 8) & 0xff);
+			cdb[11] = (u8)((num_blocks >> 16) & 0xff);
+			cdb[10] = (u8)((num_blocks >> 24) & 0xff);
+
+			io_request->IoFlags = 16; /* Specify 16-byte cdb */
+			cdb_len = 16;
 		}
 
 		/* Normal case, just load LBA here */
@@ -2026,17 +2049,11 @@
 	struct fusion_context *fusion;
 	struct megasas_cmd *cmd_mfi;
 	union MEGASAS_REQUEST_DESCRIPTOR_UNION *req_desc;
-	u32 host_diag, abs_state;
+	u32 host_diag, abs_state, status_reg, reset_adapter;
 
 	instance = (struct megasas_instance *)shost->hostdata;
 	fusion = instance->ctrl_context;
 
-	mutex_lock(&instance->reset_mutex);
-	set_bit(MEGASAS_FUSION_IN_RESET, &instance->reset_flags);
-	instance->adprecovery = MEGASAS_ADPRESET_SM_INFAULT;
-	instance->instancet->disable_intr(instance->reg_set);
-	msleep(1000);
-
 	if (instance->adprecovery == MEGASAS_HW_CRITICAL_ERROR) {
 		printk(KERN_WARNING "megaraid_sas: Hardware critical error, "
 		       "returning FAILED.\n");
@@ -2044,6 +2061,12 @@
 		goto out;
 	}
 
+	mutex_lock(&instance->reset_mutex);
+	set_bit(MEGASAS_FUSION_IN_RESET, &instance->reset_flags);
+	instance->adprecovery = MEGASAS_ADPRESET_SM_INFAULT;
+	instance->instancet->disable_intr(instance->reg_set);
+	msleep(1000);
+
 	/* First try waiting for commands to complete */
 	if (megasas_wait_for_outstanding_fusion(instance)) {
 		printk(KERN_WARNING "megaraid_sas: resetting fusion "
@@ -2060,7 +2083,12 @@
 			}
 		}
 
-		if (instance->disableOnlineCtrlReset == 1) {
+		status_reg = instance->instancet->read_fw_status_reg(
+			instance->reg_set);
+		abs_state = status_reg & MFI_STATE_MASK;
+		reset_adapter = status_reg & MFI_RESET_ADAPTER;
+		if (instance->disableOnlineCtrlReset ||
+		    (abs_state == MFI_STATE_FAULT && !reset_adapter)) {
 			/* Reset not supported, kill adapter */
 			printk(KERN_WARNING "megaraid_sas: Reset not supported"
 			       ", killing adapter.\n");
@@ -2089,6 +2117,7 @@
 
 			/* Check that the diag write enable (DRWE) bit is on */
 			host_diag = readl(&instance->reg_set->fusion_host_diag);
+			retry = 0;
 			while (!(host_diag & HOST_DIAG_WRITE_ENABLE)) {
 				msleep(100);
 				host_diag =
@@ -2126,7 +2155,7 @@
 
 			abs_state =
 				instance->instancet->read_fw_status_reg(
-					instance->reg_set);
+					instance->reg_set) & MFI_STATE_MASK;
 			retry = 0;
 
 			while ((abs_state <= MFI_STATE_FW_INIT) &&
@@ -2134,7 +2163,7 @@
 				msleep(100);
 				abs_state =
 				instance->instancet->read_fw_status_reg(
-					instance->reg_set);
+					instance->reg_set) & MFI_STATE_MASK;
 			}
 			if (abs_state <= MFI_STATE_FW_INIT) {
 				printk(KERN_WARNING "megaraid_sas: firmware "
diff -druN linux-2.6.39-libre/drivers/scsi/megaraid/megaraid_sas.h linux-3.0-rc7-libre/drivers/scsi/megaraid/megaraid_sas.h
--- linux-2.6.39-libre/drivers/scsi/megaraid/megaraid_sas.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/scsi/megaraid/megaraid_sas.h	2011-07-11 19:51:52.000000000 -0400
@@ -33,9 +33,9 @@
 /*
  * MegaRAID SAS Driver meta data
  */
-#define MEGASAS_VERSION				"00.00.05.34-rc1"
-#define MEGASAS_RELDATE				"Feb. 24, 2011"
-#define MEGASAS_EXT_VERSION			"Thu. Feb. 24 17:00:00 PDT 2011"
+#define MEGASAS_VERSION				"00.00.05.38-rc1"
+#define MEGASAS_RELDATE				"May. 11, 2011"
+#define MEGASAS_EXT_VERSION			"Wed. May. 11 17:00:00 PDT 2011"
 
 /*
  * Device IDs
@@ -76,8 +76,8 @@
 #define MFI_STATE_READY				0xB0000000
 #define MFI_STATE_OPERATIONAL			0xC0000000
 #define MFI_STATE_FAULT				0xF0000000
-#define  MFI_RESET_REQUIRED			0x00000001
-
+#define MFI_RESET_REQUIRED			0x00000001
+#define MFI_RESET_ADAPTER			0x00000002
 #define MEGAMFI_FRAME_SIZE			64
 
 /*
diff -druN linux-2.6.39-libre/drivers/scsi/megaraid.c linux-3.0-rc7-libre/drivers/scsi/megaraid.c
--- linux-2.6.39-libre/drivers/scsi/megaraid.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/scsi/megaraid.c	2011-07-11 19:51:52.000000000 -0400
@@ -1469,8 +1469,8 @@
 			if( scb->state & SCB_ABORT ) {
 
 				printk(KERN_WARNING
-				"megaraid: aborted cmd %lx[%x] complete.\n",
-					scb->cmd->serial_number, scb->idx);
+				"megaraid: aborted cmd [%x] complete.\n",
+					scb->idx);
 
 				scb->cmd->result = (DID_ABORT << 16);
 
@@ -1488,8 +1488,8 @@
 			if( scb->state & SCB_RESET ) {
 
 				printk(KERN_WARNING
-				"megaraid: reset cmd %lx[%x] complete.\n",
-					scb->cmd->serial_number, scb->idx);
+				"megaraid: reset cmd [%x] complete.\n",
+					scb->idx);
 
 				scb->cmd->result = (DID_RESET << 16);
 
@@ -1958,8 +1958,8 @@
 	struct list_head	*pos, *next;
 	scb_t			*scb;
 
-	printk(KERN_WARNING "megaraid: %s-%lx cmd=%x <c=%d t=%d l=%d>\n",
-	     (aor == SCB_ABORT)? "ABORTING":"RESET", cmd->serial_number,
+	printk(KERN_WARNING "megaraid: %s cmd=%x <c=%d t=%d l=%d>\n",
+	     (aor == SCB_ABORT)? "ABORTING":"RESET",
 	     cmd->cmnd[0], cmd->device->channel, 
 	     cmd->device->id, cmd->device->lun);
 
@@ -1983,9 +1983,9 @@
 			if( scb->state & SCB_ISSUED ) {
 
 				printk(KERN_WARNING
-					"megaraid: %s-%lx[%x], fw owner.\n",
+					"megaraid: %s[%x], fw owner.\n",
 					(aor==SCB_ABORT) ? "ABORTING":"RESET",
-					cmd->serial_number, scb->idx);
+					scb->idx);
 
 				return FALSE;
 			}
@@ -1996,9 +1996,9 @@
 				 * list
 				 */
 				printk(KERN_WARNING
-					"megaraid: %s-%lx[%x], driver owner.\n",
+					"megaraid: %s-[%x], driver owner.\n",
 					(aor==SCB_ABORT) ? "ABORTING":"RESET",
-					cmd->serial_number, scb->idx);
+					scb->idx);
 
 				mega_free_scb(adapter, scb);
 
diff -druN linux-2.6.39-libre/drivers/scsi/mesh.c linux-3.0-rc7-libre/drivers/scsi/mesh.c
--- linux-2.6.39-libre/drivers/scsi/mesh.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/scsi/mesh.c	2011-07-11 19:51:52.000000000 -0400
@@ -415,8 +415,7 @@
 #if 1
 	if (DEBUG_TARGET(cmd)) {
 		int i;
-		printk(KERN_DEBUG "mesh_start: %p ser=%lu tgt=%d cmd=",
-		       cmd, cmd->serial_number, id);
+		printk(KERN_DEBUG "mesh_start: %p tgt=%d cmd=", cmd, id);
 		for (i = 0; i < cmd->cmd_len; ++i)
 			printk(" %x", cmd->cmnd[i]);
 		printk(" use_sg=%d buffer=%p bufflen=%u\n",
diff -druN linux-2.6.39-libre/drivers/scsi/mpt2sas/mpt2sas_base.c linux-3.0-rc7-libre/drivers/scsi/mpt2sas/mpt2sas_base.c
--- linux-2.6.39-libre/drivers/scsi/mpt2sas/mpt2sas_base.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/scsi/mpt2sas/mpt2sas_base.c	2011-07-11 19:51:52.000000000 -0400
@@ -522,7 +522,8 @@
 		desc = "Device Status Change";
 		break;
 	case MPI2_EVENT_IR_OPERATION_STATUS:
-		desc = "IR Operation Status";
+		if (!ioc->hide_ir_msg)
+			desc = "IR Operation Status";
 		break;
 	case MPI2_EVENT_SAS_DISCOVERY:
 	{
@@ -553,16 +554,20 @@
 		desc = "SAS Enclosure Device Status Change";
 		break;
 	case MPI2_EVENT_IR_VOLUME:
-		desc = "IR Volume";
+		if (!ioc->hide_ir_msg)
+			desc = "IR Volume";
 		break;
 	case MPI2_EVENT_IR_PHYSICAL_DISK:
-		desc = "IR Physical Disk";
+		if (!ioc->hide_ir_msg)
+			desc = "IR Physical Disk";
 		break;
 	case MPI2_EVENT_IR_CONFIGURATION_CHANGE_LIST:
-		desc = "IR Configuration Change List";
+		if (!ioc->hide_ir_msg)
+			desc = "IR Configuration Change List";
 		break;
 	case MPI2_EVENT_LOG_ENTRY_ADDED:
-		desc = "Log Entry Added";
+		if (!ioc->hide_ir_msg)
+			desc = "Log Entry Added";
 		break;
 	}
 
@@ -616,7 +621,10 @@
 		originator_str = "PL";
 		break;
 	case 2:
-		originator_str = "IR";
+		if (!ioc->hide_ir_msg)
+			originator_str = "IR";
+		else
+			originator_str = "WarpDrive";
 		break;
 	}
 
@@ -1508,6 +1516,7 @@
 		}
 		ioc->scsi_lookup[i].cb_idx = 0xFF;
 		ioc->scsi_lookup[i].scmd = NULL;
+		ioc->scsi_lookup[i].direct_io = 0;
 		list_add_tail(&ioc->scsi_lookup[i].tracker_list,
 		    &ioc->free_list);
 		spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
@@ -1844,10 +1853,12 @@
 	printk("), ");
 	printk("Capabilities=(");
 
-	if (ioc->facts.IOCCapabilities &
-	    MPI2_IOCFACTS_CAPABILITY_INTEGRATED_RAID) {
-		printk("Raid");
-		i++;
+	if (!ioc->hide_ir_msg) {
+		if (ioc->facts.IOCCapabilities &
+		    MPI2_IOCFACTS_CAPABILITY_INTEGRATED_RAID) {
+			printk("Raid");
+			i++;
+		}
 	}
 
 	if (ioc->facts.IOCCapabilities & MPI2_IOCFACTS_CAPABILITY_TLR) {
@@ -3680,6 +3691,7 @@
 	u32 reply_address;
 	u16 smid;
 	struct _tr_list *delayed_tr, *delayed_tr_next;
+	u8 hide_flag;
 
 	dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "%s\n", ioc->name,
 	    __func__));
@@ -3706,6 +3718,7 @@
 		ioc->scsi_lookup[i].cb_idx = 0xFF;
 		ioc->scsi_lookup[i].smid = smid;
 		ioc->scsi_lookup[i].scmd = NULL;
+		ioc->scsi_lookup[i].direct_io = 0;
 		list_add_tail(&ioc->scsi_lookup[i].tracker_list,
 		    &ioc->free_list);
 	}
@@ -3766,6 +3779,15 @@
 	if (sleep_flag == CAN_SLEEP)
 		_base_static_config_pages(ioc);
 
+	if (ioc->wait_for_port_enable_to_complete && ioc->is_warpdrive) {
+		if (ioc->manu_pg10.OEMIdentifier  == 0x80) {
+			hide_flag = (u8) (ioc->manu_pg10.OEMSpecificFlags0 &
+			    MFG_PAGE10_HIDE_SSDS_MASK);
+			if (hide_flag != MFG_PAGE10_HIDE_SSDS_MASK)
+				ioc->mfg_pg10_hide_flag = hide_flag;
+		}
+	}
+
 	if (ioc->wait_for_port_enable_to_complete) {
 		if (diag_buffer_enable != 0)
 			mpt2sas_enable_diag_buffer(ioc, diag_buffer_enable);
diff -druN linux-2.6.39-libre/drivers/scsi/mpt2sas/mpt2sas_base.h linux-3.0-rc7-libre/drivers/scsi/mpt2sas/mpt2sas_base.h
--- linux-2.6.39-libre/drivers/scsi/mpt2sas/mpt2sas_base.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/scsi/mpt2sas/mpt2sas_base.h	2011-07-11 19:51:52.000000000 -0400
@@ -69,11 +69,11 @@
 #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		"08.100.00.00"
+#define MPT2SAS_DRIVER_VERSION		"08.100.00.02"
 #define MPT2SAS_MAJOR_VERSION		08
 #define MPT2SAS_MINOR_VERSION		100
 #define MPT2SAS_BUILD_VERSION		00
-#define MPT2SAS_RELEASE_VERSION		00
+#define MPT2SAS_RELEASE_VERSION		02
 
 /*
  * Set MPT2SAS_SG_DEPTH value based on user input.
@@ -189,6 +189,16 @@
 #define MPT2SAS_HP_DAUGHTER_2_4_INTERNAL_SSDID        0x0046
 
 /*
+ *  WarpDrive Specific Log codes
+ */
+
+#define MPT2_WARPDRIVE_LOGENTRY		(0x8002)
+#define MPT2_WARPDRIVE_LC_SSDT		(0x41)
+#define MPT2_WARPDRIVE_LC_SSDLW		(0x43)
+#define MPT2_WARPDRIVE_LC_SSDLF		(0x44)
+#define MPT2_WARPDRIVE_LC_BRMF		(0x4D)
+
+/*
  * per target private data
  */
 #define MPT_TARGET_FLAGS_RAID_COMPONENT	0x01
@@ -199,6 +209,7 @@
  * struct MPT2SAS_TARGET - starget private hostdata
  * @starget: starget object
  * @sas_address: target sas address
+ * @raid_device: raid_device pointer to access volume data
  * @handle: device handle
  * @num_luns: number luns
  * @flags: MPT_TARGET_FLAGS_XXX flags
@@ -208,6 +219,7 @@
 struct MPT2SAS_TARGET {
 	struct scsi_target *starget;
 	u64	sas_address;
+	struct _raid_device *raid_device;
 	u16	handle;
 	int	num_luns;
 	u32	flags;
@@ -215,6 +227,7 @@
 	u8	tm_busy;
 };
 
+
 /*
  * per device private data
  */
@@ -262,6 +275,12 @@
   MPI2_POINTER PTR_MPI2_CONFIG_PAGE_MAN_10,
   Mpi2ManufacturingPage10_t, MPI2_POINTER pMpi2ManufacturingPage10_t;
 
+#define MFG_PAGE10_HIDE_SSDS_MASK	(0x00000003)
+#define MFG_PAGE10_HIDE_ALL_DISKS	(0x00)
+#define MFG_PAGE10_EXPOSE_ALL_DISKS	(0x01)
+#define MFG_PAGE10_HIDE_IF_VOL_PRESENT	(0x02)
+
+
 struct MPT2SAS_DEVICE {
 	struct MPT2SAS_TARGET *sas_target;
 	unsigned int	lun;
@@ -341,6 +360,7 @@
  * @sdev: scsi device struct (volumes are single lun)
  * @wwid: unique identifier for the volume
  * @handle: device handle
+ * @block_size: Block size of the volume
  * @id: target id
  * @channel: target channel
  * @volume_type: the raid level
@@ -348,20 +368,33 @@
  * @num_pds: number of hidden raid components
  * @responding: used in _scsih_raid_device_mark_responding
  * @percent_complete: resync percent complete
+ * @direct_io_enabled: Whether direct io to PDs are allowed or not
+ * @stripe_exponent: X where 2powX is the stripe sz in blocks
+ * @max_lba: Maximum number of LBA in the volume
+ * @stripe_sz: Stripe Size of the volume
+ * @device_info: Device info of the volume member disk
+ * @pd_handle: Array of handles of the physical drives for direct I/O in le16
  */
+#define MPT_MAX_WARPDRIVE_PDS		8
 struct _raid_device {
 	struct list_head list;
 	struct scsi_target *starget;
 	struct scsi_device *sdev;
 	u64	wwid;
 	u16	handle;
+	u16	block_sz;
 	int	id;
 	int	channel;
 	u8	volume_type;
-	u32	device_info;
 	u8	num_pds;
 	u8	responding;
 	u8	percent_complete;
+	u8	direct_io_enabled;
+	u8	stripe_exponent;
+	u64	max_lba;
+	u32	stripe_sz;
+	u32	device_info;
+	u16	pd_handle[MPT_MAX_WARPDRIVE_PDS];
 };
 
 /**
@@ -470,6 +503,7 @@
  * @smid: system message id
  * @scmd: scsi request pointer
  * @cb_idx: callback index
+ * @direct_io: To indicate whether I/O is direct (WARPDRIVE)
  * @chain_list: list of chains associated to this IO
  * @tracker_list: list of free request (ioc->free_list)
  */
@@ -477,14 +511,14 @@
 	u16	smid;
 	struct scsi_cmnd *scmd;
 	u8	cb_idx;
+	u8	direct_io;
 	struct list_head chain_list;
 	struct list_head tracker_list;
 };
 
 /**
- * struct request_tracker - misc mf request tracker
+ * struct request_tracker - firmware request tracker
  * @smid: system message id
- * @scmd: scsi request pointer
  * @cb_idx: callback index
  * @tracker_list: list of free request (ioc->free_list)
  */
@@ -832,6 +866,11 @@
 	u32		diagnostic_flags[MPI2_DIAG_BUF_TYPE_COUNT];
 	u32		ring_buffer_offset;
 	u32		ring_buffer_sz;
+	u8		is_warpdrive;
+	u8		hide_ir_msg;
+	u8		mfg_pg10_hide_flag;
+	u8		hide_drives;
+
 };
 
 typedef u8 (*MPT_CALLBACK)(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 msix_index,
diff -druN linux-2.6.39-libre/drivers/scsi/mpt2sas/mpt2sas_ctl.c linux-3.0-rc7-libre/drivers/scsi/mpt2sas/mpt2sas_ctl.c
--- linux-2.6.39-libre/drivers/scsi/mpt2sas/mpt2sas_ctl.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/scsi/mpt2sas/mpt2sas_ctl.c	2011-07-11 19:51:52.000000000 -0400
@@ -1041,7 +1041,10 @@
 	    __func__));
 
 	memset(&karg, 0 , sizeof(karg));
-	karg.adapter_type = MPT2_IOCTL_INTERFACE_SAS2;
+	if (ioc->is_warpdrive)
+		karg.adapter_type = MPT2_IOCTL_INTERFACE_SAS2_SSS6200;
+	else
+		karg.adapter_type = MPT2_IOCTL_INTERFACE_SAS2;
 	if (ioc->pfacts)
 		karg.port_number = ioc->pfacts[0].PortNumber;
 	pci_read_config_byte(ioc->pdev, PCI_CLASS_REVISION, &revision);
diff -druN linux-2.6.39-libre/drivers/scsi/mpt2sas/mpt2sas_ctl.h linux-3.0-rc7-libre/drivers/scsi/mpt2sas/mpt2sas_ctl.h
--- linux-2.6.39-libre/drivers/scsi/mpt2sas/mpt2sas_ctl.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/scsi/mpt2sas/mpt2sas_ctl.h	2011-07-11 19:51:52.000000000 -0400
@@ -133,6 +133,7 @@
 #define MPT2_IOCTL_INTERFACE_FC_IP	(0x02)
 #define MPT2_IOCTL_INTERFACE_SAS	(0x03)
 #define MPT2_IOCTL_INTERFACE_SAS2	(0x04)
+#define MPT2_IOCTL_INTERFACE_SAS2_SSS6200	(0x05)
 #define MPT2_IOCTL_VERSION_LENGTH	(32)
 
 /**
diff -druN linux-2.6.39-libre/drivers/scsi/mpt2sas/mpt2sas_scsih.c linux-3.0-rc7-libre/drivers/scsi/mpt2sas/mpt2sas_scsih.c
--- linux-2.6.39-libre/drivers/scsi/mpt2sas/mpt2sas_scsih.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/scsi/mpt2sas/mpt2sas_scsih.c	2011-07-11 19:51:52.000000000 -0400
@@ -113,6 +113,7 @@
 };
 
 
+#define MPT2SAS_TURN_ON_FAULT_LED (0xFFFC)
 #define MPT2SAS_RESCAN_AFTER_HOST_RESET (0xFFFF)
 
 /**
@@ -121,6 +122,7 @@
  * @work: work object (ioc->fault_reset_work_q)
  * @cancel_pending_work: flag set during reset handling
  * @ioc: per adapter object
+ * @device_handle: device handle
  * @VF_ID: virtual function id
  * @VP_ID: virtual port id
  * @ignore: flag meaning this event has been marked to ignore
@@ -134,6 +136,7 @@
 	u8			cancel_pending_work;
 	struct delayed_work	delayed_work;
 	struct MPT2SAS_ADAPTER *ioc;
+	u16			device_handle;
 	u8			VF_ID;
 	u8			VP_ID;
 	u8			ignore;
@@ -233,6 +236,9 @@
 		PCI_ANY_ID, PCI_ANY_ID },
 	{ MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SAS2308_3,
 		PCI_ANY_ID, PCI_ANY_ID },
+	/* SSS6200 */
+	{ MPI2_MFGPAGE_VENDORID_LSI, MPI2_MFGPAGE_DEVID_SSS6200,
+		PCI_ANY_ID, PCI_ANY_ID },
 	{0}	/* Terminating entry */
 };
 MODULE_DEVICE_TABLE(pci, scsih_pci_table);
@@ -1256,6 +1262,7 @@
 			sas_target_priv_data->handle = raid_device->handle;
 			sas_target_priv_data->sas_address = raid_device->wwid;
 			sas_target_priv_data->flags |= MPT_TARGET_FLAGS_VOLUME;
+			sas_target_priv_data->raid_device = raid_device;
 			raid_device->starget = starget;
 		}
 		spin_unlock_irqrestore(&ioc->raid_device_lock, flags);
@@ -1455,7 +1462,10 @@
 _scsih_is_raid(struct device *dev)
 {
 	struct scsi_device *sdev = to_scsi_device(dev);
+	struct MPT2SAS_ADAPTER *ioc = shost_priv(sdev->host);
 
+	if (ioc->is_warpdrive)
+		return 0;
 	return (sdev->channel == RAID_CHANNEL) ? 1 : 0;
 }
 
@@ -1480,7 +1490,7 @@
 	    sdev->channel);
 	spin_unlock_irqrestore(&ioc->raid_device_lock, flags);
 
-	if (!raid_device)
+	if (!raid_device || ioc->is_warpdrive)
 		goto out;
 
 	if (mpt2sas_config_get_raid_volume_pg0(ioc, &mpi_reply, &vol_pg0,
@@ -1640,6 +1650,212 @@
 
 	kfree(vol_pg0);
 }
+/**
+ * _scsih_disable_ddio - Disable direct I/O for all the volumes
+ * @ioc: per adapter object
+ */
+static void
+_scsih_disable_ddio(struct MPT2SAS_ADAPTER *ioc)
+{
+	Mpi2RaidVolPage1_t vol_pg1;
+	Mpi2ConfigReply_t mpi_reply;
+	struct _raid_device *raid_device;
+	u16 handle;
+	u16 ioc_status;
+
+	handle = 0xFFFF;
+	while (!(mpt2sas_config_get_raid_volume_pg1(ioc, &mpi_reply,
+	    &vol_pg1, MPI2_RAID_VOLUME_PGAD_FORM_GET_NEXT_HANDLE, handle))) {
+		ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
+		    MPI2_IOCSTATUS_MASK;
+		if (ioc_status == MPI2_IOCSTATUS_CONFIG_INVALID_PAGE)
+			break;
+		handle = le16_to_cpu(vol_pg1.DevHandle);
+		raid_device = _scsih_raid_device_find_by_handle(ioc, handle);
+		if (raid_device)
+			raid_device->direct_io_enabled = 0;
+	}
+	return;
+}
+
+
+/**
+ * _scsih_get_num_volumes - Get number of volumes in the ioc
+ * @ioc: per adapter object
+ */
+static u8
+_scsih_get_num_volumes(struct MPT2SAS_ADAPTER *ioc)
+{
+	Mpi2RaidVolPage1_t vol_pg1;
+	Mpi2ConfigReply_t mpi_reply;
+	u16 handle;
+	u8 vol_cnt = 0;
+	u16 ioc_status;
+
+	handle = 0xFFFF;
+	while (!(mpt2sas_config_get_raid_volume_pg1(ioc, &mpi_reply,
+	    &vol_pg1, MPI2_RAID_VOLUME_PGAD_FORM_GET_NEXT_HANDLE, handle))) {
+		ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
+		    MPI2_IOCSTATUS_MASK;
+		if (ioc_status == MPI2_IOCSTATUS_CONFIG_INVALID_PAGE)
+			break;
+		vol_cnt++;
+		handle = le16_to_cpu(vol_pg1.DevHandle);
+	}
+	return vol_cnt;
+}
+
+
+/**
+ * _scsih_init_warpdrive_properties - Set properties for warpdrive direct I/O.
+ * @ioc: per adapter object
+ * @raid_device: the raid_device object
+ */
+static void
+_scsih_init_warpdrive_properties(struct MPT2SAS_ADAPTER *ioc,
+	struct _raid_device *raid_device)
+{
+	Mpi2RaidVolPage0_t *vol_pg0;
+	Mpi2RaidPhysDiskPage0_t pd_pg0;
+	Mpi2ConfigReply_t mpi_reply;
+	u16 sz;
+	u8 num_pds, count;
+	u64 mb = 1024 * 1024;
+	u64 tb_2 = 2 * mb * mb;
+	u64 capacity;
+	u32 stripe_sz;
+	u8 i, stripe_exp;
+
+	if (!ioc->is_warpdrive)
+		return;
+
+	if (ioc->mfg_pg10_hide_flag ==  MFG_PAGE10_EXPOSE_ALL_DISKS) {
+		printk(MPT2SAS_INFO_FMT "WarpDrive : Direct IO is disabled "
+		    "globally as drives are exposed\n", ioc->name);
+		return;
+	}
+	if (_scsih_get_num_volumes(ioc) > 1) {
+		_scsih_disable_ddio(ioc);
+		printk(MPT2SAS_INFO_FMT "WarpDrive : Direct IO is disabled "
+		    "globally as number of drives > 1\n", ioc->name);
+		return;
+	}
+	if ((mpt2sas_config_get_number_pds(ioc, raid_device->handle,
+	    &num_pds)) || !num_pds) {
+		printk(MPT2SAS_INFO_FMT "WarpDrive : Direct IO is disabled "
+		    "Failure in computing number of drives\n", ioc->name);
+		return;
+	}
+
+	sz = offsetof(Mpi2RaidVolPage0_t, PhysDisk) + (num_pds *
+	    sizeof(Mpi2RaidVol0PhysDisk_t));
+	vol_pg0 = kzalloc(sz, GFP_KERNEL);
+	if (!vol_pg0) {
+		printk(MPT2SAS_INFO_FMT "WarpDrive : Direct IO is disabled "
+		    "Memory allocation failure for RVPG0\n", ioc->name);
+		return;
+	}
+
+	if ((mpt2sas_config_get_raid_volume_pg0(ioc, &mpi_reply, vol_pg0,
+	     MPI2_RAID_VOLUME_PGAD_FORM_HANDLE, raid_device->handle, sz))) {
+		printk(MPT2SAS_INFO_FMT "WarpDrive : Direct IO is disabled "
+		    "Failure in retrieving RVPG0\n", ioc->name);
+		kfree(vol_pg0);
+		return;
+	}
+
+	/*
+	 * WARPDRIVE:If number of physical disks in a volume exceeds the max pds
+	 * assumed for WARPDRIVE, disable direct I/O
+	 */
+	if (num_pds > MPT_MAX_WARPDRIVE_PDS) {
+		printk(MPT2SAS_WARN_FMT "WarpDrive : Direct IO is disabled "
+		    "for the drive with handle(0x%04x): num_mem=%d, "
+		    "max_mem_allowed=%d\n", ioc->name, raid_device->handle,
+		    num_pds, MPT_MAX_WARPDRIVE_PDS);
+		kfree(vol_pg0);
+		return;
+	}
+	for (count = 0; count < num_pds; count++) {
+		if (mpt2sas_config_get_phys_disk_pg0(ioc, &mpi_reply,
+		    &pd_pg0, MPI2_PHYSDISK_PGAD_FORM_PHYSDISKNUM,
+		    vol_pg0->PhysDisk[count].PhysDiskNum) ||
+		    pd_pg0.DevHandle == MPT2SAS_INVALID_DEVICE_HANDLE) {
+			printk(MPT2SAS_INFO_FMT "WarpDrive : Direct IO is "
+			    "disabled for the drive with handle(0x%04x) member"
+			    "handle retrieval failed for member number=%d\n",
+			    ioc->name, raid_device->handle,
+			    vol_pg0->PhysDisk[count].PhysDiskNum);
+			goto out_error;
+		}
+		raid_device->pd_handle[count] = le16_to_cpu(pd_pg0.DevHandle);
+	}
+
+	/*
+	 * Assumption for WD: Direct I/O is not supported if the volume is
+	 * not RAID0, if the stripe size is not 64KB, if the block size is
+	 * not 512 and if the volume size is >2TB
+	 */
+	if (raid_device->volume_type != MPI2_RAID_VOL_TYPE_RAID0 ||
+	    le16_to_cpu(vol_pg0->BlockSize) != 512) {
+		printk(MPT2SAS_INFO_FMT "WarpDrive : Direct IO is disabled "
+		    "for the drive with handle(0x%04x): type=%d, "
+		    "s_sz=%uK, blk_size=%u\n", ioc->name,
+		    raid_device->handle, raid_device->volume_type,
+		    le32_to_cpu(vol_pg0->StripeSize)/2,
+		    le16_to_cpu(vol_pg0->BlockSize));
+		goto out_error;
+	}
+
+	capacity = (u64) le16_to_cpu(vol_pg0->BlockSize) *
+	    (le64_to_cpu(vol_pg0->MaxLBA) + 1);
+
+	if (capacity > tb_2) {
+		printk(MPT2SAS_INFO_FMT "WarpDrive : Direct IO is disabled "
+		"for the drive with handle(0x%04x) since drive sz > 2TB\n",
+		ioc->name, raid_device->handle);
+		goto out_error;
+	}
+
+	stripe_sz = le32_to_cpu(vol_pg0->StripeSize);
+	stripe_exp = 0;
+	for (i = 0; i < 32; i++) {
+		if (stripe_sz & 1)
+			break;
+		stripe_exp++;
+		stripe_sz >>= 1;
+	}
+	if (i == 32) {
+		printk(MPT2SAS_INFO_FMT "WarpDrive : Direct IO is disabled "
+		    "for the drive with handle(0x%04x) invalid stripe sz %uK\n",
+		    ioc->name, raid_device->handle,
+		    le32_to_cpu(vol_pg0->StripeSize)/2);
+		goto out_error;
+	}
+	raid_device->stripe_exponent = stripe_exp;
+	raid_device->direct_io_enabled = 1;
+
+	printk(MPT2SAS_INFO_FMT "WarpDrive : Direct IO is Enabled for the drive"
+	    " with handle(0x%04x)\n", ioc->name, raid_device->handle);
+	/*
+	 * WARPDRIVE: Though the following fields are not used for direct IO,
+	 * stored for future purpose:
+	 */
+	raid_device->max_lba = le64_to_cpu(vol_pg0->MaxLBA);
+	raid_device->stripe_sz = le32_to_cpu(vol_pg0->StripeSize);
+	raid_device->block_sz = le16_to_cpu(vol_pg0->BlockSize);
+
+
+	kfree(vol_pg0);
+	return;
+
+out_error:
+	raid_device->direct_io_enabled = 0;
+	for (count = 0; count < num_pds; count++)
+		raid_device->pd_handle[count] = 0;
+	kfree(vol_pg0);
+	return;
+}
 
 /**
  * _scsih_enable_tlr - setting TLR flags
@@ -1710,6 +1926,11 @@
 
 		_scsih_get_volume_capabilities(ioc, raid_device);
 
+		/*
+		 * WARPDRIVE: Initialize the required data for Direct IO
+		 */
+		_scsih_init_warpdrive_properties(ioc, raid_device);
+
 		/* RAID Queue Depth Support
 		 * IS volume = underlying qdepth of drive type, either
 		 *    MPT2SAS_SAS_QUEUE_DEPTH or MPT2SAS_SATA_QUEUE_DEPTH
@@ -1757,14 +1978,16 @@
 			break;
 		}
 
-		sdev_printk(KERN_INFO, sdev, "%s: "
-		    "handle(0x%04x), wwid(0x%016llx), pd_count(%d), type(%s)\n",
-		    r_level, raid_device->handle,
-		    (unsigned long long)raid_device->wwid,
-		    raid_device->num_pds, ds);
+		if (!ioc->hide_ir_msg)
+			sdev_printk(KERN_INFO, sdev, "%s: handle(0x%04x), "
+			    "wwid(0x%016llx), pd_count(%d), type(%s)\n",
+			    r_level, raid_device->handle,
+			    (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);
+		if (!ioc->is_warpdrive)
+			_scsih_set_level(sdev, raid_device);
 		return 0;
 	}
 
@@ -2133,8 +2356,7 @@
 	switch (type) {
 	case MPI2_SCSITASKMGMT_TASKTYPE_ABORT_TASK:
 		scmd_lookup = _scsih_scsi_lookup_get(ioc, smid_task);
-		if (scmd_lookup && (scmd_lookup->serial_number ==
-		    scmd->serial_number))
+		if (scmd_lookup)
 			rc = FAILED;
 		else
 			rc = SUCCESS;
@@ -2182,16 +2404,20 @@
 	struct MPT2SAS_TARGET *priv_target = starget->hostdata;
 	struct _sas_device *sas_device = NULL;
 	unsigned long flags;
+	char *device_str = NULL;
 
 	if (!priv_target)
 		return;
+	if (ioc->hide_ir_msg)
+		device_str = "WarpDrive";
+	else
+		device_str = "volume";
 
 	scsi_print_command(scmd);
 	if (priv_target->flags & MPT_TARGET_FLAGS_VOLUME) {
-		starget_printk(KERN_INFO, starget, "volume handle(0x%04x), "
-		    "volume wwid(0x%016llx)\n",
-		    priv_target->handle,
-		    (unsigned long long)priv_target->sas_address);
+		starget_printk(KERN_INFO, starget, "%s handle(0x%04x), "
+		    "%s wwid(0x%016llx)\n", device_str, priv_target->handle,
+		    device_str, (unsigned long long)priv_target->sas_address);
 	} else {
 		spin_lock_irqsave(&ioc->sas_device_lock, flags);
 		sas_device = mpt2sas_scsih_sas_device_find_by_sas_address(ioc,
@@ -3130,6 +3356,9 @@
 	a = 0;
 	b = 0;
 
+	if (ioc->is_warpdrive)
+		return;
+
 	/* Volume Resets for Deleted or Removed */
 	element = (Mpi2EventIrConfigElement_t *)&event_data->ConfigElement[0];
 	for (i = 0; i < event_data->NumElements; i++, element++) {
@@ -3273,6 +3502,7 @@
 
 	switch (prot_type) {
 	case SCSI_PROT_DIF_TYPE1:
+	case SCSI_PROT_DIF_TYPE2:
 
 		/*
 		* enable ref/guard checking
@@ -3285,13 +3515,6 @@
 		    cpu_to_be32(scsi_get_lba(scmd));
 		break;
 
-	case SCSI_PROT_DIF_TYPE2:
-
-		eedp_flags |= MPI2_SCSIIO_EEDPFLAGS_INC_PRI_REFTAG |
-		    MPI2_SCSIIO_EEDPFLAGS_CHECK_REFTAG |
-		    MPI2_SCSIIO_EEDPFLAGS_CHECK_GUARD;
-		break;
-
 	case SCSI_PROT_DIF_TYPE3:
 
 		/*
@@ -3347,6 +3570,105 @@
 }
 
 /**
+ * _scsih_scsi_direct_io_get - returns direct io flag
+ * @ioc: per adapter object
+ * @smid: system request message index
+ *
+ * Returns the smid stored scmd pointer.
+ */
+static inline u8
+_scsih_scsi_direct_io_get(struct MPT2SAS_ADAPTER *ioc, u16 smid)
+{
+	return ioc->scsi_lookup[smid - 1].direct_io;
+}
+
+/**
+ * _scsih_scsi_direct_io_set - sets direct io flag
+ * @ioc: per adapter object
+ * @smid: system request message index
+ * @direct_io: Zero or non-zero value to set in the direct_io flag
+ *
+ * Returns Nothing.
+ */
+static inline void
+_scsih_scsi_direct_io_set(struct MPT2SAS_ADAPTER *ioc, u16 smid, u8 direct_io)
+{
+	ioc->scsi_lookup[smid - 1].direct_io = direct_io;
+}
+
+
+/**
+ * _scsih_setup_direct_io - setup MPI request for WARPDRIVE Direct I/O
+ * @ioc: per adapter object
+ * @scmd: pointer to scsi command object
+ * @raid_device: pointer to raid device data structure
+ * @mpi_request: pointer to the SCSI_IO reqest message frame
+ * @smid: system request message index
+ *
+ * Returns nothing
+ */
+static void
+_scsih_setup_direct_io(struct MPT2SAS_ADAPTER *ioc, struct scsi_cmnd *scmd,
+	struct _raid_device *raid_device, Mpi2SCSIIORequest_t *mpi_request,
+	u16 smid)
+{
+	u32 v_lba, p_lba, stripe_off, stripe_unit, column, io_size;
+	u32 stripe_sz, stripe_exp;
+	u8 num_pds, *cdb_ptr, *tmp_ptr, *lba_ptr1, *lba_ptr2;
+	u8 cdb0 = scmd->cmnd[0];
+
+	/*
+	 * Try Direct I/O to RAID memeber disks
+	 */
+	if (cdb0 == READ_16 || cdb0 == READ_10 ||
+	    cdb0 == WRITE_16 || cdb0 == WRITE_10) {
+		cdb_ptr = mpi_request->CDB.CDB32;
+
+		if ((cdb0 < READ_16) || !(cdb_ptr[2] | cdb_ptr[3] | cdb_ptr[4]
+			| cdb_ptr[5])) {
+			io_size = scsi_bufflen(scmd) >> 9;
+			/* get virtual lba */
+			lba_ptr1 = lba_ptr2 = (cdb0 < READ_16) ? &cdb_ptr[2] :
+			    &cdb_ptr[6];
+			tmp_ptr = (u8 *)&v_lba + 3;
+			*tmp_ptr-- = *lba_ptr1++;
+			*tmp_ptr-- = *lba_ptr1++;
+			*tmp_ptr-- = *lba_ptr1++;
+			*tmp_ptr = *lba_ptr1;
+
+			if (((u64)v_lba + (u64)io_size - 1) <=
+			    (u32)raid_device->max_lba) {
+				stripe_sz = raid_device->stripe_sz;
+				stripe_exp = raid_device->stripe_exponent;
+				stripe_off = v_lba & (stripe_sz - 1);
+
+				/* Check whether IO falls within a stripe */
+				if ((stripe_off + io_size) <= stripe_sz) {
+					num_pds = raid_device->num_pds;
+					p_lba = v_lba >> stripe_exp;
+					stripe_unit = p_lba / num_pds;
+					column = p_lba % num_pds;
+					p_lba = (stripe_unit << stripe_exp) +
+					    stripe_off;
+					mpi_request->DevHandle =
+						cpu_to_le16(raid_device->
+						    pd_handle[column]);
+					tmp_ptr = (u8 *)&p_lba + 3;
+					*lba_ptr2++ = *tmp_ptr--;
+					*lba_ptr2++ = *tmp_ptr--;
+					*lba_ptr2++ = *tmp_ptr--;
+					*lba_ptr2 = *tmp_ptr;
+					/*
+					* WD: To indicate this I/O is directI/O
+					*/
+					_scsih_scsi_direct_io_set(ioc, smid, 1);
+				}
+			}
+		}
+	}
+}
+
+/**
  * _scsih_qcmd - main scsi request entry point
  * @scmd: pointer to scsi command object
  * @done: function pointer to be invoked on completion
@@ -3363,6 +3685,7 @@
 	struct MPT2SAS_ADAPTER *ioc = shost_priv(scmd->device->host);
 	struct MPT2SAS_DEVICE *sas_device_priv_data;
 	struct MPT2SAS_TARGET *sas_target_priv_data;
+	struct _raid_device *raid_device;
 	Mpi2SCSIIORequest_t *mpi_request;
 	u32 mpi_control;
 	u16 smid;
@@ -3424,8 +3747,10 @@
 
 	} else
 		mpi_control |= MPI2_SCSIIO_CONTROL_SIMPLEQ;
-	/* Make sure Device is not raid volume */
-	if (!_scsih_is_raid(&scmd->device->sdev_gendev) &&
+	/* Make sure Device is not raid volume.
+	 * We do not expose raid functionality to upper layer for warpdrive.
+	 */
+	if (!ioc->is_warpdrive && !_scsih_is_raid(&scmd->device->sdev_gendev) &&
 	    sas_is_tlr_enabled(scmd->device) && scmd->cmd_len != 32)
 		mpi_control |= MPI2_SCSIIO_CONTROL_TLR_ON;
 
@@ -3473,9 +3798,14 @@
 		}
 	}
 
+	raid_device = sas_target_priv_data->raid_device;
+	if (raid_device && raid_device->direct_io_enabled)
+		_scsih_setup_direct_io(ioc, scmd, raid_device, mpi_request,
+		    smid);
+
 	if (likely(mpi_request->Function == MPI2_FUNCTION_SCSI_IO_REQUEST))
 		mpt2sas_base_put_smid_scsi_io(ioc, smid,
-		    sas_device_priv_data->sas_target->handle);
+		    le16_to_cpu(mpi_request->DevHandle));
 	else
 		mpt2sas_base_put_smid_default(ioc, smid);
 	return 0;
@@ -3540,10 +3870,16 @@
 	unsigned long flags;
 	struct scsi_target *starget = scmd->device->sdev_target;
 	struct MPT2SAS_TARGET *priv_target = starget->hostdata;
+	char *device_str = NULL;
 
 	if (!priv_target)
 		return;
 
+	if (ioc->hide_ir_msg)
+		device_str = "WarpDrive";
+	else
+		device_str = "volume";
+
 	if (log_info == 0x31170000)
 		return;
 
@@ -3660,8 +3996,8 @@
 	scsi_print_command(scmd);
 
 	if (priv_target->flags & MPT_TARGET_FLAGS_VOLUME) {
-		printk(MPT2SAS_WARN_FMT "\tvolume wwid(0x%016llx)\n", ioc->name,
-		    (unsigned long long)priv_target->sas_address);
+		printk(MPT2SAS_WARN_FMT "\t%s wwid(0x%016llx)\n", ioc->name,
+		    device_str, (unsigned long long)priv_target->sas_address);
 	} else {
 		spin_lock_irqsave(&ioc->sas_device_lock, flags);
 		sas_device = mpt2sas_scsih_sas_device_find_by_sas_address(ioc,
@@ -3708,17 +4044,75 @@
 #endif
 
 /**
- * _scsih_smart_predicted_fault - illuminate Fault LED
+ * _scsih_turn_on_fault_led - illuminate Fault LED
  * @ioc: per adapter object
  * @handle: device handle
+ * Context: process
  *
  * Return nothing.
  */
 static void
-_scsih_smart_predicted_fault(struct MPT2SAS_ADAPTER *ioc, u16 handle)
+_scsih_turn_on_fault_led(struct MPT2SAS_ADAPTER *ioc, u16 handle)
 {
 	Mpi2SepReply_t mpi_reply;
 	Mpi2SepRequest_t mpi_request;
+
+	memset(&mpi_request, 0, sizeof(Mpi2SepRequest_t));
+	mpi_request.Function = MPI2_FUNCTION_SCSI_ENCLOSURE_PROCESSOR;
+	mpi_request.Action = MPI2_SEP_REQ_ACTION_WRITE_STATUS;
+	mpi_request.SlotStatus =
+	    cpu_to_le32(MPI2_SEP_REQ_SLOTSTATUS_PREDICTED_FAULT);
+	mpi_request.DevHandle = cpu_to_le16(handle);
+	mpi_request.Flags = MPI2_SEP_REQ_FLAGS_DEVHANDLE_ADDRESS;
+	if ((mpt2sas_base_scsi_enclosure_processor(ioc, &mpi_reply,
+	    &mpi_request)) != 0) {
+		printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n", ioc->name,
+		__FILE__, __LINE__, __func__);
+		return;
+	}
+
+	if (mpi_reply.IOCStatus || mpi_reply.IOCLogInfo) {
+		dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "enclosure_processor: "
+		    "ioc_status (0x%04x), loginfo(0x%08x)\n", ioc->name,
+		    le16_to_cpu(mpi_reply.IOCStatus),
+		    le32_to_cpu(mpi_reply.IOCLogInfo)));
+		return;
+	}
+}
+
+/**
+ * _scsih_send_event_to_turn_on_fault_led - fire delayed event
+ * @ioc: per adapter object
+ * @handle: device handle
+ * Context: interrupt.
+ *
+ * Return nothing.
+ */
+static void
+_scsih_send_event_to_turn_on_fault_led(struct MPT2SAS_ADAPTER *ioc, u16 handle)
+{
+	struct fw_event_work *fw_event;
+
+	fw_event = kzalloc(sizeof(struct fw_event_work), GFP_ATOMIC);
+	if (!fw_event)
+		return;
+	fw_event->event = MPT2SAS_TURN_ON_FAULT_LED;
+	fw_event->device_handle = handle;
+	fw_event->ioc = ioc;
+	_scsih_fw_event_add(ioc, fw_event);
+}
+
+/**
+ * _scsih_smart_predicted_fault - process smart errors
+ * @ioc: per adapter object
+ * @handle: device handle
+ * Context: interrupt.
+ *
+ * Return nothing.
+ */
+static void
+_scsih_smart_predicted_fault(struct MPT2SAS_ADAPTER *ioc, u16 handle)
+{
 	struct scsi_target *starget;
 	struct MPT2SAS_TARGET *sas_target_priv_data;
 	Mpi2EventNotificationReply_t *event_reply;
@@ -3745,30 +4139,8 @@
 	starget_printk(KERN_WARNING, starget, "predicted fault\n");
 	spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
 
-	if (ioc->pdev->subsystem_vendor == PCI_VENDOR_ID_IBM) {
-		memset(&mpi_request, 0, sizeof(Mpi2SepRequest_t));
-		mpi_request.Function = MPI2_FUNCTION_SCSI_ENCLOSURE_PROCESSOR;
-		mpi_request.Action = MPI2_SEP_REQ_ACTION_WRITE_STATUS;
-		mpi_request.SlotStatus =
-		    cpu_to_le32(MPI2_SEP_REQ_SLOTSTATUS_PREDICTED_FAULT);
-		mpi_request.DevHandle = cpu_to_le16(handle);
-		mpi_request.Flags = MPI2_SEP_REQ_FLAGS_DEVHANDLE_ADDRESS;
-		if ((mpt2sas_base_scsi_enclosure_processor(ioc, &mpi_reply,
-		    &mpi_request)) != 0) {
-			printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
-			    ioc->name, __FILE__, __LINE__, __func__);
-			return;
-		}
-
-		if (mpi_reply.IOCStatus || mpi_reply.IOCLogInfo) {
-			dewtprintk(ioc, printk(MPT2SAS_INFO_FMT
-			    "enclosure_processor: ioc_status (0x%04x), "
-			    "loginfo(0x%08x)\n", ioc->name,
-			    le16_to_cpu(mpi_reply.IOCStatus),
-			    le32_to_cpu(mpi_reply.IOCLogInfo)));
-			return;
-		}
-	}
+	if (ioc->pdev->subsystem_vendor == PCI_VENDOR_ID_IBM)
+		_scsih_send_event_to_turn_on_fault_led(ioc, handle);
 
 	/* insert into event log */
 	sz = offsetof(Mpi2EventNotificationReply_t, EventData) +
@@ -3840,6 +4212,20 @@
 		scmd->result = DID_NO_CONNECT << 16;
 		goto out;
 	}
+	/*
+	 * WARPDRIVE: If direct_io is set then it is directIO,
+	 * the failed direct I/O should be redirected to volume
+	 */
+	if (_scsih_scsi_direct_io_get(ioc, smid)) {
+		_scsih_scsi_direct_io_set(ioc, smid, 0);
+		memcpy(mpi_request->CDB.CDB32, scmd->cmnd, scmd->cmd_len);
+		mpi_request->DevHandle =
+		    cpu_to_le16(sas_device_priv_data->sas_target->handle);
+		mpt2sas_base_put_smid_scsi_io(ioc, smid,
+		    sas_device_priv_data->sas_target->handle);
+		return 0;
+	}
+
 
 	/* turning off TLR */
 	scsi_state = mpi_reply->SCSIState;
@@ -3848,7 +4234,10 @@
 		    le32_to_cpu(mpi_reply->ResponseInfo) & 0xFF;
 	if (!sas_device_priv_data->tlr_snoop_check) {
 		sas_device_priv_data->tlr_snoop_check++;
-	if (!_scsih_is_raid(&scmd->device->sdev_gendev) &&
+	/* Make sure Device is not raid volume.
+	 * We do not expose raid functionality to upper layer for warpdrive.
+	 */
+	if (!ioc->is_warpdrive && !_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);
@@ -4681,8 +5070,10 @@
 
 	_scsih_ublock_io_device(ioc, sas_device_backup.handle);
 
-	mpt2sas_transport_port_remove(ioc, sas_device_backup.sas_address,
-	    sas_device_backup.sas_address_parent);
+	if (!ioc->hide_drives)
+		mpt2sas_transport_port_remove(ioc,
+		    sas_device_backup.sas_address,
+		    sas_device_backup.sas_address_parent);
 
 	printk(MPT2SAS_INFO_FMT "removing handle(0x%04x), sas_addr"
 	    "(0x%016llx)\n", ioc->name, sas_device_backup.handle,
@@ -5413,6 +5804,7 @@
 	    &sas_device->volume_wwid);
 	set_bit(handle, ioc->pd_handles);
 	_scsih_reprobe_target(sas_device->starget, 1);
+
 }
 
 /**
@@ -5591,7 +5983,8 @@
 	Mpi2EventDataIrConfigChangeList_t *event_data = fw_event->event_data;
 
 #ifdef CONFIG_SCSI_MPT2SAS_LOGGING
-	if (ioc->logging_level & MPT_DEBUG_EVENT_WORK_TASK)
+	if ((ioc->logging_level & MPT_DEBUG_EVENT_WORK_TASK)
+	    && !ioc->hide_ir_msg)
 		_scsih_sas_ir_config_change_event_debug(ioc, event_data);
 
 #endif
@@ -5614,16 +6007,20 @@
 				    le16_to_cpu(element->VolDevHandle));
 			break;
 		case MPI2_EVENT_IR_CHANGE_RC_PD_CREATED:
-			_scsih_sas_pd_hide(ioc, element);
+			if (!ioc->is_warpdrive)
+				_scsih_sas_pd_hide(ioc, element);
 			break;
 		case MPI2_EVENT_IR_CHANGE_RC_PD_DELETED:
-			_scsih_sas_pd_expose(ioc, element);
+			if (!ioc->is_warpdrive)
+				_scsih_sas_pd_expose(ioc, element);
 			break;
 		case MPI2_EVENT_IR_CHANGE_RC_HIDE:
-			_scsih_sas_pd_add(ioc, element);
+			if (!ioc->is_warpdrive)
+				_scsih_sas_pd_add(ioc, element);
 			break;
 		case MPI2_EVENT_IR_CHANGE_RC_UNHIDE:
-			_scsih_sas_pd_delete(ioc, element);
+			if (!ioc->is_warpdrive)
+				_scsih_sas_pd_delete(ioc, element);
 			break;
 		}
 	}
@@ -5654,9 +6051,10 @@
 
 	handle = le16_to_cpu(event_data->VolDevHandle);
 	state = le32_to_cpu(event_data->NewValue);
-	dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: handle(0x%04x), "
-	    "old(0x%08x), new(0x%08x)\n", ioc->name, __func__,  handle,
-	    le32_to_cpu(event_data->PreviousValue), state));
+	if (!ioc->hide_ir_msg)
+		dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: handle(0x%04x), "
+		    "old(0x%08x), new(0x%08x)\n", ioc->name, __func__,  handle,
+		    le32_to_cpu(event_data->PreviousValue), state));
 
 	switch (state) {
 	case MPI2_RAID_VOL_STATE_MISSING:
@@ -5736,9 +6134,10 @@
 	handle = le16_to_cpu(event_data->PhysDiskDevHandle);
 	state = le32_to_cpu(event_data->NewValue);
 
-	dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: handle(0x%04x), "
-	    "old(0x%08x), new(0x%08x)\n", ioc->name, __func__,  handle,
-	    le32_to_cpu(event_data->PreviousValue), state));
+	if (!ioc->hide_ir_msg)
+		dewtprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: handle(0x%04x), "
+		    "old(0x%08x), new(0x%08x)\n", ioc->name, __func__,  handle,
+		    le32_to_cpu(event_data->PreviousValue), state));
 
 	switch (state) {
 	case MPI2_RAID_PD_STATE_ONLINE:
@@ -5747,7 +6146,8 @@
 	case MPI2_RAID_PD_STATE_OPTIMAL:
 	case MPI2_RAID_PD_STATE_HOT_SPARE:
 
-		set_bit(handle, ioc->pd_handles);
+		if (!ioc->is_warpdrive)
+			set_bit(handle, ioc->pd_handles);
 
 		spin_lock_irqsave(&ioc->sas_device_lock, flags);
 		sas_device = _scsih_sas_device_find_by_handle(ioc, handle);
@@ -5851,7 +6251,8 @@
 	u16 handle;
 
 #ifdef CONFIG_SCSI_MPT2SAS_LOGGING
-	if (ioc->logging_level & MPT_DEBUG_EVENT_WORK_TASK)
+	if ((ioc->logging_level & MPT_DEBUG_EVENT_WORK_TASK)
+	    && !ioc->hide_ir_msg)
 		_scsih_sas_ir_operation_status_event_debug(ioc,
 		     event_data);
 #endif
@@ -5910,7 +6311,7 @@
 _scsih_mark_responding_sas_device(struct MPT2SAS_ADAPTER *ioc, u64 sas_address,
     u16 slot, u16 handle)
 {
-	struct MPT2SAS_TARGET *sas_target_priv_data;
+	struct MPT2SAS_TARGET *sas_target_priv_data = NULL;
 	struct scsi_target *starget;
 	struct _sas_device *sas_device;
 	unsigned long flags;
@@ -5918,7 +6319,7 @@
 	spin_lock_irqsave(&ioc->sas_device_lock, flags);
 	list_for_each_entry(sas_device, &ioc->sas_device_list, list) {
 		if (sas_device->sas_address == sas_address &&
-		    sas_device->slot == slot && sas_device->starget) {
+		    sas_device->slot == slot) {
 			sas_device->responding = 1;
 			starget = sas_device->starget;
 			if (starget && starget->hostdata) {
@@ -5927,13 +6328,15 @@
 				sas_target_priv_data->deleted = 0;
 			} else
 				sas_target_priv_data = NULL;
-			starget_printk(KERN_INFO, sas_device->starget,
-			    "handle(0x%04x), sas_addr(0x%016llx), enclosure "
-			    "logical id(0x%016llx), slot(%d)\n", handle,
-			    (unsigned long long)sas_device->sas_address,
-			    (unsigned long long)
-			    sas_device->enclosure_logical_id,
-			    sas_device->slot);
+			if (starget)
+				starget_printk(KERN_INFO, starget,
+				    "handle(0x%04x), sas_addr(0x%016llx), "
+				    "enclosure logical id(0x%016llx), "
+				    "slot(%d)\n", handle,
+				    (unsigned long long)sas_device->sas_address,
+				    (unsigned long long)
+				    sas_device->enclosure_logical_id,
+				    sas_device->slot);
 			if (sas_device->handle == handle)
 				goto out;
 			printk(KERN_INFO "\thandle changed from(0x%04x)!!!\n",
@@ -6025,6 +6428,12 @@
 			starget_printk(KERN_INFO, raid_device->starget,
 			    "handle(0x%04x), wwid(0x%016llx)\n", handle,
 			    (unsigned long long)raid_device->wwid);
+			/*
+			 * WARPDRIVE: The handles of the PDs might have changed
+			 * across the host reset so re-initialize the
+			 * required data for Direct IO
+			 */
+			_scsih_init_warpdrive_properties(ioc, raid_device);
 			if (raid_device->handle == handle)
 				goto out;
 			printk(KERN_INFO "\thandle changed from(0x%04x)!!!\n",
@@ -6086,18 +6495,20 @@
 	}
 
 	/* refresh the pd_handles */
-	phys_disk_num = 0xFF;
-	memset(ioc->pd_handles, 0, ioc->pd_handles_sz);
-	while (!(mpt2sas_config_get_phys_disk_pg0(ioc, &mpi_reply,
-	    &pd_pg0, MPI2_PHYSDISK_PGAD_FORM_GET_NEXT_PHYSDISKNUM,
-	    phys_disk_num))) {
-		ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
-		    MPI2_IOCSTATUS_MASK;
-		if (ioc_status == MPI2_IOCSTATUS_CONFIG_INVALID_PAGE)
-			break;
-		phys_disk_num = pd_pg0.PhysDiskNum;
-		handle = le16_to_cpu(pd_pg0.DevHandle);
-		set_bit(handle, ioc->pd_handles);
+	if (!ioc->is_warpdrive) {
+		phys_disk_num = 0xFF;
+		memset(ioc->pd_handles, 0, ioc->pd_handles_sz);
+		while (!(mpt2sas_config_get_phys_disk_pg0(ioc, &mpi_reply,
+		    &pd_pg0, MPI2_PHYSDISK_PGAD_FORM_GET_NEXT_PHYSDISKNUM,
+		    phys_disk_num))) {
+			ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
+			    MPI2_IOCSTATUS_MASK;
+			if (ioc_status == MPI2_IOCSTATUS_CONFIG_INVALID_PAGE)
+				break;
+			phys_disk_num = pd_pg0.PhysDiskNum;
+			handle = le16_to_cpu(pd_pg0.DevHandle);
+			set_bit(handle, ioc->pd_handles);
+		}
 	}
 }
 
@@ -6243,6 +6654,50 @@
 }
 
 /**
+ * _scsih_hide_unhide_sas_devices - add/remove device to/from OS
+ * @ioc: per adapter object
+ *
+ * Return nothing.
+ */
+static void
+_scsih_hide_unhide_sas_devices(struct MPT2SAS_ADAPTER *ioc)
+{
+	struct _sas_device *sas_device, *sas_device_next;
+
+	if (!ioc->is_warpdrive || ioc->mfg_pg10_hide_flag !=
+	    MFG_PAGE10_HIDE_IF_VOL_PRESENT)
+		return;
+
+	if (ioc->hide_drives) {
+		if (_scsih_get_num_volumes(ioc))
+			return;
+		ioc->hide_drives = 0;
+		list_for_each_entry_safe(sas_device, sas_device_next,
+		    &ioc->sas_device_list, list) {
+			if (!mpt2sas_transport_port_add(ioc, sas_device->handle,
+				sas_device->sas_address_parent)) {
+				_scsih_sas_device_remove(ioc, sas_device);
+			} else if (!sas_device->starget) {
+				mpt2sas_transport_port_remove(ioc,
+				    sas_device->sas_address,
+				    sas_device->sas_address_parent);
+				_scsih_sas_device_remove(ioc, sas_device);
+			}
+		}
+	} else {
+		if (!_scsih_get_num_volumes(ioc))
+			return;
+		ioc->hide_drives = 1;
+		list_for_each_entry_safe(sas_device, sas_device_next,
+		    &ioc->sas_device_list, list) {
+			mpt2sas_transport_port_remove(ioc,
+			    sas_device->sas_address,
+			    sas_device->sas_address_parent);
+		}
+	}
+}
+
+/**
  * mpt2sas_scsih_reset_handler - reset callback handler (for scsih)
  * @ioc: per adapter object
  * @reset_phase: phase
@@ -6326,10 +6781,14 @@
 			spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock,
 			    flags);
 		_scsih_remove_unresponding_sas_devices(ioc);
+		_scsih_hide_unhide_sas_devices(ioc);
 		return;
 	}
 
 	switch (fw_event->event) {
+	case MPT2SAS_TURN_ON_FAULT_LED:
+		_scsih_turn_on_fault_led(ioc, fw_event->device_handle);
+		break;
 	case MPI2_EVENT_SAS_TOPOLOGY_CHANGE_LIST:
 		_scsih_sas_topology_change_event(ioc, fw_event);
 		break;
@@ -6425,6 +6884,53 @@
 		    (Mpi2EventDataIrVolume_t *)
 		    mpi_reply->EventData);
 		break;
+	case MPI2_EVENT_LOG_ENTRY_ADDED:
+	{
+		Mpi2EventDataLogEntryAdded_t *log_entry;
+		u32 *log_code;
+
+		if (!ioc->is_warpdrive)
+			break;
+
+		log_entry = (Mpi2EventDataLogEntryAdded_t *)
+		    mpi_reply->EventData;
+		log_code = (u32 *)log_entry->LogData;
+
+		if (le16_to_cpu(log_entry->LogEntryQualifier)
+		    != MPT2_WARPDRIVE_LOGENTRY)
+			break;
+
+		switch (le32_to_cpu(*log_code)) {
+		case MPT2_WARPDRIVE_LC_SSDT:
+			printk(MPT2SAS_WARN_FMT "WarpDrive Warning: "
+			    "IO Throttling has occurred in the WarpDrive "
+			    "subsystem. Check WarpDrive documentation for "
+			    "additional details.\n", ioc->name);
+			break;
+		case MPT2_WARPDRIVE_LC_SSDLW:
+			printk(MPT2SAS_WARN_FMT "WarpDrive Warning: "
+			    "Program/Erase Cycles for the WarpDrive subsystem "
+			    "in degraded range. Check WarpDrive documentation "
+			    "for additional details.\n", ioc->name);
+			break;
+		case MPT2_WARPDRIVE_LC_SSDLF:
+			printk(MPT2SAS_ERR_FMT "WarpDrive Fatal Error: "
+			    "There are no Program/Erase Cycles for the "
+			    "WarpDrive subsystem. The storage device will be "
+			    "in read-only mode. Check WarpDrive documentation "
+			    "for additional details.\n", ioc->name);
+			break;
+		case MPT2_WARPDRIVE_LC_BRMF:
+			printk(MPT2SAS_ERR_FMT "WarpDrive Fatal Error: "
+			    "The Backup Rail Monitor has failed on the "
+			    "WarpDrive subsystem. Check WarpDrive "
+			    "documentation for additional details.\n",
+			    ioc->name);
+			break;
+		}
+
+		break;
+	}
 	case MPI2_EVENT_SAS_DEVICE_STATUS_CHANGE:
 	case MPI2_EVENT_IR_OPERATION_STATUS:
 	case MPI2_EVENT_SAS_DISCOVERY:
@@ -6583,7 +7089,8 @@
 	mpi_request->Function = MPI2_FUNCTION_RAID_ACTION;
 	mpi_request->Action = MPI2_RAID_ACTION_SYSTEM_SHUTDOWN_INITIATED;
 
-	printk(MPT2SAS_INFO_FMT "IR shutdown (sending)\n", ioc->name);
+	if (!ioc->hide_ir_msg)
+		printk(MPT2SAS_INFO_FMT "IR shutdown (sending)\n", ioc->name);
 	init_completion(&ioc->scsih_cmds.done);
 	mpt2sas_base_put_smid_default(ioc, smid);
 	wait_for_completion_timeout(&ioc->scsih_cmds.done, 10*HZ);
@@ -6597,10 +7104,11 @@
 	if (ioc->scsih_cmds.status & MPT2_CMD_REPLY_VALID) {
 		mpi_reply = ioc->scsih_cmds.reply;
 
-		printk(MPT2SAS_INFO_FMT "IR shutdown (complete): "
-		    "ioc_status(0x%04x), loginfo(0x%08x)\n",
-		    ioc->name, le16_to_cpu(mpi_reply->IOCStatus),
-		    le32_to_cpu(mpi_reply->IOCLogInfo));
+		if (!ioc->hide_ir_msg)
+			printk(MPT2SAS_INFO_FMT "IR shutdown (complete): "
+			    "ioc_status(0x%04x), loginfo(0x%08x)\n",
+			    ioc->name, le16_to_cpu(mpi_reply->IOCStatus),
+			    le32_to_cpu(mpi_reply->IOCLogInfo));
 	}
 
  out:
@@ -6759,6 +7267,9 @@
 		spin_lock_irqsave(&ioc->sas_device_lock, flags);
 		list_move_tail(&sas_device->list, &ioc->sas_device_list);
 		spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
+
+		if (ioc->hide_drives)
+			return;
 		if (!mpt2sas_transport_port_add(ioc, sas_device->handle,
 		    sas_device->sas_address_parent)) {
 			_scsih_sas_device_remove(ioc, sas_device);
@@ -6812,6 +7323,9 @@
 		list_move_tail(&sas_device->list, &ioc->sas_device_list);
 		spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
 
+		if (ioc->hide_drives)
+			continue;
+
 		if (!mpt2sas_transport_port_add(ioc, sas_device->handle,
 		    sas_device->sas_address_parent)) {
 			_scsih_sas_device_remove(ioc, sas_device);
@@ -6882,6 +7396,11 @@
 	ioc->id = mpt_ids++;
 	sprintf(ioc->name, "%s%d", MPT2SAS_DRIVER_NAME, ioc->id);
 	ioc->pdev = pdev;
+	if (id->device == MPI2_MFGPAGE_DEVID_SSS6200) {
+		ioc->is_warpdrive = 1;
+		ioc->hide_ir_msg = 1;
+	} else
+		ioc->mfg_pg10_hide_flag = MFG_PAGE10_EXPOSE_ALL_DISKS;
 	ioc->scsi_io_cb_idx = scsi_io_cb_idx;
 	ioc->tm_cb_idx = tm_cb_idx;
 	ioc->ctl_cb_idx = ctl_cb_idx;
@@ -6947,6 +7466,20 @@
 	}
 
 	ioc->wait_for_port_enable_to_complete = 0;
+	if (ioc->is_warpdrive) {
+		if (ioc->mfg_pg10_hide_flag ==  MFG_PAGE10_EXPOSE_ALL_DISKS)
+			ioc->hide_drives = 0;
+		else if (ioc->mfg_pg10_hide_flag ==  MFG_PAGE10_HIDE_ALL_DISKS)
+			ioc->hide_drives = 1;
+		else {
+			if (_scsih_get_num_volumes(ioc))
+				ioc->hide_drives = 1;
+			else
+				ioc->hide_drives = 0;
+		}
+	} else
+		ioc->hide_drives = 0;
+
 	_scsih_probe_devices(ioc);
 	return 0;
 
diff -druN linux-2.6.39-libre/drivers/scsi/mvsas/Kconfig linux-3.0-rc7-libre/drivers/scsi/mvsas/Kconfig
--- linux-2.6.39-libre/drivers/scsi/mvsas/Kconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/scsi/mvsas/Kconfig	2011-07-11 19:51:52.000000000 -0400
@@ -3,6 +3,7 @@
 #
 # Copyright 2007 Red Hat, Inc.
 # Copyright 2008 Marvell. <kewei@marvell.com>
+# Copyright 2009-20011 Marvell. <yuxiangl@marvell.com>
 #
 # This file is licensed under GPLv2.
 #
diff -druN linux-2.6.39-libre/drivers/scsi/mvsas/Makefile linux-3.0-rc7-libre/drivers/scsi/mvsas/Makefile
--- linux-2.6.39-libre/drivers/scsi/mvsas/Makefile	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/scsi/mvsas/Makefile	2011-07-11 19:51:52.000000000 -0400
@@ -3,6 +3,7 @@
 #
 # Copyright 2007 Red Hat, Inc.
 # Copyright 2008 Marvell. <kewei@marvell.com>
+# Copyright 2009-2011 Marvell. <yuxiangl@marvell.com>
 #
 # This file is licensed under GPLv2.
 #
diff -druN linux-2.6.39-libre/drivers/scsi/mvsas/mv_64xx.c linux-3.0-rc7-libre/drivers/scsi/mvsas/mv_64xx.c
--- linux-2.6.39-libre/drivers/scsi/mvsas/mv_64xx.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/scsi/mvsas/mv_64xx.c	2011-07-11 19:51:52.000000000 -0400
@@ -3,6 +3,7 @@
  *
  * Copyright 2007 Red Hat, Inc.
  * Copyright 2008 Marvell. <kewei@marvell.com>
+ * Copyright 2009-2011 Marvell. <yuxiangl@marvell.com>
  *
  * This file is licensed under GPLv2.
  *
diff -druN linux-2.6.39-libre/drivers/scsi/mvsas/mv_64xx.h linux-3.0-rc7-libre/drivers/scsi/mvsas/mv_64xx.h
--- linux-2.6.39-libre/drivers/scsi/mvsas/mv_64xx.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/scsi/mvsas/mv_64xx.h	2011-07-11 19:51:52.000000000 -0400
@@ -3,6 +3,7 @@
  *
  * Copyright 2007 Red Hat, Inc.
  * Copyright 2008 Marvell. <kewei@marvell.com>
+ * Copyright 2009-2011 Marvell. <yuxiangl@marvell.com>
  *
  * This file is licensed under GPLv2.
  *
diff -druN linux-2.6.39-libre/drivers/scsi/mvsas/mv_94xx.c linux-3.0-rc7-libre/drivers/scsi/mvsas/mv_94xx.c
--- linux-2.6.39-libre/drivers/scsi/mvsas/mv_94xx.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/scsi/mvsas/mv_94xx.c	2011-07-11 19:51:52.000000000 -0400
@@ -3,6 +3,7 @@
  *
  * Copyright 2007 Red Hat, Inc.
  * Copyright 2008 Marvell. <kewei@marvell.com>
+ * Copyright 2009-2011 Marvell. <yuxiangl@marvell.com>
  *
  * This file is licensed under GPLv2.
  *
diff -druN linux-2.6.39-libre/drivers/scsi/mvsas/mv_94xx.h linux-3.0-rc7-libre/drivers/scsi/mvsas/mv_94xx.h
--- linux-2.6.39-libre/drivers/scsi/mvsas/mv_94xx.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/scsi/mvsas/mv_94xx.h	2011-07-11 19:51:52.000000000 -0400
@@ -3,6 +3,7 @@
  *
  * Copyright 2007 Red Hat, Inc.
  * Copyright 2008 Marvell. <kewei@marvell.com>
+ * Copyright 2009-2011 Marvell. <yuxiangl@marvell.com>
  *
  * This file is licensed under GPLv2.
  *
diff -druN linux-2.6.39-libre/drivers/scsi/mvsas/mv_chips.h linux-3.0-rc7-libre/drivers/scsi/mvsas/mv_chips.h
--- linux-2.6.39-libre/drivers/scsi/mvsas/mv_chips.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/scsi/mvsas/mv_chips.h	2011-07-11 19:51:52.000000000 -0400
@@ -3,6 +3,7 @@
  *
  * Copyright 2007 Red Hat, Inc.
  * Copyright 2008 Marvell. <kewei@marvell.com>
+ * Copyright 2009-2011 Marvell. <yuxiangl@marvell.com>
  *
  * This file is licensed under GPLv2.
  *
diff -druN linux-2.6.39-libre/drivers/scsi/mvsas/mv_defs.h linux-3.0-rc7-libre/drivers/scsi/mvsas/mv_defs.h
--- linux-2.6.39-libre/drivers/scsi/mvsas/mv_defs.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/scsi/mvsas/mv_defs.h	2011-07-11 19:51:52.000000000 -0400
@@ -3,6 +3,7 @@
  *
  * Copyright 2007 Red Hat, Inc.
  * Copyright 2008 Marvell. <kewei@marvell.com>
+ * Copyright 2009-2011 Marvell. <yuxiangl@marvell.com>
  *
  * This file is licensed under GPLv2.
  *
@@ -34,6 +35,8 @@
 	chip_6485,
 	chip_9480,
 	chip_9180,
+	chip_9445,
+	chip_9485,
 	chip_1300,
 	chip_1320
 };
diff -druN linux-2.6.39-libre/drivers/scsi/mvsas/mv_init.c linux-3.0-rc7-libre/drivers/scsi/mvsas/mv_init.c
--- linux-2.6.39-libre/drivers/scsi/mvsas/mv_init.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/scsi/mvsas/mv_init.c	2011-07-11 19:51:52.000000000 -0400
@@ -3,6 +3,7 @@
  *
  * Copyright 2007 Red Hat, Inc.
  * Copyright 2008 Marvell. <kewei@marvell.com>
+ * Copyright 2009-2011 Marvell. <yuxiangl@marvell.com>
  *
  * This file is licensed under GPLv2.
  *
@@ -25,13 +26,24 @@
 
 #include "mv_sas.h"
 
+static int lldd_max_execute_num = 1;
+module_param_named(collector, lldd_max_execute_num, int, S_IRUGO);
+MODULE_PARM_DESC(collector, "\n"
+	"\tIf greater than one, tells the SAS Layer to run in Task Collector\n"
+	"\tMode.  If 1 or 0, tells the SAS Layer to run in Direct Mode.\n"
+	"\tThe mvsas SAS LLDD supports both modes.\n"
+	"\tDefault: 1 (Direct Mode).\n");
+
 static struct scsi_transport_template *mvs_stt;
+struct kmem_cache *mvs_task_list_cache;
 static const struct mvs_chip_info mvs_chips[] = {
 	[chip_6320] =	{ 1, 2, 0x400, 17, 16,  9, &mvs_64xx_dispatch, },
 	[chip_6440] =	{ 1, 4, 0x400, 17, 16,  9, &mvs_64xx_dispatch, },
 	[chip_6485] =	{ 1, 8, 0x800, 33, 32, 10, &mvs_64xx_dispatch, },
 	[chip_9180] =	{ 2, 4, 0x800, 17, 64,  9, &mvs_94xx_dispatch, },
 	[chip_9480] =	{ 2, 4, 0x800, 17, 64,  9, &mvs_94xx_dispatch, },
+	[chip_9445] =	{ 1, 4, 0x800, 17, 64, 11, &mvs_94xx_dispatch, },
+	[chip_9485] =	{ 2, 4, 0x800, 17, 64, 11, &mvs_94xx_dispatch, },
 	[chip_1300] =	{ 1, 4, 0x400, 17, 16,  9, &mvs_64xx_dispatch, },
 	[chip_1320] =	{ 2, 4, 0x800, 17, 64,  9, &mvs_94xx_dispatch, },
 };
@@ -107,7 +119,6 @@
 
 static void mvs_free(struct mvs_info *mvi)
 {
-	int i;
 	struct mvs_wq *mwq;
 	int slot_nr;
 
@@ -119,12 +130,8 @@
 	else
 		slot_nr = MVS_SLOTS;
 
-	for (i = 0; i < mvi->tags_num; i++) {
-		struct mvs_slot_info *slot = &mvi->slot_info[i];
-		if (slot->buf)
-			dma_free_coherent(mvi->dev, MVS_SLOT_BUF_SZ,
-					  slot->buf, slot->buf_dma);
-	}
+	if (mvi->dma_pool)
+		pci_pool_destroy(mvi->dma_pool);
 
 	if (mvi->tx)
 		dma_free_coherent(mvi->dev,
@@ -213,6 +220,7 @@
 static int __devinit mvs_alloc(struct mvs_info *mvi, struct Scsi_Host *shost)
 {
 	int i = 0, slot_nr;
+	char pool_name[32];
 
 	if (mvi->flags & MVF_FLAG_SOC)
 		slot_nr = MVS_SOC_SLOTS;
@@ -272,18 +280,14 @@
 	if (!mvi->bulk_buffer)
 		goto err_out;
 #endif
-	for (i = 0; i < slot_nr; i++) {
-		struct mvs_slot_info *slot = &mvi->slot_info[i];
-
-		slot->buf = dma_alloc_coherent(mvi->dev, MVS_SLOT_BUF_SZ,
-					       &slot->buf_dma, GFP_KERNEL);
-		if (!slot->buf) {
-			printk(KERN_DEBUG"failed to allocate slot->buf.\n");
+	sprintf(pool_name, "%s%d", "mvs_dma_pool", mvi->id);
+	mvi->dma_pool = pci_pool_create(pool_name, mvi->pdev, MVS_SLOT_BUF_SZ, 16, 0);
+	if (!mvi->dma_pool) {
+			printk(KERN_DEBUG "failed to create dma pool %s.\n", pool_name);
 			goto err_out;
-		}
-		memset(slot->buf, 0, MVS_SLOT_BUF_SZ);
-		++mvi->tags_num;
 	}
+	mvi->tags_num = slot_nr;
+
 	/* Initialize tags */
 	mvs_tag_init(mvi);
 	return 0;
@@ -484,7 +488,7 @@
 
 	sha->num_phys = nr_core * chip_info->n_phy;
 
-	sha->lldd_max_execute_num = 1;
+	sha->lldd_max_execute_num = lldd_max_execute_num;
 
 	if (mvi->flags & MVF_FLAG_SOC)
 		can_queue = MVS_SOC_CAN_QUEUE;
@@ -670,6 +674,24 @@
 	{ PCI_VDEVICE(TTI, 0x2740), chip_9480 },
 	{ PCI_VDEVICE(TTI, 0x2744), chip_9480 },
 	{ PCI_VDEVICE(TTI, 0x2760), chip_9480 },
+	{
+		.vendor		= 0x1b4b,
+		.device		= 0x9445,
+		.subvendor	= PCI_ANY_ID,
+		.subdevice	= 0x9480,
+		.class		= 0,
+		.class_mask	= 0,
+		.driver_data	= chip_9445,
+	},
+	{
+		.vendor		= 0x1b4b,
+		.device		= 0x9485,
+		.subvendor	= PCI_ANY_ID,
+		.subdevice	= 0x9480,
+		.class		= 0,
+		.class_mask	= 0,
+		.driver_data	= chip_9485,
+	},
 
 	{ }	/* terminate list */
 };
@@ -690,6 +712,14 @@
 	if (!mvs_stt)
 		return -ENOMEM;
 
+	mvs_task_list_cache = kmem_cache_create("mvs_task_list", sizeof(struct mvs_task_list),
+							 0, SLAB_HWCACHE_ALIGN, NULL);
+	if (!mvs_task_list_cache) {
+		rc = -ENOMEM;
+		mv_printk("%s: mvs_task_list_cache alloc failed! \n", __func__);
+		goto err_out;
+	}
+
 	rc = pci_register_driver(&mvs_pci_driver);
 
 	if (rc)
@@ -706,6 +736,7 @@
 {
 	pci_unregister_driver(&mvs_pci_driver);
 	sas_release_transport(mvs_stt);
+	kmem_cache_destroy(mvs_task_list_cache);
 }
 
 module_init(mvs_init);
diff -druN linux-2.6.39-libre/drivers/scsi/mvsas/mv_sas.c linux-3.0-rc7-libre/drivers/scsi/mvsas/mv_sas.c
--- linux-2.6.39-libre/drivers/scsi/mvsas/mv_sas.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/scsi/mvsas/mv_sas.c	2011-07-11 19:51:52.000000000 -0400
@@ -3,6 +3,7 @@
  *
  * Copyright 2007 Red Hat, Inc.
  * Copyright 2008 Marvell. <kewei@marvell.com>
+ * Copyright 2009-2011 Marvell. <yuxiangl@marvell.com>
  *
  * This file is licensed under GPLv2.
  *
@@ -862,178 +863,286 @@
 }
 
 #define	DEV_IS_GONE(mvi_dev)	((!mvi_dev || (mvi_dev->dev_type == NO_DEVICE)))
-static int mvs_task_exec(struct sas_task *task, const int num, gfp_t gfp_flags,
-				struct completion *completion,int is_tmf,
-				struct mvs_tmf_task *tmf)
+static int mvs_task_prep(struct sas_task *task, struct mvs_info *mvi, int is_tmf,
+				struct mvs_tmf_task *tmf, int *pass)
 {
 	struct domain_device *dev = task->dev;
-	struct mvs_device *mvi_dev = (struct mvs_device *)dev->lldd_dev;
-	struct mvs_info *mvi = mvi_dev->mvi_info;
+	struct mvs_device *mvi_dev = dev->lldd_dev;
 	struct mvs_task_exec_info tei;
-	struct sas_task *t = task;
 	struct mvs_slot_info *slot;
-	u32 tag = 0xdeadbeef, rc, n_elem = 0;
-	u32 n = num, pass = 0;
-	unsigned long flags = 0,  flags_libsas = 0;
+	u32 tag = 0xdeadbeef, n_elem = 0;
+	int rc = 0;
 
 	if (!dev->port) {
-		struct task_status_struct *tsm = &t->task_status;
+		struct task_status_struct *tsm = &task->task_status;
 
 		tsm->resp = SAS_TASK_UNDELIVERED;
 		tsm->stat = SAS_PHY_DOWN;
+		/*
+		 * libsas will use dev->port, should
+		 * not call task_done for sata
+		 */
 		if (dev->dev_type != SATA_DEV)
-			t->task_done(t);
-		return 0;
+			task->task_done(task);
+		return rc;
 	}
 
-	spin_lock_irqsave(&mvi->lock, flags);
-	do {
-		dev = t->dev;
-		mvi_dev = dev->lldd_dev;
-		if (DEV_IS_GONE(mvi_dev)) {
-			if (mvi_dev)
-				mv_dprintk("device %d not ready.\n",
-					mvi_dev->device_id);
-			else
-				mv_dprintk("device %016llx not ready.\n",
-					SAS_ADDR(dev->sas_addr));
+	if (DEV_IS_GONE(mvi_dev)) {
+		if (mvi_dev)
+			mv_dprintk("device %d not ready.\n",
+				mvi_dev->device_id);
+		else
+			mv_dprintk("device %016llx not ready.\n",
+				SAS_ADDR(dev->sas_addr));
 
 			rc = SAS_PHY_DOWN;
-			goto out_done;
-		}
-
-		if (dev->port->id >= mvi->chip->n_phy)
-			tei.port = &mvi->port[dev->port->id - mvi->chip->n_phy];
-		else
-			tei.port = &mvi->port[dev->port->id];
+			return rc;
+	}
+	tei.port = dev->port->lldd_port;
+	if (tei.port && !tei.port->port_attached && !tmf) {
+		if (sas_protocol_ata(task->task_proto)) {
+			struct task_status_struct *ts = &task->task_status;
+			mv_dprintk("SATA/STP port %d does not attach"
+					"device.\n", dev->port->id);
+			ts->resp = SAS_TASK_COMPLETE;
+			ts->stat = SAS_PHY_DOWN;
 
-		if (tei.port && !tei.port->port_attached) {
-			if (sas_protocol_ata(t->task_proto)) {
-				struct task_status_struct *ts = &t->task_status;
+			task->task_done(task);
 
-				mv_dprintk("port %d does not"
-					"attached device.\n", dev->port->id);
-				ts->stat = SAS_PROTO_RESPONSE;
-				ts->stat = SAS_PHY_DOWN;
-				spin_unlock_irqrestore(dev->sata_dev.ap->lock,
-						       flags_libsas);
-				spin_unlock_irqrestore(&mvi->lock, flags);
-				t->task_done(t);
-				spin_lock_irqsave(&mvi->lock, flags);
-				spin_lock_irqsave(dev->sata_dev.ap->lock,
-						  flags_libsas);
-				if (n > 1)
-					t = list_entry(t->list.next,
-						       struct sas_task, list);
-				continue;
-			} else {
-				struct task_status_struct *ts = &t->task_status;
-				ts->resp = SAS_TASK_UNDELIVERED;
-				ts->stat = SAS_PHY_DOWN;
-				t->task_done(t);
-				if (n > 1)
-					t = list_entry(t->list.next,
-							struct sas_task, list);
-				continue;
-			}
+		} else {
+			struct task_status_struct *ts = &task->task_status;
+			mv_dprintk("SAS port %d does not attach"
+				"device.\n", dev->port->id);
+			ts->resp = SAS_TASK_UNDELIVERED;
+			ts->stat = SAS_PHY_DOWN;
+			task->task_done(task);
 		}
+		return rc;
+	}
 
-		if (!sas_protocol_ata(t->task_proto)) {
-			if (t->num_scatter) {
-				n_elem = dma_map_sg(mvi->dev,
-						    t->scatter,
-						    t->num_scatter,
-						    t->data_dir);
-				if (!n_elem) {
-					rc = -ENOMEM;
-					goto err_out;
-				}
+	if (!sas_protocol_ata(task->task_proto)) {
+		if (task->num_scatter) {
+			n_elem = dma_map_sg(mvi->dev,
+					    task->scatter,
+					    task->num_scatter,
+					    task->data_dir);
+			if (!n_elem) {
+				rc = -ENOMEM;
+				goto prep_out;
 			}
-		} else {
-			n_elem = t->num_scatter;
 		}
+	} else {
+		n_elem = task->num_scatter;
+	}
 
-		rc = mvs_tag_alloc(mvi, &tag);
-		if (rc)
-			goto err_out;
+	rc = mvs_tag_alloc(mvi, &tag);
+	if (rc)
+		goto err_out;
 
-		slot = &mvi->slot_info[tag];
+	slot = &mvi->slot_info[tag];
 
+	task->lldd_task = NULL;
+	slot->n_elem = n_elem;
+	slot->slot_tag = tag;
 
-		t->lldd_task = NULL;
-		slot->n_elem = n_elem;
-		slot->slot_tag = tag;
-		memset(slot->buf, 0, MVS_SLOT_BUF_SZ);
+	slot->buf = pci_pool_alloc(mvi->dma_pool, GFP_ATOMIC, &slot->buf_dma);
+	if (!slot->buf)
+		goto err_out_tag;
+	memset(slot->buf, 0, MVS_SLOT_BUF_SZ);
 
-		tei.task = t;
-		tei.hdr = &mvi->slot[tag];
-		tei.tag = tag;
-		tei.n_elem = n_elem;
-		switch (t->task_proto) {
-		case SAS_PROTOCOL_SMP:
-			rc = mvs_task_prep_smp(mvi, &tei);
-			break;
-		case SAS_PROTOCOL_SSP:
-			rc = mvs_task_prep_ssp(mvi, &tei, is_tmf, tmf);
-			break;
-		case SAS_PROTOCOL_SATA:
-		case SAS_PROTOCOL_STP:
-		case SAS_PROTOCOL_SATA | SAS_PROTOCOL_STP:
-			rc = mvs_task_prep_ata(mvi, &tei);
-			break;
-		default:
-			dev_printk(KERN_ERR, mvi->dev,
-				   "unknown sas_task proto: 0x%x\n",
-				   t->task_proto);
-			rc = -EINVAL;
-			break;
-		}
+	tei.task = task;
+	tei.hdr = &mvi->slot[tag];
+	tei.tag = tag;
+	tei.n_elem = n_elem;
+	switch (task->task_proto) {
+	case SAS_PROTOCOL_SMP:
+		rc = mvs_task_prep_smp(mvi, &tei);
+		break;
+	case SAS_PROTOCOL_SSP:
+		rc = mvs_task_prep_ssp(mvi, &tei, is_tmf, tmf);
+		break;
+	case SAS_PROTOCOL_SATA:
+	case SAS_PROTOCOL_STP:
+	case SAS_PROTOCOL_SATA | SAS_PROTOCOL_STP:
+		rc = mvs_task_prep_ata(mvi, &tei);
+		break;
+	default:
+		dev_printk(KERN_ERR, mvi->dev,
+			"unknown sas_task proto: 0x%x\n",
+			task->task_proto);
+		rc = -EINVAL;
+		break;
+	}
 
-		if (rc) {
-			mv_dprintk("rc is %x\n", rc);
-			goto err_out_tag;
-		}
-		slot->task = t;
-		slot->port = tei.port;
-		t->lldd_task = slot;
-		list_add_tail(&slot->entry, &tei.port->list);
-		/* TODO: select normal or high priority */
-		spin_lock(&t->task_state_lock);
-		t->task_state_flags |= SAS_TASK_AT_INITIATOR;
-		spin_unlock(&t->task_state_lock);
+	if (rc) {
+		mv_dprintk("rc is %x\n", rc);
+		goto err_out_slot_buf;
+	}
+	slot->task = task;
+	slot->port = tei.port;
+	task->lldd_task = slot;
+	list_add_tail(&slot->entry, &tei.port->list);
+	spin_lock(&task->task_state_lock);
+	task->task_state_flags |= SAS_TASK_AT_INITIATOR;
+	spin_unlock(&task->task_state_lock);
 
-		mvs_hba_memory_dump(mvi, tag, t->task_proto);
-		mvi_dev->running_req++;
-		++pass;
-		mvi->tx_prod = (mvi->tx_prod + 1) & (MVS_CHIP_SLOT_SZ - 1);
-		if (n > 1)
-			t = list_entry(t->list.next, struct sas_task, list);
-		if (likely(pass))
-			MVS_CHIP_DISP->start_delivery(mvi, (mvi->tx_prod - 1) &
-						      (MVS_CHIP_SLOT_SZ - 1));
+	mvs_hba_memory_dump(mvi, tag, task->task_proto);
+	mvi_dev->running_req++;
+	++(*pass);
+	mvi->tx_prod = (mvi->tx_prod + 1) & (MVS_CHIP_SLOT_SZ - 1);
 
-	} while (--n);
-	rc = 0;
-	goto out_done;
+	return rc;
 
+err_out_slot_buf:
+	pci_pool_free(mvi->dma_pool, slot->buf, slot->buf_dma);
 err_out_tag:
 	mvs_tag_free(mvi, tag);
 err_out:
 
-	dev_printk(KERN_ERR, mvi->dev, "mvsas exec failed[%d]!\n", rc);
-	if (!sas_protocol_ata(t->task_proto))
+	dev_printk(KERN_ERR, mvi->dev, "mvsas prep failed[%d]!\n", rc);
+	if (!sas_protocol_ata(task->task_proto))
 		if (n_elem)
-			dma_unmap_sg(mvi->dev, t->scatter, n_elem,
-				     t->data_dir);
-out_done:
+			dma_unmap_sg(mvi->dev, task->scatter, n_elem,
+				     task->data_dir);
+prep_out:
+	return rc;
+}
+
+static struct mvs_task_list *mvs_task_alloc_list(int *num, gfp_t gfp_flags)
+{
+	struct mvs_task_list *first = NULL;
+
+	for (; *num > 0; --*num) {
+		struct mvs_task_list *mvs_list = kmem_cache_zalloc(mvs_task_list_cache, gfp_flags);
+
+		if (!mvs_list)
+			break;
+
+		INIT_LIST_HEAD(&mvs_list->list);
+		if (!first)
+			first = mvs_list;
+		else
+			list_add_tail(&mvs_list->list, &first->list);
+
+	}
+
+	return first;
+}
+
+static inline void mvs_task_free_list(struct mvs_task_list *mvs_list)
+{
+	LIST_HEAD(list);
+	struct list_head *pos, *a;
+	struct mvs_task_list *mlist = NULL;
+
+	__list_add(&list, mvs_list->list.prev, &mvs_list->list);
+
+	list_for_each_safe(pos, a, &list) {
+		list_del_init(pos);
+		mlist = list_entry(pos, struct mvs_task_list, list);
+		kmem_cache_free(mvs_task_list_cache, mlist);
+	}
+}
+
+static int mvs_task_exec(struct sas_task *task, const int num, gfp_t gfp_flags,
+				struct completion *completion, int is_tmf,
+				struct mvs_tmf_task *tmf)
+{
+	struct domain_device *dev = task->dev;
+	struct mvs_info *mvi = NULL;
+	u32 rc = 0;
+	u32 pass = 0;
+	unsigned long flags = 0;
+
+	mvi = ((struct mvs_device *)task->dev->lldd_dev)->mvi_info;
+
+	if ((dev->dev_type == SATA_DEV) && (dev->sata_dev.ap != NULL))
+		spin_unlock_irq(dev->sata_dev.ap->lock);
+
+	spin_lock_irqsave(&mvi->lock, flags);
+	rc = mvs_task_prep(task, mvi, is_tmf, tmf, &pass);
+	if (rc)
+		dev_printk(KERN_ERR, mvi->dev, "mvsas exec failed[%d]!\n", rc);
+
+	if (likely(pass))
+			MVS_CHIP_DISP->start_delivery(mvi, (mvi->tx_prod - 1) &
+				(MVS_CHIP_SLOT_SZ - 1));
 	spin_unlock_irqrestore(&mvi->lock, flags);
+
+	if ((dev->dev_type == SATA_DEV) && (dev->sata_dev.ap != NULL))
+		spin_lock_irq(dev->sata_dev.ap->lock);
+
+	return rc;
+}
+
+static int mvs_collector_task_exec(struct sas_task *task, const int num, gfp_t gfp_flags,
+				struct completion *completion, int is_tmf,
+				struct mvs_tmf_task *tmf)
+{
+	struct domain_device *dev = task->dev;
+	struct mvs_prv_info *mpi = dev->port->ha->lldd_ha;
+	struct mvs_info *mvi = NULL;
+	struct sas_task *t = task;
+	struct mvs_task_list *mvs_list = NULL, *a;
+	LIST_HEAD(q);
+	int pass[2] = {0};
+	u32 rc = 0;
+	u32 n = num;
+	unsigned long flags = 0;
+
+	mvs_list = mvs_task_alloc_list(&n, gfp_flags);
+	if (n) {
+		printk(KERN_ERR "%s: mvs alloc list failed.\n", __func__);
+		rc = -ENOMEM;
+		goto free_list;
+	}
+
+	__list_add(&q, mvs_list->list.prev, &mvs_list->list);
+
+	list_for_each_entry(a, &q, list) {
+		a->task = t;
+		t = list_entry(t->list.next, struct sas_task, list);
+	}
+
+	list_for_each_entry(a, &q , list) {
+
+		t = a->task;
+		mvi = ((struct mvs_device *)t->dev->lldd_dev)->mvi_info;
+
+		spin_lock_irqsave(&mvi->lock, flags);
+		rc = mvs_task_prep(t, mvi, is_tmf, tmf, &pass[mvi->id]);
+		if (rc)
+			dev_printk(KERN_ERR, mvi->dev, "mvsas exec failed[%d]!\n", rc);
+		spin_unlock_irqrestore(&mvi->lock, flags);
+	}
+
+	if (likely(pass[0]))
+			MVS_CHIP_DISP->start_delivery(mpi->mvi[0],
+				(mpi->mvi[0]->tx_prod - 1) & (MVS_CHIP_SLOT_SZ - 1));
+
+	if (likely(pass[1]))
+			MVS_CHIP_DISP->start_delivery(mpi->mvi[1],
+				(mpi->mvi[1]->tx_prod - 1) & (MVS_CHIP_SLOT_SZ - 1));
+
+	list_del_init(&q);
+
+free_list:
+	if (mvs_list)
+		mvs_task_free_list(mvs_list);
+
 	return rc;
 }
 
 int mvs_queue_command(struct sas_task *task, const int num,
 			gfp_t gfp_flags)
 {
-	return mvs_task_exec(task, num, gfp_flags, NULL, 0, NULL);
+	struct mvs_device *mvi_dev = task->dev->lldd_dev;
+	struct sas_ha_struct *sas = mvi_dev->mvi_info->sas;
+
+	if (sas->lldd_max_execute_num < 2)
+		return mvs_task_exec(task, num, gfp_flags, NULL, 0, NULL);
+	else
+		return mvs_collector_task_exec(task, num, gfp_flags, NULL, 0, NULL);
 }
 
 static void mvs_slot_free(struct mvs_info *mvi, u32 rx_desc)
@@ -1067,6 +1176,11 @@
 		/* do nothing */
 		break;
 	}
+
+	if (slot->buf) {
+		pci_pool_free(mvi->dma_pool, slot->buf, slot->buf_dma);
+		slot->buf = NULL;
+	}
 	list_del_init(&slot->entry);
 	task->lldd_task = NULL;
 	slot->task = NULL;
@@ -1255,6 +1369,7 @@
 		spin_lock_irqsave(&mvi->lock, flags);
 	port->port_attached = 1;
 	phy->port = port;
+	sas_port->lldd_port = port;
 	if (phy->phy_type & PORT_TYPE_SAS) {
 		port->wide_port_phymap = sas_port->phy_mask;
 		mv_printk("set wide port phy map %x\n", sas_port->phy_mask);
diff -druN linux-2.6.39-libre/drivers/scsi/mvsas/mv_sas.h linux-3.0-rc7-libre/drivers/scsi/mvsas/mv_sas.h
--- linux-2.6.39-libre/drivers/scsi/mvsas/mv_sas.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/scsi/mvsas/mv_sas.h	2011-07-11 19:51:52.000000000 -0400
@@ -3,6 +3,7 @@
  *
  * Copyright 2007 Red Hat, Inc.
  * Copyright 2008 Marvell. <kewei@marvell.com>
+ * Copyright 2009-2011 Marvell. <yuxiangl@marvell.com>
  *
  * This file is licensed under GPLv2.
  *
@@ -67,6 +68,7 @@
 extern struct mvs_info *tgt_mvi;
 extern const struct mvs_dispatch mvs_64xx_dispatch;
 extern const struct mvs_dispatch mvs_94xx_dispatch;
+extern struct kmem_cache *mvs_task_list_cache;
 
 #define DEV_IS_EXPANDER(type)	\
 	((type == EDGE_DEV) || (type == FANOUT_DEV))
@@ -341,6 +343,7 @@
 	dma_addr_t bulk_buffer_dma;
 #define TRASH_BUCKET_SIZE    	0x20000
 #endif
+	void *dma_pool;
 	struct mvs_slot_info slot_info[0];
 };
 
@@ -367,6 +370,11 @@
 	int n_elem;
 };
 
+struct mvs_task_list {
+	struct sas_task *task;
+	struct list_head list;
+};
+
 
 /******************** function prototype *********************/
 void mvs_get_sas_addr(void *buf, u32 buflen);
diff -druN linux-2.6.39-libre/drivers/scsi/ncr53c8xx.c linux-3.0-rc7-libre/drivers/scsi/ncr53c8xx.c
--- linux-2.6.39-libre/drivers/scsi/ncr53c8xx.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/scsi/ncr53c8xx.c	2011-07-11 19:51:52.000000000 -0400
@@ -8147,7 +8147,7 @@
 	unsigned long flags;
 	struct scsi_cmnd *done_list;
 
-	printk("ncr53c8xx_abort: command pid %lu\n", cmd->serial_number);
+	printk("ncr53c8xx_abort\n");
 
 	NCR_LOCK_NCB(np, flags);
 
diff -druN linux-2.6.39-libre/drivers/scsi/nsp32_debug.c linux-3.0-rc7-libre/drivers/scsi/nsp32_debug.c
--- linux-2.6.39-libre/drivers/scsi/nsp32_debug.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/scsi/nsp32_debug.c	2011-07-11 19:51:52.000000000 -0400
@@ -13,7 +13,7 @@
 
 static const char * group_0_commands[] = {
 /* 00-03 */ "Test Unit Ready", "Rezero Unit", unknown, "Request Sense",
-/* 04-07 */ "Format Unit", "Read Block Limits", unknown, "Reasssign Blocks",
+/* 04-07 */ "Format Unit", "Read Block Limits", unknown, "Reassign Blocks",
 /* 08-0d */ "Read (6)", unknown, "Write (6)", "Seek (6)", unknown, unknown,
 /* 0e-12 */ unknown, "Read Reverse", "Write Filemarks", "Space", "Inquiry",  
 /* 13-16 */ unknown, "Recover Buffered Data", "Mode Select", "Reserve",
diff -druN linux-2.6.39-libre/drivers/scsi/osst.c linux-3.0-rc7-libre/drivers/scsi/osst.c
--- linux-2.6.39-libre/drivers/scsi/osst.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/scsi/osst.c	2011-07-11 19:51:52.000000000 -0400
@@ -4698,12 +4698,14 @@
 			break;
 
 			if ((SRpnt->sense[2] & 0x0f) == UNIT_ATTENTION) {
+				int j;
+
 				STp->pos_unknown = 0;
 				STp->partition = STp->new_partition = 0;
 				if (STp->can_partitions)
 					STp->nbr_partitions = 1;  /* This guess will be updated later if necessary */
-				for (i=0; i < ST_NBR_PARTITIONS; i++) {
-					STps = &(STp->ps[i]);
+				for (j = 0; j < ST_NBR_PARTITIONS; j++) {
+					STps = &(STp->ps[j]);
 					STps->rw = ST_IDLE;
 					STps->eof = ST_NOEOF;
 					STps->at_sm = 0;
diff -druN linux-2.6.39-libre/drivers/scsi/pcmcia/aha152x_stub.c linux-3.0-rc7-libre/drivers/scsi/pcmcia/aha152x_stub.c
--- linux-2.6.39-libre/drivers/scsi/pcmcia/aha152x_stub.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/scsi/pcmcia/aha152x_stub.c	2011-07-11 19:51:52.000000000 -0400
@@ -202,7 +202,7 @@
 	return 0;
 }
 
-static struct pcmcia_device_id aha152x_ids[] = {
+static const struct pcmcia_device_id aha152x_ids[] = {
 	PCMCIA_DEVICE_PROD_ID123("New Media", "SCSI", "Bus Toaster", 0xcdf7e4cc, 0x35f26476, 0xa8851d6e),
 	PCMCIA_DEVICE_PROD_ID123("NOTEWORTHY", "SCSI", "Bus Toaster", 0xad89c6e8, 0x35f26476, 0xa8851d6e),
 	PCMCIA_DEVICE_PROD_ID12("Adaptec, Inc.", "APA-1460 SCSI Host Adapter", 0x24ba9738, 0x3a3c3d20),
diff -druN linux-2.6.39-libre/drivers/scsi/pcmcia/fdomain_stub.c linux-3.0-rc7-libre/drivers/scsi/pcmcia/fdomain_stub.c
--- linux-2.6.39-libre/drivers/scsi/pcmcia/fdomain_stub.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/scsi/pcmcia/fdomain_stub.c	2011-07-11 19:51:52.000000000 -0400
@@ -178,7 +178,7 @@
 	return 0;
 }
 
-static struct pcmcia_device_id fdomain_ids[] = {
+static const struct pcmcia_device_id fdomain_ids[] = {
 	PCMCIA_DEVICE_PROD_ID12("IBM Corp.", "SCSI PCMCIA Card", 0xe3736c88, 0x859cad20),
 	PCMCIA_DEVICE_PROD_ID1("SCSI PCMCIA Adapter Card", 0x8dacb57e),
 	PCMCIA_DEVICE_PROD_ID12(" SIMPLE TECHNOLOGY Corporation", "SCSI PCMCIA Credit Card Controller", 0x182bdafe, 0xc80d106f),
diff -druN linux-2.6.39-libre/drivers/scsi/pcmcia/nsp_cs.c linux-3.0-rc7-libre/drivers/scsi/pcmcia/nsp_cs.c
--- linux-2.6.39-libre/drivers/scsi/pcmcia/nsp_cs.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/scsi/pcmcia/nsp_cs.c	2011-07-11 19:51:52.000000000 -0400
@@ -1752,7 +1752,7 @@
 /*======================================================================*
  *	module entry point
  *====================================================================*/
-static struct pcmcia_device_id nsp_cs_ids[] = {
+static const struct pcmcia_device_id nsp_cs_ids[] = {
 	PCMCIA_DEVICE_PROD_ID123("IO DATA", "CBSC16       ", "1", 0x547e66dc, 0x0d63a3fd, 0x51de003a),
 	PCMCIA_DEVICE_PROD_ID123("KME    ", "SCSI-CARD-001", "1", 0x534c02bc, 0x52008408, 0x51de003a),
 	PCMCIA_DEVICE_PROD_ID123("KME    ", "SCSI-CARD-002", "1", 0x534c02bc, 0xcb09d5b2, 0x51de003a),
diff -druN linux-2.6.39-libre/drivers/scsi/pcmcia/nsp_debug.c linux-3.0-rc7-libre/drivers/scsi/pcmcia/nsp_debug.c
--- linux-2.6.39-libre/drivers/scsi/pcmcia/nsp_debug.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/scsi/pcmcia/nsp_debug.c	2011-07-11 19:51:52.000000000 -0400
@@ -15,7 +15,7 @@
 
 static const char * group_0_commands[] = {
 /* 00-03 */ "Test Unit Ready", "Rezero Unit", unknown, "Request Sense",
-/* 04-07 */ "Format Unit", "Read Block Limits", unknown, "Reasssign Blocks",
+/* 04-07 */ "Format Unit", "Read Block Limits", unknown, "Reassign Blocks",
 /* 08-0d */ "Read (6)", unknown, "Write (6)", "Seek (6)", unknown, unknown,
 /* 0e-12 */ unknown, "Read Reverse", "Write Filemarks", "Space", "Inquiry",  
 /* 13-16 */ unknown, "Recover Buffered Data", "Mode Select", "Reserve",
diff -druN linux-2.6.39-libre/drivers/scsi/pcmcia/qlogic_stub.c linux-3.0-rc7-libre/drivers/scsi/pcmcia/qlogic_stub.c
--- linux-2.6.39-libre/drivers/scsi/pcmcia/qlogic_stub.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/scsi/pcmcia/qlogic_stub.c	2011-07-11 19:51:52.000000000 -0400
@@ -270,7 +270,7 @@
 	return 0;
 }
 
-static struct pcmcia_device_id qlogic_ids[] = {
+static const struct pcmcia_device_id qlogic_ids[] = {
 	PCMCIA_DEVICE_PROD_ID12("EIger Labs", "PCMCIA-to-SCSI Adapter", 0x88395fa7, 0x33b7a5e6),
 	PCMCIA_DEVICE_PROD_ID12("EPSON", "SCSI-2 PC Card SC200", 0xd361772f, 0x299d1751),
 	PCMCIA_DEVICE_PROD_ID12("MACNICA", "MIRACLE SCSI-II mPS110", 0x20841b68, 0xab3c3b6d),
diff -druN linux-2.6.39-libre/drivers/scsi/pcmcia/sym53c500_cs.c linux-3.0-rc7-libre/drivers/scsi/pcmcia/sym53c500_cs.c
--- linux-2.6.39-libre/drivers/scsi/pcmcia/sym53c500_cs.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/scsi/pcmcia/sym53c500_cs.c	2011-07-11 19:51:52.000000000 -0400
@@ -865,7 +865,7 @@
 MODULE_DESCRIPTION("SYM53C500 PCMCIA SCSI driver");
 MODULE_LICENSE("GPL");
 
-static struct pcmcia_device_id sym53c500_ids[] = {
+static const struct pcmcia_device_id sym53c500_ids[] = {
 	PCMCIA_DEVICE_PROD_ID12("BASICS by New Media Corporation", "SCSI Sym53C500", 0x23c78a9d, 0x0099e7f7),
 	PCMCIA_DEVICE_PROD_ID12("New Media Corporation", "SCSI Bus Toaster Sym53C500", 0x085a850b, 0x45432eb8),
 	PCMCIA_DEVICE_PROD_ID2("SCSI9000", 0x21648f44),
diff -druN linux-2.6.39-libre/drivers/scsi/pm8001/pm8001_init.c linux-3.0-rc7-libre/drivers/scsi/pm8001/pm8001_init.c
--- linux-2.6.39-libre/drivers/scsi/pm8001/pm8001_init.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/scsi/pm8001/pm8001_init.c	2011-07-11 19:51:52.000000000 -0400
@@ -160,7 +160,7 @@
 static void pm8001_tasklet(unsigned long opaque)
 {
 	struct pm8001_hba_info *pm8001_ha;
-	pm8001_ha = (struct pm8001_hba_info *)opaque;;
+	pm8001_ha = (struct pm8001_hba_info *)opaque;
 	if (unlikely(!pm8001_ha))
 		BUG_ON(1);
 	PM8001_CHIP_DISP->isr(pm8001_ha);
diff -druN linux-2.6.39-libre/drivers/scsi/pmcraid.c linux-3.0-rc7-libre/drivers/scsi/pmcraid.c
--- linux-2.6.39-libre/drivers/scsi/pmcraid.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/scsi/pmcraid.c	2011-07-11 19:51:52.000000000 -0400
@@ -4252,8 +4252,8 @@
 	char *buf
 )
 {
-	return snprintf(buf, PAGE_SIZE, "version: %s, build date: %s\n",
-			PMCRAID_DRIVER_VERSION, PMCRAID_DRIVER_DATE);
+	return snprintf(buf, PAGE_SIZE, "version: %s\n",
+			PMCRAID_DRIVER_VERSION);
 }
 
 static struct device_attribute pmcraid_driver_version_attr = {
@@ -6096,9 +6096,8 @@
 	dev_t dev;
 	int error;
 
-	pmcraid_info("%s Device Driver version: %s %s\n",
-			 PMCRAID_DRIVER_NAME,
-			 PMCRAID_DRIVER_VERSION, PMCRAID_DRIVER_DATE);
+	pmcraid_info("%s Device Driver version: %s\n",
+			 PMCRAID_DRIVER_NAME, PMCRAID_DRIVER_VERSION);
 
 	error = alloc_chrdev_region(&dev, 0,
 				    PMCRAID_MAX_ADAPTERS,
diff -druN linux-2.6.39-libre/drivers/scsi/pmcraid.h linux-3.0-rc7-libre/drivers/scsi/pmcraid.h
--- linux-2.6.39-libre/drivers/scsi/pmcraid.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/scsi/pmcraid.h	2011-07-11 19:51:52.000000000 -0400
@@ -43,7 +43,6 @@
 #define PMCRAID_DRIVER_NAME		"PMC MaxRAID"
 #define PMCRAID_DEVFILE			"pmcsas"
 #define PMCRAID_DRIVER_VERSION		"1.0.3"
-#define PMCRAID_DRIVER_DATE		__DATE__
 
 #define PMCRAID_FW_VERSION_1		0x002
 
diff -druN linux-2.6.39-libre/drivers/scsi/qla1280.c linux-3.0-rc7-libre/drivers/scsi/qla1280.c
--- linux-2.6.39-libre/drivers/scsi/qla1280.c	2011-05-19 02:17:44.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/scsi/qla1280.c	2011-07-21 06:59:44.000000000 -0400
@@ -4066,7 +4066,7 @@
 	   } */
 	printk("  tag=%d, transfersize=0x%x \n",
 	       cmd->tag, cmd->transfersize);
-	printk("  Pid=%li, SP=0x%p\n", cmd->serial_number, CMD_SP(cmd));
+	printk("  SP=0x%p\n", CMD_SP(cmd));
 	printk(" underflow size = 0x%x, direction=0x%x\n",
 	       cmd->underflow, cmd->sc_data_direction);
 }
diff -druN linux-2.6.39-libre/drivers/scsi/qla2xxx/qla_attr.c linux-3.0-rc7-libre/drivers/scsi/qla2xxx/qla_attr.c
--- linux-2.6.39-libre/drivers/scsi/qla2xxx/qla_attr.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/scsi/qla2xxx/qla_attr.c	2011-07-11 19:51:52.000000000 -0400
@@ -1,6 +1,6 @@
 /*
  * QLogic Fibre Channel HBA Driver
- * Copyright (c)  2003-2010 QLogic Corporation
+ * Copyright (c)  2003-2011 QLogic Corporation
  *
  * See LICENSE.qla2xxx for copyright and licensing details.
  */
@@ -496,8 +496,8 @@
 			offset = 0;
 		}
 
-		rval = qla2x00_read_sfp(vha, ha->sfp_data_dma, addr, offset,
-		    SFP_BLOCK_SIZE);
+		rval = qla2x00_read_sfp(vha, ha->sfp_data_dma, ha->sfp_data,
+		    addr, offset, SFP_BLOCK_SIZE, 0);
 		if (rval != QLA_SUCCESS) {
 			qla_printk(KERN_WARNING, ha,
 			    "Unable to read SFP data (%x/%x/%x).\n", rval,
@@ -628,12 +628,12 @@
 
 	memcpy(ha->edc_data, &buf[8], len);
 
-	rval = qla2x00_write_edc(vha, dev, adr, ha->edc_data_dma,
-	    ha->edc_data, len, opt);
+	rval = qla2x00_write_sfp(vha, ha->edc_data_dma, ha->edc_data,
+	    dev, adr, len, opt);
 	if (rval != QLA_SUCCESS) {
 		DEBUG2(qla_printk(KERN_INFO, ha,
 		    "Unable to write EDC (%x) %02x:%02x:%04x:%02x:%02x.\n",
-		    rval, dev, adr, opt, len, *buf));
+		    rval, dev, adr, opt, len, buf[8]));
 		return 0;
 	}
 
@@ -685,8 +685,8 @@
 			return -EINVAL;
 
 	memset(ha->edc_data, 0, len);
-	rval = qla2x00_read_edc(vha, dev, adr, ha->edc_data_dma,
-	    ha->edc_data, len, opt);
+	rval = qla2x00_read_sfp(vha, ha->edc_data_dma, ha->edc_data,
+			dev, adr, len, opt);
 	if (rval != QLA_SUCCESS) {
 		DEBUG2(qla_printk(KERN_INFO, ha,
 		    "Unable to write EDC status (%x) %02x:%02x:%04x:%02x.\n",
@@ -1568,7 +1568,7 @@
 
 	/* Now that the rport has been deleted, set the fcport state to
 	   FCS_DEVICE_DEAD */
-	atomic_set(&fcport->state, FCS_DEVICE_DEAD);
+	qla2x00_set_fcport_state(fcport, FCS_DEVICE_DEAD);
 
 	/*
 	 * Transport has effectively 'deleted' the rport, clear
@@ -1877,14 +1877,15 @@
 
 	scsi_remove_host(vha->host);
 
+	/* Allow timer to run to drain queued items, when removing vp */
+	qla24xx_deallocate_vp_id(vha);
+
 	if (vha->timer_active) {
 		qla2x00_vp_stop_timer(vha);
 		DEBUG15(printk(KERN_INFO "scsi(%ld): timer for the vport[%d]"
 		" = %p has stopped\n", vha->host_no, vha->vp_idx, vha));
 	}
 
-	qla24xx_deallocate_vp_id(vha);
-
 	/* No pending activities shall be there on the vha now */
 	DEBUG(msleep(random32()%10));  /* Just to see if something falls on
 					* the net we have placed below */
diff -druN linux-2.6.39-libre/drivers/scsi/qla2xxx/qla_bsg.c linux-3.0-rc7-libre/drivers/scsi/qla2xxx/qla_bsg.c
--- linux-2.6.39-libre/drivers/scsi/qla2xxx/qla_bsg.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/scsi/qla2xxx/qla_bsg.c	2011-07-11 19:51:52.000000000 -0400
@@ -1,6 +1,6 @@
 /*
  * QLogic Fibre Channel HBA Driver
- * Copyright (c)  2003-2010 QLogic Corporation
+ * Copyright (c)  2003-2011 QLogic Corporation
  *
  * See LICENSE.qla2xxx for copyright and licensing details.
  */
diff -druN linux-2.6.39-libre/drivers/scsi/qla2xxx/qla_bsg.h linux-3.0-rc7-libre/drivers/scsi/qla2xxx/qla_bsg.h
--- linux-2.6.39-libre/drivers/scsi/qla2xxx/qla_bsg.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/scsi/qla2xxx/qla_bsg.h	2011-07-11 19:51:52.000000000 -0400
@@ -1,6 +1,6 @@
 /*
  * QLogic Fibre Channel HBA Driver
- * Copyright (c)  2003-2010 QLogic Corporation
+ * Copyright (c)  2003-2011 QLogic Corporation
  *
  * See LICENSE.qla2xxx for copyright and licensing details.
  */
diff -druN linux-2.6.39-libre/drivers/scsi/qla2xxx/qla_dbg.c linux-3.0-rc7-libre/drivers/scsi/qla2xxx/qla_dbg.c
--- linux-2.6.39-libre/drivers/scsi/qla2xxx/qla_dbg.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/scsi/qla2xxx/qla_dbg.c	2011-07-11 19:51:52.000000000 -0400
@@ -1,6 +1,6 @@
 /*
  * QLogic Fibre Channel HBA Driver
- * Copyright (c)  2003-2010 QLogic Corporation
+ * Copyright (c)  2003-2011 QLogic Corporation
  *
  * See LICENSE.qla2xxx for copyright and licensing details.
  */
diff -druN linux-2.6.39-libre/drivers/scsi/qla2xxx/qla_dbg.h linux-3.0-rc7-libre/drivers/scsi/qla2xxx/qla_dbg.h
--- linux-2.6.39-libre/drivers/scsi/qla2xxx/qla_dbg.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/scsi/qla2xxx/qla_dbg.h	2011-07-11 19:51:52.000000000 -0400
@@ -1,6 +1,6 @@
 /*
  * QLogic Fibre Channel HBA Driver
- * Copyright (c)  2003-2010 QLogic Corporation
+ * Copyright (c)  2003-2011 QLogic Corporation
  *
  * See LICENSE.qla2xxx for copyright and licensing details.
  */
diff -druN linux-2.6.39-libre/drivers/scsi/qla2xxx/qla_def.h linux-3.0-rc7-libre/drivers/scsi/qla2xxx/qla_def.h
--- linux-2.6.39-libre/drivers/scsi/qla2xxx/qla_def.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/scsi/qla2xxx/qla_def.h	2011-07-11 19:51:52.000000000 -0400
@@ -1,6 +1,6 @@
 /*
  * QLogic Fibre Channel HBA Driver
- * Copyright (c)  2003-2010 QLogic Corporation
+ * Copyright (c)  2003-2011 QLogic Corporation
  *
  * See LICENSE.qla2xxx for copyright and licensing details.
  */
@@ -1717,6 +1717,14 @@
 #define FCS_DEVICE_LOST		3
 #define FCS_ONLINE		4
 
+static const char * const port_state_str[] = {
+	"Unknown",
+	"UNCONFIGURED",
+	"DEAD",
+	"LOST",
+	"ONLINE"
+};
+
 /*
  * FC port flags.
  */
diff -druN linux-2.6.39-libre/drivers/scsi/qla2xxx/qla_dfs.c linux-3.0-rc7-libre/drivers/scsi/qla2xxx/qla_dfs.c
--- linux-2.6.39-libre/drivers/scsi/qla2xxx/qla_dfs.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/scsi/qla2xxx/qla_dfs.c	2011-07-11 19:51:52.000000000 -0400
@@ -1,6 +1,6 @@
 /*
  * QLogic Fibre Channel HBA Driver
- * Copyright (c)  2003-2010 QLogic Corporation
+ * Copyright (c)  2003-2011 QLogic Corporation
  *
  * See LICENSE.qla2xxx for copyright and licensing details.
  */
diff -druN linux-2.6.39-libre/drivers/scsi/qla2xxx/qla_fw.h linux-3.0-rc7-libre/drivers/scsi/qla2xxx/qla_fw.h
--- linux-2.6.39-libre/drivers/scsi/qla2xxx/qla_fw.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/scsi/qla2xxx/qla_fw.h	2011-07-11 19:51:52.000000000 -0400
@@ -1,6 +1,6 @@
 /*
  * QLogic Fibre Channel HBA Driver
- * Copyright (c)  2003-2010 QLogic Corporation
+ * Copyright (c)  2003-2011 QLogic Corporation
  *
  * See LICENSE.qla2xxx for copyright and licensing details.
  */
@@ -416,8 +416,7 @@
 	uint8_t vp_index;
 
 	uint32_t fcp_data_dseg_address[2];	/* Data segment address. */
-	uint16_t fcp_data_dseg_len;		/* Data segment length. */
-	uint16_t reserved_1;			/* MUST be set to 0. */
+	uint32_t fcp_data_dseg_len;		/* Data segment length. */
 };
 
 #define COMMAND_TYPE_7	0x18		/* Command Type 7 entry */
diff -druN linux-2.6.39-libre/drivers/scsi/qla2xxx/qla_gbl.h linux-3.0-rc7-libre/drivers/scsi/qla2xxx/qla_gbl.h
--- linux-2.6.39-libre/drivers/scsi/qla2xxx/qla_gbl.h	2011-05-19 02:17:54.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/scsi/qla2xxx/qla_gbl.h	2011-07-21 06:59:51.000000000 -0400
@@ -1,6 +1,6 @@
 /*
  * QLogic Fibre Channel HBA Driver
- * Copyright (c)  2003-2010 QLogic Corporation
+ * Copyright (c)  2003-2011 QLogic Corporation
  *
  * See LICENSE.qla2xxx for copyright and licensing details.
  */
@@ -39,6 +39,8 @@
 extern int qla2x00_perform_loop_resync(scsi_qla_host_t *);
 extern int qla2x00_loop_resync(scsi_qla_host_t *);
 
+extern int qla2x00_find_new_loop_id(scsi_qla_host_t *, fc_port_t *);
+
 extern int qla2x00_fabric_login(scsi_qla_host_t *, fc_port_t *, uint16_t *);
 extern int qla2x00_local_device_login(scsi_qla_host_t *, fc_port_t *);
 
@@ -100,6 +102,8 @@
 extern int ql2xenabledif;
 extern int ql2xenablehba_err_chk;
 extern int ql2xtargetreset;
+extern int ql2xdontresethba;
+extern unsigned int ql2xmaxlun;
 
 extern int qla2x00_loop_reset(scsi_qla_host_t *);
 extern void qla2x00_abort_all_cmds(scsi_qla_host_t *, int);
@@ -319,15 +323,12 @@
 qla2x00_disable_fce_trace(scsi_qla_host_t *, uint64_t *, uint64_t *);
 
 extern int
-qla2x00_read_sfp(scsi_qla_host_t *, dma_addr_t, uint16_t, uint16_t, uint16_t);
-
-extern int
-qla2x00_read_edc(scsi_qla_host_t *, uint16_t, uint16_t, dma_addr_t,
-    uint8_t *, uint16_t, uint16_t);
+qla2x00_read_sfp(scsi_qla_host_t *, dma_addr_t, uint8_t *,
+	uint16_t, uint16_t, uint16_t, uint16_t);
 
 extern int
-qla2x00_write_edc(scsi_qla_host_t *, uint16_t, uint16_t, dma_addr_t,
-    uint8_t *, uint16_t, uint16_t);
+qla2x00_write_sfp(scsi_qla_host_t *, dma_addr_t, uint8_t *,
+	uint16_t, uint16_t, uint16_t, uint16_t);
 
 extern int
 qla2x00_set_idma_speed(scsi_qla_host_t *, uint16_t, uint16_t, uint16_t *);
@@ -549,7 +550,6 @@
 extern int qla82xx_rd_32(struct qla_hw_data *, ulong);
 extern int qla82xx_rdmem(struct qla_hw_data *, u64, void *, int);
 extern int qla82xx_wrmem(struct qla_hw_data *, u64, void *, int);
-extern void qla82xx_rom_unlock(struct qla_hw_data *);
 
 /* ISP 8021 IDC */
 extern void qla82xx_clear_drv_active(struct qla_hw_data *);
diff -druN linux-2.6.39-libre/drivers/scsi/qla2xxx/qla_gs.c linux-3.0-rc7-libre/drivers/scsi/qla2xxx/qla_gs.c
--- linux-2.6.39-libre/drivers/scsi/qla2xxx/qla_gs.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/scsi/qla2xxx/qla_gs.c	2011-07-11 19:51:52.000000000 -0400
@@ -1,6 +1,6 @@
 /*
  * QLogic Fibre Channel HBA Driver
- * Copyright (c)  2003-2010 QLogic Corporation
+ * Copyright (c)  2003-2011 QLogic Corporation
  *
  * See LICENSE.qla2xxx for copyright and licensing details.
  */
diff -druN linux-2.6.39-libre/drivers/scsi/qla2xxx/qla_init.c linux-3.0-rc7-libre/drivers/scsi/qla2xxx/qla_init.c
--- linux-2.6.39-libre/drivers/scsi/qla2xxx/qla_init.c	2011-05-19 02:17:54.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/scsi/qla2xxx/qla_init.c	2011-07-21 06:59:51.000000000 -0400
@@ -1,6 +1,6 @@
 /*
  * QLogic Fibre Channel HBA Driver
- * Copyright (c)  2003-2010 QLogic Corporation
+ * Copyright (c)  2003-2011 QLogic Corporation
  *
  * See LICENSE.qla2xxx for copyright and licensing details.
  */
@@ -35,8 +35,6 @@
 
 static int qla2x00_restart_isp(scsi_qla_host_t *);
 
-static int qla2x00_find_new_loop_id(scsi_qla_host_t *, fc_port_t *);
-
 static struct qla_chip_state_84xx *qla84xx_get_chip(struct scsi_qla_host *);
 static int qla84xx_init_chip(scsi_qla_host_t *);
 static int qla25xx_init_queues(struct qla_hw_data *);
@@ -385,8 +383,18 @@
 
 	switch (data[0]) {
 	case MBS_COMMAND_COMPLETE:
+		/*
+		 * Driver must validate login state - If PRLI not complete,
+		 * force a relogin attempt via implicit LOGO, PLOGI, and PRLI
+		 * requests.
+		 */
+		rval = qla2x00_get_port_database(vha, fcport, 0);
+		if (rval != QLA_SUCCESS) {
+			qla2x00_post_async_logout_work(vha, fcport, NULL);
+			qla2x00_post_async_login_work(vha, fcport, NULL);
+			break;
+		}
 		if (fcport->flags & FCF_FCP2_DEVICE) {
-			fcport->flags |= FCF_ASYNC_SENT;
 			qla2x00_post_async_adisc_work(vha, fcport, data);
 			break;
 		}
@@ -397,7 +405,7 @@
 		if (data[1] & QLA_LOGIO_LOGIN_RETRIED)
 			set_bit(RELOGIN_NEEDED, &vha->dpc_flags);
 		else
-			qla2x00_mark_device_lost(vha, fcport, 1, 1);
+			qla2x00_mark_device_lost(vha, fcport, 1, 0);
 		break;
 	case MBS_PORT_ID_USED:
 		fcport->loop_id = data[1];
@@ -409,7 +417,7 @@
 		rval = qla2x00_find_new_loop_id(vha, fcport);
 		if (rval != QLA_SUCCESS) {
 			fcport->flags &= ~FCF_ASYNC_SENT;
-			qla2x00_mark_device_lost(vha, fcport, 1, 1);
+			qla2x00_mark_device_lost(vha, fcport, 1, 0);
 			break;
 		}
 		qla2x00_post_async_login_work(vha, fcport, NULL);
@@ -441,7 +449,7 @@
 	if (data[1] & QLA_LOGIO_LOGIN_RETRIED)
 		set_bit(RELOGIN_NEEDED, &vha->dpc_flags);
 	else
-		qla2x00_mark_device_lost(vha, fcport, 1, 1);
+		qla2x00_mark_device_lost(vha, fcport, 1, 0);
 
 	return;
 }
@@ -2536,7 +2544,7 @@
 	fcport->vp_idx = vha->vp_idx;
 	fcport->port_type = FCT_UNKNOWN;
 	fcport->loop_id = FC_NO_LOOP_ID;
-	atomic_set(&fcport->state, FCS_UNCONFIGURED);
+	qla2x00_set_fcport_state(fcport, FCS_UNCONFIGURED);
 	fcport->supported_classes = FC_COS_UNSPECIFIED;
 
 	return fcport;
@@ -2722,7 +2730,7 @@
 			    "loop_id=0x%04x\n",
 			    vha->host_no, fcport->loop_id));
 
-			atomic_set(&fcport->state, FCS_DEVICE_LOST);
+			qla2x00_set_fcport_state(fcport, FCS_DEVICE_LOST);
 		}
 	}
 
@@ -2934,7 +2942,7 @@
 	qla2x00_iidma_fcport(vha, fcport);
 	qla24xx_update_fcport_fcp_prio(vha, fcport);
 	qla2x00_reg_remote_port(vha, fcport);
-	atomic_set(&fcport->state, FCS_ONLINE);
+	qla2x00_set_fcport_state(fcport, FCS_ONLINE);
 }
 
 /*
@@ -3391,7 +3399,7 @@
  * Context:
  *	Kernel context.
  */
-static int
+int
 qla2x00_find_new_loop_id(scsi_qla_host_t *vha, fc_port_t *dev)
 {
 	int	rval;
@@ -5202,7 +5210,7 @@
 	}
 
 	/* Reset Initialization control block */
-	memset(icb, 0, sizeof(struct init_cb_81xx));
+	memset(icb, 0, ha->init_cb_size);
 
 	/* Copy 1st segment. */
 	dptr1 = (uint8_t *)icb;
@@ -5427,6 +5435,13 @@
 		ha->isp_abort_cnt = 0;
 		clear_bit(ISP_ABORT_RETRY, &vha->dpc_flags);
 
+		/* Update the firmware version */
+		qla2x00_get_fw_version(vha, &ha->fw_major_version,
+		    &ha->fw_minor_version, &ha->fw_subminor_version,
+		    &ha->fw_attributes, &ha->fw_memory_size,
+		    ha->mpi_version, &ha->mpi_capabilities,
+		    ha->phy_version);
+
 		if (ha->fce) {
 			ha->flags.fce_enabled = 1;
 			memset(ha->fce, 0,
@@ -5508,26 +5523,26 @@
  *
  * Return:
  *	non-zero (if found)
- * 	0 (if not found)
+ *	-1 (if not found)
  *
  * Context:
  * 	Kernel context
  */
-uint8_t
+static int
 qla24xx_get_fcp_prio(scsi_qla_host_t *vha, fc_port_t *fcport)
 {
 	int i, entries;
 	uint8_t pid_match, wwn_match;
-	uint8_t priority;
+	int priority;
 	uint32_t pid1, pid2;
 	uint64_t wwn1, wwn2;
 	struct qla_fcp_prio_entry *pri_entry;
 	struct qla_hw_data *ha = vha->hw;
 
 	if (!ha->fcp_prio_cfg || !ha->flags.fcp_prio_enabled)
-		return 0;
+		return -1;
 
-	priority = 0;
+	priority = -1;
 	entries = ha->fcp_prio_cfg->num_entries;
 	pri_entry = &ha->fcp_prio_cfg->entry[0];
 
@@ -5610,7 +5625,7 @@
 qla24xx_update_fcport_fcp_prio(scsi_qla_host_t *vha, fc_port_t *fcport)
 {
 	int ret;
-	uint8_t priority;
+	int priority;
 	uint16_t mb[5];
 
 	if (fcport->port_type != FCT_TARGET ||
@@ -5618,6 +5633,9 @@
 		return QLA_FUNCTION_FAILED;
 
 	priority = qla24xx_get_fcp_prio(vha, fcport);
+	if (priority < 0)
+		return QLA_FUNCTION_FAILED;
+
 	ret = qla24xx_set_fcp_prio(vha, fcport->loop_id, priority, mb);
 	if (ret == QLA_SUCCESS)
 		fcport->fcp_prio = priority;
diff -druN linux-2.6.39-libre/drivers/scsi/qla2xxx/qla_inline.h linux-3.0-rc7-libre/drivers/scsi/qla2xxx/qla_inline.h
--- linux-2.6.39-libre/drivers/scsi/qla2xxx/qla_inline.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/scsi/qla2xxx/qla_inline.h	2011-07-11 19:51:52.000000000 -0400
@@ -1,6 +1,6 @@
 /*
  * QLogic Fibre Channel HBA Driver
- * Copyright (c)  2003-2010 QLogic Corporation
+ * Copyright (c)  2003-2011 QLogic Corporation
  *
  * See LICENSE.qla2xxx for copyright and licensing details.
  */
@@ -83,3 +83,22 @@
 	}
 	INIT_LIST_HEAD(&((struct crc_context *)sp->ctx)->dsd_list);
 }
+
+static inline void
+qla2x00_set_fcport_state(fc_port_t *fcport, int state)
+{
+	int old_state;
+
+	old_state = atomic_read(&fcport->state);
+	atomic_set(&fcport->state, state);
+
+	/* Don't print state transitions during initial allocation of fcport */
+	if (old_state && old_state != state) {
+		DEBUG(qla_printk(KERN_WARNING, fcport->vha->hw,
+		    "scsi(%ld): FCPort state transitioned from %s to %s - "
+		    "portid=%02x%02x%02x.\n", fcport->vha->host_no,
+		    port_state_str[old_state], port_state_str[state],
+		    fcport->d_id.b.domain, fcport->d_id.b.area,
+		    fcport->d_id.b.al_pa));
+	}
+}
diff -druN linux-2.6.39-libre/drivers/scsi/qla2xxx/qla_iocb.c linux-3.0-rc7-libre/drivers/scsi/qla2xxx/qla_iocb.c
--- linux-2.6.39-libre/drivers/scsi/qla2xxx/qla_iocb.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/scsi/qla2xxx/qla_iocb.c	2011-07-11 19:51:52.000000000 -0400
@@ -1,6 +1,6 @@
 /*
  * QLogic Fibre Channel HBA Driver
- * Copyright (c)  2003-2010 QLogic Corporation
+ * Copyright (c)  2003-2011 QLogic Corporation
  *
  * See LICENSE.qla2xxx for copyright and licensing details.
  */
diff -druN linux-2.6.39-libre/drivers/scsi/qla2xxx/qla_isr.c linux-3.0-rc7-libre/drivers/scsi/qla2xxx/qla_isr.c
--- linux-2.6.39-libre/drivers/scsi/qla2xxx/qla_isr.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/scsi/qla2xxx/qla_isr.c	2011-07-11 19:51:52.000000000 -0400
@@ -1,6 +1,6 @@
 /*
  * QLogic Fibre Channel HBA Driver
- * Copyright (c)  2003-2010 QLogic Corporation
+ * Copyright (c)  2003-2011 QLogic Corporation
  *
  * See LICENSE.qla2xxx for copyright and licensing details.
  */
@@ -843,7 +843,10 @@
 		qla_printk(KERN_WARNING, ha,
 		    "Invalid SCSI completion handle %d.\n", index);
 
-		set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
+		if (IS_QLA82XX(ha))
+			set_bit(FCOE_CTX_RESET_NEEDED, &vha->dpc_flags);
+		else
+			set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
 		return;
 	}
 
@@ -861,7 +864,10 @@
 		qla_printk(KERN_WARNING, ha,
 		    "Invalid ISP SCSI completion handle\n");
 
-		set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
+		if (IS_QLA82XX(ha))
+			set_bit(FCOE_CTX_RESET_NEEDED, &vha->dpc_flags);
+		else
+			set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
 	}
 }
 
@@ -878,7 +884,10 @@
 	if (index >= MAX_OUTSTANDING_COMMANDS) {
 		qla_printk(KERN_WARNING, ha,
 		    "%s: Invalid completion handle (%x).\n", func, index);
-		set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
+		if (IS_QLA82XX(ha))
+			set_bit(FCOE_CTX_RESET_NEEDED, &vha->dpc_flags);
+		else
+			set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
 		goto done;
 	}
 	sp = req->outstanding_cmds[index];
@@ -1051,7 +1060,7 @@
 		}
 		DEBUG2(qla2x00_dump_buffer((uint8_t *)pkt, sizeof(*pkt)));
 	} else {
-		bsg_job->reply->result =  DID_OK << 16;;
+		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;
@@ -1146,7 +1155,7 @@
 		DEBUG2(qla2x00_dump_buffer((uint8_t *)pkt, sizeof(*pkt)));
 	}
 	else {
-		bsg_job->reply->result =  DID_OK << 16;;
+		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;
 	}
@@ -1564,7 +1573,10 @@
 		    "scsi(%ld): Invalid status handle (0x%x).\n", vha->host_no,
 		    sts->handle);
 
-		set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
+		if (IS_QLA82XX(ha))
+			set_bit(FCOE_CTX_RESET_NEEDED, &vha->dpc_flags);
+		else
+			set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
 		qla2xxx_wake_dpc(vha);
 		return;
 	}
@@ -1794,12 +1806,13 @@
 	if (logit)
 		DEBUG2(qla_printk(KERN_INFO, ha,
 		    "scsi(%ld:%d:%d) FCP command status: 0x%x-0x%x (0x%x) "
-		    "oxid=0x%x cdb=%02x%02x%02x len=0x%x "
+		    "portid=%02x%02x%02x oxid=0x%x cdb=%02x%02x%02x len=0x%x "
 		    "rsp_info=0x%x resid=0x%x fw_resid=0x%x\n", vha->host_no,
 		    cp->device->id, cp->device->lun, comp_status, scsi_status,
-		    cp->result, ox_id, cp->cmnd[0],
-		    cp->cmnd[1], cp->cmnd[2], scsi_bufflen(cp), rsp_info_len,
-		    resid_len, fw_resid_len));
+		    cp->result, fcport->d_id.b.domain, fcport->d_id.b.area,
+		    fcport->d_id.b.al_pa, ox_id, cp->cmnd[0], cp->cmnd[1],
+		    cp->cmnd[2], scsi_bufflen(cp), rsp_info_len, resid_len,
+		    fw_resid_len));
 
 	if (rsp->status_srb == NULL)
 		qla2x00_sp_compl(ha, sp);
@@ -1908,13 +1921,17 @@
 		qla2x00_sp_compl(ha, sp);
 
 	} else if (pkt->entry_type == COMMAND_A64_TYPE || pkt->entry_type ==
-	    COMMAND_TYPE || pkt->entry_type == COMMAND_TYPE_7) {
+		COMMAND_TYPE || pkt->entry_type == COMMAND_TYPE_7
+		|| pkt->entry_type == COMMAND_TYPE_6) {
 		DEBUG2(printk("scsi(%ld): Error entry - invalid handle\n",
-		    vha->host_no));
+			vha->host_no));
 		qla_printk(KERN_WARNING, ha,
-		    "Error entry - invalid handle\n");
+			"Error entry - invalid handle\n");
 
-		set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
+		if (IS_QLA82XX(ha))
+			set_bit(FCOE_CTX_RESET_NEEDED, &vha->dpc_flags);
+		else
+			set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
 		qla2xxx_wake_dpc(vha);
 	}
 }
diff -druN linux-2.6.39-libre/drivers/scsi/qla2xxx/qla_mbx.c linux-3.0-rc7-libre/drivers/scsi/qla2xxx/qla_mbx.c
--- linux-2.6.39-libre/drivers/scsi/qla2xxx/qla_mbx.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/scsi/qla2xxx/qla_mbx.c	2011-07-11 19:51:52.000000000 -0400
@@ -1,6 +1,6 @@
 /*
  * QLogic Fibre Channel HBA Driver
- * Copyright (c)  2003-2010 QLogic Corporation
+ * Copyright (c)  2003-2011 QLogic Corporation
  *
  * See LICENSE.qla2xxx for copyright and licensing details.
  */
@@ -1261,11 +1261,12 @@
 		/* Check for logged in state. */
 		if (pd24->current_login_state != PDS_PRLI_COMPLETE &&
 		    pd24->last_login_state != PDS_PRLI_COMPLETE) {
-			DEBUG2(printk("%s(%ld): Unable to verify "
-			    "login-state (%x/%x) for loop_id %x\n",
-			    __func__, vha->host_no,
-			    pd24->current_login_state,
-			    pd24->last_login_state, fcport->loop_id));
+			DEBUG2(qla_printk(KERN_WARNING, ha,
+			   "scsi(%ld): Unable to verify login-state (%x/%x) "
+			   " - portid=%02x%02x%02x.\n", vha->host_no,
+			   pd24->current_login_state, pd24->last_login_state,
+			   fcport->d_id.b.domain, fcport->d_id.b.area,
+			   fcport->d_id.b.al_pa));
 			rval = QLA_FUNCTION_FAILED;
 			goto gpd_error_out;
 		}
@@ -1289,6 +1290,12 @@
 		/* Check for logged in state. */
 		if (pd->master_state != PD_STATE_PORT_LOGGED_IN &&
 		    pd->slave_state != PD_STATE_PORT_LOGGED_IN) {
+			DEBUG2(qla_printk(KERN_WARNING, ha,
+			   "scsi(%ld): Unable to verify login-state (%x/%x) "
+			   " - portid=%02x%02x%02x.\n", vha->host_no,
+			   pd->master_state, pd->slave_state,
+			   fcport->d_id.b.domain, fcport->d_id.b.area,
+			   fcport->d_id.b.al_pa));
 			rval = QLA_FUNCTION_FAILED;
 			goto gpd_error_out;
 		}
@@ -1883,7 +1890,8 @@
 	lg->handle = MAKE_HANDLE(req->id, lg->handle);
 	lg->nport_handle = cpu_to_le16(loop_id);
 	lg->control_flags =
-	    __constant_cpu_to_le16(LCF_COMMAND_LOGO|LCF_IMPL_LOGO);
+	    __constant_cpu_to_le16(LCF_COMMAND_LOGO|LCF_IMPL_LOGO|
+		LCF_FREE_NPORT);
 	lg->port_id[0] = al_pa;
 	lg->port_id[1] = area;
 	lg->port_id[2] = domain;
@@ -2362,7 +2370,7 @@
 	abt->entry_count = 1;
 	abt->handle = MAKE_HANDLE(req->id, abt->handle);
 	abt->nport_handle = cpu_to_le16(fcport->loop_id);
-	abt->handle_to_abort = handle;
+	abt->handle_to_abort = MAKE_HANDLE(req->id, handle);
 	abt->port_id[0] = fcport->d_id.b.al_pa;
 	abt->port_id[1] = fcport->d_id.b.area;
 	abt->port_id[2] = fcport->d_id.b.domain;
@@ -2779,44 +2787,6 @@
 }
 
 int
-qla2x00_read_sfp(scsi_qla_host_t *vha, dma_addr_t sfp_dma, uint16_t addr,
-    uint16_t off, uint16_t count)
-{
-	int rval;
-	mbx_cmd_t mc;
-	mbx_cmd_t *mcp = &mc;
-
-	if (!IS_FWI2_CAPABLE(vha->hw))
-		return QLA_FUNCTION_FAILED;
-
-	DEBUG11(printk("%s(%ld): entered.\n", __func__, vha->host_no));
-
-	mcp->mb[0] = MBC_READ_SFP;
-	mcp->mb[1] = addr;
-	mcp->mb[2] = MSW(sfp_dma);
-	mcp->mb[3] = LSW(sfp_dma);
-	mcp->mb[6] = MSW(MSD(sfp_dma));
-	mcp->mb[7] = LSW(MSD(sfp_dma));
-	mcp->mb[8] = count;
-	mcp->mb[9] = off;
-	mcp->mb[10] = 0;
-	mcp->out_mb = MBX_10|MBX_9|MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
-	mcp->in_mb = MBX_0;
-	mcp->tov = MBX_TOV_SECONDS;
-	mcp->flags = 0;
-	rval = qla2x00_mailbox_command(vha, mcp);
-
-	if (rval != QLA_SUCCESS) {
-		DEBUG2_3_11(printk("%s(%ld): failed=%x (%x).\n", __func__,
-		    vha->host_no, rval, mcp->mb[0]));
-	} else {
-		DEBUG11(printk("%s(%ld): done.\n", __func__, vha->host_no));
-	}
-
-	return rval;
-}
-
-int
 qla2x00_get_idma_speed(scsi_qla_host_t *vha, uint16_t loop_id,
 	uint16_t *port_speed, uint16_t *mb)
 {
@@ -3581,15 +3551,22 @@
 }
 
 int
-qla2x00_read_edc(scsi_qla_host_t *vha, uint16_t dev, uint16_t adr,
-    dma_addr_t sfp_dma, uint8_t *sfp, uint16_t len, uint16_t opt)
+qla2x00_read_sfp(scsi_qla_host_t *vha, dma_addr_t sfp_dma, uint8_t *sfp,
+	uint16_t dev, uint16_t off, uint16_t len, uint16_t opt)
 {
 	int rval;
 	mbx_cmd_t mc;
 	mbx_cmd_t *mcp = &mc;
+	struct qla_hw_data *ha = vha->hw;
+
+	if (!IS_FWI2_CAPABLE(ha))
+		return QLA_FUNCTION_FAILED;
 
 	DEBUG11(printk("%s(%ld): entered.\n", __func__, vha->host_no));
 
+	if (len == 1)
+		opt |= BIT_0;
+
 	mcp->mb[0] = MBC_READ_SFP;
 	mcp->mb[1] = dev;
 	mcp->mb[2] = MSW(sfp_dma);
@@ -3597,17 +3574,16 @@
 	mcp->mb[6] = MSW(MSD(sfp_dma));
 	mcp->mb[7] = LSW(MSD(sfp_dma));
 	mcp->mb[8] = len;
-	mcp->mb[9] = adr;
+	mcp->mb[9] = off;
 	mcp->mb[10] = opt;
 	mcp->out_mb = MBX_10|MBX_9|MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
-	mcp->in_mb = MBX_0;
+	mcp->in_mb = MBX_1|MBX_0;
 	mcp->tov = MBX_TOV_SECONDS;
 	mcp->flags = 0;
 	rval = qla2x00_mailbox_command(vha, mcp);
 
 	if (opt & BIT_0)
-		if (sfp)
-			*sfp = mcp->mb[8];
+		*sfp = mcp->mb[1];
 
 	if (rval != QLA_SUCCESS) {
 		DEBUG2_3_11(printk("%s(%ld): failed=%x (%x).\n", __func__,
@@ -3620,18 +3596,24 @@
 }
 
 int
-qla2x00_write_edc(scsi_qla_host_t *vha, uint16_t dev, uint16_t adr,
-    dma_addr_t sfp_dma, uint8_t *sfp, uint16_t len, uint16_t opt)
+qla2x00_write_sfp(scsi_qla_host_t *vha, dma_addr_t sfp_dma, uint8_t *sfp,
+	uint16_t dev, uint16_t off, uint16_t len, uint16_t opt)
 {
 	int rval;
 	mbx_cmd_t mc;
 	mbx_cmd_t *mcp = &mc;
+	struct qla_hw_data *ha = vha->hw;
+
+	if (!IS_FWI2_CAPABLE(ha))
+		return QLA_FUNCTION_FAILED;
 
 	DEBUG11(printk("%s(%ld): entered.\n", __func__, vha->host_no));
 
+	if (len == 1)
+		opt |= BIT_0;
+
 	if (opt & BIT_0)
-		if (sfp)
-			len = *sfp;
+		len = *sfp;
 
 	mcp->mb[0] = MBC_WRITE_SFP;
 	mcp->mb[1] = dev;
@@ -3640,10 +3622,10 @@
 	mcp->mb[6] = MSW(MSD(sfp_dma));
 	mcp->mb[7] = LSW(MSD(sfp_dma));
 	mcp->mb[8] = len;
-	mcp->mb[9] = adr;
+	mcp->mb[9] = off;
 	mcp->mb[10] = opt;
 	mcp->out_mb = MBX_10|MBX_9|MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
-	mcp->in_mb = MBX_0;
+	mcp->in_mb = MBX_1|MBX_0;
 	mcp->tov = MBX_TOV_SECONDS;
 	mcp->flags = 0;
 	rval = qla2x00_mailbox_command(vha, mcp);
@@ -4160,63 +4142,32 @@
 qla2x00_get_thermal_temp(scsi_qla_host_t *vha, uint16_t *temp, uint16_t *frac)
 {
 	int rval;
-	mbx_cmd_t mc;
-	mbx_cmd_t *mcp = &mc;
+	uint8_t byte;
 	struct qla_hw_data *ha = vha->hw;
 
-	DEBUG11(printk(KERN_INFO "%s(%ld): entered.\n", __func__, ha->host_no));
+	DEBUG11(printk(KERN_INFO "%s(%ld): entered.\n", __func__, vha->host_no));
 
-	/* High bits. */
-	mcp->mb[0] = MBC_READ_SFP;
-	mcp->mb[1] = 0x98;
-	mcp->mb[2] = 0;
-	mcp->mb[3] = 0;
-	mcp->mb[6] = 0;
-	mcp->mb[7] = 0;
-	mcp->mb[8] = 1;
-	mcp->mb[9] = 0x01;
-	mcp->mb[10] = BIT_13|BIT_0;
-	mcp->out_mb = MBX_10|MBX_9|MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
-	mcp->in_mb = MBX_1|MBX_0;
-	mcp->tov = MBX_TOV_SECONDS;
-	mcp->flags = 0;
-	rval = qla2x00_mailbox_command(vha, mcp);
+	/* Integer part */
+	rval = qla2x00_read_sfp(vha, 0, &byte, 0x98, 0x01, 1, BIT_13|BIT_0);
 	if (rval != QLA_SUCCESS) {
 		DEBUG2_3_11(printk(KERN_WARNING
-		    "%s(%ld): failed=%x (%x).\n", __func__,
-		    vha->host_no, rval, mcp->mb[0]));
+		    "%s(%ld): failed=%x.\n", __func__, vha->host_no, rval));
 		ha->flags.thermal_supported = 0;
 		goto fail;
 	}
-	*temp = mcp->mb[1] & 0xFF;
+	*temp = byte;
 
-	/* Low bits. */
-	mcp->mb[0] = MBC_READ_SFP;
-	mcp->mb[1] = 0x98;
-	mcp->mb[2] = 0;
-	mcp->mb[3] = 0;
-	mcp->mb[6] = 0;
-	mcp->mb[7] = 0;
-	mcp->mb[8] = 1;
-	mcp->mb[9] = 0x10;
-	mcp->mb[10] = BIT_13|BIT_0;
-	mcp->out_mb = MBX_10|MBX_9|MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
-	mcp->in_mb = MBX_1|MBX_0;
-	mcp->tov = MBX_TOV_SECONDS;
-	mcp->flags = 0;
-	rval = qla2x00_mailbox_command(vha, mcp);
+	/* Fraction part */
+	rval = qla2x00_read_sfp(vha, 0, &byte, 0x98, 0x10, 1, BIT_13|BIT_0);
 	if (rval != QLA_SUCCESS) {
 		DEBUG2_3_11(printk(KERN_WARNING
-		    "%s(%ld): failed=%x (%x).\n", __func__,
-		    vha->host_no, rval, mcp->mb[0]));
+		    "%s(%ld): failed=%x.\n", __func__, vha->host_no, rval));
 		ha->flags.thermal_supported = 0;
 		goto fail;
 	}
-	*frac = ((mcp->mb[1] & 0xFF) >> 6) * 25;
+	*frac = (byte >> 6) * 25;
 
-	if (rval == QLA_SUCCESS)
-		DEBUG11(printk(KERN_INFO
-		    "%s(%ld): done.\n", __func__, ha->host_no));
+	DEBUG11(printk(KERN_INFO "%s(%ld): done.\n", __func__, vha->host_no));
 fail:
 	return rval;
 }
diff -druN linux-2.6.39-libre/drivers/scsi/qla2xxx/qla_mid.c linux-3.0-rc7-libre/drivers/scsi/qla2xxx/qla_mid.c
--- linux-2.6.39-libre/drivers/scsi/qla2xxx/qla_mid.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/scsi/qla2xxx/qla_mid.c	2011-07-11 19:51:52.000000000 -0400
@@ -1,6 +1,6 @@
 /*
  * QLogic Fibre Channel HBA Driver
- * Copyright (c)  2003-2010 QLogic Corporation
+ * Copyright (c)  2003-2011 QLogic Corporation
  *
  * See LICENSE.qla2xxx for copyright and licensing details.
  */
@@ -136,7 +136,7 @@
 		    vha->host_no, fcport->loop_id, fcport->vp_idx));
 
 		qla2x00_mark_device_lost(vha, fcport, 0, 0);
-		atomic_set(&fcport->state, FCS_UNCONFIGURED);
+		qla2x00_set_fcport_state(fcport, FCS_UNCONFIGURED);
 	}
 }
 
@@ -456,7 +456,7 @@
 	else
 		host->max_cmd_len = MAX_CMDSZ;
 	host->max_channel = MAX_BUSES - 1;
-	host->max_lun = MAX_LUNS;
+	host->max_lun = ql2xmaxlun;
 	host->unique_id = host->host_no;
 	host->max_id = MAX_TARGETS_2200;
 	host->transportt = qla2xxx_transport_vport_template;
diff -druN linux-2.6.39-libre/drivers/scsi/qla2xxx/qla_nx.c linux-3.0-rc7-libre/drivers/scsi/qla2xxx/qla_nx.c
--- linux-2.6.39-libre/drivers/scsi/qla2xxx/qla_nx.c	2011-05-19 02:17:54.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/scsi/qla2xxx/qla_nx.c	2011-07-21 06:59:51.000000000 -0400
@@ -1,6 +1,6 @@
 /*
  * QLogic Fibre Channel HBA Driver
- * Copyright (c)  2003-2010 QLogic Corporation
+ * Copyright (c)  2003-2011 QLogic Corporation
  *
  * See LICENSE.qla2xxx for copyright and licensing details.
  */
@@ -844,6 +844,12 @@
 	return 0;
 }
 
+static void
+qla82xx_rom_unlock(struct qla_hw_data *ha)
+{
+	qla82xx_rd_32(ha, QLA82XX_PCIE_REG(PCIE_SEM2_UNLOCK));
+}
+
 static int
 qla82xx_wait_rom_busy(struct qla_hw_data *ha)
 {
@@ -924,7 +930,7 @@
 		return -1;
 	}
 	ret = qla82xx_do_rom_fast_read(ha, addr, valp);
-	qla82xx_rd_32(ha, QLA82XX_PCIE_REG(PCIE_SEM2_UNLOCK));
+	qla82xx_rom_unlock(ha);
 	return ret;
 }
 
@@ -1056,7 +1062,7 @@
 	ret = qla82xx_flash_wait_write_finish(ha);
 
 done_write:
-	qla82xx_rd_32(ha, QLA82XX_PCIE_REG(PCIE_SEM2_UNLOCK));
+	qla82xx_rom_unlock(ha);
 	return ret;
 }
 
@@ -1081,12 +1087,26 @@
 	/* Halt all the indiviual PEGs and other blocks of the ISP */
 	qla82xx_rom_lock(ha);
 
-	/* mask all niu interrupts */
+	/* disable all I2Q */
+	qla82xx_wr_32(ha, QLA82XX_CRB_I2Q + 0x10, 0x0);
+	qla82xx_wr_32(ha, QLA82XX_CRB_I2Q + 0x14, 0x0);
+	qla82xx_wr_32(ha, QLA82XX_CRB_I2Q + 0x18, 0x0);
+	qla82xx_wr_32(ha, QLA82XX_CRB_I2Q + 0x1c, 0x0);
+	qla82xx_wr_32(ha, QLA82XX_CRB_I2Q + 0x20, 0x0);
+	qla82xx_wr_32(ha, QLA82XX_CRB_I2Q + 0x24, 0x0);
+
+	/* disable all niu interrupts */
 	qla82xx_wr_32(ha, QLA82XX_CRB_NIU + 0x40, 0xff);
 	/* disable xge rx/tx */
 	qla82xx_wr_32(ha, QLA82XX_CRB_NIU + 0x70000, 0x00);
 	/* disable xg1 rx/tx */
 	qla82xx_wr_32(ha, QLA82XX_CRB_NIU + 0x80000, 0x00);
+	/* disable sideband mac */
+	qla82xx_wr_32(ha, QLA82XX_CRB_NIU + 0x90000, 0x00);
+	/* disable ap0 mac */
+	qla82xx_wr_32(ha, QLA82XX_CRB_NIU + 0xa0000, 0x00);
+	/* disable ap1 mac */
+	qla82xx_wr_32(ha, QLA82XX_CRB_NIU + 0xb0000, 0x00);
 
 	/* halt sre */
 	val = qla82xx_rd_32(ha, QLA82XX_CRB_SRE + 0x1000);
@@ -1101,6 +1121,7 @@
 	qla82xx_wr_32(ha, QLA82XX_CRB_TIMER + 0x10, 0x0);
 	qla82xx_wr_32(ha, QLA82XX_CRB_TIMER + 0x18, 0x0);
 	qla82xx_wr_32(ha, QLA82XX_CRB_TIMER + 0x100, 0x0);
+	qla82xx_wr_32(ha, QLA82XX_CRB_TIMER + 0x200, 0x0);
 
 	/* halt pegs */
 	qla82xx_wr_32(ha, QLA82XX_CRB_PEG_NET_0 + 0x3c, 1);
@@ -1108,9 +1129,9 @@
 	qla82xx_wr_32(ha, QLA82XX_CRB_PEG_NET_2 + 0x3c, 1);
 	qla82xx_wr_32(ha, QLA82XX_CRB_PEG_NET_3 + 0x3c, 1);
 	qla82xx_wr_32(ha, QLA82XX_CRB_PEG_NET_4 + 0x3c, 1);
+	msleep(20);
 
 	/* big hammer */
-	msleep(1000);
 	if (test_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags))
 		/* don't reset CAM block on reset */
 		qla82xx_wr_32(ha, QLA82XX_ROMUSB_GLB_SW_RESET, 0xfeffffff);
@@ -1129,7 +1150,7 @@
 	qla82xx_wr_32(ha, QLA82XX_CRB_QDR_NET + 0xe4, val);
 	msleep(20);
 
-	qla82xx_rd_32(ha, QLA82XX_PCIE_REG(PCIE_SEM2_UNLOCK));
+	qla82xx_rom_unlock(ha);
 
 	/* Read the signature value from the flash.
 	 * Offset 0: Contain signature (0xcafecafe)
@@ -2395,9 +2416,13 @@
 
 	if (qla82xx_fw_load_from_flash(ha) == QLA_SUCCESS) {
 		qla_printk(KERN_ERR, ha,
-			"Firmware loaded successfully from flash\n");
+		    "Firmware loaded successfully from flash\n");
 		return QLA_SUCCESS;
+	} else {
+		qla_printk(KERN_ERR, ha,
+		    "Firmware load from flash failed\n");
 	}
+
 try_blob_fw:
 	qla_printk(KERN_INFO, ha,
 	    "Attempting to load firmware from blob\n");
@@ -2548,11 +2573,11 @@
 			dsd_seg = (uint32_t *)&cmd_pkt->fcp_data_dseg_address;
 			*dsd_seg++ = cpu_to_le32(LSD(dsd_ptr->dsd_list_dma));
 			*dsd_seg++ = cpu_to_le32(MSD(dsd_ptr->dsd_list_dma));
-			cmd_pkt->fcp_data_dseg_len = dsd_list_len;
+			*dsd_seg++ = cpu_to_le32(dsd_list_len);
 		} else {
 			*cur_dsd++ = cpu_to_le32(LSD(dsd_ptr->dsd_list_dma));
 			*cur_dsd++ = cpu_to_le32(MSD(dsd_ptr->dsd_list_dma));
-			*cur_dsd++ = dsd_list_len;
+			*cur_dsd++ = cpu_to_le32(dsd_list_len);
 		}
 		cur_dsd = (uint32_t *)next_dsd;
 		while (avail_dsds) {
@@ -2991,7 +3016,7 @@
 		qla_printk(KERN_WARNING, ha, "Write disable failed\n");
 
 done_unprotect:
-	qla82xx_rd_32(ha, QLA82XX_PCIE_REG(PCIE_SEM2_UNLOCK));
+	qla82xx_rom_unlock(ha);
 	return ret;
 }
 
@@ -3020,7 +3045,7 @@
 	if (qla82xx_write_disable_flash(ha) != 0)
 		qla_printk(KERN_WARNING, ha, "Write disable failed\n");
 done_protect:
-	qla82xx_rd_32(ha, QLA82XX_PCIE_REG(PCIE_SEM2_UNLOCK));
+	qla82xx_rom_unlock(ha);
 	return ret;
 }
 
@@ -3048,7 +3073,7 @@
 	}
 	ret = qla82xx_flash_wait_write_finish(ha);
 done:
-	qla82xx_rd_32(ha, QLA82XX_PCIE_REG(PCIE_SEM2_UNLOCK));
+	qla82xx_rom_unlock(ha);
 	return ret;
 }
 
@@ -3228,7 +3253,7 @@
 	 * else died while holding it.
 	 * In either case, unlock.
 	 */
-	qla82xx_rd_32(ha, QLA82XX_PCIE_REG(PCIE_SEM2_UNLOCK));
+	qla82xx_rom_unlock(ha);
 }
 
 /*
@@ -3528,15 +3553,18 @@
 qla82xx_device_state_handler(scsi_qla_host_t *vha)
 {
 	uint32_t dev_state;
+	uint32_t old_dev_state;
 	int rval = QLA_SUCCESS;
 	unsigned long dev_init_timeout;
 	struct qla_hw_data *ha = vha->hw;
+	int loopcount = 0;
 
 	qla82xx_idc_lock(ha);
 	if (!vha->flags.init_done)
 		qla82xx_set_drv_active(vha);
 
 	dev_state = qla82xx_rd_32(ha, QLA82XX_CRB_DEV_STATE);
+	old_dev_state = dev_state;
 	qla_printk(KERN_INFO, ha, "1:Device state is 0x%x = %s\n", dev_state,
 		dev_state < MAX_STATES ? qdev_state[dev_state] : "Unknown");
 
@@ -3553,10 +3581,16 @@
 			break;
 		}
 		dev_state = qla82xx_rd_32(ha, QLA82XX_CRB_DEV_STATE);
-		qla_printk(KERN_INFO, ha,
-			"2:Device state is 0x%x = %s\n", dev_state,
-			dev_state < MAX_STATES ?
-			qdev_state[dev_state] : "Unknown");
+		if (old_dev_state != dev_state) {
+			loopcount = 0;
+			old_dev_state = dev_state;
+		}
+		if (loopcount < 5) {
+			qla_printk(KERN_INFO, ha,
+			    "2:Device state is 0x%x = %s\n", dev_state,
+			    dev_state < MAX_STATES ?
+			    qdev_state[dev_state] : "Unknown");
+		}
 
 		switch (dev_state) {
 		case QLA82XX_DEV_READY:
@@ -3570,6 +3604,7 @@
 			qla82xx_idc_lock(ha);
 			break;
 		case QLA82XX_DEV_NEED_RESET:
+		    if (!ql2xdontresethba)
 			qla82xx_need_reset_handler(vha);
 			dev_init_timeout = jiffies +
 				(ha->nx_dev_init_timeout * HZ);
@@ -3604,6 +3639,7 @@
 			msleep(1000);
 			qla82xx_idc_lock(ha);
 		}
+		loopcount++;
 	}
 exit:
 	qla82xx_idc_unlock(ha);
@@ -3621,7 +3657,8 @@
 		if (dev_state == QLA82XX_DEV_NEED_RESET &&
 		    !test_bit(ISP_ABORT_NEEDED, &vha->dpc_flags)) {
 			qla_printk(KERN_WARNING, ha,
-			    "%s(): Adapter reset needed!\n", __func__);
+			    "scsi(%ld) %s: Adapter reset needed!\n",
+				vha->host_no, __func__);
 			set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
 			qla2xxx_wake_dpc(vha);
 		} else if (dev_state == QLA82XX_DEV_NEED_QUIESCENT &&
@@ -3632,10 +3669,27 @@
 			set_bit(ISP_QUIESCE_NEEDED, &vha->dpc_flags);
 			qla2xxx_wake_dpc(vha);
 		} else {
-			qla82xx_check_fw_alive(vha);
 			if (qla82xx_check_fw_alive(vha)) {
 				halt_status = qla82xx_rd_32(ha,
 				    QLA82XX_PEG_HALT_STATUS1);
+				qla_printk(KERN_INFO, ha,
+				    "scsi(%ld): %s, Dumping hw/fw registers:\n "
+				    " PEG_HALT_STATUS1: 0x%x, PEG_HALT_STATUS2: 0x%x,\n "
+				    " PEG_NET_0_PC: 0x%x, PEG_NET_1_PC: 0x%x,\n "
+				    " PEG_NET_2_PC: 0x%x, PEG_NET_3_PC: 0x%x,\n "
+				    " PEG_NET_4_PC: 0x%x\n",
+				    vha->host_no, __func__, halt_status,
+				    qla82xx_rd_32(ha, QLA82XX_PEG_HALT_STATUS2),
+				    qla82xx_rd_32(ha,
+					    QLA82XX_CRB_PEG_NET_0 + 0x3c),
+				    qla82xx_rd_32(ha,
+					    QLA82XX_CRB_PEG_NET_1 + 0x3c),
+				    qla82xx_rd_32(ha,
+					    QLA82XX_CRB_PEG_NET_2 + 0x3c),
+				    qla82xx_rd_32(ha,
+					    QLA82XX_CRB_PEG_NET_3 + 0x3c),
+				    qla82xx_rd_32(ha,
+					    QLA82XX_CRB_PEG_NET_4 + 0x3c));
 				if (halt_status & HALT_STATUS_UNRECOVERABLE) {
 					set_bit(ISP_UNRECOVERABLE,
 					    &vha->dpc_flags);
@@ -3651,8 +3705,9 @@
 				if (ha->flags.mbox_busy) {
 					ha->flags.mbox_int = 1;
 					DEBUG2(qla_printk(KERN_ERR, ha,
-					    "Due to fw hung, doing premature "
-					    "completion of mbx command\n"));
+					    "scsi(%ld) Due to fw hung, doing "
+					    "premature completion of mbx "
+					    "command\n", vha->host_no));
 					if (test_bit(MBX_INTR_WAIT,
 					    &ha->mbx_cmd_flags))
 						complete(&ha->mbx_intr_comp);
diff -druN linux-2.6.39-libre/drivers/scsi/qla2xxx/qla_nx.h linux-3.0-rc7-libre/drivers/scsi/qla2xxx/qla_nx.h
--- linux-2.6.39-libre/drivers/scsi/qla2xxx/qla_nx.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/scsi/qla2xxx/qla_nx.h	2011-07-11 19:51:52.000000000 -0400
@@ -1,6 +1,6 @@
 /*
  * QLogic Fibre Channel HBA Driver
- * Copyright (c)  2003-2010 QLogic Corporation
+ * Copyright (c)  2003-2011 QLogic Corporation
  *
  * See LICENSE.qla2xxx for copyright and licensing details.
  */
diff -druN linux-2.6.39-libre/drivers/scsi/qla2xxx/qla_os.c linux-3.0-rc7-libre/drivers/scsi/qla2xxx/qla_os.c
--- linux-2.6.39-libre/drivers/scsi/qla2xxx/qla_os.c	2011-05-19 02:17:58.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/scsi/qla2xxx/qla_os.c	2011-07-21 06:59:55.000000000 -0400
@@ -1,6 +1,6 @@
 /*
  * QLogic Fibre Channel HBA Driver
- * Copyright (c)  2003-2010 QLogic Corporation
+ * Copyright (c)  2003-2011 QLogic Corporation
  *
  * See LICENSE.qla2xxx for copyright and licensing details.
  */
@@ -164,6 +164,20 @@
 MODULE_PARM_DESC(ql2xasynctmfenable,
 		"Enables issue of TM IOCBs asynchronously via IOCB mechanism"
 		"Default is 0 - Issue TM IOCBs via mailbox mechanism.");
+
+int ql2xdontresethba;
+module_param(ql2xdontresethba, int, S_IRUGO);
+MODULE_PARM_DESC(ql2xdontresethba,
+	"Option to specify reset behaviour\n"
+	" 0 (Default) -- Reset on failure.\n"
+	" 1 -- Do not reset on failure.\n");
+
+uint ql2xmaxlun = MAX_LUNS;
+module_param(ql2xmaxlun, uint, S_IRUGO);
+MODULE_PARM_DESC(ql2xmaxlun,
+		"Defines the maximum LU number to register with the SCSI "
+		"midlayer. Default is 65535.");
+
 /*
  * SCSI host template entry points
  */
@@ -528,7 +542,7 @@
 static int
 qla2xxx_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd)
 {
-	scsi_qla_host_t *vha = shost_priv(cmd->device->host);
+	scsi_qla_host_t *vha = shost_priv(host);
 	fc_port_t *fcport = (struct fc_port *) cmd->device->hostdata;
 	struct fc_rport *rport = starget_to_rport(scsi_target(cmd->device));
 	struct qla_hw_data *ha = vha->hw;
@@ -2128,7 +2142,7 @@
 	else
 		host->max_cmd_len = MAX_CMDSZ;
 	host->max_channel = MAX_BUSES - 1;
-	host->max_lun = MAX_LUNS;
+	host->max_lun = ql2xmaxlun;
 	host->transportt = qla2xxx_transport_template;
 	sht->vendor_id = (SCSI_NL_VID_TYPE_PCI | PCI_VENDOR_ID_QLOGIC);
 
@@ -2360,21 +2374,26 @@
 	base_vha = pci_get_drvdata(pdev);
 	ha = base_vha->hw;
 
-	spin_lock_irqsave(&ha->vport_slock, flags);
-	list_for_each_entry(vha, &ha->vp_list, list) {
-		atomic_inc(&vha->vref_count);
+	mutex_lock(&ha->vport_lock);
+	while (ha->cur_vport_count) {
+		struct Scsi_Host *scsi_host;
 
-		if (vha->fc_vport) {
-			spin_unlock_irqrestore(&ha->vport_slock, flags);
+		spin_lock_irqsave(&ha->vport_slock, flags);
 
-			fc_vport_terminate(vha->fc_vport);
+		BUG_ON(base_vha->list.next == &ha->vp_list);
+		/* This assumes first entry in ha->vp_list is always base vha */
+		vha = list_first_entry(&base_vha->list, scsi_qla_host_t, list);
+		scsi_host = scsi_host_get(vha->host);
 
-			spin_lock_irqsave(&ha->vport_slock, flags);
-		}
+		spin_unlock_irqrestore(&ha->vport_slock, flags);
+		mutex_unlock(&ha->vport_lock);
 
-		atomic_dec(&vha->vref_count);
+		fc_vport_terminate(vha->fc_vport);
+		scsi_host_put(vha->host);
+
+		mutex_lock(&ha->vport_lock);
 	}
-	spin_unlock_irqrestore(&ha->vport_slock, flags);
+	mutex_unlock(&ha->vport_lock);
 
 	set_bit(UNLOADING, &base_vha->dpc_flags);
 
@@ -2544,7 +2563,7 @@
 {
 	if (atomic_read(&fcport->state) == FCS_ONLINE &&
 	    vha->vp_idx == fcport->vp_idx) {
-		atomic_set(&fcport->state, FCS_DEVICE_LOST);
+		qla2x00_set_fcport_state(fcport, FCS_DEVICE_LOST);
 		qla2x00_schedule_rport_del(vha, fcport, defer);
 	}
 	/*
@@ -2552,7 +2571,7 @@
 	 * port but do the retries.
 	 */
 	if (atomic_read(&fcport->state) != FCS_DEVICE_DEAD)
-		atomic_set(&fcport->state, FCS_DEVICE_LOST);
+		qla2x00_set_fcport_state(fcport, FCS_DEVICE_LOST);
 
 	if (!do_login)
 		return;
@@ -2607,7 +2626,7 @@
 		if (atomic_read(&fcport->state) == FCS_DEVICE_DEAD)
 			continue;
 		if (atomic_read(&fcport->state) == FCS_ONLINE) {
-			atomic_set(&fcport->state, FCS_DEVICE_LOST);
+			qla2x00_set_fcport_state(fcport, FCS_DEVICE_LOST);
 			if (defer)
 				qla2x00_schedule_rport_del(vha, fcport, defer);
 			else if (vha->vp_idx == fcport->vp_idx)
@@ -3214,6 +3233,17 @@
 							fcport->d_id.b.area,
 							fcport->d_id.b.al_pa);
 
+				if (fcport->loop_id == FC_NO_LOOP_ID) {
+					fcport->loop_id = next_loopid =
+					    ha->min_external_loopid;
+					status = qla2x00_find_new_loop_id(
+					    vha, fcport);
+					if (status != QLA_SUCCESS) {
+						/* Ran out of IDs to use */
+						break;
+					}
+				}
+
 				if (IS_ALOGIO_CAPABLE(ha)) {
 					fcport->flags |= FCF_ASYNC_SENT;
 					data[0] = 0;
@@ -3604,7 +3634,8 @@
 	if (!pci_channel_offline(ha->pdev))
 		pci_read_config_word(ha->pdev, PCI_VENDOR_ID, &w);
 
-	if (IS_QLA82XX(ha)) {
+	/* Make sure qla82xx_watchdog is run only for physical port */
+	if (!vha->vp_idx && IS_QLA82XX(ha)) {
 		if (test_bit(ISP_QUIESCE_NEEDED, &vha->dpc_flags))
 			start_dpc++;
 		qla82xx_watchdog(vha);
@@ -3612,7 +3643,8 @@
 
 	/* Loop down handler. */
 	if (atomic_read(&vha->loop_down_timer) > 0 &&
-	    !(test_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags))
+	    !(test_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags)) &&
+	    !(test_bit(FCOE_CTX_RESET_NEEDED, &vha->dpc_flags))
 		&& vha->flags.online) {
 
 		if (atomic_read(&vha->loop_down_timer) ==
@@ -3648,7 +3680,11 @@
 					if (!(sfcp->flags & FCF_FCP2_DEVICE))
 						continue;
 
-					set_bit(ISP_ABORT_NEEDED,
+					if (IS_QLA82XX(ha))
+						set_bit(FCOE_CTX_RESET_NEEDED,
+							&vha->dpc_flags);
+					else
+						set_bit(ISP_ABORT_NEEDED,
 							&vha->dpc_flags);
 					break;
 				}
@@ -3667,7 +3703,12 @@
 				qla_printk(KERN_WARNING, ha,
 				    "Loop down - aborting ISP.\n");
 
-				set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
+				if (IS_QLA82XX(ha))
+					set_bit(FCOE_CTX_RESET_NEEDED,
+						&vha->dpc_flags);
+				else
+					set_bit(ISP_ABORT_NEEDED,
+						&vha->dpc_flags);
 			}
 		}
 		DEBUG3(printk("scsi(%ld): Loop Down - seconds remaining %d\n",
@@ -3675,8 +3716,8 @@
 		    atomic_read(&vha->loop_down_timer)));
 	}
 
-	/* Check if beacon LED needs to be blinked */
-	if (ha->beacon_blink_led == 1) {
+	/* Check if beacon LED needs to be blinked for physical host only */
+	if (!vha->vp_idx && (ha->beacon_blink_led == 1)) {
 		set_bit(BEACON_BLINK_NEEDED, &vha->dpc_flags);
 		start_dpc++;
 	}
diff -druN linux-2.6.39-libre/drivers/scsi/qla2xxx/qla_settings.h linux-3.0-rc7-libre/drivers/scsi/qla2xxx/qla_settings.h
--- linux-2.6.39-libre/drivers/scsi/qla2xxx/qla_settings.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/scsi/qla2xxx/qla_settings.h	2011-07-11 19:51:52.000000000 -0400
@@ -1,6 +1,6 @@
 /*
  * QLogic Fibre Channel HBA Driver
- * Copyright (c)  2003-2010 QLogic Corporation
+ * Copyright (c)  2003-2011 QLogic Corporation
  *
  * See LICENSE.qla2xxx for copyright and licensing details.
  */
diff -druN linux-2.6.39-libre/drivers/scsi/qla2xxx/qla_sup.c linux-3.0-rc7-libre/drivers/scsi/qla2xxx/qla_sup.c
--- linux-2.6.39-libre/drivers/scsi/qla2xxx/qla_sup.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/scsi/qla2xxx/qla_sup.c	2011-07-11 19:51:52.000000000 -0400
@@ -1,6 +1,6 @@
 /*
  * QLogic Fibre Channel HBA Driver
- * Copyright (c)  2003-2010 QLogic Corporation
+ * Copyright (c)  2003-2011 QLogic Corporation
  *
  * See LICENSE.qla2xxx for copyright and licensing details.
  */
diff -druN linux-2.6.39-libre/drivers/scsi/qla2xxx/qla_version.h linux-3.0-rc7-libre/drivers/scsi/qla2xxx/qla_version.h
--- linux-2.6.39-libre/drivers/scsi/qla2xxx/qla_version.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/scsi/qla2xxx/qla_version.h	2011-07-11 19:51:52.000000000 -0400
@@ -1,15 +1,15 @@
 /*
  * QLogic Fibre Channel HBA Driver
- * Copyright (c)  2003-2010 QLogic Corporation
+ * Copyright (c)  2003-2011 QLogic Corporation
  *
  * See LICENSE.qla2xxx for copyright and licensing details.
  */
 /*
  * Driver version
  */
-#define QLA2XXX_VERSION      "8.03.07.00"
+#define QLA2XXX_VERSION      "8.03.07.03-k"
 
 #define QLA_DRIVER_MAJOR_VER	8
 #define QLA_DRIVER_MINOR_VER	3
 #define QLA_DRIVER_PATCH_VER	7
-#define QLA_DRIVER_BETA_VER	0
+#define QLA_DRIVER_BETA_VER	3
diff -druN linux-2.6.39-libre/drivers/scsi/qla4xxx/Makefile linux-3.0-rc7-libre/drivers/scsi/qla4xxx/Makefile
--- linux-2.6.39-libre/drivers/scsi/qla4xxx/Makefile	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/scsi/qla4xxx/Makefile	2011-07-11 19:51:52.000000000 -0400
@@ -1,5 +1,5 @@
 qla4xxx-y := ql4_os.o ql4_init.o ql4_mbx.o ql4_iocb.o ql4_isr.o \
-		ql4_nx.o ql4_nvram.o ql4_dbg.o
+		ql4_nx.o ql4_nvram.o ql4_dbg.o ql4_attr.o
 
 obj-$(CONFIG_SCSI_QLA_ISCSI) += qla4xxx.o
 
diff -druN linux-2.6.39-libre/drivers/scsi/qla4xxx/ql4_attr.c linux-3.0-rc7-libre/drivers/scsi/qla4xxx/ql4_attr.c
--- linux-2.6.39-libre/drivers/scsi/qla4xxx/ql4_attr.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/scsi/qla4xxx/ql4_attr.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,69 @@
+/*
+ * QLogic iSCSI HBA Driver
+ * Copyright (c)  2003-2011 QLogic Corporation
+ *
+ * See LICENSE.qla4xxx for copyright and licensing details.
+ */
+
+#include "ql4_def.h"
+#include "ql4_glbl.h"
+#include "ql4_dbg.h"
+
+/* Scsi_Host attributes. */
+static ssize_t
+qla4xxx_fw_version_show(struct device *dev,
+			struct device_attribute *attr, char *buf)
+{
+	struct scsi_qla_host *ha = to_qla_host(class_to_shost(dev));
+
+	if (is_qla8022(ha))
+		return snprintf(buf, PAGE_SIZE, "%d.%02d.%02d (%x)\n",
+				ha->firmware_version[0],
+				ha->firmware_version[1],
+				ha->patch_number, ha->build_number);
+	else
+		return snprintf(buf, PAGE_SIZE, "%d.%02d.%02d.%02d\n",
+				ha->firmware_version[0],
+				ha->firmware_version[1],
+				ha->patch_number, ha->build_number);
+}
+
+static ssize_t
+qla4xxx_serial_num_show(struct device *dev, struct device_attribute *attr,
+			char *buf)
+{
+	struct scsi_qla_host *ha = to_qla_host(class_to_shost(dev));
+	return snprintf(buf, PAGE_SIZE, "%s\n", ha->serial_number);
+}
+
+static ssize_t
+qla4xxx_iscsi_version_show(struct device *dev, struct device_attribute *attr,
+			   char *buf)
+{
+	struct scsi_qla_host *ha = to_qla_host(class_to_shost(dev));
+	return snprintf(buf, PAGE_SIZE, "%d.%02d\n", ha->iscsi_major,
+			ha->iscsi_minor);
+}
+
+static ssize_t
+qla4xxx_optrom_version_show(struct device *dev, struct device_attribute *attr,
+			    char *buf)
+{
+	struct scsi_qla_host *ha = to_qla_host(class_to_shost(dev));
+	return snprintf(buf, PAGE_SIZE, "%d.%02d.%02d.%02d\n",
+			ha->bootload_major, ha->bootload_minor,
+			ha->bootload_patch, ha->bootload_build);
+}
+
+static DEVICE_ATTR(fw_version, S_IRUGO, qla4xxx_fw_version_show, NULL);
+static DEVICE_ATTR(serial_num, S_IRUGO, qla4xxx_serial_num_show, NULL);
+static DEVICE_ATTR(iscsi_version, S_IRUGO, qla4xxx_iscsi_version_show, NULL);
+static DEVICE_ATTR(optrom_version, S_IRUGO, qla4xxx_optrom_version_show, NULL);
+
+struct device_attribute *qla4xxx_host_attrs[] = {
+	&dev_attr_fw_version,
+	&dev_attr_serial_num,
+	&dev_attr_iscsi_version,
+	&dev_attr_optrom_version,
+	NULL,
+};
diff -druN linux-2.6.39-libre/drivers/scsi/qla4xxx/ql4_def.h linux-3.0-rc7-libre/drivers/scsi/qla4xxx/ql4_def.h
--- linux-2.6.39-libre/drivers/scsi/qla4xxx/ql4_def.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/scsi/qla4xxx/ql4_def.h	2011-07-11 19:51:52.000000000 -0400
@@ -115,7 +115,7 @@
 #define INVALID_ENTRY		0xFFFF
 #define MAX_CMDS_TO_RISC	1024
 #define MAX_SRBS		MAX_CMDS_TO_RISC
-#define MBOX_AEN_REG_COUNT	5
+#define MBOX_AEN_REG_COUNT	8
 #define MAX_INIT_RETRIES	5
 
 /*
@@ -368,7 +368,6 @@
 #define AF_INIT_DONE			1 /* 0x00000002 */
 #define AF_MBOX_COMMAND			2 /* 0x00000004 */
 #define AF_MBOX_COMMAND_DONE		3 /* 0x00000008 */
-#define AF_DPC_SCHEDULED		5 /* 0x00000020 */
 #define AF_INTERRUPTS_ON		6 /* 0x00000040 */
 #define AF_GET_CRASH_RECORD		7 /* 0x00000080 */
 #define AF_LINK_UP			8 /* 0x00000100 */
@@ -584,6 +583,14 @@
 	uint32_t nx_reset_timeout;
 
 	struct completion mbx_intr_comp;
+
+	/* --- From About Firmware --- */
+	uint16_t iscsi_major;
+	uint16_t iscsi_minor;
+	uint16_t bootload_major;
+	uint16_t bootload_minor;
+	uint16_t bootload_patch;
+	uint16_t bootload_build;
 };
 
 static inline int is_ipv4_enabled(struct scsi_qla_host *ha)
diff -druN linux-2.6.39-libre/drivers/scsi/qla4xxx/ql4_fw.h linux-3.0-rc7-libre/drivers/scsi/qla4xxx/ql4_fw.h
--- linux-2.6.39-libre/drivers/scsi/qla4xxx/ql4_fw.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/scsi/qla4xxx/ql4_fw.h	2011-07-11 19:51:52.000000000 -0400
@@ -690,6 +690,29 @@
 	uint8_t reserved[12];		  /* 34-3f */
 };
 
+struct about_fw_info {
+	uint16_t fw_major;		/* 00 - 01 */
+	uint16_t fw_minor;		/* 02 - 03 */
+	uint16_t fw_patch;		/* 04 - 05 */
+	uint16_t fw_build;		/* 06 - 07 */
+	uint8_t fw_build_date[16];	/* 08 - 17 ASCII String */
+	uint8_t fw_build_time[16];	/* 18 - 27 ASCII String */
+	uint8_t fw_build_user[16];	/* 28 - 37 ASCII String */
+	uint16_t fw_load_source;	/* 38 - 39 */
+					/* 1 = Flash Primary,
+					   2 = Flash Secondary,
+					   3 = Host Download
+					*/
+	uint8_t reserved1[6];		/* 3A - 3F */
+	uint16_t iscsi_major;		/* 40 - 41 */
+	uint16_t iscsi_minor;		/* 42 - 43 */
+	uint16_t bootload_major;	/* 44 - 45 */
+	uint16_t bootload_minor;	/* 46 - 47 */
+	uint16_t bootload_patch;	/* 48 - 49 */
+	uint16_t bootload_build;	/* 4A - 4B */
+	uint8_t reserved2[180];		/* 4C - FF */
+};
+
 struct crash_record {
 	uint16_t fw_major_version;	/* 00 - 01 */
 	uint16_t fw_minor_version;	/* 02 - 03 */
diff -druN linux-2.6.39-libre/drivers/scsi/qla4xxx/ql4_glbl.h linux-3.0-rc7-libre/drivers/scsi/qla4xxx/ql4_glbl.h
--- linux-2.6.39-libre/drivers/scsi/qla4xxx/ql4_glbl.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/scsi/qla4xxx/ql4_glbl.h	2011-07-11 19:51:52.000000000 -0400
@@ -61,7 +61,7 @@
 int qla4xxx_add_sess(struct ddb_entry *);
 void qla4xxx_destroy_sess(struct ddb_entry *ddb_entry);
 int qla4xxx_is_nvram_configuration_valid(struct scsi_qla_host *ha);
-int qla4xxx_get_fw_version(struct scsi_qla_host * ha);
+int qla4xxx_about_firmware(struct scsi_qla_host *ha);
 void qla4xxx_interrupt_service_routine(struct scsi_qla_host *ha,
 				       uint32_t intr_status);
 int qla4xxx_init_rings(struct scsi_qla_host *ha);
@@ -139,4 +139,5 @@
 extern int ql4xdontresethba;
 extern int ql4xenablemsix;
 
+extern struct device_attribute *qla4xxx_host_attrs[];
 #endif /* _QLA4x_GBL_H */
diff -druN linux-2.6.39-libre/drivers/scsi/qla4xxx/ql4_init.c linux-3.0-rc7-libre/drivers/scsi/qla4xxx/ql4_init.c
--- linux-2.6.39-libre/drivers/scsi/qla4xxx/ql4_init.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/scsi/qla4xxx/ql4_init.c	2011-07-11 19:51:52.000000000 -0400
@@ -1275,7 +1275,7 @@
 	if (ha->isp_ops->start_firmware(ha) == QLA_ERROR)
 		goto exit_init_hba;
 
-	if (qla4xxx_get_fw_version(ha) == QLA_ERROR)
+	if (qla4xxx_about_firmware(ha) == QLA_ERROR)
 		goto exit_init_hba;
 
 	if (ha->isp_ops->get_sys_info(ha) == QLA_ERROR)
diff -druN linux-2.6.39-libre/drivers/scsi/qla4xxx/ql4_isr.c linux-3.0-rc7-libre/drivers/scsi/qla4xxx/ql4_isr.c
--- linux-2.6.39-libre/drivers/scsi/qla4xxx/ql4_isr.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/scsi/qla4xxx/ql4_isr.c	2011-07-11 19:51:52.000000000 -0400
@@ -25,9 +25,14 @@
 
 	memset(cmd->sense_buffer, 0, SCSI_SENSE_BUFFERSIZE);
 	sense_len = le16_to_cpu(sts_entry->senseDataByteCnt);
-	if (sense_len == 0)
+	if (sense_len == 0) {
+		DEBUG2(ql4_printk(KERN_INFO, ha, "scsi%ld:%d:%d:%d: %s:"
+				  " sense len 0\n", ha->host_no,
+				  cmd->device->channel, cmd->device->id,
+				  cmd->device->lun, __func__));
+		ha->status_srb = NULL;
 		return;
-
+	}
 	/* Save total available sense length,
 	 * not to exceed cmd's sense buffer size */
 	sense_len = min_t(uint16_t, sense_len, SCSI_SENSE_BUFFERSIZE);
@@ -541,6 +546,7 @@
 		case MBOX_ASTS_UNSOLICITED_PDU_RECEIVED:  /* Connection mode */
 		case MBOX_ASTS_IPSEC_SYSTEM_FATAL_ERROR:
 		case MBOX_ASTS_SUBNET_STATE_CHANGE:
+		case MBOX_ASTS_DUPLICATE_IP:
 			/* No action */
 			DEBUG2(printk("scsi%ld: AEN %04x\n", ha->host_no,
 				      mbox_status));
@@ -593,11 +599,13 @@
 					    mbox_sts[i];
 
 				/* print debug message */
-				DEBUG2(printk("scsi%ld: AEN[%d] %04x queued"
-				    " mb1:0x%x mb2:0x%x mb3:0x%x mb4:0x%x\n",
-				    ha->host_no, ha->aen_in, mbox_sts[0],
-				    mbox_sts[1], mbox_sts[2],  mbox_sts[3],
-				    mbox_sts[4]));
+				DEBUG2(printk("scsi%ld: AEN[%d] %04x queued "
+					      "mb1:0x%x mb2:0x%x mb3:0x%x "
+					      "mb4:0x%x mb5:0x%x\n",
+					      ha->host_no, ha->aen_in,
+					      mbox_sts[0], mbox_sts[1],
+					      mbox_sts[2], mbox_sts[3],
+					      mbox_sts[4], mbox_sts[5]));
 
 				/* advance pointer */
 				ha->aen_in++;
diff -druN linux-2.6.39-libre/drivers/scsi/qla4xxx/ql4_mbx.c linux-3.0-rc7-libre/drivers/scsi/qla4xxx/ql4_mbx.c
--- linux-2.6.39-libre/drivers/scsi/qla4xxx/ql4_mbx.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/scsi/qla4xxx/ql4_mbx.c	2011-07-11 19:51:52.000000000 -0400
@@ -19,7 +19,7 @@
  * @mbx_cmd: data pointer for mailbox in registers.
  * @mbx_sts: data pointer for mailbox out registers.
  *
- * This routine isssue mailbox commands and waits for completion.
+ * This routine issue mailbox commands and waits for completion.
  * If outCount is 0, this routine completes successfully WITHOUT waiting
  * for the mailbox command to complete.
  **/
@@ -86,22 +86,8 @@
 		msleep(10);
 	}
 
-	/* To prevent overwriting mailbox registers for a command that has
-	 * not yet been serviced, check to see if an active command
-	 * (AEN, IOCB, etc.) is interrupting, then service it.
-	 * -----------------------------------------------------------------
-	 */
 	spin_lock_irqsave(&ha->hardware_lock, flags);
 
-	if (!is_qla8022(ha)) {
-		intr_status = readl(&ha->reg->ctrl_status);
-		if (intr_status & CSR_SCSI_PROCESSOR_INTR) {
-			/* Service existing interrupt */
-			ha->isp_ops->interrupt_service_routine(ha, intr_status);
-			clear_bit(AF_MBOX_COMMAND_DONE, &ha->flags);
-		}
-	}
-
 	ha->mbox_status_count = outCount;
 	for (i = 0; i < outCount; i++)
 		ha->mbox_status[i] = 0;
@@ -1057,38 +1043,65 @@
 }
 
 /**
- * qla4xxx_get_fw_version - gets firmware version
+ * qla4xxx_about_firmware - gets FW, iscsi draft and boot loader version
  * @ha: Pointer to host adapter structure.
  *
- * Retrieves the firmware version on HBA. In QLA4010, mailboxes 2 & 3 may
- * hold an address for data.  Make sure that we write 0 to those mailboxes,
- * if unused.
+ * Retrieves the FW version, iSCSI draft version & bootloader version of HBA.
+ * Mailboxes 2 & 3 may hold an address for data. Make sure that we write 0 to
+ * those mailboxes, if unused.
  **/
-int qla4xxx_get_fw_version(struct scsi_qla_host * ha)
+int qla4xxx_about_firmware(struct scsi_qla_host *ha)
 {
+	struct about_fw_info *about_fw = NULL;
+	dma_addr_t about_fw_dma;
 	uint32_t mbox_cmd[MBOX_REG_COUNT];
 	uint32_t mbox_sts[MBOX_REG_COUNT];
+	int status = QLA_ERROR;
 
-	/* Get firmware version. */
+	about_fw = dma_alloc_coherent(&ha->pdev->dev,
+				      sizeof(struct about_fw_info),
+				      &about_fw_dma, GFP_KERNEL);
+	if (!about_fw) {
+		DEBUG2(ql4_printk(KERN_ERR, ha, "%s: Unable to alloc memory "
+				  "for about_fw\n", __func__));
+		return status;
+	}
+
+	memset(about_fw, 0, sizeof(struct about_fw_info));
 	memset(&mbox_cmd, 0, sizeof(mbox_cmd));
 	memset(&mbox_sts, 0, sizeof(mbox_sts));
 
 	mbox_cmd[0] = MBOX_CMD_ABOUT_FW;
+	mbox_cmd[2] = LSDW(about_fw_dma);
+	mbox_cmd[3] = MSDW(about_fw_dma);
+	mbox_cmd[4] = sizeof(struct about_fw_info);
 
-	if (qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, 5, &mbox_cmd[0], &mbox_sts[0]) !=
-	    QLA_SUCCESS) {
-		DEBUG2(printk("scsi%ld: %s: MBOX_CMD_ABOUT_FW failed w/ "
-		    "status %04X\n", ha->host_no, __func__, mbox_sts[0]));
-		return QLA_ERROR;
+	status = qla4xxx_mailbox_command(ha, MBOX_REG_COUNT, MBOX_REG_COUNT,
+					 &mbox_cmd[0], &mbox_sts[0]);
+	if (status != QLA_SUCCESS) {
+		DEBUG2(ql4_printk(KERN_WARNING, ha, "%s: MBOX_CMD_ABOUT_FW "
+				  "failed w/ status %04X\n", __func__,
+				  mbox_sts[0]));
+		goto exit_about_fw;
 	}
 
-	/* Save firmware version information. */
-	ha->firmware_version[0] = mbox_sts[1];
-	ha->firmware_version[1] = mbox_sts[2];
-	ha->patch_number = mbox_sts[3];
-	ha->build_number = mbox_sts[4];
+	/* Save version information. */
+	ha->firmware_version[0] = le16_to_cpu(about_fw->fw_major);
+	ha->firmware_version[1] = le16_to_cpu(about_fw->fw_minor);
+	ha->patch_number = le16_to_cpu(about_fw->fw_patch);
+	ha->build_number = le16_to_cpu(about_fw->fw_build);
+	ha->iscsi_major = le16_to_cpu(about_fw->iscsi_major);
+	ha->iscsi_minor = le16_to_cpu(about_fw->iscsi_minor);
+	ha->bootload_major = le16_to_cpu(about_fw->bootload_major);
+	ha->bootload_minor = le16_to_cpu(about_fw->bootload_minor);
+	ha->bootload_patch = le16_to_cpu(about_fw->bootload_patch);
+	ha->bootload_build = le16_to_cpu(about_fw->bootload_build);
+	status = QLA_SUCCESS;
 
-	return QLA_SUCCESS;
+exit_about_fw:
+	dma_free_coherent(&ha->pdev->dev, sizeof(struct about_fw_info),
+			  about_fw, about_fw_dma);
+	return status;
 }
 
 static int qla4xxx_get_default_ddb(struct scsi_qla_host *ha,
diff -druN linux-2.6.39-libre/drivers/scsi/qla4xxx/ql4_nx.c linux-3.0-rc7-libre/drivers/scsi/qla4xxx/ql4_nx.c
--- linux-2.6.39-libre/drivers/scsi/qla4xxx/ql4_nx.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/scsi/qla4xxx/ql4_nx.c	2011-07-11 19:51:52.000000000 -0400
@@ -655,6 +655,27 @@
 	return 0;
 }
 
+#ifndef readq
+static inline __u64 readq(const volatile void __iomem *addr)
+{
+	const volatile u32 __iomem *p = addr;
+	u32 low, high;
+
+	low = readl(p);
+	high = readl(p + 1);
+
+	return low + ((u64)high << 32);
+}
+#endif
+
+#ifndef writeq
+static inline void writeq(__u64 val, volatile void __iomem *addr)
+{
+	writel(val, addr);
+	writel(val >> 32, addr+4);
+}
+#endif
+
 static int qla4_8xxx_pci_mem_read_direct(struct scsi_qla_host *ha,
 		u64 off, void *data, int size)
 {
@@ -943,12 +964,26 @@
 	/* Halt all the indiviual PEGs and other blocks of the ISP */
 	qla4_8xxx_rom_lock(ha);
 
-	/* mask all niu interrupts */
+	/* disable all I2Q */
+	qla4_8xxx_wr_32(ha, QLA82XX_CRB_I2Q + 0x10, 0x0);
+	qla4_8xxx_wr_32(ha, QLA82XX_CRB_I2Q + 0x14, 0x0);
+	qla4_8xxx_wr_32(ha, QLA82XX_CRB_I2Q + 0x18, 0x0);
+	qla4_8xxx_wr_32(ha, QLA82XX_CRB_I2Q + 0x1c, 0x0);
+	qla4_8xxx_wr_32(ha, QLA82XX_CRB_I2Q + 0x20, 0x0);
+	qla4_8xxx_wr_32(ha, QLA82XX_CRB_I2Q + 0x24, 0x0);
+
+	/* disable all niu interrupts */
 	qla4_8xxx_wr_32(ha, QLA82XX_CRB_NIU + 0x40, 0xff);
 	/* disable xge rx/tx */
 	qla4_8xxx_wr_32(ha, QLA82XX_CRB_NIU + 0x70000, 0x00);
 	/* disable xg1 rx/tx */
 	qla4_8xxx_wr_32(ha, QLA82XX_CRB_NIU + 0x80000, 0x00);
+	/* disable sideband mac */
+	qla4_8xxx_wr_32(ha, QLA82XX_CRB_NIU + 0x90000, 0x00);
+	/* disable ap0 mac */
+	qla4_8xxx_wr_32(ha, QLA82XX_CRB_NIU + 0xa0000, 0x00);
+	/* disable ap1 mac */
+	qla4_8xxx_wr_32(ha, QLA82XX_CRB_NIU + 0xb0000, 0x00);
 
 	/* halt sre */
 	val = qla4_8xxx_rd_32(ha, QLA82XX_CRB_SRE + 0x1000);
@@ -963,6 +998,7 @@
 	qla4_8xxx_wr_32(ha, QLA82XX_CRB_TIMER + 0x10, 0x0);
 	qla4_8xxx_wr_32(ha, QLA82XX_CRB_TIMER + 0x18, 0x0);
 	qla4_8xxx_wr_32(ha, QLA82XX_CRB_TIMER + 0x100, 0x0);
+	qla4_8xxx_wr_32(ha, QLA82XX_CRB_TIMER + 0x200, 0x0);
 
 	/* halt pegs */
 	qla4_8xxx_wr_32(ha, QLA82XX_CRB_PEG_NET_0 + 0x3c, 1);
@@ -970,9 +1006,9 @@
 	qla4_8xxx_wr_32(ha, QLA82XX_CRB_PEG_NET_2 + 0x3c, 1);
 	qla4_8xxx_wr_32(ha, QLA82XX_CRB_PEG_NET_3 + 0x3c, 1);
 	qla4_8xxx_wr_32(ha, QLA82XX_CRB_PEG_NET_4 + 0x3c, 1);
+	msleep(5);
 
 	/* big hammer */
-	msleep(1000);
 	if (test_bit(DPC_RESET_HA, &ha->dpc_flags))
 		/* don't reset CAM block on reset */
 		qla4_8xxx_wr_32(ha, QLA82XX_ROMUSB_GLB_SW_RESET, 0xfeffffff);
diff -druN linux-2.6.39-libre/drivers/scsi/qla4xxx/ql4_os.c linux-3.0-rc7-libre/drivers/scsi/qla4xxx/ql4_os.c
--- linux-2.6.39-libre/drivers/scsi/qla4xxx/ql4_os.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/scsi/qla4xxx/ql4_os.c	2011-07-11 19:51:52.000000000 -0400
@@ -124,6 +124,7 @@
 	.sg_tablesize		= SG_ALL,
 
 	.max_sectors		= 0xFFFF,
+	.shost_attrs		= qla4xxx_host_attrs,
 };
 
 static struct iscsi_transport qla4xxx_iscsi_transport = {
@@ -412,8 +413,7 @@
 
 static struct srb* qla4xxx_get_new_srb(struct scsi_qla_host *ha,
 				       struct ddb_entry *ddb_entry,
-				       struct scsi_cmnd *cmd,
-				       void (*done)(struct scsi_cmnd *))
+				       struct scsi_cmnd *cmd)
 {
 	struct srb *srb;
 
@@ -427,7 +427,6 @@
 	srb->cmd = cmd;
 	srb->flags = 0;
 	CMD_SP(cmd) = (void *)srb;
-	cmd->scsi_done = done;
 
 	return srb;
 }
@@ -458,9 +457,8 @@
 
 /**
  * qla4xxx_queuecommand - scsi layer issues scsi command to driver.
+ * @host: scsi host
  * @cmd: Pointer to Linux's SCSI command structure
- * @done_fn: Function that the driver calls to notify the SCSI mid-layer
- *	that the command has been processed.
  *
  * Remarks:
  * This routine is invoked by Linux to send a SCSI command to the driver.
@@ -470,10 +468,9 @@
  * completion handling).   Unfortunely, it sometimes calls the scheduler
  * in interrupt context which is a big NO! NO!.
  **/
-static int qla4xxx_queuecommand_lck(struct scsi_cmnd *cmd,
-				void (*done)(struct scsi_cmnd *))
+static int qla4xxx_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd)
 {
-	struct scsi_qla_host *ha = to_qla_host(cmd->device->host);
+	struct scsi_qla_host *ha = to_qla_host(host);
 	struct ddb_entry *ddb_entry = cmd->device->hostdata;
 	struct iscsi_cls_session *sess = ddb_entry->sess;
 	struct srb *srb;
@@ -515,37 +512,29 @@
 	    test_bit(DPC_RESET_HA_FW_CONTEXT, &ha->dpc_flags))
 		goto qc_host_busy;
 
-	spin_unlock_irq(ha->host->host_lock);
-
-	srb = qla4xxx_get_new_srb(ha, ddb_entry, cmd, done);
+	srb = qla4xxx_get_new_srb(ha, ddb_entry, cmd);
 	if (!srb)
-		goto qc_host_busy_lock;
+		goto qc_host_busy;
 
 	rval = qla4xxx_send_command_to_isp(ha, srb);
 	if (rval != QLA_SUCCESS)
 		goto qc_host_busy_free_sp;
 
-	spin_lock_irq(ha->host->host_lock);
 	return 0;
 
 qc_host_busy_free_sp:
 	qla4xxx_srb_free_dma(ha, srb);
 	mempool_free(srb, ha->srb_mempool);
 
-qc_host_busy_lock:
-	spin_lock_irq(ha->host->host_lock);
-
 qc_host_busy:
 	return SCSI_MLQUEUE_HOST_BUSY;
 
 qc_fail_command:
-	done(cmd);
+	cmd->scsi_done(cmd);
 
 	return 0;
 }
 
-static DEF_SCSI_QCMD(qla4xxx_queuecommand)
-
 /**
  * qla4xxx_mem_free - frees memory allocated to adapter
  * @ha: Pointer to host adapter structure.
@@ -679,7 +668,27 @@
 		if (ha->seconds_since_last_heartbeat == 2) {
 			ha->seconds_since_last_heartbeat = 0;
 			halt_status = qla4_8xxx_rd_32(ha,
-			    QLA82XX_PEG_HALT_STATUS1);
+						      QLA82XX_PEG_HALT_STATUS1);
+
+			ql4_printk(KERN_INFO, ha,
+				   "scsi(%ld): %s, Dumping hw/fw registers:\n "
+				   " PEG_HALT_STATUS1: 0x%x, PEG_HALT_STATUS2:"
+				   " 0x%x,\n PEG_NET_0_PC: 0x%x, PEG_NET_1_PC:"
+				   " 0x%x,\n PEG_NET_2_PC: 0x%x, PEG_NET_3_PC:"
+				   " 0x%x,\n PEG_NET_4_PC: 0x%x\n",
+				   ha->host_no, __func__, halt_status,
+				   qla4_8xxx_rd_32(ha,
+						   QLA82XX_PEG_HALT_STATUS2),
+				   qla4_8xxx_rd_32(ha, QLA82XX_CRB_PEG_NET_0 +
+						   0x3c),
+				   qla4_8xxx_rd_32(ha, QLA82XX_CRB_PEG_NET_1 +
+						   0x3c),
+				   qla4_8xxx_rd_32(ha, QLA82XX_CRB_PEG_NET_2 +
+						   0x3c),
+				   qla4_8xxx_rd_32(ha, QLA82XX_CRB_PEG_NET_3 +
+						   0x3c),
+				   qla4_8xxx_rd_32(ha, QLA82XX_CRB_PEG_NET_4 +
+						   0x3c));
 
 			/* Since we cannot change dev_state in interrupt
 			 * context, set appropriate DPC flag then wakeup
@@ -715,7 +724,7 @@
 	/* don't poll if reset is going on */
 	if (!(test_bit(DPC_RESET_ACTIVE, &ha->dpc_flags) ||
 	    test_bit(DPC_RESET_HA, &ha->dpc_flags) ||
-	    test_bit(DPC_RESET_ACTIVE, &ha->dpc_flags))) {
+	    test_bit(DPC_RETRY_RESET_HA, &ha->dpc_flags))) {
 		if (dev_state == QLA82XX_DEV_NEED_RESET &&
 		    !test_bit(DPC_RESET_HA, &ha->dpc_flags)) {
 			if (!ql4xdontresethba) {
@@ -839,7 +848,7 @@
 	}
 
 	/* Wakeup the dpc routine for this adapter, if needed. */
-	if ((start_dpc ||
+	if (start_dpc ||
 	     test_bit(DPC_RESET_HA, &ha->dpc_flags) ||
 	     test_bit(DPC_RETRY_RESET_HA, &ha->dpc_flags) ||
 	     test_bit(DPC_RELOGIN_DEVICE, &ha->dpc_flags) ||
@@ -849,9 +858,7 @@
 	     test_bit(DPC_LINK_CHANGED, &ha->dpc_flags) ||
 	     test_bit(DPC_HA_UNRECOVERABLE, &ha->dpc_flags) ||
 	     test_bit(DPC_HA_NEED_QUIESCENT, &ha->dpc_flags) ||
-	     test_bit(DPC_AEN, &ha->dpc_flags)) &&
-	     !test_bit(AF_DPC_SCHEDULED, &ha->flags) &&
-	     ha->dpc_thread) {
+	     test_bit(DPC_AEN, &ha->dpc_flags)) {
 		DEBUG2(printk("scsi%ld: %s: scheduling dpc routine"
 			      " - dpc flags = 0x%lx\n",
 			      ha->host_no, __func__, ha->dpc_flags));
@@ -1241,11 +1248,8 @@
 
 void qla4xxx_wake_dpc(struct scsi_qla_host *ha)
 {
-	if (ha->dpc_thread &&
-	    !test_bit(AF_DPC_SCHEDULED, &ha->flags)) {
-		set_bit(AF_DPC_SCHEDULED, &ha->flags);
+	if (ha->dpc_thread)
 		queue_work(ha->dpc_thread, &ha->dpc_work);
-	}
 }
 
 /**
@@ -1272,12 +1276,12 @@
 
 	/* Initialization not yet finished. Don't do anything yet. */
 	if (!test_bit(AF_INIT_DONE, &ha->flags))
-		goto do_dpc_exit;
+		return;
 
 	if (test_bit(AF_EEH_BUSY, &ha->flags)) {
 		DEBUG2(printk(KERN_INFO "scsi%ld: %s: flags = %lx\n",
 		    ha->host_no, __func__, ha->flags));
-		goto do_dpc_exit;
+		return;
 	}
 
 	if (is_qla8022(ha)) {
@@ -1384,8 +1388,6 @@
 		}
 	}
 
-do_dpc_exit:
-	clear_bit(AF_DPC_SCHEDULED, &ha->flags);
 }
 
 /**
@@ -2068,15 +2070,14 @@
 	struct scsi_qla_host *ha = to_qla_host(cmd->device->host);
 	unsigned int id = cmd->device->id;
 	unsigned int lun = cmd->device->lun;
-	unsigned long serial = cmd->serial_number;
 	unsigned long flags;
 	struct srb *srb = NULL;
 	int ret = SUCCESS;
 	int wait = 0;
 
 	ql4_printk(KERN_INFO, ha,
-	    "scsi%ld:%d:%d: Abort command issued cmd=%p, pid=%ld\n",
-	    ha->host_no, id, lun, cmd, serial);
+	    "scsi%ld:%d:%d: Abort command issued cmd=%p\n",
+	    ha->host_no, id, lun, cmd);
 
 	spin_lock_irqsave(&ha->hardware_lock, flags);
 	srb = (struct srb *) CMD_SP(cmd);
diff -druN linux-2.6.39-libre/drivers/scsi/qla4xxx/ql4_version.h linux-3.0-rc7-libre/drivers/scsi/qla4xxx/ql4_version.h
--- linux-2.6.39-libre/drivers/scsi/qla4xxx/ql4_version.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/scsi/qla4xxx/ql4_version.h	2011-07-11 19:51:52.000000000 -0400
@@ -5,4 +5,4 @@
  * See LICENSE.qla4xxx for copyright and licensing details.
  */
 
-#define QLA4XXX_DRIVER_VERSION	"5.02.00-k6"
+#define QLA4XXX_DRIVER_VERSION	"5.02.00-k7"
diff -druN linux-2.6.39-libre/drivers/scsi/scsi_error.c linux-3.0-rc7-libre/drivers/scsi/scsi_error.c
--- linux-2.6.39-libre/drivers/scsi/scsi_error.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/scsi/scsi_error.c	2011-07-11 19:51:52.000000000 -0400
@@ -50,6 +50,8 @@
 #define BUS_RESET_SETTLE_TIME   (10)
 #define HOST_RESET_SETTLE_TIME  (10)
 
+static int scsi_eh_try_stu(struct scsi_cmnd *scmd);
+
 /* called with shost->host_lock held */
 void scsi_eh_wakeup(struct Scsi_Host *shost)
 {
@@ -321,6 +323,12 @@
 				    "changed. The Linux SCSI layer does not "
 				    "automatically adjust these parameters.\n");
 
+		if (sshdr.asc == 0x38 && sshdr.ascq == 0x07)
+			scmd_printk(KERN_WARNING, scmd,
+				    "Warning! Received an indication that the "
+				    "LUN reached a thin provisioning soft "
+				    "threshold.\n");
+
 		/*
 		 * Pass the UA upwards for a determination in the completion
 		 * functions.
@@ -941,6 +949,48 @@
 }
 
 /**
+ * scsi_eh_test_devices - check if devices are responding from error recovery.
+ * @cmd_list:	scsi commands in error recovery.
+ * @work_q:     queue for commands which still need more error recovery
+ * @done_q:     queue for commands which are finished
+ * @try_stu:    boolean on if a STU command should be tried in addition to TUR.
+ *
+ * Decription:
+ *    Tests if devices are in a working state.  Commands to devices now in
+ *    a working state are sent to the done_q while commands to devices which
+ *    are still failing to respond are returned to the work_q for more
+ *    processing.
+ **/
+static int scsi_eh_test_devices(struct list_head *cmd_list,
+				struct list_head *work_q,
+				struct list_head *done_q, int try_stu)
+{
+	struct scsi_cmnd *scmd, *next;
+	struct scsi_device *sdev;
+	int finish_cmds;
+
+	while (!list_empty(cmd_list)) {
+		scmd = list_entry(cmd_list->next, struct scsi_cmnd, eh_entry);
+		sdev = scmd->device;
+
+		finish_cmds = !scsi_device_online(scmd->device) ||
+			(try_stu && !scsi_eh_try_stu(scmd) &&
+			 !scsi_eh_tur(scmd)) ||
+			!scsi_eh_tur(scmd);
+
+		list_for_each_entry_safe(scmd, next, cmd_list, eh_entry)
+			if (scmd->device == sdev) {
+				if (finish_cmds)
+					scsi_eh_finish_cmd(scmd, done_q);
+				else
+					list_move_tail(&scmd->eh_entry, work_q);
+			}
+	}
+	return list_empty(work_q);
+}
+
+
+/**
  * scsi_eh_abort_cmds - abort pending commands.
  * @work_q:	&list_head for pending commands.
  * @done_q:	&list_head for processed commands.
@@ -956,6 +1006,7 @@
 			      struct list_head *done_q)
 {
 	struct scsi_cmnd *scmd, *next;
+	LIST_HEAD(check_list);
 	int rtn;
 
 	list_for_each_entry_safe(scmd, next, work_q, eh_entry) {
@@ -967,11 +1018,10 @@
 		rtn = scsi_try_to_abort_cmd(scmd->device->host->hostt, scmd);
 		if (rtn == SUCCESS || rtn == FAST_IO_FAIL) {
 			scmd->eh_eflags &= ~SCSI_EH_CANCEL_CMD;
-			if (!scsi_device_online(scmd->device) ||
-			    rtn == FAST_IO_FAIL ||
-			    !scsi_eh_tur(scmd)) {
+			if (rtn == FAST_IO_FAIL)
 				scsi_eh_finish_cmd(scmd, done_q);
-			}
+			else
+				list_move_tail(&scmd->eh_entry, &check_list);
 		} else
 			SCSI_LOG_ERROR_RECOVERY(3, printk("%s: aborting"
 							  " cmd failed:"
@@ -980,7 +1030,7 @@
 							  scmd));
 	}
 
-	return list_empty(work_q);
+	return scsi_eh_test_devices(&check_list, work_q, done_q, 0);
 }
 
 /**
@@ -1131,6 +1181,7 @@
 				struct list_head *done_q)
 {
 	LIST_HEAD(tmp_list);
+	LIST_HEAD(check_list);
 
 	list_splice_init(work_q, &tmp_list);
 
@@ -1155,9 +1206,9 @@
 			if (scmd_id(scmd) != id)
 				continue;
 
-			if ((rtn == SUCCESS || rtn == FAST_IO_FAIL)
-			    && (!scsi_device_online(scmd->device) ||
-				 rtn == FAST_IO_FAIL || !scsi_eh_tur(scmd)))
+			if (rtn == SUCCESS)
+				list_move_tail(&scmd->eh_entry, &check_list);
+			else if (rtn == FAST_IO_FAIL)
 				scsi_eh_finish_cmd(scmd, done_q);
 			else
 				/* push back on work queue for further processing */
@@ -1165,7 +1216,7 @@
 		}
 	}
 
-	return list_empty(work_q);
+	return scsi_eh_test_devices(&check_list, work_q, done_q, 0);
 }
 
 /**
@@ -1179,6 +1230,7 @@
 			     struct list_head *done_q)
 {
 	struct scsi_cmnd *scmd, *chan_scmd, *next;
+	LIST_HEAD(check_list);
 	unsigned int channel;
 	int rtn;
 
@@ -1210,12 +1262,14 @@
 		rtn = scsi_try_bus_reset(chan_scmd);
 		if (rtn == SUCCESS || rtn == FAST_IO_FAIL) {
 			list_for_each_entry_safe(scmd, next, work_q, eh_entry) {
-				if (channel == scmd_channel(scmd))
-					if (!scsi_device_online(scmd->device) ||
-					    rtn == FAST_IO_FAIL ||
-					    !scsi_eh_tur(scmd))
+				if (channel == scmd_channel(scmd)) {
+					if (rtn == FAST_IO_FAIL)
 						scsi_eh_finish_cmd(scmd,
 								   done_q);
+					else
+						list_move_tail(&scmd->eh_entry,
+							       &check_list);
+				}
 			}
 		} else {
 			SCSI_LOG_ERROR_RECOVERY(3, printk("%s: BRST"
@@ -1224,7 +1278,7 @@
 							  channel));
 		}
 	}
-	return list_empty(work_q);
+	return scsi_eh_test_devices(&check_list, work_q, done_q, 0);
 }
 
 /**
@@ -1236,6 +1290,7 @@
 			      struct list_head *done_q)
 {
 	struct scsi_cmnd *scmd, *next;
+	LIST_HEAD(check_list);
 	int rtn;
 
 	if (!list_empty(work_q)) {
@@ -1246,12 +1301,10 @@
 						  , current->comm));
 
 		rtn = scsi_try_host_reset(scmd);
-		if (rtn == SUCCESS || rtn == FAST_IO_FAIL) {
+		if (rtn == SUCCESS) {
+			list_splice_init(work_q, &check_list);
+		} else if (rtn == FAST_IO_FAIL) {
 			list_for_each_entry_safe(scmd, next, work_q, eh_entry) {
-				if (!scsi_device_online(scmd->device) ||
-				    rtn == FAST_IO_FAIL ||
-				    (!scsi_eh_try_stu(scmd) && !scsi_eh_tur(scmd)) ||
-				    !scsi_eh_tur(scmd))
 					scsi_eh_finish_cmd(scmd, done_q);
 			}
 		} else {
@@ -1260,7 +1313,7 @@
 							  current->comm));
 		}
 	}
-	return list_empty(work_q);
+	return scsi_eh_test_devices(&check_list, work_q, done_q, 1);
 }
 
 /**
diff -druN linux-2.6.39-libre/drivers/scsi/scsi_proc.c linux-3.0-rc7-libre/drivers/scsi/scsi_proc.c
--- linux-2.6.39-libre/drivers/scsi/scsi_proc.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/scsi/scsi_proc.c	2011-07-11 19:51:52.000000000 -0400
@@ -381,18 +381,59 @@
 	return err;
 }
 
-/**
- * proc_scsi_show - show contents of /proc/scsi/scsi (attached devices)
- * @s: output goes here
- * @p: not used
- */
-static int proc_scsi_show(struct seq_file *s, void *p)
+static int always_match(struct device *dev, void *data)
 {
-	seq_printf(s, "Attached devices:\n");
-	bus_for_each_dev(&scsi_bus_type, NULL, s, proc_print_scsidevice);
-	return 0;
+	return 1;
+}
+
+static inline struct device *next_scsi_device(struct device *start)
+{
+	struct device *next = bus_find_device(&scsi_bus_type, start, NULL,
+					      always_match);
+	put_device(start);
+	return next;
+}
+
+static void *scsi_seq_start(struct seq_file *sfile, loff_t *pos)
+{
+	struct device *dev = NULL;
+	loff_t n = *pos;
+
+	while ((dev = next_scsi_device(dev))) {
+		if (!n--)
+			break;
+		sfile->private++;
+	}
+	return dev;
 }
 
+static void *scsi_seq_next(struct seq_file *sfile, void *v, loff_t *pos)
+{
+	(*pos)++;
+	sfile->private++;
+	return next_scsi_device(v);
+}
+
+static void scsi_seq_stop(struct seq_file *sfile, void *v)
+{
+	put_device(v);
+}
+
+static int scsi_seq_show(struct seq_file *sfile, void *dev)
+{
+	if (!sfile->private)
+		seq_puts(sfile, "Attached devices:\n");
+
+	return proc_print_scsidevice(dev, sfile);
+}
+
+static const struct seq_operations scsi_seq_ops = {
+	.start	= scsi_seq_start,
+	.next	= scsi_seq_next,
+	.stop	= scsi_seq_stop,
+	.show	= scsi_seq_show
+};
+
 /**
  * proc_scsi_open - glue function
  * @inode: not used
@@ -406,7 +447,7 @@
 	 * We don't really need this for the write case but it doesn't
 	 * harm either.
 	 */
-	return single_open(file, proc_scsi_show, NULL);
+	return seq_open(file, &scsi_seq_ops);
 }
 
 static const struct file_operations proc_scsi_operations = {
@@ -415,7 +456,7 @@
 	.read		= seq_read,
 	.write		= proc_scsi_write,
 	.llseek		= seq_lseek,
-	.release	= single_release,
+	.release	= seq_release,
 };
 
 /**
diff -druN linux-2.6.39-libre/drivers/scsi/scsi_scan.c linux-3.0-rc7-libre/drivers/scsi/scsi_scan.c
--- linux-2.6.39-libre/drivers/scsi/scsi_scan.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/scsi/scsi_scan.c	2011-07-11 19:51:52.000000000 -0400
@@ -297,7 +297,7 @@
 		kfree(sdev);
 		goto out;
 	}
-
+	blk_get_queue(sdev->request_queue);
 	sdev->request_queue->queuedata = sdev;
 	scsi_adjust_queue_depth(sdev, 0, sdev->host->cmd_per_lun);
 
diff -druN linux-2.6.39-libre/drivers/scsi/scsi_sysfs.c linux-3.0-rc7-libre/drivers/scsi/scsi_sysfs.c
--- linux-2.6.39-libre/drivers/scsi/scsi_sysfs.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/scsi/scsi_sysfs.c	2011-07-11 19:51:52.000000000 -0400
@@ -322,6 +322,7 @@
 		kfree(evt);
 	}
 
+	blk_put_queue(sdev->request_queue);
 	/* NULL queue means the device can't be used */
 	sdev->request_queue = NULL;
 
diff -druN linux-2.6.39-libre/drivers/scsi/scsi_tgt_lib.c linux-3.0-rc7-libre/drivers/scsi/scsi_tgt_lib.c
--- linux-2.6.39-libre/drivers/scsi/scsi_tgt_lib.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/scsi/scsi_tgt_lib.c	2011-07-11 19:51:52.000000000 -0400
@@ -275,10 +275,8 @@
 
 	for (i = 0; i < ARRAY_SIZE(qdata->cmd_hash); i++) {
 		list_for_each_entry_safe(tcmd, n, &qdata->cmd_hash[i],
-					 hash_list) {
-			list_del(&tcmd->hash_list);
-			list_add(&tcmd->hash_list, &cmds);
-		}
+					 hash_list)
+			list_move(&tcmd->hash_list, &cmds);
 	}
 
 	spin_unlock_irqrestore(&qdata->cmd_hash_lock, flags);
diff -druN linux-2.6.39-libre/drivers/scsi/scsi_trace.c linux-3.0-rc7-libre/drivers/scsi/scsi_trace.c
--- linux-2.6.39-libre/drivers/scsi/scsi_trace.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/scsi/scsi_trace.c	2011-07-11 19:51:52.000000000 -0400
@@ -59,6 +59,10 @@
 	trace_seq_printf(p, "lba=%llu txlen=%llu protect=%u",
 			 (unsigned long long)lba, (unsigned long long)txlen,
 			 cdb[1] >> 5);
+
+	if (cdb[0] == WRITE_SAME)
+		trace_seq_printf(p, " unmap=%u", cdb[1] >> 3 & 1);
+
 	trace_seq_putc(p, 0);
 
 	return ret;
diff -druN linux-2.6.39-libre/drivers/scsi/scsi_transport_fc.c linux-3.0-rc7-libre/drivers/scsi/scsi_transport_fc.c
--- linux-2.6.39-libre/drivers/scsi/scsi_transport_fc.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/scsi/scsi_transport_fc.c	2011-07-11 19:51:52.000000000 -0400
@@ -422,8 +422,7 @@
 
 	snprintf(fc_host->work_q_name, sizeof(fc_host->work_q_name),
 		 "fc_wq_%d", shost->host_no);
-	fc_host->work_q = create_singlethread_workqueue(
-					fc_host->work_q_name);
+	fc_host->work_q = alloc_workqueue(fc_host->work_q_name, 0, 0);
 	if (!fc_host->work_q)
 		return -ENOMEM;
 
@@ -431,8 +430,8 @@
 	snprintf(fc_host->devloss_work_q_name,
 		 sizeof(fc_host->devloss_work_q_name),
 		 "fc_dl_%d", shost->host_no);
-	fc_host->devloss_work_q = create_singlethread_workqueue(
-					fc_host->devloss_work_q_name);
+	fc_host->devloss_work_q =
+			alloc_workqueue(fc_host->devloss_work_q_name, 0, 0);
 	if (!fc_host->devloss_work_q) {
 		destroy_workqueue(fc_host->work_q);
 		fc_host->work_q = NULL;
@@ -2489,6 +2488,8 @@
 	unsigned long flags;
 	int do_callback = 0;
 
+	fc_terminate_rport_io(rport);
+
 	/*
 	 * if a scan is pending, flush the SCSI Host work_q so that
 	 * that we can reclaim the rport scan work element.
@@ -2496,8 +2497,6 @@
 	if (rport->flags & FC_RPORT_SCAN_PENDING)
 		scsi_flush_work(shost);
 
-	fc_terminate_rport_io(rport);
-
 	/*
 	 * Cancel any outstanding timers. These should really exist
 	 * only when rmmod'ing the LLDD and we're asking for
diff -druN linux-2.6.39-libre/drivers/scsi/sd.c linux-3.0-rc7-libre/drivers/scsi/sd.c
--- linux-2.6.39-libre/drivers/scsi/sd.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/scsi/sd.c	2011-07-11 19:51:52.000000000 -0400
@@ -490,7 +490,8 @@
 	unsigned int max_blocks = 0;
 
 	q->limits.discard_zeroes_data = sdkp->lbprz;
-	q->limits.discard_alignment = sdkp->unmap_alignment;
+	q->limits.discard_alignment = sdkp->unmap_alignment *
+		logical_block_size;
 	q->limits.discard_granularity =
 		max(sdkp->physical_block_size,
 		    sdkp->unmap_granularity * logical_block_size);
@@ -2021,16 +2022,26 @@
 
 	int dbd;
 	int modepage;
+	int first_len;
 	struct scsi_mode_data data;
 	struct scsi_sense_hdr sshdr;
 	int old_wce = sdkp->WCE;
 	int old_rcd = sdkp->RCD;
 	int old_dpofua = sdkp->DPOFUA;
 
-	if (sdp->skip_ms_page_8)
-		goto defaults;
-
-	if (sdp->type == TYPE_RBC) {
+	first_len = 4;
+	if (sdp->skip_ms_page_8) {
+		if (sdp->type == TYPE_RBC)
+			goto defaults;
+		else {
+			if (sdp->skip_ms_page_3f)
+				goto defaults;
+			modepage = 0x3F;
+			if (sdp->use_192_bytes_for_3f)
+				first_len = 192;
+			dbd = 0;
+		}
+	} else if (sdp->type == TYPE_RBC) {
 		modepage = 6;
 		dbd = 8;
 	} else {
@@ -2039,13 +2050,15 @@
 	}
 
 	/* cautiously ask */
-	res = sd_do_mode_sense(sdp, dbd, modepage, buffer, 4, &data, &sshdr);
+	res = sd_do_mode_sense(sdp, dbd, modepage, buffer, first_len,
+			&data, &sshdr);
 
 	if (!scsi_status_is_good(res))
 		goto bad_sense;
 
 	if (!data.header_length) {
 		modepage = 6;
+		first_len = 0;
 		sd_printk(KERN_ERR, sdkp, "Missing header in MODE_SENSE response\n");
 	}
 
@@ -2058,30 +2071,61 @@
 	 */
 	if (len < 3)
 		goto bad_sense;
-	if (len > 20)
-		len = 20;
-
-	/* Take headers and block descriptors into account */
-	len += data.header_length + data.block_descriptor_length;
-	if (len > SD_BUF_SIZE)
-		goto bad_sense;
+	else if (len > SD_BUF_SIZE) {
+		sd_printk(KERN_NOTICE, sdkp, "Truncating mode parameter "
+			  "data from %d to %d bytes\n", len, SD_BUF_SIZE);
+		len = SD_BUF_SIZE;
+	}
+	if (modepage == 0x3F && sdp->use_192_bytes_for_3f)
+		len = 192;
 
 	/* Get the data */
-	res = sd_do_mode_sense(sdp, dbd, modepage, buffer, len, &data, &sshdr);
+	if (len > first_len)
+		res = sd_do_mode_sense(sdp, dbd, modepage, buffer, len,
+				&data, &sshdr);
 
 	if (scsi_status_is_good(res)) {
 		int offset = data.header_length + data.block_descriptor_length;
 
-		if (offset >= SD_BUF_SIZE - 2) {
-			sd_printk(KERN_ERR, sdkp, "Malformed MODE SENSE response\n");
-			goto defaults;
+		while (offset < len) {
+			u8 page_code = buffer[offset] & 0x3F;
+			u8 spf       = buffer[offset] & 0x40;
+
+			if (page_code == 8 || page_code == 6) {
+				/* We're interested only in the first 3 bytes.
+				 */
+				if (len - offset <= 2) {
+					sd_printk(KERN_ERR, sdkp, "Incomplete "
+						  "mode parameter data\n");
+					goto defaults;
+				} else {
+					modepage = page_code;
+					goto Page_found;
+				}
+			} else {
+				/* Go to the next page */
+				if (spf && len - offset > 3)
+					offset += 4 + (buffer[offset+2] << 8) +
+						buffer[offset+3];
+				else if (!spf && len - offset > 1)
+					offset += 2 + buffer[offset+1];
+				else {
+					sd_printk(KERN_ERR, sdkp, "Incomplete "
+						  "mode parameter data\n");
+					goto defaults;
+				}
+			}
 		}
 
-		if ((buffer[offset] & 0x3f) != modepage) {
+		if (modepage == 0x3F) {
+			sd_printk(KERN_ERR, sdkp, "No Caching mode page "
+				  "present\n");
+			goto defaults;
+		} else if ((buffer[offset] & 0x3f) != modepage) {
 			sd_printk(KERN_ERR, sdkp, "Got wrong page\n");
 			goto defaults;
 		}
-
+	Page_found:
 		if (modepage == 8) {
 			sdkp->WCE = ((buffer[offset + 2] & 0x04) != 0);
 			sdkp->RCD = ((buffer[offset + 2] & 0x01) != 0);
diff -druN linux-2.6.39-libre/drivers/scsi/sgiwd93.c linux-3.0-rc7-libre/drivers/scsi/sgiwd93.c
--- linux-2.6.39-libre/drivers/scsi/sgiwd93.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/scsi/sgiwd93.c	2011-07-11 19:51:52.000000000 -0400
@@ -3,7 +3,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
+ * Copyright (C) 1996 David S. Miller (davem@davemloft.net)
  * Copyright (C) 1999 Andrew R. Baker (andrewb@uab.edu)
  * Copyright (C) 2001 Florian Lohoff (flo@rfc822.org)
  * Copyright (C) 2003, 07 Ralf Baechle (ralf@linux-mips.org)
diff -druN linux-2.6.39-libre/drivers/scsi/sr.c linux-3.0-rc7-libre/drivers/scsi/sr.c
--- linux-2.6.39-libre/drivers/scsi/sr.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/scsi/sr.c	2011-07-11 19:51:52.000000000 -0400
@@ -636,7 +636,7 @@
 	disk->first_minor = minor;
 	sprintf(disk->disk_name, "sr%d", minor);
 	disk->fops = &sr_bdops;
-	disk->flags = GENHD_FL_CD;
+	disk->flags = GENHD_FL_CD | GENHD_FL_BLOCK_EVENTS_ON_EXCL_WRITE;
 	disk->events = DISK_EVENT_MEDIA_CHANGE | DISK_EVENT_EJECT_REQUEST;
 
 	blk_queue_rq_timeout(sdev->request_queue, SR_TIMEOUT);
diff -druN linux-2.6.39-libre/drivers/scsi/tmscsim.c linux-3.0-rc7-libre/drivers/scsi/tmscsim.c
--- linux-2.6.39-libre/drivers/scsi/tmscsim.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/scsi/tmscsim.c	2011-07-11 19:51:52.000000000 -0400
@@ -565,12 +565,12 @@
 	pDCB->TagMask |= 1 << tag[1];
 	pSRB->TagNumber = tag[1];
 	DC390_write8(ScsiFifo, tag[1]);
-	DEBUG1(printk(KERN_INFO "DC390: Select w/DisCn for Cmd %li (SRB %p), block tag %02x\n", scmd->serial_number, pSRB, tag[1]));
+	DEBUG1(printk(KERN_INFO "DC390: Select w/DisCn for SRB %p, block tag %02x\n", pSRB, tag[1]));
 	cmd = SEL_W_ATN3;
     } else {
 	/* No TagQ */
 //no_tag:
-	DEBUG1(printk(KERN_INFO "DC390: Select w%s/DisCn for Cmd %li (SRB %p), No TagQ\n", disc_allowed ? "" : "o", scmd->serial_number, pSRB));
+	DEBUG1(printk(KERN_INFO "DC390: Select w%s/DisCn for SRB %p, No TagQ\n", disc_allowed ? "" : "o", pSRB));
     }
 
     pSRB->SRBState = SRB_START_;
@@ -620,8 +620,8 @@
     if (DC390_read8 (Scsi_Status) & INTERRUPT)
     {
 	dc390_freetag (pDCB, pSRB);
-	DEBUG0(printk ("DC390: Interrupt during Start SCSI (pid %li, target %02i-%02i)\n",
-		scmd->serial_number, scmd->device->id, scmd->device->lun));
+	DEBUG0(printk ("DC390: Interrupt during Start SCSI (target %02i-%02i)\n",
+		scmd->device->id, scmd->device->lun));
 	pSRB->SRBState = SRB_READY;
 	//DC390_write8 (ScsiCmd, CLEAR_FIFO_CMD);
 	pACB->SelLost++;
@@ -1705,8 +1705,7 @@
 
     status = pSRB->TargetStatus;
 
-    DEBUG0(printk (" SRBdone (%02x,%08x), SRB %p, pid %li\n", status, pcmd->result,\
-		pSRB, pcmd->serial_number));
+    DEBUG0(printk (" SRBdone (%02x,%08x), SRB %p\n", status, pcmd->result, pSRB));
     if(pSRB->SRBFlag & AUTO_REQSENSE)
     {	/* Last command was a Request Sense */
 	pSRB->SRBFlag &= ~AUTO_REQSENSE;
@@ -1727,7 +1726,7 @@
 	    } else {
 		SET_RES_DRV(pcmd->result, DRIVER_SENSE);
 		//pSRB->ScsiCmdLen	 = (u8) (pSRB->Segment1[0] >> 8);
-		DEBUG0 (printk ("DC390: RETRY pid %li (%02x), target %02i-%02i\n", pcmd->serial_number, pcmd->cmnd[0], pcmd->device->id, pcmd->device->lun));
+		DEBUG0 (printk ("DC390: RETRY (%02x), target %02i-%02i\n", pcmd->cmnd[0], pcmd->device->id, pcmd->device->lun));
 		pSRB->TotalXferredLen = 0;
 		SET_RES_DID(pcmd->result, DID_SOFT_ERROR);
 	    }
@@ -1747,7 +1746,7 @@
 	else if (status == SAM_STAT_TASK_SET_FULL)
 	{
 	    scsi_track_queue_full(pcmd->device, pDCB->GoingSRBCnt - 1);
-	    DEBUG0 (printk ("DC390: RETRY pid %li (%02x), target %02i-%02i\n", pcmd->serial_number, pcmd->cmnd[0], pcmd->device->id, pcmd->device->lun));
+	    DEBUG0 (printk ("DC390: RETRY (%02x), target %02i-%02i\n", pcmd->cmnd[0], pcmd->device->id, pcmd->device->lun));
 	    pSRB->TotalXferredLen = 0;
 	    SET_RES_DID(pcmd->result, DID_SOFT_ERROR);
 	}
@@ -1801,7 +1800,7 @@
     /* Add to free list */
     dc390_Free_insert (pACB, pSRB);
 
-    DEBUG0(printk (KERN_DEBUG "DC390: SRBdone: done pid %li\n", pcmd->serial_number));
+    DEBUG0(printk (KERN_DEBUG "DC390: SRBdone: done\n"));
     pcmd->scsi_done (pcmd);
 
     return;
@@ -1997,8 +1996,7 @@
 	struct dc390_acb *pACB = (struct dc390_acb*) cmd->device->host->hostdata;
 	struct dc390_dcb *pDCB = (struct dc390_dcb*) cmd->device->hostdata;
 
-	scmd_printk(KERN_WARNING, cmd,
-		"DC390: Abort command (pid %li)\n", cmd->serial_number);
+	scmd_printk(KERN_WARNING, cmd, "DC390: Abort command\n");
 
 	/* abort() is too stupid for already sent commands at the moment. 
 	 * If it's called we are in trouble anyway, so let's dump some info 
@@ -2006,7 +2004,7 @@
 	dc390_dumpinfo(pACB, pDCB, NULL);
 
 	pDCB->DCBFlag |= ABORT_DEV_;
-	printk(KERN_INFO "DC390: Aborted pid %li\n", cmd->serial_number);
+	printk(KERN_INFO "DC390: Aborted.\n");
 
 	return FAILED;
 }
diff -druN linux-2.6.39-libre/drivers/scsi/u14-34f.c linux-3.0-rc7-libre/drivers/scsi/u14-34f.c
--- linux-2.6.39-libre/drivers/scsi/u14-34f.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/scsi/u14-34f.c	2011-07-11 19:51:52.000000000 -0400
@@ -1256,8 +1256,8 @@
    j = ((struct hostdata *) SCpnt->device->host->hostdata)->board_number;
 
    if (SCpnt->host_scribble)
-      panic("%s: qcomm, pid %ld, SCpnt %p already active.\n",
-            BN(j), SCpnt->serial_number, SCpnt);
+      panic("%s: qcomm, SCpnt %p already active.\n",
+            BN(j), SCpnt);
 
    /* i is the mailbox number, look for the first free mailbox
       starting from last_cp_used */
@@ -1286,9 +1286,9 @@
    cpp->cpp_index = i;
    SCpnt->host_scribble = (unsigned char *) &cpp->cpp_index;
 
-   if (do_trace) printk("%s: qcomm, mbox %d, target %d.%d:%d, pid %ld.\n",
+   if (do_trace) printk("%s: qcomm, mbox %d, target %d.%d:%d.\n",
                         BN(j), i, SCpnt->device->channel, SCpnt->device->id,
-                        SCpnt->device->lun, SCpnt->serial_number);
+                        SCpnt->device->lun);
 
    cpp->opcode = OP_SCSI;
    cpp->channel = SCpnt->device->channel;
@@ -1315,7 +1315,7 @@
       unmap_dma(i, j);
       SCpnt->host_scribble = NULL;
       scmd_printk(KERN_INFO, SCpnt,
-      		"qcomm, pid %ld, adapter busy.\n", SCpnt->serial_number);
+      		"qcomm, adapter busy.\n");
       return 1;
       }
 
@@ -1337,14 +1337,12 @@
    j = ((struct hostdata *) SCarg->device->host->hostdata)->board_number;
 
    if (SCarg->host_scribble == NULL) {
-      scmd_printk(KERN_INFO, SCarg, "abort, pid %ld inactive.\n",
-             SCarg->serial_number);
+      scmd_printk(KERN_INFO, SCarg, "abort, command inactive.\n");
       return SUCCESS;
       }
 
    i = *(unsigned int *)SCarg->host_scribble;
-   scmd_printk(KERN_INFO, SCarg, "abort, mbox %d, pid %ld.\n",
-	       i, SCarg->serial_number);
+   scmd_printk(KERN_INFO, SCarg, "abort, mbox %d.\n", i);
 
    if (i >= sh[j]->can_queue)
       panic("%s: abort, invalid SCarg->host_scribble.\n", BN(j));
@@ -1387,8 +1385,7 @@
       SCarg->result = DID_ABORT << 16;
       SCarg->host_scribble = NULL;
       HD(j)->cp_stat[i] = FREE;
-      printk("%s, abort, mbox %d ready, DID_ABORT, pid %ld done.\n",
-             BN(j), i, SCarg->serial_number);
+      printk("%s, abort, mbox %d ready, DID_ABORT, done.\n", BN(j), i);
       SCarg->scsi_done(SCarg);
       return SUCCESS;
       }
@@ -1403,12 +1400,12 @@
    struct scsi_cmnd *SCpnt;
 
    j = ((struct hostdata *) SCarg->device->host->hostdata)->board_number;
-   scmd_printk(KERN_INFO, SCarg, "reset, enter, pid %ld.\n", SCarg->serial_number);
+   scmd_printk(KERN_INFO, SCarg, "reset, enter.\n");
 
    spin_lock_irq(sh[j]->host_lock);
 
    if (SCarg->host_scribble == NULL)
-      printk("%s: reset, pid %ld inactive.\n", BN(j), SCarg->serial_number);
+      printk("%s: reset, inactive.\n", BN(j));
 
    if (HD(j)->in_reset) {
       printk("%s: reset, exit, already in reset.\n", BN(j));
@@ -1445,14 +1442,12 @@
 
       if (HD(j)->cp_stat[i] == READY || HD(j)->cp_stat[i] == ABORTING) {
          HD(j)->cp_stat[i] = ABORTING;
-         printk("%s: reset, mbox %d aborting, pid %ld.\n",
-                BN(j), i, SCpnt->serial_number);
+         printk("%s: reset, mbox %d aborting.\n", BN(j), i);
          }
 
       else {
          HD(j)->cp_stat[i] = IN_RESET;
-         printk("%s: reset, mbox %d in reset, pid %ld.\n",
-                BN(j), i, SCpnt->serial_number);
+         printk("%s: reset, mbox %d in reset.\n", BN(j), i);
          }
 
       if (SCpnt->host_scribble == NULL)
@@ -1500,8 +1495,7 @@
          /* This mailbox is still waiting for its interrupt */
          HD(j)->cp_stat[i] = LOCKED;
 
-         printk("%s, reset, mbox %d locked, DID_RESET, pid %ld done.\n",
-                BN(j), i, SCpnt->serial_number);
+         printk("%s, reset, mbox %d locked, DID_RESET, done.\n", BN(j), i);
          }
 
       else if (HD(j)->cp_stat[i] == ABORTING) {
@@ -1513,8 +1507,7 @@
          /* This mailbox was never queued to the adapter */
          HD(j)->cp_stat[i] = FREE;
 
-         printk("%s, reset, mbox %d aborting, DID_RESET, pid %ld done.\n",
-                BN(j), i, SCpnt->serial_number);
+         printk("%s, reset, mbox %d aborting, DID_RESET, done.\n", BN(j), i);
          }
 
       else
@@ -1528,7 +1521,7 @@
    HD(j)->in_reset = FALSE;
    do_trace = FALSE;
 
-   if (arg_done) printk("%s: reset, exit, pid %ld done.\n", BN(j), SCarg->serial_number);
+   if (arg_done) printk("%s: reset, exit, done.\n", BN(j));
    else          printk("%s: reset, exit.\n", BN(j));
 
    spin_unlock_irq(sh[j]->host_lock);
@@ -1671,10 +1664,10 @@
    if (link_statistics && (overlap || !(flushcount % link_statistics)))
       for (n = 0; n < n_ready; n++) {
          k = il[n]; cpp = &HD(j)->cp[k]; SCpnt = cpp->SCpnt;
-         printk("%s %d.%d:%d pid %ld mb %d fc %d nr %d sec %ld ns %u"\
+         printk("%s %d.%d:%d mb %d fc %d nr %d sec %ld ns %u"\
                 " cur %ld s:%c r:%c rev:%c in:%c ov:%c xd %d.\n",
                 (ihdlr ? "ihdlr" : "qcomm"), SCpnt->channel, SCpnt->target,
-                SCpnt->lun, SCpnt->serial_number, k, flushcount, n_ready,
+                SCpnt->lun, k, flushcount, n_ready,
                 blk_rq_pos(SCpnt->request), blk_rq_sectors(SCpnt->request),
 		cursec, YESNO(s), YESNO(r), YESNO(rev), YESNO(input_only),
                 YESNO(overlap), cpp->xdir);
@@ -1709,9 +1702,9 @@
 
       if (wait_on_busy(sh[j]->io_port, MAXLOOP)) {
          scmd_printk(KERN_INFO, SCpnt,
-	 	"%s, pid %ld, mbox %d, adapter"
+	 	"%s, mbox %d, adapter"
                 " busy, will abort.\n", (ihdlr ? "ihdlr" : "qcomm"),
-                SCpnt->serial_number, k);
+                k);
          HD(j)->cp_stat[k] = ABORTING;
          continue;
          }
@@ -1793,12 +1786,12 @@
    if (SCpnt == NULL) panic("%s: ihdlr, mbox %d, SCpnt == NULL.\n", BN(j), i);
 
    if (SCpnt->host_scribble == NULL)
-      panic("%s: ihdlr, mbox %d, pid %ld, SCpnt %p garbled.\n", BN(j), i,
-            SCpnt->serial_number, SCpnt);
+      panic("%s: ihdlr, mbox %d, SCpnt %p garbled.\n", BN(j), i,
+            SCpnt);
 
    if (*(unsigned int *)SCpnt->host_scribble != i)
-      panic("%s: ihdlr, mbox %d, pid %ld, index mismatch %d.\n",
-            BN(j), i, SCpnt->serial_number, *(unsigned int *)SCpnt->host_scribble);
+      panic("%s: ihdlr, mbox %d, index mismatch %d.\n",
+            BN(j), i, *(unsigned int *)SCpnt->host_scribble);
 
    sync_dma(i, j);
 
@@ -1841,8 +1834,8 @@
              (!(tstatus == CHECK_CONDITION && HD(j)->iocount <= 1000 &&
                (SCpnt->sense_buffer[2] & 0xf) == NOT_READY)))
             scmd_printk(KERN_INFO, SCpnt,
-	    	"ihdlr, pid %ld, target_status 0x%x, sense key 0x%x.\n",
-                   SCpnt->serial_number, spp->target_status,
+	    	"ihdlr, target_status 0x%x, sense key 0x%x.\n",
+                   spp->target_status,
                    SCpnt->sense_buffer[2]);
 
          HD(j)->target_to[scmd_id(SCpnt)][scmd_channel(SCpnt)] = 0;
@@ -1913,8 +1906,8 @@
         do_trace || msg_byte(spp->target_status))
 #endif
       scmd_printk(KERN_INFO, SCpnt, "ihdlr, mbox %2d, err 0x%x:%x,"\
-             " pid %ld, reg 0x%x, count %d.\n",
-             i, spp->adapter_status, spp->target_status, SCpnt->serial_number,
+             " reg 0x%x, count %d.\n",
+             i, spp->adapter_status, spp->target_status,
              reg, HD(j)->iocount);
 
    unmap_dma(i, j);
diff -druN linux-2.6.39-libre/drivers/scsi/ultrastor.c linux-3.0-rc7-libre/drivers/scsi/ultrastor.c
--- linux-2.6.39-libre/drivers/scsi/ultrastor.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/scsi/ultrastor.c	2011-07-11 19:51:52.000000000 -0400
@@ -307,7 +307,7 @@
 	"0: bsfw %1,%w0\n\t"
 	"btr %0,%1\n\t"
 	"jnc 0b"
-	: "=&r" (rv), "=m" (*field) :);
+	: "=&r" (rv), "+m" (*field) :);
 
   return rv;
 }
diff -druN linux-2.6.39-libre/drivers/scsi/wd33c93.c linux-3.0-rc7-libre/drivers/scsi/wd33c93.c
--- linux-2.6.39-libre/drivers/scsi/wd33c93.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/scsi/wd33c93.c	2011-07-11 19:51:52.000000000 -0400
@@ -381,7 +381,7 @@
 	hostdata = (struct WD33C93_hostdata *) cmd->device->host->hostdata;
 
 	DB(DB_QUEUE_COMMAND,
-	   printk("Q-%d-%02x-%ld( ", cmd->device->id, cmd->cmnd[0], cmd->serial_number))
+	   printk("Q-%d-%02x( ", cmd->device->id, cmd->cmnd[0]))
 
 /* Set up a few fields in the scsi_cmnd structure for our own use:
  *  - host_scribble is the pointer to the next cmd in the input queue
@@ -462,7 +462,7 @@
 
 	wd33c93_execute(cmd->device->host);
 
-	DB(DB_QUEUE_COMMAND, printk(")Q-%ld ", cmd->serial_number))
+	DB(DB_QUEUE_COMMAND, printk(")Q "))
 
 	spin_unlock_irq(&hostdata->lock);
 	return 0;
@@ -687,7 +687,7 @@
 	 */
 
 	DB(DB_EXECUTE,
-	   printk("%s%ld)EX-2 ", (cmd->SCp.phase) ? "d:" : "", cmd->serial_number))
+	   printk("%s)EX-2 ", (cmd->SCp.phase) ? "d:" : ""))
 }
 
 static void
@@ -963,7 +963,7 @@
 	case CSR_XFER_DONE | PHS_COMMAND:
 	case CSR_UNEXP | PHS_COMMAND:
 	case CSR_SRV_REQ | PHS_COMMAND:
-		DB(DB_INTR, printk("CMND-%02x,%ld", cmd->cmnd[0], cmd->serial_number))
+		DB(DB_INTR, printk("CMND-%02x", cmd->cmnd[0]))
 		    transfer_pio(regs, cmd->cmnd, cmd->cmd_len, DATA_OUT_DIR,
 				 hostdata);
 		hostdata->state = S_CONNECTED;
@@ -1007,7 +1007,7 @@
 		switch (msg) {
 
 		case COMMAND_COMPLETE:
-			DB(DB_INTR, printk("CCMP-%ld", cmd->serial_number))
+			DB(DB_INTR, printk("CCMP"))
 			    write_wd33c93_cmd(regs, WD_CMD_NEGATE_ACK);
 			hostdata->state = S_PRE_CMP_DISC;
 			break;
@@ -1174,7 +1174,7 @@
 
 		write_wd33c93(regs, WD_SOURCE_ID, SRCID_ER);
 		if (phs == 0x60) {
-			DB(DB_INTR, printk("SX-DONE-%ld", cmd->serial_number))
+			DB(DB_INTR, printk("SX-DONE"))
 			    cmd->SCp.Message = COMMAND_COMPLETE;
 			lun = read_wd33c93(regs, WD_TARGET_LUN);
 			DB(DB_INTR, printk(":%d.%d", cmd->SCp.Status, lun))
@@ -1200,8 +1200,8 @@
 			wd33c93_execute(instance);
 		} else {
 			printk
-			    ("%02x:%02x:%02x-%ld: Unknown SEL_XFER_DONE phase!!---",
-			     asr, sr, phs, cmd->serial_number);
+			    ("%02x:%02x:%02x: Unknown SEL_XFER_DONE phase!!---",
+			     asr, sr, phs);
 			spin_unlock_irqrestore(&hostdata->lock, flags);
 		}
 		break;
@@ -1266,7 +1266,7 @@
 			spin_unlock_irqrestore(&hostdata->lock, flags);
 			return;
 		}
-		DB(DB_INTR, printk("UNEXP_DISC-%ld", cmd->serial_number))
+		DB(DB_INTR, printk("UNEXP_DISC"))
 		    hostdata->connected = NULL;
 		hostdata->busy[cmd->device->id] &= ~(1 << cmd->device->lun);
 		hostdata->state = S_UNCONNECTED;
@@ -1292,7 +1292,7 @@
  */
 
 		write_wd33c93(regs, WD_SOURCE_ID, SRCID_ER);
-		DB(DB_INTR, printk("DISC-%ld", cmd->serial_number))
+		DB(DB_INTR, printk("DISC"))
 		    if (cmd == NULL) {
 			printk(" - Already disconnected! ");
 			hostdata->state = S_UNCONNECTED;
@@ -1491,7 +1491,6 @@
 		} else
 			hostdata->state = S_CONNECTED;
 
-		DB(DB_INTR, printk("-%ld", cmd->serial_number))
 		    spin_unlock_irqrestore(&hostdata->lock, flags);
 		break;
 
@@ -1637,8 +1636,8 @@
 			cmd->host_scribble = NULL;
 			cmd->result = DID_ABORT << 16;
 			printk
-			    ("scsi%d: Abort - removing command %ld from input_Q. ",
-			     instance->host_no, cmd->serial_number);
+			    ("scsi%d: Abort - removing command from input_Q. ",
+			     instance->host_no);
 			enable_irq(cmd->device->host->irq);
 			cmd->scsi_done(cmd);
 			return SUCCESS;
@@ -1662,8 +1661,8 @@
 		uchar sr, asr;
 		unsigned long timeout;
 
-		printk("scsi%d: Aborting connected command %ld - ",
-		       instance->host_no, cmd->serial_number);
+		printk("scsi%d: Aborting connected command - ",
+		       instance->host_no);
 
 		printk("stopping DMA - ");
 		if (hostdata->dma == D_DMA_RUNNING) {
@@ -1729,8 +1728,8 @@
 	while (tmp) {
 		if (tmp == cmd) {
 			printk
-			    ("scsi%d: Abort - command %ld found on disconnected_Q - ",
-			     instance->host_no, cmd->serial_number);
+			    ("scsi%d: Abort - command found on disconnected_Q - ",
+			     instance->host_no);
 			printk("Abort SNOOZE. ");
 			enable_irq(cmd->device->host->irq);
 			return FAILED;
@@ -2052,8 +2051,7 @@
 	for (i = 0; i < MAX_SETUP_ARGS; i++)
 		printk("%s,", setup_args[i]);
 	printk("\n");
-	printk("           Version %s - %s, Compiled %s at %s\n",
-	       WD33C93_VERSION, WD33C93_DATE, __DATE__, __TIME__);
+	printk("           Version %s - %s\n", WD33C93_VERSION, WD33C93_DATE);
 }
 
 int
@@ -2133,8 +2131,8 @@
 	bp = buf;
 	*bp = '\0';
 	if (hd->proc & PR_VERSION) {
-		sprintf(tbuf, "\nVersion %s - %s. Compiled %s %s",
-			WD33C93_VERSION, WD33C93_DATE, __DATE__, __TIME__);
+		sprintf(tbuf, "\nVersion %s - %s.",
+			WD33C93_VERSION, WD33C93_DATE);
 		strcat(bp, tbuf);
 	}
 	if (hd->proc & PR_INFO) {
@@ -2180,8 +2178,8 @@
 		strcat(bp, "\nconnected:     ");
 		if (hd->connected) {
 			cmd = (struct scsi_cmnd *) hd->connected;
-			sprintf(tbuf, " %ld-%d:%d(%02x)",
-				cmd->serial_number, cmd->device->id, cmd->device->lun, cmd->cmnd[0]);
+			sprintf(tbuf, " %d:%d(%02x)",
+				cmd->device->id, cmd->device->lun, cmd->cmnd[0]);
 			strcat(bp, tbuf);
 		}
 	}
@@ -2189,8 +2187,8 @@
 		strcat(bp, "\ninput_Q:       ");
 		cmd = (struct scsi_cmnd *) hd->input_Q;
 		while (cmd) {
-			sprintf(tbuf, " %ld-%d:%d(%02x)",
-				cmd->serial_number, cmd->device->id, cmd->device->lun, cmd->cmnd[0]);
+			sprintf(tbuf, " %d:%d(%02x)",
+				cmd->device->id, cmd->device->lun, cmd->cmnd[0]);
 			strcat(bp, tbuf);
 			cmd = (struct scsi_cmnd *) cmd->host_scribble;
 		}
@@ -2199,8 +2197,8 @@
 		strcat(bp, "\ndisconnected_Q:");
 		cmd = (struct scsi_cmnd *) hd->disconnected_Q;
 		while (cmd) {
-			sprintf(tbuf, " %ld-%d:%d(%02x)",
-				cmd->serial_number, cmd->device->id, cmd->device->lun, cmd->cmnd[0]);
+			sprintf(tbuf, " %d:%d(%02x)",
+				cmd->device->id, cmd->device->lun, cmd->cmnd[0]);
 			strcat(bp, tbuf);
 			cmd = (struct scsi_cmnd *) cmd->host_scribble;
 		}
diff -druN linux-2.6.39-libre/drivers/sh/clk/core.c linux-3.0-rc7-libre/drivers/sh/clk/core.c
--- linux-2.6.39-libre/drivers/sh/clk/core.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/sh/clk/core.c	2011-07-11 19:51:52.000000000 -0400
@@ -635,7 +635,7 @@
 	struct clk *clkp;
 
 	list_for_each_entry(clkp, &clock_list, node) {
-		if (likely(clkp->ops)) {
+		if (likely(clkp->usecount && clkp->ops)) {
 			unsigned long rate = clkp->rate;
 
 			if (likely(clkp->ops->set_parent))
diff -druN linux-2.6.39-libre/drivers/sh/clk/cpg.c linux-3.0-rc7-libre/drivers/sh/clk/cpg.c
--- linux-2.6.39-libre/drivers/sh/clk/cpg.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/sh/clk/cpg.c	2011-07-11 19:51:52.000000000 -0400
@@ -105,7 +105,7 @@
 
 	/* Rebuild the frequency table */
 	clk_rate_table_build(clk, clk->freq_table, table->nr_divisors,
-			     table, &clk->arch_flags);
+			     table, NULL);
 
 	return 0;
 }
diff -druN linux-2.6.39-libre/drivers/sh/intc/virq.c linux-3.0-rc7-libre/drivers/sh/intc/virq.c
--- linux-2.6.39-libre/drivers/sh/intc/virq.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/sh/intc/virq.c	2011-07-11 19:51:52.000000000 -0400
@@ -235,6 +235,11 @@
 
 		irq_set_handler_data(irq, (void *)entry->handle);
 
+		/*
+		 * Set the virtual IRQ as non-threadable.
+		 */
+		irq_set_nothread(irq);
+
 		irq_set_chained_handler(entry->pirq, intc_virq_handler);
 		add_virq_to_pirq(entry->pirq, irq);
 
diff -druN linux-2.6.39-libre/drivers/spi/amba-pl022.c linux-3.0-rc7-libre/drivers/spi/amba-pl022.c
--- linux-2.6.39-libre/drivers/spi/amba-pl022.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/spi/amba-pl022.c	2011-07-11 19:51:52.000000000 -0400
@@ -24,11 +24,6 @@
  * GNU General Public License for more details.
  */
 
-/*
- * TODO:
- * - add timeout on polled transfers
- */
-
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/device.h>
@@ -287,6 +282,8 @@
 
 #define CLEAR_ALL_INTERRUPTS  0x3
 
+#define SPI_POLLING_TIMEOUT 1000
+
 
 /*
  * The type of reading going on on this chip
@@ -1063,7 +1060,7 @@
 					    pl022->master_info->dma_filter,
 					    pl022->master_info->dma_rx_param);
 	if (!pl022->dma_rx_channel) {
-		dev_err(&pl022->adev->dev, "no RX DMA channel!\n");
+		dev_dbg(&pl022->adev->dev, "no RX DMA channel!\n");
 		goto err_no_rxchan;
 	}
 
@@ -1071,13 +1068,13 @@
 					    pl022->master_info->dma_filter,
 					    pl022->master_info->dma_tx_param);
 	if (!pl022->dma_tx_channel) {
-		dev_err(&pl022->adev->dev, "no TX DMA channel!\n");
+		dev_dbg(&pl022->adev->dev, "no TX DMA channel!\n");
 		goto err_no_txchan;
 	}
 
 	pl022->dummypage = kmalloc(PAGE_SIZE, GFP_KERNEL);
 	if (!pl022->dummypage) {
-		dev_err(&pl022->adev->dev, "no DMA dummypage!\n");
+		dev_dbg(&pl022->adev->dev, "no DMA dummypage!\n");
 		goto err_no_dummypage;
 	}
 
@@ -1093,6 +1090,8 @@
 	dma_release_channel(pl022->dma_rx_channel);
 	pl022->dma_rx_channel = NULL;
 err_no_rxchan:
+	dev_err(&pl022->adev->dev,
+			"Failed to work in dma mode, work without dma!\n");
 	return -ENODEV;
 }
 
@@ -1378,6 +1377,7 @@
 	struct spi_transfer *transfer = NULL;
 	struct spi_transfer *previous = NULL;
 	struct chip_data *chip;
+	unsigned long time, timeout;
 
 	chip = pl022->cur_chip;
 	message = pl022->cur_msg;
@@ -1415,9 +1415,19 @@
 		       SSP_CR1(pl022->virtbase));
 
 		dev_dbg(&pl022->adev->dev, "polling transfer ongoing ...\n");
-		/* FIXME: insert a timeout so we don't hang here indefinitely */
-		while (pl022->tx < pl022->tx_end || pl022->rx < pl022->rx_end)
+
+		timeout = jiffies + msecs_to_jiffies(SPI_POLLING_TIMEOUT);
+		while (pl022->tx < pl022->tx_end || pl022->rx < pl022->rx_end) {
+			time = jiffies;
 			readwriter(pl022);
+			if (time_after(time, timeout)) {
+				dev_warn(&pl022->adev->dev,
+				"%s: timeout!\n", __func__);
+				message->state = STATE_ERROR;
+				goto out;
+			}
+			cpu_relax();
+		}
 
 		/* Update total byte transferred */
 		message->actual_length += pl022->cur_transfer->len;
@@ -1426,7 +1436,7 @@
 		/* Move to next transfer */
 		message->state = next_transfer(pl022);
 	}
-
+out:
 	/* Handle end of message */
 	if (message->state == STATE_DONE)
 		message->status = 0;
@@ -1851,6 +1861,7 @@
 	}
 	if ((clk_freq.cpsdvsr < CPSDVR_MIN)
 	    || (clk_freq.cpsdvsr > CPSDVR_MAX)) {
+		status = -EINVAL;
 		dev_err(&spi->dev,
 			"cpsdvsr is configured incorrectly\n");
 		goto err_config_params;
@@ -2107,7 +2118,7 @@
 	if (platform_info->enable_dma) {
 		status = pl022_dma_probe(pl022);
 		if (status != 0)
-			goto err_no_dma;
+			platform_info->enable_dma = 0;
 	}
 
 	/* Initialize and start queue */
@@ -2143,7 +2154,6 @@
  err_init_queue:
 	destroy_queue(pl022);
 	pl022_dma_remove(pl022);
- err_no_dma:
 	free_irq(adev->irq[0], pl022);
  err_no_irq:
 	clk_put(pl022->clk);
diff -druN linux-2.6.39-libre/drivers/spi/atmel_spi.c linux-3.0-rc7-libre/drivers/spi/atmel_spi.c
--- linux-2.6.39-libre/drivers/spi/atmel_spi.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/spi/atmel_spi.c	2011-07-11 19:51:52.000000000 -0400
@@ -935,6 +935,6 @@
 module_exit(atmel_spi_exit);
 
 MODULE_DESCRIPTION("Atmel AT32/AT91 SPI Controller driver");
-MODULE_AUTHOR("Haavard Skinnemoen <hskinnemoen@atmel.com>");
+MODULE_AUTHOR("Haavard Skinnemoen (Atmel)");
 MODULE_LICENSE("GPL");
 MODULE_ALIAS("platform:atmel_spi");
diff -druN linux-2.6.39-libre/drivers/spi/coldfire_qspi.c linux-3.0-rc7-libre/drivers/spi/coldfire_qspi.c
--- linux-2.6.39-libre/drivers/spi/coldfire_qspi.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/spi/coldfire_qspi.c	2011-07-11 19:51:52.000000000 -0400
@@ -33,6 +33,7 @@
 #include <linux/spi/spi.h>
 
 #include <asm/coldfire.h>
+#include <asm/mcfsim.h>
 #include <asm/mcfqspi.h>
 
 #define	DRIVER_NAME "mcfqspi"
diff -druN linux-2.6.39-libre/drivers/spi/dw_spi.c linux-3.0-rc7-libre/drivers/spi/dw_spi.c
--- linux-2.6.39-libre/drivers/spi/dw_spi.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/spi/dw_spi.c	2011-07-11 19:51:52.000000000 -0400
@@ -58,8 +58,6 @@
 	u8 bits_per_word;
 	u16 clk_div;		/* baud rate divider */
 	u32 speed_hz;		/* baud rate */
-	int (*write)(struct dw_spi *dws);
-	int (*read)(struct dw_spi *dws);
 	void (*cs_control)(u32 command);
 };
 
@@ -162,107 +160,70 @@
 }
 #endif /* CONFIG_DEBUG_FS */
 
-static void wait_till_not_busy(struct dw_spi *dws)
-{
-	unsigned long end = jiffies + 1 + usecs_to_jiffies(5000);
-
-	while (time_before(jiffies, end)) {
-		if (!(dw_readw(dws, sr) & SR_BUSY))
-			return;
-		cpu_relax();
-	}
-	dev_err(&dws->master->dev,
-		"DW SPI: Status keeps busy for 5000us after a read/write!\n");
-}
-
-static void flush(struct dw_spi *dws)
+/* Return the max entries we can fill into tx fifo */
+static inline u32 tx_max(struct dw_spi *dws)
 {
-	while (dw_readw(dws, sr) & SR_RF_NOT_EMPT) {
-		dw_readw(dws, dr);
-		cpu_relax();
-	}
-
-	wait_till_not_busy(dws);
-}
+	u32 tx_left, tx_room, rxtx_gap;
 
-static int null_writer(struct dw_spi *dws)
-{
-	u8 n_bytes = dws->n_bytes;
+	tx_left = (dws->tx_end - dws->tx) / dws->n_bytes;
+	tx_room = dws->fifo_len - dw_readw(dws, txflr);
 
-	if (!(dw_readw(dws, sr) & SR_TF_NOT_FULL)
-		|| (dws->tx == dws->tx_end))
-		return 0;
-	dw_writew(dws, dr, 0);
-	dws->tx += n_bytes;
+	/*
+	 * Another concern is about the tx/rx mismatch, we
+	 * though to use (dws->fifo_len - rxflr - txflr) as
+	 * one maximum value for tx, but it doesn't cover the
+	 * data which is out of tx/rx fifo and inside the
+	 * shift registers. So a control from sw point of
+	 * view is taken.
+	 */
+	rxtx_gap =  ((dws->rx_end - dws->rx) - (dws->tx_end - dws->tx))
+			/ dws->n_bytes;
 
-	wait_till_not_busy(dws);
-	return 1;
+	return min3(tx_left, tx_room, (u32) (dws->fifo_len - rxtx_gap));
 }
 
-static int null_reader(struct dw_spi *dws)
+/* Return the max entries we should read out of rx fifo */
+static inline u32 rx_max(struct dw_spi *dws)
 {
-	u8 n_bytes = dws->n_bytes;
+	u32 rx_left = (dws->rx_end - dws->rx) / dws->n_bytes;
 
-	while ((dw_readw(dws, sr) & SR_RF_NOT_EMPT)
-		&& (dws->rx < dws->rx_end)) {
-		dw_readw(dws, dr);
-		dws->rx += n_bytes;
-	}
-	wait_till_not_busy(dws);
-	return dws->rx == dws->rx_end;
+	return min(rx_left, (u32)dw_readw(dws, rxflr));
 }
 
-static int u8_writer(struct dw_spi *dws)
+static void dw_writer(struct dw_spi *dws)
 {
-	if (!(dw_readw(dws, sr) & SR_TF_NOT_FULL)
-		|| (dws->tx == dws->tx_end))
-		return 0;
-
-	dw_writew(dws, dr, *(u8 *)(dws->tx));
-	++dws->tx;
-
-	wait_till_not_busy(dws);
-	return 1;
-}
+	u32 max = tx_max(dws);
+	u16 txw = 0;
 
-static int u8_reader(struct dw_spi *dws)
-{
-	while ((dw_readw(dws, sr) & SR_RF_NOT_EMPT)
-		&& (dws->rx < dws->rx_end)) {
-		*(u8 *)(dws->rx) = dw_readw(dws, dr);
-		++dws->rx;
+	while (max--) {
+		/* Set the tx word if the transfer's original "tx" is not null */
+		if (dws->tx_end - dws->len) {
+			if (dws->n_bytes == 1)
+				txw = *(u8 *)(dws->tx);
+			else
+				txw = *(u16 *)(dws->tx);
+		}
+		dw_writew(dws, dr, txw);
+		dws->tx += dws->n_bytes;
 	}
-
-	wait_till_not_busy(dws);
-	return dws->rx == dws->rx_end;
-}
-
-static int u16_writer(struct dw_spi *dws)
-{
-	if (!(dw_readw(dws, sr) & SR_TF_NOT_FULL)
-		|| (dws->tx == dws->tx_end))
-		return 0;
-
-	dw_writew(dws, dr, *(u16 *)(dws->tx));
-	dws->tx += 2;
-
-	wait_till_not_busy(dws);
-	return 1;
 }
 
-static int u16_reader(struct dw_spi *dws)
+static void dw_reader(struct dw_spi *dws)
 {
-	u16 temp;
+	u32 max = rx_max(dws);
+	u16 rxw;
 
-	while ((dw_readw(dws, sr) & SR_RF_NOT_EMPT)
-		&& (dws->rx < dws->rx_end)) {
-		temp = dw_readw(dws, dr);
-		*(u16 *)(dws->rx) = temp;
-		dws->rx += 2;
+	while (max--) {
+		rxw = dw_readw(dws, dr);
+		/* Care rx only if the transfer's original "rx" is not null */
+		if (dws->rx_end - dws->len) {
+			if (dws->n_bytes == 1)
+				*(u8 *)(dws->rx) = rxw;
+			else
+				*(u16 *)(dws->rx) = rxw;
+		}
+		dws->rx += dws->n_bytes;
 	}
-
-	wait_till_not_busy(dws);
-	return dws->rx == dws->rx_end;
 }
 
 static void *next_transfer(struct dw_spi *dws)
@@ -334,8 +295,7 @@
 
 static void int_error_stop(struct dw_spi *dws, const char *msg)
 {
-	/* Stop and reset hw */
-	flush(dws);
+	/* Stop the hw */
 	spi_enable_chip(dws, 0);
 
 	dev_err(&dws->master->dev, "%s\n", msg);
@@ -362,35 +322,28 @@
 
 static irqreturn_t interrupt_transfer(struct dw_spi *dws)
 {
-	u16 irq_status, irq_mask = 0x3f;
-	u32 int_level = dws->fifo_len / 2;
-	u32 left;
+	u16 irq_status = dw_readw(dws, isr);
 
-	irq_status = dw_readw(dws, isr) & irq_mask;
 	/* Error handling */
 	if (irq_status & (SPI_INT_TXOI | SPI_INT_RXOI | SPI_INT_RXUI)) {
 		dw_readw(dws, txoicr);
 		dw_readw(dws, rxoicr);
 		dw_readw(dws, rxuicr);
-		int_error_stop(dws, "interrupt_transfer: fifo overrun");
+		int_error_stop(dws, "interrupt_transfer: fifo overrun/underrun");
 		return IRQ_HANDLED;
 	}
 
+	dw_reader(dws);
+	if (dws->rx_end == dws->rx) {
+		spi_mask_intr(dws, SPI_INT_TXEI);
+		dw_spi_xfer_done(dws);
+		return IRQ_HANDLED;
+	}
 	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);
-
-		/* 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
-			dw_spi_xfer_done(dws);
+		dw_writer(dws);
+		/* Enable TX irq always, it will be disabled when RX finished */
+		spi_umask_intr(dws, SPI_INT_TXEI);
 	}
 
 	return IRQ_HANDLED;
@@ -399,15 +352,13 @@
 static irqreturn_t dw_spi_irq(int irq, void *dev_id)
 {
 	struct dw_spi *dws = dev_id;
-	u16 irq_status, irq_mask = 0x3f;
+	u16 irq_status = dw_readw(dws, isr) & 0x3f;
 
-	irq_status = dw_readw(dws, isr) & irq_mask;
 	if (!irq_status)
 		return IRQ_NONE;
 
 	if (!dws->cur_msg) {
 		spi_mask_intr(dws, SPI_INT_TXEI);
-		/* Never fail */
 		return IRQ_HANDLED;
 	}
 
@@ -417,13 +368,11 @@
 /* Must be called inside pump_transfers() */
 static void poll_transfer(struct dw_spi *dws)
 {
-	while (dws->write(dws))
-		dws->read(dws);
-	/*
-	 * There is a possibility that the last word of a transaction
-	 * will be lost if data is not ready. Re-read to solve this issue.
-	 */
-	dws->read(dws);
+	do {
+		dw_writer(dws);
+		dw_reader(dws);
+		cpu_relax();
+	} while (dws->rx_end > dws->rx);
 
 	dw_spi_xfer_done(dws);
 }
@@ -483,8 +432,6 @@
 	dws->tx_end = dws->tx + transfer->len;
 	dws->rx = transfer->rx_buf;
 	dws->rx_end = dws->rx + transfer->len;
-	dws->write = dws->tx ? chip->write : null_writer;
-	dws->read = dws->rx ? chip->read : null_reader;
 	dws->cs_change = transfer->cs_change;
 	dws->len = dws->cur_transfer->len;
 	if (chip != dws->prev_chip)
@@ -518,20 +465,8 @@
 
 		switch (bits) {
 		case 8:
-			dws->n_bytes = 1;
-			dws->dma_width = 1;
-			dws->read = (dws->read != null_reader) ?
-					u8_reader : null_reader;
-			dws->write = (dws->write != null_writer) ?
-					u8_writer : null_writer;
-			break;
 		case 16:
-			dws->n_bytes = 2;
-			dws->dma_width = 2;
-			dws->read = (dws->read != null_reader) ?
-					u16_reader : null_reader;
-			dws->write = (dws->write != null_writer) ?
-					u16_writer : null_writer;
+			dws->n_bytes = dws->dma_width = bits >> 3;
 			break;
 		default:
 			printk(KERN_ERR "MRST SPI0: unsupported bits:"
@@ -575,7 +510,7 @@
 		txint_level = dws->fifo_len / 2;
 		txint_level = (templen > txint_level) ? txint_level : templen;
 
-		imask |= SPI_INT_TXEI;
+		imask |= SPI_INT_TXEI | SPI_INT_TXOI | SPI_INT_RXUI | SPI_INT_RXOI;
 		dws->transfer_handler = interrupt_transfer;
 	}
 
@@ -733,13 +668,9 @@
 	if (spi->bits_per_word <= 8) {
 		chip->n_bytes = 1;
 		chip->dma_width = 1;
-		chip->read = u8_reader;
-		chip->write = u8_writer;
 	} else if (spi->bits_per_word <= 16) {
 		chip->n_bytes = 2;
 		chip->dma_width = 2;
-		chip->read = u16_reader;
-		chip->write = u16_writer;
 	} else {
 		/* Never take >16b case for MRST SPIC */
 		dev_err(&spi->dev, "invalid wordsize\n");
@@ -851,7 +782,6 @@
 	spi_enable_chip(dws, 0);
 	spi_mask_intr(dws, 0xff);
 	spi_enable_chip(dws, 1);
-	flush(dws);
 
 	/*
 	 * Try to detect the FIFO depth if not set by interface driver,
diff -druN linux-2.6.39-libre/drivers/spi/dw_spi.h linux-3.0-rc7-libre/drivers/spi/dw_spi.h
--- linux-2.6.39-libre/drivers/spi/dw_spi.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/spi/dw_spi.h	2011-07-11 19:51:52.000000000 -0400
@@ -137,8 +137,6 @@
 	u8			max_bits_per_word;	/* maxim is 16b */
 	u32			dma_width;
 	int			cs_change;
-	int			(*write)(struct dw_spi *dws);
-	int			(*read)(struct dw_spi *dws);
 	irqreturn_t		(*transfer_handler)(struct dw_spi *dws);
 	void			(*cs_control)(u32 command);
 
diff -druN linux-2.6.39-libre/drivers/spi/Kconfig linux-3.0-rc7-libre/drivers/spi/Kconfig
--- linux-2.6.39-libre/drivers/spi/Kconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/spi/Kconfig	2011-07-11 19:51:52.000000000 -0400
@@ -80,6 +80,15 @@
 	help
 	  This is the SPI controller master driver for Blackfin 5xx processor.
 
+config SPI_BFIN_SPORT
+	tristate "SPI bus via Blackfin SPORT"
+	depends on BLACKFIN
+	help
+	  Enable support for a SPI bus via the Blackfin SPORT peripheral.
+
+	  This driver can also be built as a module.  If so, the module
+	  will be called spi_bfin_sport.
+
 config SPI_AU1550
 	tristate "Au1550/Au12x0 SPI Controller"
 	depends on (SOC_AU1550 || SOC_AU1200) && EXPERIMENTAL
@@ -271,8 +280,8 @@
 	  This enables using the SPI master controller on the Orion chips.
 
 config SPI_PL022
-	tristate "ARM AMBA PL022 SSP controller (EXPERIMENTAL)"
-	depends on ARM_AMBA && EXPERIMENTAL
+	tristate "ARM AMBA PL022 SSP controller"
+	depends on ARM_AMBA
 	default y if MACH_U300
 	default y if ARCH_REALVIEW
 	default y if INTEGRATOR_IMPD1
diff -druN linux-2.6.39-libre/drivers/spi/Makefile linux-3.0-rc7-libre/drivers/spi/Makefile
--- linux-2.6.39-libre/drivers/spi/Makefile	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/spi/Makefile	2011-07-11 19:51:52.000000000 -0400
@@ -13,6 +13,7 @@
 obj-$(CONFIG_SPI_ATMEL)			+= atmel_spi.o
 obj-$(CONFIG_SPI_ATH79)			+= ath79_spi.o
 obj-$(CONFIG_SPI_BFIN)			+= spi_bfin5xx.o
+obj-$(CONFIG_SPI_BFIN_SPORT)		+= spi_bfin_sport.o
 obj-$(CONFIG_SPI_BITBANG)		+= spi_bitbang.o
 obj-$(CONFIG_SPI_AU1550)		+= au1550_spi.o
 obj-$(CONFIG_SPI_BUTTERFLY)		+= spi_butterfly.o
diff -druN linux-2.6.39-libre/drivers/spi/omap2_mcspi.c linux-3.0-rc7-libre/drivers/spi/omap2_mcspi.c
--- linux-2.6.39-libre/drivers/spi/omap2_mcspi.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/spi/omap2_mcspi.c	2011-07-11 19:51:52.000000000 -0400
@@ -298,7 +298,7 @@
 	unsigned int		count, c;
 	unsigned long		base, tx_reg, rx_reg;
 	int			word_len, data_type, element_count;
-	int			elements;
+	int			elements = 0;
 	u32			l;
 	u8			* rx;
 	const u8		* tx;
diff -druN linux-2.6.39-libre/drivers/spi/spi_bfin5xx.c linux-3.0-rc7-libre/drivers/spi/spi_bfin5xx.c
--- linux-2.6.39-libre/drivers/spi/spi_bfin5xx.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/spi/spi_bfin5xx.c	2011-07-11 19:51:52.000000000 -0400
@@ -681,13 +681,14 @@
 	drv_data->cs_change = transfer->cs_change;
 
 	/* Bits per word setup */
-	bits_per_word = transfer->bits_per_word ? : message->spi->bits_per_word;
-	if ((bits_per_word > 0) && (bits_per_word % 16 == 0)) {
+	bits_per_word = transfer->bits_per_word ? :
+		message->spi->bits_per_word ? : 8;
+	if (bits_per_word % 16 == 0) {
 		drv_data->n_bytes = bits_per_word/8;
 		drv_data->len = (transfer->len) >> 1;
 		cr_width = BIT_CTL_WORDSIZE;
 		drv_data->ops = &bfin_bfin_spi_transfer_ops_u16;
-	} else if ((bits_per_word > 0) && (bits_per_word % 8 == 0)) {
+	} else if (bits_per_word % 8 == 0) {
 		drv_data->n_bytes = bits_per_word/8;
 		drv_data->len = transfer->len;
 		cr_width = 0;
diff -druN linux-2.6.39-libre/drivers/spi/spi_bfin_sport.c linux-3.0-rc7-libre/drivers/spi/spi_bfin_sport.c
--- linux-2.6.39-libre/drivers/spi/spi_bfin_sport.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/spi/spi_bfin_sport.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,952 @@
+/*
+ * SPI bus via the Blackfin SPORT peripheral
+ *
+ * Enter bugs at http://blackfin.uclinux.org/
+ *
+ * Copyright 2009-2011 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/gpio.h>
+#include <linux/io.h>
+#include <linux/ioport.h>
+#include <linux/irq.h>
+#include <linux/errno.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+#include <linux/spi/spi.h>
+#include <linux/workqueue.h>
+
+#include <asm/portmux.h>
+#include <asm/bfin5xx_spi.h>
+#include <asm/blackfin.h>
+#include <asm/bfin_sport.h>
+#include <asm/cacheflush.h>
+
+#define DRV_NAME	"bfin-sport-spi"
+#define DRV_DESC	"SPI bus via the Blackfin SPORT"
+
+MODULE_AUTHOR("Cliff Cai");
+MODULE_DESCRIPTION(DRV_DESC);
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:bfin-sport-spi");
+
+enum bfin_sport_spi_state {
+	START_STATE,
+	RUNNING_STATE,
+	DONE_STATE,
+	ERROR_STATE,
+};
+
+struct bfin_sport_spi_master_data;
+
+struct bfin_sport_transfer_ops {
+	void (*write) (struct bfin_sport_spi_master_data *);
+	void (*read) (struct bfin_sport_spi_master_data *);
+	void (*duplex) (struct bfin_sport_spi_master_data *);
+};
+
+struct bfin_sport_spi_master_data {
+	/* Driver model hookup */
+	struct device *dev;
+
+	/* SPI framework hookup */
+	struct spi_master *master;
+
+	/* Regs base of SPI controller */
+	struct sport_register __iomem *regs;
+	int err_irq;
+
+	/* Pin request list */
+	u16 *pin_req;
+
+	/* Driver message queue */
+	struct workqueue_struct *workqueue;
+	struct work_struct pump_messages;
+	spinlock_t lock;
+	struct list_head queue;
+	int busy;
+	bool run;
+
+	/* Message Transfer pump */
+	struct tasklet_struct pump_transfers;
+
+	/* Current message transfer state info */
+	enum bfin_sport_spi_state state;
+	struct spi_message *cur_msg;
+	struct spi_transfer *cur_transfer;
+	struct bfin_sport_spi_slave_data *cur_chip;
+	union {
+		void *tx;
+		u8 *tx8;
+		u16 *tx16;
+	};
+	void *tx_end;
+	union {
+		void *rx;
+		u8 *rx8;
+		u16 *rx16;
+	};
+	void *rx_end;
+
+	int cs_change;
+	struct bfin_sport_transfer_ops *ops;
+};
+
+struct bfin_sport_spi_slave_data {
+	u16 ctl_reg;
+	u16 baud;
+	u16 cs_chg_udelay;	/* Some devices require > 255usec delay */
+	u32 cs_gpio;
+	u16 idle_tx_val;
+	struct bfin_sport_transfer_ops *ops;
+};
+
+static void
+bfin_sport_spi_enable(struct bfin_sport_spi_master_data *drv_data)
+{
+	bfin_write_or(&drv_data->regs->tcr1, TSPEN);
+	bfin_write_or(&drv_data->regs->rcr1, TSPEN);
+	SSYNC();
+}
+
+static void
+bfin_sport_spi_disable(struct bfin_sport_spi_master_data *drv_data)
+{
+	bfin_write_and(&drv_data->regs->tcr1, ~TSPEN);
+	bfin_write_and(&drv_data->regs->rcr1, ~TSPEN);
+	SSYNC();
+}
+
+/* Caculate the SPI_BAUD register value based on input HZ */
+static u16
+bfin_sport_hz_to_spi_baud(u32 speed_hz)
+{
+	u_long clk, sclk = get_sclk();
+	int div = (sclk / (2 * speed_hz)) - 1;
+
+	if (div < 0)
+		div = 0;
+
+	clk = sclk / (2 * (div + 1));
+
+	if (clk > speed_hz)
+		div++;
+
+	return div;
+}
+
+/* Chip select operation functions for cs_change flag */
+static void
+bfin_sport_spi_cs_active(struct bfin_sport_spi_slave_data *chip)
+{
+	gpio_direction_output(chip->cs_gpio, 0);
+}
+
+static void
+bfin_sport_spi_cs_deactive(struct bfin_sport_spi_slave_data *chip)
+{
+	gpio_direction_output(chip->cs_gpio, 1);
+	/* Move delay here for consistency */
+	if (chip->cs_chg_udelay)
+		udelay(chip->cs_chg_udelay);
+}
+
+static void
+bfin_sport_spi_stat_poll_complete(struct bfin_sport_spi_master_data *drv_data)
+{
+	unsigned long timeout = jiffies + HZ;
+	while (!(bfin_read(&drv_data->regs->stat) & RXNE)) {
+		if (!time_before(jiffies, timeout))
+			break;
+	}
+}
+
+static void
+bfin_sport_spi_u8_writer(struct bfin_sport_spi_master_data *drv_data)
+{
+	u16 dummy;
+
+	while (drv_data->tx < drv_data->tx_end) {
+		bfin_write(&drv_data->regs->tx16, *drv_data->tx8++);
+		bfin_sport_spi_stat_poll_complete(drv_data);
+		dummy = bfin_read(&drv_data->regs->rx16);
+	}
+}
+
+static void
+bfin_sport_spi_u8_reader(struct bfin_sport_spi_master_data *drv_data)
+{
+	u16 tx_val = drv_data->cur_chip->idle_tx_val;
+
+	while (drv_data->rx < drv_data->rx_end) {
+		bfin_write(&drv_data->regs->tx16, tx_val);
+		bfin_sport_spi_stat_poll_complete(drv_data);
+		*drv_data->rx8++ = bfin_read(&drv_data->regs->rx16);
+	}
+}
+
+static void
+bfin_sport_spi_u8_duplex(struct bfin_sport_spi_master_data *drv_data)
+{
+	while (drv_data->rx < drv_data->rx_end) {
+		bfin_write(&drv_data->regs->tx16, *drv_data->tx8++);
+		bfin_sport_spi_stat_poll_complete(drv_data);
+		*drv_data->rx8++ = bfin_read(&drv_data->regs->rx16);
+	}
+}
+
+static struct bfin_sport_transfer_ops bfin_sport_transfer_ops_u8 = {
+	.write  = bfin_sport_spi_u8_writer,
+	.read   = bfin_sport_spi_u8_reader,
+	.duplex = bfin_sport_spi_u8_duplex,
+};
+
+static void
+bfin_sport_spi_u16_writer(struct bfin_sport_spi_master_data *drv_data)
+{
+	u16 dummy;
+
+	while (drv_data->tx < drv_data->tx_end) {
+		bfin_write(&drv_data->regs->tx16, *drv_data->tx16++);
+		bfin_sport_spi_stat_poll_complete(drv_data);
+		dummy = bfin_read(&drv_data->regs->rx16);
+	}
+}
+
+static void
+bfin_sport_spi_u16_reader(struct bfin_sport_spi_master_data *drv_data)
+{
+	u16 tx_val = drv_data->cur_chip->idle_tx_val;
+
+	while (drv_data->rx < drv_data->rx_end) {
+		bfin_write(&drv_data->regs->tx16, tx_val);
+		bfin_sport_spi_stat_poll_complete(drv_data);
+		*drv_data->rx16++ = bfin_read(&drv_data->regs->rx16);
+	}
+}
+
+static void
+bfin_sport_spi_u16_duplex(struct bfin_sport_spi_master_data *drv_data)
+{
+	while (drv_data->rx < drv_data->rx_end) {
+		bfin_write(&drv_data->regs->tx16, *drv_data->tx16++);
+		bfin_sport_spi_stat_poll_complete(drv_data);
+		*drv_data->rx16++ = bfin_read(&drv_data->regs->rx16);
+	}
+}
+
+static struct bfin_sport_transfer_ops bfin_sport_transfer_ops_u16 = {
+	.write  = bfin_sport_spi_u16_writer,
+	.read   = bfin_sport_spi_u16_reader,
+	.duplex = bfin_sport_spi_u16_duplex,
+};
+
+/* stop controller and re-config current chip */
+static void
+bfin_sport_spi_restore_state(struct bfin_sport_spi_master_data *drv_data)
+{
+	struct bfin_sport_spi_slave_data *chip = drv_data->cur_chip;
+	unsigned int bits = (drv_data->ops == &bfin_sport_transfer_ops_u8 ? 7 : 15);
+
+	bfin_sport_spi_disable(drv_data);
+	dev_dbg(drv_data->dev, "restoring spi ctl state\n");
+
+	bfin_write(&drv_data->regs->tcr1, chip->ctl_reg);
+	bfin_write(&drv_data->regs->tcr2, bits);
+	bfin_write(&drv_data->regs->tclkdiv, chip->baud);
+	bfin_write(&drv_data->regs->tfsdiv, bits);
+	SSYNC();
+
+	bfin_write(&drv_data->regs->rcr1, chip->ctl_reg & ~(ITCLK | ITFS));
+	bfin_write(&drv_data->regs->rcr2, bits);
+	SSYNC();
+
+	bfin_sport_spi_cs_active(chip);
+}
+
+/* test if there is more transfer to be done */
+static enum bfin_sport_spi_state
+bfin_sport_spi_next_transfer(struct bfin_sport_spi_master_data *drv_data)
+{
+	struct spi_message *msg = drv_data->cur_msg;
+	struct spi_transfer *trans = drv_data->cur_transfer;
+
+	/* Move to next transfer */
+	if (trans->transfer_list.next != &msg->transfers) {
+		drv_data->cur_transfer =
+		    list_entry(trans->transfer_list.next,
+			       struct spi_transfer, transfer_list);
+		return RUNNING_STATE;
+	}
+
+	return DONE_STATE;
+}
+
+/*
+ * caller already set message->status;
+ * dma and pio irqs are blocked give finished message back
+ */
+static void
+bfin_sport_spi_giveback(struct bfin_sport_spi_master_data *drv_data)
+{
+	struct bfin_sport_spi_slave_data *chip = drv_data->cur_chip;
+	unsigned long flags;
+	struct spi_message *msg;
+
+	spin_lock_irqsave(&drv_data->lock, flags);
+	msg = drv_data->cur_msg;
+	drv_data->state = START_STATE;
+	drv_data->cur_msg = NULL;
+	drv_data->cur_transfer = NULL;
+	drv_data->cur_chip = NULL;
+	queue_work(drv_data->workqueue, &drv_data->pump_messages);
+	spin_unlock_irqrestore(&drv_data->lock, flags);
+
+	if (!drv_data->cs_change)
+		bfin_sport_spi_cs_deactive(chip);
+
+	if (msg->complete)
+		msg->complete(msg->context);
+}
+
+static irqreturn_t
+sport_err_handler(int irq, void *dev_id)
+{
+	struct bfin_sport_spi_master_data *drv_data = dev_id;
+	u16 status;
+
+	dev_dbg(drv_data->dev, "%s enter\n", __func__);
+	status = bfin_read(&drv_data->regs->stat) & (TOVF | TUVF | ROVF | RUVF);
+
+	if (status) {
+		bfin_write(&drv_data->regs->stat, status);
+		SSYNC();
+
+		bfin_sport_spi_disable(drv_data);
+		dev_err(drv_data->dev, "status error:%s%s%s%s\n",
+			status & TOVF ? " TOVF" : "",
+			status & TUVF ? " TUVF" : "",
+			status & ROVF ? " ROVF" : "",
+			status & RUVF ? " RUVF" : "");
+	}
+
+	return IRQ_HANDLED;
+}
+
+static void
+bfin_sport_spi_pump_transfers(unsigned long data)
+{
+	struct bfin_sport_spi_master_data *drv_data = (void *)data;
+	struct spi_message *message = NULL;
+	struct spi_transfer *transfer = NULL;
+	struct spi_transfer *previous = NULL;
+	struct bfin_sport_spi_slave_data *chip = NULL;
+	unsigned int bits_per_word;
+	u32 tranf_success = 1;
+	u32 transfer_speed;
+	u8 full_duplex = 0;
+
+	/* Get current state information */
+	message = drv_data->cur_msg;
+	transfer = drv_data->cur_transfer;
+	chip = drv_data->cur_chip;
+
+	if (transfer->speed_hz)
+		transfer_speed = bfin_sport_hz_to_spi_baud(transfer->speed_hz);
+	else
+		transfer_speed = chip->baud;
+	bfin_write(&drv_data->regs->tclkdiv, transfer_speed);
+	SSYNC();
+
+	/*
+	 * if msg is error or done, report it back using complete() callback
+	 */
+
+	 /* Handle for abort */
+	if (drv_data->state == ERROR_STATE) {
+		dev_dbg(drv_data->dev, "transfer: we've hit an error\n");
+		message->status = -EIO;
+		bfin_sport_spi_giveback(drv_data);
+		return;
+	}
+
+	/* Handle end of message */
+	if (drv_data->state == DONE_STATE) {
+		dev_dbg(drv_data->dev, "transfer: all done!\n");
+		message->status = 0;
+		bfin_sport_spi_giveback(drv_data);
+		return;
+	}
+
+	/* Delay if requested at end of transfer */
+	if (drv_data->state == RUNNING_STATE) {
+		dev_dbg(drv_data->dev, "transfer: still running ...\n");
+		previous = list_entry(transfer->transfer_list.prev,
+				      struct spi_transfer, transfer_list);
+		if (previous->delay_usecs)
+			udelay(previous->delay_usecs);
+	}
+
+	if (transfer->len == 0) {
+		/* Move to next transfer of this msg */
+		drv_data->state = bfin_sport_spi_next_transfer(drv_data);
+		/* Schedule next transfer tasklet */
+		tasklet_schedule(&drv_data->pump_transfers);
+	}
+
+	if (transfer->tx_buf != NULL) {
+		drv_data->tx = (void *)transfer->tx_buf;
+		drv_data->tx_end = drv_data->tx + transfer->len;
+		dev_dbg(drv_data->dev, "tx_buf is %p, tx_end is %p\n",
+			transfer->tx_buf, drv_data->tx_end);
+	} else
+		drv_data->tx = NULL;
+
+	if (transfer->rx_buf != NULL) {
+		full_duplex = transfer->tx_buf != NULL;
+		drv_data->rx = transfer->rx_buf;
+		drv_data->rx_end = drv_data->rx + transfer->len;
+		dev_dbg(drv_data->dev, "rx_buf is %p, rx_end is %p\n",
+			transfer->rx_buf, drv_data->rx_end);
+	} else
+		drv_data->rx = NULL;
+
+	drv_data->cs_change = transfer->cs_change;
+
+	/* Bits per word setup */
+	bits_per_word = transfer->bits_per_word ? : message->spi->bits_per_word;
+	if (bits_per_word == 8)
+		drv_data->ops = &bfin_sport_transfer_ops_u8;
+	else
+		drv_data->ops = &bfin_sport_transfer_ops_u16;
+
+	drv_data->state = RUNNING_STATE;
+
+	if (drv_data->cs_change)
+		bfin_sport_spi_cs_active(chip);
+
+	dev_dbg(drv_data->dev,
+		"now pumping a transfer: width is %d, len is %d\n",
+		bits_per_word, transfer->len);
+
+	/* PIO mode write then read */
+	dev_dbg(drv_data->dev, "doing IO transfer\n");
+
+	bfin_sport_spi_enable(drv_data);
+	if (full_duplex) {
+		/* full duplex mode */
+		BUG_ON((drv_data->tx_end - drv_data->tx) !=
+		       (drv_data->rx_end - drv_data->rx));
+		drv_data->ops->duplex(drv_data);
+
+		if (drv_data->tx != drv_data->tx_end)
+			tranf_success = 0;
+	} else if (drv_data->tx != NULL) {
+		/* write only half duplex */
+
+		drv_data->ops->write(drv_data);
+
+		if (drv_data->tx != drv_data->tx_end)
+			tranf_success = 0;
+	} else if (drv_data->rx != NULL) {
+		/* read only half duplex */
+
+		drv_data->ops->read(drv_data);
+		if (drv_data->rx != drv_data->rx_end)
+			tranf_success = 0;
+	}
+	bfin_sport_spi_disable(drv_data);
+
+	if (!tranf_success) {
+		dev_dbg(drv_data->dev, "IO write error!\n");
+		drv_data->state = ERROR_STATE;
+	} else {
+		/* Update total byte transfered */
+		message->actual_length += transfer->len;
+		/* Move to next transfer of this msg */
+		drv_data->state = bfin_sport_spi_next_transfer(drv_data);
+		if (drv_data->cs_change)
+			bfin_sport_spi_cs_deactive(chip);
+	}
+
+	/* Schedule next transfer tasklet */
+	tasklet_schedule(&drv_data->pump_transfers);
+}
+
+/* pop a msg from queue and kick off real transfer */
+static void
+bfin_sport_spi_pump_messages(struct work_struct *work)
+{
+	struct bfin_sport_spi_master_data *drv_data;
+	unsigned long flags;
+	struct spi_message *next_msg;
+
+	drv_data = container_of(work, struct bfin_sport_spi_master_data, pump_messages);
+
+	/* Lock queue and check for queue work */
+	spin_lock_irqsave(&drv_data->lock, flags);
+	if (list_empty(&drv_data->queue) || !drv_data->run) {
+		/* pumper kicked off but no work to do */
+		drv_data->busy = 0;
+		spin_unlock_irqrestore(&drv_data->lock, flags);
+		return;
+	}
+
+	/* Make sure we are not already running a message */
+	if (drv_data->cur_msg) {
+		spin_unlock_irqrestore(&drv_data->lock, flags);
+		return;
+	}
+
+	/* Extract head of queue */
+	next_msg = list_entry(drv_data->queue.next,
+		struct spi_message, queue);
+
+	drv_data->cur_msg = next_msg;
+
+	/* Setup the SSP using the per chip configuration */
+	drv_data->cur_chip = spi_get_ctldata(drv_data->cur_msg->spi);
+
+	list_del_init(&drv_data->cur_msg->queue);
+
+	/* Initialize message state */
+	drv_data->cur_msg->state = START_STATE;
+	drv_data->cur_transfer = list_entry(drv_data->cur_msg->transfers.next,
+					    struct spi_transfer, transfer_list);
+	bfin_sport_spi_restore_state(drv_data);
+	dev_dbg(drv_data->dev, "got a message to pump, "
+		"state is set to: baud %d, cs_gpio %i, ctl 0x%x\n",
+		drv_data->cur_chip->baud, drv_data->cur_chip->cs_gpio,
+		drv_data->cur_chip->ctl_reg);
+
+	dev_dbg(drv_data->dev,
+		"the first transfer len is %d\n",
+		drv_data->cur_transfer->len);
+
+	/* Mark as busy and launch transfers */
+	tasklet_schedule(&drv_data->pump_transfers);
+
+	drv_data->busy = 1;
+	spin_unlock_irqrestore(&drv_data->lock, flags);
+}
+
+/*
+ * got a msg to transfer, queue it in drv_data->queue.
+ * And kick off message pumper
+ */
+static int
+bfin_sport_spi_transfer(struct spi_device *spi, struct spi_message *msg)
+{
+	struct bfin_sport_spi_master_data *drv_data = spi_master_get_devdata(spi->master);
+	unsigned long flags;
+
+	spin_lock_irqsave(&drv_data->lock, flags);
+
+	if (!drv_data->run) {
+		spin_unlock_irqrestore(&drv_data->lock, flags);
+		return -ESHUTDOWN;
+	}
+
+	msg->actual_length = 0;
+	msg->status = -EINPROGRESS;
+	msg->state = START_STATE;
+
+	dev_dbg(&spi->dev, "adding an msg in transfer()\n");
+	list_add_tail(&msg->queue, &drv_data->queue);
+
+	if (drv_data->run && !drv_data->busy)
+		queue_work(drv_data->workqueue, &drv_data->pump_messages);
+
+	spin_unlock_irqrestore(&drv_data->lock, flags);
+
+	return 0;
+}
+
+/* Called every time common spi devices change state */
+static int
+bfin_sport_spi_setup(struct spi_device *spi)
+{
+	struct bfin_sport_spi_slave_data *chip, *first = NULL;
+	int ret;
+
+	/* Only alloc (or use chip_info) on first setup */
+	chip = spi_get_ctldata(spi);
+	if (chip == NULL) {
+		struct bfin5xx_spi_chip *chip_info;
+
+		chip = first = kzalloc(sizeof(*chip), GFP_KERNEL);
+		if (!chip)
+			return -ENOMEM;
+
+		/* platform chip_info isn't required */
+		chip_info = spi->controller_data;
+		if (chip_info) {
+			/*
+			 * DITFS and TDTYPE are only thing we don't set, but
+			 * they probably shouldn't be changed by people.
+			 */
+			if (chip_info->ctl_reg || chip_info->enable_dma) {
+				ret = -EINVAL;
+				dev_err(&spi->dev, "don't set ctl_reg/enable_dma fields");
+				goto error;
+			}
+			chip->cs_chg_udelay = chip_info->cs_chg_udelay;
+			chip->idle_tx_val = chip_info->idle_tx_val;
+			spi->bits_per_word = chip_info->bits_per_word;
+		}
+	}
+
+	if (spi->bits_per_word != 8 && spi->bits_per_word != 16) {
+		ret = -EINVAL;
+		goto error;
+	}
+
+	/* translate common spi framework into our register
+	 * following configure contents are same for tx and rx.
+	 */
+
+	if (spi->mode & SPI_CPHA)
+		chip->ctl_reg &= ~TCKFE;
+	else
+		chip->ctl_reg |= TCKFE;
+
+	if (spi->mode & SPI_LSB_FIRST)
+		chip->ctl_reg |= TLSBIT;
+	else
+		chip->ctl_reg &= ~TLSBIT;
+
+	/* Sport in master mode */
+	chip->ctl_reg |= ITCLK | ITFS | TFSR | LATFS | LTFS;
+
+	chip->baud = bfin_sport_hz_to_spi_baud(spi->max_speed_hz);
+
+	chip->cs_gpio = spi->chip_select;
+	ret = gpio_request(chip->cs_gpio, spi->modalias);
+	if (ret)
+		goto error;
+
+	dev_dbg(&spi->dev, "setup spi chip %s, width is %d\n",
+			spi->modalias, spi->bits_per_word);
+	dev_dbg(&spi->dev, "ctl_reg is 0x%x, GPIO is %i\n",
+			chip->ctl_reg, spi->chip_select);
+
+	spi_set_ctldata(spi, chip);
+
+	bfin_sport_spi_cs_deactive(chip);
+
+	return ret;
+
+ error:
+	kfree(first);
+	return ret;
+}
+
+/*
+ * callback for spi framework.
+ * clean driver specific data
+ */
+static void
+bfin_sport_spi_cleanup(struct spi_device *spi)
+{
+	struct bfin_sport_spi_slave_data *chip = spi_get_ctldata(spi);
+
+	if (!chip)
+		return;
+
+	gpio_free(chip->cs_gpio);
+
+	kfree(chip);
+}
+
+static int
+bfin_sport_spi_init_queue(struct bfin_sport_spi_master_data *drv_data)
+{
+	INIT_LIST_HEAD(&drv_data->queue);
+	spin_lock_init(&drv_data->lock);
+
+	drv_data->run = false;
+	drv_data->busy = 0;
+
+	/* init transfer tasklet */
+	tasklet_init(&drv_data->pump_transfers,
+		     bfin_sport_spi_pump_transfers, (unsigned long)drv_data);
+
+	/* init messages workqueue */
+	INIT_WORK(&drv_data->pump_messages, bfin_sport_spi_pump_messages);
+	drv_data->workqueue =
+	    create_singlethread_workqueue(dev_name(drv_data->master->dev.parent));
+	if (drv_data->workqueue == NULL)
+		return -EBUSY;
+
+	return 0;
+}
+
+static int
+bfin_sport_spi_start_queue(struct bfin_sport_spi_master_data *drv_data)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&drv_data->lock, flags);
+
+	if (drv_data->run || drv_data->busy) {
+		spin_unlock_irqrestore(&drv_data->lock, flags);
+		return -EBUSY;
+	}
+
+	drv_data->run = true;
+	drv_data->cur_msg = NULL;
+	drv_data->cur_transfer = NULL;
+	drv_data->cur_chip = NULL;
+	spin_unlock_irqrestore(&drv_data->lock, flags);
+
+	queue_work(drv_data->workqueue, &drv_data->pump_messages);
+
+	return 0;
+}
+
+static inline int
+bfin_sport_spi_stop_queue(struct bfin_sport_spi_master_data *drv_data)
+{
+	unsigned long flags;
+	unsigned limit = 500;
+	int status = 0;
+
+	spin_lock_irqsave(&drv_data->lock, flags);
+
+	/*
+	 * This is a bit lame, but is optimized for the common execution path.
+	 * A wait_queue on the drv_data->busy could be used, but then the common
+	 * execution path (pump_messages) would be required to call wake_up or
+	 * friends on every SPI message. Do this instead
+	 */
+	drv_data->run = false;
+	while (!list_empty(&drv_data->queue) && drv_data->busy && limit--) {
+		spin_unlock_irqrestore(&drv_data->lock, flags);
+		msleep(10);
+		spin_lock_irqsave(&drv_data->lock, flags);
+	}
+
+	if (!list_empty(&drv_data->queue) || drv_data->busy)
+		status = -EBUSY;
+
+	spin_unlock_irqrestore(&drv_data->lock, flags);
+
+	return status;
+}
+
+static inline int
+bfin_sport_spi_destroy_queue(struct bfin_sport_spi_master_data *drv_data)
+{
+	int status;
+
+	status = bfin_sport_spi_stop_queue(drv_data);
+	if (status)
+		return status;
+
+	destroy_workqueue(drv_data->workqueue);
+
+	return 0;
+}
+
+static int __devinit
+bfin_sport_spi_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct bfin5xx_spi_master *platform_info;
+	struct spi_master *master;
+	struct resource *res, *ires;
+	struct bfin_sport_spi_master_data *drv_data;
+	int status;
+
+	platform_info = dev->platform_data;
+
+	/* Allocate master with space for drv_data */
+	master = spi_alloc_master(dev, sizeof(*master) + 16);
+	if (!master) {
+		dev_err(dev, "cannot alloc spi_master\n");
+		return -ENOMEM;
+	}
+
+	drv_data = spi_master_get_devdata(master);
+	drv_data->master = master;
+	drv_data->dev = dev;
+	drv_data->pin_req = platform_info->pin_req;
+
+	master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_LSB_FIRST;
+	master->bus_num = pdev->id;
+	master->num_chipselect = platform_info->num_chipselect;
+	master->cleanup = bfin_sport_spi_cleanup;
+	master->setup = bfin_sport_spi_setup;
+	master->transfer = bfin_sport_spi_transfer;
+
+	/* Find and map our resources */
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (res == NULL) {
+		dev_err(dev, "cannot get IORESOURCE_MEM\n");
+		status = -ENOENT;
+		goto out_error_get_res;
+	}
+
+	drv_data->regs = ioremap(res->start, resource_size(res));
+	if (drv_data->regs == NULL) {
+		dev_err(dev, "cannot map registers\n");
+		status = -ENXIO;
+		goto out_error_ioremap;
+	}
+
+	ires = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+	if (!ires) {
+		dev_err(dev, "cannot get IORESOURCE_IRQ\n");
+		status = -ENODEV;
+		goto out_error_get_ires;
+	}
+	drv_data->err_irq = ires->start;
+
+	/* Initial and start queue */
+	status = bfin_sport_spi_init_queue(drv_data);
+	if (status) {
+		dev_err(dev, "problem initializing queue\n");
+		goto out_error_queue_alloc;
+	}
+
+	status = bfin_sport_spi_start_queue(drv_data);
+	if (status) {
+		dev_err(dev, "problem starting queue\n");
+		goto out_error_queue_alloc;
+	}
+
+	status = request_irq(drv_data->err_irq, sport_err_handler,
+		0, "sport_spi_err", drv_data);
+	if (status) {
+		dev_err(dev, "unable to request sport err irq\n");
+		goto out_error_irq;
+	}
+
+	status = peripheral_request_list(drv_data->pin_req, DRV_NAME);
+	if (status) {
+		dev_err(dev, "requesting peripherals failed\n");
+		goto out_error_peripheral;
+	}
+
+	/* Register with the SPI framework */
+	platform_set_drvdata(pdev, drv_data);
+	status = spi_register_master(master);
+	if (status) {
+		dev_err(dev, "problem registering spi master\n");
+		goto out_error_master;
+	}
+
+	dev_info(dev, "%s, regs_base@%p\n", DRV_DESC, drv_data->regs);
+	return 0;
+
+ out_error_master:
+	peripheral_free_list(drv_data->pin_req);
+ out_error_peripheral:
+	free_irq(drv_data->err_irq, drv_data);
+ out_error_irq:
+ out_error_queue_alloc:
+	bfin_sport_spi_destroy_queue(drv_data);
+ out_error_get_ires:
+	iounmap(drv_data->regs);
+ out_error_ioremap:
+ out_error_get_res:
+	spi_master_put(master);
+
+	return status;
+}
+
+/* stop hardware and remove the driver */
+static int __devexit
+bfin_sport_spi_remove(struct platform_device *pdev)
+{
+	struct bfin_sport_spi_master_data *drv_data = platform_get_drvdata(pdev);
+	int status = 0;
+
+	if (!drv_data)
+		return 0;
+
+	/* Remove the queue */
+	status = bfin_sport_spi_destroy_queue(drv_data);
+	if (status)
+		return status;
+
+	/* Disable the SSP at the peripheral and SOC level */
+	bfin_sport_spi_disable(drv_data);
+
+	/* Disconnect from the SPI framework */
+	spi_unregister_master(drv_data->master);
+
+	peripheral_free_list(drv_data->pin_req);
+
+	/* Prevent double remove */
+	platform_set_drvdata(pdev, NULL);
+
+	return 0;
+}
+
+#ifdef CONFIG_PM
+static int
+bfin_sport_spi_suspend(struct platform_device *pdev, pm_message_t state)
+{
+	struct bfin_sport_spi_master_data *drv_data = platform_get_drvdata(pdev);
+	int status;
+
+	status = bfin_sport_spi_stop_queue(drv_data);
+	if (status)
+		return status;
+
+	/* stop hardware */
+	bfin_sport_spi_disable(drv_data);
+
+	return status;
+}
+
+static int
+bfin_sport_spi_resume(struct platform_device *pdev)
+{
+	struct bfin_sport_spi_master_data *drv_data = platform_get_drvdata(pdev);
+	int status;
+
+	/* Enable the SPI interface */
+	bfin_sport_spi_enable(drv_data);
+
+	/* Start the queue running */
+	status = bfin_sport_spi_start_queue(drv_data);
+	if (status)
+		dev_err(drv_data->dev, "problem resuming queue\n");
+
+	return status;
+}
+#else
+# define bfin_sport_spi_suspend NULL
+# define bfin_sport_spi_resume  NULL
+#endif
+
+static struct platform_driver bfin_sport_spi_driver = {
+	.driver	= {
+		.name = DRV_NAME,
+		.owner = THIS_MODULE,
+	},
+	.probe   = bfin_sport_spi_probe,
+	.remove  = __devexit_p(bfin_sport_spi_remove),
+	.suspend = bfin_sport_spi_suspend,
+	.resume  = bfin_sport_spi_resume,
+};
+
+static int __init bfin_sport_spi_init(void)
+{
+	return platform_driver_register(&bfin_sport_spi_driver);
+}
+module_init(bfin_sport_spi_init);
+
+static void __exit bfin_sport_spi_exit(void)
+{
+	platform_driver_unregister(&bfin_sport_spi_driver);
+}
+module_exit(bfin_sport_spi_exit);
diff -druN linux-2.6.39-libre/drivers/spi/spi.c linux-3.0-rc7-libre/drivers/spi/spi.c
--- linux-2.6.39-libre/drivers/spi/spi.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/spi/spi.c	2011-07-11 19:51:52.000000000 -0400
@@ -1047,8 +1047,8 @@
  * spi_{async,sync}() calls with dma-safe buffers.
  */
 int spi_write_then_read(struct spi_device *spi,
-		const u8 *txbuf, unsigned n_tx,
-		u8 *rxbuf, unsigned n_rx)
+		const void *txbuf, unsigned n_tx,
+		void *rxbuf, unsigned n_rx)
 {
 	static DEFINE_MUTEX(lock);
 
diff -druN linux-2.6.39-libre/drivers/spi/spi_nuc900.c linux-3.0-rc7-libre/drivers/spi/spi_nuc900.c
--- linux-2.6.39-libre/drivers/spi/spi_nuc900.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/spi/spi_nuc900.c	2011-07-11 19:51:52.000000000 -0400
@@ -463,7 +463,7 @@
 
 	platform_set_drvdata(dev, NULL);
 
-	spi_unregister_master(hw->master);
+	spi_bitbang_stop(&hw->bitbang);
 
 	clk_disable(hw->clk);
 	clk_put(hw->clk);
diff -druN linux-2.6.39-libre/drivers/spi/spi_s3c24xx.c linux-3.0-rc7-libre/drivers/spi/spi_s3c24xx.c
--- linux-2.6.39-libre/drivers/spi/spi_s3c24xx.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/spi/spi_s3c24xx.c	2011-07-11 19:51:52.000000000 -0400
@@ -668,7 +668,7 @@
 
 	platform_set_drvdata(dev, NULL);
 
-	spi_unregister_master(hw->master);
+	spi_bitbang_stop(&hw->bitbang);
 
 	clk_disable(hw->clk);
 	clk_put(hw->clk);
diff -druN linux-2.6.39-libre/drivers/spi/spi_s3c64xx.c linux-3.0-rc7-libre/drivers/spi/spi_s3c64xx.c
--- linux-2.6.39-libre/drivers/spi/spi_s3c64xx.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/spi/spi_s3c64xx.c	2011-07-11 19:51:52.000000000 -0400
@@ -116,9 +116,7 @@
 					(((i)->fifo_lvl_mask + 1))) \
 					? 1 : 0)
 
-#define S3C64XX_SPI_ST_TX_DONE(v, i) ((((v) >> (i)->rx_lvl_offset) & \
-					(((i)->fifo_lvl_mask + 1) << 1)) \
-					? 1 : 0)
+#define S3C64XX_SPI_ST_TX_DONE(v, i) (((v) & (1 << (i)->tx_st_done)) ? 1 : 0)
 #define TX_FIFO_LVL(v, i) (((v) >> 6) & (i)->fifo_lvl_mask)
 #define RX_FIFO_LVL(v, i) (((v) >> (i)->rx_lvl_offset) & (i)->fifo_lvl_mask)
 
diff -druN linux-2.6.39-libre/drivers/spi/spi_sh.c linux-3.0-rc7-libre/drivers/spi/spi_sh.c
--- linux-2.6.39-libre/drivers/spi/spi_sh.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/spi/spi_sh.c	2011-07-11 19:51:52.000000000 -0400
@@ -427,10 +427,10 @@
 {
 	struct spi_sh_data *ss = dev_get_drvdata(&pdev->dev);
 
+	spi_unregister_master(ss->master);
 	destroy_workqueue(ss->workqueue);
 	free_irq(ss->irq, ss);
 	iounmap(ss->addr);
-	spi_master_put(ss->master);
 
 	return 0;
 }
diff -druN linux-2.6.39-libre/drivers/spi/spi_tegra.c linux-3.0-rc7-libre/drivers/spi/spi_tegra.c
--- linux-2.6.39-libre/drivers/spi/spi_tegra.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/spi/spi_tegra.c	2011-07-11 19:51:52.000000000 -0400
@@ -578,6 +578,7 @@
 	master = dev_get_drvdata(&pdev->dev);
 	tspi = spi_master_get_devdata(master);
 
+	spi_unregister_master(master);
 	tegra_dma_free_channel(tspi->rx_dma);
 
 	dma_free_coherent(&pdev->dev, sizeof(u32) * BB_LEN,
@@ -586,7 +587,6 @@
 	clk_put(tspi->clk);
 	iounmap(tspi->base);
 
-	spi_master_put(master);
 	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	release_mem_region(r->start, (r->end - r->start) + 1);
 
diff -druN linux-2.6.39-libre/drivers/spi/tle62x0.c linux-3.0-rc7-libre/drivers/spi/tle62x0.c
--- linux-2.6.39-libre/drivers/spi/tle62x0.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/spi/tle62x0.c	2011-07-11 19:51:52.000000000 -0400
@@ -283,7 +283,7 @@
 	return 0;
 
  err_gpios:
-	for (; ptr > 0; ptr--)
+	while (--ptr >= 0)
 		device_remove_file(&spi->dev, gpio_attrs[ptr]);
 
 	device_remove_file(&spi->dev, &dev_attr_status_show);
@@ -301,6 +301,7 @@
 	for (ptr = 0; ptr < st->nr_gpio; ptr++)
 		device_remove_file(&spi->dev, gpio_attrs[ptr]);
 
+	device_remove_file(&spi->dev, &dev_attr_status_show);
 	kfree(st);
 	return 0;
 }
diff -druN linux-2.6.39-libre/drivers/spi/xilinx_spi.c linux-3.0-rc7-libre/drivers/spi/xilinx_spi.c
--- linux-2.6.39-libre/drivers/spi/xilinx_spi.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/spi/xilinx_spi.c	2011-07-11 19:51:52.000000000 -0400
@@ -18,7 +18,6 @@
 #include <linux/interrupt.h>
 #include <linux/of.h>
 #include <linux/platform_device.h>
-#include <linux/mfd/core.h>
 #include <linux/spi/spi.h>
 #include <linux/spi/spi_bitbang.h>
 #include <linux/spi/xilinx_spi.h>
@@ -471,7 +470,7 @@
 	struct spi_master *master;
 	u8 i;
 
-	pdata = mfd_get_data(dev);
+	pdata = dev->dev.platform_data;
 	if (pdata) {
 		num_cs = pdata->num_chipselect;
 		little_endian = pdata->little_endian;
diff -druN linux-2.6.39-libre/drivers/ssb/driver_chipcommon.c linux-3.0-rc7-libre/drivers/ssb/driver_chipcommon.c
--- linux-2.6.39-libre/drivers/ssb/driver_chipcommon.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/ssb/driver_chipcommon.c	2011-07-11 19:51:52.000000000 -0400
@@ -46,40 +46,66 @@
 	if (!ccdev)
 		return;
 	bus = ccdev->bus;
+
+	/* We support SLOW only on 6..9 */
+	if (ccdev->id.revision >= 10 && mode == SSB_CLKMODE_SLOW)
+		mode = SSB_CLKMODE_DYNAMIC;
+
+	if (cc->capabilities & SSB_CHIPCO_CAP_PMU)
+		return; /* PMU controls clockmode, separated function needed */
+	SSB_WARN_ON(ccdev->id.revision >= 20);
+
 	/* chipcommon cores prior to rev6 don't support dynamic clock control */
 	if (ccdev->id.revision < 6)
 		return;
-	/* chipcommon cores rev10 are a whole new ball game */
+
+	/* ChipCommon cores rev10+ need testing */
 	if (ccdev->id.revision >= 10)
 		return;
+
 	if (!(cc->capabilities & SSB_CHIPCO_CAP_PCTL))
 		return;
 
 	switch (mode) {
-	case SSB_CLKMODE_SLOW:
+	case SSB_CLKMODE_SLOW: /* For revs 6..9 only */
 		tmp = chipco_read32(cc, SSB_CHIPCO_SLOWCLKCTL);
 		tmp |= SSB_CHIPCO_SLOWCLKCTL_FSLOW;
 		chipco_write32(cc, SSB_CHIPCO_SLOWCLKCTL, tmp);
 		break;
 	case SSB_CLKMODE_FAST:
-		ssb_pci_xtal(bus, SSB_GPIO_XTAL, 1); /* Force crystal on */
-		tmp = chipco_read32(cc, SSB_CHIPCO_SLOWCLKCTL);
-		tmp &= ~SSB_CHIPCO_SLOWCLKCTL_FSLOW;
-		tmp |= SSB_CHIPCO_SLOWCLKCTL_IPLL;
-		chipco_write32(cc, SSB_CHIPCO_SLOWCLKCTL, tmp);
+		if (ccdev->id.revision < 10) {
+			ssb_pci_xtal(bus, SSB_GPIO_XTAL, 1); /* Force crystal on */
+			tmp = chipco_read32(cc, SSB_CHIPCO_SLOWCLKCTL);
+			tmp &= ~SSB_CHIPCO_SLOWCLKCTL_FSLOW;
+			tmp |= SSB_CHIPCO_SLOWCLKCTL_IPLL;
+			chipco_write32(cc, SSB_CHIPCO_SLOWCLKCTL, tmp);
+		} else {
+			chipco_write32(cc, SSB_CHIPCO_SYSCLKCTL,
+				(chipco_read32(cc, SSB_CHIPCO_SYSCLKCTL) |
+				 SSB_CHIPCO_SYSCLKCTL_FORCEHT));
+			/* udelay(150); TODO: not available in early init */
+		}
 		break;
 	case SSB_CLKMODE_DYNAMIC:
-		tmp = chipco_read32(cc, SSB_CHIPCO_SLOWCLKCTL);
-		tmp &= ~SSB_CHIPCO_SLOWCLKCTL_FSLOW;
-		tmp &= ~SSB_CHIPCO_SLOWCLKCTL_IPLL;
-		tmp &= ~SSB_CHIPCO_SLOWCLKCTL_ENXTAL;
-		if ((tmp & SSB_CHIPCO_SLOWCLKCTL_SRC) != SSB_CHIPCO_SLOWCLKCTL_SRC_XTAL)
-			tmp |= SSB_CHIPCO_SLOWCLKCTL_ENXTAL;
-		chipco_write32(cc, SSB_CHIPCO_SLOWCLKCTL, tmp);
+		if (ccdev->id.revision < 10) {
+			tmp = chipco_read32(cc, SSB_CHIPCO_SLOWCLKCTL);
+			tmp &= ~SSB_CHIPCO_SLOWCLKCTL_FSLOW;
+			tmp &= ~SSB_CHIPCO_SLOWCLKCTL_IPLL;
+			tmp &= ~SSB_CHIPCO_SLOWCLKCTL_ENXTAL;
+			if ((tmp & SSB_CHIPCO_SLOWCLKCTL_SRC) !=
+			    SSB_CHIPCO_SLOWCLKCTL_SRC_XTAL)
+				tmp |= SSB_CHIPCO_SLOWCLKCTL_ENXTAL;
+			chipco_write32(cc, SSB_CHIPCO_SLOWCLKCTL, tmp);
 
-		/* for dynamic control, we have to release our xtal_pu "force on" */
-		if (tmp & SSB_CHIPCO_SLOWCLKCTL_ENXTAL)
-			ssb_pci_xtal(bus, SSB_GPIO_XTAL, 0);
+			/* For dynamic control, we have to release our xtal_pu
+			 * "force on" */
+			if (tmp & SSB_CHIPCO_SLOWCLKCTL_ENXTAL)
+				ssb_pci_xtal(bus, SSB_GPIO_XTAL, 0);
+		} else {
+			chipco_write32(cc, SSB_CHIPCO_SYSCLKCTL,
+				(chipco_read32(cc, SSB_CHIPCO_SYSCLKCTL) &
+				 ~SSB_CHIPCO_SYSCLKCTL_FORCEHT));
+		}
 		break;
 	default:
 		SSB_WARN_ON(1);
@@ -260,6 +286,12 @@
 	if (cc->dev->id.revision >= 11)
 		cc->status = chipco_read32(cc, SSB_CHIPCO_CHIPSTAT);
 	ssb_dprintk(KERN_INFO PFX "chipcommon status is 0x%x\n", cc->status);
+
+	if (cc->dev->id.revision >= 20) {
+		chipco_write32(cc, SSB_CHIPCO_GPIOPULLUP, 0);
+		chipco_write32(cc, SSB_CHIPCO_GPIOPULLDOWN, 0);
+	}
+
 	ssb_pmu_init(cc);
 	chipco_powercontrol_init(cc);
 	ssb_chipco_set_clockmode(cc, SSB_CLKMODE_FAST);
diff -druN linux-2.6.39-libre/drivers/ssb/driver_chipcommon_pmu.c linux-3.0-rc7-libre/drivers/ssb/driver_chipcommon_pmu.c
--- linux-2.6.39-libre/drivers/ssb/driver_chipcommon_pmu.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/ssb/driver_chipcommon_pmu.c	2011-07-11 19:51:52.000000000 -0400
@@ -423,6 +423,8 @@
 
 	switch (bus->chip_id) {
 	case 0x4312:
+		 min_msk = 0xCBB;
+		 break;
 	case 0x4322:
 		/* We keep the default settings:
 		 * min_msk = 0xCBB
diff -druN linux-2.6.39-libre/drivers/ssb/driver_pcicore.c linux-3.0-rc7-libre/drivers/ssb/driver_pcicore.c
--- linux-2.6.39-libre/drivers/ssb/driver_pcicore.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/ssb/driver_pcicore.c	2011-07-11 19:51:52.000000000 -0400
@@ -15,6 +15,11 @@
 
 #include "ssb_private.h"
 
+static u32 ssb_pcie_read(struct ssb_pcicore *pc, u32 address);
+static void ssb_pcie_write(struct ssb_pcicore *pc, u32 address, u32 data);
+static u16 ssb_pcie_mdio_read(struct ssb_pcicore *pc, u8 device, u8 address);
+static void ssb_pcie_mdio_write(struct ssb_pcicore *pc, u8 device,
+				u8 address, u16 data);
 
 static inline
 u32 pcicore_read32(struct ssb_pcicore *pc, u16 offset)
@@ -403,6 +408,107 @@
 }
 #endif /* CONFIG_SSB_PCICORE_HOSTMODE */
 
+/**************************************************
+ * Workarounds.
+ **************************************************/
+
+static void ssb_pcicore_fix_sprom_core_index(struct ssb_pcicore *pc)
+{
+	u16 tmp = pcicore_read16(pc, SSB_PCICORE_SPROM(0));
+	if (((tmp & 0xF000) >> 12) != pc->dev->core_index) {
+		tmp &= ~0xF000;
+		tmp |= (pc->dev->core_index << 12);
+		pcicore_write16(pc, SSB_PCICORE_SPROM(0), tmp);
+	}
+}
+
+static u8 ssb_pcicore_polarity_workaround(struct ssb_pcicore *pc)
+{
+	return (ssb_pcie_read(pc, 0x204) & 0x10) ? 0xC0 : 0x80;
+}
+
+static void ssb_pcicore_serdes_workaround(struct ssb_pcicore *pc)
+{
+	const u8 serdes_pll_device = 0x1D;
+	const u8 serdes_rx_device = 0x1F;
+	u16 tmp;
+
+	ssb_pcie_mdio_write(pc, serdes_rx_device, 1 /* Control */,
+			    ssb_pcicore_polarity_workaround(pc));
+	tmp = ssb_pcie_mdio_read(pc, serdes_pll_device, 1 /* Control */);
+	if (tmp & 0x4000)
+		ssb_pcie_mdio_write(pc, serdes_pll_device, 1, tmp & ~0x4000);
+}
+
+static void ssb_pcicore_pci_setup_workarounds(struct ssb_pcicore *pc)
+{
+	struct ssb_device *pdev = pc->dev;
+	struct ssb_bus *bus = pdev->bus;
+	u32 tmp;
+
+	tmp = pcicore_read32(pc, SSB_PCICORE_SBTOPCI2);
+	tmp |= SSB_PCICORE_SBTOPCI_PREF;
+	tmp |= SSB_PCICORE_SBTOPCI_BURST;
+	pcicore_write32(pc, SSB_PCICORE_SBTOPCI2, tmp);
+
+	if (pdev->id.revision < 5) {
+		tmp = ssb_read32(pdev, SSB_IMCFGLO);
+		tmp &= ~SSB_IMCFGLO_SERTO;
+		tmp |= 2;
+		tmp &= ~SSB_IMCFGLO_REQTO;
+		tmp |= 3 << SSB_IMCFGLO_REQTO_SHIFT;
+		ssb_write32(pdev, SSB_IMCFGLO, tmp);
+		ssb_commit_settings(bus);
+	} else if (pdev->id.revision >= 11) {
+		tmp = pcicore_read32(pc, SSB_PCICORE_SBTOPCI2);
+		tmp |= SSB_PCICORE_SBTOPCI_MRM;
+		pcicore_write32(pc, SSB_PCICORE_SBTOPCI2, tmp);
+	}
+}
+
+static void ssb_pcicore_pcie_setup_workarounds(struct ssb_pcicore *pc)
+{
+	u32 tmp;
+	u8 rev = pc->dev->id.revision;
+
+	if (rev == 0 || rev == 1) {
+		/* TLP Workaround register. */
+		tmp = ssb_pcie_read(pc, 0x4);
+		tmp |= 0x8;
+		ssb_pcie_write(pc, 0x4, tmp);
+	}
+	if (rev == 1) {
+		/* DLLP Link Control register. */
+		tmp = ssb_pcie_read(pc, 0x100);
+		tmp |= 0x40;
+		ssb_pcie_write(pc, 0x100, tmp);
+	}
+
+	if (rev == 0) {
+		const u8 serdes_rx_device = 0x1F;
+
+		ssb_pcie_mdio_write(pc, serdes_rx_device,
+					2 /* Timer */, 0x8128);
+		ssb_pcie_mdio_write(pc, serdes_rx_device,
+					6 /* CDR */, 0x0100);
+		ssb_pcie_mdio_write(pc, serdes_rx_device,
+					7 /* CDR BW */, 0x1466);
+	} else if (rev == 3 || rev == 4 || rev == 5) {
+		/* TODO: DLLP Power Management Threshold */
+		ssb_pcicore_serdes_workaround(pc);
+		/* TODO: ASPM */
+	} else if (rev == 7) {
+		/* TODO: No PLL down */
+	}
+
+	if (rev >= 6) {
+		/* Miscellaneous Configuration Fixup */
+		tmp = pcicore_read16(pc, SSB_PCICORE_SPROM(5));
+		if (!(tmp & 0x8000))
+			pcicore_write16(pc, SSB_PCICORE_SPROM(5),
+					tmp | 0x8000);
+	}
+}
 
 /**************************************************
  * Generic and Clientmode operation code.
@@ -417,14 +523,14 @@
 void ssb_pcicore_init(struct ssb_pcicore *pc)
 {
 	struct ssb_device *dev = pc->dev;
-	struct ssb_bus *bus;
 
 	if (!dev)
 		return;
-	bus = dev->bus;
 	if (!ssb_device_is_enabled(dev))
 		ssb_device_enable(dev, 0);
 
+	ssb_pcicore_fix_sprom_core_index(pc);
+
 #ifdef CONFIG_SSB_PCICORE_HOSTMODE
 	pc->hostmode = pcicore_is_in_hostmode(pc);
 	if (pc->hostmode)
@@ -432,6 +538,13 @@
 #endif /* CONFIG_SSB_PCICORE_HOSTMODE */
 	if (!pc->hostmode)
 		ssb_pcicore_init_clientmode(pc);
+
+	/* Additional PCIe always once-executed workarounds */
+	if (dev->id.coreid == SSB_DEV_PCIE) {
+		ssb_pcicore_serdes_workaround(pc);
+		/* TODO: ASPM */
+		/* TODO: Clock Request Update */
+	}
 }
 
 static u32 ssb_pcie_read(struct ssb_pcicore *pc, u32 address)
@@ -446,58 +559,104 @@
 	pcicore_write32(pc, 0x134, data);
 }
 
-static void ssb_pcie_mdio_write(struct ssb_pcicore *pc, u8 device,
-				u8 address, u16 data)
+static void ssb_pcie_mdio_set_phy(struct ssb_pcicore *pc, u8 phy)
 {
 	const u16 mdio_control = 0x128;
 	const u16 mdio_data = 0x12C;
 	u32 v;
 	int i;
 
+	v = (1 << 30); /* Start of Transaction */
+	v |= (1 << 28); /* Write Transaction */
+	v |= (1 << 17); /* Turnaround */
+	v |= (0x1F << 18);
+	v |= (phy << 4);
+	pcicore_write32(pc, mdio_data, v);
+
+	udelay(10);
+	for (i = 0; i < 200; i++) {
+		v = pcicore_read32(pc, mdio_control);
+		if (v & 0x100 /* Trans complete */)
+			break;
+		msleep(1);
+	}
+}
+
+static u16 ssb_pcie_mdio_read(struct ssb_pcicore *pc, u8 device, u8 address)
+{
+	const u16 mdio_control = 0x128;
+	const u16 mdio_data = 0x12C;
+	int max_retries = 10;
+	u16 ret = 0;
+	u32 v;
+	int i;
+
 	v = 0x80; /* Enable Preamble Sequence */
 	v |= 0x2; /* MDIO Clock Divisor */
 	pcicore_write32(pc, mdio_control, v);
 
+	if (pc->dev->id.revision >= 10) {
+		max_retries = 200;
+		ssb_pcie_mdio_set_phy(pc, device);
+	}
+
 	v = (1 << 30); /* Start of Transaction */
-	v |= (1 << 28); /* Write Transaction */
+	v |= (1 << 29); /* Read Transaction */
 	v |= (1 << 17); /* Turnaround */
-	v |= (u32)device << 22;
+	if (pc->dev->id.revision < 10)
+		v |= (u32)device << 22;
 	v |= (u32)address << 18;
-	v |= data;
 	pcicore_write32(pc, mdio_data, v);
 	/* Wait for the device to complete the transaction */
 	udelay(10);
-	for (i = 0; i < 10; i++) {
+	for (i = 0; i < max_retries; i++) {
 		v = pcicore_read32(pc, mdio_control);
-		if (v & 0x100 /* Trans complete */)
+		if (v & 0x100 /* Trans complete */) {
+			udelay(10);
+			ret = pcicore_read32(pc, mdio_data);
 			break;
+		}
 		msleep(1);
 	}
 	pcicore_write32(pc, mdio_control, 0);
+	return ret;
 }
 
-static void ssb_broadcast_value(struct ssb_device *dev,
-				u32 address, u32 data)
+static void ssb_pcie_mdio_write(struct ssb_pcicore *pc, u8 device,
+				u8 address, u16 data)
 {
-	/* This is used for both, PCI and ChipCommon core, so be careful. */
-	BUILD_BUG_ON(SSB_PCICORE_BCAST_ADDR != SSB_CHIPCO_BCAST_ADDR);
-	BUILD_BUG_ON(SSB_PCICORE_BCAST_DATA != SSB_CHIPCO_BCAST_DATA);
+	const u16 mdio_control = 0x128;
+	const u16 mdio_data = 0x12C;
+	int max_retries = 10;
+	u32 v;
+	int i;
 
-	ssb_write32(dev, SSB_PCICORE_BCAST_ADDR, address);
-	ssb_read32(dev, SSB_PCICORE_BCAST_ADDR); /* flush */
-	ssb_write32(dev, SSB_PCICORE_BCAST_DATA, data);
-	ssb_read32(dev, SSB_PCICORE_BCAST_DATA); /* flush */
-}
+	v = 0x80; /* Enable Preamble Sequence */
+	v |= 0x2; /* MDIO Clock Divisor */
+	pcicore_write32(pc, mdio_control, v);
 
-static void ssb_commit_settings(struct ssb_bus *bus)
-{
-	struct ssb_device *dev;
+	if (pc->dev->id.revision >= 10) {
+		max_retries = 200;
+		ssb_pcie_mdio_set_phy(pc, device);
+	}
 
-	dev = bus->chipco.dev ? bus->chipco.dev : bus->pcicore.dev;
-	if (WARN_ON(!dev))
-		return;
-	/* This forces an update of the cached registers. */
-	ssb_broadcast_value(dev, 0xFD8, 0);
+	v = (1 << 30); /* Start of Transaction */
+	v |= (1 << 28); /* Write Transaction */
+	v |= (1 << 17); /* Turnaround */
+	if (pc->dev->id.revision < 10)
+		v |= (u32)device << 22;
+	v |= (u32)address << 18;
+	v |= data;
+	pcicore_write32(pc, mdio_data, v);
+	/* Wait for the device to complete the transaction */
+	udelay(10);
+	for (i = 0; i < max_retries; i++) {
+		v = pcicore_read32(pc, mdio_control);
+		if (v & 0x100 /* Trans complete */)
+			break;
+		msleep(1);
+	}
+	pcicore_write32(pc, mdio_control, 0);
 }
 
 int ssb_pcicore_dev_irqvecs_enable(struct ssb_pcicore *pc,
@@ -550,48 +709,10 @@
 	if (pc->setup_done)
 		goto out;
 	if (pdev->id.coreid == SSB_DEV_PCI) {
-		tmp = pcicore_read32(pc, SSB_PCICORE_SBTOPCI2);
-		tmp |= SSB_PCICORE_SBTOPCI_PREF;
-		tmp |= SSB_PCICORE_SBTOPCI_BURST;
-		pcicore_write32(pc, SSB_PCICORE_SBTOPCI2, tmp);
-
-		if (pdev->id.revision < 5) {
-			tmp = ssb_read32(pdev, SSB_IMCFGLO);
-			tmp &= ~SSB_IMCFGLO_SERTO;
-			tmp |= 2;
-			tmp &= ~SSB_IMCFGLO_REQTO;
-			tmp |= 3 << SSB_IMCFGLO_REQTO_SHIFT;
-			ssb_write32(pdev, SSB_IMCFGLO, tmp);
-			ssb_commit_settings(bus);
-		} else if (pdev->id.revision >= 11) {
-			tmp = pcicore_read32(pc, SSB_PCICORE_SBTOPCI2);
-			tmp |= SSB_PCICORE_SBTOPCI_MRM;
-			pcicore_write32(pc, SSB_PCICORE_SBTOPCI2, tmp);
-		}
+		ssb_pcicore_pci_setup_workarounds(pc);
 	} else {
 		WARN_ON(pdev->id.coreid != SSB_DEV_PCIE);
-		//TODO: Better make defines for all these magic PCIE values.
-		if ((pdev->id.revision == 0) || (pdev->id.revision == 1)) {
-			/* TLP Workaround register. */
-			tmp = ssb_pcie_read(pc, 0x4);
-			tmp |= 0x8;
-			ssb_pcie_write(pc, 0x4, tmp);
-		}
-		if (pdev->id.revision == 0) {
-			const u8 serdes_rx_device = 0x1F;
-
-			ssb_pcie_mdio_write(pc, serdes_rx_device,
-					    2 /* Timer */, 0x8128);
-			ssb_pcie_mdio_write(pc, serdes_rx_device,
-					    6 /* CDR */, 0x0100);
-			ssb_pcie_mdio_write(pc, serdes_rx_device,
-					    7 /* CDR BW */, 0x1466);
-		} else if (pdev->id.revision == 1) {
-			/* DLLP Link Control register. */
-			tmp = ssb_pcie_read(pc, 0x100);
-			tmp |= 0x40;
-			ssb_pcie_write(pc, 0x100, tmp);
-		}
+		ssb_pcicore_pcie_setup_workarounds(pc);
 	}
 	pc->setup_done = 1;
 out:
diff -druN linux-2.6.39-libre/drivers/ssb/main.c linux-3.0-rc7-libre/drivers/ssb/main.c
--- linux-2.6.39-libre/drivers/ssb/main.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/ssb/main.c	2011-07-11 19:51:52.000000000 -0400
@@ -1117,23 +1117,22 @@
 {
 	u32 rev = ssb_read32(dev, SSB_IDLOW) & SSB_IDLOW_SSBREV;
 
-	/* The REJECT bit changed position in TMSLOW between
-	 * Backplane revisions. */
+	/* The REJECT bit seems to be different for Backplane rev 2.3 */
 	switch (rev) {
 	case SSB_IDLOW_SSBREV_22:
-		return SSB_TMSLOW_REJECT_22;
+	case SSB_IDLOW_SSBREV_24:
+	case SSB_IDLOW_SSBREV_26:
+		return SSB_TMSLOW_REJECT;
 	case SSB_IDLOW_SSBREV_23:
 		return SSB_TMSLOW_REJECT_23;
-	case SSB_IDLOW_SSBREV_24:     /* TODO - find the proper REJECT bits */
-	case SSB_IDLOW_SSBREV_25:     /* same here */
-	case SSB_IDLOW_SSBREV_26:     /* same here */
+	case SSB_IDLOW_SSBREV_25:     /* TODO - find the proper REJECT bit */
 	case SSB_IDLOW_SSBREV_27:     /* same here */
-		return SSB_TMSLOW_REJECT_23;	/* this is a guess */
+		return SSB_TMSLOW_REJECT;	/* this is a guess */
 	default:
 		printk(KERN_INFO "ssb: Backplane Revision 0x%.8X\n", rev);
 		WARN_ON(1);
 	}
-	return (SSB_TMSLOW_REJECT_22 | SSB_TMSLOW_REJECT_23);
+	return (SSB_TMSLOW_REJECT | SSB_TMSLOW_REJECT_23);
 }
 
 int ssb_device_is_enabled(struct ssb_device *dev)
@@ -1309,20 +1308,20 @@
 
 int ssb_bus_powerup(struct ssb_bus *bus, bool dynamic_pctl)
 {
-	struct ssb_chipcommon *cc;
 	int err;
 	enum ssb_clkmode mode;
 
 	err = ssb_pci_xtal(bus, SSB_GPIO_XTAL | SSB_GPIO_PLL, 1);
 	if (err)
 		goto error;
-	cc = &bus->chipco;
-	mode = dynamic_pctl ? SSB_CLKMODE_DYNAMIC : SSB_CLKMODE_FAST;
-	ssb_chipco_set_clockmode(cc, mode);
 
 #ifdef CONFIG_SSB_DEBUG
 	bus->powered_up = 1;
 #endif
+
+	mode = dynamic_pctl ? SSB_CLKMODE_DYNAMIC : SSB_CLKMODE_FAST;
+	ssb_chipco_set_clockmode(&bus->chipco, mode);
+
 	return 0;
 error:
 	ssb_printk(KERN_ERR PFX "Bus powerup failed\n");
@@ -1330,6 +1329,37 @@
 }
 EXPORT_SYMBOL(ssb_bus_powerup);
 
+static void ssb_broadcast_value(struct ssb_device *dev,
+				u32 address, u32 data)
+{
+#ifdef CONFIG_SSB_DRIVER_PCICORE
+	/* This is used for both, PCI and ChipCommon core, so be careful. */
+	BUILD_BUG_ON(SSB_PCICORE_BCAST_ADDR != SSB_CHIPCO_BCAST_ADDR);
+	BUILD_BUG_ON(SSB_PCICORE_BCAST_DATA != SSB_CHIPCO_BCAST_DATA);
+#endif
+
+	ssb_write32(dev, SSB_CHIPCO_BCAST_ADDR, address);
+	ssb_read32(dev, SSB_CHIPCO_BCAST_ADDR); /* flush */
+	ssb_write32(dev, SSB_CHIPCO_BCAST_DATA, data);
+	ssb_read32(dev, SSB_CHIPCO_BCAST_DATA); /* flush */
+}
+
+void ssb_commit_settings(struct ssb_bus *bus)
+{
+	struct ssb_device *dev;
+
+#ifdef CONFIG_SSB_DRIVER_PCICORE
+	dev = bus->chipco.dev ? bus->chipco.dev : bus->pcicore.dev;
+#else
+	dev = bus->chipco.dev;
+#endif
+	if (WARN_ON(!dev))
+		return;
+	/* This forces an update of the cached registers. */
+	ssb_broadcast_value(dev, 0xFD8, 0);
+}
+EXPORT_SYMBOL(ssb_commit_settings);
+
 u32 ssb_admatch_base(u32 adm)
 {
 	u32 base = 0;
diff -druN linux-2.6.39-libre/drivers/ssb/pci.c linux-3.0-rc7-libre/drivers/ssb/pci.c
--- linux-2.6.39-libre/drivers/ssb/pci.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/ssb/pci.c	2011-07-11 19:51:52.000000000 -0400
@@ -662,7 +662,6 @@
 static int ssb_pci_sprom_get(struct ssb_bus *bus,
 			     struct ssb_sprom *sprom)
 {
-	const struct ssb_sprom *fallback;
 	int err;
 	u16 *buf;
 
@@ -707,10 +706,17 @@
 		if (err) {
 			/* All CRC attempts failed.
 			 * Maybe there is no SPROM on the device?
-			 * If we have a fallback, use that. */
-			fallback = ssb_get_fallback_sprom();
-			if (fallback) {
-				memcpy(sprom, fallback, sizeof(*sprom));
+			 * Now we ask the arch code if there is some sprom
+			 * available for this device in some other storage */
+			err = ssb_fill_sprom_with_fallback(bus, sprom);
+			if (err) {
+				ssb_printk(KERN_WARNING PFX "WARNING: Using"
+					   " fallback SPROM failed (err %d)\n",
+					   err);
+			} else {
+				ssb_dprintk(KERN_DEBUG PFX "Using SPROM"
+					    " revision %d provided by"
+					    " platform.\n", sprom->revision);
 				err = 0;
 				goto out_free;
 			}
diff -druN linux-2.6.39-libre/drivers/ssb/scan.c linux-3.0-rc7-libre/drivers/ssb/scan.c
--- linux-2.6.39-libre/drivers/ssb/scan.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/ssb/scan.c	2011-07-11 19:51:52.000000000 -0400
@@ -258,7 +258,10 @@
 #ifdef CONFIG_SSB_PCIHOST
 	if (bus->bustype == SSB_BUSTYPE_PCI) {
 		if (bus->host_pci->vendor == PCI_VENDOR_ID_BROADCOM &&
-		    bus->host_pci->device == 0x4324)
+		    ((bus->host_pci->device == 0x4313) ||
+		     (bus->host_pci->device == 0x431A) ||
+		     (bus->host_pci->device == 0x4321) ||
+		     (bus->host_pci->device == 0x4324)))
 			return 1;
 	}
 #endif /* CONFIG_SSB_PCIHOST */
@@ -307,7 +310,7 @@
 	} else {
 		if (bus->bustype == SSB_BUSTYPE_PCI) {
 			bus->chip_id = pcidev_to_chipid(bus->host_pci);
-			pci_read_config_word(bus->host_pci, PCI_REVISION_ID,
+			pci_read_config_byte(bus->host_pci, PCI_REVISION_ID,
 					     &bus->chip_rev);
 			bus->chip_package = 0;
 		} else {
diff -druN linux-2.6.39-libre/drivers/ssb/sprom.c linux-3.0-rc7-libre/drivers/ssb/sprom.c
--- linux-2.6.39-libre/drivers/ssb/sprom.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/ssb/sprom.c	2011-07-11 19:51:52.000000000 -0400
@@ -17,7 +17,7 @@
 #include <linux/slab.h>
 
 
-static const struct ssb_sprom *fallback_sprom;
+static int(*get_fallback_sprom)(struct ssb_bus *dev, struct ssb_sprom *out);
 
 
 static int sprom2hex(const u16 *sprom, char *buf, size_t buf_len,
@@ -145,36 +145,43 @@
 }
 
 /**
- * ssb_arch_set_fallback_sprom - Set a fallback SPROM for use if no SPROM is found.
+ * ssb_arch_register_fallback_sprom - Registers a method providing a
+ * fallback SPROM if no SPROM is found.
  *
- * @sprom: The SPROM data structure to register.
+ * @sprom_callback: The callback function.
  *
- * With this function the architecture implementation may register a fallback
- * SPROM data structure. The fallback is only used for PCI based SSB devices,
- * where no valid SPROM can be found in the shadow registers.
+ * With this function the architecture implementation may register a
+ * callback handler which fills the SPROM data structure. The fallback is
+ * only used for PCI based SSB devices, where no valid SPROM can be found
+ * in the shadow registers.
  *
- * This function is useful for weird architectures that have a half-assed SSB device
- * hardwired to their PCI bus.
+ * This function is useful for weird architectures that have a half-assed
+ * SSB device hardwired to their PCI bus.
  *
- * Note that it does only work with PCI attached SSB devices. PCMCIA devices currently
- * don't use this fallback.
- * Architectures must provide the SPROM for native SSB devices anyway,
- * so the fallback also isn't used for native devices.
+ * Note that it does only work with PCI attached SSB devices. PCMCIA
+ * devices currently don't use this fallback.
+ * Architectures must provide the SPROM for native SSB devices anyway, so
+ * the fallback also isn't used for native devices.
  *
- * This function is available for architecture code, only. So it is not exported.
+ * This function is available for architecture code, only. So it is not
+ * exported.
  */
-int ssb_arch_set_fallback_sprom(const struct ssb_sprom *sprom)
+int ssb_arch_register_fallback_sprom(int (*sprom_callback)(struct ssb_bus *bus,
+				     struct ssb_sprom *out))
 {
-	if (fallback_sprom)
+	if (get_fallback_sprom)
 		return -EEXIST;
-	fallback_sprom = sprom;
+	get_fallback_sprom = sprom_callback;
 
 	return 0;
 }
 
-const struct ssb_sprom *ssb_get_fallback_sprom(void)
+int ssb_fill_sprom_with_fallback(struct ssb_bus *bus, struct ssb_sprom *out)
 {
-	return fallback_sprom;
+	if (!get_fallback_sprom)
+		return -ENOENT;
+
+	return get_fallback_sprom(bus, out);
 }
 
 /* http://bcm-v4.sipsolutions.net/802.11/IsSpromAvailable */
diff -druN linux-2.6.39-libre/drivers/ssb/ssb_private.h linux-3.0-rc7-libre/drivers/ssb/ssb_private.h
--- linux-2.6.39-libre/drivers/ssb/ssb_private.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/ssb/ssb_private.h	2011-07-11 19:51:52.000000000 -0400
@@ -171,7 +171,8 @@
 			     const char *buf, size_t count,
 			     int (*sprom_check_crc)(const u16 *sprom, size_t size),
 			     int (*sprom_write)(struct ssb_bus *bus, const u16 *sprom));
-extern const struct ssb_sprom *ssb_get_fallback_sprom(void);
+extern int ssb_fill_sprom_with_fallback(struct ssb_bus *bus,
+					struct ssb_sprom *out);
 
 
 /* core.c */
diff -druN linux-2.6.39-libre/drivers/staging/altera-stapl/altera.c linux-3.0-rc7-libre/drivers/staging/altera-stapl/altera.c
--- linux-2.6.39-libre/drivers/staging/altera-stapl/altera.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/altera-stapl/altera.c	2011-07-11 19:51:52.000000000 -0400
@@ -28,7 +28,7 @@
 #include <linux/string.h>
 #include <linux/firmware.h>
 #include <linux/slab.h>
-#include <staging/altera.h>
+#include "altera.h"
 #include "altera-exprt.h"
 #include "altera-jtag.h"
 
diff -druN linux-2.6.39-libre/drivers/staging/altera-stapl/altera.h linux-3.0-rc7-libre/drivers/staging/altera-stapl/altera.h
--- linux-2.6.39-libre/drivers/staging/altera-stapl/altera.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/staging/altera-stapl/altera.h	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,49 @@
+/*
+ * altera.h
+ *
+ * altera FPGA driver
+ *
+ * Copyright (C) Altera Corporation 1998-2001
+ * Copyright (C) 2010 NetUP Inc.
+ * Copyright (C) 2010 Igor M. Liplianin <liplianin@netup.ru>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef _ALTERA_H_
+#define _ALTERA_H_
+
+struct altera_config {
+	void *dev;
+	u8 *action;
+	int (*jtag_io) (void *dev, int tms, int tdi, int tdo);
+};
+
+#if defined(CONFIG_ALTERA_STAPL) || \
+		(defined(CONFIG_ALTERA_STAPL_MODULE) && defined(MODULE))
+
+extern int altera_init(struct altera_config *config, const struct firmware *fw);
+#else
+
+static inline int altera_init(struct altera_config *config,
+						const struct firmware *fw)
+{
+	printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+	return 0;
+}
+#endif /* CONFIG_ALTERA_STAPL */
+
+#endif /* _ALTERA_H_ */
diff -druN linux-2.6.39-libre/drivers/staging/altera-stapl/altera-jtag.c linux-3.0-rc7-libre/drivers/staging/altera-stapl/altera-jtag.c
--- linux-2.6.39-libre/drivers/staging/altera-stapl/altera-jtag.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/altera-stapl/altera-jtag.c	2011-07-11 19:51:52.000000000 -0400
@@ -26,7 +26,7 @@
 #include <linux/delay.h>
 #include <linux/firmware.h>
 #include <linux/slab.h>
-#include <staging/altera.h>
+#include "altera.h"
 #include "altera-exprt.h"
 #include "altera-jtag.h"
 
diff -druN linux-2.6.39-libre/drivers/staging/ath6kl/bmi/include/bmi_internal.h linux-3.0-rc7-libre/drivers/staging/ath6kl/bmi/include/bmi_internal.h
--- linux-2.6.39-libre/drivers/staging/ath6kl/bmi/include/bmi_internal.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/ath6kl/bmi/include/bmi_internal.h	2011-07-11 19:51:52.000000000 -0400
@@ -26,11 +26,10 @@
 
 #include "a_config.h"
 #include "athdefs.h"
-#include "a_types.h"
 #include "a_osapi.h"
 #define ATH_MODULE_NAME bmi
 #include "a_debug.h"
-#include "AR6002/hw2.0/hw/mbox_host_reg.h"
+#include "hw/mbox_host_reg.h"
 #include "bmi_msg.h"
 
 #define ATH_DEBUG_BMI  ATH_DEBUG_MAKE_MODULE_MASK(0)
diff -druN linux-2.6.39-libre/drivers/staging/ath6kl/bmi/src/bmi.c linux-3.0-rc7-libre/drivers/staging/ath6kl/bmi/src/bmi.c
--- linux-2.6.39-libre/drivers/staging/ath6kl/bmi/src/bmi.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/ath6kl/bmi/src/bmi.c	2011-07-11 19:51:52.000000000 -0400
@@ -95,12 +95,12 @@
 BMICleanup(void)
 {
     if (pBMICmdCredits) {
-        A_FREE(pBMICmdCredits);
+        kfree(pBMICmdCredits);
         pBMICmdCredits = NULL;
     }
 
     if (pBMICmdBuf) {
-        A_FREE(pBMICmdBuf);
+        kfree(pBMICmdBuf);
         pBMICmdBuf = NULL;
     }
 }
@@ -127,12 +127,12 @@
     }
 
     if (pBMICmdCredits) {
-        A_FREE(pBMICmdCredits);
+        kfree(pBMICmdCredits);
         pBMICmdCredits = NULL;
     }
 
     if (pBMICmdBuf) {
-        A_FREE(pBMICmdBuf);
+        kfree(pBMICmdBuf);
         pBMICmdBuf = NULL;
     }
 
diff -druN linux-2.6.39-libre/drivers/staging/ath6kl/hif/sdio/linux_sdio/include/hif_internal.h linux-3.0-rc7-libre/drivers/staging/ath6kl/hif/sdio/linux_sdio/include/hif_internal.h
--- linux-2.6.39-libre/drivers/staging/ath6kl/hif/sdio/linux_sdio/include/hif_internal.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/ath6kl/hif/sdio/linux_sdio/include/hif_internal.h	2011-07-11 19:51:52.000000000 -0400
@@ -27,7 +27,6 @@
 
 #include "a_config.h"
 #include "athdefs.h"
-#include "a_types.h"
 #include "a_osapi.h"
 #include "hif.h"
 #include "../../../common/hif_sdio_common.h"
diff -druN linux-2.6.39-libre/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif.c linux-3.0-rc7-libre/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif.c
--- linux-2.6.39-libre/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif.c	2011-07-11 19:51:52.000000000 -0400
@@ -37,7 +37,7 @@
 #include "hif_internal.h"
 #define ATH_MODULE_NAME hif
 #include "a_debug.h"
-#include "AR6002/hw2.0/hw/mbox_host_reg.h"
+#include "hw/mbox_host_reg.h"
 
 #if HIF_USE_DMA_BOUNCE_BUFFER
 /* macro to check if DMA buffer is WORD-aligned and DMA-able.  Most host controllers assume the
@@ -53,62 +53,189 @@
 #if defined(CONFIG_PM)
 #define dev_to_sdio_func(d)	container_of(d, struct sdio_func, dev)
 #define to_sdio_driver(d)      container_of(d, struct sdio_driver, drv)
-static int hifDeviceSuspend(struct device *dev);
-static int hifDeviceResume(struct device *dev);
 #endif /* CONFIG_PM */
-static int hifDeviceInserted(struct sdio_func *func, const struct sdio_device_id *id);
-static void hifDeviceRemoved(struct sdio_func *func);
-static struct hif_device *addHifDevice(struct sdio_func *func);
-static struct hif_device *getHifDevice(struct sdio_func *func);
 static void delHifDevice(struct hif_device * device);
 static int Func0_CMD52WriteByte(struct mmc_card *card, unsigned int address, unsigned char byte);
 static int Func0_CMD52ReadByte(struct mmc_card *card, unsigned int address, unsigned char *byte);
 
+static int hifEnableFunc(struct hif_device *device, struct sdio_func *func);
+static int hifDisableFunc(struct hif_device *device, struct sdio_func *func);
+OSDRV_CALLBACKS osdrvCallbacks;
+
 int reset_sdio_on_unload = 0;
 module_param(reset_sdio_on_unload, int, 0644);
 
 extern u32 nohifscattersupport;
 
+static struct hif_device *ath6kl_alloc_hifdev(struct sdio_func *func)
+{
+	struct hif_device *hifdevice;
 
-/* ------ Static Variables ------ */
-static const struct sdio_device_id ar6k_id_table[] = {
-    {  SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_AR6002_BASE | 0x0))  },
-    {  SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_AR6002_BASE | 0x1))  },
-    {  SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_AR6003_BASE | 0x0))  },
-    {  SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_AR6003_BASE | 0x1))  },
-    { /* null */                                         },
-};
-MODULE_DEVICE_TABLE(sdio, ar6k_id_table);
+	hifdevice = kzalloc(sizeof(struct hif_device), GFP_KERNEL);
 
-static struct sdio_driver ar6k_driver = {
-	.name = "ar6k_wlan",
-	.id_table = ar6k_id_table,
-	.probe = hifDeviceInserted,
-	.remove = hifDeviceRemoved,
+#if HIF_USE_DMA_BOUNCE_BUFFER
+	hifdevice->dma_buffer = kmalloc(HIF_DMA_BUFFER_SIZE, GFP_KERNEL);
+#endif
+	hifdevice->func = func;
+	hifdevice->powerConfig = HIF_DEVICE_POWER_UP;
+	sdio_set_drvdata(func, hifdevice);
+
+	return hifdevice;
+}
+
+static struct hif_device *ath6kl_get_hifdev(struct sdio_func *func)
+{
+	return (struct hif_device *) sdio_get_drvdata(func);
+}
+
+static const struct sdio_device_id ath6kl_hifdev_ids[] = {
+	{ SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_AR6002_BASE | 0x0)) },
+	{ SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_AR6002_BASE | 0x1)) },
+	{ SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_AR6003_BASE | 0x0)) },
+	{ SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_AR6003_BASE | 0x1)) },
+	{ /* null */                                         },
 };
 
+MODULE_DEVICE_TABLE(sdio, ath6kl_hifdev_ids);
+
+static int ath6kl_hifdev_probe(struct sdio_func *func,
+			       const struct sdio_device_id *id)
+{
+	int ret;
+	struct hif_device *device;
+	int count;
+
+	AR_DEBUG_PRINTF(ATH_DEBUG_TRACE,
+			("ath6kl: Function: 0x%X, Vendor ID: 0x%X, "
+			 "Device ID: 0x%X, block size: 0x%X/0x%X\n",
+			func->num, func->vendor, func->device,
+			func->max_blksize, func->cur_blksize));
+
+	ath6kl_alloc_hifdev(func);
+	device = ath6kl_get_hifdev(func);
+
+	device->id = id;
+	device->is_disabled = true;
+
+	spin_lock_init(&device->lock);
+	spin_lock_init(&device->asynclock);
+
+	DL_LIST_INIT(&device->ScatterReqHead);
+
+	/* Try to allow scatter unless globally overridden */
+	if (!nohifscattersupport)
+		device->scatter_enabled = true;
+
+	A_MEMZERO(device->busRequest, sizeof(device->busRequest));
+
+	for (count = 0; count < BUS_REQUEST_MAX_NUM; count++) {
+		sema_init(&device->busRequest[count].sem_req, 0);
+		hifFreeBusRequest(device, &device->busRequest[count]);
+	}
+
+	sema_init(&device->sem_async, 0);
+
+	ret = hifEnableFunc(device, func);
+
+	return ret;
+}
+
+static void ath6kl_hifdev_remove(struct sdio_func *func)
+{
+	int status = 0;
+	struct hif_device *device;
+
+	device = ath6kl_get_hifdev(func);
+	if (device->claimedContext != NULL)
+		status = osdrvCallbacks.
+			deviceRemovedHandler(device->claimedContext, device);
+
+	if (device->is_disabled)
+		device->is_disabled = false;
+	else
+		status = hifDisableFunc(device, func);
+
+	CleanupHIFScatterResources(device);
+
+	delHifDevice(device);
+}
+
 #if defined(CONFIG_PM)
-/* New suspend/resume based on linux-2.6.32
- * Need to patch linux-2.6.32 with mmc2.6.32_suspend.patch
- * Need to patch with msmsdcc2.6.29_suspend.patch for msm_sdcc host
-     */
-static struct dev_pm_ops ar6k_device_pm_ops = {
-	.suspend = hifDeviceSuspend,
-	.resume = hifDeviceResume,
+static int ath6kl_hifdev_suspend(struct device *dev)
+{
+	struct sdio_func *func = dev_to_sdio_func(dev);
+	int status = 0;
+	struct hif_device *device;
+
+	device = ath6kl_get_hifdev(func);
+
+	if (device && device->claimedContext &&
+	    osdrvCallbacks.deviceSuspendHandler) {
+		/* set true first for PowerStateChangeNotify(..) */
+		device->is_suspend = true;
+		status = osdrvCallbacks.
+			deviceSuspendHandler(device->claimedContext);
+		if (status)
+			device->is_suspend = false;
+	}
+
+	CleanupHIFScatterResources(device);
+
+	switch (status) {
+	case 0:
+		return 0;
+	case A_EBUSY:
+		/* Hack for kernel in order to support deep sleep and wow */
+		return -EBUSY;
+	default:
+		return -1;
+	}
+}
+
+static int ath6kl_hifdev_resume(struct device *dev)
+{
+	struct sdio_func *func = dev_to_sdio_func(dev);
+	int status = 0;
+	struct hif_device *device;
+
+	device = ath6kl_get_hifdev(func);
+	if (device && device->claimedContext &&
+	    osdrvCallbacks.deviceSuspendHandler) {
+		status = osdrvCallbacks.
+			deviceResumeHandler(device->claimedContext);
+		if (status == 0)
+			device->is_suspend = false;
+	}
+
+	return status;
+}
+
+static const struct dev_pm_ops ath6kl_hifdev_pmops = {
+	.suspend = ath6kl_hifdev_suspend,
+	.resume = ath6kl_hifdev_resume,
 };
 #endif /* CONFIG_PM */
 
+static struct sdio_driver ath6kl_hifdev_driver = {
+	.name = "ath6kl_hifdev",
+	.id_table = ath6kl_hifdev_ids,
+	.probe = ath6kl_hifdev_probe,
+	.remove = ath6kl_hifdev_remove,
+#if defined(CONFIG_PM)
+	.drv = {
+		.pm = &ath6kl_hifdev_pmops,
+	},
+#endif
+};
+
 /* make sure we only unregister when registered. */
 static int registered = 0;
 
-OSDRV_CALLBACKS osdrvCallbacks;
 extern u32 onebitmode;
 extern u32 busspeedlow;
 extern u32 debughif;
 
 static void ResetAllCards(void);
-static int hifDisableFunc(struct hif_device *device, struct sdio_func *func);
-static int hifEnableFunc(struct hif_device *device, struct sdio_func *func);
 
 #ifdef DEBUG
 
@@ -125,31 +252,22 @@
 /* ------ Functions ------ */
 int HIFInit(OSDRV_CALLBACKS *callbacks)
 {
-    int status;
-    AR_DEBUG_ASSERT(callbacks != NULL);
-
-    A_REGISTER_MODULE_DEBUG_INFO(hif);
+	int r;
+	AR_DEBUG_ASSERT(callbacks != NULL);
 
-    /* store the callback handlers */
-    osdrvCallbacks = *callbacks;
+	A_REGISTER_MODULE_DEBUG_INFO(hif);
 
-    /* Register with bus driver core */
-    AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: HIFInit registering\n"));
-    registered = 1;
-#if defined(CONFIG_PM)
-    if (callbacks->deviceSuspendHandler && callbacks->deviceResumeHandler) {
-        ar6k_driver.drv.pm = &ar6k_device_pm_ops;
-    }
-#endif /* CONFIG_PM */
-    status = sdio_register_driver(&ar6k_driver);
-    AR_DEBUG_ASSERT(status==0);
+	/* store the callback handlers */
+	osdrvCallbacks = *callbacks;
 
-    if (status != 0) {
-        return A_ERROR;
-    }
+	/* Register with bus driver core */
+	registered = 1;
 
-    return 0;
+	r = sdio_register_driver(&ath6kl_hifdev_driver);
+	if (r < 0)
+		return r;
 
+	return 0;
 }
 
 static int
@@ -763,7 +881,7 @@
             registered = 0;
             AR_DEBUG_PRINTF(ATH_DEBUG_TRACE,
                             ("AR6000: Unregistering with the bus driver\n"));
-            sdio_unregister_driver(&ar6k_driver);
+            sdio_unregister_driver(&ath6kl_hifdev_driver);
             AR_DEBUG_PRINTF(ATH_DEBUG_TRACE,
                             ("AR6000: Unregistered\n"));
         }
@@ -778,7 +896,7 @@
     struct hif_device *device;
     AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: +hifIRQHandler\n"));
 
-    device = getHifDevice(func);
+    device = ath6kl_get_hifdev(func);
     atomic_set(&device->irqHandling, 1);
     /* release the host during ints so we can pick it back up when we process cmds */
     sdio_release_host(device->func);
@@ -823,48 +941,6 @@
 }
 #endif
 
-static int hifDeviceInserted(struct sdio_func *func, const struct sdio_device_id *id)
-{
-    int ret;
-    struct hif_device * device;
-    int count;
-
-    AR_DEBUG_PRINTF(ATH_DEBUG_TRACE,
-		    ("AR6000: hifDeviceInserted, Function: 0x%X, Vendor ID: 0x%X, Device ID: 0x%X, block size: 0x%X/0x%X\n",
-		     func->num, func->vendor, func->device, func->max_blksize, func->cur_blksize));
-
-    addHifDevice(func);
-    device = getHifDevice(func);
-
-    device->id = id;
-    device->is_disabled = true;
-
-    spin_lock_init(&device->lock);
-
-    spin_lock_init(&device->asynclock);
-    
-    DL_LIST_INIT(&device->ScatterReqHead);
-    
-    if (!nohifscattersupport) {
-            /* try to allow scatter operation on all instances,
-             * unless globally overridden */
-        device->scatter_enabled = true;
-    }
-
-    /* Initialize the bus requests to be used later */
-    A_MEMZERO(device->busRequest, sizeof(device->busRequest));
-    for (count = 0; count < BUS_REQUEST_MAX_NUM; count ++) {
-        sema_init(&device->busRequest[count].sem_req, 0);
-        hifFreeBusRequest(device, &device->busRequest[count]);
-    }
-    sema_init(&device->sem_async, 0);
-    
-    ret  = hifEnableFunc(device, func);
-
-    return ret;
-}
-
-
 void
 HIFAckInterrupt(struct hif_device *device)
 {
@@ -955,7 +1031,7 @@
     int status = 0;
 
     AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: +hifDisableFunc\n"));
-    device = getHifDevice(func);
+    device = ath6kl_get_hifdev(func);
     if (!IS_ERR(device->async_task)) {
         init_completion(&device->async_completion);
         device->async_shutdown = 1;
@@ -1004,7 +1080,7 @@
     int ret = 0;
     
     AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: +hifEnableFunc\n"));
-    device = getHifDevice(func);
+    device = ath6kl_get_hifdev(func);
 
     if (device->is_disabled) {
        /* enable the SDIO function */
@@ -1016,7 +1092,7 @@
             if (ret) {
                 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("AR6000: failed to enable 4-bit ASYNC IRQ mode %d \n",ret));
                 sdio_release_host(func);
-                return A_ERROR;
+                return ret;
             }
             AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: 4-bit ASYNC IRQ mode enabled\n"));
         }
@@ -1027,14 +1103,14 @@
             AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, ("AR6000: %s(), Unable to enable AR6K: 0x%X\n",
 					  __FUNCTION__, ret));
             sdio_release_host(func);
-            return A_ERROR;
+            return ret;
         }
         ret = sdio_set_block_size(func, HIF_MBOX_BLOCK_SIZE);
         sdio_release_host(func);
         if (ret) {
             AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, ("AR6000: %s(), Unable to set block size 0x%x  AR6K: 0x%X\n",
 					  __FUNCTION__, HIF_MBOX_BLOCK_SIZE, ret));
-            return A_ERROR;
+            return ret;
         }
         device->is_disabled = false;
         /* create async I/O thread */
@@ -1045,7 +1121,7 @@
                                            "AR6K Async");
            if (IS_ERR(device->async_task)) {
                AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, ("AR6000: %s(), to create async task\n", __FUNCTION__));
-                return A_ERROR;
+                return -ENOMEM;
            }
            AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: start async task\n"));
            wake_up_process(device->async_task );    
@@ -1060,14 +1136,14 @@
     } else {
         taskFunc = enable_task;
         taskName = "AR6K enable";
-        ret = A_PENDING;
+        ret = -ENOMEM;
 #endif /* CONFIG_PM */
     }
     /* create resume thread */
     pTask = kthread_create(taskFunc, (void *)device, taskName);
     if (IS_ERR(pTask)) {
         AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, ("AR6000: %s(), to create enabel task\n", __FUNCTION__));
-        return A_ERROR;
+        return -ENOMEM;
     }
     wake_up_process(pTask);
     AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: -hifEnableFunc\n"));
@@ -1076,79 +1152,6 @@
     return ret;
 }
 
-#if defined(CONFIG_PM)
-static int hifDeviceSuspend(struct device *dev)
-{
-    struct sdio_func *func=dev_to_sdio_func(dev);
-    int status = 0;
-    struct hif_device *device;   
-
-    device = getHifDevice(func);
-    AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: +hifDeviceSuspend\n"));
-    if (device && device->claimedContext && osdrvCallbacks.deviceSuspendHandler) {
-        device->is_suspend = true; /* set true first for PowerStateChangeNotify(..) */
-        status = osdrvCallbacks.deviceSuspendHandler(device->claimedContext);
-        if (status) {
-            device->is_suspend = false;
-        }
-    }
-    CleanupHIFScatterResources(device);
-    AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: -hifDeviceSuspend\n"));
-
-    switch (status) {
-    case 0:
-        return 0;
-    case A_EBUSY:
-        return -EBUSY; /* Hack for kernel in order to support deep sleep and wow */
-    default:
-        return -1;
-    }
-}
-
-static int hifDeviceResume(struct device *dev)
-{
-    struct sdio_func *func=dev_to_sdio_func(dev);
-    int status = 0;
-    struct hif_device *device;   
-
-    device = getHifDevice(func);
-    AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: +hifDeviceResume\n"));
-    if (device && device->claimedContext && osdrvCallbacks.deviceSuspendHandler) {
-        status = osdrvCallbacks.deviceResumeHandler(device->claimedContext);
-        if (status == 0) {
-            device->is_suspend = false;
-        }
-    }
-    AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: -hifDeviceResume\n"));
-
-    return status;
-}
-#endif /* CONFIG_PM */
-
-static void hifDeviceRemoved(struct sdio_func *func)
-{
-    int status = 0;
-    struct hif_device *device;
-    AR_DEBUG_ASSERT(func != NULL);
-
-    AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: +hifDeviceRemoved\n"));
-    device = getHifDevice(func);
-    if (device->claimedContext != NULL) {
-        status = osdrvCallbacks.deviceRemovedHandler(device->claimedContext, device);
-    }
-
-    if (device->is_disabled) {
-        device->is_disabled = false;
-    } else {
-        status = hifDisableFunc(device, func);
-    }
-    CleanupHIFScatterResources(device);
-     
-    delHifDevice(device);
-    AR_DEBUG_ASSERT(status == 0);
-    AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: -hifDeviceRemoved\n"));
-}
-
 /*
  * This should be moved to AR6K HTC layer.
  */
@@ -1182,33 +1185,6 @@
     return 0;
 }
     
-
-static struct hif_device *
-addHifDevice(struct sdio_func *func)
-{
-    struct hif_device *hifdevice;
-    AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: addHifDevice\n"));
-    AR_DEBUG_ASSERT(func != NULL);
-    hifdevice = kzalloc(sizeof(struct hif_device), GFP_KERNEL);
-    AR_DEBUG_ASSERT(hifdevice != NULL);
-#if HIF_USE_DMA_BOUNCE_BUFFER
-    hifdevice->dma_buffer = kmalloc(HIF_DMA_BUFFER_SIZE, GFP_KERNEL);
-    AR_DEBUG_ASSERT(hifdevice->dma_buffer != NULL);
-#endif
-    hifdevice->func = func;
-    hifdevice->powerConfig = HIF_DEVICE_POWER_UP;
-    sdio_set_drvdata(func, hifdevice);
-    AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: addHifDevice; 0x%p\n", hifdevice));
-    return hifdevice;
-}
-
-static struct hif_device *
-getHifDevice(struct sdio_func *func)
-{
-    AR_DEBUG_ASSERT(func != NULL);
-    return (struct hif_device *)sdio_get_drvdata(func);
-}
-
 static void
 delHifDevice(struct hif_device * device)
 {
diff -druN linux-2.6.39-libre/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif_scatter.c linux-3.0-rc7-libre/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif_scatter.c
--- linux-2.6.39-libre/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif_scatter.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif_scatter.c	2011-07-11 19:51:52.000000000 -0400
@@ -309,7 +309,7 @@
                                          (MAX_SCATTER_ENTRIES_PER_REQ - 1) * (sizeof(struct hif_scatter_item))); 
            
             if (NULL == pReqPriv->pHifScatterReq) {
-                A_FREE(pReqPriv);
+                kfree(pReqPriv);
                 break;      
             }           
                 /* just zero the main part of the scatter request */
@@ -319,8 +319,8 @@
                 /* allocate a bus request for this scatter request */
             busrequest = hifAllocateBusRequest(device);
             if (NULL == busrequest) {
-                A_FREE(pReqPriv->pHifScatterReq);
-                A_FREE(pReqPriv);
+                kfree(pReqPriv->pHifScatterReq);
+                kfree(pReqPriv);
                 break;    
             }
                 /* assign the scatter request to this bus request */
@@ -382,11 +382,11 @@
         }
         
         if (pReqPriv->pHifScatterReq != NULL) {
-            A_FREE(pReqPriv->pHifScatterReq);   
+            kfree(pReqPriv->pHifScatterReq);   
             pReqPriv->pHifScatterReq = NULL; 
         }
                 
-        A_FREE(pReqPriv);       
+        kfree(pReqPriv);       
     }
 }
 
diff -druN linux-2.6.39-libre/drivers/staging/ath6kl/htc2/AR6000/ar6k.c linux-3.0-rc7-libre/drivers/staging/ath6kl/htc2/AR6000/ar6k.c
--- linux-2.6.39-libre/drivers/staging/ath6kl/htc2/AR6000/ar6k.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/ath6kl/htc2/AR6000/ar6k.c	2011-07-11 19:51:52.000000000 -0400
@@ -25,8 +25,7 @@
 
 #include "a_config.h"
 #include "athdefs.h"
-#include "a_types.h"
-#include "AR6002/hw2.0/hw/mbox_host_reg.h"
+#include "hw/mbox_host_reg.h"
 #include "a_osapi.h"
 #include "../htc_debug.h"
 #include "hif.h"
@@ -743,7 +742,7 @@
         if (NULL == pReq) {
             break;
         }
-        A_FREE(pReq);
+        kfree(pReq);
     }
 
 }
diff -druN linux-2.6.39-libre/drivers/staging/ath6kl/htc2/AR6000/ar6k_events.c linux-3.0-rc7-libre/drivers/staging/ath6kl/htc2/AR6000/ar6k_events.c
--- linux-2.6.39-libre/drivers/staging/ath6kl/htc2/AR6000/ar6k_events.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/ath6kl/htc2/AR6000/ar6k_events.c	2011-07-11 19:51:52.000000000 -0400
@@ -25,8 +25,7 @@
 
 #include "a_config.h"
 #include "athdefs.h"
-#include "a_types.h"
-#include "AR6002/hw2.0/hw/mbox_host_reg.h"
+#include "hw/mbox_host_reg.h"
 #include "a_osapi.h"
 #include "../htc_debug.h"
 #include "hif.h"
diff -druN linux-2.6.39-libre/drivers/staging/ath6kl/htc2/AR6000/ar6k_gmbox.c linux-3.0-rc7-libre/drivers/staging/ath6kl/htc2/AR6000/ar6k_gmbox.c
--- linux-2.6.39-libre/drivers/staging/ath6kl/htc2/AR6000/ar6k_gmbox.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/ath6kl/htc2/AR6000/ar6k_gmbox.c	2011-07-11 19:51:52.000000000 -0400
@@ -24,7 +24,6 @@
 //==============================================================================
 #include "a_config.h"
 #include "athdefs.h"
-#include "a_types.h"
 #include "a_osapi.h"
 #include "../htc_debug.h"
 #include "hif.h"
diff -druN linux-2.6.39-libre/drivers/staging/ath6kl/htc2/AR6000/ar6k_gmbox_hciuart.c linux-3.0-rc7-libre/drivers/staging/ath6kl/htc2/AR6000/ar6k_gmbox_hciuart.c
--- linux-2.6.39-libre/drivers/staging/ath6kl/htc2/AR6000/ar6k_gmbox_hciuart.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/ath6kl/htc2/AR6000/ar6k_gmbox_hciuart.c	2011-07-11 19:51:52.000000000 -0400
@@ -24,7 +24,6 @@
 //==============================================================================
 #include "a_config.h"
 #include "athdefs.h"
-#include "a_types.h"
 #include "a_osapi.h"
 #include "../htc_debug.h"
 #include "hif.h"
@@ -108,7 +107,7 @@
     A_MUTEX_DELETE(&pProtocol->HCIRxLock);
     A_MUTEX_DELETE(&pProtocol->HCITxLock);
         
-    A_FREE(pProtocol);    
+    kfree(pProtocol);    
 }
 
 static int InitTxCreditState(struct gmbox_proto_hci_uart *pProt)
diff -druN linux-2.6.39-libre/drivers/staging/ath6kl/htc2/AR6000/ar6k.h linux-3.0-rc7-libre/drivers/staging/ath6kl/htc2/AR6000/ar6k.h
--- linux-2.6.39-libre/drivers/staging/ath6kl/htc2/AR6000/ar6k.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/ath6kl/htc2/AR6000/ar6k.h	2011-07-11 19:51:52.000000000 -0400
@@ -42,7 +42,6 @@
 
 //#define MBOXHW_UNIT_TEST 1
 
-#include "athstartpack.h"
 PREPACK struct ar6k_irq_proc_registers {
     u8 host_int_status;
     u8 cpu_int_status;
@@ -69,8 +68,6 @@
     u8 int_status_enable;
 } POSTPACK;
 
-#include "athendpack.h"
-
 #define AR6K_IRQ_ENABLE_REGS_SIZE sizeof(struct ar6k_irq_enable_registers)
 
 #define AR6K_REG_IO_BUFFER_SIZE     32
diff -druN linux-2.6.39-libre/drivers/staging/ath6kl/htc2/htc.c linux-3.0-rc7-libre/drivers/staging/ath6kl/htc2/htc.c
--- linux-2.6.39-libre/drivers/staging/ath6kl/htc2/htc.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/ath6kl/htc2/htc.c	2011-07-11 19:51:52.000000000 -0400
@@ -70,7 +70,7 @@
     
     for (i = 0;i < NUM_CONTROL_BUFFERS;i++) {
         if (target->HTCControlBuffers[i].Buffer) {
-            A_FREE(target->HTCControlBuffers[i].Buffer);
+            kfree(target->HTCControlBuffers[i].Buffer);
         }
     }
     
@@ -86,7 +86,7 @@
         A_MUTEX_DELETE(&target->HTCTxLock);
     }
         /* free our instance */
-    A_FREE(target);
+    kfree(target);
 }
 
 /* registered target arrival callback from the HIF layer */
@@ -448,9 +448,7 @@
         pEndpoint->ServiceID = 0;
         pEndpoint->MaxMsgLength = 0;
         pEndpoint->MaxTxQueueDepth = 0;
-#ifdef HTC_EP_STAT_PROFILING
         A_MEMZERO(&pEndpoint->EndPointStats,sizeof(pEndpoint->EndPointStats));
-#endif
         INIT_HTC_PACKET_QUEUE(&pEndpoint->RxBuffers);
         INIT_HTC_PACKET_QUEUE(&pEndpoint->TxQueue);
         INIT_HTC_PACKET_QUEUE(&pEndpoint->RecvIndicationQueue);
@@ -527,7 +525,6 @@
                                 struct htc_endpoint_stats       *pStats)
 {
 
-#ifdef HTC_EP_STAT_PROFILING
     struct htc_target *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);
     bool     clearStats = false;
     bool     sample = false;
@@ -568,9 +565,6 @@
     UNLOCK_HTC_TX(target);
 
     return true;
-#else
-    return false;
-#endif
 }
 
 struct ar6k_device  *HTCGetAR6KDevice(void *HTCHandle)
diff -druN linux-2.6.39-libre/drivers/staging/ath6kl/htc2/htc_internal.h linux-3.0-rc7-libre/drivers/staging/ath6kl/htc2/htc_internal.h
--- linux-2.6.39-libre/drivers/staging/ath6kl/htc2/htc_internal.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/ath6kl/htc2/htc_internal.h	2011-07-11 19:51:52.000000000 -0400
@@ -27,7 +27,6 @@
  * processing errors, the last frame header is dump for comparison */
 //#define HTC_CAPTURE_LAST_FRAME
 
-//#define HTC_EP_STAT_PROFILING
 
 #ifdef __cplusplus
 extern "C" {
@@ -37,7 +36,6 @@
 
 #include "a_config.h"
 #include "athdefs.h"
-#include "a_types.h"
 #include "a_osapi.h"
 #include "htc_debug.h"
 #include "htc.h"
@@ -82,17 +80,10 @@
     struct htc_target           *target;                /* back pointer to target */
     u8 SeqNo;                  /* TX seq no (helpful) for debugging */
     u32 LocalConnectionFlags;   /* local connection flags */
-#ifdef HTC_EP_STAT_PROFILING
     struct htc_endpoint_stats          EndPointStats;          /* endpoint statistics */
-#endif
 };
 
-#ifdef HTC_EP_STAT_PROFILING
 #define INC_HTC_EP_STAT(p,stat,count) (p)->EndPointStats.stat += (count);
-#else
-#define INC_HTC_EP_STAT(p,stat,count)
-#endif
-
 #define HTC_SERVICE_TX_PACKET_TAG  HTC_TX_PACKET_TAG_INTERNAL
 
 #define NUM_CONTROL_BUFFERS     8
diff -druN linux-2.6.39-libre/drivers/staging/ath6kl/htc2/htc_recv.c linux-3.0-rc7-libre/drivers/staging/ath6kl/htc2/htc_recv.c
--- linux-2.6.39-libre/drivers/staging/ath6kl/htc2/htc_recv.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/ath6kl/htc2/htc_recv.c	2011-07-11 19:51:52.000000000 -0400
@@ -36,7 +36,6 @@
                         (pP)->PktInfo.AsRx.ExpectedHdr,        \
                         (pP)->Endpoint))                         
                         
-#ifdef HTC_EP_STAT_PROFILING
 #define HTC_RX_STAT_PROFILE(t,ep,numLookAheads)        \
 {                                                      \
     INC_HTC_EP_STAT((ep), RxReceived, 1);              \
@@ -46,9 +45,6 @@
         INC_HTC_EP_STAT((ep), RxBundleLookAheads, 1);  \
     }                                                  \
 }
-#else
-#define HTC_RX_STAT_PROFILE(t,ep,lookAhead)
-#endif
 
 static void DoRecvCompletion(struct htc_endpoint     *pEndpoint,
                              struct htc_packet_queue *pQueueToIndicate)
@@ -931,12 +927,10 @@
         }
         
         if (!status) {
-#ifdef HTC_EP_STAT_PROFILING
             LOCK_HTC_RX(target);              
             HTC_RX_STAT_PROFILE(target,pEndpoint,numLookAheads);
             INC_HTC_EP_STAT(pEndpoint, RxPacketsBundled, 1);
             UNLOCK_HTC_RX(target);
-#endif      
             if (i == (pScatterReq->ValidScatterEntries - 1)) {
                     /* last packet's more packets flag is set based on the lookahead */
                 SET_MORE_RX_PACKET_INDICATION_FLAG(lookAheads,numLookAheads,pEndpoint,pPacket);
diff -druN linux-2.6.39-libre/drivers/staging/ath6kl/htc2/htc_send.c linux-3.0-rc7-libre/drivers/staging/ath6kl/htc2/htc_send.c
--- linux-2.6.39-libre/drivers/staging/ath6kl/htc2/htc_send.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/ath6kl/htc2/htc_send.c	2011-07-11 19:51:52.000000000 -0400
@@ -776,9 +776,6 @@
         AR_DEBUG_PRINTF(ATH_DEBUG_SEND, ("  Endpoint %d got %d credits \n",
                 pRpt->EndpointID, pRpt->Credits));
 
-
-#ifdef HTC_EP_STAT_PROFILING
-
         INC_HTC_EP_STAT(pEndpoint, TxCreditRpts, 1);
         INC_HTC_EP_STAT(pEndpoint, TxCreditsReturned, pRpt->Credits);
 
@@ -797,8 +794,6 @@
             INC_HTC_EP_STAT(pEndpoint, TxCreditRptsFromOther, 1);
         }
 
-#endif
-
         if (ENDPOINT_0 == pRpt->EndpointID) {
                 /* always give endpoint 0 credits back */
             pEndpoint->CreditDist.TxCredits += pRpt->Credits;
diff -druN linux-2.6.39-libre/drivers/staging/ath6kl/include/a_config.h linux-3.0-rc7-libre/drivers/staging/ath6kl/include/a_config.h
--- linux-2.6.39-libre/drivers/staging/ath6kl/include/a_config.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/ath6kl/include/a_config.h	2011-07-11 19:51:52.000000000 -0400
@@ -26,28 +26,6 @@
 #ifndef _A_CONFIG_H_
 #define _A_CONFIG_H_
 
-#ifdef UNDER_NWIFI
-#include "../os/windows/include/config.h"
-#endif
-
-#ifdef ATHR_CE_LEGACY
-#include "../os/windows/include/config.h"
-#endif
-
-#if defined(__linux__) && !defined(LINUX_EMULATION)
 #include "../os/linux/include/config_linux.h"
-#endif
-
-#ifdef REXOS
-#include "../os/rexos/include/common/config_rexos.h"
-#endif
-
-#ifdef WIN_NWF
-#include "../os/windows/include/win/config_win.h"
-#endif
-
-#ifdef THREADX
-#include "../os/threadx/include/common/config_threadx.h"
-#endif
 
 #endif
diff -druN linux-2.6.39-libre/drivers/staging/ath6kl/include/a_debug.h linux-3.0-rc7-libre/drivers/staging/ath6kl/include/a_debug.h
--- linux-2.6.39-libre/drivers/staging/ath6kl/include/a_debug.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/ath6kl/include/a_debug.h	2011-07-11 19:51:52.000000000 -0400
@@ -27,7 +27,6 @@
 extern "C" {
 #endif /* __cplusplus */
 
-#include <a_types.h>
 #include <a_osapi.h>
 
     /* standard debug print masks bits 0..7 */
@@ -187,35 +186,7 @@
 void a_module_debug_support_init(void);
 void a_module_debug_support_cleanup(void);
 
-#ifdef UNDER_NWIFI
-#include "../os/windows/include/debug.h"
-#endif
-
-#ifdef ATHR_CE_LEGACY
-#include "../os/windows/include/debug.h"
-#endif
-
-#if defined(__linux__) && !defined(LINUX_EMULATION)
 #include "../os/linux/include/debug_linux.h"
-#endif
-
-#ifdef REXOS
-#include "../os/rexos/include/common/debug_rexos.h"
-#endif
-
-#if defined ART_WIN
-#include "../os/win_art/include/debug_win.h"
-#endif
-
-#ifdef WIN_NWF
-#include <debug_win.h>
-#endif
-
-#ifdef THREADX
-#define ATH_DEBUG_MAKE_MODULE_MASK(index)  (1 << (ATH_DEBUG_MODULE_MASK_SHIFT + (index)))
-#include "../os/threadx/include/common/debug_threadx.h"
-#endif  
-
 
 #ifdef __cplusplus
 }
diff -druN linux-2.6.39-libre/drivers/staging/ath6kl/include/a_drv_api.h linux-3.0-rc7-libre/drivers/staging/ath6kl/include/a_drv_api.h
--- linux-2.6.39-libre/drivers/staging/ath6kl/include/a_drv_api.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/ath6kl/include/a_drv_api.h	2011-07-11 19:51:52.000000000 -0400
@@ -130,34 +130,6 @@
 #define A_WMI_PEER_EVENT(devt, eventCode, bssid)    \
     ar6000_peer_event ((devt), (eventCode), (bssid))
 
-#ifdef CONFIG_HOST_GPIO_SUPPORT
-
-#define A_WMI_GPIO_INTR_RX(intr_mask, input_values) \
-    ar6000_gpio_intr_rx((intr_mask), (input_values))
-
-#define A_WMI_GPIO_DATA_RX(reg_id, value) \
-    ar6000_gpio_data_rx((reg_id), (value))
-
-#define A_WMI_GPIO_ACK_RX() \
-    ar6000_gpio_ack_rx()
-
-#endif
-
-#ifdef SEND_EVENT_TO_APP
-
-#define A_WMI_SEND_EVENT_TO_APP(ar, eventId, datap, len) \
-    ar6000_send_event_to_app((ar), (eventId), (datap), (len))
-
-#define A_WMI_SEND_GENERIC_EVENT_TO_APP(ar, eventId, datap, len) \
-    ar6000_send_generic_event_to_app((ar), (eventId), (datap), (len))
-
-#else
-
-#define A_WMI_SEND_EVENT_TO_APP(ar, eventId, datap, len)
-#define A_WMI_SEND_GENERIC_EVENT_TO_APP(ar, eventId, datap, len)
-
-#endif
-
 #ifdef CONFIG_HOST_TCMD_SUPPORT
 #define A_WMI_TCMD_RX_REPORT_EVENT(devt, results, len) \
     ar6000_tcmd_rx_report_event((devt), (results), (len))
diff -druN linux-2.6.39-libre/drivers/staging/ath6kl/include/a_drv.h linux-3.0-rc7-libre/drivers/staging/ath6kl/include/a_drv.h
--- linux-2.6.39-libre/drivers/staging/ath6kl/include/a_drv.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/ath6kl/include/a_drv.h	2011-07-11 19:51:52.000000000 -0400
@@ -27,28 +27,6 @@
 #ifndef _A_DRV_H_
 #define _A_DRV_H_
 
-#if defined(__linux__) && !defined(LINUX_EMULATION)
 #include "../os/linux/include/athdrv_linux.h"
-#endif
-
-#ifdef UNDER_NWIFI
-#include "../os/windows/include/athdrv.h"
-#endif
-
-#ifdef ATHR_CE_LEGACY
-#include "../os/windows/include/athdrv.h"
-#endif
-
-#ifdef REXOS
-#include "../os/rexos/include/common/athdrv_rexos.h"
-#endif
-
-#ifdef WIN_NWF
-#include "../os/windows/include/athdrv.h"
-#endif
-
-#ifdef THREADX
-#include "../os/threadx/include/common/athdrv_threadx.h"
-#endif
 
 #endif /* _ADRV_H_ */
diff -druN linux-2.6.39-libre/drivers/staging/ath6kl/include/a_osapi.h linux-3.0-rc7-libre/drivers/staging/ath6kl/include/a_osapi.h
--- linux-2.6.39-libre/drivers/staging/ath6kl/include/a_osapi.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/ath6kl/include/a_osapi.h	2011-07-11 19:51:52.000000000 -0400
@@ -27,35 +27,6 @@
 #ifndef _A_OSAPI_H_
 #define _A_OSAPI_H_
 
-#if defined(__linux__) && !defined(LINUX_EMULATION)
 #include "../os/linux/include/osapi_linux.h"
-#endif
-
-#ifdef UNDER_NWIFI
-#include "../os/windows/include/osapi.h"
-#include "../os/windows/include/netbuf.h"
-#endif
-
-#ifdef ATHR_CE_LEGACY
-#include "../os/windows/include/osapi.h"
-#include "../os/windows/include/netbuf.h"
-#endif
-
-#ifdef REXOS
-#include "../os/rexos/include/common/osapi_rexos.h"
-#endif
-
-#if defined ART_WIN
-#include "../os/win_art/include/osapi_win.h"
-#include "../os/win_art/include/netbuf.h"
-#endif
-
-#ifdef WIN_NWF
-#include <osapi_win.h>
-#endif 
-
-#if defined(THREADX)
-#include "../os/threadx/include/common/osapi_threadx.h"
-#endif 
 
 #endif /* _OSAPI_H_ */
diff -druN linux-2.6.39-libre/drivers/staging/ath6kl/include/ar6000_api.h linux-3.0-rc7-libre/drivers/staging/ath6kl/include/ar6000_api.h
--- linux-2.6.39-libre/drivers/staging/ath6kl/include/ar6000_api.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/ath6kl/include/ar6000_api.h	2011-07-11 19:51:52.000000000 -0400
@@ -26,29 +26,7 @@
 #ifndef _AR6000_API_H_
 #define _AR6000_API_H_
 
-#if defined(__linux__) && !defined(LINUX_EMULATION)
 #include "../os/linux/include/ar6xapi_linux.h"
-#endif
-
-#ifdef UNDER_NWIFI
-#include "../os/windows/include/ar6xapi.h"
-#endif
-
-#ifdef ATHR_CE_LEGACY
-#include "../os/windows/include/ar6xapi.h"
-#endif
-
-#ifdef REXOS
-#include "../os/rexos/include/common/ar6xapi_rexos.h"
-#endif
-
-#if defined ART_WIN
-#include "../os/win_art/include/ar6xapi_win.h"
-#endif
-
-#ifdef WIN_NWF
-#include "../os/windows/include/ar6xapi.h"
-#endif
 
 #endif /* _AR6000_API_H */
 
diff -druN linux-2.6.39-libre/drivers/staging/ath6kl/include/athendpack.h linux-3.0-rc7-libre/drivers/staging/ath6kl/include/athendpack.h
--- linux-2.6.39-libre/drivers/staging/ath6kl/include/athendpack.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/ath6kl/include/athendpack.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,52 +0,0 @@
-//------------------------------------------------------------------------------
-// <copyright file="athendpack.h" company="Atheros">
-//    Copyright (c) 2004-2010 Atheros Corporation.  All rights reserved.
-// 
-//
-// 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.
-//
-//
-//------------------------------------------------------------------------------
-//==============================================================================
-// end compiler-specific structure packing
-//
-// Author(s): ="Atheros"
-//==============================================================================
-#ifdef VXWORKS
-#endif /* VXWORKS */
-
-#if defined(LINUX) || defined(__linux__)
-#endif /* LINUX */
-
-#ifdef QNX
-#endif /* QNX */
-
-#ifdef INTEGRITY
-#include "integrity/athendpack_integrity.h"
-#endif /* INTEGRITY */
-
-#ifdef NUCLEUS
-#endif /* NUCLEUS */
-
-
-#ifdef UNDER_NWIFI
-#include "../os/windows/include/athendpack.h"
-#endif
-
-#ifdef ATHR_CE_LEGACY
-#include "../os/windows/include/athendpack.h"
-#endif /* WINCE */
-
-#ifdef WIN_NWF
-#include <athendpack_win.h>
-#endif 
diff -druN linux-2.6.39-libre/drivers/staging/ath6kl/include/athstartpack.h linux-3.0-rc7-libre/drivers/staging/ath6kl/include/athstartpack.h
--- linux-2.6.39-libre/drivers/staging/ath6kl/include/athstartpack.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/ath6kl/include/athstartpack.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,55 +0,0 @@
-//------------------------------------------------------------------------------
-// <copyright file="athstartpack.h" company="Atheros">
-//    Copyright (c) 2004-2010 Atheros Corporation.  All rights reserved.
-// 
-//
-// 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.
-//
-//
-//------------------------------------------------------------------------------
-//==============================================================================
-// start compiler-specific structure packing
-//
-// Author(s): ="Atheros"
-//==============================================================================
-#ifdef VXWORKS
-#endif /* VXWORKS */
-
-#if defined(LINUX) || defined(__linux__)
-#endif /* LINUX */
-
-#ifdef QNX
-#endif /* QNX */
-
-#ifdef INTEGRITY
-#include "integrity/athstartpack_integrity.h"
-#endif /* INTEGRITY */
-
-#ifdef NUCLEUS
-#endif /* NUCLEUS */
-
-#ifdef UNDER_NWIFI
-#include "../os/windows/include/athstartpack.h"
-#endif
-
-#ifdef ATHR_CE_LEGACY
-#include "../os/windows/include/athstartpack.h"
-#endif /* WINCE */
-
-#ifdef WIN_NWF
-#include <athstartpack_win.h>
-#endif
-
-#ifdef THREADX
-#include "../os/threadx/include/common/osapi_threadx.h"
-#endif 
diff -druN linux-2.6.39-libre/drivers/staging/ath6kl/include/a_types.h linux-3.0-rc7-libre/drivers/staging/ath6kl/include/a_types.h
--- linux-2.6.39-libre/drivers/staging/ath6kl/include/a_types.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/ath6kl/include/a_types.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,58 +0,0 @@
-//------------------------------------------------------------------------------
-// <copyright file="a_types.h" company="Atheros">
-//    Copyright (c) 2004-2010 Atheros Corporation.  All rights reserved.
-// 
-//
-// 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.
-//
-//
-//------------------------------------------------------------------------------
-//==============================================================================
-// This file contains the definitions of the basic atheros data types.
-// It is used to map the data types in atheros files to a platform specific
-// type.
-//
-// Author(s): ="Atheros"
-//==============================================================================
-#ifndef _A_TYPES_H_
-#define _A_TYPES_H_
-
-#if defined(__linux__) && !defined(LINUX_EMULATION)
-#include "../os/linux/include/athtypes_linux.h"
-#endif
-
-#ifdef UNDER_NWIFI
-#include "../os/windows/include/athtypes.h"
-#endif
-
-#ifdef ATHR_CE_LEGACY
-#include "../os/windows/include/athtypes.h"
-#endif
-
-#ifdef REXOS
-#include "../os/rexos/include/common/athtypes_rexos.h"
-#endif
-
-#if defined ART_WIN
-#include "../os/win_art/include/athtypes_win.h"
-#endif
-
-#ifdef WIN_NWF
-#include <athtypes_win.h>
-#endif
-
-#ifdef THREADX
-#include "../os/threadx/include/common/athtypes_threadx.h"
-#endif
-
-#endif /* _ATHTYPES_H_ */
diff -druN linux-2.6.39-libre/drivers/staging/ath6kl/include/bmi.h linux-3.0-rc7-libre/drivers/staging/ath6kl/include/bmi.h
--- linux-2.6.39-libre/drivers/staging/ath6kl/include/bmi.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/ath6kl/include/bmi.h	2011-07-11 19:51:52.000000000 -0400
@@ -32,7 +32,6 @@
 /* Header files */
 #include "a_config.h"
 #include "athdefs.h"
-#include "a_types.h"
 #include "hif.h"
 #include "a_osapi.h"
 #include "bmi_msg.h"
diff -druN linux-2.6.39-libre/drivers/staging/ath6kl/include/common/a_hci.h linux-3.0-rc7-libre/drivers/staging/ath6kl/include/common/a_hci.h
--- linux-2.6.39-libre/drivers/staging/ath6kl/include/common/a_hci.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/ath6kl/include/common/a_hci.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,682 +0,0 @@
-//-
-// Copyright (c) 2009-2010 Atheros Communications Inc.
-// All rights reserved.
-// 
-//
-// Permission to use, copy, modify, and/or distribute this software for any
-// purpose with or without fee is hereby granted, provided that the above
-// copyright notice and this permission notice appear in all copies.
-//
-// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
-// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-//
-//
-//
-//
-
-
-#ifndef __A_HCI_H__
-#define __A_HCI_H__
-
-#define HCI_CMD_OGF_MASK            0x3F
-#define HCI_CMD_OGF_SHIFT           10
-#define HCI_CMD_GET_OGF(opcode)     ((opcode >> HCI_CMD_OGF_SHIFT) & HCI_CMD_OGF_MASK)
-
-#define HCI_CMD_OCF_MASK            0x3FF
-#define HCI_CMD_OCF_SHIFT           0 
-#define HCI_CMD_GET_OCF(opcode)     (((opcode) >> HCI_CMD_OCF_SHIFT) & HCI_CMD_OCF_MASK)
-
-#define HCI_FORM_OPCODE(ocf, ogf)    ((ocf & HCI_CMD_OCF_MASK) << HCI_CMD_OCF_SHIFT | \
-                                          (ogf & HCI_CMD_OGF_MASK) << HCI_CMD_OGF_SHIFT)
-
-
-/*======== HCI Opcode groups ===============*/
-#define OGF_NOP                         0x00
-#define OGF_LINK_CONTROL                0x01
-#define OGF_LINK_POLICY                 0x03
-#define OGF_INFO_PARAMS                 0x04
-#define OGF_STATUS                      0x05
-#define OGF_TESTING                     0x06
-#define OGF_BLUETOOTH                   0x3E
-#define OGF_VENDOR_DEBUG                0x3F
-
-
-
-#define OCF_NOP                         0x00
-
-
-/*===== Link Control Commands Opcode===================*/
-#define OCF_HCI_Create_Physical_Link                0x35
-#define OCF_HCI_Accept_Physical_Link_Req            0x36
-#define OCF_HCI_Disconnect_Physical_Link            0x37
-#define OCF_HCI_Create_Logical_Link                 0x38
-#define OCF_HCI_Accept_Logical_Link                 0x39
-#define OCF_HCI_Disconnect_Logical_Link             0x3A
-#define OCF_HCI_Logical_Link_Cancel                 0x3B
-#define OCF_HCI_Flow_Spec_Modify                    0x3C
-
-
-
-/*===== Link Policy Commands Opcode====================*/
-#define OCF_HCI_Set_Event_Mask                      0x01
-#define OCF_HCI_Reset                               0x03
-#define OCF_HCI_Read_Conn_Accept_Timeout            0x15
-#define OCF_HCI_Write_Conn_Accept_Timeout           0x16
-#define OCF_HCI_Read_Link_Supervision_Timeout       0x36
-#define OCF_HCI_Write_Link_Supervision_Timeout      0x37
-#define OCF_HCI_Enhanced_Flush                      0x5F
-#define OCF_HCI_Read_Logical_Link_Accept_Timeout    0x61
-#define OCF_HCI_Write_Logical_Link_Accept_Timeout   0x62
-#define OCF_HCI_Set_Event_Mask_Page_2               0x63
-#define OCF_HCI_Read_Location_Data                  0x64
-#define OCF_HCI_Write_Location_Data                 0x65
-#define OCF_HCI_Read_Flow_Control_Mode              0x66
-#define OCF_HCI_Write_Flow_Control_Mode             0x67
-#define OCF_HCI_Read_BE_Flush_Timeout               0x69
-#define OCF_HCI_Write_BE_Flush_Timeout              0x6A
-#define OCF_HCI_Short_Range_Mode                    0x6B
-
-
-/*======== Info Commands Opcode========================*/
-#define OCF_HCI_Read_Local_Ver_Info                 0x01
-#define OCF_HCI_Read_Local_Supported_Cmds           0x02
-#define OCF_HCI_Read_Data_Block_Size                0x0A
-/*======== Status Commands Opcode======================*/
-#define OCF_HCI_Read_Failed_Contact_Counter         0x01
-#define OCF_HCI_Reset_Failed_Contact_Counter        0x02
-#define OCF_HCI_Read_Link_Quality                   0x03
-#define OCF_HCI_Read_RSSI                           0x05
-#define OCF_HCI_Read_Local_AMP_Info                 0x09    
-#define OCF_HCI_Read_Local_AMP_ASSOC                0x0A
-#define OCF_HCI_Write_Remote_AMP_ASSOC              0x0B
-
-
-/*======= AMP_ASSOC Specific TLV tags =================*/
-#define AMP_ASSOC_MAC_ADDRESS_INFO_TYPE             0x1
-#define AMP_ASSOC_PREF_CHAN_LIST                    0x2
-#define AMP_ASSOC_CONNECTED_CHAN                    0x3
-#define AMP_ASSOC_PAL_CAPABILITIES                  0x4
-#define AMP_ASSOC_PAL_VERSION                       0x5
-
-
-/*========= PAL Events =================================*/
-#define PAL_COMMAND_COMPLETE_EVENT                  0x0E
-#define PAL_COMMAND_STATUS_EVENT                    0x0F
-#define PAL_HARDWARE_ERROR_EVENT                    0x10
-#define PAL_FLUSH_OCCURRED_EVENT                    0x11
-#define PAL_LOOPBACK_EVENT                          0x19
-#define PAL_BUFFER_OVERFLOW_EVENT                   0x1A
-#define PAL_QOS_VIOLATION_EVENT                     0x1E
-#define PAL_ENHANCED_FLUSH_COMPLT_EVENT             0x39
-#define PAL_PHYSICAL_LINK_COMPL_EVENT               0x40
-#define PAL_CHANNEL_SELECT_EVENT                    0x41
-#define PAL_DISCONNECT_PHYSICAL_LINK_EVENT          0x42
-#define PAL_PHY_LINK_EARLY_LOSS_WARNING_EVENT       0x43
-#define PAL_PHY_LINK_RECOVERY_EVENT                 0x44
-#define PAL_LOGICAL_LINK_COMPL_EVENT                0x45
-#define PAL_DISCONNECT_LOGICAL_LINK_COMPL_EVENT     0x46
-#define PAL_FLOW_SPEC_MODIFY_COMPL_EVENT            0x47
-#define PAL_NUM_COMPL_DATA_BLOCK_EVENT              0x48
-#define PAL_SHORT_RANGE_MODE_CHANGE_COMPL_EVENT     0x4C
-#define PAL_AMP_STATUS_CHANGE_EVENT                 0x4D
-/*======== End of PAL events definition =================*/
-
-
-/*======== Timeouts (not part of HCI cmd, but input to PAL engine) =========*/
-#define Timer_Conn_Accept_TO                        0x01
-#define Timer_Link_Supervision_TO                   0x02
-
-#define NUM_HCI_COMMAND_PKTS                0x1
-
-
-/*====== NOP Cmd ============================*/
-#define HCI_CMD_NOP                     HCI_FORM_OPCODE(OCF_NOP, OGF_NOP)
-
-
-/*===== Link Control Commands================*/
-#define HCI_Create_Physical_Link        HCI_FORM_OPCODE(OCF_HCI_Create_Physical_Link, OGF_LINK_CONTROL)
-#define HCI_Accept_Physical_Link_Req    HCI_FORM_OPCODE(OCF_HCI_Accept_Physical_Link_Req, OGF_LINK_CONTROL)
-#define HCI_Disconnect_Physical_Link    HCI_FORM_OPCODE(OCF_HCI_Disconnect_Physical_Link, OGF_LINK_CONTROL)
-#define HCI_Create_Logical_Link         HCI_FORM_OPCODE(OCF_HCI_Create_Logical_Link, OGF_LINK_CONTROL)
-#define HCI_Accept_Logical_Link         HCI_FORM_OPCODE(OCF_HCI_Accept_Logical_Link, OGF_LINK_CONTROL)
-#define HCI_Disconnect_Logical_Link     HCI_FORM_OPCODE(OCF_HCI_Disconnect_Logical_Link, OGF_LINK_CONTROL)
-#define HCI_Logical_Link_Cancel         HCI_FORM_OPCODE(OCF_HCI_Logical_Link_Cancel, OGF_LINK_CONTROL)
-#define HCI_Flow_Spec_Modify            HCI_FORM_OPCODE(OCF_HCI_Flow_Spec_Modify, OGF_LINK_CONTROL)
-
-
-/*===== Link Policy Commands ================*/
-#define HCI_Set_Event_Mask              HCI_FORM_OPCODE(OCF_HCI_Set_Event_Mask, OGF_LINK_POLICY)
-#define HCI_Reset                       HCI_FORM_OPCODE(OCF_HCI_Reset, OGF_LINK_POLICY)
-#define HCI_Enhanced_Flush              HCI_FORM_OPCODE(OCF_HCI_Enhanced_Flush, OGF_LINK_POLICY)
-#define HCI_Read_Conn_Accept_Timeout    HCI_FORM_OPCODE(OCF_HCI_Read_Conn_Accept_Timeout, OGF_LINK_POLICY)
-#define HCI_Write_Conn_Accept_Timeout   HCI_FORM_OPCODE(OCF_HCI_Write_Conn_Accept_Timeout, OGF_LINK_POLICY)
-#define HCI_Read_Logical_Link_Accept_Timeout    HCI_FORM_OPCODE(OCF_HCI_Read_Logical_Link_Accept_Timeout, OGF_LINK_POLICY)
-#define HCI_Write_Logical_Link_Accept_Timeout   HCI_FORM_OPCODE(OCF_HCI_Write_Logical_Link_Accept_Timeout, OGF_LINK_POLICY)
-#define HCI_Read_Link_Supervision_Timeout       HCI_FORM_OPCODE(OCF_HCI_Read_Link_Supervision_Timeout, OGF_LINK_POLICY)
-#define HCI_Write_Link_Supervision_Timeout      HCI_FORM_OPCODE(OCF_HCI_Write_Link_Supervision_Timeout, OGF_LINK_POLICY)
-#define HCI_Read_Location_Data          HCI_FORM_OPCODE(OCF_HCI_Read_Location_Data, OGF_LINK_POLICY)
-#define HCI_Write_Location_Data         HCI_FORM_OPCODE(OCF_HCI_Write_Location_Data, OGF_LINK_POLICY)
-#define HCI_Set_Event_Mask_Page_2       HCI_FORM_OPCODE(OCF_HCI_Set_Event_Mask_Page_2, OGF_LINK_POLICY)
-#define HCI_Read_Flow_Control_Mode      HCI_FORM_OPCODE(OCF_HCI_Read_Flow_Control_Mode, OGF_LINK_POLICY)
-#define HCI_Write_Flow_Control_Mode     HCI_FORM_OPCODE(OCF_HCI_Write_Flow_Control_Mode, OGF_LINK_POLICY)
-#define HCI_Write_BE_Flush_Timeout      HCI_FORM_OPCODE(OCF_HCI_Write_BE_Flush_Timeout, OGF_LINK_POLICY)
-#define HCI_Read_BE_Flush_Timeout       HCI_FORM_OPCODE(OCF_HCI_Read_BE_Flush_Timeout, OGF_LINK_POLICY)
-#define HCI_Short_Range_Mode            HCI_FORM_OPCODE(OCF_HCI_Short_Range_Mode, OGF_LINK_POLICY)            
-
-
-/*===== Info Commands =====================*/
-#define HCI_Read_Local_Ver_Info         HCI_FORM_OPCODE(OCF_HCI_Read_Local_Ver_Info,  OGF_INFO_PARAMS)
-#define HCI_Read_Local_Supported_Cmds   HCI_FORM_OPCODE(OCF_HCI_Read_Local_Supported_Cmds, OGF_INFO_PARAMS)
-#define HCI_Read_Data_Block_Size        HCI_FORM_OPCODE(OCF_HCI_Read_Data_Block_Size, OGF_INFO_PARAMS)
-
-/*===== Status Commands =====================*/
-#define HCI_Read_Link_Quality           HCI_FORM_OPCODE(OCF_HCI_Read_Link_Quality, OGF_STATUS)
-#define HCI_Read_RSSI                   HCI_FORM_OPCODE(OCF_HCI_Read_RSSI, OGF_STATUS)
-#define HCI_Read_Local_AMP_Info         HCI_FORM_OPCODE(OCF_HCI_Read_Local_AMP_Info, OGF_STATUS)
-#define HCI_Read_Local_AMP_ASSOC        HCI_FORM_OPCODE(OCF_HCI_Read_Local_AMP_ASSOC, OGF_STATUS)
-#define HCI_Write_Remote_AMP_ASSOC      HCI_FORM_OPCODE(OCF_HCI_Write_Remote_AMP_ASSOC, OGF_STATUS)
-
-/*====== End of cmd definitions =============*/
-
-
-
-/*===== Timeouts(private - can't come from HCI)=================*/
-#define Conn_Accept_TO                  HCI_FORM_OPCODE(Timer_Conn_Accept_TO, OGF_VENDOR_DEBUG)
-#define Link_Supervision_TO             HCI_FORM_OPCODE(Timer_Link_Supervision_TO, OGF_VENDOR_DEBUG)
-
-/*----- PAL Constants (Sec 6 of Doc)------------------------*/
-#define Max80211_PAL_PDU_Size      1492
-#define Max80211_AMP_ASSOC_Len      672
-#define MinGUserPrio                4
-#define MaxGUserPrio                7
-#define BEUserPrio0                 0
-#define BEUserPrio1                 3
-#define Max80211BeaconPeriod        2000    /* in millisec */
-#define ShortRangeModePowerMax      4       /* dBm */
-
-/*------ PAL Protocol Identifiers (Sec5.1) ------------------*/
-typedef enum {
-    ACL_DATA = 0x01,
-    ACTIVITY_REPORT,
-    SECURED_FRAMES,
-    LINK_SUPERVISION_REQ,
-    LINK_SUPERVISION_RESP,
-}PAL_PROTOCOL_IDENTIFIERS;
-
-#define HCI_CMD_HDR_SZ          3
-#define HCI_EVENT_HDR_SIZE      2
-#define MAX_EVT_PKT_SZ          255
-#define AMP_ASSOC_MAX_FRAG_SZ   248
-#define AMP_MAX_GUARANTEED_BW   20000
-
-#define DEFAULT_CONN_ACCPT_TO   5000
-#define DEFAULT_LL_ACCPT_TO     5000
-#define DEFAULT_LSTO            10000
-
-#define PACKET_BASED_FLOW_CONTROL_MODE      0x00
-#define DATA_BLK_BASED_FLOW_CONTROL_MODE    0x01
-
-#define SERVICE_TYPE_BEST_EFFORT    0x01
-#define SERVICE_TYPE_GUARANTEED     0x02
-
-#define MAC_ADDR_LEN            6
-#define LINK_KEY_LEN            32
-
-typedef enum  {
-    ACL_DATA_PB_1ST_NON_AUTOMATICALLY_FLUSHABLE = 0x00,
-    ACL_DATA_PB_CONTINUING_FRAGMENT = 0x01,
-    ACL_DATA_PB_1ST_AUTOMATICALLY_FLUSHABLE = 0x02,
-    ACL_DATA_PB_COMPLETE_PDU = 0x03,
-} ACL_DATA_PB_FLAGS;
-#define ACL_DATA_PB_FLAGS_SHIFT     12
-
-typedef enum {
-    ACL_DATA_BC_POINT_TO_POINT = 0x00,
-} ACL_DATA_BC_FLAGS;
-#define ACL_DATA_BC_FLAGS_SHIFT     14
-
-/* Command pkt */
-typedef struct  hci_cmd_pkt_t {
-    u16 opcode;
-    u8 param_length;
-    u8 params[255];
-} POSTPACK HCI_CMD_PKT;
-
-#define ACL_DATA_HDR_SIZE   4   /* hdl_and flags + data_len */
-/* Data pkt */
-typedef struct  hci_acl_data_pkt_t {
-    u16 hdl_and_flags;
-    u16 data_len;
-    u8 data[Max80211_PAL_PDU_Size];
-} POSTPACK HCI_ACL_DATA_PKT;
-
-/* Event pkt */
-typedef struct  hci_event_pkt_t {
-    u8 event_code;
-    u8 param_len;
-    u8 params[256];
-} POSTPACK HCI_EVENT_PKT;
-
-
-/*============== HCI Command definitions ======================= */
-typedef struct hci_cmd_phy_link_t {
-    u16 opcode;
-    u8 param_length;
-    u8 phy_link_hdl;
-    u8 link_key_len;
-    u8 link_key_type;
-    u8 link_key[LINK_KEY_LEN];
-} POSTPACK HCI_CMD_PHY_LINK;
-
-typedef struct  hci_cmd_write_rem_amp_assoc_t {
-    u16 opcode;
-    u8 param_length;
-    u8 phy_link_hdl;
-    u16 len_so_far;
-    u16 amp_assoc_remaining_len;
-    u8 amp_assoc_frag[AMP_ASSOC_MAX_FRAG_SZ];
-} POSTPACK HCI_CMD_WRITE_REM_AMP_ASSOC;
-
-
-typedef struct  hci_cmd_opcode_hdl_t {
-    u16 opcode;
-    u8 param_length;
-    u16 hdl;
-} POSTPACK HCI_CMD_READ_LINK_QUAL,
-           HCI_CMD_FLUSH,
-           HCI_CMD_READ_LINK_SUPERVISION_TIMEOUT;
-
-typedef struct  hci_cmd_read_local_amp_assoc_t {
-    u16 opcode;
-    u8 param_length;
-    u8 phy_link_hdl;
-    u16 len_so_far;
-    u16 max_rem_amp_assoc_len;
-} POSTPACK HCI_CMD_READ_LOCAL_AMP_ASSOC;
-
-
-typedef struct hci_cmd_set_event_mask_t {
-    u16 opcode;
-    u8 param_length;
-    u64 mask;
-}POSTPACK HCI_CMD_SET_EVT_MASK, HCI_CMD_SET_EVT_MASK_PG_2;
-
-
-typedef struct  hci_cmd_enhanced_flush_t{
-    u16 opcode;
-    u8 param_length;
-    u16 hdl;
-    u8 type;
-} POSTPACK HCI_CMD_ENHANCED_FLUSH;
-
-
-typedef struct  hci_cmd_write_timeout_t {
-    u16 opcode;
-    u8 param_length;
-    u16 timeout;
-} POSTPACK  HCI_CMD_WRITE_TIMEOUT;
-
-typedef struct  hci_cmd_write_link_supervision_timeout_t {
-    u16 opcode;
-    u8 param_length;
-    u16 hdl;
-    u16 timeout;
-} POSTPACK HCI_CMD_WRITE_LINK_SUPERVISION_TIMEOUT;
-
-typedef struct  hci_cmd_write_flow_control_t {
-    u16 opcode;
-    u8 param_length;
-    u8 mode;
-} POSTPACK  HCI_CMD_WRITE_FLOW_CONTROL;
-
-typedef struct  location_data_cfg_t {
-    u8 reg_domain_aware;
-    u8 reg_domain[3];
-    u8 reg_options;
-} POSTPACK LOCATION_DATA_CFG;
-
-typedef struct  hci_cmd_write_location_data_t {
-    u16 opcode;
-    u8 param_length;
-    LOCATION_DATA_CFG   cfg;
-} POSTPACK  HCI_CMD_WRITE_LOCATION_DATA;
-
-
-typedef struct  flow_spec_t {
-    u8 id;
-    u8 service_type;
-    u16 max_sdu;
-    u32 sdu_inter_arrival_time;
-    u32 access_latency;
-    u32 flush_timeout;
-} POSTPACK FLOW_SPEC;
-
-
-typedef struct  hci_cmd_create_logical_link_t {
-    u16 opcode;
-    u8 param_length;
-    u8 phy_link_hdl;
-    FLOW_SPEC   tx_flow_spec;
-    FLOW_SPEC   rx_flow_spec;
-} POSTPACK HCI_CMD_CREATE_LOGICAL_LINK;
-
-typedef struct  hci_cmd_flow_spec_modify_t {
-    u16 opcode;
-    u8 param_length;
-    u16 hdl;
-    FLOW_SPEC   tx_flow_spec;
-    FLOW_SPEC   rx_flow_spec;
-} POSTPACK HCI_CMD_FLOW_SPEC_MODIFY;
-
-typedef struct hci_cmd_logical_link_cancel_t {
-    u16 opcode;
-    u8 param_length;
-    u8 phy_link_hdl;
-    u8 tx_flow_spec_id;
-} POSTPACK HCI_CMD_LOGICAL_LINK_CANCEL;
-
-typedef struct  hci_cmd_disconnect_logical_link_t {
-    u16 opcode;
-    u8 param_length;
-    u16 logical_link_hdl;
-} POSTPACK HCI_CMD_DISCONNECT_LOGICAL_LINK;
-
-typedef struct  hci_cmd_disconnect_phy_link_t {
-    u16 opcode;
-    u8 param_length;
-    u8 phy_link_hdl;
-} POSTPACK HCI_CMD_DISCONNECT_PHY_LINK;
-
-typedef struct  hci_cmd_srm_t {
-    u16 opcode;
-    u8 param_length;
-    u8 phy_link_hdl;
-    u8 mode;
-} POSTPACK HCI_CMD_SHORT_RANGE_MODE;
-/*============== HCI Command definitions end ======================= */
-
-
-
-/*============== HCI Event definitions ============================= */
-
-/* Command complete event */
-typedef struct  hci_event_cmd_complete_t {
-    u8 event_code;
-    u8 param_len;
-    u8 num_hci_cmd_pkts;
-    u16 opcode;
-    u8 params[255];
-} POSTPACK HCI_EVENT_CMD_COMPLETE;
-
-
-/* Command status event */
-typedef struct  hci_event_cmd_status_t {
-    u8 event_code;
-    u8 param_len;
-    u8 status;
-    u8 num_hci_cmd_pkts;
-    u16 opcode;
-} POSTPACK HCI_EVENT_CMD_STATUS;
-
-/* Hardware Error event */
-typedef struct  hci_event_hw_err_t {
-    u8 event_code;
-    u8 param_len;
-    u8 hw_err_code;
-} POSTPACK HCI_EVENT_HW_ERR;
-
-/* Flush occurred event */
-/* Qos Violation event */
-typedef struct  hci_event_handle_t {
-    u8 event_code;
-    u8 param_len;
-    u16 handle;
-} POSTPACK HCI_EVENT_FLUSH_OCCRD,
-           HCI_EVENT_QOS_VIOLATION;
-
-/* Loopback command event */
-typedef struct hci_loopback_cmd_t {
-    u8 event_code;
-    u8 param_len;
-    u8 params[252];
-} POSTPACK HCI_EVENT_LOOPBACK_CMD;
-
-/* Data buffer overflow event */
-typedef struct  hci_data_buf_overflow_t {
-    u8 event_code;
-    u8 param_len;
-    u8 link_type;
-} POSTPACK  HCI_EVENT_DATA_BUF_OVERFLOW;
-
-/* Enhanced Flush complete event */
-typedef struct hci_enhanced_flush_complt_t{
-    u8 event_code;
-    u8 param_len;
-    u16 hdl;
-} POSTPACK  HCI_EVENT_ENHANCED_FLUSH_COMPLT;
-
-/* Channel select event */
-typedef struct  hci_event_chan_select_t {
-    u8 event_code;
-    u8 param_len;
-    u8 phy_link_hdl;
-} POSTPACK HCI_EVENT_CHAN_SELECT;
-
-/* Physical Link Complete event */
-typedef struct  hci_event_phy_link_complete_event_t {
-    u8 event_code;
-    u8 param_len;
-    u8 status;
-    u8 phy_link_hdl;
-} POSTPACK HCI_EVENT_PHY_LINK_COMPLETE;
-
-/* Logical Link complete event */
-typedef struct hci_event_logical_link_complete_event_t {
-    u8 event_code;
-    u8 param_len;
-    u8 status;
-    u16 logical_link_hdl;
-    u8 phy_hdl;
-    u8 tx_flow_id;
-} POSTPACK HCI_EVENT_LOGICAL_LINK_COMPLETE_EVENT;
-
-/* Disconnect Logical Link complete event */
-typedef struct hci_event_disconnect_logical_link_event_t {
-    u8 event_code;
-    u8 param_len;
-    u8 status;
-    u16 logical_link_hdl;
-    u8 reason;
-} POSTPACK HCI_EVENT_DISCONNECT_LOGICAL_LINK_EVENT;
-
-/* Disconnect Physical Link complete event */
-typedef struct hci_event_disconnect_phy_link_complete_t {
-    u8 event_code;
-    u8 param_len;
-    u8 status;
-    u8 phy_link_hdl;
-    u8 reason;
-} POSTPACK HCI_EVENT_DISCONNECT_PHY_LINK_COMPLETE;
-
-typedef struct hci_event_physical_link_loss_early_warning_t{
-    u8 event_code;
-    u8 param_len;
-    u8 phy_hdl;
-    u8 reason;
-} POSTPACK HCI_EVENT_PHY_LINK_LOSS_EARLY_WARNING;
-
-typedef struct hci_event_physical_link_recovery_t{
-    u8 event_code;
-    u8 param_len;
-    u8 phy_hdl;
-} POSTPACK HCI_EVENT_PHY_LINK_RECOVERY;
-
-
-/* Flow spec modify complete event */
-/* Flush event */
-typedef struct hci_event_status_handle_t {
-    u8 event_code;
-    u8 param_len;
-    u8 status;
-    u16 handle;
-} POSTPACK HCI_EVENT_FLOW_SPEC_MODIFY,
-           HCI_EVENT_FLUSH;
-
-
-/* Num of completed data blocks event */
-typedef struct hci_event_num_of_compl_data_blks_t {
-    u8 event_code;
-    u8 param_len;
-    u16 num_data_blks;
-    u8 num_handles;
-    u8 params[255];
-} POSTPACK HCI_EVENT_NUM_COMPL_DATA_BLKS;
-
-/* Short range mode change complete event */
-typedef struct  hci_srm_cmpl_t {
-    u8 event_code;
-    u8 param_len;
-    u8 status;
-    u8 phy_link;
-    u8 state;
-} POSTPACK HCI_EVENT_SRM_COMPL;
-
-typedef struct hci_event_amp_status_change_t{
-    u8 event_code;
-    u8 param_len;
-    u8 status;
-    u8 amp_status;
-} POSTPACK HCI_EVENT_AMP_STATUS_CHANGE;
-
-/*============== Event definitions end =========================== */
-
-
-typedef struct  local_amp_info_resp_t {
-    u8 status;
-    u8 amp_status;
-    u32 total_bw;           /* kbps */
-    u32 max_guranteed_bw;   /* kbps */
-    u32 min_latency;
-    u32 max_pdu_size;
-    u8 amp_type;
-    u16 pal_capabilities;
-    u16 amp_assoc_len;
-    u32 max_flush_timeout;  /* in ms */
-    u32 be_flush_timeout;   /* in ms */
-} POSTPACK  LOCAL_AMP_INFO;
-
-typedef struct  amp_assoc_cmd_resp_t{
-    u8 status;
-    u8 phy_hdl;
-    u16 amp_assoc_len;
-    u8 amp_assoc_frag[AMP_ASSOC_MAX_FRAG_SZ];
-}POSTPACK AMP_ASSOC_CMD_RESP;
-
-
-enum PAL_HCI_CMD_STATUS {
-    PAL_HCI_CMD_PROCESSED,
-    PAL_HCI_CMD_IGNORED
-}; 
-
-
-/*============= HCI Error Codes =======================*/
-#define HCI_SUCCESS                             0x00
-#define HCI_ERR_UNKNOW_CMD                      0x01
-#define HCI_ERR_UNKNOWN_CONN_ID                 0x02
-#define HCI_ERR_HW_FAILURE                      0x03
-#define HCI_ERR_PAGE_TIMEOUT                    0x04
-#define HCI_ERR_AUTH_FAILURE                    0x05
-#define HCI_ERR_KEY_MISSING                     0x06
-#define HCI_ERR_MEM_CAP_EXECED                  0x07
-#define HCI_ERR_CON_TIMEOUT                     0x08
-#define HCI_ERR_CON_LIMIT_EXECED                0x09
-#define	HCI_ERR_ACL_CONN_ALRDY_EXISTS	        0x0B
-#define	HCI_ERR_COMMAND_DISALLOWED		        0x0C
-#define HCI_ERR_CONN_REJ_BY_LIMIT_RES           0x0D
-#define HCI_ERR_CONN_REJ_BY_SEC                 0x0E
-#define HCI_ERR_CONN_REJ_BY_BAD_ADDR            0x0F
-#define HCI_ERR_CONN_ACCPT_TIMEOUT              0x10
-#define HCI_ERR_UNSUPPORT_FEATURE               0x11
-#define HCI_ERR_INVALID_HCI_CMD_PARAMS          0x12
-#define HCI_ERR_REMOTE_USER_TERMINATE_CONN      0x13
-#define HCI_ERR_CON_TERM_BY_HOST                0x16
-#define HCI_ERR_UNSPECIFIED_ERROR               0x1F
-#define HCI_ERR_ENCRYPTION_MODE_NOT_SUPPORT     0x25
-#define HCI_ERR_REQUESTED_QOS_NOT_SUPPORT       0x27
-#define HCI_ERR_QOS_UNACCEPTABLE_PARM           0x2C
-#define HCI_ERR_QOS_REJECTED                    0x2D
-#define HCI_ERR_CONN_REJ_NO_SUITABLE_CHAN       0x39
-
-/*============= HCI Error Codes End =======================*/
-
-
-/* Following are event return parameters.. part of HCI events 
- */
-typedef struct  timeout_read_t {
-    u8 status;
-    u16 timeout;
-}POSTPACK TIMEOUT_INFO;
-
-typedef struct  link_supervision_timeout_read_t {
-    u8 status;
-    u16 hdl;
-    u16 timeout;
-}POSTPACK LINK_SUPERVISION_TIMEOUT_INFO;
-
-typedef struct  status_hdl_t {
-    u8 status;
-    u16 hdl;
-}POSTPACK INFO_STATUS_HDL;
-
-typedef struct write_remote_amp_assoc_t{
-    u8 status;
-    u8 hdl;
-}POSTPACK WRITE_REMOTE_AMP_ASSOC_INFO;
-
-typedef struct  read_loc_info_t {
-    u8 status;
-    LOCATION_DATA_CFG   loc;
-}POSTPACK READ_LOC_INFO;
-
-typedef struct  read_flow_ctrl_mode_t {
-    u8 status;
-    u8 mode;
-}POSTPACK READ_FLWCTRL_INFO;
-
-typedef struct  read_data_blk_size_t {
-    u8 status;
-    u16 max_acl_data_pkt_len;
-    u16 data_block_len;
-    u16 total_num_data_blks;
-}POSTPACK READ_DATA_BLK_SIZE_INFO;
-
-/* Read Link quality info */
-typedef struct link_qual_t {
-    u8 status;
-    u16 hdl;
-    u8 link_qual;
-} POSTPACK READ_LINK_QUAL_INFO,
-            READ_RSSI_INFO;
-
-typedef struct ll_cancel_resp_t {
-    u8 status;
-    u8 phy_link_hdl;
-    u8 tx_flow_spec_id;
-} POSTPACK LL_CANCEL_RESP;
-
-typedef struct read_local_ver_info_t {
-    u8 status;
-    u8 hci_version;
-    u16 hci_revision;
-    u8 pal_version;
-    u16 manf_name;
-    u16 pal_sub_ver;
-} POSTPACK READ_LOCAL_VER_INFO;
-
-
-#endif  /* __A_HCI_H__ */
diff -druN linux-2.6.39-libre/drivers/staging/ath6kl/include/common/AR6002/AR6002_regdump.h linux-3.0-rc7-libre/drivers/staging/ath6kl/include/common/AR6002/AR6002_regdump.h
--- linux-2.6.39-libre/drivers/staging/ath6kl/include/common/AR6002/AR6002_regdump.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/ath6kl/include/common/AR6002/AR6002_regdump.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,60 +0,0 @@
-//------------------------------------------------------------------------------
-// Copyright (c) 2006-2010 Atheros Corporation.  All rights reserved.
-// 
-//
-// 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.
-//
-//
-//------------------------------------------------------------------------------
-//==============================================================================
-// Author(s): ="Atheros"
-//==============================================================================
-
-#ifndef __AR6002_REGDUMP_H__
-#define __AR6002_REGDUMP_H__
-
-#if !defined(__ASSEMBLER__)
-/*
- * XTensa CPU state
- * This must match the state saved by the target exception handler.
- */
-struct XTensa_exception_frame_s {
-    u32 xt_pc;
-    u32 xt_ps;
-    u32 xt_sar;
-    u32 xt_vpri;
-    u32 xt_a2;
-    u32 xt_a3;
-    u32 xt_a4;
-    u32 xt_a5;
-    u32 xt_exccause;
-    u32 xt_lcount;
-    u32 xt_lbeg;
-    u32 xt_lend;
-
-    u32 epc1, epc2, epc3, epc4;
-
-    /* Extra info to simplify post-mortem stack walkback */
-#define AR6002_REGDUMP_FRAMES 10
-    struct {
-        u32 a0;  /* pc */
-        u32 a1;  /* sp */
-        u32 a2;
-        u32 a3;
-    } wb[AR6002_REGDUMP_FRAMES];
-};
-typedef struct XTensa_exception_frame_s CPU_exception_frame_t; 
-#define RD_SIZE sizeof(CPU_exception_frame_t)
-
-#endif
-#endif /* __AR6002_REGDUMP_H__ */
diff -druN linux-2.6.39-libre/drivers/staging/ath6kl/include/common/AR6002/hw2.0/hw/analog_intf_reg.h linux-3.0-rc7-libre/drivers/staging/ath6kl/include/common/AR6002/hw2.0/hw/analog_intf_reg.h
--- linux-2.6.39-libre/drivers/staging/ath6kl/include/common/AR6002/hw2.0/hw/analog_intf_reg.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/ath6kl/include/common/AR6002/hw2.0/hw/analog_intf_reg.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,64 +0,0 @@
-#ifndef _ANALOG_INTF_REG_REG_H_
-#define _ANALOG_INTF_REG_REG_H_
-
-#define SW_OVERRIDE_ADDRESS                      0x00000080
-#define SW_OVERRIDE_OFFSET                       0x00000080
-#define SW_OVERRIDE_SUPDATE_DELAY_MSB            1
-#define SW_OVERRIDE_SUPDATE_DELAY_LSB            1
-#define SW_OVERRIDE_SUPDATE_DELAY_MASK           0x00000002
-#define SW_OVERRIDE_SUPDATE_DELAY_GET(x)         (((x) & SW_OVERRIDE_SUPDATE_DELAY_MASK) >> SW_OVERRIDE_SUPDATE_DELAY_LSB)
-#define SW_OVERRIDE_SUPDATE_DELAY_SET(x)         (((x) << SW_OVERRIDE_SUPDATE_DELAY_LSB) & SW_OVERRIDE_SUPDATE_DELAY_MASK)
-#define SW_OVERRIDE_ENABLE_MSB                   0
-#define SW_OVERRIDE_ENABLE_LSB                   0
-#define SW_OVERRIDE_ENABLE_MASK                  0x00000001
-#define SW_OVERRIDE_ENABLE_GET(x)                (((x) & SW_OVERRIDE_ENABLE_MASK) >> SW_OVERRIDE_ENABLE_LSB)
-#define SW_OVERRIDE_ENABLE_SET(x)                (((x) << SW_OVERRIDE_ENABLE_LSB) & SW_OVERRIDE_ENABLE_MASK)
-
-#define SIN_VAL_ADDRESS                          0x00000084
-#define SIN_VAL_OFFSET                           0x00000084
-#define SIN_VAL_SIN_MSB                          0
-#define SIN_VAL_SIN_LSB                          0
-#define SIN_VAL_SIN_MASK                         0x00000001
-#define SIN_VAL_SIN_GET(x)                       (((x) & SIN_VAL_SIN_MASK) >> SIN_VAL_SIN_LSB)
-#define SIN_VAL_SIN_SET(x)                       (((x) << SIN_VAL_SIN_LSB) & SIN_VAL_SIN_MASK)
-
-#define SW_SCLK_ADDRESS                          0x00000088
-#define SW_SCLK_OFFSET                           0x00000088
-#define SW_SCLK_SW_SCLK_MSB                      0
-#define SW_SCLK_SW_SCLK_LSB                      0
-#define SW_SCLK_SW_SCLK_MASK                     0x00000001
-#define SW_SCLK_SW_SCLK_GET(x)                   (((x) & SW_SCLK_SW_SCLK_MASK) >> SW_SCLK_SW_SCLK_LSB)
-#define SW_SCLK_SW_SCLK_SET(x)                   (((x) << SW_SCLK_SW_SCLK_LSB) & SW_SCLK_SW_SCLK_MASK)
-
-#define SW_CNTL_ADDRESS                          0x0000008c
-#define SW_CNTL_OFFSET                           0x0000008c
-#define SW_CNTL_SW_SCAPTURE_MSB                  2
-#define SW_CNTL_SW_SCAPTURE_LSB                  2
-#define SW_CNTL_SW_SCAPTURE_MASK                 0x00000004
-#define SW_CNTL_SW_SCAPTURE_GET(x)               (((x) & SW_CNTL_SW_SCAPTURE_MASK) >> SW_CNTL_SW_SCAPTURE_LSB)
-#define SW_CNTL_SW_SCAPTURE_SET(x)               (((x) << SW_CNTL_SW_SCAPTURE_LSB) & SW_CNTL_SW_SCAPTURE_MASK)
-#define SW_CNTL_SW_SUPDATE_MSB                   1
-#define SW_CNTL_SW_SUPDATE_LSB                   1
-#define SW_CNTL_SW_SUPDATE_MASK                  0x00000002
-#define SW_CNTL_SW_SUPDATE_GET(x)                (((x) & SW_CNTL_SW_SUPDATE_MASK) >> SW_CNTL_SW_SUPDATE_LSB)
-#define SW_CNTL_SW_SUPDATE_SET(x)                (((x) << SW_CNTL_SW_SUPDATE_LSB) & SW_CNTL_SW_SUPDATE_MASK)
-#define SW_CNTL_SW_SOUT_MSB                      0
-#define SW_CNTL_SW_SOUT_LSB                      0
-#define SW_CNTL_SW_SOUT_MASK                     0x00000001
-#define SW_CNTL_SW_SOUT_GET(x)                   (((x) & SW_CNTL_SW_SOUT_MASK) >> SW_CNTL_SW_SOUT_LSB)
-#define SW_CNTL_SW_SOUT_SET(x)                   (((x) << SW_CNTL_SW_SOUT_LSB) & SW_CNTL_SW_SOUT_MASK)
-
-
-#ifndef __ASSEMBLER__
-
-typedef struct analog_intf_reg_reg_s {
-  unsigned char pad0[128]; /* pad to 0x80 */
-  volatile unsigned int sw_override;
-  volatile unsigned int sin_val;
-  volatile unsigned int sw_sclk;
-  volatile unsigned int sw_cntl;
-} analog_intf_reg_reg_t;
-
-#endif /* __ASSEMBLER__ */
-
-#endif /* _ANALOG_INTF_REG_H_ */
diff -druN linux-2.6.39-libre/drivers/staging/ath6kl/include/common/AR6002/hw2.0/hw/analog_reg.h linux-3.0-rc7-libre/drivers/staging/ath6kl/include/common/AR6002/hw2.0/hw/analog_reg.h
--- linux-2.6.39-libre/drivers/staging/ath6kl/include/common/AR6002/hw2.0/hw/analog_reg.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/ath6kl/include/common/AR6002/hw2.0/hw/analog_reg.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,1932 +0,0 @@
-#ifndef _ANALOG_REG_REG_H_
-#define _ANALOG_REG_REG_H_
-
-#define SYNTH_SYNTH1_ADDRESS                     0x00000000
-#define SYNTH_SYNTH1_OFFSET                      0x00000000
-#define SYNTH_SYNTH1_PWD_BIAS_MSB                31
-#define SYNTH_SYNTH1_PWD_BIAS_LSB                31
-#define SYNTH_SYNTH1_PWD_BIAS_MASK               0x80000000
-#define SYNTH_SYNTH1_PWD_BIAS_GET(x)             (((x) & SYNTH_SYNTH1_PWD_BIAS_MASK) >> SYNTH_SYNTH1_PWD_BIAS_LSB)
-#define SYNTH_SYNTH1_PWD_BIAS_SET(x)             (((x) << SYNTH_SYNTH1_PWD_BIAS_LSB) & SYNTH_SYNTH1_PWD_BIAS_MASK)
-#define SYNTH_SYNTH1_PWD_CP_MSB                  30
-#define SYNTH_SYNTH1_PWD_CP_LSB                  30
-#define SYNTH_SYNTH1_PWD_CP_MASK                 0x40000000
-#define SYNTH_SYNTH1_PWD_CP_GET(x)               (((x) & SYNTH_SYNTH1_PWD_CP_MASK) >> SYNTH_SYNTH1_PWD_CP_LSB)
-#define SYNTH_SYNTH1_PWD_CP_SET(x)               (((x) << SYNTH_SYNTH1_PWD_CP_LSB) & SYNTH_SYNTH1_PWD_CP_MASK)
-#define SYNTH_SYNTH1_PWD_VCMON_MSB               29
-#define SYNTH_SYNTH1_PWD_VCMON_LSB               29
-#define SYNTH_SYNTH1_PWD_VCMON_MASK              0x20000000
-#define SYNTH_SYNTH1_PWD_VCMON_GET(x)            (((x) & SYNTH_SYNTH1_PWD_VCMON_MASK) >> SYNTH_SYNTH1_PWD_VCMON_LSB)
-#define SYNTH_SYNTH1_PWD_VCMON_SET(x)            (((x) << SYNTH_SYNTH1_PWD_VCMON_LSB) & SYNTH_SYNTH1_PWD_VCMON_MASK)
-#define SYNTH_SYNTH1_PWD_VCO_MSB                 28
-#define SYNTH_SYNTH1_PWD_VCO_LSB                 28
-#define SYNTH_SYNTH1_PWD_VCO_MASK                0x10000000
-#define SYNTH_SYNTH1_PWD_VCO_GET(x)              (((x) & SYNTH_SYNTH1_PWD_VCO_MASK) >> SYNTH_SYNTH1_PWD_VCO_LSB)
-#define SYNTH_SYNTH1_PWD_VCO_SET(x)              (((x) << SYNTH_SYNTH1_PWD_VCO_LSB) & SYNTH_SYNTH1_PWD_VCO_MASK)
-#define SYNTH_SYNTH1_PWD_PRESC_MSB               27
-#define SYNTH_SYNTH1_PWD_PRESC_LSB               27
-#define SYNTH_SYNTH1_PWD_PRESC_MASK              0x08000000
-#define SYNTH_SYNTH1_PWD_PRESC_GET(x)            (((x) & SYNTH_SYNTH1_PWD_PRESC_MASK) >> SYNTH_SYNTH1_PWD_PRESC_LSB)
-#define SYNTH_SYNTH1_PWD_PRESC_SET(x)            (((x) << SYNTH_SYNTH1_PWD_PRESC_LSB) & SYNTH_SYNTH1_PWD_PRESC_MASK)
-#define SYNTH_SYNTH1_PWD_LODIV_MSB               26
-#define SYNTH_SYNTH1_PWD_LODIV_LSB               26
-#define SYNTH_SYNTH1_PWD_LODIV_MASK              0x04000000
-#define SYNTH_SYNTH1_PWD_LODIV_GET(x)            (((x) & SYNTH_SYNTH1_PWD_LODIV_MASK) >> SYNTH_SYNTH1_PWD_LODIV_LSB)
-#define SYNTH_SYNTH1_PWD_LODIV_SET(x)            (((x) << SYNTH_SYNTH1_PWD_LODIV_LSB) & SYNTH_SYNTH1_PWD_LODIV_MASK)
-#define SYNTH_SYNTH1_PWD_LOMIX_MSB               25
-#define SYNTH_SYNTH1_PWD_LOMIX_LSB               25
-#define SYNTH_SYNTH1_PWD_LOMIX_MASK              0x02000000
-#define SYNTH_SYNTH1_PWD_LOMIX_GET(x)            (((x) & SYNTH_SYNTH1_PWD_LOMIX_MASK) >> SYNTH_SYNTH1_PWD_LOMIX_LSB)
-#define SYNTH_SYNTH1_PWD_LOMIX_SET(x)            (((x) << SYNTH_SYNTH1_PWD_LOMIX_LSB) & SYNTH_SYNTH1_PWD_LOMIX_MASK)
-#define SYNTH_SYNTH1_FORCE_LO_ON_MSB             24
-#define SYNTH_SYNTH1_FORCE_LO_ON_LSB             24
-#define SYNTH_SYNTH1_FORCE_LO_ON_MASK            0x01000000
-#define SYNTH_SYNTH1_FORCE_LO_ON_GET(x)          (((x) & SYNTH_SYNTH1_FORCE_LO_ON_MASK) >> SYNTH_SYNTH1_FORCE_LO_ON_LSB)
-#define SYNTH_SYNTH1_FORCE_LO_ON_SET(x)          (((x) << SYNTH_SYNTH1_FORCE_LO_ON_LSB) & SYNTH_SYNTH1_FORCE_LO_ON_MASK)
-#define SYNTH_SYNTH1_PWD_LOBUF5G_MSB             23
-#define SYNTH_SYNTH1_PWD_LOBUF5G_LSB             23
-#define SYNTH_SYNTH1_PWD_LOBUF5G_MASK            0x00800000
-#define SYNTH_SYNTH1_PWD_LOBUF5G_GET(x)          (((x) & SYNTH_SYNTH1_PWD_LOBUF5G_MASK) >> SYNTH_SYNTH1_PWD_LOBUF5G_LSB)
-#define SYNTH_SYNTH1_PWD_LOBUF5G_SET(x)          (((x) << SYNTH_SYNTH1_PWD_LOBUF5G_LSB) & SYNTH_SYNTH1_PWD_LOBUF5G_MASK)
-#define SYNTH_SYNTH1_VCOREGBYPASS_MSB            22
-#define SYNTH_SYNTH1_VCOREGBYPASS_LSB            22
-#define SYNTH_SYNTH1_VCOREGBYPASS_MASK           0x00400000
-#define SYNTH_SYNTH1_VCOREGBYPASS_GET(x)         (((x) & SYNTH_SYNTH1_VCOREGBYPASS_MASK) >> SYNTH_SYNTH1_VCOREGBYPASS_LSB)
-#define SYNTH_SYNTH1_VCOREGBYPASS_SET(x)         (((x) << SYNTH_SYNTH1_VCOREGBYPASS_LSB) & SYNTH_SYNTH1_VCOREGBYPASS_MASK)
-#define SYNTH_SYNTH1_VCOREGLEVEL_MSB             21
-#define SYNTH_SYNTH1_VCOREGLEVEL_LSB             20
-#define SYNTH_SYNTH1_VCOREGLEVEL_MASK            0x00300000
-#define SYNTH_SYNTH1_VCOREGLEVEL_GET(x)          (((x) & SYNTH_SYNTH1_VCOREGLEVEL_MASK) >> SYNTH_SYNTH1_VCOREGLEVEL_LSB)
-#define SYNTH_SYNTH1_VCOREGLEVEL_SET(x)          (((x) << SYNTH_SYNTH1_VCOREGLEVEL_LSB) & SYNTH_SYNTH1_VCOREGLEVEL_MASK)
-#define SYNTH_SYNTH1_VCOREGBIAS_MSB              19
-#define SYNTH_SYNTH1_VCOREGBIAS_LSB              18
-#define SYNTH_SYNTH1_VCOREGBIAS_MASK             0x000c0000
-#define SYNTH_SYNTH1_VCOREGBIAS_GET(x)           (((x) & SYNTH_SYNTH1_VCOREGBIAS_MASK) >> SYNTH_SYNTH1_VCOREGBIAS_LSB)
-#define SYNTH_SYNTH1_VCOREGBIAS_SET(x)           (((x) << SYNTH_SYNTH1_VCOREGBIAS_LSB) & SYNTH_SYNTH1_VCOREGBIAS_MASK)
-#define SYNTH_SYNTH1_SLIDINGIF_MSB               17
-#define SYNTH_SYNTH1_SLIDINGIF_LSB               17
-#define SYNTH_SYNTH1_SLIDINGIF_MASK              0x00020000
-#define SYNTH_SYNTH1_SLIDINGIF_GET(x)            (((x) & SYNTH_SYNTH1_SLIDINGIF_MASK) >> SYNTH_SYNTH1_SLIDINGIF_LSB)
-#define SYNTH_SYNTH1_SLIDINGIF_SET(x)            (((x) << SYNTH_SYNTH1_SLIDINGIF_LSB) & SYNTH_SYNTH1_SLIDINGIF_MASK)
-#define SYNTH_SYNTH1_SPARE_PWD_MSB               16
-#define SYNTH_SYNTH1_SPARE_PWD_LSB               16
-#define SYNTH_SYNTH1_SPARE_PWD_MASK              0x00010000
-#define SYNTH_SYNTH1_SPARE_PWD_GET(x)            (((x) & SYNTH_SYNTH1_SPARE_PWD_MASK) >> SYNTH_SYNTH1_SPARE_PWD_LSB)
-#define SYNTH_SYNTH1_SPARE_PWD_SET(x)            (((x) << SYNTH_SYNTH1_SPARE_PWD_LSB) & SYNTH_SYNTH1_SPARE_PWD_MASK)
-#define SYNTH_SYNTH1_CON_VDDVCOREG_MSB           15
-#define SYNTH_SYNTH1_CON_VDDVCOREG_LSB           15
-#define SYNTH_SYNTH1_CON_VDDVCOREG_MASK          0x00008000
-#define SYNTH_SYNTH1_CON_VDDVCOREG_GET(x)        (((x) & SYNTH_SYNTH1_CON_VDDVCOREG_MASK) >> SYNTH_SYNTH1_CON_VDDVCOREG_LSB)
-#define SYNTH_SYNTH1_CON_VDDVCOREG_SET(x)        (((x) << SYNTH_SYNTH1_CON_VDDVCOREG_LSB) & SYNTH_SYNTH1_CON_VDDVCOREG_MASK)
-#define SYNTH_SYNTH1_CON_IVCOREG_MSB             14
-#define SYNTH_SYNTH1_CON_IVCOREG_LSB             14
-#define SYNTH_SYNTH1_CON_IVCOREG_MASK            0x00004000
-#define SYNTH_SYNTH1_CON_IVCOREG_GET(x)          (((x) & SYNTH_SYNTH1_CON_IVCOREG_MASK) >> SYNTH_SYNTH1_CON_IVCOREG_LSB)
-#define SYNTH_SYNTH1_CON_IVCOREG_SET(x)          (((x) << SYNTH_SYNTH1_CON_IVCOREG_LSB) & SYNTH_SYNTH1_CON_IVCOREG_MASK)
-#define SYNTH_SYNTH1_CON_IVCOBUF_MSB             13
-#define SYNTH_SYNTH1_CON_IVCOBUF_LSB             13
-#define SYNTH_SYNTH1_CON_IVCOBUF_MASK            0x00002000
-#define SYNTH_SYNTH1_CON_IVCOBUF_GET(x)          (((x) & SYNTH_SYNTH1_CON_IVCOBUF_MASK) >> SYNTH_SYNTH1_CON_IVCOBUF_LSB)
-#define SYNTH_SYNTH1_CON_IVCOBUF_SET(x)          (((x) << SYNTH_SYNTH1_CON_IVCOBUF_LSB) & SYNTH_SYNTH1_CON_IVCOBUF_MASK)
-#define SYNTH_SYNTH1_SEL_VCMONABUS_MSB           12
-#define SYNTH_SYNTH1_SEL_VCMONABUS_LSB           10
-#define SYNTH_SYNTH1_SEL_VCMONABUS_MASK          0x00001c00
-#define SYNTH_SYNTH1_SEL_VCMONABUS_GET(x)        (((x) & SYNTH_SYNTH1_SEL_VCMONABUS_MASK) >> SYNTH_SYNTH1_SEL_VCMONABUS_LSB)
-#define SYNTH_SYNTH1_SEL_VCMONABUS_SET(x)        (((x) << SYNTH_SYNTH1_SEL_VCMONABUS_LSB) & SYNTH_SYNTH1_SEL_VCMONABUS_MASK)
-#define SYNTH_SYNTH1_PWUP_VCOBUF_PD_MSB          9
-#define SYNTH_SYNTH1_PWUP_VCOBUF_PD_LSB          9
-#define SYNTH_SYNTH1_PWUP_VCOBUF_PD_MASK         0x00000200
-#define SYNTH_SYNTH1_PWUP_VCOBUF_PD_GET(x)       (((x) & SYNTH_SYNTH1_PWUP_VCOBUF_PD_MASK) >> SYNTH_SYNTH1_PWUP_VCOBUF_PD_LSB)
-#define SYNTH_SYNTH1_PWUP_VCOBUF_PD_SET(x)       (((x) << SYNTH_SYNTH1_PWUP_VCOBUF_PD_LSB) & SYNTH_SYNTH1_PWUP_VCOBUF_PD_MASK)
-#define SYNTH_SYNTH1_PWUP_LODIV_PD_MSB           8
-#define SYNTH_SYNTH1_PWUP_LODIV_PD_LSB           8
-#define SYNTH_SYNTH1_PWUP_LODIV_PD_MASK          0x00000100
-#define SYNTH_SYNTH1_PWUP_LODIV_PD_GET(x)        (((x) & SYNTH_SYNTH1_PWUP_LODIV_PD_MASK) >> SYNTH_SYNTH1_PWUP_LODIV_PD_LSB)
-#define SYNTH_SYNTH1_PWUP_LODIV_PD_SET(x)        (((x) << SYNTH_SYNTH1_PWUP_LODIV_PD_LSB) & SYNTH_SYNTH1_PWUP_LODIV_PD_MASK)
-#define SYNTH_SYNTH1_PWUP_LOMIX_PD_MSB           7
-#define SYNTH_SYNTH1_PWUP_LOMIX_PD_LSB           7
-#define SYNTH_SYNTH1_PWUP_LOMIX_PD_MASK          0x00000080
-#define SYNTH_SYNTH1_PWUP_LOMIX_PD_GET(x)        (((x) & SYNTH_SYNTH1_PWUP_LOMIX_PD_MASK) >> SYNTH_SYNTH1_PWUP_LOMIX_PD_LSB)
-#define SYNTH_SYNTH1_PWUP_LOMIX_PD_SET(x)        (((x) << SYNTH_SYNTH1_PWUP_LOMIX_PD_LSB) & SYNTH_SYNTH1_PWUP_LOMIX_PD_MASK)
-#define SYNTH_SYNTH1_PWUP_LOBUF5G_PD_MSB         6
-#define SYNTH_SYNTH1_PWUP_LOBUF5G_PD_LSB         6
-#define SYNTH_SYNTH1_PWUP_LOBUF5G_PD_MASK        0x00000040
-#define SYNTH_SYNTH1_PWUP_LOBUF5G_PD_GET(x)      (((x) & SYNTH_SYNTH1_PWUP_LOBUF5G_PD_MASK) >> SYNTH_SYNTH1_PWUP_LOBUF5G_PD_LSB)
-#define SYNTH_SYNTH1_PWUP_LOBUF5G_PD_SET(x)      (((x) << SYNTH_SYNTH1_PWUP_LOBUF5G_PD_LSB) & SYNTH_SYNTH1_PWUP_LOBUF5G_PD_MASK)
-#define SYNTH_SYNTH1_MONITOR_FB_MSB              5
-#define SYNTH_SYNTH1_MONITOR_FB_LSB              5
-#define SYNTH_SYNTH1_MONITOR_FB_MASK             0x00000020
-#define SYNTH_SYNTH1_MONITOR_FB_GET(x)           (((x) & SYNTH_SYNTH1_MONITOR_FB_MASK) >> SYNTH_SYNTH1_MONITOR_FB_LSB)
-#define SYNTH_SYNTH1_MONITOR_FB_SET(x)           (((x) << SYNTH_SYNTH1_MONITOR_FB_LSB) & SYNTH_SYNTH1_MONITOR_FB_MASK)
-#define SYNTH_SYNTH1_MONITOR_REF_MSB             4
-#define SYNTH_SYNTH1_MONITOR_REF_LSB             4
-#define SYNTH_SYNTH1_MONITOR_REF_MASK            0x00000010
-#define SYNTH_SYNTH1_MONITOR_REF_GET(x)          (((x) & SYNTH_SYNTH1_MONITOR_REF_MASK) >> SYNTH_SYNTH1_MONITOR_REF_LSB)
-#define SYNTH_SYNTH1_MONITOR_REF_SET(x)          (((x) << SYNTH_SYNTH1_MONITOR_REF_LSB) & SYNTH_SYNTH1_MONITOR_REF_MASK)
-#define SYNTH_SYNTH1_MONITOR_FB_DIV2_MSB         3
-#define SYNTH_SYNTH1_MONITOR_FB_DIV2_LSB         3
-#define SYNTH_SYNTH1_MONITOR_FB_DIV2_MASK        0x00000008
-#define SYNTH_SYNTH1_MONITOR_FB_DIV2_GET(x)      (((x) & SYNTH_SYNTH1_MONITOR_FB_DIV2_MASK) >> SYNTH_SYNTH1_MONITOR_FB_DIV2_LSB)
-#define SYNTH_SYNTH1_MONITOR_FB_DIV2_SET(x)      (((x) << SYNTH_SYNTH1_MONITOR_FB_DIV2_LSB) & SYNTH_SYNTH1_MONITOR_FB_DIV2_MASK)
-#define SYNTH_SYNTH1_MONITOR_VC2HIGH_MSB         2
-#define SYNTH_SYNTH1_MONITOR_VC2HIGH_LSB         2
-#define SYNTH_SYNTH1_MONITOR_VC2HIGH_MASK        0x00000004
-#define SYNTH_SYNTH1_MONITOR_VC2HIGH_GET(x)      (((x) & SYNTH_SYNTH1_MONITOR_VC2HIGH_MASK) >> SYNTH_SYNTH1_MONITOR_VC2HIGH_LSB)
-#define SYNTH_SYNTH1_MONITOR_VC2HIGH_SET(x)      (((x) << SYNTH_SYNTH1_MONITOR_VC2HIGH_LSB) & SYNTH_SYNTH1_MONITOR_VC2HIGH_MASK)
-#define SYNTH_SYNTH1_MONITOR_VC2LOW_MSB          1
-#define SYNTH_SYNTH1_MONITOR_VC2LOW_LSB          1
-#define SYNTH_SYNTH1_MONITOR_VC2LOW_MASK         0x00000002
-#define SYNTH_SYNTH1_MONITOR_VC2LOW_GET(x)       (((x) & SYNTH_SYNTH1_MONITOR_VC2LOW_MASK) >> SYNTH_SYNTH1_MONITOR_VC2LOW_LSB)
-#define SYNTH_SYNTH1_MONITOR_VC2LOW_SET(x)       (((x) << SYNTH_SYNTH1_MONITOR_VC2LOW_LSB) & SYNTH_SYNTH1_MONITOR_VC2LOW_MASK)
-#define SYNTH_SYNTH1_MONITOR_SYNTHLOCKVCOK_MSB   0
-#define SYNTH_SYNTH1_MONITOR_SYNTHLOCKVCOK_LSB   0
-#define SYNTH_SYNTH1_MONITOR_SYNTHLOCKVCOK_MASK  0x00000001
-#define SYNTH_SYNTH1_MONITOR_SYNTHLOCKVCOK_GET(x) (((x) & SYNTH_SYNTH1_MONITOR_SYNTHLOCKVCOK_MASK) >> SYNTH_SYNTH1_MONITOR_SYNTHLOCKVCOK_LSB)
-#define SYNTH_SYNTH1_MONITOR_SYNTHLOCKVCOK_SET(x) (((x) << SYNTH_SYNTH1_MONITOR_SYNTHLOCKVCOK_LSB) & SYNTH_SYNTH1_MONITOR_SYNTHLOCKVCOK_MASK)
-
-#define SYNTH_SYNTH2_ADDRESS                     0x00000004
-#define SYNTH_SYNTH2_OFFSET                      0x00000004
-#define SYNTH_SYNTH2_VC_CAL_REF_MSB              31
-#define SYNTH_SYNTH2_VC_CAL_REF_LSB              29
-#define SYNTH_SYNTH2_VC_CAL_REF_MASK             0xe0000000
-#define SYNTH_SYNTH2_VC_CAL_REF_GET(x)           (((x) & SYNTH_SYNTH2_VC_CAL_REF_MASK) >> SYNTH_SYNTH2_VC_CAL_REF_LSB)
-#define SYNTH_SYNTH2_VC_CAL_REF_SET(x)           (((x) << SYNTH_SYNTH2_VC_CAL_REF_LSB) & SYNTH_SYNTH2_VC_CAL_REF_MASK)
-#define SYNTH_SYNTH2_VC_HI_REF_MSB               28
-#define SYNTH_SYNTH2_VC_HI_REF_LSB               26
-#define SYNTH_SYNTH2_VC_HI_REF_MASK              0x1c000000
-#define SYNTH_SYNTH2_VC_HI_REF_GET(x)            (((x) & SYNTH_SYNTH2_VC_HI_REF_MASK) >> SYNTH_SYNTH2_VC_HI_REF_LSB)
-#define SYNTH_SYNTH2_VC_HI_REF_SET(x)            (((x) << SYNTH_SYNTH2_VC_HI_REF_LSB) & SYNTH_SYNTH2_VC_HI_REF_MASK)
-#define SYNTH_SYNTH2_VC_MID_REF_MSB              25
-#define SYNTH_SYNTH2_VC_MID_REF_LSB              23
-#define SYNTH_SYNTH2_VC_MID_REF_MASK             0x03800000
-#define SYNTH_SYNTH2_VC_MID_REF_GET(x)           (((x) & SYNTH_SYNTH2_VC_MID_REF_MASK) >> SYNTH_SYNTH2_VC_MID_REF_LSB)
-#define SYNTH_SYNTH2_VC_MID_REF_SET(x)           (((x) << SYNTH_SYNTH2_VC_MID_REF_LSB) & SYNTH_SYNTH2_VC_MID_REF_MASK)
-#define SYNTH_SYNTH2_VC_LOW_REF_MSB              22
-#define SYNTH_SYNTH2_VC_LOW_REF_LSB              20
-#define SYNTH_SYNTH2_VC_LOW_REF_MASK             0x00700000
-#define SYNTH_SYNTH2_VC_LOW_REF_GET(x)           (((x) & SYNTH_SYNTH2_VC_LOW_REF_MASK) >> SYNTH_SYNTH2_VC_LOW_REF_LSB)
-#define SYNTH_SYNTH2_VC_LOW_REF_SET(x)           (((x) << SYNTH_SYNTH2_VC_LOW_REF_LSB) & SYNTH_SYNTH2_VC_LOW_REF_MASK)
-#define SYNTH_SYNTH2_LOOP_3RD_ORDER_R_MSB        19
-#define SYNTH_SYNTH2_LOOP_3RD_ORDER_R_LSB        15
-#define SYNTH_SYNTH2_LOOP_3RD_ORDER_R_MASK       0x000f8000
-#define SYNTH_SYNTH2_LOOP_3RD_ORDER_R_GET(x)     (((x) & SYNTH_SYNTH2_LOOP_3RD_ORDER_R_MASK) >> SYNTH_SYNTH2_LOOP_3RD_ORDER_R_LSB)
-#define SYNTH_SYNTH2_LOOP_3RD_ORDER_R_SET(x)     (((x) << SYNTH_SYNTH2_LOOP_3RD_ORDER_R_LSB) & SYNTH_SYNTH2_LOOP_3RD_ORDER_R_MASK)
-#define SYNTH_SYNTH2_LOOP_CP_MSB                 14
-#define SYNTH_SYNTH2_LOOP_CP_LSB                 10
-#define SYNTH_SYNTH2_LOOP_CP_MASK                0x00007c00
-#define SYNTH_SYNTH2_LOOP_CP_GET(x)              (((x) & SYNTH_SYNTH2_LOOP_CP_MASK) >> SYNTH_SYNTH2_LOOP_CP_LSB)
-#define SYNTH_SYNTH2_LOOP_CP_SET(x)              (((x) << SYNTH_SYNTH2_LOOP_CP_LSB) & SYNTH_SYNTH2_LOOP_CP_MASK)
-#define SYNTH_SYNTH2_LOOP_RS_MSB                 9
-#define SYNTH_SYNTH2_LOOP_RS_LSB                 5
-#define SYNTH_SYNTH2_LOOP_RS_MASK                0x000003e0
-#define SYNTH_SYNTH2_LOOP_RS_GET(x)              (((x) & SYNTH_SYNTH2_LOOP_RS_MASK) >> SYNTH_SYNTH2_LOOP_RS_LSB)
-#define SYNTH_SYNTH2_LOOP_RS_SET(x)              (((x) << SYNTH_SYNTH2_LOOP_RS_LSB) & SYNTH_SYNTH2_LOOP_RS_MASK)
-#define SYNTH_SYNTH2_LOOP_CS_MSB                 4
-#define SYNTH_SYNTH2_LOOP_CS_LSB                 3
-#define SYNTH_SYNTH2_LOOP_CS_MASK                0x00000018
-#define SYNTH_SYNTH2_LOOP_CS_GET(x)              (((x) & SYNTH_SYNTH2_LOOP_CS_MASK) >> SYNTH_SYNTH2_LOOP_CS_LSB)
-#define SYNTH_SYNTH2_LOOP_CS_SET(x)              (((x) << SYNTH_SYNTH2_LOOP_CS_LSB) & SYNTH_SYNTH2_LOOP_CS_MASK)
-#define SYNTH_SYNTH2_SPARE_BITS_MSB              2
-#define SYNTH_SYNTH2_SPARE_BITS_LSB              0
-#define SYNTH_SYNTH2_SPARE_BITS_MASK             0x00000007
-#define SYNTH_SYNTH2_SPARE_BITS_GET(x)           (((x) & SYNTH_SYNTH2_SPARE_BITS_MASK) >> SYNTH_SYNTH2_SPARE_BITS_LSB)
-#define SYNTH_SYNTH2_SPARE_BITS_SET(x)           (((x) << SYNTH_SYNTH2_SPARE_BITS_LSB) & SYNTH_SYNTH2_SPARE_BITS_MASK)
-
-#define SYNTH_SYNTH3_ADDRESS                     0x00000008
-#define SYNTH_SYNTH3_OFFSET                      0x00000008
-#define SYNTH_SYNTH3_DIS_CLK_XTAL_MSB            31
-#define SYNTH_SYNTH3_DIS_CLK_XTAL_LSB            31
-#define SYNTH_SYNTH3_DIS_CLK_XTAL_MASK           0x80000000
-#define SYNTH_SYNTH3_DIS_CLK_XTAL_GET(x)         (((x) & SYNTH_SYNTH3_DIS_CLK_XTAL_MASK) >> SYNTH_SYNTH3_DIS_CLK_XTAL_LSB)
-#define SYNTH_SYNTH3_DIS_CLK_XTAL_SET(x)         (((x) << SYNTH_SYNTH3_DIS_CLK_XTAL_LSB) & SYNTH_SYNTH3_DIS_CLK_XTAL_MASK)
-#define SYNTH_SYNTH3_SEL_CLK_DIV2_MSB            30
-#define SYNTH_SYNTH3_SEL_CLK_DIV2_LSB            30
-#define SYNTH_SYNTH3_SEL_CLK_DIV2_MASK           0x40000000
-#define SYNTH_SYNTH3_SEL_CLK_DIV2_GET(x)         (((x) & SYNTH_SYNTH3_SEL_CLK_DIV2_MASK) >> SYNTH_SYNTH3_SEL_CLK_DIV2_LSB)
-#define SYNTH_SYNTH3_SEL_CLK_DIV2_SET(x)         (((x) << SYNTH_SYNTH3_SEL_CLK_DIV2_LSB) & SYNTH_SYNTH3_SEL_CLK_DIV2_MASK)
-#define SYNTH_SYNTH3_WAIT_SHORTR_PWRUP_MSB       29
-#define SYNTH_SYNTH3_WAIT_SHORTR_PWRUP_LSB       24
-#define SYNTH_SYNTH3_WAIT_SHORTR_PWRUP_MASK      0x3f000000
-#define SYNTH_SYNTH3_WAIT_SHORTR_PWRUP_GET(x)    (((x) & SYNTH_SYNTH3_WAIT_SHORTR_PWRUP_MASK) >> SYNTH_SYNTH3_WAIT_SHORTR_PWRUP_LSB)
-#define SYNTH_SYNTH3_WAIT_SHORTR_PWRUP_SET(x)    (((x) << SYNTH_SYNTH3_WAIT_SHORTR_PWRUP_LSB) & SYNTH_SYNTH3_WAIT_SHORTR_PWRUP_MASK)
-#define SYNTH_SYNTH3_WAIT_PWRUP_MSB              23
-#define SYNTH_SYNTH3_WAIT_PWRUP_LSB              18
-#define SYNTH_SYNTH3_WAIT_PWRUP_MASK             0x00fc0000
-#define SYNTH_SYNTH3_WAIT_PWRUP_GET(x)           (((x) & SYNTH_SYNTH3_WAIT_PWRUP_MASK) >> SYNTH_SYNTH3_WAIT_PWRUP_LSB)
-#define SYNTH_SYNTH3_WAIT_PWRUP_SET(x)           (((x) << SYNTH_SYNTH3_WAIT_PWRUP_LSB) & SYNTH_SYNTH3_WAIT_PWRUP_MASK)
-#define SYNTH_SYNTH3_WAIT_CAL_BIN_MSB            17
-#define SYNTH_SYNTH3_WAIT_CAL_BIN_LSB            12
-#define SYNTH_SYNTH3_WAIT_CAL_BIN_MASK           0x0003f000
-#define SYNTH_SYNTH3_WAIT_CAL_BIN_GET(x)         (((x) & SYNTH_SYNTH3_WAIT_CAL_BIN_MASK) >> SYNTH_SYNTH3_WAIT_CAL_BIN_LSB)
-#define SYNTH_SYNTH3_WAIT_CAL_BIN_SET(x)         (((x) << SYNTH_SYNTH3_WAIT_CAL_BIN_LSB) & SYNTH_SYNTH3_WAIT_CAL_BIN_MASK)
-#define SYNTH_SYNTH3_WAIT_CAL_LIN_MSB            11
-#define SYNTH_SYNTH3_WAIT_CAL_LIN_LSB            6
-#define SYNTH_SYNTH3_WAIT_CAL_LIN_MASK           0x00000fc0
-#define SYNTH_SYNTH3_WAIT_CAL_LIN_GET(x)         (((x) & SYNTH_SYNTH3_WAIT_CAL_LIN_MASK) >> SYNTH_SYNTH3_WAIT_CAL_LIN_LSB)
-#define SYNTH_SYNTH3_WAIT_CAL_LIN_SET(x)         (((x) << SYNTH_SYNTH3_WAIT_CAL_LIN_LSB) & SYNTH_SYNTH3_WAIT_CAL_LIN_MASK)
-#define SYNTH_SYNTH3_WAIT_VC_CHECK_MSB           5
-#define SYNTH_SYNTH3_WAIT_VC_CHECK_LSB           0
-#define SYNTH_SYNTH3_WAIT_VC_CHECK_MASK          0x0000003f
-#define SYNTH_SYNTH3_WAIT_VC_CHECK_GET(x)        (((x) & SYNTH_SYNTH3_WAIT_VC_CHECK_MASK) >> SYNTH_SYNTH3_WAIT_VC_CHECK_LSB)
-#define SYNTH_SYNTH3_WAIT_VC_CHECK_SET(x)        (((x) << SYNTH_SYNTH3_WAIT_VC_CHECK_LSB) & SYNTH_SYNTH3_WAIT_VC_CHECK_MASK)
-
-#define SYNTH_SYNTH4_ADDRESS                     0x0000000c
-#define SYNTH_SYNTH4_OFFSET                      0x0000000c
-#define SYNTH_SYNTH4_DIS_LIN_CAPSEARCH_MSB       31
-#define SYNTH_SYNTH4_DIS_LIN_CAPSEARCH_LSB       31
-#define SYNTH_SYNTH4_DIS_LIN_CAPSEARCH_MASK      0x80000000
-#define SYNTH_SYNTH4_DIS_LIN_CAPSEARCH_GET(x)    (((x) & SYNTH_SYNTH4_DIS_LIN_CAPSEARCH_MASK) >> SYNTH_SYNTH4_DIS_LIN_CAPSEARCH_LSB)
-#define SYNTH_SYNTH4_DIS_LIN_CAPSEARCH_SET(x)    (((x) << SYNTH_SYNTH4_DIS_LIN_CAPSEARCH_LSB) & SYNTH_SYNTH4_DIS_LIN_CAPSEARCH_MASK)
-#define SYNTH_SYNTH4_DIS_LOSTVC_MSB              30
-#define SYNTH_SYNTH4_DIS_LOSTVC_LSB              30
-#define SYNTH_SYNTH4_DIS_LOSTVC_MASK             0x40000000
-#define SYNTH_SYNTH4_DIS_LOSTVC_GET(x)           (((x) & SYNTH_SYNTH4_DIS_LOSTVC_MASK) >> SYNTH_SYNTH4_DIS_LOSTVC_LSB)
-#define SYNTH_SYNTH4_DIS_LOSTVC_SET(x)           (((x) << SYNTH_SYNTH4_DIS_LOSTVC_LSB) & SYNTH_SYNTH4_DIS_LOSTVC_MASK)
-#define SYNTH_SYNTH4_ALWAYS_SHORTR_MSB           29
-#define SYNTH_SYNTH4_ALWAYS_SHORTR_LSB           29
-#define SYNTH_SYNTH4_ALWAYS_SHORTR_MASK          0x20000000
-#define SYNTH_SYNTH4_ALWAYS_SHORTR_GET(x)        (((x) & SYNTH_SYNTH4_ALWAYS_SHORTR_MASK) >> SYNTH_SYNTH4_ALWAYS_SHORTR_LSB)
-#define SYNTH_SYNTH4_ALWAYS_SHORTR_SET(x)        (((x) << SYNTH_SYNTH4_ALWAYS_SHORTR_LSB) & SYNTH_SYNTH4_ALWAYS_SHORTR_MASK)
-#define SYNTH_SYNTH4_SHORTR_UNTIL_LOCKED_MSB     28
-#define SYNTH_SYNTH4_SHORTR_UNTIL_LOCKED_LSB     28
-#define SYNTH_SYNTH4_SHORTR_UNTIL_LOCKED_MASK    0x10000000
-#define SYNTH_SYNTH4_SHORTR_UNTIL_LOCKED_GET(x)  (((x) & SYNTH_SYNTH4_SHORTR_UNTIL_LOCKED_MASK) >> SYNTH_SYNTH4_SHORTR_UNTIL_LOCKED_LSB)
-#define SYNTH_SYNTH4_SHORTR_UNTIL_LOCKED_SET(x)  (((x) << SYNTH_SYNTH4_SHORTR_UNTIL_LOCKED_LSB) & SYNTH_SYNTH4_SHORTR_UNTIL_LOCKED_MASK)
-#define SYNTH_SYNTH4_FORCE_PINVC_MSB             27
-#define SYNTH_SYNTH4_FORCE_PINVC_LSB             27
-#define SYNTH_SYNTH4_FORCE_PINVC_MASK            0x08000000
-#define SYNTH_SYNTH4_FORCE_PINVC_GET(x)          (((x) & SYNTH_SYNTH4_FORCE_PINVC_MASK) >> SYNTH_SYNTH4_FORCE_PINVC_LSB)
-#define SYNTH_SYNTH4_FORCE_PINVC_SET(x)          (((x) << SYNTH_SYNTH4_FORCE_PINVC_LSB) & SYNTH_SYNTH4_FORCE_PINVC_MASK)
-#define SYNTH_SYNTH4_FORCE_VCOCAP_MSB            26
-#define SYNTH_SYNTH4_FORCE_VCOCAP_LSB            26
-#define SYNTH_SYNTH4_FORCE_VCOCAP_MASK           0x04000000
-#define SYNTH_SYNTH4_FORCE_VCOCAP_GET(x)         (((x) & SYNTH_SYNTH4_FORCE_VCOCAP_MASK) >> SYNTH_SYNTH4_FORCE_VCOCAP_LSB)
-#define SYNTH_SYNTH4_FORCE_VCOCAP_SET(x)         (((x) << SYNTH_SYNTH4_FORCE_VCOCAP_LSB) & SYNTH_SYNTH4_FORCE_VCOCAP_MASK)
-#define SYNTH_SYNTH4_VCOCAP_OVR_MSB              25
-#define SYNTH_SYNTH4_VCOCAP_OVR_LSB              18
-#define SYNTH_SYNTH4_VCOCAP_OVR_MASK             0x03fc0000
-#define SYNTH_SYNTH4_VCOCAP_OVR_GET(x)           (((x) & SYNTH_SYNTH4_VCOCAP_OVR_MASK) >> SYNTH_SYNTH4_VCOCAP_OVR_LSB)
-#define SYNTH_SYNTH4_VCOCAP_OVR_SET(x)           (((x) << SYNTH_SYNTH4_VCOCAP_OVR_LSB) & SYNTH_SYNTH4_VCOCAP_OVR_MASK)
-#define SYNTH_SYNTH4_VCOCAPPULLUP_MSB            17
-#define SYNTH_SYNTH4_VCOCAPPULLUP_LSB            17
-#define SYNTH_SYNTH4_VCOCAPPULLUP_MASK           0x00020000
-#define SYNTH_SYNTH4_VCOCAPPULLUP_GET(x)         (((x) & SYNTH_SYNTH4_VCOCAPPULLUP_MASK) >> SYNTH_SYNTH4_VCOCAPPULLUP_LSB)
-#define SYNTH_SYNTH4_VCOCAPPULLUP_SET(x)         (((x) << SYNTH_SYNTH4_VCOCAPPULLUP_LSB) & SYNTH_SYNTH4_VCOCAPPULLUP_MASK)
-#define SYNTH_SYNTH4_REFDIVSEL_MSB               16
-#define SYNTH_SYNTH4_REFDIVSEL_LSB               15
-#define SYNTH_SYNTH4_REFDIVSEL_MASK              0x00018000
-#define SYNTH_SYNTH4_REFDIVSEL_GET(x)            (((x) & SYNTH_SYNTH4_REFDIVSEL_MASK) >> SYNTH_SYNTH4_REFDIVSEL_LSB)
-#define SYNTH_SYNTH4_REFDIVSEL_SET(x)            (((x) << SYNTH_SYNTH4_REFDIVSEL_LSB) & SYNTH_SYNTH4_REFDIVSEL_MASK)
-#define SYNTH_SYNTH4_PFDDELAY_MSB                14
-#define SYNTH_SYNTH4_PFDDELAY_LSB                14
-#define SYNTH_SYNTH4_PFDDELAY_MASK               0x00004000
-#define SYNTH_SYNTH4_PFDDELAY_GET(x)             (((x) & SYNTH_SYNTH4_PFDDELAY_MASK) >> SYNTH_SYNTH4_PFDDELAY_LSB)
-#define SYNTH_SYNTH4_PFDDELAY_SET(x)             (((x) << SYNTH_SYNTH4_PFDDELAY_LSB) & SYNTH_SYNTH4_PFDDELAY_MASK)
-#define SYNTH_SYNTH4_PFD_DISABLE_MSB             13
-#define SYNTH_SYNTH4_PFD_DISABLE_LSB             13
-#define SYNTH_SYNTH4_PFD_DISABLE_MASK            0x00002000
-#define SYNTH_SYNTH4_PFD_DISABLE_GET(x)          (((x) & SYNTH_SYNTH4_PFD_DISABLE_MASK) >> SYNTH_SYNTH4_PFD_DISABLE_LSB)
-#define SYNTH_SYNTH4_PFD_DISABLE_SET(x)          (((x) << SYNTH_SYNTH4_PFD_DISABLE_LSB) & SYNTH_SYNTH4_PFD_DISABLE_MASK)
-#define SYNTH_SYNTH4_PRESCSEL_MSB                12
-#define SYNTH_SYNTH4_PRESCSEL_LSB                11
-#define SYNTH_SYNTH4_PRESCSEL_MASK               0x00001800
-#define SYNTH_SYNTH4_PRESCSEL_GET(x)             (((x) & SYNTH_SYNTH4_PRESCSEL_MASK) >> SYNTH_SYNTH4_PRESCSEL_LSB)
-#define SYNTH_SYNTH4_PRESCSEL_SET(x)             (((x) << SYNTH_SYNTH4_PRESCSEL_LSB) & SYNTH_SYNTH4_PRESCSEL_MASK)
-#define SYNTH_SYNTH4_RESET_PRESC_MSB             10
-#define SYNTH_SYNTH4_RESET_PRESC_LSB             10
-#define SYNTH_SYNTH4_RESET_PRESC_MASK            0x00000400
-#define SYNTH_SYNTH4_RESET_PRESC_GET(x)          (((x) & SYNTH_SYNTH4_RESET_PRESC_MASK) >> SYNTH_SYNTH4_RESET_PRESC_LSB)
-#define SYNTH_SYNTH4_RESET_PRESC_SET(x)          (((x) << SYNTH_SYNTH4_RESET_PRESC_LSB) & SYNTH_SYNTH4_RESET_PRESC_MASK)
-#define SYNTH_SYNTH4_SDM_DISABLE_MSB             9
-#define SYNTH_SYNTH4_SDM_DISABLE_LSB             9
-#define SYNTH_SYNTH4_SDM_DISABLE_MASK            0x00000200
-#define SYNTH_SYNTH4_SDM_DISABLE_GET(x)          (((x) & SYNTH_SYNTH4_SDM_DISABLE_MASK) >> SYNTH_SYNTH4_SDM_DISABLE_LSB)
-#define SYNTH_SYNTH4_SDM_DISABLE_SET(x)          (((x) << SYNTH_SYNTH4_SDM_DISABLE_LSB) & SYNTH_SYNTH4_SDM_DISABLE_MASK)
-#define SYNTH_SYNTH4_SDM_MODE_MSB                8
-#define SYNTH_SYNTH4_SDM_MODE_LSB                8
-#define SYNTH_SYNTH4_SDM_MODE_MASK               0x00000100
-#define SYNTH_SYNTH4_SDM_MODE_GET(x)             (((x) & SYNTH_SYNTH4_SDM_MODE_MASK) >> SYNTH_SYNTH4_SDM_MODE_LSB)
-#define SYNTH_SYNTH4_SDM_MODE_SET(x)             (((x) << SYNTH_SYNTH4_SDM_MODE_LSB) & SYNTH_SYNTH4_SDM_MODE_MASK)
-#define SYNTH_SYNTH4_SDM_DITHER_MSB              7
-#define SYNTH_SYNTH4_SDM_DITHER_LSB              6
-#define SYNTH_SYNTH4_SDM_DITHER_MASK             0x000000c0
-#define SYNTH_SYNTH4_SDM_DITHER_GET(x)           (((x) & SYNTH_SYNTH4_SDM_DITHER_MASK) >> SYNTH_SYNTH4_SDM_DITHER_LSB)
-#define SYNTH_SYNTH4_SDM_DITHER_SET(x)           (((x) << SYNTH_SYNTH4_SDM_DITHER_LSB) & SYNTH_SYNTH4_SDM_DITHER_MASK)
-#define SYNTH_SYNTH4_PSCOUNT_FBSEL_MSB           5
-#define SYNTH_SYNTH4_PSCOUNT_FBSEL_LSB           5
-#define SYNTH_SYNTH4_PSCOUNT_FBSEL_MASK          0x00000020
-#define SYNTH_SYNTH4_PSCOUNT_FBSEL_GET(x)        (((x) & SYNTH_SYNTH4_PSCOUNT_FBSEL_MASK) >> SYNTH_SYNTH4_PSCOUNT_FBSEL_LSB)
-#define SYNTH_SYNTH4_PSCOUNT_FBSEL_SET(x)        (((x) << SYNTH_SYNTH4_PSCOUNT_FBSEL_LSB) & SYNTH_SYNTH4_PSCOUNT_FBSEL_MASK)
-#define SYNTH_SYNTH4_SEL_CLKXTAL_EDGE_MSB        4
-#define SYNTH_SYNTH4_SEL_CLKXTAL_EDGE_LSB        4
-#define SYNTH_SYNTH4_SEL_CLKXTAL_EDGE_MASK       0x00000010
-#define SYNTH_SYNTH4_SEL_CLKXTAL_EDGE_GET(x)     (((x) & SYNTH_SYNTH4_SEL_CLKXTAL_EDGE_MASK) >> SYNTH_SYNTH4_SEL_CLKXTAL_EDGE_LSB)
-#define SYNTH_SYNTH4_SEL_CLKXTAL_EDGE_SET(x)     (((x) << SYNTH_SYNTH4_SEL_CLKXTAL_EDGE_LSB) & SYNTH_SYNTH4_SEL_CLKXTAL_EDGE_MASK)
-#define SYNTH_SYNTH4_SPARE_MISC_MSB              3
-#define SYNTH_SYNTH4_SPARE_MISC_LSB              2
-#define SYNTH_SYNTH4_SPARE_MISC_MASK             0x0000000c
-#define SYNTH_SYNTH4_SPARE_MISC_GET(x)           (((x) & SYNTH_SYNTH4_SPARE_MISC_MASK) >> SYNTH_SYNTH4_SPARE_MISC_LSB)
-#define SYNTH_SYNTH4_SPARE_MISC_SET(x)           (((x) << SYNTH_SYNTH4_SPARE_MISC_LSB) & SYNTH_SYNTH4_SPARE_MISC_MASK)
-#define SYNTH_SYNTH4_LONGSHIFTSEL_MSB            1
-#define SYNTH_SYNTH4_LONGSHIFTSEL_LSB            1
-#define SYNTH_SYNTH4_LONGSHIFTSEL_MASK           0x00000002
-#define SYNTH_SYNTH4_LONGSHIFTSEL_GET(x)         (((x) & SYNTH_SYNTH4_LONGSHIFTSEL_MASK) >> SYNTH_SYNTH4_LONGSHIFTSEL_LSB)
-#define SYNTH_SYNTH4_LONGSHIFTSEL_SET(x)         (((x) << SYNTH_SYNTH4_LONGSHIFTSEL_LSB) & SYNTH_SYNTH4_LONGSHIFTSEL_MASK)
-#define SYNTH_SYNTH4_FORCE_SHIFTREG_MSB          0
-#define SYNTH_SYNTH4_FORCE_SHIFTREG_LSB          0
-#define SYNTH_SYNTH4_FORCE_SHIFTREG_MASK         0x00000001
-#define SYNTH_SYNTH4_FORCE_SHIFTREG_GET(x)       (((x) & SYNTH_SYNTH4_FORCE_SHIFTREG_MASK) >> SYNTH_SYNTH4_FORCE_SHIFTREG_LSB)
-#define SYNTH_SYNTH4_FORCE_SHIFTREG_SET(x)       (((x) << SYNTH_SYNTH4_FORCE_SHIFTREG_LSB) & SYNTH_SYNTH4_FORCE_SHIFTREG_MASK)
-
-#define SYNTH_SYNTH5_ADDRESS                     0x00000010
-#define SYNTH_SYNTH5_OFFSET                      0x00000010
-#define SYNTH_SYNTH5_LOOP_IP0_MSB                31
-#define SYNTH_SYNTH5_LOOP_IP0_LSB                28
-#define SYNTH_SYNTH5_LOOP_IP0_MASK               0xf0000000
-#define SYNTH_SYNTH5_LOOP_IP0_GET(x)             (((x) & SYNTH_SYNTH5_LOOP_IP0_MASK) >> SYNTH_SYNTH5_LOOP_IP0_LSB)
-#define SYNTH_SYNTH5_LOOP_IP0_SET(x)             (((x) << SYNTH_SYNTH5_LOOP_IP0_LSB) & SYNTH_SYNTH5_LOOP_IP0_MASK)
-#define SYNTH_SYNTH5_SLOPE_IP_MSB                27
-#define SYNTH_SYNTH5_SLOPE_IP_LSB                25
-#define SYNTH_SYNTH5_SLOPE_IP_MASK               0x0e000000
-#define SYNTH_SYNTH5_SLOPE_IP_GET(x)             (((x) & SYNTH_SYNTH5_SLOPE_IP_MASK) >> SYNTH_SYNTH5_SLOPE_IP_LSB)
-#define SYNTH_SYNTH5_SLOPE_IP_SET(x)             (((x) << SYNTH_SYNTH5_SLOPE_IP_LSB) & SYNTH_SYNTH5_SLOPE_IP_MASK)
-#define SYNTH_SYNTH5_CPBIAS_MSB                  24
-#define SYNTH_SYNTH5_CPBIAS_LSB                  23
-#define SYNTH_SYNTH5_CPBIAS_MASK                 0x01800000
-#define SYNTH_SYNTH5_CPBIAS_GET(x)               (((x) & SYNTH_SYNTH5_CPBIAS_MASK) >> SYNTH_SYNTH5_CPBIAS_LSB)
-#define SYNTH_SYNTH5_CPBIAS_SET(x)               (((x) << SYNTH_SYNTH5_CPBIAS_LSB) & SYNTH_SYNTH5_CPBIAS_MASK)
-#define SYNTH_SYNTH5_CPSTEERING_EN_MSB           22
-#define SYNTH_SYNTH5_CPSTEERING_EN_LSB           22
-#define SYNTH_SYNTH5_CPSTEERING_EN_MASK          0x00400000
-#define SYNTH_SYNTH5_CPSTEERING_EN_GET(x)        (((x) & SYNTH_SYNTH5_CPSTEERING_EN_MASK) >> SYNTH_SYNTH5_CPSTEERING_EN_LSB)
-#define SYNTH_SYNTH5_CPSTEERING_EN_SET(x)        (((x) << SYNTH_SYNTH5_CPSTEERING_EN_LSB) & SYNTH_SYNTH5_CPSTEERING_EN_MASK)
-#define SYNTH_SYNTH5_CPLOWLK_MSB                 21
-#define SYNTH_SYNTH5_CPLOWLK_LSB                 21
-#define SYNTH_SYNTH5_CPLOWLK_MASK                0x00200000
-#define SYNTH_SYNTH5_CPLOWLK_GET(x)              (((x) & SYNTH_SYNTH5_CPLOWLK_MASK) >> SYNTH_SYNTH5_CPLOWLK_LSB)
-#define SYNTH_SYNTH5_CPLOWLK_SET(x)              (((x) << SYNTH_SYNTH5_CPLOWLK_LSB) & SYNTH_SYNTH5_CPLOWLK_MASK)
-#define SYNTH_SYNTH5_LOOPLEAKCUR_MSB             20
-#define SYNTH_SYNTH5_LOOPLEAKCUR_LSB             17
-#define SYNTH_SYNTH5_LOOPLEAKCUR_MASK            0x001e0000
-#define SYNTH_SYNTH5_LOOPLEAKCUR_GET(x)          (((x) & SYNTH_SYNTH5_LOOPLEAKCUR_MASK) >> SYNTH_SYNTH5_LOOPLEAKCUR_LSB)
-#define SYNTH_SYNTH5_LOOPLEAKCUR_SET(x)          (((x) << SYNTH_SYNTH5_LOOPLEAKCUR_LSB) & SYNTH_SYNTH5_LOOPLEAKCUR_MASK)
-#define SYNTH_SYNTH5_CAPRANGE1_MSB               16
-#define SYNTH_SYNTH5_CAPRANGE1_LSB               13
-#define SYNTH_SYNTH5_CAPRANGE1_MASK              0x0001e000
-#define SYNTH_SYNTH5_CAPRANGE1_GET(x)            (((x) & SYNTH_SYNTH5_CAPRANGE1_MASK) >> SYNTH_SYNTH5_CAPRANGE1_LSB)
-#define SYNTH_SYNTH5_CAPRANGE1_SET(x)            (((x) << SYNTH_SYNTH5_CAPRANGE1_LSB) & SYNTH_SYNTH5_CAPRANGE1_MASK)
-#define SYNTH_SYNTH5_CAPRANGE2_MSB               12
-#define SYNTH_SYNTH5_CAPRANGE2_LSB               9
-#define SYNTH_SYNTH5_CAPRANGE2_MASK              0x00001e00
-#define SYNTH_SYNTH5_CAPRANGE2_GET(x)            (((x) & SYNTH_SYNTH5_CAPRANGE2_MASK) >> SYNTH_SYNTH5_CAPRANGE2_LSB)
-#define SYNTH_SYNTH5_CAPRANGE2_SET(x)            (((x) << SYNTH_SYNTH5_CAPRANGE2_LSB) & SYNTH_SYNTH5_CAPRANGE2_MASK)
-#define SYNTH_SYNTH5_CAPRANGE3_MSB               8
-#define SYNTH_SYNTH5_CAPRANGE3_LSB               5
-#define SYNTH_SYNTH5_CAPRANGE3_MASK              0x000001e0
-#define SYNTH_SYNTH5_CAPRANGE3_GET(x)            (((x) & SYNTH_SYNTH5_CAPRANGE3_MASK) >> SYNTH_SYNTH5_CAPRANGE3_LSB)
-#define SYNTH_SYNTH5_CAPRANGE3_SET(x)            (((x) << SYNTH_SYNTH5_CAPRANGE3_LSB) & SYNTH_SYNTH5_CAPRANGE3_MASK)
-#define SYNTH_SYNTH5_FORCE_LOBUF5GTUNE_MSB       4
-#define SYNTH_SYNTH5_FORCE_LOBUF5GTUNE_LSB       4
-#define SYNTH_SYNTH5_FORCE_LOBUF5GTUNE_MASK      0x00000010
-#define SYNTH_SYNTH5_FORCE_LOBUF5GTUNE_GET(x)    (((x) & SYNTH_SYNTH5_FORCE_LOBUF5GTUNE_MASK) >> SYNTH_SYNTH5_FORCE_LOBUF5GTUNE_LSB)
-#define SYNTH_SYNTH5_FORCE_LOBUF5GTUNE_SET(x)    (((x) << SYNTH_SYNTH5_FORCE_LOBUF5GTUNE_LSB) & SYNTH_SYNTH5_FORCE_LOBUF5GTUNE_MASK)
-#define SYNTH_SYNTH5_LOBUF5GTUNE_OVR_MSB         3
-#define SYNTH_SYNTH5_LOBUF5GTUNE_OVR_LSB         2
-#define SYNTH_SYNTH5_LOBUF5GTUNE_OVR_MASK        0x0000000c
-#define SYNTH_SYNTH5_LOBUF5GTUNE_OVR_GET(x)      (((x) & SYNTH_SYNTH5_LOBUF5GTUNE_OVR_MASK) >> SYNTH_SYNTH5_LOBUF5GTUNE_OVR_LSB)
-#define SYNTH_SYNTH5_LOBUF5GTUNE_OVR_SET(x)      (((x) << SYNTH_SYNTH5_LOBUF5GTUNE_OVR_LSB) & SYNTH_SYNTH5_LOBUF5GTUNE_OVR_MASK)
-#define SYNTH_SYNTH5_SPARE_MSB                   1
-#define SYNTH_SYNTH5_SPARE_LSB                   0
-#define SYNTH_SYNTH5_SPARE_MASK                  0x00000003
-#define SYNTH_SYNTH5_SPARE_GET(x)                (((x) & SYNTH_SYNTH5_SPARE_MASK) >> SYNTH_SYNTH5_SPARE_LSB)
-#define SYNTH_SYNTH5_SPARE_SET(x)                (((x) << SYNTH_SYNTH5_SPARE_LSB) & SYNTH_SYNTH5_SPARE_MASK)
-
-#define SYNTH_SYNTH6_ADDRESS                     0x00000014
-#define SYNTH_SYNTH6_OFFSET                      0x00000014
-#define SYNTH_SYNTH6_IRCP_MSB                    31
-#define SYNTH_SYNTH6_IRCP_LSB                    29
-#define SYNTH_SYNTH6_IRCP_MASK                   0xe0000000
-#define SYNTH_SYNTH6_IRCP_GET(x)                 (((x) & SYNTH_SYNTH6_IRCP_MASK) >> SYNTH_SYNTH6_IRCP_LSB)
-#define SYNTH_SYNTH6_IRCP_SET(x)                 (((x) << SYNTH_SYNTH6_IRCP_LSB) & SYNTH_SYNTH6_IRCP_MASK)
-#define SYNTH_SYNTH6_IRVCMON_MSB                 28
-#define SYNTH_SYNTH6_IRVCMON_LSB                 26
-#define SYNTH_SYNTH6_IRVCMON_MASK                0x1c000000
-#define SYNTH_SYNTH6_IRVCMON_GET(x)              (((x) & SYNTH_SYNTH6_IRVCMON_MASK) >> SYNTH_SYNTH6_IRVCMON_LSB)
-#define SYNTH_SYNTH6_IRVCMON_SET(x)              (((x) << SYNTH_SYNTH6_IRVCMON_LSB) & SYNTH_SYNTH6_IRVCMON_MASK)
-#define SYNTH_SYNTH6_IRSPARE_MSB                 25
-#define SYNTH_SYNTH6_IRSPARE_LSB                 23
-#define SYNTH_SYNTH6_IRSPARE_MASK                0x03800000
-#define SYNTH_SYNTH6_IRSPARE_GET(x)              (((x) & SYNTH_SYNTH6_IRSPARE_MASK) >> SYNTH_SYNTH6_IRSPARE_LSB)
-#define SYNTH_SYNTH6_IRSPARE_SET(x)              (((x) << SYNTH_SYNTH6_IRSPARE_LSB) & SYNTH_SYNTH6_IRSPARE_MASK)
-#define SYNTH_SYNTH6_ICPRESC_MSB                 22
-#define SYNTH_SYNTH6_ICPRESC_LSB                 20
-#define SYNTH_SYNTH6_ICPRESC_MASK                0x00700000
-#define SYNTH_SYNTH6_ICPRESC_GET(x)              (((x) & SYNTH_SYNTH6_ICPRESC_MASK) >> SYNTH_SYNTH6_ICPRESC_LSB)
-#define SYNTH_SYNTH6_ICPRESC_SET(x)              (((x) << SYNTH_SYNTH6_ICPRESC_LSB) & SYNTH_SYNTH6_ICPRESC_MASK)
-#define SYNTH_SYNTH6_ICLODIV_MSB                 19
-#define SYNTH_SYNTH6_ICLODIV_LSB                 17
-#define SYNTH_SYNTH6_ICLODIV_MASK                0x000e0000
-#define SYNTH_SYNTH6_ICLODIV_GET(x)              (((x) & SYNTH_SYNTH6_ICLODIV_MASK) >> SYNTH_SYNTH6_ICLODIV_LSB)
-#define SYNTH_SYNTH6_ICLODIV_SET(x)              (((x) << SYNTH_SYNTH6_ICLODIV_LSB) & SYNTH_SYNTH6_ICLODIV_MASK)
-#define SYNTH_SYNTH6_ICLOMIX_MSB                 16
-#define SYNTH_SYNTH6_ICLOMIX_LSB                 14
-#define SYNTH_SYNTH6_ICLOMIX_MASK                0x0001c000
-#define SYNTH_SYNTH6_ICLOMIX_GET(x)              (((x) & SYNTH_SYNTH6_ICLOMIX_MASK) >> SYNTH_SYNTH6_ICLOMIX_LSB)
-#define SYNTH_SYNTH6_ICLOMIX_SET(x)              (((x) << SYNTH_SYNTH6_ICLOMIX_LSB) & SYNTH_SYNTH6_ICLOMIX_MASK)
-#define SYNTH_SYNTH6_ICSPAREA_MSB                13
-#define SYNTH_SYNTH6_ICSPAREA_LSB                11
-#define SYNTH_SYNTH6_ICSPAREA_MASK               0x00003800
-#define SYNTH_SYNTH6_ICSPAREA_GET(x)             (((x) & SYNTH_SYNTH6_ICSPAREA_MASK) >> SYNTH_SYNTH6_ICSPAREA_LSB)
-#define SYNTH_SYNTH6_ICSPAREA_SET(x)             (((x) << SYNTH_SYNTH6_ICSPAREA_LSB) & SYNTH_SYNTH6_ICSPAREA_MASK)
-#define SYNTH_SYNTH6_ICSPAREB_MSB                10
-#define SYNTH_SYNTH6_ICSPAREB_LSB                8
-#define SYNTH_SYNTH6_ICSPAREB_MASK               0x00000700
-#define SYNTH_SYNTH6_ICSPAREB_GET(x)             (((x) & SYNTH_SYNTH6_ICSPAREB_MASK) >> SYNTH_SYNTH6_ICSPAREB_LSB)
-#define SYNTH_SYNTH6_ICSPAREB_SET(x)             (((x) << SYNTH_SYNTH6_ICSPAREB_LSB) & SYNTH_SYNTH6_ICSPAREB_MASK)
-#define SYNTH_SYNTH6_ICVCO_MSB                   7
-#define SYNTH_SYNTH6_ICVCO_LSB                   5
-#define SYNTH_SYNTH6_ICVCO_MASK                  0x000000e0
-#define SYNTH_SYNTH6_ICVCO_GET(x)                (((x) & SYNTH_SYNTH6_ICVCO_MASK) >> SYNTH_SYNTH6_ICVCO_LSB)
-#define SYNTH_SYNTH6_ICVCO_SET(x)                (((x) << SYNTH_SYNTH6_ICVCO_LSB) & SYNTH_SYNTH6_ICVCO_MASK)
-#define SYNTH_SYNTH6_VCOBUFBIAS_MSB              4
-#define SYNTH_SYNTH6_VCOBUFBIAS_LSB              3
-#define SYNTH_SYNTH6_VCOBUFBIAS_MASK             0x00000018
-#define SYNTH_SYNTH6_VCOBUFBIAS_GET(x)           (((x) & SYNTH_SYNTH6_VCOBUFBIAS_MASK) >> SYNTH_SYNTH6_VCOBUFBIAS_LSB)
-#define SYNTH_SYNTH6_VCOBUFBIAS_SET(x)           (((x) << SYNTH_SYNTH6_VCOBUFBIAS_LSB) & SYNTH_SYNTH6_VCOBUFBIAS_MASK)
-#define SYNTH_SYNTH6_SPARE_BIAS_MSB              2
-#define SYNTH_SYNTH6_SPARE_BIAS_LSB              0
-#define SYNTH_SYNTH6_SPARE_BIAS_MASK             0x00000007
-#define SYNTH_SYNTH6_SPARE_BIAS_GET(x)           (((x) & SYNTH_SYNTH6_SPARE_BIAS_MASK) >> SYNTH_SYNTH6_SPARE_BIAS_LSB)
-#define SYNTH_SYNTH6_SPARE_BIAS_SET(x)           (((x) << SYNTH_SYNTH6_SPARE_BIAS_LSB) & SYNTH_SYNTH6_SPARE_BIAS_MASK)
-
-#define SYNTH_SYNTH7_ADDRESS                     0x00000018
-#define SYNTH_SYNTH7_OFFSET                      0x00000018
-#define SYNTH_SYNTH7_SYNTH_ON_MSB                31
-#define SYNTH_SYNTH7_SYNTH_ON_LSB                31
-#define SYNTH_SYNTH7_SYNTH_ON_MASK               0x80000000
-#define SYNTH_SYNTH7_SYNTH_ON_GET(x)             (((x) & SYNTH_SYNTH7_SYNTH_ON_MASK) >> SYNTH_SYNTH7_SYNTH_ON_LSB)
-#define SYNTH_SYNTH7_SYNTH_ON_SET(x)             (((x) << SYNTH_SYNTH7_SYNTH_ON_LSB) & SYNTH_SYNTH7_SYNTH_ON_MASK)
-#define SYNTH_SYNTH7_SYNTH_SM_STATE_MSB          30
-#define SYNTH_SYNTH7_SYNTH_SM_STATE_LSB          27
-#define SYNTH_SYNTH7_SYNTH_SM_STATE_MASK         0x78000000
-#define SYNTH_SYNTH7_SYNTH_SM_STATE_GET(x)       (((x) & SYNTH_SYNTH7_SYNTH_SM_STATE_MASK) >> SYNTH_SYNTH7_SYNTH_SM_STATE_LSB)
-#define SYNTH_SYNTH7_SYNTH_SM_STATE_SET(x)       (((x) << SYNTH_SYNTH7_SYNTH_SM_STATE_LSB) & SYNTH_SYNTH7_SYNTH_SM_STATE_MASK)
-#define SYNTH_SYNTH7_CAP_SEARCH_MSB              26
-#define SYNTH_SYNTH7_CAP_SEARCH_LSB              26
-#define SYNTH_SYNTH7_CAP_SEARCH_MASK             0x04000000
-#define SYNTH_SYNTH7_CAP_SEARCH_GET(x)           (((x) & SYNTH_SYNTH7_CAP_SEARCH_MASK) >> SYNTH_SYNTH7_CAP_SEARCH_LSB)
-#define SYNTH_SYNTH7_CAP_SEARCH_SET(x)           (((x) << SYNTH_SYNTH7_CAP_SEARCH_LSB) & SYNTH_SYNTH7_CAP_SEARCH_MASK)
-#define SYNTH_SYNTH7_SYNTH_LOCK_VC_OK_MSB        25
-#define SYNTH_SYNTH7_SYNTH_LOCK_VC_OK_LSB        25
-#define SYNTH_SYNTH7_SYNTH_LOCK_VC_OK_MASK       0x02000000
-#define SYNTH_SYNTH7_SYNTH_LOCK_VC_OK_GET(x)     (((x) & SYNTH_SYNTH7_SYNTH_LOCK_VC_OK_MASK) >> SYNTH_SYNTH7_SYNTH_LOCK_VC_OK_LSB)
-#define SYNTH_SYNTH7_SYNTH_LOCK_VC_OK_SET(x)     (((x) << SYNTH_SYNTH7_SYNTH_LOCK_VC_OK_LSB) & SYNTH_SYNTH7_SYNTH_LOCK_VC_OK_MASK)
-#define SYNTH_SYNTH7_PIN_VC_MSB                  24
-#define SYNTH_SYNTH7_PIN_VC_LSB                  24
-#define SYNTH_SYNTH7_PIN_VC_MASK                 0x01000000
-#define SYNTH_SYNTH7_PIN_VC_GET(x)               (((x) & SYNTH_SYNTH7_PIN_VC_MASK) >> SYNTH_SYNTH7_PIN_VC_LSB)
-#define SYNTH_SYNTH7_PIN_VC_SET(x)               (((x) << SYNTH_SYNTH7_PIN_VC_LSB) & SYNTH_SYNTH7_PIN_VC_MASK)
-#define SYNTH_SYNTH7_VCO_CAP_ST_MSB              23
-#define SYNTH_SYNTH7_VCO_CAP_ST_LSB              16
-#define SYNTH_SYNTH7_VCO_CAP_ST_MASK             0x00ff0000
-#define SYNTH_SYNTH7_VCO_CAP_ST_GET(x)           (((x) & SYNTH_SYNTH7_VCO_CAP_ST_MASK) >> SYNTH_SYNTH7_VCO_CAP_ST_LSB)
-#define SYNTH_SYNTH7_VCO_CAP_ST_SET(x)           (((x) << SYNTH_SYNTH7_VCO_CAP_ST_LSB) & SYNTH_SYNTH7_VCO_CAP_ST_MASK)
-#define SYNTH_SYNTH7_SHORT_R_MSB                 15
-#define SYNTH_SYNTH7_SHORT_R_LSB                 15
-#define SYNTH_SYNTH7_SHORT_R_MASK                0x00008000
-#define SYNTH_SYNTH7_SHORT_R_GET(x)              (((x) & SYNTH_SYNTH7_SHORT_R_MASK) >> SYNTH_SYNTH7_SHORT_R_LSB)
-#define SYNTH_SYNTH7_SHORT_R_SET(x)              (((x) << SYNTH_SYNTH7_SHORT_R_LSB) & SYNTH_SYNTH7_SHORT_R_MASK)
-#define SYNTH_SYNTH7_RESET_RFD_MSB               14
-#define SYNTH_SYNTH7_RESET_RFD_LSB               14
-#define SYNTH_SYNTH7_RESET_RFD_MASK              0x00004000
-#define SYNTH_SYNTH7_RESET_RFD_GET(x)            (((x) & SYNTH_SYNTH7_RESET_RFD_MASK) >> SYNTH_SYNTH7_RESET_RFD_LSB)
-#define SYNTH_SYNTH7_RESET_RFD_SET(x)            (((x) << SYNTH_SYNTH7_RESET_RFD_LSB) & SYNTH_SYNTH7_RESET_RFD_MASK)
-#define SYNTH_SYNTH7_RESET_PFD_MSB               13
-#define SYNTH_SYNTH7_RESET_PFD_LSB               13
-#define SYNTH_SYNTH7_RESET_PFD_MASK              0x00002000
-#define SYNTH_SYNTH7_RESET_PFD_GET(x)            (((x) & SYNTH_SYNTH7_RESET_PFD_MASK) >> SYNTH_SYNTH7_RESET_PFD_LSB)
-#define SYNTH_SYNTH7_RESET_PFD_SET(x)            (((x) << SYNTH_SYNTH7_RESET_PFD_LSB) & SYNTH_SYNTH7_RESET_PFD_MASK)
-#define SYNTH_SYNTH7_RESET_PSCOUNTERS_MSB        12
-#define SYNTH_SYNTH7_RESET_PSCOUNTERS_LSB        12
-#define SYNTH_SYNTH7_RESET_PSCOUNTERS_MASK       0x00001000
-#define SYNTH_SYNTH7_RESET_PSCOUNTERS_GET(x)     (((x) & SYNTH_SYNTH7_RESET_PSCOUNTERS_MASK) >> SYNTH_SYNTH7_RESET_PSCOUNTERS_LSB)
-#define SYNTH_SYNTH7_RESET_PSCOUNTERS_SET(x)     (((x) << SYNTH_SYNTH7_RESET_PSCOUNTERS_LSB) & SYNTH_SYNTH7_RESET_PSCOUNTERS_MASK)
-#define SYNTH_SYNTH7_RESET_SDM_B_MSB             11
-#define SYNTH_SYNTH7_RESET_SDM_B_LSB             11
-#define SYNTH_SYNTH7_RESET_SDM_B_MASK            0x00000800
-#define SYNTH_SYNTH7_RESET_SDM_B_GET(x)          (((x) & SYNTH_SYNTH7_RESET_SDM_B_MASK) >> SYNTH_SYNTH7_RESET_SDM_B_LSB)
-#define SYNTH_SYNTH7_RESET_SDM_B_SET(x)          (((x) << SYNTH_SYNTH7_RESET_SDM_B_LSB) & SYNTH_SYNTH7_RESET_SDM_B_MASK)
-#define SYNTH_SYNTH7_VC2HIGH_MSB                 10
-#define SYNTH_SYNTH7_VC2HIGH_LSB                 10
-#define SYNTH_SYNTH7_VC2HIGH_MASK                0x00000400
-#define SYNTH_SYNTH7_VC2HIGH_GET(x)              (((x) & SYNTH_SYNTH7_VC2HIGH_MASK) >> SYNTH_SYNTH7_VC2HIGH_LSB)
-#define SYNTH_SYNTH7_VC2HIGH_SET(x)              (((x) << SYNTH_SYNTH7_VC2HIGH_LSB) & SYNTH_SYNTH7_VC2HIGH_MASK)
-#define SYNTH_SYNTH7_VC2LOW_MSB                  9
-#define SYNTH_SYNTH7_VC2LOW_LSB                  9
-#define SYNTH_SYNTH7_VC2LOW_MASK                 0x00000200
-#define SYNTH_SYNTH7_VC2LOW_GET(x)               (((x) & SYNTH_SYNTH7_VC2LOW_MASK) >> SYNTH_SYNTH7_VC2LOW_LSB)
-#define SYNTH_SYNTH7_VC2LOW_SET(x)               (((x) << SYNTH_SYNTH7_VC2LOW_LSB) & SYNTH_SYNTH7_VC2LOW_MASK)
-#define SYNTH_SYNTH7_LOOP_IP_MSB                 8
-#define SYNTH_SYNTH7_LOOP_IP_LSB                 5
-#define SYNTH_SYNTH7_LOOP_IP_MASK                0x000001e0
-#define SYNTH_SYNTH7_LOOP_IP_GET(x)              (((x) & SYNTH_SYNTH7_LOOP_IP_MASK) >> SYNTH_SYNTH7_LOOP_IP_LSB)
-#define SYNTH_SYNTH7_LOOP_IP_SET(x)              (((x) << SYNTH_SYNTH7_LOOP_IP_LSB) & SYNTH_SYNTH7_LOOP_IP_MASK)
-#define SYNTH_SYNTH7_LOBUF5GTUNE_MSB             4
-#define SYNTH_SYNTH7_LOBUF5GTUNE_LSB             3
-#define SYNTH_SYNTH7_LOBUF5GTUNE_MASK            0x00000018
-#define SYNTH_SYNTH7_LOBUF5GTUNE_GET(x)          (((x) & SYNTH_SYNTH7_LOBUF5GTUNE_MASK) >> SYNTH_SYNTH7_LOBUF5GTUNE_LSB)
-#define SYNTH_SYNTH7_LOBUF5GTUNE_SET(x)          (((x) << SYNTH_SYNTH7_LOBUF5GTUNE_LSB) & SYNTH_SYNTH7_LOBUF5GTUNE_MASK)
-#define SYNTH_SYNTH7_SPARE_READ_MSB              2
-#define SYNTH_SYNTH7_SPARE_READ_LSB              0
-#define SYNTH_SYNTH7_SPARE_READ_MASK             0x00000007
-#define SYNTH_SYNTH7_SPARE_READ_GET(x)           (((x) & SYNTH_SYNTH7_SPARE_READ_MASK) >> SYNTH_SYNTH7_SPARE_READ_LSB)
-#define SYNTH_SYNTH7_SPARE_READ_SET(x)           (((x) << SYNTH_SYNTH7_SPARE_READ_LSB) & SYNTH_SYNTH7_SPARE_READ_MASK)
-
-#define SYNTH_SYNTH8_ADDRESS                     0x0000001c
-#define SYNTH_SYNTH8_OFFSET                      0x0000001c
-#define SYNTH_SYNTH8_LOADSYNTHCHANNEL_MSB        31
-#define SYNTH_SYNTH8_LOADSYNTHCHANNEL_LSB        31
-#define SYNTH_SYNTH8_LOADSYNTHCHANNEL_MASK       0x80000000
-#define SYNTH_SYNTH8_LOADSYNTHCHANNEL_GET(x)     (((x) & SYNTH_SYNTH8_LOADSYNTHCHANNEL_MASK) >> SYNTH_SYNTH8_LOADSYNTHCHANNEL_LSB)
-#define SYNTH_SYNTH8_LOADSYNTHCHANNEL_SET(x)     (((x) << SYNTH_SYNTH8_LOADSYNTHCHANNEL_LSB) & SYNTH_SYNTH8_LOADSYNTHCHANNEL_MASK)
-#define SYNTH_SYNTH8_FRACMODE_MSB                30
-#define SYNTH_SYNTH8_FRACMODE_LSB                30
-#define SYNTH_SYNTH8_FRACMODE_MASK               0x40000000
-#define SYNTH_SYNTH8_FRACMODE_GET(x)             (((x) & SYNTH_SYNTH8_FRACMODE_MASK) >> SYNTH_SYNTH8_FRACMODE_LSB)
-#define SYNTH_SYNTH8_FRACMODE_SET(x)             (((x) << SYNTH_SYNTH8_FRACMODE_LSB) & SYNTH_SYNTH8_FRACMODE_MASK)
-#define SYNTH_SYNTH8_AMODEREFSEL_MSB             29
-#define SYNTH_SYNTH8_AMODEREFSEL_LSB             28
-#define SYNTH_SYNTH8_AMODEREFSEL_MASK            0x30000000
-#define SYNTH_SYNTH8_AMODEREFSEL_GET(x)          (((x) & SYNTH_SYNTH8_AMODEREFSEL_MASK) >> SYNTH_SYNTH8_AMODEREFSEL_LSB)
-#define SYNTH_SYNTH8_AMODEREFSEL_SET(x)          (((x) << SYNTH_SYNTH8_AMODEREFSEL_LSB) & SYNTH_SYNTH8_AMODEREFSEL_MASK)
-#define SYNTH_SYNTH8_SPARE_MSB                   27
-#define SYNTH_SYNTH8_SPARE_LSB                   27
-#define SYNTH_SYNTH8_SPARE_MASK                  0x08000000
-#define SYNTH_SYNTH8_SPARE_GET(x)                (((x) & SYNTH_SYNTH8_SPARE_MASK) >> SYNTH_SYNTH8_SPARE_LSB)
-#define SYNTH_SYNTH8_SPARE_SET(x)                (((x) << SYNTH_SYNTH8_SPARE_LSB) & SYNTH_SYNTH8_SPARE_MASK)
-#define SYNTH_SYNTH8_CHANSEL_MSB                 26
-#define SYNTH_SYNTH8_CHANSEL_LSB                 18
-#define SYNTH_SYNTH8_CHANSEL_MASK                0x07fc0000
-#define SYNTH_SYNTH8_CHANSEL_GET(x)              (((x) & SYNTH_SYNTH8_CHANSEL_MASK) >> SYNTH_SYNTH8_CHANSEL_LSB)
-#define SYNTH_SYNTH8_CHANSEL_SET(x)              (((x) << SYNTH_SYNTH8_CHANSEL_LSB) & SYNTH_SYNTH8_CHANSEL_MASK)
-#define SYNTH_SYNTH8_CHANFRAC_MSB                17
-#define SYNTH_SYNTH8_CHANFRAC_LSB                1
-#define SYNTH_SYNTH8_CHANFRAC_MASK               0x0003fffe
-#define SYNTH_SYNTH8_CHANFRAC_GET(x)             (((x) & SYNTH_SYNTH8_CHANFRAC_MASK) >> SYNTH_SYNTH8_CHANFRAC_LSB)
-#define SYNTH_SYNTH8_CHANFRAC_SET(x)             (((x) << SYNTH_SYNTH8_CHANFRAC_LSB) & SYNTH_SYNTH8_CHANFRAC_MASK)
-#define SYNTH_SYNTH8_FORCE_FRACLSB_MSB           0
-#define SYNTH_SYNTH8_FORCE_FRACLSB_LSB           0
-#define SYNTH_SYNTH8_FORCE_FRACLSB_MASK          0x00000001
-#define SYNTH_SYNTH8_FORCE_FRACLSB_GET(x)        (((x) & SYNTH_SYNTH8_FORCE_FRACLSB_MASK) >> SYNTH_SYNTH8_FORCE_FRACLSB_LSB)
-#define SYNTH_SYNTH8_FORCE_FRACLSB_SET(x)        (((x) << SYNTH_SYNTH8_FORCE_FRACLSB_LSB) & SYNTH_SYNTH8_FORCE_FRACLSB_MASK)
-
-#define RF5G_RF5G1_ADDRESS                       0x00000020
-#define RF5G_RF5G1_OFFSET                        0x00000020
-#define RF5G_RF5G1_PDTXLO5_MSB                   31
-#define RF5G_RF5G1_PDTXLO5_LSB                   31
-#define RF5G_RF5G1_PDTXLO5_MASK                  0x80000000
-#define RF5G_RF5G1_PDTXLO5_GET(x)                (((x) & RF5G_RF5G1_PDTXLO5_MASK) >> RF5G_RF5G1_PDTXLO5_LSB)
-#define RF5G_RF5G1_PDTXLO5_SET(x)                (((x) << RF5G_RF5G1_PDTXLO5_LSB) & RF5G_RF5G1_PDTXLO5_MASK)
-#define RF5G_RF5G1_PDTXMIX5_MSB                  30
-#define RF5G_RF5G1_PDTXMIX5_LSB                  30
-#define RF5G_RF5G1_PDTXMIX5_MASK                 0x40000000
-#define RF5G_RF5G1_PDTXMIX5_GET(x)               (((x) & RF5G_RF5G1_PDTXMIX5_MASK) >> RF5G_RF5G1_PDTXMIX5_LSB)
-#define RF5G_RF5G1_PDTXMIX5_SET(x)               (((x) << RF5G_RF5G1_PDTXMIX5_LSB) & RF5G_RF5G1_PDTXMIX5_MASK)
-#define RF5G_RF5G1_PDTXBUF5_MSB                  29
-#define RF5G_RF5G1_PDTXBUF5_LSB                  29
-#define RF5G_RF5G1_PDTXBUF5_MASK                 0x20000000
-#define RF5G_RF5G1_PDTXBUF5_GET(x)               (((x) & RF5G_RF5G1_PDTXBUF5_MASK) >> RF5G_RF5G1_PDTXBUF5_LSB)
-#define RF5G_RF5G1_PDTXBUF5_SET(x)               (((x) << RF5G_RF5G1_PDTXBUF5_LSB) & RF5G_RF5G1_PDTXBUF5_MASK)
-#define RF5G_RF5G1_PDPADRV5_MSB                  28
-#define RF5G_RF5G1_PDPADRV5_LSB                  28
-#define RF5G_RF5G1_PDPADRV5_MASK                 0x10000000
-#define RF5G_RF5G1_PDPADRV5_GET(x)               (((x) & RF5G_RF5G1_PDPADRV5_MASK) >> RF5G_RF5G1_PDPADRV5_LSB)
-#define RF5G_RF5G1_PDPADRV5_SET(x)               (((x) << RF5G_RF5G1_PDPADRV5_LSB) & RF5G_RF5G1_PDPADRV5_MASK)
-#define RF5G_RF5G1_PDPAOUT5_MSB                  27
-#define RF5G_RF5G1_PDPAOUT5_LSB                  27
-#define RF5G_RF5G1_PDPAOUT5_MASK                 0x08000000
-#define RF5G_RF5G1_PDPAOUT5_GET(x)               (((x) & RF5G_RF5G1_PDPAOUT5_MASK) >> RF5G_RF5G1_PDPAOUT5_LSB)
-#define RF5G_RF5G1_PDPAOUT5_SET(x)               (((x) << RF5G_RF5G1_PDPAOUT5_LSB) & RF5G_RF5G1_PDPAOUT5_MASK)
-#define RF5G_RF5G1_TUNE_PADRV5_MSB               26
-#define RF5G_RF5G1_TUNE_PADRV5_LSB               24
-#define RF5G_RF5G1_TUNE_PADRV5_MASK              0x07000000
-#define RF5G_RF5G1_TUNE_PADRV5_GET(x)            (((x) & RF5G_RF5G1_TUNE_PADRV5_MASK) >> RF5G_RF5G1_TUNE_PADRV5_LSB)
-#define RF5G_RF5G1_TUNE_PADRV5_SET(x)            (((x) << RF5G_RF5G1_TUNE_PADRV5_LSB) & RF5G_RF5G1_TUNE_PADRV5_MASK)
-#define RF5G_RF5G1_PWDTXPKD_MSB                  23
-#define RF5G_RF5G1_PWDTXPKD_LSB                  21
-#define RF5G_RF5G1_PWDTXPKD_MASK                 0x00e00000
-#define RF5G_RF5G1_PWDTXPKD_GET(x)               (((x) & RF5G_RF5G1_PWDTXPKD_MASK) >> RF5G_RF5G1_PWDTXPKD_LSB)
-#define RF5G_RF5G1_PWDTXPKD_SET(x)               (((x) << RF5G_RF5G1_PWDTXPKD_LSB) & RF5G_RF5G1_PWDTXPKD_MASK)
-#define RF5G_RF5G1_DB5_MSB                       20
-#define RF5G_RF5G1_DB5_LSB                       18
-#define RF5G_RF5G1_DB5_MASK                      0x001c0000
-#define RF5G_RF5G1_DB5_GET(x)                    (((x) & RF5G_RF5G1_DB5_MASK) >> RF5G_RF5G1_DB5_LSB)
-#define RF5G_RF5G1_DB5_SET(x)                    (((x) << RF5G_RF5G1_DB5_LSB) & RF5G_RF5G1_DB5_MASK)
-#define RF5G_RF5G1_OB5_MSB                       17
-#define RF5G_RF5G1_OB5_LSB                       15
-#define RF5G_RF5G1_OB5_MASK                      0x00038000
-#define RF5G_RF5G1_OB5_GET(x)                    (((x) & RF5G_RF5G1_OB5_MASK) >> RF5G_RF5G1_OB5_LSB)
-#define RF5G_RF5G1_OB5_SET(x)                    (((x) << RF5G_RF5G1_OB5_LSB) & RF5G_RF5G1_OB5_MASK)
-#define RF5G_RF5G1_TX5_ATB_SEL_MSB               14
-#define RF5G_RF5G1_TX5_ATB_SEL_LSB               12
-#define RF5G_RF5G1_TX5_ATB_SEL_MASK              0x00007000
-#define RF5G_RF5G1_TX5_ATB_SEL_GET(x)            (((x) & RF5G_RF5G1_TX5_ATB_SEL_MASK) >> RF5G_RF5G1_TX5_ATB_SEL_LSB)
-#define RF5G_RF5G1_TX5_ATB_SEL_SET(x)            (((x) << RF5G_RF5G1_TX5_ATB_SEL_LSB) & RF5G_RF5G1_TX5_ATB_SEL_MASK)
-#define RF5G_RF5G1_PDLO5DIV_MSB                  11
-#define RF5G_RF5G1_PDLO5DIV_LSB                  11
-#define RF5G_RF5G1_PDLO5DIV_MASK                 0x00000800
-#define RF5G_RF5G1_PDLO5DIV_GET(x)               (((x) & RF5G_RF5G1_PDLO5DIV_MASK) >> RF5G_RF5G1_PDLO5DIV_LSB)
-#define RF5G_RF5G1_PDLO5DIV_SET(x)               (((x) << RF5G_RF5G1_PDLO5DIV_LSB) & RF5G_RF5G1_PDLO5DIV_MASK)
-#define RF5G_RF5G1_PDLO5MIX_MSB                  10
-#define RF5G_RF5G1_PDLO5MIX_LSB                  10
-#define RF5G_RF5G1_PDLO5MIX_MASK                 0x00000400
-#define RF5G_RF5G1_PDLO5MIX_GET(x)               (((x) & RF5G_RF5G1_PDLO5MIX_MASK) >> RF5G_RF5G1_PDLO5MIX_LSB)
-#define RF5G_RF5G1_PDLO5MIX_SET(x)               (((x) << RF5G_RF5G1_PDLO5MIX_LSB) & RF5G_RF5G1_PDLO5MIX_MASK)
-#define RF5G_RF5G1_PDQBUF5_MSB                   9
-#define RF5G_RF5G1_PDQBUF5_LSB                   9
-#define RF5G_RF5G1_PDQBUF5_MASK                  0x00000200
-#define RF5G_RF5G1_PDQBUF5_GET(x)                (((x) & RF5G_RF5G1_PDQBUF5_MASK) >> RF5G_RF5G1_PDQBUF5_LSB)
-#define RF5G_RF5G1_PDQBUF5_SET(x)                (((x) << RF5G_RF5G1_PDQBUF5_LSB) & RF5G_RF5G1_PDQBUF5_MASK)
-#define RF5G_RF5G1_PDLO5AGC_MSB                  8
-#define RF5G_RF5G1_PDLO5AGC_LSB                  8
-#define RF5G_RF5G1_PDLO5AGC_MASK                 0x00000100
-#define RF5G_RF5G1_PDLO5AGC_GET(x)               (((x) & RF5G_RF5G1_PDLO5AGC_MASK) >> RF5G_RF5G1_PDLO5AGC_LSB)
-#define RF5G_RF5G1_PDLO5AGC_SET(x)               (((x) << RF5G_RF5G1_PDLO5AGC_LSB) & RF5G_RF5G1_PDLO5AGC_MASK)
-#define RF5G_RF5G1_PDREGLO5_MSB                  7
-#define RF5G_RF5G1_PDREGLO5_LSB                  7
-#define RF5G_RF5G1_PDREGLO5_MASK                 0x00000080
-#define RF5G_RF5G1_PDREGLO5_GET(x)               (((x) & RF5G_RF5G1_PDREGLO5_MASK) >> RF5G_RF5G1_PDREGLO5_LSB)
-#define RF5G_RF5G1_PDREGLO5_SET(x)               (((x) << RF5G_RF5G1_PDREGLO5_LSB) & RF5G_RF5G1_PDREGLO5_MASK)
-#define RF5G_RF5G1_LO5_ATB_SEL_MSB               6
-#define RF5G_RF5G1_LO5_ATB_SEL_LSB               4
-#define RF5G_RF5G1_LO5_ATB_SEL_MASK              0x00000070
-#define RF5G_RF5G1_LO5_ATB_SEL_GET(x)            (((x) & RF5G_RF5G1_LO5_ATB_SEL_MASK) >> RF5G_RF5G1_LO5_ATB_SEL_LSB)
-#define RF5G_RF5G1_LO5_ATB_SEL_SET(x)            (((x) << RF5G_RF5G1_LO5_ATB_SEL_LSB) & RF5G_RF5G1_LO5_ATB_SEL_MASK)
-#define RF5G_RF5G1_LO5CONTROL_MSB                3
-#define RF5G_RF5G1_LO5CONTROL_LSB                3
-#define RF5G_RF5G1_LO5CONTROL_MASK               0x00000008
-#define RF5G_RF5G1_LO5CONTROL_GET(x)             (((x) & RF5G_RF5G1_LO5CONTROL_MASK) >> RF5G_RF5G1_LO5CONTROL_LSB)
-#define RF5G_RF5G1_LO5CONTROL_SET(x)             (((x) << RF5G_RF5G1_LO5CONTROL_LSB) & RF5G_RF5G1_LO5CONTROL_MASK)
-#define RF5G_RF5G1_REGLO_BYPASS5_MSB             2
-#define RF5G_RF5G1_REGLO_BYPASS5_LSB             2
-#define RF5G_RF5G1_REGLO_BYPASS5_MASK            0x00000004
-#define RF5G_RF5G1_REGLO_BYPASS5_GET(x)          (((x) & RF5G_RF5G1_REGLO_BYPASS5_MASK) >> RF5G_RF5G1_REGLO_BYPASS5_LSB)
-#define RF5G_RF5G1_REGLO_BYPASS5_SET(x)          (((x) << RF5G_RF5G1_REGLO_BYPASS5_LSB) & RF5G_RF5G1_REGLO_BYPASS5_MASK)
-#define RF5G_RF5G1_SPARE_MSB                     1
-#define RF5G_RF5G1_SPARE_LSB                     0
-#define RF5G_RF5G1_SPARE_MASK                    0x00000003
-#define RF5G_RF5G1_SPARE_GET(x)                  (((x) & RF5G_RF5G1_SPARE_MASK) >> RF5G_RF5G1_SPARE_LSB)
-#define RF5G_RF5G1_SPARE_SET(x)                  (((x) << RF5G_RF5G1_SPARE_LSB) & RF5G_RF5G1_SPARE_MASK)
-
-#define RF5G_RF5G2_ADDRESS                       0x00000024
-#define RF5G_RF5G2_OFFSET                        0x00000024
-#define RF5G_RF5G2_AGCLO_B_MSB                   31
-#define RF5G_RF5G2_AGCLO_B_LSB                   29
-#define RF5G_RF5G2_AGCLO_B_MASK                  0xe0000000
-#define RF5G_RF5G2_AGCLO_B_GET(x)                (((x) & RF5G_RF5G2_AGCLO_B_MASK) >> RF5G_RF5G2_AGCLO_B_LSB)
-#define RF5G_RF5G2_AGCLO_B_SET(x)                (((x) << RF5G_RF5G2_AGCLO_B_LSB) & RF5G_RF5G2_AGCLO_B_MASK)
-#define RF5G_RF5G2_RX5_ATB_SEL_MSB               28
-#define RF5G_RF5G2_RX5_ATB_SEL_LSB               26
-#define RF5G_RF5G2_RX5_ATB_SEL_MASK              0x1c000000
-#define RF5G_RF5G2_RX5_ATB_SEL_GET(x)            (((x) & RF5G_RF5G2_RX5_ATB_SEL_MASK) >> RF5G_RF5G2_RX5_ATB_SEL_LSB)
-#define RF5G_RF5G2_RX5_ATB_SEL_SET(x)            (((x) << RF5G_RF5G2_RX5_ATB_SEL_LSB) & RF5G_RF5G2_RX5_ATB_SEL_MASK)
-#define RF5G_RF5G2_PDCMOSLO5_MSB                 25
-#define RF5G_RF5G2_PDCMOSLO5_LSB                 25
-#define RF5G_RF5G2_PDCMOSLO5_MASK                0x02000000
-#define RF5G_RF5G2_PDCMOSLO5_GET(x)              (((x) & RF5G_RF5G2_PDCMOSLO5_MASK) >> RF5G_RF5G2_PDCMOSLO5_LSB)
-#define RF5G_RF5G2_PDCMOSLO5_SET(x)              (((x) << RF5G_RF5G2_PDCMOSLO5_LSB) & RF5G_RF5G2_PDCMOSLO5_MASK)
-#define RF5G_RF5G2_PDVGM5_MSB                    24
-#define RF5G_RF5G2_PDVGM5_LSB                    24
-#define RF5G_RF5G2_PDVGM5_MASK                   0x01000000
-#define RF5G_RF5G2_PDVGM5_GET(x)                 (((x) & RF5G_RF5G2_PDVGM5_MASK) >> RF5G_RF5G2_PDVGM5_LSB)
-#define RF5G_RF5G2_PDVGM5_SET(x)                 (((x) << RF5G_RF5G2_PDVGM5_LSB) & RF5G_RF5G2_PDVGM5_MASK)
-#define RF5G_RF5G2_PDCSLNA5_MSB                  23
-#define RF5G_RF5G2_PDCSLNA5_LSB                  23
-#define RF5G_RF5G2_PDCSLNA5_MASK                 0x00800000
-#define RF5G_RF5G2_PDCSLNA5_GET(x)               (((x) & RF5G_RF5G2_PDCSLNA5_MASK) >> RF5G_RF5G2_PDCSLNA5_LSB)
-#define RF5G_RF5G2_PDCSLNA5_SET(x)               (((x) << RF5G_RF5G2_PDCSLNA5_LSB) & RF5G_RF5G2_PDCSLNA5_MASK)
-#define RF5G_RF5G2_PDRFVGA5_MSB                  22
-#define RF5G_RF5G2_PDRFVGA5_LSB                  22
-#define RF5G_RF5G2_PDRFVGA5_MASK                 0x00400000
-#define RF5G_RF5G2_PDRFVGA5_GET(x)               (((x) & RF5G_RF5G2_PDRFVGA5_MASK) >> RF5G_RF5G2_PDRFVGA5_LSB)
-#define RF5G_RF5G2_PDRFVGA5_SET(x)               (((x) << RF5G_RF5G2_PDRFVGA5_LSB) & RF5G_RF5G2_PDRFVGA5_MASK)
-#define RF5G_RF5G2_PDREGFE5_MSB                  21
-#define RF5G_RF5G2_PDREGFE5_LSB                  21
-#define RF5G_RF5G2_PDREGFE5_MASK                 0x00200000
-#define RF5G_RF5G2_PDREGFE5_GET(x)               (((x) & RF5G_RF5G2_PDREGFE5_MASK) >> RF5G_RF5G2_PDREGFE5_LSB)
-#define RF5G_RF5G2_PDREGFE5_SET(x)               (((x) << RF5G_RF5G2_PDREGFE5_LSB) & RF5G_RF5G2_PDREGFE5_MASK)
-#define RF5G_RF5G2_TUNE_RFVGA5_MSB               20
-#define RF5G_RF5G2_TUNE_RFVGA5_LSB               18
-#define RF5G_RF5G2_TUNE_RFVGA5_MASK              0x001c0000
-#define RF5G_RF5G2_TUNE_RFVGA5_GET(x)            (((x) & RF5G_RF5G2_TUNE_RFVGA5_MASK) >> RF5G_RF5G2_TUNE_RFVGA5_LSB)
-#define RF5G_RF5G2_TUNE_RFVGA5_SET(x)            (((x) << RF5G_RF5G2_TUNE_RFVGA5_LSB) & RF5G_RF5G2_TUNE_RFVGA5_MASK)
-#define RF5G_RF5G2_BRFVGA5_MSB                   17
-#define RF5G_RF5G2_BRFVGA5_LSB                   15
-#define RF5G_RF5G2_BRFVGA5_MASK                  0x00038000
-#define RF5G_RF5G2_BRFVGA5_GET(x)                (((x) & RF5G_RF5G2_BRFVGA5_MASK) >> RF5G_RF5G2_BRFVGA5_LSB)
-#define RF5G_RF5G2_BRFVGA5_SET(x)                (((x) << RF5G_RF5G2_BRFVGA5_LSB) & RF5G_RF5G2_BRFVGA5_MASK)
-#define RF5G_RF5G2_BCSLNA5_MSB                   14
-#define RF5G_RF5G2_BCSLNA5_LSB                   12
-#define RF5G_RF5G2_BCSLNA5_MASK                  0x00007000
-#define RF5G_RF5G2_BCSLNA5_GET(x)                (((x) & RF5G_RF5G2_BCSLNA5_MASK) >> RF5G_RF5G2_BCSLNA5_LSB)
-#define RF5G_RF5G2_BCSLNA5_SET(x)                (((x) << RF5G_RF5G2_BCSLNA5_LSB) & RF5G_RF5G2_BCSLNA5_MASK)
-#define RF5G_RF5G2_BVGM5_MSB                     11
-#define RF5G_RF5G2_BVGM5_LSB                     9
-#define RF5G_RF5G2_BVGM5_MASK                    0x00000e00
-#define RF5G_RF5G2_BVGM5_GET(x)                  (((x) & RF5G_RF5G2_BVGM5_MASK) >> RF5G_RF5G2_BVGM5_LSB)
-#define RF5G_RF5G2_BVGM5_SET(x)                  (((x) << RF5G_RF5G2_BVGM5_LSB) & RF5G_RF5G2_BVGM5_MASK)
-#define RF5G_RF5G2_REGFE_BYPASS5_MSB             8
-#define RF5G_RF5G2_REGFE_BYPASS5_LSB             8
-#define RF5G_RF5G2_REGFE_BYPASS5_MASK            0x00000100
-#define RF5G_RF5G2_REGFE_BYPASS5_GET(x)          (((x) & RF5G_RF5G2_REGFE_BYPASS5_MASK) >> RF5G_RF5G2_REGFE_BYPASS5_LSB)
-#define RF5G_RF5G2_REGFE_BYPASS5_SET(x)          (((x) << RF5G_RF5G2_REGFE_BYPASS5_LSB) & RF5G_RF5G2_REGFE_BYPASS5_MASK)
-#define RF5G_RF5G2_LNA5_ATTENMODE_MSB            7
-#define RF5G_RF5G2_LNA5_ATTENMODE_LSB            6
-#define RF5G_RF5G2_LNA5_ATTENMODE_MASK           0x000000c0
-#define RF5G_RF5G2_LNA5_ATTENMODE_GET(x)         (((x) & RF5G_RF5G2_LNA5_ATTENMODE_MASK) >> RF5G_RF5G2_LNA5_ATTENMODE_LSB)
-#define RF5G_RF5G2_LNA5_ATTENMODE_SET(x)         (((x) << RF5G_RF5G2_LNA5_ATTENMODE_LSB) & RF5G_RF5G2_LNA5_ATTENMODE_MASK)
-#define RF5G_RF5G2_ENABLE_PCA_MSB                5
-#define RF5G_RF5G2_ENABLE_PCA_LSB                5
-#define RF5G_RF5G2_ENABLE_PCA_MASK               0x00000020
-#define RF5G_RF5G2_ENABLE_PCA_GET(x)             (((x) & RF5G_RF5G2_ENABLE_PCA_MASK) >> RF5G_RF5G2_ENABLE_PCA_LSB)
-#define RF5G_RF5G2_ENABLE_PCA_SET(x)             (((x) << RF5G_RF5G2_ENABLE_PCA_LSB) & RF5G_RF5G2_ENABLE_PCA_MASK)
-#define RF5G_RF5G2_TUNE_LO_MSB                   4
-#define RF5G_RF5G2_TUNE_LO_LSB                   2
-#define RF5G_RF5G2_TUNE_LO_MASK                  0x0000001c
-#define RF5G_RF5G2_TUNE_LO_GET(x)                (((x) & RF5G_RF5G2_TUNE_LO_MASK) >> RF5G_RF5G2_TUNE_LO_LSB)
-#define RF5G_RF5G2_TUNE_LO_SET(x)                (((x) << RF5G_RF5G2_TUNE_LO_LSB) & RF5G_RF5G2_TUNE_LO_MASK)
-#define RF5G_RF5G2_SPARE_MSB                     1
-#define RF5G_RF5G2_SPARE_LSB                     0
-#define RF5G_RF5G2_SPARE_MASK                    0x00000003
-#define RF5G_RF5G2_SPARE_GET(x)                  (((x) & RF5G_RF5G2_SPARE_MASK) >> RF5G_RF5G2_SPARE_LSB)
-#define RF5G_RF5G2_SPARE_SET(x)                  (((x) << RF5G_RF5G2_SPARE_LSB) & RF5G_RF5G2_SPARE_MASK)
-
-#define RF2G_RF2G1_ADDRESS                       0x00000028
-#define RF2G_RF2G1_OFFSET                        0x00000028
-#define RF2G_RF2G1_BLNA1_MSB                     31
-#define RF2G_RF2G1_BLNA1_LSB                     29
-#define RF2G_RF2G1_BLNA1_MASK                    0xe0000000
-#define RF2G_RF2G1_BLNA1_GET(x)                  (((x) & RF2G_RF2G1_BLNA1_MASK) >> RF2G_RF2G1_BLNA1_LSB)
-#define RF2G_RF2G1_BLNA1_SET(x)                  (((x) << RF2G_RF2G1_BLNA1_LSB) & RF2G_RF2G1_BLNA1_MASK)
-#define RF2G_RF2G1_BLNA1F_MSB                    28
-#define RF2G_RF2G1_BLNA1F_LSB                    26
-#define RF2G_RF2G1_BLNA1F_MASK                   0x1c000000
-#define RF2G_RF2G1_BLNA1F_GET(x)                 (((x) & RF2G_RF2G1_BLNA1F_MASK) >> RF2G_RF2G1_BLNA1F_LSB)
-#define RF2G_RF2G1_BLNA1F_SET(x)                 (((x) << RF2G_RF2G1_BLNA1F_LSB) & RF2G_RF2G1_BLNA1F_MASK)
-#define RF2G_RF2G1_BLNA1BUF_MSB                  25
-#define RF2G_RF2G1_BLNA1BUF_LSB                  23
-#define RF2G_RF2G1_BLNA1BUF_MASK                 0x03800000
-#define RF2G_RF2G1_BLNA1BUF_GET(x)               (((x) & RF2G_RF2G1_BLNA1BUF_MASK) >> RF2G_RF2G1_BLNA1BUF_LSB)
-#define RF2G_RF2G1_BLNA1BUF_SET(x)               (((x) << RF2G_RF2G1_BLNA1BUF_LSB) & RF2G_RF2G1_BLNA1BUF_MASK)
-#define RF2G_RF2G1_BLNA2_MSB                     22
-#define RF2G_RF2G1_BLNA2_LSB                     20
-#define RF2G_RF2G1_BLNA2_MASK                    0x00700000
-#define RF2G_RF2G1_BLNA2_GET(x)                  (((x) & RF2G_RF2G1_BLNA2_MASK) >> RF2G_RF2G1_BLNA2_LSB)
-#define RF2G_RF2G1_BLNA2_SET(x)                  (((x) << RF2G_RF2G1_BLNA2_LSB) & RF2G_RF2G1_BLNA2_MASK)
-#define RF2G_RF2G1_DB_MSB                        19
-#define RF2G_RF2G1_DB_LSB                        17
-#define RF2G_RF2G1_DB_MASK                       0x000e0000
-#define RF2G_RF2G1_DB_GET(x)                     (((x) & RF2G_RF2G1_DB_MASK) >> RF2G_RF2G1_DB_LSB)
-#define RF2G_RF2G1_DB_SET(x)                     (((x) << RF2G_RF2G1_DB_LSB) & RF2G_RF2G1_DB_MASK)
-#define RF2G_RF2G1_OB_MSB                        16
-#define RF2G_RF2G1_OB_LSB                        14
-#define RF2G_RF2G1_OB_MASK                       0x0001c000
-#define RF2G_RF2G1_OB_GET(x)                     (((x) & RF2G_RF2G1_OB_MASK) >> RF2G_RF2G1_OB_LSB)
-#define RF2G_RF2G1_OB_SET(x)                     (((x) << RF2G_RF2G1_OB_LSB) & RF2G_RF2G1_OB_MASK)
-#define RF2G_RF2G1_FE_ATB_SEL_MSB                13
-#define RF2G_RF2G1_FE_ATB_SEL_LSB                11
-#define RF2G_RF2G1_FE_ATB_SEL_MASK               0x00003800
-#define RF2G_RF2G1_FE_ATB_SEL_GET(x)             (((x) & RF2G_RF2G1_FE_ATB_SEL_MASK) >> RF2G_RF2G1_FE_ATB_SEL_LSB)
-#define RF2G_RF2G1_FE_ATB_SEL_SET(x)             (((x) << RF2G_RF2G1_FE_ATB_SEL_LSB) & RF2G_RF2G1_FE_ATB_SEL_MASK)
-#define RF2G_RF2G1_RF_ATB_SEL_MSB                10
-#define RF2G_RF2G1_RF_ATB_SEL_LSB                8
-#define RF2G_RF2G1_RF_ATB_SEL_MASK               0x00000700
-#define RF2G_RF2G1_RF_ATB_SEL_GET(x)             (((x) & RF2G_RF2G1_RF_ATB_SEL_MASK) >> RF2G_RF2G1_RF_ATB_SEL_LSB)
-#define RF2G_RF2G1_RF_ATB_SEL_SET(x)             (((x) << RF2G_RF2G1_RF_ATB_SEL_LSB) & RF2G_RF2G1_RF_ATB_SEL_MASK)
-#define RF2G_RF2G1_SELLNA_MSB                    7
-#define RF2G_RF2G1_SELLNA_LSB                    7
-#define RF2G_RF2G1_SELLNA_MASK                   0x00000080
-#define RF2G_RF2G1_SELLNA_GET(x)                 (((x) & RF2G_RF2G1_SELLNA_MASK) >> RF2G_RF2G1_SELLNA_LSB)
-#define RF2G_RF2G1_SELLNA_SET(x)                 (((x) << RF2G_RF2G1_SELLNA_LSB) & RF2G_RF2G1_SELLNA_MASK)
-#define RF2G_RF2G1_LOCONTROL_MSB                 6
-#define RF2G_RF2G1_LOCONTROL_LSB                 6
-#define RF2G_RF2G1_LOCONTROL_MASK                0x00000040
-#define RF2G_RF2G1_LOCONTROL_GET(x)              (((x) & RF2G_RF2G1_LOCONTROL_MASK) >> RF2G_RF2G1_LOCONTROL_LSB)
-#define RF2G_RF2G1_LOCONTROL_SET(x)              (((x) << RF2G_RF2G1_LOCONTROL_LSB) & RF2G_RF2G1_LOCONTROL_MASK)
-#define RF2G_RF2G1_SHORTLNA2_MSB                 5
-#define RF2G_RF2G1_SHORTLNA2_LSB                 5
-#define RF2G_RF2G1_SHORTLNA2_MASK                0x00000020
-#define RF2G_RF2G1_SHORTLNA2_GET(x)              (((x) & RF2G_RF2G1_SHORTLNA2_MASK) >> RF2G_RF2G1_SHORTLNA2_LSB)
-#define RF2G_RF2G1_SHORTLNA2_SET(x)              (((x) << RF2G_RF2G1_SHORTLNA2_LSB) & RF2G_RF2G1_SHORTLNA2_MASK)
-#define RF2G_RF2G1_SPARE_MSB                     4
-#define RF2G_RF2G1_SPARE_LSB                     0
-#define RF2G_RF2G1_SPARE_MASK                    0x0000001f
-#define RF2G_RF2G1_SPARE_GET(x)                  (((x) & RF2G_RF2G1_SPARE_MASK) >> RF2G_RF2G1_SPARE_LSB)
-#define RF2G_RF2G1_SPARE_SET(x)                  (((x) << RF2G_RF2G1_SPARE_LSB) & RF2G_RF2G1_SPARE_MASK)
-
-#define RF2G_RF2G2_ADDRESS                       0x0000002c
-#define RF2G_RF2G2_OFFSET                        0x0000002c
-#define RF2G_RF2G2_PDCGLNA_MSB                   31
-#define RF2G_RF2G2_PDCGLNA_LSB                   31
-#define RF2G_RF2G2_PDCGLNA_MASK                  0x80000000
-#define RF2G_RF2G2_PDCGLNA_GET(x)                (((x) & RF2G_RF2G2_PDCGLNA_MASK) >> RF2G_RF2G2_PDCGLNA_LSB)
-#define RF2G_RF2G2_PDCGLNA_SET(x)                (((x) << RF2G_RF2G2_PDCGLNA_LSB) & RF2G_RF2G2_PDCGLNA_MASK)
-#define RF2G_RF2G2_PDCGLNABUF_MSB                30
-#define RF2G_RF2G2_PDCGLNABUF_LSB                30
-#define RF2G_RF2G2_PDCGLNABUF_MASK               0x40000000
-#define RF2G_RF2G2_PDCGLNABUF_GET(x)             (((x) & RF2G_RF2G2_PDCGLNABUF_MASK) >> RF2G_RF2G2_PDCGLNABUF_LSB)
-#define RF2G_RF2G2_PDCGLNABUF_SET(x)             (((x) << RF2G_RF2G2_PDCGLNABUF_LSB) & RF2G_RF2G2_PDCGLNABUF_MASK)
-#define RF2G_RF2G2_PDCSLNA_MSB                   29
-#define RF2G_RF2G2_PDCSLNA_LSB                   29
-#define RF2G_RF2G2_PDCSLNA_MASK                  0x20000000
-#define RF2G_RF2G2_PDCSLNA_GET(x)                (((x) & RF2G_RF2G2_PDCSLNA_MASK) >> RF2G_RF2G2_PDCSLNA_LSB)
-#define RF2G_RF2G2_PDCSLNA_SET(x)                (((x) << RF2G_RF2G2_PDCSLNA_LSB) & RF2G_RF2G2_PDCSLNA_MASK)
-#define RF2G_RF2G2_PDDIV_MSB                     28
-#define RF2G_RF2G2_PDDIV_LSB                     28
-#define RF2G_RF2G2_PDDIV_MASK                    0x10000000
-#define RF2G_RF2G2_PDDIV_GET(x)                  (((x) & RF2G_RF2G2_PDDIV_MASK) >> RF2G_RF2G2_PDDIV_LSB)
-#define RF2G_RF2G2_PDDIV_SET(x)                  (((x) << RF2G_RF2G2_PDDIV_LSB) & RF2G_RF2G2_PDDIV_MASK)
-#define RF2G_RF2G2_PDPADRV_MSB                   27
-#define RF2G_RF2G2_PDPADRV_LSB                   27
-#define RF2G_RF2G2_PDPADRV_MASK                  0x08000000
-#define RF2G_RF2G2_PDPADRV_GET(x)                (((x) & RF2G_RF2G2_PDPADRV_MASK) >> RF2G_RF2G2_PDPADRV_LSB)
-#define RF2G_RF2G2_PDPADRV_SET(x)                (((x) << RF2G_RF2G2_PDPADRV_LSB) & RF2G_RF2G2_PDPADRV_MASK)
-#define RF2G_RF2G2_PDPAOUT_MSB                   26
-#define RF2G_RF2G2_PDPAOUT_LSB                   26
-#define RF2G_RF2G2_PDPAOUT_MASK                  0x04000000
-#define RF2G_RF2G2_PDPAOUT_GET(x)                (((x) & RF2G_RF2G2_PDPAOUT_MASK) >> RF2G_RF2G2_PDPAOUT_LSB)
-#define RF2G_RF2G2_PDPAOUT_SET(x)                (((x) << RF2G_RF2G2_PDPAOUT_LSB) & RF2G_RF2G2_PDPAOUT_MASK)
-#define RF2G_RF2G2_PDREGLNA_MSB                  25
-#define RF2G_RF2G2_PDREGLNA_LSB                  25
-#define RF2G_RF2G2_PDREGLNA_MASK                 0x02000000
-#define RF2G_RF2G2_PDREGLNA_GET(x)               (((x) & RF2G_RF2G2_PDREGLNA_MASK) >> RF2G_RF2G2_PDREGLNA_LSB)
-#define RF2G_RF2G2_PDREGLNA_SET(x)               (((x) << RF2G_RF2G2_PDREGLNA_LSB) & RF2G_RF2G2_PDREGLNA_MASK)
-#define RF2G_RF2G2_PDREGLO_MSB                   24
-#define RF2G_RF2G2_PDREGLO_LSB                   24
-#define RF2G_RF2G2_PDREGLO_MASK                  0x01000000
-#define RF2G_RF2G2_PDREGLO_GET(x)                (((x) & RF2G_RF2G2_PDREGLO_MASK) >> RF2G_RF2G2_PDREGLO_LSB)
-#define RF2G_RF2G2_PDREGLO_SET(x)                (((x) << RF2G_RF2G2_PDREGLO_LSB) & RF2G_RF2G2_PDREGLO_MASK)
-#define RF2G_RF2G2_PDRFGM_MSB                    23
-#define RF2G_RF2G2_PDRFGM_LSB                    23
-#define RF2G_RF2G2_PDRFGM_MASK                   0x00800000
-#define RF2G_RF2G2_PDRFGM_GET(x)                 (((x) & RF2G_RF2G2_PDRFGM_MASK) >> RF2G_RF2G2_PDRFGM_LSB)
-#define RF2G_RF2G2_PDRFGM_SET(x)                 (((x) << RF2G_RF2G2_PDRFGM_LSB) & RF2G_RF2G2_PDRFGM_MASK)
-#define RF2G_RF2G2_PDRXLO_MSB                    22
-#define RF2G_RF2G2_PDRXLO_LSB                    22
-#define RF2G_RF2G2_PDRXLO_MASK                   0x00400000
-#define RF2G_RF2G2_PDRXLO_GET(x)                 (((x) & RF2G_RF2G2_PDRXLO_MASK) >> RF2G_RF2G2_PDRXLO_LSB)
-#define RF2G_RF2G2_PDRXLO_SET(x)                 (((x) << RF2G_RF2G2_PDRXLO_LSB) & RF2G_RF2G2_PDRXLO_MASK)
-#define RF2G_RF2G2_PDTXLO_MSB                    21
-#define RF2G_RF2G2_PDTXLO_LSB                    21
-#define RF2G_RF2G2_PDTXLO_MASK                   0x00200000
-#define RF2G_RF2G2_PDTXLO_GET(x)                 (((x) & RF2G_RF2G2_PDTXLO_MASK) >> RF2G_RF2G2_PDTXLO_LSB)
-#define RF2G_RF2G2_PDTXLO_SET(x)                 (((x) << RF2G_RF2G2_PDTXLO_LSB) & RF2G_RF2G2_PDTXLO_MASK)
-#define RF2G_RF2G2_PDTXMIX_MSB                   20
-#define RF2G_RF2G2_PDTXMIX_LSB                   20
-#define RF2G_RF2G2_PDTXMIX_MASK                  0x00100000
-#define RF2G_RF2G2_PDTXMIX_GET(x)                (((x) & RF2G_RF2G2_PDTXMIX_MASK) >> RF2G_RF2G2_PDTXMIX_LSB)
-#define RF2G_RF2G2_PDTXMIX_SET(x)                (((x) << RF2G_RF2G2_PDTXMIX_LSB) & RF2G_RF2G2_PDTXMIX_MASK)
-#define RF2G_RF2G2_REGLNA_BYPASS_MSB             19
-#define RF2G_RF2G2_REGLNA_BYPASS_LSB             19
-#define RF2G_RF2G2_REGLNA_BYPASS_MASK            0x00080000
-#define RF2G_RF2G2_REGLNA_BYPASS_GET(x)          (((x) & RF2G_RF2G2_REGLNA_BYPASS_MASK) >> RF2G_RF2G2_REGLNA_BYPASS_LSB)
-#define RF2G_RF2G2_REGLNA_BYPASS_SET(x)          (((x) << RF2G_RF2G2_REGLNA_BYPASS_LSB) & RF2G_RF2G2_REGLNA_BYPASS_MASK)
-#define RF2G_RF2G2_REGLO_BYPASS_MSB              18
-#define RF2G_RF2G2_REGLO_BYPASS_LSB              18
-#define RF2G_RF2G2_REGLO_BYPASS_MASK             0x00040000
-#define RF2G_RF2G2_REGLO_BYPASS_GET(x)           (((x) & RF2G_RF2G2_REGLO_BYPASS_MASK) >> RF2G_RF2G2_REGLO_BYPASS_LSB)
-#define RF2G_RF2G2_REGLO_BYPASS_SET(x)           (((x) << RF2G_RF2G2_REGLO_BYPASS_LSB) & RF2G_RF2G2_REGLO_BYPASS_MASK)
-#define RF2G_RF2G2_ENABLE_PCB_MSB                17
-#define RF2G_RF2G2_ENABLE_PCB_LSB                17
-#define RF2G_RF2G2_ENABLE_PCB_MASK               0x00020000
-#define RF2G_RF2G2_ENABLE_PCB_GET(x)             (((x) & RF2G_RF2G2_ENABLE_PCB_MASK) >> RF2G_RF2G2_ENABLE_PCB_LSB)
-#define RF2G_RF2G2_ENABLE_PCB_SET(x)             (((x) << RF2G_RF2G2_ENABLE_PCB_LSB) & RF2G_RF2G2_ENABLE_PCB_MASK)
-#define RF2G_RF2G2_SPARE_MSB                     16
-#define RF2G_RF2G2_SPARE_LSB                     0
-#define RF2G_RF2G2_SPARE_MASK                    0x0001ffff
-#define RF2G_RF2G2_SPARE_GET(x)                  (((x) & RF2G_RF2G2_SPARE_MASK) >> RF2G_RF2G2_SPARE_LSB)
-#define RF2G_RF2G2_SPARE_SET(x)                  (((x) << RF2G_RF2G2_SPARE_LSB) & RF2G_RF2G2_SPARE_MASK)
-
-#define TOP_GAIN_ADDRESS                         0x00000030
-#define TOP_GAIN_OFFSET                          0x00000030
-#define TOP_GAIN_TX6DBLOQGAIN_MSB                31
-#define TOP_GAIN_TX6DBLOQGAIN_LSB                30
-#define TOP_GAIN_TX6DBLOQGAIN_MASK               0xc0000000
-#define TOP_GAIN_TX6DBLOQGAIN_GET(x)             (((x) & TOP_GAIN_TX6DBLOQGAIN_MASK) >> TOP_GAIN_TX6DBLOQGAIN_LSB)
-#define TOP_GAIN_TX6DBLOQGAIN_SET(x)             (((x) << TOP_GAIN_TX6DBLOQGAIN_LSB) & TOP_GAIN_TX6DBLOQGAIN_MASK)
-#define TOP_GAIN_TX1DBLOQGAIN_MSB                29
-#define TOP_GAIN_TX1DBLOQGAIN_LSB                27
-#define TOP_GAIN_TX1DBLOQGAIN_MASK               0x38000000
-#define TOP_GAIN_TX1DBLOQGAIN_GET(x)             (((x) & TOP_GAIN_TX1DBLOQGAIN_MASK) >> TOP_GAIN_TX1DBLOQGAIN_LSB)
-#define TOP_GAIN_TX1DBLOQGAIN_SET(x)             (((x) << TOP_GAIN_TX1DBLOQGAIN_LSB) & TOP_GAIN_TX1DBLOQGAIN_MASK)
-#define TOP_GAIN_TXV2IGAIN_MSB                   26
-#define TOP_GAIN_TXV2IGAIN_LSB                   25
-#define TOP_GAIN_TXV2IGAIN_MASK                  0x06000000
-#define TOP_GAIN_TXV2IGAIN_GET(x)                (((x) & TOP_GAIN_TXV2IGAIN_MASK) >> TOP_GAIN_TXV2IGAIN_LSB)
-#define TOP_GAIN_TXV2IGAIN_SET(x)                (((x) << TOP_GAIN_TXV2IGAIN_LSB) & TOP_GAIN_TXV2IGAIN_MASK)
-#define TOP_GAIN_PABUF5GN_MSB                    24
-#define TOP_GAIN_PABUF5GN_LSB                    24
-#define TOP_GAIN_PABUF5GN_MASK                   0x01000000
-#define TOP_GAIN_PABUF5GN_GET(x)                 (((x) & TOP_GAIN_PABUF5GN_MASK) >> TOP_GAIN_PABUF5GN_LSB)
-#define TOP_GAIN_PABUF5GN_SET(x)                 (((x) << TOP_GAIN_PABUF5GN_LSB) & TOP_GAIN_PABUF5GN_MASK)
-#define TOP_GAIN_PADRVGN_MSB                     23
-#define TOP_GAIN_PADRVGN_LSB                     21
-#define TOP_GAIN_PADRVGN_MASK                    0x00e00000
-#define TOP_GAIN_PADRVGN_GET(x)                  (((x) & TOP_GAIN_PADRVGN_MASK) >> TOP_GAIN_PADRVGN_LSB)
-#define TOP_GAIN_PADRVGN_SET(x)                  (((x) << TOP_GAIN_PADRVGN_LSB) & TOP_GAIN_PADRVGN_MASK)
-#define TOP_GAIN_PAOUT2GN_MSB                    20
-#define TOP_GAIN_PAOUT2GN_LSB                    18
-#define TOP_GAIN_PAOUT2GN_MASK                   0x001c0000
-#define TOP_GAIN_PAOUT2GN_GET(x)                 (((x) & TOP_GAIN_PAOUT2GN_MASK) >> TOP_GAIN_PAOUT2GN_LSB)
-#define TOP_GAIN_PAOUT2GN_SET(x)                 (((x) << TOP_GAIN_PAOUT2GN_LSB) & TOP_GAIN_PAOUT2GN_MASK)
-#define TOP_GAIN_LNAON_MSB                       17
-#define TOP_GAIN_LNAON_LSB                       17
-#define TOP_GAIN_LNAON_MASK                      0x00020000
-#define TOP_GAIN_LNAON_GET(x)                    (((x) & TOP_GAIN_LNAON_MASK) >> TOP_GAIN_LNAON_LSB)
-#define TOP_GAIN_LNAON_SET(x)                    (((x) << TOP_GAIN_LNAON_LSB) & TOP_GAIN_LNAON_MASK)
-#define TOP_GAIN_LNAGAIN_MSB                     16
-#define TOP_GAIN_LNAGAIN_LSB                     13
-#define TOP_GAIN_LNAGAIN_MASK                    0x0001e000
-#define TOP_GAIN_LNAGAIN_GET(x)                  (((x) & TOP_GAIN_LNAGAIN_MASK) >> TOP_GAIN_LNAGAIN_LSB)
-#define TOP_GAIN_LNAGAIN_SET(x)                  (((x) << TOP_GAIN_LNAGAIN_LSB) & TOP_GAIN_LNAGAIN_MASK)
-#define TOP_GAIN_RFVGA5GAIN_MSB                  12
-#define TOP_GAIN_RFVGA5GAIN_LSB                  11
-#define TOP_GAIN_RFVGA5GAIN_MASK                 0x00001800
-#define TOP_GAIN_RFVGA5GAIN_GET(x)               (((x) & TOP_GAIN_RFVGA5GAIN_MASK) >> TOP_GAIN_RFVGA5GAIN_LSB)
-#define TOP_GAIN_RFVGA5GAIN_SET(x)               (((x) << TOP_GAIN_RFVGA5GAIN_LSB) & TOP_GAIN_RFVGA5GAIN_MASK)
-#define TOP_GAIN_RFGMGN_MSB                      10
-#define TOP_GAIN_RFGMGN_LSB                      8
-#define TOP_GAIN_RFGMGN_MASK                     0x00000700
-#define TOP_GAIN_RFGMGN_GET(x)                   (((x) & TOP_GAIN_RFGMGN_MASK) >> TOP_GAIN_RFGMGN_LSB)
-#define TOP_GAIN_RFGMGN_SET(x)                   (((x) << TOP_GAIN_RFGMGN_LSB) & TOP_GAIN_RFGMGN_MASK)
-#define TOP_GAIN_RX6DBLOQGAIN_MSB                7
-#define TOP_GAIN_RX6DBLOQGAIN_LSB                6
-#define TOP_GAIN_RX6DBLOQGAIN_MASK               0x000000c0
-#define TOP_GAIN_RX6DBLOQGAIN_GET(x)             (((x) & TOP_GAIN_RX6DBLOQGAIN_MASK) >> TOP_GAIN_RX6DBLOQGAIN_LSB)
-#define TOP_GAIN_RX6DBLOQGAIN_SET(x)             (((x) << TOP_GAIN_RX6DBLOQGAIN_LSB) & TOP_GAIN_RX6DBLOQGAIN_MASK)
-#define TOP_GAIN_RX1DBLOQGAIN_MSB                5
-#define TOP_GAIN_RX1DBLOQGAIN_LSB                3
-#define TOP_GAIN_RX1DBLOQGAIN_MASK               0x00000038
-#define TOP_GAIN_RX1DBLOQGAIN_GET(x)             (((x) & TOP_GAIN_RX1DBLOQGAIN_MASK) >> TOP_GAIN_RX1DBLOQGAIN_LSB)
-#define TOP_GAIN_RX1DBLOQGAIN_SET(x)             (((x) << TOP_GAIN_RX1DBLOQGAIN_LSB) & TOP_GAIN_RX1DBLOQGAIN_MASK)
-#define TOP_GAIN_RX6DBHIQGAIN_MSB                2
-#define TOP_GAIN_RX6DBHIQGAIN_LSB                1
-#define TOP_GAIN_RX6DBHIQGAIN_MASK               0x00000006
-#define TOP_GAIN_RX6DBHIQGAIN_GET(x)             (((x) & TOP_GAIN_RX6DBHIQGAIN_MASK) >> TOP_GAIN_RX6DBHIQGAIN_LSB)
-#define TOP_GAIN_RX6DBHIQGAIN_SET(x)             (((x) << TOP_GAIN_RX6DBHIQGAIN_LSB) & TOP_GAIN_RX6DBHIQGAIN_MASK)
-#define TOP_GAIN_SPARE_MSB                       0
-#define TOP_GAIN_SPARE_LSB                       0
-#define TOP_GAIN_SPARE_MASK                      0x00000001
-#define TOP_GAIN_SPARE_GET(x)                    (((x) & TOP_GAIN_SPARE_MASK) >> TOP_GAIN_SPARE_LSB)
-#define TOP_GAIN_SPARE_SET(x)                    (((x) << TOP_GAIN_SPARE_LSB) & TOP_GAIN_SPARE_MASK)
-
-#define TOP_TOP_ADDRESS                          0x00000034
-#define TOP_TOP_OFFSET                           0x00000034
-#define TOP_TOP_LOCALTXGAIN_MSB                  31
-#define TOP_TOP_LOCALTXGAIN_LSB                  31
-#define TOP_TOP_LOCALTXGAIN_MASK                 0x80000000
-#define TOP_TOP_LOCALTXGAIN_GET(x)               (((x) & TOP_TOP_LOCALTXGAIN_MASK) >> TOP_TOP_LOCALTXGAIN_LSB)
-#define TOP_TOP_LOCALTXGAIN_SET(x)               (((x) << TOP_TOP_LOCALTXGAIN_LSB) & TOP_TOP_LOCALTXGAIN_MASK)
-#define TOP_TOP_LOCALRXGAIN_MSB                  30
-#define TOP_TOP_LOCALRXGAIN_LSB                  30
-#define TOP_TOP_LOCALRXGAIN_MASK                 0x40000000
-#define TOP_TOP_LOCALRXGAIN_GET(x)               (((x) & TOP_TOP_LOCALRXGAIN_MASK) >> TOP_TOP_LOCALRXGAIN_LSB)
-#define TOP_TOP_LOCALRXGAIN_SET(x)               (((x) << TOP_TOP_LOCALRXGAIN_LSB) & TOP_TOP_LOCALRXGAIN_MASK)
-#define TOP_TOP_LOCALMODE_MSB                    29
-#define TOP_TOP_LOCALMODE_LSB                    29
-#define TOP_TOP_LOCALMODE_MASK                   0x20000000
-#define TOP_TOP_LOCALMODE_GET(x)                 (((x) & TOP_TOP_LOCALMODE_MASK) >> TOP_TOP_LOCALMODE_LSB)
-#define TOP_TOP_LOCALMODE_SET(x)                 (((x) << TOP_TOP_LOCALMODE_LSB) & TOP_TOP_LOCALMODE_MASK)
-#define TOP_TOP_CALFC_MSB                        28
-#define TOP_TOP_CALFC_LSB                        28
-#define TOP_TOP_CALFC_MASK                       0x10000000
-#define TOP_TOP_CALFC_GET(x)                     (((x) & TOP_TOP_CALFC_MASK) >> TOP_TOP_CALFC_LSB)
-#define TOP_TOP_CALFC_SET(x)                     (((x) << TOP_TOP_CALFC_LSB) & TOP_TOP_CALFC_MASK)
-#define TOP_TOP_CALDC_MSB                        27
-#define TOP_TOP_CALDC_LSB                        27
-#define TOP_TOP_CALDC_MASK                       0x08000000
-#define TOP_TOP_CALDC_GET(x)                     (((x) & TOP_TOP_CALDC_MASK) >> TOP_TOP_CALDC_LSB)
-#define TOP_TOP_CALDC_SET(x)                     (((x) << TOP_TOP_CALDC_LSB) & TOP_TOP_CALDC_MASK)
-#define TOP_TOP_CAL_RESIDUE_MSB                  26
-#define TOP_TOP_CAL_RESIDUE_LSB                  26
-#define TOP_TOP_CAL_RESIDUE_MASK                 0x04000000
-#define TOP_TOP_CAL_RESIDUE_GET(x)               (((x) & TOP_TOP_CAL_RESIDUE_MASK) >> TOP_TOP_CAL_RESIDUE_LSB)
-#define TOP_TOP_CAL_RESIDUE_SET(x)               (((x) << TOP_TOP_CAL_RESIDUE_LSB) & TOP_TOP_CAL_RESIDUE_MASK)
-#define TOP_TOP_BMODE_MSB                        25
-#define TOP_TOP_BMODE_LSB                        25
-#define TOP_TOP_BMODE_MASK                       0x02000000
-#define TOP_TOP_BMODE_GET(x)                     (((x) & TOP_TOP_BMODE_MASK) >> TOP_TOP_BMODE_LSB)
-#define TOP_TOP_BMODE_SET(x)                     (((x) << TOP_TOP_BMODE_LSB) & TOP_TOP_BMODE_MASK)
-#define TOP_TOP_SYNTHON_MSB                      24
-#define TOP_TOP_SYNTHON_LSB                      24
-#define TOP_TOP_SYNTHON_MASK                     0x01000000
-#define TOP_TOP_SYNTHON_GET(x)                   (((x) & TOP_TOP_SYNTHON_MASK) >> TOP_TOP_SYNTHON_LSB)
-#define TOP_TOP_SYNTHON_SET(x)                   (((x) << TOP_TOP_SYNTHON_LSB) & TOP_TOP_SYNTHON_MASK)
-#define TOP_TOP_RXON_MSB                         23
-#define TOP_TOP_RXON_LSB                         23
-#define TOP_TOP_RXON_MASK                        0x00800000
-#define TOP_TOP_RXON_GET(x)                      (((x) & TOP_TOP_RXON_MASK) >> TOP_TOP_RXON_LSB)
-#define TOP_TOP_RXON_SET(x)                      (((x) << TOP_TOP_RXON_LSB) & TOP_TOP_RXON_MASK)
-#define TOP_TOP_TXON_MSB                         22
-#define TOP_TOP_TXON_LSB                         22
-#define TOP_TOP_TXON_MASK                        0x00400000
-#define TOP_TOP_TXON_GET(x)                      (((x) & TOP_TOP_TXON_MASK) >> TOP_TOP_TXON_LSB)
-#define TOP_TOP_TXON_SET(x)                      (((x) << TOP_TOP_TXON_LSB) & TOP_TOP_TXON_MASK)
-#define TOP_TOP_PAON_MSB                         21
-#define TOP_TOP_PAON_LSB                         21
-#define TOP_TOP_PAON_MASK                        0x00200000
-#define TOP_TOP_PAON_GET(x)                      (((x) & TOP_TOP_PAON_MASK) >> TOP_TOP_PAON_LSB)
-#define TOP_TOP_PAON_SET(x)                      (((x) << TOP_TOP_PAON_LSB) & TOP_TOP_PAON_MASK)
-#define TOP_TOP_CALTX_MSB                        20
-#define TOP_TOP_CALTX_LSB                        20
-#define TOP_TOP_CALTX_MASK                       0x00100000
-#define TOP_TOP_CALTX_GET(x)                     (((x) & TOP_TOP_CALTX_MASK) >> TOP_TOP_CALTX_LSB)
-#define TOP_TOP_CALTX_SET(x)                     (((x) << TOP_TOP_CALTX_LSB) & TOP_TOP_CALTX_MASK)
-#define TOP_TOP_LOCALADDAC_MSB                   19
-#define TOP_TOP_LOCALADDAC_LSB                   19
-#define TOP_TOP_LOCALADDAC_MASK                  0x00080000
-#define TOP_TOP_LOCALADDAC_GET(x)                (((x) & TOP_TOP_LOCALADDAC_MASK) >> TOP_TOP_LOCALADDAC_LSB)
-#define TOP_TOP_LOCALADDAC_SET(x)                (((x) << TOP_TOP_LOCALADDAC_LSB) & TOP_TOP_LOCALADDAC_MASK)
-#define TOP_TOP_PWDPLL_MSB                       18
-#define TOP_TOP_PWDPLL_LSB                       18
-#define TOP_TOP_PWDPLL_MASK                      0x00040000
-#define TOP_TOP_PWDPLL_GET(x)                    (((x) & TOP_TOP_PWDPLL_MASK) >> TOP_TOP_PWDPLL_LSB)
-#define TOP_TOP_PWDPLL_SET(x)                    (((x) << TOP_TOP_PWDPLL_LSB) & TOP_TOP_PWDPLL_MASK)
-#define TOP_TOP_PWDADC_MSB                       17
-#define TOP_TOP_PWDADC_LSB                       17
-#define TOP_TOP_PWDADC_MASK                      0x00020000
-#define TOP_TOP_PWDADC_GET(x)                    (((x) & TOP_TOP_PWDADC_MASK) >> TOP_TOP_PWDADC_LSB)
-#define TOP_TOP_PWDADC_SET(x)                    (((x) << TOP_TOP_PWDADC_LSB) & TOP_TOP_PWDADC_MASK)
-#define TOP_TOP_PWDDAC_MSB                       16
-#define TOP_TOP_PWDDAC_LSB                       16
-#define TOP_TOP_PWDDAC_MASK                      0x00010000
-#define TOP_TOP_PWDDAC_GET(x)                    (((x) & TOP_TOP_PWDDAC_MASK) >> TOP_TOP_PWDDAC_LSB)
-#define TOP_TOP_PWDDAC_SET(x)                    (((x) << TOP_TOP_PWDDAC_LSB) & TOP_TOP_PWDDAC_MASK)
-#define TOP_TOP_LOCALXTAL_MSB                    15
-#define TOP_TOP_LOCALXTAL_LSB                    15
-#define TOP_TOP_LOCALXTAL_MASK                   0x00008000
-#define TOP_TOP_LOCALXTAL_GET(x)                 (((x) & TOP_TOP_LOCALXTAL_MASK) >> TOP_TOP_LOCALXTAL_LSB)
-#define TOP_TOP_LOCALXTAL_SET(x)                 (((x) << TOP_TOP_LOCALXTAL_LSB) & TOP_TOP_LOCALXTAL_MASK)
-#define TOP_TOP_PWDCLKIN_MSB                     14
-#define TOP_TOP_PWDCLKIN_LSB                     14
-#define TOP_TOP_PWDCLKIN_MASK                    0x00004000
-#define TOP_TOP_PWDCLKIN_GET(x)                  (((x) & TOP_TOP_PWDCLKIN_MASK) >> TOP_TOP_PWDCLKIN_LSB)
-#define TOP_TOP_PWDCLKIN_SET(x)                  (((x) << TOP_TOP_PWDCLKIN_LSB) & TOP_TOP_PWDCLKIN_MASK)
-#define TOP_TOP_OSCON_MSB                        13
-#define TOP_TOP_OSCON_LSB                        13
-#define TOP_TOP_OSCON_MASK                       0x00002000
-#define TOP_TOP_OSCON_GET(x)                     (((x) & TOP_TOP_OSCON_MASK) >> TOP_TOP_OSCON_LSB)
-#define TOP_TOP_OSCON_SET(x)                     (((x) << TOP_TOP_OSCON_LSB) & TOP_TOP_OSCON_MASK)
-#define TOP_TOP_SCLKEN_FORCE_MSB                 12
-#define TOP_TOP_SCLKEN_FORCE_LSB                 12
-#define TOP_TOP_SCLKEN_FORCE_MASK                0x00001000
-#define TOP_TOP_SCLKEN_FORCE_GET(x)              (((x) & TOP_TOP_SCLKEN_FORCE_MASK) >> TOP_TOP_SCLKEN_FORCE_LSB)
-#define TOP_TOP_SCLKEN_FORCE_SET(x)              (((x) << TOP_TOP_SCLKEN_FORCE_LSB) & TOP_TOP_SCLKEN_FORCE_MASK)
-#define TOP_TOP_SYNTHON_FORCE_MSB                11
-#define TOP_TOP_SYNTHON_FORCE_LSB                11
-#define TOP_TOP_SYNTHON_FORCE_MASK               0x00000800
-#define TOP_TOP_SYNTHON_FORCE_GET(x)             (((x) & TOP_TOP_SYNTHON_FORCE_MASK) >> TOP_TOP_SYNTHON_FORCE_LSB)
-#define TOP_TOP_SYNTHON_FORCE_SET(x)             (((x) << TOP_TOP_SYNTHON_FORCE_LSB) & TOP_TOP_SYNTHON_FORCE_MASK)
-#define TOP_TOP_PDBIAS_MSB                       10
-#define TOP_TOP_PDBIAS_LSB                       10
-#define TOP_TOP_PDBIAS_MASK                      0x00000400
-#define TOP_TOP_PDBIAS_GET(x)                    (((x) & TOP_TOP_PDBIAS_MASK) >> TOP_TOP_PDBIAS_LSB)
-#define TOP_TOP_PDBIAS_SET(x)                    (((x) << TOP_TOP_PDBIAS_LSB) & TOP_TOP_PDBIAS_MASK)
-#define TOP_TOP_DATAOUTSEL_MSB                   9
-#define TOP_TOP_DATAOUTSEL_LSB                   8
-#define TOP_TOP_DATAOUTSEL_MASK                  0x00000300
-#define TOP_TOP_DATAOUTSEL_GET(x)                (((x) & TOP_TOP_DATAOUTSEL_MASK) >> TOP_TOP_DATAOUTSEL_LSB)
-#define TOP_TOP_DATAOUTSEL_SET(x)                (((x) << TOP_TOP_DATAOUTSEL_LSB) & TOP_TOP_DATAOUTSEL_MASK)
-#define TOP_TOP_REVID_MSB                        7
-#define TOP_TOP_REVID_LSB                        5
-#define TOP_TOP_REVID_MASK                       0x000000e0
-#define TOP_TOP_REVID_GET(x)                     (((x) & TOP_TOP_REVID_MASK) >> TOP_TOP_REVID_LSB)
-#define TOP_TOP_REVID_SET(x)                     (((x) << TOP_TOP_REVID_LSB) & TOP_TOP_REVID_MASK)
-#define TOP_TOP_INT2PAD_MSB                      4
-#define TOP_TOP_INT2PAD_LSB                      4
-#define TOP_TOP_INT2PAD_MASK                     0x00000010
-#define TOP_TOP_INT2PAD_GET(x)                   (((x) & TOP_TOP_INT2PAD_MASK) >> TOP_TOP_INT2PAD_LSB)
-#define TOP_TOP_INT2PAD_SET(x)                   (((x) << TOP_TOP_INT2PAD_LSB) & TOP_TOP_INT2PAD_MASK)
-#define TOP_TOP_INTH2PAD_MSB                     3
-#define TOP_TOP_INTH2PAD_LSB                     3
-#define TOP_TOP_INTH2PAD_MASK                    0x00000008
-#define TOP_TOP_INTH2PAD_GET(x)                  (((x) & TOP_TOP_INTH2PAD_MASK) >> TOP_TOP_INTH2PAD_LSB)
-#define TOP_TOP_INTH2PAD_SET(x)                  (((x) << TOP_TOP_INTH2PAD_LSB) & TOP_TOP_INTH2PAD_MASK)
-#define TOP_TOP_PAD2GND_MSB                      2
-#define TOP_TOP_PAD2GND_LSB                      2
-#define TOP_TOP_PAD2GND_MASK                     0x00000004
-#define TOP_TOP_PAD2GND_GET(x)                   (((x) & TOP_TOP_PAD2GND_MASK) >> TOP_TOP_PAD2GND_LSB)
-#define TOP_TOP_PAD2GND_SET(x)                   (((x) << TOP_TOP_PAD2GND_LSB) & TOP_TOP_PAD2GND_MASK)
-#define TOP_TOP_INT2GND_MSB                      1
-#define TOP_TOP_INT2GND_LSB                      1
-#define TOP_TOP_INT2GND_MASK                     0x00000002
-#define TOP_TOP_INT2GND_GET(x)                   (((x) & TOP_TOP_INT2GND_MASK) >> TOP_TOP_INT2GND_LSB)
-#define TOP_TOP_INT2GND_SET(x)                   (((x) << TOP_TOP_INT2GND_LSB) & TOP_TOP_INT2GND_MASK)
-#define TOP_TOP_FORCE_XPAON_MSB                  0
-#define TOP_TOP_FORCE_XPAON_LSB                  0
-#define TOP_TOP_FORCE_XPAON_MASK                 0x00000001
-#define TOP_TOP_FORCE_XPAON_GET(x)               (((x) & TOP_TOP_FORCE_XPAON_MASK) >> TOP_TOP_FORCE_XPAON_LSB)
-#define TOP_TOP_FORCE_XPAON_SET(x)               (((x) << TOP_TOP_FORCE_XPAON_LSB) & TOP_TOP_FORCE_XPAON_MASK)
-
-#define BIAS_BIAS_SEL_ADDRESS                    0x00000038
-#define BIAS_BIAS_SEL_OFFSET                     0x00000038
-#define BIAS_BIAS_SEL_PADON_MSB                  31
-#define BIAS_BIAS_SEL_PADON_LSB                  31
-#define BIAS_BIAS_SEL_PADON_MASK                 0x80000000
-#define BIAS_BIAS_SEL_PADON_GET(x)               (((x) & BIAS_BIAS_SEL_PADON_MASK) >> BIAS_BIAS_SEL_PADON_LSB)
-#define BIAS_BIAS_SEL_PADON_SET(x)               (((x) << BIAS_BIAS_SEL_PADON_LSB) & BIAS_BIAS_SEL_PADON_MASK)
-#define BIAS_BIAS_SEL_SEL_BIAS_MSB               30
-#define BIAS_BIAS_SEL_SEL_BIAS_LSB               25
-#define BIAS_BIAS_SEL_SEL_BIAS_MASK              0x7e000000
-#define BIAS_BIAS_SEL_SEL_BIAS_GET(x)            (((x) & BIAS_BIAS_SEL_SEL_BIAS_MASK) >> BIAS_BIAS_SEL_SEL_BIAS_LSB)
-#define BIAS_BIAS_SEL_SEL_BIAS_SET(x)            (((x) << BIAS_BIAS_SEL_SEL_BIAS_LSB) & BIAS_BIAS_SEL_SEL_BIAS_MASK)
-#define BIAS_BIAS_SEL_SEL_SPARE_MSB              24
-#define BIAS_BIAS_SEL_SEL_SPARE_LSB              21
-#define BIAS_BIAS_SEL_SEL_SPARE_MASK             0x01e00000
-#define BIAS_BIAS_SEL_SEL_SPARE_GET(x)           (((x) & BIAS_BIAS_SEL_SEL_SPARE_MASK) >> BIAS_BIAS_SEL_SEL_SPARE_LSB)
-#define BIAS_BIAS_SEL_SEL_SPARE_SET(x)           (((x) << BIAS_BIAS_SEL_SEL_SPARE_LSB) & BIAS_BIAS_SEL_SEL_SPARE_MASK)
-#define BIAS_BIAS_SEL_SPARE_MSB                  20
-#define BIAS_BIAS_SEL_SPARE_LSB                  20
-#define BIAS_BIAS_SEL_SPARE_MASK                 0x00100000
-#define BIAS_BIAS_SEL_SPARE_GET(x)               (((x) & BIAS_BIAS_SEL_SPARE_MASK) >> BIAS_BIAS_SEL_SPARE_LSB)
-#define BIAS_BIAS_SEL_SPARE_SET(x)               (((x) << BIAS_BIAS_SEL_SPARE_LSB) & BIAS_BIAS_SEL_SPARE_MASK)
-#define BIAS_BIAS_SEL_PWD_ICREFBUFBIAS12P5_MSB   19
-#define BIAS_BIAS_SEL_PWD_ICREFBUFBIAS12P5_LSB   17
-#define BIAS_BIAS_SEL_PWD_ICREFBUFBIAS12P5_MASK  0x000e0000
-#define BIAS_BIAS_SEL_PWD_ICREFBUFBIAS12P5_GET(x) (((x) & BIAS_BIAS_SEL_PWD_ICREFBUFBIAS12P5_MASK) >> BIAS_BIAS_SEL_PWD_ICREFBUFBIAS12P5_LSB)
-#define BIAS_BIAS_SEL_PWD_ICREFBUFBIAS12P5_SET(x) (((x) << BIAS_BIAS_SEL_PWD_ICREFBUFBIAS12P5_LSB) & BIAS_BIAS_SEL_PWD_ICREFBUFBIAS12P5_MASK)
-#define BIAS_BIAS_SEL_PWD_IRDACREGREF12P5_MSB    16
-#define BIAS_BIAS_SEL_PWD_IRDACREGREF12P5_LSB    16
-#define BIAS_BIAS_SEL_PWD_IRDACREGREF12P5_MASK   0x00010000
-#define BIAS_BIAS_SEL_PWD_IRDACREGREF12P5_GET(x) (((x) & BIAS_BIAS_SEL_PWD_IRDACREGREF12P5_MASK) >> BIAS_BIAS_SEL_PWD_IRDACREGREF12P5_LSB)
-#define BIAS_BIAS_SEL_PWD_IRDACREGREF12P5_SET(x) (((x) << BIAS_BIAS_SEL_PWD_IRDACREGREF12P5_LSB) & BIAS_BIAS_SEL_PWD_IRDACREGREF12P5_MASK)
-#define BIAS_BIAS_SEL_PWD_IRREFMASTERBIAS12P5_MSB 15
-#define BIAS_BIAS_SEL_PWD_IRREFMASTERBIAS12P5_LSB 15
-#define BIAS_BIAS_SEL_PWD_IRREFMASTERBIAS12P5_MASK 0x00008000
-#define BIAS_BIAS_SEL_PWD_IRREFMASTERBIAS12P5_GET(x) (((x) & BIAS_BIAS_SEL_PWD_IRREFMASTERBIAS12P5_MASK) >> BIAS_BIAS_SEL_PWD_IRREFMASTERBIAS12P5_LSB)
-#define BIAS_BIAS_SEL_PWD_IRREFMASTERBIAS12P5_SET(x) (((x) << BIAS_BIAS_SEL_PWD_IRREFMASTERBIAS12P5_LSB) & BIAS_BIAS_SEL_PWD_IRREFMASTERBIAS12P5_MASK)
-#define BIAS_BIAS_SEL_PWD_ICREFOPAMPBIAS25_MSB   14
-#define BIAS_BIAS_SEL_PWD_ICREFOPAMPBIAS25_LSB   14
-#define BIAS_BIAS_SEL_PWD_ICREFOPAMPBIAS25_MASK  0x00004000
-#define BIAS_BIAS_SEL_PWD_ICREFOPAMPBIAS25_GET(x) (((x) & BIAS_BIAS_SEL_PWD_ICREFOPAMPBIAS25_MASK) >> BIAS_BIAS_SEL_PWD_ICREFOPAMPBIAS25_LSB)
-#define BIAS_BIAS_SEL_PWD_ICREFOPAMPBIAS25_SET(x) (((x) << BIAS_BIAS_SEL_PWD_ICREFOPAMPBIAS25_LSB) & BIAS_BIAS_SEL_PWD_ICREFOPAMPBIAS25_MASK)
-#define BIAS_BIAS_SEL_PWD_ICCPLL25_MSB           13
-#define BIAS_BIAS_SEL_PWD_ICCPLL25_LSB           13
-#define BIAS_BIAS_SEL_PWD_ICCPLL25_MASK          0x00002000
-#define BIAS_BIAS_SEL_PWD_ICCPLL25_GET(x)        (((x) & BIAS_BIAS_SEL_PWD_ICCPLL25_MASK) >> BIAS_BIAS_SEL_PWD_ICCPLL25_LSB)
-#define BIAS_BIAS_SEL_PWD_ICCPLL25_SET(x)        (((x) << BIAS_BIAS_SEL_PWD_ICCPLL25_LSB) & BIAS_BIAS_SEL_PWD_ICCPLL25_MASK)
-#define BIAS_BIAS_SEL_PWD_ICCOMPBIAS25_MSB       12
-#define BIAS_BIAS_SEL_PWD_ICCOMPBIAS25_LSB       10
-#define BIAS_BIAS_SEL_PWD_ICCOMPBIAS25_MASK      0x00001c00
-#define BIAS_BIAS_SEL_PWD_ICCOMPBIAS25_GET(x)    (((x) & BIAS_BIAS_SEL_PWD_ICCOMPBIAS25_MASK) >> BIAS_BIAS_SEL_PWD_ICCOMPBIAS25_LSB)
-#define BIAS_BIAS_SEL_PWD_ICCOMPBIAS25_SET(x)    (((x) << BIAS_BIAS_SEL_PWD_ICCOMPBIAS25_LSB) & BIAS_BIAS_SEL_PWD_ICCOMPBIAS25_MASK)
-#define BIAS_BIAS_SEL_PWD_ICXTAL25_MSB           9
-#define BIAS_BIAS_SEL_PWD_ICXTAL25_LSB           7
-#define BIAS_BIAS_SEL_PWD_ICXTAL25_MASK          0x00000380
-#define BIAS_BIAS_SEL_PWD_ICXTAL25_GET(x)        (((x) & BIAS_BIAS_SEL_PWD_ICXTAL25_MASK) >> BIAS_BIAS_SEL_PWD_ICXTAL25_LSB)
-#define BIAS_BIAS_SEL_PWD_ICXTAL25_SET(x)        (((x) << BIAS_BIAS_SEL_PWD_ICXTAL25_LSB) & BIAS_BIAS_SEL_PWD_ICXTAL25_MASK)
-#define BIAS_BIAS_SEL_PWD_ICTSENS25_MSB          6
-#define BIAS_BIAS_SEL_PWD_ICTSENS25_LSB          4
-#define BIAS_BIAS_SEL_PWD_ICTSENS25_MASK         0x00000070
-#define BIAS_BIAS_SEL_PWD_ICTSENS25_GET(x)       (((x) & BIAS_BIAS_SEL_PWD_ICTSENS25_MASK) >> BIAS_BIAS_SEL_PWD_ICTSENS25_LSB)
-#define BIAS_BIAS_SEL_PWD_ICTSENS25_SET(x)       (((x) << BIAS_BIAS_SEL_PWD_ICTSENS25_LSB) & BIAS_BIAS_SEL_PWD_ICTSENS25_MASK)
-#define BIAS_BIAS_SEL_PWD_ICTXPC25_MSB           3
-#define BIAS_BIAS_SEL_PWD_ICTXPC25_LSB           1
-#define BIAS_BIAS_SEL_PWD_ICTXPC25_MASK          0x0000000e
-#define BIAS_BIAS_SEL_PWD_ICTXPC25_GET(x)        (((x) & BIAS_BIAS_SEL_PWD_ICTXPC25_MASK) >> BIAS_BIAS_SEL_PWD_ICTXPC25_LSB)
-#define BIAS_BIAS_SEL_PWD_ICTXPC25_SET(x)        (((x) << BIAS_BIAS_SEL_PWD_ICTXPC25_LSB) & BIAS_BIAS_SEL_PWD_ICTXPC25_MASK)
-#define BIAS_BIAS_SEL_PWD_ICLDO25_MSB            0
-#define BIAS_BIAS_SEL_PWD_ICLDO25_LSB            0
-#define BIAS_BIAS_SEL_PWD_ICLDO25_MASK           0x00000001
-#define BIAS_BIAS_SEL_PWD_ICLDO25_GET(x)         (((x) & BIAS_BIAS_SEL_PWD_ICLDO25_MASK) >> BIAS_BIAS_SEL_PWD_ICLDO25_LSB)
-#define BIAS_BIAS_SEL_PWD_ICLDO25_SET(x)         (((x) << BIAS_BIAS_SEL_PWD_ICLDO25_LSB) & BIAS_BIAS_SEL_PWD_ICLDO25_MASK)
-
-#define BIAS_BIAS1_ADDRESS                       0x0000003c
-#define BIAS_BIAS1_OFFSET                        0x0000003c
-#define BIAS_BIAS1_PWD_ICDAC2BB25_MSB            31
-#define BIAS_BIAS1_PWD_ICDAC2BB25_LSB            29
-#define BIAS_BIAS1_PWD_ICDAC2BB25_MASK           0xe0000000
-#define BIAS_BIAS1_PWD_ICDAC2BB25_GET(x)         (((x) & BIAS_BIAS1_PWD_ICDAC2BB25_MASK) >> BIAS_BIAS1_PWD_ICDAC2BB25_LSB)
-#define BIAS_BIAS1_PWD_ICDAC2BB25_SET(x)         (((x) << BIAS_BIAS1_PWD_ICDAC2BB25_LSB) & BIAS_BIAS1_PWD_ICDAC2BB25_MASK)
-#define BIAS_BIAS1_PWD_IC2GVGM25_MSB             28
-#define BIAS_BIAS1_PWD_IC2GVGM25_LSB             26
-#define BIAS_BIAS1_PWD_IC2GVGM25_MASK            0x1c000000
-#define BIAS_BIAS1_PWD_IC2GVGM25_GET(x)          (((x) & BIAS_BIAS1_PWD_IC2GVGM25_MASK) >> BIAS_BIAS1_PWD_IC2GVGM25_LSB)
-#define BIAS_BIAS1_PWD_IC2GVGM25_SET(x)          (((x) << BIAS_BIAS1_PWD_IC2GVGM25_LSB) & BIAS_BIAS1_PWD_IC2GVGM25_MASK)
-#define BIAS_BIAS1_PWD_IC2GRFFE25_MSB            25
-#define BIAS_BIAS1_PWD_IC2GRFFE25_LSB            23
-#define BIAS_BIAS1_PWD_IC2GRFFE25_MASK           0x03800000
-#define BIAS_BIAS1_PWD_IC2GRFFE25_GET(x)         (((x) & BIAS_BIAS1_PWD_IC2GRFFE25_MASK) >> BIAS_BIAS1_PWD_IC2GRFFE25_LSB)
-#define BIAS_BIAS1_PWD_IC2GRFFE25_SET(x)         (((x) << BIAS_BIAS1_PWD_IC2GRFFE25_LSB) & BIAS_BIAS1_PWD_IC2GRFFE25_MASK)
-#define BIAS_BIAS1_PWD_IC2GLOREG25_MSB           22
-#define BIAS_BIAS1_PWD_IC2GLOREG25_LSB           20
-#define BIAS_BIAS1_PWD_IC2GLOREG25_MASK          0x00700000
-#define BIAS_BIAS1_PWD_IC2GLOREG25_GET(x)        (((x) & BIAS_BIAS1_PWD_IC2GLOREG25_MASK) >> BIAS_BIAS1_PWD_IC2GLOREG25_LSB)
-#define BIAS_BIAS1_PWD_IC2GLOREG25_SET(x)        (((x) << BIAS_BIAS1_PWD_IC2GLOREG25_LSB) & BIAS_BIAS1_PWD_IC2GLOREG25_MASK)
-#define BIAS_BIAS1_PWD_IC2GLNAREG25_MSB          19
-#define BIAS_BIAS1_PWD_IC2GLNAREG25_LSB          17
-#define BIAS_BIAS1_PWD_IC2GLNAREG25_MASK         0x000e0000
-#define BIAS_BIAS1_PWD_IC2GLNAREG25_GET(x)       (((x) & BIAS_BIAS1_PWD_IC2GLNAREG25_MASK) >> BIAS_BIAS1_PWD_IC2GLNAREG25_LSB)
-#define BIAS_BIAS1_PWD_IC2GLNAREG25_SET(x)       (((x) << BIAS_BIAS1_PWD_IC2GLNAREG25_LSB) & BIAS_BIAS1_PWD_IC2GLNAREG25_MASK)
-#define BIAS_BIAS1_PWD_ICDETECTORB25_MSB         16
-#define BIAS_BIAS1_PWD_ICDETECTORB25_LSB         16
-#define BIAS_BIAS1_PWD_ICDETECTORB25_MASK        0x00010000
-#define BIAS_BIAS1_PWD_ICDETECTORB25_GET(x)      (((x) & BIAS_BIAS1_PWD_ICDETECTORB25_MASK) >> BIAS_BIAS1_PWD_ICDETECTORB25_LSB)
-#define BIAS_BIAS1_PWD_ICDETECTORB25_SET(x)      (((x) << BIAS_BIAS1_PWD_ICDETECTORB25_LSB) & BIAS_BIAS1_PWD_ICDETECTORB25_MASK)
-#define BIAS_BIAS1_PWD_ICDETECTORA25_MSB         15
-#define BIAS_BIAS1_PWD_ICDETECTORA25_LSB         15
-#define BIAS_BIAS1_PWD_ICDETECTORA25_MASK        0x00008000
-#define BIAS_BIAS1_PWD_ICDETECTORA25_GET(x)      (((x) & BIAS_BIAS1_PWD_ICDETECTORA25_MASK) >> BIAS_BIAS1_PWD_ICDETECTORA25_LSB)
-#define BIAS_BIAS1_PWD_ICDETECTORA25_SET(x)      (((x) << BIAS_BIAS1_PWD_ICDETECTORA25_LSB) & BIAS_BIAS1_PWD_ICDETECTORA25_MASK)
-#define BIAS_BIAS1_PWD_IC5GRXRF25_MSB            14
-#define BIAS_BIAS1_PWD_IC5GRXRF25_LSB            14
-#define BIAS_BIAS1_PWD_IC5GRXRF25_MASK           0x00004000
-#define BIAS_BIAS1_PWD_IC5GRXRF25_GET(x)         (((x) & BIAS_BIAS1_PWD_IC5GRXRF25_MASK) >> BIAS_BIAS1_PWD_IC5GRXRF25_LSB)
-#define BIAS_BIAS1_PWD_IC5GRXRF25_SET(x)         (((x) << BIAS_BIAS1_PWD_IC5GRXRF25_LSB) & BIAS_BIAS1_PWD_IC5GRXRF25_MASK)
-#define BIAS_BIAS1_PWD_IC5GTXPA25_MSB            13
-#define BIAS_BIAS1_PWD_IC5GTXPA25_LSB            11
-#define BIAS_BIAS1_PWD_IC5GTXPA25_MASK           0x00003800
-#define BIAS_BIAS1_PWD_IC5GTXPA25_GET(x)         (((x) & BIAS_BIAS1_PWD_IC5GTXPA25_MASK) >> BIAS_BIAS1_PWD_IC5GTXPA25_LSB)
-#define BIAS_BIAS1_PWD_IC5GTXPA25_SET(x)         (((x) << BIAS_BIAS1_PWD_IC5GTXPA25_LSB) & BIAS_BIAS1_PWD_IC5GTXPA25_MASK)
-#define BIAS_BIAS1_PWD_IC5GTXBUF25_MSB           10
-#define BIAS_BIAS1_PWD_IC5GTXBUF25_LSB           8
-#define BIAS_BIAS1_PWD_IC5GTXBUF25_MASK          0x00000700
-#define BIAS_BIAS1_PWD_IC5GTXBUF25_GET(x)        (((x) & BIAS_BIAS1_PWD_IC5GTXBUF25_MASK) >> BIAS_BIAS1_PWD_IC5GTXBUF25_LSB)
-#define BIAS_BIAS1_PWD_IC5GTXBUF25_SET(x)        (((x) << BIAS_BIAS1_PWD_IC5GTXBUF25_LSB) & BIAS_BIAS1_PWD_IC5GTXBUF25_MASK)
-#define BIAS_BIAS1_PWD_IC5GQB25_MSB              7
-#define BIAS_BIAS1_PWD_IC5GQB25_LSB              5
-#define BIAS_BIAS1_PWD_IC5GQB25_MASK             0x000000e0
-#define BIAS_BIAS1_PWD_IC5GQB25_GET(x)           (((x) & BIAS_BIAS1_PWD_IC5GQB25_MASK) >> BIAS_BIAS1_PWD_IC5GQB25_LSB)
-#define BIAS_BIAS1_PWD_IC5GQB25_SET(x)           (((x) << BIAS_BIAS1_PWD_IC5GQB25_LSB) & BIAS_BIAS1_PWD_IC5GQB25_MASK)
-#define BIAS_BIAS1_PWD_IC5GMIXQ25_MSB            4
-#define BIAS_BIAS1_PWD_IC5GMIXQ25_LSB            2
-#define BIAS_BIAS1_PWD_IC5GMIXQ25_MASK           0x0000001c
-#define BIAS_BIAS1_PWD_IC5GMIXQ25_GET(x)         (((x) & BIAS_BIAS1_PWD_IC5GMIXQ25_MASK) >> BIAS_BIAS1_PWD_IC5GMIXQ25_LSB)
-#define BIAS_BIAS1_PWD_IC5GMIXQ25_SET(x)         (((x) << BIAS_BIAS1_PWD_IC5GMIXQ25_LSB) & BIAS_BIAS1_PWD_IC5GMIXQ25_MASK)
-#define BIAS_BIAS1_SPARE_MSB                     1
-#define BIAS_BIAS1_SPARE_LSB                     0
-#define BIAS_BIAS1_SPARE_MASK                    0x00000003
-#define BIAS_BIAS1_SPARE_GET(x)                  (((x) & BIAS_BIAS1_SPARE_MASK) >> BIAS_BIAS1_SPARE_LSB)
-#define BIAS_BIAS1_SPARE_SET(x)                  (((x) << BIAS_BIAS1_SPARE_LSB) & BIAS_BIAS1_SPARE_MASK)
-
-#define BIAS_BIAS2_ADDRESS                       0x00000040
-#define BIAS_BIAS2_OFFSET                        0x00000040
-#define BIAS_BIAS2_PWD_IC5GMIXI25_MSB            31
-#define BIAS_BIAS2_PWD_IC5GMIXI25_LSB            29
-#define BIAS_BIAS2_PWD_IC5GMIXI25_MASK           0xe0000000
-#define BIAS_BIAS2_PWD_IC5GMIXI25_GET(x)         (((x) & BIAS_BIAS2_PWD_IC5GMIXI25_MASK) >> BIAS_BIAS2_PWD_IC5GMIXI25_LSB)
-#define BIAS_BIAS2_PWD_IC5GMIXI25_SET(x)         (((x) << BIAS_BIAS2_PWD_IC5GMIXI25_LSB) & BIAS_BIAS2_PWD_IC5GMIXI25_MASK)
-#define BIAS_BIAS2_PWD_IC5GDIV25_MSB             28
-#define BIAS_BIAS2_PWD_IC5GDIV25_LSB             26
-#define BIAS_BIAS2_PWD_IC5GDIV25_MASK            0x1c000000
-#define BIAS_BIAS2_PWD_IC5GDIV25_GET(x)          (((x) & BIAS_BIAS2_PWD_IC5GDIV25_MASK) >> BIAS_BIAS2_PWD_IC5GDIV25_LSB)
-#define BIAS_BIAS2_PWD_IC5GDIV25_SET(x)          (((x) << BIAS_BIAS2_PWD_IC5GDIV25_LSB) & BIAS_BIAS2_PWD_IC5GDIV25_MASK)
-#define BIAS_BIAS2_PWD_IC5GLOREG25_MSB           25
-#define BIAS_BIAS2_PWD_IC5GLOREG25_LSB           23
-#define BIAS_BIAS2_PWD_IC5GLOREG25_MASK          0x03800000
-#define BIAS_BIAS2_PWD_IC5GLOREG25_GET(x)        (((x) & BIAS_BIAS2_PWD_IC5GLOREG25_MASK) >> BIAS_BIAS2_PWD_IC5GLOREG25_LSB)
-#define BIAS_BIAS2_PWD_IC5GLOREG25_SET(x)        (((x) << BIAS_BIAS2_PWD_IC5GLOREG25_LSB) & BIAS_BIAS2_PWD_IC5GLOREG25_MASK)
-#define BIAS_BIAS2_PWD_IRPLL25_MSB               22
-#define BIAS_BIAS2_PWD_IRPLL25_LSB               22
-#define BIAS_BIAS2_PWD_IRPLL25_MASK              0x00400000
-#define BIAS_BIAS2_PWD_IRPLL25_GET(x)            (((x) & BIAS_BIAS2_PWD_IRPLL25_MASK) >> BIAS_BIAS2_PWD_IRPLL25_LSB)
-#define BIAS_BIAS2_PWD_IRPLL25_SET(x)            (((x) << BIAS_BIAS2_PWD_IRPLL25_LSB) & BIAS_BIAS2_PWD_IRPLL25_MASK)
-#define BIAS_BIAS2_PWD_IRXTAL25_MSB              21
-#define BIAS_BIAS2_PWD_IRXTAL25_LSB              19
-#define BIAS_BIAS2_PWD_IRXTAL25_MASK             0x00380000
-#define BIAS_BIAS2_PWD_IRXTAL25_GET(x)           (((x) & BIAS_BIAS2_PWD_IRXTAL25_MASK) >> BIAS_BIAS2_PWD_IRXTAL25_LSB)
-#define BIAS_BIAS2_PWD_IRXTAL25_SET(x)           (((x) << BIAS_BIAS2_PWD_IRXTAL25_LSB) & BIAS_BIAS2_PWD_IRXTAL25_MASK)
-#define BIAS_BIAS2_PWD_IRTSENS25_MSB             18
-#define BIAS_BIAS2_PWD_IRTSENS25_LSB             16
-#define BIAS_BIAS2_PWD_IRTSENS25_MASK            0x00070000
-#define BIAS_BIAS2_PWD_IRTSENS25_GET(x)          (((x) & BIAS_BIAS2_PWD_IRTSENS25_MASK) >> BIAS_BIAS2_PWD_IRTSENS25_LSB)
-#define BIAS_BIAS2_PWD_IRTSENS25_SET(x)          (((x) << BIAS_BIAS2_PWD_IRTSENS25_LSB) & BIAS_BIAS2_PWD_IRTSENS25_MASK)
-#define BIAS_BIAS2_PWD_IRTXPC25_MSB              15
-#define BIAS_BIAS2_PWD_IRTXPC25_LSB              13
-#define BIAS_BIAS2_PWD_IRTXPC25_MASK             0x0000e000
-#define BIAS_BIAS2_PWD_IRTXPC25_GET(x)           (((x) & BIAS_BIAS2_PWD_IRTXPC25_MASK) >> BIAS_BIAS2_PWD_IRTXPC25_LSB)
-#define BIAS_BIAS2_PWD_IRTXPC25_SET(x)           (((x) << BIAS_BIAS2_PWD_IRTXPC25_LSB) & BIAS_BIAS2_PWD_IRTXPC25_MASK)
-#define BIAS_BIAS2_PWD_IRLDO25_MSB               12
-#define BIAS_BIAS2_PWD_IRLDO25_LSB               12
-#define BIAS_BIAS2_PWD_IRLDO25_MASK              0x00001000
-#define BIAS_BIAS2_PWD_IRLDO25_GET(x)            (((x) & BIAS_BIAS2_PWD_IRLDO25_MASK) >> BIAS_BIAS2_PWD_IRLDO25_LSB)
-#define BIAS_BIAS2_PWD_IRLDO25_SET(x)            (((x) << BIAS_BIAS2_PWD_IRLDO25_LSB) & BIAS_BIAS2_PWD_IRLDO25_MASK)
-#define BIAS_BIAS2_PWD_IR2GTXMIX25_MSB           11
-#define BIAS_BIAS2_PWD_IR2GTXMIX25_LSB           9
-#define BIAS_BIAS2_PWD_IR2GTXMIX25_MASK          0x00000e00
-#define BIAS_BIAS2_PWD_IR2GTXMIX25_GET(x)        (((x) & BIAS_BIAS2_PWD_IR2GTXMIX25_MASK) >> BIAS_BIAS2_PWD_IR2GTXMIX25_LSB)
-#define BIAS_BIAS2_PWD_IR2GTXMIX25_SET(x)        (((x) << BIAS_BIAS2_PWD_IR2GTXMIX25_LSB) & BIAS_BIAS2_PWD_IR2GTXMIX25_MASK)
-#define BIAS_BIAS2_PWD_IR2GLOREG25_MSB           8
-#define BIAS_BIAS2_PWD_IR2GLOREG25_LSB           6
-#define BIAS_BIAS2_PWD_IR2GLOREG25_MASK          0x000001c0
-#define BIAS_BIAS2_PWD_IR2GLOREG25_GET(x)        (((x) & BIAS_BIAS2_PWD_IR2GLOREG25_MASK) >> BIAS_BIAS2_PWD_IR2GLOREG25_LSB)
-#define BIAS_BIAS2_PWD_IR2GLOREG25_SET(x)        (((x) << BIAS_BIAS2_PWD_IR2GLOREG25_LSB) & BIAS_BIAS2_PWD_IR2GLOREG25_MASK)
-#define BIAS_BIAS2_PWD_IR2GLNAREG25_MSB          5
-#define BIAS_BIAS2_PWD_IR2GLNAREG25_LSB          3
-#define BIAS_BIAS2_PWD_IR2GLNAREG25_MASK         0x00000038
-#define BIAS_BIAS2_PWD_IR2GLNAREG25_GET(x)       (((x) & BIAS_BIAS2_PWD_IR2GLNAREG25_MASK) >> BIAS_BIAS2_PWD_IR2GLNAREG25_LSB)
-#define BIAS_BIAS2_PWD_IR2GLNAREG25_SET(x)       (((x) << BIAS_BIAS2_PWD_IR2GLNAREG25_LSB) & BIAS_BIAS2_PWD_IR2GLNAREG25_MASK)
-#define BIAS_BIAS2_PWD_IR5GRFVREF2525_MSB        2
-#define BIAS_BIAS2_PWD_IR5GRFVREF2525_LSB        0
-#define BIAS_BIAS2_PWD_IR5GRFVREF2525_MASK       0x00000007
-#define BIAS_BIAS2_PWD_IR5GRFVREF2525_GET(x)     (((x) & BIAS_BIAS2_PWD_IR5GRFVREF2525_MASK) >> BIAS_BIAS2_PWD_IR5GRFVREF2525_LSB)
-#define BIAS_BIAS2_PWD_IR5GRFVREF2525_SET(x)     (((x) << BIAS_BIAS2_PWD_IR5GRFVREF2525_LSB) & BIAS_BIAS2_PWD_IR5GRFVREF2525_MASK)
-
-#define BIAS_BIAS3_ADDRESS                       0x00000044
-#define BIAS_BIAS3_OFFSET                        0x00000044
-#define BIAS_BIAS3_PWD_IR5GTXMIX25_MSB           31
-#define BIAS_BIAS3_PWD_IR5GTXMIX25_LSB           29
-#define BIAS_BIAS3_PWD_IR5GTXMIX25_MASK          0xe0000000
-#define BIAS_BIAS3_PWD_IR5GTXMIX25_GET(x)        (((x) & BIAS_BIAS3_PWD_IR5GTXMIX25_MASK) >> BIAS_BIAS3_PWD_IR5GTXMIX25_LSB)
-#define BIAS_BIAS3_PWD_IR5GTXMIX25_SET(x)        (((x) << BIAS_BIAS3_PWD_IR5GTXMIX25_LSB) & BIAS_BIAS3_PWD_IR5GTXMIX25_MASK)
-#define BIAS_BIAS3_PWD_IR5GAGC25_MSB             28
-#define BIAS_BIAS3_PWD_IR5GAGC25_LSB             26
-#define BIAS_BIAS3_PWD_IR5GAGC25_MASK            0x1c000000
-#define BIAS_BIAS3_PWD_IR5GAGC25_GET(x)          (((x) & BIAS_BIAS3_PWD_IR5GAGC25_MASK) >> BIAS_BIAS3_PWD_IR5GAGC25_LSB)
-#define BIAS_BIAS3_PWD_IR5GAGC25_SET(x)          (((x) << BIAS_BIAS3_PWD_IR5GAGC25_LSB) & BIAS_BIAS3_PWD_IR5GAGC25_MASK)
-#define BIAS_BIAS3_PWD_ICDAC50_MSB               25
-#define BIAS_BIAS3_PWD_ICDAC50_LSB               23
-#define BIAS_BIAS3_PWD_ICDAC50_MASK              0x03800000
-#define BIAS_BIAS3_PWD_ICDAC50_GET(x)            (((x) & BIAS_BIAS3_PWD_ICDAC50_MASK) >> BIAS_BIAS3_PWD_ICDAC50_LSB)
-#define BIAS_BIAS3_PWD_ICDAC50_SET(x)            (((x) << BIAS_BIAS3_PWD_ICDAC50_LSB) & BIAS_BIAS3_PWD_ICDAC50_MASK)
-#define BIAS_BIAS3_PWD_ICSYNTH50_MSB             22
-#define BIAS_BIAS3_PWD_ICSYNTH50_LSB             22
-#define BIAS_BIAS3_PWD_ICSYNTH50_MASK            0x00400000
-#define BIAS_BIAS3_PWD_ICSYNTH50_GET(x)          (((x) & BIAS_BIAS3_PWD_ICSYNTH50_MASK) >> BIAS_BIAS3_PWD_ICSYNTH50_LSB)
-#define BIAS_BIAS3_PWD_ICSYNTH50_SET(x)          (((x) << BIAS_BIAS3_PWD_ICSYNTH50_LSB) & BIAS_BIAS3_PWD_ICSYNTH50_MASK)
-#define BIAS_BIAS3_PWD_ICBB50_MSB                21
-#define BIAS_BIAS3_PWD_ICBB50_LSB                21
-#define BIAS_BIAS3_PWD_ICBB50_MASK               0x00200000
-#define BIAS_BIAS3_PWD_ICBB50_GET(x)             (((x) & BIAS_BIAS3_PWD_ICBB50_MASK) >> BIAS_BIAS3_PWD_ICBB50_LSB)
-#define BIAS_BIAS3_PWD_ICBB50_SET(x)             (((x) << BIAS_BIAS3_PWD_ICBB50_LSB) & BIAS_BIAS3_PWD_ICBB50_MASK)
-#define BIAS_BIAS3_PWD_IC2GDIV50_MSB             20
-#define BIAS_BIAS3_PWD_IC2GDIV50_LSB             18
-#define BIAS_BIAS3_PWD_IC2GDIV50_MASK            0x001c0000
-#define BIAS_BIAS3_PWD_IC2GDIV50_GET(x)          (((x) & BIAS_BIAS3_PWD_IC2GDIV50_MASK) >> BIAS_BIAS3_PWD_IC2GDIV50_LSB)
-#define BIAS_BIAS3_PWD_IC2GDIV50_SET(x)          (((x) << BIAS_BIAS3_PWD_IC2GDIV50_LSB) & BIAS_BIAS3_PWD_IC2GDIV50_MASK)
-#define BIAS_BIAS3_PWD_IRSYNTH50_MSB             17
-#define BIAS_BIAS3_PWD_IRSYNTH50_LSB             17
-#define BIAS_BIAS3_PWD_IRSYNTH50_MASK            0x00020000
-#define BIAS_BIAS3_PWD_IRSYNTH50_GET(x)          (((x) & BIAS_BIAS3_PWD_IRSYNTH50_MASK) >> BIAS_BIAS3_PWD_IRSYNTH50_LSB)
-#define BIAS_BIAS3_PWD_IRSYNTH50_SET(x)          (((x) << BIAS_BIAS3_PWD_IRSYNTH50_LSB) & BIAS_BIAS3_PWD_IRSYNTH50_MASK)
-#define BIAS_BIAS3_PWD_IRBB50_MSB                16
-#define BIAS_BIAS3_PWD_IRBB50_LSB                16
-#define BIAS_BIAS3_PWD_IRBB50_MASK               0x00010000
-#define BIAS_BIAS3_PWD_IRBB50_GET(x)             (((x) & BIAS_BIAS3_PWD_IRBB50_MASK) >> BIAS_BIAS3_PWD_IRBB50_LSB)
-#define BIAS_BIAS3_PWD_IRBB50_SET(x)             (((x) << BIAS_BIAS3_PWD_IRBB50_LSB) & BIAS_BIAS3_PWD_IRBB50_MASK)
-#define BIAS_BIAS3_PWD_IC25SPARE1_MSB            15
-#define BIAS_BIAS3_PWD_IC25SPARE1_LSB            13
-#define BIAS_BIAS3_PWD_IC25SPARE1_MASK           0x0000e000
-#define BIAS_BIAS3_PWD_IC25SPARE1_GET(x)         (((x) & BIAS_BIAS3_PWD_IC25SPARE1_MASK) >> BIAS_BIAS3_PWD_IC25SPARE1_LSB)
-#define BIAS_BIAS3_PWD_IC25SPARE1_SET(x)         (((x) << BIAS_BIAS3_PWD_IC25SPARE1_LSB) & BIAS_BIAS3_PWD_IC25SPARE1_MASK)
-#define BIAS_BIAS3_PWD_IC25SPARE2_MSB            12
-#define BIAS_BIAS3_PWD_IC25SPARE2_LSB            10
-#define BIAS_BIAS3_PWD_IC25SPARE2_MASK           0x00001c00
-#define BIAS_BIAS3_PWD_IC25SPARE2_GET(x)         (((x) & BIAS_BIAS3_PWD_IC25SPARE2_MASK) >> BIAS_BIAS3_PWD_IC25SPARE2_LSB)
-#define BIAS_BIAS3_PWD_IC25SPARE2_SET(x)         (((x) << BIAS_BIAS3_PWD_IC25SPARE2_LSB) & BIAS_BIAS3_PWD_IC25SPARE2_MASK)
-#define BIAS_BIAS3_PWD_IR25SPARE1_MSB            9
-#define BIAS_BIAS3_PWD_IR25SPARE1_LSB            7
-#define BIAS_BIAS3_PWD_IR25SPARE1_MASK           0x00000380
-#define BIAS_BIAS3_PWD_IR25SPARE1_GET(x)         (((x) & BIAS_BIAS3_PWD_IR25SPARE1_MASK) >> BIAS_BIAS3_PWD_IR25SPARE1_LSB)
-#define BIAS_BIAS3_PWD_IR25SPARE1_SET(x)         (((x) << BIAS_BIAS3_PWD_IR25SPARE1_LSB) & BIAS_BIAS3_PWD_IR25SPARE1_MASK)
-#define BIAS_BIAS3_PWD_IR25SPARE2_MSB            6
-#define BIAS_BIAS3_PWD_IR25SPARE2_LSB            4
-#define BIAS_BIAS3_PWD_IR25SPARE2_MASK           0x00000070
-#define BIAS_BIAS3_PWD_IR25SPARE2_GET(x)         (((x) & BIAS_BIAS3_PWD_IR25SPARE2_MASK) >> BIAS_BIAS3_PWD_IR25SPARE2_LSB)
-#define BIAS_BIAS3_PWD_IR25SPARE2_SET(x)         (((x) << BIAS_BIAS3_PWD_IR25SPARE2_LSB) & BIAS_BIAS3_PWD_IR25SPARE2_MASK)
-#define BIAS_BIAS3_PWD_ICDACREG12P5_MSB          3
-#define BIAS_BIAS3_PWD_ICDACREG12P5_LSB          1
-#define BIAS_BIAS3_PWD_ICDACREG12P5_MASK         0x0000000e
-#define BIAS_BIAS3_PWD_ICDACREG12P5_GET(x)       (((x) & BIAS_BIAS3_PWD_ICDACREG12P5_MASK) >> BIAS_BIAS3_PWD_ICDACREG12P5_LSB)
-#define BIAS_BIAS3_PWD_ICDACREG12P5_SET(x)       (((x) << BIAS_BIAS3_PWD_ICDACREG12P5_LSB) & BIAS_BIAS3_PWD_ICDACREG12P5_MASK)
-#define BIAS_BIAS3_SPARE_MSB                     0
-#define BIAS_BIAS3_SPARE_LSB                     0
-#define BIAS_BIAS3_SPARE_MASK                    0x00000001
-#define BIAS_BIAS3_SPARE_GET(x)                  (((x) & BIAS_BIAS3_SPARE_MASK) >> BIAS_BIAS3_SPARE_LSB)
-#define BIAS_BIAS3_SPARE_SET(x)                  (((x) << BIAS_BIAS3_SPARE_LSB) & BIAS_BIAS3_SPARE_MASK)
-
-#define TXPC_TXPC_ADDRESS                        0x00000048
-#define TXPC_TXPC_OFFSET                         0x00000048
-#define TXPC_TXPC_SELINTPD_MSB                   31
-#define TXPC_TXPC_SELINTPD_LSB                   31
-#define TXPC_TXPC_SELINTPD_MASK                  0x80000000
-#define TXPC_TXPC_SELINTPD_GET(x)                (((x) & TXPC_TXPC_SELINTPD_MASK) >> TXPC_TXPC_SELINTPD_LSB)
-#define TXPC_TXPC_SELINTPD_SET(x)                (((x) << TXPC_TXPC_SELINTPD_LSB) & TXPC_TXPC_SELINTPD_MASK)
-#define TXPC_TXPC_TEST_MSB                       30
-#define TXPC_TXPC_TEST_LSB                       30
-#define TXPC_TXPC_TEST_MASK                      0x40000000
-#define TXPC_TXPC_TEST_GET(x)                    (((x) & TXPC_TXPC_TEST_MASK) >> TXPC_TXPC_TEST_LSB)
-#define TXPC_TXPC_TEST_SET(x)                    (((x) << TXPC_TXPC_TEST_LSB) & TXPC_TXPC_TEST_MASK)
-#define TXPC_TXPC_TESTGAIN_MSB                   29
-#define TXPC_TXPC_TESTGAIN_LSB                   28
-#define TXPC_TXPC_TESTGAIN_MASK                  0x30000000
-#define TXPC_TXPC_TESTGAIN_GET(x)                (((x) & TXPC_TXPC_TESTGAIN_MASK) >> TXPC_TXPC_TESTGAIN_LSB)
-#define TXPC_TXPC_TESTGAIN_SET(x)                (((x) << TXPC_TXPC_TESTGAIN_LSB) & TXPC_TXPC_TESTGAIN_MASK)
-#define TXPC_TXPC_TESTDAC_MSB                    27
-#define TXPC_TXPC_TESTDAC_LSB                    22
-#define TXPC_TXPC_TESTDAC_MASK                   0x0fc00000
-#define TXPC_TXPC_TESTDAC_GET(x)                 (((x) & TXPC_TXPC_TESTDAC_MASK) >> TXPC_TXPC_TESTDAC_LSB)
-#define TXPC_TXPC_TESTDAC_SET(x)                 (((x) << TXPC_TXPC_TESTDAC_LSB) & TXPC_TXPC_TESTDAC_MASK)
-#define TXPC_TXPC_TESTPWDPC_MSB                  21
-#define TXPC_TXPC_TESTPWDPC_LSB                  21
-#define TXPC_TXPC_TESTPWDPC_MASK                 0x00200000
-#define TXPC_TXPC_TESTPWDPC_GET(x)               (((x) & TXPC_TXPC_TESTPWDPC_MASK) >> TXPC_TXPC_TESTPWDPC_LSB)
-#define TXPC_TXPC_TESTPWDPC_SET(x)               (((x) << TXPC_TXPC_TESTPWDPC_LSB) & TXPC_TXPC_TESTPWDPC_MASK)
-#define TXPC_TXPC_CURHALF_MSB                    20
-#define TXPC_TXPC_CURHALF_LSB                    20
-#define TXPC_TXPC_CURHALF_MASK                   0x00100000
-#define TXPC_TXPC_CURHALF_GET(x)                 (((x) & TXPC_TXPC_CURHALF_MASK) >> TXPC_TXPC_CURHALF_LSB)
-#define TXPC_TXPC_CURHALF_SET(x)                 (((x) << TXPC_TXPC_CURHALF_LSB) & TXPC_TXPC_CURHALF_MASK)
-#define TXPC_TXPC_NEGOUT_MSB                     19
-#define TXPC_TXPC_NEGOUT_LSB                     19
-#define TXPC_TXPC_NEGOUT_MASK                    0x00080000
-#define TXPC_TXPC_NEGOUT_GET(x)                  (((x) & TXPC_TXPC_NEGOUT_MASK) >> TXPC_TXPC_NEGOUT_LSB)
-#define TXPC_TXPC_NEGOUT_SET(x)                  (((x) << TXPC_TXPC_NEGOUT_LSB) & TXPC_TXPC_NEGOUT_MASK)
-#define TXPC_TXPC_CLKDELAY_MSB                   18
-#define TXPC_TXPC_CLKDELAY_LSB                   18
-#define TXPC_TXPC_CLKDELAY_MASK                  0x00040000
-#define TXPC_TXPC_CLKDELAY_GET(x)                (((x) & TXPC_TXPC_CLKDELAY_MASK) >> TXPC_TXPC_CLKDELAY_LSB)
-#define TXPC_TXPC_CLKDELAY_SET(x)                (((x) << TXPC_TXPC_CLKDELAY_LSB) & TXPC_TXPC_CLKDELAY_MASK)
-#define TXPC_TXPC_SELMODREF_MSB                  17
-#define TXPC_TXPC_SELMODREF_LSB                  17
-#define TXPC_TXPC_SELMODREF_MASK                 0x00020000
-#define TXPC_TXPC_SELMODREF_GET(x)               (((x) & TXPC_TXPC_SELMODREF_MASK) >> TXPC_TXPC_SELMODREF_LSB)
-#define TXPC_TXPC_SELMODREF_SET(x)               (((x) << TXPC_TXPC_SELMODREF_LSB) & TXPC_TXPC_SELMODREF_MASK)
-#define TXPC_TXPC_SELCMOUT_MSB                   16
-#define TXPC_TXPC_SELCMOUT_LSB                   16
-#define TXPC_TXPC_SELCMOUT_MASK                  0x00010000
-#define TXPC_TXPC_SELCMOUT_GET(x)                (((x) & TXPC_TXPC_SELCMOUT_MASK) >> TXPC_TXPC_SELCMOUT_LSB)
-#define TXPC_TXPC_SELCMOUT_SET(x)                (((x) << TXPC_TXPC_SELCMOUT_LSB) & TXPC_TXPC_SELCMOUT_MASK)
-#define TXPC_TXPC_TSMODE_MSB                     15
-#define TXPC_TXPC_TSMODE_LSB                     14
-#define TXPC_TXPC_TSMODE_MASK                    0x0000c000
-#define TXPC_TXPC_TSMODE_GET(x)                  (((x) & TXPC_TXPC_TSMODE_MASK) >> TXPC_TXPC_TSMODE_LSB)
-#define TXPC_TXPC_TSMODE_SET(x)                  (((x) << TXPC_TXPC_TSMODE_LSB) & TXPC_TXPC_TSMODE_MASK)
-#define TXPC_TXPC_N_MSB                          13
-#define TXPC_TXPC_N_LSB                          6
-#define TXPC_TXPC_N_MASK                         0x00003fc0
-#define TXPC_TXPC_N_GET(x)                       (((x) & TXPC_TXPC_N_MASK) >> TXPC_TXPC_N_LSB)
-#define TXPC_TXPC_N_SET(x)                       (((x) << TXPC_TXPC_N_LSB) & TXPC_TXPC_N_MASK)
-#define TXPC_TXPC_ON1STSYNTHON_MSB               5
-#define TXPC_TXPC_ON1STSYNTHON_LSB               5
-#define TXPC_TXPC_ON1STSYNTHON_MASK              0x00000020
-#define TXPC_TXPC_ON1STSYNTHON_GET(x)            (((x) & TXPC_TXPC_ON1STSYNTHON_MASK) >> TXPC_TXPC_ON1STSYNTHON_LSB)
-#define TXPC_TXPC_ON1STSYNTHON_SET(x)            (((x) << TXPC_TXPC_ON1STSYNTHON_LSB) & TXPC_TXPC_ON1STSYNTHON_MASK)
-#define TXPC_TXPC_SELINIT_MSB                    4
-#define TXPC_TXPC_SELINIT_LSB                    3
-#define TXPC_TXPC_SELINIT_MASK                   0x00000018
-#define TXPC_TXPC_SELINIT_GET(x)                 (((x) & TXPC_TXPC_SELINIT_MASK) >> TXPC_TXPC_SELINIT_LSB)
-#define TXPC_TXPC_SELINIT_SET(x)                 (((x) << TXPC_TXPC_SELINIT_LSB) & TXPC_TXPC_SELINIT_MASK)
-#define TXPC_TXPC_SELCOUNT_MSB                   2
-#define TXPC_TXPC_SELCOUNT_LSB                   2
-#define TXPC_TXPC_SELCOUNT_MASK                  0x00000004
-#define TXPC_TXPC_SELCOUNT_GET(x)                (((x) & TXPC_TXPC_SELCOUNT_MASK) >> TXPC_TXPC_SELCOUNT_LSB)
-#define TXPC_TXPC_SELCOUNT_SET(x)                (((x) << TXPC_TXPC_SELCOUNT_LSB) & TXPC_TXPC_SELCOUNT_MASK)
-#define TXPC_TXPC_ATBSEL_MSB                     1
-#define TXPC_TXPC_ATBSEL_LSB                     0
-#define TXPC_TXPC_ATBSEL_MASK                    0x00000003
-#define TXPC_TXPC_ATBSEL_GET(x)                  (((x) & TXPC_TXPC_ATBSEL_MASK) >> TXPC_TXPC_ATBSEL_LSB)
-#define TXPC_TXPC_ATBSEL_SET(x)                  (((x) << TXPC_TXPC_ATBSEL_LSB) & TXPC_TXPC_ATBSEL_MASK)
-
-#define TXPC_MISC_ADDRESS                        0x0000004c
-#define TXPC_MISC_OFFSET                         0x0000004c
-#define TXPC_MISC_FLIPBMODE_MSB                  31
-#define TXPC_MISC_FLIPBMODE_LSB                  31
-#define TXPC_MISC_FLIPBMODE_MASK                 0x80000000
-#define TXPC_MISC_FLIPBMODE_GET(x)               (((x) & TXPC_MISC_FLIPBMODE_MASK) >> TXPC_MISC_FLIPBMODE_LSB)
-#define TXPC_MISC_FLIPBMODE_SET(x)               (((x) << TXPC_MISC_FLIPBMODE_LSB) & TXPC_MISC_FLIPBMODE_MASK)
-#define TXPC_MISC_LEVEL_MSB                      30
-#define TXPC_MISC_LEVEL_LSB                      29
-#define TXPC_MISC_LEVEL_MASK                     0x60000000
-#define TXPC_MISC_LEVEL_GET(x)                   (((x) & TXPC_MISC_LEVEL_MASK) >> TXPC_MISC_LEVEL_LSB)
-#define TXPC_MISC_LEVEL_SET(x)                   (((x) << TXPC_MISC_LEVEL_LSB) & TXPC_MISC_LEVEL_MASK)
-#define TXPC_MISC_LDO_TEST_MODE_MSB              28
-#define TXPC_MISC_LDO_TEST_MODE_LSB              28
-#define TXPC_MISC_LDO_TEST_MODE_MASK             0x10000000
-#define TXPC_MISC_LDO_TEST_MODE_GET(x)           (((x) & TXPC_MISC_LDO_TEST_MODE_MASK) >> TXPC_MISC_LDO_TEST_MODE_LSB)
-#define TXPC_MISC_LDO_TEST_MODE_SET(x)           (((x) << TXPC_MISC_LDO_TEST_MODE_LSB) & TXPC_MISC_LDO_TEST_MODE_MASK)
-#define TXPC_MISC_NOTCXODET_MSB                  27
-#define TXPC_MISC_NOTCXODET_LSB                  27
-#define TXPC_MISC_NOTCXODET_MASK                 0x08000000
-#define TXPC_MISC_NOTCXODET_GET(x)               (((x) & TXPC_MISC_NOTCXODET_MASK) >> TXPC_MISC_NOTCXODET_LSB)
-#define TXPC_MISC_NOTCXODET_SET(x)               (((x) << TXPC_MISC_NOTCXODET_LSB) & TXPC_MISC_NOTCXODET_MASK)
-#define TXPC_MISC_PWDCLKIND_MSB                  26
-#define TXPC_MISC_PWDCLKIND_LSB                  26
-#define TXPC_MISC_PWDCLKIND_MASK                 0x04000000
-#define TXPC_MISC_PWDCLKIND_GET(x)               (((x) & TXPC_MISC_PWDCLKIND_MASK) >> TXPC_MISC_PWDCLKIND_LSB)
-#define TXPC_MISC_PWDCLKIND_SET(x)               (((x) << TXPC_MISC_PWDCLKIND_LSB) & TXPC_MISC_PWDCLKIND_MASK)
-#define TXPC_MISC_PWDXINPAD_MSB                  25
-#define TXPC_MISC_PWDXINPAD_LSB                  25
-#define TXPC_MISC_PWDXINPAD_MASK                 0x02000000
-#define TXPC_MISC_PWDXINPAD_GET(x)               (((x) & TXPC_MISC_PWDXINPAD_MASK) >> TXPC_MISC_PWDXINPAD_LSB)
-#define TXPC_MISC_PWDXINPAD_SET(x)               (((x) << TXPC_MISC_PWDXINPAD_LSB) & TXPC_MISC_PWDXINPAD_MASK)
-#define TXPC_MISC_LOCALBIAS_MSB                  24
-#define TXPC_MISC_LOCALBIAS_LSB                  24
-#define TXPC_MISC_LOCALBIAS_MASK                 0x01000000
-#define TXPC_MISC_LOCALBIAS_GET(x)               (((x) & TXPC_MISC_LOCALBIAS_MASK) >> TXPC_MISC_LOCALBIAS_LSB)
-#define TXPC_MISC_LOCALBIAS_SET(x)               (((x) << TXPC_MISC_LOCALBIAS_LSB) & TXPC_MISC_LOCALBIAS_MASK)
-#define TXPC_MISC_LOCALBIAS2X_MSB                23
-#define TXPC_MISC_LOCALBIAS2X_LSB                23
-#define TXPC_MISC_LOCALBIAS2X_MASK               0x00800000
-#define TXPC_MISC_LOCALBIAS2X_GET(x)             (((x) & TXPC_MISC_LOCALBIAS2X_MASK) >> TXPC_MISC_LOCALBIAS2X_LSB)
-#define TXPC_MISC_LOCALBIAS2X_SET(x)             (((x) << TXPC_MISC_LOCALBIAS2X_LSB) & TXPC_MISC_LOCALBIAS2X_MASK)
-#define TXPC_MISC_SELTSP_MSB                     22
-#define TXPC_MISC_SELTSP_LSB                     22
-#define TXPC_MISC_SELTSP_MASK                    0x00400000
-#define TXPC_MISC_SELTSP_GET(x)                  (((x) & TXPC_MISC_SELTSP_MASK) >> TXPC_MISC_SELTSP_LSB)
-#define TXPC_MISC_SELTSP_SET(x)                  (((x) << TXPC_MISC_SELTSP_LSB) & TXPC_MISC_SELTSP_MASK)
-#define TXPC_MISC_SELTSN_MSB                     21
-#define TXPC_MISC_SELTSN_LSB                     21
-#define TXPC_MISC_SELTSN_MASK                    0x00200000
-#define TXPC_MISC_SELTSN_GET(x)                  (((x) & TXPC_MISC_SELTSN_MASK) >> TXPC_MISC_SELTSN_LSB)
-#define TXPC_MISC_SELTSN_SET(x)                  (((x) << TXPC_MISC_SELTSN_LSB) & TXPC_MISC_SELTSN_MASK)
-#define TXPC_MISC_SPARE_A_MSB                    20
-#define TXPC_MISC_SPARE_A_LSB                    18
-#define TXPC_MISC_SPARE_A_MASK                   0x001c0000
-#define TXPC_MISC_SPARE_A_GET(x)                 (((x) & TXPC_MISC_SPARE_A_MASK) >> TXPC_MISC_SPARE_A_LSB)
-#define TXPC_MISC_SPARE_A_SET(x)                 (((x) << TXPC_MISC_SPARE_A_LSB) & TXPC_MISC_SPARE_A_MASK)
-#define TXPC_MISC_DECOUT_MSB                     17
-#define TXPC_MISC_DECOUT_LSB                     8
-#define TXPC_MISC_DECOUT_MASK                    0x0003ff00
-#define TXPC_MISC_DECOUT_GET(x)                  (((x) & TXPC_MISC_DECOUT_MASK) >> TXPC_MISC_DECOUT_LSB)
-#define TXPC_MISC_DECOUT_SET(x)                  (((x) << TXPC_MISC_DECOUT_LSB) & TXPC_MISC_DECOUT_MASK)
-#define TXPC_MISC_XTALDIV_MSB                    7
-#define TXPC_MISC_XTALDIV_LSB                    6
-#define TXPC_MISC_XTALDIV_MASK                   0x000000c0
-#define TXPC_MISC_XTALDIV_GET(x)                 (((x) & TXPC_MISC_XTALDIV_MASK) >> TXPC_MISC_XTALDIV_LSB)
-#define TXPC_MISC_XTALDIV_SET(x)                 (((x) << TXPC_MISC_XTALDIV_LSB) & TXPC_MISC_XTALDIV_MASK)
-#define TXPC_MISC_SPARE_MSB                      5
-#define TXPC_MISC_SPARE_LSB                      0
-#define TXPC_MISC_SPARE_MASK                     0x0000003f
-#define TXPC_MISC_SPARE_GET(x)                   (((x) & TXPC_MISC_SPARE_MASK) >> TXPC_MISC_SPARE_LSB)
-#define TXPC_MISC_SPARE_SET(x)                   (((x) << TXPC_MISC_SPARE_LSB) & TXPC_MISC_SPARE_MASK)
-
-#define RXTXBB_RXTXBB1_ADDRESS                   0x00000050
-#define RXTXBB_RXTXBB1_OFFSET                    0x00000050
-#define RXTXBB_RXTXBB1_SPARE_MSB                 31
-#define RXTXBB_RXTXBB1_SPARE_LSB                 19
-#define RXTXBB_RXTXBB1_SPARE_MASK                0xfff80000
-#define RXTXBB_RXTXBB1_SPARE_GET(x)              (((x) & RXTXBB_RXTXBB1_SPARE_MASK) >> RXTXBB_RXTXBB1_SPARE_LSB)
-#define RXTXBB_RXTXBB1_SPARE_SET(x)              (((x) << RXTXBB_RXTXBB1_SPARE_LSB) & RXTXBB_RXTXBB1_SPARE_MASK)
-#define RXTXBB_RXTXBB1_FNOTCH_MSB                18
-#define RXTXBB_RXTXBB1_FNOTCH_LSB                17
-#define RXTXBB_RXTXBB1_FNOTCH_MASK               0x00060000
-#define RXTXBB_RXTXBB1_FNOTCH_GET(x)             (((x) & RXTXBB_RXTXBB1_FNOTCH_MASK) >> RXTXBB_RXTXBB1_FNOTCH_LSB)
-#define RXTXBB_RXTXBB1_FNOTCH_SET(x)             (((x) << RXTXBB_RXTXBB1_FNOTCH_LSB) & RXTXBB_RXTXBB1_FNOTCH_MASK)
-#define RXTXBB_RXTXBB1_SEL_ATB_MSB               16
-#define RXTXBB_RXTXBB1_SEL_ATB_LSB               9
-#define RXTXBB_RXTXBB1_SEL_ATB_MASK              0x0001fe00
-#define RXTXBB_RXTXBB1_SEL_ATB_GET(x)            (((x) & RXTXBB_RXTXBB1_SEL_ATB_MASK) >> RXTXBB_RXTXBB1_SEL_ATB_LSB)
-#define RXTXBB_RXTXBB1_SEL_ATB_SET(x)            (((x) << RXTXBB_RXTXBB1_SEL_ATB_LSB) & RXTXBB_RXTXBB1_SEL_ATB_MASK)
-#define RXTXBB_RXTXBB1_PDDACINTERFACE_MSB        8
-#define RXTXBB_RXTXBB1_PDDACINTERFACE_LSB        8
-#define RXTXBB_RXTXBB1_PDDACINTERFACE_MASK       0x00000100
-#define RXTXBB_RXTXBB1_PDDACINTERFACE_GET(x)     (((x) & RXTXBB_RXTXBB1_PDDACINTERFACE_MASK) >> RXTXBB_RXTXBB1_PDDACINTERFACE_LSB)
-#define RXTXBB_RXTXBB1_PDDACINTERFACE_SET(x)     (((x) << RXTXBB_RXTXBB1_PDDACINTERFACE_LSB) & RXTXBB_RXTXBB1_PDDACINTERFACE_MASK)
-#define RXTXBB_RXTXBB1_PDV2I_MSB                 7
-#define RXTXBB_RXTXBB1_PDV2I_LSB                 7
-#define RXTXBB_RXTXBB1_PDV2I_MASK                0x00000080
-#define RXTXBB_RXTXBB1_PDV2I_GET(x)              (((x) & RXTXBB_RXTXBB1_PDV2I_MASK) >> RXTXBB_RXTXBB1_PDV2I_LSB)
-#define RXTXBB_RXTXBB1_PDV2I_SET(x)              (((x) << RXTXBB_RXTXBB1_PDV2I_LSB) & RXTXBB_RXTXBB1_PDV2I_MASK)
-#define RXTXBB_RXTXBB1_PDI2V_MSB                 6
-#define RXTXBB_RXTXBB1_PDI2V_LSB                 6
-#define RXTXBB_RXTXBB1_PDI2V_MASK                0x00000040
-#define RXTXBB_RXTXBB1_PDI2V_GET(x)              (((x) & RXTXBB_RXTXBB1_PDI2V_MASK) >> RXTXBB_RXTXBB1_PDI2V_LSB)
-#define RXTXBB_RXTXBB1_PDI2V_SET(x)              (((x) << RXTXBB_RXTXBB1_PDI2V_LSB) & RXTXBB_RXTXBB1_PDI2V_MASK)
-#define RXTXBB_RXTXBB1_PDRXTXBB_MSB              5
-#define RXTXBB_RXTXBB1_PDRXTXBB_LSB              5
-#define RXTXBB_RXTXBB1_PDRXTXBB_MASK             0x00000020
-#define RXTXBB_RXTXBB1_PDRXTXBB_GET(x)           (((x) & RXTXBB_RXTXBB1_PDRXTXBB_MASK) >> RXTXBB_RXTXBB1_PDRXTXBB_LSB)
-#define RXTXBB_RXTXBB1_PDRXTXBB_SET(x)           (((x) << RXTXBB_RXTXBB1_PDRXTXBB_LSB) & RXTXBB_RXTXBB1_PDRXTXBB_MASK)
-#define RXTXBB_RXTXBB1_PDOFFSETLOQ_MSB           4
-#define RXTXBB_RXTXBB1_PDOFFSETLOQ_LSB           4
-#define RXTXBB_RXTXBB1_PDOFFSETLOQ_MASK          0x00000010
-#define RXTXBB_RXTXBB1_PDOFFSETLOQ_GET(x)        (((x) & RXTXBB_RXTXBB1_PDOFFSETLOQ_MASK) >> RXTXBB_RXTXBB1_PDOFFSETLOQ_LSB)
-#define RXTXBB_RXTXBB1_PDOFFSETLOQ_SET(x)        (((x) << RXTXBB_RXTXBB1_PDOFFSETLOQ_LSB) & RXTXBB_RXTXBB1_PDOFFSETLOQ_MASK)
-#define RXTXBB_RXTXBB1_PDOFFSETHIQ_MSB           3
-#define RXTXBB_RXTXBB1_PDOFFSETHIQ_LSB           3
-#define RXTXBB_RXTXBB1_PDOFFSETHIQ_MASK          0x00000008
-#define RXTXBB_RXTXBB1_PDOFFSETHIQ_GET(x)        (((x) & RXTXBB_RXTXBB1_PDOFFSETHIQ_MASK) >> RXTXBB_RXTXBB1_PDOFFSETHIQ_LSB)
-#define RXTXBB_RXTXBB1_PDOFFSETHIQ_SET(x)        (((x) << RXTXBB_RXTXBB1_PDOFFSETHIQ_LSB) & RXTXBB_RXTXBB1_PDOFFSETHIQ_MASK)
-#define RXTXBB_RXTXBB1_PDOFFSETI2V_MSB           2
-#define RXTXBB_RXTXBB1_PDOFFSETI2V_LSB           2
-#define RXTXBB_RXTXBB1_PDOFFSETI2V_MASK          0x00000004
-#define RXTXBB_RXTXBB1_PDOFFSETI2V_GET(x)        (((x) & RXTXBB_RXTXBB1_PDOFFSETI2V_MASK) >> RXTXBB_RXTXBB1_PDOFFSETI2V_LSB)
-#define RXTXBB_RXTXBB1_PDOFFSETI2V_SET(x)        (((x) << RXTXBB_RXTXBB1_PDOFFSETI2V_LSB) & RXTXBB_RXTXBB1_PDOFFSETI2V_MASK)
-#define RXTXBB_RXTXBB1_PDLOQ_MSB                 1
-#define RXTXBB_RXTXBB1_PDLOQ_LSB                 1
-#define RXTXBB_RXTXBB1_PDLOQ_MASK                0x00000002
-#define RXTXBB_RXTXBB1_PDLOQ_GET(x)              (((x) & RXTXBB_RXTXBB1_PDLOQ_MASK) >> RXTXBB_RXTXBB1_PDLOQ_LSB)
-#define RXTXBB_RXTXBB1_PDLOQ_SET(x)              (((x) << RXTXBB_RXTXBB1_PDLOQ_LSB) & RXTXBB_RXTXBB1_PDLOQ_MASK)
-#define RXTXBB_RXTXBB1_PDHIQ_MSB                 0
-#define RXTXBB_RXTXBB1_PDHIQ_LSB                 0
-#define RXTXBB_RXTXBB1_PDHIQ_MASK                0x00000001
-#define RXTXBB_RXTXBB1_PDHIQ_GET(x)              (((x) & RXTXBB_RXTXBB1_PDHIQ_MASK) >> RXTXBB_RXTXBB1_PDHIQ_LSB)
-#define RXTXBB_RXTXBB1_PDHIQ_SET(x)              (((x) << RXTXBB_RXTXBB1_PDHIQ_LSB) & RXTXBB_RXTXBB1_PDHIQ_MASK)
-
-#define RXTXBB_RXTXBB2_ADDRESS                   0x00000054
-#define RXTXBB_RXTXBB2_OFFSET                    0x00000054
-#define RXTXBB_RXTXBB2_IBN_37P5_OSHI_CTRL_MSB    31
-#define RXTXBB_RXTXBB2_IBN_37P5_OSHI_CTRL_LSB    29
-#define RXTXBB_RXTXBB2_IBN_37P5_OSHI_CTRL_MASK   0xe0000000
-#define RXTXBB_RXTXBB2_IBN_37P5_OSHI_CTRL_GET(x) (((x) & RXTXBB_RXTXBB2_IBN_37P5_OSHI_CTRL_MASK) >> RXTXBB_RXTXBB2_IBN_37P5_OSHI_CTRL_LSB)
-#define RXTXBB_RXTXBB2_IBN_37P5_OSHI_CTRL_SET(x) (((x) << RXTXBB_RXTXBB2_IBN_37P5_OSHI_CTRL_LSB) & RXTXBB_RXTXBB2_IBN_37P5_OSHI_CTRL_MASK)
-#define RXTXBB_RXTXBB2_IBN_37P5_OSLO_CTRL_MSB    28
-#define RXTXBB_RXTXBB2_IBN_37P5_OSLO_CTRL_LSB    26
-#define RXTXBB_RXTXBB2_IBN_37P5_OSLO_CTRL_MASK   0x1c000000
-#define RXTXBB_RXTXBB2_IBN_37P5_OSLO_CTRL_GET(x) (((x) & RXTXBB_RXTXBB2_IBN_37P5_OSLO_CTRL_MASK) >> RXTXBB_RXTXBB2_IBN_37P5_OSLO_CTRL_LSB)
-#define RXTXBB_RXTXBB2_IBN_37P5_OSLO_CTRL_SET(x) (((x) << RXTXBB_RXTXBB2_IBN_37P5_OSLO_CTRL_LSB) & RXTXBB_RXTXBB2_IBN_37P5_OSLO_CTRL_MASK)
-#define RXTXBB_RXTXBB2_IBN_37P5_OSI2V_CTRL_MSB   25
-#define RXTXBB_RXTXBB2_IBN_37P5_OSI2V_CTRL_LSB   23
-#define RXTXBB_RXTXBB2_IBN_37P5_OSI2V_CTRL_MASK  0x03800000
-#define RXTXBB_RXTXBB2_IBN_37P5_OSI2V_CTRL_GET(x) (((x) & RXTXBB_RXTXBB2_IBN_37P5_OSI2V_CTRL_MASK) >> RXTXBB_RXTXBB2_IBN_37P5_OSI2V_CTRL_LSB)
-#define RXTXBB_RXTXBB2_IBN_37P5_OSI2V_CTRL_SET(x) (((x) << RXTXBB_RXTXBB2_IBN_37P5_OSI2V_CTRL_LSB) & RXTXBB_RXTXBB2_IBN_37P5_OSI2V_CTRL_MASK)
-#define RXTXBB_RXTXBB2_SPARE_MSB                 22
-#define RXTXBB_RXTXBB2_SPARE_LSB                 21
-#define RXTXBB_RXTXBB2_SPARE_MASK                0x00600000
-#define RXTXBB_RXTXBB2_SPARE_GET(x)              (((x) & RXTXBB_RXTXBB2_SPARE_MASK) >> RXTXBB_RXTXBB2_SPARE_LSB)
-#define RXTXBB_RXTXBB2_SPARE_SET(x)              (((x) << RXTXBB_RXTXBB2_SPARE_LSB) & RXTXBB_RXTXBB2_SPARE_MASK)
-#define RXTXBB_RXTXBB2_SHORTBUFFER_MSB           20
-#define RXTXBB_RXTXBB2_SHORTBUFFER_LSB           20
-#define RXTXBB_RXTXBB2_SHORTBUFFER_MASK          0x00100000
-#define RXTXBB_RXTXBB2_SHORTBUFFER_GET(x)        (((x) & RXTXBB_RXTXBB2_SHORTBUFFER_MASK) >> RXTXBB_RXTXBB2_SHORTBUFFER_LSB)
-#define RXTXBB_RXTXBB2_SHORTBUFFER_SET(x)        (((x) << RXTXBB_RXTXBB2_SHORTBUFFER_LSB) & RXTXBB_RXTXBB2_SHORTBUFFER_MASK)
-#define RXTXBB_RXTXBB2_SELBUFFER_MSB             19
-#define RXTXBB_RXTXBB2_SELBUFFER_LSB             19
-#define RXTXBB_RXTXBB2_SELBUFFER_MASK            0x00080000
-#define RXTXBB_RXTXBB2_SELBUFFER_GET(x)          (((x) & RXTXBB_RXTXBB2_SELBUFFER_MASK) >> RXTXBB_RXTXBB2_SELBUFFER_LSB)
-#define RXTXBB_RXTXBB2_SELBUFFER_SET(x)          (((x) << RXTXBB_RXTXBB2_SELBUFFER_LSB) & RXTXBB_RXTXBB2_SELBUFFER_MASK)
-#define RXTXBB_RXTXBB2_SEL_DAC_TEST_MSB          18
-#define RXTXBB_RXTXBB2_SEL_DAC_TEST_LSB          18
-#define RXTXBB_RXTXBB2_SEL_DAC_TEST_MASK         0x00040000
-#define RXTXBB_RXTXBB2_SEL_DAC_TEST_GET(x)       (((x) & RXTXBB_RXTXBB2_SEL_DAC_TEST_MASK) >> RXTXBB_RXTXBB2_SEL_DAC_TEST_LSB)
-#define RXTXBB_RXTXBB2_SEL_DAC_TEST_SET(x)       (((x) << RXTXBB_RXTXBB2_SEL_DAC_TEST_LSB) & RXTXBB_RXTXBB2_SEL_DAC_TEST_MASK)
-#define RXTXBB_RXTXBB2_SEL_LOQ_TEST_MSB          17
-#define RXTXBB_RXTXBB2_SEL_LOQ_TEST_LSB          17
-#define RXTXBB_RXTXBB2_SEL_LOQ_TEST_MASK         0x00020000
-#define RXTXBB_RXTXBB2_SEL_LOQ_TEST_GET(x)       (((x) & RXTXBB_RXTXBB2_SEL_LOQ_TEST_MASK) >> RXTXBB_RXTXBB2_SEL_LOQ_TEST_LSB)
-#define RXTXBB_RXTXBB2_SEL_LOQ_TEST_SET(x)       (((x) << RXTXBB_RXTXBB2_SEL_LOQ_TEST_LSB) & RXTXBB_RXTXBB2_SEL_LOQ_TEST_MASK)
-#define RXTXBB_RXTXBB2_SEL_HIQ_TEST_MSB          16
-#define RXTXBB_RXTXBB2_SEL_HIQ_TEST_LSB          16
-#define RXTXBB_RXTXBB2_SEL_HIQ_TEST_MASK         0x00010000
-#define RXTXBB_RXTXBB2_SEL_HIQ_TEST_GET(x)       (((x) & RXTXBB_RXTXBB2_SEL_HIQ_TEST_MASK) >> RXTXBB_RXTXBB2_SEL_HIQ_TEST_LSB)
-#define RXTXBB_RXTXBB2_SEL_HIQ_TEST_SET(x)       (((x) << RXTXBB_RXTXBB2_SEL_HIQ_TEST_LSB) & RXTXBB_RXTXBB2_SEL_HIQ_TEST_MASK)
-#define RXTXBB_RXTXBB2_SEL_I2V_TEST_MSB          15
-#define RXTXBB_RXTXBB2_SEL_I2V_TEST_LSB          15
-#define RXTXBB_RXTXBB2_SEL_I2V_TEST_MASK         0x00008000
-#define RXTXBB_RXTXBB2_SEL_I2V_TEST_GET(x)       (((x) & RXTXBB_RXTXBB2_SEL_I2V_TEST_MASK) >> RXTXBB_RXTXBB2_SEL_I2V_TEST_LSB)
-#define RXTXBB_RXTXBB2_SEL_I2V_TEST_SET(x)       (((x) << RXTXBB_RXTXBB2_SEL_I2V_TEST_LSB) & RXTXBB_RXTXBB2_SEL_I2V_TEST_MASK)
-#define RXTXBB_RXTXBB2_CMSEL_MSB                 14
-#define RXTXBB_RXTXBB2_CMSEL_LSB                 13
-#define RXTXBB_RXTXBB2_CMSEL_MASK                0x00006000
-#define RXTXBB_RXTXBB2_CMSEL_GET(x)              (((x) & RXTXBB_RXTXBB2_CMSEL_MASK) >> RXTXBB_RXTXBB2_CMSEL_LSB)
-#define RXTXBB_RXTXBB2_CMSEL_SET(x)              (((x) << RXTXBB_RXTXBB2_CMSEL_LSB) & RXTXBB_RXTXBB2_CMSEL_MASK)
-#define RXTXBB_RXTXBB2_FILTERFC_MSB              12
-#define RXTXBB_RXTXBB2_FILTERFC_LSB              8
-#define RXTXBB_RXTXBB2_FILTERFC_MASK             0x00001f00
-#define RXTXBB_RXTXBB2_FILTERFC_GET(x)           (((x) & RXTXBB_RXTXBB2_FILTERFC_MASK) >> RXTXBB_RXTXBB2_FILTERFC_LSB)
-#define RXTXBB_RXTXBB2_FILTERFC_SET(x)           (((x) << RXTXBB_RXTXBB2_FILTERFC_LSB) & RXTXBB_RXTXBB2_FILTERFC_MASK)
-#define RXTXBB_RXTXBB2_LOCALFILTERTUNING_MSB     7
-#define RXTXBB_RXTXBB2_LOCALFILTERTUNING_LSB     7
-#define RXTXBB_RXTXBB2_LOCALFILTERTUNING_MASK    0x00000080
-#define RXTXBB_RXTXBB2_LOCALFILTERTUNING_GET(x)  (((x) & RXTXBB_RXTXBB2_LOCALFILTERTUNING_MASK) >> RXTXBB_RXTXBB2_LOCALFILTERTUNING_LSB)
-#define RXTXBB_RXTXBB2_LOCALFILTERTUNING_SET(x)  (((x) << RXTXBB_RXTXBB2_LOCALFILTERTUNING_LSB) & RXTXBB_RXTXBB2_LOCALFILTERTUNING_MASK)
-#define RXTXBB_RXTXBB2_FILTERDOUBLEBW_MSB        6
-#define RXTXBB_RXTXBB2_FILTERDOUBLEBW_LSB        6
-#define RXTXBB_RXTXBB2_FILTERDOUBLEBW_MASK       0x00000040
-#define RXTXBB_RXTXBB2_FILTERDOUBLEBW_GET(x)     (((x) & RXTXBB_RXTXBB2_FILTERDOUBLEBW_MASK) >> RXTXBB_RXTXBB2_FILTERDOUBLEBW_LSB)
-#define RXTXBB_RXTXBB2_FILTERDOUBLEBW_SET(x)     (((x) << RXTXBB_RXTXBB2_FILTERDOUBLEBW_LSB) & RXTXBB_RXTXBB2_FILTERDOUBLEBW_MASK)
-#define RXTXBB_RXTXBB2_PATH2HIQ_EN_MSB           5
-#define RXTXBB_RXTXBB2_PATH2HIQ_EN_LSB           5
-#define RXTXBB_RXTXBB2_PATH2HIQ_EN_MASK          0x00000020
-#define RXTXBB_RXTXBB2_PATH2HIQ_EN_GET(x)        (((x) & RXTXBB_RXTXBB2_PATH2HIQ_EN_MASK) >> RXTXBB_RXTXBB2_PATH2HIQ_EN_LSB)
-#define RXTXBB_RXTXBB2_PATH2HIQ_EN_SET(x)        (((x) << RXTXBB_RXTXBB2_PATH2HIQ_EN_LSB) & RXTXBB_RXTXBB2_PATH2HIQ_EN_MASK)
-#define RXTXBB_RXTXBB2_PATH1HIQ_EN_MSB           4
-#define RXTXBB_RXTXBB2_PATH1HIQ_EN_LSB           4
-#define RXTXBB_RXTXBB2_PATH1HIQ_EN_MASK          0x00000010
-#define RXTXBB_RXTXBB2_PATH1HIQ_EN_GET(x)        (((x) & RXTXBB_RXTXBB2_PATH1HIQ_EN_MASK) >> RXTXBB_RXTXBB2_PATH1HIQ_EN_LSB)
-#define RXTXBB_RXTXBB2_PATH1HIQ_EN_SET(x)        (((x) << RXTXBB_RXTXBB2_PATH1HIQ_EN_LSB) & RXTXBB_RXTXBB2_PATH1HIQ_EN_MASK)
-#define RXTXBB_RXTXBB2_PATH3LOQ_EN_MSB           3
-#define RXTXBB_RXTXBB2_PATH3LOQ_EN_LSB           3
-#define RXTXBB_RXTXBB2_PATH3LOQ_EN_MASK          0x00000008
-#define RXTXBB_RXTXBB2_PATH3LOQ_EN_GET(x)        (((x) & RXTXBB_RXTXBB2_PATH3LOQ_EN_MASK) >> RXTXBB_RXTXBB2_PATH3LOQ_EN_LSB)
-#define RXTXBB_RXTXBB2_PATH3LOQ_EN_SET(x)        (((x) << RXTXBB_RXTXBB2_PATH3LOQ_EN_LSB) & RXTXBB_RXTXBB2_PATH3LOQ_EN_MASK)
-#define RXTXBB_RXTXBB2_PATH2LOQ_EN_MSB           2
-#define RXTXBB_RXTXBB2_PATH2LOQ_EN_LSB           2
-#define RXTXBB_RXTXBB2_PATH2LOQ_EN_MASK          0x00000004
-#define RXTXBB_RXTXBB2_PATH2LOQ_EN_GET(x)        (((x) & RXTXBB_RXTXBB2_PATH2LOQ_EN_MASK) >> RXTXBB_RXTXBB2_PATH2LOQ_EN_LSB)
-#define RXTXBB_RXTXBB2_PATH2LOQ_EN_SET(x)        (((x) << RXTXBB_RXTXBB2_PATH2LOQ_EN_LSB) & RXTXBB_RXTXBB2_PATH2LOQ_EN_MASK)
-#define RXTXBB_RXTXBB2_PATH1LOQ_EN_MSB           1
-#define RXTXBB_RXTXBB2_PATH1LOQ_EN_LSB           1
-#define RXTXBB_RXTXBB2_PATH1LOQ_EN_MASK          0x00000002
-#define RXTXBB_RXTXBB2_PATH1LOQ_EN_GET(x)        (((x) & RXTXBB_RXTXBB2_PATH1LOQ_EN_MASK) >> RXTXBB_RXTXBB2_PATH1LOQ_EN_LSB)
-#define RXTXBB_RXTXBB2_PATH1LOQ_EN_SET(x)        (((x) << RXTXBB_RXTXBB2_PATH1LOQ_EN_LSB) & RXTXBB_RXTXBB2_PATH1LOQ_EN_MASK)
-#define RXTXBB_RXTXBB2_PATH_OVERRIDE_MSB         0
-#define RXTXBB_RXTXBB2_PATH_OVERRIDE_LSB         0
-#define RXTXBB_RXTXBB2_PATH_OVERRIDE_MASK        0x00000001
-#define RXTXBB_RXTXBB2_PATH_OVERRIDE_GET(x)      (((x) & RXTXBB_RXTXBB2_PATH_OVERRIDE_MASK) >> RXTXBB_RXTXBB2_PATH_OVERRIDE_LSB)
-#define RXTXBB_RXTXBB2_PATH_OVERRIDE_SET(x)      (((x) << RXTXBB_RXTXBB2_PATH_OVERRIDE_LSB) & RXTXBB_RXTXBB2_PATH_OVERRIDE_MASK)
-
-#define RXTXBB_RXTXBB3_ADDRESS                   0x00000058
-#define RXTXBB_RXTXBB3_OFFSET                    0x00000058
-#define RXTXBB_RXTXBB3_SPARE_MSB                 31
-#define RXTXBB_RXTXBB3_SPARE_LSB                 27
-#define RXTXBB_RXTXBB3_SPARE_MASK                0xf8000000
-#define RXTXBB_RXTXBB3_SPARE_GET(x)              (((x) & RXTXBB_RXTXBB3_SPARE_MASK) >> RXTXBB_RXTXBB3_SPARE_LSB)
-#define RXTXBB_RXTXBB3_SPARE_SET(x)              (((x) << RXTXBB_RXTXBB3_SPARE_LSB) & RXTXBB_RXTXBB3_SPARE_MASK)
-#define RXTXBB_RXTXBB3_IBN_25U_CM_BUFAMP_CTRL_MSB 26
-#define RXTXBB_RXTXBB3_IBN_25U_CM_BUFAMP_CTRL_LSB 24
-#define RXTXBB_RXTXBB3_IBN_25U_CM_BUFAMP_CTRL_MASK 0x07000000
-#define RXTXBB_RXTXBB3_IBN_25U_CM_BUFAMP_CTRL_GET(x) (((x) & RXTXBB_RXTXBB3_IBN_25U_CM_BUFAMP_CTRL_MASK) >> RXTXBB_RXTXBB3_IBN_25U_CM_BUFAMP_CTRL_LSB)
-#define RXTXBB_RXTXBB3_IBN_25U_CM_BUFAMP_CTRL_SET(x) (((x) << RXTXBB_RXTXBB3_IBN_25U_CM_BUFAMP_CTRL_LSB) & RXTXBB_RXTXBB3_IBN_25U_CM_BUFAMP_CTRL_MASK)
-#define RXTXBB_RXTXBB3_IBN_25U_BKV2I_CTRL_MSB    23
-#define RXTXBB_RXTXBB3_IBN_25U_BKV2I_CTRL_LSB    21
-#define RXTXBB_RXTXBB3_IBN_25U_BKV2I_CTRL_MASK   0x00e00000
-#define RXTXBB_RXTXBB3_IBN_25U_BKV2I_CTRL_GET(x) (((x) & RXTXBB_RXTXBB3_IBN_25U_BKV2I_CTRL_MASK) >> RXTXBB_RXTXBB3_IBN_25U_BKV2I_CTRL_LSB)
-#define RXTXBB_RXTXBB3_IBN_25U_BKV2I_CTRL_SET(x) (((x) << RXTXBB_RXTXBB3_IBN_25U_BKV2I_CTRL_LSB) & RXTXBB_RXTXBB3_IBN_25U_BKV2I_CTRL_MASK)
-#define RXTXBB_RXTXBB3_IBN_25U_I2V_CTRL_MSB      20
-#define RXTXBB_RXTXBB3_IBN_25U_I2V_CTRL_LSB      18
-#define RXTXBB_RXTXBB3_IBN_25U_I2V_CTRL_MASK     0x001c0000
-#define RXTXBB_RXTXBB3_IBN_25U_I2V_CTRL_GET(x)   (((x) & RXTXBB_RXTXBB3_IBN_25U_I2V_CTRL_MASK) >> RXTXBB_RXTXBB3_IBN_25U_I2V_CTRL_LSB)
-#define RXTXBB_RXTXBB3_IBN_25U_I2V_CTRL_SET(x)   (((x) << RXTXBB_RXTXBB3_IBN_25U_I2V_CTRL_LSB) & RXTXBB_RXTXBB3_IBN_25U_I2V_CTRL_MASK)
-#define RXTXBB_RXTXBB3_IBN_25U_HI1_CTRL_MSB      17
-#define RXTXBB_RXTXBB3_IBN_25U_HI1_CTRL_LSB      15
-#define RXTXBB_RXTXBB3_IBN_25U_HI1_CTRL_MASK     0x00038000
-#define RXTXBB_RXTXBB3_IBN_25U_HI1_CTRL_GET(x)   (((x) & RXTXBB_RXTXBB3_IBN_25U_HI1_CTRL_MASK) >> RXTXBB_RXTXBB3_IBN_25U_HI1_CTRL_LSB)
-#define RXTXBB_RXTXBB3_IBN_25U_HI1_CTRL_SET(x)   (((x) << RXTXBB_RXTXBB3_IBN_25U_HI1_CTRL_LSB) & RXTXBB_RXTXBB3_IBN_25U_HI1_CTRL_MASK)
-#define RXTXBB_RXTXBB3_IBN_25U_HI2_CTRL_MSB      14
-#define RXTXBB_RXTXBB3_IBN_25U_HI2_CTRL_LSB      12
-#define RXTXBB_RXTXBB3_IBN_25U_HI2_CTRL_MASK     0x00007000
-#define RXTXBB_RXTXBB3_IBN_25U_HI2_CTRL_GET(x)   (((x) & RXTXBB_RXTXBB3_IBN_25U_HI2_CTRL_MASK) >> RXTXBB_RXTXBB3_IBN_25U_HI2_CTRL_LSB)
-#define RXTXBB_RXTXBB3_IBN_25U_HI2_CTRL_SET(x)   (((x) << RXTXBB_RXTXBB3_IBN_25U_HI2_CTRL_LSB) & RXTXBB_RXTXBB3_IBN_25U_HI2_CTRL_MASK)
-#define RXTXBB_RXTXBB3_IBN_25U_LO1_CTRL_MSB      11
-#define RXTXBB_RXTXBB3_IBN_25U_LO1_CTRL_LSB      9
-#define RXTXBB_RXTXBB3_IBN_25U_LO1_CTRL_MASK     0x00000e00
-#define RXTXBB_RXTXBB3_IBN_25U_LO1_CTRL_GET(x)   (((x) & RXTXBB_RXTXBB3_IBN_25U_LO1_CTRL_MASK) >> RXTXBB_RXTXBB3_IBN_25U_LO1_CTRL_LSB)
-#define RXTXBB_RXTXBB3_IBN_25U_LO1_CTRL_SET(x)   (((x) << RXTXBB_RXTXBB3_IBN_25U_LO1_CTRL_LSB) & RXTXBB_RXTXBB3_IBN_25U_LO1_CTRL_MASK)
-#define RXTXBB_RXTXBB3_IBN_25U_LO2_CTRL_MSB      8
-#define RXTXBB_RXTXBB3_IBN_25U_LO2_CTRL_LSB      6
-#define RXTXBB_RXTXBB3_IBN_25U_LO2_CTRL_MASK     0x000001c0
-#define RXTXBB_RXTXBB3_IBN_25U_LO2_CTRL_GET(x)   (((x) & RXTXBB_RXTXBB3_IBN_25U_LO2_CTRL_MASK) >> RXTXBB_RXTXBB3_IBN_25U_LO2_CTRL_LSB)
-#define RXTXBB_RXTXBB3_IBN_25U_LO2_CTRL_SET(x)   (((x) << RXTXBB_RXTXBB3_IBN_25U_LO2_CTRL_LSB) & RXTXBB_RXTXBB3_IBN_25U_LO2_CTRL_MASK)
-#define RXTXBB_RXTXBB3_IBRN_12P5_CM_CTRL_MSB     5
-#define RXTXBB_RXTXBB3_IBRN_12P5_CM_CTRL_LSB     3
-#define RXTXBB_RXTXBB3_IBRN_12P5_CM_CTRL_MASK    0x00000038
-#define RXTXBB_RXTXBB3_IBRN_12P5_CM_CTRL_GET(x)  (((x) & RXTXBB_RXTXBB3_IBRN_12P5_CM_CTRL_MASK) >> RXTXBB_RXTXBB3_IBRN_12P5_CM_CTRL_LSB)
-#define RXTXBB_RXTXBB3_IBRN_12P5_CM_CTRL_SET(x)  (((x) << RXTXBB_RXTXBB3_IBRN_12P5_CM_CTRL_LSB) & RXTXBB_RXTXBB3_IBRN_12P5_CM_CTRL_MASK)
-#define RXTXBB_RXTXBB3_IBN_100U_TEST_CTRL_MSB    2
-#define RXTXBB_RXTXBB3_IBN_100U_TEST_CTRL_LSB    0
-#define RXTXBB_RXTXBB3_IBN_100U_TEST_CTRL_MASK   0x00000007
-#define RXTXBB_RXTXBB3_IBN_100U_TEST_CTRL_GET(x) (((x) & RXTXBB_RXTXBB3_IBN_100U_TEST_CTRL_MASK) >> RXTXBB_RXTXBB3_IBN_100U_TEST_CTRL_LSB)
-#define RXTXBB_RXTXBB3_IBN_100U_TEST_CTRL_SET(x) (((x) << RXTXBB_RXTXBB3_IBN_100U_TEST_CTRL_LSB) & RXTXBB_RXTXBB3_IBN_100U_TEST_CTRL_MASK)
-
-#define RXTXBB_RXTXBB4_ADDRESS                   0x0000005c
-#define RXTXBB_RXTXBB4_OFFSET                    0x0000005c
-#define RXTXBB_RXTXBB4_SPARE_MSB                 31
-#define RXTXBB_RXTXBB4_SPARE_LSB                 31
-#define RXTXBB_RXTXBB4_SPARE_MASK                0x80000000
-#define RXTXBB_RXTXBB4_SPARE_GET(x)              (((x) & RXTXBB_RXTXBB4_SPARE_MASK) >> RXTXBB_RXTXBB4_SPARE_LSB)
-#define RXTXBB_RXTXBB4_SPARE_SET(x)              (((x) << RXTXBB_RXTXBB4_SPARE_LSB) & RXTXBB_RXTXBB4_SPARE_MASK)
-#define RXTXBB_RXTXBB4_LOCALOFFSET_MSB           30
-#define RXTXBB_RXTXBB4_LOCALOFFSET_LSB           30
-#define RXTXBB_RXTXBB4_LOCALOFFSET_MASK          0x40000000
-#define RXTXBB_RXTXBB4_LOCALOFFSET_GET(x)        (((x) & RXTXBB_RXTXBB4_LOCALOFFSET_MASK) >> RXTXBB_RXTXBB4_LOCALOFFSET_LSB)
-#define RXTXBB_RXTXBB4_LOCALOFFSET_SET(x)        (((x) << RXTXBB_RXTXBB4_LOCALOFFSET_LSB) & RXTXBB_RXTXBB4_LOCALOFFSET_MASK)
-#define RXTXBB_RXTXBB4_OFSTCORRHII_MSB           29
-#define RXTXBB_RXTXBB4_OFSTCORRHII_LSB           25
-#define RXTXBB_RXTXBB4_OFSTCORRHII_MASK          0x3e000000
-#define RXTXBB_RXTXBB4_OFSTCORRHII_GET(x)        (((x) & RXTXBB_RXTXBB4_OFSTCORRHII_MASK) >> RXTXBB_RXTXBB4_OFSTCORRHII_LSB)
-#define RXTXBB_RXTXBB4_OFSTCORRHII_SET(x)        (((x) << RXTXBB_RXTXBB4_OFSTCORRHII_LSB) & RXTXBB_RXTXBB4_OFSTCORRHII_MASK)
-#define RXTXBB_RXTXBB4_OFSTCORRHIQ_MSB           24
-#define RXTXBB_RXTXBB4_OFSTCORRHIQ_LSB           20
-#define RXTXBB_RXTXBB4_OFSTCORRHIQ_MASK          0x01f00000
-#define RXTXBB_RXTXBB4_OFSTCORRHIQ_GET(x)        (((x) & RXTXBB_RXTXBB4_OFSTCORRHIQ_MASK) >> RXTXBB_RXTXBB4_OFSTCORRHIQ_LSB)
-#define RXTXBB_RXTXBB4_OFSTCORRHIQ_SET(x)        (((x) << RXTXBB_RXTXBB4_OFSTCORRHIQ_LSB) & RXTXBB_RXTXBB4_OFSTCORRHIQ_MASK)
-#define RXTXBB_RXTXBB4_OFSTCORRLOI_MSB           19
-#define RXTXBB_RXTXBB4_OFSTCORRLOI_LSB           15
-#define RXTXBB_RXTXBB4_OFSTCORRLOI_MASK          0x000f8000
-#define RXTXBB_RXTXBB4_OFSTCORRLOI_GET(x)        (((x) & RXTXBB_RXTXBB4_OFSTCORRLOI_MASK) >> RXTXBB_RXTXBB4_OFSTCORRLOI_LSB)
-#define RXTXBB_RXTXBB4_OFSTCORRLOI_SET(x)        (((x) << RXTXBB_RXTXBB4_OFSTCORRLOI_LSB) & RXTXBB_RXTXBB4_OFSTCORRLOI_MASK)
-#define RXTXBB_RXTXBB4_OFSTCORRLOQ_MSB           14
-#define RXTXBB_RXTXBB4_OFSTCORRLOQ_LSB           10
-#define RXTXBB_RXTXBB4_OFSTCORRLOQ_MASK          0x00007c00
-#define RXTXBB_RXTXBB4_OFSTCORRLOQ_GET(x)        (((x) & RXTXBB_RXTXBB4_OFSTCORRLOQ_MASK) >> RXTXBB_RXTXBB4_OFSTCORRLOQ_LSB)
-#define RXTXBB_RXTXBB4_OFSTCORRLOQ_SET(x)        (((x) << RXTXBB_RXTXBB4_OFSTCORRLOQ_LSB) & RXTXBB_RXTXBB4_OFSTCORRLOQ_MASK)
-#define RXTXBB_RXTXBB4_OFSTCORRI2VI_MSB          9
-#define RXTXBB_RXTXBB4_OFSTCORRI2VI_LSB          5
-#define RXTXBB_RXTXBB4_OFSTCORRI2VI_MASK         0x000003e0
-#define RXTXBB_RXTXBB4_OFSTCORRI2VI_GET(x)       (((x) & RXTXBB_RXTXBB4_OFSTCORRI2VI_MASK) >> RXTXBB_RXTXBB4_OFSTCORRI2VI_LSB)
-#define RXTXBB_RXTXBB4_OFSTCORRI2VI_SET(x)       (((x) << RXTXBB_RXTXBB4_OFSTCORRI2VI_LSB) & RXTXBB_RXTXBB4_OFSTCORRI2VI_MASK)
-#define RXTXBB_RXTXBB4_OFSTCORRI2VQ_MSB          4
-#define RXTXBB_RXTXBB4_OFSTCORRI2VQ_LSB          0
-#define RXTXBB_RXTXBB4_OFSTCORRI2VQ_MASK         0x0000001f
-#define RXTXBB_RXTXBB4_OFSTCORRI2VQ_GET(x)       (((x) & RXTXBB_RXTXBB4_OFSTCORRI2VQ_MASK) >> RXTXBB_RXTXBB4_OFSTCORRI2VQ_LSB)
-#define RXTXBB_RXTXBB4_OFSTCORRI2VQ_SET(x)       (((x) << RXTXBB_RXTXBB4_OFSTCORRI2VQ_LSB) & RXTXBB_RXTXBB4_OFSTCORRI2VQ_MASK)
-
-#define ADDAC_ADDAC1_ADDRESS                     0x00000060
-#define ADDAC_ADDAC1_OFFSET                      0x00000060
-#define ADDAC_ADDAC1_PLL_SVREG_MSB               31
-#define ADDAC_ADDAC1_PLL_SVREG_LSB               31
-#define ADDAC_ADDAC1_PLL_SVREG_MASK              0x80000000
-#define ADDAC_ADDAC1_PLL_SVREG_GET(x)            (((x) & ADDAC_ADDAC1_PLL_SVREG_MASK) >> ADDAC_ADDAC1_PLL_SVREG_LSB)
-#define ADDAC_ADDAC1_PLL_SVREG_SET(x)            (((x) << ADDAC_ADDAC1_PLL_SVREG_LSB) & ADDAC_ADDAC1_PLL_SVREG_MASK)
-#define ADDAC_ADDAC1_PLL_SCLAMP_MSB              30
-#define ADDAC_ADDAC1_PLL_SCLAMP_LSB              28
-#define ADDAC_ADDAC1_PLL_SCLAMP_MASK             0x70000000
-#define ADDAC_ADDAC1_PLL_SCLAMP_GET(x)           (((x) & ADDAC_ADDAC1_PLL_SCLAMP_MASK) >> ADDAC_ADDAC1_PLL_SCLAMP_LSB)
-#define ADDAC_ADDAC1_PLL_SCLAMP_SET(x)           (((x) << ADDAC_ADDAC1_PLL_SCLAMP_LSB) & ADDAC_ADDAC1_PLL_SCLAMP_MASK)
-#define ADDAC_ADDAC1_PLL_ATB_MSB                 27
-#define ADDAC_ADDAC1_PLL_ATB_LSB                 26
-#define ADDAC_ADDAC1_PLL_ATB_MASK                0x0c000000
-#define ADDAC_ADDAC1_PLL_ATB_GET(x)              (((x) & ADDAC_ADDAC1_PLL_ATB_MASK) >> ADDAC_ADDAC1_PLL_ATB_LSB)
-#define ADDAC_ADDAC1_PLL_ATB_SET(x)              (((x) << ADDAC_ADDAC1_PLL_ATB_LSB) & ADDAC_ADDAC1_PLL_ATB_MASK)
-#define ADDAC_ADDAC1_PLL_ICP_MSB                 25
-#define ADDAC_ADDAC1_PLL_ICP_LSB                 23
-#define ADDAC_ADDAC1_PLL_ICP_MASK                0x03800000
-#define ADDAC_ADDAC1_PLL_ICP_GET(x)              (((x) & ADDAC_ADDAC1_PLL_ICP_MASK) >> ADDAC_ADDAC1_PLL_ICP_LSB)
-#define ADDAC_ADDAC1_PLL_ICP_SET(x)              (((x) << ADDAC_ADDAC1_PLL_ICP_LSB) & ADDAC_ADDAC1_PLL_ICP_MASK)
-#define ADDAC_ADDAC1_PLL_FILTER_MSB              22
-#define ADDAC_ADDAC1_PLL_FILTER_LSB              15
-#define ADDAC_ADDAC1_PLL_FILTER_MASK             0x007f8000
-#define ADDAC_ADDAC1_PLL_FILTER_GET(x)           (((x) & ADDAC_ADDAC1_PLL_FILTER_MASK) >> ADDAC_ADDAC1_PLL_FILTER_LSB)
-#define ADDAC_ADDAC1_PLL_FILTER_SET(x)           (((x) << ADDAC_ADDAC1_PLL_FILTER_LSB) & ADDAC_ADDAC1_PLL_FILTER_MASK)
-#define ADDAC_ADDAC1_PWDPLL_MSB                  14
-#define ADDAC_ADDAC1_PWDPLL_LSB                  14
-#define ADDAC_ADDAC1_PWDPLL_MASK                 0x00004000
-#define ADDAC_ADDAC1_PWDPLL_GET(x)               (((x) & ADDAC_ADDAC1_PWDPLL_MASK) >> ADDAC_ADDAC1_PWDPLL_LSB)
-#define ADDAC_ADDAC1_PWDPLL_SET(x)               (((x) << ADDAC_ADDAC1_PWDPLL_LSB) & ADDAC_ADDAC1_PWDPLL_MASK)
-#define ADDAC_ADDAC1_PWDADC_MSB                  13
-#define ADDAC_ADDAC1_PWDADC_LSB                  13
-#define ADDAC_ADDAC1_PWDADC_MASK                 0x00002000
-#define ADDAC_ADDAC1_PWDADC_GET(x)               (((x) & ADDAC_ADDAC1_PWDADC_MASK) >> ADDAC_ADDAC1_PWDADC_LSB)
-#define ADDAC_ADDAC1_PWDADC_SET(x)               (((x) << ADDAC_ADDAC1_PWDADC_LSB) & ADDAC_ADDAC1_PWDADC_MASK)
-#define ADDAC_ADDAC1_PWDDAC_MSB                  12
-#define ADDAC_ADDAC1_PWDDAC_LSB                  12
-#define ADDAC_ADDAC1_PWDDAC_MASK                 0x00001000
-#define ADDAC_ADDAC1_PWDDAC_GET(x)               (((x) & ADDAC_ADDAC1_PWDDAC_MASK) >> ADDAC_ADDAC1_PWDDAC_LSB)
-#define ADDAC_ADDAC1_PWDDAC_SET(x)               (((x) << ADDAC_ADDAC1_PWDDAC_LSB) & ADDAC_ADDAC1_PWDDAC_MASK)
-#define ADDAC_ADDAC1_FORCEMSBLOW_MSB             11
-#define ADDAC_ADDAC1_FORCEMSBLOW_LSB             11
-#define ADDAC_ADDAC1_FORCEMSBLOW_MASK            0x00000800
-#define ADDAC_ADDAC1_FORCEMSBLOW_GET(x)          (((x) & ADDAC_ADDAC1_FORCEMSBLOW_MASK) >> ADDAC_ADDAC1_FORCEMSBLOW_LSB)
-#define ADDAC_ADDAC1_FORCEMSBLOW_SET(x)          (((x) << ADDAC_ADDAC1_FORCEMSBLOW_LSB) & ADDAC_ADDAC1_FORCEMSBLOW_MASK)
-#define ADDAC_ADDAC1_SELMANPWDS_MSB              10
-#define ADDAC_ADDAC1_SELMANPWDS_LSB              10
-#define ADDAC_ADDAC1_SELMANPWDS_MASK             0x00000400
-#define ADDAC_ADDAC1_SELMANPWDS_GET(x)           (((x) & ADDAC_ADDAC1_SELMANPWDS_MASK) >> ADDAC_ADDAC1_SELMANPWDS_LSB)
-#define ADDAC_ADDAC1_SELMANPWDS_SET(x)           (((x) << ADDAC_ADDAC1_SELMANPWDS_LSB) & ADDAC_ADDAC1_SELMANPWDS_MASK)
-#define ADDAC_ADDAC1_INV_CLK160_ADC_MSB          9
-#define ADDAC_ADDAC1_INV_CLK160_ADC_LSB          9
-#define ADDAC_ADDAC1_INV_CLK160_ADC_MASK         0x00000200
-#define ADDAC_ADDAC1_INV_CLK160_ADC_GET(x)       (((x) & ADDAC_ADDAC1_INV_CLK160_ADC_MASK) >> ADDAC_ADDAC1_INV_CLK160_ADC_LSB)
-#define ADDAC_ADDAC1_INV_CLK160_ADC_SET(x)       (((x) << ADDAC_ADDAC1_INV_CLK160_ADC_LSB) & ADDAC_ADDAC1_INV_CLK160_ADC_MASK)
-#define ADDAC_ADDAC1_CM_SEL_MSB                  8
-#define ADDAC_ADDAC1_CM_SEL_LSB                  7
-#define ADDAC_ADDAC1_CM_SEL_MASK                 0x00000180
-#define ADDAC_ADDAC1_CM_SEL_GET(x)               (((x) & ADDAC_ADDAC1_CM_SEL_MASK) >> ADDAC_ADDAC1_CM_SEL_LSB)
-#define ADDAC_ADDAC1_CM_SEL_SET(x)               (((x) << ADDAC_ADDAC1_CM_SEL_LSB) & ADDAC_ADDAC1_CM_SEL_MASK)
-#define ADDAC_ADDAC1_DISABLE_DAC_REG_MSB         6
-#define ADDAC_ADDAC1_DISABLE_DAC_REG_LSB         6
-#define ADDAC_ADDAC1_DISABLE_DAC_REG_MASK        0x00000040
-#define ADDAC_ADDAC1_DISABLE_DAC_REG_GET(x)      (((x) & ADDAC_ADDAC1_DISABLE_DAC_REG_MASK) >> ADDAC_ADDAC1_DISABLE_DAC_REG_LSB)
-#define ADDAC_ADDAC1_DISABLE_DAC_REG_SET(x)      (((x) << ADDAC_ADDAC1_DISABLE_DAC_REG_LSB) & ADDAC_ADDAC1_DISABLE_DAC_REG_MASK)
-#define ADDAC_ADDAC1_SPARE_MSB                   5
-#define ADDAC_ADDAC1_SPARE_LSB                   0
-#define ADDAC_ADDAC1_SPARE_MASK                  0x0000003f
-#define ADDAC_ADDAC1_SPARE_GET(x)                (((x) & ADDAC_ADDAC1_SPARE_MASK) >> ADDAC_ADDAC1_SPARE_LSB)
-#define ADDAC_ADDAC1_SPARE_SET(x)                (((x) << ADDAC_ADDAC1_SPARE_LSB) & ADDAC_ADDAC1_SPARE_MASK)
-
-
-#ifndef __ASSEMBLER__
-
-typedef struct analog_reg_reg_s {
-  volatile unsigned int synth_synth1;
-  volatile unsigned int synth_synth2;
-  volatile unsigned int synth_synth3;
-  volatile unsigned int synth_synth4;
-  volatile unsigned int synth_synth5;
-  volatile unsigned int synth_synth6;
-  volatile unsigned int synth_synth7;
-  volatile unsigned int synth_synth8;
-  volatile unsigned int rf5g_rf5g1;
-  volatile unsigned int rf5g_rf5g2;
-  volatile unsigned int rf2g_rf2g1;
-  volatile unsigned int rf2g_rf2g2;
-  volatile unsigned int top_gain;
-  volatile unsigned int top_top;
-  volatile unsigned int bias_bias_sel;
-  volatile unsigned int bias_bias1;
-  volatile unsigned int bias_bias2;
-  volatile unsigned int bias_bias3;
-  volatile unsigned int txpc_txpc;
-  volatile unsigned int txpc_misc;
-  volatile unsigned int rxtxbb_rxtxbb1;
-  volatile unsigned int rxtxbb_rxtxbb2;
-  volatile unsigned int rxtxbb_rxtxbb3;
-  volatile unsigned int rxtxbb_rxtxbb4;
-  volatile unsigned int addac_addac1;
-} analog_reg_reg_t;
-
-#endif /* __ASSEMBLER__ */
-
-#endif /* _ANALOG_REG_H_ */
diff -druN linux-2.6.39-libre/drivers/staging/ath6kl/include/common/AR6002/hw2.0/hw/apb_map.h linux-3.0-rc7-libre/drivers/staging/ath6kl/include/common/AR6002/hw2.0/hw/apb_map.h
--- linux-2.6.39-libre/drivers/staging/ath6kl/include/common/AR6002/hw2.0/hw/apb_map.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/ath6kl/include/common/AR6002/hw2.0/hw/apb_map.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,13 +0,0 @@
-#ifndef _APB_MAP_H_
-#define _APB_MAP_H_
-
-#define RTC_BASE_ADDRESS                         0x00004000
-#define VMC_BASE_ADDRESS                         0x00008000
-#define UART_BASE_ADDRESS                        0x0000c000
-#define SI_BASE_ADDRESS                          0x00010000
-#define GPIO_BASE_ADDRESS                        0x00014000
-#define MBOX_BASE_ADDRESS                        0x00018000
-#define ANALOG_INTF_BASE_ADDRESS                 0x0001c000
-#define MAC_BASE_ADDRESS                         0x00020000
-
-#endif /* _APB_MAP_REG_H_ */
diff -druN linux-2.6.39-libre/drivers/staging/ath6kl/include/common/AR6002/hw2.0/hw/gpio_reg.h linux-3.0-rc7-libre/drivers/staging/ath6kl/include/common/AR6002/hw2.0/hw/gpio_reg.h
--- linux-2.6.39-libre/drivers/staging/ath6kl/include/common/AR6002/hw2.0/hw/gpio_reg.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/ath6kl/include/common/AR6002/hw2.0/hw/gpio_reg.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,977 +0,0 @@
-#ifndef _GPIO_REG_REG_H_
-#define _GPIO_REG_REG_H_
-
-#define GPIO_OUT_ADDRESS                         0x00000000
-#define GPIO_OUT_OFFSET                          0x00000000
-#define GPIO_OUT_DATA_MSB                        17
-#define GPIO_OUT_DATA_LSB                        0
-#define GPIO_OUT_DATA_MASK                       0x0003ffff
-#define GPIO_OUT_DATA_GET(x)                     (((x) & GPIO_OUT_DATA_MASK) >> GPIO_OUT_DATA_LSB)
-#define GPIO_OUT_DATA_SET(x)                     (((x) << GPIO_OUT_DATA_LSB) & GPIO_OUT_DATA_MASK)
-
-#define GPIO_OUT_W1TS_ADDRESS                    0x00000004
-#define GPIO_OUT_W1TS_OFFSET                     0x00000004
-#define GPIO_OUT_W1TS_DATA_MSB                   17
-#define GPIO_OUT_W1TS_DATA_LSB                   0
-#define GPIO_OUT_W1TS_DATA_MASK                  0x0003ffff
-#define GPIO_OUT_W1TS_DATA_GET(x)                (((x) & GPIO_OUT_W1TS_DATA_MASK) >> GPIO_OUT_W1TS_DATA_LSB)
-#define GPIO_OUT_W1TS_DATA_SET(x)                (((x) << GPIO_OUT_W1TS_DATA_LSB) & GPIO_OUT_W1TS_DATA_MASK)
-
-#define GPIO_OUT_W1TC_ADDRESS                    0x00000008
-#define GPIO_OUT_W1TC_OFFSET                     0x00000008
-#define GPIO_OUT_W1TC_DATA_MSB                   17
-#define GPIO_OUT_W1TC_DATA_LSB                   0
-#define GPIO_OUT_W1TC_DATA_MASK                  0x0003ffff
-#define GPIO_OUT_W1TC_DATA_GET(x)                (((x) & GPIO_OUT_W1TC_DATA_MASK) >> GPIO_OUT_W1TC_DATA_LSB)
-#define GPIO_OUT_W1TC_DATA_SET(x)                (((x) << GPIO_OUT_W1TC_DATA_LSB) & GPIO_OUT_W1TC_DATA_MASK)
-
-#define GPIO_ENABLE_ADDRESS                      0x0000000c
-#define GPIO_ENABLE_OFFSET                       0x0000000c
-#define GPIO_ENABLE_DATA_MSB                     17
-#define GPIO_ENABLE_DATA_LSB                     0
-#define GPIO_ENABLE_DATA_MASK                    0x0003ffff
-#define GPIO_ENABLE_DATA_GET(x)                  (((x) & GPIO_ENABLE_DATA_MASK) >> GPIO_ENABLE_DATA_LSB)
-#define GPIO_ENABLE_DATA_SET(x)                  (((x) << GPIO_ENABLE_DATA_LSB) & GPIO_ENABLE_DATA_MASK)
-
-#define GPIO_ENABLE_W1TS_ADDRESS                 0x00000010
-#define GPIO_ENABLE_W1TS_OFFSET                  0x00000010
-#define GPIO_ENABLE_W1TS_DATA_MSB                17
-#define GPIO_ENABLE_W1TS_DATA_LSB                0
-#define GPIO_ENABLE_W1TS_DATA_MASK               0x0003ffff
-#define GPIO_ENABLE_W1TS_DATA_GET(x)             (((x) & GPIO_ENABLE_W1TS_DATA_MASK) >> GPIO_ENABLE_W1TS_DATA_LSB)
-#define GPIO_ENABLE_W1TS_DATA_SET(x)             (((x) << GPIO_ENABLE_W1TS_DATA_LSB) & GPIO_ENABLE_W1TS_DATA_MASK)
-
-#define GPIO_ENABLE_W1TC_ADDRESS                 0x00000014
-#define GPIO_ENABLE_W1TC_OFFSET                  0x00000014
-#define GPIO_ENABLE_W1TC_DATA_MSB                17
-#define GPIO_ENABLE_W1TC_DATA_LSB                0
-#define GPIO_ENABLE_W1TC_DATA_MASK               0x0003ffff
-#define GPIO_ENABLE_W1TC_DATA_GET(x)             (((x) & GPIO_ENABLE_W1TC_DATA_MASK) >> GPIO_ENABLE_W1TC_DATA_LSB)
-#define GPIO_ENABLE_W1TC_DATA_SET(x)             (((x) << GPIO_ENABLE_W1TC_DATA_LSB) & GPIO_ENABLE_W1TC_DATA_MASK)
-
-#define GPIO_IN_ADDRESS                          0x00000018
-#define GPIO_IN_OFFSET                           0x00000018
-#define GPIO_IN_DATA_MSB                         17
-#define GPIO_IN_DATA_LSB                         0
-#define GPIO_IN_DATA_MASK                        0x0003ffff
-#define GPIO_IN_DATA_GET(x)                      (((x) & GPIO_IN_DATA_MASK) >> GPIO_IN_DATA_LSB)
-#define GPIO_IN_DATA_SET(x)                      (((x) << GPIO_IN_DATA_LSB) & GPIO_IN_DATA_MASK)
-
-#define GPIO_STATUS_ADDRESS                      0x0000001c
-#define GPIO_STATUS_OFFSET                       0x0000001c
-#define GPIO_STATUS_INTERRUPT_MSB                17
-#define GPIO_STATUS_INTERRUPT_LSB                0
-#define GPIO_STATUS_INTERRUPT_MASK               0x0003ffff
-#define GPIO_STATUS_INTERRUPT_GET(x)             (((x) & GPIO_STATUS_INTERRUPT_MASK) >> GPIO_STATUS_INTERRUPT_LSB)
-#define GPIO_STATUS_INTERRUPT_SET(x)             (((x) << GPIO_STATUS_INTERRUPT_LSB) & GPIO_STATUS_INTERRUPT_MASK)
-
-#define GPIO_STATUS_W1TS_ADDRESS                 0x00000020
-#define GPIO_STATUS_W1TS_OFFSET                  0x00000020
-#define GPIO_STATUS_W1TS_INTERRUPT_MSB           17
-#define GPIO_STATUS_W1TS_INTERRUPT_LSB           0
-#define GPIO_STATUS_W1TS_INTERRUPT_MASK          0x0003ffff
-#define GPIO_STATUS_W1TS_INTERRUPT_GET(x)        (((x) & GPIO_STATUS_W1TS_INTERRUPT_MASK) >> GPIO_STATUS_W1TS_INTERRUPT_LSB)
-#define GPIO_STATUS_W1TS_INTERRUPT_SET(x)        (((x) << GPIO_STATUS_W1TS_INTERRUPT_LSB) & GPIO_STATUS_W1TS_INTERRUPT_MASK)
-
-#define GPIO_STATUS_W1TC_ADDRESS                 0x00000024
-#define GPIO_STATUS_W1TC_OFFSET                  0x00000024
-#define GPIO_STATUS_W1TC_INTERRUPT_MSB           17
-#define GPIO_STATUS_W1TC_INTERRUPT_LSB           0
-#define GPIO_STATUS_W1TC_INTERRUPT_MASK          0x0003ffff
-#define GPIO_STATUS_W1TC_INTERRUPT_GET(x)        (((x) & GPIO_STATUS_W1TC_INTERRUPT_MASK) >> GPIO_STATUS_W1TC_INTERRUPT_LSB)
-#define GPIO_STATUS_W1TC_INTERRUPT_SET(x)        (((x) << GPIO_STATUS_W1TC_INTERRUPT_LSB) & GPIO_STATUS_W1TC_INTERRUPT_MASK)
-
-#define GPIO_PIN0_ADDRESS                        0x00000028
-#define GPIO_PIN0_OFFSET                         0x00000028
-#define GPIO_PIN0_CONFIG_MSB                     12
-#define GPIO_PIN0_CONFIG_LSB                     11
-#define GPIO_PIN0_CONFIG_MASK                    0x00001800
-#define GPIO_PIN0_CONFIG_GET(x)                  (((x) & GPIO_PIN0_CONFIG_MASK) >> GPIO_PIN0_CONFIG_LSB)
-#define GPIO_PIN0_CONFIG_SET(x)                  (((x) << GPIO_PIN0_CONFIG_LSB) & GPIO_PIN0_CONFIG_MASK)
-#define GPIO_PIN0_WAKEUP_ENABLE_MSB              10
-#define GPIO_PIN0_WAKEUP_ENABLE_LSB              10
-#define GPIO_PIN0_WAKEUP_ENABLE_MASK             0x00000400
-#define GPIO_PIN0_WAKEUP_ENABLE_GET(x)           (((x) & GPIO_PIN0_WAKEUP_ENABLE_MASK) >> GPIO_PIN0_WAKEUP_ENABLE_LSB)
-#define GPIO_PIN0_WAKEUP_ENABLE_SET(x)           (((x) << GPIO_PIN0_WAKEUP_ENABLE_LSB) & GPIO_PIN0_WAKEUP_ENABLE_MASK)
-#define GPIO_PIN0_INT_TYPE_MSB                   9
-#define GPIO_PIN0_INT_TYPE_LSB                   7
-#define GPIO_PIN0_INT_TYPE_MASK                  0x00000380
-#define GPIO_PIN0_INT_TYPE_GET(x)                (((x) & GPIO_PIN0_INT_TYPE_MASK) >> GPIO_PIN0_INT_TYPE_LSB)
-#define GPIO_PIN0_INT_TYPE_SET(x)                (((x) << GPIO_PIN0_INT_TYPE_LSB) & GPIO_PIN0_INT_TYPE_MASK)
-#define GPIO_PIN0_PAD_DRIVER_MSB                 2
-#define GPIO_PIN0_PAD_DRIVER_LSB                 2
-#define GPIO_PIN0_PAD_DRIVER_MASK                0x00000004
-#define GPIO_PIN0_PAD_DRIVER_GET(x)              (((x) & GPIO_PIN0_PAD_DRIVER_MASK) >> GPIO_PIN0_PAD_DRIVER_LSB)
-#define GPIO_PIN0_PAD_DRIVER_SET(x)              (((x) << GPIO_PIN0_PAD_DRIVER_LSB) & GPIO_PIN0_PAD_DRIVER_MASK)
-#define GPIO_PIN0_SOURCE_MSB                     0
-#define GPIO_PIN0_SOURCE_LSB                     0
-#define GPIO_PIN0_SOURCE_MASK                    0x00000001
-#define GPIO_PIN0_SOURCE_GET(x)                  (((x) & GPIO_PIN0_SOURCE_MASK) >> GPIO_PIN0_SOURCE_LSB)
-#define GPIO_PIN0_SOURCE_SET(x)                  (((x) << GPIO_PIN0_SOURCE_LSB) & GPIO_PIN0_SOURCE_MASK)
-
-#define GPIO_PIN1_ADDRESS                        0x0000002c
-#define GPIO_PIN1_OFFSET                         0x0000002c
-#define GPIO_PIN1_CONFIG_MSB                     12
-#define GPIO_PIN1_CONFIG_LSB                     11
-#define GPIO_PIN1_CONFIG_MASK                    0x00001800
-#define GPIO_PIN1_CONFIG_GET(x)                  (((x) & GPIO_PIN1_CONFIG_MASK) >> GPIO_PIN1_CONFIG_LSB)
-#define GPIO_PIN1_CONFIG_SET(x)                  (((x) << GPIO_PIN1_CONFIG_LSB) & GPIO_PIN1_CONFIG_MASK)
-#define GPIO_PIN1_WAKEUP_ENABLE_MSB              10
-#define GPIO_PIN1_WAKEUP_ENABLE_LSB              10
-#define GPIO_PIN1_WAKEUP_ENABLE_MASK             0x00000400
-#define GPIO_PIN1_WAKEUP_ENABLE_GET(x)           (((x) & GPIO_PIN1_WAKEUP_ENABLE_MASK) >> GPIO_PIN1_WAKEUP_ENABLE_LSB)
-#define GPIO_PIN1_WAKEUP_ENABLE_SET(x)           (((x) << GPIO_PIN1_WAKEUP_ENABLE_LSB) & GPIO_PIN1_WAKEUP_ENABLE_MASK)
-#define GPIO_PIN1_INT_TYPE_MSB                   9
-#define GPIO_PIN1_INT_TYPE_LSB                   7
-#define GPIO_PIN1_INT_TYPE_MASK                  0x00000380
-#define GPIO_PIN1_INT_TYPE_GET(x)                (((x) & GPIO_PIN1_INT_TYPE_MASK) >> GPIO_PIN1_INT_TYPE_LSB)
-#define GPIO_PIN1_INT_TYPE_SET(x)                (((x) << GPIO_PIN1_INT_TYPE_LSB) & GPIO_PIN1_INT_TYPE_MASK)
-#define GPIO_PIN1_PAD_DRIVER_MSB                 2
-#define GPIO_PIN1_PAD_DRIVER_LSB                 2
-#define GPIO_PIN1_PAD_DRIVER_MASK                0x00000004
-#define GPIO_PIN1_PAD_DRIVER_GET(x)              (((x) & GPIO_PIN1_PAD_DRIVER_MASK) >> GPIO_PIN1_PAD_DRIVER_LSB)
-#define GPIO_PIN1_PAD_DRIVER_SET(x)              (((x) << GPIO_PIN1_PAD_DRIVER_LSB) & GPIO_PIN1_PAD_DRIVER_MASK)
-#define GPIO_PIN1_SOURCE_MSB                     0
-#define GPIO_PIN1_SOURCE_LSB                     0
-#define GPIO_PIN1_SOURCE_MASK                    0x00000001
-#define GPIO_PIN1_SOURCE_GET(x)                  (((x) & GPIO_PIN1_SOURCE_MASK) >> GPIO_PIN1_SOURCE_LSB)
-#define GPIO_PIN1_SOURCE_SET(x)                  (((x) << GPIO_PIN1_SOURCE_LSB) & GPIO_PIN1_SOURCE_MASK)
-
-#define GPIO_PIN2_ADDRESS                        0x00000030
-#define GPIO_PIN2_OFFSET                         0x00000030
-#define GPIO_PIN2_CONFIG_MSB                     12
-#define GPIO_PIN2_CONFIG_LSB                     11
-#define GPIO_PIN2_CONFIG_MASK                    0x00001800
-#define GPIO_PIN2_CONFIG_GET(x)                  (((x) & GPIO_PIN2_CONFIG_MASK) >> GPIO_PIN2_CONFIG_LSB)
-#define GPIO_PIN2_CONFIG_SET(x)                  (((x) << GPIO_PIN2_CONFIG_LSB) & GPIO_PIN2_CONFIG_MASK)
-#define GPIO_PIN2_WAKEUP_ENABLE_MSB              10
-#define GPIO_PIN2_WAKEUP_ENABLE_LSB              10
-#define GPIO_PIN2_WAKEUP_ENABLE_MASK             0x00000400
-#define GPIO_PIN2_WAKEUP_ENABLE_GET(x)           (((x) & GPIO_PIN2_WAKEUP_ENABLE_MASK) >> GPIO_PIN2_WAKEUP_ENABLE_LSB)
-#define GPIO_PIN2_WAKEUP_ENABLE_SET(x)           (((x) << GPIO_PIN2_WAKEUP_ENABLE_LSB) & GPIO_PIN2_WAKEUP_ENABLE_MASK)
-#define GPIO_PIN2_INT_TYPE_MSB                   9
-#define GPIO_PIN2_INT_TYPE_LSB                   7
-#define GPIO_PIN2_INT_TYPE_MASK                  0x00000380
-#define GPIO_PIN2_INT_TYPE_GET(x)                (((x) & GPIO_PIN2_INT_TYPE_MASK) >> GPIO_PIN2_INT_TYPE_LSB)
-#define GPIO_PIN2_INT_TYPE_SET(x)                (((x) << GPIO_PIN2_INT_TYPE_LSB) & GPIO_PIN2_INT_TYPE_MASK)
-#define GPIO_PIN2_PAD_DRIVER_MSB                 2
-#define GPIO_PIN2_PAD_DRIVER_LSB                 2
-#define GPIO_PIN2_PAD_DRIVER_MASK                0x00000004
-#define GPIO_PIN2_PAD_DRIVER_GET(x)              (((x) & GPIO_PIN2_PAD_DRIVER_MASK) >> GPIO_PIN2_PAD_DRIVER_LSB)
-#define GPIO_PIN2_PAD_DRIVER_SET(x)              (((x) << GPIO_PIN2_PAD_DRIVER_LSB) & GPIO_PIN2_PAD_DRIVER_MASK)
-#define GPIO_PIN2_SOURCE_MSB                     0
-#define GPIO_PIN2_SOURCE_LSB                     0
-#define GPIO_PIN2_SOURCE_MASK                    0x00000001
-#define GPIO_PIN2_SOURCE_GET(x)                  (((x) & GPIO_PIN2_SOURCE_MASK) >> GPIO_PIN2_SOURCE_LSB)
-#define GPIO_PIN2_SOURCE_SET(x)                  (((x) << GPIO_PIN2_SOURCE_LSB) & GPIO_PIN2_SOURCE_MASK)
-
-#define GPIO_PIN3_ADDRESS                        0x00000034
-#define GPIO_PIN3_OFFSET                         0x00000034
-#define GPIO_PIN3_CONFIG_MSB                     12
-#define GPIO_PIN3_CONFIG_LSB                     11
-#define GPIO_PIN3_CONFIG_MASK                    0x00001800
-#define GPIO_PIN3_CONFIG_GET(x)                  (((x) & GPIO_PIN3_CONFIG_MASK) >> GPIO_PIN3_CONFIG_LSB)
-#define GPIO_PIN3_CONFIG_SET(x)                  (((x) << GPIO_PIN3_CONFIG_LSB) & GPIO_PIN3_CONFIG_MASK)
-#define GPIO_PIN3_WAKEUP_ENABLE_MSB              10
-#define GPIO_PIN3_WAKEUP_ENABLE_LSB              10
-#define GPIO_PIN3_WAKEUP_ENABLE_MASK             0x00000400
-#define GPIO_PIN3_WAKEUP_ENABLE_GET(x)           (((x) & GPIO_PIN3_WAKEUP_ENABLE_MASK) >> GPIO_PIN3_WAKEUP_ENABLE_LSB)
-#define GPIO_PIN3_WAKEUP_ENABLE_SET(x)           (((x) << GPIO_PIN3_WAKEUP_ENABLE_LSB) & GPIO_PIN3_WAKEUP_ENABLE_MASK)
-#define GPIO_PIN3_INT_TYPE_MSB                   9
-#define GPIO_PIN3_INT_TYPE_LSB                   7
-#define GPIO_PIN3_INT_TYPE_MASK                  0x00000380
-#define GPIO_PIN3_INT_TYPE_GET(x)                (((x) & GPIO_PIN3_INT_TYPE_MASK) >> GPIO_PIN3_INT_TYPE_LSB)
-#define GPIO_PIN3_INT_TYPE_SET(x)                (((x) << GPIO_PIN3_INT_TYPE_LSB) & GPIO_PIN3_INT_TYPE_MASK)
-#define GPIO_PIN3_PAD_DRIVER_MSB                 2
-#define GPIO_PIN3_PAD_DRIVER_LSB                 2
-#define GPIO_PIN3_PAD_DRIVER_MASK                0x00000004
-#define GPIO_PIN3_PAD_DRIVER_GET(x)              (((x) & GPIO_PIN3_PAD_DRIVER_MASK) >> GPIO_PIN3_PAD_DRIVER_LSB)
-#define GPIO_PIN3_PAD_DRIVER_SET(x)              (((x) << GPIO_PIN3_PAD_DRIVER_LSB) & GPIO_PIN3_PAD_DRIVER_MASK)
-#define GPIO_PIN3_SOURCE_MSB                     0
-#define GPIO_PIN3_SOURCE_LSB                     0
-#define GPIO_PIN3_SOURCE_MASK                    0x00000001
-#define GPIO_PIN3_SOURCE_GET(x)                  (((x) & GPIO_PIN3_SOURCE_MASK) >> GPIO_PIN3_SOURCE_LSB)
-#define GPIO_PIN3_SOURCE_SET(x)                  (((x) << GPIO_PIN3_SOURCE_LSB) & GPIO_PIN3_SOURCE_MASK)
-
-#define GPIO_PIN4_ADDRESS                        0x00000038
-#define GPIO_PIN4_OFFSET                         0x00000038
-#define GPIO_PIN4_CONFIG_MSB                     12
-#define GPIO_PIN4_CONFIG_LSB                     11
-#define GPIO_PIN4_CONFIG_MASK                    0x00001800
-#define GPIO_PIN4_CONFIG_GET(x)                  (((x) & GPIO_PIN4_CONFIG_MASK) >> GPIO_PIN4_CONFIG_LSB)
-#define GPIO_PIN4_CONFIG_SET(x)                  (((x) << GPIO_PIN4_CONFIG_LSB) & GPIO_PIN4_CONFIG_MASK)
-#define GPIO_PIN4_WAKEUP_ENABLE_MSB              10
-#define GPIO_PIN4_WAKEUP_ENABLE_LSB              10
-#define GPIO_PIN4_WAKEUP_ENABLE_MASK             0x00000400
-#define GPIO_PIN4_WAKEUP_ENABLE_GET(x)           (((x) & GPIO_PIN4_WAKEUP_ENABLE_MASK) >> GPIO_PIN4_WAKEUP_ENABLE_LSB)
-#define GPIO_PIN4_WAKEUP_ENABLE_SET(x)           (((x) << GPIO_PIN4_WAKEUP_ENABLE_LSB) & GPIO_PIN4_WAKEUP_ENABLE_MASK)
-#define GPIO_PIN4_INT_TYPE_MSB                   9
-#define GPIO_PIN4_INT_TYPE_LSB                   7
-#define GPIO_PIN4_INT_TYPE_MASK                  0x00000380
-#define GPIO_PIN4_INT_TYPE_GET(x)                (((x) & GPIO_PIN4_INT_TYPE_MASK) >> GPIO_PIN4_INT_TYPE_LSB)
-#define GPIO_PIN4_INT_TYPE_SET(x)                (((x) << GPIO_PIN4_INT_TYPE_LSB) & GPIO_PIN4_INT_TYPE_MASK)
-#define GPIO_PIN4_PAD_DRIVER_MSB                 2
-#define GPIO_PIN4_PAD_DRIVER_LSB                 2
-#define GPIO_PIN4_PAD_DRIVER_MASK                0x00000004
-#define GPIO_PIN4_PAD_DRIVER_GET(x)              (((x) & GPIO_PIN4_PAD_DRIVER_MASK) >> GPIO_PIN4_PAD_DRIVER_LSB)
-#define GPIO_PIN4_PAD_DRIVER_SET(x)              (((x) << GPIO_PIN4_PAD_DRIVER_LSB) & GPIO_PIN4_PAD_DRIVER_MASK)
-#define GPIO_PIN4_SOURCE_MSB                     0
-#define GPIO_PIN4_SOURCE_LSB                     0
-#define GPIO_PIN4_SOURCE_MASK                    0x00000001
-#define GPIO_PIN4_SOURCE_GET(x)                  (((x) & GPIO_PIN4_SOURCE_MASK) >> GPIO_PIN4_SOURCE_LSB)
-#define GPIO_PIN4_SOURCE_SET(x)                  (((x) << GPIO_PIN4_SOURCE_LSB) & GPIO_PIN4_SOURCE_MASK)
-
-#define GPIO_PIN5_ADDRESS                        0x0000003c
-#define GPIO_PIN5_OFFSET                         0x0000003c
-#define GPIO_PIN5_CONFIG_MSB                     12
-#define GPIO_PIN5_CONFIG_LSB                     11
-#define GPIO_PIN5_CONFIG_MASK                    0x00001800
-#define GPIO_PIN5_CONFIG_GET(x)                  (((x) & GPIO_PIN5_CONFIG_MASK) >> GPIO_PIN5_CONFIG_LSB)
-#define GPIO_PIN5_CONFIG_SET(x)                  (((x) << GPIO_PIN5_CONFIG_LSB) & GPIO_PIN5_CONFIG_MASK)
-#define GPIO_PIN5_WAKEUP_ENABLE_MSB              10
-#define GPIO_PIN5_WAKEUP_ENABLE_LSB              10
-#define GPIO_PIN5_WAKEUP_ENABLE_MASK             0x00000400
-#define GPIO_PIN5_WAKEUP_ENABLE_GET(x)           (((x) & GPIO_PIN5_WAKEUP_ENABLE_MASK) >> GPIO_PIN5_WAKEUP_ENABLE_LSB)
-#define GPIO_PIN5_WAKEUP_ENABLE_SET(x)           (((x) << GPIO_PIN5_WAKEUP_ENABLE_LSB) & GPIO_PIN5_WAKEUP_ENABLE_MASK)
-#define GPIO_PIN5_INT_TYPE_MSB                   9
-#define GPIO_PIN5_INT_TYPE_LSB                   7
-#define GPIO_PIN5_INT_TYPE_MASK                  0x00000380
-#define GPIO_PIN5_INT_TYPE_GET(x)                (((x) & GPIO_PIN5_INT_TYPE_MASK) >> GPIO_PIN5_INT_TYPE_LSB)
-#define GPIO_PIN5_INT_TYPE_SET(x)                (((x) << GPIO_PIN5_INT_TYPE_LSB) & GPIO_PIN5_INT_TYPE_MASK)
-#define GPIO_PIN5_PAD_DRIVER_MSB                 2
-#define GPIO_PIN5_PAD_DRIVER_LSB                 2
-#define GPIO_PIN5_PAD_DRIVER_MASK                0x00000004
-#define GPIO_PIN5_PAD_DRIVER_GET(x)              (((x) & GPIO_PIN5_PAD_DRIVER_MASK) >> GPIO_PIN5_PAD_DRIVER_LSB)
-#define GPIO_PIN5_PAD_DRIVER_SET(x)              (((x) << GPIO_PIN5_PAD_DRIVER_LSB) & GPIO_PIN5_PAD_DRIVER_MASK)
-#define GPIO_PIN5_SOURCE_MSB                     0
-#define GPIO_PIN5_SOURCE_LSB                     0
-#define GPIO_PIN5_SOURCE_MASK                    0x00000001
-#define GPIO_PIN5_SOURCE_GET(x)                  (((x) & GPIO_PIN5_SOURCE_MASK) >> GPIO_PIN5_SOURCE_LSB)
-#define GPIO_PIN5_SOURCE_SET(x)                  (((x) << GPIO_PIN5_SOURCE_LSB) & GPIO_PIN5_SOURCE_MASK)
-
-#define GPIO_PIN6_ADDRESS                        0x00000040
-#define GPIO_PIN6_OFFSET                         0x00000040
-#define GPIO_PIN6_CONFIG_MSB                     12
-#define GPIO_PIN6_CONFIG_LSB                     11
-#define GPIO_PIN6_CONFIG_MASK                    0x00001800
-#define GPIO_PIN6_CONFIG_GET(x)                  (((x) & GPIO_PIN6_CONFIG_MASK) >> GPIO_PIN6_CONFIG_LSB)
-#define GPIO_PIN6_CONFIG_SET(x)                  (((x) << GPIO_PIN6_CONFIG_LSB) & GPIO_PIN6_CONFIG_MASK)
-#define GPIO_PIN6_WAKEUP_ENABLE_MSB              10
-#define GPIO_PIN6_WAKEUP_ENABLE_LSB              10
-#define GPIO_PIN6_WAKEUP_ENABLE_MASK             0x00000400
-#define GPIO_PIN6_WAKEUP_ENABLE_GET(x)           (((x) & GPIO_PIN6_WAKEUP_ENABLE_MASK) >> GPIO_PIN6_WAKEUP_ENABLE_LSB)
-#define GPIO_PIN6_WAKEUP_ENABLE_SET(x)           (((x) << GPIO_PIN6_WAKEUP_ENABLE_LSB) & GPIO_PIN6_WAKEUP_ENABLE_MASK)
-#define GPIO_PIN6_INT_TYPE_MSB                   9
-#define GPIO_PIN6_INT_TYPE_LSB                   7
-#define GPIO_PIN6_INT_TYPE_MASK                  0x00000380
-#define GPIO_PIN6_INT_TYPE_GET(x)                (((x) & GPIO_PIN6_INT_TYPE_MASK) >> GPIO_PIN6_INT_TYPE_LSB)
-#define GPIO_PIN6_INT_TYPE_SET(x)                (((x) << GPIO_PIN6_INT_TYPE_LSB) & GPIO_PIN6_INT_TYPE_MASK)
-#define GPIO_PIN6_PAD_DRIVER_MSB                 2
-#define GPIO_PIN6_PAD_DRIVER_LSB                 2
-#define GPIO_PIN6_PAD_DRIVER_MASK                0x00000004
-#define GPIO_PIN6_PAD_DRIVER_GET(x)              (((x) & GPIO_PIN6_PAD_DRIVER_MASK) >> GPIO_PIN6_PAD_DRIVER_LSB)
-#define GPIO_PIN6_PAD_DRIVER_SET(x)              (((x) << GPIO_PIN6_PAD_DRIVER_LSB) & GPIO_PIN6_PAD_DRIVER_MASK)
-#define GPIO_PIN6_SOURCE_MSB                     0
-#define GPIO_PIN6_SOURCE_LSB                     0
-#define GPIO_PIN6_SOURCE_MASK                    0x00000001
-#define GPIO_PIN6_SOURCE_GET(x)                  (((x) & GPIO_PIN6_SOURCE_MASK) >> GPIO_PIN6_SOURCE_LSB)
-#define GPIO_PIN6_SOURCE_SET(x)                  (((x) << GPIO_PIN6_SOURCE_LSB) & GPIO_PIN6_SOURCE_MASK)
-
-#define GPIO_PIN7_ADDRESS                        0x00000044
-#define GPIO_PIN7_OFFSET                         0x00000044
-#define GPIO_PIN7_CONFIG_MSB                     12
-#define GPIO_PIN7_CONFIG_LSB                     11
-#define GPIO_PIN7_CONFIG_MASK                    0x00001800
-#define GPIO_PIN7_CONFIG_GET(x)                  (((x) & GPIO_PIN7_CONFIG_MASK) >> GPIO_PIN7_CONFIG_LSB)
-#define GPIO_PIN7_CONFIG_SET(x)                  (((x) << GPIO_PIN7_CONFIG_LSB) & GPIO_PIN7_CONFIG_MASK)
-#define GPIO_PIN7_WAKEUP_ENABLE_MSB              10
-#define GPIO_PIN7_WAKEUP_ENABLE_LSB              10
-#define GPIO_PIN7_WAKEUP_ENABLE_MASK             0x00000400
-#define GPIO_PIN7_WAKEUP_ENABLE_GET(x)           (((x) & GPIO_PIN7_WAKEUP_ENABLE_MASK) >> GPIO_PIN7_WAKEUP_ENABLE_LSB)
-#define GPIO_PIN7_WAKEUP_ENABLE_SET(x)           (((x) << GPIO_PIN7_WAKEUP_ENABLE_LSB) & GPIO_PIN7_WAKEUP_ENABLE_MASK)
-#define GPIO_PIN7_INT_TYPE_MSB                   9
-#define GPIO_PIN7_INT_TYPE_LSB                   7
-#define GPIO_PIN7_INT_TYPE_MASK                  0x00000380
-#define GPIO_PIN7_INT_TYPE_GET(x)                (((x) & GPIO_PIN7_INT_TYPE_MASK) >> GPIO_PIN7_INT_TYPE_LSB)
-#define GPIO_PIN7_INT_TYPE_SET(x)                (((x) << GPIO_PIN7_INT_TYPE_LSB) & GPIO_PIN7_INT_TYPE_MASK)
-#define GPIO_PIN7_PAD_DRIVER_MSB                 2
-#define GPIO_PIN7_PAD_DRIVER_LSB                 2
-#define GPIO_PIN7_PAD_DRIVER_MASK                0x00000004
-#define GPIO_PIN7_PAD_DRIVER_GET(x)              (((x) & GPIO_PIN7_PAD_DRIVER_MASK) >> GPIO_PIN7_PAD_DRIVER_LSB)
-#define GPIO_PIN7_PAD_DRIVER_SET(x)              (((x) << GPIO_PIN7_PAD_DRIVER_LSB) & GPIO_PIN7_PAD_DRIVER_MASK)
-#define GPIO_PIN7_SOURCE_MSB                     0
-#define GPIO_PIN7_SOURCE_LSB                     0
-#define GPIO_PIN7_SOURCE_MASK                    0x00000001
-#define GPIO_PIN7_SOURCE_GET(x)                  (((x) & GPIO_PIN7_SOURCE_MASK) >> GPIO_PIN7_SOURCE_LSB)
-#define GPIO_PIN7_SOURCE_SET(x)                  (((x) << GPIO_PIN7_SOURCE_LSB) & GPIO_PIN7_SOURCE_MASK)
-
-#define GPIO_PIN8_ADDRESS                        0x00000048
-#define GPIO_PIN8_OFFSET                         0x00000048
-#define GPIO_PIN8_CONFIG_MSB                     12
-#define GPIO_PIN8_CONFIG_LSB                     11
-#define GPIO_PIN8_CONFIG_MASK                    0x00001800
-#define GPIO_PIN8_CONFIG_GET(x)                  (((x) & GPIO_PIN8_CONFIG_MASK) >> GPIO_PIN8_CONFIG_LSB)
-#define GPIO_PIN8_CONFIG_SET(x)                  (((x) << GPIO_PIN8_CONFIG_LSB) & GPIO_PIN8_CONFIG_MASK)
-#define GPIO_PIN8_WAKEUP_ENABLE_MSB              10
-#define GPIO_PIN8_WAKEUP_ENABLE_LSB              10
-#define GPIO_PIN8_WAKEUP_ENABLE_MASK             0x00000400
-#define GPIO_PIN8_WAKEUP_ENABLE_GET(x)           (((x) & GPIO_PIN8_WAKEUP_ENABLE_MASK) >> GPIO_PIN8_WAKEUP_ENABLE_LSB)
-#define GPIO_PIN8_WAKEUP_ENABLE_SET(x)           (((x) << GPIO_PIN8_WAKEUP_ENABLE_LSB) & GPIO_PIN8_WAKEUP_ENABLE_MASK)
-#define GPIO_PIN8_INT_TYPE_MSB                   9
-#define GPIO_PIN8_INT_TYPE_LSB                   7
-#define GPIO_PIN8_INT_TYPE_MASK                  0x00000380
-#define GPIO_PIN8_INT_TYPE_GET(x)                (((x) & GPIO_PIN8_INT_TYPE_MASK) >> GPIO_PIN8_INT_TYPE_LSB)
-#define GPIO_PIN8_INT_TYPE_SET(x)                (((x) << GPIO_PIN8_INT_TYPE_LSB) & GPIO_PIN8_INT_TYPE_MASK)
-#define GPIO_PIN8_PAD_DRIVER_MSB                 2
-#define GPIO_PIN8_PAD_DRIVER_LSB                 2
-#define GPIO_PIN8_PAD_DRIVER_MASK                0x00000004
-#define GPIO_PIN8_PAD_DRIVER_GET(x)              (((x) & GPIO_PIN8_PAD_DRIVER_MASK) >> GPIO_PIN8_PAD_DRIVER_LSB)
-#define GPIO_PIN8_PAD_DRIVER_SET(x)              (((x) << GPIO_PIN8_PAD_DRIVER_LSB) & GPIO_PIN8_PAD_DRIVER_MASK)
-#define GPIO_PIN8_SOURCE_MSB                     0
-#define GPIO_PIN8_SOURCE_LSB                     0
-#define GPIO_PIN8_SOURCE_MASK                    0x00000001
-#define GPIO_PIN8_SOURCE_GET(x)                  (((x) & GPIO_PIN8_SOURCE_MASK) >> GPIO_PIN8_SOURCE_LSB)
-#define GPIO_PIN8_SOURCE_SET(x)                  (((x) << GPIO_PIN8_SOURCE_LSB) & GPIO_PIN8_SOURCE_MASK)
-
-#define GPIO_PIN9_ADDRESS                        0x0000004c
-#define GPIO_PIN9_OFFSET                         0x0000004c
-#define GPIO_PIN9_CONFIG_MSB                     12
-#define GPIO_PIN9_CONFIG_LSB                     11
-#define GPIO_PIN9_CONFIG_MASK                    0x00001800
-#define GPIO_PIN9_CONFIG_GET(x)                  (((x) & GPIO_PIN9_CONFIG_MASK) >> GPIO_PIN9_CONFIG_LSB)
-#define GPIO_PIN9_CONFIG_SET(x)                  (((x) << GPIO_PIN9_CONFIG_LSB) & GPIO_PIN9_CONFIG_MASK)
-#define GPIO_PIN9_WAKEUP_ENABLE_MSB              10
-#define GPIO_PIN9_WAKEUP_ENABLE_LSB              10
-#define GPIO_PIN9_WAKEUP_ENABLE_MASK             0x00000400
-#define GPIO_PIN9_WAKEUP_ENABLE_GET(x)           (((x) & GPIO_PIN9_WAKEUP_ENABLE_MASK) >> GPIO_PIN9_WAKEUP_ENABLE_LSB)
-#define GPIO_PIN9_WAKEUP_ENABLE_SET(x)           (((x) << GPIO_PIN9_WAKEUP_ENABLE_LSB) & GPIO_PIN9_WAKEUP_ENABLE_MASK)
-#define GPIO_PIN9_INT_TYPE_MSB                   9
-#define GPIO_PIN9_INT_TYPE_LSB                   7
-#define GPIO_PIN9_INT_TYPE_MASK                  0x00000380
-#define GPIO_PIN9_INT_TYPE_GET(x)                (((x) & GPIO_PIN9_INT_TYPE_MASK) >> GPIO_PIN9_INT_TYPE_LSB)
-#define GPIO_PIN9_INT_TYPE_SET(x)                (((x) << GPIO_PIN9_INT_TYPE_LSB) & GPIO_PIN9_INT_TYPE_MASK)
-#define GPIO_PIN9_PAD_DRIVER_MSB                 2
-#define GPIO_PIN9_PAD_DRIVER_LSB                 2
-#define GPIO_PIN9_PAD_DRIVER_MASK                0x00000004
-#define GPIO_PIN9_PAD_DRIVER_GET(x)              (((x) & GPIO_PIN9_PAD_DRIVER_MASK) >> GPIO_PIN9_PAD_DRIVER_LSB)
-#define GPIO_PIN9_PAD_DRIVER_SET(x)              (((x) << GPIO_PIN9_PAD_DRIVER_LSB) & GPIO_PIN9_PAD_DRIVER_MASK)
-#define GPIO_PIN9_SOURCE_MSB                     0
-#define GPIO_PIN9_SOURCE_LSB                     0
-#define GPIO_PIN9_SOURCE_MASK                    0x00000001
-#define GPIO_PIN9_SOURCE_GET(x)                  (((x) & GPIO_PIN9_SOURCE_MASK) >> GPIO_PIN9_SOURCE_LSB)
-#define GPIO_PIN9_SOURCE_SET(x)                  (((x) << GPIO_PIN9_SOURCE_LSB) & GPIO_PIN9_SOURCE_MASK)
-
-#define GPIO_PIN10_ADDRESS                       0x00000050
-#define GPIO_PIN10_OFFSET                        0x00000050
-#define GPIO_PIN10_CONFIG_MSB                    12
-#define GPIO_PIN10_CONFIG_LSB                    11
-#define GPIO_PIN10_CONFIG_MASK                   0x00001800
-#define GPIO_PIN10_CONFIG_GET(x)                 (((x) & GPIO_PIN10_CONFIG_MASK) >> GPIO_PIN10_CONFIG_LSB)
-#define GPIO_PIN10_CONFIG_SET(x)                 (((x) << GPIO_PIN10_CONFIG_LSB) & GPIO_PIN10_CONFIG_MASK)
-#define GPIO_PIN10_WAKEUP_ENABLE_MSB             10
-#define GPIO_PIN10_WAKEUP_ENABLE_LSB             10
-#define GPIO_PIN10_WAKEUP_ENABLE_MASK            0x00000400
-#define GPIO_PIN10_WAKEUP_ENABLE_GET(x)          (((x) & GPIO_PIN10_WAKEUP_ENABLE_MASK) >> GPIO_PIN10_WAKEUP_ENABLE_LSB)
-#define GPIO_PIN10_WAKEUP_ENABLE_SET(x)          (((x) << GPIO_PIN10_WAKEUP_ENABLE_LSB) & GPIO_PIN10_WAKEUP_ENABLE_MASK)
-#define GPIO_PIN10_INT_TYPE_MSB                  9
-#define GPIO_PIN10_INT_TYPE_LSB                  7
-#define GPIO_PIN10_INT_TYPE_MASK                 0x00000380
-#define GPIO_PIN10_INT_TYPE_GET(x)               (((x) & GPIO_PIN10_INT_TYPE_MASK) >> GPIO_PIN10_INT_TYPE_LSB)
-#define GPIO_PIN10_INT_TYPE_SET(x)               (((x) << GPIO_PIN10_INT_TYPE_LSB) & GPIO_PIN10_INT_TYPE_MASK)
-#define GPIO_PIN10_PAD_DRIVER_MSB                2
-#define GPIO_PIN10_PAD_DRIVER_LSB                2
-#define GPIO_PIN10_PAD_DRIVER_MASK               0x00000004
-#define GPIO_PIN10_PAD_DRIVER_GET(x)             (((x) & GPIO_PIN10_PAD_DRIVER_MASK) >> GPIO_PIN10_PAD_DRIVER_LSB)
-#define GPIO_PIN10_PAD_DRIVER_SET(x)             (((x) << GPIO_PIN10_PAD_DRIVER_LSB) & GPIO_PIN10_PAD_DRIVER_MASK)
-#define GPIO_PIN10_SOURCE_MSB                    0
-#define GPIO_PIN10_SOURCE_LSB                    0
-#define GPIO_PIN10_SOURCE_MASK                   0x00000001
-#define GPIO_PIN10_SOURCE_GET(x)                 (((x) & GPIO_PIN10_SOURCE_MASK) >> GPIO_PIN10_SOURCE_LSB)
-#define GPIO_PIN10_SOURCE_SET(x)                 (((x) << GPIO_PIN10_SOURCE_LSB) & GPIO_PIN10_SOURCE_MASK)
-
-#define GPIO_PIN11_ADDRESS                       0x00000054
-#define GPIO_PIN11_OFFSET                        0x00000054
-#define GPIO_PIN11_CONFIG_MSB                    12
-#define GPIO_PIN11_CONFIG_LSB                    11
-#define GPIO_PIN11_CONFIG_MASK                   0x00001800
-#define GPIO_PIN11_CONFIG_GET(x)                 (((x) & GPIO_PIN11_CONFIG_MASK) >> GPIO_PIN11_CONFIG_LSB)
-#define GPIO_PIN11_CONFIG_SET(x)                 (((x) << GPIO_PIN11_CONFIG_LSB) & GPIO_PIN11_CONFIG_MASK)
-#define GPIO_PIN11_WAKEUP_ENABLE_MSB             10
-#define GPIO_PIN11_WAKEUP_ENABLE_LSB             10
-#define GPIO_PIN11_WAKEUP_ENABLE_MASK            0x00000400
-#define GPIO_PIN11_WAKEUP_ENABLE_GET(x)          (((x) & GPIO_PIN11_WAKEUP_ENABLE_MASK) >> GPIO_PIN11_WAKEUP_ENABLE_LSB)
-#define GPIO_PIN11_WAKEUP_ENABLE_SET(x)          (((x) << GPIO_PIN11_WAKEUP_ENABLE_LSB) & GPIO_PIN11_WAKEUP_ENABLE_MASK)
-#define GPIO_PIN11_INT_TYPE_MSB                  9
-#define GPIO_PIN11_INT_TYPE_LSB                  7
-#define GPIO_PIN11_INT_TYPE_MASK                 0x00000380
-#define GPIO_PIN11_INT_TYPE_GET(x)               (((x) & GPIO_PIN11_INT_TYPE_MASK) >> GPIO_PIN11_INT_TYPE_LSB)
-#define GPIO_PIN11_INT_TYPE_SET(x)               (((x) << GPIO_PIN11_INT_TYPE_LSB) & GPIO_PIN11_INT_TYPE_MASK)
-#define GPIO_PIN11_PAD_DRIVER_MSB                2
-#define GPIO_PIN11_PAD_DRIVER_LSB                2
-#define GPIO_PIN11_PAD_DRIVER_MASK               0x00000004
-#define GPIO_PIN11_PAD_DRIVER_GET(x)             (((x) & GPIO_PIN11_PAD_DRIVER_MASK) >> GPIO_PIN11_PAD_DRIVER_LSB)
-#define GPIO_PIN11_PAD_DRIVER_SET(x)             (((x) << GPIO_PIN11_PAD_DRIVER_LSB) & GPIO_PIN11_PAD_DRIVER_MASK)
-#define GPIO_PIN11_SOURCE_MSB                    0
-#define GPIO_PIN11_SOURCE_LSB                    0
-#define GPIO_PIN11_SOURCE_MASK                   0x00000001
-#define GPIO_PIN11_SOURCE_GET(x)                 (((x) & GPIO_PIN11_SOURCE_MASK) >> GPIO_PIN11_SOURCE_LSB)
-#define GPIO_PIN11_SOURCE_SET(x)                 (((x) << GPIO_PIN11_SOURCE_LSB) & GPIO_PIN11_SOURCE_MASK)
-
-#define GPIO_PIN12_ADDRESS                       0x00000058
-#define GPIO_PIN12_OFFSET                        0x00000058
-#define GPIO_PIN12_CONFIG_MSB                    12
-#define GPIO_PIN12_CONFIG_LSB                    11
-#define GPIO_PIN12_CONFIG_MASK                   0x00001800
-#define GPIO_PIN12_CONFIG_GET(x)                 (((x) & GPIO_PIN12_CONFIG_MASK) >> GPIO_PIN12_CONFIG_LSB)
-#define GPIO_PIN12_CONFIG_SET(x)                 (((x) << GPIO_PIN12_CONFIG_LSB) & GPIO_PIN12_CONFIG_MASK)
-#define GPIO_PIN12_WAKEUP_ENABLE_MSB             10
-#define GPIO_PIN12_WAKEUP_ENABLE_LSB             10
-#define GPIO_PIN12_WAKEUP_ENABLE_MASK            0x00000400
-#define GPIO_PIN12_WAKEUP_ENABLE_GET(x)          (((x) & GPIO_PIN12_WAKEUP_ENABLE_MASK) >> GPIO_PIN12_WAKEUP_ENABLE_LSB)
-#define GPIO_PIN12_WAKEUP_ENABLE_SET(x)          (((x) << GPIO_PIN12_WAKEUP_ENABLE_LSB) & GPIO_PIN12_WAKEUP_ENABLE_MASK)
-#define GPIO_PIN12_INT_TYPE_MSB                  9
-#define GPIO_PIN12_INT_TYPE_LSB                  7
-#define GPIO_PIN12_INT_TYPE_MASK                 0x00000380
-#define GPIO_PIN12_INT_TYPE_GET(x)               (((x) & GPIO_PIN12_INT_TYPE_MASK) >> GPIO_PIN12_INT_TYPE_LSB)
-#define GPIO_PIN12_INT_TYPE_SET(x)               (((x) << GPIO_PIN12_INT_TYPE_LSB) & GPIO_PIN12_INT_TYPE_MASK)
-#define GPIO_PIN12_PAD_DRIVER_MSB                2
-#define GPIO_PIN12_PAD_DRIVER_LSB                2
-#define GPIO_PIN12_PAD_DRIVER_MASK               0x00000004
-#define GPIO_PIN12_PAD_DRIVER_GET(x)             (((x) & GPIO_PIN12_PAD_DRIVER_MASK) >> GPIO_PIN12_PAD_DRIVER_LSB)
-#define GPIO_PIN12_PAD_DRIVER_SET(x)             (((x) << GPIO_PIN12_PAD_DRIVER_LSB) & GPIO_PIN12_PAD_DRIVER_MASK)
-#define GPIO_PIN12_SOURCE_MSB                    0
-#define GPIO_PIN12_SOURCE_LSB                    0
-#define GPIO_PIN12_SOURCE_MASK                   0x00000001
-#define GPIO_PIN12_SOURCE_GET(x)                 (((x) & GPIO_PIN12_SOURCE_MASK) >> GPIO_PIN12_SOURCE_LSB)
-#define GPIO_PIN12_SOURCE_SET(x)                 (((x) << GPIO_PIN12_SOURCE_LSB) & GPIO_PIN12_SOURCE_MASK)
-
-#define GPIO_PIN13_ADDRESS                       0x0000005c
-#define GPIO_PIN13_OFFSET                        0x0000005c
-#define GPIO_PIN13_CONFIG_MSB                    12
-#define GPIO_PIN13_CONFIG_LSB                    11
-#define GPIO_PIN13_CONFIG_MASK                   0x00001800
-#define GPIO_PIN13_CONFIG_GET(x)                 (((x) & GPIO_PIN13_CONFIG_MASK) >> GPIO_PIN13_CONFIG_LSB)
-#define GPIO_PIN13_CONFIG_SET(x)                 (((x) << GPIO_PIN13_CONFIG_LSB) & GPIO_PIN13_CONFIG_MASK)
-#define GPIO_PIN13_WAKEUP_ENABLE_MSB             10
-#define GPIO_PIN13_WAKEUP_ENABLE_LSB             10
-#define GPIO_PIN13_WAKEUP_ENABLE_MASK            0x00000400
-#define GPIO_PIN13_WAKEUP_ENABLE_GET(x)          (((x) & GPIO_PIN13_WAKEUP_ENABLE_MASK) >> GPIO_PIN13_WAKEUP_ENABLE_LSB)
-#define GPIO_PIN13_WAKEUP_ENABLE_SET(x)          (((x) << GPIO_PIN13_WAKEUP_ENABLE_LSB) & GPIO_PIN13_WAKEUP_ENABLE_MASK)
-#define GPIO_PIN13_INT_TYPE_MSB                  9
-#define GPIO_PIN13_INT_TYPE_LSB                  7
-#define GPIO_PIN13_INT_TYPE_MASK                 0x00000380
-#define GPIO_PIN13_INT_TYPE_GET(x)               (((x) & GPIO_PIN13_INT_TYPE_MASK) >> GPIO_PIN13_INT_TYPE_LSB)
-#define GPIO_PIN13_INT_TYPE_SET(x)               (((x) << GPIO_PIN13_INT_TYPE_LSB) & GPIO_PIN13_INT_TYPE_MASK)
-#define GPIO_PIN13_PAD_DRIVER_MSB                2
-#define GPIO_PIN13_PAD_DRIVER_LSB                2
-#define GPIO_PIN13_PAD_DRIVER_MASK               0x00000004
-#define GPIO_PIN13_PAD_DRIVER_GET(x)             (((x) & GPIO_PIN13_PAD_DRIVER_MASK) >> GPIO_PIN13_PAD_DRIVER_LSB)
-#define GPIO_PIN13_PAD_DRIVER_SET(x)             (((x) << GPIO_PIN13_PAD_DRIVER_LSB) & GPIO_PIN13_PAD_DRIVER_MASK)
-#define GPIO_PIN13_SOURCE_MSB                    0
-#define GPIO_PIN13_SOURCE_LSB                    0
-#define GPIO_PIN13_SOURCE_MASK                   0x00000001
-#define GPIO_PIN13_SOURCE_GET(x)                 (((x) & GPIO_PIN13_SOURCE_MASK) >> GPIO_PIN13_SOURCE_LSB)
-#define GPIO_PIN13_SOURCE_SET(x)                 (((x) << GPIO_PIN13_SOURCE_LSB) & GPIO_PIN13_SOURCE_MASK)
-
-#define GPIO_PIN14_ADDRESS                       0x00000060
-#define GPIO_PIN14_OFFSET                        0x00000060
-#define GPIO_PIN14_CONFIG_MSB                    12
-#define GPIO_PIN14_CONFIG_LSB                    11
-#define GPIO_PIN14_CONFIG_MASK                   0x00001800
-#define GPIO_PIN14_CONFIG_GET(x)                 (((x) & GPIO_PIN14_CONFIG_MASK) >> GPIO_PIN14_CONFIG_LSB)
-#define GPIO_PIN14_CONFIG_SET(x)                 (((x) << GPIO_PIN14_CONFIG_LSB) & GPIO_PIN14_CONFIG_MASK)
-#define GPIO_PIN14_WAKEUP_ENABLE_MSB             10
-#define GPIO_PIN14_WAKEUP_ENABLE_LSB             10
-#define GPIO_PIN14_WAKEUP_ENABLE_MASK            0x00000400
-#define GPIO_PIN14_WAKEUP_ENABLE_GET(x)          (((x) & GPIO_PIN14_WAKEUP_ENABLE_MASK) >> GPIO_PIN14_WAKEUP_ENABLE_LSB)
-#define GPIO_PIN14_WAKEUP_ENABLE_SET(x)          (((x) << GPIO_PIN14_WAKEUP_ENABLE_LSB) & GPIO_PIN14_WAKEUP_ENABLE_MASK)
-#define GPIO_PIN14_INT_TYPE_MSB                  9
-#define GPIO_PIN14_INT_TYPE_LSB                  7
-#define GPIO_PIN14_INT_TYPE_MASK                 0x00000380
-#define GPIO_PIN14_INT_TYPE_GET(x)               (((x) & GPIO_PIN14_INT_TYPE_MASK) >> GPIO_PIN14_INT_TYPE_LSB)
-#define GPIO_PIN14_INT_TYPE_SET(x)               (((x) << GPIO_PIN14_INT_TYPE_LSB) & GPIO_PIN14_INT_TYPE_MASK)
-#define GPIO_PIN14_PAD_DRIVER_MSB                2
-#define GPIO_PIN14_PAD_DRIVER_LSB                2
-#define GPIO_PIN14_PAD_DRIVER_MASK               0x00000004
-#define GPIO_PIN14_PAD_DRIVER_GET(x)             (((x) & GPIO_PIN14_PAD_DRIVER_MASK) >> GPIO_PIN14_PAD_DRIVER_LSB)
-#define GPIO_PIN14_PAD_DRIVER_SET(x)             (((x) << GPIO_PIN14_PAD_DRIVER_LSB) & GPIO_PIN14_PAD_DRIVER_MASK)
-#define GPIO_PIN14_SOURCE_MSB                    0
-#define GPIO_PIN14_SOURCE_LSB                    0
-#define GPIO_PIN14_SOURCE_MASK                   0x00000001
-#define GPIO_PIN14_SOURCE_GET(x)                 (((x) & GPIO_PIN14_SOURCE_MASK) >> GPIO_PIN14_SOURCE_LSB)
-#define GPIO_PIN14_SOURCE_SET(x)                 (((x) << GPIO_PIN14_SOURCE_LSB) & GPIO_PIN14_SOURCE_MASK)
-
-#define GPIO_PIN15_ADDRESS                       0x00000064
-#define GPIO_PIN15_OFFSET                        0x00000064
-#define GPIO_PIN15_CONFIG_MSB                    12
-#define GPIO_PIN15_CONFIG_LSB                    11
-#define GPIO_PIN15_CONFIG_MASK                   0x00001800
-#define GPIO_PIN15_CONFIG_GET(x)                 (((x) & GPIO_PIN15_CONFIG_MASK) >> GPIO_PIN15_CONFIG_LSB)
-#define GPIO_PIN15_CONFIG_SET(x)                 (((x) << GPIO_PIN15_CONFIG_LSB) & GPIO_PIN15_CONFIG_MASK)
-#define GPIO_PIN15_WAKEUP_ENABLE_MSB             10
-#define GPIO_PIN15_WAKEUP_ENABLE_LSB             10
-#define GPIO_PIN15_WAKEUP_ENABLE_MASK            0x00000400
-#define GPIO_PIN15_WAKEUP_ENABLE_GET(x)          (((x) & GPIO_PIN15_WAKEUP_ENABLE_MASK) >> GPIO_PIN15_WAKEUP_ENABLE_LSB)
-#define GPIO_PIN15_WAKEUP_ENABLE_SET(x)          (((x) << GPIO_PIN15_WAKEUP_ENABLE_LSB) & GPIO_PIN15_WAKEUP_ENABLE_MASK)
-#define GPIO_PIN15_INT_TYPE_MSB                  9
-#define GPIO_PIN15_INT_TYPE_LSB                  7
-#define GPIO_PIN15_INT_TYPE_MASK                 0x00000380
-#define GPIO_PIN15_INT_TYPE_GET(x)               (((x) & GPIO_PIN15_INT_TYPE_MASK) >> GPIO_PIN15_INT_TYPE_LSB)
-#define GPIO_PIN15_INT_TYPE_SET(x)               (((x) << GPIO_PIN15_INT_TYPE_LSB) & GPIO_PIN15_INT_TYPE_MASK)
-#define GPIO_PIN15_PAD_DRIVER_MSB                2
-#define GPIO_PIN15_PAD_DRIVER_LSB                2
-#define GPIO_PIN15_PAD_DRIVER_MASK               0x00000004
-#define GPIO_PIN15_PAD_DRIVER_GET(x)             (((x) & GPIO_PIN15_PAD_DRIVER_MASK) >> GPIO_PIN15_PAD_DRIVER_LSB)
-#define GPIO_PIN15_PAD_DRIVER_SET(x)             (((x) << GPIO_PIN15_PAD_DRIVER_LSB) & GPIO_PIN15_PAD_DRIVER_MASK)
-#define GPIO_PIN15_SOURCE_MSB                    0
-#define GPIO_PIN15_SOURCE_LSB                    0
-#define GPIO_PIN15_SOURCE_MASK                   0x00000001
-#define GPIO_PIN15_SOURCE_GET(x)                 (((x) & GPIO_PIN15_SOURCE_MASK) >> GPIO_PIN15_SOURCE_LSB)
-#define GPIO_PIN15_SOURCE_SET(x)                 (((x) << GPIO_PIN15_SOURCE_LSB) & GPIO_PIN15_SOURCE_MASK)
-
-#define GPIO_PIN16_ADDRESS                       0x00000068
-#define GPIO_PIN16_OFFSET                        0x00000068
-#define GPIO_PIN16_CONFIG_MSB                    12
-#define GPIO_PIN16_CONFIG_LSB                    11
-#define GPIO_PIN16_CONFIG_MASK                   0x00001800
-#define GPIO_PIN16_CONFIG_GET(x)                 (((x) & GPIO_PIN16_CONFIG_MASK) >> GPIO_PIN16_CONFIG_LSB)
-#define GPIO_PIN16_CONFIG_SET(x)                 (((x) << GPIO_PIN16_CONFIG_LSB) & GPIO_PIN16_CONFIG_MASK)
-#define GPIO_PIN16_WAKEUP_ENABLE_MSB             10
-#define GPIO_PIN16_WAKEUP_ENABLE_LSB             10
-#define GPIO_PIN16_WAKEUP_ENABLE_MASK            0x00000400
-#define GPIO_PIN16_WAKEUP_ENABLE_GET(x)          (((x) & GPIO_PIN16_WAKEUP_ENABLE_MASK) >> GPIO_PIN16_WAKEUP_ENABLE_LSB)
-#define GPIO_PIN16_WAKEUP_ENABLE_SET(x)          (((x) << GPIO_PIN16_WAKEUP_ENABLE_LSB) & GPIO_PIN16_WAKEUP_ENABLE_MASK)
-#define GPIO_PIN16_INT_TYPE_MSB                  9
-#define GPIO_PIN16_INT_TYPE_LSB                  7
-#define GPIO_PIN16_INT_TYPE_MASK                 0x00000380
-#define GPIO_PIN16_INT_TYPE_GET(x)               (((x) & GPIO_PIN16_INT_TYPE_MASK) >> GPIO_PIN16_INT_TYPE_LSB)
-#define GPIO_PIN16_INT_TYPE_SET(x)               (((x) << GPIO_PIN16_INT_TYPE_LSB) & GPIO_PIN16_INT_TYPE_MASK)
-#define GPIO_PIN16_PAD_DRIVER_MSB                2
-#define GPIO_PIN16_PAD_DRIVER_LSB                2
-#define GPIO_PIN16_PAD_DRIVER_MASK               0x00000004
-#define GPIO_PIN16_PAD_DRIVER_GET(x)             (((x) & GPIO_PIN16_PAD_DRIVER_MASK) >> GPIO_PIN16_PAD_DRIVER_LSB)
-#define GPIO_PIN16_PAD_DRIVER_SET(x)             (((x) << GPIO_PIN16_PAD_DRIVER_LSB) & GPIO_PIN16_PAD_DRIVER_MASK)
-#define GPIO_PIN16_SOURCE_MSB                    0
-#define GPIO_PIN16_SOURCE_LSB                    0
-#define GPIO_PIN16_SOURCE_MASK                   0x00000001
-#define GPIO_PIN16_SOURCE_GET(x)                 (((x) & GPIO_PIN16_SOURCE_MASK) >> GPIO_PIN16_SOURCE_LSB)
-#define GPIO_PIN16_SOURCE_SET(x)                 (((x) << GPIO_PIN16_SOURCE_LSB) & GPIO_PIN16_SOURCE_MASK)
-
-#define GPIO_PIN17_ADDRESS                       0x0000006c
-#define GPIO_PIN17_OFFSET                        0x0000006c
-#define GPIO_PIN17_CONFIG_MSB                    12
-#define GPIO_PIN17_CONFIG_LSB                    11
-#define GPIO_PIN17_CONFIG_MASK                   0x00001800
-#define GPIO_PIN17_CONFIG_GET(x)                 (((x) & GPIO_PIN17_CONFIG_MASK) >> GPIO_PIN17_CONFIG_LSB)
-#define GPIO_PIN17_CONFIG_SET(x)                 (((x) << GPIO_PIN17_CONFIG_LSB) & GPIO_PIN17_CONFIG_MASK)
-#define GPIO_PIN17_WAKEUP_ENABLE_MSB             10
-#define GPIO_PIN17_WAKEUP_ENABLE_LSB             10
-#define GPIO_PIN17_WAKEUP_ENABLE_MASK            0x00000400
-#define GPIO_PIN17_WAKEUP_ENABLE_GET(x)          (((x) & GPIO_PIN17_WAKEUP_ENABLE_MASK) >> GPIO_PIN17_WAKEUP_ENABLE_LSB)
-#define GPIO_PIN17_WAKEUP_ENABLE_SET(x)          (((x) << GPIO_PIN17_WAKEUP_ENABLE_LSB) & GPIO_PIN17_WAKEUP_ENABLE_MASK)
-#define GPIO_PIN17_INT_TYPE_MSB                  9
-#define GPIO_PIN17_INT_TYPE_LSB                  7
-#define GPIO_PIN17_INT_TYPE_MASK                 0x00000380
-#define GPIO_PIN17_INT_TYPE_GET(x)               (((x) & GPIO_PIN17_INT_TYPE_MASK) >> GPIO_PIN17_INT_TYPE_LSB)
-#define GPIO_PIN17_INT_TYPE_SET(x)               (((x) << GPIO_PIN17_INT_TYPE_LSB) & GPIO_PIN17_INT_TYPE_MASK)
-#define GPIO_PIN17_PAD_DRIVER_MSB                2
-#define GPIO_PIN17_PAD_DRIVER_LSB                2
-#define GPIO_PIN17_PAD_DRIVER_MASK               0x00000004
-#define GPIO_PIN17_PAD_DRIVER_GET(x)             (((x) & GPIO_PIN17_PAD_DRIVER_MASK) >> GPIO_PIN17_PAD_DRIVER_LSB)
-#define GPIO_PIN17_PAD_DRIVER_SET(x)             (((x) << GPIO_PIN17_PAD_DRIVER_LSB) & GPIO_PIN17_PAD_DRIVER_MASK)
-#define GPIO_PIN17_SOURCE_MSB                    0
-#define GPIO_PIN17_SOURCE_LSB                    0
-#define GPIO_PIN17_SOURCE_MASK                   0x00000001
-#define GPIO_PIN17_SOURCE_GET(x)                 (((x) & GPIO_PIN17_SOURCE_MASK) >> GPIO_PIN17_SOURCE_LSB)
-#define GPIO_PIN17_SOURCE_SET(x)                 (((x) << GPIO_PIN17_SOURCE_LSB) & GPIO_PIN17_SOURCE_MASK)
-
-#define SDIO_PIN_ADDRESS                         0x00000070
-#define SDIO_PIN_OFFSET                          0x00000070
-#define SDIO_PIN_PAD_PULL_MSB                    3
-#define SDIO_PIN_PAD_PULL_LSB                    2
-#define SDIO_PIN_PAD_PULL_MASK                   0x0000000c
-#define SDIO_PIN_PAD_PULL_GET(x)                 (((x) & SDIO_PIN_PAD_PULL_MASK) >> SDIO_PIN_PAD_PULL_LSB)
-#define SDIO_PIN_PAD_PULL_SET(x)                 (((x) << SDIO_PIN_PAD_PULL_LSB) & SDIO_PIN_PAD_PULL_MASK)
-#define SDIO_PIN_PAD_STRENGTH_MSB                1
-#define SDIO_PIN_PAD_STRENGTH_LSB                0
-#define SDIO_PIN_PAD_STRENGTH_MASK               0x00000003
-#define SDIO_PIN_PAD_STRENGTH_GET(x)             (((x) & SDIO_PIN_PAD_STRENGTH_MASK) >> SDIO_PIN_PAD_STRENGTH_LSB)
-#define SDIO_PIN_PAD_STRENGTH_SET(x)             (((x) << SDIO_PIN_PAD_STRENGTH_LSB) & SDIO_PIN_PAD_STRENGTH_MASK)
-
-#define CLK_REQ_PIN_ADDRESS                      0x00000074
-#define CLK_REQ_PIN_OFFSET                       0x00000074
-#define CLK_REQ_PIN_ATE_OE_L_MSB                 4
-#define CLK_REQ_PIN_ATE_OE_L_LSB                 4
-#define CLK_REQ_PIN_ATE_OE_L_MASK                0x00000010
-#define CLK_REQ_PIN_ATE_OE_L_GET(x)              (((x) & CLK_REQ_PIN_ATE_OE_L_MASK) >> CLK_REQ_PIN_ATE_OE_L_LSB)
-#define CLK_REQ_PIN_ATE_OE_L_SET(x)              (((x) << CLK_REQ_PIN_ATE_OE_L_LSB) & CLK_REQ_PIN_ATE_OE_L_MASK)
-#define CLK_REQ_PIN_PAD_PULL_MSB                 3
-#define CLK_REQ_PIN_PAD_PULL_LSB                 2
-#define CLK_REQ_PIN_PAD_PULL_MASK                0x0000000c
-#define CLK_REQ_PIN_PAD_PULL_GET(x)              (((x) & CLK_REQ_PIN_PAD_PULL_MASK) >> CLK_REQ_PIN_PAD_PULL_LSB)
-#define CLK_REQ_PIN_PAD_PULL_SET(x)              (((x) << CLK_REQ_PIN_PAD_PULL_LSB) & CLK_REQ_PIN_PAD_PULL_MASK)
-#define CLK_REQ_PIN_PAD_STRENGTH_MSB             1
-#define CLK_REQ_PIN_PAD_STRENGTH_LSB             0
-#define CLK_REQ_PIN_PAD_STRENGTH_MASK            0x00000003
-#define CLK_REQ_PIN_PAD_STRENGTH_GET(x)          (((x) & CLK_REQ_PIN_PAD_STRENGTH_MASK) >> CLK_REQ_PIN_PAD_STRENGTH_LSB)
-#define CLK_REQ_PIN_PAD_STRENGTH_SET(x)          (((x) << CLK_REQ_PIN_PAD_STRENGTH_LSB) & CLK_REQ_PIN_PAD_STRENGTH_MASK)
-
-#define SIGMA_DELTA_ADDRESS                      0x00000078
-#define SIGMA_DELTA_OFFSET                       0x00000078
-#define SIGMA_DELTA_ENABLE_MSB                   16
-#define SIGMA_DELTA_ENABLE_LSB                   16
-#define SIGMA_DELTA_ENABLE_MASK                  0x00010000
-#define SIGMA_DELTA_ENABLE_GET(x)                (((x) & SIGMA_DELTA_ENABLE_MASK) >> SIGMA_DELTA_ENABLE_LSB)
-#define SIGMA_DELTA_ENABLE_SET(x)                (((x) << SIGMA_DELTA_ENABLE_LSB) & SIGMA_DELTA_ENABLE_MASK)
-#define SIGMA_DELTA_PRESCALAR_MSB                15
-#define SIGMA_DELTA_PRESCALAR_LSB                8
-#define SIGMA_DELTA_PRESCALAR_MASK               0x0000ff00
-#define SIGMA_DELTA_PRESCALAR_GET(x)             (((x) & SIGMA_DELTA_PRESCALAR_MASK) >> SIGMA_DELTA_PRESCALAR_LSB)
-#define SIGMA_DELTA_PRESCALAR_SET(x)             (((x) << SIGMA_DELTA_PRESCALAR_LSB) & SIGMA_DELTA_PRESCALAR_MASK)
-#define SIGMA_DELTA_TARGET_MSB                   7
-#define SIGMA_DELTA_TARGET_LSB                   0
-#define SIGMA_DELTA_TARGET_MASK                  0x000000ff
-#define SIGMA_DELTA_TARGET_GET(x)                (((x) & SIGMA_DELTA_TARGET_MASK) >> SIGMA_DELTA_TARGET_LSB)
-#define SIGMA_DELTA_TARGET_SET(x)                (((x) << SIGMA_DELTA_TARGET_LSB) & SIGMA_DELTA_TARGET_MASK)
-
-#define DEBUG_CONTROL_ADDRESS                    0x0000007c
-#define DEBUG_CONTROL_OFFSET                     0x0000007c
-#define DEBUG_CONTROL_OBS_OE_L_MSB               1
-#define DEBUG_CONTROL_OBS_OE_L_LSB               1
-#define DEBUG_CONTROL_OBS_OE_L_MASK              0x00000002
-#define DEBUG_CONTROL_OBS_OE_L_GET(x)            (((x) & DEBUG_CONTROL_OBS_OE_L_MASK) >> DEBUG_CONTROL_OBS_OE_L_LSB)
-#define DEBUG_CONTROL_OBS_OE_L_SET(x)            (((x) << DEBUG_CONTROL_OBS_OE_L_LSB) & DEBUG_CONTROL_OBS_OE_L_MASK)
-#define DEBUG_CONTROL_ENABLE_MSB                 0
-#define DEBUG_CONTROL_ENABLE_LSB                 0
-#define DEBUG_CONTROL_ENABLE_MASK                0x00000001
-#define DEBUG_CONTROL_ENABLE_GET(x)              (((x) & DEBUG_CONTROL_ENABLE_MASK) >> DEBUG_CONTROL_ENABLE_LSB)
-#define DEBUG_CONTROL_ENABLE_SET(x)              (((x) << DEBUG_CONTROL_ENABLE_LSB) & DEBUG_CONTROL_ENABLE_MASK)
-
-#define DEBUG_INPUT_SEL_ADDRESS                  0x00000080
-#define DEBUG_INPUT_SEL_OFFSET                   0x00000080
-#define DEBUG_INPUT_SEL_SRC_MSB                  3
-#define DEBUG_INPUT_SEL_SRC_LSB                  0
-#define DEBUG_INPUT_SEL_SRC_MASK                 0x0000000f
-#define DEBUG_INPUT_SEL_SRC_GET(x)               (((x) & DEBUG_INPUT_SEL_SRC_MASK) >> DEBUG_INPUT_SEL_SRC_LSB)
-#define DEBUG_INPUT_SEL_SRC_SET(x)               (((x) << DEBUG_INPUT_SEL_SRC_LSB) & DEBUG_INPUT_SEL_SRC_MASK)
-
-#define DEBUG_OUT_ADDRESS                        0x00000084
-#define DEBUG_OUT_OFFSET                         0x00000084
-#define DEBUG_OUT_DATA_MSB                       17
-#define DEBUG_OUT_DATA_LSB                       0
-#define DEBUG_OUT_DATA_MASK                      0x0003ffff
-#define DEBUG_OUT_DATA_GET(x)                    (((x) & DEBUG_OUT_DATA_MASK) >> DEBUG_OUT_DATA_LSB)
-#define DEBUG_OUT_DATA_SET(x)                    (((x) << DEBUG_OUT_DATA_LSB) & DEBUG_OUT_DATA_MASK)
-
-#define LA_CONTROL_ADDRESS                       0x00000088
-#define LA_CONTROL_OFFSET                        0x00000088
-#define LA_CONTROL_RUN_MSB                       1
-#define LA_CONTROL_RUN_LSB                       1
-#define LA_CONTROL_RUN_MASK                      0x00000002
-#define LA_CONTROL_RUN_GET(x)                    (((x) & LA_CONTROL_RUN_MASK) >> LA_CONTROL_RUN_LSB)
-#define LA_CONTROL_RUN_SET(x)                    (((x) << LA_CONTROL_RUN_LSB) & LA_CONTROL_RUN_MASK)
-#define LA_CONTROL_TRIGGERED_MSB                 0
-#define LA_CONTROL_TRIGGERED_LSB                 0
-#define LA_CONTROL_TRIGGERED_MASK                0x00000001
-#define LA_CONTROL_TRIGGERED_GET(x)              (((x) & LA_CONTROL_TRIGGERED_MASK) >> LA_CONTROL_TRIGGERED_LSB)
-#define LA_CONTROL_TRIGGERED_SET(x)              (((x) << LA_CONTROL_TRIGGERED_LSB) & LA_CONTROL_TRIGGERED_MASK)
-
-#define LA_CLOCK_ADDRESS                         0x0000008c
-#define LA_CLOCK_OFFSET                          0x0000008c
-#define LA_CLOCK_DIV_MSB                         7
-#define LA_CLOCK_DIV_LSB                         0
-#define LA_CLOCK_DIV_MASK                        0x000000ff
-#define LA_CLOCK_DIV_GET(x)                      (((x) & LA_CLOCK_DIV_MASK) >> LA_CLOCK_DIV_LSB)
-#define LA_CLOCK_DIV_SET(x)                      (((x) << LA_CLOCK_DIV_LSB) & LA_CLOCK_DIV_MASK)
-
-#define LA_STATUS_ADDRESS                        0x00000090
-#define LA_STATUS_OFFSET                         0x00000090
-#define LA_STATUS_INTERRUPT_MSB                  0
-#define LA_STATUS_INTERRUPT_LSB                  0
-#define LA_STATUS_INTERRUPT_MASK                 0x00000001
-#define LA_STATUS_INTERRUPT_GET(x)               (((x) & LA_STATUS_INTERRUPT_MASK) >> LA_STATUS_INTERRUPT_LSB)
-#define LA_STATUS_INTERRUPT_SET(x)               (((x) << LA_STATUS_INTERRUPT_LSB) & LA_STATUS_INTERRUPT_MASK)
-
-#define LA_TRIGGER_SAMPLE_ADDRESS                0x00000094
-#define LA_TRIGGER_SAMPLE_OFFSET                 0x00000094
-#define LA_TRIGGER_SAMPLE_COUNT_MSB              15
-#define LA_TRIGGER_SAMPLE_COUNT_LSB              0
-#define LA_TRIGGER_SAMPLE_COUNT_MASK             0x0000ffff
-#define LA_TRIGGER_SAMPLE_COUNT_GET(x)           (((x) & LA_TRIGGER_SAMPLE_COUNT_MASK) >> LA_TRIGGER_SAMPLE_COUNT_LSB)
-#define LA_TRIGGER_SAMPLE_COUNT_SET(x)           (((x) << LA_TRIGGER_SAMPLE_COUNT_LSB) & LA_TRIGGER_SAMPLE_COUNT_MASK)
-
-#define LA_TRIGGER_POSITION_ADDRESS              0x00000098
-#define LA_TRIGGER_POSITION_OFFSET               0x00000098
-#define LA_TRIGGER_POSITION_VALUE_MSB            15
-#define LA_TRIGGER_POSITION_VALUE_LSB            0
-#define LA_TRIGGER_POSITION_VALUE_MASK           0x0000ffff
-#define LA_TRIGGER_POSITION_VALUE_GET(x)         (((x) & LA_TRIGGER_POSITION_VALUE_MASK) >> LA_TRIGGER_POSITION_VALUE_LSB)
-#define LA_TRIGGER_POSITION_VALUE_SET(x)         (((x) << LA_TRIGGER_POSITION_VALUE_LSB) & LA_TRIGGER_POSITION_VALUE_MASK)
-
-#define LA_PRE_TRIGGER_ADDRESS                   0x0000009c
-#define LA_PRE_TRIGGER_OFFSET                    0x0000009c
-#define LA_PRE_TRIGGER_COUNT_MSB                 15
-#define LA_PRE_TRIGGER_COUNT_LSB                 0
-#define LA_PRE_TRIGGER_COUNT_MASK                0x0000ffff
-#define LA_PRE_TRIGGER_COUNT_GET(x)              (((x) & LA_PRE_TRIGGER_COUNT_MASK) >> LA_PRE_TRIGGER_COUNT_LSB)
-#define LA_PRE_TRIGGER_COUNT_SET(x)              (((x) << LA_PRE_TRIGGER_COUNT_LSB) & LA_PRE_TRIGGER_COUNT_MASK)
-
-#define LA_POST_TRIGGER_ADDRESS                  0x000000a0
-#define LA_POST_TRIGGER_OFFSET                   0x000000a0
-#define LA_POST_TRIGGER_COUNT_MSB                15
-#define LA_POST_TRIGGER_COUNT_LSB                0
-#define LA_POST_TRIGGER_COUNT_MASK               0x0000ffff
-#define LA_POST_TRIGGER_COUNT_GET(x)             (((x) & LA_POST_TRIGGER_COUNT_MASK) >> LA_POST_TRIGGER_COUNT_LSB)
-#define LA_POST_TRIGGER_COUNT_SET(x)             (((x) << LA_POST_TRIGGER_COUNT_LSB) & LA_POST_TRIGGER_COUNT_MASK)
-
-#define LA_FILTER_CONTROL_ADDRESS                0x000000a4
-#define LA_FILTER_CONTROL_OFFSET                 0x000000a4
-#define LA_FILTER_CONTROL_DELTA_MSB              0
-#define LA_FILTER_CONTROL_DELTA_LSB              0
-#define LA_FILTER_CONTROL_DELTA_MASK             0x00000001
-#define LA_FILTER_CONTROL_DELTA_GET(x)           (((x) & LA_FILTER_CONTROL_DELTA_MASK) >> LA_FILTER_CONTROL_DELTA_LSB)
-#define LA_FILTER_CONTROL_DELTA_SET(x)           (((x) << LA_FILTER_CONTROL_DELTA_LSB) & LA_FILTER_CONTROL_DELTA_MASK)
-
-#define LA_FILTER_DATA_ADDRESS                   0x000000a8
-#define LA_FILTER_DATA_OFFSET                    0x000000a8
-#define LA_FILTER_DATA_MATCH_MSB                 17
-#define LA_FILTER_DATA_MATCH_LSB                 0
-#define LA_FILTER_DATA_MATCH_MASK                0x0003ffff
-#define LA_FILTER_DATA_MATCH_GET(x)              (((x) & LA_FILTER_DATA_MATCH_MASK) >> LA_FILTER_DATA_MATCH_LSB)
-#define LA_FILTER_DATA_MATCH_SET(x)              (((x) << LA_FILTER_DATA_MATCH_LSB) & LA_FILTER_DATA_MATCH_MASK)
-
-#define LA_FILTER_WILDCARD_ADDRESS               0x000000ac
-#define LA_FILTER_WILDCARD_OFFSET                0x000000ac
-#define LA_FILTER_WILDCARD_MATCH_MSB             17
-#define LA_FILTER_WILDCARD_MATCH_LSB             0
-#define LA_FILTER_WILDCARD_MATCH_MASK            0x0003ffff
-#define LA_FILTER_WILDCARD_MATCH_GET(x)          (((x) & LA_FILTER_WILDCARD_MATCH_MASK) >> LA_FILTER_WILDCARD_MATCH_LSB)
-#define LA_FILTER_WILDCARD_MATCH_SET(x)          (((x) << LA_FILTER_WILDCARD_MATCH_LSB) & LA_FILTER_WILDCARD_MATCH_MASK)
-
-#define LA_TRIGGERA_DATA_ADDRESS                 0x000000b0
-#define LA_TRIGGERA_DATA_OFFSET                  0x000000b0
-#define LA_TRIGGERA_DATA_MATCH_MSB               17
-#define LA_TRIGGERA_DATA_MATCH_LSB               0
-#define LA_TRIGGERA_DATA_MATCH_MASK              0x0003ffff
-#define LA_TRIGGERA_DATA_MATCH_GET(x)            (((x) & LA_TRIGGERA_DATA_MATCH_MASK) >> LA_TRIGGERA_DATA_MATCH_LSB)
-#define LA_TRIGGERA_DATA_MATCH_SET(x)            (((x) << LA_TRIGGERA_DATA_MATCH_LSB) & LA_TRIGGERA_DATA_MATCH_MASK)
-
-#define LA_TRIGGERA_WILDCARD_ADDRESS             0x000000b4
-#define LA_TRIGGERA_WILDCARD_OFFSET              0x000000b4
-#define LA_TRIGGERA_WILDCARD_MATCH_MSB           17
-#define LA_TRIGGERA_WILDCARD_MATCH_LSB           0
-#define LA_TRIGGERA_WILDCARD_MATCH_MASK          0x0003ffff
-#define LA_TRIGGERA_WILDCARD_MATCH_GET(x)        (((x) & LA_TRIGGERA_WILDCARD_MATCH_MASK) >> LA_TRIGGERA_WILDCARD_MATCH_LSB)
-#define LA_TRIGGERA_WILDCARD_MATCH_SET(x)        (((x) << LA_TRIGGERA_WILDCARD_MATCH_LSB) & LA_TRIGGERA_WILDCARD_MATCH_MASK)
-
-#define LA_TRIGGERB_DATA_ADDRESS                 0x000000b8
-#define LA_TRIGGERB_DATA_OFFSET                  0x000000b8
-#define LA_TRIGGERB_DATA_MATCH_MSB               17
-#define LA_TRIGGERB_DATA_MATCH_LSB               0
-#define LA_TRIGGERB_DATA_MATCH_MASK              0x0003ffff
-#define LA_TRIGGERB_DATA_MATCH_GET(x)            (((x) & LA_TRIGGERB_DATA_MATCH_MASK) >> LA_TRIGGERB_DATA_MATCH_LSB)
-#define LA_TRIGGERB_DATA_MATCH_SET(x)            (((x) << LA_TRIGGERB_DATA_MATCH_LSB) & LA_TRIGGERB_DATA_MATCH_MASK)
-
-#define LA_TRIGGERB_WILDCARD_ADDRESS             0x000000bc
-#define LA_TRIGGERB_WILDCARD_OFFSET              0x000000bc
-#define LA_TRIGGERB_WILDCARD_MATCH_MSB           17
-#define LA_TRIGGERB_WILDCARD_MATCH_LSB           0
-#define LA_TRIGGERB_WILDCARD_MATCH_MASK          0x0003ffff
-#define LA_TRIGGERB_WILDCARD_MATCH_GET(x)        (((x) & LA_TRIGGERB_WILDCARD_MATCH_MASK) >> LA_TRIGGERB_WILDCARD_MATCH_LSB)
-#define LA_TRIGGERB_WILDCARD_MATCH_SET(x)        (((x) << LA_TRIGGERB_WILDCARD_MATCH_LSB) & LA_TRIGGERB_WILDCARD_MATCH_MASK)
-
-#define LA_TRIGGER_ADDRESS                       0x000000c0
-#define LA_TRIGGER_OFFSET                        0x000000c0
-#define LA_TRIGGER_EVENT_MSB                     2
-#define LA_TRIGGER_EVENT_LSB                     0
-#define LA_TRIGGER_EVENT_MASK                    0x00000007
-#define LA_TRIGGER_EVENT_GET(x)                  (((x) & LA_TRIGGER_EVENT_MASK) >> LA_TRIGGER_EVENT_LSB)
-#define LA_TRIGGER_EVENT_SET(x)                  (((x) << LA_TRIGGER_EVENT_LSB) & LA_TRIGGER_EVENT_MASK)
-
-#define LA_FIFO_ADDRESS                          0x000000c4
-#define LA_FIFO_OFFSET                           0x000000c4
-#define LA_FIFO_FULL_MSB                         1
-#define LA_FIFO_FULL_LSB                         1
-#define LA_FIFO_FULL_MASK                        0x00000002
-#define LA_FIFO_FULL_GET(x)                      (((x) & LA_FIFO_FULL_MASK) >> LA_FIFO_FULL_LSB)
-#define LA_FIFO_FULL_SET(x)                      (((x) << LA_FIFO_FULL_LSB) & LA_FIFO_FULL_MASK)
-#define LA_FIFO_EMPTY_MSB                        0
-#define LA_FIFO_EMPTY_LSB                        0
-#define LA_FIFO_EMPTY_MASK                       0x00000001
-#define LA_FIFO_EMPTY_GET(x)                     (((x) & LA_FIFO_EMPTY_MASK) >> LA_FIFO_EMPTY_LSB)
-#define LA_FIFO_EMPTY_SET(x)                     (((x) << LA_FIFO_EMPTY_LSB) & LA_FIFO_EMPTY_MASK)
-
-#define LA_ADDRESS                               0x000000c8
-#define LA_OFFSET                                0x000000c8
-#define LA_DATA_MSB                              17
-#define LA_DATA_LSB                              0
-#define LA_DATA_MASK                             0x0003ffff
-#define LA_DATA_GET(x)                           (((x) & LA_DATA_MASK) >> LA_DATA_LSB)
-#define LA_DATA_SET(x)                           (((x) << LA_DATA_LSB) & LA_DATA_MASK)
-
-#define ANT_PIN_ADDRESS                          0x000000d0
-#define ANT_PIN_OFFSET                           0x000000d0
-#define ANT_PIN_PAD_PULL_MSB                     3
-#define ANT_PIN_PAD_PULL_LSB                     2
-#define ANT_PIN_PAD_PULL_MASK                    0x0000000c
-#define ANT_PIN_PAD_PULL_GET(x)                  (((x) & ANT_PIN_PAD_PULL_MASK) >> ANT_PIN_PAD_PULL_LSB)
-#define ANT_PIN_PAD_PULL_SET(x)                  (((x) << ANT_PIN_PAD_PULL_LSB) & ANT_PIN_PAD_PULL_MASK)
-#define ANT_PIN_PAD_STRENGTH_MSB                 1
-#define ANT_PIN_PAD_STRENGTH_LSB                 0
-#define ANT_PIN_PAD_STRENGTH_MASK                0x00000003
-#define ANT_PIN_PAD_STRENGTH_GET(x)              (((x) & ANT_PIN_PAD_STRENGTH_MASK) >> ANT_PIN_PAD_STRENGTH_LSB)
-#define ANT_PIN_PAD_STRENGTH_SET(x)              (((x) << ANT_PIN_PAD_STRENGTH_LSB) & ANT_PIN_PAD_STRENGTH_MASK)
-
-#define ANTD_PIN_ADDRESS                         0x000000d4
-#define ANTD_PIN_OFFSET                          0x000000d4
-#define ANTD_PIN_PAD_PULL_MSB                    1
-#define ANTD_PIN_PAD_PULL_LSB                    0
-#define ANTD_PIN_PAD_PULL_MASK                   0x00000003
-#define ANTD_PIN_PAD_PULL_GET(x)                 (((x) & ANTD_PIN_PAD_PULL_MASK) >> ANTD_PIN_PAD_PULL_LSB)
-#define ANTD_PIN_PAD_PULL_SET(x)                 (((x) << ANTD_PIN_PAD_PULL_LSB) & ANTD_PIN_PAD_PULL_MASK)
-
-#define GPIO_PIN_ADDRESS                         0x000000d8
-#define GPIO_PIN_OFFSET                          0x000000d8
-#define GPIO_PIN_PAD_PULL_MSB                    3
-#define GPIO_PIN_PAD_PULL_LSB                    2
-#define GPIO_PIN_PAD_PULL_MASK                   0x0000000c
-#define GPIO_PIN_PAD_PULL_GET(x)                 (((x) & GPIO_PIN_PAD_PULL_MASK) >> GPIO_PIN_PAD_PULL_LSB)
-#define GPIO_PIN_PAD_PULL_SET(x)                 (((x) << GPIO_PIN_PAD_PULL_LSB) & GPIO_PIN_PAD_PULL_MASK)
-#define GPIO_PIN_PAD_STRENGTH_MSB                1
-#define GPIO_PIN_PAD_STRENGTH_LSB                0
-#define GPIO_PIN_PAD_STRENGTH_MASK               0x00000003
-#define GPIO_PIN_PAD_STRENGTH_GET(x)             (((x) & GPIO_PIN_PAD_STRENGTH_MASK) >> GPIO_PIN_PAD_STRENGTH_LSB)
-#define GPIO_PIN_PAD_STRENGTH_SET(x)             (((x) << GPIO_PIN_PAD_STRENGTH_LSB) & GPIO_PIN_PAD_STRENGTH_MASK)
-
-#define GPIO_H_PIN_ADDRESS                       0x000000dc
-#define GPIO_H_PIN_OFFSET                        0x000000dc
-#define GPIO_H_PIN_PAD_PULL_MSB                  1
-#define GPIO_H_PIN_PAD_PULL_LSB                  0
-#define GPIO_H_PIN_PAD_PULL_MASK                 0x00000003
-#define GPIO_H_PIN_PAD_PULL_GET(x)               (((x) & GPIO_H_PIN_PAD_PULL_MASK) >> GPIO_H_PIN_PAD_PULL_LSB)
-#define GPIO_H_PIN_PAD_PULL_SET(x)               (((x) << GPIO_H_PIN_PAD_PULL_LSB) & GPIO_H_PIN_PAD_PULL_MASK)
-
-#define BT_PIN_ADDRESS                           0x000000e0
-#define BT_PIN_OFFSET                            0x000000e0
-#define BT_PIN_PAD_PULL_MSB                      3
-#define BT_PIN_PAD_PULL_LSB                      2
-#define BT_PIN_PAD_PULL_MASK                     0x0000000c
-#define BT_PIN_PAD_PULL_GET(x)                   (((x) & BT_PIN_PAD_PULL_MASK) >> BT_PIN_PAD_PULL_LSB)
-#define BT_PIN_PAD_PULL_SET(x)                   (((x) << BT_PIN_PAD_PULL_LSB) & BT_PIN_PAD_PULL_MASK)
-#define BT_PIN_PAD_STRENGTH_MSB                  1
-#define BT_PIN_PAD_STRENGTH_LSB                  0
-#define BT_PIN_PAD_STRENGTH_MASK                 0x00000003
-#define BT_PIN_PAD_STRENGTH_GET(x)               (((x) & BT_PIN_PAD_STRENGTH_MASK) >> BT_PIN_PAD_STRENGTH_LSB)
-#define BT_PIN_PAD_STRENGTH_SET(x)               (((x) << BT_PIN_PAD_STRENGTH_LSB) & BT_PIN_PAD_STRENGTH_MASK)
-
-#define BT_WLAN_PIN_ADDRESS                      0x000000e4
-#define BT_WLAN_PIN_OFFSET                       0x000000e4
-#define BT_WLAN_PIN_PAD_PULL_MSB                 1
-#define BT_WLAN_PIN_PAD_PULL_LSB                 0
-#define BT_WLAN_PIN_PAD_PULL_MASK                0x00000003
-#define BT_WLAN_PIN_PAD_PULL_GET(x)              (((x) & BT_WLAN_PIN_PAD_PULL_MASK) >> BT_WLAN_PIN_PAD_PULL_LSB)
-#define BT_WLAN_PIN_PAD_PULL_SET(x)              (((x) << BT_WLAN_PIN_PAD_PULL_LSB) & BT_WLAN_PIN_PAD_PULL_MASK)
-
-#define SI_UART_PIN_ADDRESS                      0x000000e8
-#define SI_UART_PIN_OFFSET                       0x000000e8
-#define SI_UART_PIN_PAD_PULL_MSB                 3
-#define SI_UART_PIN_PAD_PULL_LSB                 2
-#define SI_UART_PIN_PAD_PULL_MASK                0x0000000c
-#define SI_UART_PIN_PAD_PULL_GET(x)              (((x) & SI_UART_PIN_PAD_PULL_MASK) >> SI_UART_PIN_PAD_PULL_LSB)
-#define SI_UART_PIN_PAD_PULL_SET(x)              (((x) << SI_UART_PIN_PAD_PULL_LSB) & SI_UART_PIN_PAD_PULL_MASK)
-#define SI_UART_PIN_PAD_STRENGTH_MSB             1
-#define SI_UART_PIN_PAD_STRENGTH_LSB             0
-#define SI_UART_PIN_PAD_STRENGTH_MASK            0x00000003
-#define SI_UART_PIN_PAD_STRENGTH_GET(x)          (((x) & SI_UART_PIN_PAD_STRENGTH_MASK) >> SI_UART_PIN_PAD_STRENGTH_LSB)
-#define SI_UART_PIN_PAD_STRENGTH_SET(x)          (((x) << SI_UART_PIN_PAD_STRENGTH_LSB) & SI_UART_PIN_PAD_STRENGTH_MASK)
-
-#define CLK32K_PIN_ADDRESS                       0x000000ec
-#define CLK32K_PIN_OFFSET                        0x000000ec
-#define CLK32K_PIN_PAD_PULL_MSB                  1
-#define CLK32K_PIN_PAD_PULL_LSB                  0
-#define CLK32K_PIN_PAD_PULL_MASK                 0x00000003
-#define CLK32K_PIN_PAD_PULL_GET(x)               (((x) & CLK32K_PIN_PAD_PULL_MASK) >> CLK32K_PIN_PAD_PULL_LSB)
-#define CLK32K_PIN_PAD_PULL_SET(x)               (((x) << CLK32K_PIN_PAD_PULL_LSB) & CLK32K_PIN_PAD_PULL_MASK)
-
-#define RESET_TUPLE_STATUS_ADDRESS               0x000000f0
-#define RESET_TUPLE_STATUS_OFFSET                0x000000f0
-#define RESET_TUPLE_STATUS_TEST_RESET_TUPLE_MSB  11
-#define RESET_TUPLE_STATUS_TEST_RESET_TUPLE_LSB  8
-#define RESET_TUPLE_STATUS_TEST_RESET_TUPLE_MASK 0x00000f00
-#define RESET_TUPLE_STATUS_TEST_RESET_TUPLE_GET(x) (((x) & RESET_TUPLE_STATUS_TEST_RESET_TUPLE_MASK) >> RESET_TUPLE_STATUS_TEST_RESET_TUPLE_LSB)
-#define RESET_TUPLE_STATUS_TEST_RESET_TUPLE_SET(x) (((x) << RESET_TUPLE_STATUS_TEST_RESET_TUPLE_LSB) & RESET_TUPLE_STATUS_TEST_RESET_TUPLE_MASK)
-#define RESET_TUPLE_STATUS_PIN_RESET_TUPLE_MSB   7
-#define RESET_TUPLE_STATUS_PIN_RESET_TUPLE_LSB   0
-#define RESET_TUPLE_STATUS_PIN_RESET_TUPLE_MASK  0x000000ff
-#define RESET_TUPLE_STATUS_PIN_RESET_TUPLE_GET(x) (((x) & RESET_TUPLE_STATUS_PIN_RESET_TUPLE_MASK) >> RESET_TUPLE_STATUS_PIN_RESET_TUPLE_LSB)
-#define RESET_TUPLE_STATUS_PIN_RESET_TUPLE_SET(x) (((x) << RESET_TUPLE_STATUS_PIN_RESET_TUPLE_LSB) & RESET_TUPLE_STATUS_PIN_RESET_TUPLE_MASK)
-
-
-#ifndef __ASSEMBLER__
-
-typedef struct gpio_reg_reg_s {
-  volatile unsigned int gpio_out;
-  volatile unsigned int gpio_out_w1ts;
-  volatile unsigned int gpio_out_w1tc;
-  volatile unsigned int gpio_enable;
-  volatile unsigned int gpio_enable_w1ts;
-  volatile unsigned int gpio_enable_w1tc;
-  volatile unsigned int gpio_in;
-  volatile unsigned int gpio_status;
-  volatile unsigned int gpio_status_w1ts;
-  volatile unsigned int gpio_status_w1tc;
-  volatile unsigned int gpio_pin0;
-  volatile unsigned int gpio_pin1;
-  volatile unsigned int gpio_pin2;
-  volatile unsigned int gpio_pin3;
-  volatile unsigned int gpio_pin4;
-  volatile unsigned int gpio_pin5;
-  volatile unsigned int gpio_pin6;
-  volatile unsigned int gpio_pin7;
-  volatile unsigned int gpio_pin8;
-  volatile unsigned int gpio_pin9;
-  volatile unsigned int gpio_pin10;
-  volatile unsigned int gpio_pin11;
-  volatile unsigned int gpio_pin12;
-  volatile unsigned int gpio_pin13;
-  volatile unsigned int gpio_pin14;
-  volatile unsigned int gpio_pin15;
-  volatile unsigned int gpio_pin16;
-  volatile unsigned int gpio_pin17;
-  volatile unsigned int sdio_pin;
-  volatile unsigned int clk_req_pin;
-  volatile unsigned int sigma_delta;
-  volatile unsigned int debug_control;
-  volatile unsigned int debug_input_sel;
-  volatile unsigned int debug_out;
-  volatile unsigned int la_control;
-  volatile unsigned int la_clock;
-  volatile unsigned int la_status;
-  volatile unsigned int la_trigger_sample;
-  volatile unsigned int la_trigger_position;
-  volatile unsigned int la_pre_trigger;
-  volatile unsigned int la_post_trigger;
-  volatile unsigned int la_filter_control;
-  volatile unsigned int la_filter_data;
-  volatile unsigned int la_filter_wildcard;
-  volatile unsigned int la_triggera_data;
-  volatile unsigned int la_triggera_wildcard;
-  volatile unsigned int la_triggerb_data;
-  volatile unsigned int la_triggerb_wildcard;
-  volatile unsigned int la_trigger;
-  volatile unsigned int la_fifo;
-  volatile unsigned int la[2];
-  volatile unsigned int ant_pin;
-  volatile unsigned int antd_pin;
-  volatile unsigned int gpio_pin;
-  volatile unsigned int gpio_h_pin;
-  volatile unsigned int bt_pin;
-  volatile unsigned int bt_wlan_pin;
-  volatile unsigned int si_uart_pin;
-  volatile unsigned int clk32k_pin;
-  volatile unsigned int reset_tuple_status;
-} gpio_reg_reg_t;
-
-#endif /* __ASSEMBLER__ */
-
-#endif /* _GPIO_REG_H_ */
diff -druN linux-2.6.39-libre/drivers/staging/ath6kl/include/common/AR6002/hw2.0/hw/mbox_host_reg.h linux-3.0-rc7-libre/drivers/staging/ath6kl/include/common/AR6002/hw2.0/hw/mbox_host_reg.h
--- linux-2.6.39-libre/drivers/staging/ath6kl/include/common/AR6002/hw2.0/hw/mbox_host_reg.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/ath6kl/include/common/AR6002/hw2.0/hw/mbox_host_reg.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,386 +0,0 @@
-#ifndef _MBOX_HOST_REG_REG_H_
-#define _MBOX_HOST_REG_REG_H_
-
-#define HOST_INT_STATUS_ADDRESS                  0x00000400
-#define HOST_INT_STATUS_OFFSET                   0x00000400
-#define HOST_INT_STATUS_ERROR_MSB                7
-#define HOST_INT_STATUS_ERROR_LSB                7
-#define HOST_INT_STATUS_ERROR_MASK               0x00000080
-#define HOST_INT_STATUS_ERROR_GET(x)             (((x) & HOST_INT_STATUS_ERROR_MASK) >> HOST_INT_STATUS_ERROR_LSB)
-#define HOST_INT_STATUS_ERROR_SET(x)             (((x) << HOST_INT_STATUS_ERROR_LSB) & HOST_INT_STATUS_ERROR_MASK)
-#define HOST_INT_STATUS_CPU_MSB                  6
-#define HOST_INT_STATUS_CPU_LSB                  6
-#define HOST_INT_STATUS_CPU_MASK                 0x00000040
-#define HOST_INT_STATUS_CPU_GET(x)               (((x) & HOST_INT_STATUS_CPU_MASK) >> HOST_INT_STATUS_CPU_LSB)
-#define HOST_INT_STATUS_CPU_SET(x)               (((x) << HOST_INT_STATUS_CPU_LSB) & HOST_INT_STATUS_CPU_MASK)
-#define HOST_INT_STATUS_DRAGON_INT_MSB           5
-#define HOST_INT_STATUS_DRAGON_INT_LSB           5
-#define HOST_INT_STATUS_DRAGON_INT_MASK          0x00000020
-#define HOST_INT_STATUS_DRAGON_INT_GET(x)        (((x) & HOST_INT_STATUS_DRAGON_INT_MASK) >> HOST_INT_STATUS_DRAGON_INT_LSB)
-#define HOST_INT_STATUS_DRAGON_INT_SET(x)        (((x) << HOST_INT_STATUS_DRAGON_INT_LSB) & HOST_INT_STATUS_DRAGON_INT_MASK)
-#define HOST_INT_STATUS_COUNTER_MSB              4
-#define HOST_INT_STATUS_COUNTER_LSB              4
-#define HOST_INT_STATUS_COUNTER_MASK             0x00000010
-#define HOST_INT_STATUS_COUNTER_GET(x)           (((x) & HOST_INT_STATUS_COUNTER_MASK) >> HOST_INT_STATUS_COUNTER_LSB)
-#define HOST_INT_STATUS_COUNTER_SET(x)           (((x) << HOST_INT_STATUS_COUNTER_LSB) & HOST_INT_STATUS_COUNTER_MASK)
-#define HOST_INT_STATUS_MBOX_DATA_MSB            3
-#define HOST_INT_STATUS_MBOX_DATA_LSB            0
-#define HOST_INT_STATUS_MBOX_DATA_MASK           0x0000000f
-#define HOST_INT_STATUS_MBOX_DATA_GET(x)         (((x) & HOST_INT_STATUS_MBOX_DATA_MASK) >> HOST_INT_STATUS_MBOX_DATA_LSB)
-#define HOST_INT_STATUS_MBOX_DATA_SET(x)         (((x) << HOST_INT_STATUS_MBOX_DATA_LSB) & HOST_INT_STATUS_MBOX_DATA_MASK)
-
-#define CPU_INT_STATUS_ADDRESS                   0x00000401
-#define CPU_INT_STATUS_OFFSET                    0x00000401
-#define CPU_INT_STATUS_BIT_MSB                   7
-#define CPU_INT_STATUS_BIT_LSB                   0
-#define CPU_INT_STATUS_BIT_MASK                  0x000000ff
-#define CPU_INT_STATUS_BIT_GET(x)                (((x) & CPU_INT_STATUS_BIT_MASK) >> CPU_INT_STATUS_BIT_LSB)
-#define CPU_INT_STATUS_BIT_SET(x)                (((x) << CPU_INT_STATUS_BIT_LSB) & CPU_INT_STATUS_BIT_MASK)
-
-#define ERROR_INT_STATUS_ADDRESS                 0x00000402
-#define ERROR_INT_STATUS_OFFSET                  0x00000402
-#define ERROR_INT_STATUS_SPI_MSB                 3
-#define ERROR_INT_STATUS_SPI_LSB                 3
-#define ERROR_INT_STATUS_SPI_MASK                0x00000008
-#define ERROR_INT_STATUS_SPI_GET(x)              (((x) & ERROR_INT_STATUS_SPI_MASK) >> ERROR_INT_STATUS_SPI_LSB)
-#define ERROR_INT_STATUS_SPI_SET(x)              (((x) << ERROR_INT_STATUS_SPI_LSB) & ERROR_INT_STATUS_SPI_MASK)
-#define ERROR_INT_STATUS_WAKEUP_MSB              2
-#define ERROR_INT_STATUS_WAKEUP_LSB              2
-#define ERROR_INT_STATUS_WAKEUP_MASK             0x00000004
-#define ERROR_INT_STATUS_WAKEUP_GET(x)           (((x) & ERROR_INT_STATUS_WAKEUP_MASK) >> ERROR_INT_STATUS_WAKEUP_LSB)
-#define ERROR_INT_STATUS_WAKEUP_SET(x)           (((x) << ERROR_INT_STATUS_WAKEUP_LSB) & ERROR_INT_STATUS_WAKEUP_MASK)
-#define ERROR_INT_STATUS_RX_UNDERFLOW_MSB        1
-#define ERROR_INT_STATUS_RX_UNDERFLOW_LSB        1
-#define ERROR_INT_STATUS_RX_UNDERFLOW_MASK       0x00000002
-#define ERROR_INT_STATUS_RX_UNDERFLOW_GET(x)     (((x) & ERROR_INT_STATUS_RX_UNDERFLOW_MASK) >> ERROR_INT_STATUS_RX_UNDERFLOW_LSB)
-#define ERROR_INT_STATUS_RX_UNDERFLOW_SET(x)     (((x) << ERROR_INT_STATUS_RX_UNDERFLOW_LSB) & ERROR_INT_STATUS_RX_UNDERFLOW_MASK)
-#define ERROR_INT_STATUS_TX_OVERFLOW_MSB         0
-#define ERROR_INT_STATUS_TX_OVERFLOW_LSB         0
-#define ERROR_INT_STATUS_TX_OVERFLOW_MASK        0x00000001
-#define ERROR_INT_STATUS_TX_OVERFLOW_GET(x)      (((x) & ERROR_INT_STATUS_TX_OVERFLOW_MASK) >> ERROR_INT_STATUS_TX_OVERFLOW_LSB)
-#define ERROR_INT_STATUS_TX_OVERFLOW_SET(x)      (((x) << ERROR_INT_STATUS_TX_OVERFLOW_LSB) & ERROR_INT_STATUS_TX_OVERFLOW_MASK)
-
-#define COUNTER_INT_STATUS_ADDRESS               0x00000403
-#define COUNTER_INT_STATUS_OFFSET                0x00000403
-#define COUNTER_INT_STATUS_COUNTER_MSB           7
-#define COUNTER_INT_STATUS_COUNTER_LSB           0
-#define COUNTER_INT_STATUS_COUNTER_MASK          0x000000ff
-#define COUNTER_INT_STATUS_COUNTER_GET(x)        (((x) & COUNTER_INT_STATUS_COUNTER_MASK) >> COUNTER_INT_STATUS_COUNTER_LSB)
-#define COUNTER_INT_STATUS_COUNTER_SET(x)        (((x) << COUNTER_INT_STATUS_COUNTER_LSB) & COUNTER_INT_STATUS_COUNTER_MASK)
-
-#define MBOX_FRAME_ADDRESS                       0x00000404
-#define MBOX_FRAME_OFFSET                        0x00000404
-#define MBOX_FRAME_RX_EOM_MSB                    7
-#define MBOX_FRAME_RX_EOM_LSB                    4
-#define MBOX_FRAME_RX_EOM_MASK                   0x000000f0
-#define MBOX_FRAME_RX_EOM_GET(x)                 (((x) & MBOX_FRAME_RX_EOM_MASK) >> MBOX_FRAME_RX_EOM_LSB)
-#define MBOX_FRAME_RX_EOM_SET(x)                 (((x) << MBOX_FRAME_RX_EOM_LSB) & MBOX_FRAME_RX_EOM_MASK)
-#define MBOX_FRAME_RX_SOM_MSB                    3
-#define MBOX_FRAME_RX_SOM_LSB                    0
-#define MBOX_FRAME_RX_SOM_MASK                   0x0000000f
-#define MBOX_FRAME_RX_SOM_GET(x)                 (((x) & MBOX_FRAME_RX_SOM_MASK) >> MBOX_FRAME_RX_SOM_LSB)
-#define MBOX_FRAME_RX_SOM_SET(x)                 (((x) << MBOX_FRAME_RX_SOM_LSB) & MBOX_FRAME_RX_SOM_MASK)
-
-#define RX_LOOKAHEAD_VALID_ADDRESS               0x00000405
-#define RX_LOOKAHEAD_VALID_OFFSET                0x00000405
-#define RX_LOOKAHEAD_VALID_MBOX_MSB              3
-#define RX_LOOKAHEAD_VALID_MBOX_LSB              0
-#define RX_LOOKAHEAD_VALID_MBOX_MASK             0x0000000f
-#define RX_LOOKAHEAD_VALID_MBOX_GET(x)           (((x) & RX_LOOKAHEAD_VALID_MBOX_MASK) >> RX_LOOKAHEAD_VALID_MBOX_LSB)
-#define RX_LOOKAHEAD_VALID_MBOX_SET(x)           (((x) << RX_LOOKAHEAD_VALID_MBOX_LSB) & RX_LOOKAHEAD_VALID_MBOX_MASK)
-
-#define RX_LOOKAHEAD0_ADDRESS                    0x00000408
-#define RX_LOOKAHEAD0_OFFSET                     0x00000408
-#define RX_LOOKAHEAD0_DATA_MSB                   7
-#define RX_LOOKAHEAD0_DATA_LSB                   0
-#define RX_LOOKAHEAD0_DATA_MASK                  0x000000ff
-#define RX_LOOKAHEAD0_DATA_GET(x)                (((x) & RX_LOOKAHEAD0_DATA_MASK) >> RX_LOOKAHEAD0_DATA_LSB)
-#define RX_LOOKAHEAD0_DATA_SET(x)                (((x) << RX_LOOKAHEAD0_DATA_LSB) & RX_LOOKAHEAD0_DATA_MASK)
-
-#define RX_LOOKAHEAD1_ADDRESS                    0x0000040c
-#define RX_LOOKAHEAD1_OFFSET                     0x0000040c
-#define RX_LOOKAHEAD1_DATA_MSB                   7
-#define RX_LOOKAHEAD1_DATA_LSB                   0
-#define RX_LOOKAHEAD1_DATA_MASK                  0x000000ff
-#define RX_LOOKAHEAD1_DATA_GET(x)                (((x) & RX_LOOKAHEAD1_DATA_MASK) >> RX_LOOKAHEAD1_DATA_LSB)
-#define RX_LOOKAHEAD1_DATA_SET(x)                (((x) << RX_LOOKAHEAD1_DATA_LSB) & RX_LOOKAHEAD1_DATA_MASK)
-
-#define RX_LOOKAHEAD2_ADDRESS                    0x00000410
-#define RX_LOOKAHEAD2_OFFSET                     0x00000410
-#define RX_LOOKAHEAD2_DATA_MSB                   7
-#define RX_LOOKAHEAD2_DATA_LSB                   0
-#define RX_LOOKAHEAD2_DATA_MASK                  0x000000ff
-#define RX_LOOKAHEAD2_DATA_GET(x)                (((x) & RX_LOOKAHEAD2_DATA_MASK) >> RX_LOOKAHEAD2_DATA_LSB)
-#define RX_LOOKAHEAD2_DATA_SET(x)                (((x) << RX_LOOKAHEAD2_DATA_LSB) & RX_LOOKAHEAD2_DATA_MASK)
-
-#define RX_LOOKAHEAD3_ADDRESS                    0x00000414
-#define RX_LOOKAHEAD3_OFFSET                     0x00000414
-#define RX_LOOKAHEAD3_DATA_MSB                   7
-#define RX_LOOKAHEAD3_DATA_LSB                   0
-#define RX_LOOKAHEAD3_DATA_MASK                  0x000000ff
-#define RX_LOOKAHEAD3_DATA_GET(x)                (((x) & RX_LOOKAHEAD3_DATA_MASK) >> RX_LOOKAHEAD3_DATA_LSB)
-#define RX_LOOKAHEAD3_DATA_SET(x)                (((x) << RX_LOOKAHEAD3_DATA_LSB) & RX_LOOKAHEAD3_DATA_MASK)
-
-#define INT_STATUS_ENABLE_ADDRESS                0x00000418
-#define INT_STATUS_ENABLE_OFFSET                 0x00000418
-#define INT_STATUS_ENABLE_ERROR_MSB              7
-#define INT_STATUS_ENABLE_ERROR_LSB              7
-#define INT_STATUS_ENABLE_ERROR_MASK             0x00000080
-#define INT_STATUS_ENABLE_ERROR_GET(x)           (((x) & INT_STATUS_ENABLE_ERROR_MASK) >> INT_STATUS_ENABLE_ERROR_LSB)
-#define INT_STATUS_ENABLE_ERROR_SET(x)           (((x) << INT_STATUS_ENABLE_ERROR_LSB) & INT_STATUS_ENABLE_ERROR_MASK)
-#define INT_STATUS_ENABLE_CPU_MSB                6
-#define INT_STATUS_ENABLE_CPU_LSB                6
-#define INT_STATUS_ENABLE_CPU_MASK               0x00000040
-#define INT_STATUS_ENABLE_CPU_GET(x)             (((x) & INT_STATUS_ENABLE_CPU_MASK) >> INT_STATUS_ENABLE_CPU_LSB)
-#define INT_STATUS_ENABLE_CPU_SET(x)             (((x) << INT_STATUS_ENABLE_CPU_LSB) & INT_STATUS_ENABLE_CPU_MASK)
-#define INT_STATUS_ENABLE_DRAGON_INT_MSB         5
-#define INT_STATUS_ENABLE_DRAGON_INT_LSB         5
-#define INT_STATUS_ENABLE_DRAGON_INT_MASK        0x00000020
-#define INT_STATUS_ENABLE_DRAGON_INT_GET(x)      (((x) & INT_STATUS_ENABLE_DRAGON_INT_MASK) >> INT_STATUS_ENABLE_DRAGON_INT_LSB)
-#define INT_STATUS_ENABLE_DRAGON_INT_SET(x)      (((x) << INT_STATUS_ENABLE_DRAGON_INT_LSB) & INT_STATUS_ENABLE_DRAGON_INT_MASK)
-#define INT_STATUS_ENABLE_COUNTER_MSB            4
-#define INT_STATUS_ENABLE_COUNTER_LSB            4
-#define INT_STATUS_ENABLE_COUNTER_MASK           0x00000010
-#define INT_STATUS_ENABLE_COUNTER_GET(x)         (((x) & INT_STATUS_ENABLE_COUNTER_MASK) >> INT_STATUS_ENABLE_COUNTER_LSB)
-#define INT_STATUS_ENABLE_COUNTER_SET(x)         (((x) << INT_STATUS_ENABLE_COUNTER_LSB) & INT_STATUS_ENABLE_COUNTER_MASK)
-#define INT_STATUS_ENABLE_MBOX_DATA_MSB          3
-#define INT_STATUS_ENABLE_MBOX_DATA_LSB          0
-#define INT_STATUS_ENABLE_MBOX_DATA_MASK         0x0000000f
-#define INT_STATUS_ENABLE_MBOX_DATA_GET(x)       (((x) & INT_STATUS_ENABLE_MBOX_DATA_MASK) >> INT_STATUS_ENABLE_MBOX_DATA_LSB)
-#define INT_STATUS_ENABLE_MBOX_DATA_SET(x)       (((x) << INT_STATUS_ENABLE_MBOX_DATA_LSB) & INT_STATUS_ENABLE_MBOX_DATA_MASK)
-
-#define CPU_INT_STATUS_ENABLE_ADDRESS            0x00000419
-#define CPU_INT_STATUS_ENABLE_OFFSET             0x00000419
-#define CPU_INT_STATUS_ENABLE_BIT_MSB            7
-#define CPU_INT_STATUS_ENABLE_BIT_LSB            0
-#define CPU_INT_STATUS_ENABLE_BIT_MASK           0x000000ff
-#define CPU_INT_STATUS_ENABLE_BIT_GET(x)         (((x) & CPU_INT_STATUS_ENABLE_BIT_MASK) >> CPU_INT_STATUS_ENABLE_BIT_LSB)
-#define CPU_INT_STATUS_ENABLE_BIT_SET(x)         (((x) << CPU_INT_STATUS_ENABLE_BIT_LSB) & CPU_INT_STATUS_ENABLE_BIT_MASK)
-
-#define ERROR_STATUS_ENABLE_ADDRESS              0x0000041a
-#define ERROR_STATUS_ENABLE_OFFSET               0x0000041a
-#define ERROR_STATUS_ENABLE_WAKEUP_MSB           2
-#define ERROR_STATUS_ENABLE_WAKEUP_LSB           2
-#define ERROR_STATUS_ENABLE_WAKEUP_MASK          0x00000004
-#define ERROR_STATUS_ENABLE_WAKEUP_GET(x)        (((x) & ERROR_STATUS_ENABLE_WAKEUP_MASK) >> ERROR_STATUS_ENABLE_WAKEUP_LSB)
-#define ERROR_STATUS_ENABLE_WAKEUP_SET(x)        (((x) << ERROR_STATUS_ENABLE_WAKEUP_LSB) & ERROR_STATUS_ENABLE_WAKEUP_MASK)
-#define ERROR_STATUS_ENABLE_RX_UNDERFLOW_MSB     1
-#define ERROR_STATUS_ENABLE_RX_UNDERFLOW_LSB     1
-#define ERROR_STATUS_ENABLE_RX_UNDERFLOW_MASK    0x00000002
-#define ERROR_STATUS_ENABLE_RX_UNDERFLOW_GET(x)  (((x) & ERROR_STATUS_ENABLE_RX_UNDERFLOW_MASK) >> ERROR_STATUS_ENABLE_RX_UNDERFLOW_LSB)
-#define ERROR_STATUS_ENABLE_RX_UNDERFLOW_SET(x)  (((x) << ERROR_STATUS_ENABLE_RX_UNDERFLOW_LSB) & ERROR_STATUS_ENABLE_RX_UNDERFLOW_MASK)
-#define ERROR_STATUS_ENABLE_TX_OVERFLOW_MSB      0
-#define ERROR_STATUS_ENABLE_TX_OVERFLOW_LSB      0
-#define ERROR_STATUS_ENABLE_TX_OVERFLOW_MASK     0x00000001
-#define ERROR_STATUS_ENABLE_TX_OVERFLOW_GET(x)   (((x) & ERROR_STATUS_ENABLE_TX_OVERFLOW_MASK) >> ERROR_STATUS_ENABLE_TX_OVERFLOW_LSB)
-#define ERROR_STATUS_ENABLE_TX_OVERFLOW_SET(x)   (((x) << ERROR_STATUS_ENABLE_TX_OVERFLOW_LSB) & ERROR_STATUS_ENABLE_TX_OVERFLOW_MASK)
-
-#define COUNTER_INT_STATUS_ENABLE_ADDRESS        0x0000041b
-#define COUNTER_INT_STATUS_ENABLE_OFFSET         0x0000041b
-#define COUNTER_INT_STATUS_ENABLE_BIT_MSB        7
-#define COUNTER_INT_STATUS_ENABLE_BIT_LSB        0
-#define COUNTER_INT_STATUS_ENABLE_BIT_MASK       0x000000ff
-#define COUNTER_INT_STATUS_ENABLE_BIT_GET(x)     (((x) & COUNTER_INT_STATUS_ENABLE_BIT_MASK) >> COUNTER_INT_STATUS_ENABLE_BIT_LSB)
-#define COUNTER_INT_STATUS_ENABLE_BIT_SET(x)     (((x) << COUNTER_INT_STATUS_ENABLE_BIT_LSB) & COUNTER_INT_STATUS_ENABLE_BIT_MASK)
-
-#define COUNT_ADDRESS                            0x00000420
-#define COUNT_OFFSET                             0x00000420
-#define COUNT_VALUE_MSB                          7
-#define COUNT_VALUE_LSB                          0
-#define COUNT_VALUE_MASK                         0x000000ff
-#define COUNT_VALUE_GET(x)                       (((x) & COUNT_VALUE_MASK) >> COUNT_VALUE_LSB)
-#define COUNT_VALUE_SET(x)                       (((x) << COUNT_VALUE_LSB) & COUNT_VALUE_MASK)
-
-#define COUNT_DEC_ADDRESS                        0x00000440
-#define COUNT_DEC_OFFSET                         0x00000440
-#define COUNT_DEC_VALUE_MSB                      7
-#define COUNT_DEC_VALUE_LSB                      0
-#define COUNT_DEC_VALUE_MASK                     0x000000ff
-#define COUNT_DEC_VALUE_GET(x)                   (((x) & COUNT_DEC_VALUE_MASK) >> COUNT_DEC_VALUE_LSB)
-#define COUNT_DEC_VALUE_SET(x)                   (((x) << COUNT_DEC_VALUE_LSB) & COUNT_DEC_VALUE_MASK)
-
-#define SCRATCH_ADDRESS                          0x00000460
-#define SCRATCH_OFFSET                           0x00000460
-#define SCRATCH_VALUE_MSB                        7
-#define SCRATCH_VALUE_LSB                        0
-#define SCRATCH_VALUE_MASK                       0x000000ff
-#define SCRATCH_VALUE_GET(x)                     (((x) & SCRATCH_VALUE_MASK) >> SCRATCH_VALUE_LSB)
-#define SCRATCH_VALUE_SET(x)                     (((x) << SCRATCH_VALUE_LSB) & SCRATCH_VALUE_MASK)
-
-#define FIFO_TIMEOUT_ADDRESS                     0x00000468
-#define FIFO_TIMEOUT_OFFSET                      0x00000468
-#define FIFO_TIMEOUT_VALUE_MSB                   7
-#define FIFO_TIMEOUT_VALUE_LSB                   0
-#define FIFO_TIMEOUT_VALUE_MASK                  0x000000ff
-#define FIFO_TIMEOUT_VALUE_GET(x)                (((x) & FIFO_TIMEOUT_VALUE_MASK) >> FIFO_TIMEOUT_VALUE_LSB)
-#define FIFO_TIMEOUT_VALUE_SET(x)                (((x) << FIFO_TIMEOUT_VALUE_LSB) & FIFO_TIMEOUT_VALUE_MASK)
-
-#define FIFO_TIMEOUT_ENABLE_ADDRESS              0x00000469
-#define FIFO_TIMEOUT_ENABLE_OFFSET               0x00000469
-#define FIFO_TIMEOUT_ENABLE_SET_MSB              0
-#define FIFO_TIMEOUT_ENABLE_SET_LSB              0
-#define FIFO_TIMEOUT_ENABLE_SET_MASK             0x00000001
-#define FIFO_TIMEOUT_ENABLE_SET_GET(x)           (((x) & FIFO_TIMEOUT_ENABLE_SET_MASK) >> FIFO_TIMEOUT_ENABLE_SET_LSB)
-#define FIFO_TIMEOUT_ENABLE_SET_SET(x)           (((x) << FIFO_TIMEOUT_ENABLE_SET_LSB) & FIFO_TIMEOUT_ENABLE_SET_MASK)
-
-#define DISABLE_SLEEP_ADDRESS                    0x0000046a
-#define DISABLE_SLEEP_OFFSET                     0x0000046a
-#define DISABLE_SLEEP_FOR_INT_MSB                1
-#define DISABLE_SLEEP_FOR_INT_LSB                1
-#define DISABLE_SLEEP_FOR_INT_MASK               0x00000002
-#define DISABLE_SLEEP_FOR_INT_GET(x)             (((x) & DISABLE_SLEEP_FOR_INT_MASK) >> DISABLE_SLEEP_FOR_INT_LSB)
-#define DISABLE_SLEEP_FOR_INT_SET(x)             (((x) << DISABLE_SLEEP_FOR_INT_LSB) & DISABLE_SLEEP_FOR_INT_MASK)
-#define DISABLE_SLEEP_ON_MSB                     0
-#define DISABLE_SLEEP_ON_LSB                     0
-#define DISABLE_SLEEP_ON_MASK                    0x00000001
-#define DISABLE_SLEEP_ON_GET(x)                  (((x) & DISABLE_SLEEP_ON_MASK) >> DISABLE_SLEEP_ON_LSB)
-#define DISABLE_SLEEP_ON_SET(x)                  (((x) << DISABLE_SLEEP_ON_LSB) & DISABLE_SLEEP_ON_MASK)
-
-#define LOCAL_BUS_ADDRESS                        0x00000470
-#define LOCAL_BUS_OFFSET                         0x00000470
-#define LOCAL_BUS_STATE_MSB                      1
-#define LOCAL_BUS_STATE_LSB                      0
-#define LOCAL_BUS_STATE_MASK                     0x00000003
-#define LOCAL_BUS_STATE_GET(x)                   (((x) & LOCAL_BUS_STATE_MASK) >> LOCAL_BUS_STATE_LSB)
-#define LOCAL_BUS_STATE_SET(x)                   (((x) << LOCAL_BUS_STATE_LSB) & LOCAL_BUS_STATE_MASK)
-
-#define INT_WLAN_ADDRESS                         0x00000472
-#define INT_WLAN_OFFSET                          0x00000472
-#define INT_WLAN_VECTOR_MSB                      7
-#define INT_WLAN_VECTOR_LSB                      0
-#define INT_WLAN_VECTOR_MASK                     0x000000ff
-#define INT_WLAN_VECTOR_GET(x)                   (((x) & INT_WLAN_VECTOR_MASK) >> INT_WLAN_VECTOR_LSB)
-#define INT_WLAN_VECTOR_SET(x)                   (((x) << INT_WLAN_VECTOR_LSB) & INT_WLAN_VECTOR_MASK)
-
-#define WINDOW_DATA_ADDRESS                      0x00000474
-#define WINDOW_DATA_OFFSET                       0x00000474
-#define WINDOW_DATA_DATA_MSB                     7
-#define WINDOW_DATA_DATA_LSB                     0
-#define WINDOW_DATA_DATA_MASK                    0x000000ff
-#define WINDOW_DATA_DATA_GET(x)                  (((x) & WINDOW_DATA_DATA_MASK) >> WINDOW_DATA_DATA_LSB)
-#define WINDOW_DATA_DATA_SET(x)                  (((x) << WINDOW_DATA_DATA_LSB) & WINDOW_DATA_DATA_MASK)
-
-#define WINDOW_WRITE_ADDR_ADDRESS                0x00000478
-#define WINDOW_WRITE_ADDR_OFFSET                 0x00000478
-#define WINDOW_WRITE_ADDR_ADDR_MSB               7
-#define WINDOW_WRITE_ADDR_ADDR_LSB               0
-#define WINDOW_WRITE_ADDR_ADDR_MASK              0x000000ff
-#define WINDOW_WRITE_ADDR_ADDR_GET(x)            (((x) & WINDOW_WRITE_ADDR_ADDR_MASK) >> WINDOW_WRITE_ADDR_ADDR_LSB)
-#define WINDOW_WRITE_ADDR_ADDR_SET(x)            (((x) << WINDOW_WRITE_ADDR_ADDR_LSB) & WINDOW_WRITE_ADDR_ADDR_MASK)
-
-#define WINDOW_READ_ADDR_ADDRESS                 0x0000047c
-#define WINDOW_READ_ADDR_OFFSET                  0x0000047c
-#define WINDOW_READ_ADDR_ADDR_MSB                7
-#define WINDOW_READ_ADDR_ADDR_LSB                0
-#define WINDOW_READ_ADDR_ADDR_MASK               0x000000ff
-#define WINDOW_READ_ADDR_ADDR_GET(x)             (((x) & WINDOW_READ_ADDR_ADDR_MASK) >> WINDOW_READ_ADDR_ADDR_LSB)
-#define WINDOW_READ_ADDR_ADDR_SET(x)             (((x) << WINDOW_READ_ADDR_ADDR_LSB) & WINDOW_READ_ADDR_ADDR_MASK)
-
-#define SPI_CONFIG_ADDRESS                       0x00000480
-#define SPI_CONFIG_OFFSET                        0x00000480
-#define SPI_CONFIG_SPI_RESET_MSB                 4
-#define SPI_CONFIG_SPI_RESET_LSB                 4
-#define SPI_CONFIG_SPI_RESET_MASK                0x00000010
-#define SPI_CONFIG_SPI_RESET_GET(x)              (((x) & SPI_CONFIG_SPI_RESET_MASK) >> SPI_CONFIG_SPI_RESET_LSB)
-#define SPI_CONFIG_SPI_RESET_SET(x)              (((x) << SPI_CONFIG_SPI_RESET_LSB) & SPI_CONFIG_SPI_RESET_MASK)
-#define SPI_CONFIG_INTERRUPT_ENABLE_MSB          3
-#define SPI_CONFIG_INTERRUPT_ENABLE_LSB          3
-#define SPI_CONFIG_INTERRUPT_ENABLE_MASK         0x00000008
-#define SPI_CONFIG_INTERRUPT_ENABLE_GET(x)       (((x) & SPI_CONFIG_INTERRUPT_ENABLE_MASK) >> SPI_CONFIG_INTERRUPT_ENABLE_LSB)
-#define SPI_CONFIG_INTERRUPT_ENABLE_SET(x)       (((x) << SPI_CONFIG_INTERRUPT_ENABLE_LSB) & SPI_CONFIG_INTERRUPT_ENABLE_MASK)
-#define SPI_CONFIG_TEST_MODE_MSB                 2
-#define SPI_CONFIG_TEST_MODE_LSB                 2
-#define SPI_CONFIG_TEST_MODE_MASK                0x00000004
-#define SPI_CONFIG_TEST_MODE_GET(x)              (((x) & SPI_CONFIG_TEST_MODE_MASK) >> SPI_CONFIG_TEST_MODE_LSB)
-#define SPI_CONFIG_TEST_MODE_SET(x)              (((x) << SPI_CONFIG_TEST_MODE_LSB) & SPI_CONFIG_TEST_MODE_MASK)
-#define SPI_CONFIG_DATA_SIZE_MSB                 1
-#define SPI_CONFIG_DATA_SIZE_LSB                 0
-#define SPI_CONFIG_DATA_SIZE_MASK                0x00000003
-#define SPI_CONFIG_DATA_SIZE_GET(x)              (((x) & SPI_CONFIG_DATA_SIZE_MASK) >> SPI_CONFIG_DATA_SIZE_LSB)
-#define SPI_CONFIG_DATA_SIZE_SET(x)              (((x) << SPI_CONFIG_DATA_SIZE_LSB) & SPI_CONFIG_DATA_SIZE_MASK)
-
-#define SPI_STATUS_ADDRESS                       0x00000481
-#define SPI_STATUS_OFFSET                        0x00000481
-#define SPI_STATUS_ADDR_ERR_MSB                  3
-#define SPI_STATUS_ADDR_ERR_LSB                  3
-#define SPI_STATUS_ADDR_ERR_MASK                 0x00000008
-#define SPI_STATUS_ADDR_ERR_GET(x)               (((x) & SPI_STATUS_ADDR_ERR_MASK) >> SPI_STATUS_ADDR_ERR_LSB)
-#define SPI_STATUS_ADDR_ERR_SET(x)               (((x) << SPI_STATUS_ADDR_ERR_LSB) & SPI_STATUS_ADDR_ERR_MASK)
-#define SPI_STATUS_RD_ERR_MSB                    2
-#define SPI_STATUS_RD_ERR_LSB                    2
-#define SPI_STATUS_RD_ERR_MASK                   0x00000004
-#define SPI_STATUS_RD_ERR_GET(x)                 (((x) & SPI_STATUS_RD_ERR_MASK) >> SPI_STATUS_RD_ERR_LSB)
-#define SPI_STATUS_RD_ERR_SET(x)                 (((x) << SPI_STATUS_RD_ERR_LSB) & SPI_STATUS_RD_ERR_MASK)
-#define SPI_STATUS_WR_ERR_MSB                    1
-#define SPI_STATUS_WR_ERR_LSB                    1
-#define SPI_STATUS_WR_ERR_MASK                   0x00000002
-#define SPI_STATUS_WR_ERR_GET(x)                 (((x) & SPI_STATUS_WR_ERR_MASK) >> SPI_STATUS_WR_ERR_LSB)
-#define SPI_STATUS_WR_ERR_SET(x)                 (((x) << SPI_STATUS_WR_ERR_LSB) & SPI_STATUS_WR_ERR_MASK)
-#define SPI_STATUS_READY_MSB                     0
-#define SPI_STATUS_READY_LSB                     0
-#define SPI_STATUS_READY_MASK                    0x00000001
-#define SPI_STATUS_READY_GET(x)                  (((x) & SPI_STATUS_READY_MASK) >> SPI_STATUS_READY_LSB)
-#define SPI_STATUS_READY_SET(x)                  (((x) << SPI_STATUS_READY_LSB) & SPI_STATUS_READY_MASK)
-
-#define NON_ASSOC_SLEEP_EN_ADDRESS               0x00000482
-#define NON_ASSOC_SLEEP_EN_OFFSET                0x00000482
-#define NON_ASSOC_SLEEP_EN_BIT_MSB               0
-#define NON_ASSOC_SLEEP_EN_BIT_LSB               0
-#define NON_ASSOC_SLEEP_EN_BIT_MASK              0x00000001
-#define NON_ASSOC_SLEEP_EN_BIT_GET(x)            (((x) & NON_ASSOC_SLEEP_EN_BIT_MASK) >> NON_ASSOC_SLEEP_EN_BIT_LSB)
-#define NON_ASSOC_SLEEP_EN_BIT_SET(x)            (((x) << NON_ASSOC_SLEEP_EN_BIT_LSB) & NON_ASSOC_SLEEP_EN_BIT_MASK)
-
-#define CIS_WINDOW_ADDRESS                       0x00000600
-#define CIS_WINDOW_OFFSET                        0x00000600
-#define CIS_WINDOW_DATA_MSB                      7
-#define CIS_WINDOW_DATA_LSB                      0
-#define CIS_WINDOW_DATA_MASK                     0x000000ff
-#define CIS_WINDOW_DATA_GET(x)                   (((x) & CIS_WINDOW_DATA_MASK) >> CIS_WINDOW_DATA_LSB)
-#define CIS_WINDOW_DATA_SET(x)                   (((x) << CIS_WINDOW_DATA_LSB) & CIS_WINDOW_DATA_MASK)
-
-
-#ifndef __ASSEMBLER__
-
-typedef struct mbox_host_reg_reg_s {
-  unsigned char pad0[1024]; /* pad to 0x400 */
-  volatile unsigned char host_int_status;
-  volatile unsigned char cpu_int_status;
-  volatile unsigned char error_int_status;
-  volatile unsigned char counter_int_status;
-  volatile unsigned char mbox_frame;
-  volatile unsigned char rx_lookahead_valid;
-  unsigned char pad1[2]; /* pad to 0x408 */
-  volatile unsigned char rx_lookahead0[4];
-  volatile unsigned char rx_lookahead1[4];
-  volatile unsigned char rx_lookahead2[4];
-  volatile unsigned char rx_lookahead3[4];
-  volatile unsigned char int_status_enable;
-  volatile unsigned char cpu_int_status_enable;
-  volatile unsigned char error_status_enable;
-  volatile unsigned char counter_int_status_enable;
-  unsigned char pad2[4]; /* pad to 0x420 */
-  volatile unsigned char count[8];
-  unsigned char pad3[24]; /* pad to 0x440 */
-  volatile unsigned char count_dec[32];
-  volatile unsigned char scratch[8];
-  volatile unsigned char fifo_timeout;
-  volatile unsigned char fifo_timeout_enable;
-  volatile unsigned char disable_sleep;
-  unsigned char pad4[5]; /* pad to 0x470 */
-  volatile unsigned char local_bus;
-  unsigned char pad5[1]; /* pad to 0x472 */
-  volatile unsigned char int_wlan;
-  unsigned char pad6[1]; /* pad to 0x474 */
-  volatile unsigned char window_data[4];
-  volatile unsigned char window_write_addr[4];
-  volatile unsigned char window_read_addr[4];
-  volatile unsigned char spi_config;
-  volatile unsigned char spi_status;
-  volatile unsigned char non_assoc_sleep_en;
-  unsigned char pad7[381]; /* pad to 0x600 */
-  volatile unsigned char cis_window[512];
-} mbox_host_reg_reg_t;
-
-#endif /* __ASSEMBLER__ */
-
-#endif /* _MBOX_HOST_REG_H_ */
diff -druN linux-2.6.39-libre/drivers/staging/ath6kl/include/common/AR6002/hw2.0/hw/mbox_reg.h linux-3.0-rc7-libre/drivers/staging/ath6kl/include/common/AR6002/hw2.0/hw/mbox_reg.h
--- linux-2.6.39-libre/drivers/staging/ath6kl/include/common/AR6002/hw2.0/hw/mbox_reg.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/ath6kl/include/common/AR6002/hw2.0/hw/mbox_reg.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,481 +0,0 @@
-#ifndef _MBOX_REG_REG_H_
-#define _MBOX_REG_REG_H_
-
-#define MBOX_FIFO_ADDRESS                        0x00000000
-#define MBOX_FIFO_OFFSET                         0x00000000
-#define MBOX_FIFO_DATA_MSB                       19
-#define MBOX_FIFO_DATA_LSB                       0
-#define MBOX_FIFO_DATA_MASK                      0x000fffff
-#define MBOX_FIFO_DATA_GET(x)                    (((x) & MBOX_FIFO_DATA_MASK) >> MBOX_FIFO_DATA_LSB)
-#define MBOX_FIFO_DATA_SET(x)                    (((x) << MBOX_FIFO_DATA_LSB) & MBOX_FIFO_DATA_MASK)
-
-#define MBOX_FIFO_STATUS_ADDRESS                 0x00000010
-#define MBOX_FIFO_STATUS_OFFSET                  0x00000010
-#define MBOX_FIFO_STATUS_EMPTY_MSB               19
-#define MBOX_FIFO_STATUS_EMPTY_LSB               16
-#define MBOX_FIFO_STATUS_EMPTY_MASK              0x000f0000
-#define MBOX_FIFO_STATUS_EMPTY_GET(x)            (((x) & MBOX_FIFO_STATUS_EMPTY_MASK) >> MBOX_FIFO_STATUS_EMPTY_LSB)
-#define MBOX_FIFO_STATUS_EMPTY_SET(x)            (((x) << MBOX_FIFO_STATUS_EMPTY_LSB) & MBOX_FIFO_STATUS_EMPTY_MASK)
-#define MBOX_FIFO_STATUS_FULL_MSB                15
-#define MBOX_FIFO_STATUS_FULL_LSB                12
-#define MBOX_FIFO_STATUS_FULL_MASK               0x0000f000
-#define MBOX_FIFO_STATUS_FULL_GET(x)             (((x) & MBOX_FIFO_STATUS_FULL_MASK) >> MBOX_FIFO_STATUS_FULL_LSB)
-#define MBOX_FIFO_STATUS_FULL_SET(x)             (((x) << MBOX_FIFO_STATUS_FULL_LSB) & MBOX_FIFO_STATUS_FULL_MASK)
-
-#define MBOX_DMA_POLICY_ADDRESS                  0x00000014
-#define MBOX_DMA_POLICY_OFFSET                   0x00000014
-#define MBOX_DMA_POLICY_TX_QUANTUM_MSB           3
-#define MBOX_DMA_POLICY_TX_QUANTUM_LSB           3
-#define MBOX_DMA_POLICY_TX_QUANTUM_MASK          0x00000008
-#define MBOX_DMA_POLICY_TX_QUANTUM_GET(x)        (((x) & MBOX_DMA_POLICY_TX_QUANTUM_MASK) >> MBOX_DMA_POLICY_TX_QUANTUM_LSB)
-#define MBOX_DMA_POLICY_TX_QUANTUM_SET(x)        (((x) << MBOX_DMA_POLICY_TX_QUANTUM_LSB) & MBOX_DMA_POLICY_TX_QUANTUM_MASK)
-#define MBOX_DMA_POLICY_TX_ORDER_MSB             2
-#define MBOX_DMA_POLICY_TX_ORDER_LSB             2
-#define MBOX_DMA_POLICY_TX_ORDER_MASK            0x00000004
-#define MBOX_DMA_POLICY_TX_ORDER_GET(x)          (((x) & MBOX_DMA_POLICY_TX_ORDER_MASK) >> MBOX_DMA_POLICY_TX_ORDER_LSB)
-#define MBOX_DMA_POLICY_TX_ORDER_SET(x)          (((x) << MBOX_DMA_POLICY_TX_ORDER_LSB) & MBOX_DMA_POLICY_TX_ORDER_MASK)
-#define MBOX_DMA_POLICY_RX_QUANTUM_MSB           1
-#define MBOX_DMA_POLICY_RX_QUANTUM_LSB           1
-#define MBOX_DMA_POLICY_RX_QUANTUM_MASK          0x00000002
-#define MBOX_DMA_POLICY_RX_QUANTUM_GET(x)        (((x) & MBOX_DMA_POLICY_RX_QUANTUM_MASK) >> MBOX_DMA_POLICY_RX_QUANTUM_LSB)
-#define MBOX_DMA_POLICY_RX_QUANTUM_SET(x)        (((x) << MBOX_DMA_POLICY_RX_QUANTUM_LSB) & MBOX_DMA_POLICY_RX_QUANTUM_MASK)
-#define MBOX_DMA_POLICY_RX_ORDER_MSB             0
-#define MBOX_DMA_POLICY_RX_ORDER_LSB             0
-#define MBOX_DMA_POLICY_RX_ORDER_MASK            0x00000001
-#define MBOX_DMA_POLICY_RX_ORDER_GET(x)          (((x) & MBOX_DMA_POLICY_RX_ORDER_MASK) >> MBOX_DMA_POLICY_RX_ORDER_LSB)
-#define MBOX_DMA_POLICY_RX_ORDER_SET(x)          (((x) << MBOX_DMA_POLICY_RX_ORDER_LSB) & MBOX_DMA_POLICY_RX_ORDER_MASK)
-
-#define MBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS     0x00000018
-#define MBOX0_DMA_RX_DESCRIPTOR_BASE_OFFSET      0x00000018
-#define MBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MSB 27
-#define MBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_LSB 2
-#define MBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MASK 0x0ffffffc
-#define MBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_GET(x) (((x) & MBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MASK) >> MBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_LSB)
-#define MBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_SET(x) (((x) << MBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_LSB) & MBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MASK)
-
-#define MBOX0_DMA_RX_CONTROL_ADDRESS             0x0000001c
-#define MBOX0_DMA_RX_CONTROL_OFFSET              0x0000001c
-#define MBOX0_DMA_RX_CONTROL_RESUME_MSB          2
-#define MBOX0_DMA_RX_CONTROL_RESUME_LSB          2
-#define MBOX0_DMA_RX_CONTROL_RESUME_MASK         0x00000004
-#define MBOX0_DMA_RX_CONTROL_RESUME_GET(x)       (((x) & MBOX0_DMA_RX_CONTROL_RESUME_MASK) >> MBOX0_DMA_RX_CONTROL_RESUME_LSB)
-#define MBOX0_DMA_RX_CONTROL_RESUME_SET(x)       (((x) << MBOX0_DMA_RX_CONTROL_RESUME_LSB) & MBOX0_DMA_RX_CONTROL_RESUME_MASK)
-#define MBOX0_DMA_RX_CONTROL_START_MSB           1
-#define MBOX0_DMA_RX_CONTROL_START_LSB           1
-#define MBOX0_DMA_RX_CONTROL_START_MASK          0x00000002
-#define MBOX0_DMA_RX_CONTROL_START_GET(x)        (((x) & MBOX0_DMA_RX_CONTROL_START_MASK) >> MBOX0_DMA_RX_CONTROL_START_LSB)
-#define MBOX0_DMA_RX_CONTROL_START_SET(x)        (((x) << MBOX0_DMA_RX_CONTROL_START_LSB) & MBOX0_DMA_RX_CONTROL_START_MASK)
-#define MBOX0_DMA_RX_CONTROL_STOP_MSB            0
-#define MBOX0_DMA_RX_CONTROL_STOP_LSB            0
-#define MBOX0_DMA_RX_CONTROL_STOP_MASK           0x00000001
-#define MBOX0_DMA_RX_CONTROL_STOP_GET(x)         (((x) & MBOX0_DMA_RX_CONTROL_STOP_MASK) >> MBOX0_DMA_RX_CONTROL_STOP_LSB)
-#define MBOX0_DMA_RX_CONTROL_STOP_SET(x)         (((x) << MBOX0_DMA_RX_CONTROL_STOP_LSB) & MBOX0_DMA_RX_CONTROL_STOP_MASK)
-
-#define MBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS     0x00000020
-#define MBOX0_DMA_TX_DESCRIPTOR_BASE_OFFSET      0x00000020
-#define MBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MSB 27
-#define MBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_LSB 2
-#define MBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MASK 0x0ffffffc
-#define MBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_GET(x) (((x) & MBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MASK) >> MBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_LSB)
-#define MBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_SET(x) (((x) << MBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_LSB) & MBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MASK)
-
-#define MBOX0_DMA_TX_CONTROL_ADDRESS             0x00000024
-#define MBOX0_DMA_TX_CONTROL_OFFSET              0x00000024
-#define MBOX0_DMA_TX_CONTROL_RESUME_MSB          2
-#define MBOX0_DMA_TX_CONTROL_RESUME_LSB          2
-#define MBOX0_DMA_TX_CONTROL_RESUME_MASK         0x00000004
-#define MBOX0_DMA_TX_CONTROL_RESUME_GET(x)       (((x) & MBOX0_DMA_TX_CONTROL_RESUME_MASK) >> MBOX0_DMA_TX_CONTROL_RESUME_LSB)
-#define MBOX0_DMA_TX_CONTROL_RESUME_SET(x)       (((x) << MBOX0_DMA_TX_CONTROL_RESUME_LSB) & MBOX0_DMA_TX_CONTROL_RESUME_MASK)
-#define MBOX0_DMA_TX_CONTROL_START_MSB           1
-#define MBOX0_DMA_TX_CONTROL_START_LSB           1
-#define MBOX0_DMA_TX_CONTROL_START_MASK          0x00000002
-#define MBOX0_DMA_TX_CONTROL_START_GET(x)        (((x) & MBOX0_DMA_TX_CONTROL_START_MASK) >> MBOX0_DMA_TX_CONTROL_START_LSB)
-#define MBOX0_DMA_TX_CONTROL_START_SET(x)        (((x) << MBOX0_DMA_TX_CONTROL_START_LSB) & MBOX0_DMA_TX_CONTROL_START_MASK)
-#define MBOX0_DMA_TX_CONTROL_STOP_MSB            0
-#define MBOX0_DMA_TX_CONTROL_STOP_LSB            0
-#define MBOX0_DMA_TX_CONTROL_STOP_MASK           0x00000001
-#define MBOX0_DMA_TX_CONTROL_STOP_GET(x)         (((x) & MBOX0_DMA_TX_CONTROL_STOP_MASK) >> MBOX0_DMA_TX_CONTROL_STOP_LSB)
-#define MBOX0_DMA_TX_CONTROL_STOP_SET(x)         (((x) << MBOX0_DMA_TX_CONTROL_STOP_LSB) & MBOX0_DMA_TX_CONTROL_STOP_MASK)
-
-#define MBOX1_DMA_RX_DESCRIPTOR_BASE_ADDRESS     0x00000028
-#define MBOX1_DMA_RX_DESCRIPTOR_BASE_OFFSET      0x00000028
-#define MBOX1_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MSB 27
-#define MBOX1_DMA_RX_DESCRIPTOR_BASE_ADDRESS_LSB 2
-#define MBOX1_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MASK 0x0ffffffc
-#define MBOX1_DMA_RX_DESCRIPTOR_BASE_ADDRESS_GET(x) (((x) & MBOX1_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MASK) >> MBOX1_DMA_RX_DESCRIPTOR_BASE_ADDRESS_LSB)
-#define MBOX1_DMA_RX_DESCRIPTOR_BASE_ADDRESS_SET(x) (((x) << MBOX1_DMA_RX_DESCRIPTOR_BASE_ADDRESS_LSB) & MBOX1_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MASK)
-
-#define MBOX1_DMA_RX_CONTROL_ADDRESS             0x0000002c
-#define MBOX1_DMA_RX_CONTROL_OFFSET              0x0000002c
-#define MBOX1_DMA_RX_CONTROL_RESUME_MSB          2
-#define MBOX1_DMA_RX_CONTROL_RESUME_LSB          2
-#define MBOX1_DMA_RX_CONTROL_RESUME_MASK         0x00000004
-#define MBOX1_DMA_RX_CONTROL_RESUME_GET(x)       (((x) & MBOX1_DMA_RX_CONTROL_RESUME_MASK) >> MBOX1_DMA_RX_CONTROL_RESUME_LSB)
-#define MBOX1_DMA_RX_CONTROL_RESUME_SET(x)       (((x) << MBOX1_DMA_RX_CONTROL_RESUME_LSB) & MBOX1_DMA_RX_CONTROL_RESUME_MASK)
-#define MBOX1_DMA_RX_CONTROL_START_MSB           1
-#define MBOX1_DMA_RX_CONTROL_START_LSB           1
-#define MBOX1_DMA_RX_CONTROL_START_MASK          0x00000002
-#define MBOX1_DMA_RX_CONTROL_START_GET(x)        (((x) & MBOX1_DMA_RX_CONTROL_START_MASK) >> MBOX1_DMA_RX_CONTROL_START_LSB)
-#define MBOX1_DMA_RX_CONTROL_START_SET(x)        (((x) << MBOX1_DMA_RX_CONTROL_START_LSB) & MBOX1_DMA_RX_CONTROL_START_MASK)
-#define MBOX1_DMA_RX_CONTROL_STOP_MSB            0
-#define MBOX1_DMA_RX_CONTROL_STOP_LSB            0
-#define MBOX1_DMA_RX_CONTROL_STOP_MASK           0x00000001
-#define MBOX1_DMA_RX_CONTROL_STOP_GET(x)         (((x) & MBOX1_DMA_RX_CONTROL_STOP_MASK) >> MBOX1_DMA_RX_CONTROL_STOP_LSB)
-#define MBOX1_DMA_RX_CONTROL_STOP_SET(x)         (((x) << MBOX1_DMA_RX_CONTROL_STOP_LSB) & MBOX1_DMA_RX_CONTROL_STOP_MASK)
-
-#define MBOX1_DMA_TX_DESCRIPTOR_BASE_ADDRESS     0x00000030
-#define MBOX1_DMA_TX_DESCRIPTOR_BASE_OFFSET      0x00000030
-#define MBOX1_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MSB 27
-#define MBOX1_DMA_TX_DESCRIPTOR_BASE_ADDRESS_LSB 2
-#define MBOX1_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MASK 0x0ffffffc
-#define MBOX1_DMA_TX_DESCRIPTOR_BASE_ADDRESS_GET(x) (((x) & MBOX1_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MASK) >> MBOX1_DMA_TX_DESCRIPTOR_BASE_ADDRESS_LSB)
-#define MBOX1_DMA_TX_DESCRIPTOR_BASE_ADDRESS_SET(x) (((x) << MBOX1_DMA_TX_DESCRIPTOR_BASE_ADDRESS_LSB) & MBOX1_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MASK)
-
-#define MBOX1_DMA_TX_CONTROL_ADDRESS             0x00000034
-#define MBOX1_DMA_TX_CONTROL_OFFSET              0x00000034
-#define MBOX1_DMA_TX_CONTROL_RESUME_MSB          2
-#define MBOX1_DMA_TX_CONTROL_RESUME_LSB          2
-#define MBOX1_DMA_TX_CONTROL_RESUME_MASK         0x00000004
-#define MBOX1_DMA_TX_CONTROL_RESUME_GET(x)       (((x) & MBOX1_DMA_TX_CONTROL_RESUME_MASK) >> MBOX1_DMA_TX_CONTROL_RESUME_LSB)
-#define MBOX1_DMA_TX_CONTROL_RESUME_SET(x)       (((x) << MBOX1_DMA_TX_CONTROL_RESUME_LSB) & MBOX1_DMA_TX_CONTROL_RESUME_MASK)
-#define MBOX1_DMA_TX_CONTROL_START_MSB           1
-#define MBOX1_DMA_TX_CONTROL_START_LSB           1
-#define MBOX1_DMA_TX_CONTROL_START_MASK          0x00000002
-#define MBOX1_DMA_TX_CONTROL_START_GET(x)        (((x) & MBOX1_DMA_TX_CONTROL_START_MASK) >> MBOX1_DMA_TX_CONTROL_START_LSB)
-#define MBOX1_DMA_TX_CONTROL_START_SET(x)        (((x) << MBOX1_DMA_TX_CONTROL_START_LSB) & MBOX1_DMA_TX_CONTROL_START_MASK)
-#define MBOX1_DMA_TX_CONTROL_STOP_MSB            0
-#define MBOX1_DMA_TX_CONTROL_STOP_LSB            0
-#define MBOX1_DMA_TX_CONTROL_STOP_MASK           0x00000001
-#define MBOX1_DMA_TX_CONTROL_STOP_GET(x)         (((x) & MBOX1_DMA_TX_CONTROL_STOP_MASK) >> MBOX1_DMA_TX_CONTROL_STOP_LSB)
-#define MBOX1_DMA_TX_CONTROL_STOP_SET(x)         (((x) << MBOX1_DMA_TX_CONTROL_STOP_LSB) & MBOX1_DMA_TX_CONTROL_STOP_MASK)
-
-#define MBOX2_DMA_RX_DESCRIPTOR_BASE_ADDRESS     0x00000038
-#define MBOX2_DMA_RX_DESCRIPTOR_BASE_OFFSET      0x00000038
-#define MBOX2_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MSB 27
-#define MBOX2_DMA_RX_DESCRIPTOR_BASE_ADDRESS_LSB 2
-#define MBOX2_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MASK 0x0ffffffc
-#define MBOX2_DMA_RX_DESCRIPTOR_BASE_ADDRESS_GET(x) (((x) & MBOX2_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MASK) >> MBOX2_DMA_RX_DESCRIPTOR_BASE_ADDRESS_LSB)
-#define MBOX2_DMA_RX_DESCRIPTOR_BASE_ADDRESS_SET(x) (((x) << MBOX2_DMA_RX_DESCRIPTOR_BASE_ADDRESS_LSB) & MBOX2_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MASK)
-
-#define MBOX2_DMA_RX_CONTROL_ADDRESS             0x0000003c
-#define MBOX2_DMA_RX_CONTROL_OFFSET              0x0000003c
-#define MBOX2_DMA_RX_CONTROL_RESUME_MSB          2
-#define MBOX2_DMA_RX_CONTROL_RESUME_LSB          2
-#define MBOX2_DMA_RX_CONTROL_RESUME_MASK         0x00000004
-#define MBOX2_DMA_RX_CONTROL_RESUME_GET(x)       (((x) & MBOX2_DMA_RX_CONTROL_RESUME_MASK) >> MBOX2_DMA_RX_CONTROL_RESUME_LSB)
-#define MBOX2_DMA_RX_CONTROL_RESUME_SET(x)       (((x) << MBOX2_DMA_RX_CONTROL_RESUME_LSB) & MBOX2_DMA_RX_CONTROL_RESUME_MASK)
-#define MBOX2_DMA_RX_CONTROL_START_MSB           1
-#define MBOX2_DMA_RX_CONTROL_START_LSB           1
-#define MBOX2_DMA_RX_CONTROL_START_MASK          0x00000002
-#define MBOX2_DMA_RX_CONTROL_START_GET(x)        (((x) & MBOX2_DMA_RX_CONTROL_START_MASK) >> MBOX2_DMA_RX_CONTROL_START_LSB)
-#define MBOX2_DMA_RX_CONTROL_START_SET(x)        (((x) << MBOX2_DMA_RX_CONTROL_START_LSB) & MBOX2_DMA_RX_CONTROL_START_MASK)
-#define MBOX2_DMA_RX_CONTROL_STOP_MSB            0
-#define MBOX2_DMA_RX_CONTROL_STOP_LSB            0
-#define MBOX2_DMA_RX_CONTROL_STOP_MASK           0x00000001
-#define MBOX2_DMA_RX_CONTROL_STOP_GET(x)         (((x) & MBOX2_DMA_RX_CONTROL_STOP_MASK) >> MBOX2_DMA_RX_CONTROL_STOP_LSB)
-#define MBOX2_DMA_RX_CONTROL_STOP_SET(x)         (((x) << MBOX2_DMA_RX_CONTROL_STOP_LSB) & MBOX2_DMA_RX_CONTROL_STOP_MASK)
-
-#define MBOX2_DMA_TX_DESCRIPTOR_BASE_ADDRESS     0x00000040
-#define MBOX2_DMA_TX_DESCRIPTOR_BASE_OFFSET      0x00000040
-#define MBOX2_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MSB 27
-#define MBOX2_DMA_TX_DESCRIPTOR_BASE_ADDRESS_LSB 2
-#define MBOX2_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MASK 0x0ffffffc
-#define MBOX2_DMA_TX_DESCRIPTOR_BASE_ADDRESS_GET(x) (((x) & MBOX2_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MASK) >> MBOX2_DMA_TX_DESCRIPTOR_BASE_ADDRESS_LSB)
-#define MBOX2_DMA_TX_DESCRIPTOR_BASE_ADDRESS_SET(x) (((x) << MBOX2_DMA_TX_DESCRIPTOR_BASE_ADDRESS_LSB) & MBOX2_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MASK)
-
-#define MBOX2_DMA_TX_CONTROL_ADDRESS             0x00000044
-#define MBOX2_DMA_TX_CONTROL_OFFSET              0x00000044
-#define MBOX2_DMA_TX_CONTROL_RESUME_MSB          2
-#define MBOX2_DMA_TX_CONTROL_RESUME_LSB          2
-#define MBOX2_DMA_TX_CONTROL_RESUME_MASK         0x00000004
-#define MBOX2_DMA_TX_CONTROL_RESUME_GET(x)       (((x) & MBOX2_DMA_TX_CONTROL_RESUME_MASK) >> MBOX2_DMA_TX_CONTROL_RESUME_LSB)
-#define MBOX2_DMA_TX_CONTROL_RESUME_SET(x)       (((x) << MBOX2_DMA_TX_CONTROL_RESUME_LSB) & MBOX2_DMA_TX_CONTROL_RESUME_MASK)
-#define MBOX2_DMA_TX_CONTROL_START_MSB           1
-#define MBOX2_DMA_TX_CONTROL_START_LSB           1
-#define MBOX2_DMA_TX_CONTROL_START_MASK          0x00000002
-#define MBOX2_DMA_TX_CONTROL_START_GET(x)        (((x) & MBOX2_DMA_TX_CONTROL_START_MASK) >> MBOX2_DMA_TX_CONTROL_START_LSB)
-#define MBOX2_DMA_TX_CONTROL_START_SET(x)        (((x) << MBOX2_DMA_TX_CONTROL_START_LSB) & MBOX2_DMA_TX_CONTROL_START_MASK)
-#define MBOX2_DMA_TX_CONTROL_STOP_MSB            0
-#define MBOX2_DMA_TX_CONTROL_STOP_LSB            0
-#define MBOX2_DMA_TX_CONTROL_STOP_MASK           0x00000001
-#define MBOX2_DMA_TX_CONTROL_STOP_GET(x)         (((x) & MBOX2_DMA_TX_CONTROL_STOP_MASK) >> MBOX2_DMA_TX_CONTROL_STOP_LSB)
-#define MBOX2_DMA_TX_CONTROL_STOP_SET(x)         (((x) << MBOX2_DMA_TX_CONTROL_STOP_LSB) & MBOX2_DMA_TX_CONTROL_STOP_MASK)
-
-#define MBOX3_DMA_RX_DESCRIPTOR_BASE_ADDRESS     0x00000048
-#define MBOX3_DMA_RX_DESCRIPTOR_BASE_OFFSET      0x00000048
-#define MBOX3_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MSB 27
-#define MBOX3_DMA_RX_DESCRIPTOR_BASE_ADDRESS_LSB 2
-#define MBOX3_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MASK 0x0ffffffc
-#define MBOX3_DMA_RX_DESCRIPTOR_BASE_ADDRESS_GET(x) (((x) & MBOX3_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MASK) >> MBOX3_DMA_RX_DESCRIPTOR_BASE_ADDRESS_LSB)
-#define MBOX3_DMA_RX_DESCRIPTOR_BASE_ADDRESS_SET(x) (((x) << MBOX3_DMA_RX_DESCRIPTOR_BASE_ADDRESS_LSB) & MBOX3_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MASK)
-
-#define MBOX3_DMA_RX_CONTROL_ADDRESS             0x0000004c
-#define MBOX3_DMA_RX_CONTROL_OFFSET              0x0000004c
-#define MBOX3_DMA_RX_CONTROL_RESUME_MSB          2
-#define MBOX3_DMA_RX_CONTROL_RESUME_LSB          2
-#define MBOX3_DMA_RX_CONTROL_RESUME_MASK         0x00000004
-#define MBOX3_DMA_RX_CONTROL_RESUME_GET(x)       (((x) & MBOX3_DMA_RX_CONTROL_RESUME_MASK) >> MBOX3_DMA_RX_CONTROL_RESUME_LSB)
-#define MBOX3_DMA_RX_CONTROL_RESUME_SET(x)       (((x) << MBOX3_DMA_RX_CONTROL_RESUME_LSB) & MBOX3_DMA_RX_CONTROL_RESUME_MASK)
-#define MBOX3_DMA_RX_CONTROL_START_MSB           1
-#define MBOX3_DMA_RX_CONTROL_START_LSB           1
-#define MBOX3_DMA_RX_CONTROL_START_MASK          0x00000002
-#define MBOX3_DMA_RX_CONTROL_START_GET(x)        (((x) & MBOX3_DMA_RX_CONTROL_START_MASK) >> MBOX3_DMA_RX_CONTROL_START_LSB)
-#define MBOX3_DMA_RX_CONTROL_START_SET(x)        (((x) << MBOX3_DMA_RX_CONTROL_START_LSB) & MBOX3_DMA_RX_CONTROL_START_MASK)
-#define MBOX3_DMA_RX_CONTROL_STOP_MSB            0
-#define MBOX3_DMA_RX_CONTROL_STOP_LSB            0
-#define MBOX3_DMA_RX_CONTROL_STOP_MASK           0x00000001
-#define MBOX3_DMA_RX_CONTROL_STOP_GET(x)         (((x) & MBOX3_DMA_RX_CONTROL_STOP_MASK) >> MBOX3_DMA_RX_CONTROL_STOP_LSB)
-#define MBOX3_DMA_RX_CONTROL_STOP_SET(x)         (((x) << MBOX3_DMA_RX_CONTROL_STOP_LSB) & MBOX3_DMA_RX_CONTROL_STOP_MASK)
-
-#define MBOX3_DMA_TX_DESCRIPTOR_BASE_ADDRESS     0x00000050
-#define MBOX3_DMA_TX_DESCRIPTOR_BASE_OFFSET      0x00000050
-#define MBOX3_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MSB 27
-#define MBOX3_DMA_TX_DESCRIPTOR_BASE_ADDRESS_LSB 2
-#define MBOX3_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MASK 0x0ffffffc
-#define MBOX3_DMA_TX_DESCRIPTOR_BASE_ADDRESS_GET(x) (((x) & MBOX3_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MASK) >> MBOX3_DMA_TX_DESCRIPTOR_BASE_ADDRESS_LSB)
-#define MBOX3_DMA_TX_DESCRIPTOR_BASE_ADDRESS_SET(x) (((x) << MBOX3_DMA_TX_DESCRIPTOR_BASE_ADDRESS_LSB) & MBOX3_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MASK)
-
-#define MBOX3_DMA_TX_CONTROL_ADDRESS             0x00000054
-#define MBOX3_DMA_TX_CONTROL_OFFSET              0x00000054
-#define MBOX3_DMA_TX_CONTROL_RESUME_MSB          2
-#define MBOX3_DMA_TX_CONTROL_RESUME_LSB          2
-#define MBOX3_DMA_TX_CONTROL_RESUME_MASK         0x00000004
-#define MBOX3_DMA_TX_CONTROL_RESUME_GET(x)       (((x) & MBOX3_DMA_TX_CONTROL_RESUME_MASK) >> MBOX3_DMA_TX_CONTROL_RESUME_LSB)
-#define MBOX3_DMA_TX_CONTROL_RESUME_SET(x)       (((x) << MBOX3_DMA_TX_CONTROL_RESUME_LSB) & MBOX3_DMA_TX_CONTROL_RESUME_MASK)
-#define MBOX3_DMA_TX_CONTROL_START_MSB           1
-#define MBOX3_DMA_TX_CONTROL_START_LSB           1
-#define MBOX3_DMA_TX_CONTROL_START_MASK          0x00000002
-#define MBOX3_DMA_TX_CONTROL_START_GET(x)        (((x) & MBOX3_DMA_TX_CONTROL_START_MASK) >> MBOX3_DMA_TX_CONTROL_START_LSB)
-#define MBOX3_DMA_TX_CONTROL_START_SET(x)        (((x) << MBOX3_DMA_TX_CONTROL_START_LSB) & MBOX3_DMA_TX_CONTROL_START_MASK)
-#define MBOX3_DMA_TX_CONTROL_STOP_MSB            0
-#define MBOX3_DMA_TX_CONTROL_STOP_LSB            0
-#define MBOX3_DMA_TX_CONTROL_STOP_MASK           0x00000001
-#define MBOX3_DMA_TX_CONTROL_STOP_GET(x)         (((x) & MBOX3_DMA_TX_CONTROL_STOP_MASK) >> MBOX3_DMA_TX_CONTROL_STOP_LSB)
-#define MBOX3_DMA_TX_CONTROL_STOP_SET(x)         (((x) << MBOX3_DMA_TX_CONTROL_STOP_LSB) & MBOX3_DMA_TX_CONTROL_STOP_MASK)
-
-#define MBOX_INT_STATUS_ADDRESS                  0x00000058
-#define MBOX_INT_STATUS_OFFSET                   0x00000058
-#define MBOX_INT_STATUS_RX_DMA_COMPLETE_MSB      31
-#define MBOX_INT_STATUS_RX_DMA_COMPLETE_LSB      28
-#define MBOX_INT_STATUS_RX_DMA_COMPLETE_MASK     0xf0000000
-#define MBOX_INT_STATUS_RX_DMA_COMPLETE_GET(x)   (((x) & MBOX_INT_STATUS_RX_DMA_COMPLETE_MASK) >> MBOX_INT_STATUS_RX_DMA_COMPLETE_LSB)
-#define MBOX_INT_STATUS_RX_DMA_COMPLETE_SET(x)   (((x) << MBOX_INT_STATUS_RX_DMA_COMPLETE_LSB) & MBOX_INT_STATUS_RX_DMA_COMPLETE_MASK)
-#define MBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_MSB  27
-#define MBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_LSB  24
-#define MBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_MASK 0x0f000000
-#define MBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_GET(x) (((x) & MBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_MASK) >> MBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_LSB)
-#define MBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_SET(x) (((x) << MBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_LSB) & MBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_MASK)
-#define MBOX_INT_STATUS_TX_DMA_COMPLETE_MSB      23
-#define MBOX_INT_STATUS_TX_DMA_COMPLETE_LSB      20
-#define MBOX_INT_STATUS_TX_DMA_COMPLETE_MASK     0x00f00000
-#define MBOX_INT_STATUS_TX_DMA_COMPLETE_GET(x)   (((x) & MBOX_INT_STATUS_TX_DMA_COMPLETE_MASK) >> MBOX_INT_STATUS_TX_DMA_COMPLETE_LSB)
-#define MBOX_INT_STATUS_TX_DMA_COMPLETE_SET(x)   (((x) << MBOX_INT_STATUS_TX_DMA_COMPLETE_LSB) & MBOX_INT_STATUS_TX_DMA_COMPLETE_MASK)
-#define MBOX_INT_STATUS_TX_OVERFLOW_MSB          17
-#define MBOX_INT_STATUS_TX_OVERFLOW_LSB          17
-#define MBOX_INT_STATUS_TX_OVERFLOW_MASK         0x00020000
-#define MBOX_INT_STATUS_TX_OVERFLOW_GET(x)       (((x) & MBOX_INT_STATUS_TX_OVERFLOW_MASK) >> MBOX_INT_STATUS_TX_OVERFLOW_LSB)
-#define MBOX_INT_STATUS_TX_OVERFLOW_SET(x)       (((x) << MBOX_INT_STATUS_TX_OVERFLOW_LSB) & MBOX_INT_STATUS_TX_OVERFLOW_MASK)
-#define MBOX_INT_STATUS_RX_UNDERFLOW_MSB         16
-#define MBOX_INT_STATUS_RX_UNDERFLOW_LSB         16
-#define MBOX_INT_STATUS_RX_UNDERFLOW_MASK        0x00010000
-#define MBOX_INT_STATUS_RX_UNDERFLOW_GET(x)      (((x) & MBOX_INT_STATUS_RX_UNDERFLOW_MASK) >> MBOX_INT_STATUS_RX_UNDERFLOW_LSB)
-#define MBOX_INT_STATUS_RX_UNDERFLOW_SET(x)      (((x) << MBOX_INT_STATUS_RX_UNDERFLOW_LSB) & MBOX_INT_STATUS_RX_UNDERFLOW_MASK)
-#define MBOX_INT_STATUS_TX_NOT_EMPTY_MSB         15
-#define MBOX_INT_STATUS_TX_NOT_EMPTY_LSB         12
-#define MBOX_INT_STATUS_TX_NOT_EMPTY_MASK        0x0000f000
-#define MBOX_INT_STATUS_TX_NOT_EMPTY_GET(x)      (((x) & MBOX_INT_STATUS_TX_NOT_EMPTY_MASK) >> MBOX_INT_STATUS_TX_NOT_EMPTY_LSB)
-#define MBOX_INT_STATUS_TX_NOT_EMPTY_SET(x)      (((x) << MBOX_INT_STATUS_TX_NOT_EMPTY_LSB) & MBOX_INT_STATUS_TX_NOT_EMPTY_MASK)
-#define MBOX_INT_STATUS_RX_NOT_FULL_MSB          11
-#define MBOX_INT_STATUS_RX_NOT_FULL_LSB          8
-#define MBOX_INT_STATUS_RX_NOT_FULL_MASK         0x00000f00
-#define MBOX_INT_STATUS_RX_NOT_FULL_GET(x)       (((x) & MBOX_INT_STATUS_RX_NOT_FULL_MASK) >> MBOX_INT_STATUS_RX_NOT_FULL_LSB)
-#define MBOX_INT_STATUS_RX_NOT_FULL_SET(x)       (((x) << MBOX_INT_STATUS_RX_NOT_FULL_LSB) & MBOX_INT_STATUS_RX_NOT_FULL_MASK)
-#define MBOX_INT_STATUS_HOST_MSB                 7
-#define MBOX_INT_STATUS_HOST_LSB                 0
-#define MBOX_INT_STATUS_HOST_MASK                0x000000ff
-#define MBOX_INT_STATUS_HOST_GET(x)              (((x) & MBOX_INT_STATUS_HOST_MASK) >> MBOX_INT_STATUS_HOST_LSB)
-#define MBOX_INT_STATUS_HOST_SET(x)              (((x) << MBOX_INT_STATUS_HOST_LSB) & MBOX_INT_STATUS_HOST_MASK)
-
-#define MBOX_INT_ENABLE_ADDRESS                  0x0000005c
-#define MBOX_INT_ENABLE_OFFSET                   0x0000005c
-#define MBOX_INT_ENABLE_RX_DMA_COMPLETE_MSB      31
-#define MBOX_INT_ENABLE_RX_DMA_COMPLETE_LSB      28
-#define MBOX_INT_ENABLE_RX_DMA_COMPLETE_MASK     0xf0000000
-#define MBOX_INT_ENABLE_RX_DMA_COMPLETE_GET(x)   (((x) & MBOX_INT_ENABLE_RX_DMA_COMPLETE_MASK) >> MBOX_INT_ENABLE_RX_DMA_COMPLETE_LSB)
-#define MBOX_INT_ENABLE_RX_DMA_COMPLETE_SET(x)   (((x) << MBOX_INT_ENABLE_RX_DMA_COMPLETE_LSB) & MBOX_INT_ENABLE_RX_DMA_COMPLETE_MASK)
-#define MBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_MSB  27
-#define MBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_LSB  24
-#define MBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_MASK 0x0f000000
-#define MBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_GET(x) (((x) & MBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_MASK) >> MBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_LSB)
-#define MBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_SET(x) (((x) << MBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_LSB) & MBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_MASK)
-#define MBOX_INT_ENABLE_TX_DMA_COMPLETE_MSB      23
-#define MBOX_INT_ENABLE_TX_DMA_COMPLETE_LSB      20
-#define MBOX_INT_ENABLE_TX_DMA_COMPLETE_MASK     0x00f00000
-#define MBOX_INT_ENABLE_TX_DMA_COMPLETE_GET(x)   (((x) & MBOX_INT_ENABLE_TX_DMA_COMPLETE_MASK) >> MBOX_INT_ENABLE_TX_DMA_COMPLETE_LSB)
-#define MBOX_INT_ENABLE_TX_DMA_COMPLETE_SET(x)   (((x) << MBOX_INT_ENABLE_TX_DMA_COMPLETE_LSB) & MBOX_INT_ENABLE_TX_DMA_COMPLETE_MASK)
-#define MBOX_INT_ENABLE_TX_OVERFLOW_MSB          17
-#define MBOX_INT_ENABLE_TX_OVERFLOW_LSB          17
-#define MBOX_INT_ENABLE_TX_OVERFLOW_MASK         0x00020000
-#define MBOX_INT_ENABLE_TX_OVERFLOW_GET(x)       (((x) & MBOX_INT_ENABLE_TX_OVERFLOW_MASK) >> MBOX_INT_ENABLE_TX_OVERFLOW_LSB)
-#define MBOX_INT_ENABLE_TX_OVERFLOW_SET(x)       (((x) << MBOX_INT_ENABLE_TX_OVERFLOW_LSB) & MBOX_INT_ENABLE_TX_OVERFLOW_MASK)
-#define MBOX_INT_ENABLE_RX_UNDERFLOW_MSB         16
-#define MBOX_INT_ENABLE_RX_UNDERFLOW_LSB         16
-#define MBOX_INT_ENABLE_RX_UNDERFLOW_MASK        0x00010000
-#define MBOX_INT_ENABLE_RX_UNDERFLOW_GET(x)      (((x) & MBOX_INT_ENABLE_RX_UNDERFLOW_MASK) >> MBOX_INT_ENABLE_RX_UNDERFLOW_LSB)
-#define MBOX_INT_ENABLE_RX_UNDERFLOW_SET(x)      (((x) << MBOX_INT_ENABLE_RX_UNDERFLOW_LSB) & MBOX_INT_ENABLE_RX_UNDERFLOW_MASK)
-#define MBOX_INT_ENABLE_TX_NOT_EMPTY_MSB         15
-#define MBOX_INT_ENABLE_TX_NOT_EMPTY_LSB         12
-#define MBOX_INT_ENABLE_TX_NOT_EMPTY_MASK        0x0000f000
-#define MBOX_INT_ENABLE_TX_NOT_EMPTY_GET(x)      (((x) & MBOX_INT_ENABLE_TX_NOT_EMPTY_MASK) >> MBOX_INT_ENABLE_TX_NOT_EMPTY_LSB)
-#define MBOX_INT_ENABLE_TX_NOT_EMPTY_SET(x)      (((x) << MBOX_INT_ENABLE_TX_NOT_EMPTY_LSB) & MBOX_INT_ENABLE_TX_NOT_EMPTY_MASK)
-#define MBOX_INT_ENABLE_RX_NOT_FULL_MSB          11
-#define MBOX_INT_ENABLE_RX_NOT_FULL_LSB          8
-#define MBOX_INT_ENABLE_RX_NOT_FULL_MASK         0x00000f00
-#define MBOX_INT_ENABLE_RX_NOT_FULL_GET(x)       (((x) & MBOX_INT_ENABLE_RX_NOT_FULL_MASK) >> MBOX_INT_ENABLE_RX_NOT_FULL_LSB)
-#define MBOX_INT_ENABLE_RX_NOT_FULL_SET(x)       (((x) << MBOX_INT_ENABLE_RX_NOT_FULL_LSB) & MBOX_INT_ENABLE_RX_NOT_FULL_MASK)
-#define MBOX_INT_ENABLE_HOST_MSB                 7
-#define MBOX_INT_ENABLE_HOST_LSB                 0
-#define MBOX_INT_ENABLE_HOST_MASK                0x000000ff
-#define MBOX_INT_ENABLE_HOST_GET(x)              (((x) & MBOX_INT_ENABLE_HOST_MASK) >> MBOX_INT_ENABLE_HOST_LSB)
-#define MBOX_INT_ENABLE_HOST_SET(x)              (((x) << MBOX_INT_ENABLE_HOST_LSB) & MBOX_INT_ENABLE_HOST_MASK)
-
-#define INT_HOST_ADDRESS                         0x00000060
-#define INT_HOST_OFFSET                          0x00000060
-#define INT_HOST_VECTOR_MSB                      7
-#define INT_HOST_VECTOR_LSB                      0
-#define INT_HOST_VECTOR_MASK                     0x000000ff
-#define INT_HOST_VECTOR_GET(x)                   (((x) & INT_HOST_VECTOR_MASK) >> INT_HOST_VECTOR_LSB)
-#define INT_HOST_VECTOR_SET(x)                   (((x) << INT_HOST_VECTOR_LSB) & INT_HOST_VECTOR_MASK)
-
-#define LOCAL_COUNT_ADDRESS                      0x00000080
-#define LOCAL_COUNT_OFFSET                       0x00000080
-#define LOCAL_COUNT_VALUE_MSB                    7
-#define LOCAL_COUNT_VALUE_LSB                    0
-#define LOCAL_COUNT_VALUE_MASK                   0x000000ff
-#define LOCAL_COUNT_VALUE_GET(x)                 (((x) & LOCAL_COUNT_VALUE_MASK) >> LOCAL_COUNT_VALUE_LSB)
-#define LOCAL_COUNT_VALUE_SET(x)                 (((x) << LOCAL_COUNT_VALUE_LSB) & LOCAL_COUNT_VALUE_MASK)
-
-#define COUNT_INC_ADDRESS                        0x000000a0
-#define COUNT_INC_OFFSET                         0x000000a0
-#define COUNT_INC_VALUE_MSB                      7
-#define COUNT_INC_VALUE_LSB                      0
-#define COUNT_INC_VALUE_MASK                     0x000000ff
-#define COUNT_INC_VALUE_GET(x)                   (((x) & COUNT_INC_VALUE_MASK) >> COUNT_INC_VALUE_LSB)
-#define COUNT_INC_VALUE_SET(x)                   (((x) << COUNT_INC_VALUE_LSB) & COUNT_INC_VALUE_MASK)
-
-#define LOCAL_SCRATCH_ADDRESS                    0x000000c0
-#define LOCAL_SCRATCH_OFFSET                     0x000000c0
-#define LOCAL_SCRATCH_VALUE_MSB                  7
-#define LOCAL_SCRATCH_VALUE_LSB                  0
-#define LOCAL_SCRATCH_VALUE_MASK                 0x000000ff
-#define LOCAL_SCRATCH_VALUE_GET(x)               (((x) & LOCAL_SCRATCH_VALUE_MASK) >> LOCAL_SCRATCH_VALUE_LSB)
-#define LOCAL_SCRATCH_VALUE_SET(x)               (((x) << LOCAL_SCRATCH_VALUE_LSB) & LOCAL_SCRATCH_VALUE_MASK)
-
-#define USE_LOCAL_BUS_ADDRESS                    0x000000e0
-#define USE_LOCAL_BUS_OFFSET                     0x000000e0
-#define USE_LOCAL_BUS_PIN_INIT_MSB               0
-#define USE_LOCAL_BUS_PIN_INIT_LSB               0
-#define USE_LOCAL_BUS_PIN_INIT_MASK              0x00000001
-#define USE_LOCAL_BUS_PIN_INIT_GET(x)            (((x) & USE_LOCAL_BUS_PIN_INIT_MASK) >> USE_LOCAL_BUS_PIN_INIT_LSB)
-#define USE_LOCAL_BUS_PIN_INIT_SET(x)            (((x) << USE_LOCAL_BUS_PIN_INIT_LSB) & USE_LOCAL_BUS_PIN_INIT_MASK)
-
-#define SDIO_CONFIG_ADDRESS                      0x000000e4
-#define SDIO_CONFIG_OFFSET                       0x000000e4
-#define SDIO_CONFIG_CCCR_IOR1_MSB                0
-#define SDIO_CONFIG_CCCR_IOR1_LSB                0
-#define SDIO_CONFIG_CCCR_IOR1_MASK               0x00000001
-#define SDIO_CONFIG_CCCR_IOR1_GET(x)             (((x) & SDIO_CONFIG_CCCR_IOR1_MASK) >> SDIO_CONFIG_CCCR_IOR1_LSB)
-#define SDIO_CONFIG_CCCR_IOR1_SET(x)             (((x) << SDIO_CONFIG_CCCR_IOR1_LSB) & SDIO_CONFIG_CCCR_IOR1_MASK)
-
-#define MBOX_DEBUG_ADDRESS                       0x000000e8
-#define MBOX_DEBUG_OFFSET                        0x000000e8
-#define MBOX_DEBUG_SEL_MSB                       2
-#define MBOX_DEBUG_SEL_LSB                       0
-#define MBOX_DEBUG_SEL_MASK                      0x00000007
-#define MBOX_DEBUG_SEL_GET(x)                    (((x) & MBOX_DEBUG_SEL_MASK) >> MBOX_DEBUG_SEL_LSB)
-#define MBOX_DEBUG_SEL_SET(x)                    (((x) << MBOX_DEBUG_SEL_LSB) & MBOX_DEBUG_SEL_MASK)
-
-#define MBOX_FIFO_RESET_ADDRESS                  0x000000ec
-#define MBOX_FIFO_RESET_OFFSET                   0x000000ec
-#define MBOX_FIFO_RESET_INIT_MSB                 0
-#define MBOX_FIFO_RESET_INIT_LSB                 0
-#define MBOX_FIFO_RESET_INIT_MASK                0x00000001
-#define MBOX_FIFO_RESET_INIT_GET(x)              (((x) & MBOX_FIFO_RESET_INIT_MASK) >> MBOX_FIFO_RESET_INIT_LSB)
-#define MBOX_FIFO_RESET_INIT_SET(x)              (((x) << MBOX_FIFO_RESET_INIT_LSB) & MBOX_FIFO_RESET_INIT_MASK)
-
-#define MBOX_TXFIFO_POP_ADDRESS                  0x000000f0
-#define MBOX_TXFIFO_POP_OFFSET                   0x000000f0
-#define MBOX_TXFIFO_POP_DATA_MSB                 0
-#define MBOX_TXFIFO_POP_DATA_LSB                 0
-#define MBOX_TXFIFO_POP_DATA_MASK                0x00000001
-#define MBOX_TXFIFO_POP_DATA_GET(x)              (((x) & MBOX_TXFIFO_POP_DATA_MASK) >> MBOX_TXFIFO_POP_DATA_LSB)
-#define MBOX_TXFIFO_POP_DATA_SET(x)              (((x) << MBOX_TXFIFO_POP_DATA_LSB) & MBOX_TXFIFO_POP_DATA_MASK)
-
-#define MBOX_RXFIFO_POP_ADDRESS                  0x00000100
-#define MBOX_RXFIFO_POP_OFFSET                   0x00000100
-#define MBOX_RXFIFO_POP_DATA_MSB                 0
-#define MBOX_RXFIFO_POP_DATA_LSB                 0
-#define MBOX_RXFIFO_POP_DATA_MASK                0x00000001
-#define MBOX_RXFIFO_POP_DATA_GET(x)              (((x) & MBOX_RXFIFO_POP_DATA_MASK) >> MBOX_RXFIFO_POP_DATA_LSB)
-#define MBOX_RXFIFO_POP_DATA_SET(x)              (((x) << MBOX_RXFIFO_POP_DATA_LSB) & MBOX_RXFIFO_POP_DATA_MASK)
-
-#define SDIO_DEBUG_ADDRESS                       0x00000110
-#define SDIO_DEBUG_OFFSET                        0x00000110
-#define SDIO_DEBUG_SEL_MSB                       3
-#define SDIO_DEBUG_SEL_LSB                       0
-#define SDIO_DEBUG_SEL_MASK                      0x0000000f
-#define SDIO_DEBUG_SEL_GET(x)                    (((x) & SDIO_DEBUG_SEL_MASK) >> SDIO_DEBUG_SEL_LSB)
-#define SDIO_DEBUG_SEL_SET(x)                    (((x) << SDIO_DEBUG_SEL_LSB) & SDIO_DEBUG_SEL_MASK)
-
-#define HOST_IF_WINDOW_ADDRESS                   0x00002000
-#define HOST_IF_WINDOW_OFFSET                    0x00002000
-#define HOST_IF_WINDOW_DATA_MSB                  7
-#define HOST_IF_WINDOW_DATA_LSB                  0
-#define HOST_IF_WINDOW_DATA_MASK                 0x000000ff
-#define HOST_IF_WINDOW_DATA_GET(x)               (((x) & HOST_IF_WINDOW_DATA_MASK) >> HOST_IF_WINDOW_DATA_LSB)
-#define HOST_IF_WINDOW_DATA_SET(x)               (((x) << HOST_IF_WINDOW_DATA_LSB) & HOST_IF_WINDOW_DATA_MASK)
-
-
-#ifndef __ASSEMBLER__
-
-typedef struct mbox_reg_reg_s {
-  volatile unsigned int mbox_fifo[4];
-  volatile unsigned int mbox_fifo_status;
-  volatile unsigned int mbox_dma_policy;
-  volatile unsigned int mbox0_dma_rx_descriptor_base;
-  volatile unsigned int mbox0_dma_rx_control;
-  volatile unsigned int mbox0_dma_tx_descriptor_base;
-  volatile unsigned int mbox0_dma_tx_control;
-  volatile unsigned int mbox1_dma_rx_descriptor_base;
-  volatile unsigned int mbox1_dma_rx_control;
-  volatile unsigned int mbox1_dma_tx_descriptor_base;
-  volatile unsigned int mbox1_dma_tx_control;
-  volatile unsigned int mbox2_dma_rx_descriptor_base;
-  volatile unsigned int mbox2_dma_rx_control;
-  volatile unsigned int mbox2_dma_tx_descriptor_base;
-  volatile unsigned int mbox2_dma_tx_control;
-  volatile unsigned int mbox3_dma_rx_descriptor_base;
-  volatile unsigned int mbox3_dma_rx_control;
-  volatile unsigned int mbox3_dma_tx_descriptor_base;
-  volatile unsigned int mbox3_dma_tx_control;
-  volatile unsigned int mbox_int_status;
-  volatile unsigned int mbox_int_enable;
-  volatile unsigned int int_host;
-  unsigned char pad0[28]; /* pad to 0x80 */
-  volatile unsigned int local_count[8];
-  volatile unsigned int count_inc[8];
-  volatile unsigned int local_scratch[8];
-  volatile unsigned int use_local_bus;
-  volatile unsigned int sdio_config;
-  volatile unsigned int mbox_debug;
-  volatile unsigned int mbox_fifo_reset;
-  volatile unsigned int mbox_txfifo_pop[4];
-  volatile unsigned int mbox_rxfifo_pop[4];
-  volatile unsigned int sdio_debug;
-  unsigned char pad1[7916]; /* pad to 0x2000 */
-  volatile unsigned int host_if_window[2048];
-} mbox_reg_reg_t;
-
-#endif /* __ASSEMBLER__ */
-
-#endif /* _MBOX_REG_H_ */
diff -druN linux-2.6.39-libre/drivers/staging/ath6kl/include/common/AR6002/hw2.0/hw/rtc_reg.h linux-3.0-rc7-libre/drivers/staging/ath6kl/include/common/AR6002/hw2.0/hw/rtc_reg.h
--- linux-2.6.39-libre/drivers/staging/ath6kl/include/common/AR6002/hw2.0/hw/rtc_reg.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/ath6kl/include/common/AR6002/hw2.0/hw/rtc_reg.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,1163 +0,0 @@
-#ifndef _RTC_REG_REG_H_
-#define _RTC_REG_REG_H_
-
-#define RESET_CONTROL_ADDRESS                    0x00000000
-#define RESET_CONTROL_OFFSET                     0x00000000
-#define RESET_CONTROL_CPU_INIT_RESET_MSB         11
-#define RESET_CONTROL_CPU_INIT_RESET_LSB         11
-#define RESET_CONTROL_CPU_INIT_RESET_MASK        0x00000800
-#define RESET_CONTROL_CPU_INIT_RESET_GET(x)      (((x) & RESET_CONTROL_CPU_INIT_RESET_MASK) >> RESET_CONTROL_CPU_INIT_RESET_LSB)
-#define RESET_CONTROL_CPU_INIT_RESET_SET(x)      (((x) << RESET_CONTROL_CPU_INIT_RESET_LSB) & RESET_CONTROL_CPU_INIT_RESET_MASK)
-#define RESET_CONTROL_VMC_REMAP_RESET_MSB        10
-#define RESET_CONTROL_VMC_REMAP_RESET_LSB        10
-#define RESET_CONTROL_VMC_REMAP_RESET_MASK       0x00000400
-#define RESET_CONTROL_VMC_REMAP_RESET_GET(x)     (((x) & RESET_CONTROL_VMC_REMAP_RESET_MASK) >> RESET_CONTROL_VMC_REMAP_RESET_LSB)
-#define RESET_CONTROL_VMC_REMAP_RESET_SET(x)     (((x) << RESET_CONTROL_VMC_REMAP_RESET_LSB) & RESET_CONTROL_VMC_REMAP_RESET_MASK)
-#define RESET_CONTROL_RST_OUT_MSB                9
-#define RESET_CONTROL_RST_OUT_LSB                9
-#define RESET_CONTROL_RST_OUT_MASK               0x00000200
-#define RESET_CONTROL_RST_OUT_GET(x)             (((x) & RESET_CONTROL_RST_OUT_MASK) >> RESET_CONTROL_RST_OUT_LSB)
-#define RESET_CONTROL_RST_OUT_SET(x)             (((x) << RESET_CONTROL_RST_OUT_LSB) & RESET_CONTROL_RST_OUT_MASK)
-#define RESET_CONTROL_COLD_RST_MSB               8
-#define RESET_CONTROL_COLD_RST_LSB               8
-#define RESET_CONTROL_COLD_RST_MASK              0x00000100
-#define RESET_CONTROL_COLD_RST_GET(x)            (((x) & RESET_CONTROL_COLD_RST_MASK) >> RESET_CONTROL_COLD_RST_LSB)
-#define RESET_CONTROL_COLD_RST_SET(x)            (((x) << RESET_CONTROL_COLD_RST_LSB) & RESET_CONTROL_COLD_RST_MASK)
-#define RESET_CONTROL_WARM_RST_MSB               7
-#define RESET_CONTROL_WARM_RST_LSB               7
-#define RESET_CONTROL_WARM_RST_MASK              0x00000080
-#define RESET_CONTROL_WARM_RST_GET(x)            (((x) & RESET_CONTROL_WARM_RST_MASK) >> RESET_CONTROL_WARM_RST_LSB)
-#define RESET_CONTROL_WARM_RST_SET(x)            (((x) << RESET_CONTROL_WARM_RST_LSB) & RESET_CONTROL_WARM_RST_MASK)
-#define RESET_CONTROL_CPU_WARM_RST_MSB           6
-#define RESET_CONTROL_CPU_WARM_RST_LSB           6
-#define RESET_CONTROL_CPU_WARM_RST_MASK          0x00000040
-#define RESET_CONTROL_CPU_WARM_RST_GET(x)        (((x) & RESET_CONTROL_CPU_WARM_RST_MASK) >> RESET_CONTROL_CPU_WARM_RST_LSB)
-#define RESET_CONTROL_CPU_WARM_RST_SET(x)        (((x) << RESET_CONTROL_CPU_WARM_RST_LSB) & RESET_CONTROL_CPU_WARM_RST_MASK)
-#define RESET_CONTROL_MAC_COLD_RST_MSB           5
-#define RESET_CONTROL_MAC_COLD_RST_LSB           5
-#define RESET_CONTROL_MAC_COLD_RST_MASK          0x00000020
-#define RESET_CONTROL_MAC_COLD_RST_GET(x)        (((x) & RESET_CONTROL_MAC_COLD_RST_MASK) >> RESET_CONTROL_MAC_COLD_RST_LSB)
-#define RESET_CONTROL_MAC_COLD_RST_SET(x)        (((x) << RESET_CONTROL_MAC_COLD_RST_LSB) & RESET_CONTROL_MAC_COLD_RST_MASK)
-#define RESET_CONTROL_MAC_WARM_RST_MSB           4
-#define RESET_CONTROL_MAC_WARM_RST_LSB           4
-#define RESET_CONTROL_MAC_WARM_RST_MASK          0x00000010
-#define RESET_CONTROL_MAC_WARM_RST_GET(x)        (((x) & RESET_CONTROL_MAC_WARM_RST_MASK) >> RESET_CONTROL_MAC_WARM_RST_LSB)
-#define RESET_CONTROL_MAC_WARM_RST_SET(x)        (((x) << RESET_CONTROL_MAC_WARM_RST_LSB) & RESET_CONTROL_MAC_WARM_RST_MASK)
-#define RESET_CONTROL_MBOX_RST_MSB               2
-#define RESET_CONTROL_MBOX_RST_LSB               2
-#define RESET_CONTROL_MBOX_RST_MASK              0x00000004
-#define RESET_CONTROL_MBOX_RST_GET(x)            (((x) & RESET_CONTROL_MBOX_RST_MASK) >> RESET_CONTROL_MBOX_RST_LSB)
-#define RESET_CONTROL_MBOX_RST_SET(x)            (((x) << RESET_CONTROL_MBOX_RST_LSB) & RESET_CONTROL_MBOX_RST_MASK)
-#define RESET_CONTROL_UART_RST_MSB               1
-#define RESET_CONTROL_UART_RST_LSB               1
-#define RESET_CONTROL_UART_RST_MASK              0x00000002
-#define RESET_CONTROL_UART_RST_GET(x)            (((x) & RESET_CONTROL_UART_RST_MASK) >> RESET_CONTROL_UART_RST_LSB)
-#define RESET_CONTROL_UART_RST_SET(x)            (((x) << RESET_CONTROL_UART_RST_LSB) & RESET_CONTROL_UART_RST_MASK)
-#define RESET_CONTROL_SI0_RST_MSB                0
-#define RESET_CONTROL_SI0_RST_LSB                0
-#define RESET_CONTROL_SI0_RST_MASK               0x00000001
-#define RESET_CONTROL_SI0_RST_GET(x)             (((x) & RESET_CONTROL_SI0_RST_MASK) >> RESET_CONTROL_SI0_RST_LSB)
-#define RESET_CONTROL_SI0_RST_SET(x)             (((x) << RESET_CONTROL_SI0_RST_LSB) & RESET_CONTROL_SI0_RST_MASK)
-
-#define XTAL_CONTROL_ADDRESS                     0x00000004
-#define XTAL_CONTROL_OFFSET                      0x00000004
-#define XTAL_CONTROL_TCXO_MSB                    0
-#define XTAL_CONTROL_TCXO_LSB                    0
-#define XTAL_CONTROL_TCXO_MASK                   0x00000001
-#define XTAL_CONTROL_TCXO_GET(x)                 (((x) & XTAL_CONTROL_TCXO_MASK) >> XTAL_CONTROL_TCXO_LSB)
-#define XTAL_CONTROL_TCXO_SET(x)                 (((x) << XTAL_CONTROL_TCXO_LSB) & XTAL_CONTROL_TCXO_MASK)
-
-#define TCXO_DETECT_ADDRESS                      0x00000008
-#define TCXO_DETECT_OFFSET                       0x00000008
-#define TCXO_DETECT_PRESENT_MSB                  0
-#define TCXO_DETECT_PRESENT_LSB                  0
-#define TCXO_DETECT_PRESENT_MASK                 0x00000001
-#define TCXO_DETECT_PRESENT_GET(x)               (((x) & TCXO_DETECT_PRESENT_MASK) >> TCXO_DETECT_PRESENT_LSB)
-#define TCXO_DETECT_PRESENT_SET(x)               (((x) << TCXO_DETECT_PRESENT_LSB) & TCXO_DETECT_PRESENT_MASK)
-
-#define XTAL_TEST_ADDRESS                        0x0000000c
-#define XTAL_TEST_OFFSET                         0x0000000c
-#define XTAL_TEST_NOTCXODET_MSB                  0
-#define XTAL_TEST_NOTCXODET_LSB                  0
-#define XTAL_TEST_NOTCXODET_MASK                 0x00000001
-#define XTAL_TEST_NOTCXODET_GET(x)               (((x) & XTAL_TEST_NOTCXODET_MASK) >> XTAL_TEST_NOTCXODET_LSB)
-#define XTAL_TEST_NOTCXODET_SET(x)               (((x) << XTAL_TEST_NOTCXODET_LSB) & XTAL_TEST_NOTCXODET_MASK)
-
-#define QUADRATURE_ADDRESS                       0x00000010
-#define QUADRATURE_OFFSET                        0x00000010
-#define QUADRATURE_ADC_MSB                       5
-#define QUADRATURE_ADC_LSB                       4
-#define QUADRATURE_ADC_MASK                      0x00000030
-#define QUADRATURE_ADC_GET(x)                    (((x) & QUADRATURE_ADC_MASK) >> QUADRATURE_ADC_LSB)
-#define QUADRATURE_ADC_SET(x)                    (((x) << QUADRATURE_ADC_LSB) & QUADRATURE_ADC_MASK)
-#define QUADRATURE_SEL_MSB                       2
-#define QUADRATURE_SEL_LSB                       2
-#define QUADRATURE_SEL_MASK                      0x00000004
-#define QUADRATURE_SEL_GET(x)                    (((x) & QUADRATURE_SEL_MASK) >> QUADRATURE_SEL_LSB)
-#define QUADRATURE_SEL_SET(x)                    (((x) << QUADRATURE_SEL_LSB) & QUADRATURE_SEL_MASK)
-#define QUADRATURE_DAC_MSB                       1
-#define QUADRATURE_DAC_LSB                       0
-#define QUADRATURE_DAC_MASK                      0x00000003
-#define QUADRATURE_DAC_GET(x)                    (((x) & QUADRATURE_DAC_MASK) >> QUADRATURE_DAC_LSB)
-#define QUADRATURE_DAC_SET(x)                    (((x) << QUADRATURE_DAC_LSB) & QUADRATURE_DAC_MASK)
-
-#define PLL_CONTROL_ADDRESS                      0x00000014
-#define PLL_CONTROL_OFFSET                       0x00000014
-#define PLL_CONTROL_DIG_TEST_CLK_MSB             20
-#define PLL_CONTROL_DIG_TEST_CLK_LSB             20
-#define PLL_CONTROL_DIG_TEST_CLK_MASK            0x00100000
-#define PLL_CONTROL_DIG_TEST_CLK_GET(x)          (((x) & PLL_CONTROL_DIG_TEST_CLK_MASK) >> PLL_CONTROL_DIG_TEST_CLK_LSB)
-#define PLL_CONTROL_DIG_TEST_CLK_SET(x)          (((x) << PLL_CONTROL_DIG_TEST_CLK_LSB) & PLL_CONTROL_DIG_TEST_CLK_MASK)
-#define PLL_CONTROL_MAC_OVERRIDE_MSB             19
-#define PLL_CONTROL_MAC_OVERRIDE_LSB             19
-#define PLL_CONTROL_MAC_OVERRIDE_MASK            0x00080000
-#define PLL_CONTROL_MAC_OVERRIDE_GET(x)          (((x) & PLL_CONTROL_MAC_OVERRIDE_MASK) >> PLL_CONTROL_MAC_OVERRIDE_LSB)
-#define PLL_CONTROL_MAC_OVERRIDE_SET(x)          (((x) << PLL_CONTROL_MAC_OVERRIDE_LSB) & PLL_CONTROL_MAC_OVERRIDE_MASK)
-#define PLL_CONTROL_NOPWD_MSB                    18
-#define PLL_CONTROL_NOPWD_LSB                    18
-#define PLL_CONTROL_NOPWD_MASK                   0x00040000
-#define PLL_CONTROL_NOPWD_GET(x)                 (((x) & PLL_CONTROL_NOPWD_MASK) >> PLL_CONTROL_NOPWD_LSB)
-#define PLL_CONTROL_NOPWD_SET(x)                 (((x) << PLL_CONTROL_NOPWD_LSB) & PLL_CONTROL_NOPWD_MASK)
-#define PLL_CONTROL_UPDATING_MSB                 17
-#define PLL_CONTROL_UPDATING_LSB                 17
-#define PLL_CONTROL_UPDATING_MASK                0x00020000
-#define PLL_CONTROL_UPDATING_GET(x)              (((x) & PLL_CONTROL_UPDATING_MASK) >> PLL_CONTROL_UPDATING_LSB)
-#define PLL_CONTROL_UPDATING_SET(x)              (((x) << PLL_CONTROL_UPDATING_LSB) & PLL_CONTROL_UPDATING_MASK)
-#define PLL_CONTROL_BYPASS_MSB                   16
-#define PLL_CONTROL_BYPASS_LSB                   16
-#define PLL_CONTROL_BYPASS_MASK                  0x00010000
-#define PLL_CONTROL_BYPASS_GET(x)                (((x) & PLL_CONTROL_BYPASS_MASK) >> PLL_CONTROL_BYPASS_LSB)
-#define PLL_CONTROL_BYPASS_SET(x)                (((x) << PLL_CONTROL_BYPASS_LSB) & PLL_CONTROL_BYPASS_MASK)
-#define PLL_CONTROL_REFDIV_MSB                   15
-#define PLL_CONTROL_REFDIV_LSB                   12
-#define PLL_CONTROL_REFDIV_MASK                  0x0000f000
-#define PLL_CONTROL_REFDIV_GET(x)                (((x) & PLL_CONTROL_REFDIV_MASK) >> PLL_CONTROL_REFDIV_LSB)
-#define PLL_CONTROL_REFDIV_SET(x)                (((x) << PLL_CONTROL_REFDIV_LSB) & PLL_CONTROL_REFDIV_MASK)
-#define PLL_CONTROL_DIV_MSB                      9
-#define PLL_CONTROL_DIV_LSB                      0
-#define PLL_CONTROL_DIV_MASK                     0x000003ff
-#define PLL_CONTROL_DIV_GET(x)                   (((x) & PLL_CONTROL_DIV_MASK) >> PLL_CONTROL_DIV_LSB)
-#define PLL_CONTROL_DIV_SET(x)                   (((x) << PLL_CONTROL_DIV_LSB) & PLL_CONTROL_DIV_MASK)
-
-#define PLL_SETTLE_ADDRESS                       0x00000018
-#define PLL_SETTLE_OFFSET                        0x00000018
-#define PLL_SETTLE_TIME_MSB                      11
-#define PLL_SETTLE_TIME_LSB                      0
-#define PLL_SETTLE_TIME_MASK                     0x00000fff
-#define PLL_SETTLE_TIME_GET(x)                   (((x) & PLL_SETTLE_TIME_MASK) >> PLL_SETTLE_TIME_LSB)
-#define PLL_SETTLE_TIME_SET(x)                   (((x) << PLL_SETTLE_TIME_LSB) & PLL_SETTLE_TIME_MASK)
-
-#define XTAL_SETTLE_ADDRESS                      0x0000001c
-#define XTAL_SETTLE_OFFSET                       0x0000001c
-#define XTAL_SETTLE_TIME_MSB                     7
-#define XTAL_SETTLE_TIME_LSB                     0
-#define XTAL_SETTLE_TIME_MASK                    0x000000ff
-#define XTAL_SETTLE_TIME_GET(x)                  (((x) & XTAL_SETTLE_TIME_MASK) >> XTAL_SETTLE_TIME_LSB)
-#define XTAL_SETTLE_TIME_SET(x)                  (((x) << XTAL_SETTLE_TIME_LSB) & XTAL_SETTLE_TIME_MASK)
-
-#define CPU_CLOCK_ADDRESS                        0x00000020
-#define CPU_CLOCK_OFFSET                         0x00000020
-#define CPU_CLOCK_STANDARD_MSB                   1
-#define CPU_CLOCK_STANDARD_LSB                   0
-#define CPU_CLOCK_STANDARD_MASK                  0x00000003
-#define CPU_CLOCK_STANDARD_GET(x)                (((x) & CPU_CLOCK_STANDARD_MASK) >> CPU_CLOCK_STANDARD_LSB)
-#define CPU_CLOCK_STANDARD_SET(x)                (((x) << CPU_CLOCK_STANDARD_LSB) & CPU_CLOCK_STANDARD_MASK)
-
-#define CLOCK_OUT_ADDRESS                        0x00000024
-#define CLOCK_OUT_OFFSET                         0x00000024
-#define CLOCK_OUT_SELECT_MSB                     3
-#define CLOCK_OUT_SELECT_LSB                     0
-#define CLOCK_OUT_SELECT_MASK                    0x0000000f
-#define CLOCK_OUT_SELECT_GET(x)                  (((x) & CLOCK_OUT_SELECT_MASK) >> CLOCK_OUT_SELECT_LSB)
-#define CLOCK_OUT_SELECT_SET(x)                  (((x) << CLOCK_OUT_SELECT_LSB) & CLOCK_OUT_SELECT_MASK)
-
-#define CLOCK_CONTROL_ADDRESS                    0x00000028
-#define CLOCK_CONTROL_OFFSET                     0x00000028
-#define CLOCK_CONTROL_LF_CLK32_MSB               2
-#define CLOCK_CONTROL_LF_CLK32_LSB               2
-#define CLOCK_CONTROL_LF_CLK32_MASK              0x00000004
-#define CLOCK_CONTROL_LF_CLK32_GET(x)            (((x) & CLOCK_CONTROL_LF_CLK32_MASK) >> CLOCK_CONTROL_LF_CLK32_LSB)
-#define CLOCK_CONTROL_LF_CLK32_SET(x)            (((x) << CLOCK_CONTROL_LF_CLK32_LSB) & CLOCK_CONTROL_LF_CLK32_MASK)
-#define CLOCK_CONTROL_UART_CLK_MSB               1
-#define CLOCK_CONTROL_UART_CLK_LSB               1
-#define CLOCK_CONTROL_UART_CLK_MASK              0x00000002
-#define CLOCK_CONTROL_UART_CLK_GET(x)            (((x) & CLOCK_CONTROL_UART_CLK_MASK) >> CLOCK_CONTROL_UART_CLK_LSB)
-#define CLOCK_CONTROL_UART_CLK_SET(x)            (((x) << CLOCK_CONTROL_UART_CLK_LSB) & CLOCK_CONTROL_UART_CLK_MASK)
-#define CLOCK_CONTROL_SI0_CLK_MSB                0
-#define CLOCK_CONTROL_SI0_CLK_LSB                0
-#define CLOCK_CONTROL_SI0_CLK_MASK               0x00000001
-#define CLOCK_CONTROL_SI0_CLK_GET(x)             (((x) & CLOCK_CONTROL_SI0_CLK_MASK) >> CLOCK_CONTROL_SI0_CLK_LSB)
-#define CLOCK_CONTROL_SI0_CLK_SET(x)             (((x) << CLOCK_CONTROL_SI0_CLK_LSB) & CLOCK_CONTROL_SI0_CLK_MASK)
-
-#define BIAS_OVERRIDE_ADDRESS                    0x0000002c
-#define BIAS_OVERRIDE_OFFSET                     0x0000002c
-#define BIAS_OVERRIDE_ON_MSB                     0
-#define BIAS_OVERRIDE_ON_LSB                     0
-#define BIAS_OVERRIDE_ON_MASK                    0x00000001
-#define BIAS_OVERRIDE_ON_GET(x)                  (((x) & BIAS_OVERRIDE_ON_MASK) >> BIAS_OVERRIDE_ON_LSB)
-#define BIAS_OVERRIDE_ON_SET(x)                  (((x) << BIAS_OVERRIDE_ON_LSB) & BIAS_OVERRIDE_ON_MASK)
-
-#define WDT_CONTROL_ADDRESS                      0x00000030
-#define WDT_CONTROL_OFFSET                       0x00000030
-#define WDT_CONTROL_ACTION_MSB                   2
-#define WDT_CONTROL_ACTION_LSB                   0
-#define WDT_CONTROL_ACTION_MASK                  0x00000007
-#define WDT_CONTROL_ACTION_GET(x)                (((x) & WDT_CONTROL_ACTION_MASK) >> WDT_CONTROL_ACTION_LSB)
-#define WDT_CONTROL_ACTION_SET(x)                (((x) << WDT_CONTROL_ACTION_LSB) & WDT_CONTROL_ACTION_MASK)
-
-#define WDT_STATUS_ADDRESS                       0x00000034
-#define WDT_STATUS_OFFSET                        0x00000034
-#define WDT_STATUS_INTERRUPT_MSB                 0
-#define WDT_STATUS_INTERRUPT_LSB                 0
-#define WDT_STATUS_INTERRUPT_MASK                0x00000001
-#define WDT_STATUS_INTERRUPT_GET(x)              (((x) & WDT_STATUS_INTERRUPT_MASK) >> WDT_STATUS_INTERRUPT_LSB)
-#define WDT_STATUS_INTERRUPT_SET(x)              (((x) << WDT_STATUS_INTERRUPT_LSB) & WDT_STATUS_INTERRUPT_MASK)
-
-#define WDT_ADDRESS                              0x00000038
-#define WDT_OFFSET                               0x00000038
-#define WDT_TARGET_MSB                           21
-#define WDT_TARGET_LSB                           0
-#define WDT_TARGET_MASK                          0x003fffff
-#define WDT_TARGET_GET(x)                        (((x) & WDT_TARGET_MASK) >> WDT_TARGET_LSB)
-#define WDT_TARGET_SET(x)                        (((x) << WDT_TARGET_LSB) & WDT_TARGET_MASK)
-
-#define WDT_COUNT_ADDRESS                        0x0000003c
-#define WDT_COUNT_OFFSET                         0x0000003c
-#define WDT_COUNT_VALUE_MSB                      21
-#define WDT_COUNT_VALUE_LSB                      0
-#define WDT_COUNT_VALUE_MASK                     0x003fffff
-#define WDT_COUNT_VALUE_GET(x)                   (((x) & WDT_COUNT_VALUE_MASK) >> WDT_COUNT_VALUE_LSB)
-#define WDT_COUNT_VALUE_SET(x)                   (((x) << WDT_COUNT_VALUE_LSB) & WDT_COUNT_VALUE_MASK)
-
-#define WDT_RESET_ADDRESS                        0x00000040
-#define WDT_RESET_OFFSET                         0x00000040
-#define WDT_RESET_VALUE_MSB                      0
-#define WDT_RESET_VALUE_LSB                      0
-#define WDT_RESET_VALUE_MASK                     0x00000001
-#define WDT_RESET_VALUE_GET(x)                   (((x) & WDT_RESET_VALUE_MASK) >> WDT_RESET_VALUE_LSB)
-#define WDT_RESET_VALUE_SET(x)                   (((x) << WDT_RESET_VALUE_LSB) & WDT_RESET_VALUE_MASK)
-
-#define INT_STATUS_ADDRESS                       0x00000044
-#define INT_STATUS_OFFSET                        0x00000044
-#define INT_STATUS_RTC_POWER_MSB                 14
-#define INT_STATUS_RTC_POWER_LSB                 14
-#define INT_STATUS_RTC_POWER_MASK                0x00004000
-#define INT_STATUS_RTC_POWER_GET(x)              (((x) & INT_STATUS_RTC_POWER_MASK) >> INT_STATUS_RTC_POWER_LSB)
-#define INT_STATUS_RTC_POWER_SET(x)              (((x) << INT_STATUS_RTC_POWER_LSB) & INT_STATUS_RTC_POWER_MASK)
-#define INT_STATUS_MAC_MSB                       13
-#define INT_STATUS_MAC_LSB                       13
-#define INT_STATUS_MAC_MASK                      0x00002000
-#define INT_STATUS_MAC_GET(x)                    (((x) & INT_STATUS_MAC_MASK) >> INT_STATUS_MAC_LSB)
-#define INT_STATUS_MAC_SET(x)                    (((x) << INT_STATUS_MAC_LSB) & INT_STATUS_MAC_MASK)
-#define INT_STATUS_MAILBOX_MSB                   12
-#define INT_STATUS_MAILBOX_LSB                   12
-#define INT_STATUS_MAILBOX_MASK                  0x00001000
-#define INT_STATUS_MAILBOX_GET(x)                (((x) & INT_STATUS_MAILBOX_MASK) >> INT_STATUS_MAILBOX_LSB)
-#define INT_STATUS_MAILBOX_SET(x)                (((x) << INT_STATUS_MAILBOX_LSB) & INT_STATUS_MAILBOX_MASK)
-#define INT_STATUS_RTC_ALARM_MSB                 11
-#define INT_STATUS_RTC_ALARM_LSB                 11
-#define INT_STATUS_RTC_ALARM_MASK                0x00000800
-#define INT_STATUS_RTC_ALARM_GET(x)              (((x) & INT_STATUS_RTC_ALARM_MASK) >> INT_STATUS_RTC_ALARM_LSB)
-#define INT_STATUS_RTC_ALARM_SET(x)              (((x) << INT_STATUS_RTC_ALARM_LSB) & INT_STATUS_RTC_ALARM_MASK)
-#define INT_STATUS_HF_TIMER_MSB                  10
-#define INT_STATUS_HF_TIMER_LSB                  10
-#define INT_STATUS_HF_TIMER_MASK                 0x00000400
-#define INT_STATUS_HF_TIMER_GET(x)               (((x) & INT_STATUS_HF_TIMER_MASK) >> INT_STATUS_HF_TIMER_LSB)
-#define INT_STATUS_HF_TIMER_SET(x)               (((x) << INT_STATUS_HF_TIMER_LSB) & INT_STATUS_HF_TIMER_MASK)
-#define INT_STATUS_LF_TIMER3_MSB                 9
-#define INT_STATUS_LF_TIMER3_LSB                 9
-#define INT_STATUS_LF_TIMER3_MASK                0x00000200
-#define INT_STATUS_LF_TIMER3_GET(x)              (((x) & INT_STATUS_LF_TIMER3_MASK) >> INT_STATUS_LF_TIMER3_LSB)
-#define INT_STATUS_LF_TIMER3_SET(x)              (((x) << INT_STATUS_LF_TIMER3_LSB) & INT_STATUS_LF_TIMER3_MASK)
-#define INT_STATUS_LF_TIMER2_MSB                 8
-#define INT_STATUS_LF_TIMER2_LSB                 8
-#define INT_STATUS_LF_TIMER2_MASK                0x00000100
-#define INT_STATUS_LF_TIMER2_GET(x)              (((x) & INT_STATUS_LF_TIMER2_MASK) >> INT_STATUS_LF_TIMER2_LSB)
-#define INT_STATUS_LF_TIMER2_SET(x)              (((x) << INT_STATUS_LF_TIMER2_LSB) & INT_STATUS_LF_TIMER2_MASK)
-#define INT_STATUS_LF_TIMER1_MSB                 7
-#define INT_STATUS_LF_TIMER1_LSB                 7
-#define INT_STATUS_LF_TIMER1_MASK                0x00000080
-#define INT_STATUS_LF_TIMER1_GET(x)              (((x) & INT_STATUS_LF_TIMER1_MASK) >> INT_STATUS_LF_TIMER1_LSB)
-#define INT_STATUS_LF_TIMER1_SET(x)              (((x) << INT_STATUS_LF_TIMER1_LSB) & INT_STATUS_LF_TIMER1_MASK)
-#define INT_STATUS_LF_TIMER0_MSB                 6
-#define INT_STATUS_LF_TIMER0_LSB                 6
-#define INT_STATUS_LF_TIMER0_MASK                0x00000040
-#define INT_STATUS_LF_TIMER0_GET(x)              (((x) & INT_STATUS_LF_TIMER0_MASK) >> INT_STATUS_LF_TIMER0_LSB)
-#define INT_STATUS_LF_TIMER0_SET(x)              (((x) << INT_STATUS_LF_TIMER0_LSB) & INT_STATUS_LF_TIMER0_MASK)
-#define INT_STATUS_KEYPAD_MSB                    5
-#define INT_STATUS_KEYPAD_LSB                    5
-#define INT_STATUS_KEYPAD_MASK                   0x00000020
-#define INT_STATUS_KEYPAD_GET(x)                 (((x) & INT_STATUS_KEYPAD_MASK) >> INT_STATUS_KEYPAD_LSB)
-#define INT_STATUS_KEYPAD_SET(x)                 (((x) << INT_STATUS_KEYPAD_LSB) & INT_STATUS_KEYPAD_MASK)
-#define INT_STATUS_SI_MSB                        4
-#define INT_STATUS_SI_LSB                        4
-#define INT_STATUS_SI_MASK                       0x00000010
-#define INT_STATUS_SI_GET(x)                     (((x) & INT_STATUS_SI_MASK) >> INT_STATUS_SI_LSB)
-#define INT_STATUS_SI_SET(x)                     (((x) << INT_STATUS_SI_LSB) & INT_STATUS_SI_MASK)
-#define INT_STATUS_GPIO_MSB                      3
-#define INT_STATUS_GPIO_LSB                      3
-#define INT_STATUS_GPIO_MASK                     0x00000008
-#define INT_STATUS_GPIO_GET(x)                   (((x) & INT_STATUS_GPIO_MASK) >> INT_STATUS_GPIO_LSB)
-#define INT_STATUS_GPIO_SET(x)                   (((x) << INT_STATUS_GPIO_LSB) & INT_STATUS_GPIO_MASK)
-#define INT_STATUS_UART_MSB                      2
-#define INT_STATUS_UART_LSB                      2
-#define INT_STATUS_UART_MASK                     0x00000004
-#define INT_STATUS_UART_GET(x)                   (((x) & INT_STATUS_UART_MASK) >> INT_STATUS_UART_LSB)
-#define INT_STATUS_UART_SET(x)                   (((x) << INT_STATUS_UART_LSB) & INT_STATUS_UART_MASK)
-#define INT_STATUS_ERROR_MSB                     1
-#define INT_STATUS_ERROR_LSB                     1
-#define INT_STATUS_ERROR_MASK                    0x00000002
-#define INT_STATUS_ERROR_GET(x)                  (((x) & INT_STATUS_ERROR_MASK) >> INT_STATUS_ERROR_LSB)
-#define INT_STATUS_ERROR_SET(x)                  (((x) << INT_STATUS_ERROR_LSB) & INT_STATUS_ERROR_MASK)
-#define INT_STATUS_WDT_INT_MSB                   0
-#define INT_STATUS_WDT_INT_LSB                   0
-#define INT_STATUS_WDT_INT_MASK                  0x00000001
-#define INT_STATUS_WDT_INT_GET(x)                (((x) & INT_STATUS_WDT_INT_MASK) >> INT_STATUS_WDT_INT_LSB)
-#define INT_STATUS_WDT_INT_SET(x)                (((x) << INT_STATUS_WDT_INT_LSB) & INT_STATUS_WDT_INT_MASK)
-
-#define LF_TIMER0_ADDRESS                        0x00000048
-#define LF_TIMER0_OFFSET                         0x00000048
-#define LF_TIMER0_TARGET_MSB                     31
-#define LF_TIMER0_TARGET_LSB                     0
-#define LF_TIMER0_TARGET_MASK                    0xffffffff
-#define LF_TIMER0_TARGET_GET(x)                  (((x) & LF_TIMER0_TARGET_MASK) >> LF_TIMER0_TARGET_LSB)
-#define LF_TIMER0_TARGET_SET(x)                  (((x) << LF_TIMER0_TARGET_LSB) & LF_TIMER0_TARGET_MASK)
-
-#define LF_TIMER_COUNT0_ADDRESS                  0x0000004c
-#define LF_TIMER_COUNT0_OFFSET                   0x0000004c
-#define LF_TIMER_COUNT0_VALUE_MSB                31
-#define LF_TIMER_COUNT0_VALUE_LSB                0
-#define LF_TIMER_COUNT0_VALUE_MASK               0xffffffff
-#define LF_TIMER_COUNT0_VALUE_GET(x)             (((x) & LF_TIMER_COUNT0_VALUE_MASK) >> LF_TIMER_COUNT0_VALUE_LSB)
-#define LF_TIMER_COUNT0_VALUE_SET(x)             (((x) << LF_TIMER_COUNT0_VALUE_LSB) & LF_TIMER_COUNT0_VALUE_MASK)
-
-#define LF_TIMER_CONTROL0_ADDRESS                0x00000050
-#define LF_TIMER_CONTROL0_OFFSET                 0x00000050
-#define LF_TIMER_CONTROL0_ENABLE_MSB             2
-#define LF_TIMER_CONTROL0_ENABLE_LSB             2
-#define LF_TIMER_CONTROL0_ENABLE_MASK            0x00000004
-#define LF_TIMER_CONTROL0_ENABLE_GET(x)          (((x) & LF_TIMER_CONTROL0_ENABLE_MASK) >> LF_TIMER_CONTROL0_ENABLE_LSB)
-#define LF_TIMER_CONTROL0_ENABLE_SET(x)          (((x) << LF_TIMER_CONTROL0_ENABLE_LSB) & LF_TIMER_CONTROL0_ENABLE_MASK)
-#define LF_TIMER_CONTROL0_AUTO_RESTART_MSB       1
-#define LF_TIMER_CONTROL0_AUTO_RESTART_LSB       1
-#define LF_TIMER_CONTROL0_AUTO_RESTART_MASK      0x00000002
-#define LF_TIMER_CONTROL0_AUTO_RESTART_GET(x)    (((x) & LF_TIMER_CONTROL0_AUTO_RESTART_MASK) >> LF_TIMER_CONTROL0_AUTO_RESTART_LSB)
-#define LF_TIMER_CONTROL0_AUTO_RESTART_SET(x)    (((x) << LF_TIMER_CONTROL0_AUTO_RESTART_LSB) & LF_TIMER_CONTROL0_AUTO_RESTART_MASK)
-#define LF_TIMER_CONTROL0_RESET_MSB              0
-#define LF_TIMER_CONTROL0_RESET_LSB              0
-#define LF_TIMER_CONTROL0_RESET_MASK             0x00000001
-#define LF_TIMER_CONTROL0_RESET_GET(x)           (((x) & LF_TIMER_CONTROL0_RESET_MASK) >> LF_TIMER_CONTROL0_RESET_LSB)
-#define LF_TIMER_CONTROL0_RESET_SET(x)           (((x) << LF_TIMER_CONTROL0_RESET_LSB) & LF_TIMER_CONTROL0_RESET_MASK)
-
-#define LF_TIMER_STATUS0_ADDRESS                 0x00000054
-#define LF_TIMER_STATUS0_OFFSET                  0x00000054
-#define LF_TIMER_STATUS0_INTERRUPT_MSB           0
-#define LF_TIMER_STATUS0_INTERRUPT_LSB           0
-#define LF_TIMER_STATUS0_INTERRUPT_MASK          0x00000001
-#define LF_TIMER_STATUS0_INTERRUPT_GET(x)        (((x) & LF_TIMER_STATUS0_INTERRUPT_MASK) >> LF_TIMER_STATUS0_INTERRUPT_LSB)
-#define LF_TIMER_STATUS0_INTERRUPT_SET(x)        (((x) << LF_TIMER_STATUS0_INTERRUPT_LSB) & LF_TIMER_STATUS0_INTERRUPT_MASK)
-
-#define LF_TIMER1_ADDRESS                        0x00000058
-#define LF_TIMER1_OFFSET                         0x00000058
-#define LF_TIMER1_TARGET_MSB                     31
-#define LF_TIMER1_TARGET_LSB                     0
-#define LF_TIMER1_TARGET_MASK                    0xffffffff
-#define LF_TIMER1_TARGET_GET(x)                  (((x) & LF_TIMER1_TARGET_MASK) >> LF_TIMER1_TARGET_LSB)
-#define LF_TIMER1_TARGET_SET(x)                  (((x) << LF_TIMER1_TARGET_LSB) & LF_TIMER1_TARGET_MASK)
-
-#define LF_TIMER_COUNT1_ADDRESS                  0x0000005c
-#define LF_TIMER_COUNT1_OFFSET                   0x0000005c
-#define LF_TIMER_COUNT1_VALUE_MSB                31
-#define LF_TIMER_COUNT1_VALUE_LSB                0
-#define LF_TIMER_COUNT1_VALUE_MASK               0xffffffff
-#define LF_TIMER_COUNT1_VALUE_GET(x)             (((x) & LF_TIMER_COUNT1_VALUE_MASK) >> LF_TIMER_COUNT1_VALUE_LSB)
-#define LF_TIMER_COUNT1_VALUE_SET(x)             (((x) << LF_TIMER_COUNT1_VALUE_LSB) & LF_TIMER_COUNT1_VALUE_MASK)
-
-#define LF_TIMER_CONTROL1_ADDRESS                0x00000060
-#define LF_TIMER_CONTROL1_OFFSET                 0x00000060
-#define LF_TIMER_CONTROL1_ENABLE_MSB             2
-#define LF_TIMER_CONTROL1_ENABLE_LSB             2
-#define LF_TIMER_CONTROL1_ENABLE_MASK            0x00000004
-#define LF_TIMER_CONTROL1_ENABLE_GET(x)          (((x) & LF_TIMER_CONTROL1_ENABLE_MASK) >> LF_TIMER_CONTROL1_ENABLE_LSB)
-#define LF_TIMER_CONTROL1_ENABLE_SET(x)          (((x) << LF_TIMER_CONTROL1_ENABLE_LSB) & LF_TIMER_CONTROL1_ENABLE_MASK)
-#define LF_TIMER_CONTROL1_AUTO_RESTART_MSB       1
-#define LF_TIMER_CONTROL1_AUTO_RESTART_LSB       1
-#define LF_TIMER_CONTROL1_AUTO_RESTART_MASK      0x00000002
-#define LF_TIMER_CONTROL1_AUTO_RESTART_GET(x)    (((x) & LF_TIMER_CONTROL1_AUTO_RESTART_MASK) >> LF_TIMER_CONTROL1_AUTO_RESTART_LSB)
-#define LF_TIMER_CONTROL1_AUTO_RESTART_SET(x)    (((x) << LF_TIMER_CONTROL1_AUTO_RESTART_LSB) & LF_TIMER_CONTROL1_AUTO_RESTART_MASK)
-#define LF_TIMER_CONTROL1_RESET_MSB              0
-#define LF_TIMER_CONTROL1_RESET_LSB              0
-#define LF_TIMER_CONTROL1_RESET_MASK             0x00000001
-#define LF_TIMER_CONTROL1_RESET_GET(x)           (((x) & LF_TIMER_CONTROL1_RESET_MASK) >> LF_TIMER_CONTROL1_RESET_LSB)
-#define LF_TIMER_CONTROL1_RESET_SET(x)           (((x) << LF_TIMER_CONTROL1_RESET_LSB) & LF_TIMER_CONTROL1_RESET_MASK)
-
-#define LF_TIMER_STATUS1_ADDRESS                 0x00000064
-#define LF_TIMER_STATUS1_OFFSET                  0x00000064
-#define LF_TIMER_STATUS1_INTERRUPT_MSB           0
-#define LF_TIMER_STATUS1_INTERRUPT_LSB           0
-#define LF_TIMER_STATUS1_INTERRUPT_MASK          0x00000001
-#define LF_TIMER_STATUS1_INTERRUPT_GET(x)        (((x) & LF_TIMER_STATUS1_INTERRUPT_MASK) >> LF_TIMER_STATUS1_INTERRUPT_LSB)
-#define LF_TIMER_STATUS1_INTERRUPT_SET(x)        (((x) << LF_TIMER_STATUS1_INTERRUPT_LSB) & LF_TIMER_STATUS1_INTERRUPT_MASK)
-
-#define LF_TIMER2_ADDRESS                        0x00000068
-#define LF_TIMER2_OFFSET                         0x00000068
-#define LF_TIMER2_TARGET_MSB                     31
-#define LF_TIMER2_TARGET_LSB                     0
-#define LF_TIMER2_TARGET_MASK                    0xffffffff
-#define LF_TIMER2_TARGET_GET(x)                  (((x) & LF_TIMER2_TARGET_MASK) >> LF_TIMER2_TARGET_LSB)
-#define LF_TIMER2_TARGET_SET(x)                  (((x) << LF_TIMER2_TARGET_LSB) & LF_TIMER2_TARGET_MASK)
-
-#define LF_TIMER_COUNT2_ADDRESS                  0x0000006c
-#define LF_TIMER_COUNT2_OFFSET                   0x0000006c
-#define LF_TIMER_COUNT2_VALUE_MSB                31
-#define LF_TIMER_COUNT2_VALUE_LSB                0
-#define LF_TIMER_COUNT2_VALUE_MASK               0xffffffff
-#define LF_TIMER_COUNT2_VALUE_GET(x)             (((x) & LF_TIMER_COUNT2_VALUE_MASK) >> LF_TIMER_COUNT2_VALUE_LSB)
-#define LF_TIMER_COUNT2_VALUE_SET(x)             (((x) << LF_TIMER_COUNT2_VALUE_LSB) & LF_TIMER_COUNT2_VALUE_MASK)
-
-#define LF_TIMER_CONTROL2_ADDRESS                0x00000070
-#define LF_TIMER_CONTROL2_OFFSET                 0x00000070
-#define LF_TIMER_CONTROL2_ENABLE_MSB             2
-#define LF_TIMER_CONTROL2_ENABLE_LSB             2
-#define LF_TIMER_CONTROL2_ENABLE_MASK            0x00000004
-#define LF_TIMER_CONTROL2_ENABLE_GET(x)          (((x) & LF_TIMER_CONTROL2_ENABLE_MASK) >> LF_TIMER_CONTROL2_ENABLE_LSB)
-#define LF_TIMER_CONTROL2_ENABLE_SET(x)          (((x) << LF_TIMER_CONTROL2_ENABLE_LSB) & LF_TIMER_CONTROL2_ENABLE_MASK)
-#define LF_TIMER_CONTROL2_AUTO_RESTART_MSB       1
-#define LF_TIMER_CONTROL2_AUTO_RESTART_LSB       1
-#define LF_TIMER_CONTROL2_AUTO_RESTART_MASK      0x00000002
-#define LF_TIMER_CONTROL2_AUTO_RESTART_GET(x)    (((x) & LF_TIMER_CONTROL2_AUTO_RESTART_MASK) >> LF_TIMER_CONTROL2_AUTO_RESTART_LSB)
-#define LF_TIMER_CONTROL2_AUTO_RESTART_SET(x)    (((x) << LF_TIMER_CONTROL2_AUTO_RESTART_LSB) & LF_TIMER_CONTROL2_AUTO_RESTART_MASK)
-#define LF_TIMER_CONTROL2_RESET_MSB              0
-#define LF_TIMER_CONTROL2_RESET_LSB              0
-#define LF_TIMER_CONTROL2_RESET_MASK             0x00000001
-#define LF_TIMER_CONTROL2_RESET_GET(x)           (((x) & LF_TIMER_CONTROL2_RESET_MASK) >> LF_TIMER_CONTROL2_RESET_LSB)
-#define LF_TIMER_CONTROL2_RESET_SET(x)           (((x) << LF_TIMER_CONTROL2_RESET_LSB) & LF_TIMER_CONTROL2_RESET_MASK)
-
-#define LF_TIMER_STATUS2_ADDRESS                 0x00000074
-#define LF_TIMER_STATUS2_OFFSET                  0x00000074
-#define LF_TIMER_STATUS2_INTERRUPT_MSB           0
-#define LF_TIMER_STATUS2_INTERRUPT_LSB           0
-#define LF_TIMER_STATUS2_INTERRUPT_MASK          0x00000001
-#define LF_TIMER_STATUS2_INTERRUPT_GET(x)        (((x) & LF_TIMER_STATUS2_INTERRUPT_MASK) >> LF_TIMER_STATUS2_INTERRUPT_LSB)
-#define LF_TIMER_STATUS2_INTERRUPT_SET(x)        (((x) << LF_TIMER_STATUS2_INTERRUPT_LSB) & LF_TIMER_STATUS2_INTERRUPT_MASK)
-
-#define LF_TIMER3_ADDRESS                        0x00000078
-#define LF_TIMER3_OFFSET                         0x00000078
-#define LF_TIMER3_TARGET_MSB                     31
-#define LF_TIMER3_TARGET_LSB                     0
-#define LF_TIMER3_TARGET_MASK                    0xffffffff
-#define LF_TIMER3_TARGET_GET(x)                  (((x) & LF_TIMER3_TARGET_MASK) >> LF_TIMER3_TARGET_LSB)
-#define LF_TIMER3_TARGET_SET(x)                  (((x) << LF_TIMER3_TARGET_LSB) & LF_TIMER3_TARGET_MASK)
-
-#define LF_TIMER_COUNT3_ADDRESS                  0x0000007c
-#define LF_TIMER_COUNT3_OFFSET                   0x0000007c
-#define LF_TIMER_COUNT3_VALUE_MSB                31
-#define LF_TIMER_COUNT3_VALUE_LSB                0
-#define LF_TIMER_COUNT3_VALUE_MASK               0xffffffff
-#define LF_TIMER_COUNT3_VALUE_GET(x)             (((x) & LF_TIMER_COUNT3_VALUE_MASK) >> LF_TIMER_COUNT3_VALUE_LSB)
-#define LF_TIMER_COUNT3_VALUE_SET(x)             (((x) << LF_TIMER_COUNT3_VALUE_LSB) & LF_TIMER_COUNT3_VALUE_MASK)
-
-#define LF_TIMER_CONTROL3_ADDRESS                0x00000080
-#define LF_TIMER_CONTROL3_OFFSET                 0x00000080
-#define LF_TIMER_CONTROL3_ENABLE_MSB             2
-#define LF_TIMER_CONTROL3_ENABLE_LSB             2
-#define LF_TIMER_CONTROL3_ENABLE_MASK            0x00000004
-#define LF_TIMER_CONTROL3_ENABLE_GET(x)          (((x) & LF_TIMER_CONTROL3_ENABLE_MASK) >> LF_TIMER_CONTROL3_ENABLE_LSB)
-#define LF_TIMER_CONTROL3_ENABLE_SET(x)          (((x) << LF_TIMER_CONTROL3_ENABLE_LSB) & LF_TIMER_CONTROL3_ENABLE_MASK)
-#define LF_TIMER_CONTROL3_AUTO_RESTART_MSB       1
-#define LF_TIMER_CONTROL3_AUTO_RESTART_LSB       1
-#define LF_TIMER_CONTROL3_AUTO_RESTART_MASK      0x00000002
-#define LF_TIMER_CONTROL3_AUTO_RESTART_GET(x)    (((x) & LF_TIMER_CONTROL3_AUTO_RESTART_MASK) >> LF_TIMER_CONTROL3_AUTO_RESTART_LSB)
-#define LF_TIMER_CONTROL3_AUTO_RESTART_SET(x)    (((x) << LF_TIMER_CONTROL3_AUTO_RESTART_LSB) & LF_TIMER_CONTROL3_AUTO_RESTART_MASK)
-#define LF_TIMER_CONTROL3_RESET_MSB              0
-#define LF_TIMER_CONTROL3_RESET_LSB              0
-#define LF_TIMER_CONTROL3_RESET_MASK             0x00000001
-#define LF_TIMER_CONTROL3_RESET_GET(x)           (((x) & LF_TIMER_CONTROL3_RESET_MASK) >> LF_TIMER_CONTROL3_RESET_LSB)
-#define LF_TIMER_CONTROL3_RESET_SET(x)           (((x) << LF_TIMER_CONTROL3_RESET_LSB) & LF_TIMER_CONTROL3_RESET_MASK)
-
-#define LF_TIMER_STATUS3_ADDRESS                 0x00000084
-#define LF_TIMER_STATUS3_OFFSET                  0x00000084
-#define LF_TIMER_STATUS3_INTERRUPT_MSB           0
-#define LF_TIMER_STATUS3_INTERRUPT_LSB           0
-#define LF_TIMER_STATUS3_INTERRUPT_MASK          0x00000001
-#define LF_TIMER_STATUS3_INTERRUPT_GET(x)        (((x) & LF_TIMER_STATUS3_INTERRUPT_MASK) >> LF_TIMER_STATUS3_INTERRUPT_LSB)
-#define LF_TIMER_STATUS3_INTERRUPT_SET(x)        (((x) << LF_TIMER_STATUS3_INTERRUPT_LSB) & LF_TIMER_STATUS3_INTERRUPT_MASK)
-
-#define HF_TIMER_ADDRESS                         0x00000088
-#define HF_TIMER_OFFSET                          0x00000088
-#define HF_TIMER_TARGET_MSB                      31
-#define HF_TIMER_TARGET_LSB                      12
-#define HF_TIMER_TARGET_MASK                     0xfffff000
-#define HF_TIMER_TARGET_GET(x)                   (((x) & HF_TIMER_TARGET_MASK) >> HF_TIMER_TARGET_LSB)
-#define HF_TIMER_TARGET_SET(x)                   (((x) << HF_TIMER_TARGET_LSB) & HF_TIMER_TARGET_MASK)
-
-#define HF_TIMER_COUNT_ADDRESS                   0x0000008c
-#define HF_TIMER_COUNT_OFFSET                    0x0000008c
-#define HF_TIMER_COUNT_VALUE_MSB                 31
-#define HF_TIMER_COUNT_VALUE_LSB                 12
-#define HF_TIMER_COUNT_VALUE_MASK                0xfffff000
-#define HF_TIMER_COUNT_VALUE_GET(x)              (((x) & HF_TIMER_COUNT_VALUE_MASK) >> HF_TIMER_COUNT_VALUE_LSB)
-#define HF_TIMER_COUNT_VALUE_SET(x)              (((x) << HF_TIMER_COUNT_VALUE_LSB) & HF_TIMER_COUNT_VALUE_MASK)
-
-#define HF_LF_COUNT_ADDRESS                      0x00000090
-#define HF_LF_COUNT_OFFSET                       0x00000090
-#define HF_LF_COUNT_VALUE_MSB                    31
-#define HF_LF_COUNT_VALUE_LSB                    0
-#define HF_LF_COUNT_VALUE_MASK                   0xffffffff
-#define HF_LF_COUNT_VALUE_GET(x)                 (((x) & HF_LF_COUNT_VALUE_MASK) >> HF_LF_COUNT_VALUE_LSB)
-#define HF_LF_COUNT_VALUE_SET(x)                 (((x) << HF_LF_COUNT_VALUE_LSB) & HF_LF_COUNT_VALUE_MASK)
-
-#define HF_TIMER_CONTROL_ADDRESS                 0x00000094
-#define HF_TIMER_CONTROL_OFFSET                  0x00000094
-#define HF_TIMER_CONTROL_ENABLE_MSB              3
-#define HF_TIMER_CONTROL_ENABLE_LSB              3
-#define HF_TIMER_CONTROL_ENABLE_MASK             0x00000008
-#define HF_TIMER_CONTROL_ENABLE_GET(x)           (((x) & HF_TIMER_CONTROL_ENABLE_MASK) >> HF_TIMER_CONTROL_ENABLE_LSB)
-#define HF_TIMER_CONTROL_ENABLE_SET(x)           (((x) << HF_TIMER_CONTROL_ENABLE_LSB) & HF_TIMER_CONTROL_ENABLE_MASK)
-#define HF_TIMER_CONTROL_ON_MSB                  2
-#define HF_TIMER_CONTROL_ON_LSB                  2
-#define HF_TIMER_CONTROL_ON_MASK                 0x00000004
-#define HF_TIMER_CONTROL_ON_GET(x)               (((x) & HF_TIMER_CONTROL_ON_MASK) >> HF_TIMER_CONTROL_ON_LSB)
-#define HF_TIMER_CONTROL_ON_SET(x)               (((x) << HF_TIMER_CONTROL_ON_LSB) & HF_TIMER_CONTROL_ON_MASK)
-#define HF_TIMER_CONTROL_AUTO_RESTART_MSB        1
-#define HF_TIMER_CONTROL_AUTO_RESTART_LSB        1
-#define HF_TIMER_CONTROL_AUTO_RESTART_MASK       0x00000002
-#define HF_TIMER_CONTROL_AUTO_RESTART_GET(x)     (((x) & HF_TIMER_CONTROL_AUTO_RESTART_MASK) >> HF_TIMER_CONTROL_AUTO_RESTART_LSB)
-#define HF_TIMER_CONTROL_AUTO_RESTART_SET(x)     (((x) << HF_TIMER_CONTROL_AUTO_RESTART_LSB) & HF_TIMER_CONTROL_AUTO_RESTART_MASK)
-#define HF_TIMER_CONTROL_RESET_MSB               0
-#define HF_TIMER_CONTROL_RESET_LSB               0
-#define HF_TIMER_CONTROL_RESET_MASK              0x00000001
-#define HF_TIMER_CONTROL_RESET_GET(x)            (((x) & HF_TIMER_CONTROL_RESET_MASK) >> HF_TIMER_CONTROL_RESET_LSB)
-#define HF_TIMER_CONTROL_RESET_SET(x)            (((x) << HF_TIMER_CONTROL_RESET_LSB) & HF_TIMER_CONTROL_RESET_MASK)
-
-#define HF_TIMER_STATUS_ADDRESS                  0x00000098
-#define HF_TIMER_STATUS_OFFSET                   0x00000098
-#define HF_TIMER_STATUS_INTERRUPT_MSB            0
-#define HF_TIMER_STATUS_INTERRUPT_LSB            0
-#define HF_TIMER_STATUS_INTERRUPT_MASK           0x00000001
-#define HF_TIMER_STATUS_INTERRUPT_GET(x)         (((x) & HF_TIMER_STATUS_INTERRUPT_MASK) >> HF_TIMER_STATUS_INTERRUPT_LSB)
-#define HF_TIMER_STATUS_INTERRUPT_SET(x)         (((x) << HF_TIMER_STATUS_INTERRUPT_LSB) & HF_TIMER_STATUS_INTERRUPT_MASK)
-
-#define RTC_CONTROL_ADDRESS                      0x0000009c
-#define RTC_CONTROL_OFFSET                       0x0000009c
-#define RTC_CONTROL_ENABLE_MSB                   2
-#define RTC_CONTROL_ENABLE_LSB                   2
-#define RTC_CONTROL_ENABLE_MASK                  0x00000004
-#define RTC_CONTROL_ENABLE_GET(x)                (((x) & RTC_CONTROL_ENABLE_MASK) >> RTC_CONTROL_ENABLE_LSB)
-#define RTC_CONTROL_ENABLE_SET(x)                (((x) << RTC_CONTROL_ENABLE_LSB) & RTC_CONTROL_ENABLE_MASK)
-#define RTC_CONTROL_LOAD_RTC_MSB                 1
-#define RTC_CONTROL_LOAD_RTC_LSB                 1
-#define RTC_CONTROL_LOAD_RTC_MASK                0x00000002
-#define RTC_CONTROL_LOAD_RTC_GET(x)              (((x) & RTC_CONTROL_LOAD_RTC_MASK) >> RTC_CONTROL_LOAD_RTC_LSB)
-#define RTC_CONTROL_LOAD_RTC_SET(x)              (((x) << RTC_CONTROL_LOAD_RTC_LSB) & RTC_CONTROL_LOAD_RTC_MASK)
-#define RTC_CONTROL_LOAD_ALARM_MSB               0
-#define RTC_CONTROL_LOAD_ALARM_LSB               0
-#define RTC_CONTROL_LOAD_ALARM_MASK              0x00000001
-#define RTC_CONTROL_LOAD_ALARM_GET(x)            (((x) & RTC_CONTROL_LOAD_ALARM_MASK) >> RTC_CONTROL_LOAD_ALARM_LSB)
-#define RTC_CONTROL_LOAD_ALARM_SET(x)            (((x) << RTC_CONTROL_LOAD_ALARM_LSB) & RTC_CONTROL_LOAD_ALARM_MASK)
-
-#define RTC_TIME_ADDRESS                         0x000000a0
-#define RTC_TIME_OFFSET                          0x000000a0
-#define RTC_TIME_WEEK_DAY_MSB                    26
-#define RTC_TIME_WEEK_DAY_LSB                    24
-#define RTC_TIME_WEEK_DAY_MASK                   0x07000000
-#define RTC_TIME_WEEK_DAY_GET(x)                 (((x) & RTC_TIME_WEEK_DAY_MASK) >> RTC_TIME_WEEK_DAY_LSB)
-#define RTC_TIME_WEEK_DAY_SET(x)                 (((x) << RTC_TIME_WEEK_DAY_LSB) & RTC_TIME_WEEK_DAY_MASK)
-#define RTC_TIME_HOUR_MSB                        21
-#define RTC_TIME_HOUR_LSB                        16
-#define RTC_TIME_HOUR_MASK                       0x003f0000
-#define RTC_TIME_HOUR_GET(x)                     (((x) & RTC_TIME_HOUR_MASK) >> RTC_TIME_HOUR_LSB)
-#define RTC_TIME_HOUR_SET(x)                     (((x) << RTC_TIME_HOUR_LSB) & RTC_TIME_HOUR_MASK)
-#define RTC_TIME_MINUTE_MSB                      14
-#define RTC_TIME_MINUTE_LSB                      8
-#define RTC_TIME_MINUTE_MASK                     0x00007f00
-#define RTC_TIME_MINUTE_GET(x)                   (((x) & RTC_TIME_MINUTE_MASK) >> RTC_TIME_MINUTE_LSB)
-#define RTC_TIME_MINUTE_SET(x)                   (((x) << RTC_TIME_MINUTE_LSB) & RTC_TIME_MINUTE_MASK)
-#define RTC_TIME_SECOND_MSB                      6
-#define RTC_TIME_SECOND_LSB                      0
-#define RTC_TIME_SECOND_MASK                     0x0000007f
-#define RTC_TIME_SECOND_GET(x)                   (((x) & RTC_TIME_SECOND_MASK) >> RTC_TIME_SECOND_LSB)
-#define RTC_TIME_SECOND_SET(x)                   (((x) << RTC_TIME_SECOND_LSB) & RTC_TIME_SECOND_MASK)
-
-#define RTC_DATE_ADDRESS                         0x000000a4
-#define RTC_DATE_OFFSET                          0x000000a4
-#define RTC_DATE_YEAR_MSB                        23
-#define RTC_DATE_YEAR_LSB                        16
-#define RTC_DATE_YEAR_MASK                       0x00ff0000
-#define RTC_DATE_YEAR_GET(x)                     (((x) & RTC_DATE_YEAR_MASK) >> RTC_DATE_YEAR_LSB)
-#define RTC_DATE_YEAR_SET(x)                     (((x) << RTC_DATE_YEAR_LSB) & RTC_DATE_YEAR_MASK)
-#define RTC_DATE_MONTH_MSB                       12
-#define RTC_DATE_MONTH_LSB                       8
-#define RTC_DATE_MONTH_MASK                      0x00001f00
-#define RTC_DATE_MONTH_GET(x)                    (((x) & RTC_DATE_MONTH_MASK) >> RTC_DATE_MONTH_LSB)
-#define RTC_DATE_MONTH_SET(x)                    (((x) << RTC_DATE_MONTH_LSB) & RTC_DATE_MONTH_MASK)
-#define RTC_DATE_MONTH_DAY_MSB                   5
-#define RTC_DATE_MONTH_DAY_LSB                   0
-#define RTC_DATE_MONTH_DAY_MASK                  0x0000003f
-#define RTC_DATE_MONTH_DAY_GET(x)                (((x) & RTC_DATE_MONTH_DAY_MASK) >> RTC_DATE_MONTH_DAY_LSB)
-#define RTC_DATE_MONTH_DAY_SET(x)                (((x) << RTC_DATE_MONTH_DAY_LSB) & RTC_DATE_MONTH_DAY_MASK)
-
-#define RTC_SET_TIME_ADDRESS                     0x000000a8
-#define RTC_SET_TIME_OFFSET                      0x000000a8
-#define RTC_SET_TIME_WEEK_DAY_MSB                26
-#define RTC_SET_TIME_WEEK_DAY_LSB                24
-#define RTC_SET_TIME_WEEK_DAY_MASK               0x07000000
-#define RTC_SET_TIME_WEEK_DAY_GET(x)             (((x) & RTC_SET_TIME_WEEK_DAY_MASK) >> RTC_SET_TIME_WEEK_DAY_LSB)
-#define RTC_SET_TIME_WEEK_DAY_SET(x)             (((x) << RTC_SET_TIME_WEEK_DAY_LSB) & RTC_SET_TIME_WEEK_DAY_MASK)
-#define RTC_SET_TIME_HOUR_MSB                    21
-#define RTC_SET_TIME_HOUR_LSB                    16
-#define RTC_SET_TIME_HOUR_MASK                   0x003f0000
-#define RTC_SET_TIME_HOUR_GET(x)                 (((x) & RTC_SET_TIME_HOUR_MASK) >> RTC_SET_TIME_HOUR_LSB)
-#define RTC_SET_TIME_HOUR_SET(x)                 (((x) << RTC_SET_TIME_HOUR_LSB) & RTC_SET_TIME_HOUR_MASK)
-#define RTC_SET_TIME_MINUTE_MSB                  14
-#define RTC_SET_TIME_MINUTE_LSB                  8
-#define RTC_SET_TIME_MINUTE_MASK                 0x00007f00
-#define RTC_SET_TIME_MINUTE_GET(x)               (((x) & RTC_SET_TIME_MINUTE_MASK) >> RTC_SET_TIME_MINUTE_LSB)
-#define RTC_SET_TIME_MINUTE_SET(x)               (((x) << RTC_SET_TIME_MINUTE_LSB) & RTC_SET_TIME_MINUTE_MASK)
-#define RTC_SET_TIME_SECOND_MSB                  6
-#define RTC_SET_TIME_SECOND_LSB                  0
-#define RTC_SET_TIME_SECOND_MASK                 0x0000007f
-#define RTC_SET_TIME_SECOND_GET(x)               (((x) & RTC_SET_TIME_SECOND_MASK) >> RTC_SET_TIME_SECOND_LSB)
-#define RTC_SET_TIME_SECOND_SET(x)               (((x) << RTC_SET_TIME_SECOND_LSB) & RTC_SET_TIME_SECOND_MASK)
-
-#define RTC_SET_DATE_ADDRESS                     0x000000ac
-#define RTC_SET_DATE_OFFSET                      0x000000ac
-#define RTC_SET_DATE_YEAR_MSB                    23
-#define RTC_SET_DATE_YEAR_LSB                    16
-#define RTC_SET_DATE_YEAR_MASK                   0x00ff0000
-#define RTC_SET_DATE_YEAR_GET(x)                 (((x) & RTC_SET_DATE_YEAR_MASK) >> RTC_SET_DATE_YEAR_LSB)
-#define RTC_SET_DATE_YEAR_SET(x)                 (((x) << RTC_SET_DATE_YEAR_LSB) & RTC_SET_DATE_YEAR_MASK)
-#define RTC_SET_DATE_MONTH_MSB                   12
-#define RTC_SET_DATE_MONTH_LSB                   8
-#define RTC_SET_DATE_MONTH_MASK                  0x00001f00
-#define RTC_SET_DATE_MONTH_GET(x)                (((x) & RTC_SET_DATE_MONTH_MASK) >> RTC_SET_DATE_MONTH_LSB)
-#define RTC_SET_DATE_MONTH_SET(x)                (((x) << RTC_SET_DATE_MONTH_LSB) & RTC_SET_DATE_MONTH_MASK)
-#define RTC_SET_DATE_MONTH_DAY_MSB               5
-#define RTC_SET_DATE_MONTH_DAY_LSB               0
-#define RTC_SET_DATE_MONTH_DAY_MASK              0x0000003f
-#define RTC_SET_DATE_MONTH_DAY_GET(x)            (((x) & RTC_SET_DATE_MONTH_DAY_MASK) >> RTC_SET_DATE_MONTH_DAY_LSB)
-#define RTC_SET_DATE_MONTH_DAY_SET(x)            (((x) << RTC_SET_DATE_MONTH_DAY_LSB) & RTC_SET_DATE_MONTH_DAY_MASK)
-
-#define RTC_SET_ALARM_ADDRESS                    0x000000b0
-#define RTC_SET_ALARM_OFFSET                     0x000000b0
-#define RTC_SET_ALARM_HOUR_MSB                   21
-#define RTC_SET_ALARM_HOUR_LSB                   16
-#define RTC_SET_ALARM_HOUR_MASK                  0x003f0000
-#define RTC_SET_ALARM_HOUR_GET(x)                (((x) & RTC_SET_ALARM_HOUR_MASK) >> RTC_SET_ALARM_HOUR_LSB)
-#define RTC_SET_ALARM_HOUR_SET(x)                (((x) << RTC_SET_ALARM_HOUR_LSB) & RTC_SET_ALARM_HOUR_MASK)
-#define RTC_SET_ALARM_MINUTE_MSB                 14
-#define RTC_SET_ALARM_MINUTE_LSB                 8
-#define RTC_SET_ALARM_MINUTE_MASK                0x00007f00
-#define RTC_SET_ALARM_MINUTE_GET(x)              (((x) & RTC_SET_ALARM_MINUTE_MASK) >> RTC_SET_ALARM_MINUTE_LSB)
-#define RTC_SET_ALARM_MINUTE_SET(x)              (((x) << RTC_SET_ALARM_MINUTE_LSB) & RTC_SET_ALARM_MINUTE_MASK)
-#define RTC_SET_ALARM_SECOND_MSB                 6
-#define RTC_SET_ALARM_SECOND_LSB                 0
-#define RTC_SET_ALARM_SECOND_MASK                0x0000007f
-#define RTC_SET_ALARM_SECOND_GET(x)              (((x) & RTC_SET_ALARM_SECOND_MASK) >> RTC_SET_ALARM_SECOND_LSB)
-#define RTC_SET_ALARM_SECOND_SET(x)              (((x) << RTC_SET_ALARM_SECOND_LSB) & RTC_SET_ALARM_SECOND_MASK)
-
-#define RTC_CONFIG_ADDRESS                       0x000000b4
-#define RTC_CONFIG_OFFSET                        0x000000b4
-#define RTC_CONFIG_BCD_MSB                       2
-#define RTC_CONFIG_BCD_LSB                       2
-#define RTC_CONFIG_BCD_MASK                      0x00000004
-#define RTC_CONFIG_BCD_GET(x)                    (((x) & RTC_CONFIG_BCD_MASK) >> RTC_CONFIG_BCD_LSB)
-#define RTC_CONFIG_BCD_SET(x)                    (((x) << RTC_CONFIG_BCD_LSB) & RTC_CONFIG_BCD_MASK)
-#define RTC_CONFIG_TWELVE_HOUR_MSB               1
-#define RTC_CONFIG_TWELVE_HOUR_LSB               1
-#define RTC_CONFIG_TWELVE_HOUR_MASK              0x00000002
-#define RTC_CONFIG_TWELVE_HOUR_GET(x)            (((x) & RTC_CONFIG_TWELVE_HOUR_MASK) >> RTC_CONFIG_TWELVE_HOUR_LSB)
-#define RTC_CONFIG_TWELVE_HOUR_SET(x)            (((x) << RTC_CONFIG_TWELVE_HOUR_LSB) & RTC_CONFIG_TWELVE_HOUR_MASK)
-#define RTC_CONFIG_DSE_MSB                       0
-#define RTC_CONFIG_DSE_LSB                       0
-#define RTC_CONFIG_DSE_MASK                      0x00000001
-#define RTC_CONFIG_DSE_GET(x)                    (((x) & RTC_CONFIG_DSE_MASK) >> RTC_CONFIG_DSE_LSB)
-#define RTC_CONFIG_DSE_SET(x)                    (((x) << RTC_CONFIG_DSE_LSB) & RTC_CONFIG_DSE_MASK)
-
-#define RTC_ALARM_STATUS_ADDRESS                 0x000000b8
-#define RTC_ALARM_STATUS_OFFSET                  0x000000b8
-#define RTC_ALARM_STATUS_ENABLE_MSB              1
-#define RTC_ALARM_STATUS_ENABLE_LSB              1
-#define RTC_ALARM_STATUS_ENABLE_MASK             0x00000002
-#define RTC_ALARM_STATUS_ENABLE_GET(x)           (((x) & RTC_ALARM_STATUS_ENABLE_MASK) >> RTC_ALARM_STATUS_ENABLE_LSB)
-#define RTC_ALARM_STATUS_ENABLE_SET(x)           (((x) << RTC_ALARM_STATUS_ENABLE_LSB) & RTC_ALARM_STATUS_ENABLE_MASK)
-#define RTC_ALARM_STATUS_INTERRUPT_MSB           0
-#define RTC_ALARM_STATUS_INTERRUPT_LSB           0
-#define RTC_ALARM_STATUS_INTERRUPT_MASK          0x00000001
-#define RTC_ALARM_STATUS_INTERRUPT_GET(x)        (((x) & RTC_ALARM_STATUS_INTERRUPT_MASK) >> RTC_ALARM_STATUS_INTERRUPT_LSB)
-#define RTC_ALARM_STATUS_INTERRUPT_SET(x)        (((x) << RTC_ALARM_STATUS_INTERRUPT_LSB) & RTC_ALARM_STATUS_INTERRUPT_MASK)
-
-#define UART_WAKEUP_ADDRESS                      0x000000bc
-#define UART_WAKEUP_OFFSET                       0x000000bc
-#define UART_WAKEUP_ENABLE_MSB                   0
-#define UART_WAKEUP_ENABLE_LSB                   0
-#define UART_WAKEUP_ENABLE_MASK                  0x00000001
-#define UART_WAKEUP_ENABLE_GET(x)                (((x) & UART_WAKEUP_ENABLE_MASK) >> UART_WAKEUP_ENABLE_LSB)
-#define UART_WAKEUP_ENABLE_SET(x)                (((x) << UART_WAKEUP_ENABLE_LSB) & UART_WAKEUP_ENABLE_MASK)
-
-#define RESET_CAUSE_ADDRESS                      0x000000c0
-#define RESET_CAUSE_OFFSET                       0x000000c0
-#define RESET_CAUSE_LAST_MSB                     2
-#define RESET_CAUSE_LAST_LSB                     0
-#define RESET_CAUSE_LAST_MASK                    0x00000007
-#define RESET_CAUSE_LAST_GET(x)                  (((x) & RESET_CAUSE_LAST_MASK) >> RESET_CAUSE_LAST_LSB)
-#define RESET_CAUSE_LAST_SET(x)                  (((x) << RESET_CAUSE_LAST_LSB) & RESET_CAUSE_LAST_MASK)
-
-#define SYSTEM_SLEEP_ADDRESS                     0x000000c4
-#define SYSTEM_SLEEP_OFFSET                      0x000000c4
-#define SYSTEM_SLEEP_HOST_IF_MSB                 4
-#define SYSTEM_SLEEP_HOST_IF_LSB                 4
-#define SYSTEM_SLEEP_HOST_IF_MASK                0x00000010
-#define SYSTEM_SLEEP_HOST_IF_GET(x)              (((x) & SYSTEM_SLEEP_HOST_IF_MASK) >> SYSTEM_SLEEP_HOST_IF_LSB)
-#define SYSTEM_SLEEP_HOST_IF_SET(x)              (((x) << SYSTEM_SLEEP_HOST_IF_LSB) & SYSTEM_SLEEP_HOST_IF_MASK)
-#define SYSTEM_SLEEP_MBOX_MSB                    3
-#define SYSTEM_SLEEP_MBOX_LSB                    3
-#define SYSTEM_SLEEP_MBOX_MASK                   0x00000008
-#define SYSTEM_SLEEP_MBOX_GET(x)                 (((x) & SYSTEM_SLEEP_MBOX_MASK) >> SYSTEM_SLEEP_MBOX_LSB)
-#define SYSTEM_SLEEP_MBOX_SET(x)                 (((x) << SYSTEM_SLEEP_MBOX_LSB) & SYSTEM_SLEEP_MBOX_MASK)
-#define SYSTEM_SLEEP_MAC_IF_MSB                  2
-#define SYSTEM_SLEEP_MAC_IF_LSB                  2
-#define SYSTEM_SLEEP_MAC_IF_MASK                 0x00000004
-#define SYSTEM_SLEEP_MAC_IF_GET(x)               (((x) & SYSTEM_SLEEP_MAC_IF_MASK) >> SYSTEM_SLEEP_MAC_IF_LSB)
-#define SYSTEM_SLEEP_MAC_IF_SET(x)               (((x) << SYSTEM_SLEEP_MAC_IF_LSB) & SYSTEM_SLEEP_MAC_IF_MASK)
-#define SYSTEM_SLEEP_LIGHT_MSB                   1
-#define SYSTEM_SLEEP_LIGHT_LSB                   1
-#define SYSTEM_SLEEP_LIGHT_MASK                  0x00000002
-#define SYSTEM_SLEEP_LIGHT_GET(x)                (((x) & SYSTEM_SLEEP_LIGHT_MASK) >> SYSTEM_SLEEP_LIGHT_LSB)
-#define SYSTEM_SLEEP_LIGHT_SET(x)                (((x) << SYSTEM_SLEEP_LIGHT_LSB) & SYSTEM_SLEEP_LIGHT_MASK)
-#define SYSTEM_SLEEP_DISABLE_MSB                 0
-#define SYSTEM_SLEEP_DISABLE_LSB                 0
-#define SYSTEM_SLEEP_DISABLE_MASK                0x00000001
-#define SYSTEM_SLEEP_DISABLE_GET(x)              (((x) & SYSTEM_SLEEP_DISABLE_MASK) >> SYSTEM_SLEEP_DISABLE_LSB)
-#define SYSTEM_SLEEP_DISABLE_SET(x)              (((x) << SYSTEM_SLEEP_DISABLE_LSB) & SYSTEM_SLEEP_DISABLE_MASK)
-
-#define SDIO_WRAPPER_ADDRESS                     0x000000c8
-#define SDIO_WRAPPER_OFFSET                      0x000000c8
-#define SDIO_WRAPPER_SLEEP_MSB                   3
-#define SDIO_WRAPPER_SLEEP_LSB                   3
-#define SDIO_WRAPPER_SLEEP_MASK                  0x00000008
-#define SDIO_WRAPPER_SLEEP_GET(x)                (((x) & SDIO_WRAPPER_SLEEP_MASK) >> SDIO_WRAPPER_SLEEP_LSB)
-#define SDIO_WRAPPER_SLEEP_SET(x)                (((x) << SDIO_WRAPPER_SLEEP_LSB) & SDIO_WRAPPER_SLEEP_MASK)
-#define SDIO_WRAPPER_WAKEUP_MSB                  2
-#define SDIO_WRAPPER_WAKEUP_LSB                  2
-#define SDIO_WRAPPER_WAKEUP_MASK                 0x00000004
-#define SDIO_WRAPPER_WAKEUP_GET(x)               (((x) & SDIO_WRAPPER_WAKEUP_MASK) >> SDIO_WRAPPER_WAKEUP_LSB)
-#define SDIO_WRAPPER_WAKEUP_SET(x)               (((x) << SDIO_WRAPPER_WAKEUP_LSB) & SDIO_WRAPPER_WAKEUP_MASK)
-#define SDIO_WRAPPER_SOC_ON_MSB                  1
-#define SDIO_WRAPPER_SOC_ON_LSB                  1
-#define SDIO_WRAPPER_SOC_ON_MASK                 0x00000002
-#define SDIO_WRAPPER_SOC_ON_GET(x)               (((x) & SDIO_WRAPPER_SOC_ON_MASK) >> SDIO_WRAPPER_SOC_ON_LSB)
-#define SDIO_WRAPPER_SOC_ON_SET(x)               (((x) << SDIO_WRAPPER_SOC_ON_LSB) & SDIO_WRAPPER_SOC_ON_MASK)
-#define SDIO_WRAPPER_ON_MSB                      0
-#define SDIO_WRAPPER_ON_LSB                      0
-#define SDIO_WRAPPER_ON_MASK                     0x00000001
-#define SDIO_WRAPPER_ON_GET(x)                   (((x) & SDIO_WRAPPER_ON_MASK) >> SDIO_WRAPPER_ON_LSB)
-#define SDIO_WRAPPER_ON_SET(x)                   (((x) << SDIO_WRAPPER_ON_LSB) & SDIO_WRAPPER_ON_MASK)
-
-#define MAC_SLEEP_CONTROL_ADDRESS                0x000000cc
-#define MAC_SLEEP_CONTROL_OFFSET                 0x000000cc
-#define MAC_SLEEP_CONTROL_ENABLE_MSB             1
-#define MAC_SLEEP_CONTROL_ENABLE_LSB             0
-#define MAC_SLEEP_CONTROL_ENABLE_MASK            0x00000003
-#define MAC_SLEEP_CONTROL_ENABLE_GET(x)          (((x) & MAC_SLEEP_CONTROL_ENABLE_MASK) >> MAC_SLEEP_CONTROL_ENABLE_LSB)
-#define MAC_SLEEP_CONTROL_ENABLE_SET(x)          (((x) << MAC_SLEEP_CONTROL_ENABLE_LSB) & MAC_SLEEP_CONTROL_ENABLE_MASK)
-
-#define KEEP_AWAKE_ADDRESS                       0x000000d0
-#define KEEP_AWAKE_OFFSET                        0x000000d0
-#define KEEP_AWAKE_COUNT_MSB                     7
-#define KEEP_AWAKE_COUNT_LSB                     0
-#define KEEP_AWAKE_COUNT_MASK                    0x000000ff
-#define KEEP_AWAKE_COUNT_GET(x)                  (((x) & KEEP_AWAKE_COUNT_MASK) >> KEEP_AWAKE_COUNT_LSB)
-#define KEEP_AWAKE_COUNT_SET(x)                  (((x) << KEEP_AWAKE_COUNT_LSB) & KEEP_AWAKE_COUNT_MASK)
-
-#define LPO_CAL_TIME_ADDRESS                     0x000000d4
-#define LPO_CAL_TIME_OFFSET                      0x000000d4
-#define LPO_CAL_TIME_LENGTH_MSB                  13
-#define LPO_CAL_TIME_LENGTH_LSB                  0
-#define LPO_CAL_TIME_LENGTH_MASK                 0x00003fff
-#define LPO_CAL_TIME_LENGTH_GET(x)               (((x) & LPO_CAL_TIME_LENGTH_MASK) >> LPO_CAL_TIME_LENGTH_LSB)
-#define LPO_CAL_TIME_LENGTH_SET(x)               (((x) << LPO_CAL_TIME_LENGTH_LSB) & LPO_CAL_TIME_LENGTH_MASK)
-
-#define LPO_INIT_DIVIDEND_INT_ADDRESS            0x000000d8
-#define LPO_INIT_DIVIDEND_INT_OFFSET             0x000000d8
-#define LPO_INIT_DIVIDEND_INT_VALUE_MSB          23
-#define LPO_INIT_DIVIDEND_INT_VALUE_LSB          0
-#define LPO_INIT_DIVIDEND_INT_VALUE_MASK         0x00ffffff
-#define LPO_INIT_DIVIDEND_INT_VALUE_GET(x)       (((x) & LPO_INIT_DIVIDEND_INT_VALUE_MASK) >> LPO_INIT_DIVIDEND_INT_VALUE_LSB)
-#define LPO_INIT_DIVIDEND_INT_VALUE_SET(x)       (((x) << LPO_INIT_DIVIDEND_INT_VALUE_LSB) & LPO_INIT_DIVIDEND_INT_VALUE_MASK)
-
-#define LPO_INIT_DIVIDEND_FRACTION_ADDRESS       0x000000dc
-#define LPO_INIT_DIVIDEND_FRACTION_OFFSET        0x000000dc
-#define LPO_INIT_DIVIDEND_FRACTION_VALUE_MSB     10
-#define LPO_INIT_DIVIDEND_FRACTION_VALUE_LSB     0
-#define LPO_INIT_DIVIDEND_FRACTION_VALUE_MASK    0x000007ff
-#define LPO_INIT_DIVIDEND_FRACTION_VALUE_GET(x)  (((x) & LPO_INIT_DIVIDEND_FRACTION_VALUE_MASK) >> LPO_INIT_DIVIDEND_FRACTION_VALUE_LSB)
-#define LPO_INIT_DIVIDEND_FRACTION_VALUE_SET(x)  (((x) << LPO_INIT_DIVIDEND_FRACTION_VALUE_LSB) & LPO_INIT_DIVIDEND_FRACTION_VALUE_MASK)
-
-#define LPO_CAL_ADDRESS                          0x000000e0
-#define LPO_CAL_OFFSET                           0x000000e0
-#define LPO_CAL_ENABLE_MSB                       20
-#define LPO_CAL_ENABLE_LSB                       20
-#define LPO_CAL_ENABLE_MASK                      0x00100000
-#define LPO_CAL_ENABLE_GET(x)                    (((x) & LPO_CAL_ENABLE_MASK) >> LPO_CAL_ENABLE_LSB)
-#define LPO_CAL_ENABLE_SET(x)                    (((x) << LPO_CAL_ENABLE_LSB) & LPO_CAL_ENABLE_MASK)
-#define LPO_CAL_COUNT_MSB                        19
-#define LPO_CAL_COUNT_LSB                        0
-#define LPO_CAL_COUNT_MASK                       0x000fffff
-#define LPO_CAL_COUNT_GET(x)                     (((x) & LPO_CAL_COUNT_MASK) >> LPO_CAL_COUNT_LSB)
-#define LPO_CAL_COUNT_SET(x)                     (((x) << LPO_CAL_COUNT_LSB) & LPO_CAL_COUNT_MASK)
-
-#define LPO_CAL_TEST_CONTROL_ADDRESS             0x000000e4
-#define LPO_CAL_TEST_CONTROL_OFFSET              0x000000e4
-#define LPO_CAL_TEST_CONTROL_ENABLE_MSB          5
-#define LPO_CAL_TEST_CONTROL_ENABLE_LSB          5
-#define LPO_CAL_TEST_CONTROL_ENABLE_MASK         0x00000020
-#define LPO_CAL_TEST_CONTROL_ENABLE_GET(x)       (((x) & LPO_CAL_TEST_CONTROL_ENABLE_MASK) >> LPO_CAL_TEST_CONTROL_ENABLE_LSB)
-#define LPO_CAL_TEST_CONTROL_ENABLE_SET(x)       (((x) << LPO_CAL_TEST_CONTROL_ENABLE_LSB) & LPO_CAL_TEST_CONTROL_ENABLE_MASK)
-#define LPO_CAL_TEST_CONTROL_RTC_CYCLES_MSB      4
-#define LPO_CAL_TEST_CONTROL_RTC_CYCLES_LSB      0
-#define LPO_CAL_TEST_CONTROL_RTC_CYCLES_MASK     0x0000001f
-#define LPO_CAL_TEST_CONTROL_RTC_CYCLES_GET(x)   (((x) & LPO_CAL_TEST_CONTROL_RTC_CYCLES_MASK) >> LPO_CAL_TEST_CONTROL_RTC_CYCLES_LSB)
-#define LPO_CAL_TEST_CONTROL_RTC_CYCLES_SET(x)   (((x) << LPO_CAL_TEST_CONTROL_RTC_CYCLES_LSB) & LPO_CAL_TEST_CONTROL_RTC_CYCLES_MASK)
-
-#define LPO_CAL_TEST_STATUS_ADDRESS              0x000000e8
-#define LPO_CAL_TEST_STATUS_OFFSET               0x000000e8
-#define LPO_CAL_TEST_STATUS_READY_MSB            16
-#define LPO_CAL_TEST_STATUS_READY_LSB            16
-#define LPO_CAL_TEST_STATUS_READY_MASK           0x00010000
-#define LPO_CAL_TEST_STATUS_READY_GET(x)         (((x) & LPO_CAL_TEST_STATUS_READY_MASK) >> LPO_CAL_TEST_STATUS_READY_LSB)
-#define LPO_CAL_TEST_STATUS_READY_SET(x)         (((x) << LPO_CAL_TEST_STATUS_READY_LSB) & LPO_CAL_TEST_STATUS_READY_MASK)
-#define LPO_CAL_TEST_STATUS_COUNT_MSB            15
-#define LPO_CAL_TEST_STATUS_COUNT_LSB            0
-#define LPO_CAL_TEST_STATUS_COUNT_MASK           0x0000ffff
-#define LPO_CAL_TEST_STATUS_COUNT_GET(x)         (((x) & LPO_CAL_TEST_STATUS_COUNT_MASK) >> LPO_CAL_TEST_STATUS_COUNT_LSB)
-#define LPO_CAL_TEST_STATUS_COUNT_SET(x)         (((x) << LPO_CAL_TEST_STATUS_COUNT_LSB) & LPO_CAL_TEST_STATUS_COUNT_MASK)
-
-#define CHIP_ID_ADDRESS                          0x000000ec
-#define CHIP_ID_OFFSET                           0x000000ec
-#define CHIP_ID_DEVICE_ID_MSB                    31
-#define CHIP_ID_DEVICE_ID_LSB                    16
-#define CHIP_ID_DEVICE_ID_MASK                   0xffff0000
-#define CHIP_ID_DEVICE_ID_GET(x)                 (((x) & CHIP_ID_DEVICE_ID_MASK) >> CHIP_ID_DEVICE_ID_LSB)
-#define CHIP_ID_DEVICE_ID_SET(x)                 (((x) << CHIP_ID_DEVICE_ID_LSB) & CHIP_ID_DEVICE_ID_MASK)
-#define CHIP_ID_CONFIG_ID_MSB                    15
-#define CHIP_ID_CONFIG_ID_LSB                    4
-#define CHIP_ID_CONFIG_ID_MASK                   0x0000fff0
-#define CHIP_ID_CONFIG_ID_GET(x)                 (((x) & CHIP_ID_CONFIG_ID_MASK) >> CHIP_ID_CONFIG_ID_LSB)
-#define CHIP_ID_CONFIG_ID_SET(x)                 (((x) << CHIP_ID_CONFIG_ID_LSB) & CHIP_ID_CONFIG_ID_MASK)
-#define CHIP_ID_VERSION_ID_MSB                   3
-#define CHIP_ID_VERSION_ID_LSB                   0
-#define CHIP_ID_VERSION_ID_MASK                  0x0000000f
-#define CHIP_ID_VERSION_ID_GET(x)                (((x) & CHIP_ID_VERSION_ID_MASK) >> CHIP_ID_VERSION_ID_LSB)
-#define CHIP_ID_VERSION_ID_SET(x)                (((x) << CHIP_ID_VERSION_ID_LSB) & CHIP_ID_VERSION_ID_MASK)
-
-#define DERIVED_RTC_CLK_ADDRESS                  0x000000f0
-#define DERIVED_RTC_CLK_OFFSET                   0x000000f0
-#define DERIVED_RTC_CLK_EXTERNAL_DETECT_EN_MSB   20
-#define DERIVED_RTC_CLK_EXTERNAL_DETECT_EN_LSB   20
-#define DERIVED_RTC_CLK_EXTERNAL_DETECT_EN_MASK  0x00100000
-#define DERIVED_RTC_CLK_EXTERNAL_DETECT_EN_GET(x) (((x) & DERIVED_RTC_CLK_EXTERNAL_DETECT_EN_MASK) >> DERIVED_RTC_CLK_EXTERNAL_DETECT_EN_LSB)
-#define DERIVED_RTC_CLK_EXTERNAL_DETECT_EN_SET(x) (((x) << DERIVED_RTC_CLK_EXTERNAL_DETECT_EN_LSB) & DERIVED_RTC_CLK_EXTERNAL_DETECT_EN_MASK)
-#define DERIVED_RTC_CLK_EXTERNAL_DETECT_MSB      18
-#define DERIVED_RTC_CLK_EXTERNAL_DETECT_LSB      18
-#define DERIVED_RTC_CLK_EXTERNAL_DETECT_MASK     0x00040000
-#define DERIVED_RTC_CLK_EXTERNAL_DETECT_GET(x)   (((x) & DERIVED_RTC_CLK_EXTERNAL_DETECT_MASK) >> DERIVED_RTC_CLK_EXTERNAL_DETECT_LSB)
-#define DERIVED_RTC_CLK_EXTERNAL_DETECT_SET(x)   (((x) << DERIVED_RTC_CLK_EXTERNAL_DETECT_LSB) & DERIVED_RTC_CLK_EXTERNAL_DETECT_MASK)
-#define DERIVED_RTC_CLK_FORCE_MSB                17
-#define DERIVED_RTC_CLK_FORCE_LSB                16
-#define DERIVED_RTC_CLK_FORCE_MASK               0x00030000
-#define DERIVED_RTC_CLK_FORCE_GET(x)             (((x) & DERIVED_RTC_CLK_FORCE_MASK) >> DERIVED_RTC_CLK_FORCE_LSB)
-#define DERIVED_RTC_CLK_FORCE_SET(x)             (((x) << DERIVED_RTC_CLK_FORCE_LSB) & DERIVED_RTC_CLK_FORCE_MASK)
-#define DERIVED_RTC_CLK_PERIOD_MSB               15
-#define DERIVED_RTC_CLK_PERIOD_LSB               1
-#define DERIVED_RTC_CLK_PERIOD_MASK              0x0000fffe
-#define DERIVED_RTC_CLK_PERIOD_GET(x)            (((x) & DERIVED_RTC_CLK_PERIOD_MASK) >> DERIVED_RTC_CLK_PERIOD_LSB)
-#define DERIVED_RTC_CLK_PERIOD_SET(x)            (((x) << DERIVED_RTC_CLK_PERIOD_LSB) & DERIVED_RTC_CLK_PERIOD_MASK)
-
-#define MAC_PCU_SLP32_MODE_ADDRESS               0x000000f4
-#define MAC_PCU_SLP32_MODE_OFFSET                0x000000f4
-#define MAC_PCU_SLP32_MODE_TSF_WRITE_PENDING_MSB 21
-#define MAC_PCU_SLP32_MODE_TSF_WRITE_PENDING_LSB 21
-#define MAC_PCU_SLP32_MODE_TSF_WRITE_PENDING_MASK 0x00200000
-#define MAC_PCU_SLP32_MODE_TSF_WRITE_PENDING_GET(x) (((x) & MAC_PCU_SLP32_MODE_TSF_WRITE_PENDING_MASK) >> MAC_PCU_SLP32_MODE_TSF_WRITE_PENDING_LSB)
-#define MAC_PCU_SLP32_MODE_TSF_WRITE_PENDING_SET(x) (((x) << MAC_PCU_SLP32_MODE_TSF_WRITE_PENDING_LSB) & MAC_PCU_SLP32_MODE_TSF_WRITE_PENDING_MASK)
-#define MAC_PCU_SLP32_MODE_HALF_CLK_LATENCY_MSB  19
-#define MAC_PCU_SLP32_MODE_HALF_CLK_LATENCY_LSB  0
-#define MAC_PCU_SLP32_MODE_HALF_CLK_LATENCY_MASK 0x000fffff
-#define MAC_PCU_SLP32_MODE_HALF_CLK_LATENCY_GET(x) (((x) & MAC_PCU_SLP32_MODE_HALF_CLK_LATENCY_MASK) >> MAC_PCU_SLP32_MODE_HALF_CLK_LATENCY_LSB)
-#define MAC_PCU_SLP32_MODE_HALF_CLK_LATENCY_SET(x) (((x) << MAC_PCU_SLP32_MODE_HALF_CLK_LATENCY_LSB) & MAC_PCU_SLP32_MODE_HALF_CLK_LATENCY_MASK)
-
-#define MAC_PCU_SLP32_WAKE_ADDRESS               0x000000f8
-#define MAC_PCU_SLP32_WAKE_OFFSET                0x000000f8
-#define MAC_PCU_SLP32_WAKE_XTL_TIME_MSB          15
-#define MAC_PCU_SLP32_WAKE_XTL_TIME_LSB          0
-#define MAC_PCU_SLP32_WAKE_XTL_TIME_MASK         0x0000ffff
-#define MAC_PCU_SLP32_WAKE_XTL_TIME_GET(x)       (((x) & MAC_PCU_SLP32_WAKE_XTL_TIME_MASK) >> MAC_PCU_SLP32_WAKE_XTL_TIME_LSB)
-#define MAC_PCU_SLP32_WAKE_XTL_TIME_SET(x)       (((x) << MAC_PCU_SLP32_WAKE_XTL_TIME_LSB) & MAC_PCU_SLP32_WAKE_XTL_TIME_MASK)
-
-#define MAC_PCU_SLP32_INC_ADDRESS                0x000000fc
-#define MAC_PCU_SLP32_INC_OFFSET                 0x000000fc
-#define MAC_PCU_SLP32_INC_TSF_INC_MSB            19
-#define MAC_PCU_SLP32_INC_TSF_INC_LSB            0
-#define MAC_PCU_SLP32_INC_TSF_INC_MASK           0x000fffff
-#define MAC_PCU_SLP32_INC_TSF_INC_GET(x)         (((x) & MAC_PCU_SLP32_INC_TSF_INC_MASK) >> MAC_PCU_SLP32_INC_TSF_INC_LSB)
-#define MAC_PCU_SLP32_INC_TSF_INC_SET(x)         (((x) << MAC_PCU_SLP32_INC_TSF_INC_LSB) & MAC_PCU_SLP32_INC_TSF_INC_MASK)
-
-#define MAC_PCU_SLP_MIB1_ADDRESS                 0x00000100
-#define MAC_PCU_SLP_MIB1_OFFSET                  0x00000100
-#define MAC_PCU_SLP_MIB1_SLEEP_CNT_MSB           31
-#define MAC_PCU_SLP_MIB1_SLEEP_CNT_LSB           0
-#define MAC_PCU_SLP_MIB1_SLEEP_CNT_MASK          0xffffffff
-#define MAC_PCU_SLP_MIB1_SLEEP_CNT_GET(x)        (((x) & MAC_PCU_SLP_MIB1_SLEEP_CNT_MASK) >> MAC_PCU_SLP_MIB1_SLEEP_CNT_LSB)
-#define MAC_PCU_SLP_MIB1_SLEEP_CNT_SET(x)        (((x) << MAC_PCU_SLP_MIB1_SLEEP_CNT_LSB) & MAC_PCU_SLP_MIB1_SLEEP_CNT_MASK)
-
-#define MAC_PCU_SLP_MIB2_ADDRESS                 0x00000104
-#define MAC_PCU_SLP_MIB2_OFFSET                  0x00000104
-#define MAC_PCU_SLP_MIB2_CYCLE_CNT_MSB           31
-#define MAC_PCU_SLP_MIB2_CYCLE_CNT_LSB           0
-#define MAC_PCU_SLP_MIB2_CYCLE_CNT_MASK          0xffffffff
-#define MAC_PCU_SLP_MIB2_CYCLE_CNT_GET(x)        (((x) & MAC_PCU_SLP_MIB2_CYCLE_CNT_MASK) >> MAC_PCU_SLP_MIB2_CYCLE_CNT_LSB)
-#define MAC_PCU_SLP_MIB2_CYCLE_CNT_SET(x)        (((x) << MAC_PCU_SLP_MIB2_CYCLE_CNT_LSB) & MAC_PCU_SLP_MIB2_CYCLE_CNT_MASK)
-
-#define MAC_PCU_SLP_MIB3_ADDRESS                 0x00000108
-#define MAC_PCU_SLP_MIB3_OFFSET                  0x00000108
-#define MAC_PCU_SLP_MIB3_PENDING_MSB             1
-#define MAC_PCU_SLP_MIB3_PENDING_LSB             1
-#define MAC_PCU_SLP_MIB3_PENDING_MASK            0x00000002
-#define MAC_PCU_SLP_MIB3_PENDING_GET(x)          (((x) & MAC_PCU_SLP_MIB3_PENDING_MASK) >> MAC_PCU_SLP_MIB3_PENDING_LSB)
-#define MAC_PCU_SLP_MIB3_PENDING_SET(x)          (((x) << MAC_PCU_SLP_MIB3_PENDING_LSB) & MAC_PCU_SLP_MIB3_PENDING_MASK)
-#define MAC_PCU_SLP_MIB3_CLR_CNT_MSB             0
-#define MAC_PCU_SLP_MIB3_CLR_CNT_LSB             0
-#define MAC_PCU_SLP_MIB3_CLR_CNT_MASK            0x00000001
-#define MAC_PCU_SLP_MIB3_CLR_CNT_GET(x)          (((x) & MAC_PCU_SLP_MIB3_CLR_CNT_MASK) >> MAC_PCU_SLP_MIB3_CLR_CNT_LSB)
-#define MAC_PCU_SLP_MIB3_CLR_CNT_SET(x)          (((x) << MAC_PCU_SLP_MIB3_CLR_CNT_LSB) & MAC_PCU_SLP_MIB3_CLR_CNT_MASK)
-
-#define MAC_PCU_SLP_BEACON_ADDRESS               0x0000010c
-#define MAC_PCU_SLP_BEACON_OFFSET                0x0000010c
-#define MAC_PCU_SLP_BEACON_BMISS_TIMEOUT_ENABLE_MSB 24
-#define MAC_PCU_SLP_BEACON_BMISS_TIMEOUT_ENABLE_LSB 24
-#define MAC_PCU_SLP_BEACON_BMISS_TIMEOUT_ENABLE_MASK 0x01000000
-#define MAC_PCU_SLP_BEACON_BMISS_TIMEOUT_ENABLE_GET(x) (((x) & MAC_PCU_SLP_BEACON_BMISS_TIMEOUT_ENABLE_MASK) >> MAC_PCU_SLP_BEACON_BMISS_TIMEOUT_ENABLE_LSB)
-#define MAC_PCU_SLP_BEACON_BMISS_TIMEOUT_ENABLE_SET(x) (((x) << MAC_PCU_SLP_BEACON_BMISS_TIMEOUT_ENABLE_LSB) & MAC_PCU_SLP_BEACON_BMISS_TIMEOUT_ENABLE_MASK)
-#define MAC_PCU_SLP_BEACON_BMISS_TIMEOUT_MSB     23
-#define MAC_PCU_SLP_BEACON_BMISS_TIMEOUT_LSB     0
-#define MAC_PCU_SLP_BEACON_BMISS_TIMEOUT_MASK    0x00ffffff
-#define MAC_PCU_SLP_BEACON_BMISS_TIMEOUT_GET(x)  (((x) & MAC_PCU_SLP_BEACON_BMISS_TIMEOUT_MASK) >> MAC_PCU_SLP_BEACON_BMISS_TIMEOUT_LSB)
-#define MAC_PCU_SLP_BEACON_BMISS_TIMEOUT_SET(x)  (((x) << MAC_PCU_SLP_BEACON_BMISS_TIMEOUT_LSB) & MAC_PCU_SLP_BEACON_BMISS_TIMEOUT_MASK)
-
-#define POWER_REG_ADDRESS                        0x00000110
-#define POWER_REG_OFFSET                         0x00000110
-#define POWER_REG_VLVL_MSB                       11
-#define POWER_REG_VLVL_LSB                       8
-#define POWER_REG_VLVL_MASK                      0x00000f00
-#define POWER_REG_VLVL_GET(x)                    (((x) & POWER_REG_VLVL_MASK) >> POWER_REG_VLVL_LSB)
-#define POWER_REG_VLVL_SET(x)                    (((x) << POWER_REG_VLVL_LSB) & POWER_REG_VLVL_MASK)
-#define POWER_REG_CPU_INT_ENABLE_MSB             7
-#define POWER_REG_CPU_INT_ENABLE_LSB             7
-#define POWER_REG_CPU_INT_ENABLE_MASK            0x00000080
-#define POWER_REG_CPU_INT_ENABLE_GET(x)          (((x) & POWER_REG_CPU_INT_ENABLE_MASK) >> POWER_REG_CPU_INT_ENABLE_LSB)
-#define POWER_REG_CPU_INT_ENABLE_SET(x)          (((x) << POWER_REG_CPU_INT_ENABLE_LSB) & POWER_REG_CPU_INT_ENABLE_MASK)
-#define POWER_REG_WLAN_ISO_DIS_MSB               6
-#define POWER_REG_WLAN_ISO_DIS_LSB               6
-#define POWER_REG_WLAN_ISO_DIS_MASK              0x00000040
-#define POWER_REG_WLAN_ISO_DIS_GET(x)            (((x) & POWER_REG_WLAN_ISO_DIS_MASK) >> POWER_REG_WLAN_ISO_DIS_LSB)
-#define POWER_REG_WLAN_ISO_DIS_SET(x)            (((x) << POWER_REG_WLAN_ISO_DIS_LSB) & POWER_REG_WLAN_ISO_DIS_MASK)
-#define POWER_REG_WLAN_ISO_CNTL_MSB              5
-#define POWER_REG_WLAN_ISO_CNTL_LSB              5
-#define POWER_REG_WLAN_ISO_CNTL_MASK             0x00000020
-#define POWER_REG_WLAN_ISO_CNTL_GET(x)           (((x) & POWER_REG_WLAN_ISO_CNTL_MASK) >> POWER_REG_WLAN_ISO_CNTL_LSB)
-#define POWER_REG_WLAN_ISO_CNTL_SET(x)           (((x) << POWER_REG_WLAN_ISO_CNTL_LSB) & POWER_REG_WLAN_ISO_CNTL_MASK)
-#define POWER_REG_RADIO_PWD_EN_MSB               4
-#define POWER_REG_RADIO_PWD_EN_LSB               4
-#define POWER_REG_RADIO_PWD_EN_MASK              0x00000010
-#define POWER_REG_RADIO_PWD_EN_GET(x)            (((x) & POWER_REG_RADIO_PWD_EN_MASK) >> POWER_REG_RADIO_PWD_EN_LSB)
-#define POWER_REG_RADIO_PWD_EN_SET(x)            (((x) << POWER_REG_RADIO_PWD_EN_LSB) & POWER_REG_RADIO_PWD_EN_MASK)
-#define POWER_REG_SOC_SCALE_EN_MSB               3
-#define POWER_REG_SOC_SCALE_EN_LSB               3
-#define POWER_REG_SOC_SCALE_EN_MASK              0x00000008
-#define POWER_REG_SOC_SCALE_EN_GET(x)            (((x) & POWER_REG_SOC_SCALE_EN_MASK) >> POWER_REG_SOC_SCALE_EN_LSB)
-#define POWER_REG_SOC_SCALE_EN_SET(x)            (((x) << POWER_REG_SOC_SCALE_EN_LSB) & POWER_REG_SOC_SCALE_EN_MASK)
-#define POWER_REG_WLAN_SCALE_EN_MSB              2
-#define POWER_REG_WLAN_SCALE_EN_LSB              2
-#define POWER_REG_WLAN_SCALE_EN_MASK             0x00000004
-#define POWER_REG_WLAN_SCALE_EN_GET(x)           (((x) & POWER_REG_WLAN_SCALE_EN_MASK) >> POWER_REG_WLAN_SCALE_EN_LSB)
-#define POWER_REG_WLAN_SCALE_EN_SET(x)           (((x) << POWER_REG_WLAN_SCALE_EN_LSB) & POWER_REG_WLAN_SCALE_EN_MASK)
-#define POWER_REG_WLAN_PWD_EN_MSB                1
-#define POWER_REG_WLAN_PWD_EN_LSB                1
-#define POWER_REG_WLAN_PWD_EN_MASK               0x00000002
-#define POWER_REG_WLAN_PWD_EN_GET(x)             (((x) & POWER_REG_WLAN_PWD_EN_MASK) >> POWER_REG_WLAN_PWD_EN_LSB)
-#define POWER_REG_WLAN_PWD_EN_SET(x)             (((x) << POWER_REG_WLAN_PWD_EN_LSB) & POWER_REG_WLAN_PWD_EN_MASK)
-#define POWER_REG_POWER_EN_MSB                   0
-#define POWER_REG_POWER_EN_LSB                   0
-#define POWER_REG_POWER_EN_MASK                  0x00000001
-#define POWER_REG_POWER_EN_GET(x)                (((x) & POWER_REG_POWER_EN_MASK) >> POWER_REG_POWER_EN_LSB)
-#define POWER_REG_POWER_EN_SET(x)                (((x) << POWER_REG_POWER_EN_LSB) & POWER_REG_POWER_EN_MASK)
-
-#define CORE_CLK_CTRL_ADDRESS                    0x00000114
-#define CORE_CLK_CTRL_OFFSET                     0x00000114
-#define CORE_CLK_CTRL_DIV_MSB                    2
-#define CORE_CLK_CTRL_DIV_LSB                    0
-#define CORE_CLK_CTRL_DIV_MASK                   0x00000007
-#define CORE_CLK_CTRL_DIV_GET(x)                 (((x) & CORE_CLK_CTRL_DIV_MASK) >> CORE_CLK_CTRL_DIV_LSB)
-#define CORE_CLK_CTRL_DIV_SET(x)                 (((x) << CORE_CLK_CTRL_DIV_LSB) & CORE_CLK_CTRL_DIV_MASK)
-
-#define SDIO_SETUP_CIRCUIT_ADDRESS               0x00000120
-#define SDIO_SETUP_CIRCUIT_OFFSET                0x00000120
-#define SDIO_SETUP_CIRCUIT_VECTOR_MSB            7
-#define SDIO_SETUP_CIRCUIT_VECTOR_LSB            0
-#define SDIO_SETUP_CIRCUIT_VECTOR_MASK           0x000000ff
-#define SDIO_SETUP_CIRCUIT_VECTOR_GET(x)         (((x) & SDIO_SETUP_CIRCUIT_VECTOR_MASK) >> SDIO_SETUP_CIRCUIT_VECTOR_LSB)
-#define SDIO_SETUP_CIRCUIT_VECTOR_SET(x)         (((x) << SDIO_SETUP_CIRCUIT_VECTOR_LSB) & SDIO_SETUP_CIRCUIT_VECTOR_MASK)
-
-#define SDIO_SETUP_CONFIG_ADDRESS                0x00000140
-#define SDIO_SETUP_CONFIG_OFFSET                 0x00000140
-#define SDIO_SETUP_CONFIG_ENABLE_MSB             1
-#define SDIO_SETUP_CONFIG_ENABLE_LSB             1
-#define SDIO_SETUP_CONFIG_ENABLE_MASK            0x00000002
-#define SDIO_SETUP_CONFIG_ENABLE_GET(x)          (((x) & SDIO_SETUP_CONFIG_ENABLE_MASK) >> SDIO_SETUP_CONFIG_ENABLE_LSB)
-#define SDIO_SETUP_CONFIG_ENABLE_SET(x)          (((x) << SDIO_SETUP_CONFIG_ENABLE_LSB) & SDIO_SETUP_CONFIG_ENABLE_MASK)
-#define SDIO_SETUP_CONFIG_CLEAR_MSB              0
-#define SDIO_SETUP_CONFIG_CLEAR_LSB              0
-#define SDIO_SETUP_CONFIG_CLEAR_MASK             0x00000001
-#define SDIO_SETUP_CONFIG_CLEAR_GET(x)           (((x) & SDIO_SETUP_CONFIG_CLEAR_MASK) >> SDIO_SETUP_CONFIG_CLEAR_LSB)
-#define SDIO_SETUP_CONFIG_CLEAR_SET(x)           (((x) << SDIO_SETUP_CONFIG_CLEAR_LSB) & SDIO_SETUP_CONFIG_CLEAR_MASK)
-
-#define CPU_SETUP_CONFIG_ADDRESS                 0x00000144
-#define CPU_SETUP_CONFIG_OFFSET                  0x00000144
-#define CPU_SETUP_CONFIG_ENABLE_MSB              1
-#define CPU_SETUP_CONFIG_ENABLE_LSB              1
-#define CPU_SETUP_CONFIG_ENABLE_MASK             0x00000002
-#define CPU_SETUP_CONFIG_ENABLE_GET(x)           (((x) & CPU_SETUP_CONFIG_ENABLE_MASK) >> CPU_SETUP_CONFIG_ENABLE_LSB)
-#define CPU_SETUP_CONFIG_ENABLE_SET(x)           (((x) << CPU_SETUP_CONFIG_ENABLE_LSB) & CPU_SETUP_CONFIG_ENABLE_MASK)
-#define CPU_SETUP_CONFIG_CLEAR_MSB               0
-#define CPU_SETUP_CONFIG_CLEAR_LSB               0
-#define CPU_SETUP_CONFIG_CLEAR_MASK              0x00000001
-#define CPU_SETUP_CONFIG_CLEAR_GET(x)            (((x) & CPU_SETUP_CONFIG_CLEAR_MASK) >> CPU_SETUP_CONFIG_CLEAR_LSB)
-#define CPU_SETUP_CONFIG_CLEAR_SET(x)            (((x) << CPU_SETUP_CONFIG_CLEAR_LSB) & CPU_SETUP_CONFIG_CLEAR_MASK)
-
-#define CPU_SETUP_CIRCUIT_ADDRESS                0x00000160
-#define CPU_SETUP_CIRCUIT_OFFSET                 0x00000160
-#define CPU_SETUP_CIRCUIT_VECTOR_MSB             7
-#define CPU_SETUP_CIRCUIT_VECTOR_LSB             0
-#define CPU_SETUP_CIRCUIT_VECTOR_MASK            0x000000ff
-#define CPU_SETUP_CIRCUIT_VECTOR_GET(x)          (((x) & CPU_SETUP_CIRCUIT_VECTOR_MASK) >> CPU_SETUP_CIRCUIT_VECTOR_LSB)
-#define CPU_SETUP_CIRCUIT_VECTOR_SET(x)          (((x) << CPU_SETUP_CIRCUIT_VECTOR_LSB) & CPU_SETUP_CIRCUIT_VECTOR_MASK)
-
-#define BB_SETUP_CONFIG_ADDRESS                  0x00000180
-#define BB_SETUP_CONFIG_OFFSET                   0x00000180
-#define BB_SETUP_CONFIG_ENABLE_MSB               1
-#define BB_SETUP_CONFIG_ENABLE_LSB               1
-#define BB_SETUP_CONFIG_ENABLE_MASK              0x00000002
-#define BB_SETUP_CONFIG_ENABLE_GET(x)            (((x) & BB_SETUP_CONFIG_ENABLE_MASK) >> BB_SETUP_CONFIG_ENABLE_LSB)
-#define BB_SETUP_CONFIG_ENABLE_SET(x)            (((x) << BB_SETUP_CONFIG_ENABLE_LSB) & BB_SETUP_CONFIG_ENABLE_MASK)
-#define BB_SETUP_CONFIG_CLEAR_MSB                0
-#define BB_SETUP_CONFIG_CLEAR_LSB                0
-#define BB_SETUP_CONFIG_CLEAR_MASK               0x00000001
-#define BB_SETUP_CONFIG_CLEAR_GET(x)             (((x) & BB_SETUP_CONFIG_CLEAR_MASK) >> BB_SETUP_CONFIG_CLEAR_LSB)
-#define BB_SETUP_CONFIG_CLEAR_SET(x)             (((x) << BB_SETUP_CONFIG_CLEAR_LSB) & BB_SETUP_CONFIG_CLEAR_MASK)
-
-#define BB_SETUP_CIRCUIT_ADDRESS                 0x000001a0
-#define BB_SETUP_CIRCUIT_OFFSET                  0x000001a0
-#define BB_SETUP_CIRCUIT_VECTOR_MSB              7
-#define BB_SETUP_CIRCUIT_VECTOR_LSB              0
-#define BB_SETUP_CIRCUIT_VECTOR_MASK             0x000000ff
-#define BB_SETUP_CIRCUIT_VECTOR_GET(x)           (((x) & BB_SETUP_CIRCUIT_VECTOR_MASK) >> BB_SETUP_CIRCUIT_VECTOR_LSB)
-#define BB_SETUP_CIRCUIT_VECTOR_SET(x)           (((x) << BB_SETUP_CIRCUIT_VECTOR_LSB) & BB_SETUP_CIRCUIT_VECTOR_MASK)
-
-#define GPIO_WAKEUP_CONTROL_ADDRESS              0x000001c0
-#define GPIO_WAKEUP_CONTROL_OFFSET               0x000001c0
-#define GPIO_WAKEUP_CONTROL_ENABLE_MSB           0
-#define GPIO_WAKEUP_CONTROL_ENABLE_LSB           0
-#define GPIO_WAKEUP_CONTROL_ENABLE_MASK          0x00000001
-#define GPIO_WAKEUP_CONTROL_ENABLE_GET(x)        (((x) & GPIO_WAKEUP_CONTROL_ENABLE_MASK) >> GPIO_WAKEUP_CONTROL_ENABLE_LSB)
-#define GPIO_WAKEUP_CONTROL_ENABLE_SET(x)        (((x) << GPIO_WAKEUP_CONTROL_ENABLE_LSB) & GPIO_WAKEUP_CONTROL_ENABLE_MASK)
-
-
-#ifndef __ASSEMBLER__
-
-typedef struct rtc_reg_reg_s {
-  volatile unsigned int reset_control;
-  volatile unsigned int xtal_control;
-  volatile unsigned int tcxo_detect;
-  volatile unsigned int xtal_test;
-  volatile unsigned int quadrature;
-  volatile unsigned int pll_control;
-  volatile unsigned int pll_settle;
-  volatile unsigned int xtal_settle;
-  volatile unsigned int cpu_clock;
-  volatile unsigned int clock_out;
-  volatile unsigned int clock_control;
-  volatile unsigned int bias_override;
-  volatile unsigned int wdt_control;
-  volatile unsigned int wdt_status;
-  volatile unsigned int wdt;
-  volatile unsigned int wdt_count;
-  volatile unsigned int wdt_reset;
-  volatile unsigned int int_status;
-  volatile unsigned int lf_timer0;
-  volatile unsigned int lf_timer_count0;
-  volatile unsigned int lf_timer_control0;
-  volatile unsigned int lf_timer_status0;
-  volatile unsigned int lf_timer1;
-  volatile unsigned int lf_timer_count1;
-  volatile unsigned int lf_timer_control1;
-  volatile unsigned int lf_timer_status1;
-  volatile unsigned int lf_timer2;
-  volatile unsigned int lf_timer_count2;
-  volatile unsigned int lf_timer_control2;
-  volatile unsigned int lf_timer_status2;
-  volatile unsigned int lf_timer3;
-  volatile unsigned int lf_timer_count3;
-  volatile unsigned int lf_timer_control3;
-  volatile unsigned int lf_timer_status3;
-  volatile unsigned int hf_timer;
-  volatile unsigned int hf_timer_count;
-  volatile unsigned int hf_lf_count;
-  volatile unsigned int hf_timer_control;
-  volatile unsigned int hf_timer_status;
-  volatile unsigned int rtc_control;
-  volatile unsigned int rtc_time;
-  volatile unsigned int rtc_date;
-  volatile unsigned int rtc_set_time;
-  volatile unsigned int rtc_set_date;
-  volatile unsigned int rtc_set_alarm;
-  volatile unsigned int rtc_config;
-  volatile unsigned int rtc_alarm_status;
-  volatile unsigned int uart_wakeup;
-  volatile unsigned int reset_cause;
-  volatile unsigned int system_sleep;
-  volatile unsigned int sdio_wrapper;
-  volatile unsigned int mac_sleep_control;
-  volatile unsigned int keep_awake;
-  volatile unsigned int lpo_cal_time;
-  volatile unsigned int lpo_init_dividend_int;
-  volatile unsigned int lpo_init_dividend_fraction;
-  volatile unsigned int lpo_cal;
-  volatile unsigned int lpo_cal_test_control;
-  volatile unsigned int lpo_cal_test_status;
-  volatile unsigned int chip_id;
-  volatile unsigned int derived_rtc_clk;
-  volatile unsigned int mac_pcu_slp32_mode;
-  volatile unsigned int mac_pcu_slp32_wake;
-  volatile unsigned int mac_pcu_slp32_inc;
-  volatile unsigned int mac_pcu_slp_mib1;
-  volatile unsigned int mac_pcu_slp_mib2;
-  volatile unsigned int mac_pcu_slp_mib3;
-  volatile unsigned int mac_pcu_slp_beacon;
-  volatile unsigned int power_reg;
-  volatile unsigned int core_clk_ctrl;
-  unsigned char pad0[8]; /* pad to 0x120 */
-  volatile unsigned int sdio_setup_circuit[8];
-  volatile unsigned int sdio_setup_config;
-  volatile unsigned int cpu_setup_config;
-  unsigned char pad1[24]; /* pad to 0x160 */
-  volatile unsigned int cpu_setup_circuit[8];
-  volatile unsigned int bb_setup_config;
-  unsigned char pad2[28]; /* pad to 0x1a0 */
-  volatile unsigned int bb_setup_circuit[8];
-  volatile unsigned int gpio_wakeup_control;
-} rtc_reg_reg_t;
-
-#endif /* __ASSEMBLER__ */
-
-#endif /* _RTC_REG_H_ */
diff -druN linux-2.6.39-libre/drivers/staging/ath6kl/include/common/AR6002/hw2.0/hw/si_reg.h linux-3.0-rc7-libre/drivers/staging/ath6kl/include/common/AR6002/hw2.0/hw/si_reg.h
--- linux-2.6.39-libre/drivers/staging/ath6kl/include/common/AR6002/hw2.0/hw/si_reg.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/ath6kl/include/common/AR6002/hw2.0/hw/si_reg.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,186 +0,0 @@
-#ifndef _SI_REG_REG_H_
-#define _SI_REG_REG_H_
-
-#define SI_CONFIG_ADDRESS                        0x00000000
-#define SI_CONFIG_OFFSET                         0x00000000
-#define SI_CONFIG_ERR_INT_MSB                    19
-#define SI_CONFIG_ERR_INT_LSB                    19
-#define SI_CONFIG_ERR_INT_MASK                   0x00080000
-#define SI_CONFIG_ERR_INT_GET(x)                 (((x) & SI_CONFIG_ERR_INT_MASK) >> SI_CONFIG_ERR_INT_LSB)
-#define SI_CONFIG_ERR_INT_SET(x)                 (((x) << SI_CONFIG_ERR_INT_LSB) & SI_CONFIG_ERR_INT_MASK)
-#define SI_CONFIG_BIDIR_OD_DATA_MSB              18
-#define SI_CONFIG_BIDIR_OD_DATA_LSB              18
-#define SI_CONFIG_BIDIR_OD_DATA_MASK             0x00040000
-#define SI_CONFIG_BIDIR_OD_DATA_GET(x)           (((x) & SI_CONFIG_BIDIR_OD_DATA_MASK) >> SI_CONFIG_BIDIR_OD_DATA_LSB)
-#define SI_CONFIG_BIDIR_OD_DATA_SET(x)           (((x) << SI_CONFIG_BIDIR_OD_DATA_LSB) & SI_CONFIG_BIDIR_OD_DATA_MASK)
-#define SI_CONFIG_I2C_MSB                        16
-#define SI_CONFIG_I2C_LSB                        16
-#define SI_CONFIG_I2C_MASK                       0x00010000
-#define SI_CONFIG_I2C_GET(x)                     (((x) & SI_CONFIG_I2C_MASK) >> SI_CONFIG_I2C_LSB)
-#define SI_CONFIG_I2C_SET(x)                     (((x) << SI_CONFIG_I2C_LSB) & SI_CONFIG_I2C_MASK)
-#define SI_CONFIG_POS_SAMPLE_MSB                 7
-#define SI_CONFIG_POS_SAMPLE_LSB                 7
-#define SI_CONFIG_POS_SAMPLE_MASK                0x00000080
-#define SI_CONFIG_POS_SAMPLE_GET(x)              (((x) & SI_CONFIG_POS_SAMPLE_MASK) >> SI_CONFIG_POS_SAMPLE_LSB)
-#define SI_CONFIG_POS_SAMPLE_SET(x)              (((x) << SI_CONFIG_POS_SAMPLE_LSB) & SI_CONFIG_POS_SAMPLE_MASK)
-#define SI_CONFIG_POS_DRIVE_MSB                  6
-#define SI_CONFIG_POS_DRIVE_LSB                  6
-#define SI_CONFIG_POS_DRIVE_MASK                 0x00000040
-#define SI_CONFIG_POS_DRIVE_GET(x)               (((x) & SI_CONFIG_POS_DRIVE_MASK) >> SI_CONFIG_POS_DRIVE_LSB)
-#define SI_CONFIG_POS_DRIVE_SET(x)               (((x) << SI_CONFIG_POS_DRIVE_LSB) & SI_CONFIG_POS_DRIVE_MASK)
-#define SI_CONFIG_INACTIVE_DATA_MSB              5
-#define SI_CONFIG_INACTIVE_DATA_LSB              5
-#define SI_CONFIG_INACTIVE_DATA_MASK             0x00000020
-#define SI_CONFIG_INACTIVE_DATA_GET(x)           (((x) & SI_CONFIG_INACTIVE_DATA_MASK) >> SI_CONFIG_INACTIVE_DATA_LSB)
-#define SI_CONFIG_INACTIVE_DATA_SET(x)           (((x) << SI_CONFIG_INACTIVE_DATA_LSB) & SI_CONFIG_INACTIVE_DATA_MASK)
-#define SI_CONFIG_INACTIVE_CLK_MSB               4
-#define SI_CONFIG_INACTIVE_CLK_LSB               4
-#define SI_CONFIG_INACTIVE_CLK_MASK              0x00000010
-#define SI_CONFIG_INACTIVE_CLK_GET(x)            (((x) & SI_CONFIG_INACTIVE_CLK_MASK) >> SI_CONFIG_INACTIVE_CLK_LSB)
-#define SI_CONFIG_INACTIVE_CLK_SET(x)            (((x) << SI_CONFIG_INACTIVE_CLK_LSB) & SI_CONFIG_INACTIVE_CLK_MASK)
-#define SI_CONFIG_DIVIDER_MSB                    3
-#define SI_CONFIG_DIVIDER_LSB                    0
-#define SI_CONFIG_DIVIDER_MASK                   0x0000000f
-#define SI_CONFIG_DIVIDER_GET(x)                 (((x) & SI_CONFIG_DIVIDER_MASK) >> SI_CONFIG_DIVIDER_LSB)
-#define SI_CONFIG_DIVIDER_SET(x)                 (((x) << SI_CONFIG_DIVIDER_LSB) & SI_CONFIG_DIVIDER_MASK)
-
-#define SI_CS_ADDRESS                            0x00000004
-#define SI_CS_OFFSET                             0x00000004
-#define SI_CS_BIT_CNT_IN_LAST_BYTE_MSB           13
-#define SI_CS_BIT_CNT_IN_LAST_BYTE_LSB           11
-#define SI_CS_BIT_CNT_IN_LAST_BYTE_MASK          0x00003800
-#define SI_CS_BIT_CNT_IN_LAST_BYTE_GET(x)        (((x) & SI_CS_BIT_CNT_IN_LAST_BYTE_MASK) >> SI_CS_BIT_CNT_IN_LAST_BYTE_LSB)
-#define SI_CS_BIT_CNT_IN_LAST_BYTE_SET(x)        (((x) << SI_CS_BIT_CNT_IN_LAST_BYTE_LSB) & SI_CS_BIT_CNT_IN_LAST_BYTE_MASK)
-#define SI_CS_DONE_ERR_MSB                       10
-#define SI_CS_DONE_ERR_LSB                       10
-#define SI_CS_DONE_ERR_MASK                      0x00000400
-#define SI_CS_DONE_ERR_GET(x)                    (((x) & SI_CS_DONE_ERR_MASK) >> SI_CS_DONE_ERR_LSB)
-#define SI_CS_DONE_ERR_SET(x)                    (((x) << SI_CS_DONE_ERR_LSB) & SI_CS_DONE_ERR_MASK)
-#define SI_CS_DONE_INT_MSB                       9
-#define SI_CS_DONE_INT_LSB                       9
-#define SI_CS_DONE_INT_MASK                      0x00000200
-#define SI_CS_DONE_INT_GET(x)                    (((x) & SI_CS_DONE_INT_MASK) >> SI_CS_DONE_INT_LSB)
-#define SI_CS_DONE_INT_SET(x)                    (((x) << SI_CS_DONE_INT_LSB) & SI_CS_DONE_INT_MASK)
-#define SI_CS_START_MSB                          8
-#define SI_CS_START_LSB                          8
-#define SI_CS_START_MASK                         0x00000100
-#define SI_CS_START_GET(x)                       (((x) & SI_CS_START_MASK) >> SI_CS_START_LSB)
-#define SI_CS_START_SET(x)                       (((x) << SI_CS_START_LSB) & SI_CS_START_MASK)
-#define SI_CS_RX_CNT_MSB                         7
-#define SI_CS_RX_CNT_LSB                         4
-#define SI_CS_RX_CNT_MASK                        0x000000f0
-#define SI_CS_RX_CNT_GET(x)                      (((x) & SI_CS_RX_CNT_MASK) >> SI_CS_RX_CNT_LSB)
-#define SI_CS_RX_CNT_SET(x)                      (((x) << SI_CS_RX_CNT_LSB) & SI_CS_RX_CNT_MASK)
-#define SI_CS_TX_CNT_MSB                         3
-#define SI_CS_TX_CNT_LSB                         0
-#define SI_CS_TX_CNT_MASK                        0x0000000f
-#define SI_CS_TX_CNT_GET(x)                      (((x) & SI_CS_TX_CNT_MASK) >> SI_CS_TX_CNT_LSB)
-#define SI_CS_TX_CNT_SET(x)                      (((x) << SI_CS_TX_CNT_LSB) & SI_CS_TX_CNT_MASK)
-
-#define SI_TX_DATA0_ADDRESS                      0x00000008
-#define SI_TX_DATA0_OFFSET                       0x00000008
-#define SI_TX_DATA0_DATA3_MSB                    31
-#define SI_TX_DATA0_DATA3_LSB                    24
-#define SI_TX_DATA0_DATA3_MASK                   0xff000000
-#define SI_TX_DATA0_DATA3_GET(x)                 (((x) & SI_TX_DATA0_DATA3_MASK) >> SI_TX_DATA0_DATA3_LSB)
-#define SI_TX_DATA0_DATA3_SET(x)                 (((x) << SI_TX_DATA0_DATA3_LSB) & SI_TX_DATA0_DATA3_MASK)
-#define SI_TX_DATA0_DATA2_MSB                    23
-#define SI_TX_DATA0_DATA2_LSB                    16
-#define SI_TX_DATA0_DATA2_MASK                   0x00ff0000
-#define SI_TX_DATA0_DATA2_GET(x)                 (((x) & SI_TX_DATA0_DATA2_MASK) >> SI_TX_DATA0_DATA2_LSB)
-#define SI_TX_DATA0_DATA2_SET(x)                 (((x) << SI_TX_DATA0_DATA2_LSB) & SI_TX_DATA0_DATA2_MASK)
-#define SI_TX_DATA0_DATA1_MSB                    15
-#define SI_TX_DATA0_DATA1_LSB                    8
-#define SI_TX_DATA0_DATA1_MASK                   0x0000ff00
-#define SI_TX_DATA0_DATA1_GET(x)                 (((x) & SI_TX_DATA0_DATA1_MASK) >> SI_TX_DATA0_DATA1_LSB)
-#define SI_TX_DATA0_DATA1_SET(x)                 (((x) << SI_TX_DATA0_DATA1_LSB) & SI_TX_DATA0_DATA1_MASK)
-#define SI_TX_DATA0_DATA0_MSB                    7
-#define SI_TX_DATA0_DATA0_LSB                    0
-#define SI_TX_DATA0_DATA0_MASK                   0x000000ff
-#define SI_TX_DATA0_DATA0_GET(x)                 (((x) & SI_TX_DATA0_DATA0_MASK) >> SI_TX_DATA0_DATA0_LSB)
-#define SI_TX_DATA0_DATA0_SET(x)                 (((x) << SI_TX_DATA0_DATA0_LSB) & SI_TX_DATA0_DATA0_MASK)
-
-#define SI_TX_DATA1_ADDRESS                      0x0000000c
-#define SI_TX_DATA1_OFFSET                       0x0000000c
-#define SI_TX_DATA1_DATA7_MSB                    31
-#define SI_TX_DATA1_DATA7_LSB                    24
-#define SI_TX_DATA1_DATA7_MASK                   0xff000000
-#define SI_TX_DATA1_DATA7_GET(x)                 (((x) & SI_TX_DATA1_DATA7_MASK) >> SI_TX_DATA1_DATA7_LSB)
-#define SI_TX_DATA1_DATA7_SET(x)                 (((x) << SI_TX_DATA1_DATA7_LSB) & SI_TX_DATA1_DATA7_MASK)
-#define SI_TX_DATA1_DATA6_MSB                    23
-#define SI_TX_DATA1_DATA6_LSB                    16
-#define SI_TX_DATA1_DATA6_MASK                   0x00ff0000
-#define SI_TX_DATA1_DATA6_GET(x)                 (((x) & SI_TX_DATA1_DATA6_MASK) >> SI_TX_DATA1_DATA6_LSB)
-#define SI_TX_DATA1_DATA6_SET(x)                 (((x) << SI_TX_DATA1_DATA6_LSB) & SI_TX_DATA1_DATA6_MASK)
-#define SI_TX_DATA1_DATA5_MSB                    15
-#define SI_TX_DATA1_DATA5_LSB                    8
-#define SI_TX_DATA1_DATA5_MASK                   0x0000ff00
-#define SI_TX_DATA1_DATA5_GET(x)                 (((x) & SI_TX_DATA1_DATA5_MASK) >> SI_TX_DATA1_DATA5_LSB)
-#define SI_TX_DATA1_DATA5_SET(x)                 (((x) << SI_TX_DATA1_DATA5_LSB) & SI_TX_DATA1_DATA5_MASK)
-#define SI_TX_DATA1_DATA4_MSB                    7
-#define SI_TX_DATA1_DATA4_LSB                    0
-#define SI_TX_DATA1_DATA4_MASK                   0x000000ff
-#define SI_TX_DATA1_DATA4_GET(x)                 (((x) & SI_TX_DATA1_DATA4_MASK) >> SI_TX_DATA1_DATA4_LSB)
-#define SI_TX_DATA1_DATA4_SET(x)                 (((x) << SI_TX_DATA1_DATA4_LSB) & SI_TX_DATA1_DATA4_MASK)
-
-#define SI_RX_DATA0_ADDRESS                      0x00000010
-#define SI_RX_DATA0_OFFSET                       0x00000010
-#define SI_RX_DATA0_DATA3_MSB                    31
-#define SI_RX_DATA0_DATA3_LSB                    24
-#define SI_RX_DATA0_DATA3_MASK                   0xff000000
-#define SI_RX_DATA0_DATA3_GET(x)                 (((x) & SI_RX_DATA0_DATA3_MASK) >> SI_RX_DATA0_DATA3_LSB)
-#define SI_RX_DATA0_DATA3_SET(x)                 (((x) << SI_RX_DATA0_DATA3_LSB) & SI_RX_DATA0_DATA3_MASK)
-#define SI_RX_DATA0_DATA2_MSB                    23
-#define SI_RX_DATA0_DATA2_LSB                    16
-#define SI_RX_DATA0_DATA2_MASK                   0x00ff0000
-#define SI_RX_DATA0_DATA2_GET(x)                 (((x) & SI_RX_DATA0_DATA2_MASK) >> SI_RX_DATA0_DATA2_LSB)
-#define SI_RX_DATA0_DATA2_SET(x)                 (((x) << SI_RX_DATA0_DATA2_LSB) & SI_RX_DATA0_DATA2_MASK)
-#define SI_RX_DATA0_DATA1_MSB                    15
-#define SI_RX_DATA0_DATA1_LSB                    8
-#define SI_RX_DATA0_DATA1_MASK                   0x0000ff00
-#define SI_RX_DATA0_DATA1_GET(x)                 (((x) & SI_RX_DATA0_DATA1_MASK) >> SI_RX_DATA0_DATA1_LSB)
-#define SI_RX_DATA0_DATA1_SET(x)                 (((x) << SI_RX_DATA0_DATA1_LSB) & SI_RX_DATA0_DATA1_MASK)
-#define SI_RX_DATA0_DATA0_MSB                    7
-#define SI_RX_DATA0_DATA0_LSB                    0
-#define SI_RX_DATA0_DATA0_MASK                   0x000000ff
-#define SI_RX_DATA0_DATA0_GET(x)                 (((x) & SI_RX_DATA0_DATA0_MASK) >> SI_RX_DATA0_DATA0_LSB)
-#define SI_RX_DATA0_DATA0_SET(x)                 (((x) << SI_RX_DATA0_DATA0_LSB) & SI_RX_DATA0_DATA0_MASK)
-
-#define SI_RX_DATA1_ADDRESS                      0x00000014
-#define SI_RX_DATA1_OFFSET                       0x00000014
-#define SI_RX_DATA1_DATA7_MSB                    31
-#define SI_RX_DATA1_DATA7_LSB                    24
-#define SI_RX_DATA1_DATA7_MASK                   0xff000000
-#define SI_RX_DATA1_DATA7_GET(x)                 (((x) & SI_RX_DATA1_DATA7_MASK) >> SI_RX_DATA1_DATA7_LSB)
-#define SI_RX_DATA1_DATA7_SET(x)                 (((x) << SI_RX_DATA1_DATA7_LSB) & SI_RX_DATA1_DATA7_MASK)
-#define SI_RX_DATA1_DATA6_MSB                    23
-#define SI_RX_DATA1_DATA6_LSB                    16
-#define SI_RX_DATA1_DATA6_MASK                   0x00ff0000
-#define SI_RX_DATA1_DATA6_GET(x)                 (((x) & SI_RX_DATA1_DATA6_MASK) >> SI_RX_DATA1_DATA6_LSB)
-#define SI_RX_DATA1_DATA6_SET(x)                 (((x) << SI_RX_DATA1_DATA6_LSB) & SI_RX_DATA1_DATA6_MASK)
-#define SI_RX_DATA1_DATA5_MSB                    15
-#define SI_RX_DATA1_DATA5_LSB                    8
-#define SI_RX_DATA1_DATA5_MASK                   0x0000ff00
-#define SI_RX_DATA1_DATA5_GET(x)                 (((x) & SI_RX_DATA1_DATA5_MASK) >> SI_RX_DATA1_DATA5_LSB)
-#define SI_RX_DATA1_DATA5_SET(x)                 (((x) << SI_RX_DATA1_DATA5_LSB) & SI_RX_DATA1_DATA5_MASK)
-#define SI_RX_DATA1_DATA4_MSB                    7
-#define SI_RX_DATA1_DATA4_LSB                    0
-#define SI_RX_DATA1_DATA4_MASK                   0x000000ff
-#define SI_RX_DATA1_DATA4_GET(x)                 (((x) & SI_RX_DATA1_DATA4_MASK) >> SI_RX_DATA1_DATA4_LSB)
-#define SI_RX_DATA1_DATA4_SET(x)                 (((x) << SI_RX_DATA1_DATA4_LSB) & SI_RX_DATA1_DATA4_MASK)
-
-
-#ifndef __ASSEMBLER__
-
-typedef struct si_reg_reg_s {
-  volatile unsigned int si_config;
-  volatile unsigned int si_cs;
-  volatile unsigned int si_tx_data0;
-  volatile unsigned int si_tx_data1;
-  volatile unsigned int si_rx_data0;
-  volatile unsigned int si_rx_data1;
-} si_reg_reg_t;
-
-#endif /* __ASSEMBLER__ */
-
-#endif /* _SI_REG_H_ */
diff -druN linux-2.6.39-libre/drivers/staging/ath6kl/include/common/AR6002/hw2.0/hw/uart_reg.h linux-3.0-rc7-libre/drivers/staging/ath6kl/include/common/AR6002/hw2.0/hw/uart_reg.h
--- linux-2.6.39-libre/drivers/staging/ath6kl/include/common/AR6002/hw2.0/hw/uart_reg.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/ath6kl/include/common/AR6002/hw2.0/hw/uart_reg.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,327 +0,0 @@
-#ifndef _UART_REG_REG_H_
-#define _UART_REG_REG_H_
-
-#define RBR_ADDRESS                              0x00000000
-#define RBR_OFFSET                               0x00000000
-#define RBR_RBR_MSB                              7
-#define RBR_RBR_LSB                              0
-#define RBR_RBR_MASK                             0x000000ff
-#define RBR_RBR_GET(x)                           (((x) & RBR_RBR_MASK) >> RBR_RBR_LSB)
-#define RBR_RBR_SET(x)                           (((x) << RBR_RBR_LSB) & RBR_RBR_MASK)
-
-#define THR_ADDRESS                              0x00000000
-#define THR_OFFSET                               0x00000000
-#define THR_THR_MSB                              7
-#define THR_THR_LSB                              0
-#define THR_THR_MASK                             0x000000ff
-#define THR_THR_GET(x)                           (((x) & THR_THR_MASK) >> THR_THR_LSB)
-#define THR_THR_SET(x)                           (((x) << THR_THR_LSB) & THR_THR_MASK)
-
-#define DLL_ADDRESS                              0x00000000
-#define DLL_OFFSET                               0x00000000
-#define DLL_DLL_MSB                              7
-#define DLL_DLL_LSB                              0
-#define DLL_DLL_MASK                             0x000000ff
-#define DLL_DLL_GET(x)                           (((x) & DLL_DLL_MASK) >> DLL_DLL_LSB)
-#define DLL_DLL_SET(x)                           (((x) << DLL_DLL_LSB) & DLL_DLL_MASK)
-
-#define DLH_ADDRESS                              0x00000004
-#define DLH_OFFSET                               0x00000004
-#define DLH_DLH_MSB                              7
-#define DLH_DLH_LSB                              0
-#define DLH_DLH_MASK                             0x000000ff
-#define DLH_DLH_GET(x)                           (((x) & DLH_DLH_MASK) >> DLH_DLH_LSB)
-#define DLH_DLH_SET(x)                           (((x) << DLH_DLH_LSB) & DLH_DLH_MASK)
-
-#define IER_ADDRESS                              0x00000004
-#define IER_OFFSET                               0x00000004
-#define IER_EDDSI_MSB                            3
-#define IER_EDDSI_LSB                            3
-#define IER_EDDSI_MASK                           0x00000008
-#define IER_EDDSI_GET(x)                         (((x) & IER_EDDSI_MASK) >> IER_EDDSI_LSB)
-#define IER_EDDSI_SET(x)                         (((x) << IER_EDDSI_LSB) & IER_EDDSI_MASK)
-#define IER_ELSI_MSB                             2
-#define IER_ELSI_LSB                             2
-#define IER_ELSI_MASK                            0x00000004
-#define IER_ELSI_GET(x)                          (((x) & IER_ELSI_MASK) >> IER_ELSI_LSB)
-#define IER_ELSI_SET(x)                          (((x) << IER_ELSI_LSB) & IER_ELSI_MASK)
-#define IER_ETBEI_MSB                            1
-#define IER_ETBEI_LSB                            1
-#define IER_ETBEI_MASK                           0x00000002
-#define IER_ETBEI_GET(x)                         (((x) & IER_ETBEI_MASK) >> IER_ETBEI_LSB)
-#define IER_ETBEI_SET(x)                         (((x) << IER_ETBEI_LSB) & IER_ETBEI_MASK)
-#define IER_ERBFI_MSB                            0
-#define IER_ERBFI_LSB                            0
-#define IER_ERBFI_MASK                           0x00000001
-#define IER_ERBFI_GET(x)                         (((x) & IER_ERBFI_MASK) >> IER_ERBFI_LSB)
-#define IER_ERBFI_SET(x)                         (((x) << IER_ERBFI_LSB) & IER_ERBFI_MASK)
-
-#define IIR_ADDRESS                              0x00000008
-#define IIR_OFFSET                               0x00000008
-#define IIR_FIFO_STATUS_MSB                      7
-#define IIR_FIFO_STATUS_LSB                      6
-#define IIR_FIFO_STATUS_MASK                     0x000000c0
-#define IIR_FIFO_STATUS_GET(x)                   (((x) & IIR_FIFO_STATUS_MASK) >> IIR_FIFO_STATUS_LSB)
-#define IIR_FIFO_STATUS_SET(x)                   (((x) << IIR_FIFO_STATUS_LSB) & IIR_FIFO_STATUS_MASK)
-#define IIR_IID_MSB                              3
-#define IIR_IID_LSB                              0
-#define IIR_IID_MASK                             0x0000000f
-#define IIR_IID_GET(x)                           (((x) & IIR_IID_MASK) >> IIR_IID_LSB)
-#define IIR_IID_SET(x)                           (((x) << IIR_IID_LSB) & IIR_IID_MASK)
-
-#define FCR_ADDRESS                              0x00000008
-#define FCR_OFFSET                               0x00000008
-#define FCR_RCVR_TRIG_MSB                        7
-#define FCR_RCVR_TRIG_LSB                        6
-#define FCR_RCVR_TRIG_MASK                       0x000000c0
-#define FCR_RCVR_TRIG_GET(x)                     (((x) & FCR_RCVR_TRIG_MASK) >> FCR_RCVR_TRIG_LSB)
-#define FCR_RCVR_TRIG_SET(x)                     (((x) << FCR_RCVR_TRIG_LSB) & FCR_RCVR_TRIG_MASK)
-#define FCR_DMA_MODE_MSB                         3
-#define FCR_DMA_MODE_LSB                         3
-#define FCR_DMA_MODE_MASK                        0x00000008
-#define FCR_DMA_MODE_GET(x)                      (((x) & FCR_DMA_MODE_MASK) >> FCR_DMA_MODE_LSB)
-#define FCR_DMA_MODE_SET(x)                      (((x) << FCR_DMA_MODE_LSB) & FCR_DMA_MODE_MASK)
-#define FCR_XMIT_FIFO_RST_MSB                    2
-#define FCR_XMIT_FIFO_RST_LSB                    2
-#define FCR_XMIT_FIFO_RST_MASK                   0x00000004
-#define FCR_XMIT_FIFO_RST_GET(x)                 (((x) & FCR_XMIT_FIFO_RST_MASK) >> FCR_XMIT_FIFO_RST_LSB)
-#define FCR_XMIT_FIFO_RST_SET(x)                 (((x) << FCR_XMIT_FIFO_RST_LSB) & FCR_XMIT_FIFO_RST_MASK)
-#define FCR_RCVR_FIFO_RST_MSB                    1
-#define FCR_RCVR_FIFO_RST_LSB                    1
-#define FCR_RCVR_FIFO_RST_MASK                   0x00000002
-#define FCR_RCVR_FIFO_RST_GET(x)                 (((x) & FCR_RCVR_FIFO_RST_MASK) >> FCR_RCVR_FIFO_RST_LSB)
-#define FCR_RCVR_FIFO_RST_SET(x)                 (((x) << FCR_RCVR_FIFO_RST_LSB) & FCR_RCVR_FIFO_RST_MASK)
-#define FCR_FIFO_EN_MSB                          0
-#define FCR_FIFO_EN_LSB                          0
-#define FCR_FIFO_EN_MASK                         0x00000001
-#define FCR_FIFO_EN_GET(x)                       (((x) & FCR_FIFO_EN_MASK) >> FCR_FIFO_EN_LSB)
-#define FCR_FIFO_EN_SET(x)                       (((x) << FCR_FIFO_EN_LSB) & FCR_FIFO_EN_MASK)
-
-#define LCR_ADDRESS                              0x0000000c
-#define LCR_OFFSET                               0x0000000c
-#define LCR_DLAB_MSB                             7
-#define LCR_DLAB_LSB                             7
-#define LCR_DLAB_MASK                            0x00000080
-#define LCR_DLAB_GET(x)                          (((x) & LCR_DLAB_MASK) >> LCR_DLAB_LSB)
-#define LCR_DLAB_SET(x)                          (((x) << LCR_DLAB_LSB) & LCR_DLAB_MASK)
-#define LCR_BREAK_MSB                            6
-#define LCR_BREAK_LSB                            6
-#define LCR_BREAK_MASK                           0x00000040
-#define LCR_BREAK_GET(x)                         (((x) & LCR_BREAK_MASK) >> LCR_BREAK_LSB)
-#define LCR_BREAK_SET(x)                         (((x) << LCR_BREAK_LSB) & LCR_BREAK_MASK)
-#define LCR_EPS_MSB                              4
-#define LCR_EPS_LSB                              4
-#define LCR_EPS_MASK                             0x00000010
-#define LCR_EPS_GET(x)                           (((x) & LCR_EPS_MASK) >> LCR_EPS_LSB)
-#define LCR_EPS_SET(x)                           (((x) << LCR_EPS_LSB) & LCR_EPS_MASK)
-#define LCR_PEN_MSB                              3
-#define LCR_PEN_LSB                              3
-#define LCR_PEN_MASK                             0x00000008
-#define LCR_PEN_GET(x)                           (((x) & LCR_PEN_MASK) >> LCR_PEN_LSB)
-#define LCR_PEN_SET(x)                           (((x) << LCR_PEN_LSB) & LCR_PEN_MASK)
-#define LCR_STOP_MSB                             2
-#define LCR_STOP_LSB                             2
-#define LCR_STOP_MASK                            0x00000004
-#define LCR_STOP_GET(x)                          (((x) & LCR_STOP_MASK) >> LCR_STOP_LSB)
-#define LCR_STOP_SET(x)                          (((x) << LCR_STOP_LSB) & LCR_STOP_MASK)
-#define LCR_CLS_MSB                              1
-#define LCR_CLS_LSB                              0
-#define LCR_CLS_MASK                             0x00000003
-#define LCR_CLS_GET(x)                           (((x) & LCR_CLS_MASK) >> LCR_CLS_LSB)
-#define LCR_CLS_SET(x)                           (((x) << LCR_CLS_LSB) & LCR_CLS_MASK)
-
-#define MCR_ADDRESS                              0x00000010
-#define MCR_OFFSET                               0x00000010
-#define MCR_LOOPBACK_MSB                         5
-#define MCR_LOOPBACK_LSB                         5
-#define MCR_LOOPBACK_MASK                        0x00000020
-#define MCR_LOOPBACK_GET(x)                      (((x) & MCR_LOOPBACK_MASK) >> MCR_LOOPBACK_LSB)
-#define MCR_LOOPBACK_SET(x)                      (((x) << MCR_LOOPBACK_LSB) & MCR_LOOPBACK_MASK)
-#define MCR_OUT2_MSB                             3
-#define MCR_OUT2_LSB                             3
-#define MCR_OUT2_MASK                            0x00000008
-#define MCR_OUT2_GET(x)                          (((x) & MCR_OUT2_MASK) >> MCR_OUT2_LSB)
-#define MCR_OUT2_SET(x)                          (((x) << MCR_OUT2_LSB) & MCR_OUT2_MASK)
-#define MCR_OUT1_MSB                             2
-#define MCR_OUT1_LSB                             2
-#define MCR_OUT1_MASK                            0x00000004
-#define MCR_OUT1_GET(x)                          (((x) & MCR_OUT1_MASK) >> MCR_OUT1_LSB)
-#define MCR_OUT1_SET(x)                          (((x) << MCR_OUT1_LSB) & MCR_OUT1_MASK)
-#define MCR_RTS_MSB                              1
-#define MCR_RTS_LSB                              1
-#define MCR_RTS_MASK                             0x00000002
-#define MCR_RTS_GET(x)                           (((x) & MCR_RTS_MASK) >> MCR_RTS_LSB)
-#define MCR_RTS_SET(x)                           (((x) << MCR_RTS_LSB) & MCR_RTS_MASK)
-#define MCR_DTR_MSB                              0
-#define MCR_DTR_LSB                              0
-#define MCR_DTR_MASK                             0x00000001
-#define MCR_DTR_GET(x)                           (((x) & MCR_DTR_MASK) >> MCR_DTR_LSB)
-#define MCR_DTR_SET(x)                           (((x) << MCR_DTR_LSB) & MCR_DTR_MASK)
-
-#define LSR_ADDRESS                              0x00000014
-#define LSR_OFFSET                               0x00000014
-#define LSR_FERR_MSB                             7
-#define LSR_FERR_LSB                             7
-#define LSR_FERR_MASK                            0x00000080
-#define LSR_FERR_GET(x)                          (((x) & LSR_FERR_MASK) >> LSR_FERR_LSB)
-#define LSR_FERR_SET(x)                          (((x) << LSR_FERR_LSB) & LSR_FERR_MASK)
-#define LSR_TEMT_MSB                             6
-#define LSR_TEMT_LSB                             6
-#define LSR_TEMT_MASK                            0x00000040
-#define LSR_TEMT_GET(x)                          (((x) & LSR_TEMT_MASK) >> LSR_TEMT_LSB)
-#define LSR_TEMT_SET(x)                          (((x) << LSR_TEMT_LSB) & LSR_TEMT_MASK)
-#define LSR_THRE_MSB                             5
-#define LSR_THRE_LSB                             5
-#define LSR_THRE_MASK                            0x00000020
-#define LSR_THRE_GET(x)                          (((x) & LSR_THRE_MASK) >> LSR_THRE_LSB)
-#define LSR_THRE_SET(x)                          (((x) << LSR_THRE_LSB) & LSR_THRE_MASK)
-#define LSR_BI_MSB                               4
-#define LSR_BI_LSB                               4
-#define LSR_BI_MASK                              0x00000010
-#define LSR_BI_GET(x)                            (((x) & LSR_BI_MASK) >> LSR_BI_LSB)
-#define LSR_BI_SET(x)                            (((x) << LSR_BI_LSB) & LSR_BI_MASK)
-#define LSR_FE_MSB                               3
-#define LSR_FE_LSB                               3
-#define LSR_FE_MASK                              0x00000008
-#define LSR_FE_GET(x)                            (((x) & LSR_FE_MASK) >> LSR_FE_LSB)
-#define LSR_FE_SET(x)                            (((x) << LSR_FE_LSB) & LSR_FE_MASK)
-#define LSR_PE_MSB                               2
-#define LSR_PE_LSB                               2
-#define LSR_PE_MASK                              0x00000004
-#define LSR_PE_GET(x)                            (((x) & LSR_PE_MASK) >> LSR_PE_LSB)
-#define LSR_PE_SET(x)                            (((x) << LSR_PE_LSB) & LSR_PE_MASK)
-#define LSR_OE_MSB                               1
-#define LSR_OE_LSB                               1
-#define LSR_OE_MASK                              0x00000002
-#define LSR_OE_GET(x)                            (((x) & LSR_OE_MASK) >> LSR_OE_LSB)
-#define LSR_OE_SET(x)                            (((x) << LSR_OE_LSB) & LSR_OE_MASK)
-#define LSR_DR_MSB                               0
-#define LSR_DR_LSB                               0
-#define LSR_DR_MASK                              0x00000001
-#define LSR_DR_GET(x)                            (((x) & LSR_DR_MASK) >> LSR_DR_LSB)
-#define LSR_DR_SET(x)                            (((x) << LSR_DR_LSB) & LSR_DR_MASK)
-
-#define MSR_ADDRESS                              0x00000018
-#define MSR_OFFSET                               0x00000018
-#define MSR_DCD_MSB                              7
-#define MSR_DCD_LSB                              7
-#define MSR_DCD_MASK                             0x00000080
-#define MSR_DCD_GET(x)                           (((x) & MSR_DCD_MASK) >> MSR_DCD_LSB)
-#define MSR_DCD_SET(x)                           (((x) << MSR_DCD_LSB) & MSR_DCD_MASK)
-#define MSR_RI_MSB                               6
-#define MSR_RI_LSB                               6
-#define MSR_RI_MASK                              0x00000040
-#define MSR_RI_GET(x)                            (((x) & MSR_RI_MASK) >> MSR_RI_LSB)
-#define MSR_RI_SET(x)                            (((x) << MSR_RI_LSB) & MSR_RI_MASK)
-#define MSR_DSR_MSB                              5
-#define MSR_DSR_LSB                              5
-#define MSR_DSR_MASK                             0x00000020
-#define MSR_DSR_GET(x)                           (((x) & MSR_DSR_MASK) >> MSR_DSR_LSB)
-#define MSR_DSR_SET(x)                           (((x) << MSR_DSR_LSB) & MSR_DSR_MASK)
-#define MSR_CTS_MSB                              4
-#define MSR_CTS_LSB                              4
-#define MSR_CTS_MASK                             0x00000010
-#define MSR_CTS_GET(x)                           (((x) & MSR_CTS_MASK) >> MSR_CTS_LSB)
-#define MSR_CTS_SET(x)                           (((x) << MSR_CTS_LSB) & MSR_CTS_MASK)
-#define MSR_DDCD_MSB                             3
-#define MSR_DDCD_LSB                             3
-#define MSR_DDCD_MASK                            0x00000008
-#define MSR_DDCD_GET(x)                          (((x) & MSR_DDCD_MASK) >> MSR_DDCD_LSB)
-#define MSR_DDCD_SET(x)                          (((x) << MSR_DDCD_LSB) & MSR_DDCD_MASK)
-#define MSR_TERI_MSB                             2
-#define MSR_TERI_LSB                             2
-#define MSR_TERI_MASK                            0x00000004
-#define MSR_TERI_GET(x)                          (((x) & MSR_TERI_MASK) >> MSR_TERI_LSB)
-#define MSR_TERI_SET(x)                          (((x) << MSR_TERI_LSB) & MSR_TERI_MASK)
-#define MSR_DDSR_MSB                             1
-#define MSR_DDSR_LSB                             1
-#define MSR_DDSR_MASK                            0x00000002
-#define MSR_DDSR_GET(x)                          (((x) & MSR_DDSR_MASK) >> MSR_DDSR_LSB)
-#define MSR_DDSR_SET(x)                          (((x) << MSR_DDSR_LSB) & MSR_DDSR_MASK)
-#define MSR_DCTS_MSB                             0
-#define MSR_DCTS_LSB                             0
-#define MSR_DCTS_MASK                            0x00000001
-#define MSR_DCTS_GET(x)                          (((x) & MSR_DCTS_MASK) >> MSR_DCTS_LSB)
-#define MSR_DCTS_SET(x)                          (((x) << MSR_DCTS_LSB) & MSR_DCTS_MASK)
-
-#define SCR_ADDRESS                              0x0000001c
-#define SCR_OFFSET                               0x0000001c
-#define SCR_SCR_MSB                              7
-#define SCR_SCR_LSB                              0
-#define SCR_SCR_MASK                             0x000000ff
-#define SCR_SCR_GET(x)                           (((x) & SCR_SCR_MASK) >> SCR_SCR_LSB)
-#define SCR_SCR_SET(x)                           (((x) << SCR_SCR_LSB) & SCR_SCR_MASK)
-
-#define SRBR_ADDRESS                             0x00000020
-#define SRBR_OFFSET                              0x00000020
-#define SRBR_SRBR_MSB                            7
-#define SRBR_SRBR_LSB                            0
-#define SRBR_SRBR_MASK                           0x000000ff
-#define SRBR_SRBR_GET(x)                         (((x) & SRBR_SRBR_MASK) >> SRBR_SRBR_LSB)
-#define SRBR_SRBR_SET(x)                         (((x) << SRBR_SRBR_LSB) & SRBR_SRBR_MASK)
-
-#define SIIR_ADDRESS                             0x00000028
-#define SIIR_OFFSET                              0x00000028
-#define SIIR_SIIR_MSB                            7
-#define SIIR_SIIR_LSB                            0
-#define SIIR_SIIR_MASK                           0x000000ff
-#define SIIR_SIIR_GET(x)                         (((x) & SIIR_SIIR_MASK) >> SIIR_SIIR_LSB)
-#define SIIR_SIIR_SET(x)                         (((x) << SIIR_SIIR_LSB) & SIIR_SIIR_MASK)
-
-#define MWR_ADDRESS                              0x0000002c
-#define MWR_OFFSET                               0x0000002c
-#define MWR_MWR_MSB                              31
-#define MWR_MWR_LSB                              0
-#define MWR_MWR_MASK                             0xffffffff
-#define MWR_MWR_GET(x)                           (((x) & MWR_MWR_MASK) >> MWR_MWR_LSB)
-#define MWR_MWR_SET(x)                           (((x) << MWR_MWR_LSB) & MWR_MWR_MASK)
-
-#define SLSR_ADDRESS                             0x00000034
-#define SLSR_OFFSET                              0x00000034
-#define SLSR_SLSR_MSB                            7
-#define SLSR_SLSR_LSB                            0
-#define SLSR_SLSR_MASK                           0x000000ff
-#define SLSR_SLSR_GET(x)                         (((x) & SLSR_SLSR_MASK) >> SLSR_SLSR_LSB)
-#define SLSR_SLSR_SET(x)                         (((x) << SLSR_SLSR_LSB) & SLSR_SLSR_MASK)
-
-#define SMSR_ADDRESS                             0x00000038
-#define SMSR_OFFSET                              0x00000038
-#define SMSR_SMSR_MSB                            7
-#define SMSR_SMSR_LSB                            0
-#define SMSR_SMSR_MASK                           0x000000ff
-#define SMSR_SMSR_GET(x)                         (((x) & SMSR_SMSR_MASK) >> SMSR_SMSR_LSB)
-#define SMSR_SMSR_SET(x)                         (((x) << SMSR_SMSR_LSB) & SMSR_SMSR_MASK)
-
-#define MRR_ADDRESS                              0x0000003c
-#define MRR_OFFSET                               0x0000003c
-#define MRR_MRR_MSB                              31
-#define MRR_MRR_LSB                              0
-#define MRR_MRR_MASK                             0xffffffff
-#define MRR_MRR_GET(x)                           (((x) & MRR_MRR_MASK) >> MRR_MRR_LSB)
-#define MRR_MRR_SET(x)                           (((x) << MRR_MRR_LSB) & MRR_MRR_MASK)
-
-
-#ifndef __ASSEMBLER__
-
-typedef struct uart_reg_reg_s {
-  volatile unsigned int rbr;
-  volatile unsigned int dlh;
-  volatile unsigned int iir;
-  volatile unsigned int lcr;
-  volatile unsigned int mcr;
-  volatile unsigned int lsr;
-  volatile unsigned int msr;
-  volatile unsigned int scr;
-  volatile unsigned int srbr;
-  unsigned char pad0[4]; /* pad to 0x28 */
-  volatile unsigned int siir;
-  volatile unsigned int mwr;
-  unsigned char pad1[4]; /* pad to 0x34 */
-  volatile unsigned int slsr;
-  volatile unsigned int smsr;
-  volatile unsigned int mrr;
-} uart_reg_reg_t;
-
-#endif /* __ASSEMBLER__ */
-
-#endif /* _UART_REG_H_ */
diff -druN linux-2.6.39-libre/drivers/staging/ath6kl/include/common/AR6002/hw2.0/hw/vmc_reg.h linux-3.0-rc7-libre/drivers/staging/ath6kl/include/common/AR6002/hw2.0/hw/vmc_reg.h
--- linux-2.6.39-libre/drivers/staging/ath6kl/include/common/AR6002/hw2.0/hw/vmc_reg.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/ath6kl/include/common/AR6002/hw2.0/hw/vmc_reg.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,76 +0,0 @@
-#ifndef _VMC_REG_REG_H_
-#define _VMC_REG_REG_H_
-
-#define MC_TCAM_VALID_ADDRESS                    0x00000000
-#define MC_TCAM_VALID_OFFSET                     0x00000000
-#define MC_TCAM_VALID_BIT_MSB                    0
-#define MC_TCAM_VALID_BIT_LSB                    0
-#define MC_TCAM_VALID_BIT_MASK                   0x00000001
-#define MC_TCAM_VALID_BIT_GET(x)                 (((x) & MC_TCAM_VALID_BIT_MASK) >> MC_TCAM_VALID_BIT_LSB)
-#define MC_TCAM_VALID_BIT_SET(x)                 (((x) << MC_TCAM_VALID_BIT_LSB) & MC_TCAM_VALID_BIT_MASK)
-
-#define MC_TCAM_MASK_ADDRESS                     0x00000080
-#define MC_TCAM_MASK_OFFSET                      0x00000080
-#define MC_TCAM_MASK_SIZE_MSB                    2
-#define MC_TCAM_MASK_SIZE_LSB                    0
-#define MC_TCAM_MASK_SIZE_MASK                   0x00000007
-#define MC_TCAM_MASK_SIZE_GET(x)                 (((x) & MC_TCAM_MASK_SIZE_MASK) >> MC_TCAM_MASK_SIZE_LSB)
-#define MC_TCAM_MASK_SIZE_SET(x)                 (((x) << MC_TCAM_MASK_SIZE_LSB) & MC_TCAM_MASK_SIZE_MASK)
-
-#define MC_TCAM_COMPARE_ADDRESS                  0x00000100
-#define MC_TCAM_COMPARE_OFFSET                   0x00000100
-#define MC_TCAM_COMPARE_KEY_MSB                  21
-#define MC_TCAM_COMPARE_KEY_LSB                  5
-#define MC_TCAM_COMPARE_KEY_MASK                 0x003fffe0
-#define MC_TCAM_COMPARE_KEY_GET(x)               (((x) & MC_TCAM_COMPARE_KEY_MASK) >> MC_TCAM_COMPARE_KEY_LSB)
-#define MC_TCAM_COMPARE_KEY_SET(x)               (((x) << MC_TCAM_COMPARE_KEY_LSB) & MC_TCAM_COMPARE_KEY_MASK)
-
-#define MC_TCAM_TARGET_ADDRESS                   0x00000180
-#define MC_TCAM_TARGET_OFFSET                    0x00000180
-#define MC_TCAM_TARGET_ADDR_MSB                  21
-#define MC_TCAM_TARGET_ADDR_LSB                  5
-#define MC_TCAM_TARGET_ADDR_MASK                 0x003fffe0
-#define MC_TCAM_TARGET_ADDR_GET(x)               (((x) & MC_TCAM_TARGET_ADDR_MASK) >> MC_TCAM_TARGET_ADDR_LSB)
-#define MC_TCAM_TARGET_ADDR_SET(x)               (((x) << MC_TCAM_TARGET_ADDR_LSB) & MC_TCAM_TARGET_ADDR_MASK)
-
-#define ADDR_ERROR_CONTROL_ADDRESS               0x00000200
-#define ADDR_ERROR_CONTROL_OFFSET                0x00000200
-#define ADDR_ERROR_CONTROL_QUAL_ENABLE_MSB       1
-#define ADDR_ERROR_CONTROL_QUAL_ENABLE_LSB       1
-#define ADDR_ERROR_CONTROL_QUAL_ENABLE_MASK      0x00000002
-#define ADDR_ERROR_CONTROL_QUAL_ENABLE_GET(x)    (((x) & ADDR_ERROR_CONTROL_QUAL_ENABLE_MASK) >> ADDR_ERROR_CONTROL_QUAL_ENABLE_LSB)
-#define ADDR_ERROR_CONTROL_QUAL_ENABLE_SET(x)    (((x) << ADDR_ERROR_CONTROL_QUAL_ENABLE_LSB) & ADDR_ERROR_CONTROL_QUAL_ENABLE_MASK)
-#define ADDR_ERROR_CONTROL_ENABLE_MSB            0
-#define ADDR_ERROR_CONTROL_ENABLE_LSB            0
-#define ADDR_ERROR_CONTROL_ENABLE_MASK           0x00000001
-#define ADDR_ERROR_CONTROL_ENABLE_GET(x)         (((x) & ADDR_ERROR_CONTROL_ENABLE_MASK) >> ADDR_ERROR_CONTROL_ENABLE_LSB)
-#define ADDR_ERROR_CONTROL_ENABLE_SET(x)         (((x) << ADDR_ERROR_CONTROL_ENABLE_LSB) & ADDR_ERROR_CONTROL_ENABLE_MASK)
-
-#define ADDR_ERROR_STATUS_ADDRESS                0x00000204
-#define ADDR_ERROR_STATUS_OFFSET                 0x00000204
-#define ADDR_ERROR_STATUS_WRITE_MSB              25
-#define ADDR_ERROR_STATUS_WRITE_LSB              25
-#define ADDR_ERROR_STATUS_WRITE_MASK             0x02000000
-#define ADDR_ERROR_STATUS_WRITE_GET(x)           (((x) & ADDR_ERROR_STATUS_WRITE_MASK) >> ADDR_ERROR_STATUS_WRITE_LSB)
-#define ADDR_ERROR_STATUS_WRITE_SET(x)           (((x) << ADDR_ERROR_STATUS_WRITE_LSB) & ADDR_ERROR_STATUS_WRITE_MASK)
-#define ADDR_ERROR_STATUS_ADDRESS_MSB            24
-#define ADDR_ERROR_STATUS_ADDRESS_LSB            0
-#define ADDR_ERROR_STATUS_ADDRESS_MASK           0x01ffffff
-#define ADDR_ERROR_STATUS_ADDRESS_GET(x)         (((x) & ADDR_ERROR_STATUS_ADDRESS_MASK) >> ADDR_ERROR_STATUS_ADDRESS_LSB)
-#define ADDR_ERROR_STATUS_ADDRESS_SET(x)         (((x) << ADDR_ERROR_STATUS_ADDRESS_LSB) & ADDR_ERROR_STATUS_ADDRESS_MASK)
-
-
-#ifndef __ASSEMBLER__
-
-typedef struct vmc_reg_reg_s {
-  volatile unsigned int mc_tcam_valid[32];
-  volatile unsigned int mc_tcam_mask[32];
-  volatile unsigned int mc_tcam_compare[32];
-  volatile unsigned int mc_tcam_target[32];
-  volatile unsigned int addr_error_control;
-  volatile unsigned int addr_error_status;
-} vmc_reg_reg_t;
-
-#endif /* __ASSEMBLER__ */
-
-#endif /* _VMC_REG_H_ */
diff -druN linux-2.6.39-libre/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/analog_intf_ares_reg.h linux-3.0-rc7-libre/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/analog_intf_ares_reg.h
--- linux-2.6.39-libre/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/analog_intf_ares_reg.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/analog_intf_ares_reg.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,3291 +0,0 @@
-// ------------------------------------------------------------------
-// Copyright (c) 2004-2010 Atheros Corporation.  All rights reserved.
-// 
-//
-// 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.
-//
-//
-// ------------------------------------------------------------------
-//===================================================================
-// Author(s): ="Atheros"
-//===================================================================
-
-/* Copyright (C) 2009 Denali Software Inc.  All rights reserved              */
-/* THIS FILE IS AUTOMATICALLY GENERATED BY DENALI BLUEPRINT, DO NOT EDIT     */
-
-
-#ifndef _ANALOG_INTF_ARES_REG_REG_H_
-#define _ANALOG_INTF_ARES_REG_REG_H_
-
-
-/* macros for RXRF_BIAS1 */
-#define PHY_ANALOG_RXRF_BIAS1_ADDRESS                                                                0x00000000
-#define PHY_ANALOG_RXRF_BIAS1_OFFSET                                                                 0x00000000
-#define PHY_ANALOG_RXRF_BIAS1_SPARE_MSB                                                                       0
-#define PHY_ANALOG_RXRF_BIAS1_SPARE_LSB                                                                       0
-#define PHY_ANALOG_RXRF_BIAS1_SPARE_MASK                                                             0x00000001
-#define PHY_ANALOG_RXRF_BIAS1_SPARE_GET(x)                                            (((x) & 0x00000001) >> 0)
-#define PHY_ANALOG_RXRF_BIAS1_SPARE_SET(x)                                            (((x) << 0) & 0x00000001)
-#define PHY_ANALOG_RXRF_BIAS1_PWD_IR25SPARE_MSB                                                               3
-#define PHY_ANALOG_RXRF_BIAS1_PWD_IR25SPARE_LSB                                                               1
-#define PHY_ANALOG_RXRF_BIAS1_PWD_IR25SPARE_MASK                                                     0x0000000e
-#define PHY_ANALOG_RXRF_BIAS1_PWD_IR25SPARE_GET(x)                                    (((x) & 0x0000000e) >> 1)
-#define PHY_ANALOG_RXRF_BIAS1_PWD_IR25SPARE_SET(x)                                    (((x) << 1) & 0x0000000e)
-#define PHY_ANALOG_RXRF_BIAS1_PWD_IR25LO18_MSB                                                                6
-#define PHY_ANALOG_RXRF_BIAS1_PWD_IR25LO18_LSB                                                                4
-#define PHY_ANALOG_RXRF_BIAS1_PWD_IR25LO18_MASK                                                      0x00000070
-#define PHY_ANALOG_RXRF_BIAS1_PWD_IR25LO18_GET(x)                                     (((x) & 0x00000070) >> 4)
-#define PHY_ANALOG_RXRF_BIAS1_PWD_IR25LO18_SET(x)                                     (((x) << 4) & 0x00000070)
-#define PHY_ANALOG_RXRF_BIAS1_PWD_IC25LO36_MSB                                                                9
-#define PHY_ANALOG_RXRF_BIAS1_PWD_IC25LO36_LSB                                                                7
-#define PHY_ANALOG_RXRF_BIAS1_PWD_IC25LO36_MASK                                                      0x00000380
-#define PHY_ANALOG_RXRF_BIAS1_PWD_IC25LO36_GET(x)                                     (((x) & 0x00000380) >> 7)
-#define PHY_ANALOG_RXRF_BIAS1_PWD_IC25LO36_SET(x)                                     (((x) << 7) & 0x00000380)
-#define PHY_ANALOG_RXRF_BIAS1_PWD_IC25MXR2_5GH_MSB                                                           12
-#define PHY_ANALOG_RXRF_BIAS1_PWD_IC25MXR2_5GH_LSB                                                           10
-#define PHY_ANALOG_RXRF_BIAS1_PWD_IC25MXR2_5GH_MASK                                                  0x00001c00
-#define PHY_ANALOG_RXRF_BIAS1_PWD_IC25MXR2_5GH_GET(x)                                (((x) & 0x00001c00) >> 10)
-#define PHY_ANALOG_RXRF_BIAS1_PWD_IC25MXR2_5GH_SET(x)                                (((x) << 10) & 0x00001c00)
-#define PHY_ANALOG_RXRF_BIAS1_PWD_IC25MXR5GH_MSB                                                             15
-#define PHY_ANALOG_RXRF_BIAS1_PWD_IC25MXR5GH_LSB                                                             13
-#define PHY_ANALOG_RXRF_BIAS1_PWD_IC25MXR5GH_MASK                                                    0x0000e000
-#define PHY_ANALOG_RXRF_BIAS1_PWD_IC25MXR5GH_GET(x)                                  (((x) & 0x0000e000) >> 13)
-#define PHY_ANALOG_RXRF_BIAS1_PWD_IC25MXR5GH_SET(x)                                  (((x) << 13) & 0x0000e000)
-#define PHY_ANALOG_RXRF_BIAS1_PWD_IC25VGA5G_MSB                                                              18
-#define PHY_ANALOG_RXRF_BIAS1_PWD_IC25VGA5G_LSB                                                              16
-#define PHY_ANALOG_RXRF_BIAS1_PWD_IC25VGA5G_MASK                                                     0x00070000
-#define PHY_ANALOG_RXRF_BIAS1_PWD_IC25VGA5G_GET(x)                                   (((x) & 0x00070000) >> 16)
-#define PHY_ANALOG_RXRF_BIAS1_PWD_IC25VGA5G_SET(x)                                   (((x) << 16) & 0x00070000)
-#define PHY_ANALOG_RXRF_BIAS1_PWD_IC75LNA5G_MSB                                                              21
-#define PHY_ANALOG_RXRF_BIAS1_PWD_IC75LNA5G_LSB                                                              19
-#define PHY_ANALOG_RXRF_BIAS1_PWD_IC75LNA5G_MASK                                                     0x00380000
-#define PHY_ANALOG_RXRF_BIAS1_PWD_IC75LNA5G_GET(x)                                   (((x) & 0x00380000) >> 19)
-#define PHY_ANALOG_RXRF_BIAS1_PWD_IC75LNA5G_SET(x)                                   (((x) << 19) & 0x00380000)
-#define PHY_ANALOG_RXRF_BIAS1_PWD_IR25LO24_MSB                                                               24
-#define PHY_ANALOG_RXRF_BIAS1_PWD_IR25LO24_LSB                                                               22
-#define PHY_ANALOG_RXRF_BIAS1_PWD_IR25LO24_MASK                                                      0x01c00000
-#define PHY_ANALOG_RXRF_BIAS1_PWD_IR25LO24_GET(x)                                    (((x) & 0x01c00000) >> 22)
-#define PHY_ANALOG_RXRF_BIAS1_PWD_IR25LO24_SET(x)                                    (((x) << 22) & 0x01c00000)
-#define PHY_ANALOG_RXRF_BIAS1_PWD_IC25MXR2GH_MSB                                                             27
-#define PHY_ANALOG_RXRF_BIAS1_PWD_IC25MXR2GH_LSB                                                             25
-#define PHY_ANALOG_RXRF_BIAS1_PWD_IC25MXR2GH_MASK                                                    0x0e000000
-#define PHY_ANALOG_RXRF_BIAS1_PWD_IC25MXR2GH_GET(x)                                  (((x) & 0x0e000000) >> 25)
-#define PHY_ANALOG_RXRF_BIAS1_PWD_IC25MXR2GH_SET(x)                                  (((x) << 25) & 0x0e000000)
-#define PHY_ANALOG_RXRF_BIAS1_PWD_IC75LNA2G_MSB                                                              30
-#define PHY_ANALOG_RXRF_BIAS1_PWD_IC75LNA2G_LSB                                                              28
-#define PHY_ANALOG_RXRF_BIAS1_PWD_IC75LNA2G_MASK                                                     0x70000000
-#define PHY_ANALOG_RXRF_BIAS1_PWD_IC75LNA2G_GET(x)                                   (((x) & 0x70000000) >> 28)
-#define PHY_ANALOG_RXRF_BIAS1_PWD_IC75LNA2G_SET(x)                                   (((x) << 28) & 0x70000000)
-#define PHY_ANALOG_RXRF_BIAS1_PWD_BIAS_MSB                                                                   31
-#define PHY_ANALOG_RXRF_BIAS1_PWD_BIAS_LSB                                                                   31
-#define PHY_ANALOG_RXRF_BIAS1_PWD_BIAS_MASK                                                          0x80000000
-#define PHY_ANALOG_RXRF_BIAS1_PWD_BIAS_GET(x)                                        (((x) & 0x80000000) >> 31)
-#define PHY_ANALOG_RXRF_BIAS1_PWD_BIAS_SET(x)                                        (((x) << 31) & 0x80000000)
-
-/* macros for RXRF_BIAS2 */
-#define PHY_ANALOG_RXRF_BIAS2_ADDRESS                                                                0x00000004
-#define PHY_ANALOG_RXRF_BIAS2_OFFSET                                                                 0x00000004
-#define PHY_ANALOG_RXRF_BIAS2_SPARE_MSB                                                                       0
-#define PHY_ANALOG_RXRF_BIAS2_SPARE_LSB                                                                       0
-#define PHY_ANALOG_RXRF_BIAS2_SPARE_MASK                                                             0x00000001
-#define PHY_ANALOG_RXRF_BIAS2_SPARE_GET(x)                                            (((x) & 0x00000001) >> 0)
-#define PHY_ANALOG_RXRF_BIAS2_SPARE_SET(x)                                            (((x) << 0) & 0x00000001)
-#define PHY_ANALOG_RXRF_BIAS2_PKEN_MSB                                                                        3
-#define PHY_ANALOG_RXRF_BIAS2_PKEN_LSB                                                                        1
-#define PHY_ANALOG_RXRF_BIAS2_PKEN_MASK                                                              0x0000000e
-#define PHY_ANALOG_RXRF_BIAS2_PKEN_GET(x)                                             (((x) & 0x0000000e) >> 1)
-#define PHY_ANALOG_RXRF_BIAS2_PKEN_SET(x)                                             (((x) << 1) & 0x0000000e)
-#define PHY_ANALOG_RXRF_BIAS2_VCMVALUE_MSB                                                                    6
-#define PHY_ANALOG_RXRF_BIAS2_VCMVALUE_LSB                                                                    4
-#define PHY_ANALOG_RXRF_BIAS2_VCMVALUE_MASK                                                          0x00000070
-#define PHY_ANALOG_RXRF_BIAS2_VCMVALUE_GET(x)                                         (((x) & 0x00000070) >> 4)
-#define PHY_ANALOG_RXRF_BIAS2_VCMVALUE_SET(x)                                         (((x) << 4) & 0x00000070)
-#define PHY_ANALOG_RXRF_BIAS2_PWD_VCMBUF_MSB                                                                  7
-#define PHY_ANALOG_RXRF_BIAS2_PWD_VCMBUF_LSB                                                                  7
-#define PHY_ANALOG_RXRF_BIAS2_PWD_VCMBUF_MASK                                                        0x00000080
-#define PHY_ANALOG_RXRF_BIAS2_PWD_VCMBUF_GET(x)                                       (((x) & 0x00000080) >> 7)
-#define PHY_ANALOG_RXRF_BIAS2_PWD_VCMBUF_SET(x)                                       (((x) << 7) & 0x00000080)
-#define PHY_ANALOG_RXRF_BIAS2_PWD_IR25AGC5GH_MSB                                                             10
-#define PHY_ANALOG_RXRF_BIAS2_PWD_IR25AGC5GH_LSB                                                              8
-#define PHY_ANALOG_RXRF_BIAS2_PWD_IR25AGC5GH_MASK                                                    0x00000700
-#define PHY_ANALOG_RXRF_BIAS2_PWD_IR25AGC5GH_GET(x)                                   (((x) & 0x00000700) >> 8)
-#define PHY_ANALOG_RXRF_BIAS2_PWD_IR25AGC5GH_SET(x)                                   (((x) << 8) & 0x00000700)
-#define PHY_ANALOG_RXRF_BIAS2_PWD_IR25AGC5G_MSB                                                              13
-#define PHY_ANALOG_RXRF_BIAS2_PWD_IR25AGC5G_LSB                                                              11
-#define PHY_ANALOG_RXRF_BIAS2_PWD_IR25AGC5G_MASK                                                     0x00003800
-#define PHY_ANALOG_RXRF_BIAS2_PWD_IR25AGC5G_GET(x)                                   (((x) & 0x00003800) >> 11)
-#define PHY_ANALOG_RXRF_BIAS2_PWD_IR25AGC5G_SET(x)                                   (((x) << 11) & 0x00003800)
-#define PHY_ANALOG_RXRF_BIAS2_PWD_IC25AGC5G_MSB                                                              16
-#define PHY_ANALOG_RXRF_BIAS2_PWD_IC25AGC5G_LSB                                                              14
-#define PHY_ANALOG_RXRF_BIAS2_PWD_IC25AGC5G_MASK                                                     0x0001c000
-#define PHY_ANALOG_RXRF_BIAS2_PWD_IC25AGC5G_GET(x)                                   (((x) & 0x0001c000) >> 14)
-#define PHY_ANALOG_RXRF_BIAS2_PWD_IC25AGC5G_SET(x)                                   (((x) << 14) & 0x0001c000)
-#define PHY_ANALOG_RXRF_BIAS2_PWD_IR25AGC2GH_MSB                                                             19
-#define PHY_ANALOG_RXRF_BIAS2_PWD_IR25AGC2GH_LSB                                                             17
-#define PHY_ANALOG_RXRF_BIAS2_PWD_IR25AGC2GH_MASK                                                    0x000e0000
-#define PHY_ANALOG_RXRF_BIAS2_PWD_IR25AGC2GH_GET(x)                                  (((x) & 0x000e0000) >> 17)
-#define PHY_ANALOG_RXRF_BIAS2_PWD_IR25AGC2GH_SET(x)                                  (((x) << 17) & 0x000e0000)
-#define PHY_ANALOG_RXRF_BIAS2_PWD_IR25AGC2G_MSB                                                              22
-#define PHY_ANALOG_RXRF_BIAS2_PWD_IR25AGC2G_LSB                                                              20
-#define PHY_ANALOG_RXRF_BIAS2_PWD_IR25AGC2G_MASK                                                     0x00700000
-#define PHY_ANALOG_RXRF_BIAS2_PWD_IR25AGC2G_GET(x)                                   (((x) & 0x00700000) >> 20)
-#define PHY_ANALOG_RXRF_BIAS2_PWD_IR25AGC2G_SET(x)                                   (((x) << 20) & 0x00700000)
-#define PHY_ANALOG_RXRF_BIAS2_PWD_IC25AGC2G_MSB                                                              25
-#define PHY_ANALOG_RXRF_BIAS2_PWD_IC25AGC2G_LSB                                                              23
-#define PHY_ANALOG_RXRF_BIAS2_PWD_IC25AGC2G_MASK                                                     0x03800000
-#define PHY_ANALOG_RXRF_BIAS2_PWD_IC25AGC2G_GET(x)                                   (((x) & 0x03800000) >> 23)
-#define PHY_ANALOG_RXRF_BIAS2_PWD_IC25AGC2G_SET(x)                                   (((x) << 23) & 0x03800000)
-#define PHY_ANALOG_RXRF_BIAS2_PWD_IC25VCMBUF_MSB                                                             28
-#define PHY_ANALOG_RXRF_BIAS2_PWD_IC25VCMBUF_LSB                                                             26
-#define PHY_ANALOG_RXRF_BIAS2_PWD_IC25VCMBUF_MASK                                                    0x1c000000
-#define PHY_ANALOG_RXRF_BIAS2_PWD_IC25VCMBUF_GET(x)                                  (((x) & 0x1c000000) >> 26)
-#define PHY_ANALOG_RXRF_BIAS2_PWD_IC25VCMBUF_SET(x)                                  (((x) << 26) & 0x1c000000)
-#define PHY_ANALOG_RXRF_BIAS2_PWD_IR25VCM_MSB                                                                31
-#define PHY_ANALOG_RXRF_BIAS2_PWD_IR25VCM_LSB                                                                29
-#define PHY_ANALOG_RXRF_BIAS2_PWD_IR25VCM_MASK                                                       0xe0000000
-#define PHY_ANALOG_RXRF_BIAS2_PWD_IR25VCM_GET(x)                                     (((x) & 0xe0000000) >> 29)
-#define PHY_ANALOG_RXRF_BIAS2_PWD_IR25VCM_SET(x)                                     (((x) << 29) & 0xe0000000)
-
-/* macros for RXRF_GAINSTAGES */
-#define PHY_ANALOG_RXRF_GAINSTAGES_ADDRESS                                                           0x00000008
-#define PHY_ANALOG_RXRF_GAINSTAGES_OFFSET                                                            0x00000008
-#define PHY_ANALOG_RXRF_GAINSTAGES_SPARE_MSB                                                                  0
-#define PHY_ANALOG_RXRF_GAINSTAGES_SPARE_LSB                                                                  0
-#define PHY_ANALOG_RXRF_GAINSTAGES_SPARE_MASK                                                        0x00000001
-#define PHY_ANALOG_RXRF_GAINSTAGES_SPARE_GET(x)                                       (((x) & 0x00000001) >> 0)
-#define PHY_ANALOG_RXRF_GAINSTAGES_SPARE_SET(x)                                       (((x) << 0) & 0x00000001)
-#define PHY_ANALOG_RXRF_GAINSTAGES_LNAON_CALDC_MSB                                                            1
-#define PHY_ANALOG_RXRF_GAINSTAGES_LNAON_CALDC_LSB                                                            1
-#define PHY_ANALOG_RXRF_GAINSTAGES_LNAON_CALDC_MASK                                                  0x00000002
-#define PHY_ANALOG_RXRF_GAINSTAGES_LNAON_CALDC_GET(x)                                 (((x) & 0x00000002) >> 1)
-#define PHY_ANALOG_RXRF_GAINSTAGES_LNAON_CALDC_SET(x)                                 (((x) << 1) & 0x00000002)
-#define PHY_ANALOG_RXRF_GAINSTAGES_VGA5G_CAP_MSB                                                              3
-#define PHY_ANALOG_RXRF_GAINSTAGES_VGA5G_CAP_LSB                                                              2
-#define PHY_ANALOG_RXRF_GAINSTAGES_VGA5G_CAP_MASK                                                    0x0000000c
-#define PHY_ANALOG_RXRF_GAINSTAGES_VGA5G_CAP_GET(x)                                   (((x) & 0x0000000c) >> 2)
-#define PHY_ANALOG_RXRF_GAINSTAGES_VGA5G_CAP_SET(x)                                   (((x) << 2) & 0x0000000c)
-#define PHY_ANALOG_RXRF_GAINSTAGES_LNA5G_CAP_MSB                                                              5
-#define PHY_ANALOG_RXRF_GAINSTAGES_LNA5G_CAP_LSB                                                              4
-#define PHY_ANALOG_RXRF_GAINSTAGES_LNA5G_CAP_MASK                                                    0x00000030
-#define PHY_ANALOG_RXRF_GAINSTAGES_LNA5G_CAP_GET(x)                                   (((x) & 0x00000030) >> 4)
-#define PHY_ANALOG_RXRF_GAINSTAGES_LNA5G_CAP_SET(x)                                   (((x) << 4) & 0x00000030)
-#define PHY_ANALOG_RXRF_GAINSTAGES_LNA5G_SHORTINP_MSB                                                         6
-#define PHY_ANALOG_RXRF_GAINSTAGES_LNA5G_SHORTINP_LSB                                                         6
-#define PHY_ANALOG_RXRF_GAINSTAGES_LNA5G_SHORTINP_MASK                                               0x00000040
-#define PHY_ANALOG_RXRF_GAINSTAGES_LNA5G_SHORTINP_GET(x)                              (((x) & 0x00000040) >> 6)
-#define PHY_ANALOG_RXRF_GAINSTAGES_LNA5G_SHORTINP_SET(x)                              (((x) << 6) & 0x00000040)
-#define PHY_ANALOG_RXRF_GAINSTAGES_PWD_LO5G_MSB                                                               7
-#define PHY_ANALOG_RXRF_GAINSTAGES_PWD_LO5G_LSB                                                               7
-#define PHY_ANALOG_RXRF_GAINSTAGES_PWD_LO5G_MASK                                                     0x00000080
-#define PHY_ANALOG_RXRF_GAINSTAGES_PWD_LO5G_GET(x)                                    (((x) & 0x00000080) >> 7)
-#define PHY_ANALOG_RXRF_GAINSTAGES_PWD_LO5G_SET(x)                                    (((x) << 7) & 0x00000080)
-#define PHY_ANALOG_RXRF_GAINSTAGES_PWD_VGA5G_MSB                                                              8
-#define PHY_ANALOG_RXRF_GAINSTAGES_PWD_VGA5G_LSB                                                              8
-#define PHY_ANALOG_RXRF_GAINSTAGES_PWD_VGA5G_MASK                                                    0x00000100
-#define PHY_ANALOG_RXRF_GAINSTAGES_PWD_VGA5G_GET(x)                                   (((x) & 0x00000100) >> 8)
-#define PHY_ANALOG_RXRF_GAINSTAGES_PWD_VGA5G_SET(x)                                   (((x) << 8) & 0x00000100)
-#define PHY_ANALOG_RXRF_GAINSTAGES_PWD_MXR5G_MSB                                                              9
-#define PHY_ANALOG_RXRF_GAINSTAGES_PWD_MXR5G_LSB                                                              9
-#define PHY_ANALOG_RXRF_GAINSTAGES_PWD_MXR5G_MASK                                                    0x00000200
-#define PHY_ANALOG_RXRF_GAINSTAGES_PWD_MXR5G_GET(x)                                   (((x) & 0x00000200) >> 9)
-#define PHY_ANALOG_RXRF_GAINSTAGES_PWD_MXR5G_SET(x)                                   (((x) << 9) & 0x00000200)
-#define PHY_ANALOG_RXRF_GAINSTAGES_PWD_LNA5G_MSB                                                             10
-#define PHY_ANALOG_RXRF_GAINSTAGES_PWD_LNA5G_LSB                                                             10
-#define PHY_ANALOG_RXRF_GAINSTAGES_PWD_LNA5G_MASK                                                    0x00000400
-#define PHY_ANALOG_RXRF_GAINSTAGES_PWD_LNA5G_GET(x)                                  (((x) & 0x00000400) >> 10)
-#define PHY_ANALOG_RXRF_GAINSTAGES_PWD_LNA5G_SET(x)                                  (((x) << 10) & 0x00000400)
-#define PHY_ANALOG_RXRF_GAINSTAGES_LNA2G_CAP_MSB                                                             12
-#define PHY_ANALOG_RXRF_GAINSTAGES_LNA2G_CAP_LSB                                                             11
-#define PHY_ANALOG_RXRF_GAINSTAGES_LNA2G_CAP_MASK                                                    0x00001800
-#define PHY_ANALOG_RXRF_GAINSTAGES_LNA2G_CAP_GET(x)                                  (((x) & 0x00001800) >> 11)
-#define PHY_ANALOG_RXRF_GAINSTAGES_LNA2G_CAP_SET(x)                                  (((x) << 11) & 0x00001800)
-#define PHY_ANALOG_RXRF_GAINSTAGES_LNA2G_SHORTINP_MSB                                                        13
-#define PHY_ANALOG_RXRF_GAINSTAGES_LNA2G_SHORTINP_LSB                                                        13
-#define PHY_ANALOG_RXRF_GAINSTAGES_LNA2G_SHORTINP_MASK                                               0x00002000
-#define PHY_ANALOG_RXRF_GAINSTAGES_LNA2G_SHORTINP_GET(x)                             (((x) & 0x00002000) >> 13)
-#define PHY_ANALOG_RXRF_GAINSTAGES_LNA2G_SHORTINP_SET(x)                             (((x) << 13) & 0x00002000)
-#define PHY_ANALOG_RXRF_GAINSTAGES_LNA2G_LP_MSB                                                              14
-#define PHY_ANALOG_RXRF_GAINSTAGES_LNA2G_LP_LSB                                                              14
-#define PHY_ANALOG_RXRF_GAINSTAGES_LNA2G_LP_MASK                                                     0x00004000
-#define PHY_ANALOG_RXRF_GAINSTAGES_LNA2G_LP_GET(x)                                   (((x) & 0x00004000) >> 14)
-#define PHY_ANALOG_RXRF_GAINSTAGES_LNA2G_LP_SET(x)                                   (((x) << 14) & 0x00004000)
-#define PHY_ANALOG_RXRF_GAINSTAGES_PWD_LO2G_MSB                                                              15
-#define PHY_ANALOG_RXRF_GAINSTAGES_PWD_LO2G_LSB                                                              15
-#define PHY_ANALOG_RXRF_GAINSTAGES_PWD_LO2G_MASK                                                     0x00008000
-#define PHY_ANALOG_RXRF_GAINSTAGES_PWD_LO2G_GET(x)                                   (((x) & 0x00008000) >> 15)
-#define PHY_ANALOG_RXRF_GAINSTAGES_PWD_LO2G_SET(x)                                   (((x) << 15) & 0x00008000)
-#define PHY_ANALOG_RXRF_GAINSTAGES_PWD_MXR2G_MSB                                                             16
-#define PHY_ANALOG_RXRF_GAINSTAGES_PWD_MXR2G_LSB                                                             16
-#define PHY_ANALOG_RXRF_GAINSTAGES_PWD_MXR2G_MASK                                                    0x00010000
-#define PHY_ANALOG_RXRF_GAINSTAGES_PWD_MXR2G_GET(x)                                  (((x) & 0x00010000) >> 16)
-#define PHY_ANALOG_RXRF_GAINSTAGES_PWD_MXR2G_SET(x)                                  (((x) << 16) & 0x00010000)
-#define PHY_ANALOG_RXRF_GAINSTAGES_PWD_LNA2G_MSB                                                             17
-#define PHY_ANALOG_RXRF_GAINSTAGES_PWD_LNA2G_LSB                                                             17
-#define PHY_ANALOG_RXRF_GAINSTAGES_PWD_LNA2G_MASK                                                    0x00020000
-#define PHY_ANALOG_RXRF_GAINSTAGES_PWD_LNA2G_GET(x)                                  (((x) & 0x00020000) >> 17)
-#define PHY_ANALOG_RXRF_GAINSTAGES_PWD_LNA2G_SET(x)                                  (((x) << 17) & 0x00020000)
-#define PHY_ANALOG_RXRF_GAINSTAGES_MXR5G_GAIN_OVR_MSB                                                        19
-#define PHY_ANALOG_RXRF_GAINSTAGES_MXR5G_GAIN_OVR_LSB                                                        18
-#define PHY_ANALOG_RXRF_GAINSTAGES_MXR5G_GAIN_OVR_MASK                                               0x000c0000
-#define PHY_ANALOG_RXRF_GAINSTAGES_MXR5G_GAIN_OVR_GET(x)                             (((x) & 0x000c0000) >> 18)
-#define PHY_ANALOG_RXRF_GAINSTAGES_MXR5G_GAIN_OVR_SET(x)                             (((x) << 18) & 0x000c0000)
-#define PHY_ANALOG_RXRF_GAINSTAGES_VGA5G_GAIN_OVR_MSB                                                        22
-#define PHY_ANALOG_RXRF_GAINSTAGES_VGA5G_GAIN_OVR_LSB                                                        20
-#define PHY_ANALOG_RXRF_GAINSTAGES_VGA5G_GAIN_OVR_MASK                                               0x00700000
-#define PHY_ANALOG_RXRF_GAINSTAGES_VGA5G_GAIN_OVR_GET(x)                             (((x) & 0x00700000) >> 20)
-#define PHY_ANALOG_RXRF_GAINSTAGES_VGA5G_GAIN_OVR_SET(x)                             (((x) << 20) & 0x00700000)
-#define PHY_ANALOG_RXRF_GAINSTAGES_LNA5G_GAIN_OVR_MSB                                                        25
-#define PHY_ANALOG_RXRF_GAINSTAGES_LNA5G_GAIN_OVR_LSB                                                        23
-#define PHY_ANALOG_RXRF_GAINSTAGES_LNA5G_GAIN_OVR_MASK                                               0x03800000
-#define PHY_ANALOG_RXRF_GAINSTAGES_LNA5G_GAIN_OVR_GET(x)                             (((x) & 0x03800000) >> 23)
-#define PHY_ANALOG_RXRF_GAINSTAGES_LNA5G_GAIN_OVR_SET(x)                             (((x) << 23) & 0x03800000)
-#define PHY_ANALOG_RXRF_GAINSTAGES_MXR2G_GAIN_OVR_MSB                                                        27
-#define PHY_ANALOG_RXRF_GAINSTAGES_MXR2G_GAIN_OVR_LSB                                                        26
-#define PHY_ANALOG_RXRF_GAINSTAGES_MXR2G_GAIN_OVR_MASK                                               0x0c000000
-#define PHY_ANALOG_RXRF_GAINSTAGES_MXR2G_GAIN_OVR_GET(x)                             (((x) & 0x0c000000) >> 26)
-#define PHY_ANALOG_RXRF_GAINSTAGES_MXR2G_GAIN_OVR_SET(x)                             (((x) << 26) & 0x0c000000)
-#define PHY_ANALOG_RXRF_GAINSTAGES_LNA2G_GAIN_OVR_MSB                                                        30
-#define PHY_ANALOG_RXRF_GAINSTAGES_LNA2G_GAIN_OVR_LSB                                                        28
-#define PHY_ANALOG_RXRF_GAINSTAGES_LNA2G_GAIN_OVR_MASK                                               0x70000000
-#define PHY_ANALOG_RXRF_GAINSTAGES_LNA2G_GAIN_OVR_GET(x)                             (((x) & 0x70000000) >> 28)
-#define PHY_ANALOG_RXRF_GAINSTAGES_LNA2G_GAIN_OVR_SET(x)                             (((x) << 28) & 0x70000000)
-#define PHY_ANALOG_RXRF_GAINSTAGES_RX_OVERRIDE_MSB                                                           31
-#define PHY_ANALOG_RXRF_GAINSTAGES_RX_OVERRIDE_LSB                                                           31
-#define PHY_ANALOG_RXRF_GAINSTAGES_RX_OVERRIDE_MASK                                                  0x80000000
-#define PHY_ANALOG_RXRF_GAINSTAGES_RX_OVERRIDE_GET(x)                                (((x) & 0x80000000) >> 31)
-#define PHY_ANALOG_RXRF_GAINSTAGES_RX_OVERRIDE_SET(x)                                (((x) << 31) & 0x80000000)
-
-/* macros for RXRF_AGC */
-#define PHY_ANALOG_RXRF_AGC_ADDRESS                                                                  0x0000000c
-#define PHY_ANALOG_RXRF_AGC_OFFSET                                                                   0x0000000c
-#define PHY_ANALOG_RXRF_AGC_SPARE_MSB                                                                         5
-#define PHY_ANALOG_RXRF_AGC_SPARE_LSB                                                                         0
-#define PHY_ANALOG_RXRF_AGC_SPARE_MASK                                                               0x0000003f
-#define PHY_ANALOG_RXRF_AGC_SPARE_GET(x)                                              (((x) & 0x0000003f) >> 0)
-#define PHY_ANALOG_RXRF_AGC_SPARE_SET(x)                                              (((x) << 0) & 0x0000003f)
-#define PHY_ANALOG_RXRF_AGC_AGC_FALL_CTRL_MSB                                                                 8
-#define PHY_ANALOG_RXRF_AGC_AGC_FALL_CTRL_LSB                                                                 6
-#define PHY_ANALOG_RXRF_AGC_AGC_FALL_CTRL_MASK                                                       0x000001c0
-#define PHY_ANALOG_RXRF_AGC_AGC_FALL_CTRL_GET(x)                                      (((x) & 0x000001c0) >> 6)
-#define PHY_ANALOG_RXRF_AGC_AGC_FALL_CTRL_SET(x)                                      (((x) << 6) & 0x000001c0)
-#define PHY_ANALOG_RXRF_AGC_AGC5G_CALDAC_OVR_MSB                                                             14
-#define PHY_ANALOG_RXRF_AGC_AGC5G_CALDAC_OVR_LSB                                                              9
-#define PHY_ANALOG_RXRF_AGC_AGC5G_CALDAC_OVR_MASK                                                    0x00007e00
-#define PHY_ANALOG_RXRF_AGC_AGC5G_CALDAC_OVR_GET(x)                                   (((x) & 0x00007e00) >> 9)
-#define PHY_ANALOG_RXRF_AGC_AGC5G_CALDAC_OVR_SET(x)                                   (((x) << 9) & 0x00007e00)
-#define PHY_ANALOG_RXRF_AGC_AGC5G_DBDAC_OVR_MSB                                                              18
-#define PHY_ANALOG_RXRF_AGC_AGC5G_DBDAC_OVR_LSB                                                              15
-#define PHY_ANALOG_RXRF_AGC_AGC5G_DBDAC_OVR_MASK                                                     0x00078000
-#define PHY_ANALOG_RXRF_AGC_AGC5G_DBDAC_OVR_GET(x)                                   (((x) & 0x00078000) >> 15)
-#define PHY_ANALOG_RXRF_AGC_AGC5G_DBDAC_OVR_SET(x)                                   (((x) << 15) & 0x00078000)
-#define PHY_ANALOG_RXRF_AGC_AGC2G_CALDAC_OVR_MSB                                                             24
-#define PHY_ANALOG_RXRF_AGC_AGC2G_CALDAC_OVR_LSB                                                             19
-#define PHY_ANALOG_RXRF_AGC_AGC2G_CALDAC_OVR_MASK                                                    0x01f80000
-#define PHY_ANALOG_RXRF_AGC_AGC2G_CALDAC_OVR_GET(x)                                  (((x) & 0x01f80000) >> 19)
-#define PHY_ANALOG_RXRF_AGC_AGC2G_CALDAC_OVR_SET(x)                                  (((x) << 19) & 0x01f80000)
-#define PHY_ANALOG_RXRF_AGC_AGC2G_DBDAC_OVR_MSB                                                              28
-#define PHY_ANALOG_RXRF_AGC_AGC2G_DBDAC_OVR_LSB                                                              25
-#define PHY_ANALOG_RXRF_AGC_AGC2G_DBDAC_OVR_MASK                                                     0x1e000000
-#define PHY_ANALOG_RXRF_AGC_AGC2G_DBDAC_OVR_GET(x)                                   (((x) & 0x1e000000) >> 25)
-#define PHY_ANALOG_RXRF_AGC_AGC2G_DBDAC_OVR_SET(x)                                   (((x) << 25) & 0x1e000000)
-#define PHY_ANALOG_RXRF_AGC_AGC_CAL_OVR_MSB                                                                  29
-#define PHY_ANALOG_RXRF_AGC_AGC_CAL_OVR_LSB                                                                  29
-#define PHY_ANALOG_RXRF_AGC_AGC_CAL_OVR_MASK                                                         0x20000000
-#define PHY_ANALOG_RXRF_AGC_AGC_CAL_OVR_GET(x)                                       (((x) & 0x20000000) >> 29)
-#define PHY_ANALOG_RXRF_AGC_AGC_CAL_OVR_SET(x)                                       (((x) << 29) & 0x20000000)
-#define PHY_ANALOG_RXRF_AGC_AGC_ON_OVR_MSB                                                                   30
-#define PHY_ANALOG_RXRF_AGC_AGC_ON_OVR_LSB                                                                   30
-#define PHY_ANALOG_RXRF_AGC_AGC_ON_OVR_MASK                                                          0x40000000
-#define PHY_ANALOG_RXRF_AGC_AGC_ON_OVR_GET(x)                                        (((x) & 0x40000000) >> 30)
-#define PHY_ANALOG_RXRF_AGC_AGC_ON_OVR_SET(x)                                        (((x) << 30) & 0x40000000)
-#define PHY_ANALOG_RXRF_AGC_AGC_OVERRIDE_MSB                                                                 31
-#define PHY_ANALOG_RXRF_AGC_AGC_OVERRIDE_LSB                                                                 31
-#define PHY_ANALOG_RXRF_AGC_AGC_OVERRIDE_MASK                                                        0x80000000
-#define PHY_ANALOG_RXRF_AGC_AGC_OVERRIDE_GET(x)                                      (((x) & 0x80000000) >> 31)
-#define PHY_ANALOG_RXRF_AGC_AGC_OVERRIDE_SET(x)                                      (((x) << 31) & 0x80000000)
-
-/* macros for TXRF1 */
-#define PHY_ANALOG_TXRF1_ADDRESS                                                                     0x00000040
-#define PHY_ANALOG_TXRF1_OFFSET                                                                      0x00000040
-#define PHY_ANALOG_TXRF1_DCAS2G_MSB                                                                           2
-#define PHY_ANALOG_TXRF1_DCAS2G_LSB                                                                           0
-#define PHY_ANALOG_TXRF1_DCAS2G_MASK                                                                 0x00000007
-#define PHY_ANALOG_TXRF1_DCAS2G_GET(x)                                                (((x) & 0x00000007) >> 0)
-#define PHY_ANALOG_TXRF1_DCAS2G_SET(x)                                                (((x) << 0) & 0x00000007)
-#define PHY_ANALOG_TXRF1_OB2G_PALOFF_MSB                                                                      5
-#define PHY_ANALOG_TXRF1_OB2G_PALOFF_LSB                                                                      3
-#define PHY_ANALOG_TXRF1_OB2G_PALOFF_MASK                                                            0x00000038
-#define PHY_ANALOG_TXRF1_OB2G_PALOFF_GET(x)                                           (((x) & 0x00000038) >> 3)
-#define PHY_ANALOG_TXRF1_OB2G_PALOFF_SET(x)                                           (((x) << 3) & 0x00000038)
-#define PHY_ANALOG_TXRF1_OB2G_QAM_MSB                                                                         8
-#define PHY_ANALOG_TXRF1_OB2G_QAM_LSB                                                                         6
-#define PHY_ANALOG_TXRF1_OB2G_QAM_MASK                                                               0x000001c0
-#define PHY_ANALOG_TXRF1_OB2G_QAM_GET(x)                                              (((x) & 0x000001c0) >> 6)
-#define PHY_ANALOG_TXRF1_OB2G_QAM_SET(x)                                              (((x) << 6) & 0x000001c0)
-#define PHY_ANALOG_TXRF1_OB2G_PSK_MSB                                                                        11
-#define PHY_ANALOG_TXRF1_OB2G_PSK_LSB                                                                         9
-#define PHY_ANALOG_TXRF1_OB2G_PSK_MASK                                                               0x00000e00
-#define PHY_ANALOG_TXRF1_OB2G_PSK_GET(x)                                              (((x) & 0x00000e00) >> 9)
-#define PHY_ANALOG_TXRF1_OB2G_PSK_SET(x)                                              (((x) << 9) & 0x00000e00)
-#define PHY_ANALOG_TXRF1_OB2G_CCK_MSB                                                                        14
-#define PHY_ANALOG_TXRF1_OB2G_CCK_LSB                                                                        12
-#define PHY_ANALOG_TXRF1_OB2G_CCK_MASK                                                               0x00007000
-#define PHY_ANALOG_TXRF1_OB2G_CCK_GET(x)                                             (((x) & 0x00007000) >> 12)
-#define PHY_ANALOG_TXRF1_OB2G_CCK_SET(x)                                             (((x) << 12) & 0x00007000)
-#define PHY_ANALOG_TXRF1_DB2G_MSB                                                                            17
-#define PHY_ANALOG_TXRF1_DB2G_LSB                                                                            15
-#define PHY_ANALOG_TXRF1_DB2G_MASK                                                                   0x00038000
-#define PHY_ANALOG_TXRF1_DB2G_GET(x)                                                 (((x) & 0x00038000) >> 15)
-#define PHY_ANALOG_TXRF1_DB2G_SET(x)                                                 (((x) << 15) & 0x00038000)
-#define PHY_ANALOG_TXRF1_PDOUT2G_MSB                                                                         18
-#define PHY_ANALOG_TXRF1_PDOUT2G_LSB                                                                         18
-#define PHY_ANALOG_TXRF1_PDOUT2G_MASK                                                                0x00040000
-#define PHY_ANALOG_TXRF1_PDOUT2G_GET(x)                                              (((x) & 0x00040000) >> 18)
-#define PHY_ANALOG_TXRF1_PDOUT2G_SET(x)                                              (((x) << 18) & 0x00040000)
-#define PHY_ANALOG_TXRF1_PDDR2G_MSB                                                                          19
-#define PHY_ANALOG_TXRF1_PDDR2G_LSB                                                                          19
-#define PHY_ANALOG_TXRF1_PDDR2G_MASK                                                                 0x00080000
-#define PHY_ANALOG_TXRF1_PDDR2G_GET(x)                                               (((x) & 0x00080000) >> 19)
-#define PHY_ANALOG_TXRF1_PDDR2G_SET(x)                                               (((x) << 19) & 0x00080000)
-#define PHY_ANALOG_TXRF1_PDMXR2G_MSB                                                                         20
-#define PHY_ANALOG_TXRF1_PDMXR2G_LSB                                                                         20
-#define PHY_ANALOG_TXRF1_PDMXR2G_MASK                                                                0x00100000
-#define PHY_ANALOG_TXRF1_PDMXR2G_GET(x)                                              (((x) & 0x00100000) >> 20)
-#define PHY_ANALOG_TXRF1_PDMXR2G_SET(x)                                              (((x) << 20) & 0x00100000)
-#define PHY_ANALOG_TXRF1_PDLO2G_MSB                                                                          21
-#define PHY_ANALOG_TXRF1_PDLO2G_LSB                                                                          21
-#define PHY_ANALOG_TXRF1_PDLO2G_MASK                                                                 0x00200000
-#define PHY_ANALOG_TXRF1_PDLO2G_GET(x)                                               (((x) & 0x00200000) >> 21)
-#define PHY_ANALOG_TXRF1_PDLO2G_SET(x)                                               (((x) << 21) & 0x00200000)
-#define PHY_ANALOG_TXRF1_LOBUF2GFORCED_MSB                                                                   22
-#define PHY_ANALOG_TXRF1_LOBUF2GFORCED_LSB                                                                   22
-#define PHY_ANALOG_TXRF1_LOBUF2GFORCED_MASK                                                          0x00400000
-#define PHY_ANALOG_TXRF1_LOBUF2GFORCED_GET(x)                                        (((x) & 0x00400000) >> 22)
-#define PHY_ANALOG_TXRF1_LOBUF2GFORCED_SET(x)                                        (((x) << 22) & 0x00400000)
-#define PHY_ANALOG_TXRF1_LODIV2GFORCED_MSB                                                                   23
-#define PHY_ANALOG_TXRF1_LODIV2GFORCED_LSB                                                                   23
-#define PHY_ANALOG_TXRF1_LODIV2GFORCED_MASK                                                          0x00800000
-#define PHY_ANALOG_TXRF1_LODIV2GFORCED_GET(x)                                        (((x) & 0x00800000) >> 23)
-#define PHY_ANALOG_TXRF1_LODIV2GFORCED_SET(x)                                        (((x) << 23) & 0x00800000)
-#define PHY_ANALOG_TXRF1_PADRVGN2G_MSB                                                                       30
-#define PHY_ANALOG_TXRF1_PADRVGN2G_LSB                                                                       24
-#define PHY_ANALOG_TXRF1_PADRVGN2G_MASK                                                              0x7f000000
-#define PHY_ANALOG_TXRF1_PADRVGN2G_GET(x)                                            (((x) & 0x7f000000) >> 24)
-#define PHY_ANALOG_TXRF1_PADRVGN2G_SET(x)                                            (((x) << 24) & 0x7f000000)
-#define PHY_ANALOG_TXRF1_LOCALTXGAIN2G_MSB                                                                   31
-#define PHY_ANALOG_TXRF1_LOCALTXGAIN2G_LSB                                                                   31
-#define PHY_ANALOG_TXRF1_LOCALTXGAIN2G_MASK                                                          0x80000000
-#define PHY_ANALOG_TXRF1_LOCALTXGAIN2G_GET(x)                                        (((x) & 0x80000000) >> 31)
-#define PHY_ANALOG_TXRF1_LOCALTXGAIN2G_SET(x)                                        (((x) << 31) & 0x80000000)
-
-/* macros for TXRF2 */
-#define PHY_ANALOG_TXRF2_ADDRESS                                                                     0x00000044
-#define PHY_ANALOG_TXRF2_OFFSET                                                                      0x00000044
-#define PHY_ANALOG_TXRF2_SPARE2_MSB                                                                           0
-#define PHY_ANALOG_TXRF2_SPARE2_LSB                                                                           0
-#define PHY_ANALOG_TXRF2_SPARE2_MASK                                                                 0x00000001
-#define PHY_ANALOG_TXRF2_SPARE2_GET(x)                                                (((x) & 0x00000001) >> 0)
-#define PHY_ANALOG_TXRF2_SPARE2_SET(x)                                                (((x) << 0) & 0x00000001)
-#define PHY_ANALOG_TXRF2_D3B5G_MSB                                                                            3
-#define PHY_ANALOG_TXRF2_D3B5G_LSB                                                                            1
-#define PHY_ANALOG_TXRF2_D3B5G_MASK                                                                  0x0000000e
-#define PHY_ANALOG_TXRF2_D3B5G_GET(x)                                                 (((x) & 0x0000000e) >> 1)
-#define PHY_ANALOG_TXRF2_D3B5G_SET(x)                                                 (((x) << 1) & 0x0000000e)
-#define PHY_ANALOG_TXRF2_D4B5G_MSB                                                                            6
-#define PHY_ANALOG_TXRF2_D4B5G_LSB                                                                            4
-#define PHY_ANALOG_TXRF2_D4B5G_MASK                                                                  0x00000070
-#define PHY_ANALOG_TXRF2_D4B5G_GET(x)                                                 (((x) & 0x00000070) >> 4)
-#define PHY_ANALOG_TXRF2_D4B5G_SET(x)                                                 (((x) << 4) & 0x00000070)
-#define PHY_ANALOG_TXRF2_PDOUT5G_MSB                                                                         10
-#define PHY_ANALOG_TXRF2_PDOUT5G_LSB                                                                          7
-#define PHY_ANALOG_TXRF2_PDOUT5G_MASK                                                                0x00000780
-#define PHY_ANALOG_TXRF2_PDOUT5G_GET(x)                                               (((x) & 0x00000780) >> 7)
-#define PHY_ANALOG_TXRF2_PDOUT5G_SET(x)                                               (((x) << 7) & 0x00000780)
-#define PHY_ANALOG_TXRF2_PDMXR5G_MSB                                                                         11
-#define PHY_ANALOG_TXRF2_PDMXR5G_LSB                                                                         11
-#define PHY_ANALOG_TXRF2_PDMXR5G_MASK                                                                0x00000800
-#define PHY_ANALOG_TXRF2_PDMXR5G_GET(x)                                              (((x) & 0x00000800) >> 11)
-#define PHY_ANALOG_TXRF2_PDMXR5G_SET(x)                                              (((x) << 11) & 0x00000800)
-#define PHY_ANALOG_TXRF2_PDLOBUF5G_MSB                                                                       12
-#define PHY_ANALOG_TXRF2_PDLOBUF5G_LSB                                                                       12
-#define PHY_ANALOG_TXRF2_PDLOBUF5G_MASK                                                              0x00001000
-#define PHY_ANALOG_TXRF2_PDLOBUF5G_GET(x)                                            (((x) & 0x00001000) >> 12)
-#define PHY_ANALOG_TXRF2_PDLOBUF5G_SET(x)                                            (((x) << 12) & 0x00001000)
-#define PHY_ANALOG_TXRF2_PDLODIV5G_MSB                                                                       13
-#define PHY_ANALOG_TXRF2_PDLODIV5G_LSB                                                                       13
-#define PHY_ANALOG_TXRF2_PDLODIV5G_MASK                                                              0x00002000
-#define PHY_ANALOG_TXRF2_PDLODIV5G_GET(x)                                            (((x) & 0x00002000) >> 13)
-#define PHY_ANALOG_TXRF2_PDLODIV5G_SET(x)                                            (((x) << 13) & 0x00002000)
-#define PHY_ANALOG_TXRF2_LOBUF5GFORCED_MSB                                                                   14
-#define PHY_ANALOG_TXRF2_LOBUF5GFORCED_LSB                                                                   14
-#define PHY_ANALOG_TXRF2_LOBUF5GFORCED_MASK                                                          0x00004000
-#define PHY_ANALOG_TXRF2_LOBUF5GFORCED_GET(x)                                        (((x) & 0x00004000) >> 14)
-#define PHY_ANALOG_TXRF2_LOBUF5GFORCED_SET(x)                                        (((x) << 14) & 0x00004000)
-#define PHY_ANALOG_TXRF2_LODIV5GFORCED_MSB                                                                   15
-#define PHY_ANALOG_TXRF2_LODIV5GFORCED_LSB                                                                   15
-#define PHY_ANALOG_TXRF2_LODIV5GFORCED_MASK                                                          0x00008000
-#define PHY_ANALOG_TXRF2_LODIV5GFORCED_GET(x)                                        (((x) & 0x00008000) >> 15)
-#define PHY_ANALOG_TXRF2_LODIV5GFORCED_SET(x)                                        (((x) << 15) & 0x00008000)
-#define PHY_ANALOG_TXRF2_PADRV2GN5G_MSB                                                                      19
-#define PHY_ANALOG_TXRF2_PADRV2GN5G_LSB                                                                      16
-#define PHY_ANALOG_TXRF2_PADRV2GN5G_MASK                                                             0x000f0000
-#define PHY_ANALOG_TXRF2_PADRV2GN5G_GET(x)                                           (((x) & 0x000f0000) >> 16)
-#define PHY_ANALOG_TXRF2_PADRV2GN5G_SET(x)                                           (((x) << 16) & 0x000f0000)
-#define PHY_ANALOG_TXRF2_PADRV3GN5G_MSB                                                                      23
-#define PHY_ANALOG_TXRF2_PADRV3GN5G_LSB                                                                      20
-#define PHY_ANALOG_TXRF2_PADRV3GN5G_MASK                                                             0x00f00000
-#define PHY_ANALOG_TXRF2_PADRV3GN5G_GET(x)                                           (((x) & 0x00f00000) >> 20)
-#define PHY_ANALOG_TXRF2_PADRV3GN5G_SET(x)                                           (((x) << 20) & 0x00f00000)
-#define PHY_ANALOG_TXRF2_PADRV4GN5G_MSB                                                                      27
-#define PHY_ANALOG_TXRF2_PADRV4GN5G_LSB                                                                      24
-#define PHY_ANALOG_TXRF2_PADRV4GN5G_MASK                                                             0x0f000000
-#define PHY_ANALOG_TXRF2_PADRV4GN5G_GET(x)                                           (((x) & 0x0f000000) >> 24)
-#define PHY_ANALOG_TXRF2_PADRV4GN5G_SET(x)                                           (((x) << 24) & 0x0f000000)
-#define PHY_ANALOG_TXRF2_LOCALTXGAIN5G_MSB                                                                   28
-#define PHY_ANALOG_TXRF2_LOCALTXGAIN5G_LSB                                                                   28
-#define PHY_ANALOG_TXRF2_LOCALTXGAIN5G_MASK                                                          0x10000000
-#define PHY_ANALOG_TXRF2_LOCALTXGAIN5G_GET(x)                                        (((x) & 0x10000000) >> 28)
-#define PHY_ANALOG_TXRF2_LOCALTXGAIN5G_SET(x)                                        (((x) << 28) & 0x10000000)
-#define PHY_ANALOG_TXRF2_OCAS2G_MSB                                                                          31
-#define PHY_ANALOG_TXRF2_OCAS2G_LSB                                                                          29
-#define PHY_ANALOG_TXRF2_OCAS2G_MASK                                                                 0xe0000000
-#define PHY_ANALOG_TXRF2_OCAS2G_GET(x)                                               (((x) & 0xe0000000) >> 29)
-#define PHY_ANALOG_TXRF2_OCAS2G_SET(x)                                               (((x) << 29) & 0xe0000000)
-
-/* macros for TXRF3 */
-#define PHY_ANALOG_TXRF3_ADDRESS                                                                     0x00000048
-#define PHY_ANALOG_TXRF3_OFFSET                                                                      0x00000048
-#define PHY_ANALOG_TXRF3_SPARE3_MSB                                                                          22
-#define PHY_ANALOG_TXRF3_SPARE3_LSB                                                                           0
-#define PHY_ANALOG_TXRF3_SPARE3_MASK                                                                 0x007fffff
-#define PHY_ANALOG_TXRF3_SPARE3_GET(x)                                                (((x) & 0x007fffff) >> 0)
-#define PHY_ANALOG_TXRF3_SPARE3_SET(x)                                                (((x) << 0) & 0x007fffff)
-#define PHY_ANALOG_TXRF3_CAS5G_MSB                                                                           25
-#define PHY_ANALOG_TXRF3_CAS5G_LSB                                                                           23
-#define PHY_ANALOG_TXRF3_CAS5G_MASK                                                                  0x03800000
-#define PHY_ANALOG_TXRF3_CAS5G_GET(x)                                                (((x) & 0x03800000) >> 23)
-#define PHY_ANALOG_TXRF3_CAS5G_SET(x)                                                (((x) << 23) & 0x03800000)
-#define PHY_ANALOG_TXRF3_OB5G_MSB                                                                            28
-#define PHY_ANALOG_TXRF3_OB5G_LSB                                                                            26
-#define PHY_ANALOG_TXRF3_OB5G_MASK                                                                   0x1c000000
-#define PHY_ANALOG_TXRF3_OB5G_GET(x)                                                 (((x) & 0x1c000000) >> 26)
-#define PHY_ANALOG_TXRF3_OB5G_SET(x)                                                 (((x) << 26) & 0x1c000000)
-#define PHY_ANALOG_TXRF3_D2B5G_MSB                                                                           31
-#define PHY_ANALOG_TXRF3_D2B5G_LSB                                                                           29
-#define PHY_ANALOG_TXRF3_D2B5G_MASK                                                                  0xe0000000
-#define PHY_ANALOG_TXRF3_D2B5G_GET(x)                                                (((x) & 0xe0000000) >> 29)
-#define PHY_ANALOG_TXRF3_D2B5G_SET(x)                                                (((x) << 29) & 0xe0000000)
-
-/* macros for TXRF4 */
-#define PHY_ANALOG_TXRF4_ADDRESS                                                                     0x0000004c
-#define PHY_ANALOG_TXRF4_OFFSET                                                                      0x0000004c
-#define PHY_ANALOG_TXRF4_COMP2G_PSK_MSB                                                                       2
-#define PHY_ANALOG_TXRF4_COMP2G_PSK_LSB                                                                       0
-#define PHY_ANALOG_TXRF4_COMP2G_PSK_MASK                                                             0x00000007
-#define PHY_ANALOG_TXRF4_COMP2G_PSK_GET(x)                                            (((x) & 0x00000007) >> 0)
-#define PHY_ANALOG_TXRF4_COMP2G_PSK_SET(x)                                            (((x) << 0) & 0x00000007)
-#define PHY_ANALOG_TXRF4_COMP2G_CCK_MSB                                                                       5
-#define PHY_ANALOG_TXRF4_COMP2G_CCK_LSB                                                                       3
-#define PHY_ANALOG_TXRF4_COMP2G_CCK_MASK                                                             0x00000038
-#define PHY_ANALOG_TXRF4_COMP2G_CCK_GET(x)                                            (((x) & 0x00000038) >> 3)
-#define PHY_ANALOG_TXRF4_COMP2G_CCK_SET(x)                                            (((x) << 3) & 0x00000038)
-#define PHY_ANALOG_TXRF4_AMP2B2G_QAM_MSB                                                                      8
-#define PHY_ANALOG_TXRF4_AMP2B2G_QAM_LSB                                                                      6
-#define PHY_ANALOG_TXRF4_AMP2B2G_QAM_MASK                                                            0x000001c0
-#define PHY_ANALOG_TXRF4_AMP2B2G_QAM_GET(x)                                           (((x) & 0x000001c0) >> 6)
-#define PHY_ANALOG_TXRF4_AMP2B2G_QAM_SET(x)                                           (((x) << 6) & 0x000001c0)
-#define PHY_ANALOG_TXRF4_AMP2B2G_PSK_MSB                                                                     11
-#define PHY_ANALOG_TXRF4_AMP2B2G_PSK_LSB                                                                      9
-#define PHY_ANALOG_TXRF4_AMP2B2G_PSK_MASK                                                            0x00000e00
-#define PHY_ANALOG_TXRF4_AMP2B2G_PSK_GET(x)                                           (((x) & 0x00000e00) >> 9)
-#define PHY_ANALOG_TXRF4_AMP2B2G_PSK_SET(x)                                           (((x) << 9) & 0x00000e00)
-#define PHY_ANALOG_TXRF4_AMP2B2G_CCK_MSB                                                                     14
-#define PHY_ANALOG_TXRF4_AMP2B2G_CCK_LSB                                                                     12
-#define PHY_ANALOG_TXRF4_AMP2B2G_CCK_MASK                                                            0x00007000
-#define PHY_ANALOG_TXRF4_AMP2B2G_CCK_GET(x)                                          (((x) & 0x00007000) >> 12)
-#define PHY_ANALOG_TXRF4_AMP2B2G_CCK_SET(x)                                          (((x) << 12) & 0x00007000)
-#define PHY_ANALOG_TXRF4_AMP2CAS2G_MSB                                                                       17
-#define PHY_ANALOG_TXRF4_AMP2CAS2G_LSB                                                                       15
-#define PHY_ANALOG_TXRF4_AMP2CAS2G_MASK                                                              0x00038000
-#define PHY_ANALOG_TXRF4_AMP2CAS2G_GET(x)                                            (((x) & 0x00038000) >> 15)
-#define PHY_ANALOG_TXRF4_AMP2CAS2G_SET(x)                                            (((x) << 15) & 0x00038000)
-#define PHY_ANALOG_TXRF4_FILTR2G_MSB                                                                         19
-#define PHY_ANALOG_TXRF4_FILTR2G_LSB                                                                         18
-#define PHY_ANALOG_TXRF4_FILTR2G_MASK                                                                0x000c0000
-#define PHY_ANALOG_TXRF4_FILTR2G_GET(x)                                              (((x) & 0x000c0000) >> 18)
-#define PHY_ANALOG_TXRF4_FILTR2G_SET(x)                                              (((x) << 18) & 0x000c0000)
-#define PHY_ANALOG_TXRF4_PWDFB2_2G_MSB                                                                       20
-#define PHY_ANALOG_TXRF4_PWDFB2_2G_LSB                                                                       20
-#define PHY_ANALOG_TXRF4_PWDFB2_2G_MASK                                                              0x00100000
-#define PHY_ANALOG_TXRF4_PWDFB2_2G_GET(x)                                            (((x) & 0x00100000) >> 20)
-#define PHY_ANALOG_TXRF4_PWDFB2_2G_SET(x)                                            (((x) << 20) & 0x00100000)
-#define PHY_ANALOG_TXRF4_PWDFB1_2G_MSB                                                                       21
-#define PHY_ANALOG_TXRF4_PWDFB1_2G_LSB                                                                       21
-#define PHY_ANALOG_TXRF4_PWDFB1_2G_MASK                                                              0x00200000
-#define PHY_ANALOG_TXRF4_PWDFB1_2G_GET(x)                                            (((x) & 0x00200000) >> 21)
-#define PHY_ANALOG_TXRF4_PWDFB1_2G_SET(x)                                            (((x) << 21) & 0x00200000)
-#define PHY_ANALOG_TXRF4_PDFB2G_MSB                                                                          22
-#define PHY_ANALOG_TXRF4_PDFB2G_LSB                                                                          22
-#define PHY_ANALOG_TXRF4_PDFB2G_MASK                                                                 0x00400000
-#define PHY_ANALOG_TXRF4_PDFB2G_GET(x)                                               (((x) & 0x00400000) >> 22)
-#define PHY_ANALOG_TXRF4_PDFB2G_SET(x)                                               (((x) << 22) & 0x00400000)
-#define PHY_ANALOG_TXRF4_RDIV5G_MSB                                                                          24
-#define PHY_ANALOG_TXRF4_RDIV5G_LSB                                                                          23
-#define PHY_ANALOG_TXRF4_RDIV5G_MASK                                                                 0x01800000
-#define PHY_ANALOG_TXRF4_RDIV5G_GET(x)                                               (((x) & 0x01800000) >> 23)
-#define PHY_ANALOG_TXRF4_RDIV5G_SET(x)                                               (((x) << 23) & 0x01800000)
-#define PHY_ANALOG_TXRF4_CAPDIV5G_MSB                                                                        27
-#define PHY_ANALOG_TXRF4_CAPDIV5G_LSB                                                                        25
-#define PHY_ANALOG_TXRF4_CAPDIV5G_MASK                                                               0x0e000000
-#define PHY_ANALOG_TXRF4_CAPDIV5G_GET(x)                                             (((x) & 0x0e000000) >> 25)
-#define PHY_ANALOG_TXRF4_CAPDIV5G_SET(x)                                             (((x) << 25) & 0x0e000000)
-#define PHY_ANALOG_TXRF4_PDPREDIST5G_MSB                                                                     28
-#define PHY_ANALOG_TXRF4_PDPREDIST5G_LSB                                                                     28
-#define PHY_ANALOG_TXRF4_PDPREDIST5G_MASK                                                            0x10000000
-#define PHY_ANALOG_TXRF4_PDPREDIST5G_GET(x)                                          (((x) & 0x10000000) >> 28)
-#define PHY_ANALOG_TXRF4_PDPREDIST5G_SET(x)                                          (((x) << 28) & 0x10000000)
-#define PHY_ANALOG_TXRF4_RDIV2G_MSB                                                                          30
-#define PHY_ANALOG_TXRF4_RDIV2G_LSB                                                                          29
-#define PHY_ANALOG_TXRF4_RDIV2G_MASK                                                                 0x60000000
-#define PHY_ANALOG_TXRF4_RDIV2G_GET(x)                                               (((x) & 0x60000000) >> 29)
-#define PHY_ANALOG_TXRF4_RDIV2G_SET(x)                                               (((x) << 29) & 0x60000000)
-#define PHY_ANALOG_TXRF4_PDPREDIST2G_MSB                                                                     31
-#define PHY_ANALOG_TXRF4_PDPREDIST2G_LSB                                                                     31
-#define PHY_ANALOG_TXRF4_PDPREDIST2G_MASK                                                            0x80000000
-#define PHY_ANALOG_TXRF4_PDPREDIST2G_GET(x)                                          (((x) & 0x80000000) >> 31)
-#define PHY_ANALOG_TXRF4_PDPREDIST2G_SET(x)                                          (((x) << 31) & 0x80000000)
-
-/* macros for TXRF5 */
-#define PHY_ANALOG_TXRF5_ADDRESS                                                                     0x00000050
-#define PHY_ANALOG_TXRF5_OFFSET                                                                      0x00000050
-#define PHY_ANALOG_TXRF5_FBHI2G_MSB                                                                           0
-#define PHY_ANALOG_TXRF5_FBHI2G_LSB                                                                           0
-#define PHY_ANALOG_TXRF5_FBHI2G_MASK                                                                 0x00000001
-#define PHY_ANALOG_TXRF5_FBHI2G_GET(x)                                                (((x) & 0x00000001) >> 0)
-#define PHY_ANALOG_TXRF5_FBLO2G_MSB                                                                           1
-#define PHY_ANALOG_TXRF5_FBLO2G_LSB                                                                           1
-#define PHY_ANALOG_TXRF5_FBLO2G_MASK                                                                 0x00000002
-#define PHY_ANALOG_TXRF5_FBLO2G_GET(x)                                                (((x) & 0x00000002) >> 1)
-#define PHY_ANALOG_TXRF5_REFHI2G_MSB                                                                          4
-#define PHY_ANALOG_TXRF5_REFHI2G_LSB                                                                          2
-#define PHY_ANALOG_TXRF5_REFHI2G_MASK                                                                0x0000001c
-#define PHY_ANALOG_TXRF5_REFHI2G_GET(x)                                               (((x) & 0x0000001c) >> 2)
-#define PHY_ANALOG_TXRF5_REFHI2G_SET(x)                                               (((x) << 2) & 0x0000001c)
-#define PHY_ANALOG_TXRF5_REFLO2G_MSB                                                                          7
-#define PHY_ANALOG_TXRF5_REFLO2G_LSB                                                                          5
-#define PHY_ANALOG_TXRF5_REFLO2G_MASK                                                                0x000000e0
-#define PHY_ANALOG_TXRF5_REFLO2G_GET(x)                                               (((x) & 0x000000e0) >> 5)
-#define PHY_ANALOG_TXRF5_REFLO2G_SET(x)                                               (((x) << 5) & 0x000000e0)
-#define PHY_ANALOG_TXRF5_PK2B2G_QAM_MSB                                                                       9
-#define PHY_ANALOG_TXRF5_PK2B2G_QAM_LSB                                                                       8
-#define PHY_ANALOG_TXRF5_PK2B2G_QAM_MASK                                                             0x00000300
-#define PHY_ANALOG_TXRF5_PK2B2G_QAM_GET(x)                                            (((x) & 0x00000300) >> 8)
-#define PHY_ANALOG_TXRF5_PK2B2G_QAM_SET(x)                                            (((x) << 8) & 0x00000300)
-#define PHY_ANALOG_TXRF5_PK2B2G_PSK_MSB                                                                      11
-#define PHY_ANALOG_TXRF5_PK2B2G_PSK_LSB                                                                      10
-#define PHY_ANALOG_TXRF5_PK2B2G_PSK_MASK                                                             0x00000c00
-#define PHY_ANALOG_TXRF5_PK2B2G_PSK_GET(x)                                           (((x) & 0x00000c00) >> 10)
-#define PHY_ANALOG_TXRF5_PK2B2G_PSK_SET(x)                                           (((x) << 10) & 0x00000c00)
-#define PHY_ANALOG_TXRF5_PK2B2G_CCK_MSB                                                                      13
-#define PHY_ANALOG_TXRF5_PK2B2G_CCK_LSB                                                                      12
-#define PHY_ANALOG_TXRF5_PK2B2G_CCK_MASK                                                             0x00003000
-#define PHY_ANALOG_TXRF5_PK2B2G_CCK_GET(x)                                           (((x) & 0x00003000) >> 12)
-#define PHY_ANALOG_TXRF5_PK2B2G_CCK_SET(x)                                           (((x) << 12) & 0x00003000)
-#define PHY_ANALOG_TXRF5_PK1B2G_QAM_MSB                                                                      15
-#define PHY_ANALOG_TXRF5_PK1B2G_QAM_LSB                                                                      14
-#define PHY_ANALOG_TXRF5_PK1B2G_QAM_MASK                                                             0x0000c000
-#define PHY_ANALOG_TXRF5_PK1B2G_QAM_GET(x)                                           (((x) & 0x0000c000) >> 14)
-#define PHY_ANALOG_TXRF5_PK1B2G_QAM_SET(x)                                           (((x) << 14) & 0x0000c000)
-#define PHY_ANALOG_TXRF5_PK1B2G_PSK_MSB                                                                      17
-#define PHY_ANALOG_TXRF5_PK1B2G_PSK_LSB                                                                      16
-#define PHY_ANALOG_TXRF5_PK1B2G_PSK_MASK                                                             0x00030000
-#define PHY_ANALOG_TXRF5_PK1B2G_PSK_GET(x)                                           (((x) & 0x00030000) >> 16)
-#define PHY_ANALOG_TXRF5_PK1B2G_PSK_SET(x)                                           (((x) << 16) & 0x00030000)
-#define PHY_ANALOG_TXRF5_PK1B2G_CCK_MSB                                                                      19
-#define PHY_ANALOG_TXRF5_PK1B2G_CCK_LSB                                                                      18
-#define PHY_ANALOG_TXRF5_PK1B2G_CCK_MASK                                                             0x000c0000
-#define PHY_ANALOG_TXRF5_PK1B2G_CCK_GET(x)                                           (((x) & 0x000c0000) >> 18)
-#define PHY_ANALOG_TXRF5_PK1B2G_CCK_SET(x)                                           (((x) << 18) & 0x000c0000)
-#define PHY_ANALOG_TXRF5_MIOB2G_QAM_MSB                                                                      22
-#define PHY_ANALOG_TXRF5_MIOB2G_QAM_LSB                                                                      20
-#define PHY_ANALOG_TXRF5_MIOB2G_QAM_MASK                                                             0x00700000
-#define PHY_ANALOG_TXRF5_MIOB2G_QAM_GET(x)                                           (((x) & 0x00700000) >> 20)
-#define PHY_ANALOG_TXRF5_MIOB2G_QAM_SET(x)                                           (((x) << 20) & 0x00700000)
-#define PHY_ANALOG_TXRF5_MIOB2G_PSK_MSB                                                                      25
-#define PHY_ANALOG_TXRF5_MIOB2G_PSK_LSB                                                                      23
-#define PHY_ANALOG_TXRF5_MIOB2G_PSK_MASK                                                             0x03800000
-#define PHY_ANALOG_TXRF5_MIOB2G_PSK_GET(x)                                           (((x) & 0x03800000) >> 23)
-#define PHY_ANALOG_TXRF5_MIOB2G_PSK_SET(x)                                           (((x) << 23) & 0x03800000)
-#define PHY_ANALOG_TXRF5_MIOB2G_CCK_MSB                                                                      28
-#define PHY_ANALOG_TXRF5_MIOB2G_CCK_LSB                                                                      26
-#define PHY_ANALOG_TXRF5_MIOB2G_CCK_MASK                                                             0x1c000000
-#define PHY_ANALOG_TXRF5_MIOB2G_CCK_GET(x)                                           (((x) & 0x1c000000) >> 26)
-#define PHY_ANALOG_TXRF5_MIOB2G_CCK_SET(x)                                           (((x) << 26) & 0x1c000000)
-#define PHY_ANALOG_TXRF5_COMP2G_QAM_MSB                                                                      31
-#define PHY_ANALOG_TXRF5_COMP2G_QAM_LSB                                                                      29
-#define PHY_ANALOG_TXRF5_COMP2G_QAM_MASK                                                             0xe0000000
-#define PHY_ANALOG_TXRF5_COMP2G_QAM_GET(x)                                           (((x) & 0xe0000000) >> 29)
-#define PHY_ANALOG_TXRF5_COMP2G_QAM_SET(x)                                           (((x) << 29) & 0xe0000000)
-
-/* macros for TXRF6 */
-#define PHY_ANALOG_TXRF6_ADDRESS                                                                     0x00000054
-#define PHY_ANALOG_TXRF6_OFFSET                                                                      0x00000054
-#define PHY_ANALOG_TXRF6_SPARE6_MSB                                                                           0
-#define PHY_ANALOG_TXRF6_SPARE6_LSB                                                                           0
-#define PHY_ANALOG_TXRF6_SPARE6_MASK                                                                 0x00000001
-#define PHY_ANALOG_TXRF6_SPARE6_GET(x)                                                (((x) & 0x00000001) >> 0)
-#define PHY_ANALOG_TXRF6_SPARE6_SET(x)                                                (((x) << 0) & 0x00000001)
-#define PHY_ANALOG_TXRF6_PAL_LOCKED_MSB                                                                       1
-#define PHY_ANALOG_TXRF6_PAL_LOCKED_LSB                                                                       1
-#define PHY_ANALOG_TXRF6_PAL_LOCKED_MASK                                                             0x00000002
-#define PHY_ANALOG_TXRF6_PAL_LOCKED_GET(x)                                            (((x) & 0x00000002) >> 1)
-#define PHY_ANALOG_TXRF6_PADRVGN2G_SMOUT_MSB                                                                  7
-#define PHY_ANALOG_TXRF6_PADRVGN2G_SMOUT_LSB                                                                  2
-#define PHY_ANALOG_TXRF6_PADRVGN2G_SMOUT_MASK                                                        0x000000fc
-#define PHY_ANALOG_TXRF6_PADRVGN2G_SMOUT_GET(x)                                       (((x) & 0x000000fc) >> 2)
-#define PHY_ANALOG_TXRF6_GAINSTEP2G_MSB                                                                      10
-#define PHY_ANALOG_TXRF6_GAINSTEP2G_LSB                                                                       8
-#define PHY_ANALOG_TXRF6_GAINSTEP2G_MASK                                                             0x00000700
-#define PHY_ANALOG_TXRF6_GAINSTEP2G_GET(x)                                            (((x) & 0x00000700) >> 8)
-#define PHY_ANALOG_TXRF6_GAINSTEP2G_SET(x)                                            (((x) << 8) & 0x00000700)
-#define PHY_ANALOG_TXRF6_USE_GAIN_DELTA2G_MSB                                                                11
-#define PHY_ANALOG_TXRF6_USE_GAIN_DELTA2G_LSB                                                                11
-#define PHY_ANALOG_TXRF6_USE_GAIN_DELTA2G_MASK                                                       0x00000800
-#define PHY_ANALOG_TXRF6_USE_GAIN_DELTA2G_GET(x)                                     (((x) & 0x00000800) >> 11)
-#define PHY_ANALOG_TXRF6_USE_GAIN_DELTA2G_SET(x)                                     (((x) << 11) & 0x00000800)
-#define PHY_ANALOG_TXRF6_PADRVGN_INDEX_I2G_MSB                                                               15
-#define PHY_ANALOG_TXRF6_PADRVGN_INDEX_I2G_LSB                                                               12
-#define PHY_ANALOG_TXRF6_PADRVGN_INDEX_I2G_MASK                                                      0x0000f000
-#define PHY_ANALOG_TXRF6_PADRVGN_INDEX_I2G_GET(x)                                    (((x) & 0x0000f000) >> 12)
-#define PHY_ANALOG_TXRF6_PADRVGN_INDEX_I2G_SET(x)                                    (((x) << 12) & 0x0000f000)
-#define PHY_ANALOG_TXRF6_VCMONDELAY2G_MSB                                                                    18
-#define PHY_ANALOG_TXRF6_VCMONDELAY2G_LSB                                                                    16
-#define PHY_ANALOG_TXRF6_VCMONDELAY2G_MASK                                                           0x00070000
-#define PHY_ANALOG_TXRF6_VCMONDELAY2G_GET(x)                                         (((x) & 0x00070000) >> 16)
-#define PHY_ANALOG_TXRF6_VCMONDELAY2G_SET(x)                                         (((x) << 16) & 0x00070000)
-#define PHY_ANALOG_TXRF6_CAPDIV2G_MSB                                                                        21
-#define PHY_ANALOG_TXRF6_CAPDIV2G_LSB                                                                        19
-#define PHY_ANALOG_TXRF6_CAPDIV2G_MASK                                                               0x00380000
-#define PHY_ANALOG_TXRF6_CAPDIV2G_GET(x)                                             (((x) & 0x00380000) >> 19)
-#define PHY_ANALOG_TXRF6_CAPDIV2G_SET(x)                                             (((x) << 19) & 0x00380000)
-#define PHY_ANALOG_TXRF6_CAPDIV2GOVR_MSB                                                                     22
-#define PHY_ANALOG_TXRF6_CAPDIV2GOVR_LSB                                                                     22
-#define PHY_ANALOG_TXRF6_CAPDIV2GOVR_MASK                                                            0x00400000
-#define PHY_ANALOG_TXRF6_CAPDIV2GOVR_GET(x)                                          (((x) & 0x00400000) >> 22)
-#define PHY_ANALOG_TXRF6_CAPDIV2GOVR_SET(x)                                          (((x) << 22) & 0x00400000)
-#define PHY_ANALOG_TXRF6_ENPACAL2G_MSB                                                                       23
-#define PHY_ANALOG_TXRF6_ENPACAL2G_LSB                                                                       23
-#define PHY_ANALOG_TXRF6_ENPACAL2G_MASK                                                              0x00800000
-#define PHY_ANALOG_TXRF6_ENPACAL2G_GET(x)                                            (((x) & 0x00800000) >> 23)
-#define PHY_ANALOG_TXRF6_ENPACAL2G_SET(x)                                            (((x) << 23) & 0x00800000)
-#define PHY_ANALOG_TXRF6_OFFSET2G_MSB                                                                        30
-#define PHY_ANALOG_TXRF6_OFFSET2G_LSB                                                                        24
-#define PHY_ANALOG_TXRF6_OFFSET2G_MASK                                                               0x7f000000
-#define PHY_ANALOG_TXRF6_OFFSET2G_GET(x)                                             (((x) & 0x7f000000) >> 24)
-#define PHY_ANALOG_TXRF6_OFFSET2G_SET(x)                                             (((x) << 24) & 0x7f000000)
-#define PHY_ANALOG_TXRF6_ENOFFSETCAL2G_MSB                                                                   31
-#define PHY_ANALOG_TXRF6_ENOFFSETCAL2G_LSB                                                                   31
-#define PHY_ANALOG_TXRF6_ENOFFSETCAL2G_MASK                                                          0x80000000
-#define PHY_ANALOG_TXRF6_ENOFFSETCAL2G_GET(x)                                        (((x) & 0x80000000) >> 31)
-#define PHY_ANALOG_TXRF6_ENOFFSETCAL2G_SET(x)                                        (((x) << 31) & 0x80000000)
-
-/* macros for TXRF7 */
-#define PHY_ANALOG_TXRF7_ADDRESS                                                                     0x00000058
-#define PHY_ANALOG_TXRF7_OFFSET                                                                      0x00000058
-#define PHY_ANALOG_TXRF7_SPARE7_MSB                                                                           1
-#define PHY_ANALOG_TXRF7_SPARE7_LSB                                                                           0
-#define PHY_ANALOG_TXRF7_SPARE7_MASK                                                                 0x00000003
-#define PHY_ANALOG_TXRF7_SPARE7_GET(x)                                                (((x) & 0x00000003) >> 0)
-#define PHY_ANALOG_TXRF7_SPARE7_SET(x)                                                (((x) << 0) & 0x00000003)
-#define PHY_ANALOG_TXRF7_PADRVGNTAB_4_MSB                                                                     7
-#define PHY_ANALOG_TXRF7_PADRVGNTAB_4_LSB                                                                     2
-#define PHY_ANALOG_TXRF7_PADRVGNTAB_4_MASK                                                           0x000000fc
-#define PHY_ANALOG_TXRF7_PADRVGNTAB_4_GET(x)                                          (((x) & 0x000000fc) >> 2)
-#define PHY_ANALOG_TXRF7_PADRVGNTAB_4_SET(x)                                          (((x) << 2) & 0x000000fc)
-#define PHY_ANALOG_TXRF7_PADRVGNTAB_3_MSB                                                                    13
-#define PHY_ANALOG_TXRF7_PADRVGNTAB_3_LSB                                                                     8
-#define PHY_ANALOG_TXRF7_PADRVGNTAB_3_MASK                                                           0x00003f00
-#define PHY_ANALOG_TXRF7_PADRVGNTAB_3_GET(x)                                          (((x) & 0x00003f00) >> 8)
-#define PHY_ANALOG_TXRF7_PADRVGNTAB_3_SET(x)                                          (((x) << 8) & 0x00003f00)
-#define PHY_ANALOG_TXRF7_PADRVGNTAB_2_MSB                                                                    19
-#define PHY_ANALOG_TXRF7_PADRVGNTAB_2_LSB                                                                    14
-#define PHY_ANALOG_TXRF7_PADRVGNTAB_2_MASK                                                           0x000fc000
-#define PHY_ANALOG_TXRF7_PADRVGNTAB_2_GET(x)                                         (((x) & 0x000fc000) >> 14)
-#define PHY_ANALOG_TXRF7_PADRVGNTAB_2_SET(x)                                         (((x) << 14) & 0x000fc000)
-#define PHY_ANALOG_TXRF7_PADRVGNTAB_1_MSB                                                                    25
-#define PHY_ANALOG_TXRF7_PADRVGNTAB_1_LSB                                                                    20
-#define PHY_ANALOG_TXRF7_PADRVGNTAB_1_MASK                                                           0x03f00000
-#define PHY_ANALOG_TXRF7_PADRVGNTAB_1_GET(x)                                         (((x) & 0x03f00000) >> 20)
-#define PHY_ANALOG_TXRF7_PADRVGNTAB_1_SET(x)                                         (((x) << 20) & 0x03f00000)
-#define PHY_ANALOG_TXRF7_PADRVGNTAB_0_MSB                                                                    31
-#define PHY_ANALOG_TXRF7_PADRVGNTAB_0_LSB                                                                    26
-#define PHY_ANALOG_TXRF7_PADRVGNTAB_0_MASK                                                           0xfc000000
-#define PHY_ANALOG_TXRF7_PADRVGNTAB_0_GET(x)                                         (((x) & 0xfc000000) >> 26)
-#define PHY_ANALOG_TXRF7_PADRVGNTAB_0_SET(x)                                         (((x) << 26) & 0xfc000000)
-
-/* macros for TXRF8 */
-#define PHY_ANALOG_TXRF8_ADDRESS                                                                     0x0000005c
-#define PHY_ANALOG_TXRF8_OFFSET                                                                      0x0000005c
-#define PHY_ANALOG_TXRF8_SPARE8_MSB                                                                           1
-#define PHY_ANALOG_TXRF8_SPARE8_LSB                                                                           0
-#define PHY_ANALOG_TXRF8_SPARE8_MASK                                                                 0x00000003
-#define PHY_ANALOG_TXRF8_SPARE8_GET(x)                                                (((x) & 0x00000003) >> 0)
-#define PHY_ANALOG_TXRF8_SPARE8_SET(x)                                                (((x) << 0) & 0x00000003)
-#define PHY_ANALOG_TXRF8_PADRVGNTAB_9_MSB                                                                     7
-#define PHY_ANALOG_TXRF8_PADRVGNTAB_9_LSB                                                                     2
-#define PHY_ANALOG_TXRF8_PADRVGNTAB_9_MASK                                                           0x000000fc
-#define PHY_ANALOG_TXRF8_PADRVGNTAB_9_GET(x)                                          (((x) & 0x000000fc) >> 2)
-#define PHY_ANALOG_TXRF8_PADRVGNTAB_9_SET(x)                                          (((x) << 2) & 0x000000fc)
-#define PHY_ANALOG_TXRF8_PADRVGNTAB_8_MSB                                                                    13
-#define PHY_ANALOG_TXRF8_PADRVGNTAB_8_LSB                                                                     8
-#define PHY_ANALOG_TXRF8_PADRVGNTAB_8_MASK                                                           0x00003f00
-#define PHY_ANALOG_TXRF8_PADRVGNTAB_8_GET(x)                                          (((x) & 0x00003f00) >> 8)
-#define PHY_ANALOG_TXRF8_PADRVGNTAB_8_SET(x)                                          (((x) << 8) & 0x00003f00)
-#define PHY_ANALOG_TXRF8_PADRVGNTAB_7_MSB                                                                    19
-#define PHY_ANALOG_TXRF8_PADRVGNTAB_7_LSB                                                                    14
-#define PHY_ANALOG_TXRF8_PADRVGNTAB_7_MASK                                                           0x000fc000
-#define PHY_ANALOG_TXRF8_PADRVGNTAB_7_GET(x)                                         (((x) & 0x000fc000) >> 14)
-#define PHY_ANALOG_TXRF8_PADRVGNTAB_7_SET(x)                                         (((x) << 14) & 0x000fc000)
-#define PHY_ANALOG_TXRF8_PADRVGNTAB_6_MSB                                                                    25
-#define PHY_ANALOG_TXRF8_PADRVGNTAB_6_LSB                                                                    20
-#define PHY_ANALOG_TXRF8_PADRVGNTAB_6_MASK                                                           0x03f00000
-#define PHY_ANALOG_TXRF8_PADRVGNTAB_6_GET(x)                                         (((x) & 0x03f00000) >> 20)
-#define PHY_ANALOG_TXRF8_PADRVGNTAB_6_SET(x)                                         (((x) << 20) & 0x03f00000)
-#define PHY_ANALOG_TXRF8_PADRVGNTAB_5_MSB                                                                    31
-#define PHY_ANALOG_TXRF8_PADRVGNTAB_5_LSB                                                                    26
-#define PHY_ANALOG_TXRF8_PADRVGNTAB_5_MASK                                                           0xfc000000
-#define PHY_ANALOG_TXRF8_PADRVGNTAB_5_GET(x)                                         (((x) & 0xfc000000) >> 26)
-#define PHY_ANALOG_TXRF8_PADRVGNTAB_5_SET(x)                                         (((x) << 26) & 0xfc000000)
-
-/* macros for TXRF9 */
-#define PHY_ANALOG_TXRF9_ADDRESS                                                                     0x00000060
-#define PHY_ANALOG_TXRF9_OFFSET                                                                      0x00000060
-#define PHY_ANALOG_TXRF9_SPARE9_MSB                                                                           1
-#define PHY_ANALOG_TXRF9_SPARE9_LSB                                                                           0
-#define PHY_ANALOG_TXRF9_SPARE9_MASK                                                                 0x00000003
-#define PHY_ANALOG_TXRF9_SPARE9_GET(x)                                                (((x) & 0x00000003) >> 0)
-#define PHY_ANALOG_TXRF9_SPARE9_SET(x)                                                (((x) << 0) & 0x00000003)
-#define PHY_ANALOG_TXRF9_PADRVGNTAB_14_MSB                                                                    7
-#define PHY_ANALOG_TXRF9_PADRVGNTAB_14_LSB                                                                    2
-#define PHY_ANALOG_TXRF9_PADRVGNTAB_14_MASK                                                          0x000000fc
-#define PHY_ANALOG_TXRF9_PADRVGNTAB_14_GET(x)                                         (((x) & 0x000000fc) >> 2)
-#define PHY_ANALOG_TXRF9_PADRVGNTAB_14_SET(x)                                         (((x) << 2) & 0x000000fc)
-#define PHY_ANALOG_TXRF9_PADRVGNTAB_13_MSB                                                                   13
-#define PHY_ANALOG_TXRF9_PADRVGNTAB_13_LSB                                                                    8
-#define PHY_ANALOG_TXRF9_PADRVGNTAB_13_MASK                                                          0x00003f00
-#define PHY_ANALOG_TXRF9_PADRVGNTAB_13_GET(x)                                         (((x) & 0x00003f00) >> 8)
-#define PHY_ANALOG_TXRF9_PADRVGNTAB_13_SET(x)                                         (((x) << 8) & 0x00003f00)
-#define PHY_ANALOG_TXRF9_PADRVGNTAB_12_MSB                                                                   19
-#define PHY_ANALOG_TXRF9_PADRVGNTAB_12_LSB                                                                   14
-#define PHY_ANALOG_TXRF9_PADRVGNTAB_12_MASK                                                          0x000fc000
-#define PHY_ANALOG_TXRF9_PADRVGNTAB_12_GET(x)                                        (((x) & 0x000fc000) >> 14)
-#define PHY_ANALOG_TXRF9_PADRVGNTAB_12_SET(x)                                        (((x) << 14) & 0x000fc000)
-#define PHY_ANALOG_TXRF9_PADRVGNTAB_11_MSB                                                                   25
-#define PHY_ANALOG_TXRF9_PADRVGNTAB_11_LSB                                                                   20
-#define PHY_ANALOG_TXRF9_PADRVGNTAB_11_MASK                                                          0x03f00000
-#define PHY_ANALOG_TXRF9_PADRVGNTAB_11_GET(x)                                        (((x) & 0x03f00000) >> 20)
-#define PHY_ANALOG_TXRF9_PADRVGNTAB_11_SET(x)                                        (((x) << 20) & 0x03f00000)
-#define PHY_ANALOG_TXRF9_PADRVGNTAB_10_MSB                                                                   31
-#define PHY_ANALOG_TXRF9_PADRVGNTAB_10_LSB                                                                   26
-#define PHY_ANALOG_TXRF9_PADRVGNTAB_10_MASK                                                          0xfc000000
-#define PHY_ANALOG_TXRF9_PADRVGNTAB_10_GET(x)                                        (((x) & 0xfc000000) >> 26)
-#define PHY_ANALOG_TXRF9_PADRVGNTAB_10_SET(x)                                        (((x) << 26) & 0xfc000000)
-
-/* macros for TXRF10 */
-#define PHY_ANALOG_TXRF10_ADDRESS                                                                    0x00000064
-#define PHY_ANALOG_TXRF10_OFFSET                                                                     0x00000064
-#define PHY_ANALOG_TXRF10_SPARE10_MSB                                                                        12
-#define PHY_ANALOG_TXRF10_SPARE10_LSB                                                                         0
-#define PHY_ANALOG_TXRF10_SPARE10_MASK                                                               0x00001fff
-#define PHY_ANALOG_TXRF10_SPARE10_GET(x)                                              (((x) & 0x00001fff) >> 0)
-#define PHY_ANALOG_TXRF10_SPARE10_SET(x)                                              (((x) << 0) & 0x00001fff)
-#define PHY_ANALOG_TXRF10_PDOUT5G_3CALTX_MSB                                                                 13
-#define PHY_ANALOG_TXRF10_PDOUT5G_3CALTX_LSB                                                                 13
-#define PHY_ANALOG_TXRF10_PDOUT5G_3CALTX_MASK                                                        0x00002000
-#define PHY_ANALOG_TXRF10_PDOUT5G_3CALTX_GET(x)                                      (((x) & 0x00002000) >> 13)
-#define PHY_ANALOG_TXRF10_PDOUT5G_3CALTX_SET(x)                                      (((x) << 13) & 0x00002000)
-#define PHY_ANALOG_TXRF10_D3B5GCALTX_MSB                                                                     16
-#define PHY_ANALOG_TXRF10_D3B5GCALTX_LSB                                                                     14
-#define PHY_ANALOG_TXRF10_D3B5GCALTX_MASK                                                            0x0001c000
-#define PHY_ANALOG_TXRF10_D3B5GCALTX_GET(x)                                          (((x) & 0x0001c000) >> 14)
-#define PHY_ANALOG_TXRF10_D3B5GCALTX_SET(x)                                          (((x) << 14) & 0x0001c000)
-#define PHY_ANALOG_TXRF10_D4B5GCALTX_MSB                                                                     19
-#define PHY_ANALOG_TXRF10_D4B5GCALTX_LSB                                                                     17
-#define PHY_ANALOG_TXRF10_D4B5GCALTX_MASK                                                            0x000e0000
-#define PHY_ANALOG_TXRF10_D4B5GCALTX_GET(x)                                          (((x) & 0x000e0000) >> 17)
-#define PHY_ANALOG_TXRF10_D4B5GCALTX_SET(x)                                          (((x) << 17) & 0x000e0000)
-#define PHY_ANALOG_TXRF10_PADRVGN2GCALTX_MSB                                                                 26
-#define PHY_ANALOG_TXRF10_PADRVGN2GCALTX_LSB                                                                 20
-#define PHY_ANALOG_TXRF10_PADRVGN2GCALTX_MASK                                                        0x07f00000
-#define PHY_ANALOG_TXRF10_PADRVGN2GCALTX_GET(x)                                      (((x) & 0x07f00000) >> 20)
-#define PHY_ANALOG_TXRF10_PADRVGN2GCALTX_SET(x)                                      (((x) << 20) & 0x07f00000)
-#define PHY_ANALOG_TXRF10_DB2GCALTX_MSB                                                                      29
-#define PHY_ANALOG_TXRF10_DB2GCALTX_LSB                                                                      27
-#define PHY_ANALOG_TXRF10_DB2GCALTX_MASK                                                             0x38000000
-#define PHY_ANALOG_TXRF10_DB2GCALTX_GET(x)                                           (((x) & 0x38000000) >> 27)
-#define PHY_ANALOG_TXRF10_DB2GCALTX_SET(x)                                           (((x) << 27) & 0x38000000)
-#define PHY_ANALOG_TXRF10_CALTXSHIFT_MSB                                                                     30
-#define PHY_ANALOG_TXRF10_CALTXSHIFT_LSB                                                                     30
-#define PHY_ANALOG_TXRF10_CALTXSHIFT_MASK                                                            0x40000000
-#define PHY_ANALOG_TXRF10_CALTXSHIFT_GET(x)                                          (((x) & 0x40000000) >> 30)
-#define PHY_ANALOG_TXRF10_CALTXSHIFT_SET(x)                                          (((x) << 30) & 0x40000000)
-#define PHY_ANALOG_TXRF10_CALTXSHIFTOVR_MSB                                                                  31
-#define PHY_ANALOG_TXRF10_CALTXSHIFTOVR_LSB                                                                  31
-#define PHY_ANALOG_TXRF10_CALTXSHIFTOVR_MASK                                                         0x80000000
-#define PHY_ANALOG_TXRF10_CALTXSHIFTOVR_GET(x)                                       (((x) & 0x80000000) >> 31)
-#define PHY_ANALOG_TXRF10_CALTXSHIFTOVR_SET(x)                                       (((x) << 31) & 0x80000000)
-
-/* macros for TXRF11 */
-#define PHY_ANALOG_TXRF11_ADDRESS                                                                    0x00000068
-#define PHY_ANALOG_TXRF11_OFFSET                                                                     0x00000068
-#define PHY_ANALOG_TXRF11_SPARE11_MSB                                                                         1
-#define PHY_ANALOG_TXRF11_SPARE11_LSB                                                                         0
-#define PHY_ANALOG_TXRF11_SPARE11_MASK                                                               0x00000003
-#define PHY_ANALOG_TXRF11_SPARE11_GET(x)                                              (((x) & 0x00000003) >> 0)
-#define PHY_ANALOG_TXRF11_SPARE11_SET(x)                                              (((x) << 0) & 0x00000003)
-#define PHY_ANALOG_TXRF11_PWD_IR25MIXBIAS5G_MSB                                                               4
-#define PHY_ANALOG_TXRF11_PWD_IR25MIXBIAS5G_LSB                                                               2
-#define PHY_ANALOG_TXRF11_PWD_IR25MIXBIAS5G_MASK                                                     0x0000001c
-#define PHY_ANALOG_TXRF11_PWD_IR25MIXBIAS5G_GET(x)                                    (((x) & 0x0000001c) >> 2)
-#define PHY_ANALOG_TXRF11_PWD_IR25MIXBIAS5G_SET(x)                                    (((x) << 2) & 0x0000001c)
-#define PHY_ANALOG_TXRF11_PWD_IR25MIXDIV5G_MSB                                                                7
-#define PHY_ANALOG_TXRF11_PWD_IR25MIXDIV5G_LSB                                                                5
-#define PHY_ANALOG_TXRF11_PWD_IR25MIXDIV5G_MASK                                                      0x000000e0
-#define PHY_ANALOG_TXRF11_PWD_IR25MIXDIV5G_GET(x)                                     (((x) & 0x000000e0) >> 5)
-#define PHY_ANALOG_TXRF11_PWD_IR25MIXDIV5G_SET(x)                                     (((x) << 5) & 0x000000e0)
-#define PHY_ANALOG_TXRF11_PWD_IR25PA2G_MSB                                                                   10
-#define PHY_ANALOG_TXRF11_PWD_IR25PA2G_LSB                                                                    8
-#define PHY_ANALOG_TXRF11_PWD_IR25PA2G_MASK                                                          0x00000700
-#define PHY_ANALOG_TXRF11_PWD_IR25PA2G_GET(x)                                         (((x) & 0x00000700) >> 8)
-#define PHY_ANALOG_TXRF11_PWD_IR25PA2G_SET(x)                                         (((x) << 8) & 0x00000700)
-#define PHY_ANALOG_TXRF11_PWD_IR25MIXBIAS2G_MSB                                                              13
-#define PHY_ANALOG_TXRF11_PWD_IR25MIXBIAS2G_LSB                                                              11
-#define PHY_ANALOG_TXRF11_PWD_IR25MIXBIAS2G_MASK                                                     0x00003800
-#define PHY_ANALOG_TXRF11_PWD_IR25MIXBIAS2G_GET(x)                                   (((x) & 0x00003800) >> 11)
-#define PHY_ANALOG_TXRF11_PWD_IR25MIXBIAS2G_SET(x)                                   (((x) << 11) & 0x00003800)
-#define PHY_ANALOG_TXRF11_PWD_IR25MIXDIV2G_MSB                                                               16
-#define PHY_ANALOG_TXRF11_PWD_IR25MIXDIV2G_LSB                                                               14
-#define PHY_ANALOG_TXRF11_PWD_IR25MIXDIV2G_MASK                                                      0x0001c000
-#define PHY_ANALOG_TXRF11_PWD_IR25MIXDIV2G_GET(x)                                    (((x) & 0x0001c000) >> 14)
-#define PHY_ANALOG_TXRF11_PWD_IR25MIXDIV2G_SET(x)                                    (((x) << 14) & 0x0001c000)
-#define PHY_ANALOG_TXRF11_PWD_ICSPARE_MSB                                                                    19
-#define PHY_ANALOG_TXRF11_PWD_ICSPARE_LSB                                                                    17
-#define PHY_ANALOG_TXRF11_PWD_ICSPARE_MASK                                                           0x000e0000
-#define PHY_ANALOG_TXRF11_PWD_ICSPARE_GET(x)                                         (((x) & 0x000e0000) >> 17)
-#define PHY_ANALOG_TXRF11_PWD_ICSPARE_SET(x)                                         (((x) << 17) & 0x000e0000)
-#define PHY_ANALOG_TXRF11_PWD_IC25PA5G2_MSB                                                                  22
-#define PHY_ANALOG_TXRF11_PWD_IC25PA5G2_LSB                                                                  20
-#define PHY_ANALOG_TXRF11_PWD_IC25PA5G2_MASK                                                         0x00700000
-#define PHY_ANALOG_TXRF11_PWD_IC25PA5G2_GET(x)                                       (((x) & 0x00700000) >> 20)
-#define PHY_ANALOG_TXRF11_PWD_IC25PA5G2_SET(x)                                       (((x) << 20) & 0x00700000)
-#define PHY_ANALOG_TXRF11_PWD_IC25PA5G1_MSB                                                                  25
-#define PHY_ANALOG_TXRF11_PWD_IC25PA5G1_LSB                                                                  23
-#define PHY_ANALOG_TXRF11_PWD_IC25PA5G1_MASK                                                         0x03800000
-#define PHY_ANALOG_TXRF11_PWD_IC25PA5G1_GET(x)                                       (((x) & 0x03800000) >> 23)
-#define PHY_ANALOG_TXRF11_PWD_IC25PA5G1_SET(x)                                       (((x) << 23) & 0x03800000)
-#define PHY_ANALOG_TXRF11_PWD_IC25MIXBUF5G_MSB                                                               28
-#define PHY_ANALOG_TXRF11_PWD_IC25MIXBUF5G_LSB                                                               26
-#define PHY_ANALOG_TXRF11_PWD_IC25MIXBUF5G_MASK                                                      0x1c000000
-#define PHY_ANALOG_TXRF11_PWD_IC25MIXBUF5G_GET(x)                                    (((x) & 0x1c000000) >> 26)
-#define PHY_ANALOG_TXRF11_PWD_IC25MIXBUF5G_SET(x)                                    (((x) << 26) & 0x1c000000)
-#define PHY_ANALOG_TXRF11_PWD_IC25PA2G_MSB                                                                   31
-#define PHY_ANALOG_TXRF11_PWD_IC25PA2G_LSB                                                                   29
-#define PHY_ANALOG_TXRF11_PWD_IC25PA2G_MASK                                                          0xe0000000
-#define PHY_ANALOG_TXRF11_PWD_IC25PA2G_GET(x)                                        (((x) & 0xe0000000) >> 29)
-#define PHY_ANALOG_TXRF11_PWD_IC25PA2G_SET(x)                                        (((x) << 29) & 0xe0000000)
-
-/* macros for TXRF12 */
-#define PHY_ANALOG_TXRF12_ADDRESS                                                                    0x0000006c
-#define PHY_ANALOG_TXRF12_OFFSET                                                                     0x0000006c
-#define PHY_ANALOG_TXRF12_SPARE12_2_MSB                                                                       7
-#define PHY_ANALOG_TXRF12_SPARE12_2_LSB                                                                       0
-#define PHY_ANALOG_TXRF12_SPARE12_2_MASK                                                             0x000000ff
-#define PHY_ANALOG_TXRF12_SPARE12_2_GET(x)                                            (((x) & 0x000000ff) >> 0)
-#define PHY_ANALOG_TXRF12_SPARE12_1_MSB                                                                      15
-#define PHY_ANALOG_TXRF12_SPARE12_1_LSB                                                                       8
-#define PHY_ANALOG_TXRF12_SPARE12_1_MASK                                                             0x0000ff00
-#define PHY_ANALOG_TXRF12_SPARE12_1_GET(x)                                            (((x) & 0x0000ff00) >> 8)
-#define PHY_ANALOG_TXRF12_SPARE12_1_SET(x)                                            (((x) << 8) & 0x0000ff00)
-#define PHY_ANALOG_TXRF12_ATBSEL5G_MSB                                                                       19
-#define PHY_ANALOG_TXRF12_ATBSEL5G_LSB                                                                       16
-#define PHY_ANALOG_TXRF12_ATBSEL5G_MASK                                                              0x000f0000
-#define PHY_ANALOG_TXRF12_ATBSEL5G_GET(x)                                            (((x) & 0x000f0000) >> 16)
-#define PHY_ANALOG_TXRF12_ATBSEL5G_SET(x)                                            (((x) << 16) & 0x000f0000)
-#define PHY_ANALOG_TXRF12_ATBSEL2G_MSB                                                                       22
-#define PHY_ANALOG_TXRF12_ATBSEL2G_LSB                                                                       20
-#define PHY_ANALOG_TXRF12_ATBSEL2G_MASK                                                              0x00700000
-#define PHY_ANALOG_TXRF12_ATBSEL2G_GET(x)                                            (((x) & 0x00700000) >> 20)
-#define PHY_ANALOG_TXRF12_ATBSEL2G_SET(x)                                            (((x) << 20) & 0x00700000)
-#define PHY_ANALOG_TXRF12_PWD_IRSPARE_MSB                                                                    25
-#define PHY_ANALOG_TXRF12_PWD_IRSPARE_LSB                                                                    23
-#define PHY_ANALOG_TXRF12_PWD_IRSPARE_MASK                                                           0x03800000
-#define PHY_ANALOG_TXRF12_PWD_IRSPARE_GET(x)                                         (((x) & 0x03800000) >> 23)
-#define PHY_ANALOG_TXRF12_PWD_IRSPARE_SET(x)                                         (((x) << 23) & 0x03800000)
-#define PHY_ANALOG_TXRF12_PWD_IR25PA5G2_MSB                                                                  28
-#define PHY_ANALOG_TXRF12_PWD_IR25PA5G2_LSB                                                                  26
-#define PHY_ANALOG_TXRF12_PWD_IR25PA5G2_MASK                                                         0x1c000000
-#define PHY_ANALOG_TXRF12_PWD_IR25PA5G2_GET(x)                                       (((x) & 0x1c000000) >> 26)
-#define PHY_ANALOG_TXRF12_PWD_IR25PA5G2_SET(x)                                       (((x) << 26) & 0x1c000000)
-#define PHY_ANALOG_TXRF12_PWD_IR25PA5G1_MSB                                                                  31
-#define PHY_ANALOG_TXRF12_PWD_IR25PA5G1_LSB                                                                  29
-#define PHY_ANALOG_TXRF12_PWD_IR25PA5G1_MASK                                                         0xe0000000
-#define PHY_ANALOG_TXRF12_PWD_IR25PA5G1_GET(x)                                       (((x) & 0xe0000000) >> 29)
-#define PHY_ANALOG_TXRF12_PWD_IR25PA5G1_SET(x)                                       (((x) << 29) & 0xe0000000)
-
-/* macros for SYNTH1 */
-#define PHY_ANALOG_SYNTH1_ADDRESS                                                                    0x00000080
-#define PHY_ANALOG_SYNTH1_OFFSET                                                                     0x00000080
-#define PHY_ANALOG_SYNTH1_SEL_VCMONABUS_MSB                                                                   2
-#define PHY_ANALOG_SYNTH1_SEL_VCMONABUS_LSB                                                                   0
-#define PHY_ANALOG_SYNTH1_SEL_VCMONABUS_MASK                                                         0x00000007
-#define PHY_ANALOG_SYNTH1_SEL_VCMONABUS_GET(x)                                        (((x) & 0x00000007) >> 0)
-#define PHY_ANALOG_SYNTH1_SEL_VCMONABUS_SET(x)                                        (((x) << 0) & 0x00000007)
-#define PHY_ANALOG_SYNTH1_SEL_VCOABUS_MSB                                                                     5
-#define PHY_ANALOG_SYNTH1_SEL_VCOABUS_LSB                                                                     3
-#define PHY_ANALOG_SYNTH1_SEL_VCOABUS_MASK                                                           0x00000038
-#define PHY_ANALOG_SYNTH1_SEL_VCOABUS_GET(x)                                          (((x) & 0x00000038) >> 3)
-#define PHY_ANALOG_SYNTH1_SEL_VCOABUS_SET(x)                                          (((x) << 3) & 0x00000038)
-#define PHY_ANALOG_SYNTH1_MONITOR_SYNTHLOCKVCOK_MSB                                                           6
-#define PHY_ANALOG_SYNTH1_MONITOR_SYNTHLOCKVCOK_LSB                                                           6
-#define PHY_ANALOG_SYNTH1_MONITOR_SYNTHLOCKVCOK_MASK                                                 0x00000040
-#define PHY_ANALOG_SYNTH1_MONITOR_SYNTHLOCKVCOK_GET(x)                                (((x) & 0x00000040) >> 6)
-#define PHY_ANALOG_SYNTH1_MONITOR_SYNTHLOCKVCOK_SET(x)                                (((x) << 6) & 0x00000040)
-#define PHY_ANALOG_SYNTH1_MONITOR_VC2LOW_MSB                                                                  7
-#define PHY_ANALOG_SYNTH1_MONITOR_VC2LOW_LSB                                                                  7
-#define PHY_ANALOG_SYNTH1_MONITOR_VC2LOW_MASK                                                        0x00000080
-#define PHY_ANALOG_SYNTH1_MONITOR_VC2LOW_GET(x)                                       (((x) & 0x00000080) >> 7)
-#define PHY_ANALOG_SYNTH1_MONITOR_VC2LOW_SET(x)                                       (((x) << 7) & 0x00000080)
-#define PHY_ANALOG_SYNTH1_MONITOR_VC2HIGH_MSB                                                                 8
-#define PHY_ANALOG_SYNTH1_MONITOR_VC2HIGH_LSB                                                                 8
-#define PHY_ANALOG_SYNTH1_MONITOR_VC2HIGH_MASK                                                       0x00000100
-#define PHY_ANALOG_SYNTH1_MONITOR_VC2HIGH_GET(x)                                      (((x) & 0x00000100) >> 8)
-#define PHY_ANALOG_SYNTH1_MONITOR_VC2HIGH_SET(x)                                      (((x) << 8) & 0x00000100)
-#define PHY_ANALOG_SYNTH1_MONITOR_FB_DIV2_MSB                                                                 9
-#define PHY_ANALOG_SYNTH1_MONITOR_FB_DIV2_LSB                                                                 9
-#define PHY_ANALOG_SYNTH1_MONITOR_FB_DIV2_MASK                                                       0x00000200
-#define PHY_ANALOG_SYNTH1_MONITOR_FB_DIV2_GET(x)                                      (((x) & 0x00000200) >> 9)
-#define PHY_ANALOG_SYNTH1_MONITOR_FB_DIV2_SET(x)                                      (((x) << 9) & 0x00000200)
-#define PHY_ANALOG_SYNTH1_MONITOR_REF_MSB                                                                    10
-#define PHY_ANALOG_SYNTH1_MONITOR_REF_LSB                                                                    10
-#define PHY_ANALOG_SYNTH1_MONITOR_REF_MASK                                                           0x00000400
-#define PHY_ANALOG_SYNTH1_MONITOR_REF_GET(x)                                         (((x) & 0x00000400) >> 10)
-#define PHY_ANALOG_SYNTH1_MONITOR_REF_SET(x)                                         (((x) << 10) & 0x00000400)
-#define PHY_ANALOG_SYNTH1_MONITOR_FB_MSB                                                                     11
-#define PHY_ANALOG_SYNTH1_MONITOR_FB_LSB                                                                     11
-#define PHY_ANALOG_SYNTH1_MONITOR_FB_MASK                                                            0x00000800
-#define PHY_ANALOG_SYNTH1_MONITOR_FB_GET(x)                                          (((x) & 0x00000800) >> 11)
-#define PHY_ANALOG_SYNTH1_MONITOR_FB_SET(x)                                          (((x) << 11) & 0x00000800)
-#define PHY_ANALOG_SYNTH1_SEVENBITVCOCAP_MSB                                                                 12
-#define PHY_ANALOG_SYNTH1_SEVENBITVCOCAP_LSB                                                                 12
-#define PHY_ANALOG_SYNTH1_SEVENBITVCOCAP_MASK                                                        0x00001000
-#define PHY_ANALOG_SYNTH1_SEVENBITVCOCAP_GET(x)                                      (((x) & 0x00001000) >> 12)
-#define PHY_ANALOG_SYNTH1_SEVENBITVCOCAP_SET(x)                                      (((x) << 12) & 0x00001000)
-#define PHY_ANALOG_SYNTH1_PWUP_PD_MSB                                                                        15
-#define PHY_ANALOG_SYNTH1_PWUP_PD_LSB                                                                        13
-#define PHY_ANALOG_SYNTH1_PWUP_PD_MASK                                                               0x0000e000
-#define PHY_ANALOG_SYNTH1_PWUP_PD_GET(x)                                             (((x) & 0x0000e000) >> 13)
-#define PHY_ANALOG_SYNTH1_PWUP_PD_SET(x)                                             (((x) << 13) & 0x0000e000)
-#define PHY_ANALOG_SYNTH1_PWD_VCOBUF_MSB                                                                     16
-#define PHY_ANALOG_SYNTH1_PWD_VCOBUF_LSB                                                                     16
-#define PHY_ANALOG_SYNTH1_PWD_VCOBUF_MASK                                                            0x00010000
-#define PHY_ANALOG_SYNTH1_PWD_VCOBUF_GET(x)                                          (((x) & 0x00010000) >> 16)
-#define PHY_ANALOG_SYNTH1_PWD_VCOBUF_SET(x)                                          (((x) << 16) & 0x00010000)
-#define PHY_ANALOG_SYNTH1_VCOBUFGAIN_MSB                                                                     18
-#define PHY_ANALOG_SYNTH1_VCOBUFGAIN_LSB                                                                     17
-#define PHY_ANALOG_SYNTH1_VCOBUFGAIN_MASK                                                            0x00060000
-#define PHY_ANALOG_SYNTH1_VCOBUFGAIN_GET(x)                                          (((x) & 0x00060000) >> 17)
-#define PHY_ANALOG_SYNTH1_VCOBUFGAIN_SET(x)                                          (((x) << 17) & 0x00060000)
-#define PHY_ANALOG_SYNTH1_VCOREGLEVEL_MSB                                                                    20
-#define PHY_ANALOG_SYNTH1_VCOREGLEVEL_LSB                                                                    19
-#define PHY_ANALOG_SYNTH1_VCOREGLEVEL_MASK                                                           0x00180000
-#define PHY_ANALOG_SYNTH1_VCOREGLEVEL_GET(x)                                         (((x) & 0x00180000) >> 19)
-#define PHY_ANALOG_SYNTH1_VCOREGLEVEL_SET(x)                                         (((x) << 19) & 0x00180000)
-#define PHY_ANALOG_SYNTH1_VCOREGBYPASS_MSB                                                                   21
-#define PHY_ANALOG_SYNTH1_VCOREGBYPASS_LSB                                                                   21
-#define PHY_ANALOG_SYNTH1_VCOREGBYPASS_MASK                                                          0x00200000
-#define PHY_ANALOG_SYNTH1_VCOREGBYPASS_GET(x)                                        (((x) & 0x00200000) >> 21)
-#define PHY_ANALOG_SYNTH1_VCOREGBYPASS_SET(x)                                        (((x) << 21) & 0x00200000)
-#define PHY_ANALOG_SYNTH1_PWUP_LOREF_MSB                                                                     22
-#define PHY_ANALOG_SYNTH1_PWUP_LOREF_LSB                                                                     22
-#define PHY_ANALOG_SYNTH1_PWUP_LOREF_MASK                                                            0x00400000
-#define PHY_ANALOG_SYNTH1_PWUP_LOREF_GET(x)                                          (((x) & 0x00400000) >> 22)
-#define PHY_ANALOG_SYNTH1_PWUP_LOREF_SET(x)                                          (((x) << 22) & 0x00400000)
-#define PHY_ANALOG_SYNTH1_PWD_LOMIX_MSB                                                                      23
-#define PHY_ANALOG_SYNTH1_PWD_LOMIX_LSB                                                                      23
-#define PHY_ANALOG_SYNTH1_PWD_LOMIX_MASK                                                             0x00800000
-#define PHY_ANALOG_SYNTH1_PWD_LOMIX_GET(x)                                           (((x) & 0x00800000) >> 23)
-#define PHY_ANALOG_SYNTH1_PWD_LOMIX_SET(x)                                           (((x) << 23) & 0x00800000)
-#define PHY_ANALOG_SYNTH1_PWD_LODIV_MSB                                                                      24
-#define PHY_ANALOG_SYNTH1_PWD_LODIV_LSB                                                                      24
-#define PHY_ANALOG_SYNTH1_PWD_LODIV_MASK                                                             0x01000000
-#define PHY_ANALOG_SYNTH1_PWD_LODIV_GET(x)                                           (((x) & 0x01000000) >> 24)
-#define PHY_ANALOG_SYNTH1_PWD_LODIV_SET(x)                                           (((x) << 24) & 0x01000000)
-#define PHY_ANALOG_SYNTH1_PWD_LOBUF5G_MSB                                                                    25
-#define PHY_ANALOG_SYNTH1_PWD_LOBUF5G_LSB                                                                    25
-#define PHY_ANALOG_SYNTH1_PWD_LOBUF5G_MASK                                                           0x02000000
-#define PHY_ANALOG_SYNTH1_PWD_LOBUF5G_GET(x)                                         (((x) & 0x02000000) >> 25)
-#define PHY_ANALOG_SYNTH1_PWD_LOBUF5G_SET(x)                                         (((x) << 25) & 0x02000000)
-#define PHY_ANALOG_SYNTH1_PWD_LOBUF2G_MSB                                                                    26
-#define PHY_ANALOG_SYNTH1_PWD_LOBUF2G_LSB                                                                    26
-#define PHY_ANALOG_SYNTH1_PWD_LOBUF2G_MASK                                                           0x04000000
-#define PHY_ANALOG_SYNTH1_PWD_LOBUF2G_GET(x)                                         (((x) & 0x04000000) >> 26)
-#define PHY_ANALOG_SYNTH1_PWD_LOBUF2G_SET(x)                                         (((x) << 26) & 0x04000000)
-#define PHY_ANALOG_SYNTH1_PWD_PRESC_MSB                                                                      27
-#define PHY_ANALOG_SYNTH1_PWD_PRESC_LSB                                                                      27
-#define PHY_ANALOG_SYNTH1_PWD_PRESC_MASK                                                             0x08000000
-#define PHY_ANALOG_SYNTH1_PWD_PRESC_GET(x)                                           (((x) & 0x08000000) >> 27)
-#define PHY_ANALOG_SYNTH1_PWD_PRESC_SET(x)                                           (((x) << 27) & 0x08000000)
-#define PHY_ANALOG_SYNTH1_PWD_VCO_MSB                                                                        28
-#define PHY_ANALOG_SYNTH1_PWD_VCO_LSB                                                                        28
-#define PHY_ANALOG_SYNTH1_PWD_VCO_MASK                                                               0x10000000
-#define PHY_ANALOG_SYNTH1_PWD_VCO_GET(x)                                             (((x) & 0x10000000) >> 28)
-#define PHY_ANALOG_SYNTH1_PWD_VCO_SET(x)                                             (((x) << 28) & 0x10000000)
-#define PHY_ANALOG_SYNTH1_PWD_VCMON_MSB                                                                      29
-#define PHY_ANALOG_SYNTH1_PWD_VCMON_LSB                                                                      29
-#define PHY_ANALOG_SYNTH1_PWD_VCMON_MASK                                                             0x20000000
-#define PHY_ANALOG_SYNTH1_PWD_VCMON_GET(x)                                           (((x) & 0x20000000) >> 29)
-#define PHY_ANALOG_SYNTH1_PWD_VCMON_SET(x)                                           (((x) << 29) & 0x20000000)
-#define PHY_ANALOG_SYNTH1_PWD_CP_MSB                                                                         30
-#define PHY_ANALOG_SYNTH1_PWD_CP_LSB                                                                         30
-#define PHY_ANALOG_SYNTH1_PWD_CP_MASK                                                                0x40000000
-#define PHY_ANALOG_SYNTH1_PWD_CP_GET(x)                                              (((x) & 0x40000000) >> 30)
-#define PHY_ANALOG_SYNTH1_PWD_CP_SET(x)                                              (((x) << 30) & 0x40000000)
-#define PHY_ANALOG_SYNTH1_PWD_BIAS_MSB                                                                       31
-#define PHY_ANALOG_SYNTH1_PWD_BIAS_LSB                                                                       31
-#define PHY_ANALOG_SYNTH1_PWD_BIAS_MASK                                                              0x80000000
-#define PHY_ANALOG_SYNTH1_PWD_BIAS_GET(x)                                            (((x) & 0x80000000) >> 31)
-#define PHY_ANALOG_SYNTH1_PWD_BIAS_SET(x)                                            (((x) << 31) & 0x80000000)
-
-/* macros for SYNTH2 */
-#define PHY_ANALOG_SYNTH2_ADDRESS                                                                    0x00000084
-#define PHY_ANALOG_SYNTH2_OFFSET                                                                     0x00000084
-#define PHY_ANALOG_SYNTH2_CAPRANGE3_MSB                                                                       3
-#define PHY_ANALOG_SYNTH2_CAPRANGE3_LSB                                                                       0
-#define PHY_ANALOG_SYNTH2_CAPRANGE3_MASK                                                             0x0000000f
-#define PHY_ANALOG_SYNTH2_CAPRANGE3_GET(x)                                            (((x) & 0x0000000f) >> 0)
-#define PHY_ANALOG_SYNTH2_CAPRANGE3_SET(x)                                            (((x) << 0) & 0x0000000f)
-#define PHY_ANALOG_SYNTH2_CAPRANGE2_MSB                                                                       7
-#define PHY_ANALOG_SYNTH2_CAPRANGE2_LSB                                                                       4
-#define PHY_ANALOG_SYNTH2_CAPRANGE2_MASK                                                             0x000000f0
-#define PHY_ANALOG_SYNTH2_CAPRANGE2_GET(x)                                            (((x) & 0x000000f0) >> 4)
-#define PHY_ANALOG_SYNTH2_CAPRANGE2_SET(x)                                            (((x) << 4) & 0x000000f0)
-#define PHY_ANALOG_SYNTH2_CAPRANGE1_MSB                                                                      11
-#define PHY_ANALOG_SYNTH2_CAPRANGE1_LSB                                                                       8
-#define PHY_ANALOG_SYNTH2_CAPRANGE1_MASK                                                             0x00000f00
-#define PHY_ANALOG_SYNTH2_CAPRANGE1_GET(x)                                            (((x) & 0x00000f00) >> 8)
-#define PHY_ANALOG_SYNTH2_CAPRANGE1_SET(x)                                            (((x) << 8) & 0x00000f00)
-#define PHY_ANALOG_SYNTH2_LOOPLEAKCUR_MSB                                                                    15
-#define PHY_ANALOG_SYNTH2_LOOPLEAKCUR_LSB                                                                    12
-#define PHY_ANALOG_SYNTH2_LOOPLEAKCUR_MASK                                                           0x0000f000
-#define PHY_ANALOG_SYNTH2_LOOPLEAKCUR_GET(x)                                         (((x) & 0x0000f000) >> 12)
-#define PHY_ANALOG_SYNTH2_LOOPLEAKCUR_SET(x)                                         (((x) << 12) & 0x0000f000)
-#define PHY_ANALOG_SYNTH2_CPLOWLK_MSB                                                                        16
-#define PHY_ANALOG_SYNTH2_CPLOWLK_LSB                                                                        16
-#define PHY_ANALOG_SYNTH2_CPLOWLK_MASK                                                               0x00010000
-#define PHY_ANALOG_SYNTH2_CPLOWLK_GET(x)                                             (((x) & 0x00010000) >> 16)
-#define PHY_ANALOG_SYNTH2_CPLOWLK_SET(x)                                             (((x) << 16) & 0x00010000)
-#define PHY_ANALOG_SYNTH2_CPSTEERING_EN_INTN_MSB                                                             17
-#define PHY_ANALOG_SYNTH2_CPSTEERING_EN_INTN_LSB                                                             17
-#define PHY_ANALOG_SYNTH2_CPSTEERING_EN_INTN_MASK                                                    0x00020000
-#define PHY_ANALOG_SYNTH2_CPSTEERING_EN_INTN_GET(x)                                  (((x) & 0x00020000) >> 17)
-#define PHY_ANALOG_SYNTH2_CPSTEERING_EN_INTN_SET(x)                                  (((x) << 17) & 0x00020000)
-#define PHY_ANALOG_SYNTH2_CPBIAS_MSB                                                                         19
-#define PHY_ANALOG_SYNTH2_CPBIAS_LSB                                                                         18
-#define PHY_ANALOG_SYNTH2_CPBIAS_MASK                                                                0x000c0000
-#define PHY_ANALOG_SYNTH2_CPBIAS_GET(x)                                              (((x) & 0x000c0000) >> 18)
-#define PHY_ANALOG_SYNTH2_CPBIAS_SET(x)                                              (((x) << 18) & 0x000c0000)
-#define PHY_ANALOG_SYNTH2_VC_LOW_REF_MSB                                                                     22
-#define PHY_ANALOG_SYNTH2_VC_LOW_REF_LSB                                                                     20
-#define PHY_ANALOG_SYNTH2_VC_LOW_REF_MASK                                                            0x00700000
-#define PHY_ANALOG_SYNTH2_VC_LOW_REF_GET(x)                                          (((x) & 0x00700000) >> 20)
-#define PHY_ANALOG_SYNTH2_VC_LOW_REF_SET(x)                                          (((x) << 20) & 0x00700000)
-#define PHY_ANALOG_SYNTH2_VC_MID_REF_MSB                                                                     25
-#define PHY_ANALOG_SYNTH2_VC_MID_REF_LSB                                                                     23
-#define PHY_ANALOG_SYNTH2_VC_MID_REF_MASK                                                            0x03800000
-#define PHY_ANALOG_SYNTH2_VC_MID_REF_GET(x)                                          (((x) & 0x03800000) >> 23)
-#define PHY_ANALOG_SYNTH2_VC_MID_REF_SET(x)                                          (((x) << 23) & 0x03800000)
-#define PHY_ANALOG_SYNTH2_VC_HI_REF_MSB                                                                      28
-#define PHY_ANALOG_SYNTH2_VC_HI_REF_LSB                                                                      26
-#define PHY_ANALOG_SYNTH2_VC_HI_REF_MASK                                                             0x1c000000
-#define PHY_ANALOG_SYNTH2_VC_HI_REF_GET(x)                                           (((x) & 0x1c000000) >> 26)
-#define PHY_ANALOG_SYNTH2_VC_HI_REF_SET(x)                                           (((x) << 26) & 0x1c000000)
-#define PHY_ANALOG_SYNTH2_VC_CAL_REF_MSB                                                                     31
-#define PHY_ANALOG_SYNTH2_VC_CAL_REF_LSB                                                                     29
-#define PHY_ANALOG_SYNTH2_VC_CAL_REF_MASK                                                            0xe0000000
-#define PHY_ANALOG_SYNTH2_VC_CAL_REF_GET(x)                                          (((x) & 0xe0000000) >> 29)
-#define PHY_ANALOG_SYNTH2_VC_CAL_REF_SET(x)                                          (((x) << 29) & 0xe0000000)
-
-/* macros for SYNTH3 */
-#define PHY_ANALOG_SYNTH3_ADDRESS                                                                    0x00000088
-#define PHY_ANALOG_SYNTH3_OFFSET                                                                     0x00000088
-#define PHY_ANALOG_SYNTH3_WAIT_VC_CHECK_MSB                                                                   5
-#define PHY_ANALOG_SYNTH3_WAIT_VC_CHECK_LSB                                                                   0
-#define PHY_ANALOG_SYNTH3_WAIT_VC_CHECK_MASK                                                         0x0000003f
-#define PHY_ANALOG_SYNTH3_WAIT_VC_CHECK_GET(x)                                        (((x) & 0x0000003f) >> 0)
-#define PHY_ANALOG_SYNTH3_WAIT_VC_CHECK_SET(x)                                        (((x) << 0) & 0x0000003f)
-#define PHY_ANALOG_SYNTH3_WAIT_CAL_LIN_MSB                                                                   11
-#define PHY_ANALOG_SYNTH3_WAIT_CAL_LIN_LSB                                                                    6
-#define PHY_ANALOG_SYNTH3_WAIT_CAL_LIN_MASK                                                          0x00000fc0
-#define PHY_ANALOG_SYNTH3_WAIT_CAL_LIN_GET(x)                                         (((x) & 0x00000fc0) >> 6)
-#define PHY_ANALOG_SYNTH3_WAIT_CAL_LIN_SET(x)                                         (((x) << 6) & 0x00000fc0)
-#define PHY_ANALOG_SYNTH3_WAIT_CAL_BIN_MSB                                                                   17
-#define PHY_ANALOG_SYNTH3_WAIT_CAL_BIN_LSB                                                                   12
-#define PHY_ANALOG_SYNTH3_WAIT_CAL_BIN_MASK                                                          0x0003f000
-#define PHY_ANALOG_SYNTH3_WAIT_CAL_BIN_GET(x)                                        (((x) & 0x0003f000) >> 12)
-#define PHY_ANALOG_SYNTH3_WAIT_CAL_BIN_SET(x)                                        (((x) << 12) & 0x0003f000)
-#define PHY_ANALOG_SYNTH3_WAIT_PWRUP_MSB                                                                     23
-#define PHY_ANALOG_SYNTH3_WAIT_PWRUP_LSB                                                                     18
-#define PHY_ANALOG_SYNTH3_WAIT_PWRUP_MASK                                                            0x00fc0000
-#define PHY_ANALOG_SYNTH3_WAIT_PWRUP_GET(x)                                          (((x) & 0x00fc0000) >> 18)
-#define PHY_ANALOG_SYNTH3_WAIT_PWRUP_SET(x)                                          (((x) << 18) & 0x00fc0000)
-#define PHY_ANALOG_SYNTH3_WAIT_SHORTR_PWRUP_MSB                                                              29
-#define PHY_ANALOG_SYNTH3_WAIT_SHORTR_PWRUP_LSB                                                              24
-#define PHY_ANALOG_SYNTH3_WAIT_SHORTR_PWRUP_MASK                                                     0x3f000000
-#define PHY_ANALOG_SYNTH3_WAIT_SHORTR_PWRUP_GET(x)                                   (((x) & 0x3f000000) >> 24)
-#define PHY_ANALOG_SYNTH3_WAIT_SHORTR_PWRUP_SET(x)                                   (((x) << 24) & 0x3f000000)
-#define PHY_ANALOG_SYNTH3_SEL_CLK_DIV2_MSB                                                                   30
-#define PHY_ANALOG_SYNTH3_SEL_CLK_DIV2_LSB                                                                   30
-#define PHY_ANALOG_SYNTH3_SEL_CLK_DIV2_MASK                                                          0x40000000
-#define PHY_ANALOG_SYNTH3_SEL_CLK_DIV2_GET(x)                                        (((x) & 0x40000000) >> 30)
-#define PHY_ANALOG_SYNTH3_SEL_CLK_DIV2_SET(x)                                        (((x) << 30) & 0x40000000)
-#define PHY_ANALOG_SYNTH3_DIS_CLK_XTAL_MSB                                                                   31
-#define PHY_ANALOG_SYNTH3_DIS_CLK_XTAL_LSB                                                                   31
-#define PHY_ANALOG_SYNTH3_DIS_CLK_XTAL_MASK                                                          0x80000000
-#define PHY_ANALOG_SYNTH3_DIS_CLK_XTAL_GET(x)                                        (((x) & 0x80000000) >> 31)
-#define PHY_ANALOG_SYNTH3_DIS_CLK_XTAL_SET(x)                                        (((x) << 31) & 0x80000000)
-
-/* macros for SYNTH4 */
-#define PHY_ANALOG_SYNTH4_ADDRESS                                                                    0x0000008c
-#define PHY_ANALOG_SYNTH4_OFFSET                                                                     0x0000008c
-#define PHY_ANALOG_SYNTH4_PS_SINGLE_PULSE_MSB                                                                 0
-#define PHY_ANALOG_SYNTH4_PS_SINGLE_PULSE_LSB                                                                 0
-#define PHY_ANALOG_SYNTH4_PS_SINGLE_PULSE_MASK                                                       0x00000001
-#define PHY_ANALOG_SYNTH4_PS_SINGLE_PULSE_GET(x)                                      (((x) & 0x00000001) >> 0)
-#define PHY_ANALOG_SYNTH4_PS_SINGLE_PULSE_SET(x)                                      (((x) << 0) & 0x00000001)
-#define PHY_ANALOG_SYNTH4_LONGSHIFTSEL_MSB                                                                    1
-#define PHY_ANALOG_SYNTH4_LONGSHIFTSEL_LSB                                                                    1
-#define PHY_ANALOG_SYNTH4_LONGSHIFTSEL_MASK                                                          0x00000002
-#define PHY_ANALOG_SYNTH4_LONGSHIFTSEL_GET(x)                                         (((x) & 0x00000002) >> 1)
-#define PHY_ANALOG_SYNTH4_LONGSHIFTSEL_SET(x)                                         (((x) << 1) & 0x00000002)
-#define PHY_ANALOG_SYNTH4_LOBUF5GTUNE_OVR_MSB                                                                 3
-#define PHY_ANALOG_SYNTH4_LOBUF5GTUNE_OVR_LSB                                                                 2
-#define PHY_ANALOG_SYNTH4_LOBUF5GTUNE_OVR_MASK                                                       0x0000000c
-#define PHY_ANALOG_SYNTH4_LOBUF5GTUNE_OVR_GET(x)                                      (((x) & 0x0000000c) >> 2)
-#define PHY_ANALOG_SYNTH4_LOBUF5GTUNE_OVR_SET(x)                                      (((x) << 2) & 0x0000000c)
-#define PHY_ANALOG_SYNTH4_FORCE_LOBUF5GTUNE_MSB                                                               4
-#define PHY_ANALOG_SYNTH4_FORCE_LOBUF5GTUNE_LSB                                                               4
-#define PHY_ANALOG_SYNTH4_FORCE_LOBUF5GTUNE_MASK                                                     0x00000010
-#define PHY_ANALOG_SYNTH4_FORCE_LOBUF5GTUNE_GET(x)                                    (((x) & 0x00000010) >> 4)
-#define PHY_ANALOG_SYNTH4_FORCE_LOBUF5GTUNE_SET(x)                                    (((x) << 4) & 0x00000010)
-#define PHY_ANALOG_SYNTH4_PSCOUNT_FBSEL_MSB                                                                   5
-#define PHY_ANALOG_SYNTH4_PSCOUNT_FBSEL_LSB                                                                   5
-#define PHY_ANALOG_SYNTH4_PSCOUNT_FBSEL_MASK                                                         0x00000020
-#define PHY_ANALOG_SYNTH4_PSCOUNT_FBSEL_GET(x)                                        (((x) & 0x00000020) >> 5)
-#define PHY_ANALOG_SYNTH4_PSCOUNT_FBSEL_SET(x)                                        (((x) << 5) & 0x00000020)
-#define PHY_ANALOG_SYNTH4_SDM_DITHER_MSB                                                                      7
-#define PHY_ANALOG_SYNTH4_SDM_DITHER_LSB                                                                      6
-#define PHY_ANALOG_SYNTH4_SDM_DITHER_MASK                                                            0x000000c0
-#define PHY_ANALOG_SYNTH4_SDM_DITHER_GET(x)                                           (((x) & 0x000000c0) >> 6)
-#define PHY_ANALOG_SYNTH4_SDM_DITHER_SET(x)                                           (((x) << 6) & 0x000000c0)
-#define PHY_ANALOG_SYNTH4_SDM_MODE_MSB                                                                        8
-#define PHY_ANALOG_SYNTH4_SDM_MODE_LSB                                                                        8
-#define PHY_ANALOG_SYNTH4_SDM_MODE_MASK                                                              0x00000100
-#define PHY_ANALOG_SYNTH4_SDM_MODE_GET(x)                                             (((x) & 0x00000100) >> 8)
-#define PHY_ANALOG_SYNTH4_SDM_MODE_SET(x)                                             (((x) << 8) & 0x00000100)
-#define PHY_ANALOG_SYNTH4_SDM_DISABLE_MSB                                                                     9
-#define PHY_ANALOG_SYNTH4_SDM_DISABLE_LSB                                                                     9
-#define PHY_ANALOG_SYNTH4_SDM_DISABLE_MASK                                                           0x00000200
-#define PHY_ANALOG_SYNTH4_SDM_DISABLE_GET(x)                                          (((x) & 0x00000200) >> 9)
-#define PHY_ANALOG_SYNTH4_SDM_DISABLE_SET(x)                                          (((x) << 9) & 0x00000200)
-#define PHY_ANALOG_SYNTH4_RESET_PRESC_MSB                                                                    10
-#define PHY_ANALOG_SYNTH4_RESET_PRESC_LSB                                                                    10
-#define PHY_ANALOG_SYNTH4_RESET_PRESC_MASK                                                           0x00000400
-#define PHY_ANALOG_SYNTH4_RESET_PRESC_GET(x)                                         (((x) & 0x00000400) >> 10)
-#define PHY_ANALOG_SYNTH4_RESET_PRESC_SET(x)                                         (((x) << 10) & 0x00000400)
-#define PHY_ANALOG_SYNTH4_PRESCSEL_MSB                                                                       12
-#define PHY_ANALOG_SYNTH4_PRESCSEL_LSB                                                                       11
-#define PHY_ANALOG_SYNTH4_PRESCSEL_MASK                                                              0x00001800
-#define PHY_ANALOG_SYNTH4_PRESCSEL_GET(x)                                            (((x) & 0x00001800) >> 11)
-#define PHY_ANALOG_SYNTH4_PRESCSEL_SET(x)                                            (((x) << 11) & 0x00001800)
-#define PHY_ANALOG_SYNTH4_PFD_DISABLE_MSB                                                                    13
-#define PHY_ANALOG_SYNTH4_PFD_DISABLE_LSB                                                                    13
-#define PHY_ANALOG_SYNTH4_PFD_DISABLE_MASK                                                           0x00002000
-#define PHY_ANALOG_SYNTH4_PFD_DISABLE_GET(x)                                         (((x) & 0x00002000) >> 13)
-#define PHY_ANALOG_SYNTH4_PFD_DISABLE_SET(x)                                         (((x) << 13) & 0x00002000)
-#define PHY_ANALOG_SYNTH4_PFDDELAY_FRACN_MSB                                                                 14
-#define PHY_ANALOG_SYNTH4_PFDDELAY_FRACN_LSB                                                                 14
-#define PHY_ANALOG_SYNTH4_PFDDELAY_FRACN_MASK                                                        0x00004000
-#define PHY_ANALOG_SYNTH4_PFDDELAY_FRACN_GET(x)                                      (((x) & 0x00004000) >> 14)
-#define PHY_ANALOG_SYNTH4_PFDDELAY_FRACN_SET(x)                                      (((x) << 14) & 0x00004000)
-#define PHY_ANALOG_SYNTH4_FORCE_LO_ON_MSB                                                                    15
-#define PHY_ANALOG_SYNTH4_FORCE_LO_ON_LSB                                                                    15
-#define PHY_ANALOG_SYNTH4_FORCE_LO_ON_MASK                                                           0x00008000
-#define PHY_ANALOG_SYNTH4_FORCE_LO_ON_GET(x)                                         (((x) & 0x00008000) >> 15)
-#define PHY_ANALOG_SYNTH4_FORCE_LO_ON_SET(x)                                         (((x) << 15) & 0x00008000)
-#define PHY_ANALOG_SYNTH4_CLKXTAL_EDGE_SEL_MSB                                                               16
-#define PHY_ANALOG_SYNTH4_CLKXTAL_EDGE_SEL_LSB                                                               16
-#define PHY_ANALOG_SYNTH4_CLKXTAL_EDGE_SEL_MASK                                                      0x00010000
-#define PHY_ANALOG_SYNTH4_CLKXTAL_EDGE_SEL_GET(x)                                    (((x) & 0x00010000) >> 16)
-#define PHY_ANALOG_SYNTH4_CLKXTAL_EDGE_SEL_SET(x)                                    (((x) << 16) & 0x00010000)
-#define PHY_ANALOG_SYNTH4_VCOCAPPULLUP_MSB                                                                   17
-#define PHY_ANALOG_SYNTH4_VCOCAPPULLUP_LSB                                                                   17
-#define PHY_ANALOG_SYNTH4_VCOCAPPULLUP_MASK                                                          0x00020000
-#define PHY_ANALOG_SYNTH4_VCOCAPPULLUP_GET(x)                                        (((x) & 0x00020000) >> 17)
-#define PHY_ANALOG_SYNTH4_VCOCAPPULLUP_SET(x)                                        (((x) << 17) & 0x00020000)
-#define PHY_ANALOG_SYNTH4_VCOCAP_OVR_MSB                                                                     25
-#define PHY_ANALOG_SYNTH4_VCOCAP_OVR_LSB                                                                     18
-#define PHY_ANALOG_SYNTH4_VCOCAP_OVR_MASK                                                            0x03fc0000
-#define PHY_ANALOG_SYNTH4_VCOCAP_OVR_GET(x)                                          (((x) & 0x03fc0000) >> 18)
-#define PHY_ANALOG_SYNTH4_VCOCAP_OVR_SET(x)                                          (((x) << 18) & 0x03fc0000)
-#define PHY_ANALOG_SYNTH4_FORCE_VCOCAP_MSB                                                                   26
-#define PHY_ANALOG_SYNTH4_FORCE_VCOCAP_LSB                                                                   26
-#define PHY_ANALOG_SYNTH4_FORCE_VCOCAP_MASK                                                          0x04000000
-#define PHY_ANALOG_SYNTH4_FORCE_VCOCAP_GET(x)                                        (((x) & 0x04000000) >> 26)
-#define PHY_ANALOG_SYNTH4_FORCE_VCOCAP_SET(x)                                        (((x) << 26) & 0x04000000)
-#define PHY_ANALOG_SYNTH4_FORCE_PINVC_MSB                                                                    27
-#define PHY_ANALOG_SYNTH4_FORCE_PINVC_LSB                                                                    27
-#define PHY_ANALOG_SYNTH4_FORCE_PINVC_MASK                                                           0x08000000
-#define PHY_ANALOG_SYNTH4_FORCE_PINVC_GET(x)                                         (((x) & 0x08000000) >> 27)
-#define PHY_ANALOG_SYNTH4_FORCE_PINVC_SET(x)                                         (((x) << 27) & 0x08000000)
-#define PHY_ANALOG_SYNTH4_SHORTR_UNTIL_LOCKED_MSB                                                            28
-#define PHY_ANALOG_SYNTH4_SHORTR_UNTIL_LOCKED_LSB                                                            28
-#define PHY_ANALOG_SYNTH4_SHORTR_UNTIL_LOCKED_MASK                                                   0x10000000
-#define PHY_ANALOG_SYNTH4_SHORTR_UNTIL_LOCKED_GET(x)                                 (((x) & 0x10000000) >> 28)
-#define PHY_ANALOG_SYNTH4_SHORTR_UNTIL_LOCKED_SET(x)                                 (((x) << 28) & 0x10000000)
-#define PHY_ANALOG_SYNTH4_ALWAYS_SHORTR_MSB                                                                  29
-#define PHY_ANALOG_SYNTH4_ALWAYS_SHORTR_LSB                                                                  29
-#define PHY_ANALOG_SYNTH4_ALWAYS_SHORTR_MASK                                                         0x20000000
-#define PHY_ANALOG_SYNTH4_ALWAYS_SHORTR_GET(x)                                       (((x) & 0x20000000) >> 29)
-#define PHY_ANALOG_SYNTH4_ALWAYS_SHORTR_SET(x)                                       (((x) << 29) & 0x20000000)
-#define PHY_ANALOG_SYNTH4_DIS_LOSTVC_MSB                                                                     30
-#define PHY_ANALOG_SYNTH4_DIS_LOSTVC_LSB                                                                     30
-#define PHY_ANALOG_SYNTH4_DIS_LOSTVC_MASK                                                            0x40000000
-#define PHY_ANALOG_SYNTH4_DIS_LOSTVC_GET(x)                                          (((x) & 0x40000000) >> 30)
-#define PHY_ANALOG_SYNTH4_DIS_LOSTVC_SET(x)                                          (((x) << 30) & 0x40000000)
-#define PHY_ANALOG_SYNTH4_DIS_LIN_CAPSEARCH_MSB                                                              31
-#define PHY_ANALOG_SYNTH4_DIS_LIN_CAPSEARCH_LSB                                                              31
-#define PHY_ANALOG_SYNTH4_DIS_LIN_CAPSEARCH_MASK                                                     0x80000000
-#define PHY_ANALOG_SYNTH4_DIS_LIN_CAPSEARCH_GET(x)                                   (((x) & 0x80000000) >> 31)
-#define PHY_ANALOG_SYNTH4_DIS_LIN_CAPSEARCH_SET(x)                                   (((x) << 31) & 0x80000000)
-
-/* macros for SYNTH5 */
-#define PHY_ANALOG_SYNTH5_ADDRESS                                                                    0x00000090
-#define PHY_ANALOG_SYNTH5_OFFSET                                                                     0x00000090
-#define PHY_ANALOG_SYNTH5_VCOBIAS_MSB                                                                         1
-#define PHY_ANALOG_SYNTH5_VCOBIAS_LSB                                                                         0
-#define PHY_ANALOG_SYNTH5_VCOBIAS_MASK                                                               0x00000003
-#define PHY_ANALOG_SYNTH5_VCOBIAS_GET(x)                                              (((x) & 0x00000003) >> 0)
-#define PHY_ANALOG_SYNTH5_VCOBIAS_SET(x)                                              (((x) << 0) & 0x00000003)
-#define PHY_ANALOG_SYNTH5_PWDB_ICLOBUF5G50_MSB                                                                4
-#define PHY_ANALOG_SYNTH5_PWDB_ICLOBUF5G50_LSB                                                                2
-#define PHY_ANALOG_SYNTH5_PWDB_ICLOBUF5G50_MASK                                                      0x0000001c
-#define PHY_ANALOG_SYNTH5_PWDB_ICLOBUF5G50_GET(x)                                     (((x) & 0x0000001c) >> 2)
-#define PHY_ANALOG_SYNTH5_PWDB_ICLOBUF5G50_SET(x)                                     (((x) << 2) & 0x0000001c)
-#define PHY_ANALOG_SYNTH5_PWDB_ICLOBUF2G50_MSB                                                                7
-#define PHY_ANALOG_SYNTH5_PWDB_ICLOBUF2G50_LSB                                                                5
-#define PHY_ANALOG_SYNTH5_PWDB_ICLOBUF2G50_MASK                                                      0x000000e0
-#define PHY_ANALOG_SYNTH5_PWDB_ICLOBUF2G50_GET(x)                                     (((x) & 0x000000e0) >> 5)
-#define PHY_ANALOG_SYNTH5_PWDB_ICLOBUF2G50_SET(x)                                     (((x) << 5) & 0x000000e0)
-#define PHY_ANALOG_SYNTH5_PWDB_ICVCO25_MSB                                                                   10
-#define PHY_ANALOG_SYNTH5_PWDB_ICVCO25_LSB                                                                    8
-#define PHY_ANALOG_SYNTH5_PWDB_ICVCO25_MASK                                                          0x00000700
-#define PHY_ANALOG_SYNTH5_PWDB_ICVCO25_GET(x)                                         (((x) & 0x00000700) >> 8)
-#define PHY_ANALOG_SYNTH5_PWDB_ICVCO25_SET(x)                                         (((x) << 8) & 0x00000700)
-#define PHY_ANALOG_SYNTH5_PWDB_ICVCOREG25_MSB                                                                13
-#define PHY_ANALOG_SYNTH5_PWDB_ICVCOREG25_LSB                                                                11
-#define PHY_ANALOG_SYNTH5_PWDB_ICVCOREG25_MASK                                                       0x00003800
-#define PHY_ANALOG_SYNTH5_PWDB_ICVCOREG25_GET(x)                                     (((x) & 0x00003800) >> 11)
-#define PHY_ANALOG_SYNTH5_PWDB_ICVCOREG25_SET(x)                                     (((x) << 11) & 0x00003800)
-#define PHY_ANALOG_SYNTH5_PWDB_IRVCOREG50_MSB                                                                14
-#define PHY_ANALOG_SYNTH5_PWDB_IRVCOREG50_LSB                                                                14
-#define PHY_ANALOG_SYNTH5_PWDB_IRVCOREG50_MASK                                                       0x00004000
-#define PHY_ANALOG_SYNTH5_PWDB_IRVCOREG50_GET(x)                                     (((x) & 0x00004000) >> 14)
-#define PHY_ANALOG_SYNTH5_PWDB_IRVCOREG50_SET(x)                                     (((x) << 14) & 0x00004000)
-#define PHY_ANALOG_SYNTH5_PWDB_ICLOMIX_MSB                                                                   17
-#define PHY_ANALOG_SYNTH5_PWDB_ICLOMIX_LSB                                                                   15
-#define PHY_ANALOG_SYNTH5_PWDB_ICLOMIX_MASK                                                          0x00038000
-#define PHY_ANALOG_SYNTH5_PWDB_ICLOMIX_GET(x)                                        (((x) & 0x00038000) >> 15)
-#define PHY_ANALOG_SYNTH5_PWDB_ICLOMIX_SET(x)                                        (((x) << 15) & 0x00038000)
-#define PHY_ANALOG_SYNTH5_PWDB_ICLODIV50_MSB                                                                 20
-#define PHY_ANALOG_SYNTH5_PWDB_ICLODIV50_LSB                                                                 18
-#define PHY_ANALOG_SYNTH5_PWDB_ICLODIV50_MASK                                                        0x001c0000
-#define PHY_ANALOG_SYNTH5_PWDB_ICLODIV50_GET(x)                                      (((x) & 0x001c0000) >> 18)
-#define PHY_ANALOG_SYNTH5_PWDB_ICLODIV50_SET(x)                                      (((x) << 18) & 0x001c0000)
-#define PHY_ANALOG_SYNTH5_PWDB_ICPRESC50_MSB                                                                 23
-#define PHY_ANALOG_SYNTH5_PWDB_ICPRESC50_LSB                                                                 21
-#define PHY_ANALOG_SYNTH5_PWDB_ICPRESC50_MASK                                                        0x00e00000
-#define PHY_ANALOG_SYNTH5_PWDB_ICPRESC50_GET(x)                                      (((x) & 0x00e00000) >> 21)
-#define PHY_ANALOG_SYNTH5_PWDB_ICPRESC50_SET(x)                                      (((x) << 21) & 0x00e00000)
-#define PHY_ANALOG_SYNTH5_PWDB_IRVCMON25_MSB                                                                 26
-#define PHY_ANALOG_SYNTH5_PWDB_IRVCMON25_LSB                                                                 24
-#define PHY_ANALOG_SYNTH5_PWDB_IRVCMON25_MASK                                                        0x07000000
-#define PHY_ANALOG_SYNTH5_PWDB_IRVCMON25_GET(x)                                      (((x) & 0x07000000) >> 24)
-#define PHY_ANALOG_SYNTH5_PWDB_IRVCMON25_SET(x)                                      (((x) << 24) & 0x07000000)
-#define PHY_ANALOG_SYNTH5_PWDB_IRPFDCP_MSB                                                                   29
-#define PHY_ANALOG_SYNTH5_PWDB_IRPFDCP_LSB                                                                   27
-#define PHY_ANALOG_SYNTH5_PWDB_IRPFDCP_MASK                                                          0x38000000
-#define PHY_ANALOG_SYNTH5_PWDB_IRPFDCP_GET(x)                                        (((x) & 0x38000000) >> 27)
-#define PHY_ANALOG_SYNTH5_PWDB_IRPFDCP_SET(x)                                        (((x) << 27) & 0x38000000)
-#define PHY_ANALOG_SYNTH5_SPARE5A_MSB                                                                        31
-#define PHY_ANALOG_SYNTH5_SPARE5A_LSB                                                                        30
-#define PHY_ANALOG_SYNTH5_SPARE5A_MASK                                                               0xc0000000
-#define PHY_ANALOG_SYNTH5_SPARE5A_GET(x)                                             (((x) & 0xc0000000) >> 30)
-#define PHY_ANALOG_SYNTH5_SPARE5A_SET(x)                                             (((x) << 30) & 0xc0000000)
-
-/* macros for SYNTH6 */
-#define PHY_ANALOG_SYNTH6_ADDRESS                                                                    0x00000094
-#define PHY_ANALOG_SYNTH6_OFFSET                                                                     0x00000094
-#define PHY_ANALOG_SYNTH6_LOBUF5GTUNE_MSB                                                                     1
-#define PHY_ANALOG_SYNTH6_LOBUF5GTUNE_LSB                                                                     0
-#define PHY_ANALOG_SYNTH6_LOBUF5GTUNE_MASK                                                           0x00000003
-#define PHY_ANALOG_SYNTH6_LOBUF5GTUNE_GET(x)                                          (((x) & 0x00000003) >> 0)
-#define PHY_ANALOG_SYNTH6_LOOP_IP_MSB                                                                         8
-#define PHY_ANALOG_SYNTH6_LOOP_IP_LSB                                                                         2
-#define PHY_ANALOG_SYNTH6_LOOP_IP_MASK                                                               0x000001fc
-#define PHY_ANALOG_SYNTH6_LOOP_IP_GET(x)                                              (((x) & 0x000001fc) >> 2)
-#define PHY_ANALOG_SYNTH6_VC2LOW_MSB                                                                          9
-#define PHY_ANALOG_SYNTH6_VC2LOW_LSB                                                                          9
-#define PHY_ANALOG_SYNTH6_VC2LOW_MASK                                                                0x00000200
-#define PHY_ANALOG_SYNTH6_VC2LOW_GET(x)                                               (((x) & 0x00000200) >> 9)
-#define PHY_ANALOG_SYNTH6_VC2HIGH_MSB                                                                        10
-#define PHY_ANALOG_SYNTH6_VC2HIGH_LSB                                                                        10
-#define PHY_ANALOG_SYNTH6_VC2HIGH_MASK                                                               0x00000400
-#define PHY_ANALOG_SYNTH6_VC2HIGH_GET(x)                                             (((x) & 0x00000400) >> 10)
-#define PHY_ANALOG_SYNTH6_RESET_SDM_B_MSB                                                                    11
-#define PHY_ANALOG_SYNTH6_RESET_SDM_B_LSB                                                                    11
-#define PHY_ANALOG_SYNTH6_RESET_SDM_B_MASK                                                           0x00000800
-#define PHY_ANALOG_SYNTH6_RESET_SDM_B_GET(x)                                         (((x) & 0x00000800) >> 11)
-#define PHY_ANALOG_SYNTH6_RESET_PSCOUNTERS_MSB                                                               12
-#define PHY_ANALOG_SYNTH6_RESET_PSCOUNTERS_LSB                                                               12
-#define PHY_ANALOG_SYNTH6_RESET_PSCOUNTERS_MASK                                                      0x00001000
-#define PHY_ANALOG_SYNTH6_RESET_PSCOUNTERS_GET(x)                                    (((x) & 0x00001000) >> 12)
-#define PHY_ANALOG_SYNTH6_RESET_PFD_MSB                                                                      13
-#define PHY_ANALOG_SYNTH6_RESET_PFD_LSB                                                                      13
-#define PHY_ANALOG_SYNTH6_RESET_PFD_MASK                                                             0x00002000
-#define PHY_ANALOG_SYNTH6_RESET_PFD_GET(x)                                           (((x) & 0x00002000) >> 13)
-#define PHY_ANALOG_SYNTH6_RESET_RFD_MSB                                                                      14
-#define PHY_ANALOG_SYNTH6_RESET_RFD_LSB                                                                      14
-#define PHY_ANALOG_SYNTH6_RESET_RFD_MASK                                                             0x00004000
-#define PHY_ANALOG_SYNTH6_RESET_RFD_GET(x)                                           (((x) & 0x00004000) >> 14)
-#define PHY_ANALOG_SYNTH6_SHORT_R_MSB                                                                        15
-#define PHY_ANALOG_SYNTH6_SHORT_R_LSB                                                                        15
-#define PHY_ANALOG_SYNTH6_SHORT_R_MASK                                                               0x00008000
-#define PHY_ANALOG_SYNTH6_SHORT_R_GET(x)                                             (((x) & 0x00008000) >> 15)
-#define PHY_ANALOG_SYNTH6_VCO_CAP_ST_MSB                                                                     23
-#define PHY_ANALOG_SYNTH6_VCO_CAP_ST_LSB                                                                     16
-#define PHY_ANALOG_SYNTH6_VCO_CAP_ST_MASK                                                            0x00ff0000
-#define PHY_ANALOG_SYNTH6_VCO_CAP_ST_GET(x)                                          (((x) & 0x00ff0000) >> 16)
-#define PHY_ANALOG_SYNTH6_PIN_VC_MSB                                                                         24
-#define PHY_ANALOG_SYNTH6_PIN_VC_LSB                                                                         24
-#define PHY_ANALOG_SYNTH6_PIN_VC_MASK                                                                0x01000000
-#define PHY_ANALOG_SYNTH6_PIN_VC_GET(x)                                              (((x) & 0x01000000) >> 24)
-#define PHY_ANALOG_SYNTH6_SYNTH_LOCK_VC_OK_MSB                                                               25
-#define PHY_ANALOG_SYNTH6_SYNTH_LOCK_VC_OK_LSB                                                               25
-#define PHY_ANALOG_SYNTH6_SYNTH_LOCK_VC_OK_MASK                                                      0x02000000
-#define PHY_ANALOG_SYNTH6_SYNTH_LOCK_VC_OK_GET(x)                                    (((x) & 0x02000000) >> 25)
-#define PHY_ANALOG_SYNTH6_CAP_SEARCH_MSB                                                                     26
-#define PHY_ANALOG_SYNTH6_CAP_SEARCH_LSB                                                                     26
-#define PHY_ANALOG_SYNTH6_CAP_SEARCH_MASK                                                            0x04000000
-#define PHY_ANALOG_SYNTH6_CAP_SEARCH_GET(x)                                          (((x) & 0x04000000) >> 26)
-#define PHY_ANALOG_SYNTH6_SYNTH_SM_STATE_MSB                                                                 30
-#define PHY_ANALOG_SYNTH6_SYNTH_SM_STATE_LSB                                                                 27
-#define PHY_ANALOG_SYNTH6_SYNTH_SM_STATE_MASK                                                        0x78000000
-#define PHY_ANALOG_SYNTH6_SYNTH_SM_STATE_GET(x)                                      (((x) & 0x78000000) >> 27)
-#define PHY_ANALOG_SYNTH6_SYNTH_ON_MSB                                                                       31
-#define PHY_ANALOG_SYNTH6_SYNTH_ON_LSB                                                                       31
-#define PHY_ANALOG_SYNTH6_SYNTH_ON_MASK                                                              0x80000000
-#define PHY_ANALOG_SYNTH6_SYNTH_ON_GET(x)                                            (((x) & 0x80000000) >> 31)
-
-/* macros for SYNTH7 */
-#define PHY_ANALOG_SYNTH7_ADDRESS                                                                    0x00000098
-#define PHY_ANALOG_SYNTH7_OFFSET                                                                     0x00000098
-#define PHY_ANALOG_SYNTH7_OVRCHANDECODER_MSB                                                                  0
-#define PHY_ANALOG_SYNTH7_OVRCHANDECODER_LSB                                                                  0
-#define PHY_ANALOG_SYNTH7_OVRCHANDECODER_MASK                                                        0x00000001
-#define PHY_ANALOG_SYNTH7_OVRCHANDECODER_GET(x)                                       (((x) & 0x00000001) >> 0)
-#define PHY_ANALOG_SYNTH7_OVRCHANDECODER_SET(x)                                       (((x) << 0) & 0x00000001)
-#define PHY_ANALOG_SYNTH7_FORCE_FRACLSB_MSB                                                                   1
-#define PHY_ANALOG_SYNTH7_FORCE_FRACLSB_LSB                                                                   1
-#define PHY_ANALOG_SYNTH7_FORCE_FRACLSB_MASK                                                         0x00000002
-#define PHY_ANALOG_SYNTH7_FORCE_FRACLSB_GET(x)                                        (((x) & 0x00000002) >> 1)
-#define PHY_ANALOG_SYNTH7_FORCE_FRACLSB_SET(x)                                        (((x) << 1) & 0x00000002)
-#define PHY_ANALOG_SYNTH7_CHANFRAC_MSB                                                                       18
-#define PHY_ANALOG_SYNTH7_CHANFRAC_LSB                                                                        2
-#define PHY_ANALOG_SYNTH7_CHANFRAC_MASK                                                              0x0007fffc
-#define PHY_ANALOG_SYNTH7_CHANFRAC_GET(x)                                             (((x) & 0x0007fffc) >> 2)
-#define PHY_ANALOG_SYNTH7_CHANFRAC_SET(x)                                             (((x) << 2) & 0x0007fffc)
-#define PHY_ANALOG_SYNTH7_CHANSEL_MSB                                                                        27
-#define PHY_ANALOG_SYNTH7_CHANSEL_LSB                                                                        19
-#define PHY_ANALOG_SYNTH7_CHANSEL_MASK                                                               0x0ff80000
-#define PHY_ANALOG_SYNTH7_CHANSEL_GET(x)                                             (((x) & 0x0ff80000) >> 19)
-#define PHY_ANALOG_SYNTH7_CHANSEL_SET(x)                                             (((x) << 19) & 0x0ff80000)
-#define PHY_ANALOG_SYNTH7_AMODEREFSEL_MSB                                                                    29
-#define PHY_ANALOG_SYNTH7_AMODEREFSEL_LSB                                                                    28
-#define PHY_ANALOG_SYNTH7_AMODEREFSEL_MASK                                                           0x30000000
-#define PHY_ANALOG_SYNTH7_AMODEREFSEL_GET(x)                                         (((x) & 0x30000000) >> 28)
-#define PHY_ANALOG_SYNTH7_AMODEREFSEL_SET(x)                                         (((x) << 28) & 0x30000000)
-#define PHY_ANALOG_SYNTH7_FRACMODE_MSB                                                                       30
-#define PHY_ANALOG_SYNTH7_FRACMODE_LSB                                                                       30
-#define PHY_ANALOG_SYNTH7_FRACMODE_MASK                                                              0x40000000
-#define PHY_ANALOG_SYNTH7_FRACMODE_GET(x)                                            (((x) & 0x40000000) >> 30)
-#define PHY_ANALOG_SYNTH7_FRACMODE_SET(x)                                            (((x) << 30) & 0x40000000)
-#define PHY_ANALOG_SYNTH7_LOADSYNTHCHANNEL_MSB                                                               31
-#define PHY_ANALOG_SYNTH7_LOADSYNTHCHANNEL_LSB                                                               31
-#define PHY_ANALOG_SYNTH7_LOADSYNTHCHANNEL_MASK                                                      0x80000000
-#define PHY_ANALOG_SYNTH7_LOADSYNTHCHANNEL_GET(x)                                    (((x) & 0x80000000) >> 31)
-#define PHY_ANALOG_SYNTH7_LOADSYNTHCHANNEL_SET(x)                                    (((x) << 31) & 0x80000000)
-
-/* macros for SYNTH8 */
-#define PHY_ANALOG_SYNTH8_ADDRESS                                                                    0x0000009c
-#define PHY_ANALOG_SYNTH8_OFFSET                                                                     0x0000009c
-#define PHY_ANALOG_SYNTH8_CPSTEERING_EN_FRACN_MSB                                                             0
-#define PHY_ANALOG_SYNTH8_CPSTEERING_EN_FRACN_LSB                                                             0
-#define PHY_ANALOG_SYNTH8_CPSTEERING_EN_FRACN_MASK                                                   0x00000001
-#define PHY_ANALOG_SYNTH8_CPSTEERING_EN_FRACN_GET(x)                                  (((x) & 0x00000001) >> 0)
-#define PHY_ANALOG_SYNTH8_CPSTEERING_EN_FRACN_SET(x)                                  (((x) << 0) & 0x00000001)
-#define PHY_ANALOG_SYNTH8_LOOP_ICPB_MSB                                                                       7
-#define PHY_ANALOG_SYNTH8_LOOP_ICPB_LSB                                                                       1
-#define PHY_ANALOG_SYNTH8_LOOP_ICPB_MASK                                                             0x000000fe
-#define PHY_ANALOG_SYNTH8_LOOP_ICPB_GET(x)                                            (((x) & 0x000000fe) >> 1)
-#define PHY_ANALOG_SYNTH8_LOOP_ICPB_SET(x)                                            (((x) << 1) & 0x000000fe)
-#define PHY_ANALOG_SYNTH8_LOOP_CSB_MSB                                                                       11
-#define PHY_ANALOG_SYNTH8_LOOP_CSB_LSB                                                                        8
-#define PHY_ANALOG_SYNTH8_LOOP_CSB_MASK                                                              0x00000f00
-#define PHY_ANALOG_SYNTH8_LOOP_CSB_GET(x)                                             (((x) & 0x00000f00) >> 8)
-#define PHY_ANALOG_SYNTH8_LOOP_CSB_SET(x)                                             (((x) << 8) & 0x00000f00)
-#define PHY_ANALOG_SYNTH8_LOOP_RSB_MSB                                                                       16
-#define PHY_ANALOG_SYNTH8_LOOP_RSB_LSB                                                                       12
-#define PHY_ANALOG_SYNTH8_LOOP_RSB_MASK                                                              0x0001f000
-#define PHY_ANALOG_SYNTH8_LOOP_RSB_GET(x)                                            (((x) & 0x0001f000) >> 12)
-#define PHY_ANALOG_SYNTH8_LOOP_RSB_SET(x)                                            (((x) << 12) & 0x0001f000)
-#define PHY_ANALOG_SYNTH8_LOOP_CPB_MSB                                                                       21
-#define PHY_ANALOG_SYNTH8_LOOP_CPB_LSB                                                                       17
-#define PHY_ANALOG_SYNTH8_LOOP_CPB_MASK                                                              0x003e0000
-#define PHY_ANALOG_SYNTH8_LOOP_CPB_GET(x)                                            (((x) & 0x003e0000) >> 17)
-#define PHY_ANALOG_SYNTH8_LOOP_CPB_SET(x)                                            (((x) << 17) & 0x003e0000)
-#define PHY_ANALOG_SYNTH8_LOOP_3RD_ORDER_RB_MSB                                                              26
-#define PHY_ANALOG_SYNTH8_LOOP_3RD_ORDER_RB_LSB                                                              22
-#define PHY_ANALOG_SYNTH8_LOOP_3RD_ORDER_RB_MASK                                                     0x07c00000
-#define PHY_ANALOG_SYNTH8_LOOP_3RD_ORDER_RB_GET(x)                                   (((x) & 0x07c00000) >> 22)
-#define PHY_ANALOG_SYNTH8_LOOP_3RD_ORDER_RB_SET(x)                                   (((x) << 22) & 0x07c00000)
-#define PHY_ANALOG_SYNTH8_REFDIVB_MSB                                                                        31
-#define PHY_ANALOG_SYNTH8_REFDIVB_LSB                                                                        27
-#define PHY_ANALOG_SYNTH8_REFDIVB_MASK                                                               0xf8000000
-#define PHY_ANALOG_SYNTH8_REFDIVB_GET(x)                                             (((x) & 0xf8000000) >> 27)
-#define PHY_ANALOG_SYNTH8_REFDIVB_SET(x)                                             (((x) << 27) & 0xf8000000)
-
-/* macros for SYNTH9 */
-#define PHY_ANALOG_SYNTH9_ADDRESS                                                                    0x000000a0
-#define PHY_ANALOG_SYNTH9_OFFSET                                                                     0x000000a0
-#define PHY_ANALOG_SYNTH9_PFDDELAY_INTN_MSB                                                                   0
-#define PHY_ANALOG_SYNTH9_PFDDELAY_INTN_LSB                                                                   0
-#define PHY_ANALOG_SYNTH9_PFDDELAY_INTN_MASK                                                         0x00000001
-#define PHY_ANALOG_SYNTH9_PFDDELAY_INTN_GET(x)                                        (((x) & 0x00000001) >> 0)
-#define PHY_ANALOG_SYNTH9_PFDDELAY_INTN_SET(x)                                        (((x) << 0) & 0x00000001)
-#define PHY_ANALOG_SYNTH9_SLOPE_ICPA0_MSB                                                                     3
-#define PHY_ANALOG_SYNTH9_SLOPE_ICPA0_LSB                                                                     1
-#define PHY_ANALOG_SYNTH9_SLOPE_ICPA0_MASK                                                           0x0000000e
-#define PHY_ANALOG_SYNTH9_SLOPE_ICPA0_GET(x)                                          (((x) & 0x0000000e) >> 1)
-#define PHY_ANALOG_SYNTH9_SLOPE_ICPA0_SET(x)                                          (((x) << 1) & 0x0000000e)
-#define PHY_ANALOG_SYNTH9_LOOP_ICPA0_MSB                                                                      7
-#define PHY_ANALOG_SYNTH9_LOOP_ICPA0_LSB                                                                      4
-#define PHY_ANALOG_SYNTH9_LOOP_ICPA0_MASK                                                            0x000000f0
-#define PHY_ANALOG_SYNTH9_LOOP_ICPA0_GET(x)                                           (((x) & 0x000000f0) >> 4)
-#define PHY_ANALOG_SYNTH9_LOOP_ICPA0_SET(x)                                           (((x) << 4) & 0x000000f0)
-#define PHY_ANALOG_SYNTH9_LOOP_CSA0_MSB                                                                      11
-#define PHY_ANALOG_SYNTH9_LOOP_CSA0_LSB                                                                       8
-#define PHY_ANALOG_SYNTH9_LOOP_CSA0_MASK                                                             0x00000f00
-#define PHY_ANALOG_SYNTH9_LOOP_CSA0_GET(x)                                            (((x) & 0x00000f00) >> 8)
-#define PHY_ANALOG_SYNTH9_LOOP_CSA0_SET(x)                                            (((x) << 8) & 0x00000f00)
-#define PHY_ANALOG_SYNTH9_LOOP_RSA0_MSB                                                                      16
-#define PHY_ANALOG_SYNTH9_LOOP_RSA0_LSB                                                                      12
-#define PHY_ANALOG_SYNTH9_LOOP_RSA0_MASK                                                             0x0001f000
-#define PHY_ANALOG_SYNTH9_LOOP_RSA0_GET(x)                                           (((x) & 0x0001f000) >> 12)
-#define PHY_ANALOG_SYNTH9_LOOP_RSA0_SET(x)                                           (((x) << 12) & 0x0001f000)
-#define PHY_ANALOG_SYNTH9_LOOP_CPA0_MSB                                                                      21
-#define PHY_ANALOG_SYNTH9_LOOP_CPA0_LSB                                                                      17
-#define PHY_ANALOG_SYNTH9_LOOP_CPA0_MASK                                                             0x003e0000
-#define PHY_ANALOG_SYNTH9_LOOP_CPA0_GET(x)                                           (((x) & 0x003e0000) >> 17)
-#define PHY_ANALOG_SYNTH9_LOOP_CPA0_SET(x)                                           (((x) << 17) & 0x003e0000)
-#define PHY_ANALOG_SYNTH9_LOOP_3RD_ORDER_RA_MSB                                                              26
-#define PHY_ANALOG_SYNTH9_LOOP_3RD_ORDER_RA_LSB                                                              22
-#define PHY_ANALOG_SYNTH9_LOOP_3RD_ORDER_RA_MASK                                                     0x07c00000
-#define PHY_ANALOG_SYNTH9_LOOP_3RD_ORDER_RA_GET(x)                                   (((x) & 0x07c00000) >> 22)
-#define PHY_ANALOG_SYNTH9_LOOP_3RD_ORDER_RA_SET(x)                                   (((x) << 22) & 0x07c00000)
-#define PHY_ANALOG_SYNTH9_REFDIVA_MSB                                                                        31
-#define PHY_ANALOG_SYNTH9_REFDIVA_LSB                                                                        27
-#define PHY_ANALOG_SYNTH9_REFDIVA_MASK                                                               0xf8000000
-#define PHY_ANALOG_SYNTH9_REFDIVA_GET(x)                                             (((x) & 0xf8000000) >> 27)
-#define PHY_ANALOG_SYNTH9_REFDIVA_SET(x)                                             (((x) << 27) & 0xf8000000)
-
-/* macros for SYNTH10 */
-#define PHY_ANALOG_SYNTH10_ADDRESS                                                                   0x000000a4
-#define PHY_ANALOG_SYNTH10_OFFSET                                                                    0x000000a4
-#define PHY_ANALOG_SYNTH10_SPARE10A_MSB                                                                       0
-#define PHY_ANALOG_SYNTH10_SPARE10A_LSB                                                                       0
-#define PHY_ANALOG_SYNTH10_SPARE10A_MASK                                                             0x00000001
-#define PHY_ANALOG_SYNTH10_SPARE10A_GET(x)                                            (((x) & 0x00000001) >> 0)
-#define PHY_ANALOG_SYNTH10_SPARE10A_SET(x)                                            (((x) << 0) & 0x00000001)
-#define PHY_ANALOG_SYNTH10_PWDB_ICLOBIAS50_MSB                                                                3
-#define PHY_ANALOG_SYNTH10_PWDB_ICLOBIAS50_LSB                                                                1
-#define PHY_ANALOG_SYNTH10_PWDB_ICLOBIAS50_MASK                                                      0x0000000e
-#define PHY_ANALOG_SYNTH10_PWDB_ICLOBIAS50_GET(x)                                     (((x) & 0x0000000e) >> 1)
-#define PHY_ANALOG_SYNTH10_PWDB_ICLOBIAS50_SET(x)                                     (((x) << 1) & 0x0000000e)
-#define PHY_ANALOG_SYNTH10_EN_2X_LOOPFILT_MSB                                                                 4
-#define PHY_ANALOG_SYNTH10_EN_2X_LOOPFILT_LSB                                                                 4
-#define PHY_ANALOG_SYNTH10_EN_2X_LOOPFILT_MASK                                                       0x00000010
-#define PHY_ANALOG_SYNTH10_EN_2X_LOOPFILT_GET(x)                                      (((x) & 0x00000010) >> 4)
-#define PHY_ANALOG_SYNTH10_EN_2X_LOOPFILT_SET(x)                                      (((x) << 4) & 0x00000010)
-#define PHY_ANALOG_SYNTH10_PWDB_IRSPARE25_MSB                                                                 7
-#define PHY_ANALOG_SYNTH10_PWDB_IRSPARE25_LSB                                                                 5
-#define PHY_ANALOG_SYNTH10_PWDB_IRSPARE25_MASK                                                       0x000000e0
-#define PHY_ANALOG_SYNTH10_PWDB_IRSPARE25_GET(x)                                      (((x) & 0x000000e0) >> 5)
-#define PHY_ANALOG_SYNTH10_PWDB_IRSPARE25_SET(x)                                      (((x) << 5) & 0x000000e0)
-#define PHY_ANALOG_SYNTH10_PWDB_ICSPARE25_MSB                                                                10
-#define PHY_ANALOG_SYNTH10_PWDB_ICSPARE25_LSB                                                                 8
-#define PHY_ANALOG_SYNTH10_PWDB_ICSPARE25_MASK                                                       0x00000700
-#define PHY_ANALOG_SYNTH10_PWDB_ICSPARE25_GET(x)                                      (((x) & 0x00000700) >> 8)
-#define PHY_ANALOG_SYNTH10_PWDB_ICSPARE25_SET(x)                                      (((x) << 8) & 0x00000700)
-#define PHY_ANALOG_SYNTH10_SLOPE_ICPA1_MSB                                                                   13
-#define PHY_ANALOG_SYNTH10_SLOPE_ICPA1_LSB                                                                   11
-#define PHY_ANALOG_SYNTH10_SLOPE_ICPA1_MASK                                                          0x00003800
-#define PHY_ANALOG_SYNTH10_SLOPE_ICPA1_GET(x)                                        (((x) & 0x00003800) >> 11)
-#define PHY_ANALOG_SYNTH10_SLOPE_ICPA1_SET(x)                                        (((x) << 11) & 0x00003800)
-#define PHY_ANALOG_SYNTH10_LOOP_ICPA1_MSB                                                                    17
-#define PHY_ANALOG_SYNTH10_LOOP_ICPA1_LSB                                                                    14
-#define PHY_ANALOG_SYNTH10_LOOP_ICPA1_MASK                                                           0x0003c000
-#define PHY_ANALOG_SYNTH10_LOOP_ICPA1_GET(x)                                         (((x) & 0x0003c000) >> 14)
-#define PHY_ANALOG_SYNTH10_LOOP_ICPA1_SET(x)                                         (((x) << 14) & 0x0003c000)
-#define PHY_ANALOG_SYNTH10_LOOP_CSA1_MSB                                                                     21
-#define PHY_ANALOG_SYNTH10_LOOP_CSA1_LSB                                                                     18
-#define PHY_ANALOG_SYNTH10_LOOP_CSA1_MASK                                                            0x003c0000
-#define PHY_ANALOG_SYNTH10_LOOP_CSA1_GET(x)                                          (((x) & 0x003c0000) >> 18)
-#define PHY_ANALOG_SYNTH10_LOOP_CSA1_SET(x)                                          (((x) << 18) & 0x003c0000)
-#define PHY_ANALOG_SYNTH10_LOOP_RSA1_MSB                                                                     26
-#define PHY_ANALOG_SYNTH10_LOOP_RSA1_LSB                                                                     22
-#define PHY_ANALOG_SYNTH10_LOOP_RSA1_MASK                                                            0x07c00000
-#define PHY_ANALOG_SYNTH10_LOOP_RSA1_GET(x)                                          (((x) & 0x07c00000) >> 22)
-#define PHY_ANALOG_SYNTH10_LOOP_RSA1_SET(x)                                          (((x) << 22) & 0x07c00000)
-#define PHY_ANALOG_SYNTH10_LOOP_CPA1_MSB                                                                     31
-#define PHY_ANALOG_SYNTH10_LOOP_CPA1_LSB                                                                     27
-#define PHY_ANALOG_SYNTH10_LOOP_CPA1_MASK                                                            0xf8000000
-#define PHY_ANALOG_SYNTH10_LOOP_CPA1_GET(x)                                          (((x) & 0xf8000000) >> 27)
-#define PHY_ANALOG_SYNTH10_LOOP_CPA1_SET(x)                                          (((x) << 27) & 0xf8000000)
-
-/* macros for SYNTH11 */
-#define PHY_ANALOG_SYNTH11_ADDRESS                                                                   0x000000a8
-#define PHY_ANALOG_SYNTH11_OFFSET                                                                    0x000000a8
-#define PHY_ANALOG_SYNTH11_SPARE11A_MSB                                                                       4
-#define PHY_ANALOG_SYNTH11_SPARE11A_LSB                                                                       0
-#define PHY_ANALOG_SYNTH11_SPARE11A_MASK                                                             0x0000001f
-#define PHY_ANALOG_SYNTH11_SPARE11A_GET(x)                                            (((x) & 0x0000001f) >> 0)
-#define PHY_ANALOG_SYNTH11_SPARE11A_SET(x)                                            (((x) << 0) & 0x0000001f)
-#define PHY_ANALOG_SYNTH11_FORCE_LOBUF5G_ON_MSB                                                               5
-#define PHY_ANALOG_SYNTH11_FORCE_LOBUF5G_ON_LSB                                                               5
-#define PHY_ANALOG_SYNTH11_FORCE_LOBUF5G_ON_MASK                                                     0x00000020
-#define PHY_ANALOG_SYNTH11_FORCE_LOBUF5G_ON_GET(x)                                    (((x) & 0x00000020) >> 5)
-#define PHY_ANALOG_SYNTH11_FORCE_LOBUF5G_ON_SET(x)                                    (((x) << 5) & 0x00000020)
-#define PHY_ANALOG_SYNTH11_LOREFSEL_MSB                                                                       7
-#define PHY_ANALOG_SYNTH11_LOREFSEL_LSB                                                                       6
-#define PHY_ANALOG_SYNTH11_LOREFSEL_MASK                                                             0x000000c0
-#define PHY_ANALOG_SYNTH11_LOREFSEL_GET(x)                                            (((x) & 0x000000c0) >> 6)
-#define PHY_ANALOG_SYNTH11_LOREFSEL_SET(x)                                            (((x) << 6) & 0x000000c0)
-#define PHY_ANALOG_SYNTH11_LOBUF2GTUNE_MSB                                                                    9
-#define PHY_ANALOG_SYNTH11_LOBUF2GTUNE_LSB                                                                    8
-#define PHY_ANALOG_SYNTH11_LOBUF2GTUNE_MASK                                                          0x00000300
-#define PHY_ANALOG_SYNTH11_LOBUF2GTUNE_GET(x)                                         (((x) & 0x00000300) >> 8)
-#define PHY_ANALOG_SYNTH11_LOBUF2GTUNE_SET(x)                                         (((x) << 8) & 0x00000300)
-#define PHY_ANALOG_SYNTH11_CPSTEERING_MODE_MSB                                                               10
-#define PHY_ANALOG_SYNTH11_CPSTEERING_MODE_LSB                                                               10
-#define PHY_ANALOG_SYNTH11_CPSTEERING_MODE_MASK                                                      0x00000400
-#define PHY_ANALOG_SYNTH11_CPSTEERING_MODE_GET(x)                                    (((x) & 0x00000400) >> 10)
-#define PHY_ANALOG_SYNTH11_CPSTEERING_MODE_SET(x)                                    (((x) << 10) & 0x00000400)
-#define PHY_ANALOG_SYNTH11_SLOPE_ICPA2_MSB                                                                   13
-#define PHY_ANALOG_SYNTH11_SLOPE_ICPA2_LSB                                                                   11
-#define PHY_ANALOG_SYNTH11_SLOPE_ICPA2_MASK                                                          0x00003800
-#define PHY_ANALOG_SYNTH11_SLOPE_ICPA2_GET(x)                                        (((x) & 0x00003800) >> 11)
-#define PHY_ANALOG_SYNTH11_SLOPE_ICPA2_SET(x)                                        (((x) << 11) & 0x00003800)
-#define PHY_ANALOG_SYNTH11_LOOP_ICPA2_MSB                                                                    17
-#define PHY_ANALOG_SYNTH11_LOOP_ICPA2_LSB                                                                    14
-#define PHY_ANALOG_SYNTH11_LOOP_ICPA2_MASK                                                           0x0003c000
-#define PHY_ANALOG_SYNTH11_LOOP_ICPA2_GET(x)                                         (((x) & 0x0003c000) >> 14)
-#define PHY_ANALOG_SYNTH11_LOOP_ICPA2_SET(x)                                         (((x) << 14) & 0x0003c000)
-#define PHY_ANALOG_SYNTH11_LOOP_CSA2_MSB                                                                     21
-#define PHY_ANALOG_SYNTH11_LOOP_CSA2_LSB                                                                     18
-#define PHY_ANALOG_SYNTH11_LOOP_CSA2_MASK                                                            0x003c0000
-#define PHY_ANALOG_SYNTH11_LOOP_CSA2_GET(x)                                          (((x) & 0x003c0000) >> 18)
-#define PHY_ANALOG_SYNTH11_LOOP_CSA2_SET(x)                                          (((x) << 18) & 0x003c0000)
-#define PHY_ANALOG_SYNTH11_LOOP_RSA2_MSB                                                                     26
-#define PHY_ANALOG_SYNTH11_LOOP_RSA2_LSB                                                                     22
-#define PHY_ANALOG_SYNTH11_LOOP_RSA2_MASK                                                            0x07c00000
-#define PHY_ANALOG_SYNTH11_LOOP_RSA2_GET(x)                                          (((x) & 0x07c00000) >> 22)
-#define PHY_ANALOG_SYNTH11_LOOP_RSA2_SET(x)                                          (((x) << 22) & 0x07c00000)
-#define PHY_ANALOG_SYNTH11_LOOP_CPA2_MSB                                                                     31
-#define PHY_ANALOG_SYNTH11_LOOP_CPA2_LSB                                                                     27
-#define PHY_ANALOG_SYNTH11_LOOP_CPA2_MASK                                                            0xf8000000
-#define PHY_ANALOG_SYNTH11_LOOP_CPA2_GET(x)                                          (((x) & 0xf8000000) >> 27)
-#define PHY_ANALOG_SYNTH11_LOOP_CPA2_SET(x)                                          (((x) << 27) & 0xf8000000)
-
-/* macros for SYNTH12 */
-#define PHY_ANALOG_SYNTH12_ADDRESS                                                                   0x000000ac
-#define PHY_ANALOG_SYNTH12_OFFSET                                                                    0x000000ac
-#define PHY_ANALOG_SYNTH12_SPARE12A_MSB                                                                      17
-#define PHY_ANALOG_SYNTH12_SPARE12A_LSB                                                                       0
-#define PHY_ANALOG_SYNTH12_SPARE12A_MASK                                                             0x0003ffff
-#define PHY_ANALOG_SYNTH12_SPARE12A_GET(x)                                            (((x) & 0x0003ffff) >> 0)
-#define PHY_ANALOG_SYNTH12_SPARE12A_SET(x)                                            (((x) << 0) & 0x0003ffff)
-#define PHY_ANALOG_SYNTH12_STRCONT_MSB                                                                       18
-#define PHY_ANALOG_SYNTH12_STRCONT_LSB                                                                       18
-#define PHY_ANALOG_SYNTH12_STRCONT_MASK                                                              0x00040000
-#define PHY_ANALOG_SYNTH12_STRCONT_GET(x)                                            (((x) & 0x00040000) >> 18)
-#define PHY_ANALOG_SYNTH12_STRCONT_SET(x)                                            (((x) << 18) & 0x00040000)
-#define PHY_ANALOG_SYNTH12_VREFMUL3_MSB                                                                      22
-#define PHY_ANALOG_SYNTH12_VREFMUL3_LSB                                                                      19
-#define PHY_ANALOG_SYNTH12_VREFMUL3_MASK                                                             0x00780000
-#define PHY_ANALOG_SYNTH12_VREFMUL3_GET(x)                                           (((x) & 0x00780000) >> 19)
-#define PHY_ANALOG_SYNTH12_VREFMUL3_SET(x)                                           (((x) << 19) & 0x00780000)
-#define PHY_ANALOG_SYNTH12_VREFMUL2_MSB                                                                      26
-#define PHY_ANALOG_SYNTH12_VREFMUL2_LSB                                                                      23
-#define PHY_ANALOG_SYNTH12_VREFMUL2_MASK                                                             0x07800000
-#define PHY_ANALOG_SYNTH12_VREFMUL2_GET(x)                                           (((x) & 0x07800000) >> 23)
-#define PHY_ANALOG_SYNTH12_VREFMUL2_SET(x)                                           (((x) << 23) & 0x07800000)
-#define PHY_ANALOG_SYNTH12_VREFMUL1_MSB                                                                      30
-#define PHY_ANALOG_SYNTH12_VREFMUL1_LSB                                                                      27
-#define PHY_ANALOG_SYNTH12_VREFMUL1_MASK                                                             0x78000000
-#define PHY_ANALOG_SYNTH12_VREFMUL1_GET(x)                                           (((x) & 0x78000000) >> 27)
-#define PHY_ANALOG_SYNTH12_VREFMUL1_SET(x)                                           (((x) << 27) & 0x78000000)
-#define PHY_ANALOG_SYNTH12_CLK_DOUBLER_EN_MSB                                                                31
-#define PHY_ANALOG_SYNTH12_CLK_DOUBLER_EN_LSB                                                                31
-#define PHY_ANALOG_SYNTH12_CLK_DOUBLER_EN_MASK                                                       0x80000000
-#define PHY_ANALOG_SYNTH12_CLK_DOUBLER_EN_GET(x)                                     (((x) & 0x80000000) >> 31)
-#define PHY_ANALOG_SYNTH12_CLK_DOUBLER_EN_SET(x)                                     (((x) << 31) & 0x80000000)
-
-/* macros for BIAS1 */
-#define PHY_ANALOG_BIAS1_ADDRESS                                                                     0x000000c0
-#define PHY_ANALOG_BIAS1_OFFSET                                                                      0x000000c0
-#define PHY_ANALOG_BIAS1_SPARE1_MSB                                                                           6
-#define PHY_ANALOG_BIAS1_SPARE1_LSB                                                                           0
-#define PHY_ANALOG_BIAS1_SPARE1_MASK                                                                 0x0000007f
-#define PHY_ANALOG_BIAS1_SPARE1_GET(x)                                                (((x) & 0x0000007f) >> 0)
-#define PHY_ANALOG_BIAS1_SPARE1_SET(x)                                                (((x) << 0) & 0x0000007f)
-#define PHY_ANALOG_BIAS1_PWD_IC25V2IQ_MSB                                                                     9
-#define PHY_ANALOG_BIAS1_PWD_IC25V2IQ_LSB                                                                     7
-#define PHY_ANALOG_BIAS1_PWD_IC25V2IQ_MASK                                                           0x00000380
-#define PHY_ANALOG_BIAS1_PWD_IC25V2IQ_GET(x)                                          (((x) & 0x00000380) >> 7)
-#define PHY_ANALOG_BIAS1_PWD_IC25V2IQ_SET(x)                                          (((x) << 7) & 0x00000380)
-#define PHY_ANALOG_BIAS1_PWD_IC25V2II_MSB                                                                    12
-#define PHY_ANALOG_BIAS1_PWD_IC25V2II_LSB                                                                    10
-#define PHY_ANALOG_BIAS1_PWD_IC25V2II_MASK                                                           0x00001c00
-#define PHY_ANALOG_BIAS1_PWD_IC25V2II_GET(x)                                         (((x) & 0x00001c00) >> 10)
-#define PHY_ANALOG_BIAS1_PWD_IC25V2II_SET(x)                                         (((x) << 10) & 0x00001c00)
-#define PHY_ANALOG_BIAS1_PWD_IC25BB_MSB                                                                      15
-#define PHY_ANALOG_BIAS1_PWD_IC25BB_LSB                                                                      13
-#define PHY_ANALOG_BIAS1_PWD_IC25BB_MASK                                                             0x0000e000
-#define PHY_ANALOG_BIAS1_PWD_IC25BB_GET(x)                                           (((x) & 0x0000e000) >> 13)
-#define PHY_ANALOG_BIAS1_PWD_IC25BB_SET(x)                                           (((x) << 13) & 0x0000e000)
-#define PHY_ANALOG_BIAS1_PWD_IC25DAC_MSB                                                                     18
-#define PHY_ANALOG_BIAS1_PWD_IC25DAC_LSB                                                                     16
-#define PHY_ANALOG_BIAS1_PWD_IC25DAC_MASK                                                            0x00070000
-#define PHY_ANALOG_BIAS1_PWD_IC25DAC_GET(x)                                          (((x) & 0x00070000) >> 16)
-#define PHY_ANALOG_BIAS1_PWD_IC25DAC_SET(x)                                          (((x) << 16) & 0x00070000)
-#define PHY_ANALOG_BIAS1_PWD_IC25FIR_MSB                                                                     21
-#define PHY_ANALOG_BIAS1_PWD_IC25FIR_LSB                                                                     19
-#define PHY_ANALOG_BIAS1_PWD_IC25FIR_MASK                                                            0x00380000
-#define PHY_ANALOG_BIAS1_PWD_IC25FIR_GET(x)                                          (((x) & 0x00380000) >> 19)
-#define PHY_ANALOG_BIAS1_PWD_IC25FIR_SET(x)                                          (((x) << 19) & 0x00380000)
-#define PHY_ANALOG_BIAS1_PWD_IC25ADC_MSB                                                                     24
-#define PHY_ANALOG_BIAS1_PWD_IC25ADC_LSB                                                                     22
-#define PHY_ANALOG_BIAS1_PWD_IC25ADC_MASK                                                            0x01c00000
-#define PHY_ANALOG_BIAS1_PWD_IC25ADC_GET(x)                                          (((x) & 0x01c00000) >> 22)
-#define PHY_ANALOG_BIAS1_PWD_IC25ADC_SET(x)                                          (((x) << 22) & 0x01c00000)
-#define PHY_ANALOG_BIAS1_BIAS_SEL_MSB                                                                        31
-#define PHY_ANALOG_BIAS1_BIAS_SEL_LSB                                                                        25
-#define PHY_ANALOG_BIAS1_BIAS_SEL_MASK                                                               0xfe000000
-#define PHY_ANALOG_BIAS1_BIAS_SEL_GET(x)                                             (((x) & 0xfe000000) >> 25)
-#define PHY_ANALOG_BIAS1_BIAS_SEL_SET(x)                                             (((x) << 25) & 0xfe000000)
-
-/* macros for BIAS2 */
-#define PHY_ANALOG_BIAS2_ADDRESS                                                                     0x000000c4
-#define PHY_ANALOG_BIAS2_OFFSET                                                                      0x000000c4
-#define PHY_ANALOG_BIAS2_SPARE2_MSB                                                                           4
-#define PHY_ANALOG_BIAS2_SPARE2_LSB                                                                           0
-#define PHY_ANALOG_BIAS2_SPARE2_MASK                                                                 0x0000001f
-#define PHY_ANALOG_BIAS2_SPARE2_GET(x)                                                (((x) & 0x0000001f) >> 0)
-#define PHY_ANALOG_BIAS2_SPARE2_SET(x)                                                (((x) << 0) & 0x0000001f)
-#define PHY_ANALOG_BIAS2_PWD_IC25XTALREG_MSB                                                                  7
-#define PHY_ANALOG_BIAS2_PWD_IC25XTALREG_LSB                                                                  5
-#define PHY_ANALOG_BIAS2_PWD_IC25XTALREG_MASK                                                        0x000000e0
-#define PHY_ANALOG_BIAS2_PWD_IC25XTALREG_GET(x)                                       (((x) & 0x000000e0) >> 5)
-#define PHY_ANALOG_BIAS2_PWD_IC25XTALREG_SET(x)                                       (((x) << 5) & 0x000000e0)
-#define PHY_ANALOG_BIAS2_PWD_IC25XTAL_MSB                                                                    10
-#define PHY_ANALOG_BIAS2_PWD_IC25XTAL_LSB                                                                     8
-#define PHY_ANALOG_BIAS2_PWD_IC25XTAL_MASK                                                           0x00000700
-#define PHY_ANALOG_BIAS2_PWD_IC25XTAL_GET(x)                                          (((x) & 0x00000700) >> 8)
-#define PHY_ANALOG_BIAS2_PWD_IC25XTAL_SET(x)                                          (((x) << 8) & 0x00000700)
-#define PHY_ANALOG_BIAS2_PWD_IC25TXRF_MSB                                                                    13
-#define PHY_ANALOG_BIAS2_PWD_IC25TXRF_LSB                                                                    11
-#define PHY_ANALOG_BIAS2_PWD_IC25TXRF_MASK                                                           0x00003800
-#define PHY_ANALOG_BIAS2_PWD_IC25TXRF_GET(x)                                         (((x) & 0x00003800) >> 11)
-#define PHY_ANALOG_BIAS2_PWD_IC25TXRF_SET(x)                                         (((x) << 11) & 0x00003800)
-#define PHY_ANALOG_BIAS2_PWD_IC25RXRF_MSB                                                                    16
-#define PHY_ANALOG_BIAS2_PWD_IC25RXRF_LSB                                                                    14
-#define PHY_ANALOG_BIAS2_PWD_IC25RXRF_MASK                                                           0x0001c000
-#define PHY_ANALOG_BIAS2_PWD_IC25RXRF_GET(x)                                         (((x) & 0x0001c000) >> 14)
-#define PHY_ANALOG_BIAS2_PWD_IC25RXRF_SET(x)                                         (((x) << 14) & 0x0001c000)
-#define PHY_ANALOG_BIAS2_PWD_IC50SYNTH_MSB                                                                   19
-#define PHY_ANALOG_BIAS2_PWD_IC50SYNTH_LSB                                                                   17
-#define PHY_ANALOG_BIAS2_PWD_IC50SYNTH_MASK                                                          0x000e0000
-#define PHY_ANALOG_BIAS2_PWD_IC50SYNTH_GET(x)                                        (((x) & 0x000e0000) >> 17)
-#define PHY_ANALOG_BIAS2_PWD_IC50SYNTH_SET(x)                                        (((x) << 17) & 0x000e0000)
-#define PHY_ANALOG_BIAS2_PWD_IC25PLLREG_MSB                                                                  22
-#define PHY_ANALOG_BIAS2_PWD_IC25PLLREG_LSB                                                                  20
-#define PHY_ANALOG_BIAS2_PWD_IC25PLLREG_MASK                                                         0x00700000
-#define PHY_ANALOG_BIAS2_PWD_IC25PLLREG_GET(x)                                       (((x) & 0x00700000) >> 20)
-#define PHY_ANALOG_BIAS2_PWD_IC25PLLREG_SET(x)                                       (((x) << 20) & 0x00700000)
-#define PHY_ANALOG_BIAS2_PWD_IC25PLLCP2_MSB                                                                  25
-#define PHY_ANALOG_BIAS2_PWD_IC25PLLCP2_LSB                                                                  23
-#define PHY_ANALOG_BIAS2_PWD_IC25PLLCP2_MASK                                                         0x03800000
-#define PHY_ANALOG_BIAS2_PWD_IC25PLLCP2_GET(x)                                       (((x) & 0x03800000) >> 23)
-#define PHY_ANALOG_BIAS2_PWD_IC25PLLCP2_SET(x)                                       (((x) << 23) & 0x03800000)
-#define PHY_ANALOG_BIAS2_PWD_IC25PLLCP_MSB                                                                   28
-#define PHY_ANALOG_BIAS2_PWD_IC25PLLCP_LSB                                                                   26
-#define PHY_ANALOG_BIAS2_PWD_IC25PLLCP_MASK                                                          0x1c000000
-#define PHY_ANALOG_BIAS2_PWD_IC25PLLCP_GET(x)                                        (((x) & 0x1c000000) >> 26)
-#define PHY_ANALOG_BIAS2_PWD_IC25PLLCP_SET(x)                                        (((x) << 26) & 0x1c000000)
-#define PHY_ANALOG_BIAS2_PWD_IC25PLLGM_MSB                                                                   31
-#define PHY_ANALOG_BIAS2_PWD_IC25PLLGM_LSB                                                                   29
-#define PHY_ANALOG_BIAS2_PWD_IC25PLLGM_MASK                                                          0xe0000000
-#define PHY_ANALOG_BIAS2_PWD_IC25PLLGM_GET(x)                                        (((x) & 0xe0000000) >> 29)
-#define PHY_ANALOG_BIAS2_PWD_IC25PLLGM_SET(x)                                        (((x) << 29) & 0xe0000000)
-
-/* macros for BIAS3 */
-#define PHY_ANALOG_BIAS3_ADDRESS                                                                     0x000000c8
-#define PHY_ANALOG_BIAS3_OFFSET                                                                      0x000000c8
-#define PHY_ANALOG_BIAS3_SPARE3_MSB                                                                           1
-#define PHY_ANALOG_BIAS3_SPARE3_LSB                                                                           0
-#define PHY_ANALOG_BIAS3_SPARE3_MASK                                                                 0x00000003
-#define PHY_ANALOG_BIAS3_SPARE3_GET(x)                                                (((x) & 0x00000003) >> 0)
-#define PHY_ANALOG_BIAS3_SPARE3_SET(x)                                                (((x) << 0) & 0x00000003)
-#define PHY_ANALOG_BIAS3_PWD_IR25XTALREG_MSB                                                                  4
-#define PHY_ANALOG_BIAS3_PWD_IR25XTALREG_LSB                                                                  2
-#define PHY_ANALOG_BIAS3_PWD_IR25XTALREG_MASK                                                        0x0000001c
-#define PHY_ANALOG_BIAS3_PWD_IR25XTALREG_GET(x)                                       (((x) & 0x0000001c) >> 2)
-#define PHY_ANALOG_BIAS3_PWD_IR25XTALREG_SET(x)                                       (((x) << 2) & 0x0000001c)
-#define PHY_ANALOG_BIAS3_PWD_IR25TXRF_MSB                                                                     7
-#define PHY_ANALOG_BIAS3_PWD_IR25TXRF_LSB                                                                     5
-#define PHY_ANALOG_BIAS3_PWD_IR25TXRF_MASK                                                           0x000000e0
-#define PHY_ANALOG_BIAS3_PWD_IR25TXRF_GET(x)                                          (((x) & 0x000000e0) >> 5)
-#define PHY_ANALOG_BIAS3_PWD_IR25TXRF_SET(x)                                          (((x) << 5) & 0x000000e0)
-#define PHY_ANALOG_BIAS3_PWD_IR25RXRF_MSB                                                                    10
-#define PHY_ANALOG_BIAS3_PWD_IR25RXRF_LSB                                                                     8
-#define PHY_ANALOG_BIAS3_PWD_IR25RXRF_MASK                                                           0x00000700
-#define PHY_ANALOG_BIAS3_PWD_IR25RXRF_GET(x)                                          (((x) & 0x00000700) >> 8)
-#define PHY_ANALOG_BIAS3_PWD_IR25RXRF_SET(x)                                          (((x) << 8) & 0x00000700)
-#define PHY_ANALOG_BIAS3_PWD_IR50SYNTH_MSB                                                                   13
-#define PHY_ANALOG_BIAS3_PWD_IR50SYNTH_LSB                                                                   11
-#define PHY_ANALOG_BIAS3_PWD_IR50SYNTH_MASK                                                          0x00003800
-#define PHY_ANALOG_BIAS3_PWD_IR50SYNTH_GET(x)                                        (((x) & 0x00003800) >> 11)
-#define PHY_ANALOG_BIAS3_PWD_IR50SYNTH_SET(x)                                        (((x) << 11) & 0x00003800)
-#define PHY_ANALOG_BIAS3_PWD_IR25PLLREG_MSB                                                                  16
-#define PHY_ANALOG_BIAS3_PWD_IR25PLLREG_LSB                                                                  14
-#define PHY_ANALOG_BIAS3_PWD_IR25PLLREG_MASK                                                         0x0001c000
-#define PHY_ANALOG_BIAS3_PWD_IR25PLLREG_GET(x)                                       (((x) & 0x0001c000) >> 14)
-#define PHY_ANALOG_BIAS3_PWD_IR25PLLREG_SET(x)                                       (((x) << 14) & 0x0001c000)
-#define PHY_ANALOG_BIAS3_PWD_IR25BB_MSB                                                                      19
-#define PHY_ANALOG_BIAS3_PWD_IR25BB_LSB                                                                      17
-#define PHY_ANALOG_BIAS3_PWD_IR25BB_MASK                                                             0x000e0000
-#define PHY_ANALOG_BIAS3_PWD_IR25BB_GET(x)                                           (((x) & 0x000e0000) >> 17)
-#define PHY_ANALOG_BIAS3_PWD_IR25BB_SET(x)                                           (((x) << 17) & 0x000e0000)
-#define PHY_ANALOG_BIAS3_PWD_IR50DAC_MSB                                                                     22
-#define PHY_ANALOG_BIAS3_PWD_IR50DAC_LSB                                                                     20
-#define PHY_ANALOG_BIAS3_PWD_IR50DAC_MASK                                                            0x00700000
-#define PHY_ANALOG_BIAS3_PWD_IR50DAC_GET(x)                                          (((x) & 0x00700000) >> 20)
-#define PHY_ANALOG_BIAS3_PWD_IR50DAC_SET(x)                                          (((x) << 20) & 0x00700000)
-#define PHY_ANALOG_BIAS3_PWD_IR25DAC_MSB                                                                     25
-#define PHY_ANALOG_BIAS3_PWD_IR25DAC_LSB                                                                     23
-#define PHY_ANALOG_BIAS3_PWD_IR25DAC_MASK                                                            0x03800000
-#define PHY_ANALOG_BIAS3_PWD_IR25DAC_GET(x)                                          (((x) & 0x03800000) >> 23)
-#define PHY_ANALOG_BIAS3_PWD_IR25DAC_SET(x)                                          (((x) << 23) & 0x03800000)
-#define PHY_ANALOG_BIAS3_PWD_IR25FIR_MSB                                                                     28
-#define PHY_ANALOG_BIAS3_PWD_IR25FIR_LSB                                                                     26
-#define PHY_ANALOG_BIAS3_PWD_IR25FIR_MASK                                                            0x1c000000
-#define PHY_ANALOG_BIAS3_PWD_IR25FIR_GET(x)                                          (((x) & 0x1c000000) >> 26)
-#define PHY_ANALOG_BIAS3_PWD_IR25FIR_SET(x)                                          (((x) << 26) & 0x1c000000)
-#define PHY_ANALOG_BIAS3_PWD_IR50ADC_MSB                                                                     31
-#define PHY_ANALOG_BIAS3_PWD_IR50ADC_LSB                                                                     29
-#define PHY_ANALOG_BIAS3_PWD_IR50ADC_MASK                                                            0xe0000000
-#define PHY_ANALOG_BIAS3_PWD_IR50ADC_GET(x)                                          (((x) & 0xe0000000) >> 29)
-#define PHY_ANALOG_BIAS3_PWD_IR50ADC_SET(x)                                          (((x) << 29) & 0xe0000000)
-
-/* macros for BIAS4 */
-#define PHY_ANALOG_BIAS4_ADDRESS                                                                     0x000000cc
-#define PHY_ANALOG_BIAS4_OFFSET                                                                      0x000000cc
-#define PHY_ANALOG_BIAS4_SPARE4_MSB                                                                          13
-#define PHY_ANALOG_BIAS4_SPARE4_LSB                                                                           0
-#define PHY_ANALOG_BIAS4_SPARE4_MASK                                                                 0x00003fff
-#define PHY_ANALOG_BIAS4_SPARE4_GET(x)                                                (((x) & 0x00003fff) >> 0)
-#define PHY_ANALOG_BIAS4_SPARE4_SET(x)                                                (((x) << 0) & 0x00003fff)
-#define PHY_ANALOG_BIAS4_PWD_IR25SPAREC_MSB                                                                  16
-#define PHY_ANALOG_BIAS4_PWD_IR25SPAREC_LSB                                                                  14
-#define PHY_ANALOG_BIAS4_PWD_IR25SPAREC_MASK                                                         0x0001c000
-#define PHY_ANALOG_BIAS4_PWD_IR25SPAREC_GET(x)                                       (((x) & 0x0001c000) >> 14)
-#define PHY_ANALOG_BIAS4_PWD_IR25SPAREC_SET(x)                                       (((x) << 14) & 0x0001c000)
-#define PHY_ANALOG_BIAS4_PWD_IR25SPAREB_MSB                                                                  19
-#define PHY_ANALOG_BIAS4_PWD_IR25SPAREB_LSB                                                                  17
-#define PHY_ANALOG_BIAS4_PWD_IR25SPAREB_MASK                                                         0x000e0000
-#define PHY_ANALOG_BIAS4_PWD_IR25SPAREB_GET(x)                                       (((x) & 0x000e0000) >> 17)
-#define PHY_ANALOG_BIAS4_PWD_IR25SPAREB_SET(x)                                       (((x) << 17) & 0x000e0000)
-#define PHY_ANALOG_BIAS4_PWD_IR25SPAREA_MSB                                                                  22
-#define PHY_ANALOG_BIAS4_PWD_IR25SPAREA_LSB                                                                  20
-#define PHY_ANALOG_BIAS4_PWD_IR25SPAREA_MASK                                                         0x00700000
-#define PHY_ANALOG_BIAS4_PWD_IR25SPAREA_GET(x)                                       (((x) & 0x00700000) >> 20)
-#define PHY_ANALOG_BIAS4_PWD_IR25SPAREA_SET(x)                                       (((x) << 20) & 0x00700000)
-#define PHY_ANALOG_BIAS4_PWD_IC25SPAREC_MSB                                                                  25
-#define PHY_ANALOG_BIAS4_PWD_IC25SPAREC_LSB                                                                  23
-#define PHY_ANALOG_BIAS4_PWD_IC25SPAREC_MASK                                                         0x03800000
-#define PHY_ANALOG_BIAS4_PWD_IC25SPAREC_GET(x)                                       (((x) & 0x03800000) >> 23)
-#define PHY_ANALOG_BIAS4_PWD_IC25SPAREC_SET(x)                                       (((x) << 23) & 0x03800000)
-#define PHY_ANALOG_BIAS4_PWD_IC25SPAREB_MSB                                                                  28
-#define PHY_ANALOG_BIAS4_PWD_IC25SPAREB_LSB                                                                  26
-#define PHY_ANALOG_BIAS4_PWD_IC25SPAREB_MASK                                                         0x1c000000
-#define PHY_ANALOG_BIAS4_PWD_IC25SPAREB_GET(x)                                       (((x) & 0x1c000000) >> 26)
-#define PHY_ANALOG_BIAS4_PWD_IC25SPAREB_SET(x)                                       (((x) << 26) & 0x1c000000)
-#define PHY_ANALOG_BIAS4_PWD_IC25SPAREA_MSB                                                                  31
-#define PHY_ANALOG_BIAS4_PWD_IC25SPAREA_LSB                                                                  29
-#define PHY_ANALOG_BIAS4_PWD_IC25SPAREA_MASK                                                         0xe0000000
-#define PHY_ANALOG_BIAS4_PWD_IC25SPAREA_GET(x)                                       (((x) & 0xe0000000) >> 29)
-#define PHY_ANALOG_BIAS4_PWD_IC25SPAREA_SET(x)                                       (((x) << 29) & 0xe0000000)
-
-/* macros for RXTX1 */
-#define PHY_ANALOG_RXTX1_ADDRESS                                                                     0x00000100
-#define PHY_ANALOG_RXTX1_OFFSET                                                                      0x00000100
-#define PHY_ANALOG_RXTX1_SCFIR_GAIN_MSB                                                                       0
-#define PHY_ANALOG_RXTX1_SCFIR_GAIN_LSB                                                                       0
-#define PHY_ANALOG_RXTX1_SCFIR_GAIN_MASK                                                             0x00000001
-#define PHY_ANALOG_RXTX1_SCFIR_GAIN_GET(x)                                            (((x) & 0x00000001) >> 0)
-#define PHY_ANALOG_RXTX1_SCFIR_GAIN_SET(x)                                            (((x) << 0) & 0x00000001)
-#define PHY_ANALOG_RXTX1_MANRXGAIN_MSB                                                                        1
-#define PHY_ANALOG_RXTX1_MANRXGAIN_LSB                                                                        1
-#define PHY_ANALOG_RXTX1_MANRXGAIN_MASK                                                              0x00000002
-#define PHY_ANALOG_RXTX1_MANRXGAIN_GET(x)                                             (((x) & 0x00000002) >> 1)
-#define PHY_ANALOG_RXTX1_MANRXGAIN_SET(x)                                             (((x) << 1) & 0x00000002)
-#define PHY_ANALOG_RXTX1_AGC_DBDAC_MSB                                                                        5
-#define PHY_ANALOG_RXTX1_AGC_DBDAC_LSB                                                                        2
-#define PHY_ANALOG_RXTX1_AGC_DBDAC_MASK                                                              0x0000003c
-#define PHY_ANALOG_RXTX1_AGC_DBDAC_GET(x)                                             (((x) & 0x0000003c) >> 2)
-#define PHY_ANALOG_RXTX1_AGC_DBDAC_SET(x)                                             (((x) << 2) & 0x0000003c)
-#define PHY_ANALOG_RXTX1_OVR_AGC_DBDAC_MSB                                                                    6
-#define PHY_ANALOG_RXTX1_OVR_AGC_DBDAC_LSB                                                                    6
-#define PHY_ANALOG_RXTX1_OVR_AGC_DBDAC_MASK                                                          0x00000040
-#define PHY_ANALOG_RXTX1_OVR_AGC_DBDAC_GET(x)                                         (((x) & 0x00000040) >> 6)
-#define PHY_ANALOG_RXTX1_OVR_AGC_DBDAC_SET(x)                                         (((x) << 6) & 0x00000040)
-#define PHY_ANALOG_RXTX1_ENABLE_PAL_MSB                                                                       7
-#define PHY_ANALOG_RXTX1_ENABLE_PAL_LSB                                                                       7
-#define PHY_ANALOG_RXTX1_ENABLE_PAL_MASK                                                             0x00000080
-#define PHY_ANALOG_RXTX1_ENABLE_PAL_GET(x)                                            (((x) & 0x00000080) >> 7)
-#define PHY_ANALOG_RXTX1_ENABLE_PAL_SET(x)                                            (((x) << 7) & 0x00000080)
-#define PHY_ANALOG_RXTX1_ENABLE_PAL_OVR_MSB                                                                   8
-#define PHY_ANALOG_RXTX1_ENABLE_PAL_OVR_LSB                                                                   8
-#define PHY_ANALOG_RXTX1_ENABLE_PAL_OVR_MASK                                                         0x00000100
-#define PHY_ANALOG_RXTX1_ENABLE_PAL_OVR_GET(x)                                        (((x) & 0x00000100) >> 8)
-#define PHY_ANALOG_RXTX1_ENABLE_PAL_OVR_SET(x)                                        (((x) << 8) & 0x00000100)
-#define PHY_ANALOG_RXTX1_TX1DB_BIQUAD_MSB                                                                    11
-#define PHY_ANALOG_RXTX1_TX1DB_BIQUAD_LSB                                                                     9
-#define PHY_ANALOG_RXTX1_TX1DB_BIQUAD_MASK                                                           0x00000e00
-#define PHY_ANALOG_RXTX1_TX1DB_BIQUAD_GET(x)                                          (((x) & 0x00000e00) >> 9)
-#define PHY_ANALOG_RXTX1_TX1DB_BIQUAD_SET(x)                                          (((x) << 9) & 0x00000e00)
-#define PHY_ANALOG_RXTX1_TX6DB_BIQUAD_MSB                                                                    13
-#define PHY_ANALOG_RXTX1_TX6DB_BIQUAD_LSB                                                                    12
-#define PHY_ANALOG_RXTX1_TX6DB_BIQUAD_MASK                                                           0x00003000
-#define PHY_ANALOG_RXTX1_TX6DB_BIQUAD_GET(x)                                         (((x) & 0x00003000) >> 12)
-#define PHY_ANALOG_RXTX1_TX6DB_BIQUAD_SET(x)                                         (((x) << 12) & 0x00003000)
-#define PHY_ANALOG_RXTX1_PADRVHALFGN2G_MSB                                                                   14
-#define PHY_ANALOG_RXTX1_PADRVHALFGN2G_LSB                                                                   14
-#define PHY_ANALOG_RXTX1_PADRVHALFGN2G_MASK                                                          0x00004000
-#define PHY_ANALOG_RXTX1_PADRVHALFGN2G_GET(x)                                        (((x) & 0x00004000) >> 14)
-#define PHY_ANALOG_RXTX1_PADRVHALFGN2G_SET(x)                                        (((x) << 14) & 0x00004000)
-#define PHY_ANALOG_RXTX1_PADRV2GN_MSB                                                                        18
-#define PHY_ANALOG_RXTX1_PADRV2GN_LSB                                                                        15
-#define PHY_ANALOG_RXTX1_PADRV2GN_MASK                                                               0x00078000
-#define PHY_ANALOG_RXTX1_PADRV2GN_GET(x)                                             (((x) & 0x00078000) >> 15)
-#define PHY_ANALOG_RXTX1_PADRV2GN_SET(x)                                             (((x) << 15) & 0x00078000)
-#define PHY_ANALOG_RXTX1_PADRV3GN5G_MSB                                                                      22
-#define PHY_ANALOG_RXTX1_PADRV3GN5G_LSB                                                                      19
-#define PHY_ANALOG_RXTX1_PADRV3GN5G_MASK                                                             0x00780000
-#define PHY_ANALOG_RXTX1_PADRV3GN5G_GET(x)                                           (((x) & 0x00780000) >> 19)
-#define PHY_ANALOG_RXTX1_PADRV3GN5G_SET(x)                                           (((x) << 19) & 0x00780000)
-#define PHY_ANALOG_RXTX1_PADRV4GN5G_MSB                                                                      26
-#define PHY_ANALOG_RXTX1_PADRV4GN5G_LSB                                                                      23
-#define PHY_ANALOG_RXTX1_PADRV4GN5G_MASK                                                             0x07800000
-#define PHY_ANALOG_RXTX1_PADRV4GN5G_GET(x)                                           (((x) & 0x07800000) >> 23)
-#define PHY_ANALOG_RXTX1_PADRV4GN5G_SET(x)                                           (((x) << 23) & 0x07800000)
-#define PHY_ANALOG_RXTX1_TXBB_GC_MSB                                                                         30
-#define PHY_ANALOG_RXTX1_TXBB_GC_LSB                                                                         27
-#define PHY_ANALOG_RXTX1_TXBB_GC_MASK                                                                0x78000000
-#define PHY_ANALOG_RXTX1_TXBB_GC_GET(x)                                              (((x) & 0x78000000) >> 27)
-#define PHY_ANALOG_RXTX1_TXBB_GC_SET(x)                                              (((x) << 27) & 0x78000000)
-#define PHY_ANALOG_RXTX1_MANTXGAIN_MSB                                                                       31
-#define PHY_ANALOG_RXTX1_MANTXGAIN_LSB                                                                       31
-#define PHY_ANALOG_RXTX1_MANTXGAIN_MASK                                                              0x80000000
-#define PHY_ANALOG_RXTX1_MANTXGAIN_GET(x)                                            (((x) & 0x80000000) >> 31)
-#define PHY_ANALOG_RXTX1_MANTXGAIN_SET(x)                                            (((x) << 31) & 0x80000000)
-
-/* macros for RXTX2 */
-#define PHY_ANALOG_RXTX2_ADDRESS                                                                     0x00000104
-#define PHY_ANALOG_RXTX2_OFFSET                                                                      0x00000104
-#define PHY_ANALOG_RXTX2_BMODE_MSB                                                                            0
-#define PHY_ANALOG_RXTX2_BMODE_LSB                                                                            0
-#define PHY_ANALOG_RXTX2_BMODE_MASK                                                                  0x00000001
-#define PHY_ANALOG_RXTX2_BMODE_GET(x)                                                 (((x) & 0x00000001) >> 0)
-#define PHY_ANALOG_RXTX2_BMODE_SET(x)                                                 (((x) << 0) & 0x00000001)
-#define PHY_ANALOG_RXTX2_BMODE_OVR_MSB                                                                        1
-#define PHY_ANALOG_RXTX2_BMODE_OVR_LSB                                                                        1
-#define PHY_ANALOG_RXTX2_BMODE_OVR_MASK                                                              0x00000002
-#define PHY_ANALOG_RXTX2_BMODE_OVR_GET(x)                                             (((x) & 0x00000002) >> 1)
-#define PHY_ANALOG_RXTX2_BMODE_OVR_SET(x)                                             (((x) << 1) & 0x00000002)
-#define PHY_ANALOG_RXTX2_SYNTHON_MSB                                                                          2
-#define PHY_ANALOG_RXTX2_SYNTHON_LSB                                                                          2
-#define PHY_ANALOG_RXTX2_SYNTHON_MASK                                                                0x00000004
-#define PHY_ANALOG_RXTX2_SYNTHON_GET(x)                                               (((x) & 0x00000004) >> 2)
-#define PHY_ANALOG_RXTX2_SYNTHON_SET(x)                                               (((x) << 2) & 0x00000004)
-#define PHY_ANALOG_RXTX2_SYNTHON_OVR_MSB                                                                      3
-#define PHY_ANALOG_RXTX2_SYNTHON_OVR_LSB                                                                      3
-#define PHY_ANALOG_RXTX2_SYNTHON_OVR_MASK                                                            0x00000008
-#define PHY_ANALOG_RXTX2_SYNTHON_OVR_GET(x)                                           (((x) & 0x00000008) >> 3)
-#define PHY_ANALOG_RXTX2_SYNTHON_OVR_SET(x)                                           (((x) << 3) & 0x00000008)
-#define PHY_ANALOG_RXTX2_BW_ST_MSB                                                                            5
-#define PHY_ANALOG_RXTX2_BW_ST_LSB                                                                            4
-#define PHY_ANALOG_RXTX2_BW_ST_MASK                                                                  0x00000030
-#define PHY_ANALOG_RXTX2_BW_ST_GET(x)                                                 (((x) & 0x00000030) >> 4)
-#define PHY_ANALOG_RXTX2_BW_ST_SET(x)                                                 (((x) << 4) & 0x00000030)
-#define PHY_ANALOG_RXTX2_BW_ST_OVR_MSB                                                                        6
-#define PHY_ANALOG_RXTX2_BW_ST_OVR_LSB                                                                        6
-#define PHY_ANALOG_RXTX2_BW_ST_OVR_MASK                                                              0x00000040
-#define PHY_ANALOG_RXTX2_BW_ST_OVR_GET(x)                                             (((x) & 0x00000040) >> 6)
-#define PHY_ANALOG_RXTX2_BW_ST_OVR_SET(x)                                             (((x) << 6) & 0x00000040)
-#define PHY_ANALOG_RXTX2_TXON_MSB                                                                             7
-#define PHY_ANALOG_RXTX2_TXON_LSB                                                                             7
-#define PHY_ANALOG_RXTX2_TXON_MASK                                                                   0x00000080
-#define PHY_ANALOG_RXTX2_TXON_GET(x)                                                  (((x) & 0x00000080) >> 7)
-#define PHY_ANALOG_RXTX2_TXON_SET(x)                                                  (((x) << 7) & 0x00000080)
-#define PHY_ANALOG_RXTX2_TXON_OVR_MSB                                                                         8
-#define PHY_ANALOG_RXTX2_TXON_OVR_LSB                                                                         8
-#define PHY_ANALOG_RXTX2_TXON_OVR_MASK                                                               0x00000100
-#define PHY_ANALOG_RXTX2_TXON_OVR_GET(x)                                              (((x) & 0x00000100) >> 8)
-#define PHY_ANALOG_RXTX2_TXON_OVR_SET(x)                                              (((x) << 8) & 0x00000100)
-#define PHY_ANALOG_RXTX2_PAON_MSB                                                                             9
-#define PHY_ANALOG_RXTX2_PAON_LSB                                                                             9
-#define PHY_ANALOG_RXTX2_PAON_MASK                                                                   0x00000200
-#define PHY_ANALOG_RXTX2_PAON_GET(x)                                                  (((x) & 0x00000200) >> 9)
-#define PHY_ANALOG_RXTX2_PAON_SET(x)                                                  (((x) << 9) & 0x00000200)
-#define PHY_ANALOG_RXTX2_PAON_OVR_MSB                                                                        10
-#define PHY_ANALOG_RXTX2_PAON_OVR_LSB                                                                        10
-#define PHY_ANALOG_RXTX2_PAON_OVR_MASK                                                               0x00000400
-#define PHY_ANALOG_RXTX2_PAON_OVR_GET(x)                                             (((x) & 0x00000400) >> 10)
-#define PHY_ANALOG_RXTX2_PAON_OVR_SET(x)                                             (((x) << 10) & 0x00000400)
-#define PHY_ANALOG_RXTX2_RXON_MSB                                                                            11
-#define PHY_ANALOG_RXTX2_RXON_LSB                                                                            11
-#define PHY_ANALOG_RXTX2_RXON_MASK                                                                   0x00000800
-#define PHY_ANALOG_RXTX2_RXON_GET(x)                                                 (((x) & 0x00000800) >> 11)
-#define PHY_ANALOG_RXTX2_RXON_SET(x)                                                 (((x) << 11) & 0x00000800)
-#define PHY_ANALOG_RXTX2_RXON_OVR_MSB                                                                        12
-#define PHY_ANALOG_RXTX2_RXON_OVR_LSB                                                                        12
-#define PHY_ANALOG_RXTX2_RXON_OVR_MASK                                                               0x00001000
-#define PHY_ANALOG_RXTX2_RXON_OVR_GET(x)                                             (((x) & 0x00001000) >> 12)
-#define PHY_ANALOG_RXTX2_RXON_OVR_SET(x)                                             (((x) << 12) & 0x00001000)
-#define PHY_ANALOG_RXTX2_AGCON_MSB                                                                           13
-#define PHY_ANALOG_RXTX2_AGCON_LSB                                                                           13
-#define PHY_ANALOG_RXTX2_AGCON_MASK                                                                  0x00002000
-#define PHY_ANALOG_RXTX2_AGCON_GET(x)                                                (((x) & 0x00002000) >> 13)
-#define PHY_ANALOG_RXTX2_AGCON_SET(x)                                                (((x) << 13) & 0x00002000)
-#define PHY_ANALOG_RXTX2_AGCON_OVR_MSB                                                                       14
-#define PHY_ANALOG_RXTX2_AGCON_OVR_LSB                                                                       14
-#define PHY_ANALOG_RXTX2_AGCON_OVR_MASK                                                              0x00004000
-#define PHY_ANALOG_RXTX2_AGCON_OVR_GET(x)                                            (((x) & 0x00004000) >> 14)
-#define PHY_ANALOG_RXTX2_AGCON_OVR_SET(x)                                            (((x) << 14) & 0x00004000)
-#define PHY_ANALOG_RXTX2_TXMOD_MSB                                                                           17
-#define PHY_ANALOG_RXTX2_TXMOD_LSB                                                                           15
-#define PHY_ANALOG_RXTX2_TXMOD_MASK                                                                  0x00038000
-#define PHY_ANALOG_RXTX2_TXMOD_GET(x)                                                (((x) & 0x00038000) >> 15)
-#define PHY_ANALOG_RXTX2_TXMOD_SET(x)                                                (((x) << 15) & 0x00038000)
-#define PHY_ANALOG_RXTX2_TXMOD_OVR_MSB                                                                       18
-#define PHY_ANALOG_RXTX2_TXMOD_OVR_LSB                                                                       18
-#define PHY_ANALOG_RXTX2_TXMOD_OVR_MASK                                                              0x00040000
-#define PHY_ANALOG_RXTX2_TXMOD_OVR_GET(x)                                            (((x) & 0x00040000) >> 18)
-#define PHY_ANALOG_RXTX2_TXMOD_OVR_SET(x)                                            (((x) << 18) & 0x00040000)
-#define PHY_ANALOG_RXTX2_RX1DB_BIQUAD_MSB                                                                    21
-#define PHY_ANALOG_RXTX2_RX1DB_BIQUAD_LSB                                                                    19
-#define PHY_ANALOG_RXTX2_RX1DB_BIQUAD_MASK                                                           0x00380000
-#define PHY_ANALOG_RXTX2_RX1DB_BIQUAD_GET(x)                                         (((x) & 0x00380000) >> 19)
-#define PHY_ANALOG_RXTX2_RX1DB_BIQUAD_SET(x)                                         (((x) << 19) & 0x00380000)
-#define PHY_ANALOG_RXTX2_RX6DB_BIQUAD_MSB                                                                    23
-#define PHY_ANALOG_RXTX2_RX6DB_BIQUAD_LSB                                                                    22
-#define PHY_ANALOG_RXTX2_RX6DB_BIQUAD_MASK                                                           0x00c00000
-#define PHY_ANALOG_RXTX2_RX6DB_BIQUAD_GET(x)                                         (((x) & 0x00c00000) >> 22)
-#define PHY_ANALOG_RXTX2_RX6DB_BIQUAD_SET(x)                                         (((x) << 22) & 0x00c00000)
-#define PHY_ANALOG_RXTX2_MXRGAIN_MSB                                                                         25
-#define PHY_ANALOG_RXTX2_MXRGAIN_LSB                                                                         24
-#define PHY_ANALOG_RXTX2_MXRGAIN_MASK                                                                0x03000000
-#define PHY_ANALOG_RXTX2_MXRGAIN_GET(x)                                              (((x) & 0x03000000) >> 24)
-#define PHY_ANALOG_RXTX2_MXRGAIN_SET(x)                                              (((x) << 24) & 0x03000000)
-#define PHY_ANALOG_RXTX2_VGAGAIN_MSB                                                                         28
-#define PHY_ANALOG_RXTX2_VGAGAIN_LSB                                                                         26
-#define PHY_ANALOG_RXTX2_VGAGAIN_MASK                                                                0x1c000000
-#define PHY_ANALOG_RXTX2_VGAGAIN_GET(x)                                              (((x) & 0x1c000000) >> 26)
-#define PHY_ANALOG_RXTX2_VGAGAIN_SET(x)                                              (((x) << 26) & 0x1c000000)
-#define PHY_ANALOG_RXTX2_LNAGAIN_MSB                                                                         31
-#define PHY_ANALOG_RXTX2_LNAGAIN_LSB                                                                         29
-#define PHY_ANALOG_RXTX2_LNAGAIN_MASK                                                                0xe0000000
-#define PHY_ANALOG_RXTX2_LNAGAIN_GET(x)                                              (((x) & 0xe0000000) >> 29)
-#define PHY_ANALOG_RXTX2_LNAGAIN_SET(x)                                              (((x) << 29) & 0xe0000000)
-
-/* macros for RXTX3 */
-#define PHY_ANALOG_RXTX3_ADDRESS                                                                     0x00000108
-#define PHY_ANALOG_RXTX3_OFFSET                                                                      0x00000108
-#define PHY_ANALOG_RXTX3_SPARE3_MSB                                                                           2
-#define PHY_ANALOG_RXTX3_SPARE3_LSB                                                                           0
-#define PHY_ANALOG_RXTX3_SPARE3_MASK                                                                 0x00000007
-#define PHY_ANALOG_RXTX3_SPARE3_GET(x)                                                (((x) & 0x00000007) >> 0)
-#define PHY_ANALOG_RXTX3_SPARE3_SET(x)                                                (((x) << 0) & 0x00000007)
-#define PHY_ANALOG_RXTX3_DACFULLSCALE_MSB                                                                     3
-#define PHY_ANALOG_RXTX3_DACFULLSCALE_LSB                                                                     3
-#define PHY_ANALOG_RXTX3_DACFULLSCALE_MASK                                                           0x00000008
-#define PHY_ANALOG_RXTX3_DACFULLSCALE_GET(x)                                          (((x) & 0x00000008) >> 3)
-#define PHY_ANALOG_RXTX3_DACFULLSCALE_SET(x)                                          (((x) << 3) & 0x00000008)
-#define PHY_ANALOG_RXTX3_DACRSTB_MSB                                                                          4
-#define PHY_ANALOG_RXTX3_DACRSTB_LSB                                                                          4
-#define PHY_ANALOG_RXTX3_DACRSTB_MASK                                                                0x00000010
-#define PHY_ANALOG_RXTX3_DACRSTB_GET(x)                                               (((x) & 0x00000010) >> 4)
-#define PHY_ANALOG_RXTX3_DACRSTB_SET(x)                                               (((x) << 4) & 0x00000010)
-#define PHY_ANALOG_RXTX3_ADDACLOOPBACK_MSB                                                                    5
-#define PHY_ANALOG_RXTX3_ADDACLOOPBACK_LSB                                                                    5
-#define PHY_ANALOG_RXTX3_ADDACLOOPBACK_MASK                                                          0x00000020
-#define PHY_ANALOG_RXTX3_ADDACLOOPBACK_GET(x)                                         (((x) & 0x00000020) >> 5)
-#define PHY_ANALOG_RXTX3_ADDACLOOPBACK_SET(x)                                         (((x) << 5) & 0x00000020)
-#define PHY_ANALOG_RXTX3_ADCSHORT_MSB                                                                         6
-#define PHY_ANALOG_RXTX3_ADCSHORT_LSB                                                                         6
-#define PHY_ANALOG_RXTX3_ADCSHORT_MASK                                                               0x00000040
-#define PHY_ANALOG_RXTX3_ADCSHORT_GET(x)                                              (((x) & 0x00000040) >> 6)
-#define PHY_ANALOG_RXTX3_ADCSHORT_SET(x)                                              (((x) << 6) & 0x00000040)
-#define PHY_ANALOG_RXTX3_DACPWD_MSB                                                                           7
-#define PHY_ANALOG_RXTX3_DACPWD_LSB                                                                           7
-#define PHY_ANALOG_RXTX3_DACPWD_MASK                                                                 0x00000080
-#define PHY_ANALOG_RXTX3_DACPWD_GET(x)                                                (((x) & 0x00000080) >> 7)
-#define PHY_ANALOG_RXTX3_DACPWD_SET(x)                                                (((x) << 7) & 0x00000080)
-#define PHY_ANALOG_RXTX3_DACPWD_OVR_MSB                                                                       8
-#define PHY_ANALOG_RXTX3_DACPWD_OVR_LSB                                                                       8
-#define PHY_ANALOG_RXTX3_DACPWD_OVR_MASK                                                             0x00000100
-#define PHY_ANALOG_RXTX3_DACPWD_OVR_GET(x)                                            (((x) & 0x00000100) >> 8)
-#define PHY_ANALOG_RXTX3_DACPWD_OVR_SET(x)                                            (((x) << 8) & 0x00000100)
-#define PHY_ANALOG_RXTX3_ADCPWD_MSB                                                                           9
-#define PHY_ANALOG_RXTX3_ADCPWD_LSB                                                                           9
-#define PHY_ANALOG_RXTX3_ADCPWD_MASK                                                                 0x00000200
-#define PHY_ANALOG_RXTX3_ADCPWD_GET(x)                                                (((x) & 0x00000200) >> 9)
-#define PHY_ANALOG_RXTX3_ADCPWD_SET(x)                                                (((x) << 9) & 0x00000200)
-#define PHY_ANALOG_RXTX3_ADCPWD_OVR_MSB                                                                      10
-#define PHY_ANALOG_RXTX3_ADCPWD_OVR_LSB                                                                      10
-#define PHY_ANALOG_RXTX3_ADCPWD_OVR_MASK                                                             0x00000400
-#define PHY_ANALOG_RXTX3_ADCPWD_OVR_GET(x)                                           (((x) & 0x00000400) >> 10)
-#define PHY_ANALOG_RXTX3_ADCPWD_OVR_SET(x)                                           (((x) << 10) & 0x00000400)
-#define PHY_ANALOG_RXTX3_AGC_CALDAC_MSB                                                                      16
-#define PHY_ANALOG_RXTX3_AGC_CALDAC_LSB                                                                      11
-#define PHY_ANALOG_RXTX3_AGC_CALDAC_MASK                                                             0x0001f800
-#define PHY_ANALOG_RXTX3_AGC_CALDAC_GET(x)                                           (((x) & 0x0001f800) >> 11)
-#define PHY_ANALOG_RXTX3_AGC_CALDAC_SET(x)                                           (((x) << 11) & 0x0001f800)
-#define PHY_ANALOG_RXTX3_AGC_CAL_MSB                                                                         17
-#define PHY_ANALOG_RXTX3_AGC_CAL_LSB                                                                         17
-#define PHY_ANALOG_RXTX3_AGC_CAL_MASK                                                                0x00020000
-#define PHY_ANALOG_RXTX3_AGC_CAL_GET(x)                                              (((x) & 0x00020000) >> 17)
-#define PHY_ANALOG_RXTX3_AGC_CAL_SET(x)                                              (((x) << 17) & 0x00020000)
-#define PHY_ANALOG_RXTX3_AGC_CAL_OVR_MSB                                                                     18
-#define PHY_ANALOG_RXTX3_AGC_CAL_OVR_LSB                                                                     18
-#define PHY_ANALOG_RXTX3_AGC_CAL_OVR_MASK                                                            0x00040000
-#define PHY_ANALOG_RXTX3_AGC_CAL_OVR_GET(x)                                          (((x) & 0x00040000) >> 18)
-#define PHY_ANALOG_RXTX3_AGC_CAL_OVR_SET(x)                                          (((x) << 18) & 0x00040000)
-#define PHY_ANALOG_RXTX3_LOFORCEDON_MSB                                                                      19
-#define PHY_ANALOG_RXTX3_LOFORCEDON_LSB                                                                      19
-#define PHY_ANALOG_RXTX3_LOFORCEDON_MASK                                                             0x00080000
-#define PHY_ANALOG_RXTX3_LOFORCEDON_GET(x)                                           (((x) & 0x00080000) >> 19)
-#define PHY_ANALOG_RXTX3_LOFORCEDON_SET(x)                                           (((x) << 19) & 0x00080000)
-#define PHY_ANALOG_RXTX3_CALRESIDUE_MSB                                                                      20
-#define PHY_ANALOG_RXTX3_CALRESIDUE_LSB                                                                      20
-#define PHY_ANALOG_RXTX3_CALRESIDUE_MASK                                                             0x00100000
-#define PHY_ANALOG_RXTX3_CALRESIDUE_GET(x)                                           (((x) & 0x00100000) >> 20)
-#define PHY_ANALOG_RXTX3_CALRESIDUE_SET(x)                                           (((x) << 20) & 0x00100000)
-#define PHY_ANALOG_RXTX3_CALRESIDUE_OVR_MSB                                                                  21
-#define PHY_ANALOG_RXTX3_CALRESIDUE_OVR_LSB                                                                  21
-#define PHY_ANALOG_RXTX3_CALRESIDUE_OVR_MASK                                                         0x00200000
-#define PHY_ANALOG_RXTX3_CALRESIDUE_OVR_GET(x)                                       (((x) & 0x00200000) >> 21)
-#define PHY_ANALOG_RXTX3_CALRESIDUE_OVR_SET(x)                                       (((x) << 21) & 0x00200000)
-#define PHY_ANALOG_RXTX3_CALFC_MSB                                                                           22
-#define PHY_ANALOG_RXTX3_CALFC_LSB                                                                           22
-#define PHY_ANALOG_RXTX3_CALFC_MASK                                                                  0x00400000
-#define PHY_ANALOG_RXTX3_CALFC_GET(x)                                                (((x) & 0x00400000) >> 22)
-#define PHY_ANALOG_RXTX3_CALFC_SET(x)                                                (((x) << 22) & 0x00400000)
-#define PHY_ANALOG_RXTX3_CALFC_OVR_MSB                                                                       23
-#define PHY_ANALOG_RXTX3_CALFC_OVR_LSB                                                                       23
-#define PHY_ANALOG_RXTX3_CALFC_OVR_MASK                                                              0x00800000
-#define PHY_ANALOG_RXTX3_CALFC_OVR_GET(x)                                            (((x) & 0x00800000) >> 23)
-#define PHY_ANALOG_RXTX3_CALFC_OVR_SET(x)                                            (((x) << 23) & 0x00800000)
-#define PHY_ANALOG_RXTX3_CALTX_MSB                                                                           24
-#define PHY_ANALOG_RXTX3_CALTX_LSB                                                                           24
-#define PHY_ANALOG_RXTX3_CALTX_MASK                                                                  0x01000000
-#define PHY_ANALOG_RXTX3_CALTX_GET(x)                                                (((x) & 0x01000000) >> 24)
-#define PHY_ANALOG_RXTX3_CALTX_SET(x)                                                (((x) << 24) & 0x01000000)
-#define PHY_ANALOG_RXTX3_CALTX_OVR_MSB                                                                       25
-#define PHY_ANALOG_RXTX3_CALTX_OVR_LSB                                                                       25
-#define PHY_ANALOG_RXTX3_CALTX_OVR_MASK                                                              0x02000000
-#define PHY_ANALOG_RXTX3_CALTX_OVR_GET(x)                                            (((x) & 0x02000000) >> 25)
-#define PHY_ANALOG_RXTX3_CALTX_OVR_SET(x)                                            (((x) << 25) & 0x02000000)
-#define PHY_ANALOG_RXTX3_CALTXSHIFT_MSB                                                                      26
-#define PHY_ANALOG_RXTX3_CALTXSHIFT_LSB                                                                      26
-#define PHY_ANALOG_RXTX3_CALTXSHIFT_MASK                                                             0x04000000
-#define PHY_ANALOG_RXTX3_CALTXSHIFT_GET(x)                                           (((x) & 0x04000000) >> 26)
-#define PHY_ANALOG_RXTX3_CALTXSHIFT_SET(x)                                           (((x) << 26) & 0x04000000)
-#define PHY_ANALOG_RXTX3_CALTXSHIFT_OVR_MSB                                                                  27
-#define PHY_ANALOG_RXTX3_CALTXSHIFT_OVR_LSB                                                                  27
-#define PHY_ANALOG_RXTX3_CALTXSHIFT_OVR_MASK                                                         0x08000000
-#define PHY_ANALOG_RXTX3_CALTXSHIFT_OVR_GET(x)                                       (((x) & 0x08000000) >> 27)
-#define PHY_ANALOG_RXTX3_CALTXSHIFT_OVR_SET(x)                                       (((x) << 27) & 0x08000000)
-#define PHY_ANALOG_RXTX3_CALPA_MSB                                                                           28
-#define PHY_ANALOG_RXTX3_CALPA_LSB                                                                           28
-#define PHY_ANALOG_RXTX3_CALPA_MASK                                                                  0x10000000
-#define PHY_ANALOG_RXTX3_CALPA_GET(x)                                                (((x) & 0x10000000) >> 28)
-#define PHY_ANALOG_RXTX3_CALPA_SET(x)                                                (((x) << 28) & 0x10000000)
-#define PHY_ANALOG_RXTX3_CALPA_OVR_MSB                                                                       29
-#define PHY_ANALOG_RXTX3_CALPA_OVR_LSB                                                                       29
-#define PHY_ANALOG_RXTX3_CALPA_OVR_MASK                                                              0x20000000
-#define PHY_ANALOG_RXTX3_CALPA_OVR_GET(x)                                            (((x) & 0x20000000) >> 29)
-#define PHY_ANALOG_RXTX3_CALPA_OVR_SET(x)                                            (((x) << 29) & 0x20000000)
-#define PHY_ANALOG_RXTX3_SPURON_MSB                                                                          30
-#define PHY_ANALOG_RXTX3_SPURON_LSB                                                                          30
-#define PHY_ANALOG_RXTX3_SPURON_MASK                                                                 0x40000000
-#define PHY_ANALOG_RXTX3_SPURON_GET(x)                                               (((x) & 0x40000000) >> 30)
-#define PHY_ANALOG_RXTX3_SPURON_SET(x)                                               (((x) << 30) & 0x40000000)
-#define PHY_ANALOG_RXTX3_SPURON_OVR_MSB                                                                      31
-#define PHY_ANALOG_RXTX3_SPURON_OVR_LSB                                                                      31
-#define PHY_ANALOG_RXTX3_SPURON_OVR_MASK                                                             0x80000000
-#define PHY_ANALOG_RXTX3_SPURON_OVR_GET(x)                                           (((x) & 0x80000000) >> 31)
-#define PHY_ANALOG_RXTX3_SPURON_OVR_SET(x)                                           (((x) << 31) & 0x80000000)
-
-/* macros for BB1 */
-#define PHY_ANALOG_BB1_ADDRESS                                                                       0x00000140
-#define PHY_ANALOG_BB1_OFFSET                                                                        0x00000140
-#define PHY_ANALOG_BB1_I2V_CURR2X_MSB                                                                         0
-#define PHY_ANALOG_BB1_I2V_CURR2X_LSB                                                                         0
-#define PHY_ANALOG_BB1_I2V_CURR2X_MASK                                                               0x00000001
-#define PHY_ANALOG_BB1_I2V_CURR2X_GET(x)                                              (((x) & 0x00000001) >> 0)
-#define PHY_ANALOG_BB1_I2V_CURR2X_SET(x)                                              (((x) << 0) & 0x00000001)
-#define PHY_ANALOG_BB1_ENABLE_LOQ_MSB                                                                         1
-#define PHY_ANALOG_BB1_ENABLE_LOQ_LSB                                                                         1
-#define PHY_ANALOG_BB1_ENABLE_LOQ_MASK                                                               0x00000002
-#define PHY_ANALOG_BB1_ENABLE_LOQ_GET(x)                                              (((x) & 0x00000002) >> 1)
-#define PHY_ANALOG_BB1_ENABLE_LOQ_SET(x)                                              (((x) << 1) & 0x00000002)
-#define PHY_ANALOG_BB1_FORCE_LOQ_MSB                                                                          2
-#define PHY_ANALOG_BB1_FORCE_LOQ_LSB                                                                          2
-#define PHY_ANALOG_BB1_FORCE_LOQ_MASK                                                                0x00000004
-#define PHY_ANALOG_BB1_FORCE_LOQ_GET(x)                                               (((x) & 0x00000004) >> 2)
-#define PHY_ANALOG_BB1_FORCE_LOQ_SET(x)                                               (((x) << 2) & 0x00000004)
-#define PHY_ANALOG_BB1_ENABLE_NOTCH_MSB                                                                       3
-#define PHY_ANALOG_BB1_ENABLE_NOTCH_LSB                                                                       3
-#define PHY_ANALOG_BB1_ENABLE_NOTCH_MASK                                                             0x00000008
-#define PHY_ANALOG_BB1_ENABLE_NOTCH_GET(x)                                            (((x) & 0x00000008) >> 3)
-#define PHY_ANALOG_BB1_ENABLE_NOTCH_SET(x)                                            (((x) << 3) & 0x00000008)
-#define PHY_ANALOG_BB1_FORCE_NOTCH_MSB                                                                        4
-#define PHY_ANALOG_BB1_FORCE_NOTCH_LSB                                                                        4
-#define PHY_ANALOG_BB1_FORCE_NOTCH_MASK                                                              0x00000010
-#define PHY_ANALOG_BB1_FORCE_NOTCH_GET(x)                                             (((x) & 0x00000010) >> 4)
-#define PHY_ANALOG_BB1_FORCE_NOTCH_SET(x)                                             (((x) << 4) & 0x00000010)
-#define PHY_ANALOG_BB1_ENABLE_BIQUAD_MSB                                                                      5
-#define PHY_ANALOG_BB1_ENABLE_BIQUAD_LSB                                                                      5
-#define PHY_ANALOG_BB1_ENABLE_BIQUAD_MASK                                                            0x00000020
-#define PHY_ANALOG_BB1_ENABLE_BIQUAD_GET(x)                                           (((x) & 0x00000020) >> 5)
-#define PHY_ANALOG_BB1_ENABLE_BIQUAD_SET(x)                                           (((x) << 5) & 0x00000020)
-#define PHY_ANALOG_BB1_FORCE_BIQUAD_MSB                                                                       6
-#define PHY_ANALOG_BB1_FORCE_BIQUAD_LSB                                                                       6
-#define PHY_ANALOG_BB1_FORCE_BIQUAD_MASK                                                             0x00000040
-#define PHY_ANALOG_BB1_FORCE_BIQUAD_GET(x)                                            (((x) & 0x00000040) >> 6)
-#define PHY_ANALOG_BB1_FORCE_BIQUAD_SET(x)                                            (((x) << 6) & 0x00000040)
-#define PHY_ANALOG_BB1_ENABLE_OSDAC_MSB                                                                       7
-#define PHY_ANALOG_BB1_ENABLE_OSDAC_LSB                                                                       7
-#define PHY_ANALOG_BB1_ENABLE_OSDAC_MASK                                                             0x00000080
-#define PHY_ANALOG_BB1_ENABLE_OSDAC_GET(x)                                            (((x) & 0x00000080) >> 7)
-#define PHY_ANALOG_BB1_ENABLE_OSDAC_SET(x)                                            (((x) << 7) & 0x00000080)
-#define PHY_ANALOG_BB1_FORCE_OSDAC_MSB                                                                        8
-#define PHY_ANALOG_BB1_FORCE_OSDAC_LSB                                                                        8
-#define PHY_ANALOG_BB1_FORCE_OSDAC_MASK                                                              0x00000100
-#define PHY_ANALOG_BB1_FORCE_OSDAC_GET(x)                                             (((x) & 0x00000100) >> 8)
-#define PHY_ANALOG_BB1_FORCE_OSDAC_SET(x)                                             (((x) << 8) & 0x00000100)
-#define PHY_ANALOG_BB1_ENABLE_V2I_MSB                                                                         9
-#define PHY_ANALOG_BB1_ENABLE_V2I_LSB                                                                         9
-#define PHY_ANALOG_BB1_ENABLE_V2I_MASK                                                               0x00000200
-#define PHY_ANALOG_BB1_ENABLE_V2I_GET(x)                                              (((x) & 0x00000200) >> 9)
-#define PHY_ANALOG_BB1_ENABLE_V2I_SET(x)                                              (((x) << 9) & 0x00000200)
-#define PHY_ANALOG_BB1_FORCE_V2I_MSB                                                                         10
-#define PHY_ANALOG_BB1_FORCE_V2I_LSB                                                                         10
-#define PHY_ANALOG_BB1_FORCE_V2I_MASK                                                                0x00000400
-#define PHY_ANALOG_BB1_FORCE_V2I_GET(x)                                              (((x) & 0x00000400) >> 10)
-#define PHY_ANALOG_BB1_FORCE_V2I_SET(x)                                              (((x) << 10) & 0x00000400)
-#define PHY_ANALOG_BB1_ENABLE_I2V_MSB                                                                        11
-#define PHY_ANALOG_BB1_ENABLE_I2V_LSB                                                                        11
-#define PHY_ANALOG_BB1_ENABLE_I2V_MASK                                                               0x00000800
-#define PHY_ANALOG_BB1_ENABLE_I2V_GET(x)                                             (((x) & 0x00000800) >> 11)
-#define PHY_ANALOG_BB1_ENABLE_I2V_SET(x)                                             (((x) << 11) & 0x00000800)
-#define PHY_ANALOG_BB1_FORCE_I2V_MSB                                                                         12
-#define PHY_ANALOG_BB1_FORCE_I2V_LSB                                                                         12
-#define PHY_ANALOG_BB1_FORCE_I2V_MASK                                                                0x00001000
-#define PHY_ANALOG_BB1_FORCE_I2V_GET(x)                                              (((x) & 0x00001000) >> 12)
-#define PHY_ANALOG_BB1_FORCE_I2V_SET(x)                                              (((x) << 12) & 0x00001000)
-#define PHY_ANALOG_BB1_CMSEL_MSB                                                                             15
-#define PHY_ANALOG_BB1_CMSEL_LSB                                                                             13
-#define PHY_ANALOG_BB1_CMSEL_MASK                                                                    0x0000e000
-#define PHY_ANALOG_BB1_CMSEL_GET(x)                                                  (((x) & 0x0000e000) >> 13)
-#define PHY_ANALOG_BB1_CMSEL_SET(x)                                                  (((x) << 13) & 0x0000e000)
-#define PHY_ANALOG_BB1_ATBSEL_MSB                                                                            17
-#define PHY_ANALOG_BB1_ATBSEL_LSB                                                                            16
-#define PHY_ANALOG_BB1_ATBSEL_MASK                                                                   0x00030000
-#define PHY_ANALOG_BB1_ATBSEL_GET(x)                                                 (((x) & 0x00030000) >> 16)
-#define PHY_ANALOG_BB1_ATBSEL_SET(x)                                                 (((x) << 16) & 0x00030000)
-#define PHY_ANALOG_BB1_PD_OSDAC_CALTX_CALPA_MSB                                                              18
-#define PHY_ANALOG_BB1_PD_OSDAC_CALTX_CALPA_LSB                                                              18
-#define PHY_ANALOG_BB1_PD_OSDAC_CALTX_CALPA_MASK                                                     0x00040000
-#define PHY_ANALOG_BB1_PD_OSDAC_CALTX_CALPA_GET(x)                                   (((x) & 0x00040000) >> 18)
-#define PHY_ANALOG_BB1_PD_OSDAC_CALTX_CALPA_SET(x)                                   (((x) << 18) & 0x00040000)
-#define PHY_ANALOG_BB1_OFSTCORRI2VQ_MSB                                                                      23
-#define PHY_ANALOG_BB1_OFSTCORRI2VQ_LSB                                                                      19
-#define PHY_ANALOG_BB1_OFSTCORRI2VQ_MASK                                                             0x00f80000
-#define PHY_ANALOG_BB1_OFSTCORRI2VQ_GET(x)                                           (((x) & 0x00f80000) >> 19)
-#define PHY_ANALOG_BB1_OFSTCORRI2VQ_SET(x)                                           (((x) << 19) & 0x00f80000)
-#define PHY_ANALOG_BB1_OFSTCORRI2VI_MSB                                                                      28
-#define PHY_ANALOG_BB1_OFSTCORRI2VI_LSB                                                                      24
-#define PHY_ANALOG_BB1_OFSTCORRI2VI_MASK                                                             0x1f000000
-#define PHY_ANALOG_BB1_OFSTCORRI2VI_GET(x)                                           (((x) & 0x1f000000) >> 24)
-#define PHY_ANALOG_BB1_OFSTCORRI2VI_SET(x)                                           (((x) << 24) & 0x1f000000)
-#define PHY_ANALOG_BB1_LOCALOFFSET_MSB                                                                       29
-#define PHY_ANALOG_BB1_LOCALOFFSET_LSB                                                                       29
-#define PHY_ANALOG_BB1_LOCALOFFSET_MASK                                                              0x20000000
-#define PHY_ANALOG_BB1_LOCALOFFSET_GET(x)                                            (((x) & 0x20000000) >> 29)
-#define PHY_ANALOG_BB1_LOCALOFFSET_SET(x)                                            (((x) << 29) & 0x20000000)
-#define PHY_ANALOG_BB1_RANGE_OSDAC_MSB                                                                       31
-#define PHY_ANALOG_BB1_RANGE_OSDAC_LSB                                                                       30
-#define PHY_ANALOG_BB1_RANGE_OSDAC_MASK                                                              0xc0000000
-#define PHY_ANALOG_BB1_RANGE_OSDAC_GET(x)                                            (((x) & 0xc0000000) >> 30)
-#define PHY_ANALOG_BB1_RANGE_OSDAC_SET(x)                                            (((x) << 30) & 0xc0000000)
-
-/* macros for BB2 */
-#define PHY_ANALOG_BB2_ADDRESS                                                                       0x00000144
-#define PHY_ANALOG_BB2_OFFSET                                                                        0x00000144
-#define PHY_ANALOG_BB2_SPARE_MSB                                                                              6
-#define PHY_ANALOG_BB2_SPARE_LSB                                                                              0
-#define PHY_ANALOG_BB2_SPARE_MASK                                                                    0x0000007f
-#define PHY_ANALOG_BB2_SPARE_GET(x)                                                   (((x) & 0x0000007f) >> 0)
-#define PHY_ANALOG_BB2_SPARE_SET(x)                                                   (((x) << 0) & 0x0000007f)
-#define PHY_ANALOG_BB2_SEL_TEST_MSB                                                                           9
-#define PHY_ANALOG_BB2_SEL_TEST_LSB                                                                           7
-#define PHY_ANALOG_BB2_SEL_TEST_MASK                                                                 0x00000380
-#define PHY_ANALOG_BB2_SEL_TEST_GET(x)                                                (((x) & 0x00000380) >> 7)
-#define PHY_ANALOG_BB2_SEL_TEST_SET(x)                                                (((x) << 7) & 0x00000380)
-#define PHY_ANALOG_BB2_SCFIR_CAP_MSB                                                                         14
-#define PHY_ANALOG_BB2_SCFIR_CAP_LSB                                                                         10
-#define PHY_ANALOG_BB2_SCFIR_CAP_MASK                                                                0x00007c00
-#define PHY_ANALOG_BB2_SCFIR_CAP_GET(x)                                              (((x) & 0x00007c00) >> 10)
-#define PHY_ANALOG_BB2_SCFIR_CAP_SET(x)                                              (((x) << 10) & 0x00007c00)
-#define PHY_ANALOG_BB2_OVERRIDE_SCFIR_CAP_MSB                                                                15
-#define PHY_ANALOG_BB2_OVERRIDE_SCFIR_CAP_LSB                                                                15
-#define PHY_ANALOG_BB2_OVERRIDE_SCFIR_CAP_MASK                                                       0x00008000
-#define PHY_ANALOG_BB2_OVERRIDE_SCFIR_CAP_GET(x)                                     (((x) & 0x00008000) >> 15)
-#define PHY_ANALOG_BB2_OVERRIDE_SCFIR_CAP_SET(x)                                     (((x) << 15) & 0x00008000)
-#define PHY_ANALOG_BB2_FNOTCH_MSB                                                                            19
-#define PHY_ANALOG_BB2_FNOTCH_LSB                                                                            16
-#define PHY_ANALOG_BB2_FNOTCH_MASK                                                                   0x000f0000
-#define PHY_ANALOG_BB2_FNOTCH_GET(x)                                                 (((x) & 0x000f0000) >> 16)
-#define PHY_ANALOG_BB2_FNOTCH_SET(x)                                                 (((x) << 16) & 0x000f0000)
-#define PHY_ANALOG_BB2_OVERRIDE_FNOTCH_MSB                                                                   20
-#define PHY_ANALOG_BB2_OVERRIDE_FNOTCH_LSB                                                                   20
-#define PHY_ANALOG_BB2_OVERRIDE_FNOTCH_MASK                                                          0x00100000
-#define PHY_ANALOG_BB2_OVERRIDE_FNOTCH_GET(x)                                        (((x) & 0x00100000) >> 20)
-#define PHY_ANALOG_BB2_OVERRIDE_FNOTCH_SET(x)                                        (((x) << 20) & 0x00100000)
-#define PHY_ANALOG_BB2_FILTERFC_MSB                                                                          25
-#define PHY_ANALOG_BB2_FILTERFC_LSB                                                                          21
-#define PHY_ANALOG_BB2_FILTERFC_MASK                                                                 0x03e00000
-#define PHY_ANALOG_BB2_FILTERFC_GET(x)                                               (((x) & 0x03e00000) >> 21)
-#define PHY_ANALOG_BB2_FILTERFC_SET(x)                                               (((x) << 21) & 0x03e00000)
-#define PHY_ANALOG_BB2_OVERRIDE_FILTERFC_MSB                                                                 26
-#define PHY_ANALOG_BB2_OVERRIDE_FILTERFC_LSB                                                                 26
-#define PHY_ANALOG_BB2_OVERRIDE_FILTERFC_MASK                                                        0x04000000
-#define PHY_ANALOG_BB2_OVERRIDE_FILTERFC_GET(x)                                      (((x) & 0x04000000) >> 26)
-#define PHY_ANALOG_BB2_OVERRIDE_FILTERFC_SET(x)                                      (((x) << 26) & 0x04000000)
-#define PHY_ANALOG_BB2_I2V2RXOUT_EN_MSB                                                                      27
-#define PHY_ANALOG_BB2_I2V2RXOUT_EN_LSB                                                                      27
-#define PHY_ANALOG_BB2_I2V2RXOUT_EN_MASK                                                             0x08000000
-#define PHY_ANALOG_BB2_I2V2RXOUT_EN_GET(x)                                           (((x) & 0x08000000) >> 27)
-#define PHY_ANALOG_BB2_I2V2RXOUT_EN_SET(x)                                           (((x) << 27) & 0x08000000)
-#define PHY_ANALOG_BB2_BQ2RXOUT_EN_MSB                                                                       28
-#define PHY_ANALOG_BB2_BQ2RXOUT_EN_LSB                                                                       28
-#define PHY_ANALOG_BB2_BQ2RXOUT_EN_MASK                                                              0x10000000
-#define PHY_ANALOG_BB2_BQ2RXOUT_EN_GET(x)                                            (((x) & 0x10000000) >> 28)
-#define PHY_ANALOG_BB2_BQ2RXOUT_EN_SET(x)                                            (((x) << 28) & 0x10000000)
-#define PHY_ANALOG_BB2_RXIN2I2V_EN_MSB                                                                       29
-#define PHY_ANALOG_BB2_RXIN2I2V_EN_LSB                                                                       29
-#define PHY_ANALOG_BB2_RXIN2I2V_EN_MASK                                                              0x20000000
-#define PHY_ANALOG_BB2_RXIN2I2V_EN_GET(x)                                            (((x) & 0x20000000) >> 29)
-#define PHY_ANALOG_BB2_RXIN2I2V_EN_SET(x)                                            (((x) << 29) & 0x20000000)
-#define PHY_ANALOG_BB2_RXIN2BQ_EN_MSB                                                                        30
-#define PHY_ANALOG_BB2_RXIN2BQ_EN_LSB                                                                        30
-#define PHY_ANALOG_BB2_RXIN2BQ_EN_MASK                                                               0x40000000
-#define PHY_ANALOG_BB2_RXIN2BQ_EN_GET(x)                                             (((x) & 0x40000000) >> 30)
-#define PHY_ANALOG_BB2_RXIN2BQ_EN_SET(x)                                             (((x) << 30) & 0x40000000)
-#define PHY_ANALOG_BB2_SWITCH_OVERRIDE_MSB                                                                   31
-#define PHY_ANALOG_BB2_SWITCH_OVERRIDE_LSB                                                                   31
-#define PHY_ANALOG_BB2_SWITCH_OVERRIDE_MASK                                                          0x80000000
-#define PHY_ANALOG_BB2_SWITCH_OVERRIDE_GET(x)                                        (((x) & 0x80000000) >> 31)
-#define PHY_ANALOG_BB2_SWITCH_OVERRIDE_SET(x)                                        (((x) << 31) & 0x80000000)
-
-/* macros for TOP1 */
-#define PHY_ANALOG_TOP1_ADDRESS                                                                      0x00000280
-#define PHY_ANALOG_TOP1_OFFSET                                                                       0x00000280
-#define PHY_ANALOG_TOP1_SEL_KVCO_MSB                                                                          1
-#define PHY_ANALOG_TOP1_SEL_KVCO_LSB                                                                          0
-#define PHY_ANALOG_TOP1_SEL_KVCO_MASK                                                                0x00000003
-#define PHY_ANALOG_TOP1_SEL_KVCO_GET(x)                                               (((x) & 0x00000003) >> 0)
-#define PHY_ANALOG_TOP1_SEL_KVCO_SET(x)                                               (((x) << 0) & 0x00000003)
-#define PHY_ANALOG_TOP1_PLLATB_MSB                                                                            3
-#define PHY_ANALOG_TOP1_PLLATB_LSB                                                                            2
-#define PHY_ANALOG_TOP1_PLLATB_MASK                                                                  0x0000000c
-#define PHY_ANALOG_TOP1_PLLATB_GET(x)                                                 (((x) & 0x0000000c) >> 2)
-#define PHY_ANALOG_TOP1_PLLATB_SET(x)                                                 (((x) << 2) & 0x0000000c)
-#define PHY_ANALOG_TOP1_PLL_SVREG_MSB                                                                         4
-#define PHY_ANALOG_TOP1_PLL_SVREG_LSB                                                                         4
-#define PHY_ANALOG_TOP1_PLL_SVREG_MASK                                                               0x00000010
-#define PHY_ANALOG_TOP1_PLL_SVREG_GET(x)                                              (((x) & 0x00000010) >> 4)
-#define PHY_ANALOG_TOP1_PLL_SVREG_SET(x)                                              (((x) << 4) & 0x00000010)
-#define PHY_ANALOG_TOP1_HI_FREQ_EN_MSB                                                                        5
-#define PHY_ANALOG_TOP1_HI_FREQ_EN_LSB                                                                        5
-#define PHY_ANALOG_TOP1_HI_FREQ_EN_MASK                                                              0x00000020
-#define PHY_ANALOG_TOP1_HI_FREQ_EN_GET(x)                                             (((x) & 0x00000020) >> 5)
-#define PHY_ANALOG_TOP1_HI_FREQ_EN_SET(x)                                             (((x) << 5) & 0x00000020)
-#define PHY_ANALOG_TOP1_PWDPLL_MSB                                                                            6
-#define PHY_ANALOG_TOP1_PWDPLL_LSB                                                                            6
-#define PHY_ANALOG_TOP1_PWDPLL_MASK                                                                  0x00000040
-#define PHY_ANALOG_TOP1_PWDPLL_GET(x)                                                 (((x) & 0x00000040) >> 6)
-#define PHY_ANALOG_TOP1_PWDPLL_SET(x)                                                 (((x) << 6) & 0x00000040)
-#define PHY_ANALOG_TOP1_PWDEXTCLKBUF_MSB                                                                      7
-#define PHY_ANALOG_TOP1_PWDEXTCLKBUF_LSB                                                                      7
-#define PHY_ANALOG_TOP1_PWDEXTCLKBUF_MASK                                                            0x00000080
-#define PHY_ANALOG_TOP1_PWDEXTCLKBUF_GET(x)                                           (((x) & 0x00000080) >> 7)
-#define PHY_ANALOG_TOP1_PWDEXTCLKBUF_SET(x)                                           (((x) << 7) & 0x00000080)
-#define PHY_ANALOG_TOP1_ADCPWD_PHASE_MSB                                                                      9
-#define PHY_ANALOG_TOP1_ADCPWD_PHASE_LSB                                                                      8
-#define PHY_ANALOG_TOP1_ADCPWD_PHASE_MASK                                                            0x00000300
-#define PHY_ANALOG_TOP1_ADCPWD_PHASE_GET(x)                                           (((x) & 0x00000300) >> 8)
-#define PHY_ANALOG_TOP1_ADCPWD_PHASE_SET(x)                                           (((x) << 8) & 0x00000300)
-#define PHY_ANALOG_TOP1_ADCCLK_PHASE_MSB                                                                     11
-#define PHY_ANALOG_TOP1_ADCCLK_PHASE_LSB                                                                     10
-#define PHY_ANALOG_TOP1_ADCCLK_PHASE_MASK                                                            0x00000c00
-#define PHY_ANALOG_TOP1_ADCCLK_PHASE_GET(x)                                          (((x) & 0x00000c00) >> 10)
-#define PHY_ANALOG_TOP1_ADCCLK_PHASE_SET(x)                                          (((x) << 10) & 0x00000c00)
-#define PHY_ANALOG_TOP1_DAC_CLK_SEL_MSB                                                                      13
-#define PHY_ANALOG_TOP1_DAC_CLK_SEL_LSB                                                                      12
-#define PHY_ANALOG_TOP1_DAC_CLK_SEL_MASK                                                             0x00003000
-#define PHY_ANALOG_TOP1_DAC_CLK_SEL_GET(x)                                           (((x) & 0x00003000) >> 12)
-#define PHY_ANALOG_TOP1_DAC_CLK_SEL_SET(x)                                           (((x) << 12) & 0x00003000)
-#define PHY_ANALOG_TOP1_ADC_CLK_SEL_MSB                                                                      15
-#define PHY_ANALOG_TOP1_ADC_CLK_SEL_LSB                                                                      14
-#define PHY_ANALOG_TOP1_ADC_CLK_SEL_MASK                                                             0x0000c000
-#define PHY_ANALOG_TOP1_ADC_CLK_SEL_GET(x)                                           (((x) & 0x0000c000) >> 14)
-#define PHY_ANALOG_TOP1_ADC_CLK_SEL_SET(x)                                           (((x) << 14) & 0x0000c000)
-#define PHY_ANALOG_TOP1_REFDIV_MSB                                                                           19
-#define PHY_ANALOG_TOP1_REFDIV_LSB                                                                           16
-#define PHY_ANALOG_TOP1_REFDIV_MASK                                                                  0x000f0000
-#define PHY_ANALOG_TOP1_REFDIV_GET(x)                                                (((x) & 0x000f0000) >> 16)
-#define PHY_ANALOG_TOP1_REFDIV_SET(x)                                                (((x) << 16) & 0x000f0000)
-#define PHY_ANALOG_TOP1_DIV_MSB                                                                              29
-#define PHY_ANALOG_TOP1_DIV_LSB                                                                              20
-#define PHY_ANALOG_TOP1_DIV_MASK                                                                     0x3ff00000
-#define PHY_ANALOG_TOP1_DIV_GET(x)                                                   (((x) & 0x3ff00000) >> 20)
-#define PHY_ANALOG_TOP1_DIV_SET(x)                                                   (((x) << 20) & 0x3ff00000)
-#define PHY_ANALOG_TOP1_PLLBYPASS_MSB                                                                        30
-#define PHY_ANALOG_TOP1_PLLBYPASS_LSB                                                                        30
-#define PHY_ANALOG_TOP1_PLLBYPASS_MASK                                                               0x40000000
-#define PHY_ANALOG_TOP1_PLLBYPASS_GET(x)                                             (((x) & 0x40000000) >> 30)
-#define PHY_ANALOG_TOP1_PLLBYPASS_SET(x)                                             (((x) << 30) & 0x40000000)
-#define PHY_ANALOG_TOP1_CLKMOD_RSTB_MSB                                                                      31
-#define PHY_ANALOG_TOP1_CLKMOD_RSTB_LSB                                                                      31
-#define PHY_ANALOG_TOP1_CLKMOD_RSTB_MASK                                                             0x80000000
-#define PHY_ANALOG_TOP1_CLKMOD_RSTB_GET(x)                                           (((x) & 0x80000000) >> 31)
-#define PHY_ANALOG_TOP1_CLKMOD_RSTB_SET(x)                                           (((x) << 31) & 0x80000000)
-
-/* macros for TOP2 */
-#define PHY_ANALOG_TOP2_ADDRESS                                                                      0x00000284
-#define PHY_ANALOG_TOP2_OFFSET                                                                       0x00000284
-#define PHY_ANALOG_TOP2_PLL_LOWLEAK_MSB                                                                       0
-#define PHY_ANALOG_TOP2_PLL_LOWLEAK_LSB                                                                       0
-#define PHY_ANALOG_TOP2_PLL_LOWLEAK_MASK                                                             0x00000001
-#define PHY_ANALOG_TOP2_PLL_LOWLEAK_GET(x)                                            (((x) & 0x00000001) >> 0)
-#define PHY_ANALOG_TOP2_PLL_LOWLEAK_SET(x)                                            (((x) << 0) & 0x00000001)
-#define PHY_ANALOG_TOP2_PLL_LEAK_MSB                                                                          4
-#define PHY_ANALOG_TOP2_PLL_LEAK_LSB                                                                          1
-#define PHY_ANALOG_TOP2_PLL_LEAK_MASK                                                                0x0000001e
-#define PHY_ANALOG_TOP2_PLL_LEAK_GET(x)                                               (((x) & 0x0000001e) >> 1)
-#define PHY_ANALOG_TOP2_PLL_LEAK_SET(x)                                               (((x) << 1) & 0x0000001e)
-#define PHY_ANALOG_TOP2_PLLFRAC_MSB                                                                          19
-#define PHY_ANALOG_TOP2_PLLFRAC_LSB                                                                           5
-#define PHY_ANALOG_TOP2_PLLFRAC_MASK                                                                 0x000fffe0
-#define PHY_ANALOG_TOP2_PLLFRAC_GET(x)                                                (((x) & 0x000fffe0) >> 5)
-#define PHY_ANALOG_TOP2_PLLFRAC_SET(x)                                                (((x) << 5) & 0x000fffe0)
-#define PHY_ANALOG_TOP2_PWD_PLLSDM_MSB                                                                       20
-#define PHY_ANALOG_TOP2_PWD_PLLSDM_LSB                                                                       20
-#define PHY_ANALOG_TOP2_PWD_PLLSDM_MASK                                                              0x00100000
-#define PHY_ANALOG_TOP2_PWD_PLLSDM_GET(x)                                            (((x) & 0x00100000) >> 20)
-#define PHY_ANALOG_TOP2_PWD_PLLSDM_SET(x)                                            (((x) << 20) & 0x00100000)
-#define PHY_ANALOG_TOP2_PLLICP_MSB                                                                           23
-#define PHY_ANALOG_TOP2_PLLICP_LSB                                                                           21
-#define PHY_ANALOG_TOP2_PLLICP_MASK                                                                  0x00e00000
-#define PHY_ANALOG_TOP2_PLLICP_GET(x)                                                (((x) & 0x00e00000) >> 21)
-#define PHY_ANALOG_TOP2_PLLICP_SET(x)                                                (((x) << 21) & 0x00e00000)
-#define PHY_ANALOG_TOP2_PLLFILTER_MSB                                                                        31
-#define PHY_ANALOG_TOP2_PLLFILTER_LSB                                                                        24
-#define PHY_ANALOG_TOP2_PLLFILTER_MASK                                                               0xff000000
-#define PHY_ANALOG_TOP2_PLLFILTER_GET(x)                                             (((x) & 0xff000000) >> 24)
-#define PHY_ANALOG_TOP2_PLLFILTER_SET(x)                                             (((x) << 24) & 0xff000000)
-
-/* macros for TOP3 */
-#define PHY_ANALOG_TOP3_ADDRESS                                                                      0x00000288
-#define PHY_ANALOG_TOP3_OFFSET                                                                       0x00000288
-#define PHY_ANALOG_TOP3_INT2GND_MSB                                                                           0
-#define PHY_ANALOG_TOP3_INT2GND_LSB                                                                           0
-#define PHY_ANALOG_TOP3_INT2GND_MASK                                                                 0x00000001
-#define PHY_ANALOG_TOP3_INT2GND_GET(x)                                                (((x) & 0x00000001) >> 0)
-#define PHY_ANALOG_TOP3_INT2GND_SET(x)                                                (((x) << 0) & 0x00000001)
-#define PHY_ANALOG_TOP3_PWDPALCLK_MSB                                                                         1
-#define PHY_ANALOG_TOP3_PWDPALCLK_LSB                                                                         1
-#define PHY_ANALOG_TOP3_PWDPALCLK_MASK                                                               0x00000002
-#define PHY_ANALOG_TOP3_PWDPALCLK_GET(x)                                              (((x) & 0x00000002) >> 1)
-#define PHY_ANALOG_TOP3_PWDPALCLK_SET(x)                                              (((x) << 1) & 0x00000002)
-#define PHY_ANALOG_TOP3_PWDAGCCLK_MSB                                                                         2
-#define PHY_ANALOG_TOP3_PWDAGCCLK_LSB                                                                         2
-#define PHY_ANALOG_TOP3_PWDAGCCLK_MASK                                                               0x00000004
-#define PHY_ANALOG_TOP3_PWDAGCCLK_GET(x)                                              (((x) & 0x00000004) >> 2)
-#define PHY_ANALOG_TOP3_PWDAGCCLK_SET(x)                                              (((x) << 2) & 0x00000004)
-#define PHY_ANALOG_TOP3_PWDV2I_MSB                                                                            3
-#define PHY_ANALOG_TOP3_PWDV2I_LSB                                                                            3
-#define PHY_ANALOG_TOP3_PWDV2I_MASK                                                                  0x00000008
-#define PHY_ANALOG_TOP3_PWDV2I_GET(x)                                                 (((x) & 0x00000008) >> 3)
-#define PHY_ANALOG_TOP3_PWDV2I_SET(x)                                                 (((x) << 3) & 0x00000008)
-#define PHY_ANALOG_TOP3_PWDBIAS_MSB                                                                           4
-#define PHY_ANALOG_TOP3_PWDBIAS_LSB                                                                           4
-#define PHY_ANALOG_TOP3_PWDBIAS_MASK                                                                 0x00000010
-#define PHY_ANALOG_TOP3_PWDBIAS_GET(x)                                                (((x) & 0x00000010) >> 4)
-#define PHY_ANALOG_TOP3_PWDBIAS_SET(x)                                                (((x) << 4) & 0x00000010)
-#define PHY_ANALOG_TOP3_PWDBG_MSB                                                                             5
-#define PHY_ANALOG_TOP3_PWDBG_LSB                                                                             5
-#define PHY_ANALOG_TOP3_PWDBG_MASK                                                                   0x00000020
-#define PHY_ANALOG_TOP3_PWDBG_GET(x)                                                  (((x) & 0x00000020) >> 5)
-#define PHY_ANALOG_TOP3_PWDBG_SET(x)                                                  (((x) << 5) & 0x00000020)
-#define PHY_ANALOG_TOP3_XTAL_SELVREG_MSB                                                                      6
-#define PHY_ANALOG_TOP3_XTAL_SELVREG_LSB                                                                      6
-#define PHY_ANALOG_TOP3_XTAL_SELVREG_MASK                                                            0x00000040
-#define PHY_ANALOG_TOP3_XTAL_SELVREG_GET(x)                                           (((x) & 0x00000040) >> 6)
-#define PHY_ANALOG_TOP3_XTAL_SELVREG_SET(x)                                           (((x) << 6) & 0x00000040)
-#define PHY_ANALOG_TOP3_XTAL_PWDREG_MSB                                                                       7
-#define PHY_ANALOG_TOP3_XTAL_PWDREG_LSB                                                                       7
-#define PHY_ANALOG_TOP3_XTAL_PWDREG_MASK                                                             0x00000080
-#define PHY_ANALOG_TOP3_XTAL_PWDREG_GET(x)                                            (((x) & 0x00000080) >> 7)
-#define PHY_ANALOG_TOP3_XTAL_PWDREG_SET(x)                                            (((x) << 7) & 0x00000080)
-#define PHY_ANALOG_TOP3_XTAL_PWDCLKIN_MSB                                                                     8
-#define PHY_ANALOG_TOP3_XTAL_PWDCLKIN_LSB                                                                     8
-#define PHY_ANALOG_TOP3_XTAL_PWDCLKIN_MASK                                                           0x00000100
-#define PHY_ANALOG_TOP3_XTAL_PWDCLKIN_GET(x)                                          (((x) & 0x00000100) >> 8)
-#define PHY_ANALOG_TOP3_XTAL_PWDCLKIN_SET(x)                                          (((x) << 8) & 0x00000100)
-#define PHY_ANALOG_TOP3_XTAL_PWDCLKD_MSB                                                                      9
-#define PHY_ANALOG_TOP3_XTAL_PWDCLKD_LSB                                                                      9
-#define PHY_ANALOG_TOP3_XTAL_PWDCLKD_MASK                                                            0x00000200
-#define PHY_ANALOG_TOP3_XTAL_PWDCLKD_GET(x)                                           (((x) & 0x00000200) >> 9)
-#define PHY_ANALOG_TOP3_XTAL_PWDCLKD_SET(x)                                           (((x) << 9) & 0x00000200)
-#define PHY_ANALOG_TOP3_XTAL_OSCON_MSB                                                                       10
-#define PHY_ANALOG_TOP3_XTAL_OSCON_LSB                                                                       10
-#define PHY_ANALOG_TOP3_XTAL_OSCON_MASK                                                              0x00000400
-#define PHY_ANALOG_TOP3_XTAL_OSCON_GET(x)                                            (((x) & 0x00000400) >> 10)
-#define PHY_ANALOG_TOP3_XTAL_OSCON_SET(x)                                            (((x) << 10) & 0x00000400)
-#define PHY_ANALOG_TOP3_XTAL_NOTCXODET_MSB                                                                   11
-#define PHY_ANALOG_TOP3_XTAL_NOTCXODET_LSB                                                                   11
-#define PHY_ANALOG_TOP3_XTAL_NOTCXODET_MASK                                                          0x00000800
-#define PHY_ANALOG_TOP3_XTAL_NOTCXODET_GET(x)                                        (((x) & 0x00000800) >> 11)
-#define PHY_ANALOG_TOP3_XTAL_NOTCXODET_SET(x)                                        (((x) << 11) & 0x00000800)
-#define PHY_ANALOG_TOP3_XTAL_LOCALBIAS_MSB                                                                   12
-#define PHY_ANALOG_TOP3_XTAL_LOCALBIAS_LSB                                                                   12
-#define PHY_ANALOG_TOP3_XTAL_LOCALBIAS_MASK                                                          0x00001000
-#define PHY_ANALOG_TOP3_XTAL_LOCALBIAS_GET(x)                                        (((x) & 0x00001000) >> 12)
-#define PHY_ANALOG_TOP3_XTAL_LOCALBIAS_SET(x)                                        (((x) << 12) & 0x00001000)
-#define PHY_ANALOG_TOP3_XTAL_HIGHZ_MSB                                                                       13
-#define PHY_ANALOG_TOP3_XTAL_HIGHZ_LSB                                                                       13
-#define PHY_ANALOG_TOP3_XTAL_HIGHZ_MASK                                                              0x00002000
-#define PHY_ANALOG_TOP3_XTAL_HIGHZ_GET(x)                                            (((x) & 0x00002000) >> 13)
-#define PHY_ANALOG_TOP3_XTAL_HIGHZ_SET(x)                                            (((x) << 13) & 0x00002000)
-#define PHY_ANALOG_TOP3_XTAL_DRVPNR_MSB                                                                      15
-#define PHY_ANALOG_TOP3_XTAL_DRVPNR_LSB                                                                      14
-#define PHY_ANALOG_TOP3_XTAL_DRVPNR_MASK                                                             0x0000c000
-#define PHY_ANALOG_TOP3_XTAL_DRVPNR_GET(x)                                           (((x) & 0x0000c000) >> 14)
-#define PHY_ANALOG_TOP3_XTAL_DRVPNR_SET(x)                                           (((x) << 14) & 0x0000c000)
-#define PHY_ANALOG_TOP3_XTALCAPOUTDAC_MSB                                                                    22
-#define PHY_ANALOG_TOP3_XTALCAPOUTDAC_LSB                                                                    16
-#define PHY_ANALOG_TOP3_XTALCAPOUTDAC_MASK                                                           0x007f0000
-#define PHY_ANALOG_TOP3_XTALCAPOUTDAC_GET(x)                                         (((x) & 0x007f0000) >> 16)
-#define PHY_ANALOG_TOP3_XTALCAPOUTDAC_SET(x)                                         (((x) << 16) & 0x007f0000)
-#define PHY_ANALOG_TOP3_XTAL_CAPINDAC_MSB                                                                    29
-#define PHY_ANALOG_TOP3_XTAL_CAPINDAC_LSB                                                                    23
-#define PHY_ANALOG_TOP3_XTAL_CAPINDAC_MASK                                                           0x3f800000
-#define PHY_ANALOG_TOP3_XTAL_CAPINDAC_GET(x)                                         (((x) & 0x3f800000) >> 23)
-#define PHY_ANALOG_TOP3_XTAL_CAPINDAC_SET(x)                                         (((x) << 23) & 0x3f800000)
-#define PHY_ANALOG_TOP3_XTAL_BIAS2X_MSB                                                                      30
-#define PHY_ANALOG_TOP3_XTAL_BIAS2X_LSB                                                                      30
-#define PHY_ANALOG_TOP3_XTAL_BIAS2X_MASK                                                             0x40000000
-#define PHY_ANALOG_TOP3_XTAL_BIAS2X_GET(x)                                           (((x) & 0x40000000) >> 30)
-#define PHY_ANALOG_TOP3_XTAL_BIAS2X_SET(x)                                           (((x) << 30) & 0x40000000)
-#define PHY_ANALOG_TOP3_TCXODET_MSB                                                                          31
-#define PHY_ANALOG_TOP3_TCXODET_LSB                                                                          31
-#define PHY_ANALOG_TOP3_TCXODET_MASK                                                                 0x80000000
-#define PHY_ANALOG_TOP3_TCXODET_GET(x)                                               (((x) & 0x80000000) >> 31)
-
-/* macros for TOP4 */
-#define PHY_ANALOG_TOP4_ADDRESS                                                                      0x0000028c
-#define PHY_ANALOG_TOP4_OFFSET                                                                       0x0000028c
-#define PHY_ANALOG_TOP4_SPARE4_MSB                                                                           19
-#define PHY_ANALOG_TOP4_SPARE4_LSB                                                                            0
-#define PHY_ANALOG_TOP4_SPARE4_MASK                                                                  0x000fffff
-#define PHY_ANALOG_TOP4_SPARE4_GET(x)                                                 (((x) & 0x000fffff) >> 0)
-#define PHY_ANALOG_TOP4_SPARE4_SET(x)                                                 (((x) << 0) & 0x000fffff)
-#define PHY_ANALOG_TOP4_SEL_TEMPSENSOR_MSB                                                                   20
-#define PHY_ANALOG_TOP4_SEL_TEMPSENSOR_LSB                                                                   20
-#define PHY_ANALOG_TOP4_SEL_TEMPSENSOR_MASK                                                          0x00100000
-#define PHY_ANALOG_TOP4_SEL_TEMPSENSOR_GET(x)                                        (((x) & 0x00100000) >> 20)
-#define PHY_ANALOG_TOP4_SEL_TEMPSENSOR_SET(x)                                        (((x) << 20) & 0x00100000)
-#define PHY_ANALOG_TOP4_ADCPWD_OVR_MSB                                                                       21
-#define PHY_ANALOG_TOP4_ADCPWD_OVR_LSB                                                                       21
-#define PHY_ANALOG_TOP4_ADCPWD_OVR_MASK                                                              0x00200000
-#define PHY_ANALOG_TOP4_ADCPWD_OVR_GET(x)                                            (((x) & 0x00200000) >> 21)
-#define PHY_ANALOG_TOP4_ADCPWD_OVR_SET(x)                                            (((x) << 21) & 0x00200000)
-#define PHY_ANALOG_TOP4_ADCPWD_INT_MSB                                                                       22
-#define PHY_ANALOG_TOP4_ADCPWD_INT_LSB                                                                       22
-#define PHY_ANALOG_TOP4_ADCPWD_INT_MASK                                                              0x00400000
-#define PHY_ANALOG_TOP4_ADCPWD_INT_GET(x)                                            (((x) & 0x00400000) >> 22)
-#define PHY_ANALOG_TOP4_ADCPWD_INT_SET(x)                                            (((x) << 22) & 0x00400000)
-#define PHY_ANALOG_TOP4_TESTIQ_OFF_MSB                                                                       23
-#define PHY_ANALOG_TOP4_TESTIQ_OFF_LSB                                                                       23
-#define PHY_ANALOG_TOP4_TESTIQ_OFF_MASK                                                              0x00800000
-#define PHY_ANALOG_TOP4_TESTIQ_OFF_GET(x)                                            (((x) & 0x00800000) >> 23)
-#define PHY_ANALOG_TOP4_TESTIQ_OFF_SET(x)                                            (((x) << 23) & 0x00800000)
-#define PHY_ANALOG_TOP4_TESTIQ_BUFEN_MSB                                                                     24
-#define PHY_ANALOG_TOP4_TESTIQ_BUFEN_LSB                                                                     24
-#define PHY_ANALOG_TOP4_TESTIQ_BUFEN_MASK                                                            0x01000000
-#define PHY_ANALOG_TOP4_TESTIQ_BUFEN_GET(x)                                          (((x) & 0x01000000) >> 24)
-#define PHY_ANALOG_TOP4_TESTIQ_BUFEN_SET(x)                                          (((x) << 24) & 0x01000000)
-#define PHY_ANALOG_TOP4_PAL_LOCKEDEN_MSB                                                                     25
-#define PHY_ANALOG_TOP4_PAL_LOCKEDEN_LSB                                                                     25
-#define PHY_ANALOG_TOP4_PAL_LOCKEDEN_MASK                                                            0x02000000
-#define PHY_ANALOG_TOP4_PAL_LOCKEDEN_GET(x)                                          (((x) & 0x02000000) >> 25)
-#define PHY_ANALOG_TOP4_PAL_LOCKEDEN_SET(x)                                          (((x) << 25) & 0x02000000)
-#define PHY_ANALOG_TOP4_SYNTHDIGOUTEN_MSB                                                                    26
-#define PHY_ANALOG_TOP4_SYNTHDIGOUTEN_LSB                                                                    26
-#define PHY_ANALOG_TOP4_SYNTHDIGOUTEN_MASK                                                           0x04000000
-#define PHY_ANALOG_TOP4_SYNTHDIGOUTEN_GET(x)                                         (((x) & 0x04000000) >> 26)
-#define PHY_ANALOG_TOP4_SYNTHDIGOUTEN_SET(x)                                         (((x) << 26) & 0x04000000)
-#define PHY_ANALOG_TOP4_ENBTCLK_MSB                                                                          27
-#define PHY_ANALOG_TOP4_ENBTCLK_LSB                                                                          27
-#define PHY_ANALOG_TOP4_ENBTCLK_MASK                                                                 0x08000000
-#define PHY_ANALOG_TOP4_ENBTCLK_GET(x)                                               (((x) & 0x08000000) >> 27)
-#define PHY_ANALOG_TOP4_ENBTCLK_SET(x)                                               (((x) << 27) & 0x08000000)
-#define PHY_ANALOG_TOP4_PAD2GND_MSB                                                                          28
-#define PHY_ANALOG_TOP4_PAD2GND_LSB                                                                          28
-#define PHY_ANALOG_TOP4_PAD2GND_MASK                                                                 0x10000000
-#define PHY_ANALOG_TOP4_PAD2GND_GET(x)                                               (((x) & 0x10000000) >> 28)
-#define PHY_ANALOG_TOP4_PAD2GND_SET(x)                                               (((x) << 28) & 0x10000000)
-#define PHY_ANALOG_TOP4_INTH2PAD_MSB                                                                         29
-#define PHY_ANALOG_TOP4_INTH2PAD_LSB                                                                         29
-#define PHY_ANALOG_TOP4_INTH2PAD_MASK                                                                0x20000000
-#define PHY_ANALOG_TOP4_INTH2PAD_GET(x)                                              (((x) & 0x20000000) >> 29)
-#define PHY_ANALOG_TOP4_INTH2PAD_SET(x)                                              (((x) << 29) & 0x20000000)
-#define PHY_ANALOG_TOP4_INTH2GND_MSB                                                                         30
-#define PHY_ANALOG_TOP4_INTH2GND_LSB                                                                         30
-#define PHY_ANALOG_TOP4_INTH2GND_MASK                                                                0x40000000
-#define PHY_ANALOG_TOP4_INTH2GND_GET(x)                                              (((x) & 0x40000000) >> 30)
-#define PHY_ANALOG_TOP4_INTH2GND_SET(x)                                              (((x) << 30) & 0x40000000)
-#define PHY_ANALOG_TOP4_INT2PAD_MSB                                                                          31
-#define PHY_ANALOG_TOP4_INT2PAD_LSB                                                                          31
-#define PHY_ANALOG_TOP4_INT2PAD_MASK                                                                 0x80000000
-#define PHY_ANALOG_TOP4_INT2PAD_GET(x)                                               (((x) & 0x80000000) >> 31)
-#define PHY_ANALOG_TOP4_INT2PAD_SET(x)                                               (((x) << 31) & 0x80000000)
-
-/* macros for rbist_cntrl */
-#define PHY_ANALOG_RBIST_CNTRL_ADDRESS                                                               0x00000380
-#define PHY_ANALOG_RBIST_CNTRL_OFFSET                                                                0x00000380
-#define PHY_ANALOG_RBIST_CNTRL_ATE_TONEGEN_DC_ENABLE_MSB                                                      0
-#define PHY_ANALOG_RBIST_CNTRL_ATE_TONEGEN_DC_ENABLE_LSB                                                      0
-#define PHY_ANALOG_RBIST_CNTRL_ATE_TONEGEN_DC_ENABLE_MASK                                            0x00000001
-#define PHY_ANALOG_RBIST_CNTRL_ATE_TONEGEN_DC_ENABLE_GET(x)                           (((x) & 0x00000001) >> 0)
-#define PHY_ANALOG_RBIST_CNTRL_ATE_TONEGEN_DC_ENABLE_SET(x)                           (((x) << 0) & 0x00000001)
-#define PHY_ANALOG_RBIST_CNTRL_ATE_TONEGEN_TONE0_ENABLE_MSB                                                   1
-#define PHY_ANALOG_RBIST_CNTRL_ATE_TONEGEN_TONE0_ENABLE_LSB                                                   1
-#define PHY_ANALOG_RBIST_CNTRL_ATE_TONEGEN_TONE0_ENABLE_MASK                                         0x00000002
-#define PHY_ANALOG_RBIST_CNTRL_ATE_TONEGEN_TONE0_ENABLE_GET(x)                        (((x) & 0x00000002) >> 1)
-#define PHY_ANALOG_RBIST_CNTRL_ATE_TONEGEN_TONE0_ENABLE_SET(x)                        (((x) << 1) & 0x00000002)
-#define PHY_ANALOG_RBIST_CNTRL_ATE_TONEGEN_TONE1_ENABLE_MSB                                                   2
-#define PHY_ANALOG_RBIST_CNTRL_ATE_TONEGEN_TONE1_ENABLE_LSB                                                   2
-#define PHY_ANALOG_RBIST_CNTRL_ATE_TONEGEN_TONE1_ENABLE_MASK                                         0x00000004
-#define PHY_ANALOG_RBIST_CNTRL_ATE_TONEGEN_TONE1_ENABLE_GET(x)                        (((x) & 0x00000004) >> 2)
-#define PHY_ANALOG_RBIST_CNTRL_ATE_TONEGEN_TONE1_ENABLE_SET(x)                        (((x) << 2) & 0x00000004)
-#define PHY_ANALOG_RBIST_CNTRL_ATE_TONEGEN_LFTONE0_ENABLE_MSB                                                 3
-#define PHY_ANALOG_RBIST_CNTRL_ATE_TONEGEN_LFTONE0_ENABLE_LSB                                                 3
-#define PHY_ANALOG_RBIST_CNTRL_ATE_TONEGEN_LFTONE0_ENABLE_MASK                                       0x00000008
-#define PHY_ANALOG_RBIST_CNTRL_ATE_TONEGEN_LFTONE0_ENABLE_GET(x)                      (((x) & 0x00000008) >> 3)
-#define PHY_ANALOG_RBIST_CNTRL_ATE_TONEGEN_LFTONE0_ENABLE_SET(x)                      (((x) << 3) & 0x00000008)
-#define PHY_ANALOG_RBIST_CNTRL_ATE_TONEGEN_LINRAMP_ENABLE_I_MSB                                               4
-#define PHY_ANALOG_RBIST_CNTRL_ATE_TONEGEN_LINRAMP_ENABLE_I_LSB                                               4
-#define PHY_ANALOG_RBIST_CNTRL_ATE_TONEGEN_LINRAMP_ENABLE_I_MASK                                     0x00000010
-#define PHY_ANALOG_RBIST_CNTRL_ATE_TONEGEN_LINRAMP_ENABLE_I_GET(x)                    (((x) & 0x00000010) >> 4)
-#define PHY_ANALOG_RBIST_CNTRL_ATE_TONEGEN_LINRAMP_ENABLE_I_SET(x)                    (((x) << 4) & 0x00000010)
-#define PHY_ANALOG_RBIST_CNTRL_ATE_TONEGEN_LINRAMP_ENABLE_Q_MSB                                               5
-#define PHY_ANALOG_RBIST_CNTRL_ATE_TONEGEN_LINRAMP_ENABLE_Q_LSB                                               5
-#define PHY_ANALOG_RBIST_CNTRL_ATE_TONEGEN_LINRAMP_ENABLE_Q_MASK                                     0x00000020
-#define PHY_ANALOG_RBIST_CNTRL_ATE_TONEGEN_LINRAMP_ENABLE_Q_GET(x)                    (((x) & 0x00000020) >> 5)
-#define PHY_ANALOG_RBIST_CNTRL_ATE_TONEGEN_LINRAMP_ENABLE_Q_SET(x)                    (((x) << 5) & 0x00000020)
-#define PHY_ANALOG_RBIST_CNTRL_ATE_TONEGEN_PRBS_ENABLE_I_MSB                                                  6
-#define PHY_ANALOG_RBIST_CNTRL_ATE_TONEGEN_PRBS_ENABLE_I_LSB                                                  6
-#define PHY_ANALOG_RBIST_CNTRL_ATE_TONEGEN_PRBS_ENABLE_I_MASK                                        0x00000040
-#define PHY_ANALOG_RBIST_CNTRL_ATE_TONEGEN_PRBS_ENABLE_I_GET(x)                       (((x) & 0x00000040) >> 6)
-#define PHY_ANALOG_RBIST_CNTRL_ATE_TONEGEN_PRBS_ENABLE_I_SET(x)                       (((x) << 6) & 0x00000040)
-#define PHY_ANALOG_RBIST_CNTRL_ATE_TONEGEN_PRBS_ENABLE_Q_MSB                                                  7
-#define PHY_ANALOG_RBIST_CNTRL_ATE_TONEGEN_PRBS_ENABLE_Q_LSB                                                  7
-#define PHY_ANALOG_RBIST_CNTRL_ATE_TONEGEN_PRBS_ENABLE_Q_MASK                                        0x00000080
-#define PHY_ANALOG_RBIST_CNTRL_ATE_TONEGEN_PRBS_ENABLE_Q_GET(x)                       (((x) & 0x00000080) >> 7)
-#define PHY_ANALOG_RBIST_CNTRL_ATE_TONEGEN_PRBS_ENABLE_Q_SET(x)                       (((x) << 7) & 0x00000080)
-#define PHY_ANALOG_RBIST_CNTRL_ATE_CMAC_DC_WRITE_TO_CANCEL_MSB                                                8
-#define PHY_ANALOG_RBIST_CNTRL_ATE_CMAC_DC_WRITE_TO_CANCEL_LSB                                                8
-#define PHY_ANALOG_RBIST_CNTRL_ATE_CMAC_DC_WRITE_TO_CANCEL_MASK                                      0x00000100
-#define PHY_ANALOG_RBIST_CNTRL_ATE_CMAC_DC_WRITE_TO_CANCEL_GET(x)                     (((x) & 0x00000100) >> 8)
-#define PHY_ANALOG_RBIST_CNTRL_ATE_CMAC_DC_WRITE_TO_CANCEL_SET(x)                     (((x) << 8) & 0x00000100)
-#define PHY_ANALOG_RBIST_CNTRL_ATE_CMAC_DC_ENABLE_MSB                                                         9
-#define PHY_ANALOG_RBIST_CNTRL_ATE_CMAC_DC_ENABLE_LSB                                                         9
-#define PHY_ANALOG_RBIST_CNTRL_ATE_CMAC_DC_ENABLE_MASK                                               0x00000200
-#define PHY_ANALOG_RBIST_CNTRL_ATE_CMAC_DC_ENABLE_GET(x)                              (((x) & 0x00000200) >> 9)
-#define PHY_ANALOG_RBIST_CNTRL_ATE_CMAC_DC_ENABLE_SET(x)                              (((x) << 9) & 0x00000200)
-#define PHY_ANALOG_RBIST_CNTRL_ATE_CMAC_CORR_ENABLE_MSB                                                      10
-#define PHY_ANALOG_RBIST_CNTRL_ATE_CMAC_CORR_ENABLE_LSB                                                      10
-#define PHY_ANALOG_RBIST_CNTRL_ATE_CMAC_CORR_ENABLE_MASK                                             0x00000400
-#define PHY_ANALOG_RBIST_CNTRL_ATE_CMAC_CORR_ENABLE_GET(x)                           (((x) & 0x00000400) >> 10)
-#define PHY_ANALOG_RBIST_CNTRL_ATE_CMAC_CORR_ENABLE_SET(x)                           (((x) << 10) & 0x00000400)
-#define PHY_ANALOG_RBIST_CNTRL_ATE_CMAC_POWER_ENABLE_MSB                                                     11
-#define PHY_ANALOG_RBIST_CNTRL_ATE_CMAC_POWER_ENABLE_LSB                                                     11
-#define PHY_ANALOG_RBIST_CNTRL_ATE_CMAC_POWER_ENABLE_MASK                                            0x00000800
-#define PHY_ANALOG_RBIST_CNTRL_ATE_CMAC_POWER_ENABLE_GET(x)                          (((x) & 0x00000800) >> 11)
-#define PHY_ANALOG_RBIST_CNTRL_ATE_CMAC_POWER_ENABLE_SET(x)                          (((x) << 11) & 0x00000800)
-#define PHY_ANALOG_RBIST_CNTRL_ATE_CMAC_IQ_ENABLE_MSB                                                        12
-#define PHY_ANALOG_RBIST_CNTRL_ATE_CMAC_IQ_ENABLE_LSB                                                        12
-#define PHY_ANALOG_RBIST_CNTRL_ATE_CMAC_IQ_ENABLE_MASK                                               0x00001000
-#define PHY_ANALOG_RBIST_CNTRL_ATE_CMAC_IQ_ENABLE_GET(x)                             (((x) & 0x00001000) >> 12)
-#define PHY_ANALOG_RBIST_CNTRL_ATE_CMAC_IQ_ENABLE_SET(x)                             (((x) << 12) & 0x00001000)
-#define PHY_ANALOG_RBIST_CNTRL_ATE_CMAC_I2Q2_ENABLE_MSB                                                      13
-#define PHY_ANALOG_RBIST_CNTRL_ATE_CMAC_I2Q2_ENABLE_LSB                                                      13
-#define PHY_ANALOG_RBIST_CNTRL_ATE_CMAC_I2Q2_ENABLE_MASK                                             0x00002000
-#define PHY_ANALOG_RBIST_CNTRL_ATE_CMAC_I2Q2_ENABLE_GET(x)                           (((x) & 0x00002000) >> 13)
-#define PHY_ANALOG_RBIST_CNTRL_ATE_CMAC_I2Q2_ENABLE_SET(x)                           (((x) << 13) & 0x00002000)
-#define PHY_ANALOG_RBIST_CNTRL_ATE_CMAC_POWER_HPF_ENABLE_MSB                                                 14
-#define PHY_ANALOG_RBIST_CNTRL_ATE_CMAC_POWER_HPF_ENABLE_LSB                                                 14
-#define PHY_ANALOG_RBIST_CNTRL_ATE_CMAC_POWER_HPF_ENABLE_MASK                                        0x00004000
-#define PHY_ANALOG_RBIST_CNTRL_ATE_CMAC_POWER_HPF_ENABLE_GET(x)                      (((x) & 0x00004000) >> 14)
-#define PHY_ANALOG_RBIST_CNTRL_ATE_CMAC_POWER_HPF_ENABLE_SET(x)                      (((x) << 14) & 0x00004000)
-#define PHY_ANALOG_RBIST_CNTRL_ATE_RXDAC_CALIBRATE_MSB                                                       15
-#define PHY_ANALOG_RBIST_CNTRL_ATE_RXDAC_CALIBRATE_LSB                                                       15
-#define PHY_ANALOG_RBIST_CNTRL_ATE_RXDAC_CALIBRATE_MASK                                              0x00008000
-#define PHY_ANALOG_RBIST_CNTRL_ATE_RXDAC_CALIBRATE_GET(x)                            (((x) & 0x00008000) >> 15)
-#define PHY_ANALOG_RBIST_CNTRL_ATE_RXDAC_CALIBRATE_SET(x)                            (((x) << 15) & 0x00008000)
-#define PHY_ANALOG_RBIST_CNTRL_ATE_RBIST_ENABLE_MSB                                                          16
-#define PHY_ANALOG_RBIST_CNTRL_ATE_RBIST_ENABLE_LSB                                                          16
-#define PHY_ANALOG_RBIST_CNTRL_ATE_RBIST_ENABLE_MASK                                                 0x00010000
-#define PHY_ANALOG_RBIST_CNTRL_ATE_RBIST_ENABLE_GET(x)                               (((x) & 0x00010000) >> 16)
-#define PHY_ANALOG_RBIST_CNTRL_ATE_RBIST_ENABLE_SET(x)                               (((x) << 16) & 0x00010000)
-#define PHY_ANALOG_RBIST_CNTRL_ATE_ADC_CLK_INVERT_MSB                                                        17
-#define PHY_ANALOG_RBIST_CNTRL_ATE_ADC_CLK_INVERT_LSB                                                        17
-#define PHY_ANALOG_RBIST_CNTRL_ATE_ADC_CLK_INVERT_MASK                                               0x00020000
-#define PHY_ANALOG_RBIST_CNTRL_ATE_ADC_CLK_INVERT_GET(x)                             (((x) & 0x00020000) >> 17)
-#define PHY_ANALOG_RBIST_CNTRL_ATE_ADC_CLK_INVERT_SET(x)                             (((x) << 17) & 0x00020000)
-
-/* macros for tx_dc_offset */
-#define PHY_ANALOG_TX_DC_OFFSET_ADDRESS                                                              0x00000384
-#define PHY_ANALOG_TX_DC_OFFSET_OFFSET                                                               0x00000384
-#define PHY_ANALOG_TX_DC_OFFSET_ATE_TONEGEN_DC_I_MSB                                                         10
-#define PHY_ANALOG_TX_DC_OFFSET_ATE_TONEGEN_DC_I_LSB                                                          0
-#define PHY_ANALOG_TX_DC_OFFSET_ATE_TONEGEN_DC_I_MASK                                                0x000007ff
-#define PHY_ANALOG_TX_DC_OFFSET_ATE_TONEGEN_DC_I_GET(x)                               (((x) & 0x000007ff) >> 0)
-#define PHY_ANALOG_TX_DC_OFFSET_ATE_TONEGEN_DC_I_SET(x)                               (((x) << 0) & 0x000007ff)
-#define PHY_ANALOG_TX_DC_OFFSET_ATE_TONEGEN_DC_Q_MSB                                                         26
-#define PHY_ANALOG_TX_DC_OFFSET_ATE_TONEGEN_DC_Q_LSB                                                         16
-#define PHY_ANALOG_TX_DC_OFFSET_ATE_TONEGEN_DC_Q_MASK                                                0x07ff0000
-#define PHY_ANALOG_TX_DC_OFFSET_ATE_TONEGEN_DC_Q_GET(x)                              (((x) & 0x07ff0000) >> 16)
-#define PHY_ANALOG_TX_DC_OFFSET_ATE_TONEGEN_DC_Q_SET(x)                              (((x) << 16) & 0x07ff0000)
-
-/* macros for tx_tonegen0 */
-#define PHY_ANALOG_TX_TONEGEN0_ADDRESS                                                               0x00000388
-#define PHY_ANALOG_TX_TONEGEN0_OFFSET                                                                0x00000388
-#define PHY_ANALOG_TX_TONEGEN0_ATE_TONEGEN_TONE_FREQ_MSB                                                      6
-#define PHY_ANALOG_TX_TONEGEN0_ATE_TONEGEN_TONE_FREQ_LSB                                                      0
-#define PHY_ANALOG_TX_TONEGEN0_ATE_TONEGEN_TONE_FREQ_MASK                                            0x0000007f
-#define PHY_ANALOG_TX_TONEGEN0_ATE_TONEGEN_TONE_FREQ_GET(x)                           (((x) & 0x0000007f) >> 0)
-#define PHY_ANALOG_TX_TONEGEN0_ATE_TONEGEN_TONE_FREQ_SET(x)                           (((x) << 0) & 0x0000007f)
-#define PHY_ANALOG_TX_TONEGEN0_ATE_TONEGEN_TONE_A_EXP_MSB                                                    11
-#define PHY_ANALOG_TX_TONEGEN0_ATE_TONEGEN_TONE_A_EXP_LSB                                                     8
-#define PHY_ANALOG_TX_TONEGEN0_ATE_TONEGEN_TONE_A_EXP_MASK                                           0x00000f00
-#define PHY_ANALOG_TX_TONEGEN0_ATE_TONEGEN_TONE_A_EXP_GET(x)                          (((x) & 0x00000f00) >> 8)
-#define PHY_ANALOG_TX_TONEGEN0_ATE_TONEGEN_TONE_A_EXP_SET(x)                          (((x) << 8) & 0x00000f00)
-#define PHY_ANALOG_TX_TONEGEN0_ATE_TONEGEN_TONE_A_MAN_MSB                                                    23
-#define PHY_ANALOG_TX_TONEGEN0_ATE_TONEGEN_TONE_A_MAN_LSB                                                    16
-#define PHY_ANALOG_TX_TONEGEN0_ATE_TONEGEN_TONE_A_MAN_MASK                                           0x00ff0000
-#define PHY_ANALOG_TX_TONEGEN0_ATE_TONEGEN_TONE_A_MAN_GET(x)                         (((x) & 0x00ff0000) >> 16)
-#define PHY_ANALOG_TX_TONEGEN0_ATE_TONEGEN_TONE_A_MAN_SET(x)                         (((x) << 16) & 0x00ff0000)
-#define PHY_ANALOG_TX_TONEGEN0_ATE_TONEGEN_TONE_TAU_K_MSB                                                    30
-#define PHY_ANALOG_TX_TONEGEN0_ATE_TONEGEN_TONE_TAU_K_LSB                                                    24
-#define PHY_ANALOG_TX_TONEGEN0_ATE_TONEGEN_TONE_TAU_K_MASK                                           0x7f000000
-#define PHY_ANALOG_TX_TONEGEN0_ATE_TONEGEN_TONE_TAU_K_GET(x)                         (((x) & 0x7f000000) >> 24)
-#define PHY_ANALOG_TX_TONEGEN0_ATE_TONEGEN_TONE_TAU_K_SET(x)                         (((x) << 24) & 0x7f000000)
-
-/* macros for tx_tonegen1 */
-#define PHY_ANALOG_TX_TONEGEN1_ADDRESS                                                               0x0000038c
-#define PHY_ANALOG_TX_TONEGEN1_OFFSET                                                                0x0000038c
-#define PHY_ANALOG_TX_TONEGEN1_ATE_TONEGEN_TONE_FREQ_MSB                                                      6
-#define PHY_ANALOG_TX_TONEGEN1_ATE_TONEGEN_TONE_FREQ_LSB                                                      0
-#define PHY_ANALOG_TX_TONEGEN1_ATE_TONEGEN_TONE_FREQ_MASK                                            0x0000007f
-#define PHY_ANALOG_TX_TONEGEN1_ATE_TONEGEN_TONE_FREQ_GET(x)                           (((x) & 0x0000007f) >> 0)
-#define PHY_ANALOG_TX_TONEGEN1_ATE_TONEGEN_TONE_FREQ_SET(x)                           (((x) << 0) & 0x0000007f)
-#define PHY_ANALOG_TX_TONEGEN1_ATE_TONEGEN_TONE_A_EXP_MSB                                                    11
-#define PHY_ANALOG_TX_TONEGEN1_ATE_TONEGEN_TONE_A_EXP_LSB                                                     8
-#define PHY_ANALOG_TX_TONEGEN1_ATE_TONEGEN_TONE_A_EXP_MASK                                           0x00000f00
-#define PHY_ANALOG_TX_TONEGEN1_ATE_TONEGEN_TONE_A_EXP_GET(x)                          (((x) & 0x00000f00) >> 8)
-#define PHY_ANALOG_TX_TONEGEN1_ATE_TONEGEN_TONE_A_EXP_SET(x)                          (((x) << 8) & 0x00000f00)
-#define PHY_ANALOG_TX_TONEGEN1_ATE_TONEGEN_TONE_A_MAN_MSB                                                    23
-#define PHY_ANALOG_TX_TONEGEN1_ATE_TONEGEN_TONE_A_MAN_LSB                                                    16
-#define PHY_ANALOG_TX_TONEGEN1_ATE_TONEGEN_TONE_A_MAN_MASK                                           0x00ff0000
-#define PHY_ANALOG_TX_TONEGEN1_ATE_TONEGEN_TONE_A_MAN_GET(x)                         (((x) & 0x00ff0000) >> 16)
-#define PHY_ANALOG_TX_TONEGEN1_ATE_TONEGEN_TONE_A_MAN_SET(x)                         (((x) << 16) & 0x00ff0000)
-#define PHY_ANALOG_TX_TONEGEN1_ATE_TONEGEN_TONE_TAU_K_MSB                                                    30
-#define PHY_ANALOG_TX_TONEGEN1_ATE_TONEGEN_TONE_TAU_K_LSB                                                    24
-#define PHY_ANALOG_TX_TONEGEN1_ATE_TONEGEN_TONE_TAU_K_MASK                                           0x7f000000
-#define PHY_ANALOG_TX_TONEGEN1_ATE_TONEGEN_TONE_TAU_K_GET(x)                         (((x) & 0x7f000000) >> 24)
-#define PHY_ANALOG_TX_TONEGEN1_ATE_TONEGEN_TONE_TAU_K_SET(x)                         (((x) << 24) & 0x7f000000)
-
-/* macros for tx_lftonegen0 */
-#define PHY_ANALOG_TX_LFTONEGEN0_ADDRESS                                                             0x00000390
-#define PHY_ANALOG_TX_LFTONEGEN0_OFFSET                                                              0x00000390
-#define PHY_ANALOG_TX_LFTONEGEN0_ATE_TONEGEN_TONE_FREQ_MSB                                                    6
-#define PHY_ANALOG_TX_LFTONEGEN0_ATE_TONEGEN_TONE_FREQ_LSB                                                    0
-#define PHY_ANALOG_TX_LFTONEGEN0_ATE_TONEGEN_TONE_FREQ_MASK                                          0x0000007f
-#define PHY_ANALOG_TX_LFTONEGEN0_ATE_TONEGEN_TONE_FREQ_GET(x)                         (((x) & 0x0000007f) >> 0)
-#define PHY_ANALOG_TX_LFTONEGEN0_ATE_TONEGEN_TONE_FREQ_SET(x)                         (((x) << 0) & 0x0000007f)
-#define PHY_ANALOG_TX_LFTONEGEN0_ATE_TONEGEN_TONE_A_EXP_MSB                                                  11
-#define PHY_ANALOG_TX_LFTONEGEN0_ATE_TONEGEN_TONE_A_EXP_LSB                                                   8
-#define PHY_ANALOG_TX_LFTONEGEN0_ATE_TONEGEN_TONE_A_EXP_MASK                                         0x00000f00
-#define PHY_ANALOG_TX_LFTONEGEN0_ATE_TONEGEN_TONE_A_EXP_GET(x)                        (((x) & 0x00000f00) >> 8)
-#define PHY_ANALOG_TX_LFTONEGEN0_ATE_TONEGEN_TONE_A_EXP_SET(x)                        (((x) << 8) & 0x00000f00)
-#define PHY_ANALOG_TX_LFTONEGEN0_ATE_TONEGEN_TONE_A_MAN_MSB                                                  23
-#define PHY_ANALOG_TX_LFTONEGEN0_ATE_TONEGEN_TONE_A_MAN_LSB                                                  16
-#define PHY_ANALOG_TX_LFTONEGEN0_ATE_TONEGEN_TONE_A_MAN_MASK                                         0x00ff0000
-#define PHY_ANALOG_TX_LFTONEGEN0_ATE_TONEGEN_TONE_A_MAN_GET(x)                       (((x) & 0x00ff0000) >> 16)
-#define PHY_ANALOG_TX_LFTONEGEN0_ATE_TONEGEN_TONE_A_MAN_SET(x)                       (((x) << 16) & 0x00ff0000)
-#define PHY_ANALOG_TX_LFTONEGEN0_ATE_TONEGEN_TONE_TAU_K_MSB                                                  30
-#define PHY_ANALOG_TX_LFTONEGEN0_ATE_TONEGEN_TONE_TAU_K_LSB                                                  24
-#define PHY_ANALOG_TX_LFTONEGEN0_ATE_TONEGEN_TONE_TAU_K_MASK                                         0x7f000000
-#define PHY_ANALOG_TX_LFTONEGEN0_ATE_TONEGEN_TONE_TAU_K_GET(x)                       (((x) & 0x7f000000) >> 24)
-#define PHY_ANALOG_TX_LFTONEGEN0_ATE_TONEGEN_TONE_TAU_K_SET(x)                       (((x) << 24) & 0x7f000000)
-
-/* macros for tx_linear_ramp_i */
-#define PHY_ANALOG_TX_LINEAR_RAMP_I_ADDRESS                                                          0x00000394
-#define PHY_ANALOG_TX_LINEAR_RAMP_I_OFFSET                                                           0x00000394
-#define PHY_ANALOG_TX_LINEAR_RAMP_I_ATE_TONEGEN_LINRAMP_INIT_MSB                                             10
-#define PHY_ANALOG_TX_LINEAR_RAMP_I_ATE_TONEGEN_LINRAMP_INIT_LSB                                              0
-#define PHY_ANALOG_TX_LINEAR_RAMP_I_ATE_TONEGEN_LINRAMP_INIT_MASK                                    0x000007ff
-#define PHY_ANALOG_TX_LINEAR_RAMP_I_ATE_TONEGEN_LINRAMP_INIT_GET(x)                   (((x) & 0x000007ff) >> 0)
-#define PHY_ANALOG_TX_LINEAR_RAMP_I_ATE_TONEGEN_LINRAMP_INIT_SET(x)                   (((x) << 0) & 0x000007ff)
-#define PHY_ANALOG_TX_LINEAR_RAMP_I_ATE_TONEGEN_LINRAMP_DWELL_MSB                                            21
-#define PHY_ANALOG_TX_LINEAR_RAMP_I_ATE_TONEGEN_LINRAMP_DWELL_LSB                                            12
-#define PHY_ANALOG_TX_LINEAR_RAMP_I_ATE_TONEGEN_LINRAMP_DWELL_MASK                                   0x003ff000
-#define PHY_ANALOG_TX_LINEAR_RAMP_I_ATE_TONEGEN_LINRAMP_DWELL_GET(x)                 (((x) & 0x003ff000) >> 12)
-#define PHY_ANALOG_TX_LINEAR_RAMP_I_ATE_TONEGEN_LINRAMP_DWELL_SET(x)                 (((x) << 12) & 0x003ff000)
-#define PHY_ANALOG_TX_LINEAR_RAMP_I_ATE_TONEGEN_LINRAMP_STEP_MSB                                             29
-#define PHY_ANALOG_TX_LINEAR_RAMP_I_ATE_TONEGEN_LINRAMP_STEP_LSB                                             24
-#define PHY_ANALOG_TX_LINEAR_RAMP_I_ATE_TONEGEN_LINRAMP_STEP_MASK                                    0x3f000000
-#define PHY_ANALOG_TX_LINEAR_RAMP_I_ATE_TONEGEN_LINRAMP_STEP_GET(x)                  (((x) & 0x3f000000) >> 24)
-#define PHY_ANALOG_TX_LINEAR_RAMP_I_ATE_TONEGEN_LINRAMP_STEP_SET(x)                  (((x) << 24) & 0x3f000000)
-
-/* macros for tx_linear_ramp_q */
-#define PHY_ANALOG_TX_LINEAR_RAMP_Q_ADDRESS                                                          0x00000398
-#define PHY_ANALOG_TX_LINEAR_RAMP_Q_OFFSET                                                           0x00000398
-#define PHY_ANALOG_TX_LINEAR_RAMP_Q_ATE_TONEGEN_LINRAMP_INIT_MSB                                             10
-#define PHY_ANALOG_TX_LINEAR_RAMP_Q_ATE_TONEGEN_LINRAMP_INIT_LSB                                              0
-#define PHY_ANALOG_TX_LINEAR_RAMP_Q_ATE_TONEGEN_LINRAMP_INIT_MASK                                    0x000007ff
-#define PHY_ANALOG_TX_LINEAR_RAMP_Q_ATE_TONEGEN_LINRAMP_INIT_GET(x)                   (((x) & 0x000007ff) >> 0)
-#define PHY_ANALOG_TX_LINEAR_RAMP_Q_ATE_TONEGEN_LINRAMP_INIT_SET(x)                   (((x) << 0) & 0x000007ff)
-#define PHY_ANALOG_TX_LINEAR_RAMP_Q_ATE_TONEGEN_LINRAMP_DWELL_MSB                                            21
-#define PHY_ANALOG_TX_LINEAR_RAMP_Q_ATE_TONEGEN_LINRAMP_DWELL_LSB                                            12
-#define PHY_ANALOG_TX_LINEAR_RAMP_Q_ATE_TONEGEN_LINRAMP_DWELL_MASK                                   0x003ff000
-#define PHY_ANALOG_TX_LINEAR_RAMP_Q_ATE_TONEGEN_LINRAMP_DWELL_GET(x)                 (((x) & 0x003ff000) >> 12)
-#define PHY_ANALOG_TX_LINEAR_RAMP_Q_ATE_TONEGEN_LINRAMP_DWELL_SET(x)                 (((x) << 12) & 0x003ff000)
-#define PHY_ANALOG_TX_LINEAR_RAMP_Q_ATE_TONEGEN_LINRAMP_STEP_MSB                                             29
-#define PHY_ANALOG_TX_LINEAR_RAMP_Q_ATE_TONEGEN_LINRAMP_STEP_LSB                                             24
-#define PHY_ANALOG_TX_LINEAR_RAMP_Q_ATE_TONEGEN_LINRAMP_STEP_MASK                                    0x3f000000
-#define PHY_ANALOG_TX_LINEAR_RAMP_Q_ATE_TONEGEN_LINRAMP_STEP_GET(x)                  (((x) & 0x3f000000) >> 24)
-#define PHY_ANALOG_TX_LINEAR_RAMP_Q_ATE_TONEGEN_LINRAMP_STEP_SET(x)                  (((x) << 24) & 0x3f000000)
-
-/* macros for tx_prbs_mag */
-#define PHY_ANALOG_TX_PRBS_MAG_ADDRESS                                                               0x0000039c
-#define PHY_ANALOG_TX_PRBS_MAG_OFFSET                                                                0x0000039c
-#define PHY_ANALOG_TX_PRBS_MAG_ATE_TONEGEN_PRBS_MAGNITUDE_I_MSB                                               9
-#define PHY_ANALOG_TX_PRBS_MAG_ATE_TONEGEN_PRBS_MAGNITUDE_I_LSB                                               0
-#define PHY_ANALOG_TX_PRBS_MAG_ATE_TONEGEN_PRBS_MAGNITUDE_I_MASK                                     0x000003ff
-#define PHY_ANALOG_TX_PRBS_MAG_ATE_TONEGEN_PRBS_MAGNITUDE_I_GET(x)                    (((x) & 0x000003ff) >> 0)
-#define PHY_ANALOG_TX_PRBS_MAG_ATE_TONEGEN_PRBS_MAGNITUDE_I_SET(x)                    (((x) << 0) & 0x000003ff)
-#define PHY_ANALOG_TX_PRBS_MAG_ATE_TONEGEN_PRBS_MAGNITUDE_Q_MSB                                              25
-#define PHY_ANALOG_TX_PRBS_MAG_ATE_TONEGEN_PRBS_MAGNITUDE_Q_LSB                                              16
-#define PHY_ANALOG_TX_PRBS_MAG_ATE_TONEGEN_PRBS_MAGNITUDE_Q_MASK                                     0x03ff0000
-#define PHY_ANALOG_TX_PRBS_MAG_ATE_TONEGEN_PRBS_MAGNITUDE_Q_GET(x)                   (((x) & 0x03ff0000) >> 16)
-#define PHY_ANALOG_TX_PRBS_MAG_ATE_TONEGEN_PRBS_MAGNITUDE_Q_SET(x)                   (((x) << 16) & 0x03ff0000)
-
-/* macros for tx_prbs_seed_i */
-#define PHY_ANALOG_TX_PRBS_SEED_I_ADDRESS                                                            0x000003a0
-#define PHY_ANALOG_TX_PRBS_SEED_I_OFFSET                                                             0x000003a0
-#define PHY_ANALOG_TX_PRBS_SEED_I_ATE_TONEGEN_PRBS_SEED_MSB                                                  30
-#define PHY_ANALOG_TX_PRBS_SEED_I_ATE_TONEGEN_PRBS_SEED_LSB                                                   0
-#define PHY_ANALOG_TX_PRBS_SEED_I_ATE_TONEGEN_PRBS_SEED_MASK                                         0x7fffffff
-#define PHY_ANALOG_TX_PRBS_SEED_I_ATE_TONEGEN_PRBS_SEED_GET(x)                        (((x) & 0x7fffffff) >> 0)
-#define PHY_ANALOG_TX_PRBS_SEED_I_ATE_TONEGEN_PRBS_SEED_SET(x)                        (((x) << 0) & 0x7fffffff)
-
-/* macros for tx_prbs_seed_q */
-#define PHY_ANALOG_TX_PRBS_SEED_Q_ADDRESS                                                            0x000003a4
-#define PHY_ANALOG_TX_PRBS_SEED_Q_OFFSET                                                             0x000003a4
-#define PHY_ANALOG_TX_PRBS_SEED_Q_ATE_TONEGEN_PRBS_SEED_MSB                                                  30
-#define PHY_ANALOG_TX_PRBS_SEED_Q_ATE_TONEGEN_PRBS_SEED_LSB                                                   0
-#define PHY_ANALOG_TX_PRBS_SEED_Q_ATE_TONEGEN_PRBS_SEED_MASK                                         0x7fffffff
-#define PHY_ANALOG_TX_PRBS_SEED_Q_ATE_TONEGEN_PRBS_SEED_GET(x)                        (((x) & 0x7fffffff) >> 0)
-#define PHY_ANALOG_TX_PRBS_SEED_Q_ATE_TONEGEN_PRBS_SEED_SET(x)                        (((x) << 0) & 0x7fffffff)
-
-/* macros for cmac_dc_cancel */
-#define PHY_ANALOG_CMAC_DC_CANCEL_ADDRESS                                                            0x000003a8
-#define PHY_ANALOG_CMAC_DC_CANCEL_OFFSET                                                             0x000003a8
-#define PHY_ANALOG_CMAC_DC_CANCEL_ATE_CMAC_DC_CANCEL_I_MSB                                                    9
-#define PHY_ANALOG_CMAC_DC_CANCEL_ATE_CMAC_DC_CANCEL_I_LSB                                                    0
-#define PHY_ANALOG_CMAC_DC_CANCEL_ATE_CMAC_DC_CANCEL_I_MASK                                          0x000003ff
-#define PHY_ANALOG_CMAC_DC_CANCEL_ATE_CMAC_DC_CANCEL_I_GET(x)                         (((x) & 0x000003ff) >> 0)
-#define PHY_ANALOG_CMAC_DC_CANCEL_ATE_CMAC_DC_CANCEL_I_SET(x)                         (((x) << 0) & 0x000003ff)
-#define PHY_ANALOG_CMAC_DC_CANCEL_ATE_CMAC_DC_CANCEL_Q_MSB                                                   25
-#define PHY_ANALOG_CMAC_DC_CANCEL_ATE_CMAC_DC_CANCEL_Q_LSB                                                   16
-#define PHY_ANALOG_CMAC_DC_CANCEL_ATE_CMAC_DC_CANCEL_Q_MASK                                          0x03ff0000
-#define PHY_ANALOG_CMAC_DC_CANCEL_ATE_CMAC_DC_CANCEL_Q_GET(x)                        (((x) & 0x03ff0000) >> 16)
-#define PHY_ANALOG_CMAC_DC_CANCEL_ATE_CMAC_DC_CANCEL_Q_SET(x)                        (((x) << 16) & 0x03ff0000)
-
-/* macros for cmac_dc_offset */
-#define PHY_ANALOG_CMAC_DC_OFFSET_ADDRESS                                                            0x000003ac
-#define PHY_ANALOG_CMAC_DC_OFFSET_OFFSET                                                             0x000003ac
-#define PHY_ANALOG_CMAC_DC_OFFSET_ATE_CMAC_DC_CYCLES_MSB                                                      3
-#define PHY_ANALOG_CMAC_DC_OFFSET_ATE_CMAC_DC_CYCLES_LSB                                                      0
-#define PHY_ANALOG_CMAC_DC_OFFSET_ATE_CMAC_DC_CYCLES_MASK                                            0x0000000f
-#define PHY_ANALOG_CMAC_DC_OFFSET_ATE_CMAC_DC_CYCLES_GET(x)                           (((x) & 0x0000000f) >> 0)
-#define PHY_ANALOG_CMAC_DC_OFFSET_ATE_CMAC_DC_CYCLES_SET(x)                           (((x) << 0) & 0x0000000f)
-
-/* macros for cmac_corr */
-#define PHY_ANALOG_CMAC_CORR_ADDRESS                                                                 0x000003b0
-#define PHY_ANALOG_CMAC_CORR_OFFSET                                                                  0x000003b0
-#define PHY_ANALOG_CMAC_CORR_ATE_CMAC_CORR_CYCLES_MSB                                                         4
-#define PHY_ANALOG_CMAC_CORR_ATE_CMAC_CORR_CYCLES_LSB                                                         0
-#define PHY_ANALOG_CMAC_CORR_ATE_CMAC_CORR_CYCLES_MASK                                               0x0000001f
-#define PHY_ANALOG_CMAC_CORR_ATE_CMAC_CORR_CYCLES_GET(x)                              (((x) & 0x0000001f) >> 0)
-#define PHY_ANALOG_CMAC_CORR_ATE_CMAC_CORR_CYCLES_SET(x)                              (((x) << 0) & 0x0000001f)
-#define PHY_ANALOG_CMAC_CORR_ATE_CMAC_CORR_FREQ_MSB                                                          13
-#define PHY_ANALOG_CMAC_CORR_ATE_CMAC_CORR_FREQ_LSB                                                           8
-#define PHY_ANALOG_CMAC_CORR_ATE_CMAC_CORR_FREQ_MASK                                                 0x00003f00
-#define PHY_ANALOG_CMAC_CORR_ATE_CMAC_CORR_FREQ_GET(x)                                (((x) & 0x00003f00) >> 8)
-#define PHY_ANALOG_CMAC_CORR_ATE_CMAC_CORR_FREQ_SET(x)                                (((x) << 8) & 0x00003f00)
-
-/* macros for cmac_power */
-#define PHY_ANALOG_CMAC_POWER_ADDRESS                                                                0x000003b4
-#define PHY_ANALOG_CMAC_POWER_OFFSET                                                                 0x000003b4
-#define PHY_ANALOG_CMAC_POWER_ATE_CMAC_POWER_CYCLES_MSB                                                       3
-#define PHY_ANALOG_CMAC_POWER_ATE_CMAC_POWER_CYCLES_LSB                                                       0
-#define PHY_ANALOG_CMAC_POWER_ATE_CMAC_POWER_CYCLES_MASK                                             0x0000000f
-#define PHY_ANALOG_CMAC_POWER_ATE_CMAC_POWER_CYCLES_GET(x)                            (((x) & 0x0000000f) >> 0)
-#define PHY_ANALOG_CMAC_POWER_ATE_CMAC_POWER_CYCLES_SET(x)                            (((x) << 0) & 0x0000000f)
-
-/* macros for cmac_cross_corr */
-#define PHY_ANALOG_CMAC_CROSS_CORR_ADDRESS                                                           0x000003b8
-#define PHY_ANALOG_CMAC_CROSS_CORR_OFFSET                                                            0x000003b8
-#define PHY_ANALOG_CMAC_CROSS_CORR_ATE_CMAC_IQ_CYCLES_MSB                                                     3
-#define PHY_ANALOG_CMAC_CROSS_CORR_ATE_CMAC_IQ_CYCLES_LSB                                                     0
-#define PHY_ANALOG_CMAC_CROSS_CORR_ATE_CMAC_IQ_CYCLES_MASK                                           0x0000000f
-#define PHY_ANALOG_CMAC_CROSS_CORR_ATE_CMAC_IQ_CYCLES_GET(x)                          (((x) & 0x0000000f) >> 0)
-#define PHY_ANALOG_CMAC_CROSS_CORR_ATE_CMAC_IQ_CYCLES_SET(x)                          (((x) << 0) & 0x0000000f)
-
-/* macros for cmac_i2q2 */
-#define PHY_ANALOG_CMAC_I2Q2_ADDRESS                                                                 0x000003bc
-#define PHY_ANALOG_CMAC_I2Q2_OFFSET                                                                  0x000003bc
-#define PHY_ANALOG_CMAC_I2Q2_ATE_CMAC_I2Q2_CYCLES_MSB                                                         3
-#define PHY_ANALOG_CMAC_I2Q2_ATE_CMAC_I2Q2_CYCLES_LSB                                                         0
-#define PHY_ANALOG_CMAC_I2Q2_ATE_CMAC_I2Q2_CYCLES_MASK                                               0x0000000f
-#define PHY_ANALOG_CMAC_I2Q2_ATE_CMAC_I2Q2_CYCLES_GET(x)                              (((x) & 0x0000000f) >> 0)
-#define PHY_ANALOG_CMAC_I2Q2_ATE_CMAC_I2Q2_CYCLES_SET(x)                              (((x) << 0) & 0x0000000f)
-
-/* macros for cmac_power_hpf */
-#define PHY_ANALOG_CMAC_POWER_HPF_ADDRESS                                                            0x000003c0
-#define PHY_ANALOG_CMAC_POWER_HPF_OFFSET                                                             0x000003c0
-#define PHY_ANALOG_CMAC_POWER_HPF_ATE_CMAC_POWER_HPF_CYCLES_MSB                                               3
-#define PHY_ANALOG_CMAC_POWER_HPF_ATE_CMAC_POWER_HPF_CYCLES_LSB                                               0
-#define PHY_ANALOG_CMAC_POWER_HPF_ATE_CMAC_POWER_HPF_CYCLES_MASK                                     0x0000000f
-#define PHY_ANALOG_CMAC_POWER_HPF_ATE_CMAC_POWER_HPF_CYCLES_GET(x)                    (((x) & 0x0000000f) >> 0)
-#define PHY_ANALOG_CMAC_POWER_HPF_ATE_CMAC_POWER_HPF_CYCLES_SET(x)                    (((x) << 0) & 0x0000000f)
-#define PHY_ANALOG_CMAC_POWER_HPF_ATE_CMAC_POWER_HPF_WAIT_MSB                                                 7
-#define PHY_ANALOG_CMAC_POWER_HPF_ATE_CMAC_POWER_HPF_WAIT_LSB                                                 4
-#define PHY_ANALOG_CMAC_POWER_HPF_ATE_CMAC_POWER_HPF_WAIT_MASK                                       0x000000f0
-#define PHY_ANALOG_CMAC_POWER_HPF_ATE_CMAC_POWER_HPF_WAIT_GET(x)                      (((x) & 0x000000f0) >> 4)
-#define PHY_ANALOG_CMAC_POWER_HPF_ATE_CMAC_POWER_HPF_WAIT_SET(x)                      (((x) << 4) & 0x000000f0)
-
-/* macros for rxdac_set1 */
-#define PHY_ANALOG_RXDAC_SET1_ADDRESS                                                                0x000003c4
-#define PHY_ANALOG_RXDAC_SET1_OFFSET                                                                 0x000003c4
-#define PHY_ANALOG_RXDAC_SET1_ATE_RXDAC_MUX_MSB                                                               1
-#define PHY_ANALOG_RXDAC_SET1_ATE_RXDAC_MUX_LSB                                                               0
-#define PHY_ANALOG_RXDAC_SET1_ATE_RXDAC_MUX_MASK                                                     0x00000003
-#define PHY_ANALOG_RXDAC_SET1_ATE_RXDAC_MUX_GET(x)                                    (((x) & 0x00000003) >> 0)
-#define PHY_ANALOG_RXDAC_SET1_ATE_RXDAC_MUX_SET(x)                                    (((x) << 0) & 0x00000003)
-#define PHY_ANALOG_RXDAC_SET1_ATE_RXDAC_HI_GAIN_MSB                                                           4
-#define PHY_ANALOG_RXDAC_SET1_ATE_RXDAC_HI_GAIN_LSB                                                           4
-#define PHY_ANALOG_RXDAC_SET1_ATE_RXDAC_HI_GAIN_MASK                                                 0x00000010
-#define PHY_ANALOG_RXDAC_SET1_ATE_RXDAC_HI_GAIN_GET(x)                                (((x) & 0x00000010) >> 4)
-#define PHY_ANALOG_RXDAC_SET1_ATE_RXDAC_HI_GAIN_SET(x)                                (((x) << 4) & 0x00000010)
-#define PHY_ANALOG_RXDAC_SET1_ATE_RXDAC_CAL_WAIT_MSB                                                         13
-#define PHY_ANALOG_RXDAC_SET1_ATE_RXDAC_CAL_WAIT_LSB                                                          8
-#define PHY_ANALOG_RXDAC_SET1_ATE_RXDAC_CAL_WAIT_MASK                                                0x00003f00
-#define PHY_ANALOG_RXDAC_SET1_ATE_RXDAC_CAL_WAIT_GET(x)                               (((x) & 0x00003f00) >> 8)
-#define PHY_ANALOG_RXDAC_SET1_ATE_RXDAC_CAL_WAIT_SET(x)                               (((x) << 8) & 0x00003f00)
-#define PHY_ANALOG_RXDAC_SET1_ATE_RXDAC_CAL_MEASURE_TIME_MSB                                                 19
-#define PHY_ANALOG_RXDAC_SET1_ATE_RXDAC_CAL_MEASURE_TIME_LSB                                                 16
-#define PHY_ANALOG_RXDAC_SET1_ATE_RXDAC_CAL_MEASURE_TIME_MASK                                        0x000f0000
-#define PHY_ANALOG_RXDAC_SET1_ATE_RXDAC_CAL_MEASURE_TIME_GET(x)                      (((x) & 0x000f0000) >> 16)
-#define PHY_ANALOG_RXDAC_SET1_ATE_RXDAC_CAL_MEASURE_TIME_SET(x)                      (((x) << 16) & 0x000f0000)
-
-/* macros for rxdac_set2 */
-#define PHY_ANALOG_RXDAC_SET2_ADDRESS                                                                0x000003c8
-#define PHY_ANALOG_RXDAC_SET2_OFFSET                                                                 0x000003c8
-#define PHY_ANALOG_RXDAC_SET2_ATE_RXDAC_I_HI_MSB                                                              4
-#define PHY_ANALOG_RXDAC_SET2_ATE_RXDAC_I_HI_LSB                                                              0
-#define PHY_ANALOG_RXDAC_SET2_ATE_RXDAC_I_HI_MASK                                                    0x0000001f
-#define PHY_ANALOG_RXDAC_SET2_ATE_RXDAC_I_HI_GET(x)                                   (((x) & 0x0000001f) >> 0)
-#define PHY_ANALOG_RXDAC_SET2_ATE_RXDAC_I_HI_SET(x)                                   (((x) << 0) & 0x0000001f)
-#define PHY_ANALOG_RXDAC_SET2_ATE_RXDAC_Q_HI_MSB                                                             12
-#define PHY_ANALOG_RXDAC_SET2_ATE_RXDAC_Q_HI_LSB                                                              8
-#define PHY_ANALOG_RXDAC_SET2_ATE_RXDAC_Q_HI_MASK                                                    0x00001f00
-#define PHY_ANALOG_RXDAC_SET2_ATE_RXDAC_Q_HI_GET(x)                                   (((x) & 0x00001f00) >> 8)
-#define PHY_ANALOG_RXDAC_SET2_ATE_RXDAC_Q_HI_SET(x)                                   (((x) << 8) & 0x00001f00)
-#define PHY_ANALOG_RXDAC_SET2_ATE_RXDAC_I_LOW_MSB                                                            20
-#define PHY_ANALOG_RXDAC_SET2_ATE_RXDAC_I_LOW_LSB                                                            16
-#define PHY_ANALOG_RXDAC_SET2_ATE_RXDAC_I_LOW_MASK                                                   0x001f0000
-#define PHY_ANALOG_RXDAC_SET2_ATE_RXDAC_I_LOW_GET(x)                                 (((x) & 0x001f0000) >> 16)
-#define PHY_ANALOG_RXDAC_SET2_ATE_RXDAC_I_LOW_SET(x)                                 (((x) << 16) & 0x001f0000)
-#define PHY_ANALOG_RXDAC_SET2_ATE_RXDAC_Q_LOW_MSB                                                            28
-#define PHY_ANALOG_RXDAC_SET2_ATE_RXDAC_Q_LOW_LSB                                                            24
-#define PHY_ANALOG_RXDAC_SET2_ATE_RXDAC_Q_LOW_MASK                                                   0x1f000000
-#define PHY_ANALOG_RXDAC_SET2_ATE_RXDAC_Q_LOW_GET(x)                                 (((x) & 0x1f000000) >> 24)
-#define PHY_ANALOG_RXDAC_SET2_ATE_RXDAC_Q_LOW_SET(x)                                 (((x) << 24) & 0x1f000000)
-
-/* macros for rxdac_long_shift */
-#define PHY_ANALOG_RXDAC_LONG_SHIFT_ADDRESS                                                          0x000003cc
-#define PHY_ANALOG_RXDAC_LONG_SHIFT_OFFSET                                                           0x000003cc
-#define PHY_ANALOG_RXDAC_LONG_SHIFT_ATE_RXDAC_I_STATIC_MSB                                                    4
-#define PHY_ANALOG_RXDAC_LONG_SHIFT_ATE_RXDAC_I_STATIC_LSB                                                    0
-#define PHY_ANALOG_RXDAC_LONG_SHIFT_ATE_RXDAC_I_STATIC_MASK                                          0x0000001f
-#define PHY_ANALOG_RXDAC_LONG_SHIFT_ATE_RXDAC_I_STATIC_GET(x)                         (((x) & 0x0000001f) >> 0)
-#define PHY_ANALOG_RXDAC_LONG_SHIFT_ATE_RXDAC_I_STATIC_SET(x)                         (((x) << 0) & 0x0000001f)
-#define PHY_ANALOG_RXDAC_LONG_SHIFT_ATE_RXDAC_Q_STATIC_MSB                                                   12
-#define PHY_ANALOG_RXDAC_LONG_SHIFT_ATE_RXDAC_Q_STATIC_LSB                                                    8
-#define PHY_ANALOG_RXDAC_LONG_SHIFT_ATE_RXDAC_Q_STATIC_MASK                                          0x00001f00
-#define PHY_ANALOG_RXDAC_LONG_SHIFT_ATE_RXDAC_Q_STATIC_GET(x)                         (((x) & 0x00001f00) >> 8)
-#define PHY_ANALOG_RXDAC_LONG_SHIFT_ATE_RXDAC_Q_STATIC_SET(x)                         (((x) << 8) & 0x00001f00)
-
-/* macros for cmac_results_i */
-#define PHY_ANALOG_CMAC_RESULTS_I_ADDRESS                                                            0x000003d0
-#define PHY_ANALOG_CMAC_RESULTS_I_OFFSET                                                             0x000003d0
-#define PHY_ANALOG_CMAC_RESULTS_I_ATE_CMAC_RESULTS_MSB                                                       31
-#define PHY_ANALOG_CMAC_RESULTS_I_ATE_CMAC_RESULTS_LSB                                                        0
-#define PHY_ANALOG_CMAC_RESULTS_I_ATE_CMAC_RESULTS_MASK                                              0xffffffff
-#define PHY_ANALOG_CMAC_RESULTS_I_ATE_CMAC_RESULTS_GET(x)                             (((x) & 0xffffffff) >> 0)
-#define PHY_ANALOG_CMAC_RESULTS_I_ATE_CMAC_RESULTS_SET(x)                             (((x) << 0) & 0xffffffff)
-
-/* macros for cmac_results_q */
-#define PHY_ANALOG_CMAC_RESULTS_Q_ADDRESS                                                            0x000003d4
-#define PHY_ANALOG_CMAC_RESULTS_Q_OFFSET                                                             0x000003d4
-#define PHY_ANALOG_CMAC_RESULTS_Q_ATE_CMAC_RESULTS_MSB                                                       31
-#define PHY_ANALOG_CMAC_RESULTS_Q_ATE_CMAC_RESULTS_LSB                                                        0
-#define PHY_ANALOG_CMAC_RESULTS_Q_ATE_CMAC_RESULTS_MASK                                              0xffffffff
-#define PHY_ANALOG_CMAC_RESULTS_Q_ATE_CMAC_RESULTS_GET(x)                             (((x) & 0xffffffff) >> 0)
-#define PHY_ANALOG_CMAC_RESULTS_Q_ATE_CMAC_RESULTS_SET(x)                             (((x) << 0) & 0xffffffff)
-
-/* macros for PMU1 */
-#define PHY_ANALOG_PMU1_ADDRESS                                                                      0x00000740
-#define PHY_ANALOG_PMU1_OFFSET                                                                       0x00000740
-#define PHY_ANALOG_PMU1_SPARE_MSB                                                                            10
-#define PHY_ANALOG_PMU1_SPARE_LSB                                                                             0
-#define PHY_ANALOG_PMU1_SPARE_MASK                                                                   0x000007ff
-#define PHY_ANALOG_PMU1_SPARE_GET(x)                                                  (((x) & 0x000007ff) >> 0)
-#define PHY_ANALOG_PMU1_SPARE_SET(x)                                                  (((x) << 0) & 0x000007ff)
-#define PHY_ANALOG_PMU1_OTP_V25_PWD_MSB                                                                      11
-#define PHY_ANALOG_PMU1_OTP_V25_PWD_LSB                                                                      11
-#define PHY_ANALOG_PMU1_OTP_V25_PWD_MASK                                                             0x00000800
-#define PHY_ANALOG_PMU1_OTP_V25_PWD_GET(x)                                           (((x) & 0x00000800) >> 11)
-#define PHY_ANALOG_PMU1_OTP_V25_PWD_SET(x)                                           (((x) << 11) & 0x00000800)
-#define PHY_ANALOG_PMU1_PAREGON_MAN_MSB                                                                      12
-#define PHY_ANALOG_PMU1_PAREGON_MAN_LSB                                                                      12
-#define PHY_ANALOG_PMU1_PAREGON_MAN_MASK                                                             0x00001000
-#define PHY_ANALOG_PMU1_PAREGON_MAN_GET(x)                                           (((x) & 0x00001000) >> 12)
-#define PHY_ANALOG_PMU1_PAREGON_MAN_SET(x)                                           (((x) << 12) & 0x00001000)
-#define PHY_ANALOG_PMU1_OTPREGON_MAN_MSB                                                                     13
-#define PHY_ANALOG_PMU1_OTPREGON_MAN_LSB                                                                     13
-#define PHY_ANALOG_PMU1_OTPREGON_MAN_MASK                                                            0x00002000
-#define PHY_ANALOG_PMU1_OTPREGON_MAN_GET(x)                                          (((x) & 0x00002000) >> 13)
-#define PHY_ANALOG_PMU1_OTPREGON_MAN_SET(x)                                          (((x) << 13) & 0x00002000)
-#define PHY_ANALOG_PMU1_DREGON_MAN_MSB                                                                       14
-#define PHY_ANALOG_PMU1_DREGON_MAN_LSB                                                                       14
-#define PHY_ANALOG_PMU1_DREGON_MAN_MASK                                                              0x00004000
-#define PHY_ANALOG_PMU1_DREGON_MAN_GET(x)                                            (((x) & 0x00004000) >> 14)
-#define PHY_ANALOG_PMU1_DREGON_MAN_SET(x)                                            (((x) << 14) & 0x00004000)
-#define PHY_ANALOG_PMU1_DISCONTMODEEN_MSB                                                                    15
-#define PHY_ANALOG_PMU1_DISCONTMODEEN_LSB                                                                    15
-#define PHY_ANALOG_PMU1_DISCONTMODEEN_MASK                                                           0x00008000
-#define PHY_ANALOG_PMU1_DISCONTMODEEN_GET(x)                                         (((x) & 0x00008000) >> 15)
-#define PHY_ANALOG_PMU1_DISCONTMODEEN_SET(x)                                         (((x) << 15) & 0x00008000)
-#define PHY_ANALOG_PMU1_SWREGON_MAN_MSB                                                                      16
-#define PHY_ANALOG_PMU1_SWREGON_MAN_LSB                                                                      16
-#define PHY_ANALOG_PMU1_SWREGON_MAN_MASK                                                             0x00010000
-#define PHY_ANALOG_PMU1_SWREGON_MAN_GET(x)                                           (((x) & 0x00010000) >> 16)
-#define PHY_ANALOG_PMU1_SWREGON_MAN_SET(x)                                           (((x) << 16) & 0x00010000)
-#define PHY_ANALOG_PMU1_SWREG_FREQCUR_MSB                                                                    18
-#define PHY_ANALOG_PMU1_SWREG_FREQCUR_LSB                                                                    17
-#define PHY_ANALOG_PMU1_SWREG_FREQCUR_MASK                                                           0x00060000
-#define PHY_ANALOG_PMU1_SWREG_FREQCUR_GET(x)                                         (((x) & 0x00060000) >> 17)
-#define PHY_ANALOG_PMU1_SWREG_FREQCUR_SET(x)                                         (((x) << 17) & 0x00060000)
-#define PHY_ANALOG_PMU1_SWREG_FREQCAP_MSB                                                                    21
-#define PHY_ANALOG_PMU1_SWREG_FREQCAP_LSB                                                                    19
-#define PHY_ANALOG_PMU1_SWREG_FREQCAP_MASK                                                           0x00380000
-#define PHY_ANALOG_PMU1_SWREG_FREQCAP_GET(x)                                         (((x) & 0x00380000) >> 19)
-#define PHY_ANALOG_PMU1_SWREG_FREQCAP_SET(x)                                         (((x) << 19) & 0x00380000)
-#define PHY_ANALOG_PMU1_SWREG_LVLCTR_MSB                                                                     23
-#define PHY_ANALOG_PMU1_SWREG_LVLCTR_LSB                                                                     22
-#define PHY_ANALOG_PMU1_SWREG_LVLCTR_MASK                                                            0x00c00000
-#define PHY_ANALOG_PMU1_SWREG_LVLCTR_GET(x)                                          (((x) & 0x00c00000) >> 22)
-#define PHY_ANALOG_PMU1_SWREG_LVLCTR_SET(x)                                          (((x) << 22) & 0x00c00000)
-#define PHY_ANALOG_PMU1_SREG_LVLCTR_MSB                                                                      25
-#define PHY_ANALOG_PMU1_SREG_LVLCTR_LSB                                                                      24
-#define PHY_ANALOG_PMU1_SREG_LVLCTR_MASK                                                             0x03000000
-#define PHY_ANALOG_PMU1_SREG_LVLCTR_GET(x)                                           (((x) & 0x03000000) >> 24)
-#define PHY_ANALOG_PMU1_SREG_LVLCTR_SET(x)                                           (((x) << 24) & 0x03000000)
-#define PHY_ANALOG_PMU1_DREG_LVLCTR_MSB                                                                      27
-#define PHY_ANALOG_PMU1_DREG_LVLCTR_LSB                                                                      26
-#define PHY_ANALOG_PMU1_DREG_LVLCTR_MASK                                                             0x0c000000
-#define PHY_ANALOG_PMU1_DREG_LVLCTR_GET(x)                                           (((x) & 0x0c000000) >> 26)
-#define PHY_ANALOG_PMU1_DREG_LVLCTR_SET(x)                                           (((x) << 26) & 0x0c000000)
-#define PHY_ANALOG_PMU1_PAREG_XPNP_MSB                                                                       28
-#define PHY_ANALOG_PMU1_PAREG_XPNP_LSB                                                                       28
-#define PHY_ANALOG_PMU1_PAREG_XPNP_MASK                                                              0x10000000
-#define PHY_ANALOG_PMU1_PAREG_XPNP_GET(x)                                            (((x) & 0x10000000) >> 28)
-#define PHY_ANALOG_PMU1_PAREG_XPNP_SET(x)                                            (((x) << 28) & 0x10000000)
-#define PHY_ANALOG_PMU1_PAREG_LVLCTR_MSB                                                                     31
-#define PHY_ANALOG_PMU1_PAREG_LVLCTR_LSB                                                                     29
-#define PHY_ANALOG_PMU1_PAREG_LVLCTR_MASK                                                            0xe0000000
-#define PHY_ANALOG_PMU1_PAREG_LVLCTR_GET(x)                                          (((x) & 0xe0000000) >> 29)
-#define PHY_ANALOG_PMU1_PAREG_LVLCTR_SET(x)                                          (((x) << 29) & 0xe0000000)
-
-/* macros for PMU2 */
-#define PHY_ANALOG_PMU2_ADDRESS                                                                      0x00000744
-#define PHY_ANALOG_PMU2_OFFSET                                                                       0x00000744
-#define PHY_ANALOG_PMU2_SPARE_MSB                                                                             7
-#define PHY_ANALOG_PMU2_SPARE_LSB                                                                             0
-#define PHY_ANALOG_PMU2_SPARE_MASK                                                                   0x000000ff
-#define PHY_ANALOG_PMU2_SPARE_GET(x)                                                  (((x) & 0x000000ff) >> 0)
-#define PHY_ANALOG_PMU2_SPARE_SET(x)                                                  (((x) << 0) & 0x000000ff)
-#define PHY_ANALOG_PMU2_VBATT_1_3TOATB_MSB                                                                    8
-#define PHY_ANALOG_PMU2_VBATT_1_3TOATB_LSB                                                                    8
-#define PHY_ANALOG_PMU2_VBATT_1_3TOATB_MASK                                                          0x00000100
-#define PHY_ANALOG_PMU2_VBATT_1_3TOATB_GET(x)                                         (((x) & 0x00000100) >> 8)
-#define PHY_ANALOG_PMU2_VBATT_1_3TOATB_SET(x)                                         (((x) << 8) & 0x00000100)
-#define PHY_ANALOG_PMU2_VBATT_1_2TOATB_MSB                                                                    9
-#define PHY_ANALOG_PMU2_VBATT_1_2TOATB_LSB                                                                    9
-#define PHY_ANALOG_PMU2_VBATT_1_2TOATB_MASK                                                          0x00000200
-#define PHY_ANALOG_PMU2_VBATT_1_2TOATB_GET(x)                                         (((x) & 0x00000200) >> 9)
-#define PHY_ANALOG_PMU2_VBATT_1_2TOATB_SET(x)                                         (((x) << 9) & 0x00000200)
-#define PHY_ANALOG_PMU2_VBATT_2_3TOATB_MSB                                                                   10
-#define PHY_ANALOG_PMU2_VBATT_2_3TOATB_LSB                                                                   10
-#define PHY_ANALOG_PMU2_VBATT_2_3TOATB_MASK                                                          0x00000400
-#define PHY_ANALOG_PMU2_VBATT_2_3TOATB_GET(x)                                        (((x) & 0x00000400) >> 10)
-#define PHY_ANALOG_PMU2_VBATT_2_3TOATB_SET(x)                                        (((x) << 10) & 0x00000400)
-#define PHY_ANALOG_PMU2_PWD_BANDGAP_MAN_MSB                                                                  11
-#define PHY_ANALOG_PMU2_PWD_BANDGAP_MAN_LSB                                                                  11
-#define PHY_ANALOG_PMU2_PWD_BANDGAP_MAN_MASK                                                         0x00000800
-#define PHY_ANALOG_PMU2_PWD_BANDGAP_MAN_GET(x)                                       (((x) & 0x00000800) >> 11)
-#define PHY_ANALOG_PMU2_PWD_BANDGAP_MAN_SET(x)                                       (((x) << 11) & 0x00000800)
-#define PHY_ANALOG_PMU2_PWD_LFO_MAN_MSB                                                                      12
-#define PHY_ANALOG_PMU2_PWD_LFO_MAN_LSB                                                                      12
-#define PHY_ANALOG_PMU2_PWD_LFO_MAN_MASK                                                             0x00001000
-#define PHY_ANALOG_PMU2_PWD_LFO_MAN_GET(x)                                           (((x) & 0x00001000) >> 12)
-#define PHY_ANALOG_PMU2_PWD_LFO_MAN_SET(x)                                           (((x) << 12) & 0x00001000)
-#define PHY_ANALOG_PMU2_VBATT_LT_3P2_MSB                                                                     13
-#define PHY_ANALOG_PMU2_VBATT_LT_3P2_LSB                                                                     13
-#define PHY_ANALOG_PMU2_VBATT_LT_3P2_MASK                                                            0x00002000
-#define PHY_ANALOG_PMU2_VBATT_LT_3P2_GET(x)                                          (((x) & 0x00002000) >> 13)
-#define PHY_ANALOG_PMU2_VBATT_LT_3P2_SET(x)                                          (((x) << 13) & 0x00002000)
-#define PHY_ANALOG_PMU2_VBATT_LT_2P8_MSB                                                                     14
-#define PHY_ANALOG_PMU2_VBATT_LT_2P8_LSB                                                                     14
-#define PHY_ANALOG_PMU2_VBATT_LT_2P8_MASK                                                            0x00004000
-#define PHY_ANALOG_PMU2_VBATT_LT_2P8_GET(x)                                          (((x) & 0x00004000) >> 14)
-#define PHY_ANALOG_PMU2_VBATT_LT_2P8_SET(x)                                          (((x) << 14) & 0x00004000)
-#define PHY_ANALOG_PMU2_VBATT_GT_4P2_MSB                                                                     15
-#define PHY_ANALOG_PMU2_VBATT_GT_4P2_LSB                                                                     15
-#define PHY_ANALOG_PMU2_VBATT_GT_4P2_MASK                                                            0x00008000
-#define PHY_ANALOG_PMU2_VBATT_GT_4P2_GET(x)                                          (((x) & 0x00008000) >> 15)
-#define PHY_ANALOG_PMU2_VBATT_GT_4P2_SET(x)                                          (((x) << 15) & 0x00008000)
-#define PHY_ANALOG_PMU2_PMU_MAN_OVERRIDE_EN_MSB                                                              16
-#define PHY_ANALOG_PMU2_PMU_MAN_OVERRIDE_EN_LSB                                                              16
-#define PHY_ANALOG_PMU2_PMU_MAN_OVERRIDE_EN_MASK                                                     0x00010000
-#define PHY_ANALOG_PMU2_PMU_MAN_OVERRIDE_EN_GET(x)                                   (((x) & 0x00010000) >> 16)
-#define PHY_ANALOG_PMU2_PMU_MAN_OVERRIDE_EN_SET(x)                                   (((x) << 16) & 0x00010000)
-#define PHY_ANALOG_PMU2_VBATT_GT_LVLCTR_MSB                                                                  18
-#define PHY_ANALOG_PMU2_VBATT_GT_LVLCTR_LSB                                                                  17
-#define PHY_ANALOG_PMU2_VBATT_GT_LVLCTR_MASK                                                         0x00060000
-#define PHY_ANALOG_PMU2_VBATT_GT_LVLCTR_GET(x)                                       (((x) & 0x00060000) >> 17)
-#define PHY_ANALOG_PMU2_VBATT_GT_LVLCTR_SET(x)                                       (((x) << 17) & 0x00060000)
-#define PHY_ANALOG_PMU2_SWREGVSSL2ATB_MSB                                                                    19
-#define PHY_ANALOG_PMU2_SWREGVSSL2ATB_LSB                                                                    19
-#define PHY_ANALOG_PMU2_SWREGVSSL2ATB_MASK                                                           0x00080000
-#define PHY_ANALOG_PMU2_SWREGVSSL2ATB_GET(x)                                         (((x) & 0x00080000) >> 19)
-#define PHY_ANALOG_PMU2_SWREGVSSL2ATB_SET(x)                                         (((x) << 19) & 0x00080000)
-#define PHY_ANALOG_PMU2_SWREGVSSL_LVLCTR_MSB                                                                 21
-#define PHY_ANALOG_PMU2_SWREGVSSL_LVLCTR_LSB                                                                 20
-#define PHY_ANALOG_PMU2_SWREGVSSL_LVLCTR_MASK                                                        0x00300000
-#define PHY_ANALOG_PMU2_SWREGVSSL_LVLCTR_GET(x)                                      (((x) & 0x00300000) >> 20)
-#define PHY_ANALOG_PMU2_SWREGVSSL_LVLCTR_SET(x)                                      (((x) << 20) & 0x00300000)
-#define PHY_ANALOG_PMU2_SWREGVDDH2ATB_MSB                                                                    22
-#define PHY_ANALOG_PMU2_SWREGVDDH2ATB_LSB                                                                    22
-#define PHY_ANALOG_PMU2_SWREGVDDH2ATB_MASK                                                           0x00400000
-#define PHY_ANALOG_PMU2_SWREGVDDH2ATB_GET(x)                                         (((x) & 0x00400000) >> 22)
-#define PHY_ANALOG_PMU2_SWREGVDDH2ATB_SET(x)                                         (((x) << 22) & 0x00400000)
-#define PHY_ANALOG_PMU2_SWREGVDDH_LVLCTR_MSB                                                                 24
-#define PHY_ANALOG_PMU2_SWREGVDDH_LVLCTR_LSB                                                                 23
-#define PHY_ANALOG_PMU2_SWREGVDDH_LVLCTR_MASK                                                        0x01800000
-#define PHY_ANALOG_PMU2_SWREGVDDH_LVLCTR_GET(x)                                      (((x) & 0x01800000) >> 23)
-#define PHY_ANALOG_PMU2_SWREGVDDH_LVLCTR_SET(x)                                      (((x) << 23) & 0x01800000)
-#define PHY_ANALOG_PMU2_SWREG2ATB_MSB                                                                        27
-#define PHY_ANALOG_PMU2_SWREG2ATB_LSB                                                                        25
-#define PHY_ANALOG_PMU2_SWREG2ATB_MASK                                                               0x0e000000
-#define PHY_ANALOG_PMU2_SWREG2ATB_GET(x)                                             (((x) & 0x0e000000) >> 25)
-#define PHY_ANALOG_PMU2_SWREG2ATB_SET(x)                                             (((x) << 25) & 0x0e000000)
-#define PHY_ANALOG_PMU2_OTPREG2ATB_MSB                                                                       28
-#define PHY_ANALOG_PMU2_OTPREG2ATB_LSB                                                                       28
-#define PHY_ANALOG_PMU2_OTPREG2ATB_MASK                                                              0x10000000
-#define PHY_ANALOG_PMU2_OTPREG2ATB_GET(x)                                            (((x) & 0x10000000) >> 28)
-#define PHY_ANALOG_PMU2_OTPREG2ATB_SET(x)                                            (((x) << 28) & 0x10000000)
-#define PHY_ANALOG_PMU2_OTPREG_LVLCTR_MSB                                                                    30
-#define PHY_ANALOG_PMU2_OTPREG_LVLCTR_LSB                                                                    29
-#define PHY_ANALOG_PMU2_OTPREG_LVLCTR_MASK                                                           0x60000000
-#define PHY_ANALOG_PMU2_OTPREG_LVLCTR_GET(x)                                         (((x) & 0x60000000) >> 29)
-#define PHY_ANALOG_PMU2_OTPREG_LVLCTR_SET(x)                                         (((x) << 29) & 0x60000000)
-#define PHY_ANALOG_PMU2_DREG_LVLCTR_MANOVR_EN_MSB                                                            31
-#define PHY_ANALOG_PMU2_DREG_LVLCTR_MANOVR_EN_LSB                                                            31
-#define PHY_ANALOG_PMU2_DREG_LVLCTR_MANOVR_EN_MASK                                                   0x80000000
-#define PHY_ANALOG_PMU2_DREG_LVLCTR_MANOVR_EN_GET(x)                                 (((x) & 0x80000000) >> 31)
-#define PHY_ANALOG_PMU2_DREG_LVLCTR_MANOVR_EN_SET(x)                                 (((x) << 31) & 0x80000000)
-
-
-#ifndef __ASSEMBLER__
-
-typedef struct analog_intf_ares_reg_reg_s {
-  volatile unsigned int RXRF_BIAS1;                                    /*        0x0 - 0x4        */
-  volatile unsigned int RXRF_BIAS2;                                    /*        0x4 - 0x8        */
-  volatile unsigned int RXRF_GAINSTAGES;                               /*        0x8 - 0xc        */
-  volatile unsigned int RXRF_AGC;                                      /*        0xc - 0x10       */
-  volatile char pad__0[0x30];                                          /*       0x10 - 0x40       */
-  volatile unsigned int TXRF1;                                         /*       0x40 - 0x44       */
-  volatile unsigned int TXRF2;                                         /*       0x44 - 0x48       */
-  volatile unsigned int TXRF3;                                         /*       0x48 - 0x4c       */
-  volatile unsigned int TXRF4;                                         /*       0x4c - 0x50       */
-  volatile unsigned int TXRF5;                                         /*       0x50 - 0x54       */
-  volatile unsigned int TXRF6;                                         /*       0x54 - 0x58       */
-  volatile unsigned int TXRF7;                                         /*       0x58 - 0x5c       */
-  volatile unsigned int TXRF8;                                         /*       0x5c - 0x60       */
-  volatile unsigned int TXRF9;                                         /*       0x60 - 0x64       */
-  volatile unsigned int TXRF10;                                        /*       0x64 - 0x68       */
-  volatile unsigned int TXRF11;                                        /*       0x68 - 0x6c       */
-  volatile unsigned int TXRF12;                                        /*       0x6c - 0x70       */
-  volatile char pad__1[0x10];                                          /*       0x70 - 0x80       */
-  volatile unsigned int SYNTH1;                                        /*       0x80 - 0x84       */
-  volatile unsigned int SYNTH2;                                        /*       0x84 - 0x88       */
-  volatile unsigned int SYNTH3;                                        /*       0x88 - 0x8c       */
-  volatile unsigned int SYNTH4;                                        /*       0x8c - 0x90       */
-  volatile unsigned int SYNTH5;                                        /*       0x90 - 0x94       */
-  volatile unsigned int SYNTH6;                                        /*       0x94 - 0x98       */
-  volatile unsigned int SYNTH7;                                        /*       0x98 - 0x9c       */
-  volatile unsigned int SYNTH8;                                        /*       0x9c - 0xa0       */
-  volatile unsigned int SYNTH9;                                        /*       0xa0 - 0xa4       */
-  volatile unsigned int SYNTH10;                                       /*       0xa4 - 0xa8       */
-  volatile unsigned int SYNTH11;                                       /*       0xa8 - 0xac       */
-  volatile unsigned int SYNTH12;                                       /*       0xac - 0xb0       */
-  volatile char pad__2[0x10];                                          /*       0xb0 - 0xc0       */
-  volatile unsigned int BIAS1;                                         /*       0xc0 - 0xc4       */
-  volatile unsigned int BIAS2;                                         /*       0xc4 - 0xc8       */
-  volatile unsigned int BIAS3;                                         /*       0xc8 - 0xcc       */
-  volatile unsigned int BIAS4;                                         /*       0xcc - 0xd0       */
-  volatile char pad__3[0x30];                                          /*       0xd0 - 0x100      */
-  volatile unsigned int RXTX1;                                         /*      0x100 - 0x104      */
-  volatile unsigned int RXTX2;                                         /*      0x104 - 0x108      */
-  volatile unsigned int RXTX3;                                         /*      0x108 - 0x10c      */
-  volatile char pad__4[0x34];                                          /*      0x10c - 0x140      */
-  volatile unsigned int BB1;                                           /*      0x140 - 0x144      */
-  volatile unsigned int BB2;                                           /*      0x144 - 0x148      */
-  volatile char pad__5[0x138];                                         /*      0x148 - 0x280      */
-  volatile unsigned int TOP1;                                          /*      0x280 - 0x284      */
-  volatile unsigned int TOP2;                                          /*      0x284 - 0x288      */
-  volatile unsigned int TOP3;                                          /*      0x288 - 0x28c      */
-  volatile unsigned int TOP4;                                          /*      0x28c - 0x290      */
-  volatile char pad__6[0xf0];                                          /*      0x290 - 0x380      */
-  volatile unsigned int rbist_cntrl;                                   /*      0x380 - 0x384      */
-  volatile unsigned int tx_dc_offset;                                  /*      0x384 - 0x388      */
-  volatile unsigned int tx_tonegen0;                                   /*      0x388 - 0x38c      */
-  volatile unsigned int tx_tonegen1;                                   /*      0x38c - 0x390      */
-  volatile unsigned int tx_lftonegen0;                                 /*      0x390 - 0x394      */
-  volatile unsigned int tx_linear_ramp_i;                              /*      0x394 - 0x398      */
-  volatile unsigned int tx_linear_ramp_q;                              /*      0x398 - 0x39c      */
-  volatile unsigned int tx_prbs_mag;                                   /*      0x39c - 0x3a0      */
-  volatile unsigned int tx_prbs_seed_i;                                /*      0x3a0 - 0x3a4      */
-  volatile unsigned int tx_prbs_seed_q;                                /*      0x3a4 - 0x3a8      */
-  volatile unsigned int cmac_dc_cancel;                                /*      0x3a8 - 0x3ac      */
-  volatile unsigned int cmac_dc_offset;                                /*      0x3ac - 0x3b0      */
-  volatile unsigned int cmac_corr;                                     /*      0x3b0 - 0x3b4      */
-  volatile unsigned int cmac_power;                                    /*      0x3b4 - 0x3b8      */
-  volatile unsigned int cmac_cross_corr;                               /*      0x3b8 - 0x3bc      */
-  volatile unsigned int cmac_i2q2;                                     /*      0x3bc - 0x3c0      */
-  volatile unsigned int cmac_power_hpf;                                /*      0x3c0 - 0x3c4      */
-  volatile unsigned int rxdac_set1;                                    /*      0x3c4 - 0x3c8      */
-  volatile unsigned int rxdac_set2;                                    /*      0x3c8 - 0x3cc      */
-  volatile unsigned int rxdac_long_shift;                              /*      0x3cc - 0x3d0      */
-  volatile unsigned int cmac_results_i;                                /*      0x3d0 - 0x3d4      */
-  volatile unsigned int cmac_results_q;                                /*      0x3d4 - 0x3d8      */
-  volatile char pad__7[0x368];                                         /*      0x3d8 - 0x740      */
-  volatile unsigned int PMU1;                                          /*      0x740 - 0x744      */
-  volatile unsigned int PMU2;                                          /*      0x744 - 0x748      */
-} analog_intf_ares_reg_reg_t;
-
-#endif /* __ASSEMBLER__ */
-
-#endif /* _ANALOG_INTF_ARES_REG_REG_H_ */
diff -druN linux-2.6.39-libre/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/analog_intf_athr_wlan_reg.h linux-3.0-rc7-libre/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/analog_intf_athr_wlan_reg.h
--- linux-2.6.39-libre/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/analog_intf_athr_wlan_reg.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/analog_intf_athr_wlan_reg.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,3674 +0,0 @@
-// ------------------------------------------------------------------
-// Copyright (c) 2004-2010 Atheros Corporation.  All rights reserved.
-// 
-//
-// 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.
-//
-//
-// ------------------------------------------------------------------
-//===================================================================
-// Author(s): ="Atheros"
-//===================================================================
-
-/* Copyright (C) 2009 Denali Software Inc.  All rights reserved              */
-/* THIS FILE IS AUTOMATICALLY GENERATED BY DENALI BLUEPRINT, DO NOT EDIT     */
-
-
-#ifndef _ANALOG_INTF_ATHR_WLAN_REG_REG_H_
-#define _ANALOG_INTF_ATHR_WLAN_REG_REG_H_
-
-
-/* macros for RXRF_BIAS1 */
-#define PHY_ANALOG_RXRF_BIAS1_ADDRESS                                                                0x00000000
-#define PHY_ANALOG_RXRF_BIAS1_OFFSET                                                                 0x00000000
-#define PHY_ANALOG_RXRF_BIAS1_SPARE_MSB                                                                       0
-#define PHY_ANALOG_RXRF_BIAS1_SPARE_LSB                                                                       0
-#define PHY_ANALOG_RXRF_BIAS1_SPARE_MASK                                                             0x00000001
-#define PHY_ANALOG_RXRF_BIAS1_SPARE_GET(x)                                            (((x) & 0x00000001) >> 0)
-#define PHY_ANALOG_RXRF_BIAS1_SPARE_SET(x)                                            (((x) << 0) & 0x00000001)
-#define PHY_ANALOG_RXRF_BIAS1_PWD_IR25SPARE_MSB                                                               3
-#define PHY_ANALOG_RXRF_BIAS1_PWD_IR25SPARE_LSB                                                               1
-#define PHY_ANALOG_RXRF_BIAS1_PWD_IR25SPARE_MASK                                                     0x0000000e
-#define PHY_ANALOG_RXRF_BIAS1_PWD_IR25SPARE_GET(x)                                    (((x) & 0x0000000e) >> 1)
-#define PHY_ANALOG_RXRF_BIAS1_PWD_IR25SPARE_SET(x)                                    (((x) << 1) & 0x0000000e)
-#define PHY_ANALOG_RXRF_BIAS1_PWD_IR25LO18_MSB                                                                6
-#define PHY_ANALOG_RXRF_BIAS1_PWD_IR25LO18_LSB                                                                4
-#define PHY_ANALOG_RXRF_BIAS1_PWD_IR25LO18_MASK                                                      0x00000070
-#define PHY_ANALOG_RXRF_BIAS1_PWD_IR25LO18_GET(x)                                     (((x) & 0x00000070) >> 4)
-#define PHY_ANALOG_RXRF_BIAS1_PWD_IR25LO18_SET(x)                                     (((x) << 4) & 0x00000070)
-#define PHY_ANALOG_RXRF_BIAS1_PWD_IC25LO36_MSB                                                                9
-#define PHY_ANALOG_RXRF_BIAS1_PWD_IC25LO36_LSB                                                                7
-#define PHY_ANALOG_RXRF_BIAS1_PWD_IC25LO36_MASK                                                      0x00000380
-#define PHY_ANALOG_RXRF_BIAS1_PWD_IC25LO36_GET(x)                                     (((x) & 0x00000380) >> 7)
-#define PHY_ANALOG_RXRF_BIAS1_PWD_IC25LO36_SET(x)                                     (((x) << 7) & 0x00000380)
-#define PHY_ANALOG_RXRF_BIAS1_PWD_IC25MXR2_5GH_MSB                                                           12
-#define PHY_ANALOG_RXRF_BIAS1_PWD_IC25MXR2_5GH_LSB                                                           10
-#define PHY_ANALOG_RXRF_BIAS1_PWD_IC25MXR2_5GH_MASK                                                  0x00001c00
-#define PHY_ANALOG_RXRF_BIAS1_PWD_IC25MXR2_5GH_GET(x)                                (((x) & 0x00001c00) >> 10)
-#define PHY_ANALOG_RXRF_BIAS1_PWD_IC25MXR2_5GH_SET(x)                                (((x) << 10) & 0x00001c00)
-#define PHY_ANALOG_RXRF_BIAS1_PWD_IC25MXR5GH_MSB                                                             15
-#define PHY_ANALOG_RXRF_BIAS1_PWD_IC25MXR5GH_LSB                                                             13
-#define PHY_ANALOG_RXRF_BIAS1_PWD_IC25MXR5GH_MASK                                                    0x0000e000
-#define PHY_ANALOG_RXRF_BIAS1_PWD_IC25MXR5GH_GET(x)                                  (((x) & 0x0000e000) >> 13)
-#define PHY_ANALOG_RXRF_BIAS1_PWD_IC25MXR5GH_SET(x)                                  (((x) << 13) & 0x0000e000)
-#define PHY_ANALOG_RXRF_BIAS1_PWD_IC25VGA5G_MSB                                                              18
-#define PHY_ANALOG_RXRF_BIAS1_PWD_IC25VGA5G_LSB                                                              16
-#define PHY_ANALOG_RXRF_BIAS1_PWD_IC25VGA5G_MASK                                                     0x00070000
-#define PHY_ANALOG_RXRF_BIAS1_PWD_IC25VGA5G_GET(x)                                   (((x) & 0x00070000) >> 16)
-#define PHY_ANALOG_RXRF_BIAS1_PWD_IC25VGA5G_SET(x)                                   (((x) << 16) & 0x00070000)
-#define PHY_ANALOG_RXRF_BIAS1_PWD_IC75LNA5G_MSB                                                              21
-#define PHY_ANALOG_RXRF_BIAS1_PWD_IC75LNA5G_LSB                                                              19
-#define PHY_ANALOG_RXRF_BIAS1_PWD_IC75LNA5G_MASK                                                     0x00380000
-#define PHY_ANALOG_RXRF_BIAS1_PWD_IC75LNA5G_GET(x)                                   (((x) & 0x00380000) >> 19)
-#define PHY_ANALOG_RXRF_BIAS1_PWD_IC75LNA5G_SET(x)                                   (((x) << 19) & 0x00380000)
-#define PHY_ANALOG_RXRF_BIAS1_PWD_IR25LO24_MSB                                                               24
-#define PHY_ANALOG_RXRF_BIAS1_PWD_IR25LO24_LSB                                                               22
-#define PHY_ANALOG_RXRF_BIAS1_PWD_IR25LO24_MASK                                                      0x01c00000
-#define PHY_ANALOG_RXRF_BIAS1_PWD_IR25LO24_GET(x)                                    (((x) & 0x01c00000) >> 22)
-#define PHY_ANALOG_RXRF_BIAS1_PWD_IR25LO24_SET(x)                                    (((x) << 22) & 0x01c00000)
-#define PHY_ANALOG_RXRF_BIAS1_PWD_IC25MXR2GH_MSB                                                             27
-#define PHY_ANALOG_RXRF_BIAS1_PWD_IC25MXR2GH_LSB                                                             25
-#define PHY_ANALOG_RXRF_BIAS1_PWD_IC25MXR2GH_MASK                                                    0x0e000000
-#define PHY_ANALOG_RXRF_BIAS1_PWD_IC25MXR2GH_GET(x)                                  (((x) & 0x0e000000) >> 25)
-#define PHY_ANALOG_RXRF_BIAS1_PWD_IC25MXR2GH_SET(x)                                  (((x) << 25) & 0x0e000000)
-#define PHY_ANALOG_RXRF_BIAS1_PWD_IC75LNA2G_MSB                                                              30
-#define PHY_ANALOG_RXRF_BIAS1_PWD_IC75LNA2G_LSB                                                              28
-#define PHY_ANALOG_RXRF_BIAS1_PWD_IC75LNA2G_MASK                                                     0x70000000
-#define PHY_ANALOG_RXRF_BIAS1_PWD_IC75LNA2G_GET(x)                                   (((x) & 0x70000000) >> 28)
-#define PHY_ANALOG_RXRF_BIAS1_PWD_IC75LNA2G_SET(x)                                   (((x) << 28) & 0x70000000)
-#define PHY_ANALOG_RXRF_BIAS1_PWD_BIAS_MSB                                                                   31
-#define PHY_ANALOG_RXRF_BIAS1_PWD_BIAS_LSB                                                                   31
-#define PHY_ANALOG_RXRF_BIAS1_PWD_BIAS_MASK                                                          0x80000000
-#define PHY_ANALOG_RXRF_BIAS1_PWD_BIAS_GET(x)                                        (((x) & 0x80000000) >> 31)
-#define PHY_ANALOG_RXRF_BIAS1_PWD_BIAS_SET(x)                                        (((x) << 31) & 0x80000000)
-
-/* macros for RXRF_BIAS2 */
-#define PHY_ANALOG_RXRF_BIAS2_ADDRESS                                                                0x00000004
-#define PHY_ANALOG_RXRF_BIAS2_OFFSET                                                                 0x00000004
-#define PHY_ANALOG_RXRF_BIAS2_SPARE_MSB                                                                       0
-#define PHY_ANALOG_RXRF_BIAS2_SPARE_LSB                                                                       0
-#define PHY_ANALOG_RXRF_BIAS2_SPARE_MASK                                                             0x00000001
-#define PHY_ANALOG_RXRF_BIAS2_SPARE_GET(x)                                            (((x) & 0x00000001) >> 0)
-#define PHY_ANALOG_RXRF_BIAS2_SPARE_SET(x)                                            (((x) << 0) & 0x00000001)
-#define PHY_ANALOG_RXRF_BIAS2_PKEN_MSB                                                                        3
-#define PHY_ANALOG_RXRF_BIAS2_PKEN_LSB                                                                        1
-#define PHY_ANALOG_RXRF_BIAS2_PKEN_MASK                                                              0x0000000e
-#define PHY_ANALOG_RXRF_BIAS2_PKEN_GET(x)                                             (((x) & 0x0000000e) >> 1)
-#define PHY_ANALOG_RXRF_BIAS2_PKEN_SET(x)                                             (((x) << 1) & 0x0000000e)
-#define PHY_ANALOG_RXRF_BIAS2_VCMVALUE_MSB                                                                    6
-#define PHY_ANALOG_RXRF_BIAS2_VCMVALUE_LSB                                                                    4
-#define PHY_ANALOG_RXRF_BIAS2_VCMVALUE_MASK                                                          0x00000070
-#define PHY_ANALOG_RXRF_BIAS2_VCMVALUE_GET(x)                                         (((x) & 0x00000070) >> 4)
-#define PHY_ANALOG_RXRF_BIAS2_VCMVALUE_SET(x)                                         (((x) << 4) & 0x00000070)
-#define PHY_ANALOG_RXRF_BIAS2_PWD_VCMBUF_MSB                                                                  7
-#define PHY_ANALOG_RXRF_BIAS2_PWD_VCMBUF_LSB                                                                  7
-#define PHY_ANALOG_RXRF_BIAS2_PWD_VCMBUF_MASK                                                        0x00000080
-#define PHY_ANALOG_RXRF_BIAS2_PWD_VCMBUF_GET(x)                                       (((x) & 0x00000080) >> 7)
-#define PHY_ANALOG_RXRF_BIAS2_PWD_VCMBUF_SET(x)                                       (((x) << 7) & 0x00000080)
-#define PHY_ANALOG_RXRF_BIAS2_PWD_IR25SPAREH_MSB                                                             10
-#define PHY_ANALOG_RXRF_BIAS2_PWD_IR25SPAREH_LSB                                                              8
-#define PHY_ANALOG_RXRF_BIAS2_PWD_IR25SPAREH_MASK                                                    0x00000700
-#define PHY_ANALOG_RXRF_BIAS2_PWD_IR25SPAREH_GET(x)                                   (((x) & 0x00000700) >> 8)
-#define PHY_ANALOG_RXRF_BIAS2_PWD_IR25SPAREH_SET(x)                                   (((x) << 8) & 0x00000700)
-#define PHY_ANALOG_RXRF_BIAS2_PWD_IR25SPARE_MSB                                                              13
-#define PHY_ANALOG_RXRF_BIAS2_PWD_IR25SPARE_LSB                                                              11
-#define PHY_ANALOG_RXRF_BIAS2_PWD_IR25SPARE_MASK                                                     0x00003800
-#define PHY_ANALOG_RXRF_BIAS2_PWD_IR25SPARE_GET(x)                                   (((x) & 0x00003800) >> 11)
-#define PHY_ANALOG_RXRF_BIAS2_PWD_IR25SPARE_SET(x)                                   (((x) << 11) & 0x00003800)
-#define PHY_ANALOG_RXRF_BIAS2_PWD_IC25LNABUF_MSB                                                             16
-#define PHY_ANALOG_RXRF_BIAS2_PWD_IC25LNABUF_LSB                                                             14
-#define PHY_ANALOG_RXRF_BIAS2_PWD_IC25LNABUF_MASK                                                    0x0001c000
-#define PHY_ANALOG_RXRF_BIAS2_PWD_IC25LNABUF_GET(x)                                  (((x) & 0x0001c000) >> 14)
-#define PHY_ANALOG_RXRF_BIAS2_PWD_IC25LNABUF_SET(x)                                  (((x) << 14) & 0x0001c000)
-#define PHY_ANALOG_RXRF_BIAS2_PWD_IR25AGCH_MSB                                                               19
-#define PHY_ANALOG_RXRF_BIAS2_PWD_IR25AGCH_LSB                                                               17
-#define PHY_ANALOG_RXRF_BIAS2_PWD_IR25AGCH_MASK                                                      0x000e0000
-#define PHY_ANALOG_RXRF_BIAS2_PWD_IR25AGCH_GET(x)                                    (((x) & 0x000e0000) >> 17)
-#define PHY_ANALOG_RXRF_BIAS2_PWD_IR25AGCH_SET(x)                                    (((x) << 17) & 0x000e0000)
-#define PHY_ANALOG_RXRF_BIAS2_PWD_IR25AGC_MSB                                                                22
-#define PHY_ANALOG_RXRF_BIAS2_PWD_IR25AGC_LSB                                                                20
-#define PHY_ANALOG_RXRF_BIAS2_PWD_IR25AGC_MASK                                                       0x00700000
-#define PHY_ANALOG_RXRF_BIAS2_PWD_IR25AGC_GET(x)                                     (((x) & 0x00700000) >> 20)
-#define PHY_ANALOG_RXRF_BIAS2_PWD_IR25AGC_SET(x)                                     (((x) << 20) & 0x00700000)
-#define PHY_ANALOG_RXRF_BIAS2_PWD_IC25AGC_MSB                                                                25
-#define PHY_ANALOG_RXRF_BIAS2_PWD_IC25AGC_LSB                                                                23
-#define PHY_ANALOG_RXRF_BIAS2_PWD_IC25AGC_MASK                                                       0x03800000
-#define PHY_ANALOG_RXRF_BIAS2_PWD_IC25AGC_GET(x)                                     (((x) & 0x03800000) >> 23)
-#define PHY_ANALOG_RXRF_BIAS2_PWD_IC25AGC_SET(x)                                     (((x) << 23) & 0x03800000)
-#define PHY_ANALOG_RXRF_BIAS2_PWD_IC25VCMBUF_MSB                                                             28
-#define PHY_ANALOG_RXRF_BIAS2_PWD_IC25VCMBUF_LSB                                                             26
-#define PHY_ANALOG_RXRF_BIAS2_PWD_IC25VCMBUF_MASK                                                    0x1c000000
-#define PHY_ANALOG_RXRF_BIAS2_PWD_IC25VCMBUF_GET(x)                                  (((x) & 0x1c000000) >> 26)
-#define PHY_ANALOG_RXRF_BIAS2_PWD_IC25VCMBUF_SET(x)                                  (((x) << 26) & 0x1c000000)
-#define PHY_ANALOG_RXRF_BIAS2_PWD_IR25VCM_MSB                                                                31
-#define PHY_ANALOG_RXRF_BIAS2_PWD_IR25VCM_LSB                                                                29
-#define PHY_ANALOG_RXRF_BIAS2_PWD_IR25VCM_MASK                                                       0xe0000000
-#define PHY_ANALOG_RXRF_BIAS2_PWD_IR25VCM_GET(x)                                     (((x) & 0xe0000000) >> 29)
-#define PHY_ANALOG_RXRF_BIAS2_PWD_IR25VCM_SET(x)                                     (((x) << 29) & 0xe0000000)
-
-/* macros for RXRF_GAINSTAGES */
-#define PHY_ANALOG_RXRF_GAINSTAGES_ADDRESS                                                           0x00000008
-#define PHY_ANALOG_RXRF_GAINSTAGES_OFFSET                                                            0x00000008
-#define PHY_ANALOG_RXRF_GAINSTAGES_SPARE_MSB                                                                  0
-#define PHY_ANALOG_RXRF_GAINSTAGES_SPARE_LSB                                                                  0
-#define PHY_ANALOG_RXRF_GAINSTAGES_SPARE_MASK                                                        0x00000001
-#define PHY_ANALOG_RXRF_GAINSTAGES_SPARE_GET(x)                                       (((x) & 0x00000001) >> 0)
-#define PHY_ANALOG_RXRF_GAINSTAGES_SPARE_SET(x)                                       (((x) << 0) & 0x00000001)
-#define PHY_ANALOG_RXRF_GAINSTAGES_LNAON_CALDC_MSB                                                            1
-#define PHY_ANALOG_RXRF_GAINSTAGES_LNAON_CALDC_LSB                                                            1
-#define PHY_ANALOG_RXRF_GAINSTAGES_LNAON_CALDC_MASK                                                  0x00000002
-#define PHY_ANALOG_RXRF_GAINSTAGES_LNAON_CALDC_GET(x)                                 (((x) & 0x00000002) >> 1)
-#define PHY_ANALOG_RXRF_GAINSTAGES_LNAON_CALDC_SET(x)                                 (((x) << 1) & 0x00000002)
-#define PHY_ANALOG_RXRF_GAINSTAGES_VGA5G_CAP_MSB                                                              3
-#define PHY_ANALOG_RXRF_GAINSTAGES_VGA5G_CAP_LSB                                                              2
-#define PHY_ANALOG_RXRF_GAINSTAGES_VGA5G_CAP_MASK                                                    0x0000000c
-#define PHY_ANALOG_RXRF_GAINSTAGES_VGA5G_CAP_GET(x)                                   (((x) & 0x0000000c) >> 2)
-#define PHY_ANALOG_RXRF_GAINSTAGES_VGA5G_CAP_SET(x)                                   (((x) << 2) & 0x0000000c)
-#define PHY_ANALOG_RXRF_GAINSTAGES_LNA5G_CAP_MSB                                                              5
-#define PHY_ANALOG_RXRF_GAINSTAGES_LNA5G_CAP_LSB                                                              4
-#define PHY_ANALOG_RXRF_GAINSTAGES_LNA5G_CAP_MASK                                                    0x00000030
-#define PHY_ANALOG_RXRF_GAINSTAGES_LNA5G_CAP_GET(x)                                   (((x) & 0x00000030) >> 4)
-#define PHY_ANALOG_RXRF_GAINSTAGES_LNA5G_CAP_SET(x)                                   (((x) << 4) & 0x00000030)
-#define PHY_ANALOG_RXRF_GAINSTAGES_LNA5G_SHORTINP_MSB                                                         6
-#define PHY_ANALOG_RXRF_GAINSTAGES_LNA5G_SHORTINP_LSB                                                         6
-#define PHY_ANALOG_RXRF_GAINSTAGES_LNA5G_SHORTINP_MASK                                               0x00000040
-#define PHY_ANALOG_RXRF_GAINSTAGES_LNA5G_SHORTINP_GET(x)                              (((x) & 0x00000040) >> 6)
-#define PHY_ANALOG_RXRF_GAINSTAGES_LNA5G_SHORTINP_SET(x)                              (((x) << 6) & 0x00000040)
-#define PHY_ANALOG_RXRF_GAINSTAGES_PWD_LO5G_MSB                                                               7
-#define PHY_ANALOG_RXRF_GAINSTAGES_PWD_LO5G_LSB                                                               7
-#define PHY_ANALOG_RXRF_GAINSTAGES_PWD_LO5G_MASK                                                     0x00000080
-#define PHY_ANALOG_RXRF_GAINSTAGES_PWD_LO5G_GET(x)                                    (((x) & 0x00000080) >> 7)
-#define PHY_ANALOG_RXRF_GAINSTAGES_PWD_LO5G_SET(x)                                    (((x) << 7) & 0x00000080)
-#define PHY_ANALOG_RXRF_GAINSTAGES_PWD_VGA5G_MSB                                                              8
-#define PHY_ANALOG_RXRF_GAINSTAGES_PWD_VGA5G_LSB                                                              8
-#define PHY_ANALOG_RXRF_GAINSTAGES_PWD_VGA5G_MASK                                                    0x00000100
-#define PHY_ANALOG_RXRF_GAINSTAGES_PWD_VGA5G_GET(x)                                   (((x) & 0x00000100) >> 8)
-#define PHY_ANALOG_RXRF_GAINSTAGES_PWD_VGA5G_SET(x)                                   (((x) << 8) & 0x00000100)
-#define PHY_ANALOG_RXRF_GAINSTAGES_PWD_MXR5G_MSB                                                              9
-#define PHY_ANALOG_RXRF_GAINSTAGES_PWD_MXR5G_LSB                                                              9
-#define PHY_ANALOG_RXRF_GAINSTAGES_PWD_MXR5G_MASK                                                    0x00000200
-#define PHY_ANALOG_RXRF_GAINSTAGES_PWD_MXR5G_GET(x)                                   (((x) & 0x00000200) >> 9)
-#define PHY_ANALOG_RXRF_GAINSTAGES_PWD_MXR5G_SET(x)                                   (((x) << 9) & 0x00000200)
-#define PHY_ANALOG_RXRF_GAINSTAGES_PWD_LNA5G_MSB                                                             10
-#define PHY_ANALOG_RXRF_GAINSTAGES_PWD_LNA5G_LSB                                                             10
-#define PHY_ANALOG_RXRF_GAINSTAGES_PWD_LNA5G_MASK                                                    0x00000400
-#define PHY_ANALOG_RXRF_GAINSTAGES_PWD_LNA5G_GET(x)                                  (((x) & 0x00000400) >> 10)
-#define PHY_ANALOG_RXRF_GAINSTAGES_PWD_LNA5G_SET(x)                                  (((x) << 10) & 0x00000400)
-#define PHY_ANALOG_RXRF_GAINSTAGES_LNA2G_CAP_MSB                                                             12
-#define PHY_ANALOG_RXRF_GAINSTAGES_LNA2G_CAP_LSB                                                             11
-#define PHY_ANALOG_RXRF_GAINSTAGES_LNA2G_CAP_MASK                                                    0x00001800
-#define PHY_ANALOG_RXRF_GAINSTAGES_LNA2G_CAP_GET(x)                                  (((x) & 0x00001800) >> 11)
-#define PHY_ANALOG_RXRF_GAINSTAGES_LNA2G_CAP_SET(x)                                  (((x) << 11) & 0x00001800)
-#define PHY_ANALOG_RXRF_GAINSTAGES_LNA2G_SHORTINP_MSB                                                        13
-#define PHY_ANALOG_RXRF_GAINSTAGES_LNA2G_SHORTINP_LSB                                                        13
-#define PHY_ANALOG_RXRF_GAINSTAGES_LNA2G_SHORTINP_MASK                                               0x00002000
-#define PHY_ANALOG_RXRF_GAINSTAGES_LNA2G_SHORTINP_GET(x)                             (((x) & 0x00002000) >> 13)
-#define PHY_ANALOG_RXRF_GAINSTAGES_LNA2G_SHORTINP_SET(x)                             (((x) << 13) & 0x00002000)
-#define PHY_ANALOG_RXRF_GAINSTAGES_LNA2G_LP_MSB                                                              14
-#define PHY_ANALOG_RXRF_GAINSTAGES_LNA2G_LP_LSB                                                              14
-#define PHY_ANALOG_RXRF_GAINSTAGES_LNA2G_LP_MASK                                                     0x00004000
-#define PHY_ANALOG_RXRF_GAINSTAGES_LNA2G_LP_GET(x)                                   (((x) & 0x00004000) >> 14)
-#define PHY_ANALOG_RXRF_GAINSTAGES_LNA2G_LP_SET(x)                                   (((x) << 14) & 0x00004000)
-#define PHY_ANALOG_RXRF_GAINSTAGES_PWD_LO2G_MSB                                                              15
-#define PHY_ANALOG_RXRF_GAINSTAGES_PWD_LO2G_LSB                                                              15
-#define PHY_ANALOG_RXRF_GAINSTAGES_PWD_LO2G_MASK                                                     0x00008000
-#define PHY_ANALOG_RXRF_GAINSTAGES_PWD_LO2G_GET(x)                                   (((x) & 0x00008000) >> 15)
-#define PHY_ANALOG_RXRF_GAINSTAGES_PWD_LO2G_SET(x)                                   (((x) << 15) & 0x00008000)
-#define PHY_ANALOG_RXRF_GAINSTAGES_PWD_MXR2G_MSB                                                             16
-#define PHY_ANALOG_RXRF_GAINSTAGES_PWD_MXR2G_LSB                                                             16
-#define PHY_ANALOG_RXRF_GAINSTAGES_PWD_MXR2G_MASK                                                    0x00010000
-#define PHY_ANALOG_RXRF_GAINSTAGES_PWD_MXR2G_GET(x)                                  (((x) & 0x00010000) >> 16)
-#define PHY_ANALOG_RXRF_GAINSTAGES_PWD_MXR2G_SET(x)                                  (((x) << 16) & 0x00010000)
-#define PHY_ANALOG_RXRF_GAINSTAGES_PWD_LNA2G_MSB                                                             17
-#define PHY_ANALOG_RXRF_GAINSTAGES_PWD_LNA2G_LSB                                                             17
-#define PHY_ANALOG_RXRF_GAINSTAGES_PWD_LNA2G_MASK                                                    0x00020000
-#define PHY_ANALOG_RXRF_GAINSTAGES_PWD_LNA2G_GET(x)                                  (((x) & 0x00020000) >> 17)
-#define PHY_ANALOG_RXRF_GAINSTAGES_PWD_LNA2G_SET(x)                                  (((x) << 17) & 0x00020000)
-#define PHY_ANALOG_RXRF_GAINSTAGES_MXR5G_GAIN_OVR_MSB                                                        19
-#define PHY_ANALOG_RXRF_GAINSTAGES_MXR5G_GAIN_OVR_LSB                                                        18
-#define PHY_ANALOG_RXRF_GAINSTAGES_MXR5G_GAIN_OVR_MASK                                               0x000c0000
-#define PHY_ANALOG_RXRF_GAINSTAGES_MXR5G_GAIN_OVR_GET(x)                             (((x) & 0x000c0000) >> 18)
-#define PHY_ANALOG_RXRF_GAINSTAGES_MXR5G_GAIN_OVR_SET(x)                             (((x) << 18) & 0x000c0000)
-#define PHY_ANALOG_RXRF_GAINSTAGES_VGA5G_GAIN_OVR_MSB                                                        22
-#define PHY_ANALOG_RXRF_GAINSTAGES_VGA5G_GAIN_OVR_LSB                                                        20
-#define PHY_ANALOG_RXRF_GAINSTAGES_VGA5G_GAIN_OVR_MASK                                               0x00700000
-#define PHY_ANALOG_RXRF_GAINSTAGES_VGA5G_GAIN_OVR_GET(x)                             (((x) & 0x00700000) >> 20)
-#define PHY_ANALOG_RXRF_GAINSTAGES_VGA5G_GAIN_OVR_SET(x)                             (((x) << 20) & 0x00700000)
-#define PHY_ANALOG_RXRF_GAINSTAGES_LNA5G_GAIN_OVR_MSB                                                        25
-#define PHY_ANALOG_RXRF_GAINSTAGES_LNA5G_GAIN_OVR_LSB                                                        23
-#define PHY_ANALOG_RXRF_GAINSTAGES_LNA5G_GAIN_OVR_MASK                                               0x03800000
-#define PHY_ANALOG_RXRF_GAINSTAGES_LNA5G_GAIN_OVR_GET(x)                             (((x) & 0x03800000) >> 23)
-#define PHY_ANALOG_RXRF_GAINSTAGES_LNA5G_GAIN_OVR_SET(x)                             (((x) << 23) & 0x03800000)
-#define PHY_ANALOG_RXRF_GAINSTAGES_MXR2G_GAIN_OVR_MSB                                                        27
-#define PHY_ANALOG_RXRF_GAINSTAGES_MXR2G_GAIN_OVR_LSB                                                        26
-#define PHY_ANALOG_RXRF_GAINSTAGES_MXR2G_GAIN_OVR_MASK                                               0x0c000000
-#define PHY_ANALOG_RXRF_GAINSTAGES_MXR2G_GAIN_OVR_GET(x)                             (((x) & 0x0c000000) >> 26)
-#define PHY_ANALOG_RXRF_GAINSTAGES_MXR2G_GAIN_OVR_SET(x)                             (((x) << 26) & 0x0c000000)
-#define PHY_ANALOG_RXRF_GAINSTAGES_LNA2G_GAIN_OVR_MSB                                                        30
-#define PHY_ANALOG_RXRF_GAINSTAGES_LNA2G_GAIN_OVR_LSB                                                        28
-#define PHY_ANALOG_RXRF_GAINSTAGES_LNA2G_GAIN_OVR_MASK                                               0x70000000
-#define PHY_ANALOG_RXRF_GAINSTAGES_LNA2G_GAIN_OVR_GET(x)                             (((x) & 0x70000000) >> 28)
-#define PHY_ANALOG_RXRF_GAINSTAGES_LNA2G_GAIN_OVR_SET(x)                             (((x) << 28) & 0x70000000)
-#define PHY_ANALOG_RXRF_GAINSTAGES_RX_OVERRIDE_MSB                                                           31
-#define PHY_ANALOG_RXRF_GAINSTAGES_RX_OVERRIDE_LSB                                                           31
-#define PHY_ANALOG_RXRF_GAINSTAGES_RX_OVERRIDE_MASK                                                  0x80000000
-#define PHY_ANALOG_RXRF_GAINSTAGES_RX_OVERRIDE_GET(x)                                (((x) & 0x80000000) >> 31)
-#define PHY_ANALOG_RXRF_GAINSTAGES_RX_OVERRIDE_SET(x)                                (((x) << 31) & 0x80000000)
-
-/* macros for RXRF_AGC */
-#define PHY_ANALOG_RXRF_AGC_ADDRESS                                                                  0x0000000c
-#define PHY_ANALOG_RXRF_AGC_OFFSET                                                                   0x0000000c
-#define PHY_ANALOG_RXRF_AGC_RF5G_ON_DURING_CALPA_MSB                                                          0
-#define PHY_ANALOG_RXRF_AGC_RF5G_ON_DURING_CALPA_LSB                                                          0
-#define PHY_ANALOG_RXRF_AGC_RF5G_ON_DURING_CALPA_MASK                                                0x00000001
-#define PHY_ANALOG_RXRF_AGC_RF5G_ON_DURING_CALPA_GET(x)                               (((x) & 0x00000001) >> 0)
-#define PHY_ANALOG_RXRF_AGC_RF5G_ON_DURING_CALPA_SET(x)                               (((x) << 0) & 0x00000001)
-#define PHY_ANALOG_RXRF_AGC_RF2G_ON_DURING_CALPA_MSB                                                          1
-#define PHY_ANALOG_RXRF_AGC_RF2G_ON_DURING_CALPA_LSB                                                          1
-#define PHY_ANALOG_RXRF_AGC_RF2G_ON_DURING_CALPA_MASK                                                0x00000002
-#define PHY_ANALOG_RXRF_AGC_RF2G_ON_DURING_CALPA_GET(x)                               (((x) & 0x00000002) >> 1)
-#define PHY_ANALOG_RXRF_AGC_RF2G_ON_DURING_CALPA_SET(x)                               (((x) << 1) & 0x00000002)
-#define PHY_ANALOG_RXRF_AGC_AGC_OUT_MSB                                                                       2
-#define PHY_ANALOG_RXRF_AGC_AGC_OUT_LSB                                                                       2
-#define PHY_ANALOG_RXRF_AGC_AGC_OUT_MASK                                                             0x00000004
-#define PHY_ANALOG_RXRF_AGC_AGC_OUT_GET(x)                                            (((x) & 0x00000004) >> 2)
-#define PHY_ANALOG_RXRF_AGC_LNABUFGAIN2X_MSB                                                                  3
-#define PHY_ANALOG_RXRF_AGC_LNABUFGAIN2X_LSB                                                                  3
-#define PHY_ANALOG_RXRF_AGC_LNABUFGAIN2X_MASK                                                        0x00000008
-#define PHY_ANALOG_RXRF_AGC_LNABUFGAIN2X_GET(x)                                       (((x) & 0x00000008) >> 3)
-#define PHY_ANALOG_RXRF_AGC_LNABUFGAIN2X_SET(x)                                       (((x) << 3) & 0x00000008)
-#define PHY_ANALOG_RXRF_AGC_LNABUF_PWD_OVR_MSB                                                                4
-#define PHY_ANALOG_RXRF_AGC_LNABUF_PWD_OVR_LSB                                                                4
-#define PHY_ANALOG_RXRF_AGC_LNABUF_PWD_OVR_MASK                                                      0x00000010
-#define PHY_ANALOG_RXRF_AGC_LNABUF_PWD_OVR_GET(x)                                     (((x) & 0x00000010) >> 4)
-#define PHY_ANALOG_RXRF_AGC_LNABUF_PWD_OVR_SET(x)                                     (((x) << 4) & 0x00000010)
-#define PHY_ANALOG_RXRF_AGC_PWD_LNABUF_MSB                                                                    5
-#define PHY_ANALOG_RXRF_AGC_PWD_LNABUF_LSB                                                                    5
-#define PHY_ANALOG_RXRF_AGC_PWD_LNABUF_MASK                                                          0x00000020
-#define PHY_ANALOG_RXRF_AGC_PWD_LNABUF_GET(x)                                         (((x) & 0x00000020) >> 5)
-#define PHY_ANALOG_RXRF_AGC_PWD_LNABUF_SET(x)                                         (((x) << 5) & 0x00000020)
-#define PHY_ANALOG_RXRF_AGC_AGC_FALL_CTRL_MSB                                                                 8
-#define PHY_ANALOG_RXRF_AGC_AGC_FALL_CTRL_LSB                                                                 6
-#define PHY_ANALOG_RXRF_AGC_AGC_FALL_CTRL_MASK                                                       0x000001c0
-#define PHY_ANALOG_RXRF_AGC_AGC_FALL_CTRL_GET(x)                                      (((x) & 0x000001c0) >> 6)
-#define PHY_ANALOG_RXRF_AGC_AGC_FALL_CTRL_SET(x)                                      (((x) << 6) & 0x000001c0)
-#define PHY_ANALOG_RXRF_AGC_AGC5G_CALDAC_OVR_MSB                                                             14
-#define PHY_ANALOG_RXRF_AGC_AGC5G_CALDAC_OVR_LSB                                                              9
-#define PHY_ANALOG_RXRF_AGC_AGC5G_CALDAC_OVR_MASK                                                    0x00007e00
-#define PHY_ANALOG_RXRF_AGC_AGC5G_CALDAC_OVR_GET(x)                                   (((x) & 0x00007e00) >> 9)
-#define PHY_ANALOG_RXRF_AGC_AGC5G_CALDAC_OVR_SET(x)                                   (((x) << 9) & 0x00007e00)
-#define PHY_ANALOG_RXRF_AGC_AGC5G_DBDAC_OVR_MSB                                                              18
-#define PHY_ANALOG_RXRF_AGC_AGC5G_DBDAC_OVR_LSB                                                              15
-#define PHY_ANALOG_RXRF_AGC_AGC5G_DBDAC_OVR_MASK                                                     0x00078000
-#define PHY_ANALOG_RXRF_AGC_AGC5G_DBDAC_OVR_GET(x)                                   (((x) & 0x00078000) >> 15)
-#define PHY_ANALOG_RXRF_AGC_AGC5G_DBDAC_OVR_SET(x)                                   (((x) << 15) & 0x00078000)
-#define PHY_ANALOG_RXRF_AGC_AGC2G_CALDAC_OVR_MSB                                                             24
-#define PHY_ANALOG_RXRF_AGC_AGC2G_CALDAC_OVR_LSB                                                             19
-#define PHY_ANALOG_RXRF_AGC_AGC2G_CALDAC_OVR_MASK                                                    0x01f80000
-#define PHY_ANALOG_RXRF_AGC_AGC2G_CALDAC_OVR_GET(x)                                  (((x) & 0x01f80000) >> 19)
-#define PHY_ANALOG_RXRF_AGC_AGC2G_CALDAC_OVR_SET(x)                                  (((x) << 19) & 0x01f80000)
-#define PHY_ANALOG_RXRF_AGC_AGC2G_DBDAC_OVR_MSB                                                              28
-#define PHY_ANALOG_RXRF_AGC_AGC2G_DBDAC_OVR_LSB                                                              25
-#define PHY_ANALOG_RXRF_AGC_AGC2G_DBDAC_OVR_MASK                                                     0x1e000000
-#define PHY_ANALOG_RXRF_AGC_AGC2G_DBDAC_OVR_GET(x)                                   (((x) & 0x1e000000) >> 25)
-#define PHY_ANALOG_RXRF_AGC_AGC2G_DBDAC_OVR_SET(x)                                   (((x) << 25) & 0x1e000000)
-#define PHY_ANALOG_RXRF_AGC_AGC_CAL_OVR_MSB                                                                  29
-#define PHY_ANALOG_RXRF_AGC_AGC_CAL_OVR_LSB                                                                  29
-#define PHY_ANALOG_RXRF_AGC_AGC_CAL_OVR_MASK                                                         0x20000000
-#define PHY_ANALOG_RXRF_AGC_AGC_CAL_OVR_GET(x)                                       (((x) & 0x20000000) >> 29)
-#define PHY_ANALOG_RXRF_AGC_AGC_CAL_OVR_SET(x)                                       (((x) << 29) & 0x20000000)
-#define PHY_ANALOG_RXRF_AGC_AGC_ON_OVR_MSB                                                                   30
-#define PHY_ANALOG_RXRF_AGC_AGC_ON_OVR_LSB                                                                   30
-#define PHY_ANALOG_RXRF_AGC_AGC_ON_OVR_MASK                                                          0x40000000
-#define PHY_ANALOG_RXRF_AGC_AGC_ON_OVR_GET(x)                                        (((x) & 0x40000000) >> 30)
-#define PHY_ANALOG_RXRF_AGC_AGC_ON_OVR_SET(x)                                        (((x) << 30) & 0x40000000)
-#define PHY_ANALOG_RXRF_AGC_AGC_OVERRIDE_MSB                                                                 31
-#define PHY_ANALOG_RXRF_AGC_AGC_OVERRIDE_LSB                                                                 31
-#define PHY_ANALOG_RXRF_AGC_AGC_OVERRIDE_MASK                                                        0x80000000
-#define PHY_ANALOG_RXRF_AGC_AGC_OVERRIDE_GET(x)                                      (((x) & 0x80000000) >> 31)
-#define PHY_ANALOG_RXRF_AGC_AGC_OVERRIDE_SET(x)                                      (((x) << 31) & 0x80000000)
-
-/* macros for TXRF1 */
-#define PHY_ANALOG_TXRF1_ADDRESS                                                                     0x00000040
-#define PHY_ANALOG_TXRF1_OFFSET                                                                      0x00000040
-#define PHY_ANALOG_TXRF1_PDLOBUF5G_MSB                                                                        0
-#define PHY_ANALOG_TXRF1_PDLOBUF5G_LSB                                                                        0
-#define PHY_ANALOG_TXRF1_PDLOBUF5G_MASK                                                              0x00000001
-#define PHY_ANALOG_TXRF1_PDLOBUF5G_GET(x)                                             (((x) & 0x00000001) >> 0)
-#define PHY_ANALOG_TXRF1_PDLOBUF5G_SET(x)                                             (((x) << 0) & 0x00000001)
-#define PHY_ANALOG_TXRF1_PDLODIV5G_MSB                                                                        1
-#define PHY_ANALOG_TXRF1_PDLODIV5G_LSB                                                                        1
-#define PHY_ANALOG_TXRF1_PDLODIV5G_MASK                                                              0x00000002
-#define PHY_ANALOG_TXRF1_PDLODIV5G_GET(x)                                             (((x) & 0x00000002) >> 1)
-#define PHY_ANALOG_TXRF1_PDLODIV5G_SET(x)                                             (((x) << 1) & 0x00000002)
-#define PHY_ANALOG_TXRF1_LOBUF5GFORCED_MSB                                                                    2
-#define PHY_ANALOG_TXRF1_LOBUF5GFORCED_LSB                                                                    2
-#define PHY_ANALOG_TXRF1_LOBUF5GFORCED_MASK                                                          0x00000004
-#define PHY_ANALOG_TXRF1_LOBUF5GFORCED_GET(x)                                         (((x) & 0x00000004) >> 2)
-#define PHY_ANALOG_TXRF1_LOBUF5GFORCED_SET(x)                                         (((x) << 2) & 0x00000004)
-#define PHY_ANALOG_TXRF1_LODIV5GFORCED_MSB                                                                    3
-#define PHY_ANALOG_TXRF1_LODIV5GFORCED_LSB                                                                    3
-#define PHY_ANALOG_TXRF1_LODIV5GFORCED_MASK                                                          0x00000008
-#define PHY_ANALOG_TXRF1_LODIV5GFORCED_GET(x)                                         (((x) & 0x00000008) >> 3)
-#define PHY_ANALOG_TXRF1_LODIV5GFORCED_SET(x)                                         (((x) << 3) & 0x00000008)
-#define PHY_ANALOG_TXRF1_PADRV2GN5G_MSB                                                                       7
-#define PHY_ANALOG_TXRF1_PADRV2GN5G_LSB                                                                       4
-#define PHY_ANALOG_TXRF1_PADRV2GN5G_MASK                                                             0x000000f0
-#define PHY_ANALOG_TXRF1_PADRV2GN5G_GET(x)                                            (((x) & 0x000000f0) >> 4)
-#define PHY_ANALOG_TXRF1_PADRV2GN5G_SET(x)                                            (((x) << 4) & 0x000000f0)
-#define PHY_ANALOG_TXRF1_PADRV3GN5G_MSB                                                                      11
-#define PHY_ANALOG_TXRF1_PADRV3GN5G_LSB                                                                       8
-#define PHY_ANALOG_TXRF1_PADRV3GN5G_MASK                                                             0x00000f00
-#define PHY_ANALOG_TXRF1_PADRV3GN5G_GET(x)                                            (((x) & 0x00000f00) >> 8)
-#define PHY_ANALOG_TXRF1_PADRV3GN5G_SET(x)                                            (((x) << 8) & 0x00000f00)
-#define PHY_ANALOG_TXRF1_PADRV4GN5G_MSB                                                                      15
-#define PHY_ANALOG_TXRF1_PADRV4GN5G_LSB                                                                      12
-#define PHY_ANALOG_TXRF1_PADRV4GN5G_MASK                                                             0x0000f000
-#define PHY_ANALOG_TXRF1_PADRV4GN5G_GET(x)                                           (((x) & 0x0000f000) >> 12)
-#define PHY_ANALOG_TXRF1_PADRV4GN5G_SET(x)                                           (((x) << 12) & 0x0000f000)
-#define PHY_ANALOG_TXRF1_LOCALTXGAIN5G_MSB                                                                   16
-#define PHY_ANALOG_TXRF1_LOCALTXGAIN5G_LSB                                                                   16
-#define PHY_ANALOG_TXRF1_LOCALTXGAIN5G_MASK                                                          0x00010000
-#define PHY_ANALOG_TXRF1_LOCALTXGAIN5G_GET(x)                                        (((x) & 0x00010000) >> 16)
-#define PHY_ANALOG_TXRF1_LOCALTXGAIN5G_SET(x)                                        (((x) << 16) & 0x00010000)
-#define PHY_ANALOG_TXRF1_PDOUT2G_MSB                                                                         17
-#define PHY_ANALOG_TXRF1_PDOUT2G_LSB                                                                         17
-#define PHY_ANALOG_TXRF1_PDOUT2G_MASK                                                                0x00020000
-#define PHY_ANALOG_TXRF1_PDOUT2G_GET(x)                                              (((x) & 0x00020000) >> 17)
-#define PHY_ANALOG_TXRF1_PDOUT2G_SET(x)                                              (((x) << 17) & 0x00020000)
-#define PHY_ANALOG_TXRF1_PDDR2G_MSB                                                                          18
-#define PHY_ANALOG_TXRF1_PDDR2G_LSB                                                                          18
-#define PHY_ANALOG_TXRF1_PDDR2G_MASK                                                                 0x00040000
-#define PHY_ANALOG_TXRF1_PDDR2G_GET(x)                                               (((x) & 0x00040000) >> 18)
-#define PHY_ANALOG_TXRF1_PDDR2G_SET(x)                                               (((x) << 18) & 0x00040000)
-#define PHY_ANALOG_TXRF1_PDMXR2G_MSB                                                                         19
-#define PHY_ANALOG_TXRF1_PDMXR2G_LSB                                                                         19
-#define PHY_ANALOG_TXRF1_PDMXR2G_MASK                                                                0x00080000
-#define PHY_ANALOG_TXRF1_PDMXR2G_GET(x)                                              (((x) & 0x00080000) >> 19)
-#define PHY_ANALOG_TXRF1_PDMXR2G_SET(x)                                              (((x) << 19) & 0x00080000)
-#define PHY_ANALOG_TXRF1_PDLOBUF2G_MSB                                                                       20
-#define PHY_ANALOG_TXRF1_PDLOBUF2G_LSB                                                                       20
-#define PHY_ANALOG_TXRF1_PDLOBUF2G_MASK                                                              0x00100000
-#define PHY_ANALOG_TXRF1_PDLOBUF2G_GET(x)                                            (((x) & 0x00100000) >> 20)
-#define PHY_ANALOG_TXRF1_PDLOBUF2G_SET(x)                                            (((x) << 20) & 0x00100000)
-#define PHY_ANALOG_TXRF1_PDLODIV2G_MSB                                                                       21
-#define PHY_ANALOG_TXRF1_PDLODIV2G_LSB                                                                       21
-#define PHY_ANALOG_TXRF1_PDLODIV2G_MASK                                                              0x00200000
-#define PHY_ANALOG_TXRF1_PDLODIV2G_GET(x)                                            (((x) & 0x00200000) >> 21)
-#define PHY_ANALOG_TXRF1_PDLODIV2G_SET(x)                                            (((x) << 21) & 0x00200000)
-#define PHY_ANALOG_TXRF1_LOBUF2GFORCED_MSB                                                                   22
-#define PHY_ANALOG_TXRF1_LOBUF2GFORCED_LSB                                                                   22
-#define PHY_ANALOG_TXRF1_LOBUF2GFORCED_MASK                                                          0x00400000
-#define PHY_ANALOG_TXRF1_LOBUF2GFORCED_GET(x)                                        (((x) & 0x00400000) >> 22)
-#define PHY_ANALOG_TXRF1_LOBUF2GFORCED_SET(x)                                        (((x) << 22) & 0x00400000)
-#define PHY_ANALOG_TXRF1_LODIV2GFORCED_MSB                                                                   23
-#define PHY_ANALOG_TXRF1_LODIV2GFORCED_LSB                                                                   23
-#define PHY_ANALOG_TXRF1_LODIV2GFORCED_MASK                                                          0x00800000
-#define PHY_ANALOG_TXRF1_LODIV2GFORCED_GET(x)                                        (((x) & 0x00800000) >> 23)
-#define PHY_ANALOG_TXRF1_LODIV2GFORCED_SET(x)                                        (((x) << 23) & 0x00800000)
-#define PHY_ANALOG_TXRF1_PADRVGN2G_MSB                                                                       30
-#define PHY_ANALOG_TXRF1_PADRVGN2G_LSB                                                                       24
-#define PHY_ANALOG_TXRF1_PADRVGN2G_MASK                                                              0x7f000000
-#define PHY_ANALOG_TXRF1_PADRVGN2G_GET(x)                                            (((x) & 0x7f000000) >> 24)
-#define PHY_ANALOG_TXRF1_PADRVGN2G_SET(x)                                            (((x) << 24) & 0x7f000000)
-#define PHY_ANALOG_TXRF1_LOCALTXGAIN2G_MSB                                                                   31
-#define PHY_ANALOG_TXRF1_LOCALTXGAIN2G_LSB                                                                   31
-#define PHY_ANALOG_TXRF1_LOCALTXGAIN2G_MASK                                                          0x80000000
-#define PHY_ANALOG_TXRF1_LOCALTXGAIN2G_GET(x)                                        (((x) & 0x80000000) >> 31)
-#define PHY_ANALOG_TXRF1_LOCALTXGAIN2G_SET(x)                                        (((x) << 31) & 0x80000000)
-
-/* macros for TXRF2 */
-#define PHY_ANALOG_TXRF2_ADDRESS                                                                     0x00000044
-#define PHY_ANALOG_TXRF2_OFFSET                                                                      0x00000044
-#define PHY_ANALOG_TXRF2_D3B5G_MSB                                                                            2
-#define PHY_ANALOG_TXRF2_D3B5G_LSB                                                                            0
-#define PHY_ANALOG_TXRF2_D3B5G_MASK                                                                  0x00000007
-#define PHY_ANALOG_TXRF2_D3B5G_GET(x)                                                 (((x) & 0x00000007) >> 0)
-#define PHY_ANALOG_TXRF2_D3B5G_SET(x)                                                 (((x) << 0) & 0x00000007)
-#define PHY_ANALOG_TXRF2_D4B5G_MSB                                                                            5
-#define PHY_ANALOG_TXRF2_D4B5G_LSB                                                                            3
-#define PHY_ANALOG_TXRF2_D4B5G_MASK                                                                  0x00000038
-#define PHY_ANALOG_TXRF2_D4B5G_GET(x)                                                 (((x) & 0x00000038) >> 3)
-#define PHY_ANALOG_TXRF2_D4B5G_SET(x)                                                 (((x) << 3) & 0x00000038)
-#define PHY_ANALOG_TXRF2_OCAS2G_MSB                                                                           8
-#define PHY_ANALOG_TXRF2_OCAS2G_LSB                                                                           6
-#define PHY_ANALOG_TXRF2_OCAS2G_MASK                                                                 0x000001c0
-#define PHY_ANALOG_TXRF2_OCAS2G_GET(x)                                                (((x) & 0x000001c0) >> 6)
-#define PHY_ANALOG_TXRF2_OCAS2G_SET(x)                                                (((x) << 6) & 0x000001c0)
-#define PHY_ANALOG_TXRF2_DCAS2G_MSB                                                                          11
-#define PHY_ANALOG_TXRF2_DCAS2G_LSB                                                                           9
-#define PHY_ANALOG_TXRF2_DCAS2G_MASK                                                                 0x00000e00
-#define PHY_ANALOG_TXRF2_DCAS2G_GET(x)                                                (((x) & 0x00000e00) >> 9)
-#define PHY_ANALOG_TXRF2_DCAS2G_SET(x)                                                (((x) << 9) & 0x00000e00)
-#define PHY_ANALOG_TXRF2_OB2G_PALOFF_MSB                                                                     14
-#define PHY_ANALOG_TXRF2_OB2G_PALOFF_LSB                                                                     12
-#define PHY_ANALOG_TXRF2_OB2G_PALOFF_MASK                                                            0x00007000
-#define PHY_ANALOG_TXRF2_OB2G_PALOFF_GET(x)                                          (((x) & 0x00007000) >> 12)
-#define PHY_ANALOG_TXRF2_OB2G_PALOFF_SET(x)                                          (((x) << 12) & 0x00007000)
-#define PHY_ANALOG_TXRF2_OB2G_QAM_MSB                                                                        17
-#define PHY_ANALOG_TXRF2_OB2G_QAM_LSB                                                                        15
-#define PHY_ANALOG_TXRF2_OB2G_QAM_MASK                                                               0x00038000
-#define PHY_ANALOG_TXRF2_OB2G_QAM_GET(x)                                             (((x) & 0x00038000) >> 15)
-#define PHY_ANALOG_TXRF2_OB2G_QAM_SET(x)                                             (((x) << 15) & 0x00038000)
-#define PHY_ANALOG_TXRF2_OB2G_PSK_MSB                                                                        20
-#define PHY_ANALOG_TXRF2_OB2G_PSK_LSB                                                                        18
-#define PHY_ANALOG_TXRF2_OB2G_PSK_MASK                                                               0x001c0000
-#define PHY_ANALOG_TXRF2_OB2G_PSK_GET(x)                                             (((x) & 0x001c0000) >> 18)
-#define PHY_ANALOG_TXRF2_OB2G_PSK_SET(x)                                             (((x) << 18) & 0x001c0000)
-#define PHY_ANALOG_TXRF2_OB2G_CCK_MSB                                                                        23
-#define PHY_ANALOG_TXRF2_OB2G_CCK_LSB                                                                        21
-#define PHY_ANALOG_TXRF2_OB2G_CCK_MASK                                                               0x00e00000
-#define PHY_ANALOG_TXRF2_OB2G_CCK_GET(x)                                             (((x) & 0x00e00000) >> 21)
-#define PHY_ANALOG_TXRF2_OB2G_CCK_SET(x)                                             (((x) << 21) & 0x00e00000)
-#define PHY_ANALOG_TXRF2_DB2G_MSB                                                                            26
-#define PHY_ANALOG_TXRF2_DB2G_LSB                                                                            24
-#define PHY_ANALOG_TXRF2_DB2G_MASK                                                                   0x07000000
-#define PHY_ANALOG_TXRF2_DB2G_GET(x)                                                 (((x) & 0x07000000) >> 24)
-#define PHY_ANALOG_TXRF2_DB2G_SET(x)                                                 (((x) << 24) & 0x07000000)
-#define PHY_ANALOG_TXRF2_PDOUT5G_MSB                                                                         30
-#define PHY_ANALOG_TXRF2_PDOUT5G_LSB                                                                         27
-#define PHY_ANALOG_TXRF2_PDOUT5G_MASK                                                                0x78000000
-#define PHY_ANALOG_TXRF2_PDOUT5G_GET(x)                                              (((x) & 0x78000000) >> 27)
-#define PHY_ANALOG_TXRF2_PDOUT5G_SET(x)                                              (((x) << 27) & 0x78000000)
-#define PHY_ANALOG_TXRF2_PDMXR5G_MSB                                                                         31
-#define PHY_ANALOG_TXRF2_PDMXR5G_LSB                                                                         31
-#define PHY_ANALOG_TXRF2_PDMXR5G_MASK                                                                0x80000000
-#define PHY_ANALOG_TXRF2_PDMXR5G_GET(x)                                              (((x) & 0x80000000) >> 31)
-#define PHY_ANALOG_TXRF2_PDMXR5G_SET(x)                                              (((x) << 31) & 0x80000000)
-
-/* macros for TXRF3 */
-#define PHY_ANALOG_TXRF3_ADDRESS                                                                     0x00000048
-#define PHY_ANALOG_TXRF3_OFFSET                                                                      0x00000048
-#define PHY_ANALOG_TXRF3_FILTR2G_MSB                                                                          1
-#define PHY_ANALOG_TXRF3_FILTR2G_LSB                                                                          0
-#define PHY_ANALOG_TXRF3_FILTR2G_MASK                                                                0x00000003
-#define PHY_ANALOG_TXRF3_FILTR2G_GET(x)                                               (((x) & 0x00000003) >> 0)
-#define PHY_ANALOG_TXRF3_FILTR2G_SET(x)                                               (((x) << 0) & 0x00000003)
-#define PHY_ANALOG_TXRF3_PWDFB2_2G_MSB                                                                        2
-#define PHY_ANALOG_TXRF3_PWDFB2_2G_LSB                                                                        2
-#define PHY_ANALOG_TXRF3_PWDFB2_2G_MASK                                                              0x00000004
-#define PHY_ANALOG_TXRF3_PWDFB2_2G_GET(x)                                             (((x) & 0x00000004) >> 2)
-#define PHY_ANALOG_TXRF3_PWDFB2_2G_SET(x)                                             (((x) << 2) & 0x00000004)
-#define PHY_ANALOG_TXRF3_PWDFB1_2G_MSB                                                                        3
-#define PHY_ANALOG_TXRF3_PWDFB1_2G_LSB                                                                        3
-#define PHY_ANALOG_TXRF3_PWDFB1_2G_MASK                                                              0x00000008
-#define PHY_ANALOG_TXRF3_PWDFB1_2G_GET(x)                                             (((x) & 0x00000008) >> 3)
-#define PHY_ANALOG_TXRF3_PWDFB1_2G_SET(x)                                             (((x) << 3) & 0x00000008)
-#define PHY_ANALOG_TXRF3_PDFB2G_MSB                                                                           4
-#define PHY_ANALOG_TXRF3_PDFB2G_LSB                                                                           4
-#define PHY_ANALOG_TXRF3_PDFB2G_MASK                                                                 0x00000010
-#define PHY_ANALOG_TXRF3_PDFB2G_GET(x)                                                (((x) & 0x00000010) >> 4)
-#define PHY_ANALOG_TXRF3_PDFB2G_SET(x)                                                (((x) << 4) & 0x00000010)
-#define PHY_ANALOG_TXRF3_RDIV5G_MSB                                                                           6
-#define PHY_ANALOG_TXRF3_RDIV5G_LSB                                                                           5
-#define PHY_ANALOG_TXRF3_RDIV5G_MASK                                                                 0x00000060
-#define PHY_ANALOG_TXRF3_RDIV5G_GET(x)                                                (((x) & 0x00000060) >> 5)
-#define PHY_ANALOG_TXRF3_RDIV5G_SET(x)                                                (((x) << 5) & 0x00000060)
-#define PHY_ANALOG_TXRF3_CAPDIV5G_MSB                                                                         9
-#define PHY_ANALOG_TXRF3_CAPDIV5G_LSB                                                                         7
-#define PHY_ANALOG_TXRF3_CAPDIV5G_MASK                                                               0x00000380
-#define PHY_ANALOG_TXRF3_CAPDIV5G_GET(x)                                              (((x) & 0x00000380) >> 7)
-#define PHY_ANALOG_TXRF3_CAPDIV5G_SET(x)                                              (((x) << 7) & 0x00000380)
-#define PHY_ANALOG_TXRF3_PDPREDIST5G_MSB                                                                     10
-#define PHY_ANALOG_TXRF3_PDPREDIST5G_LSB                                                                     10
-#define PHY_ANALOG_TXRF3_PDPREDIST5G_MASK                                                            0x00000400
-#define PHY_ANALOG_TXRF3_PDPREDIST5G_GET(x)                                          (((x) & 0x00000400) >> 10)
-#define PHY_ANALOG_TXRF3_PDPREDIST5G_SET(x)                                          (((x) << 10) & 0x00000400)
-#define PHY_ANALOG_TXRF3_RDIV2G_MSB                                                                          12
-#define PHY_ANALOG_TXRF3_RDIV2G_LSB                                                                          11
-#define PHY_ANALOG_TXRF3_RDIV2G_MASK                                                                 0x00001800
-#define PHY_ANALOG_TXRF3_RDIV2G_GET(x)                                               (((x) & 0x00001800) >> 11)
-#define PHY_ANALOG_TXRF3_RDIV2G_SET(x)                                               (((x) << 11) & 0x00001800)
-#define PHY_ANALOG_TXRF3_PDPREDIST2G_MSB                                                                     13
-#define PHY_ANALOG_TXRF3_PDPREDIST2G_LSB                                                                     13
-#define PHY_ANALOG_TXRF3_PDPREDIST2G_MASK                                                            0x00002000
-#define PHY_ANALOG_TXRF3_PDPREDIST2G_GET(x)                                          (((x) & 0x00002000) >> 13)
-#define PHY_ANALOG_TXRF3_PDPREDIST2G_SET(x)                                          (((x) << 13) & 0x00002000)
-#define PHY_ANALOG_TXRF3_OCAS5G_MSB                                                                          16
-#define PHY_ANALOG_TXRF3_OCAS5G_LSB                                                                          14
-#define PHY_ANALOG_TXRF3_OCAS5G_MASK                                                                 0x0001c000
-#define PHY_ANALOG_TXRF3_OCAS5G_GET(x)                                               (((x) & 0x0001c000) >> 14)
-#define PHY_ANALOG_TXRF3_OCAS5G_SET(x)                                               (((x) << 14) & 0x0001c000)
-#define PHY_ANALOG_TXRF3_D2CAS5G_MSB                                                                         19
-#define PHY_ANALOG_TXRF3_D2CAS5G_LSB                                                                         17
-#define PHY_ANALOG_TXRF3_D2CAS5G_MASK                                                                0x000e0000
-#define PHY_ANALOG_TXRF3_D2CAS5G_GET(x)                                              (((x) & 0x000e0000) >> 17)
-#define PHY_ANALOG_TXRF3_D2CAS5G_SET(x)                                              (((x) << 17) & 0x000e0000)
-#define PHY_ANALOG_TXRF3_D3CAS5G_MSB                                                                         22
-#define PHY_ANALOG_TXRF3_D3CAS5G_LSB                                                                         20
-#define PHY_ANALOG_TXRF3_D3CAS5G_MASK                                                                0x00700000
-#define PHY_ANALOG_TXRF3_D3CAS5G_GET(x)                                              (((x) & 0x00700000) >> 20)
-#define PHY_ANALOG_TXRF3_D3CAS5G_SET(x)                                              (((x) << 20) & 0x00700000)
-#define PHY_ANALOG_TXRF3_D4CAS5G_MSB                                                                         25
-#define PHY_ANALOG_TXRF3_D4CAS5G_LSB                                                                         23
-#define PHY_ANALOG_TXRF3_D4CAS5G_MASK                                                                0x03800000
-#define PHY_ANALOG_TXRF3_D4CAS5G_GET(x)                                              (((x) & 0x03800000) >> 23)
-#define PHY_ANALOG_TXRF3_D4CAS5G_SET(x)                                              (((x) << 23) & 0x03800000)
-#define PHY_ANALOG_TXRF3_OB5G_MSB                                                                            28
-#define PHY_ANALOG_TXRF3_OB5G_LSB                                                                            26
-#define PHY_ANALOG_TXRF3_OB5G_MASK                                                                   0x1c000000
-#define PHY_ANALOG_TXRF3_OB5G_GET(x)                                                 (((x) & 0x1c000000) >> 26)
-#define PHY_ANALOG_TXRF3_OB5G_SET(x)                                                 (((x) << 26) & 0x1c000000)
-#define PHY_ANALOG_TXRF3_D2B5G_MSB                                                                           31
-#define PHY_ANALOG_TXRF3_D2B5G_LSB                                                                           29
-#define PHY_ANALOG_TXRF3_D2B5G_MASK                                                                  0xe0000000
-#define PHY_ANALOG_TXRF3_D2B5G_GET(x)                                                (((x) & 0xe0000000) >> 29)
-#define PHY_ANALOG_TXRF3_D2B5G_SET(x)                                                (((x) << 29) & 0xe0000000)
-
-/* macros for TXRF4 */
-#define PHY_ANALOG_TXRF4_ADDRESS                                                                     0x0000004c
-#define PHY_ANALOG_TXRF4_OFFSET                                                                      0x0000004c
-#define PHY_ANALOG_TXRF4_PK1B2G_CCK_MSB                                                                       1
-#define PHY_ANALOG_TXRF4_PK1B2G_CCK_LSB                                                                       0
-#define PHY_ANALOG_TXRF4_PK1B2G_CCK_MASK                                                             0x00000003
-#define PHY_ANALOG_TXRF4_PK1B2G_CCK_GET(x)                                            (((x) & 0x00000003) >> 0)
-#define PHY_ANALOG_TXRF4_PK1B2G_CCK_SET(x)                                            (((x) << 0) & 0x00000003)
-#define PHY_ANALOG_TXRF4_MIOB2G_QAM_MSB                                                                       4
-#define PHY_ANALOG_TXRF4_MIOB2G_QAM_LSB                                                                       2
-#define PHY_ANALOG_TXRF4_MIOB2G_QAM_MASK                                                             0x0000001c
-#define PHY_ANALOG_TXRF4_MIOB2G_QAM_GET(x)                                            (((x) & 0x0000001c) >> 2)
-#define PHY_ANALOG_TXRF4_MIOB2G_QAM_SET(x)                                            (((x) << 2) & 0x0000001c)
-#define PHY_ANALOG_TXRF4_MIOB2G_PSK_MSB                                                                       7
-#define PHY_ANALOG_TXRF4_MIOB2G_PSK_LSB                                                                       5
-#define PHY_ANALOG_TXRF4_MIOB2G_PSK_MASK                                                             0x000000e0
-#define PHY_ANALOG_TXRF4_MIOB2G_PSK_GET(x)                                            (((x) & 0x000000e0) >> 5)
-#define PHY_ANALOG_TXRF4_MIOB2G_PSK_SET(x)                                            (((x) << 5) & 0x000000e0)
-#define PHY_ANALOG_TXRF4_MIOB2G_CCK_MSB                                                                      10
-#define PHY_ANALOG_TXRF4_MIOB2G_CCK_LSB                                                                       8
-#define PHY_ANALOG_TXRF4_MIOB2G_CCK_MASK                                                             0x00000700
-#define PHY_ANALOG_TXRF4_MIOB2G_CCK_GET(x)                                            (((x) & 0x00000700) >> 8)
-#define PHY_ANALOG_TXRF4_MIOB2G_CCK_SET(x)                                            (((x) << 8) & 0x00000700)
-#define PHY_ANALOG_TXRF4_COMP2G_QAM_MSB                                                                      13
-#define PHY_ANALOG_TXRF4_COMP2G_QAM_LSB                                                                      11
-#define PHY_ANALOG_TXRF4_COMP2G_QAM_MASK                                                             0x00003800
-#define PHY_ANALOG_TXRF4_COMP2G_QAM_GET(x)                                           (((x) & 0x00003800) >> 11)
-#define PHY_ANALOG_TXRF4_COMP2G_QAM_SET(x)                                           (((x) << 11) & 0x00003800)
-#define PHY_ANALOG_TXRF4_COMP2G_PSK_MSB                                                                      16
-#define PHY_ANALOG_TXRF4_COMP2G_PSK_LSB                                                                      14
-#define PHY_ANALOG_TXRF4_COMP2G_PSK_MASK                                                             0x0001c000
-#define PHY_ANALOG_TXRF4_COMP2G_PSK_GET(x)                                           (((x) & 0x0001c000) >> 14)
-#define PHY_ANALOG_TXRF4_COMP2G_PSK_SET(x)                                           (((x) << 14) & 0x0001c000)
-#define PHY_ANALOG_TXRF4_COMP2G_CCK_MSB                                                                      19
-#define PHY_ANALOG_TXRF4_COMP2G_CCK_LSB                                                                      17
-#define PHY_ANALOG_TXRF4_COMP2G_CCK_MASK                                                             0x000e0000
-#define PHY_ANALOG_TXRF4_COMP2G_CCK_GET(x)                                           (((x) & 0x000e0000) >> 17)
-#define PHY_ANALOG_TXRF4_COMP2G_CCK_SET(x)                                           (((x) << 17) & 0x000e0000)
-#define PHY_ANALOG_TXRF4_AMP2B2G_QAM_MSB                                                                     22
-#define PHY_ANALOG_TXRF4_AMP2B2G_QAM_LSB                                                                     20
-#define PHY_ANALOG_TXRF4_AMP2B2G_QAM_MASK                                                            0x00700000
-#define PHY_ANALOG_TXRF4_AMP2B2G_QAM_GET(x)                                          (((x) & 0x00700000) >> 20)
-#define PHY_ANALOG_TXRF4_AMP2B2G_QAM_SET(x)                                          (((x) << 20) & 0x00700000)
-#define PHY_ANALOG_TXRF4_AMP2B2G_PSK_MSB                                                                     25
-#define PHY_ANALOG_TXRF4_AMP2B2G_PSK_LSB                                                                     23
-#define PHY_ANALOG_TXRF4_AMP2B2G_PSK_MASK                                                            0x03800000
-#define PHY_ANALOG_TXRF4_AMP2B2G_PSK_GET(x)                                          (((x) & 0x03800000) >> 23)
-#define PHY_ANALOG_TXRF4_AMP2B2G_PSK_SET(x)                                          (((x) << 23) & 0x03800000)
-#define PHY_ANALOG_TXRF4_AMP2B2G_CCK_MSB                                                                     28
-#define PHY_ANALOG_TXRF4_AMP2B2G_CCK_LSB                                                                     26
-#define PHY_ANALOG_TXRF4_AMP2B2G_CCK_MASK                                                            0x1c000000
-#define PHY_ANALOG_TXRF4_AMP2B2G_CCK_GET(x)                                          (((x) & 0x1c000000) >> 26)
-#define PHY_ANALOG_TXRF4_AMP2B2G_CCK_SET(x)                                          (((x) << 26) & 0x1c000000)
-#define PHY_ANALOG_TXRF4_AMP2CAS2G_MSB                                                                       31
-#define PHY_ANALOG_TXRF4_AMP2CAS2G_LSB                                                                       29
-#define PHY_ANALOG_TXRF4_AMP2CAS2G_MASK                                                              0xe0000000
-#define PHY_ANALOG_TXRF4_AMP2CAS2G_GET(x)                                            (((x) & 0xe0000000) >> 29)
-#define PHY_ANALOG_TXRF4_AMP2CAS2G_SET(x)                                            (((x) << 29) & 0xe0000000)
-
-/* macros for TXRF5 */
-#define PHY_ANALOG_TXRF5_ADDRESS                                                                     0x00000050
-#define PHY_ANALOG_TXRF5_OFFSET                                                                      0x00000050
-#define PHY_ANALOG_TXRF5_SPARE5_MSB                                                                           0
-#define PHY_ANALOG_TXRF5_SPARE5_LSB                                                                           0
-#define PHY_ANALOG_TXRF5_SPARE5_MASK                                                                 0x00000001
-#define PHY_ANALOG_TXRF5_SPARE5_GET(x)                                                (((x) & 0x00000001) >> 0)
-#define PHY_ANALOG_TXRF5_SPARE5_SET(x)                                                (((x) << 0) & 0x00000001)
-#define PHY_ANALOG_TXRF5_PAL_LOCKED_MSB                                                                       1
-#define PHY_ANALOG_TXRF5_PAL_LOCKED_LSB                                                                       1
-#define PHY_ANALOG_TXRF5_PAL_LOCKED_MASK                                                             0x00000002
-#define PHY_ANALOG_TXRF5_PAL_LOCKED_GET(x)                                            (((x) & 0x00000002) >> 1)
-#define PHY_ANALOG_TXRF5_FBHI2G_MSB                                                                           2
-#define PHY_ANALOG_TXRF5_FBHI2G_LSB                                                                           2
-#define PHY_ANALOG_TXRF5_FBHI2G_MASK                                                                 0x00000004
-#define PHY_ANALOG_TXRF5_FBHI2G_GET(x)                                                (((x) & 0x00000004) >> 2)
-#define PHY_ANALOG_TXRF5_FBLO2G_MSB                                                                           3
-#define PHY_ANALOG_TXRF5_FBLO2G_LSB                                                                           3
-#define PHY_ANALOG_TXRF5_FBLO2G_MASK                                                                 0x00000008
-#define PHY_ANALOG_TXRF5_FBLO2G_GET(x)                                                (((x) & 0x00000008) >> 3)
-#define PHY_ANALOG_TXRF5_NOPALGAIN2G_MSB                                                                      4
-#define PHY_ANALOG_TXRF5_NOPALGAIN2G_LSB                                                                      4
-#define PHY_ANALOG_TXRF5_NOPALGAIN2G_MASK                                                            0x00000010
-#define PHY_ANALOG_TXRF5_NOPALGAIN2G_GET(x)                                           (((x) & 0x00000010) >> 4)
-#define PHY_ANALOG_TXRF5_NOPALGAIN2G_SET(x)                                           (((x) << 4) & 0x00000010)
-#define PHY_ANALOG_TXRF5_ENPACAL2G_MSB                                                                        5
-#define PHY_ANALOG_TXRF5_ENPACAL2G_LSB                                                                        5
-#define PHY_ANALOG_TXRF5_ENPACAL2G_MASK                                                              0x00000020
-#define PHY_ANALOG_TXRF5_ENPACAL2G_GET(x)                                             (((x) & 0x00000020) >> 5)
-#define PHY_ANALOG_TXRF5_ENPACAL2G_SET(x)                                             (((x) << 5) & 0x00000020)
-#define PHY_ANALOG_TXRF5_OFFSET2G_MSB                                                                        12
-#define PHY_ANALOG_TXRF5_OFFSET2G_LSB                                                                         6
-#define PHY_ANALOG_TXRF5_OFFSET2G_MASK                                                               0x00001fc0
-#define PHY_ANALOG_TXRF5_OFFSET2G_GET(x)                                              (((x) & 0x00001fc0) >> 6)
-#define PHY_ANALOG_TXRF5_OFFSET2G_SET(x)                                              (((x) << 6) & 0x00001fc0)
-#define PHY_ANALOG_TXRF5_ENOFFSETCAL2G_MSB                                                                   13
-#define PHY_ANALOG_TXRF5_ENOFFSETCAL2G_LSB                                                                   13
-#define PHY_ANALOG_TXRF5_ENOFFSETCAL2G_MASK                                                          0x00002000
-#define PHY_ANALOG_TXRF5_ENOFFSETCAL2G_GET(x)                                        (((x) & 0x00002000) >> 13)
-#define PHY_ANALOG_TXRF5_ENOFFSETCAL2G_SET(x)                                        (((x) << 13) & 0x00002000)
-#define PHY_ANALOG_TXRF5_REFHI2G_MSB                                                                         16
-#define PHY_ANALOG_TXRF5_REFHI2G_LSB                                                                         14
-#define PHY_ANALOG_TXRF5_REFHI2G_MASK                                                                0x0001c000
-#define PHY_ANALOG_TXRF5_REFHI2G_GET(x)                                              (((x) & 0x0001c000) >> 14)
-#define PHY_ANALOG_TXRF5_REFHI2G_SET(x)                                              (((x) << 14) & 0x0001c000)
-#define PHY_ANALOG_TXRF5_REFLO2G_MSB                                                                         19
-#define PHY_ANALOG_TXRF5_REFLO2G_LSB                                                                         17
-#define PHY_ANALOG_TXRF5_REFLO2G_MASK                                                                0x000e0000
-#define PHY_ANALOG_TXRF5_REFLO2G_GET(x)                                              (((x) & 0x000e0000) >> 17)
-#define PHY_ANALOG_TXRF5_REFLO2G_SET(x)                                              (((x) << 17) & 0x000e0000)
-#define PHY_ANALOG_TXRF5_PALCLAMP2G_MSB                                                                      21
-#define PHY_ANALOG_TXRF5_PALCLAMP2G_LSB                                                                      20
-#define PHY_ANALOG_TXRF5_PALCLAMP2G_MASK                                                             0x00300000
-#define PHY_ANALOG_TXRF5_PALCLAMP2G_GET(x)                                           (((x) & 0x00300000) >> 20)
-#define PHY_ANALOG_TXRF5_PALCLAMP2G_SET(x)                                           (((x) << 20) & 0x00300000)
-#define PHY_ANALOG_TXRF5_PK2B2G_QAM_MSB                                                                      23
-#define PHY_ANALOG_TXRF5_PK2B2G_QAM_LSB                                                                      22
-#define PHY_ANALOG_TXRF5_PK2B2G_QAM_MASK                                                             0x00c00000
-#define PHY_ANALOG_TXRF5_PK2B2G_QAM_GET(x)                                           (((x) & 0x00c00000) >> 22)
-#define PHY_ANALOG_TXRF5_PK2B2G_QAM_SET(x)                                           (((x) << 22) & 0x00c00000)
-#define PHY_ANALOG_TXRF5_PK2B2G_PSK_MSB                                                                      25
-#define PHY_ANALOG_TXRF5_PK2B2G_PSK_LSB                                                                      24
-#define PHY_ANALOG_TXRF5_PK2B2G_PSK_MASK                                                             0x03000000
-#define PHY_ANALOG_TXRF5_PK2B2G_PSK_GET(x)                                           (((x) & 0x03000000) >> 24)
-#define PHY_ANALOG_TXRF5_PK2B2G_PSK_SET(x)                                           (((x) << 24) & 0x03000000)
-#define PHY_ANALOG_TXRF5_PK2B2G_CCK_MSB                                                                      27
-#define PHY_ANALOG_TXRF5_PK2B2G_CCK_LSB                                                                      26
-#define PHY_ANALOG_TXRF5_PK2B2G_CCK_MASK                                                             0x0c000000
-#define PHY_ANALOG_TXRF5_PK2B2G_CCK_GET(x)                                           (((x) & 0x0c000000) >> 26)
-#define PHY_ANALOG_TXRF5_PK2B2G_CCK_SET(x)                                           (((x) << 26) & 0x0c000000)
-#define PHY_ANALOG_TXRF5_PK1B2G_QAM_MSB                                                                      29
-#define PHY_ANALOG_TXRF5_PK1B2G_QAM_LSB                                                                      28
-#define PHY_ANALOG_TXRF5_PK1B2G_QAM_MASK                                                             0x30000000
-#define PHY_ANALOG_TXRF5_PK1B2G_QAM_GET(x)                                           (((x) & 0x30000000) >> 28)
-#define PHY_ANALOG_TXRF5_PK1B2G_QAM_SET(x)                                           (((x) << 28) & 0x30000000)
-#define PHY_ANALOG_TXRF5_PK1B2G_PSK_MSB                                                                      31
-#define PHY_ANALOG_TXRF5_PK1B2G_PSK_LSB                                                                      30
-#define PHY_ANALOG_TXRF5_PK1B2G_PSK_MASK                                                             0xc0000000
-#define PHY_ANALOG_TXRF5_PK1B2G_PSK_GET(x)                                           (((x) & 0xc0000000) >> 30)
-#define PHY_ANALOG_TXRF5_PK1B2G_PSK_SET(x)                                           (((x) << 30) & 0xc0000000)
-
-/* macros for TXRF6 */
-#define PHY_ANALOG_TXRF6_ADDRESS                                                                     0x00000054
-#define PHY_ANALOG_TXRF6_OFFSET                                                                      0x00000054
-#define PHY_ANALOG_TXRF6_PALCLKGATE2G_MSB                                                                     0
-#define PHY_ANALOG_TXRF6_PALCLKGATE2G_LSB                                                                     0
-#define PHY_ANALOG_TXRF6_PALCLKGATE2G_MASK                                                           0x00000001
-#define PHY_ANALOG_TXRF6_PALCLKGATE2G_GET(x)                                          (((x) & 0x00000001) >> 0)
-#define PHY_ANALOG_TXRF6_PALCLKGATE2G_SET(x)                                          (((x) << 0) & 0x00000001)
-#define PHY_ANALOG_TXRF6_PALFLUCTCOUNT2G_MSB                                                                  8
-#define PHY_ANALOG_TXRF6_PALFLUCTCOUNT2G_LSB                                                                  1
-#define PHY_ANALOG_TXRF6_PALFLUCTCOUNT2G_MASK                                                        0x000001fe
-#define PHY_ANALOG_TXRF6_PALFLUCTCOUNT2G_GET(x)                                       (((x) & 0x000001fe) >> 1)
-#define PHY_ANALOG_TXRF6_PALFLUCTCOUNT2G_SET(x)                                       (((x) << 1) & 0x000001fe)
-#define PHY_ANALOG_TXRF6_PALFLUCTGAIN2G_MSB                                                                  10
-#define PHY_ANALOG_TXRF6_PALFLUCTGAIN2G_LSB                                                                   9
-#define PHY_ANALOG_TXRF6_PALFLUCTGAIN2G_MASK                                                         0x00000600
-#define PHY_ANALOG_TXRF6_PALFLUCTGAIN2G_GET(x)                                        (((x) & 0x00000600) >> 9)
-#define PHY_ANALOG_TXRF6_PALFLUCTGAIN2G_SET(x)                                        (((x) << 9) & 0x00000600)
-#define PHY_ANALOG_TXRF6_PALNOFLUCT2G_MSB                                                                    11
-#define PHY_ANALOG_TXRF6_PALNOFLUCT2G_LSB                                                                    11
-#define PHY_ANALOG_TXRF6_PALNOFLUCT2G_MASK                                                           0x00000800
-#define PHY_ANALOG_TXRF6_PALNOFLUCT2G_GET(x)                                         (((x) & 0x00000800) >> 11)
-#define PHY_ANALOG_TXRF6_PALNOFLUCT2G_SET(x)                                         (((x) << 11) & 0x00000800)
-#define PHY_ANALOG_TXRF6_GAINSTEP2G_MSB                                                                      14
-#define PHY_ANALOG_TXRF6_GAINSTEP2G_LSB                                                                      12
-#define PHY_ANALOG_TXRF6_GAINSTEP2G_MASK                                                             0x00007000
-#define PHY_ANALOG_TXRF6_GAINSTEP2G_GET(x)                                           (((x) & 0x00007000) >> 12)
-#define PHY_ANALOG_TXRF6_GAINSTEP2G_SET(x)                                           (((x) << 12) & 0x00007000)
-#define PHY_ANALOG_TXRF6_USE_GAIN_DELTA2G_MSB                                                                15
-#define PHY_ANALOG_TXRF6_USE_GAIN_DELTA2G_LSB                                                                15
-#define PHY_ANALOG_TXRF6_USE_GAIN_DELTA2G_MASK                                                       0x00008000
-#define PHY_ANALOG_TXRF6_USE_GAIN_DELTA2G_GET(x)                                     (((x) & 0x00008000) >> 15)
-#define PHY_ANALOG_TXRF6_USE_GAIN_DELTA2G_SET(x)                                     (((x) << 15) & 0x00008000)
-#define PHY_ANALOG_TXRF6_CAPDIV_I2G_MSB                                                                      19
-#define PHY_ANALOG_TXRF6_CAPDIV_I2G_LSB                                                                      16
-#define PHY_ANALOG_TXRF6_CAPDIV_I2G_MASK                                                             0x000f0000
-#define PHY_ANALOG_TXRF6_CAPDIV_I2G_GET(x)                                           (((x) & 0x000f0000) >> 16)
-#define PHY_ANALOG_TXRF6_CAPDIV_I2G_SET(x)                                           (((x) << 16) & 0x000f0000)
-#define PHY_ANALOG_TXRF6_PADRVGN_INDEX_I2G_MSB                                                               23
-#define PHY_ANALOG_TXRF6_PADRVGN_INDEX_I2G_LSB                                                               20
-#define PHY_ANALOG_TXRF6_PADRVGN_INDEX_I2G_MASK                                                      0x00f00000
-#define PHY_ANALOG_TXRF6_PADRVGN_INDEX_I2G_GET(x)                                    (((x) & 0x00f00000) >> 20)
-#define PHY_ANALOG_TXRF6_PADRVGN_INDEX_I2G_SET(x)                                    (((x) << 20) & 0x00f00000)
-#define PHY_ANALOG_TXRF6_VCMONDELAY2G_MSB                                                                    26
-#define PHY_ANALOG_TXRF6_VCMONDELAY2G_LSB                                                                    24
-#define PHY_ANALOG_TXRF6_VCMONDELAY2G_MASK                                                           0x07000000
-#define PHY_ANALOG_TXRF6_VCMONDELAY2G_GET(x)                                         (((x) & 0x07000000) >> 24)
-#define PHY_ANALOG_TXRF6_VCMONDELAY2G_SET(x)                                         (((x) << 24) & 0x07000000)
-#define PHY_ANALOG_TXRF6_CAPDIV2G_MSB                                                                        30
-#define PHY_ANALOG_TXRF6_CAPDIV2G_LSB                                                                        27
-#define PHY_ANALOG_TXRF6_CAPDIV2G_MASK                                                               0x78000000
-#define PHY_ANALOG_TXRF6_CAPDIV2G_GET(x)                                             (((x) & 0x78000000) >> 27)
-#define PHY_ANALOG_TXRF6_CAPDIV2G_SET(x)                                             (((x) << 27) & 0x78000000)
-#define PHY_ANALOG_TXRF6_CAPDIV2GOVR_MSB                                                                     31
-#define PHY_ANALOG_TXRF6_CAPDIV2GOVR_LSB                                                                     31
-#define PHY_ANALOG_TXRF6_CAPDIV2GOVR_MASK                                                            0x80000000
-#define PHY_ANALOG_TXRF6_CAPDIV2GOVR_GET(x)                                          (((x) & 0x80000000) >> 31)
-#define PHY_ANALOG_TXRF6_CAPDIV2GOVR_SET(x)                                          (((x) << 31) & 0x80000000)
-
-/* macros for TXRF7 */
-#define PHY_ANALOG_TXRF7_ADDRESS                                                                     0x00000058
-#define PHY_ANALOG_TXRF7_OFFSET                                                                      0x00000058
-#define PHY_ANALOG_TXRF7_SPARE7_MSB                                                                           1
-#define PHY_ANALOG_TXRF7_SPARE7_LSB                                                                           0
-#define PHY_ANALOG_TXRF7_SPARE7_MASK                                                                 0x00000003
-#define PHY_ANALOG_TXRF7_SPARE7_GET(x)                                                (((x) & 0x00000003) >> 0)
-#define PHY_ANALOG_TXRF7_SPARE7_SET(x)                                                (((x) << 0) & 0x00000003)
-#define PHY_ANALOG_TXRF7_PADRVGNTAB_4_MSB                                                                     7
-#define PHY_ANALOG_TXRF7_PADRVGNTAB_4_LSB                                                                     2
-#define PHY_ANALOG_TXRF7_PADRVGNTAB_4_MASK                                                           0x000000fc
-#define PHY_ANALOG_TXRF7_PADRVGNTAB_4_GET(x)                                          (((x) & 0x000000fc) >> 2)
-#define PHY_ANALOG_TXRF7_PADRVGNTAB_4_SET(x)                                          (((x) << 2) & 0x000000fc)
-#define PHY_ANALOG_TXRF7_PADRVGNTAB_3_MSB                                                                    13
-#define PHY_ANALOG_TXRF7_PADRVGNTAB_3_LSB                                                                     8
-#define PHY_ANALOG_TXRF7_PADRVGNTAB_3_MASK                                                           0x00003f00
-#define PHY_ANALOG_TXRF7_PADRVGNTAB_3_GET(x)                                          (((x) & 0x00003f00) >> 8)
-#define PHY_ANALOG_TXRF7_PADRVGNTAB_3_SET(x)                                          (((x) << 8) & 0x00003f00)
-#define PHY_ANALOG_TXRF7_PADRVGNTAB_2_MSB                                                                    19
-#define PHY_ANALOG_TXRF7_PADRVGNTAB_2_LSB                                                                    14
-#define PHY_ANALOG_TXRF7_PADRVGNTAB_2_MASK                                                           0x000fc000
-#define PHY_ANALOG_TXRF7_PADRVGNTAB_2_GET(x)                                         (((x) & 0x000fc000) >> 14)
-#define PHY_ANALOG_TXRF7_PADRVGNTAB_2_SET(x)                                         (((x) << 14) & 0x000fc000)
-#define PHY_ANALOG_TXRF7_PADRVGNTAB_1_MSB                                                                    25
-#define PHY_ANALOG_TXRF7_PADRVGNTAB_1_LSB                                                                    20
-#define PHY_ANALOG_TXRF7_PADRVGNTAB_1_MASK                                                           0x03f00000
-#define PHY_ANALOG_TXRF7_PADRVGNTAB_1_GET(x)                                         (((x) & 0x03f00000) >> 20)
-#define PHY_ANALOG_TXRF7_PADRVGNTAB_1_SET(x)                                         (((x) << 20) & 0x03f00000)
-#define PHY_ANALOG_TXRF7_PADRVGNTAB_0_MSB                                                                    31
-#define PHY_ANALOG_TXRF7_PADRVGNTAB_0_LSB                                                                    26
-#define PHY_ANALOG_TXRF7_PADRVGNTAB_0_MASK                                                           0xfc000000
-#define PHY_ANALOG_TXRF7_PADRVGNTAB_0_GET(x)                                         (((x) & 0xfc000000) >> 26)
-#define PHY_ANALOG_TXRF7_PADRVGNTAB_0_SET(x)                                         (((x) << 26) & 0xfc000000)
-
-/* macros for TXRF8 */
-#define PHY_ANALOG_TXRF8_ADDRESS                                                                     0x0000005c
-#define PHY_ANALOG_TXRF8_OFFSET                                                                      0x0000005c
-#define PHY_ANALOG_TXRF8_SPARE8_MSB                                                                           1
-#define PHY_ANALOG_TXRF8_SPARE8_LSB                                                                           0
-#define PHY_ANALOG_TXRF8_SPARE8_MASK                                                                 0x00000003
-#define PHY_ANALOG_TXRF8_SPARE8_GET(x)                                                (((x) & 0x00000003) >> 0)
-#define PHY_ANALOG_TXRF8_SPARE8_SET(x)                                                (((x) << 0) & 0x00000003)
-#define PHY_ANALOG_TXRF8_PADRVGNTAB_9_MSB                                                                     7
-#define PHY_ANALOG_TXRF8_PADRVGNTAB_9_LSB                                                                     2
-#define PHY_ANALOG_TXRF8_PADRVGNTAB_9_MASK                                                           0x000000fc
-#define PHY_ANALOG_TXRF8_PADRVGNTAB_9_GET(x)                                          (((x) & 0x000000fc) >> 2)
-#define PHY_ANALOG_TXRF8_PADRVGNTAB_9_SET(x)                                          (((x) << 2) & 0x000000fc)
-#define PHY_ANALOG_TXRF8_PADRVGNTAB_8_MSB                                                                    13
-#define PHY_ANALOG_TXRF8_PADRVGNTAB_8_LSB                                                                     8
-#define PHY_ANALOG_TXRF8_PADRVGNTAB_8_MASK                                                           0x00003f00
-#define PHY_ANALOG_TXRF8_PADRVGNTAB_8_GET(x)                                          (((x) & 0x00003f00) >> 8)
-#define PHY_ANALOG_TXRF8_PADRVGNTAB_8_SET(x)                                          (((x) << 8) & 0x00003f00)
-#define PHY_ANALOG_TXRF8_PADRVGNTAB_7_MSB                                                                    19
-#define PHY_ANALOG_TXRF8_PADRVGNTAB_7_LSB                                                                    14
-#define PHY_ANALOG_TXRF8_PADRVGNTAB_7_MASK                                                           0x000fc000
-#define PHY_ANALOG_TXRF8_PADRVGNTAB_7_GET(x)                                         (((x) & 0x000fc000) >> 14)
-#define PHY_ANALOG_TXRF8_PADRVGNTAB_7_SET(x)                                         (((x) << 14) & 0x000fc000)
-#define PHY_ANALOG_TXRF8_PADRVGNTAB_6_MSB                                                                    25
-#define PHY_ANALOG_TXRF8_PADRVGNTAB_6_LSB                                                                    20
-#define PHY_ANALOG_TXRF8_PADRVGNTAB_6_MASK                                                           0x03f00000
-#define PHY_ANALOG_TXRF8_PADRVGNTAB_6_GET(x)                                         (((x) & 0x03f00000) >> 20)
-#define PHY_ANALOG_TXRF8_PADRVGNTAB_6_SET(x)                                         (((x) << 20) & 0x03f00000)
-#define PHY_ANALOG_TXRF8_PADRVGNTAB_5_MSB                                                                    31
-#define PHY_ANALOG_TXRF8_PADRVGNTAB_5_LSB                                                                    26
-#define PHY_ANALOG_TXRF8_PADRVGNTAB_5_MASK                                                           0xfc000000
-#define PHY_ANALOG_TXRF8_PADRVGNTAB_5_GET(x)                                         (((x) & 0xfc000000) >> 26)
-#define PHY_ANALOG_TXRF8_PADRVGNTAB_5_SET(x)                                         (((x) << 26) & 0xfc000000)
-
-/* macros for TXRF9 */
-#define PHY_ANALOG_TXRF9_ADDRESS                                                                     0x00000060
-#define PHY_ANALOG_TXRF9_OFFSET                                                                      0x00000060
-#define PHY_ANALOG_TXRF9_SPARE9_MSB                                                                           1
-#define PHY_ANALOG_TXRF9_SPARE9_LSB                                                                           0
-#define PHY_ANALOG_TXRF9_SPARE9_MASK                                                                 0x00000003
-#define PHY_ANALOG_TXRF9_SPARE9_GET(x)                                                (((x) & 0x00000003) >> 0)
-#define PHY_ANALOG_TXRF9_SPARE9_SET(x)                                                (((x) << 0) & 0x00000003)
-#define PHY_ANALOG_TXRF9_PADRVGNTAB_14_MSB                                                                    7
-#define PHY_ANALOG_TXRF9_PADRVGNTAB_14_LSB                                                                    2
-#define PHY_ANALOG_TXRF9_PADRVGNTAB_14_MASK                                                          0x000000fc
-#define PHY_ANALOG_TXRF9_PADRVGNTAB_14_GET(x)                                         (((x) & 0x000000fc) >> 2)
-#define PHY_ANALOG_TXRF9_PADRVGNTAB_14_SET(x)                                         (((x) << 2) & 0x000000fc)
-#define PHY_ANALOG_TXRF9_PADRVGNTAB_13_MSB                                                                   13
-#define PHY_ANALOG_TXRF9_PADRVGNTAB_13_LSB                                                                    8
-#define PHY_ANALOG_TXRF9_PADRVGNTAB_13_MASK                                                          0x00003f00
-#define PHY_ANALOG_TXRF9_PADRVGNTAB_13_GET(x)                                         (((x) & 0x00003f00) >> 8)
-#define PHY_ANALOG_TXRF9_PADRVGNTAB_13_SET(x)                                         (((x) << 8) & 0x00003f00)
-#define PHY_ANALOG_TXRF9_PADRVGNTAB_12_MSB                                                                   19
-#define PHY_ANALOG_TXRF9_PADRVGNTAB_12_LSB                                                                   14
-#define PHY_ANALOG_TXRF9_PADRVGNTAB_12_MASK                                                          0x000fc000
-#define PHY_ANALOG_TXRF9_PADRVGNTAB_12_GET(x)                                        (((x) & 0x000fc000) >> 14)
-#define PHY_ANALOG_TXRF9_PADRVGNTAB_12_SET(x)                                        (((x) << 14) & 0x000fc000)
-#define PHY_ANALOG_TXRF9_PADRVGNTAB_11_MSB                                                                   25
-#define PHY_ANALOG_TXRF9_PADRVGNTAB_11_LSB                                                                   20
-#define PHY_ANALOG_TXRF9_PADRVGNTAB_11_MASK                                                          0x03f00000
-#define PHY_ANALOG_TXRF9_PADRVGNTAB_11_GET(x)                                        (((x) & 0x03f00000) >> 20)
-#define PHY_ANALOG_TXRF9_PADRVGNTAB_11_SET(x)                                        (((x) << 20) & 0x03f00000)
-#define PHY_ANALOG_TXRF9_PADRVGNTAB_10_MSB                                                                   31
-#define PHY_ANALOG_TXRF9_PADRVGNTAB_10_LSB                                                                   26
-#define PHY_ANALOG_TXRF9_PADRVGNTAB_10_MASK                                                          0xfc000000
-#define PHY_ANALOG_TXRF9_PADRVGNTAB_10_GET(x)                                        (((x) & 0xfc000000) >> 26)
-#define PHY_ANALOG_TXRF9_PADRVGNTAB_10_SET(x)                                        (((x) << 26) & 0xfc000000)
-
-/* macros for TXRF10 */
-#define PHY_ANALOG_TXRF10_ADDRESS                                                                    0x00000064
-#define PHY_ANALOG_TXRF10_OFFSET                                                                     0x00000064
-#define PHY_ANALOG_TXRF10_SPARE10_MSB                                                                         2
-#define PHY_ANALOG_TXRF10_SPARE10_LSB                                                                         0
-#define PHY_ANALOG_TXRF10_SPARE10_MASK                                                               0x00000007
-#define PHY_ANALOG_TXRF10_SPARE10_GET(x)                                              (((x) & 0x00000007) >> 0)
-#define PHY_ANALOG_TXRF10_SPARE10_SET(x)                                              (((x) << 0) & 0x00000007)
-#define PHY_ANALOG_TXRF10_PDOUT5G_3CALTX_MSB                                                                  3
-#define PHY_ANALOG_TXRF10_PDOUT5G_3CALTX_LSB                                                                  3
-#define PHY_ANALOG_TXRF10_PDOUT5G_3CALTX_MASK                                                        0x00000008
-#define PHY_ANALOG_TXRF10_PDOUT5G_3CALTX_GET(x)                                       (((x) & 0x00000008) >> 3)
-#define PHY_ANALOG_TXRF10_PDOUT5G_3CALTX_SET(x)                                       (((x) << 3) & 0x00000008)
-#define PHY_ANALOG_TXRF10_D3B5GCALTX_MSB                                                                      6
-#define PHY_ANALOG_TXRF10_D3B5GCALTX_LSB                                                                      4
-#define PHY_ANALOG_TXRF10_D3B5GCALTX_MASK                                                            0x00000070
-#define PHY_ANALOG_TXRF10_D3B5GCALTX_GET(x)                                           (((x) & 0x00000070) >> 4)
-#define PHY_ANALOG_TXRF10_D3B5GCALTX_SET(x)                                           (((x) << 4) & 0x00000070)
-#define PHY_ANALOG_TXRF10_D4B5GCALTX_MSB                                                                      9
-#define PHY_ANALOG_TXRF10_D4B5GCALTX_LSB                                                                      7
-#define PHY_ANALOG_TXRF10_D4B5GCALTX_MASK                                                            0x00000380
-#define PHY_ANALOG_TXRF10_D4B5GCALTX_GET(x)                                           (((x) & 0x00000380) >> 7)
-#define PHY_ANALOG_TXRF10_D4B5GCALTX_SET(x)                                           (((x) << 7) & 0x00000380)
-#define PHY_ANALOG_TXRF10_PADRVGN2GCALTX_MSB                                                                 16
-#define PHY_ANALOG_TXRF10_PADRVGN2GCALTX_LSB                                                                 10
-#define PHY_ANALOG_TXRF10_PADRVGN2GCALTX_MASK                                                        0x0001fc00
-#define PHY_ANALOG_TXRF10_PADRVGN2GCALTX_GET(x)                                      (((x) & 0x0001fc00) >> 10)
-#define PHY_ANALOG_TXRF10_PADRVGN2GCALTX_SET(x)                                      (((x) << 10) & 0x0001fc00)
-#define PHY_ANALOG_TXRF10_DB2GCALTX_MSB                                                                      19
-#define PHY_ANALOG_TXRF10_DB2GCALTX_LSB                                                                      17
-#define PHY_ANALOG_TXRF10_DB2GCALTX_MASK                                                             0x000e0000
-#define PHY_ANALOG_TXRF10_DB2GCALTX_GET(x)                                           (((x) & 0x000e0000) >> 17)
-#define PHY_ANALOG_TXRF10_DB2GCALTX_SET(x)                                           (((x) << 17) & 0x000e0000)
-#define PHY_ANALOG_TXRF10_CALTXSHIFT_MSB                                                                     20
-#define PHY_ANALOG_TXRF10_CALTXSHIFT_LSB                                                                     20
-#define PHY_ANALOG_TXRF10_CALTXSHIFT_MASK                                                            0x00100000
-#define PHY_ANALOG_TXRF10_CALTXSHIFT_GET(x)                                          (((x) & 0x00100000) >> 20)
-#define PHY_ANALOG_TXRF10_CALTXSHIFT_SET(x)                                          (((x) << 20) & 0x00100000)
-#define PHY_ANALOG_TXRF10_CALTXSHIFTOVR_MSB                                                                  21
-#define PHY_ANALOG_TXRF10_CALTXSHIFTOVR_LSB                                                                  21
-#define PHY_ANALOG_TXRF10_CALTXSHIFTOVR_MASK                                                         0x00200000
-#define PHY_ANALOG_TXRF10_CALTXSHIFTOVR_GET(x)                                       (((x) & 0x00200000) >> 21)
-#define PHY_ANALOG_TXRF10_CALTXSHIFTOVR_SET(x)                                       (((x) << 21) & 0x00200000)
-#define PHY_ANALOG_TXRF10_PADRVGN2G_SMOUT_MSB                                                                27
-#define PHY_ANALOG_TXRF10_PADRVGN2G_SMOUT_LSB                                                                22
-#define PHY_ANALOG_TXRF10_PADRVGN2G_SMOUT_MASK                                                       0x0fc00000
-#define PHY_ANALOG_TXRF10_PADRVGN2G_SMOUT_GET(x)                                     (((x) & 0x0fc00000) >> 22)
-#define PHY_ANALOG_TXRF10_PADRVGN_INDEX2G_SMOUT_MSB                                                          31
-#define PHY_ANALOG_TXRF10_PADRVGN_INDEX2G_SMOUT_LSB                                                          28
-#define PHY_ANALOG_TXRF10_PADRVGN_INDEX2G_SMOUT_MASK                                                 0xf0000000
-#define PHY_ANALOG_TXRF10_PADRVGN_INDEX2G_SMOUT_GET(x)                               (((x) & 0xf0000000) >> 28)
-
-/* macros for TXRF11 */
-#define PHY_ANALOG_TXRF11_ADDRESS                                                                    0x00000068
-#define PHY_ANALOG_TXRF11_OFFSET                                                                     0x00000068
-#define PHY_ANALOG_TXRF11_SPARE11_MSB                                                                         1
-#define PHY_ANALOG_TXRF11_SPARE11_LSB                                                                         0
-#define PHY_ANALOG_TXRF11_SPARE11_MASK                                                               0x00000003
-#define PHY_ANALOG_TXRF11_SPARE11_GET(x)                                              (((x) & 0x00000003) >> 0)
-#define PHY_ANALOG_TXRF11_SPARE11_SET(x)                                              (((x) << 0) & 0x00000003)
-#define PHY_ANALOG_TXRF11_PWD_IR25MIXDIV5G_MSB                                                                4
-#define PHY_ANALOG_TXRF11_PWD_IR25MIXDIV5G_LSB                                                                2
-#define PHY_ANALOG_TXRF11_PWD_IR25MIXDIV5G_MASK                                                      0x0000001c
-#define PHY_ANALOG_TXRF11_PWD_IR25MIXDIV5G_GET(x)                                     (((x) & 0x0000001c) >> 2)
-#define PHY_ANALOG_TXRF11_PWD_IR25MIXDIV5G_SET(x)                                     (((x) << 2) & 0x0000001c)
-#define PHY_ANALOG_TXRF11_PWD_IR25PA2G_MSB                                                                    7
-#define PHY_ANALOG_TXRF11_PWD_IR25PA2G_LSB                                                                    5
-#define PHY_ANALOG_TXRF11_PWD_IR25PA2G_MASK                                                          0x000000e0
-#define PHY_ANALOG_TXRF11_PWD_IR25PA2G_GET(x)                                         (((x) & 0x000000e0) >> 5)
-#define PHY_ANALOG_TXRF11_PWD_IR25PA2G_SET(x)                                         (((x) << 5) & 0x000000e0)
-#define PHY_ANALOG_TXRF11_PWD_IR25MIXBIAS2G_MSB                                                              10
-#define PHY_ANALOG_TXRF11_PWD_IR25MIXBIAS2G_LSB                                                               8
-#define PHY_ANALOG_TXRF11_PWD_IR25MIXBIAS2G_MASK                                                     0x00000700
-#define PHY_ANALOG_TXRF11_PWD_IR25MIXBIAS2G_GET(x)                                    (((x) & 0x00000700) >> 8)
-#define PHY_ANALOG_TXRF11_PWD_IR25MIXBIAS2G_SET(x)                                    (((x) << 8) & 0x00000700)
-#define PHY_ANALOG_TXRF11_PWD_IR25MIXDIV2G_MSB                                                               13
-#define PHY_ANALOG_TXRF11_PWD_IR25MIXDIV2G_LSB                                                               11
-#define PHY_ANALOG_TXRF11_PWD_IR25MIXDIV2G_MASK                                                      0x00003800
-#define PHY_ANALOG_TXRF11_PWD_IR25MIXDIV2G_GET(x)                                    (((x) & 0x00003800) >> 11)
-#define PHY_ANALOG_TXRF11_PWD_IR25MIXDIV2G_SET(x)                                    (((x) << 11) & 0x00003800)
-#define PHY_ANALOG_TXRF11_PWD_ICSPARE_MSB                                                                    16
-#define PHY_ANALOG_TXRF11_PWD_ICSPARE_LSB                                                                    14
-#define PHY_ANALOG_TXRF11_PWD_ICSPARE_MASK                                                           0x0001c000
-#define PHY_ANALOG_TXRF11_PWD_ICSPARE_GET(x)                                         (((x) & 0x0001c000) >> 14)
-#define PHY_ANALOG_TXRF11_PWD_ICSPARE_SET(x)                                         (((x) << 14) & 0x0001c000)
-#define PHY_ANALOG_TXRF11_PWD_IC25TEMPSEN_MSB                                                                19
-#define PHY_ANALOG_TXRF11_PWD_IC25TEMPSEN_LSB                                                                17
-#define PHY_ANALOG_TXRF11_PWD_IC25TEMPSEN_MASK                                                       0x000e0000
-#define PHY_ANALOG_TXRF11_PWD_IC25TEMPSEN_GET(x)                                     (((x) & 0x000e0000) >> 17)
-#define PHY_ANALOG_TXRF11_PWD_IC25TEMPSEN_SET(x)                                     (((x) << 17) & 0x000e0000)
-#define PHY_ANALOG_TXRF11_PWD_IC25PA5G2_MSB                                                                  22
-#define PHY_ANALOG_TXRF11_PWD_IC25PA5G2_LSB                                                                  20
-#define PHY_ANALOG_TXRF11_PWD_IC25PA5G2_MASK                                                         0x00700000
-#define PHY_ANALOG_TXRF11_PWD_IC25PA5G2_GET(x)                                       (((x) & 0x00700000) >> 20)
-#define PHY_ANALOG_TXRF11_PWD_IC25PA5G2_SET(x)                                       (((x) << 20) & 0x00700000)
-#define PHY_ANALOG_TXRF11_PWD_IC25PA5G1_MSB                                                                  25
-#define PHY_ANALOG_TXRF11_PWD_IC25PA5G1_LSB                                                                  23
-#define PHY_ANALOG_TXRF11_PWD_IC25PA5G1_MASK                                                         0x03800000
-#define PHY_ANALOG_TXRF11_PWD_IC25PA5G1_GET(x)                                       (((x) & 0x03800000) >> 23)
-#define PHY_ANALOG_TXRF11_PWD_IC25PA5G1_SET(x)                                       (((x) << 23) & 0x03800000)
-#define PHY_ANALOG_TXRF11_PWD_IC25MIXBUF5G_MSB                                                               28
-#define PHY_ANALOG_TXRF11_PWD_IC25MIXBUF5G_LSB                                                               26
-#define PHY_ANALOG_TXRF11_PWD_IC25MIXBUF5G_MASK                                                      0x1c000000
-#define PHY_ANALOG_TXRF11_PWD_IC25MIXBUF5G_GET(x)                                    (((x) & 0x1c000000) >> 26)
-#define PHY_ANALOG_TXRF11_PWD_IC25MIXBUF5G_SET(x)                                    (((x) << 26) & 0x1c000000)
-#define PHY_ANALOG_TXRF11_PWD_IC25PA2G_MSB                                                                   31
-#define PHY_ANALOG_TXRF11_PWD_IC25PA2G_LSB                                                                   29
-#define PHY_ANALOG_TXRF11_PWD_IC25PA2G_MASK                                                          0xe0000000
-#define PHY_ANALOG_TXRF11_PWD_IC25PA2G_GET(x)                                        (((x) & 0xe0000000) >> 29)
-#define PHY_ANALOG_TXRF11_PWD_IC25PA2G_SET(x)                                        (((x) << 29) & 0xe0000000)
-
-/* macros for TXRF12 */
-#define PHY_ANALOG_TXRF12_ADDRESS                                                                    0x0000006c
-#define PHY_ANALOG_TXRF12_OFFSET                                                                     0x0000006c
-#define PHY_ANALOG_TXRF12_SPARE12_2_MSB                                                                       7
-#define PHY_ANALOG_TXRF12_SPARE12_2_LSB                                                                       0
-#define PHY_ANALOG_TXRF12_SPARE12_2_MASK                                                             0x000000ff
-#define PHY_ANALOG_TXRF12_SPARE12_2_GET(x)                                            (((x) & 0x000000ff) >> 0)
-#define PHY_ANALOG_TXRF12_SPARE12_1_MSB                                                                       9
-#define PHY_ANALOG_TXRF12_SPARE12_1_LSB                                                                       8
-#define PHY_ANALOG_TXRF12_SPARE12_1_MASK                                                             0x00000300
-#define PHY_ANALOG_TXRF12_SPARE12_1_GET(x)                                            (((x) & 0x00000300) >> 8)
-#define PHY_ANALOG_TXRF12_SPARE12_1_SET(x)                                            (((x) << 8) & 0x00000300)
-#define PHY_ANALOG_TXRF12_ATBSEL5G_MSB                                                                       13
-#define PHY_ANALOG_TXRF12_ATBSEL5G_LSB                                                                       10
-#define PHY_ANALOG_TXRF12_ATBSEL5G_MASK                                                              0x00003c00
-#define PHY_ANALOG_TXRF12_ATBSEL5G_GET(x)                                            (((x) & 0x00003c00) >> 10)
-#define PHY_ANALOG_TXRF12_ATBSEL5G_SET(x)                                            (((x) << 10) & 0x00003c00)
-#define PHY_ANALOG_TXRF12_ATBSEL2G_MSB                                                                       16
-#define PHY_ANALOG_TXRF12_ATBSEL2G_LSB                                                                       14
-#define PHY_ANALOG_TXRF12_ATBSEL2G_MASK                                                              0x0001c000
-#define PHY_ANALOG_TXRF12_ATBSEL2G_GET(x)                                            (((x) & 0x0001c000) >> 14)
-#define PHY_ANALOG_TXRF12_ATBSEL2G_SET(x)                                            (((x) << 14) & 0x0001c000)
-#define PHY_ANALOG_TXRF12_PWD_IRSPARE_MSB                                                                    19
-#define PHY_ANALOG_TXRF12_PWD_IRSPARE_LSB                                                                    17
-#define PHY_ANALOG_TXRF12_PWD_IRSPARE_MASK                                                           0x000e0000
-#define PHY_ANALOG_TXRF12_PWD_IRSPARE_GET(x)                                         (((x) & 0x000e0000) >> 17)
-#define PHY_ANALOG_TXRF12_PWD_IRSPARE_SET(x)                                         (((x) << 17) & 0x000e0000)
-#define PHY_ANALOG_TXRF12_PWD_IR25TEMPSEN_MSB                                                                22
-#define PHY_ANALOG_TXRF12_PWD_IR25TEMPSEN_LSB                                                                20
-#define PHY_ANALOG_TXRF12_PWD_IR25TEMPSEN_MASK                                                       0x00700000
-#define PHY_ANALOG_TXRF12_PWD_IR25TEMPSEN_GET(x)                                     (((x) & 0x00700000) >> 20)
-#define PHY_ANALOG_TXRF12_PWD_IR25TEMPSEN_SET(x)                                     (((x) << 20) & 0x00700000)
-#define PHY_ANALOG_TXRF12_PWD_IR25PA5G2_MSB                                                                  25
-#define PHY_ANALOG_TXRF12_PWD_IR25PA5G2_LSB                                                                  23
-#define PHY_ANALOG_TXRF12_PWD_IR25PA5G2_MASK                                                         0x03800000
-#define PHY_ANALOG_TXRF12_PWD_IR25PA5G2_GET(x)                                       (((x) & 0x03800000) >> 23)
-#define PHY_ANALOG_TXRF12_PWD_IR25PA5G2_SET(x)                                       (((x) << 23) & 0x03800000)
-#define PHY_ANALOG_TXRF12_PWD_IR25PA5G1_MSB                                                                  28
-#define PHY_ANALOG_TXRF12_PWD_IR25PA5G1_LSB                                                                  26
-#define PHY_ANALOG_TXRF12_PWD_IR25PA5G1_MASK                                                         0x1c000000
-#define PHY_ANALOG_TXRF12_PWD_IR25PA5G1_GET(x)                                       (((x) & 0x1c000000) >> 26)
-#define PHY_ANALOG_TXRF12_PWD_IR25PA5G1_SET(x)                                       (((x) << 26) & 0x1c000000)
-#define PHY_ANALOG_TXRF12_PWD_IR25MIXBIAS5G_MSB                                                              31
-#define PHY_ANALOG_TXRF12_PWD_IR25MIXBIAS5G_LSB                                                              29
-#define PHY_ANALOG_TXRF12_PWD_IR25MIXBIAS5G_MASK                                                     0xe0000000
-#define PHY_ANALOG_TXRF12_PWD_IR25MIXBIAS5G_GET(x)                                   (((x) & 0xe0000000) >> 29)
-#define PHY_ANALOG_TXRF12_PWD_IR25MIXBIAS5G_SET(x)                                   (((x) << 29) & 0xe0000000)
-
-/* macros for SYNTH1 */
-#define PHY_ANALOG_SYNTH1_ADDRESS                                                                    0x00000080
-#define PHY_ANALOG_SYNTH1_OFFSET                                                                     0x00000080
-#define PHY_ANALOG_SYNTH1_SEL_VCMONABUS_MSB                                                                   2
-#define PHY_ANALOG_SYNTH1_SEL_VCMONABUS_LSB                                                                   0
-#define PHY_ANALOG_SYNTH1_SEL_VCMONABUS_MASK                                                         0x00000007
-#define PHY_ANALOG_SYNTH1_SEL_VCMONABUS_GET(x)                                        (((x) & 0x00000007) >> 0)
-#define PHY_ANALOG_SYNTH1_SEL_VCMONABUS_SET(x)                                        (((x) << 0) & 0x00000007)
-#define PHY_ANALOG_SYNTH1_SEL_VCOABUS_MSB                                                                     5
-#define PHY_ANALOG_SYNTH1_SEL_VCOABUS_LSB                                                                     3
-#define PHY_ANALOG_SYNTH1_SEL_VCOABUS_MASK                                                           0x00000038
-#define PHY_ANALOG_SYNTH1_SEL_VCOABUS_GET(x)                                          (((x) & 0x00000038) >> 3)
-#define PHY_ANALOG_SYNTH1_SEL_VCOABUS_SET(x)                                          (((x) << 3) & 0x00000038)
-#define PHY_ANALOG_SYNTH1_MONITOR_SYNTHLOCKVCOK_MSB                                                           6
-#define PHY_ANALOG_SYNTH1_MONITOR_SYNTHLOCKVCOK_LSB                                                           6
-#define PHY_ANALOG_SYNTH1_MONITOR_SYNTHLOCKVCOK_MASK                                                 0x00000040
-#define PHY_ANALOG_SYNTH1_MONITOR_SYNTHLOCKVCOK_GET(x)                                (((x) & 0x00000040) >> 6)
-#define PHY_ANALOG_SYNTH1_MONITOR_SYNTHLOCKVCOK_SET(x)                                (((x) << 6) & 0x00000040)
-#define PHY_ANALOG_SYNTH1_MONITOR_VC2LOW_MSB                                                                  7
-#define PHY_ANALOG_SYNTH1_MONITOR_VC2LOW_LSB                                                                  7
-#define PHY_ANALOG_SYNTH1_MONITOR_VC2LOW_MASK                                                        0x00000080
-#define PHY_ANALOG_SYNTH1_MONITOR_VC2LOW_GET(x)                                       (((x) & 0x00000080) >> 7)
-#define PHY_ANALOG_SYNTH1_MONITOR_VC2LOW_SET(x)                                       (((x) << 7) & 0x00000080)
-#define PHY_ANALOG_SYNTH1_MONITOR_VC2HIGH_MSB                                                                 8
-#define PHY_ANALOG_SYNTH1_MONITOR_VC2HIGH_LSB                                                                 8
-#define PHY_ANALOG_SYNTH1_MONITOR_VC2HIGH_MASK                                                       0x00000100
-#define PHY_ANALOG_SYNTH1_MONITOR_VC2HIGH_GET(x)                                      (((x) & 0x00000100) >> 8)
-#define PHY_ANALOG_SYNTH1_MONITOR_VC2HIGH_SET(x)                                      (((x) << 8) & 0x00000100)
-#define PHY_ANALOG_SYNTH1_MONITOR_FB_DIV2_MSB                                                                 9
-#define PHY_ANALOG_SYNTH1_MONITOR_FB_DIV2_LSB                                                                 9
-#define PHY_ANALOG_SYNTH1_MONITOR_FB_DIV2_MASK                                                       0x00000200
-#define PHY_ANALOG_SYNTH1_MONITOR_FB_DIV2_GET(x)                                      (((x) & 0x00000200) >> 9)
-#define PHY_ANALOG_SYNTH1_MONITOR_FB_DIV2_SET(x)                                      (((x) << 9) & 0x00000200)
-#define PHY_ANALOG_SYNTH1_MONITOR_REF_MSB                                                                    10
-#define PHY_ANALOG_SYNTH1_MONITOR_REF_LSB                                                                    10
-#define PHY_ANALOG_SYNTH1_MONITOR_REF_MASK                                                           0x00000400
-#define PHY_ANALOG_SYNTH1_MONITOR_REF_GET(x)                                         (((x) & 0x00000400) >> 10)
-#define PHY_ANALOG_SYNTH1_MONITOR_REF_SET(x)                                         (((x) << 10) & 0x00000400)
-#define PHY_ANALOG_SYNTH1_MONITOR_FB_MSB                                                                     11
-#define PHY_ANALOG_SYNTH1_MONITOR_FB_LSB                                                                     11
-#define PHY_ANALOG_SYNTH1_MONITOR_FB_MASK                                                            0x00000800
-#define PHY_ANALOG_SYNTH1_MONITOR_FB_GET(x)                                          (((x) & 0x00000800) >> 11)
-#define PHY_ANALOG_SYNTH1_MONITOR_FB_SET(x)                                          (((x) << 11) & 0x00000800)
-#define PHY_ANALOG_SYNTH1_SEVENBITVCOCAP_MSB                                                                 12
-#define PHY_ANALOG_SYNTH1_SEVENBITVCOCAP_LSB                                                                 12
-#define PHY_ANALOG_SYNTH1_SEVENBITVCOCAP_MASK                                                        0x00001000
-#define PHY_ANALOG_SYNTH1_SEVENBITVCOCAP_GET(x)                                      (((x) & 0x00001000) >> 12)
-#define PHY_ANALOG_SYNTH1_SEVENBITVCOCAP_SET(x)                                      (((x) << 12) & 0x00001000)
-#define PHY_ANALOG_SYNTH1_PWUP_PD_MSB                                                                        15
-#define PHY_ANALOG_SYNTH1_PWUP_PD_LSB                                                                        13
-#define PHY_ANALOG_SYNTH1_PWUP_PD_MASK                                                               0x0000e000
-#define PHY_ANALOG_SYNTH1_PWUP_PD_GET(x)                                             (((x) & 0x0000e000) >> 13)
-#define PHY_ANALOG_SYNTH1_PWUP_PD_SET(x)                                             (((x) << 13) & 0x0000e000)
-#define PHY_ANALOG_SYNTH1_PWD_VCOBUF_MSB                                                                     16
-#define PHY_ANALOG_SYNTH1_PWD_VCOBUF_LSB                                                                     16
-#define PHY_ANALOG_SYNTH1_PWD_VCOBUF_MASK                                                            0x00010000
-#define PHY_ANALOG_SYNTH1_PWD_VCOBUF_GET(x)                                          (((x) & 0x00010000) >> 16)
-#define PHY_ANALOG_SYNTH1_PWD_VCOBUF_SET(x)                                          (((x) << 16) & 0x00010000)
-#define PHY_ANALOG_SYNTH1_VCOBUFGAIN_MSB                                                                     18
-#define PHY_ANALOG_SYNTH1_VCOBUFGAIN_LSB                                                                     17
-#define PHY_ANALOG_SYNTH1_VCOBUFGAIN_MASK                                                            0x00060000
-#define PHY_ANALOG_SYNTH1_VCOBUFGAIN_GET(x)                                          (((x) & 0x00060000) >> 17)
-#define PHY_ANALOG_SYNTH1_VCOBUFGAIN_SET(x)                                          (((x) << 17) & 0x00060000)
-#define PHY_ANALOG_SYNTH1_VCOREGLEVEL_MSB                                                                    20
-#define PHY_ANALOG_SYNTH1_VCOREGLEVEL_LSB                                                                    19
-#define PHY_ANALOG_SYNTH1_VCOREGLEVEL_MASK                                                           0x00180000
-#define PHY_ANALOG_SYNTH1_VCOREGLEVEL_GET(x)                                         (((x) & 0x00180000) >> 19)
-#define PHY_ANALOG_SYNTH1_VCOREGLEVEL_SET(x)                                         (((x) << 19) & 0x00180000)
-#define PHY_ANALOG_SYNTH1_VCOREGBYPASS_MSB                                                                   21
-#define PHY_ANALOG_SYNTH1_VCOREGBYPASS_LSB                                                                   21
-#define PHY_ANALOG_SYNTH1_VCOREGBYPASS_MASK                                                          0x00200000
-#define PHY_ANALOG_SYNTH1_VCOREGBYPASS_GET(x)                                        (((x) & 0x00200000) >> 21)
-#define PHY_ANALOG_SYNTH1_VCOREGBYPASS_SET(x)                                        (((x) << 21) & 0x00200000)
-#define PHY_ANALOG_SYNTH1_PWUP_LOREF_MSB                                                                     22
-#define PHY_ANALOG_SYNTH1_PWUP_LOREF_LSB                                                                     22
-#define PHY_ANALOG_SYNTH1_PWUP_LOREF_MASK                                                            0x00400000
-#define PHY_ANALOG_SYNTH1_PWUP_LOREF_GET(x)                                          (((x) & 0x00400000) >> 22)
-#define PHY_ANALOG_SYNTH1_PWUP_LOREF_SET(x)                                          (((x) << 22) & 0x00400000)
-#define PHY_ANALOG_SYNTH1_PWD_LOMIX_MSB                                                                      23
-#define PHY_ANALOG_SYNTH1_PWD_LOMIX_LSB                                                                      23
-#define PHY_ANALOG_SYNTH1_PWD_LOMIX_MASK                                                             0x00800000
-#define PHY_ANALOG_SYNTH1_PWD_LOMIX_GET(x)                                           (((x) & 0x00800000) >> 23)
-#define PHY_ANALOG_SYNTH1_PWD_LOMIX_SET(x)                                           (((x) << 23) & 0x00800000)
-#define PHY_ANALOG_SYNTH1_PWD_LODIV_MSB                                                                      24
-#define PHY_ANALOG_SYNTH1_PWD_LODIV_LSB                                                                      24
-#define PHY_ANALOG_SYNTH1_PWD_LODIV_MASK                                                             0x01000000
-#define PHY_ANALOG_SYNTH1_PWD_LODIV_GET(x)                                           (((x) & 0x01000000) >> 24)
-#define PHY_ANALOG_SYNTH1_PWD_LODIV_SET(x)                                           (((x) << 24) & 0x01000000)
-#define PHY_ANALOG_SYNTH1_PWD_LOBUF5G_MSB                                                                    25
-#define PHY_ANALOG_SYNTH1_PWD_LOBUF5G_LSB                                                                    25
-#define PHY_ANALOG_SYNTH1_PWD_LOBUF5G_MASK                                                           0x02000000
-#define PHY_ANALOG_SYNTH1_PWD_LOBUF5G_GET(x)                                         (((x) & 0x02000000) >> 25)
-#define PHY_ANALOG_SYNTH1_PWD_LOBUF5G_SET(x)                                         (((x) << 25) & 0x02000000)
-#define PHY_ANALOG_SYNTH1_PWD_LOBUF2G_MSB                                                                    26
-#define PHY_ANALOG_SYNTH1_PWD_LOBUF2G_LSB                                                                    26
-#define PHY_ANALOG_SYNTH1_PWD_LOBUF2G_MASK                                                           0x04000000
-#define PHY_ANALOG_SYNTH1_PWD_LOBUF2G_GET(x)                                         (((x) & 0x04000000) >> 26)
-#define PHY_ANALOG_SYNTH1_PWD_LOBUF2G_SET(x)                                         (((x) << 26) & 0x04000000)
-#define PHY_ANALOG_SYNTH1_PWD_PRESC_MSB                                                                      27
-#define PHY_ANALOG_SYNTH1_PWD_PRESC_LSB                                                                      27
-#define PHY_ANALOG_SYNTH1_PWD_PRESC_MASK                                                             0x08000000
-#define PHY_ANALOG_SYNTH1_PWD_PRESC_GET(x)                                           (((x) & 0x08000000) >> 27)
-#define PHY_ANALOG_SYNTH1_PWD_PRESC_SET(x)                                           (((x) << 27) & 0x08000000)
-#define PHY_ANALOG_SYNTH1_PWD_VCO_MSB                                                                        28
-#define PHY_ANALOG_SYNTH1_PWD_VCO_LSB                                                                        28
-#define PHY_ANALOG_SYNTH1_PWD_VCO_MASK                                                               0x10000000
-#define PHY_ANALOG_SYNTH1_PWD_VCO_GET(x)                                             (((x) & 0x10000000) >> 28)
-#define PHY_ANALOG_SYNTH1_PWD_VCO_SET(x)                                             (((x) << 28) & 0x10000000)
-#define PHY_ANALOG_SYNTH1_PWD_VCMON_MSB                                                                      29
-#define PHY_ANALOG_SYNTH1_PWD_VCMON_LSB                                                                      29
-#define PHY_ANALOG_SYNTH1_PWD_VCMON_MASK                                                             0x20000000
-#define PHY_ANALOG_SYNTH1_PWD_VCMON_GET(x)                                           (((x) & 0x20000000) >> 29)
-#define PHY_ANALOG_SYNTH1_PWD_VCMON_SET(x)                                           (((x) << 29) & 0x20000000)
-#define PHY_ANALOG_SYNTH1_PWD_CP_MSB                                                                         30
-#define PHY_ANALOG_SYNTH1_PWD_CP_LSB                                                                         30
-#define PHY_ANALOG_SYNTH1_PWD_CP_MASK                                                                0x40000000
-#define PHY_ANALOG_SYNTH1_PWD_CP_GET(x)                                              (((x) & 0x40000000) >> 30)
-#define PHY_ANALOG_SYNTH1_PWD_CP_SET(x)                                              (((x) << 30) & 0x40000000)
-#define PHY_ANALOG_SYNTH1_PWD_BIAS_MSB                                                                       31
-#define PHY_ANALOG_SYNTH1_PWD_BIAS_LSB                                                                       31
-#define PHY_ANALOG_SYNTH1_PWD_BIAS_MASK                                                              0x80000000
-#define PHY_ANALOG_SYNTH1_PWD_BIAS_GET(x)                                            (((x) & 0x80000000) >> 31)
-#define PHY_ANALOG_SYNTH1_PWD_BIAS_SET(x)                                            (((x) << 31) & 0x80000000)
-
-/* macros for SYNTH2 */
-#define PHY_ANALOG_SYNTH2_ADDRESS                                                                    0x00000084
-#define PHY_ANALOG_SYNTH2_OFFSET                                                                     0x00000084
-#define PHY_ANALOG_SYNTH2_CAPRANGE3_MSB                                                                       3
-#define PHY_ANALOG_SYNTH2_CAPRANGE3_LSB                                                                       0
-#define PHY_ANALOG_SYNTH2_CAPRANGE3_MASK                                                             0x0000000f
-#define PHY_ANALOG_SYNTH2_CAPRANGE3_GET(x)                                            (((x) & 0x0000000f) >> 0)
-#define PHY_ANALOG_SYNTH2_CAPRANGE3_SET(x)                                            (((x) << 0) & 0x0000000f)
-#define PHY_ANALOG_SYNTH2_CAPRANGE2_MSB                                                                       7
-#define PHY_ANALOG_SYNTH2_CAPRANGE2_LSB                                                                       4
-#define PHY_ANALOG_SYNTH2_CAPRANGE2_MASK                                                             0x000000f0
-#define PHY_ANALOG_SYNTH2_CAPRANGE2_GET(x)                                            (((x) & 0x000000f0) >> 4)
-#define PHY_ANALOG_SYNTH2_CAPRANGE2_SET(x)                                            (((x) << 4) & 0x000000f0)
-#define PHY_ANALOG_SYNTH2_CAPRANGE1_MSB                                                                      11
-#define PHY_ANALOG_SYNTH2_CAPRANGE1_LSB                                                                       8
-#define PHY_ANALOG_SYNTH2_CAPRANGE1_MASK                                                             0x00000f00
-#define PHY_ANALOG_SYNTH2_CAPRANGE1_GET(x)                                            (((x) & 0x00000f00) >> 8)
-#define PHY_ANALOG_SYNTH2_CAPRANGE1_SET(x)                                            (((x) << 8) & 0x00000f00)
-#define PHY_ANALOG_SYNTH2_LOOPLEAKCUR_INTN_MSB                                                               15
-#define PHY_ANALOG_SYNTH2_LOOPLEAKCUR_INTN_LSB                                                               12
-#define PHY_ANALOG_SYNTH2_LOOPLEAKCUR_INTN_MASK                                                      0x0000f000
-#define PHY_ANALOG_SYNTH2_LOOPLEAKCUR_INTN_GET(x)                                    (((x) & 0x0000f000) >> 12)
-#define PHY_ANALOG_SYNTH2_LOOPLEAKCUR_INTN_SET(x)                                    (((x) << 12) & 0x0000f000)
-#define PHY_ANALOG_SYNTH2_CPLOWLK_INTN_MSB                                                                   16
-#define PHY_ANALOG_SYNTH2_CPLOWLK_INTN_LSB                                                                   16
-#define PHY_ANALOG_SYNTH2_CPLOWLK_INTN_MASK                                                          0x00010000
-#define PHY_ANALOG_SYNTH2_CPLOWLK_INTN_GET(x)                                        (((x) & 0x00010000) >> 16)
-#define PHY_ANALOG_SYNTH2_CPLOWLK_INTN_SET(x)                                        (((x) << 16) & 0x00010000)
-#define PHY_ANALOG_SYNTH2_CPSTEERING_EN_INTN_MSB                                                             17
-#define PHY_ANALOG_SYNTH2_CPSTEERING_EN_INTN_LSB                                                             17
-#define PHY_ANALOG_SYNTH2_CPSTEERING_EN_INTN_MASK                                                    0x00020000
-#define PHY_ANALOG_SYNTH2_CPSTEERING_EN_INTN_GET(x)                                  (((x) & 0x00020000) >> 17)
-#define PHY_ANALOG_SYNTH2_CPSTEERING_EN_INTN_SET(x)                                  (((x) << 17) & 0x00020000)
-#define PHY_ANALOG_SYNTH2_CPBIAS_INTN_MSB                                                                    19
-#define PHY_ANALOG_SYNTH2_CPBIAS_INTN_LSB                                                                    18
-#define PHY_ANALOG_SYNTH2_CPBIAS_INTN_MASK                                                           0x000c0000
-#define PHY_ANALOG_SYNTH2_CPBIAS_INTN_GET(x)                                         (((x) & 0x000c0000) >> 18)
-#define PHY_ANALOG_SYNTH2_CPBIAS_INTN_SET(x)                                         (((x) << 18) & 0x000c0000)
-#define PHY_ANALOG_SYNTH2_VC_LOW_REF_MSB                                                                     22
-#define PHY_ANALOG_SYNTH2_VC_LOW_REF_LSB                                                                     20
-#define PHY_ANALOG_SYNTH2_VC_LOW_REF_MASK                                                            0x00700000
-#define PHY_ANALOG_SYNTH2_VC_LOW_REF_GET(x)                                          (((x) & 0x00700000) >> 20)
-#define PHY_ANALOG_SYNTH2_VC_LOW_REF_SET(x)                                          (((x) << 20) & 0x00700000)
-#define PHY_ANALOG_SYNTH2_VC_MID_REF_MSB                                                                     25
-#define PHY_ANALOG_SYNTH2_VC_MID_REF_LSB                                                                     23
-#define PHY_ANALOG_SYNTH2_VC_MID_REF_MASK                                                            0x03800000
-#define PHY_ANALOG_SYNTH2_VC_MID_REF_GET(x)                                          (((x) & 0x03800000) >> 23)
-#define PHY_ANALOG_SYNTH2_VC_MID_REF_SET(x)                                          (((x) << 23) & 0x03800000)
-#define PHY_ANALOG_SYNTH2_VC_HI_REF_MSB                                                                      28
-#define PHY_ANALOG_SYNTH2_VC_HI_REF_LSB                                                                      26
-#define PHY_ANALOG_SYNTH2_VC_HI_REF_MASK                                                             0x1c000000
-#define PHY_ANALOG_SYNTH2_VC_HI_REF_GET(x)                                           (((x) & 0x1c000000) >> 26)
-#define PHY_ANALOG_SYNTH2_VC_HI_REF_SET(x)                                           (((x) << 26) & 0x1c000000)
-#define PHY_ANALOG_SYNTH2_VC_CAL_REF_MSB                                                                     31
-#define PHY_ANALOG_SYNTH2_VC_CAL_REF_LSB                                                                     29
-#define PHY_ANALOG_SYNTH2_VC_CAL_REF_MASK                                                            0xe0000000
-#define PHY_ANALOG_SYNTH2_VC_CAL_REF_GET(x)                                          (((x) & 0xe0000000) >> 29)
-#define PHY_ANALOG_SYNTH2_VC_CAL_REF_SET(x)                                          (((x) << 29) & 0xe0000000)
-
-/* macros for SYNTH3 */
-#define PHY_ANALOG_SYNTH3_ADDRESS                                                                    0x00000088
-#define PHY_ANALOG_SYNTH3_OFFSET                                                                     0x00000088
-#define PHY_ANALOG_SYNTH3_WAIT_VC_CHECK_MSB                                                                   5
-#define PHY_ANALOG_SYNTH3_WAIT_VC_CHECK_LSB                                                                   0
-#define PHY_ANALOG_SYNTH3_WAIT_VC_CHECK_MASK                                                         0x0000003f
-#define PHY_ANALOG_SYNTH3_WAIT_VC_CHECK_GET(x)                                        (((x) & 0x0000003f) >> 0)
-#define PHY_ANALOG_SYNTH3_WAIT_VC_CHECK_SET(x)                                        (((x) << 0) & 0x0000003f)
-#define PHY_ANALOG_SYNTH3_WAIT_CAL_LIN_MSB                                                                   11
-#define PHY_ANALOG_SYNTH3_WAIT_CAL_LIN_LSB                                                                    6
-#define PHY_ANALOG_SYNTH3_WAIT_CAL_LIN_MASK                                                          0x00000fc0
-#define PHY_ANALOG_SYNTH3_WAIT_CAL_LIN_GET(x)                                         (((x) & 0x00000fc0) >> 6)
-#define PHY_ANALOG_SYNTH3_WAIT_CAL_LIN_SET(x)                                         (((x) << 6) & 0x00000fc0)
-#define PHY_ANALOG_SYNTH3_WAIT_CAL_BIN_MSB                                                                   17
-#define PHY_ANALOG_SYNTH3_WAIT_CAL_BIN_LSB                                                                   12
-#define PHY_ANALOG_SYNTH3_WAIT_CAL_BIN_MASK                                                          0x0003f000
-#define PHY_ANALOG_SYNTH3_WAIT_CAL_BIN_GET(x)                                        (((x) & 0x0003f000) >> 12)
-#define PHY_ANALOG_SYNTH3_WAIT_CAL_BIN_SET(x)                                        (((x) << 12) & 0x0003f000)
-#define PHY_ANALOG_SYNTH3_WAIT_PWRUP_MSB                                                                     23
-#define PHY_ANALOG_SYNTH3_WAIT_PWRUP_LSB                                                                     18
-#define PHY_ANALOG_SYNTH3_WAIT_PWRUP_MASK                                                            0x00fc0000
-#define PHY_ANALOG_SYNTH3_WAIT_PWRUP_GET(x)                                          (((x) & 0x00fc0000) >> 18)
-#define PHY_ANALOG_SYNTH3_WAIT_PWRUP_SET(x)                                          (((x) << 18) & 0x00fc0000)
-#define PHY_ANALOG_SYNTH3_WAIT_SHORTR_PWRUP_MSB                                                              29
-#define PHY_ANALOG_SYNTH3_WAIT_SHORTR_PWRUP_LSB                                                              24
-#define PHY_ANALOG_SYNTH3_WAIT_SHORTR_PWRUP_MASK                                                     0x3f000000
-#define PHY_ANALOG_SYNTH3_WAIT_SHORTR_PWRUP_GET(x)                                   (((x) & 0x3f000000) >> 24)
-#define PHY_ANALOG_SYNTH3_WAIT_SHORTR_PWRUP_SET(x)                                   (((x) << 24) & 0x3f000000)
-#define PHY_ANALOG_SYNTH3_SEL_CLK_DIV2_MSB                                                                   30
-#define PHY_ANALOG_SYNTH3_SEL_CLK_DIV2_LSB                                                                   30
-#define PHY_ANALOG_SYNTH3_SEL_CLK_DIV2_MASK                                                          0x40000000
-#define PHY_ANALOG_SYNTH3_SEL_CLK_DIV2_GET(x)                                        (((x) & 0x40000000) >> 30)
-#define PHY_ANALOG_SYNTH3_SEL_CLK_DIV2_SET(x)                                        (((x) << 30) & 0x40000000)
-#define PHY_ANALOG_SYNTH3_DIS_CLK_XTAL_MSB                                                                   31
-#define PHY_ANALOG_SYNTH3_DIS_CLK_XTAL_LSB                                                                   31
-#define PHY_ANALOG_SYNTH3_DIS_CLK_XTAL_MASK                                                          0x80000000
-#define PHY_ANALOG_SYNTH3_DIS_CLK_XTAL_GET(x)                                        (((x) & 0x80000000) >> 31)
-#define PHY_ANALOG_SYNTH3_DIS_CLK_XTAL_SET(x)                                        (((x) << 31) & 0x80000000)
-
-/* macros for SYNTH4 */
-#define PHY_ANALOG_SYNTH4_ADDRESS                                                                    0x0000008c
-#define PHY_ANALOG_SYNTH4_OFFSET                                                                     0x0000008c
-#define PHY_ANALOG_SYNTH4_PS_SINGLE_PULSE_MSB                                                                 0
-#define PHY_ANALOG_SYNTH4_PS_SINGLE_PULSE_LSB                                                                 0
-#define PHY_ANALOG_SYNTH4_PS_SINGLE_PULSE_MASK                                                       0x00000001
-#define PHY_ANALOG_SYNTH4_PS_SINGLE_PULSE_GET(x)                                      (((x) & 0x00000001) >> 0)
-#define PHY_ANALOG_SYNTH4_PS_SINGLE_PULSE_SET(x)                                      (((x) << 0) & 0x00000001)
-#define PHY_ANALOG_SYNTH4_LONGSHIFTSEL_MSB                                                                    1
-#define PHY_ANALOG_SYNTH4_LONGSHIFTSEL_LSB                                                                    1
-#define PHY_ANALOG_SYNTH4_LONGSHIFTSEL_MASK                                                          0x00000002
-#define PHY_ANALOG_SYNTH4_LONGSHIFTSEL_GET(x)                                         (((x) & 0x00000002) >> 1)
-#define PHY_ANALOG_SYNTH4_LONGSHIFTSEL_SET(x)                                         (((x) << 1) & 0x00000002)
-#define PHY_ANALOG_SYNTH4_LOBUF5GTUNE_OVR_MSB                                                                 3
-#define PHY_ANALOG_SYNTH4_LOBUF5GTUNE_OVR_LSB                                                                 2
-#define PHY_ANALOG_SYNTH4_LOBUF5GTUNE_OVR_MASK                                                       0x0000000c
-#define PHY_ANALOG_SYNTH4_LOBUF5GTUNE_OVR_GET(x)                                      (((x) & 0x0000000c) >> 2)
-#define PHY_ANALOG_SYNTH4_LOBUF5GTUNE_OVR_SET(x)                                      (((x) << 2) & 0x0000000c)
-#define PHY_ANALOG_SYNTH4_FORCE_LOBUF5GTUNE_MSB                                                               4
-#define PHY_ANALOG_SYNTH4_FORCE_LOBUF5GTUNE_LSB                                                               4
-#define PHY_ANALOG_SYNTH4_FORCE_LOBUF5GTUNE_MASK                                                     0x00000010
-#define PHY_ANALOG_SYNTH4_FORCE_LOBUF5GTUNE_GET(x)                                    (((x) & 0x00000010) >> 4)
-#define PHY_ANALOG_SYNTH4_FORCE_LOBUF5GTUNE_SET(x)                                    (((x) << 4) & 0x00000010)
-#define PHY_ANALOG_SYNTH4_PSCOUNT_FBSEL_MSB                                                                   5
-#define PHY_ANALOG_SYNTH4_PSCOUNT_FBSEL_LSB                                                                   5
-#define PHY_ANALOG_SYNTH4_PSCOUNT_FBSEL_MASK                                                         0x00000020
-#define PHY_ANALOG_SYNTH4_PSCOUNT_FBSEL_GET(x)                                        (((x) & 0x00000020) >> 5)
-#define PHY_ANALOG_SYNTH4_PSCOUNT_FBSEL_SET(x)                                        (((x) << 5) & 0x00000020)
-#define PHY_ANALOG_SYNTH4_SDM_DITHER1_MSB                                                                     7
-#define PHY_ANALOG_SYNTH4_SDM_DITHER1_LSB                                                                     6
-#define PHY_ANALOG_SYNTH4_SDM_DITHER1_MASK                                                           0x000000c0
-#define PHY_ANALOG_SYNTH4_SDM_DITHER1_GET(x)                                          (((x) & 0x000000c0) >> 6)
-#define PHY_ANALOG_SYNTH4_SDM_DITHER1_SET(x)                                          (((x) << 6) & 0x000000c0)
-#define PHY_ANALOG_SYNTH4_SDM_MODE_MSB                                                                        8
-#define PHY_ANALOG_SYNTH4_SDM_MODE_LSB                                                                        8
-#define PHY_ANALOG_SYNTH4_SDM_MODE_MASK                                                              0x00000100
-#define PHY_ANALOG_SYNTH4_SDM_MODE_GET(x)                                             (((x) & 0x00000100) >> 8)
-#define PHY_ANALOG_SYNTH4_SDM_MODE_SET(x)                                             (((x) << 8) & 0x00000100)
-#define PHY_ANALOG_SYNTH4_SDM_DISABLE_MSB                                                                     9
-#define PHY_ANALOG_SYNTH4_SDM_DISABLE_LSB                                                                     9
-#define PHY_ANALOG_SYNTH4_SDM_DISABLE_MASK                                                           0x00000200
-#define PHY_ANALOG_SYNTH4_SDM_DISABLE_GET(x)                                          (((x) & 0x00000200) >> 9)
-#define PHY_ANALOG_SYNTH4_SDM_DISABLE_SET(x)                                          (((x) << 9) & 0x00000200)
-#define PHY_ANALOG_SYNTH4_RESET_PRESC_MSB                                                                    10
-#define PHY_ANALOG_SYNTH4_RESET_PRESC_LSB                                                                    10
-#define PHY_ANALOG_SYNTH4_RESET_PRESC_MASK                                                           0x00000400
-#define PHY_ANALOG_SYNTH4_RESET_PRESC_GET(x)                                         (((x) & 0x00000400) >> 10)
-#define PHY_ANALOG_SYNTH4_RESET_PRESC_SET(x)                                         (((x) << 10) & 0x00000400)
-#define PHY_ANALOG_SYNTH4_PRESCSEL_MSB                                                                       12
-#define PHY_ANALOG_SYNTH4_PRESCSEL_LSB                                                                       11
-#define PHY_ANALOG_SYNTH4_PRESCSEL_MASK                                                              0x00001800
-#define PHY_ANALOG_SYNTH4_PRESCSEL_GET(x)                                            (((x) & 0x00001800) >> 11)
-#define PHY_ANALOG_SYNTH4_PRESCSEL_SET(x)                                            (((x) << 11) & 0x00001800)
-#define PHY_ANALOG_SYNTH4_PFD_DISABLE_MSB                                                                    13
-#define PHY_ANALOG_SYNTH4_PFD_DISABLE_LSB                                                                    13
-#define PHY_ANALOG_SYNTH4_PFD_DISABLE_MASK                                                           0x00002000
-#define PHY_ANALOG_SYNTH4_PFD_DISABLE_GET(x)                                         (((x) & 0x00002000) >> 13)
-#define PHY_ANALOG_SYNTH4_PFD_DISABLE_SET(x)                                         (((x) << 13) & 0x00002000)
-#define PHY_ANALOG_SYNTH4_PFDDELAY_FRACN_MSB                                                                 14
-#define PHY_ANALOG_SYNTH4_PFDDELAY_FRACN_LSB                                                                 14
-#define PHY_ANALOG_SYNTH4_PFDDELAY_FRACN_MASK                                                        0x00004000
-#define PHY_ANALOG_SYNTH4_PFDDELAY_FRACN_GET(x)                                      (((x) & 0x00004000) >> 14)
-#define PHY_ANALOG_SYNTH4_PFDDELAY_FRACN_SET(x)                                      (((x) << 14) & 0x00004000)
-#define PHY_ANALOG_SYNTH4_FORCE_LO_ON_MSB                                                                    15
-#define PHY_ANALOG_SYNTH4_FORCE_LO_ON_LSB                                                                    15
-#define PHY_ANALOG_SYNTH4_FORCE_LO_ON_MASK                                                           0x00008000
-#define PHY_ANALOG_SYNTH4_FORCE_LO_ON_GET(x)                                         (((x) & 0x00008000) >> 15)
-#define PHY_ANALOG_SYNTH4_FORCE_LO_ON_SET(x)                                         (((x) << 15) & 0x00008000)
-#define PHY_ANALOG_SYNTH4_CLKXTAL_EDGE_SEL_MSB                                                               16
-#define PHY_ANALOG_SYNTH4_CLKXTAL_EDGE_SEL_LSB                                                               16
-#define PHY_ANALOG_SYNTH4_CLKXTAL_EDGE_SEL_MASK                                                      0x00010000
-#define PHY_ANALOG_SYNTH4_CLKXTAL_EDGE_SEL_GET(x)                                    (((x) & 0x00010000) >> 16)
-#define PHY_ANALOG_SYNTH4_CLKXTAL_EDGE_SEL_SET(x)                                    (((x) << 16) & 0x00010000)
-#define PHY_ANALOG_SYNTH4_VCOCAPPULLUP_MSB                                                                   17
-#define PHY_ANALOG_SYNTH4_VCOCAPPULLUP_LSB                                                                   17
-#define PHY_ANALOG_SYNTH4_VCOCAPPULLUP_MASK                                                          0x00020000
-#define PHY_ANALOG_SYNTH4_VCOCAPPULLUP_GET(x)                                        (((x) & 0x00020000) >> 17)
-#define PHY_ANALOG_SYNTH4_VCOCAPPULLUP_SET(x)                                        (((x) << 17) & 0x00020000)
-#define PHY_ANALOG_SYNTH4_VCOCAP_OVR_MSB                                                                     25
-#define PHY_ANALOG_SYNTH4_VCOCAP_OVR_LSB                                                                     18
-#define PHY_ANALOG_SYNTH4_VCOCAP_OVR_MASK                                                            0x03fc0000
-#define PHY_ANALOG_SYNTH4_VCOCAP_OVR_GET(x)                                          (((x) & 0x03fc0000) >> 18)
-#define PHY_ANALOG_SYNTH4_VCOCAP_OVR_SET(x)                                          (((x) << 18) & 0x03fc0000)
-#define PHY_ANALOG_SYNTH4_FORCE_VCOCAP_MSB                                                                   26
-#define PHY_ANALOG_SYNTH4_FORCE_VCOCAP_LSB                                                                   26
-#define PHY_ANALOG_SYNTH4_FORCE_VCOCAP_MASK                                                          0x04000000
-#define PHY_ANALOG_SYNTH4_FORCE_VCOCAP_GET(x)                                        (((x) & 0x04000000) >> 26)
-#define PHY_ANALOG_SYNTH4_FORCE_VCOCAP_SET(x)                                        (((x) << 26) & 0x04000000)
-#define PHY_ANALOG_SYNTH4_FORCE_PINVC_MSB                                                                    27
-#define PHY_ANALOG_SYNTH4_FORCE_PINVC_LSB                                                                    27
-#define PHY_ANALOG_SYNTH4_FORCE_PINVC_MASK                                                           0x08000000
-#define PHY_ANALOG_SYNTH4_FORCE_PINVC_GET(x)                                         (((x) & 0x08000000) >> 27)
-#define PHY_ANALOG_SYNTH4_FORCE_PINVC_SET(x)                                         (((x) << 27) & 0x08000000)
-#define PHY_ANALOG_SYNTH4_SHORTR_UNTIL_LOCKED_MSB                                                            28
-#define PHY_ANALOG_SYNTH4_SHORTR_UNTIL_LOCKED_LSB                                                            28
-#define PHY_ANALOG_SYNTH4_SHORTR_UNTIL_LOCKED_MASK                                                   0x10000000
-#define PHY_ANALOG_SYNTH4_SHORTR_UNTIL_LOCKED_GET(x)                                 (((x) & 0x10000000) >> 28)
-#define PHY_ANALOG_SYNTH4_SHORTR_UNTIL_LOCKED_SET(x)                                 (((x) << 28) & 0x10000000)
-#define PHY_ANALOG_SYNTH4_ALWAYS_SHORTR_MSB                                                                  29
-#define PHY_ANALOG_SYNTH4_ALWAYS_SHORTR_LSB                                                                  29
-#define PHY_ANALOG_SYNTH4_ALWAYS_SHORTR_MASK                                                         0x20000000
-#define PHY_ANALOG_SYNTH4_ALWAYS_SHORTR_GET(x)                                       (((x) & 0x20000000) >> 29)
-#define PHY_ANALOG_SYNTH4_ALWAYS_SHORTR_SET(x)                                       (((x) << 29) & 0x20000000)
-#define PHY_ANALOG_SYNTH4_DIS_LOSTVC_MSB                                                                     30
-#define PHY_ANALOG_SYNTH4_DIS_LOSTVC_LSB                                                                     30
-#define PHY_ANALOG_SYNTH4_DIS_LOSTVC_MASK                                                            0x40000000
-#define PHY_ANALOG_SYNTH4_DIS_LOSTVC_GET(x)                                          (((x) & 0x40000000) >> 30)
-#define PHY_ANALOG_SYNTH4_DIS_LOSTVC_SET(x)                                          (((x) << 30) & 0x40000000)
-#define PHY_ANALOG_SYNTH4_DIS_LIN_CAPSEARCH_MSB                                                              31
-#define PHY_ANALOG_SYNTH4_DIS_LIN_CAPSEARCH_LSB                                                              31
-#define PHY_ANALOG_SYNTH4_DIS_LIN_CAPSEARCH_MASK                                                     0x80000000
-#define PHY_ANALOG_SYNTH4_DIS_LIN_CAPSEARCH_GET(x)                                   (((x) & 0x80000000) >> 31)
-#define PHY_ANALOG_SYNTH4_DIS_LIN_CAPSEARCH_SET(x)                                   (((x) << 31) & 0x80000000)
-
-/* macros for SYNTH5 */
-#define PHY_ANALOG_SYNTH5_ADDRESS                                                                    0x00000090
-#define PHY_ANALOG_SYNTH5_OFFSET                                                                     0x00000090
-#define PHY_ANALOG_SYNTH5_VCOBIAS_MSB                                                                         1
-#define PHY_ANALOG_SYNTH5_VCOBIAS_LSB                                                                         0
-#define PHY_ANALOG_SYNTH5_VCOBIAS_MASK                                                               0x00000003
-#define PHY_ANALOG_SYNTH5_VCOBIAS_GET(x)                                              (((x) & 0x00000003) >> 0)
-#define PHY_ANALOG_SYNTH5_VCOBIAS_SET(x)                                              (((x) << 0) & 0x00000003)
-#define PHY_ANALOG_SYNTH5_PWDB_ICLOBUF5G50_MSB                                                                4
-#define PHY_ANALOG_SYNTH5_PWDB_ICLOBUF5G50_LSB                                                                2
-#define PHY_ANALOG_SYNTH5_PWDB_ICLOBUF5G50_MASK                                                      0x0000001c
-#define PHY_ANALOG_SYNTH5_PWDB_ICLOBUF5G50_GET(x)                                     (((x) & 0x0000001c) >> 2)
-#define PHY_ANALOG_SYNTH5_PWDB_ICLOBUF5G50_SET(x)                                     (((x) << 2) & 0x0000001c)
-#define PHY_ANALOG_SYNTH5_PWDB_ICLOBUF2G50_MSB                                                                7
-#define PHY_ANALOG_SYNTH5_PWDB_ICLOBUF2G50_LSB                                                                5
-#define PHY_ANALOG_SYNTH5_PWDB_ICLOBUF2G50_MASK                                                      0x000000e0
-#define PHY_ANALOG_SYNTH5_PWDB_ICLOBUF2G50_GET(x)                                     (((x) & 0x000000e0) >> 5)
-#define PHY_ANALOG_SYNTH5_PWDB_ICLOBUF2G50_SET(x)                                     (((x) << 5) & 0x000000e0)
-#define PHY_ANALOG_SYNTH5_PWDB_ICVCO25_MSB                                                                   10
-#define PHY_ANALOG_SYNTH5_PWDB_ICVCO25_LSB                                                                    8
-#define PHY_ANALOG_SYNTH5_PWDB_ICVCO25_MASK                                                          0x00000700
-#define PHY_ANALOG_SYNTH5_PWDB_ICVCO25_GET(x)                                         (((x) & 0x00000700) >> 8)
-#define PHY_ANALOG_SYNTH5_PWDB_ICVCO25_SET(x)                                         (((x) << 8) & 0x00000700)
-#define PHY_ANALOG_SYNTH5_PWDB_ICVCOREG25_MSB                                                                13
-#define PHY_ANALOG_SYNTH5_PWDB_ICVCOREG25_LSB                                                                11
-#define PHY_ANALOG_SYNTH5_PWDB_ICVCOREG25_MASK                                                       0x00003800
-#define PHY_ANALOG_SYNTH5_PWDB_ICVCOREG25_GET(x)                                     (((x) & 0x00003800) >> 11)
-#define PHY_ANALOG_SYNTH5_PWDB_ICVCOREG25_SET(x)                                     (((x) << 11) & 0x00003800)
-#define PHY_ANALOG_SYNTH5_PWDB_IRVCOREG50_MSB                                                                14
-#define PHY_ANALOG_SYNTH5_PWDB_IRVCOREG50_LSB                                                                14
-#define PHY_ANALOG_SYNTH5_PWDB_IRVCOREG50_MASK                                                       0x00004000
-#define PHY_ANALOG_SYNTH5_PWDB_IRVCOREG50_GET(x)                                     (((x) & 0x00004000) >> 14)
-#define PHY_ANALOG_SYNTH5_PWDB_IRVCOREG50_SET(x)                                     (((x) << 14) & 0x00004000)
-#define PHY_ANALOG_SYNTH5_PWDB_ICLOMIX_MSB                                                                   17
-#define PHY_ANALOG_SYNTH5_PWDB_ICLOMIX_LSB                                                                   15
-#define PHY_ANALOG_SYNTH5_PWDB_ICLOMIX_MASK                                                          0x00038000
-#define PHY_ANALOG_SYNTH5_PWDB_ICLOMIX_GET(x)                                        (((x) & 0x00038000) >> 15)
-#define PHY_ANALOG_SYNTH5_PWDB_ICLOMIX_SET(x)                                        (((x) << 15) & 0x00038000)
-#define PHY_ANALOG_SYNTH5_PWDB_ICLODIV50_MSB                                                                 20
-#define PHY_ANALOG_SYNTH5_PWDB_ICLODIV50_LSB                                                                 18
-#define PHY_ANALOG_SYNTH5_PWDB_ICLODIV50_MASK                                                        0x001c0000
-#define PHY_ANALOG_SYNTH5_PWDB_ICLODIV50_GET(x)                                      (((x) & 0x001c0000) >> 18)
-#define PHY_ANALOG_SYNTH5_PWDB_ICLODIV50_SET(x)                                      (((x) << 18) & 0x001c0000)
-#define PHY_ANALOG_SYNTH5_PWDB_ICPRESC50_MSB                                                                 23
-#define PHY_ANALOG_SYNTH5_PWDB_ICPRESC50_LSB                                                                 21
-#define PHY_ANALOG_SYNTH5_PWDB_ICPRESC50_MASK                                                        0x00e00000
-#define PHY_ANALOG_SYNTH5_PWDB_ICPRESC50_GET(x)                                      (((x) & 0x00e00000) >> 21)
-#define PHY_ANALOG_SYNTH5_PWDB_ICPRESC50_SET(x)                                      (((x) << 21) & 0x00e00000)
-#define PHY_ANALOG_SYNTH5_PWDB_IRVCMON25_MSB                                                                 26
-#define PHY_ANALOG_SYNTH5_PWDB_IRVCMON25_LSB                                                                 24
-#define PHY_ANALOG_SYNTH5_PWDB_IRVCMON25_MASK                                                        0x07000000
-#define PHY_ANALOG_SYNTH5_PWDB_IRVCMON25_GET(x)                                      (((x) & 0x07000000) >> 24)
-#define PHY_ANALOG_SYNTH5_PWDB_IRVCMON25_SET(x)                                      (((x) << 24) & 0x07000000)
-#define PHY_ANALOG_SYNTH5_PWDB_IRPFDCP_MSB                                                                   29
-#define PHY_ANALOG_SYNTH5_PWDB_IRPFDCP_LSB                                                                   27
-#define PHY_ANALOG_SYNTH5_PWDB_IRPFDCP_MASK                                                          0x38000000
-#define PHY_ANALOG_SYNTH5_PWDB_IRPFDCP_GET(x)                                        (((x) & 0x38000000) >> 27)
-#define PHY_ANALOG_SYNTH5_PWDB_IRPFDCP_SET(x)                                        (((x) << 27) & 0x38000000)
-#define PHY_ANALOG_SYNTH5_SDM_DITHER2_MSB                                                                    31
-#define PHY_ANALOG_SYNTH5_SDM_DITHER2_LSB                                                                    30
-#define PHY_ANALOG_SYNTH5_SDM_DITHER2_MASK                                                           0xc0000000
-#define PHY_ANALOG_SYNTH5_SDM_DITHER2_GET(x)                                         (((x) & 0xc0000000) >> 30)
-#define PHY_ANALOG_SYNTH5_SDM_DITHER2_SET(x)                                         (((x) << 30) & 0xc0000000)
-
-/* macros for SYNTH6 */
-#define PHY_ANALOG_SYNTH6_ADDRESS                                                                    0x00000094
-#define PHY_ANALOG_SYNTH6_OFFSET                                                                     0x00000094
-#define PHY_ANALOG_SYNTH6_LOBUF5GTUNE_MSB                                                                     1
-#define PHY_ANALOG_SYNTH6_LOBUF5GTUNE_LSB                                                                     0
-#define PHY_ANALOG_SYNTH6_LOBUF5GTUNE_MASK                                                           0x00000003
-#define PHY_ANALOG_SYNTH6_LOBUF5GTUNE_GET(x)                                          (((x) & 0x00000003) >> 0)
-#define PHY_ANALOG_SYNTH6_LOOP_IP_MSB                                                                         8
-#define PHY_ANALOG_SYNTH6_LOOP_IP_LSB                                                                         2
-#define PHY_ANALOG_SYNTH6_LOOP_IP_MASK                                                               0x000001fc
-#define PHY_ANALOG_SYNTH6_LOOP_IP_GET(x)                                              (((x) & 0x000001fc) >> 2)
-#define PHY_ANALOG_SYNTH6_VC2LOW_MSB                                                                          9
-#define PHY_ANALOG_SYNTH6_VC2LOW_LSB                                                                          9
-#define PHY_ANALOG_SYNTH6_VC2LOW_MASK                                                                0x00000200
-#define PHY_ANALOG_SYNTH6_VC2LOW_GET(x)                                               (((x) & 0x00000200) >> 9)
-#define PHY_ANALOG_SYNTH6_VC2HIGH_MSB                                                                        10
-#define PHY_ANALOG_SYNTH6_VC2HIGH_LSB                                                                        10
-#define PHY_ANALOG_SYNTH6_VC2HIGH_MASK                                                               0x00000400
-#define PHY_ANALOG_SYNTH6_VC2HIGH_GET(x)                                             (((x) & 0x00000400) >> 10)
-#define PHY_ANALOG_SYNTH6_RESET_SDM_B_MSB                                                                    11
-#define PHY_ANALOG_SYNTH6_RESET_SDM_B_LSB                                                                    11
-#define PHY_ANALOG_SYNTH6_RESET_SDM_B_MASK                                                           0x00000800
-#define PHY_ANALOG_SYNTH6_RESET_SDM_B_GET(x)                                         (((x) & 0x00000800) >> 11)
-#define PHY_ANALOG_SYNTH6_RESET_PSCOUNTERS_MSB                                                               12
-#define PHY_ANALOG_SYNTH6_RESET_PSCOUNTERS_LSB                                                               12
-#define PHY_ANALOG_SYNTH6_RESET_PSCOUNTERS_MASK                                                      0x00001000
-#define PHY_ANALOG_SYNTH6_RESET_PSCOUNTERS_GET(x)                                    (((x) & 0x00001000) >> 12)
-#define PHY_ANALOG_SYNTH6_RESET_PFD_MSB                                                                      13
-#define PHY_ANALOG_SYNTH6_RESET_PFD_LSB                                                                      13
-#define PHY_ANALOG_SYNTH6_RESET_PFD_MASK                                                             0x00002000
-#define PHY_ANALOG_SYNTH6_RESET_PFD_GET(x)                                           (((x) & 0x00002000) >> 13)
-#define PHY_ANALOG_SYNTH6_RESET_RFD_MSB                                                                      14
-#define PHY_ANALOG_SYNTH6_RESET_RFD_LSB                                                                      14
-#define PHY_ANALOG_SYNTH6_RESET_RFD_MASK                                                             0x00004000
-#define PHY_ANALOG_SYNTH6_RESET_RFD_GET(x)                                           (((x) & 0x00004000) >> 14)
-#define PHY_ANALOG_SYNTH6_SHORT_R_MSB                                                                        15
-#define PHY_ANALOG_SYNTH6_SHORT_R_LSB                                                                        15
-#define PHY_ANALOG_SYNTH6_SHORT_R_MASK                                                               0x00008000
-#define PHY_ANALOG_SYNTH6_SHORT_R_GET(x)                                             (((x) & 0x00008000) >> 15)
-#define PHY_ANALOG_SYNTH6_VCO_CAP_ST_MSB                                                                     23
-#define PHY_ANALOG_SYNTH6_VCO_CAP_ST_LSB                                                                     16
-#define PHY_ANALOG_SYNTH6_VCO_CAP_ST_MASK                                                            0x00ff0000
-#define PHY_ANALOG_SYNTH6_VCO_CAP_ST_GET(x)                                          (((x) & 0x00ff0000) >> 16)
-#define PHY_ANALOG_SYNTH6_PIN_VC_MSB                                                                         24
-#define PHY_ANALOG_SYNTH6_PIN_VC_LSB                                                                         24
-#define PHY_ANALOG_SYNTH6_PIN_VC_MASK                                                                0x01000000
-#define PHY_ANALOG_SYNTH6_PIN_VC_GET(x)                                              (((x) & 0x01000000) >> 24)
-#define PHY_ANALOG_SYNTH6_SYNTH_LOCK_VC_OK_MSB                                                               25
-#define PHY_ANALOG_SYNTH6_SYNTH_LOCK_VC_OK_LSB                                                               25
-#define PHY_ANALOG_SYNTH6_SYNTH_LOCK_VC_OK_MASK                                                      0x02000000
-#define PHY_ANALOG_SYNTH6_SYNTH_LOCK_VC_OK_GET(x)                                    (((x) & 0x02000000) >> 25)
-#define PHY_ANALOG_SYNTH6_CAP_SEARCH_MSB                                                                     26
-#define PHY_ANALOG_SYNTH6_CAP_SEARCH_LSB                                                                     26
-#define PHY_ANALOG_SYNTH6_CAP_SEARCH_MASK                                                            0x04000000
-#define PHY_ANALOG_SYNTH6_CAP_SEARCH_GET(x)                                          (((x) & 0x04000000) >> 26)
-#define PHY_ANALOG_SYNTH6_SYNTH_SM_STATE_MSB                                                                 30
-#define PHY_ANALOG_SYNTH6_SYNTH_SM_STATE_LSB                                                                 27
-#define PHY_ANALOG_SYNTH6_SYNTH_SM_STATE_MASK                                                        0x78000000
-#define PHY_ANALOG_SYNTH6_SYNTH_SM_STATE_GET(x)                                      (((x) & 0x78000000) >> 27)
-#define PHY_ANALOG_SYNTH6_SYNTH_ON_MSB                                                                       31
-#define PHY_ANALOG_SYNTH6_SYNTH_ON_LSB                                                                       31
-#define PHY_ANALOG_SYNTH6_SYNTH_ON_MASK                                                              0x80000000
-#define PHY_ANALOG_SYNTH6_SYNTH_ON_GET(x)                                            (((x) & 0x80000000) >> 31)
-
-/* macros for SYNTH7 */
-#define PHY_ANALOG_SYNTH7_ADDRESS                                                                    0x00000098
-#define PHY_ANALOG_SYNTH7_OFFSET                                                                     0x00000098
-#define PHY_ANALOG_SYNTH7_OVRCHANDECODER_MSB                                                                  0
-#define PHY_ANALOG_SYNTH7_OVRCHANDECODER_LSB                                                                  0
-#define PHY_ANALOG_SYNTH7_OVRCHANDECODER_MASK                                                        0x00000001
-#define PHY_ANALOG_SYNTH7_OVRCHANDECODER_GET(x)                                       (((x) & 0x00000001) >> 0)
-#define PHY_ANALOG_SYNTH7_OVRCHANDECODER_SET(x)                                       (((x) << 0) & 0x00000001)
-#define PHY_ANALOG_SYNTH7_FORCE_FRACLSB_MSB                                                                   1
-#define PHY_ANALOG_SYNTH7_FORCE_FRACLSB_LSB                                                                   1
-#define PHY_ANALOG_SYNTH7_FORCE_FRACLSB_MASK                                                         0x00000002
-#define PHY_ANALOG_SYNTH7_FORCE_FRACLSB_GET(x)                                        (((x) & 0x00000002) >> 1)
-#define PHY_ANALOG_SYNTH7_FORCE_FRACLSB_SET(x)                                        (((x) << 1) & 0x00000002)
-#define PHY_ANALOG_SYNTH7_CHANFRAC_MSB                                                                       18
-#define PHY_ANALOG_SYNTH7_CHANFRAC_LSB                                                                        2
-#define PHY_ANALOG_SYNTH7_CHANFRAC_MASK                                                              0x0007fffc
-#define PHY_ANALOG_SYNTH7_CHANFRAC_GET(x)                                             (((x) & 0x0007fffc) >> 2)
-#define PHY_ANALOG_SYNTH7_CHANFRAC_SET(x)                                             (((x) << 2) & 0x0007fffc)
-#define PHY_ANALOG_SYNTH7_CHANSEL_MSB                                                                        27
-#define PHY_ANALOG_SYNTH7_CHANSEL_LSB                                                                        19
-#define PHY_ANALOG_SYNTH7_CHANSEL_MASK                                                               0x0ff80000
-#define PHY_ANALOG_SYNTH7_CHANSEL_GET(x)                                             (((x) & 0x0ff80000) >> 19)
-#define PHY_ANALOG_SYNTH7_CHANSEL_SET(x)                                             (((x) << 19) & 0x0ff80000)
-#define PHY_ANALOG_SYNTH7_AMODEREFSEL_MSB                                                                    29
-#define PHY_ANALOG_SYNTH7_AMODEREFSEL_LSB                                                                    28
-#define PHY_ANALOG_SYNTH7_AMODEREFSEL_MASK                                                           0x30000000
-#define PHY_ANALOG_SYNTH7_AMODEREFSEL_GET(x)                                         (((x) & 0x30000000) >> 28)
-#define PHY_ANALOG_SYNTH7_AMODEREFSEL_SET(x)                                         (((x) << 28) & 0x30000000)
-#define PHY_ANALOG_SYNTH7_FRACMODE_MSB                                                                       30
-#define PHY_ANALOG_SYNTH7_FRACMODE_LSB                                                                       30
-#define PHY_ANALOG_SYNTH7_FRACMODE_MASK                                                              0x40000000
-#define PHY_ANALOG_SYNTH7_FRACMODE_GET(x)                                            (((x) & 0x40000000) >> 30)
-#define PHY_ANALOG_SYNTH7_FRACMODE_SET(x)                                            (((x) << 30) & 0x40000000)
-#define PHY_ANALOG_SYNTH7_LOADSYNTHCHANNEL_MSB                                                               31
-#define PHY_ANALOG_SYNTH7_LOADSYNTHCHANNEL_LSB                                                               31
-#define PHY_ANALOG_SYNTH7_LOADSYNTHCHANNEL_MASK                                                      0x80000000
-#define PHY_ANALOG_SYNTH7_LOADSYNTHCHANNEL_GET(x)                                    (((x) & 0x80000000) >> 31)
-#define PHY_ANALOG_SYNTH7_LOADSYNTHCHANNEL_SET(x)                                    (((x) << 31) & 0x80000000)
-
-/* macros for SYNTH8 */
-#define PHY_ANALOG_SYNTH8_ADDRESS                                                                    0x0000009c
-#define PHY_ANALOG_SYNTH8_OFFSET                                                                     0x0000009c
-#define PHY_ANALOG_SYNTH8_CPSTEERING_EN_FRACN_MSB                                                             0
-#define PHY_ANALOG_SYNTH8_CPSTEERING_EN_FRACN_LSB                                                             0
-#define PHY_ANALOG_SYNTH8_CPSTEERING_EN_FRACN_MASK                                                   0x00000001
-#define PHY_ANALOG_SYNTH8_CPSTEERING_EN_FRACN_GET(x)                                  (((x) & 0x00000001) >> 0)
-#define PHY_ANALOG_SYNTH8_CPSTEERING_EN_FRACN_SET(x)                                  (((x) << 0) & 0x00000001)
-#define PHY_ANALOG_SYNTH8_LOOP_ICPB_MSB                                                                       7
-#define PHY_ANALOG_SYNTH8_LOOP_ICPB_LSB                                                                       1
-#define PHY_ANALOG_SYNTH8_LOOP_ICPB_MASK                                                             0x000000fe
-#define PHY_ANALOG_SYNTH8_LOOP_ICPB_GET(x)                                            (((x) & 0x000000fe) >> 1)
-#define PHY_ANALOG_SYNTH8_LOOP_ICPB_SET(x)                                            (((x) << 1) & 0x000000fe)
-#define PHY_ANALOG_SYNTH8_LOOP_CSB_MSB                                                                       11
-#define PHY_ANALOG_SYNTH8_LOOP_CSB_LSB                                                                        8
-#define PHY_ANALOG_SYNTH8_LOOP_CSB_MASK                                                              0x00000f00
-#define PHY_ANALOG_SYNTH8_LOOP_CSB_GET(x)                                             (((x) & 0x00000f00) >> 8)
-#define PHY_ANALOG_SYNTH8_LOOP_CSB_SET(x)                                             (((x) << 8) & 0x00000f00)
-#define PHY_ANALOG_SYNTH8_LOOP_RSB_MSB                                                                       16
-#define PHY_ANALOG_SYNTH8_LOOP_RSB_LSB                                                                       12
-#define PHY_ANALOG_SYNTH8_LOOP_RSB_MASK                                                              0x0001f000
-#define PHY_ANALOG_SYNTH8_LOOP_RSB_GET(x)                                            (((x) & 0x0001f000) >> 12)
-#define PHY_ANALOG_SYNTH8_LOOP_RSB_SET(x)                                            (((x) << 12) & 0x0001f000)
-#define PHY_ANALOG_SYNTH8_LOOP_CPB_MSB                                                                       21
-#define PHY_ANALOG_SYNTH8_LOOP_CPB_LSB                                                                       17
-#define PHY_ANALOG_SYNTH8_LOOP_CPB_MASK                                                              0x003e0000
-#define PHY_ANALOG_SYNTH8_LOOP_CPB_GET(x)                                            (((x) & 0x003e0000) >> 17)
-#define PHY_ANALOG_SYNTH8_LOOP_CPB_SET(x)                                            (((x) << 17) & 0x003e0000)
-#define PHY_ANALOG_SYNTH8_LOOP_3RD_ORDER_RB_MSB                                                              26
-#define PHY_ANALOG_SYNTH8_LOOP_3RD_ORDER_RB_LSB                                                              22
-#define PHY_ANALOG_SYNTH8_LOOP_3RD_ORDER_RB_MASK                                                     0x07c00000
-#define PHY_ANALOG_SYNTH8_LOOP_3RD_ORDER_RB_GET(x)                                   (((x) & 0x07c00000) >> 22)
-#define PHY_ANALOG_SYNTH8_LOOP_3RD_ORDER_RB_SET(x)                                   (((x) << 22) & 0x07c00000)
-#define PHY_ANALOG_SYNTH8_REFDIVB_MSB                                                                        31
-#define PHY_ANALOG_SYNTH8_REFDIVB_LSB                                                                        27
-#define PHY_ANALOG_SYNTH8_REFDIVB_MASK                                                               0xf8000000
-#define PHY_ANALOG_SYNTH8_REFDIVB_GET(x)                                             (((x) & 0xf8000000) >> 27)
-#define PHY_ANALOG_SYNTH8_REFDIVB_SET(x)                                             (((x) << 27) & 0xf8000000)
-
-/* macros for SYNTH9 */
-#define PHY_ANALOG_SYNTH9_ADDRESS                                                                    0x000000a0
-#define PHY_ANALOG_SYNTH9_OFFSET                                                                     0x000000a0
-#define PHY_ANALOG_SYNTH9_PFDDELAY_INTN_MSB                                                                   0
-#define PHY_ANALOG_SYNTH9_PFDDELAY_INTN_LSB                                                                   0
-#define PHY_ANALOG_SYNTH9_PFDDELAY_INTN_MASK                                                         0x00000001
-#define PHY_ANALOG_SYNTH9_PFDDELAY_INTN_GET(x)                                        (((x) & 0x00000001) >> 0)
-#define PHY_ANALOG_SYNTH9_PFDDELAY_INTN_SET(x)                                        (((x) << 0) & 0x00000001)
-#define PHY_ANALOG_SYNTH9_SLOPE_ICPA0_MSB                                                                     3
-#define PHY_ANALOG_SYNTH9_SLOPE_ICPA0_LSB                                                                     1
-#define PHY_ANALOG_SYNTH9_SLOPE_ICPA0_MASK                                                           0x0000000e
-#define PHY_ANALOG_SYNTH9_SLOPE_ICPA0_GET(x)                                          (((x) & 0x0000000e) >> 1)
-#define PHY_ANALOG_SYNTH9_SLOPE_ICPA0_SET(x)                                          (((x) << 1) & 0x0000000e)
-#define PHY_ANALOG_SYNTH9_LOOP_ICPA0_MSB                                                                      7
-#define PHY_ANALOG_SYNTH9_LOOP_ICPA0_LSB                                                                      4
-#define PHY_ANALOG_SYNTH9_LOOP_ICPA0_MASK                                                            0x000000f0
-#define PHY_ANALOG_SYNTH9_LOOP_ICPA0_GET(x)                                           (((x) & 0x000000f0) >> 4)
-#define PHY_ANALOG_SYNTH9_LOOP_ICPA0_SET(x)                                           (((x) << 4) & 0x000000f0)
-#define PHY_ANALOG_SYNTH9_LOOP_CSA0_MSB                                                                      11
-#define PHY_ANALOG_SYNTH9_LOOP_CSA0_LSB                                                                       8
-#define PHY_ANALOG_SYNTH9_LOOP_CSA0_MASK                                                             0x00000f00
-#define PHY_ANALOG_SYNTH9_LOOP_CSA0_GET(x)                                            (((x) & 0x00000f00) >> 8)
-#define PHY_ANALOG_SYNTH9_LOOP_CSA0_SET(x)                                            (((x) << 8) & 0x00000f00)
-#define PHY_ANALOG_SYNTH9_LOOP_RSA0_MSB                                                                      16
-#define PHY_ANALOG_SYNTH9_LOOP_RSA0_LSB                                                                      12
-#define PHY_ANALOG_SYNTH9_LOOP_RSA0_MASK                                                             0x0001f000
-#define PHY_ANALOG_SYNTH9_LOOP_RSA0_GET(x)                                           (((x) & 0x0001f000) >> 12)
-#define PHY_ANALOG_SYNTH9_LOOP_RSA0_SET(x)                                           (((x) << 12) & 0x0001f000)
-#define PHY_ANALOG_SYNTH9_LOOP_CPA0_MSB                                                                      21
-#define PHY_ANALOG_SYNTH9_LOOP_CPA0_LSB                                                                      17
-#define PHY_ANALOG_SYNTH9_LOOP_CPA0_MASK                                                             0x003e0000
-#define PHY_ANALOG_SYNTH9_LOOP_CPA0_GET(x)                                           (((x) & 0x003e0000) >> 17)
-#define PHY_ANALOG_SYNTH9_LOOP_CPA0_SET(x)                                           (((x) << 17) & 0x003e0000)
-#define PHY_ANALOG_SYNTH9_LOOP_3RD_ORDER_RA_MSB                                                              26
-#define PHY_ANALOG_SYNTH9_LOOP_3RD_ORDER_RA_LSB                                                              22
-#define PHY_ANALOG_SYNTH9_LOOP_3RD_ORDER_RA_MASK                                                     0x07c00000
-#define PHY_ANALOG_SYNTH9_LOOP_3RD_ORDER_RA_GET(x)                                   (((x) & 0x07c00000) >> 22)
-#define PHY_ANALOG_SYNTH9_LOOP_3RD_ORDER_RA_SET(x)                                   (((x) << 22) & 0x07c00000)
-#define PHY_ANALOG_SYNTH9_REFDIVA_MSB                                                                        31
-#define PHY_ANALOG_SYNTH9_REFDIVA_LSB                                                                        27
-#define PHY_ANALOG_SYNTH9_REFDIVA_MASK                                                               0xf8000000
-#define PHY_ANALOG_SYNTH9_REFDIVA_GET(x)                                             (((x) & 0xf8000000) >> 27)
-#define PHY_ANALOG_SYNTH9_REFDIVA_SET(x)                                             (((x) << 27) & 0xf8000000)
-
-/* macros for SYNTH10 */
-#define PHY_ANALOG_SYNTH10_ADDRESS                                                                   0x000000a4
-#define PHY_ANALOG_SYNTH10_OFFSET                                                                    0x000000a4
-#define PHY_ANALOG_SYNTH10_SPARE10A_MSB                                                                       1
-#define PHY_ANALOG_SYNTH10_SPARE10A_LSB                                                                       0
-#define PHY_ANALOG_SYNTH10_SPARE10A_MASK                                                             0x00000003
-#define PHY_ANALOG_SYNTH10_SPARE10A_GET(x)                                            (((x) & 0x00000003) >> 0)
-#define PHY_ANALOG_SYNTH10_SPARE10A_SET(x)                                            (((x) << 0) & 0x00000003)
-#define PHY_ANALOG_SYNTH10_PWDB_ICLOBIAS50_MSB                                                                4
-#define PHY_ANALOG_SYNTH10_PWDB_ICLOBIAS50_LSB                                                                2
-#define PHY_ANALOG_SYNTH10_PWDB_ICLOBIAS50_MASK                                                      0x0000001c
-#define PHY_ANALOG_SYNTH10_PWDB_ICLOBIAS50_GET(x)                                     (((x) & 0x0000001c) >> 2)
-#define PHY_ANALOG_SYNTH10_PWDB_ICLOBIAS50_SET(x)                                     (((x) << 2) & 0x0000001c)
-#define PHY_ANALOG_SYNTH10_PWDB_IRSPARE25_MSB                                                                 7
-#define PHY_ANALOG_SYNTH10_PWDB_IRSPARE25_LSB                                                                 5
-#define PHY_ANALOG_SYNTH10_PWDB_IRSPARE25_MASK                                                       0x000000e0
-#define PHY_ANALOG_SYNTH10_PWDB_IRSPARE25_GET(x)                                      (((x) & 0x000000e0) >> 5)
-#define PHY_ANALOG_SYNTH10_PWDB_IRSPARE25_SET(x)                                      (((x) << 5) & 0x000000e0)
-#define PHY_ANALOG_SYNTH10_PWDB_ICSPARE25_MSB                                                                10
-#define PHY_ANALOG_SYNTH10_PWDB_ICSPARE25_LSB                                                                 8
-#define PHY_ANALOG_SYNTH10_PWDB_ICSPARE25_MASK                                                       0x00000700
-#define PHY_ANALOG_SYNTH10_PWDB_ICSPARE25_GET(x)                                      (((x) & 0x00000700) >> 8)
-#define PHY_ANALOG_SYNTH10_PWDB_ICSPARE25_SET(x)                                      (((x) << 8) & 0x00000700)
-#define PHY_ANALOG_SYNTH10_SLOPE_ICPA1_MSB                                                                   13
-#define PHY_ANALOG_SYNTH10_SLOPE_ICPA1_LSB                                                                   11
-#define PHY_ANALOG_SYNTH10_SLOPE_ICPA1_MASK                                                          0x00003800
-#define PHY_ANALOG_SYNTH10_SLOPE_ICPA1_GET(x)                                        (((x) & 0x00003800) >> 11)
-#define PHY_ANALOG_SYNTH10_SLOPE_ICPA1_SET(x)                                        (((x) << 11) & 0x00003800)
-#define PHY_ANALOG_SYNTH10_LOOP_ICPA1_MSB                                                                    17
-#define PHY_ANALOG_SYNTH10_LOOP_ICPA1_LSB                                                                    14
-#define PHY_ANALOG_SYNTH10_LOOP_ICPA1_MASK                                                           0x0003c000
-#define PHY_ANALOG_SYNTH10_LOOP_ICPA1_GET(x)                                         (((x) & 0x0003c000) >> 14)
-#define PHY_ANALOG_SYNTH10_LOOP_ICPA1_SET(x)                                         (((x) << 14) & 0x0003c000)
-#define PHY_ANALOG_SYNTH10_LOOP_CSA1_MSB                                                                     21
-#define PHY_ANALOG_SYNTH10_LOOP_CSA1_LSB                                                                     18
-#define PHY_ANALOG_SYNTH10_LOOP_CSA1_MASK                                                            0x003c0000
-#define PHY_ANALOG_SYNTH10_LOOP_CSA1_GET(x)                                          (((x) & 0x003c0000) >> 18)
-#define PHY_ANALOG_SYNTH10_LOOP_CSA1_SET(x)                                          (((x) << 18) & 0x003c0000)
-#define PHY_ANALOG_SYNTH10_LOOP_RSA1_MSB                                                                     26
-#define PHY_ANALOG_SYNTH10_LOOP_RSA1_LSB                                                                     22
-#define PHY_ANALOG_SYNTH10_LOOP_RSA1_MASK                                                            0x07c00000
-#define PHY_ANALOG_SYNTH10_LOOP_RSA1_GET(x)                                          (((x) & 0x07c00000) >> 22)
-#define PHY_ANALOG_SYNTH10_LOOP_RSA1_SET(x)                                          (((x) << 22) & 0x07c00000)
-#define PHY_ANALOG_SYNTH10_LOOP_CPA1_MSB                                                                     31
-#define PHY_ANALOG_SYNTH10_LOOP_CPA1_LSB                                                                     27
-#define PHY_ANALOG_SYNTH10_LOOP_CPA1_MASK                                                            0xf8000000
-#define PHY_ANALOG_SYNTH10_LOOP_CPA1_GET(x)                                          (((x) & 0xf8000000) >> 27)
-#define PHY_ANALOG_SYNTH10_LOOP_CPA1_SET(x)                                          (((x) << 27) & 0xf8000000)
-
-/* macros for SYNTH11 */
-#define PHY_ANALOG_SYNTH11_ADDRESS                                                                   0x000000a8
-#define PHY_ANALOG_SYNTH11_OFFSET                                                                    0x000000a8
-#define PHY_ANALOG_SYNTH11_SPARE11A_MSB                                                                       4
-#define PHY_ANALOG_SYNTH11_SPARE11A_LSB                                                                       0
-#define PHY_ANALOG_SYNTH11_SPARE11A_MASK                                                             0x0000001f
-#define PHY_ANALOG_SYNTH11_SPARE11A_GET(x)                                            (((x) & 0x0000001f) >> 0)
-#define PHY_ANALOG_SYNTH11_SPARE11A_SET(x)                                            (((x) << 0) & 0x0000001f)
-#define PHY_ANALOG_SYNTH11_FORCE_LOBUF5G_ON_MSB                                                               5
-#define PHY_ANALOG_SYNTH11_FORCE_LOBUF5G_ON_LSB                                                               5
-#define PHY_ANALOG_SYNTH11_FORCE_LOBUF5G_ON_MASK                                                     0x00000020
-#define PHY_ANALOG_SYNTH11_FORCE_LOBUF5G_ON_GET(x)                                    (((x) & 0x00000020) >> 5)
-#define PHY_ANALOG_SYNTH11_FORCE_LOBUF5G_ON_SET(x)                                    (((x) << 5) & 0x00000020)
-#define PHY_ANALOG_SYNTH11_LOREFSEL_MSB                                                                       7
-#define PHY_ANALOG_SYNTH11_LOREFSEL_LSB                                                                       6
-#define PHY_ANALOG_SYNTH11_LOREFSEL_MASK                                                             0x000000c0
-#define PHY_ANALOG_SYNTH11_LOREFSEL_GET(x)                                            (((x) & 0x000000c0) >> 6)
-#define PHY_ANALOG_SYNTH11_LOREFSEL_SET(x)                                            (((x) << 6) & 0x000000c0)
-#define PHY_ANALOG_SYNTH11_LOBUF2GTUNE_MSB                                                                    9
-#define PHY_ANALOG_SYNTH11_LOBUF2GTUNE_LSB                                                                    8
-#define PHY_ANALOG_SYNTH11_LOBUF2GTUNE_MASK                                                          0x00000300
-#define PHY_ANALOG_SYNTH11_LOBUF2GTUNE_GET(x)                                         (((x) & 0x00000300) >> 8)
-#define PHY_ANALOG_SYNTH11_LOBUF2GTUNE_SET(x)                                         (((x) << 8) & 0x00000300)
-#define PHY_ANALOG_SYNTH11_CPSTEERING_MODE_MSB                                                               10
-#define PHY_ANALOG_SYNTH11_CPSTEERING_MODE_LSB                                                               10
-#define PHY_ANALOG_SYNTH11_CPSTEERING_MODE_MASK                                                      0x00000400
-#define PHY_ANALOG_SYNTH11_CPSTEERING_MODE_GET(x)                                    (((x) & 0x00000400) >> 10)
-#define PHY_ANALOG_SYNTH11_CPSTEERING_MODE_SET(x)                                    (((x) << 10) & 0x00000400)
-#define PHY_ANALOG_SYNTH11_SLOPE_ICPA2_MSB                                                                   13
-#define PHY_ANALOG_SYNTH11_SLOPE_ICPA2_LSB                                                                   11
-#define PHY_ANALOG_SYNTH11_SLOPE_ICPA2_MASK                                                          0x00003800
-#define PHY_ANALOG_SYNTH11_SLOPE_ICPA2_GET(x)                                        (((x) & 0x00003800) >> 11)
-#define PHY_ANALOG_SYNTH11_SLOPE_ICPA2_SET(x)                                        (((x) << 11) & 0x00003800)
-#define PHY_ANALOG_SYNTH11_LOOP_ICPA2_MSB                                                                    17
-#define PHY_ANALOG_SYNTH11_LOOP_ICPA2_LSB                                                                    14
-#define PHY_ANALOG_SYNTH11_LOOP_ICPA2_MASK                                                           0x0003c000
-#define PHY_ANALOG_SYNTH11_LOOP_ICPA2_GET(x)                                         (((x) & 0x0003c000) >> 14)
-#define PHY_ANALOG_SYNTH11_LOOP_ICPA2_SET(x)                                         (((x) << 14) & 0x0003c000)
-#define PHY_ANALOG_SYNTH11_LOOP_CSA2_MSB                                                                     21
-#define PHY_ANALOG_SYNTH11_LOOP_CSA2_LSB                                                                     18
-#define PHY_ANALOG_SYNTH11_LOOP_CSA2_MASK                                                            0x003c0000
-#define PHY_ANALOG_SYNTH11_LOOP_CSA2_GET(x)                                          (((x) & 0x003c0000) >> 18)
-#define PHY_ANALOG_SYNTH11_LOOP_CSA2_SET(x)                                          (((x) << 18) & 0x003c0000)
-#define PHY_ANALOG_SYNTH11_LOOP_RSA2_MSB                                                                     26
-#define PHY_ANALOG_SYNTH11_LOOP_RSA2_LSB                                                                     22
-#define PHY_ANALOG_SYNTH11_LOOP_RSA2_MASK                                                            0x07c00000
-#define PHY_ANALOG_SYNTH11_LOOP_RSA2_GET(x)                                          (((x) & 0x07c00000) >> 22)
-#define PHY_ANALOG_SYNTH11_LOOP_RSA2_SET(x)                                          (((x) << 22) & 0x07c00000)
-#define PHY_ANALOG_SYNTH11_LOOP_CPA2_MSB                                                                     31
-#define PHY_ANALOG_SYNTH11_LOOP_CPA2_LSB                                                                     27
-#define PHY_ANALOG_SYNTH11_LOOP_CPA2_MASK                                                            0xf8000000
-#define PHY_ANALOG_SYNTH11_LOOP_CPA2_GET(x)                                          (((x) & 0xf8000000) >> 27)
-#define PHY_ANALOG_SYNTH11_LOOP_CPA2_SET(x)                                          (((x) << 27) & 0xf8000000)
-
-/* macros for SYNTH12 */
-#define PHY_ANALOG_SYNTH12_ADDRESS                                                                   0x000000ac
-#define PHY_ANALOG_SYNTH12_OFFSET                                                                    0x000000ac
-#define PHY_ANALOG_SYNTH12_SPARE12A_MSB                                                                       9
-#define PHY_ANALOG_SYNTH12_SPARE12A_LSB                                                                       0
-#define PHY_ANALOG_SYNTH12_SPARE12A_MASK                                                             0x000003ff
-#define PHY_ANALOG_SYNTH12_SPARE12A_GET(x)                                            (((x) & 0x000003ff) >> 0)
-#define PHY_ANALOG_SYNTH12_SPARE12A_SET(x)                                            (((x) << 0) & 0x000003ff)
-#define PHY_ANALOG_SYNTH12_LOOPLEAKCUR_FRACN_MSB                                                             13
-#define PHY_ANALOG_SYNTH12_LOOPLEAKCUR_FRACN_LSB                                                             10
-#define PHY_ANALOG_SYNTH12_LOOPLEAKCUR_FRACN_MASK                                                    0x00003c00
-#define PHY_ANALOG_SYNTH12_LOOPLEAKCUR_FRACN_GET(x)                                  (((x) & 0x00003c00) >> 10)
-#define PHY_ANALOG_SYNTH12_LOOPLEAKCUR_FRACN_SET(x)                                  (((x) << 10) & 0x00003c00)
-#define PHY_ANALOG_SYNTH12_CPLOWLK_FRACN_MSB                                                                 14
-#define PHY_ANALOG_SYNTH12_CPLOWLK_FRACN_LSB                                                                 14
-#define PHY_ANALOG_SYNTH12_CPLOWLK_FRACN_MASK                                                        0x00004000
-#define PHY_ANALOG_SYNTH12_CPLOWLK_FRACN_GET(x)                                      (((x) & 0x00004000) >> 14)
-#define PHY_ANALOG_SYNTH12_CPLOWLK_FRACN_SET(x)                                      (((x) << 14) & 0x00004000)
-#define PHY_ANALOG_SYNTH12_CPBIAS_FRACN_MSB                                                                  16
-#define PHY_ANALOG_SYNTH12_CPBIAS_FRACN_LSB                                                                  15
-#define PHY_ANALOG_SYNTH12_CPBIAS_FRACN_MASK                                                         0x00018000
-#define PHY_ANALOG_SYNTH12_CPBIAS_FRACN_GET(x)                                       (((x) & 0x00018000) >> 15)
-#define PHY_ANALOG_SYNTH12_CPBIAS_FRACN_SET(x)                                       (((x) << 15) & 0x00018000)
-#define PHY_ANALOG_SYNTH12_SYNTHDIGOUTEN_MSB                                                                 17
-#define PHY_ANALOG_SYNTH12_SYNTHDIGOUTEN_LSB                                                                 17
-#define PHY_ANALOG_SYNTH12_SYNTHDIGOUTEN_MASK                                                        0x00020000
-#define PHY_ANALOG_SYNTH12_SYNTHDIGOUTEN_GET(x)                                      (((x) & 0x00020000) >> 17)
-#define PHY_ANALOG_SYNTH12_SYNTHDIGOUTEN_SET(x)                                      (((x) << 17) & 0x00020000)
-#define PHY_ANALOG_SYNTH12_STRCONT_MSB                                                                       18
-#define PHY_ANALOG_SYNTH12_STRCONT_LSB                                                                       18
-#define PHY_ANALOG_SYNTH12_STRCONT_MASK                                                              0x00040000
-#define PHY_ANALOG_SYNTH12_STRCONT_GET(x)                                            (((x) & 0x00040000) >> 18)
-#define PHY_ANALOG_SYNTH12_STRCONT_SET(x)                                            (((x) << 18) & 0x00040000)
-#define PHY_ANALOG_SYNTH12_VREFMUL3_MSB                                                                      22
-#define PHY_ANALOG_SYNTH12_VREFMUL3_LSB                                                                      19
-#define PHY_ANALOG_SYNTH12_VREFMUL3_MASK                                                             0x00780000
-#define PHY_ANALOG_SYNTH12_VREFMUL3_GET(x)                                           (((x) & 0x00780000) >> 19)
-#define PHY_ANALOG_SYNTH12_VREFMUL3_SET(x)                                           (((x) << 19) & 0x00780000)
-#define PHY_ANALOG_SYNTH12_VREFMUL2_MSB                                                                      26
-#define PHY_ANALOG_SYNTH12_VREFMUL2_LSB                                                                      23
-#define PHY_ANALOG_SYNTH12_VREFMUL2_MASK                                                             0x07800000
-#define PHY_ANALOG_SYNTH12_VREFMUL2_GET(x)                                           (((x) & 0x07800000) >> 23)
-#define PHY_ANALOG_SYNTH12_VREFMUL2_SET(x)                                           (((x) << 23) & 0x07800000)
-#define PHY_ANALOG_SYNTH12_VREFMUL1_MSB                                                                      30
-#define PHY_ANALOG_SYNTH12_VREFMUL1_LSB                                                                      27
-#define PHY_ANALOG_SYNTH12_VREFMUL1_MASK                                                             0x78000000
-#define PHY_ANALOG_SYNTH12_VREFMUL1_GET(x)                                           (((x) & 0x78000000) >> 27)
-#define PHY_ANALOG_SYNTH12_VREFMUL1_SET(x)                                           (((x) << 27) & 0x78000000)
-#define PHY_ANALOG_SYNTH12_CLK_DOUBLER_EN_MSB                                                                31
-#define PHY_ANALOG_SYNTH12_CLK_DOUBLER_EN_LSB                                                                31
-#define PHY_ANALOG_SYNTH12_CLK_DOUBLER_EN_MASK                                                       0x80000000
-#define PHY_ANALOG_SYNTH12_CLK_DOUBLER_EN_GET(x)                                     (((x) & 0x80000000) >> 31)
-#define PHY_ANALOG_SYNTH12_CLK_DOUBLER_EN_SET(x)                                     (((x) << 31) & 0x80000000)
-
-/* macros for SYNTH13 */
-#define PHY_ANALOG_SYNTH13_ADDRESS                                                                   0x000000b0
-#define PHY_ANALOG_SYNTH13_OFFSET                                                                    0x000000b0
-#define PHY_ANALOG_SYNTH13_SPARE13A_MSB                                                                       0
-#define PHY_ANALOG_SYNTH13_SPARE13A_LSB                                                                       0
-#define PHY_ANALOG_SYNTH13_SPARE13A_MASK                                                             0x00000001
-#define PHY_ANALOG_SYNTH13_SPARE13A_GET(x)                                            (((x) & 0x00000001) >> 0)
-#define PHY_ANALOG_SYNTH13_SPARE13A_SET(x)                                            (((x) << 0) & 0x00000001)
-#define PHY_ANALOG_SYNTH13_SLOPE_ICPA_FRACN_MSB                                                               3
-#define PHY_ANALOG_SYNTH13_SLOPE_ICPA_FRACN_LSB                                                               1
-#define PHY_ANALOG_SYNTH13_SLOPE_ICPA_FRACN_MASK                                                     0x0000000e
-#define PHY_ANALOG_SYNTH13_SLOPE_ICPA_FRACN_GET(x)                                    (((x) & 0x0000000e) >> 1)
-#define PHY_ANALOG_SYNTH13_SLOPE_ICPA_FRACN_SET(x)                                    (((x) << 1) & 0x0000000e)
-#define PHY_ANALOG_SYNTH13_LOOP_ICPA_FRACN_MSB                                                                7
-#define PHY_ANALOG_SYNTH13_LOOP_ICPA_FRACN_LSB                                                                4
-#define PHY_ANALOG_SYNTH13_LOOP_ICPA_FRACN_MASK                                                      0x000000f0
-#define PHY_ANALOG_SYNTH13_LOOP_ICPA_FRACN_GET(x)                                     (((x) & 0x000000f0) >> 4)
-#define PHY_ANALOG_SYNTH13_LOOP_ICPA_FRACN_SET(x)                                     (((x) << 4) & 0x000000f0)
-#define PHY_ANALOG_SYNTH13_LOOP_CSA_FRACN_MSB                                                                11
-#define PHY_ANALOG_SYNTH13_LOOP_CSA_FRACN_LSB                                                                 8
-#define PHY_ANALOG_SYNTH13_LOOP_CSA_FRACN_MASK                                                       0x00000f00
-#define PHY_ANALOG_SYNTH13_LOOP_CSA_FRACN_GET(x)                                      (((x) & 0x00000f00) >> 8)
-#define PHY_ANALOG_SYNTH13_LOOP_CSA_FRACN_SET(x)                                      (((x) << 8) & 0x00000f00)
-#define PHY_ANALOG_SYNTH13_LOOP_RSA_FRACN_MSB                                                                16
-#define PHY_ANALOG_SYNTH13_LOOP_RSA_FRACN_LSB                                                                12
-#define PHY_ANALOG_SYNTH13_LOOP_RSA_FRACN_MASK                                                       0x0001f000
-#define PHY_ANALOG_SYNTH13_LOOP_RSA_FRACN_GET(x)                                     (((x) & 0x0001f000) >> 12)
-#define PHY_ANALOG_SYNTH13_LOOP_RSA_FRACN_SET(x)                                     (((x) << 12) & 0x0001f000)
-#define PHY_ANALOG_SYNTH13_LOOP_CPA_FRACN_MSB                                                                21
-#define PHY_ANALOG_SYNTH13_LOOP_CPA_FRACN_LSB                                                                17
-#define PHY_ANALOG_SYNTH13_LOOP_CPA_FRACN_MASK                                                       0x003e0000
-#define PHY_ANALOG_SYNTH13_LOOP_CPA_FRACN_GET(x)                                     (((x) & 0x003e0000) >> 17)
-#define PHY_ANALOG_SYNTH13_LOOP_CPA_FRACN_SET(x)                                     (((x) << 17) & 0x003e0000)
-#define PHY_ANALOG_SYNTH13_LOOP_3RD_ORDER_RA_FRACN_MSB                                                       26
-#define PHY_ANALOG_SYNTH13_LOOP_3RD_ORDER_RA_FRACN_LSB                                                       22
-#define PHY_ANALOG_SYNTH13_LOOP_3RD_ORDER_RA_FRACN_MASK                                              0x07c00000
-#define PHY_ANALOG_SYNTH13_LOOP_3RD_ORDER_RA_FRACN_GET(x)                            (((x) & 0x07c00000) >> 22)
-#define PHY_ANALOG_SYNTH13_LOOP_3RD_ORDER_RA_FRACN_SET(x)                            (((x) << 22) & 0x07c00000)
-#define PHY_ANALOG_SYNTH13_REFDIVA_FRACN_MSB                                                                 31
-#define PHY_ANALOG_SYNTH13_REFDIVA_FRACN_LSB                                                                 27
-#define PHY_ANALOG_SYNTH13_REFDIVA_FRACN_MASK                                                        0xf8000000
-#define PHY_ANALOG_SYNTH13_REFDIVA_FRACN_GET(x)                                      (((x) & 0xf8000000) >> 27)
-#define PHY_ANALOG_SYNTH13_REFDIVA_FRACN_SET(x)                                      (((x) << 27) & 0xf8000000)
-
-/* macros for SYNTH14 */
-#define PHY_ANALOG_SYNTH14_ADDRESS                                                                   0x000000b4
-#define PHY_ANALOG_SYNTH14_OFFSET                                                                    0x000000b4
-#define PHY_ANALOG_SYNTH14_SPARE14A_MSB                                                                       1
-#define PHY_ANALOG_SYNTH14_SPARE14A_LSB                                                                       0
-#define PHY_ANALOG_SYNTH14_SPARE14A_MASK                                                             0x00000003
-#define PHY_ANALOG_SYNTH14_SPARE14A_GET(x)                                            (((x) & 0x00000003) >> 0)
-#define PHY_ANALOG_SYNTH14_SPARE14A_SET(x)                                            (((x) << 0) & 0x00000003)
-#define PHY_ANALOG_SYNTH14_LOBUF5GTUNE_3_MSB                                                                  3
-#define PHY_ANALOG_SYNTH14_LOBUF5GTUNE_3_LSB                                                                  2
-#define PHY_ANALOG_SYNTH14_LOBUF5GTUNE_3_MASK                                                        0x0000000c
-#define PHY_ANALOG_SYNTH14_LOBUF5GTUNE_3_GET(x)                                       (((x) & 0x0000000c) >> 2)
-#define PHY_ANALOG_SYNTH14_LOBUF5GTUNE_3_SET(x)                                       (((x) << 2) & 0x0000000c)
-#define PHY_ANALOG_SYNTH14_LOBUF2GTUNE_3_MSB                                                                  5
-#define PHY_ANALOG_SYNTH14_LOBUF2GTUNE_3_LSB                                                                  4
-#define PHY_ANALOG_SYNTH14_LOBUF2GTUNE_3_MASK                                                        0x00000030
-#define PHY_ANALOG_SYNTH14_LOBUF2GTUNE_3_GET(x)                                       (((x) & 0x00000030) >> 4)
-#define PHY_ANALOG_SYNTH14_LOBUF2GTUNE_3_SET(x)                                       (((x) << 4) & 0x00000030)
-#define PHY_ANALOG_SYNTH14_LOBUF5GTUNE_2_MSB                                                                  7
-#define PHY_ANALOG_SYNTH14_LOBUF5GTUNE_2_LSB                                                                  6
-#define PHY_ANALOG_SYNTH14_LOBUF5GTUNE_2_MASK                                                        0x000000c0
-#define PHY_ANALOG_SYNTH14_LOBUF5GTUNE_2_GET(x)                                       (((x) & 0x000000c0) >> 6)
-#define PHY_ANALOG_SYNTH14_LOBUF5GTUNE_2_SET(x)                                       (((x) << 6) & 0x000000c0)
-#define PHY_ANALOG_SYNTH14_LOBUF2GTUNE_2_MSB                                                                  9
-#define PHY_ANALOG_SYNTH14_LOBUF2GTUNE_2_LSB                                                                  8
-#define PHY_ANALOG_SYNTH14_LOBUF2GTUNE_2_MASK                                                        0x00000300
-#define PHY_ANALOG_SYNTH14_LOBUF2GTUNE_2_GET(x)                                       (((x) & 0x00000300) >> 8)
-#define PHY_ANALOG_SYNTH14_LOBUF2GTUNE_2_SET(x)                                       (((x) << 8) & 0x00000300)
-#define PHY_ANALOG_SYNTH14_PWD_LOBUF5G_3_MSB                                                                 10
-#define PHY_ANALOG_SYNTH14_PWD_LOBUF5G_3_LSB                                                                 10
-#define PHY_ANALOG_SYNTH14_PWD_LOBUF5G_3_MASK                                                        0x00000400
-#define PHY_ANALOG_SYNTH14_PWD_LOBUF5G_3_GET(x)                                      (((x) & 0x00000400) >> 10)
-#define PHY_ANALOG_SYNTH14_PWD_LOBUF5G_3_SET(x)                                      (((x) << 10) & 0x00000400)
-#define PHY_ANALOG_SYNTH14_PWD_LOBUF2G_3_MSB                                                                 11
-#define PHY_ANALOG_SYNTH14_PWD_LOBUF2G_3_LSB                                                                 11
-#define PHY_ANALOG_SYNTH14_PWD_LOBUF2G_3_MASK                                                        0x00000800
-#define PHY_ANALOG_SYNTH14_PWD_LOBUF2G_3_GET(x)                                      (((x) & 0x00000800) >> 11)
-#define PHY_ANALOG_SYNTH14_PWD_LOBUF2G_3_SET(x)                                      (((x) << 11) & 0x00000800)
-#define PHY_ANALOG_SYNTH14_PWD_LOBUF5G_2_MSB                                                                 12
-#define PHY_ANALOG_SYNTH14_PWD_LOBUF5G_2_LSB                                                                 12
-#define PHY_ANALOG_SYNTH14_PWD_LOBUF5G_2_MASK                                                        0x00001000
-#define PHY_ANALOG_SYNTH14_PWD_LOBUF5G_2_GET(x)                                      (((x) & 0x00001000) >> 12)
-#define PHY_ANALOG_SYNTH14_PWD_LOBUF5G_2_SET(x)                                      (((x) << 12) & 0x00001000)
-#define PHY_ANALOG_SYNTH14_PWD_LOBUF2G_2_MSB                                                                 13
-#define PHY_ANALOG_SYNTH14_PWD_LOBUF2G_2_LSB                                                                 13
-#define PHY_ANALOG_SYNTH14_PWD_LOBUF2G_2_MASK                                                        0x00002000
-#define PHY_ANALOG_SYNTH14_PWD_LOBUF2G_2_GET(x)                                      (((x) & 0x00002000) >> 13)
-#define PHY_ANALOG_SYNTH14_PWD_LOBUF2G_2_SET(x)                                      (((x) << 13) & 0x00002000)
-#define PHY_ANALOG_SYNTH14_PWUPLO23_PD_MSB                                                                   16
-#define PHY_ANALOG_SYNTH14_PWUPLO23_PD_LSB                                                                   14
-#define PHY_ANALOG_SYNTH14_PWUPLO23_PD_MASK                                                          0x0001c000
-#define PHY_ANALOG_SYNTH14_PWUPLO23_PD_GET(x)                                        (((x) & 0x0001c000) >> 14)
-#define PHY_ANALOG_SYNTH14_PWUPLO23_PD_SET(x)                                        (((x) << 14) & 0x0001c000)
-#define PHY_ANALOG_SYNTH14_PWDB_ICLOBUF5G50_3_MSB                                                            19
-#define PHY_ANALOG_SYNTH14_PWDB_ICLOBUF5G50_3_LSB                                                            17
-#define PHY_ANALOG_SYNTH14_PWDB_ICLOBUF5G50_3_MASK                                                   0x000e0000
-#define PHY_ANALOG_SYNTH14_PWDB_ICLOBUF5G50_3_GET(x)                                 (((x) & 0x000e0000) >> 17)
-#define PHY_ANALOG_SYNTH14_PWDB_ICLOBUF5G50_3_SET(x)                                 (((x) << 17) & 0x000e0000)
-#define PHY_ANALOG_SYNTH14_PWDB_ICLOBUF2G50_3_MSB                                                            22
-#define PHY_ANALOG_SYNTH14_PWDB_ICLOBUF2G50_3_LSB                                                            20
-#define PHY_ANALOG_SYNTH14_PWDB_ICLOBUF2G50_3_MASK                                                   0x00700000
-#define PHY_ANALOG_SYNTH14_PWDB_ICLOBUF2G50_3_GET(x)                                 (((x) & 0x00700000) >> 20)
-#define PHY_ANALOG_SYNTH14_PWDB_ICLOBUF2G50_3_SET(x)                                 (((x) << 20) & 0x00700000)
-#define PHY_ANALOG_SYNTH14_PWDB_ICLOBUF5G50_2_MSB                                                            25
-#define PHY_ANALOG_SYNTH14_PWDB_ICLOBUF5G50_2_LSB                                                            23
-#define PHY_ANALOG_SYNTH14_PWDB_ICLOBUF5G50_2_MASK                                                   0x03800000
-#define PHY_ANALOG_SYNTH14_PWDB_ICLOBUF5G50_2_GET(x)                                 (((x) & 0x03800000) >> 23)
-#define PHY_ANALOG_SYNTH14_PWDB_ICLOBUF5G50_2_SET(x)                                 (((x) << 23) & 0x03800000)
-#define PHY_ANALOG_SYNTH14_PWDB_ICLOBUF2G50_2_MSB                                                            28
-#define PHY_ANALOG_SYNTH14_PWDB_ICLOBUF2G50_2_LSB                                                            26
-#define PHY_ANALOG_SYNTH14_PWDB_ICLOBUF2G50_2_MASK                                                   0x1c000000
-#define PHY_ANALOG_SYNTH14_PWDB_ICLOBUF2G50_2_GET(x)                                 (((x) & 0x1c000000) >> 26)
-#define PHY_ANALOG_SYNTH14_PWDB_ICLOBUF2G50_2_SET(x)                                 (((x) << 26) & 0x1c000000)
-#define PHY_ANALOG_SYNTH14_PWDB_ICLVLSHFT_MSB                                                                31
-#define PHY_ANALOG_SYNTH14_PWDB_ICLVLSHFT_LSB                                                                29
-#define PHY_ANALOG_SYNTH14_PWDB_ICLVLSHFT_MASK                                                       0xe0000000
-#define PHY_ANALOG_SYNTH14_PWDB_ICLVLSHFT_GET(x)                                     (((x) & 0xe0000000) >> 29)
-#define PHY_ANALOG_SYNTH14_PWDB_ICLVLSHFT_SET(x)                                     (((x) << 29) & 0xe0000000)
-
-/* macros for BIAS1 */
-#define PHY_ANALOG_BIAS1_ADDRESS                                                                     0x000000c0
-#define PHY_ANALOG_BIAS1_OFFSET                                                                      0x000000c0
-#define PHY_ANALOG_BIAS1_SPARE1_MSB                                                                           6
-#define PHY_ANALOG_BIAS1_SPARE1_LSB                                                                           0
-#define PHY_ANALOG_BIAS1_SPARE1_MASK                                                                 0x0000007f
-#define PHY_ANALOG_BIAS1_SPARE1_GET(x)                                                (((x) & 0x0000007f) >> 0)
-#define PHY_ANALOG_BIAS1_SPARE1_SET(x)                                                (((x) << 0) & 0x0000007f)
-#define PHY_ANALOG_BIAS1_PWD_IC25V2IQ_MSB                                                                     9
-#define PHY_ANALOG_BIAS1_PWD_IC25V2IQ_LSB                                                                     7
-#define PHY_ANALOG_BIAS1_PWD_IC25V2IQ_MASK                                                           0x00000380
-#define PHY_ANALOG_BIAS1_PWD_IC25V2IQ_GET(x)                                          (((x) & 0x00000380) >> 7)
-#define PHY_ANALOG_BIAS1_PWD_IC25V2IQ_SET(x)                                          (((x) << 7) & 0x00000380)
-#define PHY_ANALOG_BIAS1_PWD_IC25V2II_MSB                                                                    12
-#define PHY_ANALOG_BIAS1_PWD_IC25V2II_LSB                                                                    10
-#define PHY_ANALOG_BIAS1_PWD_IC25V2II_MASK                                                           0x00001c00
-#define PHY_ANALOG_BIAS1_PWD_IC25V2II_GET(x)                                         (((x) & 0x00001c00) >> 10)
-#define PHY_ANALOG_BIAS1_PWD_IC25V2II_SET(x)                                         (((x) << 10) & 0x00001c00)
-#define PHY_ANALOG_BIAS1_PWD_IC25BB_MSB                                                                      15
-#define PHY_ANALOG_BIAS1_PWD_IC25BB_LSB                                                                      13
-#define PHY_ANALOG_BIAS1_PWD_IC25BB_MASK                                                             0x0000e000
-#define PHY_ANALOG_BIAS1_PWD_IC25BB_GET(x)                                           (((x) & 0x0000e000) >> 13)
-#define PHY_ANALOG_BIAS1_PWD_IC25BB_SET(x)                                           (((x) << 13) & 0x0000e000)
-#define PHY_ANALOG_BIAS1_PWD_IC25DAC_MSB                                                                     18
-#define PHY_ANALOG_BIAS1_PWD_IC25DAC_LSB                                                                     16
-#define PHY_ANALOG_BIAS1_PWD_IC25DAC_MASK                                                            0x00070000
-#define PHY_ANALOG_BIAS1_PWD_IC25DAC_GET(x)                                          (((x) & 0x00070000) >> 16)
-#define PHY_ANALOG_BIAS1_PWD_IC25DAC_SET(x)                                          (((x) << 16) & 0x00070000)
-#define PHY_ANALOG_BIAS1_PWD_IC25FIR_MSB                                                                     21
-#define PHY_ANALOG_BIAS1_PWD_IC25FIR_LSB                                                                     19
-#define PHY_ANALOG_BIAS1_PWD_IC25FIR_MASK                                                            0x00380000
-#define PHY_ANALOG_BIAS1_PWD_IC25FIR_GET(x)                                          (((x) & 0x00380000) >> 19)
-#define PHY_ANALOG_BIAS1_PWD_IC25FIR_SET(x)                                          (((x) << 19) & 0x00380000)
-#define PHY_ANALOG_BIAS1_PWD_IC25ADC_MSB                                                                     24
-#define PHY_ANALOG_BIAS1_PWD_IC25ADC_LSB                                                                     22
-#define PHY_ANALOG_BIAS1_PWD_IC25ADC_MASK                                                            0x01c00000
-#define PHY_ANALOG_BIAS1_PWD_IC25ADC_GET(x)                                          (((x) & 0x01c00000) >> 22)
-#define PHY_ANALOG_BIAS1_PWD_IC25ADC_SET(x)                                          (((x) << 22) & 0x01c00000)
-#define PHY_ANALOG_BIAS1_BIAS_SEL_MSB                                                                        31
-#define PHY_ANALOG_BIAS1_BIAS_SEL_LSB                                                                        25
-#define PHY_ANALOG_BIAS1_BIAS_SEL_MASK                                                               0xfe000000
-#define PHY_ANALOG_BIAS1_BIAS_SEL_GET(x)                                             (((x) & 0xfe000000) >> 25)
-#define PHY_ANALOG_BIAS1_BIAS_SEL_SET(x)                                             (((x) << 25) & 0xfe000000)
-
-/* macros for BIAS2 */
-#define PHY_ANALOG_BIAS2_ADDRESS                                                                     0x000000c4
-#define PHY_ANALOG_BIAS2_OFFSET                                                                      0x000000c4
-#define PHY_ANALOG_BIAS2_SPARE2_MSB                                                                           4
-#define PHY_ANALOG_BIAS2_SPARE2_LSB                                                                           0
-#define PHY_ANALOG_BIAS2_SPARE2_MASK                                                                 0x0000001f
-#define PHY_ANALOG_BIAS2_SPARE2_GET(x)                                                (((x) & 0x0000001f) >> 0)
-#define PHY_ANALOG_BIAS2_SPARE2_SET(x)                                                (((x) << 0) & 0x0000001f)
-#define PHY_ANALOG_BIAS2_PWD_IC25XPA_MSB                                                                      7
-#define PHY_ANALOG_BIAS2_PWD_IC25XPA_LSB                                                                      5
-#define PHY_ANALOG_BIAS2_PWD_IC25XPA_MASK                                                            0x000000e0
-#define PHY_ANALOG_BIAS2_PWD_IC25XPA_GET(x)                                           (((x) & 0x000000e0) >> 5)
-#define PHY_ANALOG_BIAS2_PWD_IC25XPA_SET(x)                                           (((x) << 5) & 0x000000e0)
-#define PHY_ANALOG_BIAS2_PWD_IC25XTAL_MSB                                                                    10
-#define PHY_ANALOG_BIAS2_PWD_IC25XTAL_LSB                                                                     8
-#define PHY_ANALOG_BIAS2_PWD_IC25XTAL_MASK                                                           0x00000700
-#define PHY_ANALOG_BIAS2_PWD_IC25XTAL_GET(x)                                          (((x) & 0x00000700) >> 8)
-#define PHY_ANALOG_BIAS2_PWD_IC25XTAL_SET(x)                                          (((x) << 8) & 0x00000700)
-#define PHY_ANALOG_BIAS2_PWD_IC25TXRF_MSB                                                                    13
-#define PHY_ANALOG_BIAS2_PWD_IC25TXRF_LSB                                                                    11
-#define PHY_ANALOG_BIAS2_PWD_IC25TXRF_MASK                                                           0x00003800
-#define PHY_ANALOG_BIAS2_PWD_IC25TXRF_GET(x)                                         (((x) & 0x00003800) >> 11)
-#define PHY_ANALOG_BIAS2_PWD_IC25TXRF_SET(x)                                         (((x) << 11) & 0x00003800)
-#define PHY_ANALOG_BIAS2_PWD_IC25RXRF_MSB                                                                    16
-#define PHY_ANALOG_BIAS2_PWD_IC25RXRF_LSB                                                                    14
-#define PHY_ANALOG_BIAS2_PWD_IC25RXRF_MASK                                                           0x0001c000
-#define PHY_ANALOG_BIAS2_PWD_IC25RXRF_GET(x)                                         (((x) & 0x0001c000) >> 14)
-#define PHY_ANALOG_BIAS2_PWD_IC25RXRF_SET(x)                                         (((x) << 14) & 0x0001c000)
-#define PHY_ANALOG_BIAS2_PWD_IC25SYNTH_MSB                                                                   19
-#define PHY_ANALOG_BIAS2_PWD_IC25SYNTH_LSB                                                                   17
-#define PHY_ANALOG_BIAS2_PWD_IC25SYNTH_MASK                                                          0x000e0000
-#define PHY_ANALOG_BIAS2_PWD_IC25SYNTH_GET(x)                                        (((x) & 0x000e0000) >> 17)
-#define PHY_ANALOG_BIAS2_PWD_IC25SYNTH_SET(x)                                        (((x) << 17) & 0x000e0000)
-#define PHY_ANALOG_BIAS2_PWD_IC25PLLREG_MSB                                                                  22
-#define PHY_ANALOG_BIAS2_PWD_IC25PLLREG_LSB                                                                  20
-#define PHY_ANALOG_BIAS2_PWD_IC25PLLREG_MASK                                                         0x00700000
-#define PHY_ANALOG_BIAS2_PWD_IC25PLLREG_GET(x)                                       (((x) & 0x00700000) >> 20)
-#define PHY_ANALOG_BIAS2_PWD_IC25PLLREG_SET(x)                                       (((x) << 20) & 0x00700000)
-#define PHY_ANALOG_BIAS2_PWD_IC25PLLCP2_MSB                                                                  25
-#define PHY_ANALOG_BIAS2_PWD_IC25PLLCP2_LSB                                                                  23
-#define PHY_ANALOG_BIAS2_PWD_IC25PLLCP2_MASK                                                         0x03800000
-#define PHY_ANALOG_BIAS2_PWD_IC25PLLCP2_GET(x)                                       (((x) & 0x03800000) >> 23)
-#define PHY_ANALOG_BIAS2_PWD_IC25PLLCP2_SET(x)                                       (((x) << 23) & 0x03800000)
-#define PHY_ANALOG_BIAS2_PWD_IC25PLLCP_MSB                                                                   28
-#define PHY_ANALOG_BIAS2_PWD_IC25PLLCP_LSB                                                                   26
-#define PHY_ANALOG_BIAS2_PWD_IC25PLLCP_MASK                                                          0x1c000000
-#define PHY_ANALOG_BIAS2_PWD_IC25PLLCP_GET(x)                                        (((x) & 0x1c000000) >> 26)
-#define PHY_ANALOG_BIAS2_PWD_IC25PLLCP_SET(x)                                        (((x) << 26) & 0x1c000000)
-#define PHY_ANALOG_BIAS2_PWD_IC25PLLGM_MSB                                                                   31
-#define PHY_ANALOG_BIAS2_PWD_IC25PLLGM_LSB                                                                   29
-#define PHY_ANALOG_BIAS2_PWD_IC25PLLGM_MASK                                                          0xe0000000
-#define PHY_ANALOG_BIAS2_PWD_IC25PLLGM_GET(x)                                        (((x) & 0xe0000000) >> 29)
-#define PHY_ANALOG_BIAS2_PWD_IC25PLLGM_SET(x)                                        (((x) << 29) & 0xe0000000)
-
-/* macros for BIAS3 */
-#define PHY_ANALOG_BIAS3_ADDRESS                                                                     0x000000c8
-#define PHY_ANALOG_BIAS3_OFFSET                                                                      0x000000c8
-#define PHY_ANALOG_BIAS3_SPARE3_MSB                                                                           1
-#define PHY_ANALOG_BIAS3_SPARE3_LSB                                                                           0
-#define PHY_ANALOG_BIAS3_SPARE3_MASK                                                                 0x00000003
-#define PHY_ANALOG_BIAS3_SPARE3_GET(x)                                                (((x) & 0x00000003) >> 0)
-#define PHY_ANALOG_BIAS3_SPARE3_SET(x)                                                (((x) << 0) & 0x00000003)
-#define PHY_ANALOG_BIAS3_PWD_IR25SAR_MSB                                                                      4
-#define PHY_ANALOG_BIAS3_PWD_IR25SAR_LSB                                                                      2
-#define PHY_ANALOG_BIAS3_PWD_IR25SAR_MASK                                                            0x0000001c
-#define PHY_ANALOG_BIAS3_PWD_IR25SAR_GET(x)                                           (((x) & 0x0000001c) >> 2)
-#define PHY_ANALOG_BIAS3_PWD_IR25SAR_SET(x)                                           (((x) << 2) & 0x0000001c)
-#define PHY_ANALOG_BIAS3_PWD_IR25TXRF_MSB                                                                     7
-#define PHY_ANALOG_BIAS3_PWD_IR25TXRF_LSB                                                                     5
-#define PHY_ANALOG_BIAS3_PWD_IR25TXRF_MASK                                                           0x000000e0
-#define PHY_ANALOG_BIAS3_PWD_IR25TXRF_GET(x)                                          (((x) & 0x000000e0) >> 5)
-#define PHY_ANALOG_BIAS3_PWD_IR25TXRF_SET(x)                                          (((x) << 5) & 0x000000e0)
-#define PHY_ANALOG_BIAS3_PWD_IR25RXRF_MSB                                                                    10
-#define PHY_ANALOG_BIAS3_PWD_IR25RXRF_LSB                                                                     8
-#define PHY_ANALOG_BIAS3_PWD_IR25RXRF_MASK                                                           0x00000700
-#define PHY_ANALOG_BIAS3_PWD_IR25RXRF_GET(x)                                          (((x) & 0x00000700) >> 8)
-#define PHY_ANALOG_BIAS3_PWD_IR25RXRF_SET(x)                                          (((x) << 8) & 0x00000700)
-#define PHY_ANALOG_BIAS3_PWD_IR25SYNTH_MSB                                                                   13
-#define PHY_ANALOG_BIAS3_PWD_IR25SYNTH_LSB                                                                   11
-#define PHY_ANALOG_BIAS3_PWD_IR25SYNTH_MASK                                                          0x00003800
-#define PHY_ANALOG_BIAS3_PWD_IR25SYNTH_GET(x)                                        (((x) & 0x00003800) >> 11)
-#define PHY_ANALOG_BIAS3_PWD_IR25SYNTH_SET(x)                                        (((x) << 11) & 0x00003800)
-#define PHY_ANALOG_BIAS3_PWD_IR25PLLREG_MSB                                                                  16
-#define PHY_ANALOG_BIAS3_PWD_IR25PLLREG_LSB                                                                  14
-#define PHY_ANALOG_BIAS3_PWD_IR25PLLREG_MASK                                                         0x0001c000
-#define PHY_ANALOG_BIAS3_PWD_IR25PLLREG_GET(x)                                       (((x) & 0x0001c000) >> 14)
-#define PHY_ANALOG_BIAS3_PWD_IR25PLLREG_SET(x)                                       (((x) << 14) & 0x0001c000)
-#define PHY_ANALOG_BIAS3_PWD_IR25BB_MSB                                                                      19
-#define PHY_ANALOG_BIAS3_PWD_IR25BB_LSB                                                                      17
-#define PHY_ANALOG_BIAS3_PWD_IR25BB_MASK                                                             0x000e0000
-#define PHY_ANALOG_BIAS3_PWD_IR25BB_GET(x)                                           (((x) & 0x000e0000) >> 17)
-#define PHY_ANALOG_BIAS3_PWD_IR25BB_SET(x)                                           (((x) << 17) & 0x000e0000)
-#define PHY_ANALOG_BIAS3_PWD_IR50DAC_MSB                                                                     22
-#define PHY_ANALOG_BIAS3_PWD_IR50DAC_LSB                                                                     20
-#define PHY_ANALOG_BIAS3_PWD_IR50DAC_MASK                                                            0x00700000
-#define PHY_ANALOG_BIAS3_PWD_IR50DAC_GET(x)                                          (((x) & 0x00700000) >> 20)
-#define PHY_ANALOG_BIAS3_PWD_IR50DAC_SET(x)                                          (((x) << 20) & 0x00700000)
-#define PHY_ANALOG_BIAS3_PWD_IR25DAC_MSB                                                                     25
-#define PHY_ANALOG_BIAS3_PWD_IR25DAC_LSB                                                                     23
-#define PHY_ANALOG_BIAS3_PWD_IR25DAC_MASK                                                            0x03800000
-#define PHY_ANALOG_BIAS3_PWD_IR25DAC_GET(x)                                          (((x) & 0x03800000) >> 23)
-#define PHY_ANALOG_BIAS3_PWD_IR25DAC_SET(x)                                          (((x) << 23) & 0x03800000)
-#define PHY_ANALOG_BIAS3_PWD_IR25FIR_MSB                                                                     28
-#define PHY_ANALOG_BIAS3_PWD_IR25FIR_LSB                                                                     26
-#define PHY_ANALOG_BIAS3_PWD_IR25FIR_MASK                                                            0x1c000000
-#define PHY_ANALOG_BIAS3_PWD_IR25FIR_GET(x)                                          (((x) & 0x1c000000) >> 26)
-#define PHY_ANALOG_BIAS3_PWD_IR25FIR_SET(x)                                          (((x) << 26) & 0x1c000000)
-#define PHY_ANALOG_BIAS3_PWD_IR50ADC_MSB                                                                     31
-#define PHY_ANALOG_BIAS3_PWD_IR50ADC_LSB                                                                     29
-#define PHY_ANALOG_BIAS3_PWD_IR50ADC_MASK                                                            0xe0000000
-#define PHY_ANALOG_BIAS3_PWD_IR50ADC_GET(x)                                          (((x) & 0xe0000000) >> 29)
-#define PHY_ANALOG_BIAS3_PWD_IR50ADC_SET(x)                                          (((x) << 29) & 0xe0000000)
-
-/* macros for BIAS4 */
-#define PHY_ANALOG_BIAS4_ADDRESS                                                                     0x000000cc
-#define PHY_ANALOG_BIAS4_OFFSET                                                                      0x000000cc
-#define PHY_ANALOG_BIAS4_SPARE4_MSB                                                                          10
-#define PHY_ANALOG_BIAS4_SPARE4_LSB                                                                           0
-#define PHY_ANALOG_BIAS4_SPARE4_MASK                                                                 0x000007ff
-#define PHY_ANALOG_BIAS4_SPARE4_GET(x)                                                (((x) & 0x000007ff) >> 0)
-#define PHY_ANALOG_BIAS4_SPARE4_SET(x)                                                (((x) << 0) & 0x000007ff)
-#define PHY_ANALOG_BIAS4_PWD_IR25SPARED_MSB                                                                  13
-#define PHY_ANALOG_BIAS4_PWD_IR25SPARED_LSB                                                                  11
-#define PHY_ANALOG_BIAS4_PWD_IR25SPARED_MASK                                                         0x00003800
-#define PHY_ANALOG_BIAS4_PWD_IR25SPARED_GET(x)                                       (((x) & 0x00003800) >> 11)
-#define PHY_ANALOG_BIAS4_PWD_IR25SPARED_SET(x)                                       (((x) << 11) & 0x00003800)
-#define PHY_ANALOG_BIAS4_PWD_IR25SPAREC_MSB                                                                  16
-#define PHY_ANALOG_BIAS4_PWD_IR25SPAREC_LSB                                                                  14
-#define PHY_ANALOG_BIAS4_PWD_IR25SPAREC_MASK                                                         0x0001c000
-#define PHY_ANALOG_BIAS4_PWD_IR25SPAREC_GET(x)                                       (((x) & 0x0001c000) >> 14)
-#define PHY_ANALOG_BIAS4_PWD_IR25SPAREC_SET(x)                                       (((x) << 14) & 0x0001c000)
-#define PHY_ANALOG_BIAS4_PWD_IR25SPAREB_MSB                                                                  19
-#define PHY_ANALOG_BIAS4_PWD_IR25SPAREB_LSB                                                                  17
-#define PHY_ANALOG_BIAS4_PWD_IR25SPAREB_MASK                                                         0x000e0000
-#define PHY_ANALOG_BIAS4_PWD_IR25SPAREB_GET(x)                                       (((x) & 0x000e0000) >> 17)
-#define PHY_ANALOG_BIAS4_PWD_IR25SPAREB_SET(x)                                       (((x) << 17) & 0x000e0000)
-#define PHY_ANALOG_BIAS4_PWD_IR25XPA_MSB                                                                     22
-#define PHY_ANALOG_BIAS4_PWD_IR25XPA_LSB                                                                     20
-#define PHY_ANALOG_BIAS4_PWD_IR25XPA_MASK                                                            0x00700000
-#define PHY_ANALOG_BIAS4_PWD_IR25XPA_GET(x)                                          (((x) & 0x00700000) >> 20)
-#define PHY_ANALOG_BIAS4_PWD_IR25XPA_SET(x)                                          (((x) << 20) & 0x00700000)
-#define PHY_ANALOG_BIAS4_PWD_IC25SPAREC_MSB                                                                  25
-#define PHY_ANALOG_BIAS4_PWD_IC25SPAREC_LSB                                                                  23
-#define PHY_ANALOG_BIAS4_PWD_IC25SPAREC_MASK                                                         0x03800000
-#define PHY_ANALOG_BIAS4_PWD_IC25SPAREC_GET(x)                                       (((x) & 0x03800000) >> 23)
-#define PHY_ANALOG_BIAS4_PWD_IC25SPAREC_SET(x)                                       (((x) << 23) & 0x03800000)
-#define PHY_ANALOG_BIAS4_PWD_IC25SPAREB_MSB                                                                  28
-#define PHY_ANALOG_BIAS4_PWD_IC25SPAREB_LSB                                                                  26
-#define PHY_ANALOG_BIAS4_PWD_IC25SPAREB_MASK                                                         0x1c000000
-#define PHY_ANALOG_BIAS4_PWD_IC25SPAREB_GET(x)                                       (((x) & 0x1c000000) >> 26)
-#define PHY_ANALOG_BIAS4_PWD_IC25SPAREB_SET(x)                                       (((x) << 26) & 0x1c000000)
-#define PHY_ANALOG_BIAS4_PWD_IC25SPAREA_MSB                                                                  31
-#define PHY_ANALOG_BIAS4_PWD_IC25SPAREA_LSB                                                                  29
-#define PHY_ANALOG_BIAS4_PWD_IC25SPAREA_MASK                                                         0xe0000000
-#define PHY_ANALOG_BIAS4_PWD_IC25SPAREA_GET(x)                                       (((x) & 0xe0000000) >> 29)
-#define PHY_ANALOG_BIAS4_PWD_IC25SPAREA_SET(x)                                       (((x) << 29) & 0xe0000000)
-
-/* macros for RXTX1 */
-#define PHY_ANALOG_RXTX1_ADDRESS                                                                     0x00000100
-#define PHY_ANALOG_RXTX1_OFFSET                                                                      0x00000100
-#define PHY_ANALOG_RXTX1_SCFIR_GAIN_MSB                                                                       0
-#define PHY_ANALOG_RXTX1_SCFIR_GAIN_LSB                                                                       0
-#define PHY_ANALOG_RXTX1_SCFIR_GAIN_MASK                                                             0x00000001
-#define PHY_ANALOG_RXTX1_SCFIR_GAIN_GET(x)                                            (((x) & 0x00000001) >> 0)
-#define PHY_ANALOG_RXTX1_SCFIR_GAIN_SET(x)                                            (((x) << 0) & 0x00000001)
-#define PHY_ANALOG_RXTX1_MANRXGAIN_MSB                                                                        1
-#define PHY_ANALOG_RXTX1_MANRXGAIN_LSB                                                                        1
-#define PHY_ANALOG_RXTX1_MANRXGAIN_MASK                                                              0x00000002
-#define PHY_ANALOG_RXTX1_MANRXGAIN_GET(x)                                             (((x) & 0x00000002) >> 1)
-#define PHY_ANALOG_RXTX1_MANRXGAIN_SET(x)                                             (((x) << 1) & 0x00000002)
-#define PHY_ANALOG_RXTX1_AGC_DBDAC_MSB                                                                        5
-#define PHY_ANALOG_RXTX1_AGC_DBDAC_LSB                                                                        2
-#define PHY_ANALOG_RXTX1_AGC_DBDAC_MASK                                                              0x0000003c
-#define PHY_ANALOG_RXTX1_AGC_DBDAC_GET(x)                                             (((x) & 0x0000003c) >> 2)
-#define PHY_ANALOG_RXTX1_AGC_DBDAC_SET(x)                                             (((x) << 2) & 0x0000003c)
-#define PHY_ANALOG_RXTX1_OVR_AGC_DBDAC_MSB                                                                    6
-#define PHY_ANALOG_RXTX1_OVR_AGC_DBDAC_LSB                                                                    6
-#define PHY_ANALOG_RXTX1_OVR_AGC_DBDAC_MASK                                                          0x00000040
-#define PHY_ANALOG_RXTX1_OVR_AGC_DBDAC_GET(x)                                         (((x) & 0x00000040) >> 6)
-#define PHY_ANALOG_RXTX1_OVR_AGC_DBDAC_SET(x)                                         (((x) << 6) & 0x00000040)
-#define PHY_ANALOG_RXTX1_ENABLE_PAL_MSB                                                                       7
-#define PHY_ANALOG_RXTX1_ENABLE_PAL_LSB                                                                       7
-#define PHY_ANALOG_RXTX1_ENABLE_PAL_MASK                                                             0x00000080
-#define PHY_ANALOG_RXTX1_ENABLE_PAL_GET(x)                                            (((x) & 0x00000080) >> 7)
-#define PHY_ANALOG_RXTX1_ENABLE_PAL_SET(x)                                            (((x) << 7) & 0x00000080)
-#define PHY_ANALOG_RXTX1_ENABLE_PAL_OVR_MSB                                                                   8
-#define PHY_ANALOG_RXTX1_ENABLE_PAL_OVR_LSB                                                                   8
-#define PHY_ANALOG_RXTX1_ENABLE_PAL_OVR_MASK                                                         0x00000100
-#define PHY_ANALOG_RXTX1_ENABLE_PAL_OVR_GET(x)                                        (((x) & 0x00000100) >> 8)
-#define PHY_ANALOG_RXTX1_ENABLE_PAL_OVR_SET(x)                                        (((x) << 8) & 0x00000100)
-#define PHY_ANALOG_RXTX1_TX1DB_BIQUAD_MSB                                                                    11
-#define PHY_ANALOG_RXTX1_TX1DB_BIQUAD_LSB                                                                     9
-#define PHY_ANALOG_RXTX1_TX1DB_BIQUAD_MASK                                                           0x00000e00
-#define PHY_ANALOG_RXTX1_TX1DB_BIQUAD_GET(x)                                          (((x) & 0x00000e00) >> 9)
-#define PHY_ANALOG_RXTX1_TX1DB_BIQUAD_SET(x)                                          (((x) << 9) & 0x00000e00)
-#define PHY_ANALOG_RXTX1_TX6DB_BIQUAD_MSB                                                                    13
-#define PHY_ANALOG_RXTX1_TX6DB_BIQUAD_LSB                                                                    12
-#define PHY_ANALOG_RXTX1_TX6DB_BIQUAD_MASK                                                           0x00003000
-#define PHY_ANALOG_RXTX1_TX6DB_BIQUAD_GET(x)                                         (((x) & 0x00003000) >> 12)
-#define PHY_ANALOG_RXTX1_TX6DB_BIQUAD_SET(x)                                         (((x) << 12) & 0x00003000)
-#define PHY_ANALOG_RXTX1_PADRVHALFGN2G_MSB                                                                   14
-#define PHY_ANALOG_RXTX1_PADRVHALFGN2G_LSB                                                                   14
-#define PHY_ANALOG_RXTX1_PADRVHALFGN2G_MASK                                                          0x00004000
-#define PHY_ANALOG_RXTX1_PADRVHALFGN2G_GET(x)                                        (((x) & 0x00004000) >> 14)
-#define PHY_ANALOG_RXTX1_PADRVHALFGN2G_SET(x)                                        (((x) << 14) & 0x00004000)
-#define PHY_ANALOG_RXTX1_PADRV2GN_MSB                                                                        18
-#define PHY_ANALOG_RXTX1_PADRV2GN_LSB                                                                        15
-#define PHY_ANALOG_RXTX1_PADRV2GN_MASK                                                               0x00078000
-#define PHY_ANALOG_RXTX1_PADRV2GN_GET(x)                                             (((x) & 0x00078000) >> 15)
-#define PHY_ANALOG_RXTX1_PADRV2GN_SET(x)                                             (((x) << 15) & 0x00078000)
-#define PHY_ANALOG_RXTX1_PADRV3GN5G_MSB                                                                      22
-#define PHY_ANALOG_RXTX1_PADRV3GN5G_LSB                                                                      19
-#define PHY_ANALOG_RXTX1_PADRV3GN5G_MASK                                                             0x00780000
-#define PHY_ANALOG_RXTX1_PADRV3GN5G_GET(x)                                           (((x) & 0x00780000) >> 19)
-#define PHY_ANALOG_RXTX1_PADRV3GN5G_SET(x)                                           (((x) << 19) & 0x00780000)
-#define PHY_ANALOG_RXTX1_PADRV4GN5G_MSB                                                                      26
-#define PHY_ANALOG_RXTX1_PADRV4GN5G_LSB                                                                      23
-#define PHY_ANALOG_RXTX1_PADRV4GN5G_MASK                                                             0x07800000
-#define PHY_ANALOG_RXTX1_PADRV4GN5G_GET(x)                                           (((x) & 0x07800000) >> 23)
-#define PHY_ANALOG_RXTX1_PADRV4GN5G_SET(x)                                           (((x) << 23) & 0x07800000)
-#define PHY_ANALOG_RXTX1_TXBB_GC_MSB                                                                         30
-#define PHY_ANALOG_RXTX1_TXBB_GC_LSB                                                                         27
-#define PHY_ANALOG_RXTX1_TXBB_GC_MASK                                                                0x78000000
-#define PHY_ANALOG_RXTX1_TXBB_GC_GET(x)                                              (((x) & 0x78000000) >> 27)
-#define PHY_ANALOG_RXTX1_TXBB_GC_SET(x)                                              (((x) << 27) & 0x78000000)
-#define PHY_ANALOG_RXTX1_MANTXGAIN_MSB                                                                       31
-#define PHY_ANALOG_RXTX1_MANTXGAIN_LSB                                                                       31
-#define PHY_ANALOG_RXTX1_MANTXGAIN_MASK                                                              0x80000000
-#define PHY_ANALOG_RXTX1_MANTXGAIN_GET(x)                                            (((x) & 0x80000000) >> 31)
-#define PHY_ANALOG_RXTX1_MANTXGAIN_SET(x)                                            (((x) << 31) & 0x80000000)
-
-/* macros for RXTX2 */
-#define PHY_ANALOG_RXTX2_ADDRESS                                                                     0x00000104
-#define PHY_ANALOG_RXTX2_OFFSET                                                                      0x00000104
-#define PHY_ANALOG_RXTX2_BMODE_MSB                                                                            0
-#define PHY_ANALOG_RXTX2_BMODE_LSB                                                                            0
-#define PHY_ANALOG_RXTX2_BMODE_MASK                                                                  0x00000001
-#define PHY_ANALOG_RXTX2_BMODE_GET(x)                                                 (((x) & 0x00000001) >> 0)
-#define PHY_ANALOG_RXTX2_BMODE_SET(x)                                                 (((x) << 0) & 0x00000001)
-#define PHY_ANALOG_RXTX2_BMODE_OVR_MSB                                                                        1
-#define PHY_ANALOG_RXTX2_BMODE_OVR_LSB                                                                        1
-#define PHY_ANALOG_RXTX2_BMODE_OVR_MASK                                                              0x00000002
-#define PHY_ANALOG_RXTX2_BMODE_OVR_GET(x)                                             (((x) & 0x00000002) >> 1)
-#define PHY_ANALOG_RXTX2_BMODE_OVR_SET(x)                                             (((x) << 1) & 0x00000002)
-#define PHY_ANALOG_RXTX2_SYNTHON_MSB                                                                          2
-#define PHY_ANALOG_RXTX2_SYNTHON_LSB                                                                          2
-#define PHY_ANALOG_RXTX2_SYNTHON_MASK                                                                0x00000004
-#define PHY_ANALOG_RXTX2_SYNTHON_GET(x)                                               (((x) & 0x00000004) >> 2)
-#define PHY_ANALOG_RXTX2_SYNTHON_SET(x)                                               (((x) << 2) & 0x00000004)
-#define PHY_ANALOG_RXTX2_SYNTHON_OVR_MSB                                                                      3
-#define PHY_ANALOG_RXTX2_SYNTHON_OVR_LSB                                                                      3
-#define PHY_ANALOG_RXTX2_SYNTHON_OVR_MASK                                                            0x00000008
-#define PHY_ANALOG_RXTX2_SYNTHON_OVR_GET(x)                                           (((x) & 0x00000008) >> 3)
-#define PHY_ANALOG_RXTX2_SYNTHON_OVR_SET(x)                                           (((x) << 3) & 0x00000008)
-#define PHY_ANALOG_RXTX2_BW_ST_MSB                                                                            5
-#define PHY_ANALOG_RXTX2_BW_ST_LSB                                                                            4
-#define PHY_ANALOG_RXTX2_BW_ST_MASK                                                                  0x00000030
-#define PHY_ANALOG_RXTX2_BW_ST_GET(x)                                                 (((x) & 0x00000030) >> 4)
-#define PHY_ANALOG_RXTX2_BW_ST_SET(x)                                                 (((x) << 4) & 0x00000030)
-#define PHY_ANALOG_RXTX2_BW_ST_OVR_MSB                                                                        6
-#define PHY_ANALOG_RXTX2_BW_ST_OVR_LSB                                                                        6
-#define PHY_ANALOG_RXTX2_BW_ST_OVR_MASK                                                              0x00000040
-#define PHY_ANALOG_RXTX2_BW_ST_OVR_GET(x)                                             (((x) & 0x00000040) >> 6)
-#define PHY_ANALOG_RXTX2_BW_ST_OVR_SET(x)                                             (((x) << 6) & 0x00000040)
-#define PHY_ANALOG_RXTX2_TXON_MSB                                                                             7
-#define PHY_ANALOG_RXTX2_TXON_LSB                                                                             7
-#define PHY_ANALOG_RXTX2_TXON_MASK                                                                   0x00000080
-#define PHY_ANALOG_RXTX2_TXON_GET(x)                                                  (((x) & 0x00000080) >> 7)
-#define PHY_ANALOG_RXTX2_TXON_SET(x)                                                  (((x) << 7) & 0x00000080)
-#define PHY_ANALOG_RXTX2_TXON_OVR_MSB                                                                         8
-#define PHY_ANALOG_RXTX2_TXON_OVR_LSB                                                                         8
-#define PHY_ANALOG_RXTX2_TXON_OVR_MASK                                                               0x00000100
-#define PHY_ANALOG_RXTX2_TXON_OVR_GET(x)                                              (((x) & 0x00000100) >> 8)
-#define PHY_ANALOG_RXTX2_TXON_OVR_SET(x)                                              (((x) << 8) & 0x00000100)
-#define PHY_ANALOG_RXTX2_PAON_MSB                                                                             9
-#define PHY_ANALOG_RXTX2_PAON_LSB                                                                             9
-#define PHY_ANALOG_RXTX2_PAON_MASK                                                                   0x00000200
-#define PHY_ANALOG_RXTX2_PAON_GET(x)                                                  (((x) & 0x00000200) >> 9)
-#define PHY_ANALOG_RXTX2_PAON_SET(x)                                                  (((x) << 9) & 0x00000200)
-#define PHY_ANALOG_RXTX2_PAON_OVR_MSB                                                                        10
-#define PHY_ANALOG_RXTX2_PAON_OVR_LSB                                                                        10
-#define PHY_ANALOG_RXTX2_PAON_OVR_MASK                                                               0x00000400
-#define PHY_ANALOG_RXTX2_PAON_OVR_GET(x)                                             (((x) & 0x00000400) >> 10)
-#define PHY_ANALOG_RXTX2_PAON_OVR_SET(x)                                             (((x) << 10) & 0x00000400)
-#define PHY_ANALOG_RXTX2_RXON_MSB                                                                            11
-#define PHY_ANALOG_RXTX2_RXON_LSB                                                                            11
-#define PHY_ANALOG_RXTX2_RXON_MASK                                                                   0x00000800
-#define PHY_ANALOG_RXTX2_RXON_GET(x)                                                 (((x) & 0x00000800) >> 11)
-#define PHY_ANALOG_RXTX2_RXON_SET(x)                                                 (((x) << 11) & 0x00000800)
-#define PHY_ANALOG_RXTX2_RXON_OVR_MSB                                                                        12
-#define PHY_ANALOG_RXTX2_RXON_OVR_LSB                                                                        12
-#define PHY_ANALOG_RXTX2_RXON_OVR_MASK                                                               0x00001000
-#define PHY_ANALOG_RXTX2_RXON_OVR_GET(x)                                             (((x) & 0x00001000) >> 12)
-#define PHY_ANALOG_RXTX2_RXON_OVR_SET(x)                                             (((x) << 12) & 0x00001000)
-#define PHY_ANALOG_RXTX2_AGCON_MSB                                                                           13
-#define PHY_ANALOG_RXTX2_AGCON_LSB                                                                           13
-#define PHY_ANALOG_RXTX2_AGCON_MASK                                                                  0x00002000
-#define PHY_ANALOG_RXTX2_AGCON_GET(x)                                                (((x) & 0x00002000) >> 13)
-#define PHY_ANALOG_RXTX2_AGCON_SET(x)                                                (((x) << 13) & 0x00002000)
-#define PHY_ANALOG_RXTX2_AGCON_OVR_MSB                                                                       14
-#define PHY_ANALOG_RXTX2_AGCON_OVR_LSB                                                                       14
-#define PHY_ANALOG_RXTX2_AGCON_OVR_MASK                                                              0x00004000
-#define PHY_ANALOG_RXTX2_AGCON_OVR_GET(x)                                            (((x) & 0x00004000) >> 14)
-#define PHY_ANALOG_RXTX2_AGCON_OVR_SET(x)                                            (((x) << 14) & 0x00004000)
-#define PHY_ANALOG_RXTX2_TXMOD_MSB                                                                           17
-#define PHY_ANALOG_RXTX2_TXMOD_LSB                                                                           15
-#define PHY_ANALOG_RXTX2_TXMOD_MASK                                                                  0x00038000
-#define PHY_ANALOG_RXTX2_TXMOD_GET(x)                                                (((x) & 0x00038000) >> 15)
-#define PHY_ANALOG_RXTX2_TXMOD_SET(x)                                                (((x) << 15) & 0x00038000)
-#define PHY_ANALOG_RXTX2_TXMOD_OVR_MSB                                                                       18
-#define PHY_ANALOG_RXTX2_TXMOD_OVR_LSB                                                                       18
-#define PHY_ANALOG_RXTX2_TXMOD_OVR_MASK                                                              0x00040000
-#define PHY_ANALOG_RXTX2_TXMOD_OVR_GET(x)                                            (((x) & 0x00040000) >> 18)
-#define PHY_ANALOG_RXTX2_TXMOD_OVR_SET(x)                                            (((x) << 18) & 0x00040000)
-#define PHY_ANALOG_RXTX2_RX1DB_BIQUAD_MSB                                                                    21
-#define PHY_ANALOG_RXTX2_RX1DB_BIQUAD_LSB                                                                    19
-#define PHY_ANALOG_RXTX2_RX1DB_BIQUAD_MASK                                                           0x00380000
-#define PHY_ANALOG_RXTX2_RX1DB_BIQUAD_GET(x)                                         (((x) & 0x00380000) >> 19)
-#define PHY_ANALOG_RXTX2_RX1DB_BIQUAD_SET(x)                                         (((x) << 19) & 0x00380000)
-#define PHY_ANALOG_RXTX2_RX6DB_BIQUAD_MSB                                                                    23
-#define PHY_ANALOG_RXTX2_RX6DB_BIQUAD_LSB                                                                    22
-#define PHY_ANALOG_RXTX2_RX6DB_BIQUAD_MASK                                                           0x00c00000
-#define PHY_ANALOG_RXTX2_RX6DB_BIQUAD_GET(x)                                         (((x) & 0x00c00000) >> 22)
-#define PHY_ANALOG_RXTX2_RX6DB_BIQUAD_SET(x)                                         (((x) << 22) & 0x00c00000)
-#define PHY_ANALOG_RXTX2_MXRGAIN_MSB                                                                         25
-#define PHY_ANALOG_RXTX2_MXRGAIN_LSB                                                                         24
-#define PHY_ANALOG_RXTX2_MXRGAIN_MASK                                                                0x03000000
-#define PHY_ANALOG_RXTX2_MXRGAIN_GET(x)                                              (((x) & 0x03000000) >> 24)
-#define PHY_ANALOG_RXTX2_MXRGAIN_SET(x)                                              (((x) << 24) & 0x03000000)
-#define PHY_ANALOG_RXTX2_VGAGAIN_MSB                                                                         28
-#define PHY_ANALOG_RXTX2_VGAGAIN_LSB                                                                         26
-#define PHY_ANALOG_RXTX2_VGAGAIN_MASK                                                                0x1c000000
-#define PHY_ANALOG_RXTX2_VGAGAIN_GET(x)                                              (((x) & 0x1c000000) >> 26)
-#define PHY_ANALOG_RXTX2_VGAGAIN_SET(x)                                              (((x) << 26) & 0x1c000000)
-#define PHY_ANALOG_RXTX2_LNAGAIN_MSB                                                                         31
-#define PHY_ANALOG_RXTX2_LNAGAIN_LSB                                                                         29
-#define PHY_ANALOG_RXTX2_LNAGAIN_MASK                                                                0xe0000000
-#define PHY_ANALOG_RXTX2_LNAGAIN_GET(x)                                              (((x) & 0xe0000000) >> 29)
-#define PHY_ANALOG_RXTX2_LNAGAIN_SET(x)                                              (((x) << 29) & 0xe0000000)
-
-/* macros for RXTX3 */
-#define PHY_ANALOG_RXTX3_ADDRESS                                                                     0x00000108
-#define PHY_ANALOG_RXTX3_OFFSET                                                                      0x00000108
-#define PHY_ANALOG_RXTX3_SPARE3_MSB                                                                           2
-#define PHY_ANALOG_RXTX3_SPARE3_LSB                                                                           0
-#define PHY_ANALOG_RXTX3_SPARE3_MASK                                                                 0x00000007
-#define PHY_ANALOG_RXTX3_SPARE3_GET(x)                                                (((x) & 0x00000007) >> 0)
-#define PHY_ANALOG_RXTX3_SPARE3_SET(x)                                                (((x) << 0) & 0x00000007)
-#define PHY_ANALOG_RXTX3_SPURON_MSB                                                                           3
-#define PHY_ANALOG_RXTX3_SPURON_LSB                                                                           3
-#define PHY_ANALOG_RXTX3_SPURON_MASK                                                                 0x00000008
-#define PHY_ANALOG_RXTX3_SPURON_GET(x)                                                (((x) & 0x00000008) >> 3)
-#define PHY_ANALOG_RXTX3_SPURON_SET(x)                                                (((x) << 3) & 0x00000008)
-#define PHY_ANALOG_RXTX3_PAL_LOCKEDEN_MSB                                                                     4
-#define PHY_ANALOG_RXTX3_PAL_LOCKEDEN_LSB                                                                     4
-#define PHY_ANALOG_RXTX3_PAL_LOCKEDEN_MASK                                                           0x00000010
-#define PHY_ANALOG_RXTX3_PAL_LOCKEDEN_GET(x)                                          (((x) & 0x00000010) >> 4)
-#define PHY_ANALOG_RXTX3_PAL_LOCKEDEN_SET(x)                                          (((x) << 4) & 0x00000010)
-#define PHY_ANALOG_RXTX3_DACFULLSCALE_MSB                                                                     5
-#define PHY_ANALOG_RXTX3_DACFULLSCALE_LSB                                                                     5
-#define PHY_ANALOG_RXTX3_DACFULLSCALE_MASK                                                           0x00000020
-#define PHY_ANALOG_RXTX3_DACFULLSCALE_GET(x)                                          (((x) & 0x00000020) >> 5)
-#define PHY_ANALOG_RXTX3_DACFULLSCALE_SET(x)                                          (((x) << 5) & 0x00000020)
-#define PHY_ANALOG_RXTX3_ADCSHORT_MSB                                                                         6
-#define PHY_ANALOG_RXTX3_ADCSHORT_LSB                                                                         6
-#define PHY_ANALOG_RXTX3_ADCSHORT_MASK                                                               0x00000040
-#define PHY_ANALOG_RXTX3_ADCSHORT_GET(x)                                              (((x) & 0x00000040) >> 6)
-#define PHY_ANALOG_RXTX3_ADCSHORT_SET(x)                                              (((x) << 6) & 0x00000040)
-#define PHY_ANALOG_RXTX3_DACPWD_MSB                                                                           7
-#define PHY_ANALOG_RXTX3_DACPWD_LSB                                                                           7
-#define PHY_ANALOG_RXTX3_DACPWD_MASK                                                                 0x00000080
-#define PHY_ANALOG_RXTX3_DACPWD_GET(x)                                                (((x) & 0x00000080) >> 7)
-#define PHY_ANALOG_RXTX3_DACPWD_SET(x)                                                (((x) << 7) & 0x00000080)
-#define PHY_ANALOG_RXTX3_DACPWD_OVR_MSB                                                                       8
-#define PHY_ANALOG_RXTX3_DACPWD_OVR_LSB                                                                       8
-#define PHY_ANALOG_RXTX3_DACPWD_OVR_MASK                                                             0x00000100
-#define PHY_ANALOG_RXTX3_DACPWD_OVR_GET(x)                                            (((x) & 0x00000100) >> 8)
-#define PHY_ANALOG_RXTX3_DACPWD_OVR_SET(x)                                            (((x) << 8) & 0x00000100)
-#define PHY_ANALOG_RXTX3_ADCPWD_MSB                                                                           9
-#define PHY_ANALOG_RXTX3_ADCPWD_LSB                                                                           9
-#define PHY_ANALOG_RXTX3_ADCPWD_MASK                                                                 0x00000200
-#define PHY_ANALOG_RXTX3_ADCPWD_GET(x)                                                (((x) & 0x00000200) >> 9)
-#define PHY_ANALOG_RXTX3_ADCPWD_SET(x)                                                (((x) << 9) & 0x00000200)
-#define PHY_ANALOG_RXTX3_ADCPWD_OVR_MSB                                                                      10
-#define PHY_ANALOG_RXTX3_ADCPWD_OVR_LSB                                                                      10
-#define PHY_ANALOG_RXTX3_ADCPWD_OVR_MASK                                                             0x00000400
-#define PHY_ANALOG_RXTX3_ADCPWD_OVR_GET(x)                                           (((x) & 0x00000400) >> 10)
-#define PHY_ANALOG_RXTX3_ADCPWD_OVR_SET(x)                                           (((x) << 10) & 0x00000400)
-#define PHY_ANALOG_RXTX3_AGC_CALDAC_MSB                                                                      16
-#define PHY_ANALOG_RXTX3_AGC_CALDAC_LSB                                                                      11
-#define PHY_ANALOG_RXTX3_AGC_CALDAC_MASK                                                             0x0001f800
-#define PHY_ANALOG_RXTX3_AGC_CALDAC_GET(x)                                           (((x) & 0x0001f800) >> 11)
-#define PHY_ANALOG_RXTX3_AGC_CALDAC_SET(x)                                           (((x) << 11) & 0x0001f800)
-#define PHY_ANALOG_RXTX3_AGC_CAL_MSB                                                                         17
-#define PHY_ANALOG_RXTX3_AGC_CAL_LSB                                                                         17
-#define PHY_ANALOG_RXTX3_AGC_CAL_MASK                                                                0x00020000
-#define PHY_ANALOG_RXTX3_AGC_CAL_GET(x)                                              (((x) & 0x00020000) >> 17)
-#define PHY_ANALOG_RXTX3_AGC_CAL_SET(x)                                              (((x) << 17) & 0x00020000)
-#define PHY_ANALOG_RXTX3_AGC_CAL_OVR_MSB                                                                     18
-#define PHY_ANALOG_RXTX3_AGC_CAL_OVR_LSB                                                                     18
-#define PHY_ANALOG_RXTX3_AGC_CAL_OVR_MASK                                                            0x00040000
-#define PHY_ANALOG_RXTX3_AGC_CAL_OVR_GET(x)                                          (((x) & 0x00040000) >> 18)
-#define PHY_ANALOG_RXTX3_AGC_CAL_OVR_SET(x)                                          (((x) << 18) & 0x00040000)
-#define PHY_ANALOG_RXTX3_LOFORCEDON_MSB                                                                      19
-#define PHY_ANALOG_RXTX3_LOFORCEDON_LSB                                                                      19
-#define PHY_ANALOG_RXTX3_LOFORCEDON_MASK                                                             0x00080000
-#define PHY_ANALOG_RXTX3_LOFORCEDON_GET(x)                                           (((x) & 0x00080000) >> 19)
-#define PHY_ANALOG_RXTX3_LOFORCEDON_SET(x)                                           (((x) << 19) & 0x00080000)
-#define PHY_ANALOG_RXTX3_CALRESIDUE_MSB                                                                      20
-#define PHY_ANALOG_RXTX3_CALRESIDUE_LSB                                                                      20
-#define PHY_ANALOG_RXTX3_CALRESIDUE_MASK                                                             0x00100000
-#define PHY_ANALOG_RXTX3_CALRESIDUE_GET(x)                                           (((x) & 0x00100000) >> 20)
-#define PHY_ANALOG_RXTX3_CALRESIDUE_SET(x)                                           (((x) << 20) & 0x00100000)
-#define PHY_ANALOG_RXTX3_CALRESIDUE_OVR_MSB                                                                  21
-#define PHY_ANALOG_RXTX3_CALRESIDUE_OVR_LSB                                                                  21
-#define PHY_ANALOG_RXTX3_CALRESIDUE_OVR_MASK                                                         0x00200000
-#define PHY_ANALOG_RXTX3_CALRESIDUE_OVR_GET(x)                                       (((x) & 0x00200000) >> 21)
-#define PHY_ANALOG_RXTX3_CALRESIDUE_OVR_SET(x)                                       (((x) << 21) & 0x00200000)
-#define PHY_ANALOG_RXTX3_CALFC_MSB                                                                           22
-#define PHY_ANALOG_RXTX3_CALFC_LSB                                                                           22
-#define PHY_ANALOG_RXTX3_CALFC_MASK                                                                  0x00400000
-#define PHY_ANALOG_RXTX3_CALFC_GET(x)                                                (((x) & 0x00400000) >> 22)
-#define PHY_ANALOG_RXTX3_CALFC_SET(x)                                                (((x) << 22) & 0x00400000)
-#define PHY_ANALOG_RXTX3_CALFC_OVR_MSB                                                                       23
-#define PHY_ANALOG_RXTX3_CALFC_OVR_LSB                                                                       23
-#define PHY_ANALOG_RXTX3_CALFC_OVR_MASK                                                              0x00800000
-#define PHY_ANALOG_RXTX3_CALFC_OVR_GET(x)                                            (((x) & 0x00800000) >> 23)
-#define PHY_ANALOG_RXTX3_CALFC_OVR_SET(x)                                            (((x) << 23) & 0x00800000)
-#define PHY_ANALOG_RXTX3_CALTX_MSB                                                                           24
-#define PHY_ANALOG_RXTX3_CALTX_LSB                                                                           24
-#define PHY_ANALOG_RXTX3_CALTX_MASK                                                                  0x01000000
-#define PHY_ANALOG_RXTX3_CALTX_GET(x)                                                (((x) & 0x01000000) >> 24)
-#define PHY_ANALOG_RXTX3_CALTX_SET(x)                                                (((x) << 24) & 0x01000000)
-#define PHY_ANALOG_RXTX3_CALTX_OVR_MSB                                                                       25
-#define PHY_ANALOG_RXTX3_CALTX_OVR_LSB                                                                       25
-#define PHY_ANALOG_RXTX3_CALTX_OVR_MASK                                                              0x02000000
-#define PHY_ANALOG_RXTX3_CALTX_OVR_GET(x)                                            (((x) & 0x02000000) >> 25)
-#define PHY_ANALOG_RXTX3_CALTX_OVR_SET(x)                                            (((x) << 25) & 0x02000000)
-#define PHY_ANALOG_RXTX3_CALTXSHIFT_MSB                                                                      26
-#define PHY_ANALOG_RXTX3_CALTXSHIFT_LSB                                                                      26
-#define PHY_ANALOG_RXTX3_CALTXSHIFT_MASK                                                             0x04000000
-#define PHY_ANALOG_RXTX3_CALTXSHIFT_GET(x)                                           (((x) & 0x04000000) >> 26)
-#define PHY_ANALOG_RXTX3_CALTXSHIFT_SET(x)                                           (((x) << 26) & 0x04000000)
-#define PHY_ANALOG_RXTX3_CALTXSHIFT_OVR_MSB                                                                  27
-#define PHY_ANALOG_RXTX3_CALTXSHIFT_OVR_LSB                                                                  27
-#define PHY_ANALOG_RXTX3_CALTXSHIFT_OVR_MASK                                                         0x08000000
-#define PHY_ANALOG_RXTX3_CALTXSHIFT_OVR_GET(x)                                       (((x) & 0x08000000) >> 27)
-#define PHY_ANALOG_RXTX3_CALTXSHIFT_OVR_SET(x)                                       (((x) << 27) & 0x08000000)
-#define PHY_ANALOG_RXTX3_CALPA_MSB                                                                           28
-#define PHY_ANALOG_RXTX3_CALPA_LSB                                                                           28
-#define PHY_ANALOG_RXTX3_CALPA_MASK                                                                  0x10000000
-#define PHY_ANALOG_RXTX3_CALPA_GET(x)                                                (((x) & 0x10000000) >> 28)
-#define PHY_ANALOG_RXTX3_CALPA_SET(x)                                                (((x) << 28) & 0x10000000)
-#define PHY_ANALOG_RXTX3_CALPA_OVR_MSB                                                                       29
-#define PHY_ANALOG_RXTX3_CALPA_OVR_LSB                                                                       29
-#define PHY_ANALOG_RXTX3_CALPA_OVR_MASK                                                              0x20000000
-#define PHY_ANALOG_RXTX3_CALPA_OVR_GET(x)                                            (((x) & 0x20000000) >> 29)
-#define PHY_ANALOG_RXTX3_CALPA_OVR_SET(x)                                            (((x) << 29) & 0x20000000)
-#define PHY_ANALOG_RXTX3_TURBOADC_MSB                                                                        30
-#define PHY_ANALOG_RXTX3_TURBOADC_LSB                                                                        30
-#define PHY_ANALOG_RXTX3_TURBOADC_MASK                                                               0x40000000
-#define PHY_ANALOG_RXTX3_TURBOADC_GET(x)                                             (((x) & 0x40000000) >> 30)
-#define PHY_ANALOG_RXTX3_TURBOADC_SET(x)                                             (((x) << 30) & 0x40000000)
-#define PHY_ANALOG_RXTX3_TURBOADC_OVR_MSB                                                                    31
-#define PHY_ANALOG_RXTX3_TURBOADC_OVR_LSB                                                                    31
-#define PHY_ANALOG_RXTX3_TURBOADC_OVR_MASK                                                           0x80000000
-#define PHY_ANALOG_RXTX3_TURBOADC_OVR_GET(x)                                         (((x) & 0x80000000) >> 31)
-#define PHY_ANALOG_RXTX3_TURBOADC_OVR_SET(x)                                         (((x) << 31) & 0x80000000)
-
-/* macros for BB1 */
-#define PHY_ANALOG_BB1_ADDRESS                                                                       0x00000140
-#define PHY_ANALOG_BB1_OFFSET                                                                        0x00000140
-#define PHY_ANALOG_BB1_I2V_CURR2X_MSB                                                                         0
-#define PHY_ANALOG_BB1_I2V_CURR2X_LSB                                                                         0
-#define PHY_ANALOG_BB1_I2V_CURR2X_MASK                                                               0x00000001
-#define PHY_ANALOG_BB1_I2V_CURR2X_GET(x)                                              (((x) & 0x00000001) >> 0)
-#define PHY_ANALOG_BB1_I2V_CURR2X_SET(x)                                              (((x) << 0) & 0x00000001)
-#define PHY_ANALOG_BB1_ENABLE_LOQ_MSB                                                                         1
-#define PHY_ANALOG_BB1_ENABLE_LOQ_LSB                                                                         1
-#define PHY_ANALOG_BB1_ENABLE_LOQ_MASK                                                               0x00000002
-#define PHY_ANALOG_BB1_ENABLE_LOQ_GET(x)                                              (((x) & 0x00000002) >> 1)
-#define PHY_ANALOG_BB1_ENABLE_LOQ_SET(x)                                              (((x) << 1) & 0x00000002)
-#define PHY_ANALOG_BB1_FORCE_LOQ_MSB                                                                          2
-#define PHY_ANALOG_BB1_FORCE_LOQ_LSB                                                                          2
-#define PHY_ANALOG_BB1_FORCE_LOQ_MASK                                                                0x00000004
-#define PHY_ANALOG_BB1_FORCE_LOQ_GET(x)                                               (((x) & 0x00000004) >> 2)
-#define PHY_ANALOG_BB1_FORCE_LOQ_SET(x)                                               (((x) << 2) & 0x00000004)
-#define PHY_ANALOG_BB1_ENABLE_NOTCH_MSB                                                                       3
-#define PHY_ANALOG_BB1_ENABLE_NOTCH_LSB                                                                       3
-#define PHY_ANALOG_BB1_ENABLE_NOTCH_MASK                                                             0x00000008
-#define PHY_ANALOG_BB1_ENABLE_NOTCH_GET(x)                                            (((x) & 0x00000008) >> 3)
-#define PHY_ANALOG_BB1_ENABLE_NOTCH_SET(x)                                            (((x) << 3) & 0x00000008)
-#define PHY_ANALOG_BB1_FORCE_NOTCH_MSB                                                                        4
-#define PHY_ANALOG_BB1_FORCE_NOTCH_LSB                                                                        4
-#define PHY_ANALOG_BB1_FORCE_NOTCH_MASK                                                              0x00000010
-#define PHY_ANALOG_BB1_FORCE_NOTCH_GET(x)                                             (((x) & 0x00000010) >> 4)
-#define PHY_ANALOG_BB1_FORCE_NOTCH_SET(x)                                             (((x) << 4) & 0x00000010)
-#define PHY_ANALOG_BB1_ENABLE_BIQUAD_MSB                                                                      5
-#define PHY_ANALOG_BB1_ENABLE_BIQUAD_LSB                                                                      5
-#define PHY_ANALOG_BB1_ENABLE_BIQUAD_MASK                                                            0x00000020
-#define PHY_ANALOG_BB1_ENABLE_BIQUAD_GET(x)                                           (((x) & 0x00000020) >> 5)
-#define PHY_ANALOG_BB1_ENABLE_BIQUAD_SET(x)                                           (((x) << 5) & 0x00000020)
-#define PHY_ANALOG_BB1_FORCE_BIQUAD_MSB                                                                       6
-#define PHY_ANALOG_BB1_FORCE_BIQUAD_LSB                                                                       6
-#define PHY_ANALOG_BB1_FORCE_BIQUAD_MASK                                                             0x00000040
-#define PHY_ANALOG_BB1_FORCE_BIQUAD_GET(x)                                            (((x) & 0x00000040) >> 6)
-#define PHY_ANALOG_BB1_FORCE_BIQUAD_SET(x)                                            (((x) << 6) & 0x00000040)
-#define PHY_ANALOG_BB1_ENABLE_OSDAC_MSB                                                                       7
-#define PHY_ANALOG_BB1_ENABLE_OSDAC_LSB                                                                       7
-#define PHY_ANALOG_BB1_ENABLE_OSDAC_MASK                                                             0x00000080
-#define PHY_ANALOG_BB1_ENABLE_OSDAC_GET(x)                                            (((x) & 0x00000080) >> 7)
-#define PHY_ANALOG_BB1_ENABLE_OSDAC_SET(x)                                            (((x) << 7) & 0x00000080)
-#define PHY_ANALOG_BB1_FORCE_OSDAC_MSB                                                                        8
-#define PHY_ANALOG_BB1_FORCE_OSDAC_LSB                                                                        8
-#define PHY_ANALOG_BB1_FORCE_OSDAC_MASK                                                              0x00000100
-#define PHY_ANALOG_BB1_FORCE_OSDAC_GET(x)                                             (((x) & 0x00000100) >> 8)
-#define PHY_ANALOG_BB1_FORCE_OSDAC_SET(x)                                             (((x) << 8) & 0x00000100)
-#define PHY_ANALOG_BB1_ENABLE_V2I_MSB                                                                         9
-#define PHY_ANALOG_BB1_ENABLE_V2I_LSB                                                                         9
-#define PHY_ANALOG_BB1_ENABLE_V2I_MASK                                                               0x00000200
-#define PHY_ANALOG_BB1_ENABLE_V2I_GET(x)                                              (((x) & 0x00000200) >> 9)
-#define PHY_ANALOG_BB1_ENABLE_V2I_SET(x)                                              (((x) << 9) & 0x00000200)
-#define PHY_ANALOG_BB1_FORCE_V2I_MSB                                                                         10
-#define PHY_ANALOG_BB1_FORCE_V2I_LSB                                                                         10
-#define PHY_ANALOG_BB1_FORCE_V2I_MASK                                                                0x00000400
-#define PHY_ANALOG_BB1_FORCE_V2I_GET(x)                                              (((x) & 0x00000400) >> 10)
-#define PHY_ANALOG_BB1_FORCE_V2I_SET(x)                                              (((x) << 10) & 0x00000400)
-#define PHY_ANALOG_BB1_ENABLE_I2V_MSB                                                                        11
-#define PHY_ANALOG_BB1_ENABLE_I2V_LSB                                                                        11
-#define PHY_ANALOG_BB1_ENABLE_I2V_MASK                                                               0x00000800
-#define PHY_ANALOG_BB1_ENABLE_I2V_GET(x)                                             (((x) & 0x00000800) >> 11)
-#define PHY_ANALOG_BB1_ENABLE_I2V_SET(x)                                             (((x) << 11) & 0x00000800)
-#define PHY_ANALOG_BB1_FORCE_I2V_MSB                                                                         12
-#define PHY_ANALOG_BB1_FORCE_I2V_LSB                                                                         12
-#define PHY_ANALOG_BB1_FORCE_I2V_MASK                                                                0x00001000
-#define PHY_ANALOG_BB1_FORCE_I2V_GET(x)                                              (((x) & 0x00001000) >> 12)
-#define PHY_ANALOG_BB1_FORCE_I2V_SET(x)                                              (((x) << 12) & 0x00001000)
-#define PHY_ANALOG_BB1_CMSEL_MSB                                                                             15
-#define PHY_ANALOG_BB1_CMSEL_LSB                                                                             13
-#define PHY_ANALOG_BB1_CMSEL_MASK                                                                    0x0000e000
-#define PHY_ANALOG_BB1_CMSEL_GET(x)                                                  (((x) & 0x0000e000) >> 13)
-#define PHY_ANALOG_BB1_CMSEL_SET(x)                                                  (((x) << 13) & 0x0000e000)
-#define PHY_ANALOG_BB1_ATBSEL_MSB                                                                            17
-#define PHY_ANALOG_BB1_ATBSEL_LSB                                                                            16
-#define PHY_ANALOG_BB1_ATBSEL_MASK                                                                   0x00030000
-#define PHY_ANALOG_BB1_ATBSEL_GET(x)                                                 (((x) & 0x00030000) >> 16)
-#define PHY_ANALOG_BB1_ATBSEL_SET(x)                                                 (((x) << 16) & 0x00030000)
-#define PHY_ANALOG_BB1_PD_OSDAC_CALTX_CALPA_MSB                                                              18
-#define PHY_ANALOG_BB1_PD_OSDAC_CALTX_CALPA_LSB                                                              18
-#define PHY_ANALOG_BB1_PD_OSDAC_CALTX_CALPA_MASK                                                     0x00040000
-#define PHY_ANALOG_BB1_PD_OSDAC_CALTX_CALPA_GET(x)                                   (((x) & 0x00040000) >> 18)
-#define PHY_ANALOG_BB1_PD_OSDAC_CALTX_CALPA_SET(x)                                   (((x) << 18) & 0x00040000)
-#define PHY_ANALOG_BB1_OFSTCORRI2VQ_MSB                                                                      23
-#define PHY_ANALOG_BB1_OFSTCORRI2VQ_LSB                                                                      19
-#define PHY_ANALOG_BB1_OFSTCORRI2VQ_MASK                                                             0x00f80000
-#define PHY_ANALOG_BB1_OFSTCORRI2VQ_GET(x)                                           (((x) & 0x00f80000) >> 19)
-#define PHY_ANALOG_BB1_OFSTCORRI2VQ_SET(x)                                           (((x) << 19) & 0x00f80000)
-#define PHY_ANALOG_BB1_OFSTCORRI2VI_MSB                                                                      28
-#define PHY_ANALOG_BB1_OFSTCORRI2VI_LSB                                                                      24
-#define PHY_ANALOG_BB1_OFSTCORRI2VI_MASK                                                             0x1f000000
-#define PHY_ANALOG_BB1_OFSTCORRI2VI_GET(x)                                           (((x) & 0x1f000000) >> 24)
-#define PHY_ANALOG_BB1_OFSTCORRI2VI_SET(x)                                           (((x) << 24) & 0x1f000000)
-#define PHY_ANALOG_BB1_LOCALOFFSET_MSB                                                                       29
-#define PHY_ANALOG_BB1_LOCALOFFSET_LSB                                                                       29
-#define PHY_ANALOG_BB1_LOCALOFFSET_MASK                                                              0x20000000
-#define PHY_ANALOG_BB1_LOCALOFFSET_GET(x)                                            (((x) & 0x20000000) >> 29)
-#define PHY_ANALOG_BB1_LOCALOFFSET_SET(x)                                            (((x) << 29) & 0x20000000)
-#define PHY_ANALOG_BB1_RANGE_OSDAC_MSB                                                                       31
-#define PHY_ANALOG_BB1_RANGE_OSDAC_LSB                                                                       30
-#define PHY_ANALOG_BB1_RANGE_OSDAC_MASK                                                              0xc0000000
-#define PHY_ANALOG_BB1_RANGE_OSDAC_GET(x)                                            (((x) & 0xc0000000) >> 30)
-#define PHY_ANALOG_BB1_RANGE_OSDAC_SET(x)                                            (((x) << 30) & 0xc0000000)
-
-/* macros for BB2 */
-#define PHY_ANALOG_BB2_ADDRESS                                                                       0x00000144
-#define PHY_ANALOG_BB2_OFFSET                                                                        0x00000144
-#define PHY_ANALOG_BB2_SPARE_MSB                                                                              3
-#define PHY_ANALOG_BB2_SPARE_LSB                                                                              0
-#define PHY_ANALOG_BB2_SPARE_MASK                                                                    0x0000000f
-#define PHY_ANALOG_BB2_SPARE_GET(x)                                                   (((x) & 0x0000000f) >> 0)
-#define PHY_ANALOG_BB2_SPARE_SET(x)                                                   (((x) << 0) & 0x0000000f)
-#define PHY_ANALOG_BB2_MXR_HIGHGAINMASK_MSB                                                                   7
-#define PHY_ANALOG_BB2_MXR_HIGHGAINMASK_LSB                                                                   4
-#define PHY_ANALOG_BB2_MXR_HIGHGAINMASK_MASK                                                         0x000000f0
-#define PHY_ANALOG_BB2_MXR_HIGHGAINMASK_GET(x)                                        (((x) & 0x000000f0) >> 4)
-#define PHY_ANALOG_BB2_MXR_HIGHGAINMASK_SET(x)                                        (((x) << 4) & 0x000000f0)
-#define PHY_ANALOG_BB2_SEL_TEST_MSB                                                                           9
-#define PHY_ANALOG_BB2_SEL_TEST_LSB                                                                           8
-#define PHY_ANALOG_BB2_SEL_TEST_MASK                                                                 0x00000300
-#define PHY_ANALOG_BB2_SEL_TEST_GET(x)                                                (((x) & 0x00000300) >> 8)
-#define PHY_ANALOG_BB2_SEL_TEST_SET(x)                                                (((x) << 8) & 0x00000300)
-#define PHY_ANALOG_BB2_RCFILTER_CAP_MSB                                                                      14
-#define PHY_ANALOG_BB2_RCFILTER_CAP_LSB                                                                      10
-#define PHY_ANALOG_BB2_RCFILTER_CAP_MASK                                                             0x00007c00
-#define PHY_ANALOG_BB2_RCFILTER_CAP_GET(x)                                           (((x) & 0x00007c00) >> 10)
-#define PHY_ANALOG_BB2_RCFILTER_CAP_SET(x)                                           (((x) << 10) & 0x00007c00)
-#define PHY_ANALOG_BB2_OVERRIDE_RCFILTER_CAP_MSB                                                             15
-#define PHY_ANALOG_BB2_OVERRIDE_RCFILTER_CAP_LSB                                                             15
-#define PHY_ANALOG_BB2_OVERRIDE_RCFILTER_CAP_MASK                                                    0x00008000
-#define PHY_ANALOG_BB2_OVERRIDE_RCFILTER_CAP_GET(x)                                  (((x) & 0x00008000) >> 15)
-#define PHY_ANALOG_BB2_OVERRIDE_RCFILTER_CAP_SET(x)                                  (((x) << 15) & 0x00008000)
-#define PHY_ANALOG_BB2_FNOTCH_MSB                                                                            19
-#define PHY_ANALOG_BB2_FNOTCH_LSB                                                                            16
-#define PHY_ANALOG_BB2_FNOTCH_MASK                                                                   0x000f0000
-#define PHY_ANALOG_BB2_FNOTCH_GET(x)                                                 (((x) & 0x000f0000) >> 16)
-#define PHY_ANALOG_BB2_FNOTCH_SET(x)                                                 (((x) << 16) & 0x000f0000)
-#define PHY_ANALOG_BB2_OVERRIDE_FNOTCH_MSB                                                                   20
-#define PHY_ANALOG_BB2_OVERRIDE_FNOTCH_LSB                                                                   20
-#define PHY_ANALOG_BB2_OVERRIDE_FNOTCH_MASK                                                          0x00100000
-#define PHY_ANALOG_BB2_OVERRIDE_FNOTCH_GET(x)                                        (((x) & 0x00100000) >> 20)
-#define PHY_ANALOG_BB2_OVERRIDE_FNOTCH_SET(x)                                        (((x) << 20) & 0x00100000)
-#define PHY_ANALOG_BB2_FILTERFC_MSB                                                                          25
-#define PHY_ANALOG_BB2_FILTERFC_LSB                                                                          21
-#define PHY_ANALOG_BB2_FILTERFC_MASK                                                                 0x03e00000
-#define PHY_ANALOG_BB2_FILTERFC_GET(x)                                               (((x) & 0x03e00000) >> 21)
-#define PHY_ANALOG_BB2_FILTERFC_SET(x)                                               (((x) << 21) & 0x03e00000)
-#define PHY_ANALOG_BB2_OVERRIDE_FILTERFC_MSB                                                                 26
-#define PHY_ANALOG_BB2_OVERRIDE_FILTERFC_LSB                                                                 26
-#define PHY_ANALOG_BB2_OVERRIDE_FILTERFC_MASK                                                        0x04000000
-#define PHY_ANALOG_BB2_OVERRIDE_FILTERFC_GET(x)                                      (((x) & 0x04000000) >> 26)
-#define PHY_ANALOG_BB2_OVERRIDE_FILTERFC_SET(x)                                      (((x) << 26) & 0x04000000)
-#define PHY_ANALOG_BB2_I2V2RXOUT_EN_MSB                                                                      27
-#define PHY_ANALOG_BB2_I2V2RXOUT_EN_LSB                                                                      27
-#define PHY_ANALOG_BB2_I2V2RXOUT_EN_MASK                                                             0x08000000
-#define PHY_ANALOG_BB2_I2V2RXOUT_EN_GET(x)                                           (((x) & 0x08000000) >> 27)
-#define PHY_ANALOG_BB2_I2V2RXOUT_EN_SET(x)                                           (((x) << 27) & 0x08000000)
-#define PHY_ANALOG_BB2_BQ2RXOUT_EN_MSB                                                                       28
-#define PHY_ANALOG_BB2_BQ2RXOUT_EN_LSB                                                                       28
-#define PHY_ANALOG_BB2_BQ2RXOUT_EN_MASK                                                              0x10000000
-#define PHY_ANALOG_BB2_BQ2RXOUT_EN_GET(x)                                            (((x) & 0x10000000) >> 28)
-#define PHY_ANALOG_BB2_BQ2RXOUT_EN_SET(x)                                            (((x) << 28) & 0x10000000)
-#define PHY_ANALOG_BB2_RXIN2I2V_EN_MSB                                                                       29
-#define PHY_ANALOG_BB2_RXIN2I2V_EN_LSB                                                                       29
-#define PHY_ANALOG_BB2_RXIN2I2V_EN_MASK                                                              0x20000000
-#define PHY_ANALOG_BB2_RXIN2I2V_EN_GET(x)                                            (((x) & 0x20000000) >> 29)
-#define PHY_ANALOG_BB2_RXIN2I2V_EN_SET(x)                                            (((x) << 29) & 0x20000000)
-#define PHY_ANALOG_BB2_RXIN2BQ_EN_MSB                                                                        30
-#define PHY_ANALOG_BB2_RXIN2BQ_EN_LSB                                                                        30
-#define PHY_ANALOG_BB2_RXIN2BQ_EN_MASK                                                               0x40000000
-#define PHY_ANALOG_BB2_RXIN2BQ_EN_GET(x)                                             (((x) & 0x40000000) >> 30)
-#define PHY_ANALOG_BB2_RXIN2BQ_EN_SET(x)                                             (((x) << 30) & 0x40000000)
-#define PHY_ANALOG_BB2_SWITCH_OVERRIDE_MSB                                                                   31
-#define PHY_ANALOG_BB2_SWITCH_OVERRIDE_LSB                                                                   31
-#define PHY_ANALOG_BB2_SWITCH_OVERRIDE_MASK                                                          0x80000000
-#define PHY_ANALOG_BB2_SWITCH_OVERRIDE_GET(x)                                        (((x) & 0x80000000) >> 31)
-#define PHY_ANALOG_BB2_SWITCH_OVERRIDE_SET(x)                                        (((x) << 31) & 0x80000000)
-
-/* macros for BB3 */
-#define PHY_ANALOG_BB3_ADDRESS                                                                       0x00000148
-#define PHY_ANALOG_BB3_OFFSET                                                                        0x00000148
-#define PHY_ANALOG_BB3_SPARE_MSB                                                                             15
-#define PHY_ANALOG_BB3_SPARE_LSB                                                                              0
-#define PHY_ANALOG_BB3_SPARE_MASK                                                                    0x0000ffff
-#define PHY_ANALOG_BB3_SPARE_GET(x)                                                   (((x) & 0x0000ffff) >> 0)
-#define PHY_ANALOG_BB3_SPARE_SET(x)                                                   (((x) << 0) & 0x0000ffff)
-#define PHY_ANALOG_BB3_FILTERFC_MSB                                                                          20
-#define PHY_ANALOG_BB3_FILTERFC_LSB                                                                          16
-#define PHY_ANALOG_BB3_FILTERFC_MASK                                                                 0x001f0000
-#define PHY_ANALOG_BB3_FILTERFC_GET(x)                                               (((x) & 0x001f0000) >> 16)
-#define PHY_ANALOG_BB3_OFSTCORRI2VQ_MSB                                                                      25
-#define PHY_ANALOG_BB3_OFSTCORRI2VQ_LSB                                                                      21
-#define PHY_ANALOG_BB3_OFSTCORRI2VQ_MASK                                                             0x03e00000
-#define PHY_ANALOG_BB3_OFSTCORRI2VQ_GET(x)                                           (((x) & 0x03e00000) >> 21)
-#define PHY_ANALOG_BB3_OFSTCORRI2VI_MSB                                                                      30
-#define PHY_ANALOG_BB3_OFSTCORRI2VI_LSB                                                                      26
-#define PHY_ANALOG_BB3_OFSTCORRI2VI_MASK                                                             0x7c000000
-#define PHY_ANALOG_BB3_OFSTCORRI2VI_GET(x)                                           (((x) & 0x7c000000) >> 26)
-#define PHY_ANALOG_BB3_EN_TXBBCONSTCUR_MSB                                                                   31
-#define PHY_ANALOG_BB3_EN_TXBBCONSTCUR_LSB                                                                   31
-#define PHY_ANALOG_BB3_EN_TXBBCONSTCUR_MASK                                                          0x80000000
-#define PHY_ANALOG_BB3_EN_TXBBCONSTCUR_GET(x)                                        (((x) & 0x80000000) >> 31)
-#define PHY_ANALOG_BB3_EN_TXBBCONSTCUR_SET(x)                                        (((x) << 31) & 0x80000000)
-
-/* macros for PLLCLKMODA */
-#define PHY_ANALOG_PLLCLKMODA_ADDRESS                                                                0x00000280
-#define PHY_ANALOG_PLLCLKMODA_OFFSET                                                                 0x00000280
-#define PHY_ANALOG_PLLCLKMODA_PWD_PLLSDM_MSB                                                                  0
-#define PHY_ANALOG_PLLCLKMODA_PWD_PLLSDM_LSB                                                                  0
-#define PHY_ANALOG_PLLCLKMODA_PWD_PLLSDM_MASK                                                        0x00000001
-#define PHY_ANALOG_PLLCLKMODA_PWD_PLLSDM_GET(x)                                       (((x) & 0x00000001) >> 0)
-#define PHY_ANALOG_PLLCLKMODA_PWD_PLLSDM_SET(x)                                       (((x) << 0) & 0x00000001)
-#define PHY_ANALOG_PLLCLKMODA_PWDPLL_MSB                                                                      1
-#define PHY_ANALOG_PLLCLKMODA_PWDPLL_LSB                                                                      1
-#define PHY_ANALOG_PLLCLKMODA_PWDPLL_MASK                                                            0x00000002
-#define PHY_ANALOG_PLLCLKMODA_PWDPLL_GET(x)                                           (((x) & 0x00000002) >> 1)
-#define PHY_ANALOG_PLLCLKMODA_PWDPLL_SET(x)                                           (((x) << 1) & 0x00000002)
-#define PHY_ANALOG_PLLCLKMODA_PLLFRAC_MSB                                                                    16
-#define PHY_ANALOG_PLLCLKMODA_PLLFRAC_LSB                                                                     2
-#define PHY_ANALOG_PLLCLKMODA_PLLFRAC_MASK                                                           0x0001fffc
-#define PHY_ANALOG_PLLCLKMODA_PLLFRAC_GET(x)                                          (((x) & 0x0001fffc) >> 2)
-#define PHY_ANALOG_PLLCLKMODA_PLLFRAC_SET(x)                                          (((x) << 2) & 0x0001fffc)
-#define PHY_ANALOG_PLLCLKMODA_REFDIV_MSB                                                                     20
-#define PHY_ANALOG_PLLCLKMODA_REFDIV_LSB                                                                     17
-#define PHY_ANALOG_PLLCLKMODA_REFDIV_MASK                                                            0x001e0000
-#define PHY_ANALOG_PLLCLKMODA_REFDIV_GET(x)                                          (((x) & 0x001e0000) >> 17)
-#define PHY_ANALOG_PLLCLKMODA_REFDIV_SET(x)                                          (((x) << 17) & 0x001e0000)
-#define PHY_ANALOG_PLLCLKMODA_DIV_MSB                                                                        30
-#define PHY_ANALOG_PLLCLKMODA_DIV_LSB                                                                        21
-#define PHY_ANALOG_PLLCLKMODA_DIV_MASK                                                               0x7fe00000
-#define PHY_ANALOG_PLLCLKMODA_DIV_GET(x)                                             (((x) & 0x7fe00000) >> 21)
-#define PHY_ANALOG_PLLCLKMODA_DIV_SET(x)                                             (((x) << 21) & 0x7fe00000)
-#define PHY_ANALOG_PLLCLKMODA_LOCAL_PLL_MSB                                                                  31
-#define PHY_ANALOG_PLLCLKMODA_LOCAL_PLL_LSB                                                                  31
-#define PHY_ANALOG_PLLCLKMODA_LOCAL_PLL_MASK                                                         0x80000000
-#define PHY_ANALOG_PLLCLKMODA_LOCAL_PLL_GET(x)                                       (((x) & 0x80000000) >> 31)
-#define PHY_ANALOG_PLLCLKMODA_LOCAL_PLL_SET(x)                                       (((x) << 31) & 0x80000000)
-
-/* macros for PLLCLKMODA2 */
-#define PHY_ANALOG_PLLCLKMODA2_ADDRESS                                                               0x00000284
-#define PHY_ANALOG_PLLCLKMODA2_OFFSET                                                                0x00000284
-#define PHY_ANALOG_PLLCLKMODA2_SPARE_MSB                                                                      3
-#define PHY_ANALOG_PLLCLKMODA2_SPARE_LSB                                                                      0
-#define PHY_ANALOG_PLLCLKMODA2_SPARE_MASK                                                            0x0000000f
-#define PHY_ANALOG_PLLCLKMODA2_SPARE_GET(x)                                           (((x) & 0x0000000f) >> 0)
-#define PHY_ANALOG_PLLCLKMODA2_SPARE_SET(x)                                           (((x) << 0) & 0x0000000f)
-#define PHY_ANALOG_PLLCLKMODA2_DACPWD_MSB                                                                     4
-#define PHY_ANALOG_PLLCLKMODA2_DACPWD_LSB                                                                     4
-#define PHY_ANALOG_PLLCLKMODA2_DACPWD_MASK                                                           0x00000010
-#define PHY_ANALOG_PLLCLKMODA2_DACPWD_GET(x)                                          (((x) & 0x00000010) >> 4)
-#define PHY_ANALOG_PLLCLKMODA2_DACPWD_SET(x)                                          (((x) << 4) & 0x00000010)
-#define PHY_ANALOG_PLLCLKMODA2_ADCPWD_MSB                                                                     5
-#define PHY_ANALOG_PLLCLKMODA2_ADCPWD_LSB                                                                     5
-#define PHY_ANALOG_PLLCLKMODA2_ADCPWD_MASK                                                           0x00000020
-#define PHY_ANALOG_PLLCLKMODA2_ADCPWD_GET(x)                                          (((x) & 0x00000020) >> 5)
-#define PHY_ANALOG_PLLCLKMODA2_ADCPWD_SET(x)                                          (((x) << 5) & 0x00000020)
-#define PHY_ANALOG_PLLCLKMODA2_LOCAL_ADDAC_MSB                                                                6
-#define PHY_ANALOG_PLLCLKMODA2_LOCAL_ADDAC_LSB                                                                6
-#define PHY_ANALOG_PLLCLKMODA2_LOCAL_ADDAC_MASK                                                      0x00000040
-#define PHY_ANALOG_PLLCLKMODA2_LOCAL_ADDAC_GET(x)                                     (((x) & 0x00000040) >> 6)
-#define PHY_ANALOG_PLLCLKMODA2_LOCAL_ADDAC_SET(x)                                     (((x) << 6) & 0x00000040)
-#define PHY_ANALOG_PLLCLKMODA2_DAC_CLK_SEL_MSB                                                                8
-#define PHY_ANALOG_PLLCLKMODA2_DAC_CLK_SEL_LSB                                                                7
-#define PHY_ANALOG_PLLCLKMODA2_DAC_CLK_SEL_MASK                                                      0x00000180
-#define PHY_ANALOG_PLLCLKMODA2_DAC_CLK_SEL_GET(x)                                     (((x) & 0x00000180) >> 7)
-#define PHY_ANALOG_PLLCLKMODA2_DAC_CLK_SEL_SET(x)                                     (((x) << 7) & 0x00000180)
-#define PHY_ANALOG_PLLCLKMODA2_ADC_CLK_SEL_MSB                                                               12
-#define PHY_ANALOG_PLLCLKMODA2_ADC_CLK_SEL_LSB                                                                9
-#define PHY_ANALOG_PLLCLKMODA2_ADC_CLK_SEL_MASK                                                      0x00001e00
-#define PHY_ANALOG_PLLCLKMODA2_ADC_CLK_SEL_GET(x)                                     (((x) & 0x00001e00) >> 9)
-#define PHY_ANALOG_PLLCLKMODA2_ADC_CLK_SEL_SET(x)                                     (((x) << 9) & 0x00001e00)
-#define PHY_ANALOG_PLLCLKMODA2_LOCAL_CLKMODA_MSB                                                             13
-#define PHY_ANALOG_PLLCLKMODA2_LOCAL_CLKMODA_LSB                                                             13
-#define PHY_ANALOG_PLLCLKMODA2_LOCAL_CLKMODA_MASK                                                    0x00002000
-#define PHY_ANALOG_PLLCLKMODA2_LOCAL_CLKMODA_GET(x)                                  (((x) & 0x00002000) >> 13)
-#define PHY_ANALOG_PLLCLKMODA2_LOCAL_CLKMODA_SET(x)                                  (((x) << 13) & 0x00002000)
-#define PHY_ANALOG_PLLCLKMODA2_PLLBYPASS_MSB                                                                 14
-#define PHY_ANALOG_PLLCLKMODA2_PLLBYPASS_LSB                                                                 14
-#define PHY_ANALOG_PLLCLKMODA2_PLLBYPASS_MASK                                                        0x00004000
-#define PHY_ANALOG_PLLCLKMODA2_PLLBYPASS_GET(x)                                      (((x) & 0x00004000) >> 14)
-#define PHY_ANALOG_PLLCLKMODA2_PLLBYPASS_SET(x)                                      (((x) << 14) & 0x00004000)
-#define PHY_ANALOG_PLLCLKMODA2_LOCAL_PLLBYPASS_MSB                                                           15
-#define PHY_ANALOG_PLLCLKMODA2_LOCAL_PLLBYPASS_LSB                                                           15
-#define PHY_ANALOG_PLLCLKMODA2_LOCAL_PLLBYPASS_MASK                                                  0x00008000
-#define PHY_ANALOG_PLLCLKMODA2_LOCAL_PLLBYPASS_GET(x)                                (((x) & 0x00008000) >> 15)
-#define PHY_ANALOG_PLLCLKMODA2_LOCAL_PLLBYPASS_SET(x)                                (((x) << 15) & 0x00008000)
-#define PHY_ANALOG_PLLCLKMODA2_PLLATB_MSB                                                                    17
-#define PHY_ANALOG_PLLCLKMODA2_PLLATB_LSB                                                                    16
-#define PHY_ANALOG_PLLCLKMODA2_PLLATB_MASK                                                           0x00030000
-#define PHY_ANALOG_PLLCLKMODA2_PLLATB_GET(x)                                         (((x) & 0x00030000) >> 16)
-#define PHY_ANALOG_PLLCLKMODA2_PLLATB_SET(x)                                         (((x) << 16) & 0x00030000)
-#define PHY_ANALOG_PLLCLKMODA2_PLL_SVREG_MSB                                                                 18
-#define PHY_ANALOG_PLLCLKMODA2_PLL_SVREG_LSB                                                                 18
-#define PHY_ANALOG_PLLCLKMODA2_PLL_SVREG_MASK                                                        0x00040000
-#define PHY_ANALOG_PLLCLKMODA2_PLL_SVREG_GET(x)                                      (((x) & 0x00040000) >> 18)
-#define PHY_ANALOG_PLLCLKMODA2_PLL_SVREG_SET(x)                                      (((x) << 18) & 0x00040000)
-#define PHY_ANALOG_PLLCLKMODA2_HI_FREQ_EN_MSB                                                                19
-#define PHY_ANALOG_PLLCLKMODA2_HI_FREQ_EN_LSB                                                                19
-#define PHY_ANALOG_PLLCLKMODA2_HI_FREQ_EN_MASK                                                       0x00080000
-#define PHY_ANALOG_PLLCLKMODA2_HI_FREQ_EN_GET(x)                                     (((x) & 0x00080000) >> 19)
-#define PHY_ANALOG_PLLCLKMODA2_HI_FREQ_EN_SET(x)                                     (((x) << 19) & 0x00080000)
-#define PHY_ANALOG_PLLCLKMODA2_RST_WARM_INT_L_MSB                                                            20
-#define PHY_ANALOG_PLLCLKMODA2_RST_WARM_INT_L_LSB                                                            20
-#define PHY_ANALOG_PLLCLKMODA2_RST_WARM_INT_L_MASK                                                   0x00100000
-#define PHY_ANALOG_PLLCLKMODA2_RST_WARM_INT_L_GET(x)                                 (((x) & 0x00100000) >> 20)
-#define PHY_ANALOG_PLLCLKMODA2_RST_WARM_INT_L_SET(x)                                 (((x) << 20) & 0x00100000)
-#define PHY_ANALOG_PLLCLKMODA2_RST_WARM_OVR_MSB                                                              21
-#define PHY_ANALOG_PLLCLKMODA2_RST_WARM_OVR_LSB                                                              21
-#define PHY_ANALOG_PLLCLKMODA2_RST_WARM_OVR_MASK                                                     0x00200000
-#define PHY_ANALOG_PLLCLKMODA2_RST_WARM_OVR_GET(x)                                   (((x) & 0x00200000) >> 21)
-#define PHY_ANALOG_PLLCLKMODA2_RST_WARM_OVR_SET(x)                                   (((x) << 21) & 0x00200000)
-#define PHY_ANALOG_PLLCLKMODA2_PLL_KVCO_MSB                                                                  23
-#define PHY_ANALOG_PLLCLKMODA2_PLL_KVCO_LSB                                                                  22
-#define PHY_ANALOG_PLLCLKMODA2_PLL_KVCO_MASK                                                         0x00c00000
-#define PHY_ANALOG_PLLCLKMODA2_PLL_KVCO_GET(x)                                       (((x) & 0x00c00000) >> 22)
-#define PHY_ANALOG_PLLCLKMODA2_PLL_KVCO_SET(x)                                       (((x) << 22) & 0x00c00000)
-#define PHY_ANALOG_PLLCLKMODA2_PLLICP_MSB                                                                    26
-#define PHY_ANALOG_PLLCLKMODA2_PLLICP_LSB                                                                    24
-#define PHY_ANALOG_PLLCLKMODA2_PLLICP_MASK                                                           0x07000000
-#define PHY_ANALOG_PLLCLKMODA2_PLLICP_GET(x)                                         (((x) & 0x07000000) >> 24)
-#define PHY_ANALOG_PLLCLKMODA2_PLLICP_SET(x)                                         (((x) << 24) & 0x07000000)
-#define PHY_ANALOG_PLLCLKMODA2_PLLFILTER_MSB                                                                 31
-#define PHY_ANALOG_PLLCLKMODA2_PLLFILTER_LSB                                                                 27
-#define PHY_ANALOG_PLLCLKMODA2_PLLFILTER_MASK                                                        0xf8000000
-#define PHY_ANALOG_PLLCLKMODA2_PLLFILTER_GET(x)                                      (((x) & 0xf8000000) >> 27)
-#define PHY_ANALOG_PLLCLKMODA2_PLLFILTER_SET(x)                                      (((x) << 27) & 0xf8000000)
-
-/* macros for TOP */
-#define PHY_ANALOG_TOP_ADDRESS                                                                       0x00000288
-#define PHY_ANALOG_TOP_OFFSET                                                                        0x00000288
-#define PHY_ANALOG_TOP_SPARE_MSB                                                                              2
-#define PHY_ANALOG_TOP_SPARE_LSB                                                                              0
-#define PHY_ANALOG_TOP_SPARE_MASK                                                                    0x00000007
-#define PHY_ANALOG_TOP_SPARE_GET(x)                                                   (((x) & 0x00000007) >> 0)
-#define PHY_ANALOG_TOP_SPARE_SET(x)                                                   (((x) << 0) & 0x00000007)
-#define PHY_ANALOG_TOP_PWDBIAS_MSB                                                                            3
-#define PHY_ANALOG_TOP_PWDBIAS_LSB                                                                            3
-#define PHY_ANALOG_TOP_PWDBIAS_MASK                                                                  0x00000008
-#define PHY_ANALOG_TOP_PWDBIAS_GET(x)                                                 (((x) & 0x00000008) >> 3)
-#define PHY_ANALOG_TOP_PWDBIAS_SET(x)                                                 (((x) << 3) & 0x00000008)
-#define PHY_ANALOG_TOP_FLIP_XPABIAS_MSB                                                                       4
-#define PHY_ANALOG_TOP_FLIP_XPABIAS_LSB                                                                       4
-#define PHY_ANALOG_TOP_FLIP_XPABIAS_MASK                                                             0x00000010
-#define PHY_ANALOG_TOP_FLIP_XPABIAS_GET(x)                                            (((x) & 0x00000010) >> 4)
-#define PHY_ANALOG_TOP_FLIP_XPABIAS_SET(x)                                            (((x) << 4) & 0x00000010)
-#define PHY_ANALOG_TOP_XPAON2_MSB                                                                             5
-#define PHY_ANALOG_TOP_XPAON2_LSB                                                                             5
-#define PHY_ANALOG_TOP_XPAON2_MASK                                                                   0x00000020
-#define PHY_ANALOG_TOP_XPAON2_GET(x)                                                  (((x) & 0x00000020) >> 5)
-#define PHY_ANALOG_TOP_XPAON2_SET(x)                                                  (((x) << 5) & 0x00000020)
-#define PHY_ANALOG_TOP_XPAON5_MSB                                                                             6
-#define PHY_ANALOG_TOP_XPAON5_LSB                                                                             6
-#define PHY_ANALOG_TOP_XPAON5_MASK                                                                   0x00000040
-#define PHY_ANALOG_TOP_XPAON5_GET(x)                                                  (((x) & 0x00000040) >> 6)
-#define PHY_ANALOG_TOP_XPAON5_SET(x)                                                  (((x) << 6) & 0x00000040)
-#define PHY_ANALOG_TOP_XPASHORT2GND_MSB                                                                       7
-#define PHY_ANALOG_TOP_XPASHORT2GND_LSB                                                                       7
-#define PHY_ANALOG_TOP_XPASHORT2GND_MASK                                                             0x00000080
-#define PHY_ANALOG_TOP_XPASHORT2GND_GET(x)                                            (((x) & 0x00000080) >> 7)
-#define PHY_ANALOG_TOP_XPASHORT2GND_SET(x)                                            (((x) << 7) & 0x00000080)
-#define PHY_ANALOG_TOP_XPABIASLVL_MSB                                                                        11
-#define PHY_ANALOG_TOP_XPABIASLVL_LSB                                                                         8
-#define PHY_ANALOG_TOP_XPABIASLVL_MASK                                                               0x00000f00
-#define PHY_ANALOG_TOP_XPABIASLVL_GET(x)                                              (((x) & 0x00000f00) >> 8)
-#define PHY_ANALOG_TOP_XPABIASLVL_SET(x)                                              (((x) << 8) & 0x00000f00)
-#define PHY_ANALOG_TOP_XPABIAS_EN_MSB                                                                        12
-#define PHY_ANALOG_TOP_XPABIAS_EN_LSB                                                                        12
-#define PHY_ANALOG_TOP_XPABIAS_EN_MASK                                                               0x00001000
-#define PHY_ANALOG_TOP_XPABIAS_EN_GET(x)                                             (((x) & 0x00001000) >> 12)
-#define PHY_ANALOG_TOP_XPABIAS_EN_SET(x)                                             (((x) << 12) & 0x00001000)
-#define PHY_ANALOG_TOP_ATBSELECT_MSB                                                                         13
-#define PHY_ANALOG_TOP_ATBSELECT_LSB                                                                         13
-#define PHY_ANALOG_TOP_ATBSELECT_MASK                                                                0x00002000
-#define PHY_ANALOG_TOP_ATBSELECT_GET(x)                                              (((x) & 0x00002000) >> 13)
-#define PHY_ANALOG_TOP_ATBSELECT_SET(x)                                              (((x) << 13) & 0x00002000)
-#define PHY_ANALOG_TOP_LOCAL_XPA_MSB                                                                         14
-#define PHY_ANALOG_TOP_LOCAL_XPA_LSB                                                                         14
-#define PHY_ANALOG_TOP_LOCAL_XPA_MASK                                                                0x00004000
-#define PHY_ANALOG_TOP_LOCAL_XPA_GET(x)                                              (((x) & 0x00004000) >> 14)
-#define PHY_ANALOG_TOP_LOCAL_XPA_SET(x)                                              (((x) << 14) & 0x00004000)
-#define PHY_ANALOG_TOP_XPABIAS_BYPASS_MSB                                                                    15
-#define PHY_ANALOG_TOP_XPABIAS_BYPASS_LSB                                                                    15
-#define PHY_ANALOG_TOP_XPABIAS_BYPASS_MASK                                                           0x00008000
-#define PHY_ANALOG_TOP_XPABIAS_BYPASS_GET(x)                                         (((x) & 0x00008000) >> 15)
-#define PHY_ANALOG_TOP_XPABIAS_BYPASS_SET(x)                                         (((x) << 15) & 0x00008000)
-#define PHY_ANALOG_TOP_TEST_PADQ_EN_MSB                                                                      16
-#define PHY_ANALOG_TOP_TEST_PADQ_EN_LSB                                                                      16
-#define PHY_ANALOG_TOP_TEST_PADQ_EN_MASK                                                             0x00010000
-#define PHY_ANALOG_TOP_TEST_PADQ_EN_GET(x)                                           (((x) & 0x00010000) >> 16)
-#define PHY_ANALOG_TOP_TEST_PADQ_EN_SET(x)                                           (((x) << 16) & 0x00010000)
-#define PHY_ANALOG_TOP_TEST_PADI_EN_MSB                                                                      17
-#define PHY_ANALOG_TOP_TEST_PADI_EN_LSB                                                                      17
-#define PHY_ANALOG_TOP_TEST_PADI_EN_MASK                                                             0x00020000
-#define PHY_ANALOG_TOP_TEST_PADI_EN_GET(x)                                           (((x) & 0x00020000) >> 17)
-#define PHY_ANALOG_TOP_TEST_PADI_EN_SET(x)                                           (((x) << 17) & 0x00020000)
-#define PHY_ANALOG_TOP_TESTIQ_RSEL_MSB                                                                       18
-#define PHY_ANALOG_TOP_TESTIQ_RSEL_LSB                                                                       18
-#define PHY_ANALOG_TOP_TESTIQ_RSEL_MASK                                                              0x00040000
-#define PHY_ANALOG_TOP_TESTIQ_RSEL_GET(x)                                            (((x) & 0x00040000) >> 18)
-#define PHY_ANALOG_TOP_TESTIQ_RSEL_SET(x)                                            (((x) << 18) & 0x00040000)
-#define PHY_ANALOG_TOP_TESTIQ_BUFEN_MSB                                                                      19
-#define PHY_ANALOG_TOP_TESTIQ_BUFEN_LSB                                                                      19
-#define PHY_ANALOG_TOP_TESTIQ_BUFEN_MASK                                                             0x00080000
-#define PHY_ANALOG_TOP_TESTIQ_BUFEN_GET(x)                                           (((x) & 0x00080000) >> 19)
-#define PHY_ANALOG_TOP_TESTIQ_BUFEN_SET(x)                                           (((x) << 19) & 0x00080000)
-#define PHY_ANALOG_TOP_PAD2GND_MSB                                                                           20
-#define PHY_ANALOG_TOP_PAD2GND_LSB                                                                           20
-#define PHY_ANALOG_TOP_PAD2GND_MASK                                                                  0x00100000
-#define PHY_ANALOG_TOP_PAD2GND_GET(x)                                                (((x) & 0x00100000) >> 20)
-#define PHY_ANALOG_TOP_PAD2GND_SET(x)                                                (((x) << 20) & 0x00100000)
-#define PHY_ANALOG_TOP_INTH2PAD_MSB                                                                          21
-#define PHY_ANALOG_TOP_INTH2PAD_LSB                                                                          21
-#define PHY_ANALOG_TOP_INTH2PAD_MASK                                                                 0x00200000
-#define PHY_ANALOG_TOP_INTH2PAD_GET(x)                                               (((x) & 0x00200000) >> 21)
-#define PHY_ANALOG_TOP_INTH2PAD_SET(x)                                               (((x) << 21) & 0x00200000)
-#define PHY_ANALOG_TOP_INTH2GND_MSB                                                                          22
-#define PHY_ANALOG_TOP_INTH2GND_LSB                                                                          22
-#define PHY_ANALOG_TOP_INTH2GND_MASK                                                                 0x00400000
-#define PHY_ANALOG_TOP_INTH2GND_GET(x)                                               (((x) & 0x00400000) >> 22)
-#define PHY_ANALOG_TOP_INTH2GND_SET(x)                                               (((x) << 22) & 0x00400000)
-#define PHY_ANALOG_TOP_INT2PAD_MSB                                                                           23
-#define PHY_ANALOG_TOP_INT2PAD_LSB                                                                           23
-#define PHY_ANALOG_TOP_INT2PAD_MASK                                                                  0x00800000
-#define PHY_ANALOG_TOP_INT2PAD_GET(x)                                                (((x) & 0x00800000) >> 23)
-#define PHY_ANALOG_TOP_INT2PAD_SET(x)                                                (((x) << 23) & 0x00800000)
-#define PHY_ANALOG_TOP_INT2GND_MSB                                                                           24
-#define PHY_ANALOG_TOP_INT2GND_LSB                                                                           24
-#define PHY_ANALOG_TOP_INT2GND_MASK                                                                  0x01000000
-#define PHY_ANALOG_TOP_INT2GND_GET(x)                                                (((x) & 0x01000000) >> 24)
-#define PHY_ANALOG_TOP_INT2GND_SET(x)                                                (((x) << 24) & 0x01000000)
-#define PHY_ANALOG_TOP_PWDPALCLK_MSB                                                                         25
-#define PHY_ANALOG_TOP_PWDPALCLK_LSB                                                                         25
-#define PHY_ANALOG_TOP_PWDPALCLK_MASK                                                                0x02000000
-#define PHY_ANALOG_TOP_PWDPALCLK_GET(x)                                              (((x) & 0x02000000) >> 25)
-#define PHY_ANALOG_TOP_PWDPALCLK_SET(x)                                              (((x) << 25) & 0x02000000)
-#define PHY_ANALOG_TOP_INV_CLK320_ADC_MSB                                                                    26
-#define PHY_ANALOG_TOP_INV_CLK320_ADC_LSB                                                                    26
-#define PHY_ANALOG_TOP_INV_CLK320_ADC_MASK                                                           0x04000000
-#define PHY_ANALOG_TOP_INV_CLK320_ADC_GET(x)                                         (((x) & 0x04000000) >> 26)
-#define PHY_ANALOG_TOP_INV_CLK320_ADC_SET(x)                                         (((x) << 26) & 0x04000000)
-#define PHY_ANALOG_TOP_FLIP_REFCLK40_MSB                                                                     27
-#define PHY_ANALOG_TOP_FLIP_REFCLK40_LSB                                                                     27
-#define PHY_ANALOG_TOP_FLIP_REFCLK40_MASK                                                            0x08000000
-#define PHY_ANALOG_TOP_FLIP_REFCLK40_GET(x)                                          (((x) & 0x08000000) >> 27)
-#define PHY_ANALOG_TOP_FLIP_REFCLK40_SET(x)                                          (((x) << 27) & 0x08000000)
-#define PHY_ANALOG_TOP_FLIP_PLLCLK320_MSB                                                                    28
-#define PHY_ANALOG_TOP_FLIP_PLLCLK320_LSB                                                                    28
-#define PHY_ANALOG_TOP_FLIP_PLLCLK320_MASK                                                           0x10000000
-#define PHY_ANALOG_TOP_FLIP_PLLCLK320_GET(x)                                         (((x) & 0x10000000) >> 28)
-#define PHY_ANALOG_TOP_FLIP_PLLCLK320_SET(x)                                         (((x) << 28) & 0x10000000)
-#define PHY_ANALOG_TOP_FLIP_PLLCLK160_MSB                                                                    29
-#define PHY_ANALOG_TOP_FLIP_PLLCLK160_LSB                                                                    29
-#define PHY_ANALOG_TOP_FLIP_PLLCLK160_MASK                                                           0x20000000
-#define PHY_ANALOG_TOP_FLIP_PLLCLK160_GET(x)                                         (((x) & 0x20000000) >> 29)
-#define PHY_ANALOG_TOP_FLIP_PLLCLK160_SET(x)                                         (((x) << 29) & 0x20000000)
-#define PHY_ANALOG_TOP_CLK_SEL_MSB                                                                           31
-#define PHY_ANALOG_TOP_CLK_SEL_LSB                                                                           30
-#define PHY_ANALOG_TOP_CLK_SEL_MASK                                                                  0xc0000000
-#define PHY_ANALOG_TOP_CLK_SEL_GET(x)                                                (((x) & 0xc0000000) >> 30)
-#define PHY_ANALOG_TOP_CLK_SEL_SET(x)                                                (((x) << 30) & 0xc0000000)
-
-/* macros for THERM */
-#define PHY_ANALOG_THERM_ADDRESS                                                                     0x0000028c
-#define PHY_ANALOG_THERM_OFFSET                                                                      0x0000028c
-#define PHY_ANALOG_THERM_LOREG_LVL_MSB                                                                        2
-#define PHY_ANALOG_THERM_LOREG_LVL_LSB                                                                        0
-#define PHY_ANALOG_THERM_LOREG_LVL_MASK                                                              0x00000007
-#define PHY_ANALOG_THERM_LOREG_LVL_GET(x)                                             (((x) & 0x00000007) >> 0)
-#define PHY_ANALOG_THERM_LOREG_LVL_SET(x)                                             (((x) << 0) & 0x00000007)
-#define PHY_ANALOG_THERM_RFREG_LVL_MSB                                                                        5
-#define PHY_ANALOG_THERM_RFREG_LVL_LSB                                                                        3
-#define PHY_ANALOG_THERM_RFREG_LVL_MASK                                                              0x00000038
-#define PHY_ANALOG_THERM_RFREG_LVL_GET(x)                                             (((x) & 0x00000038) >> 3)
-#define PHY_ANALOG_THERM_RFREG_LVL_SET(x)                                             (((x) << 3) & 0x00000038)
-#define PHY_ANALOG_THERM_SAR_ADC_DONE_MSB                                                                     6
-#define PHY_ANALOG_THERM_SAR_ADC_DONE_LSB                                                                     6
-#define PHY_ANALOG_THERM_SAR_ADC_DONE_MASK                                                           0x00000040
-#define PHY_ANALOG_THERM_SAR_ADC_DONE_GET(x)                                          (((x) & 0x00000040) >> 6)
-#define PHY_ANALOG_THERM_SAR_ADC_OUT_MSB                                                                     14
-#define PHY_ANALOG_THERM_SAR_ADC_OUT_LSB                                                                      7
-#define PHY_ANALOG_THERM_SAR_ADC_OUT_MASK                                                            0x00007f80
-#define PHY_ANALOG_THERM_SAR_ADC_OUT_GET(x)                                           (((x) & 0x00007f80) >> 7)
-#define PHY_ANALOG_THERM_SAR_DACTEST_CODE_MSB                                                                22
-#define PHY_ANALOG_THERM_SAR_DACTEST_CODE_LSB                                                                15
-#define PHY_ANALOG_THERM_SAR_DACTEST_CODE_MASK                                                       0x007f8000
-#define PHY_ANALOG_THERM_SAR_DACTEST_CODE_GET(x)                                     (((x) & 0x007f8000) >> 15)
-#define PHY_ANALOG_THERM_SAR_DACTEST_CODE_SET(x)                                     (((x) << 15) & 0x007f8000)
-#define PHY_ANALOG_THERM_SAR_DACTEST_EN_MSB                                                                  23
-#define PHY_ANALOG_THERM_SAR_DACTEST_EN_LSB                                                                  23
-#define PHY_ANALOG_THERM_SAR_DACTEST_EN_MASK                                                         0x00800000
-#define PHY_ANALOG_THERM_SAR_DACTEST_EN_GET(x)                                       (((x) & 0x00800000) >> 23)
-#define PHY_ANALOG_THERM_SAR_DACTEST_EN_SET(x)                                       (((x) << 23) & 0x00800000)
-#define PHY_ANALOG_THERM_SAR_ADCCAL_EN_MSB                                                                   24
-#define PHY_ANALOG_THERM_SAR_ADCCAL_EN_LSB                                                                   24
-#define PHY_ANALOG_THERM_SAR_ADCCAL_EN_MASK                                                          0x01000000
-#define PHY_ANALOG_THERM_SAR_ADCCAL_EN_GET(x)                                        (((x) & 0x01000000) >> 24)
-#define PHY_ANALOG_THERM_SAR_ADCCAL_EN_SET(x)                                        (((x) << 24) & 0x01000000)
-#define PHY_ANALOG_THERM_THERMSEL_MSB                                                                        26
-#define PHY_ANALOG_THERM_THERMSEL_LSB                                                                        25
-#define PHY_ANALOG_THERM_THERMSEL_MASK                                                               0x06000000
-#define PHY_ANALOG_THERM_THERMSEL_GET(x)                                             (((x) & 0x06000000) >> 25)
-#define PHY_ANALOG_THERM_THERMSEL_SET(x)                                             (((x) << 25) & 0x06000000)
-#define PHY_ANALOG_THERM_SAR_SLOW_EN_MSB                                                                     27
-#define PHY_ANALOG_THERM_SAR_SLOW_EN_LSB                                                                     27
-#define PHY_ANALOG_THERM_SAR_SLOW_EN_MASK                                                            0x08000000
-#define PHY_ANALOG_THERM_SAR_SLOW_EN_GET(x)                                          (((x) & 0x08000000) >> 27)
-#define PHY_ANALOG_THERM_SAR_SLOW_EN_SET(x)                                          (((x) << 27) & 0x08000000)
-#define PHY_ANALOG_THERM_THERMSTART_MSB                                                                      28
-#define PHY_ANALOG_THERM_THERMSTART_LSB                                                                      28
-#define PHY_ANALOG_THERM_THERMSTART_MASK                                                             0x10000000
-#define PHY_ANALOG_THERM_THERMSTART_GET(x)                                           (((x) & 0x10000000) >> 28)
-#define PHY_ANALOG_THERM_THERMSTART_SET(x)                                           (((x) << 28) & 0x10000000)
-#define PHY_ANALOG_THERM_SAR_AUTOPWD_EN_MSB                                                                  29
-#define PHY_ANALOG_THERM_SAR_AUTOPWD_EN_LSB                                                                  29
-#define PHY_ANALOG_THERM_SAR_AUTOPWD_EN_MASK                                                         0x20000000
-#define PHY_ANALOG_THERM_SAR_AUTOPWD_EN_GET(x)                                       (((x) & 0x20000000) >> 29)
-#define PHY_ANALOG_THERM_SAR_AUTOPWD_EN_SET(x)                                       (((x) << 29) & 0x20000000)
-#define PHY_ANALOG_THERM_THERMON_MSB                                                                         30
-#define PHY_ANALOG_THERM_THERMON_LSB                                                                         30
-#define PHY_ANALOG_THERM_THERMON_MASK                                                                0x40000000
-#define PHY_ANALOG_THERM_THERMON_GET(x)                                              (((x) & 0x40000000) >> 30)
-#define PHY_ANALOG_THERM_THERMON_SET(x)                                              (((x) << 30) & 0x40000000)
-#define PHY_ANALOG_THERM_LOCAL_THERM_MSB                                                                     31
-#define PHY_ANALOG_THERM_LOCAL_THERM_LSB                                                                     31
-#define PHY_ANALOG_THERM_LOCAL_THERM_MASK                                                            0x80000000
-#define PHY_ANALOG_THERM_LOCAL_THERM_GET(x)                                          (((x) & 0x80000000) >> 31)
-#define PHY_ANALOG_THERM_LOCAL_THERM_SET(x)                                          (((x) << 31) & 0x80000000)
-
-/* macros for XTAL */
-#define PHY_ANALOG_XTAL_ADDRESS                                                                      0x00000290
-#define PHY_ANALOG_XTAL_OFFSET                                                                       0x00000290
-#define PHY_ANALOG_XTAL_SPARE_MSB                                                                             5
-#define PHY_ANALOG_XTAL_SPARE_LSB                                                                             0
-#define PHY_ANALOG_XTAL_SPARE_MASK                                                                   0x0000003f
-#define PHY_ANALOG_XTAL_SPARE_GET(x)                                                  (((x) & 0x0000003f) >> 0)
-#define PHY_ANALOG_XTAL_SPARE_SET(x)                                                  (((x) << 0) & 0x0000003f)
-#define PHY_ANALOG_XTAL_XTAL_NOTCXODET_MSB                                                                    6
-#define PHY_ANALOG_XTAL_XTAL_NOTCXODET_LSB                                                                    6
-#define PHY_ANALOG_XTAL_XTAL_NOTCXODET_MASK                                                          0x00000040
-#define PHY_ANALOG_XTAL_XTAL_NOTCXODET_GET(x)                                         (((x) & 0x00000040) >> 6)
-#define PHY_ANALOG_XTAL_XTAL_NOTCXODET_SET(x)                                         (((x) << 6) & 0x00000040)
-#define PHY_ANALOG_XTAL_LOCALBIAS2X_MSB                                                                       7
-#define PHY_ANALOG_XTAL_LOCALBIAS2X_LSB                                                                       7
-#define PHY_ANALOG_XTAL_LOCALBIAS2X_MASK                                                             0x00000080
-#define PHY_ANALOG_XTAL_LOCALBIAS2X_GET(x)                                            (((x) & 0x00000080) >> 7)
-#define PHY_ANALOG_XTAL_LOCALBIAS2X_SET(x)                                            (((x) << 7) & 0x00000080)
-#define PHY_ANALOG_XTAL_LOCAL_XTAL_MSB                                                                        8
-#define PHY_ANALOG_XTAL_LOCAL_XTAL_LSB                                                                        8
-#define PHY_ANALOG_XTAL_LOCAL_XTAL_MASK                                                              0x00000100
-#define PHY_ANALOG_XTAL_LOCAL_XTAL_GET(x)                                             (((x) & 0x00000100) >> 8)
-#define PHY_ANALOG_XTAL_LOCAL_XTAL_SET(x)                                             (((x) << 8) & 0x00000100)
-#define PHY_ANALOG_XTAL_XTAL_PWDCLKIN_MSB                                                                     9
-#define PHY_ANALOG_XTAL_XTAL_PWDCLKIN_LSB                                                                     9
-#define PHY_ANALOG_XTAL_XTAL_PWDCLKIN_MASK                                                           0x00000200
-#define PHY_ANALOG_XTAL_XTAL_PWDCLKIN_GET(x)                                          (((x) & 0x00000200) >> 9)
-#define PHY_ANALOG_XTAL_XTAL_PWDCLKIN_SET(x)                                          (((x) << 9) & 0x00000200)
-#define PHY_ANALOG_XTAL_XTAL_OSCON_MSB                                                                       10
-#define PHY_ANALOG_XTAL_XTAL_OSCON_LSB                                                                       10
-#define PHY_ANALOG_XTAL_XTAL_OSCON_MASK                                                              0x00000400
-#define PHY_ANALOG_XTAL_XTAL_OSCON_GET(x)                                            (((x) & 0x00000400) >> 10)
-#define PHY_ANALOG_XTAL_XTAL_OSCON_SET(x)                                            (((x) << 10) & 0x00000400)
-#define PHY_ANALOG_XTAL_XTAL_PWDCLKD_MSB                                                                     11
-#define PHY_ANALOG_XTAL_XTAL_PWDCLKD_LSB                                                                     11
-#define PHY_ANALOG_XTAL_XTAL_PWDCLKD_MASK                                                            0x00000800
-#define PHY_ANALOG_XTAL_XTAL_PWDCLKD_GET(x)                                          (((x) & 0x00000800) >> 11)
-#define PHY_ANALOG_XTAL_XTAL_PWDCLKD_SET(x)                                          (((x) << 11) & 0x00000800)
-#define PHY_ANALOG_XTAL_XTAL_LOCALBIAS_MSB                                                                   12
-#define PHY_ANALOG_XTAL_XTAL_LOCALBIAS_LSB                                                                   12
-#define PHY_ANALOG_XTAL_XTAL_LOCALBIAS_MASK                                                          0x00001000
-#define PHY_ANALOG_XTAL_XTAL_LOCALBIAS_GET(x)                                        (((x) & 0x00001000) >> 12)
-#define PHY_ANALOG_XTAL_XTAL_LOCALBIAS_SET(x)                                        (((x) << 12) & 0x00001000)
-#define PHY_ANALOG_XTAL_XTAL_SHRTXIN_MSB                                                                     13
-#define PHY_ANALOG_XTAL_XTAL_SHRTXIN_LSB                                                                     13
-#define PHY_ANALOG_XTAL_XTAL_SHRTXIN_MASK                                                            0x00002000
-#define PHY_ANALOG_XTAL_XTAL_SHRTXIN_GET(x)                                          (((x) & 0x00002000) >> 13)
-#define PHY_ANALOG_XTAL_XTAL_SHRTXIN_SET(x)                                          (((x) << 13) & 0x00002000)
-#define PHY_ANALOG_XTAL_XTAL_DRVSTR_MSB                                                                      15
-#define PHY_ANALOG_XTAL_XTAL_DRVSTR_LSB                                                                      14
-#define PHY_ANALOG_XTAL_XTAL_DRVSTR_MASK                                                             0x0000c000
-#define PHY_ANALOG_XTAL_XTAL_DRVSTR_GET(x)                                           (((x) & 0x0000c000) >> 14)
-#define PHY_ANALOG_XTAL_XTAL_DRVSTR_SET(x)                                           (((x) << 14) & 0x0000c000)
-#define PHY_ANALOG_XTAL_XTAL_CAPOUTDAC_MSB                                                                   22
-#define PHY_ANALOG_XTAL_XTAL_CAPOUTDAC_LSB                                                                   16
-#define PHY_ANALOG_XTAL_XTAL_CAPOUTDAC_MASK                                                          0x007f0000
-#define PHY_ANALOG_XTAL_XTAL_CAPOUTDAC_GET(x)                                        (((x) & 0x007f0000) >> 16)
-#define PHY_ANALOG_XTAL_XTAL_CAPOUTDAC_SET(x)                                        (((x) << 16) & 0x007f0000)
-#define PHY_ANALOG_XTAL_XTAL_CAPINDAC_MSB                                                                    29
-#define PHY_ANALOG_XTAL_XTAL_CAPINDAC_LSB                                                                    23
-#define PHY_ANALOG_XTAL_XTAL_CAPINDAC_MASK                                                           0x3f800000
-#define PHY_ANALOG_XTAL_XTAL_CAPINDAC_GET(x)                                         (((x) & 0x3f800000) >> 23)
-#define PHY_ANALOG_XTAL_XTAL_CAPINDAC_SET(x)                                         (((x) << 23) & 0x3f800000)
-#define PHY_ANALOG_XTAL_XTAL_BIAS2X_MSB                                                                      30
-#define PHY_ANALOG_XTAL_XTAL_BIAS2X_LSB                                                                      30
-#define PHY_ANALOG_XTAL_XTAL_BIAS2X_MASK                                                             0x40000000
-#define PHY_ANALOG_XTAL_XTAL_BIAS2X_GET(x)                                           (((x) & 0x40000000) >> 30)
-#define PHY_ANALOG_XTAL_XTAL_BIAS2X_SET(x)                                           (((x) << 30) & 0x40000000)
-#define PHY_ANALOG_XTAL_TCXODET_MSB                                                                          31
-#define PHY_ANALOG_XTAL_TCXODET_LSB                                                                          31
-#define PHY_ANALOG_XTAL_TCXODET_MASK                                                                 0x80000000
-#define PHY_ANALOG_XTAL_TCXODET_GET(x)                                               (((x) & 0x80000000) >> 31)
-
-/* macros for rbist_cntrl */
-#define PHY_ANALOG_RBIST_CNTRL_ADDRESS                                                               0x00000380
-#define PHY_ANALOG_RBIST_CNTRL_OFFSET                                                                0x00000380
-#define PHY_ANALOG_RBIST_CNTRL_ATE_TONEGEN_DC_ENABLE_MSB                                                      0
-#define PHY_ANALOG_RBIST_CNTRL_ATE_TONEGEN_DC_ENABLE_LSB                                                      0
-#define PHY_ANALOG_RBIST_CNTRL_ATE_TONEGEN_DC_ENABLE_MASK                                            0x00000001
-#define PHY_ANALOG_RBIST_CNTRL_ATE_TONEGEN_DC_ENABLE_GET(x)                           (((x) & 0x00000001) >> 0)
-#define PHY_ANALOG_RBIST_CNTRL_ATE_TONEGEN_DC_ENABLE_SET(x)                           (((x) << 0) & 0x00000001)
-#define PHY_ANALOG_RBIST_CNTRL_ATE_TONEGEN_TONE0_ENABLE_MSB                                                   1
-#define PHY_ANALOG_RBIST_CNTRL_ATE_TONEGEN_TONE0_ENABLE_LSB                                                   1
-#define PHY_ANALOG_RBIST_CNTRL_ATE_TONEGEN_TONE0_ENABLE_MASK                                         0x00000002
-#define PHY_ANALOG_RBIST_CNTRL_ATE_TONEGEN_TONE0_ENABLE_GET(x)                        (((x) & 0x00000002) >> 1)
-#define PHY_ANALOG_RBIST_CNTRL_ATE_TONEGEN_TONE0_ENABLE_SET(x)                        (((x) << 1) & 0x00000002)
-#define PHY_ANALOG_RBIST_CNTRL_ATE_TONEGEN_TONE1_ENABLE_MSB                                                   2
-#define PHY_ANALOG_RBIST_CNTRL_ATE_TONEGEN_TONE1_ENABLE_LSB                                                   2
-#define PHY_ANALOG_RBIST_CNTRL_ATE_TONEGEN_TONE1_ENABLE_MASK                                         0x00000004
-#define PHY_ANALOG_RBIST_CNTRL_ATE_TONEGEN_TONE1_ENABLE_GET(x)                        (((x) & 0x00000004) >> 2)
-#define PHY_ANALOG_RBIST_CNTRL_ATE_TONEGEN_TONE1_ENABLE_SET(x)                        (((x) << 2) & 0x00000004)
-#define PHY_ANALOG_RBIST_CNTRL_ATE_TONEGEN_LFTONE0_ENABLE_MSB                                                 3
-#define PHY_ANALOG_RBIST_CNTRL_ATE_TONEGEN_LFTONE0_ENABLE_LSB                                                 3
-#define PHY_ANALOG_RBIST_CNTRL_ATE_TONEGEN_LFTONE0_ENABLE_MASK                                       0x00000008
-#define PHY_ANALOG_RBIST_CNTRL_ATE_TONEGEN_LFTONE0_ENABLE_GET(x)                      (((x) & 0x00000008) >> 3)
-#define PHY_ANALOG_RBIST_CNTRL_ATE_TONEGEN_LFTONE0_ENABLE_SET(x)                      (((x) << 3) & 0x00000008)
-#define PHY_ANALOG_RBIST_CNTRL_ATE_TONEGEN_LINRAMP_ENABLE_I_MSB                                               4
-#define PHY_ANALOG_RBIST_CNTRL_ATE_TONEGEN_LINRAMP_ENABLE_I_LSB                                               4
-#define PHY_ANALOG_RBIST_CNTRL_ATE_TONEGEN_LINRAMP_ENABLE_I_MASK                                     0x00000010
-#define PHY_ANALOG_RBIST_CNTRL_ATE_TONEGEN_LINRAMP_ENABLE_I_GET(x)                    (((x) & 0x00000010) >> 4)
-#define PHY_ANALOG_RBIST_CNTRL_ATE_TONEGEN_LINRAMP_ENABLE_I_SET(x)                    (((x) << 4) & 0x00000010)
-#define PHY_ANALOG_RBIST_CNTRL_ATE_TONEGEN_LINRAMP_ENABLE_Q_MSB                                               5
-#define PHY_ANALOG_RBIST_CNTRL_ATE_TONEGEN_LINRAMP_ENABLE_Q_LSB                                               5
-#define PHY_ANALOG_RBIST_CNTRL_ATE_TONEGEN_LINRAMP_ENABLE_Q_MASK                                     0x00000020
-#define PHY_ANALOG_RBIST_CNTRL_ATE_TONEGEN_LINRAMP_ENABLE_Q_GET(x)                    (((x) & 0x00000020) >> 5)
-#define PHY_ANALOG_RBIST_CNTRL_ATE_TONEGEN_LINRAMP_ENABLE_Q_SET(x)                    (((x) << 5) & 0x00000020)
-#define PHY_ANALOG_RBIST_CNTRL_ATE_TONEGEN_PRBS_ENABLE_I_MSB                                                  6
-#define PHY_ANALOG_RBIST_CNTRL_ATE_TONEGEN_PRBS_ENABLE_I_LSB                                                  6
-#define PHY_ANALOG_RBIST_CNTRL_ATE_TONEGEN_PRBS_ENABLE_I_MASK                                        0x00000040
-#define PHY_ANALOG_RBIST_CNTRL_ATE_TONEGEN_PRBS_ENABLE_I_GET(x)                       (((x) & 0x00000040) >> 6)
-#define PHY_ANALOG_RBIST_CNTRL_ATE_TONEGEN_PRBS_ENABLE_I_SET(x)                       (((x) << 6) & 0x00000040)
-#define PHY_ANALOG_RBIST_CNTRL_ATE_TONEGEN_PRBS_ENABLE_Q_MSB                                                  7
-#define PHY_ANALOG_RBIST_CNTRL_ATE_TONEGEN_PRBS_ENABLE_Q_LSB                                                  7
-#define PHY_ANALOG_RBIST_CNTRL_ATE_TONEGEN_PRBS_ENABLE_Q_MASK                                        0x00000080
-#define PHY_ANALOG_RBIST_CNTRL_ATE_TONEGEN_PRBS_ENABLE_Q_GET(x)                       (((x) & 0x00000080) >> 7)
-#define PHY_ANALOG_RBIST_CNTRL_ATE_TONEGEN_PRBS_ENABLE_Q_SET(x)                       (((x) << 7) & 0x00000080)
-#define PHY_ANALOG_RBIST_CNTRL_ATE_CMAC_DC_WRITE_TO_CANCEL_MSB                                                8
-#define PHY_ANALOG_RBIST_CNTRL_ATE_CMAC_DC_WRITE_TO_CANCEL_LSB                                                8
-#define PHY_ANALOG_RBIST_CNTRL_ATE_CMAC_DC_WRITE_TO_CANCEL_MASK                                      0x00000100
-#define PHY_ANALOG_RBIST_CNTRL_ATE_CMAC_DC_WRITE_TO_CANCEL_GET(x)                     (((x) & 0x00000100) >> 8)
-#define PHY_ANALOG_RBIST_CNTRL_ATE_CMAC_DC_WRITE_TO_CANCEL_SET(x)                     (((x) << 8) & 0x00000100)
-#define PHY_ANALOG_RBIST_CNTRL_ATE_CMAC_DC_ENABLE_MSB                                                         9
-#define PHY_ANALOG_RBIST_CNTRL_ATE_CMAC_DC_ENABLE_LSB                                                         9
-#define PHY_ANALOG_RBIST_CNTRL_ATE_CMAC_DC_ENABLE_MASK                                               0x00000200
-#define PHY_ANALOG_RBIST_CNTRL_ATE_CMAC_DC_ENABLE_GET(x)                              (((x) & 0x00000200) >> 9)
-#define PHY_ANALOG_RBIST_CNTRL_ATE_CMAC_DC_ENABLE_SET(x)                              (((x) << 9) & 0x00000200)
-#define PHY_ANALOG_RBIST_CNTRL_ATE_CMAC_CORR_ENABLE_MSB                                                      10
-#define PHY_ANALOG_RBIST_CNTRL_ATE_CMAC_CORR_ENABLE_LSB                                                      10
-#define PHY_ANALOG_RBIST_CNTRL_ATE_CMAC_CORR_ENABLE_MASK                                             0x00000400
-#define PHY_ANALOG_RBIST_CNTRL_ATE_CMAC_CORR_ENABLE_GET(x)                           (((x) & 0x00000400) >> 10)
-#define PHY_ANALOG_RBIST_CNTRL_ATE_CMAC_CORR_ENABLE_SET(x)                           (((x) << 10) & 0x00000400)
-#define PHY_ANALOG_RBIST_CNTRL_ATE_CMAC_POWER_ENABLE_MSB                                                     11
-#define PHY_ANALOG_RBIST_CNTRL_ATE_CMAC_POWER_ENABLE_LSB                                                     11
-#define PHY_ANALOG_RBIST_CNTRL_ATE_CMAC_POWER_ENABLE_MASK                                            0x00000800
-#define PHY_ANALOG_RBIST_CNTRL_ATE_CMAC_POWER_ENABLE_GET(x)                          (((x) & 0x00000800) >> 11)
-#define PHY_ANALOG_RBIST_CNTRL_ATE_CMAC_POWER_ENABLE_SET(x)                          (((x) << 11) & 0x00000800)
-#define PHY_ANALOG_RBIST_CNTRL_ATE_CMAC_IQ_ENABLE_MSB                                                        12
-#define PHY_ANALOG_RBIST_CNTRL_ATE_CMAC_IQ_ENABLE_LSB                                                        12
-#define PHY_ANALOG_RBIST_CNTRL_ATE_CMAC_IQ_ENABLE_MASK                                               0x00001000
-#define PHY_ANALOG_RBIST_CNTRL_ATE_CMAC_IQ_ENABLE_GET(x)                             (((x) & 0x00001000) >> 12)
-#define PHY_ANALOG_RBIST_CNTRL_ATE_CMAC_IQ_ENABLE_SET(x)                             (((x) << 12) & 0x00001000)
-#define PHY_ANALOG_RBIST_CNTRL_ATE_CMAC_I2Q2_ENABLE_MSB                                                      13
-#define PHY_ANALOG_RBIST_CNTRL_ATE_CMAC_I2Q2_ENABLE_LSB                                                      13
-#define PHY_ANALOG_RBIST_CNTRL_ATE_CMAC_I2Q2_ENABLE_MASK                                             0x00002000
-#define PHY_ANALOG_RBIST_CNTRL_ATE_CMAC_I2Q2_ENABLE_GET(x)                           (((x) & 0x00002000) >> 13)
-#define PHY_ANALOG_RBIST_CNTRL_ATE_CMAC_I2Q2_ENABLE_SET(x)                           (((x) << 13) & 0x00002000)
-#define PHY_ANALOG_RBIST_CNTRL_ATE_CMAC_POWER_HPF_ENABLE_MSB                                                 14
-#define PHY_ANALOG_RBIST_CNTRL_ATE_CMAC_POWER_HPF_ENABLE_LSB                                                 14
-#define PHY_ANALOG_RBIST_CNTRL_ATE_CMAC_POWER_HPF_ENABLE_MASK                                        0x00004000
-#define PHY_ANALOG_RBIST_CNTRL_ATE_CMAC_POWER_HPF_ENABLE_GET(x)                      (((x) & 0x00004000) >> 14)
-#define PHY_ANALOG_RBIST_CNTRL_ATE_CMAC_POWER_HPF_ENABLE_SET(x)                      (((x) << 14) & 0x00004000)
-#define PHY_ANALOG_RBIST_CNTRL_ATE_RXDAC_CALIBRATE_MSB                                                       15
-#define PHY_ANALOG_RBIST_CNTRL_ATE_RXDAC_CALIBRATE_LSB                                                       15
-#define PHY_ANALOG_RBIST_CNTRL_ATE_RXDAC_CALIBRATE_MASK                                              0x00008000
-#define PHY_ANALOG_RBIST_CNTRL_ATE_RXDAC_CALIBRATE_GET(x)                            (((x) & 0x00008000) >> 15)
-#define PHY_ANALOG_RBIST_CNTRL_ATE_RXDAC_CALIBRATE_SET(x)                            (((x) << 15) & 0x00008000)
-#define PHY_ANALOG_RBIST_CNTRL_ATE_RBIST_ENABLE_MSB                                                          16
-#define PHY_ANALOG_RBIST_CNTRL_ATE_RBIST_ENABLE_LSB                                                          16
-#define PHY_ANALOG_RBIST_CNTRL_ATE_RBIST_ENABLE_MASK                                                 0x00010000
-#define PHY_ANALOG_RBIST_CNTRL_ATE_RBIST_ENABLE_GET(x)                               (((x) & 0x00010000) >> 16)
-#define PHY_ANALOG_RBIST_CNTRL_ATE_RBIST_ENABLE_SET(x)                               (((x) << 16) & 0x00010000)
-#define PHY_ANALOG_RBIST_CNTRL_ATE_ADC_CLK_INVERT_MSB                                                        17
-#define PHY_ANALOG_RBIST_CNTRL_ATE_ADC_CLK_INVERT_LSB                                                        17
-#define PHY_ANALOG_RBIST_CNTRL_ATE_ADC_CLK_INVERT_MASK                                               0x00020000
-#define PHY_ANALOG_RBIST_CNTRL_ATE_ADC_CLK_INVERT_GET(x)                             (((x) & 0x00020000) >> 17)
-#define PHY_ANALOG_RBIST_CNTRL_ATE_ADC_CLK_INVERT_SET(x)                             (((x) << 17) & 0x00020000)
-
-/* macros for tx_dc_offset */
-#define PHY_ANALOG_TX_DC_OFFSET_ADDRESS                                                              0x00000384
-#define PHY_ANALOG_TX_DC_OFFSET_OFFSET                                                               0x00000384
-#define PHY_ANALOG_TX_DC_OFFSET_ATE_TONEGEN_DC_I_MSB                                                         10
-#define PHY_ANALOG_TX_DC_OFFSET_ATE_TONEGEN_DC_I_LSB                                                          0
-#define PHY_ANALOG_TX_DC_OFFSET_ATE_TONEGEN_DC_I_MASK                                                0x000007ff
-#define PHY_ANALOG_TX_DC_OFFSET_ATE_TONEGEN_DC_I_GET(x)                               (((x) & 0x000007ff) >> 0)
-#define PHY_ANALOG_TX_DC_OFFSET_ATE_TONEGEN_DC_I_SET(x)                               (((x) << 0) & 0x000007ff)
-#define PHY_ANALOG_TX_DC_OFFSET_ATE_TONEGEN_DC_Q_MSB                                                         26
-#define PHY_ANALOG_TX_DC_OFFSET_ATE_TONEGEN_DC_Q_LSB                                                         16
-#define PHY_ANALOG_TX_DC_OFFSET_ATE_TONEGEN_DC_Q_MASK                                                0x07ff0000
-#define PHY_ANALOG_TX_DC_OFFSET_ATE_TONEGEN_DC_Q_GET(x)                              (((x) & 0x07ff0000) >> 16)
-#define PHY_ANALOG_TX_DC_OFFSET_ATE_TONEGEN_DC_Q_SET(x)                              (((x) << 16) & 0x07ff0000)
-
-/* macros for tx_tonegen0 */
-#define PHY_ANALOG_TX_TONEGEN0_ADDRESS                                                               0x00000388
-#define PHY_ANALOG_TX_TONEGEN0_OFFSET                                                                0x00000388
-#define PHY_ANALOG_TX_TONEGEN0_ATE_TONEGEN_TONE_FREQ_MSB                                                      6
-#define PHY_ANALOG_TX_TONEGEN0_ATE_TONEGEN_TONE_FREQ_LSB                                                      0
-#define PHY_ANALOG_TX_TONEGEN0_ATE_TONEGEN_TONE_FREQ_MASK                                            0x0000007f
-#define PHY_ANALOG_TX_TONEGEN0_ATE_TONEGEN_TONE_FREQ_GET(x)                           (((x) & 0x0000007f) >> 0)
-#define PHY_ANALOG_TX_TONEGEN0_ATE_TONEGEN_TONE_FREQ_SET(x)                           (((x) << 0) & 0x0000007f)
-#define PHY_ANALOG_TX_TONEGEN0_ATE_TONEGEN_TONE_A_EXP_MSB                                                    11
-#define PHY_ANALOG_TX_TONEGEN0_ATE_TONEGEN_TONE_A_EXP_LSB                                                     8
-#define PHY_ANALOG_TX_TONEGEN0_ATE_TONEGEN_TONE_A_EXP_MASK                                           0x00000f00
-#define PHY_ANALOG_TX_TONEGEN0_ATE_TONEGEN_TONE_A_EXP_GET(x)                          (((x) & 0x00000f00) >> 8)
-#define PHY_ANALOG_TX_TONEGEN0_ATE_TONEGEN_TONE_A_EXP_SET(x)                          (((x) << 8) & 0x00000f00)
-#define PHY_ANALOG_TX_TONEGEN0_ATE_TONEGEN_TONE_A_MAN_MSB                                                    23
-#define PHY_ANALOG_TX_TONEGEN0_ATE_TONEGEN_TONE_A_MAN_LSB                                                    16
-#define PHY_ANALOG_TX_TONEGEN0_ATE_TONEGEN_TONE_A_MAN_MASK                                           0x00ff0000
-#define PHY_ANALOG_TX_TONEGEN0_ATE_TONEGEN_TONE_A_MAN_GET(x)                         (((x) & 0x00ff0000) >> 16)
-#define PHY_ANALOG_TX_TONEGEN0_ATE_TONEGEN_TONE_A_MAN_SET(x)                         (((x) << 16) & 0x00ff0000)
-#define PHY_ANALOG_TX_TONEGEN0_ATE_TONEGEN_TONE_TAU_K_MSB                                                    30
-#define PHY_ANALOG_TX_TONEGEN0_ATE_TONEGEN_TONE_TAU_K_LSB                                                    24
-#define PHY_ANALOG_TX_TONEGEN0_ATE_TONEGEN_TONE_TAU_K_MASK                                           0x7f000000
-#define PHY_ANALOG_TX_TONEGEN0_ATE_TONEGEN_TONE_TAU_K_GET(x)                         (((x) & 0x7f000000) >> 24)
-#define PHY_ANALOG_TX_TONEGEN0_ATE_TONEGEN_TONE_TAU_K_SET(x)                         (((x) << 24) & 0x7f000000)
-
-/* macros for tx_tonegen1 */
-#define PHY_ANALOG_TX_TONEGEN1_ADDRESS                                                               0x0000038c
-#define PHY_ANALOG_TX_TONEGEN1_OFFSET                                                                0x0000038c
-#define PHY_ANALOG_TX_TONEGEN1_ATE_TONEGEN_TONE_FREQ_MSB                                                      6
-#define PHY_ANALOG_TX_TONEGEN1_ATE_TONEGEN_TONE_FREQ_LSB                                                      0
-#define PHY_ANALOG_TX_TONEGEN1_ATE_TONEGEN_TONE_FREQ_MASK                                            0x0000007f
-#define PHY_ANALOG_TX_TONEGEN1_ATE_TONEGEN_TONE_FREQ_GET(x)                           (((x) & 0x0000007f) >> 0)
-#define PHY_ANALOG_TX_TONEGEN1_ATE_TONEGEN_TONE_FREQ_SET(x)                           (((x) << 0) & 0x0000007f)
-#define PHY_ANALOG_TX_TONEGEN1_ATE_TONEGEN_TONE_A_EXP_MSB                                                    11
-#define PHY_ANALOG_TX_TONEGEN1_ATE_TONEGEN_TONE_A_EXP_LSB                                                     8
-#define PHY_ANALOG_TX_TONEGEN1_ATE_TONEGEN_TONE_A_EXP_MASK                                           0x00000f00
-#define PHY_ANALOG_TX_TONEGEN1_ATE_TONEGEN_TONE_A_EXP_GET(x)                          (((x) & 0x00000f00) >> 8)
-#define PHY_ANALOG_TX_TONEGEN1_ATE_TONEGEN_TONE_A_EXP_SET(x)                          (((x) << 8) & 0x00000f00)
-#define PHY_ANALOG_TX_TONEGEN1_ATE_TONEGEN_TONE_A_MAN_MSB                                                    23
-#define PHY_ANALOG_TX_TONEGEN1_ATE_TONEGEN_TONE_A_MAN_LSB                                                    16
-#define PHY_ANALOG_TX_TONEGEN1_ATE_TONEGEN_TONE_A_MAN_MASK                                           0x00ff0000
-#define PHY_ANALOG_TX_TONEGEN1_ATE_TONEGEN_TONE_A_MAN_GET(x)                         (((x) & 0x00ff0000) >> 16)
-#define PHY_ANALOG_TX_TONEGEN1_ATE_TONEGEN_TONE_A_MAN_SET(x)                         (((x) << 16) & 0x00ff0000)
-#define PHY_ANALOG_TX_TONEGEN1_ATE_TONEGEN_TONE_TAU_K_MSB                                                    30
-#define PHY_ANALOG_TX_TONEGEN1_ATE_TONEGEN_TONE_TAU_K_LSB                                                    24
-#define PHY_ANALOG_TX_TONEGEN1_ATE_TONEGEN_TONE_TAU_K_MASK                                           0x7f000000
-#define PHY_ANALOG_TX_TONEGEN1_ATE_TONEGEN_TONE_TAU_K_GET(x)                         (((x) & 0x7f000000) >> 24)
-#define PHY_ANALOG_TX_TONEGEN1_ATE_TONEGEN_TONE_TAU_K_SET(x)                         (((x) << 24) & 0x7f000000)
-
-/* macros for tx_lftonegen0 */
-#define PHY_ANALOG_TX_LFTONEGEN0_ADDRESS                                                             0x00000390
-#define PHY_ANALOG_TX_LFTONEGEN0_OFFSET                                                              0x00000390
-#define PHY_ANALOG_TX_LFTONEGEN0_ATE_TONEGEN_TONE_FREQ_MSB                                                    6
-#define PHY_ANALOG_TX_LFTONEGEN0_ATE_TONEGEN_TONE_FREQ_LSB                                                    0
-#define PHY_ANALOG_TX_LFTONEGEN0_ATE_TONEGEN_TONE_FREQ_MASK                                          0x0000007f
-#define PHY_ANALOG_TX_LFTONEGEN0_ATE_TONEGEN_TONE_FREQ_GET(x)                         (((x) & 0x0000007f) >> 0)
-#define PHY_ANALOG_TX_LFTONEGEN0_ATE_TONEGEN_TONE_FREQ_SET(x)                         (((x) << 0) & 0x0000007f)
-#define PHY_ANALOG_TX_LFTONEGEN0_ATE_TONEGEN_TONE_A_EXP_MSB                                                  11
-#define PHY_ANALOG_TX_LFTONEGEN0_ATE_TONEGEN_TONE_A_EXP_LSB                                                   8
-#define PHY_ANALOG_TX_LFTONEGEN0_ATE_TONEGEN_TONE_A_EXP_MASK                                         0x00000f00
-#define PHY_ANALOG_TX_LFTONEGEN0_ATE_TONEGEN_TONE_A_EXP_GET(x)                        (((x) & 0x00000f00) >> 8)
-#define PHY_ANALOG_TX_LFTONEGEN0_ATE_TONEGEN_TONE_A_EXP_SET(x)                        (((x) << 8) & 0x00000f00)
-#define PHY_ANALOG_TX_LFTONEGEN0_ATE_TONEGEN_TONE_A_MAN_MSB                                                  23
-#define PHY_ANALOG_TX_LFTONEGEN0_ATE_TONEGEN_TONE_A_MAN_LSB                                                  16
-#define PHY_ANALOG_TX_LFTONEGEN0_ATE_TONEGEN_TONE_A_MAN_MASK                                         0x00ff0000
-#define PHY_ANALOG_TX_LFTONEGEN0_ATE_TONEGEN_TONE_A_MAN_GET(x)                       (((x) & 0x00ff0000) >> 16)
-#define PHY_ANALOG_TX_LFTONEGEN0_ATE_TONEGEN_TONE_A_MAN_SET(x)                       (((x) << 16) & 0x00ff0000)
-#define PHY_ANALOG_TX_LFTONEGEN0_ATE_TONEGEN_TONE_TAU_K_MSB                                                  30
-#define PHY_ANALOG_TX_LFTONEGEN0_ATE_TONEGEN_TONE_TAU_K_LSB                                                  24
-#define PHY_ANALOG_TX_LFTONEGEN0_ATE_TONEGEN_TONE_TAU_K_MASK                                         0x7f000000
-#define PHY_ANALOG_TX_LFTONEGEN0_ATE_TONEGEN_TONE_TAU_K_GET(x)                       (((x) & 0x7f000000) >> 24)
-#define PHY_ANALOG_TX_LFTONEGEN0_ATE_TONEGEN_TONE_TAU_K_SET(x)                       (((x) << 24) & 0x7f000000)
-
-/* macros for tx_linear_ramp_i */
-#define PHY_ANALOG_TX_LINEAR_RAMP_I_ADDRESS                                                          0x00000394
-#define PHY_ANALOG_TX_LINEAR_RAMP_I_OFFSET                                                           0x00000394
-#define PHY_ANALOG_TX_LINEAR_RAMP_I_ATE_TONEGEN_LINRAMP_INIT_MSB                                             10
-#define PHY_ANALOG_TX_LINEAR_RAMP_I_ATE_TONEGEN_LINRAMP_INIT_LSB                                              0
-#define PHY_ANALOG_TX_LINEAR_RAMP_I_ATE_TONEGEN_LINRAMP_INIT_MASK                                    0x000007ff
-#define PHY_ANALOG_TX_LINEAR_RAMP_I_ATE_TONEGEN_LINRAMP_INIT_GET(x)                   (((x) & 0x000007ff) >> 0)
-#define PHY_ANALOG_TX_LINEAR_RAMP_I_ATE_TONEGEN_LINRAMP_INIT_SET(x)                   (((x) << 0) & 0x000007ff)
-#define PHY_ANALOG_TX_LINEAR_RAMP_I_ATE_TONEGEN_LINRAMP_DWELL_MSB                                            21
-#define PHY_ANALOG_TX_LINEAR_RAMP_I_ATE_TONEGEN_LINRAMP_DWELL_LSB                                            12
-#define PHY_ANALOG_TX_LINEAR_RAMP_I_ATE_TONEGEN_LINRAMP_DWELL_MASK                                   0x003ff000
-#define PHY_ANALOG_TX_LINEAR_RAMP_I_ATE_TONEGEN_LINRAMP_DWELL_GET(x)                 (((x) & 0x003ff000) >> 12)
-#define PHY_ANALOG_TX_LINEAR_RAMP_I_ATE_TONEGEN_LINRAMP_DWELL_SET(x)                 (((x) << 12) & 0x003ff000)
-#define PHY_ANALOG_TX_LINEAR_RAMP_I_ATE_TONEGEN_LINRAMP_STEP_MSB                                             29
-#define PHY_ANALOG_TX_LINEAR_RAMP_I_ATE_TONEGEN_LINRAMP_STEP_LSB                                             24
-#define PHY_ANALOG_TX_LINEAR_RAMP_I_ATE_TONEGEN_LINRAMP_STEP_MASK                                    0x3f000000
-#define PHY_ANALOG_TX_LINEAR_RAMP_I_ATE_TONEGEN_LINRAMP_STEP_GET(x)                  (((x) & 0x3f000000) >> 24)
-#define PHY_ANALOG_TX_LINEAR_RAMP_I_ATE_TONEGEN_LINRAMP_STEP_SET(x)                  (((x) << 24) & 0x3f000000)
-
-/* macros for tx_linear_ramp_q */
-#define PHY_ANALOG_TX_LINEAR_RAMP_Q_ADDRESS                                                          0x00000398
-#define PHY_ANALOG_TX_LINEAR_RAMP_Q_OFFSET                                                           0x00000398
-#define PHY_ANALOG_TX_LINEAR_RAMP_Q_ATE_TONEGEN_LINRAMP_INIT_MSB                                             10
-#define PHY_ANALOG_TX_LINEAR_RAMP_Q_ATE_TONEGEN_LINRAMP_INIT_LSB                                              0
-#define PHY_ANALOG_TX_LINEAR_RAMP_Q_ATE_TONEGEN_LINRAMP_INIT_MASK                                    0x000007ff
-#define PHY_ANALOG_TX_LINEAR_RAMP_Q_ATE_TONEGEN_LINRAMP_INIT_GET(x)                   (((x) & 0x000007ff) >> 0)
-#define PHY_ANALOG_TX_LINEAR_RAMP_Q_ATE_TONEGEN_LINRAMP_INIT_SET(x)                   (((x) << 0) & 0x000007ff)
-#define PHY_ANALOG_TX_LINEAR_RAMP_Q_ATE_TONEGEN_LINRAMP_DWELL_MSB                                            21
-#define PHY_ANALOG_TX_LINEAR_RAMP_Q_ATE_TONEGEN_LINRAMP_DWELL_LSB                                            12
-#define PHY_ANALOG_TX_LINEAR_RAMP_Q_ATE_TONEGEN_LINRAMP_DWELL_MASK                                   0x003ff000
-#define PHY_ANALOG_TX_LINEAR_RAMP_Q_ATE_TONEGEN_LINRAMP_DWELL_GET(x)                 (((x) & 0x003ff000) >> 12)
-#define PHY_ANALOG_TX_LINEAR_RAMP_Q_ATE_TONEGEN_LINRAMP_DWELL_SET(x)                 (((x) << 12) & 0x003ff000)
-#define PHY_ANALOG_TX_LINEAR_RAMP_Q_ATE_TONEGEN_LINRAMP_STEP_MSB                                             29
-#define PHY_ANALOG_TX_LINEAR_RAMP_Q_ATE_TONEGEN_LINRAMP_STEP_LSB                                             24
-#define PHY_ANALOG_TX_LINEAR_RAMP_Q_ATE_TONEGEN_LINRAMP_STEP_MASK                                    0x3f000000
-#define PHY_ANALOG_TX_LINEAR_RAMP_Q_ATE_TONEGEN_LINRAMP_STEP_GET(x)                  (((x) & 0x3f000000) >> 24)
-#define PHY_ANALOG_TX_LINEAR_RAMP_Q_ATE_TONEGEN_LINRAMP_STEP_SET(x)                  (((x) << 24) & 0x3f000000)
-
-/* macros for tx_prbs_mag */
-#define PHY_ANALOG_TX_PRBS_MAG_ADDRESS                                                               0x0000039c
-#define PHY_ANALOG_TX_PRBS_MAG_OFFSET                                                                0x0000039c
-#define PHY_ANALOG_TX_PRBS_MAG_ATE_TONEGEN_PRBS_MAGNITUDE_I_MSB                                               9
-#define PHY_ANALOG_TX_PRBS_MAG_ATE_TONEGEN_PRBS_MAGNITUDE_I_LSB                                               0
-#define PHY_ANALOG_TX_PRBS_MAG_ATE_TONEGEN_PRBS_MAGNITUDE_I_MASK                                     0x000003ff
-#define PHY_ANALOG_TX_PRBS_MAG_ATE_TONEGEN_PRBS_MAGNITUDE_I_GET(x)                    (((x) & 0x000003ff) >> 0)
-#define PHY_ANALOG_TX_PRBS_MAG_ATE_TONEGEN_PRBS_MAGNITUDE_I_SET(x)                    (((x) << 0) & 0x000003ff)
-#define PHY_ANALOG_TX_PRBS_MAG_ATE_TONEGEN_PRBS_MAGNITUDE_Q_MSB                                              25
-#define PHY_ANALOG_TX_PRBS_MAG_ATE_TONEGEN_PRBS_MAGNITUDE_Q_LSB                                              16
-#define PHY_ANALOG_TX_PRBS_MAG_ATE_TONEGEN_PRBS_MAGNITUDE_Q_MASK                                     0x03ff0000
-#define PHY_ANALOG_TX_PRBS_MAG_ATE_TONEGEN_PRBS_MAGNITUDE_Q_GET(x)                   (((x) & 0x03ff0000) >> 16)
-#define PHY_ANALOG_TX_PRBS_MAG_ATE_TONEGEN_PRBS_MAGNITUDE_Q_SET(x)                   (((x) << 16) & 0x03ff0000)
-
-/* macros for tx_prbs_seed_i */
-#define PHY_ANALOG_TX_PRBS_SEED_I_ADDRESS                                                            0x000003a0
-#define PHY_ANALOG_TX_PRBS_SEED_I_OFFSET                                                             0x000003a0
-#define PHY_ANALOG_TX_PRBS_SEED_I_ATE_TONEGEN_PRBS_SEED_MSB                                                  30
-#define PHY_ANALOG_TX_PRBS_SEED_I_ATE_TONEGEN_PRBS_SEED_LSB                                                   0
-#define PHY_ANALOG_TX_PRBS_SEED_I_ATE_TONEGEN_PRBS_SEED_MASK                                         0x7fffffff
-#define PHY_ANALOG_TX_PRBS_SEED_I_ATE_TONEGEN_PRBS_SEED_GET(x)                        (((x) & 0x7fffffff) >> 0)
-#define PHY_ANALOG_TX_PRBS_SEED_I_ATE_TONEGEN_PRBS_SEED_SET(x)                        (((x) << 0) & 0x7fffffff)
-
-/* macros for tx_prbs_seed_q */
-#define PHY_ANALOG_TX_PRBS_SEED_Q_ADDRESS                                                            0x000003a4
-#define PHY_ANALOG_TX_PRBS_SEED_Q_OFFSET                                                             0x000003a4
-#define PHY_ANALOG_TX_PRBS_SEED_Q_ATE_TONEGEN_PRBS_SEED_MSB                                                  30
-#define PHY_ANALOG_TX_PRBS_SEED_Q_ATE_TONEGEN_PRBS_SEED_LSB                                                   0
-#define PHY_ANALOG_TX_PRBS_SEED_Q_ATE_TONEGEN_PRBS_SEED_MASK                                         0x7fffffff
-#define PHY_ANALOG_TX_PRBS_SEED_Q_ATE_TONEGEN_PRBS_SEED_GET(x)                        (((x) & 0x7fffffff) >> 0)
-#define PHY_ANALOG_TX_PRBS_SEED_Q_ATE_TONEGEN_PRBS_SEED_SET(x)                        (((x) << 0) & 0x7fffffff)
-
-/* macros for cmac_dc_cancel */
-#define PHY_ANALOG_CMAC_DC_CANCEL_ADDRESS                                                            0x000003a8
-#define PHY_ANALOG_CMAC_DC_CANCEL_OFFSET                                                             0x000003a8
-#define PHY_ANALOG_CMAC_DC_CANCEL_ATE_CMAC_DC_CANCEL_I_MSB                                                    9
-#define PHY_ANALOG_CMAC_DC_CANCEL_ATE_CMAC_DC_CANCEL_I_LSB                                                    0
-#define PHY_ANALOG_CMAC_DC_CANCEL_ATE_CMAC_DC_CANCEL_I_MASK                                          0x000003ff
-#define PHY_ANALOG_CMAC_DC_CANCEL_ATE_CMAC_DC_CANCEL_I_GET(x)                         (((x) & 0x000003ff) >> 0)
-#define PHY_ANALOG_CMAC_DC_CANCEL_ATE_CMAC_DC_CANCEL_I_SET(x)                         (((x) << 0) & 0x000003ff)
-#define PHY_ANALOG_CMAC_DC_CANCEL_ATE_CMAC_DC_CANCEL_Q_MSB                                                   25
-#define PHY_ANALOG_CMAC_DC_CANCEL_ATE_CMAC_DC_CANCEL_Q_LSB                                                   16
-#define PHY_ANALOG_CMAC_DC_CANCEL_ATE_CMAC_DC_CANCEL_Q_MASK                                          0x03ff0000
-#define PHY_ANALOG_CMAC_DC_CANCEL_ATE_CMAC_DC_CANCEL_Q_GET(x)                        (((x) & 0x03ff0000) >> 16)
-#define PHY_ANALOG_CMAC_DC_CANCEL_ATE_CMAC_DC_CANCEL_Q_SET(x)                        (((x) << 16) & 0x03ff0000)
-
-/* macros for cmac_dc_offset */
-#define PHY_ANALOG_CMAC_DC_OFFSET_ADDRESS                                                            0x000003ac
-#define PHY_ANALOG_CMAC_DC_OFFSET_OFFSET                                                             0x000003ac
-#define PHY_ANALOG_CMAC_DC_OFFSET_ATE_CMAC_DC_CYCLES_MSB                                                      3
-#define PHY_ANALOG_CMAC_DC_OFFSET_ATE_CMAC_DC_CYCLES_LSB                                                      0
-#define PHY_ANALOG_CMAC_DC_OFFSET_ATE_CMAC_DC_CYCLES_MASK                                            0x0000000f
-#define PHY_ANALOG_CMAC_DC_OFFSET_ATE_CMAC_DC_CYCLES_GET(x)                           (((x) & 0x0000000f) >> 0)
-#define PHY_ANALOG_CMAC_DC_OFFSET_ATE_CMAC_DC_CYCLES_SET(x)                           (((x) << 0) & 0x0000000f)
-
-/* macros for cmac_corr */
-#define PHY_ANALOG_CMAC_CORR_ADDRESS                                                                 0x000003b0
-#define PHY_ANALOG_CMAC_CORR_OFFSET                                                                  0x000003b0
-#define PHY_ANALOG_CMAC_CORR_ATE_CMAC_CORR_CYCLES_MSB                                                         4
-#define PHY_ANALOG_CMAC_CORR_ATE_CMAC_CORR_CYCLES_LSB                                                         0
-#define PHY_ANALOG_CMAC_CORR_ATE_CMAC_CORR_CYCLES_MASK                                               0x0000001f
-#define PHY_ANALOG_CMAC_CORR_ATE_CMAC_CORR_CYCLES_GET(x)                              (((x) & 0x0000001f) >> 0)
-#define PHY_ANALOG_CMAC_CORR_ATE_CMAC_CORR_CYCLES_SET(x)                              (((x) << 0) & 0x0000001f)
-#define PHY_ANALOG_CMAC_CORR_ATE_CMAC_CORR_FREQ_MSB                                                          13
-#define PHY_ANALOG_CMAC_CORR_ATE_CMAC_CORR_FREQ_LSB                                                           8
-#define PHY_ANALOG_CMAC_CORR_ATE_CMAC_CORR_FREQ_MASK                                                 0x00003f00
-#define PHY_ANALOG_CMAC_CORR_ATE_CMAC_CORR_FREQ_GET(x)                                (((x) & 0x00003f00) >> 8)
-#define PHY_ANALOG_CMAC_CORR_ATE_CMAC_CORR_FREQ_SET(x)                                (((x) << 8) & 0x00003f00)
-
-/* macros for cmac_power */
-#define PHY_ANALOG_CMAC_POWER_ADDRESS                                                                0x000003b4
-#define PHY_ANALOG_CMAC_POWER_OFFSET                                                                 0x000003b4
-#define PHY_ANALOG_CMAC_POWER_ATE_CMAC_POWER_CYCLES_MSB                                                       3
-#define PHY_ANALOG_CMAC_POWER_ATE_CMAC_POWER_CYCLES_LSB                                                       0
-#define PHY_ANALOG_CMAC_POWER_ATE_CMAC_POWER_CYCLES_MASK                                             0x0000000f
-#define PHY_ANALOG_CMAC_POWER_ATE_CMAC_POWER_CYCLES_GET(x)                            (((x) & 0x0000000f) >> 0)
-#define PHY_ANALOG_CMAC_POWER_ATE_CMAC_POWER_CYCLES_SET(x)                            (((x) << 0) & 0x0000000f)
-
-/* macros for cmac_cross_corr */
-#define PHY_ANALOG_CMAC_CROSS_CORR_ADDRESS                                                           0x000003b8
-#define PHY_ANALOG_CMAC_CROSS_CORR_OFFSET                                                            0x000003b8
-#define PHY_ANALOG_CMAC_CROSS_CORR_ATE_CMAC_IQ_CYCLES_MSB                                                     3
-#define PHY_ANALOG_CMAC_CROSS_CORR_ATE_CMAC_IQ_CYCLES_LSB                                                     0
-#define PHY_ANALOG_CMAC_CROSS_CORR_ATE_CMAC_IQ_CYCLES_MASK                                           0x0000000f
-#define PHY_ANALOG_CMAC_CROSS_CORR_ATE_CMAC_IQ_CYCLES_GET(x)                          (((x) & 0x0000000f) >> 0)
-#define PHY_ANALOG_CMAC_CROSS_CORR_ATE_CMAC_IQ_CYCLES_SET(x)                          (((x) << 0) & 0x0000000f)
-
-/* macros for cmac_i2q2 */
-#define PHY_ANALOG_CMAC_I2Q2_ADDRESS                                                                 0x000003bc
-#define PHY_ANALOG_CMAC_I2Q2_OFFSET                                                                  0x000003bc
-#define PHY_ANALOG_CMAC_I2Q2_ATE_CMAC_I2Q2_CYCLES_MSB                                                         3
-#define PHY_ANALOG_CMAC_I2Q2_ATE_CMAC_I2Q2_CYCLES_LSB                                                         0
-#define PHY_ANALOG_CMAC_I2Q2_ATE_CMAC_I2Q2_CYCLES_MASK                                               0x0000000f
-#define PHY_ANALOG_CMAC_I2Q2_ATE_CMAC_I2Q2_CYCLES_GET(x)                              (((x) & 0x0000000f) >> 0)
-#define PHY_ANALOG_CMAC_I2Q2_ATE_CMAC_I2Q2_CYCLES_SET(x)                              (((x) << 0) & 0x0000000f)
-
-/* macros for cmac_power_hpf */
-#define PHY_ANALOG_CMAC_POWER_HPF_ADDRESS                                                            0x000003c0
-#define PHY_ANALOG_CMAC_POWER_HPF_OFFSET                                                             0x000003c0
-#define PHY_ANALOG_CMAC_POWER_HPF_ATE_CMAC_POWER_HPF_CYCLES_MSB                                               3
-#define PHY_ANALOG_CMAC_POWER_HPF_ATE_CMAC_POWER_HPF_CYCLES_LSB                                               0
-#define PHY_ANALOG_CMAC_POWER_HPF_ATE_CMAC_POWER_HPF_CYCLES_MASK                                     0x0000000f
-#define PHY_ANALOG_CMAC_POWER_HPF_ATE_CMAC_POWER_HPF_CYCLES_GET(x)                    (((x) & 0x0000000f) >> 0)
-#define PHY_ANALOG_CMAC_POWER_HPF_ATE_CMAC_POWER_HPF_CYCLES_SET(x)                    (((x) << 0) & 0x0000000f)
-#define PHY_ANALOG_CMAC_POWER_HPF_ATE_CMAC_POWER_HPF_WAIT_MSB                                                 7
-#define PHY_ANALOG_CMAC_POWER_HPF_ATE_CMAC_POWER_HPF_WAIT_LSB                                                 4
-#define PHY_ANALOG_CMAC_POWER_HPF_ATE_CMAC_POWER_HPF_WAIT_MASK                                       0x000000f0
-#define PHY_ANALOG_CMAC_POWER_HPF_ATE_CMAC_POWER_HPF_WAIT_GET(x)                      (((x) & 0x000000f0) >> 4)
-#define PHY_ANALOG_CMAC_POWER_HPF_ATE_CMAC_POWER_HPF_WAIT_SET(x)                      (((x) << 4) & 0x000000f0)
-
-/* macros for rxdac_set1 */
-#define PHY_ANALOG_RXDAC_SET1_ADDRESS                                                                0x000003c4
-#define PHY_ANALOG_RXDAC_SET1_OFFSET                                                                 0x000003c4
-#define PHY_ANALOG_RXDAC_SET1_ATE_RXDAC_MUX_MSB                                                               1
-#define PHY_ANALOG_RXDAC_SET1_ATE_RXDAC_MUX_LSB                                                               0
-#define PHY_ANALOG_RXDAC_SET1_ATE_RXDAC_MUX_MASK                                                     0x00000003
-#define PHY_ANALOG_RXDAC_SET1_ATE_RXDAC_MUX_GET(x)                                    (((x) & 0x00000003) >> 0)
-#define PHY_ANALOG_RXDAC_SET1_ATE_RXDAC_MUX_SET(x)                                    (((x) << 0) & 0x00000003)
-#define PHY_ANALOG_RXDAC_SET1_ATE_RXDAC_HI_GAIN_MSB                                                           4
-#define PHY_ANALOG_RXDAC_SET1_ATE_RXDAC_HI_GAIN_LSB                                                           4
-#define PHY_ANALOG_RXDAC_SET1_ATE_RXDAC_HI_GAIN_MASK                                                 0x00000010
-#define PHY_ANALOG_RXDAC_SET1_ATE_RXDAC_HI_GAIN_GET(x)                                (((x) & 0x00000010) >> 4)
-#define PHY_ANALOG_RXDAC_SET1_ATE_RXDAC_HI_GAIN_SET(x)                                (((x) << 4) & 0x00000010)
-#define PHY_ANALOG_RXDAC_SET1_ATE_RXDAC_CAL_WAIT_MSB                                                         13
-#define PHY_ANALOG_RXDAC_SET1_ATE_RXDAC_CAL_WAIT_LSB                                                          8
-#define PHY_ANALOG_RXDAC_SET1_ATE_RXDAC_CAL_WAIT_MASK                                                0x00003f00
-#define PHY_ANALOG_RXDAC_SET1_ATE_RXDAC_CAL_WAIT_GET(x)                               (((x) & 0x00003f00) >> 8)
-#define PHY_ANALOG_RXDAC_SET1_ATE_RXDAC_CAL_WAIT_SET(x)                               (((x) << 8) & 0x00003f00)
-#define PHY_ANALOG_RXDAC_SET1_ATE_RXDAC_CAL_MEASURE_TIME_MSB                                                 19
-#define PHY_ANALOG_RXDAC_SET1_ATE_RXDAC_CAL_MEASURE_TIME_LSB                                                 16
-#define PHY_ANALOG_RXDAC_SET1_ATE_RXDAC_CAL_MEASURE_TIME_MASK                                        0x000f0000
-#define PHY_ANALOG_RXDAC_SET1_ATE_RXDAC_CAL_MEASURE_TIME_GET(x)                      (((x) & 0x000f0000) >> 16)
-#define PHY_ANALOG_RXDAC_SET1_ATE_RXDAC_CAL_MEASURE_TIME_SET(x)                      (((x) << 16) & 0x000f0000)
-
-/* macros for rxdac_set2 */
-#define PHY_ANALOG_RXDAC_SET2_ADDRESS                                                                0x000003c8
-#define PHY_ANALOG_RXDAC_SET2_OFFSET                                                                 0x000003c8
-#define PHY_ANALOG_RXDAC_SET2_ATE_RXDAC_I_HI_MSB                                                              4
-#define PHY_ANALOG_RXDAC_SET2_ATE_RXDAC_I_HI_LSB                                                              0
-#define PHY_ANALOG_RXDAC_SET2_ATE_RXDAC_I_HI_MASK                                                    0x0000001f
-#define PHY_ANALOG_RXDAC_SET2_ATE_RXDAC_I_HI_GET(x)                                   (((x) & 0x0000001f) >> 0)
-#define PHY_ANALOG_RXDAC_SET2_ATE_RXDAC_I_HI_SET(x)                                   (((x) << 0) & 0x0000001f)
-#define PHY_ANALOG_RXDAC_SET2_ATE_RXDAC_Q_HI_MSB                                                             12
-#define PHY_ANALOG_RXDAC_SET2_ATE_RXDAC_Q_HI_LSB                                                              8
-#define PHY_ANALOG_RXDAC_SET2_ATE_RXDAC_Q_HI_MASK                                                    0x00001f00
-#define PHY_ANALOG_RXDAC_SET2_ATE_RXDAC_Q_HI_GET(x)                                   (((x) & 0x00001f00) >> 8)
-#define PHY_ANALOG_RXDAC_SET2_ATE_RXDAC_Q_HI_SET(x)                                   (((x) << 8) & 0x00001f00)
-#define PHY_ANALOG_RXDAC_SET2_ATE_RXDAC_I_LOW_MSB                                                            20
-#define PHY_ANALOG_RXDAC_SET2_ATE_RXDAC_I_LOW_LSB                                                            16
-#define PHY_ANALOG_RXDAC_SET2_ATE_RXDAC_I_LOW_MASK                                                   0x001f0000
-#define PHY_ANALOG_RXDAC_SET2_ATE_RXDAC_I_LOW_GET(x)                                 (((x) & 0x001f0000) >> 16)
-#define PHY_ANALOG_RXDAC_SET2_ATE_RXDAC_I_LOW_SET(x)                                 (((x) << 16) & 0x001f0000)
-#define PHY_ANALOG_RXDAC_SET2_ATE_RXDAC_Q_LOW_MSB                                                            28
-#define PHY_ANALOG_RXDAC_SET2_ATE_RXDAC_Q_LOW_LSB                                                            24
-#define PHY_ANALOG_RXDAC_SET2_ATE_RXDAC_Q_LOW_MASK                                                   0x1f000000
-#define PHY_ANALOG_RXDAC_SET2_ATE_RXDAC_Q_LOW_GET(x)                                 (((x) & 0x1f000000) >> 24)
-#define PHY_ANALOG_RXDAC_SET2_ATE_RXDAC_Q_LOW_SET(x)                                 (((x) << 24) & 0x1f000000)
-
-/* macros for rxdac_long_shift */
-#define PHY_ANALOG_RXDAC_LONG_SHIFT_ADDRESS                                                          0x000003cc
-#define PHY_ANALOG_RXDAC_LONG_SHIFT_OFFSET                                                           0x000003cc
-#define PHY_ANALOG_RXDAC_LONG_SHIFT_ATE_RXDAC_I_STATIC_MSB                                                    4
-#define PHY_ANALOG_RXDAC_LONG_SHIFT_ATE_RXDAC_I_STATIC_LSB                                                    0
-#define PHY_ANALOG_RXDAC_LONG_SHIFT_ATE_RXDAC_I_STATIC_MASK                                          0x0000001f
-#define PHY_ANALOG_RXDAC_LONG_SHIFT_ATE_RXDAC_I_STATIC_GET(x)                         (((x) & 0x0000001f) >> 0)
-#define PHY_ANALOG_RXDAC_LONG_SHIFT_ATE_RXDAC_I_STATIC_SET(x)                         (((x) << 0) & 0x0000001f)
-#define PHY_ANALOG_RXDAC_LONG_SHIFT_ATE_RXDAC_Q_STATIC_MSB                                                   12
-#define PHY_ANALOG_RXDAC_LONG_SHIFT_ATE_RXDAC_Q_STATIC_LSB                                                    8
-#define PHY_ANALOG_RXDAC_LONG_SHIFT_ATE_RXDAC_Q_STATIC_MASK                                          0x00001f00
-#define PHY_ANALOG_RXDAC_LONG_SHIFT_ATE_RXDAC_Q_STATIC_GET(x)                         (((x) & 0x00001f00) >> 8)
-#define PHY_ANALOG_RXDAC_LONG_SHIFT_ATE_RXDAC_Q_STATIC_SET(x)                         (((x) << 8) & 0x00001f00)
-
-/* macros for cmac_results_i */
-#define PHY_ANALOG_CMAC_RESULTS_I_ADDRESS                                                            0x000003d0
-#define PHY_ANALOG_CMAC_RESULTS_I_OFFSET                                                             0x000003d0
-#define PHY_ANALOG_CMAC_RESULTS_I_ATE_CMAC_RESULTS_MSB                                                       31
-#define PHY_ANALOG_CMAC_RESULTS_I_ATE_CMAC_RESULTS_LSB                                                        0
-#define PHY_ANALOG_CMAC_RESULTS_I_ATE_CMAC_RESULTS_MASK                                              0xffffffff
-#define PHY_ANALOG_CMAC_RESULTS_I_ATE_CMAC_RESULTS_GET(x)                             (((x) & 0xffffffff) >> 0)
-#define PHY_ANALOG_CMAC_RESULTS_I_ATE_CMAC_RESULTS_SET(x)                             (((x) << 0) & 0xffffffff)
-
-/* macros for cmac_results_q */
-#define PHY_ANALOG_CMAC_RESULTS_Q_ADDRESS                                                            0x000003d4
-#define PHY_ANALOG_CMAC_RESULTS_Q_OFFSET                                                             0x000003d4
-#define PHY_ANALOG_CMAC_RESULTS_Q_ATE_CMAC_RESULTS_MSB                                                       31
-#define PHY_ANALOG_CMAC_RESULTS_Q_ATE_CMAC_RESULTS_LSB                                                        0
-#define PHY_ANALOG_CMAC_RESULTS_Q_ATE_CMAC_RESULTS_MASK                                              0xffffffff
-#define PHY_ANALOG_CMAC_RESULTS_Q_ATE_CMAC_RESULTS_GET(x)                             (((x) & 0xffffffff) >> 0)
-#define PHY_ANALOG_CMAC_RESULTS_Q_ATE_CMAC_RESULTS_SET(x)                             (((x) << 0) & 0xffffffff)
-
-/* macros for PMU1 */
-#define PHY_ANALOG_PMU1_ADDRESS                                                                      0x00000740
-#define PHY_ANALOG_PMU1_OFFSET                                                                       0x00000740
-#define PHY_ANALOG_PMU1_SPARE_MSB                                                                            10
-#define PHY_ANALOG_PMU1_SPARE_LSB                                                                             0
-#define PHY_ANALOG_PMU1_SPARE_MASK                                                                   0x000007ff
-#define PHY_ANALOG_PMU1_SPARE_GET(x)                                                  (((x) & 0x000007ff) >> 0)
-#define PHY_ANALOG_PMU1_SPARE_SET(x)                                                  (((x) << 0) & 0x000007ff)
-#define PHY_ANALOG_PMU1_OTP_V25_PWD_MSB                                                                      11
-#define PHY_ANALOG_PMU1_OTP_V25_PWD_LSB                                                                      11
-#define PHY_ANALOG_PMU1_OTP_V25_PWD_MASK                                                             0x00000800
-#define PHY_ANALOG_PMU1_OTP_V25_PWD_GET(x)                                           (((x) & 0x00000800) >> 11)
-#define PHY_ANALOG_PMU1_OTP_V25_PWD_SET(x)                                           (((x) << 11) & 0x00000800)
-#define PHY_ANALOG_PMU1_PAREGON_MAN_MSB                                                                      12
-#define PHY_ANALOG_PMU1_PAREGON_MAN_LSB                                                                      12
-#define PHY_ANALOG_PMU1_PAREGON_MAN_MASK                                                             0x00001000
-#define PHY_ANALOG_PMU1_PAREGON_MAN_GET(x)                                           (((x) & 0x00001000) >> 12)
-#define PHY_ANALOG_PMU1_PAREGON_MAN_SET(x)                                           (((x) << 12) & 0x00001000)
-#define PHY_ANALOG_PMU1_OTPREGON_MAN_MSB                                                                     13
-#define PHY_ANALOG_PMU1_OTPREGON_MAN_LSB                                                                     13
-#define PHY_ANALOG_PMU1_OTPREGON_MAN_MASK                                                            0x00002000
-#define PHY_ANALOG_PMU1_OTPREGON_MAN_GET(x)                                          (((x) & 0x00002000) >> 13)
-#define PHY_ANALOG_PMU1_OTPREGON_MAN_SET(x)                                          (((x) << 13) & 0x00002000)
-#define PHY_ANALOG_PMU1_DREGON_MAN_MSB                                                                       14
-#define PHY_ANALOG_PMU1_DREGON_MAN_LSB                                                                       14
-#define PHY_ANALOG_PMU1_DREGON_MAN_MASK                                                              0x00004000
-#define PHY_ANALOG_PMU1_DREGON_MAN_GET(x)                                            (((x) & 0x00004000) >> 14)
-#define PHY_ANALOG_PMU1_DREGON_MAN_SET(x)                                            (((x) << 14) & 0x00004000)
-#define PHY_ANALOG_PMU1_DISCONTMODEEN_MSB                                                                    15
-#define PHY_ANALOG_PMU1_DISCONTMODEEN_LSB                                                                    15
-#define PHY_ANALOG_PMU1_DISCONTMODEEN_MASK                                                           0x00008000
-#define PHY_ANALOG_PMU1_DISCONTMODEEN_GET(x)                                         (((x) & 0x00008000) >> 15)
-#define PHY_ANALOG_PMU1_DISCONTMODEEN_SET(x)                                         (((x) << 15) & 0x00008000)
-#define PHY_ANALOG_PMU1_SWREGON_MAN_MSB                                                                      16
-#define PHY_ANALOG_PMU1_SWREGON_MAN_LSB                                                                      16
-#define PHY_ANALOG_PMU1_SWREGON_MAN_MASK                                                             0x00010000
-#define PHY_ANALOG_PMU1_SWREGON_MAN_GET(x)                                           (((x) & 0x00010000) >> 16)
-#define PHY_ANALOG_PMU1_SWREGON_MAN_SET(x)                                           (((x) << 16) & 0x00010000)
-#define PHY_ANALOG_PMU1_SWREG_FREQCUR_MSB                                                                    18
-#define PHY_ANALOG_PMU1_SWREG_FREQCUR_LSB                                                                    17
-#define PHY_ANALOG_PMU1_SWREG_FREQCUR_MASK                                                           0x00060000
-#define PHY_ANALOG_PMU1_SWREG_FREQCUR_GET(x)                                         (((x) & 0x00060000) >> 17)
-#define PHY_ANALOG_PMU1_SWREG_FREQCUR_SET(x)                                         (((x) << 17) & 0x00060000)
-#define PHY_ANALOG_PMU1_SWREG_FREQCAP_MSB                                                                    21
-#define PHY_ANALOG_PMU1_SWREG_FREQCAP_LSB                                                                    19
-#define PHY_ANALOG_PMU1_SWREG_FREQCAP_MASK                                                           0x00380000
-#define PHY_ANALOG_PMU1_SWREG_FREQCAP_GET(x)                                         (((x) & 0x00380000) >> 19)
-#define PHY_ANALOG_PMU1_SWREG_FREQCAP_SET(x)                                         (((x) << 19) & 0x00380000)
-#define PHY_ANALOG_PMU1_SWREG_LVLCTR_MSB                                                                     23
-#define PHY_ANALOG_PMU1_SWREG_LVLCTR_LSB                                                                     22
-#define PHY_ANALOG_PMU1_SWREG_LVLCTR_MASK                                                            0x00c00000
-#define PHY_ANALOG_PMU1_SWREG_LVLCTR_GET(x)                                          (((x) & 0x00c00000) >> 22)
-#define PHY_ANALOG_PMU1_SWREG_LVLCTR_SET(x)                                          (((x) << 22) & 0x00c00000)
-#define PHY_ANALOG_PMU1_SREG_LVLCTR_MSB                                                                      25
-#define PHY_ANALOG_PMU1_SREG_LVLCTR_LSB                                                                      24
-#define PHY_ANALOG_PMU1_SREG_LVLCTR_MASK                                                             0x03000000
-#define PHY_ANALOG_PMU1_SREG_LVLCTR_GET(x)                                           (((x) & 0x03000000) >> 24)
-#define PHY_ANALOG_PMU1_SREG_LVLCTR_SET(x)                                           (((x) << 24) & 0x03000000)
-#define PHY_ANALOG_PMU1_DREG_LVLCTR_MSB                                                                      27
-#define PHY_ANALOG_PMU1_DREG_LVLCTR_LSB                                                                      26
-#define PHY_ANALOG_PMU1_DREG_LVLCTR_MASK                                                             0x0c000000
-#define PHY_ANALOG_PMU1_DREG_LVLCTR_GET(x)                                           (((x) & 0x0c000000) >> 26)
-#define PHY_ANALOG_PMU1_DREG_LVLCTR_SET(x)                                           (((x) << 26) & 0x0c000000)
-#define PHY_ANALOG_PMU1_PAREG_XPNP_MSB                                                                       28
-#define PHY_ANALOG_PMU1_PAREG_XPNP_LSB                                                                       28
-#define PHY_ANALOG_PMU1_PAREG_XPNP_MASK                                                              0x10000000
-#define PHY_ANALOG_PMU1_PAREG_XPNP_GET(x)                                            (((x) & 0x10000000) >> 28)
-#define PHY_ANALOG_PMU1_PAREG_XPNP_SET(x)                                            (((x) << 28) & 0x10000000)
-#define PHY_ANALOG_PMU1_PAREG_LVLCTR_MSB                                                                     31
-#define PHY_ANALOG_PMU1_PAREG_LVLCTR_LSB                                                                     29
-#define PHY_ANALOG_PMU1_PAREG_LVLCTR_MASK                                                            0xe0000000
-#define PHY_ANALOG_PMU1_PAREG_LVLCTR_GET(x)                                          (((x) & 0xe0000000) >> 29)
-#define PHY_ANALOG_PMU1_PAREG_LVLCTR_SET(x)                                          (((x) << 29) & 0xe0000000)
-
-/* macros for PMU2 */
-#define PHY_ANALOG_PMU2_ADDRESS                                                                      0x00000744
-#define PHY_ANALOG_PMU2_OFFSET                                                                       0x00000744
-#define PHY_ANALOG_PMU2_SPARE_MSB                                                                             7
-#define PHY_ANALOG_PMU2_SPARE_LSB                                                                             0
-#define PHY_ANALOG_PMU2_SPARE_MASK                                                                   0x000000ff
-#define PHY_ANALOG_PMU2_SPARE_GET(x)                                                  (((x) & 0x000000ff) >> 0)
-#define PHY_ANALOG_PMU2_SPARE_SET(x)                                                  (((x) << 0) & 0x000000ff)
-#define PHY_ANALOG_PMU2_VBATT_1_3TOATB_MSB                                                                    8
-#define PHY_ANALOG_PMU2_VBATT_1_3TOATB_LSB                                                                    8
-#define PHY_ANALOG_PMU2_VBATT_1_3TOATB_MASK                                                          0x00000100
-#define PHY_ANALOG_PMU2_VBATT_1_3TOATB_GET(x)                                         (((x) & 0x00000100) >> 8)
-#define PHY_ANALOG_PMU2_VBATT_1_3TOATB_SET(x)                                         (((x) << 8) & 0x00000100)
-#define PHY_ANALOG_PMU2_VBATT_1_2TOATB_MSB                                                                    9
-#define PHY_ANALOG_PMU2_VBATT_1_2TOATB_LSB                                                                    9
-#define PHY_ANALOG_PMU2_VBATT_1_2TOATB_MASK                                                          0x00000200
-#define PHY_ANALOG_PMU2_VBATT_1_2TOATB_GET(x)                                         (((x) & 0x00000200) >> 9)
-#define PHY_ANALOG_PMU2_VBATT_1_2TOATB_SET(x)                                         (((x) << 9) & 0x00000200)
-#define PHY_ANALOG_PMU2_VBATT_2_3TOATB_MSB                                                                   10
-#define PHY_ANALOG_PMU2_VBATT_2_3TOATB_LSB                                                                   10
-#define PHY_ANALOG_PMU2_VBATT_2_3TOATB_MASK                                                          0x00000400
-#define PHY_ANALOG_PMU2_VBATT_2_3TOATB_GET(x)                                        (((x) & 0x00000400) >> 10)
-#define PHY_ANALOG_PMU2_VBATT_2_3TOATB_SET(x)                                        (((x) << 10) & 0x00000400)
-#define PHY_ANALOG_PMU2_PWD_BANDGAP_MAN_MSB                                                                  11
-#define PHY_ANALOG_PMU2_PWD_BANDGAP_MAN_LSB                                                                  11
-#define PHY_ANALOG_PMU2_PWD_BANDGAP_MAN_MASK                                                         0x00000800
-#define PHY_ANALOG_PMU2_PWD_BANDGAP_MAN_GET(x)                                       (((x) & 0x00000800) >> 11)
-#define PHY_ANALOG_PMU2_PWD_BANDGAP_MAN_SET(x)                                       (((x) << 11) & 0x00000800)
-#define PHY_ANALOG_PMU2_PWD_LFO_MAN_MSB                                                                      12
-#define PHY_ANALOG_PMU2_PWD_LFO_MAN_LSB                                                                      12
-#define PHY_ANALOG_PMU2_PWD_LFO_MAN_MASK                                                             0x00001000
-#define PHY_ANALOG_PMU2_PWD_LFO_MAN_GET(x)                                           (((x) & 0x00001000) >> 12)
-#define PHY_ANALOG_PMU2_PWD_LFO_MAN_SET(x)                                           (((x) << 12) & 0x00001000)
-#define PHY_ANALOG_PMU2_VBATT_LT_3P2_MSB                                                                     13
-#define PHY_ANALOG_PMU2_VBATT_LT_3P2_LSB                                                                     13
-#define PHY_ANALOG_PMU2_VBATT_LT_3P2_MASK                                                            0x00002000
-#define PHY_ANALOG_PMU2_VBATT_LT_3P2_GET(x)                                          (((x) & 0x00002000) >> 13)
-#define PHY_ANALOG_PMU2_VBATT_LT_3P2_SET(x)                                          (((x) << 13) & 0x00002000)
-#define PHY_ANALOG_PMU2_VBATT_LT_2P8_MSB                                                                     14
-#define PHY_ANALOG_PMU2_VBATT_LT_2P8_LSB                                                                     14
-#define PHY_ANALOG_PMU2_VBATT_LT_2P8_MASK                                                            0x00004000
-#define PHY_ANALOG_PMU2_VBATT_LT_2P8_GET(x)                                          (((x) & 0x00004000) >> 14)
-#define PHY_ANALOG_PMU2_VBATT_LT_2P8_SET(x)                                          (((x) << 14) & 0x00004000)
-#define PHY_ANALOG_PMU2_VBATT_GT_4P2_MSB                                                                     15
-#define PHY_ANALOG_PMU2_VBATT_GT_4P2_LSB                                                                     15
-#define PHY_ANALOG_PMU2_VBATT_GT_4P2_MASK                                                            0x00008000
-#define PHY_ANALOG_PMU2_VBATT_GT_4P2_GET(x)                                          (((x) & 0x00008000) >> 15)
-#define PHY_ANALOG_PMU2_VBATT_GT_4P2_SET(x)                                          (((x) << 15) & 0x00008000)
-#define PHY_ANALOG_PMU2_PMU_MAN_OVERRIDE_EN_MSB                                                              16
-#define PHY_ANALOG_PMU2_PMU_MAN_OVERRIDE_EN_LSB                                                              16
-#define PHY_ANALOG_PMU2_PMU_MAN_OVERRIDE_EN_MASK                                                     0x00010000
-#define PHY_ANALOG_PMU2_PMU_MAN_OVERRIDE_EN_GET(x)                                   (((x) & 0x00010000) >> 16)
-#define PHY_ANALOG_PMU2_PMU_MAN_OVERRIDE_EN_SET(x)                                   (((x) << 16) & 0x00010000)
-#define PHY_ANALOG_PMU2_VBATT_GT_LVLCTR_MSB                                                                  18
-#define PHY_ANALOG_PMU2_VBATT_GT_LVLCTR_LSB                                                                  17
-#define PHY_ANALOG_PMU2_VBATT_GT_LVLCTR_MASK                                                         0x00060000
-#define PHY_ANALOG_PMU2_VBATT_GT_LVLCTR_GET(x)                                       (((x) & 0x00060000) >> 17)
-#define PHY_ANALOG_PMU2_VBATT_GT_LVLCTR_SET(x)                                       (((x) << 17) & 0x00060000)
-#define PHY_ANALOG_PMU2_SWREGVSSL2ATB_MSB                                                                    19
-#define PHY_ANALOG_PMU2_SWREGVSSL2ATB_LSB                                                                    19
-#define PHY_ANALOG_PMU2_SWREGVSSL2ATB_MASK                                                           0x00080000
-#define PHY_ANALOG_PMU2_SWREGVSSL2ATB_GET(x)                                         (((x) & 0x00080000) >> 19)
-#define PHY_ANALOG_PMU2_SWREGVSSL2ATB_SET(x)                                         (((x) << 19) & 0x00080000)
-#define PHY_ANALOG_PMU2_SWREGVSSL_LVLCTR_MSB                                                                 21
-#define PHY_ANALOG_PMU2_SWREGVSSL_LVLCTR_LSB                                                                 20
-#define PHY_ANALOG_PMU2_SWREGVSSL_LVLCTR_MASK                                                        0x00300000
-#define PHY_ANALOG_PMU2_SWREGVSSL_LVLCTR_GET(x)                                      (((x) & 0x00300000) >> 20)
-#define PHY_ANALOG_PMU2_SWREGVSSL_LVLCTR_SET(x)                                      (((x) << 20) & 0x00300000)
-#define PHY_ANALOG_PMU2_SWREGVDDH2ATB_MSB                                                                    22
-#define PHY_ANALOG_PMU2_SWREGVDDH2ATB_LSB                                                                    22
-#define PHY_ANALOG_PMU2_SWREGVDDH2ATB_MASK                                                           0x00400000
-#define PHY_ANALOG_PMU2_SWREGVDDH2ATB_GET(x)                                         (((x) & 0x00400000) >> 22)
-#define PHY_ANALOG_PMU2_SWREGVDDH2ATB_SET(x)                                         (((x) << 22) & 0x00400000)
-#define PHY_ANALOG_PMU2_SWREGVDDH_LVLCTR_MSB                                                                 24
-#define PHY_ANALOG_PMU2_SWREGVDDH_LVLCTR_LSB                                                                 23
-#define PHY_ANALOG_PMU2_SWREGVDDH_LVLCTR_MASK                                                        0x01800000
-#define PHY_ANALOG_PMU2_SWREGVDDH_LVLCTR_GET(x)                                      (((x) & 0x01800000) >> 23)
-#define PHY_ANALOG_PMU2_SWREGVDDH_LVLCTR_SET(x)                                      (((x) << 23) & 0x01800000)
-#define PHY_ANALOG_PMU2_SWREG2ATB_MSB                                                                        27
-#define PHY_ANALOG_PMU2_SWREG2ATB_LSB                                                                        25
-#define PHY_ANALOG_PMU2_SWREG2ATB_MASK                                                               0x0e000000
-#define PHY_ANALOG_PMU2_SWREG2ATB_GET(x)                                             (((x) & 0x0e000000) >> 25)
-#define PHY_ANALOG_PMU2_SWREG2ATB_SET(x)                                             (((x) << 25) & 0x0e000000)
-#define PHY_ANALOG_PMU2_OTPREG2ATB_MSB                                                                       28
-#define PHY_ANALOG_PMU2_OTPREG2ATB_LSB                                                                       28
-#define PHY_ANALOG_PMU2_OTPREG2ATB_MASK                                                              0x10000000
-#define PHY_ANALOG_PMU2_OTPREG2ATB_GET(x)                                            (((x) & 0x10000000) >> 28)
-#define PHY_ANALOG_PMU2_OTPREG2ATB_SET(x)                                            (((x) << 28) & 0x10000000)
-#define PHY_ANALOG_PMU2_OTPREG_LVLCTR_MSB                                                                    30
-#define PHY_ANALOG_PMU2_OTPREG_LVLCTR_LSB                                                                    29
-#define PHY_ANALOG_PMU2_OTPREG_LVLCTR_MASK                                                           0x60000000
-#define PHY_ANALOG_PMU2_OTPREG_LVLCTR_GET(x)                                         (((x) & 0x60000000) >> 29)
-#define PHY_ANALOG_PMU2_OTPREG_LVLCTR_SET(x)                                         (((x) << 29) & 0x60000000)
-#define PHY_ANALOG_PMU2_DREG_LVLCTR_MANOVR_EN_MSB                                                            31
-#define PHY_ANALOG_PMU2_DREG_LVLCTR_MANOVR_EN_LSB                                                            31
-#define PHY_ANALOG_PMU2_DREG_LVLCTR_MANOVR_EN_MASK                                                   0x80000000
-#define PHY_ANALOG_PMU2_DREG_LVLCTR_MANOVR_EN_GET(x)                                 (((x) & 0x80000000) >> 31)
-#define PHY_ANALOG_PMU2_DREG_LVLCTR_MANOVR_EN_SET(x)                                 (((x) << 31) & 0x80000000)
-
-
-#ifndef __ASSEMBLER__
-
-typedef struct analog_intf_athr_wlan_reg_reg_s {
-  volatile unsigned int RXRF_BIAS1;                                    /*        0x0 - 0x4        */
-  volatile unsigned int RXRF_BIAS2;                                    /*        0x4 - 0x8        */
-  volatile unsigned int RXRF_GAINSTAGES;                               /*        0x8 - 0xc        */
-  volatile unsigned int RXRF_AGC;                                      /*        0xc - 0x10       */
-  volatile char pad__0[0x30];                                          /*       0x10 - 0x40       */
-  volatile unsigned int TXRF1;                                         /*       0x40 - 0x44       */
-  volatile unsigned int TXRF2;                                         /*       0x44 - 0x48       */
-  volatile unsigned int TXRF3;                                         /*       0x48 - 0x4c       */
-  volatile unsigned int TXRF4;                                         /*       0x4c - 0x50       */
-  volatile unsigned int TXRF5;                                         /*       0x50 - 0x54       */
-  volatile unsigned int TXRF6;                                         /*       0x54 - 0x58       */
-  volatile unsigned int TXRF7;                                         /*       0x58 - 0x5c       */
-  volatile unsigned int TXRF8;                                         /*       0x5c - 0x60       */
-  volatile unsigned int TXRF9;                                         /*       0x60 - 0x64       */
-  volatile unsigned int TXRF10;                                        /*       0x64 - 0x68       */
-  volatile unsigned int TXRF11;                                        /*       0x68 - 0x6c       */
-  volatile unsigned int TXRF12;                                        /*       0x6c - 0x70       */
-  volatile char pad__1[0x10];                                          /*       0x70 - 0x80       */
-  volatile unsigned int SYNTH1;                                        /*       0x80 - 0x84       */
-  volatile unsigned int SYNTH2;                                        /*       0x84 - 0x88       */
-  volatile unsigned int SYNTH3;                                        /*       0x88 - 0x8c       */
-  volatile unsigned int SYNTH4;                                        /*       0x8c - 0x90       */
-  volatile unsigned int SYNTH5;                                        /*       0x90 - 0x94       */
-  volatile unsigned int SYNTH6;                                        /*       0x94 - 0x98       */
-  volatile unsigned int SYNTH7;                                        /*       0x98 - 0x9c       */
-  volatile unsigned int SYNTH8;                                        /*       0x9c - 0xa0       */
-  volatile unsigned int SYNTH9;                                        /*       0xa0 - 0xa4       */
-  volatile unsigned int SYNTH10;                                       /*       0xa4 - 0xa8       */
-  volatile unsigned int SYNTH11;                                       /*       0xa8 - 0xac       */
-  volatile unsigned int SYNTH12;                                       /*       0xac - 0xb0       */
-  volatile unsigned int SYNTH13;                                       /*       0xb0 - 0xb4       */
-  volatile unsigned int SYNTH14;                                       /*       0xb4 - 0xb8       */
-  volatile char pad__2[0x8];                                           /*       0xb8 - 0xc0       */
-  volatile unsigned int BIAS1;                                         /*       0xc0 - 0xc4       */
-  volatile unsigned int BIAS2;                                         /*       0xc4 - 0xc8       */
-  volatile unsigned int BIAS3;                                         /*       0xc8 - 0xcc       */
-  volatile unsigned int BIAS4;                                         /*       0xcc - 0xd0       */
-  volatile char pad__3[0x30];                                          /*       0xd0 - 0x100      */
-  volatile unsigned int RXTX1;                                         /*      0x100 - 0x104      */
-  volatile unsigned int RXTX2;                                         /*      0x104 - 0x108      */
-  volatile unsigned int RXTX3;                                         /*      0x108 - 0x10c      */
-  volatile char pad__4[0x34];                                          /*      0x10c - 0x140      */
-  volatile unsigned int BB1;                                           /*      0x140 - 0x144      */
-  volatile unsigned int BB2;                                           /*      0x144 - 0x148      */
-  volatile unsigned int BB3;                                           /*      0x148 - 0x14c      */
-  volatile char pad__5[0x134];                                         /*      0x14c - 0x280      */
-  volatile unsigned int PLLCLKMODA;                                    /*      0x280 - 0x284      */
-  volatile unsigned int PLLCLKMODA2;                                   /*      0x284 - 0x288      */
-  volatile unsigned int TOP;                                           /*      0x288 - 0x28c      */
-  volatile unsigned int THERM;                                         /*      0x28c - 0x290      */
-  volatile unsigned int XTAL;                                          /*      0x290 - 0x294      */
-  volatile char pad__6[0xec];                                          /*      0x294 - 0x380      */
-  volatile unsigned int rbist_cntrl;                                   /*      0x380 - 0x384      */
-  volatile unsigned int tx_dc_offset;                                  /*      0x384 - 0x388      */
-  volatile unsigned int tx_tonegen0;                                   /*      0x388 - 0x38c      */
-  volatile unsigned int tx_tonegen1;                                   /*      0x38c - 0x390      */
-  volatile unsigned int tx_lftonegen0;                                 /*      0x390 - 0x394      */
-  volatile unsigned int tx_linear_ramp_i;                              /*      0x394 - 0x398      */
-  volatile unsigned int tx_linear_ramp_q;                              /*      0x398 - 0x39c      */
-  volatile unsigned int tx_prbs_mag;                                   /*      0x39c - 0x3a0      */
-  volatile unsigned int tx_prbs_seed_i;                                /*      0x3a0 - 0x3a4      */
-  volatile unsigned int tx_prbs_seed_q;                                /*      0x3a4 - 0x3a8      */
-  volatile unsigned int cmac_dc_cancel;                                /*      0x3a8 - 0x3ac      */
-  volatile unsigned int cmac_dc_offset;                                /*      0x3ac - 0x3b0      */
-  volatile unsigned int cmac_corr;                                     /*      0x3b0 - 0x3b4      */
-  volatile unsigned int cmac_power;                                    /*      0x3b4 - 0x3b8      */
-  volatile unsigned int cmac_cross_corr;                               /*      0x3b8 - 0x3bc      */
-  volatile unsigned int cmac_i2q2;                                     /*      0x3bc - 0x3c0      */
-  volatile unsigned int cmac_power_hpf;                                /*      0x3c0 - 0x3c4      */
-  volatile unsigned int rxdac_set1;                                    /*      0x3c4 - 0x3c8      */
-  volatile unsigned int rxdac_set2;                                    /*      0x3c8 - 0x3cc      */
-  volatile unsigned int rxdac_long_shift;                              /*      0x3cc - 0x3d0      */
-  volatile unsigned int cmac_results_i;                                /*      0x3d0 - 0x3d4      */
-  volatile unsigned int cmac_results_q;                                /*      0x3d4 - 0x3d8      */
-  volatile char pad__7[0x368];                                         /*      0x3d8 - 0x740      */
-  volatile unsigned int PMU1;                                          /*      0x740 - 0x744      */
-  volatile unsigned int PMU2;                                          /*      0x744 - 0x748      */
-} analog_intf_athr_wlan_reg_reg_t;
-
-#endif /* __ASSEMBLER__ */
-
-#endif /* _ANALOG_INTF_ATHR_WLAN_REG_REG_H_ */
diff -druN linux-2.6.39-libre/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/analog_intf_reg.h linux-3.0-rc7-libre/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/analog_intf_reg.h
--- linux-2.6.39-libre/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/analog_intf_reg.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/analog_intf_reg.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,37 +0,0 @@
-// ------------------------------------------------------------------
-// Copyright (c) 2004-2010 Atheros Corporation.  All rights reserved.
-// 
-//
-// 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.
-//
-//
-// ------------------------------------------------------------------
-//===================================================================
-// Author(s): ="Atheros"
-//===================================================================
-
-
-#ifdef WLAN_HEADERS
-
-#include "analog_intf_athr_wlan_reg.h"
-
-
-#ifndef BT_HEADERS
-
-
-
-#endif
-#endif
-
-
-
diff -druN linux-2.6.39-libre/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/apb_map.h linux-3.0-rc7-libre/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/apb_map.h
--- linux-2.6.39-libre/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/apb_map.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/apb_map.h	2011-07-11 19:51:52.000000000 -0400
@@ -21,11 +21,8 @@
 //===================================================================
 
 
-#ifdef WLAN_HEADERS
-
 #include "apb_athr_wlan_map.h"
 
-
 #ifndef BT_HEADERS
 
 #define RTC_BASE_ADDRESS WLAN_RTC_BASE_ADDRESS
@@ -40,9 +37,4 @@
 #define MAC_BASE_ADDRESS WLAN_MAC_BASE_ADDRESS
 #define RDMA_BASE_ADDRESS WLAN_RDMA_BASE_ADDRESS
 
-
 #endif
-#endif
-
-
-
diff -druN linux-2.6.39-libre/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/bb_lc_reg.h linux-3.0-rc7-libre/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/bb_lc_reg.h
--- linux-2.6.39-libre/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/bb_lc_reg.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/bb_lc_reg.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,7076 +0,0 @@
-// ------------------------------------------------------------------
-// Copyright (c) 2004-2010 Atheros Corporation.  All rights reserved.
-// 
-//
-// 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.
-//
-//
-// ------------------------------------------------------------------
-//===================================================================
-// Author(s): ="Atheros"
-//===================================================================
-
-/* Copyright (C) 2009 Denali Software Inc.  All rights reserved              */
-/* THIS FILE IS AUTOMATICALLY GENERATED BY DENALI BLUEPRINT, DO NOT EDIT     */
-
-
-#ifndef _BB_LC_REG_REG_H_
-#define _BB_LC_REG_REG_H_
-
-
-/* macros for BB_test_controls */
-#define PHY_BB_TEST_CONTROLS_ADDRESS                                                          0x00009800
-#define PHY_BB_TEST_CONTROLS_OFFSET                                                           0x00009800
-#define PHY_BB_TEST_CONTROLS_CF_TSTTRIG_SEL_MSB                                                        3
-#define PHY_BB_TEST_CONTROLS_CF_TSTTRIG_SEL_LSB                                                        0
-#define PHY_BB_TEST_CONTROLS_CF_TSTTRIG_SEL_MASK                                              0x0000000f
-#define PHY_BB_TEST_CONTROLS_CF_TSTTRIG_SEL_GET(x)                             (((x) & 0x0000000f) >> 0)
-#define PHY_BB_TEST_CONTROLS_CF_TSTTRIG_SEL_SET(x)                             (((x) << 0) & 0x0000000f)
-#define PHY_BB_TEST_CONTROLS_CF_TSTTRIG_MSB                                                            4
-#define PHY_BB_TEST_CONTROLS_CF_TSTTRIG_LSB                                                            4
-#define PHY_BB_TEST_CONTROLS_CF_TSTTRIG_MASK                                                  0x00000010
-#define PHY_BB_TEST_CONTROLS_CF_TSTTRIG_GET(x)                                 (((x) & 0x00000010) >> 4)
-#define PHY_BB_TEST_CONTROLS_CF_TSTTRIG_SET(x)                                 (((x) << 4) & 0x00000010)
-#define PHY_BB_TEST_CONTROLS_CF_RFSHIFT_SEL_MSB                                                        6
-#define PHY_BB_TEST_CONTROLS_CF_RFSHIFT_SEL_LSB                                                        5
-#define PHY_BB_TEST_CONTROLS_CF_RFSHIFT_SEL_MASK                                              0x00000060
-#define PHY_BB_TEST_CONTROLS_CF_RFSHIFT_SEL_GET(x)                             (((x) & 0x00000060) >> 5)
-#define PHY_BB_TEST_CONTROLS_CF_RFSHIFT_SEL_SET(x)                             (((x) << 5) & 0x00000060)
-#define PHY_BB_TEST_CONTROLS_CARDBUS_MODE_MSB                                                          9
-#define PHY_BB_TEST_CONTROLS_CARDBUS_MODE_LSB                                                          8
-#define PHY_BB_TEST_CONTROLS_CARDBUS_MODE_MASK                                                0x00000300
-#define PHY_BB_TEST_CONTROLS_CARDBUS_MODE_GET(x)                               (((x) & 0x00000300) >> 8)
-#define PHY_BB_TEST_CONTROLS_CARDBUS_MODE_SET(x)                               (((x) << 8) & 0x00000300)
-#define PHY_BB_TEST_CONTROLS_CLKOUT_IS_CLK32_MSB                                                      10
-#define PHY_BB_TEST_CONTROLS_CLKOUT_IS_CLK32_LSB                                                      10
-#define PHY_BB_TEST_CONTROLS_CLKOUT_IS_CLK32_MASK                                             0x00000400
-#define PHY_BB_TEST_CONTROLS_CLKOUT_IS_CLK32_GET(x)                           (((x) & 0x00000400) >> 10)
-#define PHY_BB_TEST_CONTROLS_CLKOUT_IS_CLK32_SET(x)                           (((x) << 10) & 0x00000400)
-#define PHY_BB_TEST_CONTROLS_ENABLE_RFSILENT_BB_MSB                                                   13
-#define PHY_BB_TEST_CONTROLS_ENABLE_RFSILENT_BB_LSB                                                   13
-#define PHY_BB_TEST_CONTROLS_ENABLE_RFSILENT_BB_MASK                                          0x00002000
-#define PHY_BB_TEST_CONTROLS_ENABLE_RFSILENT_BB_GET(x)                        (((x) & 0x00002000) >> 13)
-#define PHY_BB_TEST_CONTROLS_ENABLE_RFSILENT_BB_SET(x)                        (((x) << 13) & 0x00002000)
-#define PHY_BB_TEST_CONTROLS_ENABLE_MINI_OBS_MSB                                                      15
-#define PHY_BB_TEST_CONTROLS_ENABLE_MINI_OBS_LSB                                                      15
-#define PHY_BB_TEST_CONTROLS_ENABLE_MINI_OBS_MASK                                             0x00008000
-#define PHY_BB_TEST_CONTROLS_ENABLE_MINI_OBS_GET(x)                           (((x) & 0x00008000) >> 15)
-#define PHY_BB_TEST_CONTROLS_ENABLE_MINI_OBS_SET(x)                           (((x) << 15) & 0x00008000)
-#define PHY_BB_TEST_CONTROLS_SLOW_CLK160_MSB                                                          17
-#define PHY_BB_TEST_CONTROLS_SLOW_CLK160_LSB                                                          17
-#define PHY_BB_TEST_CONTROLS_SLOW_CLK160_MASK                                                 0x00020000
-#define PHY_BB_TEST_CONTROLS_SLOW_CLK160_GET(x)                               (((x) & 0x00020000) >> 17)
-#define PHY_BB_TEST_CONTROLS_SLOW_CLK160_SET(x)                               (((x) << 17) & 0x00020000)
-#define PHY_BB_TEST_CONTROLS_AGC_OBS_SEL_3_MSB                                                        18
-#define PHY_BB_TEST_CONTROLS_AGC_OBS_SEL_3_LSB                                                        18
-#define PHY_BB_TEST_CONTROLS_AGC_OBS_SEL_3_MASK                                               0x00040000
-#define PHY_BB_TEST_CONTROLS_AGC_OBS_SEL_3_GET(x)                             (((x) & 0x00040000) >> 18)
-#define PHY_BB_TEST_CONTROLS_AGC_OBS_SEL_3_SET(x)                             (((x) << 18) & 0x00040000)
-#define PHY_BB_TEST_CONTROLS_CF_BBB_OBS_SEL_MSB                                                       22
-#define PHY_BB_TEST_CONTROLS_CF_BBB_OBS_SEL_LSB                                                       19
-#define PHY_BB_TEST_CONTROLS_CF_BBB_OBS_SEL_MASK                                              0x00780000
-#define PHY_BB_TEST_CONTROLS_CF_BBB_OBS_SEL_GET(x)                            (((x) & 0x00780000) >> 19)
-#define PHY_BB_TEST_CONTROLS_CF_BBB_OBS_SEL_SET(x)                            (((x) << 19) & 0x00780000)
-#define PHY_BB_TEST_CONTROLS_RX_OBS_SEL_5TH_BIT_MSB                                                   23
-#define PHY_BB_TEST_CONTROLS_RX_OBS_SEL_5TH_BIT_LSB                                                   23
-#define PHY_BB_TEST_CONTROLS_RX_OBS_SEL_5TH_BIT_MASK                                          0x00800000
-#define PHY_BB_TEST_CONTROLS_RX_OBS_SEL_5TH_BIT_GET(x)                        (((x) & 0x00800000) >> 23)
-#define PHY_BB_TEST_CONTROLS_RX_OBS_SEL_5TH_BIT_SET(x)                        (((x) << 23) & 0x00800000)
-#define PHY_BB_TEST_CONTROLS_AGC_OBS_SEL_4_MSB                                                        24
-#define PHY_BB_TEST_CONTROLS_AGC_OBS_SEL_4_LSB                                                        24
-#define PHY_BB_TEST_CONTROLS_AGC_OBS_SEL_4_MASK                                               0x01000000
-#define PHY_BB_TEST_CONTROLS_AGC_OBS_SEL_4_GET(x)                             (((x) & 0x01000000) >> 24)
-#define PHY_BB_TEST_CONTROLS_AGC_OBS_SEL_4_SET(x)                             (((x) << 24) & 0x01000000)
-#define PHY_BB_TEST_CONTROLS_FORCE_AGC_CLEAR_MSB                                                      28
-#define PHY_BB_TEST_CONTROLS_FORCE_AGC_CLEAR_LSB                                                      28
-#define PHY_BB_TEST_CONTROLS_FORCE_AGC_CLEAR_MASK                                             0x10000000
-#define PHY_BB_TEST_CONTROLS_FORCE_AGC_CLEAR_GET(x)                           (((x) & 0x10000000) >> 28)
-#define PHY_BB_TEST_CONTROLS_FORCE_AGC_CLEAR_SET(x)                           (((x) << 28) & 0x10000000)
-#define PHY_BB_TEST_CONTROLS_TSTDAC_OUT_SEL_MSB                                                       31
-#define PHY_BB_TEST_CONTROLS_TSTDAC_OUT_SEL_LSB                                                       30
-#define PHY_BB_TEST_CONTROLS_TSTDAC_OUT_SEL_MASK                                              0xc0000000
-#define PHY_BB_TEST_CONTROLS_TSTDAC_OUT_SEL_GET(x)                            (((x) & 0xc0000000) >> 30)
-#define PHY_BB_TEST_CONTROLS_TSTDAC_OUT_SEL_SET(x)                            (((x) << 30) & 0xc0000000)
-
-/* macros for BB_gen_controls */
-#define PHY_BB_GEN_CONTROLS_ADDRESS                                                           0x00009804
-#define PHY_BB_GEN_CONTROLS_OFFSET                                                            0x00009804
-#define PHY_BB_GEN_CONTROLS_TURBO_MSB                                                                  0
-#define PHY_BB_GEN_CONTROLS_TURBO_LSB                                                                  0
-#define PHY_BB_GEN_CONTROLS_TURBO_MASK                                                        0x00000001
-#define PHY_BB_GEN_CONTROLS_TURBO_GET(x)                                       (((x) & 0x00000001) >> 0)
-#define PHY_BB_GEN_CONTROLS_TURBO_SET(x)                                       (((x) << 0) & 0x00000001)
-#define PHY_BB_GEN_CONTROLS_CF_SHORT20_MSB                                                             1
-#define PHY_BB_GEN_CONTROLS_CF_SHORT20_LSB                                                             1
-#define PHY_BB_GEN_CONTROLS_CF_SHORT20_MASK                                                   0x00000002
-#define PHY_BB_GEN_CONTROLS_CF_SHORT20_GET(x)                                  (((x) & 0x00000002) >> 1)
-#define PHY_BB_GEN_CONTROLS_CF_SHORT20_SET(x)                                  (((x) << 1) & 0x00000002)
-#define PHY_BB_GEN_CONTROLS_DYN_20_40_MSB                                                              2
-#define PHY_BB_GEN_CONTROLS_DYN_20_40_LSB                                                              2
-#define PHY_BB_GEN_CONTROLS_DYN_20_40_MASK                                                    0x00000004
-#define PHY_BB_GEN_CONTROLS_DYN_20_40_GET(x)                                   (((x) & 0x00000004) >> 2)
-#define PHY_BB_GEN_CONTROLS_DYN_20_40_SET(x)                                   (((x) << 2) & 0x00000004)
-#define PHY_BB_GEN_CONTROLS_DYN_20_40_PRI_ONLY_MSB                                                     3
-#define PHY_BB_GEN_CONTROLS_DYN_20_40_PRI_ONLY_LSB                                                     3
-#define PHY_BB_GEN_CONTROLS_DYN_20_40_PRI_ONLY_MASK                                           0x00000008
-#define PHY_BB_GEN_CONTROLS_DYN_20_40_PRI_ONLY_GET(x)                          (((x) & 0x00000008) >> 3)
-#define PHY_BB_GEN_CONTROLS_DYN_20_40_PRI_ONLY_SET(x)                          (((x) << 3) & 0x00000008)
-#define PHY_BB_GEN_CONTROLS_DYN_20_40_PRI_CHN_MSB                                                      4
-#define PHY_BB_GEN_CONTROLS_DYN_20_40_PRI_CHN_LSB                                                      4
-#define PHY_BB_GEN_CONTROLS_DYN_20_40_PRI_CHN_MASK                                            0x00000010
-#define PHY_BB_GEN_CONTROLS_DYN_20_40_PRI_CHN_GET(x)                           (((x) & 0x00000010) >> 4)
-#define PHY_BB_GEN_CONTROLS_DYN_20_40_PRI_CHN_SET(x)                           (((x) << 4) & 0x00000010)
-#define PHY_BB_GEN_CONTROLS_DYN_20_40_EXT_CHN_MSB                                                      5
-#define PHY_BB_GEN_CONTROLS_DYN_20_40_EXT_CHN_LSB                                                      5
-#define PHY_BB_GEN_CONTROLS_DYN_20_40_EXT_CHN_MASK                                            0x00000020
-#define PHY_BB_GEN_CONTROLS_DYN_20_40_EXT_CHN_GET(x)                           (((x) & 0x00000020) >> 5)
-#define PHY_BB_GEN_CONTROLS_DYN_20_40_EXT_CHN_SET(x)                           (((x) << 5) & 0x00000020)
-#define PHY_BB_GEN_CONTROLS_HT_ENABLE_MSB                                                              6
-#define PHY_BB_GEN_CONTROLS_HT_ENABLE_LSB                                                              6
-#define PHY_BB_GEN_CONTROLS_HT_ENABLE_MASK                                                    0x00000040
-#define PHY_BB_GEN_CONTROLS_HT_ENABLE_GET(x)                                   (((x) & 0x00000040) >> 6)
-#define PHY_BB_GEN_CONTROLS_HT_ENABLE_SET(x)                                   (((x) << 6) & 0x00000040)
-#define PHY_BB_GEN_CONTROLS_ALLOW_SHORT_GI_MSB                                                         7
-#define PHY_BB_GEN_CONTROLS_ALLOW_SHORT_GI_LSB                                                         7
-#define PHY_BB_GEN_CONTROLS_ALLOW_SHORT_GI_MASK                                               0x00000080
-#define PHY_BB_GEN_CONTROLS_ALLOW_SHORT_GI_GET(x)                              (((x) & 0x00000080) >> 7)
-#define PHY_BB_GEN_CONTROLS_ALLOW_SHORT_GI_SET(x)                              (((x) << 7) & 0x00000080)
-#define PHY_BB_GEN_CONTROLS_CF_2_CHAINS_USE_WALSH_MSB                                                  8
-#define PHY_BB_GEN_CONTROLS_CF_2_CHAINS_USE_WALSH_LSB                                                  8
-#define PHY_BB_GEN_CONTROLS_CF_2_CHAINS_USE_WALSH_MASK                                        0x00000100
-#define PHY_BB_GEN_CONTROLS_CF_2_CHAINS_USE_WALSH_GET(x)                       (((x) & 0x00000100) >> 8)
-#define PHY_BB_GEN_CONTROLS_CF_2_CHAINS_USE_WALSH_SET(x)                       (((x) << 8) & 0x00000100)
-#define PHY_BB_GEN_CONTROLS_CF_SINGLE_HT_LTF1_MSB                                                      9
-#define PHY_BB_GEN_CONTROLS_CF_SINGLE_HT_LTF1_LSB                                                      9
-#define PHY_BB_GEN_CONTROLS_CF_SINGLE_HT_LTF1_MASK                                            0x00000200
-#define PHY_BB_GEN_CONTROLS_CF_SINGLE_HT_LTF1_GET(x)                           (((x) & 0x00000200) >> 9)
-#define PHY_BB_GEN_CONTROLS_CF_SINGLE_HT_LTF1_SET(x)                           (((x) << 9) & 0x00000200)
-#define PHY_BB_GEN_CONTROLS_GF_ENABLE_MSB                                                             10
-#define PHY_BB_GEN_CONTROLS_GF_ENABLE_LSB                                                             10
-#define PHY_BB_GEN_CONTROLS_GF_ENABLE_MASK                                                    0x00000400
-#define PHY_BB_GEN_CONTROLS_GF_ENABLE_GET(x)                                  (((x) & 0x00000400) >> 10)
-#define PHY_BB_GEN_CONTROLS_GF_ENABLE_SET(x)                                  (((x) << 10) & 0x00000400)
-#define PHY_BB_GEN_CONTROLS_BYPASS_DAC_FIFO_N_MSB                                                     11
-#define PHY_BB_GEN_CONTROLS_BYPASS_DAC_FIFO_N_LSB                                                     11
-#define PHY_BB_GEN_CONTROLS_BYPASS_DAC_FIFO_N_MASK                                            0x00000800
-#define PHY_BB_GEN_CONTROLS_BYPASS_DAC_FIFO_N_GET(x)                          (((x) & 0x00000800) >> 11)
-#define PHY_BB_GEN_CONTROLS_BYPASS_DAC_FIFO_N_SET(x)                          (((x) << 11) & 0x00000800)
-
-/* macros for BB_test_controls_status */
-#define PHY_BB_TEST_CONTROLS_STATUS_ADDRESS                                                   0x00009808
-#define PHY_BB_TEST_CONTROLS_STATUS_OFFSET                                                    0x00009808
-#define PHY_BB_TEST_CONTROLS_STATUS_CF_TSTDAC_EN_MSB                                                   0
-#define PHY_BB_TEST_CONTROLS_STATUS_CF_TSTDAC_EN_LSB                                                   0
-#define PHY_BB_TEST_CONTROLS_STATUS_CF_TSTDAC_EN_MASK                                         0x00000001
-#define PHY_BB_TEST_CONTROLS_STATUS_CF_TSTDAC_EN_GET(x)                        (((x) & 0x00000001) >> 0)
-#define PHY_BB_TEST_CONTROLS_STATUS_CF_TSTDAC_EN_SET(x)                        (((x) << 0) & 0x00000001)
-#define PHY_BB_TEST_CONTROLS_STATUS_CF_TX_SRC_IS_TSTDAC_MSB                                            1
-#define PHY_BB_TEST_CONTROLS_STATUS_CF_TX_SRC_IS_TSTDAC_LSB                                            1
-#define PHY_BB_TEST_CONTROLS_STATUS_CF_TX_SRC_IS_TSTDAC_MASK                                  0x00000002
-#define PHY_BB_TEST_CONTROLS_STATUS_CF_TX_SRC_IS_TSTDAC_GET(x)                 (((x) & 0x00000002) >> 1)
-#define PHY_BB_TEST_CONTROLS_STATUS_CF_TX_SRC_IS_TSTDAC_SET(x)                 (((x) << 1) & 0x00000002)
-#define PHY_BB_TEST_CONTROLS_STATUS_CF_TX_OBS_SEL_MSB                                                  4
-#define PHY_BB_TEST_CONTROLS_STATUS_CF_TX_OBS_SEL_LSB                                                  2
-#define PHY_BB_TEST_CONTROLS_STATUS_CF_TX_OBS_SEL_MASK                                        0x0000001c
-#define PHY_BB_TEST_CONTROLS_STATUS_CF_TX_OBS_SEL_GET(x)                       (((x) & 0x0000001c) >> 2)
-#define PHY_BB_TEST_CONTROLS_STATUS_CF_TX_OBS_SEL_SET(x)                       (((x) << 2) & 0x0000001c)
-#define PHY_BB_TEST_CONTROLS_STATUS_CF_TX_OBS_MUX_SEL_MSB                                              6
-#define PHY_BB_TEST_CONTROLS_STATUS_CF_TX_OBS_MUX_SEL_LSB                                              5
-#define PHY_BB_TEST_CONTROLS_STATUS_CF_TX_OBS_MUX_SEL_MASK                                    0x00000060
-#define PHY_BB_TEST_CONTROLS_STATUS_CF_TX_OBS_MUX_SEL_GET(x)                   (((x) & 0x00000060) >> 5)
-#define PHY_BB_TEST_CONTROLS_STATUS_CF_TX_OBS_MUX_SEL_SET(x)                   (((x) << 5) & 0x00000060)
-#define PHY_BB_TEST_CONTROLS_STATUS_CF_TX_SRC_ALTERNATE_MSB                                            7
-#define PHY_BB_TEST_CONTROLS_STATUS_CF_TX_SRC_ALTERNATE_LSB                                            7
-#define PHY_BB_TEST_CONTROLS_STATUS_CF_TX_SRC_ALTERNATE_MASK                                  0x00000080
-#define PHY_BB_TEST_CONTROLS_STATUS_CF_TX_SRC_ALTERNATE_GET(x)                 (((x) & 0x00000080) >> 7)
-#define PHY_BB_TEST_CONTROLS_STATUS_CF_TX_SRC_ALTERNATE_SET(x)                 (((x) << 7) & 0x00000080)
-#define PHY_BB_TEST_CONTROLS_STATUS_CF_TSTADC_EN_MSB                                                   8
-#define PHY_BB_TEST_CONTROLS_STATUS_CF_TSTADC_EN_LSB                                                   8
-#define PHY_BB_TEST_CONTROLS_STATUS_CF_TSTADC_EN_MASK                                         0x00000100
-#define PHY_BB_TEST_CONTROLS_STATUS_CF_TSTADC_EN_GET(x)                        (((x) & 0x00000100) >> 8)
-#define PHY_BB_TEST_CONTROLS_STATUS_CF_TSTADC_EN_SET(x)                        (((x) << 8) & 0x00000100)
-#define PHY_BB_TEST_CONTROLS_STATUS_CF_RX_SRC_IS_TSTADC_MSB                                            9
-#define PHY_BB_TEST_CONTROLS_STATUS_CF_RX_SRC_IS_TSTADC_LSB                                            9
-#define PHY_BB_TEST_CONTROLS_STATUS_CF_RX_SRC_IS_TSTADC_MASK                                  0x00000200
-#define PHY_BB_TEST_CONTROLS_STATUS_CF_RX_SRC_IS_TSTADC_GET(x)                 (((x) & 0x00000200) >> 9)
-#define PHY_BB_TEST_CONTROLS_STATUS_CF_RX_SRC_IS_TSTADC_SET(x)                 (((x) << 9) & 0x00000200)
-#define PHY_BB_TEST_CONTROLS_STATUS_RX_OBS_SEL_MSB                                                    13
-#define PHY_BB_TEST_CONTROLS_STATUS_RX_OBS_SEL_LSB                                                    10
-#define PHY_BB_TEST_CONTROLS_STATUS_RX_OBS_SEL_MASK                                           0x00003c00
-#define PHY_BB_TEST_CONTROLS_STATUS_RX_OBS_SEL_GET(x)                         (((x) & 0x00003c00) >> 10)
-#define PHY_BB_TEST_CONTROLS_STATUS_RX_OBS_SEL_SET(x)                         (((x) << 10) & 0x00003c00)
-#define PHY_BB_TEST_CONTROLS_STATUS_DISABLE_A2_WARM_RESET_MSB                                         14
-#define PHY_BB_TEST_CONTROLS_STATUS_DISABLE_A2_WARM_RESET_LSB                                         14
-#define PHY_BB_TEST_CONTROLS_STATUS_DISABLE_A2_WARM_RESET_MASK                                0x00004000
-#define PHY_BB_TEST_CONTROLS_STATUS_DISABLE_A2_WARM_RESET_GET(x)              (((x) & 0x00004000) >> 14)
-#define PHY_BB_TEST_CONTROLS_STATUS_DISABLE_A2_WARM_RESET_SET(x)              (((x) << 14) & 0x00004000)
-#define PHY_BB_TEST_CONTROLS_STATUS_RESET_A2_MSB                                                      15
-#define PHY_BB_TEST_CONTROLS_STATUS_RESET_A2_LSB                                                      15
-#define PHY_BB_TEST_CONTROLS_STATUS_RESET_A2_MASK                                             0x00008000
-#define PHY_BB_TEST_CONTROLS_STATUS_RESET_A2_GET(x)                           (((x) & 0x00008000) >> 15)
-#define PHY_BB_TEST_CONTROLS_STATUS_RESET_A2_SET(x)                           (((x) << 15) & 0x00008000)
-#define PHY_BB_TEST_CONTROLS_STATUS_AGC_OBS_SEL_MSB                                                   18
-#define PHY_BB_TEST_CONTROLS_STATUS_AGC_OBS_SEL_LSB                                                   16
-#define PHY_BB_TEST_CONTROLS_STATUS_AGC_OBS_SEL_MASK                                          0x00070000
-#define PHY_BB_TEST_CONTROLS_STATUS_AGC_OBS_SEL_GET(x)                        (((x) & 0x00070000) >> 16)
-#define PHY_BB_TEST_CONTROLS_STATUS_AGC_OBS_SEL_SET(x)                        (((x) << 16) & 0x00070000)
-#define PHY_BB_TEST_CONTROLS_STATUS_CF_ENABLE_FFT_DUMP_MSB                                            19
-#define PHY_BB_TEST_CONTROLS_STATUS_CF_ENABLE_FFT_DUMP_LSB                                            19
-#define PHY_BB_TEST_CONTROLS_STATUS_CF_ENABLE_FFT_DUMP_MASK                                   0x00080000
-#define PHY_BB_TEST_CONTROLS_STATUS_CF_ENABLE_FFT_DUMP_GET(x)                 (((x) & 0x00080000) >> 19)
-#define PHY_BB_TEST_CONTROLS_STATUS_CF_ENABLE_FFT_DUMP_SET(x)                 (((x) << 19) & 0x00080000)
-#define PHY_BB_TEST_CONTROLS_STATUS_CF_DEBUGPORT_IN_MSB                                               23
-#define PHY_BB_TEST_CONTROLS_STATUS_CF_DEBUGPORT_IN_LSB                                               23
-#define PHY_BB_TEST_CONTROLS_STATUS_CF_DEBUGPORT_IN_MASK                                      0x00800000
-#define PHY_BB_TEST_CONTROLS_STATUS_CF_DEBUGPORT_IN_GET(x)                    (((x) & 0x00800000) >> 23)
-#define PHY_BB_TEST_CONTROLS_STATUS_CF_DEBUGPORT_IN_SET(x)                    (((x) << 23) & 0x00800000)
-#define PHY_BB_TEST_CONTROLS_STATUS_DISABLE_AGC_TO_A2_MSB                                             27
-#define PHY_BB_TEST_CONTROLS_STATUS_DISABLE_AGC_TO_A2_LSB                                             27
-#define PHY_BB_TEST_CONTROLS_STATUS_DISABLE_AGC_TO_A2_MASK                                    0x08000000
-#define PHY_BB_TEST_CONTROLS_STATUS_DISABLE_AGC_TO_A2_GET(x)                  (((x) & 0x08000000) >> 27)
-#define PHY_BB_TEST_CONTROLS_STATUS_DISABLE_AGC_TO_A2_SET(x)                  (((x) << 27) & 0x08000000)
-#define PHY_BB_TEST_CONTROLS_STATUS_CF_DEBUGPORT_EN_MSB                                               28
-#define PHY_BB_TEST_CONTROLS_STATUS_CF_DEBUGPORT_EN_LSB                                               28
-#define PHY_BB_TEST_CONTROLS_STATUS_CF_DEBUGPORT_EN_MASK                                      0x10000000
-#define PHY_BB_TEST_CONTROLS_STATUS_CF_DEBUGPORT_EN_GET(x)                    (((x) & 0x10000000) >> 28)
-#define PHY_BB_TEST_CONTROLS_STATUS_CF_DEBUGPORT_EN_SET(x)                    (((x) << 28) & 0x10000000)
-#define PHY_BB_TEST_CONTROLS_STATUS_CF_DEBUGPORT_SEL_MSB                                              30
-#define PHY_BB_TEST_CONTROLS_STATUS_CF_DEBUGPORT_SEL_LSB                                              29
-#define PHY_BB_TEST_CONTROLS_STATUS_CF_DEBUGPORT_SEL_MASK                                     0x60000000
-#define PHY_BB_TEST_CONTROLS_STATUS_CF_DEBUGPORT_SEL_GET(x)                   (((x) & 0x60000000) >> 29)
-#define PHY_BB_TEST_CONTROLS_STATUS_CF_DEBUGPORT_SEL_SET(x)                   (((x) << 29) & 0x60000000)
-
-/* macros for BB_timing_controls_1 */
-#define PHY_BB_TIMING_CONTROLS_1_ADDRESS                                                      0x0000980c
-#define PHY_BB_TIMING_CONTROLS_1_OFFSET                                                       0x0000980c
-#define PHY_BB_TIMING_CONTROLS_1_STE_THR_MSB                                                           6
-#define PHY_BB_TIMING_CONTROLS_1_STE_THR_LSB                                                           0
-#define PHY_BB_TIMING_CONTROLS_1_STE_THR_MASK                                                 0x0000007f
-#define PHY_BB_TIMING_CONTROLS_1_STE_THR_GET(x)                                (((x) & 0x0000007f) >> 0)
-#define PHY_BB_TIMING_CONTROLS_1_STE_THR_SET(x)                                (((x) << 0) & 0x0000007f)
-#define PHY_BB_TIMING_CONTROLS_1_STE_TO_LONG1_MSB                                                     12
-#define PHY_BB_TIMING_CONTROLS_1_STE_TO_LONG1_LSB                                                      7
-#define PHY_BB_TIMING_CONTROLS_1_STE_TO_LONG1_MASK                                            0x00001f80
-#define PHY_BB_TIMING_CONTROLS_1_STE_TO_LONG1_GET(x)                           (((x) & 0x00001f80) >> 7)
-#define PHY_BB_TIMING_CONTROLS_1_STE_TO_LONG1_SET(x)                           (((x) << 7) & 0x00001f80)
-#define PHY_BB_TIMING_CONTROLS_1_TIMING_BACKOFF_MSB                                                   16
-#define PHY_BB_TIMING_CONTROLS_1_TIMING_BACKOFF_LSB                                                   13
-#define PHY_BB_TIMING_CONTROLS_1_TIMING_BACKOFF_MASK                                          0x0001e000
-#define PHY_BB_TIMING_CONTROLS_1_TIMING_BACKOFF_GET(x)                        (((x) & 0x0001e000) >> 13)
-#define PHY_BB_TIMING_CONTROLS_1_TIMING_BACKOFF_SET(x)                        (((x) << 13) & 0x0001e000)
-#define PHY_BB_TIMING_CONTROLS_1_ENABLE_HT_FINE_PPM_MSB                                               17
-#define PHY_BB_TIMING_CONTROLS_1_ENABLE_HT_FINE_PPM_LSB                                               17
-#define PHY_BB_TIMING_CONTROLS_1_ENABLE_HT_FINE_PPM_MASK                                      0x00020000
-#define PHY_BB_TIMING_CONTROLS_1_ENABLE_HT_FINE_PPM_GET(x)                    (((x) & 0x00020000) >> 17)
-#define PHY_BB_TIMING_CONTROLS_1_ENABLE_HT_FINE_PPM_SET(x)                    (((x) << 17) & 0x00020000)
-#define PHY_BB_TIMING_CONTROLS_1_HT_FINE_PPM_STREAM_MSB                                               19
-#define PHY_BB_TIMING_CONTROLS_1_HT_FINE_PPM_STREAM_LSB                                               18
-#define PHY_BB_TIMING_CONTROLS_1_HT_FINE_PPM_STREAM_MASK                                      0x000c0000
-#define PHY_BB_TIMING_CONTROLS_1_HT_FINE_PPM_STREAM_GET(x)                    (((x) & 0x000c0000) >> 18)
-#define PHY_BB_TIMING_CONTROLS_1_HT_FINE_PPM_STREAM_SET(x)                    (((x) << 18) & 0x000c0000)
-#define PHY_BB_TIMING_CONTROLS_1_HT_FINE_PPM_QAM_MSB                                                  21
-#define PHY_BB_TIMING_CONTROLS_1_HT_FINE_PPM_QAM_LSB                                                  20
-#define PHY_BB_TIMING_CONTROLS_1_HT_FINE_PPM_QAM_MASK                                         0x00300000
-#define PHY_BB_TIMING_CONTROLS_1_HT_FINE_PPM_QAM_GET(x)                       (((x) & 0x00300000) >> 20)
-#define PHY_BB_TIMING_CONTROLS_1_HT_FINE_PPM_QAM_SET(x)                       (((x) << 20) & 0x00300000)
-#define PHY_BB_TIMING_CONTROLS_1_ENABLE_LONG_CHANFIL_MSB                                              22
-#define PHY_BB_TIMING_CONTROLS_1_ENABLE_LONG_CHANFIL_LSB                                              22
-#define PHY_BB_TIMING_CONTROLS_1_ENABLE_LONG_CHANFIL_MASK                                     0x00400000
-#define PHY_BB_TIMING_CONTROLS_1_ENABLE_LONG_CHANFIL_GET(x)                   (((x) & 0x00400000) >> 22)
-#define PHY_BB_TIMING_CONTROLS_1_ENABLE_LONG_CHANFIL_SET(x)                   (((x) << 22) & 0x00400000)
-#define PHY_BB_TIMING_CONTROLS_1_ENABLE_RX_STBC_MSB                                                   23
-#define PHY_BB_TIMING_CONTROLS_1_ENABLE_RX_STBC_LSB                                                   23
-#define PHY_BB_TIMING_CONTROLS_1_ENABLE_RX_STBC_MASK                                          0x00800000
-#define PHY_BB_TIMING_CONTROLS_1_ENABLE_RX_STBC_GET(x)                        (((x) & 0x00800000) >> 23)
-#define PHY_BB_TIMING_CONTROLS_1_ENABLE_RX_STBC_SET(x)                        (((x) << 23) & 0x00800000)
-#define PHY_BB_TIMING_CONTROLS_1_ENABLE_CHANNEL_FILTER_MSB                                            24
-#define PHY_BB_TIMING_CONTROLS_1_ENABLE_CHANNEL_FILTER_LSB                                            24
-#define PHY_BB_TIMING_CONTROLS_1_ENABLE_CHANNEL_FILTER_MASK                                   0x01000000
-#define PHY_BB_TIMING_CONTROLS_1_ENABLE_CHANNEL_FILTER_GET(x)                 (((x) & 0x01000000) >> 24)
-#define PHY_BB_TIMING_CONTROLS_1_ENABLE_CHANNEL_FILTER_SET(x)                 (((x) << 24) & 0x01000000)
-#define PHY_BB_TIMING_CONTROLS_1_FALSE_ALARM_MSB                                                      26
-#define PHY_BB_TIMING_CONTROLS_1_FALSE_ALARM_LSB                                                      25
-#define PHY_BB_TIMING_CONTROLS_1_FALSE_ALARM_MASK                                             0x06000000
-#define PHY_BB_TIMING_CONTROLS_1_FALSE_ALARM_GET(x)                           (((x) & 0x06000000) >> 25)
-#define PHY_BB_TIMING_CONTROLS_1_FALSE_ALARM_SET(x)                           (((x) << 25) & 0x06000000)
-#define PHY_BB_TIMING_CONTROLS_1_ENABLE_LONG_RESCALE_MSB                                              27
-#define PHY_BB_TIMING_CONTROLS_1_ENABLE_LONG_RESCALE_LSB                                              27
-#define PHY_BB_TIMING_CONTROLS_1_ENABLE_LONG_RESCALE_MASK                                     0x08000000
-#define PHY_BB_TIMING_CONTROLS_1_ENABLE_LONG_RESCALE_GET(x)                   (((x) & 0x08000000) >> 27)
-#define PHY_BB_TIMING_CONTROLS_1_ENABLE_LONG_RESCALE_SET(x)                   (((x) << 27) & 0x08000000)
-#define PHY_BB_TIMING_CONTROLS_1_TIMING_LEAK_ENABLE_MSB                                               28
-#define PHY_BB_TIMING_CONTROLS_1_TIMING_LEAK_ENABLE_LSB                                               28
-#define PHY_BB_TIMING_CONTROLS_1_TIMING_LEAK_ENABLE_MASK                                      0x10000000
-#define PHY_BB_TIMING_CONTROLS_1_TIMING_LEAK_ENABLE_GET(x)                    (((x) & 0x10000000) >> 28)
-#define PHY_BB_TIMING_CONTROLS_1_TIMING_LEAK_ENABLE_SET(x)                    (((x) << 28) & 0x10000000)
-#define PHY_BB_TIMING_CONTROLS_1_COARSE_PPM_SELECT_MSB                                                30
-#define PHY_BB_TIMING_CONTROLS_1_COARSE_PPM_SELECT_LSB                                                29
-#define PHY_BB_TIMING_CONTROLS_1_COARSE_PPM_SELECT_MASK                                       0x60000000
-#define PHY_BB_TIMING_CONTROLS_1_COARSE_PPM_SELECT_GET(x)                     (((x) & 0x60000000) >> 29)
-#define PHY_BB_TIMING_CONTROLS_1_COARSE_PPM_SELECT_SET(x)                     (((x) << 29) & 0x60000000)
-#define PHY_BB_TIMING_CONTROLS_1_FFT_SCALING_MSB                                                      31
-#define PHY_BB_TIMING_CONTROLS_1_FFT_SCALING_LSB                                                      31
-#define PHY_BB_TIMING_CONTROLS_1_FFT_SCALING_MASK                                             0x80000000
-#define PHY_BB_TIMING_CONTROLS_1_FFT_SCALING_GET(x)                           (((x) & 0x80000000) >> 31)
-#define PHY_BB_TIMING_CONTROLS_1_FFT_SCALING_SET(x)                           (((x) << 31) & 0x80000000)
-
-/* macros for BB_timing_controls_2 */
-#define PHY_BB_TIMING_CONTROLS_2_ADDRESS                                                      0x00009810
-#define PHY_BB_TIMING_CONTROLS_2_OFFSET                                                       0x00009810
-#define PHY_BB_TIMING_CONTROLS_2_FORCED_DELTA_PHI_SYMBOL_MSB                                          11
-#define PHY_BB_TIMING_CONTROLS_2_FORCED_DELTA_PHI_SYMBOL_LSB                                           0
-#define PHY_BB_TIMING_CONTROLS_2_FORCED_DELTA_PHI_SYMBOL_MASK                                 0x00000fff
-#define PHY_BB_TIMING_CONTROLS_2_FORCED_DELTA_PHI_SYMBOL_GET(x)                (((x) & 0x00000fff) >> 0)
-#define PHY_BB_TIMING_CONTROLS_2_FORCED_DELTA_PHI_SYMBOL_SET(x)                (((x) << 0) & 0x00000fff)
-#define PHY_BB_TIMING_CONTROLS_2_FORCE_DELTA_PHI_SYMBOL_MSB                                           12
-#define PHY_BB_TIMING_CONTROLS_2_FORCE_DELTA_PHI_SYMBOL_LSB                                           12
-#define PHY_BB_TIMING_CONTROLS_2_FORCE_DELTA_PHI_SYMBOL_MASK                                  0x00001000
-#define PHY_BB_TIMING_CONTROLS_2_FORCE_DELTA_PHI_SYMBOL_GET(x)                (((x) & 0x00001000) >> 12)
-#define PHY_BB_TIMING_CONTROLS_2_FORCE_DELTA_PHI_SYMBOL_SET(x)                (((x) << 12) & 0x00001000)
-#define PHY_BB_TIMING_CONTROLS_2_ENABLE_MAGNITUDE_TRACK_MSB                                           13
-#define PHY_BB_TIMING_CONTROLS_2_ENABLE_MAGNITUDE_TRACK_LSB                                           13
-#define PHY_BB_TIMING_CONTROLS_2_ENABLE_MAGNITUDE_TRACK_MASK                                  0x00002000
-#define PHY_BB_TIMING_CONTROLS_2_ENABLE_MAGNITUDE_TRACK_GET(x)                (((x) & 0x00002000) >> 13)
-#define PHY_BB_TIMING_CONTROLS_2_ENABLE_MAGNITUDE_TRACK_SET(x)                (((x) << 13) & 0x00002000)
-#define PHY_BB_TIMING_CONTROLS_2_ENABLE_SLOPE_FILTER_MSB                                              14
-#define PHY_BB_TIMING_CONTROLS_2_ENABLE_SLOPE_FILTER_LSB                                              14
-#define PHY_BB_TIMING_CONTROLS_2_ENABLE_SLOPE_FILTER_MASK                                     0x00004000
-#define PHY_BB_TIMING_CONTROLS_2_ENABLE_SLOPE_FILTER_GET(x)                   (((x) & 0x00004000) >> 14)
-#define PHY_BB_TIMING_CONTROLS_2_ENABLE_SLOPE_FILTER_SET(x)                   (((x) << 14) & 0x00004000)
-#define PHY_BB_TIMING_CONTROLS_2_ENABLE_OFFSET_FILTER_MSB                                             15
-#define PHY_BB_TIMING_CONTROLS_2_ENABLE_OFFSET_FILTER_LSB                                             15
-#define PHY_BB_TIMING_CONTROLS_2_ENABLE_OFFSET_FILTER_MASK                                    0x00008000
-#define PHY_BB_TIMING_CONTROLS_2_ENABLE_OFFSET_FILTER_GET(x)                  (((x) & 0x00008000) >> 15)
-#define PHY_BB_TIMING_CONTROLS_2_ENABLE_OFFSET_FILTER_SET(x)                  (((x) << 15) & 0x00008000)
-#define PHY_BB_TIMING_CONTROLS_2_DC_OFF_DELTAF_THRES_MSB                                              22
-#define PHY_BB_TIMING_CONTROLS_2_DC_OFF_DELTAF_THRES_LSB                                              16
-#define PHY_BB_TIMING_CONTROLS_2_DC_OFF_DELTAF_THRES_MASK                                     0x007f0000
-#define PHY_BB_TIMING_CONTROLS_2_DC_OFF_DELTAF_THRES_GET(x)                   (((x) & 0x007f0000) >> 16)
-#define PHY_BB_TIMING_CONTROLS_2_DC_OFF_DELTAF_THRES_SET(x)                   (((x) << 16) & 0x007f0000)
-#define PHY_BB_TIMING_CONTROLS_2_DC_OFF_TIM_CONST_MSB                                                 26
-#define PHY_BB_TIMING_CONTROLS_2_DC_OFF_TIM_CONST_LSB                                                 24
-#define PHY_BB_TIMING_CONTROLS_2_DC_OFF_TIM_CONST_MASK                                        0x07000000
-#define PHY_BB_TIMING_CONTROLS_2_DC_OFF_TIM_CONST_GET(x)                      (((x) & 0x07000000) >> 24)
-#define PHY_BB_TIMING_CONTROLS_2_DC_OFF_TIM_CONST_SET(x)                      (((x) << 24) & 0x07000000)
-#define PHY_BB_TIMING_CONTROLS_2_ENABLE_DC_OFFSET_MSB                                                 27
-#define PHY_BB_TIMING_CONTROLS_2_ENABLE_DC_OFFSET_LSB                                                 27
-#define PHY_BB_TIMING_CONTROLS_2_ENABLE_DC_OFFSET_MASK                                        0x08000000
-#define PHY_BB_TIMING_CONTROLS_2_ENABLE_DC_OFFSET_GET(x)                      (((x) & 0x08000000) >> 27)
-#define PHY_BB_TIMING_CONTROLS_2_ENABLE_DC_OFFSET_SET(x)                      (((x) << 27) & 0x08000000)
-#define PHY_BB_TIMING_CONTROLS_2_ENABLE_DC_OFFSET_TRACK_MSB                                           28
-#define PHY_BB_TIMING_CONTROLS_2_ENABLE_DC_OFFSET_TRACK_LSB                                           28
-#define PHY_BB_TIMING_CONTROLS_2_ENABLE_DC_OFFSET_TRACK_MASK                                  0x10000000
-#define PHY_BB_TIMING_CONTROLS_2_ENABLE_DC_OFFSET_TRACK_GET(x)                (((x) & 0x10000000) >> 28)
-#define PHY_BB_TIMING_CONTROLS_2_ENABLE_DC_OFFSET_TRACK_SET(x)                (((x) << 28) & 0x10000000)
-#define PHY_BB_TIMING_CONTROLS_2_ENABLE_WEIGHTING_MSB                                                 29
-#define PHY_BB_TIMING_CONTROLS_2_ENABLE_WEIGHTING_LSB                                                 29
-#define PHY_BB_TIMING_CONTROLS_2_ENABLE_WEIGHTING_MASK                                        0x20000000
-#define PHY_BB_TIMING_CONTROLS_2_ENABLE_WEIGHTING_GET(x)                      (((x) & 0x20000000) >> 29)
-#define PHY_BB_TIMING_CONTROLS_2_ENABLE_WEIGHTING_SET(x)                      (((x) << 29) & 0x20000000)
-#define PHY_BB_TIMING_CONTROLS_2_TRACEBACK128_MSB                                                     30
-#define PHY_BB_TIMING_CONTROLS_2_TRACEBACK128_LSB                                                     30
-#define PHY_BB_TIMING_CONTROLS_2_TRACEBACK128_MASK                                            0x40000000
-#define PHY_BB_TIMING_CONTROLS_2_TRACEBACK128_GET(x)                          (((x) & 0x40000000) >> 30)
-#define PHY_BB_TIMING_CONTROLS_2_TRACEBACK128_SET(x)                          (((x) << 30) & 0x40000000)
-#define PHY_BB_TIMING_CONTROLS_2_ENABLE_HT_FINE_TIMING_MSB                                            31
-#define PHY_BB_TIMING_CONTROLS_2_ENABLE_HT_FINE_TIMING_LSB                                            31
-#define PHY_BB_TIMING_CONTROLS_2_ENABLE_HT_FINE_TIMING_MASK                                   0x80000000
-#define PHY_BB_TIMING_CONTROLS_2_ENABLE_HT_FINE_TIMING_GET(x)                 (((x) & 0x80000000) >> 31)
-#define PHY_BB_TIMING_CONTROLS_2_ENABLE_HT_FINE_TIMING_SET(x)                 (((x) << 31) & 0x80000000)
-
-/* macros for BB_timing_controls_3 */
-#define PHY_BB_TIMING_CONTROLS_3_ADDRESS                                                      0x00009814
-#define PHY_BB_TIMING_CONTROLS_3_OFFSET                                                       0x00009814
-#define PHY_BB_TIMING_CONTROLS_3_PPM_RESCUE_INTERVAL_MSB                                               7
-#define PHY_BB_TIMING_CONTROLS_3_PPM_RESCUE_INTERVAL_LSB                                               0
-#define PHY_BB_TIMING_CONTROLS_3_PPM_RESCUE_INTERVAL_MASK                                     0x000000ff
-#define PHY_BB_TIMING_CONTROLS_3_PPM_RESCUE_INTERVAL_GET(x)                    (((x) & 0x000000ff) >> 0)
-#define PHY_BB_TIMING_CONTROLS_3_PPM_RESCUE_INTERVAL_SET(x)                    (((x) << 0) & 0x000000ff)
-#define PHY_BB_TIMING_CONTROLS_3_ENABLE_PPM_RESCUE_MSB                                                 8
-#define PHY_BB_TIMING_CONTROLS_3_ENABLE_PPM_RESCUE_LSB                                                 8
-#define PHY_BB_TIMING_CONTROLS_3_ENABLE_PPM_RESCUE_MASK                                       0x00000100
-#define PHY_BB_TIMING_CONTROLS_3_ENABLE_PPM_RESCUE_GET(x)                      (((x) & 0x00000100) >> 8)
-#define PHY_BB_TIMING_CONTROLS_3_ENABLE_PPM_RESCUE_SET(x)                      (((x) << 8) & 0x00000100)
-#define PHY_BB_TIMING_CONTROLS_3_ENABLE_FINE_PPM_MSB                                                   9
-#define PHY_BB_TIMING_CONTROLS_3_ENABLE_FINE_PPM_LSB                                                   9
-#define PHY_BB_TIMING_CONTROLS_3_ENABLE_FINE_PPM_MASK                                         0x00000200
-#define PHY_BB_TIMING_CONTROLS_3_ENABLE_FINE_PPM_GET(x)                        (((x) & 0x00000200) >> 9)
-#define PHY_BB_TIMING_CONTROLS_3_ENABLE_FINE_PPM_SET(x)                        (((x) << 9) & 0x00000200)
-#define PHY_BB_TIMING_CONTROLS_3_ENABLE_FINE_INTERP_MSB                                               10
-#define PHY_BB_TIMING_CONTROLS_3_ENABLE_FINE_INTERP_LSB                                               10
-#define PHY_BB_TIMING_CONTROLS_3_ENABLE_FINE_INTERP_MASK                                      0x00000400
-#define PHY_BB_TIMING_CONTROLS_3_ENABLE_FINE_INTERP_GET(x)                    (((x) & 0x00000400) >> 10)
-#define PHY_BB_TIMING_CONTROLS_3_ENABLE_FINE_INTERP_SET(x)                    (((x) << 10) & 0x00000400)
-#define PHY_BB_TIMING_CONTROLS_3_CONTINUOUS_PPM_RESCUE_MSB                                            11
-#define PHY_BB_TIMING_CONTROLS_3_CONTINUOUS_PPM_RESCUE_LSB                                            11
-#define PHY_BB_TIMING_CONTROLS_3_CONTINUOUS_PPM_RESCUE_MASK                                   0x00000800
-#define PHY_BB_TIMING_CONTROLS_3_CONTINUOUS_PPM_RESCUE_GET(x)                 (((x) & 0x00000800) >> 11)
-#define PHY_BB_TIMING_CONTROLS_3_CONTINUOUS_PPM_RESCUE_SET(x)                 (((x) << 11) & 0x00000800)
-#define PHY_BB_TIMING_CONTROLS_3_ENABLE_DF_CHANEST_MSB                                                12
-#define PHY_BB_TIMING_CONTROLS_3_ENABLE_DF_CHANEST_LSB                                                12
-#define PHY_BB_TIMING_CONTROLS_3_ENABLE_DF_CHANEST_MASK                                       0x00001000
-#define PHY_BB_TIMING_CONTROLS_3_ENABLE_DF_CHANEST_GET(x)                     (((x) & 0x00001000) >> 12)
-#define PHY_BB_TIMING_CONTROLS_3_ENABLE_DF_CHANEST_SET(x)                     (((x) << 12) & 0x00001000)
-#define PHY_BB_TIMING_CONTROLS_3_DELTA_SLOPE_COEF_EXP_MSB                                             16
-#define PHY_BB_TIMING_CONTROLS_3_DELTA_SLOPE_COEF_EXP_LSB                                             13
-#define PHY_BB_TIMING_CONTROLS_3_DELTA_SLOPE_COEF_EXP_MASK                                    0x0001e000
-#define PHY_BB_TIMING_CONTROLS_3_DELTA_SLOPE_COEF_EXP_GET(x)                  (((x) & 0x0001e000) >> 13)
-#define PHY_BB_TIMING_CONTROLS_3_DELTA_SLOPE_COEF_EXP_SET(x)                  (((x) << 13) & 0x0001e000)
-#define PHY_BB_TIMING_CONTROLS_3_DELTA_SLOPE_COEF_MAN_MSB                                             31
-#define PHY_BB_TIMING_CONTROLS_3_DELTA_SLOPE_COEF_MAN_LSB                                             17
-#define PHY_BB_TIMING_CONTROLS_3_DELTA_SLOPE_COEF_MAN_MASK                                    0xfffe0000
-#define PHY_BB_TIMING_CONTROLS_3_DELTA_SLOPE_COEF_MAN_GET(x)                  (((x) & 0xfffe0000) >> 17)
-#define PHY_BB_TIMING_CONTROLS_3_DELTA_SLOPE_COEF_MAN_SET(x)                  (((x) << 17) & 0xfffe0000)
-
-/* macros for BB_D2_chip_id */
-#define PHY_BB_D2_CHIP_ID_ADDRESS                                                             0x00009818
-#define PHY_BB_D2_CHIP_ID_OFFSET                                                              0x00009818
-#define PHY_BB_D2_CHIP_ID_OLD_ID_MSB                                                                   7
-#define PHY_BB_D2_CHIP_ID_OLD_ID_LSB                                                                   0
-#define PHY_BB_D2_CHIP_ID_OLD_ID_MASK                                                         0x000000ff
-#define PHY_BB_D2_CHIP_ID_OLD_ID_GET(x)                                        (((x) & 0x000000ff) >> 0)
-#define PHY_BB_D2_CHIP_ID_ID_MSB                                                                      31
-#define PHY_BB_D2_CHIP_ID_ID_LSB                                                                       8
-#define PHY_BB_D2_CHIP_ID_ID_MASK                                                             0xffffff00
-#define PHY_BB_D2_CHIP_ID_ID_GET(x)                                            (((x) & 0xffffff00) >> 8)
-
-/* macros for BB_active */
-#define PHY_BB_ACTIVE_ADDRESS                                                                 0x0000981c
-#define PHY_BB_ACTIVE_OFFSET                                                                  0x0000981c
-#define PHY_BB_ACTIVE_CF_ACTIVE_MSB                                                                    0
-#define PHY_BB_ACTIVE_CF_ACTIVE_LSB                                                                    0
-#define PHY_BB_ACTIVE_CF_ACTIVE_MASK                                                          0x00000001
-#define PHY_BB_ACTIVE_CF_ACTIVE_GET(x)                                         (((x) & 0x00000001) >> 0)
-#define PHY_BB_ACTIVE_CF_ACTIVE_SET(x)                                         (((x) << 0) & 0x00000001)
-
-/* macros for BB_tx_timing_1 */
-#define PHY_BB_TX_TIMING_1_ADDRESS                                                            0x00009820
-#define PHY_BB_TX_TIMING_1_OFFSET                                                             0x00009820
-#define PHY_BB_TX_TIMING_1_TX_FRAME_TO_ADC_OFF_MSB                                                     7
-#define PHY_BB_TX_TIMING_1_TX_FRAME_TO_ADC_OFF_LSB                                                     0
-#define PHY_BB_TX_TIMING_1_TX_FRAME_TO_ADC_OFF_MASK                                           0x000000ff
-#define PHY_BB_TX_TIMING_1_TX_FRAME_TO_ADC_OFF_GET(x)                          (((x) & 0x000000ff) >> 0)
-#define PHY_BB_TX_TIMING_1_TX_FRAME_TO_ADC_OFF_SET(x)                          (((x) << 0) & 0x000000ff)
-#define PHY_BB_TX_TIMING_1_TX_FRAME_TO_A2_RX_OFF_MSB                                                  15
-#define PHY_BB_TX_TIMING_1_TX_FRAME_TO_A2_RX_OFF_LSB                                                   8
-#define PHY_BB_TX_TIMING_1_TX_FRAME_TO_A2_RX_OFF_MASK                                         0x0000ff00
-#define PHY_BB_TX_TIMING_1_TX_FRAME_TO_A2_RX_OFF_GET(x)                        (((x) & 0x0000ff00) >> 8)
-#define PHY_BB_TX_TIMING_1_TX_FRAME_TO_A2_RX_OFF_SET(x)                        (((x) << 8) & 0x0000ff00)
-#define PHY_BB_TX_TIMING_1_TX_FRAME_TO_DAC_ON_MSB                                                     23
-#define PHY_BB_TX_TIMING_1_TX_FRAME_TO_DAC_ON_LSB                                                     16
-#define PHY_BB_TX_TIMING_1_TX_FRAME_TO_DAC_ON_MASK                                            0x00ff0000
-#define PHY_BB_TX_TIMING_1_TX_FRAME_TO_DAC_ON_GET(x)                          (((x) & 0x00ff0000) >> 16)
-#define PHY_BB_TX_TIMING_1_TX_FRAME_TO_DAC_ON_SET(x)                          (((x) << 16) & 0x00ff0000)
-#define PHY_BB_TX_TIMING_1_TX_FRAME_TO_A2_TX_ON_MSB                                                   31
-#define PHY_BB_TX_TIMING_1_TX_FRAME_TO_A2_TX_ON_LSB                                                   24
-#define PHY_BB_TX_TIMING_1_TX_FRAME_TO_A2_TX_ON_MASK                                          0xff000000
-#define PHY_BB_TX_TIMING_1_TX_FRAME_TO_A2_TX_ON_GET(x)                        (((x) & 0xff000000) >> 24)
-#define PHY_BB_TX_TIMING_1_TX_FRAME_TO_A2_TX_ON_SET(x)                        (((x) << 24) & 0xff000000)
-
-/* macros for BB_tx_timing_2 */
-#define PHY_BB_TX_TIMING_2_ADDRESS                                                            0x00009824
-#define PHY_BB_TX_TIMING_2_OFFSET                                                             0x00009824
-#define PHY_BB_TX_TIMING_2_TX_FRAME_TO_TX_D_START_MSB                                                  7
-#define PHY_BB_TX_TIMING_2_TX_FRAME_TO_TX_D_START_LSB                                                  0
-#define PHY_BB_TX_TIMING_2_TX_FRAME_TO_TX_D_START_MASK                                        0x000000ff
-#define PHY_BB_TX_TIMING_2_TX_FRAME_TO_TX_D_START_GET(x)                       (((x) & 0x000000ff) >> 0)
-#define PHY_BB_TX_TIMING_2_TX_FRAME_TO_TX_D_START_SET(x)                       (((x) << 0) & 0x000000ff)
-#define PHY_BB_TX_TIMING_2_TX_FRAME_TO_PA_ON_MSB                                                      15
-#define PHY_BB_TX_TIMING_2_TX_FRAME_TO_PA_ON_LSB                                                       8
-#define PHY_BB_TX_TIMING_2_TX_FRAME_TO_PA_ON_MASK                                             0x0000ff00
-#define PHY_BB_TX_TIMING_2_TX_FRAME_TO_PA_ON_GET(x)                            (((x) & 0x0000ff00) >> 8)
-#define PHY_BB_TX_TIMING_2_TX_FRAME_TO_PA_ON_SET(x)                            (((x) << 8) & 0x0000ff00)
-#define PHY_BB_TX_TIMING_2_TX_END_TO_PA_OFF_MSB                                                       23
-#define PHY_BB_TX_TIMING_2_TX_END_TO_PA_OFF_LSB                                                       16
-#define PHY_BB_TX_TIMING_2_TX_END_TO_PA_OFF_MASK                                              0x00ff0000
-#define PHY_BB_TX_TIMING_2_TX_END_TO_PA_OFF_GET(x)                            (((x) & 0x00ff0000) >> 16)
-#define PHY_BB_TX_TIMING_2_TX_END_TO_PA_OFF_SET(x)                            (((x) << 16) & 0x00ff0000)
-#define PHY_BB_TX_TIMING_2_TX_END_TO_A2_TX_OFF_MSB                                                    31
-#define PHY_BB_TX_TIMING_2_TX_END_TO_A2_TX_OFF_LSB                                                    24
-#define PHY_BB_TX_TIMING_2_TX_END_TO_A2_TX_OFF_MASK                                           0xff000000
-#define PHY_BB_TX_TIMING_2_TX_END_TO_A2_TX_OFF_GET(x)                         (((x) & 0xff000000) >> 24)
-#define PHY_BB_TX_TIMING_2_TX_END_TO_A2_TX_OFF_SET(x)                         (((x) << 24) & 0xff000000)
-
-/* macros for BB_tx_timing_3 */
-#define PHY_BB_TX_TIMING_3_ADDRESS                                                            0x00009828
-#define PHY_BB_TX_TIMING_3_OFFSET                                                             0x00009828
-#define PHY_BB_TX_TIMING_3_TX_END_TO_DAC_OFF_MSB                                                       7
-#define PHY_BB_TX_TIMING_3_TX_END_TO_DAC_OFF_LSB                                                       0
-#define PHY_BB_TX_TIMING_3_TX_END_TO_DAC_OFF_MASK                                             0x000000ff
-#define PHY_BB_TX_TIMING_3_TX_END_TO_DAC_OFF_GET(x)                            (((x) & 0x000000ff) >> 0)
-#define PHY_BB_TX_TIMING_3_TX_END_TO_DAC_OFF_SET(x)                            (((x) << 0) & 0x000000ff)
-#define PHY_BB_TX_TIMING_3_TX_FRAME_TO_THERM_CHAIN_ON_MSB                                             15
-#define PHY_BB_TX_TIMING_3_TX_FRAME_TO_THERM_CHAIN_ON_LSB                                              8
-#define PHY_BB_TX_TIMING_3_TX_FRAME_TO_THERM_CHAIN_ON_MASK                                    0x0000ff00
-#define PHY_BB_TX_TIMING_3_TX_FRAME_TO_THERM_CHAIN_ON_GET(x)                   (((x) & 0x0000ff00) >> 8)
-#define PHY_BB_TX_TIMING_3_TX_FRAME_TO_THERM_CHAIN_ON_SET(x)                   (((x) << 8) & 0x0000ff00)
-#define PHY_BB_TX_TIMING_3_TX_END_TO_A2_RX_ON_MSB                                                     23
-#define PHY_BB_TX_TIMING_3_TX_END_TO_A2_RX_ON_LSB                                                     16
-#define PHY_BB_TX_TIMING_3_TX_END_TO_A2_RX_ON_MASK                                            0x00ff0000
-#define PHY_BB_TX_TIMING_3_TX_END_TO_A2_RX_ON_GET(x)                          (((x) & 0x00ff0000) >> 16)
-#define PHY_BB_TX_TIMING_3_TX_END_TO_A2_RX_ON_SET(x)                          (((x) << 16) & 0x00ff0000)
-#define PHY_BB_TX_TIMING_3_TX_END_TO_ADC_ON_MSB                                                       31
-#define PHY_BB_TX_TIMING_3_TX_END_TO_ADC_ON_LSB                                                       24
-#define PHY_BB_TX_TIMING_3_TX_END_TO_ADC_ON_MASK                                              0xff000000
-#define PHY_BB_TX_TIMING_3_TX_END_TO_ADC_ON_GET(x)                            (((x) & 0xff000000) >> 24)
-#define PHY_BB_TX_TIMING_3_TX_END_TO_ADC_ON_SET(x)                            (((x) << 24) & 0xff000000)
-
-/* macros for BB_addac_parallel_control */
-#define PHY_BB_ADDAC_PARALLEL_CONTROL_ADDRESS                                                 0x0000982c
-#define PHY_BB_ADDAC_PARALLEL_CONTROL_OFFSET                                                  0x0000982c
-#define PHY_BB_ADDAC_PARALLEL_CONTROL_OFF_DACLPMODE_MSB                                               12
-#define PHY_BB_ADDAC_PARALLEL_CONTROL_OFF_DACLPMODE_LSB                                               12
-#define PHY_BB_ADDAC_PARALLEL_CONTROL_OFF_DACLPMODE_MASK                                      0x00001000
-#define PHY_BB_ADDAC_PARALLEL_CONTROL_OFF_DACLPMODE_GET(x)                    (((x) & 0x00001000) >> 12)
-#define PHY_BB_ADDAC_PARALLEL_CONTROL_OFF_DACLPMODE_SET(x)                    (((x) << 12) & 0x00001000)
-#define PHY_BB_ADDAC_PARALLEL_CONTROL_OFF_PWDDAC_MSB                                                  13
-#define PHY_BB_ADDAC_PARALLEL_CONTROL_OFF_PWDDAC_LSB                                                  13
-#define PHY_BB_ADDAC_PARALLEL_CONTROL_OFF_PWDDAC_MASK                                         0x00002000
-#define PHY_BB_ADDAC_PARALLEL_CONTROL_OFF_PWDDAC_GET(x)                       (((x) & 0x00002000) >> 13)
-#define PHY_BB_ADDAC_PARALLEL_CONTROL_OFF_PWDDAC_SET(x)                       (((x) << 13) & 0x00002000)
-#define PHY_BB_ADDAC_PARALLEL_CONTROL_OFF_PWDADC_MSB                                                  15
-#define PHY_BB_ADDAC_PARALLEL_CONTROL_OFF_PWDADC_LSB                                                  15
-#define PHY_BB_ADDAC_PARALLEL_CONTROL_OFF_PWDADC_MASK                                         0x00008000
-#define PHY_BB_ADDAC_PARALLEL_CONTROL_OFF_PWDADC_GET(x)                       (((x) & 0x00008000) >> 15)
-#define PHY_BB_ADDAC_PARALLEL_CONTROL_OFF_PWDADC_SET(x)                       (((x) << 15) & 0x00008000)
-#define PHY_BB_ADDAC_PARALLEL_CONTROL_ON_DACLPMODE_MSB                                                28
-#define PHY_BB_ADDAC_PARALLEL_CONTROL_ON_DACLPMODE_LSB                                                28
-#define PHY_BB_ADDAC_PARALLEL_CONTROL_ON_DACLPMODE_MASK                                       0x10000000
-#define PHY_BB_ADDAC_PARALLEL_CONTROL_ON_DACLPMODE_GET(x)                     (((x) & 0x10000000) >> 28)
-#define PHY_BB_ADDAC_PARALLEL_CONTROL_ON_DACLPMODE_SET(x)                     (((x) << 28) & 0x10000000)
-#define PHY_BB_ADDAC_PARALLEL_CONTROL_ON_PWDDAC_MSB                                                   29
-#define PHY_BB_ADDAC_PARALLEL_CONTROL_ON_PWDDAC_LSB                                                   29
-#define PHY_BB_ADDAC_PARALLEL_CONTROL_ON_PWDDAC_MASK                                          0x20000000
-#define PHY_BB_ADDAC_PARALLEL_CONTROL_ON_PWDDAC_GET(x)                        (((x) & 0x20000000) >> 29)
-#define PHY_BB_ADDAC_PARALLEL_CONTROL_ON_PWDDAC_SET(x)                        (((x) << 29) & 0x20000000)
-#define PHY_BB_ADDAC_PARALLEL_CONTROL_ON_PWDADC_MSB                                                   31
-#define PHY_BB_ADDAC_PARALLEL_CONTROL_ON_PWDADC_LSB                                                   31
-#define PHY_BB_ADDAC_PARALLEL_CONTROL_ON_PWDADC_MASK                                          0x80000000
-#define PHY_BB_ADDAC_PARALLEL_CONTROL_ON_PWDADC_GET(x)                        (((x) & 0x80000000) >> 31)
-#define PHY_BB_ADDAC_PARALLEL_CONTROL_ON_PWDADC_SET(x)                        (((x) << 31) & 0x80000000)
-
-/* macros for BB_xpa_timing_control */
-#define PHY_BB_XPA_TIMING_CONTROL_ADDRESS                                                     0x00009834
-#define PHY_BB_XPA_TIMING_CONTROL_OFFSET                                                      0x00009834
-#define PHY_BB_XPA_TIMING_CONTROL_TX_FRAME_TO_XPAA_ON_MSB                                              7
-#define PHY_BB_XPA_TIMING_CONTROL_TX_FRAME_TO_XPAA_ON_LSB                                              0
-#define PHY_BB_XPA_TIMING_CONTROL_TX_FRAME_TO_XPAA_ON_MASK                                    0x000000ff
-#define PHY_BB_XPA_TIMING_CONTROL_TX_FRAME_TO_XPAA_ON_GET(x)                   (((x) & 0x000000ff) >> 0)
-#define PHY_BB_XPA_TIMING_CONTROL_TX_FRAME_TO_XPAA_ON_SET(x)                   (((x) << 0) & 0x000000ff)
-#define PHY_BB_XPA_TIMING_CONTROL_TX_FRAME_TO_XPAB_ON_MSB                                             15
-#define PHY_BB_XPA_TIMING_CONTROL_TX_FRAME_TO_XPAB_ON_LSB                                              8
-#define PHY_BB_XPA_TIMING_CONTROL_TX_FRAME_TO_XPAB_ON_MASK                                    0x0000ff00
-#define PHY_BB_XPA_TIMING_CONTROL_TX_FRAME_TO_XPAB_ON_GET(x)                   (((x) & 0x0000ff00) >> 8)
-#define PHY_BB_XPA_TIMING_CONTROL_TX_FRAME_TO_XPAB_ON_SET(x)                   (((x) << 8) & 0x0000ff00)
-#define PHY_BB_XPA_TIMING_CONTROL_TX_END_TO_XPAA_OFF_MSB                                              23
-#define PHY_BB_XPA_TIMING_CONTROL_TX_END_TO_XPAA_OFF_LSB                                              16
-#define PHY_BB_XPA_TIMING_CONTROL_TX_END_TO_XPAA_OFF_MASK                                     0x00ff0000
-#define PHY_BB_XPA_TIMING_CONTROL_TX_END_TO_XPAA_OFF_GET(x)                   (((x) & 0x00ff0000) >> 16)
-#define PHY_BB_XPA_TIMING_CONTROL_TX_END_TO_XPAA_OFF_SET(x)                   (((x) << 16) & 0x00ff0000)
-#define PHY_BB_XPA_TIMING_CONTROL_TX_END_TO_XPAB_OFF_MSB                                              31
-#define PHY_BB_XPA_TIMING_CONTROL_TX_END_TO_XPAB_OFF_LSB                                              24
-#define PHY_BB_XPA_TIMING_CONTROL_TX_END_TO_XPAB_OFF_MASK                                     0xff000000
-#define PHY_BB_XPA_TIMING_CONTROL_TX_END_TO_XPAB_OFF_GET(x)                   (((x) & 0xff000000) >> 24)
-#define PHY_BB_XPA_TIMING_CONTROL_TX_END_TO_XPAB_OFF_SET(x)                   (((x) << 24) & 0xff000000)
-
-/* macros for BB_misc_pa_control */
-#define PHY_BB_MISC_PA_CONTROL_ADDRESS                                                        0x00009838
-#define PHY_BB_MISC_PA_CONTROL_OFFSET                                                         0x00009838
-#define PHY_BB_MISC_PA_CONTROL_XPAA_ACTIVE_HIGH_MSB                                                    0
-#define PHY_BB_MISC_PA_CONTROL_XPAA_ACTIVE_HIGH_LSB                                                    0
-#define PHY_BB_MISC_PA_CONTROL_XPAA_ACTIVE_HIGH_MASK                                          0x00000001
-#define PHY_BB_MISC_PA_CONTROL_XPAA_ACTIVE_HIGH_GET(x)                         (((x) & 0x00000001) >> 0)
-#define PHY_BB_MISC_PA_CONTROL_XPAA_ACTIVE_HIGH_SET(x)                         (((x) << 0) & 0x00000001)
-#define PHY_BB_MISC_PA_CONTROL_XPAB_ACTIVE_HIGH_MSB                                                    1
-#define PHY_BB_MISC_PA_CONTROL_XPAB_ACTIVE_HIGH_LSB                                                    1
-#define PHY_BB_MISC_PA_CONTROL_XPAB_ACTIVE_HIGH_MASK                                          0x00000002
-#define PHY_BB_MISC_PA_CONTROL_XPAB_ACTIVE_HIGH_GET(x)                         (((x) & 0x00000002) >> 1)
-#define PHY_BB_MISC_PA_CONTROL_XPAB_ACTIVE_HIGH_SET(x)                         (((x) << 1) & 0x00000002)
-#define PHY_BB_MISC_PA_CONTROL_ENABLE_XPAA_MSB                                                         2
-#define PHY_BB_MISC_PA_CONTROL_ENABLE_XPAA_LSB                                                         2
-#define PHY_BB_MISC_PA_CONTROL_ENABLE_XPAA_MASK                                               0x00000004
-#define PHY_BB_MISC_PA_CONTROL_ENABLE_XPAA_GET(x)                              (((x) & 0x00000004) >> 2)
-#define PHY_BB_MISC_PA_CONTROL_ENABLE_XPAA_SET(x)                              (((x) << 2) & 0x00000004)
-#define PHY_BB_MISC_PA_CONTROL_ENABLE_XPAB_MSB                                                         3
-#define PHY_BB_MISC_PA_CONTROL_ENABLE_XPAB_LSB                                                         3
-#define PHY_BB_MISC_PA_CONTROL_ENABLE_XPAB_MASK                                               0x00000008
-#define PHY_BB_MISC_PA_CONTROL_ENABLE_XPAB_GET(x)                              (((x) & 0x00000008) >> 3)
-#define PHY_BB_MISC_PA_CONTROL_ENABLE_XPAB_SET(x)                              (((x) << 3) & 0x00000008)
-
-/* macros for BB_tstdac_constant */
-#define PHY_BB_TSTDAC_CONSTANT_ADDRESS                                                        0x0000983c
-#define PHY_BB_TSTDAC_CONSTANT_OFFSET                                                         0x0000983c
-#define PHY_BB_TSTDAC_CONSTANT_CF_TSTDAC_CONSTANT_I_MSB                                               10
-#define PHY_BB_TSTDAC_CONSTANT_CF_TSTDAC_CONSTANT_I_LSB                                                0
-#define PHY_BB_TSTDAC_CONSTANT_CF_TSTDAC_CONSTANT_I_MASK                                      0x000007ff
-#define PHY_BB_TSTDAC_CONSTANT_CF_TSTDAC_CONSTANT_I_GET(x)                     (((x) & 0x000007ff) >> 0)
-#define PHY_BB_TSTDAC_CONSTANT_CF_TSTDAC_CONSTANT_I_SET(x)                     (((x) << 0) & 0x000007ff)
-#define PHY_BB_TSTDAC_CONSTANT_CF_TSTDAC_CONSTANT_Q_MSB                                               21
-#define PHY_BB_TSTDAC_CONSTANT_CF_TSTDAC_CONSTANT_Q_LSB                                               11
-#define PHY_BB_TSTDAC_CONSTANT_CF_TSTDAC_CONSTANT_Q_MASK                                      0x003ff800
-#define PHY_BB_TSTDAC_CONSTANT_CF_TSTDAC_CONSTANT_Q_GET(x)                    (((x) & 0x003ff800) >> 11)
-#define PHY_BB_TSTDAC_CONSTANT_CF_TSTDAC_CONSTANT_Q_SET(x)                    (((x) << 11) & 0x003ff800)
-
-/* macros for BB_find_signal_low */
-#define PHY_BB_FIND_SIGNAL_LOW_ADDRESS                                                        0x00009840
-#define PHY_BB_FIND_SIGNAL_LOW_OFFSET                                                         0x00009840
-#define PHY_BB_FIND_SIGNAL_LOW_RELSTEP_LOW_MSB                                                         5
-#define PHY_BB_FIND_SIGNAL_LOW_RELSTEP_LOW_LSB                                                         0
-#define PHY_BB_FIND_SIGNAL_LOW_RELSTEP_LOW_MASK                                               0x0000003f
-#define PHY_BB_FIND_SIGNAL_LOW_RELSTEP_LOW_GET(x)                              (((x) & 0x0000003f) >> 0)
-#define PHY_BB_FIND_SIGNAL_LOW_RELSTEP_LOW_SET(x)                              (((x) << 0) & 0x0000003f)
-#define PHY_BB_FIND_SIGNAL_LOW_FIRSTEP_LOW_MSB                                                        11
-#define PHY_BB_FIND_SIGNAL_LOW_FIRSTEP_LOW_LSB                                                         6
-#define PHY_BB_FIND_SIGNAL_LOW_FIRSTEP_LOW_MASK                                               0x00000fc0
-#define PHY_BB_FIND_SIGNAL_LOW_FIRSTEP_LOW_GET(x)                              (((x) & 0x00000fc0) >> 6)
-#define PHY_BB_FIND_SIGNAL_LOW_FIRSTEP_LOW_SET(x)                              (((x) << 6) & 0x00000fc0)
-#define PHY_BB_FIND_SIGNAL_LOW_FIRPWR_LOW_MSB                                                         19
-#define PHY_BB_FIND_SIGNAL_LOW_FIRPWR_LOW_LSB                                                         12
-#define PHY_BB_FIND_SIGNAL_LOW_FIRPWR_LOW_MASK                                                0x000ff000
-#define PHY_BB_FIND_SIGNAL_LOW_FIRPWR_LOW_GET(x)                              (((x) & 0x000ff000) >> 12)
-#define PHY_BB_FIND_SIGNAL_LOW_FIRPWR_LOW_SET(x)                              (((x) << 12) & 0x000ff000)
-#define PHY_BB_FIND_SIGNAL_LOW_YCOK_MAX_LOW_MSB                                                       23
-#define PHY_BB_FIND_SIGNAL_LOW_YCOK_MAX_LOW_LSB                                                       20
-#define PHY_BB_FIND_SIGNAL_LOW_YCOK_MAX_LOW_MASK                                              0x00f00000
-#define PHY_BB_FIND_SIGNAL_LOW_YCOK_MAX_LOW_GET(x)                            (((x) & 0x00f00000) >> 20)
-#define PHY_BB_FIND_SIGNAL_LOW_YCOK_MAX_LOW_SET(x)                            (((x) << 20) & 0x00f00000)
-#define PHY_BB_FIND_SIGNAL_LOW_LONG_SC_THRESH_MSB                                                     30
-#define PHY_BB_FIND_SIGNAL_LOW_LONG_SC_THRESH_LSB                                                     24
-#define PHY_BB_FIND_SIGNAL_LOW_LONG_SC_THRESH_MASK                                            0x7f000000
-#define PHY_BB_FIND_SIGNAL_LOW_LONG_SC_THRESH_GET(x)                          (((x) & 0x7f000000) >> 24)
-#define PHY_BB_FIND_SIGNAL_LOW_LONG_SC_THRESH_SET(x)                          (((x) << 24) & 0x7f000000)
-
-/* macros for BB_settling_time */
-#define PHY_BB_SETTLING_TIME_ADDRESS                                                          0x00009844
-#define PHY_BB_SETTLING_TIME_OFFSET                                                           0x00009844
-#define PHY_BB_SETTLING_TIME_AGC_SETTLING_MSB                                                          6
-#define PHY_BB_SETTLING_TIME_AGC_SETTLING_LSB                                                          0
-#define PHY_BB_SETTLING_TIME_AGC_SETTLING_MASK                                                0x0000007f
-#define PHY_BB_SETTLING_TIME_AGC_SETTLING_GET(x)                               (((x) & 0x0000007f) >> 0)
-#define PHY_BB_SETTLING_TIME_AGC_SETTLING_SET(x)                               (((x) << 0) & 0x0000007f)
-#define PHY_BB_SETTLING_TIME_SWITCH_SETTLING_MSB                                                      13
-#define PHY_BB_SETTLING_TIME_SWITCH_SETTLING_LSB                                                       7
-#define PHY_BB_SETTLING_TIME_SWITCH_SETTLING_MASK                                             0x00003f80
-#define PHY_BB_SETTLING_TIME_SWITCH_SETTLING_GET(x)                            (((x) & 0x00003f80) >> 7)
-#define PHY_BB_SETTLING_TIME_SWITCH_SETTLING_SET(x)                            (((x) << 7) & 0x00003f80)
-#define PHY_BB_SETTLING_TIME_ADCSAT_THRL_MSB                                                          19
-#define PHY_BB_SETTLING_TIME_ADCSAT_THRL_LSB                                                          14
-#define PHY_BB_SETTLING_TIME_ADCSAT_THRL_MASK                                                 0x000fc000
-#define PHY_BB_SETTLING_TIME_ADCSAT_THRL_GET(x)                               (((x) & 0x000fc000) >> 14)
-#define PHY_BB_SETTLING_TIME_ADCSAT_THRL_SET(x)                               (((x) << 14) & 0x000fc000)
-#define PHY_BB_SETTLING_TIME_ADCSAT_THRH_MSB                                                          25
-#define PHY_BB_SETTLING_TIME_ADCSAT_THRH_LSB                                                          20
-#define PHY_BB_SETTLING_TIME_ADCSAT_THRH_MASK                                                 0x03f00000
-#define PHY_BB_SETTLING_TIME_ADCSAT_THRH_GET(x)                               (((x) & 0x03f00000) >> 20)
-#define PHY_BB_SETTLING_TIME_ADCSAT_THRH_SET(x)                               (((x) << 20) & 0x03f00000)
-#define PHY_BB_SETTLING_TIME_LBRESET_ADVANCE_MSB                                                      29
-#define PHY_BB_SETTLING_TIME_LBRESET_ADVANCE_LSB                                                      26
-#define PHY_BB_SETTLING_TIME_LBRESET_ADVANCE_MASK                                             0x3c000000
-#define PHY_BB_SETTLING_TIME_LBRESET_ADVANCE_GET(x)                           (((x) & 0x3c000000) >> 26)
-#define PHY_BB_SETTLING_TIME_LBRESET_ADVANCE_SET(x)                           (((x) << 26) & 0x3c000000)
-
-/* macros for BB_gain_force_max_gains_b0 */
-#define PHY_BB_GAIN_FORCE_MAX_GAINS_B0_ADDRESS                                                0x00009848
-#define PHY_BB_GAIN_FORCE_MAX_GAINS_B0_OFFSET                                                 0x00009848
-#define PHY_BB_GAIN_FORCE_MAX_GAINS_B0_XATTEN1_HYST_MARGIN_0_MSB                                      13
-#define PHY_BB_GAIN_FORCE_MAX_GAINS_B0_XATTEN1_HYST_MARGIN_0_LSB                                       7
-#define PHY_BB_GAIN_FORCE_MAX_GAINS_B0_XATTEN1_HYST_MARGIN_0_MASK                             0x00003f80
-#define PHY_BB_GAIN_FORCE_MAX_GAINS_B0_XATTEN1_HYST_MARGIN_0_GET(x)            (((x) & 0x00003f80) >> 7)
-#define PHY_BB_GAIN_FORCE_MAX_GAINS_B0_XATTEN1_HYST_MARGIN_0_SET(x)            (((x) << 7) & 0x00003f80)
-#define PHY_BB_GAIN_FORCE_MAX_GAINS_B0_XATTEN2_HYST_MARGIN_0_MSB                                      20
-#define PHY_BB_GAIN_FORCE_MAX_GAINS_B0_XATTEN2_HYST_MARGIN_0_LSB                                      14
-#define PHY_BB_GAIN_FORCE_MAX_GAINS_B0_XATTEN2_HYST_MARGIN_0_MASK                             0x001fc000
-#define PHY_BB_GAIN_FORCE_MAX_GAINS_B0_XATTEN2_HYST_MARGIN_0_GET(x)           (((x) & 0x001fc000) >> 14)
-#define PHY_BB_GAIN_FORCE_MAX_GAINS_B0_XATTEN2_HYST_MARGIN_0_SET(x)           (((x) << 14) & 0x001fc000)
-#define PHY_BB_GAIN_FORCE_MAX_GAINS_B0_GAIN_FORCE_MSB                                                 21
-#define PHY_BB_GAIN_FORCE_MAX_GAINS_B0_GAIN_FORCE_LSB                                                 21
-#define PHY_BB_GAIN_FORCE_MAX_GAINS_B0_GAIN_FORCE_MASK                                        0x00200000
-#define PHY_BB_GAIN_FORCE_MAX_GAINS_B0_GAIN_FORCE_GET(x)                      (((x) & 0x00200000) >> 21)
-#define PHY_BB_GAIN_FORCE_MAX_GAINS_B0_GAIN_FORCE_SET(x)                      (((x) << 21) & 0x00200000)
-#define PHY_BB_GAIN_FORCE_MAX_GAINS_B0_ENABLE_SHARED_RX_MSB                                           31
-#define PHY_BB_GAIN_FORCE_MAX_GAINS_B0_ENABLE_SHARED_RX_LSB                                           31
-#define PHY_BB_GAIN_FORCE_MAX_GAINS_B0_ENABLE_SHARED_RX_MASK                                  0x80000000
-#define PHY_BB_GAIN_FORCE_MAX_GAINS_B0_ENABLE_SHARED_RX_GET(x)                (((x) & 0x80000000) >> 31)
-#define PHY_BB_GAIN_FORCE_MAX_GAINS_B0_ENABLE_SHARED_RX_SET(x)                (((x) << 31) & 0x80000000)
-
-/* macros for BB_gains_min_offsets_b0 */
-#define PHY_BB_GAINS_MIN_OFFSETS_B0_ADDRESS                                                   0x0000984c
-#define PHY_BB_GAINS_MIN_OFFSETS_B0_OFFSET                                                    0x0000984c
-#define PHY_BB_GAINS_MIN_OFFSETS_B0_OFFSETC1_MSB                                                       6
-#define PHY_BB_GAINS_MIN_OFFSETS_B0_OFFSETC1_LSB                                                       0
-#define PHY_BB_GAINS_MIN_OFFSETS_B0_OFFSETC1_MASK                                             0x0000007f
-#define PHY_BB_GAINS_MIN_OFFSETS_B0_OFFSETC1_GET(x)                            (((x) & 0x0000007f) >> 0)
-#define PHY_BB_GAINS_MIN_OFFSETS_B0_OFFSETC1_SET(x)                            (((x) << 0) & 0x0000007f)
-#define PHY_BB_GAINS_MIN_OFFSETS_B0_OFFSETC2_MSB                                                      11
-#define PHY_BB_GAINS_MIN_OFFSETS_B0_OFFSETC2_LSB                                                       7
-#define PHY_BB_GAINS_MIN_OFFSETS_B0_OFFSETC2_MASK                                             0x00000f80
-#define PHY_BB_GAINS_MIN_OFFSETS_B0_OFFSETC2_GET(x)                            (((x) & 0x00000f80) >> 7)
-#define PHY_BB_GAINS_MIN_OFFSETS_B0_OFFSETC2_SET(x)                            (((x) << 7) & 0x00000f80)
-#define PHY_BB_GAINS_MIN_OFFSETS_B0_OFFSETC3_MSB                                                      16
-#define PHY_BB_GAINS_MIN_OFFSETS_B0_OFFSETC3_LSB                                                      12
-#define PHY_BB_GAINS_MIN_OFFSETS_B0_OFFSETC3_MASK                                             0x0001f000
-#define PHY_BB_GAINS_MIN_OFFSETS_B0_OFFSETC3_GET(x)                           (((x) & 0x0001f000) >> 12)
-#define PHY_BB_GAINS_MIN_OFFSETS_B0_OFFSETC3_SET(x)                           (((x) << 12) & 0x0001f000)
-#define PHY_BB_GAINS_MIN_OFFSETS_B0_RF_GAIN_F_0_MSB                                                   24
-#define PHY_BB_GAINS_MIN_OFFSETS_B0_RF_GAIN_F_0_LSB                                                   17
-#define PHY_BB_GAINS_MIN_OFFSETS_B0_RF_GAIN_F_0_MASK                                          0x01fe0000
-#define PHY_BB_GAINS_MIN_OFFSETS_B0_RF_GAIN_F_0_GET(x)                        (((x) & 0x01fe0000) >> 17)
-#define PHY_BB_GAINS_MIN_OFFSETS_B0_RF_GAIN_F_0_SET(x)                        (((x) << 17) & 0x01fe0000)
-#define PHY_BB_GAINS_MIN_OFFSETS_B0_XATTEN1_SW_F_0_MSB                                                25
-#define PHY_BB_GAINS_MIN_OFFSETS_B0_XATTEN1_SW_F_0_LSB                                                25
-#define PHY_BB_GAINS_MIN_OFFSETS_B0_XATTEN1_SW_F_0_MASK                                       0x02000000
-#define PHY_BB_GAINS_MIN_OFFSETS_B0_XATTEN1_SW_F_0_GET(x)                     (((x) & 0x02000000) >> 25)
-#define PHY_BB_GAINS_MIN_OFFSETS_B0_XATTEN1_SW_F_0_SET(x)                     (((x) << 25) & 0x02000000)
-#define PHY_BB_GAINS_MIN_OFFSETS_B0_XATTEN2_SW_F_0_MSB                                                26
-#define PHY_BB_GAINS_MIN_OFFSETS_B0_XATTEN2_SW_F_0_LSB                                                26
-#define PHY_BB_GAINS_MIN_OFFSETS_B0_XATTEN2_SW_F_0_MASK                                       0x04000000
-#define PHY_BB_GAINS_MIN_OFFSETS_B0_XATTEN2_SW_F_0_GET(x)                     (((x) & 0x04000000) >> 26)
-#define PHY_BB_GAINS_MIN_OFFSETS_B0_XATTEN2_SW_F_0_SET(x)                     (((x) << 26) & 0x04000000)
-
-/* macros for BB_desired_sigsize */
-#define PHY_BB_DESIRED_SIGSIZE_ADDRESS                                                        0x00009850
-#define PHY_BB_DESIRED_SIGSIZE_OFFSET                                                         0x00009850
-#define PHY_BB_DESIRED_SIGSIZE_ADC_DESIRED_SIZE_MSB                                                    7
-#define PHY_BB_DESIRED_SIGSIZE_ADC_DESIRED_SIZE_LSB                                                    0
-#define PHY_BB_DESIRED_SIGSIZE_ADC_DESIRED_SIZE_MASK                                          0x000000ff
-#define PHY_BB_DESIRED_SIGSIZE_ADC_DESIRED_SIZE_GET(x)                         (((x) & 0x000000ff) >> 0)
-#define PHY_BB_DESIRED_SIGSIZE_ADC_DESIRED_SIZE_SET(x)                         (((x) << 0) & 0x000000ff)
-#define PHY_BB_DESIRED_SIGSIZE_TOTAL_DESIRED_MSB                                                      27
-#define PHY_BB_DESIRED_SIGSIZE_TOTAL_DESIRED_LSB                                                      20
-#define PHY_BB_DESIRED_SIGSIZE_TOTAL_DESIRED_MASK                                             0x0ff00000
-#define PHY_BB_DESIRED_SIGSIZE_TOTAL_DESIRED_GET(x)                           (((x) & 0x0ff00000) >> 20)
-#define PHY_BB_DESIRED_SIGSIZE_TOTAL_DESIRED_SET(x)                           (((x) << 20) & 0x0ff00000)
-#define PHY_BB_DESIRED_SIGSIZE_INIT_GC_COUNT_MAX_MSB                                                  29
-#define PHY_BB_DESIRED_SIGSIZE_INIT_GC_COUNT_MAX_LSB                                                  28
-#define PHY_BB_DESIRED_SIGSIZE_INIT_GC_COUNT_MAX_MASK                                         0x30000000
-#define PHY_BB_DESIRED_SIGSIZE_INIT_GC_COUNT_MAX_GET(x)                       (((x) & 0x30000000) >> 28)
-#define PHY_BB_DESIRED_SIGSIZE_INIT_GC_COUNT_MAX_SET(x)                       (((x) << 28) & 0x30000000)
-#define PHY_BB_DESIRED_SIGSIZE_REDUCE_INIT_GC_COUNT_MSB                                               30
-#define PHY_BB_DESIRED_SIGSIZE_REDUCE_INIT_GC_COUNT_LSB                                               30
-#define PHY_BB_DESIRED_SIGSIZE_REDUCE_INIT_GC_COUNT_MASK                                      0x40000000
-#define PHY_BB_DESIRED_SIGSIZE_REDUCE_INIT_GC_COUNT_GET(x)                    (((x) & 0x40000000) >> 30)
-#define PHY_BB_DESIRED_SIGSIZE_REDUCE_INIT_GC_COUNT_SET(x)                    (((x) << 30) & 0x40000000)
-#define PHY_BB_DESIRED_SIGSIZE_ENA_INIT_GAIN_MSB                                                      31
-#define PHY_BB_DESIRED_SIGSIZE_ENA_INIT_GAIN_LSB                                                      31
-#define PHY_BB_DESIRED_SIGSIZE_ENA_INIT_GAIN_MASK                                             0x80000000
-#define PHY_BB_DESIRED_SIGSIZE_ENA_INIT_GAIN_GET(x)                           (((x) & 0x80000000) >> 31)
-#define PHY_BB_DESIRED_SIGSIZE_ENA_INIT_GAIN_SET(x)                           (((x) << 31) & 0x80000000)
-
-/* macros for BB_timing_control_3a */
-#define PHY_BB_TIMING_CONTROL_3A_ADDRESS                                                      0x00009854
-#define PHY_BB_TIMING_CONTROL_3A_OFFSET                                                       0x00009854
-#define PHY_BB_TIMING_CONTROL_3A_STE_THR_HI_RSSI_MSB                                                   6
-#define PHY_BB_TIMING_CONTROL_3A_STE_THR_HI_RSSI_LSB                                                   0
-#define PHY_BB_TIMING_CONTROL_3A_STE_THR_HI_RSSI_MASK                                         0x0000007f
-#define PHY_BB_TIMING_CONTROL_3A_STE_THR_HI_RSSI_GET(x)                        (((x) & 0x0000007f) >> 0)
-#define PHY_BB_TIMING_CONTROL_3A_STE_THR_HI_RSSI_SET(x)                        (((x) << 0) & 0x0000007f)
-
-/* macros for BB_find_signal */
-#define PHY_BB_FIND_SIGNAL_ADDRESS                                                            0x00009858
-#define PHY_BB_FIND_SIGNAL_OFFSET                                                             0x00009858
-#define PHY_BB_FIND_SIGNAL_RELSTEP_MSB                                                                 5
-#define PHY_BB_FIND_SIGNAL_RELSTEP_LSB                                                                 0
-#define PHY_BB_FIND_SIGNAL_RELSTEP_MASK                                                       0x0000003f
-#define PHY_BB_FIND_SIGNAL_RELSTEP_GET(x)                                      (((x) & 0x0000003f) >> 0)
-#define PHY_BB_FIND_SIGNAL_RELSTEP_SET(x)                                      (((x) << 0) & 0x0000003f)
-#define PHY_BB_FIND_SIGNAL_RELPWR_MSB                                                                 11
-#define PHY_BB_FIND_SIGNAL_RELPWR_LSB                                                                  6
-#define PHY_BB_FIND_SIGNAL_RELPWR_MASK                                                        0x00000fc0
-#define PHY_BB_FIND_SIGNAL_RELPWR_GET(x)                                       (((x) & 0x00000fc0) >> 6)
-#define PHY_BB_FIND_SIGNAL_RELPWR_SET(x)                                       (((x) << 6) & 0x00000fc0)
-#define PHY_BB_FIND_SIGNAL_FIRSTEP_MSB                                                                17
-#define PHY_BB_FIND_SIGNAL_FIRSTEP_LSB                                                                12
-#define PHY_BB_FIND_SIGNAL_FIRSTEP_MASK                                                       0x0003f000
-#define PHY_BB_FIND_SIGNAL_FIRSTEP_GET(x)                                     (((x) & 0x0003f000) >> 12)
-#define PHY_BB_FIND_SIGNAL_FIRSTEP_SET(x)                                     (((x) << 12) & 0x0003f000)
-#define PHY_BB_FIND_SIGNAL_FIRPWR_MSB                                                                 25
-#define PHY_BB_FIND_SIGNAL_FIRPWR_LSB                                                                 18
-#define PHY_BB_FIND_SIGNAL_FIRPWR_MASK                                                        0x03fc0000
-#define PHY_BB_FIND_SIGNAL_FIRPWR_GET(x)                                      (((x) & 0x03fc0000) >> 18)
-#define PHY_BB_FIND_SIGNAL_FIRPWR_SET(x)                                      (((x) << 18) & 0x03fc0000)
-#define PHY_BB_FIND_SIGNAL_M1COUNT_MAX_MSB                                                            31
-#define PHY_BB_FIND_SIGNAL_M1COUNT_MAX_LSB                                                            26
-#define PHY_BB_FIND_SIGNAL_M1COUNT_MAX_MASK                                                   0xfc000000
-#define PHY_BB_FIND_SIGNAL_M1COUNT_MAX_GET(x)                                 (((x) & 0xfc000000) >> 26)
-#define PHY_BB_FIND_SIGNAL_M1COUNT_MAX_SET(x)                                 (((x) << 26) & 0xfc000000)
-
-/* macros for BB_agc */
-#define PHY_BB_AGC_ADDRESS                                                                    0x0000985c
-#define PHY_BB_AGC_OFFSET                                                                     0x0000985c
-#define PHY_BB_AGC_COARSEPWR_CONST_MSB                                                                 6
-#define PHY_BB_AGC_COARSEPWR_CONST_LSB                                                                 0
-#define PHY_BB_AGC_COARSEPWR_CONST_MASK                                                       0x0000007f
-#define PHY_BB_AGC_COARSEPWR_CONST_GET(x)                                      (((x) & 0x0000007f) >> 0)
-#define PHY_BB_AGC_COARSEPWR_CONST_SET(x)                                      (((x) << 0) & 0x0000007f)
-#define PHY_BB_AGC_COARSE_LOW_MSB                                                                     14
-#define PHY_BB_AGC_COARSE_LOW_LSB                                                                      7
-#define PHY_BB_AGC_COARSE_LOW_MASK                                                            0x00007f80
-#define PHY_BB_AGC_COARSE_LOW_GET(x)                                           (((x) & 0x00007f80) >> 7)
-#define PHY_BB_AGC_COARSE_LOW_SET(x)                                           (((x) << 7) & 0x00007f80)
-#define PHY_BB_AGC_COARSE_HIGH_MSB                                                                    21
-#define PHY_BB_AGC_COARSE_HIGH_LSB                                                                    15
-#define PHY_BB_AGC_COARSE_HIGH_MASK                                                           0x003f8000
-#define PHY_BB_AGC_COARSE_HIGH_GET(x)                                         (((x) & 0x003f8000) >> 15)
-#define PHY_BB_AGC_COARSE_HIGH_SET(x)                                         (((x) << 15) & 0x003f8000)
-#define PHY_BB_AGC_QUICK_DROP_MSB                                                                     29
-#define PHY_BB_AGC_QUICK_DROP_LSB                                                                     22
-#define PHY_BB_AGC_QUICK_DROP_MASK                                                            0x3fc00000
-#define PHY_BB_AGC_QUICK_DROP_GET(x)                                          (((x) & 0x3fc00000) >> 22)
-#define PHY_BB_AGC_QUICK_DROP_SET(x)                                          (((x) << 22) & 0x3fc00000)
-#define PHY_BB_AGC_RSSI_OUT_SELECT_MSB                                                                31
-#define PHY_BB_AGC_RSSI_OUT_SELECT_LSB                                                                30
-#define PHY_BB_AGC_RSSI_OUT_SELECT_MASK                                                       0xc0000000
-#define PHY_BB_AGC_RSSI_OUT_SELECT_GET(x)                                     (((x) & 0xc0000000) >> 30)
-#define PHY_BB_AGC_RSSI_OUT_SELECT_SET(x)                                     (((x) << 30) & 0xc0000000)
-
-/* macros for BB_agc_control */
-#define PHY_BB_AGC_CONTROL_ADDRESS                                                            0x00009860
-#define PHY_BB_AGC_CONTROL_OFFSET                                                             0x00009860
-#define PHY_BB_AGC_CONTROL_DO_CALIBRATE_MSB                                                            0
-#define PHY_BB_AGC_CONTROL_DO_CALIBRATE_LSB                                                            0
-#define PHY_BB_AGC_CONTROL_DO_CALIBRATE_MASK                                                  0x00000001
-#define PHY_BB_AGC_CONTROL_DO_CALIBRATE_GET(x)                                 (((x) & 0x00000001) >> 0)
-#define PHY_BB_AGC_CONTROL_DO_CALIBRATE_SET(x)                                 (((x) << 0) & 0x00000001)
-#define PHY_BB_AGC_CONTROL_DO_NOISEFLOOR_MSB                                                           1
-#define PHY_BB_AGC_CONTROL_DO_NOISEFLOOR_LSB                                                           1
-#define PHY_BB_AGC_CONTROL_DO_NOISEFLOOR_MASK                                                 0x00000002
-#define PHY_BB_AGC_CONTROL_DO_NOISEFLOOR_GET(x)                                (((x) & 0x00000002) >> 1)
-#define PHY_BB_AGC_CONTROL_DO_NOISEFLOOR_SET(x)                                (((x) << 1) & 0x00000002)
-#define PHY_BB_AGC_CONTROL_MIN_NUM_GAIN_CHANGE_MSB                                                     5
-#define PHY_BB_AGC_CONTROL_MIN_NUM_GAIN_CHANGE_LSB                                                     3
-#define PHY_BB_AGC_CONTROL_MIN_NUM_GAIN_CHANGE_MASK                                           0x00000038
-#define PHY_BB_AGC_CONTROL_MIN_NUM_GAIN_CHANGE_GET(x)                          (((x) & 0x00000038) >> 3)
-#define PHY_BB_AGC_CONTROL_MIN_NUM_GAIN_CHANGE_SET(x)                          (((x) << 3) & 0x00000038)
-#define PHY_BB_AGC_CONTROL_YCOK_MAX_MSB                                                                9
-#define PHY_BB_AGC_CONTROL_YCOK_MAX_LSB                                                                6
-#define PHY_BB_AGC_CONTROL_YCOK_MAX_MASK                                                      0x000003c0
-#define PHY_BB_AGC_CONTROL_YCOK_MAX_GET(x)                                     (((x) & 0x000003c0) >> 6)
-#define PHY_BB_AGC_CONTROL_YCOK_MAX_SET(x)                                     (((x) << 6) & 0x000003c0)
-#define PHY_BB_AGC_CONTROL_LEAKY_BUCKET_ENABLE_MSB                                                    10
-#define PHY_BB_AGC_CONTROL_LEAKY_BUCKET_ENABLE_LSB                                                    10
-#define PHY_BB_AGC_CONTROL_LEAKY_BUCKET_ENABLE_MASK                                           0x00000400
-#define PHY_BB_AGC_CONTROL_LEAKY_BUCKET_ENABLE_GET(x)                         (((x) & 0x00000400) >> 10)
-#define PHY_BB_AGC_CONTROL_LEAKY_BUCKET_ENABLE_SET(x)                         (((x) << 10) & 0x00000400)
-#define PHY_BB_AGC_CONTROL_CAL_ENABLE_MSB                                                             11
-#define PHY_BB_AGC_CONTROL_CAL_ENABLE_LSB                                                             11
-#define PHY_BB_AGC_CONTROL_CAL_ENABLE_MASK                                                    0x00000800
-#define PHY_BB_AGC_CONTROL_CAL_ENABLE_GET(x)                                  (((x) & 0x00000800) >> 11)
-#define PHY_BB_AGC_CONTROL_CAL_ENABLE_SET(x)                                  (((x) << 11) & 0x00000800)
-#define PHY_BB_AGC_CONTROL_USE_TABLE_SEED_MSB                                                         12
-#define PHY_BB_AGC_CONTROL_USE_TABLE_SEED_LSB                                                         12
-#define PHY_BB_AGC_CONTROL_USE_TABLE_SEED_MASK                                                0x00001000
-#define PHY_BB_AGC_CONTROL_USE_TABLE_SEED_GET(x)                              (((x) & 0x00001000) >> 12)
-#define PHY_BB_AGC_CONTROL_USE_TABLE_SEED_SET(x)                              (((x) << 12) & 0x00001000)
-#define PHY_BB_AGC_CONTROL_AGC_UPDATE_TABLE_SEED_MSB                                                  13
-#define PHY_BB_AGC_CONTROL_AGC_UPDATE_TABLE_SEED_LSB                                                  13
-#define PHY_BB_AGC_CONTROL_AGC_UPDATE_TABLE_SEED_MASK                                         0x00002000
-#define PHY_BB_AGC_CONTROL_AGC_UPDATE_TABLE_SEED_GET(x)                       (((x) & 0x00002000) >> 13)
-#define PHY_BB_AGC_CONTROL_AGC_UPDATE_TABLE_SEED_SET(x)                       (((x) << 13) & 0x00002000)
-#define PHY_BB_AGC_CONTROL_ENABLE_NOISEFLOOR_MSB                                                      15
-#define PHY_BB_AGC_CONTROL_ENABLE_NOISEFLOOR_LSB                                                      15
-#define PHY_BB_AGC_CONTROL_ENABLE_NOISEFLOOR_MASK                                             0x00008000
-#define PHY_BB_AGC_CONTROL_ENABLE_NOISEFLOOR_GET(x)                           (((x) & 0x00008000) >> 15)
-#define PHY_BB_AGC_CONTROL_ENABLE_NOISEFLOOR_SET(x)                           (((x) << 15) & 0x00008000)
-#define PHY_BB_AGC_CONTROL_ENABLE_FLTR_CAL_MSB                                                        16
-#define PHY_BB_AGC_CONTROL_ENABLE_FLTR_CAL_LSB                                                        16
-#define PHY_BB_AGC_CONTROL_ENABLE_FLTR_CAL_MASK                                               0x00010000
-#define PHY_BB_AGC_CONTROL_ENABLE_FLTR_CAL_GET(x)                             (((x) & 0x00010000) >> 16)
-#define PHY_BB_AGC_CONTROL_ENABLE_FLTR_CAL_SET(x)                             (((x) << 16) & 0x00010000)
-#define PHY_BB_AGC_CONTROL_NO_UPDATE_NOISEFLOOR_MSB                                                   17
-#define PHY_BB_AGC_CONTROL_NO_UPDATE_NOISEFLOOR_LSB                                                   17
-#define PHY_BB_AGC_CONTROL_NO_UPDATE_NOISEFLOOR_MASK                                          0x00020000
-#define PHY_BB_AGC_CONTROL_NO_UPDATE_NOISEFLOOR_GET(x)                        (((x) & 0x00020000) >> 17)
-#define PHY_BB_AGC_CONTROL_NO_UPDATE_NOISEFLOOR_SET(x)                        (((x) << 17) & 0x00020000)
-#define PHY_BB_AGC_CONTROL_EXTEND_NF_PWR_MEAS_MSB                                                     18
-#define PHY_BB_AGC_CONTROL_EXTEND_NF_PWR_MEAS_LSB                                                     18
-#define PHY_BB_AGC_CONTROL_EXTEND_NF_PWR_MEAS_MASK                                            0x00040000
-#define PHY_BB_AGC_CONTROL_EXTEND_NF_PWR_MEAS_GET(x)                          (((x) & 0x00040000) >> 18)
-#define PHY_BB_AGC_CONTROL_EXTEND_NF_PWR_MEAS_SET(x)                          (((x) << 18) & 0x00040000)
-#define PHY_BB_AGC_CONTROL_CLC_SUCCESS_MSB                                                            19
-#define PHY_BB_AGC_CONTROL_CLC_SUCCESS_LSB                                                            19
-#define PHY_BB_AGC_CONTROL_CLC_SUCCESS_MASK                                                   0x00080000
-#define PHY_BB_AGC_CONTROL_CLC_SUCCESS_GET(x)                                 (((x) & 0x00080000) >> 19)
-#define PHY_BB_AGC_CONTROL_ENABLE_PKDET_CAL_MSB                                                       20
-#define PHY_BB_AGC_CONTROL_ENABLE_PKDET_CAL_LSB                                                       20
-#define PHY_BB_AGC_CONTROL_ENABLE_PKDET_CAL_MASK                                              0x00100000
-#define PHY_BB_AGC_CONTROL_ENABLE_PKDET_CAL_GET(x)                            (((x) & 0x00100000) >> 20)
-#define PHY_BB_AGC_CONTROL_ENABLE_PKDET_CAL_SET(x)                            (((x) << 20) & 0x00100000)
-
-/* macros for BB_cca_b0 */
-#define PHY_BB_CCA_B0_ADDRESS                                                                 0x00009864
-#define PHY_BB_CCA_B0_OFFSET                                                                  0x00009864
-#define PHY_BB_CCA_B0_CF_MAXCCAPWR_0_MSB                                                               8
-#define PHY_BB_CCA_B0_CF_MAXCCAPWR_0_LSB                                                               0
-#define PHY_BB_CCA_B0_CF_MAXCCAPWR_0_MASK                                                     0x000001ff
-#define PHY_BB_CCA_B0_CF_MAXCCAPWR_0_GET(x)                                    (((x) & 0x000001ff) >> 0)
-#define PHY_BB_CCA_B0_CF_MAXCCAPWR_0_SET(x)                                    (((x) << 0) & 0x000001ff)
-#define PHY_BB_CCA_B0_CF_CCA_COUNT_MAXC_MSB                                                           11
-#define PHY_BB_CCA_B0_CF_CCA_COUNT_MAXC_LSB                                                            9
-#define PHY_BB_CCA_B0_CF_CCA_COUNT_MAXC_MASK                                                  0x00000e00
-#define PHY_BB_CCA_B0_CF_CCA_COUNT_MAXC_GET(x)                                 (((x) & 0x00000e00) >> 9)
-#define PHY_BB_CCA_B0_CF_CCA_COUNT_MAXC_SET(x)                                 (((x) << 9) & 0x00000e00)
-#define PHY_BB_CCA_B0_CF_THRESH62_MSB                                                                 19
-#define PHY_BB_CCA_B0_CF_THRESH62_LSB                                                                 12
-#define PHY_BB_CCA_B0_CF_THRESH62_MASK                                                        0x000ff000
-#define PHY_BB_CCA_B0_CF_THRESH62_GET(x)                                      (((x) & 0x000ff000) >> 12)
-#define PHY_BB_CCA_B0_CF_THRESH62_SET(x)                                      (((x) << 12) & 0x000ff000)
-#define PHY_BB_CCA_B0_MINCCAPWR_0_MSB                                                                 28
-#define PHY_BB_CCA_B0_MINCCAPWR_0_LSB                                                                 20
-#define PHY_BB_CCA_B0_MINCCAPWR_0_MASK                                                        0x1ff00000
-#define PHY_BB_CCA_B0_MINCCAPWR_0_GET(x)                                      (((x) & 0x1ff00000) >> 20)
-
-/* macros for BB_sfcorr */
-#define PHY_BB_SFCORR_ADDRESS                                                                 0x00009868
-#define PHY_BB_SFCORR_OFFSET                                                                  0x00009868
-#define PHY_BB_SFCORR_M2COUNT_THR_MSB                                                                  4
-#define PHY_BB_SFCORR_M2COUNT_THR_LSB                                                                  0
-#define PHY_BB_SFCORR_M2COUNT_THR_MASK                                                        0x0000001f
-#define PHY_BB_SFCORR_M2COUNT_THR_GET(x)                                       (((x) & 0x0000001f) >> 0)
-#define PHY_BB_SFCORR_M2COUNT_THR_SET(x)                                       (((x) << 0) & 0x0000001f)
-#define PHY_BB_SFCORR_ADCSAT_THRESH_MSB                                                               10
-#define PHY_BB_SFCORR_ADCSAT_THRESH_LSB                                                                5
-#define PHY_BB_SFCORR_ADCSAT_THRESH_MASK                                                      0x000007e0
-#define PHY_BB_SFCORR_ADCSAT_THRESH_GET(x)                                     (((x) & 0x000007e0) >> 5)
-#define PHY_BB_SFCORR_ADCSAT_THRESH_SET(x)                                     (((x) << 5) & 0x000007e0)
-#define PHY_BB_SFCORR_ADCSAT_ICOUNT_MSB                                                               16
-#define PHY_BB_SFCORR_ADCSAT_ICOUNT_LSB                                                               11
-#define PHY_BB_SFCORR_ADCSAT_ICOUNT_MASK                                                      0x0001f800
-#define PHY_BB_SFCORR_ADCSAT_ICOUNT_GET(x)                                    (((x) & 0x0001f800) >> 11)
-#define PHY_BB_SFCORR_ADCSAT_ICOUNT_SET(x)                                    (((x) << 11) & 0x0001f800)
-#define PHY_BB_SFCORR_M1_THRES_MSB                                                                    23
-#define PHY_BB_SFCORR_M1_THRES_LSB                                                                    17
-#define PHY_BB_SFCORR_M1_THRES_MASK                                                           0x00fe0000
-#define PHY_BB_SFCORR_M1_THRES_GET(x)                                         (((x) & 0x00fe0000) >> 17)
-#define PHY_BB_SFCORR_M1_THRES_SET(x)                                         (((x) << 17) & 0x00fe0000)
-#define PHY_BB_SFCORR_M2_THRES_MSB                                                                    30
-#define PHY_BB_SFCORR_M2_THRES_LSB                                                                    24
-#define PHY_BB_SFCORR_M2_THRES_MASK                                                           0x7f000000
-#define PHY_BB_SFCORR_M2_THRES_GET(x)                                         (((x) & 0x7f000000) >> 24)
-#define PHY_BB_SFCORR_M2_THRES_SET(x)                                         (((x) << 24) & 0x7f000000)
-
-/* macros for BB_self_corr_low */
-#define PHY_BB_SELF_CORR_LOW_ADDRESS                                                          0x0000986c
-#define PHY_BB_SELF_CORR_LOW_OFFSET                                                           0x0000986c
-#define PHY_BB_SELF_CORR_LOW_USE_SELF_CORR_LOW_MSB                                                     0
-#define PHY_BB_SELF_CORR_LOW_USE_SELF_CORR_LOW_LSB                                                     0
-#define PHY_BB_SELF_CORR_LOW_USE_SELF_CORR_LOW_MASK                                           0x00000001
-#define PHY_BB_SELF_CORR_LOW_USE_SELF_CORR_LOW_GET(x)                          (((x) & 0x00000001) >> 0)
-#define PHY_BB_SELF_CORR_LOW_USE_SELF_CORR_LOW_SET(x)                          (((x) << 0) & 0x00000001)
-#define PHY_BB_SELF_CORR_LOW_M1COUNT_MAX_LOW_MSB                                                       7
-#define PHY_BB_SELF_CORR_LOW_M1COUNT_MAX_LOW_LSB                                                       1
-#define PHY_BB_SELF_CORR_LOW_M1COUNT_MAX_LOW_MASK                                             0x000000fe
-#define PHY_BB_SELF_CORR_LOW_M1COUNT_MAX_LOW_GET(x)                            (((x) & 0x000000fe) >> 1)
-#define PHY_BB_SELF_CORR_LOW_M1COUNT_MAX_LOW_SET(x)                            (((x) << 1) & 0x000000fe)
-#define PHY_BB_SELF_CORR_LOW_M2COUNT_THR_LOW_MSB                                                      13
-#define PHY_BB_SELF_CORR_LOW_M2COUNT_THR_LOW_LSB                                                       8
-#define PHY_BB_SELF_CORR_LOW_M2COUNT_THR_LOW_MASK                                             0x00003f00
-#define PHY_BB_SELF_CORR_LOW_M2COUNT_THR_LOW_GET(x)                            (((x) & 0x00003f00) >> 8)
-#define PHY_BB_SELF_CORR_LOW_M2COUNT_THR_LOW_SET(x)                            (((x) << 8) & 0x00003f00)
-#define PHY_BB_SELF_CORR_LOW_M1_THRESH_LOW_MSB                                                        20
-#define PHY_BB_SELF_CORR_LOW_M1_THRESH_LOW_LSB                                                        14
-#define PHY_BB_SELF_CORR_LOW_M1_THRESH_LOW_MASK                                               0x001fc000
-#define PHY_BB_SELF_CORR_LOW_M1_THRESH_LOW_GET(x)                             (((x) & 0x001fc000) >> 14)
-#define PHY_BB_SELF_CORR_LOW_M1_THRESH_LOW_SET(x)                             (((x) << 14) & 0x001fc000)
-#define PHY_BB_SELF_CORR_LOW_M2_THRESH_LOW_MSB                                                        27
-#define PHY_BB_SELF_CORR_LOW_M2_THRESH_LOW_LSB                                                        21
-#define PHY_BB_SELF_CORR_LOW_M2_THRESH_LOW_MASK                                               0x0fe00000
-#define PHY_BB_SELF_CORR_LOW_M2_THRESH_LOW_GET(x)                             (((x) & 0x0fe00000) >> 21)
-#define PHY_BB_SELF_CORR_LOW_M2_THRESH_LOW_SET(x)                             (((x) << 21) & 0x0fe00000)
-
-/* macros for BB_synth_control */
-#define PHY_BB_SYNTH_CONTROL_ADDRESS                                                          0x00009874
-#define PHY_BB_SYNTH_CONTROL_OFFSET                                                           0x00009874
-#define PHY_BB_SYNTH_CONTROL_RFCHANFRAC_MSB                                                           16
-#define PHY_BB_SYNTH_CONTROL_RFCHANFRAC_LSB                                                            0
-#define PHY_BB_SYNTH_CONTROL_RFCHANFRAC_MASK                                                  0x0001ffff
-#define PHY_BB_SYNTH_CONTROL_RFCHANFRAC_GET(x)                                 (((x) & 0x0001ffff) >> 0)
-#define PHY_BB_SYNTH_CONTROL_RFCHANFRAC_SET(x)                                 (((x) << 0) & 0x0001ffff)
-#define PHY_BB_SYNTH_CONTROL_RFCHANNEL_MSB                                                            25
-#define PHY_BB_SYNTH_CONTROL_RFCHANNEL_LSB                                                            17
-#define PHY_BB_SYNTH_CONTROL_RFCHANNEL_MASK                                                   0x03fe0000
-#define PHY_BB_SYNTH_CONTROL_RFCHANNEL_GET(x)                                 (((x) & 0x03fe0000) >> 17)
-#define PHY_BB_SYNTH_CONTROL_RFCHANNEL_SET(x)                                 (((x) << 17) & 0x03fe0000)
-#define PHY_BB_SYNTH_CONTROL_RFAMODEREFSEL_MSB                                                        27
-#define PHY_BB_SYNTH_CONTROL_RFAMODEREFSEL_LSB                                                        26
-#define PHY_BB_SYNTH_CONTROL_RFAMODEREFSEL_MASK                                               0x0c000000
-#define PHY_BB_SYNTH_CONTROL_RFAMODEREFSEL_GET(x)                             (((x) & 0x0c000000) >> 26)
-#define PHY_BB_SYNTH_CONTROL_RFAMODEREFSEL_SET(x)                             (((x) << 26) & 0x0c000000)
-#define PHY_BB_SYNTH_CONTROL_RFFRACMODE_MSB                                                           28
-#define PHY_BB_SYNTH_CONTROL_RFFRACMODE_LSB                                                           28
-#define PHY_BB_SYNTH_CONTROL_RFFRACMODE_MASK                                                  0x10000000
-#define PHY_BB_SYNTH_CONTROL_RFFRACMODE_GET(x)                                (((x) & 0x10000000) >> 28)
-#define PHY_BB_SYNTH_CONTROL_RFFRACMODE_SET(x)                                (((x) << 28) & 0x10000000)
-#define PHY_BB_SYNTH_CONTROL_RFBMODE_MSB                                                              29
-#define PHY_BB_SYNTH_CONTROL_RFBMODE_LSB                                                              29
-#define PHY_BB_SYNTH_CONTROL_RFBMODE_MASK                                                     0x20000000
-#define PHY_BB_SYNTH_CONTROL_RFBMODE_GET(x)                                   (((x) & 0x20000000) >> 29)
-#define PHY_BB_SYNTH_CONTROL_RFBMODE_SET(x)                                   (((x) << 29) & 0x20000000)
-#define PHY_BB_SYNTH_CONTROL_RFSYNTH_CTRL_SSHIFT_MSB                                                  30
-#define PHY_BB_SYNTH_CONTROL_RFSYNTH_CTRL_SSHIFT_LSB                                                  30
-#define PHY_BB_SYNTH_CONTROL_RFSYNTH_CTRL_SSHIFT_MASK                                         0x40000000
-#define PHY_BB_SYNTH_CONTROL_RFSYNTH_CTRL_SSHIFT_GET(x)                       (((x) & 0x40000000) >> 30)
-#define PHY_BB_SYNTH_CONTROL_RFSYNTH_CTRL_SSHIFT_SET(x)                       (((x) << 30) & 0x40000000)
-
-/* macros for BB_addac_clk_select */
-#define PHY_BB_ADDAC_CLK_SELECT_ADDRESS                                                       0x00009878
-#define PHY_BB_ADDAC_CLK_SELECT_OFFSET                                                        0x00009878
-#define PHY_BB_ADDAC_CLK_SELECT_BB_DAC_CLK_SELECT_MSB                                                  3
-#define PHY_BB_ADDAC_CLK_SELECT_BB_DAC_CLK_SELECT_LSB                                                  2
-#define PHY_BB_ADDAC_CLK_SELECT_BB_DAC_CLK_SELECT_MASK                                        0x0000000c
-#define PHY_BB_ADDAC_CLK_SELECT_BB_DAC_CLK_SELECT_GET(x)                       (((x) & 0x0000000c) >> 2)
-#define PHY_BB_ADDAC_CLK_SELECT_BB_DAC_CLK_SELECT_SET(x)                       (((x) << 2) & 0x0000000c)
-#define PHY_BB_ADDAC_CLK_SELECT_BB_ADC_CLK_SELECT_MSB                                                  5
-#define PHY_BB_ADDAC_CLK_SELECT_BB_ADC_CLK_SELECT_LSB                                                  4
-#define PHY_BB_ADDAC_CLK_SELECT_BB_ADC_CLK_SELECT_MASK                                        0x00000030
-#define PHY_BB_ADDAC_CLK_SELECT_BB_ADC_CLK_SELECT_GET(x)                       (((x) & 0x00000030) >> 4)
-#define PHY_BB_ADDAC_CLK_SELECT_BB_ADC_CLK_SELECT_SET(x)                       (((x) << 4) & 0x00000030)
-
-/* macros for BB_pll_cntl */
-#define PHY_BB_PLL_CNTL_ADDRESS                                                               0x0000987c
-#define PHY_BB_PLL_CNTL_OFFSET                                                                0x0000987c
-#define PHY_BB_PLL_CNTL_BB_PLL_DIV_MSB                                                                 9
-#define PHY_BB_PLL_CNTL_BB_PLL_DIV_LSB                                                                 0
-#define PHY_BB_PLL_CNTL_BB_PLL_DIV_MASK                                                       0x000003ff
-#define PHY_BB_PLL_CNTL_BB_PLL_DIV_GET(x)                                      (((x) & 0x000003ff) >> 0)
-#define PHY_BB_PLL_CNTL_BB_PLL_DIV_SET(x)                                      (((x) << 0) & 0x000003ff)
-#define PHY_BB_PLL_CNTL_BB_PLL_REFDIV_MSB                                                             13
-#define PHY_BB_PLL_CNTL_BB_PLL_REFDIV_LSB                                                             10
-#define PHY_BB_PLL_CNTL_BB_PLL_REFDIV_MASK                                                    0x00003c00
-#define PHY_BB_PLL_CNTL_BB_PLL_REFDIV_GET(x)                                  (((x) & 0x00003c00) >> 10)
-#define PHY_BB_PLL_CNTL_BB_PLL_REFDIV_SET(x)                                  (((x) << 10) & 0x00003c00)
-#define PHY_BB_PLL_CNTL_BB_PLL_CLK_SEL_MSB                                                            15
-#define PHY_BB_PLL_CNTL_BB_PLL_CLK_SEL_LSB                                                            14
-#define PHY_BB_PLL_CNTL_BB_PLL_CLK_SEL_MASK                                                   0x0000c000
-#define PHY_BB_PLL_CNTL_BB_PLL_CLK_SEL_GET(x)                                 (((x) & 0x0000c000) >> 14)
-#define PHY_BB_PLL_CNTL_BB_PLL_CLK_SEL_SET(x)                                 (((x) << 14) & 0x0000c000)
-#define PHY_BB_PLL_CNTL_BB_PLLBYPASS_MSB                                                              16
-#define PHY_BB_PLL_CNTL_BB_PLLBYPASS_LSB                                                              16
-#define PHY_BB_PLL_CNTL_BB_PLLBYPASS_MASK                                                     0x00010000
-#define PHY_BB_PLL_CNTL_BB_PLLBYPASS_GET(x)                                   (((x) & 0x00010000) >> 16)
-#define PHY_BB_PLL_CNTL_BB_PLLBYPASS_SET(x)                                   (((x) << 16) & 0x00010000)
-#define PHY_BB_PLL_CNTL_BB_PLL_SETTLE_TIME_MSB                                                        27
-#define PHY_BB_PLL_CNTL_BB_PLL_SETTLE_TIME_LSB                                                        17
-#define PHY_BB_PLL_CNTL_BB_PLL_SETTLE_TIME_MASK                                               0x0ffe0000
-#define PHY_BB_PLL_CNTL_BB_PLL_SETTLE_TIME_GET(x)                             (((x) & 0x0ffe0000) >> 17)
-#define PHY_BB_PLL_CNTL_BB_PLL_SETTLE_TIME_SET(x)                             (((x) << 17) & 0x0ffe0000)
-
-/* macros for BB_vit_spur_mask_A */
-#define PHY_BB_VIT_SPUR_MASK_A_ADDRESS                                                        0x00009900
-#define PHY_BB_VIT_SPUR_MASK_A_OFFSET                                                         0x00009900
-#define PHY_BB_VIT_SPUR_MASK_A_CF_PUNC_MASK_A_MSB                                                      9
-#define PHY_BB_VIT_SPUR_MASK_A_CF_PUNC_MASK_A_LSB                                                      0
-#define PHY_BB_VIT_SPUR_MASK_A_CF_PUNC_MASK_A_MASK                                            0x000003ff
-#define PHY_BB_VIT_SPUR_MASK_A_CF_PUNC_MASK_A_GET(x)                           (((x) & 0x000003ff) >> 0)
-#define PHY_BB_VIT_SPUR_MASK_A_CF_PUNC_MASK_A_SET(x)                           (((x) << 0) & 0x000003ff)
-#define PHY_BB_VIT_SPUR_MASK_A_CF_PUNC_MASK_IDX_A_MSB                                                 16
-#define PHY_BB_VIT_SPUR_MASK_A_CF_PUNC_MASK_IDX_A_LSB                                                 10
-#define PHY_BB_VIT_SPUR_MASK_A_CF_PUNC_MASK_IDX_A_MASK                                        0x0001fc00
-#define PHY_BB_VIT_SPUR_MASK_A_CF_PUNC_MASK_IDX_A_GET(x)                      (((x) & 0x0001fc00) >> 10)
-#define PHY_BB_VIT_SPUR_MASK_A_CF_PUNC_MASK_IDX_A_SET(x)                      (((x) << 10) & 0x0001fc00)
-
-/* macros for BB_vit_spur_mask_B */
-#define PHY_BB_VIT_SPUR_MASK_B_ADDRESS                                                        0x00009904
-#define PHY_BB_VIT_SPUR_MASK_B_OFFSET                                                         0x00009904
-#define PHY_BB_VIT_SPUR_MASK_B_CF_PUNC_MASK_B_MSB                                                      9
-#define PHY_BB_VIT_SPUR_MASK_B_CF_PUNC_MASK_B_LSB                                                      0
-#define PHY_BB_VIT_SPUR_MASK_B_CF_PUNC_MASK_B_MASK                                            0x000003ff
-#define PHY_BB_VIT_SPUR_MASK_B_CF_PUNC_MASK_B_GET(x)                           (((x) & 0x000003ff) >> 0)
-#define PHY_BB_VIT_SPUR_MASK_B_CF_PUNC_MASK_B_SET(x)                           (((x) << 0) & 0x000003ff)
-#define PHY_BB_VIT_SPUR_MASK_B_CF_PUNC_MASK_IDX_B_MSB                                                 16
-#define PHY_BB_VIT_SPUR_MASK_B_CF_PUNC_MASK_IDX_B_LSB                                                 10
-#define PHY_BB_VIT_SPUR_MASK_B_CF_PUNC_MASK_IDX_B_MASK                                        0x0001fc00
-#define PHY_BB_VIT_SPUR_MASK_B_CF_PUNC_MASK_IDX_B_GET(x)                      (((x) & 0x0001fc00) >> 10)
-#define PHY_BB_VIT_SPUR_MASK_B_CF_PUNC_MASK_IDX_B_SET(x)                      (((x) << 10) & 0x0001fc00)
-
-/* macros for BB_pilot_spur_mask */
-#define PHY_BB_PILOT_SPUR_MASK_ADDRESS                                                        0x00009908
-#define PHY_BB_PILOT_SPUR_MASK_OFFSET                                                         0x00009908
-#define PHY_BB_PILOT_SPUR_MASK_CF_PILOT_MASK_A_MSB                                                     4
-#define PHY_BB_PILOT_SPUR_MASK_CF_PILOT_MASK_A_LSB                                                     0
-#define PHY_BB_PILOT_SPUR_MASK_CF_PILOT_MASK_A_MASK                                           0x0000001f
-#define PHY_BB_PILOT_SPUR_MASK_CF_PILOT_MASK_A_GET(x)                          (((x) & 0x0000001f) >> 0)
-#define PHY_BB_PILOT_SPUR_MASK_CF_PILOT_MASK_A_SET(x)                          (((x) << 0) & 0x0000001f)
-#define PHY_BB_PILOT_SPUR_MASK_CF_PILOT_MASK_IDX_A_MSB                                                11
-#define PHY_BB_PILOT_SPUR_MASK_CF_PILOT_MASK_IDX_A_LSB                                                 5
-#define PHY_BB_PILOT_SPUR_MASK_CF_PILOT_MASK_IDX_A_MASK                                       0x00000fe0
-#define PHY_BB_PILOT_SPUR_MASK_CF_PILOT_MASK_IDX_A_GET(x)                      (((x) & 0x00000fe0) >> 5)
-#define PHY_BB_PILOT_SPUR_MASK_CF_PILOT_MASK_IDX_A_SET(x)                      (((x) << 5) & 0x00000fe0)
-#define PHY_BB_PILOT_SPUR_MASK_CF_PILOT_MASK_B_MSB                                                    16
-#define PHY_BB_PILOT_SPUR_MASK_CF_PILOT_MASK_B_LSB                                                    12
-#define PHY_BB_PILOT_SPUR_MASK_CF_PILOT_MASK_B_MASK                                           0x0001f000
-#define PHY_BB_PILOT_SPUR_MASK_CF_PILOT_MASK_B_GET(x)                         (((x) & 0x0001f000) >> 12)
-#define PHY_BB_PILOT_SPUR_MASK_CF_PILOT_MASK_B_SET(x)                         (((x) << 12) & 0x0001f000)
-#define PHY_BB_PILOT_SPUR_MASK_CF_PILOT_MASK_IDX_B_MSB                                                23
-#define PHY_BB_PILOT_SPUR_MASK_CF_PILOT_MASK_IDX_B_LSB                                                17
-#define PHY_BB_PILOT_SPUR_MASK_CF_PILOT_MASK_IDX_B_MASK                                       0x00fe0000
-#define PHY_BB_PILOT_SPUR_MASK_CF_PILOT_MASK_IDX_B_GET(x)                     (((x) & 0x00fe0000) >> 17)
-#define PHY_BB_PILOT_SPUR_MASK_CF_PILOT_MASK_IDX_B_SET(x)                     (((x) << 17) & 0x00fe0000)
-
-/* macros for BB_chan_spur_mask */
-#define PHY_BB_CHAN_SPUR_MASK_ADDRESS                                                         0x0000990c
-#define PHY_BB_CHAN_SPUR_MASK_OFFSET                                                          0x0000990c
-#define PHY_BB_CHAN_SPUR_MASK_CF_CHAN_MASK_A_MSB                                                       4
-#define PHY_BB_CHAN_SPUR_MASK_CF_CHAN_MASK_A_LSB                                                       0
-#define PHY_BB_CHAN_SPUR_MASK_CF_CHAN_MASK_A_MASK                                             0x0000001f
-#define PHY_BB_CHAN_SPUR_MASK_CF_CHAN_MASK_A_GET(x)                            (((x) & 0x0000001f) >> 0)
-#define PHY_BB_CHAN_SPUR_MASK_CF_CHAN_MASK_A_SET(x)                            (((x) << 0) & 0x0000001f)
-#define PHY_BB_CHAN_SPUR_MASK_CF_CHAN_MASK_IDX_A_MSB                                                  11
-#define PHY_BB_CHAN_SPUR_MASK_CF_CHAN_MASK_IDX_A_LSB                                                   5
-#define PHY_BB_CHAN_SPUR_MASK_CF_CHAN_MASK_IDX_A_MASK                                         0x00000fe0
-#define PHY_BB_CHAN_SPUR_MASK_CF_CHAN_MASK_IDX_A_GET(x)                        (((x) & 0x00000fe0) >> 5)
-#define PHY_BB_CHAN_SPUR_MASK_CF_CHAN_MASK_IDX_A_SET(x)                        (((x) << 5) & 0x00000fe0)
-#define PHY_BB_CHAN_SPUR_MASK_CF_CHAN_MASK_B_MSB                                                      16
-#define PHY_BB_CHAN_SPUR_MASK_CF_CHAN_MASK_B_LSB                                                      12
-#define PHY_BB_CHAN_SPUR_MASK_CF_CHAN_MASK_B_MASK                                             0x0001f000
-#define PHY_BB_CHAN_SPUR_MASK_CF_CHAN_MASK_B_GET(x)                           (((x) & 0x0001f000) >> 12)
-#define PHY_BB_CHAN_SPUR_MASK_CF_CHAN_MASK_B_SET(x)                           (((x) << 12) & 0x0001f000)
-#define PHY_BB_CHAN_SPUR_MASK_CF_CHAN_MASK_IDX_B_MSB                                                  23
-#define PHY_BB_CHAN_SPUR_MASK_CF_CHAN_MASK_IDX_B_LSB                                                  17
-#define PHY_BB_CHAN_SPUR_MASK_CF_CHAN_MASK_IDX_B_MASK                                         0x00fe0000
-#define PHY_BB_CHAN_SPUR_MASK_CF_CHAN_MASK_IDX_B_GET(x)                       (((x) & 0x00fe0000) >> 17)
-#define PHY_BB_CHAN_SPUR_MASK_CF_CHAN_MASK_IDX_B_SET(x)                       (((x) << 17) & 0x00fe0000)
-
-/* macros for BB_spectral_scan */
-#define PHY_BB_SPECTRAL_SCAN_ADDRESS                                                          0x00009910
-#define PHY_BB_SPECTRAL_SCAN_OFFSET                                                           0x00009910
-#define PHY_BB_SPECTRAL_SCAN_SPECTRAL_SCAN_ENA_MSB                                                     0
-#define PHY_BB_SPECTRAL_SCAN_SPECTRAL_SCAN_ENA_LSB                                                     0
-#define PHY_BB_SPECTRAL_SCAN_SPECTRAL_SCAN_ENA_MASK                                           0x00000001
-#define PHY_BB_SPECTRAL_SCAN_SPECTRAL_SCAN_ENA_GET(x)                          (((x) & 0x00000001) >> 0)
-#define PHY_BB_SPECTRAL_SCAN_SPECTRAL_SCAN_ENA_SET(x)                          (((x) << 0) & 0x00000001)
-#define PHY_BB_SPECTRAL_SCAN_SPECTRAL_SCAN_ACTIVE_MSB                                                  1
-#define PHY_BB_SPECTRAL_SCAN_SPECTRAL_SCAN_ACTIVE_LSB                                                  1
-#define PHY_BB_SPECTRAL_SCAN_SPECTRAL_SCAN_ACTIVE_MASK                                        0x00000002
-#define PHY_BB_SPECTRAL_SCAN_SPECTRAL_SCAN_ACTIVE_GET(x)                       (((x) & 0x00000002) >> 1)
-#define PHY_BB_SPECTRAL_SCAN_SPECTRAL_SCAN_ACTIVE_SET(x)                       (((x) << 1) & 0x00000002)
-#define PHY_BB_SPECTRAL_SCAN_DISABLE_RADAR_TCTL_RST_MSB                                                2
-#define PHY_BB_SPECTRAL_SCAN_DISABLE_RADAR_TCTL_RST_LSB                                                2
-#define PHY_BB_SPECTRAL_SCAN_DISABLE_RADAR_TCTL_RST_MASK                                      0x00000004
-#define PHY_BB_SPECTRAL_SCAN_DISABLE_RADAR_TCTL_RST_GET(x)                     (((x) & 0x00000004) >> 2)
-#define PHY_BB_SPECTRAL_SCAN_DISABLE_RADAR_TCTL_RST_SET(x)                     (((x) << 2) & 0x00000004)
-#define PHY_BB_SPECTRAL_SCAN_DISABLE_PULSE_COARSE_LOW_MSB                                              3
-#define PHY_BB_SPECTRAL_SCAN_DISABLE_PULSE_COARSE_LOW_LSB                                              3
-#define PHY_BB_SPECTRAL_SCAN_DISABLE_PULSE_COARSE_LOW_MASK                                    0x00000008
-#define PHY_BB_SPECTRAL_SCAN_DISABLE_PULSE_COARSE_LOW_GET(x)                   (((x) & 0x00000008) >> 3)
-#define PHY_BB_SPECTRAL_SCAN_DISABLE_PULSE_COARSE_LOW_SET(x)                   (((x) << 3) & 0x00000008)
-#define PHY_BB_SPECTRAL_SCAN_SPECTRAL_SCAN_FFT_PERIOD_MSB                                              7
-#define PHY_BB_SPECTRAL_SCAN_SPECTRAL_SCAN_FFT_PERIOD_LSB                                              4
-#define PHY_BB_SPECTRAL_SCAN_SPECTRAL_SCAN_FFT_PERIOD_MASK                                    0x000000f0
-#define PHY_BB_SPECTRAL_SCAN_SPECTRAL_SCAN_FFT_PERIOD_GET(x)                   (((x) & 0x000000f0) >> 4)
-#define PHY_BB_SPECTRAL_SCAN_SPECTRAL_SCAN_FFT_PERIOD_SET(x)                   (((x) << 4) & 0x000000f0)
-#define PHY_BB_SPECTRAL_SCAN_SPECTRAL_SCAN_PERIOD_MSB                                                 15
-#define PHY_BB_SPECTRAL_SCAN_SPECTRAL_SCAN_PERIOD_LSB                                                  8
-#define PHY_BB_SPECTRAL_SCAN_SPECTRAL_SCAN_PERIOD_MASK                                        0x0000ff00
-#define PHY_BB_SPECTRAL_SCAN_SPECTRAL_SCAN_PERIOD_GET(x)                       (((x) & 0x0000ff00) >> 8)
-#define PHY_BB_SPECTRAL_SCAN_SPECTRAL_SCAN_PERIOD_SET(x)                       (((x) << 8) & 0x0000ff00)
-#define PHY_BB_SPECTRAL_SCAN_SPECTRAL_SCAN_COUNT_MSB                                                  27
-#define PHY_BB_SPECTRAL_SCAN_SPECTRAL_SCAN_COUNT_LSB                                                  16
-#define PHY_BB_SPECTRAL_SCAN_SPECTRAL_SCAN_COUNT_MASK                                         0x0fff0000
-#define PHY_BB_SPECTRAL_SCAN_SPECTRAL_SCAN_COUNT_GET(x)                       (((x) & 0x0fff0000) >> 16)
-#define PHY_BB_SPECTRAL_SCAN_SPECTRAL_SCAN_COUNT_SET(x)                       (((x) << 16) & 0x0fff0000)
-#define PHY_BB_SPECTRAL_SCAN_SPECTRAL_SCAN_SHORT_RPT_MSB                                              28
-#define PHY_BB_SPECTRAL_SCAN_SPECTRAL_SCAN_SHORT_RPT_LSB                                              28
-#define PHY_BB_SPECTRAL_SCAN_SPECTRAL_SCAN_SHORT_RPT_MASK                                     0x10000000
-#define PHY_BB_SPECTRAL_SCAN_SPECTRAL_SCAN_SHORT_RPT_GET(x)                   (((x) & 0x10000000) >> 28)
-#define PHY_BB_SPECTRAL_SCAN_SPECTRAL_SCAN_SHORT_RPT_SET(x)                   (((x) << 28) & 0x10000000)
-#define PHY_BB_SPECTRAL_SCAN_SPECTRAL_SCAN_PRIORITY_MSB                                               29
-#define PHY_BB_SPECTRAL_SCAN_SPECTRAL_SCAN_PRIORITY_LSB                                               29
-#define PHY_BB_SPECTRAL_SCAN_SPECTRAL_SCAN_PRIORITY_MASK                                      0x20000000
-#define PHY_BB_SPECTRAL_SCAN_SPECTRAL_SCAN_PRIORITY_GET(x)                    (((x) & 0x20000000) >> 29)
-#define PHY_BB_SPECTRAL_SCAN_SPECTRAL_SCAN_PRIORITY_SET(x)                    (((x) << 29) & 0x20000000)
-#define PHY_BB_SPECTRAL_SCAN_SPECTRAL_SCAN_USE_ERR5_MSB                                               30
-#define PHY_BB_SPECTRAL_SCAN_SPECTRAL_SCAN_USE_ERR5_LSB                                               30
-#define PHY_BB_SPECTRAL_SCAN_SPECTRAL_SCAN_USE_ERR5_MASK                                      0x40000000
-#define PHY_BB_SPECTRAL_SCAN_SPECTRAL_SCAN_USE_ERR5_GET(x)                    (((x) & 0x40000000) >> 30)
-#define PHY_BB_SPECTRAL_SCAN_SPECTRAL_SCAN_USE_ERR5_SET(x)                    (((x) << 30) & 0x40000000)
-
-/* macros for BB_analog_power_on_time */
-#define PHY_BB_ANALOG_POWER_ON_TIME_ADDRESS                                                   0x00009914
-#define PHY_BB_ANALOG_POWER_ON_TIME_OFFSET                                                    0x00009914
-#define PHY_BB_ANALOG_POWER_ON_TIME_ACTIVE_TO_RECEIVE_MSB                                             13
-#define PHY_BB_ANALOG_POWER_ON_TIME_ACTIVE_TO_RECEIVE_LSB                                              0
-#define PHY_BB_ANALOG_POWER_ON_TIME_ACTIVE_TO_RECEIVE_MASK                                    0x00003fff
-#define PHY_BB_ANALOG_POWER_ON_TIME_ACTIVE_TO_RECEIVE_GET(x)                   (((x) & 0x00003fff) >> 0)
-#define PHY_BB_ANALOG_POWER_ON_TIME_ACTIVE_TO_RECEIVE_SET(x)                   (((x) << 0) & 0x00003fff)
-
-/* macros for BB_search_start_delay */
-#define PHY_BB_SEARCH_START_DELAY_ADDRESS                                                     0x00009918
-#define PHY_BB_SEARCH_START_DELAY_OFFSET                                                      0x00009918
-#define PHY_BB_SEARCH_START_DELAY_SEARCH_START_DELAY_MSB                                              11
-#define PHY_BB_SEARCH_START_DELAY_SEARCH_START_DELAY_LSB                                               0
-#define PHY_BB_SEARCH_START_DELAY_SEARCH_START_DELAY_MASK                                     0x00000fff
-#define PHY_BB_SEARCH_START_DELAY_SEARCH_START_DELAY_GET(x)                    (((x) & 0x00000fff) >> 0)
-#define PHY_BB_SEARCH_START_DELAY_SEARCH_START_DELAY_SET(x)                    (((x) << 0) & 0x00000fff)
-#define PHY_BB_SEARCH_START_DELAY_ENABLE_FLT_SVD_MSB                                                  12
-#define PHY_BB_SEARCH_START_DELAY_ENABLE_FLT_SVD_LSB                                                  12
-#define PHY_BB_SEARCH_START_DELAY_ENABLE_FLT_SVD_MASK                                         0x00001000
-#define PHY_BB_SEARCH_START_DELAY_ENABLE_FLT_SVD_GET(x)                       (((x) & 0x00001000) >> 12)
-#define PHY_BB_SEARCH_START_DELAY_ENABLE_FLT_SVD_SET(x)                       (((x) << 12) & 0x00001000)
-#define PHY_BB_SEARCH_START_DELAY_ENABLE_SEND_CHAN_MSB                                                13
-#define PHY_BB_SEARCH_START_DELAY_ENABLE_SEND_CHAN_LSB                                                13
-#define PHY_BB_SEARCH_START_DELAY_ENABLE_SEND_CHAN_MASK                                       0x00002000
-#define PHY_BB_SEARCH_START_DELAY_ENABLE_SEND_CHAN_GET(x)                     (((x) & 0x00002000) >> 13)
-#define PHY_BB_SEARCH_START_DELAY_ENABLE_SEND_CHAN_SET(x)                     (((x) << 13) & 0x00002000)
-
-/* macros for BB_max_rx_length */
-#define PHY_BB_MAX_RX_LENGTH_ADDRESS                                                          0x0000991c
-#define PHY_BB_MAX_RX_LENGTH_OFFSET                                                           0x0000991c
-#define PHY_BB_MAX_RX_LENGTH_MAX_RX_LENGTH_MSB                                                        11
-#define PHY_BB_MAX_RX_LENGTH_MAX_RX_LENGTH_LSB                                                         0
-#define PHY_BB_MAX_RX_LENGTH_MAX_RX_LENGTH_MASK                                               0x00000fff
-#define PHY_BB_MAX_RX_LENGTH_MAX_RX_LENGTH_GET(x)                              (((x) & 0x00000fff) >> 0)
-#define PHY_BB_MAX_RX_LENGTH_MAX_RX_LENGTH_SET(x)                              (((x) << 0) & 0x00000fff)
-#define PHY_BB_MAX_RX_LENGTH_MAX_HT_LENGTH_MSB                                                        29
-#define PHY_BB_MAX_RX_LENGTH_MAX_HT_LENGTH_LSB                                                        12
-#define PHY_BB_MAX_RX_LENGTH_MAX_HT_LENGTH_MASK                                               0x3ffff000
-#define PHY_BB_MAX_RX_LENGTH_MAX_HT_LENGTH_GET(x)                             (((x) & 0x3ffff000) >> 12)
-#define PHY_BB_MAX_RX_LENGTH_MAX_HT_LENGTH_SET(x)                             (((x) << 12) & 0x3ffff000)
-
-/* macros for BB_timing_control_4 */
-#define PHY_BB_TIMING_CONTROL_4_ADDRESS                                                       0x00009920
-#define PHY_BB_TIMING_CONTROL_4_OFFSET                                                        0x00009920
-#define PHY_BB_TIMING_CONTROL_4_CAL_LG_COUNT_MAX_MSB                                                  15
-#define PHY_BB_TIMING_CONTROL_4_CAL_LG_COUNT_MAX_LSB                                                  12
-#define PHY_BB_TIMING_CONTROL_4_CAL_LG_COUNT_MAX_MASK                                         0x0000f000
-#define PHY_BB_TIMING_CONTROL_4_CAL_LG_COUNT_MAX_GET(x)                       (((x) & 0x0000f000) >> 12)
-#define PHY_BB_TIMING_CONTROL_4_CAL_LG_COUNT_MAX_SET(x)                       (((x) << 12) & 0x0000f000)
-#define PHY_BB_TIMING_CONTROL_4_DO_GAIN_DC_IQ_CAL_MSB                                                 16
-#define PHY_BB_TIMING_CONTROL_4_DO_GAIN_DC_IQ_CAL_LSB                                                 16
-#define PHY_BB_TIMING_CONTROL_4_DO_GAIN_DC_IQ_CAL_MASK                                        0x00010000
-#define PHY_BB_TIMING_CONTROL_4_DO_GAIN_DC_IQ_CAL_GET(x)                      (((x) & 0x00010000) >> 16)
-#define PHY_BB_TIMING_CONTROL_4_DO_GAIN_DC_IQ_CAL_SET(x)                      (((x) << 16) & 0x00010000)
-#define PHY_BB_TIMING_CONTROL_4_USE_PILOT_TRACK_DF_MSB                                                20
-#define PHY_BB_TIMING_CONTROL_4_USE_PILOT_TRACK_DF_LSB                                                17
-#define PHY_BB_TIMING_CONTROL_4_USE_PILOT_TRACK_DF_MASK                                       0x001e0000
-#define PHY_BB_TIMING_CONTROL_4_USE_PILOT_TRACK_DF_GET(x)                     (((x) & 0x001e0000) >> 17)
-#define PHY_BB_TIMING_CONTROL_4_USE_PILOT_TRACK_DF_SET(x)                     (((x) << 17) & 0x001e0000)
-#define PHY_BB_TIMING_CONTROL_4_EARLY_TRIGGER_THR_MSB                                                 27
-#define PHY_BB_TIMING_CONTROL_4_EARLY_TRIGGER_THR_LSB                                                 21
-#define PHY_BB_TIMING_CONTROL_4_EARLY_TRIGGER_THR_MASK                                        0x0fe00000
-#define PHY_BB_TIMING_CONTROL_4_EARLY_TRIGGER_THR_GET(x)                      (((x) & 0x0fe00000) >> 21)
-#define PHY_BB_TIMING_CONTROL_4_EARLY_TRIGGER_THR_SET(x)                      (((x) << 21) & 0x0fe00000)
-#define PHY_BB_TIMING_CONTROL_4_ENABLE_PILOT_MASK_MSB                                                 28
-#define PHY_BB_TIMING_CONTROL_4_ENABLE_PILOT_MASK_LSB                                                 28
-#define PHY_BB_TIMING_CONTROL_4_ENABLE_PILOT_MASK_MASK                                        0x10000000
-#define PHY_BB_TIMING_CONTROL_4_ENABLE_PILOT_MASK_GET(x)                      (((x) & 0x10000000) >> 28)
-#define PHY_BB_TIMING_CONTROL_4_ENABLE_PILOT_MASK_SET(x)                      (((x) << 28) & 0x10000000)
-#define PHY_BB_TIMING_CONTROL_4_ENABLE_CHAN_MASK_MSB                                                  29
-#define PHY_BB_TIMING_CONTROL_4_ENABLE_CHAN_MASK_LSB                                                  29
-#define PHY_BB_TIMING_CONTROL_4_ENABLE_CHAN_MASK_MASK                                         0x20000000
-#define PHY_BB_TIMING_CONTROL_4_ENABLE_CHAN_MASK_GET(x)                       (((x) & 0x20000000) >> 29)
-#define PHY_BB_TIMING_CONTROL_4_ENABLE_CHAN_MASK_SET(x)                       (((x) << 29) & 0x20000000)
-#define PHY_BB_TIMING_CONTROL_4_ENABLE_SPUR_FILTER_MSB                                                30
-#define PHY_BB_TIMING_CONTROL_4_ENABLE_SPUR_FILTER_LSB                                                30
-#define PHY_BB_TIMING_CONTROL_4_ENABLE_SPUR_FILTER_MASK                                       0x40000000
-#define PHY_BB_TIMING_CONTROL_4_ENABLE_SPUR_FILTER_GET(x)                     (((x) & 0x40000000) >> 30)
-#define PHY_BB_TIMING_CONTROL_4_ENABLE_SPUR_FILTER_SET(x)                     (((x) << 30) & 0x40000000)
-#define PHY_BB_TIMING_CONTROL_4_ENABLE_SPUR_RSSI_MSB                                                  31
-#define PHY_BB_TIMING_CONTROL_4_ENABLE_SPUR_RSSI_LSB                                                  31
-#define PHY_BB_TIMING_CONTROL_4_ENABLE_SPUR_RSSI_MASK                                         0x80000000
-#define PHY_BB_TIMING_CONTROL_4_ENABLE_SPUR_RSSI_GET(x)                       (((x) & 0x80000000) >> 31)
-#define PHY_BB_TIMING_CONTROL_4_ENABLE_SPUR_RSSI_SET(x)                       (((x) << 31) & 0x80000000)
-
-/* macros for BB_timing_control_5 */
-#define PHY_BB_TIMING_CONTROL_5_ADDRESS                                                       0x00009924
-#define PHY_BB_TIMING_CONTROL_5_OFFSET                                                        0x00009924
-#define PHY_BB_TIMING_CONTROL_5_ENABLE_CYCPWR_THR1_MSB                                                 0
-#define PHY_BB_TIMING_CONTROL_5_ENABLE_CYCPWR_THR1_LSB                                                 0
-#define PHY_BB_TIMING_CONTROL_5_ENABLE_CYCPWR_THR1_MASK                                       0x00000001
-#define PHY_BB_TIMING_CONTROL_5_ENABLE_CYCPWR_THR1_GET(x)                      (((x) & 0x00000001) >> 0)
-#define PHY_BB_TIMING_CONTROL_5_ENABLE_CYCPWR_THR1_SET(x)                      (((x) << 0) & 0x00000001)
-#define PHY_BB_TIMING_CONTROL_5_CYCPWR_THR1_MSB                                                        7
-#define PHY_BB_TIMING_CONTROL_5_CYCPWR_THR1_LSB                                                        1
-#define PHY_BB_TIMING_CONTROL_5_CYCPWR_THR1_MASK                                              0x000000fe
-#define PHY_BB_TIMING_CONTROL_5_CYCPWR_THR1_GET(x)                             (((x) & 0x000000fe) >> 1)
-#define PHY_BB_TIMING_CONTROL_5_CYCPWR_THR1_SET(x)                             (((x) << 1) & 0x000000fe)
-#define PHY_BB_TIMING_CONTROL_5_ENABLE_RSSI_THR1A_MSB                                                 15
-#define PHY_BB_TIMING_CONTROL_5_ENABLE_RSSI_THR1A_LSB                                                 15
-#define PHY_BB_TIMING_CONTROL_5_ENABLE_RSSI_THR1A_MASK                                        0x00008000
-#define PHY_BB_TIMING_CONTROL_5_ENABLE_RSSI_THR1A_GET(x)                      (((x) & 0x00008000) >> 15)
-#define PHY_BB_TIMING_CONTROL_5_ENABLE_RSSI_THR1A_SET(x)                      (((x) << 15) & 0x00008000)
-#define PHY_BB_TIMING_CONTROL_5_RSSI_THR1A_MSB                                                        22
-#define PHY_BB_TIMING_CONTROL_5_RSSI_THR1A_LSB                                                        16
-#define PHY_BB_TIMING_CONTROL_5_RSSI_THR1A_MASK                                               0x007f0000
-#define PHY_BB_TIMING_CONTROL_5_RSSI_THR1A_GET(x)                             (((x) & 0x007f0000) >> 16)
-#define PHY_BB_TIMING_CONTROL_5_RSSI_THR1A_SET(x)                             (((x) << 16) & 0x007f0000)
-#define PHY_BB_TIMING_CONTROL_5_LONG_SC_THRESH_HI_RSSI_MSB                                            29
-#define PHY_BB_TIMING_CONTROL_5_LONG_SC_THRESH_HI_RSSI_LSB                                            23
-#define PHY_BB_TIMING_CONTROL_5_LONG_SC_THRESH_HI_RSSI_MASK                                   0x3f800000
-#define PHY_BB_TIMING_CONTROL_5_LONG_SC_THRESH_HI_RSSI_GET(x)                 (((x) & 0x3f800000) >> 23)
-#define PHY_BB_TIMING_CONTROL_5_LONG_SC_THRESH_HI_RSSI_SET(x)                 (((x) << 23) & 0x3f800000)
-#define PHY_BB_TIMING_CONTROL_5_FORCED_AGC_STR_PRI_MSB                                                30
-#define PHY_BB_TIMING_CONTROL_5_FORCED_AGC_STR_PRI_LSB                                                30
-#define PHY_BB_TIMING_CONTROL_5_FORCED_AGC_STR_PRI_MASK                                       0x40000000
-#define PHY_BB_TIMING_CONTROL_5_FORCED_AGC_STR_PRI_GET(x)                     (((x) & 0x40000000) >> 30)
-#define PHY_BB_TIMING_CONTROL_5_FORCED_AGC_STR_PRI_SET(x)                     (((x) << 30) & 0x40000000)
-#define PHY_BB_TIMING_CONTROL_5_FORCED_AGC_STR_PRI_EN_MSB                                             31
-#define PHY_BB_TIMING_CONTROL_5_FORCED_AGC_STR_PRI_EN_LSB                                             31
-#define PHY_BB_TIMING_CONTROL_5_FORCED_AGC_STR_PRI_EN_MASK                                    0x80000000
-#define PHY_BB_TIMING_CONTROL_5_FORCED_AGC_STR_PRI_EN_GET(x)                  (((x) & 0x80000000) >> 31)
-#define PHY_BB_TIMING_CONTROL_5_FORCED_AGC_STR_PRI_EN_SET(x)                  (((x) << 31) & 0x80000000)
-
-/* macros for BB_phyonly_warm_reset */
-#define PHY_BB_PHYONLY_WARM_RESET_ADDRESS                                                     0x00009928
-#define PHY_BB_PHYONLY_WARM_RESET_OFFSET                                                      0x00009928
-#define PHY_BB_PHYONLY_WARM_RESET_PHYONLY_RST_WARM_L_MSB                                               0
-#define PHY_BB_PHYONLY_WARM_RESET_PHYONLY_RST_WARM_L_LSB                                               0
-#define PHY_BB_PHYONLY_WARM_RESET_PHYONLY_RST_WARM_L_MASK                                     0x00000001
-#define PHY_BB_PHYONLY_WARM_RESET_PHYONLY_RST_WARM_L_GET(x)                    (((x) & 0x00000001) >> 0)
-#define PHY_BB_PHYONLY_WARM_RESET_PHYONLY_RST_WARM_L_SET(x)                    (((x) << 0) & 0x00000001)
-
-/* macros for BB_phyonly_control */
-#define PHY_BB_PHYONLY_CONTROL_ADDRESS                                                        0x0000992c
-#define PHY_BB_PHYONLY_CONTROL_OFFSET                                                         0x0000992c
-#define PHY_BB_PHYONLY_CONTROL_RX_DRAIN_RATE_MSB                                                       0
-#define PHY_BB_PHYONLY_CONTROL_RX_DRAIN_RATE_LSB                                                       0
-#define PHY_BB_PHYONLY_CONTROL_RX_DRAIN_RATE_MASK                                             0x00000001
-#define PHY_BB_PHYONLY_CONTROL_RX_DRAIN_RATE_GET(x)                            (((x) & 0x00000001) >> 0)
-#define PHY_BB_PHYONLY_CONTROL_RX_DRAIN_RATE_SET(x)                            (((x) << 0) & 0x00000001)
-#define PHY_BB_PHYONLY_CONTROL_LATE_TX_SIGNAL_SYMBOL_MSB                                               1
-#define PHY_BB_PHYONLY_CONTROL_LATE_TX_SIGNAL_SYMBOL_LSB                                               1
-#define PHY_BB_PHYONLY_CONTROL_LATE_TX_SIGNAL_SYMBOL_MASK                                     0x00000002
-#define PHY_BB_PHYONLY_CONTROL_LATE_TX_SIGNAL_SYMBOL_GET(x)                    (((x) & 0x00000002) >> 1)
-#define PHY_BB_PHYONLY_CONTROL_LATE_TX_SIGNAL_SYMBOL_SET(x)                    (((x) << 1) & 0x00000002)
-#define PHY_BB_PHYONLY_CONTROL_GENERATE_SCRAMBLER_MSB                                                  2
-#define PHY_BB_PHYONLY_CONTROL_GENERATE_SCRAMBLER_LSB                                                  2
-#define PHY_BB_PHYONLY_CONTROL_GENERATE_SCRAMBLER_MASK                                        0x00000004
-#define PHY_BB_PHYONLY_CONTROL_GENERATE_SCRAMBLER_GET(x)                       (((x) & 0x00000004) >> 2)
-#define PHY_BB_PHYONLY_CONTROL_GENERATE_SCRAMBLER_SET(x)                       (((x) << 2) & 0x00000004)
-#define PHY_BB_PHYONLY_CONTROL_TX_ANTENNA_SELECT_MSB                                                   3
-#define PHY_BB_PHYONLY_CONTROL_TX_ANTENNA_SELECT_LSB                                                   3
-#define PHY_BB_PHYONLY_CONTROL_TX_ANTENNA_SELECT_MASK                                         0x00000008
-#define PHY_BB_PHYONLY_CONTROL_TX_ANTENNA_SELECT_GET(x)                        (((x) & 0x00000008) >> 3)
-#define PHY_BB_PHYONLY_CONTROL_TX_ANTENNA_SELECT_SET(x)                        (((x) << 3) & 0x00000008)
-#define PHY_BB_PHYONLY_CONTROL_STATIC_TX_ANTENNA_MSB                                                   4
-#define PHY_BB_PHYONLY_CONTROL_STATIC_TX_ANTENNA_LSB                                                   4
-#define PHY_BB_PHYONLY_CONTROL_STATIC_TX_ANTENNA_MASK                                         0x00000010
-#define PHY_BB_PHYONLY_CONTROL_STATIC_TX_ANTENNA_GET(x)                        (((x) & 0x00000010) >> 4)
-#define PHY_BB_PHYONLY_CONTROL_STATIC_TX_ANTENNA_SET(x)                        (((x) << 4) & 0x00000010)
-#define PHY_BB_PHYONLY_CONTROL_RX_ANTENNA_SELECT_MSB                                                   5
-#define PHY_BB_PHYONLY_CONTROL_RX_ANTENNA_SELECT_LSB                                                   5
-#define PHY_BB_PHYONLY_CONTROL_RX_ANTENNA_SELECT_MASK                                         0x00000020
-#define PHY_BB_PHYONLY_CONTROL_RX_ANTENNA_SELECT_GET(x)                        (((x) & 0x00000020) >> 5)
-#define PHY_BB_PHYONLY_CONTROL_RX_ANTENNA_SELECT_SET(x)                        (((x) << 5) & 0x00000020)
-#define PHY_BB_PHYONLY_CONTROL_STATIC_RX_ANTENNA_MSB                                                   6
-#define PHY_BB_PHYONLY_CONTROL_STATIC_RX_ANTENNA_LSB                                                   6
-#define PHY_BB_PHYONLY_CONTROL_STATIC_RX_ANTENNA_MASK                                         0x00000040
-#define PHY_BB_PHYONLY_CONTROL_STATIC_RX_ANTENNA_GET(x)                        (((x) & 0x00000040) >> 6)
-#define PHY_BB_PHYONLY_CONTROL_STATIC_RX_ANTENNA_SET(x)                        (((x) << 6) & 0x00000040)
-#define PHY_BB_PHYONLY_CONTROL_EN_LOW_FREQ_SLEEP_MSB                                                   7
-#define PHY_BB_PHYONLY_CONTROL_EN_LOW_FREQ_SLEEP_LSB                                                   7
-#define PHY_BB_PHYONLY_CONTROL_EN_LOW_FREQ_SLEEP_MASK                                         0x00000080
-#define PHY_BB_PHYONLY_CONTROL_EN_LOW_FREQ_SLEEP_GET(x)                        (((x) & 0x00000080) >> 7)
-#define PHY_BB_PHYONLY_CONTROL_EN_LOW_FREQ_SLEEP_SET(x)                        (((x) << 7) & 0x00000080)
-
-/* macros for BB_powertx_rate1 */
-#define PHY_BB_POWERTX_RATE1_ADDRESS                                                          0x00009934
-#define PHY_BB_POWERTX_RATE1_OFFSET                                                           0x00009934
-#define PHY_BB_POWERTX_RATE1_POWERTX_0_MSB                                                             5
-#define PHY_BB_POWERTX_RATE1_POWERTX_0_LSB                                                             0
-#define PHY_BB_POWERTX_RATE1_POWERTX_0_MASK                                                   0x0000003f
-#define PHY_BB_POWERTX_RATE1_POWERTX_0_GET(x)                                  (((x) & 0x0000003f) >> 0)
-#define PHY_BB_POWERTX_RATE1_POWERTX_0_SET(x)                                  (((x) << 0) & 0x0000003f)
-#define PHY_BB_POWERTX_RATE1_POWERTX_1_MSB                                                            13
-#define PHY_BB_POWERTX_RATE1_POWERTX_1_LSB                                                             8
-#define PHY_BB_POWERTX_RATE1_POWERTX_1_MASK                                                   0x00003f00
-#define PHY_BB_POWERTX_RATE1_POWERTX_1_GET(x)                                  (((x) & 0x00003f00) >> 8)
-#define PHY_BB_POWERTX_RATE1_POWERTX_1_SET(x)                                  (((x) << 8) & 0x00003f00)
-#define PHY_BB_POWERTX_RATE1_POWERTX_2_MSB                                                            21
-#define PHY_BB_POWERTX_RATE1_POWERTX_2_LSB                                                            16
-#define PHY_BB_POWERTX_RATE1_POWERTX_2_MASK                                                   0x003f0000
-#define PHY_BB_POWERTX_RATE1_POWERTX_2_GET(x)                                 (((x) & 0x003f0000) >> 16)
-#define PHY_BB_POWERTX_RATE1_POWERTX_2_SET(x)                                 (((x) << 16) & 0x003f0000)
-#define PHY_BB_POWERTX_RATE1_POWERTX_3_MSB                                                            29
-#define PHY_BB_POWERTX_RATE1_POWERTX_3_LSB                                                            24
-#define PHY_BB_POWERTX_RATE1_POWERTX_3_MASK                                                   0x3f000000
-#define PHY_BB_POWERTX_RATE1_POWERTX_3_GET(x)                                 (((x) & 0x3f000000) >> 24)
-#define PHY_BB_POWERTX_RATE1_POWERTX_3_SET(x)                                 (((x) << 24) & 0x3f000000)
-
-/* macros for BB_powertx_rate2 */
-#define PHY_BB_POWERTX_RATE2_ADDRESS                                                          0x00009938
-#define PHY_BB_POWERTX_RATE2_OFFSET                                                           0x00009938
-#define PHY_BB_POWERTX_RATE2_POWERTX_4_MSB                                                             5
-#define PHY_BB_POWERTX_RATE2_POWERTX_4_LSB                                                             0
-#define PHY_BB_POWERTX_RATE2_POWERTX_4_MASK                                                   0x0000003f
-#define PHY_BB_POWERTX_RATE2_POWERTX_4_GET(x)                                  (((x) & 0x0000003f) >> 0)
-#define PHY_BB_POWERTX_RATE2_POWERTX_4_SET(x)                                  (((x) << 0) & 0x0000003f)
-#define PHY_BB_POWERTX_RATE2_POWERTX_5_MSB                                                            13
-#define PHY_BB_POWERTX_RATE2_POWERTX_5_LSB                                                             8
-#define PHY_BB_POWERTX_RATE2_POWERTX_5_MASK                                                   0x00003f00
-#define PHY_BB_POWERTX_RATE2_POWERTX_5_GET(x)                                  (((x) & 0x00003f00) >> 8)
-#define PHY_BB_POWERTX_RATE2_POWERTX_5_SET(x)                                  (((x) << 8) & 0x00003f00)
-#define PHY_BB_POWERTX_RATE2_POWERTX_6_MSB                                                            21
-#define PHY_BB_POWERTX_RATE2_POWERTX_6_LSB                                                            16
-#define PHY_BB_POWERTX_RATE2_POWERTX_6_MASK                                                   0x003f0000
-#define PHY_BB_POWERTX_RATE2_POWERTX_6_GET(x)                                 (((x) & 0x003f0000) >> 16)
-#define PHY_BB_POWERTX_RATE2_POWERTX_6_SET(x)                                 (((x) << 16) & 0x003f0000)
-#define PHY_BB_POWERTX_RATE2_POWERTX_7_MSB                                                            29
-#define PHY_BB_POWERTX_RATE2_POWERTX_7_LSB                                                            24
-#define PHY_BB_POWERTX_RATE2_POWERTX_7_MASK                                                   0x3f000000
-#define PHY_BB_POWERTX_RATE2_POWERTX_7_GET(x)                                 (((x) & 0x3f000000) >> 24)
-#define PHY_BB_POWERTX_RATE2_POWERTX_7_SET(x)                                 (((x) << 24) & 0x3f000000)
-
-/* macros for BB_powertx_max */
-#define PHY_BB_POWERTX_MAX_ADDRESS                                                            0x0000993c
-#define PHY_BB_POWERTX_MAX_OFFSET                                                             0x0000993c
-#define PHY_BB_POWERTX_MAX_USE_PER_PACKET_POWERTX_MAX_MSB                                              6
-#define PHY_BB_POWERTX_MAX_USE_PER_PACKET_POWERTX_MAX_LSB                                              6
-#define PHY_BB_POWERTX_MAX_USE_PER_PACKET_POWERTX_MAX_MASK                                    0x00000040
-#define PHY_BB_POWERTX_MAX_USE_PER_PACKET_POWERTX_MAX_GET(x)                   (((x) & 0x00000040) >> 6)
-#define PHY_BB_POWERTX_MAX_USE_PER_PACKET_POWERTX_MAX_SET(x)                   (((x) << 6) & 0x00000040)
-
-/* macros for BB_extension_radar */
-#define PHY_BB_EXTENSION_RADAR_ADDRESS                                                        0x00009940
-#define PHY_BB_EXTENSION_RADAR_OFFSET                                                         0x00009940
-#define PHY_BB_EXTENSION_RADAR_BLOCKER40_MAX_RADAR_MSB                                                13
-#define PHY_BB_EXTENSION_RADAR_BLOCKER40_MAX_RADAR_LSB                                                 8
-#define PHY_BB_EXTENSION_RADAR_BLOCKER40_MAX_RADAR_MASK                                       0x00003f00
-#define PHY_BB_EXTENSION_RADAR_BLOCKER40_MAX_RADAR_GET(x)                      (((x) & 0x00003f00) >> 8)
-#define PHY_BB_EXTENSION_RADAR_BLOCKER40_MAX_RADAR_SET(x)                      (((x) << 8) & 0x00003f00)
-#define PHY_BB_EXTENSION_RADAR_ENABLE_EXT_RADAR_MSB                                                   14
-#define PHY_BB_EXTENSION_RADAR_ENABLE_EXT_RADAR_LSB                                                   14
-#define PHY_BB_EXTENSION_RADAR_ENABLE_EXT_RADAR_MASK                                          0x00004000
-#define PHY_BB_EXTENSION_RADAR_ENABLE_EXT_RADAR_GET(x)                        (((x) & 0x00004000) >> 14)
-#define PHY_BB_EXTENSION_RADAR_ENABLE_EXT_RADAR_SET(x)                        (((x) << 14) & 0x00004000)
-#define PHY_BB_EXTENSION_RADAR_RADAR_DC_PWR_THRESH_MSB                                                22
-#define PHY_BB_EXTENSION_RADAR_RADAR_DC_PWR_THRESH_LSB                                                15
-#define PHY_BB_EXTENSION_RADAR_RADAR_DC_PWR_THRESH_MASK                                       0x007f8000
-#define PHY_BB_EXTENSION_RADAR_RADAR_DC_PWR_THRESH_GET(x)                     (((x) & 0x007f8000) >> 15)
-#define PHY_BB_EXTENSION_RADAR_RADAR_DC_PWR_THRESH_SET(x)                     (((x) << 15) & 0x007f8000)
-#define PHY_BB_EXTENSION_RADAR_RADAR_LB_DC_CAP_MSB                                                    30
-#define PHY_BB_EXTENSION_RADAR_RADAR_LB_DC_CAP_LSB                                                    23
-#define PHY_BB_EXTENSION_RADAR_RADAR_LB_DC_CAP_MASK                                           0x7f800000
-#define PHY_BB_EXTENSION_RADAR_RADAR_LB_DC_CAP_GET(x)                         (((x) & 0x7f800000) >> 23)
-#define PHY_BB_EXTENSION_RADAR_RADAR_LB_DC_CAP_SET(x)                         (((x) << 23) & 0x7f800000)
-#define PHY_BB_EXTENSION_RADAR_DISABLE_ADCSAT_HOLD_MSB                                                31
-#define PHY_BB_EXTENSION_RADAR_DISABLE_ADCSAT_HOLD_LSB                                                31
-#define PHY_BB_EXTENSION_RADAR_DISABLE_ADCSAT_HOLD_MASK                                       0x80000000
-#define PHY_BB_EXTENSION_RADAR_DISABLE_ADCSAT_HOLD_GET(x)                     (((x) & 0x80000000) >> 31)
-#define PHY_BB_EXTENSION_RADAR_DISABLE_ADCSAT_HOLD_SET(x)                     (((x) << 31) & 0x80000000)
-
-/* macros for BB_frame_control */
-#define PHY_BB_FRAME_CONTROL_ADDRESS                                                          0x00009944
-#define PHY_BB_FRAME_CONTROL_OFFSET                                                           0x00009944
-#define PHY_BB_FRAME_CONTROL_CF_OVERLAP_WINDOW_MSB                                                     1
-#define PHY_BB_FRAME_CONTROL_CF_OVERLAP_WINDOW_LSB                                                     0
-#define PHY_BB_FRAME_CONTROL_CF_OVERLAP_WINDOW_MASK                                           0x00000003
-#define PHY_BB_FRAME_CONTROL_CF_OVERLAP_WINDOW_GET(x)                          (((x) & 0x00000003) >> 0)
-#define PHY_BB_FRAME_CONTROL_CF_OVERLAP_WINDOW_SET(x)                          (((x) << 0) & 0x00000003)
-#define PHY_BB_FRAME_CONTROL_CF_SCALE_SHORT_MSB                                                        2
-#define PHY_BB_FRAME_CONTROL_CF_SCALE_SHORT_LSB                                                        2
-#define PHY_BB_FRAME_CONTROL_CF_SCALE_SHORT_MASK                                              0x00000004
-#define PHY_BB_FRAME_CONTROL_CF_SCALE_SHORT_GET(x)                             (((x) & 0x00000004) >> 2)
-#define PHY_BB_FRAME_CONTROL_CF_SCALE_SHORT_SET(x)                             (((x) << 2) & 0x00000004)
-#define PHY_BB_FRAME_CONTROL_CF_TX_CLIP_MSB                                                            5
-#define PHY_BB_FRAME_CONTROL_CF_TX_CLIP_LSB                                                            3
-#define PHY_BB_FRAME_CONTROL_CF_TX_CLIP_MASK                                                  0x00000038
-#define PHY_BB_FRAME_CONTROL_CF_TX_CLIP_GET(x)                                 (((x) & 0x00000038) >> 3)
-#define PHY_BB_FRAME_CONTROL_CF_TX_CLIP_SET(x)                                 (((x) << 3) & 0x00000038)
-#define PHY_BB_FRAME_CONTROL_CF_TX_DOUBLESAMP_DAC_MSB                                                  7
-#define PHY_BB_FRAME_CONTROL_CF_TX_DOUBLESAMP_DAC_LSB                                                  6
-#define PHY_BB_FRAME_CONTROL_CF_TX_DOUBLESAMP_DAC_MASK                                        0x000000c0
-#define PHY_BB_FRAME_CONTROL_CF_TX_DOUBLESAMP_DAC_GET(x)                       (((x) & 0x000000c0) >> 6)
-#define PHY_BB_FRAME_CONTROL_CF_TX_DOUBLESAMP_DAC_SET(x)                       (((x) << 6) & 0x000000c0)
-#define PHY_BB_FRAME_CONTROL_TX_END_ADJUST_MSB                                                        15
-#define PHY_BB_FRAME_CONTROL_TX_END_ADJUST_LSB                                                         8
-#define PHY_BB_FRAME_CONTROL_TX_END_ADJUST_MASK                                               0x0000ff00
-#define PHY_BB_FRAME_CONTROL_TX_END_ADJUST_GET(x)                              (((x) & 0x0000ff00) >> 8)
-#define PHY_BB_FRAME_CONTROL_TX_END_ADJUST_SET(x)                              (((x) << 8) & 0x0000ff00)
-#define PHY_BB_FRAME_CONTROL_PREPEND_CHAN_INFO_MSB                                                    16
-#define PHY_BB_FRAME_CONTROL_PREPEND_CHAN_INFO_LSB                                                    16
-#define PHY_BB_FRAME_CONTROL_PREPEND_CHAN_INFO_MASK                                           0x00010000
-#define PHY_BB_FRAME_CONTROL_PREPEND_CHAN_INFO_GET(x)                         (((x) & 0x00010000) >> 16)
-#define PHY_BB_FRAME_CONTROL_PREPEND_CHAN_INFO_SET(x)                         (((x) << 16) & 0x00010000)
-#define PHY_BB_FRAME_CONTROL_SHORT_HIGH_PAR_NORM_MSB                                                  17
-#define PHY_BB_FRAME_CONTROL_SHORT_HIGH_PAR_NORM_LSB                                                  17
-#define PHY_BB_FRAME_CONTROL_SHORT_HIGH_PAR_NORM_MASK                                         0x00020000
-#define PHY_BB_FRAME_CONTROL_SHORT_HIGH_PAR_NORM_GET(x)                       (((x) & 0x00020000) >> 17)
-#define PHY_BB_FRAME_CONTROL_SHORT_HIGH_PAR_NORM_SET(x)                       (((x) << 17) & 0x00020000)
-#define PHY_BB_FRAME_CONTROL_EN_ERR_GREEN_FIELD_MSB                                                   18
-#define PHY_BB_FRAME_CONTROL_EN_ERR_GREEN_FIELD_LSB                                                   18
-#define PHY_BB_FRAME_CONTROL_EN_ERR_GREEN_FIELD_MASK                                          0x00040000
-#define PHY_BB_FRAME_CONTROL_EN_ERR_GREEN_FIELD_GET(x)                        (((x) & 0x00040000) >> 18)
-#define PHY_BB_FRAME_CONTROL_EN_ERR_GREEN_FIELD_SET(x)                        (((x) << 18) & 0x00040000)
-#define PHY_BB_FRAME_CONTROL_EN_ERR_XR_POWER_RATIO_MSB                                                19
-#define PHY_BB_FRAME_CONTROL_EN_ERR_XR_POWER_RATIO_LSB                                                19
-#define PHY_BB_FRAME_CONTROL_EN_ERR_XR_POWER_RATIO_MASK                                       0x00080000
-#define PHY_BB_FRAME_CONTROL_EN_ERR_XR_POWER_RATIO_GET(x)                     (((x) & 0x00080000) >> 19)
-#define PHY_BB_FRAME_CONTROL_EN_ERR_XR_POWER_RATIO_SET(x)                     (((x) << 19) & 0x00080000)
-#define PHY_BB_FRAME_CONTROL_EN_ERR_OFDM_XCORR_MSB                                                    20
-#define PHY_BB_FRAME_CONTROL_EN_ERR_OFDM_XCORR_LSB                                                    20
-#define PHY_BB_FRAME_CONTROL_EN_ERR_OFDM_XCORR_MASK                                           0x00100000
-#define PHY_BB_FRAME_CONTROL_EN_ERR_OFDM_XCORR_GET(x)                         (((x) & 0x00100000) >> 20)
-#define PHY_BB_FRAME_CONTROL_EN_ERR_OFDM_XCORR_SET(x)                         (((x) << 20) & 0x00100000)
-#define PHY_BB_FRAME_CONTROL_EN_ERR_LONG_SC_THR_MSB                                                   21
-#define PHY_BB_FRAME_CONTROL_EN_ERR_LONG_SC_THR_LSB                                                   21
-#define PHY_BB_FRAME_CONTROL_EN_ERR_LONG_SC_THR_MASK                                          0x00200000
-#define PHY_BB_FRAME_CONTROL_EN_ERR_LONG_SC_THR_GET(x)                        (((x) & 0x00200000) >> 21)
-#define PHY_BB_FRAME_CONTROL_EN_ERR_LONG_SC_THR_SET(x)                        (((x) << 21) & 0x00200000)
-#define PHY_BB_FRAME_CONTROL_EN_ERR_TIM_LONG1_MSB                                                     22
-#define PHY_BB_FRAME_CONTROL_EN_ERR_TIM_LONG1_LSB                                                     22
-#define PHY_BB_FRAME_CONTROL_EN_ERR_TIM_LONG1_MASK                                            0x00400000
-#define PHY_BB_FRAME_CONTROL_EN_ERR_TIM_LONG1_GET(x)                          (((x) & 0x00400000) >> 22)
-#define PHY_BB_FRAME_CONTROL_EN_ERR_TIM_LONG1_SET(x)                          (((x) << 22) & 0x00400000)
-#define PHY_BB_FRAME_CONTROL_EN_ERR_TIM_EARLY_TRIG_MSB                                                23
-#define PHY_BB_FRAME_CONTROL_EN_ERR_TIM_EARLY_TRIG_LSB                                                23
-#define PHY_BB_FRAME_CONTROL_EN_ERR_TIM_EARLY_TRIG_MASK                                       0x00800000
-#define PHY_BB_FRAME_CONTROL_EN_ERR_TIM_EARLY_TRIG_GET(x)                     (((x) & 0x00800000) >> 23)
-#define PHY_BB_FRAME_CONTROL_EN_ERR_TIM_EARLY_TRIG_SET(x)                     (((x) << 23) & 0x00800000)
-#define PHY_BB_FRAME_CONTROL_EN_ERR_TIM_TIMEOUT_MSB                                                   24
-#define PHY_BB_FRAME_CONTROL_EN_ERR_TIM_TIMEOUT_LSB                                                   24
-#define PHY_BB_FRAME_CONTROL_EN_ERR_TIM_TIMEOUT_MASK                                          0x01000000
-#define PHY_BB_FRAME_CONTROL_EN_ERR_TIM_TIMEOUT_GET(x)                        (((x) & 0x01000000) >> 24)
-#define PHY_BB_FRAME_CONTROL_EN_ERR_TIM_TIMEOUT_SET(x)                        (((x) << 24) & 0x01000000)
-#define PHY_BB_FRAME_CONTROL_EN_ERR_SIGNAL_PARITY_MSB                                                 25
-#define PHY_BB_FRAME_CONTROL_EN_ERR_SIGNAL_PARITY_LSB                                                 25
-#define PHY_BB_FRAME_CONTROL_EN_ERR_SIGNAL_PARITY_MASK                                        0x02000000
-#define PHY_BB_FRAME_CONTROL_EN_ERR_SIGNAL_PARITY_GET(x)                      (((x) & 0x02000000) >> 25)
-#define PHY_BB_FRAME_CONTROL_EN_ERR_SIGNAL_PARITY_SET(x)                      (((x) << 25) & 0x02000000)
-#define PHY_BB_FRAME_CONTROL_EN_ERR_RATE_ILLEGAL_MSB                                                  26
-#define PHY_BB_FRAME_CONTROL_EN_ERR_RATE_ILLEGAL_LSB                                                  26
-#define PHY_BB_FRAME_CONTROL_EN_ERR_RATE_ILLEGAL_MASK                                         0x04000000
-#define PHY_BB_FRAME_CONTROL_EN_ERR_RATE_ILLEGAL_GET(x)                       (((x) & 0x04000000) >> 26)
-#define PHY_BB_FRAME_CONTROL_EN_ERR_RATE_ILLEGAL_SET(x)                       (((x) << 26) & 0x04000000)
-#define PHY_BB_FRAME_CONTROL_EN_ERR_LENGTH_ILLEGAL_MSB                                                27
-#define PHY_BB_FRAME_CONTROL_EN_ERR_LENGTH_ILLEGAL_LSB                                                27
-#define PHY_BB_FRAME_CONTROL_EN_ERR_LENGTH_ILLEGAL_MASK                                       0x08000000
-#define PHY_BB_FRAME_CONTROL_EN_ERR_LENGTH_ILLEGAL_GET(x)                     (((x) & 0x08000000) >> 27)
-#define PHY_BB_FRAME_CONTROL_EN_ERR_LENGTH_ILLEGAL_SET(x)                     (((x) << 27) & 0x08000000)
-#define PHY_BB_FRAME_CONTROL_EN_ERR_HT_SERVICE_MSB                                                    28
-#define PHY_BB_FRAME_CONTROL_EN_ERR_HT_SERVICE_LSB                                                    28
-#define PHY_BB_FRAME_CONTROL_EN_ERR_HT_SERVICE_MASK                                           0x10000000
-#define PHY_BB_FRAME_CONTROL_EN_ERR_HT_SERVICE_GET(x)                         (((x) & 0x10000000) >> 28)
-#define PHY_BB_FRAME_CONTROL_EN_ERR_HT_SERVICE_SET(x)                         (((x) << 28) & 0x10000000)
-#define PHY_BB_FRAME_CONTROL_EN_ERR_SERVICE_MSB                                                       29
-#define PHY_BB_FRAME_CONTROL_EN_ERR_SERVICE_LSB                                                       29
-#define PHY_BB_FRAME_CONTROL_EN_ERR_SERVICE_MASK                                              0x20000000
-#define PHY_BB_FRAME_CONTROL_EN_ERR_SERVICE_GET(x)                            (((x) & 0x20000000) >> 29)
-#define PHY_BB_FRAME_CONTROL_EN_ERR_SERVICE_SET(x)                            (((x) << 29) & 0x20000000)
-#define PHY_BB_FRAME_CONTROL_EN_ERR_TX_UNDERRUN_MSB                                                   30
-#define PHY_BB_FRAME_CONTROL_EN_ERR_TX_UNDERRUN_LSB                                                   30
-#define PHY_BB_FRAME_CONTROL_EN_ERR_TX_UNDERRUN_MASK                                          0x40000000
-#define PHY_BB_FRAME_CONTROL_EN_ERR_TX_UNDERRUN_GET(x)                        (((x) & 0x40000000) >> 30)
-#define PHY_BB_FRAME_CONTROL_EN_ERR_TX_UNDERRUN_SET(x)                        (((x) << 30) & 0x40000000)
-#define PHY_BB_FRAME_CONTROL_EN_ERR_RX_ABORT_MSB                                                      31
-#define PHY_BB_FRAME_CONTROL_EN_ERR_RX_ABORT_LSB                                                      31
-#define PHY_BB_FRAME_CONTROL_EN_ERR_RX_ABORT_MASK                                             0x80000000
-#define PHY_BB_FRAME_CONTROL_EN_ERR_RX_ABORT_GET(x)                           (((x) & 0x80000000) >> 31)
-#define PHY_BB_FRAME_CONTROL_EN_ERR_RX_ABORT_SET(x)                           (((x) << 31) & 0x80000000)
-
-/* macros for BB_timing_control_6 */
-#define PHY_BB_TIMING_CONTROL_6_ADDRESS                                                       0x00009948
-#define PHY_BB_TIMING_CONTROL_6_OFFSET                                                        0x00009948
-#define PHY_BB_TIMING_CONTROL_6_HI_RSSI_THRESH_MSB                                                     7
-#define PHY_BB_TIMING_CONTROL_6_HI_RSSI_THRESH_LSB                                                     0
-#define PHY_BB_TIMING_CONTROL_6_HI_RSSI_THRESH_MASK                                           0x000000ff
-#define PHY_BB_TIMING_CONTROL_6_HI_RSSI_THRESH_GET(x)                          (((x) & 0x000000ff) >> 0)
-#define PHY_BB_TIMING_CONTROL_6_HI_RSSI_THRESH_SET(x)                          (((x) << 0) & 0x000000ff)
-#define PHY_BB_TIMING_CONTROL_6_EARLY_TRIGGER_THR_HI_RSSI_MSB                                         14
-#define PHY_BB_TIMING_CONTROL_6_EARLY_TRIGGER_THR_HI_RSSI_LSB                                          8
-#define PHY_BB_TIMING_CONTROL_6_EARLY_TRIGGER_THR_HI_RSSI_MASK                                0x00007f00
-#define PHY_BB_TIMING_CONTROL_6_EARLY_TRIGGER_THR_HI_RSSI_GET(x)               (((x) & 0x00007f00) >> 8)
-#define PHY_BB_TIMING_CONTROL_6_EARLY_TRIGGER_THR_HI_RSSI_SET(x)               (((x) << 8) & 0x00007f00)
-#define PHY_BB_TIMING_CONTROL_6_OFDM_XCORR_THRESH_MSB                                                 20
-#define PHY_BB_TIMING_CONTROL_6_OFDM_XCORR_THRESH_LSB                                                 15
-#define PHY_BB_TIMING_CONTROL_6_OFDM_XCORR_THRESH_MASK                                        0x001f8000
-#define PHY_BB_TIMING_CONTROL_6_OFDM_XCORR_THRESH_GET(x)                      (((x) & 0x001f8000) >> 15)
-#define PHY_BB_TIMING_CONTROL_6_OFDM_XCORR_THRESH_SET(x)                      (((x) << 15) & 0x001f8000)
-#define PHY_BB_TIMING_CONTROL_6_OFDM_XCORR_THRESH_HI_RSSI_MSB                                         27
-#define PHY_BB_TIMING_CONTROL_6_OFDM_XCORR_THRESH_HI_RSSI_LSB                                         21
-#define PHY_BB_TIMING_CONTROL_6_OFDM_XCORR_THRESH_HI_RSSI_MASK                                0x0fe00000
-#define PHY_BB_TIMING_CONTROL_6_OFDM_XCORR_THRESH_HI_RSSI_GET(x)              (((x) & 0x0fe00000) >> 21)
-#define PHY_BB_TIMING_CONTROL_6_OFDM_XCORR_THRESH_HI_RSSI_SET(x)              (((x) << 21) & 0x0fe00000)
-#define PHY_BB_TIMING_CONTROL_6_LONG_MEDIUM_RATIO_THR_MSB                                             31
-#define PHY_BB_TIMING_CONTROL_6_LONG_MEDIUM_RATIO_THR_LSB                                             28
-#define PHY_BB_TIMING_CONTROL_6_LONG_MEDIUM_RATIO_THR_MASK                                    0xf0000000
-#define PHY_BB_TIMING_CONTROL_6_LONG_MEDIUM_RATIO_THR_GET(x)                  (((x) & 0xf0000000) >> 28)
-#define PHY_BB_TIMING_CONTROL_6_LONG_MEDIUM_RATIO_THR_SET(x)                  (((x) << 28) & 0xf0000000)
-
-/* macros for BB_spur_mask_controls */
-#define PHY_BB_SPUR_MASK_CONTROLS_ADDRESS                                                     0x0000994c
-#define PHY_BB_SPUR_MASK_CONTROLS_OFFSET                                                      0x0000994c
-#define PHY_BB_SPUR_MASK_CONTROLS_SPUR_RSSI_THRESH_MSB                                                 7
-#define PHY_BB_SPUR_MASK_CONTROLS_SPUR_RSSI_THRESH_LSB                                                 0
-#define PHY_BB_SPUR_MASK_CONTROLS_SPUR_RSSI_THRESH_MASK                                       0x000000ff
-#define PHY_BB_SPUR_MASK_CONTROLS_SPUR_RSSI_THRESH_GET(x)                      (((x) & 0x000000ff) >> 0)
-#define PHY_BB_SPUR_MASK_CONTROLS_SPUR_RSSI_THRESH_SET(x)                      (((x) << 0) & 0x000000ff)
-#define PHY_BB_SPUR_MASK_CONTROLS_EN_VIT_SPUR_RSSI_MSB                                                 8
-#define PHY_BB_SPUR_MASK_CONTROLS_EN_VIT_SPUR_RSSI_LSB                                                 8
-#define PHY_BB_SPUR_MASK_CONTROLS_EN_VIT_SPUR_RSSI_MASK                                       0x00000100
-#define PHY_BB_SPUR_MASK_CONTROLS_EN_VIT_SPUR_RSSI_GET(x)                      (((x) & 0x00000100) >> 8)
-#define PHY_BB_SPUR_MASK_CONTROLS_EN_VIT_SPUR_RSSI_SET(x)                      (((x) << 8) & 0x00000100)
-#define PHY_BB_SPUR_MASK_CONTROLS_ENABLE_MASK_PPM_MSB                                                 17
-#define PHY_BB_SPUR_MASK_CONTROLS_ENABLE_MASK_PPM_LSB                                                 17
-#define PHY_BB_SPUR_MASK_CONTROLS_ENABLE_MASK_PPM_MASK                                        0x00020000
-#define PHY_BB_SPUR_MASK_CONTROLS_ENABLE_MASK_PPM_GET(x)                      (((x) & 0x00020000) >> 17)
-#define PHY_BB_SPUR_MASK_CONTROLS_ENABLE_MASK_PPM_SET(x)                      (((x) << 17) & 0x00020000)
-#define PHY_BB_SPUR_MASK_CONTROLS_MASK_RATE_CNTL_MSB                                                  25
-#define PHY_BB_SPUR_MASK_CONTROLS_MASK_RATE_CNTL_LSB                                                  18
-#define PHY_BB_SPUR_MASK_CONTROLS_MASK_RATE_CNTL_MASK                                         0x03fc0000
-#define PHY_BB_SPUR_MASK_CONTROLS_MASK_RATE_CNTL_GET(x)                       (((x) & 0x03fc0000) >> 18)
-#define PHY_BB_SPUR_MASK_CONTROLS_MASK_RATE_CNTL_SET(x)                       (((x) << 18) & 0x03fc0000)
-
-/* macros for BB_rx_iq_corr_b0 */
-#define PHY_BB_RX_IQ_CORR_B0_ADDRESS                                                          0x00009950
-#define PHY_BB_RX_IQ_CORR_B0_OFFSET                                                           0x00009950
-#define PHY_BB_RX_IQ_CORR_B0_RX_IQCORR_Q_Q_COFF_0_MSB                                                  6
-#define PHY_BB_RX_IQ_CORR_B0_RX_IQCORR_Q_Q_COFF_0_LSB                                                  0
-#define PHY_BB_RX_IQ_CORR_B0_RX_IQCORR_Q_Q_COFF_0_MASK                                        0x0000007f
-#define PHY_BB_RX_IQ_CORR_B0_RX_IQCORR_Q_Q_COFF_0_GET(x)                       (((x) & 0x0000007f) >> 0)
-#define PHY_BB_RX_IQ_CORR_B0_RX_IQCORR_Q_Q_COFF_0_SET(x)                       (((x) << 0) & 0x0000007f)
-#define PHY_BB_RX_IQ_CORR_B0_RX_IQCORR_Q_I_COFF_0_MSB                                                 13
-#define PHY_BB_RX_IQ_CORR_B0_RX_IQCORR_Q_I_COFF_0_LSB                                                  7
-#define PHY_BB_RX_IQ_CORR_B0_RX_IQCORR_Q_I_COFF_0_MASK                                        0x00003f80
-#define PHY_BB_RX_IQ_CORR_B0_RX_IQCORR_Q_I_COFF_0_GET(x)                       (((x) & 0x00003f80) >> 7)
-#define PHY_BB_RX_IQ_CORR_B0_RX_IQCORR_Q_I_COFF_0_SET(x)                       (((x) << 7) & 0x00003f80)
-#define PHY_BB_RX_IQ_CORR_B0_RX_IQCORR_ENABLE_MSB                                                     14
-#define PHY_BB_RX_IQ_CORR_B0_RX_IQCORR_ENABLE_LSB                                                     14
-#define PHY_BB_RX_IQ_CORR_B0_RX_IQCORR_ENABLE_MASK                                            0x00004000
-#define PHY_BB_RX_IQ_CORR_B0_RX_IQCORR_ENABLE_GET(x)                          (((x) & 0x00004000) >> 14)
-#define PHY_BB_RX_IQ_CORR_B0_RX_IQCORR_ENABLE_SET(x)                          (((x) << 14) & 0x00004000)
-#define PHY_BB_RX_IQ_CORR_B0_LOOPBACK_IQCORR_Q_Q_COFF_0_MSB                                           21
-#define PHY_BB_RX_IQ_CORR_B0_LOOPBACK_IQCORR_Q_Q_COFF_0_LSB                                           15
-#define PHY_BB_RX_IQ_CORR_B0_LOOPBACK_IQCORR_Q_Q_COFF_0_MASK                                  0x003f8000
-#define PHY_BB_RX_IQ_CORR_B0_LOOPBACK_IQCORR_Q_Q_COFF_0_GET(x)                (((x) & 0x003f8000) >> 15)
-#define PHY_BB_RX_IQ_CORR_B0_LOOPBACK_IQCORR_Q_Q_COFF_0_SET(x)                (((x) << 15) & 0x003f8000)
-#define PHY_BB_RX_IQ_CORR_B0_LOOPBACK_IQCORR_Q_I_COFF_0_MSB                                           28
-#define PHY_BB_RX_IQ_CORR_B0_LOOPBACK_IQCORR_Q_I_COFF_0_LSB                                           22
-#define PHY_BB_RX_IQ_CORR_B0_LOOPBACK_IQCORR_Q_I_COFF_0_MASK                                  0x1fc00000
-#define PHY_BB_RX_IQ_CORR_B0_LOOPBACK_IQCORR_Q_I_COFF_0_GET(x)                (((x) & 0x1fc00000) >> 22)
-#define PHY_BB_RX_IQ_CORR_B0_LOOPBACK_IQCORR_Q_I_COFF_0_SET(x)                (((x) << 22) & 0x1fc00000)
-#define PHY_BB_RX_IQ_CORR_B0_LOOPBACK_IQCORR_ENABLE_MSB                                               29
-#define PHY_BB_RX_IQ_CORR_B0_LOOPBACK_IQCORR_ENABLE_LSB                                               29
-#define PHY_BB_RX_IQ_CORR_B0_LOOPBACK_IQCORR_ENABLE_MASK                                      0x20000000
-#define PHY_BB_RX_IQ_CORR_B0_LOOPBACK_IQCORR_ENABLE_GET(x)                    (((x) & 0x20000000) >> 29)
-#define PHY_BB_RX_IQ_CORR_B0_LOOPBACK_IQCORR_ENABLE_SET(x)                    (((x) << 29) & 0x20000000)
-
-/* macros for BB_radar_detection */
-#define PHY_BB_RADAR_DETECTION_ADDRESS                                                        0x00009954
-#define PHY_BB_RADAR_DETECTION_OFFSET                                                         0x00009954
-#define PHY_BB_RADAR_DETECTION_PULSE_DETECT_ENABLE_MSB                                                 0
-#define PHY_BB_RADAR_DETECTION_PULSE_DETECT_ENABLE_LSB                                                 0
-#define PHY_BB_RADAR_DETECTION_PULSE_DETECT_ENABLE_MASK                                       0x00000001
-#define PHY_BB_RADAR_DETECTION_PULSE_DETECT_ENABLE_GET(x)                      (((x) & 0x00000001) >> 0)
-#define PHY_BB_RADAR_DETECTION_PULSE_DETECT_ENABLE_SET(x)                      (((x) << 0) & 0x00000001)
-#define PHY_BB_RADAR_DETECTION_PULSE_IN_BAND_THRESH_MSB                                                5
-#define PHY_BB_RADAR_DETECTION_PULSE_IN_BAND_THRESH_LSB                                                1
-#define PHY_BB_RADAR_DETECTION_PULSE_IN_BAND_THRESH_MASK                                      0x0000003e
-#define PHY_BB_RADAR_DETECTION_PULSE_IN_BAND_THRESH_GET(x)                     (((x) & 0x0000003e) >> 1)
-#define PHY_BB_RADAR_DETECTION_PULSE_IN_BAND_THRESH_SET(x)                     (((x) << 1) & 0x0000003e)
-#define PHY_BB_RADAR_DETECTION_PULSE_RSSI_THRESH_MSB                                                  11
-#define PHY_BB_RADAR_DETECTION_PULSE_RSSI_THRESH_LSB                                                   6
-#define PHY_BB_RADAR_DETECTION_PULSE_RSSI_THRESH_MASK                                         0x00000fc0
-#define PHY_BB_RADAR_DETECTION_PULSE_RSSI_THRESH_GET(x)                        (((x) & 0x00000fc0) >> 6)
-#define PHY_BB_RADAR_DETECTION_PULSE_RSSI_THRESH_SET(x)                        (((x) << 6) & 0x00000fc0)
-#define PHY_BB_RADAR_DETECTION_PULSE_HEIGHT_THRESH_MSB                                                17
-#define PHY_BB_RADAR_DETECTION_PULSE_HEIGHT_THRESH_LSB                                                12
-#define PHY_BB_RADAR_DETECTION_PULSE_HEIGHT_THRESH_MASK                                       0x0003f000
-#define PHY_BB_RADAR_DETECTION_PULSE_HEIGHT_THRESH_GET(x)                     (((x) & 0x0003f000) >> 12)
-#define PHY_BB_RADAR_DETECTION_PULSE_HEIGHT_THRESH_SET(x)                     (((x) << 12) & 0x0003f000)
-#define PHY_BB_RADAR_DETECTION_RADAR_RSSI_THRESH_MSB                                                  23
-#define PHY_BB_RADAR_DETECTION_RADAR_RSSI_THRESH_LSB                                                  18
-#define PHY_BB_RADAR_DETECTION_RADAR_RSSI_THRESH_MASK                                         0x00fc0000
-#define PHY_BB_RADAR_DETECTION_RADAR_RSSI_THRESH_GET(x)                       (((x) & 0x00fc0000) >> 18)
-#define PHY_BB_RADAR_DETECTION_RADAR_RSSI_THRESH_SET(x)                       (((x) << 18) & 0x00fc0000)
-#define PHY_BB_RADAR_DETECTION_RADAR_FIRPWR_THRESH_MSB                                                30
-#define PHY_BB_RADAR_DETECTION_RADAR_FIRPWR_THRESH_LSB                                                24
-#define PHY_BB_RADAR_DETECTION_RADAR_FIRPWR_THRESH_MASK                                       0x7f000000
-#define PHY_BB_RADAR_DETECTION_RADAR_FIRPWR_THRESH_GET(x)                     (((x) & 0x7f000000) >> 24)
-#define PHY_BB_RADAR_DETECTION_RADAR_FIRPWR_THRESH_SET(x)                     (((x) << 24) & 0x7f000000)
-#define PHY_BB_RADAR_DETECTION_ENABLE_RADAR_FFT_MSB                                                   31
-#define PHY_BB_RADAR_DETECTION_ENABLE_RADAR_FFT_LSB                                                   31
-#define PHY_BB_RADAR_DETECTION_ENABLE_RADAR_FFT_MASK                                          0x80000000
-#define PHY_BB_RADAR_DETECTION_ENABLE_RADAR_FFT_GET(x)                        (((x) & 0x80000000) >> 31)
-#define PHY_BB_RADAR_DETECTION_ENABLE_RADAR_FFT_SET(x)                        (((x) << 31) & 0x80000000)
-
-/* macros for BB_radar_detection_2 */
-#define PHY_BB_RADAR_DETECTION_2_ADDRESS                                                      0x00009958
-#define PHY_BB_RADAR_DETECTION_2_OFFSET                                                       0x00009958
-#define PHY_BB_RADAR_DETECTION_2_RADAR_LENGTH_MAX_MSB                                                  7
-#define PHY_BB_RADAR_DETECTION_2_RADAR_LENGTH_MAX_LSB                                                  0
-#define PHY_BB_RADAR_DETECTION_2_RADAR_LENGTH_MAX_MASK                                        0x000000ff
-#define PHY_BB_RADAR_DETECTION_2_RADAR_LENGTH_MAX_GET(x)                       (((x) & 0x000000ff) >> 0)
-#define PHY_BB_RADAR_DETECTION_2_RADAR_LENGTH_MAX_SET(x)                       (((x) << 0) & 0x000000ff)
-#define PHY_BB_RADAR_DETECTION_2_PULSE_RELSTEP_THRESH_MSB                                             12
-#define PHY_BB_RADAR_DETECTION_2_PULSE_RELSTEP_THRESH_LSB                                              8
-#define PHY_BB_RADAR_DETECTION_2_PULSE_RELSTEP_THRESH_MASK                                    0x00001f00
-#define PHY_BB_RADAR_DETECTION_2_PULSE_RELSTEP_THRESH_GET(x)                   (((x) & 0x00001f00) >> 8)
-#define PHY_BB_RADAR_DETECTION_2_PULSE_RELSTEP_THRESH_SET(x)                   (((x) << 8) & 0x00001f00)
-#define PHY_BB_RADAR_DETECTION_2_ENABLE_PULSE_RELSTEP_CHECK_MSB                                       13
-#define PHY_BB_RADAR_DETECTION_2_ENABLE_PULSE_RELSTEP_CHECK_LSB                                       13
-#define PHY_BB_RADAR_DETECTION_2_ENABLE_PULSE_RELSTEP_CHECK_MASK                              0x00002000
-#define PHY_BB_RADAR_DETECTION_2_ENABLE_PULSE_RELSTEP_CHECK_GET(x)            (((x) & 0x00002000) >> 13)
-#define PHY_BB_RADAR_DETECTION_2_ENABLE_PULSE_RELSTEP_CHECK_SET(x)            (((x) << 13) & 0x00002000)
-#define PHY_BB_RADAR_DETECTION_2_ENABLE_MAX_RADAR_RSSI_MSB                                            14
-#define PHY_BB_RADAR_DETECTION_2_ENABLE_MAX_RADAR_RSSI_LSB                                            14
-#define PHY_BB_RADAR_DETECTION_2_ENABLE_MAX_RADAR_RSSI_MASK                                   0x00004000
-#define PHY_BB_RADAR_DETECTION_2_ENABLE_MAX_RADAR_RSSI_GET(x)                 (((x) & 0x00004000) >> 14)
-#define PHY_BB_RADAR_DETECTION_2_ENABLE_MAX_RADAR_RSSI_SET(x)                 (((x) << 14) & 0x00004000)
-#define PHY_BB_RADAR_DETECTION_2_ENABLE_BLOCK_RADAR_CHECK_MSB                                         15
-#define PHY_BB_RADAR_DETECTION_2_ENABLE_BLOCK_RADAR_CHECK_LSB                                         15
-#define PHY_BB_RADAR_DETECTION_2_ENABLE_BLOCK_RADAR_CHECK_MASK                                0x00008000
-#define PHY_BB_RADAR_DETECTION_2_ENABLE_BLOCK_RADAR_CHECK_GET(x)              (((x) & 0x00008000) >> 15)
-#define PHY_BB_RADAR_DETECTION_2_ENABLE_BLOCK_RADAR_CHECK_SET(x)              (((x) << 15) & 0x00008000)
-#define PHY_BB_RADAR_DETECTION_2_RADAR_RELPWR_THRESH_MSB                                              21
-#define PHY_BB_RADAR_DETECTION_2_RADAR_RELPWR_THRESH_LSB                                              16
-#define PHY_BB_RADAR_DETECTION_2_RADAR_RELPWR_THRESH_MASK                                     0x003f0000
-#define PHY_BB_RADAR_DETECTION_2_RADAR_RELPWR_THRESH_GET(x)                   (((x) & 0x003f0000) >> 16)
-#define PHY_BB_RADAR_DETECTION_2_RADAR_RELPWR_THRESH_SET(x)                   (((x) << 16) & 0x003f0000)
-#define PHY_BB_RADAR_DETECTION_2_RADAR_USE_FIRPWR_128_MSB                                             22
-#define PHY_BB_RADAR_DETECTION_2_RADAR_USE_FIRPWR_128_LSB                                             22
-#define PHY_BB_RADAR_DETECTION_2_RADAR_USE_FIRPWR_128_MASK                                    0x00400000
-#define PHY_BB_RADAR_DETECTION_2_RADAR_USE_FIRPWR_128_GET(x)                  (((x) & 0x00400000) >> 22)
-#define PHY_BB_RADAR_DETECTION_2_RADAR_USE_FIRPWR_128_SET(x)                  (((x) << 22) & 0x00400000)
-#define PHY_BB_RADAR_DETECTION_2_ENABLE_RADAR_RELPWR_CHECK_MSB                                        23
-#define PHY_BB_RADAR_DETECTION_2_ENABLE_RADAR_RELPWR_CHECK_LSB                                        23
-#define PHY_BB_RADAR_DETECTION_2_ENABLE_RADAR_RELPWR_CHECK_MASK                               0x00800000
-#define PHY_BB_RADAR_DETECTION_2_ENABLE_RADAR_RELPWR_CHECK_GET(x)             (((x) & 0x00800000) >> 23)
-#define PHY_BB_RADAR_DETECTION_2_ENABLE_RADAR_RELPWR_CHECK_SET(x)             (((x) << 23) & 0x00800000)
-#define PHY_BB_RADAR_DETECTION_2_CF_RADAR_BIN_THRESH_SEL_MSB                                          26
-#define PHY_BB_RADAR_DETECTION_2_CF_RADAR_BIN_THRESH_SEL_LSB                                          24
-#define PHY_BB_RADAR_DETECTION_2_CF_RADAR_BIN_THRESH_SEL_MASK                                 0x07000000
-#define PHY_BB_RADAR_DETECTION_2_CF_RADAR_BIN_THRESH_SEL_GET(x)               (((x) & 0x07000000) >> 24)
-#define PHY_BB_RADAR_DETECTION_2_CF_RADAR_BIN_THRESH_SEL_SET(x)               (((x) << 24) & 0x07000000)
-#define PHY_BB_RADAR_DETECTION_2_ENABLE_PULSE_GC_COUNT_CHECK_MSB                                      27
-#define PHY_BB_RADAR_DETECTION_2_ENABLE_PULSE_GC_COUNT_CHECK_LSB                                      27
-#define PHY_BB_RADAR_DETECTION_2_ENABLE_PULSE_GC_COUNT_CHECK_MASK                             0x08000000
-#define PHY_BB_RADAR_DETECTION_2_ENABLE_PULSE_GC_COUNT_CHECK_GET(x)           (((x) & 0x08000000) >> 27)
-#define PHY_BB_RADAR_DETECTION_2_ENABLE_PULSE_GC_COUNT_CHECK_SET(x)           (((x) << 27) & 0x08000000)
-
-/* macros for BB_tx_phase_ramp_b0 */
-#define PHY_BB_TX_PHASE_RAMP_B0_ADDRESS                                                       0x0000995c
-#define PHY_BB_TX_PHASE_RAMP_B0_OFFSET                                                        0x0000995c
-#define PHY_BB_TX_PHASE_RAMP_B0_CF_PHASE_RAMP_ENABLE_0_MSB                                             0
-#define PHY_BB_TX_PHASE_RAMP_B0_CF_PHASE_RAMP_ENABLE_0_LSB                                             0
-#define PHY_BB_TX_PHASE_RAMP_B0_CF_PHASE_RAMP_ENABLE_0_MASK                                   0x00000001
-#define PHY_BB_TX_PHASE_RAMP_B0_CF_PHASE_RAMP_ENABLE_0_GET(x)                  (((x) & 0x00000001) >> 0)
-#define PHY_BB_TX_PHASE_RAMP_B0_CF_PHASE_RAMP_ENABLE_0_SET(x)                  (((x) << 0) & 0x00000001)
-#define PHY_BB_TX_PHASE_RAMP_B0_CF_PHASE_RAMP_BIAS_0_MSB                                               6
-#define PHY_BB_TX_PHASE_RAMP_B0_CF_PHASE_RAMP_BIAS_0_LSB                                               1
-#define PHY_BB_TX_PHASE_RAMP_B0_CF_PHASE_RAMP_BIAS_0_MASK                                     0x0000007e
-#define PHY_BB_TX_PHASE_RAMP_B0_CF_PHASE_RAMP_BIAS_0_GET(x)                    (((x) & 0x0000007e) >> 1)
-#define PHY_BB_TX_PHASE_RAMP_B0_CF_PHASE_RAMP_BIAS_0_SET(x)                    (((x) << 1) & 0x0000007e)
-#define PHY_BB_TX_PHASE_RAMP_B0_CF_PHASE_RAMP_INIT_0_MSB                                              16
-#define PHY_BB_TX_PHASE_RAMP_B0_CF_PHASE_RAMP_INIT_0_LSB                                               7
-#define PHY_BB_TX_PHASE_RAMP_B0_CF_PHASE_RAMP_INIT_0_MASK                                     0x0001ff80
-#define PHY_BB_TX_PHASE_RAMP_B0_CF_PHASE_RAMP_INIT_0_GET(x)                    (((x) & 0x0001ff80) >> 7)
-#define PHY_BB_TX_PHASE_RAMP_B0_CF_PHASE_RAMP_INIT_0_SET(x)                    (((x) << 7) & 0x0001ff80)
-#define PHY_BB_TX_PHASE_RAMP_B0_CF_PHASE_RAMP_ALPHA_0_MSB                                             24
-#define PHY_BB_TX_PHASE_RAMP_B0_CF_PHASE_RAMP_ALPHA_0_LSB                                             17
-#define PHY_BB_TX_PHASE_RAMP_B0_CF_PHASE_RAMP_ALPHA_0_MASK                                    0x01fe0000
-#define PHY_BB_TX_PHASE_RAMP_B0_CF_PHASE_RAMP_ALPHA_0_GET(x)                  (((x) & 0x01fe0000) >> 17)
-#define PHY_BB_TX_PHASE_RAMP_B0_CF_PHASE_RAMP_ALPHA_0_SET(x)                  (((x) << 17) & 0x01fe0000)
-
-/* macros for BB_switch_table_chn_b0 */
-#define PHY_BB_SWITCH_TABLE_CHN_B0_ADDRESS                                                    0x00009960
-#define PHY_BB_SWITCH_TABLE_CHN_B0_OFFSET                                                     0x00009960
-#define PHY_BB_SWITCH_TABLE_CHN_B0_SWITCH_TABLE_IDLE_0_MSB                                             1
-#define PHY_BB_SWITCH_TABLE_CHN_B0_SWITCH_TABLE_IDLE_0_LSB                                             0
-#define PHY_BB_SWITCH_TABLE_CHN_B0_SWITCH_TABLE_IDLE_0_MASK                                   0x00000003
-#define PHY_BB_SWITCH_TABLE_CHN_B0_SWITCH_TABLE_IDLE_0_GET(x)                  (((x) & 0x00000003) >> 0)
-#define PHY_BB_SWITCH_TABLE_CHN_B0_SWITCH_TABLE_IDLE_0_SET(x)                  (((x) << 0) & 0x00000003)
-#define PHY_BB_SWITCH_TABLE_CHN_B0_SWITCH_TABLE_T_0_MSB                                                3
-#define PHY_BB_SWITCH_TABLE_CHN_B0_SWITCH_TABLE_T_0_LSB                                                2
-#define PHY_BB_SWITCH_TABLE_CHN_B0_SWITCH_TABLE_T_0_MASK                                      0x0000000c
-#define PHY_BB_SWITCH_TABLE_CHN_B0_SWITCH_TABLE_T_0_GET(x)                     (((x) & 0x0000000c) >> 2)
-#define PHY_BB_SWITCH_TABLE_CHN_B0_SWITCH_TABLE_T_0_SET(x)                     (((x) << 2) & 0x0000000c)
-#define PHY_BB_SWITCH_TABLE_CHN_B0_SWITCH_TABLE_R_0_MSB                                                5
-#define PHY_BB_SWITCH_TABLE_CHN_B0_SWITCH_TABLE_R_0_LSB                                                4
-#define PHY_BB_SWITCH_TABLE_CHN_B0_SWITCH_TABLE_R_0_MASK                                      0x00000030
-#define PHY_BB_SWITCH_TABLE_CHN_B0_SWITCH_TABLE_R_0_GET(x)                     (((x) & 0x00000030) >> 4)
-#define PHY_BB_SWITCH_TABLE_CHN_B0_SWITCH_TABLE_R_0_SET(x)                     (((x) << 4) & 0x00000030)
-#define PHY_BB_SWITCH_TABLE_CHN_B0_SWITCH_TABLE_RX1_0_MSB                                              7
-#define PHY_BB_SWITCH_TABLE_CHN_B0_SWITCH_TABLE_RX1_0_LSB                                              6
-#define PHY_BB_SWITCH_TABLE_CHN_B0_SWITCH_TABLE_RX1_0_MASK                                    0x000000c0
-#define PHY_BB_SWITCH_TABLE_CHN_B0_SWITCH_TABLE_RX1_0_GET(x)                   (((x) & 0x000000c0) >> 6)
-#define PHY_BB_SWITCH_TABLE_CHN_B0_SWITCH_TABLE_RX1_0_SET(x)                   (((x) << 6) & 0x000000c0)
-#define PHY_BB_SWITCH_TABLE_CHN_B0_SWITCH_TABLE_RX12_0_MSB                                             9
-#define PHY_BB_SWITCH_TABLE_CHN_B0_SWITCH_TABLE_RX12_0_LSB                                             8
-#define PHY_BB_SWITCH_TABLE_CHN_B0_SWITCH_TABLE_RX12_0_MASK                                   0x00000300
-#define PHY_BB_SWITCH_TABLE_CHN_B0_SWITCH_TABLE_RX12_0_GET(x)                  (((x) & 0x00000300) >> 8)
-#define PHY_BB_SWITCH_TABLE_CHN_B0_SWITCH_TABLE_RX12_0_SET(x)                  (((x) << 8) & 0x00000300)
-#define PHY_BB_SWITCH_TABLE_CHN_B0_SWITCH_TABLE_B_0_MSB                                               11
-#define PHY_BB_SWITCH_TABLE_CHN_B0_SWITCH_TABLE_B_0_LSB                                               10
-#define PHY_BB_SWITCH_TABLE_CHN_B0_SWITCH_TABLE_B_0_MASK                                      0x00000c00
-#define PHY_BB_SWITCH_TABLE_CHN_B0_SWITCH_TABLE_B_0_GET(x)                    (((x) & 0x00000c00) >> 10)
-#define PHY_BB_SWITCH_TABLE_CHN_B0_SWITCH_TABLE_B_0_SET(x)                    (((x) << 10) & 0x00000c00)
-
-/* macros for BB_switch_table_com1 */
-#define PHY_BB_SWITCH_TABLE_COM1_ADDRESS                                                      0x00009964
-#define PHY_BB_SWITCH_TABLE_COM1_OFFSET                                                       0x00009964
-#define PHY_BB_SWITCH_TABLE_COM1_SWITCH_TABLE_COM_IDLE_MSB                                             3
-#define PHY_BB_SWITCH_TABLE_COM1_SWITCH_TABLE_COM_IDLE_LSB                                             0
-#define PHY_BB_SWITCH_TABLE_COM1_SWITCH_TABLE_COM_IDLE_MASK                                   0x0000000f
-#define PHY_BB_SWITCH_TABLE_COM1_SWITCH_TABLE_COM_IDLE_GET(x)                  (((x) & 0x0000000f) >> 0)
-#define PHY_BB_SWITCH_TABLE_COM1_SWITCH_TABLE_COM_IDLE_SET(x)                  (((x) << 0) & 0x0000000f)
-#define PHY_BB_SWITCH_TABLE_COM1_SWITCH_TABLE_COM_T1_MSB                                               7
-#define PHY_BB_SWITCH_TABLE_COM1_SWITCH_TABLE_COM_T1_LSB                                               4
-#define PHY_BB_SWITCH_TABLE_COM1_SWITCH_TABLE_COM_T1_MASK                                     0x000000f0
-#define PHY_BB_SWITCH_TABLE_COM1_SWITCH_TABLE_COM_T1_GET(x)                    (((x) & 0x000000f0) >> 4)
-#define PHY_BB_SWITCH_TABLE_COM1_SWITCH_TABLE_COM_T1_SET(x)                    (((x) << 4) & 0x000000f0)
-#define PHY_BB_SWITCH_TABLE_COM1_SWITCH_TABLE_COM_T2_MSB                                              11
-#define PHY_BB_SWITCH_TABLE_COM1_SWITCH_TABLE_COM_T2_LSB                                               8
-#define PHY_BB_SWITCH_TABLE_COM1_SWITCH_TABLE_COM_T2_MASK                                     0x00000f00
-#define PHY_BB_SWITCH_TABLE_COM1_SWITCH_TABLE_COM_T2_GET(x)                    (((x) & 0x00000f00) >> 8)
-#define PHY_BB_SWITCH_TABLE_COM1_SWITCH_TABLE_COM_T2_SET(x)                    (((x) << 8) & 0x00000f00)
-#define PHY_BB_SWITCH_TABLE_COM1_SWITCH_TABLE_COM_B_MSB                                               15
-#define PHY_BB_SWITCH_TABLE_COM1_SWITCH_TABLE_COM_B_LSB                                               12
-#define PHY_BB_SWITCH_TABLE_COM1_SWITCH_TABLE_COM_B_MASK                                      0x0000f000
-#define PHY_BB_SWITCH_TABLE_COM1_SWITCH_TABLE_COM_B_GET(x)                    (((x) & 0x0000f000) >> 12)
-#define PHY_BB_SWITCH_TABLE_COM1_SWITCH_TABLE_COM_B_SET(x)                    (((x) << 12) & 0x0000f000)
-
-/* macros for BB_cca_ctrl_2_b0 */
-#define PHY_BB_CCA_CTRL_2_B0_ADDRESS                                                          0x00009968
-#define PHY_BB_CCA_CTRL_2_B0_OFFSET                                                           0x00009968
-#define PHY_BB_CCA_CTRL_2_B0_MINCCAPWR_THR_0_MSB                                                       8
-#define PHY_BB_CCA_CTRL_2_B0_MINCCAPWR_THR_0_LSB                                                       0
-#define PHY_BB_CCA_CTRL_2_B0_MINCCAPWR_THR_0_MASK                                             0x000001ff
-#define PHY_BB_CCA_CTRL_2_B0_MINCCAPWR_THR_0_GET(x)                            (((x) & 0x000001ff) >> 0)
-#define PHY_BB_CCA_CTRL_2_B0_MINCCAPWR_THR_0_SET(x)                            (((x) << 0) & 0x000001ff)
-#define PHY_BB_CCA_CTRL_2_B0_ENABLE_MINCCAPWR_THR_MSB                                                  9
-#define PHY_BB_CCA_CTRL_2_B0_ENABLE_MINCCAPWR_THR_LSB                                                  9
-#define PHY_BB_CCA_CTRL_2_B0_ENABLE_MINCCAPWR_THR_MASK                                        0x00000200
-#define PHY_BB_CCA_CTRL_2_B0_ENABLE_MINCCAPWR_THR_GET(x)                       (((x) & 0x00000200) >> 9)
-#define PHY_BB_CCA_CTRL_2_B0_ENABLE_MINCCAPWR_THR_SET(x)                       (((x) << 9) & 0x00000200)
-#define PHY_BB_CCA_CTRL_2_B0_NF_GAIN_COMP_0_MSB                                                       17
-#define PHY_BB_CCA_CTRL_2_B0_NF_GAIN_COMP_0_LSB                                                       10
-#define PHY_BB_CCA_CTRL_2_B0_NF_GAIN_COMP_0_MASK                                              0x0003fc00
-#define PHY_BB_CCA_CTRL_2_B0_NF_GAIN_COMP_0_GET(x)                            (((x) & 0x0003fc00) >> 10)
-#define PHY_BB_CCA_CTRL_2_B0_NF_GAIN_COMP_0_SET(x)                            (((x) << 10) & 0x0003fc00)
-#define PHY_BB_CCA_CTRL_2_B0_THRESH62_MODE_MSB                                                        18
-#define PHY_BB_CCA_CTRL_2_B0_THRESH62_MODE_LSB                                                        18
-#define PHY_BB_CCA_CTRL_2_B0_THRESH62_MODE_MASK                                               0x00040000
-#define PHY_BB_CCA_CTRL_2_B0_THRESH62_MODE_GET(x)                             (((x) & 0x00040000) >> 18)
-#define PHY_BB_CCA_CTRL_2_B0_THRESH62_MODE_SET(x)                             (((x) << 18) & 0x00040000)
-
-/* macros for BB_switch_table_com2 */
-#define PHY_BB_SWITCH_TABLE_COM2_ADDRESS                                                      0x0000996c
-#define PHY_BB_SWITCH_TABLE_COM2_OFFSET                                                       0x0000996c
-#define PHY_BB_SWITCH_TABLE_COM2_SWITCH_TABLE_COM_RA1NXAL1_MSB                                         3
-#define PHY_BB_SWITCH_TABLE_COM2_SWITCH_TABLE_COM_RA1NXAL1_LSB                                         0
-#define PHY_BB_SWITCH_TABLE_COM2_SWITCH_TABLE_COM_RA1NXAL1_MASK                               0x0000000f
-#define PHY_BB_SWITCH_TABLE_COM2_SWITCH_TABLE_COM_RA1NXAL1_GET(x)              (((x) & 0x0000000f) >> 0)
-#define PHY_BB_SWITCH_TABLE_COM2_SWITCH_TABLE_COM_RA1NXAL1_SET(x)              (((x) << 0) & 0x0000000f)
-#define PHY_BB_SWITCH_TABLE_COM2_SWITCH_TABLE_COM_RA2NXAL1_MSB                                         7
-#define PHY_BB_SWITCH_TABLE_COM2_SWITCH_TABLE_COM_RA2NXAL1_LSB                                         4
-#define PHY_BB_SWITCH_TABLE_COM2_SWITCH_TABLE_COM_RA2NXAL1_MASK                               0x000000f0
-#define PHY_BB_SWITCH_TABLE_COM2_SWITCH_TABLE_COM_RA2NXAL1_GET(x)              (((x) & 0x000000f0) >> 4)
-#define PHY_BB_SWITCH_TABLE_COM2_SWITCH_TABLE_COM_RA2NXAL1_SET(x)              (((x) << 4) & 0x000000f0)
-#define PHY_BB_SWITCH_TABLE_COM2_SWITCH_TABLE_COM_RA1XAL1_MSB                                         11
-#define PHY_BB_SWITCH_TABLE_COM2_SWITCH_TABLE_COM_RA1XAL1_LSB                                          8
-#define PHY_BB_SWITCH_TABLE_COM2_SWITCH_TABLE_COM_RA1XAL1_MASK                                0x00000f00
-#define PHY_BB_SWITCH_TABLE_COM2_SWITCH_TABLE_COM_RA1XAL1_GET(x)               (((x) & 0x00000f00) >> 8)
-#define PHY_BB_SWITCH_TABLE_COM2_SWITCH_TABLE_COM_RA1XAL1_SET(x)               (((x) << 8) & 0x00000f00)
-#define PHY_BB_SWITCH_TABLE_COM2_SWITCH_TABLE_COM_RA2XAL1_MSB                                         15
-#define PHY_BB_SWITCH_TABLE_COM2_SWITCH_TABLE_COM_RA2XAL1_LSB                                         12
-#define PHY_BB_SWITCH_TABLE_COM2_SWITCH_TABLE_COM_RA2XAL1_MASK                                0x0000f000
-#define PHY_BB_SWITCH_TABLE_COM2_SWITCH_TABLE_COM_RA2XAL1_GET(x)              (((x) & 0x0000f000) >> 12)
-#define PHY_BB_SWITCH_TABLE_COM2_SWITCH_TABLE_COM_RA2XAL1_SET(x)              (((x) << 12) & 0x0000f000)
-#define PHY_BB_SWITCH_TABLE_COM2_SWITCH_TABLE_COM_RA1NXAL2_MSB                                        19
-#define PHY_BB_SWITCH_TABLE_COM2_SWITCH_TABLE_COM_RA1NXAL2_LSB                                        16
-#define PHY_BB_SWITCH_TABLE_COM2_SWITCH_TABLE_COM_RA1NXAL2_MASK                               0x000f0000
-#define PHY_BB_SWITCH_TABLE_COM2_SWITCH_TABLE_COM_RA1NXAL2_GET(x)             (((x) & 0x000f0000) >> 16)
-#define PHY_BB_SWITCH_TABLE_COM2_SWITCH_TABLE_COM_RA1NXAL2_SET(x)             (((x) << 16) & 0x000f0000)
-#define PHY_BB_SWITCH_TABLE_COM2_SWITCH_TABLE_COM_RA2NXAL2_MSB                                        23
-#define PHY_BB_SWITCH_TABLE_COM2_SWITCH_TABLE_COM_RA2NXAL2_LSB                                        20
-#define PHY_BB_SWITCH_TABLE_COM2_SWITCH_TABLE_COM_RA2NXAL2_MASK                               0x00f00000
-#define PHY_BB_SWITCH_TABLE_COM2_SWITCH_TABLE_COM_RA2NXAL2_GET(x)             (((x) & 0x00f00000) >> 20)
-#define PHY_BB_SWITCH_TABLE_COM2_SWITCH_TABLE_COM_RA2NXAL2_SET(x)             (((x) << 20) & 0x00f00000)
-#define PHY_BB_SWITCH_TABLE_COM2_SWITCH_TABLE_COM_RA1XAL2_MSB                                         27
-#define PHY_BB_SWITCH_TABLE_COM2_SWITCH_TABLE_COM_RA1XAL2_LSB                                         24
-#define PHY_BB_SWITCH_TABLE_COM2_SWITCH_TABLE_COM_RA1XAL2_MASK                                0x0f000000
-#define PHY_BB_SWITCH_TABLE_COM2_SWITCH_TABLE_COM_RA1XAL2_GET(x)              (((x) & 0x0f000000) >> 24)
-#define PHY_BB_SWITCH_TABLE_COM2_SWITCH_TABLE_COM_RA1XAL2_SET(x)              (((x) << 24) & 0x0f000000)
-#define PHY_BB_SWITCH_TABLE_COM2_SWITCH_TABLE_COM_RA2XAL2_MSB                                         31
-#define PHY_BB_SWITCH_TABLE_COM2_SWITCH_TABLE_COM_RA2XAL2_LSB                                         28
-#define PHY_BB_SWITCH_TABLE_COM2_SWITCH_TABLE_COM_RA2XAL2_MASK                                0xf0000000
-#define PHY_BB_SWITCH_TABLE_COM2_SWITCH_TABLE_COM_RA2XAL2_GET(x)              (((x) & 0xf0000000) >> 28)
-#define PHY_BB_SWITCH_TABLE_COM2_SWITCH_TABLE_COM_RA2XAL2_SET(x)              (((x) << 28) & 0xf0000000)
-
-/* macros for BB_restart */
-#define PHY_BB_RESTART_ADDRESS                                                                0x00009970
-#define PHY_BB_RESTART_OFFSET                                                                 0x00009970
-#define PHY_BB_RESTART_ENABLE_RESTART_MSB                                                              0
-#define PHY_BB_RESTART_ENABLE_RESTART_LSB                                                              0
-#define PHY_BB_RESTART_ENABLE_RESTART_MASK                                                    0x00000001
-#define PHY_BB_RESTART_ENABLE_RESTART_GET(x)                                   (((x) & 0x00000001) >> 0)
-#define PHY_BB_RESTART_ENABLE_RESTART_SET(x)                                   (((x) << 0) & 0x00000001)
-#define PHY_BB_RESTART_RESTART_LGFIRPWR_DELTA_MSB                                                      5
-#define PHY_BB_RESTART_RESTART_LGFIRPWR_DELTA_LSB                                                      1
-#define PHY_BB_RESTART_RESTART_LGFIRPWR_DELTA_MASK                                            0x0000003e
-#define PHY_BB_RESTART_RESTART_LGFIRPWR_DELTA_GET(x)                           (((x) & 0x0000003e) >> 1)
-#define PHY_BB_RESTART_RESTART_LGFIRPWR_DELTA_SET(x)                           (((x) << 1) & 0x0000003e)
-#define PHY_BB_RESTART_ENABLE_PWR_DROP_ERR_MSB                                                         6
-#define PHY_BB_RESTART_ENABLE_PWR_DROP_ERR_LSB                                                         6
-#define PHY_BB_RESTART_ENABLE_PWR_DROP_ERR_MASK                                               0x00000040
-#define PHY_BB_RESTART_ENABLE_PWR_DROP_ERR_GET(x)                              (((x) & 0x00000040) >> 6)
-#define PHY_BB_RESTART_ENABLE_PWR_DROP_ERR_SET(x)                              (((x) << 6) & 0x00000040)
-#define PHY_BB_RESTART_PWRDROP_LGFIRPWR_DELTA_MSB                                                     11
-#define PHY_BB_RESTART_PWRDROP_LGFIRPWR_DELTA_LSB                                                      7
-#define PHY_BB_RESTART_PWRDROP_LGFIRPWR_DELTA_MASK                                            0x00000f80
-#define PHY_BB_RESTART_PWRDROP_LGFIRPWR_DELTA_GET(x)                           (((x) & 0x00000f80) >> 7)
-#define PHY_BB_RESTART_PWRDROP_LGFIRPWR_DELTA_SET(x)                           (((x) << 7) & 0x00000f80)
-#define PHY_BB_RESTART_OFDM_CCK_RSSI_BIAS_MSB                                                         17
-#define PHY_BB_RESTART_OFDM_CCK_RSSI_BIAS_LSB                                                         12
-#define PHY_BB_RESTART_OFDM_CCK_RSSI_BIAS_MASK                                                0x0003f000
-#define PHY_BB_RESTART_OFDM_CCK_RSSI_BIAS_GET(x)                              (((x) & 0x0003f000) >> 12)
-#define PHY_BB_RESTART_OFDM_CCK_RSSI_BIAS_SET(x)                              (((x) << 12) & 0x0003f000)
-#define PHY_BB_RESTART_ANT_FAST_DIV_GC_LIMIT_MSB                                                      20
-#define PHY_BB_RESTART_ANT_FAST_DIV_GC_LIMIT_LSB                                                      18
-#define PHY_BB_RESTART_ANT_FAST_DIV_GC_LIMIT_MASK                                             0x001c0000
-#define PHY_BB_RESTART_ANT_FAST_DIV_GC_LIMIT_GET(x)                           (((x) & 0x001c0000) >> 18)
-#define PHY_BB_RESTART_ANT_FAST_DIV_GC_LIMIT_SET(x)                           (((x) << 18) & 0x001c0000)
-#define PHY_BB_RESTART_ENABLE_ANT_FAST_DIV_M2FLAG_MSB                                                 21
-#define PHY_BB_RESTART_ENABLE_ANT_FAST_DIV_M2FLAG_LSB                                                 21
-#define PHY_BB_RESTART_ENABLE_ANT_FAST_DIV_M2FLAG_MASK                                        0x00200000
-#define PHY_BB_RESTART_ENABLE_ANT_FAST_DIV_M2FLAG_GET(x)                      (((x) & 0x00200000) >> 21)
-#define PHY_BB_RESTART_ENABLE_ANT_FAST_DIV_M2FLAG_SET(x)                      (((x) << 21) & 0x00200000)
-#define PHY_BB_RESTART_WEAK_RSSI_VOTE_THR_MSB                                                         28
-#define PHY_BB_RESTART_WEAK_RSSI_VOTE_THR_LSB                                                         22
-#define PHY_BB_RESTART_WEAK_RSSI_VOTE_THR_MASK                                                0x1fc00000
-#define PHY_BB_RESTART_WEAK_RSSI_VOTE_THR_GET(x)                              (((x) & 0x1fc00000) >> 22)
-#define PHY_BB_RESTART_WEAK_RSSI_VOTE_THR_SET(x)                              (((x) << 22) & 0x1fc00000)
-#define PHY_BB_RESTART_ENABLE_PWR_DROP_ERR_CCK_MSB                                                    29
-#define PHY_BB_RESTART_ENABLE_PWR_DROP_ERR_CCK_LSB                                                    29
-#define PHY_BB_RESTART_ENABLE_PWR_DROP_ERR_CCK_MASK                                           0x20000000
-#define PHY_BB_RESTART_ENABLE_PWR_DROP_ERR_CCK_GET(x)                         (((x) & 0x20000000) >> 29)
-#define PHY_BB_RESTART_ENABLE_PWR_DROP_ERR_CCK_SET(x)                         (((x) << 29) & 0x20000000)
-#define PHY_BB_RESTART_DISABLE_DC_RESTART_MSB                                                         30
-#define PHY_BB_RESTART_DISABLE_DC_RESTART_LSB                                                         30
-#define PHY_BB_RESTART_DISABLE_DC_RESTART_MASK                                                0x40000000
-#define PHY_BB_RESTART_DISABLE_DC_RESTART_GET(x)                              (((x) & 0x40000000) >> 30)
-#define PHY_BB_RESTART_DISABLE_DC_RESTART_SET(x)                              (((x) << 30) & 0x40000000)
-#define PHY_BB_RESTART_RESTART_MODE_BW40_MSB                                                          31
-#define PHY_BB_RESTART_RESTART_MODE_BW40_LSB                                                          31
-#define PHY_BB_RESTART_RESTART_MODE_BW40_MASK                                                 0x80000000
-#define PHY_BB_RESTART_RESTART_MODE_BW40_GET(x)                               (((x) & 0x80000000) >> 31)
-#define PHY_BB_RESTART_RESTART_MODE_BW40_SET(x)                               (((x) << 31) & 0x80000000)
-
-/* macros for BB_scrambler_seed */
-#define PHY_BB_SCRAMBLER_SEED_ADDRESS                                                         0x00009978
-#define PHY_BB_SCRAMBLER_SEED_OFFSET                                                          0x00009978
-#define PHY_BB_SCRAMBLER_SEED_FIXED_SCRAMBLER_SEED_MSB                                                 6
-#define PHY_BB_SCRAMBLER_SEED_FIXED_SCRAMBLER_SEED_LSB                                                 0
-#define PHY_BB_SCRAMBLER_SEED_FIXED_SCRAMBLER_SEED_MASK                                       0x0000007f
-#define PHY_BB_SCRAMBLER_SEED_FIXED_SCRAMBLER_SEED_GET(x)                      (((x) & 0x0000007f) >> 0)
-#define PHY_BB_SCRAMBLER_SEED_FIXED_SCRAMBLER_SEED_SET(x)                      (((x) << 0) & 0x0000007f)
-
-/* macros for BB_rfbus_request */
-#define PHY_BB_RFBUS_REQUEST_ADDRESS                                                          0x0000997c
-#define PHY_BB_RFBUS_REQUEST_OFFSET                                                           0x0000997c
-#define PHY_BB_RFBUS_REQUEST_RFBUS_REQUEST_MSB                                                         0
-#define PHY_BB_RFBUS_REQUEST_RFBUS_REQUEST_LSB                                                         0
-#define PHY_BB_RFBUS_REQUEST_RFBUS_REQUEST_MASK                                               0x00000001
-#define PHY_BB_RFBUS_REQUEST_RFBUS_REQUEST_GET(x)                              (((x) & 0x00000001) >> 0)
-#define PHY_BB_RFBUS_REQUEST_RFBUS_REQUEST_SET(x)                              (((x) << 0) & 0x00000001)
-
-/* macros for BB_timing_control_11 */
-#define PHY_BB_TIMING_CONTROL_11_ADDRESS                                                      0x000099a0
-#define PHY_BB_TIMING_CONTROL_11_OFFSET                                                       0x000099a0
-#define PHY_BB_TIMING_CONTROL_11_SPUR_DELTA_PHASE_MSB                                                 19
-#define PHY_BB_TIMING_CONTROL_11_SPUR_DELTA_PHASE_LSB                                                  0
-#define PHY_BB_TIMING_CONTROL_11_SPUR_DELTA_PHASE_MASK                                        0x000fffff
-#define PHY_BB_TIMING_CONTROL_11_SPUR_DELTA_PHASE_GET(x)                       (((x) & 0x000fffff) >> 0)
-#define PHY_BB_TIMING_CONTROL_11_SPUR_DELTA_PHASE_SET(x)                       (((x) << 0) & 0x000fffff)
-#define PHY_BB_TIMING_CONTROL_11_SPUR_FREQ_SD_MSB                                                     29
-#define PHY_BB_TIMING_CONTROL_11_SPUR_FREQ_SD_LSB                                                     20
-#define PHY_BB_TIMING_CONTROL_11_SPUR_FREQ_SD_MASK                                            0x3ff00000
-#define PHY_BB_TIMING_CONTROL_11_SPUR_FREQ_SD_GET(x)                          (((x) & 0x3ff00000) >> 20)
-#define PHY_BB_TIMING_CONTROL_11_SPUR_FREQ_SD_SET(x)                          (((x) << 20) & 0x3ff00000)
-#define PHY_BB_TIMING_CONTROL_11_USE_SPUR_FILTER_IN_AGC_MSB                                           30
-#define PHY_BB_TIMING_CONTROL_11_USE_SPUR_FILTER_IN_AGC_LSB                                           30
-#define PHY_BB_TIMING_CONTROL_11_USE_SPUR_FILTER_IN_AGC_MASK                                  0x40000000
-#define PHY_BB_TIMING_CONTROL_11_USE_SPUR_FILTER_IN_AGC_GET(x)                (((x) & 0x40000000) >> 30)
-#define PHY_BB_TIMING_CONTROL_11_USE_SPUR_FILTER_IN_AGC_SET(x)                (((x) << 30) & 0x40000000)
-#define PHY_BB_TIMING_CONTROL_11_USE_SPUR_FILTER_IN_SELFCOR_MSB                                       31
-#define PHY_BB_TIMING_CONTROL_11_USE_SPUR_FILTER_IN_SELFCOR_LSB                                       31
-#define PHY_BB_TIMING_CONTROL_11_USE_SPUR_FILTER_IN_SELFCOR_MASK                              0x80000000
-#define PHY_BB_TIMING_CONTROL_11_USE_SPUR_FILTER_IN_SELFCOR_GET(x)            (((x) & 0x80000000) >> 31)
-#define PHY_BB_TIMING_CONTROL_11_USE_SPUR_FILTER_IN_SELFCOR_SET(x)            (((x) << 31) & 0x80000000)
-
-/* macros for BB_multichain_enable */
-#define PHY_BB_MULTICHAIN_ENABLE_ADDRESS                                                      0x000099a4
-#define PHY_BB_MULTICHAIN_ENABLE_OFFSET                                                       0x000099a4
-#define PHY_BB_MULTICHAIN_ENABLE_RX_CHAIN_MASK_MSB                                                     2
-#define PHY_BB_MULTICHAIN_ENABLE_RX_CHAIN_MASK_LSB                                                     0
-#define PHY_BB_MULTICHAIN_ENABLE_RX_CHAIN_MASK_MASK                                           0x00000007
-#define PHY_BB_MULTICHAIN_ENABLE_RX_CHAIN_MASK_GET(x)                          (((x) & 0x00000007) >> 0)
-#define PHY_BB_MULTICHAIN_ENABLE_RX_CHAIN_MASK_SET(x)                          (((x) << 0) & 0x00000007)
-
-/* macros for BB_multichain_control */
-#define PHY_BB_MULTICHAIN_CONTROL_ADDRESS                                                     0x000099a8
-#define PHY_BB_MULTICHAIN_CONTROL_OFFSET                                                      0x000099a8
-#define PHY_BB_MULTICHAIN_CONTROL_FORCE_ANALOG_GAIN_DIFF_MSB                                           0
-#define PHY_BB_MULTICHAIN_CONTROL_FORCE_ANALOG_GAIN_DIFF_LSB                                           0
-#define PHY_BB_MULTICHAIN_CONTROL_FORCE_ANALOG_GAIN_DIFF_MASK                                 0x00000001
-#define PHY_BB_MULTICHAIN_CONTROL_FORCE_ANALOG_GAIN_DIFF_GET(x)                (((x) & 0x00000001) >> 0)
-#define PHY_BB_MULTICHAIN_CONTROL_FORCE_ANALOG_GAIN_DIFF_SET(x)                (((x) << 0) & 0x00000001)
-#define PHY_BB_MULTICHAIN_CONTROL_FORCED_GAIN_DIFF_01_MSB                                              7
-#define PHY_BB_MULTICHAIN_CONTROL_FORCED_GAIN_DIFF_01_LSB                                              1
-#define PHY_BB_MULTICHAIN_CONTROL_FORCED_GAIN_DIFF_01_MASK                                    0x000000fe
-#define PHY_BB_MULTICHAIN_CONTROL_FORCED_GAIN_DIFF_01_GET(x)                   (((x) & 0x000000fe) >> 1)
-#define PHY_BB_MULTICHAIN_CONTROL_FORCED_GAIN_DIFF_01_SET(x)                   (((x) << 1) & 0x000000fe)
-#define PHY_BB_MULTICHAIN_CONTROL_SYNC_SYNTHON_MSB                                                     8
-#define PHY_BB_MULTICHAIN_CONTROL_SYNC_SYNTHON_LSB                                                     8
-#define PHY_BB_MULTICHAIN_CONTROL_SYNC_SYNTHON_MASK                                           0x00000100
-#define PHY_BB_MULTICHAIN_CONTROL_SYNC_SYNTHON_GET(x)                          (((x) & 0x00000100) >> 8)
-#define PHY_BB_MULTICHAIN_CONTROL_SYNC_SYNTHON_SET(x)                          (((x) << 8) & 0x00000100)
-#define PHY_BB_MULTICHAIN_CONTROL_USE_POSEDGE_REFCLK_MSB                                               9
-#define PHY_BB_MULTICHAIN_CONTROL_USE_POSEDGE_REFCLK_LSB                                               9
-#define PHY_BB_MULTICHAIN_CONTROL_USE_POSEDGE_REFCLK_MASK                                     0x00000200
-#define PHY_BB_MULTICHAIN_CONTROL_USE_POSEDGE_REFCLK_GET(x)                    (((x) & 0x00000200) >> 9)
-#define PHY_BB_MULTICHAIN_CONTROL_USE_POSEDGE_REFCLK_SET(x)                    (((x) << 9) & 0x00000200)
-#define PHY_BB_MULTICHAIN_CONTROL_CF_SHORT_SAT_MSB                                                    20
-#define PHY_BB_MULTICHAIN_CONTROL_CF_SHORT_SAT_LSB                                                    10
-#define PHY_BB_MULTICHAIN_CONTROL_CF_SHORT_SAT_MASK                                           0x001ffc00
-#define PHY_BB_MULTICHAIN_CONTROL_CF_SHORT_SAT_GET(x)                         (((x) & 0x001ffc00) >> 10)
-#define PHY_BB_MULTICHAIN_CONTROL_CF_SHORT_SAT_SET(x)                         (((x) << 10) & 0x001ffc00)
-#define PHY_BB_MULTICHAIN_CONTROL_FORCED_GAIN_DIFF_02_MSB                                             28
-#define PHY_BB_MULTICHAIN_CONTROL_FORCED_GAIN_DIFF_02_LSB                                             22
-#define PHY_BB_MULTICHAIN_CONTROL_FORCED_GAIN_DIFF_02_MASK                                    0x1fc00000
-#define PHY_BB_MULTICHAIN_CONTROL_FORCED_GAIN_DIFF_02_GET(x)                  (((x) & 0x1fc00000) >> 22)
-#define PHY_BB_MULTICHAIN_CONTROL_FORCED_GAIN_DIFF_02_SET(x)                  (((x) << 22) & 0x1fc00000)
-#define PHY_BB_MULTICHAIN_CONTROL_FORCE_SIGMA_ZERO_MSB                                                29
-#define PHY_BB_MULTICHAIN_CONTROL_FORCE_SIGMA_ZERO_LSB                                                29
-#define PHY_BB_MULTICHAIN_CONTROL_FORCE_SIGMA_ZERO_MASK                                       0x20000000
-#define PHY_BB_MULTICHAIN_CONTROL_FORCE_SIGMA_ZERO_GET(x)                     (((x) & 0x20000000) >> 29)
-#define PHY_BB_MULTICHAIN_CONTROL_FORCE_SIGMA_ZERO_SET(x)                     (((x) << 29) & 0x20000000)
-
-/* macros for BB_multichain_gain_ctrl */
-#define PHY_BB_MULTICHAIN_GAIN_CTRL_ADDRESS                                                   0x000099ac
-#define PHY_BB_MULTICHAIN_GAIN_CTRL_OFFSET                                                    0x000099ac
-#define PHY_BB_MULTICHAIN_GAIN_CTRL_QUICKDROP_LOW_MSB                                                  7
-#define PHY_BB_MULTICHAIN_GAIN_CTRL_QUICKDROP_LOW_LSB                                                  0
-#define PHY_BB_MULTICHAIN_GAIN_CTRL_QUICKDROP_LOW_MASK                                        0x000000ff
-#define PHY_BB_MULTICHAIN_GAIN_CTRL_QUICKDROP_LOW_GET(x)                       (((x) & 0x000000ff) >> 0)
-#define PHY_BB_MULTICHAIN_GAIN_CTRL_QUICKDROP_LOW_SET(x)                       (((x) << 0) & 0x000000ff)
-#define PHY_BB_MULTICHAIN_GAIN_CTRL_ENABLE_CHECK_STRONG_ANT_MSB                                        8
-#define PHY_BB_MULTICHAIN_GAIN_CTRL_ENABLE_CHECK_STRONG_ANT_LSB                                        8
-#define PHY_BB_MULTICHAIN_GAIN_CTRL_ENABLE_CHECK_STRONG_ANT_MASK                              0x00000100
-#define PHY_BB_MULTICHAIN_GAIN_CTRL_ENABLE_CHECK_STRONG_ANT_GET(x)             (((x) & 0x00000100) >> 8)
-#define PHY_BB_MULTICHAIN_GAIN_CTRL_ENABLE_CHECK_STRONG_ANT_SET(x)             (((x) << 8) & 0x00000100)
-#define PHY_BB_MULTICHAIN_GAIN_CTRL_ANT_FAST_DIV_BIAS_MSB                                             14
-#define PHY_BB_MULTICHAIN_GAIN_CTRL_ANT_FAST_DIV_BIAS_LSB                                              9
-#define PHY_BB_MULTICHAIN_GAIN_CTRL_ANT_FAST_DIV_BIAS_MASK                                    0x00007e00
-#define PHY_BB_MULTICHAIN_GAIN_CTRL_ANT_FAST_DIV_BIAS_GET(x)                   (((x) & 0x00007e00) >> 9)
-#define PHY_BB_MULTICHAIN_GAIN_CTRL_ANT_FAST_DIV_BIAS_SET(x)                   (((x) << 9) & 0x00007e00)
-#define PHY_BB_MULTICHAIN_GAIN_CTRL_CAP_GAIN_RATIO_SNR_MSB                                            20
-#define PHY_BB_MULTICHAIN_GAIN_CTRL_CAP_GAIN_RATIO_SNR_LSB                                            15
-#define PHY_BB_MULTICHAIN_GAIN_CTRL_CAP_GAIN_RATIO_SNR_MASK                                   0x001f8000
-#define PHY_BB_MULTICHAIN_GAIN_CTRL_CAP_GAIN_RATIO_SNR_GET(x)                 (((x) & 0x001f8000) >> 15)
-#define PHY_BB_MULTICHAIN_GAIN_CTRL_CAP_GAIN_RATIO_SNR_SET(x)                 (((x) << 15) & 0x001f8000)
-#define PHY_BB_MULTICHAIN_GAIN_CTRL_CAP_GAIN_RATIO_ENA_MSB                                            21
-#define PHY_BB_MULTICHAIN_GAIN_CTRL_CAP_GAIN_RATIO_ENA_LSB                                            21
-#define PHY_BB_MULTICHAIN_GAIN_CTRL_CAP_GAIN_RATIO_ENA_MASK                                   0x00200000
-#define PHY_BB_MULTICHAIN_GAIN_CTRL_CAP_GAIN_RATIO_ENA_GET(x)                 (((x) & 0x00200000) >> 21)
-#define PHY_BB_MULTICHAIN_GAIN_CTRL_CAP_GAIN_RATIO_ENA_SET(x)                 (((x) << 21) & 0x00200000)
-#define PHY_BB_MULTICHAIN_GAIN_CTRL_CAP_GAIN_RATIO_MODE_MSB                                           22
-#define PHY_BB_MULTICHAIN_GAIN_CTRL_CAP_GAIN_RATIO_MODE_LSB                                           22
-#define PHY_BB_MULTICHAIN_GAIN_CTRL_CAP_GAIN_RATIO_MODE_MASK                                  0x00400000
-#define PHY_BB_MULTICHAIN_GAIN_CTRL_CAP_GAIN_RATIO_MODE_GET(x)                (((x) & 0x00400000) >> 22)
-#define PHY_BB_MULTICHAIN_GAIN_CTRL_CAP_GAIN_RATIO_MODE_SET(x)                (((x) << 22) & 0x00400000)
-#define PHY_BB_MULTICHAIN_GAIN_CTRL_ENABLE_ANT_SW_RX_PROT_MSB                                         23
-#define PHY_BB_MULTICHAIN_GAIN_CTRL_ENABLE_ANT_SW_RX_PROT_LSB                                         23
-#define PHY_BB_MULTICHAIN_GAIN_CTRL_ENABLE_ANT_SW_RX_PROT_MASK                                0x00800000
-#define PHY_BB_MULTICHAIN_GAIN_CTRL_ENABLE_ANT_SW_RX_PROT_GET(x)              (((x) & 0x00800000) >> 23)
-#define PHY_BB_MULTICHAIN_GAIN_CTRL_ENABLE_ANT_SW_RX_PROT_SET(x)              (((x) << 23) & 0x00800000)
-#define PHY_BB_MULTICHAIN_GAIN_CTRL_ENABLE_ANT_DIV_LNADIV_MSB                                         24
-#define PHY_BB_MULTICHAIN_GAIN_CTRL_ENABLE_ANT_DIV_LNADIV_LSB                                         24
-#define PHY_BB_MULTICHAIN_GAIN_CTRL_ENABLE_ANT_DIV_LNADIV_MASK                                0x01000000
-#define PHY_BB_MULTICHAIN_GAIN_CTRL_ENABLE_ANT_DIV_LNADIV_GET(x)              (((x) & 0x01000000) >> 24)
-#define PHY_BB_MULTICHAIN_GAIN_CTRL_ENABLE_ANT_DIV_LNADIV_SET(x)              (((x) << 24) & 0x01000000)
-#define PHY_BB_MULTICHAIN_GAIN_CTRL_ANT_DIV_ALT_LNACONF_MSB                                           26
-#define PHY_BB_MULTICHAIN_GAIN_CTRL_ANT_DIV_ALT_LNACONF_LSB                                           25
-#define PHY_BB_MULTICHAIN_GAIN_CTRL_ANT_DIV_ALT_LNACONF_MASK                                  0x06000000
-#define PHY_BB_MULTICHAIN_GAIN_CTRL_ANT_DIV_ALT_LNACONF_GET(x)                (((x) & 0x06000000) >> 25)
-#define PHY_BB_MULTICHAIN_GAIN_CTRL_ANT_DIV_ALT_LNACONF_SET(x)                (((x) << 25) & 0x06000000)
-#define PHY_BB_MULTICHAIN_GAIN_CTRL_ANT_DIV_MAIN_LNACONF_MSB                                          28
-#define PHY_BB_MULTICHAIN_GAIN_CTRL_ANT_DIV_MAIN_LNACONF_LSB                                          27
-#define PHY_BB_MULTICHAIN_GAIN_CTRL_ANT_DIV_MAIN_LNACONF_MASK                                 0x18000000
-#define PHY_BB_MULTICHAIN_GAIN_CTRL_ANT_DIV_MAIN_LNACONF_GET(x)               (((x) & 0x18000000) >> 27)
-#define PHY_BB_MULTICHAIN_GAIN_CTRL_ANT_DIV_MAIN_LNACONF_SET(x)               (((x) << 27) & 0x18000000)
-#define PHY_BB_MULTICHAIN_GAIN_CTRL_ANT_DIV_ALT_GAINTB_MSB                                            29
-#define PHY_BB_MULTICHAIN_GAIN_CTRL_ANT_DIV_ALT_GAINTB_LSB                                            29
-#define PHY_BB_MULTICHAIN_GAIN_CTRL_ANT_DIV_ALT_GAINTB_MASK                                   0x20000000
-#define PHY_BB_MULTICHAIN_GAIN_CTRL_ANT_DIV_ALT_GAINTB_GET(x)                 (((x) & 0x20000000) >> 29)
-#define PHY_BB_MULTICHAIN_GAIN_CTRL_ANT_DIV_ALT_GAINTB_SET(x)                 (((x) << 29) & 0x20000000)
-#define PHY_BB_MULTICHAIN_GAIN_CTRL_ANT_DIV_MAIN_GAINTB_MSB                                           30
-#define PHY_BB_MULTICHAIN_GAIN_CTRL_ANT_DIV_MAIN_GAINTB_LSB                                           30
-#define PHY_BB_MULTICHAIN_GAIN_CTRL_ANT_DIV_MAIN_GAINTB_MASK                                  0x40000000
-#define PHY_BB_MULTICHAIN_GAIN_CTRL_ANT_DIV_MAIN_GAINTB_GET(x)                (((x) & 0x40000000) >> 30)
-#define PHY_BB_MULTICHAIN_GAIN_CTRL_ANT_DIV_MAIN_GAINTB_SET(x)                (((x) << 30) & 0x40000000)
-
-/* macros for BB_adc_gain_dc_corr_b0 */
-#define PHY_BB_ADC_GAIN_DC_CORR_B0_ADDRESS                                                    0x000099b4
-#define PHY_BB_ADC_GAIN_DC_CORR_B0_OFFSET                                                     0x000099b4
-#define PHY_BB_ADC_GAIN_DC_CORR_B0_ADC_GAIN_CORR_Q_COEFF_0_MSB                                         5
-#define PHY_BB_ADC_GAIN_DC_CORR_B0_ADC_GAIN_CORR_Q_COEFF_0_LSB                                         0
-#define PHY_BB_ADC_GAIN_DC_CORR_B0_ADC_GAIN_CORR_Q_COEFF_0_MASK                               0x0000003f
-#define PHY_BB_ADC_GAIN_DC_CORR_B0_ADC_GAIN_CORR_Q_COEFF_0_GET(x)              (((x) & 0x0000003f) >> 0)
-#define PHY_BB_ADC_GAIN_DC_CORR_B0_ADC_GAIN_CORR_Q_COEFF_0_SET(x)              (((x) << 0) & 0x0000003f)
-#define PHY_BB_ADC_GAIN_DC_CORR_B0_ADC_GAIN_CORR_I_COEFF_0_MSB                                        11
-#define PHY_BB_ADC_GAIN_DC_CORR_B0_ADC_GAIN_CORR_I_COEFF_0_LSB                                         6
-#define PHY_BB_ADC_GAIN_DC_CORR_B0_ADC_GAIN_CORR_I_COEFF_0_MASK                               0x00000fc0
-#define PHY_BB_ADC_GAIN_DC_CORR_B0_ADC_GAIN_CORR_I_COEFF_0_GET(x)              (((x) & 0x00000fc0) >> 6)
-#define PHY_BB_ADC_GAIN_DC_CORR_B0_ADC_GAIN_CORR_I_COEFF_0_SET(x)              (((x) << 6) & 0x00000fc0)
-#define PHY_BB_ADC_GAIN_DC_CORR_B0_ADC_DC_CORR_Q_COEFF_0_MSB                                          20
-#define PHY_BB_ADC_GAIN_DC_CORR_B0_ADC_DC_CORR_Q_COEFF_0_LSB                                          12
-#define PHY_BB_ADC_GAIN_DC_CORR_B0_ADC_DC_CORR_Q_COEFF_0_MASK                                 0x001ff000
-#define PHY_BB_ADC_GAIN_DC_CORR_B0_ADC_DC_CORR_Q_COEFF_0_GET(x)               (((x) & 0x001ff000) >> 12)
-#define PHY_BB_ADC_GAIN_DC_CORR_B0_ADC_DC_CORR_Q_COEFF_0_SET(x)               (((x) << 12) & 0x001ff000)
-#define PHY_BB_ADC_GAIN_DC_CORR_B0_ADC_DC_CORR_I_COEFF_0_MSB                                          29
-#define PHY_BB_ADC_GAIN_DC_CORR_B0_ADC_DC_CORR_I_COEFF_0_LSB                                          21
-#define PHY_BB_ADC_GAIN_DC_CORR_B0_ADC_DC_CORR_I_COEFF_0_MASK                                 0x3fe00000
-#define PHY_BB_ADC_GAIN_DC_CORR_B0_ADC_DC_CORR_I_COEFF_0_GET(x)               (((x) & 0x3fe00000) >> 21)
-#define PHY_BB_ADC_GAIN_DC_CORR_B0_ADC_DC_CORR_I_COEFF_0_SET(x)               (((x) << 21) & 0x3fe00000)
-#define PHY_BB_ADC_GAIN_DC_CORR_B0_ADC_GAIN_CORR_ENABLE_MSB                                           30
-#define PHY_BB_ADC_GAIN_DC_CORR_B0_ADC_GAIN_CORR_ENABLE_LSB                                           30
-#define PHY_BB_ADC_GAIN_DC_CORR_B0_ADC_GAIN_CORR_ENABLE_MASK                                  0x40000000
-#define PHY_BB_ADC_GAIN_DC_CORR_B0_ADC_GAIN_CORR_ENABLE_GET(x)                (((x) & 0x40000000) >> 30)
-#define PHY_BB_ADC_GAIN_DC_CORR_B0_ADC_GAIN_CORR_ENABLE_SET(x)                (((x) << 30) & 0x40000000)
-#define PHY_BB_ADC_GAIN_DC_CORR_B0_ADC_DC_CORR_ENABLE_MSB                                             31
-#define PHY_BB_ADC_GAIN_DC_CORR_B0_ADC_DC_CORR_ENABLE_LSB                                             31
-#define PHY_BB_ADC_GAIN_DC_CORR_B0_ADC_DC_CORR_ENABLE_MASK                                    0x80000000
-#define PHY_BB_ADC_GAIN_DC_CORR_B0_ADC_DC_CORR_ENABLE_GET(x)                  (((x) & 0x80000000) >> 31)
-#define PHY_BB_ADC_GAIN_DC_CORR_B0_ADC_DC_CORR_ENABLE_SET(x)                  (((x) << 31) & 0x80000000)
-
-/* macros for BB_ext_chan_pwr_thr_1 */
-#define PHY_BB_EXT_CHAN_PWR_THR_1_ADDRESS                                                     0x000099b8
-#define PHY_BB_EXT_CHAN_PWR_THR_1_OFFSET                                                      0x000099b8
-#define PHY_BB_EXT_CHAN_PWR_THR_1_THRESH62_EXT_MSB                                                     7
-#define PHY_BB_EXT_CHAN_PWR_THR_1_THRESH62_EXT_LSB                                                     0
-#define PHY_BB_EXT_CHAN_PWR_THR_1_THRESH62_EXT_MASK                                           0x000000ff
-#define PHY_BB_EXT_CHAN_PWR_THR_1_THRESH62_EXT_GET(x)                          (((x) & 0x000000ff) >> 0)
-#define PHY_BB_EXT_CHAN_PWR_THR_1_THRESH62_EXT_SET(x)                          (((x) << 0) & 0x000000ff)
-#define PHY_BB_EXT_CHAN_PWR_THR_1_ANT_DIV_ALT_ANT_MINGAINIDX_MSB                                      15
-#define PHY_BB_EXT_CHAN_PWR_THR_1_ANT_DIV_ALT_ANT_MINGAINIDX_LSB                                       8
-#define PHY_BB_EXT_CHAN_PWR_THR_1_ANT_DIV_ALT_ANT_MINGAINIDX_MASK                             0x0000ff00
-#define PHY_BB_EXT_CHAN_PWR_THR_1_ANT_DIV_ALT_ANT_MINGAINIDX_GET(x)            (((x) & 0x0000ff00) >> 8)
-#define PHY_BB_EXT_CHAN_PWR_THR_1_ANT_DIV_ALT_ANT_MINGAINIDX_SET(x)            (((x) << 8) & 0x0000ff00)
-#define PHY_BB_EXT_CHAN_PWR_THR_1_ANT_DIV_ALT_ANT_DELTAGAINIDX_MSB                                    20
-#define PHY_BB_EXT_CHAN_PWR_THR_1_ANT_DIV_ALT_ANT_DELTAGAINIDX_LSB                                    16
-#define PHY_BB_EXT_CHAN_PWR_THR_1_ANT_DIV_ALT_ANT_DELTAGAINIDX_MASK                           0x001f0000
-#define PHY_BB_EXT_CHAN_PWR_THR_1_ANT_DIV_ALT_ANT_DELTAGAINIDX_GET(x)         (((x) & 0x001f0000) >> 16)
-#define PHY_BB_EXT_CHAN_PWR_THR_1_ANT_DIV_ALT_ANT_DELTAGAINIDX_SET(x)         (((x) << 16) & 0x001f0000)
-#define PHY_BB_EXT_CHAN_PWR_THR_1_ANT_DIV_ALT_ANT_DELTANF_MSB                                         26
-#define PHY_BB_EXT_CHAN_PWR_THR_1_ANT_DIV_ALT_ANT_DELTANF_LSB                                         21
-#define PHY_BB_EXT_CHAN_PWR_THR_1_ANT_DIV_ALT_ANT_DELTANF_MASK                                0x07e00000
-#define PHY_BB_EXT_CHAN_PWR_THR_1_ANT_DIV_ALT_ANT_DELTANF_GET(x)              (((x) & 0x07e00000) >> 21)
-#define PHY_BB_EXT_CHAN_PWR_THR_1_ANT_DIV_ALT_ANT_DELTANF_SET(x)              (((x) << 21) & 0x07e00000)
-
-/* macros for BB_ext_chan_pwr_thr_2_b0 */
-#define PHY_BB_EXT_CHAN_PWR_THR_2_B0_ADDRESS                                                  0x000099bc
-#define PHY_BB_EXT_CHAN_PWR_THR_2_B0_OFFSET                                                   0x000099bc
-#define PHY_BB_EXT_CHAN_PWR_THR_2_B0_CF_MAXCCAPWR_EXT_0_MSB                                            8
-#define PHY_BB_EXT_CHAN_PWR_THR_2_B0_CF_MAXCCAPWR_EXT_0_LSB                                            0
-#define PHY_BB_EXT_CHAN_PWR_THR_2_B0_CF_MAXCCAPWR_EXT_0_MASK                                  0x000001ff
-#define PHY_BB_EXT_CHAN_PWR_THR_2_B0_CF_MAXCCAPWR_EXT_0_GET(x)                 (((x) & 0x000001ff) >> 0)
-#define PHY_BB_EXT_CHAN_PWR_THR_2_B0_CF_MAXCCAPWR_EXT_0_SET(x)                 (((x) << 0) & 0x000001ff)
-#define PHY_BB_EXT_CHAN_PWR_THR_2_B0_CYCPWR_THR1_EXT_MSB                                              15
-#define PHY_BB_EXT_CHAN_PWR_THR_2_B0_CYCPWR_THR1_EXT_LSB                                               9
-#define PHY_BB_EXT_CHAN_PWR_THR_2_B0_CYCPWR_THR1_EXT_MASK                                     0x0000fe00
-#define PHY_BB_EXT_CHAN_PWR_THR_2_B0_CYCPWR_THR1_EXT_GET(x)                    (((x) & 0x0000fe00) >> 9)
-#define PHY_BB_EXT_CHAN_PWR_THR_2_B0_CYCPWR_THR1_EXT_SET(x)                    (((x) << 9) & 0x0000fe00)
-#define PHY_BB_EXT_CHAN_PWR_THR_2_B0_MINCCAPWR_EXT_0_MSB                                              24
-#define PHY_BB_EXT_CHAN_PWR_THR_2_B0_MINCCAPWR_EXT_0_LSB                                              16
-#define PHY_BB_EXT_CHAN_PWR_THR_2_B0_MINCCAPWR_EXT_0_MASK                                     0x01ff0000
-#define PHY_BB_EXT_CHAN_PWR_THR_2_B0_MINCCAPWR_EXT_0_GET(x)                   (((x) & 0x01ff0000) >> 16)
-
-/* macros for BB_ext_chan_scorr_thr */
-#define PHY_BB_EXT_CHAN_SCORR_THR_ADDRESS                                                     0x000099c0
-#define PHY_BB_EXT_CHAN_SCORR_THR_OFFSET                                                      0x000099c0
-#define PHY_BB_EXT_CHAN_SCORR_THR_M1_THRES_EXT_MSB                                                     6
-#define PHY_BB_EXT_CHAN_SCORR_THR_M1_THRES_EXT_LSB                                                     0
-#define PHY_BB_EXT_CHAN_SCORR_THR_M1_THRES_EXT_MASK                                           0x0000007f
-#define PHY_BB_EXT_CHAN_SCORR_THR_M1_THRES_EXT_GET(x)                          (((x) & 0x0000007f) >> 0)
-#define PHY_BB_EXT_CHAN_SCORR_THR_M1_THRES_EXT_SET(x)                          (((x) << 0) & 0x0000007f)
-#define PHY_BB_EXT_CHAN_SCORR_THR_M2_THRES_EXT_MSB                                                    13
-#define PHY_BB_EXT_CHAN_SCORR_THR_M2_THRES_EXT_LSB                                                     7
-#define PHY_BB_EXT_CHAN_SCORR_THR_M2_THRES_EXT_MASK                                           0x00003f80
-#define PHY_BB_EXT_CHAN_SCORR_THR_M2_THRES_EXT_GET(x)                          (((x) & 0x00003f80) >> 7)
-#define PHY_BB_EXT_CHAN_SCORR_THR_M2_THRES_EXT_SET(x)                          (((x) << 7) & 0x00003f80)
-#define PHY_BB_EXT_CHAN_SCORR_THR_M1_THRES_LOW_EXT_MSB                                                20
-#define PHY_BB_EXT_CHAN_SCORR_THR_M1_THRES_LOW_EXT_LSB                                                14
-#define PHY_BB_EXT_CHAN_SCORR_THR_M1_THRES_LOW_EXT_MASK                                       0x001fc000
-#define PHY_BB_EXT_CHAN_SCORR_THR_M1_THRES_LOW_EXT_GET(x)                     (((x) & 0x001fc000) >> 14)
-#define PHY_BB_EXT_CHAN_SCORR_THR_M1_THRES_LOW_EXT_SET(x)                     (((x) << 14) & 0x001fc000)
-#define PHY_BB_EXT_CHAN_SCORR_THR_M2_THRES_LOW_EXT_MSB                                                27
-#define PHY_BB_EXT_CHAN_SCORR_THR_M2_THRES_LOW_EXT_LSB                                                21
-#define PHY_BB_EXT_CHAN_SCORR_THR_M2_THRES_LOW_EXT_MASK                                       0x0fe00000
-#define PHY_BB_EXT_CHAN_SCORR_THR_M2_THRES_LOW_EXT_GET(x)                     (((x) & 0x0fe00000) >> 21)
-#define PHY_BB_EXT_CHAN_SCORR_THR_M2_THRES_LOW_EXT_SET(x)                     (((x) << 21) & 0x0fe00000)
-#define PHY_BB_EXT_CHAN_SCORR_THR_SPUR_SUBCHANNEL_SD_MSB                                              28
-#define PHY_BB_EXT_CHAN_SCORR_THR_SPUR_SUBCHANNEL_SD_LSB                                              28
-#define PHY_BB_EXT_CHAN_SCORR_THR_SPUR_SUBCHANNEL_SD_MASK                                     0x10000000
-#define PHY_BB_EXT_CHAN_SCORR_THR_SPUR_SUBCHANNEL_SD_GET(x)                   (((x) & 0x10000000) >> 28)
-#define PHY_BB_EXT_CHAN_SCORR_THR_SPUR_SUBCHANNEL_SD_SET(x)                   (((x) << 28) & 0x10000000)
-
-/* macros for BB_ext_chan_detect_win */
-#define PHY_BB_EXT_CHAN_DETECT_WIN_ADDRESS                                                    0x000099c4
-#define PHY_BB_EXT_CHAN_DETECT_WIN_OFFSET                                                     0x000099c4
-#define PHY_BB_EXT_CHAN_DETECT_WIN_DET_DIFF_WIN_WEAK_MSB                                               3
-#define PHY_BB_EXT_CHAN_DETECT_WIN_DET_DIFF_WIN_WEAK_LSB                                               0
-#define PHY_BB_EXT_CHAN_DETECT_WIN_DET_DIFF_WIN_WEAK_MASK                                     0x0000000f
-#define PHY_BB_EXT_CHAN_DETECT_WIN_DET_DIFF_WIN_WEAK_GET(x)                    (((x) & 0x0000000f) >> 0)
-#define PHY_BB_EXT_CHAN_DETECT_WIN_DET_DIFF_WIN_WEAK_SET(x)                    (((x) << 0) & 0x0000000f)
-#define PHY_BB_EXT_CHAN_DETECT_WIN_DET_DIFF_WIN_WEAK_LOW_MSB                                           7
-#define PHY_BB_EXT_CHAN_DETECT_WIN_DET_DIFF_WIN_WEAK_LOW_LSB                                           4
-#define PHY_BB_EXT_CHAN_DETECT_WIN_DET_DIFF_WIN_WEAK_LOW_MASK                                 0x000000f0
-#define PHY_BB_EXT_CHAN_DETECT_WIN_DET_DIFF_WIN_WEAK_LOW_GET(x)                (((x) & 0x000000f0) >> 4)
-#define PHY_BB_EXT_CHAN_DETECT_WIN_DET_DIFF_WIN_WEAK_LOW_SET(x)                (((x) << 4) & 0x000000f0)
-#define PHY_BB_EXT_CHAN_DETECT_WIN_DET_DIFF_WIN_WEAK_CCK_MSB                                          12
-#define PHY_BB_EXT_CHAN_DETECT_WIN_DET_DIFF_WIN_WEAK_CCK_LSB                                           8
-#define PHY_BB_EXT_CHAN_DETECT_WIN_DET_DIFF_WIN_WEAK_CCK_MASK                                 0x00001f00
-#define PHY_BB_EXT_CHAN_DETECT_WIN_DET_DIFF_WIN_WEAK_CCK_GET(x)                (((x) & 0x00001f00) >> 8)
-#define PHY_BB_EXT_CHAN_DETECT_WIN_DET_DIFF_WIN_WEAK_CCK_SET(x)                (((x) << 8) & 0x00001f00)
-#define PHY_BB_EXT_CHAN_DETECT_WIN_DET_20H_COUNT_MSB                                                  15
-#define PHY_BB_EXT_CHAN_DETECT_WIN_DET_20H_COUNT_LSB                                                  13
-#define PHY_BB_EXT_CHAN_DETECT_WIN_DET_20H_COUNT_MASK                                         0x0000e000
-#define PHY_BB_EXT_CHAN_DETECT_WIN_DET_20H_COUNT_GET(x)                       (((x) & 0x0000e000) >> 13)
-#define PHY_BB_EXT_CHAN_DETECT_WIN_DET_20H_COUNT_SET(x)                       (((x) << 13) & 0x0000e000)
-#define PHY_BB_EXT_CHAN_DETECT_WIN_DET_EXT_BLK_COUNT_MSB                                              18
-#define PHY_BB_EXT_CHAN_DETECT_WIN_DET_EXT_BLK_COUNT_LSB                                              16
-#define PHY_BB_EXT_CHAN_DETECT_WIN_DET_EXT_BLK_COUNT_MASK                                     0x00070000
-#define PHY_BB_EXT_CHAN_DETECT_WIN_DET_EXT_BLK_COUNT_GET(x)                   (((x) & 0x00070000) >> 16)
-#define PHY_BB_EXT_CHAN_DETECT_WIN_DET_EXT_BLK_COUNT_SET(x)                   (((x) << 16) & 0x00070000)
-#define PHY_BB_EXT_CHAN_DETECT_WIN_WEAK_SIG_THR_CCK_EXT_MSB                                           24
-#define PHY_BB_EXT_CHAN_DETECT_WIN_WEAK_SIG_THR_CCK_EXT_LSB                                           19
-#define PHY_BB_EXT_CHAN_DETECT_WIN_WEAK_SIG_THR_CCK_EXT_MASK                                  0x01f80000
-#define PHY_BB_EXT_CHAN_DETECT_WIN_WEAK_SIG_THR_CCK_EXT_GET(x)                (((x) & 0x01f80000) >> 19)
-#define PHY_BB_EXT_CHAN_DETECT_WIN_WEAK_SIG_THR_CCK_EXT_SET(x)                (((x) << 19) & 0x01f80000)
-#define PHY_BB_EXT_CHAN_DETECT_WIN_DET_DIFF_WIN_THRESH_MSB                                            28
-#define PHY_BB_EXT_CHAN_DETECT_WIN_DET_DIFF_WIN_THRESH_LSB                                            25
-#define PHY_BB_EXT_CHAN_DETECT_WIN_DET_DIFF_WIN_THRESH_MASK                                   0x1e000000
-#define PHY_BB_EXT_CHAN_DETECT_WIN_DET_DIFF_WIN_THRESH_GET(x)                 (((x) & 0x1e000000) >> 25)
-#define PHY_BB_EXT_CHAN_DETECT_WIN_DET_DIFF_WIN_THRESH_SET(x)                 (((x) << 25) & 0x1e000000)
-
-/* macros for BB_pwr_thr_20_40_det */
-#define PHY_BB_PWR_THR_20_40_DET_ADDRESS                                                      0x000099c8
-#define PHY_BB_PWR_THR_20_40_DET_OFFSET                                                       0x000099c8
-#define PHY_BB_PWR_THR_20_40_DET_PWRDIFF40_THRSTR_MSB                                                  4
-#define PHY_BB_PWR_THR_20_40_DET_PWRDIFF40_THRSTR_LSB                                                  0
-#define PHY_BB_PWR_THR_20_40_DET_PWRDIFF40_THRSTR_MASK                                        0x0000001f
-#define PHY_BB_PWR_THR_20_40_DET_PWRDIFF40_THRSTR_GET(x)                       (((x) & 0x0000001f) >> 0)
-#define PHY_BB_PWR_THR_20_40_DET_PWRDIFF40_THRSTR_SET(x)                       (((x) << 0) & 0x0000001f)
-#define PHY_BB_PWR_THR_20_40_DET_BLOCKER40_MAX_MSB                                                    10
-#define PHY_BB_PWR_THR_20_40_DET_BLOCKER40_MAX_LSB                                                     5
-#define PHY_BB_PWR_THR_20_40_DET_BLOCKER40_MAX_MASK                                           0x000007e0
-#define PHY_BB_PWR_THR_20_40_DET_BLOCKER40_MAX_GET(x)                          (((x) & 0x000007e0) >> 5)
-#define PHY_BB_PWR_THR_20_40_DET_BLOCKER40_MAX_SET(x)                          (((x) << 5) & 0x000007e0)
-#define PHY_BB_PWR_THR_20_40_DET_DET40_PWRSTEP_MAX_MSB                                                15
-#define PHY_BB_PWR_THR_20_40_DET_DET40_PWRSTEP_MAX_LSB                                                11
-#define PHY_BB_PWR_THR_20_40_DET_DET40_PWRSTEP_MAX_MASK                                       0x0000f800
-#define PHY_BB_PWR_THR_20_40_DET_DET40_PWRSTEP_MAX_GET(x)                     (((x) & 0x0000f800) >> 11)
-#define PHY_BB_PWR_THR_20_40_DET_DET40_PWRSTEP_MAX_SET(x)                     (((x) << 11) & 0x0000f800)
-#define PHY_BB_PWR_THR_20_40_DET_DET40_THR_SNR_MSB                                                    23
-#define PHY_BB_PWR_THR_20_40_DET_DET40_THR_SNR_LSB                                                    16
-#define PHY_BB_PWR_THR_20_40_DET_DET40_THR_SNR_MASK                                           0x00ff0000
-#define PHY_BB_PWR_THR_20_40_DET_DET40_THR_SNR_GET(x)                         (((x) & 0x00ff0000) >> 16)
-#define PHY_BB_PWR_THR_20_40_DET_DET40_THR_SNR_SET(x)                         (((x) << 16) & 0x00ff0000)
-#define PHY_BB_PWR_THR_20_40_DET_DET40_PRI_BIAS_MSB                                                   28
-#define PHY_BB_PWR_THR_20_40_DET_DET40_PRI_BIAS_LSB                                                   24
-#define PHY_BB_PWR_THR_20_40_DET_DET40_PRI_BIAS_MASK                                          0x1f000000
-#define PHY_BB_PWR_THR_20_40_DET_DET40_PRI_BIAS_GET(x)                        (((x) & 0x1f000000) >> 24)
-#define PHY_BB_PWR_THR_20_40_DET_DET40_PRI_BIAS_SET(x)                        (((x) << 24) & 0x1f000000)
-#define PHY_BB_PWR_THR_20_40_DET_PWRSTEP40_ENA_MSB                                                    29
-#define PHY_BB_PWR_THR_20_40_DET_PWRSTEP40_ENA_LSB                                                    29
-#define PHY_BB_PWR_THR_20_40_DET_PWRSTEP40_ENA_MASK                                           0x20000000
-#define PHY_BB_PWR_THR_20_40_DET_PWRSTEP40_ENA_GET(x)                         (((x) & 0x20000000) >> 29)
-#define PHY_BB_PWR_THR_20_40_DET_PWRSTEP40_ENA_SET(x)                         (((x) << 29) & 0x20000000)
-#define PHY_BB_PWR_THR_20_40_DET_LOWSNR40_ENA_MSB                                                     30
-#define PHY_BB_PWR_THR_20_40_DET_LOWSNR40_ENA_LSB                                                     30
-#define PHY_BB_PWR_THR_20_40_DET_LOWSNR40_ENA_MASK                                            0x40000000
-#define PHY_BB_PWR_THR_20_40_DET_LOWSNR40_ENA_GET(x)                          (((x) & 0x40000000) >> 30)
-#define PHY_BB_PWR_THR_20_40_DET_LOWSNR40_ENA_SET(x)                          (((x) << 30) & 0x40000000)
-
-/* macros for BB_short_gi_delta_slope */
-#define PHY_BB_SHORT_GI_DELTA_SLOPE_ADDRESS                                                   0x000099d0
-#define PHY_BB_SHORT_GI_DELTA_SLOPE_OFFSET                                                    0x000099d0
-#define PHY_BB_SHORT_GI_DELTA_SLOPE_DELTA_SLOPE_COEF_EXP_SHORT_GI_MSB                                  3
-#define PHY_BB_SHORT_GI_DELTA_SLOPE_DELTA_SLOPE_COEF_EXP_SHORT_GI_LSB                                  0
-#define PHY_BB_SHORT_GI_DELTA_SLOPE_DELTA_SLOPE_COEF_EXP_SHORT_GI_MASK                        0x0000000f
-#define PHY_BB_SHORT_GI_DELTA_SLOPE_DELTA_SLOPE_COEF_EXP_SHORT_GI_GET(x)       (((x) & 0x0000000f) >> 0)
-#define PHY_BB_SHORT_GI_DELTA_SLOPE_DELTA_SLOPE_COEF_EXP_SHORT_GI_SET(x)       (((x) << 0) & 0x0000000f)
-#define PHY_BB_SHORT_GI_DELTA_SLOPE_DELTA_SLOPE_COEF_MAN_SHORT_GI_MSB                                 18
-#define PHY_BB_SHORT_GI_DELTA_SLOPE_DELTA_SLOPE_COEF_MAN_SHORT_GI_LSB                                  4
-#define PHY_BB_SHORT_GI_DELTA_SLOPE_DELTA_SLOPE_COEF_MAN_SHORT_GI_MASK                        0x0007fff0
-#define PHY_BB_SHORT_GI_DELTA_SLOPE_DELTA_SLOPE_COEF_MAN_SHORT_GI_GET(x)       (((x) & 0x0007fff0) >> 4)
-#define PHY_BB_SHORT_GI_DELTA_SLOPE_DELTA_SLOPE_COEF_MAN_SHORT_GI_SET(x)       (((x) << 4) & 0x0007fff0)
-
-/* macros for BB_chaninfo_ctrl */
-#define PHY_BB_CHANINFO_CTRL_ADDRESS                                                          0x000099dc
-#define PHY_BB_CHANINFO_CTRL_OFFSET                                                           0x000099dc
-#define PHY_BB_CHANINFO_CTRL_CAPTURE_CHAN_INFO_MSB                                                     0
-#define PHY_BB_CHANINFO_CTRL_CAPTURE_CHAN_INFO_LSB                                                     0
-#define PHY_BB_CHANINFO_CTRL_CAPTURE_CHAN_INFO_MASK                                           0x00000001
-#define PHY_BB_CHANINFO_CTRL_CAPTURE_CHAN_INFO_GET(x)                          (((x) & 0x00000001) >> 0)
-#define PHY_BB_CHANINFO_CTRL_CAPTURE_CHAN_INFO_SET(x)                          (((x) << 0) & 0x00000001)
-#define PHY_BB_CHANINFO_CTRL_DISABLE_CHANINFOMEM_MSB                                                   1
-#define PHY_BB_CHANINFO_CTRL_DISABLE_CHANINFOMEM_LSB                                                   1
-#define PHY_BB_CHANINFO_CTRL_DISABLE_CHANINFOMEM_MASK                                         0x00000002
-#define PHY_BB_CHANINFO_CTRL_DISABLE_CHANINFOMEM_GET(x)                        (((x) & 0x00000002) >> 1)
-#define PHY_BB_CHANINFO_CTRL_DISABLE_CHANINFOMEM_SET(x)                        (((x) << 1) & 0x00000002)
-
-/* macros for BB_heavy_clip_ctrl */
-#define PHY_BB_HEAVY_CLIP_CTRL_ADDRESS                                                        0x000099e0
-#define PHY_BB_HEAVY_CLIP_CTRL_OFFSET                                                         0x000099e0
-#define PHY_BB_HEAVY_CLIP_CTRL_CF_HEAVY_CLIP_ENABLE_MSB                                                8
-#define PHY_BB_HEAVY_CLIP_CTRL_CF_HEAVY_CLIP_ENABLE_LSB                                                0
-#define PHY_BB_HEAVY_CLIP_CTRL_CF_HEAVY_CLIP_ENABLE_MASK                                      0x000001ff
-#define PHY_BB_HEAVY_CLIP_CTRL_CF_HEAVY_CLIP_ENABLE_GET(x)                     (((x) & 0x000001ff) >> 0)
-#define PHY_BB_HEAVY_CLIP_CTRL_CF_HEAVY_CLIP_ENABLE_SET(x)                     (((x) << 0) & 0x000001ff)
-#define PHY_BB_HEAVY_CLIP_CTRL_PRE_EMP_HT40_ENABLE_MSB                                                 9
-#define PHY_BB_HEAVY_CLIP_CTRL_PRE_EMP_HT40_ENABLE_LSB                                                 9
-#define PHY_BB_HEAVY_CLIP_CTRL_PRE_EMP_HT40_ENABLE_MASK                                       0x00000200
-#define PHY_BB_HEAVY_CLIP_CTRL_PRE_EMP_HT40_ENABLE_GET(x)                      (((x) & 0x00000200) >> 9)
-#define PHY_BB_HEAVY_CLIP_CTRL_PRE_EMP_HT40_ENABLE_SET(x)                      (((x) << 9) & 0x00000200)
-
-/* macros for BB_heavy_clip_20 */
-#define PHY_BB_HEAVY_CLIP_20_ADDRESS                                                          0x000099e4
-#define PHY_BB_HEAVY_CLIP_20_OFFSET                                                           0x000099e4
-#define PHY_BB_HEAVY_CLIP_20_HEAVY_CLIP_FACTOR_0_MSB                                                   7
-#define PHY_BB_HEAVY_CLIP_20_HEAVY_CLIP_FACTOR_0_LSB                                                   0
-#define PHY_BB_HEAVY_CLIP_20_HEAVY_CLIP_FACTOR_0_MASK                                         0x000000ff
-#define PHY_BB_HEAVY_CLIP_20_HEAVY_CLIP_FACTOR_0_GET(x)                        (((x) & 0x000000ff) >> 0)
-#define PHY_BB_HEAVY_CLIP_20_HEAVY_CLIP_FACTOR_0_SET(x)                        (((x) << 0) & 0x000000ff)
-#define PHY_BB_HEAVY_CLIP_20_HEAVY_CLIP_FACTOR_1_MSB                                                  15
-#define PHY_BB_HEAVY_CLIP_20_HEAVY_CLIP_FACTOR_1_LSB                                                   8
-#define PHY_BB_HEAVY_CLIP_20_HEAVY_CLIP_FACTOR_1_MASK                                         0x0000ff00
-#define PHY_BB_HEAVY_CLIP_20_HEAVY_CLIP_FACTOR_1_GET(x)                        (((x) & 0x0000ff00) >> 8)
-#define PHY_BB_HEAVY_CLIP_20_HEAVY_CLIP_FACTOR_1_SET(x)                        (((x) << 8) & 0x0000ff00)
-#define PHY_BB_HEAVY_CLIP_20_HEAVY_CLIP_FACTOR_2_MSB                                                  23
-#define PHY_BB_HEAVY_CLIP_20_HEAVY_CLIP_FACTOR_2_LSB                                                  16
-#define PHY_BB_HEAVY_CLIP_20_HEAVY_CLIP_FACTOR_2_MASK                                         0x00ff0000
-#define PHY_BB_HEAVY_CLIP_20_HEAVY_CLIP_FACTOR_2_GET(x)                       (((x) & 0x00ff0000) >> 16)
-#define PHY_BB_HEAVY_CLIP_20_HEAVY_CLIP_FACTOR_2_SET(x)                       (((x) << 16) & 0x00ff0000)
-#define PHY_BB_HEAVY_CLIP_20_HEAVY_CLIP_FACTOR_3_MSB                                                  31
-#define PHY_BB_HEAVY_CLIP_20_HEAVY_CLIP_FACTOR_3_LSB                                                  24
-#define PHY_BB_HEAVY_CLIP_20_HEAVY_CLIP_FACTOR_3_MASK                                         0xff000000
-#define PHY_BB_HEAVY_CLIP_20_HEAVY_CLIP_FACTOR_3_GET(x)                       (((x) & 0xff000000) >> 24)
-#define PHY_BB_HEAVY_CLIP_20_HEAVY_CLIP_FACTOR_3_SET(x)                       (((x) << 24) & 0xff000000)
-
-/* macros for BB_heavy_clip_40 */
-#define PHY_BB_HEAVY_CLIP_40_ADDRESS                                                          0x000099e8
-#define PHY_BB_HEAVY_CLIP_40_OFFSET                                                           0x000099e8
-#define PHY_BB_HEAVY_CLIP_40_HEAVY_CLIP_FACTOR_4_MSB                                                   7
-#define PHY_BB_HEAVY_CLIP_40_HEAVY_CLIP_FACTOR_4_LSB                                                   0
-#define PHY_BB_HEAVY_CLIP_40_HEAVY_CLIP_FACTOR_4_MASK                                         0x000000ff
-#define PHY_BB_HEAVY_CLIP_40_HEAVY_CLIP_FACTOR_4_GET(x)                        (((x) & 0x000000ff) >> 0)
-#define PHY_BB_HEAVY_CLIP_40_HEAVY_CLIP_FACTOR_4_SET(x)                        (((x) << 0) & 0x000000ff)
-#define PHY_BB_HEAVY_CLIP_40_HEAVY_CLIP_FACTOR_5_MSB                                                  15
-#define PHY_BB_HEAVY_CLIP_40_HEAVY_CLIP_FACTOR_5_LSB                                                   8
-#define PHY_BB_HEAVY_CLIP_40_HEAVY_CLIP_FACTOR_5_MASK                                         0x0000ff00
-#define PHY_BB_HEAVY_CLIP_40_HEAVY_CLIP_FACTOR_5_GET(x)                        (((x) & 0x0000ff00) >> 8)
-#define PHY_BB_HEAVY_CLIP_40_HEAVY_CLIP_FACTOR_5_SET(x)                        (((x) << 8) & 0x0000ff00)
-#define PHY_BB_HEAVY_CLIP_40_HEAVY_CLIP_FACTOR_6_MSB                                                  23
-#define PHY_BB_HEAVY_CLIP_40_HEAVY_CLIP_FACTOR_6_LSB                                                  16
-#define PHY_BB_HEAVY_CLIP_40_HEAVY_CLIP_FACTOR_6_MASK                                         0x00ff0000
-#define PHY_BB_HEAVY_CLIP_40_HEAVY_CLIP_FACTOR_6_GET(x)                       (((x) & 0x00ff0000) >> 16)
-#define PHY_BB_HEAVY_CLIP_40_HEAVY_CLIP_FACTOR_6_SET(x)                       (((x) << 16) & 0x00ff0000)
-#define PHY_BB_HEAVY_CLIP_40_HEAVY_CLIP_FACTOR_7_MSB                                                  31
-#define PHY_BB_HEAVY_CLIP_40_HEAVY_CLIP_FACTOR_7_LSB                                                  24
-#define PHY_BB_HEAVY_CLIP_40_HEAVY_CLIP_FACTOR_7_MASK                                         0xff000000
-#define PHY_BB_HEAVY_CLIP_40_HEAVY_CLIP_FACTOR_7_GET(x)                       (((x) & 0xff000000) >> 24)
-#define PHY_BB_HEAVY_CLIP_40_HEAVY_CLIP_FACTOR_7_SET(x)                       (((x) << 24) & 0xff000000)
-
-/* macros for BB_rifs_srch */
-#define PHY_BB_RIFS_SRCH_ADDRESS                                                              0x000099ec
-#define PHY_BB_RIFS_SRCH_OFFSET                                                               0x000099ec
-#define PHY_BB_RIFS_SRCH_HEAVY_CLIP_FACTOR_XR_MSB                                                      7
-#define PHY_BB_RIFS_SRCH_HEAVY_CLIP_FACTOR_XR_LSB                                                      0
-#define PHY_BB_RIFS_SRCH_HEAVY_CLIP_FACTOR_XR_MASK                                            0x000000ff
-#define PHY_BB_RIFS_SRCH_HEAVY_CLIP_FACTOR_XR_GET(x)                           (((x) & 0x000000ff) >> 0)
-#define PHY_BB_RIFS_SRCH_HEAVY_CLIP_FACTOR_XR_SET(x)                           (((x) << 0) & 0x000000ff)
-#define PHY_BB_RIFS_SRCH_INIT_GAIN_DB_OFFSET_MSB                                                      15
-#define PHY_BB_RIFS_SRCH_INIT_GAIN_DB_OFFSET_LSB                                                       8
-#define PHY_BB_RIFS_SRCH_INIT_GAIN_DB_OFFSET_MASK                                             0x0000ff00
-#define PHY_BB_RIFS_SRCH_INIT_GAIN_DB_OFFSET_GET(x)                            (((x) & 0x0000ff00) >> 8)
-#define PHY_BB_RIFS_SRCH_INIT_GAIN_DB_OFFSET_SET(x)                            (((x) << 8) & 0x0000ff00)
-#define PHY_BB_RIFS_SRCH_RIFS_INIT_DELAY_MSB                                                          25
-#define PHY_BB_RIFS_SRCH_RIFS_INIT_DELAY_LSB                                                          16
-#define PHY_BB_RIFS_SRCH_RIFS_INIT_DELAY_MASK                                                 0x03ff0000
-#define PHY_BB_RIFS_SRCH_RIFS_INIT_DELAY_GET(x)                               (((x) & 0x03ff0000) >> 16)
-#define PHY_BB_RIFS_SRCH_RIFS_INIT_DELAY_SET(x)                               (((x) << 16) & 0x03ff0000)
-#define PHY_BB_RIFS_SRCH_RIFS_DISABLE_PWRLOW_GC_MSB                                                   26
-#define PHY_BB_RIFS_SRCH_RIFS_DISABLE_PWRLOW_GC_LSB                                                   26
-#define PHY_BB_RIFS_SRCH_RIFS_DISABLE_PWRLOW_GC_MASK                                          0x04000000
-#define PHY_BB_RIFS_SRCH_RIFS_DISABLE_PWRLOW_GC_GET(x)                        (((x) & 0x04000000) >> 26)
-#define PHY_BB_RIFS_SRCH_RIFS_DISABLE_PWRLOW_GC_SET(x)                        (((x) << 26) & 0x04000000)
-#define PHY_BB_RIFS_SRCH_RIFS_DISABLE_CCK_DET_MSB                                                     27
-#define PHY_BB_RIFS_SRCH_RIFS_DISABLE_CCK_DET_LSB                                                     27
-#define PHY_BB_RIFS_SRCH_RIFS_DISABLE_CCK_DET_MASK                                            0x08000000
-#define PHY_BB_RIFS_SRCH_RIFS_DISABLE_CCK_DET_GET(x)                          (((x) & 0x08000000) >> 27)
-#define PHY_BB_RIFS_SRCH_RIFS_DISABLE_CCK_DET_SET(x)                          (((x) << 27) & 0x08000000)
-
-/* macros for BB_iq_adc_cal_mode */
-#define PHY_BB_IQ_ADC_CAL_MODE_ADDRESS                                                        0x000099f0
-#define PHY_BB_IQ_ADC_CAL_MODE_OFFSET                                                         0x000099f0
-#define PHY_BB_IQ_ADC_CAL_MODE_GAIN_DC_IQ_CAL_MODE_MSB                                                 1
-#define PHY_BB_IQ_ADC_CAL_MODE_GAIN_DC_IQ_CAL_MODE_LSB                                                 0
-#define PHY_BB_IQ_ADC_CAL_MODE_GAIN_DC_IQ_CAL_MODE_MASK                                       0x00000003
-#define PHY_BB_IQ_ADC_CAL_MODE_GAIN_DC_IQ_CAL_MODE_GET(x)                      (((x) & 0x00000003) >> 0)
-#define PHY_BB_IQ_ADC_CAL_MODE_GAIN_DC_IQ_CAL_MODE_SET(x)                      (((x) << 0) & 0x00000003)
-#define PHY_BB_IQ_ADC_CAL_MODE_TEST_CALADCOFF_MSB                                                      2
-#define PHY_BB_IQ_ADC_CAL_MODE_TEST_CALADCOFF_LSB                                                      2
-#define PHY_BB_IQ_ADC_CAL_MODE_TEST_CALADCOFF_MASK                                            0x00000004
-#define PHY_BB_IQ_ADC_CAL_MODE_TEST_CALADCOFF_GET(x)                           (((x) & 0x00000004) >> 2)
-#define PHY_BB_IQ_ADC_CAL_MODE_TEST_CALADCOFF_SET(x)                           (((x) << 2) & 0x00000004)
-
-/* macros for BB_per_chain_csd */
-#define PHY_BB_PER_CHAIN_CSD_ADDRESS                                                          0x000099fc
-#define PHY_BB_PER_CHAIN_CSD_OFFSET                                                           0x000099fc
-#define PHY_BB_PER_CHAIN_CSD_CSD_CHN1_2CHAINS_MSB                                                      4
-#define PHY_BB_PER_CHAIN_CSD_CSD_CHN1_2CHAINS_LSB                                                      0
-#define PHY_BB_PER_CHAIN_CSD_CSD_CHN1_2CHAINS_MASK                                            0x0000001f
-#define PHY_BB_PER_CHAIN_CSD_CSD_CHN1_2CHAINS_GET(x)                           (((x) & 0x0000001f) >> 0)
-#define PHY_BB_PER_CHAIN_CSD_CSD_CHN1_2CHAINS_SET(x)                           (((x) << 0) & 0x0000001f)
-#define PHY_BB_PER_CHAIN_CSD_CSD_CHN1_3CHAINS_MSB                                                      9
-#define PHY_BB_PER_CHAIN_CSD_CSD_CHN1_3CHAINS_LSB                                                      5
-#define PHY_BB_PER_CHAIN_CSD_CSD_CHN1_3CHAINS_MASK                                            0x000003e0
-#define PHY_BB_PER_CHAIN_CSD_CSD_CHN1_3CHAINS_GET(x)                           (((x) & 0x000003e0) >> 5)
-#define PHY_BB_PER_CHAIN_CSD_CSD_CHN1_3CHAINS_SET(x)                           (((x) << 5) & 0x000003e0)
-#define PHY_BB_PER_CHAIN_CSD_CSD_CHN2_3CHAINS_MSB                                                     14
-#define PHY_BB_PER_CHAIN_CSD_CSD_CHN2_3CHAINS_LSB                                                     10
-#define PHY_BB_PER_CHAIN_CSD_CSD_CHN2_3CHAINS_MASK                                            0x00007c00
-#define PHY_BB_PER_CHAIN_CSD_CSD_CHN2_3CHAINS_GET(x)                          (((x) & 0x00007c00) >> 10)
-#define PHY_BB_PER_CHAIN_CSD_CSD_CHN2_3CHAINS_SET(x)                          (((x) << 10) & 0x00007c00)
-
-/* macros for BB_rx_ocgain */
-#define PHY_BB_RX_OCGAIN_ADDRESS                                                              0x00009a00
-#define PHY_BB_RX_OCGAIN_OFFSET                                                               0x00009a00
-#define PHY_BB_RX_OCGAIN_GAIN_ENTRY_MSB                                                               31
-#define PHY_BB_RX_OCGAIN_GAIN_ENTRY_LSB                                                                0
-#define PHY_BB_RX_OCGAIN_GAIN_ENTRY_MASK                                                      0xffffffff
-#define PHY_BB_RX_OCGAIN_GAIN_ENTRY_SET(x)                                     (((x) << 0) & 0xffffffff)
-
-/* macros for BB_tx_crc */
-#define PHY_BB_TX_CRC_ADDRESS                                                                 0x00009c00
-#define PHY_BB_TX_CRC_OFFSET                                                                  0x00009c00
-#define PHY_BB_TX_CRC_TX_CRC_MSB                                                                      15
-#define PHY_BB_TX_CRC_TX_CRC_LSB                                                                       0
-#define PHY_BB_TX_CRC_TX_CRC_MASK                                                             0x0000ffff
-#define PHY_BB_TX_CRC_TX_CRC_GET(x)                                            (((x) & 0x0000ffff) >> 0)
-
-/* macros for BB_iq_adc_meas_0_b0 */
-#define PHY_BB_IQ_ADC_MEAS_0_B0_ADDRESS                                                       0x00009c10
-#define PHY_BB_IQ_ADC_MEAS_0_B0_OFFSET                                                        0x00009c10
-#define PHY_BB_IQ_ADC_MEAS_0_B0_GAIN_DC_IQ_CAL_MEAS_0_0_MSB                                           31
-#define PHY_BB_IQ_ADC_MEAS_0_B0_GAIN_DC_IQ_CAL_MEAS_0_0_LSB                                            0
-#define PHY_BB_IQ_ADC_MEAS_0_B0_GAIN_DC_IQ_CAL_MEAS_0_0_MASK                                  0xffffffff
-#define PHY_BB_IQ_ADC_MEAS_0_B0_GAIN_DC_IQ_CAL_MEAS_0_0_GET(x)                 (((x) & 0xffffffff) >> 0)
-
-/* macros for BB_iq_adc_meas_1_b0 */
-#define PHY_BB_IQ_ADC_MEAS_1_B0_ADDRESS                                                       0x00009c14
-#define PHY_BB_IQ_ADC_MEAS_1_B0_OFFSET                                                        0x00009c14
-#define PHY_BB_IQ_ADC_MEAS_1_B0_GAIN_DC_IQ_CAL_MEAS_1_0_MSB                                           31
-#define PHY_BB_IQ_ADC_MEAS_1_B0_GAIN_DC_IQ_CAL_MEAS_1_0_LSB                                            0
-#define PHY_BB_IQ_ADC_MEAS_1_B0_GAIN_DC_IQ_CAL_MEAS_1_0_MASK                                  0xffffffff
-#define PHY_BB_IQ_ADC_MEAS_1_B0_GAIN_DC_IQ_CAL_MEAS_1_0_GET(x)                 (((x) & 0xffffffff) >> 0)
-
-/* macros for BB_iq_adc_meas_2_b0 */
-#define PHY_BB_IQ_ADC_MEAS_2_B0_ADDRESS                                                       0x00009c18
-#define PHY_BB_IQ_ADC_MEAS_2_B0_OFFSET                                                        0x00009c18
-#define PHY_BB_IQ_ADC_MEAS_2_B0_GAIN_DC_IQ_CAL_MEAS_2_0_MSB                                           31
-#define PHY_BB_IQ_ADC_MEAS_2_B0_GAIN_DC_IQ_CAL_MEAS_2_0_LSB                                            0
-#define PHY_BB_IQ_ADC_MEAS_2_B0_GAIN_DC_IQ_CAL_MEAS_2_0_MASK                                  0xffffffff
-#define PHY_BB_IQ_ADC_MEAS_2_B0_GAIN_DC_IQ_CAL_MEAS_2_0_GET(x)                 (((x) & 0xffffffff) >> 0)
-
-/* macros for BB_iq_adc_meas_3_b0 */
-#define PHY_BB_IQ_ADC_MEAS_3_B0_ADDRESS                                                       0x00009c1c
-#define PHY_BB_IQ_ADC_MEAS_3_B0_OFFSET                                                        0x00009c1c
-#define PHY_BB_IQ_ADC_MEAS_3_B0_GAIN_DC_IQ_CAL_MEAS_3_0_MSB                                           31
-#define PHY_BB_IQ_ADC_MEAS_3_B0_GAIN_DC_IQ_CAL_MEAS_3_0_LSB                                            0
-#define PHY_BB_IQ_ADC_MEAS_3_B0_GAIN_DC_IQ_CAL_MEAS_3_0_MASK                                  0xffffffff
-#define PHY_BB_IQ_ADC_MEAS_3_B0_GAIN_DC_IQ_CAL_MEAS_3_0_GET(x)                 (((x) & 0xffffffff) >> 0)
-
-/* macros for BB_rfbus_grant */
-#define PHY_BB_RFBUS_GRANT_ADDRESS                                                            0x00009c20
-#define PHY_BB_RFBUS_GRANT_OFFSET                                                             0x00009c20
-#define PHY_BB_RFBUS_GRANT_RFBUS_GRANT_MSB                                                             0
-#define PHY_BB_RFBUS_GRANT_RFBUS_GRANT_LSB                                                             0
-#define PHY_BB_RFBUS_GRANT_RFBUS_GRANT_MASK                                                   0x00000001
-#define PHY_BB_RFBUS_GRANT_RFBUS_GRANT_GET(x)                                  (((x) & 0x00000001) >> 0)
-#define PHY_BB_RFBUS_GRANT_BT_ANT_MSB                                                                  1
-#define PHY_BB_RFBUS_GRANT_BT_ANT_LSB                                                                  1
-#define PHY_BB_RFBUS_GRANT_BT_ANT_MASK                                                        0x00000002
-#define PHY_BB_RFBUS_GRANT_BT_ANT_GET(x)                                       (((x) & 0x00000002) >> 1)
-
-/* macros for BB_tstadc */
-#define PHY_BB_TSTADC_ADDRESS                                                                 0x00009c24
-#define PHY_BB_TSTADC_OFFSET                                                                  0x00009c24
-#define PHY_BB_TSTADC_TSTADC_OUT_Q_MSB                                                                 9
-#define PHY_BB_TSTADC_TSTADC_OUT_Q_LSB                                                                 0
-#define PHY_BB_TSTADC_TSTADC_OUT_Q_MASK                                                       0x000003ff
-#define PHY_BB_TSTADC_TSTADC_OUT_Q_GET(x)                                      (((x) & 0x000003ff) >> 0)
-#define PHY_BB_TSTADC_TSTADC_OUT_I_MSB                                                                19
-#define PHY_BB_TSTADC_TSTADC_OUT_I_LSB                                                                10
-#define PHY_BB_TSTADC_TSTADC_OUT_I_MASK                                                       0x000ffc00
-#define PHY_BB_TSTADC_TSTADC_OUT_I_GET(x)                                     (((x) & 0x000ffc00) >> 10)
-
-/* macros for BB_tstdac */
-#define PHY_BB_TSTDAC_ADDRESS                                                                 0x00009c28
-#define PHY_BB_TSTDAC_OFFSET                                                                  0x00009c28
-#define PHY_BB_TSTDAC_TSTDAC_OUT_Q_MSB                                                                 9
-#define PHY_BB_TSTDAC_TSTDAC_OUT_Q_LSB                                                                 0
-#define PHY_BB_TSTDAC_TSTDAC_OUT_Q_MASK                                                       0x000003ff
-#define PHY_BB_TSTDAC_TSTDAC_OUT_Q_GET(x)                                      (((x) & 0x000003ff) >> 0)
-#define PHY_BB_TSTDAC_TSTDAC_OUT_I_MSB                                                                19
-#define PHY_BB_TSTDAC_TSTDAC_OUT_I_LSB                                                                10
-#define PHY_BB_TSTDAC_TSTDAC_OUT_I_MASK                                                       0x000ffc00
-#define PHY_BB_TSTDAC_TSTDAC_OUT_I_GET(x)                                     (((x) & 0x000ffc00) >> 10)
-
-/* macros for BB_illegal_tx_rate */
-#define PHY_BB_ILLEGAL_TX_RATE_ADDRESS                                                        0x00009c30
-#define PHY_BB_ILLEGAL_TX_RATE_OFFSET                                                         0x00009c30
-#define PHY_BB_ILLEGAL_TX_RATE_ILLEGAL_TX_RATE_MSB                                                     0
-#define PHY_BB_ILLEGAL_TX_RATE_ILLEGAL_TX_RATE_LSB                                                     0
-#define PHY_BB_ILLEGAL_TX_RATE_ILLEGAL_TX_RATE_MASK                                           0x00000001
-#define PHY_BB_ILLEGAL_TX_RATE_ILLEGAL_TX_RATE_GET(x)                          (((x) & 0x00000001) >> 0)
-
-/* macros for BB_spur_report_b0 */
-#define PHY_BB_SPUR_REPORT_B0_ADDRESS                                                         0x00009c34
-#define PHY_BB_SPUR_REPORT_B0_OFFSET                                                          0x00009c34
-#define PHY_BB_SPUR_REPORT_B0_SPUR_EST_I_0_MSB                                                         7
-#define PHY_BB_SPUR_REPORT_B0_SPUR_EST_I_0_LSB                                                         0
-#define PHY_BB_SPUR_REPORT_B0_SPUR_EST_I_0_MASK                                               0x000000ff
-#define PHY_BB_SPUR_REPORT_B0_SPUR_EST_I_0_GET(x)                              (((x) & 0x000000ff) >> 0)
-#define PHY_BB_SPUR_REPORT_B0_SPUR_EST_Q_0_MSB                                                        15
-#define PHY_BB_SPUR_REPORT_B0_SPUR_EST_Q_0_LSB                                                         8
-#define PHY_BB_SPUR_REPORT_B0_SPUR_EST_Q_0_MASK                                               0x0000ff00
-#define PHY_BB_SPUR_REPORT_B0_SPUR_EST_Q_0_GET(x)                              (((x) & 0x0000ff00) >> 8)
-#define PHY_BB_SPUR_REPORT_B0_POWER_WITH_SPUR_REMOVED_0_MSB                                           31
-#define PHY_BB_SPUR_REPORT_B0_POWER_WITH_SPUR_REMOVED_0_LSB                                           16
-#define PHY_BB_SPUR_REPORT_B0_POWER_WITH_SPUR_REMOVED_0_MASK                                  0xffff0000
-#define PHY_BB_SPUR_REPORT_B0_POWER_WITH_SPUR_REMOVED_0_GET(x)                (((x) & 0xffff0000) >> 16)
-
-/* macros for BB_channel_status */
-#define PHY_BB_CHANNEL_STATUS_ADDRESS                                                         0x00009c38
-#define PHY_BB_CHANNEL_STATUS_OFFSET                                                          0x00009c38
-#define PHY_BB_CHANNEL_STATUS_BT_ACTIVE_MSB                                                            0
-#define PHY_BB_CHANNEL_STATUS_BT_ACTIVE_LSB                                                            0
-#define PHY_BB_CHANNEL_STATUS_BT_ACTIVE_MASK                                                  0x00000001
-#define PHY_BB_CHANNEL_STATUS_BT_ACTIVE_GET(x)                                 (((x) & 0x00000001) >> 0)
-#define PHY_BB_CHANNEL_STATUS_RX_CLEAR_RAW_MSB                                                         1
-#define PHY_BB_CHANNEL_STATUS_RX_CLEAR_RAW_LSB                                                         1
-#define PHY_BB_CHANNEL_STATUS_RX_CLEAR_RAW_MASK                                               0x00000002
-#define PHY_BB_CHANNEL_STATUS_RX_CLEAR_RAW_GET(x)                              (((x) & 0x00000002) >> 1)
-#define PHY_BB_CHANNEL_STATUS_RX_CLEAR_MAC_MSB                                                         2
-#define PHY_BB_CHANNEL_STATUS_RX_CLEAR_MAC_LSB                                                         2
-#define PHY_BB_CHANNEL_STATUS_RX_CLEAR_MAC_MASK                                               0x00000004
-#define PHY_BB_CHANNEL_STATUS_RX_CLEAR_MAC_GET(x)                              (((x) & 0x00000004) >> 2)
-#define PHY_BB_CHANNEL_STATUS_RX_CLEAR_PAD_MSB                                                         3
-#define PHY_BB_CHANNEL_STATUS_RX_CLEAR_PAD_LSB                                                         3
-#define PHY_BB_CHANNEL_STATUS_RX_CLEAR_PAD_MASK                                               0x00000008
-#define PHY_BB_CHANNEL_STATUS_RX_CLEAR_PAD_GET(x)                              (((x) & 0x00000008) >> 3)
-#define PHY_BB_CHANNEL_STATUS_BB_SW_OUT_0_MSB                                                          5
-#define PHY_BB_CHANNEL_STATUS_BB_SW_OUT_0_LSB                                                          4
-#define PHY_BB_CHANNEL_STATUS_BB_SW_OUT_0_MASK                                                0x00000030
-#define PHY_BB_CHANNEL_STATUS_BB_SW_OUT_0_GET(x)                               (((x) & 0x00000030) >> 4)
-#define PHY_BB_CHANNEL_STATUS_BB_SW_OUT_1_MSB                                                          7
-#define PHY_BB_CHANNEL_STATUS_BB_SW_OUT_1_LSB                                                          6
-#define PHY_BB_CHANNEL_STATUS_BB_SW_OUT_1_MASK                                                0x000000c0
-#define PHY_BB_CHANNEL_STATUS_BB_SW_OUT_1_GET(x)                               (((x) & 0x000000c0) >> 6)
-#define PHY_BB_CHANNEL_STATUS_BB_SW_OUT_2_MSB                                                          9
-#define PHY_BB_CHANNEL_STATUS_BB_SW_OUT_2_LSB                                                          8
-#define PHY_BB_CHANNEL_STATUS_BB_SW_OUT_2_MASK                                                0x00000300
-#define PHY_BB_CHANNEL_STATUS_BB_SW_OUT_2_GET(x)                               (((x) & 0x00000300) >> 8)
-#define PHY_BB_CHANNEL_STATUS_BB_SW_COM_OUT_MSB                                                       13
-#define PHY_BB_CHANNEL_STATUS_BB_SW_COM_OUT_LSB                                                       10
-#define PHY_BB_CHANNEL_STATUS_BB_SW_COM_OUT_MASK                                              0x00003c00
-#define PHY_BB_CHANNEL_STATUS_BB_SW_COM_OUT_GET(x)                            (((x) & 0x00003c00) >> 10)
-#define PHY_BB_CHANNEL_STATUS_ANT_DIV_CFG_USED_MSB                                                    16
-#define PHY_BB_CHANNEL_STATUS_ANT_DIV_CFG_USED_LSB                                                    14
-#define PHY_BB_CHANNEL_STATUS_ANT_DIV_CFG_USED_MASK                                           0x0001c000
-#define PHY_BB_CHANNEL_STATUS_ANT_DIV_CFG_USED_GET(x)                         (((x) & 0x0001c000) >> 14)
-
-/* macros for BB_rssi_b0 */
-#define PHY_BB_RSSI_B0_ADDRESS                                                                0x00009c3c
-#define PHY_BB_RSSI_B0_OFFSET                                                                 0x00009c3c
-#define PHY_BB_RSSI_B0_RSSI_0_MSB                                                                      7
-#define PHY_BB_RSSI_B0_RSSI_0_LSB                                                                      0
-#define PHY_BB_RSSI_B0_RSSI_0_MASK                                                            0x000000ff
-#define PHY_BB_RSSI_B0_RSSI_0_GET(x)                                           (((x) & 0x000000ff) >> 0)
-#define PHY_BB_RSSI_B0_RSSI_EXT_0_MSB                                                                 15
-#define PHY_BB_RSSI_B0_RSSI_EXT_0_LSB                                                                  8
-#define PHY_BB_RSSI_B0_RSSI_EXT_0_MASK                                                        0x0000ff00
-#define PHY_BB_RSSI_B0_RSSI_EXT_0_GET(x)                                       (((x) & 0x0000ff00) >> 8)
-
-/* macros for BB_spur_est_cck_report_b0 */
-#define PHY_BB_SPUR_EST_CCK_REPORT_B0_ADDRESS                                                 0x00009c40
-#define PHY_BB_SPUR_EST_CCK_REPORT_B0_OFFSET                                                  0x00009c40
-#define PHY_BB_SPUR_EST_CCK_REPORT_B0_SPUR_EST_SD_I_0_CCK_MSB                                          7
-#define PHY_BB_SPUR_EST_CCK_REPORT_B0_SPUR_EST_SD_I_0_CCK_LSB                                          0
-#define PHY_BB_SPUR_EST_CCK_REPORT_B0_SPUR_EST_SD_I_0_CCK_MASK                                0x000000ff
-#define PHY_BB_SPUR_EST_CCK_REPORT_B0_SPUR_EST_SD_I_0_CCK_GET(x)               (((x) & 0x000000ff) >> 0)
-#define PHY_BB_SPUR_EST_CCK_REPORT_B0_SPUR_EST_SD_Q_0_CCK_MSB                                         15
-#define PHY_BB_SPUR_EST_CCK_REPORT_B0_SPUR_EST_SD_Q_0_CCK_LSB                                          8
-#define PHY_BB_SPUR_EST_CCK_REPORT_B0_SPUR_EST_SD_Q_0_CCK_MASK                                0x0000ff00
-#define PHY_BB_SPUR_EST_CCK_REPORT_B0_SPUR_EST_SD_Q_0_CCK_GET(x)               (((x) & 0x0000ff00) >> 8)
-#define PHY_BB_SPUR_EST_CCK_REPORT_B0_SPUR_EST_I_0_CCK_MSB                                            23
-#define PHY_BB_SPUR_EST_CCK_REPORT_B0_SPUR_EST_I_0_CCK_LSB                                            16
-#define PHY_BB_SPUR_EST_CCK_REPORT_B0_SPUR_EST_I_0_CCK_MASK                                   0x00ff0000
-#define PHY_BB_SPUR_EST_CCK_REPORT_B0_SPUR_EST_I_0_CCK_GET(x)                 (((x) & 0x00ff0000) >> 16)
-#define PHY_BB_SPUR_EST_CCK_REPORT_B0_SPUR_EST_Q_0_CCK_MSB                                            31
-#define PHY_BB_SPUR_EST_CCK_REPORT_B0_SPUR_EST_Q_0_CCK_LSB                                            24
-#define PHY_BB_SPUR_EST_CCK_REPORT_B0_SPUR_EST_Q_0_CCK_MASK                                   0xff000000
-#define PHY_BB_SPUR_EST_CCK_REPORT_B0_SPUR_EST_Q_0_CCK_GET(x)                 (((x) & 0xff000000) >> 24)
-
-/* macros for BB_chan_info_noise_pwr */
-#define PHY_BB_CHAN_INFO_NOISE_PWR_ADDRESS                                                    0x00009cac
-#define PHY_BB_CHAN_INFO_NOISE_PWR_OFFSET                                                     0x00009cac
-#define PHY_BB_CHAN_INFO_NOISE_PWR_NOISE_POWER_MSB                                                    11
-#define PHY_BB_CHAN_INFO_NOISE_PWR_NOISE_POWER_LSB                                                     0
-#define PHY_BB_CHAN_INFO_NOISE_PWR_NOISE_POWER_MASK                                           0x00000fff
-#define PHY_BB_CHAN_INFO_NOISE_PWR_NOISE_POWER_GET(x)                          (((x) & 0x00000fff) >> 0)
-
-/* macros for BB_chan_info_gain_diff */
-#define PHY_BB_CHAN_INFO_GAIN_DIFF_ADDRESS                                                    0x00009cb0
-#define PHY_BB_CHAN_INFO_GAIN_DIFF_OFFSET                                                     0x00009cb0
-#define PHY_BB_CHAN_INFO_GAIN_DIFF_FINE_PPM_MSB                                                       11
-#define PHY_BB_CHAN_INFO_GAIN_DIFF_FINE_PPM_LSB                                                        0
-#define PHY_BB_CHAN_INFO_GAIN_DIFF_FINE_PPM_MASK                                              0x00000fff
-#define PHY_BB_CHAN_INFO_GAIN_DIFF_FINE_PPM_GET(x)                             (((x) & 0x00000fff) >> 0)
-
-/* macros for BB_chan_info_fine_timing */
-#define PHY_BB_CHAN_INFO_FINE_TIMING_ADDRESS                                                  0x00009cb4
-#define PHY_BB_CHAN_INFO_FINE_TIMING_OFFSET                                                   0x00009cb4
-#define PHY_BB_CHAN_INFO_FINE_TIMING_COARSE_PPM_MSB                                                   11
-#define PHY_BB_CHAN_INFO_FINE_TIMING_COARSE_PPM_LSB                                                    0
-#define PHY_BB_CHAN_INFO_FINE_TIMING_COARSE_PPM_MASK                                          0x00000fff
-#define PHY_BB_CHAN_INFO_FINE_TIMING_COARSE_PPM_GET(x)                         (((x) & 0x00000fff) >> 0)
-#define PHY_BB_CHAN_INFO_FINE_TIMING_FINE_TIMING_MSB                                                  21
-#define PHY_BB_CHAN_INFO_FINE_TIMING_FINE_TIMING_LSB                                                  12
-#define PHY_BB_CHAN_INFO_FINE_TIMING_FINE_TIMING_MASK                                         0x003ff000
-#define PHY_BB_CHAN_INFO_FINE_TIMING_FINE_TIMING_GET(x)                       (((x) & 0x003ff000) >> 12)
-
-/* macros for BB_chan_info_gain_b0 */
-#define PHY_BB_CHAN_INFO_GAIN_B0_ADDRESS                                                      0x00009cb8
-#define PHY_BB_CHAN_INFO_GAIN_B0_OFFSET                                                       0x00009cb8
-#define PHY_BB_CHAN_INFO_GAIN_B0_CHAN_INFO_RSSI_0_MSB                                                  7
-#define PHY_BB_CHAN_INFO_GAIN_B0_CHAN_INFO_RSSI_0_LSB                                                  0
-#define PHY_BB_CHAN_INFO_GAIN_B0_CHAN_INFO_RSSI_0_MASK                                        0x000000ff
-#define PHY_BB_CHAN_INFO_GAIN_B0_CHAN_INFO_RSSI_0_GET(x)                       (((x) & 0x000000ff) >> 0)
-#define PHY_BB_CHAN_INFO_GAIN_B0_CHAN_INFO_RF_GAIN_0_MSB                                              15
-#define PHY_BB_CHAN_INFO_GAIN_B0_CHAN_INFO_RF_GAIN_0_LSB                                               8
-#define PHY_BB_CHAN_INFO_GAIN_B0_CHAN_INFO_RF_GAIN_0_MASK                                     0x0000ff00
-#define PHY_BB_CHAN_INFO_GAIN_B0_CHAN_INFO_RF_GAIN_0_GET(x)                    (((x) & 0x0000ff00) >> 8)
-#define PHY_BB_CHAN_INFO_GAIN_B0_CHAN_INFO_XATTEN1_SW_0_MSB                                           16
-#define PHY_BB_CHAN_INFO_GAIN_B0_CHAN_INFO_XATTEN1_SW_0_LSB                                           16
-#define PHY_BB_CHAN_INFO_GAIN_B0_CHAN_INFO_XATTEN1_SW_0_MASK                                  0x00010000
-#define PHY_BB_CHAN_INFO_GAIN_B0_CHAN_INFO_XATTEN1_SW_0_GET(x)                (((x) & 0x00010000) >> 16)
-#define PHY_BB_CHAN_INFO_GAIN_B0_CHAN_INFO_XATTEN2_SW_0_MSB                                           17
-#define PHY_BB_CHAN_INFO_GAIN_B0_CHAN_INFO_XATTEN2_SW_0_LSB                                           17
-#define PHY_BB_CHAN_INFO_GAIN_B0_CHAN_INFO_XATTEN2_SW_0_MASK                                  0x00020000
-#define PHY_BB_CHAN_INFO_GAIN_B0_CHAN_INFO_XATTEN2_SW_0_GET(x)                (((x) & 0x00020000) >> 17)
-
-/* macros for BB_chan_info_chan_tab_b0 */
-#define PHY_BB_CHAN_INFO_CHAN_TAB_B0_ADDRESS                                                  0x00009cbc
-#define PHY_BB_CHAN_INFO_CHAN_TAB_B0_OFFSET                                                   0x00009cbc
-#define PHY_BB_CHAN_INFO_CHAN_TAB_B0_MAN_Q_0_MSB                                                       5
-#define PHY_BB_CHAN_INFO_CHAN_TAB_B0_MAN_Q_0_LSB                                                       0
-#define PHY_BB_CHAN_INFO_CHAN_TAB_B0_MAN_Q_0_MASK                                             0x0000003f
-#define PHY_BB_CHAN_INFO_CHAN_TAB_B0_MAN_Q_0_GET(x)                            (((x) & 0x0000003f) >> 0)
-#define PHY_BB_CHAN_INFO_CHAN_TAB_B0_MAN_I_0_MSB                                                      11
-#define PHY_BB_CHAN_INFO_CHAN_TAB_B0_MAN_I_0_LSB                                                       6
-#define PHY_BB_CHAN_INFO_CHAN_TAB_B0_MAN_I_0_MASK                                             0x00000fc0
-#define PHY_BB_CHAN_INFO_CHAN_TAB_B0_MAN_I_0_GET(x)                            (((x) & 0x00000fc0) >> 6)
-#define PHY_BB_CHAN_INFO_CHAN_TAB_B0_EXP_0_MSB                                                        15
-#define PHY_BB_CHAN_INFO_CHAN_TAB_B0_EXP_0_LSB                                                        12
-#define PHY_BB_CHAN_INFO_CHAN_TAB_B0_EXP_0_MASK                                               0x0000f000
-#define PHY_BB_CHAN_INFO_CHAN_TAB_B0_EXP_0_GET(x)                             (((x) & 0x0000f000) >> 12)
-#define PHY_BB_CHAN_INFO_CHAN_TAB_B0_MAN_Q_1_MSB                                                      21
-#define PHY_BB_CHAN_INFO_CHAN_TAB_B0_MAN_Q_1_LSB                                                      16
-#define PHY_BB_CHAN_INFO_CHAN_TAB_B0_MAN_Q_1_MASK                                             0x003f0000
-#define PHY_BB_CHAN_INFO_CHAN_TAB_B0_MAN_Q_1_GET(x)                           (((x) & 0x003f0000) >> 16)
-#define PHY_BB_CHAN_INFO_CHAN_TAB_B0_MAN_I_1_MSB                                                      27
-#define PHY_BB_CHAN_INFO_CHAN_TAB_B0_MAN_I_1_LSB                                                      22
-#define PHY_BB_CHAN_INFO_CHAN_TAB_B0_MAN_I_1_MASK                                             0x0fc00000
-#define PHY_BB_CHAN_INFO_CHAN_TAB_B0_MAN_I_1_GET(x)                           (((x) & 0x0fc00000) >> 22)
-#define PHY_BB_CHAN_INFO_CHAN_TAB_B0_EXP_1_MSB                                                        31
-#define PHY_BB_CHAN_INFO_CHAN_TAB_B0_EXP_1_LSB                                                        28
-#define PHY_BB_CHAN_INFO_CHAN_TAB_B0_EXP_1_MASK                                               0xf0000000
-#define PHY_BB_CHAN_INFO_CHAN_TAB_B0_EXP_1_GET(x)                             (((x) & 0xf0000000) >> 28)
-
-/* macros for BB_paprd_am2am_mask */
-#define PHY_BB_PAPRD_AM2AM_MASK_ADDRESS                                                       0x00009de4
-#define PHY_BB_PAPRD_AM2AM_MASK_OFFSET                                                        0x00009de4
-#define PHY_BB_PAPRD_AM2AM_MASK_PAPRD_AM2AM_MASK_MSB                                                  24
-#define PHY_BB_PAPRD_AM2AM_MASK_PAPRD_AM2AM_MASK_LSB                                                   0
-#define PHY_BB_PAPRD_AM2AM_MASK_PAPRD_AM2AM_MASK_MASK                                         0x01ffffff
-#define PHY_BB_PAPRD_AM2AM_MASK_PAPRD_AM2AM_MASK_GET(x)                        (((x) & 0x01ffffff) >> 0)
-#define PHY_BB_PAPRD_AM2AM_MASK_PAPRD_AM2AM_MASK_SET(x)                        (((x) << 0) & 0x01ffffff)
-
-/* macros for BB_paprd_am2pm_mask */
-#define PHY_BB_PAPRD_AM2PM_MASK_ADDRESS                                                       0x00009de8
-#define PHY_BB_PAPRD_AM2PM_MASK_OFFSET                                                        0x00009de8
-#define PHY_BB_PAPRD_AM2PM_MASK_PAPRD_AM2PM_MASK_MSB                                                  24
-#define PHY_BB_PAPRD_AM2PM_MASK_PAPRD_AM2PM_MASK_LSB                                                   0
-#define PHY_BB_PAPRD_AM2PM_MASK_PAPRD_AM2PM_MASK_MASK                                         0x01ffffff
-#define PHY_BB_PAPRD_AM2PM_MASK_PAPRD_AM2PM_MASK_GET(x)                        (((x) & 0x01ffffff) >> 0)
-#define PHY_BB_PAPRD_AM2PM_MASK_PAPRD_AM2PM_MASK_SET(x)                        (((x) << 0) & 0x01ffffff)
-
-/* macros for BB_paprd_ht40_mask */
-#define PHY_BB_PAPRD_HT40_MASK_ADDRESS                                                        0x00009dec
-#define PHY_BB_PAPRD_HT40_MASK_OFFSET                                                         0x00009dec
-#define PHY_BB_PAPRD_HT40_MASK_PAPRD_HT40_MASK_MSB                                                    24
-#define PHY_BB_PAPRD_HT40_MASK_PAPRD_HT40_MASK_LSB                                                     0
-#define PHY_BB_PAPRD_HT40_MASK_PAPRD_HT40_MASK_MASK                                           0x01ffffff
-#define PHY_BB_PAPRD_HT40_MASK_PAPRD_HT40_MASK_GET(x)                          (((x) & 0x01ffffff) >> 0)
-#define PHY_BB_PAPRD_HT40_MASK_PAPRD_HT40_MASK_SET(x)                          (((x) << 0) & 0x01ffffff)
-
-/* macros for BB_paprd_ctrl0 */
-#define PHY_BB_PAPRD_CTRL0_ADDRESS                                                            0x00009df0
-#define PHY_BB_PAPRD_CTRL0_OFFSET                                                             0x00009df0
-#define PHY_BB_PAPRD_CTRL0_PAPRD_ENABLE_MSB                                                            0
-#define PHY_BB_PAPRD_CTRL0_PAPRD_ENABLE_LSB                                                            0
-#define PHY_BB_PAPRD_CTRL0_PAPRD_ENABLE_MASK                                                  0x00000001
-#define PHY_BB_PAPRD_CTRL0_PAPRD_ENABLE_GET(x)                                 (((x) & 0x00000001) >> 0)
-#define PHY_BB_PAPRD_CTRL0_PAPRD_ENABLE_SET(x)                                 (((x) << 0) & 0x00000001)
-#define PHY_BB_PAPRD_CTRL0_PAPRD_ADAPTIVE_USE_SINGLE_TABLE_MSB                                         1
-#define PHY_BB_PAPRD_CTRL0_PAPRD_ADAPTIVE_USE_SINGLE_TABLE_LSB                                         1
-#define PHY_BB_PAPRD_CTRL0_PAPRD_ADAPTIVE_USE_SINGLE_TABLE_MASK                               0x00000002
-#define PHY_BB_PAPRD_CTRL0_PAPRD_ADAPTIVE_USE_SINGLE_TABLE_GET(x)              (((x) & 0x00000002) >> 1)
-#define PHY_BB_PAPRD_CTRL0_PAPRD_ADAPTIVE_USE_SINGLE_TABLE_SET(x)              (((x) << 1) & 0x00000002)
-#define PHY_BB_PAPRD_CTRL0_PAPRD_VALID_GAIN_MSB                                                       26
-#define PHY_BB_PAPRD_CTRL0_PAPRD_VALID_GAIN_LSB                                                        2
-#define PHY_BB_PAPRD_CTRL0_PAPRD_VALID_GAIN_MASK                                              0x07fffffc
-#define PHY_BB_PAPRD_CTRL0_PAPRD_VALID_GAIN_GET(x)                             (((x) & 0x07fffffc) >> 2)
-#define PHY_BB_PAPRD_CTRL0_PAPRD_VALID_GAIN_SET(x)                             (((x) << 2) & 0x07fffffc)
-#define PHY_BB_PAPRD_CTRL0_PAPRD_MAG_THRSH_MSB                                                        31
-#define PHY_BB_PAPRD_CTRL0_PAPRD_MAG_THRSH_LSB                                                        27
-#define PHY_BB_PAPRD_CTRL0_PAPRD_MAG_THRSH_MASK                                               0xf8000000
-#define PHY_BB_PAPRD_CTRL0_PAPRD_MAG_THRSH_GET(x)                             (((x) & 0xf8000000) >> 27)
-#define PHY_BB_PAPRD_CTRL0_PAPRD_MAG_THRSH_SET(x)                             (((x) << 27) & 0xf8000000)
-
-/* macros for BB_paprd_ctrl1 */
-#define PHY_BB_PAPRD_CTRL1_ADDRESS                                                            0x00009df4
-#define PHY_BB_PAPRD_CTRL1_OFFSET                                                             0x00009df4
-#define PHY_BB_PAPRD_CTRL1_PAPRD_ADAPTIVE_SCALING_ENABLE_MSB                                           0
-#define PHY_BB_PAPRD_CTRL1_PAPRD_ADAPTIVE_SCALING_ENABLE_LSB                                           0
-#define PHY_BB_PAPRD_CTRL1_PAPRD_ADAPTIVE_SCALING_ENABLE_MASK                                 0x00000001
-#define PHY_BB_PAPRD_CTRL1_PAPRD_ADAPTIVE_SCALING_ENABLE_GET(x)                (((x) & 0x00000001) >> 0)
-#define PHY_BB_PAPRD_CTRL1_PAPRD_ADAPTIVE_SCALING_ENABLE_SET(x)                (((x) << 0) & 0x00000001)
-#define PHY_BB_PAPRD_CTRL1_PAPRD_ADAPTIVE_AM2AM_ENABLE_MSB                                             1
-#define PHY_BB_PAPRD_CTRL1_PAPRD_ADAPTIVE_AM2AM_ENABLE_LSB                                             1
-#define PHY_BB_PAPRD_CTRL1_PAPRD_ADAPTIVE_AM2AM_ENABLE_MASK                                   0x00000002
-#define PHY_BB_PAPRD_CTRL1_PAPRD_ADAPTIVE_AM2AM_ENABLE_GET(x)                  (((x) & 0x00000002) >> 1)
-#define PHY_BB_PAPRD_CTRL1_PAPRD_ADAPTIVE_AM2AM_ENABLE_SET(x)                  (((x) << 1) & 0x00000002)
-#define PHY_BB_PAPRD_CTRL1_PAPRD_ADAPTIVE_AM2PM_ENABLE_MSB                                             2
-#define PHY_BB_PAPRD_CTRL1_PAPRD_ADAPTIVE_AM2PM_ENABLE_LSB                                             2
-#define PHY_BB_PAPRD_CTRL1_PAPRD_ADAPTIVE_AM2PM_ENABLE_MASK                                   0x00000004
-#define PHY_BB_PAPRD_CTRL1_PAPRD_ADAPTIVE_AM2PM_ENABLE_GET(x)                  (((x) & 0x00000004) >> 2)
-#define PHY_BB_PAPRD_CTRL1_PAPRD_ADAPTIVE_AM2PM_ENABLE_SET(x)                  (((x) << 2) & 0x00000004)
-#define PHY_BB_PAPRD_CTRL1_PAPRD_POWER_AT_AM2AM_CAL_MSB                                                8
-#define PHY_BB_PAPRD_CTRL1_PAPRD_POWER_AT_AM2AM_CAL_LSB                                                3
-#define PHY_BB_PAPRD_CTRL1_PAPRD_POWER_AT_AM2AM_CAL_MASK                                      0x000001f8
-#define PHY_BB_PAPRD_CTRL1_PAPRD_POWER_AT_AM2AM_CAL_GET(x)                     (((x) & 0x000001f8) >> 3)
-#define PHY_BB_PAPRD_CTRL1_PAPRD_POWER_AT_AM2AM_CAL_SET(x)                     (((x) << 3) & 0x000001f8)
-#define PHY_BB_PAPRD_CTRL1_PA_GAIN_SCALE_FACTOR_MSB                                                   16
-#define PHY_BB_PAPRD_CTRL1_PA_GAIN_SCALE_FACTOR_LSB                                                    9
-#define PHY_BB_PAPRD_CTRL1_PA_GAIN_SCALE_FACTOR_MASK                                          0x0001fe00
-#define PHY_BB_PAPRD_CTRL1_PA_GAIN_SCALE_FACTOR_GET(x)                         (((x) & 0x0001fe00) >> 9)
-#define PHY_BB_PAPRD_CTRL1_PA_GAIN_SCALE_FACTOR_SET(x)                         (((x) << 9) & 0x0001fe00)
-#define PHY_BB_PAPRD_CTRL1_PAPRD_MAG_SCALE_FACTOR_MSB                                                 26
-#define PHY_BB_PAPRD_CTRL1_PAPRD_MAG_SCALE_FACTOR_LSB                                                 17
-#define PHY_BB_PAPRD_CTRL1_PAPRD_MAG_SCALE_FACTOR_MASK                                        0x07fe0000
-#define PHY_BB_PAPRD_CTRL1_PAPRD_MAG_SCALE_FACTOR_GET(x)                      (((x) & 0x07fe0000) >> 17)
-#define PHY_BB_PAPRD_CTRL1_PAPRD_MAG_SCALE_FACTOR_SET(x)                      (((x) << 17) & 0x07fe0000)
-#define PHY_BB_PAPRD_CTRL1_PAPRD_TRAINER_IANDQ_SEL_MSB                                                27
-#define PHY_BB_PAPRD_CTRL1_PAPRD_TRAINER_IANDQ_SEL_LSB                                                27
-#define PHY_BB_PAPRD_CTRL1_PAPRD_TRAINER_IANDQ_SEL_MASK                                       0x08000000
-#define PHY_BB_PAPRD_CTRL1_PAPRD_TRAINER_IANDQ_SEL_GET(x)                     (((x) & 0x08000000) >> 27)
-#define PHY_BB_PAPRD_CTRL1_PAPRD_TRAINER_IANDQ_SEL_SET(x)                     (((x) << 27) & 0x08000000)
-
-/* macros for BB_pa_gain123 */
-#define PHY_BB_PA_GAIN123_ADDRESS                                                             0x00009df8
-#define PHY_BB_PA_GAIN123_OFFSET                                                              0x00009df8
-#define PHY_BB_PA_GAIN123_PA_GAIN1_MSB                                                                 9
-#define PHY_BB_PA_GAIN123_PA_GAIN1_LSB                                                                 0
-#define PHY_BB_PA_GAIN123_PA_GAIN1_MASK                                                       0x000003ff
-#define PHY_BB_PA_GAIN123_PA_GAIN1_GET(x)                                      (((x) & 0x000003ff) >> 0)
-#define PHY_BB_PA_GAIN123_PA_GAIN1_SET(x)                                      (((x) << 0) & 0x000003ff)
-#define PHY_BB_PA_GAIN123_PA_GAIN2_MSB                                                                19
-#define PHY_BB_PA_GAIN123_PA_GAIN2_LSB                                                                10
-#define PHY_BB_PA_GAIN123_PA_GAIN2_MASK                                                       0x000ffc00
-#define PHY_BB_PA_GAIN123_PA_GAIN2_GET(x)                                     (((x) & 0x000ffc00) >> 10)
-#define PHY_BB_PA_GAIN123_PA_GAIN2_SET(x)                                     (((x) << 10) & 0x000ffc00)
-#define PHY_BB_PA_GAIN123_PA_GAIN3_MSB                                                                29
-#define PHY_BB_PA_GAIN123_PA_GAIN3_LSB                                                                20
-#define PHY_BB_PA_GAIN123_PA_GAIN3_MASK                                                       0x3ff00000
-#define PHY_BB_PA_GAIN123_PA_GAIN3_GET(x)                                     (((x) & 0x3ff00000) >> 20)
-#define PHY_BB_PA_GAIN123_PA_GAIN3_SET(x)                                     (((x) << 20) & 0x3ff00000)
-
-/* macros for BB_pa_gain45 */
-#define PHY_BB_PA_GAIN45_ADDRESS                                                              0x00009dfc
-#define PHY_BB_PA_GAIN45_OFFSET                                                               0x00009dfc
-#define PHY_BB_PA_GAIN45_PA_GAIN4_MSB                                                                  9
-#define PHY_BB_PA_GAIN45_PA_GAIN4_LSB                                                                  0
-#define PHY_BB_PA_GAIN45_PA_GAIN4_MASK                                                        0x000003ff
-#define PHY_BB_PA_GAIN45_PA_GAIN4_GET(x)                                       (((x) & 0x000003ff) >> 0)
-#define PHY_BB_PA_GAIN45_PA_GAIN4_SET(x)                                       (((x) << 0) & 0x000003ff)
-#define PHY_BB_PA_GAIN45_PA_GAIN5_MSB                                                                 19
-#define PHY_BB_PA_GAIN45_PA_GAIN5_LSB                                                                 10
-#define PHY_BB_PA_GAIN45_PA_GAIN5_MASK                                                        0x000ffc00
-#define PHY_BB_PA_GAIN45_PA_GAIN5_GET(x)                                      (((x) & 0x000ffc00) >> 10)
-#define PHY_BB_PA_GAIN45_PA_GAIN5_SET(x)                                      (((x) << 10) & 0x000ffc00)
-#define PHY_BB_PA_GAIN45_PAPRD_ADAPTIVE_TABLE_VALID_MSB                                               24
-#define PHY_BB_PA_GAIN45_PAPRD_ADAPTIVE_TABLE_VALID_LSB                                               20
-#define PHY_BB_PA_GAIN45_PAPRD_ADAPTIVE_TABLE_VALID_MASK                                      0x01f00000
-#define PHY_BB_PA_GAIN45_PAPRD_ADAPTIVE_TABLE_VALID_GET(x)                    (((x) & 0x01f00000) >> 20)
-#define PHY_BB_PA_GAIN45_PAPRD_ADAPTIVE_TABLE_VALID_SET(x)                    (((x) << 20) & 0x01f00000)
-
-/* macros for BB_paprd_pre_post_scale_0 */
-#define PHY_BB_PAPRD_PRE_POST_SCALE_0_ADDRESS                                                 0x00009e00
-#define PHY_BB_PAPRD_PRE_POST_SCALE_0_OFFSET                                                  0x00009e00
-#define PHY_BB_PAPRD_PRE_POST_SCALE_0_PAPRD_PRE_POST_SCALING_0_MSB                                    17
-#define PHY_BB_PAPRD_PRE_POST_SCALE_0_PAPRD_PRE_POST_SCALING_0_LSB                                     0
-#define PHY_BB_PAPRD_PRE_POST_SCALE_0_PAPRD_PRE_POST_SCALING_0_MASK                           0x0003ffff
-#define PHY_BB_PAPRD_PRE_POST_SCALE_0_PAPRD_PRE_POST_SCALING_0_GET(x)          (((x) & 0x0003ffff) >> 0)
-#define PHY_BB_PAPRD_PRE_POST_SCALE_0_PAPRD_PRE_POST_SCALING_0_SET(x)          (((x) << 0) & 0x0003ffff)
-
-/* macros for BB_paprd_pre_post_scale_1 */
-#define PHY_BB_PAPRD_PRE_POST_SCALE_1_ADDRESS                                                 0x00009e04
-#define PHY_BB_PAPRD_PRE_POST_SCALE_1_OFFSET                                                  0x00009e04
-#define PHY_BB_PAPRD_PRE_POST_SCALE_1_PAPRD_PRE_POST_SCALING_1_MSB                                    17
-#define PHY_BB_PAPRD_PRE_POST_SCALE_1_PAPRD_PRE_POST_SCALING_1_LSB                                     0
-#define PHY_BB_PAPRD_PRE_POST_SCALE_1_PAPRD_PRE_POST_SCALING_1_MASK                           0x0003ffff
-#define PHY_BB_PAPRD_PRE_POST_SCALE_1_PAPRD_PRE_POST_SCALING_1_GET(x)          (((x) & 0x0003ffff) >> 0)
-#define PHY_BB_PAPRD_PRE_POST_SCALE_1_PAPRD_PRE_POST_SCALING_1_SET(x)          (((x) << 0) & 0x0003ffff)
-
-/* macros for BB_paprd_pre_post_scale_2 */
-#define PHY_BB_PAPRD_PRE_POST_SCALE_2_ADDRESS                                                 0x00009e08
-#define PHY_BB_PAPRD_PRE_POST_SCALE_2_OFFSET                                                  0x00009e08
-#define PHY_BB_PAPRD_PRE_POST_SCALE_2_PAPRD_PRE_POST_SCALING_2_MSB                                    17
-#define PHY_BB_PAPRD_PRE_POST_SCALE_2_PAPRD_PRE_POST_SCALING_2_LSB                                     0
-#define PHY_BB_PAPRD_PRE_POST_SCALE_2_PAPRD_PRE_POST_SCALING_2_MASK                           0x0003ffff
-#define PHY_BB_PAPRD_PRE_POST_SCALE_2_PAPRD_PRE_POST_SCALING_2_GET(x)          (((x) & 0x0003ffff) >> 0)
-#define PHY_BB_PAPRD_PRE_POST_SCALE_2_PAPRD_PRE_POST_SCALING_2_SET(x)          (((x) << 0) & 0x0003ffff)
-
-/* macros for BB_paprd_pre_post_scale_3 */
-#define PHY_BB_PAPRD_PRE_POST_SCALE_3_ADDRESS                                                 0x00009e0c
-#define PHY_BB_PAPRD_PRE_POST_SCALE_3_OFFSET                                                  0x00009e0c
-#define PHY_BB_PAPRD_PRE_POST_SCALE_3_PAPRD_PRE_POST_SCALING_3_MSB                                    17
-#define PHY_BB_PAPRD_PRE_POST_SCALE_3_PAPRD_PRE_POST_SCALING_3_LSB                                     0
-#define PHY_BB_PAPRD_PRE_POST_SCALE_3_PAPRD_PRE_POST_SCALING_3_MASK                           0x0003ffff
-#define PHY_BB_PAPRD_PRE_POST_SCALE_3_PAPRD_PRE_POST_SCALING_3_GET(x)          (((x) & 0x0003ffff) >> 0)
-#define PHY_BB_PAPRD_PRE_POST_SCALE_3_PAPRD_PRE_POST_SCALING_3_SET(x)          (((x) << 0) & 0x0003ffff)
-
-/* macros for BB_paprd_pre_post_scale_4 */
-#define PHY_BB_PAPRD_PRE_POST_SCALE_4_ADDRESS                                                 0x00009e10
-#define PHY_BB_PAPRD_PRE_POST_SCALE_4_OFFSET                                                  0x00009e10
-#define PHY_BB_PAPRD_PRE_POST_SCALE_4_PAPRD_PRE_POST_SCALING_4_MSB                                    17
-#define PHY_BB_PAPRD_PRE_POST_SCALE_4_PAPRD_PRE_POST_SCALING_4_LSB                                     0
-#define PHY_BB_PAPRD_PRE_POST_SCALE_4_PAPRD_PRE_POST_SCALING_4_MASK                           0x0003ffff
-#define PHY_BB_PAPRD_PRE_POST_SCALE_4_PAPRD_PRE_POST_SCALING_4_GET(x)          (((x) & 0x0003ffff) >> 0)
-#define PHY_BB_PAPRD_PRE_POST_SCALE_4_PAPRD_PRE_POST_SCALING_4_SET(x)          (((x) << 0) & 0x0003ffff)
-
-/* macros for BB_paprd_pre_post_scale_5 */
-#define PHY_BB_PAPRD_PRE_POST_SCALE_5_ADDRESS                                                 0x00009e14
-#define PHY_BB_PAPRD_PRE_POST_SCALE_5_OFFSET                                                  0x00009e14
-#define PHY_BB_PAPRD_PRE_POST_SCALE_5_PAPRD_PRE_POST_SCALING_5_MSB                                    17
-#define PHY_BB_PAPRD_PRE_POST_SCALE_5_PAPRD_PRE_POST_SCALING_5_LSB                                     0
-#define PHY_BB_PAPRD_PRE_POST_SCALE_5_PAPRD_PRE_POST_SCALING_5_MASK                           0x0003ffff
-#define PHY_BB_PAPRD_PRE_POST_SCALE_5_PAPRD_PRE_POST_SCALING_5_GET(x)          (((x) & 0x0003ffff) >> 0)
-#define PHY_BB_PAPRD_PRE_POST_SCALE_5_PAPRD_PRE_POST_SCALING_5_SET(x)          (((x) << 0) & 0x0003ffff)
-
-/* macros for BB_paprd_pre_post_scale_6 */
-#define PHY_BB_PAPRD_PRE_POST_SCALE_6_ADDRESS                                                 0x00009e18
-#define PHY_BB_PAPRD_PRE_POST_SCALE_6_OFFSET                                                  0x00009e18
-#define PHY_BB_PAPRD_PRE_POST_SCALE_6_PAPRD_PRE_POST_SCALING_6_MSB                                    17
-#define PHY_BB_PAPRD_PRE_POST_SCALE_6_PAPRD_PRE_POST_SCALING_6_LSB                                     0
-#define PHY_BB_PAPRD_PRE_POST_SCALE_6_PAPRD_PRE_POST_SCALING_6_MASK                           0x0003ffff
-#define PHY_BB_PAPRD_PRE_POST_SCALE_6_PAPRD_PRE_POST_SCALING_6_GET(x)          (((x) & 0x0003ffff) >> 0)
-#define PHY_BB_PAPRD_PRE_POST_SCALE_6_PAPRD_PRE_POST_SCALING_6_SET(x)          (((x) << 0) & 0x0003ffff)
-
-/* macros for BB_paprd_pre_post_scale_7 */
-#define PHY_BB_PAPRD_PRE_POST_SCALE_7_ADDRESS                                                 0x00009e1c
-#define PHY_BB_PAPRD_PRE_POST_SCALE_7_OFFSET                                                  0x00009e1c
-#define PHY_BB_PAPRD_PRE_POST_SCALE_7_PAPRD_PRE_POST_SCALING_7_MSB                                    17
-#define PHY_BB_PAPRD_PRE_POST_SCALE_7_PAPRD_PRE_POST_SCALING_7_LSB                                     0
-#define PHY_BB_PAPRD_PRE_POST_SCALE_7_PAPRD_PRE_POST_SCALING_7_MASK                           0x0003ffff
-#define PHY_BB_PAPRD_PRE_POST_SCALE_7_PAPRD_PRE_POST_SCALING_7_GET(x)          (((x) & 0x0003ffff) >> 0)
-#define PHY_BB_PAPRD_PRE_POST_SCALE_7_PAPRD_PRE_POST_SCALING_7_SET(x)          (((x) << 0) & 0x0003ffff)
-
-/* macros for BB_paprd_mem_tab */
-#define PHY_BB_PAPRD_MEM_TAB_ADDRESS                                                          0x00009e20
-#define PHY_BB_PAPRD_MEM_TAB_OFFSET                                                           0x00009e20
-#define PHY_BB_PAPRD_MEM_TAB_PAPRD_MEM_MSB                                                            21
-#define PHY_BB_PAPRD_MEM_TAB_PAPRD_MEM_LSB                                                             0
-#define PHY_BB_PAPRD_MEM_TAB_PAPRD_MEM_MASK                                                   0x003fffff
-#define PHY_BB_PAPRD_MEM_TAB_PAPRD_MEM_GET(x)                                  (((x) & 0x003fffff) >> 0)
-#define PHY_BB_PAPRD_MEM_TAB_PAPRD_MEM_SET(x)                                  (((x) << 0) & 0x003fffff)
-
-/* macros for BB_peak_det_ctrl_1 */
-#define PHY_BB_PEAK_DET_CTRL_1_ADDRESS                                                        0x0000a000
-#define PHY_BB_PEAK_DET_CTRL_1_OFFSET                                                         0x0000a000
-#define PHY_BB_PEAK_DET_CTRL_1_USE_OC_GAIN_TABLE_MSB                                                   0
-#define PHY_BB_PEAK_DET_CTRL_1_USE_OC_GAIN_TABLE_LSB                                                   0
-#define PHY_BB_PEAK_DET_CTRL_1_USE_OC_GAIN_TABLE_MASK                                         0x00000001
-#define PHY_BB_PEAK_DET_CTRL_1_USE_OC_GAIN_TABLE_GET(x)                        (((x) & 0x00000001) >> 0)
-#define PHY_BB_PEAK_DET_CTRL_1_USE_OC_GAIN_TABLE_SET(x)                        (((x) << 0) & 0x00000001)
-#define PHY_BB_PEAK_DET_CTRL_1_USE_PEAK_DET_MSB                                                        1
-#define PHY_BB_PEAK_DET_CTRL_1_USE_PEAK_DET_LSB                                                        1
-#define PHY_BB_PEAK_DET_CTRL_1_USE_PEAK_DET_MASK                                              0x00000002
-#define PHY_BB_PEAK_DET_CTRL_1_USE_PEAK_DET_GET(x)                             (((x) & 0x00000002) >> 1)
-#define PHY_BB_PEAK_DET_CTRL_1_USE_PEAK_DET_SET(x)                             (((x) << 1) & 0x00000002)
-#define PHY_BB_PEAK_DET_CTRL_1_PEAK_DET_WIN_LEN_MSB                                                    7
-#define PHY_BB_PEAK_DET_CTRL_1_PEAK_DET_WIN_LEN_LSB                                                    2
-#define PHY_BB_PEAK_DET_CTRL_1_PEAK_DET_WIN_LEN_MASK                                          0x000000fc
-#define PHY_BB_PEAK_DET_CTRL_1_PEAK_DET_WIN_LEN_GET(x)                         (((x) & 0x000000fc) >> 2)
-#define PHY_BB_PEAK_DET_CTRL_1_PEAK_DET_WIN_LEN_SET(x)                         (((x) << 2) & 0x000000fc)
-#define PHY_BB_PEAK_DET_CTRL_1_PEAK_DET_TALLY_THR_LOW_MSB                                             12
-#define PHY_BB_PEAK_DET_CTRL_1_PEAK_DET_TALLY_THR_LOW_LSB                                              8
-#define PHY_BB_PEAK_DET_CTRL_1_PEAK_DET_TALLY_THR_LOW_MASK                                    0x00001f00
-#define PHY_BB_PEAK_DET_CTRL_1_PEAK_DET_TALLY_THR_LOW_GET(x)                   (((x) & 0x00001f00) >> 8)
-#define PHY_BB_PEAK_DET_CTRL_1_PEAK_DET_TALLY_THR_LOW_SET(x)                   (((x) << 8) & 0x00001f00)
-#define PHY_BB_PEAK_DET_CTRL_1_PEAK_DET_TALLY_THR_MED_MSB                                             17
-#define PHY_BB_PEAK_DET_CTRL_1_PEAK_DET_TALLY_THR_MED_LSB                                             13
-#define PHY_BB_PEAK_DET_CTRL_1_PEAK_DET_TALLY_THR_MED_MASK                                    0x0003e000
-#define PHY_BB_PEAK_DET_CTRL_1_PEAK_DET_TALLY_THR_MED_GET(x)                  (((x) & 0x0003e000) >> 13)
-#define PHY_BB_PEAK_DET_CTRL_1_PEAK_DET_TALLY_THR_MED_SET(x)                  (((x) << 13) & 0x0003e000)
-#define PHY_BB_PEAK_DET_CTRL_1_PEAK_DET_TALLY_THR_HIGH_MSB                                            22
-#define PHY_BB_PEAK_DET_CTRL_1_PEAK_DET_TALLY_THR_HIGH_LSB                                            18
-#define PHY_BB_PEAK_DET_CTRL_1_PEAK_DET_TALLY_THR_HIGH_MASK                                   0x007c0000
-#define PHY_BB_PEAK_DET_CTRL_1_PEAK_DET_TALLY_THR_HIGH_GET(x)                 (((x) & 0x007c0000) >> 18)
-#define PHY_BB_PEAK_DET_CTRL_1_PEAK_DET_TALLY_THR_HIGH_SET(x)                 (((x) << 18) & 0x007c0000)
-#define PHY_BB_PEAK_DET_CTRL_1_PEAK_DET_SETTLING_MSB                                                  29
-#define PHY_BB_PEAK_DET_CTRL_1_PEAK_DET_SETTLING_LSB                                                  23
-#define PHY_BB_PEAK_DET_CTRL_1_PEAK_DET_SETTLING_MASK                                         0x3f800000
-#define PHY_BB_PEAK_DET_CTRL_1_PEAK_DET_SETTLING_GET(x)                       (((x) & 0x3f800000) >> 23)
-#define PHY_BB_PEAK_DET_CTRL_1_PEAK_DET_SETTLING_SET(x)                       (((x) << 23) & 0x3f800000)
-#define PHY_BB_PEAK_DET_CTRL_1_PWD_PKDET_DURING_CAL_MSB                                               30
-#define PHY_BB_PEAK_DET_CTRL_1_PWD_PKDET_DURING_CAL_LSB                                               30
-#define PHY_BB_PEAK_DET_CTRL_1_PWD_PKDET_DURING_CAL_MASK                                      0x40000000
-#define PHY_BB_PEAK_DET_CTRL_1_PWD_PKDET_DURING_CAL_GET(x)                    (((x) & 0x40000000) >> 30)
-#define PHY_BB_PEAK_DET_CTRL_1_PWD_PKDET_DURING_CAL_SET(x)                    (((x) << 30) & 0x40000000)
-#define PHY_BB_PEAK_DET_CTRL_1_PWD_PKDET_DURING_RX_MSB                                                31
-#define PHY_BB_PEAK_DET_CTRL_1_PWD_PKDET_DURING_RX_LSB                                                31
-#define PHY_BB_PEAK_DET_CTRL_1_PWD_PKDET_DURING_RX_MASK                                       0x80000000
-#define PHY_BB_PEAK_DET_CTRL_1_PWD_PKDET_DURING_RX_GET(x)                     (((x) & 0x80000000) >> 31)
-#define PHY_BB_PEAK_DET_CTRL_1_PWD_PKDET_DURING_RX_SET(x)                     (((x) << 31) & 0x80000000)
-
-/* macros for BB_peak_det_ctrl_2 */
-#define PHY_BB_PEAK_DET_CTRL_2_ADDRESS                                                        0x0000a004
-#define PHY_BB_PEAK_DET_CTRL_2_OFFSET                                                         0x0000a004
-#define PHY_BB_PEAK_DET_CTRL_2_RFSAT_2_ADD_RFGAIN_DEL_MSB                                              9
-#define PHY_BB_PEAK_DET_CTRL_2_RFSAT_2_ADD_RFGAIN_DEL_LSB                                              0
-#define PHY_BB_PEAK_DET_CTRL_2_RFSAT_2_ADD_RFGAIN_DEL_MASK                                    0x000003ff
-#define PHY_BB_PEAK_DET_CTRL_2_RFSAT_2_ADD_RFGAIN_DEL_GET(x)                   (((x) & 0x000003ff) >> 0)
-#define PHY_BB_PEAK_DET_CTRL_2_RFSAT_2_ADD_RFGAIN_DEL_SET(x)                   (((x) << 0) & 0x000003ff)
-#define PHY_BB_PEAK_DET_CTRL_2_RF_GAIN_DROP_DB_LOW_MSB                                                14
-#define PHY_BB_PEAK_DET_CTRL_2_RF_GAIN_DROP_DB_LOW_LSB                                                10
-#define PHY_BB_PEAK_DET_CTRL_2_RF_GAIN_DROP_DB_LOW_MASK                                       0x00007c00
-#define PHY_BB_PEAK_DET_CTRL_2_RF_GAIN_DROP_DB_LOW_GET(x)                     (((x) & 0x00007c00) >> 10)
-#define PHY_BB_PEAK_DET_CTRL_2_RF_GAIN_DROP_DB_LOW_SET(x)                     (((x) << 10) & 0x00007c00)
-#define PHY_BB_PEAK_DET_CTRL_2_RF_GAIN_DROP_DB_MED_MSB                                                19
-#define PHY_BB_PEAK_DET_CTRL_2_RF_GAIN_DROP_DB_MED_LSB                                                15
-#define PHY_BB_PEAK_DET_CTRL_2_RF_GAIN_DROP_DB_MED_MASK                                       0x000f8000
-#define PHY_BB_PEAK_DET_CTRL_2_RF_GAIN_DROP_DB_MED_GET(x)                     (((x) & 0x000f8000) >> 15)
-#define PHY_BB_PEAK_DET_CTRL_2_RF_GAIN_DROP_DB_MED_SET(x)                     (((x) << 15) & 0x000f8000)
-#define PHY_BB_PEAK_DET_CTRL_2_RF_GAIN_DROP_DB_HIGH_MSB                                               24
-#define PHY_BB_PEAK_DET_CTRL_2_RF_GAIN_DROP_DB_HIGH_LSB                                               20
-#define PHY_BB_PEAK_DET_CTRL_2_RF_GAIN_DROP_DB_HIGH_MASK                                      0x01f00000
-#define PHY_BB_PEAK_DET_CTRL_2_RF_GAIN_DROP_DB_HIGH_GET(x)                    (((x) & 0x01f00000) >> 20)
-#define PHY_BB_PEAK_DET_CTRL_2_RF_GAIN_DROP_DB_HIGH_SET(x)                    (((x) << 20) & 0x01f00000)
-#define PHY_BB_PEAK_DET_CTRL_2_RF_GAIN_DROP_DB_NON_MSB                                                29
-#define PHY_BB_PEAK_DET_CTRL_2_RF_GAIN_DROP_DB_NON_LSB                                                25
-#define PHY_BB_PEAK_DET_CTRL_2_RF_GAIN_DROP_DB_NON_MASK                                       0x3e000000
-#define PHY_BB_PEAK_DET_CTRL_2_RF_GAIN_DROP_DB_NON_GET(x)                     (((x) & 0x3e000000) >> 25)
-#define PHY_BB_PEAK_DET_CTRL_2_RF_GAIN_DROP_DB_NON_SET(x)                     (((x) << 25) & 0x3e000000)
-
-/* macros for BB_rx_gain_bounds_1 */
-#define PHY_BB_RX_GAIN_BOUNDS_1_ADDRESS                                                       0x0000a008
-#define PHY_BB_RX_GAIN_BOUNDS_1_OFFSET                                                        0x0000a008
-#define PHY_BB_RX_GAIN_BOUNDS_1_RX_MAX_MB_GAIN_MSB                                                     7
-#define PHY_BB_RX_GAIN_BOUNDS_1_RX_MAX_MB_GAIN_LSB                                                     0
-#define PHY_BB_RX_GAIN_BOUNDS_1_RX_MAX_MB_GAIN_MASK                                           0x000000ff
-#define PHY_BB_RX_GAIN_BOUNDS_1_RX_MAX_MB_GAIN_GET(x)                          (((x) & 0x000000ff) >> 0)
-#define PHY_BB_RX_GAIN_BOUNDS_1_RX_MAX_MB_GAIN_SET(x)                          (((x) << 0) & 0x000000ff)
-#define PHY_BB_RX_GAIN_BOUNDS_1_RX_MAX_RF_GAIN_REF_MSB                                                15
-#define PHY_BB_RX_GAIN_BOUNDS_1_RX_MAX_RF_GAIN_REF_LSB                                                 8
-#define PHY_BB_RX_GAIN_BOUNDS_1_RX_MAX_RF_GAIN_REF_MASK                                       0x0000ff00
-#define PHY_BB_RX_GAIN_BOUNDS_1_RX_MAX_RF_GAIN_REF_GET(x)                      (((x) & 0x0000ff00) >> 8)
-#define PHY_BB_RX_GAIN_BOUNDS_1_RX_MAX_RF_GAIN_REF_SET(x)                      (((x) << 8) & 0x0000ff00)
-#define PHY_BB_RX_GAIN_BOUNDS_1_RX_MAX_RF_GAIN_MSB                                                    23
-#define PHY_BB_RX_GAIN_BOUNDS_1_RX_MAX_RF_GAIN_LSB                                                    16
-#define PHY_BB_RX_GAIN_BOUNDS_1_RX_MAX_RF_GAIN_MASK                                           0x00ff0000
-#define PHY_BB_RX_GAIN_BOUNDS_1_RX_MAX_RF_GAIN_GET(x)                         (((x) & 0x00ff0000) >> 16)
-#define PHY_BB_RX_GAIN_BOUNDS_1_RX_MAX_RF_GAIN_SET(x)                         (((x) << 16) & 0x00ff0000)
-#define PHY_BB_RX_GAIN_BOUNDS_1_RX_OCGAIN_SEL_2G_MSB                                                  24
-#define PHY_BB_RX_GAIN_BOUNDS_1_RX_OCGAIN_SEL_2G_LSB                                                  24
-#define PHY_BB_RX_GAIN_BOUNDS_1_RX_OCGAIN_SEL_2G_MASK                                         0x01000000
-#define PHY_BB_RX_GAIN_BOUNDS_1_RX_OCGAIN_SEL_2G_GET(x)                       (((x) & 0x01000000) >> 24)
-#define PHY_BB_RX_GAIN_BOUNDS_1_RX_OCGAIN_SEL_2G_SET(x)                       (((x) << 24) & 0x01000000)
-#define PHY_BB_RX_GAIN_BOUNDS_1_RX_OCGAIN_SEL_5G_MSB                                                  25
-#define PHY_BB_RX_GAIN_BOUNDS_1_RX_OCGAIN_SEL_5G_LSB                                                  25
-#define PHY_BB_RX_GAIN_BOUNDS_1_RX_OCGAIN_SEL_5G_MASK                                         0x02000000
-#define PHY_BB_RX_GAIN_BOUNDS_1_RX_OCGAIN_SEL_5G_GET(x)                       (((x) & 0x02000000) >> 25)
-#define PHY_BB_RX_GAIN_BOUNDS_1_RX_OCGAIN_SEL_5G_SET(x)                       (((x) << 25) & 0x02000000)
-
-/* macros for BB_rx_gain_bounds_2 */
-#define PHY_BB_RX_GAIN_BOUNDS_2_ADDRESS                                                       0x0000a00c
-#define PHY_BB_RX_GAIN_BOUNDS_2_OFFSET                                                        0x0000a00c
-#define PHY_BB_RX_GAIN_BOUNDS_2_GC_RSSI_LOW_DB_MSB                                                     7
-#define PHY_BB_RX_GAIN_BOUNDS_2_GC_RSSI_LOW_DB_LSB                                                     0
-#define PHY_BB_RX_GAIN_BOUNDS_2_GC_RSSI_LOW_DB_MASK                                           0x000000ff
-#define PHY_BB_RX_GAIN_BOUNDS_2_GC_RSSI_LOW_DB_GET(x)                          (((x) & 0x000000ff) >> 0)
-#define PHY_BB_RX_GAIN_BOUNDS_2_GC_RSSI_LOW_DB_SET(x)                          (((x) << 0) & 0x000000ff)
-#define PHY_BB_RX_GAIN_BOUNDS_2_RF_GAIN_REF_BASE_ADDR_MSB                                             15
-#define PHY_BB_RX_GAIN_BOUNDS_2_RF_GAIN_REF_BASE_ADDR_LSB                                              8
-#define PHY_BB_RX_GAIN_BOUNDS_2_RF_GAIN_REF_BASE_ADDR_MASK                                    0x0000ff00
-#define PHY_BB_RX_GAIN_BOUNDS_2_RF_GAIN_REF_BASE_ADDR_GET(x)                   (((x) & 0x0000ff00) >> 8)
-#define PHY_BB_RX_GAIN_BOUNDS_2_RF_GAIN_REF_BASE_ADDR_SET(x)                   (((x) << 8) & 0x0000ff00)
-#define PHY_BB_RX_GAIN_BOUNDS_2_RF_GAIN_BASE_ADDR_MSB                                                 23
-#define PHY_BB_RX_GAIN_BOUNDS_2_RF_GAIN_BASE_ADDR_LSB                                                 16
-#define PHY_BB_RX_GAIN_BOUNDS_2_RF_GAIN_BASE_ADDR_MASK                                        0x00ff0000
-#define PHY_BB_RX_GAIN_BOUNDS_2_RF_GAIN_BASE_ADDR_GET(x)                      (((x) & 0x00ff0000) >> 16)
-#define PHY_BB_RX_GAIN_BOUNDS_2_RF_GAIN_BASE_ADDR_SET(x)                      (((x) << 16) & 0x00ff0000)
-#define PHY_BB_RX_GAIN_BOUNDS_2_RF_GAIN_DIV_BASE_ADDR_MSB                                             31
-#define PHY_BB_RX_GAIN_BOUNDS_2_RF_GAIN_DIV_BASE_ADDR_LSB                                             24
-#define PHY_BB_RX_GAIN_BOUNDS_2_RF_GAIN_DIV_BASE_ADDR_MASK                                    0xff000000
-#define PHY_BB_RX_GAIN_BOUNDS_2_RF_GAIN_DIV_BASE_ADDR_GET(x)                  (((x) & 0xff000000) >> 24)
-#define PHY_BB_RX_GAIN_BOUNDS_2_RF_GAIN_DIV_BASE_ADDR_SET(x)                  (((x) << 24) & 0xff000000)
-
-/* macros for BB_peak_det_cal_ctrl */
-#define PHY_BB_PEAK_DET_CAL_CTRL_ADDRESS                                                      0x0000a010
-#define PHY_BB_PEAK_DET_CAL_CTRL_OFFSET                                                       0x0000a010
-#define PHY_BB_PEAK_DET_CAL_CTRL_PKDET_CAL_WIN_THR_MSB                                                 5
-#define PHY_BB_PEAK_DET_CAL_CTRL_PKDET_CAL_WIN_THR_LSB                                                 0
-#define PHY_BB_PEAK_DET_CAL_CTRL_PKDET_CAL_WIN_THR_MASK                                       0x0000003f
-#define PHY_BB_PEAK_DET_CAL_CTRL_PKDET_CAL_WIN_THR_GET(x)                      (((x) & 0x0000003f) >> 0)
-#define PHY_BB_PEAK_DET_CAL_CTRL_PKDET_CAL_WIN_THR_SET(x)                      (((x) << 0) & 0x0000003f)
-#define PHY_BB_PEAK_DET_CAL_CTRL_PKDET_CAL_BIAS_MSB                                                   11
-#define PHY_BB_PEAK_DET_CAL_CTRL_PKDET_CAL_BIAS_LSB                                                    6
-#define PHY_BB_PEAK_DET_CAL_CTRL_PKDET_CAL_BIAS_MASK                                          0x00000fc0
-#define PHY_BB_PEAK_DET_CAL_CTRL_PKDET_CAL_BIAS_GET(x)                         (((x) & 0x00000fc0) >> 6)
-#define PHY_BB_PEAK_DET_CAL_CTRL_PKDET_CAL_BIAS_SET(x)                         (((x) << 6) & 0x00000fc0)
-#define PHY_BB_PEAK_DET_CAL_CTRL_PKDET_CAL_MEAS_TIME_SEL_MSB                                          13
-#define PHY_BB_PEAK_DET_CAL_CTRL_PKDET_CAL_MEAS_TIME_SEL_LSB                                          12
-#define PHY_BB_PEAK_DET_CAL_CTRL_PKDET_CAL_MEAS_TIME_SEL_MASK                                 0x00003000
-#define PHY_BB_PEAK_DET_CAL_CTRL_PKDET_CAL_MEAS_TIME_SEL_GET(x)               (((x) & 0x00003000) >> 12)
-#define PHY_BB_PEAK_DET_CAL_CTRL_PKDET_CAL_MEAS_TIME_SEL_SET(x)               (((x) << 12) & 0x00003000)
-
-/* macros for BB_agc_dig_dc_ctrl */
-#define PHY_BB_AGC_DIG_DC_CTRL_ADDRESS                                                        0x0000a014
-#define PHY_BB_AGC_DIG_DC_CTRL_OFFSET                                                         0x0000a014
-#define PHY_BB_AGC_DIG_DC_CTRL_USE_DIG_DC_MSB                                                          0
-#define PHY_BB_AGC_DIG_DC_CTRL_USE_DIG_DC_LSB                                                          0
-#define PHY_BB_AGC_DIG_DC_CTRL_USE_DIG_DC_MASK                                                0x00000001
-#define PHY_BB_AGC_DIG_DC_CTRL_USE_DIG_DC_GET(x)                               (((x) & 0x00000001) >> 0)
-#define PHY_BB_AGC_DIG_DC_CTRL_USE_DIG_DC_SET(x)                               (((x) << 0) & 0x00000001)
-#define PHY_BB_AGC_DIG_DC_CTRL_DIG_DC_SCALE_BIAS_MSB                                                   3
-#define PHY_BB_AGC_DIG_DC_CTRL_DIG_DC_SCALE_BIAS_LSB                                                   1
-#define PHY_BB_AGC_DIG_DC_CTRL_DIG_DC_SCALE_BIAS_MASK                                         0x0000000e
-#define PHY_BB_AGC_DIG_DC_CTRL_DIG_DC_SCALE_BIAS_GET(x)                        (((x) & 0x0000000e) >> 1)
-#define PHY_BB_AGC_DIG_DC_CTRL_DIG_DC_SCALE_BIAS_SET(x)                        (((x) << 1) & 0x0000000e)
-#define PHY_BB_AGC_DIG_DC_CTRL_DIG_DC_CORRECT_CAP_MSB                                                  9
-#define PHY_BB_AGC_DIG_DC_CTRL_DIG_DC_CORRECT_CAP_LSB                                                  4
-#define PHY_BB_AGC_DIG_DC_CTRL_DIG_DC_CORRECT_CAP_MASK                                        0x000003f0
-#define PHY_BB_AGC_DIG_DC_CTRL_DIG_DC_CORRECT_CAP_GET(x)                       (((x) & 0x000003f0) >> 4)
-#define PHY_BB_AGC_DIG_DC_CTRL_DIG_DC_CORRECT_CAP_SET(x)                       (((x) << 4) & 0x000003f0)
-#define PHY_BB_AGC_DIG_DC_CTRL_DIG_DC_MIXER_SEL_MASK_MSB                                              31
-#define PHY_BB_AGC_DIG_DC_CTRL_DIG_DC_MIXER_SEL_MASK_LSB                                              16
-#define PHY_BB_AGC_DIG_DC_CTRL_DIG_DC_MIXER_SEL_MASK_MASK                                     0xffff0000
-#define PHY_BB_AGC_DIG_DC_CTRL_DIG_DC_MIXER_SEL_MASK_GET(x)                   (((x) & 0xffff0000) >> 16)
-#define PHY_BB_AGC_DIG_DC_CTRL_DIG_DC_MIXER_SEL_MASK_SET(x)                   (((x) << 16) & 0xffff0000)
-
-/* macros for BB_agc_dig_dc_status_i_b0 */
-#define PHY_BB_AGC_DIG_DC_STATUS_I_B0_ADDRESS                                                 0x0000a018
-#define PHY_BB_AGC_DIG_DC_STATUS_I_B0_OFFSET                                                  0x0000a018
-#define PHY_BB_AGC_DIG_DC_STATUS_I_B0_DIG_DC_C1_RES_I_0_MSB                                            8
-#define PHY_BB_AGC_DIG_DC_STATUS_I_B0_DIG_DC_C1_RES_I_0_LSB                                            0
-#define PHY_BB_AGC_DIG_DC_STATUS_I_B0_DIG_DC_C1_RES_I_0_MASK                                  0x000001ff
-#define PHY_BB_AGC_DIG_DC_STATUS_I_B0_DIG_DC_C1_RES_I_0_GET(x)                 (((x) & 0x000001ff) >> 0)
-#define PHY_BB_AGC_DIG_DC_STATUS_I_B0_DIG_DC_C2_RES_I_0_MSB                                           17
-#define PHY_BB_AGC_DIG_DC_STATUS_I_B0_DIG_DC_C2_RES_I_0_LSB                                            9
-#define PHY_BB_AGC_DIG_DC_STATUS_I_B0_DIG_DC_C2_RES_I_0_MASK                                  0x0003fe00
-#define PHY_BB_AGC_DIG_DC_STATUS_I_B0_DIG_DC_C2_RES_I_0_GET(x)                 (((x) & 0x0003fe00) >> 9)
-#define PHY_BB_AGC_DIG_DC_STATUS_I_B0_DIG_DC_C3_RES_I_0_MSB                                           26
-#define PHY_BB_AGC_DIG_DC_STATUS_I_B0_DIG_DC_C3_RES_I_0_LSB                                           18
-#define PHY_BB_AGC_DIG_DC_STATUS_I_B0_DIG_DC_C3_RES_I_0_MASK                                  0x07fc0000
-#define PHY_BB_AGC_DIG_DC_STATUS_I_B0_DIG_DC_C3_RES_I_0_GET(x)                (((x) & 0x07fc0000) >> 18)
-
-/* macros for BB_agc_dig_dc_status_q_b0 */
-#define PHY_BB_AGC_DIG_DC_STATUS_Q_B0_ADDRESS                                                 0x0000a01c
-#define PHY_BB_AGC_DIG_DC_STATUS_Q_B0_OFFSET                                                  0x0000a01c
-#define PHY_BB_AGC_DIG_DC_STATUS_Q_B0_DIG_DC_C1_RES_Q_0_MSB                                            8
-#define PHY_BB_AGC_DIG_DC_STATUS_Q_B0_DIG_DC_C1_RES_Q_0_LSB                                            0
-#define PHY_BB_AGC_DIG_DC_STATUS_Q_B0_DIG_DC_C1_RES_Q_0_MASK                                  0x000001ff
-#define PHY_BB_AGC_DIG_DC_STATUS_Q_B0_DIG_DC_C1_RES_Q_0_GET(x)                 (((x) & 0x000001ff) >> 0)
-#define PHY_BB_AGC_DIG_DC_STATUS_Q_B0_DIG_DC_C2_RES_Q_0_MSB                                           17
-#define PHY_BB_AGC_DIG_DC_STATUS_Q_B0_DIG_DC_C2_RES_Q_0_LSB                                            9
-#define PHY_BB_AGC_DIG_DC_STATUS_Q_B0_DIG_DC_C2_RES_Q_0_MASK                                  0x0003fe00
-#define PHY_BB_AGC_DIG_DC_STATUS_Q_B0_DIG_DC_C2_RES_Q_0_GET(x)                 (((x) & 0x0003fe00) >> 9)
-#define PHY_BB_AGC_DIG_DC_STATUS_Q_B0_DIG_DC_C3_RES_Q_0_MSB                                           26
-#define PHY_BB_AGC_DIG_DC_STATUS_Q_B0_DIG_DC_C3_RES_Q_0_LSB                                           18
-#define PHY_BB_AGC_DIG_DC_STATUS_Q_B0_DIG_DC_C3_RES_Q_0_MASK                                  0x07fc0000
-#define PHY_BB_AGC_DIG_DC_STATUS_Q_B0_DIG_DC_C3_RES_Q_0_GET(x)                (((x) & 0x07fc0000) >> 18)
-
-/* macros for BB_bbb_txfir_0 */
-#define PHY_BB_BBB_TXFIR_0_ADDRESS                                                            0x0000a1f4
-#define PHY_BB_BBB_TXFIR_0_OFFSET                                                             0x0000a1f4
-#define PHY_BB_BBB_TXFIR_0_TXFIR_COEFF_H0_MSB                                                          3
-#define PHY_BB_BBB_TXFIR_0_TXFIR_COEFF_H0_LSB                                                          0
-#define PHY_BB_BBB_TXFIR_0_TXFIR_COEFF_H0_MASK                                                0x0000000f
-#define PHY_BB_BBB_TXFIR_0_TXFIR_COEFF_H0_GET(x)                               (((x) & 0x0000000f) >> 0)
-#define PHY_BB_BBB_TXFIR_0_TXFIR_COEFF_H0_SET(x)                               (((x) << 0) & 0x0000000f)
-#define PHY_BB_BBB_TXFIR_0_TXFIR_COEFF_H1_MSB                                                         11
-#define PHY_BB_BBB_TXFIR_0_TXFIR_COEFF_H1_LSB                                                          8
-#define PHY_BB_BBB_TXFIR_0_TXFIR_COEFF_H1_MASK                                                0x00000f00
-#define PHY_BB_BBB_TXFIR_0_TXFIR_COEFF_H1_GET(x)                               (((x) & 0x00000f00) >> 8)
-#define PHY_BB_BBB_TXFIR_0_TXFIR_COEFF_H1_SET(x)                               (((x) << 8) & 0x00000f00)
-#define PHY_BB_BBB_TXFIR_0_TXFIR_COEFF_H2_MSB                                                         20
-#define PHY_BB_BBB_TXFIR_0_TXFIR_COEFF_H2_LSB                                                         16
-#define PHY_BB_BBB_TXFIR_0_TXFIR_COEFF_H2_MASK                                                0x001f0000
-#define PHY_BB_BBB_TXFIR_0_TXFIR_COEFF_H2_GET(x)                              (((x) & 0x001f0000) >> 16)
-#define PHY_BB_BBB_TXFIR_0_TXFIR_COEFF_H2_SET(x)                              (((x) << 16) & 0x001f0000)
-#define PHY_BB_BBB_TXFIR_0_TXFIR_COEFF_H3_MSB                                                         28
-#define PHY_BB_BBB_TXFIR_0_TXFIR_COEFF_H3_LSB                                                         24
-#define PHY_BB_BBB_TXFIR_0_TXFIR_COEFF_H3_MASK                                                0x1f000000
-#define PHY_BB_BBB_TXFIR_0_TXFIR_COEFF_H3_GET(x)                              (((x) & 0x1f000000) >> 24)
-#define PHY_BB_BBB_TXFIR_0_TXFIR_COEFF_H3_SET(x)                              (((x) << 24) & 0x1f000000)
-
-/* macros for BB_bbb_txfir_1 */
-#define PHY_BB_BBB_TXFIR_1_ADDRESS                                                            0x0000a1f8
-#define PHY_BB_BBB_TXFIR_1_OFFSET                                                             0x0000a1f8
-#define PHY_BB_BBB_TXFIR_1_TXFIR_COEFF_H4_MSB                                                          5
-#define PHY_BB_BBB_TXFIR_1_TXFIR_COEFF_H4_LSB                                                          0
-#define PHY_BB_BBB_TXFIR_1_TXFIR_COEFF_H4_MASK                                                0x0000003f
-#define PHY_BB_BBB_TXFIR_1_TXFIR_COEFF_H4_GET(x)                               (((x) & 0x0000003f) >> 0)
-#define PHY_BB_BBB_TXFIR_1_TXFIR_COEFF_H4_SET(x)                               (((x) << 0) & 0x0000003f)
-#define PHY_BB_BBB_TXFIR_1_TXFIR_COEFF_H5_MSB                                                         13
-#define PHY_BB_BBB_TXFIR_1_TXFIR_COEFF_H5_LSB                                                          8
-#define PHY_BB_BBB_TXFIR_1_TXFIR_COEFF_H5_MASK                                                0x00003f00
-#define PHY_BB_BBB_TXFIR_1_TXFIR_COEFF_H5_GET(x)                               (((x) & 0x00003f00) >> 8)
-#define PHY_BB_BBB_TXFIR_1_TXFIR_COEFF_H5_SET(x)                               (((x) << 8) & 0x00003f00)
-#define PHY_BB_BBB_TXFIR_1_TXFIR_COEFF_H6_MSB                                                         22
-#define PHY_BB_BBB_TXFIR_1_TXFIR_COEFF_H6_LSB                                                         16
-#define PHY_BB_BBB_TXFIR_1_TXFIR_COEFF_H6_MASK                                                0x007f0000
-#define PHY_BB_BBB_TXFIR_1_TXFIR_COEFF_H6_GET(x)                              (((x) & 0x007f0000) >> 16)
-#define PHY_BB_BBB_TXFIR_1_TXFIR_COEFF_H6_SET(x)                              (((x) << 16) & 0x007f0000)
-#define PHY_BB_BBB_TXFIR_1_TXFIR_COEFF_H7_MSB                                                         30
-#define PHY_BB_BBB_TXFIR_1_TXFIR_COEFF_H7_LSB                                                         24
-#define PHY_BB_BBB_TXFIR_1_TXFIR_COEFF_H7_MASK                                                0x7f000000
-#define PHY_BB_BBB_TXFIR_1_TXFIR_COEFF_H7_GET(x)                              (((x) & 0x7f000000) >> 24)
-#define PHY_BB_BBB_TXFIR_1_TXFIR_COEFF_H7_SET(x)                              (((x) << 24) & 0x7f000000)
-
-/* macros for BB_bbb_txfir_2 */
-#define PHY_BB_BBB_TXFIR_2_ADDRESS                                                            0x0000a1fc
-#define PHY_BB_BBB_TXFIR_2_OFFSET                                                             0x0000a1fc
-#define PHY_BB_BBB_TXFIR_2_TXFIR_COEFF_H8_MSB                                                          7
-#define PHY_BB_BBB_TXFIR_2_TXFIR_COEFF_H8_LSB                                                          0
-#define PHY_BB_BBB_TXFIR_2_TXFIR_COEFF_H8_MASK                                                0x000000ff
-#define PHY_BB_BBB_TXFIR_2_TXFIR_COEFF_H8_GET(x)                               (((x) & 0x000000ff) >> 0)
-#define PHY_BB_BBB_TXFIR_2_TXFIR_COEFF_H8_SET(x)                               (((x) << 0) & 0x000000ff)
-#define PHY_BB_BBB_TXFIR_2_TXFIR_COEFF_H9_MSB                                                         15
-#define PHY_BB_BBB_TXFIR_2_TXFIR_COEFF_H9_LSB                                                          8
-#define PHY_BB_BBB_TXFIR_2_TXFIR_COEFF_H9_MASK                                                0x0000ff00
-#define PHY_BB_BBB_TXFIR_2_TXFIR_COEFF_H9_GET(x)                               (((x) & 0x0000ff00) >> 8)
-#define PHY_BB_BBB_TXFIR_2_TXFIR_COEFF_H9_SET(x)                               (((x) << 8) & 0x0000ff00)
-#define PHY_BB_BBB_TXFIR_2_TXFIR_COEFF_H10_MSB                                                        23
-#define PHY_BB_BBB_TXFIR_2_TXFIR_COEFF_H10_LSB                                                        16
-#define PHY_BB_BBB_TXFIR_2_TXFIR_COEFF_H10_MASK                                               0x00ff0000
-#define PHY_BB_BBB_TXFIR_2_TXFIR_COEFF_H10_GET(x)                             (((x) & 0x00ff0000) >> 16)
-#define PHY_BB_BBB_TXFIR_2_TXFIR_COEFF_H10_SET(x)                             (((x) << 16) & 0x00ff0000)
-#define PHY_BB_BBB_TXFIR_2_TXFIR_COEFF_H11_MSB                                                        31
-#define PHY_BB_BBB_TXFIR_2_TXFIR_COEFF_H11_LSB                                                        24
-#define PHY_BB_BBB_TXFIR_2_TXFIR_COEFF_H11_MASK                                               0xff000000
-#define PHY_BB_BBB_TXFIR_2_TXFIR_COEFF_H11_GET(x)                             (((x) & 0xff000000) >> 24)
-#define PHY_BB_BBB_TXFIR_2_TXFIR_COEFF_H11_SET(x)                             (((x) << 24) & 0xff000000)
-
-/* macros for BB_modes_select */
-#define PHY_BB_MODES_SELECT_ADDRESS                                                           0x0000a200
-#define PHY_BB_MODES_SELECT_OFFSET                                                            0x0000a200
-#define PHY_BB_MODES_SELECT_CCK_MODE_MSB                                                               0
-#define PHY_BB_MODES_SELECT_CCK_MODE_LSB                                                               0
-#define PHY_BB_MODES_SELECT_CCK_MODE_MASK                                                     0x00000001
-#define PHY_BB_MODES_SELECT_CCK_MODE_GET(x)                                    (((x) & 0x00000001) >> 0)
-#define PHY_BB_MODES_SELECT_CCK_MODE_SET(x)                                    (((x) << 0) & 0x00000001)
-#define PHY_BB_MODES_SELECT_DYN_OFDM_CCK_MODE_MSB                                                      2
-#define PHY_BB_MODES_SELECT_DYN_OFDM_CCK_MODE_LSB                                                      2
-#define PHY_BB_MODES_SELECT_DYN_OFDM_CCK_MODE_MASK                                            0x00000004
-#define PHY_BB_MODES_SELECT_DYN_OFDM_CCK_MODE_GET(x)                           (((x) & 0x00000004) >> 2)
-#define PHY_BB_MODES_SELECT_DYN_OFDM_CCK_MODE_SET(x)                           (((x) << 2) & 0x00000004)
-#define PHY_BB_MODES_SELECT_HALF_RATE_MODE_MSB                                                         5
-#define PHY_BB_MODES_SELECT_HALF_RATE_MODE_LSB                                                         5
-#define PHY_BB_MODES_SELECT_HALF_RATE_MODE_MASK                                               0x00000020
-#define PHY_BB_MODES_SELECT_HALF_RATE_MODE_GET(x)                              (((x) & 0x00000020) >> 5)
-#define PHY_BB_MODES_SELECT_HALF_RATE_MODE_SET(x)                              (((x) << 5) & 0x00000020)
-#define PHY_BB_MODES_SELECT_QUARTER_RATE_MODE_MSB                                                      6
-#define PHY_BB_MODES_SELECT_QUARTER_RATE_MODE_LSB                                                      6
-#define PHY_BB_MODES_SELECT_QUARTER_RATE_MODE_MASK                                            0x00000040
-#define PHY_BB_MODES_SELECT_QUARTER_RATE_MODE_GET(x)                           (((x) & 0x00000040) >> 6)
-#define PHY_BB_MODES_SELECT_QUARTER_RATE_MODE_SET(x)                           (((x) << 6) & 0x00000040)
-#define PHY_BB_MODES_SELECT_MAC_CLK_MODE_MSB                                                           7
-#define PHY_BB_MODES_SELECT_MAC_CLK_MODE_LSB                                                           7
-#define PHY_BB_MODES_SELECT_MAC_CLK_MODE_MASK                                                 0x00000080
-#define PHY_BB_MODES_SELECT_MAC_CLK_MODE_GET(x)                                (((x) & 0x00000080) >> 7)
-#define PHY_BB_MODES_SELECT_MAC_CLK_MODE_SET(x)                                (((x) << 7) & 0x00000080)
-#define PHY_BB_MODES_SELECT_DISABLE_DYN_CCK_DET_MSB                                                    8
-#define PHY_BB_MODES_SELECT_DISABLE_DYN_CCK_DET_LSB                                                    8
-#define PHY_BB_MODES_SELECT_DISABLE_DYN_CCK_DET_MASK                                          0x00000100
-#define PHY_BB_MODES_SELECT_DISABLE_DYN_CCK_DET_GET(x)                         (((x) & 0x00000100) >> 8)
-#define PHY_BB_MODES_SELECT_DISABLE_DYN_CCK_DET_SET(x)                         (((x) << 8) & 0x00000100)
-
-/* macros for BB_bbb_tx_ctrl */
-#define PHY_BB_BBB_TX_CTRL_ADDRESS                                                            0x0000a204
-#define PHY_BB_BBB_TX_CTRL_OFFSET                                                             0x0000a204
-#define PHY_BB_BBB_TX_CTRL_DISABLE_SCRAMBLER_MSB                                                       0
-#define PHY_BB_BBB_TX_CTRL_DISABLE_SCRAMBLER_LSB                                                       0
-#define PHY_BB_BBB_TX_CTRL_DISABLE_SCRAMBLER_MASK                                             0x00000001
-#define PHY_BB_BBB_TX_CTRL_DISABLE_SCRAMBLER_GET(x)                            (((x) & 0x00000001) >> 0)
-#define PHY_BB_BBB_TX_CTRL_DISABLE_SCRAMBLER_SET(x)                            (((x) << 0) & 0x00000001)
-#define PHY_BB_BBB_TX_CTRL_USE_SCRAMBLER_SEED_MSB                                                      1
-#define PHY_BB_BBB_TX_CTRL_USE_SCRAMBLER_SEED_LSB                                                      1
-#define PHY_BB_BBB_TX_CTRL_USE_SCRAMBLER_SEED_MASK                                            0x00000002
-#define PHY_BB_BBB_TX_CTRL_USE_SCRAMBLER_SEED_GET(x)                           (((x) & 0x00000002) >> 1)
-#define PHY_BB_BBB_TX_CTRL_USE_SCRAMBLER_SEED_SET(x)                           (((x) << 1) & 0x00000002)
-#define PHY_BB_BBB_TX_CTRL_TX_DAC_SCALE_CCK_MSB                                                        3
-#define PHY_BB_BBB_TX_CTRL_TX_DAC_SCALE_CCK_LSB                                                        2
-#define PHY_BB_BBB_TX_CTRL_TX_DAC_SCALE_CCK_MASK                                              0x0000000c
-#define PHY_BB_BBB_TX_CTRL_TX_DAC_SCALE_CCK_GET(x)                             (((x) & 0x0000000c) >> 2)
-#define PHY_BB_BBB_TX_CTRL_TX_DAC_SCALE_CCK_SET(x)                             (((x) << 2) & 0x0000000c)
-#define PHY_BB_BBB_TX_CTRL_TXFIR_JAPAN_CCK_MSB                                                         4
-#define PHY_BB_BBB_TX_CTRL_TXFIR_JAPAN_CCK_LSB                                                         4
-#define PHY_BB_BBB_TX_CTRL_TXFIR_JAPAN_CCK_MASK                                               0x00000010
-#define PHY_BB_BBB_TX_CTRL_TXFIR_JAPAN_CCK_GET(x)                              (((x) & 0x00000010) >> 4)
-#define PHY_BB_BBB_TX_CTRL_TXFIR_JAPAN_CCK_SET(x)                              (((x) << 4) & 0x00000010)
-#define PHY_BB_BBB_TX_CTRL_ALLOW_1MBPS_SHORT_MSB                                                       5
-#define PHY_BB_BBB_TX_CTRL_ALLOW_1MBPS_SHORT_LSB                                                       5
-#define PHY_BB_BBB_TX_CTRL_ALLOW_1MBPS_SHORT_MASK                                             0x00000020
-#define PHY_BB_BBB_TX_CTRL_ALLOW_1MBPS_SHORT_GET(x)                            (((x) & 0x00000020) >> 5)
-#define PHY_BB_BBB_TX_CTRL_ALLOW_1MBPS_SHORT_SET(x)                            (((x) << 5) & 0x00000020)
-#define PHY_BB_BBB_TX_CTRL_TX_CCK_DELAY_1_MSB                                                          8
-#define PHY_BB_BBB_TX_CTRL_TX_CCK_DELAY_1_LSB                                                          6
-#define PHY_BB_BBB_TX_CTRL_TX_CCK_DELAY_1_MASK                                                0x000001c0
-#define PHY_BB_BBB_TX_CTRL_TX_CCK_DELAY_1_GET(x)                               (((x) & 0x000001c0) >> 6)
-#define PHY_BB_BBB_TX_CTRL_TX_CCK_DELAY_1_SET(x)                               (((x) << 6) & 0x000001c0)
-#define PHY_BB_BBB_TX_CTRL_TX_CCK_DELAY_2_MSB                                                         11
-#define PHY_BB_BBB_TX_CTRL_TX_CCK_DELAY_2_LSB                                                          9
-#define PHY_BB_BBB_TX_CTRL_TX_CCK_DELAY_2_MASK                                                0x00000e00
-#define PHY_BB_BBB_TX_CTRL_TX_CCK_DELAY_2_GET(x)                               (((x) & 0x00000e00) >> 9)
-#define PHY_BB_BBB_TX_CTRL_TX_CCK_DELAY_2_SET(x)                               (((x) << 9) & 0x00000e00)
-
-/* macros for BB_bbb_sig_detect */
-#define PHY_BB_BBB_SIG_DETECT_ADDRESS                                                         0x0000a208
-#define PHY_BB_BBB_SIG_DETECT_OFFSET                                                          0x0000a208
-#define PHY_BB_BBB_SIG_DETECT_WEAK_SIG_THR_CCK_MSB                                                     5
-#define PHY_BB_BBB_SIG_DETECT_WEAK_SIG_THR_CCK_LSB                                                     0
-#define PHY_BB_BBB_SIG_DETECT_WEAK_SIG_THR_CCK_MASK                                           0x0000003f
-#define PHY_BB_BBB_SIG_DETECT_WEAK_SIG_THR_CCK_GET(x)                          (((x) & 0x0000003f) >> 0)
-#define PHY_BB_BBB_SIG_DETECT_WEAK_SIG_THR_CCK_SET(x)                          (((x) << 0) & 0x0000003f)
-#define PHY_BB_BBB_SIG_DETECT_ANT_SWITCH_TIME_MSB                                                     12
-#define PHY_BB_BBB_SIG_DETECT_ANT_SWITCH_TIME_LSB                                                      6
-#define PHY_BB_BBB_SIG_DETECT_ANT_SWITCH_TIME_MASK                                            0x00001fc0
-#define PHY_BB_BBB_SIG_DETECT_ANT_SWITCH_TIME_GET(x)                           (((x) & 0x00001fc0) >> 6)
-#define PHY_BB_BBB_SIG_DETECT_ANT_SWITCH_TIME_SET(x)                           (((x) << 6) & 0x00001fc0)
-#define PHY_BB_BBB_SIG_DETECT_ENABLE_ANT_FAST_DIV_MSB                                                 13
-#define PHY_BB_BBB_SIG_DETECT_ENABLE_ANT_FAST_DIV_LSB                                                 13
-#define PHY_BB_BBB_SIG_DETECT_ENABLE_ANT_FAST_DIV_MASK                                        0x00002000
-#define PHY_BB_BBB_SIG_DETECT_ENABLE_ANT_FAST_DIV_GET(x)                      (((x) & 0x00002000) >> 13)
-#define PHY_BB_BBB_SIG_DETECT_ENABLE_ANT_FAST_DIV_SET(x)                      (((x) << 13) & 0x00002000)
-#define PHY_BB_BBB_SIG_DETECT_LB_ALPHA_128_CCK_MSB                                                    14
-#define PHY_BB_BBB_SIG_DETECT_LB_ALPHA_128_CCK_LSB                                                    14
-#define PHY_BB_BBB_SIG_DETECT_LB_ALPHA_128_CCK_MASK                                           0x00004000
-#define PHY_BB_BBB_SIG_DETECT_LB_ALPHA_128_CCK_GET(x)                         (((x) & 0x00004000) >> 14)
-#define PHY_BB_BBB_SIG_DETECT_LB_ALPHA_128_CCK_SET(x)                         (((x) << 14) & 0x00004000)
-#define PHY_BB_BBB_SIG_DETECT_LB_RX_ENABLE_CCK_MSB                                                    15
-#define PHY_BB_BBB_SIG_DETECT_LB_RX_ENABLE_CCK_LSB                                                    15
-#define PHY_BB_BBB_SIG_DETECT_LB_RX_ENABLE_CCK_MASK                                           0x00008000
-#define PHY_BB_BBB_SIG_DETECT_LB_RX_ENABLE_CCK_GET(x)                         (((x) & 0x00008000) >> 15)
-#define PHY_BB_BBB_SIG_DETECT_LB_RX_ENABLE_CCK_SET(x)                         (((x) << 15) & 0x00008000)
-#define PHY_BB_BBB_SIG_DETECT_CYC32_COARSE_DC_EST_CCK_MSB                                             16
-#define PHY_BB_BBB_SIG_DETECT_CYC32_COARSE_DC_EST_CCK_LSB                                             16
-#define PHY_BB_BBB_SIG_DETECT_CYC32_COARSE_DC_EST_CCK_MASK                                    0x00010000
-#define PHY_BB_BBB_SIG_DETECT_CYC32_COARSE_DC_EST_CCK_GET(x)                  (((x) & 0x00010000) >> 16)
-#define PHY_BB_BBB_SIG_DETECT_CYC32_COARSE_DC_EST_CCK_SET(x)                  (((x) << 16) & 0x00010000)
-#define PHY_BB_BBB_SIG_DETECT_CYC64_COARSE_DC_EST_CCK_MSB                                             17
-#define PHY_BB_BBB_SIG_DETECT_CYC64_COARSE_DC_EST_CCK_LSB                                             17
-#define PHY_BB_BBB_SIG_DETECT_CYC64_COARSE_DC_EST_CCK_MASK                                    0x00020000
-#define PHY_BB_BBB_SIG_DETECT_CYC64_COARSE_DC_EST_CCK_GET(x)                  (((x) & 0x00020000) >> 17)
-#define PHY_BB_BBB_SIG_DETECT_CYC64_COARSE_DC_EST_CCK_SET(x)                  (((x) << 17) & 0x00020000)
-#define PHY_BB_BBB_SIG_DETECT_ENABLE_COARSE_DC_CCK_MSB                                                18
-#define PHY_BB_BBB_SIG_DETECT_ENABLE_COARSE_DC_CCK_LSB                                                18
-#define PHY_BB_BBB_SIG_DETECT_ENABLE_COARSE_DC_CCK_MASK                                       0x00040000
-#define PHY_BB_BBB_SIG_DETECT_ENABLE_COARSE_DC_CCK_GET(x)                     (((x) & 0x00040000) >> 18)
-#define PHY_BB_BBB_SIG_DETECT_ENABLE_COARSE_DC_CCK_SET(x)                     (((x) << 18) & 0x00040000)
-#define PHY_BB_BBB_SIG_DETECT_CYC256_FINE_DC_EST_CCK_MSB                                              19
-#define PHY_BB_BBB_SIG_DETECT_CYC256_FINE_DC_EST_CCK_LSB                                              19
-#define PHY_BB_BBB_SIG_DETECT_CYC256_FINE_DC_EST_CCK_MASK                                     0x00080000
-#define PHY_BB_BBB_SIG_DETECT_CYC256_FINE_DC_EST_CCK_GET(x)                   (((x) & 0x00080000) >> 19)
-#define PHY_BB_BBB_SIG_DETECT_CYC256_FINE_DC_EST_CCK_SET(x)                   (((x) << 19) & 0x00080000)
-#define PHY_BB_BBB_SIG_DETECT_ENABLE_FINE_DC_CCK_MSB                                                  20
-#define PHY_BB_BBB_SIG_DETECT_ENABLE_FINE_DC_CCK_LSB                                                  20
-#define PHY_BB_BBB_SIG_DETECT_ENABLE_FINE_DC_CCK_MASK                                         0x00100000
-#define PHY_BB_BBB_SIG_DETECT_ENABLE_FINE_DC_CCK_GET(x)                       (((x) & 0x00100000) >> 20)
-#define PHY_BB_BBB_SIG_DETECT_ENABLE_FINE_DC_CCK_SET(x)                       (((x) << 20) & 0x00100000)
-#define PHY_BB_BBB_SIG_DETECT_DELAY_START_SYNC_CCK_MSB                                                21
-#define PHY_BB_BBB_SIG_DETECT_DELAY_START_SYNC_CCK_LSB                                                21
-#define PHY_BB_BBB_SIG_DETECT_DELAY_START_SYNC_CCK_MASK                                       0x00200000
-#define PHY_BB_BBB_SIG_DETECT_DELAY_START_SYNC_CCK_GET(x)                     (((x) & 0x00200000) >> 21)
-#define PHY_BB_BBB_SIG_DETECT_DELAY_START_SYNC_CCK_SET(x)                     (((x) << 21) & 0x00200000)
-#define PHY_BB_BBB_SIG_DETECT_USE_DC_EST_DURING_SRCH_MSB                                              22
-#define PHY_BB_BBB_SIG_DETECT_USE_DC_EST_DURING_SRCH_LSB                                              22
-#define PHY_BB_BBB_SIG_DETECT_USE_DC_EST_DURING_SRCH_MASK                                     0x00400000
-#define PHY_BB_BBB_SIG_DETECT_USE_DC_EST_DURING_SRCH_GET(x)                   (((x) & 0x00400000) >> 22)
-#define PHY_BB_BBB_SIG_DETECT_USE_DC_EST_DURING_SRCH_SET(x)                   (((x) << 22) & 0x00400000)
-#define PHY_BB_BBB_SIG_DETECT_ENABLE_BARKER_TWO_PHASE_MSB                                             31
-#define PHY_BB_BBB_SIG_DETECT_ENABLE_BARKER_TWO_PHASE_LSB                                             31
-#define PHY_BB_BBB_SIG_DETECT_ENABLE_BARKER_TWO_PHASE_MASK                                    0x80000000
-#define PHY_BB_BBB_SIG_DETECT_ENABLE_BARKER_TWO_PHASE_GET(x)                  (((x) & 0x80000000) >> 31)
-#define PHY_BB_BBB_SIG_DETECT_ENABLE_BARKER_TWO_PHASE_SET(x)                  (((x) << 31) & 0x80000000)
-
-/* macros for BB_ext_atten_switch_ctl_b0 */
-#define PHY_BB_EXT_ATTEN_SWITCH_CTL_B0_ADDRESS                                                0x0000a20c
-#define PHY_BB_EXT_ATTEN_SWITCH_CTL_B0_OFFSET                                                 0x0000a20c
-#define PHY_BB_EXT_ATTEN_SWITCH_CTL_B0_XATTEN1_DB_0_MSB                                                5
-#define PHY_BB_EXT_ATTEN_SWITCH_CTL_B0_XATTEN1_DB_0_LSB                                                0
-#define PHY_BB_EXT_ATTEN_SWITCH_CTL_B0_XATTEN1_DB_0_MASK                                      0x0000003f
-#define PHY_BB_EXT_ATTEN_SWITCH_CTL_B0_XATTEN1_DB_0_GET(x)                     (((x) & 0x0000003f) >> 0)
-#define PHY_BB_EXT_ATTEN_SWITCH_CTL_B0_XATTEN1_DB_0_SET(x)                     (((x) << 0) & 0x0000003f)
-#define PHY_BB_EXT_ATTEN_SWITCH_CTL_B0_XATTEN2_DB_0_MSB                                               11
-#define PHY_BB_EXT_ATTEN_SWITCH_CTL_B0_XATTEN2_DB_0_LSB                                                6
-#define PHY_BB_EXT_ATTEN_SWITCH_CTL_B0_XATTEN2_DB_0_MASK                                      0x00000fc0
-#define PHY_BB_EXT_ATTEN_SWITCH_CTL_B0_XATTEN2_DB_0_GET(x)                     (((x) & 0x00000fc0) >> 6)
-#define PHY_BB_EXT_ATTEN_SWITCH_CTL_B0_XATTEN2_DB_0_SET(x)                     (((x) << 6) & 0x00000fc0)
-#define PHY_BB_EXT_ATTEN_SWITCH_CTL_B0_XATTEN1_MARGIN_0_MSB                                           16
-#define PHY_BB_EXT_ATTEN_SWITCH_CTL_B0_XATTEN1_MARGIN_0_LSB                                           12
-#define PHY_BB_EXT_ATTEN_SWITCH_CTL_B0_XATTEN1_MARGIN_0_MASK                                  0x0001f000
-#define PHY_BB_EXT_ATTEN_SWITCH_CTL_B0_XATTEN1_MARGIN_0_GET(x)                (((x) & 0x0001f000) >> 12)
-#define PHY_BB_EXT_ATTEN_SWITCH_CTL_B0_XATTEN1_MARGIN_0_SET(x)                (((x) << 12) & 0x0001f000)
-#define PHY_BB_EXT_ATTEN_SWITCH_CTL_B0_XATTEN2_MARGIN_0_MSB                                           21
-#define PHY_BB_EXT_ATTEN_SWITCH_CTL_B0_XATTEN2_MARGIN_0_LSB                                           17
-#define PHY_BB_EXT_ATTEN_SWITCH_CTL_B0_XATTEN2_MARGIN_0_MASK                                  0x003e0000
-#define PHY_BB_EXT_ATTEN_SWITCH_CTL_B0_XATTEN2_MARGIN_0_GET(x)                (((x) & 0x003e0000) >> 17)
-#define PHY_BB_EXT_ATTEN_SWITCH_CTL_B0_XATTEN2_MARGIN_0_SET(x)                (((x) << 17) & 0x003e0000)
-
-/* macros for BB_bbb_rx_ctrl_1 */
-#define PHY_BB_BBB_RX_CTRL_1_ADDRESS                                                          0x0000a210
-#define PHY_BB_BBB_RX_CTRL_1_OFFSET                                                           0x0000a210
-#define PHY_BB_BBB_RX_CTRL_1_COARSE_TIM_THRESHOLD_2_MSB                                                2
-#define PHY_BB_BBB_RX_CTRL_1_COARSE_TIM_THRESHOLD_2_LSB                                                0
-#define PHY_BB_BBB_RX_CTRL_1_COARSE_TIM_THRESHOLD_2_MASK                                      0x00000007
-#define PHY_BB_BBB_RX_CTRL_1_COARSE_TIM_THRESHOLD_2_GET(x)                     (((x) & 0x00000007) >> 0)
-#define PHY_BB_BBB_RX_CTRL_1_COARSE_TIM_THRESHOLD_2_SET(x)                     (((x) << 0) & 0x00000007)
-#define PHY_BB_BBB_RX_CTRL_1_COARSE_TIM_THRESHOLD_MSB                                                  7
-#define PHY_BB_BBB_RX_CTRL_1_COARSE_TIM_THRESHOLD_LSB                                                  3
-#define PHY_BB_BBB_RX_CTRL_1_COARSE_TIM_THRESHOLD_MASK                                        0x000000f8
-#define PHY_BB_BBB_RX_CTRL_1_COARSE_TIM_THRESHOLD_GET(x)                       (((x) & 0x000000f8) >> 3)
-#define PHY_BB_BBB_RX_CTRL_1_COARSE_TIM_THRESHOLD_SET(x)                       (((x) << 3) & 0x000000f8)
-#define PHY_BB_BBB_RX_CTRL_1_COARSE_TIM_N_SYNC_MSB                                                    10
-#define PHY_BB_BBB_RX_CTRL_1_COARSE_TIM_N_SYNC_LSB                                                     8
-#define PHY_BB_BBB_RX_CTRL_1_COARSE_TIM_N_SYNC_MASK                                           0x00000700
-#define PHY_BB_BBB_RX_CTRL_1_COARSE_TIM_N_SYNC_GET(x)                          (((x) & 0x00000700) >> 8)
-#define PHY_BB_BBB_RX_CTRL_1_COARSE_TIM_N_SYNC_SET(x)                          (((x) << 8) & 0x00000700)
-#define PHY_BB_BBB_RX_CTRL_1_MAX_BAL_LONG_MSB                                                         15
-#define PHY_BB_BBB_RX_CTRL_1_MAX_BAL_LONG_LSB                                                         11
-#define PHY_BB_BBB_RX_CTRL_1_MAX_BAL_LONG_MASK                                                0x0000f800
-#define PHY_BB_BBB_RX_CTRL_1_MAX_BAL_LONG_GET(x)                              (((x) & 0x0000f800) >> 11)
-#define PHY_BB_BBB_RX_CTRL_1_MAX_BAL_LONG_SET(x)                              (((x) << 11) & 0x0000f800)
-#define PHY_BB_BBB_RX_CTRL_1_MAX_BAL_SHORT_MSB                                                        20
-#define PHY_BB_BBB_RX_CTRL_1_MAX_BAL_SHORT_LSB                                                        16
-#define PHY_BB_BBB_RX_CTRL_1_MAX_BAL_SHORT_MASK                                               0x001f0000
-#define PHY_BB_BBB_RX_CTRL_1_MAX_BAL_SHORT_GET(x)                             (((x) & 0x001f0000) >> 16)
-#define PHY_BB_BBB_RX_CTRL_1_MAX_BAL_SHORT_SET(x)                             (((x) << 16) & 0x001f0000)
-#define PHY_BB_BBB_RX_CTRL_1_RECON_LMS_STEP_MSB                                                       23
-#define PHY_BB_BBB_RX_CTRL_1_RECON_LMS_STEP_LSB                                                       21
-#define PHY_BB_BBB_RX_CTRL_1_RECON_LMS_STEP_MASK                                              0x00e00000
-#define PHY_BB_BBB_RX_CTRL_1_RECON_LMS_STEP_GET(x)                            (((x) & 0x00e00000) >> 21)
-#define PHY_BB_BBB_RX_CTRL_1_RECON_LMS_STEP_SET(x)                            (((x) << 21) & 0x00e00000)
-#define PHY_BB_BBB_RX_CTRL_1_SB_CHECK_WIN_MSB                                                         30
-#define PHY_BB_BBB_RX_CTRL_1_SB_CHECK_WIN_LSB                                                         24
-#define PHY_BB_BBB_RX_CTRL_1_SB_CHECK_WIN_MASK                                                0x7f000000
-#define PHY_BB_BBB_RX_CTRL_1_SB_CHECK_WIN_GET(x)                              (((x) & 0x7f000000) >> 24)
-#define PHY_BB_BBB_RX_CTRL_1_SB_CHECK_WIN_SET(x)                              (((x) << 24) & 0x7f000000)
-#define PHY_BB_BBB_RX_CTRL_1_EN_RX_ABORT_CCK_MSB                                                      31
-#define PHY_BB_BBB_RX_CTRL_1_EN_RX_ABORT_CCK_LSB                                                      31
-#define PHY_BB_BBB_RX_CTRL_1_EN_RX_ABORT_CCK_MASK                                             0x80000000
-#define PHY_BB_BBB_RX_CTRL_1_EN_RX_ABORT_CCK_GET(x)                           (((x) & 0x80000000) >> 31)
-#define PHY_BB_BBB_RX_CTRL_1_EN_RX_ABORT_CCK_SET(x)                           (((x) << 31) & 0x80000000)
-
-/* macros for BB_bbb_rx_ctrl_2 */
-#define PHY_BB_BBB_RX_CTRL_2_ADDRESS                                                          0x0000a214
-#define PHY_BB_BBB_RX_CTRL_2_OFFSET                                                           0x0000a214
-#define PHY_BB_BBB_RX_CTRL_2_FREQ_EST_N_AVG_LONG_MSB                                                   5
-#define PHY_BB_BBB_RX_CTRL_2_FREQ_EST_N_AVG_LONG_LSB                                                   0
-#define PHY_BB_BBB_RX_CTRL_2_FREQ_EST_N_AVG_LONG_MASK                                         0x0000003f
-#define PHY_BB_BBB_RX_CTRL_2_FREQ_EST_N_AVG_LONG_GET(x)                        (((x) & 0x0000003f) >> 0)
-#define PHY_BB_BBB_RX_CTRL_2_FREQ_EST_N_AVG_LONG_SET(x)                        (((x) << 0) & 0x0000003f)
-#define PHY_BB_BBB_RX_CTRL_2_CHAN_AVG_LONG_MSB                                                        11
-#define PHY_BB_BBB_RX_CTRL_2_CHAN_AVG_LONG_LSB                                                         6
-#define PHY_BB_BBB_RX_CTRL_2_CHAN_AVG_LONG_MASK                                               0x00000fc0
-#define PHY_BB_BBB_RX_CTRL_2_CHAN_AVG_LONG_GET(x)                              (((x) & 0x00000fc0) >> 6)
-#define PHY_BB_BBB_RX_CTRL_2_CHAN_AVG_LONG_SET(x)                              (((x) << 6) & 0x00000fc0)
-#define PHY_BB_BBB_RX_CTRL_2_COARSE_TIM_THRESHOLD_3_MSB                                               16
-#define PHY_BB_BBB_RX_CTRL_2_COARSE_TIM_THRESHOLD_3_LSB                                               12
-#define PHY_BB_BBB_RX_CTRL_2_COARSE_TIM_THRESHOLD_3_MASK                                      0x0001f000
-#define PHY_BB_BBB_RX_CTRL_2_COARSE_TIM_THRESHOLD_3_GET(x)                    (((x) & 0x0001f000) >> 12)
-#define PHY_BB_BBB_RX_CTRL_2_COARSE_TIM_THRESHOLD_3_SET(x)                    (((x) << 12) & 0x0001f000)
-#define PHY_BB_BBB_RX_CTRL_2_FREQ_TRACK_UPDATE_PERIOD_MSB                                             21
-#define PHY_BB_BBB_RX_CTRL_2_FREQ_TRACK_UPDATE_PERIOD_LSB                                             17
-#define PHY_BB_BBB_RX_CTRL_2_FREQ_TRACK_UPDATE_PERIOD_MASK                                    0x003e0000
-#define PHY_BB_BBB_RX_CTRL_2_FREQ_TRACK_UPDATE_PERIOD_GET(x)                  (((x) & 0x003e0000) >> 17)
-#define PHY_BB_BBB_RX_CTRL_2_FREQ_TRACK_UPDATE_PERIOD_SET(x)                  (((x) << 17) & 0x003e0000)
-#define PHY_BB_BBB_RX_CTRL_2_FREQ_EST_SCALING_PERIOD_MSB                                              25
-#define PHY_BB_BBB_RX_CTRL_2_FREQ_EST_SCALING_PERIOD_LSB                                              22
-#define PHY_BB_BBB_RX_CTRL_2_FREQ_EST_SCALING_PERIOD_MASK                                     0x03c00000
-#define PHY_BB_BBB_RX_CTRL_2_FREQ_EST_SCALING_PERIOD_GET(x)                   (((x) & 0x03c00000) >> 22)
-#define PHY_BB_BBB_RX_CTRL_2_FREQ_EST_SCALING_PERIOD_SET(x)                   (((x) << 22) & 0x03c00000)
-#define PHY_BB_BBB_RX_CTRL_2_LOOP_COEF_DPSK_C2_DATA_MSB                                               31
-#define PHY_BB_BBB_RX_CTRL_2_LOOP_COEF_DPSK_C2_DATA_LSB                                               26
-#define PHY_BB_BBB_RX_CTRL_2_LOOP_COEF_DPSK_C2_DATA_MASK                                      0xfc000000
-#define PHY_BB_BBB_RX_CTRL_2_LOOP_COEF_DPSK_C2_DATA_GET(x)                    (((x) & 0xfc000000) >> 26)
-#define PHY_BB_BBB_RX_CTRL_2_LOOP_COEF_DPSK_C2_DATA_SET(x)                    (((x) << 26) & 0xfc000000)
-
-/* macros for BB_bbb_rx_ctrl_3 */
-#define PHY_BB_BBB_RX_CTRL_3_ADDRESS                                                          0x0000a218
-#define PHY_BB_BBB_RX_CTRL_3_OFFSET                                                           0x0000a218
-#define PHY_BB_BBB_RX_CTRL_3_TIM_ADJUST_FREQ_DPSK_MSB                                                  7
-#define PHY_BB_BBB_RX_CTRL_3_TIM_ADJUST_FREQ_DPSK_LSB                                                  0
-#define PHY_BB_BBB_RX_CTRL_3_TIM_ADJUST_FREQ_DPSK_MASK                                        0x000000ff
-#define PHY_BB_BBB_RX_CTRL_3_TIM_ADJUST_FREQ_DPSK_GET(x)                       (((x) & 0x000000ff) >> 0)
-#define PHY_BB_BBB_RX_CTRL_3_TIM_ADJUST_FREQ_DPSK_SET(x)                       (((x) << 0) & 0x000000ff)
-#define PHY_BB_BBB_RX_CTRL_3_TIM_ADJUST_FREQ_CCK_MSB                                                  15
-#define PHY_BB_BBB_RX_CTRL_3_TIM_ADJUST_FREQ_CCK_LSB                                                   8
-#define PHY_BB_BBB_RX_CTRL_3_TIM_ADJUST_FREQ_CCK_MASK                                         0x0000ff00
-#define PHY_BB_BBB_RX_CTRL_3_TIM_ADJUST_FREQ_CCK_GET(x)                        (((x) & 0x0000ff00) >> 8)
-#define PHY_BB_BBB_RX_CTRL_3_TIM_ADJUST_FREQ_CCK_SET(x)                        (((x) << 8) & 0x0000ff00)
-#define PHY_BB_BBB_RX_CTRL_3_TIMER_N_SFD_MSB                                                          23
-#define PHY_BB_BBB_RX_CTRL_3_TIMER_N_SFD_LSB                                                          16
-#define PHY_BB_BBB_RX_CTRL_3_TIMER_N_SFD_MASK                                                 0x00ff0000
-#define PHY_BB_BBB_RX_CTRL_3_TIMER_N_SFD_GET(x)                               (((x) & 0x00ff0000) >> 16)
-#define PHY_BB_BBB_RX_CTRL_3_TIMER_N_SFD_SET(x)                               (((x) << 16) & 0x00ff0000)
-
-/* macros for BB_bbb_rx_ctrl_4 */
-#define PHY_BB_BBB_RX_CTRL_4_ADDRESS                                                          0x0000a21c
-#define PHY_BB_BBB_RX_CTRL_4_OFFSET                                                           0x0000a21c
-#define PHY_BB_BBB_RX_CTRL_4_TIMER_N_SYNC_MSB                                                          3
-#define PHY_BB_BBB_RX_CTRL_4_TIMER_N_SYNC_LSB                                                          0
-#define PHY_BB_BBB_RX_CTRL_4_TIMER_N_SYNC_MASK                                                0x0000000f
-#define PHY_BB_BBB_RX_CTRL_4_TIMER_N_SYNC_GET(x)                               (((x) & 0x0000000f) >> 0)
-#define PHY_BB_BBB_RX_CTRL_4_TIMER_N_SYNC_SET(x)                               (((x) << 0) & 0x0000000f)
-#define PHY_BB_BBB_RX_CTRL_4_TIM_ADJUST_TIMER_EXP_MSB                                                 15
-#define PHY_BB_BBB_RX_CTRL_4_TIM_ADJUST_TIMER_EXP_LSB                                                  4
-#define PHY_BB_BBB_RX_CTRL_4_TIM_ADJUST_TIMER_EXP_MASK                                        0x0000fff0
-#define PHY_BB_BBB_RX_CTRL_4_TIM_ADJUST_TIMER_EXP_GET(x)                       (((x) & 0x0000fff0) >> 4)
-#define PHY_BB_BBB_RX_CTRL_4_TIM_ADJUST_TIMER_EXP_SET(x)                       (((x) << 4) & 0x0000fff0)
-#define PHY_BB_BBB_RX_CTRL_4_FORCE_UNLOCKED_CLOCKS_MSB                                                16
-#define PHY_BB_BBB_RX_CTRL_4_FORCE_UNLOCKED_CLOCKS_LSB                                                16
-#define PHY_BB_BBB_RX_CTRL_4_FORCE_UNLOCKED_CLOCKS_MASK                                       0x00010000
-#define PHY_BB_BBB_RX_CTRL_4_FORCE_UNLOCKED_CLOCKS_GET(x)                     (((x) & 0x00010000) >> 16)
-#define PHY_BB_BBB_RX_CTRL_4_FORCE_UNLOCKED_CLOCKS_SET(x)                     (((x) << 16) & 0x00010000)
-#define PHY_BB_BBB_RX_CTRL_4_DYNAMIC_PREAM_SEL_MSB                                                    17
-#define PHY_BB_BBB_RX_CTRL_4_DYNAMIC_PREAM_SEL_LSB                                                    17
-#define PHY_BB_BBB_RX_CTRL_4_DYNAMIC_PREAM_SEL_MASK                                           0x00020000
-#define PHY_BB_BBB_RX_CTRL_4_DYNAMIC_PREAM_SEL_GET(x)                         (((x) & 0x00020000) >> 17)
-#define PHY_BB_BBB_RX_CTRL_4_DYNAMIC_PREAM_SEL_SET(x)                         (((x) << 17) & 0x00020000)
-#define PHY_BB_BBB_RX_CTRL_4_SHORT_PREAMBLE_MSB                                                       18
-#define PHY_BB_BBB_RX_CTRL_4_SHORT_PREAMBLE_LSB                                                       18
-#define PHY_BB_BBB_RX_CTRL_4_SHORT_PREAMBLE_MASK                                              0x00040000
-#define PHY_BB_BBB_RX_CTRL_4_SHORT_PREAMBLE_GET(x)                            (((x) & 0x00040000) >> 18)
-#define PHY_BB_BBB_RX_CTRL_4_SHORT_PREAMBLE_SET(x)                            (((x) << 18) & 0x00040000)
-#define PHY_BB_BBB_RX_CTRL_4_FREQ_EST_N_AVG_SHORT_MSB                                                 24
-#define PHY_BB_BBB_RX_CTRL_4_FREQ_EST_N_AVG_SHORT_LSB                                                 19
-#define PHY_BB_BBB_RX_CTRL_4_FREQ_EST_N_AVG_SHORT_MASK                                        0x01f80000
-#define PHY_BB_BBB_RX_CTRL_4_FREQ_EST_N_AVG_SHORT_GET(x)                      (((x) & 0x01f80000) >> 19)
-#define PHY_BB_BBB_RX_CTRL_4_FREQ_EST_N_AVG_SHORT_SET(x)                      (((x) << 19) & 0x01f80000)
-#define PHY_BB_BBB_RX_CTRL_4_CHAN_AVG_SHORT_MSB                                                       30
-#define PHY_BB_BBB_RX_CTRL_4_CHAN_AVG_SHORT_LSB                                                       25
-#define PHY_BB_BBB_RX_CTRL_4_CHAN_AVG_SHORT_MASK                                              0x7e000000
-#define PHY_BB_BBB_RX_CTRL_4_CHAN_AVG_SHORT_GET(x)                            (((x) & 0x7e000000) >> 25)
-#define PHY_BB_BBB_RX_CTRL_4_CHAN_AVG_SHORT_SET(x)                            (((x) << 25) & 0x7e000000)
-
-/* macros for BB_bbb_rx_ctrl_5 */
-#define PHY_BB_BBB_RX_CTRL_5_ADDRESS                                                          0x0000a220
-#define PHY_BB_BBB_RX_CTRL_5_OFFSET                                                           0x0000a220
-#define PHY_BB_BBB_RX_CTRL_5_LOOP_COEF_DPSK_C1_DATA_MSB                                                4
-#define PHY_BB_BBB_RX_CTRL_5_LOOP_COEF_DPSK_C1_DATA_LSB                                                0
-#define PHY_BB_BBB_RX_CTRL_5_LOOP_COEF_DPSK_C1_DATA_MASK                                      0x0000001f
-#define PHY_BB_BBB_RX_CTRL_5_LOOP_COEF_DPSK_C1_DATA_GET(x)                     (((x) & 0x0000001f) >> 0)
-#define PHY_BB_BBB_RX_CTRL_5_LOOP_COEF_DPSK_C1_DATA_SET(x)                     (((x) << 0) & 0x0000001f)
-#define PHY_BB_BBB_RX_CTRL_5_LOOP_COEF_DPSK_C1_HEAD_MSB                                                9
-#define PHY_BB_BBB_RX_CTRL_5_LOOP_COEF_DPSK_C1_HEAD_LSB                                                5
-#define PHY_BB_BBB_RX_CTRL_5_LOOP_COEF_DPSK_C1_HEAD_MASK                                      0x000003e0
-#define PHY_BB_BBB_RX_CTRL_5_LOOP_COEF_DPSK_C1_HEAD_GET(x)                     (((x) & 0x000003e0) >> 5)
-#define PHY_BB_BBB_RX_CTRL_5_LOOP_COEF_DPSK_C1_HEAD_SET(x)                     (((x) << 5) & 0x000003e0)
-#define PHY_BB_BBB_RX_CTRL_5_LOOP_COEF_DPSK_C2_HEAD_MSB                                               15
-#define PHY_BB_BBB_RX_CTRL_5_LOOP_COEF_DPSK_C2_HEAD_LSB                                               10
-#define PHY_BB_BBB_RX_CTRL_5_LOOP_COEF_DPSK_C2_HEAD_MASK                                      0x0000fc00
-#define PHY_BB_BBB_RX_CTRL_5_LOOP_COEF_DPSK_C2_HEAD_GET(x)                    (((x) & 0x0000fc00) >> 10)
-#define PHY_BB_BBB_RX_CTRL_5_LOOP_COEF_DPSK_C2_HEAD_SET(x)                    (((x) << 10) & 0x0000fc00)
-#define PHY_BB_BBB_RX_CTRL_5_LOOP_COEF_CCK_C1_MSB                                                     20
-#define PHY_BB_BBB_RX_CTRL_5_LOOP_COEF_CCK_C1_LSB                                                     16
-#define PHY_BB_BBB_RX_CTRL_5_LOOP_COEF_CCK_C1_MASK                                            0x001f0000
-#define PHY_BB_BBB_RX_CTRL_5_LOOP_COEF_CCK_C1_GET(x)                          (((x) & 0x001f0000) >> 16)
-#define PHY_BB_BBB_RX_CTRL_5_LOOP_COEF_CCK_C1_SET(x)                          (((x) << 16) & 0x001f0000)
-#define PHY_BB_BBB_RX_CTRL_5_LOOP_COEF_CCK_C2_MSB                                                     26
-#define PHY_BB_BBB_RX_CTRL_5_LOOP_COEF_CCK_C2_LSB                                                     21
-#define PHY_BB_BBB_RX_CTRL_5_LOOP_COEF_CCK_C2_MASK                                            0x07e00000
-#define PHY_BB_BBB_RX_CTRL_5_LOOP_COEF_CCK_C2_GET(x)                          (((x) & 0x07e00000) >> 21)
-#define PHY_BB_BBB_RX_CTRL_5_LOOP_COEF_CCK_C2_SET(x)                          (((x) << 21) & 0x07e00000)
-
-/* macros for BB_bbb_rx_ctrl_6 */
-#define PHY_BB_BBB_RX_CTRL_6_ADDRESS                                                          0x0000a224
-#define PHY_BB_BBB_RX_CTRL_6_OFFSET                                                           0x0000a224
-#define PHY_BB_BBB_RX_CTRL_6_SYNC_START_DELAY_MSB                                                      9
-#define PHY_BB_BBB_RX_CTRL_6_SYNC_START_DELAY_LSB                                                      0
-#define PHY_BB_BBB_RX_CTRL_6_SYNC_START_DELAY_MASK                                            0x000003ff
-#define PHY_BB_BBB_RX_CTRL_6_SYNC_START_DELAY_GET(x)                           (((x) & 0x000003ff) >> 0)
-#define PHY_BB_BBB_RX_CTRL_6_SYNC_START_DELAY_SET(x)                           (((x) << 0) & 0x000003ff)
-#define PHY_BB_BBB_RX_CTRL_6_MAP_1S_TO_2S_MSB                                                         10
-#define PHY_BB_BBB_RX_CTRL_6_MAP_1S_TO_2S_LSB                                                         10
-#define PHY_BB_BBB_RX_CTRL_6_MAP_1S_TO_2S_MASK                                                0x00000400
-#define PHY_BB_BBB_RX_CTRL_6_MAP_1S_TO_2S_GET(x)                              (((x) & 0x00000400) >> 10)
-#define PHY_BB_BBB_RX_CTRL_6_MAP_1S_TO_2S_SET(x)                              (((x) << 10) & 0x00000400)
-#define PHY_BB_BBB_RX_CTRL_6_START_IIR_DELAY_MSB                                                      20
-#define PHY_BB_BBB_RX_CTRL_6_START_IIR_DELAY_LSB                                                      11
-#define PHY_BB_BBB_RX_CTRL_6_START_IIR_DELAY_MASK                                             0x001ff800
-#define PHY_BB_BBB_RX_CTRL_6_START_IIR_DELAY_GET(x)                           (((x) & 0x001ff800) >> 11)
-#define PHY_BB_BBB_RX_CTRL_6_START_IIR_DELAY_SET(x)                           (((x) << 11) & 0x001ff800)
-
-/* macros for BB_bbb_dagc_ctrl */
-#define PHY_BB_BBB_DAGC_CTRL_ADDRESS                                                          0x0000a228
-#define PHY_BB_BBB_DAGC_CTRL_OFFSET                                                           0x0000a228
-#define PHY_BB_BBB_DAGC_CTRL_ENABLE_DAGC_CCK_MSB                                                       0
-#define PHY_BB_BBB_DAGC_CTRL_ENABLE_DAGC_CCK_LSB                                                       0
-#define PHY_BB_BBB_DAGC_CTRL_ENABLE_DAGC_CCK_MASK                                             0x00000001
-#define PHY_BB_BBB_DAGC_CTRL_ENABLE_DAGC_CCK_GET(x)                            (((x) & 0x00000001) >> 0)
-#define PHY_BB_BBB_DAGC_CTRL_ENABLE_DAGC_CCK_SET(x)                            (((x) << 0) & 0x00000001)
-#define PHY_BB_BBB_DAGC_CTRL_DAGC_TARGET_PWR_CCK_MSB                                                   8
-#define PHY_BB_BBB_DAGC_CTRL_DAGC_TARGET_PWR_CCK_LSB                                                   1
-#define PHY_BB_BBB_DAGC_CTRL_DAGC_TARGET_PWR_CCK_MASK                                         0x000001fe
-#define PHY_BB_BBB_DAGC_CTRL_DAGC_TARGET_PWR_CCK_GET(x)                        (((x) & 0x000001fe) >> 1)
-#define PHY_BB_BBB_DAGC_CTRL_DAGC_TARGET_PWR_CCK_SET(x)                        (((x) << 1) & 0x000001fe)
-#define PHY_BB_BBB_DAGC_CTRL_ENABLE_BARKER_RSSI_THR_MSB                                                9
-#define PHY_BB_BBB_DAGC_CTRL_ENABLE_BARKER_RSSI_THR_LSB                                                9
-#define PHY_BB_BBB_DAGC_CTRL_ENABLE_BARKER_RSSI_THR_MASK                                      0x00000200
-#define PHY_BB_BBB_DAGC_CTRL_ENABLE_BARKER_RSSI_THR_GET(x)                     (((x) & 0x00000200) >> 9)
-#define PHY_BB_BBB_DAGC_CTRL_ENABLE_BARKER_RSSI_THR_SET(x)                     (((x) << 9) & 0x00000200)
-#define PHY_BB_BBB_DAGC_CTRL_BARKER_RSSI_THR_MSB                                                      16
-#define PHY_BB_BBB_DAGC_CTRL_BARKER_RSSI_THR_LSB                                                      10
-#define PHY_BB_BBB_DAGC_CTRL_BARKER_RSSI_THR_MASK                                             0x0001fc00
-#define PHY_BB_BBB_DAGC_CTRL_BARKER_RSSI_THR_GET(x)                           (((x) & 0x0001fc00) >> 10)
-#define PHY_BB_BBB_DAGC_CTRL_BARKER_RSSI_THR_SET(x)                           (((x) << 10) & 0x0001fc00)
-#define PHY_BB_BBB_DAGC_CTRL_ENABLE_FIRSTEP_SEL_MSB                                                   17
-#define PHY_BB_BBB_DAGC_CTRL_ENABLE_FIRSTEP_SEL_LSB                                                   17
-#define PHY_BB_BBB_DAGC_CTRL_ENABLE_FIRSTEP_SEL_MASK                                          0x00020000
-#define PHY_BB_BBB_DAGC_CTRL_ENABLE_FIRSTEP_SEL_GET(x)                        (((x) & 0x00020000) >> 17)
-#define PHY_BB_BBB_DAGC_CTRL_ENABLE_FIRSTEP_SEL_SET(x)                        (((x) << 17) & 0x00020000)
-#define PHY_BB_BBB_DAGC_CTRL_FIRSTEP_2_MSB                                                            23
-#define PHY_BB_BBB_DAGC_CTRL_FIRSTEP_2_LSB                                                            18
-#define PHY_BB_BBB_DAGC_CTRL_FIRSTEP_2_MASK                                                   0x00fc0000
-#define PHY_BB_BBB_DAGC_CTRL_FIRSTEP_2_GET(x)                                 (((x) & 0x00fc0000) >> 18)
-#define PHY_BB_BBB_DAGC_CTRL_FIRSTEP_2_SET(x)                                 (((x) << 18) & 0x00fc0000)
-#define PHY_BB_BBB_DAGC_CTRL_FIRSTEP_COUNT_LGMAX_MSB                                                  27
-#define PHY_BB_BBB_DAGC_CTRL_FIRSTEP_COUNT_LGMAX_LSB                                                  24
-#define PHY_BB_BBB_DAGC_CTRL_FIRSTEP_COUNT_LGMAX_MASK                                         0x0f000000
-#define PHY_BB_BBB_DAGC_CTRL_FIRSTEP_COUNT_LGMAX_GET(x)                       (((x) & 0x0f000000) >> 24)
-#define PHY_BB_BBB_DAGC_CTRL_FIRSTEP_COUNT_LGMAX_SET(x)                       (((x) << 24) & 0x0f000000)
-
-/* macros for BB_force_clken_cck */
-#define PHY_BB_FORCE_CLKEN_CCK_ADDRESS                                                        0x0000a22c
-#define PHY_BB_FORCE_CLKEN_CCK_OFFSET                                                         0x0000a22c
-#define PHY_BB_FORCE_CLKEN_CCK_FORCE_RX_ENABLE0_MSB                                                    0
-#define PHY_BB_FORCE_CLKEN_CCK_FORCE_RX_ENABLE0_LSB                                                    0
-#define PHY_BB_FORCE_CLKEN_CCK_FORCE_RX_ENABLE0_MASK                                          0x00000001
-#define PHY_BB_FORCE_CLKEN_CCK_FORCE_RX_ENABLE0_GET(x)                         (((x) & 0x00000001) >> 0)
-#define PHY_BB_FORCE_CLKEN_CCK_FORCE_RX_ENABLE0_SET(x)                         (((x) << 0) & 0x00000001)
-#define PHY_BB_FORCE_CLKEN_CCK_FORCE_RX_ENABLE1_MSB                                                    1
-#define PHY_BB_FORCE_CLKEN_CCK_FORCE_RX_ENABLE1_LSB                                                    1
-#define PHY_BB_FORCE_CLKEN_CCK_FORCE_RX_ENABLE1_MASK                                          0x00000002
-#define PHY_BB_FORCE_CLKEN_CCK_FORCE_RX_ENABLE1_GET(x)                         (((x) & 0x00000002) >> 1)
-#define PHY_BB_FORCE_CLKEN_CCK_FORCE_RX_ENABLE1_SET(x)                         (((x) << 1) & 0x00000002)
-#define PHY_BB_FORCE_CLKEN_CCK_FORCE_RX_ENABLE2_MSB                                                    2
-#define PHY_BB_FORCE_CLKEN_CCK_FORCE_RX_ENABLE2_LSB                                                    2
-#define PHY_BB_FORCE_CLKEN_CCK_FORCE_RX_ENABLE2_MASK                                          0x00000004
-#define PHY_BB_FORCE_CLKEN_CCK_FORCE_RX_ENABLE2_GET(x)                         (((x) & 0x00000004) >> 2)
-#define PHY_BB_FORCE_CLKEN_CCK_FORCE_RX_ENABLE2_SET(x)                         (((x) << 2) & 0x00000004)
-#define PHY_BB_FORCE_CLKEN_CCK_FORCE_RX_ENABLE3_MSB                                                    3
-#define PHY_BB_FORCE_CLKEN_CCK_FORCE_RX_ENABLE3_LSB                                                    3
-#define PHY_BB_FORCE_CLKEN_CCK_FORCE_RX_ENABLE3_MASK                                          0x00000008
-#define PHY_BB_FORCE_CLKEN_CCK_FORCE_RX_ENABLE3_GET(x)                         (((x) & 0x00000008) >> 3)
-#define PHY_BB_FORCE_CLKEN_CCK_FORCE_RX_ENABLE3_SET(x)                         (((x) << 3) & 0x00000008)
-#define PHY_BB_FORCE_CLKEN_CCK_FORCE_RX_ALWAYS_MSB                                                     4
-#define PHY_BB_FORCE_CLKEN_CCK_FORCE_RX_ALWAYS_LSB                                                     4
-#define PHY_BB_FORCE_CLKEN_CCK_FORCE_RX_ALWAYS_MASK                                           0x00000010
-#define PHY_BB_FORCE_CLKEN_CCK_FORCE_RX_ALWAYS_GET(x)                          (((x) & 0x00000010) >> 4)
-#define PHY_BB_FORCE_CLKEN_CCK_FORCE_RX_ALWAYS_SET(x)                          (((x) << 4) & 0x00000010)
-#define PHY_BB_FORCE_CLKEN_CCK_FORCE_TXSM_CLKEN_MSB                                                    5
-#define PHY_BB_FORCE_CLKEN_CCK_FORCE_TXSM_CLKEN_LSB                                                    5
-#define PHY_BB_FORCE_CLKEN_CCK_FORCE_TXSM_CLKEN_MASK                                          0x00000020
-#define PHY_BB_FORCE_CLKEN_CCK_FORCE_TXSM_CLKEN_GET(x)                         (((x) & 0x00000020) >> 5)
-#define PHY_BB_FORCE_CLKEN_CCK_FORCE_TXSM_CLKEN_SET(x)                         (((x) << 5) & 0x00000020)
-
-/* macros for BB_rx_clear_delay */
-#define PHY_BB_RX_CLEAR_DELAY_ADDRESS                                                         0x0000a230
-#define PHY_BB_RX_CLEAR_DELAY_OFFSET                                                          0x0000a230
-#define PHY_BB_RX_CLEAR_DELAY_OFDM_XR_RX_CLEAR_DELAY_MSB                                               9
-#define PHY_BB_RX_CLEAR_DELAY_OFDM_XR_RX_CLEAR_DELAY_LSB                                               0
-#define PHY_BB_RX_CLEAR_DELAY_OFDM_XR_RX_CLEAR_DELAY_MASK                                     0x000003ff
-#define PHY_BB_RX_CLEAR_DELAY_OFDM_XR_RX_CLEAR_DELAY_GET(x)                    (((x) & 0x000003ff) >> 0)
-#define PHY_BB_RX_CLEAR_DELAY_OFDM_XR_RX_CLEAR_DELAY_SET(x)                    (((x) << 0) & 0x000003ff)
-
-/* macros for BB_powertx_rate3 */
-#define PHY_BB_POWERTX_RATE3_ADDRESS                                                          0x0000a234
-#define PHY_BB_POWERTX_RATE3_OFFSET                                                           0x0000a234
-#define PHY_BB_POWERTX_RATE3_POWERTX_1L_MSB                                                            5
-#define PHY_BB_POWERTX_RATE3_POWERTX_1L_LSB                                                            0
-#define PHY_BB_POWERTX_RATE3_POWERTX_1L_MASK                                                  0x0000003f
-#define PHY_BB_POWERTX_RATE3_POWERTX_1L_GET(x)                                 (((x) & 0x0000003f) >> 0)
-#define PHY_BB_POWERTX_RATE3_POWERTX_1L_SET(x)                                 (((x) << 0) & 0x0000003f)
-#define PHY_BB_POWERTX_RATE3_POWERTX_2L_MSB                                                           21
-#define PHY_BB_POWERTX_RATE3_POWERTX_2L_LSB                                                           16
-#define PHY_BB_POWERTX_RATE3_POWERTX_2L_MASK                                                  0x003f0000
-#define PHY_BB_POWERTX_RATE3_POWERTX_2L_GET(x)                                (((x) & 0x003f0000) >> 16)
-#define PHY_BB_POWERTX_RATE3_POWERTX_2L_SET(x)                                (((x) << 16) & 0x003f0000)
-#define PHY_BB_POWERTX_RATE3_POWERTX_2S_MSB                                                           29
-#define PHY_BB_POWERTX_RATE3_POWERTX_2S_LSB                                                           24
-#define PHY_BB_POWERTX_RATE3_POWERTX_2S_MASK                                                  0x3f000000
-#define PHY_BB_POWERTX_RATE3_POWERTX_2S_GET(x)                                (((x) & 0x3f000000) >> 24)
-#define PHY_BB_POWERTX_RATE3_POWERTX_2S_SET(x)                                (((x) << 24) & 0x3f000000)
-
-/* macros for BB_powertx_rate4 */
-#define PHY_BB_POWERTX_RATE4_ADDRESS                                                          0x0000a238
-#define PHY_BB_POWERTX_RATE4_OFFSET                                                           0x0000a238
-#define PHY_BB_POWERTX_RATE4_POWERTX_55L_MSB                                                           5
-#define PHY_BB_POWERTX_RATE4_POWERTX_55L_LSB                                                           0
-#define PHY_BB_POWERTX_RATE4_POWERTX_55L_MASK                                                 0x0000003f
-#define PHY_BB_POWERTX_RATE4_POWERTX_55L_GET(x)                                (((x) & 0x0000003f) >> 0)
-#define PHY_BB_POWERTX_RATE4_POWERTX_55L_SET(x)                                (((x) << 0) & 0x0000003f)
-#define PHY_BB_POWERTX_RATE4_POWERTX_55S_MSB                                                          13
-#define PHY_BB_POWERTX_RATE4_POWERTX_55S_LSB                                                           8
-#define PHY_BB_POWERTX_RATE4_POWERTX_55S_MASK                                                 0x00003f00
-#define PHY_BB_POWERTX_RATE4_POWERTX_55S_GET(x)                                (((x) & 0x00003f00) >> 8)
-#define PHY_BB_POWERTX_RATE4_POWERTX_55S_SET(x)                                (((x) << 8) & 0x00003f00)
-#define PHY_BB_POWERTX_RATE4_POWERTX_11L_MSB                                                          21
-#define PHY_BB_POWERTX_RATE4_POWERTX_11L_LSB                                                          16
-#define PHY_BB_POWERTX_RATE4_POWERTX_11L_MASK                                                 0x003f0000
-#define PHY_BB_POWERTX_RATE4_POWERTX_11L_GET(x)                               (((x) & 0x003f0000) >> 16)
-#define PHY_BB_POWERTX_RATE4_POWERTX_11L_SET(x)                               (((x) << 16) & 0x003f0000)
-#define PHY_BB_POWERTX_RATE4_POWERTX_11S_MSB                                                          29
-#define PHY_BB_POWERTX_RATE4_POWERTX_11S_LSB                                                          24
-#define PHY_BB_POWERTX_RATE4_POWERTX_11S_MASK                                                 0x3f000000
-#define PHY_BB_POWERTX_RATE4_POWERTX_11S_GET(x)                               (((x) & 0x3f000000) >> 24)
-#define PHY_BB_POWERTX_RATE4_POWERTX_11S_SET(x)                               (((x) << 24) & 0x3f000000)
-
-/* macros for BB_cck_spur_mit */
-#define PHY_BB_CCK_SPUR_MIT_ADDRESS                                                           0x0000a240
-#define PHY_BB_CCK_SPUR_MIT_OFFSET                                                            0x0000a240
-#define PHY_BB_CCK_SPUR_MIT_USE_CCK_SPUR_MIT_MSB                                                       0
-#define PHY_BB_CCK_SPUR_MIT_USE_CCK_SPUR_MIT_LSB                                                       0
-#define PHY_BB_CCK_SPUR_MIT_USE_CCK_SPUR_MIT_MASK                                             0x00000001
-#define PHY_BB_CCK_SPUR_MIT_USE_CCK_SPUR_MIT_GET(x)                            (((x) & 0x00000001) >> 0)
-#define PHY_BB_CCK_SPUR_MIT_USE_CCK_SPUR_MIT_SET(x)                            (((x) << 0) & 0x00000001)
-#define PHY_BB_CCK_SPUR_MIT_SPUR_RSSI_THR_MSB                                                          8
-#define PHY_BB_CCK_SPUR_MIT_SPUR_RSSI_THR_LSB                                                          1
-#define PHY_BB_CCK_SPUR_MIT_SPUR_RSSI_THR_MASK                                                0x000001fe
-#define PHY_BB_CCK_SPUR_MIT_SPUR_RSSI_THR_GET(x)                               (((x) & 0x000001fe) >> 1)
-#define PHY_BB_CCK_SPUR_MIT_SPUR_RSSI_THR_SET(x)                               (((x) << 1) & 0x000001fe)
-#define PHY_BB_CCK_SPUR_MIT_CCK_SPUR_FREQ_MSB                                                         28
-#define PHY_BB_CCK_SPUR_MIT_CCK_SPUR_FREQ_LSB                                                          9
-#define PHY_BB_CCK_SPUR_MIT_CCK_SPUR_FREQ_MASK                                                0x1ffffe00
-#define PHY_BB_CCK_SPUR_MIT_CCK_SPUR_FREQ_GET(x)                               (((x) & 0x1ffffe00) >> 9)
-#define PHY_BB_CCK_SPUR_MIT_CCK_SPUR_FREQ_SET(x)                               (((x) << 9) & 0x1ffffe00)
-#define PHY_BB_CCK_SPUR_MIT_SPUR_FILTER_TYPE_MSB                                                      30
-#define PHY_BB_CCK_SPUR_MIT_SPUR_FILTER_TYPE_LSB                                                      29
-#define PHY_BB_CCK_SPUR_MIT_SPUR_FILTER_TYPE_MASK                                             0x60000000
-#define PHY_BB_CCK_SPUR_MIT_SPUR_FILTER_TYPE_GET(x)                           (((x) & 0x60000000) >> 29)
-#define PHY_BB_CCK_SPUR_MIT_SPUR_FILTER_TYPE_SET(x)                           (((x) << 29) & 0x60000000)
-
-/* macros for BB_panic_watchdog_status */
-#define PHY_BB_PANIC_WATCHDOG_STATUS_ADDRESS                                                  0x0000a244
-#define PHY_BB_PANIC_WATCHDOG_STATUS_OFFSET                                                   0x0000a244
-#define PHY_BB_PANIC_WATCHDOG_STATUS_PANIC_WATCHDOG_STATUS_1_MSB                                       2
-#define PHY_BB_PANIC_WATCHDOG_STATUS_PANIC_WATCHDOG_STATUS_1_LSB                                       0
-#define PHY_BB_PANIC_WATCHDOG_STATUS_PANIC_WATCHDOG_STATUS_1_MASK                             0x00000007
-#define PHY_BB_PANIC_WATCHDOG_STATUS_PANIC_WATCHDOG_STATUS_1_GET(x)            (((x) & 0x00000007) >> 0)
-#define PHY_BB_PANIC_WATCHDOG_STATUS_PANIC_WATCHDOG_STATUS_1_SET(x)            (((x) << 0) & 0x00000007)
-#define PHY_BB_PANIC_WATCHDOG_STATUS_PANIC_WATCHDOG_DET_HANG_MSB                                       3
-#define PHY_BB_PANIC_WATCHDOG_STATUS_PANIC_WATCHDOG_DET_HANG_LSB                                       3
-#define PHY_BB_PANIC_WATCHDOG_STATUS_PANIC_WATCHDOG_DET_HANG_MASK                             0x00000008
-#define PHY_BB_PANIC_WATCHDOG_STATUS_PANIC_WATCHDOG_DET_HANG_GET(x)            (((x) & 0x00000008) >> 3)
-#define PHY_BB_PANIC_WATCHDOG_STATUS_PANIC_WATCHDOG_DET_HANG_SET(x)            (((x) << 3) & 0x00000008)
-#define PHY_BB_PANIC_WATCHDOG_STATUS_PANIC_WATCHDOG_STATUS_2_MSB                                       7
-#define PHY_BB_PANIC_WATCHDOG_STATUS_PANIC_WATCHDOG_STATUS_2_LSB                                       4
-#define PHY_BB_PANIC_WATCHDOG_STATUS_PANIC_WATCHDOG_STATUS_2_MASK                             0x000000f0
-#define PHY_BB_PANIC_WATCHDOG_STATUS_PANIC_WATCHDOG_STATUS_2_GET(x)            (((x) & 0x000000f0) >> 4)
-#define PHY_BB_PANIC_WATCHDOG_STATUS_PANIC_WATCHDOG_STATUS_2_SET(x)            (((x) << 4) & 0x000000f0)
-#define PHY_BB_PANIC_WATCHDOG_STATUS_PANIC_WATCHDOG_STATUS_3_MSB                                      11
-#define PHY_BB_PANIC_WATCHDOG_STATUS_PANIC_WATCHDOG_STATUS_3_LSB                                       8
-#define PHY_BB_PANIC_WATCHDOG_STATUS_PANIC_WATCHDOG_STATUS_3_MASK                             0x00000f00
-#define PHY_BB_PANIC_WATCHDOG_STATUS_PANIC_WATCHDOG_STATUS_3_GET(x)            (((x) & 0x00000f00) >> 8)
-#define PHY_BB_PANIC_WATCHDOG_STATUS_PANIC_WATCHDOG_STATUS_3_SET(x)            (((x) << 8) & 0x00000f00)
-#define PHY_BB_PANIC_WATCHDOG_STATUS_PANIC_WATCHDOG_STATUS_4_MSB                                      15
-#define PHY_BB_PANIC_WATCHDOG_STATUS_PANIC_WATCHDOG_STATUS_4_LSB                                      12
-#define PHY_BB_PANIC_WATCHDOG_STATUS_PANIC_WATCHDOG_STATUS_4_MASK                             0x0000f000
-#define PHY_BB_PANIC_WATCHDOG_STATUS_PANIC_WATCHDOG_STATUS_4_GET(x)           (((x) & 0x0000f000) >> 12)
-#define PHY_BB_PANIC_WATCHDOG_STATUS_PANIC_WATCHDOG_STATUS_4_SET(x)           (((x) << 12) & 0x0000f000)
-#define PHY_BB_PANIC_WATCHDOG_STATUS_PANIC_WATCHDOG_STATUS_5_MSB                                      19
-#define PHY_BB_PANIC_WATCHDOG_STATUS_PANIC_WATCHDOG_STATUS_5_LSB                                      16
-#define PHY_BB_PANIC_WATCHDOG_STATUS_PANIC_WATCHDOG_STATUS_5_MASK                             0x000f0000
-#define PHY_BB_PANIC_WATCHDOG_STATUS_PANIC_WATCHDOG_STATUS_5_GET(x)           (((x) & 0x000f0000) >> 16)
-#define PHY_BB_PANIC_WATCHDOG_STATUS_PANIC_WATCHDOG_STATUS_5_SET(x)           (((x) << 16) & 0x000f0000)
-#define PHY_BB_PANIC_WATCHDOG_STATUS_PANIC_WATCHDOG_STATUS_6_MSB                                      23
-#define PHY_BB_PANIC_WATCHDOG_STATUS_PANIC_WATCHDOG_STATUS_6_LSB                                      20
-#define PHY_BB_PANIC_WATCHDOG_STATUS_PANIC_WATCHDOG_STATUS_6_MASK                             0x00f00000
-#define PHY_BB_PANIC_WATCHDOG_STATUS_PANIC_WATCHDOG_STATUS_6_GET(x)           (((x) & 0x00f00000) >> 20)
-#define PHY_BB_PANIC_WATCHDOG_STATUS_PANIC_WATCHDOG_STATUS_6_SET(x)           (((x) << 20) & 0x00f00000)
-#define PHY_BB_PANIC_WATCHDOG_STATUS_PANIC_WATCHDOG_STATUS_7_MSB                                      27
-#define PHY_BB_PANIC_WATCHDOG_STATUS_PANIC_WATCHDOG_STATUS_7_LSB                                      24
-#define PHY_BB_PANIC_WATCHDOG_STATUS_PANIC_WATCHDOG_STATUS_7_MASK                             0x0f000000
-#define PHY_BB_PANIC_WATCHDOG_STATUS_PANIC_WATCHDOG_STATUS_7_GET(x)           (((x) & 0x0f000000) >> 24)
-#define PHY_BB_PANIC_WATCHDOG_STATUS_PANIC_WATCHDOG_STATUS_7_SET(x)           (((x) << 24) & 0x0f000000)
-#define PHY_BB_PANIC_WATCHDOG_STATUS_PANIC_WATCHDOG_STATUS_8_MSB                                      31
-#define PHY_BB_PANIC_WATCHDOG_STATUS_PANIC_WATCHDOG_STATUS_8_LSB                                      28
-#define PHY_BB_PANIC_WATCHDOG_STATUS_PANIC_WATCHDOG_STATUS_8_MASK                             0xf0000000
-#define PHY_BB_PANIC_WATCHDOG_STATUS_PANIC_WATCHDOG_STATUS_8_GET(x)           (((x) & 0xf0000000) >> 28)
-#define PHY_BB_PANIC_WATCHDOG_STATUS_PANIC_WATCHDOG_STATUS_8_SET(x)           (((x) << 28) & 0xf0000000)
-
-/* macros for BB_panic_watchdog_ctrl_1 */
-#define PHY_BB_PANIC_WATCHDOG_CTRL_1_ADDRESS                                                  0x0000a248
-#define PHY_BB_PANIC_WATCHDOG_CTRL_1_OFFSET                                                   0x0000a248
-#define PHY_BB_PANIC_WATCHDOG_CTRL_1_ENABLE_PANIC_WATCHDOG_NON_IDLE_MSB                                0
-#define PHY_BB_PANIC_WATCHDOG_CTRL_1_ENABLE_PANIC_WATCHDOG_NON_IDLE_LSB                                0
-#define PHY_BB_PANIC_WATCHDOG_CTRL_1_ENABLE_PANIC_WATCHDOG_NON_IDLE_MASK                      0x00000001
-#define PHY_BB_PANIC_WATCHDOG_CTRL_1_ENABLE_PANIC_WATCHDOG_NON_IDLE_GET(x)     (((x) & 0x00000001) >> 0)
-#define PHY_BB_PANIC_WATCHDOG_CTRL_1_ENABLE_PANIC_WATCHDOG_NON_IDLE_SET(x)     (((x) << 0) & 0x00000001)
-#define PHY_BB_PANIC_WATCHDOG_CTRL_1_ENABLE_PANIC_WATCHDOG_IDLE_MSB                                    1
-#define PHY_BB_PANIC_WATCHDOG_CTRL_1_ENABLE_PANIC_WATCHDOG_IDLE_LSB                                    1
-#define PHY_BB_PANIC_WATCHDOG_CTRL_1_ENABLE_PANIC_WATCHDOG_IDLE_MASK                          0x00000002
-#define PHY_BB_PANIC_WATCHDOG_CTRL_1_ENABLE_PANIC_WATCHDOG_IDLE_GET(x)         (((x) & 0x00000002) >> 1)
-#define PHY_BB_PANIC_WATCHDOG_CTRL_1_ENABLE_PANIC_WATCHDOG_IDLE_SET(x)         (((x) << 1) & 0x00000002)
-#define PHY_BB_PANIC_WATCHDOG_CTRL_1_PANIC_WATCHDOG_NON_IDLE_LIMIT_MSB                                15
-#define PHY_BB_PANIC_WATCHDOG_CTRL_1_PANIC_WATCHDOG_NON_IDLE_LIMIT_LSB                                 2
-#define PHY_BB_PANIC_WATCHDOG_CTRL_1_PANIC_WATCHDOG_NON_IDLE_LIMIT_MASK                       0x0000fffc
-#define PHY_BB_PANIC_WATCHDOG_CTRL_1_PANIC_WATCHDOG_NON_IDLE_LIMIT_GET(x)      (((x) & 0x0000fffc) >> 2)
-#define PHY_BB_PANIC_WATCHDOG_CTRL_1_PANIC_WATCHDOG_NON_IDLE_LIMIT_SET(x)      (((x) << 2) & 0x0000fffc)
-#define PHY_BB_PANIC_WATCHDOG_CTRL_1_PANIC_WATCHDOG_IDLE_LIMIT_MSB                                    31
-#define PHY_BB_PANIC_WATCHDOG_CTRL_1_PANIC_WATCHDOG_IDLE_LIMIT_LSB                                    16
-#define PHY_BB_PANIC_WATCHDOG_CTRL_1_PANIC_WATCHDOG_IDLE_LIMIT_MASK                           0xffff0000
-#define PHY_BB_PANIC_WATCHDOG_CTRL_1_PANIC_WATCHDOG_IDLE_LIMIT_GET(x)         (((x) & 0xffff0000) >> 16)
-#define PHY_BB_PANIC_WATCHDOG_CTRL_1_PANIC_WATCHDOG_IDLE_LIMIT_SET(x)         (((x) << 16) & 0xffff0000)
-
-/* macros for BB_panic_watchdog_ctrl_2 */
-#define PHY_BB_PANIC_WATCHDOG_CTRL_2_ADDRESS                                                  0x0000a24c
-#define PHY_BB_PANIC_WATCHDOG_CTRL_2_OFFSET                                                   0x0000a24c
-#define PHY_BB_PANIC_WATCHDOG_CTRL_2_FORCE_FAST_ADC_CLK_MSB                                            0
-#define PHY_BB_PANIC_WATCHDOG_CTRL_2_FORCE_FAST_ADC_CLK_LSB                                            0
-#define PHY_BB_PANIC_WATCHDOG_CTRL_2_FORCE_FAST_ADC_CLK_MASK                                  0x00000001
-#define PHY_BB_PANIC_WATCHDOG_CTRL_2_FORCE_FAST_ADC_CLK_GET(x)                 (((x) & 0x00000001) >> 0)
-#define PHY_BB_PANIC_WATCHDOG_CTRL_2_FORCE_FAST_ADC_CLK_SET(x)                 (((x) << 0) & 0x00000001)
-#define PHY_BB_PANIC_WATCHDOG_CTRL_2_PANIC_WATCHDOG_RESET_ENA_MSB                                      1
-#define PHY_BB_PANIC_WATCHDOG_CTRL_2_PANIC_WATCHDOG_RESET_ENA_LSB                                      1
-#define PHY_BB_PANIC_WATCHDOG_CTRL_2_PANIC_WATCHDOG_RESET_ENA_MASK                            0x00000002
-#define PHY_BB_PANIC_WATCHDOG_CTRL_2_PANIC_WATCHDOG_RESET_ENA_GET(x)           (((x) & 0x00000002) >> 1)
-#define PHY_BB_PANIC_WATCHDOG_CTRL_2_PANIC_WATCHDOG_RESET_ENA_SET(x)           (((x) << 1) & 0x00000002)
-#define PHY_BB_PANIC_WATCHDOG_CTRL_2_PANIC_WATCHDOG_IRQ_ENA_MSB                                        2
-#define PHY_BB_PANIC_WATCHDOG_CTRL_2_PANIC_WATCHDOG_IRQ_ENA_LSB                                        2
-#define PHY_BB_PANIC_WATCHDOG_CTRL_2_PANIC_WATCHDOG_IRQ_ENA_MASK                              0x00000004
-#define PHY_BB_PANIC_WATCHDOG_CTRL_2_PANIC_WATCHDOG_IRQ_ENA_GET(x)             (((x) & 0x00000004) >> 2)
-#define PHY_BB_PANIC_WATCHDOG_CTRL_2_PANIC_WATCHDOG_IRQ_ENA_SET(x)             (((x) << 2) & 0x00000004)
-
-/* macros for BB_iqcorr_ctrl_cck */
-#define PHY_BB_IQCORR_CTRL_CCK_ADDRESS                                                        0x0000a250
-#define PHY_BB_IQCORR_CTRL_CCK_OFFSET                                                         0x0000a250
-#define PHY_BB_IQCORR_CTRL_CCK_IQCORR_Q_Q_COFF_CCK_MSB                                                 4
-#define PHY_BB_IQCORR_CTRL_CCK_IQCORR_Q_Q_COFF_CCK_LSB                                                 0
-#define PHY_BB_IQCORR_CTRL_CCK_IQCORR_Q_Q_COFF_CCK_MASK                                       0x0000001f
-#define PHY_BB_IQCORR_CTRL_CCK_IQCORR_Q_Q_COFF_CCK_GET(x)                      (((x) & 0x0000001f) >> 0)
-#define PHY_BB_IQCORR_CTRL_CCK_IQCORR_Q_Q_COFF_CCK_SET(x)                      (((x) << 0) & 0x0000001f)
-#define PHY_BB_IQCORR_CTRL_CCK_IQCORR_Q_I_COFF_CCK_MSB                                                10
-#define PHY_BB_IQCORR_CTRL_CCK_IQCORR_Q_I_COFF_CCK_LSB                                                 5
-#define PHY_BB_IQCORR_CTRL_CCK_IQCORR_Q_I_COFF_CCK_MASK                                       0x000007e0
-#define PHY_BB_IQCORR_CTRL_CCK_IQCORR_Q_I_COFF_CCK_GET(x)                      (((x) & 0x000007e0) >> 5)
-#define PHY_BB_IQCORR_CTRL_CCK_IQCORR_Q_I_COFF_CCK_SET(x)                      (((x) << 5) & 0x000007e0)
-#define PHY_BB_IQCORR_CTRL_CCK_ENABLE_IQCORR_CCK_MSB                                                  11
-#define PHY_BB_IQCORR_CTRL_CCK_ENABLE_IQCORR_CCK_LSB                                                  11
-#define PHY_BB_IQCORR_CTRL_CCK_ENABLE_IQCORR_CCK_MASK                                         0x00000800
-#define PHY_BB_IQCORR_CTRL_CCK_ENABLE_IQCORR_CCK_GET(x)                       (((x) & 0x00000800) >> 11)
-#define PHY_BB_IQCORR_CTRL_CCK_ENABLE_IQCORR_CCK_SET(x)                       (((x) << 11) & 0x00000800)
-#define PHY_BB_IQCORR_CTRL_CCK_RXCAL_MEAS_TIME_SEL_MSB                                                13
-#define PHY_BB_IQCORR_CTRL_CCK_RXCAL_MEAS_TIME_SEL_LSB                                                12
-#define PHY_BB_IQCORR_CTRL_CCK_RXCAL_MEAS_TIME_SEL_MASK                                       0x00003000
-#define PHY_BB_IQCORR_CTRL_CCK_RXCAL_MEAS_TIME_SEL_GET(x)                     (((x) & 0x00003000) >> 12)
-#define PHY_BB_IQCORR_CTRL_CCK_RXCAL_MEAS_TIME_SEL_SET(x)                     (((x) << 12) & 0x00003000)
-#define PHY_BB_IQCORR_CTRL_CCK_CLCAL_MEAS_TIME_SEL_MSB                                                15
-#define PHY_BB_IQCORR_CTRL_CCK_CLCAL_MEAS_TIME_SEL_LSB                                                14
-#define PHY_BB_IQCORR_CTRL_CCK_CLCAL_MEAS_TIME_SEL_MASK                                       0x0000c000
-#define PHY_BB_IQCORR_CTRL_CCK_CLCAL_MEAS_TIME_SEL_GET(x)                     (((x) & 0x0000c000) >> 14)
-#define PHY_BB_IQCORR_CTRL_CCK_CLCAL_MEAS_TIME_SEL_SET(x)                     (((x) << 14) & 0x0000c000)
-#define PHY_BB_IQCORR_CTRL_CCK_CF_CLC_INIT_RFGAIN_MSB                                                 20
-#define PHY_BB_IQCORR_CTRL_CCK_CF_CLC_INIT_RFGAIN_LSB                                                 16
-#define PHY_BB_IQCORR_CTRL_CCK_CF_CLC_INIT_RFGAIN_MASK                                        0x001f0000
-#define PHY_BB_IQCORR_CTRL_CCK_CF_CLC_INIT_RFGAIN_GET(x)                      (((x) & 0x001f0000) >> 16)
-#define PHY_BB_IQCORR_CTRL_CCK_CF_CLC_INIT_RFGAIN_SET(x)                      (((x) << 16) & 0x001f0000)
-#define PHY_BB_IQCORR_CTRL_CCK_CF_CLC_PAL_MODE_MSB                                                    21
-#define PHY_BB_IQCORR_CTRL_CCK_CF_CLC_PAL_MODE_LSB                                                    21
-#define PHY_BB_IQCORR_CTRL_CCK_CF_CLC_PAL_MODE_MASK                                           0x00200000
-#define PHY_BB_IQCORR_CTRL_CCK_CF_CLC_PAL_MODE_GET(x)                         (((x) & 0x00200000) >> 21)
-#define PHY_BB_IQCORR_CTRL_CCK_CF_CLC_PAL_MODE_SET(x)                         (((x) << 21) & 0x00200000)
-
-/* macros for BB_bluetooth_cntl */
-#define PHY_BB_BLUETOOTH_CNTL_ADDRESS                                                         0x0000a254
-#define PHY_BB_BLUETOOTH_CNTL_OFFSET                                                          0x0000a254
-#define PHY_BB_BLUETOOTH_CNTL_BT_BREAK_CCK_EN_MSB                                                      0
-#define PHY_BB_BLUETOOTH_CNTL_BT_BREAK_CCK_EN_LSB                                                      0
-#define PHY_BB_BLUETOOTH_CNTL_BT_BREAK_CCK_EN_MASK                                            0x00000001
-#define PHY_BB_BLUETOOTH_CNTL_BT_BREAK_CCK_EN_GET(x)                           (((x) & 0x00000001) >> 0)
-#define PHY_BB_BLUETOOTH_CNTL_BT_BREAK_CCK_EN_SET(x)                           (((x) << 0) & 0x00000001)
-#define PHY_BB_BLUETOOTH_CNTL_BT_ANT_HALT_WLAN_MSB                                                     1
-#define PHY_BB_BLUETOOTH_CNTL_BT_ANT_HALT_WLAN_LSB                                                     1
-#define PHY_BB_BLUETOOTH_CNTL_BT_ANT_HALT_WLAN_MASK                                           0x00000002
-#define PHY_BB_BLUETOOTH_CNTL_BT_ANT_HALT_WLAN_GET(x)                          (((x) & 0x00000002) >> 1)
-#define PHY_BB_BLUETOOTH_CNTL_BT_ANT_HALT_WLAN_SET(x)                          (((x) << 1) & 0x00000002)
-
-/* macros for BB_tpc_1 */
-#define PHY_BB_TPC_1_ADDRESS                                                                  0x0000a258
-#define PHY_BB_TPC_1_OFFSET                                                                   0x0000a258
-#define PHY_BB_TPC_1_FORCE_DAC_GAIN_MSB                                                                0
-#define PHY_BB_TPC_1_FORCE_DAC_GAIN_LSB                                                                0
-#define PHY_BB_TPC_1_FORCE_DAC_GAIN_MASK                                                      0x00000001
-#define PHY_BB_TPC_1_FORCE_DAC_GAIN_GET(x)                                     (((x) & 0x00000001) >> 0)
-#define PHY_BB_TPC_1_FORCE_DAC_GAIN_SET(x)                                     (((x) << 0) & 0x00000001)
-#define PHY_BB_TPC_1_FORCED_DAC_GAIN_MSB                                                               5
-#define PHY_BB_TPC_1_FORCED_DAC_GAIN_LSB                                                               1
-#define PHY_BB_TPC_1_FORCED_DAC_GAIN_MASK                                                     0x0000003e
-#define PHY_BB_TPC_1_FORCED_DAC_GAIN_GET(x)                                    (((x) & 0x0000003e) >> 1)
-#define PHY_BB_TPC_1_FORCED_DAC_GAIN_SET(x)                                    (((x) << 1) & 0x0000003e)
-#define PHY_BB_TPC_1_PD_DC_OFFSET_TARGET_MSB                                                          13
-#define PHY_BB_TPC_1_PD_DC_OFFSET_TARGET_LSB                                                           6
-#define PHY_BB_TPC_1_PD_DC_OFFSET_TARGET_MASK                                                 0x00003fc0
-#define PHY_BB_TPC_1_PD_DC_OFFSET_TARGET_GET(x)                                (((x) & 0x00003fc0) >> 6)
-#define PHY_BB_TPC_1_PD_DC_OFFSET_TARGET_SET(x)                                (((x) << 6) & 0x00003fc0)
-#define PHY_BB_TPC_1_NUM_PD_GAIN_MSB                                                                  15
-#define PHY_BB_TPC_1_NUM_PD_GAIN_LSB                                                                  14
-#define PHY_BB_TPC_1_NUM_PD_GAIN_MASK                                                         0x0000c000
-#define PHY_BB_TPC_1_NUM_PD_GAIN_GET(x)                                       (((x) & 0x0000c000) >> 14)
-#define PHY_BB_TPC_1_NUM_PD_GAIN_SET(x)                                       (((x) << 14) & 0x0000c000)
-#define PHY_BB_TPC_1_PD_GAIN_SETTING1_MSB                                                             17
-#define PHY_BB_TPC_1_PD_GAIN_SETTING1_LSB                                                             16
-#define PHY_BB_TPC_1_PD_GAIN_SETTING1_MASK                                                    0x00030000
-#define PHY_BB_TPC_1_PD_GAIN_SETTING1_GET(x)                                  (((x) & 0x00030000) >> 16)
-#define PHY_BB_TPC_1_PD_GAIN_SETTING1_SET(x)                                  (((x) << 16) & 0x00030000)
-#define PHY_BB_TPC_1_PD_GAIN_SETTING2_MSB                                                             19
-#define PHY_BB_TPC_1_PD_GAIN_SETTING2_LSB                                                             18
-#define PHY_BB_TPC_1_PD_GAIN_SETTING2_MASK                                                    0x000c0000
-#define PHY_BB_TPC_1_PD_GAIN_SETTING2_GET(x)                                  (((x) & 0x000c0000) >> 18)
-#define PHY_BB_TPC_1_PD_GAIN_SETTING2_SET(x)                                  (((x) << 18) & 0x000c0000)
-#define PHY_BB_TPC_1_PD_GAIN_SETTING3_MSB                                                             21
-#define PHY_BB_TPC_1_PD_GAIN_SETTING3_LSB                                                             20
-#define PHY_BB_TPC_1_PD_GAIN_SETTING3_MASK                                                    0x00300000
-#define PHY_BB_TPC_1_PD_GAIN_SETTING3_GET(x)                                  (((x) & 0x00300000) >> 20)
-#define PHY_BB_TPC_1_PD_GAIN_SETTING3_SET(x)                                  (((x) << 20) & 0x00300000)
-#define PHY_BB_TPC_1_ENABLE_PD_CALIBRATE_MSB                                                          22
-#define PHY_BB_TPC_1_ENABLE_PD_CALIBRATE_LSB                                                          22
-#define PHY_BB_TPC_1_ENABLE_PD_CALIBRATE_MASK                                                 0x00400000
-#define PHY_BB_TPC_1_ENABLE_PD_CALIBRATE_GET(x)                               (((x) & 0x00400000) >> 22)
-#define PHY_BB_TPC_1_ENABLE_PD_CALIBRATE_SET(x)                               (((x) << 22) & 0x00400000)
-#define PHY_BB_TPC_1_PD_CALIBRATE_WAIT_MSB                                                            28
-#define PHY_BB_TPC_1_PD_CALIBRATE_WAIT_LSB                                                            23
-#define PHY_BB_TPC_1_PD_CALIBRATE_WAIT_MASK                                                   0x1f800000
-#define PHY_BB_TPC_1_PD_CALIBRATE_WAIT_GET(x)                                 (((x) & 0x1f800000) >> 23)
-#define PHY_BB_TPC_1_PD_CALIBRATE_WAIT_SET(x)                                 (((x) << 23) & 0x1f800000)
-#define PHY_BB_TPC_1_FORCE_PDADC_GAIN_MSB                                                             29
-#define PHY_BB_TPC_1_FORCE_PDADC_GAIN_LSB                                                             29
-#define PHY_BB_TPC_1_FORCE_PDADC_GAIN_MASK                                                    0x20000000
-#define PHY_BB_TPC_1_FORCE_PDADC_GAIN_GET(x)                                  (((x) & 0x20000000) >> 29)
-#define PHY_BB_TPC_1_FORCE_PDADC_GAIN_SET(x)                                  (((x) << 29) & 0x20000000)
-#define PHY_BB_TPC_1_FORCED_PDADC_GAIN_MSB                                                            31
-#define PHY_BB_TPC_1_FORCED_PDADC_GAIN_LSB                                                            30
-#define PHY_BB_TPC_1_FORCED_PDADC_GAIN_MASK                                                   0xc0000000
-#define PHY_BB_TPC_1_FORCED_PDADC_GAIN_GET(x)                                 (((x) & 0xc0000000) >> 30)
-#define PHY_BB_TPC_1_FORCED_PDADC_GAIN_SET(x)                                 (((x) << 30) & 0xc0000000)
-
-/* macros for BB_tpc_2 */
-#define PHY_BB_TPC_2_ADDRESS                                                                  0x0000a25c
-#define PHY_BB_TPC_2_OFFSET                                                                   0x0000a25c
-#define PHY_BB_TPC_2_TX_FRAME_TO_PDADC_ON_MSB                                                          7
-#define PHY_BB_TPC_2_TX_FRAME_TO_PDADC_ON_LSB                                                          0
-#define PHY_BB_TPC_2_TX_FRAME_TO_PDADC_ON_MASK                                                0x000000ff
-#define PHY_BB_TPC_2_TX_FRAME_TO_PDADC_ON_GET(x)                               (((x) & 0x000000ff) >> 0)
-#define PHY_BB_TPC_2_TX_FRAME_TO_PDADC_ON_SET(x)                               (((x) << 0) & 0x000000ff)
-#define PHY_BB_TPC_2_TX_FRAME_TO_PD_ACC_OFDM_MSB                                                      15
-#define PHY_BB_TPC_2_TX_FRAME_TO_PD_ACC_OFDM_LSB                                                       8
-#define PHY_BB_TPC_2_TX_FRAME_TO_PD_ACC_OFDM_MASK                                             0x0000ff00
-#define PHY_BB_TPC_2_TX_FRAME_TO_PD_ACC_OFDM_GET(x)                            (((x) & 0x0000ff00) >> 8)
-#define PHY_BB_TPC_2_TX_FRAME_TO_PD_ACC_OFDM_SET(x)                            (((x) << 8) & 0x0000ff00)
-#define PHY_BB_TPC_2_TX_FRAME_TO_PD_ACC_CCK_MSB                                                       23
-#define PHY_BB_TPC_2_TX_FRAME_TO_PD_ACC_CCK_LSB                                                       16
-#define PHY_BB_TPC_2_TX_FRAME_TO_PD_ACC_CCK_MASK                                              0x00ff0000
-#define PHY_BB_TPC_2_TX_FRAME_TO_PD_ACC_CCK_GET(x)                            (((x) & 0x00ff0000) >> 16)
-#define PHY_BB_TPC_2_TX_FRAME_TO_PD_ACC_CCK_SET(x)                            (((x) << 16) & 0x00ff0000)
-
-/* macros for BB_tpc_3 */
-#define PHY_BB_TPC_3_ADDRESS                                                                  0x0000a260
-#define PHY_BB_TPC_3_OFFSET                                                                   0x0000a260
-#define PHY_BB_TPC_3_TX_END_TO_PDADC_ON_MSB                                                            7
-#define PHY_BB_TPC_3_TX_END_TO_PDADC_ON_LSB                                                            0
-#define PHY_BB_TPC_3_TX_END_TO_PDADC_ON_MASK                                                  0x000000ff
-#define PHY_BB_TPC_3_TX_END_TO_PDADC_ON_GET(x)                                 (((x) & 0x000000ff) >> 0)
-#define PHY_BB_TPC_3_TX_END_TO_PDADC_ON_SET(x)                                 (((x) << 0) & 0x000000ff)
-#define PHY_BB_TPC_3_TX_END_TO_PD_ACC_ON_MSB                                                          15
-#define PHY_BB_TPC_3_TX_END_TO_PD_ACC_ON_LSB                                                           8
-#define PHY_BB_TPC_3_TX_END_TO_PD_ACC_ON_MASK                                                 0x0000ff00
-#define PHY_BB_TPC_3_TX_END_TO_PD_ACC_ON_GET(x)                                (((x) & 0x0000ff00) >> 8)
-#define PHY_BB_TPC_3_TX_END_TO_PD_ACC_ON_SET(x)                                (((x) << 8) & 0x0000ff00)
-#define PHY_BB_TPC_3_PD_ACC_WINDOW_DC_OFF_MSB                                                         18
-#define PHY_BB_TPC_3_PD_ACC_WINDOW_DC_OFF_LSB                                                         16
-#define PHY_BB_TPC_3_PD_ACC_WINDOW_DC_OFF_MASK                                                0x00070000
-#define PHY_BB_TPC_3_PD_ACC_WINDOW_DC_OFF_GET(x)                              (((x) & 0x00070000) >> 16)
-#define PHY_BB_TPC_3_PD_ACC_WINDOW_DC_OFF_SET(x)                              (((x) << 16) & 0x00070000)
-#define PHY_BB_TPC_3_PD_ACC_WINDOW_CAL_MSB                                                            21
-#define PHY_BB_TPC_3_PD_ACC_WINDOW_CAL_LSB                                                            19
-#define PHY_BB_TPC_3_PD_ACC_WINDOW_CAL_MASK                                                   0x00380000
-#define PHY_BB_TPC_3_PD_ACC_WINDOW_CAL_GET(x)                                 (((x) & 0x00380000) >> 19)
-#define PHY_BB_TPC_3_PD_ACC_WINDOW_CAL_SET(x)                                 (((x) << 19) & 0x00380000)
-#define PHY_BB_TPC_3_PD_ACC_WINDOW_OFDM_MSB                                                           24
-#define PHY_BB_TPC_3_PD_ACC_WINDOW_OFDM_LSB                                                           22
-#define PHY_BB_TPC_3_PD_ACC_WINDOW_OFDM_MASK                                                  0x01c00000
-#define PHY_BB_TPC_3_PD_ACC_WINDOW_OFDM_GET(x)                                (((x) & 0x01c00000) >> 22)
-#define PHY_BB_TPC_3_PD_ACC_WINDOW_OFDM_SET(x)                                (((x) << 22) & 0x01c00000)
-#define PHY_BB_TPC_3_PD_ACC_WINDOW_CCK_MSB                                                            27
-#define PHY_BB_TPC_3_PD_ACC_WINDOW_CCK_LSB                                                            25
-#define PHY_BB_TPC_3_PD_ACC_WINDOW_CCK_MASK                                                   0x0e000000
-#define PHY_BB_TPC_3_PD_ACC_WINDOW_CCK_GET(x)                                 (((x) & 0x0e000000) >> 25)
-#define PHY_BB_TPC_3_PD_ACC_WINDOW_CCK_SET(x)                                 (((x) << 25) & 0x0e000000)
-#define PHY_BB_TPC_3_TPC_CLK_GATE_ENABLE_MSB                                                          31
-#define PHY_BB_TPC_3_TPC_CLK_GATE_ENABLE_LSB                                                          31
-#define PHY_BB_TPC_3_TPC_CLK_GATE_ENABLE_MASK                                                 0x80000000
-#define PHY_BB_TPC_3_TPC_CLK_GATE_ENABLE_GET(x)                               (((x) & 0x80000000) >> 31)
-#define PHY_BB_TPC_3_TPC_CLK_GATE_ENABLE_SET(x)                               (((x) << 31) & 0x80000000)
-
-/* macros for BB_tpc_4_b0 */
-#define PHY_BB_TPC_4_B0_ADDRESS                                                               0x0000a264
-#define PHY_BB_TPC_4_B0_OFFSET                                                                0x0000a264
-#define PHY_BB_TPC_4_B0_PD_AVG_VALID_0_MSB                                                             0
-#define PHY_BB_TPC_4_B0_PD_AVG_VALID_0_LSB                                                             0
-#define PHY_BB_TPC_4_B0_PD_AVG_VALID_0_MASK                                                   0x00000001
-#define PHY_BB_TPC_4_B0_PD_AVG_VALID_0_GET(x)                                  (((x) & 0x00000001) >> 0)
-#define PHY_BB_TPC_4_B0_PD_AVG_OUT_0_MSB                                                               8
-#define PHY_BB_TPC_4_B0_PD_AVG_OUT_0_LSB                                                               1
-#define PHY_BB_TPC_4_B0_PD_AVG_OUT_0_MASK                                                     0x000001fe
-#define PHY_BB_TPC_4_B0_PD_AVG_OUT_0_GET(x)                                    (((x) & 0x000001fe) >> 1)
-#define PHY_BB_TPC_4_B0_DAC_GAIN_0_MSB                                                                13
-#define PHY_BB_TPC_4_B0_DAC_GAIN_0_LSB                                                                 9
-#define PHY_BB_TPC_4_B0_DAC_GAIN_0_MASK                                                       0x00003e00
-#define PHY_BB_TPC_4_B0_DAC_GAIN_0_GET(x)                                      (((x) & 0x00003e00) >> 9)
-#define PHY_BB_TPC_4_B0_TX_GAIN_SETTING_0_MSB                                                         19
-#define PHY_BB_TPC_4_B0_TX_GAIN_SETTING_0_LSB                                                         14
-#define PHY_BB_TPC_4_B0_TX_GAIN_SETTING_0_MASK                                                0x000fc000
-#define PHY_BB_TPC_4_B0_TX_GAIN_SETTING_0_GET(x)                              (((x) & 0x000fc000) >> 14)
-#define PHY_BB_TPC_4_B0_RATE_SENT_0_MSB                                                               24
-#define PHY_BB_TPC_4_B0_RATE_SENT_0_LSB                                                               20
-#define PHY_BB_TPC_4_B0_RATE_SENT_0_MASK                                                      0x01f00000
-#define PHY_BB_TPC_4_B0_RATE_SENT_0_GET(x)                                    (((x) & 0x01f00000) >> 20)
-#define PHY_BB_TPC_4_B0_ERROR_EST_UPDATE_POWER_THRESH_MSB                                             30
-#define PHY_BB_TPC_4_B0_ERROR_EST_UPDATE_POWER_THRESH_LSB                                             25
-#define PHY_BB_TPC_4_B0_ERROR_EST_UPDATE_POWER_THRESH_MASK                                    0x7e000000
-#define PHY_BB_TPC_4_B0_ERROR_EST_UPDATE_POWER_THRESH_GET(x)                  (((x) & 0x7e000000) >> 25)
-#define PHY_BB_TPC_4_B0_ERROR_EST_UPDATE_POWER_THRESH_SET(x)                  (((x) << 25) & 0x7e000000)
-
-/* macros for BB_analog_swap */
-#define PHY_BB_ANALOG_SWAP_ADDRESS                                                            0x0000a268
-#define PHY_BB_ANALOG_SWAP_OFFSET                                                             0x0000a268
-#define PHY_BB_ANALOG_SWAP_ANALOG_RX_SWAP_CNTL_MSB                                                     2
-#define PHY_BB_ANALOG_SWAP_ANALOG_RX_SWAP_CNTL_LSB                                                     0
-#define PHY_BB_ANALOG_SWAP_ANALOG_RX_SWAP_CNTL_MASK                                           0x00000007
-#define PHY_BB_ANALOG_SWAP_ANALOG_RX_SWAP_CNTL_GET(x)                          (((x) & 0x00000007) >> 0)
-#define PHY_BB_ANALOG_SWAP_ANALOG_RX_SWAP_CNTL_SET(x)                          (((x) << 0) & 0x00000007)
-#define PHY_BB_ANALOG_SWAP_ANALOG_TX_SWAP_CNTL_MSB                                                     5
-#define PHY_BB_ANALOG_SWAP_ANALOG_TX_SWAP_CNTL_LSB                                                     3
-#define PHY_BB_ANALOG_SWAP_ANALOG_TX_SWAP_CNTL_MASK                                           0x00000038
-#define PHY_BB_ANALOG_SWAP_ANALOG_TX_SWAP_CNTL_GET(x)                          (((x) & 0x00000038) >> 3)
-#define PHY_BB_ANALOG_SWAP_ANALOG_TX_SWAP_CNTL_SET(x)                          (((x) << 3) & 0x00000038)
-#define PHY_BB_ANALOG_SWAP_SWAP_ALT_CHN_MSB                                                            6
-#define PHY_BB_ANALOG_SWAP_SWAP_ALT_CHN_LSB                                                            6
-#define PHY_BB_ANALOG_SWAP_SWAP_ALT_CHN_MASK                                                  0x00000040
-#define PHY_BB_ANALOG_SWAP_SWAP_ALT_CHN_GET(x)                                 (((x) & 0x00000040) >> 6)
-#define PHY_BB_ANALOG_SWAP_SWAP_ALT_CHN_SET(x)                                 (((x) << 6) & 0x00000040)
-#define PHY_BB_ANALOG_SWAP_ANALOG_DC_DAC_POLARITY_MSB                                                  7
-#define PHY_BB_ANALOG_SWAP_ANALOG_DC_DAC_POLARITY_LSB                                                  7
-#define PHY_BB_ANALOG_SWAP_ANALOG_DC_DAC_POLARITY_MASK                                        0x00000080
-#define PHY_BB_ANALOG_SWAP_ANALOG_DC_DAC_POLARITY_GET(x)                       (((x) & 0x00000080) >> 7)
-#define PHY_BB_ANALOG_SWAP_ANALOG_DC_DAC_POLARITY_SET(x)                       (((x) << 7) & 0x00000080)
-#define PHY_BB_ANALOG_SWAP_ANALOG_PKDET_DAC_POLARITY_MSB                                               8
-#define PHY_BB_ANALOG_SWAP_ANALOG_PKDET_DAC_POLARITY_LSB                                               8
-#define PHY_BB_ANALOG_SWAP_ANALOG_PKDET_DAC_POLARITY_MASK                                     0x00000100
-#define PHY_BB_ANALOG_SWAP_ANALOG_PKDET_DAC_POLARITY_GET(x)                    (((x) & 0x00000100) >> 8)
-#define PHY_BB_ANALOG_SWAP_ANALOG_PKDET_DAC_POLARITY_SET(x)                    (((x) << 8) & 0x00000100)
-
-/* macros for BB_tpc_5_b0 */
-#define PHY_BB_TPC_5_B0_ADDRESS                                                               0x0000a26c
-#define PHY_BB_TPC_5_B0_OFFSET                                                                0x0000a26c
-#define PHY_BB_TPC_5_B0_PD_GAIN_OVERLAP_MSB                                                            3
-#define PHY_BB_TPC_5_B0_PD_GAIN_OVERLAP_LSB                                                            0
-#define PHY_BB_TPC_5_B0_PD_GAIN_OVERLAP_MASK                                                  0x0000000f
-#define PHY_BB_TPC_5_B0_PD_GAIN_OVERLAP_GET(x)                                 (((x) & 0x0000000f) >> 0)
-#define PHY_BB_TPC_5_B0_PD_GAIN_OVERLAP_SET(x)                                 (((x) << 0) & 0x0000000f)
-#define PHY_BB_TPC_5_B0_PD_GAIN_BOUNDARY_1_0_MSB                                                       9
-#define PHY_BB_TPC_5_B0_PD_GAIN_BOUNDARY_1_0_LSB                                                       4
-#define PHY_BB_TPC_5_B0_PD_GAIN_BOUNDARY_1_0_MASK                                             0x000003f0
-#define PHY_BB_TPC_5_B0_PD_GAIN_BOUNDARY_1_0_GET(x)                            (((x) & 0x000003f0) >> 4)
-#define PHY_BB_TPC_5_B0_PD_GAIN_BOUNDARY_1_0_SET(x)                            (((x) << 4) & 0x000003f0)
-#define PHY_BB_TPC_5_B0_PD_GAIN_BOUNDARY_2_0_MSB                                                      15
-#define PHY_BB_TPC_5_B0_PD_GAIN_BOUNDARY_2_0_LSB                                                      10
-#define PHY_BB_TPC_5_B0_PD_GAIN_BOUNDARY_2_0_MASK                                             0x0000fc00
-#define PHY_BB_TPC_5_B0_PD_GAIN_BOUNDARY_2_0_GET(x)                           (((x) & 0x0000fc00) >> 10)
-#define PHY_BB_TPC_5_B0_PD_GAIN_BOUNDARY_2_0_SET(x)                           (((x) << 10) & 0x0000fc00)
-#define PHY_BB_TPC_5_B0_PD_GAIN_BOUNDARY_3_0_MSB                                                      21
-#define PHY_BB_TPC_5_B0_PD_GAIN_BOUNDARY_3_0_LSB                                                      16
-#define PHY_BB_TPC_5_B0_PD_GAIN_BOUNDARY_3_0_MASK                                             0x003f0000
-#define PHY_BB_TPC_5_B0_PD_GAIN_BOUNDARY_3_0_GET(x)                           (((x) & 0x003f0000) >> 16)
-#define PHY_BB_TPC_5_B0_PD_GAIN_BOUNDARY_3_0_SET(x)                           (((x) << 16) & 0x003f0000)
-#define PHY_BB_TPC_5_B0_PD_GAIN_BOUNDARY_4_0_MSB                                                      27
-#define PHY_BB_TPC_5_B0_PD_GAIN_BOUNDARY_4_0_LSB                                                      22
-#define PHY_BB_TPC_5_B0_PD_GAIN_BOUNDARY_4_0_MASK                                             0x0fc00000
-#define PHY_BB_TPC_5_B0_PD_GAIN_BOUNDARY_4_0_GET(x)                           (((x) & 0x0fc00000) >> 22)
-#define PHY_BB_TPC_5_B0_PD_GAIN_BOUNDARY_4_0_SET(x)                           (((x) << 22) & 0x0fc00000)
-
-/* macros for BB_tpc_6_b0 */
-#define PHY_BB_TPC_6_B0_ADDRESS                                                               0x0000a270
-#define PHY_BB_TPC_6_B0_OFFSET                                                                0x0000a270
-#define PHY_BB_TPC_6_B0_PD_DAC_SETTING_1_0_MSB                                                         5
-#define PHY_BB_TPC_6_B0_PD_DAC_SETTING_1_0_LSB                                                         0
-#define PHY_BB_TPC_6_B0_PD_DAC_SETTING_1_0_MASK                                               0x0000003f
-#define PHY_BB_TPC_6_B0_PD_DAC_SETTING_1_0_GET(x)                              (((x) & 0x0000003f) >> 0)
-#define PHY_BB_TPC_6_B0_PD_DAC_SETTING_1_0_SET(x)                              (((x) << 0) & 0x0000003f)
-#define PHY_BB_TPC_6_B0_PD_DAC_SETTING_2_0_MSB                                                        11
-#define PHY_BB_TPC_6_B0_PD_DAC_SETTING_2_0_LSB                                                         6
-#define PHY_BB_TPC_6_B0_PD_DAC_SETTING_2_0_MASK                                               0x00000fc0
-#define PHY_BB_TPC_6_B0_PD_DAC_SETTING_2_0_GET(x)                              (((x) & 0x00000fc0) >> 6)
-#define PHY_BB_TPC_6_B0_PD_DAC_SETTING_2_0_SET(x)                              (((x) << 6) & 0x00000fc0)
-#define PHY_BB_TPC_6_B0_PD_DAC_SETTING_3_0_MSB                                                        17
-#define PHY_BB_TPC_6_B0_PD_DAC_SETTING_3_0_LSB                                                        12
-#define PHY_BB_TPC_6_B0_PD_DAC_SETTING_3_0_MASK                                               0x0003f000
-#define PHY_BB_TPC_6_B0_PD_DAC_SETTING_3_0_GET(x)                             (((x) & 0x0003f000) >> 12)
-#define PHY_BB_TPC_6_B0_PD_DAC_SETTING_3_0_SET(x)                             (((x) << 12) & 0x0003f000)
-#define PHY_BB_TPC_6_B0_PD_DAC_SETTING_4_0_MSB                                                        23
-#define PHY_BB_TPC_6_B0_PD_DAC_SETTING_4_0_LSB                                                        18
-#define PHY_BB_TPC_6_B0_PD_DAC_SETTING_4_0_MASK                                               0x00fc0000
-#define PHY_BB_TPC_6_B0_PD_DAC_SETTING_4_0_GET(x)                             (((x) & 0x00fc0000) >> 18)
-#define PHY_BB_TPC_6_B0_PD_DAC_SETTING_4_0_SET(x)                             (((x) << 18) & 0x00fc0000)
-#define PHY_BB_TPC_6_B0_ERROR_EST_MODE_MSB                                                            25
-#define PHY_BB_TPC_6_B0_ERROR_EST_MODE_LSB                                                            24
-#define PHY_BB_TPC_6_B0_ERROR_EST_MODE_MASK                                                   0x03000000
-#define PHY_BB_TPC_6_B0_ERROR_EST_MODE_GET(x)                                 (((x) & 0x03000000) >> 24)
-#define PHY_BB_TPC_6_B0_ERROR_EST_MODE_SET(x)                                 (((x) << 24) & 0x03000000)
-#define PHY_BB_TPC_6_B0_ERROR_EST_FILTER_COEFF_MSB                                                    28
-#define PHY_BB_TPC_6_B0_ERROR_EST_FILTER_COEFF_LSB                                                    26
-#define PHY_BB_TPC_6_B0_ERROR_EST_FILTER_COEFF_MASK                                           0x1c000000
-#define PHY_BB_TPC_6_B0_ERROR_EST_FILTER_COEFF_GET(x)                         (((x) & 0x1c000000) >> 26)
-#define PHY_BB_TPC_6_B0_ERROR_EST_FILTER_COEFF_SET(x)                         (((x) << 26) & 0x1c000000)
-
-/* macros for BB_tpc_7 */
-#define PHY_BB_TPC_7_ADDRESS                                                                  0x0000a274
-#define PHY_BB_TPC_7_OFFSET                                                                   0x0000a274
-#define PHY_BB_TPC_7_TX_GAIN_TABLE_MAX_MSB                                                             5
-#define PHY_BB_TPC_7_TX_GAIN_TABLE_MAX_LSB                                                             0
-#define PHY_BB_TPC_7_TX_GAIN_TABLE_MAX_MASK                                                   0x0000003f
-#define PHY_BB_TPC_7_TX_GAIN_TABLE_MAX_GET(x)                                  (((x) & 0x0000003f) >> 0)
-#define PHY_BB_TPC_7_TX_GAIN_TABLE_MAX_SET(x)                                  (((x) << 0) & 0x0000003f)
-#define PHY_BB_TPC_7_INIT_TX_GAIN_SETTING_MSB                                                         11
-#define PHY_BB_TPC_7_INIT_TX_GAIN_SETTING_LSB                                                          6
-#define PHY_BB_TPC_7_INIT_TX_GAIN_SETTING_MASK                                                0x00000fc0
-#define PHY_BB_TPC_7_INIT_TX_GAIN_SETTING_GET(x)                               (((x) & 0x00000fc0) >> 6)
-#define PHY_BB_TPC_7_INIT_TX_GAIN_SETTING_SET(x)                               (((x) << 6) & 0x00000fc0)
-#define PHY_BB_TPC_7_EN_CL_GAIN_MOD_MSB                                                               12
-#define PHY_BB_TPC_7_EN_CL_GAIN_MOD_LSB                                                               12
-#define PHY_BB_TPC_7_EN_CL_GAIN_MOD_MASK                                                      0x00001000
-#define PHY_BB_TPC_7_EN_CL_GAIN_MOD_GET(x)                                    (((x) & 0x00001000) >> 12)
-#define PHY_BB_TPC_7_EN_CL_GAIN_MOD_SET(x)                                    (((x) << 12) & 0x00001000)
-#define PHY_BB_TPC_7_USE_TX_PD_IN_XPA_MSB                                                             13
-#define PHY_BB_TPC_7_USE_TX_PD_IN_XPA_LSB                                                             13
-#define PHY_BB_TPC_7_USE_TX_PD_IN_XPA_MASK                                                    0x00002000
-#define PHY_BB_TPC_7_USE_TX_PD_IN_XPA_GET(x)                                  (((x) & 0x00002000) >> 13)
-#define PHY_BB_TPC_7_USE_TX_PD_IN_XPA_SET(x)                                  (((x) << 13) & 0x00002000)
-#define PHY_BB_TPC_7_EXTEND_TX_FRAME_FOR_TPC_MSB                                                      14
-#define PHY_BB_TPC_7_EXTEND_TX_FRAME_FOR_TPC_LSB                                                      14
-#define PHY_BB_TPC_7_EXTEND_TX_FRAME_FOR_TPC_MASK                                             0x00004000
-#define PHY_BB_TPC_7_EXTEND_TX_FRAME_FOR_TPC_GET(x)                           (((x) & 0x00004000) >> 14)
-#define PHY_BB_TPC_7_EXTEND_TX_FRAME_FOR_TPC_SET(x)                           (((x) << 14) & 0x00004000)
-#define PHY_BB_TPC_7_USE_INIT_TX_GAIN_SETTING_AFTER_WARM_RESET_MSB                                    15
-#define PHY_BB_TPC_7_USE_INIT_TX_GAIN_SETTING_AFTER_WARM_RESET_LSB                                    15
-#define PHY_BB_TPC_7_USE_INIT_TX_GAIN_SETTING_AFTER_WARM_RESET_MASK                           0x00008000
-#define PHY_BB_TPC_7_USE_INIT_TX_GAIN_SETTING_AFTER_WARM_RESET_GET(x)         (((x) & 0x00008000) >> 15)
-#define PHY_BB_TPC_7_USE_INIT_TX_GAIN_SETTING_AFTER_WARM_RESET_SET(x)         (((x) << 15) & 0x00008000)
-
-/* macros for BB_tpc_8 */
-#define PHY_BB_TPC_8_ADDRESS                                                                  0x0000a278
-#define PHY_BB_TPC_8_OFFSET                                                                   0x0000a278
-#define PHY_BB_TPC_8_DESIRED_SCALE_0_MSB                                                               4
-#define PHY_BB_TPC_8_DESIRED_SCALE_0_LSB                                                               0
-#define PHY_BB_TPC_8_DESIRED_SCALE_0_MASK                                                     0x0000001f
-#define PHY_BB_TPC_8_DESIRED_SCALE_0_GET(x)                                    (((x) & 0x0000001f) >> 0)
-#define PHY_BB_TPC_8_DESIRED_SCALE_0_SET(x)                                    (((x) << 0) & 0x0000001f)
-#define PHY_BB_TPC_8_DESIRED_SCALE_1_MSB                                                               9
-#define PHY_BB_TPC_8_DESIRED_SCALE_1_LSB                                                               5
-#define PHY_BB_TPC_8_DESIRED_SCALE_1_MASK                                                     0x000003e0
-#define PHY_BB_TPC_8_DESIRED_SCALE_1_GET(x)                                    (((x) & 0x000003e0) >> 5)
-#define PHY_BB_TPC_8_DESIRED_SCALE_1_SET(x)                                    (((x) << 5) & 0x000003e0)
-#define PHY_BB_TPC_8_DESIRED_SCALE_2_MSB                                                              14
-#define PHY_BB_TPC_8_DESIRED_SCALE_2_LSB                                                              10
-#define PHY_BB_TPC_8_DESIRED_SCALE_2_MASK                                                     0x00007c00
-#define PHY_BB_TPC_8_DESIRED_SCALE_2_GET(x)                                   (((x) & 0x00007c00) >> 10)
-#define PHY_BB_TPC_8_DESIRED_SCALE_2_SET(x)                                   (((x) << 10) & 0x00007c00)
-#define PHY_BB_TPC_8_DESIRED_SCALE_3_MSB                                                              19
-#define PHY_BB_TPC_8_DESIRED_SCALE_3_LSB                                                              15
-#define PHY_BB_TPC_8_DESIRED_SCALE_3_MASK                                                     0x000f8000
-#define PHY_BB_TPC_8_DESIRED_SCALE_3_GET(x)                                   (((x) & 0x000f8000) >> 15)
-#define PHY_BB_TPC_8_DESIRED_SCALE_3_SET(x)                                   (((x) << 15) & 0x000f8000)
-#define PHY_BB_TPC_8_DESIRED_SCALE_4_MSB                                                              24
-#define PHY_BB_TPC_8_DESIRED_SCALE_4_LSB                                                              20
-#define PHY_BB_TPC_8_DESIRED_SCALE_4_MASK                                                     0x01f00000
-#define PHY_BB_TPC_8_DESIRED_SCALE_4_GET(x)                                   (((x) & 0x01f00000) >> 20)
-#define PHY_BB_TPC_8_DESIRED_SCALE_4_SET(x)                                   (((x) << 20) & 0x01f00000)
-#define PHY_BB_TPC_8_DESIRED_SCALE_5_MSB                                                              29
-#define PHY_BB_TPC_8_DESIRED_SCALE_5_LSB                                                              25
-#define PHY_BB_TPC_8_DESIRED_SCALE_5_MASK                                                     0x3e000000
-#define PHY_BB_TPC_8_DESIRED_SCALE_5_GET(x)                                   (((x) & 0x3e000000) >> 25)
-#define PHY_BB_TPC_8_DESIRED_SCALE_5_SET(x)                                   (((x) << 25) & 0x3e000000)
-
-/* macros for BB_tpc_9 */
-#define PHY_BB_TPC_9_ADDRESS                                                                  0x0000a27c
-#define PHY_BB_TPC_9_OFFSET                                                                   0x0000a27c
-#define PHY_BB_TPC_9_DESIRED_SCALE_6_MSB                                                               4
-#define PHY_BB_TPC_9_DESIRED_SCALE_6_LSB                                                               0
-#define PHY_BB_TPC_9_DESIRED_SCALE_6_MASK                                                     0x0000001f
-#define PHY_BB_TPC_9_DESIRED_SCALE_6_GET(x)                                    (((x) & 0x0000001f) >> 0)
-#define PHY_BB_TPC_9_DESIRED_SCALE_6_SET(x)                                    (((x) << 0) & 0x0000001f)
-#define PHY_BB_TPC_9_DESIRED_SCALE_7_MSB                                                               9
-#define PHY_BB_TPC_9_DESIRED_SCALE_7_LSB                                                               5
-#define PHY_BB_TPC_9_DESIRED_SCALE_7_MASK                                                     0x000003e0
-#define PHY_BB_TPC_9_DESIRED_SCALE_7_GET(x)                                    (((x) & 0x000003e0) >> 5)
-#define PHY_BB_TPC_9_DESIRED_SCALE_7_SET(x)                                    (((x) << 5) & 0x000003e0)
-#define PHY_BB_TPC_9_DESIRED_SCALE_CCK_MSB                                                            14
-#define PHY_BB_TPC_9_DESIRED_SCALE_CCK_LSB                                                            10
-#define PHY_BB_TPC_9_DESIRED_SCALE_CCK_MASK                                                   0x00007c00
-#define PHY_BB_TPC_9_DESIRED_SCALE_CCK_GET(x)                                 (((x) & 0x00007c00) >> 10)
-#define PHY_BB_TPC_9_DESIRED_SCALE_CCK_SET(x)                                 (((x) << 10) & 0x00007c00)
-#define PHY_BB_TPC_9_EN_PD_DC_OFFSET_THR_MSB                                                          20
-#define PHY_BB_TPC_9_EN_PD_DC_OFFSET_THR_LSB                                                          20
-#define PHY_BB_TPC_9_EN_PD_DC_OFFSET_THR_MASK                                                 0x00100000
-#define PHY_BB_TPC_9_EN_PD_DC_OFFSET_THR_GET(x)                               (((x) & 0x00100000) >> 20)
-#define PHY_BB_TPC_9_EN_PD_DC_OFFSET_THR_SET(x)                               (((x) << 20) & 0x00100000)
-#define PHY_BB_TPC_9_PD_DC_OFFSET_THR_MSB                                                             26
-#define PHY_BB_TPC_9_PD_DC_OFFSET_THR_LSB                                                             21
-#define PHY_BB_TPC_9_PD_DC_OFFSET_THR_MASK                                                    0x07e00000
-#define PHY_BB_TPC_9_PD_DC_OFFSET_THR_GET(x)                                  (((x) & 0x07e00000) >> 21)
-#define PHY_BB_TPC_9_PD_DC_OFFSET_THR_SET(x)                                  (((x) << 21) & 0x07e00000)
-#define PHY_BB_TPC_9_WAIT_CALTX_SETTLE_MSB                                                            30
-#define PHY_BB_TPC_9_WAIT_CALTX_SETTLE_LSB                                                            27
-#define PHY_BB_TPC_9_WAIT_CALTX_SETTLE_MASK                                                   0x78000000
-#define PHY_BB_TPC_9_WAIT_CALTX_SETTLE_GET(x)                                 (((x) & 0x78000000) >> 27)
-#define PHY_BB_TPC_9_WAIT_CALTX_SETTLE_SET(x)                                 (((x) << 27) & 0x78000000)
-#define PHY_BB_TPC_9_DISABLE_PDADC_RESIDUAL_DC_REMOVAL_MSB                                            31
-#define PHY_BB_TPC_9_DISABLE_PDADC_RESIDUAL_DC_REMOVAL_LSB                                            31
-#define PHY_BB_TPC_9_DISABLE_PDADC_RESIDUAL_DC_REMOVAL_MASK                                   0x80000000
-#define PHY_BB_TPC_9_DISABLE_PDADC_RESIDUAL_DC_REMOVAL_GET(x)                 (((x) & 0x80000000) >> 31)
-#define PHY_BB_TPC_9_DISABLE_PDADC_RESIDUAL_DC_REMOVAL_SET(x)                 (((x) << 31) & 0x80000000)
-
-/* macros for BB_pdadc_tab_b0 */
-#define PHY_BB_PDADC_TAB_B0_ADDRESS                                                           0x0000a280
-#define PHY_BB_PDADC_TAB_B0_OFFSET                                                            0x0000a280
-#define PHY_BB_PDADC_TAB_B0_TAB_ENTRY_MSB                                                             31
-#define PHY_BB_PDADC_TAB_B0_TAB_ENTRY_LSB                                                              0
-#define PHY_BB_PDADC_TAB_B0_TAB_ENTRY_MASK                                                    0xffffffff
-#define PHY_BB_PDADC_TAB_B0_TAB_ENTRY_SET(x)                                   (((x) << 0) & 0xffffffff)
-
-/* macros for BB_cl_tab_b0 */
-#define PHY_BB_CL_TAB_B0_ADDRESS                                                              0x0000a300
-#define PHY_BB_CL_TAB_B0_OFFSET                                                               0x0000a300
-#define PHY_BB_CL_TAB_B0_CL_GAIN_MOD_MSB                                                               4
-#define PHY_BB_CL_TAB_B0_CL_GAIN_MOD_LSB                                                               0
-#define PHY_BB_CL_TAB_B0_CL_GAIN_MOD_MASK                                                     0x0000001f
-#define PHY_BB_CL_TAB_B0_CL_GAIN_MOD_GET(x)                                    (((x) & 0x0000001f) >> 0)
-#define PHY_BB_CL_TAB_B0_CL_GAIN_MOD_SET(x)                                    (((x) << 0) & 0x0000001f)
-#define PHY_BB_CL_TAB_B0_CARR_LK_DC_ADD_Q_MSB                                                         15
-#define PHY_BB_CL_TAB_B0_CARR_LK_DC_ADD_Q_LSB                                                          5
-#define PHY_BB_CL_TAB_B0_CARR_LK_DC_ADD_Q_MASK                                                0x0000ffe0
-#define PHY_BB_CL_TAB_B0_CARR_LK_DC_ADD_Q_GET(x)                               (((x) & 0x0000ffe0) >> 5)
-#define PHY_BB_CL_TAB_B0_CARR_LK_DC_ADD_Q_SET(x)                               (((x) << 5) & 0x0000ffe0)
-#define PHY_BB_CL_TAB_B0_CARR_LK_DC_ADD_I_MSB                                                         26
-#define PHY_BB_CL_TAB_B0_CARR_LK_DC_ADD_I_LSB                                                         16
-#define PHY_BB_CL_TAB_B0_CARR_LK_DC_ADD_I_MASK                                                0x07ff0000
-#define PHY_BB_CL_TAB_B0_CARR_LK_DC_ADD_I_GET(x)                              (((x) & 0x07ff0000) >> 16)
-#define PHY_BB_CL_TAB_B0_CARR_LK_DC_ADD_I_SET(x)                              (((x) << 16) & 0x07ff0000)
-#define PHY_BB_CL_TAB_B0_BB_GAIN_MSB                                                                  30
-#define PHY_BB_CL_TAB_B0_BB_GAIN_LSB                                                                  27
-#define PHY_BB_CL_TAB_B0_BB_GAIN_MASK                                                         0x78000000
-#define PHY_BB_CL_TAB_B0_BB_GAIN_GET(x)                                       (((x) & 0x78000000) >> 27)
-#define PHY_BB_CL_TAB_B0_BB_GAIN_SET(x)                                       (((x) << 27) & 0x78000000)
-
-/* macros for BB_cl_map_0_b0 */
-#define PHY_BB_CL_MAP_0_B0_ADDRESS                                                            0x0000a340
-#define PHY_BB_CL_MAP_0_B0_OFFSET                                                             0x0000a340
-#define PHY_BB_CL_MAP_0_B0_CL_MAP_0_MSB                                                               31
-#define PHY_BB_CL_MAP_0_B0_CL_MAP_0_LSB                                                                0
-#define PHY_BB_CL_MAP_0_B0_CL_MAP_0_MASK                                                      0xffffffff
-#define PHY_BB_CL_MAP_0_B0_CL_MAP_0_GET(x)                                     (((x) & 0xffffffff) >> 0)
-#define PHY_BB_CL_MAP_0_B0_CL_MAP_0_SET(x)                                     (((x) << 0) & 0xffffffff)
-
-/* macros for BB_cl_map_1_b0 */
-#define PHY_BB_CL_MAP_1_B0_ADDRESS                                                            0x0000a344
-#define PHY_BB_CL_MAP_1_B0_OFFSET                                                             0x0000a344
-#define PHY_BB_CL_MAP_1_B0_CL_MAP_1_MSB                                                               31
-#define PHY_BB_CL_MAP_1_B0_CL_MAP_1_LSB                                                                0
-#define PHY_BB_CL_MAP_1_B0_CL_MAP_1_MASK                                                      0xffffffff
-#define PHY_BB_CL_MAP_1_B0_CL_MAP_1_GET(x)                                     (((x) & 0xffffffff) >> 0)
-#define PHY_BB_CL_MAP_1_B0_CL_MAP_1_SET(x)                                     (((x) << 0) & 0xffffffff)
-
-/* macros for BB_cl_map_2_b0 */
-#define PHY_BB_CL_MAP_2_B0_ADDRESS                                                            0x0000a348
-#define PHY_BB_CL_MAP_2_B0_OFFSET                                                             0x0000a348
-#define PHY_BB_CL_MAP_2_B0_CL_MAP_2_MSB                                                               31
-#define PHY_BB_CL_MAP_2_B0_CL_MAP_2_LSB                                                                0
-#define PHY_BB_CL_MAP_2_B0_CL_MAP_2_MASK                                                      0xffffffff
-#define PHY_BB_CL_MAP_2_B0_CL_MAP_2_GET(x)                                     (((x) & 0xffffffff) >> 0)
-#define PHY_BB_CL_MAP_2_B0_CL_MAP_2_SET(x)                                     (((x) << 0) & 0xffffffff)
-
-/* macros for BB_cl_map_3_b0 */
-#define PHY_BB_CL_MAP_3_B0_ADDRESS                                                            0x0000a34c
-#define PHY_BB_CL_MAP_3_B0_OFFSET                                                             0x0000a34c
-#define PHY_BB_CL_MAP_3_B0_CL_MAP_3_MSB                                                               31
-#define PHY_BB_CL_MAP_3_B0_CL_MAP_3_LSB                                                                0
-#define PHY_BB_CL_MAP_3_B0_CL_MAP_3_MASK                                                      0xffffffff
-#define PHY_BB_CL_MAP_3_B0_CL_MAP_3_GET(x)                                     (((x) & 0xffffffff) >> 0)
-#define PHY_BB_CL_MAP_3_B0_CL_MAP_3_SET(x)                                     (((x) << 0) & 0xffffffff)
-
-/* macros for BB_cl_cal_ctrl */
-#define PHY_BB_CL_CAL_CTRL_ADDRESS                                                            0x0000a358
-#define PHY_BB_CL_CAL_CTRL_OFFSET                                                             0x0000a358
-#define PHY_BB_CL_CAL_CTRL_ENABLE_PARALLEL_CAL_MSB                                                     0
-#define PHY_BB_CL_CAL_CTRL_ENABLE_PARALLEL_CAL_LSB                                                     0
-#define PHY_BB_CL_CAL_CTRL_ENABLE_PARALLEL_CAL_MASK                                           0x00000001
-#define PHY_BB_CL_CAL_CTRL_ENABLE_PARALLEL_CAL_GET(x)                          (((x) & 0x00000001) >> 0)
-#define PHY_BB_CL_CAL_CTRL_ENABLE_PARALLEL_CAL_SET(x)                          (((x) << 0) & 0x00000001)
-#define PHY_BB_CL_CAL_CTRL_ENABLE_CL_CALIBRATE_MSB                                                     1
-#define PHY_BB_CL_CAL_CTRL_ENABLE_CL_CALIBRATE_LSB                                                     1
-#define PHY_BB_CL_CAL_CTRL_ENABLE_CL_CALIBRATE_MASK                                           0x00000002
-#define PHY_BB_CL_CAL_CTRL_ENABLE_CL_CALIBRATE_GET(x)                          (((x) & 0x00000002) >> 1)
-#define PHY_BB_CL_CAL_CTRL_ENABLE_CL_CALIBRATE_SET(x)                          (((x) << 1) & 0x00000002)
-#define PHY_BB_CL_CAL_CTRL_CF_CLC_TEST_POINT_MSB                                                       3
-#define PHY_BB_CL_CAL_CTRL_CF_CLC_TEST_POINT_LSB                                                       2
-#define PHY_BB_CL_CAL_CTRL_CF_CLC_TEST_POINT_MASK                                             0x0000000c
-#define PHY_BB_CL_CAL_CTRL_CF_CLC_TEST_POINT_GET(x)                            (((x) & 0x0000000c) >> 2)
-#define PHY_BB_CL_CAL_CTRL_CF_CLC_TEST_POINT_SET(x)                            (((x) << 2) & 0x0000000c)
-#define PHY_BB_CL_CAL_CTRL_CF_CLC_FORCED_PAGAIN_MSB                                                    7
-#define PHY_BB_CL_CAL_CTRL_CF_CLC_FORCED_PAGAIN_LSB                                                    4
-#define PHY_BB_CL_CAL_CTRL_CF_CLC_FORCED_PAGAIN_MASK                                          0x000000f0
-#define PHY_BB_CL_CAL_CTRL_CF_CLC_FORCED_PAGAIN_GET(x)                         (((x) & 0x000000f0) >> 4)
-#define PHY_BB_CL_CAL_CTRL_CF_CLC_FORCED_PAGAIN_SET(x)                         (((x) << 4) & 0x000000f0)
-#define PHY_BB_CL_CAL_CTRL_CARR_LEAK_MAX_OFFSET_MSB                                                   15
-#define PHY_BB_CL_CAL_CTRL_CARR_LEAK_MAX_OFFSET_LSB                                                    8
-#define PHY_BB_CL_CAL_CTRL_CARR_LEAK_MAX_OFFSET_MASK                                          0x0000ff00
-#define PHY_BB_CL_CAL_CTRL_CARR_LEAK_MAX_OFFSET_GET(x)                         (((x) & 0x0000ff00) >> 8)
-#define PHY_BB_CL_CAL_CTRL_CARR_LEAK_MAX_OFFSET_SET(x)                         (((x) << 8) & 0x0000ff00)
-#define PHY_BB_CL_CAL_CTRL_CF_CLC_INIT_BBGAIN_MSB                                                     21
-#define PHY_BB_CL_CAL_CTRL_CF_CLC_INIT_BBGAIN_LSB                                                     16
-#define PHY_BB_CL_CAL_CTRL_CF_CLC_INIT_BBGAIN_MASK                                            0x003f0000
-#define PHY_BB_CL_CAL_CTRL_CF_CLC_INIT_BBGAIN_GET(x)                          (((x) & 0x003f0000) >> 16)
-#define PHY_BB_CL_CAL_CTRL_CF_CLC_INIT_BBGAIN_SET(x)                          (((x) << 16) & 0x003f0000)
-#define PHY_BB_CL_CAL_CTRL_CF_ADC_BOUND_MSB                                                           29
-#define PHY_BB_CL_CAL_CTRL_CF_ADC_BOUND_LSB                                                           22
-#define PHY_BB_CL_CAL_CTRL_CF_ADC_BOUND_MASK                                                  0x3fc00000
-#define PHY_BB_CL_CAL_CTRL_CF_ADC_BOUND_GET(x)                                (((x) & 0x3fc00000) >> 22)
-#define PHY_BB_CL_CAL_CTRL_CF_ADC_BOUND_SET(x)                                (((x) << 22) & 0x3fc00000)
-#define PHY_BB_CL_CAL_CTRL_USE_DAC_CL_CORRECTION_MSB                                                  30
-#define PHY_BB_CL_CAL_CTRL_USE_DAC_CL_CORRECTION_LSB                                                  30
-#define PHY_BB_CL_CAL_CTRL_USE_DAC_CL_CORRECTION_MASK                                         0x40000000
-#define PHY_BB_CL_CAL_CTRL_USE_DAC_CL_CORRECTION_GET(x)                       (((x) & 0x40000000) >> 30)
-#define PHY_BB_CL_CAL_CTRL_USE_DAC_CL_CORRECTION_SET(x)                       (((x) << 30) & 0x40000000)
-#define PHY_BB_CL_CAL_CTRL_CL_MAP_HW_GEN_MSB                                                          31
-#define PHY_BB_CL_CAL_CTRL_CL_MAP_HW_GEN_LSB                                                          31
-#define PHY_BB_CL_CAL_CTRL_CL_MAP_HW_GEN_MASK                                                 0x80000000
-#define PHY_BB_CL_CAL_CTRL_CL_MAP_HW_GEN_GET(x)                               (((x) & 0x80000000) >> 31)
-#define PHY_BB_CL_CAL_CTRL_CL_MAP_HW_GEN_SET(x)                               (((x) << 31) & 0x80000000)
-
-/* macros for BB_cl_map_pal_0_b0 */
-#define PHY_BB_CL_MAP_PAL_0_B0_ADDRESS                                                        0x0000a35c
-#define PHY_BB_CL_MAP_PAL_0_B0_OFFSET                                                         0x0000a35c
-#define PHY_BB_CL_MAP_PAL_0_B0_CL_MAP_0_MSB                                                           31
-#define PHY_BB_CL_MAP_PAL_0_B0_CL_MAP_0_LSB                                                            0
-#define PHY_BB_CL_MAP_PAL_0_B0_CL_MAP_0_MASK                                                  0xffffffff
-#define PHY_BB_CL_MAP_PAL_0_B0_CL_MAP_0_GET(x)                                 (((x) & 0xffffffff) >> 0)
-#define PHY_BB_CL_MAP_PAL_0_B0_CL_MAP_0_SET(x)                                 (((x) << 0) & 0xffffffff)
-
-/* macros for BB_cl_map_pal_1_b0 */
-#define PHY_BB_CL_MAP_PAL_1_B0_ADDRESS                                                        0x0000a360
-#define PHY_BB_CL_MAP_PAL_1_B0_OFFSET                                                         0x0000a360
-#define PHY_BB_CL_MAP_PAL_1_B0_CL_MAP_1_MSB                                                           31
-#define PHY_BB_CL_MAP_PAL_1_B0_CL_MAP_1_LSB                                                            0
-#define PHY_BB_CL_MAP_PAL_1_B0_CL_MAP_1_MASK                                                  0xffffffff
-#define PHY_BB_CL_MAP_PAL_1_B0_CL_MAP_1_GET(x)                                 (((x) & 0xffffffff) >> 0)
-#define PHY_BB_CL_MAP_PAL_1_B0_CL_MAP_1_SET(x)                                 (((x) << 0) & 0xffffffff)
-
-/* macros for BB_cl_map_pal_2_b0 */
-#define PHY_BB_CL_MAP_PAL_2_B0_ADDRESS                                                        0x0000a364
-#define PHY_BB_CL_MAP_PAL_2_B0_OFFSET                                                         0x0000a364
-#define PHY_BB_CL_MAP_PAL_2_B0_CL_MAP_2_MSB                                                           31
-#define PHY_BB_CL_MAP_PAL_2_B0_CL_MAP_2_LSB                                                            0
-#define PHY_BB_CL_MAP_PAL_2_B0_CL_MAP_2_MASK                                                  0xffffffff
-#define PHY_BB_CL_MAP_PAL_2_B0_CL_MAP_2_GET(x)                                 (((x) & 0xffffffff) >> 0)
-#define PHY_BB_CL_MAP_PAL_2_B0_CL_MAP_2_SET(x)                                 (((x) << 0) & 0xffffffff)
-
-/* macros for BB_cl_map_pal_3_b0 */
-#define PHY_BB_CL_MAP_PAL_3_B0_ADDRESS                                                        0x0000a368
-#define PHY_BB_CL_MAP_PAL_3_B0_OFFSET                                                         0x0000a368
-#define PHY_BB_CL_MAP_PAL_3_B0_CL_MAP_3_MSB                                                           31
-#define PHY_BB_CL_MAP_PAL_3_B0_CL_MAP_3_LSB                                                            0
-#define PHY_BB_CL_MAP_PAL_3_B0_CL_MAP_3_MASK                                                  0xffffffff
-#define PHY_BB_CL_MAP_PAL_3_B0_CL_MAP_3_GET(x)                                 (((x) & 0xffffffff) >> 0)
-#define PHY_BB_CL_MAP_PAL_3_B0_CL_MAP_3_SET(x)                                 (((x) << 0) & 0xffffffff)
-
-/* macros for BB_rifs */
-#define PHY_BB_RIFS_ADDRESS                                                                   0x0000a388
-#define PHY_BB_RIFS_OFFSET                                                                    0x0000a388
-#define PHY_BB_RIFS_DISABLE_FCC_FIX_MSB                                                               25
-#define PHY_BB_RIFS_DISABLE_FCC_FIX_LSB                                                               25
-#define PHY_BB_RIFS_DISABLE_FCC_FIX_MASK                                                      0x02000000
-#define PHY_BB_RIFS_DISABLE_FCC_FIX_GET(x)                                    (((x) & 0x02000000) >> 25)
-#define PHY_BB_RIFS_DISABLE_FCC_FIX_SET(x)                                    (((x) << 25) & 0x02000000)
-#define PHY_BB_RIFS_ENABLE_RESET_TDOMAIN_MSB                                                          26
-#define PHY_BB_RIFS_ENABLE_RESET_TDOMAIN_LSB                                                          26
-#define PHY_BB_RIFS_ENABLE_RESET_TDOMAIN_MASK                                                 0x04000000
-#define PHY_BB_RIFS_ENABLE_RESET_TDOMAIN_GET(x)                               (((x) & 0x04000000) >> 26)
-#define PHY_BB_RIFS_ENABLE_RESET_TDOMAIN_SET(x)                               (((x) << 26) & 0x04000000)
-#define PHY_BB_RIFS_DISABLE_FCC_FIX2_MSB                                                              27
-#define PHY_BB_RIFS_DISABLE_FCC_FIX2_LSB                                                              27
-#define PHY_BB_RIFS_DISABLE_FCC_FIX2_MASK                                                     0x08000000
-#define PHY_BB_RIFS_DISABLE_FCC_FIX2_GET(x)                                   (((x) & 0x08000000) >> 27)
-#define PHY_BB_RIFS_DISABLE_FCC_FIX2_SET(x)                                   (((x) << 27) & 0x08000000)
-#define PHY_BB_RIFS_DISABLE_RIFS_CCK_FIX_MSB                                                          28
-#define PHY_BB_RIFS_DISABLE_RIFS_CCK_FIX_LSB                                                          28
-#define PHY_BB_RIFS_DISABLE_RIFS_CCK_FIX_MASK                                                 0x10000000
-#define PHY_BB_RIFS_DISABLE_RIFS_CCK_FIX_GET(x)                               (((x) & 0x10000000) >> 28)
-#define PHY_BB_RIFS_DISABLE_RIFS_CCK_FIX_SET(x)                               (((x) << 28) & 0x10000000)
-#define PHY_BB_RIFS_DISABLE_ERROR_RESET_FIX_MSB                                                       29
-#define PHY_BB_RIFS_DISABLE_ERROR_RESET_FIX_LSB                                                       29
-#define PHY_BB_RIFS_DISABLE_ERROR_RESET_FIX_MASK                                              0x20000000
-#define PHY_BB_RIFS_DISABLE_ERROR_RESET_FIX_GET(x)                            (((x) & 0x20000000) >> 29)
-#define PHY_BB_RIFS_DISABLE_ERROR_RESET_FIX_SET(x)                            (((x) << 29) & 0x20000000)
-#define PHY_BB_RIFS_RADAR_USE_FDOMAIN_RESET_MSB                                                       30
-#define PHY_BB_RIFS_RADAR_USE_FDOMAIN_RESET_LSB                                                       30
-#define PHY_BB_RIFS_RADAR_USE_FDOMAIN_RESET_MASK                                              0x40000000
-#define PHY_BB_RIFS_RADAR_USE_FDOMAIN_RESET_GET(x)                            (((x) & 0x40000000) >> 30)
-#define PHY_BB_RIFS_RADAR_USE_FDOMAIN_RESET_SET(x)                            (((x) << 30) & 0x40000000)
-
-/* macros for BB_powertx_rate5 */
-#define PHY_BB_POWERTX_RATE5_ADDRESS                                                          0x0000a38c
-#define PHY_BB_POWERTX_RATE5_OFFSET                                                           0x0000a38c
-#define PHY_BB_POWERTX_RATE5_POWERTXHT20_0_MSB                                                         5
-#define PHY_BB_POWERTX_RATE5_POWERTXHT20_0_LSB                                                         0
-#define PHY_BB_POWERTX_RATE5_POWERTXHT20_0_MASK                                               0x0000003f
-#define PHY_BB_POWERTX_RATE5_POWERTXHT20_0_GET(x)                              (((x) & 0x0000003f) >> 0)
-#define PHY_BB_POWERTX_RATE5_POWERTXHT20_0_SET(x)                              (((x) << 0) & 0x0000003f)
-#define PHY_BB_POWERTX_RATE5_POWERTXHT20_1_MSB                                                        13
-#define PHY_BB_POWERTX_RATE5_POWERTXHT20_1_LSB                                                         8
-#define PHY_BB_POWERTX_RATE5_POWERTXHT20_1_MASK                                               0x00003f00
-#define PHY_BB_POWERTX_RATE5_POWERTXHT20_1_GET(x)                              (((x) & 0x00003f00) >> 8)
-#define PHY_BB_POWERTX_RATE5_POWERTXHT20_1_SET(x)                              (((x) << 8) & 0x00003f00)
-#define PHY_BB_POWERTX_RATE5_POWERTXHT20_2_MSB                                                        21
-#define PHY_BB_POWERTX_RATE5_POWERTXHT20_2_LSB                                                        16
-#define PHY_BB_POWERTX_RATE5_POWERTXHT20_2_MASK                                               0x003f0000
-#define PHY_BB_POWERTX_RATE5_POWERTXHT20_2_GET(x)                             (((x) & 0x003f0000) >> 16)
-#define PHY_BB_POWERTX_RATE5_POWERTXHT20_2_SET(x)                             (((x) << 16) & 0x003f0000)
-#define PHY_BB_POWERTX_RATE5_POWERTXHT20_3_MSB                                                        29
-#define PHY_BB_POWERTX_RATE5_POWERTXHT20_3_LSB                                                        24
-#define PHY_BB_POWERTX_RATE5_POWERTXHT20_3_MASK                                               0x3f000000
-#define PHY_BB_POWERTX_RATE5_POWERTXHT20_3_GET(x)                             (((x) & 0x3f000000) >> 24)
-#define PHY_BB_POWERTX_RATE5_POWERTXHT20_3_SET(x)                             (((x) << 24) & 0x3f000000)
-
-/* macros for BB_powertx_rate6 */
-#define PHY_BB_POWERTX_RATE6_ADDRESS                                                          0x0000a390
-#define PHY_BB_POWERTX_RATE6_OFFSET                                                           0x0000a390
-#define PHY_BB_POWERTX_RATE6_POWERTXHT20_4_MSB                                                         5
-#define PHY_BB_POWERTX_RATE6_POWERTXHT20_4_LSB                                                         0
-#define PHY_BB_POWERTX_RATE6_POWERTXHT20_4_MASK                                               0x0000003f
-#define PHY_BB_POWERTX_RATE6_POWERTXHT20_4_GET(x)                              (((x) & 0x0000003f) >> 0)
-#define PHY_BB_POWERTX_RATE6_POWERTXHT20_4_SET(x)                              (((x) << 0) & 0x0000003f)
-#define PHY_BB_POWERTX_RATE6_POWERTXHT20_5_MSB                                                        13
-#define PHY_BB_POWERTX_RATE6_POWERTXHT20_5_LSB                                                         8
-#define PHY_BB_POWERTX_RATE6_POWERTXHT20_5_MASK                                               0x00003f00
-#define PHY_BB_POWERTX_RATE6_POWERTXHT20_5_GET(x)                              (((x) & 0x00003f00) >> 8)
-#define PHY_BB_POWERTX_RATE6_POWERTXHT20_5_SET(x)                              (((x) << 8) & 0x00003f00)
-#define PHY_BB_POWERTX_RATE6_POWERTXHT20_6_MSB                                                        21
-#define PHY_BB_POWERTX_RATE6_POWERTXHT20_6_LSB                                                        16
-#define PHY_BB_POWERTX_RATE6_POWERTXHT20_6_MASK                                               0x003f0000
-#define PHY_BB_POWERTX_RATE6_POWERTXHT20_6_GET(x)                             (((x) & 0x003f0000) >> 16)
-#define PHY_BB_POWERTX_RATE6_POWERTXHT20_6_SET(x)                             (((x) << 16) & 0x003f0000)
-#define PHY_BB_POWERTX_RATE6_POWERTXHT20_7_MSB                                                        29
-#define PHY_BB_POWERTX_RATE6_POWERTXHT20_7_LSB                                                        24
-#define PHY_BB_POWERTX_RATE6_POWERTXHT20_7_MASK                                               0x3f000000
-#define PHY_BB_POWERTX_RATE6_POWERTXHT20_7_GET(x)                             (((x) & 0x3f000000) >> 24)
-#define PHY_BB_POWERTX_RATE6_POWERTXHT20_7_SET(x)                             (((x) << 24) & 0x3f000000)
-
-/* macros for BB_tpc_10 */
-#define PHY_BB_TPC_10_ADDRESS                                                                 0x0000a394
-#define PHY_BB_TPC_10_OFFSET                                                                  0x0000a394
-#define PHY_BB_TPC_10_DESIRED_SCALE_HT20_0_MSB                                                         4
-#define PHY_BB_TPC_10_DESIRED_SCALE_HT20_0_LSB                                                         0
-#define PHY_BB_TPC_10_DESIRED_SCALE_HT20_0_MASK                                               0x0000001f
-#define PHY_BB_TPC_10_DESIRED_SCALE_HT20_0_GET(x)                              (((x) & 0x0000001f) >> 0)
-#define PHY_BB_TPC_10_DESIRED_SCALE_HT20_0_SET(x)                              (((x) << 0) & 0x0000001f)
-#define PHY_BB_TPC_10_DESIRED_SCALE_HT20_1_MSB                                                         9
-#define PHY_BB_TPC_10_DESIRED_SCALE_HT20_1_LSB                                                         5
-#define PHY_BB_TPC_10_DESIRED_SCALE_HT20_1_MASK                                               0x000003e0
-#define PHY_BB_TPC_10_DESIRED_SCALE_HT20_1_GET(x)                              (((x) & 0x000003e0) >> 5)
-#define PHY_BB_TPC_10_DESIRED_SCALE_HT20_1_SET(x)                              (((x) << 5) & 0x000003e0)
-#define PHY_BB_TPC_10_DESIRED_SCALE_HT20_2_MSB                                                        14
-#define PHY_BB_TPC_10_DESIRED_SCALE_HT20_2_LSB                                                        10
-#define PHY_BB_TPC_10_DESIRED_SCALE_HT20_2_MASK                                               0x00007c00
-#define PHY_BB_TPC_10_DESIRED_SCALE_HT20_2_GET(x)                             (((x) & 0x00007c00) >> 10)
-#define PHY_BB_TPC_10_DESIRED_SCALE_HT20_2_SET(x)                             (((x) << 10) & 0x00007c00)
-#define PHY_BB_TPC_10_DESIRED_SCALE_HT20_3_MSB                                                        19
-#define PHY_BB_TPC_10_DESIRED_SCALE_HT20_3_LSB                                                        15
-#define PHY_BB_TPC_10_DESIRED_SCALE_HT20_3_MASK                                               0x000f8000
-#define PHY_BB_TPC_10_DESIRED_SCALE_HT20_3_GET(x)                             (((x) & 0x000f8000) >> 15)
-#define PHY_BB_TPC_10_DESIRED_SCALE_HT20_3_SET(x)                             (((x) << 15) & 0x000f8000)
-#define PHY_BB_TPC_10_DESIRED_SCALE_HT20_4_MSB                                                        24
-#define PHY_BB_TPC_10_DESIRED_SCALE_HT20_4_LSB                                                        20
-#define PHY_BB_TPC_10_DESIRED_SCALE_HT20_4_MASK                                               0x01f00000
-#define PHY_BB_TPC_10_DESIRED_SCALE_HT20_4_GET(x)                             (((x) & 0x01f00000) >> 20)
-#define PHY_BB_TPC_10_DESIRED_SCALE_HT20_4_SET(x)                             (((x) << 20) & 0x01f00000)
-#define PHY_BB_TPC_10_DESIRED_SCALE_HT20_5_MSB                                                        29
-#define PHY_BB_TPC_10_DESIRED_SCALE_HT20_5_LSB                                                        25
-#define PHY_BB_TPC_10_DESIRED_SCALE_HT20_5_MASK                                               0x3e000000
-#define PHY_BB_TPC_10_DESIRED_SCALE_HT20_5_GET(x)                             (((x) & 0x3e000000) >> 25)
-#define PHY_BB_TPC_10_DESIRED_SCALE_HT20_5_SET(x)                             (((x) << 25) & 0x3e000000)
-
-/* macros for BB_tpc_11_b0 */
-#define PHY_BB_TPC_11_B0_ADDRESS                                                              0x0000a398
-#define PHY_BB_TPC_11_B0_OFFSET                                                               0x0000a398
-#define PHY_BB_TPC_11_B0_DESIRED_SCALE_HT20_6_MSB                                                      4
-#define PHY_BB_TPC_11_B0_DESIRED_SCALE_HT20_6_LSB                                                      0
-#define PHY_BB_TPC_11_B0_DESIRED_SCALE_HT20_6_MASK                                            0x0000001f
-#define PHY_BB_TPC_11_B0_DESIRED_SCALE_HT20_6_GET(x)                           (((x) & 0x0000001f) >> 0)
-#define PHY_BB_TPC_11_B0_DESIRED_SCALE_HT20_6_SET(x)                           (((x) << 0) & 0x0000001f)
-#define PHY_BB_TPC_11_B0_DESIRED_SCALE_HT20_7_MSB                                                      9
-#define PHY_BB_TPC_11_B0_DESIRED_SCALE_HT20_7_LSB                                                      5
-#define PHY_BB_TPC_11_B0_DESIRED_SCALE_HT20_7_MASK                                            0x000003e0
-#define PHY_BB_TPC_11_B0_DESIRED_SCALE_HT20_7_GET(x)                           (((x) & 0x000003e0) >> 5)
-#define PHY_BB_TPC_11_B0_DESIRED_SCALE_HT20_7_SET(x)                           (((x) << 5) & 0x000003e0)
-#define PHY_BB_TPC_11_B0_OLPC_GAIN_DELTA_0_MSB                                                        23
-#define PHY_BB_TPC_11_B0_OLPC_GAIN_DELTA_0_LSB                                                        16
-#define PHY_BB_TPC_11_B0_OLPC_GAIN_DELTA_0_MASK                                               0x00ff0000
-#define PHY_BB_TPC_11_B0_OLPC_GAIN_DELTA_0_GET(x)                             (((x) & 0x00ff0000) >> 16)
-#define PHY_BB_TPC_11_B0_OLPC_GAIN_DELTA_0_SET(x)                             (((x) << 16) & 0x00ff0000)
-#define PHY_BB_TPC_11_B0_OLPC_GAIN_DELTA_0_PAL_ON_MSB                                                 31
-#define PHY_BB_TPC_11_B0_OLPC_GAIN_DELTA_0_PAL_ON_LSB                                                 24
-#define PHY_BB_TPC_11_B0_OLPC_GAIN_DELTA_0_PAL_ON_MASK                                        0xff000000
-#define PHY_BB_TPC_11_B0_OLPC_GAIN_DELTA_0_PAL_ON_GET(x)                      (((x) & 0xff000000) >> 24)
-#define PHY_BB_TPC_11_B0_OLPC_GAIN_DELTA_0_PAL_ON_SET(x)                      (((x) << 24) & 0xff000000)
-
-/* macros for BB_cal_chain_mask */
-#define PHY_BB_CAL_CHAIN_MASK_ADDRESS                                                         0x0000a39c
-#define PHY_BB_CAL_CHAIN_MASK_OFFSET                                                          0x0000a39c
-#define PHY_BB_CAL_CHAIN_MASK_CAL_CHAIN_MASK_MSB                                                       2
-#define PHY_BB_CAL_CHAIN_MASK_CAL_CHAIN_MASK_LSB                                                       0
-#define PHY_BB_CAL_CHAIN_MASK_CAL_CHAIN_MASK_MASK                                             0x00000007
-#define PHY_BB_CAL_CHAIN_MASK_CAL_CHAIN_MASK_GET(x)                            (((x) & 0x00000007) >> 0)
-#define PHY_BB_CAL_CHAIN_MASK_CAL_CHAIN_MASK_SET(x)                            (((x) << 0) & 0x00000007)
-
-/* macros for BB_powertx_sub */
-#define PHY_BB_POWERTX_SUB_ADDRESS                                                            0x0000a3bc
-#define PHY_BB_POWERTX_SUB_OFFSET                                                             0x0000a3bc
-#define PHY_BB_POWERTX_SUB_POWERTX_SUB_FOR_2CHAIN_MSB                                                  5
-#define PHY_BB_POWERTX_SUB_POWERTX_SUB_FOR_2CHAIN_LSB                                                  0
-#define PHY_BB_POWERTX_SUB_POWERTX_SUB_FOR_2CHAIN_MASK                                        0x0000003f
-#define PHY_BB_POWERTX_SUB_POWERTX_SUB_FOR_2CHAIN_GET(x)                       (((x) & 0x0000003f) >> 0)
-#define PHY_BB_POWERTX_SUB_POWERTX_SUB_FOR_2CHAIN_SET(x)                       (((x) << 0) & 0x0000003f)
-
-/* macros for BB_powertx_rate7 */
-#define PHY_BB_POWERTX_RATE7_ADDRESS                                                          0x0000a3c0
-#define PHY_BB_POWERTX_RATE7_OFFSET                                                           0x0000a3c0
-#define PHY_BB_POWERTX_RATE7_POWERTXHT40_0_MSB                                                         5
-#define PHY_BB_POWERTX_RATE7_POWERTXHT40_0_LSB                                                         0
-#define PHY_BB_POWERTX_RATE7_POWERTXHT40_0_MASK                                               0x0000003f
-#define PHY_BB_POWERTX_RATE7_POWERTXHT40_0_GET(x)                              (((x) & 0x0000003f) >> 0)
-#define PHY_BB_POWERTX_RATE7_POWERTXHT40_0_SET(x)                              (((x) << 0) & 0x0000003f)
-#define PHY_BB_POWERTX_RATE7_POWERTXHT40_1_MSB                                                        13
-#define PHY_BB_POWERTX_RATE7_POWERTXHT40_1_LSB                                                         8
-#define PHY_BB_POWERTX_RATE7_POWERTXHT40_1_MASK                                               0x00003f00
-#define PHY_BB_POWERTX_RATE7_POWERTXHT40_1_GET(x)                              (((x) & 0x00003f00) >> 8)
-#define PHY_BB_POWERTX_RATE7_POWERTXHT40_1_SET(x)                              (((x) << 8) & 0x00003f00)
-#define PHY_BB_POWERTX_RATE7_POWERTXHT40_2_MSB                                                        21
-#define PHY_BB_POWERTX_RATE7_POWERTXHT40_2_LSB                                                        16
-#define PHY_BB_POWERTX_RATE7_POWERTXHT40_2_MASK                                               0x003f0000
-#define PHY_BB_POWERTX_RATE7_POWERTXHT40_2_GET(x)                             (((x) & 0x003f0000) >> 16)
-#define PHY_BB_POWERTX_RATE7_POWERTXHT40_2_SET(x)                             (((x) << 16) & 0x003f0000)
-#define PHY_BB_POWERTX_RATE7_POWERTXHT40_3_MSB                                                        29
-#define PHY_BB_POWERTX_RATE7_POWERTXHT40_3_LSB                                                        24
-#define PHY_BB_POWERTX_RATE7_POWERTXHT40_3_MASK                                               0x3f000000
-#define PHY_BB_POWERTX_RATE7_POWERTXHT40_3_GET(x)                             (((x) & 0x3f000000) >> 24)
-#define PHY_BB_POWERTX_RATE7_POWERTXHT40_3_SET(x)                             (((x) << 24) & 0x3f000000)
-
-/* macros for BB_powertx_rate8 */
-#define PHY_BB_POWERTX_RATE8_ADDRESS                                                          0x0000a3c4
-#define PHY_BB_POWERTX_RATE8_OFFSET                                                           0x0000a3c4
-#define PHY_BB_POWERTX_RATE8_POWERTXHT40_4_MSB                                                         5
-#define PHY_BB_POWERTX_RATE8_POWERTXHT40_4_LSB                                                         0
-#define PHY_BB_POWERTX_RATE8_POWERTXHT40_4_MASK                                               0x0000003f
-#define PHY_BB_POWERTX_RATE8_POWERTXHT40_4_GET(x)                              (((x) & 0x0000003f) >> 0)
-#define PHY_BB_POWERTX_RATE8_POWERTXHT40_4_SET(x)                              (((x) << 0) & 0x0000003f)
-#define PHY_BB_POWERTX_RATE8_POWERTXHT40_5_MSB                                                        13
-#define PHY_BB_POWERTX_RATE8_POWERTXHT40_5_LSB                                                         8
-#define PHY_BB_POWERTX_RATE8_POWERTXHT40_5_MASK                                               0x00003f00
-#define PHY_BB_POWERTX_RATE8_POWERTXHT40_5_GET(x)                              (((x) & 0x00003f00) >> 8)
-#define PHY_BB_POWERTX_RATE8_POWERTXHT40_5_SET(x)                              (((x) << 8) & 0x00003f00)
-#define PHY_BB_POWERTX_RATE8_POWERTXHT40_6_MSB                                                        21
-#define PHY_BB_POWERTX_RATE8_POWERTXHT40_6_LSB                                                        16
-#define PHY_BB_POWERTX_RATE8_POWERTXHT40_6_MASK                                               0x003f0000
-#define PHY_BB_POWERTX_RATE8_POWERTXHT40_6_GET(x)                             (((x) & 0x003f0000) >> 16)
-#define PHY_BB_POWERTX_RATE8_POWERTXHT40_6_SET(x)                             (((x) << 16) & 0x003f0000)
-#define PHY_BB_POWERTX_RATE8_POWERTXHT40_7_MSB                                                        29
-#define PHY_BB_POWERTX_RATE8_POWERTXHT40_7_LSB                                                        24
-#define PHY_BB_POWERTX_RATE8_POWERTXHT40_7_MASK                                               0x3f000000
-#define PHY_BB_POWERTX_RATE8_POWERTXHT40_7_GET(x)                             (((x) & 0x3f000000) >> 24)
-#define PHY_BB_POWERTX_RATE8_POWERTXHT40_7_SET(x)                             (((x) << 24) & 0x3f000000)
-
-/* macros for BB_powertx_rate9 */
-#define PHY_BB_POWERTX_RATE9_ADDRESS                                                          0x0000a3c8
-#define PHY_BB_POWERTX_RATE9_OFFSET                                                           0x0000a3c8
-#define PHY_BB_POWERTX_RATE9_POWERTX_DUP40_CCK_MSB                                                     5
-#define PHY_BB_POWERTX_RATE9_POWERTX_DUP40_CCK_LSB                                                     0
-#define PHY_BB_POWERTX_RATE9_POWERTX_DUP40_CCK_MASK                                           0x0000003f
-#define PHY_BB_POWERTX_RATE9_POWERTX_DUP40_CCK_GET(x)                          (((x) & 0x0000003f) >> 0)
-#define PHY_BB_POWERTX_RATE9_POWERTX_DUP40_CCK_SET(x)                          (((x) << 0) & 0x0000003f)
-#define PHY_BB_POWERTX_RATE9_POWERTX_DUP40_OFDM_MSB                                                   13
-#define PHY_BB_POWERTX_RATE9_POWERTX_DUP40_OFDM_LSB                                                    8
-#define PHY_BB_POWERTX_RATE9_POWERTX_DUP40_OFDM_MASK                                          0x00003f00
-#define PHY_BB_POWERTX_RATE9_POWERTX_DUP40_OFDM_GET(x)                         (((x) & 0x00003f00) >> 8)
-#define PHY_BB_POWERTX_RATE9_POWERTX_DUP40_OFDM_SET(x)                         (((x) << 8) & 0x00003f00)
-#define PHY_BB_POWERTX_RATE9_POWERTX_EXT20_CCK_MSB                                                    21
-#define PHY_BB_POWERTX_RATE9_POWERTX_EXT20_CCK_LSB                                                    16
-#define PHY_BB_POWERTX_RATE9_POWERTX_EXT20_CCK_MASK                                           0x003f0000
-#define PHY_BB_POWERTX_RATE9_POWERTX_EXT20_CCK_GET(x)                         (((x) & 0x003f0000) >> 16)
-#define PHY_BB_POWERTX_RATE9_POWERTX_EXT20_CCK_SET(x)                         (((x) << 16) & 0x003f0000)
-#define PHY_BB_POWERTX_RATE9_POWERTX_EXT20_OFDM_MSB                                                   29
-#define PHY_BB_POWERTX_RATE9_POWERTX_EXT20_OFDM_LSB                                                   24
-#define PHY_BB_POWERTX_RATE9_POWERTX_EXT20_OFDM_MASK                                          0x3f000000
-#define PHY_BB_POWERTX_RATE9_POWERTX_EXT20_OFDM_GET(x)                        (((x) & 0x3f000000) >> 24)
-#define PHY_BB_POWERTX_RATE9_POWERTX_EXT20_OFDM_SET(x)                        (((x) << 24) & 0x3f000000)
-
-/* macros for BB_powertx_rate10 */
-#define PHY_BB_POWERTX_RATE10_ADDRESS                                                         0x0000a3cc
-#define PHY_BB_POWERTX_RATE10_OFFSET                                                          0x0000a3cc
-#define PHY_BB_POWERTX_RATE10_POWERTXHT20_8_MSB                                                        5
-#define PHY_BB_POWERTX_RATE10_POWERTXHT20_8_LSB                                                        0
-#define PHY_BB_POWERTX_RATE10_POWERTXHT20_8_MASK                                              0x0000003f
-#define PHY_BB_POWERTX_RATE10_POWERTXHT20_8_GET(x)                             (((x) & 0x0000003f) >> 0)
-#define PHY_BB_POWERTX_RATE10_POWERTXHT20_8_SET(x)                             (((x) << 0) & 0x0000003f)
-#define PHY_BB_POWERTX_RATE10_POWERTXHT20_9_MSB                                                       13
-#define PHY_BB_POWERTX_RATE10_POWERTXHT20_9_LSB                                                        8
-#define PHY_BB_POWERTX_RATE10_POWERTXHT20_9_MASK                                              0x00003f00
-#define PHY_BB_POWERTX_RATE10_POWERTXHT20_9_GET(x)                             (((x) & 0x00003f00) >> 8)
-#define PHY_BB_POWERTX_RATE10_POWERTXHT20_9_SET(x)                             (((x) << 8) & 0x00003f00)
-#define PHY_BB_POWERTX_RATE10_POWERTXHT20_10_MSB                                                      21
-#define PHY_BB_POWERTX_RATE10_POWERTXHT20_10_LSB                                                      16
-#define PHY_BB_POWERTX_RATE10_POWERTXHT20_10_MASK                                             0x003f0000
-#define PHY_BB_POWERTX_RATE10_POWERTXHT20_10_GET(x)                           (((x) & 0x003f0000) >> 16)
-#define PHY_BB_POWERTX_RATE10_POWERTXHT20_10_SET(x)                           (((x) << 16) & 0x003f0000)
-#define PHY_BB_POWERTX_RATE10_POWERTXHT20_11_MSB                                                      29
-#define PHY_BB_POWERTX_RATE10_POWERTXHT20_11_LSB                                                      24
-#define PHY_BB_POWERTX_RATE10_POWERTXHT20_11_MASK                                             0x3f000000
-#define PHY_BB_POWERTX_RATE10_POWERTXHT20_11_GET(x)                           (((x) & 0x3f000000) >> 24)
-#define PHY_BB_POWERTX_RATE10_POWERTXHT20_11_SET(x)                           (((x) << 24) & 0x3f000000)
-
-/* macros for BB_powertx_rate11 */
-#define PHY_BB_POWERTX_RATE11_ADDRESS                                                         0x0000a3d0
-#define PHY_BB_POWERTX_RATE11_OFFSET                                                          0x0000a3d0
-#define PHY_BB_POWERTX_RATE11_POWERTXHT20_12_MSB                                                       5
-#define PHY_BB_POWERTX_RATE11_POWERTXHT20_12_LSB                                                       0
-#define PHY_BB_POWERTX_RATE11_POWERTXHT20_12_MASK                                             0x0000003f
-#define PHY_BB_POWERTX_RATE11_POWERTXHT20_12_GET(x)                            (((x) & 0x0000003f) >> 0)
-#define PHY_BB_POWERTX_RATE11_POWERTXHT20_12_SET(x)                            (((x) << 0) & 0x0000003f)
-#define PHY_BB_POWERTX_RATE11_POWERTXHT20_13_MSB                                                      13
-#define PHY_BB_POWERTX_RATE11_POWERTXHT20_13_LSB                                                       8
-#define PHY_BB_POWERTX_RATE11_POWERTXHT20_13_MASK                                             0x00003f00
-#define PHY_BB_POWERTX_RATE11_POWERTXHT20_13_GET(x)                            (((x) & 0x00003f00) >> 8)
-#define PHY_BB_POWERTX_RATE11_POWERTXHT20_13_SET(x)                            (((x) << 8) & 0x00003f00)
-#define PHY_BB_POWERTX_RATE11_POWERTXHT40_12_MSB                                                      21
-#define PHY_BB_POWERTX_RATE11_POWERTXHT40_12_LSB                                                      16
-#define PHY_BB_POWERTX_RATE11_POWERTXHT40_12_MASK                                             0x003f0000
-#define PHY_BB_POWERTX_RATE11_POWERTXHT40_12_GET(x)                           (((x) & 0x003f0000) >> 16)
-#define PHY_BB_POWERTX_RATE11_POWERTXHT40_12_SET(x)                           (((x) << 16) & 0x003f0000)
-#define PHY_BB_POWERTX_RATE11_POWERTXHT40_13_MSB                                                      29
-#define PHY_BB_POWERTX_RATE11_POWERTXHT40_13_LSB                                                      24
-#define PHY_BB_POWERTX_RATE11_POWERTXHT40_13_MASK                                             0x3f000000
-#define PHY_BB_POWERTX_RATE11_POWERTXHT40_13_GET(x)                           (((x) & 0x3f000000) >> 24)
-#define PHY_BB_POWERTX_RATE11_POWERTXHT40_13_SET(x)                           (((x) << 24) & 0x3f000000)
-
-/* macros for BB_powertx_rate12 */
-#define PHY_BB_POWERTX_RATE12_ADDRESS                                                         0x0000a3d4
-#define PHY_BB_POWERTX_RATE12_OFFSET                                                          0x0000a3d4
-#define PHY_BB_POWERTX_RATE12_POWERTXHT40_8_MSB                                                        5
-#define PHY_BB_POWERTX_RATE12_POWERTXHT40_8_LSB                                                        0
-#define PHY_BB_POWERTX_RATE12_POWERTXHT40_8_MASK                                              0x0000003f
-#define PHY_BB_POWERTX_RATE12_POWERTXHT40_8_GET(x)                             (((x) & 0x0000003f) >> 0)
-#define PHY_BB_POWERTX_RATE12_POWERTXHT40_8_SET(x)                             (((x) << 0) & 0x0000003f)
-#define PHY_BB_POWERTX_RATE12_POWERTXHT40_9_MSB                                                       13
-#define PHY_BB_POWERTX_RATE12_POWERTXHT40_9_LSB                                                        8
-#define PHY_BB_POWERTX_RATE12_POWERTXHT40_9_MASK                                              0x00003f00
-#define PHY_BB_POWERTX_RATE12_POWERTXHT40_9_GET(x)                             (((x) & 0x00003f00) >> 8)
-#define PHY_BB_POWERTX_RATE12_POWERTXHT40_9_SET(x)                             (((x) << 8) & 0x00003f00)
-#define PHY_BB_POWERTX_RATE12_POWERTXHT40_10_MSB                                                      21
-#define PHY_BB_POWERTX_RATE12_POWERTXHT40_10_LSB                                                      16
-#define PHY_BB_POWERTX_RATE12_POWERTXHT40_10_MASK                                             0x003f0000
-#define PHY_BB_POWERTX_RATE12_POWERTXHT40_10_GET(x)                           (((x) & 0x003f0000) >> 16)
-#define PHY_BB_POWERTX_RATE12_POWERTXHT40_10_SET(x)                           (((x) << 16) & 0x003f0000)
-#define PHY_BB_POWERTX_RATE12_POWERTXHT40_11_MSB                                                      29
-#define PHY_BB_POWERTX_RATE12_POWERTXHT40_11_LSB                                                      24
-#define PHY_BB_POWERTX_RATE12_POWERTXHT40_11_MASK                                             0x3f000000
-#define PHY_BB_POWERTX_RATE12_POWERTXHT40_11_GET(x)                           (((x) & 0x3f000000) >> 24)
-#define PHY_BB_POWERTX_RATE12_POWERTXHT40_11_SET(x)                           (((x) << 24) & 0x3f000000)
-
-/* macros for BB_force_analog */
-#define PHY_BB_FORCE_ANALOG_ADDRESS                                                           0x0000a3d8
-#define PHY_BB_FORCE_ANALOG_OFFSET                                                            0x0000a3d8
-#define PHY_BB_FORCE_ANALOG_FORCE_XPAON_MSB                                                            0
-#define PHY_BB_FORCE_ANALOG_FORCE_XPAON_LSB                                                            0
-#define PHY_BB_FORCE_ANALOG_FORCE_XPAON_MASK                                                  0x00000001
-#define PHY_BB_FORCE_ANALOG_FORCE_XPAON_GET(x)                                 (((x) & 0x00000001) >> 0)
-#define PHY_BB_FORCE_ANALOG_FORCE_XPAON_SET(x)                                 (((x) << 0) & 0x00000001)
-#define PHY_BB_FORCE_ANALOG_FORCED_XPAON_MSB                                                           3
-#define PHY_BB_FORCE_ANALOG_FORCED_XPAON_LSB                                                           1
-#define PHY_BB_FORCE_ANALOG_FORCED_XPAON_MASK                                                 0x0000000e
-#define PHY_BB_FORCE_ANALOG_FORCED_XPAON_GET(x)                                (((x) & 0x0000000e) >> 1)
-#define PHY_BB_FORCE_ANALOG_FORCED_XPAON_SET(x)                                (((x) << 1) & 0x0000000e)
-#define PHY_BB_FORCE_ANALOG_FORCE_PDADC_PWD_MSB                                                        4
-#define PHY_BB_FORCE_ANALOG_FORCE_PDADC_PWD_LSB                                                        4
-#define PHY_BB_FORCE_ANALOG_FORCE_PDADC_PWD_MASK                                              0x00000010
-#define PHY_BB_FORCE_ANALOG_FORCE_PDADC_PWD_GET(x)                             (((x) & 0x00000010) >> 4)
-#define PHY_BB_FORCE_ANALOG_FORCE_PDADC_PWD_SET(x)                             (((x) << 4) & 0x00000010)
-#define PHY_BB_FORCE_ANALOG_FORCED_PDADC_PWD_MSB                                                       7
-#define PHY_BB_FORCE_ANALOG_FORCED_PDADC_PWD_LSB                                                       5
-#define PHY_BB_FORCE_ANALOG_FORCED_PDADC_PWD_MASK                                             0x000000e0
-#define PHY_BB_FORCE_ANALOG_FORCED_PDADC_PWD_GET(x)                            (((x) & 0x000000e0) >> 5)
-#define PHY_BB_FORCE_ANALOG_FORCED_PDADC_PWD_SET(x)                            (((x) << 5) & 0x000000e0)
-
-/* macros for BB_tpc_12 */
-#define PHY_BB_TPC_12_ADDRESS                                                                 0x0000a3dc
-#define PHY_BB_TPC_12_OFFSET                                                                  0x0000a3dc
-#define PHY_BB_TPC_12_DESIRED_SCALE_HT40_0_MSB                                                         4
-#define PHY_BB_TPC_12_DESIRED_SCALE_HT40_0_LSB                                                         0
-#define PHY_BB_TPC_12_DESIRED_SCALE_HT40_0_MASK                                               0x0000001f
-#define PHY_BB_TPC_12_DESIRED_SCALE_HT40_0_GET(x)                              (((x) & 0x0000001f) >> 0)
-#define PHY_BB_TPC_12_DESIRED_SCALE_HT40_0_SET(x)                              (((x) << 0) & 0x0000001f)
-#define PHY_BB_TPC_12_DESIRED_SCALE_HT40_1_MSB                                                         9
-#define PHY_BB_TPC_12_DESIRED_SCALE_HT40_1_LSB                                                         5
-#define PHY_BB_TPC_12_DESIRED_SCALE_HT40_1_MASK                                               0x000003e0
-#define PHY_BB_TPC_12_DESIRED_SCALE_HT40_1_GET(x)                              (((x) & 0x000003e0) >> 5)
-#define PHY_BB_TPC_12_DESIRED_SCALE_HT40_1_SET(x)                              (((x) << 5) & 0x000003e0)
-#define PHY_BB_TPC_12_DESIRED_SCALE_HT40_2_MSB                                                        14
-#define PHY_BB_TPC_12_DESIRED_SCALE_HT40_2_LSB                                                        10
-#define PHY_BB_TPC_12_DESIRED_SCALE_HT40_2_MASK                                               0x00007c00
-#define PHY_BB_TPC_12_DESIRED_SCALE_HT40_2_GET(x)                             (((x) & 0x00007c00) >> 10)
-#define PHY_BB_TPC_12_DESIRED_SCALE_HT40_2_SET(x)                             (((x) << 10) & 0x00007c00)
-#define PHY_BB_TPC_12_DESIRED_SCALE_HT40_3_MSB                                                        19
-#define PHY_BB_TPC_12_DESIRED_SCALE_HT40_3_LSB                                                        15
-#define PHY_BB_TPC_12_DESIRED_SCALE_HT40_3_MASK                                               0x000f8000
-#define PHY_BB_TPC_12_DESIRED_SCALE_HT40_3_GET(x)                             (((x) & 0x000f8000) >> 15)
-#define PHY_BB_TPC_12_DESIRED_SCALE_HT40_3_SET(x)                             (((x) << 15) & 0x000f8000)
-#define PHY_BB_TPC_12_DESIRED_SCALE_HT40_4_MSB                                                        24
-#define PHY_BB_TPC_12_DESIRED_SCALE_HT40_4_LSB                                                        20
-#define PHY_BB_TPC_12_DESIRED_SCALE_HT40_4_MASK                                               0x01f00000
-#define PHY_BB_TPC_12_DESIRED_SCALE_HT40_4_GET(x)                             (((x) & 0x01f00000) >> 20)
-#define PHY_BB_TPC_12_DESIRED_SCALE_HT40_4_SET(x)                             (((x) << 20) & 0x01f00000)
-#define PHY_BB_TPC_12_DESIRED_SCALE_HT40_5_MSB                                                        29
-#define PHY_BB_TPC_12_DESIRED_SCALE_HT40_5_LSB                                                        25
-#define PHY_BB_TPC_12_DESIRED_SCALE_HT40_5_MASK                                               0x3e000000
-#define PHY_BB_TPC_12_DESIRED_SCALE_HT40_5_GET(x)                             (((x) & 0x3e000000) >> 25)
-#define PHY_BB_TPC_12_DESIRED_SCALE_HT40_5_SET(x)                             (((x) << 25) & 0x3e000000)
-
-/* macros for BB_tpc_13 */
-#define PHY_BB_TPC_13_ADDRESS                                                                 0x0000a3e0
-#define PHY_BB_TPC_13_OFFSET                                                                  0x0000a3e0
-#define PHY_BB_TPC_13_DESIRED_SCALE_HT40_6_MSB                                                         4
-#define PHY_BB_TPC_13_DESIRED_SCALE_HT40_6_LSB                                                         0
-#define PHY_BB_TPC_13_DESIRED_SCALE_HT40_6_MASK                                               0x0000001f
-#define PHY_BB_TPC_13_DESIRED_SCALE_HT40_6_GET(x)                              (((x) & 0x0000001f) >> 0)
-#define PHY_BB_TPC_13_DESIRED_SCALE_HT40_6_SET(x)                              (((x) << 0) & 0x0000001f)
-#define PHY_BB_TPC_13_DESIRED_SCALE_HT40_7_MSB                                                         9
-#define PHY_BB_TPC_13_DESIRED_SCALE_HT40_7_LSB                                                         5
-#define PHY_BB_TPC_13_DESIRED_SCALE_HT40_7_MASK                                               0x000003e0
-#define PHY_BB_TPC_13_DESIRED_SCALE_HT40_7_GET(x)                              (((x) & 0x000003e0) >> 5)
-#define PHY_BB_TPC_13_DESIRED_SCALE_HT40_7_SET(x)                              (((x) << 5) & 0x000003e0)
-
-/* macros for BB_tpc_14 */
-#define PHY_BB_TPC_14_ADDRESS                                                                 0x0000a3e4
-#define PHY_BB_TPC_14_OFFSET                                                                  0x0000a3e4
-#define PHY_BB_TPC_14_DESIRED_SCALE_HT20_8_MSB                                                         4
-#define PHY_BB_TPC_14_DESIRED_SCALE_HT20_8_LSB                                                         0
-#define PHY_BB_TPC_14_DESIRED_SCALE_HT20_8_MASK                                               0x0000001f
-#define PHY_BB_TPC_14_DESIRED_SCALE_HT20_8_GET(x)                              (((x) & 0x0000001f) >> 0)
-#define PHY_BB_TPC_14_DESIRED_SCALE_HT20_8_SET(x)                              (((x) << 0) & 0x0000001f)
-#define PHY_BB_TPC_14_DESIRED_SCALE_HT20_9_MSB                                                         9
-#define PHY_BB_TPC_14_DESIRED_SCALE_HT20_9_LSB                                                         5
-#define PHY_BB_TPC_14_DESIRED_SCALE_HT20_9_MASK                                               0x000003e0
-#define PHY_BB_TPC_14_DESIRED_SCALE_HT20_9_GET(x)                              (((x) & 0x000003e0) >> 5)
-#define PHY_BB_TPC_14_DESIRED_SCALE_HT20_9_SET(x)                              (((x) << 5) & 0x000003e0)
-#define PHY_BB_TPC_14_DESIRED_SCALE_HT20_10_MSB                                                       14
-#define PHY_BB_TPC_14_DESIRED_SCALE_HT20_10_LSB                                                       10
-#define PHY_BB_TPC_14_DESIRED_SCALE_HT20_10_MASK                                              0x00007c00
-#define PHY_BB_TPC_14_DESIRED_SCALE_HT20_10_GET(x)                            (((x) & 0x00007c00) >> 10)
-#define PHY_BB_TPC_14_DESIRED_SCALE_HT20_10_SET(x)                            (((x) << 10) & 0x00007c00)
-#define PHY_BB_TPC_14_DESIRED_SCALE_HT20_11_MSB                                                       19
-#define PHY_BB_TPC_14_DESIRED_SCALE_HT20_11_LSB                                                       15
-#define PHY_BB_TPC_14_DESIRED_SCALE_HT20_11_MASK                                              0x000f8000
-#define PHY_BB_TPC_14_DESIRED_SCALE_HT20_11_GET(x)                            (((x) & 0x000f8000) >> 15)
-#define PHY_BB_TPC_14_DESIRED_SCALE_HT20_11_SET(x)                            (((x) << 15) & 0x000f8000)
-#define PHY_BB_TPC_14_DESIRED_SCALE_HT20_12_MSB                                                       24
-#define PHY_BB_TPC_14_DESIRED_SCALE_HT20_12_LSB                                                       20
-#define PHY_BB_TPC_14_DESIRED_SCALE_HT20_12_MASK                                              0x01f00000
-#define PHY_BB_TPC_14_DESIRED_SCALE_HT20_12_GET(x)                            (((x) & 0x01f00000) >> 20)
-#define PHY_BB_TPC_14_DESIRED_SCALE_HT20_12_SET(x)                            (((x) << 20) & 0x01f00000)
-#define PHY_BB_TPC_14_DESIRED_SCALE_HT20_13_MSB                                                       29
-#define PHY_BB_TPC_14_DESIRED_SCALE_HT20_13_LSB                                                       25
-#define PHY_BB_TPC_14_DESIRED_SCALE_HT20_13_MASK                                              0x3e000000
-#define PHY_BB_TPC_14_DESIRED_SCALE_HT20_13_GET(x)                            (((x) & 0x3e000000) >> 25)
-#define PHY_BB_TPC_14_DESIRED_SCALE_HT20_13_SET(x)                            (((x) << 25) & 0x3e000000)
-
-/* macros for BB_tpc_15 */
-#define PHY_BB_TPC_15_ADDRESS                                                                 0x0000a3e8
-#define PHY_BB_TPC_15_OFFSET                                                                  0x0000a3e8
-#define PHY_BB_TPC_15_DESIRED_SCALE_HT40_8_MSB                                                         4
-#define PHY_BB_TPC_15_DESIRED_SCALE_HT40_8_LSB                                                         0
-#define PHY_BB_TPC_15_DESIRED_SCALE_HT40_8_MASK                                               0x0000001f
-#define PHY_BB_TPC_15_DESIRED_SCALE_HT40_8_GET(x)                              (((x) & 0x0000001f) >> 0)
-#define PHY_BB_TPC_15_DESIRED_SCALE_HT40_8_SET(x)                              (((x) << 0) & 0x0000001f)
-#define PHY_BB_TPC_15_DESIRED_SCALE_HT40_9_MSB                                                         9
-#define PHY_BB_TPC_15_DESIRED_SCALE_HT40_9_LSB                                                         5
-#define PHY_BB_TPC_15_DESIRED_SCALE_HT40_9_MASK                                               0x000003e0
-#define PHY_BB_TPC_15_DESIRED_SCALE_HT40_9_GET(x)                              (((x) & 0x000003e0) >> 5)
-#define PHY_BB_TPC_15_DESIRED_SCALE_HT40_9_SET(x)                              (((x) << 5) & 0x000003e0)
-#define PHY_BB_TPC_15_DESIRED_SCALE_HT40_10_MSB                                                       14
-#define PHY_BB_TPC_15_DESIRED_SCALE_HT40_10_LSB                                                       10
-#define PHY_BB_TPC_15_DESIRED_SCALE_HT40_10_MASK                                              0x00007c00
-#define PHY_BB_TPC_15_DESIRED_SCALE_HT40_10_GET(x)                            (((x) & 0x00007c00) >> 10)
-#define PHY_BB_TPC_15_DESIRED_SCALE_HT40_10_SET(x)                            (((x) << 10) & 0x00007c00)
-#define PHY_BB_TPC_15_DESIRED_SCALE_HT40_11_MSB                                                       19
-#define PHY_BB_TPC_15_DESIRED_SCALE_HT40_11_LSB                                                       15
-#define PHY_BB_TPC_15_DESIRED_SCALE_HT40_11_MASK                                              0x000f8000
-#define PHY_BB_TPC_15_DESIRED_SCALE_HT40_11_GET(x)                            (((x) & 0x000f8000) >> 15)
-#define PHY_BB_TPC_15_DESIRED_SCALE_HT40_11_SET(x)                            (((x) << 15) & 0x000f8000)
-#define PHY_BB_TPC_15_DESIRED_SCALE_HT40_12_MSB                                                       24
-#define PHY_BB_TPC_15_DESIRED_SCALE_HT40_12_LSB                                                       20
-#define PHY_BB_TPC_15_DESIRED_SCALE_HT40_12_MASK                                              0x01f00000
-#define PHY_BB_TPC_15_DESIRED_SCALE_HT40_12_GET(x)                            (((x) & 0x01f00000) >> 20)
-#define PHY_BB_TPC_15_DESIRED_SCALE_HT40_12_SET(x)                            (((x) << 20) & 0x01f00000)
-#define PHY_BB_TPC_15_DESIRED_SCALE_HT40_13_MSB                                                       29
-#define PHY_BB_TPC_15_DESIRED_SCALE_HT40_13_LSB                                                       25
-#define PHY_BB_TPC_15_DESIRED_SCALE_HT40_13_MASK                                              0x3e000000
-#define PHY_BB_TPC_15_DESIRED_SCALE_HT40_13_GET(x)                            (((x) & 0x3e000000) >> 25)
-#define PHY_BB_TPC_15_DESIRED_SCALE_HT40_13_SET(x)                            (((x) << 25) & 0x3e000000)
-
-/* macros for BB_tpc_16 */
-#define PHY_BB_TPC_16_ADDRESS                                                                 0x0000a3ec
-#define PHY_BB_TPC_16_OFFSET                                                                  0x0000a3ec
-#define PHY_BB_TPC_16_PDADC_PAR_CORR_CCK_MSB                                                          13
-#define PHY_BB_TPC_16_PDADC_PAR_CORR_CCK_LSB                                                           8
-#define PHY_BB_TPC_16_PDADC_PAR_CORR_CCK_MASK                                                 0x00003f00
-#define PHY_BB_TPC_16_PDADC_PAR_CORR_CCK_GET(x)                                (((x) & 0x00003f00) >> 8)
-#define PHY_BB_TPC_16_PDADC_PAR_CORR_CCK_SET(x)                                (((x) << 8) & 0x00003f00)
-#define PHY_BB_TPC_16_PDADC_PAR_CORR_OFDM_MSB                                                         21
-#define PHY_BB_TPC_16_PDADC_PAR_CORR_OFDM_LSB                                                         16
-#define PHY_BB_TPC_16_PDADC_PAR_CORR_OFDM_MASK                                                0x003f0000
-#define PHY_BB_TPC_16_PDADC_PAR_CORR_OFDM_GET(x)                              (((x) & 0x003f0000) >> 16)
-#define PHY_BB_TPC_16_PDADC_PAR_CORR_OFDM_SET(x)                              (((x) << 16) & 0x003f0000)
-#define PHY_BB_TPC_16_PDADC_PAR_CORR_HT40_MSB                                                         29
-#define PHY_BB_TPC_16_PDADC_PAR_CORR_HT40_LSB                                                         24
-#define PHY_BB_TPC_16_PDADC_PAR_CORR_HT40_MASK                                                0x3f000000
-#define PHY_BB_TPC_16_PDADC_PAR_CORR_HT40_GET(x)                              (((x) & 0x3f000000) >> 24)
-#define PHY_BB_TPC_16_PDADC_PAR_CORR_HT40_SET(x)                              (((x) << 24) & 0x3f000000)
-
-/* macros for BB_tpc_17 */
-#define PHY_BB_TPC_17_ADDRESS                                                                 0x0000a3f0
-#define PHY_BB_TPC_17_OFFSET                                                                  0x0000a3f0
-#define PHY_BB_TPC_17_ENABLE_PAL_MSB                                                                   0
-#define PHY_BB_TPC_17_ENABLE_PAL_LSB                                                                   0
-#define PHY_BB_TPC_17_ENABLE_PAL_MASK                                                         0x00000001
-#define PHY_BB_TPC_17_ENABLE_PAL_GET(x)                                        (((x) & 0x00000001) >> 0)
-#define PHY_BB_TPC_17_ENABLE_PAL_SET(x)                                        (((x) << 0) & 0x00000001)
-#define PHY_BB_TPC_17_ENABLE_PAL_CCK_MSB                                                               1
-#define PHY_BB_TPC_17_ENABLE_PAL_CCK_LSB                                                               1
-#define PHY_BB_TPC_17_ENABLE_PAL_CCK_MASK                                                     0x00000002
-#define PHY_BB_TPC_17_ENABLE_PAL_CCK_GET(x)                                    (((x) & 0x00000002) >> 1)
-#define PHY_BB_TPC_17_ENABLE_PAL_CCK_SET(x)                                    (((x) << 1) & 0x00000002)
-#define PHY_BB_TPC_17_ENABLE_PAL_OFDM_20_MSB                                                           2
-#define PHY_BB_TPC_17_ENABLE_PAL_OFDM_20_LSB                                                           2
-#define PHY_BB_TPC_17_ENABLE_PAL_OFDM_20_MASK                                                 0x00000004
-#define PHY_BB_TPC_17_ENABLE_PAL_OFDM_20_GET(x)                                (((x) & 0x00000004) >> 2)
-#define PHY_BB_TPC_17_ENABLE_PAL_OFDM_20_SET(x)                                (((x) << 2) & 0x00000004)
-#define PHY_BB_TPC_17_ENABLE_PAL_OFDM_40_MSB                                                           3
-#define PHY_BB_TPC_17_ENABLE_PAL_OFDM_40_LSB                                                           3
-#define PHY_BB_TPC_17_ENABLE_PAL_OFDM_40_MASK                                                 0x00000008
-#define PHY_BB_TPC_17_ENABLE_PAL_OFDM_40_GET(x)                                (((x) & 0x00000008) >> 3)
-#define PHY_BB_TPC_17_ENABLE_PAL_OFDM_40_SET(x)                                (((x) << 3) & 0x00000008)
-#define PHY_BB_TPC_17_PAL_POWER_THRESHOLD_MSB                                                          9
-#define PHY_BB_TPC_17_PAL_POWER_THRESHOLD_LSB                                                          4
-#define PHY_BB_TPC_17_PAL_POWER_THRESHOLD_MASK                                                0x000003f0
-#define PHY_BB_TPC_17_PAL_POWER_THRESHOLD_GET(x)                               (((x) & 0x000003f0) >> 4)
-#define PHY_BB_TPC_17_PAL_POWER_THRESHOLD_SET(x)                               (((x) << 4) & 0x000003f0)
-#define PHY_BB_TPC_17_FORCE_PAL_LOCKED_MSB                                                            10
-#define PHY_BB_TPC_17_FORCE_PAL_LOCKED_LSB                                                            10
-#define PHY_BB_TPC_17_FORCE_PAL_LOCKED_MASK                                                   0x00000400
-#define PHY_BB_TPC_17_FORCE_PAL_LOCKED_GET(x)                                 (((x) & 0x00000400) >> 10)
-#define PHY_BB_TPC_17_FORCE_PAL_LOCKED_SET(x)                                 (((x) << 10) & 0x00000400)
-#define PHY_BB_TPC_17_INIT_TX_GAIN_SETTING_PAL_ON_MSB                                                 16
-#define PHY_BB_TPC_17_INIT_TX_GAIN_SETTING_PAL_ON_LSB                                                 11
-#define PHY_BB_TPC_17_INIT_TX_GAIN_SETTING_PAL_ON_MASK                                        0x0001f800
-#define PHY_BB_TPC_17_INIT_TX_GAIN_SETTING_PAL_ON_GET(x)                      (((x) & 0x0001f800) >> 11)
-#define PHY_BB_TPC_17_INIT_TX_GAIN_SETTING_PAL_ON_SET(x)                      (((x) << 11) & 0x0001f800)
-
-/* macros for BB_tpc_18 */
-#define PHY_BB_TPC_18_ADDRESS                                                                 0x0000a3f4
-#define PHY_BB_TPC_18_OFFSET                                                                  0x0000a3f4
-#define PHY_BB_TPC_18_THERM_CAL_VALUE_MSB                                                              7
-#define PHY_BB_TPC_18_THERM_CAL_VALUE_LSB                                                              0
-#define PHY_BB_TPC_18_THERM_CAL_VALUE_MASK                                                    0x000000ff
-#define PHY_BB_TPC_18_THERM_CAL_VALUE_GET(x)                                   (((x) & 0x000000ff) >> 0)
-#define PHY_BB_TPC_18_THERM_CAL_VALUE_SET(x)                                   (((x) << 0) & 0x000000ff)
-#define PHY_BB_TPC_18_VOLT_CAL_VALUE_MSB                                                              15
-#define PHY_BB_TPC_18_VOLT_CAL_VALUE_LSB                                                               8
-#define PHY_BB_TPC_18_VOLT_CAL_VALUE_MASK                                                     0x0000ff00
-#define PHY_BB_TPC_18_VOLT_CAL_VALUE_GET(x)                                    (((x) & 0x0000ff00) >> 8)
-#define PHY_BB_TPC_18_VOLT_CAL_VALUE_SET(x)                                    (((x) << 8) & 0x0000ff00)
-#define PHY_BB_TPC_18_USE_LEGACY_TPC_MSB                                                              16
-#define PHY_BB_TPC_18_USE_LEGACY_TPC_LSB                                                              16
-#define PHY_BB_TPC_18_USE_LEGACY_TPC_MASK                                                     0x00010000
-#define PHY_BB_TPC_18_USE_LEGACY_TPC_GET(x)                                   (((x) & 0x00010000) >> 16)
-#define PHY_BB_TPC_18_USE_LEGACY_TPC_SET(x)                                   (((x) << 16) & 0x00010000)
-
-/* macros for BB_tpc_19 */
-#define PHY_BB_TPC_19_ADDRESS                                                                 0x0000a3f8
-#define PHY_BB_TPC_19_OFFSET                                                                  0x0000a3f8
-#define PHY_BB_TPC_19_ALPHA_THERM_MSB                                                                  7
-#define PHY_BB_TPC_19_ALPHA_THERM_LSB                                                                  0
-#define PHY_BB_TPC_19_ALPHA_THERM_MASK                                                        0x000000ff
-#define PHY_BB_TPC_19_ALPHA_THERM_GET(x)                                       (((x) & 0x000000ff) >> 0)
-#define PHY_BB_TPC_19_ALPHA_THERM_SET(x)                                       (((x) << 0) & 0x000000ff)
-#define PHY_BB_TPC_19_ALPHA_THERM_PAL_ON_MSB                                                          15
-#define PHY_BB_TPC_19_ALPHA_THERM_PAL_ON_LSB                                                           8
-#define PHY_BB_TPC_19_ALPHA_THERM_PAL_ON_MASK                                                 0x0000ff00
-#define PHY_BB_TPC_19_ALPHA_THERM_PAL_ON_GET(x)                                (((x) & 0x0000ff00) >> 8)
-#define PHY_BB_TPC_19_ALPHA_THERM_PAL_ON_SET(x)                                (((x) << 8) & 0x0000ff00)
-#define PHY_BB_TPC_19_ALPHA_VOLT_MSB                                                                  20
-#define PHY_BB_TPC_19_ALPHA_VOLT_LSB                                                                  16
-#define PHY_BB_TPC_19_ALPHA_VOLT_MASK                                                         0x001f0000
-#define PHY_BB_TPC_19_ALPHA_VOLT_GET(x)                                       (((x) & 0x001f0000) >> 16)
-#define PHY_BB_TPC_19_ALPHA_VOLT_SET(x)                                       (((x) << 16) & 0x001f0000)
-#define PHY_BB_TPC_19_ALPHA_VOLT_PAL_ON_MSB                                                           25
-#define PHY_BB_TPC_19_ALPHA_VOLT_PAL_ON_LSB                                                           21
-#define PHY_BB_TPC_19_ALPHA_VOLT_PAL_ON_MASK                                                  0x03e00000
-#define PHY_BB_TPC_19_ALPHA_VOLT_PAL_ON_GET(x)                                (((x) & 0x03e00000) >> 21)
-#define PHY_BB_TPC_19_ALPHA_VOLT_PAL_ON_SET(x)                                (((x) << 21) & 0x03e00000)
-
-/* macros for BB_tpc_20 */
-#define PHY_BB_TPC_20_ADDRESS                                                                 0x0000a3fc
-#define PHY_BB_TPC_20_OFFSET                                                                  0x0000a3fc
-#define PHY_BB_TPC_20_ENABLE_PAL_MCS_0_MSB                                                             0
-#define PHY_BB_TPC_20_ENABLE_PAL_MCS_0_LSB                                                             0
-#define PHY_BB_TPC_20_ENABLE_PAL_MCS_0_MASK                                                   0x00000001
-#define PHY_BB_TPC_20_ENABLE_PAL_MCS_0_GET(x)                                  (((x) & 0x00000001) >> 0)
-#define PHY_BB_TPC_20_ENABLE_PAL_MCS_0_SET(x)                                  (((x) << 0) & 0x00000001)
-#define PHY_BB_TPC_20_ENABLE_PAL_MCS_1_MSB                                                             1
-#define PHY_BB_TPC_20_ENABLE_PAL_MCS_1_LSB                                                             1
-#define PHY_BB_TPC_20_ENABLE_PAL_MCS_1_MASK                                                   0x00000002
-#define PHY_BB_TPC_20_ENABLE_PAL_MCS_1_GET(x)                                  (((x) & 0x00000002) >> 1)
-#define PHY_BB_TPC_20_ENABLE_PAL_MCS_1_SET(x)                                  (((x) << 1) & 0x00000002)
-#define PHY_BB_TPC_20_ENABLE_PAL_MCS_2_MSB                                                             2
-#define PHY_BB_TPC_20_ENABLE_PAL_MCS_2_LSB                                                             2
-#define PHY_BB_TPC_20_ENABLE_PAL_MCS_2_MASK                                                   0x00000004
-#define PHY_BB_TPC_20_ENABLE_PAL_MCS_2_GET(x)                                  (((x) & 0x00000004) >> 2)
-#define PHY_BB_TPC_20_ENABLE_PAL_MCS_2_SET(x)                                  (((x) << 2) & 0x00000004)
-#define PHY_BB_TPC_20_ENABLE_PAL_MCS_3_MSB                                                             3
-#define PHY_BB_TPC_20_ENABLE_PAL_MCS_3_LSB                                                             3
-#define PHY_BB_TPC_20_ENABLE_PAL_MCS_3_MASK                                                   0x00000008
-#define PHY_BB_TPC_20_ENABLE_PAL_MCS_3_GET(x)                                  (((x) & 0x00000008) >> 3)
-#define PHY_BB_TPC_20_ENABLE_PAL_MCS_3_SET(x)                                  (((x) << 3) & 0x00000008)
-#define PHY_BB_TPC_20_ENABLE_PAL_MCS_4_MSB                                                             4
-#define PHY_BB_TPC_20_ENABLE_PAL_MCS_4_LSB                                                             4
-#define PHY_BB_TPC_20_ENABLE_PAL_MCS_4_MASK                                                   0x00000010
-#define PHY_BB_TPC_20_ENABLE_PAL_MCS_4_GET(x)                                  (((x) & 0x00000010) >> 4)
-#define PHY_BB_TPC_20_ENABLE_PAL_MCS_4_SET(x)                                  (((x) << 4) & 0x00000010)
-#define PHY_BB_TPC_20_ENABLE_PAL_MCS_5_MSB                                                             5
-#define PHY_BB_TPC_20_ENABLE_PAL_MCS_5_LSB                                                             5
-#define PHY_BB_TPC_20_ENABLE_PAL_MCS_5_MASK                                                   0x00000020
-#define PHY_BB_TPC_20_ENABLE_PAL_MCS_5_GET(x)                                  (((x) & 0x00000020) >> 5)
-#define PHY_BB_TPC_20_ENABLE_PAL_MCS_5_SET(x)                                  (((x) << 5) & 0x00000020)
-#define PHY_BB_TPC_20_ENABLE_PAL_MCS_6_MSB                                                             6
-#define PHY_BB_TPC_20_ENABLE_PAL_MCS_6_LSB                                                             6
-#define PHY_BB_TPC_20_ENABLE_PAL_MCS_6_MASK                                                   0x00000040
-#define PHY_BB_TPC_20_ENABLE_PAL_MCS_6_GET(x)                                  (((x) & 0x00000040) >> 6)
-#define PHY_BB_TPC_20_ENABLE_PAL_MCS_6_SET(x)                                  (((x) << 6) & 0x00000040)
-#define PHY_BB_TPC_20_ENABLE_PAL_MCS_7_MSB                                                             7
-#define PHY_BB_TPC_20_ENABLE_PAL_MCS_7_LSB                                                             7
-#define PHY_BB_TPC_20_ENABLE_PAL_MCS_7_MASK                                                   0x00000080
-#define PHY_BB_TPC_20_ENABLE_PAL_MCS_7_GET(x)                                  (((x) & 0x00000080) >> 7)
-#define PHY_BB_TPC_20_ENABLE_PAL_MCS_7_SET(x)                                  (((x) << 7) & 0x00000080)
-#define PHY_BB_TPC_20_ENABLE_PAL_MCS_8_MSB                                                             8
-#define PHY_BB_TPC_20_ENABLE_PAL_MCS_8_LSB                                                             8
-#define PHY_BB_TPC_20_ENABLE_PAL_MCS_8_MASK                                                   0x00000100
-#define PHY_BB_TPC_20_ENABLE_PAL_MCS_8_GET(x)                                  (((x) & 0x00000100) >> 8)
-#define PHY_BB_TPC_20_ENABLE_PAL_MCS_8_SET(x)                                  (((x) << 8) & 0x00000100)
-#define PHY_BB_TPC_20_ENABLE_PAL_MCS_9_MSB                                                             9
-#define PHY_BB_TPC_20_ENABLE_PAL_MCS_9_LSB                                                             9
-#define PHY_BB_TPC_20_ENABLE_PAL_MCS_9_MASK                                                   0x00000200
-#define PHY_BB_TPC_20_ENABLE_PAL_MCS_9_GET(x)                                  (((x) & 0x00000200) >> 9)
-#define PHY_BB_TPC_20_ENABLE_PAL_MCS_9_SET(x)                                  (((x) << 9) & 0x00000200)
-#define PHY_BB_TPC_20_ENABLE_PAL_MCS_10_MSB                                                           10
-#define PHY_BB_TPC_20_ENABLE_PAL_MCS_10_LSB                                                           10
-#define PHY_BB_TPC_20_ENABLE_PAL_MCS_10_MASK                                                  0x00000400
-#define PHY_BB_TPC_20_ENABLE_PAL_MCS_10_GET(x)                                (((x) & 0x00000400) >> 10)
-#define PHY_BB_TPC_20_ENABLE_PAL_MCS_10_SET(x)                                (((x) << 10) & 0x00000400)
-#define PHY_BB_TPC_20_ENABLE_PAL_MCS_11_MSB                                                           11
-#define PHY_BB_TPC_20_ENABLE_PAL_MCS_11_LSB                                                           11
-#define PHY_BB_TPC_20_ENABLE_PAL_MCS_11_MASK                                                  0x00000800
-#define PHY_BB_TPC_20_ENABLE_PAL_MCS_11_GET(x)                                (((x) & 0x00000800) >> 11)
-#define PHY_BB_TPC_20_ENABLE_PAL_MCS_11_SET(x)                                (((x) << 11) & 0x00000800)
-#define PHY_BB_TPC_20_ENABLE_PAL_MCS_12_MSB                                                           12
-#define PHY_BB_TPC_20_ENABLE_PAL_MCS_12_LSB                                                           12
-#define PHY_BB_TPC_20_ENABLE_PAL_MCS_12_MASK                                                  0x00001000
-#define PHY_BB_TPC_20_ENABLE_PAL_MCS_12_GET(x)                                (((x) & 0x00001000) >> 12)
-#define PHY_BB_TPC_20_ENABLE_PAL_MCS_12_SET(x)                                (((x) << 12) & 0x00001000)
-#define PHY_BB_TPC_20_ENABLE_PAL_MCS_13_MSB                                                           13
-#define PHY_BB_TPC_20_ENABLE_PAL_MCS_13_LSB                                                           13
-#define PHY_BB_TPC_20_ENABLE_PAL_MCS_13_MASK                                                  0x00002000
-#define PHY_BB_TPC_20_ENABLE_PAL_MCS_13_GET(x)                                (((x) & 0x00002000) >> 13)
-#define PHY_BB_TPC_20_ENABLE_PAL_MCS_13_SET(x)                                (((x) << 13) & 0x00002000)
-#define PHY_BB_TPC_20_ENABLE_PAL_MCS_14_MSB                                                           14
-#define PHY_BB_TPC_20_ENABLE_PAL_MCS_14_LSB                                                           14
-#define PHY_BB_TPC_20_ENABLE_PAL_MCS_14_MASK                                                  0x00004000
-#define PHY_BB_TPC_20_ENABLE_PAL_MCS_14_GET(x)                                (((x) & 0x00004000) >> 14)
-#define PHY_BB_TPC_20_ENABLE_PAL_MCS_14_SET(x)                                (((x) << 14) & 0x00004000)
-#define PHY_BB_TPC_20_ENABLE_PAL_MCS_15_MSB                                                           15
-#define PHY_BB_TPC_20_ENABLE_PAL_MCS_15_LSB                                                           15
-#define PHY_BB_TPC_20_ENABLE_PAL_MCS_15_MASK                                                  0x00008000
-#define PHY_BB_TPC_20_ENABLE_PAL_MCS_15_GET(x)                                (((x) & 0x00008000) >> 15)
-#define PHY_BB_TPC_20_ENABLE_PAL_MCS_15_SET(x)                                (((x) << 15) & 0x00008000)
-#define PHY_BB_TPC_20_ENABLE_PAL_MCS_16_MSB                                                           16
-#define PHY_BB_TPC_20_ENABLE_PAL_MCS_16_LSB                                                           16
-#define PHY_BB_TPC_20_ENABLE_PAL_MCS_16_MASK                                                  0x00010000
-#define PHY_BB_TPC_20_ENABLE_PAL_MCS_16_GET(x)                                (((x) & 0x00010000) >> 16)
-#define PHY_BB_TPC_20_ENABLE_PAL_MCS_16_SET(x)                                (((x) << 16) & 0x00010000)
-#define PHY_BB_TPC_20_ENABLE_PAL_MCS_17_MSB                                                           17
-#define PHY_BB_TPC_20_ENABLE_PAL_MCS_17_LSB                                                           17
-#define PHY_BB_TPC_20_ENABLE_PAL_MCS_17_MASK                                                  0x00020000
-#define PHY_BB_TPC_20_ENABLE_PAL_MCS_17_GET(x)                                (((x) & 0x00020000) >> 17)
-#define PHY_BB_TPC_20_ENABLE_PAL_MCS_17_SET(x)                                (((x) << 17) & 0x00020000)
-#define PHY_BB_TPC_20_ENABLE_PAL_MCS_18_MSB                                                           18
-#define PHY_BB_TPC_20_ENABLE_PAL_MCS_18_LSB                                                           18
-#define PHY_BB_TPC_20_ENABLE_PAL_MCS_18_MASK                                                  0x00040000
-#define PHY_BB_TPC_20_ENABLE_PAL_MCS_18_GET(x)                                (((x) & 0x00040000) >> 18)
-#define PHY_BB_TPC_20_ENABLE_PAL_MCS_18_SET(x)                                (((x) << 18) & 0x00040000)
-#define PHY_BB_TPC_20_ENABLE_PAL_MCS_19_MSB                                                           19
-#define PHY_BB_TPC_20_ENABLE_PAL_MCS_19_LSB                                                           19
-#define PHY_BB_TPC_20_ENABLE_PAL_MCS_19_MASK                                                  0x00080000
-#define PHY_BB_TPC_20_ENABLE_PAL_MCS_19_GET(x)                                (((x) & 0x00080000) >> 19)
-#define PHY_BB_TPC_20_ENABLE_PAL_MCS_19_SET(x)                                (((x) << 19) & 0x00080000)
-#define PHY_BB_TPC_20_ENABLE_PAL_MCS_20_MSB                                                           20
-#define PHY_BB_TPC_20_ENABLE_PAL_MCS_20_LSB                                                           20
-#define PHY_BB_TPC_20_ENABLE_PAL_MCS_20_MASK                                                  0x00100000
-#define PHY_BB_TPC_20_ENABLE_PAL_MCS_20_GET(x)                                (((x) & 0x00100000) >> 20)
-#define PHY_BB_TPC_20_ENABLE_PAL_MCS_20_SET(x)                                (((x) << 20) & 0x00100000)
-#define PHY_BB_TPC_20_ENABLE_PAL_MCS_21_MSB                                                           21
-#define PHY_BB_TPC_20_ENABLE_PAL_MCS_21_LSB                                                           21
-#define PHY_BB_TPC_20_ENABLE_PAL_MCS_21_MASK                                                  0x00200000
-#define PHY_BB_TPC_20_ENABLE_PAL_MCS_21_GET(x)                                (((x) & 0x00200000) >> 21)
-#define PHY_BB_TPC_20_ENABLE_PAL_MCS_21_SET(x)                                (((x) << 21) & 0x00200000)
-#define PHY_BB_TPC_20_ENABLE_PAL_MCS_22_MSB                                                           22
-#define PHY_BB_TPC_20_ENABLE_PAL_MCS_22_LSB                                                           22
-#define PHY_BB_TPC_20_ENABLE_PAL_MCS_22_MASK                                                  0x00400000
-#define PHY_BB_TPC_20_ENABLE_PAL_MCS_22_GET(x)                                (((x) & 0x00400000) >> 22)
-#define PHY_BB_TPC_20_ENABLE_PAL_MCS_22_SET(x)                                (((x) << 22) & 0x00400000)
-#define PHY_BB_TPC_20_ENABLE_PAL_MCS_23_MSB                                                           23
-#define PHY_BB_TPC_20_ENABLE_PAL_MCS_23_LSB                                                           23
-#define PHY_BB_TPC_20_ENABLE_PAL_MCS_23_MASK                                                  0x00800000
-#define PHY_BB_TPC_20_ENABLE_PAL_MCS_23_GET(x)                                (((x) & 0x00800000) >> 23)
-#define PHY_BB_TPC_20_ENABLE_PAL_MCS_23_SET(x)                                (((x) << 23) & 0x00800000)
-
-/* macros for BB_tx_gain_tab_1 */
-#define PHY_BB_TX_GAIN_TAB_1_ADDRESS                                                          0x0000a400
-#define PHY_BB_TX_GAIN_TAB_1_OFFSET                                                           0x0000a400
-#define PHY_BB_TX_GAIN_TAB_1_TG_TABLE1_MSB                                                            31
-#define PHY_BB_TX_GAIN_TAB_1_TG_TABLE1_LSB                                                             0
-#define PHY_BB_TX_GAIN_TAB_1_TG_TABLE1_MASK                                                   0xffffffff
-#define PHY_BB_TX_GAIN_TAB_1_TG_TABLE1_GET(x)                                  (((x) & 0xffffffff) >> 0)
-#define PHY_BB_TX_GAIN_TAB_1_TG_TABLE1_SET(x)                                  (((x) << 0) & 0xffffffff)
-
-/* macros for BB_tx_gain_tab_2 */
-#define PHY_BB_TX_GAIN_TAB_2_ADDRESS                                                          0x0000a404
-#define PHY_BB_TX_GAIN_TAB_2_OFFSET                                                           0x0000a404
-#define PHY_BB_TX_GAIN_TAB_2_TG_TABLE2_MSB                                                            31
-#define PHY_BB_TX_GAIN_TAB_2_TG_TABLE2_LSB                                                             0
-#define PHY_BB_TX_GAIN_TAB_2_TG_TABLE2_MASK                                                   0xffffffff
-#define PHY_BB_TX_GAIN_TAB_2_TG_TABLE2_GET(x)                                  (((x) & 0xffffffff) >> 0)
-#define PHY_BB_TX_GAIN_TAB_2_TG_TABLE2_SET(x)                                  (((x) << 0) & 0xffffffff)
-
-/* macros for BB_tx_gain_tab_3 */
-#define PHY_BB_TX_GAIN_TAB_3_ADDRESS                                                          0x0000a408
-#define PHY_BB_TX_GAIN_TAB_3_OFFSET                                                           0x0000a408
-#define PHY_BB_TX_GAIN_TAB_3_TG_TABLE3_MSB                                                            31
-#define PHY_BB_TX_GAIN_TAB_3_TG_TABLE3_LSB                                                             0
-#define PHY_BB_TX_GAIN_TAB_3_TG_TABLE3_MASK                                                   0xffffffff
-#define PHY_BB_TX_GAIN_TAB_3_TG_TABLE3_GET(x)                                  (((x) & 0xffffffff) >> 0)
-#define PHY_BB_TX_GAIN_TAB_3_TG_TABLE3_SET(x)                                  (((x) << 0) & 0xffffffff)
-
-/* macros for BB_tx_gain_tab_4 */
-#define PHY_BB_TX_GAIN_TAB_4_ADDRESS                                                          0x0000a40c
-#define PHY_BB_TX_GAIN_TAB_4_OFFSET                                                           0x0000a40c
-#define PHY_BB_TX_GAIN_TAB_4_TG_TABLE4_MSB                                                            31
-#define PHY_BB_TX_GAIN_TAB_4_TG_TABLE4_LSB                                                             0
-#define PHY_BB_TX_GAIN_TAB_4_TG_TABLE4_MASK                                                   0xffffffff
-#define PHY_BB_TX_GAIN_TAB_4_TG_TABLE4_GET(x)                                  (((x) & 0xffffffff) >> 0)
-#define PHY_BB_TX_GAIN_TAB_4_TG_TABLE4_SET(x)                                  (((x) << 0) & 0xffffffff)
-
-/* macros for BB_tx_gain_tab_5 */
-#define PHY_BB_TX_GAIN_TAB_5_ADDRESS                                                          0x0000a410
-#define PHY_BB_TX_GAIN_TAB_5_OFFSET                                                           0x0000a410
-#define PHY_BB_TX_GAIN_TAB_5_TG_TABLE5_MSB                                                            31
-#define PHY_BB_TX_GAIN_TAB_5_TG_TABLE5_LSB                                                             0
-#define PHY_BB_TX_GAIN_TAB_5_TG_TABLE5_MASK                                                   0xffffffff
-#define PHY_BB_TX_GAIN_TAB_5_TG_TABLE5_GET(x)                                  (((x) & 0xffffffff) >> 0)
-#define PHY_BB_TX_GAIN_TAB_5_TG_TABLE5_SET(x)                                  (((x) << 0) & 0xffffffff)
-
-/* macros for BB_tx_gain_tab_6 */
-#define PHY_BB_TX_GAIN_TAB_6_ADDRESS                                                          0x0000a414
-#define PHY_BB_TX_GAIN_TAB_6_OFFSET                                                           0x0000a414
-#define PHY_BB_TX_GAIN_TAB_6_TG_TABLE6_MSB                                                            31
-#define PHY_BB_TX_GAIN_TAB_6_TG_TABLE6_LSB                                                             0
-#define PHY_BB_TX_GAIN_TAB_6_TG_TABLE6_MASK                                                   0xffffffff
-#define PHY_BB_TX_GAIN_TAB_6_TG_TABLE6_GET(x)                                  (((x) & 0xffffffff) >> 0)
-#define PHY_BB_TX_GAIN_TAB_6_TG_TABLE6_SET(x)                                  (((x) << 0) & 0xffffffff)
-
-/* macros for BB_tx_gain_tab_7 */
-#define PHY_BB_TX_GAIN_TAB_7_ADDRESS                                                          0x0000a418
-#define PHY_BB_TX_GAIN_TAB_7_OFFSET                                                           0x0000a418
-#define PHY_BB_TX_GAIN_TAB_7_TG_TABLE7_MSB                                                            31
-#define PHY_BB_TX_GAIN_TAB_7_TG_TABLE7_LSB                                                             0
-#define PHY_BB_TX_GAIN_TAB_7_TG_TABLE7_MASK                                                   0xffffffff
-#define PHY_BB_TX_GAIN_TAB_7_TG_TABLE7_GET(x)                                  (((x) & 0xffffffff) >> 0)
-#define PHY_BB_TX_GAIN_TAB_7_TG_TABLE7_SET(x)                                  (((x) << 0) & 0xffffffff)
-
-/* macros for BB_tx_gain_tab_8 */
-#define PHY_BB_TX_GAIN_TAB_8_ADDRESS                                                          0x0000a41c
-#define PHY_BB_TX_GAIN_TAB_8_OFFSET                                                           0x0000a41c
-#define PHY_BB_TX_GAIN_TAB_8_TG_TABLE8_MSB                                                            31
-#define PHY_BB_TX_GAIN_TAB_8_TG_TABLE8_LSB                                                             0
-#define PHY_BB_TX_GAIN_TAB_8_TG_TABLE8_MASK                                                   0xffffffff
-#define PHY_BB_TX_GAIN_TAB_8_TG_TABLE8_GET(x)                                  (((x) & 0xffffffff) >> 0)
-#define PHY_BB_TX_GAIN_TAB_8_TG_TABLE8_SET(x)                                  (((x) << 0) & 0xffffffff)
-
-/* macros for BB_tx_gain_tab_9 */
-#define PHY_BB_TX_GAIN_TAB_9_ADDRESS                                                          0x0000a420
-#define PHY_BB_TX_GAIN_TAB_9_OFFSET                                                           0x0000a420
-#define PHY_BB_TX_GAIN_TAB_9_TG_TABLE9_MSB                                                            31
-#define PHY_BB_TX_GAIN_TAB_9_TG_TABLE9_LSB                                                             0
-#define PHY_BB_TX_GAIN_TAB_9_TG_TABLE9_MASK                                                   0xffffffff
-#define PHY_BB_TX_GAIN_TAB_9_TG_TABLE9_GET(x)                                  (((x) & 0xffffffff) >> 0)
-#define PHY_BB_TX_GAIN_TAB_9_TG_TABLE9_SET(x)                                  (((x) << 0) & 0xffffffff)
-
-/* macros for BB_tx_gain_tab_10 */
-#define PHY_BB_TX_GAIN_TAB_10_ADDRESS                                                         0x0000a424
-#define PHY_BB_TX_GAIN_TAB_10_OFFSET                                                          0x0000a424
-#define PHY_BB_TX_GAIN_TAB_10_TG_TABLE10_MSB                                                          31
-#define PHY_BB_TX_GAIN_TAB_10_TG_TABLE10_LSB                                                           0
-#define PHY_BB_TX_GAIN_TAB_10_TG_TABLE10_MASK                                                 0xffffffff
-#define PHY_BB_TX_GAIN_TAB_10_TG_TABLE10_GET(x)                                (((x) & 0xffffffff) >> 0)
-#define PHY_BB_TX_GAIN_TAB_10_TG_TABLE10_SET(x)                                (((x) << 0) & 0xffffffff)
-
-/* macros for BB_tx_gain_tab_11 */
-#define PHY_BB_TX_GAIN_TAB_11_ADDRESS                                                         0x0000a428
-#define PHY_BB_TX_GAIN_TAB_11_OFFSET                                                          0x0000a428
-#define PHY_BB_TX_GAIN_TAB_11_TG_TABLE11_MSB                                                          31
-#define PHY_BB_TX_GAIN_TAB_11_TG_TABLE11_LSB                                                           0
-#define PHY_BB_TX_GAIN_TAB_11_TG_TABLE11_MASK                                                 0xffffffff
-#define PHY_BB_TX_GAIN_TAB_11_TG_TABLE11_GET(x)                                (((x) & 0xffffffff) >> 0)
-#define PHY_BB_TX_GAIN_TAB_11_TG_TABLE11_SET(x)                                (((x) << 0) & 0xffffffff)
-
-/* macros for BB_tx_gain_tab_12 */
-#define PHY_BB_TX_GAIN_TAB_12_ADDRESS                                                         0x0000a42c
-#define PHY_BB_TX_GAIN_TAB_12_OFFSET                                                          0x0000a42c
-#define PHY_BB_TX_GAIN_TAB_12_TG_TABLE12_MSB                                                          31
-#define PHY_BB_TX_GAIN_TAB_12_TG_TABLE12_LSB                                                           0
-#define PHY_BB_TX_GAIN_TAB_12_TG_TABLE12_MASK                                                 0xffffffff
-#define PHY_BB_TX_GAIN_TAB_12_TG_TABLE12_GET(x)                                (((x) & 0xffffffff) >> 0)
-#define PHY_BB_TX_GAIN_TAB_12_TG_TABLE12_SET(x)                                (((x) << 0) & 0xffffffff)
-
-/* macros for BB_tx_gain_tab_13 */
-#define PHY_BB_TX_GAIN_TAB_13_ADDRESS                                                         0x0000a430
-#define PHY_BB_TX_GAIN_TAB_13_OFFSET                                                          0x0000a430
-#define PHY_BB_TX_GAIN_TAB_13_TG_TABLE13_MSB                                                          31
-#define PHY_BB_TX_GAIN_TAB_13_TG_TABLE13_LSB                                                           0
-#define PHY_BB_TX_GAIN_TAB_13_TG_TABLE13_MASK                                                 0xffffffff
-#define PHY_BB_TX_GAIN_TAB_13_TG_TABLE13_GET(x)                                (((x) & 0xffffffff) >> 0)
-#define PHY_BB_TX_GAIN_TAB_13_TG_TABLE13_SET(x)                                (((x) << 0) & 0xffffffff)
-
-/* macros for BB_tx_gain_tab_14 */
-#define PHY_BB_TX_GAIN_TAB_14_ADDRESS                                                         0x0000a434
-#define PHY_BB_TX_GAIN_TAB_14_OFFSET                                                          0x0000a434
-#define PHY_BB_TX_GAIN_TAB_14_TG_TABLE14_MSB                                                          31
-#define PHY_BB_TX_GAIN_TAB_14_TG_TABLE14_LSB                                                           0
-#define PHY_BB_TX_GAIN_TAB_14_TG_TABLE14_MASK                                                 0xffffffff
-#define PHY_BB_TX_GAIN_TAB_14_TG_TABLE14_GET(x)                                (((x) & 0xffffffff) >> 0)
-#define PHY_BB_TX_GAIN_TAB_14_TG_TABLE14_SET(x)                                (((x) << 0) & 0xffffffff)
-
-/* macros for BB_tx_gain_tab_15 */
-#define PHY_BB_TX_GAIN_TAB_15_ADDRESS                                                         0x0000a438
-#define PHY_BB_TX_GAIN_TAB_15_OFFSET                                                          0x0000a438
-#define PHY_BB_TX_GAIN_TAB_15_TG_TABLE15_MSB                                                          31
-#define PHY_BB_TX_GAIN_TAB_15_TG_TABLE15_LSB                                                           0
-#define PHY_BB_TX_GAIN_TAB_15_TG_TABLE15_MASK                                                 0xffffffff
-#define PHY_BB_TX_GAIN_TAB_15_TG_TABLE15_GET(x)                                (((x) & 0xffffffff) >> 0)
-#define PHY_BB_TX_GAIN_TAB_15_TG_TABLE15_SET(x)                                (((x) << 0) & 0xffffffff)
-
-/* macros for BB_tx_gain_tab_16 */
-#define PHY_BB_TX_GAIN_TAB_16_ADDRESS                                                         0x0000a43c
-#define PHY_BB_TX_GAIN_TAB_16_OFFSET                                                          0x0000a43c
-#define PHY_BB_TX_GAIN_TAB_16_TG_TABLE16_MSB                                                          31
-#define PHY_BB_TX_GAIN_TAB_16_TG_TABLE16_LSB                                                           0
-#define PHY_BB_TX_GAIN_TAB_16_TG_TABLE16_MASK                                                 0xffffffff
-#define PHY_BB_TX_GAIN_TAB_16_TG_TABLE16_GET(x)                                (((x) & 0xffffffff) >> 0)
-#define PHY_BB_TX_GAIN_TAB_16_TG_TABLE16_SET(x)                                (((x) << 0) & 0xffffffff)
-
-/* macros for BB_tx_gain_tab_17 */
-#define PHY_BB_TX_GAIN_TAB_17_ADDRESS                                                         0x0000a440
-#define PHY_BB_TX_GAIN_TAB_17_OFFSET                                                          0x0000a440
-#define PHY_BB_TX_GAIN_TAB_17_TG_TABLE17_MSB                                                          31
-#define PHY_BB_TX_GAIN_TAB_17_TG_TABLE17_LSB                                                           0
-#define PHY_BB_TX_GAIN_TAB_17_TG_TABLE17_MASK                                                 0xffffffff
-#define PHY_BB_TX_GAIN_TAB_17_TG_TABLE17_GET(x)                                (((x) & 0xffffffff) >> 0)
-#define PHY_BB_TX_GAIN_TAB_17_TG_TABLE17_SET(x)                                (((x) << 0) & 0xffffffff)
-
-/* macros for BB_tx_gain_tab_18 */
-#define PHY_BB_TX_GAIN_TAB_18_ADDRESS                                                         0x0000a444
-#define PHY_BB_TX_GAIN_TAB_18_OFFSET                                                          0x0000a444
-#define PHY_BB_TX_GAIN_TAB_18_TG_TABLE18_MSB                                                          31
-#define PHY_BB_TX_GAIN_TAB_18_TG_TABLE18_LSB                                                           0
-#define PHY_BB_TX_GAIN_TAB_18_TG_TABLE18_MASK                                                 0xffffffff
-#define PHY_BB_TX_GAIN_TAB_18_TG_TABLE18_GET(x)                                (((x) & 0xffffffff) >> 0)
-#define PHY_BB_TX_GAIN_TAB_18_TG_TABLE18_SET(x)                                (((x) << 0) & 0xffffffff)
-
-/* macros for BB_tx_gain_tab_19 */
-#define PHY_BB_TX_GAIN_TAB_19_ADDRESS                                                         0x0000a448
-#define PHY_BB_TX_GAIN_TAB_19_OFFSET                                                          0x0000a448
-#define PHY_BB_TX_GAIN_TAB_19_TG_TABLE19_MSB                                                          31
-#define PHY_BB_TX_GAIN_TAB_19_TG_TABLE19_LSB                                                           0
-#define PHY_BB_TX_GAIN_TAB_19_TG_TABLE19_MASK                                                 0xffffffff
-#define PHY_BB_TX_GAIN_TAB_19_TG_TABLE19_GET(x)                                (((x) & 0xffffffff) >> 0)
-#define PHY_BB_TX_GAIN_TAB_19_TG_TABLE19_SET(x)                                (((x) << 0) & 0xffffffff)
-
-/* macros for BB_tx_gain_tab_20 */
-#define PHY_BB_TX_GAIN_TAB_20_ADDRESS                                                         0x0000a44c
-#define PHY_BB_TX_GAIN_TAB_20_OFFSET                                                          0x0000a44c
-#define PHY_BB_TX_GAIN_TAB_20_TG_TABLE20_MSB                                                          31
-#define PHY_BB_TX_GAIN_TAB_20_TG_TABLE20_LSB                                                           0
-#define PHY_BB_TX_GAIN_TAB_20_TG_TABLE20_MASK                                                 0xffffffff
-#define PHY_BB_TX_GAIN_TAB_20_TG_TABLE20_GET(x)                                (((x) & 0xffffffff) >> 0)
-#define PHY_BB_TX_GAIN_TAB_20_TG_TABLE20_SET(x)                                (((x) << 0) & 0xffffffff)
-
-/* macros for BB_tx_gain_tab_21 */
-#define PHY_BB_TX_GAIN_TAB_21_ADDRESS                                                         0x0000a450
-#define PHY_BB_TX_GAIN_TAB_21_OFFSET                                                          0x0000a450
-#define PHY_BB_TX_GAIN_TAB_21_TG_TABLE21_MSB                                                          31
-#define PHY_BB_TX_GAIN_TAB_21_TG_TABLE21_LSB                                                           0
-#define PHY_BB_TX_GAIN_TAB_21_TG_TABLE21_MASK                                                 0xffffffff
-#define PHY_BB_TX_GAIN_TAB_21_TG_TABLE21_GET(x)                                (((x) & 0xffffffff) >> 0)
-#define PHY_BB_TX_GAIN_TAB_21_TG_TABLE21_SET(x)                                (((x) << 0) & 0xffffffff)
-
-/* macros for BB_tx_gain_tab_22 */
-#define PHY_BB_TX_GAIN_TAB_22_ADDRESS                                                         0x0000a454
-#define PHY_BB_TX_GAIN_TAB_22_OFFSET                                                          0x0000a454
-#define PHY_BB_TX_GAIN_TAB_22_TG_TABLE22_MSB                                                          31
-#define PHY_BB_TX_GAIN_TAB_22_TG_TABLE22_LSB                                                           0
-#define PHY_BB_TX_GAIN_TAB_22_TG_TABLE22_MASK                                                 0xffffffff
-#define PHY_BB_TX_GAIN_TAB_22_TG_TABLE22_GET(x)                                (((x) & 0xffffffff) >> 0)
-#define PHY_BB_TX_GAIN_TAB_22_TG_TABLE22_SET(x)                                (((x) << 0) & 0xffffffff)
-
-/* macros for BB_tx_gain_tab_23 */
-#define PHY_BB_TX_GAIN_TAB_23_ADDRESS                                                         0x0000a458
-#define PHY_BB_TX_GAIN_TAB_23_OFFSET                                                          0x0000a458
-#define PHY_BB_TX_GAIN_TAB_23_TG_TABLE23_MSB                                                          31
-#define PHY_BB_TX_GAIN_TAB_23_TG_TABLE23_LSB                                                           0
-#define PHY_BB_TX_GAIN_TAB_23_TG_TABLE23_MASK                                                 0xffffffff
-#define PHY_BB_TX_GAIN_TAB_23_TG_TABLE23_GET(x)                                (((x) & 0xffffffff) >> 0)
-#define PHY_BB_TX_GAIN_TAB_23_TG_TABLE23_SET(x)                                (((x) << 0) & 0xffffffff)
-
-/* macros for BB_tx_gain_tab_24 */
-#define PHY_BB_TX_GAIN_TAB_24_ADDRESS                                                         0x0000a45c
-#define PHY_BB_TX_GAIN_TAB_24_OFFSET                                                          0x0000a45c
-#define PHY_BB_TX_GAIN_TAB_24_TG_TABLE24_MSB                                                          31
-#define PHY_BB_TX_GAIN_TAB_24_TG_TABLE24_LSB                                                           0
-#define PHY_BB_TX_GAIN_TAB_24_TG_TABLE24_MASK                                                 0xffffffff
-#define PHY_BB_TX_GAIN_TAB_24_TG_TABLE24_GET(x)                                (((x) & 0xffffffff) >> 0)
-#define PHY_BB_TX_GAIN_TAB_24_TG_TABLE24_SET(x)                                (((x) << 0) & 0xffffffff)
-
-/* macros for BB_tx_gain_tab_25 */
-#define PHY_BB_TX_GAIN_TAB_25_ADDRESS                                                         0x0000a460
-#define PHY_BB_TX_GAIN_TAB_25_OFFSET                                                          0x0000a460
-#define PHY_BB_TX_GAIN_TAB_25_TG_TABLE25_MSB                                                          31
-#define PHY_BB_TX_GAIN_TAB_25_TG_TABLE25_LSB                                                           0
-#define PHY_BB_TX_GAIN_TAB_25_TG_TABLE25_MASK                                                 0xffffffff
-#define PHY_BB_TX_GAIN_TAB_25_TG_TABLE25_GET(x)                                (((x) & 0xffffffff) >> 0)
-#define PHY_BB_TX_GAIN_TAB_25_TG_TABLE25_SET(x)                                (((x) << 0) & 0xffffffff)
-
-/* macros for BB_tx_gain_tab_26 */
-#define PHY_BB_TX_GAIN_TAB_26_ADDRESS                                                         0x0000a464
-#define PHY_BB_TX_GAIN_TAB_26_OFFSET                                                          0x0000a464
-#define PHY_BB_TX_GAIN_TAB_26_TG_TABLE26_MSB                                                          31
-#define PHY_BB_TX_GAIN_TAB_26_TG_TABLE26_LSB                                                           0
-#define PHY_BB_TX_GAIN_TAB_26_TG_TABLE26_MASK                                                 0xffffffff
-#define PHY_BB_TX_GAIN_TAB_26_TG_TABLE26_GET(x)                                (((x) & 0xffffffff) >> 0)
-#define PHY_BB_TX_GAIN_TAB_26_TG_TABLE26_SET(x)                                (((x) << 0) & 0xffffffff)
-
-/* macros for BB_tx_gain_tab_27 */
-#define PHY_BB_TX_GAIN_TAB_27_ADDRESS                                                         0x0000a468
-#define PHY_BB_TX_GAIN_TAB_27_OFFSET                                                          0x0000a468
-#define PHY_BB_TX_GAIN_TAB_27_TG_TABLE27_MSB                                                          31
-#define PHY_BB_TX_GAIN_TAB_27_TG_TABLE27_LSB                                                           0
-#define PHY_BB_TX_GAIN_TAB_27_TG_TABLE27_MASK                                                 0xffffffff
-#define PHY_BB_TX_GAIN_TAB_27_TG_TABLE27_GET(x)                                (((x) & 0xffffffff) >> 0)
-#define PHY_BB_TX_GAIN_TAB_27_TG_TABLE27_SET(x)                                (((x) << 0) & 0xffffffff)
-
-/* macros for BB_tx_gain_tab_28 */
-#define PHY_BB_TX_GAIN_TAB_28_ADDRESS                                                         0x0000a46c
-#define PHY_BB_TX_GAIN_TAB_28_OFFSET                                                          0x0000a46c
-#define PHY_BB_TX_GAIN_TAB_28_TG_TABLE28_MSB                                                          31
-#define PHY_BB_TX_GAIN_TAB_28_TG_TABLE28_LSB                                                           0
-#define PHY_BB_TX_GAIN_TAB_28_TG_TABLE28_MASK                                                 0xffffffff
-#define PHY_BB_TX_GAIN_TAB_28_TG_TABLE28_GET(x)                                (((x) & 0xffffffff) >> 0)
-#define PHY_BB_TX_GAIN_TAB_28_TG_TABLE28_SET(x)                                (((x) << 0) & 0xffffffff)
-
-/* macros for BB_tx_gain_tab_29 */
-#define PHY_BB_TX_GAIN_TAB_29_ADDRESS                                                         0x0000a470
-#define PHY_BB_TX_GAIN_TAB_29_OFFSET                                                          0x0000a470
-#define PHY_BB_TX_GAIN_TAB_29_TG_TABLE29_MSB                                                          31
-#define PHY_BB_TX_GAIN_TAB_29_TG_TABLE29_LSB                                                           0
-#define PHY_BB_TX_GAIN_TAB_29_TG_TABLE29_MASK                                                 0xffffffff
-#define PHY_BB_TX_GAIN_TAB_29_TG_TABLE29_GET(x)                                (((x) & 0xffffffff) >> 0)
-#define PHY_BB_TX_GAIN_TAB_29_TG_TABLE29_SET(x)                                (((x) << 0) & 0xffffffff)
-
-/* macros for BB_tx_gain_tab_30 */
-#define PHY_BB_TX_GAIN_TAB_30_ADDRESS                                                         0x0000a474
-#define PHY_BB_TX_GAIN_TAB_30_OFFSET                                                          0x0000a474
-#define PHY_BB_TX_GAIN_TAB_30_TG_TABLE30_MSB                                                          31
-#define PHY_BB_TX_GAIN_TAB_30_TG_TABLE30_LSB                                                           0
-#define PHY_BB_TX_GAIN_TAB_30_TG_TABLE30_MASK                                                 0xffffffff
-#define PHY_BB_TX_GAIN_TAB_30_TG_TABLE30_GET(x)                                (((x) & 0xffffffff) >> 0)
-#define PHY_BB_TX_GAIN_TAB_30_TG_TABLE30_SET(x)                                (((x) << 0) & 0xffffffff)
-
-/* macros for BB_tx_gain_tab_31 */
-#define PHY_BB_TX_GAIN_TAB_31_ADDRESS                                                         0x0000a478
-#define PHY_BB_TX_GAIN_TAB_31_OFFSET                                                          0x0000a478
-#define PHY_BB_TX_GAIN_TAB_31_TG_TABLE31_MSB                                                          31
-#define PHY_BB_TX_GAIN_TAB_31_TG_TABLE31_LSB                                                           0
-#define PHY_BB_TX_GAIN_TAB_31_TG_TABLE31_MASK                                                 0xffffffff
-#define PHY_BB_TX_GAIN_TAB_31_TG_TABLE31_GET(x)                                (((x) & 0xffffffff) >> 0)
-#define PHY_BB_TX_GAIN_TAB_31_TG_TABLE31_SET(x)                                (((x) << 0) & 0xffffffff)
-
-/* macros for BB_tx_gain_tab_32 */
-#define PHY_BB_TX_GAIN_TAB_32_ADDRESS                                                         0x0000a47c
-#define PHY_BB_TX_GAIN_TAB_32_OFFSET                                                          0x0000a47c
-#define PHY_BB_TX_GAIN_TAB_32_TG_TABLE32_MSB                                                          31
-#define PHY_BB_TX_GAIN_TAB_32_TG_TABLE32_LSB                                                           0
-#define PHY_BB_TX_GAIN_TAB_32_TG_TABLE32_MASK                                                 0xffffffff
-#define PHY_BB_TX_GAIN_TAB_32_TG_TABLE32_GET(x)                                (((x) & 0xffffffff) >> 0)
-#define PHY_BB_TX_GAIN_TAB_32_TG_TABLE32_SET(x)                                (((x) << 0) & 0xffffffff)
-
-/* macros for BB_tx_gain_tab_pal_1 */
-#define PHY_BB_TX_GAIN_TAB_PAL_1_ADDRESS                                                      0x0000a480
-#define PHY_BB_TX_GAIN_TAB_PAL_1_OFFSET                                                       0x0000a480
-#define PHY_BB_TX_GAIN_TAB_PAL_1_TG_TABLE1_PAL_ON_MSB                                                 31
-#define PHY_BB_TX_GAIN_TAB_PAL_1_TG_TABLE1_PAL_ON_LSB                                                  0
-#define PHY_BB_TX_GAIN_TAB_PAL_1_TG_TABLE1_PAL_ON_MASK                                        0xffffffff
-#define PHY_BB_TX_GAIN_TAB_PAL_1_TG_TABLE1_PAL_ON_GET(x)                       (((x) & 0xffffffff) >> 0)
-#define PHY_BB_TX_GAIN_TAB_PAL_1_TG_TABLE1_PAL_ON_SET(x)                       (((x) << 0) & 0xffffffff)
-
-/* macros for BB_tx_gain_tab_pal_2 */
-#define PHY_BB_TX_GAIN_TAB_PAL_2_ADDRESS                                                      0x0000a484
-#define PHY_BB_TX_GAIN_TAB_PAL_2_OFFSET                                                       0x0000a484
-#define PHY_BB_TX_GAIN_TAB_PAL_2_TG_TABLE2_PAL_ON_MSB                                                 31
-#define PHY_BB_TX_GAIN_TAB_PAL_2_TG_TABLE2_PAL_ON_LSB                                                  0
-#define PHY_BB_TX_GAIN_TAB_PAL_2_TG_TABLE2_PAL_ON_MASK                                        0xffffffff
-#define PHY_BB_TX_GAIN_TAB_PAL_2_TG_TABLE2_PAL_ON_GET(x)                       (((x) & 0xffffffff) >> 0)
-#define PHY_BB_TX_GAIN_TAB_PAL_2_TG_TABLE2_PAL_ON_SET(x)                       (((x) << 0) & 0xffffffff)
-
-/* macros for BB_tx_gain_tab_pal_3 */
-#define PHY_BB_TX_GAIN_TAB_PAL_3_ADDRESS                                                      0x0000a488
-#define PHY_BB_TX_GAIN_TAB_PAL_3_OFFSET                                                       0x0000a488
-#define PHY_BB_TX_GAIN_TAB_PAL_3_TG_TABLE3_PAL_ON_MSB                                                 31
-#define PHY_BB_TX_GAIN_TAB_PAL_3_TG_TABLE3_PAL_ON_LSB                                                  0
-#define PHY_BB_TX_GAIN_TAB_PAL_3_TG_TABLE3_PAL_ON_MASK                                        0xffffffff
-#define PHY_BB_TX_GAIN_TAB_PAL_3_TG_TABLE3_PAL_ON_GET(x)                       (((x) & 0xffffffff) >> 0)
-#define PHY_BB_TX_GAIN_TAB_PAL_3_TG_TABLE3_PAL_ON_SET(x)                       (((x) << 0) & 0xffffffff)
-
-/* macros for BB_tx_gain_tab_pal_4 */
-#define PHY_BB_TX_GAIN_TAB_PAL_4_ADDRESS                                                      0x0000a48c
-#define PHY_BB_TX_GAIN_TAB_PAL_4_OFFSET                                                       0x0000a48c
-#define PHY_BB_TX_GAIN_TAB_PAL_4_TG_TABLE4_PAL_ON_MSB                                                 31
-#define PHY_BB_TX_GAIN_TAB_PAL_4_TG_TABLE4_PAL_ON_LSB                                                  0
-#define PHY_BB_TX_GAIN_TAB_PAL_4_TG_TABLE4_PAL_ON_MASK                                        0xffffffff
-#define PHY_BB_TX_GAIN_TAB_PAL_4_TG_TABLE4_PAL_ON_GET(x)                       (((x) & 0xffffffff) >> 0)
-#define PHY_BB_TX_GAIN_TAB_PAL_4_TG_TABLE4_PAL_ON_SET(x)                       (((x) << 0) & 0xffffffff)
-
-/* macros for BB_tx_gain_tab_pal_5 */
-#define PHY_BB_TX_GAIN_TAB_PAL_5_ADDRESS                                                      0x0000a490
-#define PHY_BB_TX_GAIN_TAB_PAL_5_OFFSET                                                       0x0000a490
-#define PHY_BB_TX_GAIN_TAB_PAL_5_TG_TABLE5_PAL_ON_MSB                                                 31
-#define PHY_BB_TX_GAIN_TAB_PAL_5_TG_TABLE5_PAL_ON_LSB                                                  0
-#define PHY_BB_TX_GAIN_TAB_PAL_5_TG_TABLE5_PAL_ON_MASK                                        0xffffffff
-#define PHY_BB_TX_GAIN_TAB_PAL_5_TG_TABLE5_PAL_ON_GET(x)                       (((x) & 0xffffffff) >> 0)
-#define PHY_BB_TX_GAIN_TAB_PAL_5_TG_TABLE5_PAL_ON_SET(x)                       (((x) << 0) & 0xffffffff)
-
-/* macros for BB_tx_gain_tab_pal_6 */
-#define PHY_BB_TX_GAIN_TAB_PAL_6_ADDRESS                                                      0x0000a494
-#define PHY_BB_TX_GAIN_TAB_PAL_6_OFFSET                                                       0x0000a494
-#define PHY_BB_TX_GAIN_TAB_PAL_6_TG_TABLE6_PAL_ON_MSB                                                 31
-#define PHY_BB_TX_GAIN_TAB_PAL_6_TG_TABLE6_PAL_ON_LSB                                                  0
-#define PHY_BB_TX_GAIN_TAB_PAL_6_TG_TABLE6_PAL_ON_MASK                                        0xffffffff
-#define PHY_BB_TX_GAIN_TAB_PAL_6_TG_TABLE6_PAL_ON_GET(x)                       (((x) & 0xffffffff) >> 0)
-#define PHY_BB_TX_GAIN_TAB_PAL_6_TG_TABLE6_PAL_ON_SET(x)                       (((x) << 0) & 0xffffffff)
-
-/* macros for BB_tx_gain_tab_pal_7 */
-#define PHY_BB_TX_GAIN_TAB_PAL_7_ADDRESS                                                      0x0000a498
-#define PHY_BB_TX_GAIN_TAB_PAL_7_OFFSET                                                       0x0000a498
-#define PHY_BB_TX_GAIN_TAB_PAL_7_TG_TABLE7_PAL_ON_MSB                                                 31
-#define PHY_BB_TX_GAIN_TAB_PAL_7_TG_TABLE7_PAL_ON_LSB                                                  0
-#define PHY_BB_TX_GAIN_TAB_PAL_7_TG_TABLE7_PAL_ON_MASK                                        0xffffffff
-#define PHY_BB_TX_GAIN_TAB_PAL_7_TG_TABLE7_PAL_ON_GET(x)                       (((x) & 0xffffffff) >> 0)
-#define PHY_BB_TX_GAIN_TAB_PAL_7_TG_TABLE7_PAL_ON_SET(x)                       (((x) << 0) & 0xffffffff)
-
-/* macros for BB_tx_gain_tab_pal_8 */
-#define PHY_BB_TX_GAIN_TAB_PAL_8_ADDRESS                                                      0x0000a49c
-#define PHY_BB_TX_GAIN_TAB_PAL_8_OFFSET                                                       0x0000a49c
-#define PHY_BB_TX_GAIN_TAB_PAL_8_TG_TABLE8_PAL_ON_MSB                                                 31
-#define PHY_BB_TX_GAIN_TAB_PAL_8_TG_TABLE8_PAL_ON_LSB                                                  0
-#define PHY_BB_TX_GAIN_TAB_PAL_8_TG_TABLE8_PAL_ON_MASK                                        0xffffffff
-#define PHY_BB_TX_GAIN_TAB_PAL_8_TG_TABLE8_PAL_ON_GET(x)                       (((x) & 0xffffffff) >> 0)
-#define PHY_BB_TX_GAIN_TAB_PAL_8_TG_TABLE8_PAL_ON_SET(x)                       (((x) << 0) & 0xffffffff)
-
-/* macros for BB_tx_gain_tab_pal_9 */
-#define PHY_BB_TX_GAIN_TAB_PAL_9_ADDRESS                                                      0x0000a4a0
-#define PHY_BB_TX_GAIN_TAB_PAL_9_OFFSET                                                       0x0000a4a0
-#define PHY_BB_TX_GAIN_TAB_PAL_9_TG_TABLE9_PAL_ON_MSB                                                 31
-#define PHY_BB_TX_GAIN_TAB_PAL_9_TG_TABLE9_PAL_ON_LSB                                                  0
-#define PHY_BB_TX_GAIN_TAB_PAL_9_TG_TABLE9_PAL_ON_MASK                                        0xffffffff
-#define PHY_BB_TX_GAIN_TAB_PAL_9_TG_TABLE9_PAL_ON_GET(x)                       (((x) & 0xffffffff) >> 0)
-#define PHY_BB_TX_GAIN_TAB_PAL_9_TG_TABLE9_PAL_ON_SET(x)                       (((x) << 0) & 0xffffffff)
-
-/* macros for BB_tx_gain_tab_pal_10 */
-#define PHY_BB_TX_GAIN_TAB_PAL_10_ADDRESS                                                     0x0000a4a4
-#define PHY_BB_TX_GAIN_TAB_PAL_10_OFFSET                                                      0x0000a4a4
-#define PHY_BB_TX_GAIN_TAB_PAL_10_TG_TABLE10_PAL_ON_MSB                                               31
-#define PHY_BB_TX_GAIN_TAB_PAL_10_TG_TABLE10_PAL_ON_LSB                                                0
-#define PHY_BB_TX_GAIN_TAB_PAL_10_TG_TABLE10_PAL_ON_MASK                                      0xffffffff
-#define PHY_BB_TX_GAIN_TAB_PAL_10_TG_TABLE10_PAL_ON_GET(x)                     (((x) & 0xffffffff) >> 0)
-#define PHY_BB_TX_GAIN_TAB_PAL_10_TG_TABLE10_PAL_ON_SET(x)                     (((x) << 0) & 0xffffffff)
-
-/* macros for BB_tx_gain_tab_pal_11 */
-#define PHY_BB_TX_GAIN_TAB_PAL_11_ADDRESS                                                     0x0000a4a8
-#define PHY_BB_TX_GAIN_TAB_PAL_11_OFFSET                                                      0x0000a4a8
-#define PHY_BB_TX_GAIN_TAB_PAL_11_TG_TABLE11_PAL_ON_MSB                                               31
-#define PHY_BB_TX_GAIN_TAB_PAL_11_TG_TABLE11_PAL_ON_LSB                                                0
-#define PHY_BB_TX_GAIN_TAB_PAL_11_TG_TABLE11_PAL_ON_MASK                                      0xffffffff
-#define PHY_BB_TX_GAIN_TAB_PAL_11_TG_TABLE11_PAL_ON_GET(x)                     (((x) & 0xffffffff) >> 0)
-#define PHY_BB_TX_GAIN_TAB_PAL_11_TG_TABLE11_PAL_ON_SET(x)                     (((x) << 0) & 0xffffffff)
-
-/* macros for BB_tx_gain_tab_pal_12 */
-#define PHY_BB_TX_GAIN_TAB_PAL_12_ADDRESS                                                     0x0000a4ac
-#define PHY_BB_TX_GAIN_TAB_PAL_12_OFFSET                                                      0x0000a4ac
-#define PHY_BB_TX_GAIN_TAB_PAL_12_TG_TABLE12_PAL_ON_MSB                                               31
-#define PHY_BB_TX_GAIN_TAB_PAL_12_TG_TABLE12_PAL_ON_LSB                                                0
-#define PHY_BB_TX_GAIN_TAB_PAL_12_TG_TABLE12_PAL_ON_MASK                                      0xffffffff
-#define PHY_BB_TX_GAIN_TAB_PAL_12_TG_TABLE12_PAL_ON_GET(x)                     (((x) & 0xffffffff) >> 0)
-#define PHY_BB_TX_GAIN_TAB_PAL_12_TG_TABLE12_PAL_ON_SET(x)                     (((x) << 0) & 0xffffffff)
-
-/* macros for BB_tx_gain_tab_pal_13 */
-#define PHY_BB_TX_GAIN_TAB_PAL_13_ADDRESS                                                     0x0000a4b0
-#define PHY_BB_TX_GAIN_TAB_PAL_13_OFFSET                                                      0x0000a4b0
-#define PHY_BB_TX_GAIN_TAB_PAL_13_TG_TABLE13_PAL_ON_MSB                                               31
-#define PHY_BB_TX_GAIN_TAB_PAL_13_TG_TABLE13_PAL_ON_LSB                                                0
-#define PHY_BB_TX_GAIN_TAB_PAL_13_TG_TABLE13_PAL_ON_MASK                                      0xffffffff
-#define PHY_BB_TX_GAIN_TAB_PAL_13_TG_TABLE13_PAL_ON_GET(x)                     (((x) & 0xffffffff) >> 0)
-#define PHY_BB_TX_GAIN_TAB_PAL_13_TG_TABLE13_PAL_ON_SET(x)                     (((x) << 0) & 0xffffffff)
-
-/* macros for BB_tx_gain_tab_pal_14 */
-#define PHY_BB_TX_GAIN_TAB_PAL_14_ADDRESS                                                     0x0000a4b4
-#define PHY_BB_TX_GAIN_TAB_PAL_14_OFFSET                                                      0x0000a4b4
-#define PHY_BB_TX_GAIN_TAB_PAL_14_TG_TABLE14_PAL_ON_MSB                                               31
-#define PHY_BB_TX_GAIN_TAB_PAL_14_TG_TABLE14_PAL_ON_LSB                                                0
-#define PHY_BB_TX_GAIN_TAB_PAL_14_TG_TABLE14_PAL_ON_MASK                                      0xffffffff
-#define PHY_BB_TX_GAIN_TAB_PAL_14_TG_TABLE14_PAL_ON_GET(x)                     (((x) & 0xffffffff) >> 0)
-#define PHY_BB_TX_GAIN_TAB_PAL_14_TG_TABLE14_PAL_ON_SET(x)                     (((x) << 0) & 0xffffffff)
-
-/* macros for BB_tx_gain_tab_pal_15 */
-#define PHY_BB_TX_GAIN_TAB_PAL_15_ADDRESS                                                     0x0000a4b8
-#define PHY_BB_TX_GAIN_TAB_PAL_15_OFFSET                                                      0x0000a4b8
-#define PHY_BB_TX_GAIN_TAB_PAL_15_TG_TABLE15_PAL_ON_MSB                                               31
-#define PHY_BB_TX_GAIN_TAB_PAL_15_TG_TABLE15_PAL_ON_LSB                                                0
-#define PHY_BB_TX_GAIN_TAB_PAL_15_TG_TABLE15_PAL_ON_MASK                                      0xffffffff
-#define PHY_BB_TX_GAIN_TAB_PAL_15_TG_TABLE15_PAL_ON_GET(x)                     (((x) & 0xffffffff) >> 0)
-#define PHY_BB_TX_GAIN_TAB_PAL_15_TG_TABLE15_PAL_ON_SET(x)                     (((x) << 0) & 0xffffffff)
-
-/* macros for BB_tx_gain_tab_pal_16 */
-#define PHY_BB_TX_GAIN_TAB_PAL_16_ADDRESS                                                     0x0000a4bc
-#define PHY_BB_TX_GAIN_TAB_PAL_16_OFFSET                                                      0x0000a4bc
-#define PHY_BB_TX_GAIN_TAB_PAL_16_TG_TABLE16_PAL_ON_MSB                                               31
-#define PHY_BB_TX_GAIN_TAB_PAL_16_TG_TABLE16_PAL_ON_LSB                                                0
-#define PHY_BB_TX_GAIN_TAB_PAL_16_TG_TABLE16_PAL_ON_MASK                                      0xffffffff
-#define PHY_BB_TX_GAIN_TAB_PAL_16_TG_TABLE16_PAL_ON_GET(x)                     (((x) & 0xffffffff) >> 0)
-#define PHY_BB_TX_GAIN_TAB_PAL_16_TG_TABLE16_PAL_ON_SET(x)                     (((x) << 0) & 0xffffffff)
-
-/* macros for BB_tx_gain_tab_pal_17 */
-#define PHY_BB_TX_GAIN_TAB_PAL_17_ADDRESS                                                     0x0000a4c0
-#define PHY_BB_TX_GAIN_TAB_PAL_17_OFFSET                                                      0x0000a4c0
-#define PHY_BB_TX_GAIN_TAB_PAL_17_TG_TABLE17_PAL_ON_MSB                                               31
-#define PHY_BB_TX_GAIN_TAB_PAL_17_TG_TABLE17_PAL_ON_LSB                                                0
-#define PHY_BB_TX_GAIN_TAB_PAL_17_TG_TABLE17_PAL_ON_MASK                                      0xffffffff
-#define PHY_BB_TX_GAIN_TAB_PAL_17_TG_TABLE17_PAL_ON_GET(x)                     (((x) & 0xffffffff) >> 0)
-#define PHY_BB_TX_GAIN_TAB_PAL_17_TG_TABLE17_PAL_ON_SET(x)                     (((x) << 0) & 0xffffffff)
-
-/* macros for BB_tx_gain_tab_pal_18 */
-#define PHY_BB_TX_GAIN_TAB_PAL_18_ADDRESS                                                     0x0000a4c4
-#define PHY_BB_TX_GAIN_TAB_PAL_18_OFFSET                                                      0x0000a4c4
-#define PHY_BB_TX_GAIN_TAB_PAL_18_TG_TABLE18_PAL_ON_MSB                                               31
-#define PHY_BB_TX_GAIN_TAB_PAL_18_TG_TABLE18_PAL_ON_LSB                                                0
-#define PHY_BB_TX_GAIN_TAB_PAL_18_TG_TABLE18_PAL_ON_MASK                                      0xffffffff
-#define PHY_BB_TX_GAIN_TAB_PAL_18_TG_TABLE18_PAL_ON_GET(x)                     (((x) & 0xffffffff) >> 0)
-#define PHY_BB_TX_GAIN_TAB_PAL_18_TG_TABLE18_PAL_ON_SET(x)                     (((x) << 0) & 0xffffffff)
-
-/* macros for BB_tx_gain_tab_pal_19 */
-#define PHY_BB_TX_GAIN_TAB_PAL_19_ADDRESS                                                     0x0000a4c8
-#define PHY_BB_TX_GAIN_TAB_PAL_19_OFFSET                                                      0x0000a4c8
-#define PHY_BB_TX_GAIN_TAB_PAL_19_TG_TABLE19_PAL_ON_MSB                                               31
-#define PHY_BB_TX_GAIN_TAB_PAL_19_TG_TABLE19_PAL_ON_LSB                                                0
-#define PHY_BB_TX_GAIN_TAB_PAL_19_TG_TABLE19_PAL_ON_MASK                                      0xffffffff
-#define PHY_BB_TX_GAIN_TAB_PAL_19_TG_TABLE19_PAL_ON_GET(x)                     (((x) & 0xffffffff) >> 0)
-#define PHY_BB_TX_GAIN_TAB_PAL_19_TG_TABLE19_PAL_ON_SET(x)                     (((x) << 0) & 0xffffffff)
-
-/* macros for BB_tx_gain_tab_pal_20 */
-#define PHY_BB_TX_GAIN_TAB_PAL_20_ADDRESS                                                     0x0000a4cc
-#define PHY_BB_TX_GAIN_TAB_PAL_20_OFFSET                                                      0x0000a4cc
-#define PHY_BB_TX_GAIN_TAB_PAL_20_TG_TABLE20_PAL_ON_MSB                                               31
-#define PHY_BB_TX_GAIN_TAB_PAL_20_TG_TABLE20_PAL_ON_LSB                                                0
-#define PHY_BB_TX_GAIN_TAB_PAL_20_TG_TABLE20_PAL_ON_MASK                                      0xffffffff
-#define PHY_BB_TX_GAIN_TAB_PAL_20_TG_TABLE20_PAL_ON_GET(x)                     (((x) & 0xffffffff) >> 0)
-#define PHY_BB_TX_GAIN_TAB_PAL_20_TG_TABLE20_PAL_ON_SET(x)                     (((x) << 0) & 0xffffffff)
-
-/* macros for BB_tx_gain_tab_pal_21 */
-#define PHY_BB_TX_GAIN_TAB_PAL_21_ADDRESS                                                     0x0000a4d0
-#define PHY_BB_TX_GAIN_TAB_PAL_21_OFFSET                                                      0x0000a4d0
-#define PHY_BB_TX_GAIN_TAB_PAL_21_TG_TABLE21_PAL_ON_MSB                                               31
-#define PHY_BB_TX_GAIN_TAB_PAL_21_TG_TABLE21_PAL_ON_LSB                                                0
-#define PHY_BB_TX_GAIN_TAB_PAL_21_TG_TABLE21_PAL_ON_MASK                                      0xffffffff
-#define PHY_BB_TX_GAIN_TAB_PAL_21_TG_TABLE21_PAL_ON_GET(x)                     (((x) & 0xffffffff) >> 0)
-#define PHY_BB_TX_GAIN_TAB_PAL_21_TG_TABLE21_PAL_ON_SET(x)                     (((x) << 0) & 0xffffffff)
-
-/* macros for BB_tx_gain_tab_pal_22 */
-#define PHY_BB_TX_GAIN_TAB_PAL_22_ADDRESS                                                     0x0000a4d4
-#define PHY_BB_TX_GAIN_TAB_PAL_22_OFFSET                                                      0x0000a4d4
-#define PHY_BB_TX_GAIN_TAB_PAL_22_TG_TABLE22_PAL_ON_MSB                                               31
-#define PHY_BB_TX_GAIN_TAB_PAL_22_TG_TABLE22_PAL_ON_LSB                                                0
-#define PHY_BB_TX_GAIN_TAB_PAL_22_TG_TABLE22_PAL_ON_MASK                                      0xffffffff
-#define PHY_BB_TX_GAIN_TAB_PAL_22_TG_TABLE22_PAL_ON_GET(x)                     (((x) & 0xffffffff) >> 0)
-#define PHY_BB_TX_GAIN_TAB_PAL_22_TG_TABLE22_PAL_ON_SET(x)                     (((x) << 0) & 0xffffffff)
-
-/* macros for BB_tx_gain_tab_pal_23 */
-#define PHY_BB_TX_GAIN_TAB_PAL_23_ADDRESS                                                     0x0000a4d8
-#define PHY_BB_TX_GAIN_TAB_PAL_23_OFFSET                                                      0x0000a4d8
-#define PHY_BB_TX_GAIN_TAB_PAL_23_TG_TABLE23_PAL_ON_MSB                                               31
-#define PHY_BB_TX_GAIN_TAB_PAL_23_TG_TABLE23_PAL_ON_LSB                                                0
-#define PHY_BB_TX_GAIN_TAB_PAL_23_TG_TABLE23_PAL_ON_MASK                                      0xffffffff
-#define PHY_BB_TX_GAIN_TAB_PAL_23_TG_TABLE23_PAL_ON_GET(x)                     (((x) & 0xffffffff) >> 0)
-#define PHY_BB_TX_GAIN_TAB_PAL_23_TG_TABLE23_PAL_ON_SET(x)                     (((x) << 0) & 0xffffffff)
-
-/* macros for BB_tx_gain_tab_pal_24 */
-#define PHY_BB_TX_GAIN_TAB_PAL_24_ADDRESS                                                     0x0000a4dc
-#define PHY_BB_TX_GAIN_TAB_PAL_24_OFFSET                                                      0x0000a4dc
-#define PHY_BB_TX_GAIN_TAB_PAL_24_TG_TABLE24_PAL_ON_MSB                                               31
-#define PHY_BB_TX_GAIN_TAB_PAL_24_TG_TABLE24_PAL_ON_LSB                                                0
-#define PHY_BB_TX_GAIN_TAB_PAL_24_TG_TABLE24_PAL_ON_MASK                                      0xffffffff
-#define PHY_BB_TX_GAIN_TAB_PAL_24_TG_TABLE24_PAL_ON_GET(x)                     (((x) & 0xffffffff) >> 0)
-#define PHY_BB_TX_GAIN_TAB_PAL_24_TG_TABLE24_PAL_ON_SET(x)                     (((x) << 0) & 0xffffffff)
-
-/* macros for BB_tx_gain_tab_pal_25 */
-#define PHY_BB_TX_GAIN_TAB_PAL_25_ADDRESS                                                     0x0000a4e0
-#define PHY_BB_TX_GAIN_TAB_PAL_25_OFFSET                                                      0x0000a4e0
-#define PHY_BB_TX_GAIN_TAB_PAL_25_TG_TABLE25_PAL_ON_MSB                                               31
-#define PHY_BB_TX_GAIN_TAB_PAL_25_TG_TABLE25_PAL_ON_LSB                                                0
-#define PHY_BB_TX_GAIN_TAB_PAL_25_TG_TABLE25_PAL_ON_MASK                                      0xffffffff
-#define PHY_BB_TX_GAIN_TAB_PAL_25_TG_TABLE25_PAL_ON_GET(x)                     (((x) & 0xffffffff) >> 0)
-#define PHY_BB_TX_GAIN_TAB_PAL_25_TG_TABLE25_PAL_ON_SET(x)                     (((x) << 0) & 0xffffffff)
-
-/* macros for BB_tx_gain_tab_pal_26 */
-#define PHY_BB_TX_GAIN_TAB_PAL_26_ADDRESS                                                     0x0000a4e4
-#define PHY_BB_TX_GAIN_TAB_PAL_26_OFFSET                                                      0x0000a4e4
-#define PHY_BB_TX_GAIN_TAB_PAL_26_TG_TABLE26_PAL_ON_MSB                                               31
-#define PHY_BB_TX_GAIN_TAB_PAL_26_TG_TABLE26_PAL_ON_LSB                                                0
-#define PHY_BB_TX_GAIN_TAB_PAL_26_TG_TABLE26_PAL_ON_MASK                                      0xffffffff
-#define PHY_BB_TX_GAIN_TAB_PAL_26_TG_TABLE26_PAL_ON_GET(x)                     (((x) & 0xffffffff) >> 0)
-#define PHY_BB_TX_GAIN_TAB_PAL_26_TG_TABLE26_PAL_ON_SET(x)                     (((x) << 0) & 0xffffffff)
-
-/* macros for BB_tx_gain_tab_pal_27 */
-#define PHY_BB_TX_GAIN_TAB_PAL_27_ADDRESS                                                     0x0000a4e8
-#define PHY_BB_TX_GAIN_TAB_PAL_27_OFFSET                                                      0x0000a4e8
-#define PHY_BB_TX_GAIN_TAB_PAL_27_TG_TABLE27_PAL_ON_MSB                                               31
-#define PHY_BB_TX_GAIN_TAB_PAL_27_TG_TABLE27_PAL_ON_LSB                                                0
-#define PHY_BB_TX_GAIN_TAB_PAL_27_TG_TABLE27_PAL_ON_MASK                                      0xffffffff
-#define PHY_BB_TX_GAIN_TAB_PAL_27_TG_TABLE27_PAL_ON_GET(x)                     (((x) & 0xffffffff) >> 0)
-#define PHY_BB_TX_GAIN_TAB_PAL_27_TG_TABLE27_PAL_ON_SET(x)                     (((x) << 0) & 0xffffffff)
-
-/* macros for BB_tx_gain_tab_pal_28 */
-#define PHY_BB_TX_GAIN_TAB_PAL_28_ADDRESS                                                     0x0000a4ec
-#define PHY_BB_TX_GAIN_TAB_PAL_28_OFFSET                                                      0x0000a4ec
-#define PHY_BB_TX_GAIN_TAB_PAL_28_TG_TABLE28_PAL_ON_MSB                                               31
-#define PHY_BB_TX_GAIN_TAB_PAL_28_TG_TABLE28_PAL_ON_LSB                                                0
-#define PHY_BB_TX_GAIN_TAB_PAL_28_TG_TABLE28_PAL_ON_MASK                                      0xffffffff
-#define PHY_BB_TX_GAIN_TAB_PAL_28_TG_TABLE28_PAL_ON_GET(x)                     (((x) & 0xffffffff) >> 0)
-#define PHY_BB_TX_GAIN_TAB_PAL_28_TG_TABLE28_PAL_ON_SET(x)                     (((x) << 0) & 0xffffffff)
-
-/* macros for BB_tx_gain_tab_pal_29 */
-#define PHY_BB_TX_GAIN_TAB_PAL_29_ADDRESS                                                     0x0000a4f0
-#define PHY_BB_TX_GAIN_TAB_PAL_29_OFFSET                                                      0x0000a4f0
-#define PHY_BB_TX_GAIN_TAB_PAL_29_TG_TABLE29_PAL_ON_MSB                                               31
-#define PHY_BB_TX_GAIN_TAB_PAL_29_TG_TABLE29_PAL_ON_LSB                                                0
-#define PHY_BB_TX_GAIN_TAB_PAL_29_TG_TABLE29_PAL_ON_MASK                                      0xffffffff
-#define PHY_BB_TX_GAIN_TAB_PAL_29_TG_TABLE29_PAL_ON_GET(x)                     (((x) & 0xffffffff) >> 0)
-#define PHY_BB_TX_GAIN_TAB_PAL_29_TG_TABLE29_PAL_ON_SET(x)                     (((x) << 0) & 0xffffffff)
-
-/* macros for BB_tx_gain_tab_pal_30 */
-#define PHY_BB_TX_GAIN_TAB_PAL_30_ADDRESS                                                     0x0000a4f4
-#define PHY_BB_TX_GAIN_TAB_PAL_30_OFFSET                                                      0x0000a4f4
-#define PHY_BB_TX_GAIN_TAB_PAL_30_TG_TABLE30_PAL_ON_MSB                                               31
-#define PHY_BB_TX_GAIN_TAB_PAL_30_TG_TABLE30_PAL_ON_LSB                                                0
-#define PHY_BB_TX_GAIN_TAB_PAL_30_TG_TABLE30_PAL_ON_MASK                                      0xffffffff
-#define PHY_BB_TX_GAIN_TAB_PAL_30_TG_TABLE30_PAL_ON_GET(x)                     (((x) & 0xffffffff) >> 0)
-#define PHY_BB_TX_GAIN_TAB_PAL_30_TG_TABLE30_PAL_ON_SET(x)                     (((x) << 0) & 0xffffffff)
-
-/* macros for BB_tx_gain_tab_pal_31 */
-#define PHY_BB_TX_GAIN_TAB_PAL_31_ADDRESS                                                     0x0000a4f8
-#define PHY_BB_TX_GAIN_TAB_PAL_31_OFFSET                                                      0x0000a4f8
-#define PHY_BB_TX_GAIN_TAB_PAL_31_TG_TABLE31_PAL_ON_MSB                                               31
-#define PHY_BB_TX_GAIN_TAB_PAL_31_TG_TABLE31_PAL_ON_LSB                                                0
-#define PHY_BB_TX_GAIN_TAB_PAL_31_TG_TABLE31_PAL_ON_MASK                                      0xffffffff
-#define PHY_BB_TX_GAIN_TAB_PAL_31_TG_TABLE31_PAL_ON_GET(x)                     (((x) & 0xffffffff) >> 0)
-#define PHY_BB_TX_GAIN_TAB_PAL_31_TG_TABLE31_PAL_ON_SET(x)                     (((x) << 0) & 0xffffffff)
-
-/* macros for BB_tx_gain_tab_pal_32 */
-#define PHY_BB_TX_GAIN_TAB_PAL_32_ADDRESS                                                     0x0000a4fc
-#define PHY_BB_TX_GAIN_TAB_PAL_32_OFFSET                                                      0x0000a4fc
-#define PHY_BB_TX_GAIN_TAB_PAL_32_TG_TABLE32_PAL_ON_MSB                                               31
-#define PHY_BB_TX_GAIN_TAB_PAL_32_TG_TABLE32_PAL_ON_LSB                                                0
-#define PHY_BB_TX_GAIN_TAB_PAL_32_TG_TABLE32_PAL_ON_MASK                                      0xffffffff
-#define PHY_BB_TX_GAIN_TAB_PAL_32_TG_TABLE32_PAL_ON_GET(x)                     (((x) & 0xffffffff) >> 0)
-#define PHY_BB_TX_GAIN_TAB_PAL_32_TG_TABLE32_PAL_ON_SET(x)                     (((x) << 0) & 0xffffffff)
-
-/* macros for BB_caltx_gain_set_0 */
-#define PHY_BB_CALTX_GAIN_SET_0_ADDRESS                                                       0x0000a518
-#define PHY_BB_CALTX_GAIN_SET_0_OFFSET                                                        0x0000a518
-#define PHY_BB_CALTX_GAIN_SET_0_CALTX_GAIN_SET_0_MSB                                                  13
-#define PHY_BB_CALTX_GAIN_SET_0_CALTX_GAIN_SET_0_LSB                                                   0
-#define PHY_BB_CALTX_GAIN_SET_0_CALTX_GAIN_SET_0_MASK                                         0x00003fff
-#define PHY_BB_CALTX_GAIN_SET_0_CALTX_GAIN_SET_0_GET(x)                        (((x) & 0x00003fff) >> 0)
-#define PHY_BB_CALTX_GAIN_SET_0_CALTX_GAIN_SET_0_SET(x)                        (((x) << 0) & 0x00003fff)
-#define PHY_BB_CALTX_GAIN_SET_0_CALTX_GAIN_SET_1_MSB                                                  27
-#define PHY_BB_CALTX_GAIN_SET_0_CALTX_GAIN_SET_1_LSB                                                  14
-#define PHY_BB_CALTX_GAIN_SET_0_CALTX_GAIN_SET_1_MASK                                         0x0fffc000
-#define PHY_BB_CALTX_GAIN_SET_0_CALTX_GAIN_SET_1_GET(x)                       (((x) & 0x0fffc000) >> 14)
-#define PHY_BB_CALTX_GAIN_SET_0_CALTX_GAIN_SET_1_SET(x)                       (((x) << 14) & 0x0fffc000)
-
-/* macros for BB_caltx_gain_set_2 */
-#define PHY_BB_CALTX_GAIN_SET_2_ADDRESS                                                       0x0000a51c
-#define PHY_BB_CALTX_GAIN_SET_2_OFFSET                                                        0x0000a51c
-#define PHY_BB_CALTX_GAIN_SET_2_CALTX_GAIN_SET_2_MSB                                                  13
-#define PHY_BB_CALTX_GAIN_SET_2_CALTX_GAIN_SET_2_LSB                                                   0
-#define PHY_BB_CALTX_GAIN_SET_2_CALTX_GAIN_SET_2_MASK                                         0x00003fff
-#define PHY_BB_CALTX_GAIN_SET_2_CALTX_GAIN_SET_2_GET(x)                        (((x) & 0x00003fff) >> 0)
-#define PHY_BB_CALTX_GAIN_SET_2_CALTX_GAIN_SET_2_SET(x)                        (((x) << 0) & 0x00003fff)
-#define PHY_BB_CALTX_GAIN_SET_2_CALTX_GAIN_SET_3_MSB                                                  27
-#define PHY_BB_CALTX_GAIN_SET_2_CALTX_GAIN_SET_3_LSB                                                  14
-#define PHY_BB_CALTX_GAIN_SET_2_CALTX_GAIN_SET_3_MASK                                         0x0fffc000
-#define PHY_BB_CALTX_GAIN_SET_2_CALTX_GAIN_SET_3_GET(x)                       (((x) & 0x0fffc000) >> 14)
-#define PHY_BB_CALTX_GAIN_SET_2_CALTX_GAIN_SET_3_SET(x)                       (((x) << 14) & 0x0fffc000)
-
-/* macros for BB_caltx_gain_set_4 */
-#define PHY_BB_CALTX_GAIN_SET_4_ADDRESS                                                       0x0000a520
-#define PHY_BB_CALTX_GAIN_SET_4_OFFSET                                                        0x0000a520
-#define PHY_BB_CALTX_GAIN_SET_4_CALTX_GAIN_SET_4_MSB                                                  13
-#define PHY_BB_CALTX_GAIN_SET_4_CALTX_GAIN_SET_4_LSB                                                   0
-#define PHY_BB_CALTX_GAIN_SET_4_CALTX_GAIN_SET_4_MASK                                         0x00003fff
-#define PHY_BB_CALTX_GAIN_SET_4_CALTX_GAIN_SET_4_GET(x)                        (((x) & 0x00003fff) >> 0)
-#define PHY_BB_CALTX_GAIN_SET_4_CALTX_GAIN_SET_4_SET(x)                        (((x) << 0) & 0x00003fff)
-#define PHY_BB_CALTX_GAIN_SET_4_CALTX_GAIN_SET_5_MSB                                                  27
-#define PHY_BB_CALTX_GAIN_SET_4_CALTX_GAIN_SET_5_LSB                                                  14
-#define PHY_BB_CALTX_GAIN_SET_4_CALTX_GAIN_SET_5_MASK                                         0x0fffc000
-#define PHY_BB_CALTX_GAIN_SET_4_CALTX_GAIN_SET_5_GET(x)                       (((x) & 0x0fffc000) >> 14)
-#define PHY_BB_CALTX_GAIN_SET_4_CALTX_GAIN_SET_5_SET(x)                       (((x) << 14) & 0x0fffc000)
-
-/* macros for BB_caltx_gain_set_6 */
-#define PHY_BB_CALTX_GAIN_SET_6_ADDRESS                                                       0x0000a524
-#define PHY_BB_CALTX_GAIN_SET_6_OFFSET                                                        0x0000a524
-#define PHY_BB_CALTX_GAIN_SET_6_CALTX_GAIN_SET_6_MSB                                                  13
-#define PHY_BB_CALTX_GAIN_SET_6_CALTX_GAIN_SET_6_LSB                                                   0
-#define PHY_BB_CALTX_GAIN_SET_6_CALTX_GAIN_SET_6_MASK                                         0x00003fff
-#define PHY_BB_CALTX_GAIN_SET_6_CALTX_GAIN_SET_6_GET(x)                        (((x) & 0x00003fff) >> 0)
-#define PHY_BB_CALTX_GAIN_SET_6_CALTX_GAIN_SET_6_SET(x)                        (((x) << 0) & 0x00003fff)
-#define PHY_BB_CALTX_GAIN_SET_6_CALTX_GAIN_SET_7_MSB                                                  27
-#define PHY_BB_CALTX_GAIN_SET_6_CALTX_GAIN_SET_7_LSB                                                  14
-#define PHY_BB_CALTX_GAIN_SET_6_CALTX_GAIN_SET_7_MASK                                         0x0fffc000
-#define PHY_BB_CALTX_GAIN_SET_6_CALTX_GAIN_SET_7_GET(x)                       (((x) & 0x0fffc000) >> 14)
-#define PHY_BB_CALTX_GAIN_SET_6_CALTX_GAIN_SET_7_SET(x)                       (((x) << 14) & 0x0fffc000)
-
-/* macros for BB_caltx_gain_set_8 */
-#define PHY_BB_CALTX_GAIN_SET_8_ADDRESS                                                       0x0000a528
-#define PHY_BB_CALTX_GAIN_SET_8_OFFSET                                                        0x0000a528
-#define PHY_BB_CALTX_GAIN_SET_8_CALTX_GAIN_SET_8_MSB                                                  13
-#define PHY_BB_CALTX_GAIN_SET_8_CALTX_GAIN_SET_8_LSB                                                   0
-#define PHY_BB_CALTX_GAIN_SET_8_CALTX_GAIN_SET_8_MASK                                         0x00003fff
-#define PHY_BB_CALTX_GAIN_SET_8_CALTX_GAIN_SET_8_GET(x)                        (((x) & 0x00003fff) >> 0)
-#define PHY_BB_CALTX_GAIN_SET_8_CALTX_GAIN_SET_8_SET(x)                        (((x) << 0) & 0x00003fff)
-#define PHY_BB_CALTX_GAIN_SET_8_CALTX_GAIN_SET_9_MSB                                                  27
-#define PHY_BB_CALTX_GAIN_SET_8_CALTX_GAIN_SET_9_LSB                                                  14
-#define PHY_BB_CALTX_GAIN_SET_8_CALTX_GAIN_SET_9_MASK                                         0x0fffc000
-#define PHY_BB_CALTX_GAIN_SET_8_CALTX_GAIN_SET_9_GET(x)                       (((x) & 0x0fffc000) >> 14)
-#define PHY_BB_CALTX_GAIN_SET_8_CALTX_GAIN_SET_9_SET(x)                       (((x) << 14) & 0x0fffc000)
-
-/* macros for BB_caltx_gain_set_10 */
-#define PHY_BB_CALTX_GAIN_SET_10_ADDRESS                                                      0x0000a52c
-#define PHY_BB_CALTX_GAIN_SET_10_OFFSET                                                       0x0000a52c
-#define PHY_BB_CALTX_GAIN_SET_10_CALTX_GAIN_SET_10_MSB                                                13
-#define PHY_BB_CALTX_GAIN_SET_10_CALTX_GAIN_SET_10_LSB                                                 0
-#define PHY_BB_CALTX_GAIN_SET_10_CALTX_GAIN_SET_10_MASK                                       0x00003fff
-#define PHY_BB_CALTX_GAIN_SET_10_CALTX_GAIN_SET_10_GET(x)                      (((x) & 0x00003fff) >> 0)
-#define PHY_BB_CALTX_GAIN_SET_10_CALTX_GAIN_SET_10_SET(x)                      (((x) << 0) & 0x00003fff)
-#define PHY_BB_CALTX_GAIN_SET_10_CALTX_GAIN_SET_11_MSB                                                27
-#define PHY_BB_CALTX_GAIN_SET_10_CALTX_GAIN_SET_11_LSB                                                14
-#define PHY_BB_CALTX_GAIN_SET_10_CALTX_GAIN_SET_11_MASK                                       0x0fffc000
-#define PHY_BB_CALTX_GAIN_SET_10_CALTX_GAIN_SET_11_GET(x)                     (((x) & 0x0fffc000) >> 14)
-#define PHY_BB_CALTX_GAIN_SET_10_CALTX_GAIN_SET_11_SET(x)                     (((x) << 14) & 0x0fffc000)
-
-/* macros for BB_caltx_gain_set_12 */
-#define PHY_BB_CALTX_GAIN_SET_12_ADDRESS                                                      0x0000a530
-#define PHY_BB_CALTX_GAIN_SET_12_OFFSET                                                       0x0000a530
-#define PHY_BB_CALTX_GAIN_SET_12_CALTX_GAIN_SET_12_MSB                                                13
-#define PHY_BB_CALTX_GAIN_SET_12_CALTX_GAIN_SET_12_LSB                                                 0
-#define PHY_BB_CALTX_GAIN_SET_12_CALTX_GAIN_SET_12_MASK                                       0x00003fff
-#define PHY_BB_CALTX_GAIN_SET_12_CALTX_GAIN_SET_12_GET(x)                      (((x) & 0x00003fff) >> 0)
-#define PHY_BB_CALTX_GAIN_SET_12_CALTX_GAIN_SET_12_SET(x)                      (((x) << 0) & 0x00003fff)
-#define PHY_BB_CALTX_GAIN_SET_12_CALTX_GAIN_SET_13_MSB                                                27
-#define PHY_BB_CALTX_GAIN_SET_12_CALTX_GAIN_SET_13_LSB                                                14
-#define PHY_BB_CALTX_GAIN_SET_12_CALTX_GAIN_SET_13_MASK                                       0x0fffc000
-#define PHY_BB_CALTX_GAIN_SET_12_CALTX_GAIN_SET_13_GET(x)                     (((x) & 0x0fffc000) >> 14)
-#define PHY_BB_CALTX_GAIN_SET_12_CALTX_GAIN_SET_13_SET(x)                     (((x) << 14) & 0x0fffc000)
-
-/* macros for BB_caltx_gain_set_14 */
-#define PHY_BB_CALTX_GAIN_SET_14_ADDRESS                                                      0x0000a534
-#define PHY_BB_CALTX_GAIN_SET_14_OFFSET                                                       0x0000a534
-#define PHY_BB_CALTX_GAIN_SET_14_CALTX_GAIN_SET_14_MSB                                                13
-#define PHY_BB_CALTX_GAIN_SET_14_CALTX_GAIN_SET_14_LSB                                                 0
-#define PHY_BB_CALTX_GAIN_SET_14_CALTX_GAIN_SET_14_MASK                                       0x00003fff
-#define PHY_BB_CALTX_GAIN_SET_14_CALTX_GAIN_SET_14_GET(x)                      (((x) & 0x00003fff) >> 0)
-#define PHY_BB_CALTX_GAIN_SET_14_CALTX_GAIN_SET_14_SET(x)                      (((x) << 0) & 0x00003fff)
-#define PHY_BB_CALTX_GAIN_SET_14_CALTX_GAIN_SET_15_MSB                                                27
-#define PHY_BB_CALTX_GAIN_SET_14_CALTX_GAIN_SET_15_LSB                                                14
-#define PHY_BB_CALTX_GAIN_SET_14_CALTX_GAIN_SET_15_MASK                                       0x0fffc000
-#define PHY_BB_CALTX_GAIN_SET_14_CALTX_GAIN_SET_15_GET(x)                     (((x) & 0x0fffc000) >> 14)
-#define PHY_BB_CALTX_GAIN_SET_14_CALTX_GAIN_SET_15_SET(x)                     (((x) << 14) & 0x0fffc000)
-
-/* macros for BB_caltx_gain_set_16 */
-#define PHY_BB_CALTX_GAIN_SET_16_ADDRESS                                                      0x0000a538
-#define PHY_BB_CALTX_GAIN_SET_16_OFFSET                                                       0x0000a538
-#define PHY_BB_CALTX_GAIN_SET_16_CALTX_GAIN_SET_16_MSB                                                13
-#define PHY_BB_CALTX_GAIN_SET_16_CALTX_GAIN_SET_16_LSB                                                 0
-#define PHY_BB_CALTX_GAIN_SET_16_CALTX_GAIN_SET_16_MASK                                       0x00003fff
-#define PHY_BB_CALTX_GAIN_SET_16_CALTX_GAIN_SET_16_GET(x)                      (((x) & 0x00003fff) >> 0)
-#define PHY_BB_CALTX_GAIN_SET_16_CALTX_GAIN_SET_16_SET(x)                      (((x) << 0) & 0x00003fff)
-#define PHY_BB_CALTX_GAIN_SET_16_CALTX_GAIN_SET_17_MSB                                                27
-#define PHY_BB_CALTX_GAIN_SET_16_CALTX_GAIN_SET_17_LSB                                                14
-#define PHY_BB_CALTX_GAIN_SET_16_CALTX_GAIN_SET_17_MASK                                       0x0fffc000
-#define PHY_BB_CALTX_GAIN_SET_16_CALTX_GAIN_SET_17_GET(x)                     (((x) & 0x0fffc000) >> 14)
-#define PHY_BB_CALTX_GAIN_SET_16_CALTX_GAIN_SET_17_SET(x)                     (((x) << 14) & 0x0fffc000)
-
-/* macros for BB_caltx_gain_set_18 */
-#define PHY_BB_CALTX_GAIN_SET_18_ADDRESS                                                      0x0000a53c
-#define PHY_BB_CALTX_GAIN_SET_18_OFFSET                                                       0x0000a53c
-#define PHY_BB_CALTX_GAIN_SET_18_CALTX_GAIN_SET_18_MSB                                                13
-#define PHY_BB_CALTX_GAIN_SET_18_CALTX_GAIN_SET_18_LSB                                                 0
-#define PHY_BB_CALTX_GAIN_SET_18_CALTX_GAIN_SET_18_MASK                                       0x00003fff
-#define PHY_BB_CALTX_GAIN_SET_18_CALTX_GAIN_SET_18_GET(x)                      (((x) & 0x00003fff) >> 0)
-#define PHY_BB_CALTX_GAIN_SET_18_CALTX_GAIN_SET_18_SET(x)                      (((x) << 0) & 0x00003fff)
-#define PHY_BB_CALTX_GAIN_SET_18_CALTX_GAIN_SET_19_MSB                                                27
-#define PHY_BB_CALTX_GAIN_SET_18_CALTX_GAIN_SET_19_LSB                                                14
-#define PHY_BB_CALTX_GAIN_SET_18_CALTX_GAIN_SET_19_MASK                                       0x0fffc000
-#define PHY_BB_CALTX_GAIN_SET_18_CALTX_GAIN_SET_19_GET(x)                     (((x) & 0x0fffc000) >> 14)
-#define PHY_BB_CALTX_GAIN_SET_18_CALTX_GAIN_SET_19_SET(x)                     (((x) << 14) & 0x0fffc000)
-
-/* macros for BB_caltx_gain_set_20 */
-#define PHY_BB_CALTX_GAIN_SET_20_ADDRESS                                                      0x0000a540
-#define PHY_BB_CALTX_GAIN_SET_20_OFFSET                                                       0x0000a540
-#define PHY_BB_CALTX_GAIN_SET_20_CALTX_GAIN_SET_20_MSB                                                13
-#define PHY_BB_CALTX_GAIN_SET_20_CALTX_GAIN_SET_20_LSB                                                 0
-#define PHY_BB_CALTX_GAIN_SET_20_CALTX_GAIN_SET_20_MASK                                       0x00003fff
-#define PHY_BB_CALTX_GAIN_SET_20_CALTX_GAIN_SET_20_GET(x)                      (((x) & 0x00003fff) >> 0)
-#define PHY_BB_CALTX_GAIN_SET_20_CALTX_GAIN_SET_20_SET(x)                      (((x) << 0) & 0x00003fff)
-#define PHY_BB_CALTX_GAIN_SET_20_CALTX_GAIN_SET_21_MSB                                                27
-#define PHY_BB_CALTX_GAIN_SET_20_CALTX_GAIN_SET_21_LSB                                                14
-#define PHY_BB_CALTX_GAIN_SET_20_CALTX_GAIN_SET_21_MASK                                       0x0fffc000
-#define PHY_BB_CALTX_GAIN_SET_20_CALTX_GAIN_SET_21_GET(x)                     (((x) & 0x0fffc000) >> 14)
-#define PHY_BB_CALTX_GAIN_SET_20_CALTX_GAIN_SET_21_SET(x)                     (((x) << 14) & 0x0fffc000)
-
-/* macros for BB_caltx_gain_set_22 */
-#define PHY_BB_CALTX_GAIN_SET_22_ADDRESS                                                      0x0000a544
-#define PHY_BB_CALTX_GAIN_SET_22_OFFSET                                                       0x0000a544
-#define PHY_BB_CALTX_GAIN_SET_22_CALTX_GAIN_SET_22_MSB                                                13
-#define PHY_BB_CALTX_GAIN_SET_22_CALTX_GAIN_SET_22_LSB                                                 0
-#define PHY_BB_CALTX_GAIN_SET_22_CALTX_GAIN_SET_22_MASK                                       0x00003fff
-#define PHY_BB_CALTX_GAIN_SET_22_CALTX_GAIN_SET_22_GET(x)                      (((x) & 0x00003fff) >> 0)
-#define PHY_BB_CALTX_GAIN_SET_22_CALTX_GAIN_SET_22_SET(x)                      (((x) << 0) & 0x00003fff)
-#define PHY_BB_CALTX_GAIN_SET_22_CALTX_GAIN_SET_23_MSB                                                27
-#define PHY_BB_CALTX_GAIN_SET_22_CALTX_GAIN_SET_23_LSB                                                14
-#define PHY_BB_CALTX_GAIN_SET_22_CALTX_GAIN_SET_23_MASK                                       0x0fffc000
-#define PHY_BB_CALTX_GAIN_SET_22_CALTX_GAIN_SET_23_GET(x)                     (((x) & 0x0fffc000) >> 14)
-#define PHY_BB_CALTX_GAIN_SET_22_CALTX_GAIN_SET_23_SET(x)                     (((x) << 14) & 0x0fffc000)
-
-/* macros for BB_caltx_gain_set_24 */
-#define PHY_BB_CALTX_GAIN_SET_24_ADDRESS                                                      0x0000a548
-#define PHY_BB_CALTX_GAIN_SET_24_OFFSET                                                       0x0000a548
-#define PHY_BB_CALTX_GAIN_SET_24_CALTX_GAIN_SET_24_MSB                                                13
-#define PHY_BB_CALTX_GAIN_SET_24_CALTX_GAIN_SET_24_LSB                                                 0
-#define PHY_BB_CALTX_GAIN_SET_24_CALTX_GAIN_SET_24_MASK                                       0x00003fff
-#define PHY_BB_CALTX_GAIN_SET_24_CALTX_GAIN_SET_24_GET(x)                      (((x) & 0x00003fff) >> 0)
-#define PHY_BB_CALTX_GAIN_SET_24_CALTX_GAIN_SET_24_SET(x)                      (((x) << 0) & 0x00003fff)
-#define PHY_BB_CALTX_GAIN_SET_24_CALTX_GAIN_SET_25_MSB                                                27
-#define PHY_BB_CALTX_GAIN_SET_24_CALTX_GAIN_SET_25_LSB                                                14
-#define PHY_BB_CALTX_GAIN_SET_24_CALTX_GAIN_SET_25_MASK                                       0x0fffc000
-#define PHY_BB_CALTX_GAIN_SET_24_CALTX_GAIN_SET_25_GET(x)                     (((x) & 0x0fffc000) >> 14)
-#define PHY_BB_CALTX_GAIN_SET_24_CALTX_GAIN_SET_25_SET(x)                     (((x) << 14) & 0x0fffc000)
-
-/* macros for BB_caltx_gain_set_26 */
-#define PHY_BB_CALTX_GAIN_SET_26_ADDRESS                                                      0x0000a54c
-#define PHY_BB_CALTX_GAIN_SET_26_OFFSET                                                       0x0000a54c
-#define PHY_BB_CALTX_GAIN_SET_26_CALTX_GAIN_SET_26_MSB                                                13
-#define PHY_BB_CALTX_GAIN_SET_26_CALTX_GAIN_SET_26_LSB                                                 0
-#define PHY_BB_CALTX_GAIN_SET_26_CALTX_GAIN_SET_26_MASK                                       0x00003fff
-#define PHY_BB_CALTX_GAIN_SET_26_CALTX_GAIN_SET_26_GET(x)                      (((x) & 0x00003fff) >> 0)
-#define PHY_BB_CALTX_GAIN_SET_26_CALTX_GAIN_SET_26_SET(x)                      (((x) << 0) & 0x00003fff)
-#define PHY_BB_CALTX_GAIN_SET_26_CALTX_GAIN_SET_27_MSB                                                27
-#define PHY_BB_CALTX_GAIN_SET_26_CALTX_GAIN_SET_27_LSB                                                14
-#define PHY_BB_CALTX_GAIN_SET_26_CALTX_GAIN_SET_27_MASK                                       0x0fffc000
-#define PHY_BB_CALTX_GAIN_SET_26_CALTX_GAIN_SET_27_GET(x)                     (((x) & 0x0fffc000) >> 14)
-#define PHY_BB_CALTX_GAIN_SET_26_CALTX_GAIN_SET_27_SET(x)                     (((x) << 14) & 0x0fffc000)
-
-/* macros for BB_caltx_gain_set_28 */
-#define PHY_BB_CALTX_GAIN_SET_28_ADDRESS                                                      0x0000a550
-#define PHY_BB_CALTX_GAIN_SET_28_OFFSET                                                       0x0000a550
-#define PHY_BB_CALTX_GAIN_SET_28_CALTX_GAIN_SET_28_MSB                                                13
-#define PHY_BB_CALTX_GAIN_SET_28_CALTX_GAIN_SET_28_LSB                                                 0
-#define PHY_BB_CALTX_GAIN_SET_28_CALTX_GAIN_SET_28_MASK                                       0x00003fff
-#define PHY_BB_CALTX_GAIN_SET_28_CALTX_GAIN_SET_28_GET(x)                      (((x) & 0x00003fff) >> 0)
-#define PHY_BB_CALTX_GAIN_SET_28_CALTX_GAIN_SET_28_SET(x)                      (((x) << 0) & 0x00003fff)
-#define PHY_BB_CALTX_GAIN_SET_28_CALTX_GAIN_SET_29_MSB                                                27
-#define PHY_BB_CALTX_GAIN_SET_28_CALTX_GAIN_SET_29_LSB                                                14
-#define PHY_BB_CALTX_GAIN_SET_28_CALTX_GAIN_SET_29_MASK                                       0x0fffc000
-#define PHY_BB_CALTX_GAIN_SET_28_CALTX_GAIN_SET_29_GET(x)                     (((x) & 0x0fffc000) >> 14)
-#define PHY_BB_CALTX_GAIN_SET_28_CALTX_GAIN_SET_29_SET(x)                     (((x) << 14) & 0x0fffc000)
-
-/* macros for BB_caltx_gain_set_30 */
-#define PHY_BB_CALTX_GAIN_SET_30_ADDRESS                                                      0x0000a554
-#define PHY_BB_CALTX_GAIN_SET_30_OFFSET                                                       0x0000a554
-#define PHY_BB_CALTX_GAIN_SET_30_CALTX_GAIN_SET_30_MSB                                                13
-#define PHY_BB_CALTX_GAIN_SET_30_CALTX_GAIN_SET_30_LSB                                                 0
-#define PHY_BB_CALTX_GAIN_SET_30_CALTX_GAIN_SET_30_MASK                                       0x00003fff
-#define PHY_BB_CALTX_GAIN_SET_30_CALTX_GAIN_SET_30_GET(x)                      (((x) & 0x00003fff) >> 0)
-#define PHY_BB_CALTX_GAIN_SET_30_CALTX_GAIN_SET_30_SET(x)                      (((x) << 0) & 0x00003fff)
-#define PHY_BB_CALTX_GAIN_SET_30_CALTX_GAIN_SET_31_MSB                                                27
-#define PHY_BB_CALTX_GAIN_SET_30_CALTX_GAIN_SET_31_LSB                                                14
-#define PHY_BB_CALTX_GAIN_SET_30_CALTX_GAIN_SET_31_MASK                                       0x0fffc000
-#define PHY_BB_CALTX_GAIN_SET_30_CALTX_GAIN_SET_31_GET(x)                     (((x) & 0x0fffc000) >> 14)
-#define PHY_BB_CALTX_GAIN_SET_30_CALTX_GAIN_SET_31_SET(x)                     (((x) << 14) & 0x0fffc000)
-
-/* macros for BB_txiqcal_meas_b0 */
-#define PHY_BB_TXIQCAL_MEAS_B0_ADDRESS                                                        0x0000a558
-#define PHY_BB_TXIQCAL_MEAS_B0_OFFSET                                                         0x0000a558
-#define PHY_BB_TXIQCAL_MEAS_B0_TXIQC_MEAS_DATA0_0_MSB                                                 11
-#define PHY_BB_TXIQCAL_MEAS_B0_TXIQC_MEAS_DATA0_0_LSB                                                  0
-#define PHY_BB_TXIQCAL_MEAS_B0_TXIQC_MEAS_DATA0_0_MASK                                        0x00000fff
-#define PHY_BB_TXIQCAL_MEAS_B0_TXIQC_MEAS_DATA0_0_GET(x)                       (((x) & 0x00000fff) >> 0)
-#define PHY_BB_TXIQCAL_MEAS_B0_TXIQC_MEAS_DATA1_0_MSB                                                 23
-#define PHY_BB_TXIQCAL_MEAS_B0_TXIQC_MEAS_DATA1_0_LSB                                                 12
-#define PHY_BB_TXIQCAL_MEAS_B0_TXIQC_MEAS_DATA1_0_MASK                                        0x00fff000
-#define PHY_BB_TXIQCAL_MEAS_B0_TXIQC_MEAS_DATA1_0_GET(x)                      (((x) & 0x00fff000) >> 12)
-
-/* macros for BB_txiqcal_start */
-#define PHY_BB_TXIQCAL_START_ADDRESS                                                          0x0000a6d8
-#define PHY_BB_TXIQCAL_START_OFFSET                                                           0x0000a6d8
-#define PHY_BB_TXIQCAL_START_DO_TX_IQCAL_MSB                                                           0
-#define PHY_BB_TXIQCAL_START_DO_TX_IQCAL_LSB                                                           0
-#define PHY_BB_TXIQCAL_START_DO_TX_IQCAL_MASK                                                 0x00000001
-#define PHY_BB_TXIQCAL_START_DO_TX_IQCAL_GET(x)                                (((x) & 0x00000001) >> 0)
-#define PHY_BB_TXIQCAL_START_DO_TX_IQCAL_SET(x)                                (((x) << 0) & 0x00000001)
-
-/* macros for BB_txiqcal_control_0 */
-#define PHY_BB_TXIQCAL_CONTROL_0_ADDRESS                                                      0x0000a6dc
-#define PHY_BB_TXIQCAL_CONTROL_0_OFFSET                                                       0x0000a6dc
-#define PHY_BB_TXIQCAL_CONTROL_0_IQC_TX_TABLE_SEL_MSB                                                  0
-#define PHY_BB_TXIQCAL_CONTROL_0_IQC_TX_TABLE_SEL_LSB                                                  0
-#define PHY_BB_TXIQCAL_CONTROL_0_IQC_TX_TABLE_SEL_MASK                                        0x00000001
-#define PHY_BB_TXIQCAL_CONTROL_0_IQC_TX_TABLE_SEL_GET(x)                       (((x) & 0x00000001) >> 0)
-#define PHY_BB_TXIQCAL_CONTROL_0_IQC_TX_TABLE_SEL_SET(x)                       (((x) << 0) & 0x00000001)
-#define PHY_BB_TXIQCAL_CONTROL_0_BASE_TX_TONE_DB_MSB                                                   6
-#define PHY_BB_TXIQCAL_CONTROL_0_BASE_TX_TONE_DB_LSB                                                   1
-#define PHY_BB_TXIQCAL_CONTROL_0_BASE_TX_TONE_DB_MASK                                         0x0000007e
-#define PHY_BB_TXIQCAL_CONTROL_0_BASE_TX_TONE_DB_GET(x)                        (((x) & 0x0000007e) >> 1)
-#define PHY_BB_TXIQCAL_CONTROL_0_BASE_TX_TONE_DB_SET(x)                        (((x) << 1) & 0x0000007e)
-#define PHY_BB_TXIQCAL_CONTROL_0_MAX_TX_TONE_GAIN_MSB                                                 12
-#define PHY_BB_TXIQCAL_CONTROL_0_MAX_TX_TONE_GAIN_LSB                                                  7
-#define PHY_BB_TXIQCAL_CONTROL_0_MAX_TX_TONE_GAIN_MASK                                        0x00001f80
-#define PHY_BB_TXIQCAL_CONTROL_0_MAX_TX_TONE_GAIN_GET(x)                       (((x) & 0x00001f80) >> 7)
-#define PHY_BB_TXIQCAL_CONTROL_0_MAX_TX_TONE_GAIN_SET(x)                       (((x) << 7) & 0x00001f80)
-#define PHY_BB_TXIQCAL_CONTROL_0_MIN_TX_TONE_GAIN_MSB                                                 18
-#define PHY_BB_TXIQCAL_CONTROL_0_MIN_TX_TONE_GAIN_LSB                                                 13
-#define PHY_BB_TXIQCAL_CONTROL_0_MIN_TX_TONE_GAIN_MASK                                        0x0007e000
-#define PHY_BB_TXIQCAL_CONTROL_0_MIN_TX_TONE_GAIN_GET(x)                      (((x) & 0x0007e000) >> 13)
-#define PHY_BB_TXIQCAL_CONTROL_0_MIN_TX_TONE_GAIN_SET(x)                      (((x) << 13) & 0x0007e000)
-#define PHY_BB_TXIQCAL_CONTROL_0_CALTXSHIFT_DELAY_MSB                                                 22
-#define PHY_BB_TXIQCAL_CONTROL_0_CALTXSHIFT_DELAY_LSB                                                 19
-#define PHY_BB_TXIQCAL_CONTROL_0_CALTXSHIFT_DELAY_MASK                                        0x00780000
-#define PHY_BB_TXIQCAL_CONTROL_0_CALTXSHIFT_DELAY_GET(x)                      (((x) & 0x00780000) >> 19)
-#define PHY_BB_TXIQCAL_CONTROL_0_CALTXSHIFT_DELAY_SET(x)                      (((x) << 19) & 0x00780000)
-#define PHY_BB_TXIQCAL_CONTROL_0_LOOPBACK_DELAY_MSB                                                   29
-#define PHY_BB_TXIQCAL_CONTROL_0_LOOPBACK_DELAY_LSB                                                   23
-#define PHY_BB_TXIQCAL_CONTROL_0_LOOPBACK_DELAY_MASK                                          0x3f800000
-#define PHY_BB_TXIQCAL_CONTROL_0_LOOPBACK_DELAY_GET(x)                        (((x) & 0x3f800000) >> 23)
-#define PHY_BB_TXIQCAL_CONTROL_0_LOOPBACK_DELAY_SET(x)                        (((x) << 23) & 0x3f800000)
-
-/* macros for BB_txiqcal_control_1 */
-#define PHY_BB_TXIQCAL_CONTROL_1_ADDRESS                                                      0x0000a6e0
-#define PHY_BB_TXIQCAL_CONTROL_1_OFFSET                                                       0x0000a6e0
-#define PHY_BB_TXIQCAL_CONTROL_1_RX_INIT_GAIN_DB_MSB                                                   5
-#define PHY_BB_TXIQCAL_CONTROL_1_RX_INIT_GAIN_DB_LSB                                                   0
-#define PHY_BB_TXIQCAL_CONTROL_1_RX_INIT_GAIN_DB_MASK                                         0x0000003f
-#define PHY_BB_TXIQCAL_CONTROL_1_RX_INIT_GAIN_DB_GET(x)                        (((x) & 0x0000003f) >> 0)
-#define PHY_BB_TXIQCAL_CONTROL_1_RX_INIT_GAIN_DB_SET(x)                        (((x) << 0) & 0x0000003f)
-#define PHY_BB_TXIQCAL_CONTROL_1_MAX_RX_GAIN_DB_MSB                                                   11
-#define PHY_BB_TXIQCAL_CONTROL_1_MAX_RX_GAIN_DB_LSB                                                    6
-#define PHY_BB_TXIQCAL_CONTROL_1_MAX_RX_GAIN_DB_MASK                                          0x00000fc0
-#define PHY_BB_TXIQCAL_CONTROL_1_MAX_RX_GAIN_DB_GET(x)                         (((x) & 0x00000fc0) >> 6)
-#define PHY_BB_TXIQCAL_CONTROL_1_MAX_RX_GAIN_DB_SET(x)                         (((x) << 6) & 0x00000fc0)
-#define PHY_BB_TXIQCAL_CONTROL_1_MIN_RX_GAIN_DB_MSB                                                   17
-#define PHY_BB_TXIQCAL_CONTROL_1_MIN_RX_GAIN_DB_LSB                                                   12
-#define PHY_BB_TXIQCAL_CONTROL_1_MIN_RX_GAIN_DB_MASK                                          0x0003f000
-#define PHY_BB_TXIQCAL_CONTROL_1_MIN_RX_GAIN_DB_GET(x)                        (((x) & 0x0003f000) >> 12)
-#define PHY_BB_TXIQCAL_CONTROL_1_MIN_RX_GAIN_DB_SET(x)                        (((x) << 12) & 0x0003f000)
-#define PHY_BB_TXIQCAL_CONTROL_1_IQCORR_I_Q_COFF_DELPT_MSB                                            24
-#define PHY_BB_TXIQCAL_CONTROL_1_IQCORR_I_Q_COFF_DELPT_LSB                                            18
-#define PHY_BB_TXIQCAL_CONTROL_1_IQCORR_I_Q_COFF_DELPT_MASK                                   0x01fc0000
-#define PHY_BB_TXIQCAL_CONTROL_1_IQCORR_I_Q_COFF_DELPT_GET(x)                 (((x) & 0x01fc0000) >> 18)
-#define PHY_BB_TXIQCAL_CONTROL_1_IQCORR_I_Q_COFF_DELPT_SET(x)                 (((x) << 18) & 0x01fc0000)
-
-/* macros for BB_txiqcal_control_2 */
-#define PHY_BB_TXIQCAL_CONTROL_2_ADDRESS                                                      0x0000a6e4
-#define PHY_BB_TXIQCAL_CONTROL_2_OFFSET                                                       0x0000a6e4
-#define PHY_BB_TXIQCAL_CONTROL_2_IQC_FORCED_PAGAIN_MSB                                                 3
-#define PHY_BB_TXIQCAL_CONTROL_2_IQC_FORCED_PAGAIN_LSB                                                 0
-#define PHY_BB_TXIQCAL_CONTROL_2_IQC_FORCED_PAGAIN_MASK                                       0x0000000f
-#define PHY_BB_TXIQCAL_CONTROL_2_IQC_FORCED_PAGAIN_GET(x)                      (((x) & 0x0000000f) >> 0)
-#define PHY_BB_TXIQCAL_CONTROL_2_IQC_FORCED_PAGAIN_SET(x)                      (((x) << 0) & 0x0000000f)
-#define PHY_BB_TXIQCAL_CONTROL_2_IQCAL_MIN_TX_GAIN_MSB                                                 8
-#define PHY_BB_TXIQCAL_CONTROL_2_IQCAL_MIN_TX_GAIN_LSB                                                 4
-#define PHY_BB_TXIQCAL_CONTROL_2_IQCAL_MIN_TX_GAIN_MASK                                       0x000001f0
-#define PHY_BB_TXIQCAL_CONTROL_2_IQCAL_MIN_TX_GAIN_GET(x)                      (((x) & 0x000001f0) >> 4)
-#define PHY_BB_TXIQCAL_CONTROL_2_IQCAL_MIN_TX_GAIN_SET(x)                      (((x) << 4) & 0x000001f0)
-#define PHY_BB_TXIQCAL_CONTROL_2_IQCAL_MAX_TX_GAIN_MSB                                                13
-#define PHY_BB_TXIQCAL_CONTROL_2_IQCAL_MAX_TX_GAIN_LSB                                                 9
-#define PHY_BB_TXIQCAL_CONTROL_2_IQCAL_MAX_TX_GAIN_MASK                                       0x00003e00
-#define PHY_BB_TXIQCAL_CONTROL_2_IQCAL_MAX_TX_GAIN_GET(x)                      (((x) & 0x00003e00) >> 9)
-#define PHY_BB_TXIQCAL_CONTROL_2_IQCAL_MAX_TX_GAIN_SET(x)                      (((x) << 9) & 0x00003e00)
-
-/* macros for BB_txiqcal_control_3 */
-#define PHY_BB_TXIQCAL_CONTROL_3_ADDRESS                                                      0x0000a6e8
-#define PHY_BB_TXIQCAL_CONTROL_3_OFFSET                                                       0x0000a6e8
-#define PHY_BB_TXIQCAL_CONTROL_3_PWR_HIGH_DB_MSB                                                       5
-#define PHY_BB_TXIQCAL_CONTROL_3_PWR_HIGH_DB_LSB                                                       0
-#define PHY_BB_TXIQCAL_CONTROL_3_PWR_HIGH_DB_MASK                                             0x0000003f
-#define PHY_BB_TXIQCAL_CONTROL_3_PWR_HIGH_DB_GET(x)                            (((x) & 0x0000003f) >> 0)
-#define PHY_BB_TXIQCAL_CONTROL_3_PWR_HIGH_DB_SET(x)                            (((x) << 0) & 0x0000003f)
-#define PHY_BB_TXIQCAL_CONTROL_3_PWR_LOW_DB_MSB                                                       11
-#define PHY_BB_TXIQCAL_CONTROL_3_PWR_LOW_DB_LSB                                                        6
-#define PHY_BB_TXIQCAL_CONTROL_3_PWR_LOW_DB_MASK                                              0x00000fc0
-#define PHY_BB_TXIQCAL_CONTROL_3_PWR_LOW_DB_GET(x)                             (((x) & 0x00000fc0) >> 6)
-#define PHY_BB_TXIQCAL_CONTROL_3_PWR_LOW_DB_SET(x)                             (((x) << 6) & 0x00000fc0)
-#define PHY_BB_TXIQCAL_CONTROL_3_IQCAL_TONE_PHS_STEP_MSB                                              21
-#define PHY_BB_TXIQCAL_CONTROL_3_IQCAL_TONE_PHS_STEP_LSB                                              12
-#define PHY_BB_TXIQCAL_CONTROL_3_IQCAL_TONE_PHS_STEP_MASK                                     0x003ff000
-#define PHY_BB_TXIQCAL_CONTROL_3_IQCAL_TONE_PHS_STEP_GET(x)                   (((x) & 0x003ff000) >> 12)
-#define PHY_BB_TXIQCAL_CONTROL_3_IQCAL_TONE_PHS_STEP_SET(x)                   (((x) << 12) & 0x003ff000)
-#define PHY_BB_TXIQCAL_CONTROL_3_DC_EST_LEN_MSB                                                       23
-#define PHY_BB_TXIQCAL_CONTROL_3_DC_EST_LEN_LSB                                                       22
-#define PHY_BB_TXIQCAL_CONTROL_3_DC_EST_LEN_MASK                                              0x00c00000
-#define PHY_BB_TXIQCAL_CONTROL_3_DC_EST_LEN_GET(x)                            (((x) & 0x00c00000) >> 22)
-#define PHY_BB_TXIQCAL_CONTROL_3_DC_EST_LEN_SET(x)                            (((x) << 22) & 0x00c00000)
-#define PHY_BB_TXIQCAL_CONTROL_3_ADC_SAT_LEN_MSB                                                      24
-#define PHY_BB_TXIQCAL_CONTROL_3_ADC_SAT_LEN_LSB                                                      24
-#define PHY_BB_TXIQCAL_CONTROL_3_ADC_SAT_LEN_MASK                                             0x01000000
-#define PHY_BB_TXIQCAL_CONTROL_3_ADC_SAT_LEN_GET(x)                           (((x) & 0x01000000) >> 24)
-#define PHY_BB_TXIQCAL_CONTROL_3_ADC_SAT_LEN_SET(x)                           (((x) << 24) & 0x01000000)
-#define PHY_BB_TXIQCAL_CONTROL_3_ADC_SAT_SEL_MSB                                                      26
-#define PHY_BB_TXIQCAL_CONTROL_3_ADC_SAT_SEL_LSB                                                      25
-#define PHY_BB_TXIQCAL_CONTROL_3_ADC_SAT_SEL_MASK                                             0x06000000
-#define PHY_BB_TXIQCAL_CONTROL_3_ADC_SAT_SEL_GET(x)                           (((x) & 0x06000000) >> 25)
-#define PHY_BB_TXIQCAL_CONTROL_3_ADC_SAT_SEL_SET(x)                           (((x) << 25) & 0x06000000)
-#define PHY_BB_TXIQCAL_CONTROL_3_IQCAL_MEAS_LEN_MSB                                                   28
-#define PHY_BB_TXIQCAL_CONTROL_3_IQCAL_MEAS_LEN_LSB                                                   27
-#define PHY_BB_TXIQCAL_CONTROL_3_IQCAL_MEAS_LEN_MASK                                          0x18000000
-#define PHY_BB_TXIQCAL_CONTROL_3_IQCAL_MEAS_LEN_GET(x)                        (((x) & 0x18000000) >> 27)
-#define PHY_BB_TXIQCAL_CONTROL_3_IQCAL_MEAS_LEN_SET(x)                        (((x) << 27) & 0x18000000)
-#define PHY_BB_TXIQCAL_CONTROL_3_DESIRED_SIZE_DB_MSB                                                  30
-#define PHY_BB_TXIQCAL_CONTROL_3_DESIRED_SIZE_DB_LSB                                                  29
-#define PHY_BB_TXIQCAL_CONTROL_3_DESIRED_SIZE_DB_MASK                                         0x60000000
-#define PHY_BB_TXIQCAL_CONTROL_3_DESIRED_SIZE_DB_GET(x)                       (((x) & 0x60000000) >> 29)
-#define PHY_BB_TXIQCAL_CONTROL_3_DESIRED_SIZE_DB_SET(x)                       (((x) << 29) & 0x60000000)
-#define PHY_BB_TXIQCAL_CONTROL_3_TX_IQCORR_EN_MSB                                                     31
-#define PHY_BB_TXIQCAL_CONTROL_3_TX_IQCORR_EN_LSB                                                     31
-#define PHY_BB_TXIQCAL_CONTROL_3_TX_IQCORR_EN_MASK                                            0x80000000
-#define PHY_BB_TXIQCAL_CONTROL_3_TX_IQCORR_EN_GET(x)                          (((x) & 0x80000000) >> 31)
-#define PHY_BB_TXIQCAL_CONTROL_3_TX_IQCORR_EN_SET(x)                          (((x) << 31) & 0x80000000)
-
-/* macros for BB_txiq_corr_coeff_01_b0 */
-#define PHY_BB_TXIQ_CORR_COEFF_01_B0_ADDRESS                                                  0x0000a6ec
-#define PHY_BB_TXIQ_CORR_COEFF_01_B0_OFFSET                                                   0x0000a6ec
-#define PHY_BB_TXIQ_CORR_COEFF_01_B0_IQC_COEFF_TABLE_0_0_MSB                                          13
-#define PHY_BB_TXIQ_CORR_COEFF_01_B0_IQC_COEFF_TABLE_0_0_LSB                                           0
-#define PHY_BB_TXIQ_CORR_COEFF_01_B0_IQC_COEFF_TABLE_0_0_MASK                                 0x00003fff
-#define PHY_BB_TXIQ_CORR_COEFF_01_B0_IQC_COEFF_TABLE_0_0_GET(x)                (((x) & 0x00003fff) >> 0)
-#define PHY_BB_TXIQ_CORR_COEFF_01_B0_IQC_COEFF_TABLE_0_0_SET(x)                (((x) << 0) & 0x00003fff)
-#define PHY_BB_TXIQ_CORR_COEFF_01_B0_IQC_COEFF_TABLE_1_0_MSB                                          27
-#define PHY_BB_TXIQ_CORR_COEFF_01_B0_IQC_COEFF_TABLE_1_0_LSB                                          14
-#define PHY_BB_TXIQ_CORR_COEFF_01_B0_IQC_COEFF_TABLE_1_0_MASK                                 0x0fffc000
-#define PHY_BB_TXIQ_CORR_COEFF_01_B0_IQC_COEFF_TABLE_1_0_GET(x)               (((x) & 0x0fffc000) >> 14)
-#define PHY_BB_TXIQ_CORR_COEFF_01_B0_IQC_COEFF_TABLE_1_0_SET(x)               (((x) << 14) & 0x0fffc000)
-
-/* macros for BB_txiq_corr_coeff_23_b0 */
-#define PHY_BB_TXIQ_CORR_COEFF_23_B0_ADDRESS                                                  0x0000a6f0
-#define PHY_BB_TXIQ_CORR_COEFF_23_B0_OFFSET                                                   0x0000a6f0
-#define PHY_BB_TXIQ_CORR_COEFF_23_B0_IQC_COEFF_TABLE_2_0_MSB                                          13
-#define PHY_BB_TXIQ_CORR_COEFF_23_B0_IQC_COEFF_TABLE_2_0_LSB                                           0
-#define PHY_BB_TXIQ_CORR_COEFF_23_B0_IQC_COEFF_TABLE_2_0_MASK                                 0x00003fff
-#define PHY_BB_TXIQ_CORR_COEFF_23_B0_IQC_COEFF_TABLE_2_0_GET(x)                (((x) & 0x00003fff) >> 0)
-#define PHY_BB_TXIQ_CORR_COEFF_23_B0_IQC_COEFF_TABLE_2_0_SET(x)                (((x) << 0) & 0x00003fff)
-#define PHY_BB_TXIQ_CORR_COEFF_23_B0_IQC_COEFF_TABLE_3_0_MSB                                          27
-#define PHY_BB_TXIQ_CORR_COEFF_23_B0_IQC_COEFF_TABLE_3_0_LSB                                          14
-#define PHY_BB_TXIQ_CORR_COEFF_23_B0_IQC_COEFF_TABLE_3_0_MASK                                 0x0fffc000
-#define PHY_BB_TXIQ_CORR_COEFF_23_B0_IQC_COEFF_TABLE_3_0_GET(x)               (((x) & 0x0fffc000) >> 14)
-#define PHY_BB_TXIQ_CORR_COEFF_23_B0_IQC_COEFF_TABLE_3_0_SET(x)               (((x) << 14) & 0x0fffc000)
-
-/* macros for BB_txiq_corr_coeff_45_b0 */
-#define PHY_BB_TXIQ_CORR_COEFF_45_B0_ADDRESS                                                  0x0000a6f4
-#define PHY_BB_TXIQ_CORR_COEFF_45_B0_OFFSET                                                   0x0000a6f4
-#define PHY_BB_TXIQ_CORR_COEFF_45_B0_IQC_COEFF_TABLE_4_0_MSB                                          13
-#define PHY_BB_TXIQ_CORR_COEFF_45_B0_IQC_COEFF_TABLE_4_0_LSB                                           0
-#define PHY_BB_TXIQ_CORR_COEFF_45_B0_IQC_COEFF_TABLE_4_0_MASK                                 0x00003fff
-#define PHY_BB_TXIQ_CORR_COEFF_45_B0_IQC_COEFF_TABLE_4_0_GET(x)                (((x) & 0x00003fff) >> 0)
-#define PHY_BB_TXIQ_CORR_COEFF_45_B0_IQC_COEFF_TABLE_4_0_SET(x)                (((x) << 0) & 0x00003fff)
-#define PHY_BB_TXIQ_CORR_COEFF_45_B0_IQC_COEFF_TABLE_5_0_MSB                                          27
-#define PHY_BB_TXIQ_CORR_COEFF_45_B0_IQC_COEFF_TABLE_5_0_LSB                                          14
-#define PHY_BB_TXIQ_CORR_COEFF_45_B0_IQC_COEFF_TABLE_5_0_MASK                                 0x0fffc000
-#define PHY_BB_TXIQ_CORR_COEFF_45_B0_IQC_COEFF_TABLE_5_0_GET(x)               (((x) & 0x0fffc000) >> 14)
-#define PHY_BB_TXIQ_CORR_COEFF_45_B0_IQC_COEFF_TABLE_5_0_SET(x)               (((x) << 14) & 0x0fffc000)
-
-/* macros for BB_txiq_corr_coeff_67_b0 */
-#define PHY_BB_TXIQ_CORR_COEFF_67_B0_ADDRESS                                                  0x0000a6f8
-#define PHY_BB_TXIQ_CORR_COEFF_67_B0_OFFSET                                                   0x0000a6f8
-#define PHY_BB_TXIQ_CORR_COEFF_67_B0_IQC_COEFF_TABLE_6_0_MSB                                          13
-#define PHY_BB_TXIQ_CORR_COEFF_67_B0_IQC_COEFF_TABLE_6_0_LSB                                           0
-#define PHY_BB_TXIQ_CORR_COEFF_67_B0_IQC_COEFF_TABLE_6_0_MASK                                 0x00003fff
-#define PHY_BB_TXIQ_CORR_COEFF_67_B0_IQC_COEFF_TABLE_6_0_GET(x)                (((x) & 0x00003fff) >> 0)
-#define PHY_BB_TXIQ_CORR_COEFF_67_B0_IQC_COEFF_TABLE_6_0_SET(x)                (((x) << 0) & 0x00003fff)
-#define PHY_BB_TXIQ_CORR_COEFF_67_B0_IQC_COEFF_TABLE_7_0_MSB                                          27
-#define PHY_BB_TXIQ_CORR_COEFF_67_B0_IQC_COEFF_TABLE_7_0_LSB                                          14
-#define PHY_BB_TXIQ_CORR_COEFF_67_B0_IQC_COEFF_TABLE_7_0_MASK                                 0x0fffc000
-#define PHY_BB_TXIQ_CORR_COEFF_67_B0_IQC_COEFF_TABLE_7_0_GET(x)               (((x) & 0x0fffc000) >> 14)
-#define PHY_BB_TXIQ_CORR_COEFF_67_B0_IQC_COEFF_TABLE_7_0_SET(x)               (((x) << 14) & 0x0fffc000)
-
-/* macros for BB_txiq_corr_coeff_89_b0 */
-#define PHY_BB_TXIQ_CORR_COEFF_89_B0_ADDRESS                                                  0x0000a6fc
-#define PHY_BB_TXIQ_CORR_COEFF_89_B0_OFFSET                                                   0x0000a6fc
-#define PHY_BB_TXIQ_CORR_COEFF_89_B0_IQC_COEFF_TABLE_8_0_MSB                                          13
-#define PHY_BB_TXIQ_CORR_COEFF_89_B0_IQC_COEFF_TABLE_8_0_LSB                                           0
-#define PHY_BB_TXIQ_CORR_COEFF_89_B0_IQC_COEFF_TABLE_8_0_MASK                                 0x00003fff
-#define PHY_BB_TXIQ_CORR_COEFF_89_B0_IQC_COEFF_TABLE_8_0_GET(x)                (((x) & 0x00003fff) >> 0)
-#define PHY_BB_TXIQ_CORR_COEFF_89_B0_IQC_COEFF_TABLE_8_0_SET(x)                (((x) << 0) & 0x00003fff)
-#define PHY_BB_TXIQ_CORR_COEFF_89_B0_IQC_COEFF_TABLE_9_0_MSB                                          27
-#define PHY_BB_TXIQ_CORR_COEFF_89_B0_IQC_COEFF_TABLE_9_0_LSB                                          14
-#define PHY_BB_TXIQ_CORR_COEFF_89_B0_IQC_COEFF_TABLE_9_0_MASK                                 0x0fffc000
-#define PHY_BB_TXIQ_CORR_COEFF_89_B0_IQC_COEFF_TABLE_9_0_GET(x)               (((x) & 0x0fffc000) >> 14)
-#define PHY_BB_TXIQ_CORR_COEFF_89_B0_IQC_COEFF_TABLE_9_0_SET(x)               (((x) << 14) & 0x0fffc000)
-
-/* macros for BB_txiq_corr_coeff_ab_b0 */
-#define PHY_BB_TXIQ_CORR_COEFF_AB_B0_ADDRESS                                                  0x0000a700
-#define PHY_BB_TXIQ_CORR_COEFF_AB_B0_OFFSET                                                   0x0000a700
-#define PHY_BB_TXIQ_CORR_COEFF_AB_B0_IQC_COEFF_TABLE_A_0_MSB                                          13
-#define PHY_BB_TXIQ_CORR_COEFF_AB_B0_IQC_COEFF_TABLE_A_0_LSB                                           0
-#define PHY_BB_TXIQ_CORR_COEFF_AB_B0_IQC_COEFF_TABLE_A_0_MASK                                 0x00003fff
-#define PHY_BB_TXIQ_CORR_COEFF_AB_B0_IQC_COEFF_TABLE_A_0_GET(x)                (((x) & 0x00003fff) >> 0)
-#define PHY_BB_TXIQ_CORR_COEFF_AB_B0_IQC_COEFF_TABLE_A_0_SET(x)                (((x) << 0) & 0x00003fff)
-#define PHY_BB_TXIQ_CORR_COEFF_AB_B0_IQC_COEFF_TABLE_B_0_MSB                                          27
-#define PHY_BB_TXIQ_CORR_COEFF_AB_B0_IQC_COEFF_TABLE_B_0_LSB                                          14
-#define PHY_BB_TXIQ_CORR_COEFF_AB_B0_IQC_COEFF_TABLE_B_0_MASK                                 0x0fffc000
-#define PHY_BB_TXIQ_CORR_COEFF_AB_B0_IQC_COEFF_TABLE_B_0_GET(x)               (((x) & 0x0fffc000) >> 14)
-#define PHY_BB_TXIQ_CORR_COEFF_AB_B0_IQC_COEFF_TABLE_B_0_SET(x)               (((x) << 14) & 0x0fffc000)
-
-/* macros for BB_txiq_corr_coeff_cd_b0 */
-#define PHY_BB_TXIQ_CORR_COEFF_CD_B0_ADDRESS                                                  0x0000a704
-#define PHY_BB_TXIQ_CORR_COEFF_CD_B0_OFFSET                                                   0x0000a704
-#define PHY_BB_TXIQ_CORR_COEFF_CD_B0_IQC_COEFF_TABLE_C_0_MSB                                          13
-#define PHY_BB_TXIQ_CORR_COEFF_CD_B0_IQC_COEFF_TABLE_C_0_LSB                                           0
-#define PHY_BB_TXIQ_CORR_COEFF_CD_B0_IQC_COEFF_TABLE_C_0_MASK                                 0x00003fff
-#define PHY_BB_TXIQ_CORR_COEFF_CD_B0_IQC_COEFF_TABLE_C_0_GET(x)                (((x) & 0x00003fff) >> 0)
-#define PHY_BB_TXIQ_CORR_COEFF_CD_B0_IQC_COEFF_TABLE_C_0_SET(x)                (((x) << 0) & 0x00003fff)
-#define PHY_BB_TXIQ_CORR_COEFF_CD_B0_IQC_COEFF_TABLE_D_0_MSB                                          27
-#define PHY_BB_TXIQ_CORR_COEFF_CD_B0_IQC_COEFF_TABLE_D_0_LSB                                          14
-#define PHY_BB_TXIQ_CORR_COEFF_CD_B0_IQC_COEFF_TABLE_D_0_MASK                                 0x0fffc000
-#define PHY_BB_TXIQ_CORR_COEFF_CD_B0_IQC_COEFF_TABLE_D_0_GET(x)               (((x) & 0x0fffc000) >> 14)
-#define PHY_BB_TXIQ_CORR_COEFF_CD_B0_IQC_COEFF_TABLE_D_0_SET(x)               (((x) << 14) & 0x0fffc000)
-
-/* macros for BB_txiq_corr_coeff_ef_b0 */
-#define PHY_BB_TXIQ_CORR_COEFF_EF_B0_ADDRESS                                                  0x0000a708
-#define PHY_BB_TXIQ_CORR_COEFF_EF_B0_OFFSET                                                   0x0000a708
-#define PHY_BB_TXIQ_CORR_COEFF_EF_B0_IQC_COEFF_TABLE_E_0_MSB                                          13
-#define PHY_BB_TXIQ_CORR_COEFF_EF_B0_IQC_COEFF_TABLE_E_0_LSB                                           0
-#define PHY_BB_TXIQ_CORR_COEFF_EF_B0_IQC_COEFF_TABLE_E_0_MASK                                 0x00003fff
-#define PHY_BB_TXIQ_CORR_COEFF_EF_B0_IQC_COEFF_TABLE_E_0_GET(x)                (((x) & 0x00003fff) >> 0)
-#define PHY_BB_TXIQ_CORR_COEFF_EF_B0_IQC_COEFF_TABLE_E_0_SET(x)                (((x) << 0) & 0x00003fff)
-#define PHY_BB_TXIQ_CORR_COEFF_EF_B0_IQC_COEFF_TABLE_F_0_MSB                                          27
-#define PHY_BB_TXIQ_CORR_COEFF_EF_B0_IQC_COEFF_TABLE_F_0_LSB                                          14
-#define PHY_BB_TXIQ_CORR_COEFF_EF_B0_IQC_COEFF_TABLE_F_0_MASK                                 0x0fffc000
-#define PHY_BB_TXIQ_CORR_COEFF_EF_B0_IQC_COEFF_TABLE_F_0_GET(x)               (((x) & 0x0fffc000) >> 14)
-#define PHY_BB_TXIQ_CORR_COEFF_EF_B0_IQC_COEFF_TABLE_F_0_SET(x)               (((x) << 14) & 0x0fffc000)
-
-/* macros for BB_cal_rxbb_gain_tbl_0 */
-#define PHY_BB_CAL_RXBB_GAIN_TBL_0_ADDRESS                                                    0x0000a70c
-#define PHY_BB_CAL_RXBB_GAIN_TBL_0_OFFSET                                                     0x0000a70c
-#define PHY_BB_CAL_RXBB_GAIN_TBL_0_TXCAL_RX_BB_GAIN_TABLE_0_MSB                                        5
-#define PHY_BB_CAL_RXBB_GAIN_TBL_0_TXCAL_RX_BB_GAIN_TABLE_0_LSB                                        0
-#define PHY_BB_CAL_RXBB_GAIN_TBL_0_TXCAL_RX_BB_GAIN_TABLE_0_MASK                              0x0000003f
-#define PHY_BB_CAL_RXBB_GAIN_TBL_0_TXCAL_RX_BB_GAIN_TABLE_0_GET(x)             (((x) & 0x0000003f) >> 0)
-#define PHY_BB_CAL_RXBB_GAIN_TBL_0_TXCAL_RX_BB_GAIN_TABLE_0_SET(x)             (((x) << 0) & 0x0000003f)
-#define PHY_BB_CAL_RXBB_GAIN_TBL_0_TXCAL_RX_BB_GAIN_TABLE_1_MSB                                       11
-#define PHY_BB_CAL_RXBB_GAIN_TBL_0_TXCAL_RX_BB_GAIN_TABLE_1_LSB                                        6
-#define PHY_BB_CAL_RXBB_GAIN_TBL_0_TXCAL_RX_BB_GAIN_TABLE_1_MASK                              0x00000fc0
-#define PHY_BB_CAL_RXBB_GAIN_TBL_0_TXCAL_RX_BB_GAIN_TABLE_1_GET(x)             (((x) & 0x00000fc0) >> 6)
-#define PHY_BB_CAL_RXBB_GAIN_TBL_0_TXCAL_RX_BB_GAIN_TABLE_1_SET(x)             (((x) << 6) & 0x00000fc0)
-#define PHY_BB_CAL_RXBB_GAIN_TBL_0_TXCAL_RX_BB_GAIN_TABLE_2_MSB                                       17
-#define PHY_BB_CAL_RXBB_GAIN_TBL_0_TXCAL_RX_BB_GAIN_TABLE_2_LSB                                       12
-#define PHY_BB_CAL_RXBB_GAIN_TBL_0_TXCAL_RX_BB_GAIN_TABLE_2_MASK                              0x0003f000
-#define PHY_BB_CAL_RXBB_GAIN_TBL_0_TXCAL_RX_BB_GAIN_TABLE_2_GET(x)            (((x) & 0x0003f000) >> 12)
-#define PHY_BB_CAL_RXBB_GAIN_TBL_0_TXCAL_RX_BB_GAIN_TABLE_2_SET(x)            (((x) << 12) & 0x0003f000)
-#define PHY_BB_CAL_RXBB_GAIN_TBL_0_TXCAL_RX_BB_GAIN_TABLE_3_MSB                                       23
-#define PHY_BB_CAL_RXBB_GAIN_TBL_0_TXCAL_RX_BB_GAIN_TABLE_3_LSB                                       18
-#define PHY_BB_CAL_RXBB_GAIN_TBL_0_TXCAL_RX_BB_GAIN_TABLE_3_MASK                              0x00fc0000
-#define PHY_BB_CAL_RXBB_GAIN_TBL_0_TXCAL_RX_BB_GAIN_TABLE_3_GET(x)            (((x) & 0x00fc0000) >> 18)
-#define PHY_BB_CAL_RXBB_GAIN_TBL_0_TXCAL_RX_BB_GAIN_TABLE_3_SET(x)            (((x) << 18) & 0x00fc0000)
-
-/* macros for BB_cal_rxbb_gain_tbl_4 */
-#define PHY_BB_CAL_RXBB_GAIN_TBL_4_ADDRESS                                                    0x0000a710
-#define PHY_BB_CAL_RXBB_GAIN_TBL_4_OFFSET                                                     0x0000a710
-#define PHY_BB_CAL_RXBB_GAIN_TBL_4_TXCAL_RX_BB_GAIN_TABLE_4_MSB                                        5
-#define PHY_BB_CAL_RXBB_GAIN_TBL_4_TXCAL_RX_BB_GAIN_TABLE_4_LSB                                        0
-#define PHY_BB_CAL_RXBB_GAIN_TBL_4_TXCAL_RX_BB_GAIN_TABLE_4_MASK                              0x0000003f
-#define PHY_BB_CAL_RXBB_GAIN_TBL_4_TXCAL_RX_BB_GAIN_TABLE_4_GET(x)             (((x) & 0x0000003f) >> 0)
-#define PHY_BB_CAL_RXBB_GAIN_TBL_4_TXCAL_RX_BB_GAIN_TABLE_4_SET(x)             (((x) << 0) & 0x0000003f)
-#define PHY_BB_CAL_RXBB_GAIN_TBL_4_TXCAL_RX_BB_GAIN_TABLE_5_MSB                                       11
-#define PHY_BB_CAL_RXBB_GAIN_TBL_4_TXCAL_RX_BB_GAIN_TABLE_5_LSB                                        6
-#define PHY_BB_CAL_RXBB_GAIN_TBL_4_TXCAL_RX_BB_GAIN_TABLE_5_MASK                              0x00000fc0
-#define PHY_BB_CAL_RXBB_GAIN_TBL_4_TXCAL_RX_BB_GAIN_TABLE_5_GET(x)             (((x) & 0x00000fc0) >> 6)
-#define PHY_BB_CAL_RXBB_GAIN_TBL_4_TXCAL_RX_BB_GAIN_TABLE_5_SET(x)             (((x) << 6) & 0x00000fc0)
-#define PHY_BB_CAL_RXBB_GAIN_TBL_4_TXCAL_RX_BB_GAIN_TABLE_6_MSB                                       17
-#define PHY_BB_CAL_RXBB_GAIN_TBL_4_TXCAL_RX_BB_GAIN_TABLE_6_LSB                                       12
-#define PHY_BB_CAL_RXBB_GAIN_TBL_4_TXCAL_RX_BB_GAIN_TABLE_6_MASK                              0x0003f000
-#define PHY_BB_CAL_RXBB_GAIN_TBL_4_TXCAL_RX_BB_GAIN_TABLE_6_GET(x)            (((x) & 0x0003f000) >> 12)
-#define PHY_BB_CAL_RXBB_GAIN_TBL_4_TXCAL_RX_BB_GAIN_TABLE_6_SET(x)            (((x) << 12) & 0x0003f000)
-#define PHY_BB_CAL_RXBB_GAIN_TBL_4_TXCAL_RX_BB_GAIN_TABLE_7_MSB                                       23
-#define PHY_BB_CAL_RXBB_GAIN_TBL_4_TXCAL_RX_BB_GAIN_TABLE_7_LSB                                       18
-#define PHY_BB_CAL_RXBB_GAIN_TBL_4_TXCAL_RX_BB_GAIN_TABLE_7_MASK                              0x00fc0000
-#define PHY_BB_CAL_RXBB_GAIN_TBL_4_TXCAL_RX_BB_GAIN_TABLE_7_GET(x)            (((x) & 0x00fc0000) >> 18)
-#define PHY_BB_CAL_RXBB_GAIN_TBL_4_TXCAL_RX_BB_GAIN_TABLE_7_SET(x)            (((x) << 18) & 0x00fc0000)
-
-/* macros for BB_cal_rxbb_gain_tbl_8 */
-#define PHY_BB_CAL_RXBB_GAIN_TBL_8_ADDRESS                                                    0x0000a714
-#define PHY_BB_CAL_RXBB_GAIN_TBL_8_OFFSET                                                     0x0000a714
-#define PHY_BB_CAL_RXBB_GAIN_TBL_8_TXCAL_RX_BB_GAIN_TABLE_8_MSB                                        5
-#define PHY_BB_CAL_RXBB_GAIN_TBL_8_TXCAL_RX_BB_GAIN_TABLE_8_LSB                                        0
-#define PHY_BB_CAL_RXBB_GAIN_TBL_8_TXCAL_RX_BB_GAIN_TABLE_8_MASK                              0x0000003f
-#define PHY_BB_CAL_RXBB_GAIN_TBL_8_TXCAL_RX_BB_GAIN_TABLE_8_GET(x)             (((x) & 0x0000003f) >> 0)
-#define PHY_BB_CAL_RXBB_GAIN_TBL_8_TXCAL_RX_BB_GAIN_TABLE_8_SET(x)             (((x) << 0) & 0x0000003f)
-#define PHY_BB_CAL_RXBB_GAIN_TBL_8_TXCAL_RX_BB_GAIN_TABLE_9_MSB                                       11
-#define PHY_BB_CAL_RXBB_GAIN_TBL_8_TXCAL_RX_BB_GAIN_TABLE_9_LSB                                        6
-#define PHY_BB_CAL_RXBB_GAIN_TBL_8_TXCAL_RX_BB_GAIN_TABLE_9_MASK                              0x00000fc0
-#define PHY_BB_CAL_RXBB_GAIN_TBL_8_TXCAL_RX_BB_GAIN_TABLE_9_GET(x)             (((x) & 0x00000fc0) >> 6)
-#define PHY_BB_CAL_RXBB_GAIN_TBL_8_TXCAL_RX_BB_GAIN_TABLE_9_SET(x)             (((x) << 6) & 0x00000fc0)
-#define PHY_BB_CAL_RXBB_GAIN_TBL_8_TXCAL_RX_BB_GAIN_TABLE_10_MSB                                      17
-#define PHY_BB_CAL_RXBB_GAIN_TBL_8_TXCAL_RX_BB_GAIN_TABLE_10_LSB                                      12
-#define PHY_BB_CAL_RXBB_GAIN_TBL_8_TXCAL_RX_BB_GAIN_TABLE_10_MASK                             0x0003f000
-#define PHY_BB_CAL_RXBB_GAIN_TBL_8_TXCAL_RX_BB_GAIN_TABLE_10_GET(x)           (((x) & 0x0003f000) >> 12)
-#define PHY_BB_CAL_RXBB_GAIN_TBL_8_TXCAL_RX_BB_GAIN_TABLE_10_SET(x)           (((x) << 12) & 0x0003f000)
-#define PHY_BB_CAL_RXBB_GAIN_TBL_8_TXCAL_RX_BB_GAIN_TABLE_11_MSB                                      23
-#define PHY_BB_CAL_RXBB_GAIN_TBL_8_TXCAL_RX_BB_GAIN_TABLE_11_LSB                                      18
-#define PHY_BB_CAL_RXBB_GAIN_TBL_8_TXCAL_RX_BB_GAIN_TABLE_11_MASK                             0x00fc0000
-#define PHY_BB_CAL_RXBB_GAIN_TBL_8_TXCAL_RX_BB_GAIN_TABLE_11_GET(x)           (((x) & 0x00fc0000) >> 18)
-#define PHY_BB_CAL_RXBB_GAIN_TBL_8_TXCAL_RX_BB_GAIN_TABLE_11_SET(x)           (((x) << 18) & 0x00fc0000)
-
-/* macros for BB_cal_rxbb_gain_tbl_12 */
-#define PHY_BB_CAL_RXBB_GAIN_TBL_12_ADDRESS                                                   0x0000a718
-#define PHY_BB_CAL_RXBB_GAIN_TBL_12_OFFSET                                                    0x0000a718
-#define PHY_BB_CAL_RXBB_GAIN_TBL_12_TXCAL_RX_BB_GAIN_TABLE_12_MSB                                      5
-#define PHY_BB_CAL_RXBB_GAIN_TBL_12_TXCAL_RX_BB_GAIN_TABLE_12_LSB                                      0
-#define PHY_BB_CAL_RXBB_GAIN_TBL_12_TXCAL_RX_BB_GAIN_TABLE_12_MASK                            0x0000003f
-#define PHY_BB_CAL_RXBB_GAIN_TBL_12_TXCAL_RX_BB_GAIN_TABLE_12_GET(x)           (((x) & 0x0000003f) >> 0)
-#define PHY_BB_CAL_RXBB_GAIN_TBL_12_TXCAL_RX_BB_GAIN_TABLE_12_SET(x)           (((x) << 0) & 0x0000003f)
-#define PHY_BB_CAL_RXBB_GAIN_TBL_12_TXCAL_RX_BB_GAIN_TABLE_13_MSB                                     11
-#define PHY_BB_CAL_RXBB_GAIN_TBL_12_TXCAL_RX_BB_GAIN_TABLE_13_LSB                                      6
-#define PHY_BB_CAL_RXBB_GAIN_TBL_12_TXCAL_RX_BB_GAIN_TABLE_13_MASK                            0x00000fc0
-#define PHY_BB_CAL_RXBB_GAIN_TBL_12_TXCAL_RX_BB_GAIN_TABLE_13_GET(x)           (((x) & 0x00000fc0) >> 6)
-#define PHY_BB_CAL_RXBB_GAIN_TBL_12_TXCAL_RX_BB_GAIN_TABLE_13_SET(x)           (((x) << 6) & 0x00000fc0)
-#define PHY_BB_CAL_RXBB_GAIN_TBL_12_TXCAL_RX_BB_GAIN_TABLE_14_MSB                                     17
-#define PHY_BB_CAL_RXBB_GAIN_TBL_12_TXCAL_RX_BB_GAIN_TABLE_14_LSB                                     12
-#define PHY_BB_CAL_RXBB_GAIN_TBL_12_TXCAL_RX_BB_GAIN_TABLE_14_MASK                            0x0003f000
-#define PHY_BB_CAL_RXBB_GAIN_TBL_12_TXCAL_RX_BB_GAIN_TABLE_14_GET(x)          (((x) & 0x0003f000) >> 12)
-#define PHY_BB_CAL_RXBB_GAIN_TBL_12_TXCAL_RX_BB_GAIN_TABLE_14_SET(x)          (((x) << 12) & 0x0003f000)
-#define PHY_BB_CAL_RXBB_GAIN_TBL_12_TXCAL_RX_BB_GAIN_TABLE_15_MSB                                     23
-#define PHY_BB_CAL_RXBB_GAIN_TBL_12_TXCAL_RX_BB_GAIN_TABLE_15_LSB                                     18
-#define PHY_BB_CAL_RXBB_GAIN_TBL_12_TXCAL_RX_BB_GAIN_TABLE_15_MASK                            0x00fc0000
-#define PHY_BB_CAL_RXBB_GAIN_TBL_12_TXCAL_RX_BB_GAIN_TABLE_15_GET(x)          (((x) & 0x00fc0000) >> 18)
-#define PHY_BB_CAL_RXBB_GAIN_TBL_12_TXCAL_RX_BB_GAIN_TABLE_15_SET(x)          (((x) << 18) & 0x00fc0000)
-
-/* macros for BB_cal_rxbb_gain_tbl_16 */
-#define PHY_BB_CAL_RXBB_GAIN_TBL_16_ADDRESS                                                   0x0000a71c
-#define PHY_BB_CAL_RXBB_GAIN_TBL_16_OFFSET                                                    0x0000a71c
-#define PHY_BB_CAL_RXBB_GAIN_TBL_16_TXCAL_RX_BB_GAIN_TABLE_16_MSB                                      5
-#define PHY_BB_CAL_RXBB_GAIN_TBL_16_TXCAL_RX_BB_GAIN_TABLE_16_LSB                                      0
-#define PHY_BB_CAL_RXBB_GAIN_TBL_16_TXCAL_RX_BB_GAIN_TABLE_16_MASK                            0x0000003f
-#define PHY_BB_CAL_RXBB_GAIN_TBL_16_TXCAL_RX_BB_GAIN_TABLE_16_GET(x)           (((x) & 0x0000003f) >> 0)
-#define PHY_BB_CAL_RXBB_GAIN_TBL_16_TXCAL_RX_BB_GAIN_TABLE_16_SET(x)           (((x) << 0) & 0x0000003f)
-#define PHY_BB_CAL_RXBB_GAIN_TBL_16_TXCAL_RX_BB_GAIN_TABLE_17_MSB                                     11
-#define PHY_BB_CAL_RXBB_GAIN_TBL_16_TXCAL_RX_BB_GAIN_TABLE_17_LSB                                      6
-#define PHY_BB_CAL_RXBB_GAIN_TBL_16_TXCAL_RX_BB_GAIN_TABLE_17_MASK                            0x00000fc0
-#define PHY_BB_CAL_RXBB_GAIN_TBL_16_TXCAL_RX_BB_GAIN_TABLE_17_GET(x)           (((x) & 0x00000fc0) >> 6)
-#define PHY_BB_CAL_RXBB_GAIN_TBL_16_TXCAL_RX_BB_GAIN_TABLE_17_SET(x)           (((x) << 6) & 0x00000fc0)
-#define PHY_BB_CAL_RXBB_GAIN_TBL_16_TXCAL_RX_BB_GAIN_TABLE_18_MSB                                     17
-#define PHY_BB_CAL_RXBB_GAIN_TBL_16_TXCAL_RX_BB_GAIN_TABLE_18_LSB                                     12
-#define PHY_BB_CAL_RXBB_GAIN_TBL_16_TXCAL_RX_BB_GAIN_TABLE_18_MASK                            0x0003f000
-#define PHY_BB_CAL_RXBB_GAIN_TBL_16_TXCAL_RX_BB_GAIN_TABLE_18_GET(x)          (((x) & 0x0003f000) >> 12)
-#define PHY_BB_CAL_RXBB_GAIN_TBL_16_TXCAL_RX_BB_GAIN_TABLE_18_SET(x)          (((x) << 12) & 0x0003f000)
-#define PHY_BB_CAL_RXBB_GAIN_TBL_16_TXCAL_RX_BB_GAIN_TABLE_19_MSB                                     23
-#define PHY_BB_CAL_RXBB_GAIN_TBL_16_TXCAL_RX_BB_GAIN_TABLE_19_LSB                                     18
-#define PHY_BB_CAL_RXBB_GAIN_TBL_16_TXCAL_RX_BB_GAIN_TABLE_19_MASK                            0x00fc0000
-#define PHY_BB_CAL_RXBB_GAIN_TBL_16_TXCAL_RX_BB_GAIN_TABLE_19_GET(x)          (((x) & 0x00fc0000) >> 18)
-#define PHY_BB_CAL_RXBB_GAIN_TBL_16_TXCAL_RX_BB_GAIN_TABLE_19_SET(x)          (((x) << 18) & 0x00fc0000)
-
-/* macros for BB_cal_rxbb_gain_tbl_20 */
-#define PHY_BB_CAL_RXBB_GAIN_TBL_20_ADDRESS                                                   0x0000a720
-#define PHY_BB_CAL_RXBB_GAIN_TBL_20_OFFSET                                                    0x0000a720
-#define PHY_BB_CAL_RXBB_GAIN_TBL_20_TXCAL_RX_BB_GAIN_TABLE_20_MSB                                      5
-#define PHY_BB_CAL_RXBB_GAIN_TBL_20_TXCAL_RX_BB_GAIN_TABLE_20_LSB                                      0
-#define PHY_BB_CAL_RXBB_GAIN_TBL_20_TXCAL_RX_BB_GAIN_TABLE_20_MASK                            0x0000003f
-#define PHY_BB_CAL_RXBB_GAIN_TBL_20_TXCAL_RX_BB_GAIN_TABLE_20_GET(x)           (((x) & 0x0000003f) >> 0)
-#define PHY_BB_CAL_RXBB_GAIN_TBL_20_TXCAL_RX_BB_GAIN_TABLE_20_SET(x)           (((x) << 0) & 0x0000003f)
-#define PHY_BB_CAL_RXBB_GAIN_TBL_20_TXCAL_RX_BB_GAIN_TABLE_21_MSB                                     11
-#define PHY_BB_CAL_RXBB_GAIN_TBL_20_TXCAL_RX_BB_GAIN_TABLE_21_LSB                                      6
-#define PHY_BB_CAL_RXBB_GAIN_TBL_20_TXCAL_RX_BB_GAIN_TABLE_21_MASK                            0x00000fc0
-#define PHY_BB_CAL_RXBB_GAIN_TBL_20_TXCAL_RX_BB_GAIN_TABLE_21_GET(x)           (((x) & 0x00000fc0) >> 6)
-#define PHY_BB_CAL_RXBB_GAIN_TBL_20_TXCAL_RX_BB_GAIN_TABLE_21_SET(x)           (((x) << 6) & 0x00000fc0)
-#define PHY_BB_CAL_RXBB_GAIN_TBL_20_TXCAL_RX_BB_GAIN_TABLE_22_MSB                                     17
-#define PHY_BB_CAL_RXBB_GAIN_TBL_20_TXCAL_RX_BB_GAIN_TABLE_22_LSB                                     12
-#define PHY_BB_CAL_RXBB_GAIN_TBL_20_TXCAL_RX_BB_GAIN_TABLE_22_MASK                            0x0003f000
-#define PHY_BB_CAL_RXBB_GAIN_TBL_20_TXCAL_RX_BB_GAIN_TABLE_22_GET(x)          (((x) & 0x0003f000) >> 12)
-#define PHY_BB_CAL_RXBB_GAIN_TBL_20_TXCAL_RX_BB_GAIN_TABLE_22_SET(x)          (((x) << 12) & 0x0003f000)
-#define PHY_BB_CAL_RXBB_GAIN_TBL_20_TXCAL_RX_BB_GAIN_TABLE_23_MSB                                     23
-#define PHY_BB_CAL_RXBB_GAIN_TBL_20_TXCAL_RX_BB_GAIN_TABLE_23_LSB                                     18
-#define PHY_BB_CAL_RXBB_GAIN_TBL_20_TXCAL_RX_BB_GAIN_TABLE_23_MASK                            0x00fc0000
-#define PHY_BB_CAL_RXBB_GAIN_TBL_20_TXCAL_RX_BB_GAIN_TABLE_23_GET(x)          (((x) & 0x00fc0000) >> 18)
-#define PHY_BB_CAL_RXBB_GAIN_TBL_20_TXCAL_RX_BB_GAIN_TABLE_23_SET(x)          (((x) << 18) & 0x00fc0000)
-
-/* macros for BB_cal_rxbb_gain_tbl_24 */
-#define PHY_BB_CAL_RXBB_GAIN_TBL_24_ADDRESS                                                   0x0000a724
-#define PHY_BB_CAL_RXBB_GAIN_TBL_24_OFFSET                                                    0x0000a724
-#define PHY_BB_CAL_RXBB_GAIN_TBL_24_TXCAL_RX_BB_GAIN_TABLE_24_MSB                                      5
-#define PHY_BB_CAL_RXBB_GAIN_TBL_24_TXCAL_RX_BB_GAIN_TABLE_24_LSB                                      0
-#define PHY_BB_CAL_RXBB_GAIN_TBL_24_TXCAL_RX_BB_GAIN_TABLE_24_MASK                            0x0000003f
-#define PHY_BB_CAL_RXBB_GAIN_TBL_24_TXCAL_RX_BB_GAIN_TABLE_24_GET(x)           (((x) & 0x0000003f) >> 0)
-#define PHY_BB_CAL_RXBB_GAIN_TBL_24_TXCAL_RX_BB_GAIN_TABLE_24_SET(x)           (((x) << 0) & 0x0000003f)
-
-/* macros for BB_txiqcal_status_b0 */
-#define PHY_BB_TXIQCAL_STATUS_B0_ADDRESS                                                      0x0000a728
-#define PHY_BB_TXIQCAL_STATUS_B0_OFFSET                                                       0x0000a728
-#define PHY_BB_TXIQCAL_STATUS_B0_TXIQCAL_FAILED_0_MSB                                                  0
-#define PHY_BB_TXIQCAL_STATUS_B0_TXIQCAL_FAILED_0_LSB                                                  0
-#define PHY_BB_TXIQCAL_STATUS_B0_TXIQCAL_FAILED_0_MASK                                        0x00000001
-#define PHY_BB_TXIQCAL_STATUS_B0_TXIQCAL_FAILED_0_GET(x)                       (((x) & 0x00000001) >> 0)
-#define PHY_BB_TXIQCAL_STATUS_B0_CALIBRATED_GAINS_0_MSB                                                5
-#define PHY_BB_TXIQCAL_STATUS_B0_CALIBRATED_GAINS_0_LSB                                                1
-#define PHY_BB_TXIQCAL_STATUS_B0_CALIBRATED_GAINS_0_MASK                                      0x0000003e
-#define PHY_BB_TXIQCAL_STATUS_B0_CALIBRATED_GAINS_0_GET(x)                     (((x) & 0x0000003e) >> 1)
-#define PHY_BB_TXIQCAL_STATUS_B0_TONE_GAIN_USED_0_MSB                                                 11
-#define PHY_BB_TXIQCAL_STATUS_B0_TONE_GAIN_USED_0_LSB                                                  6
-#define PHY_BB_TXIQCAL_STATUS_B0_TONE_GAIN_USED_0_MASK                                        0x00000fc0
-#define PHY_BB_TXIQCAL_STATUS_B0_TONE_GAIN_USED_0_GET(x)                       (((x) & 0x00000fc0) >> 6)
-#define PHY_BB_TXIQCAL_STATUS_B0_RX_GAIN_USED_0_MSB                                                   17
-#define PHY_BB_TXIQCAL_STATUS_B0_RX_GAIN_USED_0_LSB                                                   12
-#define PHY_BB_TXIQCAL_STATUS_B0_RX_GAIN_USED_0_MASK                                          0x0003f000
-#define PHY_BB_TXIQCAL_STATUS_B0_RX_GAIN_USED_0_GET(x)                        (((x) & 0x0003f000) >> 12)
-#define PHY_BB_TXIQCAL_STATUS_B0_LAST_MEAS_ADDR_0_MSB                                                 24
-#define PHY_BB_TXIQCAL_STATUS_B0_LAST_MEAS_ADDR_0_LSB                                                 18
-#define PHY_BB_TXIQCAL_STATUS_B0_LAST_MEAS_ADDR_0_MASK                                        0x01fc0000
-#define PHY_BB_TXIQCAL_STATUS_B0_LAST_MEAS_ADDR_0_GET(x)                      (((x) & 0x01fc0000) >> 18)
-
-/* macros for BB_paprd_trainer_cntl1 */
-#define PHY_BB_PAPRD_TRAINER_CNTL1_ADDRESS                                                    0x0000a72c
-#define PHY_BB_PAPRD_TRAINER_CNTL1_OFFSET                                                     0x0000a72c
-#define PHY_BB_PAPRD_TRAINER_CNTL1_CF_PAPRD_TRAIN_ENABLE_MSB                                           0
-#define PHY_BB_PAPRD_TRAINER_CNTL1_CF_PAPRD_TRAIN_ENABLE_LSB                                           0
-#define PHY_BB_PAPRD_TRAINER_CNTL1_CF_PAPRD_TRAIN_ENABLE_MASK                                 0x00000001
-#define PHY_BB_PAPRD_TRAINER_CNTL1_CF_PAPRD_TRAIN_ENABLE_GET(x)                (((x) & 0x00000001) >> 0)
-#define PHY_BB_PAPRD_TRAINER_CNTL1_CF_PAPRD_TRAIN_ENABLE_SET(x)                (((x) << 0) & 0x00000001)
-#define PHY_BB_PAPRD_TRAINER_CNTL1_CF_PAPRD_AGC2_SETTLING_MSB                                          7
-#define PHY_BB_PAPRD_TRAINER_CNTL1_CF_PAPRD_AGC2_SETTLING_LSB                                          1
-#define PHY_BB_PAPRD_TRAINER_CNTL1_CF_PAPRD_AGC2_SETTLING_MASK                                0x000000fe
-#define PHY_BB_PAPRD_TRAINER_CNTL1_CF_PAPRD_AGC2_SETTLING_GET(x)               (((x) & 0x000000fe) >> 1)
-#define PHY_BB_PAPRD_TRAINER_CNTL1_CF_PAPRD_AGC2_SETTLING_SET(x)               (((x) << 1) & 0x000000fe)
-#define PHY_BB_PAPRD_TRAINER_CNTL1_CF_PAPRD_IQCORR_ENABLE_MSB                                          8
-#define PHY_BB_PAPRD_TRAINER_CNTL1_CF_PAPRD_IQCORR_ENABLE_LSB                                          8
-#define PHY_BB_PAPRD_TRAINER_CNTL1_CF_PAPRD_IQCORR_ENABLE_MASK                                0x00000100
-#define PHY_BB_PAPRD_TRAINER_CNTL1_CF_PAPRD_IQCORR_ENABLE_GET(x)               (((x) & 0x00000100) >> 8)
-#define PHY_BB_PAPRD_TRAINER_CNTL1_CF_PAPRD_IQCORR_ENABLE_SET(x)               (((x) << 8) & 0x00000100)
-#define PHY_BB_PAPRD_TRAINER_CNTL1_CF_PAPRD_RX_BB_GAIN_FORCE_MSB                                       9
-#define PHY_BB_PAPRD_TRAINER_CNTL1_CF_PAPRD_RX_BB_GAIN_FORCE_LSB                                       9
-#define PHY_BB_PAPRD_TRAINER_CNTL1_CF_PAPRD_RX_BB_GAIN_FORCE_MASK                             0x00000200
-#define PHY_BB_PAPRD_TRAINER_CNTL1_CF_PAPRD_RX_BB_GAIN_FORCE_GET(x)            (((x) & 0x00000200) >> 9)
-#define PHY_BB_PAPRD_TRAINER_CNTL1_CF_PAPRD_RX_BB_GAIN_FORCE_SET(x)            (((x) << 9) & 0x00000200)
-#define PHY_BB_PAPRD_TRAINER_CNTL1_CF_PAPRD_TX_GAIN_FORCE_MSB                                         10
-#define PHY_BB_PAPRD_TRAINER_CNTL1_CF_PAPRD_TX_GAIN_FORCE_LSB                                         10
-#define PHY_BB_PAPRD_TRAINER_CNTL1_CF_PAPRD_TX_GAIN_FORCE_MASK                                0x00000400
-#define PHY_BB_PAPRD_TRAINER_CNTL1_CF_PAPRD_TX_GAIN_FORCE_GET(x)              (((x) & 0x00000400) >> 10)
-#define PHY_BB_PAPRD_TRAINER_CNTL1_CF_PAPRD_TX_GAIN_FORCE_SET(x)              (((x) << 10) & 0x00000400)
-#define PHY_BB_PAPRD_TRAINER_CNTL1_CF_PAPRD_LB_ENABLE_MSB                                             11
-#define PHY_BB_PAPRD_TRAINER_CNTL1_CF_PAPRD_LB_ENABLE_LSB                                             11
-#define PHY_BB_PAPRD_TRAINER_CNTL1_CF_PAPRD_LB_ENABLE_MASK                                    0x00000800
-#define PHY_BB_PAPRD_TRAINER_CNTL1_CF_PAPRD_LB_ENABLE_GET(x)                  (((x) & 0x00000800) >> 11)
-#define PHY_BB_PAPRD_TRAINER_CNTL1_CF_PAPRD_LB_ENABLE_SET(x)                  (((x) << 11) & 0x00000800)
-#define PHY_BB_PAPRD_TRAINER_CNTL1_CF_PAPRD_LB_SKIP_MSB                                               18
-#define PHY_BB_PAPRD_TRAINER_CNTL1_CF_PAPRD_LB_SKIP_LSB                                               12
-#define PHY_BB_PAPRD_TRAINER_CNTL1_CF_PAPRD_LB_SKIP_MASK                                      0x0007f000
-#define PHY_BB_PAPRD_TRAINER_CNTL1_CF_PAPRD_LB_SKIP_GET(x)                    (((x) & 0x0007f000) >> 12)
-#define PHY_BB_PAPRD_TRAINER_CNTL1_CF_PAPRD_LB_SKIP_SET(x)                    (((x) << 12) & 0x0007f000)
-
-/* macros for BB_paprd_trainer_cntl2 */
-#define PHY_BB_PAPRD_TRAINER_CNTL2_ADDRESS                                                    0x0000a730
-#define PHY_BB_PAPRD_TRAINER_CNTL2_OFFSET                                                     0x0000a730
-#define PHY_BB_PAPRD_TRAINER_CNTL2_CF_PAPRD_INIT_RX_BB_GAIN_MSB                                       31
-#define PHY_BB_PAPRD_TRAINER_CNTL2_CF_PAPRD_INIT_RX_BB_GAIN_LSB                                        0
-#define PHY_BB_PAPRD_TRAINER_CNTL2_CF_PAPRD_INIT_RX_BB_GAIN_MASK                              0xffffffff
-#define PHY_BB_PAPRD_TRAINER_CNTL2_CF_PAPRD_INIT_RX_BB_GAIN_GET(x)             (((x) & 0xffffffff) >> 0)
-#define PHY_BB_PAPRD_TRAINER_CNTL2_CF_PAPRD_INIT_RX_BB_GAIN_SET(x)             (((x) << 0) & 0xffffffff)
-
-/* macros for BB_paprd_trainer_cntl3 */
-#define PHY_BB_PAPRD_TRAINER_CNTL3_ADDRESS                                                    0x0000a734
-#define PHY_BB_PAPRD_TRAINER_CNTL3_OFFSET                                                     0x0000a734
-#define PHY_BB_PAPRD_TRAINER_CNTL3_CF_PAPRD_ADC_DESIRED_SIZE_MSB                                       5
-#define PHY_BB_PAPRD_TRAINER_CNTL3_CF_PAPRD_ADC_DESIRED_SIZE_LSB                                       0
-#define PHY_BB_PAPRD_TRAINER_CNTL3_CF_PAPRD_ADC_DESIRED_SIZE_MASK                             0x0000003f
-#define PHY_BB_PAPRD_TRAINER_CNTL3_CF_PAPRD_ADC_DESIRED_SIZE_GET(x)            (((x) & 0x0000003f) >> 0)
-#define PHY_BB_PAPRD_TRAINER_CNTL3_CF_PAPRD_ADC_DESIRED_SIZE_SET(x)            (((x) << 0) & 0x0000003f)
-#define PHY_BB_PAPRD_TRAINER_CNTL3_CF_PAPRD_QUICK_DROP_MSB                                            11
-#define PHY_BB_PAPRD_TRAINER_CNTL3_CF_PAPRD_QUICK_DROP_LSB                                             6
-#define PHY_BB_PAPRD_TRAINER_CNTL3_CF_PAPRD_QUICK_DROP_MASK                                   0x00000fc0
-#define PHY_BB_PAPRD_TRAINER_CNTL3_CF_PAPRD_QUICK_DROP_GET(x)                  (((x) & 0x00000fc0) >> 6)
-#define PHY_BB_PAPRD_TRAINER_CNTL3_CF_PAPRD_QUICK_DROP_SET(x)                  (((x) << 6) & 0x00000fc0)
-#define PHY_BB_PAPRD_TRAINER_CNTL3_CF_PAPRD_MIN_LOOPBACK_DEL_MSB                                      16
-#define PHY_BB_PAPRD_TRAINER_CNTL3_CF_PAPRD_MIN_LOOPBACK_DEL_LSB                                      12
-#define PHY_BB_PAPRD_TRAINER_CNTL3_CF_PAPRD_MIN_LOOPBACK_DEL_MASK                             0x0001f000
-#define PHY_BB_PAPRD_TRAINER_CNTL3_CF_PAPRD_MIN_LOOPBACK_DEL_GET(x)           (((x) & 0x0001f000) >> 12)
-#define PHY_BB_PAPRD_TRAINER_CNTL3_CF_PAPRD_MIN_LOOPBACK_DEL_SET(x)           (((x) << 12) & 0x0001f000)
-#define PHY_BB_PAPRD_TRAINER_CNTL3_CF_PAPRD_NUM_CORR_STAGES_MSB                                       19
-#define PHY_BB_PAPRD_TRAINER_CNTL3_CF_PAPRD_NUM_CORR_STAGES_LSB                                       17
-#define PHY_BB_PAPRD_TRAINER_CNTL3_CF_PAPRD_NUM_CORR_STAGES_MASK                              0x000e0000
-#define PHY_BB_PAPRD_TRAINER_CNTL3_CF_PAPRD_NUM_CORR_STAGES_GET(x)            (((x) & 0x000e0000) >> 17)
-#define PHY_BB_PAPRD_TRAINER_CNTL3_CF_PAPRD_NUM_CORR_STAGES_SET(x)            (((x) << 17) & 0x000e0000)
-#define PHY_BB_PAPRD_TRAINER_CNTL3_CF_PAPRD_COARSE_CORR_LEN_MSB                                       23
-#define PHY_BB_PAPRD_TRAINER_CNTL3_CF_PAPRD_COARSE_CORR_LEN_LSB                                       20
-#define PHY_BB_PAPRD_TRAINER_CNTL3_CF_PAPRD_COARSE_CORR_LEN_MASK                              0x00f00000
-#define PHY_BB_PAPRD_TRAINER_CNTL3_CF_PAPRD_COARSE_CORR_LEN_GET(x)            (((x) & 0x00f00000) >> 20)
-#define PHY_BB_PAPRD_TRAINER_CNTL3_CF_PAPRD_COARSE_CORR_LEN_SET(x)            (((x) << 20) & 0x00f00000)
-#define PHY_BB_PAPRD_TRAINER_CNTL3_CF_PAPRD_FINE_CORR_LEN_MSB                                         27
-#define PHY_BB_PAPRD_TRAINER_CNTL3_CF_PAPRD_FINE_CORR_LEN_LSB                                         24
-#define PHY_BB_PAPRD_TRAINER_CNTL3_CF_PAPRD_FINE_CORR_LEN_MASK                                0x0f000000
-#define PHY_BB_PAPRD_TRAINER_CNTL3_CF_PAPRD_FINE_CORR_LEN_GET(x)              (((x) & 0x0f000000) >> 24)
-#define PHY_BB_PAPRD_TRAINER_CNTL3_CF_PAPRD_FINE_CORR_LEN_SET(x)              (((x) << 24) & 0x0f000000)
-#define PHY_BB_PAPRD_TRAINER_CNTL3_CF_PAPRD_BBTXMIX_DISABLE_MSB                                       28
-#define PHY_BB_PAPRD_TRAINER_CNTL3_CF_PAPRD_BBTXMIX_DISABLE_LSB                                       28
-#define PHY_BB_PAPRD_TRAINER_CNTL3_CF_PAPRD_BBTXMIX_DISABLE_MASK                              0x10000000
-#define PHY_BB_PAPRD_TRAINER_CNTL3_CF_PAPRD_BBTXMIX_DISABLE_GET(x)            (((x) & 0x10000000) >> 28)
-#define PHY_BB_PAPRD_TRAINER_CNTL3_CF_PAPRD_BBTXMIX_DISABLE_SET(x)            (((x) << 28) & 0x10000000)
-
-/* macros for BB_paprd_trainer_cntl4 */
-#define PHY_BB_PAPRD_TRAINER_CNTL4_ADDRESS                                                    0x0000a738
-#define PHY_BB_PAPRD_TRAINER_CNTL4_OFFSET                                                     0x0000a738
-#define PHY_BB_PAPRD_TRAINER_CNTL4_CF_PAPRD_MIN_CORR_MSB                                              11
-#define PHY_BB_PAPRD_TRAINER_CNTL4_CF_PAPRD_MIN_CORR_LSB                                               0
-#define PHY_BB_PAPRD_TRAINER_CNTL4_CF_PAPRD_MIN_CORR_MASK                                     0x00000fff
-#define PHY_BB_PAPRD_TRAINER_CNTL4_CF_PAPRD_MIN_CORR_GET(x)                    (((x) & 0x00000fff) >> 0)
-#define PHY_BB_PAPRD_TRAINER_CNTL4_CF_PAPRD_MIN_CORR_SET(x)                    (((x) << 0) & 0x00000fff)
-#define PHY_BB_PAPRD_TRAINER_CNTL4_CF_PAPRD_SAFETY_DELTA_MSB                                          15
-#define PHY_BB_PAPRD_TRAINER_CNTL4_CF_PAPRD_SAFETY_DELTA_LSB                                          12
-#define PHY_BB_PAPRD_TRAINER_CNTL4_CF_PAPRD_SAFETY_DELTA_MASK                                 0x0000f000
-#define PHY_BB_PAPRD_TRAINER_CNTL4_CF_PAPRD_SAFETY_DELTA_GET(x)               (((x) & 0x0000f000) >> 12)
-#define PHY_BB_PAPRD_TRAINER_CNTL4_CF_PAPRD_SAFETY_DELTA_SET(x)               (((x) << 12) & 0x0000f000)
-#define PHY_BB_PAPRD_TRAINER_CNTL4_CF_PAPRD_NUM_TRAIN_SAMPLES_MSB                                     25
-#define PHY_BB_PAPRD_TRAINER_CNTL4_CF_PAPRD_NUM_TRAIN_SAMPLES_LSB                                     16
-#define PHY_BB_PAPRD_TRAINER_CNTL4_CF_PAPRD_NUM_TRAIN_SAMPLES_MASK                            0x03ff0000
-#define PHY_BB_PAPRD_TRAINER_CNTL4_CF_PAPRD_NUM_TRAIN_SAMPLES_GET(x)          (((x) & 0x03ff0000) >> 16)
-#define PHY_BB_PAPRD_TRAINER_CNTL4_CF_PAPRD_NUM_TRAIN_SAMPLES_SET(x)          (((x) << 16) & 0x03ff0000)
-
-/* macros for BB_paprd_trainer_stat1 */
-#define PHY_BB_PAPRD_TRAINER_STAT1_ADDRESS                                                    0x0000a73c
-#define PHY_BB_PAPRD_TRAINER_STAT1_OFFSET                                                     0x0000a73c
-#define PHY_BB_PAPRD_TRAINER_STAT1_PAPRD_TRAIN_DONE_MSB                                                0
-#define PHY_BB_PAPRD_TRAINER_STAT1_PAPRD_TRAIN_DONE_LSB                                                0
-#define PHY_BB_PAPRD_TRAINER_STAT1_PAPRD_TRAIN_DONE_MASK                                      0x00000001
-#define PHY_BB_PAPRD_TRAINER_STAT1_PAPRD_TRAIN_DONE_GET(x)                     (((x) & 0x00000001) >> 0)
-#define PHY_BB_PAPRD_TRAINER_STAT1_PAPRD_TRAIN_DONE_SET(x)                     (((x) << 0) & 0x00000001)
-#define PHY_BB_PAPRD_TRAINER_STAT1_PAPRD_TRAIN_INCOMPLETE_MSB                                          1
-#define PHY_BB_PAPRD_TRAINER_STAT1_PAPRD_TRAIN_INCOMPLETE_LSB                                          1
-#define PHY_BB_PAPRD_TRAINER_STAT1_PAPRD_TRAIN_INCOMPLETE_MASK                                0x00000002
-#define PHY_BB_PAPRD_TRAINER_STAT1_PAPRD_TRAIN_INCOMPLETE_GET(x)               (((x) & 0x00000002) >> 1)
-#define PHY_BB_PAPRD_TRAINER_STAT1_PAPRD_CORR_ERR_MSB                                                  2
-#define PHY_BB_PAPRD_TRAINER_STAT1_PAPRD_CORR_ERR_LSB                                                  2
-#define PHY_BB_PAPRD_TRAINER_STAT1_PAPRD_CORR_ERR_MASK                                        0x00000004
-#define PHY_BB_PAPRD_TRAINER_STAT1_PAPRD_CORR_ERR_GET(x)                       (((x) & 0x00000004) >> 2)
-#define PHY_BB_PAPRD_TRAINER_STAT1_PAPRD_TRAIN_ACTIVE_MSB                                              3
-#define PHY_BB_PAPRD_TRAINER_STAT1_PAPRD_TRAIN_ACTIVE_LSB                                              3
-#define PHY_BB_PAPRD_TRAINER_STAT1_PAPRD_TRAIN_ACTIVE_MASK                                    0x00000008
-#define PHY_BB_PAPRD_TRAINER_STAT1_PAPRD_TRAIN_ACTIVE_GET(x)                   (((x) & 0x00000008) >> 3)
-#define PHY_BB_PAPRD_TRAINER_STAT1_PAPRD_RX_GAIN_IDX_MSB                                               8
-#define PHY_BB_PAPRD_TRAINER_STAT1_PAPRD_RX_GAIN_IDX_LSB                                               4
-#define PHY_BB_PAPRD_TRAINER_STAT1_PAPRD_RX_GAIN_IDX_MASK                                     0x000001f0
-#define PHY_BB_PAPRD_TRAINER_STAT1_PAPRD_RX_GAIN_IDX_GET(x)                    (((x) & 0x000001f0) >> 4)
-#define PHY_BB_PAPRD_TRAINER_STAT1_PAPRD_AGC2_PWR_MSB                                                 16
-#define PHY_BB_PAPRD_TRAINER_STAT1_PAPRD_AGC2_PWR_LSB                                                  9
-#define PHY_BB_PAPRD_TRAINER_STAT1_PAPRD_AGC2_PWR_MASK                                        0x0001fe00
-#define PHY_BB_PAPRD_TRAINER_STAT1_PAPRD_AGC2_PWR_GET(x)                       (((x) & 0x0001fe00) >> 9)
-
-/* macros for BB_paprd_trainer_stat2 */
-#define PHY_BB_PAPRD_TRAINER_STAT2_ADDRESS                                                    0x0000a740
-#define PHY_BB_PAPRD_TRAINER_STAT2_OFFSET                                                     0x0000a740
-#define PHY_BB_PAPRD_TRAINER_STAT2_PAPRD_FINE_VAL_MSB                                                 15
-#define PHY_BB_PAPRD_TRAINER_STAT2_PAPRD_FINE_VAL_LSB                                                  0
-#define PHY_BB_PAPRD_TRAINER_STAT2_PAPRD_FINE_VAL_MASK                                        0x0000ffff
-#define PHY_BB_PAPRD_TRAINER_STAT2_PAPRD_FINE_VAL_GET(x)                       (((x) & 0x0000ffff) >> 0)
-#define PHY_BB_PAPRD_TRAINER_STAT2_PAPRD_COARSE_IDX_MSB                                               20
-#define PHY_BB_PAPRD_TRAINER_STAT2_PAPRD_COARSE_IDX_LSB                                               16
-#define PHY_BB_PAPRD_TRAINER_STAT2_PAPRD_COARSE_IDX_MASK                                      0x001f0000
-#define PHY_BB_PAPRD_TRAINER_STAT2_PAPRD_COARSE_IDX_GET(x)                    (((x) & 0x001f0000) >> 16)
-#define PHY_BB_PAPRD_TRAINER_STAT2_PAPRD_FINE_IDX_MSB                                                 22
-#define PHY_BB_PAPRD_TRAINER_STAT2_PAPRD_FINE_IDX_LSB                                                 21
-#define PHY_BB_PAPRD_TRAINER_STAT2_PAPRD_FINE_IDX_MASK                                        0x00600000
-#define PHY_BB_PAPRD_TRAINER_STAT2_PAPRD_FINE_IDX_GET(x)                      (((x) & 0x00600000) >> 21)
-
-/* macros for BB_paprd_trainer_stat3 */
-#define PHY_BB_PAPRD_TRAINER_STAT3_ADDRESS                                                    0x0000a744
-#define PHY_BB_PAPRD_TRAINER_STAT3_OFFSET                                                     0x0000a744
-#define PHY_BB_PAPRD_TRAINER_STAT3_PAPRD_TRAIN_SAMPLES_CNT_MSB                                        19
-#define PHY_BB_PAPRD_TRAINER_STAT3_PAPRD_TRAIN_SAMPLES_CNT_LSB                                         0
-#define PHY_BB_PAPRD_TRAINER_STAT3_PAPRD_TRAIN_SAMPLES_CNT_MASK                               0x000fffff
-#define PHY_BB_PAPRD_TRAINER_STAT3_PAPRD_TRAIN_SAMPLES_CNT_GET(x)              (((x) & 0x000fffff) >> 0)
-
-/* macros for BB_fcal_1 */
-#define PHY_BB_FCAL_1_ADDRESS                                                                 0x0000a7d8
-#define PHY_BB_FCAL_1_OFFSET                                                                  0x0000a7d8
-#define PHY_BB_FCAL_1_FLC_PB_FSTEP_MSB                                                                 9
-#define PHY_BB_FCAL_1_FLC_PB_FSTEP_LSB                                                                 0
-#define PHY_BB_FCAL_1_FLC_PB_FSTEP_MASK                                                       0x000003ff
-#define PHY_BB_FCAL_1_FLC_PB_FSTEP_GET(x)                                      (((x) & 0x000003ff) >> 0)
-#define PHY_BB_FCAL_1_FLC_PB_FSTEP_SET(x)                                      (((x) << 0) & 0x000003ff)
-#define PHY_BB_FCAL_1_FLC_SB_FSTEP_MSB                                                                19
-#define PHY_BB_FCAL_1_FLC_SB_FSTEP_LSB                                                                10
-#define PHY_BB_FCAL_1_FLC_SB_FSTEP_MASK                                                       0x000ffc00
-#define PHY_BB_FCAL_1_FLC_SB_FSTEP_GET(x)                                     (((x) & 0x000ffc00) >> 10)
-#define PHY_BB_FCAL_1_FLC_SB_FSTEP_SET(x)                                     (((x) << 10) & 0x000ffc00)
-#define PHY_BB_FCAL_1_FLC_PB_ATTEN_MSB                                                                24
-#define PHY_BB_FCAL_1_FLC_PB_ATTEN_LSB                                                                20
-#define PHY_BB_FCAL_1_FLC_PB_ATTEN_MASK                                                       0x01f00000
-#define PHY_BB_FCAL_1_FLC_PB_ATTEN_GET(x)                                     (((x) & 0x01f00000) >> 20)
-#define PHY_BB_FCAL_1_FLC_PB_ATTEN_SET(x)                                     (((x) << 20) & 0x01f00000)
-#define PHY_BB_FCAL_1_FLC_SB_ATTEN_MSB                                                                29
-#define PHY_BB_FCAL_1_FLC_SB_ATTEN_LSB                                                                25
-#define PHY_BB_FCAL_1_FLC_SB_ATTEN_MASK                                                       0x3e000000
-#define PHY_BB_FCAL_1_FLC_SB_ATTEN_GET(x)                                     (((x) & 0x3e000000) >> 25)
-#define PHY_BB_FCAL_1_FLC_SB_ATTEN_SET(x)                                     (((x) << 25) & 0x3e000000)
-
-/* macros for BB_fcal_2_b0 */
-#define PHY_BB_FCAL_2_B0_ADDRESS                                                              0x0000a7dc
-#define PHY_BB_FCAL_2_B0_OFFSET                                                               0x0000a7dc
-#define PHY_BB_FCAL_2_B0_FLC_PWR_THRESH_MSB                                                            2
-#define PHY_BB_FCAL_2_B0_FLC_PWR_THRESH_LSB                                                            0
-#define PHY_BB_FCAL_2_B0_FLC_PWR_THRESH_MASK                                                  0x00000007
-#define PHY_BB_FCAL_2_B0_FLC_PWR_THRESH_GET(x)                                 (((x) & 0x00000007) >> 0)
-#define PHY_BB_FCAL_2_B0_FLC_PWR_THRESH_SET(x)                                 (((x) << 0) & 0x00000007)
-#define PHY_BB_FCAL_2_B0_FLC_SW_CAP_VAL_0_MSB                                                          7
-#define PHY_BB_FCAL_2_B0_FLC_SW_CAP_VAL_0_LSB                                                          3
-#define PHY_BB_FCAL_2_B0_FLC_SW_CAP_VAL_0_MASK                                                0x000000f8
-#define PHY_BB_FCAL_2_B0_FLC_SW_CAP_VAL_0_GET(x)                               (((x) & 0x000000f8) >> 3)
-#define PHY_BB_FCAL_2_B0_FLC_SW_CAP_VAL_0_SET(x)                               (((x) << 3) & 0x000000f8)
-#define PHY_BB_FCAL_2_B0_FLC_BBMISCGAIN_MSB                                                            9
-#define PHY_BB_FCAL_2_B0_FLC_BBMISCGAIN_LSB                                                            8
-#define PHY_BB_FCAL_2_B0_FLC_BBMISCGAIN_MASK                                                  0x00000300
-#define PHY_BB_FCAL_2_B0_FLC_BBMISCGAIN_GET(x)                                 (((x) & 0x00000300) >> 8)
-#define PHY_BB_FCAL_2_B0_FLC_BBMISCGAIN_SET(x)                                 (((x) << 8) & 0x00000300)
-#define PHY_BB_FCAL_2_B0_FLC_BB1DBGAIN_MSB                                                            12
-#define PHY_BB_FCAL_2_B0_FLC_BB1DBGAIN_LSB                                                            10
-#define PHY_BB_FCAL_2_B0_FLC_BB1DBGAIN_MASK                                                   0x00001c00
-#define PHY_BB_FCAL_2_B0_FLC_BB1DBGAIN_GET(x)                                 (((x) & 0x00001c00) >> 10)
-#define PHY_BB_FCAL_2_B0_FLC_BB1DBGAIN_SET(x)                                 (((x) << 10) & 0x00001c00)
-#define PHY_BB_FCAL_2_B0_FLC_BB6DBGAIN_MSB                                                            14
-#define PHY_BB_FCAL_2_B0_FLC_BB6DBGAIN_LSB                                                            13
-#define PHY_BB_FCAL_2_B0_FLC_BB6DBGAIN_MASK                                                   0x00006000
-#define PHY_BB_FCAL_2_B0_FLC_BB6DBGAIN_GET(x)                                 (((x) & 0x00006000) >> 13)
-#define PHY_BB_FCAL_2_B0_FLC_BB6DBGAIN_SET(x)                                 (((x) << 13) & 0x00006000)
-#define PHY_BB_FCAL_2_B0_FLC_SW_CAP_SET_MSB                                                           15
-#define PHY_BB_FCAL_2_B0_FLC_SW_CAP_SET_LSB                                                           15
-#define PHY_BB_FCAL_2_B0_FLC_SW_CAP_SET_MASK                                                  0x00008000
-#define PHY_BB_FCAL_2_B0_FLC_SW_CAP_SET_GET(x)                                (((x) & 0x00008000) >> 15)
-#define PHY_BB_FCAL_2_B0_FLC_SW_CAP_SET_SET(x)                                (((x) << 15) & 0x00008000)
-#define PHY_BB_FCAL_2_B0_FLC_MEAS_WIN_MSB                                                             18
-#define PHY_BB_FCAL_2_B0_FLC_MEAS_WIN_LSB                                                             16
-#define PHY_BB_FCAL_2_B0_FLC_MEAS_WIN_MASK                                                    0x00070000
-#define PHY_BB_FCAL_2_B0_FLC_MEAS_WIN_GET(x)                                  (((x) & 0x00070000) >> 16)
-#define PHY_BB_FCAL_2_B0_FLC_MEAS_WIN_SET(x)                                  (((x) << 16) & 0x00070000)
-#define PHY_BB_FCAL_2_B0_FLC_CAP_VAL_STATUS_0_MSB                                                     24
-#define PHY_BB_FCAL_2_B0_FLC_CAP_VAL_STATUS_0_LSB                                                     20
-#define PHY_BB_FCAL_2_B0_FLC_CAP_VAL_STATUS_0_MASK                                            0x01f00000
-#define PHY_BB_FCAL_2_B0_FLC_CAP_VAL_STATUS_0_GET(x)                          (((x) & 0x01f00000) >> 20)
-
-/* macros for BB_radar_bw_filter */
-#define PHY_BB_RADAR_BW_FILTER_ADDRESS                                                        0x0000a7e0
-#define PHY_BB_RADAR_BW_FILTER_OFFSET                                                         0x0000a7e0
-#define PHY_BB_RADAR_BW_FILTER_RADAR_AVG_BW_CHECK_MSB                                                  0
-#define PHY_BB_RADAR_BW_FILTER_RADAR_AVG_BW_CHECK_LSB                                                  0
-#define PHY_BB_RADAR_BW_FILTER_RADAR_AVG_BW_CHECK_MASK                                        0x00000001
-#define PHY_BB_RADAR_BW_FILTER_RADAR_AVG_BW_CHECK_GET(x)                       (((x) & 0x00000001) >> 0)
-#define PHY_BB_RADAR_BW_FILTER_RADAR_AVG_BW_CHECK_SET(x)                       (((x) << 0) & 0x00000001)
-#define PHY_BB_RADAR_BW_FILTER_RADAR_DC_SRC_SEL_MSB                                                    1
-#define PHY_BB_RADAR_BW_FILTER_RADAR_DC_SRC_SEL_LSB                                                    1
-#define PHY_BB_RADAR_BW_FILTER_RADAR_DC_SRC_SEL_MASK                                          0x00000002
-#define PHY_BB_RADAR_BW_FILTER_RADAR_DC_SRC_SEL_GET(x)                         (((x) & 0x00000002) >> 1)
-#define PHY_BB_RADAR_BW_FILTER_RADAR_DC_SRC_SEL_SET(x)                         (((x) << 1) & 0x00000002)
-#define PHY_BB_RADAR_BW_FILTER_RADAR_FIRPWR_SEL_MSB                                                    3
-#define PHY_BB_RADAR_BW_FILTER_RADAR_FIRPWR_SEL_LSB                                                    2
-#define PHY_BB_RADAR_BW_FILTER_RADAR_FIRPWR_SEL_MASK                                          0x0000000c
-#define PHY_BB_RADAR_BW_FILTER_RADAR_FIRPWR_SEL_GET(x)                         (((x) & 0x0000000c) >> 2)
-#define PHY_BB_RADAR_BW_FILTER_RADAR_FIRPWR_SEL_SET(x)                         (((x) << 2) & 0x0000000c)
-#define PHY_BB_RADAR_BW_FILTER_RADAR_PULSE_WIDTH_SEL_MSB                                               5
-#define PHY_BB_RADAR_BW_FILTER_RADAR_PULSE_WIDTH_SEL_LSB                                               4
-#define PHY_BB_RADAR_BW_FILTER_RADAR_PULSE_WIDTH_SEL_MASK                                     0x00000030
-#define PHY_BB_RADAR_BW_FILTER_RADAR_PULSE_WIDTH_SEL_GET(x)                    (((x) & 0x00000030) >> 4)
-#define PHY_BB_RADAR_BW_FILTER_RADAR_PULSE_WIDTH_SEL_SET(x)                    (((x) << 4) & 0x00000030)
-#define PHY_BB_RADAR_BW_FILTER_RADAR_DC_FIRPWR_THRESH_MSB                                             14
-#define PHY_BB_RADAR_BW_FILTER_RADAR_DC_FIRPWR_THRESH_LSB                                              8
-#define PHY_BB_RADAR_BW_FILTER_RADAR_DC_FIRPWR_THRESH_MASK                                    0x00007f00
-#define PHY_BB_RADAR_BW_FILTER_RADAR_DC_FIRPWR_THRESH_GET(x)                   (((x) & 0x00007f00) >> 8)
-#define PHY_BB_RADAR_BW_FILTER_RADAR_DC_FIRPWR_THRESH_SET(x)                   (((x) << 8) & 0x00007f00)
-#define PHY_BB_RADAR_BW_FILTER_RADAR_DC_PWR_BIAS_MSB                                                  20
-#define PHY_BB_RADAR_BW_FILTER_RADAR_DC_PWR_BIAS_LSB                                                  15
-#define PHY_BB_RADAR_BW_FILTER_RADAR_DC_PWR_BIAS_MASK                                         0x001f8000
-#define PHY_BB_RADAR_BW_FILTER_RADAR_DC_PWR_BIAS_GET(x)                       (((x) & 0x001f8000) >> 15)
-#define PHY_BB_RADAR_BW_FILTER_RADAR_DC_PWR_BIAS_SET(x)                       (((x) << 15) & 0x001f8000)
-#define PHY_BB_RADAR_BW_FILTER_RADAR_BIN_MAX_BW_MSB                                                   26
-#define PHY_BB_RADAR_BW_FILTER_RADAR_BIN_MAX_BW_LSB                                                   21
-#define PHY_BB_RADAR_BW_FILTER_RADAR_BIN_MAX_BW_MASK                                          0x07e00000
-#define PHY_BB_RADAR_BW_FILTER_RADAR_BIN_MAX_BW_GET(x)                        (((x) & 0x07e00000) >> 21)
-#define PHY_BB_RADAR_BW_FILTER_RADAR_BIN_MAX_BW_SET(x)                        (((x) << 21) & 0x07e00000)
-
-/* macros for BB_dft_tone_ctrl_b0 */
-#define PHY_BB_DFT_TONE_CTRL_B0_ADDRESS                                                       0x0000a7e4
-#define PHY_BB_DFT_TONE_CTRL_B0_OFFSET                                                        0x0000a7e4
-#define PHY_BB_DFT_TONE_CTRL_B0_DFT_TONE_EN_0_MSB                                                      0
-#define PHY_BB_DFT_TONE_CTRL_B0_DFT_TONE_EN_0_LSB                                                      0
-#define PHY_BB_DFT_TONE_CTRL_B0_DFT_TONE_EN_0_MASK                                            0x00000001
-#define PHY_BB_DFT_TONE_CTRL_B0_DFT_TONE_EN_0_GET(x)                           (((x) & 0x00000001) >> 0)
-#define PHY_BB_DFT_TONE_CTRL_B0_DFT_TONE_EN_0_SET(x)                           (((x) << 0) & 0x00000001)
-#define PHY_BB_DFT_TONE_CTRL_B0_DFT_TONE_AMP_SEL_0_MSB                                                 3
-#define PHY_BB_DFT_TONE_CTRL_B0_DFT_TONE_AMP_SEL_0_LSB                                                 2
-#define PHY_BB_DFT_TONE_CTRL_B0_DFT_TONE_AMP_SEL_0_MASK                                       0x0000000c
-#define PHY_BB_DFT_TONE_CTRL_B0_DFT_TONE_AMP_SEL_0_GET(x)                      (((x) & 0x0000000c) >> 2)
-#define PHY_BB_DFT_TONE_CTRL_B0_DFT_TONE_AMP_SEL_0_SET(x)                      (((x) << 2) & 0x0000000c)
-#define PHY_BB_DFT_TONE_CTRL_B0_DFT_TONE_FREQ_ANG_0_MSB                                               12
-#define PHY_BB_DFT_TONE_CTRL_B0_DFT_TONE_FREQ_ANG_0_LSB                                                4
-#define PHY_BB_DFT_TONE_CTRL_B0_DFT_TONE_FREQ_ANG_0_MASK                                      0x00001ff0
-#define PHY_BB_DFT_TONE_CTRL_B0_DFT_TONE_FREQ_ANG_0_GET(x)                     (((x) & 0x00001ff0) >> 4)
-#define PHY_BB_DFT_TONE_CTRL_B0_DFT_TONE_FREQ_ANG_0_SET(x)                     (((x) << 4) & 0x00001ff0)
-
-/* macros for BB_therm_adc_1 */
-#define PHY_BB_THERM_ADC_1_ADDRESS                                                            0x0000a7e8
-#define PHY_BB_THERM_ADC_1_OFFSET                                                             0x0000a7e8
-#define PHY_BB_THERM_ADC_1_INIT_THERM_SETTING_MSB                                                      7
-#define PHY_BB_THERM_ADC_1_INIT_THERM_SETTING_LSB                                                      0
-#define PHY_BB_THERM_ADC_1_INIT_THERM_SETTING_MASK                                            0x000000ff
-#define PHY_BB_THERM_ADC_1_INIT_THERM_SETTING_GET(x)                           (((x) & 0x000000ff) >> 0)
-#define PHY_BB_THERM_ADC_1_INIT_THERM_SETTING_SET(x)                           (((x) << 0) & 0x000000ff)
-#define PHY_BB_THERM_ADC_1_INIT_VOLT_SETTING_MSB                                                      15
-#define PHY_BB_THERM_ADC_1_INIT_VOLT_SETTING_LSB                                                       8
-#define PHY_BB_THERM_ADC_1_INIT_VOLT_SETTING_MASK                                             0x0000ff00
-#define PHY_BB_THERM_ADC_1_INIT_VOLT_SETTING_GET(x)                            (((x) & 0x0000ff00) >> 8)
-#define PHY_BB_THERM_ADC_1_INIT_VOLT_SETTING_SET(x)                            (((x) << 8) & 0x0000ff00)
-#define PHY_BB_THERM_ADC_1_INIT_ATB_SETTING_MSB                                                       23
-#define PHY_BB_THERM_ADC_1_INIT_ATB_SETTING_LSB                                                       16
-#define PHY_BB_THERM_ADC_1_INIT_ATB_SETTING_MASK                                              0x00ff0000
-#define PHY_BB_THERM_ADC_1_INIT_ATB_SETTING_GET(x)                            (((x) & 0x00ff0000) >> 16)
-#define PHY_BB_THERM_ADC_1_INIT_ATB_SETTING_SET(x)                            (((x) << 16) & 0x00ff0000)
-#define PHY_BB_THERM_ADC_1_SAMPLES_CNT_CODING_MSB                                                     25
-#define PHY_BB_THERM_ADC_1_SAMPLES_CNT_CODING_LSB                                                     24
-#define PHY_BB_THERM_ADC_1_SAMPLES_CNT_CODING_MASK                                            0x03000000
-#define PHY_BB_THERM_ADC_1_SAMPLES_CNT_CODING_GET(x)                          (((x) & 0x03000000) >> 24)
-#define PHY_BB_THERM_ADC_1_SAMPLES_CNT_CODING_SET(x)                          (((x) << 24) & 0x03000000)
-#define PHY_BB_THERM_ADC_1_USE_INIT_THERM_VOLT_ATB_AFTER_WARM_RESET_MSB                               26
-#define PHY_BB_THERM_ADC_1_USE_INIT_THERM_VOLT_ATB_AFTER_WARM_RESET_LSB                               26
-#define PHY_BB_THERM_ADC_1_USE_INIT_THERM_VOLT_ATB_AFTER_WARM_RESET_MASK                      0x04000000
-#define PHY_BB_THERM_ADC_1_USE_INIT_THERM_VOLT_ATB_AFTER_WARM_RESET_GET(x)    (((x) & 0x04000000) >> 26)
-#define PHY_BB_THERM_ADC_1_USE_INIT_THERM_VOLT_ATB_AFTER_WARM_RESET_SET(x)    (((x) << 26) & 0x04000000)
-#define PHY_BB_THERM_ADC_1_FORCE_THERM_VOLT_ATB_TO_INIT_SETTINGS_MSB                                  27
-#define PHY_BB_THERM_ADC_1_FORCE_THERM_VOLT_ATB_TO_INIT_SETTINGS_LSB                                  27
-#define PHY_BB_THERM_ADC_1_FORCE_THERM_VOLT_ATB_TO_INIT_SETTINGS_MASK                         0x08000000
-#define PHY_BB_THERM_ADC_1_FORCE_THERM_VOLT_ATB_TO_INIT_SETTINGS_GET(x)       (((x) & 0x08000000) >> 27)
-#define PHY_BB_THERM_ADC_1_FORCE_THERM_VOLT_ATB_TO_INIT_SETTINGS_SET(x)       (((x) << 27) & 0x08000000)
-
-/* macros for BB_therm_adc_2 */
-#define PHY_BB_THERM_ADC_2_ADDRESS                                                            0x0000a7ec
-#define PHY_BB_THERM_ADC_2_OFFSET                                                             0x0000a7ec
-#define PHY_BB_THERM_ADC_2_MEASURE_THERM_FREQ_MSB                                                     11
-#define PHY_BB_THERM_ADC_2_MEASURE_THERM_FREQ_LSB                                                      0
-#define PHY_BB_THERM_ADC_2_MEASURE_THERM_FREQ_MASK                                            0x00000fff
-#define PHY_BB_THERM_ADC_2_MEASURE_THERM_FREQ_GET(x)                           (((x) & 0x00000fff) >> 0)
-#define PHY_BB_THERM_ADC_2_MEASURE_THERM_FREQ_SET(x)                           (((x) << 0) & 0x00000fff)
-#define PHY_BB_THERM_ADC_2_MEASURE_VOLT_FREQ_MSB                                                      21
-#define PHY_BB_THERM_ADC_2_MEASURE_VOLT_FREQ_LSB                                                      12
-#define PHY_BB_THERM_ADC_2_MEASURE_VOLT_FREQ_MASK                                             0x003ff000
-#define PHY_BB_THERM_ADC_2_MEASURE_VOLT_FREQ_GET(x)                           (((x) & 0x003ff000) >> 12)
-#define PHY_BB_THERM_ADC_2_MEASURE_VOLT_FREQ_SET(x)                           (((x) << 12) & 0x003ff000)
-#define PHY_BB_THERM_ADC_2_MEASURE_ATB_FREQ_MSB                                                       31
-#define PHY_BB_THERM_ADC_2_MEASURE_ATB_FREQ_LSB                                                       22
-#define PHY_BB_THERM_ADC_2_MEASURE_ATB_FREQ_MASK                                              0xffc00000
-#define PHY_BB_THERM_ADC_2_MEASURE_ATB_FREQ_GET(x)                            (((x) & 0xffc00000) >> 22)
-#define PHY_BB_THERM_ADC_2_MEASURE_ATB_FREQ_SET(x)                            (((x) << 22) & 0xffc00000)
-
-/* macros for BB_therm_adc_3 */
-#define PHY_BB_THERM_ADC_3_ADDRESS                                                            0x0000a7f0
-#define PHY_BB_THERM_ADC_3_OFFSET                                                             0x0000a7f0
-#define PHY_BB_THERM_ADC_3_THERM_ADC_OFFSET_MSB                                                        7
-#define PHY_BB_THERM_ADC_3_THERM_ADC_OFFSET_LSB                                                        0
-#define PHY_BB_THERM_ADC_3_THERM_ADC_OFFSET_MASK                                              0x000000ff
-#define PHY_BB_THERM_ADC_3_THERM_ADC_OFFSET_GET(x)                             (((x) & 0x000000ff) >> 0)
-#define PHY_BB_THERM_ADC_3_THERM_ADC_OFFSET_SET(x)                             (((x) << 0) & 0x000000ff)
-#define PHY_BB_THERM_ADC_3_THERM_ADC_SCALED_GAIN_MSB                                                  16
-#define PHY_BB_THERM_ADC_3_THERM_ADC_SCALED_GAIN_LSB                                                   8
-#define PHY_BB_THERM_ADC_3_THERM_ADC_SCALED_GAIN_MASK                                         0x0001ff00
-#define PHY_BB_THERM_ADC_3_THERM_ADC_SCALED_GAIN_GET(x)                        (((x) & 0x0001ff00) >> 8)
-#define PHY_BB_THERM_ADC_3_THERM_ADC_SCALED_GAIN_SET(x)                        (((x) << 8) & 0x0001ff00)
-#define PHY_BB_THERM_ADC_3_ADC_INTERVAL_MSB                                                           29
-#define PHY_BB_THERM_ADC_3_ADC_INTERVAL_LSB                                                           17
-#define PHY_BB_THERM_ADC_3_ADC_INTERVAL_MASK                                                  0x3ffe0000
-#define PHY_BB_THERM_ADC_3_ADC_INTERVAL_GET(x)                                (((x) & 0x3ffe0000) >> 17)
-#define PHY_BB_THERM_ADC_3_ADC_INTERVAL_SET(x)                                (((x) << 17) & 0x3ffe0000)
-
-/* macros for BB_therm_adc_4 */
-#define PHY_BB_THERM_ADC_4_ADDRESS                                                            0x0000a7f4
-#define PHY_BB_THERM_ADC_4_OFFSET                                                             0x0000a7f4
-#define PHY_BB_THERM_ADC_4_LATEST_THERM_VALUE_MSB                                                      7
-#define PHY_BB_THERM_ADC_4_LATEST_THERM_VALUE_LSB                                                      0
-#define PHY_BB_THERM_ADC_4_LATEST_THERM_VALUE_MASK                                            0x000000ff
-#define PHY_BB_THERM_ADC_4_LATEST_THERM_VALUE_GET(x)                           (((x) & 0x000000ff) >> 0)
-#define PHY_BB_THERM_ADC_4_LATEST_VOLT_VALUE_MSB                                                      15
-#define PHY_BB_THERM_ADC_4_LATEST_VOLT_VALUE_LSB                                                       8
-#define PHY_BB_THERM_ADC_4_LATEST_VOLT_VALUE_MASK                                             0x0000ff00
-#define PHY_BB_THERM_ADC_4_LATEST_VOLT_VALUE_GET(x)                            (((x) & 0x0000ff00) >> 8)
-#define PHY_BB_THERM_ADC_4_LATEST_ATB_VALUE_MSB                                                       23
-#define PHY_BB_THERM_ADC_4_LATEST_ATB_VALUE_LSB                                                       16
-#define PHY_BB_THERM_ADC_4_LATEST_ATB_VALUE_MASK                                              0x00ff0000
-#define PHY_BB_THERM_ADC_4_LATEST_ATB_VALUE_GET(x)                            (((x) & 0x00ff0000) >> 16)
-
-/* macros for BB_tx_forced_gain */
-#define PHY_BB_TX_FORCED_GAIN_ADDRESS                                                         0x0000a7f8
-#define PHY_BB_TX_FORCED_GAIN_OFFSET                                                          0x0000a7f8
-#define PHY_BB_TX_FORCED_GAIN_FORCE_TX_GAIN_MSB                                                        0
-#define PHY_BB_TX_FORCED_GAIN_FORCE_TX_GAIN_LSB                                                        0
-#define PHY_BB_TX_FORCED_GAIN_FORCE_TX_GAIN_MASK                                              0x00000001
-#define PHY_BB_TX_FORCED_GAIN_FORCE_TX_GAIN_GET(x)                             (((x) & 0x00000001) >> 0)
-#define PHY_BB_TX_FORCED_GAIN_FORCE_TX_GAIN_SET(x)                             (((x) << 0) & 0x00000001)
-#define PHY_BB_TX_FORCED_GAIN_FORCED_TXBB1DBGAIN_MSB                                                   3
-#define PHY_BB_TX_FORCED_GAIN_FORCED_TXBB1DBGAIN_LSB                                                   1
-#define PHY_BB_TX_FORCED_GAIN_FORCED_TXBB1DBGAIN_MASK                                         0x0000000e
-#define PHY_BB_TX_FORCED_GAIN_FORCED_TXBB1DBGAIN_GET(x)                        (((x) & 0x0000000e) >> 1)
-#define PHY_BB_TX_FORCED_GAIN_FORCED_TXBB1DBGAIN_SET(x)                        (((x) << 1) & 0x0000000e)
-#define PHY_BB_TX_FORCED_GAIN_FORCED_TXBB6DBGAIN_MSB                                                   5
-#define PHY_BB_TX_FORCED_GAIN_FORCED_TXBB6DBGAIN_LSB                                                   4
-#define PHY_BB_TX_FORCED_GAIN_FORCED_TXBB6DBGAIN_MASK                                         0x00000030
-#define PHY_BB_TX_FORCED_GAIN_FORCED_TXBB6DBGAIN_GET(x)                        (((x) & 0x00000030) >> 4)
-#define PHY_BB_TX_FORCED_GAIN_FORCED_TXBB6DBGAIN_SET(x)                        (((x) << 4) & 0x00000030)
-#define PHY_BB_TX_FORCED_GAIN_FORCED_TXMXRGAIN_MSB                                                     9
-#define PHY_BB_TX_FORCED_GAIN_FORCED_TXMXRGAIN_LSB                                                     6
-#define PHY_BB_TX_FORCED_GAIN_FORCED_TXMXRGAIN_MASK                                           0x000003c0
-#define PHY_BB_TX_FORCED_GAIN_FORCED_TXMXRGAIN_GET(x)                          (((x) & 0x000003c0) >> 6)
-#define PHY_BB_TX_FORCED_GAIN_FORCED_TXMXRGAIN_SET(x)                          (((x) << 6) & 0x000003c0)
-#define PHY_BB_TX_FORCED_GAIN_FORCED_PADRVGNA_MSB                                                     13
-#define PHY_BB_TX_FORCED_GAIN_FORCED_PADRVGNA_LSB                                                     10
-#define PHY_BB_TX_FORCED_GAIN_FORCED_PADRVGNA_MASK                                            0x00003c00
-#define PHY_BB_TX_FORCED_GAIN_FORCED_PADRVGNA_GET(x)                          (((x) & 0x00003c00) >> 10)
-#define PHY_BB_TX_FORCED_GAIN_FORCED_PADRVGNA_SET(x)                          (((x) << 10) & 0x00003c00)
-#define PHY_BB_TX_FORCED_GAIN_FORCED_PADRVGNB_MSB                                                     17
-#define PHY_BB_TX_FORCED_GAIN_FORCED_PADRVGNB_LSB                                                     14
-#define PHY_BB_TX_FORCED_GAIN_FORCED_PADRVGNB_MASK                                            0x0003c000
-#define PHY_BB_TX_FORCED_GAIN_FORCED_PADRVGNB_GET(x)                          (((x) & 0x0003c000) >> 14)
-#define PHY_BB_TX_FORCED_GAIN_FORCED_PADRVGNB_SET(x)                          (((x) << 14) & 0x0003c000)
-#define PHY_BB_TX_FORCED_GAIN_FORCED_PADRVGNC_MSB                                                     21
-#define PHY_BB_TX_FORCED_GAIN_FORCED_PADRVGNC_LSB                                                     18
-#define PHY_BB_TX_FORCED_GAIN_FORCED_PADRVGNC_MASK                                            0x003c0000
-#define PHY_BB_TX_FORCED_GAIN_FORCED_PADRVGNC_GET(x)                          (((x) & 0x003c0000) >> 18)
-#define PHY_BB_TX_FORCED_GAIN_FORCED_PADRVGNC_SET(x)                          (((x) << 18) & 0x003c0000)
-#define PHY_BB_TX_FORCED_GAIN_FORCED_PADRVGND_MSB                                                     23
-#define PHY_BB_TX_FORCED_GAIN_FORCED_PADRVGND_LSB                                                     22
-#define PHY_BB_TX_FORCED_GAIN_FORCED_PADRVGND_MASK                                            0x00c00000
-#define PHY_BB_TX_FORCED_GAIN_FORCED_PADRVGND_GET(x)                          (((x) & 0x00c00000) >> 22)
-#define PHY_BB_TX_FORCED_GAIN_FORCED_PADRVGND_SET(x)                          (((x) << 22) & 0x00c00000)
-#define PHY_BB_TX_FORCED_GAIN_FORCED_ENABLE_PAL_MSB                                                   24
-#define PHY_BB_TX_FORCED_GAIN_FORCED_ENABLE_PAL_LSB                                                   24
-#define PHY_BB_TX_FORCED_GAIN_FORCED_ENABLE_PAL_MASK                                          0x01000000
-#define PHY_BB_TX_FORCED_GAIN_FORCED_ENABLE_PAL_GET(x)                        (((x) & 0x01000000) >> 24)
-#define PHY_BB_TX_FORCED_GAIN_FORCED_ENABLE_PAL_SET(x)                        (((x) << 24) & 0x01000000)
-
-/* macros for BB_eco_ctrl */
-#define PHY_BB_ECO_CTRL_ADDRESS                                                               0x0000a7fc
-#define PHY_BB_ECO_CTRL_OFFSET                                                                0x0000a7fc
-#define PHY_BB_ECO_CTRL_ECO_CTRL_MSB                                                                   7
-#define PHY_BB_ECO_CTRL_ECO_CTRL_LSB                                                                   0
-#define PHY_BB_ECO_CTRL_ECO_CTRL_MASK                                                         0x000000ff
-#define PHY_BB_ECO_CTRL_ECO_CTRL_GET(x)                                        (((x) & 0x000000ff) >> 0)
-#define PHY_BB_ECO_CTRL_ECO_CTRL_SET(x)                                        (((x) << 0) & 0x000000ff)
-
-/* macros for BB_gain_force_max_gains_b1 */
-#define PHY_BB_GAIN_FORCE_MAX_GAINS_B1_ADDRESS                                                0x0000a848
-#define PHY_BB_GAIN_FORCE_MAX_GAINS_B1_OFFSET                                                 0x0000a848
-#define PHY_BB_GAIN_FORCE_MAX_GAINS_B1_XATTEN1_HYST_MARGIN_1_MSB                                      13
-#define PHY_BB_GAIN_FORCE_MAX_GAINS_B1_XATTEN1_HYST_MARGIN_1_LSB                                       7
-#define PHY_BB_GAIN_FORCE_MAX_GAINS_B1_XATTEN1_HYST_MARGIN_1_MASK                             0x00003f80
-#define PHY_BB_GAIN_FORCE_MAX_GAINS_B1_XATTEN1_HYST_MARGIN_1_GET(x)            (((x) & 0x00003f80) >> 7)
-#define PHY_BB_GAIN_FORCE_MAX_GAINS_B1_XATTEN1_HYST_MARGIN_1_SET(x)            (((x) << 7) & 0x00003f80)
-#define PHY_BB_GAIN_FORCE_MAX_GAINS_B1_XATTEN2_HYST_MARGIN_1_MSB                                      20
-#define PHY_BB_GAIN_FORCE_MAX_GAINS_B1_XATTEN2_HYST_MARGIN_1_LSB                                      14
-#define PHY_BB_GAIN_FORCE_MAX_GAINS_B1_XATTEN2_HYST_MARGIN_1_MASK                             0x001fc000
-#define PHY_BB_GAIN_FORCE_MAX_GAINS_B1_XATTEN2_HYST_MARGIN_1_GET(x)           (((x) & 0x001fc000) >> 14)
-#define PHY_BB_GAIN_FORCE_MAX_GAINS_B1_XATTEN2_HYST_MARGIN_1_SET(x)           (((x) << 14) & 0x001fc000)
-
-/* macros for BB_gains_min_offsets_b1 */
-#define PHY_BB_GAINS_MIN_OFFSETS_B1_ADDRESS                                                   0x0000a84c
-#define PHY_BB_GAINS_MIN_OFFSETS_B1_OFFSET                                                    0x0000a84c
-#define PHY_BB_GAINS_MIN_OFFSETS_B1_RF_GAIN_F_1_MSB                                                   24
-#define PHY_BB_GAINS_MIN_OFFSETS_B1_RF_GAIN_F_1_LSB                                                   17
-#define PHY_BB_GAINS_MIN_OFFSETS_B1_RF_GAIN_F_1_MASK                                          0x01fe0000
-#define PHY_BB_GAINS_MIN_OFFSETS_B1_RF_GAIN_F_1_GET(x)                        (((x) & 0x01fe0000) >> 17)
-#define PHY_BB_GAINS_MIN_OFFSETS_B1_RF_GAIN_F_1_SET(x)                        (((x) << 17) & 0x01fe0000)
-#define PHY_BB_GAINS_MIN_OFFSETS_B1_XATTEN1_SW_F_1_MSB                                                25
-#define PHY_BB_GAINS_MIN_OFFSETS_B1_XATTEN1_SW_F_1_LSB                                                25
-#define PHY_BB_GAINS_MIN_OFFSETS_B1_XATTEN1_SW_F_1_MASK                                       0x02000000
-#define PHY_BB_GAINS_MIN_OFFSETS_B1_XATTEN1_SW_F_1_GET(x)                     (((x) & 0x02000000) >> 25)
-#define PHY_BB_GAINS_MIN_OFFSETS_B1_XATTEN1_SW_F_1_SET(x)                     (((x) << 25) & 0x02000000)
-#define PHY_BB_GAINS_MIN_OFFSETS_B1_XATTEN2_SW_F_1_MSB                                                26
-#define PHY_BB_GAINS_MIN_OFFSETS_B1_XATTEN2_SW_F_1_LSB                                                26
-#define PHY_BB_GAINS_MIN_OFFSETS_B1_XATTEN2_SW_F_1_MASK                                       0x04000000
-#define PHY_BB_GAINS_MIN_OFFSETS_B1_XATTEN2_SW_F_1_GET(x)                     (((x) & 0x04000000) >> 26)
-#define PHY_BB_GAINS_MIN_OFFSETS_B1_XATTEN2_SW_F_1_SET(x)                     (((x) << 26) & 0x04000000)
-
-/* macros for BB_rx_ocgain2 */
-#define PHY_BB_RX_OCGAIN2_ADDRESS                                                             0x0000aa00
-#define PHY_BB_RX_OCGAIN2_OFFSET                                                              0x0000aa00
-#define PHY_BB_RX_OCGAIN2_GAIN_ENTRY2_MSB                                                             31
-#define PHY_BB_RX_OCGAIN2_GAIN_ENTRY2_LSB                                                              0
-#define PHY_BB_RX_OCGAIN2_GAIN_ENTRY2_MASK                                                    0xffffffff
-#define PHY_BB_RX_OCGAIN2_GAIN_ENTRY2_SET(x)                                   (((x) << 0) & 0xffffffff)
-
-/* macros for BB_ext_atten_switch_ctl_b1 */
-#define PHY_BB_EXT_ATTEN_SWITCH_CTL_B1_ADDRESS                                                0x0000b20c
-#define PHY_BB_EXT_ATTEN_SWITCH_CTL_B1_OFFSET                                                 0x0000b20c
-#define PHY_BB_EXT_ATTEN_SWITCH_CTL_B1_XATTEN1_DB_1_MSB                                                5
-#define PHY_BB_EXT_ATTEN_SWITCH_CTL_B1_XATTEN1_DB_1_LSB                                                0
-#define PHY_BB_EXT_ATTEN_SWITCH_CTL_B1_XATTEN1_DB_1_MASK                                      0x0000003f
-#define PHY_BB_EXT_ATTEN_SWITCH_CTL_B1_XATTEN1_DB_1_GET(x)                     (((x) & 0x0000003f) >> 0)
-#define PHY_BB_EXT_ATTEN_SWITCH_CTL_B1_XATTEN1_DB_1_SET(x)                     (((x) << 0) & 0x0000003f)
-#define PHY_BB_EXT_ATTEN_SWITCH_CTL_B1_XATTEN2_DB_1_MSB                                               11
-#define PHY_BB_EXT_ATTEN_SWITCH_CTL_B1_XATTEN2_DB_1_LSB                                                6
-#define PHY_BB_EXT_ATTEN_SWITCH_CTL_B1_XATTEN2_DB_1_MASK                                      0x00000fc0
-#define PHY_BB_EXT_ATTEN_SWITCH_CTL_B1_XATTEN2_DB_1_GET(x)                     (((x) & 0x00000fc0) >> 6)
-#define PHY_BB_EXT_ATTEN_SWITCH_CTL_B1_XATTEN2_DB_1_SET(x)                     (((x) << 6) & 0x00000fc0)
-#define PHY_BB_EXT_ATTEN_SWITCH_CTL_B1_XATTEN1_MARGIN_1_MSB                                           16
-#define PHY_BB_EXT_ATTEN_SWITCH_CTL_B1_XATTEN1_MARGIN_1_LSB                                           12
-#define PHY_BB_EXT_ATTEN_SWITCH_CTL_B1_XATTEN1_MARGIN_1_MASK                                  0x0001f000
-#define PHY_BB_EXT_ATTEN_SWITCH_CTL_B1_XATTEN1_MARGIN_1_GET(x)                (((x) & 0x0001f000) >> 12)
-#define PHY_BB_EXT_ATTEN_SWITCH_CTL_B1_XATTEN1_MARGIN_1_SET(x)                (((x) << 12) & 0x0001f000)
-#define PHY_BB_EXT_ATTEN_SWITCH_CTL_B1_XATTEN2_MARGIN_1_MSB                                           21
-#define PHY_BB_EXT_ATTEN_SWITCH_CTL_B1_XATTEN2_MARGIN_1_LSB                                           17
-#define PHY_BB_EXT_ATTEN_SWITCH_CTL_B1_XATTEN2_MARGIN_1_MASK                                  0x003e0000
-#define PHY_BB_EXT_ATTEN_SWITCH_CTL_B1_XATTEN2_MARGIN_1_GET(x)                (((x) & 0x003e0000) >> 17)
-#define PHY_BB_EXT_ATTEN_SWITCH_CTL_B1_XATTEN2_MARGIN_1_SET(x)                (((x) << 17) & 0x003e0000)
-
-
-#ifndef __ASSEMBLER__
-
-typedef struct bb_lc_reg_reg_s {
-  volatile char pad__0[0x9800];                                        /*        0x0 - 0x9800     */
-  volatile unsigned int BB_test_controls;                              /*     0x9800 - 0x9804     */
-  volatile unsigned int BB_gen_controls;                               /*     0x9804 - 0x9808     */
-  volatile unsigned int BB_test_controls_status;                       /*     0x9808 - 0x980c     */
-  volatile unsigned int BB_timing_controls_1;                          /*     0x980c - 0x9810     */
-  volatile unsigned int BB_timing_controls_2;                          /*     0x9810 - 0x9814     */
-  volatile unsigned int BB_timing_controls_3;                          /*     0x9814 - 0x9818     */
-  volatile unsigned int BB_D2_chip_id;                                 /*     0x9818 - 0x981c     */
-  volatile unsigned int BB_active;                                     /*     0x981c - 0x9820     */
-  volatile unsigned int BB_tx_timing_1;                                /*     0x9820 - 0x9824     */
-  volatile unsigned int BB_tx_timing_2;                                /*     0x9824 - 0x9828     */
-  volatile unsigned int BB_tx_timing_3;                                /*     0x9828 - 0x982c     */
-  volatile unsigned int BB_addac_parallel_control;                     /*     0x982c - 0x9830     */
-  volatile char pad__1[0x4];                                           /*     0x9830 - 0x9834     */
-  volatile unsigned int BB_xpa_timing_control;                         /*     0x9834 - 0x9838     */
-  volatile unsigned int BB_misc_pa_control;                            /*     0x9838 - 0x983c     */
-  volatile unsigned int BB_tstdac_constant;                            /*     0x983c - 0x9840     */
-  volatile unsigned int BB_find_signal_low;                            /*     0x9840 - 0x9844     */
-  volatile unsigned int BB_settling_time;                              /*     0x9844 - 0x9848     */
-  volatile unsigned int BB_gain_force_max_gains_b0;                    /*     0x9848 - 0x984c     */
-  volatile unsigned int BB_gains_min_offsets_b0;                       /*     0x984c - 0x9850     */
-  volatile unsigned int BB_desired_sigsize;                            /*     0x9850 - 0x9854     */
-  volatile unsigned int BB_timing_control_3a;                          /*     0x9854 - 0x9858     */
-  volatile unsigned int BB_find_signal;                                /*     0x9858 - 0x985c     */
-  volatile unsigned int BB_agc;                                        /*     0x985c - 0x9860     */
-  volatile unsigned int BB_agc_control;                                /*     0x9860 - 0x9864     */
-  volatile unsigned int BB_cca_b0;                                     /*     0x9864 - 0x9868     */
-  volatile unsigned int BB_sfcorr;                                     /*     0x9868 - 0x986c     */
-  volatile unsigned int BB_self_corr_low;                              /*     0x986c - 0x9870     */
-  volatile char pad__2[0x4];                                           /*     0x9870 - 0x9874     */
-  volatile unsigned int BB_synth_control;                              /*     0x9874 - 0x9878     */
-  volatile unsigned int BB_addac_clk_select;                           /*     0x9878 - 0x987c     */
-  volatile unsigned int BB_pll_cntl;                                   /*     0x987c - 0x9880     */
-  volatile char pad__3[0x80];                                          /*     0x9880 - 0x9900     */
-  volatile unsigned int BB_vit_spur_mask_A;                            /*     0x9900 - 0x9904     */
-  volatile unsigned int BB_vit_spur_mask_B;                            /*     0x9904 - 0x9908     */
-  volatile unsigned int BB_pilot_spur_mask;                            /*     0x9908 - 0x990c     */
-  volatile unsigned int BB_chan_spur_mask;                             /*     0x990c - 0x9910     */
-  volatile unsigned int BB_spectral_scan;                              /*     0x9910 - 0x9914     */
-  volatile unsigned int BB_analog_power_on_time;                       /*     0x9914 - 0x9918     */
-  volatile unsigned int BB_search_start_delay;                         /*     0x9918 - 0x991c     */
-  volatile unsigned int BB_max_rx_length;                              /*     0x991c - 0x9920     */
-  volatile unsigned int BB_timing_control_4;                           /*     0x9920 - 0x9924     */
-  volatile unsigned int BB_timing_control_5;                           /*     0x9924 - 0x9928     */
-  volatile unsigned int BB_phyonly_warm_reset;                         /*     0x9928 - 0x992c     */
-  volatile unsigned int BB_phyonly_control;                            /*     0x992c - 0x9930     */
-  volatile char pad__4[0x4];                                           /*     0x9930 - 0x9934     */
-  volatile unsigned int BB_powertx_rate1;                              /*     0x9934 - 0x9938     */
-  volatile unsigned int BB_powertx_rate2;                              /*     0x9938 - 0x993c     */
-  volatile unsigned int BB_powertx_max;                                /*     0x993c - 0x9940     */
-  volatile unsigned int BB_extension_radar;                            /*     0x9940 - 0x9944     */
-  volatile unsigned int BB_frame_control;                              /*     0x9944 - 0x9948     */
-  volatile unsigned int BB_timing_control_6;                           /*     0x9948 - 0x994c     */
-  volatile unsigned int BB_spur_mask_controls;                         /*     0x994c - 0x9950     */
-  volatile unsigned int BB_rx_iq_corr_b0;                              /*     0x9950 - 0x9954     */
-  volatile unsigned int BB_radar_detection;                            /*     0x9954 - 0x9958     */
-  volatile unsigned int BB_radar_detection_2;                          /*     0x9958 - 0x995c     */
-  volatile unsigned int BB_tx_phase_ramp_b0;                           /*     0x995c - 0x9960     */
-  volatile unsigned int BB_switch_table_chn_b0;                        /*     0x9960 - 0x9964     */
-  volatile unsigned int BB_switch_table_com1;                          /*     0x9964 - 0x9968     */
-  volatile unsigned int BB_cca_ctrl_2_b0;                              /*     0x9968 - 0x996c     */
-  volatile unsigned int BB_switch_table_com2;                          /*     0x996c - 0x9970     */
-  volatile unsigned int BB_restart;                                    /*     0x9970 - 0x9974     */
-  volatile char pad__5[0x4];                                           /*     0x9974 - 0x9978     */
-  volatile unsigned int BB_scrambler_seed;                             /*     0x9978 - 0x997c     */
-  volatile unsigned int BB_rfbus_request;                              /*     0x997c - 0x9980     */
-  volatile char pad__6[0x20];                                          /*     0x9980 - 0x99a0     */
-  volatile unsigned int BB_timing_control_11;                          /*     0x99a0 - 0x99a4     */
-  volatile unsigned int BB_multichain_enable;                          /*     0x99a4 - 0x99a8     */
-  volatile unsigned int BB_multichain_control;                         /*     0x99a8 - 0x99ac     */
-  volatile unsigned int BB_multichain_gain_ctrl;                       /*     0x99ac - 0x99b0     */
-  volatile char pad__7[0x4];                                           /*     0x99b0 - 0x99b4     */
-  volatile unsigned int BB_adc_gain_dc_corr_b0;                        /*     0x99b4 - 0x99b8     */
-  volatile unsigned int BB_ext_chan_pwr_thr_1;                         /*     0x99b8 - 0x99bc     */
-  volatile unsigned int BB_ext_chan_pwr_thr_2_b0;                      /*     0x99bc - 0x99c0     */
-  volatile unsigned int BB_ext_chan_scorr_thr;                         /*     0x99c0 - 0x99c4     */
-  volatile unsigned int BB_ext_chan_detect_win;                        /*     0x99c4 - 0x99c8     */
-  volatile unsigned int BB_pwr_thr_20_40_det;                          /*     0x99c8 - 0x99cc     */
-  volatile char pad__8[0x4];                                           /*     0x99cc - 0x99d0     */
-  volatile unsigned int BB_short_gi_delta_slope;                       /*     0x99d0 - 0x99d4     */
-  volatile char pad__9[0x8];                                           /*     0x99d4 - 0x99dc     */
-  volatile unsigned int BB_chaninfo_ctrl;                              /*     0x99dc - 0x99e0     */
-  volatile unsigned int BB_heavy_clip_ctrl;                            /*     0x99e0 - 0x99e4     */
-  volatile unsigned int BB_heavy_clip_20;                              /*     0x99e4 - 0x99e8     */
-  volatile unsigned int BB_heavy_clip_40;                              /*     0x99e8 - 0x99ec     */
-  volatile unsigned int BB_rifs_srch;                                  /*     0x99ec - 0x99f0     */
-  volatile unsigned int BB_iq_adc_cal_mode;                            /*     0x99f0 - 0x99f4     */
-  volatile char pad__10[0x8];                                          /*     0x99f4 - 0x99fc     */
-  volatile unsigned int BB_per_chain_csd;                              /*     0x99fc - 0x9a00     */
-  volatile unsigned int BB_rx_ocgain[128];                             /*     0x9a00 - 0x9c00     */
-  volatile unsigned int BB_tx_crc;                                     /*     0x9c00 - 0x9c04     */
-  volatile char pad__11[0xc];                                          /*     0x9c04 - 0x9c10     */
-  volatile unsigned int BB_iq_adc_meas_0_b0;                           /*     0x9c10 - 0x9c14     */
-  volatile unsigned int BB_iq_adc_meas_1_b0;                           /*     0x9c14 - 0x9c18     */
-  volatile unsigned int BB_iq_adc_meas_2_b0;                           /*     0x9c18 - 0x9c1c     */
-  volatile unsigned int BB_iq_adc_meas_3_b0;                           /*     0x9c1c - 0x9c20     */
-  volatile unsigned int BB_rfbus_grant;                                /*     0x9c20 - 0x9c24     */
-  volatile unsigned int BB_tstadc;                                     /*     0x9c24 - 0x9c28     */
-  volatile unsigned int BB_tstdac;                                     /*     0x9c28 - 0x9c2c     */
-  volatile char pad__12[0x4];                                          /*     0x9c2c - 0x9c30     */
-  volatile unsigned int BB_illegal_tx_rate;                            /*     0x9c30 - 0x9c34     */
-  volatile unsigned int BB_spur_report_b0;                             /*     0x9c34 - 0x9c38     */
-  volatile unsigned int BB_channel_status;                             /*     0x9c38 - 0x9c3c     */
-  volatile unsigned int BB_rssi_b0;                                    /*     0x9c3c - 0x9c40     */
-  volatile unsigned int BB_spur_est_cck_report_b0;                     /*     0x9c40 - 0x9c44     */
-  volatile char pad__13[0x68];                                         /*     0x9c44 - 0x9cac     */
-  volatile unsigned int BB_chan_info_noise_pwr;                        /*     0x9cac - 0x9cb0     */
-  volatile unsigned int BB_chan_info_gain_diff;                        /*     0x9cb0 - 0x9cb4     */
-  volatile unsigned int BB_chan_info_fine_timing;                      /*     0x9cb4 - 0x9cb8     */
-  volatile unsigned int BB_chan_info_gain_b0;                          /*     0x9cb8 - 0x9cbc     */
-  volatile unsigned int BB_chan_info_chan_tab_b0[60];                  /*     0x9cbc - 0x9dac     */
-  volatile char pad__14[0x38];                                         /*     0x9dac - 0x9de4     */
-  volatile unsigned int BB_paprd_am2am_mask;                           /*     0x9de4 - 0x9de8     */
-  volatile unsigned int BB_paprd_am2pm_mask;                           /*     0x9de8 - 0x9dec     */
-  volatile unsigned int BB_paprd_ht40_mask;                            /*     0x9dec - 0x9df0     */
-  volatile unsigned int BB_paprd_ctrl0;                                /*     0x9df0 - 0x9df4     */
-  volatile unsigned int BB_paprd_ctrl1;                                /*     0x9df4 - 0x9df8     */
-  volatile unsigned int BB_pa_gain123;                                 /*     0x9df8 - 0x9dfc     */
-  volatile unsigned int BB_pa_gain45;                                  /*     0x9dfc - 0x9e00     */
-  volatile unsigned int BB_paprd_pre_post_scale_0;                     /*     0x9e00 - 0x9e04     */
-  volatile unsigned int BB_paprd_pre_post_scale_1;                     /*     0x9e04 - 0x9e08     */
-  volatile unsigned int BB_paprd_pre_post_scale_2;                     /*     0x9e08 - 0x9e0c     */
-  volatile unsigned int BB_paprd_pre_post_scale_3;                     /*     0x9e0c - 0x9e10     */
-  volatile unsigned int BB_paprd_pre_post_scale_4;                     /*     0x9e10 - 0x9e14     */
-  volatile unsigned int BB_paprd_pre_post_scale_5;                     /*     0x9e14 - 0x9e18     */
-  volatile unsigned int BB_paprd_pre_post_scale_6;                     /*     0x9e18 - 0x9e1c     */
-  volatile unsigned int BB_paprd_pre_post_scale_7;                     /*     0x9e1c - 0x9e20     */
-  volatile unsigned int BB_paprd_mem_tab[120];                         /*     0x9e20 - 0xa000     */
-  volatile unsigned int BB_peak_det_ctrl_1;                            /*     0xa000 - 0xa004     */
-  volatile unsigned int BB_peak_det_ctrl_2;                            /*     0xa004 - 0xa008     */
-  volatile unsigned int BB_rx_gain_bounds_1;                           /*     0xa008 - 0xa00c     */
-  volatile unsigned int BB_rx_gain_bounds_2;                           /*     0xa00c - 0xa010     */
-  volatile unsigned int BB_peak_det_cal_ctrl;                          /*     0xa010 - 0xa014     */
-  volatile unsigned int BB_agc_dig_dc_ctrl;                            /*     0xa014 - 0xa018     */
-  volatile unsigned int BB_agc_dig_dc_status_i_b0;                     /*     0xa018 - 0xa01c     */
-  volatile unsigned int BB_agc_dig_dc_status_q_b0;                     /*     0xa01c - 0xa020     */
-  volatile char pad__15[0x1d4];                                        /*     0xa020 - 0xa1f4     */
-  volatile unsigned int BB_bbb_txfir_0;                                /*     0xa1f4 - 0xa1f8     */
-  volatile unsigned int BB_bbb_txfir_1;                                /*     0xa1f8 - 0xa1fc     */
-  volatile unsigned int BB_bbb_txfir_2;                                /*     0xa1fc - 0xa200     */
-  volatile unsigned int BB_modes_select;                               /*     0xa200 - 0xa204     */
-  volatile unsigned int BB_bbb_tx_ctrl;                                /*     0xa204 - 0xa208     */
-  volatile unsigned int BB_bbb_sig_detect;                             /*     0xa208 - 0xa20c     */
-  volatile unsigned int BB_ext_atten_switch_ctl_b0;                    /*     0xa20c - 0xa210     */
-  volatile unsigned int BB_bbb_rx_ctrl_1;                              /*     0xa210 - 0xa214     */
-  volatile unsigned int BB_bbb_rx_ctrl_2;                              /*     0xa214 - 0xa218     */
-  volatile unsigned int BB_bbb_rx_ctrl_3;                              /*     0xa218 - 0xa21c     */
-  volatile unsigned int BB_bbb_rx_ctrl_4;                              /*     0xa21c - 0xa220     */
-  volatile unsigned int BB_bbb_rx_ctrl_5;                              /*     0xa220 - 0xa224     */
-  volatile unsigned int BB_bbb_rx_ctrl_6;                              /*     0xa224 - 0xa228     */
-  volatile unsigned int BB_bbb_dagc_ctrl;                              /*     0xa228 - 0xa22c     */
-  volatile unsigned int BB_force_clken_cck;                            /*     0xa22c - 0xa230     */
-  volatile unsigned int BB_rx_clear_delay;                             /*     0xa230 - 0xa234     */
-  volatile unsigned int BB_powertx_rate3;                              /*     0xa234 - 0xa238     */
-  volatile unsigned int BB_powertx_rate4;                              /*     0xa238 - 0xa23c     */
-  volatile char pad__16[0x4];                                          /*     0xa23c - 0xa240     */
-  volatile unsigned int BB_cck_spur_mit;                               /*     0xa240 - 0xa244     */
-  volatile unsigned int BB_panic_watchdog_status;                      /*     0xa244 - 0xa248     */
-  volatile unsigned int BB_panic_watchdog_ctrl_1;                      /*     0xa248 - 0xa24c     */
-  volatile unsigned int BB_panic_watchdog_ctrl_2;                      /*     0xa24c - 0xa250     */
-  volatile unsigned int BB_iqcorr_ctrl_cck;                            /*     0xa250 - 0xa254     */
-  volatile unsigned int BB_bluetooth_cntl;                             /*     0xa254 - 0xa258     */
-  volatile unsigned int BB_tpc_1;                                      /*     0xa258 - 0xa25c     */
-  volatile unsigned int BB_tpc_2;                                      /*     0xa25c - 0xa260     */
-  volatile unsigned int BB_tpc_3;                                      /*     0xa260 - 0xa264     */
-  volatile unsigned int BB_tpc_4_b0;                                   /*     0xa264 - 0xa268     */
-  volatile unsigned int BB_analog_swap;                                /*     0xa268 - 0xa26c     */
-  volatile unsigned int BB_tpc_5_b0;                                   /*     0xa26c - 0xa270     */
-  volatile unsigned int BB_tpc_6_b0;                                   /*     0xa270 - 0xa274     */
-  volatile unsigned int BB_tpc_7;                                      /*     0xa274 - 0xa278     */
-  volatile unsigned int BB_tpc_8;                                      /*     0xa278 - 0xa27c     */
-  volatile unsigned int BB_tpc_9;                                      /*     0xa27c - 0xa280     */
-  volatile unsigned int BB_pdadc_tab_b0[32];                           /*     0xa280 - 0xa300     */
-  volatile unsigned int BB_cl_tab_b0[16];                              /*     0xa300 - 0xa340     */
-  volatile unsigned int BB_cl_map_0_b0;                                /*     0xa340 - 0xa344     */
-  volatile unsigned int BB_cl_map_1_b0;                                /*     0xa344 - 0xa348     */
-  volatile unsigned int BB_cl_map_2_b0;                                /*     0xa348 - 0xa34c     */
-  volatile unsigned int BB_cl_map_3_b0;                                /*     0xa34c - 0xa350     */
-  volatile char pad__17[0x8];                                          /*     0xa350 - 0xa358     */
-  volatile unsigned int BB_cl_cal_ctrl;                                /*     0xa358 - 0xa35c     */
-  volatile unsigned int BB_cl_map_pal_0_b0;                            /*     0xa35c - 0xa360     */
-  volatile unsigned int BB_cl_map_pal_1_b0;                            /*     0xa360 - 0xa364     */
-  volatile unsigned int BB_cl_map_pal_2_b0;                            /*     0xa364 - 0xa368     */
-  volatile unsigned int BB_cl_map_pal_3_b0;                            /*     0xa368 - 0xa36c     */
-  volatile char pad__18[0x1c];                                         /*     0xa36c - 0xa388     */
-  volatile unsigned int BB_rifs;                                       /*     0xa388 - 0xa38c     */
-  volatile unsigned int BB_powertx_rate5;                              /*     0xa38c - 0xa390     */
-  volatile unsigned int BB_powertx_rate6;                              /*     0xa390 - 0xa394     */
-  volatile unsigned int BB_tpc_10;                                     /*     0xa394 - 0xa398     */
-  volatile unsigned int BB_tpc_11_b0;                                  /*     0xa398 - 0xa39c     */
-  volatile unsigned int BB_cal_chain_mask;                             /*     0xa39c - 0xa3a0     */
-  volatile char pad__19[0x1c];                                         /*     0xa3a0 - 0xa3bc     */
-  volatile unsigned int BB_powertx_sub;                                /*     0xa3bc - 0xa3c0     */
-  volatile unsigned int BB_powertx_rate7;                              /*     0xa3c0 - 0xa3c4     */
-  volatile unsigned int BB_powertx_rate8;                              /*     0xa3c4 - 0xa3c8     */
-  volatile unsigned int BB_powertx_rate9;                              /*     0xa3c8 - 0xa3cc     */
-  volatile unsigned int BB_powertx_rate10;                             /*     0xa3cc - 0xa3d0     */
-  volatile unsigned int BB_powertx_rate11;                             /*     0xa3d0 - 0xa3d4     */
-  volatile unsigned int BB_powertx_rate12;                             /*     0xa3d4 - 0xa3d8     */
-  volatile unsigned int BB_force_analog;                               /*     0xa3d8 - 0xa3dc     */
-  volatile unsigned int BB_tpc_12;                                     /*     0xa3dc - 0xa3e0     */
-  volatile unsigned int BB_tpc_13;                                     /*     0xa3e0 - 0xa3e4     */
-  volatile unsigned int BB_tpc_14;                                     /*     0xa3e4 - 0xa3e8     */
-  volatile unsigned int BB_tpc_15;                                     /*     0xa3e8 - 0xa3ec     */
-  volatile unsigned int BB_tpc_16;                                     /*     0xa3ec - 0xa3f0     */
-  volatile unsigned int BB_tpc_17;                                     /*     0xa3f0 - 0xa3f4     */
-  volatile unsigned int BB_tpc_18;                                     /*     0xa3f4 - 0xa3f8     */
-  volatile unsigned int BB_tpc_19;                                     /*     0xa3f8 - 0xa3fc     */
-  volatile unsigned int BB_tpc_20;                                     /*     0xa3fc - 0xa400     */
-  volatile unsigned int BB_tx_gain_tab_1;                              /*     0xa400 - 0xa404     */
-  volatile unsigned int BB_tx_gain_tab_2;                              /*     0xa404 - 0xa408     */
-  volatile unsigned int BB_tx_gain_tab_3;                              /*     0xa408 - 0xa40c     */
-  volatile unsigned int BB_tx_gain_tab_4;                              /*     0xa40c - 0xa410     */
-  volatile unsigned int BB_tx_gain_tab_5;                              /*     0xa410 - 0xa414     */
-  volatile unsigned int BB_tx_gain_tab_6;                              /*     0xa414 - 0xa418     */
-  volatile unsigned int BB_tx_gain_tab_7;                              /*     0xa418 - 0xa41c     */
-  volatile unsigned int BB_tx_gain_tab_8;                              /*     0xa41c - 0xa420     */
-  volatile unsigned int BB_tx_gain_tab_9;                              /*     0xa420 - 0xa424     */
-  volatile unsigned int BB_tx_gain_tab_10;                             /*     0xa424 - 0xa428     */
-  volatile unsigned int BB_tx_gain_tab_11;                             /*     0xa428 - 0xa42c     */
-  volatile unsigned int BB_tx_gain_tab_12;                             /*     0xa42c - 0xa430     */
-  volatile unsigned int BB_tx_gain_tab_13;                             /*     0xa430 - 0xa434     */
-  volatile unsigned int BB_tx_gain_tab_14;                             /*     0xa434 - 0xa438     */
-  volatile unsigned int BB_tx_gain_tab_15;                             /*     0xa438 - 0xa43c     */
-  volatile unsigned int BB_tx_gain_tab_16;                             /*     0xa43c - 0xa440     */
-  volatile unsigned int BB_tx_gain_tab_17;                             /*     0xa440 - 0xa444     */
-  volatile unsigned int BB_tx_gain_tab_18;                             /*     0xa444 - 0xa448     */
-  volatile unsigned int BB_tx_gain_tab_19;                             /*     0xa448 - 0xa44c     */
-  volatile unsigned int BB_tx_gain_tab_20;                             /*     0xa44c - 0xa450     */
-  volatile unsigned int BB_tx_gain_tab_21;                             /*     0xa450 - 0xa454     */
-  volatile unsigned int BB_tx_gain_tab_22;                             /*     0xa454 - 0xa458     */
-  volatile unsigned int BB_tx_gain_tab_23;                             /*     0xa458 - 0xa45c     */
-  volatile unsigned int BB_tx_gain_tab_24;                             /*     0xa45c - 0xa460     */
-  volatile unsigned int BB_tx_gain_tab_25;                             /*     0xa460 - 0xa464     */
-  volatile unsigned int BB_tx_gain_tab_26;                             /*     0xa464 - 0xa468     */
-  volatile unsigned int BB_tx_gain_tab_27;                             /*     0xa468 - 0xa46c     */
-  volatile unsigned int BB_tx_gain_tab_28;                             /*     0xa46c - 0xa470     */
-  volatile unsigned int BB_tx_gain_tab_29;                             /*     0xa470 - 0xa474     */
-  volatile unsigned int BB_tx_gain_tab_30;                             /*     0xa474 - 0xa478     */
-  volatile unsigned int BB_tx_gain_tab_31;                             /*     0xa478 - 0xa47c     */
-  volatile unsigned int BB_tx_gain_tab_32;                             /*     0xa47c - 0xa480     */
-  volatile unsigned int BB_tx_gain_tab_pal_1;                          /*     0xa480 - 0xa484     */
-  volatile unsigned int BB_tx_gain_tab_pal_2;                          /*     0xa484 - 0xa488     */
-  volatile unsigned int BB_tx_gain_tab_pal_3;                          /*     0xa488 - 0xa48c     */
-  volatile unsigned int BB_tx_gain_tab_pal_4;                          /*     0xa48c - 0xa490     */
-  volatile unsigned int BB_tx_gain_tab_pal_5;                          /*     0xa490 - 0xa494     */
-  volatile unsigned int BB_tx_gain_tab_pal_6;                          /*     0xa494 - 0xa498     */
-  volatile unsigned int BB_tx_gain_tab_pal_7;                          /*     0xa498 - 0xa49c     */
-  volatile unsigned int BB_tx_gain_tab_pal_8;                          /*     0xa49c - 0xa4a0     */
-  volatile unsigned int BB_tx_gain_tab_pal_9;                          /*     0xa4a0 - 0xa4a4     */
-  volatile unsigned int BB_tx_gain_tab_pal_10;                         /*     0xa4a4 - 0xa4a8     */
-  volatile unsigned int BB_tx_gain_tab_pal_11;                         /*     0xa4a8 - 0xa4ac     */
-  volatile unsigned int BB_tx_gain_tab_pal_12;                         /*     0xa4ac - 0xa4b0     */
-  volatile unsigned int BB_tx_gain_tab_pal_13;                         /*     0xa4b0 - 0xa4b4     */
-  volatile unsigned int BB_tx_gain_tab_pal_14;                         /*     0xa4b4 - 0xa4b8     */
-  volatile unsigned int BB_tx_gain_tab_pal_15;                         /*     0xa4b8 - 0xa4bc     */
-  volatile unsigned int BB_tx_gain_tab_pal_16;                         /*     0xa4bc - 0xa4c0     */
-  volatile unsigned int BB_tx_gain_tab_pal_17;                         /*     0xa4c0 - 0xa4c4     */
-  volatile unsigned int BB_tx_gain_tab_pal_18;                         /*     0xa4c4 - 0xa4c8     */
-  volatile unsigned int BB_tx_gain_tab_pal_19;                         /*     0xa4c8 - 0xa4cc     */
-  volatile unsigned int BB_tx_gain_tab_pal_20;                         /*     0xa4cc - 0xa4d0     */
-  volatile unsigned int BB_tx_gain_tab_pal_21;                         /*     0xa4d0 - 0xa4d4     */
-  volatile unsigned int BB_tx_gain_tab_pal_22;                         /*     0xa4d4 - 0xa4d8     */
-  volatile unsigned int BB_tx_gain_tab_pal_23;                         /*     0xa4d8 - 0xa4dc     */
-  volatile unsigned int BB_tx_gain_tab_pal_24;                         /*     0xa4dc - 0xa4e0     */
-  volatile unsigned int BB_tx_gain_tab_pal_25;                         /*     0xa4e0 - 0xa4e4     */
-  volatile unsigned int BB_tx_gain_tab_pal_26;                         /*     0xa4e4 - 0xa4e8     */
-  volatile unsigned int BB_tx_gain_tab_pal_27;                         /*     0xa4e8 - 0xa4ec     */
-  volatile unsigned int BB_tx_gain_tab_pal_28;                         /*     0xa4ec - 0xa4f0     */
-  volatile unsigned int BB_tx_gain_tab_pal_29;                         /*     0xa4f0 - 0xa4f4     */
-  volatile unsigned int BB_tx_gain_tab_pal_30;                         /*     0xa4f4 - 0xa4f8     */
-  volatile unsigned int BB_tx_gain_tab_pal_31;                         /*     0xa4f8 - 0xa4fc     */
-  volatile unsigned int BB_tx_gain_tab_pal_32;                         /*     0xa4fc - 0xa500     */
-  volatile char pad__20[0x18];                                         /*     0xa500 - 0xa518     */
-  volatile unsigned int BB_caltx_gain_set_0;                           /*     0xa518 - 0xa51c     */
-  volatile unsigned int BB_caltx_gain_set_2;                           /*     0xa51c - 0xa520     */
-  volatile unsigned int BB_caltx_gain_set_4;                           /*     0xa520 - 0xa524     */
-  volatile unsigned int BB_caltx_gain_set_6;                           /*     0xa524 - 0xa528     */
-  volatile unsigned int BB_caltx_gain_set_8;                           /*     0xa528 - 0xa52c     */
-  volatile unsigned int BB_caltx_gain_set_10;                          /*     0xa52c - 0xa530     */
-  volatile unsigned int BB_caltx_gain_set_12;                          /*     0xa530 - 0xa534     */
-  volatile unsigned int BB_caltx_gain_set_14;                          /*     0xa534 - 0xa538     */
-  volatile unsigned int BB_caltx_gain_set_16;                          /*     0xa538 - 0xa53c     */
-  volatile unsigned int BB_caltx_gain_set_18;                          /*     0xa53c - 0xa540     */
-  volatile unsigned int BB_caltx_gain_set_20;                          /*     0xa540 - 0xa544     */
-  volatile unsigned int BB_caltx_gain_set_22;                          /*     0xa544 - 0xa548     */
-  volatile unsigned int BB_caltx_gain_set_24;                          /*     0xa548 - 0xa54c     */
-  volatile unsigned int BB_caltx_gain_set_26;                          /*     0xa54c - 0xa550     */
-  volatile unsigned int BB_caltx_gain_set_28;                          /*     0xa550 - 0xa554     */
-  volatile unsigned int BB_caltx_gain_set_30;                          /*     0xa554 - 0xa558     */
-  volatile unsigned int BB_txiqcal_meas_b0[96];                        /*     0xa558 - 0xa6d8     */
-  volatile unsigned int BB_txiqcal_start;                              /*     0xa6d8 - 0xa6dc     */
-  volatile unsigned int BB_txiqcal_control_0;                          /*     0xa6dc - 0xa6e0     */
-  volatile unsigned int BB_txiqcal_control_1;                          /*     0xa6e0 - 0xa6e4     */
-  volatile unsigned int BB_txiqcal_control_2;                          /*     0xa6e4 - 0xa6e8     */
-  volatile unsigned int BB_txiqcal_control_3;                          /*     0xa6e8 - 0xa6ec     */
-  volatile unsigned int BB_txiq_corr_coeff_01_b0;                      /*     0xa6ec - 0xa6f0     */
-  volatile unsigned int BB_txiq_corr_coeff_23_b0;                      /*     0xa6f0 - 0xa6f4     */
-  volatile unsigned int BB_txiq_corr_coeff_45_b0;                      /*     0xa6f4 - 0xa6f8     */
-  volatile unsigned int BB_txiq_corr_coeff_67_b0;                      /*     0xa6f8 - 0xa6fc     */
-  volatile unsigned int BB_txiq_corr_coeff_89_b0;                      /*     0xa6fc - 0xa700     */
-  volatile unsigned int BB_txiq_corr_coeff_ab_b0;                      /*     0xa700 - 0xa704     */
-  volatile unsigned int BB_txiq_corr_coeff_cd_b0;                      /*     0xa704 - 0xa708     */
-  volatile unsigned int BB_txiq_corr_coeff_ef_b0;                      /*     0xa708 - 0xa70c     */
-  volatile unsigned int BB_cal_rxbb_gain_tbl_0;                        /*     0xa70c - 0xa710     */
-  volatile unsigned int BB_cal_rxbb_gain_tbl_4;                        /*     0xa710 - 0xa714     */
-  volatile unsigned int BB_cal_rxbb_gain_tbl_8;                        /*     0xa714 - 0xa718     */
-  volatile unsigned int BB_cal_rxbb_gain_tbl_12;                       /*     0xa718 - 0xa71c     */
-  volatile unsigned int BB_cal_rxbb_gain_tbl_16;                       /*     0xa71c - 0xa720     */
-  volatile unsigned int BB_cal_rxbb_gain_tbl_20;                       /*     0xa720 - 0xa724     */
-  volatile unsigned int BB_cal_rxbb_gain_tbl_24;                       /*     0xa724 - 0xa728     */
-  volatile unsigned int BB_txiqcal_status_b0;                          /*     0xa728 - 0xa72c     */
-  volatile unsigned int BB_paprd_trainer_cntl1;                        /*     0xa72c - 0xa730     */
-  volatile unsigned int BB_paprd_trainer_cntl2;                        /*     0xa730 - 0xa734     */
-  volatile unsigned int BB_paprd_trainer_cntl3;                        /*     0xa734 - 0xa738     */
-  volatile unsigned int BB_paprd_trainer_cntl4;                        /*     0xa738 - 0xa73c     */
-  volatile unsigned int BB_paprd_trainer_stat1;                        /*     0xa73c - 0xa740     */
-  volatile unsigned int BB_paprd_trainer_stat2;                        /*     0xa740 - 0xa744     */
-  volatile unsigned int BB_paprd_trainer_stat3;                        /*     0xa744 - 0xa748     */
-  volatile char pad__21[0x90];                                         /*     0xa748 - 0xa7d8     */
-  volatile unsigned int BB_fcal_1;                                     /*     0xa7d8 - 0xa7dc     */
-  volatile unsigned int BB_fcal_2_b0;                                  /*     0xa7dc - 0xa7e0     */
-  volatile unsigned int BB_radar_bw_filter;                            /*     0xa7e0 - 0xa7e4     */
-  volatile unsigned int BB_dft_tone_ctrl_b0;                           /*     0xa7e4 - 0xa7e8     */
-  volatile unsigned int BB_therm_adc_1;                                /*     0xa7e8 - 0xa7ec     */
-  volatile unsigned int BB_therm_adc_2;                                /*     0xa7ec - 0xa7f0     */
-  volatile unsigned int BB_therm_adc_3;                                /*     0xa7f0 - 0xa7f4     */
-  volatile unsigned int BB_therm_adc_4;                                /*     0xa7f4 - 0xa7f8     */
-  volatile unsigned int BB_tx_forced_gain;                             /*     0xa7f8 - 0xa7fc     */
-  volatile unsigned int BB_eco_ctrl;                                   /*     0xa7fc - 0xa800     */
-  volatile char pad__22[0x48];                                         /*     0xa800 - 0xa848     */
-  volatile unsigned int BB_gain_force_max_gains_b1;                    /*     0xa848 - 0xa84c     */
-  volatile unsigned int BB_gains_min_offsets_b1;                       /*     0xa84c - 0xa850     */
-  volatile char pad__23[0x1b0];                                        /*     0xa850 - 0xaa00     */
-  volatile unsigned int BB_rx_ocgain2[128];                            /*     0xaa00 - 0xac00     */
-  volatile char pad__24[0x60c];                                        /*     0xac00 - 0xb20c     */
-  volatile unsigned int BB_ext_atten_switch_ctl_b1;                    /*     0xb20c - 0xb210     */
-} bb_lc_reg_reg_t;
-
-#endif /* __ASSEMBLER__ */
-
-#endif /* _BB_LC_REG_REG_H_ */
diff -druN linux-2.6.39-libre/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/efuse_reg.h linux-3.0-rc7-libre/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/efuse_reg.h
--- linux-2.6.39-libre/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/efuse_reg.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/efuse_reg.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,108 +0,0 @@
-// ------------------------------------------------------------------
-// Copyright (c) 2004-2010 Atheros Corporation.  All rights reserved.
-// 
-//
-// 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.
-//
-//
-// ------------------------------------------------------------------
-//===================================================================
-// Author(s): ="Atheros"
-//===================================================================
-
-
-#ifndef _EFUSE_REG_REG_H_
-#define _EFUSE_REG_REG_H_
-
-#define EFUSE_WR_ENABLE_REG_ADDRESS              0x00000000
-#define EFUSE_WR_ENABLE_REG_OFFSET               0x00000000
-#define EFUSE_WR_ENABLE_REG_V_MSB                0
-#define EFUSE_WR_ENABLE_REG_V_LSB                0
-#define EFUSE_WR_ENABLE_REG_V_MASK               0x00000001
-#define EFUSE_WR_ENABLE_REG_V_GET(x)             (((x) & EFUSE_WR_ENABLE_REG_V_MASK) >> EFUSE_WR_ENABLE_REG_V_LSB)
-#define EFUSE_WR_ENABLE_REG_V_SET(x)             (((x) << EFUSE_WR_ENABLE_REG_V_LSB) & EFUSE_WR_ENABLE_REG_V_MASK)
-
-#define EFUSE_INT_ENABLE_REG_ADDRESS             0x00000004
-#define EFUSE_INT_ENABLE_REG_OFFSET              0x00000004
-#define EFUSE_INT_ENABLE_REG_V_MSB               0
-#define EFUSE_INT_ENABLE_REG_V_LSB               0
-#define EFUSE_INT_ENABLE_REG_V_MASK              0x00000001
-#define EFUSE_INT_ENABLE_REG_V_GET(x)            (((x) & EFUSE_INT_ENABLE_REG_V_MASK) >> EFUSE_INT_ENABLE_REG_V_LSB)
-#define EFUSE_INT_ENABLE_REG_V_SET(x)            (((x) << EFUSE_INT_ENABLE_REG_V_LSB) & EFUSE_INT_ENABLE_REG_V_MASK)
-
-#define EFUSE_INT_STATUS_REG_ADDRESS             0x00000008
-#define EFUSE_INT_STATUS_REG_OFFSET              0x00000008
-#define EFUSE_INT_STATUS_REG_V_MSB               0
-#define EFUSE_INT_STATUS_REG_V_LSB               0
-#define EFUSE_INT_STATUS_REG_V_MASK              0x00000001
-#define EFUSE_INT_STATUS_REG_V_GET(x)            (((x) & EFUSE_INT_STATUS_REG_V_MASK) >> EFUSE_INT_STATUS_REG_V_LSB)
-#define EFUSE_INT_STATUS_REG_V_SET(x)            (((x) << EFUSE_INT_STATUS_REG_V_LSB) & EFUSE_INT_STATUS_REG_V_MASK)
-
-#define BITMASK_WR_REG_ADDRESS                   0x0000000c
-#define BITMASK_WR_REG_OFFSET                    0x0000000c
-#define BITMASK_WR_REG_V_MSB                     31
-#define BITMASK_WR_REG_V_LSB                     0
-#define BITMASK_WR_REG_V_MASK                    0xffffffff
-#define BITMASK_WR_REG_V_GET(x)                  (((x) & BITMASK_WR_REG_V_MASK) >> BITMASK_WR_REG_V_LSB)
-#define BITMASK_WR_REG_V_SET(x)                  (((x) << BITMASK_WR_REG_V_LSB) & BITMASK_WR_REG_V_MASK)
-
-#define VDDQ_SETTLE_TIME_REG_ADDRESS             0x00000010
-#define VDDQ_SETTLE_TIME_REG_OFFSET              0x00000010
-#define VDDQ_SETTLE_TIME_REG_V_MSB               31
-#define VDDQ_SETTLE_TIME_REG_V_LSB               0
-#define VDDQ_SETTLE_TIME_REG_V_MASK              0xffffffff
-#define VDDQ_SETTLE_TIME_REG_V_GET(x)            (((x) & VDDQ_SETTLE_TIME_REG_V_MASK) >> VDDQ_SETTLE_TIME_REG_V_LSB)
-#define VDDQ_SETTLE_TIME_REG_V_SET(x)            (((x) << VDDQ_SETTLE_TIME_REG_V_LSB) & VDDQ_SETTLE_TIME_REG_V_MASK)
-
-#define RD_STROBE_PW_REG_ADDRESS                 0x00000014
-#define RD_STROBE_PW_REG_OFFSET                  0x00000014
-#define RD_STROBE_PW_REG_V_MSB                   31
-#define RD_STROBE_PW_REG_V_LSB                   0
-#define RD_STROBE_PW_REG_V_MASK                  0xffffffff
-#define RD_STROBE_PW_REG_V_GET(x)                (((x) & RD_STROBE_PW_REG_V_MASK) >> RD_STROBE_PW_REG_V_LSB)
-#define RD_STROBE_PW_REG_V_SET(x)                (((x) << RD_STROBE_PW_REG_V_LSB) & RD_STROBE_PW_REG_V_MASK)
-
-#define PG_STROBE_PW_REG_ADDRESS                 0x00000018
-#define PG_STROBE_PW_REG_OFFSET                  0x00000018
-#define PG_STROBE_PW_REG_V_MSB                   31
-#define PG_STROBE_PW_REG_V_LSB                   0
-#define PG_STROBE_PW_REG_V_MASK                  0xffffffff
-#define PG_STROBE_PW_REG_V_GET(x)                (((x) & PG_STROBE_PW_REG_V_MASK) >> PG_STROBE_PW_REG_V_LSB)
-#define PG_STROBE_PW_REG_V_SET(x)                (((x) << PG_STROBE_PW_REG_V_LSB) & PG_STROBE_PW_REG_V_MASK)
-
-#define EFUSE_INTF_ADDRESS                       0x00000800
-#define EFUSE_INTF_OFFSET                        0x00000800
-#define EFUSE_INTF_R_MSB                         31
-#define EFUSE_INTF_R_LSB                         0
-#define EFUSE_INTF_R_MASK                        0xffffffff
-#define EFUSE_INTF_R_GET(x)                      (((x) & EFUSE_INTF_R_MASK) >> EFUSE_INTF_R_LSB)
-#define EFUSE_INTF_R_SET(x)                      (((x) << EFUSE_INTF_R_LSB) & EFUSE_INTF_R_MASK)
-
-
-#ifndef __ASSEMBLER__
-
-typedef struct efuse_reg_reg_s {
-  volatile unsigned int efuse_wr_enable_reg;
-  volatile unsigned int efuse_int_enable_reg;
-  volatile unsigned int efuse_int_status_reg;
-  volatile unsigned int bitmask_wr_reg;
-  volatile unsigned int vddq_settle_time_reg;
-  volatile unsigned int rd_strobe_pw_reg;
-  volatile unsigned int pg_strobe_pw_reg;
-  unsigned char pad0[2020]; /* pad to 0x800 */
-  volatile unsigned int efuse_intf[512];
-} efuse_reg_reg_t;
-
-#endif /* __ASSEMBLER__ */
-
-#endif /* _EFUSE_REG_H_ */
diff -druN linux-2.6.39-libre/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/gpio_athr_wlan_reg.h linux-3.0-rc7-libre/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/gpio_athr_wlan_reg.h
--- linux-2.6.39-libre/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/gpio_athr_wlan_reg.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/gpio_athr_wlan_reg.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,1253 +0,0 @@
-// ------------------------------------------------------------------
-// Copyright (c) 2004-2010 Atheros Corporation.  All rights reserved.
-// 
-//
-// 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.
-//
-//
-// ------------------------------------------------------------------
-//===================================================================
-// Author(s): ="Atheros"
-//===================================================================
-
-
-#ifndef _GPIO_ATHR_WLAN_REG_REG_H_
-#define _GPIO_ATHR_WLAN_REG_REG_H_
-
-#define WLAN_GPIO_OUT_ADDRESS                    0x00000000
-#define WLAN_GPIO_OUT_OFFSET                     0x00000000
-#define WLAN_GPIO_OUT_DATA_MSB                   25
-#define WLAN_GPIO_OUT_DATA_LSB                   0
-#define WLAN_GPIO_OUT_DATA_MASK                  0x03ffffff
-#define WLAN_GPIO_OUT_DATA_GET(x)                (((x) & WLAN_GPIO_OUT_DATA_MASK) >> WLAN_GPIO_OUT_DATA_LSB)
-#define WLAN_GPIO_OUT_DATA_SET(x)                (((x) << WLAN_GPIO_OUT_DATA_LSB) & WLAN_GPIO_OUT_DATA_MASK)
-
-#define WLAN_GPIO_OUT_W1TS_ADDRESS               0x00000004
-#define WLAN_GPIO_OUT_W1TS_OFFSET                0x00000004
-#define WLAN_GPIO_OUT_W1TS_DATA_MSB              25
-#define WLAN_GPIO_OUT_W1TS_DATA_LSB              0
-#define WLAN_GPIO_OUT_W1TS_DATA_MASK             0x03ffffff
-#define WLAN_GPIO_OUT_W1TS_DATA_GET(x)           (((x) & WLAN_GPIO_OUT_W1TS_DATA_MASK) >> WLAN_GPIO_OUT_W1TS_DATA_LSB)
-#define WLAN_GPIO_OUT_W1TS_DATA_SET(x)           (((x) << WLAN_GPIO_OUT_W1TS_DATA_LSB) & WLAN_GPIO_OUT_W1TS_DATA_MASK)
-
-#define WLAN_GPIO_OUT_W1TC_ADDRESS               0x00000008
-#define WLAN_GPIO_OUT_W1TC_OFFSET                0x00000008
-#define WLAN_GPIO_OUT_W1TC_DATA_MSB              25
-#define WLAN_GPIO_OUT_W1TC_DATA_LSB              0
-#define WLAN_GPIO_OUT_W1TC_DATA_MASK             0x03ffffff
-#define WLAN_GPIO_OUT_W1TC_DATA_GET(x)           (((x) & WLAN_GPIO_OUT_W1TC_DATA_MASK) >> WLAN_GPIO_OUT_W1TC_DATA_LSB)
-#define WLAN_GPIO_OUT_W1TC_DATA_SET(x)           (((x) << WLAN_GPIO_OUT_W1TC_DATA_LSB) & WLAN_GPIO_OUT_W1TC_DATA_MASK)
-
-#define WLAN_GPIO_ENABLE_ADDRESS                 0x0000000c
-#define WLAN_GPIO_ENABLE_OFFSET                  0x0000000c
-#define WLAN_GPIO_ENABLE_DATA_MSB                25
-#define WLAN_GPIO_ENABLE_DATA_LSB                0
-#define WLAN_GPIO_ENABLE_DATA_MASK               0x03ffffff
-#define WLAN_GPIO_ENABLE_DATA_GET(x)             (((x) & WLAN_GPIO_ENABLE_DATA_MASK) >> WLAN_GPIO_ENABLE_DATA_LSB)
-#define WLAN_GPIO_ENABLE_DATA_SET(x)             (((x) << WLAN_GPIO_ENABLE_DATA_LSB) & WLAN_GPIO_ENABLE_DATA_MASK)
-
-#define WLAN_GPIO_ENABLE_W1TS_ADDRESS            0x00000010
-#define WLAN_GPIO_ENABLE_W1TS_OFFSET             0x00000010
-#define WLAN_GPIO_ENABLE_W1TS_DATA_MSB           25
-#define WLAN_GPIO_ENABLE_W1TS_DATA_LSB           0
-#define WLAN_GPIO_ENABLE_W1TS_DATA_MASK          0x03ffffff
-#define WLAN_GPIO_ENABLE_W1TS_DATA_GET(x)        (((x) & WLAN_GPIO_ENABLE_W1TS_DATA_MASK) >> WLAN_GPIO_ENABLE_W1TS_DATA_LSB)
-#define WLAN_GPIO_ENABLE_W1TS_DATA_SET(x)        (((x) << WLAN_GPIO_ENABLE_W1TS_DATA_LSB) & WLAN_GPIO_ENABLE_W1TS_DATA_MASK)
-
-#define WLAN_GPIO_ENABLE_W1TC_ADDRESS            0x00000014
-#define WLAN_GPIO_ENABLE_W1TC_OFFSET             0x00000014
-#define WLAN_GPIO_ENABLE_W1TC_DATA_MSB           25
-#define WLAN_GPIO_ENABLE_W1TC_DATA_LSB           0
-#define WLAN_GPIO_ENABLE_W1TC_DATA_MASK          0x03ffffff
-#define WLAN_GPIO_ENABLE_W1TC_DATA_GET(x)        (((x) & WLAN_GPIO_ENABLE_W1TC_DATA_MASK) >> WLAN_GPIO_ENABLE_W1TC_DATA_LSB)
-#define WLAN_GPIO_ENABLE_W1TC_DATA_SET(x)        (((x) << WLAN_GPIO_ENABLE_W1TC_DATA_LSB) & WLAN_GPIO_ENABLE_W1TC_DATA_MASK)
-
-#define WLAN_GPIO_IN_ADDRESS                     0x00000018
-#define WLAN_GPIO_IN_OFFSET                      0x00000018
-#define WLAN_GPIO_IN_DATA_MSB                    25
-#define WLAN_GPIO_IN_DATA_LSB                    0
-#define WLAN_GPIO_IN_DATA_MASK                   0x03ffffff
-#define WLAN_GPIO_IN_DATA_GET(x)                 (((x) & WLAN_GPIO_IN_DATA_MASK) >> WLAN_GPIO_IN_DATA_LSB)
-#define WLAN_GPIO_IN_DATA_SET(x)                 (((x) << WLAN_GPIO_IN_DATA_LSB) & WLAN_GPIO_IN_DATA_MASK)
-
-#define WLAN_GPIO_STATUS_ADDRESS                 0x0000001c
-#define WLAN_GPIO_STATUS_OFFSET                  0x0000001c
-#define WLAN_GPIO_STATUS_INTERRUPT_MSB           25
-#define WLAN_GPIO_STATUS_INTERRUPT_LSB           0
-#define WLAN_GPIO_STATUS_INTERRUPT_MASK          0x03ffffff
-#define WLAN_GPIO_STATUS_INTERRUPT_GET(x)        (((x) & WLAN_GPIO_STATUS_INTERRUPT_MASK) >> WLAN_GPIO_STATUS_INTERRUPT_LSB)
-#define WLAN_GPIO_STATUS_INTERRUPT_SET(x)        (((x) << WLAN_GPIO_STATUS_INTERRUPT_LSB) & WLAN_GPIO_STATUS_INTERRUPT_MASK)
-
-#define WLAN_GPIO_STATUS_W1TS_ADDRESS            0x00000020
-#define WLAN_GPIO_STATUS_W1TS_OFFSET             0x00000020
-#define WLAN_GPIO_STATUS_W1TS_INTERRUPT_MSB      25
-#define WLAN_GPIO_STATUS_W1TS_INTERRUPT_LSB      0
-#define WLAN_GPIO_STATUS_W1TS_INTERRUPT_MASK     0x03ffffff
-#define WLAN_GPIO_STATUS_W1TS_INTERRUPT_GET(x)   (((x) & WLAN_GPIO_STATUS_W1TS_INTERRUPT_MASK) >> WLAN_GPIO_STATUS_W1TS_INTERRUPT_LSB)
-#define WLAN_GPIO_STATUS_W1TS_INTERRUPT_SET(x)   (((x) << WLAN_GPIO_STATUS_W1TS_INTERRUPT_LSB) & WLAN_GPIO_STATUS_W1TS_INTERRUPT_MASK)
-
-#define WLAN_GPIO_STATUS_W1TC_ADDRESS            0x00000024
-#define WLAN_GPIO_STATUS_W1TC_OFFSET             0x00000024
-#define WLAN_GPIO_STATUS_W1TC_INTERRUPT_MSB      25
-#define WLAN_GPIO_STATUS_W1TC_INTERRUPT_LSB      0
-#define WLAN_GPIO_STATUS_W1TC_INTERRUPT_MASK     0x03ffffff
-#define WLAN_GPIO_STATUS_W1TC_INTERRUPT_GET(x)   (((x) & WLAN_GPIO_STATUS_W1TC_INTERRUPT_MASK) >> WLAN_GPIO_STATUS_W1TC_INTERRUPT_LSB)
-#define WLAN_GPIO_STATUS_W1TC_INTERRUPT_SET(x)   (((x) << WLAN_GPIO_STATUS_W1TC_INTERRUPT_LSB) & WLAN_GPIO_STATUS_W1TC_INTERRUPT_MASK)
-
-#define WLAN_GPIO_PIN0_ADDRESS                   0x00000028
-#define WLAN_GPIO_PIN0_OFFSET                    0x00000028
-#define WLAN_GPIO_PIN0_CONFIG_MSB                13
-#define WLAN_GPIO_PIN0_CONFIG_LSB                11
-#define WLAN_GPIO_PIN0_CONFIG_MASK               0x00003800
-#define WLAN_GPIO_PIN0_CONFIG_GET(x)             (((x) & WLAN_GPIO_PIN0_CONFIG_MASK) >> WLAN_GPIO_PIN0_CONFIG_LSB)
-#define WLAN_GPIO_PIN0_CONFIG_SET(x)             (((x) << WLAN_GPIO_PIN0_CONFIG_LSB) & WLAN_GPIO_PIN0_CONFIG_MASK)
-#define WLAN_GPIO_PIN0_WAKEUP_ENABLE_MSB         10
-#define WLAN_GPIO_PIN0_WAKEUP_ENABLE_LSB         10
-#define WLAN_GPIO_PIN0_WAKEUP_ENABLE_MASK        0x00000400
-#define WLAN_GPIO_PIN0_WAKEUP_ENABLE_GET(x)      (((x) & WLAN_GPIO_PIN0_WAKEUP_ENABLE_MASK) >> WLAN_GPIO_PIN0_WAKEUP_ENABLE_LSB)
-#define WLAN_GPIO_PIN0_WAKEUP_ENABLE_SET(x)      (((x) << WLAN_GPIO_PIN0_WAKEUP_ENABLE_LSB) & WLAN_GPIO_PIN0_WAKEUP_ENABLE_MASK)
-#define WLAN_GPIO_PIN0_INT_TYPE_MSB              9
-#define WLAN_GPIO_PIN0_INT_TYPE_LSB              7
-#define WLAN_GPIO_PIN0_INT_TYPE_MASK             0x00000380
-#define WLAN_GPIO_PIN0_INT_TYPE_GET(x)           (((x) & WLAN_GPIO_PIN0_INT_TYPE_MASK) >> WLAN_GPIO_PIN0_INT_TYPE_LSB)
-#define WLAN_GPIO_PIN0_INT_TYPE_SET(x)           (((x) << WLAN_GPIO_PIN0_INT_TYPE_LSB) & WLAN_GPIO_PIN0_INT_TYPE_MASK)
-#define WLAN_GPIO_PIN0_PAD_PULL_MSB              6
-#define WLAN_GPIO_PIN0_PAD_PULL_LSB              5
-#define WLAN_GPIO_PIN0_PAD_PULL_MASK             0x00000060
-#define WLAN_GPIO_PIN0_PAD_PULL_GET(x)           (((x) & WLAN_GPIO_PIN0_PAD_PULL_MASK) >> WLAN_GPIO_PIN0_PAD_PULL_LSB)
-#define WLAN_GPIO_PIN0_PAD_PULL_SET(x)           (((x) << WLAN_GPIO_PIN0_PAD_PULL_LSB) & WLAN_GPIO_PIN0_PAD_PULL_MASK)
-#define WLAN_GPIO_PIN0_PAD_STRENGTH_MSB          4
-#define WLAN_GPIO_PIN0_PAD_STRENGTH_LSB          3
-#define WLAN_GPIO_PIN0_PAD_STRENGTH_MASK         0x00000018
-#define WLAN_GPIO_PIN0_PAD_STRENGTH_GET(x)       (((x) & WLAN_GPIO_PIN0_PAD_STRENGTH_MASK) >> WLAN_GPIO_PIN0_PAD_STRENGTH_LSB)
-#define WLAN_GPIO_PIN0_PAD_STRENGTH_SET(x)       (((x) << WLAN_GPIO_PIN0_PAD_STRENGTH_LSB) & WLAN_GPIO_PIN0_PAD_STRENGTH_MASK)
-#define WLAN_GPIO_PIN0_PAD_DRIVER_MSB            2
-#define WLAN_GPIO_PIN0_PAD_DRIVER_LSB            2
-#define WLAN_GPIO_PIN0_PAD_DRIVER_MASK           0x00000004
-#define WLAN_GPIO_PIN0_PAD_DRIVER_GET(x)         (((x) & WLAN_GPIO_PIN0_PAD_DRIVER_MASK) >> WLAN_GPIO_PIN0_PAD_DRIVER_LSB)
-#define WLAN_GPIO_PIN0_PAD_DRIVER_SET(x)         (((x) << WLAN_GPIO_PIN0_PAD_DRIVER_LSB) & WLAN_GPIO_PIN0_PAD_DRIVER_MASK)
-#define WLAN_GPIO_PIN0_SOURCE_MSB                0
-#define WLAN_GPIO_PIN0_SOURCE_LSB                0
-#define WLAN_GPIO_PIN0_SOURCE_MASK               0x00000001
-#define WLAN_GPIO_PIN0_SOURCE_GET(x)             (((x) & WLAN_GPIO_PIN0_SOURCE_MASK) >> WLAN_GPIO_PIN0_SOURCE_LSB)
-#define WLAN_GPIO_PIN0_SOURCE_SET(x)             (((x) << WLAN_GPIO_PIN0_SOURCE_LSB) & WLAN_GPIO_PIN0_SOURCE_MASK)
-
-#define WLAN_GPIO_PIN1_ADDRESS                   0x0000002c
-#define WLAN_GPIO_PIN1_OFFSET                    0x0000002c
-#define WLAN_GPIO_PIN1_CONFIG_MSB                13
-#define WLAN_GPIO_PIN1_CONFIG_LSB                11
-#define WLAN_GPIO_PIN1_CONFIG_MASK               0x00003800
-#define WLAN_GPIO_PIN1_CONFIG_GET(x)             (((x) & WLAN_GPIO_PIN1_CONFIG_MASK) >> WLAN_GPIO_PIN1_CONFIG_LSB)
-#define WLAN_GPIO_PIN1_CONFIG_SET(x)             (((x) << WLAN_GPIO_PIN1_CONFIG_LSB) & WLAN_GPIO_PIN1_CONFIG_MASK)
-#define WLAN_GPIO_PIN1_WAKEUP_ENABLE_MSB         10
-#define WLAN_GPIO_PIN1_WAKEUP_ENABLE_LSB         10
-#define WLAN_GPIO_PIN1_WAKEUP_ENABLE_MASK        0x00000400
-#define WLAN_GPIO_PIN1_WAKEUP_ENABLE_GET(x)      (((x) & WLAN_GPIO_PIN1_WAKEUP_ENABLE_MASK) >> WLAN_GPIO_PIN1_WAKEUP_ENABLE_LSB)
-#define WLAN_GPIO_PIN1_WAKEUP_ENABLE_SET(x)      (((x) << WLAN_GPIO_PIN1_WAKEUP_ENABLE_LSB) & WLAN_GPIO_PIN1_WAKEUP_ENABLE_MASK)
-#define WLAN_GPIO_PIN1_INT_TYPE_MSB              9
-#define WLAN_GPIO_PIN1_INT_TYPE_LSB              7
-#define WLAN_GPIO_PIN1_INT_TYPE_MASK             0x00000380
-#define WLAN_GPIO_PIN1_INT_TYPE_GET(x)           (((x) & WLAN_GPIO_PIN1_INT_TYPE_MASK) >> WLAN_GPIO_PIN1_INT_TYPE_LSB)
-#define WLAN_GPIO_PIN1_INT_TYPE_SET(x)           (((x) << WLAN_GPIO_PIN1_INT_TYPE_LSB) & WLAN_GPIO_PIN1_INT_TYPE_MASK)
-#define WLAN_GPIO_PIN1_PAD_PULL_MSB              6
-#define WLAN_GPIO_PIN1_PAD_PULL_LSB              5
-#define WLAN_GPIO_PIN1_PAD_PULL_MASK             0x00000060
-#define WLAN_GPIO_PIN1_PAD_PULL_GET(x)           (((x) & WLAN_GPIO_PIN1_PAD_PULL_MASK) >> WLAN_GPIO_PIN1_PAD_PULL_LSB)
-#define WLAN_GPIO_PIN1_PAD_PULL_SET(x)           (((x) << WLAN_GPIO_PIN1_PAD_PULL_LSB) & WLAN_GPIO_PIN1_PAD_PULL_MASK)
-#define WLAN_GPIO_PIN1_PAD_STRENGTH_MSB          4
-#define WLAN_GPIO_PIN1_PAD_STRENGTH_LSB          3
-#define WLAN_GPIO_PIN1_PAD_STRENGTH_MASK         0x00000018
-#define WLAN_GPIO_PIN1_PAD_STRENGTH_GET(x)       (((x) & WLAN_GPIO_PIN1_PAD_STRENGTH_MASK) >> WLAN_GPIO_PIN1_PAD_STRENGTH_LSB)
-#define WLAN_GPIO_PIN1_PAD_STRENGTH_SET(x)       (((x) << WLAN_GPIO_PIN1_PAD_STRENGTH_LSB) & WLAN_GPIO_PIN1_PAD_STRENGTH_MASK)
-#define WLAN_GPIO_PIN1_PAD_DRIVER_MSB            2
-#define WLAN_GPIO_PIN1_PAD_DRIVER_LSB            2
-#define WLAN_GPIO_PIN1_PAD_DRIVER_MASK           0x00000004
-#define WLAN_GPIO_PIN1_PAD_DRIVER_GET(x)         (((x) & WLAN_GPIO_PIN1_PAD_DRIVER_MASK) >> WLAN_GPIO_PIN1_PAD_DRIVER_LSB)
-#define WLAN_GPIO_PIN1_PAD_DRIVER_SET(x)         (((x) << WLAN_GPIO_PIN1_PAD_DRIVER_LSB) & WLAN_GPIO_PIN1_PAD_DRIVER_MASK)
-#define WLAN_GPIO_PIN1_SOURCE_MSB                0
-#define WLAN_GPIO_PIN1_SOURCE_LSB                0
-#define WLAN_GPIO_PIN1_SOURCE_MASK               0x00000001
-#define WLAN_GPIO_PIN1_SOURCE_GET(x)             (((x) & WLAN_GPIO_PIN1_SOURCE_MASK) >> WLAN_GPIO_PIN1_SOURCE_LSB)
-#define WLAN_GPIO_PIN1_SOURCE_SET(x)             (((x) << WLAN_GPIO_PIN1_SOURCE_LSB) & WLAN_GPIO_PIN1_SOURCE_MASK)
-
-#define WLAN_GPIO_PIN2_ADDRESS                   0x00000030
-#define WLAN_GPIO_PIN2_OFFSET                    0x00000030
-#define WLAN_GPIO_PIN2_CONFIG_MSB                13
-#define WLAN_GPIO_PIN2_CONFIG_LSB                11
-#define WLAN_GPIO_PIN2_CONFIG_MASK               0x00003800
-#define WLAN_GPIO_PIN2_CONFIG_GET(x)             (((x) & WLAN_GPIO_PIN2_CONFIG_MASK) >> WLAN_GPIO_PIN2_CONFIG_LSB)
-#define WLAN_GPIO_PIN2_CONFIG_SET(x)             (((x) << WLAN_GPIO_PIN2_CONFIG_LSB) & WLAN_GPIO_PIN2_CONFIG_MASK)
-#define WLAN_GPIO_PIN2_WAKEUP_ENABLE_MSB         10
-#define WLAN_GPIO_PIN2_WAKEUP_ENABLE_LSB         10
-#define WLAN_GPIO_PIN2_WAKEUP_ENABLE_MASK        0x00000400
-#define WLAN_GPIO_PIN2_WAKEUP_ENABLE_GET(x)      (((x) & WLAN_GPIO_PIN2_WAKEUP_ENABLE_MASK) >> WLAN_GPIO_PIN2_WAKEUP_ENABLE_LSB)
-#define WLAN_GPIO_PIN2_WAKEUP_ENABLE_SET(x)      (((x) << WLAN_GPIO_PIN2_WAKEUP_ENABLE_LSB) & WLAN_GPIO_PIN2_WAKEUP_ENABLE_MASK)
-#define WLAN_GPIO_PIN2_INT_TYPE_MSB              9
-#define WLAN_GPIO_PIN2_INT_TYPE_LSB              7
-#define WLAN_GPIO_PIN2_INT_TYPE_MASK             0x00000380
-#define WLAN_GPIO_PIN2_INT_TYPE_GET(x)           (((x) & WLAN_GPIO_PIN2_INT_TYPE_MASK) >> WLAN_GPIO_PIN2_INT_TYPE_LSB)
-#define WLAN_GPIO_PIN2_INT_TYPE_SET(x)           (((x) << WLAN_GPIO_PIN2_INT_TYPE_LSB) & WLAN_GPIO_PIN2_INT_TYPE_MASK)
-#define WLAN_GPIO_PIN2_PAD_PULL_MSB              6
-#define WLAN_GPIO_PIN2_PAD_PULL_LSB              5
-#define WLAN_GPIO_PIN2_PAD_PULL_MASK             0x00000060
-#define WLAN_GPIO_PIN2_PAD_PULL_GET(x)           (((x) & WLAN_GPIO_PIN2_PAD_PULL_MASK) >> WLAN_GPIO_PIN2_PAD_PULL_LSB)
-#define WLAN_GPIO_PIN2_PAD_PULL_SET(x)           (((x) << WLAN_GPIO_PIN2_PAD_PULL_LSB) & WLAN_GPIO_PIN2_PAD_PULL_MASK)
-#define WLAN_GPIO_PIN2_PAD_STRENGTH_MSB          4
-#define WLAN_GPIO_PIN2_PAD_STRENGTH_LSB          3
-#define WLAN_GPIO_PIN2_PAD_STRENGTH_MASK         0x00000018
-#define WLAN_GPIO_PIN2_PAD_STRENGTH_GET(x)       (((x) & WLAN_GPIO_PIN2_PAD_STRENGTH_MASK) >> WLAN_GPIO_PIN2_PAD_STRENGTH_LSB)
-#define WLAN_GPIO_PIN2_PAD_STRENGTH_SET(x)       (((x) << WLAN_GPIO_PIN2_PAD_STRENGTH_LSB) & WLAN_GPIO_PIN2_PAD_STRENGTH_MASK)
-#define WLAN_GPIO_PIN2_PAD_DRIVER_MSB            2
-#define WLAN_GPIO_PIN2_PAD_DRIVER_LSB            2
-#define WLAN_GPIO_PIN2_PAD_DRIVER_MASK           0x00000004
-#define WLAN_GPIO_PIN2_PAD_DRIVER_GET(x)         (((x) & WLAN_GPIO_PIN2_PAD_DRIVER_MASK) >> WLAN_GPIO_PIN2_PAD_DRIVER_LSB)
-#define WLAN_GPIO_PIN2_PAD_DRIVER_SET(x)         (((x) << WLAN_GPIO_PIN2_PAD_DRIVER_LSB) & WLAN_GPIO_PIN2_PAD_DRIVER_MASK)
-#define WLAN_GPIO_PIN2_SOURCE_MSB                0
-#define WLAN_GPIO_PIN2_SOURCE_LSB                0
-#define WLAN_GPIO_PIN2_SOURCE_MASK               0x00000001
-#define WLAN_GPIO_PIN2_SOURCE_GET(x)             (((x) & WLAN_GPIO_PIN2_SOURCE_MASK) >> WLAN_GPIO_PIN2_SOURCE_LSB)
-#define WLAN_GPIO_PIN2_SOURCE_SET(x)             (((x) << WLAN_GPIO_PIN2_SOURCE_LSB) & WLAN_GPIO_PIN2_SOURCE_MASK)
-
-#define WLAN_GPIO_PIN3_ADDRESS                   0x00000034
-#define WLAN_GPIO_PIN3_OFFSET                    0x00000034
-#define WLAN_GPIO_PIN3_CONFIG_MSB                13
-#define WLAN_GPIO_PIN3_CONFIG_LSB                11
-#define WLAN_GPIO_PIN3_CONFIG_MASK               0x00003800
-#define WLAN_GPIO_PIN3_CONFIG_GET(x)             (((x) & WLAN_GPIO_PIN3_CONFIG_MASK) >> WLAN_GPIO_PIN3_CONFIG_LSB)
-#define WLAN_GPIO_PIN3_CONFIG_SET(x)             (((x) << WLAN_GPIO_PIN3_CONFIG_LSB) & WLAN_GPIO_PIN3_CONFIG_MASK)
-#define WLAN_GPIO_PIN3_WAKEUP_ENABLE_MSB         10
-#define WLAN_GPIO_PIN3_WAKEUP_ENABLE_LSB         10
-#define WLAN_GPIO_PIN3_WAKEUP_ENABLE_MASK        0x00000400
-#define WLAN_GPIO_PIN3_WAKEUP_ENABLE_GET(x)      (((x) & WLAN_GPIO_PIN3_WAKEUP_ENABLE_MASK) >> WLAN_GPIO_PIN3_WAKEUP_ENABLE_LSB)
-#define WLAN_GPIO_PIN3_WAKEUP_ENABLE_SET(x)      (((x) << WLAN_GPIO_PIN3_WAKEUP_ENABLE_LSB) & WLAN_GPIO_PIN3_WAKEUP_ENABLE_MASK)
-#define WLAN_GPIO_PIN3_INT_TYPE_MSB              9
-#define WLAN_GPIO_PIN3_INT_TYPE_LSB              7
-#define WLAN_GPIO_PIN3_INT_TYPE_MASK             0x00000380
-#define WLAN_GPIO_PIN3_INT_TYPE_GET(x)           (((x) & WLAN_GPIO_PIN3_INT_TYPE_MASK) >> WLAN_GPIO_PIN3_INT_TYPE_LSB)
-#define WLAN_GPIO_PIN3_INT_TYPE_SET(x)           (((x) << WLAN_GPIO_PIN3_INT_TYPE_LSB) & WLAN_GPIO_PIN3_INT_TYPE_MASK)
-#define WLAN_GPIO_PIN3_PAD_PULL_MSB              6
-#define WLAN_GPIO_PIN3_PAD_PULL_LSB              5
-#define WLAN_GPIO_PIN3_PAD_PULL_MASK             0x00000060
-#define WLAN_GPIO_PIN3_PAD_PULL_GET(x)           (((x) & WLAN_GPIO_PIN3_PAD_PULL_MASK) >> WLAN_GPIO_PIN3_PAD_PULL_LSB)
-#define WLAN_GPIO_PIN3_PAD_PULL_SET(x)           (((x) << WLAN_GPIO_PIN3_PAD_PULL_LSB) & WLAN_GPIO_PIN3_PAD_PULL_MASK)
-#define WLAN_GPIO_PIN3_PAD_STRENGTH_MSB          4
-#define WLAN_GPIO_PIN3_PAD_STRENGTH_LSB          3
-#define WLAN_GPIO_PIN3_PAD_STRENGTH_MASK         0x00000018
-#define WLAN_GPIO_PIN3_PAD_STRENGTH_GET(x)       (((x) & WLAN_GPIO_PIN3_PAD_STRENGTH_MASK) >> WLAN_GPIO_PIN3_PAD_STRENGTH_LSB)
-#define WLAN_GPIO_PIN3_PAD_STRENGTH_SET(x)       (((x) << WLAN_GPIO_PIN3_PAD_STRENGTH_LSB) & WLAN_GPIO_PIN3_PAD_STRENGTH_MASK)
-#define WLAN_GPIO_PIN3_PAD_DRIVER_MSB            2
-#define WLAN_GPIO_PIN3_PAD_DRIVER_LSB            2
-#define WLAN_GPIO_PIN3_PAD_DRIVER_MASK           0x00000004
-#define WLAN_GPIO_PIN3_PAD_DRIVER_GET(x)         (((x) & WLAN_GPIO_PIN3_PAD_DRIVER_MASK) >> WLAN_GPIO_PIN3_PAD_DRIVER_LSB)
-#define WLAN_GPIO_PIN3_PAD_DRIVER_SET(x)         (((x) << WLAN_GPIO_PIN3_PAD_DRIVER_LSB) & WLAN_GPIO_PIN3_PAD_DRIVER_MASK)
-#define WLAN_GPIO_PIN3_SOURCE_MSB                0
-#define WLAN_GPIO_PIN3_SOURCE_LSB                0
-#define WLAN_GPIO_PIN3_SOURCE_MASK               0x00000001
-#define WLAN_GPIO_PIN3_SOURCE_GET(x)             (((x) & WLAN_GPIO_PIN3_SOURCE_MASK) >> WLAN_GPIO_PIN3_SOURCE_LSB)
-#define WLAN_GPIO_PIN3_SOURCE_SET(x)             (((x) << WLAN_GPIO_PIN3_SOURCE_LSB) & WLAN_GPIO_PIN3_SOURCE_MASK)
-
-#define WLAN_GPIO_PIN4_ADDRESS                   0x00000038
-#define WLAN_GPIO_PIN4_OFFSET                    0x00000038
-#define WLAN_GPIO_PIN4_CONFIG_MSB                13
-#define WLAN_GPIO_PIN4_CONFIG_LSB                11
-#define WLAN_GPIO_PIN4_CONFIG_MASK               0x00003800
-#define WLAN_GPIO_PIN4_CONFIG_GET(x)             (((x) & WLAN_GPIO_PIN4_CONFIG_MASK) >> WLAN_GPIO_PIN4_CONFIG_LSB)
-#define WLAN_GPIO_PIN4_CONFIG_SET(x)             (((x) << WLAN_GPIO_PIN4_CONFIG_LSB) & WLAN_GPIO_PIN4_CONFIG_MASK)
-#define WLAN_GPIO_PIN4_WAKEUP_ENABLE_MSB         10
-#define WLAN_GPIO_PIN4_WAKEUP_ENABLE_LSB         10
-#define WLAN_GPIO_PIN4_WAKEUP_ENABLE_MASK        0x00000400
-#define WLAN_GPIO_PIN4_WAKEUP_ENABLE_GET(x)      (((x) & WLAN_GPIO_PIN4_WAKEUP_ENABLE_MASK) >> WLAN_GPIO_PIN4_WAKEUP_ENABLE_LSB)
-#define WLAN_GPIO_PIN4_WAKEUP_ENABLE_SET(x)      (((x) << WLAN_GPIO_PIN4_WAKEUP_ENABLE_LSB) & WLAN_GPIO_PIN4_WAKEUP_ENABLE_MASK)
-#define WLAN_GPIO_PIN4_INT_TYPE_MSB              9
-#define WLAN_GPIO_PIN4_INT_TYPE_LSB              7
-#define WLAN_GPIO_PIN4_INT_TYPE_MASK             0x00000380
-#define WLAN_GPIO_PIN4_INT_TYPE_GET(x)           (((x) & WLAN_GPIO_PIN4_INT_TYPE_MASK) >> WLAN_GPIO_PIN4_INT_TYPE_LSB)
-#define WLAN_GPIO_PIN4_INT_TYPE_SET(x)           (((x) << WLAN_GPIO_PIN4_INT_TYPE_LSB) & WLAN_GPIO_PIN4_INT_TYPE_MASK)
-#define WLAN_GPIO_PIN4_PAD_PULL_MSB              6
-#define WLAN_GPIO_PIN4_PAD_PULL_LSB              5
-#define WLAN_GPIO_PIN4_PAD_PULL_MASK             0x00000060
-#define WLAN_GPIO_PIN4_PAD_PULL_GET(x)           (((x) & WLAN_GPIO_PIN4_PAD_PULL_MASK) >> WLAN_GPIO_PIN4_PAD_PULL_LSB)
-#define WLAN_GPIO_PIN4_PAD_PULL_SET(x)           (((x) << WLAN_GPIO_PIN4_PAD_PULL_LSB) & WLAN_GPIO_PIN4_PAD_PULL_MASK)
-#define WLAN_GPIO_PIN4_PAD_STRENGTH_MSB          4
-#define WLAN_GPIO_PIN4_PAD_STRENGTH_LSB          3
-#define WLAN_GPIO_PIN4_PAD_STRENGTH_MASK         0x00000018
-#define WLAN_GPIO_PIN4_PAD_STRENGTH_GET(x)       (((x) & WLAN_GPIO_PIN4_PAD_STRENGTH_MASK) >> WLAN_GPIO_PIN4_PAD_STRENGTH_LSB)
-#define WLAN_GPIO_PIN4_PAD_STRENGTH_SET(x)       (((x) << WLAN_GPIO_PIN4_PAD_STRENGTH_LSB) & WLAN_GPIO_PIN4_PAD_STRENGTH_MASK)
-#define WLAN_GPIO_PIN4_PAD_DRIVER_MSB            2
-#define WLAN_GPIO_PIN4_PAD_DRIVER_LSB            2
-#define WLAN_GPIO_PIN4_PAD_DRIVER_MASK           0x00000004
-#define WLAN_GPIO_PIN4_PAD_DRIVER_GET(x)         (((x) & WLAN_GPIO_PIN4_PAD_DRIVER_MASK) >> WLAN_GPIO_PIN4_PAD_DRIVER_LSB)
-#define WLAN_GPIO_PIN4_PAD_DRIVER_SET(x)         (((x) << WLAN_GPIO_PIN4_PAD_DRIVER_LSB) & WLAN_GPIO_PIN4_PAD_DRIVER_MASK)
-#define WLAN_GPIO_PIN4_SOURCE_MSB                0
-#define WLAN_GPIO_PIN4_SOURCE_LSB                0
-#define WLAN_GPIO_PIN4_SOURCE_MASK               0x00000001
-#define WLAN_GPIO_PIN4_SOURCE_GET(x)             (((x) & WLAN_GPIO_PIN4_SOURCE_MASK) >> WLAN_GPIO_PIN4_SOURCE_LSB)
-#define WLAN_GPIO_PIN4_SOURCE_SET(x)             (((x) << WLAN_GPIO_PIN4_SOURCE_LSB) & WLAN_GPIO_PIN4_SOURCE_MASK)
-
-#define WLAN_GPIO_PIN5_ADDRESS                   0x0000003c
-#define WLAN_GPIO_PIN5_OFFSET                    0x0000003c
-#define WLAN_GPIO_PIN5_CONFIG_MSB                13
-#define WLAN_GPIO_PIN5_CONFIG_LSB                11
-#define WLAN_GPIO_PIN5_CONFIG_MASK               0x00003800
-#define WLAN_GPIO_PIN5_CONFIG_GET(x)             (((x) & WLAN_GPIO_PIN5_CONFIG_MASK) >> WLAN_GPIO_PIN5_CONFIG_LSB)
-#define WLAN_GPIO_PIN5_CONFIG_SET(x)             (((x) << WLAN_GPIO_PIN5_CONFIG_LSB) & WLAN_GPIO_PIN5_CONFIG_MASK)
-#define WLAN_GPIO_PIN5_WAKEUP_ENABLE_MSB         10
-#define WLAN_GPIO_PIN5_WAKEUP_ENABLE_LSB         10
-#define WLAN_GPIO_PIN5_WAKEUP_ENABLE_MASK        0x00000400
-#define WLAN_GPIO_PIN5_WAKEUP_ENABLE_GET(x)      (((x) & WLAN_GPIO_PIN5_WAKEUP_ENABLE_MASK) >> WLAN_GPIO_PIN5_WAKEUP_ENABLE_LSB)
-#define WLAN_GPIO_PIN5_WAKEUP_ENABLE_SET(x)      (((x) << WLAN_GPIO_PIN5_WAKEUP_ENABLE_LSB) & WLAN_GPIO_PIN5_WAKEUP_ENABLE_MASK)
-#define WLAN_GPIO_PIN5_INT_TYPE_MSB              9
-#define WLAN_GPIO_PIN5_INT_TYPE_LSB              7
-#define WLAN_GPIO_PIN5_INT_TYPE_MASK             0x00000380
-#define WLAN_GPIO_PIN5_INT_TYPE_GET(x)           (((x) & WLAN_GPIO_PIN5_INT_TYPE_MASK) >> WLAN_GPIO_PIN5_INT_TYPE_LSB)
-#define WLAN_GPIO_PIN5_INT_TYPE_SET(x)           (((x) << WLAN_GPIO_PIN5_INT_TYPE_LSB) & WLAN_GPIO_PIN5_INT_TYPE_MASK)
-#define WLAN_GPIO_PIN5_PAD_PULL_MSB              6
-#define WLAN_GPIO_PIN5_PAD_PULL_LSB              5
-#define WLAN_GPIO_PIN5_PAD_PULL_MASK             0x00000060
-#define WLAN_GPIO_PIN5_PAD_PULL_GET(x)           (((x) & WLAN_GPIO_PIN5_PAD_PULL_MASK) >> WLAN_GPIO_PIN5_PAD_PULL_LSB)
-#define WLAN_GPIO_PIN5_PAD_PULL_SET(x)           (((x) << WLAN_GPIO_PIN5_PAD_PULL_LSB) & WLAN_GPIO_PIN5_PAD_PULL_MASK)
-#define WLAN_GPIO_PIN5_PAD_STRENGTH_MSB          4
-#define WLAN_GPIO_PIN5_PAD_STRENGTH_LSB          3
-#define WLAN_GPIO_PIN5_PAD_STRENGTH_MASK         0x00000018
-#define WLAN_GPIO_PIN5_PAD_STRENGTH_GET(x)       (((x) & WLAN_GPIO_PIN5_PAD_STRENGTH_MASK) >> WLAN_GPIO_PIN5_PAD_STRENGTH_LSB)
-#define WLAN_GPIO_PIN5_PAD_STRENGTH_SET(x)       (((x) << WLAN_GPIO_PIN5_PAD_STRENGTH_LSB) & WLAN_GPIO_PIN5_PAD_STRENGTH_MASK)
-#define WLAN_GPIO_PIN5_PAD_DRIVER_MSB            2
-#define WLAN_GPIO_PIN5_PAD_DRIVER_LSB            2
-#define WLAN_GPIO_PIN5_PAD_DRIVER_MASK           0x00000004
-#define WLAN_GPIO_PIN5_PAD_DRIVER_GET(x)         (((x) & WLAN_GPIO_PIN5_PAD_DRIVER_MASK) >> WLAN_GPIO_PIN5_PAD_DRIVER_LSB)
-#define WLAN_GPIO_PIN5_PAD_DRIVER_SET(x)         (((x) << WLAN_GPIO_PIN5_PAD_DRIVER_LSB) & WLAN_GPIO_PIN5_PAD_DRIVER_MASK)
-#define WLAN_GPIO_PIN5_SOURCE_MSB                0
-#define WLAN_GPIO_PIN5_SOURCE_LSB                0
-#define WLAN_GPIO_PIN5_SOURCE_MASK               0x00000001
-#define WLAN_GPIO_PIN5_SOURCE_GET(x)             (((x) & WLAN_GPIO_PIN5_SOURCE_MASK) >> WLAN_GPIO_PIN5_SOURCE_LSB)
-#define WLAN_GPIO_PIN5_SOURCE_SET(x)             (((x) << WLAN_GPIO_PIN5_SOURCE_LSB) & WLAN_GPIO_PIN5_SOURCE_MASK)
-
-#define WLAN_GPIO_PIN6_ADDRESS                   0x00000040
-#define WLAN_GPIO_PIN6_OFFSET                    0x00000040
-#define WLAN_GPIO_PIN6_CONFIG_MSB                13
-#define WLAN_GPIO_PIN6_CONFIG_LSB                11
-#define WLAN_GPIO_PIN6_CONFIG_MASK               0x00003800
-#define WLAN_GPIO_PIN6_CONFIG_GET(x)             (((x) & WLAN_GPIO_PIN6_CONFIG_MASK) >> WLAN_GPIO_PIN6_CONFIG_LSB)
-#define WLAN_GPIO_PIN6_CONFIG_SET(x)             (((x) << WLAN_GPIO_PIN6_CONFIG_LSB) & WLAN_GPIO_PIN6_CONFIG_MASK)
-#define WLAN_GPIO_PIN6_WAKEUP_ENABLE_MSB         10
-#define WLAN_GPIO_PIN6_WAKEUP_ENABLE_LSB         10
-#define WLAN_GPIO_PIN6_WAKEUP_ENABLE_MASK        0x00000400
-#define WLAN_GPIO_PIN6_WAKEUP_ENABLE_GET(x)      (((x) & WLAN_GPIO_PIN6_WAKEUP_ENABLE_MASK) >> WLAN_GPIO_PIN6_WAKEUP_ENABLE_LSB)
-#define WLAN_GPIO_PIN6_WAKEUP_ENABLE_SET(x)      (((x) << WLAN_GPIO_PIN6_WAKEUP_ENABLE_LSB) & WLAN_GPIO_PIN6_WAKEUP_ENABLE_MASK)
-#define WLAN_GPIO_PIN6_INT_TYPE_MSB              9
-#define WLAN_GPIO_PIN6_INT_TYPE_LSB              7
-#define WLAN_GPIO_PIN6_INT_TYPE_MASK             0x00000380
-#define WLAN_GPIO_PIN6_INT_TYPE_GET(x)           (((x) & WLAN_GPIO_PIN6_INT_TYPE_MASK) >> WLAN_GPIO_PIN6_INT_TYPE_LSB)
-#define WLAN_GPIO_PIN6_INT_TYPE_SET(x)           (((x) << WLAN_GPIO_PIN6_INT_TYPE_LSB) & WLAN_GPIO_PIN6_INT_TYPE_MASK)
-#define WLAN_GPIO_PIN6_PAD_PULL_MSB              6
-#define WLAN_GPIO_PIN6_PAD_PULL_LSB              5
-#define WLAN_GPIO_PIN6_PAD_PULL_MASK             0x00000060
-#define WLAN_GPIO_PIN6_PAD_PULL_GET(x)           (((x) & WLAN_GPIO_PIN6_PAD_PULL_MASK) >> WLAN_GPIO_PIN6_PAD_PULL_LSB)
-#define WLAN_GPIO_PIN6_PAD_PULL_SET(x)           (((x) << WLAN_GPIO_PIN6_PAD_PULL_LSB) & WLAN_GPIO_PIN6_PAD_PULL_MASK)
-#define WLAN_GPIO_PIN6_PAD_STRENGTH_MSB          4
-#define WLAN_GPIO_PIN6_PAD_STRENGTH_LSB          3
-#define WLAN_GPIO_PIN6_PAD_STRENGTH_MASK         0x00000018
-#define WLAN_GPIO_PIN6_PAD_STRENGTH_GET(x)       (((x) & WLAN_GPIO_PIN6_PAD_STRENGTH_MASK) >> WLAN_GPIO_PIN6_PAD_STRENGTH_LSB)
-#define WLAN_GPIO_PIN6_PAD_STRENGTH_SET(x)       (((x) << WLAN_GPIO_PIN6_PAD_STRENGTH_LSB) & WLAN_GPIO_PIN6_PAD_STRENGTH_MASK)
-#define WLAN_GPIO_PIN6_PAD_DRIVER_MSB            2
-#define WLAN_GPIO_PIN6_PAD_DRIVER_LSB            2
-#define WLAN_GPIO_PIN6_PAD_DRIVER_MASK           0x00000004
-#define WLAN_GPIO_PIN6_PAD_DRIVER_GET(x)         (((x) & WLAN_GPIO_PIN6_PAD_DRIVER_MASK) >> WLAN_GPIO_PIN6_PAD_DRIVER_LSB)
-#define WLAN_GPIO_PIN6_PAD_DRIVER_SET(x)         (((x) << WLAN_GPIO_PIN6_PAD_DRIVER_LSB) & WLAN_GPIO_PIN6_PAD_DRIVER_MASK)
-#define WLAN_GPIO_PIN6_SOURCE_MSB                0
-#define WLAN_GPIO_PIN6_SOURCE_LSB                0
-#define WLAN_GPIO_PIN6_SOURCE_MASK               0x00000001
-#define WLAN_GPIO_PIN6_SOURCE_GET(x)             (((x) & WLAN_GPIO_PIN6_SOURCE_MASK) >> WLAN_GPIO_PIN6_SOURCE_LSB)
-#define WLAN_GPIO_PIN6_SOURCE_SET(x)             (((x) << WLAN_GPIO_PIN6_SOURCE_LSB) & WLAN_GPIO_PIN6_SOURCE_MASK)
-
-#define WLAN_GPIO_PIN7_ADDRESS                   0x00000044
-#define WLAN_GPIO_PIN7_OFFSET                    0x00000044
-#define WLAN_GPIO_PIN7_CONFIG_MSB                13
-#define WLAN_GPIO_PIN7_CONFIG_LSB                11
-#define WLAN_GPIO_PIN7_CONFIG_MASK               0x00003800
-#define WLAN_GPIO_PIN7_CONFIG_GET(x)             (((x) & WLAN_GPIO_PIN7_CONFIG_MASK) >> WLAN_GPIO_PIN7_CONFIG_LSB)
-#define WLAN_GPIO_PIN7_CONFIG_SET(x)             (((x) << WLAN_GPIO_PIN7_CONFIG_LSB) & WLAN_GPIO_PIN7_CONFIG_MASK)
-#define WLAN_GPIO_PIN7_WAKEUP_ENABLE_MSB         10
-#define WLAN_GPIO_PIN7_WAKEUP_ENABLE_LSB         10
-#define WLAN_GPIO_PIN7_WAKEUP_ENABLE_MASK        0x00000400
-#define WLAN_GPIO_PIN7_WAKEUP_ENABLE_GET(x)      (((x) & WLAN_GPIO_PIN7_WAKEUP_ENABLE_MASK) >> WLAN_GPIO_PIN7_WAKEUP_ENABLE_LSB)
-#define WLAN_GPIO_PIN7_WAKEUP_ENABLE_SET(x)      (((x) << WLAN_GPIO_PIN7_WAKEUP_ENABLE_LSB) & WLAN_GPIO_PIN7_WAKEUP_ENABLE_MASK)
-#define WLAN_GPIO_PIN7_INT_TYPE_MSB              9
-#define WLAN_GPIO_PIN7_INT_TYPE_LSB              7
-#define WLAN_GPIO_PIN7_INT_TYPE_MASK             0x00000380
-#define WLAN_GPIO_PIN7_INT_TYPE_GET(x)           (((x) & WLAN_GPIO_PIN7_INT_TYPE_MASK) >> WLAN_GPIO_PIN7_INT_TYPE_LSB)
-#define WLAN_GPIO_PIN7_INT_TYPE_SET(x)           (((x) << WLAN_GPIO_PIN7_INT_TYPE_LSB) & WLAN_GPIO_PIN7_INT_TYPE_MASK)
-#define WLAN_GPIO_PIN7_PAD_PULL_MSB              6
-#define WLAN_GPIO_PIN7_PAD_PULL_LSB              5
-#define WLAN_GPIO_PIN7_PAD_PULL_MASK             0x00000060
-#define WLAN_GPIO_PIN7_PAD_PULL_GET(x)           (((x) & WLAN_GPIO_PIN7_PAD_PULL_MASK) >> WLAN_GPIO_PIN7_PAD_PULL_LSB)
-#define WLAN_GPIO_PIN7_PAD_PULL_SET(x)           (((x) << WLAN_GPIO_PIN7_PAD_PULL_LSB) & WLAN_GPIO_PIN7_PAD_PULL_MASK)
-#define WLAN_GPIO_PIN7_PAD_STRENGTH_MSB          4
-#define WLAN_GPIO_PIN7_PAD_STRENGTH_LSB          3
-#define WLAN_GPIO_PIN7_PAD_STRENGTH_MASK         0x00000018
-#define WLAN_GPIO_PIN7_PAD_STRENGTH_GET(x)       (((x) & WLAN_GPIO_PIN7_PAD_STRENGTH_MASK) >> WLAN_GPIO_PIN7_PAD_STRENGTH_LSB)
-#define WLAN_GPIO_PIN7_PAD_STRENGTH_SET(x)       (((x) << WLAN_GPIO_PIN7_PAD_STRENGTH_LSB) & WLAN_GPIO_PIN7_PAD_STRENGTH_MASK)
-#define WLAN_GPIO_PIN7_PAD_DRIVER_MSB            2
-#define WLAN_GPIO_PIN7_PAD_DRIVER_LSB            2
-#define WLAN_GPIO_PIN7_PAD_DRIVER_MASK           0x00000004
-#define WLAN_GPIO_PIN7_PAD_DRIVER_GET(x)         (((x) & WLAN_GPIO_PIN7_PAD_DRIVER_MASK) >> WLAN_GPIO_PIN7_PAD_DRIVER_LSB)
-#define WLAN_GPIO_PIN7_PAD_DRIVER_SET(x)         (((x) << WLAN_GPIO_PIN7_PAD_DRIVER_LSB) & WLAN_GPIO_PIN7_PAD_DRIVER_MASK)
-#define WLAN_GPIO_PIN7_SOURCE_MSB                0
-#define WLAN_GPIO_PIN7_SOURCE_LSB                0
-#define WLAN_GPIO_PIN7_SOURCE_MASK               0x00000001
-#define WLAN_GPIO_PIN7_SOURCE_GET(x)             (((x) & WLAN_GPIO_PIN7_SOURCE_MASK) >> WLAN_GPIO_PIN7_SOURCE_LSB)
-#define WLAN_GPIO_PIN7_SOURCE_SET(x)             (((x) << WLAN_GPIO_PIN7_SOURCE_LSB) & WLAN_GPIO_PIN7_SOURCE_MASK)
-
-#define WLAN_GPIO_PIN8_ADDRESS                   0x00000048
-#define WLAN_GPIO_PIN8_OFFSET                    0x00000048
-#define WLAN_GPIO_PIN8_CONFIG_MSB                13
-#define WLAN_GPIO_PIN8_CONFIG_LSB                11
-#define WLAN_GPIO_PIN8_CONFIG_MASK               0x00003800
-#define WLAN_GPIO_PIN8_CONFIG_GET(x)             (((x) & WLAN_GPIO_PIN8_CONFIG_MASK) >> WLAN_GPIO_PIN8_CONFIG_LSB)
-#define WLAN_GPIO_PIN8_CONFIG_SET(x)             (((x) << WLAN_GPIO_PIN8_CONFIG_LSB) & WLAN_GPIO_PIN8_CONFIG_MASK)
-#define WLAN_GPIO_PIN8_WAKEUP_ENABLE_MSB         10
-#define WLAN_GPIO_PIN8_WAKEUP_ENABLE_LSB         10
-#define WLAN_GPIO_PIN8_WAKEUP_ENABLE_MASK        0x00000400
-#define WLAN_GPIO_PIN8_WAKEUP_ENABLE_GET(x)      (((x) & WLAN_GPIO_PIN8_WAKEUP_ENABLE_MASK) >> WLAN_GPIO_PIN8_WAKEUP_ENABLE_LSB)
-#define WLAN_GPIO_PIN8_WAKEUP_ENABLE_SET(x)      (((x) << WLAN_GPIO_PIN8_WAKEUP_ENABLE_LSB) & WLAN_GPIO_PIN8_WAKEUP_ENABLE_MASK)
-#define WLAN_GPIO_PIN8_INT_TYPE_MSB              9
-#define WLAN_GPIO_PIN8_INT_TYPE_LSB              7
-#define WLAN_GPIO_PIN8_INT_TYPE_MASK             0x00000380
-#define WLAN_GPIO_PIN8_INT_TYPE_GET(x)           (((x) & WLAN_GPIO_PIN8_INT_TYPE_MASK) >> WLAN_GPIO_PIN8_INT_TYPE_LSB)
-#define WLAN_GPIO_PIN8_INT_TYPE_SET(x)           (((x) << WLAN_GPIO_PIN8_INT_TYPE_LSB) & WLAN_GPIO_PIN8_INT_TYPE_MASK)
-#define WLAN_GPIO_PIN8_PAD_PULL_MSB              6
-#define WLAN_GPIO_PIN8_PAD_PULL_LSB              5
-#define WLAN_GPIO_PIN8_PAD_PULL_MASK             0x00000060
-#define WLAN_GPIO_PIN8_PAD_PULL_GET(x)           (((x) & WLAN_GPIO_PIN8_PAD_PULL_MASK) >> WLAN_GPIO_PIN8_PAD_PULL_LSB)
-#define WLAN_GPIO_PIN8_PAD_PULL_SET(x)           (((x) << WLAN_GPIO_PIN8_PAD_PULL_LSB) & WLAN_GPIO_PIN8_PAD_PULL_MASK)
-#define WLAN_GPIO_PIN8_PAD_STRENGTH_MSB          4
-#define WLAN_GPIO_PIN8_PAD_STRENGTH_LSB          3
-#define WLAN_GPIO_PIN8_PAD_STRENGTH_MASK         0x00000018
-#define WLAN_GPIO_PIN8_PAD_STRENGTH_GET(x)       (((x) & WLAN_GPIO_PIN8_PAD_STRENGTH_MASK) >> WLAN_GPIO_PIN8_PAD_STRENGTH_LSB)
-#define WLAN_GPIO_PIN8_PAD_STRENGTH_SET(x)       (((x) << WLAN_GPIO_PIN8_PAD_STRENGTH_LSB) & WLAN_GPIO_PIN8_PAD_STRENGTH_MASK)
-#define WLAN_GPIO_PIN8_PAD_DRIVER_MSB            2
-#define WLAN_GPIO_PIN8_PAD_DRIVER_LSB            2
-#define WLAN_GPIO_PIN8_PAD_DRIVER_MASK           0x00000004
-#define WLAN_GPIO_PIN8_PAD_DRIVER_GET(x)         (((x) & WLAN_GPIO_PIN8_PAD_DRIVER_MASK) >> WLAN_GPIO_PIN8_PAD_DRIVER_LSB)
-#define WLAN_GPIO_PIN8_PAD_DRIVER_SET(x)         (((x) << WLAN_GPIO_PIN8_PAD_DRIVER_LSB) & WLAN_GPIO_PIN8_PAD_DRIVER_MASK)
-#define WLAN_GPIO_PIN8_SOURCE_MSB                0
-#define WLAN_GPIO_PIN8_SOURCE_LSB                0
-#define WLAN_GPIO_PIN8_SOURCE_MASK               0x00000001
-#define WLAN_GPIO_PIN8_SOURCE_GET(x)             (((x) & WLAN_GPIO_PIN8_SOURCE_MASK) >> WLAN_GPIO_PIN8_SOURCE_LSB)
-#define WLAN_GPIO_PIN8_SOURCE_SET(x)             (((x) << WLAN_GPIO_PIN8_SOURCE_LSB) & WLAN_GPIO_PIN8_SOURCE_MASK)
-
-#define WLAN_GPIO_PIN9_ADDRESS                   0x0000004c
-#define WLAN_GPIO_PIN9_OFFSET                    0x0000004c
-#define WLAN_GPIO_PIN9_CONFIG_MSB                13
-#define WLAN_GPIO_PIN9_CONFIG_LSB                11
-#define WLAN_GPIO_PIN9_CONFIG_MASK               0x00003800
-#define WLAN_GPIO_PIN9_CONFIG_GET(x)             (((x) & WLAN_GPIO_PIN9_CONFIG_MASK) >> WLAN_GPIO_PIN9_CONFIG_LSB)
-#define WLAN_GPIO_PIN9_CONFIG_SET(x)             (((x) << WLAN_GPIO_PIN9_CONFIG_LSB) & WLAN_GPIO_PIN9_CONFIG_MASK)
-#define WLAN_GPIO_PIN9_WAKEUP_ENABLE_MSB         10
-#define WLAN_GPIO_PIN9_WAKEUP_ENABLE_LSB         10
-#define WLAN_GPIO_PIN9_WAKEUP_ENABLE_MASK        0x00000400
-#define WLAN_GPIO_PIN9_WAKEUP_ENABLE_GET(x)      (((x) & WLAN_GPIO_PIN9_WAKEUP_ENABLE_MASK) >> WLAN_GPIO_PIN9_WAKEUP_ENABLE_LSB)
-#define WLAN_GPIO_PIN9_WAKEUP_ENABLE_SET(x)      (((x) << WLAN_GPIO_PIN9_WAKEUP_ENABLE_LSB) & WLAN_GPIO_PIN9_WAKEUP_ENABLE_MASK)
-#define WLAN_GPIO_PIN9_INT_TYPE_MSB              9
-#define WLAN_GPIO_PIN9_INT_TYPE_LSB              7
-#define WLAN_GPIO_PIN9_INT_TYPE_MASK             0x00000380
-#define WLAN_GPIO_PIN9_INT_TYPE_GET(x)           (((x) & WLAN_GPIO_PIN9_INT_TYPE_MASK) >> WLAN_GPIO_PIN9_INT_TYPE_LSB)
-#define WLAN_GPIO_PIN9_INT_TYPE_SET(x)           (((x) << WLAN_GPIO_PIN9_INT_TYPE_LSB) & WLAN_GPIO_PIN9_INT_TYPE_MASK)
-#define WLAN_GPIO_PIN9_PAD_PULL_MSB              6
-#define WLAN_GPIO_PIN9_PAD_PULL_LSB              5
-#define WLAN_GPIO_PIN9_PAD_PULL_MASK             0x00000060
-#define WLAN_GPIO_PIN9_PAD_PULL_GET(x)           (((x) & WLAN_GPIO_PIN9_PAD_PULL_MASK) >> WLAN_GPIO_PIN9_PAD_PULL_LSB)
-#define WLAN_GPIO_PIN9_PAD_PULL_SET(x)           (((x) << WLAN_GPIO_PIN9_PAD_PULL_LSB) & WLAN_GPIO_PIN9_PAD_PULL_MASK)
-#define WLAN_GPIO_PIN9_PAD_STRENGTH_MSB          4
-#define WLAN_GPIO_PIN9_PAD_STRENGTH_LSB          3
-#define WLAN_GPIO_PIN9_PAD_STRENGTH_MASK         0x00000018
-#define WLAN_GPIO_PIN9_PAD_STRENGTH_GET(x)       (((x) & WLAN_GPIO_PIN9_PAD_STRENGTH_MASK) >> WLAN_GPIO_PIN9_PAD_STRENGTH_LSB)
-#define WLAN_GPIO_PIN9_PAD_STRENGTH_SET(x)       (((x) << WLAN_GPIO_PIN9_PAD_STRENGTH_LSB) & WLAN_GPIO_PIN9_PAD_STRENGTH_MASK)
-#define WLAN_GPIO_PIN9_PAD_DRIVER_MSB            2
-#define WLAN_GPIO_PIN9_PAD_DRIVER_LSB            2
-#define WLAN_GPIO_PIN9_PAD_DRIVER_MASK           0x00000004
-#define WLAN_GPIO_PIN9_PAD_DRIVER_GET(x)         (((x) & WLAN_GPIO_PIN9_PAD_DRIVER_MASK) >> WLAN_GPIO_PIN9_PAD_DRIVER_LSB)
-#define WLAN_GPIO_PIN9_PAD_DRIVER_SET(x)         (((x) << WLAN_GPIO_PIN9_PAD_DRIVER_LSB) & WLAN_GPIO_PIN9_PAD_DRIVER_MASK)
-#define WLAN_GPIO_PIN9_SOURCE_MSB                0
-#define WLAN_GPIO_PIN9_SOURCE_LSB                0
-#define WLAN_GPIO_PIN9_SOURCE_MASK               0x00000001
-#define WLAN_GPIO_PIN9_SOURCE_GET(x)             (((x) & WLAN_GPIO_PIN9_SOURCE_MASK) >> WLAN_GPIO_PIN9_SOURCE_LSB)
-#define WLAN_GPIO_PIN9_SOURCE_SET(x)             (((x) << WLAN_GPIO_PIN9_SOURCE_LSB) & WLAN_GPIO_PIN9_SOURCE_MASK)
-
-#define WLAN_GPIO_PIN10_ADDRESS                  0x00000050
-#define WLAN_GPIO_PIN10_OFFSET                   0x00000050
-#define WLAN_GPIO_PIN10_CONFIG_MSB               13
-#define WLAN_GPIO_PIN10_CONFIG_LSB               11
-#define WLAN_GPIO_PIN10_CONFIG_MASK              0x00003800
-#define WLAN_GPIO_PIN10_CONFIG_GET(x)            (((x) & WLAN_GPIO_PIN10_CONFIG_MASK) >> WLAN_GPIO_PIN10_CONFIG_LSB)
-#define WLAN_GPIO_PIN10_CONFIG_SET(x)            (((x) << WLAN_GPIO_PIN10_CONFIG_LSB) & WLAN_GPIO_PIN10_CONFIG_MASK)
-#define WLAN_GPIO_PIN10_WAKEUP_ENABLE_MSB        10
-#define WLAN_GPIO_PIN10_WAKEUP_ENABLE_LSB        10
-#define WLAN_GPIO_PIN10_WAKEUP_ENABLE_MASK       0x00000400
-#define WLAN_GPIO_PIN10_WAKEUP_ENABLE_GET(x)     (((x) & WLAN_GPIO_PIN10_WAKEUP_ENABLE_MASK) >> WLAN_GPIO_PIN10_WAKEUP_ENABLE_LSB)
-#define WLAN_GPIO_PIN10_WAKEUP_ENABLE_SET(x)     (((x) << WLAN_GPIO_PIN10_WAKEUP_ENABLE_LSB) & WLAN_GPIO_PIN10_WAKEUP_ENABLE_MASK)
-#define WLAN_GPIO_PIN10_INT_TYPE_MSB             9
-#define WLAN_GPIO_PIN10_INT_TYPE_LSB             7
-#define WLAN_GPIO_PIN10_INT_TYPE_MASK            0x00000380
-#define WLAN_GPIO_PIN10_INT_TYPE_GET(x)          (((x) & WLAN_GPIO_PIN10_INT_TYPE_MASK) >> WLAN_GPIO_PIN10_INT_TYPE_LSB)
-#define WLAN_GPIO_PIN10_INT_TYPE_SET(x)          (((x) << WLAN_GPIO_PIN10_INT_TYPE_LSB) & WLAN_GPIO_PIN10_INT_TYPE_MASK)
-#define WLAN_GPIO_PIN10_PAD_PULL_MSB             6
-#define WLAN_GPIO_PIN10_PAD_PULL_LSB             5
-#define WLAN_GPIO_PIN10_PAD_PULL_MASK            0x00000060
-#define WLAN_GPIO_PIN10_PAD_PULL_GET(x)          (((x) & WLAN_GPIO_PIN10_PAD_PULL_MASK) >> WLAN_GPIO_PIN10_PAD_PULL_LSB)
-#define WLAN_GPIO_PIN10_PAD_PULL_SET(x)          (((x) << WLAN_GPIO_PIN10_PAD_PULL_LSB) & WLAN_GPIO_PIN10_PAD_PULL_MASK)
-#define WLAN_GPIO_PIN10_PAD_STRENGTH_MSB         4
-#define WLAN_GPIO_PIN10_PAD_STRENGTH_LSB         3
-#define WLAN_GPIO_PIN10_PAD_STRENGTH_MASK        0x00000018
-#define WLAN_GPIO_PIN10_PAD_STRENGTH_GET(x)      (((x) & WLAN_GPIO_PIN10_PAD_STRENGTH_MASK) >> WLAN_GPIO_PIN10_PAD_STRENGTH_LSB)
-#define WLAN_GPIO_PIN10_PAD_STRENGTH_SET(x)      (((x) << WLAN_GPIO_PIN10_PAD_STRENGTH_LSB) & WLAN_GPIO_PIN10_PAD_STRENGTH_MASK)
-#define WLAN_GPIO_PIN10_PAD_DRIVER_MSB           2
-#define WLAN_GPIO_PIN10_PAD_DRIVER_LSB           2
-#define WLAN_GPIO_PIN10_PAD_DRIVER_MASK          0x00000004
-#define WLAN_GPIO_PIN10_PAD_DRIVER_GET(x)        (((x) & WLAN_GPIO_PIN10_PAD_DRIVER_MASK) >> WLAN_GPIO_PIN10_PAD_DRIVER_LSB)
-#define WLAN_GPIO_PIN10_PAD_DRIVER_SET(x)        (((x) << WLAN_GPIO_PIN10_PAD_DRIVER_LSB) & WLAN_GPIO_PIN10_PAD_DRIVER_MASK)
-#define WLAN_GPIO_PIN10_SOURCE_MSB               0
-#define WLAN_GPIO_PIN10_SOURCE_LSB               0
-#define WLAN_GPIO_PIN10_SOURCE_MASK              0x00000001
-#define WLAN_GPIO_PIN10_SOURCE_GET(x)            (((x) & WLAN_GPIO_PIN10_SOURCE_MASK) >> WLAN_GPIO_PIN10_SOURCE_LSB)
-#define WLAN_GPIO_PIN10_SOURCE_SET(x)            (((x) << WLAN_GPIO_PIN10_SOURCE_LSB) & WLAN_GPIO_PIN10_SOURCE_MASK)
-
-#define WLAN_GPIO_PIN11_ADDRESS                  0x00000054
-#define WLAN_GPIO_PIN11_OFFSET                   0x00000054
-#define WLAN_GPIO_PIN11_CONFIG_MSB               13
-#define WLAN_GPIO_PIN11_CONFIG_LSB               11
-#define WLAN_GPIO_PIN11_CONFIG_MASK              0x00003800
-#define WLAN_GPIO_PIN11_CONFIG_GET(x)            (((x) & WLAN_GPIO_PIN11_CONFIG_MASK) >> WLAN_GPIO_PIN11_CONFIG_LSB)
-#define WLAN_GPIO_PIN11_CONFIG_SET(x)            (((x) << WLAN_GPIO_PIN11_CONFIG_LSB) & WLAN_GPIO_PIN11_CONFIG_MASK)
-#define WLAN_GPIO_PIN11_WAKEUP_ENABLE_MSB        10
-#define WLAN_GPIO_PIN11_WAKEUP_ENABLE_LSB        10
-#define WLAN_GPIO_PIN11_WAKEUP_ENABLE_MASK       0x00000400
-#define WLAN_GPIO_PIN11_WAKEUP_ENABLE_GET(x)     (((x) & WLAN_GPIO_PIN11_WAKEUP_ENABLE_MASK) >> WLAN_GPIO_PIN11_WAKEUP_ENABLE_LSB)
-#define WLAN_GPIO_PIN11_WAKEUP_ENABLE_SET(x)     (((x) << WLAN_GPIO_PIN11_WAKEUP_ENABLE_LSB) & WLAN_GPIO_PIN11_WAKEUP_ENABLE_MASK)
-#define WLAN_GPIO_PIN11_INT_TYPE_MSB             9
-#define WLAN_GPIO_PIN11_INT_TYPE_LSB             7
-#define WLAN_GPIO_PIN11_INT_TYPE_MASK            0x00000380
-#define WLAN_GPIO_PIN11_INT_TYPE_GET(x)          (((x) & WLAN_GPIO_PIN11_INT_TYPE_MASK) >> WLAN_GPIO_PIN11_INT_TYPE_LSB)
-#define WLAN_GPIO_PIN11_INT_TYPE_SET(x)          (((x) << WLAN_GPIO_PIN11_INT_TYPE_LSB) & WLAN_GPIO_PIN11_INT_TYPE_MASK)
-#define WLAN_GPIO_PIN11_PAD_PULL_MSB             6
-#define WLAN_GPIO_PIN11_PAD_PULL_LSB             5
-#define WLAN_GPIO_PIN11_PAD_PULL_MASK            0x00000060
-#define WLAN_GPIO_PIN11_PAD_PULL_GET(x)          (((x) & WLAN_GPIO_PIN11_PAD_PULL_MASK) >> WLAN_GPIO_PIN11_PAD_PULL_LSB)
-#define WLAN_GPIO_PIN11_PAD_PULL_SET(x)          (((x) << WLAN_GPIO_PIN11_PAD_PULL_LSB) & WLAN_GPIO_PIN11_PAD_PULL_MASK)
-#define WLAN_GPIO_PIN11_PAD_STRENGTH_MSB         4
-#define WLAN_GPIO_PIN11_PAD_STRENGTH_LSB         3
-#define WLAN_GPIO_PIN11_PAD_STRENGTH_MASK        0x00000018
-#define WLAN_GPIO_PIN11_PAD_STRENGTH_GET(x)      (((x) & WLAN_GPIO_PIN11_PAD_STRENGTH_MASK) >> WLAN_GPIO_PIN11_PAD_STRENGTH_LSB)
-#define WLAN_GPIO_PIN11_PAD_STRENGTH_SET(x)      (((x) << WLAN_GPIO_PIN11_PAD_STRENGTH_LSB) & WLAN_GPIO_PIN11_PAD_STRENGTH_MASK)
-#define WLAN_GPIO_PIN11_PAD_DRIVER_MSB           2
-#define WLAN_GPIO_PIN11_PAD_DRIVER_LSB           2
-#define WLAN_GPIO_PIN11_PAD_DRIVER_MASK          0x00000004
-#define WLAN_GPIO_PIN11_PAD_DRIVER_GET(x)        (((x) & WLAN_GPIO_PIN11_PAD_DRIVER_MASK) >> WLAN_GPIO_PIN11_PAD_DRIVER_LSB)
-#define WLAN_GPIO_PIN11_PAD_DRIVER_SET(x)        (((x) << WLAN_GPIO_PIN11_PAD_DRIVER_LSB) & WLAN_GPIO_PIN11_PAD_DRIVER_MASK)
-#define WLAN_GPIO_PIN11_SOURCE_MSB               0
-#define WLAN_GPIO_PIN11_SOURCE_LSB               0
-#define WLAN_GPIO_PIN11_SOURCE_MASK              0x00000001
-#define WLAN_GPIO_PIN11_SOURCE_GET(x)            (((x) & WLAN_GPIO_PIN11_SOURCE_MASK) >> WLAN_GPIO_PIN11_SOURCE_LSB)
-#define WLAN_GPIO_PIN11_SOURCE_SET(x)            (((x) << WLAN_GPIO_PIN11_SOURCE_LSB) & WLAN_GPIO_PIN11_SOURCE_MASK)
-
-#define WLAN_GPIO_PIN12_ADDRESS                  0x00000058
-#define WLAN_GPIO_PIN12_OFFSET                   0x00000058
-#define WLAN_GPIO_PIN12_CONFIG_MSB               13
-#define WLAN_GPIO_PIN12_CONFIG_LSB               11
-#define WLAN_GPIO_PIN12_CONFIG_MASK              0x00003800
-#define WLAN_GPIO_PIN12_CONFIG_GET(x)            (((x) & WLAN_GPIO_PIN12_CONFIG_MASK) >> WLAN_GPIO_PIN12_CONFIG_LSB)
-#define WLAN_GPIO_PIN12_CONFIG_SET(x)            (((x) << WLAN_GPIO_PIN12_CONFIG_LSB) & WLAN_GPIO_PIN12_CONFIG_MASK)
-#define WLAN_GPIO_PIN12_WAKEUP_ENABLE_MSB        10
-#define WLAN_GPIO_PIN12_WAKEUP_ENABLE_LSB        10
-#define WLAN_GPIO_PIN12_WAKEUP_ENABLE_MASK       0x00000400
-#define WLAN_GPIO_PIN12_WAKEUP_ENABLE_GET(x)     (((x) & WLAN_GPIO_PIN12_WAKEUP_ENABLE_MASK) >> WLAN_GPIO_PIN12_WAKEUP_ENABLE_LSB)
-#define WLAN_GPIO_PIN12_WAKEUP_ENABLE_SET(x)     (((x) << WLAN_GPIO_PIN12_WAKEUP_ENABLE_LSB) & WLAN_GPIO_PIN12_WAKEUP_ENABLE_MASK)
-#define WLAN_GPIO_PIN12_INT_TYPE_MSB             9
-#define WLAN_GPIO_PIN12_INT_TYPE_LSB             7
-#define WLAN_GPIO_PIN12_INT_TYPE_MASK            0x00000380
-#define WLAN_GPIO_PIN12_INT_TYPE_GET(x)          (((x) & WLAN_GPIO_PIN12_INT_TYPE_MASK) >> WLAN_GPIO_PIN12_INT_TYPE_LSB)
-#define WLAN_GPIO_PIN12_INT_TYPE_SET(x)          (((x) << WLAN_GPIO_PIN12_INT_TYPE_LSB) & WLAN_GPIO_PIN12_INT_TYPE_MASK)
-#define WLAN_GPIO_PIN12_PAD_PULL_MSB             6
-#define WLAN_GPIO_PIN12_PAD_PULL_LSB             5
-#define WLAN_GPIO_PIN12_PAD_PULL_MASK            0x00000060
-#define WLAN_GPIO_PIN12_PAD_PULL_GET(x)          (((x) & WLAN_GPIO_PIN12_PAD_PULL_MASK) >> WLAN_GPIO_PIN12_PAD_PULL_LSB)
-#define WLAN_GPIO_PIN12_PAD_PULL_SET(x)          (((x) << WLAN_GPIO_PIN12_PAD_PULL_LSB) & WLAN_GPIO_PIN12_PAD_PULL_MASK)
-#define WLAN_GPIO_PIN12_PAD_STRENGTH_MSB         4
-#define WLAN_GPIO_PIN12_PAD_STRENGTH_LSB         3
-#define WLAN_GPIO_PIN12_PAD_STRENGTH_MASK        0x00000018
-#define WLAN_GPIO_PIN12_PAD_STRENGTH_GET(x)      (((x) & WLAN_GPIO_PIN12_PAD_STRENGTH_MASK) >> WLAN_GPIO_PIN12_PAD_STRENGTH_LSB)
-#define WLAN_GPIO_PIN12_PAD_STRENGTH_SET(x)      (((x) << WLAN_GPIO_PIN12_PAD_STRENGTH_LSB) & WLAN_GPIO_PIN12_PAD_STRENGTH_MASK)
-#define WLAN_GPIO_PIN12_PAD_DRIVER_MSB           2
-#define WLAN_GPIO_PIN12_PAD_DRIVER_LSB           2
-#define WLAN_GPIO_PIN12_PAD_DRIVER_MASK          0x00000004
-#define WLAN_GPIO_PIN12_PAD_DRIVER_GET(x)        (((x) & WLAN_GPIO_PIN12_PAD_DRIVER_MASK) >> WLAN_GPIO_PIN12_PAD_DRIVER_LSB)
-#define WLAN_GPIO_PIN12_PAD_DRIVER_SET(x)        (((x) << WLAN_GPIO_PIN12_PAD_DRIVER_LSB) & WLAN_GPIO_PIN12_PAD_DRIVER_MASK)
-#define WLAN_GPIO_PIN12_SOURCE_MSB               0
-#define WLAN_GPIO_PIN12_SOURCE_LSB               0
-#define WLAN_GPIO_PIN12_SOURCE_MASK              0x00000001
-#define WLAN_GPIO_PIN12_SOURCE_GET(x)            (((x) & WLAN_GPIO_PIN12_SOURCE_MASK) >> WLAN_GPIO_PIN12_SOURCE_LSB)
-#define WLAN_GPIO_PIN12_SOURCE_SET(x)            (((x) << WLAN_GPIO_PIN12_SOURCE_LSB) & WLAN_GPIO_PIN12_SOURCE_MASK)
-
-#define WLAN_GPIO_PIN13_ADDRESS                  0x0000005c
-#define WLAN_GPIO_PIN13_OFFSET                   0x0000005c
-#define WLAN_GPIO_PIN13_CONFIG_MSB               13
-#define WLAN_GPIO_PIN13_CONFIG_LSB               11
-#define WLAN_GPIO_PIN13_CONFIG_MASK              0x00003800
-#define WLAN_GPIO_PIN13_CONFIG_GET(x)            (((x) & WLAN_GPIO_PIN13_CONFIG_MASK) >> WLAN_GPIO_PIN13_CONFIG_LSB)
-#define WLAN_GPIO_PIN13_CONFIG_SET(x)            (((x) << WLAN_GPIO_PIN13_CONFIG_LSB) & WLAN_GPIO_PIN13_CONFIG_MASK)
-#define WLAN_GPIO_PIN13_WAKEUP_ENABLE_MSB        10
-#define WLAN_GPIO_PIN13_WAKEUP_ENABLE_LSB        10
-#define WLAN_GPIO_PIN13_WAKEUP_ENABLE_MASK       0x00000400
-#define WLAN_GPIO_PIN13_WAKEUP_ENABLE_GET(x)     (((x) & WLAN_GPIO_PIN13_WAKEUP_ENABLE_MASK) >> WLAN_GPIO_PIN13_WAKEUP_ENABLE_LSB)
-#define WLAN_GPIO_PIN13_WAKEUP_ENABLE_SET(x)     (((x) << WLAN_GPIO_PIN13_WAKEUP_ENABLE_LSB) & WLAN_GPIO_PIN13_WAKEUP_ENABLE_MASK)
-#define WLAN_GPIO_PIN13_INT_TYPE_MSB             9
-#define WLAN_GPIO_PIN13_INT_TYPE_LSB             7
-#define WLAN_GPIO_PIN13_INT_TYPE_MASK            0x00000380
-#define WLAN_GPIO_PIN13_INT_TYPE_GET(x)          (((x) & WLAN_GPIO_PIN13_INT_TYPE_MASK) >> WLAN_GPIO_PIN13_INT_TYPE_LSB)
-#define WLAN_GPIO_PIN13_INT_TYPE_SET(x)          (((x) << WLAN_GPIO_PIN13_INT_TYPE_LSB) & WLAN_GPIO_PIN13_INT_TYPE_MASK)
-#define WLAN_GPIO_PIN13_PAD_PULL_MSB             6
-#define WLAN_GPIO_PIN13_PAD_PULL_LSB             5
-#define WLAN_GPIO_PIN13_PAD_PULL_MASK            0x00000060
-#define WLAN_GPIO_PIN13_PAD_PULL_GET(x)          (((x) & WLAN_GPIO_PIN13_PAD_PULL_MASK) >> WLAN_GPIO_PIN13_PAD_PULL_LSB)
-#define WLAN_GPIO_PIN13_PAD_PULL_SET(x)          (((x) << WLAN_GPIO_PIN13_PAD_PULL_LSB) & WLAN_GPIO_PIN13_PAD_PULL_MASK)
-#define WLAN_GPIO_PIN13_PAD_STRENGTH_MSB         4
-#define WLAN_GPIO_PIN13_PAD_STRENGTH_LSB         3
-#define WLAN_GPIO_PIN13_PAD_STRENGTH_MASK        0x00000018
-#define WLAN_GPIO_PIN13_PAD_STRENGTH_GET(x)      (((x) & WLAN_GPIO_PIN13_PAD_STRENGTH_MASK) >> WLAN_GPIO_PIN13_PAD_STRENGTH_LSB)
-#define WLAN_GPIO_PIN13_PAD_STRENGTH_SET(x)      (((x) << WLAN_GPIO_PIN13_PAD_STRENGTH_LSB) & WLAN_GPIO_PIN13_PAD_STRENGTH_MASK)
-#define WLAN_GPIO_PIN13_PAD_DRIVER_MSB           2
-#define WLAN_GPIO_PIN13_PAD_DRIVER_LSB           2
-#define WLAN_GPIO_PIN13_PAD_DRIVER_MASK          0x00000004
-#define WLAN_GPIO_PIN13_PAD_DRIVER_GET(x)        (((x) & WLAN_GPIO_PIN13_PAD_DRIVER_MASK) >> WLAN_GPIO_PIN13_PAD_DRIVER_LSB)
-#define WLAN_GPIO_PIN13_PAD_DRIVER_SET(x)        (((x) << WLAN_GPIO_PIN13_PAD_DRIVER_LSB) & WLAN_GPIO_PIN13_PAD_DRIVER_MASK)
-#define WLAN_GPIO_PIN13_SOURCE_MSB               0
-#define WLAN_GPIO_PIN13_SOURCE_LSB               0
-#define WLAN_GPIO_PIN13_SOURCE_MASK              0x00000001
-#define WLAN_GPIO_PIN13_SOURCE_GET(x)            (((x) & WLAN_GPIO_PIN13_SOURCE_MASK) >> WLAN_GPIO_PIN13_SOURCE_LSB)
-#define WLAN_GPIO_PIN13_SOURCE_SET(x)            (((x) << WLAN_GPIO_PIN13_SOURCE_LSB) & WLAN_GPIO_PIN13_SOURCE_MASK)
-
-#define WLAN_GPIO_PIN14_ADDRESS                  0x00000060
-#define WLAN_GPIO_PIN14_OFFSET                   0x00000060
-#define WLAN_GPIO_PIN14_CONFIG_MSB               13
-#define WLAN_GPIO_PIN14_CONFIG_LSB               11
-#define WLAN_GPIO_PIN14_CONFIG_MASK              0x00003800
-#define WLAN_GPIO_PIN14_CONFIG_GET(x)            (((x) & WLAN_GPIO_PIN14_CONFIG_MASK) >> WLAN_GPIO_PIN14_CONFIG_LSB)
-#define WLAN_GPIO_PIN14_CONFIG_SET(x)            (((x) << WLAN_GPIO_PIN14_CONFIG_LSB) & WLAN_GPIO_PIN14_CONFIG_MASK)
-#define WLAN_GPIO_PIN14_WAKEUP_ENABLE_MSB        10
-#define WLAN_GPIO_PIN14_WAKEUP_ENABLE_LSB        10
-#define WLAN_GPIO_PIN14_WAKEUP_ENABLE_MASK       0x00000400
-#define WLAN_GPIO_PIN14_WAKEUP_ENABLE_GET(x)     (((x) & WLAN_GPIO_PIN14_WAKEUP_ENABLE_MASK) >> WLAN_GPIO_PIN14_WAKEUP_ENABLE_LSB)
-#define WLAN_GPIO_PIN14_WAKEUP_ENABLE_SET(x)     (((x) << WLAN_GPIO_PIN14_WAKEUP_ENABLE_LSB) & WLAN_GPIO_PIN14_WAKEUP_ENABLE_MASK)
-#define WLAN_GPIO_PIN14_INT_TYPE_MSB             9
-#define WLAN_GPIO_PIN14_INT_TYPE_LSB             7
-#define WLAN_GPIO_PIN14_INT_TYPE_MASK            0x00000380
-#define WLAN_GPIO_PIN14_INT_TYPE_GET(x)          (((x) & WLAN_GPIO_PIN14_INT_TYPE_MASK) >> WLAN_GPIO_PIN14_INT_TYPE_LSB)
-#define WLAN_GPIO_PIN14_INT_TYPE_SET(x)          (((x) << WLAN_GPIO_PIN14_INT_TYPE_LSB) & WLAN_GPIO_PIN14_INT_TYPE_MASK)
-#define WLAN_GPIO_PIN14_PAD_PULL_MSB             6
-#define WLAN_GPIO_PIN14_PAD_PULL_LSB             5
-#define WLAN_GPIO_PIN14_PAD_PULL_MASK            0x00000060
-#define WLAN_GPIO_PIN14_PAD_PULL_GET(x)          (((x) & WLAN_GPIO_PIN14_PAD_PULL_MASK) >> WLAN_GPIO_PIN14_PAD_PULL_LSB)
-#define WLAN_GPIO_PIN14_PAD_PULL_SET(x)          (((x) << WLAN_GPIO_PIN14_PAD_PULL_LSB) & WLAN_GPIO_PIN14_PAD_PULL_MASK)
-#define WLAN_GPIO_PIN14_PAD_STRENGTH_MSB         4
-#define WLAN_GPIO_PIN14_PAD_STRENGTH_LSB         3
-#define WLAN_GPIO_PIN14_PAD_STRENGTH_MASK        0x00000018
-#define WLAN_GPIO_PIN14_PAD_STRENGTH_GET(x)      (((x) & WLAN_GPIO_PIN14_PAD_STRENGTH_MASK) >> WLAN_GPIO_PIN14_PAD_STRENGTH_LSB)
-#define WLAN_GPIO_PIN14_PAD_STRENGTH_SET(x)      (((x) << WLAN_GPIO_PIN14_PAD_STRENGTH_LSB) & WLAN_GPIO_PIN14_PAD_STRENGTH_MASK)
-#define WLAN_GPIO_PIN14_PAD_DRIVER_MSB           2
-#define WLAN_GPIO_PIN14_PAD_DRIVER_LSB           2
-#define WLAN_GPIO_PIN14_PAD_DRIVER_MASK          0x00000004
-#define WLAN_GPIO_PIN14_PAD_DRIVER_GET(x)        (((x) & WLAN_GPIO_PIN14_PAD_DRIVER_MASK) >> WLAN_GPIO_PIN14_PAD_DRIVER_LSB)
-#define WLAN_GPIO_PIN14_PAD_DRIVER_SET(x)        (((x) << WLAN_GPIO_PIN14_PAD_DRIVER_LSB) & WLAN_GPIO_PIN14_PAD_DRIVER_MASK)
-#define WLAN_GPIO_PIN14_SOURCE_MSB               0
-#define WLAN_GPIO_PIN14_SOURCE_LSB               0
-#define WLAN_GPIO_PIN14_SOURCE_MASK              0x00000001
-#define WLAN_GPIO_PIN14_SOURCE_GET(x)            (((x) & WLAN_GPIO_PIN14_SOURCE_MASK) >> WLAN_GPIO_PIN14_SOURCE_LSB)
-#define WLAN_GPIO_PIN14_SOURCE_SET(x)            (((x) << WLAN_GPIO_PIN14_SOURCE_LSB) & WLAN_GPIO_PIN14_SOURCE_MASK)
-
-#define WLAN_GPIO_PIN15_ADDRESS                  0x00000064
-#define WLAN_GPIO_PIN15_OFFSET                   0x00000064
-#define WLAN_GPIO_PIN15_CONFIG_MSB               13
-#define WLAN_GPIO_PIN15_CONFIG_LSB               11
-#define WLAN_GPIO_PIN15_CONFIG_MASK              0x00003800
-#define WLAN_GPIO_PIN15_CONFIG_GET(x)            (((x) & WLAN_GPIO_PIN15_CONFIG_MASK) >> WLAN_GPIO_PIN15_CONFIG_LSB)
-#define WLAN_GPIO_PIN15_CONFIG_SET(x)            (((x) << WLAN_GPIO_PIN15_CONFIG_LSB) & WLAN_GPIO_PIN15_CONFIG_MASK)
-#define WLAN_GPIO_PIN15_WAKEUP_ENABLE_MSB        10
-#define WLAN_GPIO_PIN15_WAKEUP_ENABLE_LSB        10
-#define WLAN_GPIO_PIN15_WAKEUP_ENABLE_MASK       0x00000400
-#define WLAN_GPIO_PIN15_WAKEUP_ENABLE_GET(x)     (((x) & WLAN_GPIO_PIN15_WAKEUP_ENABLE_MASK) >> WLAN_GPIO_PIN15_WAKEUP_ENABLE_LSB)
-#define WLAN_GPIO_PIN15_WAKEUP_ENABLE_SET(x)     (((x) << WLAN_GPIO_PIN15_WAKEUP_ENABLE_LSB) & WLAN_GPIO_PIN15_WAKEUP_ENABLE_MASK)
-#define WLAN_GPIO_PIN15_INT_TYPE_MSB             9
-#define WLAN_GPIO_PIN15_INT_TYPE_LSB             7
-#define WLAN_GPIO_PIN15_INT_TYPE_MASK            0x00000380
-#define WLAN_GPIO_PIN15_INT_TYPE_GET(x)          (((x) & WLAN_GPIO_PIN15_INT_TYPE_MASK) >> WLAN_GPIO_PIN15_INT_TYPE_LSB)
-#define WLAN_GPIO_PIN15_INT_TYPE_SET(x)          (((x) << WLAN_GPIO_PIN15_INT_TYPE_LSB) & WLAN_GPIO_PIN15_INT_TYPE_MASK)
-#define WLAN_GPIO_PIN15_PAD_PULL_MSB             6
-#define WLAN_GPIO_PIN15_PAD_PULL_LSB             5
-#define WLAN_GPIO_PIN15_PAD_PULL_MASK            0x00000060
-#define WLAN_GPIO_PIN15_PAD_PULL_GET(x)          (((x) & WLAN_GPIO_PIN15_PAD_PULL_MASK) >> WLAN_GPIO_PIN15_PAD_PULL_LSB)
-#define WLAN_GPIO_PIN15_PAD_PULL_SET(x)          (((x) << WLAN_GPIO_PIN15_PAD_PULL_LSB) & WLAN_GPIO_PIN15_PAD_PULL_MASK)
-#define WLAN_GPIO_PIN15_PAD_STRENGTH_MSB         4
-#define WLAN_GPIO_PIN15_PAD_STRENGTH_LSB         3
-#define WLAN_GPIO_PIN15_PAD_STRENGTH_MASK        0x00000018
-#define WLAN_GPIO_PIN15_PAD_STRENGTH_GET(x)      (((x) & WLAN_GPIO_PIN15_PAD_STRENGTH_MASK) >> WLAN_GPIO_PIN15_PAD_STRENGTH_LSB)
-#define WLAN_GPIO_PIN15_PAD_STRENGTH_SET(x)      (((x) << WLAN_GPIO_PIN15_PAD_STRENGTH_LSB) & WLAN_GPIO_PIN15_PAD_STRENGTH_MASK)
-#define WLAN_GPIO_PIN15_PAD_DRIVER_MSB           2
-#define WLAN_GPIO_PIN15_PAD_DRIVER_LSB           2
-#define WLAN_GPIO_PIN15_PAD_DRIVER_MASK          0x00000004
-#define WLAN_GPIO_PIN15_PAD_DRIVER_GET(x)        (((x) & WLAN_GPIO_PIN15_PAD_DRIVER_MASK) >> WLAN_GPIO_PIN15_PAD_DRIVER_LSB)
-#define WLAN_GPIO_PIN15_PAD_DRIVER_SET(x)        (((x) << WLAN_GPIO_PIN15_PAD_DRIVER_LSB) & WLAN_GPIO_PIN15_PAD_DRIVER_MASK)
-#define WLAN_GPIO_PIN15_SOURCE_MSB               0
-#define WLAN_GPIO_PIN15_SOURCE_LSB               0
-#define WLAN_GPIO_PIN15_SOURCE_MASK              0x00000001
-#define WLAN_GPIO_PIN15_SOURCE_GET(x)            (((x) & WLAN_GPIO_PIN15_SOURCE_MASK) >> WLAN_GPIO_PIN15_SOURCE_LSB)
-#define WLAN_GPIO_PIN15_SOURCE_SET(x)            (((x) << WLAN_GPIO_PIN15_SOURCE_LSB) & WLAN_GPIO_PIN15_SOURCE_MASK)
-
-#define WLAN_GPIO_PIN16_ADDRESS                  0x00000068
-#define WLAN_GPIO_PIN16_OFFSET                   0x00000068
-#define WLAN_GPIO_PIN16_CONFIG_MSB               13
-#define WLAN_GPIO_PIN16_CONFIG_LSB               11
-#define WLAN_GPIO_PIN16_CONFIG_MASK              0x00003800
-#define WLAN_GPIO_PIN16_CONFIG_GET(x)            (((x) & WLAN_GPIO_PIN16_CONFIG_MASK) >> WLAN_GPIO_PIN16_CONFIG_LSB)
-#define WLAN_GPIO_PIN16_CONFIG_SET(x)            (((x) << WLAN_GPIO_PIN16_CONFIG_LSB) & WLAN_GPIO_PIN16_CONFIG_MASK)
-#define WLAN_GPIO_PIN16_WAKEUP_ENABLE_MSB        10
-#define WLAN_GPIO_PIN16_WAKEUP_ENABLE_LSB        10
-#define WLAN_GPIO_PIN16_WAKEUP_ENABLE_MASK       0x00000400
-#define WLAN_GPIO_PIN16_WAKEUP_ENABLE_GET(x)     (((x) & WLAN_GPIO_PIN16_WAKEUP_ENABLE_MASK) >> WLAN_GPIO_PIN16_WAKEUP_ENABLE_LSB)
-#define WLAN_GPIO_PIN16_WAKEUP_ENABLE_SET(x)     (((x) << WLAN_GPIO_PIN16_WAKEUP_ENABLE_LSB) & WLAN_GPIO_PIN16_WAKEUP_ENABLE_MASK)
-#define WLAN_GPIO_PIN16_INT_TYPE_MSB             9
-#define WLAN_GPIO_PIN16_INT_TYPE_LSB             7
-#define WLAN_GPIO_PIN16_INT_TYPE_MASK            0x00000380
-#define WLAN_GPIO_PIN16_INT_TYPE_GET(x)          (((x) & WLAN_GPIO_PIN16_INT_TYPE_MASK) >> WLAN_GPIO_PIN16_INT_TYPE_LSB)
-#define WLAN_GPIO_PIN16_INT_TYPE_SET(x)          (((x) << WLAN_GPIO_PIN16_INT_TYPE_LSB) & WLAN_GPIO_PIN16_INT_TYPE_MASK)
-#define WLAN_GPIO_PIN16_PAD_PULL_MSB             6
-#define WLAN_GPIO_PIN16_PAD_PULL_LSB             5
-#define WLAN_GPIO_PIN16_PAD_PULL_MASK            0x00000060
-#define WLAN_GPIO_PIN16_PAD_PULL_GET(x)          (((x) & WLAN_GPIO_PIN16_PAD_PULL_MASK) >> WLAN_GPIO_PIN16_PAD_PULL_LSB)
-#define WLAN_GPIO_PIN16_PAD_PULL_SET(x)          (((x) << WLAN_GPIO_PIN16_PAD_PULL_LSB) & WLAN_GPIO_PIN16_PAD_PULL_MASK)
-#define WLAN_GPIO_PIN16_PAD_STRENGTH_MSB         4
-#define WLAN_GPIO_PIN16_PAD_STRENGTH_LSB         3
-#define WLAN_GPIO_PIN16_PAD_STRENGTH_MASK        0x00000018
-#define WLAN_GPIO_PIN16_PAD_STRENGTH_GET(x)      (((x) & WLAN_GPIO_PIN16_PAD_STRENGTH_MASK) >> WLAN_GPIO_PIN16_PAD_STRENGTH_LSB)
-#define WLAN_GPIO_PIN16_PAD_STRENGTH_SET(x)      (((x) << WLAN_GPIO_PIN16_PAD_STRENGTH_LSB) & WLAN_GPIO_PIN16_PAD_STRENGTH_MASK)
-#define WLAN_GPIO_PIN16_PAD_DRIVER_MSB           2
-#define WLAN_GPIO_PIN16_PAD_DRIVER_LSB           2
-#define WLAN_GPIO_PIN16_PAD_DRIVER_MASK          0x00000004
-#define WLAN_GPIO_PIN16_PAD_DRIVER_GET(x)        (((x) & WLAN_GPIO_PIN16_PAD_DRIVER_MASK) >> WLAN_GPIO_PIN16_PAD_DRIVER_LSB)
-#define WLAN_GPIO_PIN16_PAD_DRIVER_SET(x)        (((x) << WLAN_GPIO_PIN16_PAD_DRIVER_LSB) & WLAN_GPIO_PIN16_PAD_DRIVER_MASK)
-#define WLAN_GPIO_PIN16_SOURCE_MSB               0
-#define WLAN_GPIO_PIN16_SOURCE_LSB               0
-#define WLAN_GPIO_PIN16_SOURCE_MASK              0x00000001
-#define WLAN_GPIO_PIN16_SOURCE_GET(x)            (((x) & WLAN_GPIO_PIN16_SOURCE_MASK) >> WLAN_GPIO_PIN16_SOURCE_LSB)
-#define WLAN_GPIO_PIN16_SOURCE_SET(x)            (((x) << WLAN_GPIO_PIN16_SOURCE_LSB) & WLAN_GPIO_PIN16_SOURCE_MASK)
-
-#define WLAN_GPIO_PIN17_ADDRESS                  0x0000006c
-#define WLAN_GPIO_PIN17_OFFSET                   0x0000006c
-#define WLAN_GPIO_PIN17_CONFIG_MSB               13
-#define WLAN_GPIO_PIN17_CONFIG_LSB               11
-#define WLAN_GPIO_PIN17_CONFIG_MASK              0x00003800
-#define WLAN_GPIO_PIN17_CONFIG_GET(x)            (((x) & WLAN_GPIO_PIN17_CONFIG_MASK) >> WLAN_GPIO_PIN17_CONFIG_LSB)
-#define WLAN_GPIO_PIN17_CONFIG_SET(x)            (((x) << WLAN_GPIO_PIN17_CONFIG_LSB) & WLAN_GPIO_PIN17_CONFIG_MASK)
-#define WLAN_GPIO_PIN17_WAKEUP_ENABLE_MSB        10
-#define WLAN_GPIO_PIN17_WAKEUP_ENABLE_LSB        10
-#define WLAN_GPIO_PIN17_WAKEUP_ENABLE_MASK       0x00000400
-#define WLAN_GPIO_PIN17_WAKEUP_ENABLE_GET(x)     (((x) & WLAN_GPIO_PIN17_WAKEUP_ENABLE_MASK) >> WLAN_GPIO_PIN17_WAKEUP_ENABLE_LSB)
-#define WLAN_GPIO_PIN17_WAKEUP_ENABLE_SET(x)     (((x) << WLAN_GPIO_PIN17_WAKEUP_ENABLE_LSB) & WLAN_GPIO_PIN17_WAKEUP_ENABLE_MASK)
-#define WLAN_GPIO_PIN17_INT_TYPE_MSB             9
-#define WLAN_GPIO_PIN17_INT_TYPE_LSB             7
-#define WLAN_GPIO_PIN17_INT_TYPE_MASK            0x00000380
-#define WLAN_GPIO_PIN17_INT_TYPE_GET(x)          (((x) & WLAN_GPIO_PIN17_INT_TYPE_MASK) >> WLAN_GPIO_PIN17_INT_TYPE_LSB)
-#define WLAN_GPIO_PIN17_INT_TYPE_SET(x)          (((x) << WLAN_GPIO_PIN17_INT_TYPE_LSB) & WLAN_GPIO_PIN17_INT_TYPE_MASK)
-#define WLAN_GPIO_PIN17_PAD_PULL_MSB             6
-#define WLAN_GPIO_PIN17_PAD_PULL_LSB             5
-#define WLAN_GPIO_PIN17_PAD_PULL_MASK            0x00000060
-#define WLAN_GPIO_PIN17_PAD_PULL_GET(x)          (((x) & WLAN_GPIO_PIN17_PAD_PULL_MASK) >> WLAN_GPIO_PIN17_PAD_PULL_LSB)
-#define WLAN_GPIO_PIN17_PAD_PULL_SET(x)          (((x) << WLAN_GPIO_PIN17_PAD_PULL_LSB) & WLAN_GPIO_PIN17_PAD_PULL_MASK)
-#define WLAN_GPIO_PIN17_PAD_STRENGTH_MSB         4
-#define WLAN_GPIO_PIN17_PAD_STRENGTH_LSB         3
-#define WLAN_GPIO_PIN17_PAD_STRENGTH_MASK        0x00000018
-#define WLAN_GPIO_PIN17_PAD_STRENGTH_GET(x)      (((x) & WLAN_GPIO_PIN17_PAD_STRENGTH_MASK) >> WLAN_GPIO_PIN17_PAD_STRENGTH_LSB)
-#define WLAN_GPIO_PIN17_PAD_STRENGTH_SET(x)      (((x) << WLAN_GPIO_PIN17_PAD_STRENGTH_LSB) & WLAN_GPIO_PIN17_PAD_STRENGTH_MASK)
-#define WLAN_GPIO_PIN17_PAD_DRIVER_MSB           2
-#define WLAN_GPIO_PIN17_PAD_DRIVER_LSB           2
-#define WLAN_GPIO_PIN17_PAD_DRIVER_MASK          0x00000004
-#define WLAN_GPIO_PIN17_PAD_DRIVER_GET(x)        (((x) & WLAN_GPIO_PIN17_PAD_DRIVER_MASK) >> WLAN_GPIO_PIN17_PAD_DRIVER_LSB)
-#define WLAN_GPIO_PIN17_PAD_DRIVER_SET(x)        (((x) << WLAN_GPIO_PIN17_PAD_DRIVER_LSB) & WLAN_GPIO_PIN17_PAD_DRIVER_MASK)
-#define WLAN_GPIO_PIN17_SOURCE_MSB               0
-#define WLAN_GPIO_PIN17_SOURCE_LSB               0
-#define WLAN_GPIO_PIN17_SOURCE_MASK              0x00000001
-#define WLAN_GPIO_PIN17_SOURCE_GET(x)            (((x) & WLAN_GPIO_PIN17_SOURCE_MASK) >> WLAN_GPIO_PIN17_SOURCE_LSB)
-#define WLAN_GPIO_PIN17_SOURCE_SET(x)            (((x) << WLAN_GPIO_PIN17_SOURCE_LSB) & WLAN_GPIO_PIN17_SOURCE_MASK)
-
-#define WLAN_GPIO_PIN18_ADDRESS                  0x00000070
-#define WLAN_GPIO_PIN18_OFFSET                   0x00000070
-#define WLAN_GPIO_PIN18_CONFIG_MSB               13
-#define WLAN_GPIO_PIN18_CONFIG_LSB               11
-#define WLAN_GPIO_PIN18_CONFIG_MASK              0x00003800
-#define WLAN_GPIO_PIN18_CONFIG_GET(x)            (((x) & WLAN_GPIO_PIN18_CONFIG_MASK) >> WLAN_GPIO_PIN18_CONFIG_LSB)
-#define WLAN_GPIO_PIN18_CONFIG_SET(x)            (((x) << WLAN_GPIO_PIN18_CONFIG_LSB) & WLAN_GPIO_PIN18_CONFIG_MASK)
-#define WLAN_GPIO_PIN18_WAKEUP_ENABLE_MSB        10
-#define WLAN_GPIO_PIN18_WAKEUP_ENABLE_LSB        10
-#define WLAN_GPIO_PIN18_WAKEUP_ENABLE_MASK       0x00000400
-#define WLAN_GPIO_PIN18_WAKEUP_ENABLE_GET(x)     (((x) & WLAN_GPIO_PIN18_WAKEUP_ENABLE_MASK) >> WLAN_GPIO_PIN18_WAKEUP_ENABLE_LSB)
-#define WLAN_GPIO_PIN18_WAKEUP_ENABLE_SET(x)     (((x) << WLAN_GPIO_PIN18_WAKEUP_ENABLE_LSB) & WLAN_GPIO_PIN18_WAKEUP_ENABLE_MASK)
-#define WLAN_GPIO_PIN18_INT_TYPE_MSB             9
-#define WLAN_GPIO_PIN18_INT_TYPE_LSB             7
-#define WLAN_GPIO_PIN18_INT_TYPE_MASK            0x00000380
-#define WLAN_GPIO_PIN18_INT_TYPE_GET(x)          (((x) & WLAN_GPIO_PIN18_INT_TYPE_MASK) >> WLAN_GPIO_PIN18_INT_TYPE_LSB)
-#define WLAN_GPIO_PIN18_INT_TYPE_SET(x)          (((x) << WLAN_GPIO_PIN18_INT_TYPE_LSB) & WLAN_GPIO_PIN18_INT_TYPE_MASK)
-#define WLAN_GPIO_PIN18_PAD_PULL_MSB             6
-#define WLAN_GPIO_PIN18_PAD_PULL_LSB             5
-#define WLAN_GPIO_PIN18_PAD_PULL_MASK            0x00000060
-#define WLAN_GPIO_PIN18_PAD_PULL_GET(x)          (((x) & WLAN_GPIO_PIN18_PAD_PULL_MASK) >> WLAN_GPIO_PIN18_PAD_PULL_LSB)
-#define WLAN_GPIO_PIN18_PAD_PULL_SET(x)          (((x) << WLAN_GPIO_PIN18_PAD_PULL_LSB) & WLAN_GPIO_PIN18_PAD_PULL_MASK)
-#define WLAN_GPIO_PIN18_PAD_STRENGTH_MSB         4
-#define WLAN_GPIO_PIN18_PAD_STRENGTH_LSB         3
-#define WLAN_GPIO_PIN18_PAD_STRENGTH_MASK        0x00000018
-#define WLAN_GPIO_PIN18_PAD_STRENGTH_GET(x)      (((x) & WLAN_GPIO_PIN18_PAD_STRENGTH_MASK) >> WLAN_GPIO_PIN18_PAD_STRENGTH_LSB)
-#define WLAN_GPIO_PIN18_PAD_STRENGTH_SET(x)      (((x) << WLAN_GPIO_PIN18_PAD_STRENGTH_LSB) & WLAN_GPIO_PIN18_PAD_STRENGTH_MASK)
-#define WLAN_GPIO_PIN18_PAD_DRIVER_MSB           2
-#define WLAN_GPIO_PIN18_PAD_DRIVER_LSB           2
-#define WLAN_GPIO_PIN18_PAD_DRIVER_MASK          0x00000004
-#define WLAN_GPIO_PIN18_PAD_DRIVER_GET(x)        (((x) & WLAN_GPIO_PIN18_PAD_DRIVER_MASK) >> WLAN_GPIO_PIN18_PAD_DRIVER_LSB)
-#define WLAN_GPIO_PIN18_PAD_DRIVER_SET(x)        (((x) << WLAN_GPIO_PIN18_PAD_DRIVER_LSB) & WLAN_GPIO_PIN18_PAD_DRIVER_MASK)
-#define WLAN_GPIO_PIN18_SOURCE_MSB               0
-#define WLAN_GPIO_PIN18_SOURCE_LSB               0
-#define WLAN_GPIO_PIN18_SOURCE_MASK              0x00000001
-#define WLAN_GPIO_PIN18_SOURCE_GET(x)            (((x) & WLAN_GPIO_PIN18_SOURCE_MASK) >> WLAN_GPIO_PIN18_SOURCE_LSB)
-#define WLAN_GPIO_PIN18_SOURCE_SET(x)            (((x) << WLAN_GPIO_PIN18_SOURCE_LSB) & WLAN_GPIO_PIN18_SOURCE_MASK)
-
-#define WLAN_GPIO_PIN19_ADDRESS                  0x00000074
-#define WLAN_GPIO_PIN19_OFFSET                   0x00000074
-#define WLAN_GPIO_PIN19_CONFIG_MSB               13
-#define WLAN_GPIO_PIN19_CONFIG_LSB               11
-#define WLAN_GPIO_PIN19_CONFIG_MASK              0x00003800
-#define WLAN_GPIO_PIN19_CONFIG_GET(x)            (((x) & WLAN_GPIO_PIN19_CONFIG_MASK) >> WLAN_GPIO_PIN19_CONFIG_LSB)
-#define WLAN_GPIO_PIN19_CONFIG_SET(x)            (((x) << WLAN_GPIO_PIN19_CONFIG_LSB) & WLAN_GPIO_PIN19_CONFIG_MASK)
-#define WLAN_GPIO_PIN19_WAKEUP_ENABLE_MSB        10
-#define WLAN_GPIO_PIN19_WAKEUP_ENABLE_LSB        10
-#define WLAN_GPIO_PIN19_WAKEUP_ENABLE_MASK       0x00000400
-#define WLAN_GPIO_PIN19_WAKEUP_ENABLE_GET(x)     (((x) & WLAN_GPIO_PIN19_WAKEUP_ENABLE_MASK) >> WLAN_GPIO_PIN19_WAKEUP_ENABLE_LSB)
-#define WLAN_GPIO_PIN19_WAKEUP_ENABLE_SET(x)     (((x) << WLAN_GPIO_PIN19_WAKEUP_ENABLE_LSB) & WLAN_GPIO_PIN19_WAKEUP_ENABLE_MASK)
-#define WLAN_GPIO_PIN19_INT_TYPE_MSB             9
-#define WLAN_GPIO_PIN19_INT_TYPE_LSB             7
-#define WLAN_GPIO_PIN19_INT_TYPE_MASK            0x00000380
-#define WLAN_GPIO_PIN19_INT_TYPE_GET(x)          (((x) & WLAN_GPIO_PIN19_INT_TYPE_MASK) >> WLAN_GPIO_PIN19_INT_TYPE_LSB)
-#define WLAN_GPIO_PIN19_INT_TYPE_SET(x)          (((x) << WLAN_GPIO_PIN19_INT_TYPE_LSB) & WLAN_GPIO_PIN19_INT_TYPE_MASK)
-#define WLAN_GPIO_PIN19_PAD_PULL_MSB             6
-#define WLAN_GPIO_PIN19_PAD_PULL_LSB             5
-#define WLAN_GPIO_PIN19_PAD_PULL_MASK            0x00000060
-#define WLAN_GPIO_PIN19_PAD_PULL_GET(x)          (((x) & WLAN_GPIO_PIN19_PAD_PULL_MASK) >> WLAN_GPIO_PIN19_PAD_PULL_LSB)
-#define WLAN_GPIO_PIN19_PAD_PULL_SET(x)          (((x) << WLAN_GPIO_PIN19_PAD_PULL_LSB) & WLAN_GPIO_PIN19_PAD_PULL_MASK)
-#define WLAN_GPIO_PIN19_PAD_STRENGTH_MSB         4
-#define WLAN_GPIO_PIN19_PAD_STRENGTH_LSB         3
-#define WLAN_GPIO_PIN19_PAD_STRENGTH_MASK        0x00000018
-#define WLAN_GPIO_PIN19_PAD_STRENGTH_GET(x)      (((x) & WLAN_GPIO_PIN19_PAD_STRENGTH_MASK) >> WLAN_GPIO_PIN19_PAD_STRENGTH_LSB)
-#define WLAN_GPIO_PIN19_PAD_STRENGTH_SET(x)      (((x) << WLAN_GPIO_PIN19_PAD_STRENGTH_LSB) & WLAN_GPIO_PIN19_PAD_STRENGTH_MASK)
-#define WLAN_GPIO_PIN19_PAD_DRIVER_MSB           2
-#define WLAN_GPIO_PIN19_PAD_DRIVER_LSB           2
-#define WLAN_GPIO_PIN19_PAD_DRIVER_MASK          0x00000004
-#define WLAN_GPIO_PIN19_PAD_DRIVER_GET(x)        (((x) & WLAN_GPIO_PIN19_PAD_DRIVER_MASK) >> WLAN_GPIO_PIN19_PAD_DRIVER_LSB)
-#define WLAN_GPIO_PIN19_PAD_DRIVER_SET(x)        (((x) << WLAN_GPIO_PIN19_PAD_DRIVER_LSB) & WLAN_GPIO_PIN19_PAD_DRIVER_MASK)
-#define WLAN_GPIO_PIN19_SOURCE_MSB               0
-#define WLAN_GPIO_PIN19_SOURCE_LSB               0
-#define WLAN_GPIO_PIN19_SOURCE_MASK              0x00000001
-#define WLAN_GPIO_PIN19_SOURCE_GET(x)            (((x) & WLAN_GPIO_PIN19_SOURCE_MASK) >> WLAN_GPIO_PIN19_SOURCE_LSB)
-#define WLAN_GPIO_PIN19_SOURCE_SET(x)            (((x) << WLAN_GPIO_PIN19_SOURCE_LSB) & WLAN_GPIO_PIN19_SOURCE_MASK)
-
-#define WLAN_GPIO_PIN20_ADDRESS                  0x00000078
-#define WLAN_GPIO_PIN20_OFFSET                   0x00000078
-#define WLAN_GPIO_PIN20_CONFIG_MSB               13
-#define WLAN_GPIO_PIN20_CONFIG_LSB               11
-#define WLAN_GPIO_PIN20_CONFIG_MASK              0x00003800
-#define WLAN_GPIO_PIN20_CONFIG_GET(x)            (((x) & WLAN_GPIO_PIN20_CONFIG_MASK) >> WLAN_GPIO_PIN20_CONFIG_LSB)
-#define WLAN_GPIO_PIN20_CONFIG_SET(x)            (((x) << WLAN_GPIO_PIN20_CONFIG_LSB) & WLAN_GPIO_PIN20_CONFIG_MASK)
-#define WLAN_GPIO_PIN20_WAKEUP_ENABLE_MSB        10
-#define WLAN_GPIO_PIN20_WAKEUP_ENABLE_LSB        10
-#define WLAN_GPIO_PIN20_WAKEUP_ENABLE_MASK       0x00000400
-#define WLAN_GPIO_PIN20_WAKEUP_ENABLE_GET(x)     (((x) & WLAN_GPIO_PIN20_WAKEUP_ENABLE_MASK) >> WLAN_GPIO_PIN20_WAKEUP_ENABLE_LSB)
-#define WLAN_GPIO_PIN20_WAKEUP_ENABLE_SET(x)     (((x) << WLAN_GPIO_PIN20_WAKEUP_ENABLE_LSB) & WLAN_GPIO_PIN20_WAKEUP_ENABLE_MASK)
-#define WLAN_GPIO_PIN20_INT_TYPE_MSB             9
-#define WLAN_GPIO_PIN20_INT_TYPE_LSB             7
-#define WLAN_GPIO_PIN20_INT_TYPE_MASK            0x00000380
-#define WLAN_GPIO_PIN20_INT_TYPE_GET(x)          (((x) & WLAN_GPIO_PIN20_INT_TYPE_MASK) >> WLAN_GPIO_PIN20_INT_TYPE_LSB)
-#define WLAN_GPIO_PIN20_INT_TYPE_SET(x)          (((x) << WLAN_GPIO_PIN20_INT_TYPE_LSB) & WLAN_GPIO_PIN20_INT_TYPE_MASK)
-#define WLAN_GPIO_PIN20_PAD_PULL_MSB             6
-#define WLAN_GPIO_PIN20_PAD_PULL_LSB             5
-#define WLAN_GPIO_PIN20_PAD_PULL_MASK            0x00000060
-#define WLAN_GPIO_PIN20_PAD_PULL_GET(x)          (((x) & WLAN_GPIO_PIN20_PAD_PULL_MASK) >> WLAN_GPIO_PIN20_PAD_PULL_LSB)
-#define WLAN_GPIO_PIN20_PAD_PULL_SET(x)          (((x) << WLAN_GPIO_PIN20_PAD_PULL_LSB) & WLAN_GPIO_PIN20_PAD_PULL_MASK)
-#define WLAN_GPIO_PIN20_PAD_STRENGTH_MSB         4
-#define WLAN_GPIO_PIN20_PAD_STRENGTH_LSB         3
-#define WLAN_GPIO_PIN20_PAD_STRENGTH_MASK        0x00000018
-#define WLAN_GPIO_PIN20_PAD_STRENGTH_GET(x)      (((x) & WLAN_GPIO_PIN20_PAD_STRENGTH_MASK) >> WLAN_GPIO_PIN20_PAD_STRENGTH_LSB)
-#define WLAN_GPIO_PIN20_PAD_STRENGTH_SET(x)      (((x) << WLAN_GPIO_PIN20_PAD_STRENGTH_LSB) & WLAN_GPIO_PIN20_PAD_STRENGTH_MASK)
-#define WLAN_GPIO_PIN20_PAD_DRIVER_MSB           2
-#define WLAN_GPIO_PIN20_PAD_DRIVER_LSB           2
-#define WLAN_GPIO_PIN20_PAD_DRIVER_MASK          0x00000004
-#define WLAN_GPIO_PIN20_PAD_DRIVER_GET(x)        (((x) & WLAN_GPIO_PIN20_PAD_DRIVER_MASK) >> WLAN_GPIO_PIN20_PAD_DRIVER_LSB)
-#define WLAN_GPIO_PIN20_PAD_DRIVER_SET(x)        (((x) << WLAN_GPIO_PIN20_PAD_DRIVER_LSB) & WLAN_GPIO_PIN20_PAD_DRIVER_MASK)
-#define WLAN_GPIO_PIN20_SOURCE_MSB               0
-#define WLAN_GPIO_PIN20_SOURCE_LSB               0
-#define WLAN_GPIO_PIN20_SOURCE_MASK              0x00000001
-#define WLAN_GPIO_PIN20_SOURCE_GET(x)            (((x) & WLAN_GPIO_PIN20_SOURCE_MASK) >> WLAN_GPIO_PIN20_SOURCE_LSB)
-#define WLAN_GPIO_PIN20_SOURCE_SET(x)            (((x) << WLAN_GPIO_PIN20_SOURCE_LSB) & WLAN_GPIO_PIN20_SOURCE_MASK)
-
-#define WLAN_GPIO_PIN21_ADDRESS                  0x0000007c
-#define WLAN_GPIO_PIN21_OFFSET                   0x0000007c
-#define WLAN_GPIO_PIN21_CONFIG_MSB               13
-#define WLAN_GPIO_PIN21_CONFIG_LSB               11
-#define WLAN_GPIO_PIN21_CONFIG_MASK              0x00003800
-#define WLAN_GPIO_PIN21_CONFIG_GET(x)            (((x) & WLAN_GPIO_PIN21_CONFIG_MASK) >> WLAN_GPIO_PIN21_CONFIG_LSB)
-#define WLAN_GPIO_PIN21_CONFIG_SET(x)            (((x) << WLAN_GPIO_PIN21_CONFIG_LSB) & WLAN_GPIO_PIN21_CONFIG_MASK)
-#define WLAN_GPIO_PIN21_WAKEUP_ENABLE_MSB        10
-#define WLAN_GPIO_PIN21_WAKEUP_ENABLE_LSB        10
-#define WLAN_GPIO_PIN21_WAKEUP_ENABLE_MASK       0x00000400
-#define WLAN_GPIO_PIN21_WAKEUP_ENABLE_GET(x)     (((x) & WLAN_GPIO_PIN21_WAKEUP_ENABLE_MASK) >> WLAN_GPIO_PIN21_WAKEUP_ENABLE_LSB)
-#define WLAN_GPIO_PIN21_WAKEUP_ENABLE_SET(x)     (((x) << WLAN_GPIO_PIN21_WAKEUP_ENABLE_LSB) & WLAN_GPIO_PIN21_WAKEUP_ENABLE_MASK)
-#define WLAN_GPIO_PIN21_INT_TYPE_MSB             9
-#define WLAN_GPIO_PIN21_INT_TYPE_LSB             7
-#define WLAN_GPIO_PIN21_INT_TYPE_MASK            0x00000380
-#define WLAN_GPIO_PIN21_INT_TYPE_GET(x)          (((x) & WLAN_GPIO_PIN21_INT_TYPE_MASK) >> WLAN_GPIO_PIN21_INT_TYPE_LSB)
-#define WLAN_GPIO_PIN21_INT_TYPE_SET(x)          (((x) << WLAN_GPIO_PIN21_INT_TYPE_LSB) & WLAN_GPIO_PIN21_INT_TYPE_MASK)
-#define WLAN_GPIO_PIN21_PAD_PULL_MSB             6
-#define WLAN_GPIO_PIN21_PAD_PULL_LSB             5
-#define WLAN_GPIO_PIN21_PAD_PULL_MASK            0x00000060
-#define WLAN_GPIO_PIN21_PAD_PULL_GET(x)          (((x) & WLAN_GPIO_PIN21_PAD_PULL_MASK) >> WLAN_GPIO_PIN21_PAD_PULL_LSB)
-#define WLAN_GPIO_PIN21_PAD_PULL_SET(x)          (((x) << WLAN_GPIO_PIN21_PAD_PULL_LSB) & WLAN_GPIO_PIN21_PAD_PULL_MASK)
-#define WLAN_GPIO_PIN21_PAD_STRENGTH_MSB         4
-#define WLAN_GPIO_PIN21_PAD_STRENGTH_LSB         3
-#define WLAN_GPIO_PIN21_PAD_STRENGTH_MASK        0x00000018
-#define WLAN_GPIO_PIN21_PAD_STRENGTH_GET(x)      (((x) & WLAN_GPIO_PIN21_PAD_STRENGTH_MASK) >> WLAN_GPIO_PIN21_PAD_STRENGTH_LSB)
-#define WLAN_GPIO_PIN21_PAD_STRENGTH_SET(x)      (((x) << WLAN_GPIO_PIN21_PAD_STRENGTH_LSB) & WLAN_GPIO_PIN21_PAD_STRENGTH_MASK)
-#define WLAN_GPIO_PIN21_PAD_DRIVER_MSB           2
-#define WLAN_GPIO_PIN21_PAD_DRIVER_LSB           2
-#define WLAN_GPIO_PIN21_PAD_DRIVER_MASK          0x00000004
-#define WLAN_GPIO_PIN21_PAD_DRIVER_GET(x)        (((x) & WLAN_GPIO_PIN21_PAD_DRIVER_MASK) >> WLAN_GPIO_PIN21_PAD_DRIVER_LSB)
-#define WLAN_GPIO_PIN21_PAD_DRIVER_SET(x)        (((x) << WLAN_GPIO_PIN21_PAD_DRIVER_LSB) & WLAN_GPIO_PIN21_PAD_DRIVER_MASK)
-#define WLAN_GPIO_PIN21_SOURCE_MSB               0
-#define WLAN_GPIO_PIN21_SOURCE_LSB               0
-#define WLAN_GPIO_PIN21_SOURCE_MASK              0x00000001
-#define WLAN_GPIO_PIN21_SOURCE_GET(x)            (((x) & WLAN_GPIO_PIN21_SOURCE_MASK) >> WLAN_GPIO_PIN21_SOURCE_LSB)
-#define WLAN_GPIO_PIN21_SOURCE_SET(x)            (((x) << WLAN_GPIO_PIN21_SOURCE_LSB) & WLAN_GPIO_PIN21_SOURCE_MASK)
-
-#define WLAN_GPIO_PIN22_ADDRESS                  0x00000080
-#define WLAN_GPIO_PIN22_OFFSET                   0x00000080
-#define WLAN_GPIO_PIN22_CONFIG_MSB               13
-#define WLAN_GPIO_PIN22_CONFIG_LSB               11
-#define WLAN_GPIO_PIN22_CONFIG_MASK              0x00003800
-#define WLAN_GPIO_PIN22_CONFIG_GET(x)            (((x) & WLAN_GPIO_PIN22_CONFIG_MASK) >> WLAN_GPIO_PIN22_CONFIG_LSB)
-#define WLAN_GPIO_PIN22_CONFIG_SET(x)            (((x) << WLAN_GPIO_PIN22_CONFIG_LSB) & WLAN_GPIO_PIN22_CONFIG_MASK)
-#define WLAN_GPIO_PIN22_WAKEUP_ENABLE_MSB        10
-#define WLAN_GPIO_PIN22_WAKEUP_ENABLE_LSB        10
-#define WLAN_GPIO_PIN22_WAKEUP_ENABLE_MASK       0x00000400
-#define WLAN_GPIO_PIN22_WAKEUP_ENABLE_GET(x)     (((x) & WLAN_GPIO_PIN22_WAKEUP_ENABLE_MASK) >> WLAN_GPIO_PIN22_WAKEUP_ENABLE_LSB)
-#define WLAN_GPIO_PIN22_WAKEUP_ENABLE_SET(x)     (((x) << WLAN_GPIO_PIN22_WAKEUP_ENABLE_LSB) & WLAN_GPIO_PIN22_WAKEUP_ENABLE_MASK)
-#define WLAN_GPIO_PIN22_INT_TYPE_MSB             9
-#define WLAN_GPIO_PIN22_INT_TYPE_LSB             7
-#define WLAN_GPIO_PIN22_INT_TYPE_MASK            0x00000380
-#define WLAN_GPIO_PIN22_INT_TYPE_GET(x)          (((x) & WLAN_GPIO_PIN22_INT_TYPE_MASK) >> WLAN_GPIO_PIN22_INT_TYPE_LSB)
-#define WLAN_GPIO_PIN22_INT_TYPE_SET(x)          (((x) << WLAN_GPIO_PIN22_INT_TYPE_LSB) & WLAN_GPIO_PIN22_INT_TYPE_MASK)
-#define WLAN_GPIO_PIN22_PAD_PULL_MSB             6
-#define WLAN_GPIO_PIN22_PAD_PULL_LSB             5
-#define WLAN_GPIO_PIN22_PAD_PULL_MASK            0x00000060
-#define WLAN_GPIO_PIN22_PAD_PULL_GET(x)          (((x) & WLAN_GPIO_PIN22_PAD_PULL_MASK) >> WLAN_GPIO_PIN22_PAD_PULL_LSB)
-#define WLAN_GPIO_PIN22_PAD_PULL_SET(x)          (((x) << WLAN_GPIO_PIN22_PAD_PULL_LSB) & WLAN_GPIO_PIN22_PAD_PULL_MASK)
-#define WLAN_GPIO_PIN22_PAD_STRENGTH_MSB         4
-#define WLAN_GPIO_PIN22_PAD_STRENGTH_LSB         3
-#define WLAN_GPIO_PIN22_PAD_STRENGTH_MASK        0x00000018
-#define WLAN_GPIO_PIN22_PAD_STRENGTH_GET(x)      (((x) & WLAN_GPIO_PIN22_PAD_STRENGTH_MASK) >> WLAN_GPIO_PIN22_PAD_STRENGTH_LSB)
-#define WLAN_GPIO_PIN22_PAD_STRENGTH_SET(x)      (((x) << WLAN_GPIO_PIN22_PAD_STRENGTH_LSB) & WLAN_GPIO_PIN22_PAD_STRENGTH_MASK)
-#define WLAN_GPIO_PIN22_PAD_DRIVER_MSB           2
-#define WLAN_GPIO_PIN22_PAD_DRIVER_LSB           2
-#define WLAN_GPIO_PIN22_PAD_DRIVER_MASK          0x00000004
-#define WLAN_GPIO_PIN22_PAD_DRIVER_GET(x)        (((x) & WLAN_GPIO_PIN22_PAD_DRIVER_MASK) >> WLAN_GPIO_PIN22_PAD_DRIVER_LSB)
-#define WLAN_GPIO_PIN22_PAD_DRIVER_SET(x)        (((x) << WLAN_GPIO_PIN22_PAD_DRIVER_LSB) & WLAN_GPIO_PIN22_PAD_DRIVER_MASK)
-#define WLAN_GPIO_PIN22_SOURCE_MSB               0
-#define WLAN_GPIO_PIN22_SOURCE_LSB               0
-#define WLAN_GPIO_PIN22_SOURCE_MASK              0x00000001
-#define WLAN_GPIO_PIN22_SOURCE_GET(x)            (((x) & WLAN_GPIO_PIN22_SOURCE_MASK) >> WLAN_GPIO_PIN22_SOURCE_LSB)
-#define WLAN_GPIO_PIN22_SOURCE_SET(x)            (((x) << WLAN_GPIO_PIN22_SOURCE_LSB) & WLAN_GPIO_PIN22_SOURCE_MASK)
-
-#define WLAN_GPIO_PIN23_ADDRESS                  0x00000084
-#define WLAN_GPIO_PIN23_OFFSET                   0x00000084
-#define WLAN_GPIO_PIN23_CONFIG_MSB               13
-#define WLAN_GPIO_PIN23_CONFIG_LSB               11
-#define WLAN_GPIO_PIN23_CONFIG_MASK              0x00003800
-#define WLAN_GPIO_PIN23_CONFIG_GET(x)            (((x) & WLAN_GPIO_PIN23_CONFIG_MASK) >> WLAN_GPIO_PIN23_CONFIG_LSB)
-#define WLAN_GPIO_PIN23_CONFIG_SET(x)            (((x) << WLAN_GPIO_PIN23_CONFIG_LSB) & WLAN_GPIO_PIN23_CONFIG_MASK)
-#define WLAN_GPIO_PIN23_WAKEUP_ENABLE_MSB        10
-#define WLAN_GPIO_PIN23_WAKEUP_ENABLE_LSB        10
-#define WLAN_GPIO_PIN23_WAKEUP_ENABLE_MASK       0x00000400
-#define WLAN_GPIO_PIN23_WAKEUP_ENABLE_GET(x)     (((x) & WLAN_GPIO_PIN23_WAKEUP_ENABLE_MASK) >> WLAN_GPIO_PIN23_WAKEUP_ENABLE_LSB)
-#define WLAN_GPIO_PIN23_WAKEUP_ENABLE_SET(x)     (((x) << WLAN_GPIO_PIN23_WAKEUP_ENABLE_LSB) & WLAN_GPIO_PIN23_WAKEUP_ENABLE_MASK)
-#define WLAN_GPIO_PIN23_INT_TYPE_MSB             9
-#define WLAN_GPIO_PIN23_INT_TYPE_LSB             7
-#define WLAN_GPIO_PIN23_INT_TYPE_MASK            0x00000380
-#define WLAN_GPIO_PIN23_INT_TYPE_GET(x)          (((x) & WLAN_GPIO_PIN23_INT_TYPE_MASK) >> WLAN_GPIO_PIN23_INT_TYPE_LSB)
-#define WLAN_GPIO_PIN23_INT_TYPE_SET(x)          (((x) << WLAN_GPIO_PIN23_INT_TYPE_LSB) & WLAN_GPIO_PIN23_INT_TYPE_MASK)
-#define WLAN_GPIO_PIN23_PAD_DRIVER_MSB           2
-#define WLAN_GPIO_PIN23_PAD_DRIVER_LSB           2
-#define WLAN_GPIO_PIN23_PAD_DRIVER_MASK          0x00000004
-#define WLAN_GPIO_PIN23_PAD_DRIVER_GET(x)        (((x) & WLAN_GPIO_PIN23_PAD_DRIVER_MASK) >> WLAN_GPIO_PIN23_PAD_DRIVER_LSB)
-#define WLAN_GPIO_PIN23_PAD_DRIVER_SET(x)        (((x) << WLAN_GPIO_PIN23_PAD_DRIVER_LSB) & WLAN_GPIO_PIN23_PAD_DRIVER_MASK)
-#define WLAN_GPIO_PIN23_SOURCE_MSB               0
-#define WLAN_GPIO_PIN23_SOURCE_LSB               0
-#define WLAN_GPIO_PIN23_SOURCE_MASK              0x00000001
-#define WLAN_GPIO_PIN23_SOURCE_GET(x)            (((x) & WLAN_GPIO_PIN23_SOURCE_MASK) >> WLAN_GPIO_PIN23_SOURCE_LSB)
-#define WLAN_GPIO_PIN23_SOURCE_SET(x)            (((x) << WLAN_GPIO_PIN23_SOURCE_LSB) & WLAN_GPIO_PIN23_SOURCE_MASK)
-
-#define WLAN_GPIO_PIN24_ADDRESS                  0x00000088
-#define WLAN_GPIO_PIN24_OFFSET                   0x00000088
-#define WLAN_GPIO_PIN24_CONFIG_MSB               13
-#define WLAN_GPIO_PIN24_CONFIG_LSB               11
-#define WLAN_GPIO_PIN24_CONFIG_MASK              0x00003800
-#define WLAN_GPIO_PIN24_CONFIG_GET(x)            (((x) & WLAN_GPIO_PIN24_CONFIG_MASK) >> WLAN_GPIO_PIN24_CONFIG_LSB)
-#define WLAN_GPIO_PIN24_CONFIG_SET(x)            (((x) << WLAN_GPIO_PIN24_CONFIG_LSB) & WLAN_GPIO_PIN24_CONFIG_MASK)
-#define WLAN_GPIO_PIN24_WAKEUP_ENABLE_MSB        10
-#define WLAN_GPIO_PIN24_WAKEUP_ENABLE_LSB        10
-#define WLAN_GPIO_PIN24_WAKEUP_ENABLE_MASK       0x00000400
-#define WLAN_GPIO_PIN24_WAKEUP_ENABLE_GET(x)     (((x) & WLAN_GPIO_PIN24_WAKEUP_ENABLE_MASK) >> WLAN_GPIO_PIN24_WAKEUP_ENABLE_LSB)
-#define WLAN_GPIO_PIN24_WAKEUP_ENABLE_SET(x)     (((x) << WLAN_GPIO_PIN24_WAKEUP_ENABLE_LSB) & WLAN_GPIO_PIN24_WAKEUP_ENABLE_MASK)
-#define WLAN_GPIO_PIN24_INT_TYPE_MSB             9
-#define WLAN_GPIO_PIN24_INT_TYPE_LSB             7
-#define WLAN_GPIO_PIN24_INT_TYPE_MASK            0x00000380
-#define WLAN_GPIO_PIN24_INT_TYPE_GET(x)          (((x) & WLAN_GPIO_PIN24_INT_TYPE_MASK) >> WLAN_GPIO_PIN24_INT_TYPE_LSB)
-#define WLAN_GPIO_PIN24_INT_TYPE_SET(x)          (((x) << WLAN_GPIO_PIN24_INT_TYPE_LSB) & WLAN_GPIO_PIN24_INT_TYPE_MASK)
-#define WLAN_GPIO_PIN24_PAD_DRIVER_MSB           2
-#define WLAN_GPIO_PIN24_PAD_DRIVER_LSB           2
-#define WLAN_GPIO_PIN24_PAD_DRIVER_MASK          0x00000004
-#define WLAN_GPIO_PIN24_PAD_DRIVER_GET(x)        (((x) & WLAN_GPIO_PIN24_PAD_DRIVER_MASK) >> WLAN_GPIO_PIN24_PAD_DRIVER_LSB)
-#define WLAN_GPIO_PIN24_PAD_DRIVER_SET(x)        (((x) << WLAN_GPIO_PIN24_PAD_DRIVER_LSB) & WLAN_GPIO_PIN24_PAD_DRIVER_MASK)
-#define WLAN_GPIO_PIN24_SOURCE_MSB               0
-#define WLAN_GPIO_PIN24_SOURCE_LSB               0
-#define WLAN_GPIO_PIN24_SOURCE_MASK              0x00000001
-#define WLAN_GPIO_PIN24_SOURCE_GET(x)            (((x) & WLAN_GPIO_PIN24_SOURCE_MASK) >> WLAN_GPIO_PIN24_SOURCE_LSB)
-#define WLAN_GPIO_PIN24_SOURCE_SET(x)            (((x) << WLAN_GPIO_PIN24_SOURCE_LSB) & WLAN_GPIO_PIN24_SOURCE_MASK)
-
-#define WLAN_GPIO_PIN25_ADDRESS                  0x0000008c
-#define WLAN_GPIO_PIN25_OFFSET                   0x0000008c
-#define WLAN_GPIO_PIN25_CONFIG_MSB               13
-#define WLAN_GPIO_PIN25_CONFIG_LSB               11
-#define WLAN_GPIO_PIN25_CONFIG_MASK              0x00003800
-#define WLAN_GPIO_PIN25_CONFIG_GET(x)            (((x) & WLAN_GPIO_PIN25_CONFIG_MASK) >> WLAN_GPIO_PIN25_CONFIG_LSB)
-#define WLAN_GPIO_PIN25_CONFIG_SET(x)            (((x) << WLAN_GPIO_PIN25_CONFIG_LSB) & WLAN_GPIO_PIN25_CONFIG_MASK)
-#define WLAN_GPIO_PIN25_WAKEUP_ENABLE_MSB        10
-#define WLAN_GPIO_PIN25_WAKEUP_ENABLE_LSB        10
-#define WLAN_GPIO_PIN25_WAKEUP_ENABLE_MASK       0x00000400
-#define WLAN_GPIO_PIN25_WAKEUP_ENABLE_GET(x)     (((x) & WLAN_GPIO_PIN25_WAKEUP_ENABLE_MASK) >> WLAN_GPIO_PIN25_WAKEUP_ENABLE_LSB)
-#define WLAN_GPIO_PIN25_WAKEUP_ENABLE_SET(x)     (((x) << WLAN_GPIO_PIN25_WAKEUP_ENABLE_LSB) & WLAN_GPIO_PIN25_WAKEUP_ENABLE_MASK)
-#define WLAN_GPIO_PIN25_INT_TYPE_MSB             9
-#define WLAN_GPIO_PIN25_INT_TYPE_LSB             7
-#define WLAN_GPIO_PIN25_INT_TYPE_MASK            0x00000380
-#define WLAN_GPIO_PIN25_INT_TYPE_GET(x)          (((x) & WLAN_GPIO_PIN25_INT_TYPE_MASK) >> WLAN_GPIO_PIN25_INT_TYPE_LSB)
-#define WLAN_GPIO_PIN25_INT_TYPE_SET(x)          (((x) << WLAN_GPIO_PIN25_INT_TYPE_LSB) & WLAN_GPIO_PIN25_INT_TYPE_MASK)
-#define WLAN_GPIO_PIN25_PAD_DRIVER_MSB           2
-#define WLAN_GPIO_PIN25_PAD_DRIVER_LSB           2
-#define WLAN_GPIO_PIN25_PAD_DRIVER_MASK          0x00000004
-#define WLAN_GPIO_PIN25_PAD_DRIVER_GET(x)        (((x) & WLAN_GPIO_PIN25_PAD_DRIVER_MASK) >> WLAN_GPIO_PIN25_PAD_DRIVER_LSB)
-#define WLAN_GPIO_PIN25_PAD_DRIVER_SET(x)        (((x) << WLAN_GPIO_PIN25_PAD_DRIVER_LSB) & WLAN_GPIO_PIN25_PAD_DRIVER_MASK)
-#define WLAN_GPIO_PIN25_SOURCE_MSB               0
-#define WLAN_GPIO_PIN25_SOURCE_LSB               0
-#define WLAN_GPIO_PIN25_SOURCE_MASK              0x00000001
-#define WLAN_GPIO_PIN25_SOURCE_GET(x)            (((x) & WLAN_GPIO_PIN25_SOURCE_MASK) >> WLAN_GPIO_PIN25_SOURCE_LSB)
-#define WLAN_GPIO_PIN25_SOURCE_SET(x)            (((x) << WLAN_GPIO_PIN25_SOURCE_LSB) & WLAN_GPIO_PIN25_SOURCE_MASK)
-
-#define SDIO_ADDRESS                             0x00000090
-#define SDIO_OFFSET                              0x00000090
-#define SDIO_PINS_EN_MSB                         0
-#define SDIO_PINS_EN_LSB                         0
-#define SDIO_PINS_EN_MASK                        0x00000001
-#define SDIO_PINS_EN_GET(x)                      (((x) & SDIO_PINS_EN_MASK) >> SDIO_PINS_EN_LSB)
-#define SDIO_PINS_EN_SET(x)                      (((x) << SDIO_PINS_EN_LSB) & SDIO_PINS_EN_MASK)
-
-#define FUNC_BUS_ADDRESS                         0x00000094
-#define FUNC_BUS_OFFSET                          0x00000094
-#define FUNC_BUS_GPIO_MODE_MSB                   22
-#define FUNC_BUS_GPIO_MODE_LSB                   22
-#define FUNC_BUS_GPIO_MODE_MASK                  0x00400000
-#define FUNC_BUS_GPIO_MODE_GET(x)                (((x) & FUNC_BUS_GPIO_MODE_MASK) >> FUNC_BUS_GPIO_MODE_LSB)
-#define FUNC_BUS_GPIO_MODE_SET(x)                (((x) << FUNC_BUS_GPIO_MODE_LSB) & FUNC_BUS_GPIO_MODE_MASK)
-#define FUNC_BUS_OE_L_MSB                        21
-#define FUNC_BUS_OE_L_LSB                        0
-#define FUNC_BUS_OE_L_MASK                       0x003fffff
-#define FUNC_BUS_OE_L_GET(x)                     (((x) & FUNC_BUS_OE_L_MASK) >> FUNC_BUS_OE_L_LSB)
-#define FUNC_BUS_OE_L_SET(x)                     (((x) << FUNC_BUS_OE_L_LSB) & FUNC_BUS_OE_L_MASK)
-
-#define WL_SOC_APB_ADDRESS                       0x00000098
-#define WL_SOC_APB_OFFSET                        0x00000098
-#define WL_SOC_APB_TOGGLE_MSB                    0
-#define WL_SOC_APB_TOGGLE_LSB                    0
-#define WL_SOC_APB_TOGGLE_MASK                   0x00000001
-#define WL_SOC_APB_TOGGLE_GET(x)                 (((x) & WL_SOC_APB_TOGGLE_MASK) >> WL_SOC_APB_TOGGLE_LSB)
-#define WL_SOC_APB_TOGGLE_SET(x)                 (((x) << WL_SOC_APB_TOGGLE_LSB) & WL_SOC_APB_TOGGLE_MASK)
-
-#define WLAN_SIGMA_DELTA_ADDRESS                 0x0000009c
-#define WLAN_SIGMA_DELTA_OFFSET                  0x0000009c
-#define WLAN_SIGMA_DELTA_ENABLE_MSB              16
-#define WLAN_SIGMA_DELTA_ENABLE_LSB              16
-#define WLAN_SIGMA_DELTA_ENABLE_MASK             0x00010000
-#define WLAN_SIGMA_DELTA_ENABLE_GET(x)           (((x) & WLAN_SIGMA_DELTA_ENABLE_MASK) >> WLAN_SIGMA_DELTA_ENABLE_LSB)
-#define WLAN_SIGMA_DELTA_ENABLE_SET(x)           (((x) << WLAN_SIGMA_DELTA_ENABLE_LSB) & WLAN_SIGMA_DELTA_ENABLE_MASK)
-#define WLAN_SIGMA_DELTA_PRESCALAR_MSB           15
-#define WLAN_SIGMA_DELTA_PRESCALAR_LSB           8
-#define WLAN_SIGMA_DELTA_PRESCALAR_MASK          0x0000ff00
-#define WLAN_SIGMA_DELTA_PRESCALAR_GET(x)        (((x) & WLAN_SIGMA_DELTA_PRESCALAR_MASK) >> WLAN_SIGMA_DELTA_PRESCALAR_LSB)
-#define WLAN_SIGMA_DELTA_PRESCALAR_SET(x)        (((x) << WLAN_SIGMA_DELTA_PRESCALAR_LSB) & WLAN_SIGMA_DELTA_PRESCALAR_MASK)
-#define WLAN_SIGMA_DELTA_TARGET_MSB              7
-#define WLAN_SIGMA_DELTA_TARGET_LSB              0
-#define WLAN_SIGMA_DELTA_TARGET_MASK             0x000000ff
-#define WLAN_SIGMA_DELTA_TARGET_GET(x)           (((x) & WLAN_SIGMA_DELTA_TARGET_MASK) >> WLAN_SIGMA_DELTA_TARGET_LSB)
-#define WLAN_SIGMA_DELTA_TARGET_SET(x)           (((x) << WLAN_SIGMA_DELTA_TARGET_LSB) & WLAN_SIGMA_DELTA_TARGET_MASK)
-
-#define WL_BOOTSTRAP_ADDRESS                     0x000000a0
-#define WL_BOOTSTRAP_OFFSET                      0x000000a0
-#define WL_BOOTSTRAP_STATUS_MSB                  22
-#define WL_BOOTSTRAP_STATUS_LSB                  0
-#define WL_BOOTSTRAP_STATUS_MASK                 0x007fffff
-#define WL_BOOTSTRAP_STATUS_GET(x)               (((x) & WL_BOOTSTRAP_STATUS_MASK) >> WL_BOOTSTRAP_STATUS_LSB)
-#define WL_BOOTSTRAP_STATUS_SET(x)               (((x) << WL_BOOTSTRAP_STATUS_LSB) & WL_BOOTSTRAP_STATUS_MASK)
-
-#define CLOCK_GPIO_ADDRESS                       0x000000a4
-#define CLOCK_GPIO_OFFSET                        0x000000a4
-#define CLOCK_GPIO_CLK_REQ_OUT_EN_MSB            2
-#define CLOCK_GPIO_CLK_REQ_OUT_EN_LSB            2
-#define CLOCK_GPIO_CLK_REQ_OUT_EN_MASK           0x00000004
-#define CLOCK_GPIO_CLK_REQ_OUT_EN_GET(x)         (((x) & CLOCK_GPIO_CLK_REQ_OUT_EN_MASK) >> CLOCK_GPIO_CLK_REQ_OUT_EN_LSB)
-#define CLOCK_GPIO_CLK_REQ_OUT_EN_SET(x)         (((x) << CLOCK_GPIO_CLK_REQ_OUT_EN_LSB) & CLOCK_GPIO_CLK_REQ_OUT_EN_MASK)
-#define CLOCK_GPIO_BT_CLK_REQ_EN_MSB             1
-#define CLOCK_GPIO_BT_CLK_REQ_EN_LSB             1
-#define CLOCK_GPIO_BT_CLK_REQ_EN_MASK            0x00000002
-#define CLOCK_GPIO_BT_CLK_REQ_EN_GET(x)          (((x) & CLOCK_GPIO_BT_CLK_REQ_EN_MASK) >> CLOCK_GPIO_BT_CLK_REQ_EN_LSB)
-#define CLOCK_GPIO_BT_CLK_REQ_EN_SET(x)          (((x) << CLOCK_GPIO_BT_CLK_REQ_EN_LSB) & CLOCK_GPIO_BT_CLK_REQ_EN_MASK)
-#define CLOCK_GPIO_BT_CLK_OUT_EN_MSB             0
-#define CLOCK_GPIO_BT_CLK_OUT_EN_LSB             0
-#define CLOCK_GPIO_BT_CLK_OUT_EN_MASK            0x00000001
-#define CLOCK_GPIO_BT_CLK_OUT_EN_GET(x)          (((x) & CLOCK_GPIO_BT_CLK_OUT_EN_MASK) >> CLOCK_GPIO_BT_CLK_OUT_EN_LSB)
-#define CLOCK_GPIO_BT_CLK_OUT_EN_SET(x)          (((x) << CLOCK_GPIO_BT_CLK_OUT_EN_LSB) & CLOCK_GPIO_BT_CLK_OUT_EN_MASK)
-
-#define WLAN_DEBUG_CONTROL_ADDRESS               0x000000a8
-#define WLAN_DEBUG_CONTROL_OFFSET                0x000000a8
-#define WLAN_DEBUG_CONTROL_ENABLE_MSB            0
-#define WLAN_DEBUG_CONTROL_ENABLE_LSB            0
-#define WLAN_DEBUG_CONTROL_ENABLE_MASK           0x00000001
-#define WLAN_DEBUG_CONTROL_ENABLE_GET(x)         (((x) & WLAN_DEBUG_CONTROL_ENABLE_MASK) >> WLAN_DEBUG_CONTROL_ENABLE_LSB)
-#define WLAN_DEBUG_CONTROL_ENABLE_SET(x)         (((x) << WLAN_DEBUG_CONTROL_ENABLE_LSB) & WLAN_DEBUG_CONTROL_ENABLE_MASK)
-
-#define WLAN_DEBUG_INPUT_SEL_ADDRESS             0x000000ac
-#define WLAN_DEBUG_INPUT_SEL_OFFSET              0x000000ac
-#define WLAN_DEBUG_INPUT_SEL_SHIFT_MSB           5
-#define WLAN_DEBUG_INPUT_SEL_SHIFT_LSB           4
-#define WLAN_DEBUG_INPUT_SEL_SHIFT_MASK          0x00000030
-#define WLAN_DEBUG_INPUT_SEL_SHIFT_GET(x)        (((x) & WLAN_DEBUG_INPUT_SEL_SHIFT_MASK) >> WLAN_DEBUG_INPUT_SEL_SHIFT_LSB)
-#define WLAN_DEBUG_INPUT_SEL_SHIFT_SET(x)        (((x) << WLAN_DEBUG_INPUT_SEL_SHIFT_LSB) & WLAN_DEBUG_INPUT_SEL_SHIFT_MASK)
-#define WLAN_DEBUG_INPUT_SEL_SRC_MSB             3
-#define WLAN_DEBUG_INPUT_SEL_SRC_LSB             0
-#define WLAN_DEBUG_INPUT_SEL_SRC_MASK            0x0000000f
-#define WLAN_DEBUG_INPUT_SEL_SRC_GET(x)          (((x) & WLAN_DEBUG_INPUT_SEL_SRC_MASK) >> WLAN_DEBUG_INPUT_SEL_SRC_LSB)
-#define WLAN_DEBUG_INPUT_SEL_SRC_SET(x)          (((x) << WLAN_DEBUG_INPUT_SEL_SRC_LSB) & WLAN_DEBUG_INPUT_SEL_SRC_MASK)
-
-#define WLAN_DEBUG_OUT_ADDRESS                   0x000000b0
-#define WLAN_DEBUG_OUT_OFFSET                    0x000000b0
-#define WLAN_DEBUG_OUT_DATA_MSB                  17
-#define WLAN_DEBUG_OUT_DATA_LSB                  0
-#define WLAN_DEBUG_OUT_DATA_MASK                 0x0003ffff
-#define WLAN_DEBUG_OUT_DATA_GET(x)               (((x) & WLAN_DEBUG_OUT_DATA_MASK) >> WLAN_DEBUG_OUT_DATA_LSB)
-#define WLAN_DEBUG_OUT_DATA_SET(x)               (((x) << WLAN_DEBUG_OUT_DATA_LSB) & WLAN_DEBUG_OUT_DATA_MASK)
-
-#define WLAN_RESET_TUPLE_STATUS_ADDRESS          0x000000b4
-#define WLAN_RESET_TUPLE_STATUS_OFFSET           0x000000b4
-#define WLAN_RESET_TUPLE_STATUS_TEST_RESET_TUPLE_MSB 11
-#define WLAN_RESET_TUPLE_STATUS_TEST_RESET_TUPLE_LSB 8
-#define WLAN_RESET_TUPLE_STATUS_TEST_RESET_TUPLE_MASK 0x00000f00
-#define WLAN_RESET_TUPLE_STATUS_TEST_RESET_TUPLE_GET(x) (((x) & WLAN_RESET_TUPLE_STATUS_TEST_RESET_TUPLE_MASK) >> WLAN_RESET_TUPLE_STATUS_TEST_RESET_TUPLE_LSB)
-#define WLAN_RESET_TUPLE_STATUS_TEST_RESET_TUPLE_SET(x) (((x) << WLAN_RESET_TUPLE_STATUS_TEST_RESET_TUPLE_LSB) & WLAN_RESET_TUPLE_STATUS_TEST_RESET_TUPLE_MASK)
-#define WLAN_RESET_TUPLE_STATUS_PIN_RESET_TUPLE_MSB 7
-#define WLAN_RESET_TUPLE_STATUS_PIN_RESET_TUPLE_LSB 0
-#define WLAN_RESET_TUPLE_STATUS_PIN_RESET_TUPLE_MASK 0x000000ff
-#define WLAN_RESET_TUPLE_STATUS_PIN_RESET_TUPLE_GET(x) (((x) & WLAN_RESET_TUPLE_STATUS_PIN_RESET_TUPLE_MASK) >> WLAN_RESET_TUPLE_STATUS_PIN_RESET_TUPLE_LSB)
-#define WLAN_RESET_TUPLE_STATUS_PIN_RESET_TUPLE_SET(x) (((x) << WLAN_RESET_TUPLE_STATUS_PIN_RESET_TUPLE_LSB) & WLAN_RESET_TUPLE_STATUS_PIN_RESET_TUPLE_MASK)
-
-#define ANTENNA_SLEEP_CONTROL_ADDRESS            0x000000b8
-#define ANTENNA_SLEEP_CONTROL_OFFSET             0x000000b8
-#define ANTENNA_SLEEP_CONTROL_OVERRIDE_MSB       14
-#define ANTENNA_SLEEP_CONTROL_OVERRIDE_LSB       10
-#define ANTENNA_SLEEP_CONTROL_OVERRIDE_MASK      0x00007c00
-#define ANTENNA_SLEEP_CONTROL_OVERRIDE_GET(x)    (((x) & ANTENNA_SLEEP_CONTROL_OVERRIDE_MASK) >> ANTENNA_SLEEP_CONTROL_OVERRIDE_LSB)
-#define ANTENNA_SLEEP_CONTROL_OVERRIDE_SET(x)    (((x) << ANTENNA_SLEEP_CONTROL_OVERRIDE_LSB) & ANTENNA_SLEEP_CONTROL_OVERRIDE_MASK)
-#define ANTENNA_SLEEP_CONTROL_VALUE_MSB          9
-#define ANTENNA_SLEEP_CONTROL_VALUE_LSB          5
-#define ANTENNA_SLEEP_CONTROL_VALUE_MASK         0x000003e0
-#define ANTENNA_SLEEP_CONTROL_VALUE_GET(x)       (((x) & ANTENNA_SLEEP_CONTROL_VALUE_MASK) >> ANTENNA_SLEEP_CONTROL_VALUE_LSB)
-#define ANTENNA_SLEEP_CONTROL_VALUE_SET(x)       (((x) << ANTENNA_SLEEP_CONTROL_VALUE_LSB) & ANTENNA_SLEEP_CONTROL_VALUE_MASK)
-#define ANTENNA_SLEEP_CONTROL_ENABLE_MSB         4
-#define ANTENNA_SLEEP_CONTROL_ENABLE_LSB         0
-#define ANTENNA_SLEEP_CONTROL_ENABLE_MASK        0x0000001f
-#define ANTENNA_SLEEP_CONTROL_ENABLE_GET(x)      (((x) & ANTENNA_SLEEP_CONTROL_ENABLE_MASK) >> ANTENNA_SLEEP_CONTROL_ENABLE_LSB)
-#define ANTENNA_SLEEP_CONTROL_ENABLE_SET(x)      (((x) << ANTENNA_SLEEP_CONTROL_ENABLE_LSB) & ANTENNA_SLEEP_CONTROL_ENABLE_MASK)
-
-
-#ifndef __ASSEMBLER__
-
-typedef struct gpio_athr_wlan_reg_reg_s {
-  volatile unsigned int wlan_gpio_out;
-  volatile unsigned int wlan_gpio_out_w1ts;
-  volatile unsigned int wlan_gpio_out_w1tc;
-  volatile unsigned int wlan_gpio_enable;
-  volatile unsigned int wlan_gpio_enable_w1ts;
-  volatile unsigned int wlan_gpio_enable_w1tc;
-  volatile unsigned int wlan_gpio_in;
-  volatile unsigned int wlan_gpio_status;
-  volatile unsigned int wlan_gpio_status_w1ts;
-  volatile unsigned int wlan_gpio_status_w1tc;
-  volatile unsigned int wlan_gpio_pin0;
-  volatile unsigned int wlan_gpio_pin1;
-  volatile unsigned int wlan_gpio_pin2;
-  volatile unsigned int wlan_gpio_pin3;
-  volatile unsigned int wlan_gpio_pin4;
-  volatile unsigned int wlan_gpio_pin5;
-  volatile unsigned int wlan_gpio_pin6;
-  volatile unsigned int wlan_gpio_pin7;
-  volatile unsigned int wlan_gpio_pin8;
-  volatile unsigned int wlan_gpio_pin9;
-  volatile unsigned int wlan_gpio_pin10;
-  volatile unsigned int wlan_gpio_pin11;
-  volatile unsigned int wlan_gpio_pin12;
-  volatile unsigned int wlan_gpio_pin13;
-  volatile unsigned int wlan_gpio_pin14;
-  volatile unsigned int wlan_gpio_pin15;
-  volatile unsigned int wlan_gpio_pin16;
-  volatile unsigned int wlan_gpio_pin17;
-  volatile unsigned int wlan_gpio_pin18;
-  volatile unsigned int wlan_gpio_pin19;
-  volatile unsigned int wlan_gpio_pin20;
-  volatile unsigned int wlan_gpio_pin21;
-  volatile unsigned int wlan_gpio_pin22;
-  volatile unsigned int wlan_gpio_pin23;
-  volatile unsigned int wlan_gpio_pin24;
-  volatile unsigned int wlan_gpio_pin25;
-  volatile unsigned int sdio;
-  volatile unsigned int func_bus;
-  volatile unsigned int wl_soc_apb;
-  volatile unsigned int wlan_sigma_delta;
-  volatile unsigned int wl_bootstrap;
-  volatile unsigned int clock_gpio;
-  volatile unsigned int wlan_debug_control;
-  volatile unsigned int wlan_debug_input_sel;
-  volatile unsigned int wlan_debug_out;
-  volatile unsigned int wlan_reset_tuple_status;
-  volatile unsigned int antenna_sleep_control;
-} gpio_athr_wlan_reg_reg_t;
-
-#endif /* __ASSEMBLER__ */
-
-#endif /* _GPIO_ATHR_WLAN_REG_H_ */
diff -druN linux-2.6.39-libre/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/gpio_reg.h linux-3.0-rc7-libre/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/gpio_reg.h
--- linux-2.6.39-libre/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/gpio_reg.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/gpio_reg.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,1094 +0,0 @@
-// ------------------------------------------------------------------
-// Copyright (c) 2004-2010 Atheros Corporation.  All rights reserved.
-// 
-//
-// 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.
-//
-//
-// ------------------------------------------------------------------
-//===================================================================
-// Author(s): ="Atheros"
-//===================================================================
-
-
-#ifdef WLAN_HEADERS
-
-#include "gpio_athr_wlan_reg.h"
-
-
-#ifndef BT_HEADERS
-
-#define GPIO_OUT_ADDRESS WLAN_GPIO_OUT_ADDRESS
-#define GPIO_OUT_OFFSET WLAN_GPIO_OUT_OFFSET
-#define GPIO_OUT_DATA_MSB WLAN_GPIO_OUT_DATA_MSB
-#define GPIO_OUT_DATA_LSB WLAN_GPIO_OUT_DATA_LSB
-#define GPIO_OUT_DATA_MASK WLAN_GPIO_OUT_DATA_MASK
-#define GPIO_OUT_DATA_GET(x) WLAN_GPIO_OUT_DATA_GET(x)
-#define GPIO_OUT_DATA_SET(x) WLAN_GPIO_OUT_DATA_SET(x)
-#define GPIO_OUT_W1TS_ADDRESS WLAN_GPIO_OUT_W1TS_ADDRESS
-#define GPIO_OUT_W1TS_OFFSET WLAN_GPIO_OUT_W1TS_OFFSET
-#define GPIO_OUT_W1TS_DATA_MSB WLAN_GPIO_OUT_W1TS_DATA_MSB
-#define GPIO_OUT_W1TS_DATA_LSB WLAN_GPIO_OUT_W1TS_DATA_LSB
-#define GPIO_OUT_W1TS_DATA_MASK WLAN_GPIO_OUT_W1TS_DATA_MASK
-#define GPIO_OUT_W1TS_DATA_GET(x) WLAN_GPIO_OUT_W1TS_DATA_GET(x)
-#define GPIO_OUT_W1TS_DATA_SET(x) WLAN_GPIO_OUT_W1TS_DATA_SET(x)
-#define GPIO_OUT_W1TC_ADDRESS WLAN_GPIO_OUT_W1TC_ADDRESS
-#define GPIO_OUT_W1TC_OFFSET WLAN_GPIO_OUT_W1TC_OFFSET
-#define GPIO_OUT_W1TC_DATA_MSB WLAN_GPIO_OUT_W1TC_DATA_MSB
-#define GPIO_OUT_W1TC_DATA_LSB WLAN_GPIO_OUT_W1TC_DATA_LSB
-#define GPIO_OUT_W1TC_DATA_MASK WLAN_GPIO_OUT_W1TC_DATA_MASK
-#define GPIO_OUT_W1TC_DATA_GET(x) WLAN_GPIO_OUT_W1TC_DATA_GET(x)
-#define GPIO_OUT_W1TC_DATA_SET(x) WLAN_GPIO_OUT_W1TC_DATA_SET(x)
-#define GPIO_ENABLE_ADDRESS WLAN_GPIO_ENABLE_ADDRESS
-#define GPIO_ENABLE_OFFSET WLAN_GPIO_ENABLE_OFFSET
-#define GPIO_ENABLE_DATA_MSB WLAN_GPIO_ENABLE_DATA_MSB
-#define GPIO_ENABLE_DATA_LSB WLAN_GPIO_ENABLE_DATA_LSB
-#define GPIO_ENABLE_DATA_MASK WLAN_GPIO_ENABLE_DATA_MASK
-#define GPIO_ENABLE_DATA_GET(x) WLAN_GPIO_ENABLE_DATA_GET(x)
-#define GPIO_ENABLE_DATA_SET(x) WLAN_GPIO_ENABLE_DATA_SET(x)
-#define GPIO_ENABLE_W1TS_ADDRESS WLAN_GPIO_ENABLE_W1TS_ADDRESS
-#define GPIO_ENABLE_W1TS_OFFSET WLAN_GPIO_ENABLE_W1TS_OFFSET
-#define GPIO_ENABLE_W1TS_DATA_MSB WLAN_GPIO_ENABLE_W1TS_DATA_MSB
-#define GPIO_ENABLE_W1TS_DATA_LSB WLAN_GPIO_ENABLE_W1TS_DATA_LSB
-#define GPIO_ENABLE_W1TS_DATA_MASK WLAN_GPIO_ENABLE_W1TS_DATA_MASK
-#define GPIO_ENABLE_W1TS_DATA_GET(x) WLAN_GPIO_ENABLE_W1TS_DATA_GET(x)
-#define GPIO_ENABLE_W1TS_DATA_SET(x) WLAN_GPIO_ENABLE_W1TS_DATA_SET(x)
-#define GPIO_ENABLE_W1TC_ADDRESS WLAN_GPIO_ENABLE_W1TC_ADDRESS
-#define GPIO_ENABLE_W1TC_OFFSET WLAN_GPIO_ENABLE_W1TC_OFFSET
-#define GPIO_ENABLE_W1TC_DATA_MSB WLAN_GPIO_ENABLE_W1TC_DATA_MSB
-#define GPIO_ENABLE_W1TC_DATA_LSB WLAN_GPIO_ENABLE_W1TC_DATA_LSB
-#define GPIO_ENABLE_W1TC_DATA_MASK WLAN_GPIO_ENABLE_W1TC_DATA_MASK
-#define GPIO_ENABLE_W1TC_DATA_GET(x) WLAN_GPIO_ENABLE_W1TC_DATA_GET(x)
-#define GPIO_ENABLE_W1TC_DATA_SET(x) WLAN_GPIO_ENABLE_W1TC_DATA_SET(x)
-#define GPIO_IN_ADDRESS WLAN_GPIO_IN_ADDRESS
-#define GPIO_IN_OFFSET WLAN_GPIO_IN_OFFSET
-#define GPIO_IN_DATA_MSB WLAN_GPIO_IN_DATA_MSB
-#define GPIO_IN_DATA_LSB WLAN_GPIO_IN_DATA_LSB
-#define GPIO_IN_DATA_MASK WLAN_GPIO_IN_DATA_MASK
-#define GPIO_IN_DATA_GET(x) WLAN_GPIO_IN_DATA_GET(x)
-#define GPIO_IN_DATA_SET(x) WLAN_GPIO_IN_DATA_SET(x)
-#define GPIO_STATUS_ADDRESS WLAN_GPIO_STATUS_ADDRESS
-#define GPIO_STATUS_OFFSET WLAN_GPIO_STATUS_OFFSET
-#define GPIO_STATUS_INTERRUPT_MSB WLAN_GPIO_STATUS_INTERRUPT_MSB
-#define GPIO_STATUS_INTERRUPT_LSB WLAN_GPIO_STATUS_INTERRUPT_LSB
-#define GPIO_STATUS_INTERRUPT_MASK WLAN_GPIO_STATUS_INTERRUPT_MASK
-#define GPIO_STATUS_INTERRUPT_GET(x) WLAN_GPIO_STATUS_INTERRUPT_GET(x)
-#define GPIO_STATUS_INTERRUPT_SET(x) WLAN_GPIO_STATUS_INTERRUPT_SET(x)
-#define GPIO_STATUS_W1TS_ADDRESS WLAN_GPIO_STATUS_W1TS_ADDRESS
-#define GPIO_STATUS_W1TS_OFFSET WLAN_GPIO_STATUS_W1TS_OFFSET
-#define GPIO_STATUS_W1TS_INTERRUPT_MSB WLAN_GPIO_STATUS_W1TS_INTERRUPT_MSB
-#define GPIO_STATUS_W1TS_INTERRUPT_LSB WLAN_GPIO_STATUS_W1TS_INTERRUPT_LSB
-#define GPIO_STATUS_W1TS_INTERRUPT_MASK WLAN_GPIO_STATUS_W1TS_INTERRUPT_MASK
-#define GPIO_STATUS_W1TS_INTERRUPT_GET(x) WLAN_GPIO_STATUS_W1TS_INTERRUPT_GET(x)
-#define GPIO_STATUS_W1TS_INTERRUPT_SET(x) WLAN_GPIO_STATUS_W1TS_INTERRUPT_SET(x)
-#define GPIO_STATUS_W1TC_ADDRESS WLAN_GPIO_STATUS_W1TC_ADDRESS
-#define GPIO_STATUS_W1TC_OFFSET WLAN_GPIO_STATUS_W1TC_OFFSET
-#define GPIO_STATUS_W1TC_INTERRUPT_MSB WLAN_GPIO_STATUS_W1TC_INTERRUPT_MSB
-#define GPIO_STATUS_W1TC_INTERRUPT_LSB WLAN_GPIO_STATUS_W1TC_INTERRUPT_LSB
-#define GPIO_STATUS_W1TC_INTERRUPT_MASK WLAN_GPIO_STATUS_W1TC_INTERRUPT_MASK
-#define GPIO_STATUS_W1TC_INTERRUPT_GET(x) WLAN_GPIO_STATUS_W1TC_INTERRUPT_GET(x)
-#define GPIO_STATUS_W1TC_INTERRUPT_SET(x) WLAN_GPIO_STATUS_W1TC_INTERRUPT_SET(x)
-#define GPIO_PIN0_ADDRESS WLAN_GPIO_PIN0_ADDRESS
-#define GPIO_PIN0_OFFSET WLAN_GPIO_PIN0_OFFSET
-#define GPIO_PIN0_CONFIG_MSB WLAN_GPIO_PIN0_CONFIG_MSB
-#define GPIO_PIN0_CONFIG_LSB WLAN_GPIO_PIN0_CONFIG_LSB
-#define GPIO_PIN0_CONFIG_MASK WLAN_GPIO_PIN0_CONFIG_MASK
-#define GPIO_PIN0_CONFIG_GET(x) WLAN_GPIO_PIN0_CONFIG_GET(x)
-#define GPIO_PIN0_CONFIG_SET(x) WLAN_GPIO_PIN0_CONFIG_SET(x)
-#define GPIO_PIN0_WAKEUP_ENABLE_MSB WLAN_GPIO_PIN0_WAKEUP_ENABLE_MSB
-#define GPIO_PIN0_WAKEUP_ENABLE_LSB WLAN_GPIO_PIN0_WAKEUP_ENABLE_LSB
-#define GPIO_PIN0_WAKEUP_ENABLE_MASK WLAN_GPIO_PIN0_WAKEUP_ENABLE_MASK
-#define GPIO_PIN0_WAKEUP_ENABLE_GET(x) WLAN_GPIO_PIN0_WAKEUP_ENABLE_GET(x)
-#define GPIO_PIN0_WAKEUP_ENABLE_SET(x) WLAN_GPIO_PIN0_WAKEUP_ENABLE_SET(x)
-#define GPIO_PIN0_INT_TYPE_MSB WLAN_GPIO_PIN0_INT_TYPE_MSB
-#define GPIO_PIN0_INT_TYPE_LSB WLAN_GPIO_PIN0_INT_TYPE_LSB
-#define GPIO_PIN0_INT_TYPE_MASK WLAN_GPIO_PIN0_INT_TYPE_MASK
-#define GPIO_PIN0_INT_TYPE_GET(x) WLAN_GPIO_PIN0_INT_TYPE_GET(x)
-#define GPIO_PIN0_INT_TYPE_SET(x) WLAN_GPIO_PIN0_INT_TYPE_SET(x)
-#define GPIO_PIN0_PAD_PULL_MSB WLAN_GPIO_PIN0_PAD_PULL_MSB
-#define GPIO_PIN0_PAD_PULL_LSB WLAN_GPIO_PIN0_PAD_PULL_LSB
-#define GPIO_PIN0_PAD_PULL_MASK WLAN_GPIO_PIN0_PAD_PULL_MASK
-#define GPIO_PIN0_PAD_PULL_GET(x) WLAN_GPIO_PIN0_PAD_PULL_GET(x)
-#define GPIO_PIN0_PAD_PULL_SET(x) WLAN_GPIO_PIN0_PAD_PULL_SET(x)
-#define GPIO_PIN0_PAD_STRENGTH_MSB WLAN_GPIO_PIN0_PAD_STRENGTH_MSB
-#define GPIO_PIN0_PAD_STRENGTH_LSB WLAN_GPIO_PIN0_PAD_STRENGTH_LSB
-#define GPIO_PIN0_PAD_STRENGTH_MASK WLAN_GPIO_PIN0_PAD_STRENGTH_MASK
-#define GPIO_PIN0_PAD_STRENGTH_GET(x) WLAN_GPIO_PIN0_PAD_STRENGTH_GET(x)
-#define GPIO_PIN0_PAD_STRENGTH_SET(x) WLAN_GPIO_PIN0_PAD_STRENGTH_SET(x)
-#define GPIO_PIN0_PAD_DRIVER_MSB WLAN_GPIO_PIN0_PAD_DRIVER_MSB
-#define GPIO_PIN0_PAD_DRIVER_LSB WLAN_GPIO_PIN0_PAD_DRIVER_LSB
-#define GPIO_PIN0_PAD_DRIVER_MASK WLAN_GPIO_PIN0_PAD_DRIVER_MASK
-#define GPIO_PIN0_PAD_DRIVER_GET(x) WLAN_GPIO_PIN0_PAD_DRIVER_GET(x)
-#define GPIO_PIN0_PAD_DRIVER_SET(x) WLAN_GPIO_PIN0_PAD_DRIVER_SET(x)
-#define GPIO_PIN0_SOURCE_MSB WLAN_GPIO_PIN0_SOURCE_MSB
-#define GPIO_PIN0_SOURCE_LSB WLAN_GPIO_PIN0_SOURCE_LSB
-#define GPIO_PIN0_SOURCE_MASK WLAN_GPIO_PIN0_SOURCE_MASK
-#define GPIO_PIN0_SOURCE_GET(x) WLAN_GPIO_PIN0_SOURCE_GET(x)
-#define GPIO_PIN0_SOURCE_SET(x) WLAN_GPIO_PIN0_SOURCE_SET(x)
-#define GPIO_PIN1_ADDRESS WLAN_GPIO_PIN1_ADDRESS
-#define GPIO_PIN1_OFFSET WLAN_GPIO_PIN1_OFFSET
-#define GPIO_PIN1_CONFIG_MSB WLAN_GPIO_PIN1_CONFIG_MSB
-#define GPIO_PIN1_CONFIG_LSB WLAN_GPIO_PIN1_CONFIG_LSB
-#define GPIO_PIN1_CONFIG_MASK WLAN_GPIO_PIN1_CONFIG_MASK
-#define GPIO_PIN1_CONFIG_GET(x) WLAN_GPIO_PIN1_CONFIG_GET(x)
-#define GPIO_PIN1_CONFIG_SET(x) WLAN_GPIO_PIN1_CONFIG_SET(x)
-#define GPIO_PIN1_WAKEUP_ENABLE_MSB WLAN_GPIO_PIN1_WAKEUP_ENABLE_MSB
-#define GPIO_PIN1_WAKEUP_ENABLE_LSB WLAN_GPIO_PIN1_WAKEUP_ENABLE_LSB
-#define GPIO_PIN1_WAKEUP_ENABLE_MASK WLAN_GPIO_PIN1_WAKEUP_ENABLE_MASK
-#define GPIO_PIN1_WAKEUP_ENABLE_GET(x) WLAN_GPIO_PIN1_WAKEUP_ENABLE_GET(x)
-#define GPIO_PIN1_WAKEUP_ENABLE_SET(x) WLAN_GPIO_PIN1_WAKEUP_ENABLE_SET(x)
-#define GPIO_PIN1_INT_TYPE_MSB WLAN_GPIO_PIN1_INT_TYPE_MSB
-#define GPIO_PIN1_INT_TYPE_LSB WLAN_GPIO_PIN1_INT_TYPE_LSB
-#define GPIO_PIN1_INT_TYPE_MASK WLAN_GPIO_PIN1_INT_TYPE_MASK
-#define GPIO_PIN1_INT_TYPE_GET(x) WLAN_GPIO_PIN1_INT_TYPE_GET(x)
-#define GPIO_PIN1_INT_TYPE_SET(x) WLAN_GPIO_PIN1_INT_TYPE_SET(x)
-#define GPIO_PIN1_PAD_PULL_MSB WLAN_GPIO_PIN1_PAD_PULL_MSB
-#define GPIO_PIN1_PAD_PULL_LSB WLAN_GPIO_PIN1_PAD_PULL_LSB
-#define GPIO_PIN1_PAD_PULL_MASK WLAN_GPIO_PIN1_PAD_PULL_MASK
-#define GPIO_PIN1_PAD_PULL_GET(x) WLAN_GPIO_PIN1_PAD_PULL_GET(x)
-#define GPIO_PIN1_PAD_PULL_SET(x) WLAN_GPIO_PIN1_PAD_PULL_SET(x)
-#define GPIO_PIN1_PAD_STRENGTH_MSB WLAN_GPIO_PIN1_PAD_STRENGTH_MSB
-#define GPIO_PIN1_PAD_STRENGTH_LSB WLAN_GPIO_PIN1_PAD_STRENGTH_LSB
-#define GPIO_PIN1_PAD_STRENGTH_MASK WLAN_GPIO_PIN1_PAD_STRENGTH_MASK
-#define GPIO_PIN1_PAD_STRENGTH_GET(x) WLAN_GPIO_PIN1_PAD_STRENGTH_GET(x)
-#define GPIO_PIN1_PAD_STRENGTH_SET(x) WLAN_GPIO_PIN1_PAD_STRENGTH_SET(x)
-#define GPIO_PIN1_PAD_DRIVER_MSB WLAN_GPIO_PIN1_PAD_DRIVER_MSB
-#define GPIO_PIN1_PAD_DRIVER_LSB WLAN_GPIO_PIN1_PAD_DRIVER_LSB
-#define GPIO_PIN1_PAD_DRIVER_MASK WLAN_GPIO_PIN1_PAD_DRIVER_MASK
-#define GPIO_PIN1_PAD_DRIVER_GET(x) WLAN_GPIO_PIN1_PAD_DRIVER_GET(x)
-#define GPIO_PIN1_PAD_DRIVER_SET(x) WLAN_GPIO_PIN1_PAD_DRIVER_SET(x)
-#define GPIO_PIN1_SOURCE_MSB WLAN_GPIO_PIN1_SOURCE_MSB
-#define GPIO_PIN1_SOURCE_LSB WLAN_GPIO_PIN1_SOURCE_LSB
-#define GPIO_PIN1_SOURCE_MASK WLAN_GPIO_PIN1_SOURCE_MASK
-#define GPIO_PIN1_SOURCE_GET(x) WLAN_GPIO_PIN1_SOURCE_GET(x)
-#define GPIO_PIN1_SOURCE_SET(x) WLAN_GPIO_PIN1_SOURCE_SET(x)
-#define GPIO_PIN2_ADDRESS WLAN_GPIO_PIN2_ADDRESS
-#define GPIO_PIN2_OFFSET WLAN_GPIO_PIN2_OFFSET
-#define GPIO_PIN2_CONFIG_MSB WLAN_GPIO_PIN2_CONFIG_MSB
-#define GPIO_PIN2_CONFIG_LSB WLAN_GPIO_PIN2_CONFIG_LSB
-#define GPIO_PIN2_CONFIG_MASK WLAN_GPIO_PIN2_CONFIG_MASK
-#define GPIO_PIN2_CONFIG_GET(x) WLAN_GPIO_PIN2_CONFIG_GET(x)
-#define GPIO_PIN2_CONFIG_SET(x) WLAN_GPIO_PIN2_CONFIG_SET(x)
-#define GPIO_PIN2_WAKEUP_ENABLE_MSB WLAN_GPIO_PIN2_WAKEUP_ENABLE_MSB
-#define GPIO_PIN2_WAKEUP_ENABLE_LSB WLAN_GPIO_PIN2_WAKEUP_ENABLE_LSB
-#define GPIO_PIN2_WAKEUP_ENABLE_MASK WLAN_GPIO_PIN2_WAKEUP_ENABLE_MASK
-#define GPIO_PIN2_WAKEUP_ENABLE_GET(x) WLAN_GPIO_PIN2_WAKEUP_ENABLE_GET(x)
-#define GPIO_PIN2_WAKEUP_ENABLE_SET(x) WLAN_GPIO_PIN2_WAKEUP_ENABLE_SET(x)
-#define GPIO_PIN2_INT_TYPE_MSB WLAN_GPIO_PIN2_INT_TYPE_MSB
-#define GPIO_PIN2_INT_TYPE_LSB WLAN_GPIO_PIN2_INT_TYPE_LSB
-#define GPIO_PIN2_INT_TYPE_MASK WLAN_GPIO_PIN2_INT_TYPE_MASK
-#define GPIO_PIN2_INT_TYPE_GET(x) WLAN_GPIO_PIN2_INT_TYPE_GET(x)
-#define GPIO_PIN2_INT_TYPE_SET(x) WLAN_GPIO_PIN2_INT_TYPE_SET(x)
-#define GPIO_PIN2_PAD_PULL_MSB WLAN_GPIO_PIN2_PAD_PULL_MSB
-#define GPIO_PIN2_PAD_PULL_LSB WLAN_GPIO_PIN2_PAD_PULL_LSB
-#define GPIO_PIN2_PAD_PULL_MASK WLAN_GPIO_PIN2_PAD_PULL_MASK
-#define GPIO_PIN2_PAD_PULL_GET(x) WLAN_GPIO_PIN2_PAD_PULL_GET(x)
-#define GPIO_PIN2_PAD_PULL_SET(x) WLAN_GPIO_PIN2_PAD_PULL_SET(x)
-#define GPIO_PIN2_PAD_STRENGTH_MSB WLAN_GPIO_PIN2_PAD_STRENGTH_MSB
-#define GPIO_PIN2_PAD_STRENGTH_LSB WLAN_GPIO_PIN2_PAD_STRENGTH_LSB
-#define GPIO_PIN2_PAD_STRENGTH_MASK WLAN_GPIO_PIN2_PAD_STRENGTH_MASK
-#define GPIO_PIN2_PAD_STRENGTH_GET(x) WLAN_GPIO_PIN2_PAD_STRENGTH_GET(x)
-#define GPIO_PIN2_PAD_STRENGTH_SET(x) WLAN_GPIO_PIN2_PAD_STRENGTH_SET(x)
-#define GPIO_PIN2_PAD_DRIVER_MSB WLAN_GPIO_PIN2_PAD_DRIVER_MSB
-#define GPIO_PIN2_PAD_DRIVER_LSB WLAN_GPIO_PIN2_PAD_DRIVER_LSB
-#define GPIO_PIN2_PAD_DRIVER_MASK WLAN_GPIO_PIN2_PAD_DRIVER_MASK
-#define GPIO_PIN2_PAD_DRIVER_GET(x) WLAN_GPIO_PIN2_PAD_DRIVER_GET(x)
-#define GPIO_PIN2_PAD_DRIVER_SET(x) WLAN_GPIO_PIN2_PAD_DRIVER_SET(x)
-#define GPIO_PIN2_SOURCE_MSB WLAN_GPIO_PIN2_SOURCE_MSB
-#define GPIO_PIN2_SOURCE_LSB WLAN_GPIO_PIN2_SOURCE_LSB
-#define GPIO_PIN2_SOURCE_MASK WLAN_GPIO_PIN2_SOURCE_MASK
-#define GPIO_PIN2_SOURCE_GET(x) WLAN_GPIO_PIN2_SOURCE_GET(x)
-#define GPIO_PIN2_SOURCE_SET(x) WLAN_GPIO_PIN2_SOURCE_SET(x)
-#define GPIO_PIN3_ADDRESS WLAN_GPIO_PIN3_ADDRESS
-#define GPIO_PIN3_OFFSET WLAN_GPIO_PIN3_OFFSET
-#define GPIO_PIN3_CONFIG_MSB WLAN_GPIO_PIN3_CONFIG_MSB
-#define GPIO_PIN3_CONFIG_LSB WLAN_GPIO_PIN3_CONFIG_LSB
-#define GPIO_PIN3_CONFIG_MASK WLAN_GPIO_PIN3_CONFIG_MASK
-#define GPIO_PIN3_CONFIG_GET(x) WLAN_GPIO_PIN3_CONFIG_GET(x)
-#define GPIO_PIN3_CONFIG_SET(x) WLAN_GPIO_PIN3_CONFIG_SET(x)
-#define GPIO_PIN3_WAKEUP_ENABLE_MSB WLAN_GPIO_PIN3_WAKEUP_ENABLE_MSB
-#define GPIO_PIN3_WAKEUP_ENABLE_LSB WLAN_GPIO_PIN3_WAKEUP_ENABLE_LSB
-#define GPIO_PIN3_WAKEUP_ENABLE_MASK WLAN_GPIO_PIN3_WAKEUP_ENABLE_MASK
-#define GPIO_PIN3_WAKEUP_ENABLE_GET(x) WLAN_GPIO_PIN3_WAKEUP_ENABLE_GET(x)
-#define GPIO_PIN3_WAKEUP_ENABLE_SET(x) WLAN_GPIO_PIN3_WAKEUP_ENABLE_SET(x)
-#define GPIO_PIN3_INT_TYPE_MSB WLAN_GPIO_PIN3_INT_TYPE_MSB
-#define GPIO_PIN3_INT_TYPE_LSB WLAN_GPIO_PIN3_INT_TYPE_LSB
-#define GPIO_PIN3_INT_TYPE_MASK WLAN_GPIO_PIN3_INT_TYPE_MASK
-#define GPIO_PIN3_INT_TYPE_GET(x) WLAN_GPIO_PIN3_INT_TYPE_GET(x)
-#define GPIO_PIN3_INT_TYPE_SET(x) WLAN_GPIO_PIN3_INT_TYPE_SET(x)
-#define GPIO_PIN3_PAD_PULL_MSB WLAN_GPIO_PIN3_PAD_PULL_MSB
-#define GPIO_PIN3_PAD_PULL_LSB WLAN_GPIO_PIN3_PAD_PULL_LSB
-#define GPIO_PIN3_PAD_PULL_MASK WLAN_GPIO_PIN3_PAD_PULL_MASK
-#define GPIO_PIN3_PAD_PULL_GET(x) WLAN_GPIO_PIN3_PAD_PULL_GET(x)
-#define GPIO_PIN3_PAD_PULL_SET(x) WLAN_GPIO_PIN3_PAD_PULL_SET(x)
-#define GPIO_PIN3_PAD_STRENGTH_MSB WLAN_GPIO_PIN3_PAD_STRENGTH_MSB
-#define GPIO_PIN3_PAD_STRENGTH_LSB WLAN_GPIO_PIN3_PAD_STRENGTH_LSB
-#define GPIO_PIN3_PAD_STRENGTH_MASK WLAN_GPIO_PIN3_PAD_STRENGTH_MASK
-#define GPIO_PIN3_PAD_STRENGTH_GET(x) WLAN_GPIO_PIN3_PAD_STRENGTH_GET(x)
-#define GPIO_PIN3_PAD_STRENGTH_SET(x) WLAN_GPIO_PIN3_PAD_STRENGTH_SET(x)
-#define GPIO_PIN3_PAD_DRIVER_MSB WLAN_GPIO_PIN3_PAD_DRIVER_MSB
-#define GPIO_PIN3_PAD_DRIVER_LSB WLAN_GPIO_PIN3_PAD_DRIVER_LSB
-#define GPIO_PIN3_PAD_DRIVER_MASK WLAN_GPIO_PIN3_PAD_DRIVER_MASK
-#define GPIO_PIN3_PAD_DRIVER_GET(x) WLAN_GPIO_PIN3_PAD_DRIVER_GET(x)
-#define GPIO_PIN3_PAD_DRIVER_SET(x) WLAN_GPIO_PIN3_PAD_DRIVER_SET(x)
-#define GPIO_PIN3_SOURCE_MSB WLAN_GPIO_PIN3_SOURCE_MSB
-#define GPIO_PIN3_SOURCE_LSB WLAN_GPIO_PIN3_SOURCE_LSB
-#define GPIO_PIN3_SOURCE_MASK WLAN_GPIO_PIN3_SOURCE_MASK
-#define GPIO_PIN3_SOURCE_GET(x) WLAN_GPIO_PIN3_SOURCE_GET(x)
-#define GPIO_PIN3_SOURCE_SET(x) WLAN_GPIO_PIN3_SOURCE_SET(x)
-#define GPIO_PIN4_ADDRESS WLAN_GPIO_PIN4_ADDRESS
-#define GPIO_PIN4_OFFSET WLAN_GPIO_PIN4_OFFSET
-#define GPIO_PIN4_CONFIG_MSB WLAN_GPIO_PIN4_CONFIG_MSB
-#define GPIO_PIN4_CONFIG_LSB WLAN_GPIO_PIN4_CONFIG_LSB
-#define GPIO_PIN4_CONFIG_MASK WLAN_GPIO_PIN4_CONFIG_MASK
-#define GPIO_PIN4_CONFIG_GET(x) WLAN_GPIO_PIN4_CONFIG_GET(x)
-#define GPIO_PIN4_CONFIG_SET(x) WLAN_GPIO_PIN4_CONFIG_SET(x)
-#define GPIO_PIN4_WAKEUP_ENABLE_MSB WLAN_GPIO_PIN4_WAKEUP_ENABLE_MSB
-#define GPIO_PIN4_WAKEUP_ENABLE_LSB WLAN_GPIO_PIN4_WAKEUP_ENABLE_LSB
-#define GPIO_PIN4_WAKEUP_ENABLE_MASK WLAN_GPIO_PIN4_WAKEUP_ENABLE_MASK
-#define GPIO_PIN4_WAKEUP_ENABLE_GET(x) WLAN_GPIO_PIN4_WAKEUP_ENABLE_GET(x)
-#define GPIO_PIN4_WAKEUP_ENABLE_SET(x) WLAN_GPIO_PIN4_WAKEUP_ENABLE_SET(x)
-#define GPIO_PIN4_INT_TYPE_MSB WLAN_GPIO_PIN4_INT_TYPE_MSB
-#define GPIO_PIN4_INT_TYPE_LSB WLAN_GPIO_PIN4_INT_TYPE_LSB
-#define GPIO_PIN4_INT_TYPE_MASK WLAN_GPIO_PIN4_INT_TYPE_MASK
-#define GPIO_PIN4_INT_TYPE_GET(x) WLAN_GPIO_PIN4_INT_TYPE_GET(x)
-#define GPIO_PIN4_INT_TYPE_SET(x) WLAN_GPIO_PIN4_INT_TYPE_SET(x)
-#define GPIO_PIN4_PAD_PULL_MSB WLAN_GPIO_PIN4_PAD_PULL_MSB
-#define GPIO_PIN4_PAD_PULL_LSB WLAN_GPIO_PIN4_PAD_PULL_LSB
-#define GPIO_PIN4_PAD_PULL_MASK WLAN_GPIO_PIN4_PAD_PULL_MASK
-#define GPIO_PIN4_PAD_PULL_GET(x) WLAN_GPIO_PIN4_PAD_PULL_GET(x)
-#define GPIO_PIN4_PAD_PULL_SET(x) WLAN_GPIO_PIN4_PAD_PULL_SET(x)
-#define GPIO_PIN4_PAD_STRENGTH_MSB WLAN_GPIO_PIN4_PAD_STRENGTH_MSB
-#define GPIO_PIN4_PAD_STRENGTH_LSB WLAN_GPIO_PIN4_PAD_STRENGTH_LSB
-#define GPIO_PIN4_PAD_STRENGTH_MASK WLAN_GPIO_PIN4_PAD_STRENGTH_MASK
-#define GPIO_PIN4_PAD_STRENGTH_GET(x) WLAN_GPIO_PIN4_PAD_STRENGTH_GET(x)
-#define GPIO_PIN4_PAD_STRENGTH_SET(x) WLAN_GPIO_PIN4_PAD_STRENGTH_SET(x)
-#define GPIO_PIN4_PAD_DRIVER_MSB WLAN_GPIO_PIN4_PAD_DRIVER_MSB
-#define GPIO_PIN4_PAD_DRIVER_LSB WLAN_GPIO_PIN4_PAD_DRIVER_LSB
-#define GPIO_PIN4_PAD_DRIVER_MASK WLAN_GPIO_PIN4_PAD_DRIVER_MASK
-#define GPIO_PIN4_PAD_DRIVER_GET(x) WLAN_GPIO_PIN4_PAD_DRIVER_GET(x)
-#define GPIO_PIN4_PAD_DRIVER_SET(x) WLAN_GPIO_PIN4_PAD_DRIVER_SET(x)
-#define GPIO_PIN4_SOURCE_MSB WLAN_GPIO_PIN4_SOURCE_MSB
-#define GPIO_PIN4_SOURCE_LSB WLAN_GPIO_PIN4_SOURCE_LSB
-#define GPIO_PIN4_SOURCE_MASK WLAN_GPIO_PIN4_SOURCE_MASK
-#define GPIO_PIN4_SOURCE_GET(x) WLAN_GPIO_PIN4_SOURCE_GET(x)
-#define GPIO_PIN4_SOURCE_SET(x) WLAN_GPIO_PIN4_SOURCE_SET(x)
-#define GPIO_PIN5_ADDRESS WLAN_GPIO_PIN5_ADDRESS
-#define GPIO_PIN5_OFFSET WLAN_GPIO_PIN5_OFFSET
-#define GPIO_PIN5_CONFIG_MSB WLAN_GPIO_PIN5_CONFIG_MSB
-#define GPIO_PIN5_CONFIG_LSB WLAN_GPIO_PIN5_CONFIG_LSB
-#define GPIO_PIN5_CONFIG_MASK WLAN_GPIO_PIN5_CONFIG_MASK
-#define GPIO_PIN5_CONFIG_GET(x) WLAN_GPIO_PIN5_CONFIG_GET(x)
-#define GPIO_PIN5_CONFIG_SET(x) WLAN_GPIO_PIN5_CONFIG_SET(x)
-#define GPIO_PIN5_WAKEUP_ENABLE_MSB WLAN_GPIO_PIN5_WAKEUP_ENABLE_MSB
-#define GPIO_PIN5_WAKEUP_ENABLE_LSB WLAN_GPIO_PIN5_WAKEUP_ENABLE_LSB
-#define GPIO_PIN5_WAKEUP_ENABLE_MASK WLAN_GPIO_PIN5_WAKEUP_ENABLE_MASK
-#define GPIO_PIN5_WAKEUP_ENABLE_GET(x) WLAN_GPIO_PIN5_WAKEUP_ENABLE_GET(x)
-#define GPIO_PIN5_WAKEUP_ENABLE_SET(x) WLAN_GPIO_PIN5_WAKEUP_ENABLE_SET(x)
-#define GPIO_PIN5_INT_TYPE_MSB WLAN_GPIO_PIN5_INT_TYPE_MSB
-#define GPIO_PIN5_INT_TYPE_LSB WLAN_GPIO_PIN5_INT_TYPE_LSB
-#define GPIO_PIN5_INT_TYPE_MASK WLAN_GPIO_PIN5_INT_TYPE_MASK
-#define GPIO_PIN5_INT_TYPE_GET(x) WLAN_GPIO_PIN5_INT_TYPE_GET(x)
-#define GPIO_PIN5_INT_TYPE_SET(x) WLAN_GPIO_PIN5_INT_TYPE_SET(x)
-#define GPIO_PIN5_PAD_PULL_MSB WLAN_GPIO_PIN5_PAD_PULL_MSB
-#define GPIO_PIN5_PAD_PULL_LSB WLAN_GPIO_PIN5_PAD_PULL_LSB
-#define GPIO_PIN5_PAD_PULL_MASK WLAN_GPIO_PIN5_PAD_PULL_MASK
-#define GPIO_PIN5_PAD_PULL_GET(x) WLAN_GPIO_PIN5_PAD_PULL_GET(x)
-#define GPIO_PIN5_PAD_PULL_SET(x) WLAN_GPIO_PIN5_PAD_PULL_SET(x)
-#define GPIO_PIN5_PAD_STRENGTH_MSB WLAN_GPIO_PIN5_PAD_STRENGTH_MSB
-#define GPIO_PIN5_PAD_STRENGTH_LSB WLAN_GPIO_PIN5_PAD_STRENGTH_LSB
-#define GPIO_PIN5_PAD_STRENGTH_MASK WLAN_GPIO_PIN5_PAD_STRENGTH_MASK
-#define GPIO_PIN5_PAD_STRENGTH_GET(x) WLAN_GPIO_PIN5_PAD_STRENGTH_GET(x)
-#define GPIO_PIN5_PAD_STRENGTH_SET(x) WLAN_GPIO_PIN5_PAD_STRENGTH_SET(x)
-#define GPIO_PIN5_PAD_DRIVER_MSB WLAN_GPIO_PIN5_PAD_DRIVER_MSB
-#define GPIO_PIN5_PAD_DRIVER_LSB WLAN_GPIO_PIN5_PAD_DRIVER_LSB
-#define GPIO_PIN5_PAD_DRIVER_MASK WLAN_GPIO_PIN5_PAD_DRIVER_MASK
-#define GPIO_PIN5_PAD_DRIVER_GET(x) WLAN_GPIO_PIN5_PAD_DRIVER_GET(x)
-#define GPIO_PIN5_PAD_DRIVER_SET(x) WLAN_GPIO_PIN5_PAD_DRIVER_SET(x)
-#define GPIO_PIN5_SOURCE_MSB WLAN_GPIO_PIN5_SOURCE_MSB
-#define GPIO_PIN5_SOURCE_LSB WLAN_GPIO_PIN5_SOURCE_LSB
-#define GPIO_PIN5_SOURCE_MASK WLAN_GPIO_PIN5_SOURCE_MASK
-#define GPIO_PIN5_SOURCE_GET(x) WLAN_GPIO_PIN5_SOURCE_GET(x)
-#define GPIO_PIN5_SOURCE_SET(x) WLAN_GPIO_PIN5_SOURCE_SET(x)
-#define GPIO_PIN6_ADDRESS WLAN_GPIO_PIN6_ADDRESS
-#define GPIO_PIN6_OFFSET WLAN_GPIO_PIN6_OFFSET
-#define GPIO_PIN6_CONFIG_MSB WLAN_GPIO_PIN6_CONFIG_MSB
-#define GPIO_PIN6_CONFIG_LSB WLAN_GPIO_PIN6_CONFIG_LSB
-#define GPIO_PIN6_CONFIG_MASK WLAN_GPIO_PIN6_CONFIG_MASK
-#define GPIO_PIN6_CONFIG_GET(x) WLAN_GPIO_PIN6_CONFIG_GET(x)
-#define GPIO_PIN6_CONFIG_SET(x) WLAN_GPIO_PIN6_CONFIG_SET(x)
-#define GPIO_PIN6_WAKEUP_ENABLE_MSB WLAN_GPIO_PIN6_WAKEUP_ENABLE_MSB
-#define GPIO_PIN6_WAKEUP_ENABLE_LSB WLAN_GPIO_PIN6_WAKEUP_ENABLE_LSB
-#define GPIO_PIN6_WAKEUP_ENABLE_MASK WLAN_GPIO_PIN6_WAKEUP_ENABLE_MASK
-#define GPIO_PIN6_WAKEUP_ENABLE_GET(x) WLAN_GPIO_PIN6_WAKEUP_ENABLE_GET(x)
-#define GPIO_PIN6_WAKEUP_ENABLE_SET(x) WLAN_GPIO_PIN6_WAKEUP_ENABLE_SET(x)
-#define GPIO_PIN6_INT_TYPE_MSB WLAN_GPIO_PIN6_INT_TYPE_MSB
-#define GPIO_PIN6_INT_TYPE_LSB WLAN_GPIO_PIN6_INT_TYPE_LSB
-#define GPIO_PIN6_INT_TYPE_MASK WLAN_GPIO_PIN6_INT_TYPE_MASK
-#define GPIO_PIN6_INT_TYPE_GET(x) WLAN_GPIO_PIN6_INT_TYPE_GET(x)
-#define GPIO_PIN6_INT_TYPE_SET(x) WLAN_GPIO_PIN6_INT_TYPE_SET(x)
-#define GPIO_PIN6_PAD_PULL_MSB WLAN_GPIO_PIN6_PAD_PULL_MSB
-#define GPIO_PIN6_PAD_PULL_LSB WLAN_GPIO_PIN6_PAD_PULL_LSB
-#define GPIO_PIN6_PAD_PULL_MASK WLAN_GPIO_PIN6_PAD_PULL_MASK
-#define GPIO_PIN6_PAD_PULL_GET(x) WLAN_GPIO_PIN6_PAD_PULL_GET(x)
-#define GPIO_PIN6_PAD_PULL_SET(x) WLAN_GPIO_PIN6_PAD_PULL_SET(x)
-#define GPIO_PIN6_PAD_STRENGTH_MSB WLAN_GPIO_PIN6_PAD_STRENGTH_MSB
-#define GPIO_PIN6_PAD_STRENGTH_LSB WLAN_GPIO_PIN6_PAD_STRENGTH_LSB
-#define GPIO_PIN6_PAD_STRENGTH_MASK WLAN_GPIO_PIN6_PAD_STRENGTH_MASK
-#define GPIO_PIN6_PAD_STRENGTH_GET(x) WLAN_GPIO_PIN6_PAD_STRENGTH_GET(x)
-#define GPIO_PIN6_PAD_STRENGTH_SET(x) WLAN_GPIO_PIN6_PAD_STRENGTH_SET(x)
-#define GPIO_PIN6_PAD_DRIVER_MSB WLAN_GPIO_PIN6_PAD_DRIVER_MSB
-#define GPIO_PIN6_PAD_DRIVER_LSB WLAN_GPIO_PIN6_PAD_DRIVER_LSB
-#define GPIO_PIN6_PAD_DRIVER_MASK WLAN_GPIO_PIN6_PAD_DRIVER_MASK
-#define GPIO_PIN6_PAD_DRIVER_GET(x) WLAN_GPIO_PIN6_PAD_DRIVER_GET(x)
-#define GPIO_PIN6_PAD_DRIVER_SET(x) WLAN_GPIO_PIN6_PAD_DRIVER_SET(x)
-#define GPIO_PIN6_SOURCE_MSB WLAN_GPIO_PIN6_SOURCE_MSB
-#define GPIO_PIN6_SOURCE_LSB WLAN_GPIO_PIN6_SOURCE_LSB
-#define GPIO_PIN6_SOURCE_MASK WLAN_GPIO_PIN6_SOURCE_MASK
-#define GPIO_PIN6_SOURCE_GET(x) WLAN_GPIO_PIN6_SOURCE_GET(x)
-#define GPIO_PIN6_SOURCE_SET(x) WLAN_GPIO_PIN6_SOURCE_SET(x)
-#define GPIO_PIN7_ADDRESS WLAN_GPIO_PIN7_ADDRESS
-#define GPIO_PIN7_OFFSET WLAN_GPIO_PIN7_OFFSET
-#define GPIO_PIN7_CONFIG_MSB WLAN_GPIO_PIN7_CONFIG_MSB
-#define GPIO_PIN7_CONFIG_LSB WLAN_GPIO_PIN7_CONFIG_LSB
-#define GPIO_PIN7_CONFIG_MASK WLAN_GPIO_PIN7_CONFIG_MASK
-#define GPIO_PIN7_CONFIG_GET(x) WLAN_GPIO_PIN7_CONFIG_GET(x)
-#define GPIO_PIN7_CONFIG_SET(x) WLAN_GPIO_PIN7_CONFIG_SET(x)
-#define GPIO_PIN7_WAKEUP_ENABLE_MSB WLAN_GPIO_PIN7_WAKEUP_ENABLE_MSB
-#define GPIO_PIN7_WAKEUP_ENABLE_LSB WLAN_GPIO_PIN7_WAKEUP_ENABLE_LSB
-#define GPIO_PIN7_WAKEUP_ENABLE_MASK WLAN_GPIO_PIN7_WAKEUP_ENABLE_MASK
-#define GPIO_PIN7_WAKEUP_ENABLE_GET(x) WLAN_GPIO_PIN7_WAKEUP_ENABLE_GET(x)
-#define GPIO_PIN7_WAKEUP_ENABLE_SET(x) WLAN_GPIO_PIN7_WAKEUP_ENABLE_SET(x)
-#define GPIO_PIN7_INT_TYPE_MSB WLAN_GPIO_PIN7_INT_TYPE_MSB
-#define GPIO_PIN7_INT_TYPE_LSB WLAN_GPIO_PIN7_INT_TYPE_LSB
-#define GPIO_PIN7_INT_TYPE_MASK WLAN_GPIO_PIN7_INT_TYPE_MASK
-#define GPIO_PIN7_INT_TYPE_GET(x) WLAN_GPIO_PIN7_INT_TYPE_GET(x)
-#define GPIO_PIN7_INT_TYPE_SET(x) WLAN_GPIO_PIN7_INT_TYPE_SET(x)
-#define GPIO_PIN7_PAD_PULL_MSB WLAN_GPIO_PIN7_PAD_PULL_MSB
-#define GPIO_PIN7_PAD_PULL_LSB WLAN_GPIO_PIN7_PAD_PULL_LSB
-#define GPIO_PIN7_PAD_PULL_MASK WLAN_GPIO_PIN7_PAD_PULL_MASK
-#define GPIO_PIN7_PAD_PULL_GET(x) WLAN_GPIO_PIN7_PAD_PULL_GET(x)
-#define GPIO_PIN7_PAD_PULL_SET(x) WLAN_GPIO_PIN7_PAD_PULL_SET(x)
-#define GPIO_PIN7_PAD_STRENGTH_MSB WLAN_GPIO_PIN7_PAD_STRENGTH_MSB
-#define GPIO_PIN7_PAD_STRENGTH_LSB WLAN_GPIO_PIN7_PAD_STRENGTH_LSB
-#define GPIO_PIN7_PAD_STRENGTH_MASK WLAN_GPIO_PIN7_PAD_STRENGTH_MASK
-#define GPIO_PIN7_PAD_STRENGTH_GET(x) WLAN_GPIO_PIN7_PAD_STRENGTH_GET(x)
-#define GPIO_PIN7_PAD_STRENGTH_SET(x) WLAN_GPIO_PIN7_PAD_STRENGTH_SET(x)
-#define GPIO_PIN7_PAD_DRIVER_MSB WLAN_GPIO_PIN7_PAD_DRIVER_MSB
-#define GPIO_PIN7_PAD_DRIVER_LSB WLAN_GPIO_PIN7_PAD_DRIVER_LSB
-#define GPIO_PIN7_PAD_DRIVER_MASK WLAN_GPIO_PIN7_PAD_DRIVER_MASK
-#define GPIO_PIN7_PAD_DRIVER_GET(x) WLAN_GPIO_PIN7_PAD_DRIVER_GET(x)
-#define GPIO_PIN7_PAD_DRIVER_SET(x) WLAN_GPIO_PIN7_PAD_DRIVER_SET(x)
-#define GPIO_PIN7_SOURCE_MSB WLAN_GPIO_PIN7_SOURCE_MSB
-#define GPIO_PIN7_SOURCE_LSB WLAN_GPIO_PIN7_SOURCE_LSB
-#define GPIO_PIN7_SOURCE_MASK WLAN_GPIO_PIN7_SOURCE_MASK
-#define GPIO_PIN7_SOURCE_GET(x) WLAN_GPIO_PIN7_SOURCE_GET(x)
-#define GPIO_PIN7_SOURCE_SET(x) WLAN_GPIO_PIN7_SOURCE_SET(x)
-#define GPIO_PIN8_ADDRESS WLAN_GPIO_PIN8_ADDRESS
-#define GPIO_PIN8_OFFSET WLAN_GPIO_PIN8_OFFSET
-#define GPIO_PIN8_CONFIG_MSB WLAN_GPIO_PIN8_CONFIG_MSB
-#define GPIO_PIN8_CONFIG_LSB WLAN_GPIO_PIN8_CONFIG_LSB
-#define GPIO_PIN8_CONFIG_MASK WLAN_GPIO_PIN8_CONFIG_MASK
-#define GPIO_PIN8_CONFIG_GET(x) WLAN_GPIO_PIN8_CONFIG_GET(x)
-#define GPIO_PIN8_CONFIG_SET(x) WLAN_GPIO_PIN8_CONFIG_SET(x)
-#define GPIO_PIN8_WAKEUP_ENABLE_MSB WLAN_GPIO_PIN8_WAKEUP_ENABLE_MSB
-#define GPIO_PIN8_WAKEUP_ENABLE_LSB WLAN_GPIO_PIN8_WAKEUP_ENABLE_LSB
-#define GPIO_PIN8_WAKEUP_ENABLE_MASK WLAN_GPIO_PIN8_WAKEUP_ENABLE_MASK
-#define GPIO_PIN8_WAKEUP_ENABLE_GET(x) WLAN_GPIO_PIN8_WAKEUP_ENABLE_GET(x)
-#define GPIO_PIN8_WAKEUP_ENABLE_SET(x) WLAN_GPIO_PIN8_WAKEUP_ENABLE_SET(x)
-#define GPIO_PIN8_INT_TYPE_MSB WLAN_GPIO_PIN8_INT_TYPE_MSB
-#define GPIO_PIN8_INT_TYPE_LSB WLAN_GPIO_PIN8_INT_TYPE_LSB
-#define GPIO_PIN8_INT_TYPE_MASK WLAN_GPIO_PIN8_INT_TYPE_MASK
-#define GPIO_PIN8_INT_TYPE_GET(x) WLAN_GPIO_PIN8_INT_TYPE_GET(x)
-#define GPIO_PIN8_INT_TYPE_SET(x) WLAN_GPIO_PIN8_INT_TYPE_SET(x)
-#define GPIO_PIN8_PAD_PULL_MSB WLAN_GPIO_PIN8_PAD_PULL_MSB
-#define GPIO_PIN8_PAD_PULL_LSB WLAN_GPIO_PIN8_PAD_PULL_LSB
-#define GPIO_PIN8_PAD_PULL_MASK WLAN_GPIO_PIN8_PAD_PULL_MASK
-#define GPIO_PIN8_PAD_PULL_GET(x) WLAN_GPIO_PIN8_PAD_PULL_GET(x)
-#define GPIO_PIN8_PAD_PULL_SET(x) WLAN_GPIO_PIN8_PAD_PULL_SET(x)
-#define GPIO_PIN8_PAD_STRENGTH_MSB WLAN_GPIO_PIN8_PAD_STRENGTH_MSB
-#define GPIO_PIN8_PAD_STRENGTH_LSB WLAN_GPIO_PIN8_PAD_STRENGTH_LSB
-#define GPIO_PIN8_PAD_STRENGTH_MASK WLAN_GPIO_PIN8_PAD_STRENGTH_MASK
-#define GPIO_PIN8_PAD_STRENGTH_GET(x) WLAN_GPIO_PIN8_PAD_STRENGTH_GET(x)
-#define GPIO_PIN8_PAD_STRENGTH_SET(x) WLAN_GPIO_PIN8_PAD_STRENGTH_SET(x)
-#define GPIO_PIN8_PAD_DRIVER_MSB WLAN_GPIO_PIN8_PAD_DRIVER_MSB
-#define GPIO_PIN8_PAD_DRIVER_LSB WLAN_GPIO_PIN8_PAD_DRIVER_LSB
-#define GPIO_PIN8_PAD_DRIVER_MASK WLAN_GPIO_PIN8_PAD_DRIVER_MASK
-#define GPIO_PIN8_PAD_DRIVER_GET(x) WLAN_GPIO_PIN8_PAD_DRIVER_GET(x)
-#define GPIO_PIN8_PAD_DRIVER_SET(x) WLAN_GPIO_PIN8_PAD_DRIVER_SET(x)
-#define GPIO_PIN8_SOURCE_MSB WLAN_GPIO_PIN8_SOURCE_MSB
-#define GPIO_PIN8_SOURCE_LSB WLAN_GPIO_PIN8_SOURCE_LSB
-#define GPIO_PIN8_SOURCE_MASK WLAN_GPIO_PIN8_SOURCE_MASK
-#define GPIO_PIN8_SOURCE_GET(x) WLAN_GPIO_PIN8_SOURCE_GET(x)
-#define GPIO_PIN8_SOURCE_SET(x) WLAN_GPIO_PIN8_SOURCE_SET(x)
-#define GPIO_PIN9_ADDRESS WLAN_GPIO_PIN9_ADDRESS
-#define GPIO_PIN9_OFFSET WLAN_GPIO_PIN9_OFFSET
-#define GPIO_PIN9_CONFIG_MSB WLAN_GPIO_PIN9_CONFIG_MSB
-#define GPIO_PIN9_CONFIG_LSB WLAN_GPIO_PIN9_CONFIG_LSB
-#define GPIO_PIN9_CONFIG_MASK WLAN_GPIO_PIN9_CONFIG_MASK
-#define GPIO_PIN9_CONFIG_GET(x) WLAN_GPIO_PIN9_CONFIG_GET(x)
-#define GPIO_PIN9_CONFIG_SET(x) WLAN_GPIO_PIN9_CONFIG_SET(x)
-#define GPIO_PIN9_WAKEUP_ENABLE_MSB WLAN_GPIO_PIN9_WAKEUP_ENABLE_MSB
-#define GPIO_PIN9_WAKEUP_ENABLE_LSB WLAN_GPIO_PIN9_WAKEUP_ENABLE_LSB
-#define GPIO_PIN9_WAKEUP_ENABLE_MASK WLAN_GPIO_PIN9_WAKEUP_ENABLE_MASK
-#define GPIO_PIN9_WAKEUP_ENABLE_GET(x) WLAN_GPIO_PIN9_WAKEUP_ENABLE_GET(x)
-#define GPIO_PIN9_WAKEUP_ENABLE_SET(x) WLAN_GPIO_PIN9_WAKEUP_ENABLE_SET(x)
-#define GPIO_PIN9_INT_TYPE_MSB WLAN_GPIO_PIN9_INT_TYPE_MSB
-#define GPIO_PIN9_INT_TYPE_LSB WLAN_GPIO_PIN9_INT_TYPE_LSB
-#define GPIO_PIN9_INT_TYPE_MASK WLAN_GPIO_PIN9_INT_TYPE_MASK
-#define GPIO_PIN9_INT_TYPE_GET(x) WLAN_GPIO_PIN9_INT_TYPE_GET(x)
-#define GPIO_PIN9_INT_TYPE_SET(x) WLAN_GPIO_PIN9_INT_TYPE_SET(x)
-#define GPIO_PIN9_PAD_PULL_MSB WLAN_GPIO_PIN9_PAD_PULL_MSB
-#define GPIO_PIN9_PAD_PULL_LSB WLAN_GPIO_PIN9_PAD_PULL_LSB
-#define GPIO_PIN9_PAD_PULL_MASK WLAN_GPIO_PIN9_PAD_PULL_MASK
-#define GPIO_PIN9_PAD_PULL_GET(x) WLAN_GPIO_PIN9_PAD_PULL_GET(x)
-#define GPIO_PIN9_PAD_PULL_SET(x) WLAN_GPIO_PIN9_PAD_PULL_SET(x)
-#define GPIO_PIN9_PAD_STRENGTH_MSB WLAN_GPIO_PIN9_PAD_STRENGTH_MSB
-#define GPIO_PIN9_PAD_STRENGTH_LSB WLAN_GPIO_PIN9_PAD_STRENGTH_LSB
-#define GPIO_PIN9_PAD_STRENGTH_MASK WLAN_GPIO_PIN9_PAD_STRENGTH_MASK
-#define GPIO_PIN9_PAD_STRENGTH_GET(x) WLAN_GPIO_PIN9_PAD_STRENGTH_GET(x)
-#define GPIO_PIN9_PAD_STRENGTH_SET(x) WLAN_GPIO_PIN9_PAD_STRENGTH_SET(x)
-#define GPIO_PIN9_PAD_DRIVER_MSB WLAN_GPIO_PIN9_PAD_DRIVER_MSB
-#define GPIO_PIN9_PAD_DRIVER_LSB WLAN_GPIO_PIN9_PAD_DRIVER_LSB
-#define GPIO_PIN9_PAD_DRIVER_MASK WLAN_GPIO_PIN9_PAD_DRIVER_MASK
-#define GPIO_PIN9_PAD_DRIVER_GET(x) WLAN_GPIO_PIN9_PAD_DRIVER_GET(x)
-#define GPIO_PIN9_PAD_DRIVER_SET(x) WLAN_GPIO_PIN9_PAD_DRIVER_SET(x)
-#define GPIO_PIN9_SOURCE_MSB WLAN_GPIO_PIN9_SOURCE_MSB
-#define GPIO_PIN9_SOURCE_LSB WLAN_GPIO_PIN9_SOURCE_LSB
-#define GPIO_PIN9_SOURCE_MASK WLAN_GPIO_PIN9_SOURCE_MASK
-#define GPIO_PIN9_SOURCE_GET(x) WLAN_GPIO_PIN9_SOURCE_GET(x)
-#define GPIO_PIN9_SOURCE_SET(x) WLAN_GPIO_PIN9_SOURCE_SET(x)
-#define GPIO_PIN10_ADDRESS WLAN_GPIO_PIN10_ADDRESS
-#define GPIO_PIN10_OFFSET WLAN_GPIO_PIN10_OFFSET
-#define GPIO_PIN10_CONFIG_MSB WLAN_GPIO_PIN10_CONFIG_MSB
-#define GPIO_PIN10_CONFIG_LSB WLAN_GPIO_PIN10_CONFIG_LSB
-#define GPIO_PIN10_CONFIG_MASK WLAN_GPIO_PIN10_CONFIG_MASK
-#define GPIO_PIN10_CONFIG_GET(x) WLAN_GPIO_PIN10_CONFIG_GET(x)
-#define GPIO_PIN10_CONFIG_SET(x) WLAN_GPIO_PIN10_CONFIG_SET(x)
-#define GPIO_PIN10_WAKEUP_ENABLE_MSB WLAN_GPIO_PIN10_WAKEUP_ENABLE_MSB
-#define GPIO_PIN10_WAKEUP_ENABLE_LSB WLAN_GPIO_PIN10_WAKEUP_ENABLE_LSB
-#define GPIO_PIN10_WAKEUP_ENABLE_MASK WLAN_GPIO_PIN10_WAKEUP_ENABLE_MASK
-#define GPIO_PIN10_WAKEUP_ENABLE_GET(x) WLAN_GPIO_PIN10_WAKEUP_ENABLE_GET(x)
-#define GPIO_PIN10_WAKEUP_ENABLE_SET(x) WLAN_GPIO_PIN10_WAKEUP_ENABLE_SET(x)
-#define GPIO_PIN10_INT_TYPE_MSB WLAN_GPIO_PIN10_INT_TYPE_MSB
-#define GPIO_PIN10_INT_TYPE_LSB WLAN_GPIO_PIN10_INT_TYPE_LSB
-#define GPIO_PIN10_INT_TYPE_MASK WLAN_GPIO_PIN10_INT_TYPE_MASK
-#define GPIO_PIN10_INT_TYPE_GET(x) WLAN_GPIO_PIN10_INT_TYPE_GET(x)
-#define GPIO_PIN10_INT_TYPE_SET(x) WLAN_GPIO_PIN10_INT_TYPE_SET(x)
-#define GPIO_PIN10_PAD_PULL_MSB WLAN_GPIO_PIN10_PAD_PULL_MSB
-#define GPIO_PIN10_PAD_PULL_LSB WLAN_GPIO_PIN10_PAD_PULL_LSB
-#define GPIO_PIN10_PAD_PULL_MASK WLAN_GPIO_PIN10_PAD_PULL_MASK
-#define GPIO_PIN10_PAD_PULL_GET(x) WLAN_GPIO_PIN10_PAD_PULL_GET(x)
-#define GPIO_PIN10_PAD_PULL_SET(x) WLAN_GPIO_PIN10_PAD_PULL_SET(x)
-#define GPIO_PIN10_PAD_STRENGTH_MSB WLAN_GPIO_PIN10_PAD_STRENGTH_MSB
-#define GPIO_PIN10_PAD_STRENGTH_LSB WLAN_GPIO_PIN10_PAD_STRENGTH_LSB
-#define GPIO_PIN10_PAD_STRENGTH_MASK WLAN_GPIO_PIN10_PAD_STRENGTH_MASK
-#define GPIO_PIN10_PAD_STRENGTH_GET(x) WLAN_GPIO_PIN10_PAD_STRENGTH_GET(x)
-#define GPIO_PIN10_PAD_STRENGTH_SET(x) WLAN_GPIO_PIN10_PAD_STRENGTH_SET(x)
-#define GPIO_PIN10_PAD_DRIVER_MSB WLAN_GPIO_PIN10_PAD_DRIVER_MSB
-#define GPIO_PIN10_PAD_DRIVER_LSB WLAN_GPIO_PIN10_PAD_DRIVER_LSB
-#define GPIO_PIN10_PAD_DRIVER_MASK WLAN_GPIO_PIN10_PAD_DRIVER_MASK
-#define GPIO_PIN10_PAD_DRIVER_GET(x) WLAN_GPIO_PIN10_PAD_DRIVER_GET(x)
-#define GPIO_PIN10_PAD_DRIVER_SET(x) WLAN_GPIO_PIN10_PAD_DRIVER_SET(x)
-#define GPIO_PIN10_SOURCE_MSB WLAN_GPIO_PIN10_SOURCE_MSB
-#define GPIO_PIN10_SOURCE_LSB WLAN_GPIO_PIN10_SOURCE_LSB
-#define GPIO_PIN10_SOURCE_MASK WLAN_GPIO_PIN10_SOURCE_MASK
-#define GPIO_PIN10_SOURCE_GET(x) WLAN_GPIO_PIN10_SOURCE_GET(x)
-#define GPIO_PIN10_SOURCE_SET(x) WLAN_GPIO_PIN10_SOURCE_SET(x)
-#define GPIO_PIN11_ADDRESS WLAN_GPIO_PIN11_ADDRESS
-#define GPIO_PIN11_OFFSET WLAN_GPIO_PIN11_OFFSET
-#define GPIO_PIN11_CONFIG_MSB WLAN_GPIO_PIN11_CONFIG_MSB
-#define GPIO_PIN11_CONFIG_LSB WLAN_GPIO_PIN11_CONFIG_LSB
-#define GPIO_PIN11_CONFIG_MASK WLAN_GPIO_PIN11_CONFIG_MASK
-#define GPIO_PIN11_CONFIG_GET(x) WLAN_GPIO_PIN11_CONFIG_GET(x)
-#define GPIO_PIN11_CONFIG_SET(x) WLAN_GPIO_PIN11_CONFIG_SET(x)
-#define GPIO_PIN11_WAKEUP_ENABLE_MSB WLAN_GPIO_PIN11_WAKEUP_ENABLE_MSB
-#define GPIO_PIN11_WAKEUP_ENABLE_LSB WLAN_GPIO_PIN11_WAKEUP_ENABLE_LSB
-#define GPIO_PIN11_WAKEUP_ENABLE_MASK WLAN_GPIO_PIN11_WAKEUP_ENABLE_MASK
-#define GPIO_PIN11_WAKEUP_ENABLE_GET(x) WLAN_GPIO_PIN11_WAKEUP_ENABLE_GET(x)
-#define GPIO_PIN11_WAKEUP_ENABLE_SET(x) WLAN_GPIO_PIN11_WAKEUP_ENABLE_SET(x)
-#define GPIO_PIN11_INT_TYPE_MSB WLAN_GPIO_PIN11_INT_TYPE_MSB
-#define GPIO_PIN11_INT_TYPE_LSB WLAN_GPIO_PIN11_INT_TYPE_LSB
-#define GPIO_PIN11_INT_TYPE_MASK WLAN_GPIO_PIN11_INT_TYPE_MASK
-#define GPIO_PIN11_INT_TYPE_GET(x) WLAN_GPIO_PIN11_INT_TYPE_GET(x)
-#define GPIO_PIN11_INT_TYPE_SET(x) WLAN_GPIO_PIN11_INT_TYPE_SET(x)
-#define GPIO_PIN11_PAD_PULL_MSB WLAN_GPIO_PIN11_PAD_PULL_MSB
-#define GPIO_PIN11_PAD_PULL_LSB WLAN_GPIO_PIN11_PAD_PULL_LSB
-#define GPIO_PIN11_PAD_PULL_MASK WLAN_GPIO_PIN11_PAD_PULL_MASK
-#define GPIO_PIN11_PAD_PULL_GET(x) WLAN_GPIO_PIN11_PAD_PULL_GET(x)
-#define GPIO_PIN11_PAD_PULL_SET(x) WLAN_GPIO_PIN11_PAD_PULL_SET(x)
-#define GPIO_PIN11_PAD_STRENGTH_MSB WLAN_GPIO_PIN11_PAD_STRENGTH_MSB
-#define GPIO_PIN11_PAD_STRENGTH_LSB WLAN_GPIO_PIN11_PAD_STRENGTH_LSB
-#define GPIO_PIN11_PAD_STRENGTH_MASK WLAN_GPIO_PIN11_PAD_STRENGTH_MASK
-#define GPIO_PIN11_PAD_STRENGTH_GET(x) WLAN_GPIO_PIN11_PAD_STRENGTH_GET(x)
-#define GPIO_PIN11_PAD_STRENGTH_SET(x) WLAN_GPIO_PIN11_PAD_STRENGTH_SET(x)
-#define GPIO_PIN11_PAD_DRIVER_MSB WLAN_GPIO_PIN11_PAD_DRIVER_MSB
-#define GPIO_PIN11_PAD_DRIVER_LSB WLAN_GPIO_PIN11_PAD_DRIVER_LSB
-#define GPIO_PIN11_PAD_DRIVER_MASK WLAN_GPIO_PIN11_PAD_DRIVER_MASK
-#define GPIO_PIN11_PAD_DRIVER_GET(x) WLAN_GPIO_PIN11_PAD_DRIVER_GET(x)
-#define GPIO_PIN11_PAD_DRIVER_SET(x) WLAN_GPIO_PIN11_PAD_DRIVER_SET(x)
-#define GPIO_PIN11_SOURCE_MSB WLAN_GPIO_PIN11_SOURCE_MSB
-#define GPIO_PIN11_SOURCE_LSB WLAN_GPIO_PIN11_SOURCE_LSB
-#define GPIO_PIN11_SOURCE_MASK WLAN_GPIO_PIN11_SOURCE_MASK
-#define GPIO_PIN11_SOURCE_GET(x) WLAN_GPIO_PIN11_SOURCE_GET(x)
-#define GPIO_PIN11_SOURCE_SET(x) WLAN_GPIO_PIN11_SOURCE_SET(x)
-#define GPIO_PIN12_ADDRESS WLAN_GPIO_PIN12_ADDRESS
-#define GPIO_PIN12_OFFSET WLAN_GPIO_PIN12_OFFSET
-#define GPIO_PIN12_CONFIG_MSB WLAN_GPIO_PIN12_CONFIG_MSB
-#define GPIO_PIN12_CONFIG_LSB WLAN_GPIO_PIN12_CONFIG_LSB
-#define GPIO_PIN12_CONFIG_MASK WLAN_GPIO_PIN12_CONFIG_MASK
-#define GPIO_PIN12_CONFIG_GET(x) WLAN_GPIO_PIN12_CONFIG_GET(x)
-#define GPIO_PIN12_CONFIG_SET(x) WLAN_GPIO_PIN12_CONFIG_SET(x)
-#define GPIO_PIN12_WAKEUP_ENABLE_MSB WLAN_GPIO_PIN12_WAKEUP_ENABLE_MSB
-#define GPIO_PIN12_WAKEUP_ENABLE_LSB WLAN_GPIO_PIN12_WAKEUP_ENABLE_LSB
-#define GPIO_PIN12_WAKEUP_ENABLE_MASK WLAN_GPIO_PIN12_WAKEUP_ENABLE_MASK
-#define GPIO_PIN12_WAKEUP_ENABLE_GET(x) WLAN_GPIO_PIN12_WAKEUP_ENABLE_GET(x)
-#define GPIO_PIN12_WAKEUP_ENABLE_SET(x) WLAN_GPIO_PIN12_WAKEUP_ENABLE_SET(x)
-#define GPIO_PIN12_INT_TYPE_MSB WLAN_GPIO_PIN12_INT_TYPE_MSB
-#define GPIO_PIN12_INT_TYPE_LSB WLAN_GPIO_PIN12_INT_TYPE_LSB
-#define GPIO_PIN12_INT_TYPE_MASK WLAN_GPIO_PIN12_INT_TYPE_MASK
-#define GPIO_PIN12_INT_TYPE_GET(x) WLAN_GPIO_PIN12_INT_TYPE_GET(x)
-#define GPIO_PIN12_INT_TYPE_SET(x) WLAN_GPIO_PIN12_INT_TYPE_SET(x)
-#define GPIO_PIN12_PAD_PULL_MSB WLAN_GPIO_PIN12_PAD_PULL_MSB
-#define GPIO_PIN12_PAD_PULL_LSB WLAN_GPIO_PIN12_PAD_PULL_LSB
-#define GPIO_PIN12_PAD_PULL_MASK WLAN_GPIO_PIN12_PAD_PULL_MASK
-#define GPIO_PIN12_PAD_PULL_GET(x) WLAN_GPIO_PIN12_PAD_PULL_GET(x)
-#define GPIO_PIN12_PAD_PULL_SET(x) WLAN_GPIO_PIN12_PAD_PULL_SET(x)
-#define GPIO_PIN12_PAD_STRENGTH_MSB WLAN_GPIO_PIN12_PAD_STRENGTH_MSB
-#define GPIO_PIN12_PAD_STRENGTH_LSB WLAN_GPIO_PIN12_PAD_STRENGTH_LSB
-#define GPIO_PIN12_PAD_STRENGTH_MASK WLAN_GPIO_PIN12_PAD_STRENGTH_MASK
-#define GPIO_PIN12_PAD_STRENGTH_GET(x) WLAN_GPIO_PIN12_PAD_STRENGTH_GET(x)
-#define GPIO_PIN12_PAD_STRENGTH_SET(x) WLAN_GPIO_PIN12_PAD_STRENGTH_SET(x)
-#define GPIO_PIN12_PAD_DRIVER_MSB WLAN_GPIO_PIN12_PAD_DRIVER_MSB
-#define GPIO_PIN12_PAD_DRIVER_LSB WLAN_GPIO_PIN12_PAD_DRIVER_LSB
-#define GPIO_PIN12_PAD_DRIVER_MASK WLAN_GPIO_PIN12_PAD_DRIVER_MASK
-#define GPIO_PIN12_PAD_DRIVER_GET(x) WLAN_GPIO_PIN12_PAD_DRIVER_GET(x)
-#define GPIO_PIN12_PAD_DRIVER_SET(x) WLAN_GPIO_PIN12_PAD_DRIVER_SET(x)
-#define GPIO_PIN12_SOURCE_MSB WLAN_GPIO_PIN12_SOURCE_MSB
-#define GPIO_PIN12_SOURCE_LSB WLAN_GPIO_PIN12_SOURCE_LSB
-#define GPIO_PIN12_SOURCE_MASK WLAN_GPIO_PIN12_SOURCE_MASK
-#define GPIO_PIN12_SOURCE_GET(x) WLAN_GPIO_PIN12_SOURCE_GET(x)
-#define GPIO_PIN12_SOURCE_SET(x) WLAN_GPIO_PIN12_SOURCE_SET(x)
-#define GPIO_PIN13_ADDRESS WLAN_GPIO_PIN13_ADDRESS
-#define GPIO_PIN13_OFFSET WLAN_GPIO_PIN13_OFFSET
-#define GPIO_PIN13_CONFIG_MSB WLAN_GPIO_PIN13_CONFIG_MSB
-#define GPIO_PIN13_CONFIG_LSB WLAN_GPIO_PIN13_CONFIG_LSB
-#define GPIO_PIN13_CONFIG_MASK WLAN_GPIO_PIN13_CONFIG_MASK
-#define GPIO_PIN13_CONFIG_GET(x) WLAN_GPIO_PIN13_CONFIG_GET(x)
-#define GPIO_PIN13_CONFIG_SET(x) WLAN_GPIO_PIN13_CONFIG_SET(x)
-#define GPIO_PIN13_WAKEUP_ENABLE_MSB WLAN_GPIO_PIN13_WAKEUP_ENABLE_MSB
-#define GPIO_PIN13_WAKEUP_ENABLE_LSB WLAN_GPIO_PIN13_WAKEUP_ENABLE_LSB
-#define GPIO_PIN13_WAKEUP_ENABLE_MASK WLAN_GPIO_PIN13_WAKEUP_ENABLE_MASK
-#define GPIO_PIN13_WAKEUP_ENABLE_GET(x) WLAN_GPIO_PIN13_WAKEUP_ENABLE_GET(x)
-#define GPIO_PIN13_WAKEUP_ENABLE_SET(x) WLAN_GPIO_PIN13_WAKEUP_ENABLE_SET(x)
-#define GPIO_PIN13_INT_TYPE_MSB WLAN_GPIO_PIN13_INT_TYPE_MSB
-#define GPIO_PIN13_INT_TYPE_LSB WLAN_GPIO_PIN13_INT_TYPE_LSB
-#define GPIO_PIN13_INT_TYPE_MASK WLAN_GPIO_PIN13_INT_TYPE_MASK
-#define GPIO_PIN13_INT_TYPE_GET(x) WLAN_GPIO_PIN13_INT_TYPE_GET(x)
-#define GPIO_PIN13_INT_TYPE_SET(x) WLAN_GPIO_PIN13_INT_TYPE_SET(x)
-#define GPIO_PIN13_PAD_PULL_MSB WLAN_GPIO_PIN13_PAD_PULL_MSB
-#define GPIO_PIN13_PAD_PULL_LSB WLAN_GPIO_PIN13_PAD_PULL_LSB
-#define GPIO_PIN13_PAD_PULL_MASK WLAN_GPIO_PIN13_PAD_PULL_MASK
-#define GPIO_PIN13_PAD_PULL_GET(x) WLAN_GPIO_PIN13_PAD_PULL_GET(x)
-#define GPIO_PIN13_PAD_PULL_SET(x) WLAN_GPIO_PIN13_PAD_PULL_SET(x)
-#define GPIO_PIN13_PAD_STRENGTH_MSB WLAN_GPIO_PIN13_PAD_STRENGTH_MSB
-#define GPIO_PIN13_PAD_STRENGTH_LSB WLAN_GPIO_PIN13_PAD_STRENGTH_LSB
-#define GPIO_PIN13_PAD_STRENGTH_MASK WLAN_GPIO_PIN13_PAD_STRENGTH_MASK
-#define GPIO_PIN13_PAD_STRENGTH_GET(x) WLAN_GPIO_PIN13_PAD_STRENGTH_GET(x)
-#define GPIO_PIN13_PAD_STRENGTH_SET(x) WLAN_GPIO_PIN13_PAD_STRENGTH_SET(x)
-#define GPIO_PIN13_PAD_DRIVER_MSB WLAN_GPIO_PIN13_PAD_DRIVER_MSB
-#define GPIO_PIN13_PAD_DRIVER_LSB WLAN_GPIO_PIN13_PAD_DRIVER_LSB
-#define GPIO_PIN13_PAD_DRIVER_MASK WLAN_GPIO_PIN13_PAD_DRIVER_MASK
-#define GPIO_PIN13_PAD_DRIVER_GET(x) WLAN_GPIO_PIN13_PAD_DRIVER_GET(x)
-#define GPIO_PIN13_PAD_DRIVER_SET(x) WLAN_GPIO_PIN13_PAD_DRIVER_SET(x)
-#define GPIO_PIN13_SOURCE_MSB WLAN_GPIO_PIN13_SOURCE_MSB
-#define GPIO_PIN13_SOURCE_LSB WLAN_GPIO_PIN13_SOURCE_LSB
-#define GPIO_PIN13_SOURCE_MASK WLAN_GPIO_PIN13_SOURCE_MASK
-#define GPIO_PIN13_SOURCE_GET(x) WLAN_GPIO_PIN13_SOURCE_GET(x)
-#define GPIO_PIN13_SOURCE_SET(x) WLAN_GPIO_PIN13_SOURCE_SET(x)
-#define GPIO_PIN14_ADDRESS WLAN_GPIO_PIN14_ADDRESS
-#define GPIO_PIN14_OFFSET WLAN_GPIO_PIN14_OFFSET
-#define GPIO_PIN14_CONFIG_MSB WLAN_GPIO_PIN14_CONFIG_MSB
-#define GPIO_PIN14_CONFIG_LSB WLAN_GPIO_PIN14_CONFIG_LSB
-#define GPIO_PIN14_CONFIG_MASK WLAN_GPIO_PIN14_CONFIG_MASK
-#define GPIO_PIN14_CONFIG_GET(x) WLAN_GPIO_PIN14_CONFIG_GET(x)
-#define GPIO_PIN14_CONFIG_SET(x) WLAN_GPIO_PIN14_CONFIG_SET(x)
-#define GPIO_PIN14_WAKEUP_ENABLE_MSB WLAN_GPIO_PIN14_WAKEUP_ENABLE_MSB
-#define GPIO_PIN14_WAKEUP_ENABLE_LSB WLAN_GPIO_PIN14_WAKEUP_ENABLE_LSB
-#define GPIO_PIN14_WAKEUP_ENABLE_MASK WLAN_GPIO_PIN14_WAKEUP_ENABLE_MASK
-#define GPIO_PIN14_WAKEUP_ENABLE_GET(x) WLAN_GPIO_PIN14_WAKEUP_ENABLE_GET(x)
-#define GPIO_PIN14_WAKEUP_ENABLE_SET(x) WLAN_GPIO_PIN14_WAKEUP_ENABLE_SET(x)
-#define GPIO_PIN14_INT_TYPE_MSB WLAN_GPIO_PIN14_INT_TYPE_MSB
-#define GPIO_PIN14_INT_TYPE_LSB WLAN_GPIO_PIN14_INT_TYPE_LSB
-#define GPIO_PIN14_INT_TYPE_MASK WLAN_GPIO_PIN14_INT_TYPE_MASK
-#define GPIO_PIN14_INT_TYPE_GET(x) WLAN_GPIO_PIN14_INT_TYPE_GET(x)
-#define GPIO_PIN14_INT_TYPE_SET(x) WLAN_GPIO_PIN14_INT_TYPE_SET(x)
-#define GPIO_PIN14_PAD_PULL_MSB WLAN_GPIO_PIN14_PAD_PULL_MSB
-#define GPIO_PIN14_PAD_PULL_LSB WLAN_GPIO_PIN14_PAD_PULL_LSB
-#define GPIO_PIN14_PAD_PULL_MASK WLAN_GPIO_PIN14_PAD_PULL_MASK
-#define GPIO_PIN14_PAD_PULL_GET(x) WLAN_GPIO_PIN14_PAD_PULL_GET(x)
-#define GPIO_PIN14_PAD_PULL_SET(x) WLAN_GPIO_PIN14_PAD_PULL_SET(x)
-#define GPIO_PIN14_PAD_STRENGTH_MSB WLAN_GPIO_PIN14_PAD_STRENGTH_MSB
-#define GPIO_PIN14_PAD_STRENGTH_LSB WLAN_GPIO_PIN14_PAD_STRENGTH_LSB
-#define GPIO_PIN14_PAD_STRENGTH_MASK WLAN_GPIO_PIN14_PAD_STRENGTH_MASK
-#define GPIO_PIN14_PAD_STRENGTH_GET(x) WLAN_GPIO_PIN14_PAD_STRENGTH_GET(x)
-#define GPIO_PIN14_PAD_STRENGTH_SET(x) WLAN_GPIO_PIN14_PAD_STRENGTH_SET(x)
-#define GPIO_PIN14_PAD_DRIVER_MSB WLAN_GPIO_PIN14_PAD_DRIVER_MSB
-#define GPIO_PIN14_PAD_DRIVER_LSB WLAN_GPIO_PIN14_PAD_DRIVER_LSB
-#define GPIO_PIN14_PAD_DRIVER_MASK WLAN_GPIO_PIN14_PAD_DRIVER_MASK
-#define GPIO_PIN14_PAD_DRIVER_GET(x) WLAN_GPIO_PIN14_PAD_DRIVER_GET(x)
-#define GPIO_PIN14_PAD_DRIVER_SET(x) WLAN_GPIO_PIN14_PAD_DRIVER_SET(x)
-#define GPIO_PIN14_SOURCE_MSB WLAN_GPIO_PIN14_SOURCE_MSB
-#define GPIO_PIN14_SOURCE_LSB WLAN_GPIO_PIN14_SOURCE_LSB
-#define GPIO_PIN14_SOURCE_MASK WLAN_GPIO_PIN14_SOURCE_MASK
-#define GPIO_PIN14_SOURCE_GET(x) WLAN_GPIO_PIN14_SOURCE_GET(x)
-#define GPIO_PIN14_SOURCE_SET(x) WLAN_GPIO_PIN14_SOURCE_SET(x)
-#define GPIO_PIN15_ADDRESS WLAN_GPIO_PIN15_ADDRESS
-#define GPIO_PIN15_OFFSET WLAN_GPIO_PIN15_OFFSET
-#define GPIO_PIN15_CONFIG_MSB WLAN_GPIO_PIN15_CONFIG_MSB
-#define GPIO_PIN15_CONFIG_LSB WLAN_GPIO_PIN15_CONFIG_LSB
-#define GPIO_PIN15_CONFIG_MASK WLAN_GPIO_PIN15_CONFIG_MASK
-#define GPIO_PIN15_CONFIG_GET(x) WLAN_GPIO_PIN15_CONFIG_GET(x)
-#define GPIO_PIN15_CONFIG_SET(x) WLAN_GPIO_PIN15_CONFIG_SET(x)
-#define GPIO_PIN15_WAKEUP_ENABLE_MSB WLAN_GPIO_PIN15_WAKEUP_ENABLE_MSB
-#define GPIO_PIN15_WAKEUP_ENABLE_LSB WLAN_GPIO_PIN15_WAKEUP_ENABLE_LSB
-#define GPIO_PIN15_WAKEUP_ENABLE_MASK WLAN_GPIO_PIN15_WAKEUP_ENABLE_MASK
-#define GPIO_PIN15_WAKEUP_ENABLE_GET(x) WLAN_GPIO_PIN15_WAKEUP_ENABLE_GET(x)
-#define GPIO_PIN15_WAKEUP_ENABLE_SET(x) WLAN_GPIO_PIN15_WAKEUP_ENABLE_SET(x)
-#define GPIO_PIN15_INT_TYPE_MSB WLAN_GPIO_PIN15_INT_TYPE_MSB
-#define GPIO_PIN15_INT_TYPE_LSB WLAN_GPIO_PIN15_INT_TYPE_LSB
-#define GPIO_PIN15_INT_TYPE_MASK WLAN_GPIO_PIN15_INT_TYPE_MASK
-#define GPIO_PIN15_INT_TYPE_GET(x) WLAN_GPIO_PIN15_INT_TYPE_GET(x)
-#define GPIO_PIN15_INT_TYPE_SET(x) WLAN_GPIO_PIN15_INT_TYPE_SET(x)
-#define GPIO_PIN15_PAD_PULL_MSB WLAN_GPIO_PIN15_PAD_PULL_MSB
-#define GPIO_PIN15_PAD_PULL_LSB WLAN_GPIO_PIN15_PAD_PULL_LSB
-#define GPIO_PIN15_PAD_PULL_MASK WLAN_GPIO_PIN15_PAD_PULL_MASK
-#define GPIO_PIN15_PAD_PULL_GET(x) WLAN_GPIO_PIN15_PAD_PULL_GET(x)
-#define GPIO_PIN15_PAD_PULL_SET(x) WLAN_GPIO_PIN15_PAD_PULL_SET(x)
-#define GPIO_PIN15_PAD_STRENGTH_MSB WLAN_GPIO_PIN15_PAD_STRENGTH_MSB
-#define GPIO_PIN15_PAD_STRENGTH_LSB WLAN_GPIO_PIN15_PAD_STRENGTH_LSB
-#define GPIO_PIN15_PAD_STRENGTH_MASK WLAN_GPIO_PIN15_PAD_STRENGTH_MASK
-#define GPIO_PIN15_PAD_STRENGTH_GET(x) WLAN_GPIO_PIN15_PAD_STRENGTH_GET(x)
-#define GPIO_PIN15_PAD_STRENGTH_SET(x) WLAN_GPIO_PIN15_PAD_STRENGTH_SET(x)
-#define GPIO_PIN15_PAD_DRIVER_MSB WLAN_GPIO_PIN15_PAD_DRIVER_MSB
-#define GPIO_PIN15_PAD_DRIVER_LSB WLAN_GPIO_PIN15_PAD_DRIVER_LSB
-#define GPIO_PIN15_PAD_DRIVER_MASK WLAN_GPIO_PIN15_PAD_DRIVER_MASK
-#define GPIO_PIN15_PAD_DRIVER_GET(x) WLAN_GPIO_PIN15_PAD_DRIVER_GET(x)
-#define GPIO_PIN15_PAD_DRIVER_SET(x) WLAN_GPIO_PIN15_PAD_DRIVER_SET(x)
-#define GPIO_PIN15_SOURCE_MSB WLAN_GPIO_PIN15_SOURCE_MSB
-#define GPIO_PIN15_SOURCE_LSB WLAN_GPIO_PIN15_SOURCE_LSB
-#define GPIO_PIN15_SOURCE_MASK WLAN_GPIO_PIN15_SOURCE_MASK
-#define GPIO_PIN15_SOURCE_GET(x) WLAN_GPIO_PIN15_SOURCE_GET(x)
-#define GPIO_PIN15_SOURCE_SET(x) WLAN_GPIO_PIN15_SOURCE_SET(x)
-#define GPIO_PIN16_ADDRESS WLAN_GPIO_PIN16_ADDRESS
-#define GPIO_PIN16_OFFSET WLAN_GPIO_PIN16_OFFSET
-#define GPIO_PIN16_CONFIG_MSB WLAN_GPIO_PIN16_CONFIG_MSB
-#define GPIO_PIN16_CONFIG_LSB WLAN_GPIO_PIN16_CONFIG_LSB
-#define GPIO_PIN16_CONFIG_MASK WLAN_GPIO_PIN16_CONFIG_MASK
-#define GPIO_PIN16_CONFIG_GET(x) WLAN_GPIO_PIN16_CONFIG_GET(x)
-#define GPIO_PIN16_CONFIG_SET(x) WLAN_GPIO_PIN16_CONFIG_SET(x)
-#define GPIO_PIN16_WAKEUP_ENABLE_MSB WLAN_GPIO_PIN16_WAKEUP_ENABLE_MSB
-#define GPIO_PIN16_WAKEUP_ENABLE_LSB WLAN_GPIO_PIN16_WAKEUP_ENABLE_LSB
-#define GPIO_PIN16_WAKEUP_ENABLE_MASK WLAN_GPIO_PIN16_WAKEUP_ENABLE_MASK
-#define GPIO_PIN16_WAKEUP_ENABLE_GET(x) WLAN_GPIO_PIN16_WAKEUP_ENABLE_GET(x)
-#define GPIO_PIN16_WAKEUP_ENABLE_SET(x) WLAN_GPIO_PIN16_WAKEUP_ENABLE_SET(x)
-#define GPIO_PIN16_INT_TYPE_MSB WLAN_GPIO_PIN16_INT_TYPE_MSB
-#define GPIO_PIN16_INT_TYPE_LSB WLAN_GPIO_PIN16_INT_TYPE_LSB
-#define GPIO_PIN16_INT_TYPE_MASK WLAN_GPIO_PIN16_INT_TYPE_MASK
-#define GPIO_PIN16_INT_TYPE_GET(x) WLAN_GPIO_PIN16_INT_TYPE_GET(x)
-#define GPIO_PIN16_INT_TYPE_SET(x) WLAN_GPIO_PIN16_INT_TYPE_SET(x)
-#define GPIO_PIN16_PAD_PULL_MSB WLAN_GPIO_PIN16_PAD_PULL_MSB
-#define GPIO_PIN16_PAD_PULL_LSB WLAN_GPIO_PIN16_PAD_PULL_LSB
-#define GPIO_PIN16_PAD_PULL_MASK WLAN_GPIO_PIN16_PAD_PULL_MASK
-#define GPIO_PIN16_PAD_PULL_GET(x) WLAN_GPIO_PIN16_PAD_PULL_GET(x)
-#define GPIO_PIN16_PAD_PULL_SET(x) WLAN_GPIO_PIN16_PAD_PULL_SET(x)
-#define GPIO_PIN16_PAD_STRENGTH_MSB WLAN_GPIO_PIN16_PAD_STRENGTH_MSB
-#define GPIO_PIN16_PAD_STRENGTH_LSB WLAN_GPIO_PIN16_PAD_STRENGTH_LSB
-#define GPIO_PIN16_PAD_STRENGTH_MASK WLAN_GPIO_PIN16_PAD_STRENGTH_MASK
-#define GPIO_PIN16_PAD_STRENGTH_GET(x) WLAN_GPIO_PIN16_PAD_STRENGTH_GET(x)
-#define GPIO_PIN16_PAD_STRENGTH_SET(x) WLAN_GPIO_PIN16_PAD_STRENGTH_SET(x)
-#define GPIO_PIN16_PAD_DRIVER_MSB WLAN_GPIO_PIN16_PAD_DRIVER_MSB
-#define GPIO_PIN16_PAD_DRIVER_LSB WLAN_GPIO_PIN16_PAD_DRIVER_LSB
-#define GPIO_PIN16_PAD_DRIVER_MASK WLAN_GPIO_PIN16_PAD_DRIVER_MASK
-#define GPIO_PIN16_PAD_DRIVER_GET(x) WLAN_GPIO_PIN16_PAD_DRIVER_GET(x)
-#define GPIO_PIN16_PAD_DRIVER_SET(x) WLAN_GPIO_PIN16_PAD_DRIVER_SET(x)
-#define GPIO_PIN16_SOURCE_MSB WLAN_GPIO_PIN16_SOURCE_MSB
-#define GPIO_PIN16_SOURCE_LSB WLAN_GPIO_PIN16_SOURCE_LSB
-#define GPIO_PIN16_SOURCE_MASK WLAN_GPIO_PIN16_SOURCE_MASK
-#define GPIO_PIN16_SOURCE_GET(x) WLAN_GPIO_PIN16_SOURCE_GET(x)
-#define GPIO_PIN16_SOURCE_SET(x) WLAN_GPIO_PIN16_SOURCE_SET(x)
-#define GPIO_PIN17_ADDRESS WLAN_GPIO_PIN17_ADDRESS
-#define GPIO_PIN17_OFFSET WLAN_GPIO_PIN17_OFFSET
-#define GPIO_PIN17_CONFIG_MSB WLAN_GPIO_PIN17_CONFIG_MSB
-#define GPIO_PIN17_CONFIG_LSB WLAN_GPIO_PIN17_CONFIG_LSB
-#define GPIO_PIN17_CONFIG_MASK WLAN_GPIO_PIN17_CONFIG_MASK
-#define GPIO_PIN17_CONFIG_GET(x) WLAN_GPIO_PIN17_CONFIG_GET(x)
-#define GPIO_PIN17_CONFIG_SET(x) WLAN_GPIO_PIN17_CONFIG_SET(x)
-#define GPIO_PIN17_WAKEUP_ENABLE_MSB WLAN_GPIO_PIN17_WAKEUP_ENABLE_MSB
-#define GPIO_PIN17_WAKEUP_ENABLE_LSB WLAN_GPIO_PIN17_WAKEUP_ENABLE_LSB
-#define GPIO_PIN17_WAKEUP_ENABLE_MASK WLAN_GPIO_PIN17_WAKEUP_ENABLE_MASK
-#define GPIO_PIN17_WAKEUP_ENABLE_GET(x) WLAN_GPIO_PIN17_WAKEUP_ENABLE_GET(x)
-#define GPIO_PIN17_WAKEUP_ENABLE_SET(x) WLAN_GPIO_PIN17_WAKEUP_ENABLE_SET(x)
-#define GPIO_PIN17_INT_TYPE_MSB WLAN_GPIO_PIN17_INT_TYPE_MSB
-#define GPIO_PIN17_INT_TYPE_LSB WLAN_GPIO_PIN17_INT_TYPE_LSB
-#define GPIO_PIN17_INT_TYPE_MASK WLAN_GPIO_PIN17_INT_TYPE_MASK
-#define GPIO_PIN17_INT_TYPE_GET(x) WLAN_GPIO_PIN17_INT_TYPE_GET(x)
-#define GPIO_PIN17_INT_TYPE_SET(x) WLAN_GPIO_PIN17_INT_TYPE_SET(x)
-#define GPIO_PIN17_PAD_PULL_MSB WLAN_GPIO_PIN17_PAD_PULL_MSB
-#define GPIO_PIN17_PAD_PULL_LSB WLAN_GPIO_PIN17_PAD_PULL_LSB
-#define GPIO_PIN17_PAD_PULL_MASK WLAN_GPIO_PIN17_PAD_PULL_MASK
-#define GPIO_PIN17_PAD_PULL_GET(x) WLAN_GPIO_PIN17_PAD_PULL_GET(x)
-#define GPIO_PIN17_PAD_PULL_SET(x) WLAN_GPIO_PIN17_PAD_PULL_SET(x)
-#define GPIO_PIN17_PAD_STRENGTH_MSB WLAN_GPIO_PIN17_PAD_STRENGTH_MSB
-#define GPIO_PIN17_PAD_STRENGTH_LSB WLAN_GPIO_PIN17_PAD_STRENGTH_LSB
-#define GPIO_PIN17_PAD_STRENGTH_MASK WLAN_GPIO_PIN17_PAD_STRENGTH_MASK
-#define GPIO_PIN17_PAD_STRENGTH_GET(x) WLAN_GPIO_PIN17_PAD_STRENGTH_GET(x)
-#define GPIO_PIN17_PAD_STRENGTH_SET(x) WLAN_GPIO_PIN17_PAD_STRENGTH_SET(x)
-#define GPIO_PIN17_PAD_DRIVER_MSB WLAN_GPIO_PIN17_PAD_DRIVER_MSB
-#define GPIO_PIN17_PAD_DRIVER_LSB WLAN_GPIO_PIN17_PAD_DRIVER_LSB
-#define GPIO_PIN17_PAD_DRIVER_MASK WLAN_GPIO_PIN17_PAD_DRIVER_MASK
-#define GPIO_PIN17_PAD_DRIVER_GET(x) WLAN_GPIO_PIN17_PAD_DRIVER_GET(x)
-#define GPIO_PIN17_PAD_DRIVER_SET(x) WLAN_GPIO_PIN17_PAD_DRIVER_SET(x)
-#define GPIO_PIN17_SOURCE_MSB WLAN_GPIO_PIN17_SOURCE_MSB
-#define GPIO_PIN17_SOURCE_LSB WLAN_GPIO_PIN17_SOURCE_LSB
-#define GPIO_PIN17_SOURCE_MASK WLAN_GPIO_PIN17_SOURCE_MASK
-#define GPIO_PIN17_SOURCE_GET(x) WLAN_GPIO_PIN17_SOURCE_GET(x)
-#define GPIO_PIN17_SOURCE_SET(x) WLAN_GPIO_PIN17_SOURCE_SET(x)
-#define GPIO_PIN18_ADDRESS WLAN_GPIO_PIN18_ADDRESS
-#define GPIO_PIN18_OFFSET WLAN_GPIO_PIN18_OFFSET
-#define GPIO_PIN18_CONFIG_MSB WLAN_GPIO_PIN18_CONFIG_MSB
-#define GPIO_PIN18_CONFIG_LSB WLAN_GPIO_PIN18_CONFIG_LSB
-#define GPIO_PIN18_CONFIG_MASK WLAN_GPIO_PIN18_CONFIG_MASK
-#define GPIO_PIN18_CONFIG_GET(x) WLAN_GPIO_PIN18_CONFIG_GET(x)
-#define GPIO_PIN18_CONFIG_SET(x) WLAN_GPIO_PIN18_CONFIG_SET(x)
-#define GPIO_PIN18_WAKEUP_ENABLE_MSB WLAN_GPIO_PIN18_WAKEUP_ENABLE_MSB
-#define GPIO_PIN18_WAKEUP_ENABLE_LSB WLAN_GPIO_PIN18_WAKEUP_ENABLE_LSB
-#define GPIO_PIN18_WAKEUP_ENABLE_MASK WLAN_GPIO_PIN18_WAKEUP_ENABLE_MASK
-#define GPIO_PIN18_WAKEUP_ENABLE_GET(x) WLAN_GPIO_PIN18_WAKEUP_ENABLE_GET(x)
-#define GPIO_PIN18_WAKEUP_ENABLE_SET(x) WLAN_GPIO_PIN18_WAKEUP_ENABLE_SET(x)
-#define GPIO_PIN18_INT_TYPE_MSB WLAN_GPIO_PIN18_INT_TYPE_MSB
-#define GPIO_PIN18_INT_TYPE_LSB WLAN_GPIO_PIN18_INT_TYPE_LSB
-#define GPIO_PIN18_INT_TYPE_MASK WLAN_GPIO_PIN18_INT_TYPE_MASK
-#define GPIO_PIN18_INT_TYPE_GET(x) WLAN_GPIO_PIN18_INT_TYPE_GET(x)
-#define GPIO_PIN18_INT_TYPE_SET(x) WLAN_GPIO_PIN18_INT_TYPE_SET(x)
-#define GPIO_PIN18_PAD_PULL_MSB WLAN_GPIO_PIN18_PAD_PULL_MSB
-#define GPIO_PIN18_PAD_PULL_LSB WLAN_GPIO_PIN18_PAD_PULL_LSB
-#define GPIO_PIN18_PAD_PULL_MASK WLAN_GPIO_PIN18_PAD_PULL_MASK
-#define GPIO_PIN18_PAD_PULL_GET(x) WLAN_GPIO_PIN18_PAD_PULL_GET(x)
-#define GPIO_PIN18_PAD_PULL_SET(x) WLAN_GPIO_PIN18_PAD_PULL_SET(x)
-#define GPIO_PIN18_PAD_STRENGTH_MSB WLAN_GPIO_PIN18_PAD_STRENGTH_MSB
-#define GPIO_PIN18_PAD_STRENGTH_LSB WLAN_GPIO_PIN18_PAD_STRENGTH_LSB
-#define GPIO_PIN18_PAD_STRENGTH_MASK WLAN_GPIO_PIN18_PAD_STRENGTH_MASK
-#define GPIO_PIN18_PAD_STRENGTH_GET(x) WLAN_GPIO_PIN18_PAD_STRENGTH_GET(x)
-#define GPIO_PIN18_PAD_STRENGTH_SET(x) WLAN_GPIO_PIN18_PAD_STRENGTH_SET(x)
-#define GPIO_PIN18_PAD_DRIVER_MSB WLAN_GPIO_PIN18_PAD_DRIVER_MSB
-#define GPIO_PIN18_PAD_DRIVER_LSB WLAN_GPIO_PIN18_PAD_DRIVER_LSB
-#define GPIO_PIN18_PAD_DRIVER_MASK WLAN_GPIO_PIN18_PAD_DRIVER_MASK
-#define GPIO_PIN18_PAD_DRIVER_GET(x) WLAN_GPIO_PIN18_PAD_DRIVER_GET(x)
-#define GPIO_PIN18_PAD_DRIVER_SET(x) WLAN_GPIO_PIN18_PAD_DRIVER_SET(x)
-#define GPIO_PIN18_SOURCE_MSB WLAN_GPIO_PIN18_SOURCE_MSB
-#define GPIO_PIN18_SOURCE_LSB WLAN_GPIO_PIN18_SOURCE_LSB
-#define GPIO_PIN18_SOURCE_MASK WLAN_GPIO_PIN18_SOURCE_MASK
-#define GPIO_PIN18_SOURCE_GET(x) WLAN_GPIO_PIN18_SOURCE_GET(x)
-#define GPIO_PIN18_SOURCE_SET(x) WLAN_GPIO_PIN18_SOURCE_SET(x)
-#define GPIO_PIN19_ADDRESS WLAN_GPIO_PIN19_ADDRESS
-#define GPIO_PIN19_OFFSET WLAN_GPIO_PIN19_OFFSET
-#define GPIO_PIN19_CONFIG_MSB WLAN_GPIO_PIN19_CONFIG_MSB
-#define GPIO_PIN19_CONFIG_LSB WLAN_GPIO_PIN19_CONFIG_LSB
-#define GPIO_PIN19_CONFIG_MASK WLAN_GPIO_PIN19_CONFIG_MASK
-#define GPIO_PIN19_CONFIG_GET(x) WLAN_GPIO_PIN19_CONFIG_GET(x)
-#define GPIO_PIN19_CONFIG_SET(x) WLAN_GPIO_PIN19_CONFIG_SET(x)
-#define GPIO_PIN19_WAKEUP_ENABLE_MSB WLAN_GPIO_PIN19_WAKEUP_ENABLE_MSB
-#define GPIO_PIN19_WAKEUP_ENABLE_LSB WLAN_GPIO_PIN19_WAKEUP_ENABLE_LSB
-#define GPIO_PIN19_WAKEUP_ENABLE_MASK WLAN_GPIO_PIN19_WAKEUP_ENABLE_MASK
-#define GPIO_PIN19_WAKEUP_ENABLE_GET(x) WLAN_GPIO_PIN19_WAKEUP_ENABLE_GET(x)
-#define GPIO_PIN19_WAKEUP_ENABLE_SET(x) WLAN_GPIO_PIN19_WAKEUP_ENABLE_SET(x)
-#define GPIO_PIN19_INT_TYPE_MSB WLAN_GPIO_PIN19_INT_TYPE_MSB
-#define GPIO_PIN19_INT_TYPE_LSB WLAN_GPIO_PIN19_INT_TYPE_LSB
-#define GPIO_PIN19_INT_TYPE_MASK WLAN_GPIO_PIN19_INT_TYPE_MASK
-#define GPIO_PIN19_INT_TYPE_GET(x) WLAN_GPIO_PIN19_INT_TYPE_GET(x)
-#define GPIO_PIN19_INT_TYPE_SET(x) WLAN_GPIO_PIN19_INT_TYPE_SET(x)
-#define GPIO_PIN19_PAD_PULL_MSB WLAN_GPIO_PIN19_PAD_PULL_MSB
-#define GPIO_PIN19_PAD_PULL_LSB WLAN_GPIO_PIN19_PAD_PULL_LSB
-#define GPIO_PIN19_PAD_PULL_MASK WLAN_GPIO_PIN19_PAD_PULL_MASK
-#define GPIO_PIN19_PAD_PULL_GET(x) WLAN_GPIO_PIN19_PAD_PULL_GET(x)
-#define GPIO_PIN19_PAD_PULL_SET(x) WLAN_GPIO_PIN19_PAD_PULL_SET(x)
-#define GPIO_PIN19_PAD_STRENGTH_MSB WLAN_GPIO_PIN19_PAD_STRENGTH_MSB
-#define GPIO_PIN19_PAD_STRENGTH_LSB WLAN_GPIO_PIN19_PAD_STRENGTH_LSB
-#define GPIO_PIN19_PAD_STRENGTH_MASK WLAN_GPIO_PIN19_PAD_STRENGTH_MASK
-#define GPIO_PIN19_PAD_STRENGTH_GET(x) WLAN_GPIO_PIN19_PAD_STRENGTH_GET(x)
-#define GPIO_PIN19_PAD_STRENGTH_SET(x) WLAN_GPIO_PIN19_PAD_STRENGTH_SET(x)
-#define GPIO_PIN19_PAD_DRIVER_MSB WLAN_GPIO_PIN19_PAD_DRIVER_MSB
-#define GPIO_PIN19_PAD_DRIVER_LSB WLAN_GPIO_PIN19_PAD_DRIVER_LSB
-#define GPIO_PIN19_PAD_DRIVER_MASK WLAN_GPIO_PIN19_PAD_DRIVER_MASK
-#define GPIO_PIN19_PAD_DRIVER_GET(x) WLAN_GPIO_PIN19_PAD_DRIVER_GET(x)
-#define GPIO_PIN19_PAD_DRIVER_SET(x) WLAN_GPIO_PIN19_PAD_DRIVER_SET(x)
-#define GPIO_PIN19_SOURCE_MSB WLAN_GPIO_PIN19_SOURCE_MSB
-#define GPIO_PIN19_SOURCE_LSB WLAN_GPIO_PIN19_SOURCE_LSB
-#define GPIO_PIN19_SOURCE_MASK WLAN_GPIO_PIN19_SOURCE_MASK
-#define GPIO_PIN19_SOURCE_GET(x) WLAN_GPIO_PIN19_SOURCE_GET(x)
-#define GPIO_PIN19_SOURCE_SET(x) WLAN_GPIO_PIN19_SOURCE_SET(x)
-#define GPIO_PIN20_ADDRESS WLAN_GPIO_PIN20_ADDRESS
-#define GPIO_PIN20_OFFSET WLAN_GPIO_PIN20_OFFSET
-#define GPIO_PIN20_CONFIG_MSB WLAN_GPIO_PIN20_CONFIG_MSB
-#define GPIO_PIN20_CONFIG_LSB WLAN_GPIO_PIN20_CONFIG_LSB
-#define GPIO_PIN20_CONFIG_MASK WLAN_GPIO_PIN20_CONFIG_MASK
-#define GPIO_PIN20_CONFIG_GET(x) WLAN_GPIO_PIN20_CONFIG_GET(x)
-#define GPIO_PIN20_CONFIG_SET(x) WLAN_GPIO_PIN20_CONFIG_SET(x)
-#define GPIO_PIN20_WAKEUP_ENABLE_MSB WLAN_GPIO_PIN20_WAKEUP_ENABLE_MSB
-#define GPIO_PIN20_WAKEUP_ENABLE_LSB WLAN_GPIO_PIN20_WAKEUP_ENABLE_LSB
-#define GPIO_PIN20_WAKEUP_ENABLE_MASK WLAN_GPIO_PIN20_WAKEUP_ENABLE_MASK
-#define GPIO_PIN20_WAKEUP_ENABLE_GET(x) WLAN_GPIO_PIN20_WAKEUP_ENABLE_GET(x)
-#define GPIO_PIN20_WAKEUP_ENABLE_SET(x) WLAN_GPIO_PIN20_WAKEUP_ENABLE_SET(x)
-#define GPIO_PIN20_INT_TYPE_MSB WLAN_GPIO_PIN20_INT_TYPE_MSB
-#define GPIO_PIN20_INT_TYPE_LSB WLAN_GPIO_PIN20_INT_TYPE_LSB
-#define GPIO_PIN20_INT_TYPE_MASK WLAN_GPIO_PIN20_INT_TYPE_MASK
-#define GPIO_PIN20_INT_TYPE_GET(x) WLAN_GPIO_PIN20_INT_TYPE_GET(x)
-#define GPIO_PIN20_INT_TYPE_SET(x) WLAN_GPIO_PIN20_INT_TYPE_SET(x)
-#define GPIO_PIN20_PAD_PULL_MSB WLAN_GPIO_PIN20_PAD_PULL_MSB
-#define GPIO_PIN20_PAD_PULL_LSB WLAN_GPIO_PIN20_PAD_PULL_LSB
-#define GPIO_PIN20_PAD_PULL_MASK WLAN_GPIO_PIN20_PAD_PULL_MASK
-#define GPIO_PIN20_PAD_PULL_GET(x) WLAN_GPIO_PIN20_PAD_PULL_GET(x)
-#define GPIO_PIN20_PAD_PULL_SET(x) WLAN_GPIO_PIN20_PAD_PULL_SET(x)
-#define GPIO_PIN20_PAD_STRENGTH_MSB WLAN_GPIO_PIN20_PAD_STRENGTH_MSB
-#define GPIO_PIN20_PAD_STRENGTH_LSB WLAN_GPIO_PIN20_PAD_STRENGTH_LSB
-#define GPIO_PIN20_PAD_STRENGTH_MASK WLAN_GPIO_PIN20_PAD_STRENGTH_MASK
-#define GPIO_PIN20_PAD_STRENGTH_GET(x) WLAN_GPIO_PIN20_PAD_STRENGTH_GET(x)
-#define GPIO_PIN20_PAD_STRENGTH_SET(x) WLAN_GPIO_PIN20_PAD_STRENGTH_SET(x)
-#define GPIO_PIN20_PAD_DRIVER_MSB WLAN_GPIO_PIN20_PAD_DRIVER_MSB
-#define GPIO_PIN20_PAD_DRIVER_LSB WLAN_GPIO_PIN20_PAD_DRIVER_LSB
-#define GPIO_PIN20_PAD_DRIVER_MASK WLAN_GPIO_PIN20_PAD_DRIVER_MASK
-#define GPIO_PIN20_PAD_DRIVER_GET(x) WLAN_GPIO_PIN20_PAD_DRIVER_GET(x)
-#define GPIO_PIN20_PAD_DRIVER_SET(x) WLAN_GPIO_PIN20_PAD_DRIVER_SET(x)
-#define GPIO_PIN20_SOURCE_MSB WLAN_GPIO_PIN20_SOURCE_MSB
-#define GPIO_PIN20_SOURCE_LSB WLAN_GPIO_PIN20_SOURCE_LSB
-#define GPIO_PIN20_SOURCE_MASK WLAN_GPIO_PIN20_SOURCE_MASK
-#define GPIO_PIN20_SOURCE_GET(x) WLAN_GPIO_PIN20_SOURCE_GET(x)
-#define GPIO_PIN20_SOURCE_SET(x) WLAN_GPIO_PIN20_SOURCE_SET(x)
-#define GPIO_PIN21_ADDRESS WLAN_GPIO_PIN21_ADDRESS
-#define GPIO_PIN21_OFFSET WLAN_GPIO_PIN21_OFFSET
-#define GPIO_PIN21_CONFIG_MSB WLAN_GPIO_PIN21_CONFIG_MSB
-#define GPIO_PIN21_CONFIG_LSB WLAN_GPIO_PIN21_CONFIG_LSB
-#define GPIO_PIN21_CONFIG_MASK WLAN_GPIO_PIN21_CONFIG_MASK
-#define GPIO_PIN21_CONFIG_GET(x) WLAN_GPIO_PIN21_CONFIG_GET(x)
-#define GPIO_PIN21_CONFIG_SET(x) WLAN_GPIO_PIN21_CONFIG_SET(x)
-#define GPIO_PIN21_WAKEUP_ENABLE_MSB WLAN_GPIO_PIN21_WAKEUP_ENABLE_MSB
-#define GPIO_PIN21_WAKEUP_ENABLE_LSB WLAN_GPIO_PIN21_WAKEUP_ENABLE_LSB
-#define GPIO_PIN21_WAKEUP_ENABLE_MASK WLAN_GPIO_PIN21_WAKEUP_ENABLE_MASK
-#define GPIO_PIN21_WAKEUP_ENABLE_GET(x) WLAN_GPIO_PIN21_WAKEUP_ENABLE_GET(x)
-#define GPIO_PIN21_WAKEUP_ENABLE_SET(x) WLAN_GPIO_PIN21_WAKEUP_ENABLE_SET(x)
-#define GPIO_PIN21_INT_TYPE_MSB WLAN_GPIO_PIN21_INT_TYPE_MSB
-#define GPIO_PIN21_INT_TYPE_LSB WLAN_GPIO_PIN21_INT_TYPE_LSB
-#define GPIO_PIN21_INT_TYPE_MASK WLAN_GPIO_PIN21_INT_TYPE_MASK
-#define GPIO_PIN21_INT_TYPE_GET(x) WLAN_GPIO_PIN21_INT_TYPE_GET(x)
-#define GPIO_PIN21_INT_TYPE_SET(x) WLAN_GPIO_PIN21_INT_TYPE_SET(x)
-#define GPIO_PIN21_PAD_PULL_MSB WLAN_GPIO_PIN21_PAD_PULL_MSB
-#define GPIO_PIN21_PAD_PULL_LSB WLAN_GPIO_PIN21_PAD_PULL_LSB
-#define GPIO_PIN21_PAD_PULL_MASK WLAN_GPIO_PIN21_PAD_PULL_MASK
-#define GPIO_PIN21_PAD_PULL_GET(x) WLAN_GPIO_PIN21_PAD_PULL_GET(x)
-#define GPIO_PIN21_PAD_PULL_SET(x) WLAN_GPIO_PIN21_PAD_PULL_SET(x)
-#define GPIO_PIN21_PAD_STRENGTH_MSB WLAN_GPIO_PIN21_PAD_STRENGTH_MSB
-#define GPIO_PIN21_PAD_STRENGTH_LSB WLAN_GPIO_PIN21_PAD_STRENGTH_LSB
-#define GPIO_PIN21_PAD_STRENGTH_MASK WLAN_GPIO_PIN21_PAD_STRENGTH_MASK
-#define GPIO_PIN21_PAD_STRENGTH_GET(x) WLAN_GPIO_PIN21_PAD_STRENGTH_GET(x)
-#define GPIO_PIN21_PAD_STRENGTH_SET(x) WLAN_GPIO_PIN21_PAD_STRENGTH_SET(x)
-#define GPIO_PIN21_PAD_DRIVER_MSB WLAN_GPIO_PIN21_PAD_DRIVER_MSB
-#define GPIO_PIN21_PAD_DRIVER_LSB WLAN_GPIO_PIN21_PAD_DRIVER_LSB
-#define GPIO_PIN21_PAD_DRIVER_MASK WLAN_GPIO_PIN21_PAD_DRIVER_MASK
-#define GPIO_PIN21_PAD_DRIVER_GET(x) WLAN_GPIO_PIN21_PAD_DRIVER_GET(x)
-#define GPIO_PIN21_PAD_DRIVER_SET(x) WLAN_GPIO_PIN21_PAD_DRIVER_SET(x)
-#define GPIO_PIN21_SOURCE_MSB WLAN_GPIO_PIN21_SOURCE_MSB
-#define GPIO_PIN21_SOURCE_LSB WLAN_GPIO_PIN21_SOURCE_LSB
-#define GPIO_PIN21_SOURCE_MASK WLAN_GPIO_PIN21_SOURCE_MASK
-#define GPIO_PIN21_SOURCE_GET(x) WLAN_GPIO_PIN21_SOURCE_GET(x)
-#define GPIO_PIN21_SOURCE_SET(x) WLAN_GPIO_PIN21_SOURCE_SET(x)
-#define GPIO_PIN22_ADDRESS WLAN_GPIO_PIN22_ADDRESS
-#define GPIO_PIN22_OFFSET WLAN_GPIO_PIN22_OFFSET
-#define GPIO_PIN22_CONFIG_MSB WLAN_GPIO_PIN22_CONFIG_MSB
-#define GPIO_PIN22_CONFIG_LSB WLAN_GPIO_PIN22_CONFIG_LSB
-#define GPIO_PIN22_CONFIG_MASK WLAN_GPIO_PIN22_CONFIG_MASK
-#define GPIO_PIN22_CONFIG_GET(x) WLAN_GPIO_PIN22_CONFIG_GET(x)
-#define GPIO_PIN22_CONFIG_SET(x) WLAN_GPIO_PIN22_CONFIG_SET(x)
-#define GPIO_PIN22_WAKEUP_ENABLE_MSB WLAN_GPIO_PIN22_WAKEUP_ENABLE_MSB
-#define GPIO_PIN22_WAKEUP_ENABLE_LSB WLAN_GPIO_PIN22_WAKEUP_ENABLE_LSB
-#define GPIO_PIN22_WAKEUP_ENABLE_MASK WLAN_GPIO_PIN22_WAKEUP_ENABLE_MASK
-#define GPIO_PIN22_WAKEUP_ENABLE_GET(x) WLAN_GPIO_PIN22_WAKEUP_ENABLE_GET(x)
-#define GPIO_PIN22_WAKEUP_ENABLE_SET(x) WLAN_GPIO_PIN22_WAKEUP_ENABLE_SET(x)
-#define GPIO_PIN22_INT_TYPE_MSB WLAN_GPIO_PIN22_INT_TYPE_MSB
-#define GPIO_PIN22_INT_TYPE_LSB WLAN_GPIO_PIN22_INT_TYPE_LSB
-#define GPIO_PIN22_INT_TYPE_MASK WLAN_GPIO_PIN22_INT_TYPE_MASK
-#define GPIO_PIN22_INT_TYPE_GET(x) WLAN_GPIO_PIN22_INT_TYPE_GET(x)
-#define GPIO_PIN22_INT_TYPE_SET(x) WLAN_GPIO_PIN22_INT_TYPE_SET(x)
-#define GPIO_PIN22_PAD_PULL_MSB WLAN_GPIO_PIN22_PAD_PULL_MSB
-#define GPIO_PIN22_PAD_PULL_LSB WLAN_GPIO_PIN22_PAD_PULL_LSB
-#define GPIO_PIN22_PAD_PULL_MASK WLAN_GPIO_PIN22_PAD_PULL_MASK
-#define GPIO_PIN22_PAD_PULL_GET(x) WLAN_GPIO_PIN22_PAD_PULL_GET(x)
-#define GPIO_PIN22_PAD_PULL_SET(x) WLAN_GPIO_PIN22_PAD_PULL_SET(x)
-#define GPIO_PIN22_PAD_STRENGTH_MSB WLAN_GPIO_PIN22_PAD_STRENGTH_MSB
-#define GPIO_PIN22_PAD_STRENGTH_LSB WLAN_GPIO_PIN22_PAD_STRENGTH_LSB
-#define GPIO_PIN22_PAD_STRENGTH_MASK WLAN_GPIO_PIN22_PAD_STRENGTH_MASK
-#define GPIO_PIN22_PAD_STRENGTH_GET(x) WLAN_GPIO_PIN22_PAD_STRENGTH_GET(x)
-#define GPIO_PIN22_PAD_STRENGTH_SET(x) WLAN_GPIO_PIN22_PAD_STRENGTH_SET(x)
-#define GPIO_PIN22_PAD_DRIVER_MSB WLAN_GPIO_PIN22_PAD_DRIVER_MSB
-#define GPIO_PIN22_PAD_DRIVER_LSB WLAN_GPIO_PIN22_PAD_DRIVER_LSB
-#define GPIO_PIN22_PAD_DRIVER_MASK WLAN_GPIO_PIN22_PAD_DRIVER_MASK
-#define GPIO_PIN22_PAD_DRIVER_GET(x) WLAN_GPIO_PIN22_PAD_DRIVER_GET(x)
-#define GPIO_PIN22_PAD_DRIVER_SET(x) WLAN_GPIO_PIN22_PAD_DRIVER_SET(x)
-#define GPIO_PIN22_SOURCE_MSB WLAN_GPIO_PIN22_SOURCE_MSB
-#define GPIO_PIN22_SOURCE_LSB WLAN_GPIO_PIN22_SOURCE_LSB
-#define GPIO_PIN22_SOURCE_MASK WLAN_GPIO_PIN22_SOURCE_MASK
-#define GPIO_PIN22_SOURCE_GET(x) WLAN_GPIO_PIN22_SOURCE_GET(x)
-#define GPIO_PIN22_SOURCE_SET(x) WLAN_GPIO_PIN22_SOURCE_SET(x)
-#define GPIO_PIN23_ADDRESS WLAN_GPIO_PIN23_ADDRESS
-#define GPIO_PIN23_OFFSET WLAN_GPIO_PIN23_OFFSET
-#define GPIO_PIN23_CONFIG_MSB WLAN_GPIO_PIN23_CONFIG_MSB
-#define GPIO_PIN23_CONFIG_LSB WLAN_GPIO_PIN23_CONFIG_LSB
-#define GPIO_PIN23_CONFIG_MASK WLAN_GPIO_PIN23_CONFIG_MASK
-#define GPIO_PIN23_CONFIG_GET(x) WLAN_GPIO_PIN23_CONFIG_GET(x)
-#define GPIO_PIN23_CONFIG_SET(x) WLAN_GPIO_PIN23_CONFIG_SET(x)
-#define GPIO_PIN23_WAKEUP_ENABLE_MSB WLAN_GPIO_PIN23_WAKEUP_ENABLE_MSB
-#define GPIO_PIN23_WAKEUP_ENABLE_LSB WLAN_GPIO_PIN23_WAKEUP_ENABLE_LSB
-#define GPIO_PIN23_WAKEUP_ENABLE_MASK WLAN_GPIO_PIN23_WAKEUP_ENABLE_MASK
-#define GPIO_PIN23_WAKEUP_ENABLE_GET(x) WLAN_GPIO_PIN23_WAKEUP_ENABLE_GET(x)
-#define GPIO_PIN23_WAKEUP_ENABLE_SET(x) WLAN_GPIO_PIN23_WAKEUP_ENABLE_SET(x)
-#define GPIO_PIN23_INT_TYPE_MSB WLAN_GPIO_PIN23_INT_TYPE_MSB
-#define GPIO_PIN23_INT_TYPE_LSB WLAN_GPIO_PIN23_INT_TYPE_LSB
-#define GPIO_PIN23_INT_TYPE_MASK WLAN_GPIO_PIN23_INT_TYPE_MASK
-#define GPIO_PIN23_INT_TYPE_GET(x) WLAN_GPIO_PIN23_INT_TYPE_GET(x)
-#define GPIO_PIN23_INT_TYPE_SET(x) WLAN_GPIO_PIN23_INT_TYPE_SET(x)
-#define GPIO_PIN23_PAD_DRIVER_MSB WLAN_GPIO_PIN23_PAD_DRIVER_MSB
-#define GPIO_PIN23_PAD_DRIVER_LSB WLAN_GPIO_PIN23_PAD_DRIVER_LSB
-#define GPIO_PIN23_PAD_DRIVER_MASK WLAN_GPIO_PIN23_PAD_DRIVER_MASK
-#define GPIO_PIN23_PAD_DRIVER_GET(x) WLAN_GPIO_PIN23_PAD_DRIVER_GET(x)
-#define GPIO_PIN23_PAD_DRIVER_SET(x) WLAN_GPIO_PIN23_PAD_DRIVER_SET(x)
-#define GPIO_PIN23_SOURCE_MSB WLAN_GPIO_PIN23_SOURCE_MSB
-#define GPIO_PIN23_SOURCE_LSB WLAN_GPIO_PIN23_SOURCE_LSB
-#define GPIO_PIN23_SOURCE_MASK WLAN_GPIO_PIN23_SOURCE_MASK
-#define GPIO_PIN23_SOURCE_GET(x) WLAN_GPIO_PIN23_SOURCE_GET(x)
-#define GPIO_PIN23_SOURCE_SET(x) WLAN_GPIO_PIN23_SOURCE_SET(x)
-#define GPIO_PIN24_ADDRESS WLAN_GPIO_PIN24_ADDRESS
-#define GPIO_PIN24_OFFSET WLAN_GPIO_PIN24_OFFSET
-#define GPIO_PIN24_CONFIG_MSB WLAN_GPIO_PIN24_CONFIG_MSB
-#define GPIO_PIN24_CONFIG_LSB WLAN_GPIO_PIN24_CONFIG_LSB
-#define GPIO_PIN24_CONFIG_MASK WLAN_GPIO_PIN24_CONFIG_MASK
-#define GPIO_PIN24_CONFIG_GET(x) WLAN_GPIO_PIN24_CONFIG_GET(x)
-#define GPIO_PIN24_CONFIG_SET(x) WLAN_GPIO_PIN24_CONFIG_SET(x)
-#define GPIO_PIN24_WAKEUP_ENABLE_MSB WLAN_GPIO_PIN24_WAKEUP_ENABLE_MSB
-#define GPIO_PIN24_WAKEUP_ENABLE_LSB WLAN_GPIO_PIN24_WAKEUP_ENABLE_LSB
-#define GPIO_PIN24_WAKEUP_ENABLE_MASK WLAN_GPIO_PIN24_WAKEUP_ENABLE_MASK
-#define GPIO_PIN24_WAKEUP_ENABLE_GET(x) WLAN_GPIO_PIN24_WAKEUP_ENABLE_GET(x)
-#define GPIO_PIN24_WAKEUP_ENABLE_SET(x) WLAN_GPIO_PIN24_WAKEUP_ENABLE_SET(x)
-#define GPIO_PIN24_INT_TYPE_MSB WLAN_GPIO_PIN24_INT_TYPE_MSB
-#define GPIO_PIN24_INT_TYPE_LSB WLAN_GPIO_PIN24_INT_TYPE_LSB
-#define GPIO_PIN24_INT_TYPE_MASK WLAN_GPIO_PIN24_INT_TYPE_MASK
-#define GPIO_PIN24_INT_TYPE_GET(x) WLAN_GPIO_PIN24_INT_TYPE_GET(x)
-#define GPIO_PIN24_INT_TYPE_SET(x) WLAN_GPIO_PIN24_INT_TYPE_SET(x)
-#define GPIO_PIN24_PAD_DRIVER_MSB WLAN_GPIO_PIN24_PAD_DRIVER_MSB
-#define GPIO_PIN24_PAD_DRIVER_LSB WLAN_GPIO_PIN24_PAD_DRIVER_LSB
-#define GPIO_PIN24_PAD_DRIVER_MASK WLAN_GPIO_PIN24_PAD_DRIVER_MASK
-#define GPIO_PIN24_PAD_DRIVER_GET(x) WLAN_GPIO_PIN24_PAD_DRIVER_GET(x)
-#define GPIO_PIN24_PAD_DRIVER_SET(x) WLAN_GPIO_PIN24_PAD_DRIVER_SET(x)
-#define GPIO_PIN24_SOURCE_MSB WLAN_GPIO_PIN24_SOURCE_MSB
-#define GPIO_PIN24_SOURCE_LSB WLAN_GPIO_PIN24_SOURCE_LSB
-#define GPIO_PIN24_SOURCE_MASK WLAN_GPIO_PIN24_SOURCE_MASK
-#define GPIO_PIN24_SOURCE_GET(x) WLAN_GPIO_PIN24_SOURCE_GET(x)
-#define GPIO_PIN24_SOURCE_SET(x) WLAN_GPIO_PIN24_SOURCE_SET(x)
-#define GPIO_PIN25_ADDRESS WLAN_GPIO_PIN25_ADDRESS
-#define GPIO_PIN25_OFFSET WLAN_GPIO_PIN25_OFFSET
-#define GPIO_PIN25_CONFIG_MSB WLAN_GPIO_PIN25_CONFIG_MSB
-#define GPIO_PIN25_CONFIG_LSB WLAN_GPIO_PIN25_CONFIG_LSB
-#define GPIO_PIN25_CONFIG_MASK WLAN_GPIO_PIN25_CONFIG_MASK
-#define GPIO_PIN25_CONFIG_GET(x) WLAN_GPIO_PIN25_CONFIG_GET(x)
-#define GPIO_PIN25_CONFIG_SET(x) WLAN_GPIO_PIN25_CONFIG_SET(x)
-#define GPIO_PIN25_WAKEUP_ENABLE_MSB WLAN_GPIO_PIN25_WAKEUP_ENABLE_MSB
-#define GPIO_PIN25_WAKEUP_ENABLE_LSB WLAN_GPIO_PIN25_WAKEUP_ENABLE_LSB
-#define GPIO_PIN25_WAKEUP_ENABLE_MASK WLAN_GPIO_PIN25_WAKEUP_ENABLE_MASK
-#define GPIO_PIN25_WAKEUP_ENABLE_GET(x) WLAN_GPIO_PIN25_WAKEUP_ENABLE_GET(x)
-#define GPIO_PIN25_WAKEUP_ENABLE_SET(x) WLAN_GPIO_PIN25_WAKEUP_ENABLE_SET(x)
-#define GPIO_PIN25_INT_TYPE_MSB WLAN_GPIO_PIN25_INT_TYPE_MSB
-#define GPIO_PIN25_INT_TYPE_LSB WLAN_GPIO_PIN25_INT_TYPE_LSB
-#define GPIO_PIN25_INT_TYPE_MASK WLAN_GPIO_PIN25_INT_TYPE_MASK
-#define GPIO_PIN25_INT_TYPE_GET(x) WLAN_GPIO_PIN25_INT_TYPE_GET(x)
-#define GPIO_PIN25_INT_TYPE_SET(x) WLAN_GPIO_PIN25_INT_TYPE_SET(x)
-#define GPIO_PIN25_PAD_DRIVER_MSB WLAN_GPIO_PIN25_PAD_DRIVER_MSB
-#define GPIO_PIN25_PAD_DRIVER_LSB WLAN_GPIO_PIN25_PAD_DRIVER_LSB
-#define GPIO_PIN25_PAD_DRIVER_MASK WLAN_GPIO_PIN25_PAD_DRIVER_MASK
-#define GPIO_PIN25_PAD_DRIVER_GET(x) WLAN_GPIO_PIN25_PAD_DRIVER_GET(x)
-#define GPIO_PIN25_PAD_DRIVER_SET(x) WLAN_GPIO_PIN25_PAD_DRIVER_SET(x)
-#define GPIO_PIN25_SOURCE_MSB WLAN_GPIO_PIN25_SOURCE_MSB
-#define GPIO_PIN25_SOURCE_LSB WLAN_GPIO_PIN25_SOURCE_LSB
-#define GPIO_PIN25_SOURCE_MASK WLAN_GPIO_PIN25_SOURCE_MASK
-#define GPIO_PIN25_SOURCE_GET(x) WLAN_GPIO_PIN25_SOURCE_GET(x)
-#define GPIO_PIN25_SOURCE_SET(x) WLAN_GPIO_PIN25_SOURCE_SET(x)
-#define SIGMA_DELTA_ADDRESS WLAN_SIGMA_DELTA_ADDRESS
-#define SIGMA_DELTA_OFFSET WLAN_SIGMA_DELTA_OFFSET
-#define SIGMA_DELTA_ENABLE_MSB WLAN_SIGMA_DELTA_ENABLE_MSB
-#define SIGMA_DELTA_ENABLE_LSB WLAN_SIGMA_DELTA_ENABLE_LSB
-#define SIGMA_DELTA_ENABLE_MASK WLAN_SIGMA_DELTA_ENABLE_MASK
-#define SIGMA_DELTA_ENABLE_GET(x) WLAN_SIGMA_DELTA_ENABLE_GET(x)
-#define SIGMA_DELTA_ENABLE_SET(x) WLAN_SIGMA_DELTA_ENABLE_SET(x)
-#define SIGMA_DELTA_PRESCALAR_MSB WLAN_SIGMA_DELTA_PRESCALAR_MSB
-#define SIGMA_DELTA_PRESCALAR_LSB WLAN_SIGMA_DELTA_PRESCALAR_LSB
-#define SIGMA_DELTA_PRESCALAR_MASK WLAN_SIGMA_DELTA_PRESCALAR_MASK
-#define SIGMA_DELTA_PRESCALAR_GET(x) WLAN_SIGMA_DELTA_PRESCALAR_GET(x)
-#define SIGMA_DELTA_PRESCALAR_SET(x) WLAN_SIGMA_DELTA_PRESCALAR_SET(x)
-#define SIGMA_DELTA_TARGET_MSB WLAN_SIGMA_DELTA_TARGET_MSB
-#define SIGMA_DELTA_TARGET_LSB WLAN_SIGMA_DELTA_TARGET_LSB
-#define SIGMA_DELTA_TARGET_MASK WLAN_SIGMA_DELTA_TARGET_MASK
-#define SIGMA_DELTA_TARGET_GET(x) WLAN_SIGMA_DELTA_TARGET_GET(x)
-#define SIGMA_DELTA_TARGET_SET(x) WLAN_SIGMA_DELTA_TARGET_SET(x)
-#define DEBUG_CONTROL_ADDRESS WLAN_DEBUG_CONTROL_ADDRESS
-#define DEBUG_CONTROL_OFFSET WLAN_DEBUG_CONTROL_OFFSET
-#define DEBUG_CONTROL_ENABLE_MSB WLAN_DEBUG_CONTROL_ENABLE_MSB
-#define DEBUG_CONTROL_ENABLE_LSB WLAN_DEBUG_CONTROL_ENABLE_LSB
-#define DEBUG_CONTROL_ENABLE_MASK WLAN_DEBUG_CONTROL_ENABLE_MASK
-#define DEBUG_CONTROL_ENABLE_GET(x) WLAN_DEBUG_CONTROL_ENABLE_GET(x)
-#define DEBUG_CONTROL_ENABLE_SET(x) WLAN_DEBUG_CONTROL_ENABLE_SET(x)
-#define DEBUG_INPUT_SEL_ADDRESS WLAN_DEBUG_INPUT_SEL_ADDRESS
-#define DEBUG_INPUT_SEL_OFFSET WLAN_DEBUG_INPUT_SEL_OFFSET
-#define DEBUG_INPUT_SEL_SHIFT_MSB WLAN_DEBUG_INPUT_SEL_SHIFT_MSB
-#define DEBUG_INPUT_SEL_SHIFT_LSB WLAN_DEBUG_INPUT_SEL_SHIFT_LSB
-#define DEBUG_INPUT_SEL_SHIFT_MASK WLAN_DEBUG_INPUT_SEL_SHIFT_MASK
-#define DEBUG_INPUT_SEL_SHIFT_GET(x) WLAN_DEBUG_INPUT_SEL_SHIFT_GET(x)
-#define DEBUG_INPUT_SEL_SHIFT_SET(x) WLAN_DEBUG_INPUT_SEL_SHIFT_SET(x)
-#define DEBUG_INPUT_SEL_SRC_MSB WLAN_DEBUG_INPUT_SEL_SRC_MSB
-#define DEBUG_INPUT_SEL_SRC_LSB WLAN_DEBUG_INPUT_SEL_SRC_LSB
-#define DEBUG_INPUT_SEL_SRC_MASK WLAN_DEBUG_INPUT_SEL_SRC_MASK
-#define DEBUG_INPUT_SEL_SRC_GET(x) WLAN_DEBUG_INPUT_SEL_SRC_GET(x)
-#define DEBUG_INPUT_SEL_SRC_SET(x) WLAN_DEBUG_INPUT_SEL_SRC_SET(x)
-#define DEBUG_OUT_ADDRESS WLAN_DEBUG_OUT_ADDRESS
-#define DEBUG_OUT_OFFSET WLAN_DEBUG_OUT_OFFSET
-#define DEBUG_OUT_DATA_MSB WLAN_DEBUG_OUT_DATA_MSB
-#define DEBUG_OUT_DATA_LSB WLAN_DEBUG_OUT_DATA_LSB
-#define DEBUG_OUT_DATA_MASK WLAN_DEBUG_OUT_DATA_MASK
-#define DEBUG_OUT_DATA_GET(x) WLAN_DEBUG_OUT_DATA_GET(x)
-#define DEBUG_OUT_DATA_SET(x) WLAN_DEBUG_OUT_DATA_SET(x)
-#define RESET_TUPLE_STATUS_ADDRESS WLAN_RESET_TUPLE_STATUS_ADDRESS
-#define RESET_TUPLE_STATUS_OFFSET WLAN_RESET_TUPLE_STATUS_OFFSET
-#define RESET_TUPLE_STATUS_TEST_RESET_TUPLE_MSB WLAN_RESET_TUPLE_STATUS_TEST_RESET_TUPLE_MSB
-#define RESET_TUPLE_STATUS_TEST_RESET_TUPLE_LSB WLAN_RESET_TUPLE_STATUS_TEST_RESET_TUPLE_LSB
-#define RESET_TUPLE_STATUS_TEST_RESET_TUPLE_MASK WLAN_RESET_TUPLE_STATUS_TEST_RESET_TUPLE_MASK
-#define RESET_TUPLE_STATUS_TEST_RESET_TUPLE_GET(x) WLAN_RESET_TUPLE_STATUS_TEST_RESET_TUPLE_GET(x)
-#define RESET_TUPLE_STATUS_TEST_RESET_TUPLE_SET(x) WLAN_RESET_TUPLE_STATUS_TEST_RESET_TUPLE_SET(x)
-#define RESET_TUPLE_STATUS_PIN_RESET_TUPLE_MSB WLAN_RESET_TUPLE_STATUS_PIN_RESET_TUPLE_MSB
-#define RESET_TUPLE_STATUS_PIN_RESET_TUPLE_LSB WLAN_RESET_TUPLE_STATUS_PIN_RESET_TUPLE_LSB
-#define RESET_TUPLE_STATUS_PIN_RESET_TUPLE_MASK WLAN_RESET_TUPLE_STATUS_PIN_RESET_TUPLE_MASK
-#define RESET_TUPLE_STATUS_PIN_RESET_TUPLE_GET(x) WLAN_RESET_TUPLE_STATUS_PIN_RESET_TUPLE_GET(x)
-#define RESET_TUPLE_STATUS_PIN_RESET_TUPLE_SET(x) WLAN_RESET_TUPLE_STATUS_PIN_RESET_TUPLE_SET(x)
-
-
-#endif
-#endif
-
-
-
diff -druN linux-2.6.39-libre/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/mac_dma_reg.h linux-3.0-rc7-libre/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/mac_dma_reg.h
--- linux-2.6.39-libre/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/mac_dma_reg.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/mac_dma_reg.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,605 +0,0 @@
-// ------------------------------------------------------------------
-// Copyright (c) 2002-2010 Atheros Communications Inc.
-// All rights reserved.
-// 
-//
-// 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.
-//
-//
-// ------------------------------------------------------------------
-//===================================================================
-// Author(s): ="Atheros"
-//===================================================================
-
-
-/*****************************************************************************/
-/* AR6003 WLAN MAC DMA register definitions                                  */
-/*****************************************************************************/
-
-#ifndef _AR6000_DMAREG_H_
-#define _AR6000_DMAREG_H_
-
-/*
- * Definitions for the Atheros AR6003 chipset.
- */
-
-/* DMA Control and Interrupt Registers */
-#define MAC_DMA_CR_ADDRESS                       0x00000008 /* MAC control register */
-#define MAC_DMA_CR_RXE_MASK                      0x00000004 /* Receive enable */
-#define MAC_DMA_CR_RXD_MASK                      0x00000020 /* Receive disable */
-#define MAC_DMA_CR_SWI_MASK                      0x00000040 /* One-shot software interrupt */
-
-#define MAC_DMA_RXDP_ADDRESS                     0x0000000C /* MAC receive queue descriptor pointer */
-
-#define MAC_DMA_CFG_ADDRESS                      0x00000014 /* MAC configuration and status register */
-#define MAC_DMA_CFG_SWTD_MASK                    0x00000001 /* byteswap tx descriptor words */
-#define MAC_DMA_CFG_SWTB_MASK                    0x00000002 /* byteswap tx data buffer words */
-#define MAC_DMA_CFG_SWRD_MASK                    0x00000004 /* byteswap rx descriptor words */
-#define MAC_DMA_CFG_SWRB_MASK                    0x00000008 /* byteswap rx data buffer words */
-#define MAC_DMA_CFG_SWRG_MASK                    0x00000010 /* byteswap register access data words */
-#define MAC_DMA_CFG_AP_ADHOC_INDICATION_MASK     0x00000020 /* AP/adhoc indication (0-AP, 1-Adhoc) */
-#define MAC_DMA_CFG_PHOK_MASK                    0x00000100 /* PHY OK status */
-#define MAC_DMA_CFG_CLK_GATE_DIS_MASK            0x00000400 /* Clock gating disable  */
-
-#define MAC_DMA_MIRT_ADDRESS                     0x00000020 /* Maximum rate threshold register */
-#define MAC_DMA_MIRT_THRESH_MASK                 0x0000FFFF 
-
-#define MAC_DMA_IER_ADDRESS                      0x00000024  /* MAC Interrupt enable register */
-#define MAC_DMA_IER_ENABLE_MASK                  0x00000001 /* Global interrupt enable */
-#define MAC_DMA_IER_DISABLE_MASK                 0x00000000 /* Global interrupt disable */
-
-#define MAC_DMA_TIMT_ADDRESS                     0x00000028 /* Transmit Interrupt Mitigation Threshold */
-#define MAC_DMA_TIMT_LAST_PACKER_THRESH_MASK     0x0000FFFF /* Last packet threshold mask */
-#define MAC_DMA_TIMT_FIRST_PACKER_THRESH_MASK    0xFFFF0000 /* First packet threshold mask */
-
-#define MAC_DMA_RIMT_ADDRESS                     0x0000002C /* Receive Interrupt Mitigation Threshold */
-#define MAC_DMA_RIMT_LAST_PACKER_THRESH_MASK     0x0000FFFF /* Last packet threshold mask */
-#define MAC_DMA_RIMT_FIRST_PACKER_THRESH_MASK    0xFFFF0000 /* First packet threshold mask */
-
-#define MAC_DMA_TXCFG_ADDRESS                    0x00000030  /* MAC tx DMA size config register */
-#define MAC_DMA_FTRIG_MASK                       0x000003F0 /* Mask for Frame trigger level */
-#define MAC_DMA_FTRIG_LSB                        4          /* Shift for Frame trigger level */
-#define MAC_DMA_FTRIG_IMMED                      0x00000000 /* bytes in PCU TX FIFO before air */
-#define MAC_DMA_FTRIG_64B                        0x00000010 /* default */
-#define MAC_DMA_FTRIG_128B                       0x00000020
-#define MAC_DMA_FTRIG_192B                       0x00000030
-#define MAC_DMA_FTRIG_256B                       0x00000040 /* 5 bits total */
-#define MAC_DMA_TXCFG_ADHOC_BEACON_ATIM_TX_POLICY_MASK 0x00000800
-
-#define MAC_DMA_RXCFG_ADDRESS                     0x00000034  /* MAC rx DMA size config register */
-#define MAC_DMA_RXCFG_ZLFDMA_MASK                 0x00000010 /* Enable DMA of zero-length frame */
-#define MAC_DMA_RXCFG_DMASIZE_4B                  0x00000000 /* DMA size 4 bytes (TXCFG + RXCFG) */
-#define MAC_DMA_RXCFG_DMASIZE_8B                  0x00000001 /* DMA size 8 bytes */
-#define MAC_DMA_RXCFG_DMASIZE_16B                 0x00000002 /* DMA size 16 bytes */
-#define MAC_DMA_RXCFG_DMASIZE_32B                 0x00000003 /* DMA size 32 bytes */
-#define MAC_DMA_RXCFG_DMASIZE_64B                 0x00000004 /* DMA size 64 bytes */
-#define MAC_DMA_RXCFG_DMASIZE_128B                0x00000005 /* DMA size 128 bytes */
-#define MAC_DMA_RXCFG_DMASIZE_256B                0x00000006 /* DMA size 256 bytes */
-#define MAC_DMA_RXCFG_DMASIZE_512B                0x00000007 /* DMA size 512 bytes */
-
-#define MAC_DMA_MIBC_ADDRESS                      0x00000040  /* MAC MIB control register */
-#define MAC_DMA_MIBC_COW_MASK                     0x00000001 /* counter overflow warning */
-#define MAC_DMA_MIBC_FMC_MASK                     0x00000002 /* freeze MIB counters */
-#define MAC_DMA_MIBC_CMC_MASK                     0x00000004 /* clear MIB counters */
-#define MAC_DMA_MIBC_MCS_MASK                     0x00000008 /* MIB counter strobe, increment all */
-
-#define MAC_DMA_TOPS_ADDRESS                      0x00000044  /* MAC timeout prescale count */
-#define MAC_DMA_TOPS_MASK                         0x0000FFFF /* Mask for timeout prescale */
-
-#define MAC_DMA_RXNPTO_ADDRESS                    0x00000048  /* MAC no frame received timeout */
-#define MAC_DMA_RXNPTO_MASK                       0x000003FF /* Mask for no frame received timeout */
-
-#define MAC_DMA_TXNPTO_ADDRESS                    0x0000004C  /* MAC no frame trasmitted timeout */
-#define MAC_DMA_TXNPTO_MASK                       0x000003FF /* Mask for no frame transmitted timeout */
-#define MAC_DMA_TXNPTO_QCU_MASK                   0x000FFC00 /* Mask indicating the set of QCUs */
-                                                       /* for which frame completions will cause */
-                                                       /* a reset of the no frame xmit'd timeout */
-
-#define MAC_DMA_RPGTO_ADDRESS                     0x00000050  /* MAC receive frame gap timeout */
-#define MAC_DMA_RPGTO_MASK                        0x000003FF /* Mask for receive frame gap timeout */
-
-#define MAC_DMA_RPCNT_ADDRESS                     0x00000054  /* MAC receive frame count limit */
-#define MAC_DMA_RPCNT_MASK                        0x0000001F /* Mask for receive frame count limit */
-
-#define MAC_DMA_MACMISC_ADDRESS                   0x00000058  /* MAC miscellaneous control/status register */
-#define MAC_DMA_MACMISC_DMA_OBS_MASK              0x000001E0 /* Mask for DMA observation bus mux select */
-#define MAC_DMA_MACMISC_DMA_OBS_LSB               5          /* Shift for DMA observation bus mux select */
-#define MAC_DMA_MACMISC_MISC_OBS                  0x00000E00 /* Mask for MISC observation bus mux select */
-#define MAC_DMA_MACMISC_MISC_OBS_LSB              9          /* Shift for MISC observation bus mux select */
-#define MAC_DMA_MACMISC_MAC_OBS_BUS_LSB           0x00007000 /* Mask for MAC observation bus mux select (lsb) */
-#define MAC_DMA_MACMISC_MAC_OBS_BUS_LSB_LSB       12         /* Shift for MAC observation bus mux select (lsb) */
-#define MAC_DMA_MACMISC_MAC_OBS_BUS_MSB           0x00038000 /* Mask for MAC observation bus mux select (msb) */
-#define MAC_DMA_MACMISC_MAC_OBS_BUS_MSB_LSB       15         /* Shift for MAC observation bus mux select (msb) */
-
-
-#define MAC_DMA_ISR_ADDRESS                        0x00000080  /* MAC Primary interrupt status register */
-/*
- * Interrupt Status Registers
- *
- * Only the bits in the ISR_P register and the IMR_P registers
- * control whether the MAC's INTA# output is asserted.  The bits in
- * the secondary interrupt status/mask registers control what bits
- * are set in the primary interrupt status register; however the
- * IMR_S* registers DO NOT determine whether INTA# is asserted.
- * That is INTA# is asserted only when the logical AND of ISR_P
- * and IMR_P is non-zero.  The secondary interrupt mask/status
- * registers affect what bits are set in ISR_P but they do not
- * directly affect whether INTA# is asserted.
- */
-#define MAC_DMA_ISR_RXOK_MASK                    0x00000001 /* At least one frame received sans errors */
-#define MAC_DMA_ISR_RXDESC_MASK                  0x00000002 /* Receive interrupt request */
-#define MAC_DMA_ISR_RXERR_MASK                   0x00000004 /* Receive error interrupt */
-#define MAC_DMA_ISR_RXNOPKT_MASK                 0x00000008 /* No frame received within timeout clock */
-#define MAC_DMA_ISR_RXEOL_MASK                   0x00000010 /* Received descriptor empty interrupt */
-#define MAC_DMA_ISR_RXORN_MASK                   0x00000020 /* Receive FIFO overrun interrupt */
-#define MAC_DMA_ISR_TXOK_MASK                    0x00000040 /* Transmit okay interrupt */
-#define MAC_DMA_ISR_TXDESC_MASK                  0x00000080 /* Transmit interrupt request */
-#define MAC_DMA_ISR_TXERR_MASK                   0x00000100 /* Transmit error interrupt */
-#define MAC_DMA_ISR_TXNOPKT_MASK                 0x00000200 /* No frame transmitted interrupt */
-#define MAC_DMA_ISR_TXEOL_MASK                   0x00000400 /* Transmit descriptor empty interrupt */
-#define MAC_DMA_ISR_TXURN_MASK                   0x00000800 /* Transmit FIFO underrun interrupt */
-#define MAC_DMA_ISR_MIB_MASK                     0x00001000 /* MIB interrupt - see MIBC */
-#define MAC_DMA_ISR_SWI_MASK                     0x00002000 /* Software interrupt */
-#define MAC_DMA_ISR_RXPHY_MASK                   0x00004000 /* PHY receive error interrupt */
-#define MAC_DMA_ISR_RXKCM_MASK                   0x00008000 /* Key-cache miss interrupt */
-#define MAC_DMA_ISR_BRSSI_HI_MASK                0x00010000 /* Beacon rssi high threshold interrupt */
-#define MAC_DMA_ISR_BRSSI_LO_MASK                0x00020000 /* Beacon threshold interrupt */
-#define MAC_DMA_ISR_BMISS_MASK                   0x00040000 /* Beacon missed interrupt */
-#define MAC_DMA_ISR_TXMINTR_MASK                 0x00080000 /* Maximum transmit interrupt rate */
-#define MAC_DMA_ISR_BNR_MASK                     0x00100000 /* Beacon not ready interrupt */
-#define MAC_DMA_ISR_HIUERR_MASK                  0x00200000 /* An unexpected bus error has occurred */
-#define MAC_DMA_ISR_BCNMISC_MASK                 0x00800000 /* 'or' of TIM, CABEND, DTIMSYNC, BCNTO */
-#define MAC_DMA_ISR_RXMINTR_MASK                 0x01000000 /* Maximum receive interrupt rate */
-#define MAC_DMA_ISR_QCBROVF_MASK                 0x02000000 /* QCU CBR overflow interrupt */
-#define MAC_DMA_ISR_QCBRURN_MASK                 0x04000000 /* QCU CBR underrun interrupt */
-#define MAC_DMA_ISR_QTRIG_MASK                   0x08000000 /* QCU scheduling trigger interrupt */
-#define MAC_DMA_ISR_TIMER_MASK                   0x10000000 /* GENTMR interrupt */
-#define MAC_DMA_ISR_HCFTO_MASK                   0x20000000 /* HCFTO interrupt   */
-#define MAC_DMA_ISR_TXINTM_MASK                  0x40000000 /* Transmit completion mitigation interrupt */
-#define MAC_DMA_ISR_RXINTM_MASK                  0x80000000 /* Receive completion mitigation interrupt */
-
-#define MAC_DMA_ISR_S0_ADDRESS                   0x00000084  /* MAC Secondary interrupt status register 0 */
-#define MAC_DMA_ISR_S0_QCU_TXOK_MASK             0x000003FF /* Mask for TXOK (QCU 0-9) */
-#define MAC_DMA_ISR_S0_QCU_TXOK_LSB              0
-#define MAC_DMA_ISR_S0_QCU_TXDESC_MASK           0x03FF0000 /* Mask for TXDESC (QCU 0-9) */
-#define MAC_DMA_ISR_S0_QCU_TXDESC_LSB            16
-
-#define MAC_DMA_ISR_S1_ADDRESS                   0x00000088  /* MAC Secondary interrupt status register 1 */
-#define MAC_DMA_ISR_S1_QCU_TXERR_MASK            0x000003FF /* Mask for TXERR (QCU 0-9) */
-#define MAC_DMA_ISR_S1_QCU_TXERR_LSB             0
-#define MAC_DMA_ISR_S1_QCU_TXEOL_MASK            0x03FF0000 /* Mask for TXEOL (QCU 0-9) */
-#define MAC_DMA_ISR_S1_QCU_TXEOL_LSB             16
-
-#define MAC_DMA_ISR_S2_ADDRESS                      0x0000008c  /* MAC Secondary interrupt status register 2 */
-#define MAC_DMA_ISR_S2_QCU_TXURN_MASK               0x000003FF /* Mask for TXURN (QCU 0-9) */
-#define MAC_DMA_ISR_S2_QCU_TXURN_LSB                0 /* Shift for TXURN (QCU 0-9) */
-#define MAC_DMA_ISR_S2_RX_INT_MASK			        0x00000800
-#define MAC_DMA_ISR_S2_WL_STOMPED_MASK		        0x00001000
-#define MAC_DMA_ISR_S2_RX_PTR_BAD_MASK		        0x00002000
-#define MAC_DMA_ISR_S2_BT_LOW_PRIORITY_RISING_MASK  0x00004000
-#define MAC_DMA_ISR_S2_BT_LOW_PRIORITY_FALLING_MASK	0x00008000
-#define MAC_DMA_ISR_S2_BB_PANIC_IRQ_MASK            0x00010000
-#define MAC_DMA_ISR_S2_BT_STOMPED_MASK		        0x00020000
-#define MAC_DMA_ISR_S2_BT_ACTIVE_RISING_MASK	    0x00040000
-#define MAC_DMA_ISR_S2_BT_ACTIVE_FALLING_MASK	    0x00080000
-#define MAC_DMA_ISR_S2_BT_PRIORITY_RISING_MASK	    0x00100000
-#define MAC_DMA_ISR_S2_BT_PRIORITY_FALLING_MASK	    0x00200000
-#define MAC_DMA_ISR_S2_CST_MASK			            0x00400000
-#define MAC_DMA_ISR_S2_GTT_MASK			            0x00800000
-#define MAC_DMA_ISR_S2_TIM_MASK                     0x01000000 /* TIM */
-#define MAC_DMA_ISR_S2_CABEND_MASK                  0x02000000 /* CABEND */
-#define MAC_DMA_ISR_S2_DTIMSYNC_MASK                0x04000000 /* DTIMSYNC */
-#define MAC_DMA_ISR_S2_BCNTO_MASK                   0x08000000 /* BCNTO */
-#define MAC_DMA_ISR_S2_CABTO_MASK                   0x10000000 /* CABTO */
-#define MAC_DMA_ISR_S2_DTIM_MASK                    0x20000000 /* DTIM */
-#define MAC_DMA_ISR_S2_TSFOOR_MASK                  0x40000000 /* TSFOOR */
-
-#define MAC_DMA_ISR_S3_ADDRESS                   0x00000090  /* MAC Secondary interrupt status register 3 */
-#define MAC_DMA_ISR_S3_QCU_QCBROVF_MASK          0x000003FF /* Mask for QCBROVF (QCU 0-9) */
-#define MAC_DMA_ISR_S3_QCU_QCBRURN_MASK          0x03FF0000 /* Mask for QCBRURN (QCU 0-9) */
-
-#define MAC_DMA_ISR_S4_ADDRESS                   0x00000094  /* MAC Secondary interrupt status register 4 */
-#define MAC_DMA_ISR_S4_QCU_QTRIG_MASK            0x000003FF /* Mask for QTRIG (QCU 0-9) */
-
-#define MAC_DMA_ISR_S5_ADDRESS                   0x00000098  /* MAC Secondary interrupt status register 5 */
-#define MAC_DMA_ISR_S5_TBTT_TIMER_TRIGGER_MASK   0x00000001
-#define MAC_DMA_ISR_S5_DBA_TIMER_TRIGGER_MASK    0x00000002
-#define MAC_DMA_ISR_S5_SBA_TIMER_TRIGGER_MASK    0x00000004
-#define MAC_DMA_ISR_S5_HCF_TIMER_TRIGGER_MASK    0x00000008
-#define MAC_DMA_ISR_S5_TIM_TIMER_TRIGGER_MASK    0x00000010
-#define MAC_DMA_ISR_S5_DTIM_TIMER_TRIGGER_MASK   0x00000020
-#define MAC_DMA_ISR_S5_QUIET_TIMER_TRIGGER_MASK  0x00000040
-#define MAC_DMA_ISR_S5_NDP_TIMER_TRIGGER_MASK    0x00000080
-#define MAC_DMA_ISR_S5_GENERIC_TIMER2_TRIGGER_MASK 0x0000FF00
-#define MAC_DMA_ISR_S5_GENERIC_TIMER2_TRIGGER_LSB 8 
-#define MAC_DMA_ISR_S5_GENERIC_TIMER2_TRIGGER(_i) (0x00000100 << (_i))
-#define MAC_DMA_ISR_S5_TIMER_OVERFLOW_MASK       0x00010000
-#define MAC_DMA_ISR_S5_DBA_TIMER_THRESHOLD_MASK  0x00020000
-#define MAC_DMA_ISR_S5_SBA_TIMER_THRESHOLD_MASK  0x00040000
-#define MAC_DMA_ISR_S5_HCF_TIMER_THRESHOLD_MASK  0x00080000
-#define MAC_DMA_ISR_S5_TIM_TIMER_THRESHOLD_MASK  0x00100000
-#define MAC_DMA_ISR_S5_DTIM_TIMER_THRESHOLD_MASK  0x00200000
-#define MAC_DMA_ISR_S5_QUIET_TIMER_THRESHOLD_MASK 0x00400000
-#define MAC_DMA_ISR_S5_NDP_TIMER_THRESHOLD_MASK   0x00800000
-#define MAC_DMA_IMR_S5_GENERIC_TIMER2_THRESHOLD_MASK 0xFF000000
-#define MAC_DMA_IMR_S5_GENERIC_TIMER2_THRESHOLD_LSB  24 
-#define MAC_DMA_IMR_S5_GENERIC_TIMER2_THRESHOLD(_i) (0x01000000 << (_i))
-
-#define MAC_DMA_IMR_ADDRESS                      0x000000A0  /* MAC Primary interrupt mask register */
-/*
- * Interrupt Mask Registers
- *
- * Only the bits in the IMR control whether the MAC's INTA#
- * output will be asserted.  The bits in the secondary interrupt
- * mask registers control what bits get set in the primary
- * interrupt status register; however the IMR_S* registers
- * DO NOT determine whether INTA# is asserted.
- */
-#define MAC_DMA_IMR_RXOK_MASK                    0x00000001 /* At least one frame received sans errors */
-#define MAC_DMA_IMR_RXDESC_MASK                  0x00000002 /* Receive interrupt request */
-#define MAC_DMA_IMR_RXERR_MASK                   0x00000004 /* Receive error interrupt */
-#define MAC_DMA_IMR_RXNOPKT_MASK                 0x00000008 /* No frame received within timeout clock */
-#define MAC_DMA_IMR_RXEOL_MASK                   0x00000010 /* Received descriptor empty interrupt */
-#define MAC_DMA_IMR_RXORN_MASK                   0x00000020 /* Receive FIFO overrun interrupt */
-#define MAC_DMA_IMR_TXOK_MASK                    0x00000040 /* Transmit okay interrupt */
-#define MAC_DMA_IMR_TXDESC_MASK                  0x00000080 /* Transmit interrupt request */
-#define MAC_DMA_IMR_TXERR_MASK                   0x00000100 /* Transmit error interrupt */
-#define MAC_DMA_IMR_TXNOPKT_MASK                 0x00000200 /* No frame transmitted interrupt */
-#define MAC_DMA_IMR_TXEOL_MASK                   0x00000400 /* Transmit descriptor empty interrupt */
-#define MAC_DMA_IMR_TXURN_MASK                   0x00000800 /* Transmit FIFO underrun interrupt */
-#define MAC_DMA_IMR_MIB_MASK                     0x00001000 /* MIB interrupt - see MIBC */
-#define MAC_DMA_IMR_SWI_MASK                     0x00002000 /* Software interrupt */
-#define MAC_DMA_IMR_RXPHY_MASK                   0x00004000 /* PHY receive error interrupt */
-#define MAC_DMA_IMR_RXKCM_MASK                   0x00008000 /* Key-cache miss interrupt */
-#define MAC_DMA_IMR_BRSSI_HI_MASK                0x00010000 /* Beacon rssi hi threshold interrupt */
-#define MAC_DMA_IMR_BRSSI_LO_MASK                0x00020000 /* Beacon rssi lo threshold interrupt */
-#define MAC_DMA_IMR_BMISS_MASK                   0x00040000 /* Beacon missed interrupt */
-#define MAC_DMA_IMR_TXMINTR_MASK                 0x00080000 /* Maximum transmit interrupt rate */
-#define MAC_DMA_IMR_BNR_MASK                     0x00100000 /* BNR interrupt */
-#define MAC_DMA_IMR_HIUERR_MASK                  0x00200000 /* An unexpected bus error has occurred */
-#define MAC_DMA_IMR_BCNMISC_MASK                 0x00800000 /* Beacon Misc */
-#define MAC_DMA_IMR_RXMINTR_MASK                 0x01000000 /* Maximum receive interrupt rate */
-#define MAC_DMA_IMR_QCBROVF_MASK                 0x02000000 /* QCU CBR overflow interrupt */
-#define MAC_DMA_IMR_QCBRURN_MASK                 0x04000000 /* QCU CBR underrun interrupt */
-#define MAC_DMA_IMR_QTRIG_MASK                   0x08000000 /* QCU scheduling trigger interrupt */
-#define MAC_DMA_IMR_TIMER_MASK                   0x10000000 /* GENTMR interrupt */
-#define MAC_DMA_IMR_HCFTO_MASK                   0x20000000 /* HCFTO interrupt*/
-#define MAC_DMA_IMR_TXINTM_MASK                  0x40000000 /* Transmit completion mitigation interrupt */
-#define MAC_DMA_IMR_RXINTM_MASK                  0x80000000 /* Receive completion mitigation interrupt */
-
-#define MAC_DMA_IMR_S0_ADDRESS                   0x000000A4  /* MAC Secondary interrupt mask register 0 */
-#define MAC_DMA_IMR_S0_QCU_TXOK_MASK             0x000003FF /* TXOK (QCU 0-9) */
-#define MAC_DMA_IMR_S0_QCU_TXOK_LSB              0
-#define MAC_DMA_IMR_S0_QCU_TXDESC_MASK           0x03FF0000 /* TXDESC (QCU 0-9) */
-#define MAC_DMA_IMR_S0_QCU_TXDESC_LSB            16
-
-#define MAC_DMA_IMR_S1_ADDRESS                   0x000000A8  /* MAC Secondary interrupt mask register 1 */
-#define MAC_DMA_IMR_S1_QCU_TXERR_MASK            0x000003FF /* TXERR (QCU 0-9) */
-#define MAC_DMA_IMR_S1_QCU_TXERR_LSB             0
-#define MAC_DMA_IMR_S1_QCU_TXEOL_MASK            0x03FF0000 /* TXEOL (QCU 0-9) */
-#define MAC_DMA_IMR_S1_QCU_TXEOL_LSB             16
-
-#define MAC_DMA_IMR_S2_ADDRESS                      0x000000AC  /* MAC Secondary interrupt mask register 2 */
-#define MAC_DMA_IMR_S2_QCU_TXURN_MASK               0x000003FF /* Mask for TXURN (QCU 0-9) */
-#define MAC_DMA_IMR_S2_QCU_TXURN_LSB                0
-#define MAC_DMA_IMR_S2_RX_INT_MASK			        0x00000800
-#define MAC_DMA_IMR_S2_WL_STOMPED_MASK		        0x00001000
-#define MAC_DMA_IMR_S2_RX_PTR_BAD_MASK		        0x00002000
-#define MAC_DMA_IMR_S2_BT_LOW_PRIORITY_RISING_MASK  0x00004000
-#define MAC_DMA_IMR_S2_BT_LOW_PRIORITY_FALLING_MASK	0x00008000
-#define MAC_DMA_IMR_S2_BB_PANIC_IRQ_MASK            0x00010000
-#define MAC_DMA_IMR_S2_BT_STOMPED_MASK		        0x00020000
-#define MAC_DMA_IMR_S2_BT_ACTIVE_RISING_MASK	    0x00040000
-#define MAC_DMA_IMR_S2_BT_ACTIVE_FALLING_MASK	    0x00080000
-#define MAC_DMA_IMR_S2_BT_PRIORITY_RISING_MASK	    0x00100000
-#define MAC_DMA_IMR_S2_BT_PRIORITY_FALLING_MASK	    0x00200000
-#define MAC_DMA_IMR_S2_CST_MASK			            0x00400000
-#define MAC_DMA_IMR_S2_GTT_MASK			            0x00800000
-#define MAC_DMA_IMR_S2_TIM_MASK                     0x01000000 /* TIM */
-#define MAC_DMA_IMR_S2_CABEND_MASK                  0x02000000 /* CABEND */
-#define MAC_DMA_IMR_S2_DTIMSYNC_MASK                0x04000000 /* DTIMSYNC */
-#define MAC_DMA_IMR_S2_BCNTO_MASK                   0x08000000 /* BCNTO */
-#define MAC_DMA_IMR_S2_CABTO_MASK                   0x10000000 /* CABTO */
-#define MAC_DMA_IMR_S2_DTIM_MASK                    0x20000000 /* DTIM */
-#define MAC_DMA_IMR_S2_TSFOOR_MASK                  0x40000000 /* TSFOOR */
-
-#define MAC_DMA_IMR_S3_ADDRESS                   0x000000B0  /* MAC Secondary interrupt mask register 3 */
-#define MAC_DMA_IMR_S3_QCU_QCBROVF_MASK          0x000003FF /* Mask for QCBROVF (QCU 0-9) */
-#define MAC_DMA_IMR_S3_QCU_QCBRURN_MASK          0x03FF0000 /* Mask for QCBRURN (QCU 0-9) */
-#define MAC_DMA_IMR_S3_QCU_QCBRURN_LSB           16 
-
-#define MAC_DMA_IMR_S4_ADDRESS                   0x000000B4  /* MAC Secondary interrupt mask register 4 */
-#define MAC_DMA_IMR_S4_QCU_QTRIG_MASK            0x000003FF /* Mask for QTRIG (QCU 0-9) */
-
-#define MAC_DMA_IMR_S5_ADDRESS                   0x000000B8  /* MAC Secondary interrupt mask register 5 */
-#define MAC_DMA_IMR_S5_TBTT_TIMER_TRIGGER_MASK   0x00000001
-#define MAC_DMA_IMR_S5_DBA_TIMER_TRIGGER_MASK    0x00000002
-#define MAC_DMA_IMR_S5_SBA_TIMER_TRIGGER_MASK    0x00000004
-#define MAC_DMA_IMR_S5_HCF_TIMER_TRIGGER_MASK    0x00000008
-#define MAC_DMA_IMR_S5_TIM_TIMER_TRIGGER_MASK    0x00000010
-#define MAC_DMA_IMR_S5_DTIM_TIMER_TRIGGER_MASK   0x00000020
-#define MAC_DMA_IMR_S5_QUIET_TIMER_TRIGGER_MASK  0x00000040
-#define MAC_DMA_IMR_S5_NDP_TIMER_TRIGGER_MASK    0x00000080
-#define MAC_DMA_IMR_S5_GENERIC_TIMER2_TRIGGER_MASK 0x0000FF00
-#define MAC_DMA_IMR_S5_GENERIC_TIMER2_TRIGGER_LSB 8 
-#define MAC_DMA_IMR_S5_GENERIC_TIMER2_TRIGGER(_i)    (0x100 << (_i))
-#define MAC_DMA_IMR_S5_TIMER_OVERFLOW_MASK       0x00010000
-#define MAC_DMA_IMR_S5_DBA_TIMER_THRESHOLD_MASK  0x00020000
-#define MAC_DMA_IMR_S5_SBA_TIMER_THRESHOLD_MASK  0x00040000
-#define MAC_DMA_IMR_S5_HCF_TIMER_THRESHOLD_MASK  0x00080000
-#define MAC_DMA_IMR_S5_TIM_TIMER_THRESHOLD_MASK  0x00100000
-#define MAC_DMA_IMR_S5_DTIM_TIMER_THRESHOLD_MASK 0x00200000
-#define MAC_DMA_IMR_S5_QUIET_TIMER_THRESHOLD_MASK 0000400000
-#define MAC_DMA_IMR_S5_NDP_TIMER_THRESHOLD_MASK  0x00800000
-#define MAC_DMA_IMR_S5_GENERIC_TIMER2_THRESHOLD_MASK 0xFF000000
-#define MAC_DMA_IMR_S5_GENERIC_TIMER2_THRESHOLD_LSB  24 
-#define MAC_DMA_IMR_S5_GENERIC_TIMER2_THRESHOLD(_i) (0x01000000 << (_i))
-
-#define MAC_DMA_ISR_RAC_ADDRESS                  0x000000C0  /* ISR read-and-clear access */
-
-/* Shadow copies with read-and-clear access */
-#define MAC_DMA_ISR_S0_S_ADDRESS                 0x000000C4  /* ISR_S0 shadow copy */
-#define MAC_DMA_ISR_S1_S_ADDRESS                 0x000000C8  /* ISR_S1 shadow copy */
-#define MAC_DMA_ISR_S2_S_ADDRESS                 0x000000Cc  /* ISR_S2 shadow copy */
-#define MAC_DMA_ISR_S3_S_ADDRESS                 0x000000D0  /* ISR_S3 shadow copy */
-#define MAC_DMA_ISR_S4_S_ADDRESS                 0x000000D4  /* ISR_S4 shadow copy */
-#define MAC_DMA_ISR_S5_S_ADDRESS                 0x000000D8  /* ISR_S5 shadow copy */
-
-#define MAC_DMA_Q0_TXDP_ADDRESS                  0x00000800  /* MAC Transmit Queue descriptor pointer */
-#define MAC_DMA_Q1_TXDP_ADDRESS                  0x00000804  /* MAC Transmit Queue descriptor pointer */
-#define MAC_DMA_Q2_TXDP_ADDRESS                  0x00000808  /* MAC Transmit Queue descriptor pointer */
-#define MAC_DMA_Q3_TXDP_ADDRESS                  0x0000080C  /* MAC Transmit Queue descriptor pointer */
-#define MAC_DMA_Q4_TXDP_ADDRESS                  0x00000810  /* MAC Transmit Queue descriptor pointer */
-#define MAC_DMA_Q5_TXDP_ADDRESS                  0x00000814  /* MAC Transmit Queue descriptor pointer */
-#define MAC_DMA_Q6_TXDP_ADDRESS                  0x00000818  /* MAC Transmit Queue descriptor pointer */
-#define MAC_DMA_Q7_TXDP_ADDRESS                  0x0000081C  /* MAC Transmit Queue descriptor pointer */
-#define MAC_DMA_Q8_TXDP_ADDRESS                  0x00000820  /* MAC Transmit Queue descriptor pointer */
-#define MAC_DMA_Q9_TXDP_ADDRESS                  0x00000824  /* MAC Transmit Queue descriptor pointer */
-#define MAC_DMA_QTXDP_ADDRESS(_i)                (MAC_DMA_Q0_TXDP_ADDRESS + ((_i)<<2))
-
-#define MAC_DMA_Q_TXE_ADDRESS                    0x00000840  /* MAC Transmit Queue enable */
-#define MAC_DMA_Q_TXD_ADDRESS                    0x00000880  /* MAC Transmit Queue disable */
-/* QCU registers */
-
-#define MAC_DMA_Q0_CBRCFG_ADDRESS                0x000008C0  /* MAC CBR configuration */
-#define MAC_DMA_Q1_CBRCFG_ADDRESS                0x000008C4  /* MAC CBR configuration */
-#define MAC_DMA_Q2_CBRCFG_ADDRESS                0x000008C8  /* MAC CBR configuration */
-#define MAC_DMA_Q3_CBRCFG_ADDRESS                0x000008CC  /* MAC CBR configuration */
-#define MAC_DMA_Q4_CBRCFG_ADDRESS                0x000008D0  /* MAC CBR configuration */
-#define MAC_DMA_Q5_CBRCFG_ADDRESS                0x000008D4  /* MAC CBR configuration */
-#define MAC_DMA_Q6_CBRCFG_ADDRESS                0x000008D8  /* MAC CBR configuration */
-#define MAC_DMA_Q7_CBRCFG_ADDRESS                0x000008DC  /* MAC CBR configuration */
-#define MAC_DMA_Q8_CBRCFG_ADDRESS                0x000008E0  /* MAC CBR configuration */
-#define MAC_DMA_Q9_CBRCFG_ADDRESS                0x000008E4  /* MAC CBR configuration */
-#define MAC_DMA_QCBRCFG_ADDRESS(_i)             (MAC_DMA_Q0_CBRCFG_ADDRESS + ((_i)<<2))
-
-#define MAC_DMA_Q_CBRCFG_CBR_INTERVAL_MASK        0x00FFFFFF /* Mask for CBR interval (us) */
-#define MAC_DMA_Q_CBRCFG_CBR_INTERVAL_LSB         0   /* Shift for CBR interval */
-#define MAC_DMA_Q_CBRCFG_CBR_OVF_THRESH_MASK      0xFF000000 /* Mask for CBR overflow threshold */
-#define MAC_DMA_Q_CBRCFG_CBR_OVF_THRESH_LSB       24  /* Shift for CBR overflow thresh */
-
-
-#define MAC_DMA_Q0_RDYTIMECFG_ADDRESS             0x00000900  /* MAC ReadyTime configuration */
-#define MAC_DMA_Q1_RDYTIMECFG_ADDRESS             0x00000904  /* MAC ReadyTime configuration */
-#define MAC_DMA_Q2_RDYTIMECFG_ADDRESS             0x00000908  /* MAC ReadyTime configuration */
-#define MAC_DMA_Q3_RDYTIMECFG_ADDRESS             0x0000090C  /* MAC ReadyTime configuration */
-#define MAC_DMA_Q4_RDYTIMECFG_ADDRESS             0x00000910  /* MAC ReadyTime configuration */
-#define MAC_DMA_Q5_RDYTIMECFG_ADDRESS             0x00000914  /* MAC ReadyTime configuration */
-#define MAC_DMA_Q6_RDYTIMECFG_ADDRESS             0x00000918  /* MAC ReadyTime configuration */
-#define MAC_DMA_Q7_RDYTIMECFG_ADDRESS             0x0000091C  /* MAC ReadyTime configuration */
-#define MAC_DMA_Q8_RDYTIMECFG_ADDRESS             0x00000920  /* MAC ReadyTime configuration */
-#define MAC_DMA_Q9_RDYTIMECFG_ADDRESS             0x00000924  /* MAC ReadyTime configuration */
-#define MAC_DMA_QRDYTIMECFG_ADDRESS(_i)           (MAC_DMA_Q0_RDYTIMECFG_ADDRESS + ((_i)<<2))
-
-#define MAC_DMA_Q_RDYTIMECFG_INT_MASK             0x00FFFFFF /* CBR interval (us) */
-#define MAC_DMA_Q_RDYTIMECFG_INT_LSB              0  /* Shift for ReadyTime Interval (us) */
-#define MAC_DMA_Q_RDYTIMECFG_ENA_MASK             0x01000000 /* CBR enable */
-
-#define MAC_DMA_Q_ONESHOTMAC_DMAM_SC_ADDRESS      0x00000940  /* MAC OneShotArm set control */
-#define MAC_DMA_Q_ONESHOTMAC_DMAM_CC_ADDRESS      0x00000980  /* MAC OneShotArm clear control */
-
-#define MAC_DMA_Q0_MISC_ADDRESS                   0x000009C0  /* MAC Miscellaneous QCU settings */
-#define MAC_DMA_Q1_MISC_ADDRESS                   0x000009C4  /* MAC Miscellaneous QCU settings */
-#define MAC_DMA_Q2_MISC_ADDRESS                   0x000009C8  /* MAC Miscellaneous QCU settings */
-#define MAC_DMA_Q3_MISC_ADDRESS                   0x000009CC  /* MAC Miscellaneous QCU settings */
-#define MAC_DMA_Q4_MISC_ADDRESS                   0x000009D0  /* MAC Miscellaneous QCU settings */
-#define MAC_DMA_Q5_MISC_ADDRESS                   0x000009D4  /* MAC Miscellaneous QCU settings */
-#define MAC_DMA_Q6_MISC_ADDRESS                   0x000009D8  /* MAC Miscellaneous QCU settings */
-#define MAC_DMA_Q7_MISC_ADDRESS                   0x000009DC  /* MAC Miscellaneous QCU settings */
-#define MAC_DMA_Q8_MISC_ADDRESS                   0x000009E0  /* MAC Miscellaneous QCU settings */
-#define MAC_DMA_Q9_MISC_ADDRESS                   0x000009E4  /* MAC Miscellaneous QCU settings */
-#define MAC_DMA_QMISC_ADDRESS(_i)                 (MAC_DMA_Q0_MISC_ADDRESS + ((_i)<<2))
-
-#define MAC_DMA_Q_MISC_FSP_MASK                   0x0000000F /* Frame Scheduling Policy mask */
-#define MAC_DMA_Q_MISC_FSP_ASAP                   0   /* ASAP */
-#define MAC_DMA_Q_MISC_FSP_CBR                    1   /* CBR */
-#define MAC_DMA_Q_MISC_FSP_DBA_GATED              2   /* DMA Beacon Alert gated */
-#define MAC_DMA_Q_MISC_FSP_TIM_GATED              3   /* TIM gated */
-#define MAC_DMA_Q_MISC_FSP_BEACON_SENT_GATED      4   /* Beacon-sent-gated */
-#define MAC_DMA_Q_MISC_ONE_SHOT_EN_MASK           0x00000010 /* OneShot enable */
-#define MAC_DMA_Q_MISC_CBR_INCR_DIS1_MASK         0x00000020 /* Disable CBR expired counter incr
-                                                        (empty q) */
-#define MAC_DMA_Q_MISC_CBR_INCR_DIS0_MASK         0x00000040 /* Disable CBR expired counter incr
-                                                        (empty beacon q) */
-#define MAC_DMA_Q_MISC_BEACON_USE_MASK            0x00000080 /* Beacon use indication */
-#define MAC_DMA_Q_MISC_CBR_EXP_CNTR_LIMIT_MASK    0x00000100 /* CBR expired counter limit enable */
-#define MAC_DMA_Q_MISC_RDYTIME_EXP_POLICY_MASK    0x00000200 /* Enable TXE cleared on ReadyTime expired or VEOL */
-#define MAC_DMA_Q_MISC_RESET_CBR_EXP_CTR_MASK     0x00000400 /* Reset CBR expired counter */
-#define MAC_DMA_Q_MISC_DCU_EARLY_TERM_REQ_MASK    0x00000800 /* DCU frame early termination request control */
-
-#define MAC_DMA_Q0_STS_ADDRESS                   0x00000A00  /* MAC Miscellaneous QCU status */
-#define MAC_DMA_Q1_STS_ADDRESS                   0x00000A04  /* MAC Miscellaneous QCU status */
-#define MAC_DMA_Q2_STS_ADDRESS                   0x00000A08  /* MAC Miscellaneous QCU status */
-#define MAC_DMA_Q3_STS_ADDRESS                   0x00000A0C  /* MAC Miscellaneous QCU status */
-#define MAC_DMA_Q4_STS_ADDRESS                   0x00000A10  /* MAC Miscellaneous QCU status */
-#define MAC_DMA_Q5_STS_ADDRESS                   0x00000A14  /* MAC Miscellaneous QCU status */
-#define MAC_DMA_Q6_STS_ADDRESS                   0x00000A18  /* MAC Miscellaneous QCU status */
-#define MAC_DMA_Q7_STS_ADDRESS                   0x00000A1C  /* MAC Miscellaneous QCU status */
-#define MAC_DMA_Q8_STS_ADDRESS                   0x00000A20  /* MAC Miscellaneous QCU status */
-#define MAC_DMA_Q9_STS_ADDRESS                   0x00000A24  /* MAC Miscellaneous QCU status */
-#define MAC_DMA_QSTS_ADDRESS(_i)                 (MAC_DMA_Q0_STS_ADDRESS + ((_i)<<2))
-
-#define MAC_DMA_Q_STS_PEND_FR_CNT_MASK           0x00000003 /* Mask for Pending Frame Count */
-#define MAC_DMA_Q_STS_CBR_EXP_CNT_MASK           0x0000FF00 /* Mask for CBR expired counter */
-
-#define MAC_DMA_Q_RDYTIMESHDN_ADDRESS            0x00000A40  /* MAC ReadyTimeShutdown status */
-
-/* DCU registers */
-
-#define MAC_DMA_D0_QCUMASK_ADDRESS               0x00001000  /* MAC QCU Mask */
-#define MAC_DMA_D1_QCUMASK_ADDRESS               0x00001004  /* MAC QCU Mask */
-#define MAC_DMA_D2_QCUMASK_ADDRESS               0x00001008  /* MAC QCU Mask */
-#define MAC_DMA_D3_QCUMASK_ADDRESS               0x0000100C  /* MAC QCU Mask */
-#define MAC_DMA_D4_QCUMASK_ADDRESS               0x00001010  /* MAC QCU Mask */
-#define MAC_DMA_D5_QCUMASK_ADDRESS               0x00001014  /* MAC QCU Mask */
-#define MAC_DMA_D6_QCUMASK_ADDRESS               0x00001018  /* MAC QCU Mask */
-#define MAC_DMA_D7_QCUMASK_ADDRESS               0x0000101C  /* MAC QCU Mask */
-#define MAC_DMA_D8_QCUMASK_ADDRESS               0x00001020  /* MAC QCU Mask */
-#define MAC_DMA_D9_QCUMASK_ADDRESS               0x00001024  /* MAC QCU Mask */
-#define MAC_DMA_DQCUMASK_ADDRESS(_i)             (MAC_DMA_D0_QCUMASK_ADDRESS + ((_i)<<2))
-
-#define MAC_DMA_D_QCUMASK_MASK                   0x000003FF /* Mask for QCU Mask (QCU 0-9) */
-
-#define MAC_DMA_D_GBL_IFS_SIFS_ADDRESS           0x00001030  /* DCU global SIFS settings */
-
-
-#define MAC_DMA_D0_LCL_IFS_ADDRESS               0x00001040  /* MAC DCU-specific IFS settings */
-#define MAC_DMA_D1_LCL_IFS_ADDRESS               0x00001044  /* MAC DCU-specific IFS settings */
-#define MAC_DMA_D2_LCL_IFS_ADDRESS               0x00001048  /* MAC DCU-specific IFS settings */
-#define MAC_DMA_D3_LCL_IFS_ADDRESS               0x0000104C  /* MAC DCU-specific IFS settings */
-#define MAC_DMA_D4_LCL_IFS_ADDRESS               0x00001050  /* MAC DCU-specific IFS settings */
-#define MAC_DMA_D5_LCL_IFS_ADDRESS               0x00001054  /* MAC DCU-specific IFS settings */
-#define MAC_DMA_D6_LCL_IFS_ADDRESS               0x00001058  /* MAC DCU-specific IFS settings */
-#define MAC_DMA_D7_LCL_IFS_ADDRESS               0x0000105C  /* MAC DCU-specific IFS settings */
-#define MAC_DMA_D8_LCL_IFS_ADDRESS               0x00001060  /* MAC DCU-specific IFS settings */
-#define MAC_DMA_D9_LCL_IFS_ADDRESS               0x00001064  /* MAC DCU-specific IFS settings */
-#define MAC_DMA_DLCL_IFS_ADDRESS(_i)             (MAC_DMA_D0_LCL_IFS_ADDRESS + ((_i)<<2))
-#define MAC_DMA_D_LCL_IFS_CWMIN_MASK             0x000003FF /* Mask for CW_MIN */
-#define MAC_DMA_D_LCL_IFS_CWMIN_LSB              0
-#define MAC_DMA_D_LCL_IFS_CWMAX_MASK             0x000FFC00 /* Mask for CW_MAX */
-#define MAC_DMA_D_LCL_IFS_CWMAX_LSB              10
-#define MAC_DMA_D_LCL_IFS_AIFS_MASK              0x0FF00000 /* Mask for AIFS */
-#define MAC_DMA_D_LCL_IFS_AIFS_LSB               20
-/*
- *  Note:  even though this field is 8 bits wide the
- *  maximum supported AIFS value is 0xFc.  Setting the AIFS value
- *  to 0xFd 0xFe, or 0xFf will not work correctly and will cause
- *  the DCU to hang.
- */
-#define MAC_DMA_D_GBL_IFS_SLOT_ADDRESS           0x00001070  /* DC global slot interval */
-
-#define MAC_DMA_D0_RETRY_LIMIT_ADDRESS           0x00001080  /* MAC Retry limits */
-#define MAC_DMA_D1_RETRY_LIMIT_ADDRESS           0x00001084  /* MAC Retry limits */
-#define MAC_DMA_D2_RETRY_LIMIT_ADDRESS           0x00001088  /* MAC Retry limits */
-#define MAC_DMA_D3_RETRY_LIMIT_ADDRESS           0x0000108C  /* MAC Retry limits */
-#define MAC_DMA_D4_RETRY_LIMIT_ADDRESS           0x00001090  /* MAC Retry limits */
-#define MAC_DMA_D5_RETRY_LIMIT_ADDRESS           0x00001094  /* MAC Retry limits */
-#define MAC_DMA_D6_RETRY_LIMIT_ADDRESS           0x00001098  /* MAC Retry limits */
-#define MAC_DMA_D7_RETRY_LIMIT_ADDRESS           0x0000109C  /* MAC Retry limits */
-#define MAC_DMA_D8_RETRY_LIMIT_ADDRESS           0x000010A0  /* MAC Retry limits */
-#define MAC_DMA_D9_RETRY_LIMIT_ADDRESS           0x000010A4  /* MAC Retry limits */
-#define MAC_DMA_DRETRY_LIMIT_ADDRESS(_i)         (MAC_DMA_D0_RETRY_LIMIT_ADDRESS + ((_i)<<2))
-
-#define MAC_DMA_D_RETRY_LIMIT_FR_RTS_MASK        0x0000000F /* frame RTS failure limit */
-#define MAC_DMA_D_RETRY_LIMIT_FR_RTS_LSB         0
-#define MAC_DMA_D_RETRY_LIMIT_STA_RTS_MASK       0x00003F00 /* station RTS failure limit */
-#define MAC_DMA_D_RETRY_LIMIT_STA_RTS_LSB        8
-#define MAC_DMA_D_RETRY_LIMIT_STA_DATA_MASK      0x000FC000 /* station short retry limit */
-#define MAC_DMA_D_RETRY_LIMIT_STA_DATA_LSB       14
-
-#define MAC_DMA_D_GBL_IFS_EIFS_ADDRESS           0x000010B0  /* DCU global EIFS setting */
-
-#define MAC_DMA_D0_CHNTIME_ADDRESS               0x000010C0  /* MAC ChannelTime settings */
-#define MAC_DMA_D1_CHNTIME_ADDRESS               0x000010C4  /* MAC ChannelTime settings */
-#define MAC_DMA_D2_CHNTIME_ADDRESS               0x000010C8  /* MAC ChannelTime settings */
-#define MAC_DMA_D3_CHNTIME_ADDRESS               0x000010CC  /* MAC ChannelTime settings */
-#define MAC_DMA_D4_CHNTIME_ADDRESS               0x000010D0  /* MAC ChannelTime settings */
-#define MAC_DMA_D5_CHNTIME_ADDRESS               0x000010D4  /* MAC ChannelTime settings */
-#define MAC_DMA_D6_CHNTIME_ADDRESS               0x000010D8  /* MAC ChannelTime settings */
-#define MAC_DMA_D7_CHNTIME_ADDRESS               0x000010DC  /* MAC ChannelTime settings */
-#define MAC_DMA_D8_CHNTIME_ADDRESS               0x000010E0  /* MAC ChannelTime settings */
-#define MAC_DMA_D9_CHNTIME_ADDRESS               0x000010E4  /* MAC ChannelTime settings */
-#define MAC_DMA_DCHNTIME_ADDRESS(_i)             (MAC_DMA_D0_CHNTIME_ADDRESS + ((_i)<<2))
-
-#define MAC_DMA_D_CHNTIME_DUR_MASK               0x000FFFFF /* ChannelTime duration (us) */
-#define MAC_DMA_D_CHNTIME_DUR_LSB                0 /* Shift for ChannelTime duration */
-#define MAC_DMA_D_CHNTIME_EN_MASK                0x00100000 /* ChannelTime enable */
-
-#define MAC_DMA_D_GBL_IFS_MISC_ADDRESS           0x000010f0  /* DCU global misc. IFS settings */
-#define MAC_DMA_D_GBL_IFS_MISC_LFSR_SLICE_SEL_MASK 0x00000007 /* LFSR slice select */
-#define MAC_DMA_D_GBL_IFS_MISC_TURBO_MODE_MASK     0x00000008 /* Turbo mode indication */
-#define MAC_DMA_D_GBL_IFS_MISC_DCU_ARBITER_DLY_MASK 0x00300000 /* DCU arbiter delay */
-#define MAC_DMA_D_GBL_IFS_IGNORE_BACKOFF_MASK      0x10000000
-
-#define MAC_DMA_D0_MISC_ADDRESS                  0x00001100  /* MAC Miscellaneous DCU-specific settings */
-#define MAC_DMA_D1_MISC_ADDRESS                  0x00001104  /* MAC Miscellaneous DCU-specific settings */
-#define MAC_DMA_D2_MISC_ADDRESS                  0x00001108  /* MAC Miscellaneous DCU-specific settings */
-#define MAC_DMA_D3_MISC_ADDRESS                  0x0000110C  /* MAC Miscellaneous DCU-specific settings */
-#define MAC_DMA_D4_MISC_ADDRESS                  0x00001110  /* MAC Miscellaneous DCU-specific settings */
-#define MAC_DMA_D5_MISC_ADDRESS                  0x00001114  /* MAC Miscellaneous DCU-specific settings */
-#define MAC_DMA_D6_MISC_ADDRESS                  0x00001118  /* MAC Miscellaneous DCU-specific settings */
-#define MAC_DMA_D7_MISC_ADDRESS                  0x0000111C  /* MAC Miscellaneous DCU-specific settings */
-#define MAC_DMA_D8_MISC_ADDRESS                  0x00001120  /* MAC Miscellaneous DCU-specific settings */
-#define MAC_DMA_D9_MISC_ADDRESS                  0x00001124  /* MAC Miscellaneous DCU-specific settings */
-#define MAC_DMA_DMISC_ADDRESS(_i)                (MAC_DMA_D0_MISC_ADDRESS + ((_i)<<2))
-
-#define MAC_DMA_D0_EOL_ADDRESS                  0x00001180
-#define MAC_DMA_D1_EOL_ADDRESS                  0x00001184
-#define MAC_DMA_D2_EOL_ADDRESS                  0x00001188
-#define MAC_DMA_D3_EOL_ADDRESS                  0x0000118C
-#define MAC_DMA_D4_EOL_ADDRESS                  0x00001190
-#define MAC_DMA_D5_EOL_ADDRESS                  0x00001194
-#define MAC_DMA_D6_EOL_ADDRESS                  0x00001198
-#define MAC_DMA_D7_EOL_ADDRESS                  0x0000119C
-#define MAC_DMA_D8_EOL_ADDRESS                  0x00001200
-#define MAC_DMA_D9_EOL_ADDRESS                  0x00001204
-#define MAC_DMA_DEOL_ADDRESS(_i)                (MAC_DMA_D0_EOL_ADDRESS + ((_i)<<2))
-
-#define MAC_DMA_D_MISC_BKOFF_THRESH_MASK         0x0000003F /* Backoff threshold */
-#define MAC_DMA_D_MISC_BACK_OFF_THRESH_LSB       0
-#define MAC_DMA_D_MISC_ETS_RTS_MASK              0x00000040 /* End of transmission series
-                                                          station RTS/data failure
-                                                          count reset policy */
-#define MAC_DMA_D_MISC_ETS_CW_MASK               0x00000080 /* End of transmission series
-                                                          CW reset policy */
-#define MAC_DMA_D_MISC_FRAG_WAIT_EN_MASK         0x00000100  /* Fragment Starvation Policy */
-
-#define MAC_DMA_D_MISC_FRAG_BKOFF_EN_MASK        0x00000200 /* Backoff during a frag burst */
-#define MAC_DMA_D_MISC_HCF_POLL_EN_MASK          0x00000800 /* HFC poll enable */
-#define MAC_DMA_D_MISC_BKOFF_PERSISTENCE_MASK    0x00001000 /* Backoff persistence factor
-                                                          setting */
-#define MAC_DMA_D_MISC_VIR_COL_HANDLING_MASK     0x0000C000 /* Mask for Virtual collision
-                                                          handling policy */
-#define MAC_DMA_D_MISC_VIR_COL_HANDLING_LSB      14
-#define MAC_DMA_D_MISC_VIR_COL_HANDLING_DEFAULT  0   /* Normal */
-#define MAC_DMA_D_MISC_VIR_COL_HANDLING_IGNORE   1   /* Ignore */
-#define MAC_DMA_D_MISC_BEACON_USE_MASK           0x00010000 /*  Beacon use indication */
-#define MAC_DMA_D_MISC_ARB_LOCKOUT_CNTRL_MASK 0x00060000 /*  Mask for DCU arbiter lockout control */
-#define MAC_DMA_D_MISC_ARB_LOCKOUT_CNTRL_LSB  17
-#define MAC_DMA_D_MISC_ARB_LOCKOUT_CNTRL_NONE     0        /*  No lockout*/
-#define MAC_DMA_D_MISC_ARB_LOCKOUT_CNTRL_INTRA_FR 1        /*  Intra-frame*/
-#define MAC_DMA_D_MISC_ARB_LOCKOUT_CNTRL_GLOBAL   2        /*  Global */
-#define MAC_DMA_D_MISC_ARB_LOCKOUT_IGNORE_MASK 0x00080000 /*  DCU arbiter lockout ignore control */
-#define MAC_DMA_D_MISC_SEQ_NUM_INCR_DIS_MASK    0x00100000 /* Sequence number increment disable */
-#define MAC_DMA_D_MISC_POST_FR_BKOFF_DIS_MASK   0x00200000 /* Post-frame backoff disable */
-#define MAC_DMA_D_MISC_VIRT_COLL_POLICY_MASK    0x00400000 /* Virtual coll. handling policy */
-#define MAC_DMA_D_MISC_BLOWN_IFS_POLICY_MASK    0x00800000 /* Blown IFS handling policy */
-
-#define MAC_DMA_D_SEQNUM_ADDRESS                0x00001140  /* MAC Frame sequence number */
-
-
-
-#define MAC_DMA_D_FPCTL_ADDRESS                  0x00001230      /* DCU frame prefetch settings */
-#define MAC_DMA_D_TXPSE_ADDRESS                  0x00001270      /* DCU transmit pause control/status */
-
-#endif /* _AR6000_DMMAEG_H_ */
diff -druN linux-2.6.39-libre/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/mac_pcu_reg.h linux-3.0-rc7-libre/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/mac_pcu_reg.h
--- linux-2.6.39-libre/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/mac_pcu_reg.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/mac_pcu_reg.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,3065 +0,0 @@
-// ------------------------------------------------------------------
-// Copyright (c) 2004-2010 Atheros Corporation.  All rights reserved.
-// 
-//
-// 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.
-//
-//
-// ------------------------------------------------------------------
-//===================================================================
-// Author(s): ="Atheros"
-//===================================================================
-
-
-#ifndef _MAC_PCU_REG_H_
-#define _MAC_PCU_REG_H_
-
-#define MAC_PCU_STA_ADDR_L32_ADDRESS             0x00008000
-#define MAC_PCU_STA_ADDR_L32_OFFSET              0x00000000
-#define MAC_PCU_STA_ADDR_L32_ADDR_31_0_MSB       31
-#define MAC_PCU_STA_ADDR_L32_ADDR_31_0_LSB       0
-#define MAC_PCU_STA_ADDR_L32_ADDR_31_0_MASK      0xffffffff
-#define MAC_PCU_STA_ADDR_L32_ADDR_31_0_GET(x)    (((x) & MAC_PCU_STA_ADDR_L32_ADDR_31_0_MASK) >> MAC_PCU_STA_ADDR_L32_ADDR_31_0_LSB)
-#define MAC_PCU_STA_ADDR_L32_ADDR_31_0_SET(x)    (((x) << MAC_PCU_STA_ADDR_L32_ADDR_31_0_LSB) & MAC_PCU_STA_ADDR_L32_ADDR_31_0_MASK)
-
-#define MAC_PCU_STA_ADDR_U16_ADDRESS             0x00008004
-#define MAC_PCU_STA_ADDR_U16_OFFSET              0x00000004
-#define MAC_PCU_STA_ADDR_U16_ADHOC_MCAST_SEARCH_MSB 31
-#define MAC_PCU_STA_ADDR_U16_ADHOC_MCAST_SEARCH_LSB 31
-#define MAC_PCU_STA_ADDR_U16_ADHOC_MCAST_SEARCH_MASK 0x80000000
-#define MAC_PCU_STA_ADDR_U16_ADHOC_MCAST_SEARCH_GET(x) (((x) & MAC_PCU_STA_ADDR_U16_ADHOC_MCAST_SEARCH_MASK) >> MAC_PCU_STA_ADDR_U16_ADHOC_MCAST_SEARCH_LSB)
-#define MAC_PCU_STA_ADDR_U16_ADHOC_MCAST_SEARCH_SET(x) (((x) << MAC_PCU_STA_ADDR_U16_ADHOC_MCAST_SEARCH_LSB) & MAC_PCU_STA_ADDR_U16_ADHOC_MCAST_SEARCH_MASK)
-#define MAC_PCU_STA_ADDR_U16_CBCIV_ENDIAN_MSB    30
-#define MAC_PCU_STA_ADDR_U16_CBCIV_ENDIAN_LSB    30
-#define MAC_PCU_STA_ADDR_U16_CBCIV_ENDIAN_MASK   0x40000000
-#define MAC_PCU_STA_ADDR_U16_CBCIV_ENDIAN_GET(x) (((x) & MAC_PCU_STA_ADDR_U16_CBCIV_ENDIAN_MASK) >> MAC_PCU_STA_ADDR_U16_CBCIV_ENDIAN_LSB)
-#define MAC_PCU_STA_ADDR_U16_CBCIV_ENDIAN_SET(x) (((x) << MAC_PCU_STA_ADDR_U16_CBCIV_ENDIAN_LSB) & MAC_PCU_STA_ADDR_U16_CBCIV_ENDIAN_MASK)
-#define MAC_PCU_STA_ADDR_U16_PRESERVE_SEQNUM_MSB 29
-#define MAC_PCU_STA_ADDR_U16_PRESERVE_SEQNUM_LSB 29
-#define MAC_PCU_STA_ADDR_U16_PRESERVE_SEQNUM_MASK 0x20000000
-#define MAC_PCU_STA_ADDR_U16_PRESERVE_SEQNUM_GET(x) (((x) & MAC_PCU_STA_ADDR_U16_PRESERVE_SEQNUM_MASK) >> MAC_PCU_STA_ADDR_U16_PRESERVE_SEQNUM_LSB)
-#define MAC_PCU_STA_ADDR_U16_PRESERVE_SEQNUM_SET(x) (((x) << MAC_PCU_STA_ADDR_U16_PRESERVE_SEQNUM_LSB) & MAC_PCU_STA_ADDR_U16_PRESERVE_SEQNUM_MASK)
-#define MAC_PCU_STA_ADDR_U16_KSRCH_MODE_MSB      28
-#define MAC_PCU_STA_ADDR_U16_KSRCH_MODE_LSB      28
-#define MAC_PCU_STA_ADDR_U16_KSRCH_MODE_MASK     0x10000000
-#define MAC_PCU_STA_ADDR_U16_KSRCH_MODE_GET(x)   (((x) & MAC_PCU_STA_ADDR_U16_KSRCH_MODE_MASK) >> MAC_PCU_STA_ADDR_U16_KSRCH_MODE_LSB)
-#define MAC_PCU_STA_ADDR_U16_KSRCH_MODE_SET(x)   (((x) << MAC_PCU_STA_ADDR_U16_KSRCH_MODE_LSB) & MAC_PCU_STA_ADDR_U16_KSRCH_MODE_MASK)
-#define MAC_PCU_STA_ADDR_U16_CRPT_MIC_ENABLE_MSB 27
-#define MAC_PCU_STA_ADDR_U16_CRPT_MIC_ENABLE_LSB 27
-#define MAC_PCU_STA_ADDR_U16_CRPT_MIC_ENABLE_MASK 0x08000000
-#define MAC_PCU_STA_ADDR_U16_CRPT_MIC_ENABLE_GET(x) (((x) & MAC_PCU_STA_ADDR_U16_CRPT_MIC_ENABLE_MASK) >> MAC_PCU_STA_ADDR_U16_CRPT_MIC_ENABLE_LSB)
-#define MAC_PCU_STA_ADDR_U16_CRPT_MIC_ENABLE_SET(x) (((x) << MAC_PCU_STA_ADDR_U16_CRPT_MIC_ENABLE_LSB) & MAC_PCU_STA_ADDR_U16_CRPT_MIC_ENABLE_MASK)
-#define MAC_PCU_STA_ADDR_U16_SECTOR_SELF_GEN_MSB 26
-#define MAC_PCU_STA_ADDR_U16_SECTOR_SELF_GEN_LSB 26
-#define MAC_PCU_STA_ADDR_U16_SECTOR_SELF_GEN_MASK 0x04000000
-#define MAC_PCU_STA_ADDR_U16_SECTOR_SELF_GEN_GET(x) (((x) & MAC_PCU_STA_ADDR_U16_SECTOR_SELF_GEN_MASK) >> MAC_PCU_STA_ADDR_U16_SECTOR_SELF_GEN_LSB)
-#define MAC_PCU_STA_ADDR_U16_SECTOR_SELF_GEN_SET(x) (((x) << MAC_PCU_STA_ADDR_U16_SECTOR_SELF_GEN_LSB) & MAC_PCU_STA_ADDR_U16_SECTOR_SELF_GEN_MASK)
-#define MAC_PCU_STA_ADDR_U16_BASE_RATE_11B_MSB   25
-#define MAC_PCU_STA_ADDR_U16_BASE_RATE_11B_LSB   25
-#define MAC_PCU_STA_ADDR_U16_BASE_RATE_11B_MASK  0x02000000
-#define MAC_PCU_STA_ADDR_U16_BASE_RATE_11B_GET(x) (((x) & MAC_PCU_STA_ADDR_U16_BASE_RATE_11B_MASK) >> MAC_PCU_STA_ADDR_U16_BASE_RATE_11B_LSB)
-#define MAC_PCU_STA_ADDR_U16_BASE_RATE_11B_SET(x) (((x) << MAC_PCU_STA_ADDR_U16_BASE_RATE_11B_LSB) & MAC_PCU_STA_ADDR_U16_BASE_RATE_11B_MASK)
-#define MAC_PCU_STA_ADDR_U16_ACKCTS_6MB_MSB      24
-#define MAC_PCU_STA_ADDR_U16_ACKCTS_6MB_LSB      24
-#define MAC_PCU_STA_ADDR_U16_ACKCTS_6MB_MASK     0x01000000
-#define MAC_PCU_STA_ADDR_U16_ACKCTS_6MB_GET(x)   (((x) & MAC_PCU_STA_ADDR_U16_ACKCTS_6MB_MASK) >> MAC_PCU_STA_ADDR_U16_ACKCTS_6MB_LSB)
-#define MAC_PCU_STA_ADDR_U16_ACKCTS_6MB_SET(x)   (((x) << MAC_PCU_STA_ADDR_U16_ACKCTS_6MB_LSB) & MAC_PCU_STA_ADDR_U16_ACKCTS_6MB_MASK)
-#define MAC_PCU_STA_ADDR_U16_RTS_USE_DEF_MSB     23
-#define MAC_PCU_STA_ADDR_U16_RTS_USE_DEF_LSB     23
-#define MAC_PCU_STA_ADDR_U16_RTS_USE_DEF_MASK    0x00800000
-#define MAC_PCU_STA_ADDR_U16_RTS_USE_DEF_GET(x)  (((x) & MAC_PCU_STA_ADDR_U16_RTS_USE_DEF_MASK) >> MAC_PCU_STA_ADDR_U16_RTS_USE_DEF_LSB)
-#define MAC_PCU_STA_ADDR_U16_RTS_USE_DEF_SET(x)  (((x) << MAC_PCU_STA_ADDR_U16_RTS_USE_DEF_LSB) & MAC_PCU_STA_ADDR_U16_RTS_USE_DEF_MASK)
-#define MAC_PCU_STA_ADDR_U16_DEFANT_UPDATE_MSB   22
-#define MAC_PCU_STA_ADDR_U16_DEFANT_UPDATE_LSB   22
-#define MAC_PCU_STA_ADDR_U16_DEFANT_UPDATE_MASK  0x00400000
-#define MAC_PCU_STA_ADDR_U16_DEFANT_UPDATE_GET(x) (((x) & MAC_PCU_STA_ADDR_U16_DEFANT_UPDATE_MASK) >> MAC_PCU_STA_ADDR_U16_DEFANT_UPDATE_LSB)
-#define MAC_PCU_STA_ADDR_U16_DEFANT_UPDATE_SET(x) (((x) << MAC_PCU_STA_ADDR_U16_DEFANT_UPDATE_LSB) & MAC_PCU_STA_ADDR_U16_DEFANT_UPDATE_MASK)
-#define MAC_PCU_STA_ADDR_U16_USE_DEFANT_MSB      21
-#define MAC_PCU_STA_ADDR_U16_USE_DEFANT_LSB      21
-#define MAC_PCU_STA_ADDR_U16_USE_DEFANT_MASK     0x00200000
-#define MAC_PCU_STA_ADDR_U16_USE_DEFANT_GET(x)   (((x) & MAC_PCU_STA_ADDR_U16_USE_DEFANT_MASK) >> MAC_PCU_STA_ADDR_U16_USE_DEFANT_LSB)
-#define MAC_PCU_STA_ADDR_U16_USE_DEFANT_SET(x)   (((x) << MAC_PCU_STA_ADDR_U16_USE_DEFANT_LSB) & MAC_PCU_STA_ADDR_U16_USE_DEFANT_MASK)
-#define MAC_PCU_STA_ADDR_U16_PCF_MSB             20
-#define MAC_PCU_STA_ADDR_U16_PCF_LSB             20
-#define MAC_PCU_STA_ADDR_U16_PCF_MASK            0x00100000
-#define MAC_PCU_STA_ADDR_U16_PCF_GET(x)          (((x) & MAC_PCU_STA_ADDR_U16_PCF_MASK) >> MAC_PCU_STA_ADDR_U16_PCF_LSB)
-#define MAC_PCU_STA_ADDR_U16_PCF_SET(x)          (((x) << MAC_PCU_STA_ADDR_U16_PCF_LSB) & MAC_PCU_STA_ADDR_U16_PCF_MASK)
-#define MAC_PCU_STA_ADDR_U16_KEYSRCH_DIS_MSB     19
-#define MAC_PCU_STA_ADDR_U16_KEYSRCH_DIS_LSB     19
-#define MAC_PCU_STA_ADDR_U16_KEYSRCH_DIS_MASK    0x00080000
-#define MAC_PCU_STA_ADDR_U16_KEYSRCH_DIS_GET(x)  (((x) & MAC_PCU_STA_ADDR_U16_KEYSRCH_DIS_MASK) >> MAC_PCU_STA_ADDR_U16_KEYSRCH_DIS_LSB)
-#define MAC_PCU_STA_ADDR_U16_KEYSRCH_DIS_SET(x)  (((x) << MAC_PCU_STA_ADDR_U16_KEYSRCH_DIS_LSB) & MAC_PCU_STA_ADDR_U16_KEYSRCH_DIS_MASK)
-#define MAC_PCU_STA_ADDR_U16_PW_SAVE_MSB         18
-#define MAC_PCU_STA_ADDR_U16_PW_SAVE_LSB         18
-#define MAC_PCU_STA_ADDR_U16_PW_SAVE_MASK        0x00040000
-#define MAC_PCU_STA_ADDR_U16_PW_SAVE_GET(x)      (((x) & MAC_PCU_STA_ADDR_U16_PW_SAVE_MASK) >> MAC_PCU_STA_ADDR_U16_PW_SAVE_LSB)
-#define MAC_PCU_STA_ADDR_U16_PW_SAVE_SET(x)      (((x) << MAC_PCU_STA_ADDR_U16_PW_SAVE_LSB) & MAC_PCU_STA_ADDR_U16_PW_SAVE_MASK)
-#define MAC_PCU_STA_ADDR_U16_ADHOC_MSB           17
-#define MAC_PCU_STA_ADDR_U16_ADHOC_LSB           17
-#define MAC_PCU_STA_ADDR_U16_ADHOC_MASK          0x00020000
-#define MAC_PCU_STA_ADDR_U16_ADHOC_GET(x)        (((x) & MAC_PCU_STA_ADDR_U16_ADHOC_MASK) >> MAC_PCU_STA_ADDR_U16_ADHOC_LSB)
-#define MAC_PCU_STA_ADDR_U16_ADHOC_SET(x)        (((x) << MAC_PCU_STA_ADDR_U16_ADHOC_LSB) & MAC_PCU_STA_ADDR_U16_ADHOC_MASK)
-#define MAC_PCU_STA_ADDR_U16_STA_AP_MSB          16
-#define MAC_PCU_STA_ADDR_U16_STA_AP_LSB          16
-#define MAC_PCU_STA_ADDR_U16_STA_AP_MASK         0x00010000
-#define MAC_PCU_STA_ADDR_U16_STA_AP_GET(x)       (((x) & MAC_PCU_STA_ADDR_U16_STA_AP_MASK) >> MAC_PCU_STA_ADDR_U16_STA_AP_LSB)
-#define MAC_PCU_STA_ADDR_U16_STA_AP_SET(x)       (((x) << MAC_PCU_STA_ADDR_U16_STA_AP_LSB) & MAC_PCU_STA_ADDR_U16_STA_AP_MASK)
-#define MAC_PCU_STA_ADDR_U16_ADDR_47_32_MSB      15
-#define MAC_PCU_STA_ADDR_U16_ADDR_47_32_LSB      0
-#define MAC_PCU_STA_ADDR_U16_ADDR_47_32_MASK     0x0000ffff
-#define MAC_PCU_STA_ADDR_U16_ADDR_47_32_GET(x)   (((x) & MAC_PCU_STA_ADDR_U16_ADDR_47_32_MASK) >> MAC_PCU_STA_ADDR_U16_ADDR_47_32_LSB)
-#define MAC_PCU_STA_ADDR_U16_ADDR_47_32_SET(x)   (((x) << MAC_PCU_STA_ADDR_U16_ADDR_47_32_LSB) & MAC_PCU_STA_ADDR_U16_ADDR_47_32_MASK)
-
-#define MAC_PCU_BSSID_L32_ADDRESS                0x00008008
-#define MAC_PCU_BSSID_L32_OFFSET                 0x00000008
-#define MAC_PCU_BSSID_L32_ADDR_MSB               31
-#define MAC_PCU_BSSID_L32_ADDR_LSB               0
-#define MAC_PCU_BSSID_L32_ADDR_MASK              0xffffffff
-#define MAC_PCU_BSSID_L32_ADDR_GET(x)            (((x) & MAC_PCU_BSSID_L32_ADDR_MASK) >> MAC_PCU_BSSID_L32_ADDR_LSB)
-#define MAC_PCU_BSSID_L32_ADDR_SET(x)            (((x) << MAC_PCU_BSSID_L32_ADDR_LSB) & MAC_PCU_BSSID_L32_ADDR_MASK)
-
-#define MAC_PCU_BSSID_U16_ADDRESS                0x0000800c
-#define MAC_PCU_BSSID_U16_OFFSET                 0x0000000c
-#define MAC_PCU_BSSID_U16_AID_MSB                26
-#define MAC_PCU_BSSID_U16_AID_LSB                16
-#define MAC_PCU_BSSID_U16_AID_MASK               0x07ff0000
-#define MAC_PCU_BSSID_U16_AID_GET(x)             (((x) & MAC_PCU_BSSID_U16_AID_MASK) >> MAC_PCU_BSSID_U16_AID_LSB)
-#define MAC_PCU_BSSID_U16_AID_SET(x)             (((x) << MAC_PCU_BSSID_U16_AID_LSB) & MAC_PCU_BSSID_U16_AID_MASK)
-#define MAC_PCU_BSSID_U16_ADDR_MSB               15
-#define MAC_PCU_BSSID_U16_ADDR_LSB               0
-#define MAC_PCU_BSSID_U16_ADDR_MASK              0x0000ffff
-#define MAC_PCU_BSSID_U16_ADDR_GET(x)            (((x) & MAC_PCU_BSSID_U16_ADDR_MASK) >> MAC_PCU_BSSID_U16_ADDR_LSB)
-#define MAC_PCU_BSSID_U16_ADDR_SET(x)            (((x) << MAC_PCU_BSSID_U16_ADDR_LSB) & MAC_PCU_BSSID_U16_ADDR_MASK)
-
-#define MAC_PCU_BCN_RSSI_AVE_ADDRESS             0x00008010
-#define MAC_PCU_BCN_RSSI_AVE_OFFSET              0x00000010
-#define MAC_PCU_BCN_RSSI_AVE_VALUE_MSB           11
-#define MAC_PCU_BCN_RSSI_AVE_VALUE_LSB           0
-#define MAC_PCU_BCN_RSSI_AVE_VALUE_MASK          0x00000fff
-#define MAC_PCU_BCN_RSSI_AVE_VALUE_GET(x)        (((x) & MAC_PCU_BCN_RSSI_AVE_VALUE_MASK) >> MAC_PCU_BCN_RSSI_AVE_VALUE_LSB)
-#define MAC_PCU_BCN_RSSI_AVE_VALUE_SET(x)        (((x) << MAC_PCU_BCN_RSSI_AVE_VALUE_LSB) & MAC_PCU_BCN_RSSI_AVE_VALUE_MASK)
-
-#define MAC_PCU_ACK_CTS_TIMEOUT_ADDRESS          0x00008014
-#define MAC_PCU_ACK_CTS_TIMEOUT_OFFSET           0x00000014
-#define MAC_PCU_ACK_CTS_TIMEOUT_CTS_TIMEOUT_MSB  29
-#define MAC_PCU_ACK_CTS_TIMEOUT_CTS_TIMEOUT_LSB  16
-#define MAC_PCU_ACK_CTS_TIMEOUT_CTS_TIMEOUT_MASK 0x3fff0000
-#define MAC_PCU_ACK_CTS_TIMEOUT_CTS_TIMEOUT_GET(x) (((x) & MAC_PCU_ACK_CTS_TIMEOUT_CTS_TIMEOUT_MASK) >> MAC_PCU_ACK_CTS_TIMEOUT_CTS_TIMEOUT_LSB)
-#define MAC_PCU_ACK_CTS_TIMEOUT_CTS_TIMEOUT_SET(x) (((x) << MAC_PCU_ACK_CTS_TIMEOUT_CTS_TIMEOUT_LSB) & MAC_PCU_ACK_CTS_TIMEOUT_CTS_TIMEOUT_MASK)
-#define MAC_PCU_ACK_CTS_TIMEOUT_ACK_TIMEOUT_MSB  13
-#define MAC_PCU_ACK_CTS_TIMEOUT_ACK_TIMEOUT_LSB  0
-#define MAC_PCU_ACK_CTS_TIMEOUT_ACK_TIMEOUT_MASK 0x00003fff
-#define MAC_PCU_ACK_CTS_TIMEOUT_ACK_TIMEOUT_GET(x) (((x) & MAC_PCU_ACK_CTS_TIMEOUT_ACK_TIMEOUT_MASK) >> MAC_PCU_ACK_CTS_TIMEOUT_ACK_TIMEOUT_LSB)
-#define MAC_PCU_ACK_CTS_TIMEOUT_ACK_TIMEOUT_SET(x) (((x) << MAC_PCU_ACK_CTS_TIMEOUT_ACK_TIMEOUT_LSB) & MAC_PCU_ACK_CTS_TIMEOUT_ACK_TIMEOUT_MASK)
-
-#define MAC_PCU_BCN_RSSI_CTL_ADDRESS             0x00008018
-#define MAC_PCU_BCN_RSSI_CTL_OFFSET              0x00000018
-#define MAC_PCU_BCN_RSSI_CTL_RESET_MSB           29
-#define MAC_PCU_BCN_RSSI_CTL_RESET_LSB           29
-#define MAC_PCU_BCN_RSSI_CTL_RESET_MASK          0x20000000
-#define MAC_PCU_BCN_RSSI_CTL_RESET_GET(x)        (((x) & MAC_PCU_BCN_RSSI_CTL_RESET_MASK) >> MAC_PCU_BCN_RSSI_CTL_RESET_LSB)
-#define MAC_PCU_BCN_RSSI_CTL_RESET_SET(x)        (((x) << MAC_PCU_BCN_RSSI_CTL_RESET_LSB) & MAC_PCU_BCN_RSSI_CTL_RESET_MASK)
-#define MAC_PCU_BCN_RSSI_CTL_WEIGHT_MSB          28
-#define MAC_PCU_BCN_RSSI_CTL_WEIGHT_LSB          24
-#define MAC_PCU_BCN_RSSI_CTL_WEIGHT_MASK         0x1f000000
-#define MAC_PCU_BCN_RSSI_CTL_WEIGHT_GET(x)       (((x) & MAC_PCU_BCN_RSSI_CTL_WEIGHT_MASK) >> MAC_PCU_BCN_RSSI_CTL_WEIGHT_LSB)
-#define MAC_PCU_BCN_RSSI_CTL_WEIGHT_SET(x)       (((x) << MAC_PCU_BCN_RSSI_CTL_WEIGHT_LSB) & MAC_PCU_BCN_RSSI_CTL_WEIGHT_MASK)
-#define MAC_PCU_BCN_RSSI_CTL_RSSI_HIGH_THRESH_MSB 23
-#define MAC_PCU_BCN_RSSI_CTL_RSSI_HIGH_THRESH_LSB 16
-#define MAC_PCU_BCN_RSSI_CTL_RSSI_HIGH_THRESH_MASK 0x00ff0000
-#define MAC_PCU_BCN_RSSI_CTL_RSSI_HIGH_THRESH_GET(x) (((x) & MAC_PCU_BCN_RSSI_CTL_RSSI_HIGH_THRESH_MASK) >> MAC_PCU_BCN_RSSI_CTL_RSSI_HIGH_THRESH_LSB)
-#define MAC_PCU_BCN_RSSI_CTL_RSSI_HIGH_THRESH_SET(x) (((x) << MAC_PCU_BCN_RSSI_CTL_RSSI_HIGH_THRESH_LSB) & MAC_PCU_BCN_RSSI_CTL_RSSI_HIGH_THRESH_MASK)
-#define MAC_PCU_BCN_RSSI_CTL_MISS_THRESH_MSB     15
-#define MAC_PCU_BCN_RSSI_CTL_MISS_THRESH_LSB     8
-#define MAC_PCU_BCN_RSSI_CTL_MISS_THRESH_MASK    0x0000ff00
-#define MAC_PCU_BCN_RSSI_CTL_MISS_THRESH_GET(x)  (((x) & MAC_PCU_BCN_RSSI_CTL_MISS_THRESH_MASK) >> MAC_PCU_BCN_RSSI_CTL_MISS_THRESH_LSB)
-#define MAC_PCU_BCN_RSSI_CTL_MISS_THRESH_SET(x)  (((x) << MAC_PCU_BCN_RSSI_CTL_MISS_THRESH_LSB) & MAC_PCU_BCN_RSSI_CTL_MISS_THRESH_MASK)
-#define MAC_PCU_BCN_RSSI_CTL_RSSI_LOW_THRESH_MSB 7
-#define MAC_PCU_BCN_RSSI_CTL_RSSI_LOW_THRESH_LSB 0
-#define MAC_PCU_BCN_RSSI_CTL_RSSI_LOW_THRESH_MASK 0x000000ff
-#define MAC_PCU_BCN_RSSI_CTL_RSSI_LOW_THRESH_GET(x) (((x) & MAC_PCU_BCN_RSSI_CTL_RSSI_LOW_THRESH_MASK) >> MAC_PCU_BCN_RSSI_CTL_RSSI_LOW_THRESH_LSB)
-#define MAC_PCU_BCN_RSSI_CTL_RSSI_LOW_THRESH_SET(x) (((x) << MAC_PCU_BCN_RSSI_CTL_RSSI_LOW_THRESH_LSB) & MAC_PCU_BCN_RSSI_CTL_RSSI_LOW_THRESH_MASK)
-
-#define MAC_PCU_USEC_LATENCY_ADDRESS             0x0000801c
-#define MAC_PCU_USEC_LATENCY_OFFSET              0x0000001c
-#define MAC_PCU_USEC_LATENCY_RX_LATENCY_MSB      28
-#define MAC_PCU_USEC_LATENCY_RX_LATENCY_LSB      23
-#define MAC_PCU_USEC_LATENCY_RX_LATENCY_MASK     0x1f800000
-#define MAC_PCU_USEC_LATENCY_RX_LATENCY_GET(x)   (((x) & MAC_PCU_USEC_LATENCY_RX_LATENCY_MASK) >> MAC_PCU_USEC_LATENCY_RX_LATENCY_LSB)
-#define MAC_PCU_USEC_LATENCY_RX_LATENCY_SET(x)   (((x) << MAC_PCU_USEC_LATENCY_RX_LATENCY_LSB) & MAC_PCU_USEC_LATENCY_RX_LATENCY_MASK)
-#define MAC_PCU_USEC_LATENCY_TX_LATENCY_MSB      22
-#define MAC_PCU_USEC_LATENCY_TX_LATENCY_LSB      14
-#define MAC_PCU_USEC_LATENCY_TX_LATENCY_MASK     0x007fc000
-#define MAC_PCU_USEC_LATENCY_TX_LATENCY_GET(x)   (((x) & MAC_PCU_USEC_LATENCY_TX_LATENCY_MASK) >> MAC_PCU_USEC_LATENCY_TX_LATENCY_LSB)
-#define MAC_PCU_USEC_LATENCY_TX_LATENCY_SET(x)   (((x) << MAC_PCU_USEC_LATENCY_TX_LATENCY_LSB) & MAC_PCU_USEC_LATENCY_TX_LATENCY_MASK)
-#define MAC_PCU_USEC_LATENCY_USEC_MSB            7
-#define MAC_PCU_USEC_LATENCY_USEC_LSB            0
-#define MAC_PCU_USEC_LATENCY_USEC_MASK           0x000000ff
-#define MAC_PCU_USEC_LATENCY_USEC_GET(x)         (((x) & MAC_PCU_USEC_LATENCY_USEC_MASK) >> MAC_PCU_USEC_LATENCY_USEC_LSB)
-#define MAC_PCU_USEC_LATENCY_USEC_SET(x)         (((x) << MAC_PCU_USEC_LATENCY_USEC_LSB) & MAC_PCU_USEC_LATENCY_USEC_MASK)
-
-#define PCU_MAX_CFP_DUR_ADDRESS                  0x00008020
-#define PCU_MAX_CFP_DUR_OFFSET                   0x00000020
-#define PCU_MAX_CFP_DUR_VALUE_MSB                15
-#define PCU_MAX_CFP_DUR_VALUE_LSB                0
-#define PCU_MAX_CFP_DUR_VALUE_MASK               0x0000ffff
-#define PCU_MAX_CFP_DUR_VALUE_GET(x)             (((x) & PCU_MAX_CFP_DUR_VALUE_MASK) >> PCU_MAX_CFP_DUR_VALUE_LSB)
-#define PCU_MAX_CFP_DUR_VALUE_SET(x)             (((x) << PCU_MAX_CFP_DUR_VALUE_LSB) & PCU_MAX_CFP_DUR_VALUE_MASK)
-
-#define MAC_PCU_RX_FILTER_ADDRESS                0x00008024
-#define MAC_PCU_RX_FILTER_OFFSET                 0x00000024
-#define MAC_PCU_RX_FILTER_GENERIC_FILTER_MSB     25
-#define MAC_PCU_RX_FILTER_GENERIC_FILTER_LSB     24
-#define MAC_PCU_RX_FILTER_GENERIC_FILTER_MASK    0x03000000
-#define MAC_PCU_RX_FILTER_GENERIC_FILTER_GET(x)  (((x) & MAC_PCU_RX_FILTER_GENERIC_FILTER_MASK) >> MAC_PCU_RX_FILTER_GENERIC_FILTER_LSB)
-#define MAC_PCU_RX_FILTER_GENERIC_FILTER_SET(x)  (((x) << MAC_PCU_RX_FILTER_GENERIC_FILTER_LSB) & MAC_PCU_RX_FILTER_GENERIC_FILTER_MASK)
-#define MAC_PCU_RX_FILTER_GENERIC_FTYPE_MSB      23
-#define MAC_PCU_RX_FILTER_GENERIC_FTYPE_LSB      18
-#define MAC_PCU_RX_FILTER_GENERIC_FTYPE_MASK     0x00fc0000
-#define MAC_PCU_RX_FILTER_GENERIC_FTYPE_GET(x)   (((x) & MAC_PCU_RX_FILTER_GENERIC_FTYPE_MASK) >> MAC_PCU_RX_FILTER_GENERIC_FTYPE_LSB)
-#define MAC_PCU_RX_FILTER_GENERIC_FTYPE_SET(x)   (((x) << MAC_PCU_RX_FILTER_GENERIC_FTYPE_LSB) & MAC_PCU_RX_FILTER_GENERIC_FTYPE_MASK)
-#define MAC_PCU_RX_FILTER_FROM_TO_DS_MSB         17
-#define MAC_PCU_RX_FILTER_FROM_TO_DS_LSB         17
-#define MAC_PCU_RX_FILTER_FROM_TO_DS_MASK        0x00020000
-#define MAC_PCU_RX_FILTER_FROM_TO_DS_GET(x)      (((x) & MAC_PCU_RX_FILTER_FROM_TO_DS_MASK) >> MAC_PCU_RX_FILTER_FROM_TO_DS_LSB)
-#define MAC_PCU_RX_FILTER_FROM_TO_DS_SET(x)      (((x) << MAC_PCU_RX_FILTER_FROM_TO_DS_LSB) & MAC_PCU_RX_FILTER_FROM_TO_DS_MASK)
-#define MAC_PCU_RX_FILTER_RST_DLMTR_CNT_DISABLE_MSB 16
-#define MAC_PCU_RX_FILTER_RST_DLMTR_CNT_DISABLE_LSB 16
-#define MAC_PCU_RX_FILTER_RST_DLMTR_CNT_DISABLE_MASK 0x00010000
-#define MAC_PCU_RX_FILTER_RST_DLMTR_CNT_DISABLE_GET(x) (((x) & MAC_PCU_RX_FILTER_RST_DLMTR_CNT_DISABLE_MASK) >> MAC_PCU_RX_FILTER_RST_DLMTR_CNT_DISABLE_LSB)
-#define MAC_PCU_RX_FILTER_RST_DLMTR_CNT_DISABLE_SET(x) (((x) << MAC_PCU_RX_FILTER_RST_DLMTR_CNT_DISABLE_LSB) & MAC_PCU_RX_FILTER_RST_DLMTR_CNT_DISABLE_MASK)
-#define MAC_PCU_RX_FILTER_MCAST_BCAST_ALL_MSB    15
-#define MAC_PCU_RX_FILTER_MCAST_BCAST_ALL_LSB    15
-#define MAC_PCU_RX_FILTER_MCAST_BCAST_ALL_MASK   0x00008000
-#define MAC_PCU_RX_FILTER_MCAST_BCAST_ALL_GET(x) (((x) & MAC_PCU_RX_FILTER_MCAST_BCAST_ALL_MASK) >> MAC_PCU_RX_FILTER_MCAST_BCAST_ALL_LSB)
-#define MAC_PCU_RX_FILTER_MCAST_BCAST_ALL_SET(x) (((x) << MAC_PCU_RX_FILTER_MCAST_BCAST_ALL_LSB) & MAC_PCU_RX_FILTER_MCAST_BCAST_ALL_MASK)
-#define MAC_PCU_RX_FILTER_PS_POLL_MSB            14
-#define MAC_PCU_RX_FILTER_PS_POLL_LSB            14
-#define MAC_PCU_RX_FILTER_PS_POLL_MASK           0x00004000
-#define MAC_PCU_RX_FILTER_PS_POLL_GET(x)         (((x) & MAC_PCU_RX_FILTER_PS_POLL_MASK) >> MAC_PCU_RX_FILTER_PS_POLL_LSB)
-#define MAC_PCU_RX_FILTER_PS_POLL_SET(x)         (((x) << MAC_PCU_RX_FILTER_PS_POLL_LSB) & MAC_PCU_RX_FILTER_PS_POLL_MASK)
-#define MAC_PCU_RX_FILTER_ASSUME_RADAR_MSB       13
-#define MAC_PCU_RX_FILTER_ASSUME_RADAR_LSB       13
-#define MAC_PCU_RX_FILTER_ASSUME_RADAR_MASK      0x00002000
-#define MAC_PCU_RX_FILTER_ASSUME_RADAR_GET(x)    (((x) & MAC_PCU_RX_FILTER_ASSUME_RADAR_MASK) >> MAC_PCU_RX_FILTER_ASSUME_RADAR_LSB)
-#define MAC_PCU_RX_FILTER_ASSUME_RADAR_SET(x)    (((x) << MAC_PCU_RX_FILTER_ASSUME_RADAR_LSB) & MAC_PCU_RX_FILTER_ASSUME_RADAR_MASK)
-#define MAC_PCU_RX_FILTER_UNCOMPRESSED_BA_BAR_MSB 12
-#define MAC_PCU_RX_FILTER_UNCOMPRESSED_BA_BAR_LSB 12
-#define MAC_PCU_RX_FILTER_UNCOMPRESSED_BA_BAR_MASK 0x00001000
-#define MAC_PCU_RX_FILTER_UNCOMPRESSED_BA_BAR_GET(x) (((x) & MAC_PCU_RX_FILTER_UNCOMPRESSED_BA_BAR_MASK) >> MAC_PCU_RX_FILTER_UNCOMPRESSED_BA_BAR_LSB)
-#define MAC_PCU_RX_FILTER_UNCOMPRESSED_BA_BAR_SET(x) (((x) << MAC_PCU_RX_FILTER_UNCOMPRESSED_BA_BAR_LSB) & MAC_PCU_RX_FILTER_UNCOMPRESSED_BA_BAR_MASK)
-#define MAC_PCU_RX_FILTER_COMPRESSED_BA_MSB      11
-#define MAC_PCU_RX_FILTER_COMPRESSED_BA_LSB      11
-#define MAC_PCU_RX_FILTER_COMPRESSED_BA_MASK     0x00000800
-#define MAC_PCU_RX_FILTER_COMPRESSED_BA_GET(x)   (((x) & MAC_PCU_RX_FILTER_COMPRESSED_BA_MASK) >> MAC_PCU_RX_FILTER_COMPRESSED_BA_LSB)
-#define MAC_PCU_RX_FILTER_COMPRESSED_BA_SET(x)   (((x) << MAC_PCU_RX_FILTER_COMPRESSED_BA_LSB) & MAC_PCU_RX_FILTER_COMPRESSED_BA_MASK)
-#define MAC_PCU_RX_FILTER_COMPRESSED_BAR_MSB     10
-#define MAC_PCU_RX_FILTER_COMPRESSED_BAR_LSB     10
-#define MAC_PCU_RX_FILTER_COMPRESSED_BAR_MASK    0x00000400
-#define MAC_PCU_RX_FILTER_COMPRESSED_BAR_GET(x)  (((x) & MAC_PCU_RX_FILTER_COMPRESSED_BAR_MASK) >> MAC_PCU_RX_FILTER_COMPRESSED_BAR_LSB)
-#define MAC_PCU_RX_FILTER_COMPRESSED_BAR_SET(x)  (((x) << MAC_PCU_RX_FILTER_COMPRESSED_BAR_LSB) & MAC_PCU_RX_FILTER_COMPRESSED_BAR_MASK)
-#define MAC_PCU_RX_FILTER_MY_BEACON_MSB          9
-#define MAC_PCU_RX_FILTER_MY_BEACON_LSB          9
-#define MAC_PCU_RX_FILTER_MY_BEACON_MASK         0x00000200
-#define MAC_PCU_RX_FILTER_MY_BEACON_GET(x)       (((x) & MAC_PCU_RX_FILTER_MY_BEACON_MASK) >> MAC_PCU_RX_FILTER_MY_BEACON_LSB)
-#define MAC_PCU_RX_FILTER_MY_BEACON_SET(x)       (((x) << MAC_PCU_RX_FILTER_MY_BEACON_LSB) & MAC_PCU_RX_FILTER_MY_BEACON_MASK)
-#define MAC_PCU_RX_FILTER_SYNC_FRAME_MSB         8
-#define MAC_PCU_RX_FILTER_SYNC_FRAME_LSB         8
-#define MAC_PCU_RX_FILTER_SYNC_FRAME_MASK        0x00000100
-#define MAC_PCU_RX_FILTER_SYNC_FRAME_GET(x)      (((x) & MAC_PCU_RX_FILTER_SYNC_FRAME_MASK) >> MAC_PCU_RX_FILTER_SYNC_FRAME_LSB)
-#define MAC_PCU_RX_FILTER_SYNC_FRAME_SET(x)      (((x) << MAC_PCU_RX_FILTER_SYNC_FRAME_LSB) & MAC_PCU_RX_FILTER_SYNC_FRAME_MASK)
-#define MAC_PCU_RX_FILTER_PROBE_REQ_MSB          7
-#define MAC_PCU_RX_FILTER_PROBE_REQ_LSB          7
-#define MAC_PCU_RX_FILTER_PROBE_REQ_MASK         0x00000080
-#define MAC_PCU_RX_FILTER_PROBE_REQ_GET(x)       (((x) & MAC_PCU_RX_FILTER_PROBE_REQ_MASK) >> MAC_PCU_RX_FILTER_PROBE_REQ_LSB)
-#define MAC_PCU_RX_FILTER_PROBE_REQ_SET(x)       (((x) << MAC_PCU_RX_FILTER_PROBE_REQ_LSB) & MAC_PCU_RX_FILTER_PROBE_REQ_MASK)
-#define MAC_PCU_RX_FILTER_XR_POLL_MSB            6
-#define MAC_PCU_RX_FILTER_XR_POLL_LSB            6
-#define MAC_PCU_RX_FILTER_XR_POLL_MASK           0x00000040
-#define MAC_PCU_RX_FILTER_XR_POLL_GET(x)         (((x) & MAC_PCU_RX_FILTER_XR_POLL_MASK) >> MAC_PCU_RX_FILTER_XR_POLL_LSB)
-#define MAC_PCU_RX_FILTER_XR_POLL_SET(x)         (((x) << MAC_PCU_RX_FILTER_XR_POLL_LSB) & MAC_PCU_RX_FILTER_XR_POLL_MASK)
-#define MAC_PCU_RX_FILTER_PROMISCUOUS_MSB        5
-#define MAC_PCU_RX_FILTER_PROMISCUOUS_LSB        5
-#define MAC_PCU_RX_FILTER_PROMISCUOUS_MASK       0x00000020
-#define MAC_PCU_RX_FILTER_PROMISCUOUS_GET(x)     (((x) & MAC_PCU_RX_FILTER_PROMISCUOUS_MASK) >> MAC_PCU_RX_FILTER_PROMISCUOUS_LSB)
-#define MAC_PCU_RX_FILTER_PROMISCUOUS_SET(x)     (((x) << MAC_PCU_RX_FILTER_PROMISCUOUS_LSB) & MAC_PCU_RX_FILTER_PROMISCUOUS_MASK)
-#define MAC_PCU_RX_FILTER_BEACON_MSB             4
-#define MAC_PCU_RX_FILTER_BEACON_LSB             4
-#define MAC_PCU_RX_FILTER_BEACON_MASK            0x00000010
-#define MAC_PCU_RX_FILTER_BEACON_GET(x)          (((x) & MAC_PCU_RX_FILTER_BEACON_MASK) >> MAC_PCU_RX_FILTER_BEACON_LSB)
-#define MAC_PCU_RX_FILTER_BEACON_SET(x)          (((x) << MAC_PCU_RX_FILTER_BEACON_LSB) & MAC_PCU_RX_FILTER_BEACON_MASK)
-#define MAC_PCU_RX_FILTER_CONTROL_MSB            3
-#define MAC_PCU_RX_FILTER_CONTROL_LSB            3
-#define MAC_PCU_RX_FILTER_CONTROL_MASK           0x00000008
-#define MAC_PCU_RX_FILTER_CONTROL_GET(x)         (((x) & MAC_PCU_RX_FILTER_CONTROL_MASK) >> MAC_PCU_RX_FILTER_CONTROL_LSB)
-#define MAC_PCU_RX_FILTER_CONTROL_SET(x)         (((x) << MAC_PCU_RX_FILTER_CONTROL_LSB) & MAC_PCU_RX_FILTER_CONTROL_MASK)
-#define MAC_PCU_RX_FILTER_BROADCAST_MSB          2
-#define MAC_PCU_RX_FILTER_BROADCAST_LSB          2
-#define MAC_PCU_RX_FILTER_BROADCAST_MASK         0x00000004
-#define MAC_PCU_RX_FILTER_BROADCAST_GET(x)       (((x) & MAC_PCU_RX_FILTER_BROADCAST_MASK) >> MAC_PCU_RX_FILTER_BROADCAST_LSB)
-#define MAC_PCU_RX_FILTER_BROADCAST_SET(x)       (((x) << MAC_PCU_RX_FILTER_BROADCAST_LSB) & MAC_PCU_RX_FILTER_BROADCAST_MASK)
-#define MAC_PCU_RX_FILTER_MULTICAST_MSB          1
-#define MAC_PCU_RX_FILTER_MULTICAST_LSB          1
-#define MAC_PCU_RX_FILTER_MULTICAST_MASK         0x00000002
-#define MAC_PCU_RX_FILTER_MULTICAST_GET(x)       (((x) & MAC_PCU_RX_FILTER_MULTICAST_MASK) >> MAC_PCU_RX_FILTER_MULTICAST_LSB)
-#define MAC_PCU_RX_FILTER_MULTICAST_SET(x)       (((x) << MAC_PCU_RX_FILTER_MULTICAST_LSB) & MAC_PCU_RX_FILTER_MULTICAST_MASK)
-#define MAC_PCU_RX_FILTER_UNICAST_MSB            0
-#define MAC_PCU_RX_FILTER_UNICAST_LSB            0
-#define MAC_PCU_RX_FILTER_UNICAST_MASK           0x00000001
-#define MAC_PCU_RX_FILTER_UNICAST_GET(x)         (((x) & MAC_PCU_RX_FILTER_UNICAST_MASK) >> MAC_PCU_RX_FILTER_UNICAST_LSB)
-#define MAC_PCU_RX_FILTER_UNICAST_SET(x)         (((x) << MAC_PCU_RX_FILTER_UNICAST_LSB) & MAC_PCU_RX_FILTER_UNICAST_MASK)
-
-#define MAC_PCU_MCAST_FILTER_L32_ADDRESS         0x00008028
-#define MAC_PCU_MCAST_FILTER_L32_OFFSET          0x00000028
-#define MAC_PCU_MCAST_FILTER_L32_VALUE_MSB       31
-#define MAC_PCU_MCAST_FILTER_L32_VALUE_LSB       0
-#define MAC_PCU_MCAST_FILTER_L32_VALUE_MASK      0xffffffff
-#define MAC_PCU_MCAST_FILTER_L32_VALUE_GET(x)    (((x) & MAC_PCU_MCAST_FILTER_L32_VALUE_MASK) >> MAC_PCU_MCAST_FILTER_L32_VALUE_LSB)
-#define MAC_PCU_MCAST_FILTER_L32_VALUE_SET(x)    (((x) << MAC_PCU_MCAST_FILTER_L32_VALUE_LSB) & MAC_PCU_MCAST_FILTER_L32_VALUE_MASK)
-
-#define MAC_PCU_MCAST_FILTER_U32_ADDRESS         0x0000802c
-#define MAC_PCU_MCAST_FILTER_U32_OFFSET          0x0000002c
-#define MAC_PCU_MCAST_FILTER_U32_VALUE_MSB       31
-#define MAC_PCU_MCAST_FILTER_U32_VALUE_LSB       0
-#define MAC_PCU_MCAST_FILTER_U32_VALUE_MASK      0xffffffff
-#define MAC_PCU_MCAST_FILTER_U32_VALUE_GET(x)    (((x) & MAC_PCU_MCAST_FILTER_U32_VALUE_MASK) >> MAC_PCU_MCAST_FILTER_U32_VALUE_LSB)
-#define MAC_PCU_MCAST_FILTER_U32_VALUE_SET(x)    (((x) << MAC_PCU_MCAST_FILTER_U32_VALUE_LSB) & MAC_PCU_MCAST_FILTER_U32_VALUE_MASK)
-
-#define MAC_PCU_DIAG_SW_ADDRESS                  0x00008030
-#define MAC_PCU_DIAG_SW_OFFSET                   0x00000030
-#define MAC_PCU_DIAG_SW_DEBUG_MODE_MSB           31
-#define MAC_PCU_DIAG_SW_DEBUG_MODE_LSB           30
-#define MAC_PCU_DIAG_SW_DEBUG_MODE_MASK          0xc0000000
-#define MAC_PCU_DIAG_SW_DEBUG_MODE_GET(x)        (((x) & MAC_PCU_DIAG_SW_DEBUG_MODE_MASK) >> MAC_PCU_DIAG_SW_DEBUG_MODE_LSB)
-#define MAC_PCU_DIAG_SW_DEBUG_MODE_SET(x)        (((x) << MAC_PCU_DIAG_SW_DEBUG_MODE_LSB) & MAC_PCU_DIAG_SW_DEBUG_MODE_MASK)
-#define MAC_PCU_DIAG_SW_RX_CLEAR_EXT_LOW_MSB     29
-#define MAC_PCU_DIAG_SW_RX_CLEAR_EXT_LOW_LSB     29
-#define MAC_PCU_DIAG_SW_RX_CLEAR_EXT_LOW_MASK    0x20000000
-#define MAC_PCU_DIAG_SW_RX_CLEAR_EXT_LOW_GET(x)  (((x) & MAC_PCU_DIAG_SW_RX_CLEAR_EXT_LOW_MASK) >> MAC_PCU_DIAG_SW_RX_CLEAR_EXT_LOW_LSB)
-#define MAC_PCU_DIAG_SW_RX_CLEAR_EXT_LOW_SET(x)  (((x) << MAC_PCU_DIAG_SW_RX_CLEAR_EXT_LOW_LSB) & MAC_PCU_DIAG_SW_RX_CLEAR_EXT_LOW_MASK)
-#define MAC_PCU_DIAG_SW_RX_CLEAR_CTL_LOW_MSB     28
-#define MAC_PCU_DIAG_SW_RX_CLEAR_CTL_LOW_LSB     28
-#define MAC_PCU_DIAG_SW_RX_CLEAR_CTL_LOW_MASK    0x10000000
-#define MAC_PCU_DIAG_SW_RX_CLEAR_CTL_LOW_GET(x)  (((x) & MAC_PCU_DIAG_SW_RX_CLEAR_CTL_LOW_MASK) >> MAC_PCU_DIAG_SW_RX_CLEAR_CTL_LOW_LSB)
-#define MAC_PCU_DIAG_SW_RX_CLEAR_CTL_LOW_SET(x)  (((x) << MAC_PCU_DIAG_SW_RX_CLEAR_CTL_LOW_LSB) & MAC_PCU_DIAG_SW_RX_CLEAR_CTL_LOW_MASK)
-#define MAC_PCU_DIAG_SW_OBS_SEL_2_MSB            27
-#define MAC_PCU_DIAG_SW_OBS_SEL_2_LSB            27
-#define MAC_PCU_DIAG_SW_OBS_SEL_2_MASK           0x08000000
-#define MAC_PCU_DIAG_SW_OBS_SEL_2_GET(x)         (((x) & MAC_PCU_DIAG_SW_OBS_SEL_2_MASK) >> MAC_PCU_DIAG_SW_OBS_SEL_2_LSB)
-#define MAC_PCU_DIAG_SW_OBS_SEL_2_SET(x)         (((x) << MAC_PCU_DIAG_SW_OBS_SEL_2_LSB) & MAC_PCU_DIAG_SW_OBS_SEL_2_MASK)
-#define MAC_PCU_DIAG_SW_SATURATE_CYCLE_CNT_MSB   26
-#define MAC_PCU_DIAG_SW_SATURATE_CYCLE_CNT_LSB   26
-#define MAC_PCU_DIAG_SW_SATURATE_CYCLE_CNT_MASK  0x04000000
-#define MAC_PCU_DIAG_SW_SATURATE_CYCLE_CNT_GET(x) (((x) & MAC_PCU_DIAG_SW_SATURATE_CYCLE_CNT_MASK) >> MAC_PCU_DIAG_SW_SATURATE_CYCLE_CNT_LSB)
-#define MAC_PCU_DIAG_SW_SATURATE_CYCLE_CNT_SET(x) (((x) << MAC_PCU_DIAG_SW_SATURATE_CYCLE_CNT_LSB) & MAC_PCU_DIAG_SW_SATURATE_CYCLE_CNT_MASK)
-#define MAC_PCU_DIAG_SW_FORCE_RX_ABORT_MSB       25
-#define MAC_PCU_DIAG_SW_FORCE_RX_ABORT_LSB       25
-#define MAC_PCU_DIAG_SW_FORCE_RX_ABORT_MASK      0x02000000
-#define MAC_PCU_DIAG_SW_FORCE_RX_ABORT_GET(x)    (((x) & MAC_PCU_DIAG_SW_FORCE_RX_ABORT_MASK) >> MAC_PCU_DIAG_SW_FORCE_RX_ABORT_LSB)
-#define MAC_PCU_DIAG_SW_FORCE_RX_ABORT_SET(x)    (((x) << MAC_PCU_DIAG_SW_FORCE_RX_ABORT_LSB) & MAC_PCU_DIAG_SW_FORCE_RX_ABORT_MASK)
-#define MAC_PCU_DIAG_SW_DUAL_CHAIN_CHAN_INFO_MSB 24
-#define MAC_PCU_DIAG_SW_DUAL_CHAIN_CHAN_INFO_LSB 24
-#define MAC_PCU_DIAG_SW_DUAL_CHAIN_CHAN_INFO_MASK 0x01000000
-#define MAC_PCU_DIAG_SW_DUAL_CHAIN_CHAN_INFO_GET(x) (((x) & MAC_PCU_DIAG_SW_DUAL_CHAIN_CHAN_INFO_MASK) >> MAC_PCU_DIAG_SW_DUAL_CHAIN_CHAN_INFO_LSB)
-#define MAC_PCU_DIAG_SW_DUAL_CHAIN_CHAN_INFO_SET(x) (((x) << MAC_PCU_DIAG_SW_DUAL_CHAIN_CHAN_INFO_LSB) & MAC_PCU_DIAG_SW_DUAL_CHAIN_CHAN_INFO_MASK)
-#define MAC_PCU_DIAG_SW_PHYERR_ENABLE_EIFS_CTL_MSB 23
-#define MAC_PCU_DIAG_SW_PHYERR_ENABLE_EIFS_CTL_LSB 23
-#define MAC_PCU_DIAG_SW_PHYERR_ENABLE_EIFS_CTL_MASK 0x00800000
-#define MAC_PCU_DIAG_SW_PHYERR_ENABLE_EIFS_CTL_GET(x) (((x) & MAC_PCU_DIAG_SW_PHYERR_ENABLE_EIFS_CTL_MASK) >> MAC_PCU_DIAG_SW_PHYERR_ENABLE_EIFS_CTL_LSB)
-#define MAC_PCU_DIAG_SW_PHYERR_ENABLE_EIFS_CTL_SET(x) (((x) << MAC_PCU_DIAG_SW_PHYERR_ENABLE_EIFS_CTL_LSB) & MAC_PCU_DIAG_SW_PHYERR_ENABLE_EIFS_CTL_MASK)
-#define MAC_PCU_DIAG_SW_CHAN_IDLE_HIGH_MSB       22
-#define MAC_PCU_DIAG_SW_CHAN_IDLE_HIGH_LSB       22
-#define MAC_PCU_DIAG_SW_CHAN_IDLE_HIGH_MASK      0x00400000
-#define MAC_PCU_DIAG_SW_CHAN_IDLE_HIGH_GET(x)    (((x) & MAC_PCU_DIAG_SW_CHAN_IDLE_HIGH_MASK) >> MAC_PCU_DIAG_SW_CHAN_IDLE_HIGH_LSB)
-#define MAC_PCU_DIAG_SW_CHAN_IDLE_HIGH_SET(x)    (((x) << MAC_PCU_DIAG_SW_CHAN_IDLE_HIGH_LSB) & MAC_PCU_DIAG_SW_CHAN_IDLE_HIGH_MASK)
-#define MAC_PCU_DIAG_SW_IGNORE_NAV_MSB           21
-#define MAC_PCU_DIAG_SW_IGNORE_NAV_LSB           21
-#define MAC_PCU_DIAG_SW_IGNORE_NAV_MASK          0x00200000
-#define MAC_PCU_DIAG_SW_IGNORE_NAV_GET(x)        (((x) & MAC_PCU_DIAG_SW_IGNORE_NAV_MASK) >> MAC_PCU_DIAG_SW_IGNORE_NAV_LSB)
-#define MAC_PCU_DIAG_SW_IGNORE_NAV_SET(x)        (((x) << MAC_PCU_DIAG_SW_IGNORE_NAV_LSB) & MAC_PCU_DIAG_SW_IGNORE_NAV_MASK)
-#define MAC_PCU_DIAG_SW_RX_CLEAR_HIGH_MSB        20
-#define MAC_PCU_DIAG_SW_RX_CLEAR_HIGH_LSB        20
-#define MAC_PCU_DIAG_SW_RX_CLEAR_HIGH_MASK       0x00100000
-#define MAC_PCU_DIAG_SW_RX_CLEAR_HIGH_GET(x)     (((x) & MAC_PCU_DIAG_SW_RX_CLEAR_HIGH_MASK) >> MAC_PCU_DIAG_SW_RX_CLEAR_HIGH_LSB)
-#define MAC_PCU_DIAG_SW_RX_CLEAR_HIGH_SET(x)     (((x) << MAC_PCU_DIAG_SW_RX_CLEAR_HIGH_LSB) & MAC_PCU_DIAG_SW_RX_CLEAR_HIGH_MASK)
-#define MAC_PCU_DIAG_SW_OBS_SEL_1_0_MSB          19
-#define MAC_PCU_DIAG_SW_OBS_SEL_1_0_LSB          18
-#define MAC_PCU_DIAG_SW_OBS_SEL_1_0_MASK         0x000c0000
-#define MAC_PCU_DIAG_SW_OBS_SEL_1_0_GET(x)       (((x) & MAC_PCU_DIAG_SW_OBS_SEL_1_0_MASK) >> MAC_PCU_DIAG_SW_OBS_SEL_1_0_LSB)
-#define MAC_PCU_DIAG_SW_OBS_SEL_1_0_SET(x)       (((x) << MAC_PCU_DIAG_SW_OBS_SEL_1_0_LSB) & MAC_PCU_DIAG_SW_OBS_SEL_1_0_MASK)
-#define MAC_PCU_DIAG_SW_ACCEPT_NON_V0_MSB        17
-#define MAC_PCU_DIAG_SW_ACCEPT_NON_V0_LSB        17
-#define MAC_PCU_DIAG_SW_ACCEPT_NON_V0_MASK       0x00020000
-#define MAC_PCU_DIAG_SW_ACCEPT_NON_V0_GET(x)     (((x) & MAC_PCU_DIAG_SW_ACCEPT_NON_V0_MASK) >> MAC_PCU_DIAG_SW_ACCEPT_NON_V0_LSB)
-#define MAC_PCU_DIAG_SW_ACCEPT_NON_V0_SET(x)     (((x) << MAC_PCU_DIAG_SW_ACCEPT_NON_V0_LSB) & MAC_PCU_DIAG_SW_ACCEPT_NON_V0_MASK)
-#define MAC_PCU_DIAG_SW_DUMP_CHAN_INFO_MSB       8
-#define MAC_PCU_DIAG_SW_DUMP_CHAN_INFO_LSB       8
-#define MAC_PCU_DIAG_SW_DUMP_CHAN_INFO_MASK      0x00000100
-#define MAC_PCU_DIAG_SW_DUMP_CHAN_INFO_GET(x)    (((x) & MAC_PCU_DIAG_SW_DUMP_CHAN_INFO_MASK) >> MAC_PCU_DIAG_SW_DUMP_CHAN_INFO_LSB)
-#define MAC_PCU_DIAG_SW_DUMP_CHAN_INFO_SET(x)    (((x) << MAC_PCU_DIAG_SW_DUMP_CHAN_INFO_LSB) & MAC_PCU_DIAG_SW_DUMP_CHAN_INFO_MASK)
-#define MAC_PCU_DIAG_SW_CORRUPT_FCS_MSB          7
-#define MAC_PCU_DIAG_SW_CORRUPT_FCS_LSB          7
-#define MAC_PCU_DIAG_SW_CORRUPT_FCS_MASK         0x00000080
-#define MAC_PCU_DIAG_SW_CORRUPT_FCS_GET(x)       (((x) & MAC_PCU_DIAG_SW_CORRUPT_FCS_MASK) >> MAC_PCU_DIAG_SW_CORRUPT_FCS_LSB)
-#define MAC_PCU_DIAG_SW_CORRUPT_FCS_SET(x)       (((x) << MAC_PCU_DIAG_SW_CORRUPT_FCS_LSB) & MAC_PCU_DIAG_SW_CORRUPT_FCS_MASK)
-#define MAC_PCU_DIAG_SW_LOOP_BACK_MSB            6
-#define MAC_PCU_DIAG_SW_LOOP_BACK_LSB            6
-#define MAC_PCU_DIAG_SW_LOOP_BACK_MASK           0x00000040
-#define MAC_PCU_DIAG_SW_LOOP_BACK_GET(x)         (((x) & MAC_PCU_DIAG_SW_LOOP_BACK_MASK) >> MAC_PCU_DIAG_SW_LOOP_BACK_LSB)
-#define MAC_PCU_DIAG_SW_LOOP_BACK_SET(x)         (((x) << MAC_PCU_DIAG_SW_LOOP_BACK_LSB) & MAC_PCU_DIAG_SW_LOOP_BACK_MASK)
-#define MAC_PCU_DIAG_SW_HALT_RX_MSB              5
-#define MAC_PCU_DIAG_SW_HALT_RX_LSB              5
-#define MAC_PCU_DIAG_SW_HALT_RX_MASK             0x00000020
-#define MAC_PCU_DIAG_SW_HALT_RX_GET(x)           (((x) & MAC_PCU_DIAG_SW_HALT_RX_MASK) >> MAC_PCU_DIAG_SW_HALT_RX_LSB)
-#define MAC_PCU_DIAG_SW_HALT_RX_SET(x)           (((x) << MAC_PCU_DIAG_SW_HALT_RX_LSB) & MAC_PCU_DIAG_SW_HALT_RX_MASK)
-#define MAC_PCU_DIAG_SW_NO_DECRYPT_MSB           4
-#define MAC_PCU_DIAG_SW_NO_DECRYPT_LSB           4
-#define MAC_PCU_DIAG_SW_NO_DECRYPT_MASK          0x00000010
-#define MAC_PCU_DIAG_SW_NO_DECRYPT_GET(x)        (((x) & MAC_PCU_DIAG_SW_NO_DECRYPT_MASK) >> MAC_PCU_DIAG_SW_NO_DECRYPT_LSB)
-#define MAC_PCU_DIAG_SW_NO_DECRYPT_SET(x)        (((x) << MAC_PCU_DIAG_SW_NO_DECRYPT_LSB) & MAC_PCU_DIAG_SW_NO_DECRYPT_MASK)
-#define MAC_PCU_DIAG_SW_NO_ENCRYPT_MSB           3
-#define MAC_PCU_DIAG_SW_NO_ENCRYPT_LSB           3
-#define MAC_PCU_DIAG_SW_NO_ENCRYPT_MASK          0x00000008
-#define MAC_PCU_DIAG_SW_NO_ENCRYPT_GET(x)        (((x) & MAC_PCU_DIAG_SW_NO_ENCRYPT_MASK) >> MAC_PCU_DIAG_SW_NO_ENCRYPT_LSB)
-#define MAC_PCU_DIAG_SW_NO_ENCRYPT_SET(x)        (((x) << MAC_PCU_DIAG_SW_NO_ENCRYPT_LSB) & MAC_PCU_DIAG_SW_NO_ENCRYPT_MASK)
-#define MAC_PCU_DIAG_SW_NO_CTS_MSB               2
-#define MAC_PCU_DIAG_SW_NO_CTS_LSB               2
-#define MAC_PCU_DIAG_SW_NO_CTS_MASK              0x00000004
-#define MAC_PCU_DIAG_SW_NO_CTS_GET(x)            (((x) & MAC_PCU_DIAG_SW_NO_CTS_MASK) >> MAC_PCU_DIAG_SW_NO_CTS_LSB)
-#define MAC_PCU_DIAG_SW_NO_CTS_SET(x)            (((x) << MAC_PCU_DIAG_SW_NO_CTS_LSB) & MAC_PCU_DIAG_SW_NO_CTS_MASK)
-#define MAC_PCU_DIAG_SW_NO_ACK_MSB               1
-#define MAC_PCU_DIAG_SW_NO_ACK_LSB               1
-#define MAC_PCU_DIAG_SW_NO_ACK_MASK              0x00000002
-#define MAC_PCU_DIAG_SW_NO_ACK_GET(x)            (((x) & MAC_PCU_DIAG_SW_NO_ACK_MASK) >> MAC_PCU_DIAG_SW_NO_ACK_LSB)
-#define MAC_PCU_DIAG_SW_NO_ACK_SET(x)            (((x) << MAC_PCU_DIAG_SW_NO_ACK_LSB) & MAC_PCU_DIAG_SW_NO_ACK_MASK)
-#define MAC_PCU_DIAG_SW_INVALID_KEY_NO_ACK_MSB   0
-#define MAC_PCU_DIAG_SW_INVALID_KEY_NO_ACK_LSB   0
-#define MAC_PCU_DIAG_SW_INVALID_KEY_NO_ACK_MASK  0x00000001
-#define MAC_PCU_DIAG_SW_INVALID_KEY_NO_ACK_GET(x) (((x) & MAC_PCU_DIAG_SW_INVALID_KEY_NO_ACK_MASK) >> MAC_PCU_DIAG_SW_INVALID_KEY_NO_ACK_LSB)
-#define MAC_PCU_DIAG_SW_INVALID_KEY_NO_ACK_SET(x) (((x) << MAC_PCU_DIAG_SW_INVALID_KEY_NO_ACK_LSB) & MAC_PCU_DIAG_SW_INVALID_KEY_NO_ACK_MASK)
-
-#define MAC_PCU_TST_ADDAC_ADDRESS                0x00008034
-#define MAC_PCU_TST_ADDAC_OFFSET                 0x00000034
-#define MAC_PCU_TST_ADDAC_TEST_ARM_MSB           20
-#define MAC_PCU_TST_ADDAC_TEST_ARM_LSB           20
-#define MAC_PCU_TST_ADDAC_TEST_ARM_MASK          0x00100000
-#define MAC_PCU_TST_ADDAC_TEST_ARM_GET(x)        (((x) & MAC_PCU_TST_ADDAC_TEST_ARM_MASK) >> MAC_PCU_TST_ADDAC_TEST_ARM_LSB)
-#define MAC_PCU_TST_ADDAC_TEST_ARM_SET(x)        (((x) << MAC_PCU_TST_ADDAC_TEST_ARM_LSB) & MAC_PCU_TST_ADDAC_TEST_ARM_MASK)
-#define MAC_PCU_TST_ADDAC_TEST_CAPTURE_MSB       19
-#define MAC_PCU_TST_ADDAC_TEST_CAPTURE_LSB       19
-#define MAC_PCU_TST_ADDAC_TEST_CAPTURE_MASK      0x00080000
-#define MAC_PCU_TST_ADDAC_TEST_CAPTURE_GET(x)    (((x) & MAC_PCU_TST_ADDAC_TEST_CAPTURE_MASK) >> MAC_PCU_TST_ADDAC_TEST_CAPTURE_LSB)
-#define MAC_PCU_TST_ADDAC_TEST_CAPTURE_SET(x)    (((x) << MAC_PCU_TST_ADDAC_TEST_CAPTURE_LSB) & MAC_PCU_TST_ADDAC_TEST_CAPTURE_MASK)
-#define MAC_PCU_TST_ADDAC_CONT_TEST_MSB          18
-#define MAC_PCU_TST_ADDAC_CONT_TEST_LSB          18
-#define MAC_PCU_TST_ADDAC_CONT_TEST_MASK         0x00040000
-#define MAC_PCU_TST_ADDAC_CONT_TEST_GET(x)       (((x) & MAC_PCU_TST_ADDAC_CONT_TEST_MASK) >> MAC_PCU_TST_ADDAC_CONT_TEST_LSB)
-#define MAC_PCU_TST_ADDAC_CONT_TEST_SET(x)       (((x) << MAC_PCU_TST_ADDAC_CONT_TEST_LSB) & MAC_PCU_TST_ADDAC_CONT_TEST_MASK)
-#define MAC_PCU_TST_ADDAC_TRIG_POLARITY_MSB      17
-#define MAC_PCU_TST_ADDAC_TRIG_POLARITY_LSB      17
-#define MAC_PCU_TST_ADDAC_TRIG_POLARITY_MASK     0x00020000
-#define MAC_PCU_TST_ADDAC_TRIG_POLARITY_GET(x)   (((x) & MAC_PCU_TST_ADDAC_TRIG_POLARITY_MASK) >> MAC_PCU_TST_ADDAC_TRIG_POLARITY_LSB)
-#define MAC_PCU_TST_ADDAC_TRIG_POLARITY_SET(x)   (((x) << MAC_PCU_TST_ADDAC_TRIG_POLARITY_LSB) & MAC_PCU_TST_ADDAC_TRIG_POLARITY_MASK)
-#define MAC_PCU_TST_ADDAC_TRIG_SEL_MSB           16
-#define MAC_PCU_TST_ADDAC_TRIG_SEL_LSB           16
-#define MAC_PCU_TST_ADDAC_TRIG_SEL_MASK          0x00010000
-#define MAC_PCU_TST_ADDAC_TRIG_SEL_GET(x)        (((x) & MAC_PCU_TST_ADDAC_TRIG_SEL_MASK) >> MAC_PCU_TST_ADDAC_TRIG_SEL_LSB)
-#define MAC_PCU_TST_ADDAC_TRIG_SEL_SET(x)        (((x) << MAC_PCU_TST_ADDAC_TRIG_SEL_LSB) & MAC_PCU_TST_ADDAC_TRIG_SEL_MASK)
-#define MAC_PCU_TST_ADDAC_UPPER_8B_MSB           14
-#define MAC_PCU_TST_ADDAC_UPPER_8B_LSB           14
-#define MAC_PCU_TST_ADDAC_UPPER_8B_MASK          0x00004000
-#define MAC_PCU_TST_ADDAC_UPPER_8B_GET(x)        (((x) & MAC_PCU_TST_ADDAC_UPPER_8B_MASK) >> MAC_PCU_TST_ADDAC_UPPER_8B_LSB)
-#define MAC_PCU_TST_ADDAC_UPPER_8B_SET(x)        (((x) << MAC_PCU_TST_ADDAC_UPPER_8B_LSB) & MAC_PCU_TST_ADDAC_UPPER_8B_MASK)
-#define MAC_PCU_TST_ADDAC_LOOP_LEN_MSB           13
-#define MAC_PCU_TST_ADDAC_LOOP_LEN_LSB           3
-#define MAC_PCU_TST_ADDAC_LOOP_LEN_MASK          0x00003ff8
-#define MAC_PCU_TST_ADDAC_LOOP_LEN_GET(x)        (((x) & MAC_PCU_TST_ADDAC_LOOP_LEN_MASK) >> MAC_PCU_TST_ADDAC_LOOP_LEN_LSB)
-#define MAC_PCU_TST_ADDAC_LOOP_LEN_SET(x)        (((x) << MAC_PCU_TST_ADDAC_LOOP_LEN_LSB) & MAC_PCU_TST_ADDAC_LOOP_LEN_MASK)
-#define MAC_PCU_TST_ADDAC_LOOP_MSB               2
-#define MAC_PCU_TST_ADDAC_LOOP_LSB               2
-#define MAC_PCU_TST_ADDAC_LOOP_MASK              0x00000004
-#define MAC_PCU_TST_ADDAC_LOOP_GET(x)            (((x) & MAC_PCU_TST_ADDAC_LOOP_MASK) >> MAC_PCU_TST_ADDAC_LOOP_LSB)
-#define MAC_PCU_TST_ADDAC_LOOP_SET(x)            (((x) << MAC_PCU_TST_ADDAC_LOOP_LSB) & MAC_PCU_TST_ADDAC_LOOP_MASK)
-#define MAC_PCU_TST_ADDAC_TESTMODE_MSB           1
-#define MAC_PCU_TST_ADDAC_TESTMODE_LSB           1
-#define MAC_PCU_TST_ADDAC_TESTMODE_MASK          0x00000002
-#define MAC_PCU_TST_ADDAC_TESTMODE_GET(x)        (((x) & MAC_PCU_TST_ADDAC_TESTMODE_MASK) >> MAC_PCU_TST_ADDAC_TESTMODE_LSB)
-#define MAC_PCU_TST_ADDAC_TESTMODE_SET(x)        (((x) << MAC_PCU_TST_ADDAC_TESTMODE_LSB) & MAC_PCU_TST_ADDAC_TESTMODE_MASK)
-#define MAC_PCU_TST_ADDAC_CONT_TX_MSB            0
-#define MAC_PCU_TST_ADDAC_CONT_TX_LSB            0
-#define MAC_PCU_TST_ADDAC_CONT_TX_MASK           0x00000001
-#define MAC_PCU_TST_ADDAC_CONT_TX_GET(x)         (((x) & MAC_PCU_TST_ADDAC_CONT_TX_MASK) >> MAC_PCU_TST_ADDAC_CONT_TX_LSB)
-#define MAC_PCU_TST_ADDAC_CONT_TX_SET(x)         (((x) << MAC_PCU_TST_ADDAC_CONT_TX_LSB) & MAC_PCU_TST_ADDAC_CONT_TX_MASK)
-
-#define MAC_PCU_DEF_ANTENNA_ADDRESS              0x00008038
-#define MAC_PCU_DEF_ANTENNA_OFFSET               0x00000038
-#define MAC_PCU_DEF_ANTENNA_RX_LNA_CONFIG_SEL_MSB 28
-#define MAC_PCU_DEF_ANTENNA_RX_LNA_CONFIG_SEL_LSB 28
-#define MAC_PCU_DEF_ANTENNA_RX_LNA_CONFIG_SEL_MASK 0x10000000
-#define MAC_PCU_DEF_ANTENNA_RX_LNA_CONFIG_SEL_GET(x) (((x) & MAC_PCU_DEF_ANTENNA_RX_LNA_CONFIG_SEL_MASK) >> MAC_PCU_DEF_ANTENNA_RX_LNA_CONFIG_SEL_LSB)
-#define MAC_PCU_DEF_ANTENNA_RX_LNA_CONFIG_SEL_SET(x) (((x) << MAC_PCU_DEF_ANTENNA_RX_LNA_CONFIG_SEL_LSB) & MAC_PCU_DEF_ANTENNA_RX_LNA_CONFIG_SEL_MASK)
-#define MAC_PCU_DEF_ANTENNA_TX_DEF_ANT_SEL_MSB   24
-#define MAC_PCU_DEF_ANTENNA_TX_DEF_ANT_SEL_LSB   24
-#define MAC_PCU_DEF_ANTENNA_TX_DEF_ANT_SEL_MASK  0x01000000
-#define MAC_PCU_DEF_ANTENNA_TX_DEF_ANT_SEL_GET(x) (((x) & MAC_PCU_DEF_ANTENNA_TX_DEF_ANT_SEL_MASK) >> MAC_PCU_DEF_ANTENNA_TX_DEF_ANT_SEL_LSB)
-#define MAC_PCU_DEF_ANTENNA_TX_DEF_ANT_SEL_SET(x) (((x) << MAC_PCU_DEF_ANTENNA_TX_DEF_ANT_SEL_LSB) & MAC_PCU_DEF_ANTENNA_TX_DEF_ANT_SEL_MASK)
-#define MAC_PCU_DEF_ANTENNA_VALUE_MSB            23
-#define MAC_PCU_DEF_ANTENNA_VALUE_LSB            0
-#define MAC_PCU_DEF_ANTENNA_VALUE_MASK           0x00ffffff
-#define MAC_PCU_DEF_ANTENNA_VALUE_GET(x)         (((x) & MAC_PCU_DEF_ANTENNA_VALUE_MASK) >> MAC_PCU_DEF_ANTENNA_VALUE_LSB)
-#define MAC_PCU_DEF_ANTENNA_VALUE_SET(x)         (((x) << MAC_PCU_DEF_ANTENNA_VALUE_LSB) & MAC_PCU_DEF_ANTENNA_VALUE_MASK)
-
-#define MAC_PCU_AES_MUTE_MASK_0_ADDRESS          0x0000803c
-#define MAC_PCU_AES_MUTE_MASK_0_OFFSET           0x0000003c
-#define MAC_PCU_AES_MUTE_MASK_0_QOS_MSB          31
-#define MAC_PCU_AES_MUTE_MASK_0_QOS_LSB          16
-#define MAC_PCU_AES_MUTE_MASK_0_QOS_MASK         0xffff0000
-#define MAC_PCU_AES_MUTE_MASK_0_QOS_GET(x)       (((x) & MAC_PCU_AES_MUTE_MASK_0_QOS_MASK) >> MAC_PCU_AES_MUTE_MASK_0_QOS_LSB)
-#define MAC_PCU_AES_MUTE_MASK_0_QOS_SET(x)       (((x) << MAC_PCU_AES_MUTE_MASK_0_QOS_LSB) & MAC_PCU_AES_MUTE_MASK_0_QOS_MASK)
-#define MAC_PCU_AES_MUTE_MASK_0_FC_MSB           15
-#define MAC_PCU_AES_MUTE_MASK_0_FC_LSB           0
-#define MAC_PCU_AES_MUTE_MASK_0_FC_MASK          0x0000ffff
-#define MAC_PCU_AES_MUTE_MASK_0_FC_GET(x)        (((x) & MAC_PCU_AES_MUTE_MASK_0_FC_MASK) >> MAC_PCU_AES_MUTE_MASK_0_FC_LSB)
-#define MAC_PCU_AES_MUTE_MASK_0_FC_SET(x)        (((x) << MAC_PCU_AES_MUTE_MASK_0_FC_LSB) & MAC_PCU_AES_MUTE_MASK_0_FC_MASK)
-
-#define MAC_PCU_AES_MUTE_MASK_1_ADDRESS          0x00008040
-#define MAC_PCU_AES_MUTE_MASK_1_OFFSET           0x00000040
-#define MAC_PCU_AES_MUTE_MASK_1_FC_MGMT_MSB      31
-#define MAC_PCU_AES_MUTE_MASK_1_FC_MGMT_LSB      16
-#define MAC_PCU_AES_MUTE_MASK_1_FC_MGMT_MASK     0xffff0000
-#define MAC_PCU_AES_MUTE_MASK_1_FC_MGMT_GET(x)   (((x) & MAC_PCU_AES_MUTE_MASK_1_FC_MGMT_MASK) >> MAC_PCU_AES_MUTE_MASK_1_FC_MGMT_LSB)
-#define MAC_PCU_AES_MUTE_MASK_1_FC_MGMT_SET(x)   (((x) << MAC_PCU_AES_MUTE_MASK_1_FC_MGMT_LSB) & MAC_PCU_AES_MUTE_MASK_1_FC_MGMT_MASK)
-#define MAC_PCU_AES_MUTE_MASK_1_SEQ_MSB          15
-#define MAC_PCU_AES_MUTE_MASK_1_SEQ_LSB          0
-#define MAC_PCU_AES_MUTE_MASK_1_SEQ_MASK         0x0000ffff
-#define MAC_PCU_AES_MUTE_MASK_1_SEQ_GET(x)       (((x) & MAC_PCU_AES_MUTE_MASK_1_SEQ_MASK) >> MAC_PCU_AES_MUTE_MASK_1_SEQ_LSB)
-#define MAC_PCU_AES_MUTE_MASK_1_SEQ_SET(x)       (((x) << MAC_PCU_AES_MUTE_MASK_1_SEQ_LSB) & MAC_PCU_AES_MUTE_MASK_1_SEQ_MASK)
-
-#define MAC_PCU_GATED_CLKS_ADDRESS               0x00008044
-#define MAC_PCU_GATED_CLKS_OFFSET                0x00000044
-#define MAC_PCU_GATED_CLKS_GATED_REG_MSB         3
-#define MAC_PCU_GATED_CLKS_GATED_REG_LSB         3
-#define MAC_PCU_GATED_CLKS_GATED_REG_MASK        0x00000008
-#define MAC_PCU_GATED_CLKS_GATED_REG_GET(x)      (((x) & MAC_PCU_GATED_CLKS_GATED_REG_MASK) >> MAC_PCU_GATED_CLKS_GATED_REG_LSB)
-#define MAC_PCU_GATED_CLKS_GATED_REG_SET(x)      (((x) << MAC_PCU_GATED_CLKS_GATED_REG_LSB) & MAC_PCU_GATED_CLKS_GATED_REG_MASK)
-#define MAC_PCU_GATED_CLKS_GATED_RX_MSB          2
-#define MAC_PCU_GATED_CLKS_GATED_RX_LSB          2
-#define MAC_PCU_GATED_CLKS_GATED_RX_MASK         0x00000004
-#define MAC_PCU_GATED_CLKS_GATED_RX_GET(x)       (((x) & MAC_PCU_GATED_CLKS_GATED_RX_MASK) >> MAC_PCU_GATED_CLKS_GATED_RX_LSB)
-#define MAC_PCU_GATED_CLKS_GATED_RX_SET(x)       (((x) << MAC_PCU_GATED_CLKS_GATED_RX_LSB) & MAC_PCU_GATED_CLKS_GATED_RX_MASK)
-#define MAC_PCU_GATED_CLKS_GATED_TX_MSB          1
-#define MAC_PCU_GATED_CLKS_GATED_TX_LSB          1
-#define MAC_PCU_GATED_CLKS_GATED_TX_MASK         0x00000002
-#define MAC_PCU_GATED_CLKS_GATED_TX_GET(x)       (((x) & MAC_PCU_GATED_CLKS_GATED_TX_MASK) >> MAC_PCU_GATED_CLKS_GATED_TX_LSB)
-#define MAC_PCU_GATED_CLKS_GATED_TX_SET(x)       (((x) << MAC_PCU_GATED_CLKS_GATED_TX_LSB) & MAC_PCU_GATED_CLKS_GATED_TX_MASK)
-
-#define MAC_PCU_OBS_BUS_2_ADDRESS                0x00008048
-#define MAC_PCU_OBS_BUS_2_OFFSET                 0x00000048
-#define MAC_PCU_OBS_BUS_2_VALUE_MSB              17
-#define MAC_PCU_OBS_BUS_2_VALUE_LSB              0
-#define MAC_PCU_OBS_BUS_2_VALUE_MASK             0x0003ffff
-#define MAC_PCU_OBS_BUS_2_VALUE_GET(x)           (((x) & MAC_PCU_OBS_BUS_2_VALUE_MASK) >> MAC_PCU_OBS_BUS_2_VALUE_LSB)
-#define MAC_PCU_OBS_BUS_2_VALUE_SET(x)           (((x) << MAC_PCU_OBS_BUS_2_VALUE_LSB) & MAC_PCU_OBS_BUS_2_VALUE_MASK)
-
-#define MAC_PCU_OBS_BUS_1_ADDRESS                0x0000804c
-#define MAC_PCU_OBS_BUS_1_OFFSET                 0x0000004c
-#define MAC_PCU_OBS_BUS_1_TX_STATE_MSB           30
-#define MAC_PCU_OBS_BUS_1_TX_STATE_LSB           25
-#define MAC_PCU_OBS_BUS_1_TX_STATE_MASK          0x7e000000
-#define MAC_PCU_OBS_BUS_1_TX_STATE_GET(x)        (((x) & MAC_PCU_OBS_BUS_1_TX_STATE_MASK) >> MAC_PCU_OBS_BUS_1_TX_STATE_LSB)
-#define MAC_PCU_OBS_BUS_1_TX_STATE_SET(x)        (((x) << MAC_PCU_OBS_BUS_1_TX_STATE_LSB) & MAC_PCU_OBS_BUS_1_TX_STATE_MASK)
-#define MAC_PCU_OBS_BUS_1_RX_STATE_MSB           24
-#define MAC_PCU_OBS_BUS_1_RX_STATE_LSB           20
-#define MAC_PCU_OBS_BUS_1_RX_STATE_MASK          0x01f00000
-#define MAC_PCU_OBS_BUS_1_RX_STATE_GET(x)        (((x) & MAC_PCU_OBS_BUS_1_RX_STATE_MASK) >> MAC_PCU_OBS_BUS_1_RX_STATE_LSB)
-#define MAC_PCU_OBS_BUS_1_RX_STATE_SET(x)        (((x) << MAC_PCU_OBS_BUS_1_RX_STATE_LSB) & MAC_PCU_OBS_BUS_1_RX_STATE_MASK)
-#define MAC_PCU_OBS_BUS_1_WEP_STATE_MSB          17
-#define MAC_PCU_OBS_BUS_1_WEP_STATE_LSB          12
-#define MAC_PCU_OBS_BUS_1_WEP_STATE_MASK         0x0003f000
-#define MAC_PCU_OBS_BUS_1_WEP_STATE_GET(x)       (((x) & MAC_PCU_OBS_BUS_1_WEP_STATE_MASK) >> MAC_PCU_OBS_BUS_1_WEP_STATE_LSB)
-#define MAC_PCU_OBS_BUS_1_WEP_STATE_SET(x)       (((x) << MAC_PCU_OBS_BUS_1_WEP_STATE_LSB) & MAC_PCU_OBS_BUS_1_WEP_STATE_MASK)
-#define MAC_PCU_OBS_BUS_1_RX_CLEAR_MSB           11
-#define MAC_PCU_OBS_BUS_1_RX_CLEAR_LSB           11
-#define MAC_PCU_OBS_BUS_1_RX_CLEAR_MASK          0x00000800
-#define MAC_PCU_OBS_BUS_1_RX_CLEAR_GET(x)        (((x) & MAC_PCU_OBS_BUS_1_RX_CLEAR_MASK) >> MAC_PCU_OBS_BUS_1_RX_CLEAR_LSB)
-#define MAC_PCU_OBS_BUS_1_RX_CLEAR_SET(x)        (((x) << MAC_PCU_OBS_BUS_1_RX_CLEAR_LSB) & MAC_PCU_OBS_BUS_1_RX_CLEAR_MASK)
-#define MAC_PCU_OBS_BUS_1_RX_FRAME_MSB           10
-#define MAC_PCU_OBS_BUS_1_RX_FRAME_LSB           10
-#define MAC_PCU_OBS_BUS_1_RX_FRAME_MASK          0x00000400
-#define MAC_PCU_OBS_BUS_1_RX_FRAME_GET(x)        (((x) & MAC_PCU_OBS_BUS_1_RX_FRAME_MASK) >> MAC_PCU_OBS_BUS_1_RX_FRAME_LSB)
-#define MAC_PCU_OBS_BUS_1_RX_FRAME_SET(x)        (((x) << MAC_PCU_OBS_BUS_1_RX_FRAME_LSB) & MAC_PCU_OBS_BUS_1_RX_FRAME_MASK)
-#define MAC_PCU_OBS_BUS_1_TX_FRAME_MSB           9
-#define MAC_PCU_OBS_BUS_1_TX_FRAME_LSB           9
-#define MAC_PCU_OBS_BUS_1_TX_FRAME_MASK          0x00000200
-#define MAC_PCU_OBS_BUS_1_TX_FRAME_GET(x)        (((x) & MAC_PCU_OBS_BUS_1_TX_FRAME_MASK) >> MAC_PCU_OBS_BUS_1_TX_FRAME_LSB)
-#define MAC_PCU_OBS_BUS_1_TX_FRAME_SET(x)        (((x) << MAC_PCU_OBS_BUS_1_TX_FRAME_LSB) & MAC_PCU_OBS_BUS_1_TX_FRAME_MASK)
-#define MAC_PCU_OBS_BUS_1_TX_HOLD_MSB            8
-#define MAC_PCU_OBS_BUS_1_TX_HOLD_LSB            8
-#define MAC_PCU_OBS_BUS_1_TX_HOLD_MASK           0x00000100
-#define MAC_PCU_OBS_BUS_1_TX_HOLD_GET(x)         (((x) & MAC_PCU_OBS_BUS_1_TX_HOLD_MASK) >> MAC_PCU_OBS_BUS_1_TX_HOLD_LSB)
-#define MAC_PCU_OBS_BUS_1_TX_HOLD_SET(x)         (((x) << MAC_PCU_OBS_BUS_1_TX_HOLD_LSB) & MAC_PCU_OBS_BUS_1_TX_HOLD_MASK)
-#define MAC_PCU_OBS_BUS_1_PCU_CHANNEL_IDLE_MSB   7
-#define MAC_PCU_OBS_BUS_1_PCU_CHANNEL_IDLE_LSB   7
-#define MAC_PCU_OBS_BUS_1_PCU_CHANNEL_IDLE_MASK  0x00000080
-#define MAC_PCU_OBS_BUS_1_PCU_CHANNEL_IDLE_GET(x) (((x) & MAC_PCU_OBS_BUS_1_PCU_CHANNEL_IDLE_MASK) >> MAC_PCU_OBS_BUS_1_PCU_CHANNEL_IDLE_LSB)
-#define MAC_PCU_OBS_BUS_1_PCU_CHANNEL_IDLE_SET(x) (((x) << MAC_PCU_OBS_BUS_1_PCU_CHANNEL_IDLE_LSB) & MAC_PCU_OBS_BUS_1_PCU_CHANNEL_IDLE_MASK)
-#define MAC_PCU_OBS_BUS_1_TM_QUIET_TIME_MSB      6
-#define MAC_PCU_OBS_BUS_1_TM_QUIET_TIME_LSB      6
-#define MAC_PCU_OBS_BUS_1_TM_QUIET_TIME_MASK     0x00000040
-#define MAC_PCU_OBS_BUS_1_TM_QUIET_TIME_GET(x)   (((x) & MAC_PCU_OBS_BUS_1_TM_QUIET_TIME_MASK) >> MAC_PCU_OBS_BUS_1_TM_QUIET_TIME_LSB)
-#define MAC_PCU_OBS_BUS_1_TM_QUIET_TIME_SET(x)   (((x) << MAC_PCU_OBS_BUS_1_TM_QUIET_TIME_LSB) & MAC_PCU_OBS_BUS_1_TM_QUIET_TIME_MASK)
-#define MAC_PCU_OBS_BUS_1_TX_HCF_MSB             5
-#define MAC_PCU_OBS_BUS_1_TX_HCF_LSB             5
-#define MAC_PCU_OBS_BUS_1_TX_HCF_MASK            0x00000020
-#define MAC_PCU_OBS_BUS_1_TX_HCF_GET(x)          (((x) & MAC_PCU_OBS_BUS_1_TX_HCF_MASK) >> MAC_PCU_OBS_BUS_1_TX_HCF_LSB)
-#define MAC_PCU_OBS_BUS_1_TX_HCF_SET(x)          (((x) << MAC_PCU_OBS_BUS_1_TX_HCF_LSB) & MAC_PCU_OBS_BUS_1_TX_HCF_MASK)
-#define MAC_PCU_OBS_BUS_1_FILTER_PASS_MSB        4
-#define MAC_PCU_OBS_BUS_1_FILTER_PASS_LSB        4
-#define MAC_PCU_OBS_BUS_1_FILTER_PASS_MASK       0x00000010
-#define MAC_PCU_OBS_BUS_1_FILTER_PASS_GET(x)     (((x) & MAC_PCU_OBS_BUS_1_FILTER_PASS_MASK) >> MAC_PCU_OBS_BUS_1_FILTER_PASS_LSB)
-#define MAC_PCU_OBS_BUS_1_FILTER_PASS_SET(x)     (((x) << MAC_PCU_OBS_BUS_1_FILTER_PASS_LSB) & MAC_PCU_OBS_BUS_1_FILTER_PASS_MASK)
-#define MAC_PCU_OBS_BUS_1_RX_MY_BEACON_MSB       3
-#define MAC_PCU_OBS_BUS_1_RX_MY_BEACON_LSB       3
-#define MAC_PCU_OBS_BUS_1_RX_MY_BEACON_MASK      0x00000008
-#define MAC_PCU_OBS_BUS_1_RX_MY_BEACON_GET(x)    (((x) & MAC_PCU_OBS_BUS_1_RX_MY_BEACON_MASK) >> MAC_PCU_OBS_BUS_1_RX_MY_BEACON_LSB)
-#define MAC_PCU_OBS_BUS_1_RX_MY_BEACON_SET(x)    (((x) << MAC_PCU_OBS_BUS_1_RX_MY_BEACON_LSB) & MAC_PCU_OBS_BUS_1_RX_MY_BEACON_MASK)
-#define MAC_PCU_OBS_BUS_1_RX_WEP_MSB             2
-#define MAC_PCU_OBS_BUS_1_RX_WEP_LSB             2
-#define MAC_PCU_OBS_BUS_1_RX_WEP_MASK            0x00000004
-#define MAC_PCU_OBS_BUS_1_RX_WEP_GET(x)          (((x) & MAC_PCU_OBS_BUS_1_RX_WEP_MASK) >> MAC_PCU_OBS_BUS_1_RX_WEP_LSB)
-#define MAC_PCU_OBS_BUS_1_RX_WEP_SET(x)          (((x) << MAC_PCU_OBS_BUS_1_RX_WEP_LSB) & MAC_PCU_OBS_BUS_1_RX_WEP_MASK)
-#define MAC_PCU_OBS_BUS_1_PCU_RX_END_MSB         1
-#define MAC_PCU_OBS_BUS_1_PCU_RX_END_LSB         1
-#define MAC_PCU_OBS_BUS_1_PCU_RX_END_MASK        0x00000002
-#define MAC_PCU_OBS_BUS_1_PCU_RX_END_GET(x)      (((x) & MAC_PCU_OBS_BUS_1_PCU_RX_END_MASK) >> MAC_PCU_OBS_BUS_1_PCU_RX_END_LSB)
-#define MAC_PCU_OBS_BUS_1_PCU_RX_END_SET(x)      (((x) << MAC_PCU_OBS_BUS_1_PCU_RX_END_LSB) & MAC_PCU_OBS_BUS_1_PCU_RX_END_MASK)
-#define MAC_PCU_OBS_BUS_1_PCU_DIRECTED_MSB       0
-#define MAC_PCU_OBS_BUS_1_PCU_DIRECTED_LSB       0
-#define MAC_PCU_OBS_BUS_1_PCU_DIRECTED_MASK      0x00000001
-#define MAC_PCU_OBS_BUS_1_PCU_DIRECTED_GET(x)    (((x) & MAC_PCU_OBS_BUS_1_PCU_DIRECTED_MASK) >> MAC_PCU_OBS_BUS_1_PCU_DIRECTED_LSB)
-#define MAC_PCU_OBS_BUS_1_PCU_DIRECTED_SET(x)    (((x) << MAC_PCU_OBS_BUS_1_PCU_DIRECTED_LSB) & MAC_PCU_OBS_BUS_1_PCU_DIRECTED_MASK)
-
-#define MAC_PCU_DYM_MIMO_PWR_SAVE_ADDRESS        0x00008050
-#define MAC_PCU_DYM_MIMO_PWR_SAVE_OFFSET         0x00000050
-#define MAC_PCU_DYM_MIMO_PWR_SAVE_HI_PWR_CHAIN_MASK_MSB 10
-#define MAC_PCU_DYM_MIMO_PWR_SAVE_HI_PWR_CHAIN_MASK_LSB 8
-#define MAC_PCU_DYM_MIMO_PWR_SAVE_HI_PWR_CHAIN_MASK_MASK 0x00000700
-#define MAC_PCU_DYM_MIMO_PWR_SAVE_HI_PWR_CHAIN_MASK_GET(x) (((x) & MAC_PCU_DYM_MIMO_PWR_SAVE_HI_PWR_CHAIN_MASK_MASK) >> MAC_PCU_DYM_MIMO_PWR_SAVE_HI_PWR_CHAIN_MASK_LSB)
-#define MAC_PCU_DYM_MIMO_PWR_SAVE_HI_PWR_CHAIN_MASK_SET(x) (((x) << MAC_PCU_DYM_MIMO_PWR_SAVE_HI_PWR_CHAIN_MASK_LSB) & MAC_PCU_DYM_MIMO_PWR_SAVE_HI_PWR_CHAIN_MASK_MASK)
-#define MAC_PCU_DYM_MIMO_PWR_SAVE_LOW_PWR_CHAIN_MASK_MSB 6
-#define MAC_PCU_DYM_MIMO_PWR_SAVE_LOW_PWR_CHAIN_MASK_LSB 4
-#define MAC_PCU_DYM_MIMO_PWR_SAVE_LOW_PWR_CHAIN_MASK_MASK 0x00000070
-#define MAC_PCU_DYM_MIMO_PWR_SAVE_LOW_PWR_CHAIN_MASK_GET(x) (((x) & MAC_PCU_DYM_MIMO_PWR_SAVE_LOW_PWR_CHAIN_MASK_MASK) >> MAC_PCU_DYM_MIMO_PWR_SAVE_LOW_PWR_CHAIN_MASK_LSB)
-#define MAC_PCU_DYM_MIMO_PWR_SAVE_LOW_PWR_CHAIN_MASK_SET(x) (((x) << MAC_PCU_DYM_MIMO_PWR_SAVE_LOW_PWR_CHAIN_MASK_LSB) & MAC_PCU_DYM_MIMO_PWR_SAVE_LOW_PWR_CHAIN_MASK_MASK)
-#define MAC_PCU_DYM_MIMO_PWR_SAVE_SW_CHAIN_MASK_SEL_MSB 2
-#define MAC_PCU_DYM_MIMO_PWR_SAVE_SW_CHAIN_MASK_SEL_LSB 2
-#define MAC_PCU_DYM_MIMO_PWR_SAVE_SW_CHAIN_MASK_SEL_MASK 0x00000004
-#define MAC_PCU_DYM_MIMO_PWR_SAVE_SW_CHAIN_MASK_SEL_GET(x) (((x) & MAC_PCU_DYM_MIMO_PWR_SAVE_SW_CHAIN_MASK_SEL_MASK) >> MAC_PCU_DYM_MIMO_PWR_SAVE_SW_CHAIN_MASK_SEL_LSB)
-#define MAC_PCU_DYM_MIMO_PWR_SAVE_SW_CHAIN_MASK_SEL_SET(x) (((x) << MAC_PCU_DYM_MIMO_PWR_SAVE_SW_CHAIN_MASK_SEL_LSB) & MAC_PCU_DYM_MIMO_PWR_SAVE_SW_CHAIN_MASK_SEL_MASK)
-#define MAC_PCU_DYM_MIMO_PWR_SAVE_HW_CTRL_EN_MSB 1
-#define MAC_PCU_DYM_MIMO_PWR_SAVE_HW_CTRL_EN_LSB 1
-#define MAC_PCU_DYM_MIMO_PWR_SAVE_HW_CTRL_EN_MASK 0x00000002
-#define MAC_PCU_DYM_MIMO_PWR_SAVE_HW_CTRL_EN_GET(x) (((x) & MAC_PCU_DYM_MIMO_PWR_SAVE_HW_CTRL_EN_MASK) >> MAC_PCU_DYM_MIMO_PWR_SAVE_HW_CTRL_EN_LSB)
-#define MAC_PCU_DYM_MIMO_PWR_SAVE_HW_CTRL_EN_SET(x) (((x) << MAC_PCU_DYM_MIMO_PWR_SAVE_HW_CTRL_EN_LSB) & MAC_PCU_DYM_MIMO_PWR_SAVE_HW_CTRL_EN_MASK)
-#define MAC_PCU_DYM_MIMO_PWR_SAVE_USE_MAC_CTRL_MSB 0
-#define MAC_PCU_DYM_MIMO_PWR_SAVE_USE_MAC_CTRL_LSB 0
-#define MAC_PCU_DYM_MIMO_PWR_SAVE_USE_MAC_CTRL_MASK 0x00000001
-#define MAC_PCU_DYM_MIMO_PWR_SAVE_USE_MAC_CTRL_GET(x) (((x) & MAC_PCU_DYM_MIMO_PWR_SAVE_USE_MAC_CTRL_MASK) >> MAC_PCU_DYM_MIMO_PWR_SAVE_USE_MAC_CTRL_LSB)
-#define MAC_PCU_DYM_MIMO_PWR_SAVE_USE_MAC_CTRL_SET(x) (((x) << MAC_PCU_DYM_MIMO_PWR_SAVE_USE_MAC_CTRL_LSB) & MAC_PCU_DYM_MIMO_PWR_SAVE_USE_MAC_CTRL_MASK)
-
-#define MAC_PCU_LAST_BEACON_TSF_ADDRESS          0x00008054
-#define MAC_PCU_LAST_BEACON_TSF_OFFSET           0x00000054
-#define MAC_PCU_LAST_BEACON_TSF_VALUE_MSB        31
-#define MAC_PCU_LAST_BEACON_TSF_VALUE_LSB        0
-#define MAC_PCU_LAST_BEACON_TSF_VALUE_MASK       0xffffffff
-#define MAC_PCU_LAST_BEACON_TSF_VALUE_GET(x)     (((x) & MAC_PCU_LAST_BEACON_TSF_VALUE_MASK) >> MAC_PCU_LAST_BEACON_TSF_VALUE_LSB)
-#define MAC_PCU_LAST_BEACON_TSF_VALUE_SET(x)     (((x) << MAC_PCU_LAST_BEACON_TSF_VALUE_LSB) & MAC_PCU_LAST_BEACON_TSF_VALUE_MASK)
-
-#define MAC_PCU_NAV_ADDRESS                      0x00008058
-#define MAC_PCU_NAV_OFFSET                       0x00000058
-#define MAC_PCU_NAV_VALUE_MSB                    25
-#define MAC_PCU_NAV_VALUE_LSB                    0
-#define MAC_PCU_NAV_VALUE_MASK                   0x03ffffff
-#define MAC_PCU_NAV_VALUE_GET(x)                 (((x) & MAC_PCU_NAV_VALUE_MASK) >> MAC_PCU_NAV_VALUE_LSB)
-#define MAC_PCU_NAV_VALUE_SET(x)                 (((x) << MAC_PCU_NAV_VALUE_LSB) & MAC_PCU_NAV_VALUE_MASK)
-
-#define MAC_PCU_RTS_SUCCESS_CNT_ADDRESS          0x0000805c
-#define MAC_PCU_RTS_SUCCESS_CNT_OFFSET           0x0000005c
-#define MAC_PCU_RTS_SUCCESS_CNT_VALUE_MSB        15
-#define MAC_PCU_RTS_SUCCESS_CNT_VALUE_LSB        0
-#define MAC_PCU_RTS_SUCCESS_CNT_VALUE_MASK       0x0000ffff
-#define MAC_PCU_RTS_SUCCESS_CNT_VALUE_GET(x)     (((x) & MAC_PCU_RTS_SUCCESS_CNT_VALUE_MASK) >> MAC_PCU_RTS_SUCCESS_CNT_VALUE_LSB)
-#define MAC_PCU_RTS_SUCCESS_CNT_VALUE_SET(x)     (((x) << MAC_PCU_RTS_SUCCESS_CNT_VALUE_LSB) & MAC_PCU_RTS_SUCCESS_CNT_VALUE_MASK)
-
-#define MAC_PCU_RTS_FAIL_CNT_ADDRESS             0x00008060
-#define MAC_PCU_RTS_FAIL_CNT_OFFSET              0x00000060
-#define MAC_PCU_RTS_FAIL_CNT_VALUE_MSB           15
-#define MAC_PCU_RTS_FAIL_CNT_VALUE_LSB           0
-#define MAC_PCU_RTS_FAIL_CNT_VALUE_MASK          0x0000ffff
-#define MAC_PCU_RTS_FAIL_CNT_VALUE_GET(x)        (((x) & MAC_PCU_RTS_FAIL_CNT_VALUE_MASK) >> MAC_PCU_RTS_FAIL_CNT_VALUE_LSB)
-#define MAC_PCU_RTS_FAIL_CNT_VALUE_SET(x)        (((x) << MAC_PCU_RTS_FAIL_CNT_VALUE_LSB) & MAC_PCU_RTS_FAIL_CNT_VALUE_MASK)
-
-#define MAC_PCU_ACK_FAIL_CNT_ADDRESS             0x00008064
-#define MAC_PCU_ACK_FAIL_CNT_OFFSET              0x00000064
-#define MAC_PCU_ACK_FAIL_CNT_VALUE_MSB           15
-#define MAC_PCU_ACK_FAIL_CNT_VALUE_LSB           0
-#define MAC_PCU_ACK_FAIL_CNT_VALUE_MASK          0x0000ffff
-#define MAC_PCU_ACK_FAIL_CNT_VALUE_GET(x)        (((x) & MAC_PCU_ACK_FAIL_CNT_VALUE_MASK) >> MAC_PCU_ACK_FAIL_CNT_VALUE_LSB)
-#define MAC_PCU_ACK_FAIL_CNT_VALUE_SET(x)        (((x) << MAC_PCU_ACK_FAIL_CNT_VALUE_LSB) & MAC_PCU_ACK_FAIL_CNT_VALUE_MASK)
-
-#define MAC_PCU_FCS_FAIL_CNT_ADDRESS             0x00008068
-#define MAC_PCU_FCS_FAIL_CNT_OFFSET              0x00000068
-#define MAC_PCU_FCS_FAIL_CNT_VALUE_MSB           15
-#define MAC_PCU_FCS_FAIL_CNT_VALUE_LSB           0
-#define MAC_PCU_FCS_FAIL_CNT_VALUE_MASK          0x0000ffff
-#define MAC_PCU_FCS_FAIL_CNT_VALUE_GET(x)        (((x) & MAC_PCU_FCS_FAIL_CNT_VALUE_MASK) >> MAC_PCU_FCS_FAIL_CNT_VALUE_LSB)
-#define MAC_PCU_FCS_FAIL_CNT_VALUE_SET(x)        (((x) << MAC_PCU_FCS_FAIL_CNT_VALUE_LSB) & MAC_PCU_FCS_FAIL_CNT_VALUE_MASK)
-
-#define MAC_PCU_BEACON_CNT_ADDRESS               0x0000806c
-#define MAC_PCU_BEACON_CNT_OFFSET                0x0000006c
-#define MAC_PCU_BEACON_CNT_VALUE_MSB             15
-#define MAC_PCU_BEACON_CNT_VALUE_LSB             0
-#define MAC_PCU_BEACON_CNT_VALUE_MASK            0x0000ffff
-#define MAC_PCU_BEACON_CNT_VALUE_GET(x)          (((x) & MAC_PCU_BEACON_CNT_VALUE_MASK) >> MAC_PCU_BEACON_CNT_VALUE_LSB)
-#define MAC_PCU_BEACON_CNT_VALUE_SET(x)          (((x) << MAC_PCU_BEACON_CNT_VALUE_LSB) & MAC_PCU_BEACON_CNT_VALUE_MASK)
-
-#define MAC_PCU_XRMODE_ADDRESS                   0x00008070
-#define MAC_PCU_XRMODE_OFFSET                    0x00000070
-#define MAC_PCU_XRMODE_FRAME_HOLD_MSB            31
-#define MAC_PCU_XRMODE_FRAME_HOLD_LSB            20
-#define MAC_PCU_XRMODE_FRAME_HOLD_MASK           0xfff00000
-#define MAC_PCU_XRMODE_FRAME_HOLD_GET(x)         (((x) & MAC_PCU_XRMODE_FRAME_HOLD_MASK) >> MAC_PCU_XRMODE_FRAME_HOLD_LSB)
-#define MAC_PCU_XRMODE_FRAME_HOLD_SET(x)         (((x) << MAC_PCU_XRMODE_FRAME_HOLD_LSB) & MAC_PCU_XRMODE_FRAME_HOLD_MASK)
-#define MAC_PCU_XRMODE_WAIT_FOR_POLL_MSB         7
-#define MAC_PCU_XRMODE_WAIT_FOR_POLL_LSB         7
-#define MAC_PCU_XRMODE_WAIT_FOR_POLL_MASK        0x00000080
-#define MAC_PCU_XRMODE_WAIT_FOR_POLL_GET(x)      (((x) & MAC_PCU_XRMODE_WAIT_FOR_POLL_MASK) >> MAC_PCU_XRMODE_WAIT_FOR_POLL_LSB)
-#define MAC_PCU_XRMODE_WAIT_FOR_POLL_SET(x)      (((x) << MAC_PCU_XRMODE_WAIT_FOR_POLL_LSB) & MAC_PCU_XRMODE_WAIT_FOR_POLL_MASK)
-#define MAC_PCU_XRMODE_POLL_TYPE_MSB             5
-#define MAC_PCU_XRMODE_POLL_TYPE_LSB             0
-#define MAC_PCU_XRMODE_POLL_TYPE_MASK            0x0000003f
-#define MAC_PCU_XRMODE_POLL_TYPE_GET(x)          (((x) & MAC_PCU_XRMODE_POLL_TYPE_MASK) >> MAC_PCU_XRMODE_POLL_TYPE_LSB)
-#define MAC_PCU_XRMODE_POLL_TYPE_SET(x)          (((x) << MAC_PCU_XRMODE_POLL_TYPE_LSB) & MAC_PCU_XRMODE_POLL_TYPE_MASK)
-
-#define MAC_PCU_XRDEL_ADDRESS                    0x00008074
-#define MAC_PCU_XRDEL_OFFSET                     0x00000074
-#define MAC_PCU_XRDEL_CHIRP_DATA_DELAY_MSB       31
-#define MAC_PCU_XRDEL_CHIRP_DATA_DELAY_LSB       16
-#define MAC_PCU_XRDEL_CHIRP_DATA_DELAY_MASK      0xffff0000
-#define MAC_PCU_XRDEL_CHIRP_DATA_DELAY_GET(x)    (((x) & MAC_PCU_XRDEL_CHIRP_DATA_DELAY_MASK) >> MAC_PCU_XRDEL_CHIRP_DATA_DELAY_LSB)
-#define MAC_PCU_XRDEL_CHIRP_DATA_DELAY_SET(x)    (((x) << MAC_PCU_XRDEL_CHIRP_DATA_DELAY_LSB) & MAC_PCU_XRDEL_CHIRP_DATA_DELAY_MASK)
-#define MAC_PCU_XRDEL_SLOT_DELAY_MSB             15
-#define MAC_PCU_XRDEL_SLOT_DELAY_LSB             0
-#define MAC_PCU_XRDEL_SLOT_DELAY_MASK            0x0000ffff
-#define MAC_PCU_XRDEL_SLOT_DELAY_GET(x)          (((x) & MAC_PCU_XRDEL_SLOT_DELAY_MASK) >> MAC_PCU_XRDEL_SLOT_DELAY_LSB)
-#define MAC_PCU_XRDEL_SLOT_DELAY_SET(x)          (((x) << MAC_PCU_XRDEL_SLOT_DELAY_LSB) & MAC_PCU_XRDEL_SLOT_DELAY_MASK)
-
-#define MAC_PCU_XRTO_ADDRESS                     0x00008078
-#define MAC_PCU_XRTO_OFFSET                      0x00000078
-#define MAC_PCU_XRTO_POLL_TIMEOUT_MSB            31
-#define MAC_PCU_XRTO_POLL_TIMEOUT_LSB            16
-#define MAC_PCU_XRTO_POLL_TIMEOUT_MASK           0xffff0000
-#define MAC_PCU_XRTO_POLL_TIMEOUT_GET(x)         (((x) & MAC_PCU_XRTO_POLL_TIMEOUT_MASK) >> MAC_PCU_XRTO_POLL_TIMEOUT_LSB)
-#define MAC_PCU_XRTO_POLL_TIMEOUT_SET(x)         (((x) << MAC_PCU_XRTO_POLL_TIMEOUT_LSB) & MAC_PCU_XRTO_POLL_TIMEOUT_MASK)
-#define MAC_PCU_XRTO_CHIRP_TIMEOUT_MSB           15
-#define MAC_PCU_XRTO_CHIRP_TIMEOUT_LSB           0
-#define MAC_PCU_XRTO_CHIRP_TIMEOUT_MASK          0x0000ffff
-#define MAC_PCU_XRTO_CHIRP_TIMEOUT_GET(x)        (((x) & MAC_PCU_XRTO_CHIRP_TIMEOUT_MASK) >> MAC_PCU_XRTO_CHIRP_TIMEOUT_LSB)
-#define MAC_PCU_XRTO_CHIRP_TIMEOUT_SET(x)        (((x) << MAC_PCU_XRTO_CHIRP_TIMEOUT_LSB) & MAC_PCU_XRTO_CHIRP_TIMEOUT_MASK)
-
-#define MAC_PCU_XRCRP_ADDRESS                    0x0000807c
-#define MAC_PCU_XRCRP_OFFSET                     0x0000007c
-#define MAC_PCU_XRCRP_CHIRP_GAP_MSB              31
-#define MAC_PCU_XRCRP_CHIRP_GAP_LSB              16
-#define MAC_PCU_XRCRP_CHIRP_GAP_MASK             0xffff0000
-#define MAC_PCU_XRCRP_CHIRP_GAP_GET(x)           (((x) & MAC_PCU_XRCRP_CHIRP_GAP_MASK) >> MAC_PCU_XRCRP_CHIRP_GAP_LSB)
-#define MAC_PCU_XRCRP_CHIRP_GAP_SET(x)           (((x) << MAC_PCU_XRCRP_CHIRP_GAP_LSB) & MAC_PCU_XRCRP_CHIRP_GAP_MASK)
-#define MAC_PCU_XRCRP_SEND_CHIRP_MSB             0
-#define MAC_PCU_XRCRP_SEND_CHIRP_LSB             0
-#define MAC_PCU_XRCRP_SEND_CHIRP_MASK            0x00000001
-#define MAC_PCU_XRCRP_SEND_CHIRP_GET(x)          (((x) & MAC_PCU_XRCRP_SEND_CHIRP_MASK) >> MAC_PCU_XRCRP_SEND_CHIRP_LSB)
-#define MAC_PCU_XRCRP_SEND_CHIRP_SET(x)          (((x) << MAC_PCU_XRCRP_SEND_CHIRP_LSB) & MAC_PCU_XRCRP_SEND_CHIRP_MASK)
-
-#define MAC_PCU_XRSTMP_ADDRESS                   0x00008080
-#define MAC_PCU_XRSTMP_OFFSET                    0x00000080
-#define MAC_PCU_XRSTMP_RX_ABORT_RSSI_THRESH_MSB  23
-#define MAC_PCU_XRSTMP_RX_ABORT_RSSI_THRESH_LSB  16
-#define MAC_PCU_XRSTMP_RX_ABORT_RSSI_THRESH_MASK 0x00ff0000
-#define MAC_PCU_XRSTMP_RX_ABORT_RSSI_THRESH_GET(x) (((x) & MAC_PCU_XRSTMP_RX_ABORT_RSSI_THRESH_MASK) >> MAC_PCU_XRSTMP_RX_ABORT_RSSI_THRESH_LSB)
-#define MAC_PCU_XRSTMP_RX_ABORT_RSSI_THRESH_SET(x) (((x) << MAC_PCU_XRSTMP_RX_ABORT_RSSI_THRESH_LSB) & MAC_PCU_XRSTMP_RX_ABORT_RSSI_THRESH_MASK)
-#define MAC_PCU_XRSTMP_TX_STOMP_RSSI_THRESH_MSB  15
-#define MAC_PCU_XRSTMP_TX_STOMP_RSSI_THRESH_LSB  8
-#define MAC_PCU_XRSTMP_TX_STOMP_RSSI_THRESH_MASK 0x0000ff00
-#define MAC_PCU_XRSTMP_TX_STOMP_RSSI_THRESH_GET(x) (((x) & MAC_PCU_XRSTMP_TX_STOMP_RSSI_THRESH_MASK) >> MAC_PCU_XRSTMP_TX_STOMP_RSSI_THRESH_LSB)
-#define MAC_PCU_XRSTMP_TX_STOMP_RSSI_THRESH_SET(x) (((x) << MAC_PCU_XRSTMP_TX_STOMP_RSSI_THRESH_LSB) & MAC_PCU_XRSTMP_TX_STOMP_RSSI_THRESH_MASK)
-#define MAC_PCU_XRSTMP_RX_ABORT_DATA_MSB         5
-#define MAC_PCU_XRSTMP_RX_ABORT_DATA_LSB         5
-#define MAC_PCU_XRSTMP_RX_ABORT_DATA_MASK        0x00000020
-#define MAC_PCU_XRSTMP_RX_ABORT_DATA_GET(x)      (((x) & MAC_PCU_XRSTMP_RX_ABORT_DATA_MASK) >> MAC_PCU_XRSTMP_RX_ABORT_DATA_LSB)
-#define MAC_PCU_XRSTMP_RX_ABORT_DATA_SET(x)      (((x) << MAC_PCU_XRSTMP_RX_ABORT_DATA_LSB) & MAC_PCU_XRSTMP_RX_ABORT_DATA_MASK)
-#define MAC_PCU_XRSTMP_TX_STOMP_DATA_MSB         4
-#define MAC_PCU_XRSTMP_TX_STOMP_DATA_LSB         4
-#define MAC_PCU_XRSTMP_TX_STOMP_DATA_MASK        0x00000010
-#define MAC_PCU_XRSTMP_TX_STOMP_DATA_GET(x)      (((x) & MAC_PCU_XRSTMP_TX_STOMP_DATA_MASK) >> MAC_PCU_XRSTMP_TX_STOMP_DATA_LSB)
-#define MAC_PCU_XRSTMP_TX_STOMP_DATA_SET(x)      (((x) << MAC_PCU_XRSTMP_TX_STOMP_DATA_LSB) & MAC_PCU_XRSTMP_TX_STOMP_DATA_MASK)
-#define MAC_PCU_XRSTMP_TX_STOMP_BSSID_MSB        3
-#define MAC_PCU_XRSTMP_TX_STOMP_BSSID_LSB        3
-#define MAC_PCU_XRSTMP_TX_STOMP_BSSID_MASK       0x00000008
-#define MAC_PCU_XRSTMP_TX_STOMP_BSSID_GET(x)     (((x) & MAC_PCU_XRSTMP_TX_STOMP_BSSID_MASK) >> MAC_PCU_XRSTMP_TX_STOMP_BSSID_LSB)
-#define MAC_PCU_XRSTMP_TX_STOMP_BSSID_SET(x)     (((x) << MAC_PCU_XRSTMP_TX_STOMP_BSSID_LSB) & MAC_PCU_XRSTMP_TX_STOMP_BSSID_MASK)
-#define MAC_PCU_XRSTMP_TX_STOMP_RSSI_MSB         2
-#define MAC_PCU_XRSTMP_TX_STOMP_RSSI_LSB         2
-#define MAC_PCU_XRSTMP_TX_STOMP_RSSI_MASK        0x00000004
-#define MAC_PCU_XRSTMP_TX_STOMP_RSSI_GET(x)      (((x) & MAC_PCU_XRSTMP_TX_STOMP_RSSI_MASK) >> MAC_PCU_XRSTMP_TX_STOMP_RSSI_LSB)
-#define MAC_PCU_XRSTMP_TX_STOMP_RSSI_SET(x)      (((x) << MAC_PCU_XRSTMP_TX_STOMP_RSSI_LSB) & MAC_PCU_XRSTMP_TX_STOMP_RSSI_MASK)
-#define MAC_PCU_XRSTMP_RX_ABORT_BSSID_MSB        1
-#define MAC_PCU_XRSTMP_RX_ABORT_BSSID_LSB        1
-#define MAC_PCU_XRSTMP_RX_ABORT_BSSID_MASK       0x00000002
-#define MAC_PCU_XRSTMP_RX_ABORT_BSSID_GET(x)     (((x) & MAC_PCU_XRSTMP_RX_ABORT_BSSID_MASK) >> MAC_PCU_XRSTMP_RX_ABORT_BSSID_LSB)
-#define MAC_PCU_XRSTMP_RX_ABORT_BSSID_SET(x)     (((x) << MAC_PCU_XRSTMP_RX_ABORT_BSSID_LSB) & MAC_PCU_XRSTMP_RX_ABORT_BSSID_MASK)
-#define MAC_PCU_XRSTMP_RX_ABORT_RSSI_MSB         0
-#define MAC_PCU_XRSTMP_RX_ABORT_RSSI_LSB         0
-#define MAC_PCU_XRSTMP_RX_ABORT_RSSI_MASK        0x00000001
-#define MAC_PCU_XRSTMP_RX_ABORT_RSSI_GET(x)      (((x) & MAC_PCU_XRSTMP_RX_ABORT_RSSI_MASK) >> MAC_PCU_XRSTMP_RX_ABORT_RSSI_LSB)
-#define MAC_PCU_XRSTMP_RX_ABORT_RSSI_SET(x)      (((x) << MAC_PCU_XRSTMP_RX_ABORT_RSSI_LSB) & MAC_PCU_XRSTMP_RX_ABORT_RSSI_MASK)
-
-#define MAC_PCU_ADDR1_MASK_L32_ADDRESS           0x00008084
-#define MAC_PCU_ADDR1_MASK_L32_OFFSET            0x00000084
-#define MAC_PCU_ADDR1_MASK_L32_VALUE_MSB         31
-#define MAC_PCU_ADDR1_MASK_L32_VALUE_LSB         0
-#define MAC_PCU_ADDR1_MASK_L32_VALUE_MASK        0xffffffff
-#define MAC_PCU_ADDR1_MASK_L32_VALUE_GET(x)      (((x) & MAC_PCU_ADDR1_MASK_L32_VALUE_MASK) >> MAC_PCU_ADDR1_MASK_L32_VALUE_LSB)
-#define MAC_PCU_ADDR1_MASK_L32_VALUE_SET(x)      (((x) << MAC_PCU_ADDR1_MASK_L32_VALUE_LSB) & MAC_PCU_ADDR1_MASK_L32_VALUE_MASK)
-
-#define MAC_PCU_ADDR1_MASK_U16_ADDRESS           0x00008088
-#define MAC_PCU_ADDR1_MASK_U16_OFFSET            0x00000088
-#define MAC_PCU_ADDR1_MASK_U16_VALUE_MSB         15
-#define MAC_PCU_ADDR1_MASK_U16_VALUE_LSB         0
-#define MAC_PCU_ADDR1_MASK_U16_VALUE_MASK        0x0000ffff
-#define MAC_PCU_ADDR1_MASK_U16_VALUE_GET(x)      (((x) & MAC_PCU_ADDR1_MASK_U16_VALUE_MASK) >> MAC_PCU_ADDR1_MASK_U16_VALUE_LSB)
-#define MAC_PCU_ADDR1_MASK_U16_VALUE_SET(x)      (((x) << MAC_PCU_ADDR1_MASK_U16_VALUE_LSB) & MAC_PCU_ADDR1_MASK_U16_VALUE_MASK)
-
-#define MAC_PCU_TPC_ADDRESS                      0x0000808c
-#define MAC_PCU_TPC_OFFSET                       0x0000008c
-#define MAC_PCU_TPC_CHIRP_PWR_MSB                21
-#define MAC_PCU_TPC_CHIRP_PWR_LSB                16
-#define MAC_PCU_TPC_CHIRP_PWR_MASK               0x003f0000
-#define MAC_PCU_TPC_CHIRP_PWR_GET(x)             (((x) & MAC_PCU_TPC_CHIRP_PWR_MASK) >> MAC_PCU_TPC_CHIRP_PWR_LSB)
-#define MAC_PCU_TPC_CHIRP_PWR_SET(x)             (((x) << MAC_PCU_TPC_CHIRP_PWR_LSB) & MAC_PCU_TPC_CHIRP_PWR_MASK)
-#define MAC_PCU_TPC_CTS_PWR_MSB                  13
-#define MAC_PCU_TPC_CTS_PWR_LSB                  8
-#define MAC_PCU_TPC_CTS_PWR_MASK                 0x00003f00
-#define MAC_PCU_TPC_CTS_PWR_GET(x)               (((x) & MAC_PCU_TPC_CTS_PWR_MASK) >> MAC_PCU_TPC_CTS_PWR_LSB)
-#define MAC_PCU_TPC_CTS_PWR_SET(x)               (((x) << MAC_PCU_TPC_CTS_PWR_LSB) & MAC_PCU_TPC_CTS_PWR_MASK)
-#define MAC_PCU_TPC_ACK_PWR_MSB                  5
-#define MAC_PCU_TPC_ACK_PWR_LSB                  0
-#define MAC_PCU_TPC_ACK_PWR_MASK                 0x0000003f
-#define MAC_PCU_TPC_ACK_PWR_GET(x)               (((x) & MAC_PCU_TPC_ACK_PWR_MASK) >> MAC_PCU_TPC_ACK_PWR_LSB)
-#define MAC_PCU_TPC_ACK_PWR_SET(x)               (((x) << MAC_PCU_TPC_ACK_PWR_LSB) & MAC_PCU_TPC_ACK_PWR_MASK)
-
-#define MAC_PCU_TX_FRAME_CNT_ADDRESS             0x00008090
-#define MAC_PCU_TX_FRAME_CNT_OFFSET              0x00000090
-#define MAC_PCU_TX_FRAME_CNT_VALUE_MSB           31
-#define MAC_PCU_TX_FRAME_CNT_VALUE_LSB           0
-#define MAC_PCU_TX_FRAME_CNT_VALUE_MASK          0xffffffff
-#define MAC_PCU_TX_FRAME_CNT_VALUE_GET(x)        (((x) & MAC_PCU_TX_FRAME_CNT_VALUE_MASK) >> MAC_PCU_TX_FRAME_CNT_VALUE_LSB)
-#define MAC_PCU_TX_FRAME_CNT_VALUE_SET(x)        (((x) << MAC_PCU_TX_FRAME_CNT_VALUE_LSB) & MAC_PCU_TX_FRAME_CNT_VALUE_MASK)
-
-#define MAC_PCU_RX_FRAME_CNT_ADDRESS             0x00008094
-#define MAC_PCU_RX_FRAME_CNT_OFFSET              0x00000094
-#define MAC_PCU_RX_FRAME_CNT_VALUE_MSB           31
-#define MAC_PCU_RX_FRAME_CNT_VALUE_LSB           0
-#define MAC_PCU_RX_FRAME_CNT_VALUE_MASK          0xffffffff
-#define MAC_PCU_RX_FRAME_CNT_VALUE_GET(x)        (((x) & MAC_PCU_RX_FRAME_CNT_VALUE_MASK) >> MAC_PCU_RX_FRAME_CNT_VALUE_LSB)
-#define MAC_PCU_RX_FRAME_CNT_VALUE_SET(x)        (((x) << MAC_PCU_RX_FRAME_CNT_VALUE_LSB) & MAC_PCU_RX_FRAME_CNT_VALUE_MASK)
-
-#define MAC_PCU_RX_CLEAR_CNT_ADDRESS             0x00008098
-#define MAC_PCU_RX_CLEAR_CNT_OFFSET              0x00000098
-#define MAC_PCU_RX_CLEAR_CNT_VALUE_MSB           31
-#define MAC_PCU_RX_CLEAR_CNT_VALUE_LSB           0
-#define MAC_PCU_RX_CLEAR_CNT_VALUE_MASK          0xffffffff
-#define MAC_PCU_RX_CLEAR_CNT_VALUE_GET(x)        (((x) & MAC_PCU_RX_CLEAR_CNT_VALUE_MASK) >> MAC_PCU_RX_CLEAR_CNT_VALUE_LSB)
-#define MAC_PCU_RX_CLEAR_CNT_VALUE_SET(x)        (((x) << MAC_PCU_RX_CLEAR_CNT_VALUE_LSB) & MAC_PCU_RX_CLEAR_CNT_VALUE_MASK)
-
-#define MAC_PCU_CYCLE_CNT_ADDRESS                0x0000809c
-#define MAC_PCU_CYCLE_CNT_OFFSET                 0x0000009c
-#define MAC_PCU_CYCLE_CNT_VALUE_MSB              31
-#define MAC_PCU_CYCLE_CNT_VALUE_LSB              0
-#define MAC_PCU_CYCLE_CNT_VALUE_MASK             0xffffffff
-#define MAC_PCU_CYCLE_CNT_VALUE_GET(x)           (((x) & MAC_PCU_CYCLE_CNT_VALUE_MASK) >> MAC_PCU_CYCLE_CNT_VALUE_LSB)
-#define MAC_PCU_CYCLE_CNT_VALUE_SET(x)           (((x) << MAC_PCU_CYCLE_CNT_VALUE_LSB) & MAC_PCU_CYCLE_CNT_VALUE_MASK)
-
-#define MAC_PCU_QUIET_TIME_1_ADDRESS             0x000080a0
-#define MAC_PCU_QUIET_TIME_1_OFFSET              0x000000a0
-#define MAC_PCU_QUIET_TIME_1_ACK_CTS_ENABLE_MSB  17
-#define MAC_PCU_QUIET_TIME_1_ACK_CTS_ENABLE_LSB  17
-#define MAC_PCU_QUIET_TIME_1_ACK_CTS_ENABLE_MASK 0x00020000
-#define MAC_PCU_QUIET_TIME_1_ACK_CTS_ENABLE_GET(x) (((x) & MAC_PCU_QUIET_TIME_1_ACK_CTS_ENABLE_MASK) >> MAC_PCU_QUIET_TIME_1_ACK_CTS_ENABLE_LSB)
-#define MAC_PCU_QUIET_TIME_1_ACK_CTS_ENABLE_SET(x) (((x) << MAC_PCU_QUIET_TIME_1_ACK_CTS_ENABLE_LSB) & MAC_PCU_QUIET_TIME_1_ACK_CTS_ENABLE_MASK)
-
-#define MAC_PCU_QUIET_TIME_2_ADDRESS             0x000080a4
-#define MAC_PCU_QUIET_TIME_2_OFFSET              0x000000a4
-#define MAC_PCU_QUIET_TIME_2_DURATION_MSB        31
-#define MAC_PCU_QUIET_TIME_2_DURATION_LSB        16
-#define MAC_PCU_QUIET_TIME_2_DURATION_MASK       0xffff0000
-#define MAC_PCU_QUIET_TIME_2_DURATION_GET(x)     (((x) & MAC_PCU_QUIET_TIME_2_DURATION_MASK) >> MAC_PCU_QUIET_TIME_2_DURATION_LSB)
-#define MAC_PCU_QUIET_TIME_2_DURATION_SET(x)     (((x) << MAC_PCU_QUIET_TIME_2_DURATION_LSB) & MAC_PCU_QUIET_TIME_2_DURATION_MASK)
-
-#define MAC_PCU_QOS_NO_ACK_ADDRESS               0x000080a8
-#define MAC_PCU_QOS_NO_ACK_OFFSET                0x000000a8
-#define MAC_PCU_QOS_NO_ACK_BYTE_OFFSET_MSB       8
-#define MAC_PCU_QOS_NO_ACK_BYTE_OFFSET_LSB       7
-#define MAC_PCU_QOS_NO_ACK_BYTE_OFFSET_MASK      0x00000180
-#define MAC_PCU_QOS_NO_ACK_BYTE_OFFSET_GET(x)    (((x) & MAC_PCU_QOS_NO_ACK_BYTE_OFFSET_MASK) >> MAC_PCU_QOS_NO_ACK_BYTE_OFFSET_LSB)
-#define MAC_PCU_QOS_NO_ACK_BYTE_OFFSET_SET(x)    (((x) << MAC_PCU_QOS_NO_ACK_BYTE_OFFSET_LSB) & MAC_PCU_QOS_NO_ACK_BYTE_OFFSET_MASK)
-#define MAC_PCU_QOS_NO_ACK_BIT_OFFSET_MSB        6
-#define MAC_PCU_QOS_NO_ACK_BIT_OFFSET_LSB        4
-#define MAC_PCU_QOS_NO_ACK_BIT_OFFSET_MASK       0x00000070
-#define MAC_PCU_QOS_NO_ACK_BIT_OFFSET_GET(x)     (((x) & MAC_PCU_QOS_NO_ACK_BIT_OFFSET_MASK) >> MAC_PCU_QOS_NO_ACK_BIT_OFFSET_LSB)
-#define MAC_PCU_QOS_NO_ACK_BIT_OFFSET_SET(x)     (((x) << MAC_PCU_QOS_NO_ACK_BIT_OFFSET_LSB) & MAC_PCU_QOS_NO_ACK_BIT_OFFSET_MASK)
-#define MAC_PCU_QOS_NO_ACK_TWO_BIT_VALUES_MSB    3
-#define MAC_PCU_QOS_NO_ACK_TWO_BIT_VALUES_LSB    0
-#define MAC_PCU_QOS_NO_ACK_TWO_BIT_VALUES_MASK   0x0000000f
-#define MAC_PCU_QOS_NO_ACK_TWO_BIT_VALUES_GET(x) (((x) & MAC_PCU_QOS_NO_ACK_TWO_BIT_VALUES_MASK) >> MAC_PCU_QOS_NO_ACK_TWO_BIT_VALUES_LSB)
-#define MAC_PCU_QOS_NO_ACK_TWO_BIT_VALUES_SET(x) (((x) << MAC_PCU_QOS_NO_ACK_TWO_BIT_VALUES_LSB) & MAC_PCU_QOS_NO_ACK_TWO_BIT_VALUES_MASK)
-
-#define MAC_PCU_PHY_ERROR_MASK_ADDRESS           0x000080ac
-#define MAC_PCU_PHY_ERROR_MASK_OFFSET            0x000000ac
-#define MAC_PCU_PHY_ERROR_MASK_VALUE_MSB         31
-#define MAC_PCU_PHY_ERROR_MASK_VALUE_LSB         0
-#define MAC_PCU_PHY_ERROR_MASK_VALUE_MASK        0xffffffff
-#define MAC_PCU_PHY_ERROR_MASK_VALUE_GET(x)      (((x) & MAC_PCU_PHY_ERROR_MASK_VALUE_MASK) >> MAC_PCU_PHY_ERROR_MASK_VALUE_LSB)
-#define MAC_PCU_PHY_ERROR_MASK_VALUE_SET(x)      (((x) << MAC_PCU_PHY_ERROR_MASK_VALUE_LSB) & MAC_PCU_PHY_ERROR_MASK_VALUE_MASK)
-
-#define MAC_PCU_XRLAT_ADDRESS                    0x000080b0
-#define MAC_PCU_XRLAT_OFFSET                     0x000000b0
-#define MAC_PCU_XRLAT_VALUE_MSB                  11
-#define MAC_PCU_XRLAT_VALUE_LSB                  0
-#define MAC_PCU_XRLAT_VALUE_MASK                 0x00000fff
-#define MAC_PCU_XRLAT_VALUE_GET(x)               (((x) & MAC_PCU_XRLAT_VALUE_MASK) >> MAC_PCU_XRLAT_VALUE_LSB)
-#define MAC_PCU_XRLAT_VALUE_SET(x)               (((x) << MAC_PCU_XRLAT_VALUE_LSB) & MAC_PCU_XRLAT_VALUE_MASK)
-
-#define MAC_PCU_RXBUF_ADDRESS                    0x000080b4
-#define MAC_PCU_RXBUF_OFFSET                     0x000000b4
-#define MAC_PCU_RXBUF_REG_RD_ENABLE_MSB          11
-#define MAC_PCU_RXBUF_REG_RD_ENABLE_LSB          11
-#define MAC_PCU_RXBUF_REG_RD_ENABLE_MASK         0x00000800
-#define MAC_PCU_RXBUF_REG_RD_ENABLE_GET(x)       (((x) & MAC_PCU_RXBUF_REG_RD_ENABLE_MASK) >> MAC_PCU_RXBUF_REG_RD_ENABLE_LSB)
-#define MAC_PCU_RXBUF_REG_RD_ENABLE_SET(x)       (((x) << MAC_PCU_RXBUF_REG_RD_ENABLE_LSB) & MAC_PCU_RXBUF_REG_RD_ENABLE_MASK)
-#define MAC_PCU_RXBUF_HIGH_PRIORITY_THRSHD_MSB   10
-#define MAC_PCU_RXBUF_HIGH_PRIORITY_THRSHD_LSB   0
-#define MAC_PCU_RXBUF_HIGH_PRIORITY_THRSHD_MASK  0x000007ff
-#define MAC_PCU_RXBUF_HIGH_PRIORITY_THRSHD_GET(x) (((x) & MAC_PCU_RXBUF_HIGH_PRIORITY_THRSHD_MASK) >> MAC_PCU_RXBUF_HIGH_PRIORITY_THRSHD_LSB)
-#define MAC_PCU_RXBUF_HIGH_PRIORITY_THRSHD_SET(x) (((x) << MAC_PCU_RXBUF_HIGH_PRIORITY_THRSHD_LSB) & MAC_PCU_RXBUF_HIGH_PRIORITY_THRSHD_MASK)
-
-#define MAC_PCU_MIC_QOS_CONTROL_ADDRESS          0x000080b8
-#define MAC_PCU_MIC_QOS_CONTROL_OFFSET           0x000000b8
-#define MAC_PCU_MIC_QOS_CONTROL_ENABLE_MSB       16
-#define MAC_PCU_MIC_QOS_CONTROL_ENABLE_LSB       16
-#define MAC_PCU_MIC_QOS_CONTROL_ENABLE_MASK      0x00010000
-#define MAC_PCU_MIC_QOS_CONTROL_ENABLE_GET(x)    (((x) & MAC_PCU_MIC_QOS_CONTROL_ENABLE_MASK) >> MAC_PCU_MIC_QOS_CONTROL_ENABLE_LSB)
-#define MAC_PCU_MIC_QOS_CONTROL_ENABLE_SET(x)    (((x) << MAC_PCU_MIC_QOS_CONTROL_ENABLE_LSB) & MAC_PCU_MIC_QOS_CONTROL_ENABLE_MASK)
-#define MAC_PCU_MIC_QOS_CONTROL_VALUE_7_MSB      15
-#define MAC_PCU_MIC_QOS_CONTROL_VALUE_7_LSB      14
-#define MAC_PCU_MIC_QOS_CONTROL_VALUE_7_MASK     0x0000c000
-#define MAC_PCU_MIC_QOS_CONTROL_VALUE_7_GET(x)   (((x) & MAC_PCU_MIC_QOS_CONTROL_VALUE_7_MASK) >> MAC_PCU_MIC_QOS_CONTROL_VALUE_7_LSB)
-#define MAC_PCU_MIC_QOS_CONTROL_VALUE_7_SET(x)   (((x) << MAC_PCU_MIC_QOS_CONTROL_VALUE_7_LSB) & MAC_PCU_MIC_QOS_CONTROL_VALUE_7_MASK)
-#define MAC_PCU_MIC_QOS_CONTROL_VALUE_6_MSB      13
-#define MAC_PCU_MIC_QOS_CONTROL_VALUE_6_LSB      12
-#define MAC_PCU_MIC_QOS_CONTROL_VALUE_6_MASK     0x00003000
-#define MAC_PCU_MIC_QOS_CONTROL_VALUE_6_GET(x)   (((x) & MAC_PCU_MIC_QOS_CONTROL_VALUE_6_MASK) >> MAC_PCU_MIC_QOS_CONTROL_VALUE_6_LSB)
-#define MAC_PCU_MIC_QOS_CONTROL_VALUE_6_SET(x)   (((x) << MAC_PCU_MIC_QOS_CONTROL_VALUE_6_LSB) & MAC_PCU_MIC_QOS_CONTROL_VALUE_6_MASK)
-#define MAC_PCU_MIC_QOS_CONTROL_VALUE_5_MSB      11
-#define MAC_PCU_MIC_QOS_CONTROL_VALUE_5_LSB      10
-#define MAC_PCU_MIC_QOS_CONTROL_VALUE_5_MASK     0x00000c00
-#define MAC_PCU_MIC_QOS_CONTROL_VALUE_5_GET(x)   (((x) & MAC_PCU_MIC_QOS_CONTROL_VALUE_5_MASK) >> MAC_PCU_MIC_QOS_CONTROL_VALUE_5_LSB)
-#define MAC_PCU_MIC_QOS_CONTROL_VALUE_5_SET(x)   (((x) << MAC_PCU_MIC_QOS_CONTROL_VALUE_5_LSB) & MAC_PCU_MIC_QOS_CONTROL_VALUE_5_MASK)
-#define MAC_PCU_MIC_QOS_CONTROL_VALUE_4_MSB      9
-#define MAC_PCU_MIC_QOS_CONTROL_VALUE_4_LSB      8
-#define MAC_PCU_MIC_QOS_CONTROL_VALUE_4_MASK     0x00000300
-#define MAC_PCU_MIC_QOS_CONTROL_VALUE_4_GET(x)   (((x) & MAC_PCU_MIC_QOS_CONTROL_VALUE_4_MASK) >> MAC_PCU_MIC_QOS_CONTROL_VALUE_4_LSB)
-#define MAC_PCU_MIC_QOS_CONTROL_VALUE_4_SET(x)   (((x) << MAC_PCU_MIC_QOS_CONTROL_VALUE_4_LSB) & MAC_PCU_MIC_QOS_CONTROL_VALUE_4_MASK)
-#define MAC_PCU_MIC_QOS_CONTROL_VALUE_3_MSB      7
-#define MAC_PCU_MIC_QOS_CONTROL_VALUE_3_LSB      6
-#define MAC_PCU_MIC_QOS_CONTROL_VALUE_3_MASK     0x000000c0
-#define MAC_PCU_MIC_QOS_CONTROL_VALUE_3_GET(x)   (((x) & MAC_PCU_MIC_QOS_CONTROL_VALUE_3_MASK) >> MAC_PCU_MIC_QOS_CONTROL_VALUE_3_LSB)
-#define MAC_PCU_MIC_QOS_CONTROL_VALUE_3_SET(x)   (((x) << MAC_PCU_MIC_QOS_CONTROL_VALUE_3_LSB) & MAC_PCU_MIC_QOS_CONTROL_VALUE_3_MASK)
-#define MAC_PCU_MIC_QOS_CONTROL_VALUE_2_MSB      5
-#define MAC_PCU_MIC_QOS_CONTROL_VALUE_2_LSB      4
-#define MAC_PCU_MIC_QOS_CONTROL_VALUE_2_MASK     0x00000030
-#define MAC_PCU_MIC_QOS_CONTROL_VALUE_2_GET(x)   (((x) & MAC_PCU_MIC_QOS_CONTROL_VALUE_2_MASK) >> MAC_PCU_MIC_QOS_CONTROL_VALUE_2_LSB)
-#define MAC_PCU_MIC_QOS_CONTROL_VALUE_2_SET(x)   (((x) << MAC_PCU_MIC_QOS_CONTROL_VALUE_2_LSB) & MAC_PCU_MIC_QOS_CONTROL_VALUE_2_MASK)
-#define MAC_PCU_MIC_QOS_CONTROL_VALUE_1_MSB      3
-#define MAC_PCU_MIC_QOS_CONTROL_VALUE_1_LSB      2
-#define MAC_PCU_MIC_QOS_CONTROL_VALUE_1_MASK     0x0000000c
-#define MAC_PCU_MIC_QOS_CONTROL_VALUE_1_GET(x)   (((x) & MAC_PCU_MIC_QOS_CONTROL_VALUE_1_MASK) >> MAC_PCU_MIC_QOS_CONTROL_VALUE_1_LSB)
-#define MAC_PCU_MIC_QOS_CONTROL_VALUE_1_SET(x)   (((x) << MAC_PCU_MIC_QOS_CONTROL_VALUE_1_LSB) & MAC_PCU_MIC_QOS_CONTROL_VALUE_1_MASK)
-#define MAC_PCU_MIC_QOS_CONTROL_VALUE_0_MSB      1
-#define MAC_PCU_MIC_QOS_CONTROL_VALUE_0_LSB      0
-#define MAC_PCU_MIC_QOS_CONTROL_VALUE_0_MASK     0x00000003
-#define MAC_PCU_MIC_QOS_CONTROL_VALUE_0_GET(x)   (((x) & MAC_PCU_MIC_QOS_CONTROL_VALUE_0_MASK) >> MAC_PCU_MIC_QOS_CONTROL_VALUE_0_LSB)
-#define MAC_PCU_MIC_QOS_CONTROL_VALUE_0_SET(x)   (((x) << MAC_PCU_MIC_QOS_CONTROL_VALUE_0_LSB) & MAC_PCU_MIC_QOS_CONTROL_VALUE_0_MASK)
-
-#define MAC_PCU_MIC_QOS_SELECT_ADDRESS           0x000080bc
-#define MAC_PCU_MIC_QOS_SELECT_OFFSET            0x000000bc
-#define MAC_PCU_MIC_QOS_SELECT_VALUE_7_MSB       31
-#define MAC_PCU_MIC_QOS_SELECT_VALUE_7_LSB       28
-#define MAC_PCU_MIC_QOS_SELECT_VALUE_7_MASK      0xf0000000
-#define MAC_PCU_MIC_QOS_SELECT_VALUE_7_GET(x)    (((x) & MAC_PCU_MIC_QOS_SELECT_VALUE_7_MASK) >> MAC_PCU_MIC_QOS_SELECT_VALUE_7_LSB)
-#define MAC_PCU_MIC_QOS_SELECT_VALUE_7_SET(x)    (((x) << MAC_PCU_MIC_QOS_SELECT_VALUE_7_LSB) & MAC_PCU_MIC_QOS_SELECT_VALUE_7_MASK)
-#define MAC_PCU_MIC_QOS_SELECT_VALUE_6_MSB       27
-#define MAC_PCU_MIC_QOS_SELECT_VALUE_6_LSB       24
-#define MAC_PCU_MIC_QOS_SELECT_VALUE_6_MASK      0x0f000000
-#define MAC_PCU_MIC_QOS_SELECT_VALUE_6_GET(x)    (((x) & MAC_PCU_MIC_QOS_SELECT_VALUE_6_MASK) >> MAC_PCU_MIC_QOS_SELECT_VALUE_6_LSB)
-#define MAC_PCU_MIC_QOS_SELECT_VALUE_6_SET(x)    (((x) << MAC_PCU_MIC_QOS_SELECT_VALUE_6_LSB) & MAC_PCU_MIC_QOS_SELECT_VALUE_6_MASK)
-#define MAC_PCU_MIC_QOS_SELECT_VALUE_5_MSB       23
-#define MAC_PCU_MIC_QOS_SELECT_VALUE_5_LSB       20
-#define MAC_PCU_MIC_QOS_SELECT_VALUE_5_MASK      0x00f00000
-#define MAC_PCU_MIC_QOS_SELECT_VALUE_5_GET(x)    (((x) & MAC_PCU_MIC_QOS_SELECT_VALUE_5_MASK) >> MAC_PCU_MIC_QOS_SELECT_VALUE_5_LSB)
-#define MAC_PCU_MIC_QOS_SELECT_VALUE_5_SET(x)    (((x) << MAC_PCU_MIC_QOS_SELECT_VALUE_5_LSB) & MAC_PCU_MIC_QOS_SELECT_VALUE_5_MASK)
-#define MAC_PCU_MIC_QOS_SELECT_VALUE_4_MSB       19
-#define MAC_PCU_MIC_QOS_SELECT_VALUE_4_LSB       16
-#define MAC_PCU_MIC_QOS_SELECT_VALUE_4_MASK      0x000f0000
-#define MAC_PCU_MIC_QOS_SELECT_VALUE_4_GET(x)    (((x) & MAC_PCU_MIC_QOS_SELECT_VALUE_4_MASK) >> MAC_PCU_MIC_QOS_SELECT_VALUE_4_LSB)
-#define MAC_PCU_MIC_QOS_SELECT_VALUE_4_SET(x)    (((x) << MAC_PCU_MIC_QOS_SELECT_VALUE_4_LSB) & MAC_PCU_MIC_QOS_SELECT_VALUE_4_MASK)
-#define MAC_PCU_MIC_QOS_SELECT_VALUE_3_MSB       15
-#define MAC_PCU_MIC_QOS_SELECT_VALUE_3_LSB       12
-#define MAC_PCU_MIC_QOS_SELECT_VALUE_3_MASK      0x0000f000
-#define MAC_PCU_MIC_QOS_SELECT_VALUE_3_GET(x)    (((x) & MAC_PCU_MIC_QOS_SELECT_VALUE_3_MASK) >> MAC_PCU_MIC_QOS_SELECT_VALUE_3_LSB)
-#define MAC_PCU_MIC_QOS_SELECT_VALUE_3_SET(x)    (((x) << MAC_PCU_MIC_QOS_SELECT_VALUE_3_LSB) & MAC_PCU_MIC_QOS_SELECT_VALUE_3_MASK)
-#define MAC_PCU_MIC_QOS_SELECT_VALUE_2_MSB       11
-#define MAC_PCU_MIC_QOS_SELECT_VALUE_2_LSB       8
-#define MAC_PCU_MIC_QOS_SELECT_VALUE_2_MASK      0x00000f00
-#define MAC_PCU_MIC_QOS_SELECT_VALUE_2_GET(x)    (((x) & MAC_PCU_MIC_QOS_SELECT_VALUE_2_MASK) >> MAC_PCU_MIC_QOS_SELECT_VALUE_2_LSB)
-#define MAC_PCU_MIC_QOS_SELECT_VALUE_2_SET(x)    (((x) << MAC_PCU_MIC_QOS_SELECT_VALUE_2_LSB) & MAC_PCU_MIC_QOS_SELECT_VALUE_2_MASK)
-#define MAC_PCU_MIC_QOS_SELECT_VALUE_1_MSB       7
-#define MAC_PCU_MIC_QOS_SELECT_VALUE_1_LSB       4
-#define MAC_PCU_MIC_QOS_SELECT_VALUE_1_MASK      0x000000f0
-#define MAC_PCU_MIC_QOS_SELECT_VALUE_1_GET(x)    (((x) & MAC_PCU_MIC_QOS_SELECT_VALUE_1_MASK) >> MAC_PCU_MIC_QOS_SELECT_VALUE_1_LSB)
-#define MAC_PCU_MIC_QOS_SELECT_VALUE_1_SET(x)    (((x) << MAC_PCU_MIC_QOS_SELECT_VALUE_1_LSB) & MAC_PCU_MIC_QOS_SELECT_VALUE_1_MASK)
-#define MAC_PCU_MIC_QOS_SELECT_VALUE_0_MSB       3
-#define MAC_PCU_MIC_QOS_SELECT_VALUE_0_LSB       0
-#define MAC_PCU_MIC_QOS_SELECT_VALUE_0_MASK      0x0000000f
-#define MAC_PCU_MIC_QOS_SELECT_VALUE_0_GET(x)    (((x) & MAC_PCU_MIC_QOS_SELECT_VALUE_0_MASK) >> MAC_PCU_MIC_QOS_SELECT_VALUE_0_LSB)
-#define MAC_PCU_MIC_QOS_SELECT_VALUE_0_SET(x)    (((x) << MAC_PCU_MIC_QOS_SELECT_VALUE_0_LSB) & MAC_PCU_MIC_QOS_SELECT_VALUE_0_MASK)
-
-#define MAC_PCU_MISC_MODE_ADDRESS                0x000080c0
-#define MAC_PCU_MISC_MODE_OFFSET                 0x000000c0
-#define MAC_PCU_MISC_MODE_DEBUG_MODE_MSB         31
-#define MAC_PCU_MISC_MODE_DEBUG_MODE_LSB         30
-#define MAC_PCU_MISC_MODE_DEBUG_MODE_MASK        0xc0000000
-#define MAC_PCU_MISC_MODE_DEBUG_MODE_GET(x)      (((x) & MAC_PCU_MISC_MODE_DEBUG_MODE_MASK) >> MAC_PCU_MISC_MODE_DEBUG_MODE_LSB)
-#define MAC_PCU_MISC_MODE_DEBUG_MODE_SET(x)      (((x) << MAC_PCU_MISC_MODE_DEBUG_MODE_LSB) & MAC_PCU_MISC_MODE_DEBUG_MODE_MASK)
-#define MAC_PCU_MISC_MODE_USE_EOP_PTR_FOR_DMA_WR_MSB 29
-#define MAC_PCU_MISC_MODE_USE_EOP_PTR_FOR_DMA_WR_LSB 29
-#define MAC_PCU_MISC_MODE_USE_EOP_PTR_FOR_DMA_WR_MASK 0x20000000
-#define MAC_PCU_MISC_MODE_USE_EOP_PTR_FOR_DMA_WR_GET(x) (((x) & MAC_PCU_MISC_MODE_USE_EOP_PTR_FOR_DMA_WR_MASK) >> MAC_PCU_MISC_MODE_USE_EOP_PTR_FOR_DMA_WR_LSB)
-#define MAC_PCU_MISC_MODE_USE_EOP_PTR_FOR_DMA_WR_SET(x) (((x) << MAC_PCU_MISC_MODE_USE_EOP_PTR_FOR_DMA_WR_LSB) & MAC_PCU_MISC_MODE_USE_EOP_PTR_FOR_DMA_WR_MASK)
-#define MAC_PCU_MISC_MODE_ALWAYS_PERFORM_KEY_SEARCH_MSB 28
-#define MAC_PCU_MISC_MODE_ALWAYS_PERFORM_KEY_SEARCH_LSB 28
-#define MAC_PCU_MISC_MODE_ALWAYS_PERFORM_KEY_SEARCH_MASK 0x10000000
-#define MAC_PCU_MISC_MODE_ALWAYS_PERFORM_KEY_SEARCH_GET(x) (((x) & MAC_PCU_MISC_MODE_ALWAYS_PERFORM_KEY_SEARCH_MASK) >> MAC_PCU_MISC_MODE_ALWAYS_PERFORM_KEY_SEARCH_LSB)
-#define MAC_PCU_MISC_MODE_ALWAYS_PERFORM_KEY_SEARCH_SET(x) (((x) << MAC_PCU_MISC_MODE_ALWAYS_PERFORM_KEY_SEARCH_LSB) & MAC_PCU_MISC_MODE_ALWAYS_PERFORM_KEY_SEARCH_MASK)
-#define MAC_PCU_MISC_MODE_SEL_EVM_MSB            27
-#define MAC_PCU_MISC_MODE_SEL_EVM_LSB            27
-#define MAC_PCU_MISC_MODE_SEL_EVM_MASK           0x08000000
-#define MAC_PCU_MISC_MODE_SEL_EVM_GET(x)         (((x) & MAC_PCU_MISC_MODE_SEL_EVM_MASK) >> MAC_PCU_MISC_MODE_SEL_EVM_LSB)
-#define MAC_PCU_MISC_MODE_SEL_EVM_SET(x)         (((x) << MAC_PCU_MISC_MODE_SEL_EVM_LSB) & MAC_PCU_MISC_MODE_SEL_EVM_MASK)
-#define MAC_PCU_MISC_MODE_CLEAR_BA_VALID_MSB     26
-#define MAC_PCU_MISC_MODE_CLEAR_BA_VALID_LSB     26
-#define MAC_PCU_MISC_MODE_CLEAR_BA_VALID_MASK    0x04000000
-#define MAC_PCU_MISC_MODE_CLEAR_BA_VALID_GET(x)  (((x) & MAC_PCU_MISC_MODE_CLEAR_BA_VALID_MASK) >> MAC_PCU_MISC_MODE_CLEAR_BA_VALID_LSB)
-#define MAC_PCU_MISC_MODE_CLEAR_BA_VALID_SET(x)  (((x) << MAC_PCU_MISC_MODE_CLEAR_BA_VALID_LSB) & MAC_PCU_MISC_MODE_CLEAR_BA_VALID_MASK)
-#define MAC_PCU_MISC_MODE_CLEAR_FIRST_HCF_MSB    25
-#define MAC_PCU_MISC_MODE_CLEAR_FIRST_HCF_LSB    25
-#define MAC_PCU_MISC_MODE_CLEAR_FIRST_HCF_MASK   0x02000000
-#define MAC_PCU_MISC_MODE_CLEAR_FIRST_HCF_GET(x) (((x) & MAC_PCU_MISC_MODE_CLEAR_FIRST_HCF_MASK) >> MAC_PCU_MISC_MODE_CLEAR_FIRST_HCF_LSB)
-#define MAC_PCU_MISC_MODE_CLEAR_FIRST_HCF_SET(x) (((x) << MAC_PCU_MISC_MODE_CLEAR_FIRST_HCF_LSB) & MAC_PCU_MISC_MODE_CLEAR_FIRST_HCF_MASK)
-#define MAC_PCU_MISC_MODE_CLEAR_VMF_MSB          24
-#define MAC_PCU_MISC_MODE_CLEAR_VMF_LSB          24
-#define MAC_PCU_MISC_MODE_CLEAR_VMF_MASK         0x01000000
-#define MAC_PCU_MISC_MODE_CLEAR_VMF_GET(x)       (((x) & MAC_PCU_MISC_MODE_CLEAR_VMF_MASK) >> MAC_PCU_MISC_MODE_CLEAR_VMF_LSB)
-#define MAC_PCU_MISC_MODE_CLEAR_VMF_SET(x)       (((x) << MAC_PCU_MISC_MODE_CLEAR_VMF_LSB) & MAC_PCU_MISC_MODE_CLEAR_VMF_MASK)
-#define MAC_PCU_MISC_MODE_RX_HCF_POLL_ENABLE_MSB 23
-#define MAC_PCU_MISC_MODE_RX_HCF_POLL_ENABLE_LSB 23
-#define MAC_PCU_MISC_MODE_RX_HCF_POLL_ENABLE_MASK 0x00800000
-#define MAC_PCU_MISC_MODE_RX_HCF_POLL_ENABLE_GET(x) (((x) & MAC_PCU_MISC_MODE_RX_HCF_POLL_ENABLE_MASK) >> MAC_PCU_MISC_MODE_RX_HCF_POLL_ENABLE_LSB)
-#define MAC_PCU_MISC_MODE_RX_HCF_POLL_ENABLE_SET(x) (((x) << MAC_PCU_MISC_MODE_RX_HCF_POLL_ENABLE_LSB) & MAC_PCU_MISC_MODE_RX_HCF_POLL_ENABLE_MASK)
-#define MAC_PCU_MISC_MODE_HCF_POLL_CANCELS_NAV_MSB 22
-#define MAC_PCU_MISC_MODE_HCF_POLL_CANCELS_NAV_LSB 22
-#define MAC_PCU_MISC_MODE_HCF_POLL_CANCELS_NAV_MASK 0x00400000
-#define MAC_PCU_MISC_MODE_HCF_POLL_CANCELS_NAV_GET(x) (((x) & MAC_PCU_MISC_MODE_HCF_POLL_CANCELS_NAV_MASK) >> MAC_PCU_MISC_MODE_HCF_POLL_CANCELS_NAV_LSB)
-#define MAC_PCU_MISC_MODE_HCF_POLL_CANCELS_NAV_SET(x) (((x) << MAC_PCU_MISC_MODE_HCF_POLL_CANCELS_NAV_LSB) & MAC_PCU_MISC_MODE_HCF_POLL_CANCELS_NAV_MASK)
-#define MAC_PCU_MISC_MODE_TBTT_PROTECT_MSB       21
-#define MAC_PCU_MISC_MODE_TBTT_PROTECT_LSB       21
-#define MAC_PCU_MISC_MODE_TBTT_PROTECT_MASK      0x00200000
-#define MAC_PCU_MISC_MODE_TBTT_PROTECT_GET(x)    (((x) & MAC_PCU_MISC_MODE_TBTT_PROTECT_MASK) >> MAC_PCU_MISC_MODE_TBTT_PROTECT_LSB)
-#define MAC_PCU_MISC_MODE_TBTT_PROTECT_SET(x)    (((x) << MAC_PCU_MISC_MODE_TBTT_PROTECT_LSB) & MAC_PCU_MISC_MODE_TBTT_PROTECT_MASK)
-#define MAC_PCU_MISC_MODE_BT_ANT_PREVENTS_RX_MSB 20
-#define MAC_PCU_MISC_MODE_BT_ANT_PREVENTS_RX_LSB 20
-#define MAC_PCU_MISC_MODE_BT_ANT_PREVENTS_RX_MASK 0x00100000
-#define MAC_PCU_MISC_MODE_BT_ANT_PREVENTS_RX_GET(x) (((x) & MAC_PCU_MISC_MODE_BT_ANT_PREVENTS_RX_MASK) >> MAC_PCU_MISC_MODE_BT_ANT_PREVENTS_RX_LSB)
-#define MAC_PCU_MISC_MODE_BT_ANT_PREVENTS_RX_SET(x) (((x) << MAC_PCU_MISC_MODE_BT_ANT_PREVENTS_RX_LSB) & MAC_PCU_MISC_MODE_BT_ANT_PREVENTS_RX_MASK)
-#define MAC_PCU_MISC_MODE_FORCE_QUIET_COLLISION_MSB 18
-#define MAC_PCU_MISC_MODE_FORCE_QUIET_COLLISION_LSB 18
-#define MAC_PCU_MISC_MODE_FORCE_QUIET_COLLISION_MASK 0x00040000
-#define MAC_PCU_MISC_MODE_FORCE_QUIET_COLLISION_GET(x) (((x) & MAC_PCU_MISC_MODE_FORCE_QUIET_COLLISION_MASK) >> MAC_PCU_MISC_MODE_FORCE_QUIET_COLLISION_LSB)
-#define MAC_PCU_MISC_MODE_FORCE_QUIET_COLLISION_SET(x) (((x) << MAC_PCU_MISC_MODE_FORCE_QUIET_COLLISION_LSB) & MAC_PCU_MISC_MODE_FORCE_QUIET_COLLISION_MASK)
-#define MAC_PCU_MISC_MODE_MISS_BEACON_IN_SLEEP_MSB 14
-#define MAC_PCU_MISC_MODE_MISS_BEACON_IN_SLEEP_LSB 14
-#define MAC_PCU_MISC_MODE_MISS_BEACON_IN_SLEEP_MASK 0x00004000
-#define MAC_PCU_MISC_MODE_MISS_BEACON_IN_SLEEP_GET(x) (((x) & MAC_PCU_MISC_MODE_MISS_BEACON_IN_SLEEP_MASK) >> MAC_PCU_MISC_MODE_MISS_BEACON_IN_SLEEP_LSB)
-#define MAC_PCU_MISC_MODE_MISS_BEACON_IN_SLEEP_SET(x) (((x) << MAC_PCU_MISC_MODE_MISS_BEACON_IN_SLEEP_LSB) & MAC_PCU_MISC_MODE_MISS_BEACON_IN_SLEEP_MASK)
-#define MAC_PCU_MISC_MODE_TXOP_TBTT_LIMIT_ENABLE_MSB 12
-#define MAC_PCU_MISC_MODE_TXOP_TBTT_LIMIT_ENABLE_LSB 12
-#define MAC_PCU_MISC_MODE_TXOP_TBTT_LIMIT_ENABLE_MASK 0x00001000
-#define MAC_PCU_MISC_MODE_TXOP_TBTT_LIMIT_ENABLE_GET(x) (((x) & MAC_PCU_MISC_MODE_TXOP_TBTT_LIMIT_ENABLE_MASK) >> MAC_PCU_MISC_MODE_TXOP_TBTT_LIMIT_ENABLE_LSB)
-#define MAC_PCU_MISC_MODE_TXOP_TBTT_LIMIT_ENABLE_SET(x) (((x) << MAC_PCU_MISC_MODE_TXOP_TBTT_LIMIT_ENABLE_LSB) & MAC_PCU_MISC_MODE_TXOP_TBTT_LIMIT_ENABLE_MASK)
-#define MAC_PCU_MISC_MODE_KC_RX_ANT_UPDATE_MSB   11
-#define MAC_PCU_MISC_MODE_KC_RX_ANT_UPDATE_LSB   11
-#define MAC_PCU_MISC_MODE_KC_RX_ANT_UPDATE_MASK  0x00000800
-#define MAC_PCU_MISC_MODE_KC_RX_ANT_UPDATE_GET(x) (((x) & MAC_PCU_MISC_MODE_KC_RX_ANT_UPDATE_MASK) >> MAC_PCU_MISC_MODE_KC_RX_ANT_UPDATE_LSB)
-#define MAC_PCU_MISC_MODE_KC_RX_ANT_UPDATE_SET(x) (((x) << MAC_PCU_MISC_MODE_KC_RX_ANT_UPDATE_LSB) & MAC_PCU_MISC_MODE_KC_RX_ANT_UPDATE_MASK)
-#define MAC_PCU_MISC_MODE_DEBUG_MODE_SIFS_MSB    10
-#define MAC_PCU_MISC_MODE_DEBUG_MODE_SIFS_LSB    10
-#define MAC_PCU_MISC_MODE_DEBUG_MODE_SIFS_MASK   0x00000400
-#define MAC_PCU_MISC_MODE_DEBUG_MODE_SIFS_GET(x) (((x) & MAC_PCU_MISC_MODE_DEBUG_MODE_SIFS_MASK) >> MAC_PCU_MISC_MODE_DEBUG_MODE_SIFS_LSB)
-#define MAC_PCU_MISC_MODE_DEBUG_MODE_SIFS_SET(x) (((x) << MAC_PCU_MISC_MODE_DEBUG_MODE_SIFS_LSB) & MAC_PCU_MISC_MODE_DEBUG_MODE_SIFS_MASK)
-#define MAC_PCU_MISC_MODE_DEBUG_MODE_BA_BITMAP_MSB 9
-#define MAC_PCU_MISC_MODE_DEBUG_MODE_BA_BITMAP_LSB 9
-#define MAC_PCU_MISC_MODE_DEBUG_MODE_BA_BITMAP_MASK 0x00000200
-#define MAC_PCU_MISC_MODE_DEBUG_MODE_BA_BITMAP_GET(x) (((x) & MAC_PCU_MISC_MODE_DEBUG_MODE_BA_BITMAP_MASK) >> MAC_PCU_MISC_MODE_DEBUG_MODE_BA_BITMAP_LSB)
-#define MAC_PCU_MISC_MODE_DEBUG_MODE_BA_BITMAP_SET(x) (((x) << MAC_PCU_MISC_MODE_DEBUG_MODE_BA_BITMAP_LSB) & MAC_PCU_MISC_MODE_DEBUG_MODE_BA_BITMAP_MASK)
-#define MAC_PCU_MISC_MODE_CCK_SIFS_MODE_MSB      4
-#define MAC_PCU_MISC_MODE_CCK_SIFS_MODE_LSB      4
-#define MAC_PCU_MISC_MODE_CCK_SIFS_MODE_MASK     0x00000010
-#define MAC_PCU_MISC_MODE_CCK_SIFS_MODE_GET(x)   (((x) & MAC_PCU_MISC_MODE_CCK_SIFS_MODE_MASK) >> MAC_PCU_MISC_MODE_CCK_SIFS_MODE_LSB)
-#define MAC_PCU_MISC_MODE_CCK_SIFS_MODE_SET(x)   (((x) << MAC_PCU_MISC_MODE_CCK_SIFS_MODE_LSB) & MAC_PCU_MISC_MODE_CCK_SIFS_MODE_MASK)
-#define MAC_PCU_MISC_MODE_TX_ADD_TSF_MSB         3
-#define MAC_PCU_MISC_MODE_TX_ADD_TSF_LSB         3
-#define MAC_PCU_MISC_MODE_TX_ADD_TSF_MASK        0x00000008
-#define MAC_PCU_MISC_MODE_TX_ADD_TSF_GET(x)      (((x) & MAC_PCU_MISC_MODE_TX_ADD_TSF_MASK) >> MAC_PCU_MISC_MODE_TX_ADD_TSF_LSB)
-#define MAC_PCU_MISC_MODE_TX_ADD_TSF_SET(x)      (((x) << MAC_PCU_MISC_MODE_TX_ADD_TSF_LSB) & MAC_PCU_MISC_MODE_TX_ADD_TSF_MASK)
-#define MAC_PCU_MISC_MODE_MIC_NEW_LOCATION_ENABLE_MSB 2
-#define MAC_PCU_MISC_MODE_MIC_NEW_LOCATION_ENABLE_LSB 2
-#define MAC_PCU_MISC_MODE_MIC_NEW_LOCATION_ENABLE_MASK 0x00000004
-#define MAC_PCU_MISC_MODE_MIC_NEW_LOCATION_ENABLE_GET(x) (((x) & MAC_PCU_MISC_MODE_MIC_NEW_LOCATION_ENABLE_MASK) >> MAC_PCU_MISC_MODE_MIC_NEW_LOCATION_ENABLE_LSB)
-#define MAC_PCU_MISC_MODE_MIC_NEW_LOCATION_ENABLE_SET(x) (((x) << MAC_PCU_MISC_MODE_MIC_NEW_LOCATION_ENABLE_LSB) & MAC_PCU_MISC_MODE_MIC_NEW_LOCATION_ENABLE_MASK)
-#define MAC_PCU_MISC_MODE_DEBUG_MODE_AD_MSB      1
-#define MAC_PCU_MISC_MODE_DEBUG_MODE_AD_LSB      1
-#define MAC_PCU_MISC_MODE_DEBUG_MODE_AD_MASK     0x00000002
-#define MAC_PCU_MISC_MODE_DEBUG_MODE_AD_GET(x)   (((x) & MAC_PCU_MISC_MODE_DEBUG_MODE_AD_MASK) >> MAC_PCU_MISC_MODE_DEBUG_MODE_AD_LSB)
-#define MAC_PCU_MISC_MODE_DEBUG_MODE_AD_SET(x)   (((x) << MAC_PCU_MISC_MODE_DEBUG_MODE_AD_LSB) & MAC_PCU_MISC_MODE_DEBUG_MODE_AD_MASK)
-#define MAC_PCU_MISC_MODE_BSSID_MATCH_FORCE_MSB  0
-#define MAC_PCU_MISC_MODE_BSSID_MATCH_FORCE_LSB  0
-#define MAC_PCU_MISC_MODE_BSSID_MATCH_FORCE_MASK 0x00000001
-#define MAC_PCU_MISC_MODE_BSSID_MATCH_FORCE_GET(x) (((x) & MAC_PCU_MISC_MODE_BSSID_MATCH_FORCE_MASK) >> MAC_PCU_MISC_MODE_BSSID_MATCH_FORCE_LSB)
-#define MAC_PCU_MISC_MODE_BSSID_MATCH_FORCE_SET(x) (((x) << MAC_PCU_MISC_MODE_BSSID_MATCH_FORCE_LSB) & MAC_PCU_MISC_MODE_BSSID_MATCH_FORCE_MASK)
-
-#define MAC_PCU_FILTER_OFDM_CNT_ADDRESS          0x000080c4
-#define MAC_PCU_FILTER_OFDM_CNT_OFFSET           0x000000c4
-#define MAC_PCU_FILTER_OFDM_CNT_VALUE_MSB        23
-#define MAC_PCU_FILTER_OFDM_CNT_VALUE_LSB        0
-#define MAC_PCU_FILTER_OFDM_CNT_VALUE_MASK       0x00ffffff
-#define MAC_PCU_FILTER_OFDM_CNT_VALUE_GET(x)     (((x) & MAC_PCU_FILTER_OFDM_CNT_VALUE_MASK) >> MAC_PCU_FILTER_OFDM_CNT_VALUE_LSB)
-#define MAC_PCU_FILTER_OFDM_CNT_VALUE_SET(x)     (((x) << MAC_PCU_FILTER_OFDM_CNT_VALUE_LSB) & MAC_PCU_FILTER_OFDM_CNT_VALUE_MASK)
-
-#define MAC_PCU_FILTER_CCK_CNT_ADDRESS           0x000080c8
-#define MAC_PCU_FILTER_CCK_CNT_OFFSET            0x000000c8
-#define MAC_PCU_FILTER_CCK_CNT_VALUE_MSB         23
-#define MAC_PCU_FILTER_CCK_CNT_VALUE_LSB         0
-#define MAC_PCU_FILTER_CCK_CNT_VALUE_MASK        0x00ffffff
-#define MAC_PCU_FILTER_CCK_CNT_VALUE_GET(x)      (((x) & MAC_PCU_FILTER_CCK_CNT_VALUE_MASK) >> MAC_PCU_FILTER_CCK_CNT_VALUE_LSB)
-#define MAC_PCU_FILTER_CCK_CNT_VALUE_SET(x)      (((x) << MAC_PCU_FILTER_CCK_CNT_VALUE_LSB) & MAC_PCU_FILTER_CCK_CNT_VALUE_MASK)
-
-#define MAC_PCU_PHY_ERR_CNT_1_ADDRESS            0x000080cc
-#define MAC_PCU_PHY_ERR_CNT_1_OFFSET             0x000000cc
-#define MAC_PCU_PHY_ERR_CNT_1_VALUE_MSB          23
-#define MAC_PCU_PHY_ERR_CNT_1_VALUE_LSB          0
-#define MAC_PCU_PHY_ERR_CNT_1_VALUE_MASK         0x00ffffff
-#define MAC_PCU_PHY_ERR_CNT_1_VALUE_GET(x)       (((x) & MAC_PCU_PHY_ERR_CNT_1_VALUE_MASK) >> MAC_PCU_PHY_ERR_CNT_1_VALUE_LSB)
-#define MAC_PCU_PHY_ERR_CNT_1_VALUE_SET(x)       (((x) << MAC_PCU_PHY_ERR_CNT_1_VALUE_LSB) & MAC_PCU_PHY_ERR_CNT_1_VALUE_MASK)
-
-#define MAC_PCU_PHY_ERR_CNT_1_MASK_ADDRESS       0x000080d0
-#define MAC_PCU_PHY_ERR_CNT_1_MASK_OFFSET        0x000000d0
-#define MAC_PCU_PHY_ERR_CNT_1_MASK_VALUE_MSB     31
-#define MAC_PCU_PHY_ERR_CNT_1_MASK_VALUE_LSB     0
-#define MAC_PCU_PHY_ERR_CNT_1_MASK_VALUE_MASK    0xffffffff
-#define MAC_PCU_PHY_ERR_CNT_1_MASK_VALUE_GET(x)  (((x) & MAC_PCU_PHY_ERR_CNT_1_MASK_VALUE_MASK) >> MAC_PCU_PHY_ERR_CNT_1_MASK_VALUE_LSB)
-#define MAC_PCU_PHY_ERR_CNT_1_MASK_VALUE_SET(x)  (((x) << MAC_PCU_PHY_ERR_CNT_1_MASK_VALUE_LSB) & MAC_PCU_PHY_ERR_CNT_1_MASK_VALUE_MASK)
-
-#define MAC_PCU_PHY_ERR_CNT_2_ADDRESS            0x000080d4
-#define MAC_PCU_PHY_ERR_CNT_2_OFFSET             0x000000d4
-#define MAC_PCU_PHY_ERR_CNT_2_VALUE_MSB          23
-#define MAC_PCU_PHY_ERR_CNT_2_VALUE_LSB          0
-#define MAC_PCU_PHY_ERR_CNT_2_VALUE_MASK         0x00ffffff
-#define MAC_PCU_PHY_ERR_CNT_2_VALUE_GET(x)       (((x) & MAC_PCU_PHY_ERR_CNT_2_VALUE_MASK) >> MAC_PCU_PHY_ERR_CNT_2_VALUE_LSB)
-#define MAC_PCU_PHY_ERR_CNT_2_VALUE_SET(x)       (((x) << MAC_PCU_PHY_ERR_CNT_2_VALUE_LSB) & MAC_PCU_PHY_ERR_CNT_2_VALUE_MASK)
-
-#define MAC_PCU_PHY_ERR_CNT_2_MASK_ADDRESS       0x000080d8
-#define MAC_PCU_PHY_ERR_CNT_2_MASK_OFFSET        0x000000d8
-#define MAC_PCU_PHY_ERR_CNT_2_MASK_VALUE_MSB     31
-#define MAC_PCU_PHY_ERR_CNT_2_MASK_VALUE_LSB     0
-#define MAC_PCU_PHY_ERR_CNT_2_MASK_VALUE_MASK    0xffffffff
-#define MAC_PCU_PHY_ERR_CNT_2_MASK_VALUE_GET(x)  (((x) & MAC_PCU_PHY_ERR_CNT_2_MASK_VALUE_MASK) >> MAC_PCU_PHY_ERR_CNT_2_MASK_VALUE_LSB)
-#define MAC_PCU_PHY_ERR_CNT_2_MASK_VALUE_SET(x)  (((x) << MAC_PCU_PHY_ERR_CNT_2_MASK_VALUE_LSB) & MAC_PCU_PHY_ERR_CNT_2_MASK_VALUE_MASK)
-
-#define MAC_PCU_TSF_THRESHOLD_ADDRESS            0x000080dc
-#define MAC_PCU_TSF_THRESHOLD_OFFSET             0x000000dc
-#define MAC_PCU_TSF_THRESHOLD_VALUE_MSB          15
-#define MAC_PCU_TSF_THRESHOLD_VALUE_LSB          0
-#define MAC_PCU_TSF_THRESHOLD_VALUE_MASK         0x0000ffff
-#define MAC_PCU_TSF_THRESHOLD_VALUE_GET(x)       (((x) & MAC_PCU_TSF_THRESHOLD_VALUE_MASK) >> MAC_PCU_TSF_THRESHOLD_VALUE_LSB)
-#define MAC_PCU_TSF_THRESHOLD_VALUE_SET(x)       (((x) << MAC_PCU_TSF_THRESHOLD_VALUE_LSB) & MAC_PCU_TSF_THRESHOLD_VALUE_MASK)
-
-#define MAC_PCU_PHY_ERROR_EIFS_MASK_ADDRESS      0x000080e0
-#define MAC_PCU_PHY_ERROR_EIFS_MASK_OFFSET       0x000000e0
-#define MAC_PCU_PHY_ERROR_EIFS_MASK_VALUE_MSB    31
-#define MAC_PCU_PHY_ERROR_EIFS_MASK_VALUE_LSB    0
-#define MAC_PCU_PHY_ERROR_EIFS_MASK_VALUE_MASK   0xffffffff
-#define MAC_PCU_PHY_ERROR_EIFS_MASK_VALUE_GET(x) (((x) & MAC_PCU_PHY_ERROR_EIFS_MASK_VALUE_MASK) >> MAC_PCU_PHY_ERROR_EIFS_MASK_VALUE_LSB)
-#define MAC_PCU_PHY_ERROR_EIFS_MASK_VALUE_SET(x) (((x) << MAC_PCU_PHY_ERROR_EIFS_MASK_VALUE_LSB) & MAC_PCU_PHY_ERROR_EIFS_MASK_VALUE_MASK)
-
-#define MAC_PCU_PHY_ERR_CNT_3_ADDRESS            0x000080e4
-#define MAC_PCU_PHY_ERR_CNT_3_OFFSET             0x000000e4
-#define MAC_PCU_PHY_ERR_CNT_3_VALUE_MSB          23
-#define MAC_PCU_PHY_ERR_CNT_3_VALUE_LSB          0
-#define MAC_PCU_PHY_ERR_CNT_3_VALUE_MASK         0x00ffffff
-#define MAC_PCU_PHY_ERR_CNT_3_VALUE_GET(x)       (((x) & MAC_PCU_PHY_ERR_CNT_3_VALUE_MASK) >> MAC_PCU_PHY_ERR_CNT_3_VALUE_LSB)
-#define MAC_PCU_PHY_ERR_CNT_3_VALUE_SET(x)       (((x) << MAC_PCU_PHY_ERR_CNT_3_VALUE_LSB) & MAC_PCU_PHY_ERR_CNT_3_VALUE_MASK)
-
-#define MAC_PCU_PHY_ERR_CNT_3_MASK_ADDRESS       0x000080e8
-#define MAC_PCU_PHY_ERR_CNT_3_MASK_OFFSET        0x000000e8
-#define MAC_PCU_PHY_ERR_CNT_3_MASK_VALUE_MSB     31
-#define MAC_PCU_PHY_ERR_CNT_3_MASK_VALUE_LSB     0
-#define MAC_PCU_PHY_ERR_CNT_3_MASK_VALUE_MASK    0xffffffff
-#define MAC_PCU_PHY_ERR_CNT_3_MASK_VALUE_GET(x)  (((x) & MAC_PCU_PHY_ERR_CNT_3_MASK_VALUE_MASK) >> MAC_PCU_PHY_ERR_CNT_3_MASK_VALUE_LSB)
-#define MAC_PCU_PHY_ERR_CNT_3_MASK_VALUE_SET(x)  (((x) << MAC_PCU_PHY_ERR_CNT_3_MASK_VALUE_LSB) & MAC_PCU_PHY_ERR_CNT_3_MASK_VALUE_MASK)
-
-#define MAC_PCU_BLUETOOTH_MODE_ADDRESS           0x000080ec
-#define MAC_PCU_BLUETOOTH_MODE_OFFSET            0x000000ec
-#define MAC_PCU_BLUETOOTH_MODE_FIRST_SLOT_TIME_MSB 31
-#define MAC_PCU_BLUETOOTH_MODE_FIRST_SLOT_TIME_LSB 24
-#define MAC_PCU_BLUETOOTH_MODE_FIRST_SLOT_TIME_MASK 0xff000000
-#define MAC_PCU_BLUETOOTH_MODE_FIRST_SLOT_TIME_GET(x) (((x) & MAC_PCU_BLUETOOTH_MODE_FIRST_SLOT_TIME_MASK) >> MAC_PCU_BLUETOOTH_MODE_FIRST_SLOT_TIME_LSB)
-#define MAC_PCU_BLUETOOTH_MODE_FIRST_SLOT_TIME_SET(x) (((x) << MAC_PCU_BLUETOOTH_MODE_FIRST_SLOT_TIME_LSB) & MAC_PCU_BLUETOOTH_MODE_FIRST_SLOT_TIME_MASK)
-#define MAC_PCU_BLUETOOTH_MODE_PRIORITY_TIME_MSB 23
-#define MAC_PCU_BLUETOOTH_MODE_PRIORITY_TIME_LSB 18
-#define MAC_PCU_BLUETOOTH_MODE_PRIORITY_TIME_MASK 0x00fc0000
-#define MAC_PCU_BLUETOOTH_MODE_PRIORITY_TIME_GET(x) (((x) & MAC_PCU_BLUETOOTH_MODE_PRIORITY_TIME_MASK) >> MAC_PCU_BLUETOOTH_MODE_PRIORITY_TIME_LSB)
-#define MAC_PCU_BLUETOOTH_MODE_PRIORITY_TIME_SET(x) (((x) << MAC_PCU_BLUETOOTH_MODE_PRIORITY_TIME_LSB) & MAC_PCU_BLUETOOTH_MODE_PRIORITY_TIME_MASK)
-#define MAC_PCU_BLUETOOTH_MODE_RX_CLEAR_POLARITY_MSB 17
-#define MAC_PCU_BLUETOOTH_MODE_RX_CLEAR_POLARITY_LSB 17
-#define MAC_PCU_BLUETOOTH_MODE_RX_CLEAR_POLARITY_MASK 0x00020000
-#define MAC_PCU_BLUETOOTH_MODE_RX_CLEAR_POLARITY_GET(x) (((x) & MAC_PCU_BLUETOOTH_MODE_RX_CLEAR_POLARITY_MASK) >> MAC_PCU_BLUETOOTH_MODE_RX_CLEAR_POLARITY_LSB)
-#define MAC_PCU_BLUETOOTH_MODE_RX_CLEAR_POLARITY_SET(x) (((x) << MAC_PCU_BLUETOOTH_MODE_RX_CLEAR_POLARITY_LSB) & MAC_PCU_BLUETOOTH_MODE_RX_CLEAR_POLARITY_MASK)
-#define MAC_PCU_BLUETOOTH_MODE_QCU_THRESH_MSB    16
-#define MAC_PCU_BLUETOOTH_MODE_QCU_THRESH_LSB    13
-#define MAC_PCU_BLUETOOTH_MODE_QCU_THRESH_MASK   0x0001e000
-#define MAC_PCU_BLUETOOTH_MODE_QCU_THRESH_GET(x) (((x) & MAC_PCU_BLUETOOTH_MODE_QCU_THRESH_MASK) >> MAC_PCU_BLUETOOTH_MODE_QCU_THRESH_LSB)
-#define MAC_PCU_BLUETOOTH_MODE_QCU_THRESH_SET(x) (((x) << MAC_PCU_BLUETOOTH_MODE_QCU_THRESH_LSB) & MAC_PCU_BLUETOOTH_MODE_QCU_THRESH_MASK)
-#define MAC_PCU_BLUETOOTH_MODE_QUIET_MSB         12
-#define MAC_PCU_BLUETOOTH_MODE_QUIET_LSB         12
-#define MAC_PCU_BLUETOOTH_MODE_QUIET_MASK        0x00001000
-#define MAC_PCU_BLUETOOTH_MODE_QUIET_GET(x)      (((x) & MAC_PCU_BLUETOOTH_MODE_QUIET_MASK) >> MAC_PCU_BLUETOOTH_MODE_QUIET_LSB)
-#define MAC_PCU_BLUETOOTH_MODE_QUIET_SET(x)      (((x) << MAC_PCU_BLUETOOTH_MODE_QUIET_LSB) & MAC_PCU_BLUETOOTH_MODE_QUIET_MASK)
-#define MAC_PCU_BLUETOOTH_MODE_MODE_MSB          11
-#define MAC_PCU_BLUETOOTH_MODE_MODE_LSB          10
-#define MAC_PCU_BLUETOOTH_MODE_MODE_MASK         0x00000c00
-#define MAC_PCU_BLUETOOTH_MODE_MODE_GET(x)       (((x) & MAC_PCU_BLUETOOTH_MODE_MODE_MASK) >> MAC_PCU_BLUETOOTH_MODE_MODE_LSB)
-#define MAC_PCU_BLUETOOTH_MODE_MODE_SET(x)       (((x) << MAC_PCU_BLUETOOTH_MODE_MODE_LSB) & MAC_PCU_BLUETOOTH_MODE_MODE_MASK)
-#define MAC_PCU_BLUETOOTH_MODE_TX_FRAME_EXTEND_MSB 9
-#define MAC_PCU_BLUETOOTH_MODE_TX_FRAME_EXTEND_LSB 9
-#define MAC_PCU_BLUETOOTH_MODE_TX_FRAME_EXTEND_MASK 0x00000200
-#define MAC_PCU_BLUETOOTH_MODE_TX_FRAME_EXTEND_GET(x) (((x) & MAC_PCU_BLUETOOTH_MODE_TX_FRAME_EXTEND_MASK) >> MAC_PCU_BLUETOOTH_MODE_TX_FRAME_EXTEND_LSB)
-#define MAC_PCU_BLUETOOTH_MODE_TX_FRAME_EXTEND_SET(x) (((x) << MAC_PCU_BLUETOOTH_MODE_TX_FRAME_EXTEND_LSB) & MAC_PCU_BLUETOOTH_MODE_TX_FRAME_EXTEND_MASK)
-#define MAC_PCU_BLUETOOTH_MODE_TX_STATE_EXTEND_MSB 8
-#define MAC_PCU_BLUETOOTH_MODE_TX_STATE_EXTEND_LSB 8
-#define MAC_PCU_BLUETOOTH_MODE_TX_STATE_EXTEND_MASK 0x00000100
-#define MAC_PCU_BLUETOOTH_MODE_TX_STATE_EXTEND_GET(x) (((x) & MAC_PCU_BLUETOOTH_MODE_TX_STATE_EXTEND_MASK) >> MAC_PCU_BLUETOOTH_MODE_TX_STATE_EXTEND_LSB)
-#define MAC_PCU_BLUETOOTH_MODE_TX_STATE_EXTEND_SET(x) (((x) << MAC_PCU_BLUETOOTH_MODE_TX_STATE_EXTEND_LSB) & MAC_PCU_BLUETOOTH_MODE_TX_STATE_EXTEND_MASK)
-#define MAC_PCU_BLUETOOTH_MODE_TIME_EXTEND_MSB   7
-#define MAC_PCU_BLUETOOTH_MODE_TIME_EXTEND_LSB   0
-#define MAC_PCU_BLUETOOTH_MODE_TIME_EXTEND_MASK  0x000000ff
-#define MAC_PCU_BLUETOOTH_MODE_TIME_EXTEND_GET(x) (((x) & MAC_PCU_BLUETOOTH_MODE_TIME_EXTEND_MASK) >> MAC_PCU_BLUETOOTH_MODE_TIME_EXTEND_LSB)
-#define MAC_PCU_BLUETOOTH_MODE_TIME_EXTEND_SET(x) (((x) << MAC_PCU_BLUETOOTH_MODE_TIME_EXTEND_LSB) & MAC_PCU_BLUETOOTH_MODE_TIME_EXTEND_MASK)
-
-#define MAC_PCU_BLUETOOTH_WEIGHTS_ADDRESS        0x000080f0
-#define MAC_PCU_BLUETOOTH_WEIGHTS_OFFSET         0x000000f0
-#define MAC_PCU_BLUETOOTH_WEIGHTS_WL_WEIGHT_MSB  31
-#define MAC_PCU_BLUETOOTH_WEIGHTS_WL_WEIGHT_LSB  16
-#define MAC_PCU_BLUETOOTH_WEIGHTS_WL_WEIGHT_MASK 0xffff0000
-#define MAC_PCU_BLUETOOTH_WEIGHTS_WL_WEIGHT_GET(x) (((x) & MAC_PCU_BLUETOOTH_WEIGHTS_WL_WEIGHT_MASK) >> MAC_PCU_BLUETOOTH_WEIGHTS_WL_WEIGHT_LSB)
-#define MAC_PCU_BLUETOOTH_WEIGHTS_WL_WEIGHT_SET(x) (((x) << MAC_PCU_BLUETOOTH_WEIGHTS_WL_WEIGHT_LSB) & MAC_PCU_BLUETOOTH_WEIGHTS_WL_WEIGHT_MASK)
-#define MAC_PCU_BLUETOOTH_WEIGHTS_BT_WEIGHT_MSB  15
-#define MAC_PCU_BLUETOOTH_WEIGHTS_BT_WEIGHT_LSB  0
-#define MAC_PCU_BLUETOOTH_WEIGHTS_BT_WEIGHT_MASK 0x0000ffff
-#define MAC_PCU_BLUETOOTH_WEIGHTS_BT_WEIGHT_GET(x) (((x) & MAC_PCU_BLUETOOTH_WEIGHTS_BT_WEIGHT_MASK) >> MAC_PCU_BLUETOOTH_WEIGHTS_BT_WEIGHT_LSB)
-#define MAC_PCU_BLUETOOTH_WEIGHTS_BT_WEIGHT_SET(x) (((x) << MAC_PCU_BLUETOOTH_WEIGHTS_BT_WEIGHT_LSB) & MAC_PCU_BLUETOOTH_WEIGHTS_BT_WEIGHT_MASK)
-
-#define MAC_PCU_BLUETOOTH_MODE2_ADDRESS          0x000080f4
-#define MAC_PCU_BLUETOOTH_MODE2_OFFSET           0x000000f4
-#define MAC_PCU_BLUETOOTH_MODE2_PHY_ERR_BT_COLL_ENABLE_MSB 31
-#define MAC_PCU_BLUETOOTH_MODE2_PHY_ERR_BT_COLL_ENABLE_LSB 31
-#define MAC_PCU_BLUETOOTH_MODE2_PHY_ERR_BT_COLL_ENABLE_MASK 0x80000000
-#define MAC_PCU_BLUETOOTH_MODE2_PHY_ERR_BT_COLL_ENABLE_GET(x) (((x) & MAC_PCU_BLUETOOTH_MODE2_PHY_ERR_BT_COLL_ENABLE_MASK) >> MAC_PCU_BLUETOOTH_MODE2_PHY_ERR_BT_COLL_ENABLE_LSB)
-#define MAC_PCU_BLUETOOTH_MODE2_PHY_ERR_BT_COLL_ENABLE_SET(x) (((x) << MAC_PCU_BLUETOOTH_MODE2_PHY_ERR_BT_COLL_ENABLE_LSB) & MAC_PCU_BLUETOOTH_MODE2_PHY_ERR_BT_COLL_ENABLE_MASK)
-#define MAC_PCU_BLUETOOTH_MODE2_INTERRUPT_ENABLE_MSB 30
-#define MAC_PCU_BLUETOOTH_MODE2_INTERRUPT_ENABLE_LSB 30
-#define MAC_PCU_BLUETOOTH_MODE2_INTERRUPT_ENABLE_MASK 0x40000000
-#define MAC_PCU_BLUETOOTH_MODE2_INTERRUPT_ENABLE_GET(x) (((x) & MAC_PCU_BLUETOOTH_MODE2_INTERRUPT_ENABLE_MASK) >> MAC_PCU_BLUETOOTH_MODE2_INTERRUPT_ENABLE_LSB)
-#define MAC_PCU_BLUETOOTH_MODE2_INTERRUPT_ENABLE_SET(x) (((x) << MAC_PCU_BLUETOOTH_MODE2_INTERRUPT_ENABLE_LSB) & MAC_PCU_BLUETOOTH_MODE2_INTERRUPT_ENABLE_MASK)
-#define MAC_PCU_BLUETOOTH_MODE2_TSF_BT_PRIORITY_CTRL_MSB 29
-#define MAC_PCU_BLUETOOTH_MODE2_TSF_BT_PRIORITY_CTRL_LSB 28
-#define MAC_PCU_BLUETOOTH_MODE2_TSF_BT_PRIORITY_CTRL_MASK 0x30000000
-#define MAC_PCU_BLUETOOTH_MODE2_TSF_BT_PRIORITY_CTRL_GET(x) (((x) & MAC_PCU_BLUETOOTH_MODE2_TSF_BT_PRIORITY_CTRL_MASK) >> MAC_PCU_BLUETOOTH_MODE2_TSF_BT_PRIORITY_CTRL_LSB)
-#define MAC_PCU_BLUETOOTH_MODE2_TSF_BT_PRIORITY_CTRL_SET(x) (((x) << MAC_PCU_BLUETOOTH_MODE2_TSF_BT_PRIORITY_CTRL_LSB) & MAC_PCU_BLUETOOTH_MODE2_TSF_BT_PRIORITY_CTRL_MASK)
-#define MAC_PCU_BLUETOOTH_MODE2_TSF_BT_ACTIVE_CTRL_MSB 27
-#define MAC_PCU_BLUETOOTH_MODE2_TSF_BT_ACTIVE_CTRL_LSB 26
-#define MAC_PCU_BLUETOOTH_MODE2_TSF_BT_ACTIVE_CTRL_MASK 0x0c000000
-#define MAC_PCU_BLUETOOTH_MODE2_TSF_BT_ACTIVE_CTRL_GET(x) (((x) & MAC_PCU_BLUETOOTH_MODE2_TSF_BT_ACTIVE_CTRL_MASK) >> MAC_PCU_BLUETOOTH_MODE2_TSF_BT_ACTIVE_CTRL_LSB)
-#define MAC_PCU_BLUETOOTH_MODE2_TSF_BT_ACTIVE_CTRL_SET(x) (((x) << MAC_PCU_BLUETOOTH_MODE2_TSF_BT_ACTIVE_CTRL_LSB) & MAC_PCU_BLUETOOTH_MODE2_TSF_BT_ACTIVE_CTRL_MASK)
-#define MAC_PCU_BLUETOOTH_MODE2_RS_DISCARD_EXTEND_MSB 25
-#define MAC_PCU_BLUETOOTH_MODE2_RS_DISCARD_EXTEND_LSB 25
-#define MAC_PCU_BLUETOOTH_MODE2_RS_DISCARD_EXTEND_MASK 0x02000000
-#define MAC_PCU_BLUETOOTH_MODE2_RS_DISCARD_EXTEND_GET(x) (((x) & MAC_PCU_BLUETOOTH_MODE2_RS_DISCARD_EXTEND_MASK) >> MAC_PCU_BLUETOOTH_MODE2_RS_DISCARD_EXTEND_LSB)
-#define MAC_PCU_BLUETOOTH_MODE2_RS_DISCARD_EXTEND_SET(x) (((x) << MAC_PCU_BLUETOOTH_MODE2_RS_DISCARD_EXTEND_LSB) & MAC_PCU_BLUETOOTH_MODE2_RS_DISCARD_EXTEND_MASK)
-#define MAC_PCU_BLUETOOTH_MODE2_WL_TXRX_SEPARATE_MSB 24
-#define MAC_PCU_BLUETOOTH_MODE2_WL_TXRX_SEPARATE_LSB 24
-#define MAC_PCU_BLUETOOTH_MODE2_WL_TXRX_SEPARATE_MASK 0x01000000
-#define MAC_PCU_BLUETOOTH_MODE2_WL_TXRX_SEPARATE_GET(x) (((x) & MAC_PCU_BLUETOOTH_MODE2_WL_TXRX_SEPARATE_MASK) >> MAC_PCU_BLUETOOTH_MODE2_WL_TXRX_SEPARATE_LSB)
-#define MAC_PCU_BLUETOOTH_MODE2_WL_TXRX_SEPARATE_SET(x) (((x) << MAC_PCU_BLUETOOTH_MODE2_WL_TXRX_SEPARATE_LSB) & MAC_PCU_BLUETOOTH_MODE2_WL_TXRX_SEPARATE_MASK)
-#define MAC_PCU_BLUETOOTH_MODE2_WL_ACTIVE_MODE_MSB 23
-#define MAC_PCU_BLUETOOTH_MODE2_WL_ACTIVE_MODE_LSB 22
-#define MAC_PCU_BLUETOOTH_MODE2_WL_ACTIVE_MODE_MASK 0x00c00000
-#define MAC_PCU_BLUETOOTH_MODE2_WL_ACTIVE_MODE_GET(x) (((x) & MAC_PCU_BLUETOOTH_MODE2_WL_ACTIVE_MODE_MASK) >> MAC_PCU_BLUETOOTH_MODE2_WL_ACTIVE_MODE_LSB)
-#define MAC_PCU_BLUETOOTH_MODE2_WL_ACTIVE_MODE_SET(x) (((x) << MAC_PCU_BLUETOOTH_MODE2_WL_ACTIVE_MODE_LSB) & MAC_PCU_BLUETOOTH_MODE2_WL_ACTIVE_MODE_MASK)
-#define MAC_PCU_BLUETOOTH_MODE2_QUIET_2_WIRE_MSB 21
-#define MAC_PCU_BLUETOOTH_MODE2_QUIET_2_WIRE_LSB 21
-#define MAC_PCU_BLUETOOTH_MODE2_QUIET_2_WIRE_MASK 0x00200000
-#define MAC_PCU_BLUETOOTH_MODE2_QUIET_2_WIRE_GET(x) (((x) & MAC_PCU_BLUETOOTH_MODE2_QUIET_2_WIRE_MASK) >> MAC_PCU_BLUETOOTH_MODE2_QUIET_2_WIRE_LSB)
-#define MAC_PCU_BLUETOOTH_MODE2_QUIET_2_WIRE_SET(x) (((x) << MAC_PCU_BLUETOOTH_MODE2_QUIET_2_WIRE_LSB) & MAC_PCU_BLUETOOTH_MODE2_QUIET_2_WIRE_MASK)
-#define MAC_PCU_BLUETOOTH_MODE2_DISABLE_BT_ANT_MSB 20
-#define MAC_PCU_BLUETOOTH_MODE2_DISABLE_BT_ANT_LSB 20
-#define MAC_PCU_BLUETOOTH_MODE2_DISABLE_BT_ANT_MASK 0x00100000
-#define MAC_PCU_BLUETOOTH_MODE2_DISABLE_BT_ANT_GET(x) (((x) & MAC_PCU_BLUETOOTH_MODE2_DISABLE_BT_ANT_MASK) >> MAC_PCU_BLUETOOTH_MODE2_DISABLE_BT_ANT_LSB)
-#define MAC_PCU_BLUETOOTH_MODE2_DISABLE_BT_ANT_SET(x) (((x) << MAC_PCU_BLUETOOTH_MODE2_DISABLE_BT_ANT_LSB) & MAC_PCU_BLUETOOTH_MODE2_DISABLE_BT_ANT_MASK)
-#define MAC_PCU_BLUETOOTH_MODE2_PROTECT_BT_AFTER_WAKEUP_MSB 19
-#define MAC_PCU_BLUETOOTH_MODE2_PROTECT_BT_AFTER_WAKEUP_LSB 19
-#define MAC_PCU_BLUETOOTH_MODE2_PROTECT_BT_AFTER_WAKEUP_MASK 0x00080000
-#define MAC_PCU_BLUETOOTH_MODE2_PROTECT_BT_AFTER_WAKEUP_GET(x) (((x) & MAC_PCU_BLUETOOTH_MODE2_PROTECT_BT_AFTER_WAKEUP_MASK) >> MAC_PCU_BLUETOOTH_MODE2_PROTECT_BT_AFTER_WAKEUP_LSB)
-#define MAC_PCU_BLUETOOTH_MODE2_PROTECT_BT_AFTER_WAKEUP_SET(x) (((x) << MAC_PCU_BLUETOOTH_MODE2_PROTECT_BT_AFTER_WAKEUP_LSB) & MAC_PCU_BLUETOOTH_MODE2_PROTECT_BT_AFTER_WAKEUP_MASK)
-#define MAC_PCU_BLUETOOTH_MODE2_SLEEP_ALLOW_BT_ACCESS_MSB 17
-#define MAC_PCU_BLUETOOTH_MODE2_SLEEP_ALLOW_BT_ACCESS_LSB 17
-#define MAC_PCU_BLUETOOTH_MODE2_SLEEP_ALLOW_BT_ACCESS_MASK 0x00020000
-#define MAC_PCU_BLUETOOTH_MODE2_SLEEP_ALLOW_BT_ACCESS_GET(x) (((x) & MAC_PCU_BLUETOOTH_MODE2_SLEEP_ALLOW_BT_ACCESS_MASK) >> MAC_PCU_BLUETOOTH_MODE2_SLEEP_ALLOW_BT_ACCESS_LSB)
-#define MAC_PCU_BLUETOOTH_MODE2_SLEEP_ALLOW_BT_ACCESS_SET(x) (((x) << MAC_PCU_BLUETOOTH_MODE2_SLEEP_ALLOW_BT_ACCESS_LSB) & MAC_PCU_BLUETOOTH_MODE2_SLEEP_ALLOW_BT_ACCESS_MASK)
-#define MAC_PCU_BLUETOOTH_MODE2_HOLD_RX_CLEAR_MSB 16
-#define MAC_PCU_BLUETOOTH_MODE2_HOLD_RX_CLEAR_LSB 16
-#define MAC_PCU_BLUETOOTH_MODE2_HOLD_RX_CLEAR_MASK 0x00010000
-#define MAC_PCU_BLUETOOTH_MODE2_HOLD_RX_CLEAR_GET(x) (((x) & MAC_PCU_BLUETOOTH_MODE2_HOLD_RX_CLEAR_MASK) >> MAC_PCU_BLUETOOTH_MODE2_HOLD_RX_CLEAR_LSB)
-#define MAC_PCU_BLUETOOTH_MODE2_HOLD_RX_CLEAR_SET(x) (((x) << MAC_PCU_BLUETOOTH_MODE2_HOLD_RX_CLEAR_LSB) & MAC_PCU_BLUETOOTH_MODE2_HOLD_RX_CLEAR_MASK)
-#define MAC_PCU_BLUETOOTH_MODE2_BCN_MISS_CNT_MSB 15
-#define MAC_PCU_BLUETOOTH_MODE2_BCN_MISS_CNT_LSB 8
-#define MAC_PCU_BLUETOOTH_MODE2_BCN_MISS_CNT_MASK 0x0000ff00
-#define MAC_PCU_BLUETOOTH_MODE2_BCN_MISS_CNT_GET(x) (((x) & MAC_PCU_BLUETOOTH_MODE2_BCN_MISS_CNT_MASK) >> MAC_PCU_BLUETOOTH_MODE2_BCN_MISS_CNT_LSB)
-#define MAC_PCU_BLUETOOTH_MODE2_BCN_MISS_CNT_SET(x) (((x) << MAC_PCU_BLUETOOTH_MODE2_BCN_MISS_CNT_LSB) & MAC_PCU_BLUETOOTH_MODE2_BCN_MISS_CNT_MASK)
-#define MAC_PCU_BLUETOOTH_MODE2_BCN_MISS_THRESH_MSB 7
-#define MAC_PCU_BLUETOOTH_MODE2_BCN_MISS_THRESH_LSB 0
-#define MAC_PCU_BLUETOOTH_MODE2_BCN_MISS_THRESH_MASK 0x000000ff
-#define MAC_PCU_BLUETOOTH_MODE2_BCN_MISS_THRESH_GET(x) (((x) & MAC_PCU_BLUETOOTH_MODE2_BCN_MISS_THRESH_MASK) >> MAC_PCU_BLUETOOTH_MODE2_BCN_MISS_THRESH_LSB)
-#define MAC_PCU_BLUETOOTH_MODE2_BCN_MISS_THRESH_SET(x) (((x) << MAC_PCU_BLUETOOTH_MODE2_BCN_MISS_THRESH_LSB) & MAC_PCU_BLUETOOTH_MODE2_BCN_MISS_THRESH_MASK)
-
-#define MAC_PCU_TXSIFS_ADDRESS                   0x000080f8
-#define MAC_PCU_TXSIFS_OFFSET                    0x000000f8
-#define MAC_PCU_TXSIFS_ACK_SHIFT_MSB             14
-#define MAC_PCU_TXSIFS_ACK_SHIFT_LSB             12
-#define MAC_PCU_TXSIFS_ACK_SHIFT_MASK            0x00007000
-#define MAC_PCU_TXSIFS_ACK_SHIFT_GET(x)          (((x) & MAC_PCU_TXSIFS_ACK_SHIFT_MASK) >> MAC_PCU_TXSIFS_ACK_SHIFT_LSB)
-#define MAC_PCU_TXSIFS_ACK_SHIFT_SET(x)          (((x) << MAC_PCU_TXSIFS_ACK_SHIFT_LSB) & MAC_PCU_TXSIFS_ACK_SHIFT_MASK)
-#define MAC_PCU_TXSIFS_TX_LATENCY_MSB            11
-#define MAC_PCU_TXSIFS_TX_LATENCY_LSB            8
-#define MAC_PCU_TXSIFS_TX_LATENCY_MASK           0x00000f00
-#define MAC_PCU_TXSIFS_TX_LATENCY_GET(x)         (((x) & MAC_PCU_TXSIFS_TX_LATENCY_MASK) >> MAC_PCU_TXSIFS_TX_LATENCY_LSB)
-#define MAC_PCU_TXSIFS_TX_LATENCY_SET(x)         (((x) << MAC_PCU_TXSIFS_TX_LATENCY_LSB) & MAC_PCU_TXSIFS_TX_LATENCY_MASK)
-#define MAC_PCU_TXSIFS_SIFS_TIME_MSB             7
-#define MAC_PCU_TXSIFS_SIFS_TIME_LSB             0
-#define MAC_PCU_TXSIFS_SIFS_TIME_MASK            0x000000ff
-#define MAC_PCU_TXSIFS_SIFS_TIME_GET(x)          (((x) & MAC_PCU_TXSIFS_SIFS_TIME_MASK) >> MAC_PCU_TXSIFS_SIFS_TIME_LSB)
-#define MAC_PCU_TXSIFS_SIFS_TIME_SET(x)          (((x) << MAC_PCU_TXSIFS_SIFS_TIME_LSB) & MAC_PCU_TXSIFS_SIFS_TIME_MASK)
-
-#define MAC_PCU_TXOP_X_ADDRESS                   0x000080fc
-#define MAC_PCU_TXOP_X_OFFSET                    0x000000fc
-#define MAC_PCU_TXOP_X_VALUE_MSB                 7
-#define MAC_PCU_TXOP_X_VALUE_LSB                 0
-#define MAC_PCU_TXOP_X_VALUE_MASK                0x000000ff
-#define MAC_PCU_TXOP_X_VALUE_GET(x)              (((x) & MAC_PCU_TXOP_X_VALUE_MASK) >> MAC_PCU_TXOP_X_VALUE_LSB)
-#define MAC_PCU_TXOP_X_VALUE_SET(x)              (((x) << MAC_PCU_TXOP_X_VALUE_LSB) & MAC_PCU_TXOP_X_VALUE_MASK)
-
-#define MAC_PCU_TXOP_0_3_ADDRESS                 0x00008100
-#define MAC_PCU_TXOP_0_3_OFFSET                  0x00000100
-#define MAC_PCU_TXOP_0_3_VALUE_3_MSB             31
-#define MAC_PCU_TXOP_0_3_VALUE_3_LSB             24
-#define MAC_PCU_TXOP_0_3_VALUE_3_MASK            0xff000000
-#define MAC_PCU_TXOP_0_3_VALUE_3_GET(x)          (((x) & MAC_PCU_TXOP_0_3_VALUE_3_MASK) >> MAC_PCU_TXOP_0_3_VALUE_3_LSB)
-#define MAC_PCU_TXOP_0_3_VALUE_3_SET(x)          (((x) << MAC_PCU_TXOP_0_3_VALUE_3_LSB) & MAC_PCU_TXOP_0_3_VALUE_3_MASK)
-#define MAC_PCU_TXOP_0_3_VALUE_2_MSB             23
-#define MAC_PCU_TXOP_0_3_VALUE_2_LSB             16
-#define MAC_PCU_TXOP_0_3_VALUE_2_MASK            0x00ff0000
-#define MAC_PCU_TXOP_0_3_VALUE_2_GET(x)          (((x) & MAC_PCU_TXOP_0_3_VALUE_2_MASK) >> MAC_PCU_TXOP_0_3_VALUE_2_LSB)
-#define MAC_PCU_TXOP_0_3_VALUE_2_SET(x)          (((x) << MAC_PCU_TXOP_0_3_VALUE_2_LSB) & MAC_PCU_TXOP_0_3_VALUE_2_MASK)
-#define MAC_PCU_TXOP_0_3_VALUE_1_MSB             15
-#define MAC_PCU_TXOP_0_3_VALUE_1_LSB             8
-#define MAC_PCU_TXOP_0_3_VALUE_1_MASK            0x0000ff00
-#define MAC_PCU_TXOP_0_3_VALUE_1_GET(x)          (((x) & MAC_PCU_TXOP_0_3_VALUE_1_MASK) >> MAC_PCU_TXOP_0_3_VALUE_1_LSB)
-#define MAC_PCU_TXOP_0_3_VALUE_1_SET(x)          (((x) << MAC_PCU_TXOP_0_3_VALUE_1_LSB) & MAC_PCU_TXOP_0_3_VALUE_1_MASK)
-#define MAC_PCU_TXOP_0_3_VALUE_0_MSB             7
-#define MAC_PCU_TXOP_0_3_VALUE_0_LSB             0
-#define MAC_PCU_TXOP_0_3_VALUE_0_MASK            0x000000ff
-#define MAC_PCU_TXOP_0_3_VALUE_0_GET(x)          (((x) & MAC_PCU_TXOP_0_3_VALUE_0_MASK) >> MAC_PCU_TXOP_0_3_VALUE_0_LSB)
-#define MAC_PCU_TXOP_0_3_VALUE_0_SET(x)          (((x) << MAC_PCU_TXOP_0_3_VALUE_0_LSB) & MAC_PCU_TXOP_0_3_VALUE_0_MASK)
-
-#define MAC_PCU_TXOP_4_7_ADDRESS                 0x00008104
-#define MAC_PCU_TXOP_4_7_OFFSET                  0x00000104
-#define MAC_PCU_TXOP_4_7_VALUE_7_MSB             31
-#define MAC_PCU_TXOP_4_7_VALUE_7_LSB             24
-#define MAC_PCU_TXOP_4_7_VALUE_7_MASK            0xff000000
-#define MAC_PCU_TXOP_4_7_VALUE_7_GET(x)          (((x) & MAC_PCU_TXOP_4_7_VALUE_7_MASK) >> MAC_PCU_TXOP_4_7_VALUE_7_LSB)
-#define MAC_PCU_TXOP_4_7_VALUE_7_SET(x)          (((x) << MAC_PCU_TXOP_4_7_VALUE_7_LSB) & MAC_PCU_TXOP_4_7_VALUE_7_MASK)
-#define MAC_PCU_TXOP_4_7_VALUE_6_MSB             23
-#define MAC_PCU_TXOP_4_7_VALUE_6_LSB             16
-#define MAC_PCU_TXOP_4_7_VALUE_6_MASK            0x00ff0000
-#define MAC_PCU_TXOP_4_7_VALUE_6_GET(x)          (((x) & MAC_PCU_TXOP_4_7_VALUE_6_MASK) >> MAC_PCU_TXOP_4_7_VALUE_6_LSB)
-#define MAC_PCU_TXOP_4_7_VALUE_6_SET(x)          (((x) << MAC_PCU_TXOP_4_7_VALUE_6_LSB) & MAC_PCU_TXOP_4_7_VALUE_6_MASK)
-#define MAC_PCU_TXOP_4_7_VALUE_5_MSB             15
-#define MAC_PCU_TXOP_4_7_VALUE_5_LSB             8
-#define MAC_PCU_TXOP_4_7_VALUE_5_MASK            0x0000ff00
-#define MAC_PCU_TXOP_4_7_VALUE_5_GET(x)          (((x) & MAC_PCU_TXOP_4_7_VALUE_5_MASK) >> MAC_PCU_TXOP_4_7_VALUE_5_LSB)
-#define MAC_PCU_TXOP_4_7_VALUE_5_SET(x)          (((x) << MAC_PCU_TXOP_4_7_VALUE_5_LSB) & MAC_PCU_TXOP_4_7_VALUE_5_MASK)
-#define MAC_PCU_TXOP_4_7_VALUE_4_MSB             7
-#define MAC_PCU_TXOP_4_7_VALUE_4_LSB             0
-#define MAC_PCU_TXOP_4_7_VALUE_4_MASK            0x000000ff
-#define MAC_PCU_TXOP_4_7_VALUE_4_GET(x)          (((x) & MAC_PCU_TXOP_4_7_VALUE_4_MASK) >> MAC_PCU_TXOP_4_7_VALUE_4_LSB)
-#define MAC_PCU_TXOP_4_7_VALUE_4_SET(x)          (((x) << MAC_PCU_TXOP_4_7_VALUE_4_LSB) & MAC_PCU_TXOP_4_7_VALUE_4_MASK)
-
-#define MAC_PCU_TXOP_8_11_ADDRESS                0x00008108
-#define MAC_PCU_TXOP_8_11_OFFSET                 0x00000108
-#define MAC_PCU_TXOP_8_11_VALUE_11_MSB           31
-#define MAC_PCU_TXOP_8_11_VALUE_11_LSB           24
-#define MAC_PCU_TXOP_8_11_VALUE_11_MASK          0xff000000
-#define MAC_PCU_TXOP_8_11_VALUE_11_GET(x)        (((x) & MAC_PCU_TXOP_8_11_VALUE_11_MASK) >> MAC_PCU_TXOP_8_11_VALUE_11_LSB)
-#define MAC_PCU_TXOP_8_11_VALUE_11_SET(x)        (((x) << MAC_PCU_TXOP_8_11_VALUE_11_LSB) & MAC_PCU_TXOP_8_11_VALUE_11_MASK)
-#define MAC_PCU_TXOP_8_11_VALUE_10_MSB           23
-#define MAC_PCU_TXOP_8_11_VALUE_10_LSB           16
-#define MAC_PCU_TXOP_8_11_VALUE_10_MASK          0x00ff0000
-#define MAC_PCU_TXOP_8_11_VALUE_10_GET(x)        (((x) & MAC_PCU_TXOP_8_11_VALUE_10_MASK) >> MAC_PCU_TXOP_8_11_VALUE_10_LSB)
-#define MAC_PCU_TXOP_8_11_VALUE_10_SET(x)        (((x) << MAC_PCU_TXOP_8_11_VALUE_10_LSB) & MAC_PCU_TXOP_8_11_VALUE_10_MASK)
-#define MAC_PCU_TXOP_8_11_VALUE_9_MSB            15
-#define MAC_PCU_TXOP_8_11_VALUE_9_LSB            8
-#define MAC_PCU_TXOP_8_11_VALUE_9_MASK           0x0000ff00
-#define MAC_PCU_TXOP_8_11_VALUE_9_GET(x)         (((x) & MAC_PCU_TXOP_8_11_VALUE_9_MASK) >> MAC_PCU_TXOP_8_11_VALUE_9_LSB)
-#define MAC_PCU_TXOP_8_11_VALUE_9_SET(x)         (((x) << MAC_PCU_TXOP_8_11_VALUE_9_LSB) & MAC_PCU_TXOP_8_11_VALUE_9_MASK)
-#define MAC_PCU_TXOP_8_11_VALUE_8_MSB            7
-#define MAC_PCU_TXOP_8_11_VALUE_8_LSB            0
-#define MAC_PCU_TXOP_8_11_VALUE_8_MASK           0x000000ff
-#define MAC_PCU_TXOP_8_11_VALUE_8_GET(x)         (((x) & MAC_PCU_TXOP_8_11_VALUE_8_MASK) >> MAC_PCU_TXOP_8_11_VALUE_8_LSB)
-#define MAC_PCU_TXOP_8_11_VALUE_8_SET(x)         (((x) << MAC_PCU_TXOP_8_11_VALUE_8_LSB) & MAC_PCU_TXOP_8_11_VALUE_8_MASK)
-
-#define MAC_PCU_TXOP_12_15_ADDRESS               0x0000810c
-#define MAC_PCU_TXOP_12_15_OFFSET                0x0000010c
-#define MAC_PCU_TXOP_12_15_VALUE_15_MSB          31
-#define MAC_PCU_TXOP_12_15_VALUE_15_LSB          24
-#define MAC_PCU_TXOP_12_15_VALUE_15_MASK         0xff000000
-#define MAC_PCU_TXOP_12_15_VALUE_15_GET(x)       (((x) & MAC_PCU_TXOP_12_15_VALUE_15_MASK) >> MAC_PCU_TXOP_12_15_VALUE_15_LSB)
-#define MAC_PCU_TXOP_12_15_VALUE_15_SET(x)       (((x) << MAC_PCU_TXOP_12_15_VALUE_15_LSB) & MAC_PCU_TXOP_12_15_VALUE_15_MASK)
-#define MAC_PCU_TXOP_12_15_VALUE_14_MSB          23
-#define MAC_PCU_TXOP_12_15_VALUE_14_LSB          16
-#define MAC_PCU_TXOP_12_15_VALUE_14_MASK         0x00ff0000
-#define MAC_PCU_TXOP_12_15_VALUE_14_GET(x)       (((x) & MAC_PCU_TXOP_12_15_VALUE_14_MASK) >> MAC_PCU_TXOP_12_15_VALUE_14_LSB)
-#define MAC_PCU_TXOP_12_15_VALUE_14_SET(x)       (((x) << MAC_PCU_TXOP_12_15_VALUE_14_LSB) & MAC_PCU_TXOP_12_15_VALUE_14_MASK)
-#define MAC_PCU_TXOP_12_15_VALUE_13_MSB          15
-#define MAC_PCU_TXOP_12_15_VALUE_13_LSB          8
-#define MAC_PCU_TXOP_12_15_VALUE_13_MASK         0x0000ff00
-#define MAC_PCU_TXOP_12_15_VALUE_13_GET(x)       (((x) & MAC_PCU_TXOP_12_15_VALUE_13_MASK) >> MAC_PCU_TXOP_12_15_VALUE_13_LSB)
-#define MAC_PCU_TXOP_12_15_VALUE_13_SET(x)       (((x) << MAC_PCU_TXOP_12_15_VALUE_13_LSB) & MAC_PCU_TXOP_12_15_VALUE_13_MASK)
-#define MAC_PCU_TXOP_12_15_VALUE_12_MSB          7
-#define MAC_PCU_TXOP_12_15_VALUE_12_LSB          0
-#define MAC_PCU_TXOP_12_15_VALUE_12_MASK         0x000000ff
-#define MAC_PCU_TXOP_12_15_VALUE_12_GET(x)       (((x) & MAC_PCU_TXOP_12_15_VALUE_12_MASK) >> MAC_PCU_TXOP_12_15_VALUE_12_LSB)
-#define MAC_PCU_TXOP_12_15_VALUE_12_SET(x)       (((x) << MAC_PCU_TXOP_12_15_VALUE_12_LSB) & MAC_PCU_TXOP_12_15_VALUE_12_MASK)
-
-#define MAC_PCU_LOGIC_ANALYZER_ADDRESS           0x00008110
-#define MAC_PCU_LOGIC_ANALYZER_OFFSET            0x00000110
-#define MAC_PCU_LOGIC_ANALYZER_DIAG_MODE_MSB     31
-#define MAC_PCU_LOGIC_ANALYZER_DIAG_MODE_LSB     18
-#define MAC_PCU_LOGIC_ANALYZER_DIAG_MODE_MASK    0xfffc0000
-#define MAC_PCU_LOGIC_ANALYZER_DIAG_MODE_GET(x)  (((x) & MAC_PCU_LOGIC_ANALYZER_DIAG_MODE_MASK) >> MAC_PCU_LOGIC_ANALYZER_DIAG_MODE_LSB)
-#define MAC_PCU_LOGIC_ANALYZER_DIAG_MODE_SET(x)  (((x) << MAC_PCU_LOGIC_ANALYZER_DIAG_MODE_LSB) & MAC_PCU_LOGIC_ANALYZER_DIAG_MODE_MASK)
-#define MAC_PCU_LOGIC_ANALYZER_INT_ADDR_MSB      17
-#define MAC_PCU_LOGIC_ANALYZER_INT_ADDR_LSB      8
-#define MAC_PCU_LOGIC_ANALYZER_INT_ADDR_MASK     0x0003ff00
-#define MAC_PCU_LOGIC_ANALYZER_INT_ADDR_GET(x)   (((x) & MAC_PCU_LOGIC_ANALYZER_INT_ADDR_MASK) >> MAC_PCU_LOGIC_ANALYZER_INT_ADDR_LSB)
-#define MAC_PCU_LOGIC_ANALYZER_INT_ADDR_SET(x)   (((x) << MAC_PCU_LOGIC_ANALYZER_INT_ADDR_LSB) & MAC_PCU_LOGIC_ANALYZER_INT_ADDR_MASK)
-#define MAC_PCU_LOGIC_ANALYZER_QCU_SEL_MSB       7
-#define MAC_PCU_LOGIC_ANALYZER_QCU_SEL_LSB       4
-#define MAC_PCU_LOGIC_ANALYZER_QCU_SEL_MASK      0x000000f0
-#define MAC_PCU_LOGIC_ANALYZER_QCU_SEL_GET(x)    (((x) & MAC_PCU_LOGIC_ANALYZER_QCU_SEL_MASK) >> MAC_PCU_LOGIC_ANALYZER_QCU_SEL_LSB)
-#define MAC_PCU_LOGIC_ANALYZER_QCU_SEL_SET(x)    (((x) << MAC_PCU_LOGIC_ANALYZER_QCU_SEL_LSB) & MAC_PCU_LOGIC_ANALYZER_QCU_SEL_MASK)
-#define MAC_PCU_LOGIC_ANALYZER_ENABLE_MSB        3
-#define MAC_PCU_LOGIC_ANALYZER_ENABLE_LSB        3
-#define MAC_PCU_LOGIC_ANALYZER_ENABLE_MASK       0x00000008
-#define MAC_PCU_LOGIC_ANALYZER_ENABLE_GET(x)     (((x) & MAC_PCU_LOGIC_ANALYZER_ENABLE_MASK) >> MAC_PCU_LOGIC_ANALYZER_ENABLE_LSB)
-#define MAC_PCU_LOGIC_ANALYZER_ENABLE_SET(x)     (((x) << MAC_PCU_LOGIC_ANALYZER_ENABLE_LSB) & MAC_PCU_LOGIC_ANALYZER_ENABLE_MASK)
-#define MAC_PCU_LOGIC_ANALYZER_STATE_MSB         2
-#define MAC_PCU_LOGIC_ANALYZER_STATE_LSB         2
-#define MAC_PCU_LOGIC_ANALYZER_STATE_MASK        0x00000004
-#define MAC_PCU_LOGIC_ANALYZER_STATE_GET(x)      (((x) & MAC_PCU_LOGIC_ANALYZER_STATE_MASK) >> MAC_PCU_LOGIC_ANALYZER_STATE_LSB)
-#define MAC_PCU_LOGIC_ANALYZER_STATE_SET(x)      (((x) << MAC_PCU_LOGIC_ANALYZER_STATE_LSB) & MAC_PCU_LOGIC_ANALYZER_STATE_MASK)
-#define MAC_PCU_LOGIC_ANALYZER_CLEAR_MSB         1
-#define MAC_PCU_LOGIC_ANALYZER_CLEAR_LSB         1
-#define MAC_PCU_LOGIC_ANALYZER_CLEAR_MASK        0x00000002
-#define MAC_PCU_LOGIC_ANALYZER_CLEAR_GET(x)      (((x) & MAC_PCU_LOGIC_ANALYZER_CLEAR_MASK) >> MAC_PCU_LOGIC_ANALYZER_CLEAR_LSB)
-#define MAC_PCU_LOGIC_ANALYZER_CLEAR_SET(x)      (((x) << MAC_PCU_LOGIC_ANALYZER_CLEAR_LSB) & MAC_PCU_LOGIC_ANALYZER_CLEAR_MASK)
-#define MAC_PCU_LOGIC_ANALYZER_HOLD_MSB          0
-#define MAC_PCU_LOGIC_ANALYZER_HOLD_LSB          0
-#define MAC_PCU_LOGIC_ANALYZER_HOLD_MASK         0x00000001
-#define MAC_PCU_LOGIC_ANALYZER_HOLD_GET(x)       (((x) & MAC_PCU_LOGIC_ANALYZER_HOLD_MASK) >> MAC_PCU_LOGIC_ANALYZER_HOLD_LSB)
-#define MAC_PCU_LOGIC_ANALYZER_HOLD_SET(x)       (((x) << MAC_PCU_LOGIC_ANALYZER_HOLD_LSB) & MAC_PCU_LOGIC_ANALYZER_HOLD_MASK)
-
-#define MAC_PCU_LOGIC_ANALYZER_32L_ADDRESS       0x00008114
-#define MAC_PCU_LOGIC_ANALYZER_32L_OFFSET        0x00000114
-#define MAC_PCU_LOGIC_ANALYZER_32L_MASK_MSB      31
-#define MAC_PCU_LOGIC_ANALYZER_32L_MASK_LSB      0
-#define MAC_PCU_LOGIC_ANALYZER_32L_MASK_MASK     0xffffffff
-#define MAC_PCU_LOGIC_ANALYZER_32L_MASK_GET(x)   (((x) & MAC_PCU_LOGIC_ANALYZER_32L_MASK_MASK) >> MAC_PCU_LOGIC_ANALYZER_32L_MASK_LSB)
-#define MAC_PCU_LOGIC_ANALYZER_32L_MASK_SET(x)   (((x) << MAC_PCU_LOGIC_ANALYZER_32L_MASK_LSB) & MAC_PCU_LOGIC_ANALYZER_32L_MASK_MASK)
-
-#define MAC_PCU_LOGIC_ANALYZER_16U_ADDRESS       0x00008118
-#define MAC_PCU_LOGIC_ANALYZER_16U_OFFSET        0x00000118
-#define MAC_PCU_LOGIC_ANALYZER_16U_MASK_MSB      15
-#define MAC_PCU_LOGIC_ANALYZER_16U_MASK_LSB      0
-#define MAC_PCU_LOGIC_ANALYZER_16U_MASK_MASK     0x0000ffff
-#define MAC_PCU_LOGIC_ANALYZER_16U_MASK_GET(x)   (((x) & MAC_PCU_LOGIC_ANALYZER_16U_MASK_MASK) >> MAC_PCU_LOGIC_ANALYZER_16U_MASK_LSB)
-#define MAC_PCU_LOGIC_ANALYZER_16U_MASK_SET(x)   (((x) << MAC_PCU_LOGIC_ANALYZER_16U_MASK_LSB) & MAC_PCU_LOGIC_ANALYZER_16U_MASK_MASK)
-
-#define MAC_PCU_PHY_ERR_CNT_MASK_CONT_ADDRESS    0x0000811c
-#define MAC_PCU_PHY_ERR_CNT_MASK_CONT_OFFSET     0x0000011c
-#define MAC_PCU_PHY_ERR_CNT_MASK_CONT_MASK3_MSB  23
-#define MAC_PCU_PHY_ERR_CNT_MASK_CONT_MASK3_LSB  16
-#define MAC_PCU_PHY_ERR_CNT_MASK_CONT_MASK3_MASK 0x00ff0000
-#define MAC_PCU_PHY_ERR_CNT_MASK_CONT_MASK3_GET(x) (((x) & MAC_PCU_PHY_ERR_CNT_MASK_CONT_MASK3_MASK) >> MAC_PCU_PHY_ERR_CNT_MASK_CONT_MASK3_LSB)
-#define MAC_PCU_PHY_ERR_CNT_MASK_CONT_MASK3_SET(x) (((x) << MAC_PCU_PHY_ERR_CNT_MASK_CONT_MASK3_LSB) & MAC_PCU_PHY_ERR_CNT_MASK_CONT_MASK3_MASK)
-#define MAC_PCU_PHY_ERR_CNT_MASK_CONT_MASK2_MSB  15
-#define MAC_PCU_PHY_ERR_CNT_MASK_CONT_MASK2_LSB  8
-#define MAC_PCU_PHY_ERR_CNT_MASK_CONT_MASK2_MASK 0x0000ff00
-#define MAC_PCU_PHY_ERR_CNT_MASK_CONT_MASK2_GET(x) (((x) & MAC_PCU_PHY_ERR_CNT_MASK_CONT_MASK2_MASK) >> MAC_PCU_PHY_ERR_CNT_MASK_CONT_MASK2_LSB)
-#define MAC_PCU_PHY_ERR_CNT_MASK_CONT_MASK2_SET(x) (((x) << MAC_PCU_PHY_ERR_CNT_MASK_CONT_MASK2_LSB) & MAC_PCU_PHY_ERR_CNT_MASK_CONT_MASK2_MASK)
-#define MAC_PCU_PHY_ERR_CNT_MASK_CONT_MASK1_MSB  7
-#define MAC_PCU_PHY_ERR_CNT_MASK_CONT_MASK1_LSB  0
-#define MAC_PCU_PHY_ERR_CNT_MASK_CONT_MASK1_MASK 0x000000ff
-#define MAC_PCU_PHY_ERR_CNT_MASK_CONT_MASK1_GET(x) (((x) & MAC_PCU_PHY_ERR_CNT_MASK_CONT_MASK1_MASK) >> MAC_PCU_PHY_ERR_CNT_MASK_CONT_MASK1_LSB)
-#define MAC_PCU_PHY_ERR_CNT_MASK_CONT_MASK1_SET(x) (((x) << MAC_PCU_PHY_ERR_CNT_MASK_CONT_MASK1_LSB) & MAC_PCU_PHY_ERR_CNT_MASK_CONT_MASK1_MASK)
-
-#define MAC_PCU_AZIMUTH_MODE_ADDRESS             0x00008120
-#define MAC_PCU_AZIMUTH_MODE_OFFSET              0x00000120
-#define MAC_PCU_AZIMUTH_MODE_BA_USES_AD1_MSB     7
-#define MAC_PCU_AZIMUTH_MODE_BA_USES_AD1_LSB     7
-#define MAC_PCU_AZIMUTH_MODE_BA_USES_AD1_MASK    0x00000080
-#define MAC_PCU_AZIMUTH_MODE_BA_USES_AD1_GET(x)  (((x) & MAC_PCU_AZIMUTH_MODE_BA_USES_AD1_MASK) >> MAC_PCU_AZIMUTH_MODE_BA_USES_AD1_LSB)
-#define MAC_PCU_AZIMUTH_MODE_BA_USES_AD1_SET(x)  (((x) << MAC_PCU_AZIMUTH_MODE_BA_USES_AD1_LSB) & MAC_PCU_AZIMUTH_MODE_BA_USES_AD1_MASK)
-#define MAC_PCU_AZIMUTH_MODE_ACK_CTS_MATCH_TX_AD2_MSB 6
-#define MAC_PCU_AZIMUTH_MODE_ACK_CTS_MATCH_TX_AD2_LSB 6
-#define MAC_PCU_AZIMUTH_MODE_ACK_CTS_MATCH_TX_AD2_MASK 0x00000040
-#define MAC_PCU_AZIMUTH_MODE_ACK_CTS_MATCH_TX_AD2_GET(x) (((x) & MAC_PCU_AZIMUTH_MODE_ACK_CTS_MATCH_TX_AD2_MASK) >> MAC_PCU_AZIMUTH_MODE_ACK_CTS_MATCH_TX_AD2_LSB)
-#define MAC_PCU_AZIMUTH_MODE_ACK_CTS_MATCH_TX_AD2_SET(x) (((x) << MAC_PCU_AZIMUTH_MODE_ACK_CTS_MATCH_TX_AD2_LSB) & MAC_PCU_AZIMUTH_MODE_ACK_CTS_MATCH_TX_AD2_MASK)
-#define MAC_PCU_AZIMUTH_MODE_TX_DESC_EN_MSB      5
-#define MAC_PCU_AZIMUTH_MODE_TX_DESC_EN_LSB      5
-#define MAC_PCU_AZIMUTH_MODE_TX_DESC_EN_MASK     0x00000020
-#define MAC_PCU_AZIMUTH_MODE_TX_DESC_EN_GET(x)   (((x) & MAC_PCU_AZIMUTH_MODE_TX_DESC_EN_MASK) >> MAC_PCU_AZIMUTH_MODE_TX_DESC_EN_LSB)
-#define MAC_PCU_AZIMUTH_MODE_TX_DESC_EN_SET(x)   (((x) << MAC_PCU_AZIMUTH_MODE_TX_DESC_EN_LSB) & MAC_PCU_AZIMUTH_MODE_TX_DESC_EN_MASK)
-#define MAC_PCU_AZIMUTH_MODE_CLK_EN_MSB          4
-#define MAC_PCU_AZIMUTH_MODE_CLK_EN_LSB          4
-#define MAC_PCU_AZIMUTH_MODE_CLK_EN_MASK         0x00000010
-#define MAC_PCU_AZIMUTH_MODE_CLK_EN_GET(x)       (((x) & MAC_PCU_AZIMUTH_MODE_CLK_EN_MASK) >> MAC_PCU_AZIMUTH_MODE_CLK_EN_LSB)
-#define MAC_PCU_AZIMUTH_MODE_CLK_EN_SET(x)       (((x) << MAC_PCU_AZIMUTH_MODE_CLK_EN_LSB) & MAC_PCU_AZIMUTH_MODE_CLK_EN_MASK)
-#define MAC_PCU_AZIMUTH_MODE_RX_TSF_STATUS_SEL_MSB 3
-#define MAC_PCU_AZIMUTH_MODE_RX_TSF_STATUS_SEL_LSB 3
-#define MAC_PCU_AZIMUTH_MODE_RX_TSF_STATUS_SEL_MASK 0x00000008
-#define MAC_PCU_AZIMUTH_MODE_RX_TSF_STATUS_SEL_GET(x) (((x) & MAC_PCU_AZIMUTH_MODE_RX_TSF_STATUS_SEL_MASK) >> MAC_PCU_AZIMUTH_MODE_RX_TSF_STATUS_SEL_LSB)
-#define MAC_PCU_AZIMUTH_MODE_RX_TSF_STATUS_SEL_SET(x) (((x) << MAC_PCU_AZIMUTH_MODE_RX_TSF_STATUS_SEL_LSB) & MAC_PCU_AZIMUTH_MODE_RX_TSF_STATUS_SEL_MASK)
-#define MAC_PCU_AZIMUTH_MODE_TX_TSF_STATUS_SEL_MSB 2
-#define MAC_PCU_AZIMUTH_MODE_TX_TSF_STATUS_SEL_LSB 2
-#define MAC_PCU_AZIMUTH_MODE_TX_TSF_STATUS_SEL_MASK 0x00000004
-#define MAC_PCU_AZIMUTH_MODE_TX_TSF_STATUS_SEL_GET(x) (((x) & MAC_PCU_AZIMUTH_MODE_TX_TSF_STATUS_SEL_MASK) >> MAC_PCU_AZIMUTH_MODE_TX_TSF_STATUS_SEL_LSB)
-#define MAC_PCU_AZIMUTH_MODE_TX_TSF_STATUS_SEL_SET(x) (((x) << MAC_PCU_AZIMUTH_MODE_TX_TSF_STATUS_SEL_LSB) & MAC_PCU_AZIMUTH_MODE_TX_TSF_STATUS_SEL_MASK)
-#define MAC_PCU_AZIMUTH_MODE_KEY_SEARCH_AD1_MSB  1
-#define MAC_PCU_AZIMUTH_MODE_KEY_SEARCH_AD1_LSB  1
-#define MAC_PCU_AZIMUTH_MODE_KEY_SEARCH_AD1_MASK 0x00000002
-#define MAC_PCU_AZIMUTH_MODE_KEY_SEARCH_AD1_GET(x) (((x) & MAC_PCU_AZIMUTH_MODE_KEY_SEARCH_AD1_MASK) >> MAC_PCU_AZIMUTH_MODE_KEY_SEARCH_AD1_LSB)
-#define MAC_PCU_AZIMUTH_MODE_KEY_SEARCH_AD1_SET(x) (((x) << MAC_PCU_AZIMUTH_MODE_KEY_SEARCH_AD1_LSB) & MAC_PCU_AZIMUTH_MODE_KEY_SEARCH_AD1_MASK)
-#define MAC_PCU_AZIMUTH_MODE_DISABLE_TSF_UPDATE_MSB 0
-#define MAC_PCU_AZIMUTH_MODE_DISABLE_TSF_UPDATE_LSB 0
-#define MAC_PCU_AZIMUTH_MODE_DISABLE_TSF_UPDATE_MASK 0x00000001
-#define MAC_PCU_AZIMUTH_MODE_DISABLE_TSF_UPDATE_GET(x) (((x) & MAC_PCU_AZIMUTH_MODE_DISABLE_TSF_UPDATE_MASK) >> MAC_PCU_AZIMUTH_MODE_DISABLE_TSF_UPDATE_LSB)
-#define MAC_PCU_AZIMUTH_MODE_DISABLE_TSF_UPDATE_SET(x) (((x) << MAC_PCU_AZIMUTH_MODE_DISABLE_TSF_UPDATE_LSB) & MAC_PCU_AZIMUTH_MODE_DISABLE_TSF_UPDATE_MASK)
-
-#define MAC_PCU_20_40_MODE_ADDRESS               0x00008124
-#define MAC_PCU_20_40_MODE_OFFSET                0x00000124
-#define MAC_PCU_20_40_MODE_PIFS_CYCLES_MSB       15
-#define MAC_PCU_20_40_MODE_PIFS_CYCLES_LSB       4
-#define MAC_PCU_20_40_MODE_PIFS_CYCLES_MASK      0x0000fff0
-#define MAC_PCU_20_40_MODE_PIFS_CYCLES_GET(x)    (((x) & MAC_PCU_20_40_MODE_PIFS_CYCLES_MASK) >> MAC_PCU_20_40_MODE_PIFS_CYCLES_LSB)
-#define MAC_PCU_20_40_MODE_PIFS_CYCLES_SET(x)    (((x) << MAC_PCU_20_40_MODE_PIFS_CYCLES_LSB) & MAC_PCU_20_40_MODE_PIFS_CYCLES_MASK)
-#define MAC_PCU_20_40_MODE_SWAMPED_FORCES_RX_CLEAR_CTL_IDLE_MSB 3
-#define MAC_PCU_20_40_MODE_SWAMPED_FORCES_RX_CLEAR_CTL_IDLE_LSB 3
-#define MAC_PCU_20_40_MODE_SWAMPED_FORCES_RX_CLEAR_CTL_IDLE_MASK 0x00000008
-#define MAC_PCU_20_40_MODE_SWAMPED_FORCES_RX_CLEAR_CTL_IDLE_GET(x) (((x) & MAC_PCU_20_40_MODE_SWAMPED_FORCES_RX_CLEAR_CTL_IDLE_MASK) >> MAC_PCU_20_40_MODE_SWAMPED_FORCES_RX_CLEAR_CTL_IDLE_LSB)
-#define MAC_PCU_20_40_MODE_SWAMPED_FORCES_RX_CLEAR_CTL_IDLE_SET(x) (((x) << MAC_PCU_20_40_MODE_SWAMPED_FORCES_RX_CLEAR_CTL_IDLE_LSB) & MAC_PCU_20_40_MODE_SWAMPED_FORCES_RX_CLEAR_CTL_IDLE_MASK)
-#define MAC_PCU_20_40_MODE_TX_HT20_ON_EXT_BUSY_MSB 2
-#define MAC_PCU_20_40_MODE_TX_HT20_ON_EXT_BUSY_LSB 2
-#define MAC_PCU_20_40_MODE_TX_HT20_ON_EXT_BUSY_MASK 0x00000004
-#define MAC_PCU_20_40_MODE_TX_HT20_ON_EXT_BUSY_GET(x) (((x) & MAC_PCU_20_40_MODE_TX_HT20_ON_EXT_BUSY_MASK) >> MAC_PCU_20_40_MODE_TX_HT20_ON_EXT_BUSY_LSB)
-#define MAC_PCU_20_40_MODE_TX_HT20_ON_EXT_BUSY_SET(x) (((x) << MAC_PCU_20_40_MODE_TX_HT20_ON_EXT_BUSY_LSB) & MAC_PCU_20_40_MODE_TX_HT20_ON_EXT_BUSY_MASK)
-#define MAC_PCU_20_40_MODE_EXT_PIFS_ENABLE_MSB   1
-#define MAC_PCU_20_40_MODE_EXT_PIFS_ENABLE_LSB   1
-#define MAC_PCU_20_40_MODE_EXT_PIFS_ENABLE_MASK  0x00000002
-#define MAC_PCU_20_40_MODE_EXT_PIFS_ENABLE_GET(x) (((x) & MAC_PCU_20_40_MODE_EXT_PIFS_ENABLE_MASK) >> MAC_PCU_20_40_MODE_EXT_PIFS_ENABLE_LSB)
-#define MAC_PCU_20_40_MODE_EXT_PIFS_ENABLE_SET(x) (((x) << MAC_PCU_20_40_MODE_EXT_PIFS_ENABLE_LSB) & MAC_PCU_20_40_MODE_EXT_PIFS_ENABLE_MASK)
-#define MAC_PCU_20_40_MODE_JOINED_RX_CLEAR_MSB   0
-#define MAC_PCU_20_40_MODE_JOINED_RX_CLEAR_LSB   0
-#define MAC_PCU_20_40_MODE_JOINED_RX_CLEAR_MASK  0x00000001
-#define MAC_PCU_20_40_MODE_JOINED_RX_CLEAR_GET(x) (((x) & MAC_PCU_20_40_MODE_JOINED_RX_CLEAR_MASK) >> MAC_PCU_20_40_MODE_JOINED_RX_CLEAR_LSB)
-#define MAC_PCU_20_40_MODE_JOINED_RX_CLEAR_SET(x) (((x) << MAC_PCU_20_40_MODE_JOINED_RX_CLEAR_LSB) & MAC_PCU_20_40_MODE_JOINED_RX_CLEAR_MASK)
-
-#define MAC_PCU_RX_CLEAR_DIFF_CNT_ADDRESS        0x00008128
-#define MAC_PCU_RX_CLEAR_DIFF_CNT_OFFSET         0x00000128
-#define MAC_PCU_RX_CLEAR_DIFF_CNT_VALUE_MSB      31
-#define MAC_PCU_RX_CLEAR_DIFF_CNT_VALUE_LSB      0
-#define MAC_PCU_RX_CLEAR_DIFF_CNT_VALUE_MASK     0xffffffff
-#define MAC_PCU_RX_CLEAR_DIFF_CNT_VALUE_GET(x)   (((x) & MAC_PCU_RX_CLEAR_DIFF_CNT_VALUE_MASK) >> MAC_PCU_RX_CLEAR_DIFF_CNT_VALUE_LSB)
-#define MAC_PCU_RX_CLEAR_DIFF_CNT_VALUE_SET(x)   (((x) << MAC_PCU_RX_CLEAR_DIFF_CNT_VALUE_LSB) & MAC_PCU_RX_CLEAR_DIFF_CNT_VALUE_MASK)
-
-#define MAC_PCU_SELF_GEN_ANTENNA_MASK_ADDRESS    0x0000812c
-#define MAC_PCU_SELF_GEN_ANTENNA_MASK_OFFSET     0x0000012c
-#define MAC_PCU_SELF_GEN_ANTENNA_MASK_VALUE_MSB  2
-#define MAC_PCU_SELF_GEN_ANTENNA_MASK_VALUE_LSB  0
-#define MAC_PCU_SELF_GEN_ANTENNA_MASK_VALUE_MASK 0x00000007
-#define MAC_PCU_SELF_GEN_ANTENNA_MASK_VALUE_GET(x) (((x) & MAC_PCU_SELF_GEN_ANTENNA_MASK_VALUE_MASK) >> MAC_PCU_SELF_GEN_ANTENNA_MASK_VALUE_LSB)
-#define MAC_PCU_SELF_GEN_ANTENNA_MASK_VALUE_SET(x) (((x) << MAC_PCU_SELF_GEN_ANTENNA_MASK_VALUE_LSB) & MAC_PCU_SELF_GEN_ANTENNA_MASK_VALUE_MASK)
-
-#define MAC_PCU_BA_BAR_CONTROL_ADDRESS           0x00008130
-#define MAC_PCU_BA_BAR_CONTROL_OFFSET            0x00000130
-#define MAC_PCU_BA_BAR_CONTROL_UPDATE_BA_BITMAP_QOS_NULL_MSB 12
-#define MAC_PCU_BA_BAR_CONTROL_UPDATE_BA_BITMAP_QOS_NULL_LSB 12
-#define MAC_PCU_BA_BAR_CONTROL_UPDATE_BA_BITMAP_QOS_NULL_MASK 0x00001000
-#define MAC_PCU_BA_BAR_CONTROL_UPDATE_BA_BITMAP_QOS_NULL_GET(x) (((x) & MAC_PCU_BA_BAR_CONTROL_UPDATE_BA_BITMAP_QOS_NULL_MASK) >> MAC_PCU_BA_BAR_CONTROL_UPDATE_BA_BITMAP_QOS_NULL_LSB)
-#define MAC_PCU_BA_BAR_CONTROL_UPDATE_BA_BITMAP_QOS_NULL_SET(x) (((x) << MAC_PCU_BA_BAR_CONTROL_UPDATE_BA_BITMAP_QOS_NULL_LSB) & MAC_PCU_BA_BAR_CONTROL_UPDATE_BA_BITMAP_QOS_NULL_MASK)
-#define MAC_PCU_BA_BAR_CONTROL_TX_BA_CLEAR_BA_VALID_MSB 11
-#define MAC_PCU_BA_BAR_CONTROL_TX_BA_CLEAR_BA_VALID_LSB 11
-#define MAC_PCU_BA_BAR_CONTROL_TX_BA_CLEAR_BA_VALID_MASK 0x00000800
-#define MAC_PCU_BA_BAR_CONTROL_TX_BA_CLEAR_BA_VALID_GET(x) (((x) & MAC_PCU_BA_BAR_CONTROL_TX_BA_CLEAR_BA_VALID_MASK) >> MAC_PCU_BA_BAR_CONTROL_TX_BA_CLEAR_BA_VALID_LSB)
-#define MAC_PCU_BA_BAR_CONTROL_TX_BA_CLEAR_BA_VALID_SET(x) (((x) << MAC_PCU_BA_BAR_CONTROL_TX_BA_CLEAR_BA_VALID_LSB) & MAC_PCU_BA_BAR_CONTROL_TX_BA_CLEAR_BA_VALID_MASK)
-#define MAC_PCU_BA_BAR_CONTROL_FORCE_NO_MATCH_MSB 10
-#define MAC_PCU_BA_BAR_CONTROL_FORCE_NO_MATCH_LSB 10
-#define MAC_PCU_BA_BAR_CONTROL_FORCE_NO_MATCH_MASK 0x00000400
-#define MAC_PCU_BA_BAR_CONTROL_FORCE_NO_MATCH_GET(x) (((x) & MAC_PCU_BA_BAR_CONTROL_FORCE_NO_MATCH_MASK) >> MAC_PCU_BA_BAR_CONTROL_FORCE_NO_MATCH_LSB)
-#define MAC_PCU_BA_BAR_CONTROL_FORCE_NO_MATCH_SET(x) (((x) << MAC_PCU_BA_BAR_CONTROL_FORCE_NO_MATCH_LSB) & MAC_PCU_BA_BAR_CONTROL_FORCE_NO_MATCH_MASK)
-#define MAC_PCU_BA_BAR_CONTROL_ACK_POLICY_VALUE_MSB 9
-#define MAC_PCU_BA_BAR_CONTROL_ACK_POLICY_VALUE_LSB 9
-#define MAC_PCU_BA_BAR_CONTROL_ACK_POLICY_VALUE_MASK 0x00000200
-#define MAC_PCU_BA_BAR_CONTROL_ACK_POLICY_VALUE_GET(x) (((x) & MAC_PCU_BA_BAR_CONTROL_ACK_POLICY_VALUE_MASK) >> MAC_PCU_BA_BAR_CONTROL_ACK_POLICY_VALUE_LSB)
-#define MAC_PCU_BA_BAR_CONTROL_ACK_POLICY_VALUE_SET(x) (((x) << MAC_PCU_BA_BAR_CONTROL_ACK_POLICY_VALUE_LSB) & MAC_PCU_BA_BAR_CONTROL_ACK_POLICY_VALUE_MASK)
-#define MAC_PCU_BA_BAR_CONTROL_COMPRESSED_VALUE_MSB 8
-#define MAC_PCU_BA_BAR_CONTROL_COMPRESSED_VALUE_LSB 8
-#define MAC_PCU_BA_BAR_CONTROL_COMPRESSED_VALUE_MASK 0x00000100
-#define MAC_PCU_BA_BAR_CONTROL_COMPRESSED_VALUE_GET(x) (((x) & MAC_PCU_BA_BAR_CONTROL_COMPRESSED_VALUE_MASK) >> MAC_PCU_BA_BAR_CONTROL_COMPRESSED_VALUE_LSB)
-#define MAC_PCU_BA_BAR_CONTROL_COMPRESSED_VALUE_SET(x) (((x) << MAC_PCU_BA_BAR_CONTROL_COMPRESSED_VALUE_LSB) & MAC_PCU_BA_BAR_CONTROL_COMPRESSED_VALUE_MASK)
-#define MAC_PCU_BA_BAR_CONTROL_ACK_POLICY_OFFSET_MSB 7
-#define MAC_PCU_BA_BAR_CONTROL_ACK_POLICY_OFFSET_LSB 4
-#define MAC_PCU_BA_BAR_CONTROL_ACK_POLICY_OFFSET_MASK 0x000000f0
-#define MAC_PCU_BA_BAR_CONTROL_ACK_POLICY_OFFSET_GET(x) (((x) & MAC_PCU_BA_BAR_CONTROL_ACK_POLICY_OFFSET_MASK) >> MAC_PCU_BA_BAR_CONTROL_ACK_POLICY_OFFSET_LSB)
-#define MAC_PCU_BA_BAR_CONTROL_ACK_POLICY_OFFSET_SET(x) (((x) << MAC_PCU_BA_BAR_CONTROL_ACK_POLICY_OFFSET_LSB) & MAC_PCU_BA_BAR_CONTROL_ACK_POLICY_OFFSET_MASK)
-#define MAC_PCU_BA_BAR_CONTROL_COMPRESSED_OFFSET_MSB 3
-#define MAC_PCU_BA_BAR_CONTROL_COMPRESSED_OFFSET_LSB 0
-#define MAC_PCU_BA_BAR_CONTROL_COMPRESSED_OFFSET_MASK 0x0000000f
-#define MAC_PCU_BA_BAR_CONTROL_COMPRESSED_OFFSET_GET(x) (((x) & MAC_PCU_BA_BAR_CONTROL_COMPRESSED_OFFSET_MASK) >> MAC_PCU_BA_BAR_CONTROL_COMPRESSED_OFFSET_LSB)
-#define MAC_PCU_BA_BAR_CONTROL_COMPRESSED_OFFSET_SET(x) (((x) << MAC_PCU_BA_BAR_CONTROL_COMPRESSED_OFFSET_LSB) & MAC_PCU_BA_BAR_CONTROL_COMPRESSED_OFFSET_MASK)
-
-#define MAC_PCU_LEGACY_PLCP_SPOOF_ADDRESS        0x00008134
-#define MAC_PCU_LEGACY_PLCP_SPOOF_OFFSET         0x00000134
-#define MAC_PCU_LEGACY_PLCP_SPOOF_MIN_LENGTH_MSB 12
-#define MAC_PCU_LEGACY_PLCP_SPOOF_MIN_LENGTH_LSB 8
-#define MAC_PCU_LEGACY_PLCP_SPOOF_MIN_LENGTH_MASK 0x00001f00
-#define MAC_PCU_LEGACY_PLCP_SPOOF_MIN_LENGTH_GET(x) (((x) & MAC_PCU_LEGACY_PLCP_SPOOF_MIN_LENGTH_MASK) >> MAC_PCU_LEGACY_PLCP_SPOOF_MIN_LENGTH_LSB)
-#define MAC_PCU_LEGACY_PLCP_SPOOF_MIN_LENGTH_SET(x) (((x) << MAC_PCU_LEGACY_PLCP_SPOOF_MIN_LENGTH_LSB) & MAC_PCU_LEGACY_PLCP_SPOOF_MIN_LENGTH_MASK)
-#define MAC_PCU_LEGACY_PLCP_SPOOF_EIFS_MINUS_DIFS_MSB 7
-#define MAC_PCU_LEGACY_PLCP_SPOOF_EIFS_MINUS_DIFS_LSB 0
-#define MAC_PCU_LEGACY_PLCP_SPOOF_EIFS_MINUS_DIFS_MASK 0x000000ff
-#define MAC_PCU_LEGACY_PLCP_SPOOF_EIFS_MINUS_DIFS_GET(x) (((x) & MAC_PCU_LEGACY_PLCP_SPOOF_EIFS_MINUS_DIFS_MASK) >> MAC_PCU_LEGACY_PLCP_SPOOF_EIFS_MINUS_DIFS_LSB)
-#define MAC_PCU_LEGACY_PLCP_SPOOF_EIFS_MINUS_DIFS_SET(x) (((x) << MAC_PCU_LEGACY_PLCP_SPOOF_EIFS_MINUS_DIFS_LSB) & MAC_PCU_LEGACY_PLCP_SPOOF_EIFS_MINUS_DIFS_MASK)
-
-#define MAC_PCU_PHY_ERROR_MASK_CONT_ADDRESS      0x00008138
-#define MAC_PCU_PHY_ERROR_MASK_CONT_OFFSET       0x00000138
-#define MAC_PCU_PHY_ERROR_MASK_CONT_EIFS_VALUE_MSB 23
-#define MAC_PCU_PHY_ERROR_MASK_CONT_EIFS_VALUE_LSB 16
-#define MAC_PCU_PHY_ERROR_MASK_CONT_EIFS_VALUE_MASK 0x00ff0000
-#define MAC_PCU_PHY_ERROR_MASK_CONT_EIFS_VALUE_GET(x) (((x) & MAC_PCU_PHY_ERROR_MASK_CONT_EIFS_VALUE_MASK) >> MAC_PCU_PHY_ERROR_MASK_CONT_EIFS_VALUE_LSB)
-#define MAC_PCU_PHY_ERROR_MASK_CONT_EIFS_VALUE_SET(x) (((x) << MAC_PCU_PHY_ERROR_MASK_CONT_EIFS_VALUE_LSB) & MAC_PCU_PHY_ERROR_MASK_CONT_EIFS_VALUE_MASK)
-#define MAC_PCU_PHY_ERROR_MASK_CONT_MASK_VALUE_MSB 7
-#define MAC_PCU_PHY_ERROR_MASK_CONT_MASK_VALUE_LSB 0
-#define MAC_PCU_PHY_ERROR_MASK_CONT_MASK_VALUE_MASK 0x000000ff
-#define MAC_PCU_PHY_ERROR_MASK_CONT_MASK_VALUE_GET(x) (((x) & MAC_PCU_PHY_ERROR_MASK_CONT_MASK_VALUE_MASK) >> MAC_PCU_PHY_ERROR_MASK_CONT_MASK_VALUE_LSB)
-#define MAC_PCU_PHY_ERROR_MASK_CONT_MASK_VALUE_SET(x) (((x) << MAC_PCU_PHY_ERROR_MASK_CONT_MASK_VALUE_LSB) & MAC_PCU_PHY_ERROR_MASK_CONT_MASK_VALUE_MASK)
-
-#define MAC_PCU_TX_TIMER_ADDRESS                 0x0000813c
-#define MAC_PCU_TX_TIMER_OFFSET                  0x0000013c
-#define MAC_PCU_TX_TIMER_QUIET_TIMER_ENABLE_MSB  25
-#define MAC_PCU_TX_TIMER_QUIET_TIMER_ENABLE_LSB  25
-#define MAC_PCU_TX_TIMER_QUIET_TIMER_ENABLE_MASK 0x02000000
-#define MAC_PCU_TX_TIMER_QUIET_TIMER_ENABLE_GET(x) (((x) & MAC_PCU_TX_TIMER_QUIET_TIMER_ENABLE_MASK) >> MAC_PCU_TX_TIMER_QUIET_TIMER_ENABLE_LSB)
-#define MAC_PCU_TX_TIMER_QUIET_TIMER_ENABLE_SET(x) (((x) << MAC_PCU_TX_TIMER_QUIET_TIMER_ENABLE_LSB) & MAC_PCU_TX_TIMER_QUIET_TIMER_ENABLE_MASK)
-#define MAC_PCU_TX_TIMER_QUIET_TIMER_MSB         24
-#define MAC_PCU_TX_TIMER_QUIET_TIMER_LSB         20
-#define MAC_PCU_TX_TIMER_QUIET_TIMER_MASK        0x01f00000
-#define MAC_PCU_TX_TIMER_QUIET_TIMER_GET(x)      (((x) & MAC_PCU_TX_TIMER_QUIET_TIMER_MASK) >> MAC_PCU_TX_TIMER_QUIET_TIMER_LSB)
-#define MAC_PCU_TX_TIMER_QUIET_TIMER_SET(x)      (((x) << MAC_PCU_TX_TIMER_QUIET_TIMER_LSB) & MAC_PCU_TX_TIMER_QUIET_TIMER_MASK)
-#define MAC_PCU_TX_TIMER_RIFS_TIMER_MSB          19
-#define MAC_PCU_TX_TIMER_RIFS_TIMER_LSB          16
-#define MAC_PCU_TX_TIMER_RIFS_TIMER_MASK         0x000f0000
-#define MAC_PCU_TX_TIMER_RIFS_TIMER_GET(x)       (((x) & MAC_PCU_TX_TIMER_RIFS_TIMER_MASK) >> MAC_PCU_TX_TIMER_RIFS_TIMER_LSB)
-#define MAC_PCU_TX_TIMER_RIFS_TIMER_SET(x)       (((x) << MAC_PCU_TX_TIMER_RIFS_TIMER_LSB) & MAC_PCU_TX_TIMER_RIFS_TIMER_MASK)
-#define MAC_PCU_TX_TIMER_TX_TIMER_ENABLE_MSB     15
-#define MAC_PCU_TX_TIMER_TX_TIMER_ENABLE_LSB     15
-#define MAC_PCU_TX_TIMER_TX_TIMER_ENABLE_MASK    0x00008000
-#define MAC_PCU_TX_TIMER_TX_TIMER_ENABLE_GET(x)  (((x) & MAC_PCU_TX_TIMER_TX_TIMER_ENABLE_MASK) >> MAC_PCU_TX_TIMER_TX_TIMER_ENABLE_LSB)
-#define MAC_PCU_TX_TIMER_TX_TIMER_ENABLE_SET(x)  (((x) << MAC_PCU_TX_TIMER_TX_TIMER_ENABLE_LSB) & MAC_PCU_TX_TIMER_TX_TIMER_ENABLE_MASK)
-#define MAC_PCU_TX_TIMER_TX_TIMER_MSB            14
-#define MAC_PCU_TX_TIMER_TX_TIMER_LSB            0
-#define MAC_PCU_TX_TIMER_TX_TIMER_MASK           0x00007fff
-#define MAC_PCU_TX_TIMER_TX_TIMER_GET(x)         (((x) & MAC_PCU_TX_TIMER_TX_TIMER_MASK) >> MAC_PCU_TX_TIMER_TX_TIMER_LSB)
-#define MAC_PCU_TX_TIMER_TX_TIMER_SET(x)         (((x) << MAC_PCU_TX_TIMER_TX_TIMER_LSB) & MAC_PCU_TX_TIMER_TX_TIMER_MASK)
-
-#define MAC_PCU_TXBUF_CTRL_ADDRESS               0x00008140
-#define MAC_PCU_TXBUF_CTRL_OFFSET                0x00000140
-#define MAC_PCU_TXBUF_CTRL_TX_FIFO_WRAP_ENABLE_MSB 16
-#define MAC_PCU_TXBUF_CTRL_TX_FIFO_WRAP_ENABLE_LSB 16
-#define MAC_PCU_TXBUF_CTRL_TX_FIFO_WRAP_ENABLE_MASK 0x00010000
-#define MAC_PCU_TXBUF_CTRL_TX_FIFO_WRAP_ENABLE_GET(x) (((x) & MAC_PCU_TXBUF_CTRL_TX_FIFO_WRAP_ENABLE_MASK) >> MAC_PCU_TXBUF_CTRL_TX_FIFO_WRAP_ENABLE_LSB)
-#define MAC_PCU_TXBUF_CTRL_TX_FIFO_WRAP_ENABLE_SET(x) (((x) << MAC_PCU_TXBUF_CTRL_TX_FIFO_WRAP_ENABLE_LSB) & MAC_PCU_TXBUF_CTRL_TX_FIFO_WRAP_ENABLE_MASK)
-#define MAC_PCU_TXBUF_CTRL_USABLE_ENTRIES_MSB    11
-#define MAC_PCU_TXBUF_CTRL_USABLE_ENTRIES_LSB    0
-#define MAC_PCU_TXBUF_CTRL_USABLE_ENTRIES_MASK   0x00000fff
-#define MAC_PCU_TXBUF_CTRL_USABLE_ENTRIES_GET(x) (((x) & MAC_PCU_TXBUF_CTRL_USABLE_ENTRIES_MASK) >> MAC_PCU_TXBUF_CTRL_USABLE_ENTRIES_LSB)
-#define MAC_PCU_TXBUF_CTRL_USABLE_ENTRIES_SET(x) (((x) << MAC_PCU_TXBUF_CTRL_USABLE_ENTRIES_LSB) & MAC_PCU_TXBUF_CTRL_USABLE_ENTRIES_MASK)
-
-#define MAC_PCU_MISC_MODE2_ADDRESS               0x00008144
-#define MAC_PCU_MISC_MODE2_OFFSET                0x00000144
-#define MAC_PCU_MISC_MODE2_RESERVED_1_MSB        31
-#define MAC_PCU_MISC_MODE2_RESERVED_1_LSB        28
-#define MAC_PCU_MISC_MODE2_RESERVED_1_MASK       0xf0000000
-#define MAC_PCU_MISC_MODE2_RESERVED_1_GET(x)     (((x) & MAC_PCU_MISC_MODE2_RESERVED_1_MASK) >> MAC_PCU_MISC_MODE2_RESERVED_1_LSB)
-#define MAC_PCU_MISC_MODE2_RESERVED_1_SET(x)     (((x) << MAC_PCU_MISC_MODE2_RESERVED_1_LSB) & MAC_PCU_MISC_MODE2_RESERVED_1_MASK)
-#define MAC_PCU_MISC_MODE2_RCV_TIMESTAMP_FIX_MSB 27
-#define MAC_PCU_MISC_MODE2_RCV_TIMESTAMP_FIX_LSB 27
-#define MAC_PCU_MISC_MODE2_RCV_TIMESTAMP_FIX_MASK 0x08000000
-#define MAC_PCU_MISC_MODE2_RCV_TIMESTAMP_FIX_GET(x) (((x) & MAC_PCU_MISC_MODE2_RCV_TIMESTAMP_FIX_MASK) >> MAC_PCU_MISC_MODE2_RCV_TIMESTAMP_FIX_LSB)
-#define MAC_PCU_MISC_MODE2_RCV_TIMESTAMP_FIX_SET(x) (((x) << MAC_PCU_MISC_MODE2_RCV_TIMESTAMP_FIX_LSB) & MAC_PCU_MISC_MODE2_RCV_TIMESTAMP_FIX_MASK)
-#define MAC_PCU_MISC_MODE2_BEACON_FROM_TO_DS_MSB 26
-#define MAC_PCU_MISC_MODE2_BEACON_FROM_TO_DS_LSB 26
-#define MAC_PCU_MISC_MODE2_BEACON_FROM_TO_DS_MASK 0x04000000
-#define MAC_PCU_MISC_MODE2_BEACON_FROM_TO_DS_GET(x) (((x) & MAC_PCU_MISC_MODE2_BEACON_FROM_TO_DS_MASK) >> MAC_PCU_MISC_MODE2_BEACON_FROM_TO_DS_LSB)
-#define MAC_PCU_MISC_MODE2_BEACON_FROM_TO_DS_SET(x) (((x) << MAC_PCU_MISC_MODE2_BEACON_FROM_TO_DS_LSB) & MAC_PCU_MISC_MODE2_BEACON_FROM_TO_DS_MASK)
-#define MAC_PCU_MISC_MODE2_PM_FIELD_FOR_MGMT_MSB 25
-#define MAC_PCU_MISC_MODE2_PM_FIELD_FOR_MGMT_LSB 25
-#define MAC_PCU_MISC_MODE2_PM_FIELD_FOR_MGMT_MASK 0x02000000
-#define MAC_PCU_MISC_MODE2_PM_FIELD_FOR_MGMT_GET(x) (((x) & MAC_PCU_MISC_MODE2_PM_FIELD_FOR_MGMT_MASK) >> MAC_PCU_MISC_MODE2_PM_FIELD_FOR_MGMT_LSB)
-#define MAC_PCU_MISC_MODE2_PM_FIELD_FOR_MGMT_SET(x) (((x) << MAC_PCU_MISC_MODE2_PM_FIELD_FOR_MGMT_LSB) & MAC_PCU_MISC_MODE2_PM_FIELD_FOR_MGMT_MASK)
-#define MAC_PCU_MISC_MODE2_PM_FIELD_FOR_DAT_MSB  24
-#define MAC_PCU_MISC_MODE2_PM_FIELD_FOR_DAT_LSB  24
-#define MAC_PCU_MISC_MODE2_PM_FIELD_FOR_DAT_MASK 0x01000000
-#define MAC_PCU_MISC_MODE2_PM_FIELD_FOR_DAT_GET(x) (((x) & MAC_PCU_MISC_MODE2_PM_FIELD_FOR_DAT_MASK) >> MAC_PCU_MISC_MODE2_PM_FIELD_FOR_DAT_LSB)
-#define MAC_PCU_MISC_MODE2_PM_FIELD_FOR_DAT_SET(x) (((x) << MAC_PCU_MISC_MODE2_PM_FIELD_FOR_DAT_LSB) & MAC_PCU_MISC_MODE2_PM_FIELD_FOR_DAT_MASK)
-#define MAC_PCU_MISC_MODE2_IGNORE_TXOP_IF_ZERO_MSB 23
-#define MAC_PCU_MISC_MODE2_IGNORE_TXOP_IF_ZERO_LSB 23
-#define MAC_PCU_MISC_MODE2_IGNORE_TXOP_IF_ZERO_MASK 0x00800000
-#define MAC_PCU_MISC_MODE2_IGNORE_TXOP_IF_ZERO_GET(x) (((x) & MAC_PCU_MISC_MODE2_IGNORE_TXOP_IF_ZERO_MASK) >> MAC_PCU_MISC_MODE2_IGNORE_TXOP_IF_ZERO_LSB)
-#define MAC_PCU_MISC_MODE2_IGNORE_TXOP_IF_ZERO_SET(x) (((x) << MAC_PCU_MISC_MODE2_IGNORE_TXOP_IF_ZERO_LSB) & MAC_PCU_MISC_MODE2_IGNORE_TXOP_IF_ZERO_MASK)
-#define MAC_PCU_MISC_MODE2_IGNORE_TXOP_1ST_PKT_MSB 22
-#define MAC_PCU_MISC_MODE2_IGNORE_TXOP_1ST_PKT_LSB 22
-#define MAC_PCU_MISC_MODE2_IGNORE_TXOP_1ST_PKT_MASK 0x00400000
-#define MAC_PCU_MISC_MODE2_IGNORE_TXOP_1ST_PKT_GET(x) (((x) & MAC_PCU_MISC_MODE2_IGNORE_TXOP_1ST_PKT_MASK) >> MAC_PCU_MISC_MODE2_IGNORE_TXOP_1ST_PKT_LSB)
-#define MAC_PCU_MISC_MODE2_IGNORE_TXOP_1ST_PKT_SET(x) (((x) << MAC_PCU_MISC_MODE2_IGNORE_TXOP_1ST_PKT_LSB) & MAC_PCU_MISC_MODE2_IGNORE_TXOP_1ST_PKT_MASK)
-#define MAC_PCU_MISC_MODE2_CLEAR_MORE_FRAG_MSB   21
-#define MAC_PCU_MISC_MODE2_CLEAR_MORE_FRAG_LSB   21
-#define MAC_PCU_MISC_MODE2_CLEAR_MORE_FRAG_MASK  0x00200000
-#define MAC_PCU_MISC_MODE2_CLEAR_MORE_FRAG_GET(x) (((x) & MAC_PCU_MISC_MODE2_CLEAR_MORE_FRAG_MASK) >> MAC_PCU_MISC_MODE2_CLEAR_MORE_FRAG_LSB)
-#define MAC_PCU_MISC_MODE2_CLEAR_MORE_FRAG_SET(x) (((x) << MAC_PCU_MISC_MODE2_CLEAR_MORE_FRAG_LSB) & MAC_PCU_MISC_MODE2_CLEAR_MORE_FRAG_MASK)
-#define MAC_PCU_MISC_MODE2_BUG_28676_MSB         20
-#define MAC_PCU_MISC_MODE2_BUG_28676_LSB         20
-#define MAC_PCU_MISC_MODE2_BUG_28676_MASK        0x00100000
-#define MAC_PCU_MISC_MODE2_BUG_28676_GET(x)      (((x) & MAC_PCU_MISC_MODE2_BUG_28676_MASK) >> MAC_PCU_MISC_MODE2_BUG_28676_LSB)
-#define MAC_PCU_MISC_MODE2_BUG_28676_SET(x)      (((x) << MAC_PCU_MISC_MODE2_BUG_28676_LSB) & MAC_PCU_MISC_MODE2_BUG_28676_MASK)
-#define MAC_PCU_MISC_MODE2_DUR_ACCOUNT_BY_BA_MSB 19
-#define MAC_PCU_MISC_MODE2_DUR_ACCOUNT_BY_BA_LSB 19
-#define MAC_PCU_MISC_MODE2_DUR_ACCOUNT_BY_BA_MASK 0x00080000
-#define MAC_PCU_MISC_MODE2_DUR_ACCOUNT_BY_BA_GET(x) (((x) & MAC_PCU_MISC_MODE2_DUR_ACCOUNT_BY_BA_MASK) >> MAC_PCU_MISC_MODE2_DUR_ACCOUNT_BY_BA_LSB)
-#define MAC_PCU_MISC_MODE2_DUR_ACCOUNT_BY_BA_SET(x) (((x) << MAC_PCU_MISC_MODE2_DUR_ACCOUNT_BY_BA_LSB) & MAC_PCU_MISC_MODE2_DUR_ACCOUNT_BY_BA_MASK)
-#define MAC_PCU_MISC_MODE2_BC_MC_WAPI_MODE_MSB   18
-#define MAC_PCU_MISC_MODE2_BC_MC_WAPI_MODE_LSB   18
-#define MAC_PCU_MISC_MODE2_BC_MC_WAPI_MODE_MASK  0x00040000
-#define MAC_PCU_MISC_MODE2_BC_MC_WAPI_MODE_GET(x) (((x) & MAC_PCU_MISC_MODE2_BC_MC_WAPI_MODE_MASK) >> MAC_PCU_MISC_MODE2_BC_MC_WAPI_MODE_LSB)
-#define MAC_PCU_MISC_MODE2_BC_MC_WAPI_MODE_SET(x) (((x) << MAC_PCU_MISC_MODE2_BC_MC_WAPI_MODE_LSB) & MAC_PCU_MISC_MODE2_BC_MC_WAPI_MODE_MASK)
-#define MAC_PCU_MISC_MODE2_AGG_WEP_MSB           17
-#define MAC_PCU_MISC_MODE2_AGG_WEP_LSB           17
-#define MAC_PCU_MISC_MODE2_AGG_WEP_MASK          0x00020000
-#define MAC_PCU_MISC_MODE2_AGG_WEP_GET(x)        (((x) & MAC_PCU_MISC_MODE2_AGG_WEP_MASK) >> MAC_PCU_MISC_MODE2_AGG_WEP_LSB)
-#define MAC_PCU_MISC_MODE2_AGG_WEP_SET(x)        (((x) << MAC_PCU_MISC_MODE2_AGG_WEP_LSB) & MAC_PCU_MISC_MODE2_AGG_WEP_MASK)
-#define MAC_PCU_MISC_MODE2_ENABLE_LOAD_NAV_BEACON_DURATION_MSB 16
-#define MAC_PCU_MISC_MODE2_ENABLE_LOAD_NAV_BEACON_DURATION_LSB 16
-#define MAC_PCU_MISC_MODE2_ENABLE_LOAD_NAV_BEACON_DURATION_MASK 0x00010000
-#define MAC_PCU_MISC_MODE2_ENABLE_LOAD_NAV_BEACON_DURATION_GET(x) (((x) & MAC_PCU_MISC_MODE2_ENABLE_LOAD_NAV_BEACON_DURATION_MASK) >> MAC_PCU_MISC_MODE2_ENABLE_LOAD_NAV_BEACON_DURATION_LSB)
-#define MAC_PCU_MISC_MODE2_ENABLE_LOAD_NAV_BEACON_DURATION_SET(x) (((x) << MAC_PCU_MISC_MODE2_ENABLE_LOAD_NAV_BEACON_DURATION_LSB) & MAC_PCU_MISC_MODE2_ENABLE_LOAD_NAV_BEACON_DURATION_MASK)
-#define MAC_PCU_MISC_MODE2_MGMT_QOS_MSB          15
-#define MAC_PCU_MISC_MODE2_MGMT_QOS_LSB          8
-#define MAC_PCU_MISC_MODE2_MGMT_QOS_MASK         0x0000ff00
-#define MAC_PCU_MISC_MODE2_MGMT_QOS_GET(x)       (((x) & MAC_PCU_MISC_MODE2_MGMT_QOS_MASK) >> MAC_PCU_MISC_MODE2_MGMT_QOS_LSB)
-#define MAC_PCU_MISC_MODE2_MGMT_QOS_SET(x)       (((x) << MAC_PCU_MISC_MODE2_MGMT_QOS_LSB) & MAC_PCU_MISC_MODE2_MGMT_QOS_MASK)
-#define MAC_PCU_MISC_MODE2_CFP_IGNORE_MSB        7
-#define MAC_PCU_MISC_MODE2_CFP_IGNORE_LSB        7
-#define MAC_PCU_MISC_MODE2_CFP_IGNORE_MASK       0x00000080
-#define MAC_PCU_MISC_MODE2_CFP_IGNORE_GET(x)     (((x) & MAC_PCU_MISC_MODE2_CFP_IGNORE_MASK) >> MAC_PCU_MISC_MODE2_CFP_IGNORE_LSB)
-#define MAC_PCU_MISC_MODE2_CFP_IGNORE_SET(x)     (((x) << MAC_PCU_MISC_MODE2_CFP_IGNORE_LSB) & MAC_PCU_MISC_MODE2_CFP_IGNORE_MASK)
-#define MAC_PCU_MISC_MODE2_ADHOC_MCAST_KEYID_ENABLE_MSB 6
-#define MAC_PCU_MISC_MODE2_ADHOC_MCAST_KEYID_ENABLE_LSB 6
-#define MAC_PCU_MISC_MODE2_ADHOC_MCAST_KEYID_ENABLE_MASK 0x00000040
-#define MAC_PCU_MISC_MODE2_ADHOC_MCAST_KEYID_ENABLE_GET(x) (((x) & MAC_PCU_MISC_MODE2_ADHOC_MCAST_KEYID_ENABLE_MASK) >> MAC_PCU_MISC_MODE2_ADHOC_MCAST_KEYID_ENABLE_LSB)
-#define MAC_PCU_MISC_MODE2_ADHOC_MCAST_KEYID_ENABLE_SET(x) (((x) << MAC_PCU_MISC_MODE2_ADHOC_MCAST_KEYID_ENABLE_LSB) & MAC_PCU_MISC_MODE2_ADHOC_MCAST_KEYID_ENABLE_MASK)
-#define MAC_PCU_MISC_MODE2_RESERVED_2_MSB        5
-#define MAC_PCU_MISC_MODE2_RESERVED_2_LSB        5
-#define MAC_PCU_MISC_MODE2_RESERVED_2_MASK       0x00000020
-#define MAC_PCU_MISC_MODE2_RESERVED_2_GET(x)     (((x) & MAC_PCU_MISC_MODE2_RESERVED_2_MASK) >> MAC_PCU_MISC_MODE2_RESERVED_2_LSB)
-#define MAC_PCU_MISC_MODE2_RESERVED_2_SET(x)     (((x) << MAC_PCU_MISC_MODE2_RESERVED_2_LSB) & MAC_PCU_MISC_MODE2_RESERVED_2_MASK)
-#define MAC_PCU_MISC_MODE2_BUG_58057_FIX_ENABLE_MSB 4
-#define MAC_PCU_MISC_MODE2_BUG_58057_FIX_ENABLE_LSB 4
-#define MAC_PCU_MISC_MODE2_BUG_58057_FIX_ENABLE_MASK 0x00000010
-#define MAC_PCU_MISC_MODE2_BUG_58057_FIX_ENABLE_GET(x) (((x) & MAC_PCU_MISC_MODE2_BUG_58057_FIX_ENABLE_MASK) >> MAC_PCU_MISC_MODE2_BUG_58057_FIX_ENABLE_LSB)
-#define MAC_PCU_MISC_MODE2_BUG_58057_FIX_ENABLE_SET(x) (((x) << MAC_PCU_MISC_MODE2_BUG_58057_FIX_ENABLE_LSB) & MAC_PCU_MISC_MODE2_BUG_58057_FIX_ENABLE_MASK)
-#define MAC_PCU_MISC_MODE2_RESERVED_0_MSB        3
-#define MAC_PCU_MISC_MODE2_RESERVED_0_LSB        3
-#define MAC_PCU_MISC_MODE2_RESERVED_0_MASK       0x00000008
-#define MAC_PCU_MISC_MODE2_RESERVED_0_GET(x)     (((x) & MAC_PCU_MISC_MODE2_RESERVED_0_MASK) >> MAC_PCU_MISC_MODE2_RESERVED_0_LSB)
-#define MAC_PCU_MISC_MODE2_RESERVED_0_SET(x)     (((x) << MAC_PCU_MISC_MODE2_RESERVED_0_LSB) & MAC_PCU_MISC_MODE2_RESERVED_0_MASK)
-#define MAC_PCU_MISC_MODE2_NO_CRYPTO_FOR_NON_DATA_PKT_MSB 2
-#define MAC_PCU_MISC_MODE2_NO_CRYPTO_FOR_NON_DATA_PKT_LSB 2
-#define MAC_PCU_MISC_MODE2_NO_CRYPTO_FOR_NON_DATA_PKT_MASK 0x00000004
-#define MAC_PCU_MISC_MODE2_NO_CRYPTO_FOR_NON_DATA_PKT_GET(x) (((x) & MAC_PCU_MISC_MODE2_NO_CRYPTO_FOR_NON_DATA_PKT_MASK) >> MAC_PCU_MISC_MODE2_NO_CRYPTO_FOR_NON_DATA_PKT_LSB)
-#define MAC_PCU_MISC_MODE2_NO_CRYPTO_FOR_NON_DATA_PKT_SET(x) (((x) << MAC_PCU_MISC_MODE2_NO_CRYPTO_FOR_NON_DATA_PKT_LSB) & MAC_PCU_MISC_MODE2_NO_CRYPTO_FOR_NON_DATA_PKT_MASK)
-#define MAC_PCU_MISC_MODE2_MGMT_CRYPTO_ENABLE_MSB 1
-#define MAC_PCU_MISC_MODE2_MGMT_CRYPTO_ENABLE_LSB 1
-#define MAC_PCU_MISC_MODE2_MGMT_CRYPTO_ENABLE_MASK 0x00000002
-#define MAC_PCU_MISC_MODE2_MGMT_CRYPTO_ENABLE_GET(x) (((x) & MAC_PCU_MISC_MODE2_MGMT_CRYPTO_ENABLE_MASK) >> MAC_PCU_MISC_MODE2_MGMT_CRYPTO_ENABLE_LSB)
-#define MAC_PCU_MISC_MODE2_MGMT_CRYPTO_ENABLE_SET(x) (((x) << MAC_PCU_MISC_MODE2_MGMT_CRYPTO_ENABLE_LSB) & MAC_PCU_MISC_MODE2_MGMT_CRYPTO_ENABLE_MASK)
-#define MAC_PCU_MISC_MODE2_BUG_21532_FIX_ENABLE_MSB 0
-#define MAC_PCU_MISC_MODE2_BUG_21532_FIX_ENABLE_LSB 0
-#define MAC_PCU_MISC_MODE2_BUG_21532_FIX_ENABLE_MASK 0x00000001
-#define MAC_PCU_MISC_MODE2_BUG_21532_FIX_ENABLE_GET(x) (((x) & MAC_PCU_MISC_MODE2_BUG_21532_FIX_ENABLE_MASK) >> MAC_PCU_MISC_MODE2_BUG_21532_FIX_ENABLE_LSB)
-#define MAC_PCU_MISC_MODE2_BUG_21532_FIX_ENABLE_SET(x) (((x) << MAC_PCU_MISC_MODE2_BUG_21532_FIX_ENABLE_LSB) & MAC_PCU_MISC_MODE2_BUG_21532_FIX_ENABLE_MASK)
-
-#define MAC_PCU_ALT_AES_MUTE_MASK_ADDRESS        0x00008148
-#define MAC_PCU_ALT_AES_MUTE_MASK_OFFSET         0x00000148
-#define MAC_PCU_ALT_AES_MUTE_MASK_QOS_MSB        31
-#define MAC_PCU_ALT_AES_MUTE_MASK_QOS_LSB        16
-#define MAC_PCU_ALT_AES_MUTE_MASK_QOS_MASK       0xffff0000
-#define MAC_PCU_ALT_AES_MUTE_MASK_QOS_GET(x)     (((x) & MAC_PCU_ALT_AES_MUTE_MASK_QOS_MASK) >> MAC_PCU_ALT_AES_MUTE_MASK_QOS_LSB)
-#define MAC_PCU_ALT_AES_MUTE_MASK_QOS_SET(x)     (((x) << MAC_PCU_ALT_AES_MUTE_MASK_QOS_LSB) & MAC_PCU_ALT_AES_MUTE_MASK_QOS_MASK)
-
-#define MAC_PCU_AZIMUTH_TIME_STAMP_ADDRESS       0x0000814c
-#define MAC_PCU_AZIMUTH_TIME_STAMP_OFFSET        0x0000014c
-#define MAC_PCU_AZIMUTH_TIME_STAMP_VALUE_MSB     31
-#define MAC_PCU_AZIMUTH_TIME_STAMP_VALUE_LSB     0
-#define MAC_PCU_AZIMUTH_TIME_STAMP_VALUE_MASK    0xffffffff
-#define MAC_PCU_AZIMUTH_TIME_STAMP_VALUE_GET(x)  (((x) & MAC_PCU_AZIMUTH_TIME_STAMP_VALUE_MASK) >> MAC_PCU_AZIMUTH_TIME_STAMP_VALUE_LSB)
-#define MAC_PCU_AZIMUTH_TIME_STAMP_VALUE_SET(x)  (((x) << MAC_PCU_AZIMUTH_TIME_STAMP_VALUE_LSB) & MAC_PCU_AZIMUTH_TIME_STAMP_VALUE_MASK)
-
-#define MAC_PCU_MAX_CFP_DUR_ADDRESS              0x00008150
-#define MAC_PCU_MAX_CFP_DUR_OFFSET               0x00000150
-#define MAC_PCU_MAX_CFP_DUR_USEC_FRAC_DENOMINATOR_MSB 7
-#define MAC_PCU_MAX_CFP_DUR_USEC_FRAC_DENOMINATOR_LSB 4
-#define MAC_PCU_MAX_CFP_DUR_USEC_FRAC_DENOMINATOR_MASK 0x000000f0
-#define MAC_PCU_MAX_CFP_DUR_USEC_FRAC_DENOMINATOR_GET(x) (((x) & MAC_PCU_MAX_CFP_DUR_USEC_FRAC_DENOMINATOR_MASK) >> MAC_PCU_MAX_CFP_DUR_USEC_FRAC_DENOMINATOR_LSB)
-#define MAC_PCU_MAX_CFP_DUR_USEC_FRAC_DENOMINATOR_SET(x) (((x) << MAC_PCU_MAX_CFP_DUR_USEC_FRAC_DENOMINATOR_LSB) & MAC_PCU_MAX_CFP_DUR_USEC_FRAC_DENOMINATOR_MASK)
-#define MAC_PCU_MAX_CFP_DUR_USEC_FRAC_NUMERATOR_MSB 3
-#define MAC_PCU_MAX_CFP_DUR_USEC_FRAC_NUMERATOR_LSB 0
-#define MAC_PCU_MAX_CFP_DUR_USEC_FRAC_NUMERATOR_MASK 0x0000000f
-#define MAC_PCU_MAX_CFP_DUR_USEC_FRAC_NUMERATOR_GET(x) (((x) & MAC_PCU_MAX_CFP_DUR_USEC_FRAC_NUMERATOR_MASK) >> MAC_PCU_MAX_CFP_DUR_USEC_FRAC_NUMERATOR_LSB)
-#define MAC_PCU_MAX_CFP_DUR_USEC_FRAC_NUMERATOR_SET(x) (((x) << MAC_PCU_MAX_CFP_DUR_USEC_FRAC_NUMERATOR_LSB) & MAC_PCU_MAX_CFP_DUR_USEC_FRAC_NUMERATOR_MASK)
-
-#define MAC_PCU_HCF_TIMEOUT_ADDRESS              0x00008154
-#define MAC_PCU_HCF_TIMEOUT_OFFSET               0x00000154
-#define MAC_PCU_HCF_TIMEOUT_VALUE_MSB            15
-#define MAC_PCU_HCF_TIMEOUT_VALUE_LSB            0
-#define MAC_PCU_HCF_TIMEOUT_VALUE_MASK           0x0000ffff
-#define MAC_PCU_HCF_TIMEOUT_VALUE_GET(x)         (((x) & MAC_PCU_HCF_TIMEOUT_VALUE_MASK) >> MAC_PCU_HCF_TIMEOUT_VALUE_LSB)
-#define MAC_PCU_HCF_TIMEOUT_VALUE_SET(x)         (((x) << MAC_PCU_HCF_TIMEOUT_VALUE_LSB) & MAC_PCU_HCF_TIMEOUT_VALUE_MASK)
-
-#define MAC_PCU_BLUETOOTH_WEIGHTS2_ADDRESS       0x00008158
-#define MAC_PCU_BLUETOOTH_WEIGHTS2_OFFSET        0x00000158
-#define MAC_PCU_BLUETOOTH_WEIGHTS2_WL_WEIGHT_CONTD_MSB 31
-#define MAC_PCU_BLUETOOTH_WEIGHTS2_WL_WEIGHT_CONTD_LSB 16
-#define MAC_PCU_BLUETOOTH_WEIGHTS2_WL_WEIGHT_CONTD_MASK 0xffff0000
-#define MAC_PCU_BLUETOOTH_WEIGHTS2_WL_WEIGHT_CONTD_GET(x) (((x) & MAC_PCU_BLUETOOTH_WEIGHTS2_WL_WEIGHT_CONTD_MASK) >> MAC_PCU_BLUETOOTH_WEIGHTS2_WL_WEIGHT_CONTD_LSB)
-#define MAC_PCU_BLUETOOTH_WEIGHTS2_WL_WEIGHT_CONTD_SET(x) (((x) << MAC_PCU_BLUETOOTH_WEIGHTS2_WL_WEIGHT_CONTD_LSB) & MAC_PCU_BLUETOOTH_WEIGHTS2_WL_WEIGHT_CONTD_MASK)
-
-#define MAC_PCU_BLUETOOTH_TSF_BT_ACTIVE_ADDRESS  0x0000815c
-#define MAC_PCU_BLUETOOTH_TSF_BT_ACTIVE_OFFSET   0x0000015c
-#define MAC_PCU_BLUETOOTH_TSF_BT_ACTIVE_VALUE_MSB 31
-#define MAC_PCU_BLUETOOTH_TSF_BT_ACTIVE_VALUE_LSB 0
-#define MAC_PCU_BLUETOOTH_TSF_BT_ACTIVE_VALUE_MASK 0xffffffff
-#define MAC_PCU_BLUETOOTH_TSF_BT_ACTIVE_VALUE_GET(x) (((x) & MAC_PCU_BLUETOOTH_TSF_BT_ACTIVE_VALUE_MASK) >> MAC_PCU_BLUETOOTH_TSF_BT_ACTIVE_VALUE_LSB)
-#define MAC_PCU_BLUETOOTH_TSF_BT_ACTIVE_VALUE_SET(x) (((x) << MAC_PCU_BLUETOOTH_TSF_BT_ACTIVE_VALUE_LSB) & MAC_PCU_BLUETOOTH_TSF_BT_ACTIVE_VALUE_MASK)
-
-#define MAC_PCU_BLUETOOTH_TSF_BT_PRIORITY_ADDRESS 0x00008160
-#define MAC_PCU_BLUETOOTH_TSF_BT_PRIORITY_OFFSET 0x00000160
-#define MAC_PCU_BLUETOOTH_TSF_BT_PRIORITY_VALUE_MSB 31
-#define MAC_PCU_BLUETOOTH_TSF_BT_PRIORITY_VALUE_LSB 0
-#define MAC_PCU_BLUETOOTH_TSF_BT_PRIORITY_VALUE_MASK 0xffffffff
-#define MAC_PCU_BLUETOOTH_TSF_BT_PRIORITY_VALUE_GET(x) (((x) & MAC_PCU_BLUETOOTH_TSF_BT_PRIORITY_VALUE_MASK) >> MAC_PCU_BLUETOOTH_TSF_BT_PRIORITY_VALUE_LSB)
-#define MAC_PCU_BLUETOOTH_TSF_BT_PRIORITY_VALUE_SET(x) (((x) << MAC_PCU_BLUETOOTH_TSF_BT_PRIORITY_VALUE_LSB) & MAC_PCU_BLUETOOTH_TSF_BT_PRIORITY_VALUE_MASK)
-
-#define MAC_PCU_BLUETOOTH_MODE3_ADDRESS          0x00008164
-#define MAC_PCU_BLUETOOTH_MODE3_OFFSET           0x00000164
-#define MAC_PCU_BLUETOOTH_MODE3_BT_PRIORITY_EXTEND_THRES_MSB 31
-#define MAC_PCU_BLUETOOTH_MODE3_BT_PRIORITY_EXTEND_THRES_LSB 28
-#define MAC_PCU_BLUETOOTH_MODE3_BT_PRIORITY_EXTEND_THRES_MASK 0xf0000000
-#define MAC_PCU_BLUETOOTH_MODE3_BT_PRIORITY_EXTEND_THRES_GET(x) (((x) & MAC_PCU_BLUETOOTH_MODE3_BT_PRIORITY_EXTEND_THRES_MASK) >> MAC_PCU_BLUETOOTH_MODE3_BT_PRIORITY_EXTEND_THRES_LSB)
-#define MAC_PCU_BLUETOOTH_MODE3_BT_PRIORITY_EXTEND_THRES_SET(x) (((x) << MAC_PCU_BLUETOOTH_MODE3_BT_PRIORITY_EXTEND_THRES_LSB) & MAC_PCU_BLUETOOTH_MODE3_BT_PRIORITY_EXTEND_THRES_MASK)
-#define MAC_PCU_BLUETOOTH_MODE3_BT_TX_ON_EN_MSB  27
-#define MAC_PCU_BLUETOOTH_MODE3_BT_TX_ON_EN_LSB  27
-#define MAC_PCU_BLUETOOTH_MODE3_BT_TX_ON_EN_MASK 0x08000000
-#define MAC_PCU_BLUETOOTH_MODE3_BT_TX_ON_EN_GET(x) (((x) & MAC_PCU_BLUETOOTH_MODE3_BT_TX_ON_EN_MASK) >> MAC_PCU_BLUETOOTH_MODE3_BT_TX_ON_EN_LSB)
-#define MAC_PCU_BLUETOOTH_MODE3_BT_TX_ON_EN_SET(x) (((x) << MAC_PCU_BLUETOOTH_MODE3_BT_TX_ON_EN_LSB) & MAC_PCU_BLUETOOTH_MODE3_BT_TX_ON_EN_MASK)
-#define MAC_PCU_BLUETOOTH_MODE3_SLOT_SLOP_MSB    26
-#define MAC_PCU_BLUETOOTH_MODE3_SLOT_SLOP_LSB    25
-#define MAC_PCU_BLUETOOTH_MODE3_SLOT_SLOP_MASK   0x06000000
-#define MAC_PCU_BLUETOOTH_MODE3_SLOT_SLOP_GET(x) (((x) & MAC_PCU_BLUETOOTH_MODE3_SLOT_SLOP_MASK) >> MAC_PCU_BLUETOOTH_MODE3_SLOT_SLOP_LSB)
-#define MAC_PCU_BLUETOOTH_MODE3_SLOT_SLOP_SET(x) (((x) << MAC_PCU_BLUETOOTH_MODE3_SLOT_SLOP_LSB) & MAC_PCU_BLUETOOTH_MODE3_SLOT_SLOP_MASK)
-#define MAC_PCU_BLUETOOTH_MODE3_DYNAMIC_TOGGLE_WLA_EN_MSB 24
-#define MAC_PCU_BLUETOOTH_MODE3_DYNAMIC_TOGGLE_WLA_EN_LSB 24
-#define MAC_PCU_BLUETOOTH_MODE3_DYNAMIC_TOGGLE_WLA_EN_MASK 0x01000000
-#define MAC_PCU_BLUETOOTH_MODE3_DYNAMIC_TOGGLE_WLA_EN_GET(x) (((x) & MAC_PCU_BLUETOOTH_MODE3_DYNAMIC_TOGGLE_WLA_EN_MASK) >> MAC_PCU_BLUETOOTH_MODE3_DYNAMIC_TOGGLE_WLA_EN_LSB)
-#define MAC_PCU_BLUETOOTH_MODE3_DYNAMIC_TOGGLE_WLA_EN_SET(x) (((x) << MAC_PCU_BLUETOOTH_MODE3_DYNAMIC_TOGGLE_WLA_EN_LSB) & MAC_PCU_BLUETOOTH_MODE3_DYNAMIC_TOGGLE_WLA_EN_MASK)
-#define MAC_PCU_BLUETOOTH_MODE3_DYNAMIC_PRI_EN_MSB 23
-#define MAC_PCU_BLUETOOTH_MODE3_DYNAMIC_PRI_EN_LSB 23
-#define MAC_PCU_BLUETOOTH_MODE3_DYNAMIC_PRI_EN_MASK 0x00800000
-#define MAC_PCU_BLUETOOTH_MODE3_DYNAMIC_PRI_EN_GET(x) (((x) & MAC_PCU_BLUETOOTH_MODE3_DYNAMIC_PRI_EN_MASK) >> MAC_PCU_BLUETOOTH_MODE3_DYNAMIC_PRI_EN_LSB)
-#define MAC_PCU_BLUETOOTH_MODE3_DYNAMIC_PRI_EN_SET(x) (((x) << MAC_PCU_BLUETOOTH_MODE3_DYNAMIC_PRI_EN_LSB) & MAC_PCU_BLUETOOTH_MODE3_DYNAMIC_PRI_EN_MASK)
-#define MAC_PCU_BLUETOOTH_MODE3_RFGAIN_LOCK_SRC_MSB 22
-#define MAC_PCU_BLUETOOTH_MODE3_RFGAIN_LOCK_SRC_LSB 22
-#define MAC_PCU_BLUETOOTH_MODE3_RFGAIN_LOCK_SRC_MASK 0x00400000
-#define MAC_PCU_BLUETOOTH_MODE3_RFGAIN_LOCK_SRC_GET(x) (((x) & MAC_PCU_BLUETOOTH_MODE3_RFGAIN_LOCK_SRC_MASK) >> MAC_PCU_BLUETOOTH_MODE3_RFGAIN_LOCK_SRC_LSB)
-#define MAC_PCU_BLUETOOTH_MODE3_RFGAIN_LOCK_SRC_SET(x) (((x) << MAC_PCU_BLUETOOTH_MODE3_RFGAIN_LOCK_SRC_LSB) & MAC_PCU_BLUETOOTH_MODE3_RFGAIN_LOCK_SRC_MASK)
-#define MAC_PCU_BLUETOOTH_MODE3_WL_PRIORITY_OFFSET_EN_MSB 21
-#define MAC_PCU_BLUETOOTH_MODE3_WL_PRIORITY_OFFSET_EN_LSB 21
-#define MAC_PCU_BLUETOOTH_MODE3_WL_PRIORITY_OFFSET_EN_MASK 0x00200000
-#define MAC_PCU_BLUETOOTH_MODE3_WL_PRIORITY_OFFSET_EN_GET(x) (((x) & MAC_PCU_BLUETOOTH_MODE3_WL_PRIORITY_OFFSET_EN_MASK) >> MAC_PCU_BLUETOOTH_MODE3_WL_PRIORITY_OFFSET_EN_LSB)
-#define MAC_PCU_BLUETOOTH_MODE3_WL_PRIORITY_OFFSET_EN_SET(x) (((x) << MAC_PCU_BLUETOOTH_MODE3_WL_PRIORITY_OFFSET_EN_LSB) & MAC_PCU_BLUETOOTH_MODE3_WL_PRIORITY_OFFSET_EN_MASK)
-#define MAC_PCU_BLUETOOTH_MODE3_SHARED_RX_MSB    20
-#define MAC_PCU_BLUETOOTH_MODE3_SHARED_RX_LSB    20
-#define MAC_PCU_BLUETOOTH_MODE3_SHARED_RX_MASK   0x00100000
-#define MAC_PCU_BLUETOOTH_MODE3_SHARED_RX_GET(x) (((x) & MAC_PCU_BLUETOOTH_MODE3_SHARED_RX_MASK) >> MAC_PCU_BLUETOOTH_MODE3_SHARED_RX_LSB)
-#define MAC_PCU_BLUETOOTH_MODE3_SHARED_RX_SET(x) (((x) << MAC_PCU_BLUETOOTH_MODE3_SHARED_RX_LSB) & MAC_PCU_BLUETOOTH_MODE3_SHARED_RX_MASK)
-#define MAC_PCU_BLUETOOTH_MODE3_ALLOW_CONCURRENT_ACCESS_MSB 19
-#define MAC_PCU_BLUETOOTH_MODE3_ALLOW_CONCURRENT_ACCESS_LSB 16
-#define MAC_PCU_BLUETOOTH_MODE3_ALLOW_CONCURRENT_ACCESS_MASK 0x000f0000
-#define MAC_PCU_BLUETOOTH_MODE3_ALLOW_CONCURRENT_ACCESS_GET(x) (((x) & MAC_PCU_BLUETOOTH_MODE3_ALLOW_CONCURRENT_ACCESS_MASK) >> MAC_PCU_BLUETOOTH_MODE3_ALLOW_CONCURRENT_ACCESS_LSB)
-#define MAC_PCU_BLUETOOTH_MODE3_ALLOW_CONCURRENT_ACCESS_SET(x) (((x) << MAC_PCU_BLUETOOTH_MODE3_ALLOW_CONCURRENT_ACCESS_LSB) & MAC_PCU_BLUETOOTH_MODE3_ALLOW_CONCURRENT_ACCESS_MASK)
-#define MAC_PCU_BLUETOOTH_MODE3_WL_QC_TIME_MSB   15
-#define MAC_PCU_BLUETOOTH_MODE3_WL_QC_TIME_LSB   8
-#define MAC_PCU_BLUETOOTH_MODE3_WL_QC_TIME_MASK  0x0000ff00
-#define MAC_PCU_BLUETOOTH_MODE3_WL_QC_TIME_GET(x) (((x) & MAC_PCU_BLUETOOTH_MODE3_WL_QC_TIME_MASK) >> MAC_PCU_BLUETOOTH_MODE3_WL_QC_TIME_LSB)
-#define MAC_PCU_BLUETOOTH_MODE3_WL_QC_TIME_SET(x) (((x) << MAC_PCU_BLUETOOTH_MODE3_WL_QC_TIME_LSB) & MAC_PCU_BLUETOOTH_MODE3_WL_QC_TIME_MASK)
-#define MAC_PCU_BLUETOOTH_MODE3_WL_ACTIVE_TIME_MSB 7
-#define MAC_PCU_BLUETOOTH_MODE3_WL_ACTIVE_TIME_LSB 0
-#define MAC_PCU_BLUETOOTH_MODE3_WL_ACTIVE_TIME_MASK 0x000000ff
-#define MAC_PCU_BLUETOOTH_MODE3_WL_ACTIVE_TIME_GET(x) (((x) & MAC_PCU_BLUETOOTH_MODE3_WL_ACTIVE_TIME_MASK) >> MAC_PCU_BLUETOOTH_MODE3_WL_ACTIVE_TIME_LSB)
-#define MAC_PCU_BLUETOOTH_MODE3_WL_ACTIVE_TIME_SET(x) (((x) << MAC_PCU_BLUETOOTH_MODE3_WL_ACTIVE_TIME_LSB) & MAC_PCU_BLUETOOTH_MODE3_WL_ACTIVE_TIME_MASK)
-
-#define MAC_PCU_BLUETOOTH_MODE4_ADDRESS          0x00008168
-#define MAC_PCU_BLUETOOTH_MODE4_OFFSET           0x00000168
-#define MAC_PCU_BLUETOOTH_MODE4_BT_PRIORITY_EXTEND_MSB 31
-#define MAC_PCU_BLUETOOTH_MODE4_BT_PRIORITY_EXTEND_LSB 16
-#define MAC_PCU_BLUETOOTH_MODE4_BT_PRIORITY_EXTEND_MASK 0xffff0000
-#define MAC_PCU_BLUETOOTH_MODE4_BT_PRIORITY_EXTEND_GET(x) (((x) & MAC_PCU_BLUETOOTH_MODE4_BT_PRIORITY_EXTEND_MASK) >> MAC_PCU_BLUETOOTH_MODE4_BT_PRIORITY_EXTEND_LSB)
-#define MAC_PCU_BLUETOOTH_MODE4_BT_PRIORITY_EXTEND_SET(x) (((x) << MAC_PCU_BLUETOOTH_MODE4_BT_PRIORITY_EXTEND_LSB) & MAC_PCU_BLUETOOTH_MODE4_BT_PRIORITY_EXTEND_MASK)
-#define MAC_PCU_BLUETOOTH_MODE4_BT_ACTIVE_EXTEND_MSB 15
-#define MAC_PCU_BLUETOOTH_MODE4_BT_ACTIVE_EXTEND_LSB 0
-#define MAC_PCU_BLUETOOTH_MODE4_BT_ACTIVE_EXTEND_MASK 0x0000ffff
-#define MAC_PCU_BLUETOOTH_MODE4_BT_ACTIVE_EXTEND_GET(x) (((x) & MAC_PCU_BLUETOOTH_MODE4_BT_ACTIVE_EXTEND_MASK) >> MAC_PCU_BLUETOOTH_MODE4_BT_ACTIVE_EXTEND_LSB)
-#define MAC_PCU_BLUETOOTH_MODE4_BT_ACTIVE_EXTEND_SET(x) (((x) << MAC_PCU_BLUETOOTH_MODE4_BT_ACTIVE_EXTEND_LSB) & MAC_PCU_BLUETOOTH_MODE4_BT_ACTIVE_EXTEND_MASK)
-
-#define MAC_PCU_BT_BT_ADDRESS                    0x00008200
-#define MAC_PCU_BT_BT_OFFSET                     0x00000200
-#define MAC_PCU_BT_BT_WEIGHT_MSB                 31
-#define MAC_PCU_BT_BT_WEIGHT_LSB                 0
-#define MAC_PCU_BT_BT_WEIGHT_MASK                0xffffffff
-#define MAC_PCU_BT_BT_WEIGHT_GET(x)              (((x) & MAC_PCU_BT_BT_WEIGHT_MASK) >> MAC_PCU_BT_BT_WEIGHT_LSB)
-#define MAC_PCU_BT_BT_WEIGHT_SET(x)              (((x) << MAC_PCU_BT_BT_WEIGHT_LSB) & MAC_PCU_BT_BT_WEIGHT_MASK)
-
-#define MAC_PCU_BT_BT_ASYNC_ADDRESS              0x00008300
-#define MAC_PCU_BT_BT_ASYNC_OFFSET               0x00000300
-#define MAC_PCU_BT_BT_ASYNC_RXLP_WEIGHT_MSB      15
-#define MAC_PCU_BT_BT_ASYNC_RXLP_WEIGHT_LSB      12
-#define MAC_PCU_BT_BT_ASYNC_RXLP_WEIGHT_MASK     0x0000f000
-#define MAC_PCU_BT_BT_ASYNC_RXLP_WEIGHT_GET(x)   (((x) & MAC_PCU_BT_BT_ASYNC_RXLP_WEIGHT_MASK) >> MAC_PCU_BT_BT_ASYNC_RXLP_WEIGHT_LSB)
-#define MAC_PCU_BT_BT_ASYNC_RXLP_WEIGHT_SET(x)   (((x) << MAC_PCU_BT_BT_ASYNC_RXLP_WEIGHT_LSB) & MAC_PCU_BT_BT_ASYNC_RXLP_WEIGHT_MASK)
-#define MAC_PCU_BT_BT_ASYNC_RXHP_WEIGHT_MSB      11
-#define MAC_PCU_BT_BT_ASYNC_RXHP_WEIGHT_LSB      8
-#define MAC_PCU_BT_BT_ASYNC_RXHP_WEIGHT_MASK     0x00000f00
-#define MAC_PCU_BT_BT_ASYNC_RXHP_WEIGHT_GET(x)   (((x) & MAC_PCU_BT_BT_ASYNC_RXHP_WEIGHT_MASK) >> MAC_PCU_BT_BT_ASYNC_RXHP_WEIGHT_LSB)
-#define MAC_PCU_BT_BT_ASYNC_RXHP_WEIGHT_SET(x)   (((x) << MAC_PCU_BT_BT_ASYNC_RXHP_WEIGHT_LSB) & MAC_PCU_BT_BT_ASYNC_RXHP_WEIGHT_MASK)
-#define MAC_PCU_BT_BT_ASYNC_TXLP_WEIGHT_MSB      7
-#define MAC_PCU_BT_BT_ASYNC_TXLP_WEIGHT_LSB      4
-#define MAC_PCU_BT_BT_ASYNC_TXLP_WEIGHT_MASK     0x000000f0
-#define MAC_PCU_BT_BT_ASYNC_TXLP_WEIGHT_GET(x)   (((x) & MAC_PCU_BT_BT_ASYNC_TXLP_WEIGHT_MASK) >> MAC_PCU_BT_BT_ASYNC_TXLP_WEIGHT_LSB)
-#define MAC_PCU_BT_BT_ASYNC_TXLP_WEIGHT_SET(x)   (((x) << MAC_PCU_BT_BT_ASYNC_TXLP_WEIGHT_LSB) & MAC_PCU_BT_BT_ASYNC_TXLP_WEIGHT_MASK)
-#define MAC_PCU_BT_BT_ASYNC_TXHP_WEIGHT_MSB      3
-#define MAC_PCU_BT_BT_ASYNC_TXHP_WEIGHT_LSB      0
-#define MAC_PCU_BT_BT_ASYNC_TXHP_WEIGHT_MASK     0x0000000f
-#define MAC_PCU_BT_BT_ASYNC_TXHP_WEIGHT_GET(x)   (((x) & MAC_PCU_BT_BT_ASYNC_TXHP_WEIGHT_MASK) >> MAC_PCU_BT_BT_ASYNC_TXHP_WEIGHT_LSB)
-#define MAC_PCU_BT_BT_ASYNC_TXHP_WEIGHT_SET(x)   (((x) << MAC_PCU_BT_BT_ASYNC_TXHP_WEIGHT_LSB) & MAC_PCU_BT_BT_ASYNC_TXHP_WEIGHT_MASK)
-
-#define MAC_PCU_BT_WL_1_ADDRESS                  0x00008304
-#define MAC_PCU_BT_WL_1_OFFSET                   0x00000304
-#define MAC_PCU_BT_WL_1_WEIGHT_MSB               31
-#define MAC_PCU_BT_WL_1_WEIGHT_LSB               0
-#define MAC_PCU_BT_WL_1_WEIGHT_MASK              0xffffffff
-#define MAC_PCU_BT_WL_1_WEIGHT_GET(x)            (((x) & MAC_PCU_BT_WL_1_WEIGHT_MASK) >> MAC_PCU_BT_WL_1_WEIGHT_LSB)
-#define MAC_PCU_BT_WL_1_WEIGHT_SET(x)            (((x) << MAC_PCU_BT_WL_1_WEIGHT_LSB) & MAC_PCU_BT_WL_1_WEIGHT_MASK)
-
-#define MAC_PCU_BT_WL_2_ADDRESS                  0x00008308
-#define MAC_PCU_BT_WL_2_OFFSET                   0x00000308
-#define MAC_PCU_BT_WL_2_WEIGHT_MSB               31
-#define MAC_PCU_BT_WL_2_WEIGHT_LSB               0
-#define MAC_PCU_BT_WL_2_WEIGHT_MASK              0xffffffff
-#define MAC_PCU_BT_WL_2_WEIGHT_GET(x)            (((x) & MAC_PCU_BT_WL_2_WEIGHT_MASK) >> MAC_PCU_BT_WL_2_WEIGHT_LSB)
-#define MAC_PCU_BT_WL_2_WEIGHT_SET(x)            (((x) << MAC_PCU_BT_WL_2_WEIGHT_LSB) & MAC_PCU_BT_WL_2_WEIGHT_MASK)
-
-#define MAC_PCU_BT_WL_3_ADDRESS                  0x0000830c
-#define MAC_PCU_BT_WL_3_OFFSET                   0x0000030c
-#define MAC_PCU_BT_WL_3_WEIGHT_MSB               31
-#define MAC_PCU_BT_WL_3_WEIGHT_LSB               0
-#define MAC_PCU_BT_WL_3_WEIGHT_MASK              0xffffffff
-#define MAC_PCU_BT_WL_3_WEIGHT_GET(x)            (((x) & MAC_PCU_BT_WL_3_WEIGHT_MASK) >> MAC_PCU_BT_WL_3_WEIGHT_LSB)
-#define MAC_PCU_BT_WL_3_WEIGHT_SET(x)            (((x) << MAC_PCU_BT_WL_3_WEIGHT_LSB) & MAC_PCU_BT_WL_3_WEIGHT_MASK)
-
-#define MAC_PCU_BT_WL_4_ADDRESS                  0x00008310
-#define MAC_PCU_BT_WL_4_OFFSET                   0x00000310
-#define MAC_PCU_BT_WL_4_WEIGHT_MSB               31
-#define MAC_PCU_BT_WL_4_WEIGHT_LSB               0
-#define MAC_PCU_BT_WL_4_WEIGHT_MASK              0xffffffff
-#define MAC_PCU_BT_WL_4_WEIGHT_GET(x)            (((x) & MAC_PCU_BT_WL_4_WEIGHT_MASK) >> MAC_PCU_BT_WL_4_WEIGHT_LSB)
-#define MAC_PCU_BT_WL_4_WEIGHT_SET(x)            (((x) << MAC_PCU_BT_WL_4_WEIGHT_LSB) & MAC_PCU_BT_WL_4_WEIGHT_MASK)
-
-#define MAC_PCU_COEX_EPTA_ADDRESS                0x00008314
-#define MAC_PCU_COEX_EPTA_OFFSET                 0x00000314
-#define MAC_PCU_COEX_EPTA_WT_IDX_MSB             12
-#define MAC_PCU_COEX_EPTA_WT_IDX_LSB             6
-#define MAC_PCU_COEX_EPTA_WT_IDX_MASK            0x00001fc0
-#define MAC_PCU_COEX_EPTA_WT_IDX_GET(x)          (((x) & MAC_PCU_COEX_EPTA_WT_IDX_MASK) >> MAC_PCU_COEX_EPTA_WT_IDX_LSB)
-#define MAC_PCU_COEX_EPTA_WT_IDX_SET(x)          (((x) << MAC_PCU_COEX_EPTA_WT_IDX_LSB) & MAC_PCU_COEX_EPTA_WT_IDX_MASK)
-#define MAC_PCU_COEX_EPTA_LINKID_MSB             5
-#define MAC_PCU_COEX_EPTA_LINKID_LSB             0
-#define MAC_PCU_COEX_EPTA_LINKID_MASK            0x0000003f
-#define MAC_PCU_COEX_EPTA_LINKID_GET(x)          (((x) & MAC_PCU_COEX_EPTA_LINKID_MASK) >> MAC_PCU_COEX_EPTA_LINKID_LSB)
-#define MAC_PCU_COEX_EPTA_LINKID_SET(x)          (((x) << MAC_PCU_COEX_EPTA_LINKID_LSB) & MAC_PCU_COEX_EPTA_LINKID_MASK)
-
-#define MAC_PCU_COEX_LNAMAXGAIN1_ADDRESS         0x00008318
-#define MAC_PCU_COEX_LNAMAXGAIN1_OFFSET          0x00000318
-#define MAC_PCU_COEX_LNAMAXGAIN1_MAXGAIN4_MSB    31
-#define MAC_PCU_COEX_LNAMAXGAIN1_MAXGAIN4_LSB    24
-#define MAC_PCU_COEX_LNAMAXGAIN1_MAXGAIN4_MASK   0xff000000
-#define MAC_PCU_COEX_LNAMAXGAIN1_MAXGAIN4_GET(x) (((x) & MAC_PCU_COEX_LNAMAXGAIN1_MAXGAIN4_MASK) >> MAC_PCU_COEX_LNAMAXGAIN1_MAXGAIN4_LSB)
-#define MAC_PCU_COEX_LNAMAXGAIN1_MAXGAIN4_SET(x) (((x) << MAC_PCU_COEX_LNAMAXGAIN1_MAXGAIN4_LSB) & MAC_PCU_COEX_LNAMAXGAIN1_MAXGAIN4_MASK)
-#define MAC_PCU_COEX_LNAMAXGAIN1_MAXGAIN3_MSB    23
-#define MAC_PCU_COEX_LNAMAXGAIN1_MAXGAIN3_LSB    16
-#define MAC_PCU_COEX_LNAMAXGAIN1_MAXGAIN3_MASK   0x00ff0000
-#define MAC_PCU_COEX_LNAMAXGAIN1_MAXGAIN3_GET(x) (((x) & MAC_PCU_COEX_LNAMAXGAIN1_MAXGAIN3_MASK) >> MAC_PCU_COEX_LNAMAXGAIN1_MAXGAIN3_LSB)
-#define MAC_PCU_COEX_LNAMAXGAIN1_MAXGAIN3_SET(x) (((x) << MAC_PCU_COEX_LNAMAXGAIN1_MAXGAIN3_LSB) & MAC_PCU_COEX_LNAMAXGAIN1_MAXGAIN3_MASK)
-#define MAC_PCU_COEX_LNAMAXGAIN1_MAXGAIN2_MSB    15
-#define MAC_PCU_COEX_LNAMAXGAIN1_MAXGAIN2_LSB    8
-#define MAC_PCU_COEX_LNAMAXGAIN1_MAXGAIN2_MASK   0x0000ff00
-#define MAC_PCU_COEX_LNAMAXGAIN1_MAXGAIN2_GET(x) (((x) & MAC_PCU_COEX_LNAMAXGAIN1_MAXGAIN2_MASK) >> MAC_PCU_COEX_LNAMAXGAIN1_MAXGAIN2_LSB)
-#define MAC_PCU_COEX_LNAMAXGAIN1_MAXGAIN2_SET(x) (((x) << MAC_PCU_COEX_LNAMAXGAIN1_MAXGAIN2_LSB) & MAC_PCU_COEX_LNAMAXGAIN1_MAXGAIN2_MASK)
-#define MAC_PCU_COEX_LNAMAXGAIN1_MAXGAIN1_MSB    7
-#define MAC_PCU_COEX_LNAMAXGAIN1_MAXGAIN1_LSB    0
-#define MAC_PCU_COEX_LNAMAXGAIN1_MAXGAIN1_MASK   0x000000ff
-#define MAC_PCU_COEX_LNAMAXGAIN1_MAXGAIN1_GET(x) (((x) & MAC_PCU_COEX_LNAMAXGAIN1_MAXGAIN1_MASK) >> MAC_PCU_COEX_LNAMAXGAIN1_MAXGAIN1_LSB)
-#define MAC_PCU_COEX_LNAMAXGAIN1_MAXGAIN1_SET(x) (((x) << MAC_PCU_COEX_LNAMAXGAIN1_MAXGAIN1_LSB) & MAC_PCU_COEX_LNAMAXGAIN1_MAXGAIN1_MASK)
-
-#define MAC_PCU_COEX_LNAMAXGAIN2_ADDRESS         0x0000831c
-#define MAC_PCU_COEX_LNAMAXGAIN2_OFFSET          0x0000031c
-#define MAC_PCU_COEX_LNAMAXGAIN2_MAXGAIN4_MSB    31
-#define MAC_PCU_COEX_LNAMAXGAIN2_MAXGAIN4_LSB    24
-#define MAC_PCU_COEX_LNAMAXGAIN2_MAXGAIN4_MASK   0xff000000
-#define MAC_PCU_COEX_LNAMAXGAIN2_MAXGAIN4_GET(x) (((x) & MAC_PCU_COEX_LNAMAXGAIN2_MAXGAIN4_MASK) >> MAC_PCU_COEX_LNAMAXGAIN2_MAXGAIN4_LSB)
-#define MAC_PCU_COEX_LNAMAXGAIN2_MAXGAIN4_SET(x) (((x) << MAC_PCU_COEX_LNAMAXGAIN2_MAXGAIN4_LSB) & MAC_PCU_COEX_LNAMAXGAIN2_MAXGAIN4_MASK)
-#define MAC_PCU_COEX_LNAMAXGAIN2_MAXGAIN3_MSB    23
-#define MAC_PCU_COEX_LNAMAXGAIN2_MAXGAIN3_LSB    16
-#define MAC_PCU_COEX_LNAMAXGAIN2_MAXGAIN3_MASK   0x00ff0000
-#define MAC_PCU_COEX_LNAMAXGAIN2_MAXGAIN3_GET(x) (((x) & MAC_PCU_COEX_LNAMAXGAIN2_MAXGAIN3_MASK) >> MAC_PCU_COEX_LNAMAXGAIN2_MAXGAIN3_LSB)
-#define MAC_PCU_COEX_LNAMAXGAIN2_MAXGAIN3_SET(x) (((x) << MAC_PCU_COEX_LNAMAXGAIN2_MAXGAIN3_LSB) & MAC_PCU_COEX_LNAMAXGAIN2_MAXGAIN3_MASK)
-#define MAC_PCU_COEX_LNAMAXGAIN2_MAXGAIN2_MSB    15
-#define MAC_PCU_COEX_LNAMAXGAIN2_MAXGAIN2_LSB    8
-#define MAC_PCU_COEX_LNAMAXGAIN2_MAXGAIN2_MASK   0x0000ff00
-#define MAC_PCU_COEX_LNAMAXGAIN2_MAXGAIN2_GET(x) (((x) & MAC_PCU_COEX_LNAMAXGAIN2_MAXGAIN2_MASK) >> MAC_PCU_COEX_LNAMAXGAIN2_MAXGAIN2_LSB)
-#define MAC_PCU_COEX_LNAMAXGAIN2_MAXGAIN2_SET(x) (((x) << MAC_PCU_COEX_LNAMAXGAIN2_MAXGAIN2_LSB) & MAC_PCU_COEX_LNAMAXGAIN2_MAXGAIN2_MASK)
-#define MAC_PCU_COEX_LNAMAXGAIN2_MAXGAIN1_MSB    7
-#define MAC_PCU_COEX_LNAMAXGAIN2_MAXGAIN1_LSB    0
-#define MAC_PCU_COEX_LNAMAXGAIN2_MAXGAIN1_MASK   0x000000ff
-#define MAC_PCU_COEX_LNAMAXGAIN2_MAXGAIN1_GET(x) (((x) & MAC_PCU_COEX_LNAMAXGAIN2_MAXGAIN1_MASK) >> MAC_PCU_COEX_LNAMAXGAIN2_MAXGAIN1_LSB)
-#define MAC_PCU_COEX_LNAMAXGAIN2_MAXGAIN1_SET(x) (((x) << MAC_PCU_COEX_LNAMAXGAIN2_MAXGAIN1_LSB) & MAC_PCU_COEX_LNAMAXGAIN2_MAXGAIN1_MASK)
-
-#define MAC_PCU_COEX_LNAMAXGAIN3_ADDRESS         0x00008320
-#define MAC_PCU_COEX_LNAMAXGAIN3_OFFSET          0x00000320
-#define MAC_PCU_COEX_LNAMAXGAIN3_MAXGAIN4_MSB    31
-#define MAC_PCU_COEX_LNAMAXGAIN3_MAXGAIN4_LSB    24
-#define MAC_PCU_COEX_LNAMAXGAIN3_MAXGAIN4_MASK   0xff000000
-#define MAC_PCU_COEX_LNAMAXGAIN3_MAXGAIN4_GET(x) (((x) & MAC_PCU_COEX_LNAMAXGAIN3_MAXGAIN4_MASK) >> MAC_PCU_COEX_LNAMAXGAIN3_MAXGAIN4_LSB)
-#define MAC_PCU_COEX_LNAMAXGAIN3_MAXGAIN4_SET(x) (((x) << MAC_PCU_COEX_LNAMAXGAIN3_MAXGAIN4_LSB) & MAC_PCU_COEX_LNAMAXGAIN3_MAXGAIN4_MASK)
-#define MAC_PCU_COEX_LNAMAXGAIN3_MAXGAIN3_MSB    23
-#define MAC_PCU_COEX_LNAMAXGAIN3_MAXGAIN3_LSB    16
-#define MAC_PCU_COEX_LNAMAXGAIN3_MAXGAIN3_MASK   0x00ff0000
-#define MAC_PCU_COEX_LNAMAXGAIN3_MAXGAIN3_GET(x) (((x) & MAC_PCU_COEX_LNAMAXGAIN3_MAXGAIN3_MASK) >> MAC_PCU_COEX_LNAMAXGAIN3_MAXGAIN3_LSB)
-#define MAC_PCU_COEX_LNAMAXGAIN3_MAXGAIN3_SET(x) (((x) << MAC_PCU_COEX_LNAMAXGAIN3_MAXGAIN3_LSB) & MAC_PCU_COEX_LNAMAXGAIN3_MAXGAIN3_MASK)
-#define MAC_PCU_COEX_LNAMAXGAIN3_MAXGAIN2_MSB    15
-#define MAC_PCU_COEX_LNAMAXGAIN3_MAXGAIN2_LSB    8
-#define MAC_PCU_COEX_LNAMAXGAIN3_MAXGAIN2_MASK   0x0000ff00
-#define MAC_PCU_COEX_LNAMAXGAIN3_MAXGAIN2_GET(x) (((x) & MAC_PCU_COEX_LNAMAXGAIN3_MAXGAIN2_MASK) >> MAC_PCU_COEX_LNAMAXGAIN3_MAXGAIN2_LSB)
-#define MAC_PCU_COEX_LNAMAXGAIN3_MAXGAIN2_SET(x) (((x) << MAC_PCU_COEX_LNAMAXGAIN3_MAXGAIN2_LSB) & MAC_PCU_COEX_LNAMAXGAIN3_MAXGAIN2_MASK)
-#define MAC_PCU_COEX_LNAMAXGAIN3_MAXGAIN1_MSB    7
-#define MAC_PCU_COEX_LNAMAXGAIN3_MAXGAIN1_LSB    0
-#define MAC_PCU_COEX_LNAMAXGAIN3_MAXGAIN1_MASK   0x000000ff
-#define MAC_PCU_COEX_LNAMAXGAIN3_MAXGAIN1_GET(x) (((x) & MAC_PCU_COEX_LNAMAXGAIN3_MAXGAIN1_MASK) >> MAC_PCU_COEX_LNAMAXGAIN3_MAXGAIN1_LSB)
-#define MAC_PCU_COEX_LNAMAXGAIN3_MAXGAIN1_SET(x) (((x) << MAC_PCU_COEX_LNAMAXGAIN3_MAXGAIN1_LSB) & MAC_PCU_COEX_LNAMAXGAIN3_MAXGAIN1_MASK)
-
-#define MAC_PCU_COEX_LNAMAXGAIN4_ADDRESS         0x00008324
-#define MAC_PCU_COEX_LNAMAXGAIN4_OFFSET          0x00000324
-#define MAC_PCU_COEX_LNAMAXGAIN4_MAXGAIN4_MSB    31
-#define MAC_PCU_COEX_LNAMAXGAIN4_MAXGAIN4_LSB    24
-#define MAC_PCU_COEX_LNAMAXGAIN4_MAXGAIN4_MASK   0xff000000
-#define MAC_PCU_COEX_LNAMAXGAIN4_MAXGAIN4_GET(x) (((x) & MAC_PCU_COEX_LNAMAXGAIN4_MAXGAIN4_MASK) >> MAC_PCU_COEX_LNAMAXGAIN4_MAXGAIN4_LSB)
-#define MAC_PCU_COEX_LNAMAXGAIN4_MAXGAIN4_SET(x) (((x) << MAC_PCU_COEX_LNAMAXGAIN4_MAXGAIN4_LSB) & MAC_PCU_COEX_LNAMAXGAIN4_MAXGAIN4_MASK)
-#define MAC_PCU_COEX_LNAMAXGAIN4_MAXGAIN3_MSB    23
-#define MAC_PCU_COEX_LNAMAXGAIN4_MAXGAIN3_LSB    16
-#define MAC_PCU_COEX_LNAMAXGAIN4_MAXGAIN3_MASK   0x00ff0000
-#define MAC_PCU_COEX_LNAMAXGAIN4_MAXGAIN3_GET(x) (((x) & MAC_PCU_COEX_LNAMAXGAIN4_MAXGAIN3_MASK) >> MAC_PCU_COEX_LNAMAXGAIN4_MAXGAIN3_LSB)
-#define MAC_PCU_COEX_LNAMAXGAIN4_MAXGAIN3_SET(x) (((x) << MAC_PCU_COEX_LNAMAXGAIN4_MAXGAIN3_LSB) & MAC_PCU_COEX_LNAMAXGAIN4_MAXGAIN3_MASK)
-#define MAC_PCU_COEX_LNAMAXGAIN4_MAXGAIN2_MSB    15
-#define MAC_PCU_COEX_LNAMAXGAIN4_MAXGAIN2_LSB    8
-#define MAC_PCU_COEX_LNAMAXGAIN4_MAXGAIN2_MASK   0x0000ff00
-#define MAC_PCU_COEX_LNAMAXGAIN4_MAXGAIN2_GET(x) (((x) & MAC_PCU_COEX_LNAMAXGAIN4_MAXGAIN2_MASK) >> MAC_PCU_COEX_LNAMAXGAIN4_MAXGAIN2_LSB)
-#define MAC_PCU_COEX_LNAMAXGAIN4_MAXGAIN2_SET(x) (((x) << MAC_PCU_COEX_LNAMAXGAIN4_MAXGAIN2_LSB) & MAC_PCU_COEX_LNAMAXGAIN4_MAXGAIN2_MASK)
-#define MAC_PCU_COEX_LNAMAXGAIN4_MAXGAIN1_MSB    7
-#define MAC_PCU_COEX_LNAMAXGAIN4_MAXGAIN1_LSB    0
-#define MAC_PCU_COEX_LNAMAXGAIN4_MAXGAIN1_MASK   0x000000ff
-#define MAC_PCU_COEX_LNAMAXGAIN4_MAXGAIN1_GET(x) (((x) & MAC_PCU_COEX_LNAMAXGAIN4_MAXGAIN1_MASK) >> MAC_PCU_COEX_LNAMAXGAIN4_MAXGAIN1_LSB)
-#define MAC_PCU_COEX_LNAMAXGAIN4_MAXGAIN1_SET(x) (((x) << MAC_PCU_COEX_LNAMAXGAIN4_MAXGAIN1_LSB) & MAC_PCU_COEX_LNAMAXGAIN4_MAXGAIN1_MASK)
-
-#define MAC_PCU_BASIC_RATE_SET0_ADDRESS          0x00008328
-#define MAC_PCU_BASIC_RATE_SET0_OFFSET           0x00000328
-#define MAC_PCU_BASIC_RATE_SET0_VALUE_MSB        29
-#define MAC_PCU_BASIC_RATE_SET0_VALUE_LSB        0
-#define MAC_PCU_BASIC_RATE_SET0_VALUE_MASK       0x3fffffff
-#define MAC_PCU_BASIC_RATE_SET0_VALUE_GET(x)     (((x) & MAC_PCU_BASIC_RATE_SET0_VALUE_MASK) >> MAC_PCU_BASIC_RATE_SET0_VALUE_LSB)
-#define MAC_PCU_BASIC_RATE_SET0_VALUE_SET(x)     (((x) << MAC_PCU_BASIC_RATE_SET0_VALUE_LSB) & MAC_PCU_BASIC_RATE_SET0_VALUE_MASK)
-
-#define MAC_PCU_BASIC_RATE_SET1_ADDRESS          0x0000832c
-#define MAC_PCU_BASIC_RATE_SET1_OFFSET           0x0000032c
-#define MAC_PCU_BASIC_RATE_SET1_VALUE_MSB        29
-#define MAC_PCU_BASIC_RATE_SET1_VALUE_LSB        0
-#define MAC_PCU_BASIC_RATE_SET1_VALUE_MASK       0x3fffffff
-#define MAC_PCU_BASIC_RATE_SET1_VALUE_GET(x)     (((x) & MAC_PCU_BASIC_RATE_SET1_VALUE_MASK) >> MAC_PCU_BASIC_RATE_SET1_VALUE_LSB)
-#define MAC_PCU_BASIC_RATE_SET1_VALUE_SET(x)     (((x) << MAC_PCU_BASIC_RATE_SET1_VALUE_LSB) & MAC_PCU_BASIC_RATE_SET1_VALUE_MASK)
-
-#define MAC_PCU_BASIC_RATE_SET2_ADDRESS          0x00008330
-#define MAC_PCU_BASIC_RATE_SET2_OFFSET           0x00000330
-#define MAC_PCU_BASIC_RATE_SET2_VALUE_MSB        29
-#define MAC_PCU_BASIC_RATE_SET2_VALUE_LSB        0
-#define MAC_PCU_BASIC_RATE_SET2_VALUE_MASK       0x3fffffff
-#define MAC_PCU_BASIC_RATE_SET2_VALUE_GET(x)     (((x) & MAC_PCU_BASIC_RATE_SET2_VALUE_MASK) >> MAC_PCU_BASIC_RATE_SET2_VALUE_LSB)
-#define MAC_PCU_BASIC_RATE_SET2_VALUE_SET(x)     (((x) << MAC_PCU_BASIC_RATE_SET2_VALUE_LSB) & MAC_PCU_BASIC_RATE_SET2_VALUE_MASK)
-
-#define MAC_PCU_BASIC_RATE_SET3_ADDRESS          0x00008334
-#define MAC_PCU_BASIC_RATE_SET3_OFFSET           0x00000334
-#define MAC_PCU_BASIC_RATE_SET3_VALUE_MSB        24
-#define MAC_PCU_BASIC_RATE_SET3_VALUE_LSB        0
-#define MAC_PCU_BASIC_RATE_SET3_VALUE_MASK       0x01ffffff
-#define MAC_PCU_BASIC_RATE_SET3_VALUE_GET(x)     (((x) & MAC_PCU_BASIC_RATE_SET3_VALUE_MASK) >> MAC_PCU_BASIC_RATE_SET3_VALUE_LSB)
-#define MAC_PCU_BASIC_RATE_SET3_VALUE_SET(x)     (((x) << MAC_PCU_BASIC_RATE_SET3_VALUE_LSB) & MAC_PCU_BASIC_RATE_SET3_VALUE_MASK)
-
-#define MAC_PCU_RX_INT_STATUS0_ADDRESS           0x00008338
-#define MAC_PCU_RX_INT_STATUS0_OFFSET            0x00000338
-#define MAC_PCU_RX_INT_STATUS0_DURATION_H_MSB    31
-#define MAC_PCU_RX_INT_STATUS0_DURATION_H_LSB    24
-#define MAC_PCU_RX_INT_STATUS0_DURATION_H_MASK   0xff000000
-#define MAC_PCU_RX_INT_STATUS0_DURATION_H_GET(x) (((x) & MAC_PCU_RX_INT_STATUS0_DURATION_H_MASK) >> MAC_PCU_RX_INT_STATUS0_DURATION_H_LSB)
-#define MAC_PCU_RX_INT_STATUS0_DURATION_H_SET(x) (((x) << MAC_PCU_RX_INT_STATUS0_DURATION_H_LSB) & MAC_PCU_RX_INT_STATUS0_DURATION_H_MASK)
-#define MAC_PCU_RX_INT_STATUS0_DURATION_L_MSB    23
-#define MAC_PCU_RX_INT_STATUS0_DURATION_L_LSB    16
-#define MAC_PCU_RX_INT_STATUS0_DURATION_L_MASK   0x00ff0000
-#define MAC_PCU_RX_INT_STATUS0_DURATION_L_GET(x) (((x) & MAC_PCU_RX_INT_STATUS0_DURATION_L_MASK) >> MAC_PCU_RX_INT_STATUS0_DURATION_L_LSB)
-#define MAC_PCU_RX_INT_STATUS0_DURATION_L_SET(x) (((x) << MAC_PCU_RX_INT_STATUS0_DURATION_L_LSB) & MAC_PCU_RX_INT_STATUS0_DURATION_L_MASK)
-#define MAC_PCU_RX_INT_STATUS0_FRAME_CONTROL_H_MSB 15
-#define MAC_PCU_RX_INT_STATUS0_FRAME_CONTROL_H_LSB 8
-#define MAC_PCU_RX_INT_STATUS0_FRAME_CONTROL_H_MASK 0x0000ff00
-#define MAC_PCU_RX_INT_STATUS0_FRAME_CONTROL_H_GET(x) (((x) & MAC_PCU_RX_INT_STATUS0_FRAME_CONTROL_H_MASK) >> MAC_PCU_RX_INT_STATUS0_FRAME_CONTROL_H_LSB)
-#define MAC_PCU_RX_INT_STATUS0_FRAME_CONTROL_H_SET(x) (((x) << MAC_PCU_RX_INT_STATUS0_FRAME_CONTROL_H_LSB) & MAC_PCU_RX_INT_STATUS0_FRAME_CONTROL_H_MASK)
-#define MAC_PCU_RX_INT_STATUS0_FRAME_CONTROL_L_MSB 7
-#define MAC_PCU_RX_INT_STATUS0_FRAME_CONTROL_L_LSB 0
-#define MAC_PCU_RX_INT_STATUS0_FRAME_CONTROL_L_MASK 0x000000ff
-#define MAC_PCU_RX_INT_STATUS0_FRAME_CONTROL_L_GET(x) (((x) & MAC_PCU_RX_INT_STATUS0_FRAME_CONTROL_L_MASK) >> MAC_PCU_RX_INT_STATUS0_FRAME_CONTROL_L_LSB)
-#define MAC_PCU_RX_INT_STATUS0_FRAME_CONTROL_L_SET(x) (((x) << MAC_PCU_RX_INT_STATUS0_FRAME_CONTROL_L_LSB) & MAC_PCU_RX_INT_STATUS0_FRAME_CONTROL_L_MASK)
-
-#define MAC_PCU_RX_INT_STATUS1_ADDRESS           0x0000833c
-#define MAC_PCU_RX_INT_STATUS1_OFFSET            0x0000033c
-#define MAC_PCU_RX_INT_STATUS1_VALUE_MSB         17
-#define MAC_PCU_RX_INT_STATUS1_VALUE_LSB         0
-#define MAC_PCU_RX_INT_STATUS1_VALUE_MASK        0x0003ffff
-#define MAC_PCU_RX_INT_STATUS1_VALUE_GET(x)      (((x) & MAC_PCU_RX_INT_STATUS1_VALUE_MASK) >> MAC_PCU_RX_INT_STATUS1_VALUE_LSB)
-#define MAC_PCU_RX_INT_STATUS1_VALUE_SET(x)      (((x) << MAC_PCU_RX_INT_STATUS1_VALUE_LSB) & MAC_PCU_RX_INT_STATUS1_VALUE_MASK)
-
-#define MAC_PCU_RX_INT_STATUS2_ADDRESS           0x00008340
-#define MAC_PCU_RX_INT_STATUS2_OFFSET            0x00000340
-#define MAC_PCU_RX_INT_STATUS2_VALUE_MSB         26
-#define MAC_PCU_RX_INT_STATUS2_VALUE_LSB         0
-#define MAC_PCU_RX_INT_STATUS2_VALUE_MASK        0x07ffffff
-#define MAC_PCU_RX_INT_STATUS2_VALUE_GET(x)      (((x) & MAC_PCU_RX_INT_STATUS2_VALUE_MASK) >> MAC_PCU_RX_INT_STATUS2_VALUE_LSB)
-#define MAC_PCU_RX_INT_STATUS2_VALUE_SET(x)      (((x) << MAC_PCU_RX_INT_STATUS2_VALUE_LSB) & MAC_PCU_RX_INT_STATUS2_VALUE_MASK)
-
-#define MAC_PCU_RX_INT_STATUS3_ADDRESS           0x00008344
-#define MAC_PCU_RX_INT_STATUS3_OFFSET            0x00000344
-#define MAC_PCU_RX_INT_STATUS3_VALUE_MSB         23
-#define MAC_PCU_RX_INT_STATUS3_VALUE_LSB         0
-#define MAC_PCU_RX_INT_STATUS3_VALUE_MASK        0x00ffffff
-#define MAC_PCU_RX_INT_STATUS3_VALUE_GET(x)      (((x) & MAC_PCU_RX_INT_STATUS3_VALUE_MASK) >> MAC_PCU_RX_INT_STATUS3_VALUE_LSB)
-#define MAC_PCU_RX_INT_STATUS3_VALUE_SET(x)      (((x) << MAC_PCU_RX_INT_STATUS3_VALUE_LSB) & MAC_PCU_RX_INT_STATUS3_VALUE_MASK)
-
-#define HT_HALF_GI_RATE1_ADDRESS                 0x00008348
-#define HT_HALF_GI_RATE1_OFFSET                  0x00000348
-#define HT_HALF_GI_RATE1_MCS3_MSB                31
-#define HT_HALF_GI_RATE1_MCS3_LSB                24
-#define HT_HALF_GI_RATE1_MCS3_MASK               0xff000000
-#define HT_HALF_GI_RATE1_MCS3_GET(x)             (((x) & HT_HALF_GI_RATE1_MCS3_MASK) >> HT_HALF_GI_RATE1_MCS3_LSB)
-#define HT_HALF_GI_RATE1_MCS3_SET(x)             (((x) << HT_HALF_GI_RATE1_MCS3_LSB) & HT_HALF_GI_RATE1_MCS3_MASK)
-#define HT_HALF_GI_RATE1_MCS2_MSB                23
-#define HT_HALF_GI_RATE1_MCS2_LSB                16
-#define HT_HALF_GI_RATE1_MCS2_MASK               0x00ff0000
-#define HT_HALF_GI_RATE1_MCS2_GET(x)             (((x) & HT_HALF_GI_RATE1_MCS2_MASK) >> HT_HALF_GI_RATE1_MCS2_LSB)
-#define HT_HALF_GI_RATE1_MCS2_SET(x)             (((x) << HT_HALF_GI_RATE1_MCS2_LSB) & HT_HALF_GI_RATE1_MCS2_MASK)
-#define HT_HALF_GI_RATE1_MCS1_MSB                15
-#define HT_HALF_GI_RATE1_MCS1_LSB                8
-#define HT_HALF_GI_RATE1_MCS1_MASK               0x0000ff00
-#define HT_HALF_GI_RATE1_MCS1_GET(x)             (((x) & HT_HALF_GI_RATE1_MCS1_MASK) >> HT_HALF_GI_RATE1_MCS1_LSB)
-#define HT_HALF_GI_RATE1_MCS1_SET(x)             (((x) << HT_HALF_GI_RATE1_MCS1_LSB) & HT_HALF_GI_RATE1_MCS1_MASK)
-#define HT_HALF_GI_RATE1_MCS0_MSB                7
-#define HT_HALF_GI_RATE1_MCS0_LSB                0
-#define HT_HALF_GI_RATE1_MCS0_MASK               0x000000ff
-#define HT_HALF_GI_RATE1_MCS0_GET(x)             (((x) & HT_HALF_GI_RATE1_MCS0_MASK) >> HT_HALF_GI_RATE1_MCS0_LSB)
-#define HT_HALF_GI_RATE1_MCS0_SET(x)             (((x) << HT_HALF_GI_RATE1_MCS0_LSB) & HT_HALF_GI_RATE1_MCS0_MASK)
-
-#define HT_HALF_GI_RATE2_ADDRESS                 0x0000834c
-#define HT_HALF_GI_RATE2_OFFSET                  0x0000034c
-#define HT_HALF_GI_RATE2_MCS7_MSB                31
-#define HT_HALF_GI_RATE2_MCS7_LSB                24
-#define HT_HALF_GI_RATE2_MCS7_MASK               0xff000000
-#define HT_HALF_GI_RATE2_MCS7_GET(x)             (((x) & HT_HALF_GI_RATE2_MCS7_MASK) >> HT_HALF_GI_RATE2_MCS7_LSB)
-#define HT_HALF_GI_RATE2_MCS7_SET(x)             (((x) << HT_HALF_GI_RATE2_MCS7_LSB) & HT_HALF_GI_RATE2_MCS7_MASK)
-#define HT_HALF_GI_RATE2_MCS6_MSB                23
-#define HT_HALF_GI_RATE2_MCS6_LSB                16
-#define HT_HALF_GI_RATE2_MCS6_MASK               0x00ff0000
-#define HT_HALF_GI_RATE2_MCS6_GET(x)             (((x) & HT_HALF_GI_RATE2_MCS6_MASK) >> HT_HALF_GI_RATE2_MCS6_LSB)
-#define HT_HALF_GI_RATE2_MCS6_SET(x)             (((x) << HT_HALF_GI_RATE2_MCS6_LSB) & HT_HALF_GI_RATE2_MCS6_MASK)
-#define HT_HALF_GI_RATE2_MCS5_MSB                15
-#define HT_HALF_GI_RATE2_MCS5_LSB                8
-#define HT_HALF_GI_RATE2_MCS5_MASK               0x0000ff00
-#define HT_HALF_GI_RATE2_MCS5_GET(x)             (((x) & HT_HALF_GI_RATE2_MCS5_MASK) >> HT_HALF_GI_RATE2_MCS5_LSB)
-#define HT_HALF_GI_RATE2_MCS5_SET(x)             (((x) << HT_HALF_GI_RATE2_MCS5_LSB) & HT_HALF_GI_RATE2_MCS5_MASK)
-#define HT_HALF_GI_RATE2_MCS4_MSB                7
-#define HT_HALF_GI_RATE2_MCS4_LSB                0
-#define HT_HALF_GI_RATE2_MCS4_MASK               0x000000ff
-#define HT_HALF_GI_RATE2_MCS4_GET(x)             (((x) & HT_HALF_GI_RATE2_MCS4_MASK) >> HT_HALF_GI_RATE2_MCS4_LSB)
-#define HT_HALF_GI_RATE2_MCS4_SET(x)             (((x) << HT_HALF_GI_RATE2_MCS4_LSB) & HT_HALF_GI_RATE2_MCS4_MASK)
-
-#define HT_FULL_GI_RATE1_ADDRESS                 0x00008350
-#define HT_FULL_GI_RATE1_OFFSET                  0x00000350
-#define HT_FULL_GI_RATE1_MCS3_MSB                31
-#define HT_FULL_GI_RATE1_MCS3_LSB                24
-#define HT_FULL_GI_RATE1_MCS3_MASK               0xff000000
-#define HT_FULL_GI_RATE1_MCS3_GET(x)             (((x) & HT_FULL_GI_RATE1_MCS3_MASK) >> HT_FULL_GI_RATE1_MCS3_LSB)
-#define HT_FULL_GI_RATE1_MCS3_SET(x)             (((x) << HT_FULL_GI_RATE1_MCS3_LSB) & HT_FULL_GI_RATE1_MCS3_MASK)
-#define HT_FULL_GI_RATE1_MCS2_MSB                23
-#define HT_FULL_GI_RATE1_MCS2_LSB                16
-#define HT_FULL_GI_RATE1_MCS2_MASK               0x00ff0000
-#define HT_FULL_GI_RATE1_MCS2_GET(x)             (((x) & HT_FULL_GI_RATE1_MCS2_MASK) >> HT_FULL_GI_RATE1_MCS2_LSB)
-#define HT_FULL_GI_RATE1_MCS2_SET(x)             (((x) << HT_FULL_GI_RATE1_MCS2_LSB) & HT_FULL_GI_RATE1_MCS2_MASK)
-#define HT_FULL_GI_RATE1_MCS1_MSB                15
-#define HT_FULL_GI_RATE1_MCS1_LSB                8
-#define HT_FULL_GI_RATE1_MCS1_MASK               0x0000ff00
-#define HT_FULL_GI_RATE1_MCS1_GET(x)             (((x) & HT_FULL_GI_RATE1_MCS1_MASK) >> HT_FULL_GI_RATE1_MCS1_LSB)
-#define HT_FULL_GI_RATE1_MCS1_SET(x)             (((x) << HT_FULL_GI_RATE1_MCS1_LSB) & HT_FULL_GI_RATE1_MCS1_MASK)
-#define HT_FULL_GI_RATE1_MCS0_MSB                7
-#define HT_FULL_GI_RATE1_MCS0_LSB                0
-#define HT_FULL_GI_RATE1_MCS0_MASK               0x000000ff
-#define HT_FULL_GI_RATE1_MCS0_GET(x)             (((x) & HT_FULL_GI_RATE1_MCS0_MASK) >> HT_FULL_GI_RATE1_MCS0_LSB)
-#define HT_FULL_GI_RATE1_MCS0_SET(x)             (((x) << HT_FULL_GI_RATE1_MCS0_LSB) & HT_FULL_GI_RATE1_MCS0_MASK)
-
-#define HT_FULL_GI_RATE2_ADDRESS                 0x00008354
-#define HT_FULL_GI_RATE2_OFFSET                  0x00000354
-#define HT_FULL_GI_RATE2_MCS7_MSB                31
-#define HT_FULL_GI_RATE2_MCS7_LSB                24
-#define HT_FULL_GI_RATE2_MCS7_MASK               0xff000000
-#define HT_FULL_GI_RATE2_MCS7_GET(x)             (((x) & HT_FULL_GI_RATE2_MCS7_MASK) >> HT_FULL_GI_RATE2_MCS7_LSB)
-#define HT_FULL_GI_RATE2_MCS7_SET(x)             (((x) << HT_FULL_GI_RATE2_MCS7_LSB) & HT_FULL_GI_RATE2_MCS7_MASK)
-#define HT_FULL_GI_RATE2_MCS6_MSB                23
-#define HT_FULL_GI_RATE2_MCS6_LSB                16
-#define HT_FULL_GI_RATE2_MCS6_MASK               0x00ff0000
-#define HT_FULL_GI_RATE2_MCS6_GET(x)             (((x) & HT_FULL_GI_RATE2_MCS6_MASK) >> HT_FULL_GI_RATE2_MCS6_LSB)
-#define HT_FULL_GI_RATE2_MCS6_SET(x)             (((x) << HT_FULL_GI_RATE2_MCS6_LSB) & HT_FULL_GI_RATE2_MCS6_MASK)
-#define HT_FULL_GI_RATE2_MCS5_MSB                15
-#define HT_FULL_GI_RATE2_MCS5_LSB                8
-#define HT_FULL_GI_RATE2_MCS5_MASK               0x0000ff00
-#define HT_FULL_GI_RATE2_MCS5_GET(x)             (((x) & HT_FULL_GI_RATE2_MCS5_MASK) >> HT_FULL_GI_RATE2_MCS5_LSB)
-#define HT_FULL_GI_RATE2_MCS5_SET(x)             (((x) << HT_FULL_GI_RATE2_MCS5_LSB) & HT_FULL_GI_RATE2_MCS5_MASK)
-#define HT_FULL_GI_RATE2_MCS4_MSB                7
-#define HT_FULL_GI_RATE2_MCS4_LSB                0
-#define HT_FULL_GI_RATE2_MCS4_MASK               0x000000ff
-#define HT_FULL_GI_RATE2_MCS4_GET(x)             (((x) & HT_FULL_GI_RATE2_MCS4_MASK) >> HT_FULL_GI_RATE2_MCS4_LSB)
-#define HT_FULL_GI_RATE2_MCS4_SET(x)             (((x) << HT_FULL_GI_RATE2_MCS4_LSB) & HT_FULL_GI_RATE2_MCS4_MASK)
-
-#define LEGACY_RATE1_ADDRESS                     0x00008358
-#define LEGACY_RATE1_OFFSET                      0x00000358
-#define LEGACY_RATE1_RATE12_MSB                  29
-#define LEGACY_RATE1_RATE12_LSB                  24
-#define LEGACY_RATE1_RATE12_MASK                 0x3f000000
-#define LEGACY_RATE1_RATE12_GET(x)               (((x) & LEGACY_RATE1_RATE12_MASK) >> LEGACY_RATE1_RATE12_LSB)
-#define LEGACY_RATE1_RATE12_SET(x)               (((x) << LEGACY_RATE1_RATE12_LSB) & LEGACY_RATE1_RATE12_MASK)
-#define LEGACY_RATE1_RATE11_MSB                  23
-#define LEGACY_RATE1_RATE11_LSB                  18
-#define LEGACY_RATE1_RATE11_MASK                 0x00fc0000
-#define LEGACY_RATE1_RATE11_GET(x)               (((x) & LEGACY_RATE1_RATE11_MASK) >> LEGACY_RATE1_RATE11_LSB)
-#define LEGACY_RATE1_RATE11_SET(x)               (((x) << LEGACY_RATE1_RATE11_LSB) & LEGACY_RATE1_RATE11_MASK)
-#define LEGACY_RATE1_RATE10_MSB                  17
-#define LEGACY_RATE1_RATE10_LSB                  12
-#define LEGACY_RATE1_RATE10_MASK                 0x0003f000
-#define LEGACY_RATE1_RATE10_GET(x)               (((x) & LEGACY_RATE1_RATE10_MASK) >> LEGACY_RATE1_RATE10_LSB)
-#define LEGACY_RATE1_RATE10_SET(x)               (((x) << LEGACY_RATE1_RATE10_LSB) & LEGACY_RATE1_RATE10_MASK)
-#define LEGACY_RATE1_RATE9_MSB                   11
-#define LEGACY_RATE1_RATE9_LSB                   6
-#define LEGACY_RATE1_RATE9_MASK                  0x00000fc0
-#define LEGACY_RATE1_RATE9_GET(x)                (((x) & LEGACY_RATE1_RATE9_MASK) >> LEGACY_RATE1_RATE9_LSB)
-#define LEGACY_RATE1_RATE9_SET(x)                (((x) << LEGACY_RATE1_RATE9_LSB) & LEGACY_RATE1_RATE9_MASK)
-#define LEGACY_RATE1_RATE8_MSB                   5
-#define LEGACY_RATE1_RATE8_LSB                   0
-#define LEGACY_RATE1_RATE8_MASK                  0x0000003f
-#define LEGACY_RATE1_RATE8_GET(x)                (((x) & LEGACY_RATE1_RATE8_MASK) >> LEGACY_RATE1_RATE8_LSB)
-#define LEGACY_RATE1_RATE8_SET(x)                (((x) << LEGACY_RATE1_RATE8_LSB) & LEGACY_RATE1_RATE8_MASK)
-
-#define LEGACY_RATE2_ADDRESS                     0x0000835c
-#define LEGACY_RATE2_OFFSET                      0x0000035c
-#define LEGACY_RATE2_RATE25_MSB                  29
-#define LEGACY_RATE2_RATE25_LSB                  24
-#define LEGACY_RATE2_RATE25_MASK                 0x3f000000
-#define LEGACY_RATE2_RATE25_GET(x)               (((x) & LEGACY_RATE2_RATE25_MASK) >> LEGACY_RATE2_RATE25_LSB)
-#define LEGACY_RATE2_RATE25_SET(x)               (((x) << LEGACY_RATE2_RATE25_LSB) & LEGACY_RATE2_RATE25_MASK)
-#define LEGACY_RATE2_RATE24_MSB                  23
-#define LEGACY_RATE2_RATE24_LSB                  18
-#define LEGACY_RATE2_RATE24_MASK                 0x00fc0000
-#define LEGACY_RATE2_RATE24_GET(x)               (((x) & LEGACY_RATE2_RATE24_MASK) >> LEGACY_RATE2_RATE24_LSB)
-#define LEGACY_RATE2_RATE24_SET(x)               (((x) << LEGACY_RATE2_RATE24_LSB) & LEGACY_RATE2_RATE24_MASK)
-#define LEGACY_RATE2_RATE15_MSB                  17
-#define LEGACY_RATE2_RATE15_LSB                  12
-#define LEGACY_RATE2_RATE15_MASK                 0x0003f000
-#define LEGACY_RATE2_RATE15_GET(x)               (((x) & LEGACY_RATE2_RATE15_MASK) >> LEGACY_RATE2_RATE15_LSB)
-#define LEGACY_RATE2_RATE15_SET(x)               (((x) << LEGACY_RATE2_RATE15_LSB) & LEGACY_RATE2_RATE15_MASK)
-#define LEGACY_RATE2_RATE14_MSB                  11
-#define LEGACY_RATE2_RATE14_LSB                  6
-#define LEGACY_RATE2_RATE14_MASK                 0x00000fc0
-#define LEGACY_RATE2_RATE14_GET(x)               (((x) & LEGACY_RATE2_RATE14_MASK) >> LEGACY_RATE2_RATE14_LSB)
-#define LEGACY_RATE2_RATE14_SET(x)               (((x) << LEGACY_RATE2_RATE14_LSB) & LEGACY_RATE2_RATE14_MASK)
-#define LEGACY_RATE2_RATE13_MSB                  5
-#define LEGACY_RATE2_RATE13_LSB                  0
-#define LEGACY_RATE2_RATE13_MASK                 0x0000003f
-#define LEGACY_RATE2_RATE13_GET(x)               (((x) & LEGACY_RATE2_RATE13_MASK) >> LEGACY_RATE2_RATE13_LSB)
-#define LEGACY_RATE2_RATE13_SET(x)               (((x) << LEGACY_RATE2_RATE13_LSB) & LEGACY_RATE2_RATE13_MASK)
-
-#define LEGACY_RATE3_ADDRESS                     0x00008360
-#define LEGACY_RATE3_OFFSET                      0x00000360
-#define LEGACY_RATE3_RATE30_MSB                  29
-#define LEGACY_RATE3_RATE30_LSB                  24
-#define LEGACY_RATE3_RATE30_MASK                 0x3f000000
-#define LEGACY_RATE3_RATE30_GET(x)               (((x) & LEGACY_RATE3_RATE30_MASK) >> LEGACY_RATE3_RATE30_LSB)
-#define LEGACY_RATE3_RATE30_SET(x)               (((x) << LEGACY_RATE3_RATE30_LSB) & LEGACY_RATE3_RATE30_MASK)
-#define LEGACY_RATE3_RATE29_MSB                  23
-#define LEGACY_RATE3_RATE29_LSB                  18
-#define LEGACY_RATE3_RATE29_MASK                 0x00fc0000
-#define LEGACY_RATE3_RATE29_GET(x)               (((x) & LEGACY_RATE3_RATE29_MASK) >> LEGACY_RATE3_RATE29_LSB)
-#define LEGACY_RATE3_RATE29_SET(x)               (((x) << LEGACY_RATE3_RATE29_LSB) & LEGACY_RATE3_RATE29_MASK)
-#define LEGACY_RATE3_RATE28_MSB                  17
-#define LEGACY_RATE3_RATE28_LSB                  12
-#define LEGACY_RATE3_RATE28_MASK                 0x0003f000
-#define LEGACY_RATE3_RATE28_GET(x)               (((x) & LEGACY_RATE3_RATE28_MASK) >> LEGACY_RATE3_RATE28_LSB)
-#define LEGACY_RATE3_RATE28_SET(x)               (((x) << LEGACY_RATE3_RATE28_LSB) & LEGACY_RATE3_RATE28_MASK)
-#define LEGACY_RATE3_RATE27_MSB                  11
-#define LEGACY_RATE3_RATE27_LSB                  6
-#define LEGACY_RATE3_RATE27_MASK                 0x00000fc0
-#define LEGACY_RATE3_RATE27_GET(x)               (((x) & LEGACY_RATE3_RATE27_MASK) >> LEGACY_RATE3_RATE27_LSB)
-#define LEGACY_RATE3_RATE27_SET(x)               (((x) << LEGACY_RATE3_RATE27_LSB) & LEGACY_RATE3_RATE27_MASK)
-#define LEGACY_RATE3_RATE26_MSB                  5
-#define LEGACY_RATE3_RATE26_LSB                  0
-#define LEGACY_RATE3_RATE26_MASK                 0x0000003f
-#define LEGACY_RATE3_RATE26_GET(x)               (((x) & LEGACY_RATE3_RATE26_MASK) >> LEGACY_RATE3_RATE26_LSB)
-#define LEGACY_RATE3_RATE26_SET(x)               (((x) << LEGACY_RATE3_RATE26_LSB) & LEGACY_RATE3_RATE26_MASK)
-
-#define RX_INT_FILTER_ADDRESS                    0x00008364
-#define RX_INT_FILTER_OFFSET                     0x00000364
-#define RX_INT_FILTER_BEACON_MSB                 17
-#define RX_INT_FILTER_BEACON_LSB                 17
-#define RX_INT_FILTER_BEACON_MASK                0x00020000
-#define RX_INT_FILTER_BEACON_GET(x)              (((x) & RX_INT_FILTER_BEACON_MASK) >> RX_INT_FILTER_BEACON_LSB)
-#define RX_INT_FILTER_BEACON_SET(x)              (((x) << RX_INT_FILTER_BEACON_LSB) & RX_INT_FILTER_BEACON_MASK)
-#define RX_INT_FILTER_AMPDU_MSB                  16
-#define RX_INT_FILTER_AMPDU_LSB                  16
-#define RX_INT_FILTER_AMPDU_MASK                 0x00010000
-#define RX_INT_FILTER_AMPDU_GET(x)               (((x) & RX_INT_FILTER_AMPDU_MASK) >> RX_INT_FILTER_AMPDU_LSB)
-#define RX_INT_FILTER_AMPDU_SET(x)               (((x) << RX_INT_FILTER_AMPDU_LSB) & RX_INT_FILTER_AMPDU_MASK)
-#define RX_INT_FILTER_EOSP_MSB                   15
-#define RX_INT_FILTER_EOSP_LSB                   15
-#define RX_INT_FILTER_EOSP_MASK                  0x00008000
-#define RX_INT_FILTER_EOSP_GET(x)                (((x) & RX_INT_FILTER_EOSP_MASK) >> RX_INT_FILTER_EOSP_LSB)
-#define RX_INT_FILTER_EOSP_SET(x)                (((x) << RX_INT_FILTER_EOSP_LSB) & RX_INT_FILTER_EOSP_MASK)
-#define RX_INT_FILTER_LENGTH_LOW_MSB             14
-#define RX_INT_FILTER_LENGTH_LOW_LSB             14
-#define RX_INT_FILTER_LENGTH_LOW_MASK            0x00004000
-#define RX_INT_FILTER_LENGTH_LOW_GET(x)          (((x) & RX_INT_FILTER_LENGTH_LOW_MASK) >> RX_INT_FILTER_LENGTH_LOW_LSB)
-#define RX_INT_FILTER_LENGTH_LOW_SET(x)          (((x) << RX_INT_FILTER_LENGTH_LOW_LSB) & RX_INT_FILTER_LENGTH_LOW_MASK)
-#define RX_INT_FILTER_LENGTH_HIGH_MSB            13
-#define RX_INT_FILTER_LENGTH_HIGH_LSB            13
-#define RX_INT_FILTER_LENGTH_HIGH_MASK           0x00002000
-#define RX_INT_FILTER_LENGTH_HIGH_GET(x)         (((x) & RX_INT_FILTER_LENGTH_HIGH_MASK) >> RX_INT_FILTER_LENGTH_HIGH_LSB)
-#define RX_INT_FILTER_LENGTH_HIGH_SET(x)         (((x) << RX_INT_FILTER_LENGTH_HIGH_LSB) & RX_INT_FILTER_LENGTH_HIGH_MASK)
-#define RX_INT_FILTER_RSSI_MSB                   12
-#define RX_INT_FILTER_RSSI_LSB                   12
-#define RX_INT_FILTER_RSSI_MASK                  0x00001000
-#define RX_INT_FILTER_RSSI_GET(x)                (((x) & RX_INT_FILTER_RSSI_MASK) >> RX_INT_FILTER_RSSI_LSB)
-#define RX_INT_FILTER_RSSI_SET(x)                (((x) << RX_INT_FILTER_RSSI_LSB) & RX_INT_FILTER_RSSI_MASK)
-#define RX_INT_FILTER_RATE_LOW_MSB               11
-#define RX_INT_FILTER_RATE_LOW_LSB               11
-#define RX_INT_FILTER_RATE_LOW_MASK              0x00000800
-#define RX_INT_FILTER_RATE_LOW_GET(x)            (((x) & RX_INT_FILTER_RATE_LOW_MASK) >> RX_INT_FILTER_RATE_LOW_LSB)
-#define RX_INT_FILTER_RATE_LOW_SET(x)            (((x) << RX_INT_FILTER_RATE_LOW_LSB) & RX_INT_FILTER_RATE_LOW_MASK)
-#define RX_INT_FILTER_RATE_HIGH_MSB              10
-#define RX_INT_FILTER_RATE_HIGH_LSB              10
-#define RX_INT_FILTER_RATE_HIGH_MASK             0x00000400
-#define RX_INT_FILTER_RATE_HIGH_GET(x)           (((x) & RX_INT_FILTER_RATE_HIGH_MASK) >> RX_INT_FILTER_RATE_HIGH_LSB)
-#define RX_INT_FILTER_RATE_HIGH_SET(x)           (((x) << RX_INT_FILTER_RATE_HIGH_LSB) & RX_INT_FILTER_RATE_HIGH_MASK)
-#define RX_INT_FILTER_MORE_FRAG_MSB              9
-#define RX_INT_FILTER_MORE_FRAG_LSB              9
-#define RX_INT_FILTER_MORE_FRAG_MASK             0x00000200
-#define RX_INT_FILTER_MORE_FRAG_GET(x)           (((x) & RX_INT_FILTER_MORE_FRAG_MASK) >> RX_INT_FILTER_MORE_FRAG_LSB)
-#define RX_INT_FILTER_MORE_FRAG_SET(x)           (((x) << RX_INT_FILTER_MORE_FRAG_LSB) & RX_INT_FILTER_MORE_FRAG_MASK)
-#define RX_INT_FILTER_MORE_DATA_MSB              8
-#define RX_INT_FILTER_MORE_DATA_LSB              8
-#define RX_INT_FILTER_MORE_DATA_MASK             0x00000100
-#define RX_INT_FILTER_MORE_DATA_GET(x)           (((x) & RX_INT_FILTER_MORE_DATA_MASK) >> RX_INT_FILTER_MORE_DATA_LSB)
-#define RX_INT_FILTER_MORE_DATA_SET(x)           (((x) << RX_INT_FILTER_MORE_DATA_LSB) & RX_INT_FILTER_MORE_DATA_MASK)
-#define RX_INT_FILTER_RETRY_MSB                  7
-#define RX_INT_FILTER_RETRY_LSB                  7
-#define RX_INT_FILTER_RETRY_MASK                 0x00000080
-#define RX_INT_FILTER_RETRY_GET(x)               (((x) & RX_INT_FILTER_RETRY_MASK) >> RX_INT_FILTER_RETRY_LSB)
-#define RX_INT_FILTER_RETRY_SET(x)               (((x) << RX_INT_FILTER_RETRY_LSB) & RX_INT_FILTER_RETRY_MASK)
-#define RX_INT_FILTER_CTS_MSB                    6
-#define RX_INT_FILTER_CTS_LSB                    6
-#define RX_INT_FILTER_CTS_MASK                   0x00000040
-#define RX_INT_FILTER_CTS_GET(x)                 (((x) & RX_INT_FILTER_CTS_MASK) >> RX_INT_FILTER_CTS_LSB)
-#define RX_INT_FILTER_CTS_SET(x)                 (((x) << RX_INT_FILTER_CTS_LSB) & RX_INT_FILTER_CTS_MASK)
-#define RX_INT_FILTER_ACK_MSB                    5
-#define RX_INT_FILTER_ACK_LSB                    5
-#define RX_INT_FILTER_ACK_MASK                   0x00000020
-#define RX_INT_FILTER_ACK_GET(x)                 (((x) & RX_INT_FILTER_ACK_MASK) >> RX_INT_FILTER_ACK_LSB)
-#define RX_INT_FILTER_ACK_SET(x)                 (((x) << RX_INT_FILTER_ACK_LSB) & RX_INT_FILTER_ACK_MASK)
-#define RX_INT_FILTER_RTS_MSB                    4
-#define RX_INT_FILTER_RTS_LSB                    4
-#define RX_INT_FILTER_RTS_MASK                   0x00000010
-#define RX_INT_FILTER_RTS_GET(x)                 (((x) & RX_INT_FILTER_RTS_MASK) >> RX_INT_FILTER_RTS_LSB)
-#define RX_INT_FILTER_RTS_SET(x)                 (((x) << RX_INT_FILTER_RTS_LSB) & RX_INT_FILTER_RTS_MASK)
-#define RX_INT_FILTER_MCAST_MSB                  3
-#define RX_INT_FILTER_MCAST_LSB                  3
-#define RX_INT_FILTER_MCAST_MASK                 0x00000008
-#define RX_INT_FILTER_MCAST_GET(x)               (((x) & RX_INT_FILTER_MCAST_MASK) >> RX_INT_FILTER_MCAST_LSB)
-#define RX_INT_FILTER_MCAST_SET(x)               (((x) << RX_INT_FILTER_MCAST_LSB) & RX_INT_FILTER_MCAST_MASK)
-#define RX_INT_FILTER_BCAST_MSB                  2
-#define RX_INT_FILTER_BCAST_LSB                  2
-#define RX_INT_FILTER_BCAST_MASK                 0x00000004
-#define RX_INT_FILTER_BCAST_GET(x)               (((x) & RX_INT_FILTER_BCAST_MASK) >> RX_INT_FILTER_BCAST_LSB)
-#define RX_INT_FILTER_BCAST_SET(x)               (((x) << RX_INT_FILTER_BCAST_LSB) & RX_INT_FILTER_BCAST_MASK)
-#define RX_INT_FILTER_DIRECTED_MSB               1
-#define RX_INT_FILTER_DIRECTED_LSB               1
-#define RX_INT_FILTER_DIRECTED_MASK              0x00000002
-#define RX_INT_FILTER_DIRECTED_GET(x)            (((x) & RX_INT_FILTER_DIRECTED_MASK) >> RX_INT_FILTER_DIRECTED_LSB)
-#define RX_INT_FILTER_DIRECTED_SET(x)            (((x) << RX_INT_FILTER_DIRECTED_LSB) & RX_INT_FILTER_DIRECTED_MASK)
-#define RX_INT_FILTER_ENABLE_MSB                 0
-#define RX_INT_FILTER_ENABLE_LSB                 0
-#define RX_INT_FILTER_ENABLE_MASK                0x00000001
-#define RX_INT_FILTER_ENABLE_GET(x)              (((x) & RX_INT_FILTER_ENABLE_MASK) >> RX_INT_FILTER_ENABLE_LSB)
-#define RX_INT_FILTER_ENABLE_SET(x)              (((x) << RX_INT_FILTER_ENABLE_LSB) & RX_INT_FILTER_ENABLE_MASK)
-
-#define RX_INT_OVERFLOW_ADDRESS                  0x00008368
-#define RX_INT_OVERFLOW_OFFSET                   0x00000368
-#define RX_INT_OVERFLOW_STATUS_MSB               0
-#define RX_INT_OVERFLOW_STATUS_LSB               0
-#define RX_INT_OVERFLOW_STATUS_MASK              0x00000001
-#define RX_INT_OVERFLOW_STATUS_GET(x)            (((x) & RX_INT_OVERFLOW_STATUS_MASK) >> RX_INT_OVERFLOW_STATUS_LSB)
-#define RX_INT_OVERFLOW_STATUS_SET(x)            (((x) << RX_INT_OVERFLOW_STATUS_LSB) & RX_INT_OVERFLOW_STATUS_MASK)
-
-#define RX_FILTER_THRESH_ADDRESS                 0x0000836c
-#define RX_FILTER_THRESH_OFFSET                  0x0000036c
-#define RX_FILTER_THRESH_RSSI_LOW_MSB            23
-#define RX_FILTER_THRESH_RSSI_LOW_LSB            16
-#define RX_FILTER_THRESH_RSSI_LOW_MASK           0x00ff0000
-#define RX_FILTER_THRESH_RSSI_LOW_GET(x)         (((x) & RX_FILTER_THRESH_RSSI_LOW_MASK) >> RX_FILTER_THRESH_RSSI_LOW_LSB)
-#define RX_FILTER_THRESH_RSSI_LOW_SET(x)         (((x) << RX_FILTER_THRESH_RSSI_LOW_LSB) & RX_FILTER_THRESH_RSSI_LOW_MASK)
-#define RX_FILTER_THRESH_RATE_LOW_MSB            15
-#define RX_FILTER_THRESH_RATE_LOW_LSB            8
-#define RX_FILTER_THRESH_RATE_LOW_MASK           0x0000ff00
-#define RX_FILTER_THRESH_RATE_LOW_GET(x)         (((x) & RX_FILTER_THRESH_RATE_LOW_MASK) >> RX_FILTER_THRESH_RATE_LOW_LSB)
-#define RX_FILTER_THRESH_RATE_LOW_SET(x)         (((x) << RX_FILTER_THRESH_RATE_LOW_LSB) & RX_FILTER_THRESH_RATE_LOW_MASK)
-#define RX_FILTER_THRESH_RATE_HIGH_MSB           7
-#define RX_FILTER_THRESH_RATE_HIGH_LSB           0
-#define RX_FILTER_THRESH_RATE_HIGH_MASK          0x000000ff
-#define RX_FILTER_THRESH_RATE_HIGH_GET(x)        (((x) & RX_FILTER_THRESH_RATE_HIGH_MASK) >> RX_FILTER_THRESH_RATE_HIGH_LSB)
-#define RX_FILTER_THRESH_RATE_HIGH_SET(x)        (((x) << RX_FILTER_THRESH_RATE_HIGH_LSB) & RX_FILTER_THRESH_RATE_HIGH_MASK)
-
-#define RX_FILTER_THRESH1_ADDRESS                0x00008370
-#define RX_FILTER_THRESH1_OFFSET                 0x00000370
-#define RX_FILTER_THRESH1_LENGTH_LOW_MSB         23
-#define RX_FILTER_THRESH1_LENGTH_LOW_LSB         12
-#define RX_FILTER_THRESH1_LENGTH_LOW_MASK        0x00fff000
-#define RX_FILTER_THRESH1_LENGTH_LOW_GET(x)      (((x) & RX_FILTER_THRESH1_LENGTH_LOW_MASK) >> RX_FILTER_THRESH1_LENGTH_LOW_LSB)
-#define RX_FILTER_THRESH1_LENGTH_LOW_SET(x)      (((x) << RX_FILTER_THRESH1_LENGTH_LOW_LSB) & RX_FILTER_THRESH1_LENGTH_LOW_MASK)
-#define RX_FILTER_THRESH1_LENGTH_HIGH_MSB        11
-#define RX_FILTER_THRESH1_LENGTH_HIGH_LSB        0
-#define RX_FILTER_THRESH1_LENGTH_HIGH_MASK       0x00000fff
-#define RX_FILTER_THRESH1_LENGTH_HIGH_GET(x)     (((x) & RX_FILTER_THRESH1_LENGTH_HIGH_MASK) >> RX_FILTER_THRESH1_LENGTH_HIGH_LSB)
-#define RX_FILTER_THRESH1_LENGTH_HIGH_SET(x)     (((x) << RX_FILTER_THRESH1_LENGTH_HIGH_LSB) & RX_FILTER_THRESH1_LENGTH_HIGH_MASK)
-
-#define RX_PRIORITY_THRESH0_ADDRESS              0x00008374
-#define RX_PRIORITY_THRESH0_OFFSET               0x00000374
-#define RX_PRIORITY_THRESH0_RSSI_LOW_MSB         31
-#define RX_PRIORITY_THRESH0_RSSI_LOW_LSB         24
-#define RX_PRIORITY_THRESH0_RSSI_LOW_MASK        0xff000000
-#define RX_PRIORITY_THRESH0_RSSI_LOW_GET(x)      (((x) & RX_PRIORITY_THRESH0_RSSI_LOW_MASK) >> RX_PRIORITY_THRESH0_RSSI_LOW_LSB)
-#define RX_PRIORITY_THRESH0_RSSI_LOW_SET(x)      (((x) << RX_PRIORITY_THRESH0_RSSI_LOW_LSB) & RX_PRIORITY_THRESH0_RSSI_LOW_MASK)
-#define RX_PRIORITY_THRESH0_RSSI_HIGH_MSB        23
-#define RX_PRIORITY_THRESH0_RSSI_HIGH_LSB        16
-#define RX_PRIORITY_THRESH0_RSSI_HIGH_MASK       0x00ff0000
-#define RX_PRIORITY_THRESH0_RSSI_HIGH_GET(x)     (((x) & RX_PRIORITY_THRESH0_RSSI_HIGH_MASK) >> RX_PRIORITY_THRESH0_RSSI_HIGH_LSB)
-#define RX_PRIORITY_THRESH0_RSSI_HIGH_SET(x)     (((x) << RX_PRIORITY_THRESH0_RSSI_HIGH_LSB) & RX_PRIORITY_THRESH0_RSSI_HIGH_MASK)
-#define RX_PRIORITY_THRESH0_RATE_LOW_MSB         15
-#define RX_PRIORITY_THRESH0_RATE_LOW_LSB         8
-#define RX_PRIORITY_THRESH0_RATE_LOW_MASK        0x0000ff00
-#define RX_PRIORITY_THRESH0_RATE_LOW_GET(x)      (((x) & RX_PRIORITY_THRESH0_RATE_LOW_MASK) >> RX_PRIORITY_THRESH0_RATE_LOW_LSB)
-#define RX_PRIORITY_THRESH0_RATE_LOW_SET(x)      (((x) << RX_PRIORITY_THRESH0_RATE_LOW_LSB) & RX_PRIORITY_THRESH0_RATE_LOW_MASK)
-#define RX_PRIORITY_THRESH0_RATE_HIGH_MSB        7
-#define RX_PRIORITY_THRESH0_RATE_HIGH_LSB        0
-#define RX_PRIORITY_THRESH0_RATE_HIGH_MASK       0x000000ff
-#define RX_PRIORITY_THRESH0_RATE_HIGH_GET(x)     (((x) & RX_PRIORITY_THRESH0_RATE_HIGH_MASK) >> RX_PRIORITY_THRESH0_RATE_HIGH_LSB)
-#define RX_PRIORITY_THRESH0_RATE_HIGH_SET(x)     (((x) << RX_PRIORITY_THRESH0_RATE_HIGH_LSB) & RX_PRIORITY_THRESH0_RATE_HIGH_MASK)
-
-#define RX_PRIORITY_THRESH1_ADDRESS              0x00008378
-#define RX_PRIORITY_THRESH1_OFFSET               0x00000378
-#define RX_PRIORITY_THRESH1_XCAST_RSSI_HIGH_MSB  31
-#define RX_PRIORITY_THRESH1_XCAST_RSSI_HIGH_LSB  24
-#define RX_PRIORITY_THRESH1_XCAST_RSSI_HIGH_MASK 0xff000000
-#define RX_PRIORITY_THRESH1_XCAST_RSSI_HIGH_GET(x) (((x) & RX_PRIORITY_THRESH1_XCAST_RSSI_HIGH_MASK) >> RX_PRIORITY_THRESH1_XCAST_RSSI_HIGH_LSB)
-#define RX_PRIORITY_THRESH1_XCAST_RSSI_HIGH_SET(x) (((x) << RX_PRIORITY_THRESH1_XCAST_RSSI_HIGH_LSB) & RX_PRIORITY_THRESH1_XCAST_RSSI_HIGH_MASK)
-#define RX_PRIORITY_THRESH1_LENGTH_LOW_MSB       23
-#define RX_PRIORITY_THRESH1_LENGTH_LOW_LSB       12
-#define RX_PRIORITY_THRESH1_LENGTH_LOW_MASK      0x00fff000
-#define RX_PRIORITY_THRESH1_LENGTH_LOW_GET(x)    (((x) & RX_PRIORITY_THRESH1_LENGTH_LOW_MASK) >> RX_PRIORITY_THRESH1_LENGTH_LOW_LSB)
-#define RX_PRIORITY_THRESH1_LENGTH_LOW_SET(x)    (((x) << RX_PRIORITY_THRESH1_LENGTH_LOW_LSB) & RX_PRIORITY_THRESH1_LENGTH_LOW_MASK)
-#define RX_PRIORITY_THRESH1_LENGTH_HIGH_MSB      11
-#define RX_PRIORITY_THRESH1_LENGTH_HIGH_LSB      0
-#define RX_PRIORITY_THRESH1_LENGTH_HIGH_MASK     0x00000fff
-#define RX_PRIORITY_THRESH1_LENGTH_HIGH_GET(x)   (((x) & RX_PRIORITY_THRESH1_LENGTH_HIGH_MASK) >> RX_PRIORITY_THRESH1_LENGTH_HIGH_LSB)
-#define RX_PRIORITY_THRESH1_LENGTH_HIGH_SET(x)   (((x) << RX_PRIORITY_THRESH1_LENGTH_HIGH_LSB) & RX_PRIORITY_THRESH1_LENGTH_HIGH_MASK)
-
-#define RX_PRIORITY_THRESH2_ADDRESS              0x0000837c
-#define RX_PRIORITY_THRESH2_OFFSET               0x0000037c
-#define RX_PRIORITY_THRESH2_NULL_RSSI_HIGH_MSB   31
-#define RX_PRIORITY_THRESH2_NULL_RSSI_HIGH_LSB   24
-#define RX_PRIORITY_THRESH2_NULL_RSSI_HIGH_MASK  0xff000000
-#define RX_PRIORITY_THRESH2_NULL_RSSI_HIGH_GET(x) (((x) & RX_PRIORITY_THRESH2_NULL_RSSI_HIGH_MASK) >> RX_PRIORITY_THRESH2_NULL_RSSI_HIGH_LSB)
-#define RX_PRIORITY_THRESH2_NULL_RSSI_HIGH_SET(x) (((x) << RX_PRIORITY_THRESH2_NULL_RSSI_HIGH_LSB) & RX_PRIORITY_THRESH2_NULL_RSSI_HIGH_MASK)
-#define RX_PRIORITY_THRESH2_BEACON_RSSI_HIGH_MSB 23
-#define RX_PRIORITY_THRESH2_BEACON_RSSI_HIGH_LSB 16
-#define RX_PRIORITY_THRESH2_BEACON_RSSI_HIGH_MASK 0x00ff0000
-#define RX_PRIORITY_THRESH2_BEACON_RSSI_HIGH_GET(x) (((x) & RX_PRIORITY_THRESH2_BEACON_RSSI_HIGH_MASK) >> RX_PRIORITY_THRESH2_BEACON_RSSI_HIGH_LSB)
-#define RX_PRIORITY_THRESH2_BEACON_RSSI_HIGH_SET(x) (((x) << RX_PRIORITY_THRESH2_BEACON_RSSI_HIGH_LSB) & RX_PRIORITY_THRESH2_BEACON_RSSI_HIGH_MASK)
-#define RX_PRIORITY_THRESH2_MGMT_RSSI_HIGH_MSB   15
-#define RX_PRIORITY_THRESH2_MGMT_RSSI_HIGH_LSB   8
-#define RX_PRIORITY_THRESH2_MGMT_RSSI_HIGH_MASK  0x0000ff00
-#define RX_PRIORITY_THRESH2_MGMT_RSSI_HIGH_GET(x) (((x) & RX_PRIORITY_THRESH2_MGMT_RSSI_HIGH_MASK) >> RX_PRIORITY_THRESH2_MGMT_RSSI_HIGH_LSB)
-#define RX_PRIORITY_THRESH2_MGMT_RSSI_HIGH_SET(x) (((x) << RX_PRIORITY_THRESH2_MGMT_RSSI_HIGH_LSB) & RX_PRIORITY_THRESH2_MGMT_RSSI_HIGH_MASK)
-#define RX_PRIORITY_THRESH2_PRESP_RSSI_HIGH_MSB  7
-#define RX_PRIORITY_THRESH2_PRESP_RSSI_HIGH_LSB  0
-#define RX_PRIORITY_THRESH2_PRESP_RSSI_HIGH_MASK 0x000000ff
-#define RX_PRIORITY_THRESH2_PRESP_RSSI_HIGH_GET(x) (((x) & RX_PRIORITY_THRESH2_PRESP_RSSI_HIGH_MASK) >> RX_PRIORITY_THRESH2_PRESP_RSSI_HIGH_LSB)
-#define RX_PRIORITY_THRESH2_PRESP_RSSI_HIGH_SET(x) (((x) << RX_PRIORITY_THRESH2_PRESP_RSSI_HIGH_LSB) & RX_PRIORITY_THRESH2_PRESP_RSSI_HIGH_MASK)
-
-#define RX_PRIORITY_THRESH3_ADDRESS              0x00008380
-#define RX_PRIORITY_THRESH3_OFFSET               0x00000380
-#define RX_PRIORITY_THRESH3_PS_POLL_RSSI_HIGH_MSB 15
-#define RX_PRIORITY_THRESH3_PS_POLL_RSSI_HIGH_LSB 8
-#define RX_PRIORITY_THRESH3_PS_POLL_RSSI_HIGH_MASK 0x0000ff00
-#define RX_PRIORITY_THRESH3_PS_POLL_RSSI_HIGH_GET(x) (((x) & RX_PRIORITY_THRESH3_PS_POLL_RSSI_HIGH_MASK) >> RX_PRIORITY_THRESH3_PS_POLL_RSSI_HIGH_LSB)
-#define RX_PRIORITY_THRESH3_PS_POLL_RSSI_HIGH_SET(x) (((x) << RX_PRIORITY_THRESH3_PS_POLL_RSSI_HIGH_LSB) & RX_PRIORITY_THRESH3_PS_POLL_RSSI_HIGH_MASK)
-#define RX_PRIORITY_THRESH3_PREQ_RSSI_HIGH_MSB   7
-#define RX_PRIORITY_THRESH3_PREQ_RSSI_HIGH_LSB   0
-#define RX_PRIORITY_THRESH3_PREQ_RSSI_HIGH_MASK  0x000000ff
-#define RX_PRIORITY_THRESH3_PREQ_RSSI_HIGH_GET(x) (((x) & RX_PRIORITY_THRESH3_PREQ_RSSI_HIGH_MASK) >> RX_PRIORITY_THRESH3_PREQ_RSSI_HIGH_LSB)
-#define RX_PRIORITY_THRESH3_PREQ_RSSI_HIGH_SET(x) (((x) << RX_PRIORITY_THRESH3_PREQ_RSSI_HIGH_LSB) & RX_PRIORITY_THRESH3_PREQ_RSSI_HIGH_MASK)
-
-#define RX_PRIORITY_OFFSET0_ADDRESS              0x00008384
-#define RX_PRIORITY_OFFSET0_OFFSET               0x00000384
-#define RX_PRIORITY_OFFSET0_XCAST_RSSI_HIGH_MSB  29
-#define RX_PRIORITY_OFFSET0_XCAST_RSSI_HIGH_LSB  24
-#define RX_PRIORITY_OFFSET0_XCAST_RSSI_HIGH_MASK 0x3f000000
-#define RX_PRIORITY_OFFSET0_XCAST_RSSI_HIGH_GET(x) (((x) & RX_PRIORITY_OFFSET0_XCAST_RSSI_HIGH_MASK) >> RX_PRIORITY_OFFSET0_XCAST_RSSI_HIGH_LSB)
-#define RX_PRIORITY_OFFSET0_XCAST_RSSI_HIGH_SET(x) (((x) << RX_PRIORITY_OFFSET0_XCAST_RSSI_HIGH_LSB) & RX_PRIORITY_OFFSET0_XCAST_RSSI_HIGH_MASK)
-#define RX_PRIORITY_OFFSET0_RSSI_LOW_MSB         23
-#define RX_PRIORITY_OFFSET0_RSSI_LOW_LSB         18
-#define RX_PRIORITY_OFFSET0_RSSI_LOW_MASK        0x00fc0000
-#define RX_PRIORITY_OFFSET0_RSSI_LOW_GET(x)      (((x) & RX_PRIORITY_OFFSET0_RSSI_LOW_MASK) >> RX_PRIORITY_OFFSET0_RSSI_LOW_LSB)
-#define RX_PRIORITY_OFFSET0_RSSI_LOW_SET(x)      (((x) << RX_PRIORITY_OFFSET0_RSSI_LOW_LSB) & RX_PRIORITY_OFFSET0_RSSI_LOW_MASK)
-#define RX_PRIORITY_OFFSET0_RSSI_HIGH_MSB        17
-#define RX_PRIORITY_OFFSET0_RSSI_HIGH_LSB        12
-#define RX_PRIORITY_OFFSET0_RSSI_HIGH_MASK       0x0003f000
-#define RX_PRIORITY_OFFSET0_RSSI_HIGH_GET(x)     (((x) & RX_PRIORITY_OFFSET0_RSSI_HIGH_MASK) >> RX_PRIORITY_OFFSET0_RSSI_HIGH_LSB)
-#define RX_PRIORITY_OFFSET0_RSSI_HIGH_SET(x)     (((x) << RX_PRIORITY_OFFSET0_RSSI_HIGH_LSB) & RX_PRIORITY_OFFSET0_RSSI_HIGH_MASK)
-#define RX_PRIORITY_OFFSET0_PHY_RATE_LOW_MSB     11
-#define RX_PRIORITY_OFFSET0_PHY_RATE_LOW_LSB     6
-#define RX_PRIORITY_OFFSET0_PHY_RATE_LOW_MASK    0x00000fc0
-#define RX_PRIORITY_OFFSET0_PHY_RATE_LOW_GET(x)  (((x) & RX_PRIORITY_OFFSET0_PHY_RATE_LOW_MASK) >> RX_PRIORITY_OFFSET0_PHY_RATE_LOW_LSB)
-#define RX_PRIORITY_OFFSET0_PHY_RATE_LOW_SET(x)  (((x) << RX_PRIORITY_OFFSET0_PHY_RATE_LOW_LSB) & RX_PRIORITY_OFFSET0_PHY_RATE_LOW_MASK)
-#define RX_PRIORITY_OFFSET0_PHY_RATE_HIGH_MSB    5
-#define RX_PRIORITY_OFFSET0_PHY_RATE_HIGH_LSB    0
-#define RX_PRIORITY_OFFSET0_PHY_RATE_HIGH_MASK   0x0000003f
-#define RX_PRIORITY_OFFSET0_PHY_RATE_HIGH_GET(x) (((x) & RX_PRIORITY_OFFSET0_PHY_RATE_HIGH_MASK) >> RX_PRIORITY_OFFSET0_PHY_RATE_HIGH_LSB)
-#define RX_PRIORITY_OFFSET0_PHY_RATE_HIGH_SET(x) (((x) << RX_PRIORITY_OFFSET0_PHY_RATE_HIGH_LSB) & RX_PRIORITY_OFFSET0_PHY_RATE_HIGH_MASK)
-
-#define RX_PRIORITY_OFFSET1_ADDRESS              0x00008388
-#define RX_PRIORITY_OFFSET1_OFFSET               0x00000388
-#define RX_PRIORITY_OFFSET1_RTS_MSB              29
-#define RX_PRIORITY_OFFSET1_RTS_LSB              24
-#define RX_PRIORITY_OFFSET1_RTS_MASK             0x3f000000
-#define RX_PRIORITY_OFFSET1_RTS_GET(x)           (((x) & RX_PRIORITY_OFFSET1_RTS_MASK) >> RX_PRIORITY_OFFSET1_RTS_LSB)
-#define RX_PRIORITY_OFFSET1_RTS_SET(x)           (((x) << RX_PRIORITY_OFFSET1_RTS_LSB) & RX_PRIORITY_OFFSET1_RTS_MASK)
-#define RX_PRIORITY_OFFSET1_RETX_MSB             23
-#define RX_PRIORITY_OFFSET1_RETX_LSB             18
-#define RX_PRIORITY_OFFSET1_RETX_MASK            0x00fc0000
-#define RX_PRIORITY_OFFSET1_RETX_GET(x)          (((x) & RX_PRIORITY_OFFSET1_RETX_MASK) >> RX_PRIORITY_OFFSET1_RETX_LSB)
-#define RX_PRIORITY_OFFSET1_RETX_SET(x)          (((x) << RX_PRIORITY_OFFSET1_RETX_LSB) & RX_PRIORITY_OFFSET1_RETX_MASK)
-#define RX_PRIORITY_OFFSET1_PRESP_RSSI_HIGH_MSB  17
-#define RX_PRIORITY_OFFSET1_PRESP_RSSI_HIGH_LSB  12
-#define RX_PRIORITY_OFFSET1_PRESP_RSSI_HIGH_MASK 0x0003f000
-#define RX_PRIORITY_OFFSET1_PRESP_RSSI_HIGH_GET(x) (((x) & RX_PRIORITY_OFFSET1_PRESP_RSSI_HIGH_MASK) >> RX_PRIORITY_OFFSET1_PRESP_RSSI_HIGH_LSB)
-#define RX_PRIORITY_OFFSET1_PRESP_RSSI_HIGH_SET(x) (((x) << RX_PRIORITY_OFFSET1_PRESP_RSSI_HIGH_LSB) & RX_PRIORITY_OFFSET1_PRESP_RSSI_HIGH_MASK)
-#define RX_PRIORITY_OFFSET1_LENGTH_LOW_MSB       11
-#define RX_PRIORITY_OFFSET1_LENGTH_LOW_LSB       6
-#define RX_PRIORITY_OFFSET1_LENGTH_LOW_MASK      0x00000fc0
-#define RX_PRIORITY_OFFSET1_LENGTH_LOW_GET(x)    (((x) & RX_PRIORITY_OFFSET1_LENGTH_LOW_MASK) >> RX_PRIORITY_OFFSET1_LENGTH_LOW_LSB)
-#define RX_PRIORITY_OFFSET1_LENGTH_LOW_SET(x)    (((x) << RX_PRIORITY_OFFSET1_LENGTH_LOW_LSB) & RX_PRIORITY_OFFSET1_LENGTH_LOW_MASK)
-#define RX_PRIORITY_OFFSET1_LENGTH_HIGH_MSB      5
-#define RX_PRIORITY_OFFSET1_LENGTH_HIGH_LSB      0
-#define RX_PRIORITY_OFFSET1_LENGTH_HIGH_MASK     0x0000003f
-#define RX_PRIORITY_OFFSET1_LENGTH_HIGH_GET(x)   (((x) & RX_PRIORITY_OFFSET1_LENGTH_HIGH_MASK) >> RX_PRIORITY_OFFSET1_LENGTH_HIGH_LSB)
-#define RX_PRIORITY_OFFSET1_LENGTH_HIGH_SET(x)   (((x) << RX_PRIORITY_OFFSET1_LENGTH_HIGH_LSB) & RX_PRIORITY_OFFSET1_LENGTH_HIGH_MASK)
-
-#define RX_PRIORITY_OFFSET2_ADDRESS              0x0000838c
-#define RX_PRIORITY_OFFSET2_OFFSET               0x0000038c
-#define RX_PRIORITY_OFFSET2_BEACON_MSB           29
-#define RX_PRIORITY_OFFSET2_BEACON_LSB           24
-#define RX_PRIORITY_OFFSET2_BEACON_MASK          0x3f000000
-#define RX_PRIORITY_OFFSET2_BEACON_GET(x)        (((x) & RX_PRIORITY_OFFSET2_BEACON_MASK) >> RX_PRIORITY_OFFSET2_BEACON_LSB)
-#define RX_PRIORITY_OFFSET2_BEACON_SET(x)        (((x) << RX_PRIORITY_OFFSET2_BEACON_LSB) & RX_PRIORITY_OFFSET2_BEACON_MASK)
-#define RX_PRIORITY_OFFSET2_MGMT_MSB             23
-#define RX_PRIORITY_OFFSET2_MGMT_LSB             18
-#define RX_PRIORITY_OFFSET2_MGMT_MASK            0x00fc0000
-#define RX_PRIORITY_OFFSET2_MGMT_GET(x)          (((x) & RX_PRIORITY_OFFSET2_MGMT_MASK) >> RX_PRIORITY_OFFSET2_MGMT_LSB)
-#define RX_PRIORITY_OFFSET2_MGMT_SET(x)          (((x) << RX_PRIORITY_OFFSET2_MGMT_LSB) & RX_PRIORITY_OFFSET2_MGMT_MASK)
-#define RX_PRIORITY_OFFSET2_ATIM_MSB             17
-#define RX_PRIORITY_OFFSET2_ATIM_LSB             12
-#define RX_PRIORITY_OFFSET2_ATIM_MASK            0x0003f000
-#define RX_PRIORITY_OFFSET2_ATIM_GET(x)          (((x) & RX_PRIORITY_OFFSET2_ATIM_MASK) >> RX_PRIORITY_OFFSET2_ATIM_LSB)
-#define RX_PRIORITY_OFFSET2_ATIM_SET(x)          (((x) << RX_PRIORITY_OFFSET2_ATIM_LSB) & RX_PRIORITY_OFFSET2_ATIM_MASK)
-#define RX_PRIORITY_OFFSET2_PRESP_MSB            11
-#define RX_PRIORITY_OFFSET2_PRESP_LSB            6
-#define RX_PRIORITY_OFFSET2_PRESP_MASK           0x00000fc0
-#define RX_PRIORITY_OFFSET2_PRESP_GET(x)         (((x) & RX_PRIORITY_OFFSET2_PRESP_MASK) >> RX_PRIORITY_OFFSET2_PRESP_LSB)
-#define RX_PRIORITY_OFFSET2_PRESP_SET(x)         (((x) << RX_PRIORITY_OFFSET2_PRESP_LSB) & RX_PRIORITY_OFFSET2_PRESP_MASK)
-#define RX_PRIORITY_OFFSET2_XCAST_MSB            5
-#define RX_PRIORITY_OFFSET2_XCAST_LSB            0
-#define RX_PRIORITY_OFFSET2_XCAST_MASK           0x0000003f
-#define RX_PRIORITY_OFFSET2_XCAST_GET(x)         (((x) & RX_PRIORITY_OFFSET2_XCAST_MASK) >> RX_PRIORITY_OFFSET2_XCAST_LSB)
-#define RX_PRIORITY_OFFSET2_XCAST_SET(x)         (((x) << RX_PRIORITY_OFFSET2_XCAST_LSB) & RX_PRIORITY_OFFSET2_XCAST_MASK)
-
-#define RX_PRIORITY_OFFSET3_ADDRESS              0x00008390
-#define RX_PRIORITY_OFFSET3_OFFSET               0x00000390
-#define RX_PRIORITY_OFFSET3_PS_POLL_MSB          29
-#define RX_PRIORITY_OFFSET3_PS_POLL_LSB          24
-#define RX_PRIORITY_OFFSET3_PS_POLL_MASK         0x3f000000
-#define RX_PRIORITY_OFFSET3_PS_POLL_GET(x)       (((x) & RX_PRIORITY_OFFSET3_PS_POLL_MASK) >> RX_PRIORITY_OFFSET3_PS_POLL_LSB)
-#define RX_PRIORITY_OFFSET3_PS_POLL_SET(x)       (((x) << RX_PRIORITY_OFFSET3_PS_POLL_LSB) & RX_PRIORITY_OFFSET3_PS_POLL_MASK)
-#define RX_PRIORITY_OFFSET3_AMSDU_MSB            23
-#define RX_PRIORITY_OFFSET3_AMSDU_LSB            18
-#define RX_PRIORITY_OFFSET3_AMSDU_MASK           0x00fc0000
-#define RX_PRIORITY_OFFSET3_AMSDU_GET(x)         (((x) & RX_PRIORITY_OFFSET3_AMSDU_MASK) >> RX_PRIORITY_OFFSET3_AMSDU_LSB)
-#define RX_PRIORITY_OFFSET3_AMSDU_SET(x)         (((x) << RX_PRIORITY_OFFSET3_AMSDU_LSB) & RX_PRIORITY_OFFSET3_AMSDU_MASK)
-#define RX_PRIORITY_OFFSET3_AMPDU_MSB            17
-#define RX_PRIORITY_OFFSET3_AMPDU_LSB            12
-#define RX_PRIORITY_OFFSET3_AMPDU_MASK           0x0003f000
-#define RX_PRIORITY_OFFSET3_AMPDU_GET(x)         (((x) & RX_PRIORITY_OFFSET3_AMPDU_MASK) >> RX_PRIORITY_OFFSET3_AMPDU_LSB)
-#define RX_PRIORITY_OFFSET3_AMPDU_SET(x)         (((x) << RX_PRIORITY_OFFSET3_AMPDU_LSB) & RX_PRIORITY_OFFSET3_AMPDU_MASK)
-#define RX_PRIORITY_OFFSET3_EOSP_MSB             11
-#define RX_PRIORITY_OFFSET3_EOSP_LSB             6
-#define RX_PRIORITY_OFFSET3_EOSP_MASK            0x00000fc0
-#define RX_PRIORITY_OFFSET3_EOSP_GET(x)          (((x) & RX_PRIORITY_OFFSET3_EOSP_MASK) >> RX_PRIORITY_OFFSET3_EOSP_LSB)
-#define RX_PRIORITY_OFFSET3_EOSP_SET(x)          (((x) << RX_PRIORITY_OFFSET3_EOSP_LSB) & RX_PRIORITY_OFFSET3_EOSP_MASK)
-#define RX_PRIORITY_OFFSET3_MORE_MSB             5
-#define RX_PRIORITY_OFFSET3_MORE_LSB             0
-#define RX_PRIORITY_OFFSET3_MORE_MASK            0x0000003f
-#define RX_PRIORITY_OFFSET3_MORE_GET(x)          (((x) & RX_PRIORITY_OFFSET3_MORE_MASK) >> RX_PRIORITY_OFFSET3_MORE_LSB)
-#define RX_PRIORITY_OFFSET3_MORE_SET(x)          (((x) << RX_PRIORITY_OFFSET3_MORE_LSB) & RX_PRIORITY_OFFSET3_MORE_MASK)
-
-#define RX_PRIORITY_OFFSET4_ADDRESS              0x00008394
-#define RX_PRIORITY_OFFSET4_OFFSET               0x00000394
-#define RX_PRIORITY_OFFSET4_BEACON_RSSI_HIGH_MSB 29
-#define RX_PRIORITY_OFFSET4_BEACON_RSSI_HIGH_LSB 24
-#define RX_PRIORITY_OFFSET4_BEACON_RSSI_HIGH_MASK 0x3f000000
-#define RX_PRIORITY_OFFSET4_BEACON_RSSI_HIGH_GET(x) (((x) & RX_PRIORITY_OFFSET4_BEACON_RSSI_HIGH_MASK) >> RX_PRIORITY_OFFSET4_BEACON_RSSI_HIGH_LSB)
-#define RX_PRIORITY_OFFSET4_BEACON_RSSI_HIGH_SET(x) (((x) << RX_PRIORITY_OFFSET4_BEACON_RSSI_HIGH_LSB) & RX_PRIORITY_OFFSET4_BEACON_RSSI_HIGH_MASK)
-#define RX_PRIORITY_OFFSET4_MGMT_RSSI_HIGH_MSB   23
-#define RX_PRIORITY_OFFSET4_MGMT_RSSI_HIGH_LSB   18
-#define RX_PRIORITY_OFFSET4_MGMT_RSSI_HIGH_MASK  0x00fc0000
-#define RX_PRIORITY_OFFSET4_MGMT_RSSI_HIGH_GET(x) (((x) & RX_PRIORITY_OFFSET4_MGMT_RSSI_HIGH_MASK) >> RX_PRIORITY_OFFSET4_MGMT_RSSI_HIGH_LSB)
-#define RX_PRIORITY_OFFSET4_MGMT_RSSI_HIGH_SET(x) (((x) << RX_PRIORITY_OFFSET4_MGMT_RSSI_HIGH_LSB) & RX_PRIORITY_OFFSET4_MGMT_RSSI_HIGH_MASK)
-#define RX_PRIORITY_OFFSET4_BEACON_SSID_MSB      17
-#define RX_PRIORITY_OFFSET4_BEACON_SSID_LSB      12
-#define RX_PRIORITY_OFFSET4_BEACON_SSID_MASK     0x0003f000
-#define RX_PRIORITY_OFFSET4_BEACON_SSID_GET(x)   (((x) & RX_PRIORITY_OFFSET4_BEACON_SSID_MASK) >> RX_PRIORITY_OFFSET4_BEACON_SSID_LSB)
-#define RX_PRIORITY_OFFSET4_BEACON_SSID_SET(x)   (((x) << RX_PRIORITY_OFFSET4_BEACON_SSID_LSB) & RX_PRIORITY_OFFSET4_BEACON_SSID_MASK)
-#define RX_PRIORITY_OFFSET4_NULL_MSB             11
-#define RX_PRIORITY_OFFSET4_NULL_LSB             6
-#define RX_PRIORITY_OFFSET4_NULL_MASK            0x00000fc0
-#define RX_PRIORITY_OFFSET4_NULL_GET(x)          (((x) & RX_PRIORITY_OFFSET4_NULL_MASK) >> RX_PRIORITY_OFFSET4_NULL_LSB)
-#define RX_PRIORITY_OFFSET4_NULL_SET(x)          (((x) << RX_PRIORITY_OFFSET4_NULL_LSB) & RX_PRIORITY_OFFSET4_NULL_MASK)
-#define RX_PRIORITY_OFFSET4_PREQ_MSB             5
-#define RX_PRIORITY_OFFSET4_PREQ_LSB             0
-#define RX_PRIORITY_OFFSET4_PREQ_MASK            0x0000003f
-#define RX_PRIORITY_OFFSET4_PREQ_GET(x)          (((x) & RX_PRIORITY_OFFSET4_PREQ_MASK) >> RX_PRIORITY_OFFSET4_PREQ_LSB)
-#define RX_PRIORITY_OFFSET4_PREQ_SET(x)          (((x) << RX_PRIORITY_OFFSET4_PREQ_LSB) & RX_PRIORITY_OFFSET4_PREQ_MASK)
-
-#define RX_PRIORITY_OFFSET5_ADDRESS              0x00008398
-#define RX_PRIORITY_OFFSET5_OFFSET               0x00000398
-#define RX_PRIORITY_OFFSET5_PS_POLL_RSSI_HIGH_MSB 17
-#define RX_PRIORITY_OFFSET5_PS_POLL_RSSI_HIGH_LSB 12
-#define RX_PRIORITY_OFFSET5_PS_POLL_RSSI_HIGH_MASK 0x0003f000
-#define RX_PRIORITY_OFFSET5_PS_POLL_RSSI_HIGH_GET(x) (((x) & RX_PRIORITY_OFFSET5_PS_POLL_RSSI_HIGH_MASK) >> RX_PRIORITY_OFFSET5_PS_POLL_RSSI_HIGH_LSB)
-#define RX_PRIORITY_OFFSET5_PS_POLL_RSSI_HIGH_SET(x) (((x) << RX_PRIORITY_OFFSET5_PS_POLL_RSSI_HIGH_LSB) & RX_PRIORITY_OFFSET5_PS_POLL_RSSI_HIGH_MASK)
-#define RX_PRIORITY_OFFSET5_PREQ_RSSI_HIGH_MSB   11
-#define RX_PRIORITY_OFFSET5_PREQ_RSSI_HIGH_LSB   6
-#define RX_PRIORITY_OFFSET5_PREQ_RSSI_HIGH_MASK  0x00000fc0
-#define RX_PRIORITY_OFFSET5_PREQ_RSSI_HIGH_GET(x) (((x) & RX_PRIORITY_OFFSET5_PREQ_RSSI_HIGH_MASK) >> RX_PRIORITY_OFFSET5_PREQ_RSSI_HIGH_LSB)
-#define RX_PRIORITY_OFFSET5_PREQ_RSSI_HIGH_SET(x) (((x) << RX_PRIORITY_OFFSET5_PREQ_RSSI_HIGH_LSB) & RX_PRIORITY_OFFSET5_PREQ_RSSI_HIGH_MASK)
-#define RX_PRIORITY_OFFSET5_NULL_RSSI_HIGH_MSB   5
-#define RX_PRIORITY_OFFSET5_NULL_RSSI_HIGH_LSB   0
-#define RX_PRIORITY_OFFSET5_NULL_RSSI_HIGH_MASK  0x0000003f
-#define RX_PRIORITY_OFFSET5_NULL_RSSI_HIGH_GET(x) (((x) & RX_PRIORITY_OFFSET5_NULL_RSSI_HIGH_MASK) >> RX_PRIORITY_OFFSET5_NULL_RSSI_HIGH_LSB)
-#define RX_PRIORITY_OFFSET5_NULL_RSSI_HIGH_SET(x) (((x) << RX_PRIORITY_OFFSET5_NULL_RSSI_HIGH_LSB) & RX_PRIORITY_OFFSET5_NULL_RSSI_HIGH_MASK)
-
-#define MAC_PCU_BSSID2_L32_ADDRESS               0x0000839c
-#define MAC_PCU_BSSID2_L32_OFFSET                0x0000039c
-#define MAC_PCU_BSSID2_L32_ADDR_MSB              31
-#define MAC_PCU_BSSID2_L32_ADDR_LSB              0
-#define MAC_PCU_BSSID2_L32_ADDR_MASK             0xffffffff
-#define MAC_PCU_BSSID2_L32_ADDR_GET(x)           (((x) & MAC_PCU_BSSID2_L32_ADDR_MASK) >> MAC_PCU_BSSID2_L32_ADDR_LSB)
-#define MAC_PCU_BSSID2_L32_ADDR_SET(x)           (((x) << MAC_PCU_BSSID2_L32_ADDR_LSB) & MAC_PCU_BSSID2_L32_ADDR_MASK)
-
-#define MAC_PCU_BSSID2_U16_ADDRESS               0x000083a0
-#define MAC_PCU_BSSID2_U16_OFFSET                0x000003a0
-#define MAC_PCU_BSSID2_U16_ENABLE_MSB            16
-#define MAC_PCU_BSSID2_U16_ENABLE_LSB            16
-#define MAC_PCU_BSSID2_U16_ENABLE_MASK           0x00010000
-#define MAC_PCU_BSSID2_U16_ENABLE_GET(x)         (((x) & MAC_PCU_BSSID2_U16_ENABLE_MASK) >> MAC_PCU_BSSID2_U16_ENABLE_LSB)
-#define MAC_PCU_BSSID2_U16_ENABLE_SET(x)         (((x) << MAC_PCU_BSSID2_U16_ENABLE_LSB) & MAC_PCU_BSSID2_U16_ENABLE_MASK)
-#define MAC_PCU_BSSID2_U16_ADDR_MSB              15
-#define MAC_PCU_BSSID2_U16_ADDR_LSB              0
-#define MAC_PCU_BSSID2_U16_ADDR_MASK             0x0000ffff
-#define MAC_PCU_BSSID2_U16_ADDR_GET(x)           (((x) & MAC_PCU_BSSID2_U16_ADDR_MASK) >> MAC_PCU_BSSID2_U16_ADDR_LSB)
-#define MAC_PCU_BSSID2_U16_ADDR_SET(x)           (((x) << MAC_PCU_BSSID2_U16_ADDR_LSB) & MAC_PCU_BSSID2_U16_ADDR_MASK)
-
-#define MAC_PCU_TSF1_STATUS_L32_ADDRESS          0x000083a4
-#define MAC_PCU_TSF1_STATUS_L32_OFFSET           0x000003a4
-#define MAC_PCU_TSF1_STATUS_L32_VALUE_MSB        31
-#define MAC_PCU_TSF1_STATUS_L32_VALUE_LSB        0
-#define MAC_PCU_TSF1_STATUS_L32_VALUE_MASK       0xffffffff
-#define MAC_PCU_TSF1_STATUS_L32_VALUE_GET(x)     (((x) & MAC_PCU_TSF1_STATUS_L32_VALUE_MASK) >> MAC_PCU_TSF1_STATUS_L32_VALUE_LSB)
-#define MAC_PCU_TSF1_STATUS_L32_VALUE_SET(x)     (((x) << MAC_PCU_TSF1_STATUS_L32_VALUE_LSB) & MAC_PCU_TSF1_STATUS_L32_VALUE_MASK)
-
-#define MAC_PCU_TSF1_STATUS_U32_ADDRESS          0x000083a8
-#define MAC_PCU_TSF1_STATUS_U32_OFFSET           0x000003a8
-#define MAC_PCU_TSF1_STATUS_U32_VALUE_MSB        31
-#define MAC_PCU_TSF1_STATUS_U32_VALUE_LSB        0
-#define MAC_PCU_TSF1_STATUS_U32_VALUE_MASK       0xffffffff
-#define MAC_PCU_TSF1_STATUS_U32_VALUE_GET(x)     (((x) & MAC_PCU_TSF1_STATUS_U32_VALUE_MASK) >> MAC_PCU_TSF1_STATUS_U32_VALUE_LSB)
-#define MAC_PCU_TSF1_STATUS_U32_VALUE_SET(x)     (((x) << MAC_PCU_TSF1_STATUS_U32_VALUE_LSB) & MAC_PCU_TSF1_STATUS_U32_VALUE_MASK)
-
-#define MAC_PCU_TSF2_STATUS_L32_ADDRESS          0x000083ac
-#define MAC_PCU_TSF2_STATUS_L32_OFFSET           0x000003ac
-#define MAC_PCU_TSF2_STATUS_L32_VALUE_MSB        31
-#define MAC_PCU_TSF2_STATUS_L32_VALUE_LSB        0
-#define MAC_PCU_TSF2_STATUS_L32_VALUE_MASK       0xffffffff
-#define MAC_PCU_TSF2_STATUS_L32_VALUE_GET(x)     (((x) & MAC_PCU_TSF2_STATUS_L32_VALUE_MASK) >> MAC_PCU_TSF2_STATUS_L32_VALUE_LSB)
-#define MAC_PCU_TSF2_STATUS_L32_VALUE_SET(x)     (((x) << MAC_PCU_TSF2_STATUS_L32_VALUE_LSB) & MAC_PCU_TSF2_STATUS_L32_VALUE_MASK)
-
-#define MAC_PCU_TSF2_STATUS_U32_ADDRESS          0x000083b0
-#define MAC_PCU_TSF2_STATUS_U32_OFFSET           0x000003b0
-#define MAC_PCU_TSF2_STATUS_U32_VALUE_MSB        31
-#define MAC_PCU_TSF2_STATUS_U32_VALUE_LSB        0
-#define MAC_PCU_TSF2_STATUS_U32_VALUE_MASK       0xffffffff
-#define MAC_PCU_TSF2_STATUS_U32_VALUE_GET(x)     (((x) & MAC_PCU_TSF2_STATUS_U32_VALUE_MASK) >> MAC_PCU_TSF2_STATUS_U32_VALUE_LSB)
-#define MAC_PCU_TSF2_STATUS_U32_VALUE_SET(x)     (((x) << MAC_PCU_TSF2_STATUS_U32_VALUE_LSB) & MAC_PCU_TSF2_STATUS_U32_VALUE_MASK)
-
-#define MAC_PCU_TXBUF_BA_ADDRESS                 0x00008400
-#define MAC_PCU_TXBUF_BA_OFFSET                  0x00000400
-#define MAC_PCU_TXBUF_BA_DATA_MSB                31
-#define MAC_PCU_TXBUF_BA_DATA_LSB                0
-#define MAC_PCU_TXBUF_BA_DATA_MASK               0xffffffff
-#define MAC_PCU_TXBUF_BA_DATA_GET(x)             (((x) & MAC_PCU_TXBUF_BA_DATA_MASK) >> MAC_PCU_TXBUF_BA_DATA_LSB)
-#define MAC_PCU_TXBUF_BA_DATA_SET(x)             (((x) << MAC_PCU_TXBUF_BA_DATA_LSB) & MAC_PCU_TXBUF_BA_DATA_MASK)
-
-#define MAC_PCU_KEY_CACHE_1_ADDRESS              0x00008800
-#define MAC_PCU_KEY_CACHE_1_OFFSET               0x00000800
-#define MAC_PCU_KEY_CACHE_1_DATA_MSB             31
-#define MAC_PCU_KEY_CACHE_1_DATA_LSB             0
-#define MAC_PCU_KEY_CACHE_1_DATA_MASK            0xffffffff
-#define MAC_PCU_KEY_CACHE_1_DATA_GET(x)          (((x) & MAC_PCU_KEY_CACHE_1_DATA_MASK) >> MAC_PCU_KEY_CACHE_1_DATA_LSB)
-#define MAC_PCU_KEY_CACHE_1_DATA_SET(x)          (((x) << MAC_PCU_KEY_CACHE_1_DATA_LSB) & MAC_PCU_KEY_CACHE_1_DATA_MASK)
-
-#define MAC_PCU_BASEBAND_0_ADDRESS               0x00009800
-#define MAC_PCU_BASEBAND_0_OFFSET                0x00001800
-#define MAC_PCU_BASEBAND_0_DATA_MSB              31
-#define MAC_PCU_BASEBAND_0_DATA_LSB              0
-#define MAC_PCU_BASEBAND_0_DATA_MASK             0xffffffff
-#define MAC_PCU_BASEBAND_0_DATA_GET(x)           (((x) & MAC_PCU_BASEBAND_0_DATA_MASK) >> MAC_PCU_BASEBAND_0_DATA_LSB)
-#define MAC_PCU_BASEBAND_0_DATA_SET(x)           (((x) << MAC_PCU_BASEBAND_0_DATA_LSB) & MAC_PCU_BASEBAND_0_DATA_MASK)
-
-#define MAC_PCU_BASEBAND_1_ADDRESS               0x0000a000
-#define MAC_PCU_BASEBAND_1_OFFSET                0x00002000
-#define MAC_PCU_BASEBAND_1_DATA_MSB              31
-#define MAC_PCU_BASEBAND_1_DATA_LSB              0
-#define MAC_PCU_BASEBAND_1_DATA_MASK             0xffffffff
-#define MAC_PCU_BASEBAND_1_DATA_GET(x)           (((x) & MAC_PCU_BASEBAND_1_DATA_MASK) >> MAC_PCU_BASEBAND_1_DATA_LSB)
-#define MAC_PCU_BASEBAND_1_DATA_SET(x)           (((x) << MAC_PCU_BASEBAND_1_DATA_LSB) & MAC_PCU_BASEBAND_1_DATA_MASK)
-
-#define MAC_PCU_BASEBAND_2_ADDRESS               0x0000c000
-#define MAC_PCU_BASEBAND_2_OFFSET                0x00004000
-#define MAC_PCU_BASEBAND_2_DATA_MSB              31
-#define MAC_PCU_BASEBAND_2_DATA_LSB              0
-#define MAC_PCU_BASEBAND_2_DATA_MASK             0xffffffff
-#define MAC_PCU_BASEBAND_2_DATA_GET(x)           (((x) & MAC_PCU_BASEBAND_2_DATA_MASK) >> MAC_PCU_BASEBAND_2_DATA_LSB)
-#define MAC_PCU_BASEBAND_2_DATA_SET(x)           (((x) << MAC_PCU_BASEBAND_2_DATA_LSB) & MAC_PCU_BASEBAND_2_DATA_MASK)
-
-#define MAC_PCU_BASEBAND_3_ADDRESS               0x0000d000
-#define MAC_PCU_BASEBAND_3_OFFSET                0x00005000
-#define MAC_PCU_BASEBAND_3_DATA_MSB              31
-#define MAC_PCU_BASEBAND_3_DATA_LSB              0
-#define MAC_PCU_BASEBAND_3_DATA_MASK             0xffffffff
-#define MAC_PCU_BASEBAND_3_DATA_GET(x)           (((x) & MAC_PCU_BASEBAND_3_DATA_MASK) >> MAC_PCU_BASEBAND_3_DATA_LSB)
-#define MAC_PCU_BASEBAND_3_DATA_SET(x)           (((x) << MAC_PCU_BASEBAND_3_DATA_LSB) & MAC_PCU_BASEBAND_3_DATA_MASK)
-
-#define MAC_PCU_BUF_ADDRESS                      0x0000e000
-#define MAC_PCU_BUF_OFFSET                       0x00006000
-#define MAC_PCU_BUF_DATA_MSB                     31
-#define MAC_PCU_BUF_DATA_LSB                     0
-#define MAC_PCU_BUF_DATA_MASK                    0xffffffff
-#define MAC_PCU_BUF_DATA_GET(x)                  (((x) & MAC_PCU_BUF_DATA_MASK) >> MAC_PCU_BUF_DATA_LSB)
-#define MAC_PCU_BUF_DATA_SET(x)                  (((x) << MAC_PCU_BUF_DATA_LSB) & MAC_PCU_BUF_DATA_MASK)
-
-
-#ifndef __ASSEMBLER__
-
-typedef struct mac_pcu_reg_s {
-  volatile unsigned int mac_pcu_sta_addr_l32;
-  volatile unsigned int mac_pcu_sta_addr_u16;
-  volatile unsigned int mac_pcu_bssid_l32;
-  volatile unsigned int mac_pcu_bssid_u16;
-  volatile unsigned int mac_pcu_bcn_rssi_ave;
-  volatile unsigned int mac_pcu_ack_cts_timeout;
-  volatile unsigned int mac_pcu_bcn_rssi_ctl;
-  volatile unsigned int mac_pcu_usec_latency;
-  volatile unsigned int pcu_max_cfp_dur;
-  volatile unsigned int mac_pcu_rx_filter;
-  volatile unsigned int mac_pcu_mcast_filter_l32;
-  volatile unsigned int mac_pcu_mcast_filter_u32;
-  volatile unsigned int mac_pcu_diag_sw;
-  volatile unsigned int mac_pcu_tst_addac;
-  volatile unsigned int mac_pcu_def_antenna;
-  volatile unsigned int mac_pcu_aes_mute_mask_0;
-  volatile unsigned int mac_pcu_aes_mute_mask_1;
-  volatile unsigned int mac_pcu_gated_clks;
-  volatile unsigned int mac_pcu_obs_bus_2;
-  volatile unsigned int mac_pcu_obs_bus_1;
-  volatile unsigned int mac_pcu_dym_mimo_pwr_save;
-  volatile unsigned int mac_pcu_last_beacon_tsf;
-  volatile unsigned int mac_pcu_nav;
-  volatile unsigned int mac_pcu_rts_success_cnt;
-  volatile unsigned int mac_pcu_rts_fail_cnt;
-  volatile unsigned int mac_pcu_ack_fail_cnt;
-  volatile unsigned int mac_pcu_fcs_fail_cnt;
-  volatile unsigned int mac_pcu_beacon_cnt;
-  volatile unsigned int mac_pcu_xrmode;
-  volatile unsigned int mac_pcu_xrdel;
-  volatile unsigned int mac_pcu_xrto;
-  volatile unsigned int mac_pcu_xrcrp;
-  volatile unsigned int mac_pcu_xrstmp;
-  volatile unsigned int mac_pcu_addr1_mask_l32;
-  volatile unsigned int mac_pcu_addr1_mask_u16;
-  volatile unsigned int mac_pcu_tpc;
-  volatile unsigned int mac_pcu_tx_frame_cnt;
-  volatile unsigned int mac_pcu_rx_frame_cnt;
-  volatile unsigned int mac_pcu_rx_clear_cnt;
-  volatile unsigned int mac_pcu_cycle_cnt;
-  volatile unsigned int mac_pcu_quiet_time_1;
-  volatile unsigned int mac_pcu_quiet_time_2;
-  volatile unsigned int mac_pcu_qos_no_ack;
-  volatile unsigned int mac_pcu_phy_error_mask;
-  volatile unsigned int mac_pcu_xrlat;
-  volatile unsigned int mac_pcu_rxbuf;
-  volatile unsigned int mac_pcu_mic_qos_control;
-  volatile unsigned int mac_pcu_mic_qos_select;
-  volatile unsigned int mac_pcu_misc_mode;
-  volatile unsigned int mac_pcu_filter_ofdm_cnt;
-  volatile unsigned int mac_pcu_filter_cck_cnt;
-  volatile unsigned int mac_pcu_phy_err_cnt_1;
-  volatile unsigned int mac_pcu_phy_err_cnt_1_mask;
-  volatile unsigned int mac_pcu_phy_err_cnt_2;
-  volatile unsigned int mac_pcu_phy_err_cnt_2_mask;
-  volatile unsigned int mac_pcu_tsf_threshold;
-  volatile unsigned int mac_pcu_phy_error_eifs_mask;
-  volatile unsigned int mac_pcu_phy_err_cnt_3;
-  volatile unsigned int mac_pcu_phy_err_cnt_3_mask;
-  volatile unsigned int mac_pcu_bluetooth_mode;
-  volatile unsigned int mac_pcu_bluetooth_weights;
-  volatile unsigned int mac_pcu_bluetooth_mode2;
-  volatile unsigned int mac_pcu_txsifs;
-  volatile unsigned int mac_pcu_txop_x;
-  volatile unsigned int mac_pcu_txop_0_3;
-  volatile unsigned int mac_pcu_txop_4_7;
-  volatile unsigned int mac_pcu_txop_8_11;
-  volatile unsigned int mac_pcu_txop_12_15;
-  volatile unsigned int mac_pcu_logic_analyzer;
-  volatile unsigned int mac_pcu_logic_analyzer_32l;
-  volatile unsigned int mac_pcu_logic_analyzer_16u;
-  volatile unsigned int mac_pcu_phy_err_cnt_mask_cont;
-  volatile unsigned int mac_pcu_azimuth_mode;
-  volatile unsigned int mac_pcu_20_40_mode;
-  volatile unsigned int mac_pcu_rx_clear_diff_cnt;
-  volatile unsigned int mac_pcu_self_gen_antenna_mask;
-  volatile unsigned int mac_pcu_ba_bar_control;
-  volatile unsigned int mac_pcu_legacy_plcp_spoof;
-  volatile unsigned int mac_pcu_phy_error_mask_cont;
-  volatile unsigned int mac_pcu_tx_timer;
-  volatile unsigned int mac_pcu_txbuf_ctrl;
-  volatile unsigned int mac_pcu_misc_mode2;
-  volatile unsigned int mac_pcu_alt_aes_mute_mask;
-  volatile unsigned int mac_pcu_azimuth_time_stamp;
-  volatile unsigned int mac_pcu_max_cfp_dur;
-  volatile unsigned int mac_pcu_hcf_timeout;
-  volatile unsigned int mac_pcu_bluetooth_weights2;
-  volatile unsigned int mac_pcu_bluetooth_tsf_bt_active;
-  volatile unsigned int mac_pcu_bluetooth_tsf_bt_priority;
-  volatile unsigned int mac_pcu_bluetooth_mode3;
-  volatile unsigned int mac_pcu_bluetooth_mode4;
-  unsigned char pad0[148]; /* pad to 0x200 */
-  volatile unsigned int mac_pcu_bt_bt[64];
-  volatile unsigned int mac_pcu_bt_bt_async;
-  volatile unsigned int mac_pcu_bt_wl_1;
-  volatile unsigned int mac_pcu_bt_wl_2;
-  volatile unsigned int mac_pcu_bt_wl_3;
-  volatile unsigned int mac_pcu_bt_wl_4;
-  volatile unsigned int mac_pcu_coex_epta;
-  volatile unsigned int mac_pcu_coex_lnamaxgain1;
-  volatile unsigned int mac_pcu_coex_lnamaxgain2;
-  volatile unsigned int mac_pcu_coex_lnamaxgain3;
-  volatile unsigned int mac_pcu_coex_lnamaxgain4;
-  volatile unsigned int mac_pcu_basic_rate_set0;
-  volatile unsigned int mac_pcu_basic_rate_set1;
-  volatile unsigned int mac_pcu_basic_rate_set2;
-  volatile unsigned int mac_pcu_basic_rate_set3;
-  volatile unsigned int mac_pcu_rx_int_status0;
-  volatile unsigned int mac_pcu_rx_int_status1;
-  volatile unsigned int mac_pcu_rx_int_status2;
-  volatile unsigned int mac_pcu_rx_int_status3;
-  volatile unsigned int ht_half_gi_rate1;
-  volatile unsigned int ht_half_gi_rate2;
-  volatile unsigned int ht_full_gi_rate1;
-  volatile unsigned int ht_full_gi_rate2;
-  volatile unsigned int legacy_rate1;
-  volatile unsigned int legacy_rate2;
-  volatile unsigned int legacy_rate3;
-  volatile unsigned int rx_int_filter;
-  volatile unsigned int rx_int_overflow;
-  volatile unsigned int rx_filter_thresh;
-  volatile unsigned int rx_filter_thresh1;
-  volatile unsigned int rx_priority_thresh0;
-  volatile unsigned int rx_priority_thresh1;
-  volatile unsigned int rx_priority_thresh2;
-  volatile unsigned int rx_priority_thresh3;
-  volatile unsigned int rx_priority_offset0;
-  volatile unsigned int rx_priority_offset1;
-  volatile unsigned int rx_priority_offset2;
-  volatile unsigned int rx_priority_offset3;
-  volatile unsigned int rx_priority_offset4;
-  volatile unsigned int rx_priority_offset5;
-  volatile unsigned int mac_pcu_bssid2_l32;
-  volatile unsigned int mac_pcu_bssid2_u16;
-  volatile unsigned int mac_pcu_tsf1_status_l32;
-  volatile unsigned int mac_pcu_tsf1_status_u32;
-  volatile unsigned int mac_pcu_tsf2_status_l32;
-  volatile unsigned int mac_pcu_tsf2_status_u32;
-  unsigned char pad1[76]; /* pad to 0x400 */
-  volatile unsigned int mac_pcu_txbuf_ba[64];
-  unsigned char pad2[768]; /* pad to 0x800 */
-  volatile unsigned int mac_pcu_key_cache_1[256];
-  unsigned char pad3[3072]; /* pad to 0x1800 */
-  volatile unsigned int mac_pcu_baseband_0[512];
-  volatile unsigned int mac_pcu_baseband_1[2048];
-  volatile unsigned int mac_pcu_baseband_2[1024];
-  volatile unsigned int mac_pcu_baseband_3[1024];
-  volatile unsigned int mac_pcu_buf[512];
-} mac_pcu_reg_t;
-
-#endif /* __ASSEMBLER__ */
-
-#endif /* _MAC_PCU_H_ */
diff -druN linux-2.6.39-libre/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/mbox_host_reg.h linux-3.0-rc7-libre/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/mbox_host_reg.h
--- linux-2.6.39-libre/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/mbox_host_reg.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/mbox_host_reg.h	2011-07-11 19:51:52.000000000 -0400
@@ -21,17 +21,4 @@
 //===================================================================
 
 
-#ifdef WLAN_HEADERS
-
 #include "mbox_wlan_host_reg.h"
-
-
-#ifndef BT_HEADERS
-
-
-
-#endif
-#endif
-
-
-
diff -druN linux-2.6.39-libre/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/mbox_reg.h linux-3.0-rc7-libre/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/mbox_reg.h
--- linux-2.6.39-libre/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/mbox_reg.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/mbox_reg.h	2011-07-11 19:51:52.000000000 -0400
@@ -21,11 +21,8 @@
 //===================================================================
 
 
-#ifdef WLAN_HEADERS
-
 #include "mbox_wlan_reg.h"
 
-
 #ifndef BT_HEADERS
 
 #define MBOX_FIFO_ADDRESS WLAN_MBOX_FIFO_ADDRESS
@@ -552,9 +549,4 @@
 #define HOST_IF_WINDOW_DATA_GET(x) WLAN_HOST_IF_WINDOW_DATA_GET(x)
 #define HOST_IF_WINDOW_DATA_SET(x) WLAN_HOST_IF_WINDOW_DATA_SET(x)
 
-
 #endif
-#endif
-
-
-
diff -druN linux-2.6.39-libre/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/mbox_wlan_host_reg.h linux-3.0-rc7-libre/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/mbox_wlan_host_reg.h
--- linux-2.6.39-libre/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/mbox_wlan_host_reg.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/mbox_wlan_host_reg.h	2011-07-11 19:51:52.000000000 -0400
@@ -468,55 +468,4 @@
 #define CIS_WINDOW_DATA_SET(x)                   (((x) << CIS_WINDOW_DATA_LSB) & CIS_WINDOW_DATA_MASK)
 
 
-#ifndef __ASSEMBLER__
-
-typedef struct mbox_wlan_host_reg_reg_s {
-  unsigned char pad0[1024]; /* pad to 0x400 */
-  volatile unsigned char host_int_status;
-  volatile unsigned char cpu_int_status;
-  volatile unsigned char error_int_status;
-  volatile unsigned char counter_int_status;
-  volatile unsigned char mbox_frame;
-  volatile unsigned char rx_lookahead_valid;
-  volatile unsigned char host_int_status2;
-  volatile unsigned char gmbox_rx_avail;
-  volatile unsigned char rx_lookahead0[4];
-  volatile unsigned char rx_lookahead1[4];
-  volatile unsigned char rx_lookahead2[4];
-  volatile unsigned char rx_lookahead3[4];
-  volatile unsigned char int_status_enable;
-  volatile unsigned char cpu_int_status_enable;
-  volatile unsigned char error_status_enable;
-  volatile unsigned char counter_int_status_enable;
-  unsigned char pad1[4]; /* pad to 0x420 */
-  volatile unsigned char count[8];
-  unsigned char pad2[24]; /* pad to 0x440 */
-  volatile unsigned char count_dec[32];
-  volatile unsigned char scratch[8];
-  volatile unsigned char fifo_timeout;
-  volatile unsigned char fifo_timeout_enable;
-  volatile unsigned char disable_sleep;
-  unsigned char pad3[5]; /* pad to 0x470 */
-  volatile unsigned char local_bus;
-  unsigned char pad4[1]; /* pad to 0x472 */
-  volatile unsigned char int_wlan;
-  unsigned char pad5[1]; /* pad to 0x474 */
-  volatile unsigned char window_data[4];
-  volatile unsigned char window_write_addr[4];
-  volatile unsigned char window_read_addr[4];
-  volatile unsigned char host_ctrl_spi_config;
-  volatile unsigned char host_ctrl_spi_status;
-  volatile unsigned char non_assoc_sleep_en;
-  volatile unsigned char cpu_dbg_sel;
-  volatile unsigned char cpu_dbg[4];
-  volatile unsigned char int_status2_enable;
-  unsigned char pad6[7]; /* pad to 0x490 */
-  volatile unsigned char gmbox_rx_lookahead[8];
-  volatile unsigned char gmbox_rx_lookahead_mux;
-  unsigned char pad7[359]; /* pad to 0x600 */
-  volatile unsigned char cis_window[512];
-} mbox_wlan_host_reg_reg_t;
-
-#endif /* __ASSEMBLER__ */
-
 #endif /* _MBOX_WLAN_HOST_REG_H_ */
diff -druN linux-2.6.39-libre/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/mbox_wlan_reg.h linux-3.0-rc7-libre/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/mbox_wlan_reg.h
--- linux-2.6.39-libre/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/mbox_wlan_reg.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/mbox_wlan_reg.h	2011-07-11 19:51:52.000000000 -0400
@@ -586,53 +586,4 @@
 #define WLAN_HOST_IF_WINDOW_DATA_GET(x)          (((x) & WLAN_HOST_IF_WINDOW_DATA_MASK) >> WLAN_HOST_IF_WINDOW_DATA_LSB)
 #define WLAN_HOST_IF_WINDOW_DATA_SET(x)          (((x) << WLAN_HOST_IF_WINDOW_DATA_LSB) & WLAN_HOST_IF_WINDOW_DATA_MASK)
 
-
-#ifndef __ASSEMBLER__
-
-typedef struct mbox_wlan_reg_reg_s {
-  volatile unsigned int wlan_mbox_fifo[4];
-  volatile unsigned int wlan_mbox_fifo_status;
-  volatile unsigned int wlan_mbox_dma_policy;
-  volatile unsigned int wlan_mbox0_dma_rx_descriptor_base;
-  volatile unsigned int wlan_mbox0_dma_rx_control;
-  volatile unsigned int wlan_mbox0_dma_tx_descriptor_base;
-  volatile unsigned int wlan_mbox0_dma_tx_control;
-  volatile unsigned int wlan_mbox1_dma_rx_descriptor_base;
-  volatile unsigned int wlan_mbox1_dma_rx_control;
-  volatile unsigned int wlan_mbox1_dma_tx_descriptor_base;
-  volatile unsigned int wlan_mbox1_dma_tx_control;
-  volatile unsigned int wlan_mbox2_dma_rx_descriptor_base;
-  volatile unsigned int wlan_mbox2_dma_rx_control;
-  volatile unsigned int wlan_mbox2_dma_tx_descriptor_base;
-  volatile unsigned int wlan_mbox2_dma_tx_control;
-  volatile unsigned int wlan_mbox3_dma_rx_descriptor_base;
-  volatile unsigned int wlan_mbox3_dma_rx_control;
-  volatile unsigned int wlan_mbox3_dma_tx_descriptor_base;
-  volatile unsigned int wlan_mbox3_dma_tx_control;
-  volatile unsigned int wlan_mbox_int_status;
-  volatile unsigned int wlan_mbox_int_enable;
-  volatile unsigned int wlan_int_host;
-  unsigned char pad0[28]; /* pad to 0x80 */
-  volatile unsigned int wlan_local_count[8];
-  volatile unsigned int wlan_count_inc[8];
-  volatile unsigned int wlan_local_scratch[8];
-  volatile unsigned int wlan_use_local_bus;
-  volatile unsigned int wlan_sdio_config;
-  volatile unsigned int wlan_mbox_debug;
-  volatile unsigned int wlan_mbox_fifo_reset;
-  volatile unsigned int wlan_mbox_txfifo_pop[4];
-  volatile unsigned int wlan_mbox_rxfifo_pop[4];
-  volatile unsigned int wlan_sdio_debug;
-  volatile unsigned int wlan_gmbox0_dma_rx_descriptor_base;
-  volatile unsigned int wlan_gmbox0_dma_rx_control;
-  volatile unsigned int wlan_gmbox0_dma_tx_descriptor_base;
-  volatile unsigned int wlan_gmbox0_dma_tx_control;
-  volatile unsigned int wlan_gmbox_int_status;
-  volatile unsigned int wlan_gmbox_int_enable;
-  unsigned char pad1[7892]; /* pad to 0x2000 */
-  volatile unsigned int wlan_host_if_window[2048];
-} mbox_wlan_reg_reg_t;
-
-#endif /* __ASSEMBLER__ */
-
 #endif /* _MBOX_WLAN_REG_H_ */
diff -druN linux-2.6.39-libre/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/rdma_reg.h linux-3.0-rc7-libre/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/rdma_reg.h
--- linux-2.6.39-libre/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/rdma_reg.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/rdma_reg.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,564 +0,0 @@
-// ------------------------------------------------------------------
-// Copyright (c) 2004-2010 Atheros Corporation.  All rights reserved.
-// 
-//
-// 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.
-//
-//
-// ------------------------------------------------------------------
-//===================================================================
-// Author(s): ="Atheros"
-//===================================================================
-
-
-#ifndef _RDMA_REG_REG_H_
-#define _RDMA_REG_REG_H_
-
-#define DMA_CONFIG_ADDRESS                       0x00000000
-#define DMA_CONFIG_OFFSET                        0x00000000
-#define DMA_CONFIG_WLBB_PWD_EN_MSB               4
-#define DMA_CONFIG_WLBB_PWD_EN_LSB               4
-#define DMA_CONFIG_WLBB_PWD_EN_MASK              0x00000010
-#define DMA_CONFIG_WLBB_PWD_EN_GET(x)            (((x) & DMA_CONFIG_WLBB_PWD_EN_MASK) >> DMA_CONFIG_WLBB_PWD_EN_LSB)
-#define DMA_CONFIG_WLBB_PWD_EN_SET(x)            (((x) << DMA_CONFIG_WLBB_PWD_EN_LSB) & DMA_CONFIG_WLBB_PWD_EN_MASK)
-#define DMA_CONFIG_WLMAC_PWD_EN_MSB              3
-#define DMA_CONFIG_WLMAC_PWD_EN_LSB              3
-#define DMA_CONFIG_WLMAC_PWD_EN_MASK             0x00000008
-#define DMA_CONFIG_WLMAC_PWD_EN_GET(x)           (((x) & DMA_CONFIG_WLMAC_PWD_EN_MASK) >> DMA_CONFIG_WLMAC_PWD_EN_LSB)
-#define DMA_CONFIG_WLMAC_PWD_EN_SET(x)           (((x) << DMA_CONFIG_WLMAC_PWD_EN_LSB) & DMA_CONFIG_WLMAC_PWD_EN_MASK)
-#define DMA_CONFIG_ENABLE_RETENTION_MSB          2
-#define DMA_CONFIG_ENABLE_RETENTION_LSB          2
-#define DMA_CONFIG_ENABLE_RETENTION_MASK         0x00000004
-#define DMA_CONFIG_ENABLE_RETENTION_GET(x)       (((x) & DMA_CONFIG_ENABLE_RETENTION_MASK) >> DMA_CONFIG_ENABLE_RETENTION_LSB)
-#define DMA_CONFIG_ENABLE_RETENTION_SET(x)       (((x) << DMA_CONFIG_ENABLE_RETENTION_LSB) & DMA_CONFIG_ENABLE_RETENTION_MASK)
-#define DMA_CONFIG_RTC_PRIORITY_MSB              1
-#define DMA_CONFIG_RTC_PRIORITY_LSB              1
-#define DMA_CONFIG_RTC_PRIORITY_MASK             0x00000002
-#define DMA_CONFIG_RTC_PRIORITY_GET(x)           (((x) & DMA_CONFIG_RTC_PRIORITY_MASK) >> DMA_CONFIG_RTC_PRIORITY_LSB)
-#define DMA_CONFIG_RTC_PRIORITY_SET(x)           (((x) << DMA_CONFIG_RTC_PRIORITY_LSB) & DMA_CONFIG_RTC_PRIORITY_MASK)
-#define DMA_CONFIG_DMA_TYPE_MSB                  0
-#define DMA_CONFIG_DMA_TYPE_LSB                  0
-#define DMA_CONFIG_DMA_TYPE_MASK                 0x00000001
-#define DMA_CONFIG_DMA_TYPE_GET(x)               (((x) & DMA_CONFIG_DMA_TYPE_MASK) >> DMA_CONFIG_DMA_TYPE_LSB)
-#define DMA_CONFIG_DMA_TYPE_SET(x)               (((x) << DMA_CONFIG_DMA_TYPE_LSB) & DMA_CONFIG_DMA_TYPE_MASK)
-
-#define DMA_CONTROL_ADDRESS                      0x00000004
-#define DMA_CONTROL_OFFSET                       0x00000004
-#define DMA_CONTROL_START_MSB                    1
-#define DMA_CONTROL_START_LSB                    1
-#define DMA_CONTROL_START_MASK                   0x00000002
-#define DMA_CONTROL_START_GET(x)                 (((x) & DMA_CONTROL_START_MASK) >> DMA_CONTROL_START_LSB)
-#define DMA_CONTROL_START_SET(x)                 (((x) << DMA_CONTROL_START_LSB) & DMA_CONTROL_START_MASK)
-#define DMA_CONTROL_STOP_MSB                     0
-#define DMA_CONTROL_STOP_LSB                     0
-#define DMA_CONTROL_STOP_MASK                    0x00000001
-#define DMA_CONTROL_STOP_GET(x)                  (((x) & DMA_CONTROL_STOP_MASK) >> DMA_CONTROL_STOP_LSB)
-#define DMA_CONTROL_STOP_SET(x)                  (((x) << DMA_CONTROL_STOP_LSB) & DMA_CONTROL_STOP_MASK)
-
-#define DMA_SRC_ADDRESS                          0x00000008
-#define DMA_SRC_OFFSET                           0x00000008
-#define DMA_SRC_ADDR_MSB                         31
-#define DMA_SRC_ADDR_LSB                         2
-#define DMA_SRC_ADDR_MASK                        0xfffffffc
-#define DMA_SRC_ADDR_GET(x)                      (((x) & DMA_SRC_ADDR_MASK) >> DMA_SRC_ADDR_LSB)
-#define DMA_SRC_ADDR_SET(x)                      (((x) << DMA_SRC_ADDR_LSB) & DMA_SRC_ADDR_MASK)
-
-#define DMA_DEST_ADDRESS                         0x0000000c
-#define DMA_DEST_OFFSET                          0x0000000c
-#define DMA_DEST_ADDR_MSB                        31
-#define DMA_DEST_ADDR_LSB                        2
-#define DMA_DEST_ADDR_MASK                       0xfffffffc
-#define DMA_DEST_ADDR_GET(x)                     (((x) & DMA_DEST_ADDR_MASK) >> DMA_DEST_ADDR_LSB)
-#define DMA_DEST_ADDR_SET(x)                     (((x) << DMA_DEST_ADDR_LSB) & DMA_DEST_ADDR_MASK)
-
-#define DMA_LENGTH_ADDRESS                       0x00000010
-#define DMA_LENGTH_OFFSET                        0x00000010
-#define DMA_LENGTH_WORDS_MSB                     11
-#define DMA_LENGTH_WORDS_LSB                     0
-#define DMA_LENGTH_WORDS_MASK                    0x00000fff
-#define DMA_LENGTH_WORDS_GET(x)                  (((x) & DMA_LENGTH_WORDS_MASK) >> DMA_LENGTH_WORDS_LSB)
-#define DMA_LENGTH_WORDS_SET(x)                  (((x) << DMA_LENGTH_WORDS_LSB) & DMA_LENGTH_WORDS_MASK)
-
-#define VMC_BASE_ADDRESS                         0x00000014
-#define VMC_BASE_OFFSET                          0x00000014
-#define VMC_BASE_ADDR_MSB                        31
-#define VMC_BASE_ADDR_LSB                        2
-#define VMC_BASE_ADDR_MASK                       0xfffffffc
-#define VMC_BASE_ADDR_GET(x)                     (((x) & VMC_BASE_ADDR_MASK) >> VMC_BASE_ADDR_LSB)
-#define VMC_BASE_ADDR_SET(x)                     (((x) << VMC_BASE_ADDR_LSB) & VMC_BASE_ADDR_MASK)
-
-#define INDIRECT_REG_ADDRESS                     0x00000018
-#define INDIRECT_REG_OFFSET                      0x00000018
-#define INDIRECT_REG_ID_MSB                      31
-#define INDIRECT_REG_ID_LSB                      2
-#define INDIRECT_REG_ID_MASK                     0xfffffffc
-#define INDIRECT_REG_ID_GET(x)                   (((x) & INDIRECT_REG_ID_MASK) >> INDIRECT_REG_ID_LSB)
-#define INDIRECT_REG_ID_SET(x)                   (((x) << INDIRECT_REG_ID_LSB) & INDIRECT_REG_ID_MASK)
-
-#define INDIRECT_RETURN_ADDRESS                  0x0000001c
-#define INDIRECT_RETURN_OFFSET                   0x0000001c
-#define INDIRECT_RETURN_ADDR_MSB                 31
-#define INDIRECT_RETURN_ADDR_LSB                 2
-#define INDIRECT_RETURN_ADDR_MASK                0xfffffffc
-#define INDIRECT_RETURN_ADDR_GET(x)              (((x) & INDIRECT_RETURN_ADDR_MASK) >> INDIRECT_RETURN_ADDR_LSB)
-#define INDIRECT_RETURN_ADDR_SET(x)              (((x) << INDIRECT_RETURN_ADDR_LSB) & INDIRECT_RETURN_ADDR_MASK)
-
-#define RDMA_REGION_0__ADDRESS                   0x00000020
-#define RDMA_REGION_0__OFFSET                    0x00000020
-#define RDMA_REGION_0__ADDR_MSB                  31
-#define RDMA_REGION_0__ADDR_LSB                  13
-#define RDMA_REGION_0__ADDR_MASK                 0xffffe000
-#define RDMA_REGION_0__ADDR_GET(x)               (((x) & RDMA_REGION_0__ADDR_MASK) >> RDMA_REGION_0__ADDR_LSB)
-#define RDMA_REGION_0__ADDR_SET(x)               (((x) << RDMA_REGION_0__ADDR_LSB) & RDMA_REGION_0__ADDR_MASK)
-#define RDMA_REGION_0__LENGTH_MSB                12
-#define RDMA_REGION_0__LENGTH_LSB                2
-#define RDMA_REGION_0__LENGTH_MASK               0x00001ffc
-#define RDMA_REGION_0__LENGTH_GET(x)             (((x) & RDMA_REGION_0__LENGTH_MASK) >> RDMA_REGION_0__LENGTH_LSB)
-#define RDMA_REGION_0__LENGTH_SET(x)             (((x) << RDMA_REGION_0__LENGTH_LSB) & RDMA_REGION_0__LENGTH_MASK)
-#define RDMA_REGION_0__INDI_MSB                  1
-#define RDMA_REGION_0__INDI_LSB                  1
-#define RDMA_REGION_0__INDI_MASK                 0x00000002
-#define RDMA_REGION_0__INDI_GET(x)               (((x) & RDMA_REGION_0__INDI_MASK) >> RDMA_REGION_0__INDI_LSB)
-#define RDMA_REGION_0__INDI_SET(x)               (((x) << RDMA_REGION_0__INDI_LSB) & RDMA_REGION_0__INDI_MASK)
-#define RDMA_REGION_0__NEXT_MSB                  0
-#define RDMA_REGION_0__NEXT_LSB                  0
-#define RDMA_REGION_0__NEXT_MASK                 0x00000001
-#define RDMA_REGION_0__NEXT_GET(x)               (((x) & RDMA_REGION_0__NEXT_MASK) >> RDMA_REGION_0__NEXT_LSB)
-#define RDMA_REGION_0__NEXT_SET(x)               (((x) << RDMA_REGION_0__NEXT_LSB) & RDMA_REGION_0__NEXT_MASK)
-
-#define RDMA_REGION_1__ADDRESS                   0x00000024
-#define RDMA_REGION_1__OFFSET                    0x00000024
-#define RDMA_REGION_1__ADDR_MSB                  31
-#define RDMA_REGION_1__ADDR_LSB                  13
-#define RDMA_REGION_1__ADDR_MASK                 0xffffe000
-#define RDMA_REGION_1__ADDR_GET(x)               (((x) & RDMA_REGION_1__ADDR_MASK) >> RDMA_REGION_1__ADDR_LSB)
-#define RDMA_REGION_1__ADDR_SET(x)               (((x) << RDMA_REGION_1__ADDR_LSB) & RDMA_REGION_1__ADDR_MASK)
-#define RDMA_REGION_1__LENGTH_MSB                12
-#define RDMA_REGION_1__LENGTH_LSB                2
-#define RDMA_REGION_1__LENGTH_MASK               0x00001ffc
-#define RDMA_REGION_1__LENGTH_GET(x)             (((x) & RDMA_REGION_1__LENGTH_MASK) >> RDMA_REGION_1__LENGTH_LSB)
-#define RDMA_REGION_1__LENGTH_SET(x)             (((x) << RDMA_REGION_1__LENGTH_LSB) & RDMA_REGION_1__LENGTH_MASK)
-#define RDMA_REGION_1__INDI_MSB                  1
-#define RDMA_REGION_1__INDI_LSB                  1
-#define RDMA_REGION_1__INDI_MASK                 0x00000002
-#define RDMA_REGION_1__INDI_GET(x)               (((x) & RDMA_REGION_1__INDI_MASK) >> RDMA_REGION_1__INDI_LSB)
-#define RDMA_REGION_1__INDI_SET(x)               (((x) << RDMA_REGION_1__INDI_LSB) & RDMA_REGION_1__INDI_MASK)
-#define RDMA_REGION_1__NEXT_MSB                  0
-#define RDMA_REGION_1__NEXT_LSB                  0
-#define RDMA_REGION_1__NEXT_MASK                 0x00000001
-#define RDMA_REGION_1__NEXT_GET(x)               (((x) & RDMA_REGION_1__NEXT_MASK) >> RDMA_REGION_1__NEXT_LSB)
-#define RDMA_REGION_1__NEXT_SET(x)               (((x) << RDMA_REGION_1__NEXT_LSB) & RDMA_REGION_1__NEXT_MASK)
-
-#define RDMA_REGION_2__ADDRESS                   0x00000028
-#define RDMA_REGION_2__OFFSET                    0x00000028
-#define RDMA_REGION_2__ADDR_MSB                  31
-#define RDMA_REGION_2__ADDR_LSB                  13
-#define RDMA_REGION_2__ADDR_MASK                 0xffffe000
-#define RDMA_REGION_2__ADDR_GET(x)               (((x) & RDMA_REGION_2__ADDR_MASK) >> RDMA_REGION_2__ADDR_LSB)
-#define RDMA_REGION_2__ADDR_SET(x)               (((x) << RDMA_REGION_2__ADDR_LSB) & RDMA_REGION_2__ADDR_MASK)
-#define RDMA_REGION_2__LENGTH_MSB                12
-#define RDMA_REGION_2__LENGTH_LSB                2
-#define RDMA_REGION_2__LENGTH_MASK               0x00001ffc
-#define RDMA_REGION_2__LENGTH_GET(x)             (((x) & RDMA_REGION_2__LENGTH_MASK) >> RDMA_REGION_2__LENGTH_LSB)
-#define RDMA_REGION_2__LENGTH_SET(x)             (((x) << RDMA_REGION_2__LENGTH_LSB) & RDMA_REGION_2__LENGTH_MASK)
-#define RDMA_REGION_2__INDI_MSB                  1
-#define RDMA_REGION_2__INDI_LSB                  1
-#define RDMA_REGION_2__INDI_MASK                 0x00000002
-#define RDMA_REGION_2__INDI_GET(x)               (((x) & RDMA_REGION_2__INDI_MASK) >> RDMA_REGION_2__INDI_LSB)
-#define RDMA_REGION_2__INDI_SET(x)               (((x) << RDMA_REGION_2__INDI_LSB) & RDMA_REGION_2__INDI_MASK)
-#define RDMA_REGION_2__NEXT_MSB                  0
-#define RDMA_REGION_2__NEXT_LSB                  0
-#define RDMA_REGION_2__NEXT_MASK                 0x00000001
-#define RDMA_REGION_2__NEXT_GET(x)               (((x) & RDMA_REGION_2__NEXT_MASK) >> RDMA_REGION_2__NEXT_LSB)
-#define RDMA_REGION_2__NEXT_SET(x)               (((x) << RDMA_REGION_2__NEXT_LSB) & RDMA_REGION_2__NEXT_MASK)
-
-#define RDMA_REGION_3__ADDRESS                   0x0000002c
-#define RDMA_REGION_3__OFFSET                    0x0000002c
-#define RDMA_REGION_3__ADDR_MSB                  31
-#define RDMA_REGION_3__ADDR_LSB                  13
-#define RDMA_REGION_3__ADDR_MASK                 0xffffe000
-#define RDMA_REGION_3__ADDR_GET(x)               (((x) & RDMA_REGION_3__ADDR_MASK) >> RDMA_REGION_3__ADDR_LSB)
-#define RDMA_REGION_3__ADDR_SET(x)               (((x) << RDMA_REGION_3__ADDR_LSB) & RDMA_REGION_3__ADDR_MASK)
-#define RDMA_REGION_3__LENGTH_MSB                12
-#define RDMA_REGION_3__LENGTH_LSB                2
-#define RDMA_REGION_3__LENGTH_MASK               0x00001ffc
-#define RDMA_REGION_3__LENGTH_GET(x)             (((x) & RDMA_REGION_3__LENGTH_MASK) >> RDMA_REGION_3__LENGTH_LSB)
-#define RDMA_REGION_3__LENGTH_SET(x)             (((x) << RDMA_REGION_3__LENGTH_LSB) & RDMA_REGION_3__LENGTH_MASK)
-#define RDMA_REGION_3__INDI_MSB                  1
-#define RDMA_REGION_3__INDI_LSB                  1
-#define RDMA_REGION_3__INDI_MASK                 0x00000002
-#define RDMA_REGION_3__INDI_GET(x)               (((x) & RDMA_REGION_3__INDI_MASK) >> RDMA_REGION_3__INDI_LSB)
-#define RDMA_REGION_3__INDI_SET(x)               (((x) << RDMA_REGION_3__INDI_LSB) & RDMA_REGION_3__INDI_MASK)
-#define RDMA_REGION_3__NEXT_MSB                  0
-#define RDMA_REGION_3__NEXT_LSB                  0
-#define RDMA_REGION_3__NEXT_MASK                 0x00000001
-#define RDMA_REGION_3__NEXT_GET(x)               (((x) & RDMA_REGION_3__NEXT_MASK) >> RDMA_REGION_3__NEXT_LSB)
-#define RDMA_REGION_3__NEXT_SET(x)               (((x) << RDMA_REGION_3__NEXT_LSB) & RDMA_REGION_3__NEXT_MASK)
-
-#define RDMA_REGION_4__ADDRESS                   0x00000030
-#define RDMA_REGION_4__OFFSET                    0x00000030
-#define RDMA_REGION_4__ADDR_MSB                  31
-#define RDMA_REGION_4__ADDR_LSB                  13
-#define RDMA_REGION_4__ADDR_MASK                 0xffffe000
-#define RDMA_REGION_4__ADDR_GET(x)               (((x) & RDMA_REGION_4__ADDR_MASK) >> RDMA_REGION_4__ADDR_LSB)
-#define RDMA_REGION_4__ADDR_SET(x)               (((x) << RDMA_REGION_4__ADDR_LSB) & RDMA_REGION_4__ADDR_MASK)
-#define RDMA_REGION_4__LENGTH_MSB                12
-#define RDMA_REGION_4__LENGTH_LSB                2
-#define RDMA_REGION_4__LENGTH_MASK               0x00001ffc
-#define RDMA_REGION_4__LENGTH_GET(x)             (((x) & RDMA_REGION_4__LENGTH_MASK) >> RDMA_REGION_4__LENGTH_LSB)
-#define RDMA_REGION_4__LENGTH_SET(x)             (((x) << RDMA_REGION_4__LENGTH_LSB) & RDMA_REGION_4__LENGTH_MASK)
-#define RDMA_REGION_4__INDI_MSB                  1
-#define RDMA_REGION_4__INDI_LSB                  1
-#define RDMA_REGION_4__INDI_MASK                 0x00000002
-#define RDMA_REGION_4__INDI_GET(x)               (((x) & RDMA_REGION_4__INDI_MASK) >> RDMA_REGION_4__INDI_LSB)
-#define RDMA_REGION_4__INDI_SET(x)               (((x) << RDMA_REGION_4__INDI_LSB) & RDMA_REGION_4__INDI_MASK)
-#define RDMA_REGION_4__NEXT_MSB                  0
-#define RDMA_REGION_4__NEXT_LSB                  0
-#define RDMA_REGION_4__NEXT_MASK                 0x00000001
-#define RDMA_REGION_4__NEXT_GET(x)               (((x) & RDMA_REGION_4__NEXT_MASK) >> RDMA_REGION_4__NEXT_LSB)
-#define RDMA_REGION_4__NEXT_SET(x)               (((x) << RDMA_REGION_4__NEXT_LSB) & RDMA_REGION_4__NEXT_MASK)
-
-#define RDMA_REGION_5__ADDRESS                   0x00000034
-#define RDMA_REGION_5__OFFSET                    0x00000034
-#define RDMA_REGION_5__ADDR_MSB                  31
-#define RDMA_REGION_5__ADDR_LSB                  13
-#define RDMA_REGION_5__ADDR_MASK                 0xffffe000
-#define RDMA_REGION_5__ADDR_GET(x)               (((x) & RDMA_REGION_5__ADDR_MASK) >> RDMA_REGION_5__ADDR_LSB)
-#define RDMA_REGION_5__ADDR_SET(x)               (((x) << RDMA_REGION_5__ADDR_LSB) & RDMA_REGION_5__ADDR_MASK)
-#define RDMA_REGION_5__LENGTH_MSB                12
-#define RDMA_REGION_5__LENGTH_LSB                2
-#define RDMA_REGION_5__LENGTH_MASK               0x00001ffc
-#define RDMA_REGION_5__LENGTH_GET(x)             (((x) & RDMA_REGION_5__LENGTH_MASK) >> RDMA_REGION_5__LENGTH_LSB)
-#define RDMA_REGION_5__LENGTH_SET(x)             (((x) << RDMA_REGION_5__LENGTH_LSB) & RDMA_REGION_5__LENGTH_MASK)
-#define RDMA_REGION_5__INDI_MSB                  1
-#define RDMA_REGION_5__INDI_LSB                  1
-#define RDMA_REGION_5__INDI_MASK                 0x00000002
-#define RDMA_REGION_5__INDI_GET(x)               (((x) & RDMA_REGION_5__INDI_MASK) >> RDMA_REGION_5__INDI_LSB)
-#define RDMA_REGION_5__INDI_SET(x)               (((x) << RDMA_REGION_5__INDI_LSB) & RDMA_REGION_5__INDI_MASK)
-#define RDMA_REGION_5__NEXT_MSB                  0
-#define RDMA_REGION_5__NEXT_LSB                  0
-#define RDMA_REGION_5__NEXT_MASK                 0x00000001
-#define RDMA_REGION_5__NEXT_GET(x)               (((x) & RDMA_REGION_5__NEXT_MASK) >> RDMA_REGION_5__NEXT_LSB)
-#define RDMA_REGION_5__NEXT_SET(x)               (((x) << RDMA_REGION_5__NEXT_LSB) & RDMA_REGION_5__NEXT_MASK)
-
-#define RDMA_REGION_6__ADDRESS                   0x00000038
-#define RDMA_REGION_6__OFFSET                    0x00000038
-#define RDMA_REGION_6__ADDR_MSB                  31
-#define RDMA_REGION_6__ADDR_LSB                  13
-#define RDMA_REGION_6__ADDR_MASK                 0xffffe000
-#define RDMA_REGION_6__ADDR_GET(x)               (((x) & RDMA_REGION_6__ADDR_MASK) >> RDMA_REGION_6__ADDR_LSB)
-#define RDMA_REGION_6__ADDR_SET(x)               (((x) << RDMA_REGION_6__ADDR_LSB) & RDMA_REGION_6__ADDR_MASK)
-#define RDMA_REGION_6__LENGTH_MSB                12
-#define RDMA_REGION_6__LENGTH_LSB                2
-#define RDMA_REGION_6__LENGTH_MASK               0x00001ffc
-#define RDMA_REGION_6__LENGTH_GET(x)             (((x) & RDMA_REGION_6__LENGTH_MASK) >> RDMA_REGION_6__LENGTH_LSB)
-#define RDMA_REGION_6__LENGTH_SET(x)             (((x) << RDMA_REGION_6__LENGTH_LSB) & RDMA_REGION_6__LENGTH_MASK)
-#define RDMA_REGION_6__INDI_MSB                  1
-#define RDMA_REGION_6__INDI_LSB                  1
-#define RDMA_REGION_6__INDI_MASK                 0x00000002
-#define RDMA_REGION_6__INDI_GET(x)               (((x) & RDMA_REGION_6__INDI_MASK) >> RDMA_REGION_6__INDI_LSB)
-#define RDMA_REGION_6__INDI_SET(x)               (((x) << RDMA_REGION_6__INDI_LSB) & RDMA_REGION_6__INDI_MASK)
-#define RDMA_REGION_6__NEXT_MSB                  0
-#define RDMA_REGION_6__NEXT_LSB                  0
-#define RDMA_REGION_6__NEXT_MASK                 0x00000001
-#define RDMA_REGION_6__NEXT_GET(x)               (((x) & RDMA_REGION_6__NEXT_MASK) >> RDMA_REGION_6__NEXT_LSB)
-#define RDMA_REGION_6__NEXT_SET(x)               (((x) << RDMA_REGION_6__NEXT_LSB) & RDMA_REGION_6__NEXT_MASK)
-
-#define RDMA_REGION_7__ADDRESS                   0x0000003c
-#define RDMA_REGION_7__OFFSET                    0x0000003c
-#define RDMA_REGION_7__ADDR_MSB                  31
-#define RDMA_REGION_7__ADDR_LSB                  13
-#define RDMA_REGION_7__ADDR_MASK                 0xffffe000
-#define RDMA_REGION_7__ADDR_GET(x)               (((x) & RDMA_REGION_7__ADDR_MASK) >> RDMA_REGION_7__ADDR_LSB)
-#define RDMA_REGION_7__ADDR_SET(x)               (((x) << RDMA_REGION_7__ADDR_LSB) & RDMA_REGION_7__ADDR_MASK)
-#define RDMA_REGION_7__LENGTH_MSB                12
-#define RDMA_REGION_7__LENGTH_LSB                2
-#define RDMA_REGION_7__LENGTH_MASK               0x00001ffc
-#define RDMA_REGION_7__LENGTH_GET(x)             (((x) & RDMA_REGION_7__LENGTH_MASK) >> RDMA_REGION_7__LENGTH_LSB)
-#define RDMA_REGION_7__LENGTH_SET(x)             (((x) << RDMA_REGION_7__LENGTH_LSB) & RDMA_REGION_7__LENGTH_MASK)
-#define RDMA_REGION_7__INDI_MSB                  1
-#define RDMA_REGION_7__INDI_LSB                  1
-#define RDMA_REGION_7__INDI_MASK                 0x00000002
-#define RDMA_REGION_7__INDI_GET(x)               (((x) & RDMA_REGION_7__INDI_MASK) >> RDMA_REGION_7__INDI_LSB)
-#define RDMA_REGION_7__INDI_SET(x)               (((x) << RDMA_REGION_7__INDI_LSB) & RDMA_REGION_7__INDI_MASK)
-#define RDMA_REGION_7__NEXT_MSB                  0
-#define RDMA_REGION_7__NEXT_LSB                  0
-#define RDMA_REGION_7__NEXT_MASK                 0x00000001
-#define RDMA_REGION_7__NEXT_GET(x)               (((x) & RDMA_REGION_7__NEXT_MASK) >> RDMA_REGION_7__NEXT_LSB)
-#define RDMA_REGION_7__NEXT_SET(x)               (((x) << RDMA_REGION_7__NEXT_LSB) & RDMA_REGION_7__NEXT_MASK)
-
-#define RDMA_REGION_8__ADDRESS                   0x00000040
-#define RDMA_REGION_8__OFFSET                    0x00000040
-#define RDMA_REGION_8__ADDR_MSB                  31
-#define RDMA_REGION_8__ADDR_LSB                  13
-#define RDMA_REGION_8__ADDR_MASK                 0xffffe000
-#define RDMA_REGION_8__ADDR_GET(x)               (((x) & RDMA_REGION_8__ADDR_MASK) >> RDMA_REGION_8__ADDR_LSB)
-#define RDMA_REGION_8__ADDR_SET(x)               (((x) << RDMA_REGION_8__ADDR_LSB) & RDMA_REGION_8__ADDR_MASK)
-#define RDMA_REGION_8__LENGTH_MSB                12
-#define RDMA_REGION_8__LENGTH_LSB                2
-#define RDMA_REGION_8__LENGTH_MASK               0x00001ffc
-#define RDMA_REGION_8__LENGTH_GET(x)             (((x) & RDMA_REGION_8__LENGTH_MASK) >> RDMA_REGION_8__LENGTH_LSB)
-#define RDMA_REGION_8__LENGTH_SET(x)             (((x) << RDMA_REGION_8__LENGTH_LSB) & RDMA_REGION_8__LENGTH_MASK)
-#define RDMA_REGION_8__INDI_MSB                  1
-#define RDMA_REGION_8__INDI_LSB                  1
-#define RDMA_REGION_8__INDI_MASK                 0x00000002
-#define RDMA_REGION_8__INDI_GET(x)               (((x) & RDMA_REGION_8__INDI_MASK) >> RDMA_REGION_8__INDI_LSB)
-#define RDMA_REGION_8__INDI_SET(x)               (((x) << RDMA_REGION_8__INDI_LSB) & RDMA_REGION_8__INDI_MASK)
-#define RDMA_REGION_8__NEXT_MSB                  0
-#define RDMA_REGION_8__NEXT_LSB                  0
-#define RDMA_REGION_8__NEXT_MASK                 0x00000001
-#define RDMA_REGION_8__NEXT_GET(x)               (((x) & RDMA_REGION_8__NEXT_MASK) >> RDMA_REGION_8__NEXT_LSB)
-#define RDMA_REGION_8__NEXT_SET(x)               (((x) << RDMA_REGION_8__NEXT_LSB) & RDMA_REGION_8__NEXT_MASK)
-
-#define RDMA_REGION_9__ADDRESS                   0x00000044
-#define RDMA_REGION_9__OFFSET                    0x00000044
-#define RDMA_REGION_9__ADDR_MSB                  31
-#define RDMA_REGION_9__ADDR_LSB                  13
-#define RDMA_REGION_9__ADDR_MASK                 0xffffe000
-#define RDMA_REGION_9__ADDR_GET(x)               (((x) & RDMA_REGION_9__ADDR_MASK) >> RDMA_REGION_9__ADDR_LSB)
-#define RDMA_REGION_9__ADDR_SET(x)               (((x) << RDMA_REGION_9__ADDR_LSB) & RDMA_REGION_9__ADDR_MASK)
-#define RDMA_REGION_9__LENGTH_MSB                12
-#define RDMA_REGION_9__LENGTH_LSB                2
-#define RDMA_REGION_9__LENGTH_MASK               0x00001ffc
-#define RDMA_REGION_9__LENGTH_GET(x)             (((x) & RDMA_REGION_9__LENGTH_MASK) >> RDMA_REGION_9__LENGTH_LSB)
-#define RDMA_REGION_9__LENGTH_SET(x)             (((x) << RDMA_REGION_9__LENGTH_LSB) & RDMA_REGION_9__LENGTH_MASK)
-#define RDMA_REGION_9__INDI_MSB                  1
-#define RDMA_REGION_9__INDI_LSB                  1
-#define RDMA_REGION_9__INDI_MASK                 0x00000002
-#define RDMA_REGION_9__INDI_GET(x)               (((x) & RDMA_REGION_9__INDI_MASK) >> RDMA_REGION_9__INDI_LSB)
-#define RDMA_REGION_9__INDI_SET(x)               (((x) << RDMA_REGION_9__INDI_LSB) & RDMA_REGION_9__INDI_MASK)
-#define RDMA_REGION_9__NEXT_MSB                  0
-#define RDMA_REGION_9__NEXT_LSB                  0
-#define RDMA_REGION_9__NEXT_MASK                 0x00000001
-#define RDMA_REGION_9__NEXT_GET(x)               (((x) & RDMA_REGION_9__NEXT_MASK) >> RDMA_REGION_9__NEXT_LSB)
-#define RDMA_REGION_9__NEXT_SET(x)               (((x) << RDMA_REGION_9__NEXT_LSB) & RDMA_REGION_9__NEXT_MASK)
-
-#define RDMA_REGION_10__ADDRESS                  0x00000048
-#define RDMA_REGION_10__OFFSET                   0x00000048
-#define RDMA_REGION_10__ADDR_MSB                 31
-#define RDMA_REGION_10__ADDR_LSB                 13
-#define RDMA_REGION_10__ADDR_MASK                0xffffe000
-#define RDMA_REGION_10__ADDR_GET(x)              (((x) & RDMA_REGION_10__ADDR_MASK) >> RDMA_REGION_10__ADDR_LSB)
-#define RDMA_REGION_10__ADDR_SET(x)              (((x) << RDMA_REGION_10__ADDR_LSB) & RDMA_REGION_10__ADDR_MASK)
-#define RDMA_REGION_10__LENGTH_MSB               12
-#define RDMA_REGION_10__LENGTH_LSB               2
-#define RDMA_REGION_10__LENGTH_MASK              0x00001ffc
-#define RDMA_REGION_10__LENGTH_GET(x)            (((x) & RDMA_REGION_10__LENGTH_MASK) >> RDMA_REGION_10__LENGTH_LSB)
-#define RDMA_REGION_10__LENGTH_SET(x)            (((x) << RDMA_REGION_10__LENGTH_LSB) & RDMA_REGION_10__LENGTH_MASK)
-#define RDMA_REGION_10__INDI_MSB                 1
-#define RDMA_REGION_10__INDI_LSB                 1
-#define RDMA_REGION_10__INDI_MASK                0x00000002
-#define RDMA_REGION_10__INDI_GET(x)              (((x) & RDMA_REGION_10__INDI_MASK) >> RDMA_REGION_10__INDI_LSB)
-#define RDMA_REGION_10__INDI_SET(x)              (((x) << RDMA_REGION_10__INDI_LSB) & RDMA_REGION_10__INDI_MASK)
-#define RDMA_REGION_10__NEXT_MSB                 0
-#define RDMA_REGION_10__NEXT_LSB                 0
-#define RDMA_REGION_10__NEXT_MASK                0x00000001
-#define RDMA_REGION_10__NEXT_GET(x)              (((x) & RDMA_REGION_10__NEXT_MASK) >> RDMA_REGION_10__NEXT_LSB)
-#define RDMA_REGION_10__NEXT_SET(x)              (((x) << RDMA_REGION_10__NEXT_LSB) & RDMA_REGION_10__NEXT_MASK)
-
-#define RDMA_REGION_11__ADDRESS                  0x0000004c
-#define RDMA_REGION_11__OFFSET                   0x0000004c
-#define RDMA_REGION_11__ADDR_MSB                 31
-#define RDMA_REGION_11__ADDR_LSB                 13
-#define RDMA_REGION_11__ADDR_MASK                0xffffe000
-#define RDMA_REGION_11__ADDR_GET(x)              (((x) & RDMA_REGION_11__ADDR_MASK) >> RDMA_REGION_11__ADDR_LSB)
-#define RDMA_REGION_11__ADDR_SET(x)              (((x) << RDMA_REGION_11__ADDR_LSB) & RDMA_REGION_11__ADDR_MASK)
-#define RDMA_REGION_11__LENGTH_MSB               12
-#define RDMA_REGION_11__LENGTH_LSB               2
-#define RDMA_REGION_11__LENGTH_MASK              0x00001ffc
-#define RDMA_REGION_11__LENGTH_GET(x)            (((x) & RDMA_REGION_11__LENGTH_MASK) >> RDMA_REGION_11__LENGTH_LSB)
-#define RDMA_REGION_11__LENGTH_SET(x)            (((x) << RDMA_REGION_11__LENGTH_LSB) & RDMA_REGION_11__LENGTH_MASK)
-#define RDMA_REGION_11__INDI_MSB                 1
-#define RDMA_REGION_11__INDI_LSB                 1
-#define RDMA_REGION_11__INDI_MASK                0x00000002
-#define RDMA_REGION_11__INDI_GET(x)              (((x) & RDMA_REGION_11__INDI_MASK) >> RDMA_REGION_11__INDI_LSB)
-#define RDMA_REGION_11__INDI_SET(x)              (((x) << RDMA_REGION_11__INDI_LSB) & RDMA_REGION_11__INDI_MASK)
-#define RDMA_REGION_11__NEXT_MSB                 0
-#define RDMA_REGION_11__NEXT_LSB                 0
-#define RDMA_REGION_11__NEXT_MASK                0x00000001
-#define RDMA_REGION_11__NEXT_GET(x)              (((x) & RDMA_REGION_11__NEXT_MASK) >> RDMA_REGION_11__NEXT_LSB)
-#define RDMA_REGION_11__NEXT_SET(x)              (((x) << RDMA_REGION_11__NEXT_LSB) & RDMA_REGION_11__NEXT_MASK)
-
-#define RDMA_REGION_12__ADDRESS                  0x00000050
-#define RDMA_REGION_12__OFFSET                   0x00000050
-#define RDMA_REGION_12__ADDR_MSB                 31
-#define RDMA_REGION_12__ADDR_LSB                 13
-#define RDMA_REGION_12__ADDR_MASK                0xffffe000
-#define RDMA_REGION_12__ADDR_GET(x)              (((x) & RDMA_REGION_12__ADDR_MASK) >> RDMA_REGION_12__ADDR_LSB)
-#define RDMA_REGION_12__ADDR_SET(x)              (((x) << RDMA_REGION_12__ADDR_LSB) & RDMA_REGION_12__ADDR_MASK)
-#define RDMA_REGION_12__LENGTH_MSB               12
-#define RDMA_REGION_12__LENGTH_LSB               2
-#define RDMA_REGION_12__LENGTH_MASK              0x00001ffc
-#define RDMA_REGION_12__LENGTH_GET(x)            (((x) & RDMA_REGION_12__LENGTH_MASK) >> RDMA_REGION_12__LENGTH_LSB)
-#define RDMA_REGION_12__LENGTH_SET(x)            (((x) << RDMA_REGION_12__LENGTH_LSB) & RDMA_REGION_12__LENGTH_MASK)
-#define RDMA_REGION_12__INDI_MSB                 1
-#define RDMA_REGION_12__INDI_LSB                 1
-#define RDMA_REGION_12__INDI_MASK                0x00000002
-#define RDMA_REGION_12__INDI_GET(x)              (((x) & RDMA_REGION_12__INDI_MASK) >> RDMA_REGION_12__INDI_LSB)
-#define RDMA_REGION_12__INDI_SET(x)              (((x) << RDMA_REGION_12__INDI_LSB) & RDMA_REGION_12__INDI_MASK)
-#define RDMA_REGION_12__NEXT_MSB                 0
-#define RDMA_REGION_12__NEXT_LSB                 0
-#define RDMA_REGION_12__NEXT_MASK                0x00000001
-#define RDMA_REGION_12__NEXT_GET(x)              (((x) & RDMA_REGION_12__NEXT_MASK) >> RDMA_REGION_12__NEXT_LSB)
-#define RDMA_REGION_12__NEXT_SET(x)              (((x) << RDMA_REGION_12__NEXT_LSB) & RDMA_REGION_12__NEXT_MASK)
-
-#define RDMA_REGION_13__ADDRESS                  0x00000054
-#define RDMA_REGION_13__OFFSET                   0x00000054
-#define RDMA_REGION_13__ADDR_MSB                 31
-#define RDMA_REGION_13__ADDR_LSB                 13
-#define RDMA_REGION_13__ADDR_MASK                0xffffe000
-#define RDMA_REGION_13__ADDR_GET(x)              (((x) & RDMA_REGION_13__ADDR_MASK) >> RDMA_REGION_13__ADDR_LSB)
-#define RDMA_REGION_13__ADDR_SET(x)              (((x) << RDMA_REGION_13__ADDR_LSB) & RDMA_REGION_13__ADDR_MASK)
-#define RDMA_REGION_13__LENGTH_MSB               12
-#define RDMA_REGION_13__LENGTH_LSB               2
-#define RDMA_REGION_13__LENGTH_MASK              0x00001ffc
-#define RDMA_REGION_13__LENGTH_GET(x)            (((x) & RDMA_REGION_13__LENGTH_MASK) >> RDMA_REGION_13__LENGTH_LSB)
-#define RDMA_REGION_13__LENGTH_SET(x)            (((x) << RDMA_REGION_13__LENGTH_LSB) & RDMA_REGION_13__LENGTH_MASK)
-#define RDMA_REGION_13__INDI_MSB                 1
-#define RDMA_REGION_13__INDI_LSB                 1
-#define RDMA_REGION_13__INDI_MASK                0x00000002
-#define RDMA_REGION_13__INDI_GET(x)              (((x) & RDMA_REGION_13__INDI_MASK) >> RDMA_REGION_13__INDI_LSB)
-#define RDMA_REGION_13__INDI_SET(x)              (((x) << RDMA_REGION_13__INDI_LSB) & RDMA_REGION_13__INDI_MASK)
-#define RDMA_REGION_13__NEXT_MSB                 0
-#define RDMA_REGION_13__NEXT_LSB                 0
-#define RDMA_REGION_13__NEXT_MASK                0x00000001
-#define RDMA_REGION_13__NEXT_GET(x)              (((x) & RDMA_REGION_13__NEXT_MASK) >> RDMA_REGION_13__NEXT_LSB)
-#define RDMA_REGION_13__NEXT_SET(x)              (((x) << RDMA_REGION_13__NEXT_LSB) & RDMA_REGION_13__NEXT_MASK)
-
-#define RDMA_REGION_14__ADDRESS                  0x00000058
-#define RDMA_REGION_14__OFFSET                   0x00000058
-#define RDMA_REGION_14__ADDR_MSB                 31
-#define RDMA_REGION_14__ADDR_LSB                 13
-#define RDMA_REGION_14__ADDR_MASK                0xffffe000
-#define RDMA_REGION_14__ADDR_GET(x)              (((x) & RDMA_REGION_14__ADDR_MASK) >> RDMA_REGION_14__ADDR_LSB)
-#define RDMA_REGION_14__ADDR_SET(x)              (((x) << RDMA_REGION_14__ADDR_LSB) & RDMA_REGION_14__ADDR_MASK)
-#define RDMA_REGION_14__LENGTH_MSB               12
-#define RDMA_REGION_14__LENGTH_LSB               2
-#define RDMA_REGION_14__LENGTH_MASK              0x00001ffc
-#define RDMA_REGION_14__LENGTH_GET(x)            (((x) & RDMA_REGION_14__LENGTH_MASK) >> RDMA_REGION_14__LENGTH_LSB)
-#define RDMA_REGION_14__LENGTH_SET(x)            (((x) << RDMA_REGION_14__LENGTH_LSB) & RDMA_REGION_14__LENGTH_MASK)
-#define RDMA_REGION_14__INDI_MSB                 1
-#define RDMA_REGION_14__INDI_LSB                 1
-#define RDMA_REGION_14__INDI_MASK                0x00000002
-#define RDMA_REGION_14__INDI_GET(x)              (((x) & RDMA_REGION_14__INDI_MASK) >> RDMA_REGION_14__INDI_LSB)
-#define RDMA_REGION_14__INDI_SET(x)              (((x) << RDMA_REGION_14__INDI_LSB) & RDMA_REGION_14__INDI_MASK)
-#define RDMA_REGION_14__NEXT_MSB                 0
-#define RDMA_REGION_14__NEXT_LSB                 0
-#define RDMA_REGION_14__NEXT_MASK                0x00000001
-#define RDMA_REGION_14__NEXT_GET(x)              (((x) & RDMA_REGION_14__NEXT_MASK) >> RDMA_REGION_14__NEXT_LSB)
-#define RDMA_REGION_14__NEXT_SET(x)              (((x) << RDMA_REGION_14__NEXT_LSB) & RDMA_REGION_14__NEXT_MASK)
-
-#define RDMA_REGION_15__ADDRESS                  0x0000005c
-#define RDMA_REGION_15__OFFSET                   0x0000005c
-#define RDMA_REGION_15__ADDR_MSB                 31
-#define RDMA_REGION_15__ADDR_LSB                 13
-#define RDMA_REGION_15__ADDR_MASK                0xffffe000
-#define RDMA_REGION_15__ADDR_GET(x)              (((x) & RDMA_REGION_15__ADDR_MASK) >> RDMA_REGION_15__ADDR_LSB)
-#define RDMA_REGION_15__ADDR_SET(x)              (((x) << RDMA_REGION_15__ADDR_LSB) & RDMA_REGION_15__ADDR_MASK)
-#define RDMA_REGION_15__LENGTH_MSB               12
-#define RDMA_REGION_15__LENGTH_LSB               2
-#define RDMA_REGION_15__LENGTH_MASK              0x00001ffc
-#define RDMA_REGION_15__LENGTH_GET(x)            (((x) & RDMA_REGION_15__LENGTH_MASK) >> RDMA_REGION_15__LENGTH_LSB)
-#define RDMA_REGION_15__LENGTH_SET(x)            (((x) << RDMA_REGION_15__LENGTH_LSB) & RDMA_REGION_15__LENGTH_MASK)
-#define RDMA_REGION_15__INDI_MSB                 1
-#define RDMA_REGION_15__INDI_LSB                 1
-#define RDMA_REGION_15__INDI_MASK                0x00000002
-#define RDMA_REGION_15__INDI_GET(x)              (((x) & RDMA_REGION_15__INDI_MASK) >> RDMA_REGION_15__INDI_LSB)
-#define RDMA_REGION_15__INDI_SET(x)              (((x) << RDMA_REGION_15__INDI_LSB) & RDMA_REGION_15__INDI_MASK)
-#define RDMA_REGION_15__NEXT_MSB                 0
-#define RDMA_REGION_15__NEXT_LSB                 0
-#define RDMA_REGION_15__NEXT_MASK                0x00000001
-#define RDMA_REGION_15__NEXT_GET(x)              (((x) & RDMA_REGION_15__NEXT_MASK) >> RDMA_REGION_15__NEXT_LSB)
-#define RDMA_REGION_15__NEXT_SET(x)              (((x) << RDMA_REGION_15__NEXT_LSB) & RDMA_REGION_15__NEXT_MASK)
-
-#define DMA_STATUS_ADDRESS                       0x00000060
-#define DMA_STATUS_OFFSET                        0x00000060
-#define DMA_STATUS_ERROR_CODE_MSB                14
-#define DMA_STATUS_ERROR_CODE_LSB                4
-#define DMA_STATUS_ERROR_CODE_MASK               0x00007ff0
-#define DMA_STATUS_ERROR_CODE_GET(x)             (((x) & DMA_STATUS_ERROR_CODE_MASK) >> DMA_STATUS_ERROR_CODE_LSB)
-#define DMA_STATUS_ERROR_CODE_SET(x)             (((x) << DMA_STATUS_ERROR_CODE_LSB) & DMA_STATUS_ERROR_CODE_MASK)
-#define DMA_STATUS_ERROR_MSB                     3
-#define DMA_STATUS_ERROR_LSB                     3
-#define DMA_STATUS_ERROR_MASK                    0x00000008
-#define DMA_STATUS_ERROR_GET(x)                  (((x) & DMA_STATUS_ERROR_MASK) >> DMA_STATUS_ERROR_LSB)
-#define DMA_STATUS_ERROR_SET(x)                  (((x) << DMA_STATUS_ERROR_LSB) & DMA_STATUS_ERROR_MASK)
-#define DMA_STATUS_DONE_MSB                      2
-#define DMA_STATUS_DONE_LSB                      2
-#define DMA_STATUS_DONE_MASK                     0x00000004
-#define DMA_STATUS_DONE_GET(x)                   (((x) & DMA_STATUS_DONE_MASK) >> DMA_STATUS_DONE_LSB)
-#define DMA_STATUS_DONE_SET(x)                   (((x) << DMA_STATUS_DONE_LSB) & DMA_STATUS_DONE_MASK)
-#define DMA_STATUS_STOPPED_MSB                   1
-#define DMA_STATUS_STOPPED_LSB                   1
-#define DMA_STATUS_STOPPED_MASK                  0x00000002
-#define DMA_STATUS_STOPPED_GET(x)                (((x) & DMA_STATUS_STOPPED_MASK) >> DMA_STATUS_STOPPED_LSB)
-#define DMA_STATUS_STOPPED_SET(x)                (((x) << DMA_STATUS_STOPPED_LSB) & DMA_STATUS_STOPPED_MASK)
-#define DMA_STATUS_RUNNING_MSB                   0
-#define DMA_STATUS_RUNNING_LSB                   0
-#define DMA_STATUS_RUNNING_MASK                  0x00000001
-#define DMA_STATUS_RUNNING_GET(x)                (((x) & DMA_STATUS_RUNNING_MASK) >> DMA_STATUS_RUNNING_LSB)
-#define DMA_STATUS_RUNNING_SET(x)                (((x) << DMA_STATUS_RUNNING_LSB) & DMA_STATUS_RUNNING_MASK)
-
-#define DMA_INT_EN_ADDRESS                       0x00000064
-#define DMA_INT_EN_OFFSET                        0x00000064
-#define DMA_INT_EN_ERROR_ENA_MSB                 3
-#define DMA_INT_EN_ERROR_ENA_LSB                 3
-#define DMA_INT_EN_ERROR_ENA_MASK                0x00000008
-#define DMA_INT_EN_ERROR_ENA_GET(x)              (((x) & DMA_INT_EN_ERROR_ENA_MASK) >> DMA_INT_EN_ERROR_ENA_LSB)
-#define DMA_INT_EN_ERROR_ENA_SET(x)              (((x) << DMA_INT_EN_ERROR_ENA_LSB) & DMA_INT_EN_ERROR_ENA_MASK)
-#define DMA_INT_EN_DONE_ENA_MSB                  2
-#define DMA_INT_EN_DONE_ENA_LSB                  2
-#define DMA_INT_EN_DONE_ENA_MASK                 0x00000004
-#define DMA_INT_EN_DONE_ENA_GET(x)               (((x) & DMA_INT_EN_DONE_ENA_MASK) >> DMA_INT_EN_DONE_ENA_LSB)
-#define DMA_INT_EN_DONE_ENA_SET(x)               (((x) << DMA_INT_EN_DONE_ENA_LSB) & DMA_INT_EN_DONE_ENA_MASK)
-#define DMA_INT_EN_STOPPED_ENA_MSB               1
-#define DMA_INT_EN_STOPPED_ENA_LSB               1
-#define DMA_INT_EN_STOPPED_ENA_MASK              0x00000002
-#define DMA_INT_EN_STOPPED_ENA_GET(x)            (((x) & DMA_INT_EN_STOPPED_ENA_MASK) >> DMA_INT_EN_STOPPED_ENA_LSB)
-#define DMA_INT_EN_STOPPED_ENA_SET(x)            (((x) << DMA_INT_EN_STOPPED_ENA_LSB) & DMA_INT_EN_STOPPED_ENA_MASK)
-
-
-#ifndef __ASSEMBLER__
-
-typedef struct rdma_reg_reg_s {
-  volatile unsigned int dma_config;
-  volatile unsigned int dma_control;
-  volatile unsigned int dma_src;
-  volatile unsigned int dma_dest;
-  volatile unsigned int dma_length;
-  volatile unsigned int vmc_base;
-  volatile unsigned int indirect_reg;
-  volatile unsigned int indirect_return;
-  volatile unsigned int rdma_region_0_;
-  volatile unsigned int rdma_region_1_;
-  volatile unsigned int rdma_region_2_;
-  volatile unsigned int rdma_region_3_;
-  volatile unsigned int rdma_region_4_;
-  volatile unsigned int rdma_region_5_;
-  volatile unsigned int rdma_region_6_;
-  volatile unsigned int rdma_region_7_;
-  volatile unsigned int rdma_region_8_;
-  volatile unsigned int rdma_region_9_;
-  volatile unsigned int rdma_region_10_;
-  volatile unsigned int rdma_region_11_;
-  volatile unsigned int rdma_region_12_;
-  volatile unsigned int rdma_region_13_;
-  volatile unsigned int rdma_region_14_;
-  volatile unsigned int rdma_region_15_;
-  volatile unsigned int dma_status;
-  volatile unsigned int dma_int_en;
-} rdma_reg_reg_t;
-
-#endif /* __ASSEMBLER__ */
-
-#endif /* _RDMA_REG_H_ */
diff -druN linux-2.6.39-libre/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/rtc_reg.h linux-3.0-rc7-libre/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/rtc_reg.h
--- linux-2.6.39-libre/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/rtc_reg.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/rtc_reg.h	2011-07-11 19:51:52.000000000 -0400
@@ -21,11 +21,8 @@
 //===================================================================
 
 
-#ifdef WLAN_HEADERS
-
 #include "rtc_wlan_reg.h"
 
-
 #ifndef BT_HEADERS
 
 #define RESET_CONTROL_ADDRESS WLAN_RESET_CONTROL_ADDRESS
@@ -100,95 +97,6 @@
 #define RESET_CONTROL_SI0_RST_MASK WLAN_RESET_CONTROL_SI0_RST_MASK
 #define RESET_CONTROL_SI0_RST_GET(x) WLAN_RESET_CONTROL_SI0_RST_GET(x)
 #define RESET_CONTROL_SI0_RST_SET(x) WLAN_RESET_CONTROL_SI0_RST_SET(x)
-#define XTAL_CONTROL_ADDRESS WLAN_XTAL_CONTROL_ADDRESS
-#define XTAL_CONTROL_OFFSET WLAN_XTAL_CONTROL_OFFSET
-#define XTAL_CONTROL_TCXO_MSB WLAN_XTAL_CONTROL_TCXO_MSB
-#define XTAL_CONTROL_TCXO_LSB WLAN_XTAL_CONTROL_TCXO_LSB
-#define XTAL_CONTROL_TCXO_MASK WLAN_XTAL_CONTROL_TCXO_MASK
-#define XTAL_CONTROL_TCXO_GET(x) WLAN_XTAL_CONTROL_TCXO_GET(x)
-#define XTAL_CONTROL_TCXO_SET(x) WLAN_XTAL_CONTROL_TCXO_SET(x)
-#define TCXO_DETECT_ADDRESS WLAN_TCXO_DETECT_ADDRESS
-#define TCXO_DETECT_OFFSET WLAN_TCXO_DETECT_OFFSET
-#define TCXO_DETECT_PRESENT_MSB WLAN_TCXO_DETECT_PRESENT_MSB
-#define TCXO_DETECT_PRESENT_LSB WLAN_TCXO_DETECT_PRESENT_LSB
-#define TCXO_DETECT_PRESENT_MASK WLAN_TCXO_DETECT_PRESENT_MASK
-#define TCXO_DETECT_PRESENT_GET(x) WLAN_TCXO_DETECT_PRESENT_GET(x)
-#define TCXO_DETECT_PRESENT_SET(x) WLAN_TCXO_DETECT_PRESENT_SET(x)
-#define XTAL_TEST_ADDRESS WLAN_XTAL_TEST_ADDRESS
-#define XTAL_TEST_OFFSET WLAN_XTAL_TEST_OFFSET
-#define XTAL_TEST_NOTCXODET_MSB WLAN_XTAL_TEST_NOTCXODET_MSB
-#define XTAL_TEST_NOTCXODET_LSB WLAN_XTAL_TEST_NOTCXODET_LSB
-#define XTAL_TEST_NOTCXODET_MASK WLAN_XTAL_TEST_NOTCXODET_MASK
-#define XTAL_TEST_NOTCXODET_GET(x) WLAN_XTAL_TEST_NOTCXODET_GET(x)
-#define XTAL_TEST_NOTCXODET_SET(x) WLAN_XTAL_TEST_NOTCXODET_SET(x)
-#define QUADRATURE_ADDRESS WLAN_QUADRATURE_ADDRESS
-#define QUADRATURE_OFFSET WLAN_QUADRATURE_OFFSET
-#define QUADRATURE_ADC_MSB WLAN_QUADRATURE_ADC_MSB
-#define QUADRATURE_ADC_LSB WLAN_QUADRATURE_ADC_LSB
-#define QUADRATURE_ADC_MASK WLAN_QUADRATURE_ADC_MASK
-#define QUADRATURE_ADC_GET(x) WLAN_QUADRATURE_ADC_GET(x)
-#define QUADRATURE_ADC_SET(x) WLAN_QUADRATURE_ADC_SET(x)
-#define QUADRATURE_SEL_MSB WLAN_QUADRATURE_SEL_MSB
-#define QUADRATURE_SEL_LSB WLAN_QUADRATURE_SEL_LSB
-#define QUADRATURE_SEL_MASK WLAN_QUADRATURE_SEL_MASK
-#define QUADRATURE_SEL_GET(x) WLAN_QUADRATURE_SEL_GET(x)
-#define QUADRATURE_SEL_SET(x) WLAN_QUADRATURE_SEL_SET(x)
-#define QUADRATURE_DAC_MSB WLAN_QUADRATURE_DAC_MSB
-#define QUADRATURE_DAC_LSB WLAN_QUADRATURE_DAC_LSB
-#define QUADRATURE_DAC_MASK WLAN_QUADRATURE_DAC_MASK
-#define QUADRATURE_DAC_GET(x) WLAN_QUADRATURE_DAC_GET(x)
-#define QUADRATURE_DAC_SET(x) WLAN_QUADRATURE_DAC_SET(x)
-#define PLL_CONTROL_ADDRESS WLAN_PLL_CONTROL_ADDRESS
-#define PLL_CONTROL_OFFSET WLAN_PLL_CONTROL_OFFSET
-#define PLL_CONTROL_DIG_TEST_CLK_MSB WLAN_PLL_CONTROL_DIG_TEST_CLK_MSB
-#define PLL_CONTROL_DIG_TEST_CLK_LSB WLAN_PLL_CONTROL_DIG_TEST_CLK_LSB
-#define PLL_CONTROL_DIG_TEST_CLK_MASK WLAN_PLL_CONTROL_DIG_TEST_CLK_MASK
-#define PLL_CONTROL_DIG_TEST_CLK_GET(x) WLAN_PLL_CONTROL_DIG_TEST_CLK_GET(x)
-#define PLL_CONTROL_DIG_TEST_CLK_SET(x) WLAN_PLL_CONTROL_DIG_TEST_CLK_SET(x)
-#define PLL_CONTROL_MAC_OVERRIDE_MSB WLAN_PLL_CONTROL_MAC_OVERRIDE_MSB
-#define PLL_CONTROL_MAC_OVERRIDE_LSB WLAN_PLL_CONTROL_MAC_OVERRIDE_LSB
-#define PLL_CONTROL_MAC_OVERRIDE_MASK WLAN_PLL_CONTROL_MAC_OVERRIDE_MASK
-#define PLL_CONTROL_MAC_OVERRIDE_GET(x) WLAN_PLL_CONTROL_MAC_OVERRIDE_GET(x)
-#define PLL_CONTROL_MAC_OVERRIDE_SET(x) WLAN_PLL_CONTROL_MAC_OVERRIDE_SET(x)
-#define PLL_CONTROL_NOPWD_MSB WLAN_PLL_CONTROL_NOPWD_MSB
-#define PLL_CONTROL_NOPWD_LSB WLAN_PLL_CONTROL_NOPWD_LSB
-#define PLL_CONTROL_NOPWD_MASK WLAN_PLL_CONTROL_NOPWD_MASK
-#define PLL_CONTROL_NOPWD_GET(x) WLAN_PLL_CONTROL_NOPWD_GET(x)
-#define PLL_CONTROL_NOPWD_SET(x) WLAN_PLL_CONTROL_NOPWD_SET(x)
-#define PLL_CONTROL_UPDATING_MSB WLAN_PLL_CONTROL_UPDATING_MSB
-#define PLL_CONTROL_UPDATING_LSB WLAN_PLL_CONTROL_UPDATING_LSB
-#define PLL_CONTROL_UPDATING_MASK WLAN_PLL_CONTROL_UPDATING_MASK
-#define PLL_CONTROL_UPDATING_GET(x) WLAN_PLL_CONTROL_UPDATING_GET(x)
-#define PLL_CONTROL_UPDATING_SET(x) WLAN_PLL_CONTROL_UPDATING_SET(x)
-#define PLL_CONTROL_BYPASS_MSB WLAN_PLL_CONTROL_BYPASS_MSB
-#define PLL_CONTROL_BYPASS_LSB WLAN_PLL_CONTROL_BYPASS_LSB
-#define PLL_CONTROL_BYPASS_MASK WLAN_PLL_CONTROL_BYPASS_MASK
-#define PLL_CONTROL_BYPASS_GET(x) WLAN_PLL_CONTROL_BYPASS_GET(x)
-#define PLL_CONTROL_BYPASS_SET(x) WLAN_PLL_CONTROL_BYPASS_SET(x)
-#define PLL_CONTROL_REFDIV_MSB WLAN_PLL_CONTROL_REFDIV_MSB
-#define PLL_CONTROL_REFDIV_LSB WLAN_PLL_CONTROL_REFDIV_LSB
-#define PLL_CONTROL_REFDIV_MASK WLAN_PLL_CONTROL_REFDIV_MASK
-#define PLL_CONTROL_REFDIV_GET(x) WLAN_PLL_CONTROL_REFDIV_GET(x)
-#define PLL_CONTROL_REFDIV_SET(x) WLAN_PLL_CONTROL_REFDIV_SET(x)
-#define PLL_CONTROL_DIV_MSB WLAN_PLL_CONTROL_DIV_MSB
-#define PLL_CONTROL_DIV_LSB WLAN_PLL_CONTROL_DIV_LSB
-#define PLL_CONTROL_DIV_MASK WLAN_PLL_CONTROL_DIV_MASK
-#define PLL_CONTROL_DIV_GET(x) WLAN_PLL_CONTROL_DIV_GET(x)
-#define PLL_CONTROL_DIV_SET(x) WLAN_PLL_CONTROL_DIV_SET(x)
-#define PLL_SETTLE_ADDRESS WLAN_PLL_SETTLE_ADDRESS
-#define PLL_SETTLE_OFFSET WLAN_PLL_SETTLE_OFFSET
-#define PLL_SETTLE_TIME_MSB WLAN_PLL_SETTLE_TIME_MSB
-#define PLL_SETTLE_TIME_LSB WLAN_PLL_SETTLE_TIME_LSB
-#define PLL_SETTLE_TIME_MASK WLAN_PLL_SETTLE_TIME_MASK
-#define PLL_SETTLE_TIME_GET(x) WLAN_PLL_SETTLE_TIME_GET(x)
-#define PLL_SETTLE_TIME_SET(x) WLAN_PLL_SETTLE_TIME_SET(x)
-#define XTAL_SETTLE_ADDRESS WLAN_XTAL_SETTLE_ADDRESS
-#define XTAL_SETTLE_OFFSET WLAN_XTAL_SETTLE_OFFSET
-#define XTAL_SETTLE_TIME_MSB WLAN_XTAL_SETTLE_TIME_MSB
-#define XTAL_SETTLE_TIME_LSB WLAN_XTAL_SETTLE_TIME_LSB
-#define XTAL_SETTLE_TIME_MASK WLAN_XTAL_SETTLE_TIME_MASK
-#define XTAL_SETTLE_TIME_GET(x) WLAN_XTAL_SETTLE_TIME_GET(x)
-#define XTAL_SETTLE_TIME_SET(x) WLAN_XTAL_SETTLE_TIME_SET(x)
 #define CPU_CLOCK_ADDRESS WLAN_CPU_CLOCK_ADDRESS
 #define CPU_CLOCK_OFFSET WLAN_CPU_CLOCK_OFFSET
 #define CPU_CLOCK_STANDARD_MSB WLAN_CPU_CLOCK_STANDARD_MSB
@@ -215,510 +123,6 @@
 #define CLOCK_CONTROL_SI0_CLK_MASK WLAN_CLOCK_CONTROL_SI0_CLK_MASK
 #define CLOCK_CONTROL_SI0_CLK_GET(x) WLAN_CLOCK_CONTROL_SI0_CLK_GET(x)
 #define CLOCK_CONTROL_SI0_CLK_SET(x) WLAN_CLOCK_CONTROL_SI0_CLK_SET(x)
-#define BIAS_OVERRIDE_ADDRESS WLAN_BIAS_OVERRIDE_ADDRESS
-#define BIAS_OVERRIDE_OFFSET WLAN_BIAS_OVERRIDE_OFFSET
-#define BIAS_OVERRIDE_ON_MSB WLAN_BIAS_OVERRIDE_ON_MSB
-#define BIAS_OVERRIDE_ON_LSB WLAN_BIAS_OVERRIDE_ON_LSB
-#define BIAS_OVERRIDE_ON_MASK WLAN_BIAS_OVERRIDE_ON_MASK
-#define BIAS_OVERRIDE_ON_GET(x) WLAN_BIAS_OVERRIDE_ON_GET(x)
-#define BIAS_OVERRIDE_ON_SET(x) WLAN_BIAS_OVERRIDE_ON_SET(x)
-#define WDT_CONTROL_ADDRESS WLAN_WDT_CONTROL_ADDRESS
-#define WDT_CONTROL_OFFSET WLAN_WDT_CONTROL_OFFSET
-#define WDT_CONTROL_ACTION_MSB WLAN_WDT_CONTROL_ACTION_MSB
-#define WDT_CONTROL_ACTION_LSB WLAN_WDT_CONTROL_ACTION_LSB
-#define WDT_CONTROL_ACTION_MASK WLAN_WDT_CONTROL_ACTION_MASK
-#define WDT_CONTROL_ACTION_GET(x) WLAN_WDT_CONTROL_ACTION_GET(x)
-#define WDT_CONTROL_ACTION_SET(x) WLAN_WDT_CONTROL_ACTION_SET(x)
-#define WDT_STATUS_ADDRESS WLAN_WDT_STATUS_ADDRESS
-#define WDT_STATUS_OFFSET WLAN_WDT_STATUS_OFFSET
-#define WDT_STATUS_INTERRUPT_MSB WLAN_WDT_STATUS_INTERRUPT_MSB
-#define WDT_STATUS_INTERRUPT_LSB WLAN_WDT_STATUS_INTERRUPT_LSB
-#define WDT_STATUS_INTERRUPT_MASK WLAN_WDT_STATUS_INTERRUPT_MASK
-#define WDT_STATUS_INTERRUPT_GET(x) WLAN_WDT_STATUS_INTERRUPT_GET(x)
-#define WDT_STATUS_INTERRUPT_SET(x) WLAN_WDT_STATUS_INTERRUPT_SET(x)
-#define WDT_ADDRESS WLAN_WDT_ADDRESS
-#define WDT_OFFSET WLAN_WDT_OFFSET
-#define WDT_TARGET_MSB WLAN_WDT_TARGET_MSB
-#define WDT_TARGET_LSB WLAN_WDT_TARGET_LSB
-#define WDT_TARGET_MASK WLAN_WDT_TARGET_MASK
-#define WDT_TARGET_GET(x) WLAN_WDT_TARGET_GET(x)
-#define WDT_TARGET_SET(x) WLAN_WDT_TARGET_SET(x)
-#define WDT_COUNT_ADDRESS WLAN_WDT_COUNT_ADDRESS
-#define WDT_COUNT_OFFSET WLAN_WDT_COUNT_OFFSET
-#define WDT_COUNT_VALUE_MSB WLAN_WDT_COUNT_VALUE_MSB
-#define WDT_COUNT_VALUE_LSB WLAN_WDT_COUNT_VALUE_LSB
-#define WDT_COUNT_VALUE_MASK WLAN_WDT_COUNT_VALUE_MASK
-#define WDT_COUNT_VALUE_GET(x) WLAN_WDT_COUNT_VALUE_GET(x)
-#define WDT_COUNT_VALUE_SET(x) WLAN_WDT_COUNT_VALUE_SET(x)
-#define WDT_RESET_ADDRESS WLAN_WDT_RESET_ADDRESS
-#define WDT_RESET_OFFSET WLAN_WDT_RESET_OFFSET
-#define WDT_RESET_VALUE_MSB WLAN_WDT_RESET_VALUE_MSB
-#define WDT_RESET_VALUE_LSB WLAN_WDT_RESET_VALUE_LSB
-#define WDT_RESET_VALUE_MASK WLAN_WDT_RESET_VALUE_MASK
-#define WDT_RESET_VALUE_GET(x) WLAN_WDT_RESET_VALUE_GET(x)
-#define WDT_RESET_VALUE_SET(x) WLAN_WDT_RESET_VALUE_SET(x)
-#define INT_STATUS_ADDRESS WLAN_INT_STATUS_ADDRESS
-#define INT_STATUS_OFFSET WLAN_INT_STATUS_OFFSET
-#define INT_STATUS_HCI_UART_MSB WLAN_INT_STATUS_HCI_UART_MSB
-#define INT_STATUS_HCI_UART_LSB WLAN_INT_STATUS_HCI_UART_LSB
-#define INT_STATUS_HCI_UART_MASK WLAN_INT_STATUS_HCI_UART_MASK
-#define INT_STATUS_HCI_UART_GET(x) WLAN_INT_STATUS_HCI_UART_GET(x)
-#define INT_STATUS_HCI_UART_SET(x) WLAN_INT_STATUS_HCI_UART_SET(x)
-#define INT_STATUS_THERM_MSB WLAN_INT_STATUS_THERM_MSB
-#define INT_STATUS_THERM_LSB WLAN_INT_STATUS_THERM_LSB
-#define INT_STATUS_THERM_MASK WLAN_INT_STATUS_THERM_MASK
-#define INT_STATUS_THERM_GET(x) WLAN_INT_STATUS_THERM_GET(x)
-#define INT_STATUS_THERM_SET(x) WLAN_INT_STATUS_THERM_SET(x)
-#define INT_STATUS_EFUSE_OVERWRITE_MSB WLAN_INT_STATUS_EFUSE_OVERWRITE_MSB
-#define INT_STATUS_EFUSE_OVERWRITE_LSB WLAN_INT_STATUS_EFUSE_OVERWRITE_LSB
-#define INT_STATUS_EFUSE_OVERWRITE_MASK WLAN_INT_STATUS_EFUSE_OVERWRITE_MASK
-#define INT_STATUS_EFUSE_OVERWRITE_GET(x) WLAN_INT_STATUS_EFUSE_OVERWRITE_GET(x)
-#define INT_STATUS_EFUSE_OVERWRITE_SET(x) WLAN_INT_STATUS_EFUSE_OVERWRITE_SET(x)
-#define INT_STATUS_UART_MBOX_MSB WLAN_INT_STATUS_UART_MBOX_MSB
-#define INT_STATUS_UART_MBOX_LSB WLAN_INT_STATUS_UART_MBOX_LSB
-#define INT_STATUS_UART_MBOX_MASK WLAN_INT_STATUS_UART_MBOX_MASK
-#define INT_STATUS_UART_MBOX_GET(x) WLAN_INT_STATUS_UART_MBOX_GET(x)
-#define INT_STATUS_UART_MBOX_SET(x) WLAN_INT_STATUS_UART_MBOX_SET(x)
-#define INT_STATUS_GENERIC_MBOX_MSB WLAN_INT_STATUS_GENERIC_MBOX_MSB
-#define INT_STATUS_GENERIC_MBOX_LSB WLAN_INT_STATUS_GENERIC_MBOX_LSB
-#define INT_STATUS_GENERIC_MBOX_MASK WLAN_INT_STATUS_GENERIC_MBOX_MASK
-#define INT_STATUS_GENERIC_MBOX_GET(x) WLAN_INT_STATUS_GENERIC_MBOX_GET(x)
-#define INT_STATUS_GENERIC_MBOX_SET(x) WLAN_INT_STATUS_GENERIC_MBOX_SET(x)
-#define INT_STATUS_RDMA_MSB WLAN_INT_STATUS_RDMA_MSB
-#define INT_STATUS_RDMA_LSB WLAN_INT_STATUS_RDMA_LSB
-#define INT_STATUS_RDMA_MASK WLAN_INT_STATUS_RDMA_MASK
-#define INT_STATUS_RDMA_GET(x) WLAN_INT_STATUS_RDMA_GET(x)
-#define INT_STATUS_RDMA_SET(x) WLAN_INT_STATUS_RDMA_SET(x)
-#define INT_STATUS_BTCOEX_MSB WLAN_INT_STATUS_BTCOEX_MSB
-#define INT_STATUS_BTCOEX_LSB WLAN_INT_STATUS_BTCOEX_LSB
-#define INT_STATUS_BTCOEX_MASK WLAN_INT_STATUS_BTCOEX_MASK
-#define INT_STATUS_BTCOEX_GET(x) WLAN_INT_STATUS_BTCOEX_GET(x)
-#define INT_STATUS_BTCOEX_SET(x) WLAN_INT_STATUS_BTCOEX_SET(x)
-#define INT_STATUS_RTC_POWER_MSB WLAN_INT_STATUS_RTC_POWER_MSB
-#define INT_STATUS_RTC_POWER_LSB WLAN_INT_STATUS_RTC_POWER_LSB
-#define INT_STATUS_RTC_POWER_MASK WLAN_INT_STATUS_RTC_POWER_MASK
-#define INT_STATUS_RTC_POWER_GET(x) WLAN_INT_STATUS_RTC_POWER_GET(x)
-#define INT_STATUS_RTC_POWER_SET(x) WLAN_INT_STATUS_RTC_POWER_SET(x)
-#define INT_STATUS_MAC_MSB WLAN_INT_STATUS_MAC_MSB
-#define INT_STATUS_MAC_LSB WLAN_INT_STATUS_MAC_LSB
-#define INT_STATUS_MAC_MASK WLAN_INT_STATUS_MAC_MASK
-#define INT_STATUS_MAC_GET(x) WLAN_INT_STATUS_MAC_GET(x)
-#define INT_STATUS_MAC_SET(x) WLAN_INT_STATUS_MAC_SET(x)
-#define INT_STATUS_MAILBOX_MSB WLAN_INT_STATUS_MAILBOX_MSB
-#define INT_STATUS_MAILBOX_LSB WLAN_INT_STATUS_MAILBOX_LSB
-#define INT_STATUS_MAILBOX_MASK WLAN_INT_STATUS_MAILBOX_MASK
-#define INT_STATUS_MAILBOX_GET(x) WLAN_INT_STATUS_MAILBOX_GET(x)
-#define INT_STATUS_MAILBOX_SET(x) WLAN_INT_STATUS_MAILBOX_SET(x)
-#define INT_STATUS_RTC_ALARM_MSB WLAN_INT_STATUS_RTC_ALARM_MSB
-#define INT_STATUS_RTC_ALARM_LSB WLAN_INT_STATUS_RTC_ALARM_LSB
-#define INT_STATUS_RTC_ALARM_MASK WLAN_INT_STATUS_RTC_ALARM_MASK
-#define INT_STATUS_RTC_ALARM_GET(x) WLAN_INT_STATUS_RTC_ALARM_GET(x)
-#define INT_STATUS_RTC_ALARM_SET(x) WLAN_INT_STATUS_RTC_ALARM_SET(x)
-#define INT_STATUS_HF_TIMER_MSB WLAN_INT_STATUS_HF_TIMER_MSB
-#define INT_STATUS_HF_TIMER_LSB WLAN_INT_STATUS_HF_TIMER_LSB
-#define INT_STATUS_HF_TIMER_MASK WLAN_INT_STATUS_HF_TIMER_MASK
-#define INT_STATUS_HF_TIMER_GET(x) WLAN_INT_STATUS_HF_TIMER_GET(x)
-#define INT_STATUS_HF_TIMER_SET(x) WLAN_INT_STATUS_HF_TIMER_SET(x)
-#define INT_STATUS_LF_TIMER3_MSB WLAN_INT_STATUS_LF_TIMER3_MSB
-#define INT_STATUS_LF_TIMER3_LSB WLAN_INT_STATUS_LF_TIMER3_LSB
-#define INT_STATUS_LF_TIMER3_MASK WLAN_INT_STATUS_LF_TIMER3_MASK
-#define INT_STATUS_LF_TIMER3_GET(x) WLAN_INT_STATUS_LF_TIMER3_GET(x)
-#define INT_STATUS_LF_TIMER3_SET(x) WLAN_INT_STATUS_LF_TIMER3_SET(x)
-#define INT_STATUS_LF_TIMER2_MSB WLAN_INT_STATUS_LF_TIMER2_MSB
-#define INT_STATUS_LF_TIMER2_LSB WLAN_INT_STATUS_LF_TIMER2_LSB
-#define INT_STATUS_LF_TIMER2_MASK WLAN_INT_STATUS_LF_TIMER2_MASK
-#define INT_STATUS_LF_TIMER2_GET(x) WLAN_INT_STATUS_LF_TIMER2_GET(x)
-#define INT_STATUS_LF_TIMER2_SET(x) WLAN_INT_STATUS_LF_TIMER2_SET(x)
-#define INT_STATUS_LF_TIMER1_MSB WLAN_INT_STATUS_LF_TIMER1_MSB
-#define INT_STATUS_LF_TIMER1_LSB WLAN_INT_STATUS_LF_TIMER1_LSB
-#define INT_STATUS_LF_TIMER1_MASK WLAN_INT_STATUS_LF_TIMER1_MASK
-#define INT_STATUS_LF_TIMER1_GET(x) WLAN_INT_STATUS_LF_TIMER1_GET(x)
-#define INT_STATUS_LF_TIMER1_SET(x) WLAN_INT_STATUS_LF_TIMER1_SET(x)
-#define INT_STATUS_LF_TIMER0_MSB WLAN_INT_STATUS_LF_TIMER0_MSB
-#define INT_STATUS_LF_TIMER0_LSB WLAN_INT_STATUS_LF_TIMER0_LSB
-#define INT_STATUS_LF_TIMER0_MASK WLAN_INT_STATUS_LF_TIMER0_MASK
-#define INT_STATUS_LF_TIMER0_GET(x) WLAN_INT_STATUS_LF_TIMER0_GET(x)
-#define INT_STATUS_LF_TIMER0_SET(x) WLAN_INT_STATUS_LF_TIMER0_SET(x)
-#define INT_STATUS_KEYPAD_MSB WLAN_INT_STATUS_KEYPAD_MSB
-#define INT_STATUS_KEYPAD_LSB WLAN_INT_STATUS_KEYPAD_LSB
-#define INT_STATUS_KEYPAD_MASK WLAN_INT_STATUS_KEYPAD_MASK
-#define INT_STATUS_KEYPAD_GET(x) WLAN_INT_STATUS_KEYPAD_GET(x)
-#define INT_STATUS_KEYPAD_SET(x) WLAN_INT_STATUS_KEYPAD_SET(x)
-#define INT_STATUS_SI_MSB WLAN_INT_STATUS_SI_MSB
-#define INT_STATUS_SI_LSB WLAN_INT_STATUS_SI_LSB
-#define INT_STATUS_SI_MASK WLAN_INT_STATUS_SI_MASK
-#define INT_STATUS_SI_GET(x) WLAN_INT_STATUS_SI_GET(x)
-#define INT_STATUS_SI_SET(x) WLAN_INT_STATUS_SI_SET(x)
-#define INT_STATUS_GPIO_MSB WLAN_INT_STATUS_GPIO_MSB
-#define INT_STATUS_GPIO_LSB WLAN_INT_STATUS_GPIO_LSB
-#define INT_STATUS_GPIO_MASK WLAN_INT_STATUS_GPIO_MASK
-#define INT_STATUS_GPIO_GET(x) WLAN_INT_STATUS_GPIO_GET(x)
-#define INT_STATUS_GPIO_SET(x) WLAN_INT_STATUS_GPIO_SET(x)
-#define INT_STATUS_UART_MSB WLAN_INT_STATUS_UART_MSB
-#define INT_STATUS_UART_LSB WLAN_INT_STATUS_UART_LSB
-#define INT_STATUS_UART_MASK WLAN_INT_STATUS_UART_MASK
-#define INT_STATUS_UART_GET(x) WLAN_INT_STATUS_UART_GET(x)
-#define INT_STATUS_UART_SET(x) WLAN_INT_STATUS_UART_SET(x)
-#define INT_STATUS_ERROR_MSB WLAN_INT_STATUS_ERROR_MSB
-#define INT_STATUS_ERROR_LSB WLAN_INT_STATUS_ERROR_LSB
-#define INT_STATUS_ERROR_MASK WLAN_INT_STATUS_ERROR_MASK
-#define INT_STATUS_ERROR_GET(x) WLAN_INT_STATUS_ERROR_GET(x)
-#define INT_STATUS_ERROR_SET(x) WLAN_INT_STATUS_ERROR_SET(x)
-#define INT_STATUS_WDT_INT_MSB WLAN_INT_STATUS_WDT_INT_MSB
-#define INT_STATUS_WDT_INT_LSB WLAN_INT_STATUS_WDT_INT_LSB
-#define INT_STATUS_WDT_INT_MASK WLAN_INT_STATUS_WDT_INT_MASK
-#define INT_STATUS_WDT_INT_GET(x) WLAN_INT_STATUS_WDT_INT_GET(x)
-#define INT_STATUS_WDT_INT_SET(x) WLAN_INT_STATUS_WDT_INT_SET(x)
-#define LF_TIMER0_ADDRESS WLAN_LF_TIMER0_ADDRESS
-#define LF_TIMER0_OFFSET WLAN_LF_TIMER0_OFFSET
-#define LF_TIMER0_TARGET_MSB WLAN_LF_TIMER0_TARGET_MSB
-#define LF_TIMER0_TARGET_LSB WLAN_LF_TIMER0_TARGET_LSB
-#define LF_TIMER0_TARGET_MASK WLAN_LF_TIMER0_TARGET_MASK
-#define LF_TIMER0_TARGET_GET(x) WLAN_LF_TIMER0_TARGET_GET(x)
-#define LF_TIMER0_TARGET_SET(x) WLAN_LF_TIMER0_TARGET_SET(x)
-#define LF_TIMER_COUNT0_ADDRESS WLAN_LF_TIMER_COUNT0_ADDRESS
-#define LF_TIMER_COUNT0_OFFSET WLAN_LF_TIMER_COUNT0_OFFSET
-#define LF_TIMER_COUNT0_VALUE_MSB WLAN_LF_TIMER_COUNT0_VALUE_MSB
-#define LF_TIMER_COUNT0_VALUE_LSB WLAN_LF_TIMER_COUNT0_VALUE_LSB
-#define LF_TIMER_COUNT0_VALUE_MASK WLAN_LF_TIMER_COUNT0_VALUE_MASK
-#define LF_TIMER_COUNT0_VALUE_GET(x) WLAN_LF_TIMER_COUNT0_VALUE_GET(x)
-#define LF_TIMER_COUNT0_VALUE_SET(x) WLAN_LF_TIMER_COUNT0_VALUE_SET(x)
-#define LF_TIMER_CONTROL0_ADDRESS WLAN_LF_TIMER_CONTROL0_ADDRESS
-#define LF_TIMER_CONTROL0_OFFSET WLAN_LF_TIMER_CONTROL0_OFFSET
-#define LF_TIMER_CONTROL0_ENABLE_MSB WLAN_LF_TIMER_CONTROL0_ENABLE_MSB
-#define LF_TIMER_CONTROL0_ENABLE_LSB WLAN_LF_TIMER_CONTROL0_ENABLE_LSB
-#define LF_TIMER_CONTROL0_ENABLE_MASK WLAN_LF_TIMER_CONTROL0_ENABLE_MASK
-#define LF_TIMER_CONTROL0_ENABLE_GET(x) WLAN_LF_TIMER_CONTROL0_ENABLE_GET(x)
-#define LF_TIMER_CONTROL0_ENABLE_SET(x) WLAN_LF_TIMER_CONTROL0_ENABLE_SET(x)
-#define LF_TIMER_CONTROL0_AUTO_RESTART_MSB WLAN_LF_TIMER_CONTROL0_AUTO_RESTART_MSB
-#define LF_TIMER_CONTROL0_AUTO_RESTART_LSB WLAN_LF_TIMER_CONTROL0_AUTO_RESTART_LSB
-#define LF_TIMER_CONTROL0_AUTO_RESTART_MASK WLAN_LF_TIMER_CONTROL0_AUTO_RESTART_MASK
-#define LF_TIMER_CONTROL0_AUTO_RESTART_GET(x) WLAN_LF_TIMER_CONTROL0_AUTO_RESTART_GET(x)
-#define LF_TIMER_CONTROL0_AUTO_RESTART_SET(x) WLAN_LF_TIMER_CONTROL0_AUTO_RESTART_SET(x)
-#define LF_TIMER_CONTROL0_RESET_MSB WLAN_LF_TIMER_CONTROL0_RESET_MSB
-#define LF_TIMER_CONTROL0_RESET_LSB WLAN_LF_TIMER_CONTROL0_RESET_LSB
-#define LF_TIMER_CONTROL0_RESET_MASK WLAN_LF_TIMER_CONTROL0_RESET_MASK
-#define LF_TIMER_CONTROL0_RESET_GET(x) WLAN_LF_TIMER_CONTROL0_RESET_GET(x)
-#define LF_TIMER_CONTROL0_RESET_SET(x) WLAN_LF_TIMER_CONTROL0_RESET_SET(x)
-#define LF_TIMER_STATUS0_ADDRESS WLAN_LF_TIMER_STATUS0_ADDRESS
-#define LF_TIMER_STATUS0_OFFSET WLAN_LF_TIMER_STATUS0_OFFSET
-#define LF_TIMER_STATUS0_INTERRUPT_MSB WLAN_LF_TIMER_STATUS0_INTERRUPT_MSB
-#define LF_TIMER_STATUS0_INTERRUPT_LSB WLAN_LF_TIMER_STATUS0_INTERRUPT_LSB
-#define LF_TIMER_STATUS0_INTERRUPT_MASK WLAN_LF_TIMER_STATUS0_INTERRUPT_MASK
-#define LF_TIMER_STATUS0_INTERRUPT_GET(x) WLAN_LF_TIMER_STATUS0_INTERRUPT_GET(x)
-#define LF_TIMER_STATUS0_INTERRUPT_SET(x) WLAN_LF_TIMER_STATUS0_INTERRUPT_SET(x)
-#define LF_TIMER1_ADDRESS WLAN_LF_TIMER1_ADDRESS
-#define LF_TIMER1_OFFSET WLAN_LF_TIMER1_OFFSET
-#define LF_TIMER1_TARGET_MSB WLAN_LF_TIMER1_TARGET_MSB
-#define LF_TIMER1_TARGET_LSB WLAN_LF_TIMER1_TARGET_LSB
-#define LF_TIMER1_TARGET_MASK WLAN_LF_TIMER1_TARGET_MASK
-#define LF_TIMER1_TARGET_GET(x) WLAN_LF_TIMER1_TARGET_GET(x)
-#define LF_TIMER1_TARGET_SET(x) WLAN_LF_TIMER1_TARGET_SET(x)
-#define LF_TIMER_COUNT1_ADDRESS WLAN_LF_TIMER_COUNT1_ADDRESS
-#define LF_TIMER_COUNT1_OFFSET WLAN_LF_TIMER_COUNT1_OFFSET
-#define LF_TIMER_COUNT1_VALUE_MSB WLAN_LF_TIMER_COUNT1_VALUE_MSB
-#define LF_TIMER_COUNT1_VALUE_LSB WLAN_LF_TIMER_COUNT1_VALUE_LSB
-#define LF_TIMER_COUNT1_VALUE_MASK WLAN_LF_TIMER_COUNT1_VALUE_MASK
-#define LF_TIMER_COUNT1_VALUE_GET(x) WLAN_LF_TIMER_COUNT1_VALUE_GET(x)
-#define LF_TIMER_COUNT1_VALUE_SET(x) WLAN_LF_TIMER_COUNT1_VALUE_SET(x)
-#define LF_TIMER_CONTROL1_ADDRESS WLAN_LF_TIMER_CONTROL1_ADDRESS
-#define LF_TIMER_CONTROL1_OFFSET WLAN_LF_TIMER_CONTROL1_OFFSET
-#define LF_TIMER_CONTROL1_ENABLE_MSB WLAN_LF_TIMER_CONTROL1_ENABLE_MSB
-#define LF_TIMER_CONTROL1_ENABLE_LSB WLAN_LF_TIMER_CONTROL1_ENABLE_LSB
-#define LF_TIMER_CONTROL1_ENABLE_MASK WLAN_LF_TIMER_CONTROL1_ENABLE_MASK
-#define LF_TIMER_CONTROL1_ENABLE_GET(x) WLAN_LF_TIMER_CONTROL1_ENABLE_GET(x)
-#define LF_TIMER_CONTROL1_ENABLE_SET(x) WLAN_LF_TIMER_CONTROL1_ENABLE_SET(x)
-#define LF_TIMER_CONTROL1_AUTO_RESTART_MSB WLAN_LF_TIMER_CONTROL1_AUTO_RESTART_MSB
-#define LF_TIMER_CONTROL1_AUTO_RESTART_LSB WLAN_LF_TIMER_CONTROL1_AUTO_RESTART_LSB
-#define LF_TIMER_CONTROL1_AUTO_RESTART_MASK WLAN_LF_TIMER_CONTROL1_AUTO_RESTART_MASK
-#define LF_TIMER_CONTROL1_AUTO_RESTART_GET(x) WLAN_LF_TIMER_CONTROL1_AUTO_RESTART_GET(x)
-#define LF_TIMER_CONTROL1_AUTO_RESTART_SET(x) WLAN_LF_TIMER_CONTROL1_AUTO_RESTART_SET(x)
-#define LF_TIMER_CONTROL1_RESET_MSB WLAN_LF_TIMER_CONTROL1_RESET_MSB
-#define LF_TIMER_CONTROL1_RESET_LSB WLAN_LF_TIMER_CONTROL1_RESET_LSB
-#define LF_TIMER_CONTROL1_RESET_MASK WLAN_LF_TIMER_CONTROL1_RESET_MASK
-#define LF_TIMER_CONTROL1_RESET_GET(x) WLAN_LF_TIMER_CONTROL1_RESET_GET(x)
-#define LF_TIMER_CONTROL1_RESET_SET(x) WLAN_LF_TIMER_CONTROL1_RESET_SET(x)
-#define LF_TIMER_STATUS1_ADDRESS WLAN_LF_TIMER_STATUS1_ADDRESS
-#define LF_TIMER_STATUS1_OFFSET WLAN_LF_TIMER_STATUS1_OFFSET
-#define LF_TIMER_STATUS1_INTERRUPT_MSB WLAN_LF_TIMER_STATUS1_INTERRUPT_MSB
-#define LF_TIMER_STATUS1_INTERRUPT_LSB WLAN_LF_TIMER_STATUS1_INTERRUPT_LSB
-#define LF_TIMER_STATUS1_INTERRUPT_MASK WLAN_LF_TIMER_STATUS1_INTERRUPT_MASK
-#define LF_TIMER_STATUS1_INTERRUPT_GET(x) WLAN_LF_TIMER_STATUS1_INTERRUPT_GET(x)
-#define LF_TIMER_STATUS1_INTERRUPT_SET(x) WLAN_LF_TIMER_STATUS1_INTERRUPT_SET(x)
-#define LF_TIMER2_ADDRESS WLAN_LF_TIMER2_ADDRESS
-#define LF_TIMER2_OFFSET WLAN_LF_TIMER2_OFFSET
-#define LF_TIMER2_TARGET_MSB WLAN_LF_TIMER2_TARGET_MSB
-#define LF_TIMER2_TARGET_LSB WLAN_LF_TIMER2_TARGET_LSB
-#define LF_TIMER2_TARGET_MASK WLAN_LF_TIMER2_TARGET_MASK
-#define LF_TIMER2_TARGET_GET(x) WLAN_LF_TIMER2_TARGET_GET(x)
-#define LF_TIMER2_TARGET_SET(x) WLAN_LF_TIMER2_TARGET_SET(x)
-#define LF_TIMER_COUNT2_ADDRESS WLAN_LF_TIMER_COUNT2_ADDRESS
-#define LF_TIMER_COUNT2_OFFSET WLAN_LF_TIMER_COUNT2_OFFSET
-#define LF_TIMER_COUNT2_VALUE_MSB WLAN_LF_TIMER_COUNT2_VALUE_MSB
-#define LF_TIMER_COUNT2_VALUE_LSB WLAN_LF_TIMER_COUNT2_VALUE_LSB
-#define LF_TIMER_COUNT2_VALUE_MASK WLAN_LF_TIMER_COUNT2_VALUE_MASK
-#define LF_TIMER_COUNT2_VALUE_GET(x) WLAN_LF_TIMER_COUNT2_VALUE_GET(x)
-#define LF_TIMER_COUNT2_VALUE_SET(x) WLAN_LF_TIMER_COUNT2_VALUE_SET(x)
-#define LF_TIMER_CONTROL2_ADDRESS WLAN_LF_TIMER_CONTROL2_ADDRESS
-#define LF_TIMER_CONTROL2_OFFSET WLAN_LF_TIMER_CONTROL2_OFFSET
-#define LF_TIMER_CONTROL2_ENABLE_MSB WLAN_LF_TIMER_CONTROL2_ENABLE_MSB
-#define LF_TIMER_CONTROL2_ENABLE_LSB WLAN_LF_TIMER_CONTROL2_ENABLE_LSB
-#define LF_TIMER_CONTROL2_ENABLE_MASK WLAN_LF_TIMER_CONTROL2_ENABLE_MASK
-#define LF_TIMER_CONTROL2_ENABLE_GET(x) WLAN_LF_TIMER_CONTROL2_ENABLE_GET(x)
-#define LF_TIMER_CONTROL2_ENABLE_SET(x) WLAN_LF_TIMER_CONTROL2_ENABLE_SET(x)
-#define LF_TIMER_CONTROL2_AUTO_RESTART_MSB WLAN_LF_TIMER_CONTROL2_AUTO_RESTART_MSB
-#define LF_TIMER_CONTROL2_AUTO_RESTART_LSB WLAN_LF_TIMER_CONTROL2_AUTO_RESTART_LSB
-#define LF_TIMER_CONTROL2_AUTO_RESTART_MASK WLAN_LF_TIMER_CONTROL2_AUTO_RESTART_MASK
-#define LF_TIMER_CONTROL2_AUTO_RESTART_GET(x) WLAN_LF_TIMER_CONTROL2_AUTO_RESTART_GET(x)
-#define LF_TIMER_CONTROL2_AUTO_RESTART_SET(x) WLAN_LF_TIMER_CONTROL2_AUTO_RESTART_SET(x)
-#define LF_TIMER_CONTROL2_RESET_MSB WLAN_LF_TIMER_CONTROL2_RESET_MSB
-#define LF_TIMER_CONTROL2_RESET_LSB WLAN_LF_TIMER_CONTROL2_RESET_LSB
-#define LF_TIMER_CONTROL2_RESET_MASK WLAN_LF_TIMER_CONTROL2_RESET_MASK
-#define LF_TIMER_CONTROL2_RESET_GET(x) WLAN_LF_TIMER_CONTROL2_RESET_GET(x)
-#define LF_TIMER_CONTROL2_RESET_SET(x) WLAN_LF_TIMER_CONTROL2_RESET_SET(x)
-#define LF_TIMER_STATUS2_ADDRESS WLAN_LF_TIMER_STATUS2_ADDRESS
-#define LF_TIMER_STATUS2_OFFSET WLAN_LF_TIMER_STATUS2_OFFSET
-#define LF_TIMER_STATUS2_INTERRUPT_MSB WLAN_LF_TIMER_STATUS2_INTERRUPT_MSB
-#define LF_TIMER_STATUS2_INTERRUPT_LSB WLAN_LF_TIMER_STATUS2_INTERRUPT_LSB
-#define LF_TIMER_STATUS2_INTERRUPT_MASK WLAN_LF_TIMER_STATUS2_INTERRUPT_MASK
-#define LF_TIMER_STATUS2_INTERRUPT_GET(x) WLAN_LF_TIMER_STATUS2_INTERRUPT_GET(x)
-#define LF_TIMER_STATUS2_INTERRUPT_SET(x) WLAN_LF_TIMER_STATUS2_INTERRUPT_SET(x)
-#define LF_TIMER3_ADDRESS WLAN_LF_TIMER3_ADDRESS
-#define LF_TIMER3_OFFSET WLAN_LF_TIMER3_OFFSET
-#define LF_TIMER3_TARGET_MSB WLAN_LF_TIMER3_TARGET_MSB
-#define LF_TIMER3_TARGET_LSB WLAN_LF_TIMER3_TARGET_LSB
-#define LF_TIMER3_TARGET_MASK WLAN_LF_TIMER3_TARGET_MASK
-#define LF_TIMER3_TARGET_GET(x) WLAN_LF_TIMER3_TARGET_GET(x)
-#define LF_TIMER3_TARGET_SET(x) WLAN_LF_TIMER3_TARGET_SET(x)
-#define LF_TIMER_COUNT3_ADDRESS WLAN_LF_TIMER_COUNT3_ADDRESS
-#define LF_TIMER_COUNT3_OFFSET WLAN_LF_TIMER_COUNT3_OFFSET
-#define LF_TIMER_COUNT3_VALUE_MSB WLAN_LF_TIMER_COUNT3_VALUE_MSB
-#define LF_TIMER_COUNT3_VALUE_LSB WLAN_LF_TIMER_COUNT3_VALUE_LSB
-#define LF_TIMER_COUNT3_VALUE_MASK WLAN_LF_TIMER_COUNT3_VALUE_MASK
-#define LF_TIMER_COUNT3_VALUE_GET(x) WLAN_LF_TIMER_COUNT3_VALUE_GET(x)
-#define LF_TIMER_COUNT3_VALUE_SET(x) WLAN_LF_TIMER_COUNT3_VALUE_SET(x)
-#define LF_TIMER_CONTROL3_ADDRESS WLAN_LF_TIMER_CONTROL3_ADDRESS
-#define LF_TIMER_CONTROL3_OFFSET WLAN_LF_TIMER_CONTROL3_OFFSET
-#define LF_TIMER_CONTROL3_ENABLE_MSB WLAN_LF_TIMER_CONTROL3_ENABLE_MSB
-#define LF_TIMER_CONTROL3_ENABLE_LSB WLAN_LF_TIMER_CONTROL3_ENABLE_LSB
-#define LF_TIMER_CONTROL3_ENABLE_MASK WLAN_LF_TIMER_CONTROL3_ENABLE_MASK
-#define LF_TIMER_CONTROL3_ENABLE_GET(x) WLAN_LF_TIMER_CONTROL3_ENABLE_GET(x)
-#define LF_TIMER_CONTROL3_ENABLE_SET(x) WLAN_LF_TIMER_CONTROL3_ENABLE_SET(x)
-#define LF_TIMER_CONTROL3_AUTO_RESTART_MSB WLAN_LF_TIMER_CONTROL3_AUTO_RESTART_MSB
-#define LF_TIMER_CONTROL3_AUTO_RESTART_LSB WLAN_LF_TIMER_CONTROL3_AUTO_RESTART_LSB
-#define LF_TIMER_CONTROL3_AUTO_RESTART_MASK WLAN_LF_TIMER_CONTROL3_AUTO_RESTART_MASK
-#define LF_TIMER_CONTROL3_AUTO_RESTART_GET(x) WLAN_LF_TIMER_CONTROL3_AUTO_RESTART_GET(x)
-#define LF_TIMER_CONTROL3_AUTO_RESTART_SET(x) WLAN_LF_TIMER_CONTROL3_AUTO_RESTART_SET(x)
-#define LF_TIMER_CONTROL3_RESET_MSB WLAN_LF_TIMER_CONTROL3_RESET_MSB
-#define LF_TIMER_CONTROL3_RESET_LSB WLAN_LF_TIMER_CONTROL3_RESET_LSB
-#define LF_TIMER_CONTROL3_RESET_MASK WLAN_LF_TIMER_CONTROL3_RESET_MASK
-#define LF_TIMER_CONTROL3_RESET_GET(x) WLAN_LF_TIMER_CONTROL3_RESET_GET(x)
-#define LF_TIMER_CONTROL3_RESET_SET(x) WLAN_LF_TIMER_CONTROL3_RESET_SET(x)
-#define LF_TIMER_STATUS3_ADDRESS WLAN_LF_TIMER_STATUS3_ADDRESS
-#define LF_TIMER_STATUS3_OFFSET WLAN_LF_TIMER_STATUS3_OFFSET
-#define LF_TIMER_STATUS3_INTERRUPT_MSB WLAN_LF_TIMER_STATUS3_INTERRUPT_MSB
-#define LF_TIMER_STATUS3_INTERRUPT_LSB WLAN_LF_TIMER_STATUS3_INTERRUPT_LSB
-#define LF_TIMER_STATUS3_INTERRUPT_MASK WLAN_LF_TIMER_STATUS3_INTERRUPT_MASK
-#define LF_TIMER_STATUS3_INTERRUPT_GET(x) WLAN_LF_TIMER_STATUS3_INTERRUPT_GET(x)
-#define LF_TIMER_STATUS3_INTERRUPT_SET(x) WLAN_LF_TIMER_STATUS3_INTERRUPT_SET(x)
-#define HF_TIMER_ADDRESS WLAN_HF_TIMER_ADDRESS
-#define HF_TIMER_OFFSET WLAN_HF_TIMER_OFFSET
-#define HF_TIMER_TARGET_MSB WLAN_HF_TIMER_TARGET_MSB
-#define HF_TIMER_TARGET_LSB WLAN_HF_TIMER_TARGET_LSB
-#define HF_TIMER_TARGET_MASK WLAN_HF_TIMER_TARGET_MASK
-#define HF_TIMER_TARGET_GET(x) WLAN_HF_TIMER_TARGET_GET(x)
-#define HF_TIMER_TARGET_SET(x) WLAN_HF_TIMER_TARGET_SET(x)
-#define HF_TIMER_COUNT_ADDRESS WLAN_HF_TIMER_COUNT_ADDRESS
-#define HF_TIMER_COUNT_OFFSET WLAN_HF_TIMER_COUNT_OFFSET
-#define HF_TIMER_COUNT_VALUE_MSB WLAN_HF_TIMER_COUNT_VALUE_MSB
-#define HF_TIMER_COUNT_VALUE_LSB WLAN_HF_TIMER_COUNT_VALUE_LSB
-#define HF_TIMER_COUNT_VALUE_MASK WLAN_HF_TIMER_COUNT_VALUE_MASK
-#define HF_TIMER_COUNT_VALUE_GET(x) WLAN_HF_TIMER_COUNT_VALUE_GET(x)
-#define HF_TIMER_COUNT_VALUE_SET(x) WLAN_HF_TIMER_COUNT_VALUE_SET(x)
-#define HF_LF_COUNT_ADDRESS WLAN_HF_LF_COUNT_ADDRESS
-#define HF_LF_COUNT_OFFSET WLAN_HF_LF_COUNT_OFFSET
-#define HF_LF_COUNT_VALUE_MSB WLAN_HF_LF_COUNT_VALUE_MSB
-#define HF_LF_COUNT_VALUE_LSB WLAN_HF_LF_COUNT_VALUE_LSB
-#define HF_LF_COUNT_VALUE_MASK WLAN_HF_LF_COUNT_VALUE_MASK
-#define HF_LF_COUNT_VALUE_GET(x) WLAN_HF_LF_COUNT_VALUE_GET(x)
-#define HF_LF_COUNT_VALUE_SET(x) WLAN_HF_LF_COUNT_VALUE_SET(x)
-#define HF_TIMER_CONTROL_ADDRESS WLAN_HF_TIMER_CONTROL_ADDRESS
-#define HF_TIMER_CONTROL_OFFSET WLAN_HF_TIMER_CONTROL_OFFSET
-#define HF_TIMER_CONTROL_ENABLE_MSB WLAN_HF_TIMER_CONTROL_ENABLE_MSB
-#define HF_TIMER_CONTROL_ENABLE_LSB WLAN_HF_TIMER_CONTROL_ENABLE_LSB
-#define HF_TIMER_CONTROL_ENABLE_MASK WLAN_HF_TIMER_CONTROL_ENABLE_MASK
-#define HF_TIMER_CONTROL_ENABLE_GET(x) WLAN_HF_TIMER_CONTROL_ENABLE_GET(x)
-#define HF_TIMER_CONTROL_ENABLE_SET(x) WLAN_HF_TIMER_CONTROL_ENABLE_SET(x)
-#define HF_TIMER_CONTROL_ON_MSB WLAN_HF_TIMER_CONTROL_ON_MSB
-#define HF_TIMER_CONTROL_ON_LSB WLAN_HF_TIMER_CONTROL_ON_LSB
-#define HF_TIMER_CONTROL_ON_MASK WLAN_HF_TIMER_CONTROL_ON_MASK
-#define HF_TIMER_CONTROL_ON_GET(x) WLAN_HF_TIMER_CONTROL_ON_GET(x)
-#define HF_TIMER_CONTROL_ON_SET(x) WLAN_HF_TIMER_CONTROL_ON_SET(x)
-#define HF_TIMER_CONTROL_AUTO_RESTART_MSB WLAN_HF_TIMER_CONTROL_AUTO_RESTART_MSB
-#define HF_TIMER_CONTROL_AUTO_RESTART_LSB WLAN_HF_TIMER_CONTROL_AUTO_RESTART_LSB
-#define HF_TIMER_CONTROL_AUTO_RESTART_MASK WLAN_HF_TIMER_CONTROL_AUTO_RESTART_MASK
-#define HF_TIMER_CONTROL_AUTO_RESTART_GET(x) WLAN_HF_TIMER_CONTROL_AUTO_RESTART_GET(x)
-#define HF_TIMER_CONTROL_AUTO_RESTART_SET(x) WLAN_HF_TIMER_CONTROL_AUTO_RESTART_SET(x)
-#define HF_TIMER_CONTROL_RESET_MSB WLAN_HF_TIMER_CONTROL_RESET_MSB
-#define HF_TIMER_CONTROL_RESET_LSB WLAN_HF_TIMER_CONTROL_RESET_LSB
-#define HF_TIMER_CONTROL_RESET_MASK WLAN_HF_TIMER_CONTROL_RESET_MASK
-#define HF_TIMER_CONTROL_RESET_GET(x) WLAN_HF_TIMER_CONTROL_RESET_GET(x)
-#define HF_TIMER_CONTROL_RESET_SET(x) WLAN_HF_TIMER_CONTROL_RESET_SET(x)
-#define HF_TIMER_STATUS_ADDRESS WLAN_HF_TIMER_STATUS_ADDRESS
-#define HF_TIMER_STATUS_OFFSET WLAN_HF_TIMER_STATUS_OFFSET
-#define HF_TIMER_STATUS_INTERRUPT_MSB WLAN_HF_TIMER_STATUS_INTERRUPT_MSB
-#define HF_TIMER_STATUS_INTERRUPT_LSB WLAN_HF_TIMER_STATUS_INTERRUPT_LSB
-#define HF_TIMER_STATUS_INTERRUPT_MASK WLAN_HF_TIMER_STATUS_INTERRUPT_MASK
-#define HF_TIMER_STATUS_INTERRUPT_GET(x) WLAN_HF_TIMER_STATUS_INTERRUPT_GET(x)
-#define HF_TIMER_STATUS_INTERRUPT_SET(x) WLAN_HF_TIMER_STATUS_INTERRUPT_SET(x)
-#define RTC_CONTROL_ADDRESS WLAN_RTC_CONTROL_ADDRESS
-#define RTC_CONTROL_OFFSET WLAN_RTC_CONTROL_OFFSET
-#define RTC_CONTROL_ENABLE_MSB WLAN_RTC_CONTROL_ENABLE_MSB
-#define RTC_CONTROL_ENABLE_LSB WLAN_RTC_CONTROL_ENABLE_LSB
-#define RTC_CONTROL_ENABLE_MASK WLAN_RTC_CONTROL_ENABLE_MASK
-#define RTC_CONTROL_ENABLE_GET(x) WLAN_RTC_CONTROL_ENABLE_GET(x)
-#define RTC_CONTROL_ENABLE_SET(x) WLAN_RTC_CONTROL_ENABLE_SET(x)
-#define RTC_CONTROL_LOAD_RTC_MSB WLAN_RTC_CONTROL_LOAD_RTC_MSB
-#define RTC_CONTROL_LOAD_RTC_LSB WLAN_RTC_CONTROL_LOAD_RTC_LSB
-#define RTC_CONTROL_LOAD_RTC_MASK WLAN_RTC_CONTROL_LOAD_RTC_MASK
-#define RTC_CONTROL_LOAD_RTC_GET(x) WLAN_RTC_CONTROL_LOAD_RTC_GET(x)
-#define RTC_CONTROL_LOAD_RTC_SET(x) WLAN_RTC_CONTROL_LOAD_RTC_SET(x)
-#define RTC_CONTROL_LOAD_ALARM_MSB WLAN_RTC_CONTROL_LOAD_ALARM_MSB
-#define RTC_CONTROL_LOAD_ALARM_LSB WLAN_RTC_CONTROL_LOAD_ALARM_LSB
-#define RTC_CONTROL_LOAD_ALARM_MASK WLAN_RTC_CONTROL_LOAD_ALARM_MASK
-#define RTC_CONTROL_LOAD_ALARM_GET(x) WLAN_RTC_CONTROL_LOAD_ALARM_GET(x)
-#define RTC_CONTROL_LOAD_ALARM_SET(x) WLAN_RTC_CONTROL_LOAD_ALARM_SET(x)
-#define RTC_TIME_ADDRESS WLAN_RTC_TIME_ADDRESS
-#define RTC_TIME_OFFSET WLAN_RTC_TIME_OFFSET
-#define RTC_TIME_WEEK_DAY_MSB WLAN_RTC_TIME_WEEK_DAY_MSB
-#define RTC_TIME_WEEK_DAY_LSB WLAN_RTC_TIME_WEEK_DAY_LSB
-#define RTC_TIME_WEEK_DAY_MASK WLAN_RTC_TIME_WEEK_DAY_MASK
-#define RTC_TIME_WEEK_DAY_GET(x) WLAN_RTC_TIME_WEEK_DAY_GET(x)
-#define RTC_TIME_WEEK_DAY_SET(x) WLAN_RTC_TIME_WEEK_DAY_SET(x)
-#define RTC_TIME_HOUR_MSB WLAN_RTC_TIME_HOUR_MSB
-#define RTC_TIME_HOUR_LSB WLAN_RTC_TIME_HOUR_LSB
-#define RTC_TIME_HOUR_MASK WLAN_RTC_TIME_HOUR_MASK
-#define RTC_TIME_HOUR_GET(x) WLAN_RTC_TIME_HOUR_GET(x)
-#define RTC_TIME_HOUR_SET(x) WLAN_RTC_TIME_HOUR_SET(x)
-#define RTC_TIME_MINUTE_MSB WLAN_RTC_TIME_MINUTE_MSB
-#define RTC_TIME_MINUTE_LSB WLAN_RTC_TIME_MINUTE_LSB
-#define RTC_TIME_MINUTE_MASK WLAN_RTC_TIME_MINUTE_MASK
-#define RTC_TIME_MINUTE_GET(x) WLAN_RTC_TIME_MINUTE_GET(x)
-#define RTC_TIME_MINUTE_SET(x) WLAN_RTC_TIME_MINUTE_SET(x)
-#define RTC_TIME_SECOND_MSB WLAN_RTC_TIME_SECOND_MSB
-#define RTC_TIME_SECOND_LSB WLAN_RTC_TIME_SECOND_LSB
-#define RTC_TIME_SECOND_MASK WLAN_RTC_TIME_SECOND_MASK
-#define RTC_TIME_SECOND_GET(x) WLAN_RTC_TIME_SECOND_GET(x)
-#define RTC_TIME_SECOND_SET(x) WLAN_RTC_TIME_SECOND_SET(x)
-#define RTC_DATE_ADDRESS WLAN_RTC_DATE_ADDRESS
-#define RTC_DATE_OFFSET WLAN_RTC_DATE_OFFSET
-#define RTC_DATE_YEAR_MSB WLAN_RTC_DATE_YEAR_MSB
-#define RTC_DATE_YEAR_LSB WLAN_RTC_DATE_YEAR_LSB
-#define RTC_DATE_YEAR_MASK WLAN_RTC_DATE_YEAR_MASK
-#define RTC_DATE_YEAR_GET(x) WLAN_RTC_DATE_YEAR_GET(x)
-#define RTC_DATE_YEAR_SET(x) WLAN_RTC_DATE_YEAR_SET(x)
-#define RTC_DATE_MONTH_MSB WLAN_RTC_DATE_MONTH_MSB
-#define RTC_DATE_MONTH_LSB WLAN_RTC_DATE_MONTH_LSB
-#define RTC_DATE_MONTH_MASK WLAN_RTC_DATE_MONTH_MASK
-#define RTC_DATE_MONTH_GET(x) WLAN_RTC_DATE_MONTH_GET(x)
-#define RTC_DATE_MONTH_SET(x) WLAN_RTC_DATE_MONTH_SET(x)
-#define RTC_DATE_MONTH_DAY_MSB WLAN_RTC_DATE_MONTH_DAY_MSB
-#define RTC_DATE_MONTH_DAY_LSB WLAN_RTC_DATE_MONTH_DAY_LSB
-#define RTC_DATE_MONTH_DAY_MASK WLAN_RTC_DATE_MONTH_DAY_MASK
-#define RTC_DATE_MONTH_DAY_GET(x) WLAN_RTC_DATE_MONTH_DAY_GET(x)
-#define RTC_DATE_MONTH_DAY_SET(x) WLAN_RTC_DATE_MONTH_DAY_SET(x)
-#define RTC_SET_TIME_ADDRESS WLAN_RTC_SET_TIME_ADDRESS
-#define RTC_SET_TIME_OFFSET WLAN_RTC_SET_TIME_OFFSET
-#define RTC_SET_TIME_WEEK_DAY_MSB WLAN_RTC_SET_TIME_WEEK_DAY_MSB
-#define RTC_SET_TIME_WEEK_DAY_LSB WLAN_RTC_SET_TIME_WEEK_DAY_LSB
-#define RTC_SET_TIME_WEEK_DAY_MASK WLAN_RTC_SET_TIME_WEEK_DAY_MASK
-#define RTC_SET_TIME_WEEK_DAY_GET(x) WLAN_RTC_SET_TIME_WEEK_DAY_GET(x)
-#define RTC_SET_TIME_WEEK_DAY_SET(x) WLAN_RTC_SET_TIME_WEEK_DAY_SET(x)
-#define RTC_SET_TIME_HOUR_MSB WLAN_RTC_SET_TIME_HOUR_MSB
-#define RTC_SET_TIME_HOUR_LSB WLAN_RTC_SET_TIME_HOUR_LSB
-#define RTC_SET_TIME_HOUR_MASK WLAN_RTC_SET_TIME_HOUR_MASK
-#define RTC_SET_TIME_HOUR_GET(x) WLAN_RTC_SET_TIME_HOUR_GET(x)
-#define RTC_SET_TIME_HOUR_SET(x) WLAN_RTC_SET_TIME_HOUR_SET(x)
-#define RTC_SET_TIME_MINUTE_MSB WLAN_RTC_SET_TIME_MINUTE_MSB
-#define RTC_SET_TIME_MINUTE_LSB WLAN_RTC_SET_TIME_MINUTE_LSB
-#define RTC_SET_TIME_MINUTE_MASK WLAN_RTC_SET_TIME_MINUTE_MASK
-#define RTC_SET_TIME_MINUTE_GET(x) WLAN_RTC_SET_TIME_MINUTE_GET(x)
-#define RTC_SET_TIME_MINUTE_SET(x) WLAN_RTC_SET_TIME_MINUTE_SET(x)
-#define RTC_SET_TIME_SECOND_MSB WLAN_RTC_SET_TIME_SECOND_MSB
-#define RTC_SET_TIME_SECOND_LSB WLAN_RTC_SET_TIME_SECOND_LSB
-#define RTC_SET_TIME_SECOND_MASK WLAN_RTC_SET_TIME_SECOND_MASK
-#define RTC_SET_TIME_SECOND_GET(x) WLAN_RTC_SET_TIME_SECOND_GET(x)
-#define RTC_SET_TIME_SECOND_SET(x) WLAN_RTC_SET_TIME_SECOND_SET(x)
-#define RTC_SET_DATE_ADDRESS WLAN_RTC_SET_DATE_ADDRESS
-#define RTC_SET_DATE_OFFSET WLAN_RTC_SET_DATE_OFFSET
-#define RTC_SET_DATE_YEAR_MSB WLAN_RTC_SET_DATE_YEAR_MSB
-#define RTC_SET_DATE_YEAR_LSB WLAN_RTC_SET_DATE_YEAR_LSB
-#define RTC_SET_DATE_YEAR_MASK WLAN_RTC_SET_DATE_YEAR_MASK
-#define RTC_SET_DATE_YEAR_GET(x) WLAN_RTC_SET_DATE_YEAR_GET(x)
-#define RTC_SET_DATE_YEAR_SET(x) WLAN_RTC_SET_DATE_YEAR_SET(x)
-#define RTC_SET_DATE_MONTH_MSB WLAN_RTC_SET_DATE_MONTH_MSB
-#define RTC_SET_DATE_MONTH_LSB WLAN_RTC_SET_DATE_MONTH_LSB
-#define RTC_SET_DATE_MONTH_MASK WLAN_RTC_SET_DATE_MONTH_MASK
-#define RTC_SET_DATE_MONTH_GET(x) WLAN_RTC_SET_DATE_MONTH_GET(x)
-#define RTC_SET_DATE_MONTH_SET(x) WLAN_RTC_SET_DATE_MONTH_SET(x)
-#define RTC_SET_DATE_MONTH_DAY_MSB WLAN_RTC_SET_DATE_MONTH_DAY_MSB
-#define RTC_SET_DATE_MONTH_DAY_LSB WLAN_RTC_SET_DATE_MONTH_DAY_LSB
-#define RTC_SET_DATE_MONTH_DAY_MASK WLAN_RTC_SET_DATE_MONTH_DAY_MASK
-#define RTC_SET_DATE_MONTH_DAY_GET(x) WLAN_RTC_SET_DATE_MONTH_DAY_GET(x)
-#define RTC_SET_DATE_MONTH_DAY_SET(x) WLAN_RTC_SET_DATE_MONTH_DAY_SET(x)
-#define RTC_SET_ALARM_ADDRESS WLAN_RTC_SET_ALARM_ADDRESS
-#define RTC_SET_ALARM_OFFSET WLAN_RTC_SET_ALARM_OFFSET
-#define RTC_SET_ALARM_HOUR_MSB WLAN_RTC_SET_ALARM_HOUR_MSB
-#define RTC_SET_ALARM_HOUR_LSB WLAN_RTC_SET_ALARM_HOUR_LSB
-#define RTC_SET_ALARM_HOUR_MASK WLAN_RTC_SET_ALARM_HOUR_MASK
-#define RTC_SET_ALARM_HOUR_GET(x) WLAN_RTC_SET_ALARM_HOUR_GET(x)
-#define RTC_SET_ALARM_HOUR_SET(x) WLAN_RTC_SET_ALARM_HOUR_SET(x)
-#define RTC_SET_ALARM_MINUTE_MSB WLAN_RTC_SET_ALARM_MINUTE_MSB
-#define RTC_SET_ALARM_MINUTE_LSB WLAN_RTC_SET_ALARM_MINUTE_LSB
-#define RTC_SET_ALARM_MINUTE_MASK WLAN_RTC_SET_ALARM_MINUTE_MASK
-#define RTC_SET_ALARM_MINUTE_GET(x) WLAN_RTC_SET_ALARM_MINUTE_GET(x)
-#define RTC_SET_ALARM_MINUTE_SET(x) WLAN_RTC_SET_ALARM_MINUTE_SET(x)
-#define RTC_SET_ALARM_SECOND_MSB WLAN_RTC_SET_ALARM_SECOND_MSB
-#define RTC_SET_ALARM_SECOND_LSB WLAN_RTC_SET_ALARM_SECOND_LSB
-#define RTC_SET_ALARM_SECOND_MASK WLAN_RTC_SET_ALARM_SECOND_MASK
-#define RTC_SET_ALARM_SECOND_GET(x) WLAN_RTC_SET_ALARM_SECOND_GET(x)
-#define RTC_SET_ALARM_SECOND_SET(x) WLAN_RTC_SET_ALARM_SECOND_SET(x)
-#define RTC_CONFIG_ADDRESS WLAN_RTC_CONFIG_ADDRESS
-#define RTC_CONFIG_OFFSET WLAN_RTC_CONFIG_OFFSET
-#define RTC_CONFIG_BCD_MSB WLAN_RTC_CONFIG_BCD_MSB
-#define RTC_CONFIG_BCD_LSB WLAN_RTC_CONFIG_BCD_LSB
-#define RTC_CONFIG_BCD_MASK WLAN_RTC_CONFIG_BCD_MASK
-#define RTC_CONFIG_BCD_GET(x) WLAN_RTC_CONFIG_BCD_GET(x)
-#define RTC_CONFIG_BCD_SET(x) WLAN_RTC_CONFIG_BCD_SET(x)
-#define RTC_CONFIG_TWELVE_HOUR_MSB WLAN_RTC_CONFIG_TWELVE_HOUR_MSB
-#define RTC_CONFIG_TWELVE_HOUR_LSB WLAN_RTC_CONFIG_TWELVE_HOUR_LSB
-#define RTC_CONFIG_TWELVE_HOUR_MASK WLAN_RTC_CONFIG_TWELVE_HOUR_MASK
-#define RTC_CONFIG_TWELVE_HOUR_GET(x) WLAN_RTC_CONFIG_TWELVE_HOUR_GET(x)
-#define RTC_CONFIG_TWELVE_HOUR_SET(x) WLAN_RTC_CONFIG_TWELVE_HOUR_SET(x)
-#define RTC_CONFIG_DSE_MSB WLAN_RTC_CONFIG_DSE_MSB
-#define RTC_CONFIG_DSE_LSB WLAN_RTC_CONFIG_DSE_LSB
-#define RTC_CONFIG_DSE_MASK WLAN_RTC_CONFIG_DSE_MASK
-#define RTC_CONFIG_DSE_GET(x) WLAN_RTC_CONFIG_DSE_GET(x)
-#define RTC_CONFIG_DSE_SET(x) WLAN_RTC_CONFIG_DSE_SET(x)
-#define RTC_ALARM_STATUS_ADDRESS WLAN_RTC_ALARM_STATUS_ADDRESS
-#define RTC_ALARM_STATUS_OFFSET WLAN_RTC_ALARM_STATUS_OFFSET
-#define RTC_ALARM_STATUS_ENABLE_MSB WLAN_RTC_ALARM_STATUS_ENABLE_MSB
-#define RTC_ALARM_STATUS_ENABLE_LSB WLAN_RTC_ALARM_STATUS_ENABLE_LSB
-#define RTC_ALARM_STATUS_ENABLE_MASK WLAN_RTC_ALARM_STATUS_ENABLE_MASK
-#define RTC_ALARM_STATUS_ENABLE_GET(x) WLAN_RTC_ALARM_STATUS_ENABLE_GET(x)
-#define RTC_ALARM_STATUS_ENABLE_SET(x) WLAN_RTC_ALARM_STATUS_ENABLE_SET(x)
-#define RTC_ALARM_STATUS_INTERRUPT_MSB WLAN_RTC_ALARM_STATUS_INTERRUPT_MSB
-#define RTC_ALARM_STATUS_INTERRUPT_LSB WLAN_RTC_ALARM_STATUS_INTERRUPT_LSB
-#define RTC_ALARM_STATUS_INTERRUPT_MASK WLAN_RTC_ALARM_STATUS_INTERRUPT_MASK
-#define RTC_ALARM_STATUS_INTERRUPT_GET(x) WLAN_RTC_ALARM_STATUS_INTERRUPT_GET(x)
-#define RTC_ALARM_STATUS_INTERRUPT_SET(x) WLAN_RTC_ALARM_STATUS_INTERRUPT_SET(x)
-#define UART_WAKEUP_ADDRESS WLAN_UART_WAKEUP_ADDRESS
-#define UART_WAKEUP_OFFSET WLAN_UART_WAKEUP_OFFSET
-#define UART_WAKEUP_ENABLE_MSB WLAN_UART_WAKEUP_ENABLE_MSB
-#define UART_WAKEUP_ENABLE_LSB WLAN_UART_WAKEUP_ENABLE_LSB
-#define UART_WAKEUP_ENABLE_MASK WLAN_UART_WAKEUP_ENABLE_MASK
-#define UART_WAKEUP_ENABLE_GET(x) WLAN_UART_WAKEUP_ENABLE_GET(x)
-#define UART_WAKEUP_ENABLE_SET(x) WLAN_UART_WAKEUP_ENABLE_SET(x)
 #define RESET_CAUSE_ADDRESS WLAN_RESET_CAUSE_ADDRESS
 #define RESET_CAUSE_OFFSET WLAN_RESET_CAUSE_OFFSET
 #define RESET_CAUSE_LAST_MSB WLAN_RESET_CAUSE_LAST_MSB
@@ -753,49 +157,6 @@
 #define SYSTEM_SLEEP_DISABLE_MASK WLAN_SYSTEM_SLEEP_DISABLE_MASK
 #define SYSTEM_SLEEP_DISABLE_GET(x) WLAN_SYSTEM_SLEEP_DISABLE_GET(x)
 #define SYSTEM_SLEEP_DISABLE_SET(x) WLAN_SYSTEM_SLEEP_DISABLE_SET(x)
-#define SDIO_WRAPPER_ADDRESS WLAN_SDIO_WRAPPER_ADDRESS
-#define SDIO_WRAPPER_OFFSET WLAN_SDIO_WRAPPER_OFFSET
-#define SDIO_WRAPPER_SLEEP_MSB WLAN_SDIO_WRAPPER_SLEEP_MSB
-#define SDIO_WRAPPER_SLEEP_LSB WLAN_SDIO_WRAPPER_SLEEP_LSB
-#define SDIO_WRAPPER_SLEEP_MASK WLAN_SDIO_WRAPPER_SLEEP_MASK
-#define SDIO_WRAPPER_SLEEP_GET(x) WLAN_SDIO_WRAPPER_SLEEP_GET(x)
-#define SDIO_WRAPPER_SLEEP_SET(x) WLAN_SDIO_WRAPPER_SLEEP_SET(x)
-#define SDIO_WRAPPER_WAKEUP_MSB WLAN_SDIO_WRAPPER_WAKEUP_MSB
-#define SDIO_WRAPPER_WAKEUP_LSB WLAN_SDIO_WRAPPER_WAKEUP_LSB
-#define SDIO_WRAPPER_WAKEUP_MASK WLAN_SDIO_WRAPPER_WAKEUP_MASK
-#define SDIO_WRAPPER_WAKEUP_GET(x) WLAN_SDIO_WRAPPER_WAKEUP_GET(x)
-#define SDIO_WRAPPER_WAKEUP_SET(x) WLAN_SDIO_WRAPPER_WAKEUP_SET(x)
-#define SDIO_WRAPPER_SOC_ON_MSB WLAN_SDIO_WRAPPER_SOC_ON_MSB
-#define SDIO_WRAPPER_SOC_ON_LSB WLAN_SDIO_WRAPPER_SOC_ON_LSB
-#define SDIO_WRAPPER_SOC_ON_MASK WLAN_SDIO_WRAPPER_SOC_ON_MASK
-#define SDIO_WRAPPER_SOC_ON_GET(x) WLAN_SDIO_WRAPPER_SOC_ON_GET(x)
-#define SDIO_WRAPPER_SOC_ON_SET(x) WLAN_SDIO_WRAPPER_SOC_ON_SET(x)
-#define SDIO_WRAPPER_ON_MSB WLAN_SDIO_WRAPPER_ON_MSB
-#define SDIO_WRAPPER_ON_LSB WLAN_SDIO_WRAPPER_ON_LSB
-#define SDIO_WRAPPER_ON_MASK WLAN_SDIO_WRAPPER_ON_MASK
-#define SDIO_WRAPPER_ON_GET(x) WLAN_SDIO_WRAPPER_ON_GET(x)
-#define SDIO_WRAPPER_ON_SET(x) WLAN_SDIO_WRAPPER_ON_SET(x)
-#define MAC_SLEEP_CONTROL_ADDRESS WLAN_MAC_SLEEP_CONTROL_ADDRESS
-#define MAC_SLEEP_CONTROL_OFFSET WLAN_MAC_SLEEP_CONTROL_OFFSET
-#define MAC_SLEEP_CONTROL_ENABLE_MSB WLAN_MAC_SLEEP_CONTROL_ENABLE_MSB
-#define MAC_SLEEP_CONTROL_ENABLE_LSB WLAN_MAC_SLEEP_CONTROL_ENABLE_LSB
-#define MAC_SLEEP_CONTROL_ENABLE_MASK WLAN_MAC_SLEEP_CONTROL_ENABLE_MASK
-#define MAC_SLEEP_CONTROL_ENABLE_GET(x) WLAN_MAC_SLEEP_CONTROL_ENABLE_GET(x)
-#define MAC_SLEEP_CONTROL_ENABLE_SET(x) WLAN_MAC_SLEEP_CONTROL_ENABLE_SET(x)
-#define KEEP_AWAKE_ADDRESS WLAN_KEEP_AWAKE_ADDRESS
-#define KEEP_AWAKE_OFFSET WLAN_KEEP_AWAKE_OFFSET
-#define KEEP_AWAKE_COUNT_MSB WLAN_KEEP_AWAKE_COUNT_MSB
-#define KEEP_AWAKE_COUNT_LSB WLAN_KEEP_AWAKE_COUNT_LSB
-#define KEEP_AWAKE_COUNT_MASK WLAN_KEEP_AWAKE_COUNT_MASK
-#define KEEP_AWAKE_COUNT_GET(x) WLAN_KEEP_AWAKE_COUNT_GET(x)
-#define KEEP_AWAKE_COUNT_SET(x) WLAN_KEEP_AWAKE_COUNT_SET(x)
-#define LPO_CAL_TIME_ADDRESS WLAN_LPO_CAL_TIME_ADDRESS
-#define LPO_CAL_TIME_OFFSET WLAN_LPO_CAL_TIME_OFFSET
-#define LPO_CAL_TIME_LENGTH_MSB WLAN_LPO_CAL_TIME_LENGTH_MSB
-#define LPO_CAL_TIME_LENGTH_LSB WLAN_LPO_CAL_TIME_LENGTH_LSB
-#define LPO_CAL_TIME_LENGTH_MASK WLAN_LPO_CAL_TIME_LENGTH_MASK
-#define LPO_CAL_TIME_LENGTH_GET(x) WLAN_LPO_CAL_TIME_LENGTH_GET(x)
-#define LPO_CAL_TIME_LENGTH_SET(x) WLAN_LPO_CAL_TIME_LENGTH_SET(x)
 #define LPO_INIT_DIVIDEND_INT_ADDRESS WLAN_LPO_INIT_DIVIDEND_INT_ADDRESS
 #define LPO_INIT_DIVIDEND_INT_OFFSET WLAN_LPO_INIT_DIVIDEND_INT_OFFSET
 #define LPO_INIT_DIVIDEND_INT_VALUE_MSB WLAN_LPO_INIT_DIVIDEND_INT_VALUE_MSB
@@ -822,154 +183,5 @@
 #define LPO_CAL_COUNT_MASK WLAN_LPO_CAL_COUNT_MASK
 #define LPO_CAL_COUNT_GET(x) WLAN_LPO_CAL_COUNT_GET(x)
 #define LPO_CAL_COUNT_SET(x) WLAN_LPO_CAL_COUNT_SET(x)
-#define LPO_CAL_TEST_CONTROL_ADDRESS WLAN_LPO_CAL_TEST_CONTROL_ADDRESS
-#define LPO_CAL_TEST_CONTROL_OFFSET WLAN_LPO_CAL_TEST_CONTROL_OFFSET
-#define LPO_CAL_TEST_CONTROL_ENABLE_MSB WLAN_LPO_CAL_TEST_CONTROL_ENABLE_MSB
-#define LPO_CAL_TEST_CONTROL_ENABLE_LSB WLAN_LPO_CAL_TEST_CONTROL_ENABLE_LSB
-#define LPO_CAL_TEST_CONTROL_ENABLE_MASK WLAN_LPO_CAL_TEST_CONTROL_ENABLE_MASK
-#define LPO_CAL_TEST_CONTROL_ENABLE_GET(x) WLAN_LPO_CAL_TEST_CONTROL_ENABLE_GET(x)
-#define LPO_CAL_TEST_CONTROL_ENABLE_SET(x) WLAN_LPO_CAL_TEST_CONTROL_ENABLE_SET(x)
-#define LPO_CAL_TEST_CONTROL_RTC_CYCLES_MSB WLAN_LPO_CAL_TEST_CONTROL_RTC_CYCLES_MSB
-#define LPO_CAL_TEST_CONTROL_RTC_CYCLES_LSB WLAN_LPO_CAL_TEST_CONTROL_RTC_CYCLES_LSB
-#define LPO_CAL_TEST_CONTROL_RTC_CYCLES_MASK WLAN_LPO_CAL_TEST_CONTROL_RTC_CYCLES_MASK
-#define LPO_CAL_TEST_CONTROL_RTC_CYCLES_GET(x) WLAN_LPO_CAL_TEST_CONTROL_RTC_CYCLES_GET(x)
-#define LPO_CAL_TEST_CONTROL_RTC_CYCLES_SET(x) WLAN_LPO_CAL_TEST_CONTROL_RTC_CYCLES_SET(x)
-#define LPO_CAL_TEST_STATUS_ADDRESS WLAN_LPO_CAL_TEST_STATUS_ADDRESS
-#define LPO_CAL_TEST_STATUS_OFFSET WLAN_LPO_CAL_TEST_STATUS_OFFSET
-#define LPO_CAL_TEST_STATUS_READY_MSB WLAN_LPO_CAL_TEST_STATUS_READY_MSB
-#define LPO_CAL_TEST_STATUS_READY_LSB WLAN_LPO_CAL_TEST_STATUS_READY_LSB
-#define LPO_CAL_TEST_STATUS_READY_MASK WLAN_LPO_CAL_TEST_STATUS_READY_MASK
-#define LPO_CAL_TEST_STATUS_READY_GET(x) WLAN_LPO_CAL_TEST_STATUS_READY_GET(x)
-#define LPO_CAL_TEST_STATUS_READY_SET(x) WLAN_LPO_CAL_TEST_STATUS_READY_SET(x)
-#define LPO_CAL_TEST_STATUS_COUNT_MSB WLAN_LPO_CAL_TEST_STATUS_COUNT_MSB
-#define LPO_CAL_TEST_STATUS_COUNT_LSB WLAN_LPO_CAL_TEST_STATUS_COUNT_LSB
-#define LPO_CAL_TEST_STATUS_COUNT_MASK WLAN_LPO_CAL_TEST_STATUS_COUNT_MASK
-#define LPO_CAL_TEST_STATUS_COUNT_GET(x) WLAN_LPO_CAL_TEST_STATUS_COUNT_GET(x)
-#define LPO_CAL_TEST_STATUS_COUNT_SET(x) WLAN_LPO_CAL_TEST_STATUS_COUNT_SET(x)
-#define CHIP_ID_ADDRESS WLAN_CHIP_ID_ADDRESS
-#define CHIP_ID_OFFSET WLAN_CHIP_ID_OFFSET
-#define CHIP_ID_DEVICE_ID_MSB WLAN_CHIP_ID_DEVICE_ID_MSB
-#define CHIP_ID_DEVICE_ID_LSB WLAN_CHIP_ID_DEVICE_ID_LSB
-#define CHIP_ID_DEVICE_ID_MASK WLAN_CHIP_ID_DEVICE_ID_MASK
-#define CHIP_ID_DEVICE_ID_GET(x) WLAN_CHIP_ID_DEVICE_ID_GET(x)
-#define CHIP_ID_DEVICE_ID_SET(x) WLAN_CHIP_ID_DEVICE_ID_SET(x)
-#define CHIP_ID_CONFIG_ID_MSB WLAN_CHIP_ID_CONFIG_ID_MSB
-#define CHIP_ID_CONFIG_ID_LSB WLAN_CHIP_ID_CONFIG_ID_LSB
-#define CHIP_ID_CONFIG_ID_MASK WLAN_CHIP_ID_CONFIG_ID_MASK
-#define CHIP_ID_CONFIG_ID_GET(x) WLAN_CHIP_ID_CONFIG_ID_GET(x)
-#define CHIP_ID_CONFIG_ID_SET(x) WLAN_CHIP_ID_CONFIG_ID_SET(x)
-#define CHIP_ID_VERSION_ID_MSB WLAN_CHIP_ID_VERSION_ID_MSB
-#define CHIP_ID_VERSION_ID_LSB WLAN_CHIP_ID_VERSION_ID_LSB
-#define CHIP_ID_VERSION_ID_MASK WLAN_CHIP_ID_VERSION_ID_MASK
-#define CHIP_ID_VERSION_ID_GET(x) WLAN_CHIP_ID_VERSION_ID_GET(x)
-#define CHIP_ID_VERSION_ID_SET(x) WLAN_CHIP_ID_VERSION_ID_SET(x)
-#define DERIVED_RTC_CLK_ADDRESS WLAN_DERIVED_RTC_CLK_ADDRESS
-#define DERIVED_RTC_CLK_OFFSET WLAN_DERIVED_RTC_CLK_OFFSET
-#define DERIVED_RTC_CLK_EXTERNAL_DETECT_EN_MSB WLAN_DERIVED_RTC_CLK_EXTERNAL_DETECT_EN_MSB
-#define DERIVED_RTC_CLK_EXTERNAL_DETECT_EN_LSB WLAN_DERIVED_RTC_CLK_EXTERNAL_DETECT_EN_LSB
-#define DERIVED_RTC_CLK_EXTERNAL_DETECT_EN_MASK WLAN_DERIVED_RTC_CLK_EXTERNAL_DETECT_EN_MASK
-#define DERIVED_RTC_CLK_EXTERNAL_DETECT_EN_GET(x) WLAN_DERIVED_RTC_CLK_EXTERNAL_DETECT_EN_GET(x)
-#define DERIVED_RTC_CLK_EXTERNAL_DETECT_EN_SET(x) WLAN_DERIVED_RTC_CLK_EXTERNAL_DETECT_EN_SET(x)
-#define DERIVED_RTC_CLK_EXTERNAL_DETECT_MSB WLAN_DERIVED_RTC_CLK_EXTERNAL_DETECT_MSB
-#define DERIVED_RTC_CLK_EXTERNAL_DETECT_LSB WLAN_DERIVED_RTC_CLK_EXTERNAL_DETECT_LSB
-#define DERIVED_RTC_CLK_EXTERNAL_DETECT_MASK WLAN_DERIVED_RTC_CLK_EXTERNAL_DETECT_MASK
-#define DERIVED_RTC_CLK_EXTERNAL_DETECT_GET(x) WLAN_DERIVED_RTC_CLK_EXTERNAL_DETECT_GET(x)
-#define DERIVED_RTC_CLK_EXTERNAL_DETECT_SET(x) WLAN_DERIVED_RTC_CLK_EXTERNAL_DETECT_SET(x)
-#define DERIVED_RTC_CLK_FORCE_MSB WLAN_DERIVED_RTC_CLK_FORCE_MSB
-#define DERIVED_RTC_CLK_FORCE_LSB WLAN_DERIVED_RTC_CLK_FORCE_LSB
-#define DERIVED_RTC_CLK_FORCE_MASK WLAN_DERIVED_RTC_CLK_FORCE_MASK
-#define DERIVED_RTC_CLK_FORCE_GET(x) WLAN_DERIVED_RTC_CLK_FORCE_GET(x)
-#define DERIVED_RTC_CLK_FORCE_SET(x) WLAN_DERIVED_RTC_CLK_FORCE_SET(x)
-#define DERIVED_RTC_CLK_PERIOD_MSB WLAN_DERIVED_RTC_CLK_PERIOD_MSB
-#define DERIVED_RTC_CLK_PERIOD_LSB WLAN_DERIVED_RTC_CLK_PERIOD_LSB
-#define DERIVED_RTC_CLK_PERIOD_MASK WLAN_DERIVED_RTC_CLK_PERIOD_MASK
-#define DERIVED_RTC_CLK_PERIOD_GET(x) WLAN_DERIVED_RTC_CLK_PERIOD_GET(x)
-#define DERIVED_RTC_CLK_PERIOD_SET(x) WLAN_DERIVED_RTC_CLK_PERIOD_SET(x)
-#define POWER_REG_ADDRESS WLAN_POWER_REG_ADDRESS
-#define POWER_REG_OFFSET WLAN_POWER_REG_OFFSET
-#define POWER_REG_SLEEP_MAKE_N_BREAK_EN_MSB WLAN_POWER_REG_SLEEP_MAKE_N_BREAK_EN_MSB
-#define POWER_REG_SLEEP_MAKE_N_BREAK_EN_LSB WLAN_POWER_REG_SLEEP_MAKE_N_BREAK_EN_LSB
-#define POWER_REG_SLEEP_MAKE_N_BREAK_EN_MASK WLAN_POWER_REG_SLEEP_MAKE_N_BREAK_EN_MASK
-#define POWER_REG_SLEEP_MAKE_N_BREAK_EN_GET(x) WLAN_POWER_REG_SLEEP_MAKE_N_BREAK_EN_GET(x)
-#define POWER_REG_SLEEP_MAKE_N_BREAK_EN_SET(x) WLAN_POWER_REG_SLEEP_MAKE_N_BREAK_EN_SET(x)
-#define POWER_REG_DEBUG_EN_MSB WLAN_POWER_REG_DEBUG_EN_MSB
-#define POWER_REG_DEBUG_EN_LSB WLAN_POWER_REG_DEBUG_EN_LSB
-#define POWER_REG_DEBUG_EN_MASK WLAN_POWER_REG_DEBUG_EN_MASK
-#define POWER_REG_DEBUG_EN_GET(x) WLAN_POWER_REG_DEBUG_EN_GET(x)
-#define POWER_REG_DEBUG_EN_SET(x) WLAN_POWER_REG_DEBUG_EN_SET(x)
-#define POWER_REG_WLAN_BB_PWD_EN_MSB WLAN_POWER_REG_WLAN_BB_PWD_EN_MSB
-#define POWER_REG_WLAN_BB_PWD_EN_LSB WLAN_POWER_REG_WLAN_BB_PWD_EN_LSB
-#define POWER_REG_WLAN_BB_PWD_EN_MASK WLAN_POWER_REG_WLAN_BB_PWD_EN_MASK
-#define POWER_REG_WLAN_BB_PWD_EN_GET(x) WLAN_POWER_REG_WLAN_BB_PWD_EN_GET(x)
-#define POWER_REG_WLAN_BB_PWD_EN_SET(x) WLAN_POWER_REG_WLAN_BB_PWD_EN_SET(x)
-#define POWER_REG_WLAN_MAC_PWD_EN_MSB WLAN_POWER_REG_WLAN_MAC_PWD_EN_MSB
-#define POWER_REG_WLAN_MAC_PWD_EN_LSB WLAN_POWER_REG_WLAN_MAC_PWD_EN_LSB
-#define POWER_REG_WLAN_MAC_PWD_EN_MASK WLAN_POWER_REG_WLAN_MAC_PWD_EN_MASK
-#define POWER_REG_WLAN_MAC_PWD_EN_GET(x) WLAN_POWER_REG_WLAN_MAC_PWD_EN_GET(x)
-#define POWER_REG_WLAN_MAC_PWD_EN_SET(x) WLAN_POWER_REG_WLAN_MAC_PWD_EN_SET(x)
-#define POWER_REG_VLVL_MSB WLAN_POWER_REG_VLVL_MSB
-#define POWER_REG_VLVL_LSB WLAN_POWER_REG_VLVL_LSB
-#define POWER_REG_VLVL_MASK WLAN_POWER_REG_VLVL_MASK
-#define POWER_REG_VLVL_GET(x) WLAN_POWER_REG_VLVL_GET(x)
-#define POWER_REG_VLVL_SET(x) WLAN_POWER_REG_VLVL_SET(x)
-#define POWER_REG_CPU_INT_ENABLE_MSB WLAN_POWER_REG_CPU_INT_ENABLE_MSB
-#define POWER_REG_CPU_INT_ENABLE_LSB WLAN_POWER_REG_CPU_INT_ENABLE_LSB
-#define POWER_REG_CPU_INT_ENABLE_MASK WLAN_POWER_REG_CPU_INT_ENABLE_MASK
-#define POWER_REG_CPU_INT_ENABLE_GET(x) WLAN_POWER_REG_CPU_INT_ENABLE_GET(x)
-#define POWER_REG_CPU_INT_ENABLE_SET(x) WLAN_POWER_REG_CPU_INT_ENABLE_SET(x)
-#define POWER_REG_WLAN_ISO_DIS_MSB WLAN_POWER_REG_WLAN_ISO_DIS_MSB
-#define POWER_REG_WLAN_ISO_DIS_LSB WLAN_POWER_REG_WLAN_ISO_DIS_LSB
-#define POWER_REG_WLAN_ISO_DIS_MASK WLAN_POWER_REG_WLAN_ISO_DIS_MASK
-#define POWER_REG_WLAN_ISO_DIS_GET(x) WLAN_POWER_REG_WLAN_ISO_DIS_GET(x)
-#define POWER_REG_WLAN_ISO_DIS_SET(x) WLAN_POWER_REG_WLAN_ISO_DIS_SET(x)
-#define POWER_REG_WLAN_ISO_CNTL_MSB WLAN_POWER_REG_WLAN_ISO_CNTL_MSB
-#define POWER_REG_WLAN_ISO_CNTL_LSB WLAN_POWER_REG_WLAN_ISO_CNTL_LSB
-#define POWER_REG_WLAN_ISO_CNTL_MASK WLAN_POWER_REG_WLAN_ISO_CNTL_MASK
-#define POWER_REG_WLAN_ISO_CNTL_GET(x) WLAN_POWER_REG_WLAN_ISO_CNTL_GET(x)
-#define POWER_REG_WLAN_ISO_CNTL_SET(x) WLAN_POWER_REG_WLAN_ISO_CNTL_SET(x)
-#define POWER_REG_RADIO_PWD_EN_MSB WLAN_POWER_REG_RADIO_PWD_EN_MSB
-#define POWER_REG_RADIO_PWD_EN_LSB WLAN_POWER_REG_RADIO_PWD_EN_LSB
-#define POWER_REG_RADIO_PWD_EN_MASK WLAN_POWER_REG_RADIO_PWD_EN_MASK
-#define POWER_REG_RADIO_PWD_EN_GET(x) WLAN_POWER_REG_RADIO_PWD_EN_GET(x)
-#define POWER_REG_RADIO_PWD_EN_SET(x) WLAN_POWER_REG_RADIO_PWD_EN_SET(x)
-#define POWER_REG_SOC_ISO_EN_MSB WLAN_POWER_REG_SOC_ISO_EN_MSB
-#define POWER_REG_SOC_ISO_EN_LSB WLAN_POWER_REG_SOC_ISO_EN_LSB
-#define POWER_REG_SOC_ISO_EN_MASK WLAN_POWER_REG_SOC_ISO_EN_MASK
-#define POWER_REG_SOC_ISO_EN_GET(x) WLAN_POWER_REG_SOC_ISO_EN_GET(x)
-#define POWER_REG_SOC_ISO_EN_SET(x) WLAN_POWER_REG_SOC_ISO_EN_SET(x)
-#define POWER_REG_WLAN_ISO_EN_MSB WLAN_POWER_REG_WLAN_ISO_EN_MSB
-#define POWER_REG_WLAN_ISO_EN_LSB WLAN_POWER_REG_WLAN_ISO_EN_LSB
-#define POWER_REG_WLAN_ISO_EN_MASK WLAN_POWER_REG_WLAN_ISO_EN_MASK
-#define POWER_REG_WLAN_ISO_EN_GET(x) WLAN_POWER_REG_WLAN_ISO_EN_GET(x)
-#define POWER_REG_WLAN_ISO_EN_SET(x) WLAN_POWER_REG_WLAN_ISO_EN_SET(x)
-#define POWER_REG_WLAN_PWD_EN_MSB WLAN_POWER_REG_WLAN_PWD_EN_MSB
-#define POWER_REG_WLAN_PWD_EN_LSB WLAN_POWER_REG_WLAN_PWD_EN_LSB
-#define POWER_REG_WLAN_PWD_EN_MASK WLAN_POWER_REG_WLAN_PWD_EN_MASK
-#define POWER_REG_WLAN_PWD_EN_GET(x) WLAN_POWER_REG_WLAN_PWD_EN_GET(x)
-#define POWER_REG_WLAN_PWD_EN_SET(x) WLAN_POWER_REG_WLAN_PWD_EN_SET(x)
-#define POWER_REG_POWER_EN_MSB WLAN_POWER_REG_POWER_EN_MSB
-#define POWER_REG_POWER_EN_LSB WLAN_POWER_REG_POWER_EN_LSB
-#define POWER_REG_POWER_EN_MASK WLAN_POWER_REG_POWER_EN_MASK
-#define POWER_REG_POWER_EN_GET(x) WLAN_POWER_REG_POWER_EN_GET(x)
-#define POWER_REG_POWER_EN_SET(x) WLAN_POWER_REG_POWER_EN_SET(x)
-#define CORE_CLK_CTRL_ADDRESS WLAN_CORE_CLK_CTRL_ADDRESS
-#define CORE_CLK_CTRL_OFFSET WLAN_CORE_CLK_CTRL_OFFSET
-#define CORE_CLK_CTRL_DIV_MSB WLAN_CORE_CLK_CTRL_DIV_MSB
-#define CORE_CLK_CTRL_DIV_LSB WLAN_CORE_CLK_CTRL_DIV_LSB
-#define CORE_CLK_CTRL_DIV_MASK WLAN_CORE_CLK_CTRL_DIV_MASK
-#define CORE_CLK_CTRL_DIV_GET(x) WLAN_CORE_CLK_CTRL_DIV_GET(x)
-#define CORE_CLK_CTRL_DIV_SET(x) WLAN_CORE_CLK_CTRL_DIV_SET(x)
-#define GPIO_WAKEUP_CONTROL_ADDRESS WLAN_GPIO_WAKEUP_CONTROL_ADDRESS
-#define GPIO_WAKEUP_CONTROL_OFFSET WLAN_GPIO_WAKEUP_CONTROL_OFFSET
-#define GPIO_WAKEUP_CONTROL_ENABLE_MSB WLAN_GPIO_WAKEUP_CONTROL_ENABLE_MSB
-#define GPIO_WAKEUP_CONTROL_ENABLE_LSB WLAN_GPIO_WAKEUP_CONTROL_ENABLE_LSB
-#define GPIO_WAKEUP_CONTROL_ENABLE_MASK WLAN_GPIO_WAKEUP_CONTROL_ENABLE_MASK
-#define GPIO_WAKEUP_CONTROL_ENABLE_GET(x) WLAN_GPIO_WAKEUP_CONTROL_ENABLE_GET(x)
-#define GPIO_WAKEUP_CONTROL_ENABLE_SET(x) WLAN_GPIO_WAKEUP_CONTROL_ENABLE_SET(x)
-
 
 #endif
-#endif
-
-
-
diff -druN linux-2.6.39-libre/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/rtc_wlan_reg.h linux-3.0-rc7-libre/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/rtc_wlan_reg.h
--- linux-2.6.39-libre/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/rtc_wlan_reg.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/rtc_wlan_reg.h	2011-07-11 19:51:52.000000000 -0400
@@ -97,102 +97,6 @@
 #define WLAN_RESET_CONTROL_SI0_RST_GET(x)        (((x) & WLAN_RESET_CONTROL_SI0_RST_MASK) >> WLAN_RESET_CONTROL_SI0_RST_LSB)
 #define WLAN_RESET_CONTROL_SI0_RST_SET(x)        (((x) << WLAN_RESET_CONTROL_SI0_RST_LSB) & WLAN_RESET_CONTROL_SI0_RST_MASK)
 
-#define WLAN_XTAL_CONTROL_ADDRESS                0x00000004
-#define WLAN_XTAL_CONTROL_OFFSET                 0x00000004
-#define WLAN_XTAL_CONTROL_TCXO_MSB               0
-#define WLAN_XTAL_CONTROL_TCXO_LSB               0
-#define WLAN_XTAL_CONTROL_TCXO_MASK              0x00000001
-#define WLAN_XTAL_CONTROL_TCXO_GET(x)            (((x) & WLAN_XTAL_CONTROL_TCXO_MASK) >> WLAN_XTAL_CONTROL_TCXO_LSB)
-#define WLAN_XTAL_CONTROL_TCXO_SET(x)            (((x) << WLAN_XTAL_CONTROL_TCXO_LSB) & WLAN_XTAL_CONTROL_TCXO_MASK)
-
-#define WLAN_TCXO_DETECT_ADDRESS                 0x00000008
-#define WLAN_TCXO_DETECT_OFFSET                  0x00000008
-#define WLAN_TCXO_DETECT_PRESENT_MSB             0
-#define WLAN_TCXO_DETECT_PRESENT_LSB             0
-#define WLAN_TCXO_DETECT_PRESENT_MASK            0x00000001
-#define WLAN_TCXO_DETECT_PRESENT_GET(x)          (((x) & WLAN_TCXO_DETECT_PRESENT_MASK) >> WLAN_TCXO_DETECT_PRESENT_LSB)
-#define WLAN_TCXO_DETECT_PRESENT_SET(x)          (((x) << WLAN_TCXO_DETECT_PRESENT_LSB) & WLAN_TCXO_DETECT_PRESENT_MASK)
-
-#define WLAN_XTAL_TEST_ADDRESS                   0x0000000c
-#define WLAN_XTAL_TEST_OFFSET                    0x0000000c
-#define WLAN_XTAL_TEST_NOTCXODET_MSB             0
-#define WLAN_XTAL_TEST_NOTCXODET_LSB             0
-#define WLAN_XTAL_TEST_NOTCXODET_MASK            0x00000001
-#define WLAN_XTAL_TEST_NOTCXODET_GET(x)          (((x) & WLAN_XTAL_TEST_NOTCXODET_MASK) >> WLAN_XTAL_TEST_NOTCXODET_LSB)
-#define WLAN_XTAL_TEST_NOTCXODET_SET(x)          (((x) << WLAN_XTAL_TEST_NOTCXODET_LSB) & WLAN_XTAL_TEST_NOTCXODET_MASK)
-
-#define WLAN_QUADRATURE_ADDRESS                  0x00000010
-#define WLAN_QUADRATURE_OFFSET                   0x00000010
-#define WLAN_QUADRATURE_ADC_MSB                  7
-#define WLAN_QUADRATURE_ADC_LSB                  4
-#define WLAN_QUADRATURE_ADC_MASK                 0x000000f0
-#define WLAN_QUADRATURE_ADC_GET(x)               (((x) & WLAN_QUADRATURE_ADC_MASK) >> WLAN_QUADRATURE_ADC_LSB)
-#define WLAN_QUADRATURE_ADC_SET(x)               (((x) << WLAN_QUADRATURE_ADC_LSB) & WLAN_QUADRATURE_ADC_MASK)
-#define WLAN_QUADRATURE_SEL_MSB                  2
-#define WLAN_QUADRATURE_SEL_LSB                  2
-#define WLAN_QUADRATURE_SEL_MASK                 0x00000004
-#define WLAN_QUADRATURE_SEL_GET(x)               (((x) & WLAN_QUADRATURE_SEL_MASK) >> WLAN_QUADRATURE_SEL_LSB)
-#define WLAN_QUADRATURE_SEL_SET(x)               (((x) << WLAN_QUADRATURE_SEL_LSB) & WLAN_QUADRATURE_SEL_MASK)
-#define WLAN_QUADRATURE_DAC_MSB                  1
-#define WLAN_QUADRATURE_DAC_LSB                  0
-#define WLAN_QUADRATURE_DAC_MASK                 0x00000003
-#define WLAN_QUADRATURE_DAC_GET(x)               (((x) & WLAN_QUADRATURE_DAC_MASK) >> WLAN_QUADRATURE_DAC_LSB)
-#define WLAN_QUADRATURE_DAC_SET(x)               (((x) << WLAN_QUADRATURE_DAC_LSB) & WLAN_QUADRATURE_DAC_MASK)
-
-#define WLAN_PLL_CONTROL_ADDRESS                 0x00000014
-#define WLAN_PLL_CONTROL_OFFSET                  0x00000014
-#define WLAN_PLL_CONTROL_DIG_TEST_CLK_MSB        20
-#define WLAN_PLL_CONTROL_DIG_TEST_CLK_LSB        20
-#define WLAN_PLL_CONTROL_DIG_TEST_CLK_MASK       0x00100000
-#define WLAN_PLL_CONTROL_DIG_TEST_CLK_GET(x)     (((x) & WLAN_PLL_CONTROL_DIG_TEST_CLK_MASK) >> WLAN_PLL_CONTROL_DIG_TEST_CLK_LSB)
-#define WLAN_PLL_CONTROL_DIG_TEST_CLK_SET(x)     (((x) << WLAN_PLL_CONTROL_DIG_TEST_CLK_LSB) & WLAN_PLL_CONTROL_DIG_TEST_CLK_MASK)
-#define WLAN_PLL_CONTROL_MAC_OVERRIDE_MSB        19
-#define WLAN_PLL_CONTROL_MAC_OVERRIDE_LSB        19
-#define WLAN_PLL_CONTROL_MAC_OVERRIDE_MASK       0x00080000
-#define WLAN_PLL_CONTROL_MAC_OVERRIDE_GET(x)     (((x) & WLAN_PLL_CONTROL_MAC_OVERRIDE_MASK) >> WLAN_PLL_CONTROL_MAC_OVERRIDE_LSB)
-#define WLAN_PLL_CONTROL_MAC_OVERRIDE_SET(x)     (((x) << WLAN_PLL_CONTROL_MAC_OVERRIDE_LSB) & WLAN_PLL_CONTROL_MAC_OVERRIDE_MASK)
-#define WLAN_PLL_CONTROL_NOPWD_MSB               18
-#define WLAN_PLL_CONTROL_NOPWD_LSB               18
-#define WLAN_PLL_CONTROL_NOPWD_MASK              0x00040000
-#define WLAN_PLL_CONTROL_NOPWD_GET(x)            (((x) & WLAN_PLL_CONTROL_NOPWD_MASK) >> WLAN_PLL_CONTROL_NOPWD_LSB)
-#define WLAN_PLL_CONTROL_NOPWD_SET(x)            (((x) << WLAN_PLL_CONTROL_NOPWD_LSB) & WLAN_PLL_CONTROL_NOPWD_MASK)
-#define WLAN_PLL_CONTROL_UPDATING_MSB            17
-#define WLAN_PLL_CONTROL_UPDATING_LSB            17
-#define WLAN_PLL_CONTROL_UPDATING_MASK           0x00020000
-#define WLAN_PLL_CONTROL_UPDATING_GET(x)         (((x) & WLAN_PLL_CONTROL_UPDATING_MASK) >> WLAN_PLL_CONTROL_UPDATING_LSB)
-#define WLAN_PLL_CONTROL_UPDATING_SET(x)         (((x) << WLAN_PLL_CONTROL_UPDATING_LSB) & WLAN_PLL_CONTROL_UPDATING_MASK)
-#define WLAN_PLL_CONTROL_BYPASS_MSB              16
-#define WLAN_PLL_CONTROL_BYPASS_LSB              16
-#define WLAN_PLL_CONTROL_BYPASS_MASK             0x00010000
-#define WLAN_PLL_CONTROL_BYPASS_GET(x)           (((x) & WLAN_PLL_CONTROL_BYPASS_MASK) >> WLAN_PLL_CONTROL_BYPASS_LSB)
-#define WLAN_PLL_CONTROL_BYPASS_SET(x)           (((x) << WLAN_PLL_CONTROL_BYPASS_LSB) & WLAN_PLL_CONTROL_BYPASS_MASK)
-#define WLAN_PLL_CONTROL_REFDIV_MSB              15
-#define WLAN_PLL_CONTROL_REFDIV_LSB              12
-#define WLAN_PLL_CONTROL_REFDIV_MASK             0x0000f000
-#define WLAN_PLL_CONTROL_REFDIV_GET(x)           (((x) & WLAN_PLL_CONTROL_REFDIV_MASK) >> WLAN_PLL_CONTROL_REFDIV_LSB)
-#define WLAN_PLL_CONTROL_REFDIV_SET(x)           (((x) << WLAN_PLL_CONTROL_REFDIV_LSB) & WLAN_PLL_CONTROL_REFDIV_MASK)
-#define WLAN_PLL_CONTROL_DIV_MSB                 9
-#define WLAN_PLL_CONTROL_DIV_LSB                 0
-#define WLAN_PLL_CONTROL_DIV_MASK                0x000003ff
-#define WLAN_PLL_CONTROL_DIV_GET(x)              (((x) & WLAN_PLL_CONTROL_DIV_MASK) >> WLAN_PLL_CONTROL_DIV_LSB)
-#define WLAN_PLL_CONTROL_DIV_SET(x)              (((x) << WLAN_PLL_CONTROL_DIV_LSB) & WLAN_PLL_CONTROL_DIV_MASK)
-
-#define WLAN_PLL_SETTLE_ADDRESS                  0x00000018
-#define WLAN_PLL_SETTLE_OFFSET                   0x00000018
-#define WLAN_PLL_SETTLE_TIME_MSB                 11
-#define WLAN_PLL_SETTLE_TIME_LSB                 0
-#define WLAN_PLL_SETTLE_TIME_MASK                0x00000fff
-#define WLAN_PLL_SETTLE_TIME_GET(x)              (((x) & WLAN_PLL_SETTLE_TIME_MASK) >> WLAN_PLL_SETTLE_TIME_LSB)
-#define WLAN_PLL_SETTLE_TIME_SET(x)              (((x) << WLAN_PLL_SETTLE_TIME_LSB) & WLAN_PLL_SETTLE_TIME_MASK)
-
-#define WLAN_XTAL_SETTLE_ADDRESS                 0x0000001c
-#define WLAN_XTAL_SETTLE_OFFSET                  0x0000001c
-#define WLAN_XTAL_SETTLE_TIME_MSB                7
-#define WLAN_XTAL_SETTLE_TIME_LSB                0
-#define WLAN_XTAL_SETTLE_TIME_MASK               0x000000ff
-#define WLAN_XTAL_SETTLE_TIME_GET(x)             (((x) & WLAN_XTAL_SETTLE_TIME_MASK) >> WLAN_XTAL_SETTLE_TIME_LSB)
-#define WLAN_XTAL_SETTLE_TIME_SET(x)             (((x) << WLAN_XTAL_SETTLE_TIME_LSB) & WLAN_XTAL_SETTLE_TIME_MASK)
-
 #define WLAN_CPU_CLOCK_ADDRESS                   0x00000020
 #define WLAN_CPU_CLOCK_OFFSET                    0x00000020
 #define WLAN_CPU_CLOCK_STANDARD_MSB              1
@@ -201,14 +105,6 @@
 #define WLAN_CPU_CLOCK_STANDARD_GET(x)           (((x) & WLAN_CPU_CLOCK_STANDARD_MASK) >> WLAN_CPU_CLOCK_STANDARD_LSB)
 #define WLAN_CPU_CLOCK_STANDARD_SET(x)           (((x) << WLAN_CPU_CLOCK_STANDARD_LSB) & WLAN_CPU_CLOCK_STANDARD_MASK)
 
-#define WLAN_CLOCK_OUT_ADDRESS                   0x00000024
-#define WLAN_CLOCK_OUT_OFFSET                    0x00000024
-#define WLAN_CLOCK_OUT_SELECT_MSB                3
-#define WLAN_CLOCK_OUT_SELECT_LSB                0
-#define WLAN_CLOCK_OUT_SELECT_MASK               0x0000000f
-#define WLAN_CLOCK_OUT_SELECT_GET(x)             (((x) & WLAN_CLOCK_OUT_SELECT_MASK) >> WLAN_CLOCK_OUT_SELECT_LSB)
-#define WLAN_CLOCK_OUT_SELECT_SET(x)             (((x) << WLAN_CLOCK_OUT_SELECT_LSB) & WLAN_CLOCK_OUT_SELECT_MASK)
-
 #define WLAN_CLOCK_CONTROL_ADDRESS               0x00000028
 #define WLAN_CLOCK_CONTROL_OFFSET                0x00000028
 #define WLAN_CLOCK_CONTROL_LF_CLK32_MSB          2
@@ -222,555 +118,6 @@
 #define WLAN_CLOCK_CONTROL_SI0_CLK_GET(x)        (((x) & WLAN_CLOCK_CONTROL_SI0_CLK_MASK) >> WLAN_CLOCK_CONTROL_SI0_CLK_LSB)
 #define WLAN_CLOCK_CONTROL_SI0_CLK_SET(x)        (((x) << WLAN_CLOCK_CONTROL_SI0_CLK_LSB) & WLAN_CLOCK_CONTROL_SI0_CLK_MASK)
 
-#define WLAN_BIAS_OVERRIDE_ADDRESS               0x0000002c
-#define WLAN_BIAS_OVERRIDE_OFFSET                0x0000002c
-#define WLAN_BIAS_OVERRIDE_ON_MSB                0
-#define WLAN_BIAS_OVERRIDE_ON_LSB                0
-#define WLAN_BIAS_OVERRIDE_ON_MASK               0x00000001
-#define WLAN_BIAS_OVERRIDE_ON_GET(x)             (((x) & WLAN_BIAS_OVERRIDE_ON_MASK) >> WLAN_BIAS_OVERRIDE_ON_LSB)
-#define WLAN_BIAS_OVERRIDE_ON_SET(x)             (((x) << WLAN_BIAS_OVERRIDE_ON_LSB) & WLAN_BIAS_OVERRIDE_ON_MASK)
-
-#define WLAN_WDT_CONTROL_ADDRESS                 0x00000030
-#define WLAN_WDT_CONTROL_OFFSET                  0x00000030
-#define WLAN_WDT_CONTROL_ACTION_MSB              2
-#define WLAN_WDT_CONTROL_ACTION_LSB              0
-#define WLAN_WDT_CONTROL_ACTION_MASK             0x00000007
-#define WLAN_WDT_CONTROL_ACTION_GET(x)           (((x) & WLAN_WDT_CONTROL_ACTION_MASK) >> WLAN_WDT_CONTROL_ACTION_LSB)
-#define WLAN_WDT_CONTROL_ACTION_SET(x)           (((x) << WLAN_WDT_CONTROL_ACTION_LSB) & WLAN_WDT_CONTROL_ACTION_MASK)
-
-#define WLAN_WDT_STATUS_ADDRESS                  0x00000034
-#define WLAN_WDT_STATUS_OFFSET                   0x00000034
-#define WLAN_WDT_STATUS_INTERRUPT_MSB            0
-#define WLAN_WDT_STATUS_INTERRUPT_LSB            0
-#define WLAN_WDT_STATUS_INTERRUPT_MASK           0x00000001
-#define WLAN_WDT_STATUS_INTERRUPT_GET(x)         (((x) & WLAN_WDT_STATUS_INTERRUPT_MASK) >> WLAN_WDT_STATUS_INTERRUPT_LSB)
-#define WLAN_WDT_STATUS_INTERRUPT_SET(x)         (((x) << WLAN_WDT_STATUS_INTERRUPT_LSB) & WLAN_WDT_STATUS_INTERRUPT_MASK)
-
-#define WLAN_WDT_ADDRESS                         0x00000038
-#define WLAN_WDT_OFFSET                          0x00000038
-#define WLAN_WDT_TARGET_MSB                      21
-#define WLAN_WDT_TARGET_LSB                      0
-#define WLAN_WDT_TARGET_MASK                     0x003fffff
-#define WLAN_WDT_TARGET_GET(x)                   (((x) & WLAN_WDT_TARGET_MASK) >> WLAN_WDT_TARGET_LSB)
-#define WLAN_WDT_TARGET_SET(x)                   (((x) << WLAN_WDT_TARGET_LSB) & WLAN_WDT_TARGET_MASK)
-
-#define WLAN_WDT_COUNT_ADDRESS                   0x0000003c
-#define WLAN_WDT_COUNT_OFFSET                    0x0000003c
-#define WLAN_WDT_COUNT_VALUE_MSB                 21
-#define WLAN_WDT_COUNT_VALUE_LSB                 0
-#define WLAN_WDT_COUNT_VALUE_MASK                0x003fffff
-#define WLAN_WDT_COUNT_VALUE_GET(x)              (((x) & WLAN_WDT_COUNT_VALUE_MASK) >> WLAN_WDT_COUNT_VALUE_LSB)
-#define WLAN_WDT_COUNT_VALUE_SET(x)              (((x) << WLAN_WDT_COUNT_VALUE_LSB) & WLAN_WDT_COUNT_VALUE_MASK)
-
-#define WLAN_WDT_RESET_ADDRESS                   0x00000040
-#define WLAN_WDT_RESET_OFFSET                    0x00000040
-#define WLAN_WDT_RESET_VALUE_MSB                 0
-#define WLAN_WDT_RESET_VALUE_LSB                 0
-#define WLAN_WDT_RESET_VALUE_MASK                0x00000001
-#define WLAN_WDT_RESET_VALUE_GET(x)              (((x) & WLAN_WDT_RESET_VALUE_MASK) >> WLAN_WDT_RESET_VALUE_LSB)
-#define WLAN_WDT_RESET_VALUE_SET(x)              (((x) << WLAN_WDT_RESET_VALUE_LSB) & WLAN_WDT_RESET_VALUE_MASK)
-
-#define WLAN_INT_STATUS_ADDRESS                  0x00000044
-#define WLAN_INT_STATUS_OFFSET                   0x00000044
-#define WLAN_INT_STATUS_HCI_UART_MSB             21
-#define WLAN_INT_STATUS_HCI_UART_LSB             21
-#define WLAN_INT_STATUS_HCI_UART_MASK            0x00200000
-#define WLAN_INT_STATUS_HCI_UART_GET(x)          (((x) & WLAN_INT_STATUS_HCI_UART_MASK) >> WLAN_INT_STATUS_HCI_UART_LSB)
-#define WLAN_INT_STATUS_HCI_UART_SET(x)          (((x) << WLAN_INT_STATUS_HCI_UART_LSB) & WLAN_INT_STATUS_HCI_UART_MASK)
-#define WLAN_INT_STATUS_THERM_MSB                20
-#define WLAN_INT_STATUS_THERM_LSB                20
-#define WLAN_INT_STATUS_THERM_MASK               0x00100000
-#define WLAN_INT_STATUS_THERM_GET(x)             (((x) & WLAN_INT_STATUS_THERM_MASK) >> WLAN_INT_STATUS_THERM_LSB)
-#define WLAN_INT_STATUS_THERM_SET(x)             (((x) << WLAN_INT_STATUS_THERM_LSB) & WLAN_INT_STATUS_THERM_MASK)
-#define WLAN_INT_STATUS_EFUSE_OVERWRITE_MSB      19
-#define WLAN_INT_STATUS_EFUSE_OVERWRITE_LSB      19
-#define WLAN_INT_STATUS_EFUSE_OVERWRITE_MASK     0x00080000
-#define WLAN_INT_STATUS_EFUSE_OVERWRITE_GET(x)   (((x) & WLAN_INT_STATUS_EFUSE_OVERWRITE_MASK) >> WLAN_INT_STATUS_EFUSE_OVERWRITE_LSB)
-#define WLAN_INT_STATUS_EFUSE_OVERWRITE_SET(x)   (((x) << WLAN_INT_STATUS_EFUSE_OVERWRITE_LSB) & WLAN_INT_STATUS_EFUSE_OVERWRITE_MASK)
-#define WLAN_INT_STATUS_UART_MBOX_MSB            18
-#define WLAN_INT_STATUS_UART_MBOX_LSB            18
-#define WLAN_INT_STATUS_UART_MBOX_MASK           0x00040000
-#define WLAN_INT_STATUS_UART_MBOX_GET(x)         (((x) & WLAN_INT_STATUS_UART_MBOX_MASK) >> WLAN_INT_STATUS_UART_MBOX_LSB)
-#define WLAN_INT_STATUS_UART_MBOX_SET(x)         (((x) << WLAN_INT_STATUS_UART_MBOX_LSB) & WLAN_INT_STATUS_UART_MBOX_MASK)
-#define WLAN_INT_STATUS_GENERIC_MBOX_MSB         17
-#define WLAN_INT_STATUS_GENERIC_MBOX_LSB         17
-#define WLAN_INT_STATUS_GENERIC_MBOX_MASK        0x00020000
-#define WLAN_INT_STATUS_GENERIC_MBOX_GET(x)      (((x) & WLAN_INT_STATUS_GENERIC_MBOX_MASK) >> WLAN_INT_STATUS_GENERIC_MBOX_LSB)
-#define WLAN_INT_STATUS_GENERIC_MBOX_SET(x)      (((x) << WLAN_INT_STATUS_GENERIC_MBOX_LSB) & WLAN_INT_STATUS_GENERIC_MBOX_MASK)
-#define WLAN_INT_STATUS_RDMA_MSB                 16
-#define WLAN_INT_STATUS_RDMA_LSB                 16
-#define WLAN_INT_STATUS_RDMA_MASK                0x00010000
-#define WLAN_INT_STATUS_RDMA_GET(x)              (((x) & WLAN_INT_STATUS_RDMA_MASK) >> WLAN_INT_STATUS_RDMA_LSB)
-#define WLAN_INT_STATUS_RDMA_SET(x)              (((x) << WLAN_INT_STATUS_RDMA_LSB) & WLAN_INT_STATUS_RDMA_MASK)
-#define WLAN_INT_STATUS_BTCOEX_MSB               15
-#define WLAN_INT_STATUS_BTCOEX_LSB               15
-#define WLAN_INT_STATUS_BTCOEX_MASK              0x00008000
-#define WLAN_INT_STATUS_BTCOEX_GET(x)            (((x) & WLAN_INT_STATUS_BTCOEX_MASK) >> WLAN_INT_STATUS_BTCOEX_LSB)
-#define WLAN_INT_STATUS_BTCOEX_SET(x)            (((x) << WLAN_INT_STATUS_BTCOEX_LSB) & WLAN_INT_STATUS_BTCOEX_MASK)
-#define WLAN_INT_STATUS_RTC_POWER_MSB            14
-#define WLAN_INT_STATUS_RTC_POWER_LSB            14
-#define WLAN_INT_STATUS_RTC_POWER_MASK           0x00004000
-#define WLAN_INT_STATUS_RTC_POWER_GET(x)         (((x) & WLAN_INT_STATUS_RTC_POWER_MASK) >> WLAN_INT_STATUS_RTC_POWER_LSB)
-#define WLAN_INT_STATUS_RTC_POWER_SET(x)         (((x) << WLAN_INT_STATUS_RTC_POWER_LSB) & WLAN_INT_STATUS_RTC_POWER_MASK)
-#define WLAN_INT_STATUS_MAC_MSB                  13
-#define WLAN_INT_STATUS_MAC_LSB                  13
-#define WLAN_INT_STATUS_MAC_MASK                 0x00002000
-#define WLAN_INT_STATUS_MAC_GET(x)               (((x) & WLAN_INT_STATUS_MAC_MASK) >> WLAN_INT_STATUS_MAC_LSB)
-#define WLAN_INT_STATUS_MAC_SET(x)               (((x) << WLAN_INT_STATUS_MAC_LSB) & WLAN_INT_STATUS_MAC_MASK)
-#define WLAN_INT_STATUS_MAILBOX_MSB              12
-#define WLAN_INT_STATUS_MAILBOX_LSB              12
-#define WLAN_INT_STATUS_MAILBOX_MASK             0x00001000
-#define WLAN_INT_STATUS_MAILBOX_GET(x)           (((x) & WLAN_INT_STATUS_MAILBOX_MASK) >> WLAN_INT_STATUS_MAILBOX_LSB)
-#define WLAN_INT_STATUS_MAILBOX_SET(x)           (((x) << WLAN_INT_STATUS_MAILBOX_LSB) & WLAN_INT_STATUS_MAILBOX_MASK)
-#define WLAN_INT_STATUS_RTC_ALARM_MSB            11
-#define WLAN_INT_STATUS_RTC_ALARM_LSB            11
-#define WLAN_INT_STATUS_RTC_ALARM_MASK           0x00000800
-#define WLAN_INT_STATUS_RTC_ALARM_GET(x)         (((x) & WLAN_INT_STATUS_RTC_ALARM_MASK) >> WLAN_INT_STATUS_RTC_ALARM_LSB)
-#define WLAN_INT_STATUS_RTC_ALARM_SET(x)         (((x) << WLAN_INT_STATUS_RTC_ALARM_LSB) & WLAN_INT_STATUS_RTC_ALARM_MASK)
-#define WLAN_INT_STATUS_HF_TIMER_MSB             10
-#define WLAN_INT_STATUS_HF_TIMER_LSB             10
-#define WLAN_INT_STATUS_HF_TIMER_MASK            0x00000400
-#define WLAN_INT_STATUS_HF_TIMER_GET(x)          (((x) & WLAN_INT_STATUS_HF_TIMER_MASK) >> WLAN_INT_STATUS_HF_TIMER_LSB)
-#define WLAN_INT_STATUS_HF_TIMER_SET(x)          (((x) << WLAN_INT_STATUS_HF_TIMER_LSB) & WLAN_INT_STATUS_HF_TIMER_MASK)
-#define WLAN_INT_STATUS_LF_TIMER3_MSB            9
-#define WLAN_INT_STATUS_LF_TIMER3_LSB            9
-#define WLAN_INT_STATUS_LF_TIMER3_MASK           0x00000200
-#define WLAN_INT_STATUS_LF_TIMER3_GET(x)         (((x) & WLAN_INT_STATUS_LF_TIMER3_MASK) >> WLAN_INT_STATUS_LF_TIMER3_LSB)
-#define WLAN_INT_STATUS_LF_TIMER3_SET(x)         (((x) << WLAN_INT_STATUS_LF_TIMER3_LSB) & WLAN_INT_STATUS_LF_TIMER3_MASK)
-#define WLAN_INT_STATUS_LF_TIMER2_MSB            8
-#define WLAN_INT_STATUS_LF_TIMER2_LSB            8
-#define WLAN_INT_STATUS_LF_TIMER2_MASK           0x00000100
-#define WLAN_INT_STATUS_LF_TIMER2_GET(x)         (((x) & WLAN_INT_STATUS_LF_TIMER2_MASK) >> WLAN_INT_STATUS_LF_TIMER2_LSB)
-#define WLAN_INT_STATUS_LF_TIMER2_SET(x)         (((x) << WLAN_INT_STATUS_LF_TIMER2_LSB) & WLAN_INT_STATUS_LF_TIMER2_MASK)
-#define WLAN_INT_STATUS_LF_TIMER1_MSB            7
-#define WLAN_INT_STATUS_LF_TIMER1_LSB            7
-#define WLAN_INT_STATUS_LF_TIMER1_MASK           0x00000080
-#define WLAN_INT_STATUS_LF_TIMER1_GET(x)         (((x) & WLAN_INT_STATUS_LF_TIMER1_MASK) >> WLAN_INT_STATUS_LF_TIMER1_LSB)
-#define WLAN_INT_STATUS_LF_TIMER1_SET(x)         (((x) << WLAN_INT_STATUS_LF_TIMER1_LSB) & WLAN_INT_STATUS_LF_TIMER1_MASK)
-#define WLAN_INT_STATUS_LF_TIMER0_MSB            6
-#define WLAN_INT_STATUS_LF_TIMER0_LSB            6
-#define WLAN_INT_STATUS_LF_TIMER0_MASK           0x00000040
-#define WLAN_INT_STATUS_LF_TIMER0_GET(x)         (((x) & WLAN_INT_STATUS_LF_TIMER0_MASK) >> WLAN_INT_STATUS_LF_TIMER0_LSB)
-#define WLAN_INT_STATUS_LF_TIMER0_SET(x)         (((x) << WLAN_INT_STATUS_LF_TIMER0_LSB) & WLAN_INT_STATUS_LF_TIMER0_MASK)
-#define WLAN_INT_STATUS_KEYPAD_MSB               5
-#define WLAN_INT_STATUS_KEYPAD_LSB               5
-#define WLAN_INT_STATUS_KEYPAD_MASK              0x00000020
-#define WLAN_INT_STATUS_KEYPAD_GET(x)            (((x) & WLAN_INT_STATUS_KEYPAD_MASK) >> WLAN_INT_STATUS_KEYPAD_LSB)
-#define WLAN_INT_STATUS_KEYPAD_SET(x)            (((x) << WLAN_INT_STATUS_KEYPAD_LSB) & WLAN_INT_STATUS_KEYPAD_MASK)
-#define WLAN_INT_STATUS_SI_MSB                   4
-#define WLAN_INT_STATUS_SI_LSB                   4
-#define WLAN_INT_STATUS_SI_MASK                  0x00000010
-#define WLAN_INT_STATUS_SI_GET(x)                (((x) & WLAN_INT_STATUS_SI_MASK) >> WLAN_INT_STATUS_SI_LSB)
-#define WLAN_INT_STATUS_SI_SET(x)                (((x) << WLAN_INT_STATUS_SI_LSB) & WLAN_INT_STATUS_SI_MASK)
-#define WLAN_INT_STATUS_GPIO_MSB                 3
-#define WLAN_INT_STATUS_GPIO_LSB                 3
-#define WLAN_INT_STATUS_GPIO_MASK                0x00000008
-#define WLAN_INT_STATUS_GPIO_GET(x)              (((x) & WLAN_INT_STATUS_GPIO_MASK) >> WLAN_INT_STATUS_GPIO_LSB)
-#define WLAN_INT_STATUS_GPIO_SET(x)              (((x) << WLAN_INT_STATUS_GPIO_LSB) & WLAN_INT_STATUS_GPIO_MASK)
-#define WLAN_INT_STATUS_UART_MSB                 2
-#define WLAN_INT_STATUS_UART_LSB                 2
-#define WLAN_INT_STATUS_UART_MASK                0x00000004
-#define WLAN_INT_STATUS_UART_GET(x)              (((x) & WLAN_INT_STATUS_UART_MASK) >> WLAN_INT_STATUS_UART_LSB)
-#define WLAN_INT_STATUS_UART_SET(x)              (((x) << WLAN_INT_STATUS_UART_LSB) & WLAN_INT_STATUS_UART_MASK)
-#define WLAN_INT_STATUS_ERROR_MSB                1
-#define WLAN_INT_STATUS_ERROR_LSB                1
-#define WLAN_INT_STATUS_ERROR_MASK               0x00000002
-#define WLAN_INT_STATUS_ERROR_GET(x)             (((x) & WLAN_INT_STATUS_ERROR_MASK) >> WLAN_INT_STATUS_ERROR_LSB)
-#define WLAN_INT_STATUS_ERROR_SET(x)             (((x) << WLAN_INT_STATUS_ERROR_LSB) & WLAN_INT_STATUS_ERROR_MASK)
-#define WLAN_INT_STATUS_WDT_INT_MSB              0
-#define WLAN_INT_STATUS_WDT_INT_LSB              0
-#define WLAN_INT_STATUS_WDT_INT_MASK             0x00000001
-#define WLAN_INT_STATUS_WDT_INT_GET(x)           (((x) & WLAN_INT_STATUS_WDT_INT_MASK) >> WLAN_INT_STATUS_WDT_INT_LSB)
-#define WLAN_INT_STATUS_WDT_INT_SET(x)           (((x) << WLAN_INT_STATUS_WDT_INT_LSB) & WLAN_INT_STATUS_WDT_INT_MASK)
-
-#define WLAN_LF_TIMER0_ADDRESS                   0x00000048
-#define WLAN_LF_TIMER0_OFFSET                    0x00000048
-#define WLAN_LF_TIMER0_TARGET_MSB                31
-#define WLAN_LF_TIMER0_TARGET_LSB                0
-#define WLAN_LF_TIMER0_TARGET_MASK               0xffffffff
-#define WLAN_LF_TIMER0_TARGET_GET(x)             (((x) & WLAN_LF_TIMER0_TARGET_MASK) >> WLAN_LF_TIMER0_TARGET_LSB)
-#define WLAN_LF_TIMER0_TARGET_SET(x)             (((x) << WLAN_LF_TIMER0_TARGET_LSB) & WLAN_LF_TIMER0_TARGET_MASK)
-
-#define WLAN_LF_TIMER_COUNT0_ADDRESS             0x0000004c
-#define WLAN_LF_TIMER_COUNT0_OFFSET              0x0000004c
-#define WLAN_LF_TIMER_COUNT0_VALUE_MSB           31
-#define WLAN_LF_TIMER_COUNT0_VALUE_LSB           0
-#define WLAN_LF_TIMER_COUNT0_VALUE_MASK          0xffffffff
-#define WLAN_LF_TIMER_COUNT0_VALUE_GET(x)        (((x) & WLAN_LF_TIMER_COUNT0_VALUE_MASK) >> WLAN_LF_TIMER_COUNT0_VALUE_LSB)
-#define WLAN_LF_TIMER_COUNT0_VALUE_SET(x)        (((x) << WLAN_LF_TIMER_COUNT0_VALUE_LSB) & WLAN_LF_TIMER_COUNT0_VALUE_MASK)
-
-#define WLAN_LF_TIMER_CONTROL0_ADDRESS           0x00000050
-#define WLAN_LF_TIMER_CONTROL0_OFFSET            0x00000050
-#define WLAN_LF_TIMER_CONTROL0_ENABLE_MSB        2
-#define WLAN_LF_TIMER_CONTROL0_ENABLE_LSB        2
-#define WLAN_LF_TIMER_CONTROL0_ENABLE_MASK       0x00000004
-#define WLAN_LF_TIMER_CONTROL0_ENABLE_GET(x)     (((x) & WLAN_LF_TIMER_CONTROL0_ENABLE_MASK) >> WLAN_LF_TIMER_CONTROL0_ENABLE_LSB)
-#define WLAN_LF_TIMER_CONTROL0_ENABLE_SET(x)     (((x) << WLAN_LF_TIMER_CONTROL0_ENABLE_LSB) & WLAN_LF_TIMER_CONTROL0_ENABLE_MASK)
-#define WLAN_LF_TIMER_CONTROL0_AUTO_RESTART_MSB  1
-#define WLAN_LF_TIMER_CONTROL0_AUTO_RESTART_LSB  1
-#define WLAN_LF_TIMER_CONTROL0_AUTO_RESTART_MASK 0x00000002
-#define WLAN_LF_TIMER_CONTROL0_AUTO_RESTART_GET(x) (((x) & WLAN_LF_TIMER_CONTROL0_AUTO_RESTART_MASK) >> WLAN_LF_TIMER_CONTROL0_AUTO_RESTART_LSB)
-#define WLAN_LF_TIMER_CONTROL0_AUTO_RESTART_SET(x) (((x) << WLAN_LF_TIMER_CONTROL0_AUTO_RESTART_LSB) & WLAN_LF_TIMER_CONTROL0_AUTO_RESTART_MASK)
-#define WLAN_LF_TIMER_CONTROL0_RESET_MSB         0
-#define WLAN_LF_TIMER_CONTROL0_RESET_LSB         0
-#define WLAN_LF_TIMER_CONTROL0_RESET_MASK        0x00000001
-#define WLAN_LF_TIMER_CONTROL0_RESET_GET(x)      (((x) & WLAN_LF_TIMER_CONTROL0_RESET_MASK) >> WLAN_LF_TIMER_CONTROL0_RESET_LSB)
-#define WLAN_LF_TIMER_CONTROL0_RESET_SET(x)      (((x) << WLAN_LF_TIMER_CONTROL0_RESET_LSB) & WLAN_LF_TIMER_CONTROL0_RESET_MASK)
-
-#define WLAN_LF_TIMER_STATUS0_ADDRESS            0x00000054
-#define WLAN_LF_TIMER_STATUS0_OFFSET             0x00000054
-#define WLAN_LF_TIMER_STATUS0_INTERRUPT_MSB      0
-#define WLAN_LF_TIMER_STATUS0_INTERRUPT_LSB      0
-#define WLAN_LF_TIMER_STATUS0_INTERRUPT_MASK     0x00000001
-#define WLAN_LF_TIMER_STATUS0_INTERRUPT_GET(x)   (((x) & WLAN_LF_TIMER_STATUS0_INTERRUPT_MASK) >> WLAN_LF_TIMER_STATUS0_INTERRUPT_LSB)
-#define WLAN_LF_TIMER_STATUS0_INTERRUPT_SET(x)   (((x) << WLAN_LF_TIMER_STATUS0_INTERRUPT_LSB) & WLAN_LF_TIMER_STATUS0_INTERRUPT_MASK)
-
-#define WLAN_LF_TIMER1_ADDRESS                   0x00000058
-#define WLAN_LF_TIMER1_OFFSET                    0x00000058
-#define WLAN_LF_TIMER1_TARGET_MSB                31
-#define WLAN_LF_TIMER1_TARGET_LSB                0
-#define WLAN_LF_TIMER1_TARGET_MASK               0xffffffff
-#define WLAN_LF_TIMER1_TARGET_GET(x)             (((x) & WLAN_LF_TIMER1_TARGET_MASK) >> WLAN_LF_TIMER1_TARGET_LSB)
-#define WLAN_LF_TIMER1_TARGET_SET(x)             (((x) << WLAN_LF_TIMER1_TARGET_LSB) & WLAN_LF_TIMER1_TARGET_MASK)
-
-#define WLAN_LF_TIMER_COUNT1_ADDRESS             0x0000005c
-#define WLAN_LF_TIMER_COUNT1_OFFSET              0x0000005c
-#define WLAN_LF_TIMER_COUNT1_VALUE_MSB           31
-#define WLAN_LF_TIMER_COUNT1_VALUE_LSB           0
-#define WLAN_LF_TIMER_COUNT1_VALUE_MASK          0xffffffff
-#define WLAN_LF_TIMER_COUNT1_VALUE_GET(x)        (((x) & WLAN_LF_TIMER_COUNT1_VALUE_MASK) >> WLAN_LF_TIMER_COUNT1_VALUE_LSB)
-#define WLAN_LF_TIMER_COUNT1_VALUE_SET(x)        (((x) << WLAN_LF_TIMER_COUNT1_VALUE_LSB) & WLAN_LF_TIMER_COUNT1_VALUE_MASK)
-
-#define WLAN_LF_TIMER_CONTROL1_ADDRESS           0x00000060
-#define WLAN_LF_TIMER_CONTROL1_OFFSET            0x00000060
-#define WLAN_LF_TIMER_CONTROL1_ENABLE_MSB        2
-#define WLAN_LF_TIMER_CONTROL1_ENABLE_LSB        2
-#define WLAN_LF_TIMER_CONTROL1_ENABLE_MASK       0x00000004
-#define WLAN_LF_TIMER_CONTROL1_ENABLE_GET(x)     (((x) & WLAN_LF_TIMER_CONTROL1_ENABLE_MASK) >> WLAN_LF_TIMER_CONTROL1_ENABLE_LSB)
-#define WLAN_LF_TIMER_CONTROL1_ENABLE_SET(x)     (((x) << WLAN_LF_TIMER_CONTROL1_ENABLE_LSB) & WLAN_LF_TIMER_CONTROL1_ENABLE_MASK)
-#define WLAN_LF_TIMER_CONTROL1_AUTO_RESTART_MSB  1
-#define WLAN_LF_TIMER_CONTROL1_AUTO_RESTART_LSB  1
-#define WLAN_LF_TIMER_CONTROL1_AUTO_RESTART_MASK 0x00000002
-#define WLAN_LF_TIMER_CONTROL1_AUTO_RESTART_GET(x) (((x) & WLAN_LF_TIMER_CONTROL1_AUTO_RESTART_MASK) >> WLAN_LF_TIMER_CONTROL1_AUTO_RESTART_LSB)
-#define WLAN_LF_TIMER_CONTROL1_AUTO_RESTART_SET(x) (((x) << WLAN_LF_TIMER_CONTROL1_AUTO_RESTART_LSB) & WLAN_LF_TIMER_CONTROL1_AUTO_RESTART_MASK)
-#define WLAN_LF_TIMER_CONTROL1_RESET_MSB         0
-#define WLAN_LF_TIMER_CONTROL1_RESET_LSB         0
-#define WLAN_LF_TIMER_CONTROL1_RESET_MASK        0x00000001
-#define WLAN_LF_TIMER_CONTROL1_RESET_GET(x)      (((x) & WLAN_LF_TIMER_CONTROL1_RESET_MASK) >> WLAN_LF_TIMER_CONTROL1_RESET_LSB)
-#define WLAN_LF_TIMER_CONTROL1_RESET_SET(x)      (((x) << WLAN_LF_TIMER_CONTROL1_RESET_LSB) & WLAN_LF_TIMER_CONTROL1_RESET_MASK)
-
-#define WLAN_LF_TIMER_STATUS1_ADDRESS            0x00000064
-#define WLAN_LF_TIMER_STATUS1_OFFSET             0x00000064
-#define WLAN_LF_TIMER_STATUS1_INTERRUPT_MSB      0
-#define WLAN_LF_TIMER_STATUS1_INTERRUPT_LSB      0
-#define WLAN_LF_TIMER_STATUS1_INTERRUPT_MASK     0x00000001
-#define WLAN_LF_TIMER_STATUS1_INTERRUPT_GET(x)   (((x) & WLAN_LF_TIMER_STATUS1_INTERRUPT_MASK) >> WLAN_LF_TIMER_STATUS1_INTERRUPT_LSB)
-#define WLAN_LF_TIMER_STATUS1_INTERRUPT_SET(x)   (((x) << WLAN_LF_TIMER_STATUS1_INTERRUPT_LSB) & WLAN_LF_TIMER_STATUS1_INTERRUPT_MASK)
-
-#define WLAN_LF_TIMER2_ADDRESS                   0x00000068
-#define WLAN_LF_TIMER2_OFFSET                    0x00000068
-#define WLAN_LF_TIMER2_TARGET_MSB                31
-#define WLAN_LF_TIMER2_TARGET_LSB                0
-#define WLAN_LF_TIMER2_TARGET_MASK               0xffffffff
-#define WLAN_LF_TIMER2_TARGET_GET(x)             (((x) & WLAN_LF_TIMER2_TARGET_MASK) >> WLAN_LF_TIMER2_TARGET_LSB)
-#define WLAN_LF_TIMER2_TARGET_SET(x)             (((x) << WLAN_LF_TIMER2_TARGET_LSB) & WLAN_LF_TIMER2_TARGET_MASK)
-
-#define WLAN_LF_TIMER_COUNT2_ADDRESS             0x0000006c
-#define WLAN_LF_TIMER_COUNT2_OFFSET              0x0000006c
-#define WLAN_LF_TIMER_COUNT2_VALUE_MSB           31
-#define WLAN_LF_TIMER_COUNT2_VALUE_LSB           0
-#define WLAN_LF_TIMER_COUNT2_VALUE_MASK          0xffffffff
-#define WLAN_LF_TIMER_COUNT2_VALUE_GET(x)        (((x) & WLAN_LF_TIMER_COUNT2_VALUE_MASK) >> WLAN_LF_TIMER_COUNT2_VALUE_LSB)
-#define WLAN_LF_TIMER_COUNT2_VALUE_SET(x)        (((x) << WLAN_LF_TIMER_COUNT2_VALUE_LSB) & WLAN_LF_TIMER_COUNT2_VALUE_MASK)
-
-#define WLAN_LF_TIMER_CONTROL2_ADDRESS           0x00000070
-#define WLAN_LF_TIMER_CONTROL2_OFFSET            0x00000070
-#define WLAN_LF_TIMER_CONTROL2_ENABLE_MSB        2
-#define WLAN_LF_TIMER_CONTROL2_ENABLE_LSB        2
-#define WLAN_LF_TIMER_CONTROL2_ENABLE_MASK       0x00000004
-#define WLAN_LF_TIMER_CONTROL2_ENABLE_GET(x)     (((x) & WLAN_LF_TIMER_CONTROL2_ENABLE_MASK) >> WLAN_LF_TIMER_CONTROL2_ENABLE_LSB)
-#define WLAN_LF_TIMER_CONTROL2_ENABLE_SET(x)     (((x) << WLAN_LF_TIMER_CONTROL2_ENABLE_LSB) & WLAN_LF_TIMER_CONTROL2_ENABLE_MASK)
-#define WLAN_LF_TIMER_CONTROL2_AUTO_RESTART_MSB  1
-#define WLAN_LF_TIMER_CONTROL2_AUTO_RESTART_LSB  1
-#define WLAN_LF_TIMER_CONTROL2_AUTO_RESTART_MASK 0x00000002
-#define WLAN_LF_TIMER_CONTROL2_AUTO_RESTART_GET(x) (((x) & WLAN_LF_TIMER_CONTROL2_AUTO_RESTART_MASK) >> WLAN_LF_TIMER_CONTROL2_AUTO_RESTART_LSB)
-#define WLAN_LF_TIMER_CONTROL2_AUTO_RESTART_SET(x) (((x) << WLAN_LF_TIMER_CONTROL2_AUTO_RESTART_LSB) & WLAN_LF_TIMER_CONTROL2_AUTO_RESTART_MASK)
-#define WLAN_LF_TIMER_CONTROL2_RESET_MSB         0
-#define WLAN_LF_TIMER_CONTROL2_RESET_LSB         0
-#define WLAN_LF_TIMER_CONTROL2_RESET_MASK        0x00000001
-#define WLAN_LF_TIMER_CONTROL2_RESET_GET(x)      (((x) & WLAN_LF_TIMER_CONTROL2_RESET_MASK) >> WLAN_LF_TIMER_CONTROL2_RESET_LSB)
-#define WLAN_LF_TIMER_CONTROL2_RESET_SET(x)      (((x) << WLAN_LF_TIMER_CONTROL2_RESET_LSB) & WLAN_LF_TIMER_CONTROL2_RESET_MASK)
-
-#define WLAN_LF_TIMER_STATUS2_ADDRESS            0x00000074
-#define WLAN_LF_TIMER_STATUS2_OFFSET             0x00000074
-#define WLAN_LF_TIMER_STATUS2_INTERRUPT_MSB      0
-#define WLAN_LF_TIMER_STATUS2_INTERRUPT_LSB      0
-#define WLAN_LF_TIMER_STATUS2_INTERRUPT_MASK     0x00000001
-#define WLAN_LF_TIMER_STATUS2_INTERRUPT_GET(x)   (((x) & WLAN_LF_TIMER_STATUS2_INTERRUPT_MASK) >> WLAN_LF_TIMER_STATUS2_INTERRUPT_LSB)
-#define WLAN_LF_TIMER_STATUS2_INTERRUPT_SET(x)   (((x) << WLAN_LF_TIMER_STATUS2_INTERRUPT_LSB) & WLAN_LF_TIMER_STATUS2_INTERRUPT_MASK)
-
-#define WLAN_LF_TIMER3_ADDRESS                   0x00000078
-#define WLAN_LF_TIMER3_OFFSET                    0x00000078
-#define WLAN_LF_TIMER3_TARGET_MSB                31
-#define WLAN_LF_TIMER3_TARGET_LSB                0
-#define WLAN_LF_TIMER3_TARGET_MASK               0xffffffff
-#define WLAN_LF_TIMER3_TARGET_GET(x)             (((x) & WLAN_LF_TIMER3_TARGET_MASK) >> WLAN_LF_TIMER3_TARGET_LSB)
-#define WLAN_LF_TIMER3_TARGET_SET(x)             (((x) << WLAN_LF_TIMER3_TARGET_LSB) & WLAN_LF_TIMER3_TARGET_MASK)
-
-#define WLAN_LF_TIMER_COUNT3_ADDRESS             0x0000007c
-#define WLAN_LF_TIMER_COUNT3_OFFSET              0x0000007c
-#define WLAN_LF_TIMER_COUNT3_VALUE_MSB           31
-#define WLAN_LF_TIMER_COUNT3_VALUE_LSB           0
-#define WLAN_LF_TIMER_COUNT3_VALUE_MASK          0xffffffff
-#define WLAN_LF_TIMER_COUNT3_VALUE_GET(x)        (((x) & WLAN_LF_TIMER_COUNT3_VALUE_MASK) >> WLAN_LF_TIMER_COUNT3_VALUE_LSB)
-#define WLAN_LF_TIMER_COUNT3_VALUE_SET(x)        (((x) << WLAN_LF_TIMER_COUNT3_VALUE_LSB) & WLAN_LF_TIMER_COUNT3_VALUE_MASK)
-
-#define WLAN_LF_TIMER_CONTROL3_ADDRESS           0x00000080
-#define WLAN_LF_TIMER_CONTROL3_OFFSET            0x00000080
-#define WLAN_LF_TIMER_CONTROL3_ENABLE_MSB        2
-#define WLAN_LF_TIMER_CONTROL3_ENABLE_LSB        2
-#define WLAN_LF_TIMER_CONTROL3_ENABLE_MASK       0x00000004
-#define WLAN_LF_TIMER_CONTROL3_ENABLE_GET(x)     (((x) & WLAN_LF_TIMER_CONTROL3_ENABLE_MASK) >> WLAN_LF_TIMER_CONTROL3_ENABLE_LSB)
-#define WLAN_LF_TIMER_CONTROL3_ENABLE_SET(x)     (((x) << WLAN_LF_TIMER_CONTROL3_ENABLE_LSB) & WLAN_LF_TIMER_CONTROL3_ENABLE_MASK)
-#define WLAN_LF_TIMER_CONTROL3_AUTO_RESTART_MSB  1
-#define WLAN_LF_TIMER_CONTROL3_AUTO_RESTART_LSB  1
-#define WLAN_LF_TIMER_CONTROL3_AUTO_RESTART_MASK 0x00000002
-#define WLAN_LF_TIMER_CONTROL3_AUTO_RESTART_GET(x) (((x) & WLAN_LF_TIMER_CONTROL3_AUTO_RESTART_MASK) >> WLAN_LF_TIMER_CONTROL3_AUTO_RESTART_LSB)
-#define WLAN_LF_TIMER_CONTROL3_AUTO_RESTART_SET(x) (((x) << WLAN_LF_TIMER_CONTROL3_AUTO_RESTART_LSB) & WLAN_LF_TIMER_CONTROL3_AUTO_RESTART_MASK)
-#define WLAN_LF_TIMER_CONTROL3_RESET_MSB         0
-#define WLAN_LF_TIMER_CONTROL3_RESET_LSB         0
-#define WLAN_LF_TIMER_CONTROL3_RESET_MASK        0x00000001
-#define WLAN_LF_TIMER_CONTROL3_RESET_GET(x)      (((x) & WLAN_LF_TIMER_CONTROL3_RESET_MASK) >> WLAN_LF_TIMER_CONTROL3_RESET_LSB)
-#define WLAN_LF_TIMER_CONTROL3_RESET_SET(x)      (((x) << WLAN_LF_TIMER_CONTROL3_RESET_LSB) & WLAN_LF_TIMER_CONTROL3_RESET_MASK)
-
-#define WLAN_LF_TIMER_STATUS3_ADDRESS            0x00000084
-#define WLAN_LF_TIMER_STATUS3_OFFSET             0x00000084
-#define WLAN_LF_TIMER_STATUS3_INTERRUPT_MSB      0
-#define WLAN_LF_TIMER_STATUS3_INTERRUPT_LSB      0
-#define WLAN_LF_TIMER_STATUS3_INTERRUPT_MASK     0x00000001
-#define WLAN_LF_TIMER_STATUS3_INTERRUPT_GET(x)   (((x) & WLAN_LF_TIMER_STATUS3_INTERRUPT_MASK) >> WLAN_LF_TIMER_STATUS3_INTERRUPT_LSB)
-#define WLAN_LF_TIMER_STATUS3_INTERRUPT_SET(x)   (((x) << WLAN_LF_TIMER_STATUS3_INTERRUPT_LSB) & WLAN_LF_TIMER_STATUS3_INTERRUPT_MASK)
-
-#define WLAN_HF_TIMER_ADDRESS                    0x00000088
-#define WLAN_HF_TIMER_OFFSET                     0x00000088
-#define WLAN_HF_TIMER_TARGET_MSB                 31
-#define WLAN_HF_TIMER_TARGET_LSB                 12
-#define WLAN_HF_TIMER_TARGET_MASK                0xfffff000
-#define WLAN_HF_TIMER_TARGET_GET(x)              (((x) & WLAN_HF_TIMER_TARGET_MASK) >> WLAN_HF_TIMER_TARGET_LSB)
-#define WLAN_HF_TIMER_TARGET_SET(x)              (((x) << WLAN_HF_TIMER_TARGET_LSB) & WLAN_HF_TIMER_TARGET_MASK)
-
-#define WLAN_HF_TIMER_COUNT_ADDRESS              0x0000008c
-#define WLAN_HF_TIMER_COUNT_OFFSET               0x0000008c
-#define WLAN_HF_TIMER_COUNT_VALUE_MSB            31
-#define WLAN_HF_TIMER_COUNT_VALUE_LSB            12
-#define WLAN_HF_TIMER_COUNT_VALUE_MASK           0xfffff000
-#define WLAN_HF_TIMER_COUNT_VALUE_GET(x)         (((x) & WLAN_HF_TIMER_COUNT_VALUE_MASK) >> WLAN_HF_TIMER_COUNT_VALUE_LSB)
-#define WLAN_HF_TIMER_COUNT_VALUE_SET(x)         (((x) << WLAN_HF_TIMER_COUNT_VALUE_LSB) & WLAN_HF_TIMER_COUNT_VALUE_MASK)
-
-#define WLAN_HF_LF_COUNT_ADDRESS                 0x00000090
-#define WLAN_HF_LF_COUNT_OFFSET                  0x00000090
-#define WLAN_HF_LF_COUNT_VALUE_MSB               31
-#define WLAN_HF_LF_COUNT_VALUE_LSB               0
-#define WLAN_HF_LF_COUNT_VALUE_MASK              0xffffffff
-#define WLAN_HF_LF_COUNT_VALUE_GET(x)            (((x) & WLAN_HF_LF_COUNT_VALUE_MASK) >> WLAN_HF_LF_COUNT_VALUE_LSB)
-#define WLAN_HF_LF_COUNT_VALUE_SET(x)            (((x) << WLAN_HF_LF_COUNT_VALUE_LSB) & WLAN_HF_LF_COUNT_VALUE_MASK)
-
-#define WLAN_HF_TIMER_CONTROL_ADDRESS            0x00000094
-#define WLAN_HF_TIMER_CONTROL_OFFSET             0x00000094
-#define WLAN_HF_TIMER_CONTROL_ENABLE_MSB         3
-#define WLAN_HF_TIMER_CONTROL_ENABLE_LSB         3
-#define WLAN_HF_TIMER_CONTROL_ENABLE_MASK        0x00000008
-#define WLAN_HF_TIMER_CONTROL_ENABLE_GET(x)      (((x) & WLAN_HF_TIMER_CONTROL_ENABLE_MASK) >> WLAN_HF_TIMER_CONTROL_ENABLE_LSB)
-#define WLAN_HF_TIMER_CONTROL_ENABLE_SET(x)      (((x) << WLAN_HF_TIMER_CONTROL_ENABLE_LSB) & WLAN_HF_TIMER_CONTROL_ENABLE_MASK)
-#define WLAN_HF_TIMER_CONTROL_ON_MSB             2
-#define WLAN_HF_TIMER_CONTROL_ON_LSB             2
-#define WLAN_HF_TIMER_CONTROL_ON_MASK            0x00000004
-#define WLAN_HF_TIMER_CONTROL_ON_GET(x)          (((x) & WLAN_HF_TIMER_CONTROL_ON_MASK) >> WLAN_HF_TIMER_CONTROL_ON_LSB)
-#define WLAN_HF_TIMER_CONTROL_ON_SET(x)          (((x) << WLAN_HF_TIMER_CONTROL_ON_LSB) & WLAN_HF_TIMER_CONTROL_ON_MASK)
-#define WLAN_HF_TIMER_CONTROL_AUTO_RESTART_MSB   1
-#define WLAN_HF_TIMER_CONTROL_AUTO_RESTART_LSB   1
-#define WLAN_HF_TIMER_CONTROL_AUTO_RESTART_MASK  0x00000002
-#define WLAN_HF_TIMER_CONTROL_AUTO_RESTART_GET(x) (((x) & WLAN_HF_TIMER_CONTROL_AUTO_RESTART_MASK) >> WLAN_HF_TIMER_CONTROL_AUTO_RESTART_LSB)
-#define WLAN_HF_TIMER_CONTROL_AUTO_RESTART_SET(x) (((x) << WLAN_HF_TIMER_CONTROL_AUTO_RESTART_LSB) & WLAN_HF_TIMER_CONTROL_AUTO_RESTART_MASK)
-#define WLAN_HF_TIMER_CONTROL_RESET_MSB          0
-#define WLAN_HF_TIMER_CONTROL_RESET_LSB          0
-#define WLAN_HF_TIMER_CONTROL_RESET_MASK         0x00000001
-#define WLAN_HF_TIMER_CONTROL_RESET_GET(x)       (((x) & WLAN_HF_TIMER_CONTROL_RESET_MASK) >> WLAN_HF_TIMER_CONTROL_RESET_LSB)
-#define WLAN_HF_TIMER_CONTROL_RESET_SET(x)       (((x) << WLAN_HF_TIMER_CONTROL_RESET_LSB) & WLAN_HF_TIMER_CONTROL_RESET_MASK)
-
-#define WLAN_HF_TIMER_STATUS_ADDRESS             0x00000098
-#define WLAN_HF_TIMER_STATUS_OFFSET              0x00000098
-#define WLAN_HF_TIMER_STATUS_INTERRUPT_MSB       0
-#define WLAN_HF_TIMER_STATUS_INTERRUPT_LSB       0
-#define WLAN_HF_TIMER_STATUS_INTERRUPT_MASK      0x00000001
-#define WLAN_HF_TIMER_STATUS_INTERRUPT_GET(x)    (((x) & WLAN_HF_TIMER_STATUS_INTERRUPT_MASK) >> WLAN_HF_TIMER_STATUS_INTERRUPT_LSB)
-#define WLAN_HF_TIMER_STATUS_INTERRUPT_SET(x)    (((x) << WLAN_HF_TIMER_STATUS_INTERRUPT_LSB) & WLAN_HF_TIMER_STATUS_INTERRUPT_MASK)
-
-#define WLAN_RTC_CONTROL_ADDRESS                 0x0000009c
-#define WLAN_RTC_CONTROL_OFFSET                  0x0000009c
-#define WLAN_RTC_CONTROL_ENABLE_MSB              2
-#define WLAN_RTC_CONTROL_ENABLE_LSB              2
-#define WLAN_RTC_CONTROL_ENABLE_MASK             0x00000004
-#define WLAN_RTC_CONTROL_ENABLE_GET(x)           (((x) & WLAN_RTC_CONTROL_ENABLE_MASK) >> WLAN_RTC_CONTROL_ENABLE_LSB)
-#define WLAN_RTC_CONTROL_ENABLE_SET(x)           (((x) << WLAN_RTC_CONTROL_ENABLE_LSB) & WLAN_RTC_CONTROL_ENABLE_MASK)
-#define WLAN_RTC_CONTROL_LOAD_RTC_MSB            1
-#define WLAN_RTC_CONTROL_LOAD_RTC_LSB            1
-#define WLAN_RTC_CONTROL_LOAD_RTC_MASK           0x00000002
-#define WLAN_RTC_CONTROL_LOAD_RTC_GET(x)         (((x) & WLAN_RTC_CONTROL_LOAD_RTC_MASK) >> WLAN_RTC_CONTROL_LOAD_RTC_LSB)
-#define WLAN_RTC_CONTROL_LOAD_RTC_SET(x)         (((x) << WLAN_RTC_CONTROL_LOAD_RTC_LSB) & WLAN_RTC_CONTROL_LOAD_RTC_MASK)
-#define WLAN_RTC_CONTROL_LOAD_ALARM_MSB          0
-#define WLAN_RTC_CONTROL_LOAD_ALARM_LSB          0
-#define WLAN_RTC_CONTROL_LOAD_ALARM_MASK         0x00000001
-#define WLAN_RTC_CONTROL_LOAD_ALARM_GET(x)       (((x) & WLAN_RTC_CONTROL_LOAD_ALARM_MASK) >> WLAN_RTC_CONTROL_LOAD_ALARM_LSB)
-#define WLAN_RTC_CONTROL_LOAD_ALARM_SET(x)       (((x) << WLAN_RTC_CONTROL_LOAD_ALARM_LSB) & WLAN_RTC_CONTROL_LOAD_ALARM_MASK)
-
-#define WLAN_RTC_TIME_ADDRESS                    0x000000a0
-#define WLAN_RTC_TIME_OFFSET                     0x000000a0
-#define WLAN_RTC_TIME_WEEK_DAY_MSB               26
-#define WLAN_RTC_TIME_WEEK_DAY_LSB               24
-#define WLAN_RTC_TIME_WEEK_DAY_MASK              0x07000000
-#define WLAN_RTC_TIME_WEEK_DAY_GET(x)            (((x) & WLAN_RTC_TIME_WEEK_DAY_MASK) >> WLAN_RTC_TIME_WEEK_DAY_LSB)
-#define WLAN_RTC_TIME_WEEK_DAY_SET(x)            (((x) << WLAN_RTC_TIME_WEEK_DAY_LSB) & WLAN_RTC_TIME_WEEK_DAY_MASK)
-#define WLAN_RTC_TIME_HOUR_MSB                   21
-#define WLAN_RTC_TIME_HOUR_LSB                   16
-#define WLAN_RTC_TIME_HOUR_MASK                  0x003f0000
-#define WLAN_RTC_TIME_HOUR_GET(x)                (((x) & WLAN_RTC_TIME_HOUR_MASK) >> WLAN_RTC_TIME_HOUR_LSB)
-#define WLAN_RTC_TIME_HOUR_SET(x)                (((x) << WLAN_RTC_TIME_HOUR_LSB) & WLAN_RTC_TIME_HOUR_MASK)
-#define WLAN_RTC_TIME_MINUTE_MSB                 14
-#define WLAN_RTC_TIME_MINUTE_LSB                 8
-#define WLAN_RTC_TIME_MINUTE_MASK                0x00007f00
-#define WLAN_RTC_TIME_MINUTE_GET(x)              (((x) & WLAN_RTC_TIME_MINUTE_MASK) >> WLAN_RTC_TIME_MINUTE_LSB)
-#define WLAN_RTC_TIME_MINUTE_SET(x)              (((x) << WLAN_RTC_TIME_MINUTE_LSB) & WLAN_RTC_TIME_MINUTE_MASK)
-#define WLAN_RTC_TIME_SECOND_MSB                 6
-#define WLAN_RTC_TIME_SECOND_LSB                 0
-#define WLAN_RTC_TIME_SECOND_MASK                0x0000007f
-#define WLAN_RTC_TIME_SECOND_GET(x)              (((x) & WLAN_RTC_TIME_SECOND_MASK) >> WLAN_RTC_TIME_SECOND_LSB)
-#define WLAN_RTC_TIME_SECOND_SET(x)              (((x) << WLAN_RTC_TIME_SECOND_LSB) & WLAN_RTC_TIME_SECOND_MASK)
-
-#define WLAN_RTC_DATE_ADDRESS                    0x000000a4
-#define WLAN_RTC_DATE_OFFSET                     0x000000a4
-#define WLAN_RTC_DATE_YEAR_MSB                   23
-#define WLAN_RTC_DATE_YEAR_LSB                   16
-#define WLAN_RTC_DATE_YEAR_MASK                  0x00ff0000
-#define WLAN_RTC_DATE_YEAR_GET(x)                (((x) & WLAN_RTC_DATE_YEAR_MASK) >> WLAN_RTC_DATE_YEAR_LSB)
-#define WLAN_RTC_DATE_YEAR_SET(x)                (((x) << WLAN_RTC_DATE_YEAR_LSB) & WLAN_RTC_DATE_YEAR_MASK)
-#define WLAN_RTC_DATE_MONTH_MSB                  12
-#define WLAN_RTC_DATE_MONTH_LSB                  8
-#define WLAN_RTC_DATE_MONTH_MASK                 0x00001f00
-#define WLAN_RTC_DATE_MONTH_GET(x)               (((x) & WLAN_RTC_DATE_MONTH_MASK) >> WLAN_RTC_DATE_MONTH_LSB)
-#define WLAN_RTC_DATE_MONTH_SET(x)               (((x) << WLAN_RTC_DATE_MONTH_LSB) & WLAN_RTC_DATE_MONTH_MASK)
-#define WLAN_RTC_DATE_MONTH_DAY_MSB              5
-#define WLAN_RTC_DATE_MONTH_DAY_LSB              0
-#define WLAN_RTC_DATE_MONTH_DAY_MASK             0x0000003f
-#define WLAN_RTC_DATE_MONTH_DAY_GET(x)           (((x) & WLAN_RTC_DATE_MONTH_DAY_MASK) >> WLAN_RTC_DATE_MONTH_DAY_LSB)
-#define WLAN_RTC_DATE_MONTH_DAY_SET(x)           (((x) << WLAN_RTC_DATE_MONTH_DAY_LSB) & WLAN_RTC_DATE_MONTH_DAY_MASK)
-
-#define WLAN_RTC_SET_TIME_ADDRESS                0x000000a8
-#define WLAN_RTC_SET_TIME_OFFSET                 0x000000a8
-#define WLAN_RTC_SET_TIME_WEEK_DAY_MSB           26
-#define WLAN_RTC_SET_TIME_WEEK_DAY_LSB           24
-#define WLAN_RTC_SET_TIME_WEEK_DAY_MASK          0x07000000
-#define WLAN_RTC_SET_TIME_WEEK_DAY_GET(x)        (((x) & WLAN_RTC_SET_TIME_WEEK_DAY_MASK) >> WLAN_RTC_SET_TIME_WEEK_DAY_LSB)
-#define WLAN_RTC_SET_TIME_WEEK_DAY_SET(x)        (((x) << WLAN_RTC_SET_TIME_WEEK_DAY_LSB) & WLAN_RTC_SET_TIME_WEEK_DAY_MASK)
-#define WLAN_RTC_SET_TIME_HOUR_MSB               21
-#define WLAN_RTC_SET_TIME_HOUR_LSB               16
-#define WLAN_RTC_SET_TIME_HOUR_MASK              0x003f0000
-#define WLAN_RTC_SET_TIME_HOUR_GET(x)            (((x) & WLAN_RTC_SET_TIME_HOUR_MASK) >> WLAN_RTC_SET_TIME_HOUR_LSB)
-#define WLAN_RTC_SET_TIME_HOUR_SET(x)            (((x) << WLAN_RTC_SET_TIME_HOUR_LSB) & WLAN_RTC_SET_TIME_HOUR_MASK)
-#define WLAN_RTC_SET_TIME_MINUTE_MSB             14
-#define WLAN_RTC_SET_TIME_MINUTE_LSB             8
-#define WLAN_RTC_SET_TIME_MINUTE_MASK            0x00007f00
-#define WLAN_RTC_SET_TIME_MINUTE_GET(x)          (((x) & WLAN_RTC_SET_TIME_MINUTE_MASK) >> WLAN_RTC_SET_TIME_MINUTE_LSB)
-#define WLAN_RTC_SET_TIME_MINUTE_SET(x)          (((x) << WLAN_RTC_SET_TIME_MINUTE_LSB) & WLAN_RTC_SET_TIME_MINUTE_MASK)
-#define WLAN_RTC_SET_TIME_SECOND_MSB             6
-#define WLAN_RTC_SET_TIME_SECOND_LSB             0
-#define WLAN_RTC_SET_TIME_SECOND_MASK            0x0000007f
-#define WLAN_RTC_SET_TIME_SECOND_GET(x)          (((x) & WLAN_RTC_SET_TIME_SECOND_MASK) >> WLAN_RTC_SET_TIME_SECOND_LSB)
-#define WLAN_RTC_SET_TIME_SECOND_SET(x)          (((x) << WLAN_RTC_SET_TIME_SECOND_LSB) & WLAN_RTC_SET_TIME_SECOND_MASK)
-
-#define WLAN_RTC_SET_DATE_ADDRESS                0x000000ac
-#define WLAN_RTC_SET_DATE_OFFSET                 0x000000ac
-#define WLAN_RTC_SET_DATE_YEAR_MSB               23
-#define WLAN_RTC_SET_DATE_YEAR_LSB               16
-#define WLAN_RTC_SET_DATE_YEAR_MASK              0x00ff0000
-#define WLAN_RTC_SET_DATE_YEAR_GET(x)            (((x) & WLAN_RTC_SET_DATE_YEAR_MASK) >> WLAN_RTC_SET_DATE_YEAR_LSB)
-#define WLAN_RTC_SET_DATE_YEAR_SET(x)            (((x) << WLAN_RTC_SET_DATE_YEAR_LSB) & WLAN_RTC_SET_DATE_YEAR_MASK)
-#define WLAN_RTC_SET_DATE_MONTH_MSB              12
-#define WLAN_RTC_SET_DATE_MONTH_LSB              8
-#define WLAN_RTC_SET_DATE_MONTH_MASK             0x00001f00
-#define WLAN_RTC_SET_DATE_MONTH_GET(x)           (((x) & WLAN_RTC_SET_DATE_MONTH_MASK) >> WLAN_RTC_SET_DATE_MONTH_LSB)
-#define WLAN_RTC_SET_DATE_MONTH_SET(x)           (((x) << WLAN_RTC_SET_DATE_MONTH_LSB) & WLAN_RTC_SET_DATE_MONTH_MASK)
-#define WLAN_RTC_SET_DATE_MONTH_DAY_MSB          5
-#define WLAN_RTC_SET_DATE_MONTH_DAY_LSB          0
-#define WLAN_RTC_SET_DATE_MONTH_DAY_MASK         0x0000003f
-#define WLAN_RTC_SET_DATE_MONTH_DAY_GET(x)       (((x) & WLAN_RTC_SET_DATE_MONTH_DAY_MASK) >> WLAN_RTC_SET_DATE_MONTH_DAY_LSB)
-#define WLAN_RTC_SET_DATE_MONTH_DAY_SET(x)       (((x) << WLAN_RTC_SET_DATE_MONTH_DAY_LSB) & WLAN_RTC_SET_DATE_MONTH_DAY_MASK)
-
-#define WLAN_RTC_SET_ALARM_ADDRESS               0x000000b0
-#define WLAN_RTC_SET_ALARM_OFFSET                0x000000b0
-#define WLAN_RTC_SET_ALARM_HOUR_MSB              21
-#define WLAN_RTC_SET_ALARM_HOUR_LSB              16
-#define WLAN_RTC_SET_ALARM_HOUR_MASK             0x003f0000
-#define WLAN_RTC_SET_ALARM_HOUR_GET(x)           (((x) & WLAN_RTC_SET_ALARM_HOUR_MASK) >> WLAN_RTC_SET_ALARM_HOUR_LSB)
-#define WLAN_RTC_SET_ALARM_HOUR_SET(x)           (((x) << WLAN_RTC_SET_ALARM_HOUR_LSB) & WLAN_RTC_SET_ALARM_HOUR_MASK)
-#define WLAN_RTC_SET_ALARM_MINUTE_MSB            14
-#define WLAN_RTC_SET_ALARM_MINUTE_LSB            8
-#define WLAN_RTC_SET_ALARM_MINUTE_MASK           0x00007f00
-#define WLAN_RTC_SET_ALARM_MINUTE_GET(x)         (((x) & WLAN_RTC_SET_ALARM_MINUTE_MASK) >> WLAN_RTC_SET_ALARM_MINUTE_LSB)
-#define WLAN_RTC_SET_ALARM_MINUTE_SET(x)         (((x) << WLAN_RTC_SET_ALARM_MINUTE_LSB) & WLAN_RTC_SET_ALARM_MINUTE_MASK)
-#define WLAN_RTC_SET_ALARM_SECOND_MSB            6
-#define WLAN_RTC_SET_ALARM_SECOND_LSB            0
-#define WLAN_RTC_SET_ALARM_SECOND_MASK           0x0000007f
-#define WLAN_RTC_SET_ALARM_SECOND_GET(x)         (((x) & WLAN_RTC_SET_ALARM_SECOND_MASK) >> WLAN_RTC_SET_ALARM_SECOND_LSB)
-#define WLAN_RTC_SET_ALARM_SECOND_SET(x)         (((x) << WLAN_RTC_SET_ALARM_SECOND_LSB) & WLAN_RTC_SET_ALARM_SECOND_MASK)
-
-#define WLAN_RTC_CONFIG_ADDRESS                  0x000000b4
-#define WLAN_RTC_CONFIG_OFFSET                   0x000000b4
-#define WLAN_RTC_CONFIG_BCD_MSB                  2
-#define WLAN_RTC_CONFIG_BCD_LSB                  2
-#define WLAN_RTC_CONFIG_BCD_MASK                 0x00000004
-#define WLAN_RTC_CONFIG_BCD_GET(x)               (((x) & WLAN_RTC_CONFIG_BCD_MASK) >> WLAN_RTC_CONFIG_BCD_LSB)
-#define WLAN_RTC_CONFIG_BCD_SET(x)               (((x) << WLAN_RTC_CONFIG_BCD_LSB) & WLAN_RTC_CONFIG_BCD_MASK)
-#define WLAN_RTC_CONFIG_TWELVE_HOUR_MSB          1
-#define WLAN_RTC_CONFIG_TWELVE_HOUR_LSB          1
-#define WLAN_RTC_CONFIG_TWELVE_HOUR_MASK         0x00000002
-#define WLAN_RTC_CONFIG_TWELVE_HOUR_GET(x)       (((x) & WLAN_RTC_CONFIG_TWELVE_HOUR_MASK) >> WLAN_RTC_CONFIG_TWELVE_HOUR_LSB)
-#define WLAN_RTC_CONFIG_TWELVE_HOUR_SET(x)       (((x) << WLAN_RTC_CONFIG_TWELVE_HOUR_LSB) & WLAN_RTC_CONFIG_TWELVE_HOUR_MASK)
-#define WLAN_RTC_CONFIG_DSE_MSB                  0
-#define WLAN_RTC_CONFIG_DSE_LSB                  0
-#define WLAN_RTC_CONFIG_DSE_MASK                 0x00000001
-#define WLAN_RTC_CONFIG_DSE_GET(x)               (((x) & WLAN_RTC_CONFIG_DSE_MASK) >> WLAN_RTC_CONFIG_DSE_LSB)
-#define WLAN_RTC_CONFIG_DSE_SET(x)               (((x) << WLAN_RTC_CONFIG_DSE_LSB) & WLAN_RTC_CONFIG_DSE_MASK)
-
-#define WLAN_RTC_ALARM_STATUS_ADDRESS            0x000000b8
-#define WLAN_RTC_ALARM_STATUS_OFFSET             0x000000b8
-#define WLAN_RTC_ALARM_STATUS_ENABLE_MSB         1
-#define WLAN_RTC_ALARM_STATUS_ENABLE_LSB         1
-#define WLAN_RTC_ALARM_STATUS_ENABLE_MASK        0x00000002
-#define WLAN_RTC_ALARM_STATUS_ENABLE_GET(x)      (((x) & WLAN_RTC_ALARM_STATUS_ENABLE_MASK) >> WLAN_RTC_ALARM_STATUS_ENABLE_LSB)
-#define WLAN_RTC_ALARM_STATUS_ENABLE_SET(x)      (((x) << WLAN_RTC_ALARM_STATUS_ENABLE_LSB) & WLAN_RTC_ALARM_STATUS_ENABLE_MASK)
-#define WLAN_RTC_ALARM_STATUS_INTERRUPT_MSB      0
-#define WLAN_RTC_ALARM_STATUS_INTERRUPT_LSB      0
-#define WLAN_RTC_ALARM_STATUS_INTERRUPT_MASK     0x00000001
-#define WLAN_RTC_ALARM_STATUS_INTERRUPT_GET(x)   (((x) & WLAN_RTC_ALARM_STATUS_INTERRUPT_MASK) >> WLAN_RTC_ALARM_STATUS_INTERRUPT_LSB)
-#define WLAN_RTC_ALARM_STATUS_INTERRUPT_SET(x)   (((x) << WLAN_RTC_ALARM_STATUS_INTERRUPT_LSB) & WLAN_RTC_ALARM_STATUS_INTERRUPT_MASK)
-
-#define WLAN_UART_WAKEUP_ADDRESS                 0x000000bc
-#define WLAN_UART_WAKEUP_OFFSET                  0x000000bc
-#define WLAN_UART_WAKEUP_ENABLE_MSB              0
-#define WLAN_UART_WAKEUP_ENABLE_LSB              0
-#define WLAN_UART_WAKEUP_ENABLE_MASK             0x00000001
-#define WLAN_UART_WAKEUP_ENABLE_GET(x)           (((x) & WLAN_UART_WAKEUP_ENABLE_MASK) >> WLAN_UART_WAKEUP_ENABLE_LSB)
-#define WLAN_UART_WAKEUP_ENABLE_SET(x)           (((x) << WLAN_UART_WAKEUP_ENABLE_LSB) & WLAN_UART_WAKEUP_ENABLE_MASK)
-
-#define WLAN_RESET_CAUSE_ADDRESS                 0x000000c0
-#define WLAN_RESET_CAUSE_OFFSET                  0x000000c0
-#define WLAN_RESET_CAUSE_LAST_MSB                2
-#define WLAN_RESET_CAUSE_LAST_LSB                0
-#define WLAN_RESET_CAUSE_LAST_MASK               0x00000007
-#define WLAN_RESET_CAUSE_LAST_GET(x)             (((x) & WLAN_RESET_CAUSE_LAST_MASK) >> WLAN_RESET_CAUSE_LAST_LSB)
-#define WLAN_RESET_CAUSE_LAST_SET(x)             (((x) << WLAN_RESET_CAUSE_LAST_LSB) & WLAN_RESET_CAUSE_LAST_MASK)
-
 #define WLAN_SYSTEM_SLEEP_ADDRESS                0x000000c4
 #define WLAN_SYSTEM_SLEEP_OFFSET                 0x000000c4
 #define WLAN_SYSTEM_SLEEP_HOST_IF_MSB            4
@@ -799,69 +146,6 @@
 #define WLAN_SYSTEM_SLEEP_DISABLE_GET(x)         (((x) & WLAN_SYSTEM_SLEEP_DISABLE_MASK) >> WLAN_SYSTEM_SLEEP_DISABLE_LSB)
 #define WLAN_SYSTEM_SLEEP_DISABLE_SET(x)         (((x) << WLAN_SYSTEM_SLEEP_DISABLE_LSB) & WLAN_SYSTEM_SLEEP_DISABLE_MASK)
 
-#define WLAN_SDIO_WRAPPER_ADDRESS                0x000000c8
-#define WLAN_SDIO_WRAPPER_OFFSET                 0x000000c8
-#define WLAN_SDIO_WRAPPER_SLEEP_MSB              3
-#define WLAN_SDIO_WRAPPER_SLEEP_LSB              3
-#define WLAN_SDIO_WRAPPER_SLEEP_MASK             0x00000008
-#define WLAN_SDIO_WRAPPER_SLEEP_GET(x)           (((x) & WLAN_SDIO_WRAPPER_SLEEP_MASK) >> WLAN_SDIO_WRAPPER_SLEEP_LSB)
-#define WLAN_SDIO_WRAPPER_SLEEP_SET(x)           (((x) << WLAN_SDIO_WRAPPER_SLEEP_LSB) & WLAN_SDIO_WRAPPER_SLEEP_MASK)
-#define WLAN_SDIO_WRAPPER_WAKEUP_MSB             2
-#define WLAN_SDIO_WRAPPER_WAKEUP_LSB             2
-#define WLAN_SDIO_WRAPPER_WAKEUP_MASK            0x00000004
-#define WLAN_SDIO_WRAPPER_WAKEUP_GET(x)          (((x) & WLAN_SDIO_WRAPPER_WAKEUP_MASK) >> WLAN_SDIO_WRAPPER_WAKEUP_LSB)
-#define WLAN_SDIO_WRAPPER_WAKEUP_SET(x)          (((x) << WLAN_SDIO_WRAPPER_WAKEUP_LSB) & WLAN_SDIO_WRAPPER_WAKEUP_MASK)
-#define WLAN_SDIO_WRAPPER_SOC_ON_MSB             1
-#define WLAN_SDIO_WRAPPER_SOC_ON_LSB             1
-#define WLAN_SDIO_WRAPPER_SOC_ON_MASK            0x00000002
-#define WLAN_SDIO_WRAPPER_SOC_ON_GET(x)          (((x) & WLAN_SDIO_WRAPPER_SOC_ON_MASK) >> WLAN_SDIO_WRAPPER_SOC_ON_LSB)
-#define WLAN_SDIO_WRAPPER_SOC_ON_SET(x)          (((x) << WLAN_SDIO_WRAPPER_SOC_ON_LSB) & WLAN_SDIO_WRAPPER_SOC_ON_MASK)
-#define WLAN_SDIO_WRAPPER_ON_MSB                 0
-#define WLAN_SDIO_WRAPPER_ON_LSB                 0
-#define WLAN_SDIO_WRAPPER_ON_MASK                0x00000001
-#define WLAN_SDIO_WRAPPER_ON_GET(x)              (((x) & WLAN_SDIO_WRAPPER_ON_MASK) >> WLAN_SDIO_WRAPPER_ON_LSB)
-#define WLAN_SDIO_WRAPPER_ON_SET(x)              (((x) << WLAN_SDIO_WRAPPER_ON_LSB) & WLAN_SDIO_WRAPPER_ON_MASK)
-
-#define WLAN_MAC_SLEEP_CONTROL_ADDRESS           0x000000cc
-#define WLAN_MAC_SLEEP_CONTROL_OFFSET            0x000000cc
-#define WLAN_MAC_SLEEP_CONTROL_ENABLE_MSB        1
-#define WLAN_MAC_SLEEP_CONTROL_ENABLE_LSB        0
-#define WLAN_MAC_SLEEP_CONTROL_ENABLE_MASK       0x00000003
-#define WLAN_MAC_SLEEP_CONTROL_ENABLE_GET(x)     (((x) & WLAN_MAC_SLEEP_CONTROL_ENABLE_MASK) >> WLAN_MAC_SLEEP_CONTROL_ENABLE_LSB)
-#define WLAN_MAC_SLEEP_CONTROL_ENABLE_SET(x)     (((x) << WLAN_MAC_SLEEP_CONTROL_ENABLE_LSB) & WLAN_MAC_SLEEP_CONTROL_ENABLE_MASK)
-
-#define WLAN_KEEP_AWAKE_ADDRESS                  0x000000d0
-#define WLAN_KEEP_AWAKE_OFFSET                   0x000000d0
-#define WLAN_KEEP_AWAKE_COUNT_MSB                7
-#define WLAN_KEEP_AWAKE_COUNT_LSB                0
-#define WLAN_KEEP_AWAKE_COUNT_MASK               0x000000ff
-#define WLAN_KEEP_AWAKE_COUNT_GET(x)             (((x) & WLAN_KEEP_AWAKE_COUNT_MASK) >> WLAN_KEEP_AWAKE_COUNT_LSB)
-#define WLAN_KEEP_AWAKE_COUNT_SET(x)             (((x) << WLAN_KEEP_AWAKE_COUNT_LSB) & WLAN_KEEP_AWAKE_COUNT_MASK)
-
-#define WLAN_LPO_CAL_TIME_ADDRESS                0x000000d4
-#define WLAN_LPO_CAL_TIME_OFFSET                 0x000000d4
-#define WLAN_LPO_CAL_TIME_LENGTH_MSB             13
-#define WLAN_LPO_CAL_TIME_LENGTH_LSB             0
-#define WLAN_LPO_CAL_TIME_LENGTH_MASK            0x00003fff
-#define WLAN_LPO_CAL_TIME_LENGTH_GET(x)          (((x) & WLAN_LPO_CAL_TIME_LENGTH_MASK) >> WLAN_LPO_CAL_TIME_LENGTH_LSB)
-#define WLAN_LPO_CAL_TIME_LENGTH_SET(x)          (((x) << WLAN_LPO_CAL_TIME_LENGTH_LSB) & WLAN_LPO_CAL_TIME_LENGTH_MASK)
-
-#define WLAN_LPO_INIT_DIVIDEND_INT_ADDRESS       0x000000d8
-#define WLAN_LPO_INIT_DIVIDEND_INT_OFFSET        0x000000d8
-#define WLAN_LPO_INIT_DIVIDEND_INT_VALUE_MSB     23
-#define WLAN_LPO_INIT_DIVIDEND_INT_VALUE_LSB     0
-#define WLAN_LPO_INIT_DIVIDEND_INT_VALUE_MASK    0x00ffffff
-#define WLAN_LPO_INIT_DIVIDEND_INT_VALUE_GET(x)  (((x) & WLAN_LPO_INIT_DIVIDEND_INT_VALUE_MASK) >> WLAN_LPO_INIT_DIVIDEND_INT_VALUE_LSB)
-#define WLAN_LPO_INIT_DIVIDEND_INT_VALUE_SET(x)  (((x) << WLAN_LPO_INIT_DIVIDEND_INT_VALUE_LSB) & WLAN_LPO_INIT_DIVIDEND_INT_VALUE_MASK)
-
-#define WLAN_LPO_INIT_DIVIDEND_FRACTION_ADDRESS  0x000000dc
-#define WLAN_LPO_INIT_DIVIDEND_FRACTION_OFFSET   0x000000dc
-#define WLAN_LPO_INIT_DIVIDEND_FRACTION_VALUE_MSB 10
-#define WLAN_LPO_INIT_DIVIDEND_FRACTION_VALUE_LSB 0
-#define WLAN_LPO_INIT_DIVIDEND_FRACTION_VALUE_MASK 0x000007ff
-#define WLAN_LPO_INIT_DIVIDEND_FRACTION_VALUE_GET(x) (((x) & WLAN_LPO_INIT_DIVIDEND_FRACTION_VALUE_MASK) >> WLAN_LPO_INIT_DIVIDEND_FRACTION_VALUE_LSB)
-#define WLAN_LPO_INIT_DIVIDEND_FRACTION_VALUE_SET(x) (((x) << WLAN_LPO_INIT_DIVIDEND_FRACTION_VALUE_LSB) & WLAN_LPO_INIT_DIVIDEND_FRACTION_VALUE_MASK)
-
 #define WLAN_LPO_CAL_ADDRESS                     0x000000e0
 #define WLAN_LPO_CAL_OFFSET                      0x000000e0
 #define WLAN_LPO_CAL_ENABLE_MSB                  20
@@ -875,1191 +159,4 @@
 #define WLAN_LPO_CAL_COUNT_GET(x)                (((x) & WLAN_LPO_CAL_COUNT_MASK) >> WLAN_LPO_CAL_COUNT_LSB)
 #define WLAN_LPO_CAL_COUNT_SET(x)                (((x) << WLAN_LPO_CAL_COUNT_LSB) & WLAN_LPO_CAL_COUNT_MASK)
 
-#define WLAN_LPO_CAL_TEST_CONTROL_ADDRESS        0x000000e4
-#define WLAN_LPO_CAL_TEST_CONTROL_OFFSET         0x000000e4
-#define WLAN_LPO_CAL_TEST_CONTROL_ENABLE_MSB     5
-#define WLAN_LPO_CAL_TEST_CONTROL_ENABLE_LSB     5
-#define WLAN_LPO_CAL_TEST_CONTROL_ENABLE_MASK    0x00000020
-#define WLAN_LPO_CAL_TEST_CONTROL_ENABLE_GET(x)  (((x) & WLAN_LPO_CAL_TEST_CONTROL_ENABLE_MASK) >> WLAN_LPO_CAL_TEST_CONTROL_ENABLE_LSB)
-#define WLAN_LPO_CAL_TEST_CONTROL_ENABLE_SET(x)  (((x) << WLAN_LPO_CAL_TEST_CONTROL_ENABLE_LSB) & WLAN_LPO_CAL_TEST_CONTROL_ENABLE_MASK)
-#define WLAN_LPO_CAL_TEST_CONTROL_RTC_CYCLES_MSB 4
-#define WLAN_LPO_CAL_TEST_CONTROL_RTC_CYCLES_LSB 0
-#define WLAN_LPO_CAL_TEST_CONTROL_RTC_CYCLES_MASK 0x0000001f
-#define WLAN_LPO_CAL_TEST_CONTROL_RTC_CYCLES_GET(x) (((x) & WLAN_LPO_CAL_TEST_CONTROL_RTC_CYCLES_MASK) >> WLAN_LPO_CAL_TEST_CONTROL_RTC_CYCLES_LSB)
-#define WLAN_LPO_CAL_TEST_CONTROL_RTC_CYCLES_SET(x) (((x) << WLAN_LPO_CAL_TEST_CONTROL_RTC_CYCLES_LSB) & WLAN_LPO_CAL_TEST_CONTROL_RTC_CYCLES_MASK)
-
-#define WLAN_LPO_CAL_TEST_STATUS_ADDRESS         0x000000e8
-#define WLAN_LPO_CAL_TEST_STATUS_OFFSET          0x000000e8
-#define WLAN_LPO_CAL_TEST_STATUS_READY_MSB       16
-#define WLAN_LPO_CAL_TEST_STATUS_READY_LSB       16
-#define WLAN_LPO_CAL_TEST_STATUS_READY_MASK      0x00010000
-#define WLAN_LPO_CAL_TEST_STATUS_READY_GET(x)    (((x) & WLAN_LPO_CAL_TEST_STATUS_READY_MASK) >> WLAN_LPO_CAL_TEST_STATUS_READY_LSB)
-#define WLAN_LPO_CAL_TEST_STATUS_READY_SET(x)    (((x) << WLAN_LPO_CAL_TEST_STATUS_READY_LSB) & WLAN_LPO_CAL_TEST_STATUS_READY_MASK)
-#define WLAN_LPO_CAL_TEST_STATUS_COUNT_MSB       15
-#define WLAN_LPO_CAL_TEST_STATUS_COUNT_LSB       0
-#define WLAN_LPO_CAL_TEST_STATUS_COUNT_MASK      0x0000ffff
-#define WLAN_LPO_CAL_TEST_STATUS_COUNT_GET(x)    (((x) & WLAN_LPO_CAL_TEST_STATUS_COUNT_MASK) >> WLAN_LPO_CAL_TEST_STATUS_COUNT_LSB)
-#define WLAN_LPO_CAL_TEST_STATUS_COUNT_SET(x)    (((x) << WLAN_LPO_CAL_TEST_STATUS_COUNT_LSB) & WLAN_LPO_CAL_TEST_STATUS_COUNT_MASK)
-
-#define WLAN_CHIP_ID_ADDRESS                     0x000000ec
-#define WLAN_CHIP_ID_OFFSET                      0x000000ec
-#define WLAN_CHIP_ID_DEVICE_ID_MSB               31
-#define WLAN_CHIP_ID_DEVICE_ID_LSB               16
-#define WLAN_CHIP_ID_DEVICE_ID_MASK              0xffff0000
-#define WLAN_CHIP_ID_DEVICE_ID_GET(x)            (((x) & WLAN_CHIP_ID_DEVICE_ID_MASK) >> WLAN_CHIP_ID_DEVICE_ID_LSB)
-#define WLAN_CHIP_ID_DEVICE_ID_SET(x)            (((x) << WLAN_CHIP_ID_DEVICE_ID_LSB) & WLAN_CHIP_ID_DEVICE_ID_MASK)
-#define WLAN_CHIP_ID_CONFIG_ID_MSB               15
-#define WLAN_CHIP_ID_CONFIG_ID_LSB               4
-#define WLAN_CHIP_ID_CONFIG_ID_MASK              0x0000fff0
-#define WLAN_CHIP_ID_CONFIG_ID_GET(x)            (((x) & WLAN_CHIP_ID_CONFIG_ID_MASK) >> WLAN_CHIP_ID_CONFIG_ID_LSB)
-#define WLAN_CHIP_ID_CONFIG_ID_SET(x)            (((x) << WLAN_CHIP_ID_CONFIG_ID_LSB) & WLAN_CHIP_ID_CONFIG_ID_MASK)
-#define WLAN_CHIP_ID_VERSION_ID_MSB              3
-#define WLAN_CHIP_ID_VERSION_ID_LSB              0
-#define WLAN_CHIP_ID_VERSION_ID_MASK             0x0000000f
-#define WLAN_CHIP_ID_VERSION_ID_GET(x)           (((x) & WLAN_CHIP_ID_VERSION_ID_MASK) >> WLAN_CHIP_ID_VERSION_ID_LSB)
-#define WLAN_CHIP_ID_VERSION_ID_SET(x)           (((x) << WLAN_CHIP_ID_VERSION_ID_LSB) & WLAN_CHIP_ID_VERSION_ID_MASK)
-
-#define WLAN_DERIVED_RTC_CLK_ADDRESS             0x000000f0
-#define WLAN_DERIVED_RTC_CLK_OFFSET              0x000000f0
-#define WLAN_DERIVED_RTC_CLK_EXTERNAL_DETECT_EN_MSB 20
-#define WLAN_DERIVED_RTC_CLK_EXTERNAL_DETECT_EN_LSB 20
-#define WLAN_DERIVED_RTC_CLK_EXTERNAL_DETECT_EN_MASK 0x00100000
-#define WLAN_DERIVED_RTC_CLK_EXTERNAL_DETECT_EN_GET(x) (((x) & WLAN_DERIVED_RTC_CLK_EXTERNAL_DETECT_EN_MASK) >> WLAN_DERIVED_RTC_CLK_EXTERNAL_DETECT_EN_LSB)
-#define WLAN_DERIVED_RTC_CLK_EXTERNAL_DETECT_EN_SET(x) (((x) << WLAN_DERIVED_RTC_CLK_EXTERNAL_DETECT_EN_LSB) & WLAN_DERIVED_RTC_CLK_EXTERNAL_DETECT_EN_MASK)
-#define WLAN_DERIVED_RTC_CLK_EXTERNAL_DETECT_MSB 18
-#define WLAN_DERIVED_RTC_CLK_EXTERNAL_DETECT_LSB 18
-#define WLAN_DERIVED_RTC_CLK_EXTERNAL_DETECT_MASK 0x00040000
-#define WLAN_DERIVED_RTC_CLK_EXTERNAL_DETECT_GET(x) (((x) & WLAN_DERIVED_RTC_CLK_EXTERNAL_DETECT_MASK) >> WLAN_DERIVED_RTC_CLK_EXTERNAL_DETECT_LSB)
-#define WLAN_DERIVED_RTC_CLK_EXTERNAL_DETECT_SET(x) (((x) << WLAN_DERIVED_RTC_CLK_EXTERNAL_DETECT_LSB) & WLAN_DERIVED_RTC_CLK_EXTERNAL_DETECT_MASK)
-#define WLAN_DERIVED_RTC_CLK_FORCE_MSB           17
-#define WLAN_DERIVED_RTC_CLK_FORCE_LSB           16
-#define WLAN_DERIVED_RTC_CLK_FORCE_MASK          0x00030000
-#define WLAN_DERIVED_RTC_CLK_FORCE_GET(x)        (((x) & WLAN_DERIVED_RTC_CLK_FORCE_MASK) >> WLAN_DERIVED_RTC_CLK_FORCE_LSB)
-#define WLAN_DERIVED_RTC_CLK_FORCE_SET(x)        (((x) << WLAN_DERIVED_RTC_CLK_FORCE_LSB) & WLAN_DERIVED_RTC_CLK_FORCE_MASK)
-#define WLAN_DERIVED_RTC_CLK_PERIOD_MSB          15
-#define WLAN_DERIVED_RTC_CLK_PERIOD_LSB          1
-#define WLAN_DERIVED_RTC_CLK_PERIOD_MASK         0x0000fffe
-#define WLAN_DERIVED_RTC_CLK_PERIOD_GET(x)       (((x) & WLAN_DERIVED_RTC_CLK_PERIOD_MASK) >> WLAN_DERIVED_RTC_CLK_PERIOD_LSB)
-#define WLAN_DERIVED_RTC_CLK_PERIOD_SET(x)       (((x) << WLAN_DERIVED_RTC_CLK_PERIOD_LSB) & WLAN_DERIVED_RTC_CLK_PERIOD_MASK)
-
-#define MAC_PCU_SLP32_MODE_ADDRESS               0x000000f4
-#define MAC_PCU_SLP32_MODE_OFFSET                0x000000f4
-#define MAC_PCU_SLP32_MODE_TSF2_WRITE_STATUS_MSB 24
-#define MAC_PCU_SLP32_MODE_TSF2_WRITE_STATUS_LSB 24
-#define MAC_PCU_SLP32_MODE_TSF2_WRITE_STATUS_MASK 0x01000000
-#define MAC_PCU_SLP32_MODE_TSF2_WRITE_STATUS_GET(x) (((x) & MAC_PCU_SLP32_MODE_TSF2_WRITE_STATUS_MASK) >> MAC_PCU_SLP32_MODE_TSF2_WRITE_STATUS_LSB)
-#define MAC_PCU_SLP32_MODE_TSF2_WRITE_STATUS_SET(x) (((x) << MAC_PCU_SLP32_MODE_TSF2_WRITE_STATUS_LSB) & MAC_PCU_SLP32_MODE_TSF2_WRITE_STATUS_MASK)
-#define MAC_PCU_SLP32_MODE_FORCE_BIAS_BLOCK_ON_MSB 23
-#define MAC_PCU_SLP32_MODE_FORCE_BIAS_BLOCK_ON_LSB 23
-#define MAC_PCU_SLP32_MODE_FORCE_BIAS_BLOCK_ON_MASK 0x00800000
-#define MAC_PCU_SLP32_MODE_FORCE_BIAS_BLOCK_ON_GET(x) (((x) & MAC_PCU_SLP32_MODE_FORCE_BIAS_BLOCK_ON_MASK) >> MAC_PCU_SLP32_MODE_FORCE_BIAS_BLOCK_ON_LSB)
-#define MAC_PCU_SLP32_MODE_FORCE_BIAS_BLOCK_ON_SET(x) (((x) << MAC_PCU_SLP32_MODE_FORCE_BIAS_BLOCK_ON_LSB) & MAC_PCU_SLP32_MODE_FORCE_BIAS_BLOCK_ON_MASK)
-#define MAC_PCU_SLP32_MODE_DISABLE_32KHZ_MSB     22
-#define MAC_PCU_SLP32_MODE_DISABLE_32KHZ_LSB     22
-#define MAC_PCU_SLP32_MODE_DISABLE_32KHZ_MASK    0x00400000
-#define MAC_PCU_SLP32_MODE_DISABLE_32KHZ_GET(x)  (((x) & MAC_PCU_SLP32_MODE_DISABLE_32KHZ_MASK) >> MAC_PCU_SLP32_MODE_DISABLE_32KHZ_LSB)
-#define MAC_PCU_SLP32_MODE_DISABLE_32KHZ_SET(x)  (((x) << MAC_PCU_SLP32_MODE_DISABLE_32KHZ_LSB) & MAC_PCU_SLP32_MODE_DISABLE_32KHZ_MASK)
-#define MAC_PCU_SLP32_MODE_TSF_WRITE_STATUS_MSB  21
-#define MAC_PCU_SLP32_MODE_TSF_WRITE_STATUS_LSB  21
-#define MAC_PCU_SLP32_MODE_TSF_WRITE_STATUS_MASK 0x00200000
-#define MAC_PCU_SLP32_MODE_TSF_WRITE_STATUS_GET(x) (((x) & MAC_PCU_SLP32_MODE_TSF_WRITE_STATUS_MASK) >> MAC_PCU_SLP32_MODE_TSF_WRITE_STATUS_LSB)
-#define MAC_PCU_SLP32_MODE_TSF_WRITE_STATUS_SET(x) (((x) << MAC_PCU_SLP32_MODE_TSF_WRITE_STATUS_LSB) & MAC_PCU_SLP32_MODE_TSF_WRITE_STATUS_MASK)
-#define MAC_PCU_SLP32_MODE_ENABLE_MSB            20
-#define MAC_PCU_SLP32_MODE_ENABLE_LSB            20
-#define MAC_PCU_SLP32_MODE_ENABLE_MASK           0x00100000
-#define MAC_PCU_SLP32_MODE_ENABLE_GET(x)         (((x) & MAC_PCU_SLP32_MODE_ENABLE_MASK) >> MAC_PCU_SLP32_MODE_ENABLE_LSB)
-#define MAC_PCU_SLP32_MODE_ENABLE_SET(x)         (((x) << MAC_PCU_SLP32_MODE_ENABLE_LSB) & MAC_PCU_SLP32_MODE_ENABLE_MASK)
-#define MAC_PCU_SLP32_MODE_HALF_CLK_LATENCY_MSB  19
-#define MAC_PCU_SLP32_MODE_HALF_CLK_LATENCY_LSB  0
-#define MAC_PCU_SLP32_MODE_HALF_CLK_LATENCY_MASK 0x000fffff
-#define MAC_PCU_SLP32_MODE_HALF_CLK_LATENCY_GET(x) (((x) & MAC_PCU_SLP32_MODE_HALF_CLK_LATENCY_MASK) >> MAC_PCU_SLP32_MODE_HALF_CLK_LATENCY_LSB)
-#define MAC_PCU_SLP32_MODE_HALF_CLK_LATENCY_SET(x) (((x) << MAC_PCU_SLP32_MODE_HALF_CLK_LATENCY_LSB) & MAC_PCU_SLP32_MODE_HALF_CLK_LATENCY_MASK)
-
-#define MAC_PCU_SLP32_WAKE_ADDRESS               0x000000f8
-#define MAC_PCU_SLP32_WAKE_OFFSET                0x000000f8
-#define MAC_PCU_SLP32_WAKE_XTL_TIME_MSB          15
-#define MAC_PCU_SLP32_WAKE_XTL_TIME_LSB          0
-#define MAC_PCU_SLP32_WAKE_XTL_TIME_MASK         0x0000ffff
-#define MAC_PCU_SLP32_WAKE_XTL_TIME_GET(x)       (((x) & MAC_PCU_SLP32_WAKE_XTL_TIME_MASK) >> MAC_PCU_SLP32_WAKE_XTL_TIME_LSB)
-#define MAC_PCU_SLP32_WAKE_XTL_TIME_SET(x)       (((x) << MAC_PCU_SLP32_WAKE_XTL_TIME_LSB) & MAC_PCU_SLP32_WAKE_XTL_TIME_MASK)
-
-#define MAC_PCU_SLP32_INC_ADDRESS                0x000000fc
-#define MAC_PCU_SLP32_INC_OFFSET                 0x000000fc
-#define MAC_PCU_SLP32_INC_TSF_INC_MSB            19
-#define MAC_PCU_SLP32_INC_TSF_INC_LSB            0
-#define MAC_PCU_SLP32_INC_TSF_INC_MASK           0x000fffff
-#define MAC_PCU_SLP32_INC_TSF_INC_GET(x)         (((x) & MAC_PCU_SLP32_INC_TSF_INC_MASK) >> MAC_PCU_SLP32_INC_TSF_INC_LSB)
-#define MAC_PCU_SLP32_INC_TSF_INC_SET(x)         (((x) << MAC_PCU_SLP32_INC_TSF_INC_LSB) & MAC_PCU_SLP32_INC_TSF_INC_MASK)
-
-#define MAC_PCU_SLP_MIB1_ADDRESS                 0x00000100
-#define MAC_PCU_SLP_MIB1_OFFSET                  0x00000100
-#define MAC_PCU_SLP_MIB1_SLEEP_CNT_MSB           31
-#define MAC_PCU_SLP_MIB1_SLEEP_CNT_LSB           0
-#define MAC_PCU_SLP_MIB1_SLEEP_CNT_MASK          0xffffffff
-#define MAC_PCU_SLP_MIB1_SLEEP_CNT_GET(x)        (((x) & MAC_PCU_SLP_MIB1_SLEEP_CNT_MASK) >> MAC_PCU_SLP_MIB1_SLEEP_CNT_LSB)
-#define MAC_PCU_SLP_MIB1_SLEEP_CNT_SET(x)        (((x) << MAC_PCU_SLP_MIB1_SLEEP_CNT_LSB) & MAC_PCU_SLP_MIB1_SLEEP_CNT_MASK)
-
-#define MAC_PCU_SLP_MIB2_ADDRESS                 0x00000104
-#define MAC_PCU_SLP_MIB2_OFFSET                  0x00000104
-#define MAC_PCU_SLP_MIB2_CYCLE_CNT_MSB           31
-#define MAC_PCU_SLP_MIB2_CYCLE_CNT_LSB           0
-#define MAC_PCU_SLP_MIB2_CYCLE_CNT_MASK          0xffffffff
-#define MAC_PCU_SLP_MIB2_CYCLE_CNT_GET(x)        (((x) & MAC_PCU_SLP_MIB2_CYCLE_CNT_MASK) >> MAC_PCU_SLP_MIB2_CYCLE_CNT_LSB)
-#define MAC_PCU_SLP_MIB2_CYCLE_CNT_SET(x)        (((x) << MAC_PCU_SLP_MIB2_CYCLE_CNT_LSB) & MAC_PCU_SLP_MIB2_CYCLE_CNT_MASK)
-
-#define MAC_PCU_SLP_MIB3_ADDRESS                 0x00000108
-#define MAC_PCU_SLP_MIB3_OFFSET                  0x00000108
-#define MAC_PCU_SLP_MIB3_PENDING_MSB             1
-#define MAC_PCU_SLP_MIB3_PENDING_LSB             1
-#define MAC_PCU_SLP_MIB3_PENDING_MASK            0x00000002
-#define MAC_PCU_SLP_MIB3_PENDING_GET(x)          (((x) & MAC_PCU_SLP_MIB3_PENDING_MASK) >> MAC_PCU_SLP_MIB3_PENDING_LSB)
-#define MAC_PCU_SLP_MIB3_PENDING_SET(x)          (((x) << MAC_PCU_SLP_MIB3_PENDING_LSB) & MAC_PCU_SLP_MIB3_PENDING_MASK)
-#define MAC_PCU_SLP_MIB3_CLR_CNT_MSB             0
-#define MAC_PCU_SLP_MIB3_CLR_CNT_LSB             0
-#define MAC_PCU_SLP_MIB3_CLR_CNT_MASK            0x00000001
-#define MAC_PCU_SLP_MIB3_CLR_CNT_GET(x)          (((x) & MAC_PCU_SLP_MIB3_CLR_CNT_MASK) >> MAC_PCU_SLP_MIB3_CLR_CNT_LSB)
-#define MAC_PCU_SLP_MIB3_CLR_CNT_SET(x)          (((x) << MAC_PCU_SLP_MIB3_CLR_CNT_LSB) & MAC_PCU_SLP_MIB3_CLR_CNT_MASK)
-
-#define WLAN_POWER_REG_ADDRESS                   0x0000010c
-#define WLAN_POWER_REG_OFFSET                    0x0000010c
-#define WLAN_POWER_REG_SLEEP_MAKE_N_BREAK_EN_MSB 15
-#define WLAN_POWER_REG_SLEEP_MAKE_N_BREAK_EN_LSB 15
-#define WLAN_POWER_REG_SLEEP_MAKE_N_BREAK_EN_MASK 0x00008000
-#define WLAN_POWER_REG_SLEEP_MAKE_N_BREAK_EN_GET(x) (((x) & WLAN_POWER_REG_SLEEP_MAKE_N_BREAK_EN_MASK) >> WLAN_POWER_REG_SLEEP_MAKE_N_BREAK_EN_LSB)
-#define WLAN_POWER_REG_SLEEP_MAKE_N_BREAK_EN_SET(x) (((x) << WLAN_POWER_REG_SLEEP_MAKE_N_BREAK_EN_LSB) & WLAN_POWER_REG_SLEEP_MAKE_N_BREAK_EN_MASK)
-#define WLAN_POWER_REG_DEBUG_EN_MSB              14
-#define WLAN_POWER_REG_DEBUG_EN_LSB              14
-#define WLAN_POWER_REG_DEBUG_EN_MASK             0x00004000
-#define WLAN_POWER_REG_DEBUG_EN_GET(x)           (((x) & WLAN_POWER_REG_DEBUG_EN_MASK) >> WLAN_POWER_REG_DEBUG_EN_LSB)
-#define WLAN_POWER_REG_DEBUG_EN_SET(x)           (((x) << WLAN_POWER_REG_DEBUG_EN_LSB) & WLAN_POWER_REG_DEBUG_EN_MASK)
-#define WLAN_POWER_REG_WLAN_BB_PWD_EN_MSB        13
-#define WLAN_POWER_REG_WLAN_BB_PWD_EN_LSB        13
-#define WLAN_POWER_REG_WLAN_BB_PWD_EN_MASK       0x00002000
-#define WLAN_POWER_REG_WLAN_BB_PWD_EN_GET(x)     (((x) & WLAN_POWER_REG_WLAN_BB_PWD_EN_MASK) >> WLAN_POWER_REG_WLAN_BB_PWD_EN_LSB)
-#define WLAN_POWER_REG_WLAN_BB_PWD_EN_SET(x)     (((x) << WLAN_POWER_REG_WLAN_BB_PWD_EN_LSB) & WLAN_POWER_REG_WLAN_BB_PWD_EN_MASK)
-#define WLAN_POWER_REG_WLAN_MAC_PWD_EN_MSB       12
-#define WLAN_POWER_REG_WLAN_MAC_PWD_EN_LSB       12
-#define WLAN_POWER_REG_WLAN_MAC_PWD_EN_MASK      0x00001000
-#define WLAN_POWER_REG_WLAN_MAC_PWD_EN_GET(x)    (((x) & WLAN_POWER_REG_WLAN_MAC_PWD_EN_MASK) >> WLAN_POWER_REG_WLAN_MAC_PWD_EN_LSB)
-#define WLAN_POWER_REG_WLAN_MAC_PWD_EN_SET(x)    (((x) << WLAN_POWER_REG_WLAN_MAC_PWD_EN_LSB) & WLAN_POWER_REG_WLAN_MAC_PWD_EN_MASK)
-#define WLAN_POWER_REG_VLVL_MSB                  11
-#define WLAN_POWER_REG_VLVL_LSB                  8
-#define WLAN_POWER_REG_VLVL_MASK                 0x00000f00
-#define WLAN_POWER_REG_VLVL_GET(x)               (((x) & WLAN_POWER_REG_VLVL_MASK) >> WLAN_POWER_REG_VLVL_LSB)
-#define WLAN_POWER_REG_VLVL_SET(x)               (((x) << WLAN_POWER_REG_VLVL_LSB) & WLAN_POWER_REG_VLVL_MASK)
-#define WLAN_POWER_REG_CPU_INT_ENABLE_MSB        7
-#define WLAN_POWER_REG_CPU_INT_ENABLE_LSB        7
-#define WLAN_POWER_REG_CPU_INT_ENABLE_MASK       0x00000080
-#define WLAN_POWER_REG_CPU_INT_ENABLE_GET(x)     (((x) & WLAN_POWER_REG_CPU_INT_ENABLE_MASK) >> WLAN_POWER_REG_CPU_INT_ENABLE_LSB)
-#define WLAN_POWER_REG_CPU_INT_ENABLE_SET(x)     (((x) << WLAN_POWER_REG_CPU_INT_ENABLE_LSB) & WLAN_POWER_REG_CPU_INT_ENABLE_MASK)
-#define WLAN_POWER_REG_WLAN_ISO_DIS_MSB          6
-#define WLAN_POWER_REG_WLAN_ISO_DIS_LSB          6
-#define WLAN_POWER_REG_WLAN_ISO_DIS_MASK         0x00000040
-#define WLAN_POWER_REG_WLAN_ISO_DIS_GET(x)       (((x) & WLAN_POWER_REG_WLAN_ISO_DIS_MASK) >> WLAN_POWER_REG_WLAN_ISO_DIS_LSB)
-#define WLAN_POWER_REG_WLAN_ISO_DIS_SET(x)       (((x) << WLAN_POWER_REG_WLAN_ISO_DIS_LSB) & WLAN_POWER_REG_WLAN_ISO_DIS_MASK)
-#define WLAN_POWER_REG_WLAN_ISO_CNTL_MSB         5
-#define WLAN_POWER_REG_WLAN_ISO_CNTL_LSB         5
-#define WLAN_POWER_REG_WLAN_ISO_CNTL_MASK        0x00000020
-#define WLAN_POWER_REG_WLAN_ISO_CNTL_GET(x)      (((x) & WLAN_POWER_REG_WLAN_ISO_CNTL_MASK) >> WLAN_POWER_REG_WLAN_ISO_CNTL_LSB)
-#define WLAN_POWER_REG_WLAN_ISO_CNTL_SET(x)      (((x) << WLAN_POWER_REG_WLAN_ISO_CNTL_LSB) & WLAN_POWER_REG_WLAN_ISO_CNTL_MASK)
-#define WLAN_POWER_REG_RADIO_PWD_EN_MSB          4
-#define WLAN_POWER_REG_RADIO_PWD_EN_LSB          4
-#define WLAN_POWER_REG_RADIO_PWD_EN_MASK         0x00000010
-#define WLAN_POWER_REG_RADIO_PWD_EN_GET(x)       (((x) & WLAN_POWER_REG_RADIO_PWD_EN_MASK) >> WLAN_POWER_REG_RADIO_PWD_EN_LSB)
-#define WLAN_POWER_REG_RADIO_PWD_EN_SET(x)       (((x) << WLAN_POWER_REG_RADIO_PWD_EN_LSB) & WLAN_POWER_REG_RADIO_PWD_EN_MASK)
-#define WLAN_POWER_REG_SOC_ISO_EN_MSB            3
-#define WLAN_POWER_REG_SOC_ISO_EN_LSB            3
-#define WLAN_POWER_REG_SOC_ISO_EN_MASK           0x00000008
-#define WLAN_POWER_REG_SOC_ISO_EN_GET(x)         (((x) & WLAN_POWER_REG_SOC_ISO_EN_MASK) >> WLAN_POWER_REG_SOC_ISO_EN_LSB)
-#define WLAN_POWER_REG_SOC_ISO_EN_SET(x)         (((x) << WLAN_POWER_REG_SOC_ISO_EN_LSB) & WLAN_POWER_REG_SOC_ISO_EN_MASK)
-#define WLAN_POWER_REG_WLAN_ISO_EN_MSB           2
-#define WLAN_POWER_REG_WLAN_ISO_EN_LSB           2
-#define WLAN_POWER_REG_WLAN_ISO_EN_MASK          0x00000004
-#define WLAN_POWER_REG_WLAN_ISO_EN_GET(x)        (((x) & WLAN_POWER_REG_WLAN_ISO_EN_MASK) >> WLAN_POWER_REG_WLAN_ISO_EN_LSB)
-#define WLAN_POWER_REG_WLAN_ISO_EN_SET(x)        (((x) << WLAN_POWER_REG_WLAN_ISO_EN_LSB) & WLAN_POWER_REG_WLAN_ISO_EN_MASK)
-#define WLAN_POWER_REG_WLAN_PWD_EN_MSB           1
-#define WLAN_POWER_REG_WLAN_PWD_EN_LSB           1
-#define WLAN_POWER_REG_WLAN_PWD_EN_MASK          0x00000002
-#define WLAN_POWER_REG_WLAN_PWD_EN_GET(x)        (((x) & WLAN_POWER_REG_WLAN_PWD_EN_MASK) >> WLAN_POWER_REG_WLAN_PWD_EN_LSB)
-#define WLAN_POWER_REG_WLAN_PWD_EN_SET(x)        (((x) << WLAN_POWER_REG_WLAN_PWD_EN_LSB) & WLAN_POWER_REG_WLAN_PWD_EN_MASK)
-#define WLAN_POWER_REG_POWER_EN_MSB              0
-#define WLAN_POWER_REG_POWER_EN_LSB              0
-#define WLAN_POWER_REG_POWER_EN_MASK             0x00000001
-#define WLAN_POWER_REG_POWER_EN_GET(x)           (((x) & WLAN_POWER_REG_POWER_EN_MASK) >> WLAN_POWER_REG_POWER_EN_LSB)
-#define WLAN_POWER_REG_POWER_EN_SET(x)           (((x) << WLAN_POWER_REG_POWER_EN_LSB) & WLAN_POWER_REG_POWER_EN_MASK)
-
-#define WLAN_CORE_CLK_CTRL_ADDRESS               0x00000110
-#define WLAN_CORE_CLK_CTRL_OFFSET                0x00000110
-#define WLAN_CORE_CLK_CTRL_DIV_MSB               2
-#define WLAN_CORE_CLK_CTRL_DIV_LSB               0
-#define WLAN_CORE_CLK_CTRL_DIV_MASK              0x00000007
-#define WLAN_CORE_CLK_CTRL_DIV_GET(x)            (((x) & WLAN_CORE_CLK_CTRL_DIV_MASK) >> WLAN_CORE_CLK_CTRL_DIV_LSB)
-#define WLAN_CORE_CLK_CTRL_DIV_SET(x)            (((x) << WLAN_CORE_CLK_CTRL_DIV_LSB) & WLAN_CORE_CLK_CTRL_DIV_MASK)
-
-#define WLAN_GPIO_WAKEUP_CONTROL_ADDRESS         0x00000114
-#define WLAN_GPIO_WAKEUP_CONTROL_OFFSET          0x00000114
-#define WLAN_GPIO_WAKEUP_CONTROL_ENABLE_MSB      0
-#define WLAN_GPIO_WAKEUP_CONTROL_ENABLE_LSB      0
-#define WLAN_GPIO_WAKEUP_CONTROL_ENABLE_MASK     0x00000001
-#define WLAN_GPIO_WAKEUP_CONTROL_ENABLE_GET(x)   (((x) & WLAN_GPIO_WAKEUP_CONTROL_ENABLE_MASK) >> WLAN_GPIO_WAKEUP_CONTROL_ENABLE_LSB)
-#define WLAN_GPIO_WAKEUP_CONTROL_ENABLE_SET(x)   (((x) << WLAN_GPIO_WAKEUP_CONTROL_ENABLE_LSB) & WLAN_GPIO_WAKEUP_CONTROL_ENABLE_MASK)
-
-#define HT_ADDRESS                               0x00000118
-#define HT_OFFSET                                0x00000118
-#define HT_MODE_MSB                              0
-#define HT_MODE_LSB                              0
-#define HT_MODE_MASK                             0x00000001
-#define HT_MODE_GET(x)                           (((x) & HT_MODE_MASK) >> HT_MODE_LSB)
-#define HT_MODE_SET(x)                           (((x) << HT_MODE_LSB) & HT_MODE_MASK)
-
-#define MAC_PCU_TSF_L32_ADDRESS                  0x0000011c
-#define MAC_PCU_TSF_L32_OFFSET                   0x0000011c
-#define MAC_PCU_TSF_L32_VALUE_MSB                31
-#define MAC_PCU_TSF_L32_VALUE_LSB                0
-#define MAC_PCU_TSF_L32_VALUE_MASK               0xffffffff
-#define MAC_PCU_TSF_L32_VALUE_GET(x)             (((x) & MAC_PCU_TSF_L32_VALUE_MASK) >> MAC_PCU_TSF_L32_VALUE_LSB)
-#define MAC_PCU_TSF_L32_VALUE_SET(x)             (((x) << MAC_PCU_TSF_L32_VALUE_LSB) & MAC_PCU_TSF_L32_VALUE_MASK)
-
-#define MAC_PCU_TSF_U32_ADDRESS                  0x00000120
-#define MAC_PCU_TSF_U32_OFFSET                   0x00000120
-#define MAC_PCU_TSF_U32_VALUE_MSB                31
-#define MAC_PCU_TSF_U32_VALUE_LSB                0
-#define MAC_PCU_TSF_U32_VALUE_MASK               0xffffffff
-#define MAC_PCU_TSF_U32_VALUE_GET(x)             (((x) & MAC_PCU_TSF_U32_VALUE_MASK) >> MAC_PCU_TSF_U32_VALUE_LSB)
-#define MAC_PCU_TSF_U32_VALUE_SET(x)             (((x) << MAC_PCU_TSF_U32_VALUE_LSB) & MAC_PCU_TSF_U32_VALUE_MASK)
-
-#define MAC_PCU_WBTIMER_ADDRESS                  0x00000124
-#define MAC_PCU_WBTIMER_OFFSET                   0x00000124
-#define MAC_PCU_WBTIMER_VALUE_MSB                31
-#define MAC_PCU_WBTIMER_VALUE_LSB                0
-#define MAC_PCU_WBTIMER_VALUE_MASK               0xffffffff
-#define MAC_PCU_WBTIMER_VALUE_GET(x)             (((x) & MAC_PCU_WBTIMER_VALUE_MASK) >> MAC_PCU_WBTIMER_VALUE_LSB)
-#define MAC_PCU_WBTIMER_VALUE_SET(x)             (((x) << MAC_PCU_WBTIMER_VALUE_LSB) & MAC_PCU_WBTIMER_VALUE_MASK)
-
-#define MAC_PCU_GENERIC_TIMERS_ADDRESS           0x00000140
-#define MAC_PCU_GENERIC_TIMERS_OFFSET            0x00000140
-#define MAC_PCU_GENERIC_TIMERS_DATA_MSB          31
-#define MAC_PCU_GENERIC_TIMERS_DATA_LSB          0
-#define MAC_PCU_GENERIC_TIMERS_DATA_MASK         0xffffffff
-#define MAC_PCU_GENERIC_TIMERS_DATA_GET(x)       (((x) & MAC_PCU_GENERIC_TIMERS_DATA_MASK) >> MAC_PCU_GENERIC_TIMERS_DATA_LSB)
-#define MAC_PCU_GENERIC_TIMERS_DATA_SET(x)       (((x) << MAC_PCU_GENERIC_TIMERS_DATA_LSB) & MAC_PCU_GENERIC_TIMERS_DATA_MASK)
-
-#define MAC_PCU_GENERIC_TIMERS_MODE_ADDRESS      0x00000180
-#define MAC_PCU_GENERIC_TIMERS_MODE_OFFSET       0x00000180
-#define MAC_PCU_GENERIC_TIMERS_MODE_ENABLE_MSB   15
-#define MAC_PCU_GENERIC_TIMERS_MODE_ENABLE_LSB   0
-#define MAC_PCU_GENERIC_TIMERS_MODE_ENABLE_MASK  0x0000ffff
-#define MAC_PCU_GENERIC_TIMERS_MODE_ENABLE_GET(x) (((x) & MAC_PCU_GENERIC_TIMERS_MODE_ENABLE_MASK) >> MAC_PCU_GENERIC_TIMERS_MODE_ENABLE_LSB)
-#define MAC_PCU_GENERIC_TIMERS_MODE_ENABLE_SET(x) (((x) << MAC_PCU_GENERIC_TIMERS_MODE_ENABLE_LSB) & MAC_PCU_GENERIC_TIMERS_MODE_ENABLE_MASK)
-
-#define MAC_PCU_GENERIC_TIMERS2_ADDRESS          0x000001c0
-#define MAC_PCU_GENERIC_TIMERS2_OFFSET           0x000001c0
-#define MAC_PCU_GENERIC_TIMERS2_DATA_MSB         31
-#define MAC_PCU_GENERIC_TIMERS2_DATA_LSB         0
-#define MAC_PCU_GENERIC_TIMERS2_DATA_MASK        0xffffffff
-#define MAC_PCU_GENERIC_TIMERS2_DATA_GET(x)      (((x) & MAC_PCU_GENERIC_TIMERS2_DATA_MASK) >> MAC_PCU_GENERIC_TIMERS2_DATA_LSB)
-#define MAC_PCU_GENERIC_TIMERS2_DATA_SET(x)      (((x) << MAC_PCU_GENERIC_TIMERS2_DATA_LSB) & MAC_PCU_GENERIC_TIMERS2_DATA_MASK)
-
-#define MAC_PCU_GENERIC_TIMERS_MODE2_ADDRESS     0x00000200
-#define MAC_PCU_GENERIC_TIMERS_MODE2_OFFSET      0x00000200
-#define MAC_PCU_GENERIC_TIMERS_MODE2_ENABLE_MSB  15
-#define MAC_PCU_GENERIC_TIMERS_MODE2_ENABLE_LSB  0
-#define MAC_PCU_GENERIC_TIMERS_MODE2_ENABLE_MASK 0x0000ffff
-#define MAC_PCU_GENERIC_TIMERS_MODE2_ENABLE_GET(x) (((x) & MAC_PCU_GENERIC_TIMERS_MODE2_ENABLE_MASK) >> MAC_PCU_GENERIC_TIMERS_MODE2_ENABLE_LSB)
-#define MAC_PCU_GENERIC_TIMERS_MODE2_ENABLE_SET(x) (((x) << MAC_PCU_GENERIC_TIMERS_MODE2_ENABLE_LSB) & MAC_PCU_GENERIC_TIMERS_MODE2_ENABLE_MASK)
-
-#define MAC_PCU_SLP1_ADDRESS                     0x00000204
-#define MAC_PCU_SLP1_OFFSET                      0x00000204
-#define MAC_PCU_SLP1_ASSUME_DTIM_MSB             19
-#define MAC_PCU_SLP1_ASSUME_DTIM_LSB             19
-#define MAC_PCU_SLP1_ASSUME_DTIM_MASK            0x00080000
-#define MAC_PCU_SLP1_ASSUME_DTIM_GET(x)          (((x) & MAC_PCU_SLP1_ASSUME_DTIM_MASK) >> MAC_PCU_SLP1_ASSUME_DTIM_LSB)
-#define MAC_PCU_SLP1_ASSUME_DTIM_SET(x)          (((x) << MAC_PCU_SLP1_ASSUME_DTIM_LSB) & MAC_PCU_SLP1_ASSUME_DTIM_MASK)
-#define MAC_PCU_SLP1_CAB_TIMEOUT_MSB             15
-#define MAC_PCU_SLP1_CAB_TIMEOUT_LSB             0
-#define MAC_PCU_SLP1_CAB_TIMEOUT_MASK            0x0000ffff
-#define MAC_PCU_SLP1_CAB_TIMEOUT_GET(x)          (((x) & MAC_PCU_SLP1_CAB_TIMEOUT_MASK) >> MAC_PCU_SLP1_CAB_TIMEOUT_LSB)
-#define MAC_PCU_SLP1_CAB_TIMEOUT_SET(x)          (((x) << MAC_PCU_SLP1_CAB_TIMEOUT_LSB) & MAC_PCU_SLP1_CAB_TIMEOUT_MASK)
-
-#define MAC_PCU_SLP2_ADDRESS                     0x00000208
-#define MAC_PCU_SLP2_OFFSET                      0x00000208
-#define MAC_PCU_SLP2_BEACON_TIMEOUT_MSB          15
-#define MAC_PCU_SLP2_BEACON_TIMEOUT_LSB          0
-#define MAC_PCU_SLP2_BEACON_TIMEOUT_MASK         0x0000ffff
-#define MAC_PCU_SLP2_BEACON_TIMEOUT_GET(x)       (((x) & MAC_PCU_SLP2_BEACON_TIMEOUT_MASK) >> MAC_PCU_SLP2_BEACON_TIMEOUT_LSB)
-#define MAC_PCU_SLP2_BEACON_TIMEOUT_SET(x)       (((x) << MAC_PCU_SLP2_BEACON_TIMEOUT_LSB) & MAC_PCU_SLP2_BEACON_TIMEOUT_MASK)
-
-#define MAC_PCU_RESET_TSF_ADDRESS                0x0000020c
-#define MAC_PCU_RESET_TSF_OFFSET                 0x0000020c
-#define MAC_PCU_RESET_TSF_ONE_SHOT2_MSB          25
-#define MAC_PCU_RESET_TSF_ONE_SHOT2_LSB          25
-#define MAC_PCU_RESET_TSF_ONE_SHOT2_MASK         0x02000000
-#define MAC_PCU_RESET_TSF_ONE_SHOT2_GET(x)       (((x) & MAC_PCU_RESET_TSF_ONE_SHOT2_MASK) >> MAC_PCU_RESET_TSF_ONE_SHOT2_LSB)
-#define MAC_PCU_RESET_TSF_ONE_SHOT2_SET(x)       (((x) << MAC_PCU_RESET_TSF_ONE_SHOT2_LSB) & MAC_PCU_RESET_TSF_ONE_SHOT2_MASK)
-#define MAC_PCU_RESET_TSF_ONE_SHOT_MSB           24
-#define MAC_PCU_RESET_TSF_ONE_SHOT_LSB           24
-#define MAC_PCU_RESET_TSF_ONE_SHOT_MASK          0x01000000
-#define MAC_PCU_RESET_TSF_ONE_SHOT_GET(x)        (((x) & MAC_PCU_RESET_TSF_ONE_SHOT_MASK) >> MAC_PCU_RESET_TSF_ONE_SHOT_LSB)
-#define MAC_PCU_RESET_TSF_ONE_SHOT_SET(x)        (((x) << MAC_PCU_RESET_TSF_ONE_SHOT_LSB) & MAC_PCU_RESET_TSF_ONE_SHOT_MASK)
-
-#define MAC_PCU_TSF_ADD_PLL_ADDRESS              0x00000210
-#define MAC_PCU_TSF_ADD_PLL_OFFSET               0x00000210
-#define MAC_PCU_TSF_ADD_PLL_VALUE_MSB            7
-#define MAC_PCU_TSF_ADD_PLL_VALUE_LSB            0
-#define MAC_PCU_TSF_ADD_PLL_VALUE_MASK           0x000000ff
-#define MAC_PCU_TSF_ADD_PLL_VALUE_GET(x)         (((x) & MAC_PCU_TSF_ADD_PLL_VALUE_MASK) >> MAC_PCU_TSF_ADD_PLL_VALUE_LSB)
-#define MAC_PCU_TSF_ADD_PLL_VALUE_SET(x)         (((x) << MAC_PCU_TSF_ADD_PLL_VALUE_LSB) & MAC_PCU_TSF_ADD_PLL_VALUE_MASK)
-
-#define SLEEP_RETENTION_ADDRESS                  0x00000214
-#define SLEEP_RETENTION_OFFSET                   0x00000214
-#define SLEEP_RETENTION_TIME_MSB                 9
-#define SLEEP_RETENTION_TIME_LSB                 2
-#define SLEEP_RETENTION_TIME_MASK                0x000003fc
-#define SLEEP_RETENTION_TIME_GET(x)              (((x) & SLEEP_RETENTION_TIME_MASK) >> SLEEP_RETENTION_TIME_LSB)
-#define SLEEP_RETENTION_TIME_SET(x)              (((x) << SLEEP_RETENTION_TIME_LSB) & SLEEP_RETENTION_TIME_MASK)
-#define SLEEP_RETENTION_MODE_MSB                 1
-#define SLEEP_RETENTION_MODE_LSB                 1
-#define SLEEP_RETENTION_MODE_MASK                0x00000002
-#define SLEEP_RETENTION_MODE_GET(x)              (((x) & SLEEP_RETENTION_MODE_MASK) >> SLEEP_RETENTION_MODE_LSB)
-#define SLEEP_RETENTION_MODE_SET(x)              (((x) << SLEEP_RETENTION_MODE_LSB) & SLEEP_RETENTION_MODE_MASK)
-#define SLEEP_RETENTION_ENABLE_MSB               0
-#define SLEEP_RETENTION_ENABLE_LSB               0
-#define SLEEP_RETENTION_ENABLE_MASK              0x00000001
-#define SLEEP_RETENTION_ENABLE_GET(x)            (((x) & SLEEP_RETENTION_ENABLE_MASK) >> SLEEP_RETENTION_ENABLE_LSB)
-#define SLEEP_RETENTION_ENABLE_SET(x)            (((x) << SLEEP_RETENTION_ENABLE_LSB) & SLEEP_RETENTION_ENABLE_MASK)
-
-#define BTCOEXCTRL_ADDRESS                       0x00000218
-#define BTCOEXCTRL_OFFSET                        0x00000218
-#define BTCOEXCTRL_WBTIMER_ENABLE_MSB            26
-#define BTCOEXCTRL_WBTIMER_ENABLE_LSB            26
-#define BTCOEXCTRL_WBTIMER_ENABLE_MASK           0x04000000
-#define BTCOEXCTRL_WBTIMER_ENABLE_GET(x)         (((x) & BTCOEXCTRL_WBTIMER_ENABLE_MASK) >> BTCOEXCTRL_WBTIMER_ENABLE_LSB)
-#define BTCOEXCTRL_WBTIMER_ENABLE_SET(x)         (((x) << BTCOEXCTRL_WBTIMER_ENABLE_LSB) & BTCOEXCTRL_WBTIMER_ENABLE_MASK)
-#define BTCOEXCTRL_WBSYNC_ON_BEACON_MSB          25
-#define BTCOEXCTRL_WBSYNC_ON_BEACON_LSB          25
-#define BTCOEXCTRL_WBSYNC_ON_BEACON_MASK         0x02000000
-#define BTCOEXCTRL_WBSYNC_ON_BEACON_GET(x)       (((x) & BTCOEXCTRL_WBSYNC_ON_BEACON_MASK) >> BTCOEXCTRL_WBSYNC_ON_BEACON_LSB)
-#define BTCOEXCTRL_WBSYNC_ON_BEACON_SET(x)       (((x) << BTCOEXCTRL_WBSYNC_ON_BEACON_LSB) & BTCOEXCTRL_WBSYNC_ON_BEACON_MASK)
-#define BTCOEXCTRL_PTA_MODE_MSB                  24
-#define BTCOEXCTRL_PTA_MODE_LSB                  23
-#define BTCOEXCTRL_PTA_MODE_MASK                 0x01800000
-#define BTCOEXCTRL_PTA_MODE_GET(x)               (((x) & BTCOEXCTRL_PTA_MODE_MASK) >> BTCOEXCTRL_PTA_MODE_LSB)
-#define BTCOEXCTRL_PTA_MODE_SET(x)               (((x) << BTCOEXCTRL_PTA_MODE_LSB) & BTCOEXCTRL_PTA_MODE_MASK)
-#define BTCOEXCTRL_FREQ_TIME_MSB                 22
-#define BTCOEXCTRL_FREQ_TIME_LSB                 18
-#define BTCOEXCTRL_FREQ_TIME_MASK                0x007c0000
-#define BTCOEXCTRL_FREQ_TIME_GET(x)              (((x) & BTCOEXCTRL_FREQ_TIME_MASK) >> BTCOEXCTRL_FREQ_TIME_LSB)
-#define BTCOEXCTRL_FREQ_TIME_SET(x)              (((x) << BTCOEXCTRL_FREQ_TIME_LSB) & BTCOEXCTRL_FREQ_TIME_MASK)
-#define BTCOEXCTRL_PRIORITY_TIME_MSB             17
-#define BTCOEXCTRL_PRIORITY_TIME_LSB             12
-#define BTCOEXCTRL_PRIORITY_TIME_MASK            0x0003f000
-#define BTCOEXCTRL_PRIORITY_TIME_GET(x)          (((x) & BTCOEXCTRL_PRIORITY_TIME_MASK) >> BTCOEXCTRL_PRIORITY_TIME_LSB)
-#define BTCOEXCTRL_PRIORITY_TIME_SET(x)          (((x) << BTCOEXCTRL_PRIORITY_TIME_LSB) & BTCOEXCTRL_PRIORITY_TIME_MASK)
-#define BTCOEXCTRL_SYNC_DET_EN_MSB               11
-#define BTCOEXCTRL_SYNC_DET_EN_LSB               11
-#define BTCOEXCTRL_SYNC_DET_EN_MASK              0x00000800
-#define BTCOEXCTRL_SYNC_DET_EN_GET(x)            (((x) & BTCOEXCTRL_SYNC_DET_EN_MASK) >> BTCOEXCTRL_SYNC_DET_EN_LSB)
-#define BTCOEXCTRL_SYNC_DET_EN_SET(x)            (((x) << BTCOEXCTRL_SYNC_DET_EN_LSB) & BTCOEXCTRL_SYNC_DET_EN_MASK)
-#define BTCOEXCTRL_IDLE_CNT_EN_MSB               10
-#define BTCOEXCTRL_IDLE_CNT_EN_LSB               10
-#define BTCOEXCTRL_IDLE_CNT_EN_MASK              0x00000400
-#define BTCOEXCTRL_IDLE_CNT_EN_GET(x)            (((x) & BTCOEXCTRL_IDLE_CNT_EN_MASK) >> BTCOEXCTRL_IDLE_CNT_EN_LSB)
-#define BTCOEXCTRL_IDLE_CNT_EN_SET(x)            (((x) << BTCOEXCTRL_IDLE_CNT_EN_LSB) & BTCOEXCTRL_IDLE_CNT_EN_MASK)
-#define BTCOEXCTRL_FRAME_CNT_EN_MSB              9
-#define BTCOEXCTRL_FRAME_CNT_EN_LSB              9
-#define BTCOEXCTRL_FRAME_CNT_EN_MASK             0x00000200
-#define BTCOEXCTRL_FRAME_CNT_EN_GET(x)           (((x) & BTCOEXCTRL_FRAME_CNT_EN_MASK) >> BTCOEXCTRL_FRAME_CNT_EN_LSB)
-#define BTCOEXCTRL_FRAME_CNT_EN_SET(x)           (((x) << BTCOEXCTRL_FRAME_CNT_EN_LSB) & BTCOEXCTRL_FRAME_CNT_EN_MASK)
-#define BTCOEXCTRL_CLK_CNT_EN_MSB                8
-#define BTCOEXCTRL_CLK_CNT_EN_LSB                8
-#define BTCOEXCTRL_CLK_CNT_EN_MASK               0x00000100
-#define BTCOEXCTRL_CLK_CNT_EN_GET(x)             (((x) & BTCOEXCTRL_CLK_CNT_EN_MASK) >> BTCOEXCTRL_CLK_CNT_EN_LSB)
-#define BTCOEXCTRL_CLK_CNT_EN_SET(x)             (((x) << BTCOEXCTRL_CLK_CNT_EN_LSB) & BTCOEXCTRL_CLK_CNT_EN_MASK)
-#define BTCOEXCTRL_GAP_MSB                       7
-#define BTCOEXCTRL_GAP_LSB                       0
-#define BTCOEXCTRL_GAP_MASK                      0x000000ff
-#define BTCOEXCTRL_GAP_GET(x)                    (((x) & BTCOEXCTRL_GAP_MASK) >> BTCOEXCTRL_GAP_LSB)
-#define BTCOEXCTRL_GAP_SET(x)                    (((x) << BTCOEXCTRL_GAP_LSB) & BTCOEXCTRL_GAP_MASK)
-
-#define WBSYNC_PRIORITY1_ADDRESS                 0x0000021c
-#define WBSYNC_PRIORITY1_OFFSET                  0x0000021c
-#define WBSYNC_PRIORITY1_BITMAP_MSB              31
-#define WBSYNC_PRIORITY1_BITMAP_LSB              0
-#define WBSYNC_PRIORITY1_BITMAP_MASK             0xffffffff
-#define WBSYNC_PRIORITY1_BITMAP_GET(x)           (((x) & WBSYNC_PRIORITY1_BITMAP_MASK) >> WBSYNC_PRIORITY1_BITMAP_LSB)
-#define WBSYNC_PRIORITY1_BITMAP_SET(x)           (((x) << WBSYNC_PRIORITY1_BITMAP_LSB) & WBSYNC_PRIORITY1_BITMAP_MASK)
-
-#define WBSYNC_PRIORITY2_ADDRESS                 0x00000220
-#define WBSYNC_PRIORITY2_OFFSET                  0x00000220
-#define WBSYNC_PRIORITY2_BITMAP_MSB              31
-#define WBSYNC_PRIORITY2_BITMAP_LSB              0
-#define WBSYNC_PRIORITY2_BITMAP_MASK             0xffffffff
-#define WBSYNC_PRIORITY2_BITMAP_GET(x)           (((x) & WBSYNC_PRIORITY2_BITMAP_MASK) >> WBSYNC_PRIORITY2_BITMAP_LSB)
-#define WBSYNC_PRIORITY2_BITMAP_SET(x)           (((x) << WBSYNC_PRIORITY2_BITMAP_LSB) & WBSYNC_PRIORITY2_BITMAP_MASK)
-
-#define WBSYNC_PRIORITY3_ADDRESS                 0x00000224
-#define WBSYNC_PRIORITY3_OFFSET                  0x00000224
-#define WBSYNC_PRIORITY3_BITMAP_MSB              31
-#define WBSYNC_PRIORITY3_BITMAP_LSB              0
-#define WBSYNC_PRIORITY3_BITMAP_MASK             0xffffffff
-#define WBSYNC_PRIORITY3_BITMAP_GET(x)           (((x) & WBSYNC_PRIORITY3_BITMAP_MASK) >> WBSYNC_PRIORITY3_BITMAP_LSB)
-#define WBSYNC_PRIORITY3_BITMAP_SET(x)           (((x) << WBSYNC_PRIORITY3_BITMAP_LSB) & WBSYNC_PRIORITY3_BITMAP_MASK)
-
-#define BTCOEX0_ADDRESS                          0x00000228
-#define BTCOEX0_OFFSET                           0x00000228
-#define BTCOEX0_SYNC_DUR_MSB                     7
-#define BTCOEX0_SYNC_DUR_LSB                     0
-#define BTCOEX0_SYNC_DUR_MASK                    0x000000ff
-#define BTCOEX0_SYNC_DUR_GET(x)                  (((x) & BTCOEX0_SYNC_DUR_MASK) >> BTCOEX0_SYNC_DUR_LSB)
-#define BTCOEX0_SYNC_DUR_SET(x)                  (((x) << BTCOEX0_SYNC_DUR_LSB) & BTCOEX0_SYNC_DUR_MASK)
-
-#define BTCOEX1_ADDRESS                          0x0000022c
-#define BTCOEX1_OFFSET                           0x0000022c
-#define BTCOEX1_CLK_THRES_MSB                    20
-#define BTCOEX1_CLK_THRES_LSB                    0
-#define BTCOEX1_CLK_THRES_MASK                   0x001fffff
-#define BTCOEX1_CLK_THRES_GET(x)                 (((x) & BTCOEX1_CLK_THRES_MASK) >> BTCOEX1_CLK_THRES_LSB)
-#define BTCOEX1_CLK_THRES_SET(x)                 (((x) << BTCOEX1_CLK_THRES_LSB) & BTCOEX1_CLK_THRES_MASK)
-
-#define BTCOEX2_ADDRESS                          0x00000230
-#define BTCOEX2_OFFSET                           0x00000230
-#define BTCOEX2_FRAME_THRES_MSB                  7
-#define BTCOEX2_FRAME_THRES_LSB                  0
-#define BTCOEX2_FRAME_THRES_MASK                 0x000000ff
-#define BTCOEX2_FRAME_THRES_GET(x)               (((x) & BTCOEX2_FRAME_THRES_MASK) >> BTCOEX2_FRAME_THRES_LSB)
-#define BTCOEX2_FRAME_THRES_SET(x)               (((x) << BTCOEX2_FRAME_THRES_LSB) & BTCOEX2_FRAME_THRES_MASK)
-
-#define BTCOEX3_ADDRESS                          0x00000234
-#define BTCOEX3_OFFSET                           0x00000234
-#define BTCOEX3_CLK_CNT_MSB                      20
-#define BTCOEX3_CLK_CNT_LSB                      0
-#define BTCOEX3_CLK_CNT_MASK                     0x001fffff
-#define BTCOEX3_CLK_CNT_GET(x)                   (((x) & BTCOEX3_CLK_CNT_MASK) >> BTCOEX3_CLK_CNT_LSB)
-#define BTCOEX3_CLK_CNT_SET(x)                   (((x) << BTCOEX3_CLK_CNT_LSB) & BTCOEX3_CLK_CNT_MASK)
-
-#define BTCOEX4_ADDRESS                          0x00000238
-#define BTCOEX4_OFFSET                           0x00000238
-#define BTCOEX4_FRAME_CNT_MSB                    7
-#define BTCOEX4_FRAME_CNT_LSB                    0
-#define BTCOEX4_FRAME_CNT_MASK                   0x000000ff
-#define BTCOEX4_FRAME_CNT_GET(x)                 (((x) & BTCOEX4_FRAME_CNT_MASK) >> BTCOEX4_FRAME_CNT_LSB)
-#define BTCOEX4_FRAME_CNT_SET(x)                 (((x) << BTCOEX4_FRAME_CNT_LSB) & BTCOEX4_FRAME_CNT_MASK)
-
-#define BTCOEX5_ADDRESS                          0x0000023c
-#define BTCOEX5_OFFSET                           0x0000023c
-#define BTCOEX5_IDLE_CNT_MSB                     15
-#define BTCOEX5_IDLE_CNT_LSB                     0
-#define BTCOEX5_IDLE_CNT_MASK                    0x0000ffff
-#define BTCOEX5_IDLE_CNT_GET(x)                  (((x) & BTCOEX5_IDLE_CNT_MASK) >> BTCOEX5_IDLE_CNT_LSB)
-#define BTCOEX5_IDLE_CNT_SET(x)                  (((x) << BTCOEX5_IDLE_CNT_LSB) & BTCOEX5_IDLE_CNT_MASK)
-
-#define BTCOEX6_ADDRESS                          0x00000240
-#define BTCOEX6_OFFSET                           0x00000240
-#define BTCOEX6_IDLE_RESET_LVL_BITMAP_MSB        31
-#define BTCOEX6_IDLE_RESET_LVL_BITMAP_LSB        0
-#define BTCOEX6_IDLE_RESET_LVL_BITMAP_MASK       0xffffffff
-#define BTCOEX6_IDLE_RESET_LVL_BITMAP_GET(x)     (((x) & BTCOEX6_IDLE_RESET_LVL_BITMAP_MASK) >> BTCOEX6_IDLE_RESET_LVL_BITMAP_LSB)
-#define BTCOEX6_IDLE_RESET_LVL_BITMAP_SET(x)     (((x) << BTCOEX6_IDLE_RESET_LVL_BITMAP_LSB) & BTCOEX6_IDLE_RESET_LVL_BITMAP_MASK)
-
-#define LOCK_ADDRESS                             0x00000244
-#define LOCK_OFFSET                              0x00000244
-#define LOCK_TLOCK_SLAVE_MSB                     31
-#define LOCK_TLOCK_SLAVE_LSB                     24
-#define LOCK_TLOCK_SLAVE_MASK                    0xff000000
-#define LOCK_TLOCK_SLAVE_GET(x)                  (((x) & LOCK_TLOCK_SLAVE_MASK) >> LOCK_TLOCK_SLAVE_LSB)
-#define LOCK_TLOCK_SLAVE_SET(x)                  (((x) << LOCK_TLOCK_SLAVE_LSB) & LOCK_TLOCK_SLAVE_MASK)
-#define LOCK_TUNLOCK_SLAVE_MSB                   23
-#define LOCK_TUNLOCK_SLAVE_LSB                   16
-#define LOCK_TUNLOCK_SLAVE_MASK                  0x00ff0000
-#define LOCK_TUNLOCK_SLAVE_GET(x)                (((x) & LOCK_TUNLOCK_SLAVE_MASK) >> LOCK_TUNLOCK_SLAVE_LSB)
-#define LOCK_TUNLOCK_SLAVE_SET(x)                (((x) << LOCK_TUNLOCK_SLAVE_LSB) & LOCK_TUNLOCK_SLAVE_MASK)
-#define LOCK_TLOCK_MASTER_MSB                    15
-#define LOCK_TLOCK_MASTER_LSB                    8
-#define LOCK_TLOCK_MASTER_MASK                   0x0000ff00
-#define LOCK_TLOCK_MASTER_GET(x)                 (((x) & LOCK_TLOCK_MASTER_MASK) >> LOCK_TLOCK_MASTER_LSB)
-#define LOCK_TLOCK_MASTER_SET(x)                 (((x) << LOCK_TLOCK_MASTER_LSB) & LOCK_TLOCK_MASTER_MASK)
-#define LOCK_TUNLOCK_MASTER_MSB                  7
-#define LOCK_TUNLOCK_MASTER_LSB                  0
-#define LOCK_TUNLOCK_MASTER_MASK                 0x000000ff
-#define LOCK_TUNLOCK_MASTER_GET(x)               (((x) & LOCK_TUNLOCK_MASTER_MASK) >> LOCK_TUNLOCK_MASTER_LSB)
-#define LOCK_TUNLOCK_MASTER_SET(x)               (((x) << LOCK_TUNLOCK_MASTER_LSB) & LOCK_TUNLOCK_MASTER_MASK)
-
-#define NOLOCK_PRIORITY_ADDRESS                  0x00000248
-#define NOLOCK_PRIORITY_OFFSET                   0x00000248
-#define NOLOCK_PRIORITY_BITMAP_MSB               31
-#define NOLOCK_PRIORITY_BITMAP_LSB               0
-#define NOLOCK_PRIORITY_BITMAP_MASK              0xffffffff
-#define NOLOCK_PRIORITY_BITMAP_GET(x)            (((x) & NOLOCK_PRIORITY_BITMAP_MASK) >> NOLOCK_PRIORITY_BITMAP_LSB)
-#define NOLOCK_PRIORITY_BITMAP_SET(x)            (((x) << NOLOCK_PRIORITY_BITMAP_LSB) & NOLOCK_PRIORITY_BITMAP_MASK)
-
-#define WBSYNC_ADDRESS                           0x0000024c
-#define WBSYNC_OFFSET                            0x0000024c
-#define WBSYNC_BTCLOCK_MSB                       31
-#define WBSYNC_BTCLOCK_LSB                       0
-#define WBSYNC_BTCLOCK_MASK                      0xffffffff
-#define WBSYNC_BTCLOCK_GET(x)                    (((x) & WBSYNC_BTCLOCK_MASK) >> WBSYNC_BTCLOCK_LSB)
-#define WBSYNC_BTCLOCK_SET(x)                    (((x) << WBSYNC_BTCLOCK_LSB) & WBSYNC_BTCLOCK_MASK)
-
-#define WBSYNC1_ADDRESS                          0x00000250
-#define WBSYNC1_OFFSET                           0x00000250
-#define WBSYNC1_BTCLOCK_MSB                      31
-#define WBSYNC1_BTCLOCK_LSB                      0
-#define WBSYNC1_BTCLOCK_MASK                     0xffffffff
-#define WBSYNC1_BTCLOCK_GET(x)                   (((x) & WBSYNC1_BTCLOCK_MASK) >> WBSYNC1_BTCLOCK_LSB)
-#define WBSYNC1_BTCLOCK_SET(x)                   (((x) << WBSYNC1_BTCLOCK_LSB) & WBSYNC1_BTCLOCK_MASK)
-
-#define WBSYNC2_ADDRESS                          0x00000254
-#define WBSYNC2_OFFSET                           0x00000254
-#define WBSYNC2_BTCLOCK_MSB                      31
-#define WBSYNC2_BTCLOCK_LSB                      0
-#define WBSYNC2_BTCLOCK_MASK                     0xffffffff
-#define WBSYNC2_BTCLOCK_GET(x)                   (((x) & WBSYNC2_BTCLOCK_MASK) >> WBSYNC2_BTCLOCK_LSB)
-#define WBSYNC2_BTCLOCK_SET(x)                   (((x) << WBSYNC2_BTCLOCK_LSB) & WBSYNC2_BTCLOCK_MASK)
-
-#define WBSYNC3_ADDRESS                          0x00000258
-#define WBSYNC3_OFFSET                           0x00000258
-#define WBSYNC3_BTCLOCK_MSB                      31
-#define WBSYNC3_BTCLOCK_LSB                      0
-#define WBSYNC3_BTCLOCK_MASK                     0xffffffff
-#define WBSYNC3_BTCLOCK_GET(x)                   (((x) & WBSYNC3_BTCLOCK_MASK) >> WBSYNC3_BTCLOCK_LSB)
-#define WBSYNC3_BTCLOCK_SET(x)                   (((x) << WBSYNC3_BTCLOCK_LSB) & WBSYNC3_BTCLOCK_MASK)
-
-#define WB_TIMER_TARGET_ADDRESS                  0x0000025c
-#define WB_TIMER_TARGET_OFFSET                   0x0000025c
-#define WB_TIMER_TARGET_VALUE_MSB                31
-#define WB_TIMER_TARGET_VALUE_LSB                0
-#define WB_TIMER_TARGET_VALUE_MASK               0xffffffff
-#define WB_TIMER_TARGET_VALUE_GET(x)             (((x) & WB_TIMER_TARGET_VALUE_MASK) >> WB_TIMER_TARGET_VALUE_LSB)
-#define WB_TIMER_TARGET_VALUE_SET(x)             (((x) << WB_TIMER_TARGET_VALUE_LSB) & WB_TIMER_TARGET_VALUE_MASK)
-
-#define WB_TIMER_SLOP_ADDRESS                    0x00000260
-#define WB_TIMER_SLOP_OFFSET                     0x00000260
-#define WB_TIMER_SLOP_VALUE_MSB                  9
-#define WB_TIMER_SLOP_VALUE_LSB                  0
-#define WB_TIMER_SLOP_VALUE_MASK                 0x000003ff
-#define WB_TIMER_SLOP_VALUE_GET(x)               (((x) & WB_TIMER_SLOP_VALUE_MASK) >> WB_TIMER_SLOP_VALUE_LSB)
-#define WB_TIMER_SLOP_VALUE_SET(x)               (((x) << WB_TIMER_SLOP_VALUE_LSB) & WB_TIMER_SLOP_VALUE_MASK)
-
-#define BTCOEX_INT_EN_ADDRESS                    0x00000264
-#define BTCOEX_INT_EN_OFFSET                     0x00000264
-#define BTCOEX_INT_EN_I2C_RECV_OVERFLOW_MSB      11
-#define BTCOEX_INT_EN_I2C_RECV_OVERFLOW_LSB      11
-#define BTCOEX_INT_EN_I2C_RECV_OVERFLOW_MASK     0x00000800
-#define BTCOEX_INT_EN_I2C_RECV_OVERFLOW_GET(x)   (((x) & BTCOEX_INT_EN_I2C_RECV_OVERFLOW_MASK) >> BTCOEX_INT_EN_I2C_RECV_OVERFLOW_LSB)
-#define BTCOEX_INT_EN_I2C_RECV_OVERFLOW_SET(x)   (((x) << BTCOEX_INT_EN_I2C_RECV_OVERFLOW_LSB) & BTCOEX_INT_EN_I2C_RECV_OVERFLOW_MASK)
-#define BTCOEX_INT_EN_I2C_TX_FAILED_MSB          10
-#define BTCOEX_INT_EN_I2C_TX_FAILED_LSB          10
-#define BTCOEX_INT_EN_I2C_TX_FAILED_MASK         0x00000400
-#define BTCOEX_INT_EN_I2C_TX_FAILED_GET(x)       (((x) & BTCOEX_INT_EN_I2C_TX_FAILED_MASK) >> BTCOEX_INT_EN_I2C_TX_FAILED_LSB)
-#define BTCOEX_INT_EN_I2C_TX_FAILED_SET(x)       (((x) << BTCOEX_INT_EN_I2C_TX_FAILED_LSB) & BTCOEX_INT_EN_I2C_TX_FAILED_MASK)
-#define BTCOEX_INT_EN_I2C_MESG_SENT_MSB          9
-#define BTCOEX_INT_EN_I2C_MESG_SENT_LSB          9
-#define BTCOEX_INT_EN_I2C_MESG_SENT_MASK         0x00000200
-#define BTCOEX_INT_EN_I2C_MESG_SENT_GET(x)       (((x) & BTCOEX_INT_EN_I2C_MESG_SENT_MASK) >> BTCOEX_INT_EN_I2C_MESG_SENT_LSB)
-#define BTCOEX_INT_EN_I2C_MESG_SENT_SET(x)       (((x) << BTCOEX_INT_EN_I2C_MESG_SENT_LSB) & BTCOEX_INT_EN_I2C_MESG_SENT_MASK)
-#define BTCOEX_INT_EN_ST_MESG_RECV_MSB           8
-#define BTCOEX_INT_EN_ST_MESG_RECV_LSB           8
-#define BTCOEX_INT_EN_ST_MESG_RECV_MASK          0x00000100
-#define BTCOEX_INT_EN_ST_MESG_RECV_GET(x)        (((x) & BTCOEX_INT_EN_ST_MESG_RECV_MASK) >> BTCOEX_INT_EN_ST_MESG_RECV_LSB)
-#define BTCOEX_INT_EN_ST_MESG_RECV_SET(x)        (((x) << BTCOEX_INT_EN_ST_MESG_RECV_LSB) & BTCOEX_INT_EN_ST_MESG_RECV_MASK)
-#define BTCOEX_INT_EN_WB_TIMER_MSB               7
-#define BTCOEX_INT_EN_WB_TIMER_LSB               7
-#define BTCOEX_INT_EN_WB_TIMER_MASK              0x00000080
-#define BTCOEX_INT_EN_WB_TIMER_GET(x)            (((x) & BTCOEX_INT_EN_WB_TIMER_MASK) >> BTCOEX_INT_EN_WB_TIMER_LSB)
-#define BTCOEX_INT_EN_WB_TIMER_SET(x)            (((x) << BTCOEX_INT_EN_WB_TIMER_LSB) & BTCOEX_INT_EN_WB_TIMER_MASK)
-#define BTCOEX_INT_EN_NOSYNC_MSB                 4
-#define BTCOEX_INT_EN_NOSYNC_LSB                 4
-#define BTCOEX_INT_EN_NOSYNC_MASK                0x00000010
-#define BTCOEX_INT_EN_NOSYNC_GET(x)              (((x) & BTCOEX_INT_EN_NOSYNC_MASK) >> BTCOEX_INT_EN_NOSYNC_LSB)
-#define BTCOEX_INT_EN_NOSYNC_SET(x)              (((x) << BTCOEX_INT_EN_NOSYNC_LSB) & BTCOEX_INT_EN_NOSYNC_MASK)
-#define BTCOEX_INT_EN_SYNC_MSB                   3
-#define BTCOEX_INT_EN_SYNC_LSB                   3
-#define BTCOEX_INT_EN_SYNC_MASK                  0x00000008
-#define BTCOEX_INT_EN_SYNC_GET(x)                (((x) & BTCOEX_INT_EN_SYNC_MASK) >> BTCOEX_INT_EN_SYNC_LSB)
-#define BTCOEX_INT_EN_SYNC_SET(x)                (((x) << BTCOEX_INT_EN_SYNC_LSB) & BTCOEX_INT_EN_SYNC_MASK)
-#define BTCOEX_INT_EN_END_MSB                    2
-#define BTCOEX_INT_EN_END_LSB                    2
-#define BTCOEX_INT_EN_END_MASK                   0x00000004
-#define BTCOEX_INT_EN_END_GET(x)                 (((x) & BTCOEX_INT_EN_END_MASK) >> BTCOEX_INT_EN_END_LSB)
-#define BTCOEX_INT_EN_END_SET(x)                 (((x) << BTCOEX_INT_EN_END_LSB) & BTCOEX_INT_EN_END_MASK)
-#define BTCOEX_INT_EN_FRAME_CNT_MSB              1
-#define BTCOEX_INT_EN_FRAME_CNT_LSB              1
-#define BTCOEX_INT_EN_FRAME_CNT_MASK             0x00000002
-#define BTCOEX_INT_EN_FRAME_CNT_GET(x)           (((x) & BTCOEX_INT_EN_FRAME_CNT_MASK) >> BTCOEX_INT_EN_FRAME_CNT_LSB)
-#define BTCOEX_INT_EN_FRAME_CNT_SET(x)           (((x) << BTCOEX_INT_EN_FRAME_CNT_LSB) & BTCOEX_INT_EN_FRAME_CNT_MASK)
-#define BTCOEX_INT_EN_CLK_CNT_MSB                0
-#define BTCOEX_INT_EN_CLK_CNT_LSB                0
-#define BTCOEX_INT_EN_CLK_CNT_MASK               0x00000001
-#define BTCOEX_INT_EN_CLK_CNT_GET(x)             (((x) & BTCOEX_INT_EN_CLK_CNT_MASK) >> BTCOEX_INT_EN_CLK_CNT_LSB)
-#define BTCOEX_INT_EN_CLK_CNT_SET(x)             (((x) << BTCOEX_INT_EN_CLK_CNT_LSB) & BTCOEX_INT_EN_CLK_CNT_MASK)
-
-#define BTCOEX_INT_STAT_ADDRESS                  0x00000268
-#define BTCOEX_INT_STAT_OFFSET                   0x00000268
-#define BTCOEX_INT_STAT_I2C_RECV_OVERFLOW_MSB    11
-#define BTCOEX_INT_STAT_I2C_RECV_OVERFLOW_LSB    11
-#define BTCOEX_INT_STAT_I2C_RECV_OVERFLOW_MASK   0x00000800
-#define BTCOEX_INT_STAT_I2C_RECV_OVERFLOW_GET(x) (((x) & BTCOEX_INT_STAT_I2C_RECV_OVERFLOW_MASK) >> BTCOEX_INT_STAT_I2C_RECV_OVERFLOW_LSB)
-#define BTCOEX_INT_STAT_I2C_RECV_OVERFLOW_SET(x) (((x) << BTCOEX_INT_STAT_I2C_RECV_OVERFLOW_LSB) & BTCOEX_INT_STAT_I2C_RECV_OVERFLOW_MASK)
-#define BTCOEX_INT_STAT_I2C_TX_FAILED_MSB        10
-#define BTCOEX_INT_STAT_I2C_TX_FAILED_LSB        10
-#define BTCOEX_INT_STAT_I2C_TX_FAILED_MASK       0x00000400
-#define BTCOEX_INT_STAT_I2C_TX_FAILED_GET(x)     (((x) & BTCOEX_INT_STAT_I2C_TX_FAILED_MASK) >> BTCOEX_INT_STAT_I2C_TX_FAILED_LSB)
-#define BTCOEX_INT_STAT_I2C_TX_FAILED_SET(x)     (((x) << BTCOEX_INT_STAT_I2C_TX_FAILED_LSB) & BTCOEX_INT_STAT_I2C_TX_FAILED_MASK)
-#define BTCOEX_INT_STAT_I2C_MESG_SENT_MSB        9
-#define BTCOEX_INT_STAT_I2C_MESG_SENT_LSB        9
-#define BTCOEX_INT_STAT_I2C_MESG_SENT_MASK       0x00000200
-#define BTCOEX_INT_STAT_I2C_MESG_SENT_GET(x)     (((x) & BTCOEX_INT_STAT_I2C_MESG_SENT_MASK) >> BTCOEX_INT_STAT_I2C_MESG_SENT_LSB)
-#define BTCOEX_INT_STAT_I2C_MESG_SENT_SET(x)     (((x) << BTCOEX_INT_STAT_I2C_MESG_SENT_LSB) & BTCOEX_INT_STAT_I2C_MESG_SENT_MASK)
-#define BTCOEX_INT_STAT_I2C_MESG_RECV_MSB        8
-#define BTCOEX_INT_STAT_I2C_MESG_RECV_LSB        8
-#define BTCOEX_INT_STAT_I2C_MESG_RECV_MASK       0x00000100
-#define BTCOEX_INT_STAT_I2C_MESG_RECV_GET(x)     (((x) & BTCOEX_INT_STAT_I2C_MESG_RECV_MASK) >> BTCOEX_INT_STAT_I2C_MESG_RECV_LSB)
-#define BTCOEX_INT_STAT_I2C_MESG_RECV_SET(x)     (((x) << BTCOEX_INT_STAT_I2C_MESG_RECV_LSB) & BTCOEX_INT_STAT_I2C_MESG_RECV_MASK)
-#define BTCOEX_INT_STAT_WB_TIMER_MSB             7
-#define BTCOEX_INT_STAT_WB_TIMER_LSB             7
-#define BTCOEX_INT_STAT_WB_TIMER_MASK            0x00000080
-#define BTCOEX_INT_STAT_WB_TIMER_GET(x)          (((x) & BTCOEX_INT_STAT_WB_TIMER_MASK) >> BTCOEX_INT_STAT_WB_TIMER_LSB)
-#define BTCOEX_INT_STAT_WB_TIMER_SET(x)          (((x) << BTCOEX_INT_STAT_WB_TIMER_LSB) & BTCOEX_INT_STAT_WB_TIMER_MASK)
-#define BTCOEX_INT_STAT_BTPRIORITY_STOMP_MSB     6
-#define BTCOEX_INT_STAT_BTPRIORITY_STOMP_LSB     6
-#define BTCOEX_INT_STAT_BTPRIORITY_STOMP_MASK    0x00000040
-#define BTCOEX_INT_STAT_BTPRIORITY_STOMP_GET(x)  (((x) & BTCOEX_INT_STAT_BTPRIORITY_STOMP_MASK) >> BTCOEX_INT_STAT_BTPRIORITY_STOMP_LSB)
-#define BTCOEX_INT_STAT_BTPRIORITY_STOMP_SET(x)  (((x) << BTCOEX_INT_STAT_BTPRIORITY_STOMP_LSB) & BTCOEX_INT_STAT_BTPRIORITY_STOMP_MASK)
-#define BTCOEX_INT_STAT_BTPRIORITY_MSB           5
-#define BTCOEX_INT_STAT_BTPRIORITY_LSB           5
-#define BTCOEX_INT_STAT_BTPRIORITY_MASK          0x00000020
-#define BTCOEX_INT_STAT_BTPRIORITY_GET(x)        (((x) & BTCOEX_INT_STAT_BTPRIORITY_MASK) >> BTCOEX_INT_STAT_BTPRIORITY_LSB)
-#define BTCOEX_INT_STAT_BTPRIORITY_SET(x)        (((x) << BTCOEX_INT_STAT_BTPRIORITY_LSB) & BTCOEX_INT_STAT_BTPRIORITY_MASK)
-#define BTCOEX_INT_STAT_NOSYNC_MSB               4
-#define BTCOEX_INT_STAT_NOSYNC_LSB               4
-#define BTCOEX_INT_STAT_NOSYNC_MASK              0x00000010
-#define BTCOEX_INT_STAT_NOSYNC_GET(x)            (((x) & BTCOEX_INT_STAT_NOSYNC_MASK) >> BTCOEX_INT_STAT_NOSYNC_LSB)
-#define BTCOEX_INT_STAT_NOSYNC_SET(x)            (((x) << BTCOEX_INT_STAT_NOSYNC_LSB) & BTCOEX_INT_STAT_NOSYNC_MASK)
-#define BTCOEX_INT_STAT_SYNC_MSB                 3
-#define BTCOEX_INT_STAT_SYNC_LSB                 3
-#define BTCOEX_INT_STAT_SYNC_MASK                0x00000008
-#define BTCOEX_INT_STAT_SYNC_GET(x)              (((x) & BTCOEX_INT_STAT_SYNC_MASK) >> BTCOEX_INT_STAT_SYNC_LSB)
-#define BTCOEX_INT_STAT_SYNC_SET(x)              (((x) << BTCOEX_INT_STAT_SYNC_LSB) & BTCOEX_INT_STAT_SYNC_MASK)
-#define BTCOEX_INT_STAT_END_MSB                  2
-#define BTCOEX_INT_STAT_END_LSB                  2
-#define BTCOEX_INT_STAT_END_MASK                 0x00000004
-#define BTCOEX_INT_STAT_END_GET(x)               (((x) & BTCOEX_INT_STAT_END_MASK) >> BTCOEX_INT_STAT_END_LSB)
-#define BTCOEX_INT_STAT_END_SET(x)               (((x) << BTCOEX_INT_STAT_END_LSB) & BTCOEX_INT_STAT_END_MASK)
-#define BTCOEX_INT_STAT_FRAME_CNT_MSB            1
-#define BTCOEX_INT_STAT_FRAME_CNT_LSB            1
-#define BTCOEX_INT_STAT_FRAME_CNT_MASK           0x00000002
-#define BTCOEX_INT_STAT_FRAME_CNT_GET(x)         (((x) & BTCOEX_INT_STAT_FRAME_CNT_MASK) >> BTCOEX_INT_STAT_FRAME_CNT_LSB)
-#define BTCOEX_INT_STAT_FRAME_CNT_SET(x)         (((x) << BTCOEX_INT_STAT_FRAME_CNT_LSB) & BTCOEX_INT_STAT_FRAME_CNT_MASK)
-#define BTCOEX_INT_STAT_CLK_CNT_MSB              0
-#define BTCOEX_INT_STAT_CLK_CNT_LSB              0
-#define BTCOEX_INT_STAT_CLK_CNT_MASK             0x00000001
-#define BTCOEX_INT_STAT_CLK_CNT_GET(x)           (((x) & BTCOEX_INT_STAT_CLK_CNT_MASK) >> BTCOEX_INT_STAT_CLK_CNT_LSB)
-#define BTCOEX_INT_STAT_CLK_CNT_SET(x)           (((x) << BTCOEX_INT_STAT_CLK_CNT_LSB) & BTCOEX_INT_STAT_CLK_CNT_MASK)
-
-#define BTPRIORITY_INT_EN_ADDRESS                0x0000026c
-#define BTPRIORITY_INT_EN_OFFSET                 0x0000026c
-#define BTPRIORITY_INT_EN_BITMAP_MSB             31
-#define BTPRIORITY_INT_EN_BITMAP_LSB             0
-#define BTPRIORITY_INT_EN_BITMAP_MASK            0xffffffff
-#define BTPRIORITY_INT_EN_BITMAP_GET(x)          (((x) & BTPRIORITY_INT_EN_BITMAP_MASK) >> BTPRIORITY_INT_EN_BITMAP_LSB)
-#define BTPRIORITY_INT_EN_BITMAP_SET(x)          (((x) << BTPRIORITY_INT_EN_BITMAP_LSB) & BTPRIORITY_INT_EN_BITMAP_MASK)
-
-#define BTPRIORITY_INT_STAT_ADDRESS              0x00000270
-#define BTPRIORITY_INT_STAT_OFFSET               0x00000270
-#define BTPRIORITY_INT_STAT_BITMAP_MSB           31
-#define BTPRIORITY_INT_STAT_BITMAP_LSB           0
-#define BTPRIORITY_INT_STAT_BITMAP_MASK          0xffffffff
-#define BTPRIORITY_INT_STAT_BITMAP_GET(x)        (((x) & BTPRIORITY_INT_STAT_BITMAP_MASK) >> BTPRIORITY_INT_STAT_BITMAP_LSB)
-#define BTPRIORITY_INT_STAT_BITMAP_SET(x)        (((x) << BTPRIORITY_INT_STAT_BITMAP_LSB) & BTPRIORITY_INT_STAT_BITMAP_MASK)
-
-#define BTPRIORITY_STOMP_INT_EN_ADDRESS          0x00000274
-#define BTPRIORITY_STOMP_INT_EN_OFFSET           0x00000274
-#define BTPRIORITY_STOMP_INT_EN_BITMAP_MSB       31
-#define BTPRIORITY_STOMP_INT_EN_BITMAP_LSB       0
-#define BTPRIORITY_STOMP_INT_EN_BITMAP_MASK      0xffffffff
-#define BTPRIORITY_STOMP_INT_EN_BITMAP_GET(x)    (((x) & BTPRIORITY_STOMP_INT_EN_BITMAP_MASK) >> BTPRIORITY_STOMP_INT_EN_BITMAP_LSB)
-#define BTPRIORITY_STOMP_INT_EN_BITMAP_SET(x)    (((x) << BTPRIORITY_STOMP_INT_EN_BITMAP_LSB) & BTPRIORITY_STOMP_INT_EN_BITMAP_MASK)
-
-#define BTPRIORITY_STOMP_INT_STAT_ADDRESS        0x00000278
-#define BTPRIORITY_STOMP_INT_STAT_OFFSET         0x00000278
-#define BTPRIORITY_STOMP_INT_STAT_BITMAP_MSB     31
-#define BTPRIORITY_STOMP_INT_STAT_BITMAP_LSB     0
-#define BTPRIORITY_STOMP_INT_STAT_BITMAP_MASK    0xffffffff
-#define BTPRIORITY_STOMP_INT_STAT_BITMAP_GET(x)  (((x) & BTPRIORITY_STOMP_INT_STAT_BITMAP_MASK) >> BTPRIORITY_STOMP_INT_STAT_BITMAP_LSB)
-#define BTPRIORITY_STOMP_INT_STAT_BITMAP_SET(x)  (((x) << BTPRIORITY_STOMP_INT_STAT_BITMAP_LSB) & BTPRIORITY_STOMP_INT_STAT_BITMAP_MASK)
-
-#define MAC_PCU_BMISS_TIMEOUT_ADDRESS            0x0000027c
-#define MAC_PCU_BMISS_TIMEOUT_OFFSET             0x0000027c
-#define MAC_PCU_BMISS_TIMEOUT_ENABLE_MSB         24
-#define MAC_PCU_BMISS_TIMEOUT_ENABLE_LSB         24
-#define MAC_PCU_BMISS_TIMEOUT_ENABLE_MASK        0x01000000
-#define MAC_PCU_BMISS_TIMEOUT_ENABLE_GET(x)      (((x) & MAC_PCU_BMISS_TIMEOUT_ENABLE_MASK) >> MAC_PCU_BMISS_TIMEOUT_ENABLE_LSB)
-#define MAC_PCU_BMISS_TIMEOUT_ENABLE_SET(x)      (((x) << MAC_PCU_BMISS_TIMEOUT_ENABLE_LSB) & MAC_PCU_BMISS_TIMEOUT_ENABLE_MASK)
-#define MAC_PCU_BMISS_TIMEOUT_VALUE_MSB          23
-#define MAC_PCU_BMISS_TIMEOUT_VALUE_LSB          0
-#define MAC_PCU_BMISS_TIMEOUT_VALUE_MASK         0x00ffffff
-#define MAC_PCU_BMISS_TIMEOUT_VALUE_GET(x)       (((x) & MAC_PCU_BMISS_TIMEOUT_VALUE_MASK) >> MAC_PCU_BMISS_TIMEOUT_VALUE_LSB)
-#define MAC_PCU_BMISS_TIMEOUT_VALUE_SET(x)       (((x) << MAC_PCU_BMISS_TIMEOUT_VALUE_LSB) & MAC_PCU_BMISS_TIMEOUT_VALUE_MASK)
-
-#define MAC_PCU_CAB_AWAKE_ADDRESS                0x00000280
-#define MAC_PCU_CAB_AWAKE_OFFSET                 0x00000280
-#define MAC_PCU_CAB_AWAKE_ENABLE_MSB             16
-#define MAC_PCU_CAB_AWAKE_ENABLE_LSB             16
-#define MAC_PCU_CAB_AWAKE_ENABLE_MASK            0x00010000
-#define MAC_PCU_CAB_AWAKE_ENABLE_GET(x)          (((x) & MAC_PCU_CAB_AWAKE_ENABLE_MASK) >> MAC_PCU_CAB_AWAKE_ENABLE_LSB)
-#define MAC_PCU_CAB_AWAKE_ENABLE_SET(x)          (((x) << MAC_PCU_CAB_AWAKE_ENABLE_LSB) & MAC_PCU_CAB_AWAKE_ENABLE_MASK)
-#define MAC_PCU_CAB_AWAKE_DURATION_MSB           15
-#define MAC_PCU_CAB_AWAKE_DURATION_LSB           0
-#define MAC_PCU_CAB_AWAKE_DURATION_MASK          0x0000ffff
-#define MAC_PCU_CAB_AWAKE_DURATION_GET(x)        (((x) & MAC_PCU_CAB_AWAKE_DURATION_MASK) >> MAC_PCU_CAB_AWAKE_DURATION_LSB)
-#define MAC_PCU_CAB_AWAKE_DURATION_SET(x)        (((x) << MAC_PCU_CAB_AWAKE_DURATION_LSB) & MAC_PCU_CAB_AWAKE_DURATION_MASK)
-
-#define LP_PERF_COUNTER_ADDRESS                  0x00000284
-#define LP_PERF_COUNTER_OFFSET                   0x00000284
-#define LP_PERF_COUNTER_EN_MSB                   0
-#define LP_PERF_COUNTER_EN_LSB                   0
-#define LP_PERF_COUNTER_EN_MASK                  0x00000001
-#define LP_PERF_COUNTER_EN_GET(x)                (((x) & LP_PERF_COUNTER_EN_MASK) >> LP_PERF_COUNTER_EN_LSB)
-#define LP_PERF_COUNTER_EN_SET(x)                (((x) << LP_PERF_COUNTER_EN_LSB) & LP_PERF_COUNTER_EN_MASK)
-
-#define LP_PERF_LIGHT_SLEEP_ADDRESS              0x00000288
-#define LP_PERF_LIGHT_SLEEP_OFFSET               0x00000288
-#define LP_PERF_LIGHT_SLEEP_CNT_MSB              31
-#define LP_PERF_LIGHT_SLEEP_CNT_LSB              0
-#define LP_PERF_LIGHT_SLEEP_CNT_MASK             0xffffffff
-#define LP_PERF_LIGHT_SLEEP_CNT_GET(x)           (((x) & LP_PERF_LIGHT_SLEEP_CNT_MASK) >> LP_PERF_LIGHT_SLEEP_CNT_LSB)
-#define LP_PERF_LIGHT_SLEEP_CNT_SET(x)           (((x) << LP_PERF_LIGHT_SLEEP_CNT_LSB) & LP_PERF_LIGHT_SLEEP_CNT_MASK)
-
-#define LP_PERF_DEEP_SLEEP_ADDRESS               0x0000028c
-#define LP_PERF_DEEP_SLEEP_OFFSET                0x0000028c
-#define LP_PERF_DEEP_SLEEP_CNT_MSB               31
-#define LP_PERF_DEEP_SLEEP_CNT_LSB               0
-#define LP_PERF_DEEP_SLEEP_CNT_MASK              0xffffffff
-#define LP_PERF_DEEP_SLEEP_CNT_GET(x)            (((x) & LP_PERF_DEEP_SLEEP_CNT_MASK) >> LP_PERF_DEEP_SLEEP_CNT_LSB)
-#define LP_PERF_DEEP_SLEEP_CNT_SET(x)            (((x) << LP_PERF_DEEP_SLEEP_CNT_LSB) & LP_PERF_DEEP_SLEEP_CNT_MASK)
-
-#define LP_PERF_ON_ADDRESS                       0x00000290
-#define LP_PERF_ON_OFFSET                        0x00000290
-#define LP_PERF_ON_CNT_MSB                       31
-#define LP_PERF_ON_CNT_LSB                       0
-#define LP_PERF_ON_CNT_MASK                      0xffffffff
-#define LP_PERF_ON_CNT_GET(x)                    (((x) & LP_PERF_ON_CNT_MASK) >> LP_PERF_ON_CNT_LSB)
-#define LP_PERF_ON_CNT_SET(x)                    (((x) << LP_PERF_ON_CNT_LSB) & LP_PERF_ON_CNT_MASK)
-
-#define ST_64_BIT_ADDRESS                        0x00000294
-#define ST_64_BIT_OFFSET                         0x00000294
-#define ST_64_BIT_TIMEOUT_MSB                    26
-#define ST_64_BIT_TIMEOUT_LSB                    9
-#define ST_64_BIT_TIMEOUT_MASK                   0x07fffe00
-#define ST_64_BIT_TIMEOUT_GET(x)                 (((x) & ST_64_BIT_TIMEOUT_MASK) >> ST_64_BIT_TIMEOUT_LSB)
-#define ST_64_BIT_TIMEOUT_SET(x)                 (((x) << ST_64_BIT_TIMEOUT_LSB) & ST_64_BIT_TIMEOUT_MASK)
-#define ST_64_BIT_REQ_ACK_NOT_PULLED_DOWN_MSB    8
-#define ST_64_BIT_REQ_ACK_NOT_PULLED_DOWN_LSB    8
-#define ST_64_BIT_REQ_ACK_NOT_PULLED_DOWN_MASK   0x00000100
-#define ST_64_BIT_REQ_ACK_NOT_PULLED_DOWN_GET(x) (((x) & ST_64_BIT_REQ_ACK_NOT_PULLED_DOWN_MASK) >> ST_64_BIT_REQ_ACK_NOT_PULLED_DOWN_LSB)
-#define ST_64_BIT_REQ_ACK_NOT_PULLED_DOWN_SET(x) (((x) << ST_64_BIT_REQ_ACK_NOT_PULLED_DOWN_LSB) & ST_64_BIT_REQ_ACK_NOT_PULLED_DOWN_MASK)
-#define ST_64_BIT_DRIVE_MODE_MSB                 7
-#define ST_64_BIT_DRIVE_MODE_LSB                 7
-#define ST_64_BIT_DRIVE_MODE_MASK                0x00000080
-#define ST_64_BIT_DRIVE_MODE_GET(x)              (((x) & ST_64_BIT_DRIVE_MODE_MASK) >> ST_64_BIT_DRIVE_MODE_LSB)
-#define ST_64_BIT_DRIVE_MODE_SET(x)              (((x) << ST_64_BIT_DRIVE_MODE_LSB) & ST_64_BIT_DRIVE_MODE_MASK)
-#define ST_64_BIT_CLOCK_GATE_MSB                 6
-#define ST_64_BIT_CLOCK_GATE_LSB                 6
-#define ST_64_BIT_CLOCK_GATE_MASK                0x00000040
-#define ST_64_BIT_CLOCK_GATE_GET(x)              (((x) & ST_64_BIT_CLOCK_GATE_MASK) >> ST_64_BIT_CLOCK_GATE_LSB)
-#define ST_64_BIT_CLOCK_GATE_SET(x)              (((x) << ST_64_BIT_CLOCK_GATE_LSB) & ST_64_BIT_CLOCK_GATE_MASK)
-#define ST_64_BIT_SOC_CLK_DIVIDE_RATIO_MSB       5
-#define ST_64_BIT_SOC_CLK_DIVIDE_RATIO_LSB       1
-#define ST_64_BIT_SOC_CLK_DIVIDE_RATIO_MASK      0x0000003e
-#define ST_64_BIT_SOC_CLK_DIVIDE_RATIO_GET(x)    (((x) & ST_64_BIT_SOC_CLK_DIVIDE_RATIO_MASK) >> ST_64_BIT_SOC_CLK_DIVIDE_RATIO_LSB)
-#define ST_64_BIT_SOC_CLK_DIVIDE_RATIO_SET(x)    (((x) << ST_64_BIT_SOC_CLK_DIVIDE_RATIO_LSB) & ST_64_BIT_SOC_CLK_DIVIDE_RATIO_MASK)
-#define ST_64_BIT_MODE_MSB                       0
-#define ST_64_BIT_MODE_LSB                       0
-#define ST_64_BIT_MODE_MASK                      0x00000001
-#define ST_64_BIT_MODE_GET(x)                    (((x) & ST_64_BIT_MODE_MASK) >> ST_64_BIT_MODE_LSB)
-#define ST_64_BIT_MODE_SET(x)                    (((x) << ST_64_BIT_MODE_LSB) & ST_64_BIT_MODE_MASK)
-
-#define MESSAGE_WR_ADDRESS                       0x00000298
-#define MESSAGE_WR_OFFSET                        0x00000298
-#define MESSAGE_WR_TYPE_MSB                      31
-#define MESSAGE_WR_TYPE_LSB                      0
-#define MESSAGE_WR_TYPE_MASK                     0xffffffff
-#define MESSAGE_WR_TYPE_GET(x)                   (((x) & MESSAGE_WR_TYPE_MASK) >> MESSAGE_WR_TYPE_LSB)
-#define MESSAGE_WR_TYPE_SET(x)                   (((x) << MESSAGE_WR_TYPE_LSB) & MESSAGE_WR_TYPE_MASK)
-
-#define MESSAGE_WR_P_ADDRESS                     0x0000029c
-#define MESSAGE_WR_P_OFFSET                      0x0000029c
-#define MESSAGE_WR_P_PARAMETER_MSB               31
-#define MESSAGE_WR_P_PARAMETER_LSB               0
-#define MESSAGE_WR_P_PARAMETER_MASK              0xffffffff
-#define MESSAGE_WR_P_PARAMETER_GET(x)            (((x) & MESSAGE_WR_P_PARAMETER_MASK) >> MESSAGE_WR_P_PARAMETER_LSB)
-#define MESSAGE_WR_P_PARAMETER_SET(x)            (((x) << MESSAGE_WR_P_PARAMETER_LSB) & MESSAGE_WR_P_PARAMETER_MASK)
-
-#define MESSAGE_RD_ADDRESS                       0x000002a0
-#define MESSAGE_RD_OFFSET                        0x000002a0
-#define MESSAGE_RD_TYPE_MSB                      31
-#define MESSAGE_RD_TYPE_LSB                      0
-#define MESSAGE_RD_TYPE_MASK                     0xffffffff
-#define MESSAGE_RD_TYPE_GET(x)                   (((x) & MESSAGE_RD_TYPE_MASK) >> MESSAGE_RD_TYPE_LSB)
-#define MESSAGE_RD_TYPE_SET(x)                   (((x) << MESSAGE_RD_TYPE_LSB) & MESSAGE_RD_TYPE_MASK)
-
-#define MESSAGE_RD_P_ADDRESS                     0x000002a4
-#define MESSAGE_RD_P_OFFSET                      0x000002a4
-#define MESSAGE_RD_P_PARAMETER_MSB               31
-#define MESSAGE_RD_P_PARAMETER_LSB               0
-#define MESSAGE_RD_P_PARAMETER_MASK              0xffffffff
-#define MESSAGE_RD_P_PARAMETER_GET(x)            (((x) & MESSAGE_RD_P_PARAMETER_MASK) >> MESSAGE_RD_P_PARAMETER_LSB)
-#define MESSAGE_RD_P_PARAMETER_SET(x)            (((x) << MESSAGE_RD_P_PARAMETER_LSB) & MESSAGE_RD_P_PARAMETER_MASK)
-
-#define CHIP_MODE_ADDRESS                        0x000002a8
-#define CHIP_MODE_OFFSET                         0x000002a8
-#define CHIP_MODE_BIT_MSB                        1
-#define CHIP_MODE_BIT_LSB                        0
-#define CHIP_MODE_BIT_MASK                       0x00000003
-#define CHIP_MODE_BIT_GET(x)                     (((x) & CHIP_MODE_BIT_MASK) >> CHIP_MODE_BIT_LSB)
-#define CHIP_MODE_BIT_SET(x)                     (((x) << CHIP_MODE_BIT_LSB) & CHIP_MODE_BIT_MASK)
-
-#define CLK_REQ_FALL_EDGE_ADDRESS                0x000002ac
-#define CLK_REQ_FALL_EDGE_OFFSET                 0x000002ac
-#define CLK_REQ_FALL_EDGE_EN_MSB                 31
-#define CLK_REQ_FALL_EDGE_EN_LSB                 31
-#define CLK_REQ_FALL_EDGE_EN_MASK                0x80000000
-#define CLK_REQ_FALL_EDGE_EN_GET(x)              (((x) & CLK_REQ_FALL_EDGE_EN_MASK) >> CLK_REQ_FALL_EDGE_EN_LSB)
-#define CLK_REQ_FALL_EDGE_EN_SET(x)              (((x) << CLK_REQ_FALL_EDGE_EN_LSB) & CLK_REQ_FALL_EDGE_EN_MASK)
-#define CLK_REQ_FALL_EDGE_DELAY_MSB              7
-#define CLK_REQ_FALL_EDGE_DELAY_LSB              0
-#define CLK_REQ_FALL_EDGE_DELAY_MASK             0x000000ff
-#define CLK_REQ_FALL_EDGE_DELAY_GET(x)           (((x) & CLK_REQ_FALL_EDGE_DELAY_MASK) >> CLK_REQ_FALL_EDGE_DELAY_LSB)
-#define CLK_REQ_FALL_EDGE_DELAY_SET(x)           (((x) << CLK_REQ_FALL_EDGE_DELAY_LSB) & CLK_REQ_FALL_EDGE_DELAY_MASK)
-
-#define OTP_ADDRESS                              0x000002b0
-#define OTP_OFFSET                               0x000002b0
-#define OTP_LDO25_EN_MSB                         1
-#define OTP_LDO25_EN_LSB                         1
-#define OTP_LDO25_EN_MASK                        0x00000002
-#define OTP_LDO25_EN_GET(x)                      (((x) & OTP_LDO25_EN_MASK) >> OTP_LDO25_EN_LSB)
-#define OTP_LDO25_EN_SET(x)                      (((x) << OTP_LDO25_EN_LSB) & OTP_LDO25_EN_MASK)
-#define OTP_VDD12_EN_MSB                         0
-#define OTP_VDD12_EN_LSB                         0
-#define OTP_VDD12_EN_MASK                        0x00000001
-#define OTP_VDD12_EN_GET(x)                      (((x) & OTP_VDD12_EN_MASK) >> OTP_VDD12_EN_LSB)
-#define OTP_VDD12_EN_SET(x)                      (((x) << OTP_VDD12_EN_LSB) & OTP_VDD12_EN_MASK)
-
-#define OTP_STATUS_ADDRESS                       0x000002b4
-#define OTP_STATUS_OFFSET                        0x000002b4
-#define OTP_STATUS_LDO25_EN_READY_MSB            1
-#define OTP_STATUS_LDO25_EN_READY_LSB            1
-#define OTP_STATUS_LDO25_EN_READY_MASK           0x00000002
-#define OTP_STATUS_LDO25_EN_READY_GET(x)         (((x) & OTP_STATUS_LDO25_EN_READY_MASK) >> OTP_STATUS_LDO25_EN_READY_LSB)
-#define OTP_STATUS_LDO25_EN_READY_SET(x)         (((x) << OTP_STATUS_LDO25_EN_READY_LSB) & OTP_STATUS_LDO25_EN_READY_MASK)
-#define OTP_STATUS_VDD12_EN_READY_MSB            0
-#define OTP_STATUS_VDD12_EN_READY_LSB            0
-#define OTP_STATUS_VDD12_EN_READY_MASK           0x00000001
-#define OTP_STATUS_VDD12_EN_READY_GET(x)         (((x) & OTP_STATUS_VDD12_EN_READY_MASK) >> OTP_STATUS_VDD12_EN_READY_LSB)
-#define OTP_STATUS_VDD12_EN_READY_SET(x)         (((x) << OTP_STATUS_VDD12_EN_READY_LSB) & OTP_STATUS_VDD12_EN_READY_MASK)
-
-#define PMU_ADDRESS                              0x000002b8
-#define PMU_OFFSET                               0x000002b8
-#define PMU_REG_WAKEUP_TIME_SEL_MSB              1
-#define PMU_REG_WAKEUP_TIME_SEL_LSB              0
-#define PMU_REG_WAKEUP_TIME_SEL_MASK             0x00000003
-#define PMU_REG_WAKEUP_TIME_SEL_GET(x)           (((x) & PMU_REG_WAKEUP_TIME_SEL_MASK) >> PMU_REG_WAKEUP_TIME_SEL_LSB)
-#define PMU_REG_WAKEUP_TIME_SEL_SET(x)           (((x) << PMU_REG_WAKEUP_TIME_SEL_LSB) & PMU_REG_WAKEUP_TIME_SEL_MASK)
-
-#define PMU_CONFIG_ADDRESS                       0x000002c0
-#define PMU_CONFIG_OFFSET                        0x000002c0
-#define PMU_CONFIG_VALUE_MSB                     15
-#define PMU_CONFIG_VALUE_LSB                     0
-#define PMU_CONFIG_VALUE_MASK                    0x0000ffff
-#define PMU_CONFIG_VALUE_GET(x)                  (((x) & PMU_CONFIG_VALUE_MASK) >> PMU_CONFIG_VALUE_LSB)
-#define PMU_CONFIG_VALUE_SET(x)                  (((x) << PMU_CONFIG_VALUE_LSB) & PMU_CONFIG_VALUE_MASK)
-
-#define PMU_BYPASS_ADDRESS                       0x000002c8
-#define PMU_BYPASS_OFFSET                        0x000002c8
-#define PMU_BYPASS_SWREG_MSB                     2
-#define PMU_BYPASS_SWREG_LSB                     2
-#define PMU_BYPASS_SWREG_MASK                    0x00000004
-#define PMU_BYPASS_SWREG_GET(x)                  (((x) & PMU_BYPASS_SWREG_MASK) >> PMU_BYPASS_SWREG_LSB)
-#define PMU_BYPASS_SWREG_SET(x)                  (((x) << PMU_BYPASS_SWREG_LSB) & PMU_BYPASS_SWREG_MASK)
-#define PMU_BYPASS_DREG_MSB                      1
-#define PMU_BYPASS_DREG_LSB                      1
-#define PMU_BYPASS_DREG_MASK                     0x00000002
-#define PMU_BYPASS_DREG_GET(x)                   (((x) & PMU_BYPASS_DREG_MASK) >> PMU_BYPASS_DREG_LSB)
-#define PMU_BYPASS_DREG_SET(x)                   (((x) << PMU_BYPASS_DREG_LSB) & PMU_BYPASS_DREG_MASK)
-#define PMU_BYPASS_PAREG_MSB                     0
-#define PMU_BYPASS_PAREG_LSB                     0
-#define PMU_BYPASS_PAREG_MASK                    0x00000001
-#define PMU_BYPASS_PAREG_GET(x)                  (((x) & PMU_BYPASS_PAREG_MASK) >> PMU_BYPASS_PAREG_LSB)
-#define PMU_BYPASS_PAREG_SET(x)                  (((x) << PMU_BYPASS_PAREG_LSB) & PMU_BYPASS_PAREG_MASK)
-
-#define MAC_PCU_TSF2_L32_ADDRESS                 0x000002cc
-#define MAC_PCU_TSF2_L32_OFFSET                  0x000002cc
-#define MAC_PCU_TSF2_L32_VALUE_MSB               31
-#define MAC_PCU_TSF2_L32_VALUE_LSB               0
-#define MAC_PCU_TSF2_L32_VALUE_MASK              0xffffffff
-#define MAC_PCU_TSF2_L32_VALUE_GET(x)            (((x) & MAC_PCU_TSF2_L32_VALUE_MASK) >> MAC_PCU_TSF2_L32_VALUE_LSB)
-#define MAC_PCU_TSF2_L32_VALUE_SET(x)            (((x) << MAC_PCU_TSF2_L32_VALUE_LSB) & MAC_PCU_TSF2_L32_VALUE_MASK)
-
-#define MAC_PCU_TSF2_U32_ADDRESS                 0x000002d0
-#define MAC_PCU_TSF2_U32_OFFSET                  0x000002d0
-#define MAC_PCU_TSF2_U32_VALUE_MSB               31
-#define MAC_PCU_TSF2_U32_VALUE_LSB               0
-#define MAC_PCU_TSF2_U32_VALUE_MASK              0xffffffff
-#define MAC_PCU_TSF2_U32_VALUE_GET(x)            (((x) & MAC_PCU_TSF2_U32_VALUE_MASK) >> MAC_PCU_TSF2_U32_VALUE_LSB)
-#define MAC_PCU_TSF2_U32_VALUE_SET(x)            (((x) << MAC_PCU_TSF2_U32_VALUE_LSB) & MAC_PCU_TSF2_U32_VALUE_MASK)
-
-#define MAC_PCU_GENERIC_TIMERS_MODE3_ADDRESS     0x000002d4
-#define MAC_PCU_GENERIC_TIMERS_MODE3_OFFSET      0x000002d4
-#define MAC_PCU_GENERIC_TIMERS_MODE3_OVERFLOW_INDEX_MSB 27
-#define MAC_PCU_GENERIC_TIMERS_MODE3_OVERFLOW_INDEX_LSB 24
-#define MAC_PCU_GENERIC_TIMERS_MODE3_OVERFLOW_INDEX_MASK 0x0f000000
-#define MAC_PCU_GENERIC_TIMERS_MODE3_OVERFLOW_INDEX_GET(x) (((x) & MAC_PCU_GENERIC_TIMERS_MODE3_OVERFLOW_INDEX_MASK) >> MAC_PCU_GENERIC_TIMERS_MODE3_OVERFLOW_INDEX_LSB)
-#define MAC_PCU_GENERIC_TIMERS_MODE3_OVERFLOW_INDEX_SET(x) (((x) << MAC_PCU_GENERIC_TIMERS_MODE3_OVERFLOW_INDEX_LSB) & MAC_PCU_GENERIC_TIMERS_MODE3_OVERFLOW_INDEX_MASK)
-#define MAC_PCU_GENERIC_TIMERS_MODE3_THRESH_MSB  19
-#define MAC_PCU_GENERIC_TIMERS_MODE3_THRESH_LSB  0
-#define MAC_PCU_GENERIC_TIMERS_MODE3_THRESH_MASK 0x000fffff
-#define MAC_PCU_GENERIC_TIMERS_MODE3_THRESH_GET(x) (((x) & MAC_PCU_GENERIC_TIMERS_MODE3_THRESH_MASK) >> MAC_PCU_GENERIC_TIMERS_MODE3_THRESH_LSB)
-#define MAC_PCU_GENERIC_TIMERS_MODE3_THRESH_SET(x) (((x) << MAC_PCU_GENERIC_TIMERS_MODE3_THRESH_LSB) & MAC_PCU_GENERIC_TIMERS_MODE3_THRESH_MASK)
-
-#define MAC_PCU_DIRECT_CONNECT_ADDRESS           0x000002d8
-#define MAC_PCU_DIRECT_CONNECT_OFFSET            0x000002d8
-#define MAC_PCU_DIRECT_CONNECT_STA_TSF_1_2_SEL_MSB 2
-#define MAC_PCU_DIRECT_CONNECT_STA_TSF_1_2_SEL_LSB 2
-#define MAC_PCU_DIRECT_CONNECT_STA_TSF_1_2_SEL_MASK 0x00000004
-#define MAC_PCU_DIRECT_CONNECT_STA_TSF_1_2_SEL_GET(x) (((x) & MAC_PCU_DIRECT_CONNECT_STA_TSF_1_2_SEL_MASK) >> MAC_PCU_DIRECT_CONNECT_STA_TSF_1_2_SEL_LSB)
-#define MAC_PCU_DIRECT_CONNECT_STA_TSF_1_2_SEL_SET(x) (((x) << MAC_PCU_DIRECT_CONNECT_STA_TSF_1_2_SEL_LSB) & MAC_PCU_DIRECT_CONNECT_STA_TSF_1_2_SEL_MASK)
-#define MAC_PCU_DIRECT_CONNECT_AP_TSF_1_2_SEL_MSB 1
-#define MAC_PCU_DIRECT_CONNECT_AP_TSF_1_2_SEL_LSB 1
-#define MAC_PCU_DIRECT_CONNECT_AP_TSF_1_2_SEL_MASK 0x00000002
-#define MAC_PCU_DIRECT_CONNECT_AP_TSF_1_2_SEL_GET(x) (((x) & MAC_PCU_DIRECT_CONNECT_AP_TSF_1_2_SEL_MASK) >> MAC_PCU_DIRECT_CONNECT_AP_TSF_1_2_SEL_LSB)
-#define MAC_PCU_DIRECT_CONNECT_AP_TSF_1_2_SEL_SET(x) (((x) << MAC_PCU_DIRECT_CONNECT_AP_TSF_1_2_SEL_LSB) & MAC_PCU_DIRECT_CONNECT_AP_TSF_1_2_SEL_MASK)
-#define MAC_PCU_DIRECT_CONNECT_AP_STA_ENABLE_MSB 0
-#define MAC_PCU_DIRECT_CONNECT_AP_STA_ENABLE_LSB 0
-#define MAC_PCU_DIRECT_CONNECT_AP_STA_ENABLE_MASK 0x00000001
-#define MAC_PCU_DIRECT_CONNECT_AP_STA_ENABLE_GET(x) (((x) & MAC_PCU_DIRECT_CONNECT_AP_STA_ENABLE_MASK) >> MAC_PCU_DIRECT_CONNECT_AP_STA_ENABLE_LSB)
-#define MAC_PCU_DIRECT_CONNECT_AP_STA_ENABLE_SET(x) (((x) << MAC_PCU_DIRECT_CONNECT_AP_STA_ENABLE_LSB) & MAC_PCU_DIRECT_CONNECT_AP_STA_ENABLE_MASK)
-
-#define THERM_CTRL1_ADDRESS                      0x000002dc
-#define THERM_CTRL1_OFFSET                       0x000002dc
-#define THERM_CTRL1_BYPASS_MSB                   16
-#define THERM_CTRL1_BYPASS_LSB                   16
-#define THERM_CTRL1_BYPASS_MASK                  0x00010000
-#define THERM_CTRL1_BYPASS_GET(x)                (((x) & THERM_CTRL1_BYPASS_MASK) >> THERM_CTRL1_BYPASS_LSB)
-#define THERM_CTRL1_BYPASS_SET(x)                (((x) << THERM_CTRL1_BYPASS_LSB) & THERM_CTRL1_BYPASS_MASK)
-#define THERM_CTRL1_WIDTH_ARBITOR_MSB            15
-#define THERM_CTRL1_WIDTH_ARBITOR_LSB            12
-#define THERM_CTRL1_WIDTH_ARBITOR_MASK           0x0000f000
-#define THERM_CTRL1_WIDTH_ARBITOR_GET(x)         (((x) & THERM_CTRL1_WIDTH_ARBITOR_MASK) >> THERM_CTRL1_WIDTH_ARBITOR_LSB)
-#define THERM_CTRL1_WIDTH_ARBITOR_SET(x)         (((x) << THERM_CTRL1_WIDTH_ARBITOR_LSB) & THERM_CTRL1_WIDTH_ARBITOR_MASK)
-#define THERM_CTRL1_WIDTH_MSB                    11
-#define THERM_CTRL1_WIDTH_LSB                    5
-#define THERM_CTRL1_WIDTH_MASK                   0x00000fe0
-#define THERM_CTRL1_WIDTH_GET(x)                 (((x) & THERM_CTRL1_WIDTH_MASK) >> THERM_CTRL1_WIDTH_LSB)
-#define THERM_CTRL1_WIDTH_SET(x)                 (((x) << THERM_CTRL1_WIDTH_LSB) & THERM_CTRL1_WIDTH_MASK)
-#define THERM_CTRL1_TYPE_MSB                     4
-#define THERM_CTRL1_TYPE_LSB                     3
-#define THERM_CTRL1_TYPE_MASK                    0x00000018
-#define THERM_CTRL1_TYPE_GET(x)                  (((x) & THERM_CTRL1_TYPE_MASK) >> THERM_CTRL1_TYPE_LSB)
-#define THERM_CTRL1_TYPE_SET(x)                  (((x) << THERM_CTRL1_TYPE_LSB) & THERM_CTRL1_TYPE_MASK)
-#define THERM_CTRL1_MEASURE_MSB                  2
-#define THERM_CTRL1_MEASURE_LSB                  2
-#define THERM_CTRL1_MEASURE_MASK                 0x00000004
-#define THERM_CTRL1_MEASURE_GET(x)               (((x) & THERM_CTRL1_MEASURE_MASK) >> THERM_CTRL1_MEASURE_LSB)
-#define THERM_CTRL1_MEASURE_SET(x)               (((x) << THERM_CTRL1_MEASURE_LSB) & THERM_CTRL1_MEASURE_MASK)
-#define THERM_CTRL1_INT_EN_MSB                   1
-#define THERM_CTRL1_INT_EN_LSB                   1
-#define THERM_CTRL1_INT_EN_MASK                  0x00000002
-#define THERM_CTRL1_INT_EN_GET(x)                (((x) & THERM_CTRL1_INT_EN_MASK) >> THERM_CTRL1_INT_EN_LSB)
-#define THERM_CTRL1_INT_EN_SET(x)                (((x) << THERM_CTRL1_INT_EN_LSB) & THERM_CTRL1_INT_EN_MASK)
-#define THERM_CTRL1_INT_STATUS_MSB               0
-#define THERM_CTRL1_INT_STATUS_LSB               0
-#define THERM_CTRL1_INT_STATUS_MASK              0x00000001
-#define THERM_CTRL1_INT_STATUS_GET(x)            (((x) & THERM_CTRL1_INT_STATUS_MASK) >> THERM_CTRL1_INT_STATUS_LSB)
-#define THERM_CTRL1_INT_STATUS_SET(x)            (((x) << THERM_CTRL1_INT_STATUS_LSB) & THERM_CTRL1_INT_STATUS_MASK)
-
-#define THERM_CTRL2_ADDRESS                      0x000002e0
-#define THERM_CTRL2_OFFSET                       0x000002e0
-#define THERM_CTRL2_ADC_OFF_MSB                  25
-#define THERM_CTRL2_ADC_OFF_LSB                  25
-#define THERM_CTRL2_ADC_OFF_MASK                 0x02000000
-#define THERM_CTRL2_ADC_OFF_GET(x)               (((x) & THERM_CTRL2_ADC_OFF_MASK) >> THERM_CTRL2_ADC_OFF_LSB)
-#define THERM_CTRL2_ADC_OFF_SET(x)               (((x) << THERM_CTRL2_ADC_OFF_LSB) & THERM_CTRL2_ADC_OFF_MASK)
-#define THERM_CTRL2_ADC_ON_MSB                   24
-#define THERM_CTRL2_ADC_ON_LSB                   24
-#define THERM_CTRL2_ADC_ON_MASK                  0x01000000
-#define THERM_CTRL2_ADC_ON_GET(x)                (((x) & THERM_CTRL2_ADC_ON_MASK) >> THERM_CTRL2_ADC_ON_LSB)
-#define THERM_CTRL2_ADC_ON_SET(x)                (((x) << THERM_CTRL2_ADC_ON_LSB) & THERM_CTRL2_ADC_ON_MASK)
-#define THERM_CTRL2_SAMPLE_MSB                   23
-#define THERM_CTRL2_SAMPLE_LSB                   16
-#define THERM_CTRL2_SAMPLE_MASK                  0x00ff0000
-#define THERM_CTRL2_SAMPLE_GET(x)                (((x) & THERM_CTRL2_SAMPLE_MASK) >> THERM_CTRL2_SAMPLE_LSB)
-#define THERM_CTRL2_SAMPLE_SET(x)                (((x) << THERM_CTRL2_SAMPLE_LSB) & THERM_CTRL2_SAMPLE_MASK)
-#define THERM_CTRL2_HIGH_MSB                     15
-#define THERM_CTRL2_HIGH_LSB                     8
-#define THERM_CTRL2_HIGH_MASK                    0x0000ff00
-#define THERM_CTRL2_HIGH_GET(x)                  (((x) & THERM_CTRL2_HIGH_MASK) >> THERM_CTRL2_HIGH_LSB)
-#define THERM_CTRL2_HIGH_SET(x)                  (((x) << THERM_CTRL2_HIGH_LSB) & THERM_CTRL2_HIGH_MASK)
-#define THERM_CTRL2_LOW_MSB                      7
-#define THERM_CTRL2_LOW_LSB                      0
-#define THERM_CTRL2_LOW_MASK                     0x000000ff
-#define THERM_CTRL2_LOW_GET(x)                   (((x) & THERM_CTRL2_LOW_MASK) >> THERM_CTRL2_LOW_LSB)
-#define THERM_CTRL2_LOW_SET(x)                   (((x) << THERM_CTRL2_LOW_LSB) & THERM_CTRL2_LOW_MASK)
-
-#define THERM_CTRL3_ADDRESS                      0x000002e4
-#define THERM_CTRL3_OFFSET                       0x000002e4
-#define THERM_CTRL3_ADC_GAIN_MSB                 16
-#define THERM_CTRL3_ADC_GAIN_LSB                 8
-#define THERM_CTRL3_ADC_GAIN_MASK                0x0001ff00
-#define THERM_CTRL3_ADC_GAIN_GET(x)              (((x) & THERM_CTRL3_ADC_GAIN_MASK) >> THERM_CTRL3_ADC_GAIN_LSB)
-#define THERM_CTRL3_ADC_GAIN_SET(x)              (((x) << THERM_CTRL3_ADC_GAIN_LSB) & THERM_CTRL3_ADC_GAIN_MASK)
-#define THERM_CTRL3_ADC_OFFSET_MSB               7
-#define THERM_CTRL3_ADC_OFFSET_LSB               0
-#define THERM_CTRL3_ADC_OFFSET_MASK              0x000000ff
-#define THERM_CTRL3_ADC_OFFSET_GET(x)            (((x) & THERM_CTRL3_ADC_OFFSET_MASK) >> THERM_CTRL3_ADC_OFFSET_LSB)
-#define THERM_CTRL3_ADC_OFFSET_SET(x)            (((x) << THERM_CTRL3_ADC_OFFSET_LSB) & THERM_CTRL3_ADC_OFFSET_MASK)
-
-
-#ifndef __ASSEMBLER__
-
-typedef struct rtc_wlan_reg_reg_s {
-  volatile unsigned int wlan_reset_control;
-  volatile unsigned int wlan_xtal_control;
-  volatile unsigned int wlan_tcxo_detect;
-  volatile unsigned int wlan_xtal_test;
-  volatile unsigned int wlan_quadrature;
-  volatile unsigned int wlan_pll_control;
-  volatile unsigned int wlan_pll_settle;
-  volatile unsigned int wlan_xtal_settle;
-  volatile unsigned int wlan_cpu_clock;
-  volatile unsigned int wlan_clock_out;
-  volatile unsigned int wlan_clock_control;
-  volatile unsigned int wlan_bias_override;
-  volatile unsigned int wlan_wdt_control;
-  volatile unsigned int wlan_wdt_status;
-  volatile unsigned int wlan_wdt;
-  volatile unsigned int wlan_wdt_count;
-  volatile unsigned int wlan_wdt_reset;
-  volatile unsigned int wlan_int_status;
-  volatile unsigned int wlan_lf_timer0;
-  volatile unsigned int wlan_lf_timer_count0;
-  volatile unsigned int wlan_lf_timer_control0;
-  volatile unsigned int wlan_lf_timer_status0;
-  volatile unsigned int wlan_lf_timer1;
-  volatile unsigned int wlan_lf_timer_count1;
-  volatile unsigned int wlan_lf_timer_control1;
-  volatile unsigned int wlan_lf_timer_status1;
-  volatile unsigned int wlan_lf_timer2;
-  volatile unsigned int wlan_lf_timer_count2;
-  volatile unsigned int wlan_lf_timer_control2;
-  volatile unsigned int wlan_lf_timer_status2;
-  volatile unsigned int wlan_lf_timer3;
-  volatile unsigned int wlan_lf_timer_count3;
-  volatile unsigned int wlan_lf_timer_control3;
-  volatile unsigned int wlan_lf_timer_status3;
-  volatile unsigned int wlan_hf_timer;
-  volatile unsigned int wlan_hf_timer_count;
-  volatile unsigned int wlan_hf_lf_count;
-  volatile unsigned int wlan_hf_timer_control;
-  volatile unsigned int wlan_hf_timer_status;
-  volatile unsigned int wlan_rtc_control;
-  volatile unsigned int wlan_rtc_time;
-  volatile unsigned int wlan_rtc_date;
-  volatile unsigned int wlan_rtc_set_time;
-  volatile unsigned int wlan_rtc_set_date;
-  volatile unsigned int wlan_rtc_set_alarm;
-  volatile unsigned int wlan_rtc_config;
-  volatile unsigned int wlan_rtc_alarm_status;
-  volatile unsigned int wlan_uart_wakeup;
-  volatile unsigned int wlan_reset_cause;
-  volatile unsigned int wlan_system_sleep;
-  volatile unsigned int wlan_sdio_wrapper;
-  volatile unsigned int wlan_mac_sleep_control;
-  volatile unsigned int wlan_keep_awake;
-  volatile unsigned int wlan_lpo_cal_time;
-  volatile unsigned int wlan_lpo_init_dividend_int;
-  volatile unsigned int wlan_lpo_init_dividend_fraction;
-  volatile unsigned int wlan_lpo_cal;
-  volatile unsigned int wlan_lpo_cal_test_control;
-  volatile unsigned int wlan_lpo_cal_test_status;
-  volatile unsigned int wlan_chip_id;
-  volatile unsigned int wlan_derived_rtc_clk;
-  volatile unsigned int mac_pcu_slp32_mode;
-  volatile unsigned int mac_pcu_slp32_wake;
-  volatile unsigned int mac_pcu_slp32_inc;
-  volatile unsigned int mac_pcu_slp_mib1;
-  volatile unsigned int mac_pcu_slp_mib2;
-  volatile unsigned int mac_pcu_slp_mib3;
-  volatile unsigned int wlan_power_reg;
-  volatile unsigned int wlan_core_clk_ctrl;
-  volatile unsigned int wlan_gpio_wakeup_control;
-  volatile unsigned int ht;
-  volatile unsigned int mac_pcu_tsf_l32;
-  volatile unsigned int mac_pcu_tsf_u32;
-  volatile unsigned int mac_pcu_wbtimer;
-  unsigned char pad0[24]; /* pad to 0x140 */
-  volatile unsigned int mac_pcu_generic_timers[16];
-  volatile unsigned int mac_pcu_generic_timers_mode;
-  unsigned char pad1[60]; /* pad to 0x1c0 */
-  volatile unsigned int mac_pcu_generic_timers2[16];
-  volatile unsigned int mac_pcu_generic_timers_mode2;
-  volatile unsigned int mac_pcu_slp1;
-  volatile unsigned int mac_pcu_slp2;
-  volatile unsigned int mac_pcu_reset_tsf;
-  volatile unsigned int mac_pcu_tsf_add_pll;
-  volatile unsigned int sleep_retention;
-  volatile unsigned int btcoexctrl;
-  volatile unsigned int wbsync_priority1;
-  volatile unsigned int wbsync_priority2;
-  volatile unsigned int wbsync_priority3;
-  volatile unsigned int btcoex0;
-  volatile unsigned int btcoex1;
-  volatile unsigned int btcoex2;
-  volatile unsigned int btcoex3;
-  volatile unsigned int btcoex4;
-  volatile unsigned int btcoex5;
-  volatile unsigned int btcoex6;
-  volatile unsigned int lock;
-  volatile unsigned int nolock_priority;
-  volatile unsigned int wbsync;
-  volatile unsigned int wbsync1;
-  volatile unsigned int wbsync2;
-  volatile unsigned int wbsync3;
-  volatile unsigned int wb_timer_target;
-  volatile unsigned int wb_timer_slop;
-  volatile unsigned int btcoex_int_en;
-  volatile unsigned int btcoex_int_stat;
-  volatile unsigned int btpriority_int_en;
-  volatile unsigned int btpriority_int_stat;
-  volatile unsigned int btpriority_stomp_int_en;
-  volatile unsigned int btpriority_stomp_int_stat;
-  volatile unsigned int mac_pcu_bmiss_timeout;
-  volatile unsigned int mac_pcu_cab_awake;
-  volatile unsigned int lp_perf_counter;
-  volatile unsigned int lp_perf_light_sleep;
-  volatile unsigned int lp_perf_deep_sleep;
-  volatile unsigned int lp_perf_on;
-  volatile unsigned int st_64_bit;
-  volatile unsigned int message_wr;
-  volatile unsigned int message_wr_p;
-  volatile unsigned int message_rd;
-  volatile unsigned int message_rd_p;
-  volatile unsigned int chip_mode;
-  volatile unsigned int clk_req_fall_edge;
-  volatile unsigned int otp;
-  volatile unsigned int otp_status;
-  volatile unsigned int pmu;
-  unsigned char pad2[4]; /* pad to 0x2c0 */
-  volatile unsigned int pmu_config[2];
-  volatile unsigned int pmu_bypass;
-  volatile unsigned int mac_pcu_tsf2_l32;
-  volatile unsigned int mac_pcu_tsf2_u32;
-  volatile unsigned int mac_pcu_generic_timers_mode3;
-  volatile unsigned int mac_pcu_direct_connect;
-  volatile unsigned int therm_ctrl1;
-  volatile unsigned int therm_ctrl2;
-  volatile unsigned int therm_ctrl3;
-} rtc_wlan_reg_reg_t;
-
-#endif /* __ASSEMBLER__ */
-
 #endif /* _RTC_WLAN_REG_H_ */
diff -druN linux-2.6.39-libre/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/si_reg.h linux-3.0-rc7-libre/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/si_reg.h
--- linux-2.6.39-libre/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/si_reg.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/si_reg.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,209 +0,0 @@
-// ------------------------------------------------------------------
-// Copyright (c) 2004-2010 Atheros Corporation.  All rights reserved.
-// 
-//
-// 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.
-//
-//
-// ------------------------------------------------------------------
-//===================================================================
-// Author(s): ="Atheros"
-//===================================================================
-
-
-#ifndef _SI_REG_REG_H_
-#define _SI_REG_REG_H_
-
-#define SI_CONFIG_ADDRESS                        0x00000000
-#define SI_CONFIG_OFFSET                         0x00000000
-#define SI_CONFIG_ERR_INT_MSB                    19
-#define SI_CONFIG_ERR_INT_LSB                    19
-#define SI_CONFIG_ERR_INT_MASK                   0x00080000
-#define SI_CONFIG_ERR_INT_GET(x)                 (((x) & SI_CONFIG_ERR_INT_MASK) >> SI_CONFIG_ERR_INT_LSB)
-#define SI_CONFIG_ERR_INT_SET(x)                 (((x) << SI_CONFIG_ERR_INT_LSB) & SI_CONFIG_ERR_INT_MASK)
-#define SI_CONFIG_BIDIR_OD_DATA_MSB              18
-#define SI_CONFIG_BIDIR_OD_DATA_LSB              18
-#define SI_CONFIG_BIDIR_OD_DATA_MASK             0x00040000
-#define SI_CONFIG_BIDIR_OD_DATA_GET(x)           (((x) & SI_CONFIG_BIDIR_OD_DATA_MASK) >> SI_CONFIG_BIDIR_OD_DATA_LSB)
-#define SI_CONFIG_BIDIR_OD_DATA_SET(x)           (((x) << SI_CONFIG_BIDIR_OD_DATA_LSB) & SI_CONFIG_BIDIR_OD_DATA_MASK)
-#define SI_CONFIG_I2C_MSB                        16
-#define SI_CONFIG_I2C_LSB                        16
-#define SI_CONFIG_I2C_MASK                       0x00010000
-#define SI_CONFIG_I2C_GET(x)                     (((x) & SI_CONFIG_I2C_MASK) >> SI_CONFIG_I2C_LSB)
-#define SI_CONFIG_I2C_SET(x)                     (((x) << SI_CONFIG_I2C_LSB) & SI_CONFIG_I2C_MASK)
-#define SI_CONFIG_POS_SAMPLE_MSB                 7
-#define SI_CONFIG_POS_SAMPLE_LSB                 7
-#define SI_CONFIG_POS_SAMPLE_MASK                0x00000080
-#define SI_CONFIG_POS_SAMPLE_GET(x)              (((x) & SI_CONFIG_POS_SAMPLE_MASK) >> SI_CONFIG_POS_SAMPLE_LSB)
-#define SI_CONFIG_POS_SAMPLE_SET(x)              (((x) << SI_CONFIG_POS_SAMPLE_LSB) & SI_CONFIG_POS_SAMPLE_MASK)
-#define SI_CONFIG_POS_DRIVE_MSB                  6
-#define SI_CONFIG_POS_DRIVE_LSB                  6
-#define SI_CONFIG_POS_DRIVE_MASK                 0x00000040
-#define SI_CONFIG_POS_DRIVE_GET(x)               (((x) & SI_CONFIG_POS_DRIVE_MASK) >> SI_CONFIG_POS_DRIVE_LSB)
-#define SI_CONFIG_POS_DRIVE_SET(x)               (((x) << SI_CONFIG_POS_DRIVE_LSB) & SI_CONFIG_POS_DRIVE_MASK)
-#define SI_CONFIG_INACTIVE_DATA_MSB              5
-#define SI_CONFIG_INACTIVE_DATA_LSB              5
-#define SI_CONFIG_INACTIVE_DATA_MASK             0x00000020
-#define SI_CONFIG_INACTIVE_DATA_GET(x)           (((x) & SI_CONFIG_INACTIVE_DATA_MASK) >> SI_CONFIG_INACTIVE_DATA_LSB)
-#define SI_CONFIG_INACTIVE_DATA_SET(x)           (((x) << SI_CONFIG_INACTIVE_DATA_LSB) & SI_CONFIG_INACTIVE_DATA_MASK)
-#define SI_CONFIG_INACTIVE_CLK_MSB               4
-#define SI_CONFIG_INACTIVE_CLK_LSB               4
-#define SI_CONFIG_INACTIVE_CLK_MASK              0x00000010
-#define SI_CONFIG_INACTIVE_CLK_GET(x)            (((x) & SI_CONFIG_INACTIVE_CLK_MASK) >> SI_CONFIG_INACTIVE_CLK_LSB)
-#define SI_CONFIG_INACTIVE_CLK_SET(x)            (((x) << SI_CONFIG_INACTIVE_CLK_LSB) & SI_CONFIG_INACTIVE_CLK_MASK)
-#define SI_CONFIG_DIVIDER_MSB                    3
-#define SI_CONFIG_DIVIDER_LSB                    0
-#define SI_CONFIG_DIVIDER_MASK                   0x0000000f
-#define SI_CONFIG_DIVIDER_GET(x)                 (((x) & SI_CONFIG_DIVIDER_MASK) >> SI_CONFIG_DIVIDER_LSB)
-#define SI_CONFIG_DIVIDER_SET(x)                 (((x) << SI_CONFIG_DIVIDER_LSB) & SI_CONFIG_DIVIDER_MASK)
-
-#define SI_CS_ADDRESS                            0x00000004
-#define SI_CS_OFFSET                             0x00000004
-#define SI_CS_BIT_CNT_IN_LAST_BYTE_MSB           13
-#define SI_CS_BIT_CNT_IN_LAST_BYTE_LSB           11
-#define SI_CS_BIT_CNT_IN_LAST_BYTE_MASK          0x00003800
-#define SI_CS_BIT_CNT_IN_LAST_BYTE_GET(x)        (((x) & SI_CS_BIT_CNT_IN_LAST_BYTE_MASK) >> SI_CS_BIT_CNT_IN_LAST_BYTE_LSB)
-#define SI_CS_BIT_CNT_IN_LAST_BYTE_SET(x)        (((x) << SI_CS_BIT_CNT_IN_LAST_BYTE_LSB) & SI_CS_BIT_CNT_IN_LAST_BYTE_MASK)
-#define SI_CS_DONE_ERR_MSB                       10
-#define SI_CS_DONE_ERR_LSB                       10
-#define SI_CS_DONE_ERR_MASK                      0x00000400
-#define SI_CS_DONE_ERR_GET(x)                    (((x) & SI_CS_DONE_ERR_MASK) >> SI_CS_DONE_ERR_LSB)
-#define SI_CS_DONE_ERR_SET(x)                    (((x) << SI_CS_DONE_ERR_LSB) & SI_CS_DONE_ERR_MASK)
-#define SI_CS_DONE_INT_MSB                       9
-#define SI_CS_DONE_INT_LSB                       9
-#define SI_CS_DONE_INT_MASK                      0x00000200
-#define SI_CS_DONE_INT_GET(x)                    (((x) & SI_CS_DONE_INT_MASK) >> SI_CS_DONE_INT_LSB)
-#define SI_CS_DONE_INT_SET(x)                    (((x) << SI_CS_DONE_INT_LSB) & SI_CS_DONE_INT_MASK)
-#define SI_CS_START_MSB                          8
-#define SI_CS_START_LSB                          8
-#define SI_CS_START_MASK                         0x00000100
-#define SI_CS_START_GET(x)                       (((x) & SI_CS_START_MASK) >> SI_CS_START_LSB)
-#define SI_CS_START_SET(x)                       (((x) << SI_CS_START_LSB) & SI_CS_START_MASK)
-#define SI_CS_RX_CNT_MSB                         7
-#define SI_CS_RX_CNT_LSB                         4
-#define SI_CS_RX_CNT_MASK                        0x000000f0
-#define SI_CS_RX_CNT_GET(x)                      (((x) & SI_CS_RX_CNT_MASK) >> SI_CS_RX_CNT_LSB)
-#define SI_CS_RX_CNT_SET(x)                      (((x) << SI_CS_RX_CNT_LSB) & SI_CS_RX_CNT_MASK)
-#define SI_CS_TX_CNT_MSB                         3
-#define SI_CS_TX_CNT_LSB                         0
-#define SI_CS_TX_CNT_MASK                        0x0000000f
-#define SI_CS_TX_CNT_GET(x)                      (((x) & SI_CS_TX_CNT_MASK) >> SI_CS_TX_CNT_LSB)
-#define SI_CS_TX_CNT_SET(x)                      (((x) << SI_CS_TX_CNT_LSB) & SI_CS_TX_CNT_MASK)
-
-#define SI_TX_DATA0_ADDRESS                      0x00000008
-#define SI_TX_DATA0_OFFSET                       0x00000008
-#define SI_TX_DATA0_DATA3_MSB                    31
-#define SI_TX_DATA0_DATA3_LSB                    24
-#define SI_TX_DATA0_DATA3_MASK                   0xff000000
-#define SI_TX_DATA0_DATA3_GET(x)                 (((x) & SI_TX_DATA0_DATA3_MASK) >> SI_TX_DATA0_DATA3_LSB)
-#define SI_TX_DATA0_DATA3_SET(x)                 (((x) << SI_TX_DATA0_DATA3_LSB) & SI_TX_DATA0_DATA3_MASK)
-#define SI_TX_DATA0_DATA2_MSB                    23
-#define SI_TX_DATA0_DATA2_LSB                    16
-#define SI_TX_DATA0_DATA2_MASK                   0x00ff0000
-#define SI_TX_DATA0_DATA2_GET(x)                 (((x) & SI_TX_DATA0_DATA2_MASK) >> SI_TX_DATA0_DATA2_LSB)
-#define SI_TX_DATA0_DATA2_SET(x)                 (((x) << SI_TX_DATA0_DATA2_LSB) & SI_TX_DATA0_DATA2_MASK)
-#define SI_TX_DATA0_DATA1_MSB                    15
-#define SI_TX_DATA0_DATA1_LSB                    8
-#define SI_TX_DATA0_DATA1_MASK                   0x0000ff00
-#define SI_TX_DATA0_DATA1_GET(x)                 (((x) & SI_TX_DATA0_DATA1_MASK) >> SI_TX_DATA0_DATA1_LSB)
-#define SI_TX_DATA0_DATA1_SET(x)                 (((x) << SI_TX_DATA0_DATA1_LSB) & SI_TX_DATA0_DATA1_MASK)
-#define SI_TX_DATA0_DATA0_MSB                    7
-#define SI_TX_DATA0_DATA0_LSB                    0
-#define SI_TX_DATA0_DATA0_MASK                   0x000000ff
-#define SI_TX_DATA0_DATA0_GET(x)                 (((x) & SI_TX_DATA0_DATA0_MASK) >> SI_TX_DATA0_DATA0_LSB)
-#define SI_TX_DATA0_DATA0_SET(x)                 (((x) << SI_TX_DATA0_DATA0_LSB) & SI_TX_DATA0_DATA0_MASK)
-
-#define SI_TX_DATA1_ADDRESS                      0x0000000c
-#define SI_TX_DATA1_OFFSET                       0x0000000c
-#define SI_TX_DATA1_DATA7_MSB                    31
-#define SI_TX_DATA1_DATA7_LSB                    24
-#define SI_TX_DATA1_DATA7_MASK                   0xff000000
-#define SI_TX_DATA1_DATA7_GET(x)                 (((x) & SI_TX_DATA1_DATA7_MASK) >> SI_TX_DATA1_DATA7_LSB)
-#define SI_TX_DATA1_DATA7_SET(x)                 (((x) << SI_TX_DATA1_DATA7_LSB) & SI_TX_DATA1_DATA7_MASK)
-#define SI_TX_DATA1_DATA6_MSB                    23
-#define SI_TX_DATA1_DATA6_LSB                    16
-#define SI_TX_DATA1_DATA6_MASK                   0x00ff0000
-#define SI_TX_DATA1_DATA6_GET(x)                 (((x) & SI_TX_DATA1_DATA6_MASK) >> SI_TX_DATA1_DATA6_LSB)
-#define SI_TX_DATA1_DATA6_SET(x)                 (((x) << SI_TX_DATA1_DATA6_LSB) & SI_TX_DATA1_DATA6_MASK)
-#define SI_TX_DATA1_DATA5_MSB                    15
-#define SI_TX_DATA1_DATA5_LSB                    8
-#define SI_TX_DATA1_DATA5_MASK                   0x0000ff00
-#define SI_TX_DATA1_DATA5_GET(x)                 (((x) & SI_TX_DATA1_DATA5_MASK) >> SI_TX_DATA1_DATA5_LSB)
-#define SI_TX_DATA1_DATA5_SET(x)                 (((x) << SI_TX_DATA1_DATA5_LSB) & SI_TX_DATA1_DATA5_MASK)
-#define SI_TX_DATA1_DATA4_MSB                    7
-#define SI_TX_DATA1_DATA4_LSB                    0
-#define SI_TX_DATA1_DATA4_MASK                   0x000000ff
-#define SI_TX_DATA1_DATA4_GET(x)                 (((x) & SI_TX_DATA1_DATA4_MASK) >> SI_TX_DATA1_DATA4_LSB)
-#define SI_TX_DATA1_DATA4_SET(x)                 (((x) << SI_TX_DATA1_DATA4_LSB) & SI_TX_DATA1_DATA4_MASK)
-
-#define SI_RX_DATA0_ADDRESS                      0x00000010
-#define SI_RX_DATA0_OFFSET                       0x00000010
-#define SI_RX_DATA0_DATA3_MSB                    31
-#define SI_RX_DATA0_DATA3_LSB                    24
-#define SI_RX_DATA0_DATA3_MASK                   0xff000000
-#define SI_RX_DATA0_DATA3_GET(x)                 (((x) & SI_RX_DATA0_DATA3_MASK) >> SI_RX_DATA0_DATA3_LSB)
-#define SI_RX_DATA0_DATA3_SET(x)                 (((x) << SI_RX_DATA0_DATA3_LSB) & SI_RX_DATA0_DATA3_MASK)
-#define SI_RX_DATA0_DATA2_MSB                    23
-#define SI_RX_DATA0_DATA2_LSB                    16
-#define SI_RX_DATA0_DATA2_MASK                   0x00ff0000
-#define SI_RX_DATA0_DATA2_GET(x)                 (((x) & SI_RX_DATA0_DATA2_MASK) >> SI_RX_DATA0_DATA2_LSB)
-#define SI_RX_DATA0_DATA2_SET(x)                 (((x) << SI_RX_DATA0_DATA2_LSB) & SI_RX_DATA0_DATA2_MASK)
-#define SI_RX_DATA0_DATA1_MSB                    15
-#define SI_RX_DATA0_DATA1_LSB                    8
-#define SI_RX_DATA0_DATA1_MASK                   0x0000ff00
-#define SI_RX_DATA0_DATA1_GET(x)                 (((x) & SI_RX_DATA0_DATA1_MASK) >> SI_RX_DATA0_DATA1_LSB)
-#define SI_RX_DATA0_DATA1_SET(x)                 (((x) << SI_RX_DATA0_DATA1_LSB) & SI_RX_DATA0_DATA1_MASK)
-#define SI_RX_DATA0_DATA0_MSB                    7
-#define SI_RX_DATA0_DATA0_LSB                    0
-#define SI_RX_DATA0_DATA0_MASK                   0x000000ff
-#define SI_RX_DATA0_DATA0_GET(x)                 (((x) & SI_RX_DATA0_DATA0_MASK) >> SI_RX_DATA0_DATA0_LSB)
-#define SI_RX_DATA0_DATA0_SET(x)                 (((x) << SI_RX_DATA0_DATA0_LSB) & SI_RX_DATA0_DATA0_MASK)
-
-#define SI_RX_DATA1_ADDRESS                      0x00000014
-#define SI_RX_DATA1_OFFSET                       0x00000014
-#define SI_RX_DATA1_DATA7_MSB                    31
-#define SI_RX_DATA1_DATA7_LSB                    24
-#define SI_RX_DATA1_DATA7_MASK                   0xff000000
-#define SI_RX_DATA1_DATA7_GET(x)                 (((x) & SI_RX_DATA1_DATA7_MASK) >> SI_RX_DATA1_DATA7_LSB)
-#define SI_RX_DATA1_DATA7_SET(x)                 (((x) << SI_RX_DATA1_DATA7_LSB) & SI_RX_DATA1_DATA7_MASK)
-#define SI_RX_DATA1_DATA6_MSB                    23
-#define SI_RX_DATA1_DATA6_LSB                    16
-#define SI_RX_DATA1_DATA6_MASK                   0x00ff0000
-#define SI_RX_DATA1_DATA6_GET(x)                 (((x) & SI_RX_DATA1_DATA6_MASK) >> SI_RX_DATA1_DATA6_LSB)
-#define SI_RX_DATA1_DATA6_SET(x)                 (((x) << SI_RX_DATA1_DATA6_LSB) & SI_RX_DATA1_DATA6_MASK)
-#define SI_RX_DATA1_DATA5_MSB                    15
-#define SI_RX_DATA1_DATA5_LSB                    8
-#define SI_RX_DATA1_DATA5_MASK                   0x0000ff00
-#define SI_RX_DATA1_DATA5_GET(x)                 (((x) & SI_RX_DATA1_DATA5_MASK) >> SI_RX_DATA1_DATA5_LSB)
-#define SI_RX_DATA1_DATA5_SET(x)                 (((x) << SI_RX_DATA1_DATA5_LSB) & SI_RX_DATA1_DATA5_MASK)
-#define SI_RX_DATA1_DATA4_MSB                    7
-#define SI_RX_DATA1_DATA4_LSB                    0
-#define SI_RX_DATA1_DATA4_MASK                   0x000000ff
-#define SI_RX_DATA1_DATA4_GET(x)                 (((x) & SI_RX_DATA1_DATA4_MASK) >> SI_RX_DATA1_DATA4_LSB)
-#define SI_RX_DATA1_DATA4_SET(x)                 (((x) << SI_RX_DATA1_DATA4_LSB) & SI_RX_DATA1_DATA4_MASK)
-
-
-#ifndef __ASSEMBLER__
-
-typedef struct si_reg_reg_s {
-  volatile unsigned int si_config;
-  volatile unsigned int si_cs;
-  volatile unsigned int si_tx_data0;
-  volatile unsigned int si_tx_data1;
-  volatile unsigned int si_rx_data0;
-  volatile unsigned int si_rx_data1;
-} si_reg_reg_t;
-
-#endif /* __ASSEMBLER__ */
-
-#endif /* _SI_REG_H_ */
diff -druN linux-2.6.39-libre/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/uart_reg.h linux-3.0-rc7-libre/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/uart_reg.h
--- linux-2.6.39-libre/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/uart_reg.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/uart_reg.h	2011-07-11 19:51:52.000000000 -0400
@@ -24,107 +24,6 @@
 #ifndef _UART_REG_REG_H_
 #define _UART_REG_REG_H_
 
-#define UART_DATA_ADDRESS                        0x00000000
-#define UART_DATA_OFFSET                         0x00000000
-#define UART_DATA_TX_CSR_MSB                     9
-#define UART_DATA_TX_CSR_LSB                     9
-#define UART_DATA_TX_CSR_MASK                    0x00000200
-#define UART_DATA_TX_CSR_GET(x)                  (((x) & UART_DATA_TX_CSR_MASK) >> UART_DATA_TX_CSR_LSB)
-#define UART_DATA_TX_CSR_SET(x)                  (((x) << UART_DATA_TX_CSR_LSB) & UART_DATA_TX_CSR_MASK)
-#define UART_DATA_RX_CSR_MSB                     8
-#define UART_DATA_RX_CSR_LSB                     8
-#define UART_DATA_RX_CSR_MASK                    0x00000100
-#define UART_DATA_RX_CSR_GET(x)                  (((x) & UART_DATA_RX_CSR_MASK) >> UART_DATA_RX_CSR_LSB)
-#define UART_DATA_RX_CSR_SET(x)                  (((x) << UART_DATA_RX_CSR_LSB) & UART_DATA_RX_CSR_MASK)
-#define UART_DATA_TXRX_DATA_MSB                  7
-#define UART_DATA_TXRX_DATA_LSB                  0
-#define UART_DATA_TXRX_DATA_MASK                 0x000000ff
-#define UART_DATA_TXRX_DATA_GET(x)               (((x) & UART_DATA_TXRX_DATA_MASK) >> UART_DATA_TXRX_DATA_LSB)
-#define UART_DATA_TXRX_DATA_SET(x)               (((x) << UART_DATA_TXRX_DATA_LSB) & UART_DATA_TXRX_DATA_MASK)
-
-#define UART_CONTROL_ADDRESS                     0x00000004
-#define UART_CONTROL_OFFSET                      0x00000004
-#define UART_CONTROL_RX_BUSY_MSB                 15
-#define UART_CONTROL_RX_BUSY_LSB                 15
-#define UART_CONTROL_RX_BUSY_MASK                0x00008000
-#define UART_CONTROL_RX_BUSY_GET(x)              (((x) & UART_CONTROL_RX_BUSY_MASK) >> UART_CONTROL_RX_BUSY_LSB)
-#define UART_CONTROL_RX_BUSY_SET(x)              (((x) << UART_CONTROL_RX_BUSY_LSB) & UART_CONTROL_RX_BUSY_MASK)
-#define UART_CONTROL_TX_BUSY_MSB                 14
-#define UART_CONTROL_TX_BUSY_LSB                 14
-#define UART_CONTROL_TX_BUSY_MASK                0x00004000
-#define UART_CONTROL_TX_BUSY_GET(x)              (((x) & UART_CONTROL_TX_BUSY_MASK) >> UART_CONTROL_TX_BUSY_LSB)
-#define UART_CONTROL_TX_BUSY_SET(x)              (((x) << UART_CONTROL_TX_BUSY_LSB) & UART_CONTROL_TX_BUSY_MASK)
-#define UART_CONTROL_HOST_INT_ENABLE_MSB         13
-#define UART_CONTROL_HOST_INT_ENABLE_LSB         13
-#define UART_CONTROL_HOST_INT_ENABLE_MASK        0x00002000
-#define UART_CONTROL_HOST_INT_ENABLE_GET(x)      (((x) & UART_CONTROL_HOST_INT_ENABLE_MASK) >> UART_CONTROL_HOST_INT_ENABLE_LSB)
-#define UART_CONTROL_HOST_INT_ENABLE_SET(x)      (((x) << UART_CONTROL_HOST_INT_ENABLE_LSB) & UART_CONTROL_HOST_INT_ENABLE_MASK)
-#define UART_CONTROL_HOST_INT_MSB                12
-#define UART_CONTROL_HOST_INT_LSB                12
-#define UART_CONTROL_HOST_INT_MASK               0x00001000
-#define UART_CONTROL_HOST_INT_GET(x)             (((x) & UART_CONTROL_HOST_INT_MASK) >> UART_CONTROL_HOST_INT_LSB)
-#define UART_CONTROL_HOST_INT_SET(x)             (((x) << UART_CONTROL_HOST_INT_LSB) & UART_CONTROL_HOST_INT_MASK)
-#define UART_CONTROL_TX_BREAK_MSB                11
-#define UART_CONTROL_TX_BREAK_LSB                11
-#define UART_CONTROL_TX_BREAK_MASK               0x00000800
-#define UART_CONTROL_TX_BREAK_GET(x)             (((x) & UART_CONTROL_TX_BREAK_MASK) >> UART_CONTROL_TX_BREAK_LSB)
-#define UART_CONTROL_TX_BREAK_SET(x)             (((x) << UART_CONTROL_TX_BREAK_LSB) & UART_CONTROL_TX_BREAK_MASK)
-#define UART_CONTROL_RX_BREAK_MSB                10
-#define UART_CONTROL_RX_BREAK_LSB                10
-#define UART_CONTROL_RX_BREAK_MASK               0x00000400
-#define UART_CONTROL_RX_BREAK_GET(x)             (((x) & UART_CONTROL_RX_BREAK_MASK) >> UART_CONTROL_RX_BREAK_LSB)
-#define UART_CONTROL_RX_BREAK_SET(x)             (((x) << UART_CONTROL_RX_BREAK_LSB) & UART_CONTROL_RX_BREAK_MASK)
-#define UART_CONTROL_SERIAL_TX_READY_MSB         9
-#define UART_CONTROL_SERIAL_TX_READY_LSB         9
-#define UART_CONTROL_SERIAL_TX_READY_MASK        0x00000200
-#define UART_CONTROL_SERIAL_TX_READY_GET(x)      (((x) & UART_CONTROL_SERIAL_TX_READY_MASK) >> UART_CONTROL_SERIAL_TX_READY_LSB)
-#define UART_CONTROL_SERIAL_TX_READY_SET(x)      (((x) << UART_CONTROL_SERIAL_TX_READY_LSB) & UART_CONTROL_SERIAL_TX_READY_MASK)
-#define UART_CONTROL_TX_READY_ORIDE_MSB          8
-#define UART_CONTROL_TX_READY_ORIDE_LSB          8
-#define UART_CONTROL_TX_READY_ORIDE_MASK         0x00000100
-#define UART_CONTROL_TX_READY_ORIDE_GET(x)       (((x) & UART_CONTROL_TX_READY_ORIDE_MASK) >> UART_CONTROL_TX_READY_ORIDE_LSB)
-#define UART_CONTROL_TX_READY_ORIDE_SET(x)       (((x) << UART_CONTROL_TX_READY_ORIDE_LSB) & UART_CONTROL_TX_READY_ORIDE_MASK)
-#define UART_CONTROL_RX_READY_ORIDE_MSB          7
-#define UART_CONTROL_RX_READY_ORIDE_LSB          7
-#define UART_CONTROL_RX_READY_ORIDE_MASK         0x00000080
-#define UART_CONTROL_RX_READY_ORIDE_GET(x)       (((x) & UART_CONTROL_RX_READY_ORIDE_MASK) >> UART_CONTROL_RX_READY_ORIDE_LSB)
-#define UART_CONTROL_RX_READY_ORIDE_SET(x)       (((x) << UART_CONTROL_RX_READY_ORIDE_LSB) & UART_CONTROL_RX_READY_ORIDE_MASK)
-#define UART_CONTROL_DMA_ENABLE_MSB              6
-#define UART_CONTROL_DMA_ENABLE_LSB              6
-#define UART_CONTROL_DMA_ENABLE_MASK             0x00000040
-#define UART_CONTROL_DMA_ENABLE_GET(x)           (((x) & UART_CONTROL_DMA_ENABLE_MASK) >> UART_CONTROL_DMA_ENABLE_LSB)
-#define UART_CONTROL_DMA_ENABLE_SET(x)           (((x) << UART_CONTROL_DMA_ENABLE_LSB) & UART_CONTROL_DMA_ENABLE_MASK)
-#define UART_CONTROL_FLOW_ENABLE_MSB             5
-#define UART_CONTROL_FLOW_ENABLE_LSB             5
-#define UART_CONTROL_FLOW_ENABLE_MASK            0x00000020
-#define UART_CONTROL_FLOW_ENABLE_GET(x)          (((x) & UART_CONTROL_FLOW_ENABLE_MASK) >> UART_CONTROL_FLOW_ENABLE_LSB)
-#define UART_CONTROL_FLOW_ENABLE_SET(x)          (((x) << UART_CONTROL_FLOW_ENABLE_LSB) & UART_CONTROL_FLOW_ENABLE_MASK)
-#define UART_CONTROL_FLOW_INVERT_MSB             4
-#define UART_CONTROL_FLOW_INVERT_LSB             4
-#define UART_CONTROL_FLOW_INVERT_MASK            0x00000010
-#define UART_CONTROL_FLOW_INVERT_GET(x)          (((x) & UART_CONTROL_FLOW_INVERT_MASK) >> UART_CONTROL_FLOW_INVERT_LSB)
-#define UART_CONTROL_FLOW_INVERT_SET(x)          (((x) << UART_CONTROL_FLOW_INVERT_LSB) & UART_CONTROL_FLOW_INVERT_MASK)
-#define UART_CONTROL_IFC_ENABLE_MSB              3
-#define UART_CONTROL_IFC_ENABLE_LSB              3
-#define UART_CONTROL_IFC_ENABLE_MASK             0x00000008
-#define UART_CONTROL_IFC_ENABLE_GET(x)           (((x) & UART_CONTROL_IFC_ENABLE_MASK) >> UART_CONTROL_IFC_ENABLE_LSB)
-#define UART_CONTROL_IFC_ENABLE_SET(x)           (((x) << UART_CONTROL_IFC_ENABLE_LSB) & UART_CONTROL_IFC_ENABLE_MASK)
-#define UART_CONTROL_IFC_DCE_MSB                 2
-#define UART_CONTROL_IFC_DCE_LSB                 2
-#define UART_CONTROL_IFC_DCE_MASK                0x00000004
-#define UART_CONTROL_IFC_DCE_GET(x)              (((x) & UART_CONTROL_IFC_DCE_MASK) >> UART_CONTROL_IFC_DCE_LSB)
-#define UART_CONTROL_IFC_DCE_SET(x)              (((x) << UART_CONTROL_IFC_DCE_LSB) & UART_CONTROL_IFC_DCE_MASK)
-#define UART_CONTROL_PARITY_ENABLE_MSB           1
-#define UART_CONTROL_PARITY_ENABLE_LSB           1
-#define UART_CONTROL_PARITY_ENABLE_MASK          0x00000002
-#define UART_CONTROL_PARITY_ENABLE_GET(x)        (((x) & UART_CONTROL_PARITY_ENABLE_MASK) >> UART_CONTROL_PARITY_ENABLE_LSB)
-#define UART_CONTROL_PARITY_ENABLE_SET(x)        (((x) << UART_CONTROL_PARITY_ENABLE_LSB) & UART_CONTROL_PARITY_ENABLE_MASK)
-#define UART_CONTROL_PARITY_EVEN_MSB             0
-#define UART_CONTROL_PARITY_EVEN_LSB             0
-#define UART_CONTROL_PARITY_EVEN_MASK            0x00000001
-#define UART_CONTROL_PARITY_EVEN_GET(x)          (((x) & UART_CONTROL_PARITY_EVEN_MASK) >> UART_CONTROL_PARITY_EVEN_LSB)
-#define UART_CONTROL_PARITY_EVEN_SET(x)          (((x) << UART_CONTROL_PARITY_EVEN_LSB) & UART_CONTROL_PARITY_EVEN_MASK)
-
 #define UART_CLKDIV_ADDRESS                      0x00000008
 #define UART_CLKDIV_OFFSET                       0x00000008
 #define UART_CLKDIV_CLK_SCALE_MSB                23
@@ -138,123 +37,4 @@
 #define UART_CLKDIV_CLK_STEP_GET(x)              (((x) & UART_CLKDIV_CLK_STEP_MASK) >> UART_CLKDIV_CLK_STEP_LSB)
 #define UART_CLKDIV_CLK_STEP_SET(x)              (((x) << UART_CLKDIV_CLK_STEP_LSB) & UART_CLKDIV_CLK_STEP_MASK)
 
-#define UART_INT_ADDRESS                         0x0000000c
-#define UART_INT_OFFSET                          0x0000000c
-#define UART_INT_TX_EMPTY_INT_MSB                9
-#define UART_INT_TX_EMPTY_INT_LSB                9
-#define UART_INT_TX_EMPTY_INT_MASK               0x00000200
-#define UART_INT_TX_EMPTY_INT_GET(x)             (((x) & UART_INT_TX_EMPTY_INT_MASK) >> UART_INT_TX_EMPTY_INT_LSB)
-#define UART_INT_TX_EMPTY_INT_SET(x)             (((x) << UART_INT_TX_EMPTY_INT_LSB) & UART_INT_TX_EMPTY_INT_MASK)
-#define UART_INT_RX_FULL_INT_MSB                 8
-#define UART_INT_RX_FULL_INT_LSB                 8
-#define UART_INT_RX_FULL_INT_MASK                0x00000100
-#define UART_INT_RX_FULL_INT_GET(x)              (((x) & UART_INT_RX_FULL_INT_MASK) >> UART_INT_RX_FULL_INT_LSB)
-#define UART_INT_RX_FULL_INT_SET(x)              (((x) << UART_INT_RX_FULL_INT_LSB) & UART_INT_RX_FULL_INT_MASK)
-#define UART_INT_RX_BREAK_OFF_INT_MSB            7
-#define UART_INT_RX_BREAK_OFF_INT_LSB            7
-#define UART_INT_RX_BREAK_OFF_INT_MASK           0x00000080
-#define UART_INT_RX_BREAK_OFF_INT_GET(x)         (((x) & UART_INT_RX_BREAK_OFF_INT_MASK) >> UART_INT_RX_BREAK_OFF_INT_LSB)
-#define UART_INT_RX_BREAK_OFF_INT_SET(x)         (((x) << UART_INT_RX_BREAK_OFF_INT_LSB) & UART_INT_RX_BREAK_OFF_INT_MASK)
-#define UART_INT_RX_BREAK_ON_INT_MSB             6
-#define UART_INT_RX_BREAK_ON_INT_LSB             6
-#define UART_INT_RX_BREAK_ON_INT_MASK            0x00000040
-#define UART_INT_RX_BREAK_ON_INT_GET(x)          (((x) & UART_INT_RX_BREAK_ON_INT_MASK) >> UART_INT_RX_BREAK_ON_INT_LSB)
-#define UART_INT_RX_BREAK_ON_INT_SET(x)          (((x) << UART_INT_RX_BREAK_ON_INT_LSB) & UART_INT_RX_BREAK_ON_INT_MASK)
-#define UART_INT_RX_PARITY_ERR_INT_MSB           5
-#define UART_INT_RX_PARITY_ERR_INT_LSB           5
-#define UART_INT_RX_PARITY_ERR_INT_MASK          0x00000020
-#define UART_INT_RX_PARITY_ERR_INT_GET(x)        (((x) & UART_INT_RX_PARITY_ERR_INT_MASK) >> UART_INT_RX_PARITY_ERR_INT_LSB)
-#define UART_INT_RX_PARITY_ERR_INT_SET(x)        (((x) << UART_INT_RX_PARITY_ERR_INT_LSB) & UART_INT_RX_PARITY_ERR_INT_MASK)
-#define UART_INT_TX_OFLOW_ERR_INT_MSB            4
-#define UART_INT_TX_OFLOW_ERR_INT_LSB            4
-#define UART_INT_TX_OFLOW_ERR_INT_MASK           0x00000010
-#define UART_INT_TX_OFLOW_ERR_INT_GET(x)         (((x) & UART_INT_TX_OFLOW_ERR_INT_MASK) >> UART_INT_TX_OFLOW_ERR_INT_LSB)
-#define UART_INT_TX_OFLOW_ERR_INT_SET(x)         (((x) << UART_INT_TX_OFLOW_ERR_INT_LSB) & UART_INT_TX_OFLOW_ERR_INT_MASK)
-#define UART_INT_RX_OFLOW_ERR_INT_MSB            3
-#define UART_INT_RX_OFLOW_ERR_INT_LSB            3
-#define UART_INT_RX_OFLOW_ERR_INT_MASK           0x00000008
-#define UART_INT_RX_OFLOW_ERR_INT_GET(x)         (((x) & UART_INT_RX_OFLOW_ERR_INT_MASK) >> UART_INT_RX_OFLOW_ERR_INT_LSB)
-#define UART_INT_RX_OFLOW_ERR_INT_SET(x)         (((x) << UART_INT_RX_OFLOW_ERR_INT_LSB) & UART_INT_RX_OFLOW_ERR_INT_MASK)
-#define UART_INT_RX_FRAMING_ERR_INT_MSB          2
-#define UART_INT_RX_FRAMING_ERR_INT_LSB          2
-#define UART_INT_RX_FRAMING_ERR_INT_MASK         0x00000004
-#define UART_INT_RX_FRAMING_ERR_INT_GET(x)       (((x) & UART_INT_RX_FRAMING_ERR_INT_MASK) >> UART_INT_RX_FRAMING_ERR_INT_LSB)
-#define UART_INT_RX_FRAMING_ERR_INT_SET(x)       (((x) << UART_INT_RX_FRAMING_ERR_INT_LSB) & UART_INT_RX_FRAMING_ERR_INT_MASK)
-#define UART_INT_TX_READY_INT_MSB                1
-#define UART_INT_TX_READY_INT_LSB                1
-#define UART_INT_TX_READY_INT_MASK               0x00000002
-#define UART_INT_TX_READY_INT_GET(x)             (((x) & UART_INT_TX_READY_INT_MASK) >> UART_INT_TX_READY_INT_LSB)
-#define UART_INT_TX_READY_INT_SET(x)             (((x) << UART_INT_TX_READY_INT_LSB) & UART_INT_TX_READY_INT_MASK)
-#define UART_INT_RX_VALID_INT_MSB                0
-#define UART_INT_RX_VALID_INT_LSB                0
-#define UART_INT_RX_VALID_INT_MASK               0x00000001
-#define UART_INT_RX_VALID_INT_GET(x)             (((x) & UART_INT_RX_VALID_INT_MASK) >> UART_INT_RX_VALID_INT_LSB)
-#define UART_INT_RX_VALID_INT_SET(x)             (((x) << UART_INT_RX_VALID_INT_LSB) & UART_INT_RX_VALID_INT_MASK)
-
-#define UART_INT_EN_ADDRESS                      0x00000010
-#define UART_INT_EN_OFFSET                       0x00000010
-#define UART_INT_EN_TX_EMPTY_INT_EN_MSB          9
-#define UART_INT_EN_TX_EMPTY_INT_EN_LSB          9
-#define UART_INT_EN_TX_EMPTY_INT_EN_MASK         0x00000200
-#define UART_INT_EN_TX_EMPTY_INT_EN_GET(x)       (((x) & UART_INT_EN_TX_EMPTY_INT_EN_MASK) >> UART_INT_EN_TX_EMPTY_INT_EN_LSB)
-#define UART_INT_EN_TX_EMPTY_INT_EN_SET(x)       (((x) << UART_INT_EN_TX_EMPTY_INT_EN_LSB) & UART_INT_EN_TX_EMPTY_INT_EN_MASK)
-#define UART_INT_EN_RX_FULL_INT_EN_MSB           8
-#define UART_INT_EN_RX_FULL_INT_EN_LSB           8
-#define UART_INT_EN_RX_FULL_INT_EN_MASK          0x00000100
-#define UART_INT_EN_RX_FULL_INT_EN_GET(x)        (((x) & UART_INT_EN_RX_FULL_INT_EN_MASK) >> UART_INT_EN_RX_FULL_INT_EN_LSB)
-#define UART_INT_EN_RX_FULL_INT_EN_SET(x)        (((x) << UART_INT_EN_RX_FULL_INT_EN_LSB) & UART_INT_EN_RX_FULL_INT_EN_MASK)
-#define UART_INT_EN_RX_BREAK_OFF_INT_EN_MSB      7
-#define UART_INT_EN_RX_BREAK_OFF_INT_EN_LSB      7
-#define UART_INT_EN_RX_BREAK_OFF_INT_EN_MASK     0x00000080
-#define UART_INT_EN_RX_BREAK_OFF_INT_EN_GET(x)   (((x) & UART_INT_EN_RX_BREAK_OFF_INT_EN_MASK) >> UART_INT_EN_RX_BREAK_OFF_INT_EN_LSB)
-#define UART_INT_EN_RX_BREAK_OFF_INT_EN_SET(x)   (((x) << UART_INT_EN_RX_BREAK_OFF_INT_EN_LSB) & UART_INT_EN_RX_BREAK_OFF_INT_EN_MASK)
-#define UART_INT_EN_RX_BREAK_ON_INT_EN_MSB       6
-#define UART_INT_EN_RX_BREAK_ON_INT_EN_LSB       6
-#define UART_INT_EN_RX_BREAK_ON_INT_EN_MASK      0x00000040
-#define UART_INT_EN_RX_BREAK_ON_INT_EN_GET(x)    (((x) & UART_INT_EN_RX_BREAK_ON_INT_EN_MASK) >> UART_INT_EN_RX_BREAK_ON_INT_EN_LSB)
-#define UART_INT_EN_RX_BREAK_ON_INT_EN_SET(x)    (((x) << UART_INT_EN_RX_BREAK_ON_INT_EN_LSB) & UART_INT_EN_RX_BREAK_ON_INT_EN_MASK)
-#define UART_INT_EN_RX_PARITY_ERR_INT_EN_MSB     5
-#define UART_INT_EN_RX_PARITY_ERR_INT_EN_LSB     5
-#define UART_INT_EN_RX_PARITY_ERR_INT_EN_MASK    0x00000020
-#define UART_INT_EN_RX_PARITY_ERR_INT_EN_GET(x)  (((x) & UART_INT_EN_RX_PARITY_ERR_INT_EN_MASK) >> UART_INT_EN_RX_PARITY_ERR_INT_EN_LSB)
-#define UART_INT_EN_RX_PARITY_ERR_INT_EN_SET(x)  (((x) << UART_INT_EN_RX_PARITY_ERR_INT_EN_LSB) & UART_INT_EN_RX_PARITY_ERR_INT_EN_MASK)
-#define UART_INT_EN_TX_OFLOW_ERR_INT_EN_MSB      4
-#define UART_INT_EN_TX_OFLOW_ERR_INT_EN_LSB      4
-#define UART_INT_EN_TX_OFLOW_ERR_INT_EN_MASK     0x00000010
-#define UART_INT_EN_TX_OFLOW_ERR_INT_EN_GET(x)   (((x) & UART_INT_EN_TX_OFLOW_ERR_INT_EN_MASK) >> UART_INT_EN_TX_OFLOW_ERR_INT_EN_LSB)
-#define UART_INT_EN_TX_OFLOW_ERR_INT_EN_SET(x)   (((x) << UART_INT_EN_TX_OFLOW_ERR_INT_EN_LSB) & UART_INT_EN_TX_OFLOW_ERR_INT_EN_MASK)
-#define UART_INT_EN_RX_OFLOW_ERR_INT_EN_MSB      3
-#define UART_INT_EN_RX_OFLOW_ERR_INT_EN_LSB      3
-#define UART_INT_EN_RX_OFLOW_ERR_INT_EN_MASK     0x00000008
-#define UART_INT_EN_RX_OFLOW_ERR_INT_EN_GET(x)   (((x) & UART_INT_EN_RX_OFLOW_ERR_INT_EN_MASK) >> UART_INT_EN_RX_OFLOW_ERR_INT_EN_LSB)
-#define UART_INT_EN_RX_OFLOW_ERR_INT_EN_SET(x)   (((x) << UART_INT_EN_RX_OFLOW_ERR_INT_EN_LSB) & UART_INT_EN_RX_OFLOW_ERR_INT_EN_MASK)
-#define UART_INT_EN_RX_FRAMING_ERR_INT_EN_MSB    2
-#define UART_INT_EN_RX_FRAMING_ERR_INT_EN_LSB    2
-#define UART_INT_EN_RX_FRAMING_ERR_INT_EN_MASK   0x00000004
-#define UART_INT_EN_RX_FRAMING_ERR_INT_EN_GET(x) (((x) & UART_INT_EN_RX_FRAMING_ERR_INT_EN_MASK) >> UART_INT_EN_RX_FRAMING_ERR_INT_EN_LSB)
-#define UART_INT_EN_RX_FRAMING_ERR_INT_EN_SET(x) (((x) << UART_INT_EN_RX_FRAMING_ERR_INT_EN_LSB) & UART_INT_EN_RX_FRAMING_ERR_INT_EN_MASK)
-#define UART_INT_EN_TX_READY_INT_EN_MSB          1
-#define UART_INT_EN_TX_READY_INT_EN_LSB          1
-#define UART_INT_EN_TX_READY_INT_EN_MASK         0x00000002
-#define UART_INT_EN_TX_READY_INT_EN_GET(x)       (((x) & UART_INT_EN_TX_READY_INT_EN_MASK) >> UART_INT_EN_TX_READY_INT_EN_LSB)
-#define UART_INT_EN_TX_READY_INT_EN_SET(x)       (((x) << UART_INT_EN_TX_READY_INT_EN_LSB) & UART_INT_EN_TX_READY_INT_EN_MASK)
-#define UART_INT_EN_RX_VALID_INT_EN_MSB          0
-#define UART_INT_EN_RX_VALID_INT_EN_LSB          0
-#define UART_INT_EN_RX_VALID_INT_EN_MASK         0x00000001
-#define UART_INT_EN_RX_VALID_INT_EN_GET(x)       (((x) & UART_INT_EN_RX_VALID_INT_EN_MASK) >> UART_INT_EN_RX_VALID_INT_EN_LSB)
-#define UART_INT_EN_RX_VALID_INT_EN_SET(x)       (((x) << UART_INT_EN_RX_VALID_INT_EN_LSB) & UART_INT_EN_RX_VALID_INT_EN_MASK)
-
-
-#ifndef __ASSEMBLER__
-
-typedef struct uart_reg_reg_s {
-  volatile unsigned int uart_data;
-  volatile unsigned int uart_control;
-  volatile unsigned int uart_clkdiv;
-  volatile unsigned int uart_int;
-  volatile unsigned int uart_int_en;
-} uart_reg_reg_t;
-
-#endif /* __ASSEMBLER__ */
-
 #endif /* _UART_REG_H_ */
diff -druN linux-2.6.39-libre/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/umbox_reg.h linux-3.0-rc7-libre/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/umbox_reg.h
--- linux-2.6.39-libre/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/umbox_reg.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/umbox_reg.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,37 +0,0 @@
-// ------------------------------------------------------------------
-// Copyright (c) 2004-2010 Atheros Corporation.  All rights reserved.
-// 
-//
-// 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.
-//
-//
-// ------------------------------------------------------------------
-//===================================================================
-// Author(s): ="Atheros"
-//===================================================================
-
-
-#ifdef WLAN_HEADERS
-
-#include "umbox_wlan_reg.h"
-
-
-#ifndef BT_HEADERS
-
-
-
-#endif
-#endif
-
-
-
diff -druN linux-2.6.39-libre/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/umbox_wlan_reg.h linux-3.0-rc7-libre/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/umbox_wlan_reg.h
--- linux-2.6.39-libre/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/umbox_wlan_reg.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/umbox_wlan_reg.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,322 +0,0 @@
-// ------------------------------------------------------------------
-// Copyright (c) 2004-2010 Atheros Corporation.  All rights reserved.
-// 
-//
-// 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.
-//
-//
-// ------------------------------------------------------------------
-//===================================================================
-// Author(s): ="Atheros"
-//===================================================================
-
-
-#ifndef _UMBOX_WLAN_REG_REG_H_
-#define _UMBOX_WLAN_REG_REG_H_
-
-#define UMBOX_FIFO_ADDRESS                       0x00000000
-#define UMBOX_FIFO_OFFSET                        0x00000000
-#define UMBOX_FIFO_DATA_MSB                      8
-#define UMBOX_FIFO_DATA_LSB                      0
-#define UMBOX_FIFO_DATA_MASK                     0x000001ff
-#define UMBOX_FIFO_DATA_GET(x)                   (((x) & UMBOX_FIFO_DATA_MASK) >> UMBOX_FIFO_DATA_LSB)
-#define UMBOX_FIFO_DATA_SET(x)                   (((x) << UMBOX_FIFO_DATA_LSB) & UMBOX_FIFO_DATA_MASK)
-
-#define UMBOX_FIFO_STATUS_ADDRESS                0x00000008
-#define UMBOX_FIFO_STATUS_OFFSET                 0x00000008
-#define UMBOX_FIFO_STATUS_TX_EMPTY_MSB           3
-#define UMBOX_FIFO_STATUS_TX_EMPTY_LSB           3
-#define UMBOX_FIFO_STATUS_TX_EMPTY_MASK          0x00000008
-#define UMBOX_FIFO_STATUS_TX_EMPTY_GET(x)        (((x) & UMBOX_FIFO_STATUS_TX_EMPTY_MASK) >> UMBOX_FIFO_STATUS_TX_EMPTY_LSB)
-#define UMBOX_FIFO_STATUS_TX_EMPTY_SET(x)        (((x) << UMBOX_FIFO_STATUS_TX_EMPTY_LSB) & UMBOX_FIFO_STATUS_TX_EMPTY_MASK)
-#define UMBOX_FIFO_STATUS_TX_FULL_MSB            2
-#define UMBOX_FIFO_STATUS_TX_FULL_LSB            2
-#define UMBOX_FIFO_STATUS_TX_FULL_MASK           0x00000004
-#define UMBOX_FIFO_STATUS_TX_FULL_GET(x)         (((x) & UMBOX_FIFO_STATUS_TX_FULL_MASK) >> UMBOX_FIFO_STATUS_TX_FULL_LSB)
-#define UMBOX_FIFO_STATUS_TX_FULL_SET(x)         (((x) << UMBOX_FIFO_STATUS_TX_FULL_LSB) & UMBOX_FIFO_STATUS_TX_FULL_MASK)
-#define UMBOX_FIFO_STATUS_RX_EMPTY_MSB           1
-#define UMBOX_FIFO_STATUS_RX_EMPTY_LSB           1
-#define UMBOX_FIFO_STATUS_RX_EMPTY_MASK          0x00000002
-#define UMBOX_FIFO_STATUS_RX_EMPTY_GET(x)        (((x) & UMBOX_FIFO_STATUS_RX_EMPTY_MASK) >> UMBOX_FIFO_STATUS_RX_EMPTY_LSB)
-#define UMBOX_FIFO_STATUS_RX_EMPTY_SET(x)        (((x) << UMBOX_FIFO_STATUS_RX_EMPTY_LSB) & UMBOX_FIFO_STATUS_RX_EMPTY_MASK)
-#define UMBOX_FIFO_STATUS_RX_FULL_MSB            0
-#define UMBOX_FIFO_STATUS_RX_FULL_LSB            0
-#define UMBOX_FIFO_STATUS_RX_FULL_MASK           0x00000001
-#define UMBOX_FIFO_STATUS_RX_FULL_GET(x)         (((x) & UMBOX_FIFO_STATUS_RX_FULL_MASK) >> UMBOX_FIFO_STATUS_RX_FULL_LSB)
-#define UMBOX_FIFO_STATUS_RX_FULL_SET(x)         (((x) << UMBOX_FIFO_STATUS_RX_FULL_LSB) & UMBOX_FIFO_STATUS_RX_FULL_MASK)
-
-#define UMBOX_DMA_POLICY_ADDRESS                 0x0000000c
-#define UMBOX_DMA_POLICY_OFFSET                  0x0000000c
-#define UMBOX_DMA_POLICY_TX_QUANTUM_MSB          3
-#define UMBOX_DMA_POLICY_TX_QUANTUM_LSB          3
-#define UMBOX_DMA_POLICY_TX_QUANTUM_MASK         0x00000008
-#define UMBOX_DMA_POLICY_TX_QUANTUM_GET(x)       (((x) & UMBOX_DMA_POLICY_TX_QUANTUM_MASK) >> UMBOX_DMA_POLICY_TX_QUANTUM_LSB)
-#define UMBOX_DMA_POLICY_TX_QUANTUM_SET(x)       (((x) << UMBOX_DMA_POLICY_TX_QUANTUM_LSB) & UMBOX_DMA_POLICY_TX_QUANTUM_MASK)
-#define UMBOX_DMA_POLICY_TX_ORDER_MSB            2
-#define UMBOX_DMA_POLICY_TX_ORDER_LSB            2
-#define UMBOX_DMA_POLICY_TX_ORDER_MASK           0x00000004
-#define UMBOX_DMA_POLICY_TX_ORDER_GET(x)         (((x) & UMBOX_DMA_POLICY_TX_ORDER_MASK) >> UMBOX_DMA_POLICY_TX_ORDER_LSB)
-#define UMBOX_DMA_POLICY_TX_ORDER_SET(x)         (((x) << UMBOX_DMA_POLICY_TX_ORDER_LSB) & UMBOX_DMA_POLICY_TX_ORDER_MASK)
-#define UMBOX_DMA_POLICY_RX_QUANTUM_MSB          1
-#define UMBOX_DMA_POLICY_RX_QUANTUM_LSB          1
-#define UMBOX_DMA_POLICY_RX_QUANTUM_MASK         0x00000002
-#define UMBOX_DMA_POLICY_RX_QUANTUM_GET(x)       (((x) & UMBOX_DMA_POLICY_RX_QUANTUM_MASK) >> UMBOX_DMA_POLICY_RX_QUANTUM_LSB)
-#define UMBOX_DMA_POLICY_RX_QUANTUM_SET(x)       (((x) << UMBOX_DMA_POLICY_RX_QUANTUM_LSB) & UMBOX_DMA_POLICY_RX_QUANTUM_MASK)
-#define UMBOX_DMA_POLICY_RX_ORDER_MSB            0
-#define UMBOX_DMA_POLICY_RX_ORDER_LSB            0
-#define UMBOX_DMA_POLICY_RX_ORDER_MASK           0x00000001
-#define UMBOX_DMA_POLICY_RX_ORDER_GET(x)         (((x) & UMBOX_DMA_POLICY_RX_ORDER_MASK) >> UMBOX_DMA_POLICY_RX_ORDER_LSB)
-#define UMBOX_DMA_POLICY_RX_ORDER_SET(x)         (((x) << UMBOX_DMA_POLICY_RX_ORDER_LSB) & UMBOX_DMA_POLICY_RX_ORDER_MASK)
-
-#define UMBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS    0x00000010
-#define UMBOX0_DMA_RX_DESCRIPTOR_BASE_OFFSET     0x00000010
-#define UMBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MSB 27
-#define UMBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_LSB 2
-#define UMBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MASK 0x0ffffffc
-#define UMBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_GET(x) (((x) & UMBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MASK) >> UMBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_LSB)
-#define UMBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_SET(x) (((x) << UMBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_LSB) & UMBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MASK)
-
-#define UMBOX0_DMA_RX_CONTROL_ADDRESS            0x00000014
-#define UMBOX0_DMA_RX_CONTROL_OFFSET             0x00000014
-#define UMBOX0_DMA_RX_CONTROL_RESUME_MSB         2
-#define UMBOX0_DMA_RX_CONTROL_RESUME_LSB         2
-#define UMBOX0_DMA_RX_CONTROL_RESUME_MASK        0x00000004
-#define UMBOX0_DMA_RX_CONTROL_RESUME_GET(x)      (((x) & UMBOX0_DMA_RX_CONTROL_RESUME_MASK) >> UMBOX0_DMA_RX_CONTROL_RESUME_LSB)
-#define UMBOX0_DMA_RX_CONTROL_RESUME_SET(x)      (((x) << UMBOX0_DMA_RX_CONTROL_RESUME_LSB) & UMBOX0_DMA_RX_CONTROL_RESUME_MASK)
-#define UMBOX0_DMA_RX_CONTROL_START_MSB          1
-#define UMBOX0_DMA_RX_CONTROL_START_LSB          1
-#define UMBOX0_DMA_RX_CONTROL_START_MASK         0x00000002
-#define UMBOX0_DMA_RX_CONTROL_START_GET(x)       (((x) & UMBOX0_DMA_RX_CONTROL_START_MASK) >> UMBOX0_DMA_RX_CONTROL_START_LSB)
-#define UMBOX0_DMA_RX_CONTROL_START_SET(x)       (((x) << UMBOX0_DMA_RX_CONTROL_START_LSB) & UMBOX0_DMA_RX_CONTROL_START_MASK)
-#define UMBOX0_DMA_RX_CONTROL_STOP_MSB           0
-#define UMBOX0_DMA_RX_CONTROL_STOP_LSB           0
-#define UMBOX0_DMA_RX_CONTROL_STOP_MASK          0x00000001
-#define UMBOX0_DMA_RX_CONTROL_STOP_GET(x)        (((x) & UMBOX0_DMA_RX_CONTROL_STOP_MASK) >> UMBOX0_DMA_RX_CONTROL_STOP_LSB)
-#define UMBOX0_DMA_RX_CONTROL_STOP_SET(x)        (((x) << UMBOX0_DMA_RX_CONTROL_STOP_LSB) & UMBOX0_DMA_RX_CONTROL_STOP_MASK)
-
-#define UMBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS    0x00000018
-#define UMBOX0_DMA_TX_DESCRIPTOR_BASE_OFFSET     0x00000018
-#define UMBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MSB 27
-#define UMBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_LSB 2
-#define UMBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MASK 0x0ffffffc
-#define UMBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_GET(x) (((x) & UMBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MASK) >> UMBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_LSB)
-#define UMBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_SET(x) (((x) << UMBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_LSB) & UMBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MASK)
-
-#define UMBOX0_DMA_TX_CONTROL_ADDRESS            0x0000001c
-#define UMBOX0_DMA_TX_CONTROL_OFFSET             0x0000001c
-#define UMBOX0_DMA_TX_CONTROL_RESUME_MSB         2
-#define UMBOX0_DMA_TX_CONTROL_RESUME_LSB         2
-#define UMBOX0_DMA_TX_CONTROL_RESUME_MASK        0x00000004
-#define UMBOX0_DMA_TX_CONTROL_RESUME_GET(x)      (((x) & UMBOX0_DMA_TX_CONTROL_RESUME_MASK) >> UMBOX0_DMA_TX_CONTROL_RESUME_LSB)
-#define UMBOX0_DMA_TX_CONTROL_RESUME_SET(x)      (((x) << UMBOX0_DMA_TX_CONTROL_RESUME_LSB) & UMBOX0_DMA_TX_CONTROL_RESUME_MASK)
-#define UMBOX0_DMA_TX_CONTROL_START_MSB          1
-#define UMBOX0_DMA_TX_CONTROL_START_LSB          1
-#define UMBOX0_DMA_TX_CONTROL_START_MASK         0x00000002
-#define UMBOX0_DMA_TX_CONTROL_START_GET(x)       (((x) & UMBOX0_DMA_TX_CONTROL_START_MASK) >> UMBOX0_DMA_TX_CONTROL_START_LSB)
-#define UMBOX0_DMA_TX_CONTROL_START_SET(x)       (((x) << UMBOX0_DMA_TX_CONTROL_START_LSB) & UMBOX0_DMA_TX_CONTROL_START_MASK)
-#define UMBOX0_DMA_TX_CONTROL_STOP_MSB           0
-#define UMBOX0_DMA_TX_CONTROL_STOP_LSB           0
-#define UMBOX0_DMA_TX_CONTROL_STOP_MASK          0x00000001
-#define UMBOX0_DMA_TX_CONTROL_STOP_GET(x)        (((x) & UMBOX0_DMA_TX_CONTROL_STOP_MASK) >> UMBOX0_DMA_TX_CONTROL_STOP_LSB)
-#define UMBOX0_DMA_TX_CONTROL_STOP_SET(x)        (((x) << UMBOX0_DMA_TX_CONTROL_STOP_LSB) & UMBOX0_DMA_TX_CONTROL_STOP_MASK)
-
-#define UMBOX_FIFO_TIMEOUT_ADDRESS               0x00000020
-#define UMBOX_FIFO_TIMEOUT_OFFSET                0x00000020
-#define UMBOX_FIFO_TIMEOUT_ENABLE_SET_MSB        8
-#define UMBOX_FIFO_TIMEOUT_ENABLE_SET_LSB        8
-#define UMBOX_FIFO_TIMEOUT_ENABLE_SET_MASK       0x00000100
-#define UMBOX_FIFO_TIMEOUT_ENABLE_SET_GET(x)     (((x) & UMBOX_FIFO_TIMEOUT_ENABLE_SET_MASK) >> UMBOX_FIFO_TIMEOUT_ENABLE_SET_LSB)
-#define UMBOX_FIFO_TIMEOUT_ENABLE_SET_SET(x)     (((x) << UMBOX_FIFO_TIMEOUT_ENABLE_SET_LSB) & UMBOX_FIFO_TIMEOUT_ENABLE_SET_MASK)
-#define UMBOX_FIFO_TIMEOUT_VALUE_MSB             7
-#define UMBOX_FIFO_TIMEOUT_VALUE_LSB             0
-#define UMBOX_FIFO_TIMEOUT_VALUE_MASK            0x000000ff
-#define UMBOX_FIFO_TIMEOUT_VALUE_GET(x)          (((x) & UMBOX_FIFO_TIMEOUT_VALUE_MASK) >> UMBOX_FIFO_TIMEOUT_VALUE_LSB)
-#define UMBOX_FIFO_TIMEOUT_VALUE_SET(x)          (((x) << UMBOX_FIFO_TIMEOUT_VALUE_LSB) & UMBOX_FIFO_TIMEOUT_VALUE_MASK)
-
-#define UMBOX_INT_STATUS_ADDRESS                 0x00000024
-#define UMBOX_INT_STATUS_OFFSET                  0x00000024
-#define UMBOX_INT_STATUS_HCI_FRAMER_UNDERFLOW_MSB 9
-#define UMBOX_INT_STATUS_HCI_FRAMER_UNDERFLOW_LSB 9
-#define UMBOX_INT_STATUS_HCI_FRAMER_UNDERFLOW_MASK 0x00000200
-#define UMBOX_INT_STATUS_HCI_FRAMER_UNDERFLOW_GET(x) (((x) & UMBOX_INT_STATUS_HCI_FRAMER_UNDERFLOW_MASK) >> UMBOX_INT_STATUS_HCI_FRAMER_UNDERFLOW_LSB)
-#define UMBOX_INT_STATUS_HCI_FRAMER_UNDERFLOW_SET(x) (((x) << UMBOX_INT_STATUS_HCI_FRAMER_UNDERFLOW_LSB) & UMBOX_INT_STATUS_HCI_FRAMER_UNDERFLOW_MASK)
-#define UMBOX_INT_STATUS_HCI_FRAMER_OVERFLOW_MSB 8
-#define UMBOX_INT_STATUS_HCI_FRAMER_OVERFLOW_LSB 8
-#define UMBOX_INT_STATUS_HCI_FRAMER_OVERFLOW_MASK 0x00000100
-#define UMBOX_INT_STATUS_HCI_FRAMER_OVERFLOW_GET(x) (((x) & UMBOX_INT_STATUS_HCI_FRAMER_OVERFLOW_MASK) >> UMBOX_INT_STATUS_HCI_FRAMER_OVERFLOW_LSB)
-#define UMBOX_INT_STATUS_HCI_FRAMER_OVERFLOW_SET(x) (((x) << UMBOX_INT_STATUS_HCI_FRAMER_OVERFLOW_LSB) & UMBOX_INT_STATUS_HCI_FRAMER_OVERFLOW_MASK)
-#define UMBOX_INT_STATUS_RX_DMA_COMPLETE_MSB     7
-#define UMBOX_INT_STATUS_RX_DMA_COMPLETE_LSB     7
-#define UMBOX_INT_STATUS_RX_DMA_COMPLETE_MASK    0x00000080
-#define UMBOX_INT_STATUS_RX_DMA_COMPLETE_GET(x)  (((x) & UMBOX_INT_STATUS_RX_DMA_COMPLETE_MASK) >> UMBOX_INT_STATUS_RX_DMA_COMPLETE_LSB)
-#define UMBOX_INT_STATUS_RX_DMA_COMPLETE_SET(x)  (((x) << UMBOX_INT_STATUS_RX_DMA_COMPLETE_LSB) & UMBOX_INT_STATUS_RX_DMA_COMPLETE_MASK)
-#define UMBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_MSB 6
-#define UMBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_LSB 6
-#define UMBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_MASK 0x00000040
-#define UMBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_GET(x) (((x) & UMBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_MASK) >> UMBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_LSB)
-#define UMBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_SET(x) (((x) << UMBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_LSB) & UMBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_MASK)
-#define UMBOX_INT_STATUS_TX_DMA_COMPLETE_MSB     5
-#define UMBOX_INT_STATUS_TX_DMA_COMPLETE_LSB     5
-#define UMBOX_INT_STATUS_TX_DMA_COMPLETE_MASK    0x00000020
-#define UMBOX_INT_STATUS_TX_DMA_COMPLETE_GET(x)  (((x) & UMBOX_INT_STATUS_TX_DMA_COMPLETE_MASK) >> UMBOX_INT_STATUS_TX_DMA_COMPLETE_LSB)
-#define UMBOX_INT_STATUS_TX_DMA_COMPLETE_SET(x)  (((x) << UMBOX_INT_STATUS_TX_DMA_COMPLETE_LSB) & UMBOX_INT_STATUS_TX_DMA_COMPLETE_MASK)
-#define UMBOX_INT_STATUS_HCI_SYNC_ERROR_MSB      4
-#define UMBOX_INT_STATUS_HCI_SYNC_ERROR_LSB      4
-#define UMBOX_INT_STATUS_HCI_SYNC_ERROR_MASK     0x00000010
-#define UMBOX_INT_STATUS_HCI_SYNC_ERROR_GET(x)   (((x) & UMBOX_INT_STATUS_HCI_SYNC_ERROR_MASK) >> UMBOX_INT_STATUS_HCI_SYNC_ERROR_LSB)
-#define UMBOX_INT_STATUS_HCI_SYNC_ERROR_SET(x)   (((x) << UMBOX_INT_STATUS_HCI_SYNC_ERROR_LSB) & UMBOX_INT_STATUS_HCI_SYNC_ERROR_MASK)
-#define UMBOX_INT_STATUS_TX_OVERFLOW_MSB         3
-#define UMBOX_INT_STATUS_TX_OVERFLOW_LSB         3
-#define UMBOX_INT_STATUS_TX_OVERFLOW_MASK        0x00000008
-#define UMBOX_INT_STATUS_TX_OVERFLOW_GET(x)      (((x) & UMBOX_INT_STATUS_TX_OVERFLOW_MASK) >> UMBOX_INT_STATUS_TX_OVERFLOW_LSB)
-#define UMBOX_INT_STATUS_TX_OVERFLOW_SET(x)      (((x) << UMBOX_INT_STATUS_TX_OVERFLOW_LSB) & UMBOX_INT_STATUS_TX_OVERFLOW_MASK)
-#define UMBOX_INT_STATUS_RX_UNDERFLOW_MSB        2
-#define UMBOX_INT_STATUS_RX_UNDERFLOW_LSB        2
-#define UMBOX_INT_STATUS_RX_UNDERFLOW_MASK       0x00000004
-#define UMBOX_INT_STATUS_RX_UNDERFLOW_GET(x)     (((x) & UMBOX_INT_STATUS_RX_UNDERFLOW_MASK) >> UMBOX_INT_STATUS_RX_UNDERFLOW_LSB)
-#define UMBOX_INT_STATUS_RX_UNDERFLOW_SET(x)     (((x) << UMBOX_INT_STATUS_RX_UNDERFLOW_LSB) & UMBOX_INT_STATUS_RX_UNDERFLOW_MASK)
-#define UMBOX_INT_STATUS_TX_NOT_EMPTY_MSB        1
-#define UMBOX_INT_STATUS_TX_NOT_EMPTY_LSB        1
-#define UMBOX_INT_STATUS_TX_NOT_EMPTY_MASK       0x00000002
-#define UMBOX_INT_STATUS_TX_NOT_EMPTY_GET(x)     (((x) & UMBOX_INT_STATUS_TX_NOT_EMPTY_MASK) >> UMBOX_INT_STATUS_TX_NOT_EMPTY_LSB)
-#define UMBOX_INT_STATUS_TX_NOT_EMPTY_SET(x)     (((x) << UMBOX_INT_STATUS_TX_NOT_EMPTY_LSB) & UMBOX_INT_STATUS_TX_NOT_EMPTY_MASK)
-#define UMBOX_INT_STATUS_RX_NOT_FULL_MSB         0
-#define UMBOX_INT_STATUS_RX_NOT_FULL_LSB         0
-#define UMBOX_INT_STATUS_RX_NOT_FULL_MASK        0x00000001
-#define UMBOX_INT_STATUS_RX_NOT_FULL_GET(x)      (((x) & UMBOX_INT_STATUS_RX_NOT_FULL_MASK) >> UMBOX_INT_STATUS_RX_NOT_FULL_LSB)
-#define UMBOX_INT_STATUS_RX_NOT_FULL_SET(x)      (((x) << UMBOX_INT_STATUS_RX_NOT_FULL_LSB) & UMBOX_INT_STATUS_RX_NOT_FULL_MASK)
-
-#define UMBOX_INT_ENABLE_ADDRESS                 0x00000028
-#define UMBOX_INT_ENABLE_OFFSET                  0x00000028
-#define UMBOX_INT_ENABLE_HCI_FRAMER_UNDERFLOW_MSB 9
-#define UMBOX_INT_ENABLE_HCI_FRAMER_UNDERFLOW_LSB 9
-#define UMBOX_INT_ENABLE_HCI_FRAMER_UNDERFLOW_MASK 0x00000200
-#define UMBOX_INT_ENABLE_HCI_FRAMER_UNDERFLOW_GET(x) (((x) & UMBOX_INT_ENABLE_HCI_FRAMER_UNDERFLOW_MASK) >> UMBOX_INT_ENABLE_HCI_FRAMER_UNDERFLOW_LSB)
-#define UMBOX_INT_ENABLE_HCI_FRAMER_UNDERFLOW_SET(x) (((x) << UMBOX_INT_ENABLE_HCI_FRAMER_UNDERFLOW_LSB) & UMBOX_INT_ENABLE_HCI_FRAMER_UNDERFLOW_MASK)
-#define UMBOX_INT_ENABLE_HCI_FRAMER_OVERFLOW_MSB 8
-#define UMBOX_INT_ENABLE_HCI_FRAMER_OVERFLOW_LSB 8
-#define UMBOX_INT_ENABLE_HCI_FRAMER_OVERFLOW_MASK 0x00000100
-#define UMBOX_INT_ENABLE_HCI_FRAMER_OVERFLOW_GET(x) (((x) & UMBOX_INT_ENABLE_HCI_FRAMER_OVERFLOW_MASK) >> UMBOX_INT_ENABLE_HCI_FRAMER_OVERFLOW_LSB)
-#define UMBOX_INT_ENABLE_HCI_FRAMER_OVERFLOW_SET(x) (((x) << UMBOX_INT_ENABLE_HCI_FRAMER_OVERFLOW_LSB) & UMBOX_INT_ENABLE_HCI_FRAMER_OVERFLOW_MASK)
-#define UMBOX_INT_ENABLE_RX_DMA_COMPLETE_MSB     7
-#define UMBOX_INT_ENABLE_RX_DMA_COMPLETE_LSB     7
-#define UMBOX_INT_ENABLE_RX_DMA_COMPLETE_MASK    0x00000080
-#define UMBOX_INT_ENABLE_RX_DMA_COMPLETE_GET(x)  (((x) & UMBOX_INT_ENABLE_RX_DMA_COMPLETE_MASK) >> UMBOX_INT_ENABLE_RX_DMA_COMPLETE_LSB)
-#define UMBOX_INT_ENABLE_RX_DMA_COMPLETE_SET(x)  (((x) << UMBOX_INT_ENABLE_RX_DMA_COMPLETE_LSB) & UMBOX_INT_ENABLE_RX_DMA_COMPLETE_MASK)
-#define UMBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_MSB 6
-#define UMBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_LSB 6
-#define UMBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_MASK 0x00000040
-#define UMBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_GET(x) (((x) & UMBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_MASK) >> UMBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_LSB)
-#define UMBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_SET(x) (((x) << UMBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_LSB) & UMBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_MASK)
-#define UMBOX_INT_ENABLE_TX_DMA_COMPLETE_MSB     5
-#define UMBOX_INT_ENABLE_TX_DMA_COMPLETE_LSB     5
-#define UMBOX_INT_ENABLE_TX_DMA_COMPLETE_MASK    0x00000020
-#define UMBOX_INT_ENABLE_TX_DMA_COMPLETE_GET(x)  (((x) & UMBOX_INT_ENABLE_TX_DMA_COMPLETE_MASK) >> UMBOX_INT_ENABLE_TX_DMA_COMPLETE_LSB)
-#define UMBOX_INT_ENABLE_TX_DMA_COMPLETE_SET(x)  (((x) << UMBOX_INT_ENABLE_TX_DMA_COMPLETE_LSB) & UMBOX_INT_ENABLE_TX_DMA_COMPLETE_MASK)
-#define UMBOX_INT_ENABLE_HCI_SYNC_ERROR_MSB      4
-#define UMBOX_INT_ENABLE_HCI_SYNC_ERROR_LSB      4
-#define UMBOX_INT_ENABLE_HCI_SYNC_ERROR_MASK     0x00000010
-#define UMBOX_INT_ENABLE_HCI_SYNC_ERROR_GET(x)   (((x) & UMBOX_INT_ENABLE_HCI_SYNC_ERROR_MASK) >> UMBOX_INT_ENABLE_HCI_SYNC_ERROR_LSB)
-#define UMBOX_INT_ENABLE_HCI_SYNC_ERROR_SET(x)   (((x) << UMBOX_INT_ENABLE_HCI_SYNC_ERROR_LSB) & UMBOX_INT_ENABLE_HCI_SYNC_ERROR_MASK)
-#define UMBOX_INT_ENABLE_TX_OVERFLOW_MSB         3
-#define UMBOX_INT_ENABLE_TX_OVERFLOW_LSB         3
-#define UMBOX_INT_ENABLE_TX_OVERFLOW_MASK        0x00000008
-#define UMBOX_INT_ENABLE_TX_OVERFLOW_GET(x)      (((x) & UMBOX_INT_ENABLE_TX_OVERFLOW_MASK) >> UMBOX_INT_ENABLE_TX_OVERFLOW_LSB)
-#define UMBOX_INT_ENABLE_TX_OVERFLOW_SET(x)      (((x) << UMBOX_INT_ENABLE_TX_OVERFLOW_LSB) & UMBOX_INT_ENABLE_TX_OVERFLOW_MASK)
-#define UMBOX_INT_ENABLE_RX_UNDERFLOW_MSB        2
-#define UMBOX_INT_ENABLE_RX_UNDERFLOW_LSB        2
-#define UMBOX_INT_ENABLE_RX_UNDERFLOW_MASK       0x00000004
-#define UMBOX_INT_ENABLE_RX_UNDERFLOW_GET(x)     (((x) & UMBOX_INT_ENABLE_RX_UNDERFLOW_MASK) >> UMBOX_INT_ENABLE_RX_UNDERFLOW_LSB)
-#define UMBOX_INT_ENABLE_RX_UNDERFLOW_SET(x)     (((x) << UMBOX_INT_ENABLE_RX_UNDERFLOW_LSB) & UMBOX_INT_ENABLE_RX_UNDERFLOW_MASK)
-#define UMBOX_INT_ENABLE_TX_NOT_EMPTY_MSB        1
-#define UMBOX_INT_ENABLE_TX_NOT_EMPTY_LSB        1
-#define UMBOX_INT_ENABLE_TX_NOT_EMPTY_MASK       0x00000002
-#define UMBOX_INT_ENABLE_TX_NOT_EMPTY_GET(x)     (((x) & UMBOX_INT_ENABLE_TX_NOT_EMPTY_MASK) >> UMBOX_INT_ENABLE_TX_NOT_EMPTY_LSB)
-#define UMBOX_INT_ENABLE_TX_NOT_EMPTY_SET(x)     (((x) << UMBOX_INT_ENABLE_TX_NOT_EMPTY_LSB) & UMBOX_INT_ENABLE_TX_NOT_EMPTY_MASK)
-#define UMBOX_INT_ENABLE_RX_NOT_FULL_MSB         0
-#define UMBOX_INT_ENABLE_RX_NOT_FULL_LSB         0
-#define UMBOX_INT_ENABLE_RX_NOT_FULL_MASK        0x00000001
-#define UMBOX_INT_ENABLE_RX_NOT_FULL_GET(x)      (((x) & UMBOX_INT_ENABLE_RX_NOT_FULL_MASK) >> UMBOX_INT_ENABLE_RX_NOT_FULL_LSB)
-#define UMBOX_INT_ENABLE_RX_NOT_FULL_SET(x)      (((x) << UMBOX_INT_ENABLE_RX_NOT_FULL_LSB) & UMBOX_INT_ENABLE_RX_NOT_FULL_MASK)
-
-#define UMBOX_DEBUG_ADDRESS                      0x0000002c
-#define UMBOX_DEBUG_OFFSET                       0x0000002c
-#define UMBOX_DEBUG_SEL_MSB                      2
-#define UMBOX_DEBUG_SEL_LSB                      0
-#define UMBOX_DEBUG_SEL_MASK                     0x00000007
-#define UMBOX_DEBUG_SEL_GET(x)                   (((x) & UMBOX_DEBUG_SEL_MASK) >> UMBOX_DEBUG_SEL_LSB)
-#define UMBOX_DEBUG_SEL_SET(x)                   (((x) << UMBOX_DEBUG_SEL_LSB) & UMBOX_DEBUG_SEL_MASK)
-
-#define UMBOX_FIFO_RESET_ADDRESS                 0x00000030
-#define UMBOX_FIFO_RESET_OFFSET                  0x00000030
-#define UMBOX_FIFO_RESET_INIT_MSB                0
-#define UMBOX_FIFO_RESET_INIT_LSB                0
-#define UMBOX_FIFO_RESET_INIT_MASK               0x00000001
-#define UMBOX_FIFO_RESET_INIT_GET(x)             (((x) & UMBOX_FIFO_RESET_INIT_MASK) >> UMBOX_FIFO_RESET_INIT_LSB)
-#define UMBOX_FIFO_RESET_INIT_SET(x)             (((x) << UMBOX_FIFO_RESET_INIT_LSB) & UMBOX_FIFO_RESET_INIT_MASK)
-
-#define UMBOX_HCI_FRAMER_ADDRESS                 0x00000034
-#define UMBOX_HCI_FRAMER_OFFSET                  0x00000034
-#define UMBOX_HCI_FRAMER_CRC_OVERRIDE_MSB        6
-#define UMBOX_HCI_FRAMER_CRC_OVERRIDE_LSB        6
-#define UMBOX_HCI_FRAMER_CRC_OVERRIDE_MASK       0x00000040
-#define UMBOX_HCI_FRAMER_CRC_OVERRIDE_GET(x)     (((x) & UMBOX_HCI_FRAMER_CRC_OVERRIDE_MASK) >> UMBOX_HCI_FRAMER_CRC_OVERRIDE_LSB)
-#define UMBOX_HCI_FRAMER_CRC_OVERRIDE_SET(x)     (((x) << UMBOX_HCI_FRAMER_CRC_OVERRIDE_LSB) & UMBOX_HCI_FRAMER_CRC_OVERRIDE_MASK)
-#define UMBOX_HCI_FRAMER_ENABLE_MSB              5
-#define UMBOX_HCI_FRAMER_ENABLE_LSB              5
-#define UMBOX_HCI_FRAMER_ENABLE_MASK             0x00000020
-#define UMBOX_HCI_FRAMER_ENABLE_GET(x)           (((x) & UMBOX_HCI_FRAMER_ENABLE_MASK) >> UMBOX_HCI_FRAMER_ENABLE_LSB)
-#define UMBOX_HCI_FRAMER_ENABLE_SET(x)           (((x) << UMBOX_HCI_FRAMER_ENABLE_LSB) & UMBOX_HCI_FRAMER_ENABLE_MASK)
-#define UMBOX_HCI_FRAMER_SYNC_ERROR_MSB          4
-#define UMBOX_HCI_FRAMER_SYNC_ERROR_LSB          4
-#define UMBOX_HCI_FRAMER_SYNC_ERROR_MASK         0x00000010
-#define UMBOX_HCI_FRAMER_SYNC_ERROR_GET(x)       (((x) & UMBOX_HCI_FRAMER_SYNC_ERROR_MASK) >> UMBOX_HCI_FRAMER_SYNC_ERROR_LSB)
-#define UMBOX_HCI_FRAMER_SYNC_ERROR_SET(x)       (((x) << UMBOX_HCI_FRAMER_SYNC_ERROR_LSB) & UMBOX_HCI_FRAMER_SYNC_ERROR_MASK)
-#define UMBOX_HCI_FRAMER_UNDERFLOW_MSB           3
-#define UMBOX_HCI_FRAMER_UNDERFLOW_LSB           3
-#define UMBOX_HCI_FRAMER_UNDERFLOW_MASK          0x00000008
-#define UMBOX_HCI_FRAMER_UNDERFLOW_GET(x)        (((x) & UMBOX_HCI_FRAMER_UNDERFLOW_MASK) >> UMBOX_HCI_FRAMER_UNDERFLOW_LSB)
-#define UMBOX_HCI_FRAMER_UNDERFLOW_SET(x)        (((x) << UMBOX_HCI_FRAMER_UNDERFLOW_LSB) & UMBOX_HCI_FRAMER_UNDERFLOW_MASK)
-#define UMBOX_HCI_FRAMER_OVERFLOW_MSB            2
-#define UMBOX_HCI_FRAMER_OVERFLOW_LSB            2
-#define UMBOX_HCI_FRAMER_OVERFLOW_MASK           0x00000004
-#define UMBOX_HCI_FRAMER_OVERFLOW_GET(x)         (((x) & UMBOX_HCI_FRAMER_OVERFLOW_MASK) >> UMBOX_HCI_FRAMER_OVERFLOW_LSB)
-#define UMBOX_HCI_FRAMER_OVERFLOW_SET(x)         (((x) << UMBOX_HCI_FRAMER_OVERFLOW_LSB) & UMBOX_HCI_FRAMER_OVERFLOW_MASK)
-#define UMBOX_HCI_FRAMER_CONFIG_MODE_MSB         1
-#define UMBOX_HCI_FRAMER_CONFIG_MODE_LSB         0
-#define UMBOX_HCI_FRAMER_CONFIG_MODE_MASK        0x00000003
-#define UMBOX_HCI_FRAMER_CONFIG_MODE_GET(x)      (((x) & UMBOX_HCI_FRAMER_CONFIG_MODE_MASK) >> UMBOX_HCI_FRAMER_CONFIG_MODE_LSB)
-#define UMBOX_HCI_FRAMER_CONFIG_MODE_SET(x)      (((x) << UMBOX_HCI_FRAMER_CONFIG_MODE_LSB) & UMBOX_HCI_FRAMER_CONFIG_MODE_MASK)
-
-
-#ifndef __ASSEMBLER__
-
-typedef struct umbox_wlan_reg_reg_s {
-  volatile unsigned int umbox_fifo[2];
-  volatile unsigned int umbox_fifo_status;
-  volatile unsigned int umbox_dma_policy;
-  volatile unsigned int umbox0_dma_rx_descriptor_base;
-  volatile unsigned int umbox0_dma_rx_control;
-  volatile unsigned int umbox0_dma_tx_descriptor_base;
-  volatile unsigned int umbox0_dma_tx_control;
-  volatile unsigned int umbox_fifo_timeout;
-  volatile unsigned int umbox_int_status;
-  volatile unsigned int umbox_int_enable;
-  volatile unsigned int umbox_debug;
-  volatile unsigned int umbox_fifo_reset;
-  volatile unsigned int umbox_hci_framer;
-} umbox_wlan_reg_reg_t;
-
-#endif /* __ASSEMBLER__ */
-
-#endif /* _UMBOX_WLAN_REG_H_ */
diff -druN linux-2.6.39-libre/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/vmc_reg.h linux-3.0-rc7-libre/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/vmc_reg.h
--- linux-2.6.39-libre/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/vmc_reg.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/vmc_reg.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,167 +0,0 @@
-// ------------------------------------------------------------------
-// Copyright (c) 2004-2010 Atheros Corporation.  All rights reserved.
-// 
-//
-// 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.
-//
-//
-// ------------------------------------------------------------------
-//===================================================================
-// Author(s): ="Atheros"
-//===================================================================
-
-
-#ifdef WLAN_HEADERS
-
-#include "vmc_wlan_reg.h"
-
-
-#ifndef BT_HEADERS
-
-#define MC_BCAM_VALID_ADDRESS WLAN_MC_BCAM_VALID_ADDRESS
-#define MC_BCAM_VALID_OFFSET WLAN_MC_BCAM_VALID_OFFSET
-#define MC_BCAM_VALID_BIT_MSB WLAN_MC_BCAM_VALID_BIT_MSB
-#define MC_BCAM_VALID_BIT_LSB WLAN_MC_BCAM_VALID_BIT_LSB
-#define MC_BCAM_VALID_BIT_MASK WLAN_MC_BCAM_VALID_BIT_MASK
-#define MC_BCAM_VALID_BIT_GET(x) WLAN_MC_BCAM_VALID_BIT_GET(x)
-#define MC_BCAM_VALID_BIT_SET(x) WLAN_MC_BCAM_VALID_BIT_SET(x)
-#define MC_BCAM_COMPARE_ADDRESS WLAN_MC_BCAM_COMPARE_ADDRESS
-#define MC_BCAM_COMPARE_OFFSET WLAN_MC_BCAM_COMPARE_OFFSET
-#define MC_BCAM_COMPARE_KEY_MSB WLAN_MC_BCAM_COMPARE_KEY_MSB
-#define MC_BCAM_COMPARE_KEY_LSB WLAN_MC_BCAM_COMPARE_KEY_LSB
-#define MC_BCAM_COMPARE_KEY_MASK WLAN_MC_BCAM_COMPARE_KEY_MASK
-#define MC_BCAM_COMPARE_KEY_GET(x) WLAN_MC_BCAM_COMPARE_KEY_GET(x)
-#define MC_BCAM_COMPARE_KEY_SET(x) WLAN_MC_BCAM_COMPARE_KEY_SET(x)
-#define MC_BCAM_TARGET_ADDRESS WLAN_MC_BCAM_TARGET_ADDRESS
-#define MC_BCAM_TARGET_OFFSET WLAN_MC_BCAM_TARGET_OFFSET
-#define MC_BCAM_TARGET_INST_MSB WLAN_MC_BCAM_TARGET_INST_MSB
-#define MC_BCAM_TARGET_INST_LSB WLAN_MC_BCAM_TARGET_INST_LSB
-#define MC_BCAM_TARGET_INST_MASK WLAN_MC_BCAM_TARGET_INST_MASK
-#define MC_BCAM_TARGET_INST_GET(x) WLAN_MC_BCAM_TARGET_INST_GET(x)
-#define MC_BCAM_TARGET_INST_SET(x) WLAN_MC_BCAM_TARGET_INST_SET(x)
-#define APB_ADDR_ERROR_CONTROL_ADDRESS WLAN_APB_ADDR_ERROR_CONTROL_ADDRESS
-#define APB_ADDR_ERROR_CONTROL_OFFSET WLAN_APB_ADDR_ERROR_CONTROL_OFFSET
-#define APB_ADDR_ERROR_CONTROL_QUAL_ENABLE_MSB WLAN_APB_ADDR_ERROR_CONTROL_QUAL_ENABLE_MSB
-#define APB_ADDR_ERROR_CONTROL_QUAL_ENABLE_LSB WLAN_APB_ADDR_ERROR_CONTROL_QUAL_ENABLE_LSB
-#define APB_ADDR_ERROR_CONTROL_QUAL_ENABLE_MASK WLAN_APB_ADDR_ERROR_CONTROL_QUAL_ENABLE_MASK
-#define APB_ADDR_ERROR_CONTROL_QUAL_ENABLE_GET(x) WLAN_APB_ADDR_ERROR_CONTROL_QUAL_ENABLE_GET(x)
-#define APB_ADDR_ERROR_CONTROL_QUAL_ENABLE_SET(x) WLAN_APB_ADDR_ERROR_CONTROL_QUAL_ENABLE_SET(x)
-#define APB_ADDR_ERROR_CONTROL_ENABLE_MSB WLAN_APB_ADDR_ERROR_CONTROL_ENABLE_MSB
-#define APB_ADDR_ERROR_CONTROL_ENABLE_LSB WLAN_APB_ADDR_ERROR_CONTROL_ENABLE_LSB
-#define APB_ADDR_ERROR_CONTROL_ENABLE_MASK WLAN_APB_ADDR_ERROR_CONTROL_ENABLE_MASK
-#define APB_ADDR_ERROR_CONTROL_ENABLE_GET(x) WLAN_APB_ADDR_ERROR_CONTROL_ENABLE_GET(x)
-#define APB_ADDR_ERROR_CONTROL_ENABLE_SET(x) WLAN_APB_ADDR_ERROR_CONTROL_ENABLE_SET(x)
-#define APB_ADDR_ERROR_STATUS_ADDRESS WLAN_APB_ADDR_ERROR_STATUS_ADDRESS
-#define APB_ADDR_ERROR_STATUS_OFFSET WLAN_APB_ADDR_ERROR_STATUS_OFFSET
-#define APB_ADDR_ERROR_STATUS_WRITE_MSB WLAN_APB_ADDR_ERROR_STATUS_WRITE_MSB
-#define APB_ADDR_ERROR_STATUS_WRITE_LSB WLAN_APB_ADDR_ERROR_STATUS_WRITE_LSB
-#define APB_ADDR_ERROR_STATUS_WRITE_MASK WLAN_APB_ADDR_ERROR_STATUS_WRITE_MASK
-#define APB_ADDR_ERROR_STATUS_WRITE_GET(x) WLAN_APB_ADDR_ERROR_STATUS_WRITE_GET(x)
-#define APB_ADDR_ERROR_STATUS_WRITE_SET(x) WLAN_APB_ADDR_ERROR_STATUS_WRITE_SET(x)
-#define APB_ADDR_ERROR_STATUS_ADDRESS_MSB WLAN_APB_ADDR_ERROR_STATUS_ADDRESS_MSB
-#define APB_ADDR_ERROR_STATUS_ADDRESS_LSB WLAN_APB_ADDR_ERROR_STATUS_ADDRESS_LSB
-#define APB_ADDR_ERROR_STATUS_ADDRESS_MASK WLAN_APB_ADDR_ERROR_STATUS_ADDRESS_MASK
-#define APB_ADDR_ERROR_STATUS_ADDRESS_GET(x) WLAN_APB_ADDR_ERROR_STATUS_ADDRESS_GET(x)
-#define APB_ADDR_ERROR_STATUS_ADDRESS_SET(x) WLAN_APB_ADDR_ERROR_STATUS_ADDRESS_SET(x)
-#define AHB_ADDR_ERROR_CONTROL_ADDRESS WLAN_AHB_ADDR_ERROR_CONTROL_ADDRESS
-#define AHB_ADDR_ERROR_CONTROL_OFFSET WLAN_AHB_ADDR_ERROR_CONTROL_OFFSET
-#define AHB_ADDR_ERROR_CONTROL_ENABLE_MSB WLAN_AHB_ADDR_ERROR_CONTROL_ENABLE_MSB
-#define AHB_ADDR_ERROR_CONTROL_ENABLE_LSB WLAN_AHB_ADDR_ERROR_CONTROL_ENABLE_LSB
-#define AHB_ADDR_ERROR_CONTROL_ENABLE_MASK WLAN_AHB_ADDR_ERROR_CONTROL_ENABLE_MASK
-#define AHB_ADDR_ERROR_CONTROL_ENABLE_GET(x) WLAN_AHB_ADDR_ERROR_CONTROL_ENABLE_GET(x)
-#define AHB_ADDR_ERROR_CONTROL_ENABLE_SET(x) WLAN_AHB_ADDR_ERROR_CONTROL_ENABLE_SET(x)
-#define AHB_ADDR_ERROR_STATUS_ADDRESS WLAN_AHB_ADDR_ERROR_STATUS_ADDRESS
-#define AHB_ADDR_ERROR_STATUS_OFFSET WLAN_AHB_ADDR_ERROR_STATUS_OFFSET
-#define AHB_ADDR_ERROR_STATUS_MAC_MSB WLAN_AHB_ADDR_ERROR_STATUS_MAC_MSB
-#define AHB_ADDR_ERROR_STATUS_MAC_LSB WLAN_AHB_ADDR_ERROR_STATUS_MAC_LSB
-#define AHB_ADDR_ERROR_STATUS_MAC_MASK WLAN_AHB_ADDR_ERROR_STATUS_MAC_MASK
-#define AHB_ADDR_ERROR_STATUS_MAC_GET(x) WLAN_AHB_ADDR_ERROR_STATUS_MAC_GET(x)
-#define AHB_ADDR_ERROR_STATUS_MAC_SET(x) WLAN_AHB_ADDR_ERROR_STATUS_MAC_SET(x)
-#define AHB_ADDR_ERROR_STATUS_MBOX_MSB WLAN_AHB_ADDR_ERROR_STATUS_MBOX_MSB
-#define AHB_ADDR_ERROR_STATUS_MBOX_LSB WLAN_AHB_ADDR_ERROR_STATUS_MBOX_LSB
-#define AHB_ADDR_ERROR_STATUS_MBOX_MASK WLAN_AHB_ADDR_ERROR_STATUS_MBOX_MASK
-#define AHB_ADDR_ERROR_STATUS_MBOX_GET(x) WLAN_AHB_ADDR_ERROR_STATUS_MBOX_GET(x)
-#define AHB_ADDR_ERROR_STATUS_MBOX_SET(x) WLAN_AHB_ADDR_ERROR_STATUS_MBOX_SET(x)
-#define AHB_ADDR_ERROR_STATUS_ADDRESS_MSB WLAN_AHB_ADDR_ERROR_STATUS_ADDRESS_MSB
-#define AHB_ADDR_ERROR_STATUS_ADDRESS_LSB WLAN_AHB_ADDR_ERROR_STATUS_ADDRESS_LSB
-#define AHB_ADDR_ERROR_STATUS_ADDRESS_MASK WLAN_AHB_ADDR_ERROR_STATUS_ADDRESS_MASK
-#define AHB_ADDR_ERROR_STATUS_ADDRESS_GET(x) WLAN_AHB_ADDR_ERROR_STATUS_ADDRESS_GET(x)
-#define AHB_ADDR_ERROR_STATUS_ADDRESS_SET(x) WLAN_AHB_ADDR_ERROR_STATUS_ADDRESS_SET(x)
-#define BCAM_CONFLICT_ERROR_ADDRESS WLAN_BCAM_CONFLICT_ERROR_ADDRESS
-#define BCAM_CONFLICT_ERROR_OFFSET WLAN_BCAM_CONFLICT_ERROR_OFFSET
-#define BCAM_CONFLICT_ERROR_IPORT_FLAG_MSB WLAN_BCAM_CONFLICT_ERROR_IPORT_FLAG_MSB
-#define BCAM_CONFLICT_ERROR_IPORT_FLAG_LSB WLAN_BCAM_CONFLICT_ERROR_IPORT_FLAG_LSB
-#define BCAM_CONFLICT_ERROR_IPORT_FLAG_MASK WLAN_BCAM_CONFLICT_ERROR_IPORT_FLAG_MASK
-#define BCAM_CONFLICT_ERROR_IPORT_FLAG_GET(x) WLAN_BCAM_CONFLICT_ERROR_IPORT_FLAG_GET(x)
-#define BCAM_CONFLICT_ERROR_IPORT_FLAG_SET(x) WLAN_BCAM_CONFLICT_ERROR_IPORT_FLAG_SET(x)
-#define BCAM_CONFLICT_ERROR_DPORT_FLAG_MSB WLAN_BCAM_CONFLICT_ERROR_DPORT_FLAG_MSB
-#define BCAM_CONFLICT_ERROR_DPORT_FLAG_LSB WLAN_BCAM_CONFLICT_ERROR_DPORT_FLAG_LSB
-#define BCAM_CONFLICT_ERROR_DPORT_FLAG_MASK WLAN_BCAM_CONFLICT_ERROR_DPORT_FLAG_MASK
-#define BCAM_CONFLICT_ERROR_DPORT_FLAG_GET(x) WLAN_BCAM_CONFLICT_ERROR_DPORT_FLAG_GET(x)
-#define BCAM_CONFLICT_ERROR_DPORT_FLAG_SET(x) WLAN_BCAM_CONFLICT_ERROR_DPORT_FLAG_SET(x)
-#define CPU_PERF_CNT_ADDRESS WLAN_CPU_PERF_CNT_ADDRESS
-#define CPU_PERF_CNT_OFFSET WLAN_CPU_PERF_CNT_OFFSET
-#define CPU_PERF_CNT_EN_MSB WLAN_CPU_PERF_CNT_EN_MSB
-#define CPU_PERF_CNT_EN_LSB WLAN_CPU_PERF_CNT_EN_LSB
-#define CPU_PERF_CNT_EN_MASK WLAN_CPU_PERF_CNT_EN_MASK
-#define CPU_PERF_CNT_EN_GET(x) WLAN_CPU_PERF_CNT_EN_GET(x)
-#define CPU_PERF_CNT_EN_SET(x) WLAN_CPU_PERF_CNT_EN_SET(x)
-#define CPU_INST_FETCH_ADDRESS WLAN_CPU_INST_FETCH_ADDRESS
-#define CPU_INST_FETCH_OFFSET WLAN_CPU_INST_FETCH_OFFSET
-#define CPU_INST_FETCH_CNT_MSB WLAN_CPU_INST_FETCH_CNT_MSB
-#define CPU_INST_FETCH_CNT_LSB WLAN_CPU_INST_FETCH_CNT_LSB
-#define CPU_INST_FETCH_CNT_MASK WLAN_CPU_INST_FETCH_CNT_MASK
-#define CPU_INST_FETCH_CNT_GET(x) WLAN_CPU_INST_FETCH_CNT_GET(x)
-#define CPU_INST_FETCH_CNT_SET(x) WLAN_CPU_INST_FETCH_CNT_SET(x)
-#define CPU_DATA_FETCH_ADDRESS WLAN_CPU_DATA_FETCH_ADDRESS
-#define CPU_DATA_FETCH_OFFSET WLAN_CPU_DATA_FETCH_OFFSET
-#define CPU_DATA_FETCH_CNT_MSB WLAN_CPU_DATA_FETCH_CNT_MSB
-#define CPU_DATA_FETCH_CNT_LSB WLAN_CPU_DATA_FETCH_CNT_LSB
-#define CPU_DATA_FETCH_CNT_MASK WLAN_CPU_DATA_FETCH_CNT_MASK
-#define CPU_DATA_FETCH_CNT_GET(x) WLAN_CPU_DATA_FETCH_CNT_GET(x)
-#define CPU_DATA_FETCH_CNT_SET(x) WLAN_CPU_DATA_FETCH_CNT_SET(x)
-#define CPU_RAM1_CONFLICT_ADDRESS WLAN_CPU_RAM1_CONFLICT_ADDRESS
-#define CPU_RAM1_CONFLICT_OFFSET WLAN_CPU_RAM1_CONFLICT_OFFSET
-#define CPU_RAM1_CONFLICT_CNT_MSB WLAN_CPU_RAM1_CONFLICT_CNT_MSB
-#define CPU_RAM1_CONFLICT_CNT_LSB WLAN_CPU_RAM1_CONFLICT_CNT_LSB
-#define CPU_RAM1_CONFLICT_CNT_MASK WLAN_CPU_RAM1_CONFLICT_CNT_MASK
-#define CPU_RAM1_CONFLICT_CNT_GET(x) WLAN_CPU_RAM1_CONFLICT_CNT_GET(x)
-#define CPU_RAM1_CONFLICT_CNT_SET(x) WLAN_CPU_RAM1_CONFLICT_CNT_SET(x)
-#define CPU_RAM2_CONFLICT_ADDRESS WLAN_CPU_RAM2_CONFLICT_ADDRESS
-#define CPU_RAM2_CONFLICT_OFFSET WLAN_CPU_RAM2_CONFLICT_OFFSET
-#define CPU_RAM2_CONFLICT_CNT_MSB WLAN_CPU_RAM2_CONFLICT_CNT_MSB
-#define CPU_RAM2_CONFLICT_CNT_LSB WLAN_CPU_RAM2_CONFLICT_CNT_LSB
-#define CPU_RAM2_CONFLICT_CNT_MASK WLAN_CPU_RAM2_CONFLICT_CNT_MASK
-#define CPU_RAM2_CONFLICT_CNT_GET(x) WLAN_CPU_RAM2_CONFLICT_CNT_GET(x)
-#define CPU_RAM2_CONFLICT_CNT_SET(x) WLAN_CPU_RAM2_CONFLICT_CNT_SET(x)
-#define CPU_RAM3_CONFLICT_ADDRESS WLAN_CPU_RAM3_CONFLICT_ADDRESS
-#define CPU_RAM3_CONFLICT_OFFSET WLAN_CPU_RAM3_CONFLICT_OFFSET
-#define CPU_RAM3_CONFLICT_CNT_MSB WLAN_CPU_RAM3_CONFLICT_CNT_MSB
-#define CPU_RAM3_CONFLICT_CNT_LSB WLAN_CPU_RAM3_CONFLICT_CNT_LSB
-#define CPU_RAM3_CONFLICT_CNT_MASK WLAN_CPU_RAM3_CONFLICT_CNT_MASK
-#define CPU_RAM3_CONFLICT_CNT_GET(x) WLAN_CPU_RAM3_CONFLICT_CNT_GET(x)
-#define CPU_RAM3_CONFLICT_CNT_SET(x) WLAN_CPU_RAM3_CONFLICT_CNT_SET(x)
-#define CPU_RAM4_CONFLICT_ADDRESS WLAN_CPU_RAM4_CONFLICT_ADDRESS
-#define CPU_RAM4_CONFLICT_OFFSET WLAN_CPU_RAM4_CONFLICT_OFFSET
-#define CPU_RAM4_CONFLICT_CNT_MSB WLAN_CPU_RAM4_CONFLICT_CNT_MSB
-#define CPU_RAM4_CONFLICT_CNT_LSB WLAN_CPU_RAM4_CONFLICT_CNT_LSB
-#define CPU_RAM4_CONFLICT_CNT_MASK WLAN_CPU_RAM4_CONFLICT_CNT_MASK
-#define CPU_RAM4_CONFLICT_CNT_GET(x) WLAN_CPU_RAM4_CONFLICT_CNT_GET(x)
-#define CPU_RAM4_CONFLICT_CNT_SET(x) WLAN_CPU_RAM4_CONFLICT_CNT_SET(x)
-
-
-#endif
-#endif
-
-
-
diff -druN linux-2.6.39-libre/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/vmc_wlan_reg.h linux-3.0-rc7-libre/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/vmc_wlan_reg.h
--- linux-2.6.39-libre/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/vmc_wlan_reg.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/vmc_wlan_reg.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,195 +0,0 @@
-// ------------------------------------------------------------------
-// Copyright (c) 2004-2010 Atheros Corporation.  All rights reserved.
-// 
-//
-// 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.
-//
-//
-// ------------------------------------------------------------------
-//===================================================================
-// Author(s): ="Atheros"
-//===================================================================
-
-
-#ifndef _VMC_WLAN_REG_REG_H_
-#define _VMC_WLAN_REG_REG_H_
-
-#define WLAN_MC_BCAM_VALID_ADDRESS               0x00000000
-#define WLAN_MC_BCAM_VALID_OFFSET                0x00000000
-#define WLAN_MC_BCAM_VALID_BIT_MSB               0
-#define WLAN_MC_BCAM_VALID_BIT_LSB               0
-#define WLAN_MC_BCAM_VALID_BIT_MASK              0x00000001
-#define WLAN_MC_BCAM_VALID_BIT_GET(x)            (((x) & WLAN_MC_BCAM_VALID_BIT_MASK) >> WLAN_MC_BCAM_VALID_BIT_LSB)
-#define WLAN_MC_BCAM_VALID_BIT_SET(x)            (((x) << WLAN_MC_BCAM_VALID_BIT_LSB) & WLAN_MC_BCAM_VALID_BIT_MASK)
-
-#define WLAN_MC_BCAM_COMPARE_ADDRESS             0x00000200
-#define WLAN_MC_BCAM_COMPARE_OFFSET              0x00000200
-#define WLAN_MC_BCAM_COMPARE_KEY_MSB             19
-#define WLAN_MC_BCAM_COMPARE_KEY_LSB             2
-#define WLAN_MC_BCAM_COMPARE_KEY_MASK            0x000ffffc
-#define WLAN_MC_BCAM_COMPARE_KEY_GET(x)          (((x) & WLAN_MC_BCAM_COMPARE_KEY_MASK) >> WLAN_MC_BCAM_COMPARE_KEY_LSB)
-#define WLAN_MC_BCAM_COMPARE_KEY_SET(x)          (((x) << WLAN_MC_BCAM_COMPARE_KEY_LSB) & WLAN_MC_BCAM_COMPARE_KEY_MASK)
-
-#define WLAN_MC_BCAM_TARGET_ADDRESS              0x00000400
-#define WLAN_MC_BCAM_TARGET_OFFSET               0x00000400
-#define WLAN_MC_BCAM_TARGET_INST_MSB             31
-#define WLAN_MC_BCAM_TARGET_INST_LSB             0
-#define WLAN_MC_BCAM_TARGET_INST_MASK            0xffffffff
-#define WLAN_MC_BCAM_TARGET_INST_GET(x)          (((x) & WLAN_MC_BCAM_TARGET_INST_MASK) >> WLAN_MC_BCAM_TARGET_INST_LSB)
-#define WLAN_MC_BCAM_TARGET_INST_SET(x)          (((x) << WLAN_MC_BCAM_TARGET_INST_LSB) & WLAN_MC_BCAM_TARGET_INST_MASK)
-
-#define WLAN_APB_ADDR_ERROR_CONTROL_ADDRESS      0x00000600
-#define WLAN_APB_ADDR_ERROR_CONTROL_OFFSET       0x00000600
-#define WLAN_APB_ADDR_ERROR_CONTROL_QUAL_ENABLE_MSB 1
-#define WLAN_APB_ADDR_ERROR_CONTROL_QUAL_ENABLE_LSB 1
-#define WLAN_APB_ADDR_ERROR_CONTROL_QUAL_ENABLE_MASK 0x00000002
-#define WLAN_APB_ADDR_ERROR_CONTROL_QUAL_ENABLE_GET(x) (((x) & WLAN_APB_ADDR_ERROR_CONTROL_QUAL_ENABLE_MASK) >> WLAN_APB_ADDR_ERROR_CONTROL_QUAL_ENABLE_LSB)
-#define WLAN_APB_ADDR_ERROR_CONTROL_QUAL_ENABLE_SET(x) (((x) << WLAN_APB_ADDR_ERROR_CONTROL_QUAL_ENABLE_LSB) & WLAN_APB_ADDR_ERROR_CONTROL_QUAL_ENABLE_MASK)
-#define WLAN_APB_ADDR_ERROR_CONTROL_ENABLE_MSB   0
-#define WLAN_APB_ADDR_ERROR_CONTROL_ENABLE_LSB   0
-#define WLAN_APB_ADDR_ERROR_CONTROL_ENABLE_MASK  0x00000001
-#define WLAN_APB_ADDR_ERROR_CONTROL_ENABLE_GET(x) (((x) & WLAN_APB_ADDR_ERROR_CONTROL_ENABLE_MASK) >> WLAN_APB_ADDR_ERROR_CONTROL_ENABLE_LSB)
-#define WLAN_APB_ADDR_ERROR_CONTROL_ENABLE_SET(x) (((x) << WLAN_APB_ADDR_ERROR_CONTROL_ENABLE_LSB) & WLAN_APB_ADDR_ERROR_CONTROL_ENABLE_MASK)
-
-#define WLAN_APB_ADDR_ERROR_STATUS_ADDRESS       0x00000604
-#define WLAN_APB_ADDR_ERROR_STATUS_OFFSET        0x00000604
-#define WLAN_APB_ADDR_ERROR_STATUS_WRITE_MSB     25
-#define WLAN_APB_ADDR_ERROR_STATUS_WRITE_LSB     25
-#define WLAN_APB_ADDR_ERROR_STATUS_WRITE_MASK    0x02000000
-#define WLAN_APB_ADDR_ERROR_STATUS_WRITE_GET(x)  (((x) & WLAN_APB_ADDR_ERROR_STATUS_WRITE_MASK) >> WLAN_APB_ADDR_ERROR_STATUS_WRITE_LSB)
-#define WLAN_APB_ADDR_ERROR_STATUS_WRITE_SET(x)  (((x) << WLAN_APB_ADDR_ERROR_STATUS_WRITE_LSB) & WLAN_APB_ADDR_ERROR_STATUS_WRITE_MASK)
-#define WLAN_APB_ADDR_ERROR_STATUS_ADDRESS_MSB   24
-#define WLAN_APB_ADDR_ERROR_STATUS_ADDRESS_LSB   0
-#define WLAN_APB_ADDR_ERROR_STATUS_ADDRESS_MASK  0x01ffffff
-#define WLAN_APB_ADDR_ERROR_STATUS_ADDRESS_GET(x) (((x) & WLAN_APB_ADDR_ERROR_STATUS_ADDRESS_MASK) >> WLAN_APB_ADDR_ERROR_STATUS_ADDRESS_LSB)
-#define WLAN_APB_ADDR_ERROR_STATUS_ADDRESS_SET(x) (((x) << WLAN_APB_ADDR_ERROR_STATUS_ADDRESS_LSB) & WLAN_APB_ADDR_ERROR_STATUS_ADDRESS_MASK)
-
-#define WLAN_AHB_ADDR_ERROR_CONTROL_ADDRESS      0x00000608
-#define WLAN_AHB_ADDR_ERROR_CONTROL_OFFSET       0x00000608
-#define WLAN_AHB_ADDR_ERROR_CONTROL_ENABLE_MSB   0
-#define WLAN_AHB_ADDR_ERROR_CONTROL_ENABLE_LSB   0
-#define WLAN_AHB_ADDR_ERROR_CONTROL_ENABLE_MASK  0x00000001
-#define WLAN_AHB_ADDR_ERROR_CONTROL_ENABLE_GET(x) (((x) & WLAN_AHB_ADDR_ERROR_CONTROL_ENABLE_MASK) >> WLAN_AHB_ADDR_ERROR_CONTROL_ENABLE_LSB)
-#define WLAN_AHB_ADDR_ERROR_CONTROL_ENABLE_SET(x) (((x) << WLAN_AHB_ADDR_ERROR_CONTROL_ENABLE_LSB) & WLAN_AHB_ADDR_ERROR_CONTROL_ENABLE_MASK)
-
-#define WLAN_AHB_ADDR_ERROR_STATUS_ADDRESS       0x0000060c
-#define WLAN_AHB_ADDR_ERROR_STATUS_OFFSET        0x0000060c
-#define WLAN_AHB_ADDR_ERROR_STATUS_MAC_MSB       31
-#define WLAN_AHB_ADDR_ERROR_STATUS_MAC_LSB       31
-#define WLAN_AHB_ADDR_ERROR_STATUS_MAC_MASK      0x80000000
-#define WLAN_AHB_ADDR_ERROR_STATUS_MAC_GET(x)    (((x) & WLAN_AHB_ADDR_ERROR_STATUS_MAC_MASK) >> WLAN_AHB_ADDR_ERROR_STATUS_MAC_LSB)
-#define WLAN_AHB_ADDR_ERROR_STATUS_MAC_SET(x)    (((x) << WLAN_AHB_ADDR_ERROR_STATUS_MAC_LSB) & WLAN_AHB_ADDR_ERROR_STATUS_MAC_MASK)
-#define WLAN_AHB_ADDR_ERROR_STATUS_MBOX_MSB      30
-#define WLAN_AHB_ADDR_ERROR_STATUS_MBOX_LSB      30
-#define WLAN_AHB_ADDR_ERROR_STATUS_MBOX_MASK     0x40000000
-#define WLAN_AHB_ADDR_ERROR_STATUS_MBOX_GET(x)   (((x) & WLAN_AHB_ADDR_ERROR_STATUS_MBOX_MASK) >> WLAN_AHB_ADDR_ERROR_STATUS_MBOX_LSB)
-#define WLAN_AHB_ADDR_ERROR_STATUS_MBOX_SET(x)   (((x) << WLAN_AHB_ADDR_ERROR_STATUS_MBOX_LSB) & WLAN_AHB_ADDR_ERROR_STATUS_MBOX_MASK)
-#define WLAN_AHB_ADDR_ERROR_STATUS_ADDRESS_MSB   23
-#define WLAN_AHB_ADDR_ERROR_STATUS_ADDRESS_LSB   0
-#define WLAN_AHB_ADDR_ERROR_STATUS_ADDRESS_MASK  0x00ffffff
-#define WLAN_AHB_ADDR_ERROR_STATUS_ADDRESS_GET(x) (((x) & WLAN_AHB_ADDR_ERROR_STATUS_ADDRESS_MASK) >> WLAN_AHB_ADDR_ERROR_STATUS_ADDRESS_LSB)
-#define WLAN_AHB_ADDR_ERROR_STATUS_ADDRESS_SET(x) (((x) << WLAN_AHB_ADDR_ERROR_STATUS_ADDRESS_LSB) & WLAN_AHB_ADDR_ERROR_STATUS_ADDRESS_MASK)
-
-#define WLAN_BCAM_CONFLICT_ERROR_ADDRESS         0x00000610
-#define WLAN_BCAM_CONFLICT_ERROR_OFFSET          0x00000610
-#define WLAN_BCAM_CONFLICT_ERROR_IPORT_FLAG_MSB  1
-#define WLAN_BCAM_CONFLICT_ERROR_IPORT_FLAG_LSB  1
-#define WLAN_BCAM_CONFLICT_ERROR_IPORT_FLAG_MASK 0x00000002
-#define WLAN_BCAM_CONFLICT_ERROR_IPORT_FLAG_GET(x) (((x) & WLAN_BCAM_CONFLICT_ERROR_IPORT_FLAG_MASK) >> WLAN_BCAM_CONFLICT_ERROR_IPORT_FLAG_LSB)
-#define WLAN_BCAM_CONFLICT_ERROR_IPORT_FLAG_SET(x) (((x) << WLAN_BCAM_CONFLICT_ERROR_IPORT_FLAG_LSB) & WLAN_BCAM_CONFLICT_ERROR_IPORT_FLAG_MASK)
-#define WLAN_BCAM_CONFLICT_ERROR_DPORT_FLAG_MSB  0
-#define WLAN_BCAM_CONFLICT_ERROR_DPORT_FLAG_LSB  0
-#define WLAN_BCAM_CONFLICT_ERROR_DPORT_FLAG_MASK 0x00000001
-#define WLAN_BCAM_CONFLICT_ERROR_DPORT_FLAG_GET(x) (((x) & WLAN_BCAM_CONFLICT_ERROR_DPORT_FLAG_MASK) >> WLAN_BCAM_CONFLICT_ERROR_DPORT_FLAG_LSB)
-#define WLAN_BCAM_CONFLICT_ERROR_DPORT_FLAG_SET(x) (((x) << WLAN_BCAM_CONFLICT_ERROR_DPORT_FLAG_LSB) & WLAN_BCAM_CONFLICT_ERROR_DPORT_FLAG_MASK)
-
-#define WLAN_CPU_PERF_CNT_ADDRESS                0x00000614
-#define WLAN_CPU_PERF_CNT_OFFSET                 0x00000614
-#define WLAN_CPU_PERF_CNT_EN_MSB                 0
-#define WLAN_CPU_PERF_CNT_EN_LSB                 0
-#define WLAN_CPU_PERF_CNT_EN_MASK                0x00000001
-#define WLAN_CPU_PERF_CNT_EN_GET(x)              (((x) & WLAN_CPU_PERF_CNT_EN_MASK) >> WLAN_CPU_PERF_CNT_EN_LSB)
-#define WLAN_CPU_PERF_CNT_EN_SET(x)              (((x) << WLAN_CPU_PERF_CNT_EN_LSB) & WLAN_CPU_PERF_CNT_EN_MASK)
-
-#define WLAN_CPU_INST_FETCH_ADDRESS              0x00000618
-#define WLAN_CPU_INST_FETCH_OFFSET               0x00000618
-#define WLAN_CPU_INST_FETCH_CNT_MSB              31
-#define WLAN_CPU_INST_FETCH_CNT_LSB              0
-#define WLAN_CPU_INST_FETCH_CNT_MASK             0xffffffff
-#define WLAN_CPU_INST_FETCH_CNT_GET(x)           (((x) & WLAN_CPU_INST_FETCH_CNT_MASK) >> WLAN_CPU_INST_FETCH_CNT_LSB)
-#define WLAN_CPU_INST_FETCH_CNT_SET(x)           (((x) << WLAN_CPU_INST_FETCH_CNT_LSB) & WLAN_CPU_INST_FETCH_CNT_MASK)
-
-#define WLAN_CPU_DATA_FETCH_ADDRESS              0x0000061c
-#define WLAN_CPU_DATA_FETCH_OFFSET               0x0000061c
-#define WLAN_CPU_DATA_FETCH_CNT_MSB              31
-#define WLAN_CPU_DATA_FETCH_CNT_LSB              0
-#define WLAN_CPU_DATA_FETCH_CNT_MASK             0xffffffff
-#define WLAN_CPU_DATA_FETCH_CNT_GET(x)           (((x) & WLAN_CPU_DATA_FETCH_CNT_MASK) >> WLAN_CPU_DATA_FETCH_CNT_LSB)
-#define WLAN_CPU_DATA_FETCH_CNT_SET(x)           (((x) << WLAN_CPU_DATA_FETCH_CNT_LSB) & WLAN_CPU_DATA_FETCH_CNT_MASK)
-
-#define WLAN_CPU_RAM1_CONFLICT_ADDRESS           0x00000620
-#define WLAN_CPU_RAM1_CONFLICT_OFFSET            0x00000620
-#define WLAN_CPU_RAM1_CONFLICT_CNT_MSB           11
-#define WLAN_CPU_RAM1_CONFLICT_CNT_LSB           0
-#define WLAN_CPU_RAM1_CONFLICT_CNT_MASK          0x00000fff
-#define WLAN_CPU_RAM1_CONFLICT_CNT_GET(x)        (((x) & WLAN_CPU_RAM1_CONFLICT_CNT_MASK) >> WLAN_CPU_RAM1_CONFLICT_CNT_LSB)
-#define WLAN_CPU_RAM1_CONFLICT_CNT_SET(x)        (((x) << WLAN_CPU_RAM1_CONFLICT_CNT_LSB) & WLAN_CPU_RAM1_CONFLICT_CNT_MASK)
-
-#define WLAN_CPU_RAM2_CONFLICT_ADDRESS           0x00000624
-#define WLAN_CPU_RAM2_CONFLICT_OFFSET            0x00000624
-#define WLAN_CPU_RAM2_CONFLICT_CNT_MSB           11
-#define WLAN_CPU_RAM2_CONFLICT_CNT_LSB           0
-#define WLAN_CPU_RAM2_CONFLICT_CNT_MASK          0x00000fff
-#define WLAN_CPU_RAM2_CONFLICT_CNT_GET(x)        (((x) & WLAN_CPU_RAM2_CONFLICT_CNT_MASK) >> WLAN_CPU_RAM2_CONFLICT_CNT_LSB)
-#define WLAN_CPU_RAM2_CONFLICT_CNT_SET(x)        (((x) << WLAN_CPU_RAM2_CONFLICT_CNT_LSB) & WLAN_CPU_RAM2_CONFLICT_CNT_MASK)
-
-#define WLAN_CPU_RAM3_CONFLICT_ADDRESS           0x00000628
-#define WLAN_CPU_RAM3_CONFLICT_OFFSET            0x00000628
-#define WLAN_CPU_RAM3_CONFLICT_CNT_MSB           11
-#define WLAN_CPU_RAM3_CONFLICT_CNT_LSB           0
-#define WLAN_CPU_RAM3_CONFLICT_CNT_MASK          0x00000fff
-#define WLAN_CPU_RAM3_CONFLICT_CNT_GET(x)        (((x) & WLAN_CPU_RAM3_CONFLICT_CNT_MASK) >> WLAN_CPU_RAM3_CONFLICT_CNT_LSB)
-#define WLAN_CPU_RAM3_CONFLICT_CNT_SET(x)        (((x) << WLAN_CPU_RAM3_CONFLICT_CNT_LSB) & WLAN_CPU_RAM3_CONFLICT_CNT_MASK)
-
-#define WLAN_CPU_RAM4_CONFLICT_ADDRESS           0x0000062c
-#define WLAN_CPU_RAM4_CONFLICT_OFFSET            0x0000062c
-#define WLAN_CPU_RAM4_CONFLICT_CNT_MSB           11
-#define WLAN_CPU_RAM4_CONFLICT_CNT_LSB           0
-#define WLAN_CPU_RAM4_CONFLICT_CNT_MASK          0x00000fff
-#define WLAN_CPU_RAM4_CONFLICT_CNT_GET(x)        (((x) & WLAN_CPU_RAM4_CONFLICT_CNT_MASK) >> WLAN_CPU_RAM4_CONFLICT_CNT_LSB)
-#define WLAN_CPU_RAM4_CONFLICT_CNT_SET(x)        (((x) << WLAN_CPU_RAM4_CONFLICT_CNT_LSB) & WLAN_CPU_RAM4_CONFLICT_CNT_MASK)
-
-
-#ifndef __ASSEMBLER__
-
-typedef struct vmc_wlan_reg_reg_s {
-  volatile unsigned int wlan_mc_bcam_valid[128];
-  volatile unsigned int wlan_mc_bcam_compare[128];
-  volatile unsigned int wlan_mc_bcam_target[128];
-  volatile unsigned int wlan_apb_addr_error_control;
-  volatile unsigned int wlan_apb_addr_error_status;
-  volatile unsigned int wlan_ahb_addr_error_control;
-  volatile unsigned int wlan_ahb_addr_error_status;
-  volatile unsigned int wlan_bcam_conflict_error;
-  volatile unsigned int wlan_cpu_perf_cnt;
-  volatile unsigned int wlan_cpu_inst_fetch;
-  volatile unsigned int wlan_cpu_data_fetch;
-  volatile unsigned int wlan_cpu_ram1_conflict;
-  volatile unsigned int wlan_cpu_ram2_conflict;
-  volatile unsigned int wlan_cpu_ram3_conflict;
-  volatile unsigned int wlan_cpu_ram4_conflict;
-} vmc_wlan_reg_reg_t;
-
-#endif /* __ASSEMBLER__ */
-
-#endif /* _VMC_WLAN_REG_H_ */
diff -druN linux-2.6.39-libre/drivers/staging/ath6kl/include/common/bmi_msg.h linux-3.0-rc7-libre/drivers/staging/ath6kl/include/common/bmi_msg.h
--- linux-2.6.39-libre/drivers/staging/ath6kl/include/common/bmi_msg.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/ath6kl/include/common/bmi_msg.h	2011-07-11 19:51:52.000000000 -0400
@@ -22,10 +22,6 @@
 #ifndef __BMI_MSG_H__
 #define __BMI_MSG_H__
 
-#ifndef ATH_TARGET
-#include "athstartpack.h"
-#endif
-
 /*
  * Bootloader Messaging Interface (BMI)
  *
@@ -234,8 +230,4 @@
          * Note: Not supported on all versions of ROM firmware.
          */
 
-#ifndef ATH_TARGET
-#include "athendpack.h"
-#endif
-
 #endif /* __BMI_MSG_H__ */
diff -druN linux-2.6.39-libre/drivers/staging/ath6kl/include/common/btcoexGpio.h linux-3.0-rc7-libre/drivers/staging/ath6kl/include/common/btcoexGpio.h
--- linux-2.6.39-libre/drivers/staging/ath6kl/include/common/btcoexGpio.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/ath6kl/include/common/btcoexGpio.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,86 +0,0 @@
-// Copyright (c) 2010 Atheros Communications Inc.
-// All rights reserved.
-// 
-//
-// Permission to use, copy, modify, and/or distribute this software for any
-// purpose with or without fee is hereby granted, provided that the above
-// copyright notice and this permission notice appear in all copies.
-//
-// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
-// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-//
-//
-
-#ifndef BTCOEX_GPIO_H_
-#define BTCOEX_GPIO_H_
-
-
-
-#ifdef FPGA
-#define GPIO_A      (15)
-#define GPIO_B      (16)
-#define GPIO_C      (17)
-#define GPIO_D      (18)
-#define GPIO_E      (19)
-#define GPIO_F      (21)
-#define GPIO_G      (21)
-#else
-#define GPIO_A      (0)
-#define GPIO_B      (5)
-#define GPIO_C      (6)
-#define GPIO_D      (7)
-#define GPIO_E      (7)
-#define GPIO_F      (7)
-#define GPIO_G      (7)
-#endif
-
-
-
-
-
-#define GPIO_DEBUG_WORD_1                                 (1<<GPIO_A)
-#define GPIO_DEBUG_WORD_2                   (1<<GPIO_B)
-#define GPIO_DEBUG_WORD_3                  ((1<<GPIO_B) | (1<<GPIO_A))
-#define GPIO_DEBUG_WORD_4     (1<<GPIO_C)
-#define GPIO_DEBUG_WORD_5    ((1<<GPIO_C) |               (1<<GPIO_A))
-#define GPIO_DEBUG_WORD_6    ((1<<GPIO_C) | (1<<GPIO_B))
-#define GPIO_DEBUG_WORD_7    ((1<<GPIO_C) | (1<<GPIO_B) | (1<<GPIO_A))
-
-#define GPIO_DEBUG_WORD_8     (1<<GPIO_D)
-#define GPIO_DEBUG_WORD_9    ((1<<GPIO_D) | GPIO_DEBUG_WORD_1)
-#define GPIO_DEBUG_WORD_10   ((1<<GPIO_D) | GPIO_DEBUG_WORD_2)
-#define GPIO_DEBUG_WORD_11   ((1<<GPIO_D) | GPIO_DEBUG_WORD_3)
-#define GPIO_DEBUG_WORD_12   ((1<<GPIO_D) | GPIO_DEBUG_WORD_4)
-#define GPIO_DEBUG_WORD_13   ((1<<GPIO_D) | GPIO_DEBUG_WORD_5)
-#define GPIO_DEBUG_WORD_14   ((1<<GPIO_D) | GPIO_DEBUG_WORD_6)
-#define GPIO_DEBUG_WORD_15   ((1<<GPIO_D) | GPIO_DEBUG_WORD_7)
-
-#define GPIO_DEBUG_WORD_16   (1<<GPIO_E)
-#define GPIO_DEBUG_WORD_17    ((1<<GPIO_E) | GPIO_DEBUG_WORD_1)
-#define GPIO_DEBUG_WORD_18   ((1<<GPIO_E) | GPIO_DEBUG_WORD_2)
-#define GPIO_DEBUG_WORD_19   ((1<<GPIO_E) | GPIO_DEBUG_WORD_3)
-#define GPIO_DEBUG_WORD_20   ((1<<GPIO_E) | GPIO_DEBUG_WORD_4)
-#define GPIO_DEBUG_WORD_21   ((1<<GPIO_E) | GPIO_DEBUG_WORD_5)
-#define GPIO_DEBUG_WORD_22   ((1<<GPIO_E) | GPIO_DEBUG_WORD_6)
-#define GPIO_DEBUG_WORD_23   ((1<<GPIO_E) | GPIO_DEBUG_WORD_7)
-
-
-
-extern void btcoexDbgPulseWord(u32 gpioPinMask);
-extern void btcoexDbgPulse(u32 pin);
-
-#ifdef CONFIG_BTCOEX_ENABLE_GPIO_DEBUG
-#define BTCOEX_DBG_PULSE_WORD(gpioPinMask)  (btcoexDbgPulseWord(gpioPinMask))
-#define BTCOEX_DBG_PULSE(pin)               (btcoexDbgPulse(pin))
-#else
-#define BTCOEX_DBG_PULSE_WORD(gpioPinMask)
-#define BTCOEX_DBG_PULSE(pin)
-
-#endif
-#endif
-
diff -druN linux-2.6.39-libre/drivers/staging/ath6kl/include/common/dbglog.h linux-3.0-rc7-libre/drivers/staging/ath6kl/include/common/dbglog.h
--- linux-2.6.39-libre/drivers/staging/ath6kl/include/common/dbglog.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/ath6kl/include/common/dbglog.h	2011-07-11 19:51:52.000000000 -0400
@@ -24,10 +24,6 @@
 #ifndef _DBGLOG_H_
 #define _DBGLOG_H_
 
-#ifndef ATH_TARGET
-#include "athstartpack.h"
-#endif
-
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -127,8 +123,4 @@
 }
 #endif
 
-#ifndef ATH_TARGET
-#include "athendpack.h"
-#endif
-
 #endif /* _DBGLOG_H_ */
diff -druN linux-2.6.39-libre/drivers/staging/ath6kl/include/common/dsetid.h linux-3.0-rc7-libre/drivers/staging/ath6kl/include/common/dsetid.h
--- linux-2.6.39-libre/drivers/staging/ath6kl/include/common/dsetid.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/ath6kl/include/common/dsetid.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,134 +0,0 @@
-//------------------------------------------------------------------------------
-// <copyright file="dsetid.h" company="Atheros">
-//    Copyright (c) 2004-2010 Atheros Corporation.  All rights reserved.
-// 
-//
-// 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.
-//
-//
-//------------------------------------------------------------------------------
-//==============================================================================
-// Author(s): ="Atheros"
-//==============================================================================
-
-
-#ifndef __DSETID_H__
-#define __DSETID_H__
-
-#ifndef ATH_TARGET
-#include "athstartpack.h"
-#endif
-
-/* Well-known DataSet IDs */
-#define DSETID_UNUSED                     0x00000000
-#define DSETID_BOARD_DATA                 0x00000001 /* Cal and board data */
-#define DSETID_REGDB                      0x00000002 /* Regulatory Database */
-#define DSETID_POWER_CONTROL              0x00000003 /* TX Pwr Lim & Ant Gain */
-#define DSETID_USER_CONFIG                0x00000004 /* User Configuration */
-
-#define DSETID_ANALOG_CONTROL_DATA_START  0x00000005
-#define DSETID_ANALOG_CONTROL_DATA_END    0x00000025
-/*
- * Get DSETID for various reference clock speeds.
- * For each speed there are three DataSets that correspond
- * to the three columns of bank6 data (addr, 11a, 11b/g).
- * This macro returns the dsetid of the first of those
- * three DataSets.
- */
-#define ANALOG_CONTROL_DATA_DSETID(refclk) \
-        (DSETID_ANALOG_CONTROL_DATA_START + 3*refclk)
-
-/*
- * There are TWO STARTUP_PATCH DataSets.
- * DSETID_STARTUP_PATCH is historical, and was applied before BMI on
- * earlier systems.  On AR6002, it is applied after BMI, just like
- * DSETID_STARTUP_PATCH2.
- */
-#define DSETID_STARTUP_PATCH              0x00000026
-#define DSETID_GPIO_CONFIG_PATCH          0x00000027
-#define DSETID_WLANREGS                   0x00000028 /* override wlan regs */
-#define DSETID_STARTUP_PATCH2             0x00000029
-
-#define DSETID_WOW_CONFIG                 0x00000090 /* WoW Configuration */
-
-/* Add WHAL_INI_DATA_ID to DSETID_INI_DATA for a specific WHAL INI table. */
-#define DSETID_INI_DATA                   0x00000100
-/* Reserved for WHAL INI Tables: 0x100..0x11f */
-#define DSETID_INI_DATA_END               0x0000011f
-
-#define DSETID_VENDOR_START               0x00010000 /* Vendor-defined DataSets */
-
-#define DSETID_INDEX_END                  0xfffffffe /* Reserved to indicate the
-                                                        end of a memory-based
-                                                        DataSet Index */
-#define DSETID_INDEX_FREE                 0xffffffff /* An unused index entry */
-
-/* 
- * PATCH DataSet format:
- * A list of patches, terminated by a patch with
- * address=PATCH_END.
- *
- * This allows for patches to be stored in flash.
- */
-PREPACK struct patch_s {
-    u32 *address;
-    u32 data;
-} POSTPACK ;
-
-/*
- * Skip some patches.  Can be used to erase a single patch in a
- * patch DataSet without having to re-write the DataSet.  May
- * also be used to embed information for use by subsequent
- * patch code.  The "data" in a PATCH_SKIP tells how many
- * bytes of length "patch_s" to skip.
- */
-#define PATCH_SKIP      ((u32 *)0x00000000)
-
-/*
- * Execute code at the address specified by "data".
- * The address of the patch structure is passed as
- * the one parameter.
- */
-#define PATCH_CODE_ABS  ((u32 *)0x00000001)
-
-/*
- * Same as PATCH_CODE_ABS, but treat "data" as an
- * offset from the start of the patch word.
- */
-#define PATCH_CODE_REL  ((u32 *)0x00000002)
-
-/* Mark the end of this patch DataSet. */
-#define PATCH_END       ((u32 *)0xffffffff)
-
-/*
- * A DataSet which contains a Binary Patch to some other DataSet
- * uses the original dsetid with the DSETID_BPATCH_FLAG bit set.
- * Such a BPatch DataSet consists of BPatch metadata followed by
- * the bdiff bytes.  BPatch metadata consists of a single 32-bit
- * word that contains the size of the BPatched final image.
- *
- * To create a suitable bdiff DataSet, use bdiff in host/tools/bdiff
- * to create "diffs":
- *  bdiff -q -O -nooldmd5 -nonewmd5 -d ORIGfile NEWfile diffs
- * Then add BPatch metadata to the start of "diffs".
- *
- * NB: There are some implementation-induced restrictions
- * on which DataSets can be BPatched.
- */
-#define DSETID_BPATCH_FLAG                0x80000000
-
-#ifndef ATH_TARGET
-#include "athendpack.h"
-#endif
-
-#endif /* __DSETID_H__ */
diff -druN linux-2.6.39-libre/drivers/staging/ath6kl/include/common/dset_internal.h linux-3.0-rc7-libre/drivers/staging/ath6kl/include/common/dset_internal.h
--- linux-2.6.39-libre/drivers/staging/ath6kl/include/common/dset_internal.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/ath6kl/include/common/dset_internal.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,63 +0,0 @@
-//------------------------------------------------------------------------------
-// <copyright file="dset_internal.h" company="Atheros">
-//    Copyright (c) 2004-2010 Atheros Corporation.  All rights reserved.
-// 
-//
-// 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.
-//
-//
-//------------------------------------------------------------------------------
-//==============================================================================
-// Author(s): ="Atheros"
-//==============================================================================
-
-
-#ifndef __DSET_INTERNAL_H__
-#define __DSET_INTERNAL_H__
-
-#ifndef ATH_TARGET
-#include "athstartpack.h"
-#endif
-
-/*
- * Internal dset definitions, common for DataSet layer.
- */
-
-#define DSET_TYPE_STANDARD      0
-#define DSET_TYPE_BPATCHED      1
-#define DSET_TYPE_COMPRESSED    2
-
-/* Dataset descriptor */
-
-typedef PREPACK struct dset_descriptor_s {
-  struct dset_descriptor_s  *next;         /* List link. NULL only at the last
-                                              descriptor */
-  u16 id;           /* Dset ID */
-  u16 size;         /* Dset size. */
-  void                      *DataPtr;      /* Pointer to raw data for standard
-                                              DataSet or pointer to original
-                                              dset_descriptor for patched
-                                              DataSet */
-  u32 data_type;    /* DSET_TYPE_*, above */
-
-  void                      *AuxPtr;       /* Additional data that might
-                                              needed for data_type. For
-                                              example, pointer to patch
-                                              Dataset descriptor for BPatch. */
-} POSTPACK dset_descriptor_t;
-
-#ifndef ATH_TARGET
-#include "athendpack.h"
-#endif
-
-#endif /* __DSET_INTERNAL_H__ */
diff -druN linux-2.6.39-libre/drivers/staging/ath6kl/include/common/epping_test.h linux-3.0-rc7-libre/drivers/staging/ath6kl/include/common/epping_test.h
--- linux-2.6.39-libre/drivers/staging/ath6kl/include/common/epping_test.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/ath6kl/include/common/epping_test.h	2011-07-11 19:51:52.000000000 -0400
@@ -25,10 +25,6 @@
 #ifndef EPPING_TEST_H_
 #define EPPING_TEST_H_
 
-#ifndef ATH_TARGET
-#include "athstartpack.h"
-#endif
-
     /* alignment to 4-bytes */
 #define EPPING_ALIGNMENT_PAD  (((sizeof(struct htc_frame_hdr) + 3) & (~0x3)) - sizeof(struct htc_frame_hdr))
 
@@ -112,9 +108,4 @@
 #define HCI_TRANSPORT_STREAM_NUM  16  /* this number is higher than the define WMM AC classes so we
                                          can use this to distinguish packets */
 
-#ifndef ATH_TARGET
-#include "athendpack.h"
-#endif
-    
-    
 #endif /*EPPING_TEST_H_*/
diff -druN linux-2.6.39-libre/drivers/staging/ath6kl/include/common/gmboxif.h linux-3.0-rc7-libre/drivers/staging/ath6kl/include/common/gmboxif.h
--- linux-2.6.39-libre/drivers/staging/ath6kl/include/common/gmboxif.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/ath6kl/include/common/gmboxif.h	2011-07-11 19:51:52.000000000 -0400
@@ -23,10 +23,6 @@
 #ifndef __GMBOXIF_H__
 #define __GMBOXIF_H__
 
-#ifndef ATH_TARGET
-#include "athstartpack.h"
-#endif
-
 /* GMBOX interface definitions */
     
 #define AR6K_GMBOX_CREDIT_COUNTER       1   /* we use credit counter 1 to track credits */
@@ -70,9 +66,5 @@
 #define MBOX_SIG_HCI_BRIDGE_PWR_SAV_OFF   4
 
 
-#ifndef ATH_TARGET
-#include "athendpack.h"
-#endif
-
 #endif /* __GMBOXIF_H__ */
 
diff -druN linux-2.6.39-libre/drivers/staging/ath6kl/include/common/gpio.h linux-3.0-rc7-libre/drivers/staging/ath6kl/include/common/gpio.h
--- linux-2.6.39-libre/drivers/staging/ath6kl/include/common/gpio.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/ath6kl/include/common/gpio.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,45 +0,0 @@
-//------------------------------------------------------------------------------
-// Copyright (c) 2005-2010 Atheros Corporation.  All rights reserved.
-//
-//
-// 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.
-//
-//
-//
-// Author(s): ="Atheros"
-//------------------------------------------------------------------------------
-
-#define AR6001_GPIO_PIN_COUNT 18
-#define AR6002_GPIO_PIN_COUNT 18
-#define AR6003_GPIO_PIN_COUNT 28
-
-/*
- * Possible values for WMIX_GPIO_SET_REGISTER_CMDID.
- * NB: These match hardware order, so that addresses can
- * easily be computed.
- */
-#define GPIO_ID_OUT             0x00000000
-#define GPIO_ID_OUT_W1TS        0x00000001
-#define GPIO_ID_OUT_W1TC        0x00000002
-#define GPIO_ID_ENABLE          0x00000003
-#define GPIO_ID_ENABLE_W1TS     0x00000004
-#define GPIO_ID_ENABLE_W1TC     0x00000005
-#define GPIO_ID_IN              0x00000006
-#define GPIO_ID_STATUS          0x00000007
-#define GPIO_ID_STATUS_W1TS     0x00000008
-#define GPIO_ID_STATUS_W1TC     0x00000009
-#define GPIO_ID_PIN0            0x0000000a
-#define GPIO_ID_PIN(n)          (GPIO_ID_PIN0+(n))
-
-#define GPIO_LAST_REGISTER_ID   GPIO_ID_PIN(17)
-#define GPIO_ID_NONE            0xffffffff
diff -druN linux-2.6.39-libre/drivers/staging/ath6kl/include/common/gpio_reg.h linux-3.0-rc7-libre/drivers/staging/ath6kl/include/common/gpio_reg.h
--- linux-2.6.39-libre/drivers/staging/ath6kl/include/common/gpio_reg.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/staging/ath6kl/include/common/gpio_reg.h	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,9 @@
+#ifndef _GPIO_REG_REG_H_
+#define _GPIO_REG_REG_H_
+
+#define GPIO_PIN10_ADDRESS                       0x00000050
+#define GPIO_PIN11_ADDRESS                       0x00000054
+#define GPIO_PIN12_ADDRESS                       0x00000058
+#define GPIO_PIN13_ADDRESS                       0x0000005c
+
+#endif /* _GPIO_REG_H_ */
diff -druN linux-2.6.39-libre/drivers/staging/ath6kl/include/common/htc.h linux-3.0-rc7-libre/drivers/staging/ath6kl/include/common/htc.h
--- linux-2.6.39-libre/drivers/staging/ath6kl/include/common/htc.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/ath6kl/include/common/htc.h	2011-07-11 19:51:52.000000000 -0400
@@ -24,10 +24,6 @@
 #ifndef __HTC_H__
 #define __HTC_H__
 
-#ifndef ATH_TARGET
-#include "athstartpack.h"
-#endif
-
 #define A_OFFSETOF(type,field) (unsigned long)(&(((type *)NULL)->field))
 
 #define ASSEMBLE_UNALIGNED_UINT16(p,highbyte,lowbyte) \
@@ -227,10 +223,5 @@
     u8 LookAhead[4];     /* 4 byte lookahead */
 } POSTPACK HTC_BUNDLED_LOOKAHEAD_REPORT;
 
-#ifndef ATH_TARGET
-#include "athendpack.h"
-#endif
-
-
 #endif /* __HTC_H__ */
 
diff -druN linux-2.6.39-libre/drivers/staging/ath6kl/include/common/ini_dset.h linux-3.0-rc7-libre/drivers/staging/ath6kl/include/common/ini_dset.h
--- linux-2.6.39-libre/drivers/staging/ath6kl/include/common/ini_dset.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/ath6kl/include/common/ini_dset.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,82 +0,0 @@
-//------------------------------------------------------------------------------
-// Copyright (c) 2004-2010 Atheros Corporation.  All rights reserved.
-//
-//
-// 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.
-//
-//
-//
-// Author(s): ="Atheros"
-//------------------------------------------------------------------------------
-
-#ifndef _INI_DSET_H_
-#define _INI_DSET_H_
-
-/*
- * Each of these represents a WHAL INI table, which consists
- * of an "address column" followed by 1 or more "value columns".
- *
- * Software uses the base WHAL_INI_DATA_ID+column to access a
- * DataSet that holds a particular column of data.
- */
-typedef enum {
-#if defined(AR6002_REV4) || defined(AR6003)
-/* Add these definitions for compatibility  */
-#define WHAL_INI_DATA_ID_BB_RFGAIN_LNA1 WHAL_INI_DATA_ID_BB_RFGAIN
-#define WHAL_INI_DATA_ID_BB_RFGAIN_LNA2 WHAL_INI_DATA_ID_BB_RFGAIN
-    WHAL_INI_DATA_ID_NULL               =0,
-    WHAL_INI_DATA_ID_MODE_SPECIFIC      =1,  /* 2,3,4,5 */
-    WHAL_INI_DATA_ID_COMMON             =6,  /* 7 */
-    WHAL_INI_DATA_ID_BB_RFGAIN          =8,  /* 9,10 */
-#ifdef FPGA
-    WHAL_INI_DATA_ID_ANALOG_BANK0       =11, /* 12 */
-    WHAL_INI_DATA_ID_ANALOG_BANK1       =13, /* 14 */
-    WHAL_INI_DATA_ID_ANALOG_BANK2       =15, /* 16 */
-    WHAL_INI_DATA_ID_ANALOG_BANK3       =17, /* 18, 19 */
-    WHAL_INI_DATA_ID_ANALOG_BANK6       =20, /* 21,22 */
-    WHAL_INI_DATA_ID_ANALOG_BANK7       =23, /* 24 */
-    WHAL_INI_DATA_ID_ADDAC              =25, /* 26 */
-#else
-    WHAL_INI_DATA_ID_ANALOG_COMMON      =11, /* 12 */ 
-    WHAL_INI_DATA_ID_ANALOG_MODE_SPECIFIC=13, /* 14,15 */ 
-    WHAL_INI_DATA_ID_ANALOG_BANK6       =16, /* 17,18 */
-    WHAL_INI_DATA_ID_MODE_OVERRIDES     =19, /* 20,21,22,23 */
-    WHAL_INI_DATA_ID_COMMON_OVERRIDES   =24, /* 25 */
-    WHAL_INI_DATA_ID_ANALOG_OVERRIDES   =26, /* 27,28 */
-#endif /* FPGA */
-#else
-    WHAL_INI_DATA_ID_NULL               =0,
-    WHAL_INI_DATA_ID_MODE_SPECIFIC      =1,  /* 2,3 */
-    WHAL_INI_DATA_ID_COMMON             =4,  /* 5 */
-    WHAL_INI_DATA_ID_BB_RFGAIN          =6,  /* 7,8 */
-#define WHAL_INI_DATA_ID_BB_RFGAIN_LNA1 WHAL_INI_DATA_ID_BB_RFGAIN
-    WHAL_INI_DATA_ID_ANALOG_BANK1       =9,  /* 10 */
-    WHAL_INI_DATA_ID_ANALOG_BANK2       =11, /* 12 */
-    WHAL_INI_DATA_ID_ANALOG_BANK3       =13, /* 14, 15 */
-    WHAL_INI_DATA_ID_ANALOG_BANK6       =16, /* 17, 18 */
-    WHAL_INI_DATA_ID_ANALOG_BANK7       =19, /* 20 */
-    WHAL_INI_DATA_ID_MODE_OVERRIDES     =21, /* 22,23 */
-    WHAL_INI_DATA_ID_COMMON_OVERRIDES   =24, /* 25 */
-    WHAL_INI_DATA_ID_ANALOG_OVERRIDES   =26, /* 27,28 */
-    WHAL_INI_DATA_ID_BB_RFGAIN_LNA2     =29, /* 30,31 */
-#endif
-    WHAL_INI_DATA_ID_MAX                =31
-} WHAL_INI_DATA_ID;
-
-typedef PREPACK struct {
-    u16 freqIndex; // 1 - A mode 2 - B or G mode 0 - common
-    u16 offset;
-    u32 newValue;
-} POSTPACK INI_DSET_REG_OVERRIDE;
-
-#endif
diff -druN linux-2.6.39-libre/drivers/staging/ath6kl/include/common/regDb.h linux-3.0-rc7-libre/drivers/staging/ath6kl/include/common/regDb.h
--- linux-2.6.39-libre/drivers/staging/ath6kl/include/common/regDb.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/ath6kl/include/common/regDb.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,29 +0,0 @@
-//------------------------------------------------------------------------------
-// Copyright (c) 2005-2010 Atheros Corporation.  All rights reserved.
-// 
-//
-// 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.
-//
-//
-//------------------------------------------------------------------------------
-//==============================================================================
-// Author(s): ="Atheros"
-//==============================================================================
-
-#ifndef __REG_DB_H__
-#define __REG_DB_H__
-
-#include "./regulatory/reg_dbschema.h"
-#include "./regulatory/reg_dbvalues.h"
-
-#endif  /* __REG_DB_H__ */
diff -druN linux-2.6.39-libre/drivers/staging/ath6kl/include/common/regdump.h linux-3.0-rc7-libre/drivers/staging/ath6kl/include/common/regdump.h
--- linux-2.6.39-libre/drivers/staging/ath6kl/include/common/regdump.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/ath6kl/include/common/regdump.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,59 +0,0 @@
-//------------------------------------------------------------------------------
-// <copyright file="regdump.h" company="Atheros">
-//    Copyright (c) 2004-2010 Atheros Corporation.  All rights reserved.
-// 
-//
-// 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.
-//
-//
-//------------------------------------------------------------------------------
-//==============================================================================
-// Author(s): ="Atheros"
-//==============================================================================
-
-#ifndef __REGDUMP_H__
-#define __REGDUMP_H__
-
-#ifndef ATH_TARGET
-#include "athstartpack.h"
-#endif
-
-#if defined(AR6001)
-#include "AR6001/AR6001_regdump.h"
-#endif
-#if defined(AR6002)
-#include "AR6002/AR6002_regdump.h"
-#endif
-
-#if !defined(__ASSEMBLER__)
-/*
- * Target CPU state at the time of failure is reflected
- * in a register dump, which the Host can fetch through
- * the diagnostic window.
- */
-PREPACK struct register_dump_s {
-    u32 target_id;               /* Target ID */
-    u32 assline;                 /* Line number (if assertion failure) */
-    u32 pc;                      /* Program Counter at time of exception */
-    u32 badvaddr;                /* Virtual address causing exception */
-    CPU_exception_frame_t exc_frame;  /* CPU-specific exception info */
-
-    /* Could copy top of stack here, too.... */
-} POSTPACK;
-#endif /* __ASSEMBLER__ */
-
-#ifndef ATH_TARGET
-#include "athendpack.h"
-#endif
-
-#endif /* __REGDUMP_H__ */
diff -druN linux-2.6.39-libre/drivers/staging/ath6kl/include/common/regulatory/reg_dbschema.h linux-3.0-rc7-libre/drivers/staging/ath6kl/include/common/regulatory/reg_dbschema.h
--- linux-2.6.39-libre/drivers/staging/ath6kl/include/common/regulatory/reg_dbschema.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/ath6kl/include/common/regulatory/reg_dbschema.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,237 +0,0 @@
-//------------------------------------------------------------------------------
-// Copyright (c) 2005-2010 Atheros Corporation.  All rights reserved.
-// 
-//
-// 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.
-//
-//
-//------------------------------------------------------------------------------
-//==============================================================================
-// Author(s): ="Atheros"
-//==============================================================================
-
-#ifndef __REG_DBSCHEMA_H__
-#define __REG_DBSCHEMA_H__
-
-/*
- * This file describes the regulatory DB schema, which is common between the
- * 'generator' and 'parser'. The 'generator' runs on a host(typically a x86
- * Linux) and spits outs two binary files, which follow the DB file
- * format(described below). The resultant output "regulatoryData_AG.bin"
- * is binary file which has information regarding A and G regulatory
- * information, while the "regulatoryData_G.bin" consists of G-ONLY regulatory
- * information. This binary file is parsed in the target for extracting
- * regulatory information.
- * 
- * The DB values used to populate the regulatory DB are defined in
- * reg_dbvalues.h
- *
- */
-
-/* Binary data file - Representation of Regulatory DB*/
-#define REG_DATA_FILE_AG    "./regulatoryData_AG.bin"
-#define REG_DATA_FILE_G     "./regulatoryData_G.bin"
-
-
-/* Table tags used to encode different tables in the database */
-enum data_tags_t{
-    REG_DMN_PAIR_MAPPING_TAG = 0,
-    REG_COUNTRY_CODE_TO_ENUM_RD_TAG,
-    REG_DMN_FREQ_BAND_regDmn5GhzFreq_TAG,
-    REG_DMN_FREQ_BAND_regDmn2Ghz11_BG_Freq_TAG,
-    REG_DOMAIN_TAG,
-    MAX_DB_TABLE_TAGS
-    };
-
-
-
-/*
- ****************************************************************************
- * Regulatory DB file format :
- * 4-bytes : "RGDB" (Magic Key)
- * 4-bytes : version (Default is 5379(my extn))
- * 4-bytes : length of file
- * dbType(4)
- * TAG(4)
- * Entries(1)entrySize(1)searchType(1)reserved[3]tableSize(2)"0xdeadbeef"(4)struct_data....
- * TAG(4)
- * Entries(1)entrySize(1)searchType(1)reserved[3]tableSize(2)"0xdeadbeef"(4)struct_data....
- * TAG(4)
- * Entries(1)entrySize(1)searchType(1)reserved[3]tableSize(2)"0xdeadbeef"(4)struct_data....
- * ...
- * ...
- ****************************************************************************
- *
- */
-
-/*
- * Length of the file would be filled in when the file is created and
- * it would include the header size.
- */
-
-#define REG_DB_KEY          "RGDB" /* Should be EXACTLY 4-bytes */
-#define REG_DB_VER           7802  /* Between 0-9999 */
-/*  REG_DB_VER history in reverse chronological order: 
- *  7802: 78 (ASCII code of N) + 02 (minor version number) - updated 10/21/09 
- *  7801: 78 (ASCII code of N) + 01 (minor version number, increment on further changes)
- *  1178: '11N' = 11 + ASCII code of N(78)
- *  5379: initial version, no 11N support
- */
-#define MAGIC_KEY_OFFSET    0
-#define VERSION_OFFSET      4
-#define FILE_SZ_OFFSET      8
-#define DB_TYPE_OFFSET      12
-
-#define MAGIC_KEY_SZ        4
-#define VERSION_SZ          4
-#define FILE_SZ_SZ          4
-#define DB_TYPE_SZ          4
-#define DB_TAG_SZ           4
-
-#define REGDB_GET_MAGICKEY(x)     ((char *)x + MAGIC_KEY_OFFSET) 
-#define REGDB_GET_VERSION(x)      ((char *)x + VERSION_OFFSET)
-#define REGDB_GET_FILESIZE(x)     *((unsigned int *)((char *)x + FILE_SZ_OFFSET))
-#define REGDB_GET_DBTYPE(x)       *((char *)x + DB_TYPE_OFFSET)
-
-#define REGDB_SET_FILESIZE(x, sz_) *((unsigned int *)((char *)x + FILE_SZ_OFFSET)) = (sz_)
-#define REGDB_IS_EOF(cur, begin)  ( REGDB_GET_FILESIZE(begin) > ((cur) - (begin)) )
-
-
-/* A Table can be search based on key as a parameter or accessed directly
- * by giving its index in to the table.
- */
-enum searchType {
-    KEY_BASED_TABLE_SEARCH = 1,
-    INDEX_BASED_TABLE_ACCESS
-    };
-
-
-/* Data is organised as different tables. There is a Master table, which
- * holds information regarding all the tables. It does not have any
- * knowledge about the attributes of the table it is holding
- * but has external view of the same(for ex, how many entries, record size,
- * how to search the table, total table size and reference to the data
- * instance of table).
- */
-typedef PREPACK struct dbMasterTable_t {    /* Hold ptrs to Table data structures */
-    u8     numOfEntries;
-    char entrySize;      /* Entry size per table row */
-    char searchType;     /* Index based access or key based */
-    char reserved[3];    /* for alignment */
-    u16 tableSize;      /* Size of this table */
-    char *dataPtr;       /* Ptr to the actual Table */
-} POSTPACK dbMasterTable;    /* Master table - table of tables */
-
-
-/* used to get the number of rows in a table */
-#define REGDB_NUM_OF_ROWS(a)    (sizeof (a) / sizeof (a[0]))
-
-/* 
- * Used to set the RegDomain bitmask which chooses which frequency
- * band specs are used.
- */
-
-#define BMLEN 2         /* Use 2 32-bit uint for channel bitmask */
-#define BMZERO {0,0}    /* BMLEN zeros */
-
-#define BM(_fa, _fb, _fc, _fd, _fe, _ff, _fg, _fh) \
-      {((((_fa >= 0) && (_fa < 32)) ? (((u32) 1) << _fa) : 0) | \
-    (((_fb >= 0) && (_fb < 32)) ? (((u32) 1) << _fb) : 0) | \
-    (((_fc >= 0) && (_fc < 32)) ? (((u32) 1) << _fc) : 0) | \
-    (((_fd >= 0) && (_fd < 32)) ? (((u32) 1) << _fd) : 0) | \
-    (((_fe >= 0) && (_fe < 32)) ? (((u32) 1) << _fe) : 0) | \
-    (((_ff >= 0) && (_ff < 32)) ? (((u32) 1) << _ff) : 0) | \
-    (((_fg >= 0) && (_fg < 32)) ? (((u32) 1) << _fg) : 0) | \
-    (((_fh >= 0) && (_fh < 32)) ? (((u32) 1) << _fh) : 0)), \
-       ((((_fa > 31) && (_fa < 64)) ? (((u32) 1) << (_fa - 32)) : 0) | \
-        (((_fb > 31) && (_fb < 64)) ? (((u32) 1) << (_fb - 32)) : 0) | \
-        (((_fc > 31) && (_fc < 64)) ? (((u32) 1) << (_fc - 32)) : 0) | \
-        (((_fd > 31) && (_fd < 64)) ? (((u32) 1) << (_fd - 32)) : 0) | \
-        (((_fe > 31) && (_fe < 64)) ? (((u32) 1) << (_fe - 32)) : 0) | \
-        (((_ff > 31) && (_ff < 64)) ? (((u32) 1) << (_ff - 32)) : 0) | \
-        (((_fg > 31) && (_fg < 64)) ? (((u32) 1) << (_fg - 32)) : 0) | \
-        (((_fh > 31) && (_fh < 64)) ? (((u32) 1) << (_fh - 32)) : 0))}
-
-
-/*
- * THE following table is the mapping of regdomain pairs specified by
- * a regdomain value to the individual unitary reg domains
- */
-
-typedef PREPACK struct reg_dmn_pair_mapping {
-    u16 regDmnEnum;    /* 16 bit reg domain pair */
-    u16 regDmn5GHz;    /* 5GHz reg domain */
-    u16 regDmn2GHz;    /* 2GHz reg domain */
-    u8 flags5GHz;     /* Requirements flags (AdHoc disallow etc) */
-    u8 flags2GHz;     /* Requirements flags (AdHoc disallow etc) */
-    u32 pscanMask;     /* Passive Scan flags which can override unitary domain passive scan
-                                   flags.  This value is used as a mask on the unitary flags*/
-} POSTPACK REG_DMN_PAIR_MAPPING;
-
-#define OFDM_YES (1 << 0)
-#define OFDM_NO  (0 << 0)
-#define MCS_HT20_YES   (1 << 1)
-#define MCS_HT20_NO    (0 << 1)
-#define MCS_HT40_A_YES (1 << 2)
-#define MCS_HT40_A_NO  (0 << 2)
-#define MCS_HT40_G_YES (1 << 3)
-#define MCS_HT40_G_NO  (0 << 3)
-
-typedef PREPACK struct {
-    u16 countryCode;
-    u16 regDmnEnum;
-    char isoName[3];
-    char allowMode;  /* what mode is allowed - bit 0: OFDM; bit 1: MCS_HT20; bit 2: MCS_HT40_A; bit 3: MCS_HT40_G */
-} POSTPACK COUNTRY_CODE_TO_ENUM_RD;
-
-/* lower 16 bits of ht40ChanMask */
-#define NO_FREQ_HT40    0x0     /* no freq is HT40 capable */
-#define F1_TO_F4_HT40   0xF     /* freq 1 to 4 in the block is ht40 capable */
-#define F2_TO_F3_HT40   0x6     /* freq 2 to 3 in the block is ht40 capable */
-#define F1_TO_F10_HT40  0x3FF   /* freq 1 to 10 in the block is ht40 capable */
-#define F3_TO_F11_HT40  0x7FC   /* freq 3 to 11 in the block is ht40 capable */
-#define F3_TO_F9_HT40   0x1FC   /* freq 3 to 9 in the block is ht40 capable */
-#define F1_TO_F8_HT40   0xFF    /* freq 1 to 8 in the block is ht40 capable */
-#define F1_TO_F4_F9_TO_F10_HT40   0x30F    /* freq 1 to 4, 9 to 10 in the block is ht40 capable */
-
-/* upper 16 bits of ht40ChanMask */
-#define FREQ_HALF_RATE      0x10000
-#define FREQ_QUARTER_RATE   0x20000
-
-typedef PREPACK struct RegDmnFreqBand {
-    u16 lowChannel;     /* Low channel center in MHz */
-    u16 highChannel;    /* High Channel center in MHz */
-    u8 power;          /* Max power (dBm) for channel range */
-    u8 channelSep;     /* Channel separation within the band */
-    u8 useDfs;         /* Use DFS in the RegDomain if corresponding bit is set */
-    u8 mode;           /* Mode of operation */
-    u32 usePassScan;    /* Use Passive Scan in the RegDomain if corresponding bit is set */
-    u32 ht40ChanMask;   /* lower 16 bits: indicate which frequencies in the block is HT40 capable
-                                   upper 16 bits: what rate (half/quarter) the channel is  */
-} POSTPACK REG_DMN_FREQ_BAND;
-
-
-
-typedef PREPACK struct regDomain {
-    u16 regDmnEnum;     /* value from EnumRd table */
-    u8 rdCTL;
-    u8 maxAntGain;
-    u8 dfsMask;        /* DFS bitmask for 5Ghz tables */
-    u8 flags;          /* Requirement flags (AdHoc disallow etc) */
-    u16 reserved;       /* for alignment */
-    u32 pscan;          /* Bitmask for passive scan */
-    u32 chan11a[BMLEN]; /* 64 bit bitmask for channel/band selection */
-    u32 chan11bg[BMLEN];/* 64 bit bitmask for channel/band selection */
-} POSTPACK REG_DOMAIN;
-
-#endif /* __REG_DBSCHEMA_H__ */
diff -druN linux-2.6.39-libre/drivers/staging/ath6kl/include/common/regulatory/reg_dbvalues.h linux-3.0-rc7-libre/drivers/staging/ath6kl/include/common/regulatory/reg_dbvalues.h
--- linux-2.6.39-libre/drivers/staging/ath6kl/include/common/regulatory/reg_dbvalues.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/ath6kl/include/common/regulatory/reg_dbvalues.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,504 +0,0 @@
-//------------------------------------------------------------------------------
-// Copyright (c) 2005-2010 Atheros Corporation.  All rights reserved.
-// 
-//
-// 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.
-//
-//
-//------------------------------------------------------------------------------
-//==============================================================================
-// Author(s): ="Atheros"
-//==============================================================================
-
-
-#ifndef __REG_DBVALUE_H__
-#define __REG_DBVALUE_H__
-
-/*
- * Numbering from ISO 3166
- */
-enum CountryCode {
-    CTRY_ALBANIA              = 8,       /* Albania */
-    CTRY_ALGERIA              = 12,      /* Algeria */
-    CTRY_ARGENTINA            = 32,      /* Argentina */
-    CTRY_ARMENIA              = 51,      /* Armenia */
-    CTRY_ARUBA                = 533,     /* Aruba */
-    CTRY_AUSTRALIA            = 36,      /* Australia (for STA) */
-    CTRY_AUSTRALIA_AP         = 5000,    /* Australia (for AP) */
-    CTRY_AUSTRIA              = 40,      /* Austria */
-    CTRY_AZERBAIJAN           = 31,      /* Azerbaijan */
-    CTRY_BAHRAIN              = 48,      /* Bahrain */
-    CTRY_BANGLADESH           = 50,      /* Bangladesh */
-    CTRY_BARBADOS             = 52,      /* Barbados */
-    CTRY_BELARUS              = 112,     /* Belarus */
-    CTRY_BELGIUM              = 56,      /* Belgium */
-    CTRY_BELIZE               = 84,      /* Belize */
-    CTRY_BOLIVIA              = 68,      /* Bolivia */
-    CTRY_BOSNIA_HERZEGOWANIA  = 70,      /* Bosnia & Herzegowania */
-    CTRY_BRAZIL               = 76,      /* Brazil */
-    CTRY_BRUNEI_DARUSSALAM    = 96,      /* Brunei Darussalam */
-    CTRY_BULGARIA             = 100,     /* Bulgaria */
-    CTRY_CAMBODIA             = 116,     /* Cambodia */
-    CTRY_CANADA               = 124,     /* Canada (for STA) */
-    CTRY_CANADA_AP            = 5001,    /* Canada (for AP) */
-    CTRY_CHILE                = 152,     /* Chile */
-    CTRY_CHINA                = 156,     /* People's Republic of China */
-    CTRY_COLOMBIA             = 170,     /* Colombia */
-    CTRY_COSTA_RICA           = 188,     /* Costa Rica */
-    CTRY_CROATIA              = 191,     /* Croatia */
-    CTRY_CYPRUS               = 196,
-    CTRY_CZECH                = 203,     /* Czech Republic */
-    CTRY_DENMARK              = 208,     /* Denmark */
-    CTRY_DOMINICAN_REPUBLIC   = 214,     /* Dominican Republic */
-    CTRY_ECUADOR              = 218,     /* Ecuador */
-    CTRY_EGYPT                = 818,     /* Egypt */
-    CTRY_EL_SALVADOR          = 222,     /* El Salvador */
-    CTRY_ESTONIA              = 233,     /* Estonia */
-    CTRY_FAEROE_ISLANDS       = 234,     /* Faeroe Islands */
-    CTRY_FINLAND              = 246,     /* Finland */
-    CTRY_FRANCE               = 250,     /* France */
-    CTRY_FRANCE2              = 255,     /* France2 */
-    CTRY_GEORGIA              = 268,     /* Georgia */
-    CTRY_GERMANY              = 276,     /* Germany */
-    CTRY_GREECE               = 300,     /* Greece */
-    CTRY_GREENLAND            = 304,     /* Greenland */
-    CTRY_GRENADA              = 308,     /* Grenada */
-    CTRY_GUAM                 = 316,     /* Guam */
-    CTRY_GUATEMALA            = 320,     /* Guatemala */
-    CTRY_HAITI                = 332,     /* Haiti */
-    CTRY_HONDURAS             = 340,     /* Honduras */
-    CTRY_HONG_KONG            = 344,     /* Hong Kong S.A.R., P.R.C. */
-    CTRY_HUNGARY              = 348,     /* Hungary */
-    CTRY_ICELAND              = 352,     /* Iceland */
-    CTRY_INDIA                = 356,     /* India */
-    CTRY_INDONESIA            = 360,     /* Indonesia */
-    CTRY_IRAN                 = 364,     /* Iran */
-    CTRY_IRAQ                 = 368,     /* Iraq */
-    CTRY_IRELAND              = 372,     /* Ireland */
-    CTRY_ISRAEL               = 376,     /* Israel */
-    CTRY_ITALY                = 380,     /* Italy */
-    CTRY_JAMAICA              = 388,     /* Jamaica */
-    CTRY_JAPAN                = 392,     /* Japan */
-    CTRY_JAPAN1               = 393,     /* Japan (JP1) */
-    CTRY_JAPAN2               = 394,     /* Japan (JP0) */
-    CTRY_JAPAN3               = 395,     /* Japan (JP1-1) */
-    CTRY_JAPAN4               = 396,     /* Japan (JE1) */
-    CTRY_JAPAN5               = 397,     /* Japan (JE2) */
-    CTRY_JAPAN6               = 399,     /* Japan (JP6) */
-    CTRY_JORDAN               = 400,     /* Jordan */
-    CTRY_KAZAKHSTAN           = 398,     /* Kazakhstan */
-    CTRY_KENYA                = 404,     /* Kenya */
-    CTRY_KOREA_NORTH          = 408,     /* North Korea */
-    CTRY_KOREA_ROC            = 410,     /* South Korea (for STA) */
-    CTRY_KOREA_ROC2           = 411,     /* South Korea */
-    CTRY_KOREA_ROC3           = 412,     /* South Korea (for AP) */
-    CTRY_KUWAIT               = 414,     /* Kuwait */
-    CTRY_LATVIA               = 428,     /* Latvia */
-    CTRY_LEBANON              = 422,     /* Lebanon */
-    CTRY_LIBYA                = 434,     /* Libya */
-    CTRY_LIECHTENSTEIN        = 438,     /* Liechtenstein */
-    CTRY_LITHUANIA            = 440,     /* Lithuania */
-    CTRY_LUXEMBOURG           = 442,     /* Luxembourg */
-    CTRY_MACAU                = 446,     /* Macau */
-    CTRY_MACEDONIA            = 807,     /* the Former Yugoslav Republic of Macedonia */
-    CTRY_MALAYSIA             = 458,     /* Malaysia */
-    CTRY_MALTA                = 470,     /* Malta */
-    CTRY_MEXICO               = 484,     /* Mexico */
-    CTRY_MONACO               = 492,     /* Principality of Monaco */
-    CTRY_MOROCCO              = 504,     /* Morocco */
-    CTRY_NEPAL                = 524,     /* Nepal */   
-    CTRY_NETHERLANDS          = 528,     /* Netherlands */
-    CTRY_NETHERLAND_ANTILLES  = 530,     /* Netherlands-Antilles */
-    CTRY_NEW_ZEALAND          = 554,     /* New Zealand */
-    CTRY_NICARAGUA            = 558,     /* Nicaragua */
-    CTRY_NORWAY               = 578,     /* Norway */
-    CTRY_OMAN                 = 512,     /* Oman */
-    CTRY_PAKISTAN             = 586,     /* Islamic Republic of Pakistan */
-    CTRY_PANAMA               = 591,     /* Panama */
-    CTRY_PARAGUAY             = 600,     /* Paraguay */
-    CTRY_PERU                 = 604,     /* Peru */
-    CTRY_PHILIPPINES          = 608,     /* Republic of the Philippines */
-    CTRY_POLAND               = 616,     /* Poland */
-    CTRY_PORTUGAL             = 620,     /* Portugal */
-    CTRY_PUERTO_RICO          = 630,     /* Puerto Rico */
-    CTRY_QATAR                = 634,     /* Qatar */
-    CTRY_ROMANIA              = 642,     /* Romania */
-    CTRY_RUSSIA               = 643,     /* Russia */
-    CTRY_SAUDI_ARABIA         = 682,     /* Saudi Arabia */
-    CTRY_MONTENEGRO           = 891,     /* Montenegro */
-    CTRY_SINGAPORE            = 702,     /* Singapore */
-    CTRY_SLOVAKIA             = 703,     /* Slovak Republic */
-    CTRY_SLOVENIA             = 705,     /* Slovenia */
-    CTRY_SOUTH_AFRICA         = 710,     /* South Africa */
-    CTRY_SPAIN                = 724,     /* Spain */
-    CTRY_SRILANKA             = 144,     /* Sri Lanka */
-    CTRY_SWEDEN               = 752,     /* Sweden */
-    CTRY_SWITZERLAND          = 756,     /* Switzerland */
-    CTRY_SYRIA                = 760,     /* Syria */
-    CTRY_TAIWAN               = 158,     /* Taiwan */
-    CTRY_THAILAND             = 764,     /* Thailand */
-    CTRY_TRINIDAD_Y_TOBAGO    = 780,     /* Trinidad y Tobago */
-    CTRY_TUNISIA              = 788,     /* Tunisia */
-    CTRY_TURKEY               = 792,     /* Turkey */
-    CTRY_UAE                  = 784,     /* U.A.E. */
-    CTRY_UKRAINE              = 804,     /* Ukraine */
-    CTRY_UNITED_KINGDOM       = 826,     /* United Kingdom */
-    CTRY_UNITED_STATES        = 840,     /* United States (for STA) */
-    CTRY_UNITED_STATES_AP     = 841,     /* United States (for AP) */
-    CTRY_UNITED_STATES_PS     = 842,     /* United States - public safety */
-    CTRY_URUGUAY              = 858,     /* Uruguay */
-    CTRY_UZBEKISTAN           = 860,     /* Uzbekistan */
-    CTRY_VENEZUELA            = 862,     /* Venezuela */
-    CTRY_VIET_NAM             = 704,     /* Viet Nam */
-    CTRY_YEMEN                = 887,     /* Yemen */
-    CTRY_ZIMBABWE             = 716      /* Zimbabwe */
-};
-
-#define CTRY_DEBUG      0
-#define CTRY_DEFAULT    0x1ff
-
-/*
- * The following regulatory domain definitions are
- * found in the EEPROM. Each regulatory domain
- * can operate in either a 5GHz or 2.4GHz wireless mode or
- * both 5GHz and 2.4GHz wireless modes.
- * In general, the value holds no special
- * meaning and is used to decode into either specific
- * 2.4GHz or 5GHz wireless mode for that particular
- * regulatory domain.
- *
- * Enumerated Regulatory Domain Information 8 bit values indicate that
- * the regdomain is really a pair of unitary regdomains.  12 bit values
- * are the real unitary regdomains and are the only ones which have the
- * frequency bitmasks and flags set.
- */
-
-enum EnumRd {
-    NO_ENUMRD   = 0x00,
-    NULL1_WORLD = 0x03,     /* For 11b-only countries (no 11a allowed) */
-    NULL1_ETSIB = 0x07,     /* Israel */
-    NULL1_ETSIC = 0x08,
-
-    FCC1_FCCA   = 0x10,     /* USA */
-    FCC1_WORLD  = 0x11,     /* Hong Kong */
-    FCC2_FCCA   = 0x20,     /* Canada */
-    FCC2_WORLD  = 0x21,     /* Australia & HK */
-    FCC2_ETSIC  = 0x22,
-    FCC3_FCCA   = 0x3A,     /* USA & Canada w/5470 band, 11h, DFS enabled */
-    FCC3_WORLD  = 0x3B,     /* USA & Canada w/5470 band, 11h, DFS enabled */
-    FCC4_FCCA   = 0x12,     /* FCC public safety plus UNII bands */
-    FCC5_FCCA   = 0x13,     /* US with no DFS */
-    FCC5_WORLD  = 0x16,     /* US with no DFS */
-    FCC6_FCCA   = 0x14,     /* Same as FCC2_FCCA but with 5600-5650MHz channels disabled for US & Canada APs */
-    FCC6_WORLD  = 0x23,     /* Same as FCC2_FCCA but with 5600-5650MHz channels disabled for Australia APs */
-
-    ETSI1_WORLD = 0x37,
-
-    ETSI2_WORLD = 0x35,     /* Hungary & others */
-    ETSI3_WORLD = 0x36,     /* France & others */
-    ETSI4_WORLD = 0x30,
-    ETSI4_ETSIC = 0x38,
-    ETSI5_WORLD = 0x39,
-    ETSI6_WORLD = 0x34,     /* Bulgaria */
-    ETSI_RESERVED   = 0x33,     /* Reserved (Do not used) */
-    FRANCE_RES  = 0x31,     /* Legacy France for OEM */
-
-    APL6_WORLD  = 0x5B,     /* Singapore */
-    APL4_WORLD  = 0x42,     /* Singapore */
-    APL3_FCCA   = 0x50,
-    APL_RESERVED    = 0x44,     /* Reserved (Do not used)  */
-    APL2_WORLD  = 0x45,     /* Korea */
-    APL2_APLC   = 0x46,
-    APL3_WORLD  = 0x47,
-    APL2_APLD   = 0x49,     /* Korea with 2.3G channels */
-    APL2_FCCA   = 0x4D,     /* Specific Mobile Customer */
-    APL1_WORLD  = 0x52,     /* Latin America */
-    APL1_FCCA   = 0x53,
-    APL1_ETSIC  = 0x55,
-    APL2_ETSIC  = 0x56,     /* Venezuela */
-    APL5_WORLD  = 0x58,     /* Chile */
-    APL7_FCCA   = 0x5C,
-    APL8_WORLD  = 0x5D,
-    APL9_WORLD  = 0x5E,
-    APL10_WORLD = 0x5F,     /* Korea 5GHz for STA */
-
-
-    MKK5_MKKA   = 0x99, /* This is a temporary value. MG and DQ have to give official one */
-    MKK5_FCCA   = 0x9A, /* This is a temporary value. MG and DQ have to give official one */
-    MKK5_MKKC   = 0x88,
-    MKK11_MKKA  = 0xD4,
-    MKK11_FCCA  = 0xD5,
-    MKK11_MKKC  = 0xD7,
-
-    /*
-     * World mode SKUs
-     */
-    WOR0_WORLD  = 0x60,     /* World0 (WO0 SKU) */
-    WOR1_WORLD  = 0x61,     /* World1 (WO1 SKU) */
-    WOR2_WORLD  = 0x62,     /* World2 (WO2 SKU) */
-    WOR3_WORLD  = 0x63,     /* World3 (WO3 SKU) */
-    WOR4_WORLD  = 0x64,     /* World4 (WO4 SKU) */  
-    WOR5_ETSIC  = 0x65,     /* World5 (WO5 SKU) */    
-
-    WOR01_WORLD = 0x66,     /* World0-1 (WW0-1 SKU) */
-    WOR02_WORLD = 0x67,     /* World0-2 (WW0-2 SKU) */
-    EU1_WORLD   = 0x68,     /* Same as World0-2 (WW0-2 SKU), except active scan ch1-13. No ch14 */
-
-    WOR9_WORLD  = 0x69,     /* World9 (WO9 SKU) */  
-    WORA_WORLD  = 0x6A,     /* WorldA (WOA SKU) */  
-    WORB_WORLD  = 0x6B,     /* WorldB (WOA SKU) */  
-    WORC_WORLD  = 0x6C,     /* WorldC (WOA SKU) */  
-
-    /*
-     * Regulator domains ending in a number (e.g. APL1,
-     * MK1, ETSI4, etc) apply to 5GHz channel and power
-     * information.  Regulator domains ending in a letter
-     * (e.g. APLA, FCCA, etc) apply to 2.4GHz channel and
-     * power information.
-     */
-    APL1        = 0x0150,   /* LAT & Asia */
-    APL2        = 0x0250,   /* LAT & Asia */
-    APL3        = 0x0350,   /* Taiwan */
-    APL4        = 0x0450,   /* Jordan */
-    APL5        = 0x0550,   /* Chile */
-    APL6        = 0x0650,   /* Singapore */
-    APL7        = 0x0750,   /* Taiwan */
-    APL8        = 0x0850,   /* Malaysia */
-    APL9        = 0x0950,   /* Korea */
-    APL10       = 0x1050,   /* Korea 5GHz */
-
-    ETSI1       = 0x0130,   /* Europe & others */
-    ETSI2       = 0x0230,   /* Europe & others */
-    ETSI3       = 0x0330,   /* Europe & others */
-    ETSI4       = 0x0430,   /* Europe & others */
-    ETSI5       = 0x0530,   /* Europe & others */
-    ETSI6       = 0x0630,   /* Europe & others */
-    ETSIB       = 0x0B30,   /* Israel */
-    ETSIC       = 0x0C30,   /* Latin America */
-
-    FCC1        = 0x0110,   /* US & others */
-    FCC2        = 0x0120,   /* Canada, Australia & New Zealand */
-    FCC3        = 0x0160,   /* US w/new middle band & DFS */    
-    FCC4        = 0x0165,
-    FCC5        = 0x0180,
-    FCC6        = 0x0610,
-    FCCA        = 0x0A10,    
-
-    APLD        = 0x0D50,   /* South Korea */
-
-    MKK1        = 0x0140,   /* Japan */
-    MKK2        = 0x0240,   /* Japan Extended */
-    MKK3        = 0x0340,   /* Japan new 5GHz */
-    MKK4        = 0x0440,   /* Japan new 5GHz */
-    MKK5        = 0x0540,   /* Japan new 5GHz */
-    MKK6        = 0x0640,   /* Japan new 5GHz */
-    MKK7        = 0x0740,   /* Japan new 5GHz */
-    MKK8        = 0x0840,   /* Japan new 5GHz */
-    MKK9        = 0x0940,   /* Japan new 5GHz */
-    MKK10       = 0x1040,   /* Japan new 5GHz */
-    MKK11       = 0x1140,   /* Japan new 5GHz */
-    MKK12       = 0x1240,   /* Japan new 5GHz */
-
-    MKKA        = 0x0A40,   /* Japan */
-    MKKC        = 0x0A50,
-
-    NULL1       = 0x0198,
-    WORLD       = 0x0199,
-    DEBUG_REG_DMN   = 0x01ff,
-    UNINIT_REG_DMN  = 0x0fff,
-};
-
-enum {                  /* conformance test limits */
-    FCC = 0x10,
-    MKK = 0x40,
-    ETSI    = 0x30,
-    NO_CTL  = 0xff,
-    CTL_11B = 1,
-    CTL_11G = 2
-};
-
-
-/*
- * The following are flags for different requirements per reg domain.
- * These requirements are either inhereted from the reg domain pair or
- * from the unitary reg domain if the reg domain pair flags value is
- * 0
- */
-
-enum {
-    NO_REQ              = 0x00,
-    DISALLOW_ADHOC_11A  = 0x01,
-    ADHOC_PER_11D       = 0x02,
-    ADHOC_NO_11A        = 0x04,
-    DISALLOW_ADHOC_11G  = 0x08
-};
-
-
-
-
-/*
- * The following describe the bit masks for different passive scan
- * capability/requirements per regdomain.
- */
-#define NO_PSCAN        0x00000000
-#define PSCAN_FCC       0x00000001
-#define PSCAN_ETSI      0x00000002
-#define PSCAN_MKK       0x00000004
-#define PSCAN_ETSIB     0x00000008
-#define PSCAN_ETSIC     0x00000010
-#define PSCAN_WWR       0x00000020
-#define PSCAN_DEFER     0xFFFFFFFF
-
-/* Bit masks for DFS per regdomain */
-
-enum {
-    NO_DFS   = 0x00,
-    DFS_FCC3 = 0x01,
-    DFS_ETSI = 0x02,
-    DFS_MKK  = 0x04
-};
-
-
-#define DEF_REGDMN      FCC1_FCCA
-
-/* 
- * The following table is the master list for all different freqeuncy
- * bands with the complete matrix of all possible flags and settings
- * for each band if it is used in ANY reg domain.
- *
- * The table of frequency bands is indexed by a bitmask.  The ordering
- * must be consistent with the enum below.  When adding a new
- * frequency band, be sure to match the location in the enum with the
- * comments 
- */
-
-/*
- * These frequency values are as per channel tags and regulatory domain
- * info. Please update them as database is updated.
- */
-#define A_FREQ_MIN              4920
-#define A_FREQ_MAX              5825
-
-#define A_CHAN0_FREQ            5000
-#define A_CHAN_MAX              ((A_FREQ_MAX - A_CHAN0_FREQ)/5)
-
-#define BG_FREQ_MIN             2412
-#define BG_FREQ_MAX             2484
-
-#define BG_CHAN0_FREQ           2407
-#define BG_CHAN_MIN             ((BG_FREQ_MIN - BG_CHAN0_FREQ)/5)
-#define BG_CHAN_MAX             14      /* corresponding to 2484 MHz */
-
-#define A_20MHZ_BAND_FREQ_MAX   5000
-
-
-/*
- * 5GHz 11A channel tags
- */
-
-enum {
-    F1_4920_4980,
-    F1_5040_5080,
-
-    F1_5120_5240,
-
-    F1_5180_5240,
-    F2_5180_5240,
-    F3_5180_5240,
-    F4_5180_5240,
-    F5_5180_5240,
-    F6_5180_5240,
-    F7_5180_5240,
-
-    F1_5260_5280,
-
-    F1_5260_5320,
-    F2_5260_5320,
-    F3_5260_5320,
-    F4_5260_5320,
-    F5_5260_5320,
-    F6_5260_5320,
-
-    F1_5260_5700,
-
-    F1_5280_5320,
-
-    F1_5500_5620,
-
-    F1_5500_5700,
-    F2_5500_5700,
-    F3_5500_5700,
-    F4_5500_5700,
-    F5_5500_5700,
-    F6_5500_5700,
-    F7_5500_5700,
-
-    F1_5745_5805,
-    F2_5745_5805,
-
-    F1_5745_5825,
-    F2_5745_5825,
-    F3_5745_5825,
-    F4_5745_5825,
-    F5_5745_5825,
-    F6_5745_5825,
-
-    W1_4920_4980,
-    W1_5040_5080,
-    W1_5170_5230,
-    W1_5180_5240,
-    W1_5260_5320,
-    W1_5745_5825,
-    W1_5500_5700,
-};
-
-
-/* 2.4 GHz table - for 11b and 11g info */
-enum {
-    BG1_2312_2372,
-    BG2_2312_2372,
-
-    BG1_2412_2472,
-    BG2_2412_2472,
-    BG3_2412_2472,
-    BG4_2412_2472,
-
-    BG1_2412_2462,
-    BG2_2412_2462,
-
-    BG1_2432_2442,
-
-    BG1_2457_2472,
-
-    BG1_2467_2472,
-
-    BG1_2484_2484, /* No G */
-    BG2_2484_2484, /* No G */
-
-    BG1_2512_2732,
-
-    WBG1_2312_2372,
-    WBG1_2412_2412,
-    WBG1_2417_2432,
-    WBG1_2437_2442,
-    WBG1_2447_2457,
-    WBG1_2462_2462,
-    WBG1_2467_2467,
-    WBG2_2467_2467,
-    WBG1_2472_2472,
-    WBG2_2472_2472,
-    WBG1_2484_2484, /* No G */
-    WBG2_2484_2484, /* No G */
-};
-    
-#endif /* __REG_DBVALUE_H__ */
diff -druN linux-2.6.39-libre/drivers/staging/ath6kl/include/common/targaddrs.h linux-3.0-rc7-libre/drivers/staging/ath6kl/include/common/targaddrs.h
--- linux-2.6.39-libre/drivers/staging/ath6kl/include/common/targaddrs.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/ath6kl/include/common/targaddrs.h	2011-07-11 19:51:52.000000000 -0400
@@ -22,10 +22,6 @@
 #ifndef __TARGADDRS_H__
 #define __TARGADDRS_H__
 
-#ifndef ATH_TARGET
-#include "athstartpack.h"
-#endif
-
 #if defined(AR6002)
 #include "AR6002/addrs.h"
 #endif
@@ -91,15 +87,7 @@
     /* Pointer to debug logging header */
     u32 hi_dbglog_hdr;                             /* 0x08 */
 
-    /* Indicates whether or not flash is present on Target.
-     * NB: flash_is_present indicator is here not just
-     * because it might be of interest to the Host; but
-     * also because it's set early on by Target's startup
-     * asm code and we need it to have a special RAM address
-     * so that it doesn't get reinitialized with the rest
-     * of data.
-     */
-    u32 hi_flash_is_present;                       /* 0x0c */
+    u32 hi_unused1;                       /* 0x0c */
 
     /*
      * General-purpose flag bits, similar to AR6000_OPTION_* flags.
@@ -113,7 +101,7 @@
      */
     u32 hi_serial_enable;                          /* 0x14 */
 
-    /* Start address of Flash DataSet index, if any */
+    /* Start address of DataSet index, if any */
     u32 hi_dset_list_head;                         /* 0x18 */
 
     /* Override Target application start address */
@@ -171,35 +159,179 @@
     u32 hi_hci_uart_support_pins;                  /* 0xa4 */
         /* NOTE: byte [0] = RESET pin (bit 7 is polarity), bytes[1]..bytes[3] are for future use */
     u32 hi_hci_uart_pwr_mgmt_params;               /* 0xa8 */
-        /* 0xa8 - [0]: 1 = enable, 0 = disable
-         *        [1]: 0 = UART FC active low, 1 = UART FC active high
-         * 0xa9 - [7:0]: wakeup timeout in ms
-         * 0xaa, 0xab - [15:0]: idle timeout in ms
-         */       
-    /* Pointer to extended board Data  */
-    u32 hi_board_ext_data;                         /* 0xac */
-    u32 hi_board_ext_data_initialized;             /* 0xb0 */
+	/*
+	 * 0xa8   - [1]: 0 = UART FC active low, 1 = UART FC active high
+	 *      [31:16]: wakeup timeout in ms
+	 */
+
+	/* Pointer to extended board data */
+	u32 hi_board_ext_data;                /* 0xac */
+	u32 hi_board_ext_data_config;         /* 0xb0 */
+
+	/*
+         * Bit [0]  :   valid
+         * Bit[31:16:   size
+	*/
+	/*
+	 * hi_reset_flag is used to do some stuff when target reset.
+	 * such as restore app_start after warm reset or
+	 * preserve host Interest area, or preserve ROM data, literals etc.
+	 */
+	u32 hi_reset_flag;                            /* 0xb4 */
+	/* indicate hi_reset_flag is valid */
+	u32 hi_reset_flag_valid;                      /* 0xb8 */
+	u32 hi_hci_uart_pwr_mgmt_params_ext;           /* 0xbc */
+	/*
+	 * 0xbc - [31:0]: idle timeout in ms
+	 */
+	/* ACS flags */
+	u32 hi_acs_flags;                              /* 0xc0 */
+	u32 hi_console_flags;                          /* 0xc4 */
+	u32 hi_nvram_state;                            /* 0xc8 */
+	u32 hi_option_flag2;                           /* 0xcc */
+
+	/* If non-zero, override values sent to Host in WMI_READY event. */
+	u32 hi_sw_version_override;                    /* 0xd0 */
+	u32 hi_abi_version_override;                   /* 0xd4 */
+
+	/*
+	 * Percentage of high priority RX traffic to total expected RX traffic -
+	 * applicable only to ar6004
+	 */
+	u32 hi_hp_rx_traffic_ratio;                    /* 0xd8 */
+
+	/* test applications flags */
+	u32 hi_test_apps_related    ;                  /* 0xdc */
+	/* location of test script */
+	u32 hi_ota_testscript;                         /* 0xe0 */
+	/* location of CAL data */
+	u32 hi_cal_data;                               /* 0xe4 */
+	/* Number of packet log buffers */
+        u32 hi_pktlog_num_buffers;                     /* 0xe8 */
+
 } POSTPACK;
 
 /* Bits defined in hi_option_flag */
 #define HI_OPTION_TIMER_WAR       0x01 /* Enable timer workaround */
 #define HI_OPTION_BMI_CRED_LIMIT  0x02 /* Limit BMI command credits */
 #define HI_OPTION_RELAY_DOT11_HDR 0x04 /* Relay Dot11 hdr to/from host */
-#define HI_OPTION_FW_MODE_LSB     0x08 /* low bit of MODE (see below) */
-#define HI_OPTION_FW_MODE_MSB     0x10 /* high bit of MODE (see below) */
-#define HI_OPTION_ENABLE_PROFILE  0x20 /* Enable CPU profiling */
-#define HI_OPTION_DISABLE_DBGLOG  0x40 /* Disable debug logging */
-#define HI_OPTION_SKIP_ERA_TRACKING  0x80 /* Skip Era Tracking */
-#define HI_OPTION_PAPRD_DISABLE      0x100 /* Disable PAPRD (debug) */
+/* MAC addr method 0-locally administred 1-globally unique addrs */
+#define HI_OPTION_MAC_ADDR_METHOD   0x08
+#define HI_OPTION_FW_BRIDGE         0x10 /* Firmware Bridging */
+#define HI_OPTION_ENABLE_PROFILE    0x20 /* Enable CPU profiling */
+#define HI_OPTION_DISABLE_DBGLOG    0x40 /* Disable debug logging */
+#define HI_OPTION_SKIP_ERA_TRACKING 0x80 /* Skip Era Tracking */
+#define HI_OPTION_PAPRD_DISABLE     0x100 /* Disable PAPRD (debug) */
+#define HI_OPTION_NUM_DEV_LSB       0x200
+#define HI_OPTION_NUM_DEV_MSB       0x800
+#define HI_OPTION_DEV_MODE_LSB      0x1000
+#define HI_OPTION_DEV_MODE_MSB      0x8000000
+/* Disable LowFreq Timer Stabilization */
+#define HI_OPTION_NO_LFT_STBL       0x10000000
+#define HI_OPTION_SKIP_REG_SCAN     0x20000000 /* Skip regulatory scan */
+/* Do regulatory scan during init beforesending WMI ready event to host */
+#define HI_OPTION_INIT_REG_SCAN     0x40000000
+#define HI_OPTION_SKIP_MEMMAP       0x80000000 /* REV6: Do not adjust memory
+                                                map */
+
+/* hi_option_flag2 options */
+#define HI_OPTION_OFFLOAD_AMSDU     0x01
+#define HI_OPTION_DFS_SUPPORT       0x02 /* Enable DFS support */
+
+#define HI_OPTION_MAC_ADDR_METHOD_SHIFT 3
 
 /* 2 bits of hi_option_flag are used to represent 3 modes */
 #define HI_OPTION_FW_MODE_IBSS    0x0 /* IBSS Mode */
 #define HI_OPTION_FW_MODE_BSS_STA 0x1 /* STA Mode */
 #define HI_OPTION_FW_MODE_AP      0x2 /* AP Mode */
 
-/* Fw Mode Mask */
-#define HI_OPTION_FW_MODE_MASK    0x3
-#define HI_OPTION_FW_MODE_SHIFT   0x3
+/* 2 bits of hi_option flag are usedto represent 4 submodes */
+#define HI_OPTION_FW_SUBMODE_NONE    0x0  /* Normal mode */
+#define HI_OPTION_FW_SUBMODE_P2PDEV  0x1  /* p2p device mode */
+#define HI_OPTION_FW_SUBMODE_P2PCLIENT 0x2 /* p2p client mode */
+#define HI_OPTION_FW_SUBMODE_P2PGO   0x3 /* p2p go mode */
+
+/* Num dev Mask */
+#define HI_OPTION_NUM_DEV_MASK    0x7
+#define HI_OPTION_NUM_DEV_SHIFT   0x9
+
+/* firmware bridging */
+#define HI_OPTION_FW_BRIDGE_SHIFT 0x04
+
+/* Fw Mode/SubMode Mask
+|------------------------------------------------------------------------------|
+|   SUB   |   SUB   |   SUB   |  SUB    |         |         |         |
+| MODE[3] | MODE[2] | MODE[1] | MODE[0] | MODE[3] | MODE[2] | MODE[1] | MODE[0|
+|   (2)   |   (2)   |   (2)   |   (2)   |   (2)   |   (2)   |   (2)   |   (2)
+|------------------------------------------------------------------------------|
+*/
+#define HI_OPTION_FW_MODE_BITS         0x2
+#define HI_OPTION_FW_MODE_MASK         0x3
+#define HI_OPTION_FW_MODE_SHIFT        0xC
+#define HI_OPTION_ALL_FW_MODE_MASK     0xFF
+
+#define HI_OPTION_FW_SUBMODE_BITS      0x2
+#define HI_OPTION_FW_SUBMODE_MASK      0x3
+#define HI_OPTION_FW_SUBMODE_SHIFT     0x14
+#define HI_OPTION_ALL_FW_SUBMODE_MASK  0xFF00
+#define HI_OPTION_ALL_FW_SUBMODE_SHIFT 0x8
+
+/* hi_reset_flag */
+
+/* preserve App Start address */
+#define HI_RESET_FLAG_PRESERVE_APP_START         0x01
+/* preserve host interest */
+#define HI_RESET_FLAG_PRESERVE_HOST_INTEREST     0x02
+#define HI_RESET_FLAG_PRESERVE_ROMDATA           0x04  /* preserve ROM data */
+#define HI_RESET_FLAG_PRESERVE_NVRAM_STATE       0x08
+#define HI_RESET_FLAG_PRESERVE_BOOT_INFO         0x10
+
+#define HI_RESET_FLAG_IS_VALID  0x12345678 /* indicate the reset flag is
+valid */
+
+#define ON_RESET_FLAGS_VALID() \
+	(HOST_INTEREST->hi_reset_flag_valid == HI_RESET_FLAG_IS_VALID)
+
+#define RESET_FLAGS_VALIDATE()  \
+	(HOST_INTEREST->hi_reset_flag_valid = HI_RESET_FLAG_IS_VALID)
+
+#define RESET_FLAGS_INVALIDATE() \
+	(HOST_INTEREST->hi_reset_flag_valid = 0)
+
+#define ON_RESET_PRESERVE_APP_START() \
+        (HOST_INTEREST->hi_reset_flag & HI_RESET_FLAG_PRESERVE_APP_START)
+
+#define ON_RESET_PRESERVE_NVRAM_STATE() \
+        (HOST_INTEREST->hi_reset_flag & HI_RESET_FLAG_PRESERVE_NVRAM_STATE)
+
+#define ON_RESET_PRESERVE_HOST_INTEREST() \
+        (HOST_INTEREST->hi_reset_flag & HI_RESET_FLAG_PRESERVE_HOST_INTEREST)
+
+#define ON_RESET_PRESERVE_ROMDATA() \
+        (HOST_INTEREST->hi_reset_flag & HI_RESET_FLAG_PRESERVE_ROMDATA)
+
+#define ON_RESET_PRESERVE_BOOT_INFO() \
+        (HOST_INTEREST->hi_reset_flag & HI_RESET_FLAG_PRESERVE_BOOT_INFO)
+
+#define HI_ACS_FLAGS_ENABLED        (1 << 0)    /* ACS is enabled */
+#define HI_ACS_FLAGS_USE_WWAN       (1 << 1)    /* Use physical WWAN device */
+#define HI_ACS_FLAGS_TEST_VAP       (1 << 2)    /* Use test VAP */
+
+/* CONSOLE FLAGS
+ *
+ * Bit Range  Meaning
+ * ---------  --------------------------------
+ *   2..0     UART ID (0 = Default)
+ *    3       Baud Select (0 = 9600, 1 = 115200)
+ *   30..4    Reserved
+ *    31      Enable Console
+ *
+ */
+
+#define HI_CONSOLE_FLAGS_ENABLE       (1 << 31)
+#define HI_CONSOLE_FLAGS_UART_MASK    (0x7)
+#define HI_CONSOLE_FLAGS_UART_SHIFT   0
+#define HI_CONSOLE_FLAGS_BAUD_SELECT  (1 << 3)
 
 /*
  * Intended for use by Host software, this macro returns the Target RAM
@@ -212,34 +344,52 @@
 #define AR6003_HOST_INTEREST_ITEM_ADDRESS(item) \
     (u32)((unsigned long)&((((struct host_interest_s *)(AR6003_HOST_INTEREST_ADDRESS))->item)))
 
+#define AR6004_HOST_INTEREST_ITEM_ADDRESS(item) \
+        ((u32)&((((struct host_interest_s *)(AR6004_HOST_INTEREST_ADDRESS))->item)))
+
+
 #define HOST_INTEREST_DBGLOG_IS_ENABLED() \
         (!(HOST_INTEREST->hi_option_flag & HI_OPTION_DISABLE_DBGLOG))
 
+#define HOST_INTEREST_PKTLOG_IS_ENABLED() \
+        ((HOST_INTEREST->hi_pktlog_num_buffers))
+
+
 #define HOST_INTEREST_PROFILE_IS_ENABLED() \
         (HOST_INTEREST->hi_option_flag & HI_OPTION_ENABLE_PROFILE)
 
+#define LF_TIMER_STABILIZATION_IS_ENABLED() \
+        (!(HOST_INTEREST->hi_option_flag & HI_OPTION_NO_LFT_STBL))
+
+#define IS_AMSDU_OFFLAOD_ENABLED() \
+        ((HOST_INTEREST->hi_option_flag2 & HI_OPTION_OFFLOAD_AMSDU))
+
+#define HOST_INTEREST_DFS_IS_ENABLED() \
+        ((HOST_INTEREST->hi_option_flag2 & HI_OPTION_DFS_SUPPORT))
+
 /* Convert a Target virtual address into a Target physical address */
 #define AR6002_VTOP(vaddr) ((vaddr) & 0x001fffff)
 #define AR6003_VTOP(vaddr) ((vaddr) & 0x001fffff)
 #define TARG_VTOP(TargetType, vaddr) \
         (((TargetType) == TARGET_TYPE_AR6002) ? AR6002_VTOP(vaddr) : AR6003_VTOP(vaddr))
 
-/* override REV2 ROM's app start address */
-#define AR6002_REV2_APP_START_OVERRIDE    0x911A00
-#define AR6003_REV1_APP_START_OVERRIDE    0x944c00
-#define AR6003_REV1_OTP_DATA_ADDRESS      0x542800
-#define AR6003_REV2_APP_START_OVERRIDE    0x945000
-#define AR6003_REV2_OTP_DATA_ADDRESS      0x543800
-#define AR6003_BOARD_EXT_DATA_ADDRESS     0x57E600
+#define AR6003_REV2_APP_START_OVERRIDE          0x944C00
+#define AR6003_REV2_APP_LOAD_ADDRESS            0x543180
+#define AR6003_REV2_BOARD_EXT_DATA_ADDRESS      0x57E500
+#define AR6003_REV2_DATASET_PATCH_ADDRESS       0x57e884
+#define AR6003_REV2_RAM_RESERVE_SIZE            6912
+
+#define AR6003_REV3_APP_START_OVERRIDE          0x945d00
+#define AR6003_REV3_APP_LOAD_ADDRESS            0x545000
+#define AR6003_REV3_BOARD_EXT_DATA_ADDRESS      0x542330
+#define AR6003_REV3_DATASET_PATCH_ADDRESS       0x57FF74
+#define AR6003_REV3_RAM_RESERVE_SIZE            512
 
+#define AR6003_BOARD_EXT_DATA_ADDRESS           0x57E600
 
 /* # of u32 entries in targregs, used by DIAG_FETCH_TARG_REGS */
 #define AR6003_FETCH_TARG_REGS_COUNT 64
 
 #endif /* !__ASSEMBLER__ */
 
-#ifndef ATH_TARGET
-#include "athendpack.h"
-#endif
-
 #endif /* __TARGADDRS_H__ */
diff -druN linux-2.6.39-libre/drivers/staging/ath6kl/include/common/wlan_dset.h linux-3.0-rc7-libre/drivers/staging/ath6kl/include/common/wlan_dset.h
--- linux-2.6.39-libre/drivers/staging/ath6kl/include/common/wlan_dset.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/ath6kl/include/common/wlan_dset.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,33 +0,0 @@
-//------------------------------------------------------------------------------
-// Copyright (c) 2007-2010 Atheros Corporation.  All rights reserved.
-// 
-//
-// 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.
-//
-//
-//------------------------------------------------------------------------------
-//==============================================================================
-// Author(s): ="Atheros"
-//==============================================================================
-
-#ifndef __WLAN_DSET_H__
-#define __WLAN_DSET_H__
-
-typedef PREPACK struct wow_config_dset {
-
-    u8 valid_dset;
-    u8 gpio_enable;
-    u16 gpio_pin;
-} POSTPACK WOW_CONFIG_DSET;
-
-#endif
diff -druN linux-2.6.39-libre/drivers/staging/ath6kl/include/common/wmi.h linux-3.0-rc7-libre/drivers/staging/ath6kl/include/common/wmi.h
--- linux-2.6.39-libre/drivers/staging/ath6kl/include/common/wmi.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/ath6kl/include/common/wmi.h	2011-07-11 19:51:52.000000000 -0400
@@ -34,10 +34,6 @@
 #ifndef _WMI_H_
 #define _WMI_H_
 
-#ifndef ATH_TARGET
-#include "athstartpack.h"
-#endif
-
 #include "wmix.h"
 #include "wlan_defs.h"
 
@@ -118,7 +114,7 @@
 typedef enum {
     WMI_DATA_HDR_DATA_TYPE_802_3 = 0,
     WMI_DATA_HDR_DATA_TYPE_802_11,
-    WMI_DATA_HDR_DATA_TYPE_ACL,
+    WMI_DATA_HDR_DATA_TYPE_ACL, /* used to be used for the PAL */
 } WMI_DATA_HDR_DATA_TYPE;
 
 #define WMI_DATA_HDR_DATA_TYPE_MASK     0x3
@@ -159,6 +155,16 @@
 #define WMI_DATA_HDR_GET_META(h)        (((h)->info2 >> WMI_DATA_HDR_META_SHIFT) & WMI_DATA_HDR_META_MASK)
 #define WMI_DATA_HDR_SET_META(h, _v)    ((h)->info2 = ((h)->info2 & ~(WMI_DATA_HDR_META_MASK << WMI_DATA_HDR_META_SHIFT)) | ((_v) << WMI_DATA_HDR_META_SHIFT))
 
+/* Macros for operating on WMI_DATA_HDR (info3) field */
+#define WMI_DATA_HDR_DEVID_MASK      0xF
+#define WMI_DATA_HDR_DEVID_SHIFT     0
+#define GET_DEVID(_v)                ((_v) & WMI_DATA_HDR_DEVID_MASK)
+
+#define WMI_DATA_HDR_GET_DEVID(h) \
+	(((h)->info3 >> WMI_DATA_HDR_DEVID_SHIFT) & WMI_DATA_HDR_DEVID_MASK)
+#define WMI_DATA_HDR_SET_DEVID(h, _v) \
+	((h)->info3 = ((h)->info3 & ~(WMI_DATA_HDR_DEVID_MASK << WMI_DATA_HDR_DEVID_SHIFT)) | (GET_DEVID(_v) << WMI_DATA_HDR_DEVID_SHIFT))
+
 typedef PREPACK struct {
     s8 rssi;
     u8 info;               /* usage of 'info' field(8-bit):
@@ -175,7 +181,7 @@
                                      * b12          - A-MSDU?
                                      * b15:b13      - META_DATA_VERSION 0 - 7
                                      */
-    u16 reserved;
+    u16 info3;
 } POSTPACK WMI_DATA_HDR;
 
 /*
@@ -259,6 +265,17 @@
 
 
 #define WMI_GET_DEVICE_ID(info1) ((info1) & 0xF)
+/* Macros for operating on WMI_CMD_HDR (info1) field */
+#define WMI_CMD_HDR_DEVID_MASK      0xF
+#define WMI_CMD_HDR_DEVID_SHIFT     0
+#define GET_CMD_DEVID(_v)           ((_v) & WMI_CMD_HDR_DEVID_MASK)
+
+#define WMI_CMD_HDR_GET_DEVID(h) \
+	(((h)->info1 >> WMI_CMD_HDR_DEVID_SHIFT) & WMI_CMD_HDR_DEVID_MASK)
+#define WMI_CMD_HDR_SET_DEVID(h, _v) \
+	((h)->info1 = ((h)->info1 & \
+		~(WMI_CMD_HDR_DEVID_MASK << WMI_CMD_HDR_DEVID_SHIFT)) | \
+		 (GET_CMD_DEVID(_v) << WMI_CMD_HDR_DEVID_SHIFT))
 
 /*
  * Control Path
@@ -433,13 +450,47 @@
     WMI_SET_BTCOEX_BT_OPERATING_STATUS_CMDID,
     WMI_GET_BTCOEX_STATS_CMDID,
     WMI_GET_BTCOEX_CONFIG_CMDID,
-    WMI_GET_PMK_CMDID,
-    WMI_SET_PASSPHRASE_CMDID,
-    WMI_ENABLE_WAC_CMDID,
-    WMI_WAC_SCAN_REPLY_CMDID,
-    WMI_WAC_CTRL_REQ_CMDID,
-    WMI_SET_DIV_PARAMS_CMDID,
-    WMI_SET_EXCESS_TX_RETRY_THRES_CMDID,
+
+	WMI_SET_DFS_ENABLE_CMDID,   /* F034 */
+	WMI_SET_DFS_MINRSSITHRESH_CMDID,
+	WMI_SET_DFS_MAXPULSEDUR_CMDID,
+	WMI_DFS_RADAR_DETECTED_CMDID,
+
+	/* P2P CMDS */
+	WMI_P2P_SET_CONFIG_CMDID,    /* F038 */
+	WMI_WPS_SET_CONFIG_CMDID,
+	WMI_SET_REQ_DEV_ATTR_CMDID,
+	WMI_P2P_FIND_CMDID,
+	WMI_P2P_STOP_FIND_CMDID,
+	WMI_P2P_GO_NEG_START_CMDID,
+	WMI_P2P_LISTEN_CMDID,
+
+	WMI_CONFIG_TX_MAC_RULES_CMDID,    /* F040 */
+	WMI_SET_PROMISCUOUS_MODE_CMDID,
+	WMI_RX_FRAME_FILTER_CMDID,
+	WMI_SET_CHANNEL_CMDID,
+
+	/* WAC commands */
+	WMI_ENABLE_WAC_CMDID,
+	WMI_WAC_SCAN_REPLY_CMDID,
+	WMI_WAC_CTRL_REQ_CMDID,
+	WMI_SET_DIV_PARAMS_CMDID,
+
+	WMI_GET_PMK_CMDID,
+	WMI_SET_PASSPHRASE_CMDID,
+	WMI_SEND_ASSOC_RES_CMDID,
+	WMI_SET_ASSOC_REQ_RELAY_CMDID,
+	WMI_GET_RFKILL_MODE_CMDID,
+
+	/* ACS command, consists of sub-commands */
+	WMI_ACS_CTRL_CMDID,
+
+	/* Ultra low power store / recall commands */
+	WMI_STORERECALL_CONFIGURE_CMDID,
+	WMI_STORERECALL_RECALL_CMDID,
+	WMI_STORERECALL_HOST_READY_CMDID,
+	WMI_FORCE_TARGET_ASSERT_CMDID,
+	WMI_SET_EXCESS_TX_RETRY_THRES_CMDID,
 } WMI_COMMAND_ID;
 
 /*
@@ -470,6 +521,11 @@
     LEAP_AUTH           = 0x04,  /* different from IEEE_AUTH_MODE definitions */
 } DOT11_AUTH_MODE;
 
+enum {
+	AUTH_IDLE,
+	AUTH_OPEN_IN_PROGRESS,
+};
+
 typedef enum {
     NONE_AUTH           = 0x01,
     WPA_AUTH            = 0x02,
@@ -560,7 +616,7 @@
  * WMI_SET_EXCESS_TX_RETRY_THRES_CMDID
  */
 typedef PREPACK struct {
-    A_UINT32 threshold;
+    u32 threshold;
 } POSTPACK WMI_SET_EXCESS_TX_RETRY_THRES_CMD;
 
 /*
@@ -1969,12 +2025,47 @@
 #endif
     WMI_REPORT_BTCOEX_STATS_EVENTID,
     WMI_REPORT_BTCOEX_CONFIG_EVENTID,
-    WMI_ACM_REJECT_EVENTID,
-    WMI_THIN_RESERVED_START_EVENTID = 0x8000,
-    /* Events in this range are reserved for thinmode 
-     * See wmi_thin.h for actual definitions */
-    WMI_THIN_RESERVED_END_EVENTID = 0x8fff,
+	WMI_GET_PMK_EVENTID,
+
+	/* DFS Events */
+	WMI_DFS_HOST_ATTACH_EVENTID,
+	WMI_DFS_HOST_INIT_EVENTID,
+	WMI_DFS_RESET_DELAYLINES_EVENTID,
+	WMI_DFS_RESET_RADARQ_EVENTID,
+	WMI_DFS_RESET_AR_EVENTID,
+	WMI_DFS_RESET_ARQ_EVENTID,
+	WMI_DFS_SET_DUR_MULTIPLIER_EVENTID,
+	WMI_DFS_SET_BANGRADAR_EVENTID,
+	WMI_DFS_SET_DEBUGLEVEL_EVENTID,
+	WMI_DFS_PHYERR_EVENTID,
+	/* CCX Evants */
+	WMI_CCX_RM_STATUS_EVENTID,
+
+	/* P2P Events */
+	WMI_P2P_GO_NEG_RESULT_EVENTID,
+
+	WMI_WAC_SCAN_DONE_EVENTID,
+	WMI_WAC_REPORT_BSS_EVENTID,
+	WMI_WAC_START_WPS_EVENTID,
+	WMI_WAC_CTRL_REQ_REPLY_EVENTID,
+
+	/* RFKILL Events */
+	WMI_RFKILL_STATE_CHANGE_EVENTID,
+	WMI_RFKILL_GET_MODE_CMD_EVENTID,
+	WMI_THIN_RESERVED_START_EVENTID = 0x8000,
 
+	/*
+	 * Events in this range are reserved for thinmode
+	 * See wmi_thin.h for actual definitions
+	 */
+	WMI_THIN_RESERVED_END_EVENTID = 0x8fff,
+
+	WMI_SET_CHANNEL_EVENTID,
+	WMI_ASSOC_REQ_EVENTID,
+
+	/* generic ACS event */
+	WMI_ACS_EVENTID,
+	WMI_REPORT_WMM_PARAMS_EVENTID
 } WMI_EVENT_ID;
 
 
@@ -3122,10 +3213,6 @@
  * End of AP mode definitions
  */
 
-#ifndef ATH_TARGET
-#include "athendpack.h"
-#endif
-
 #ifdef __cplusplus
 }
 #endif
diff -druN linux-2.6.39-libre/drivers/staging/ath6kl/include/common/wmi_thin.h linux-3.0-rc7-libre/drivers/staging/ath6kl/include/common/wmi_thin.h
--- linux-2.6.39-libre/drivers/staging/ath6kl/include/common/wmi_thin.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/ath6kl/include/common/wmi_thin.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,347 +0,0 @@
-//------------------------------------------------------------------------------
-// <copyright file="wmi_thin.h" company="Atheros">
-//    Copyright (c) 2004-2010 Atheros Corporation.  All rights reserved.
-// 
-//
-// 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.
-//
-//
-//------------------------------------------------------------------------------
-//==============================================================================
-// Author(s): ="Atheros"
-//==============================================================================
-
-/*
- * This file contains the definitions of the WMI protocol specified in the
- * Wireless Module Interface (WMI).  It includes definitions of all the
- * commands and events. Commands are messages from the host to the WM.
- * Events and Replies are messages from the WM to the host.
- *
- * Ownership of correctness in regards to WMI commands
- * belongs to the host driver and the WM is not required to validate
- * parameters for value, proper range, or any other checking.
- *
- */
-
-#ifndef _WMI_THIN_H_
-#define _WMI_THIN_H_
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
-typedef enum {
-    WMI_THIN_CONFIG_CMDID =  0x8000, // WMI_THIN_RESERVED_START 
-    WMI_THIN_SET_MIB_CMDID,
-    WMI_THIN_GET_MIB_CMDID,
-    WMI_THIN_JOIN_CMDID,
-    /* add new CMDID's here */
-    WMI_THIN_RESERVED_END_CMDID = 0x8fff // WMI_THIN_RESERVED_END
-} WMI_THIN_COMMAND_ID;
-
-typedef enum{
-    TEMPLATE_FRM_FIRST = 0,
-    TEMPLATE_FRM_PROBE_REQ =TEMPLATE_FRM_FIRST,
-    TEMPLATE_FRM_BEACON,
-    TEMPLATE_FRM_PROBE_RESP,
-    TEMPLATE_FRM_NULL,
-    TEMPLATE_FRM_QOS_NULL,
-    TEMPLATE_FRM_PSPOLL,
-    TEMPLATE_FRM_MAX
-}WMI_TEMPLATE_FRM_TYPE;
-
-/* TEMPLATE_FRM_LEN... represent the maximum allowable
- * data lengths (bytes) for each frame type */
-#define TEMPLATE_FRM_LEN_PROBE_REQ  (256) /* Symbian dictates a minimum of 256 for these 3 frame types */
-#define TEMPLATE_FRM_LEN_BEACON     (256)
-#define TEMPLATE_FRM_LEN_PROBE_RESP (256)
-#define TEMPLATE_FRM_LEN_NULL       (32)
-#define TEMPLATE_FRM_LEN_QOS_NULL   (32)
-#define TEMPLATE_FRM_LEN_PSPOLL     (32)
-#define TEMPLATE_FRM_LEN_SUM (TEMPLATE_FRM_LEN_PROBE_REQ + TEMPLATE_FRM_LEN_BEACON + TEMPLATE_FRM_LEN_PROBE_RESP + \
-            TEMPLATE_FRM_LEN_NULL + TEMPLATE_FRM_LEN_QOS_NULL + TEMPLATE_FRM_LEN_PSPOLL)
-
-
-/* MAC Header Build Rules */
-/*  These values allow the host to configure the 
- *  target code that is responsible for constructing
- *  the MAC header.  In cases where the MAC header
- *  is provided by the host framework, the target
- *  has a diminished responsibility over what fields
- *  it must write. This will vary from framework to framework.
- *  Symbian requires different behavior from MAC80211 which
- *  requires different behavior from MS Native Wifi. */
-#define WMI_WRT_VER_TYPE    0x00000001
-#define WMI_WRT_DURATION    0x00000002
-#define WMI_WRT_DIRECTION   0x00000004
-#define WMI_WRT_POWER       0x00000008
-#define WMI_WRT_WEP         0x00000010
-#define WMI_WRT_MORE        0x00000020
-#define WMI_WRT_BSSID       0x00000040
-#define WMI_WRT_QOS         0x00000080
-#define WMI_WRT_SEQNO       0x00000100
-#define WMI_GUARD_TX        0x00000200 /* prevents TX ops that are not allowed for a current state */
-#define WMI_WRT_DEFAULT_CONFIG  (WMI_WRT_VER_TYPE | WMI_WRT_DURATION | WMI_WRT_DIRECTION | \
-                                 WMI_WRT_POWER | WMI_WRT_MORE | WMI_WRT_WEP | WMI_WRT_BSSID | \
-                                 WMI_WRT_QOS | WMI_WRT_SEQNO | WMI_GUARD_TX)
-
-/* WMI_THIN_CONFIG_TXCOMPLETE -- Used to configure the params and content for 
- *  TX Complete messages the will come from the Target.  these messages are 
- *  disabled by default but can be enabled using this structure and the 
- *  WMI_THIN_CONFIG_CMDID. */
-typedef PREPACK struct {
-    u8 version; /* the versioned type of messages to use or 0 to disable */
-    u8 countThreshold; /* msg count threshold triggering a tx complete message */
-    u16 timeThreshold; /* timeout interval in MSEC triggering a tx complete message */
-} POSTPACK WMI_THIN_CONFIG_TXCOMPLETE;
-
-/* WMI_THIN_CONFIG_DECRYPT_ERR -- Used to configure behavior for received frames 
- *  that have decryption errors.  The default behavior is to discard the frame
- *  without notification. Alternately, the MAC Header is forwarded to the host 
- *  with the failed status. */
-typedef PREPACK struct {
-    u8 enable; /* 1 == send decrypt errors to the host, 0 == don't */
-    u8 reserved[3]; /* align padding */
-} POSTPACK WMI_THIN_CONFIG_DECRYPT_ERR;
-
-/* WMI_THIN_CONFIG_TX_MAC_RULES -- Used to configure behavior for transmitted
- *  frames that require partial MAC header construction. These rules 
- *  are used by the target to indicate which fields need to be written. */
-typedef PREPACK struct {
-    u32 rules; /* combination of WMI_WRT_... values */
-} POSTPACK WMI_THIN_CONFIG_TX_MAC_RULES;
-
-/* WMI_THIN_CONFIG_RX_FILTER_RULES -- Used to configure behavior for received
- *  frames as to which frames should get forwarded to the host and which
- *  should get processed internally. */
-typedef PREPACK struct {
-    u32 rules; /* combination of WMI_FILT_... values */
-} POSTPACK WMI_THIN_CONFIG_RX_FILTER_RULES;
-
-/* WMI_THIN_CONFIG_CMD -- Used to contain some combination of the above
- *  WMI_THIN_CONFIG_... structures. The actual combination is indicated 
- *  by the value of cfgField. Each bit in this field corresponds to 
- *  one of the above structures. */
-typedef PREPACK struct {
-#define WMI_THIN_CFG_TXCOMP         0x00000001
-#define WMI_THIN_CFG_DECRYPT        0x00000002
-#define WMI_THIN_CFG_MAC_RULES      0x00000004
-#define WMI_THIN_CFG_FILTER_RULES   0x00000008
-    u32 cfgField;   /* combination of WMI_THIN_CFG_... describes contents of config command */
-    u16 length;     /* length in bytes of appended sub-commands */
-    u8 reserved[2];   /* align padding */
-} POSTPACK WMI_THIN_CONFIG_CMD;
-
-/* MIB Access Identifiers tailored for Symbian. */
-enum {
-    MIB_ID_STA_MAC = 1,             // [READONLY]
-    MIB_ID_RX_LIFE_TIME,            // [NOT IMPLEMENTED]
-    MIB_ID_SLOT_TIME,               // [READ/WRITE]
-    MIB_ID_RTS_THRESHOLD,           // [READ/WRITE]
-    MIB_ID_CTS_TO_SELF,             // [READ/WRITE]
-    MIB_ID_TEMPLATE_FRAME,          // [WRITE ONLY]
-    MIB_ID_RXFRAME_FILTER,          // [READ/WRITE]
-    MIB_ID_BEACON_FILTER_TABLE,     // [WRITE ONLY]
-    MIB_ID_BEACON_FILTER,           // [READ/WRITE]
-    MIB_ID_BEACON_LOST_COUNT,       // [WRITE ONLY]
-    MIB_ID_RSSI_THRESHOLD,          // [WRITE ONLY]
-    MIB_ID_HT_CAP,                  // [NOT IMPLEMENTED]
-    MIB_ID_HT_OP,                   // [NOT IMPLEMENTED]
-    MIB_ID_HT_2ND_BEACON,           // [NOT IMPLEMENTED]
-    MIB_ID_HT_BLOCK_ACK,            // [NOT IMPLEMENTED]
-    MIB_ID_PREAMBLE,                // [READ/WRITE]
-    /*MIB_ID_GROUP_ADDR_TABLE,*/
-    /*MIB_ID_WEP_DEFAULT_KEY_ID */
-    /*MIB_ID_TX_POWER */
-    /*MIB_ID_ARP_IP_TABLE */
-    /*MIB_ID_SLEEP_MODE */
-    /*MIB_ID_WAKE_INTERVAL*/
-    /*MIB_ID_STAT_TABLE*/
-    /*MIB_ID_IBSS_PWR_SAVE*/
-    /*MIB_ID_COUNTERS_TABLE*/
-    /*MIB_ID_ETHERTYPE_FILTER*/
-    /*MIB_ID_BC_UDP_FILTER*/
-       
-};
-
-typedef PREPACK struct {
-    u8 addr[ATH_MAC_LEN];
-} POSTPACK WMI_THIN_MIB_STA_MAC;
-
-typedef PREPACK struct {
-    u32 time; // units == msec
-} POSTPACK WMI_THIN_MIB_RX_LIFE_TIME;
-
-typedef PREPACK struct {
-    u8 enable; //1 = on, 0 = off
-} POSTPACK WMI_THIN_MIB_CTS_TO_SELF;
-
-typedef PREPACK struct {
-    u32 time; // units == usec
-} POSTPACK WMI_THIN_MIB_SLOT_TIME;
-
-typedef PREPACK struct {
-    u16 length; //units == bytes
-} POSTPACK WMI_THIN_MIB_RTS_THRESHOLD;
-
-typedef PREPACK struct {
-    u8 type; // type of frame
-    u8 rate; // tx rate to be used (one of WMI_BIT_RATE)
-    u16 length; // num bytes following this structure as the template data
-} POSTPACK WMI_THIN_MIB_TEMPLATE_FRAME;
-
-typedef PREPACK struct {
-#define FRAME_FILTER_PROMISCUOUS 0x00000001
-#define FRAME_FILTER_BSSID       0x00000002
-    u32 filterMask;
-} POSTPACK WMI_THIN_MIB_RXFRAME_FILTER;
-
-
-#define IE_FILTER_TREATMENT_CHANGE 1
-#define IE_FILTER_TREATMENT_APPEAR 2
-
-typedef PREPACK struct {
-    u8 ie;
-    u8 treatment;
-} POSTPACK WMI_THIN_MIB_BEACON_FILTER_TABLE;
-
-typedef PREPACK struct {
-    u8 ie;
-    u8 treatment;
-    u8 oui[3];
-    u8 type;
-    u16 version;
-} POSTPACK WMI_THIN_MIB_BEACON_FILTER_TABLE_OUI;
-
-typedef PREPACK struct {
-    u16 numElements;
-    u8 entrySize; // sizeof(WMI_THIN_MIB_BEACON_FILTER_TABLE) on host cpu may be 2 may be 4
-    u8 reserved;
-} POSTPACK WMI_THIN_MIB_BEACON_FILTER_TABLE_HEADER; 
-
-typedef PREPACK struct {
-    u32 count; /* num beacons between deliveries */
-    u8 enable;
-    u8 reserved[3];
-} POSTPACK WMI_THIN_MIB_BEACON_FILTER;
-
-typedef PREPACK struct {
-    u32 count; /* num consec lost beacons after which send event */
-} POSTPACK WMI_THIN_MIB_BEACON_LOST_COUNT;
-
-typedef PREPACK struct {
-    u8 rssi; /* the low threshold which can trigger an event warning */
-    u8 tolerance; /* the range above and below the threshold to prevent event flooding to the host. */
-    u8 count; /* the sample count of consecutive frames necessary to trigger an event. */
-    u8 reserved[1]; /* padding */
-} POSTPACK WMI_THIN_MIB_RSSI_THRESHOLD;
-
-
-typedef PREPACK struct {
-    u32 cap;
-    u32 rxRateField;
-    u32 beamForming;
-    u8 addr[ATH_MAC_LEN];
-    u8 enable;
-    u8 stbc;
-    u8 maxAMPDU;
-    u8 msduSpacing;
-    u8 mcsFeedback;
-    u8 antennaSelCap;
-} POSTPACK WMI_THIN_MIB_HT_CAP;
-
-typedef PREPACK struct {
-    u32 infoField;
-    u32 basicRateField;
-    u8 protection;
-    u8 secondChanneloffset;
-    u8 channelWidth;
-    u8 reserved;
-} POSTPACK WMI_THIN_MIB_HT_OP;
-
-typedef PREPACK struct {
-#define SECOND_BEACON_PRIMARY   1
-#define SECOND_BEACON_EITHER    2
-#define SECOND_BEACON_SECONDARY 3
-    u8 cfg;
-    u8 reserved[3]; /* padding */
-} POSTPACK WMI_THIN_MIB_HT_2ND_BEACON;
-
-typedef PREPACK struct {
-    u8 txTIDField;
-    u8 rxTIDField;
-    u8 reserved[2]; /* padding */
-} POSTPACK WMI_THIN_MIB_HT_BLOCK_ACK;
-
-typedef PREPACK struct {
-    u8 enableLong; // 1 == long preamble, 0 == short preamble
-    u8 reserved[3];
-} POSTPACK WMI_THIN_MIB_PREAMBLE;
-
-typedef PREPACK struct {    
-    u16 length;     /* the length in bytes of the appended MIB data */
-    u8 mibID;      /* the ID of the MIB element being set */
-    u8 reserved; /* align padding */
-} POSTPACK WMI_THIN_SET_MIB_CMD;
-
-typedef PREPACK struct {    
-    u8 mibID;      /* the ID of the MIB element being set */
-    u8 reserved[3]; /* align padding */
-} POSTPACK WMI_THIN_GET_MIB_CMD;
-
-typedef PREPACK struct {
-    u32 basicRateMask; /* bit mask of basic rates */
-    u32 beaconIntval; /* TUs */
-    u16 atimWindow; /* TUs */
-    u16 channel; /* frequency in Mhz */
-    u8 networkType; /* INFRA_NETWORK | ADHOC_NETWORK */
-    u8 ssidLength; /* 0 - 32 */
-    u8 probe;      /* != 0 : issue probe req at start */
-    u8 reserved;   /* alignment */
-    u8     ssid[WMI_MAX_SSID_LEN];    
-    u8 bssid[ATH_MAC_LEN];
-} POSTPACK WMI_THIN_JOIN_CMD;
-
-typedef PREPACK struct {
-    u16 dtim; /* dtim interval in num beacons */
-    u16 aid; /* 80211 AID from Assoc resp */
-} POSTPACK WMI_THIN_POST_ASSOC_CMD;
-
-typedef enum {
-    WMI_THIN_EVENTID_RESERVED_START           = 0x8000,
-    WMI_THIN_GET_MIB_EVENTID,
-    WMI_THIN_JOIN_EVENTID,
-    
-    /* Add new THIN EVENTID's here */
-    WMI_THIN_EVENTID_RESERVED_END           = 0x8fff    
-} WMI_THIN_EVENT_ID;
-
-/* Possible values for WMI_THIN_JOIN_EVENT.result */
-typedef enum {
-    WMI_THIN_JOIN_RES_SUCCESS = 0, // device has joined the network
-    WMI_THIN_JOIN_RES_FAIL, // device failed for unspecified reason
-    WMI_THIN_JOIN_RES_TIMEOUT, // device failed due to no beacon rx in time limit
-    WMI_THIN_JOIN_RES_BAD_PARAM, // device failed due to bad cmd param.
-}WMI_THIN_JOIN_RESULT;
-
-typedef PREPACK struct {
-    u8 result; /* the result of the join cmd. one of WMI_THIN_JOIN_RESULT */
-    u8 reserved[3]; /* alignment */
-} POSTPACK WMI_THIN_JOIN_EVENT;
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _WMI_THIN_H_ */
diff -druN linux-2.6.39-libre/drivers/staging/ath6kl/include/common/wmix.h linux-3.0-rc7-libre/drivers/staging/ath6kl/include/common/wmix.h
--- linux-2.6.39-libre/drivers/staging/ath6kl/include/common/wmix.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/ath6kl/include/common/wmix.h	2011-07-11 19:51:52.000000000 -0400
@@ -40,10 +40,6 @@
 extern "C" {
 #endif
 
-#ifndef ATH_TARGET
-#include "athstartpack.h"
-#endif
-
 #include "dbglog.h"
 
 /*
@@ -148,7 +144,6 @@
  * All masks are 18-bit masks with bit N operating on GPIO pin N.
  */
 
-#include "gpio.h"
 
 /*
  * Set GPIO pin output state.
@@ -268,9 +263,6 @@
     u32 count;
 } POSTPACK WMIX_PROF_COUNT_EVENT;
 
-#ifndef ATH_TARGET
-#include "athendpack.h"
-#endif
 
 #ifdef __cplusplus
 }
diff -druN linux-2.6.39-libre/drivers/staging/ath6kl/include/common_drv.h linux-3.0-rc7-libre/drivers/staging/ath6kl/include/common_drv.h
--- linux-2.6.39-libre/drivers/staging/ath6kl/include/common_drv.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/ath6kl/include/common_drv.h	2011-07-11 19:51:52.000000000 -0400
@@ -81,10 +81,6 @@
                                u32 MboxIsrYieldValue,
                                u8 HtcControlBuffers);
 
-int ar6000_prepare_target(struct hif_device *hifDevice,
-                               u32 TargetType,
-                               u32 TargetVersion);
-
 int ar6000_set_hci_bridge_flags(struct hif_device *hifDevice,
                                      u32 TargetType,
                                      u32 Flags);
diff -druN linux-2.6.39-libre/drivers/staging/ath6kl/include/gpio_api.h linux-3.0-rc7-libre/drivers/staging/ath6kl/include/gpio_api.h
--- linux-2.6.39-libre/drivers/staging/ath6kl/include/gpio_api.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/ath6kl/include/gpio_api.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,59 +0,0 @@
-//------------------------------------------------------------------------------
-// <copyright file="gpio_api.h" company="Atheros">
-//    Copyright (c) 2004-2010 Atheros Corporation.  All rights reserved.
-// 
-//
-// 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.
-//
-//
-//------------------------------------------------------------------------------
-//==============================================================================
-// Host-side General Purpose I/O API.
-//
-// Author(s): ="Atheros"
-//==============================================================================
-#ifndef _GPIO_API_H_
-#define _GPIO_API_H_
-
-/*
- * Send a command to the Target in order to change output on GPIO pins.
- */
-int wmi_gpio_output_set(struct wmi_t *wmip,
-                             u32 set_mask,
-                             u32 clear_mask,
-                             u32 enable_mask,
-                             u32 disable_mask);
-
-/*
- * Send a command to the Target requesting input state of GPIO pins.
- */
-int wmi_gpio_input_get(struct wmi_t *wmip);
-
-/*
- * Send a command to the Target to change the value of a GPIO register.
- */
-int wmi_gpio_register_set(struct wmi_t *wmip,
-                               u32 gpioreg_id,
-                               u32 value);
-
-/*
- * Send a command to the Target to fetch the value of a GPIO register.
- */
-int wmi_gpio_register_get(struct wmi_t *wmip, u32 gpioreg_id);
-
-/*
- * Send a command to the Target, acknowledging some GPIO interrupts.
- */
-int wmi_gpio_intr_ack(struct wmi_t *wmip, u32 ack_mask);
-
-#endif /* _GPIO_API_H_ */
diff -druN linux-2.6.39-libre/drivers/staging/ath6kl/include/hif.h linux-3.0-rc7-libre/drivers/staging/ath6kl/include/hif.h
--- linux-2.6.39-libre/drivers/staging/ath6kl/include/hif.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/ath6kl/include/hif.h	2011-07-11 19:51:52.000000000 -0400
@@ -32,7 +32,6 @@
 /* Header files */
 #include "a_config.h"
 #include "athdefs.h"
-#include "a_types.h"
 #include "a_osapi.h"
 #include "dl_list.h"
 
@@ -148,7 +147,7 @@
  *
  *   HIF_DEVICE_GET_MBOX_BLOCK_SIZE
  *   input : none
- *   output : array of 4 A_UINT32s
+ *   output : array of 4 u32s
  *   notes: block size is returned for each mailbox (4)
  *
  *   HIF_DEVICE_GET_MBOX_ADDR
diff -druN linux-2.6.39-libre/drivers/staging/ath6kl/include/target_reg_table.h linux-3.0-rc7-libre/drivers/staging/ath6kl/include/target_reg_table.h
--- linux-2.6.39-libre/drivers/staging/ath6kl/include/target_reg_table.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/ath6kl/include/target_reg_table.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,244 +0,0 @@
-//------------------------------------------------------------------------------
-// <copyright file="target_reg_table.h" company="Atheros">
-//    Copyright (c) 2004-2010 Atheros Corporation.  All rights reserved.
-// 
-//
-// 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.
-//
-//
-//------------------------------------------------------------------------------
-//==============================================================================
-// Target register table macros and structure definitions
-//
-// Author(s): ="Atheros"
-//==============================================================================
-
-#ifndef TARGET_REG_TABLE_H_
-#define TARGET_REG_TABLE_H_
-
-#include "targaddrs.h"
-
-/*** WARNING : Add to the end of the TABLE! do not change the order ****/
-typedef struct targetdef_s {
-    u32 d_RTC_BASE_ADDRESS;
-    u32 d_SYSTEM_SLEEP_OFFSET;
-    u32 d_SYSTEM_SLEEP_DISABLE_LSB;
-    u32 d_SYSTEM_SLEEP_DISABLE_MASK;
-    u32 d_CLOCK_CONTROL_OFFSET;
-    u32 d_CLOCK_CONTROL_SI0_CLK_MASK;
-    u32 d_RESET_CONTROL_OFFSET;
-    u32 d_RESET_CONTROL_SI0_RST_MASK;
-    u32 d_GPIO_BASE_ADDRESS;
-    u32 d_GPIO_PIN0_OFFSET;
-    u32 d_GPIO_PIN1_OFFSET;
-    u32 d_GPIO_PIN0_CONFIG_MASK;
-    u32 d_GPIO_PIN1_CONFIG_MASK;
-    u32 d_SI_CONFIG_BIDIR_OD_DATA_LSB;
-    u32 d_SI_CONFIG_BIDIR_OD_DATA_MASK;
-    u32 d_SI_CONFIG_I2C_LSB;
-    u32 d_SI_CONFIG_I2C_MASK;
-    u32 d_SI_CONFIG_POS_SAMPLE_LSB;
-    u32 d_SI_CONFIG_POS_SAMPLE_MASK;
-    u32 d_SI_CONFIG_INACTIVE_CLK_LSB;
-    u32 d_SI_CONFIG_INACTIVE_CLK_MASK;
-    u32 d_SI_CONFIG_INACTIVE_DATA_LSB;
-    u32 d_SI_CONFIG_INACTIVE_DATA_MASK;
-    u32 d_SI_CONFIG_DIVIDER_LSB;
-    u32 d_SI_CONFIG_DIVIDER_MASK;
-    u32 d_SI_BASE_ADDRESS;
-    u32 d_SI_CONFIG_OFFSET;
-    u32 d_SI_TX_DATA0_OFFSET;
-    u32 d_SI_TX_DATA1_OFFSET;
-    u32 d_SI_RX_DATA0_OFFSET;
-    u32 d_SI_RX_DATA1_OFFSET;
-    u32 d_SI_CS_OFFSET;
-    u32 d_SI_CS_DONE_ERR_MASK;
-    u32 d_SI_CS_DONE_INT_MASK;
-    u32 d_SI_CS_START_LSB;
-    u32 d_SI_CS_START_MASK;
-    u32 d_SI_CS_RX_CNT_LSB;
-    u32 d_SI_CS_RX_CNT_MASK;
-    u32 d_SI_CS_TX_CNT_LSB;
-    u32 d_SI_CS_TX_CNT_MASK;
-    u32 d_BOARD_DATA_SZ;
-    u32 d_BOARD_EXT_DATA_SZ;
-} TARGET_REGISTER_TABLE;
-
-#define BOARD_DATA_SZ_MAX 2048
-
-#if defined(MY_TARGET_DEF) /* { */
-
-#ifdef ATH_REG_TABLE_DIRECT_ASSIGN
-
-static struct targetdef_s my_target_def = {
-    RTC_BASE_ADDRESS,
-    SYSTEM_SLEEP_OFFSET,
-    SYSTEM_SLEEP_DISABLE_LSB,
-    SYSTEM_SLEEP_DISABLE_MASK,
-    CLOCK_CONTROL_OFFSET,
-    CLOCK_CONTROL_SI0_CLK_MASK,
-    RESET_CONTROL_OFFSET,
-    RESET_CONTROL_SI0_RST_MASK,
-    GPIO_BASE_ADDRESS,
-    GPIO_PIN0_OFFSET,
-    GPIO_PIN0_CONFIG_MASK,
-    GPIO_PIN1_OFFSET,
-    GPIO_PIN1_CONFIG_MASK,
-    SI_CONFIG_BIDIR_OD_DATA_LSB,
-    SI_CONFIG_BIDIR_OD_DATA_MASK,
-    SI_CONFIG_I2C_LSB,
-    SI_CONFIG_I2C_MASK,
-    SI_CONFIG_POS_SAMPLE_LSB,
-    SI_CONFIG_POS_SAMPLE_MASK,
-    SI_CONFIG_INACTIVE_CLK_LSB,
-    SI_CONFIG_INACTIVE_CLK_MASK,
-    SI_CONFIG_INACTIVE_DATA_LSB,
-    SI_CONFIG_INACTIVE_DATA_MASK,
-    SI_CONFIG_DIVIDER_LSB,
-    SI_CONFIG_DIVIDER_MASK,
-    SI_BASE_ADDRESS,
-    SI_CONFIG_OFFSET,
-    SI_TX_DATA0_OFFSET,
-    SI_TX_DATA1_OFFSET,
-    SI_RX_DATA0_OFFSET,
-    SI_RX_DATA1_OFFSET,
-    SI_CS_OFFSET,
-    SI_CS_DONE_ERR_MASK,
-    SI_CS_DONE_INT_MASK,
-    SI_CS_START_LSB,
-    SI_CS_START_MASK,
-    SI_CS_RX_CNT_LSB,
-    SI_CS_RX_CNT_MASK,
-    SI_CS_TX_CNT_LSB,
-    SI_CS_TX_CNT_MASK,
-    MY_TARGET_BOARD_DATA_SZ,
-    MY_TARGET_BOARD_EXT_DATA_SZ,
-};
-
-#else
-
-static struct targetdef_s my_target_def = {
-    .d_RTC_BASE_ADDRESS = RTC_BASE_ADDRESS,
-    .d_SYSTEM_SLEEP_OFFSET = SYSTEM_SLEEP_OFFSET,
-    .d_SYSTEM_SLEEP_DISABLE_LSB = SYSTEM_SLEEP_DISABLE_LSB,
-    .d_SYSTEM_SLEEP_DISABLE_MASK = SYSTEM_SLEEP_DISABLE_MASK,
-    .d_CLOCK_CONTROL_OFFSET = CLOCK_CONTROL_OFFSET,
-    .d_CLOCK_CONTROL_SI0_CLK_MASK = CLOCK_CONTROL_SI0_CLK_MASK,
-    .d_RESET_CONTROL_OFFSET = RESET_CONTROL_OFFSET,
-    .d_RESET_CONTROL_SI0_RST_MASK = RESET_CONTROL_SI0_RST_MASK,
-    .d_GPIO_BASE_ADDRESS = GPIO_BASE_ADDRESS,
-    .d_GPIO_PIN0_OFFSET = GPIO_PIN0_OFFSET,
-    .d_GPIO_PIN0_CONFIG_MASK = GPIO_PIN0_CONFIG_MASK,
-    .d_GPIO_PIN1_OFFSET = GPIO_PIN1_OFFSET,
-    .d_GPIO_PIN1_CONFIG_MASK = GPIO_PIN1_CONFIG_MASK,
-    .d_SI_CONFIG_BIDIR_OD_DATA_LSB = SI_CONFIG_BIDIR_OD_DATA_LSB,
-    .d_SI_CONFIG_BIDIR_OD_DATA_MASK = SI_CONFIG_BIDIR_OD_DATA_MASK,
-    .d_SI_CONFIG_I2C_LSB = SI_CONFIG_I2C_LSB,
-    .d_SI_CONFIG_I2C_MASK = SI_CONFIG_I2C_MASK,
-    .d_SI_CONFIG_POS_SAMPLE_LSB = SI_CONFIG_POS_SAMPLE_LSB,
-    .d_SI_CONFIG_POS_SAMPLE_MASK = SI_CONFIG_POS_SAMPLE_MASK,
-    .d_SI_CONFIG_INACTIVE_CLK_LSB = SI_CONFIG_INACTIVE_CLK_LSB,
-    .d_SI_CONFIG_INACTIVE_CLK_MASK = SI_CONFIG_INACTIVE_CLK_MASK,
-    .d_SI_CONFIG_INACTIVE_DATA_LSB = SI_CONFIG_INACTIVE_DATA_LSB,
-    .d_SI_CONFIG_INACTIVE_DATA_MASK = SI_CONFIG_INACTIVE_DATA_MASK,
-    .d_SI_CONFIG_DIVIDER_LSB = SI_CONFIG_DIVIDER_LSB,
-    .d_SI_CONFIG_DIVIDER_MASK = SI_CONFIG_DIVIDER_MASK,
-    .d_SI_BASE_ADDRESS = SI_BASE_ADDRESS,
-    .d_SI_CONFIG_OFFSET = SI_CONFIG_OFFSET,
-    .d_SI_TX_DATA0_OFFSET = SI_TX_DATA0_OFFSET,
-    .d_SI_TX_DATA1_OFFSET = SI_TX_DATA1_OFFSET,
-    .d_SI_RX_DATA0_OFFSET = SI_RX_DATA0_OFFSET,
-    .d_SI_RX_DATA1_OFFSET = SI_RX_DATA1_OFFSET,
-    .d_SI_CS_OFFSET = SI_CS_OFFSET,
-    .d_SI_CS_DONE_ERR_MASK = SI_CS_DONE_ERR_MASK,
-    .d_SI_CS_DONE_INT_MASK = SI_CS_DONE_INT_MASK,
-    .d_SI_CS_START_LSB = SI_CS_START_LSB,
-    .d_SI_CS_START_MASK = SI_CS_START_MASK,
-    .d_SI_CS_RX_CNT_LSB = SI_CS_RX_CNT_LSB,
-    .d_SI_CS_RX_CNT_MASK = SI_CS_RX_CNT_MASK,
-    .d_SI_CS_TX_CNT_LSB = SI_CS_TX_CNT_LSB,
-    .d_SI_CS_TX_CNT_MASK = SI_CS_TX_CNT_MASK,
-    .d_BOARD_DATA_SZ = MY_TARGET_BOARD_DATA_SZ,
-    .d_BOARD_EXT_DATA_SZ = MY_TARGET_BOARD_EXT_DATA_SZ,
-};
-
-#endif
-
-#if MY_TARGET_BOARD_DATA_SZ > BOARD_DATA_SZ_MAX
-#error "BOARD_DATA_SZ_MAX is too small"
-#endif
-
-struct targetdef_s *MY_TARGET_DEF = &my_target_def;
-
-#else /* } { */
-
-#define RTC_BASE_ADDRESS (targetdef->d_RTC_BASE_ADDRESS)
-#define SYSTEM_SLEEP_OFFSET (targetdef->d_SYSTEM_SLEEP_OFFSET)
-#define SYSTEM_SLEEP_DISABLE_LSB (targetdef->d_SYSTEM_SLEEP_DISABLE_LSB)
-#define SYSTEM_SLEEP_DISABLE_MASK (targetdef->d_SYSTEM_SLEEP_DISABLE_MASK)
-#define CLOCK_CONTROL_OFFSET (targetdef->d_CLOCK_CONTROL_OFFSET)
-#define CLOCK_CONTROL_SI0_CLK_MASK (targetdef->d_CLOCK_CONTROL_SI0_CLK_MASK)
-#define RESET_CONTROL_OFFSET (targetdef->d_RESET_CONTROL_OFFSET)
-#define RESET_CONTROL_SI0_RST_MASK (targetdef->d_RESET_CONTROL_SI0_RST_MASK)
-#define GPIO_BASE_ADDRESS (targetdef->d_GPIO_BASE_ADDRESS)
-#define GPIO_PIN0_OFFSET (targetdef->d_GPIO_PIN0_OFFSET)
-#define GPIO_PIN0_CONFIG_MASK (targetdef->d_GPIO_PIN0_CONFIG_MASK)
-#define GPIO_PIN1_OFFSET (targetdef->d_GPIO_PIN1_OFFSET)
-#define GPIO_PIN1_CONFIG_MASK (targetdef->d_GPIO_PIN1_CONFIG_MASK)
-#define SI_CONFIG_BIDIR_OD_DATA_LSB (targetdef->d_SI_CONFIG_BIDIR_OD_DATA_LSB)
-#define SI_CONFIG_BIDIR_OD_DATA_MASK (targetdef->d_SI_CONFIG_BIDIR_OD_DATA_MASK)
-#define SI_CONFIG_I2C_LSB (targetdef->d_SI_CONFIG_I2C_LSB)
-#define SI_CONFIG_I2C_MASK (targetdef->d_SI_CONFIG_I2C_MASK)
-#define SI_CONFIG_POS_SAMPLE_LSB (targetdef->d_SI_CONFIG_POS_SAMPLE_LSB)
-#define SI_CONFIG_POS_SAMPLE_MASK (targetdef->d_SI_CONFIG_POS_SAMPLE_MASK)
-#define SI_CONFIG_INACTIVE_CLK_LSB (targetdef->d_SI_CONFIG_INACTIVE_CLK_LSB)
-#define SI_CONFIG_INACTIVE_CLK_MASK (targetdef->d_SI_CONFIG_INACTIVE_CLK_MASK)
-#define SI_CONFIG_INACTIVE_DATA_LSB (targetdef->d_SI_CONFIG_INACTIVE_DATA_LSB)
-#define SI_CONFIG_INACTIVE_DATA_MASK (targetdef->d_SI_CONFIG_INACTIVE_DATA_MASK)
-#define SI_CONFIG_DIVIDER_LSB (targetdef->d_SI_CONFIG_DIVIDER_LSB)
-#define SI_CONFIG_DIVIDER_MASK (targetdef->d_SI_CONFIG_DIVIDER_MASK)
-#define SI_BASE_ADDRESS (targetdef->d_SI_BASE_ADDRESS)
-#define SI_CONFIG_OFFSET (targetdef->d_SI_CONFIG_OFFSET)
-#define SI_TX_DATA0_OFFSET (targetdef->d_SI_TX_DATA0_OFFSET)
-#define SI_TX_DATA1_OFFSET (targetdef->d_SI_TX_DATA1_OFFSET)
-#define SI_RX_DATA0_OFFSET (targetdef->d_SI_RX_DATA0_OFFSET)
-#define SI_RX_DATA1_OFFSET (targetdef->d_SI_RX_DATA1_OFFSET)
-#define SI_CS_OFFSET (targetdef->d_SI_CS_OFFSET)
-#define SI_CS_DONE_ERR_MASK (targetdef->d_SI_CS_DONE_ERR_MASK)
-#define SI_CS_DONE_INT_MASK (targetdef->d_SI_CS_DONE_INT_MASK)
-#define SI_CS_START_LSB (targetdef->d_SI_CS_START_LSB)
-#define SI_CS_START_MASK (targetdef->d_SI_CS_START_MASK)
-#define SI_CS_RX_CNT_LSB (targetdef->d_SI_CS_RX_CNT_LSB)
-#define SI_CS_RX_CNT_MASK (targetdef->d_SI_CS_RX_CNT_MASK)
-#define SI_CS_TX_CNT_LSB (targetdef->d_SI_CS_TX_CNT_LSB)
-#define SI_CS_TX_CNT_MASK (targetdef->d_SI_CS_TX_CNT_MASK)
-#define EEPROM_SZ (targetdef->d_BOARD_DATA_SZ)
-#define EEPROM_EXT_SZ (targetdef->d_BOARD_EXT_DATA_SZ)
-
-/* SET macros */
-#define SYSTEM_SLEEP_DISABLE_SET(x)              (((x) << SYSTEM_SLEEP_DISABLE_LSB) & SYSTEM_SLEEP_DISABLE_MASK)
-#define SI_CONFIG_BIDIR_OD_DATA_SET(x) (((x) << SI_CONFIG_BIDIR_OD_DATA_LSB) & SI_CONFIG_BIDIR_OD_DATA_MASK)
-#define SI_CONFIG_I2C_SET(x) (((x) << SI_CONFIG_I2C_LSB) & SI_CONFIG_I2C_MASK)
-#define SI_CONFIG_POS_SAMPLE_SET(x) (((x) << SI_CONFIG_POS_SAMPLE_LSB) & SI_CONFIG_POS_SAMPLE_MASK)
-#define SI_CONFIG_INACTIVE_CLK_SET(x) (((x) << SI_CONFIG_INACTIVE_CLK_LSB) & SI_CONFIG_INACTIVE_CLK_MASK)
-#define SI_CONFIG_INACTIVE_DATA_SET(x) (((x) << SI_CONFIG_INACTIVE_DATA_LSB) & SI_CONFIG_INACTIVE_DATA_MASK)
-#define SI_CONFIG_DIVIDER_SET(x) (((x) << SI_CONFIG_DIVIDER_LSB) & SI_CONFIG_DIVIDER_MASK)
-#define SI_CS_START_SET(x) (((x) << SI_CS_START_LSB) & SI_CS_START_MASK)
-#define SI_CS_RX_CNT_SET(x) (((x) << SI_CS_RX_CNT_LSB) & SI_CS_RX_CNT_MASK)
-#define SI_CS_TX_CNT_SET(x) (((x) << SI_CS_TX_CNT_LSB) & SI_CS_TX_CNT_MASK)
-
-#endif /* } */
-
-#endif /*TARGET_REG_TABLE_H_*/
-
-
diff -druN linux-2.6.39-libre/drivers/staging/ath6kl/Kconfig linux-3.0-rc7-libre/drivers/staging/ath6kl/Kconfig
--- linux-2.6.39-libre/drivers/staging/ath6kl/Kconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/ath6kl/Kconfig	2011-07-11 19:51:52.000000000 -0400
@@ -1,6 +1,7 @@
 config ATH6K_LEGACY
 	tristate "Atheros AR6003 support (non mac80211)"
         depends on MMC && WLAN
+	depends on CFG80211
         select WIRELESS_EXT
         select WEXT_PRIV
 	help
@@ -100,12 +101,6 @@
 	help
 	WLAN GPIO to be used for resetting BT
 
-config ATH6KL_CFG80211
-	bool "CFG80211 support"
-	depends on ATH6K_LEGACY && CFG80211
-	help
-	Enables support for CFG80211 APIs. The default option is to use WEXT. Even with this option enabled, WEXT is not explicitly disabled and the onus of not exercising WEXT lies on the application(s) running in the user space.
-
 config ATH6KL_HTC_RAW_INTERFACE
 	bool "RAW HTC support"
 	depends on ATH6K_LEGACY
diff -druN linux-2.6.39-libre/drivers/staging/ath6kl/Makefile linux-3.0-rc7-libre/drivers/staging/ath6kl/Makefile
--- linux-2.6.39-libre/drivers/staging/ath6kl/Makefile	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/ath6kl/Makefile	2011-07-11 19:51:52.000000000 -0400
@@ -29,26 +29,6 @@
 ccflags-y += -I$(obj)/bmi/include
 ccflags-y += -I$(obj)/include/common/AR6002/hw4.0
 
-ifeq ($(CONFIG_AR600x_SD31_XXX),y)
-ccflags-y += -DAR600x_SD31_XXX
-endif
-
-ifeq ($(CONFIG_AR600x_WB31_XXX),y)
-ccflags-y += -DAR600x_WB31_XXX
-endif
-
-ifeq ($(CONFIG_AR600x_SD32_XXX),y)
-ccflags-y += -DAR600x_SD32_XXX
-endif
-
-ifeq ($(CONFIG_AR600x_CUSTOM_XXX),y)
-ccflags-y += -DAR600x_CUSTOM_XXX
-endif
-
-ifeq ($(CONFIG_ATH6KL_ENABLE_COEXISTENCE),y)
-ccflags-y += -DENABLE_COEXISTENCE
-endif
-
 ifeq ($(CONFIG_AR600x_DUAL_ANTENNA),y)
 ccflags-y += -DAR600x_DUAL_ANTENNA
 endif
@@ -85,11 +65,6 @@
 ccflags-y += -DATH6KL_CONFIG_GPIO_BT_RESET
 endif
 
-ifeq ($(CONFIG_ATH6KL_CFG80211),y)
-ccflags-y += -DATH6K_CONFIG_CFG80211
-ath6kl-y += os/linux/cfg80211.o
-endif
-
 ifeq ($(CONFIG_ATH6KL_HTC_RAW_INTERFACE),y)
 ccflags-y += -DHTC_RAW_INTERFACE
 endif
@@ -115,18 +90,8 @@
 ccflags-y += -DATH6KL_SKIP_ABI_VERSION_CHECK
 endif
 
-ccflags-y += -DLINUX -DKERNEL_2_6
-ccflags-y += -DTCMD
-ccflags-y += -DSEND_EVENT_TO_APP
-ccflags-y += -DUSER_KEYS
-ccflags-y += -DNO_SYNC_FLUSH
-ccflags-y += -DHTC_EP_STAT_PROFILING
-ccflags-y += -DATH_AR6K_11N_SUPPORT
 ccflags-y += -DWAPI_ENABLE
 ccflags-y += -DCHECKSUM_OFFLOAD
-ccflags-y += -DWLAN_HEADERS
-ccflags-y += -DINIT_MODE_DRV_ENABLED
-ccflags-y += -DBMIENABLE_SET
 
 obj-$(CONFIG_ATH6K_LEGACY) := ath6kl.o
 ath6kl-y += htc2/AR6000/ar6k.o
@@ -136,14 +101,12 @@
 ath6kl-y += htc2/htc_services.o
 ath6kl-y += htc2/htc.o
 ath6kl-y += bmi/src/bmi.o
+ath6kl-y += os/linux/cfg80211.o
 ath6kl-y += os/linux/ar6000_drv.o
 ath6kl-y += os/linux/ar6000_raw_if.o
 ath6kl-y += os/linux/ar6000_pm.o
 ath6kl-y += os/linux/netbuf.o
-ath6kl-y += os/linux/wireless_ext.o
-ath6kl-y += os/linux/ioctl.o
 ath6kl-y += os/linux/hci_bridge.o
-ath6kl-y += os/linux/ar6k_pal.o
 ath6kl-y += miscdrv/common_drv.o
 ath6kl-y += miscdrv/credit_dist.o
 ath6kl-y += wmi/wmi.o
diff -druN linux-2.6.39-libre/drivers/staging/ath6kl/miscdrv/ar3kconfig.c linux-3.0-rc7-libre/drivers/staging/ath6kl/miscdrv/ar3kconfig.c
--- linux-2.6.39-libre/drivers/staging/ath6kl/miscdrv/ar3kconfig.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/ath6kl/miscdrv/ar3kconfig.c	2011-07-11 19:51:52.000000000 -0400
@@ -24,7 +24,6 @@
 
 #include "a_config.h"
 #include "athdefs.h"
-#include "a_types.h"
 #include "a_osapi.h"
 #define ATH_MODULE_NAME misc
 #include "a_debug.h"
@@ -78,7 +77,7 @@
     } while (false);
    
     if (pPacket != NULL) {
-        A_FREE(pPacket);
+        kfree(pPacket);
     }
         
     return status;
@@ -116,7 +115,7 @@
     } while (false);
        
     if (pRecvPacket != NULL) {
-        A_FREE(pRecvPacket);    
+        kfree(pRecvPacket);    
     }
     
     return status;
@@ -203,7 +202,7 @@
     } while (false);
 
     if (pBuffer != NULL) {
-        A_FREE(pBuffer);    
+        kfree(pBuffer);    
     }
     
     return status;    
@@ -268,7 +267,7 @@
     } while (false);
                         
     if (pBufferToFree != NULL) {
-        A_FREE(pBufferToFree);    
+        kfree(pBufferToFree);    
     }
         
     return status;
@@ -304,7 +303,7 @@
     }
     
     if (pBufferToFree != NULL) {
-        A_FREE(pBufferToFree);    
+        kfree(pBufferToFree);    
     }
     
     return status;                                              
@@ -328,7 +327,7 @@
     }
 
     if (pBufferToFree != NULL) {
-        A_FREE(pBufferToFree);
+        kfree(pBufferToFree);
     }
 
     return status;
@@ -382,7 +381,7 @@
                                                &pEvent,
                                                &pBufferToFree);
     if (pBufferToFree != NULL) {
-        A_FREE(pBufferToFree);    
+        kfree(pBufferToFree);    
     }
     if (status) {
         AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("HostWakeup Config Failed! \n"));    
@@ -397,7 +396,7 @@
                                                &pEvent,
                                                &pBufferToFree);
     if (pBufferToFree != NULL) {
-        A_FREE(pBufferToFree);    
+        kfree(pBufferToFree);    
     }
     if (status) {
         AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Target Wakeup Config Failed! \n"));    
@@ -412,7 +411,7 @@
                                                &pEvent,
                                                &pBufferToFree);
     if (pBufferToFree != NULL) {
-        A_FREE(pBufferToFree);    
+        kfree(pBufferToFree);    
     }
     if (status) {
         AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("HostWakeup Enable Failed! \n"));    
@@ -427,7 +426,7 @@
                                                &pEvent,
                                                &pBufferToFree);
     if (pBufferToFree != NULL) {
-        A_FREE(pBufferToFree);    
+        kfree(pBufferToFree);    
     }
     if (status) {
         AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Target Wakeup Enable Failed! \n"));    
@@ -442,7 +441,7 @@
                                                &pEvent,
                                                &pBufferToFree);
     if (pBufferToFree != NULL) {
-        A_FREE(pBufferToFree);    
+        kfree(pBufferToFree);    
     }
     if (status) {
         AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Sleep Enable Failed! \n"));    
diff -druN linux-2.6.39-libre/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsconfig.c linux-3.0-rc7-libre/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsconfig.c
--- linux-2.6.39-libre/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsconfig.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsconfig.c	2011-07-11 19:51:52.000000000 -0400
@@ -222,7 +222,7 @@
         A_RELEASE_FIRMWARE(firmware);
         /* Parse the PS buffer to a global variable */
         status = AthDoParsePS(buffer,len);
-        A_FREE(buffer);
+        kfree(buffer);
     } else {
         A_RELEASE_FIRMWARE(firmware);
     }
@@ -256,7 +256,7 @@
                 A_RELEASE_FIRMWARE(firmware);
                 /* parse and store the Patch file contents to a global variables */
                 status = AthDoParsePatch(buffer,len);
-                A_FREE(buffer);
+                kfree(buffer);
             } else {
                 A_RELEASE_FIRMWARE(firmware);
             }
@@ -283,7 +283,7 @@
     &bufferToFree) == 0) {
         if(ReadPSEvent(event) == 0) { /* Exit if the status is success */
             if(bufferToFree != NULL) {
-                A_FREE(bufferToFree);
+                kfree(bufferToFree);
                 }
 	
 #ifndef HCI_TRANSPORT_SDIO
@@ -295,7 +295,7 @@
                goto complete;
         }
         if(bufferToFree != NULL) {
-               A_FREE(bufferToFree);
+               kfree(bufferToFree);
         }
     } else {
         status = 0;
@@ -312,13 +312,13 @@
         &bufferToFree) == 0) {
             if(ReadPSEvent(event) != 0) { /* Exit if the status is success */
                 if(bufferToFree != NULL) {
-                    A_FREE(bufferToFree);
+                    kfree(bufferToFree);
                     }
                    status = 1;
                     goto complete;
             }
             if(bufferToFree != NULL) {
-                   A_FREE(bufferToFree);
+                   kfree(bufferToFree);
             }
         } else {
             status = 0;
@@ -376,10 +376,10 @@
         AthFreeCommandList(&HciCmdList,numCmds);
     }
     if(path) {
-        A_FREE(path);
+        kfree(path);
     }
     if(config_path) {
-        A_FREE(config_path);
+        kfree(config_path);
     }
     return status;
 }
@@ -511,7 +511,7 @@
 
     }
     if(bufferToFree != NULL) {
-        A_FREE(bufferToFree);
+        kfree(bufferToFree);
    }
     return result;
 
@@ -527,7 +527,7 @@
 
     }
     if(bufferToFree != NULL) {
-        A_FREE(bufferToFree);
+        kfree(bufferToFree);
    }
     return result;
 }
@@ -564,7 +564,7 @@
 
     }
     if(bufferToFree != NULL) {
-        A_FREE(bufferToFree);
+        kfree(bufferToFree);
    }
     return result;
 }
diff -druN linux-2.6.39-libre/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsparser.c linux-3.0-rc7-libre/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsparser.c
--- linux-2.6.39-libre/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsparser.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsparser.c	2011-07-11 19:51:52.000000000 -0400
@@ -362,7 +362,7 @@
              {
                  AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("error\n"));
                  if(Buffer != NULL) {
-                     A_FREE(Buffer);
+                     kfree(Buffer);
                  }
                  return A_ERROR;
              }
@@ -401,7 +401,7 @@
                     if(uGetInputDataFormat(pCharLine, &stPS_DataFormat)) {
                         AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("uGetInputDataFormat fail\n"));
                      if(Buffer != NULL) {
-                             A_FREE(Buffer);
+                             kfree(Buffer);
                      }
                         return A_ERROR;
                     }    
@@ -422,7 +422,7 @@
                     if(uGetInputDataFormat(pCharLine, &stPS_DataFormat)) {
                         AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("uGetInputDataFormat fail \n"));
                      if(Buffer != NULL) {
-                             A_FREE(Buffer);
+                             kfree(Buffer);
                      }
                         return A_ERROR;
                     }
@@ -433,7 +433,7 @@
                     if (ByteCount > LINE_SIZE_MAX/2)
                     {
                      if(Buffer != NULL) {
-                             A_FREE(Buffer);
+                             kfree(Buffer);
                      }
                        return A_ERROR;
                     }
@@ -449,7 +449,7 @@
                         if(uGetInputDataFormat(pCharLine,&stPS_DataFormat)) {
                             AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("uGetInputDataFormat Fail\n"));
                             if(Buffer != NULL) {
-                                 A_FREE(Buffer);
+                                 kfree(Buffer);
                          }
                             return A_ERROR;
                         }
@@ -510,7 +510,7 @@
                     {
                        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("\n Buffer over flow PS File too big!!!"));
                        if(Buffer != NULL) {
-                           A_FREE(Buffer);
+                           kfree(Buffer);
                        }
                        return A_ERROR;
                        //Sleep (3000);
@@ -524,7 +524,7 @@
              default:
              {
                    if(Buffer != NULL) {
-                       A_FREE(Buffer);
+                       kfree(Buffer);
                    }
                    return A_ERROR;
              }
@@ -541,13 +541,13 @@
    {
 
       if(Buffer != NULL) {
-           A_FREE(Buffer);
+           kfree(Buffer);
       }
       return A_ERROR;
    }
 
    if(Buffer != NULL) {
-        A_FREE(Buffer);
+        kfree(Buffer);
    }
    return 0;
 
@@ -609,7 +609,7 @@
         /* Handle case when the number of patch buffer is more than the 20K */
         if(MAX_NUM_PATCH_ENTRY == Patch_Count) {
             for(i = 0; i < Patch_Count; i++) {
-                A_FREE(RamPatch[i].Data);
+                kfree(RamPatch[i].Data);
             }
             return A_ERROR;
         }
@@ -812,13 +812,13 @@
     for(count = 0; count < Patch_Count; count++) {
 
         AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Freeing Patch Buffer %d \r\n",count));
-        A_FREE(RamPatch[Patch_Count].Data);
+        kfree(RamPatch[Patch_Count].Data);
     }
 
     for(count = 0; count < Tag_Count; count++) {
 
         AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Freeing PS Buffer %d \r\n",count));
-        A_FREE(PsTagEntry[count].TagData);
+        kfree(PsTagEntry[count].TagData);
     }
 
 /* 
@@ -962,8 +962,8 @@
         return A_ERROR;
     }
     for(i = 0; i < numPackets;i++) {
-        A_FREE((*HciPacketList)[i].Hcipacket);
+        kfree((*HciPacketList)[i].Hcipacket);
     }  
-    A_FREE(*HciPacketList);
+    kfree(*HciPacketList);
     return 0;
 }
diff -druN linux-2.6.39-libre/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsparser.h linux-3.0-rc7-libre/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsparser.h
--- linux-2.6.39-libre/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsparser.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsparser.h	2011-07-11 19:51:52.000000000 -0400
@@ -33,7 +33,6 @@
 #include "athdefs.h"
 #ifdef HCI_TRANSPORT_SDIO
 #include "a_config.h"
-#include "a_types.h"
 #include "a_osapi.h"
 #define ATH_MODULE_NAME misc
 #include "a_debug.h"
@@ -60,11 +59,6 @@
 #ifndef A_MALLOC
 #define A_MALLOC(size)  kmalloc((size),GFP_KERNEL)
 #endif /* A_MALLOC */
-
-
-#ifndef A_FREE
-#define A_FREE(addr)  kfree((addr))
-#endif /* A_MALLOC */
 #endif /* HCI_TRANSPORT_UART */
 
 /* String manipulation APIs */
diff -druN linux-2.6.39-libre/drivers/staging/ath6kl/miscdrv/common_drv.c linux-3.0-rc7-libre/drivers/staging/ath6kl/miscdrv/common_drv.c
--- linux-2.6.39-libre/drivers/staging/ath6kl/miscdrv/common_drv.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/ath6kl/miscdrv/common_drv.c	2011-07-11 19:51:52.000000000 -0400
@@ -23,15 +23,12 @@
 
 #include "a_config.h"
 #include "athdefs.h"
-#include "a_types.h"
 
-#include "AR6002/hw2.0/hw/mbox_host_reg.h"
-#include "AR6002/hw2.0/hw/apb_map.h"
-#include "AR6002/hw2.0/hw/si_reg.h"
-#include "AR6002/hw2.0/hw/gpio_reg.h"
-#include "AR6002/hw2.0/hw/rtc_reg.h"
-#include "AR6002/hw2.0/hw/vmc_reg.h"
-#include "AR6002/hw2.0/hw/mbox_reg.h"
+#include "hw/mbox_host_reg.h"
+#include "gpio_reg.h"
+#include "hw/rtc_reg.h"
+#include "hw/mbox_reg.h"
+#include "hw/apb_map.h"
 
 #include "a_osapi.h"
 #include "targaddrs.h"
@@ -683,119 +680,6 @@
     return status;
 }
 
-
-static int prepare_ar6002(struct hif_device *hifDevice, u32 TargetVersion)
-{
-    int status = 0;
-
-    /* placeholder */
-
-    return status;
-}
-
-static int prepare_ar6003(struct hif_device *hifDevice, u32 TargetVersion)
-{
-    int status = 0;
-
-    /* placeholder */
-
-    return status;
-}
-
-/* this function assumes the caller has already initialized the BMI APIs */
-int ar6000_prepare_target(struct hif_device *hifDevice,
-                               u32 TargetType,
-                               u32 TargetVersion)
-{
-    if (TargetType == TARGET_TYPE_AR6002) {
-            /* do any preparations for AR6002 devices */
-        return prepare_ar6002(hifDevice,TargetVersion);
-    } else if (TargetType == TARGET_TYPE_AR6003) {
-        return prepare_ar6003(hifDevice,TargetVersion);
-    }
-
-    return 0;
-}
-
-#if defined(CONFIG_AR6002_REV1_FORCE_HOST)
-/*
- * Call this function just before the call to BMIInit
- * in order to force* AR6002 rev 1.x firmware to detect a Host.
- * THIS IS FOR USE ONLY WITH AR6002 REV 1.x.
- * TBDXXX: Remove this function when REV 1.x is desupported.
- */
-int
-ar6002_REV1_reset_force_host (struct hif_device *hifDevice)
-{
-    s32 i;
-    struct forceROM_s {
-        u32 addr;
-        u32 data;
-    };
-    struct forceROM_s *ForceROM;
-    s32 szForceROM;
-    int status = 0;
-    u32 address;
-    u32 data;
-
-    /* Force AR6002 REV1.x to recognize Host presence.
-     *
-     * Note: Use RAM at 0x52df80..0x52dfa0 with ROM Remap entry 0
-     * so that this workaround functions with AR6002.war1.sh.  We
-     * could fold that entire workaround into this one, but it's not
-     * worth the effort at this point.  This workaround cannot be
-     * merged into the other workaround because this must be done
-     * before BMI.
-     */
-
-    static struct forceROM_s ForceROM_NEW[] = {
-        {0x52df80, 0x20f31c07},
-        {0x52df84, 0x92374420},
-        {0x52df88, 0x1d120c03},
-        {0x52df8c, 0xff8216f0},
-        {0x52df90, 0xf01d120c},
-        {0x52df94, 0x81004136},
-        {0x52df98, 0xbc9100bd},
-        {0x52df9c, 0x00bba100},
-
-        {0x00008000|MC_TCAM_TARGET_ADDRESS, 0x0012dfe0}, /* Use remap entry 0 */
-        {0x00008000|MC_TCAM_COMPARE_ADDRESS, 0x000e2380},
-        {0x00008000|MC_TCAM_MASK_ADDRESS, 0x00000000},
-        {0x00008000|MC_TCAM_VALID_ADDRESS, 0x00000001},
-
-        {0x00018000|(LOCAL_COUNT_ADDRESS+0x10), 0}, /* clear BMI credit counter */
-
-        {0x00004000|AR6002_RESET_CONTROL_ADDRESS, RESET_CONTROL_WARM_RST_MASK},
-    };
-
-    address = 0x004ed4b0; /* REV1 target software ID is stored here */
-    status = ar6000_ReadRegDiag(hifDevice, &address, &data);
-    if (status || (data != AR6002_VERSION_REV1)) {
-        return A_ERROR; /* Not AR6002 REV1 */
-    }
-
-    ForceROM = ForceROM_NEW;
-    szForceROM = sizeof(ForceROM_NEW)/sizeof(*ForceROM);
-
-    ATH_DEBUG_PRINTF (DBG_MISC_DRV, ATH_DEBUG_TRC, ("Force Target to recognize Host....\n"));
-    for (i = 0; i < szForceROM; i++)
-    {
-        if (ar6000_WriteRegDiag(hifDevice,
-                                &ForceROM[i].addr,
-                                &ForceROM[i].data) != 0)
-        {
-            ATH_DEBUG_PRINTF (DBG_MISC_DRV, ATH_DEBUG_TRC, ("Cannot force Target to recognize Host!\n"));
-            return A_ERROR;
-        }
-    }
-
-    A_MDELAY(1000);
-
-    return 0;
-}
-
-#endif /* CONFIG_AR6002_REV1_FORCE_HOST */
-
 void DebugDumpBytes(u8 *buffer, u16 length, char *pDescription)
 {
     char stream[60];
diff -druN linux-2.6.39-libre/drivers/staging/ath6kl/miscdrv/credit_dist.c linux-3.0-rc7-libre/drivers/staging/ath6kl/miscdrv/credit_dist.c
--- linux-2.6.39-libre/drivers/staging/ath6kl/miscdrv/credit_dist.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/ath6kl/miscdrv/credit_dist.c	2011-07-11 19:51:52.000000000 -0400
@@ -23,7 +23,6 @@
 
 #include "a_config.h"
 #include "athdefs.h"
-#include "a_types.h"
 #include "a_osapi.h"
 #define ATH_MODULE_NAME misc
 #include "a_debug.h"
diff -druN linux-2.6.39-libre/drivers/staging/ath6kl/os/linux/ar6000_android.c linux-3.0-rc7-libre/drivers/staging/ath6kl/os/linux/ar6000_android.c
--- linux-2.6.39-libre/drivers/staging/ath6kl/os/linux/ar6000_android.c	2011-05-19 02:14:59.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/ath6kl/os/linux/ar6000_android.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,389 +0,0 @@
-//------------------------------------------------------------------------------
-// Copyright (c) 2004-2010 Atheros Communications Inc.
-// All rights reserved.
-//
-// 
-//
-// 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.
-//
-//
-//
-// Author(s): ="Atheros"
-//------------------------------------------------------------------------------
-#include "ar6000_drv.h"
-#include "htc.h"
-#include <linux/vmalloc.h>
-#include <linux/fs.h>
-
-#ifdef CONFIG_HAS_EARLYSUSPEND
-#include <linux/earlysuspend.h>
-#endif
-
-bool enable_mmc_host_detect_change = false;
-static void ar6000_enable_mmchost_detect_change(int enable);
-
-
-char fwpath[256] = "/system/wifi";
-int wowledon;
-unsigned int enablelogcat;
-
-extern int bmienable;
-extern struct net_device *ar6000_devices[];
-extern char ifname[];
-
-const char def_ifname[] = "wlan0";
-module_param_string(fwpath, fwpath, sizeof(fwpath), 0644);
-module_param(enablelogcat, uint, 0644);
-module_param(wowledon, int, 0644);
-
-#ifdef CONFIG_HAS_EARLYSUSPEND
-static int screen_is_off;
-static struct early_suspend ar6k_early_suspend;
-#endif
-
-static int (*ar6000_avail_ev_p)(void *, void *);
-
-#if defined(CONFIG_ANDROID_LOGGER) && (!defined(CONFIG_MMC_MSM))
-int logger_write(const enum logidx index,
-                const unsigned char prio,
-                const char __kernel * const tag,
-                const char __kernel * const fmt,
-                ...)
-{
-    int ret = 0;
-    va_list vargs;
-    struct file *filp = (struct file *)-ENOENT;
-    mm_segment_t oldfs;
-    struct iovec vec[3];
-    int tag_bytes = strlen(tag) + 1, msg_bytes;
-    char *msg;      
-    va_start(vargs, fmt);
-    msg = kvasprintf(GFP_ATOMIC, fmt, vargs);
-    va_end(vargs);
-    if (!msg)
-        return -ENOMEM;
-    if (in_interrupt()) {
-        /* we have no choice since aio_write may be blocked */
-        printk(KERN_ALERT "%s", msg);
-        goto out_free_message;
-    }
-    msg_bytes = strlen(msg) + 1;
-    if (msg_bytes <= 1) /* empty message? */
-        goto out_free_message; /* don't bother, then */
-    if ((msg_bytes + tag_bytes + 1) > 2048) {
-        ret = -E2BIG;
-        goto out_free_message;
-    }
-            
-    vec[0].iov_base  = (unsigned char *) &prio;
-    vec[0].iov_len    = 1;
-    vec[1].iov_base   = (void *) tag;
-    vec[1].iov_len    = strlen(tag) + 1;
-    vec[2].iov_base   = (void *) msg;
-    vec[2].iov_len    = strlen(msg) + 1; 
-
-    oldfs = get_fs();
-    set_fs(KERNEL_DS);
-    do {
-        filp = filp_open("/dev/log/main", O_WRONLY, S_IRUSR);
-        if (IS_ERR(filp) || !filp->f_op) {
-            AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: filp_open /dev/log/main error\n", __FUNCTION__));
-            ret = -ENOENT;
-            break;
-        }
-
-        if (filp->f_op->aio_write) {
-            int nr_segs = sizeof(vec) / sizeof(vec[0]);
-            int len = vec[0].iov_len + vec[1].iov_len + vec[2].iov_len;
-            struct kiocb kiocb;
-            init_sync_kiocb(&kiocb, filp);
-            kiocb.ki_pos = 0;
-            kiocb.ki_left = len;
-            kiocb.ki_nbytes = len;
-            ret = filp->f_op->aio_write(&kiocb, vec, nr_segs, kiocb.ki_pos);
-        }
-        
-    } while (0);
-
-    if (!IS_ERR(filp)) {
-        filp_close(filp, NULL);
-    }
-    set_fs(oldfs);
-out_free_message:
-    kfree(msg);
-    return ret;
-}
-#endif
-
-int android_logger_lv(void *module, int mask)
-{
-    switch (mask) {
-    case ATH_DEBUG_ERR:
-        return 6;
-    case ATH_DEBUG_INFO:
-        return 4;
-    case ATH_DEBUG_WARN:
-        return 5; 
-    case ATH_DEBUG_TRC:        
-        return 3; 
-    default:
-#ifdef DEBUG
-        if (!module) {
-            return 3;
-        } else if (module == &GET_ATH_MODULE_DEBUG_VAR_NAME(driver)) {
-            return (mask <=ATH_DEBUG_MAKE_MODULE_MASK(3)) ? 3 : 2;
-        } else if (module == &GET_ATH_MODULE_DEBUG_VAR_NAME(htc)) {
-            return 2;
-        } else {
-            return 3;
-        }
-#else
-        return 3; /* DEBUG */
-#endif
-    }
-}
-
-static int android_readwrite_file(const char *filename, char *rbuf, const char *wbuf, size_t length)
-{
-    int ret = 0;
-    struct file *filp = (struct file *)-ENOENT;
-    mm_segment_t oldfs;
-    oldfs = get_fs();
-    set_fs(KERNEL_DS);
-    do {
-        int mode = (wbuf) ? O_RDWR : O_RDONLY;
-        filp = filp_open(filename, mode, S_IRUSR);
-        if (IS_ERR(filp) || !filp->f_op) {
-            AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: file %s filp_open error\n", __FUNCTION__, filename));
-            ret = -ENOENT;
-            break;
-        }
-    
-        if (length==0) {
-            /* Read the length of the file only */
-            struct inode    *inode;
-
-            inode = GET_INODE_FROM_FILEP(filp);
-            if (!inode) {
-                AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Get inode from %s failed\n", __FUNCTION__, filename));
-                ret = -ENOENT;
-                break;
-            }
-            ret = i_size_read(inode->i_mapping->host);
-            break;
-        }
-
-        if (wbuf) {
-            if ( (ret=filp->f_op->write(filp, wbuf, length, &filp->f_pos)) < 0) {
-                AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Write %u bytes to file %s error %d\n", __FUNCTION__, 
-                                length, filename, ret));
-                break;
-            }
-        } else {
-            if ( (ret=filp->f_op->read(filp, rbuf, length, &filp->f_pos)) < 0) {
-                AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Read %u bytes from file %s error %d\n", __FUNCTION__,
-                                length, filename, ret));
-                break;
-            }
-        }
-    } while (0);
-
-    if (!IS_ERR(filp)) {
-        filp_close(filp, NULL);
-    }
-    set_fs(oldfs);
-
-    return ret;
-}
-
-int android_reject_firmware(const struct firmware **firmware_p, const char *name,
-                     struct device *device)
-{
-    int ret = 0;
-    struct firmware *firmware;
-    char filename[256];
-    const char *raw_filename = name;
-	return -1;
-	*firmware_p = firmware = kzalloc(sizeof(*firmware), GFP_KERNEL);
-    if (!firmware) 
-		return -ENOMEM;
-	sprintf(filename, "%s/%s", fwpath, raw_filename);
-    do {
-        size_t length, bufsize, bmisize;
-
-        if ( (ret=android_readwrite_file(filename, NULL, NULL, 0)) < 0) {
-            break;
-        } else {
-            length = ret;
-        }
-    
-        bufsize = ALIGN(length, PAGE_SIZE);
-        bmisize = A_ROUND_UP(length, 4);
-        bufsize = max(bmisize, bufsize);
-        firmware->data = vmalloc(bufsize);
-        firmware->size = length;
-        if (!firmware->data) {
-            AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("%s: Cannot allocate buffer for firmware\n", __FUNCTION__));
-            ret = -ENOMEM;
-            break;
-        }
-    
-        if ( (ret=android_readwrite_file(filename, (char*)firmware->data, NULL, length)) != length) {
-            AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("%s: file read error, ret %d request %d\n", __FUNCTION__, ret, length));
-            ret = -1;
-            break;
-        }
-    
-    } while (0);
-
-    if (ret<0) {
-        if (firmware) {
-            if (firmware->data)
-                vfree(firmware->data);
-            kfree(firmware);
-        }
-        *firmware_p = NULL;
-    } else {
-        ret = 0;
-    }
-    return ret;    
-}
-
-void android_release_firmware(const struct firmware *firmware)
-{
-	if (firmware) {
-        if (firmware->data)
-            vfree(firmware->data);
-        kfree(firmware);
-    }
-}
-
-static int ar6000_android_avail_ev(void *context, void *hif_handle)
-{
-    int ret;
-    ar6000_enable_mmchost_detect_change(0);
-    ret = ar6000_avail_ev_p(context, hif_handle);
-    return ret;
-}
-
-/* Useful for qualcom platform to detect our wlan card for mmc stack */
-static void ar6000_enable_mmchost_detect_change(int enable)
-{
-#ifdef CONFIG_MMC_MSM
-#define MMC_MSM_DEV "msm_sdcc.1"
-    char buf[3];
-    int length;
-
-    if (!enable_mmc_host_detect_change) {
-        return;
-    }
-    length = snprintf(buf, sizeof(buf), "%d\n", enable ? 1 : 0);
-    if (android_readwrite_file("/sys/devices/platform/" MMC_MSM_DEV "/detect_change", 
-                               NULL, buf, length) < 0) {
-        /* fall back to polling */
-        android_readwrite_file("/sys/devices/platform/" MMC_MSM_DEV "/polling", NULL, buf, length);
-    }
-#endif
-}
-
-#ifdef CONFIG_HAS_EARLYSUSPEND
-static void android_early_suspend(struct early_suspend *h)
-{
-    screen_is_off = 1;
-}
-
-static void android_late_resume(struct early_suspend *h)
-{
-    screen_is_off = 0;
-}
-#endif
-
-void android_module_init(OSDRV_CALLBACKS *osdrvCallbacks)
-{
-    bmienable = 1;
-    if (ifname[0] == '\0')
-        strcpy(ifname, def_ifname);
-#ifdef CONFIG_HAS_EARLYSUSPEND
-    ar6k_early_suspend.suspend = android_early_suspend;
-    ar6k_early_suspend.resume  = android_late_resume;
-    ar6k_early_suspend.level   = EARLY_SUSPEND_LEVEL_BLANK_SCREEN;
-    register_early_suspend(&ar6k_early_suspend);
-#endif
-
-    ar6000_avail_ev_p = osdrvCallbacks->deviceInsertedHandler;
-    osdrvCallbacks->deviceInsertedHandler = ar6000_android_avail_ev;
-
-    ar6000_enable_mmchost_detect_change(1);
-}
-
-void android_module_exit(void)
-{
-#ifdef CONFIG_HAS_EARLYSUSPEND
-    unregister_early_suspend(&ar6k_early_suspend);
-#endif
-    ar6000_enable_mmchost_detect_change(1);
-}
-
-#ifdef CONFIG_PM
-void android_ar6k_check_wow_status(struct ar6_softc *ar, struct sk_buff *skb, bool isEvent)
-{
-    if (
-#ifdef CONFIG_HAS_EARLYSUSPEND
-        screen_is_off && 
-#endif 
-            skb && ar->arConnected) {
-        bool needWake = false;
-        if (isEvent) {
-            if (A_NETBUF_LEN(skb) >= sizeof(u16)) {
-                u16 cmd = *(const u16 *)A_NETBUF_DATA(skb);
-                switch (cmd) {
-                case WMI_CONNECT_EVENTID:
-                case WMI_DISCONNECT_EVENTID:
-                    needWake = true;
-                    break;
-                default:
-                    /* dont wake lock the system for other event */
-                    break;
-                }
-            }
-        } else if (A_NETBUF_LEN(skb) >= sizeof(ATH_MAC_HDR)) {
-            ATH_MAC_HDR *datap = (ATH_MAC_HDR *)A_NETBUF_DATA(skb);
-            if (!IEEE80211_IS_MULTICAST(datap->dstMac)) {
-                switch (A_BE2CPU16(datap->typeOrLen)) {
-                case 0x0800: /* IP */
-                case 0x888e: /* EAPOL */
-                case 0x88c7: /* RSN_PREAUTH */
-                case 0x88b4: /* WAPI */
-                     needWake = true;
-                     break;
-                case 0x0806: /* ARP is not important to hold wake lock */
-                default:
-                    break;
-                }
-            }
-        }
-        if (needWake) {
-            /* keep host wake up if there is any event and packate coming in*/
-            if (wowledon) {
-                char buf[32];
-                int len = sprintf(buf, "on");
-                android_readwrite_file("/sys/power/state", NULL, buf, len);
-
-                len = sprintf(buf, "%d", 127);
-                android_readwrite_file("/sys/class/leds/lcd-backlight/brightness",
-                                       NULL, buf,len);
-            }
-        }
-    }
-}
-#endif /* CONFIG_PM */
diff -druN linux-2.6.39-libre/drivers/staging/ath6kl/os/linux/ar6000_drv.c linux-3.0-rc7-libre/drivers/staging/ath6kl/os/linux/ar6000_drv.c
--- linux-2.6.39-libre/drivers/staging/ath6kl/os/linux/ar6000_drv.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/ath6kl/os/linux/ar6000_drv.c	2011-07-11 19:51:52.000000000 -0400
@@ -27,9 +27,7 @@
  */
 
 #include "ar6000_drv.h"
-#ifdef ATH6K_CONFIG_CFG80211
 #include "cfg80211.h"
-#endif /* ATH6K_CONFIG_CFG80211 */
 #include "htc.h"
 #include "wmi_filter_linux.h"
 #include "epping_test.h"
@@ -118,7 +116,6 @@
 #endif
 
 unsigned int processDot11Hdr = 0;
-int bmienable = BMIENABLE_DEFAULT;
 
 char ifname[IFNAMSIZ] = {0,};
 
@@ -134,6 +131,8 @@
 unsigned int enableuartprint = ENABLEUARTPRINT_DEFAULT;
 unsigned int logWmiRawMsgs = 0;
 unsigned int enabletimerwar = 0;
+unsigned int num_device = 1;
+unsigned int regscanmode;
 unsigned int fwmode = 1;
 unsigned int mbox_yield_limit = 99;
 unsigned int enablerssicompensation = 0;
@@ -148,7 +147,6 @@
 unsigned int nohifscattersupport = NOHIFSCATTERSUPPORT_DEFAULT;
 
 unsigned int setuphci = SETUPHCI_DEFAULT;
-unsigned int setuphcipal = SETUPHCIPAL_DEFAULT;
 unsigned int loghci = 0;
 unsigned int setupbtdev = SETUPBTDEV_DEFAULT;
 #ifndef EXPORT_HCI_BRIDGE_INTERFACE
@@ -156,15 +154,14 @@
 unsigned int hciuartscale = HCIUARTSCALE_DEFAULT;
 unsigned int hciuartstep = HCIUARTSTEP_DEFAULT;
 #endif
-#ifdef CONFIG_CHECKSUM_OFFLOAD
 unsigned int csumOffload=0;
 unsigned int csumOffloadTest=0;
-#endif
 unsigned int eppingtest=0;
+unsigned int mac_addr_method;
+unsigned int firmware_bridge;
 
 module_param_string(ifname, ifname, sizeof(ifname), 0644);
 module_param(wlaninitmode, int, 0644);
-module_param(bmienable, int, 0644);
 module_param(bypasswmi, bool, 0644);
 module_param(debuglevel, uint, 0644);
 module_param(tspecCompliance, int, 0644);
@@ -182,9 +179,7 @@
 module_param(allow_trace_signal, int, 0644);
 module_param(enablerssicompensation, uint, 0644);
 module_param(processDot11Hdr, uint, 0644);
-#ifdef CONFIG_CHECKSUM_OFFLOAD
 module_param(csumOffload, uint, 0644);
-#endif
 #ifdef CONFIG_HOST_TCMD_SUPPORT
 module_param(testmode, uint, 0644);
 #endif
@@ -192,7 +187,6 @@
 module_param(nohifscattersupport, uint, 0644);
 module_param(panic_on_assert, uint, 0644);
 module_param(setuphci, uint, 0644);
-module_param(setuphcipal, uint, 0644);
 module_param(loghci, uint, 0644);
 module_param(setupbtdev, uint, 0644);
 #ifndef EXPORT_HCI_BRIDGE_INTERFACE
@@ -288,20 +282,11 @@
 static void ar6000_detect_error(unsigned long ptr);
 static void	ar6000_set_multicast_list(struct net_device *dev);
 static struct net_device_stats *ar6000_get_stats(struct net_device *dev);
-static struct iw_statistics *ar6000_get_iwstats(struct net_device * dev);
 
 static void disconnect_timer_handler(unsigned long ptr);
 
 void read_rssi_compensation_param(struct ar6_softc *ar);
 
-    /* for android builds we call external APIs that handle firmware download and configuration */
-#ifdef ANDROID_ENV
-/* !!!! Interim android support to make it easier to patch the default driver for
- * android use. You must define an external source file ar6000_android.c that handles the following
- * APIs */
-extern void android_module_init(OSDRV_CALLBACKS *osdrvCallbacks);
-extern void android_module_exit(void);
-#endif
 /*
  * HTC service connection handlers
  */
@@ -321,9 +306,7 @@
 
 static HTC_SEND_FULL_ACTION ar6000_tx_queue_full(void *Context, struct htc_packet *pPacket);
 
-#ifdef ATH_AR6K_11N_SUPPORT
 static void ar6000_alloc_netbufs(A_NETBUF_QUEUE_T *q, u16 num);
-#endif
 static void ar6000_deliver_frames_to_nw_stack(void * dev, void *osbuf);
 //static void ar6000_deliver_frames_to_bt_stack(void * dev, void *osbuf);
 
@@ -346,8 +329,6 @@
 static int
 ar6000_sysfs_bmi_init(struct ar6_softc *ar);
 
-/* HCI PAL callback function declarations */
-int ar6k_setup_hci_pal(struct ar6_softc *ar);
 void  ar6k_cleanup_hci_pal(struct ar6_softc *ar);
 
 static void
@@ -362,16 +343,13 @@
 
 struct net_device *ar6000_devices[MAX_AR6000];
 static int is_netdev_registered;
-extern struct iw_handler_def ath_iw_handler_def;
 DECLARE_WAIT_QUEUE_HEAD(arEvent);
 static void ar6000_cookie_init(struct ar6_softc *ar);
 static void ar6000_cookie_cleanup(struct ar6_softc *ar);
 static void ar6000_free_cookie(struct ar6_softc *ar, struct ar_cookie * cookie);
 static struct ar_cookie *ar6000_alloc_cookie(struct ar6_softc *ar);
 
-#ifdef USER_KEYS
 static int ar6000_reinstall_keys(struct ar6_softc *ar,u8 key_op_ctrl);
-#endif
 
 #ifdef CONFIG_AP_VIRTUAL_ADAPTER_SUPPORT
 struct net_device *arApNetDev;
@@ -389,7 +367,6 @@
     .ndo_open               = ar6000_open,
     .ndo_stop               = ar6000_close,
     .ndo_get_stats          = ar6000_get_stats,
-    .ndo_do_ioctl           = ar6000_ioctl,
     .ndo_start_xmit         = ar6000_data_tx,
     .ndo_set_multicast_list = ar6000_set_multicast_list,
 };
@@ -612,7 +589,6 @@
     send = dbglog_get_debug_fragment(&buffer[sent], length - sent,
                                      MAX_WIRELESS_EVENT_SIZE);
     while (send) {
-        ar6000_send_event_to_app(ar, WMIX_DBGLOG_EVENTID, (u8 *)&buffer[sent], send);
         sent += send;
         send = dbglog_get_debug_fragment(&buffer[sent], length - sent,
                                          MAX_WIRELESS_EVENT_SIZE);
@@ -631,7 +607,7 @@
 ar6000_init_module(void)
 {
     static int probed = 0;
-    int status;
+    int r;
     OSDRV_CALLBACKS osdrvCallbacks;
 
     a_module_debug_support_init();
@@ -664,12 +640,6 @@
     osdrvCallbacks.devicePowerChangeHandler = ar6000_power_change_ev;
 #endif
 
-    ar6000_pm_init();
-
-#ifdef ANDROID_ENV
-    android_module_init(&osdrvCallbacks);
-#endif
-
 #ifdef DEBUG
     /* Set the debug flags if specified at load time */
     if(debugflags != 0)
@@ -687,13 +657,9 @@
     memset(&aptcTR, 0, sizeof(APTC_TRAFFIC_RECORD));
 #endif /* ADAPTIVE_POWER_THROUGHPUT_CONTROL */
 
-#ifdef CONFIG_HOST_GPIO_SUPPORT
-    ar6000_gpio_init();
-#endif /* CONFIG_HOST_GPIO_SUPPORT */
-
-    status = HIFInit(&osdrvCallbacks);
-    if (status)
-        return -ENODEV;
+    r = HIFInit(&osdrvCallbacks);
+    if (r)
+        return r;
 
     return 0;
 }
@@ -723,12 +689,6 @@
 
     a_module_debug_support_cleanup();
 
-    ar6000_pm_exit();
-
-#ifdef ANDROID_ENV    
-    android_module_exit();
-#endif
-
     AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("ar6000_cleanup: success\n"));
 }
 
@@ -769,7 +729,6 @@
 }
 #endif /* ADAPTIVE_POWER_THROUGHPUT_CONTROL */
 
-#ifdef ATH_AR6K_11N_SUPPORT
 static void
 ar6000_alloc_netbufs(A_NETBUF_QUEUE_T *q, u16 num)
 {
@@ -788,7 +747,6 @@
         A_PRINTF("%s(), allocation of netbuf failed", __func__);
     }
 }
-#endif
 
 static struct bin_attribute bmi_attr = {
     .attr = {.name = "bmi", .mode = 0600},
@@ -894,8 +852,6 @@
     } \
 } while(0)
 
-#ifdef INIT_MODE_DRV_ENABLED
-
 #ifdef SOFTMAC_FILE_USED
 #define AR6002_MAC_ADDRESS_OFFSET     0x0A
 #define AR6003_MAC_ADDRESS_OFFSET     0x16
@@ -982,7 +938,7 @@
                 }
                 source = "softmac file";
             }
-            A_FREE(macbuf);
+            kfree(macbuf);
         }
         A_RELEASE_FIRMWARE(softmac_entry);
     }
@@ -1005,6 +961,8 @@
                 filename = AR6003_REV1_OTP_FILE;
             } else if (ar->arVersion.target_ver == AR6003_REV2_VERSION) {
                 filename = AR6003_REV2_OTP_FILE;
+                } else if (ar->arVersion.target_ver == AR6003_REV3_VERSION) {
+                        filename = AR6003_REV3_OTP_FILE;
             } else {
                 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unknown firmware revision: %d\n", ar->arVersion.target_ver));
                 return A_ERROR;
@@ -1016,6 +974,8 @@
                 filename = AR6003_REV1_FIRMWARE_FILE;
             } else if (ar->arVersion.target_ver == AR6003_REV2_VERSION) {
                 filename = AR6003_REV2_FIRMWARE_FILE;
+                } else if (ar->arVersion.target_ver == AR6003_REV3_VERSION) {
+                        filename = AR6003_REV3_FIRMWARE_FILE;
             } else {
                 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unknown firmware revision: %d\n", ar->arVersion.target_ver));
                 return A_ERROR;
@@ -1027,6 +987,8 @@
                     filename = AR6003_REV1_EPPING_FIRMWARE_FILE;
                 } else if (ar->arVersion.target_ver == AR6003_REV2_VERSION) {
                     filename = AR6003_REV2_EPPING_FIRMWARE_FILE;
+                } else if (ar->arVersion.target_ver == AR6003_REV3_VERSION) {
+                        filename = AR6003_REV3_EPPING_FIRMWARE_FILE;
                 } else {
                     AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("eppingtest : unsupported firmware revision: %d\n", 
                         ar->arVersion.target_ver));
@@ -1041,6 +1003,8 @@
                     filename = AR6003_REV1_TCMD_FIRMWARE_FILE;
                 } else if (ar->arVersion.target_ver == AR6003_REV2_VERSION) {
                     filename = AR6003_REV2_TCMD_FIRMWARE_FILE;
+                } else if (ar->arVersion.target_ver == AR6003_REV3_VERSION) {
+                        filename = AR6003_REV3_TCMD_FIRMWARE_FILE;
                 } else {
                     AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unknown firmware revision: %d\n", ar->arVersion.target_ver));
                     return A_ERROR;
@@ -1068,6 +1032,8 @@
                 filename = AR6003_REV1_PATCH_FILE;
             } else if (ar->arVersion.target_ver == AR6003_REV2_VERSION) {
                 filename = AR6003_REV2_PATCH_FILE;
+                } else if (ar->arVersion.target_ver == AR6003_REV3_VERSION) {
+                        filename = AR6003_REV3_PATCH_FILE;
             } else {
                 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unknown firmware revision: %d\n", ar->arVersion.target_ver));
                 return A_ERROR;
@@ -1079,6 +1045,8 @@
                 filename = AR6003_REV1_BOARD_DATA_FILE;
             } else if (ar->arVersion.target_ver == AR6003_REV2_VERSION) {
                 filename = AR6003_REV2_BOARD_DATA_FILE;
+                } else if (ar->arVersion.target_ver == AR6003_REV3_VERSION) {
+                        filename = AR6003_REV3_BOARD_DATA_FILE;
             } else {
                 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unknown firmware revision: %d\n", ar->arVersion.target_ver));
                 return A_ERROR;
@@ -1133,8 +1101,10 @@
             }
 
             /* Record the fact that extended board Data IS initialized */
-            param = 1;
-            bmifn(BMIWriteMemory(ar->arHifDevice, HOST_INTEREST_ITEM_ADDRESS(ar, hi_board_ext_data_initialized), (u8 *)&param, 4));
+            param = (board_ext_data_size << 16) | 1;
+            bmifn(BMIWriteMemory(ar->arHifDevice,
+            HOST_INTEREST_ITEM_ADDRESS(ar, hi_board_ext_data_config),
+				       (unsigned char *)&param, 4));
         }
         fw_entry_size = board_data_size;
     }
@@ -1153,7 +1123,6 @@
     A_RELEASE_FIRMWARE(fw_entry);
     return 0;
 }
-#endif /* INIT_MODE_DRV_ENABLED */
 
 int
 ar6000_update_bdaddr(struct ar6_softc *ar)
@@ -1200,7 +1169,6 @@
         }
 
         A_RELEASE_FIRMWARE(fw_entry);
-#ifdef INIT_MODE_DRV_ENABLED
     } else {
         /* The config is contained within the driver itself */
         int status;
@@ -1293,7 +1261,9 @@
             bmifn(BMIWriteMemory(ar->arHifDevice, HOST_INTEREST_ITEM_ADDRESS(ar, hi_board_data_initialized), (u8 *)&param, 4));
 
             /* Transfer One time Programmable data */
-            AR6K_DATA_DOWNLOAD_ADDRESS(address, ar->arVersion.target_ver);
+	    AR6K_APP_LOAD_ADDRESS(address, ar->arVersion.target_ver);
+	    if (ar->arVersion.target_ver == AR6003_REV3_VERSION)
+		  address = 0x1234;
             status = ar6000_transfer_bin_file(ar, AR6K_OTP_FILE, address, true);
             if (status == 0) {
                 /* Execute the OTP code */
@@ -1309,7 +1279,9 @@
         }
 
         /* Download Target firmware */
-        AR6K_DATA_DOWNLOAD_ADDRESS(address, ar->arVersion.target_ver);
+        AR6K_APP_LOAD_ADDRESS(address, ar->arVersion.target_ver);
+        if (ar->arVersion.target_ver == AR6003_REV3_VERSION)
+                address = 0x1234;
         if ((ar6000_transfer_bin_file(ar, AR6K_FIRMWARE_FILE, address, true)) != 0) {
             return A_ERROR;
         }
@@ -1318,25 +1290,16 @@
         AR6K_APP_START_OVERRIDE_ADDRESS(address, ar->arVersion.target_ver);
         bmifn(BMISetAppStart(ar->arHifDevice, address));
 
-        /* Apply the patches */
-        AR6K_PATCH_DOWNLOAD_ADDRESS(address, ar->arVersion.target_ver);
-        if ((ar6000_transfer_bin_file(ar, AR6K_PATCH_FILE, address, false)) != 0) {
-            return A_ERROR;
-        }
-
-        param = address;
-        bmifn(BMIWriteMemory(ar->arHifDevice, HOST_INTEREST_ITEM_ADDRESS(ar, hi_dset_list_head), (u8 *)&param, 4));
-
-        if (ar->arTargetType == TARGET_TYPE_AR6003) {
-            if (ar->arVersion.target_ver == AR6003_REV1_VERSION) {
-                /* Reserve 5.5K of RAM */
-                param = 5632;
-            } else { /* AR6003_REV2_VERSION */
-                /* Reserve 6.5K of RAM */
-                param = 6656;
-            }
-            bmifn(BMIWriteMemory(ar->arHifDevice, HOST_INTEREST_ITEM_ADDRESS(ar, hi_end_RAM_reserve_sz), (u8 *)&param, 4));
-        }
+	if(ar->arTargetType == TARGET_TYPE_AR6003) {
+		AR6K_DATASET_PATCH_ADDRESS(address, ar->arVersion.target_ver);
+		if ((ar6000_transfer_bin_file(ar, AR6K_PATCH_FILE,
+					      address, false)) != 0)
+			return A_ERROR;
+		param = address;
+		bmifn(BMIWriteMemory(ar->arHifDevice,
+		HOST_INTEREST_ITEM_ADDRESS(ar, hi_dset_list_head),
+					   (unsigned char *)&param, 4));
+	}
 
         /* Restore system sleep */
         address = RTC_BASE_ADDRESS + SYSTEM_SLEEP_ADDRESS;
@@ -1390,8 +1353,6 @@
             msleep(1000);
         }
 #endif /* HTC_RAW_INTERFACE */
-
-#endif /* INIT_MODE_DRV_ENABLED */
     }
 
     return 0;
@@ -1470,7 +1431,11 @@
             return A_ERROR;
         }
 
+        param |= (num_device << HI_OPTION_NUM_DEV_SHIFT);
         param |= (fwmode << HI_OPTION_FW_MODE_SHIFT);
+        param |= (mac_addr_method << HI_OPTION_MAC_ADDR_METHOD_SHIFT);
+        param |= (firmware_bridge << HI_OPTION_FW_BRIDGE_SHIFT);
+
 
         if (BMIWriteMemory(ar->arHifDevice,
             HOST_INTEREST_ITEM_ADDRESS(ar, hi_option_flag),
@@ -1518,18 +1483,34 @@
      * It is difficult to patch the firmware boot code,
      * but possible in theory.
      */
-    if (ar->arTargetType == TARGET_TYPE_AR6003) {
-        param = AR6003_BOARD_EXT_DATA_ADDRESS; 
-        if (BMIWriteMemory(ar->arHifDevice,
-            HOST_INTEREST_ITEM_ADDRESS(ar, hi_board_ext_data),
-            (u8 *)&param,
-            4) != 0)
-        {
-            AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("BMIWriteMemory for hi_board_ext_data failed \n"));
-            return A_ERROR;
-        }
-    }
 
+	if (ar->arTargetType == TARGET_TYPE_AR6003) {
+		u32 ramReservedSz;
+		if (ar->arVersion.target_ver == AR6003_REV2_VERSION) {
+			param = AR6003_REV2_BOARD_EXT_DATA_ADDRESS;
+			ramReservedSz =  AR6003_REV2_RAM_RESERVE_SIZE;
+                } else {
+			param = AR6003_REV3_BOARD_EXT_DATA_ADDRESS;
+			ramReservedSz =  AR6003_REV3_RAM_RESERVE_SIZE;
+		}
+		if (BMIWriteMemory(ar->arHifDevice,
+			HOST_INTEREST_ITEM_ADDRESS(ar, hi_board_ext_data),
+						   (u8 *)&param, 4) != 0) {
+				AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
+						("BMIWriteMemory for "
+						 "hi_board_ext_data failed\n"));
+				return A_ERROR;
+		}
+		if (BMIWriteMemory(ar->arHifDevice,
+				   HOST_INTEREST_ITEM_ADDRESS(ar,
+				   hi_end_RAM_reserve_sz),
+				   (u8 *)&ramReservedSz, 4) != 0) {
+			AR_DEBUG_PRINTF(ATH_DEBUG_ERR ,
+					("BMIWriteMemory for "
+					 "hi_end_RAM_reserve_sz failed\n"));
+			return A_ERROR;
+		}
+	}
 
         /* since BMIInit is called in the driver layer, we have to set the block
          * size here for the target */
@@ -1555,9 +1536,6 @@
 {
     dev->netdev_ops = &ar6000_netdev_ops;
     dev->watchdog_timeo = AR6000_TX_TIMEOUT;
-    dev->wireless_handlers = &ath_iw_handler_def;
-
-    ath_iw_handler_def.get_wireless_stats = ar6000_get_iwstats; /*Displayed via proc fs */
 
    /*
     * We need the OS to provide us with more headroom in order to
@@ -1575,10 +1553,6 @@
         strcpy(dev->name, name);
     }
 
-#ifdef SET_MODULE_OWNER
-    SET_MODULE_OWNER(dev);
-#endif
-
 #ifdef CONFIG_CHECKSUM_OFFLOAD
     if(csumOffload){
         dev->features |= NETIF_F_IP_CSUM; /*advertise kernel capability to do TCP/UDP CSUM offload for IPV4*/
@@ -1588,6 +1562,52 @@
     return;
 }
 
+static int __ath6kl_init_netdev(struct net_device *dev)
+{
+	int r;
+
+	rtnl_lock();
+	r = ar6000_init(dev);
+	rtnl_unlock();
+
+	if (r) {
+		AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("ar6000_avail: ar6000_init\n"));
+		return r;
+	}
+
+	return 0;
+}
+
+#ifdef HTC_RAW_INTERFACE
+static int ath6kl_init_netdev_wmi(struct net_device *dev)
+{
+	if (!eppingtest && bypasswmi)
+		return 0;
+
+	return __ath6kl_init_netdev(dev);
+}
+#else
+static int ath6kl_init_netdev_wmi(struct net_device *dev)
+{
+	return __ath6kl_init_netdev(dev);
+}
+#endif
+
+static int ath6kl_init_netdev(struct ar6_softc *ar)
+{
+	int r;
+
+        r = ar6000_sysfs_bmi_get_config(ar, wlaninitmode);
+        if (r) {
+		AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
+				("ar6000_avail: "
+				 "ar6000_sysfs_bmi_get_config failed\n"));
+		return r;
+        }
+
+	return ath6kl_init_netdev_wmi(ar->arNetDev);
+}
+
 /*
  * HTC Event handlers
  */
@@ -1600,10 +1620,8 @@
     struct ar6_softc *ar;
     int device_index = 0;
     struct htc_init_info  htcInfo;
-#ifdef ATH6K_CONFIG_CFG80211
     struct wireless_dev *wdev;
-#endif /* ATH6K_CONFIG_CFG80211 */
-    int init_status = 0;
+    int r = 0;
     struct hif_device_os_device_info osDevInfo;
 
     memset(&osDevInfo, 0, sizeof(osDevInfo));
@@ -1630,22 +1648,12 @@
     /* we use another local "i" variable below.                      */
     device_index = i;
 
-#ifdef ATH6K_CONFIG_CFG80211
     wdev = ar6k_cfg80211_init(osDevInfo.pOSDevice);
     if (IS_ERR(wdev)) {
         AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: ar6k_cfg80211_init failed\n", __func__));
         return A_ERROR;
     }
     ar_netif = wdev_priv(wdev);
-#else
-    dev = alloc_etherdev(sizeof(struct ar6_softc));
-    if (dev == NULL) {
-        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("ar6000_available: can't alloc etherdev\n"));
-        return A_ERROR;
-    }
-    ether_setup(dev);
-    ar_netif = ar6k_priv(dev);
-#endif /* ATH6K_CONFIG_CFG80211 */
 
     if (ar_netif == NULL) {
         AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Can't allocate ar6k priv memory\n", __func__));
@@ -1655,7 +1663,6 @@
     A_MEMZERO(ar_netif, sizeof(struct ar6_softc));
     ar = (struct ar6_softc *)ar_netif;
 
-#ifdef ATH6K_CONFIG_CFG80211
     ar->wdev = wdev;
     wdev->iftype = NL80211_IFTYPE_STATION;
 
@@ -1671,15 +1678,10 @@
     wdev->netdev = dev;
     ar->arNetworkType = INFRA_NETWORK;
     ar->smeState = SME_DISCONNECTED;
-#endif /* ATH6K_CONFIG_CFG80211 */
+    ar->arAutoAuthStage = AUTH_IDLE;
 
     init_netdev(dev, ifname);
 
-#ifdef SET_NETDEV_DEV
-    if (ar_netif) { 
-        SET_NETDEV_DEV(dev, osDevInfo.pOSDevice);
-    }
-#endif 
 
     ar->arNetDev             = dev;
     ar->arHifDevice          = hif_handle;
@@ -1719,35 +1721,23 @@
 
     BMIInit();
 
-    if (bmienable) {
-        ar6000_sysfs_bmi_init(ar);
-    }
+    ar6000_sysfs_bmi_init(ar);
 
     {
         struct bmi_target_info targ_info;
 
-        if (BMIGetTargetInfo(ar->arHifDevice, &targ_info) != 0) {
-            init_status = A_ERROR;
+        r = BMIGetTargetInfo(ar->arHifDevice, &targ_info);
+        if (r)
             goto avail_ev_failed;
-        }
 
         ar->arVersion.target_ver = targ_info.target_ver;
         ar->arTargetType = targ_info.target_type;
-
-            /* do any target-specific preparation that can be done through BMI */
-        if (ar6000_prepare_target(ar->arHifDevice,
-                                  targ_info.target_type,
-                                  targ_info.target_ver) != 0) {
-            init_status = A_ERROR;
-            goto avail_ev_failed;
-        }
-
+	wdev->wiphy->hw_version = targ_info.target_ver;
     }
 
-    if (ar6000_configure_target(ar) != 0) {
-            init_status = A_ERROR;
+    r = ar6000_configure_target(ar);
+    if (r)
             goto avail_ev_failed;
-    }
 
     A_MEMZERO(&htcInfo,sizeof(htcInfo));
     htcInfo.pContext = ar;
@@ -1755,8 +1745,8 @@
 
     ar->arHtcTarget = HTCCreate(ar->arHifDevice,&htcInfo);
 
-    if (ar->arHtcTarget == NULL) {
-        init_status = A_ERROR;
+    if (!ar->arHtcTarget) {
+        r = -ENOMEM;
         goto avail_ev_failed;
     }
 
@@ -1767,22 +1757,19 @@
 #endif
 
 
-#ifdef CONFIG_CHECKSUM_OFFLOAD
     if(csumOffload){
         /*if external frame work is also needed, change and use an extended rxMetaVerion*/
         ar->rxMetaVersion=WMI_META_VERSION_2;
     }
-#endif
 
-#ifdef ATH_AR6K_11N_SUPPORT
-    if((ar->aggr_cntxt = aggr_init(ar6000_alloc_netbufs)) == NULL) {
+    ar->aggr_cntxt = aggr_init(ar6000_alloc_netbufs);
+    if (!ar->aggr_cntxt) {
             AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("%s() Failed to initialize aggr.\n", __func__));
-            init_status = A_ERROR;
+            r = -ENOMEM;
             goto avail_ev_failed;
     }
 
     aggr_register_rx_dispatcher(ar->aggr_cntxt, (void *)dev, ar6000_deliver_frames_to_nw_stack);
-#endif
 
     HIFClaimDevice(ar->arHifDevice, ar);
 
@@ -1791,46 +1778,20 @@
     /* when the module is unloaded.                                  */
     ar6000_devices[device_index] = dev;
 
-    /* Don't install the init function if BMI is requested */
-    if (!bmienable) {
-        ar6000_netdev_ops.ndo_init = ar6000_init;
-    } else {
-        AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("BMI enabled: %d\n", wlaninitmode));
-        if ((wlaninitmode == WLAN_INIT_MODE_UDEV) ||
-            (wlaninitmode == WLAN_INIT_MODE_DRV))
-        {
-            int status = 0;
-            do {
-                if ((status = ar6000_sysfs_bmi_get_config(ar, wlaninitmode)) != 0)
-                {
-                    AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("ar6000_avail: ar6000_sysfs_bmi_get_config failed\n"));
-                    break;
-                }
-#ifdef HTC_RAW_INTERFACE
-                if (!eppingtest && bypasswmi) {
-                    break; /* Don't call ar6000_init for ART */
-                }
-#endif 
-                rtnl_lock();
-                status = (ar6000_init(dev)==0) ? 0 : A_ERROR;
-                rtnl_unlock();
-                if (status) {
-                    AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("ar6000_avail: ar6000_init\n"));
-                }
-            } while (false);
-
-            if (status) {
-                init_status = status;
-                goto avail_ev_failed;
-            }
-        }
+    AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("BMI enabled: %d\n", wlaninitmode));
+    if ((wlaninitmode == WLAN_INIT_MODE_UDEV) ||
+        (wlaninitmode == WLAN_INIT_MODE_DRV)) {
+	r = ath6kl_init_netdev(ar);
+	if (r)
+            goto avail_ev_failed;
     }
 
     /* This runs the init function if registered */
-    if (register_netdev(dev)) {
+    r = register_netdev(dev);
+    if (r) {
         AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("ar6000_avail: register_netdev failed\n"));
         ar6000_destroy(dev, 0);
-        return A_ERROR;
+        return r;
     }
 
 	is_netdev_registered = 1;
@@ -1843,13 +1804,10 @@
                     (unsigned long)ar));
 
 avail_ev_failed :
-    if (init_status) {
-        if (bmienable) { 
-            ar6000_sysfs_bmi_deinit(ar);  
-        }
-    }
+    if (r)
+        ar6000_sysfs_bmi_deinit(ar);  
 
-    return init_status;
+    return r;
 }
 
 static void ar6000_target_failure(void *Instance, int Status)
@@ -1880,9 +1838,6 @@
             sip = true;
             errEvent.errorVal = WMI_TARGET_COM_ERR |
                                 WMI_TARGET_FATAL_ERR;
-            ar6000_send_event_to_app(ar, WMI_ERROR_REPORT_EVENTID,
-                                     (u8 *)&errEvent,
-                                     sizeof(WMI_TARGET_ERROR_REPORT_EVENT));
         }
     }
 }
@@ -1980,10 +1935,8 @@
                     ar6000_disconnect_event(ar, DISCONNECT_CMD, ar->arBssid, 0, NULL, 0);
                 }
             }
-#ifdef USER_KEYS
             ar->user_savedkeys_stat = USER_SAVEDKEYS_STAT_INIT;
             ar->user_key_ctrl      = 0;
-#endif
         }
 
          AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("%s(): WMI stopped\n", __func__));
@@ -2025,15 +1978,6 @@
         if (setuphci)
         	ar6000_cleanup_hci(ar);
 #endif
-#ifdef EXPORT_HCI_PAL_INTERFACE
-        if (setuphcipal && (NULL != ar6kHciPalCallbacks_g.cleanupTransport)) {
-           ar6kHciPalCallbacks_g.cleanupTransport(ar);
-        }
-#else
-				/* cleanup hci pal driver data structures */
-        if(setuphcipal)
-          ar6k_cleanup_hci_pal(ar);
-#endif
         AR_DEBUG_PRINTF(ATH_DEBUG_INFO,(" Shutting down HTC .... \n"));
         /* stop HTC */
         HTCStop(ar->arHtcTarget);
@@ -2094,9 +2038,6 @@
     if (ar->arWlanPowerState != WLAN_POWER_STATE_CUT_PWR) {
         /* only stop endpoint if we are not stop it in suspend_ev */
         ar6000_stop_endpoint(dev, false, true);
-    } else {
-        /* clear up the platform power state before rmmod */
-        plat_setup_power(1,0);
     }
 
     ar->arWlanState = WLAN_DISABLED;
@@ -2110,9 +2051,7 @@
         HIFReleaseDevice(ar->arHifDevice);
         HIFShutDownDevice(ar->arHifDevice);
     }
-#ifdef ATH_AR6K_11N_SUPPORT
     aggr_module_destroy(ar->aggr_cntxt);
-#endif
 
        /* Done with cookies */
     ar6000_cookie_cleanup(ar);
@@ -2120,9 +2059,7 @@
         /* cleanup any allocated AMSDU buffers */
     ar6000_cleanup_amsdu_rxbufs(ar);
 
-    if (bmienable) {
-        ar6000_sysfs_bmi_deinit(ar);
-    }
+    ar6000_sysfs_bmi_deinit(ar);
 
     /* Cleanup BMI */
     BMICleanup();
@@ -2134,7 +2071,7 @@
 
 #ifdef HTC_RAW_INTERFACE
     if (ar->arRawHtc) {
-        A_FREE(ar->arRawHtc);
+        kfree(ar->arRawHtc);
         ar->arRawHtc = NULL;
     }
 #endif 
@@ -2145,9 +2082,7 @@
     }
     free_netdev(dev);
 
-#ifdef ATH6K_CONFIG_CFG80211
     ar6k_cfg80211_deinit(ar);
-#endif /* ATH6K_CONFIG_CFG80211 */
 
 #ifdef CONFIG_AP_VIRTUL_ADAPTER_SUPPORT
     ar6000_remove_ap_interface();
@@ -2187,9 +2122,6 @@
         ar->arHBChallengeResp.seqNum = 0;
         errEvent.errorVal = WMI_TARGET_COM_ERR | WMI_TARGET_FATAL_ERR;
         AR6000_SPIN_UNLOCK(&ar->arLock, 0);
-        ar6000_send_event_to_app(ar, WMI_ERROR_REPORT_EVENTID,
-                                 (u8 *)&errEvent,
-                                 sizeof(WMI_TARGET_ERROR_REPORT_EVENT));
         return;
     }
 
@@ -2295,11 +2227,9 @@
 
     spin_lock_irqsave(&ar->arLock, flags);
 
-#ifdef ATH6K_CONFIG_CFG80211
     if(ar->arWlanState == WLAN_DISABLED) {
         ar->arWlanState = WLAN_ENABLED;
     }
-#endif /* ATH6K_CONFIG_CFG80211 */
 
     if( ar->arConnected || bypasswmi) {
         netif_carrier_on(dev);
@@ -2316,12 +2246,9 @@
 static int
 ar6000_close(struct net_device *dev)
 {
-#ifdef ATH6K_CONFIG_CFG80211
     struct ar6_softc    *ar = (struct ar6_softc *)ar6k_priv(dev);
-#endif /* ATH6K_CONFIG_CFG80211 */
     netif_stop_queue(dev);
 
-#ifdef ATH6K_CONFIG_CFG80211
     ar6000_disconnect(ar);
 
     if(ar->arWmiReady == true) {
@@ -2332,7 +2259,6 @@
         ar->arWlanState = WLAN_DISABLED;
     }
 	ar6k_cfg80211_scanComplete_event(ar, A_ECANCELED);
-#endif /* ATH6K_CONFIG_CFG80211 */
 
     return 0;
 }
@@ -2422,16 +2348,52 @@
     return(arEndpoint2Ac(ar, ep ));
 }
 
+#if defined(CONFIG_ATH6KL_ENABLE_COEXISTENCE)
+static int ath6kl_config_btcoex_params(struct ar6_softc *ar)
+{
+	int r;
+	WMI_SET_BTCOEX_COLOCATED_BT_DEV_CMD sbcb_cmd;
+	WMI_SET_BTCOEX_FE_ANT_CMD sbfa_cmd;
+
+	/* Configure the type of BT collocated with WLAN */
+	memset(&sbcb_cmd, 0, sizeof(WMI_SET_BTCOEX_COLOCATED_BT_DEV_CMD));
+	sbcb_cmd.btcoexCoLocatedBTdev = ATH6KL_BT_DEV;
+
+	r = wmi_set_btcoex_colocated_bt_dev_cmd(ar->arWmi, &sbcb_cmd);
+
+	if (r) {
+		AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
+				("Unable to set collocated BT type\n"));
+		return r;
+	}
+
+	/* Configure the type of BT collocated with WLAN */
+	memset(&sbfa_cmd, 0, sizeof(WMI_SET_BTCOEX_FE_ANT_CMD));
+
+	sbfa_cmd.btcoexFeAntType = ATH6KL_BT_ANTENNA;
+
+	r = wmi_set_btcoex_fe_ant_cmd(ar->arWmi, &sbfa_cmd);
+	if (r) {
+		AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
+				("Unable to set fornt end antenna configuration\n"));
+		return r;
+	}
+
+	return 0;
+}
+#else
+static int ath6kl_config_btcoex_params(struct ar6_softc *ar)
+{
+	return 0;
+}
+#endif /* CONFIG_ATH6KL_ENABLE_COEXISTENCE */
+
 /*
  * This function applies WLAN specific configuration defined in wlan_config.h
  */
 int ar6000_target_config_wlan_params(struct ar6_softc *ar)
 {
     int status = 0;
-#if defined(INIT_MODE_DRV_ENABLED) && defined(ENABLE_COEXISTENCE)
-    WMI_SET_BTCOEX_COLOCATED_BT_DEV_CMD sbcb_cmd;
-    WMI_SET_BTCOEX_FE_ANT_CMD sbfa_cmd;
-#endif /* INIT_MODE_DRV_ENABLED && ENABLE_COEXISTENCE */
 
 #ifdef CONFIG_HOST_TCMD_SUPPORT
     if (ar->arTargetMode != AR6000_WLAN_MODE) {
@@ -2449,39 +2411,9 @@
         status = A_ERROR;
     }
 
-#if defined(INIT_MODE_DRV_ENABLED) && defined(ENABLE_COEXISTENCE)
-    /* Configure the type of BT collocated with WLAN */
-    memset(&sbcb_cmd, 0, sizeof(WMI_SET_BTCOEX_COLOCATED_BT_DEV_CMD));
-#ifdef CONFIG_AR600x_BT_QCOM
-    sbcb_cmd.btcoexCoLocatedBTdev = 1;
-#elif defined(CONFIG_AR600x_BT_CSR)
-    sbcb_cmd.btcoexCoLocatedBTdev = 2;
-#elif defined(CONFIG_AR600x_BT_AR3001)
-    sbcb_cmd.btcoexCoLocatedBTdev = 3;
-#else
-#error Unsupported Bluetooth Type
-#endif /* Collocated Bluetooth Type */
-
-    if ((wmi_set_btcoex_colocated_bt_dev_cmd(ar->arWmi, &sbcb_cmd)) != 0) {
-        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Unable to set collocated BT type\n"));
-        status = A_ERROR;
-    }
-
-    /* Configure the type of BT collocated with WLAN */
-    memset(&sbfa_cmd, 0, sizeof(WMI_SET_BTCOEX_FE_ANT_CMD));
-#ifdef CONFIG_AR600x_DUAL_ANTENNA
-    sbfa_cmd.btcoexFeAntType = 2;
-#elif defined(CONFIG_AR600x_SINGLE_ANTENNA)
-    sbfa_cmd.btcoexFeAntType = 1;
-#else
-#error Unsupported Front-End Antenna Configuration
-#endif /* AR600x Front-End Antenna Configuration */
-
-    if ((wmi_set_btcoex_fe_ant_cmd(ar->arWmi, &sbfa_cmd)) != 0) {
-        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Unable to set fornt end antenna configuration\n"));
-        status = A_ERROR;
-    }
-#endif /* INIT_MODE_DRV_ENABLED && ENABLE_COEXISTENCE */
+    status = ath6kl_config_btcoex_params(ar);
+    if (status)
+	return status;
 
 #if WLAN_CONFIG_IGNORE_POWER_SAVE_FAIL_EVENT_DURING_SCAN
     if ((wmi_pmparams_cmd(ar->arWmi, 0, 1, 0, 0, 1, IGNORE_POWER_SAVE_FAIL_EVENT_DURING_SCAN)) != 0) {
@@ -2736,13 +2668,6 @@
             status = ar6000_setup_hci(ar);
         }
 #endif
-#ifdef EXPORT_HCI_PAL_INTERFACE
-        if (setuphcipal && (NULL != ar6kHciPalCallbacks_g.setupTransport))
-          status = ar6kHciPalCallbacks_g.setupTransport(ar);
-#else
-        if(setuphcipal)
-          status = ar6k_setup_hci_pal(ar);
-#endif
 
     } while (false);
 
@@ -2751,6 +2676,38 @@
         goto ar6000_init_done;
     }
 
+	if (regscanmode) {
+		u32 param;
+
+		if (BMIReadMemory(ar->arHifDevice,
+				  HOST_INTEREST_ITEM_ADDRESS(ar,
+							     hi_option_flag),
+							     (u8 *)&param,
+							     4) != 0) {
+			AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
+					("BMIReadMemory forsetting "
+					 "regscanmode failed\n"));
+			return A_ERROR;
+		}
+
+		if (regscanmode == 1)
+			param |= HI_OPTION_SKIP_REG_SCAN;
+		else if (regscanmode == 2)
+			param |= HI_OPTION_INIT_REG_SCAN;
+
+		if (BMIWriteMemory(ar->arHifDevice,
+				   HOST_INTEREST_ITEM_ADDRESS(ar,
+							      hi_option_flag),
+							      (u8 *)&param,
+							      4) != 0) {
+			AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
+					("BMIWriteMemory forsetting "
+					"regscanmode failed\n"));
+			return A_ERROR;
+		}
+		AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("Regulatory scan mode set\n"));
+	}
+
     /*
      * give our connected endpoints some buffers
      */
@@ -3095,7 +3052,6 @@
         }
 
         if (ar->arWmiEnabled) {
-#ifdef CONFIG_CHECKSUM_OFFLOAD
         u8 csumStart=0;
         u8 csumDest=0;
         u8 csum=skb->ip_summed;
@@ -3104,7 +3060,6 @@
 			 sizeof(ATH_LLC_SNAP_HDR));
             csumDest=skb->csum_offset+csumStart;
         }
-#endif
             if (A_NETBUF_HEADROOM(skb) < dev->hard_header_len - LINUX_HACK_FUDGE_FACTOR) {
                 struct sk_buff  *newbuf;
 
@@ -3135,7 +3090,6 @@
                     break;
                 }
             }
-#ifdef CONFIG_CHECKSUM_OFFLOAD
             if(csumOffload && (csum ==CHECKSUM_PARTIAL)){
                 WMI_TX_META_V2  metaV2;
                 metaV2.csumStart =csumStart;
@@ -3149,7 +3103,6 @@
 
             }
             else
-#endif
             {
                 if (wmi_data_hdr_add(ar->arWmi, skb, DATA_MSGTYPE, bMoreData, dot11Hdr,0,NULL) != 0) {
                     AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("ar6000_data_tx - wmi_data_hdr_add failed\n"));
@@ -3704,8 +3657,23 @@
                 WMI_DATA_HDR *dhdr = (WMI_DATA_HDR *)A_NETBUF_DATA(skb);
                 bool is_amsdu;
                 u8 tid;
-                bool is_acl_data_frame;
-                is_acl_data_frame = WMI_DATA_HDR_GET_DATA_TYPE(dhdr) == WMI_DATA_HDR_DATA_TYPE_ACL;
+
+		/*
+		 * This check can be removed if after a while we do not
+		 * see the warning. For now we leave it to ensure
+		 * we drop these frames accordingly in case the
+		 * target generates them for some reason. These
+		 * were used for an internal PAL but that's not
+		 * used or supported anymore. These frames should
+		 * not come up from the target.
+		 */
+                if (WARN_ON(WMI_DATA_HDR_GET_DATA_TYPE(dhdr) ==
+			    WMI_DATA_HDR_DATA_TYPE_ACL)) {
+			AR6000_STAT_INC(ar, rx_errors);
+			A_NETBUF_FREE(skb);
+			return;
+		}
+
 #ifdef CONFIG_PM 
                 ar6000_check_wow_status(ar, NULL, false);
 #endif /* CONFIG_PM */
@@ -3727,7 +3695,7 @@
                  * ACL data frames don't follow ethernet frame bounds for
                  * min length
                  */
-                if (ar->arNetworkType != AP_NETWORK &&  !is_acl_data_frame &&
+                if (ar->arNetworkType != AP_NETWORK &&
                     ((pPacket->ActualLength < minHdrLen) ||
                     (pPacket->ActualLength > AR6000_MAX_RX_MESSAGE_SIZE)))
                 {
@@ -3767,11 +3735,9 @@
                             case WMI_META_VERSION_1:
                                 offset += sizeof(WMI_RX_META_V1);
                                 break;
-#ifdef CONFIG_CHECKSUM_OFFLOAD
                             case WMI_META_VERSION_2:
                                 offset += sizeof(WMI_RX_META_V2);
                                 break;
-#endif
                             default:
                                 break;
                         }
@@ -3841,7 +3807,6 @@
                                 A_NETBUF_PULL((void*)skb, sizeof(WMI_RX_META_V1));
                                 break;
                             }
-#ifdef CONFIG_CHECKSUM_OFFLOAD
                         case WMI_META_VERSION_2:
                             {
                                 WMI_RX_META_V2 *pMeta = (WMI_RX_META_V2 *)A_NETBUF_DATA(skb);
@@ -3852,7 +3817,6 @@
                                 A_NETBUF_PULL((void*)skb, sizeof(WMI_RX_META_V2));
                                 break;
                             }
-#endif
                         default:
                             break;
                     }
@@ -3862,7 +3826,7 @@
                     /* NWF: print the 802.11 hdr bytes */
                     if(containsDot11Hdr) {
                         status = wmi_dot11_hdr_remove(ar->arWmi,skb);
-                    } else if(!is_amsdu && !is_acl_data_frame) {
+                    } else if(!is_amsdu) {
                         status = wmi_dot3_2_dix(skb);
                     }
 
@@ -3872,16 +3836,6 @@
                         goto rx_done;
                     }
 
-                    if (is_acl_data_frame) {
-                        A_NETBUF_PUSH(skb, sizeof(int));
-                        *((short *)A_NETBUF_DATA(skb)) = WMI_ACL_DATA_EVENTID;
-	                /* send the data packet to PAL driver */
-			if(ar6k_pal_config_g.fpar6k_pal_recv_pkt) {
-				if((*ar6k_pal_config_g.fpar6k_pal_recv_pkt)(ar->hcipal_info, skb) == true)
-					goto rx_done;
-			}
-                    }
-
                     if ((ar->arNetDev->flags & IFF_UP) == IFF_UP) {
                         if (ar->arNetworkType == AP_NETWORK) {
                             struct sk_buff *skb1 = NULL;
@@ -3915,9 +3869,7 @@
                             }
                         }
                     }
-#ifdef ATH_AR6K_11N_SUPPORT
                     aggr_process_recv_frm(ar->aggr_cntxt, tid, seq_no, is_amsdu, (void **)&skb);
-#endif
                     ar6000_deliver_frames_to_nw_stack((void *) ar->arNetDev, (void *)skb);
                 }
             }
@@ -4146,93 +4098,6 @@
     return &ar->arNetStats;
 }
 
-static struct iw_statistics *
-ar6000_get_iwstats(struct net_device * dev)
-{
-    struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev);
-    TARGET_STATS *pStats = &ar->arTargetStats;
-    struct iw_statistics * pIwStats = &ar->arIwStats;
-    int rtnllocked;
-
-    if (ar->bIsDestroyProgress || ar->arWmiReady == false || ar->arWlanState == WLAN_DISABLED)
-    {
-        pIwStats->status = 0;
-        pIwStats->qual.qual = 0;
-        pIwStats->qual.level =0;
-        pIwStats->qual.noise = 0;
-        pIwStats->discard.code =0;
-        pIwStats->discard.retries=0;
-        pIwStats->miss.beacon =0;
-        return pIwStats;
-    }
-
-    /*
-     * The in_atomic function is used to determine if the scheduling is
-     * allowed in the current context or not. This was introduced in 2.6
-     * From what I have read on the differences between 2.4 and 2.6, the
-     * 2.4 kernel did not support preemption and so this check might not
-     * be required for 2.4 kernels.
-     */
-    if (in_atomic())
-    {
-        wmi_get_stats_cmd(ar->arWmi);
-
-        pIwStats->status = 1 ;
-        pIwStats->qual.qual = pStats->cs_aveBeacon_rssi - 161;
-        pIwStats->qual.level =pStats->cs_aveBeacon_rssi; /* noise is -95 dBm */
-        pIwStats->qual.noise = pStats->noise_floor_calibation;
-        pIwStats->discard.code = pStats->rx_decrypt_err;
-        pIwStats->discard.retries = pStats->tx_retry_cnt;
-        pIwStats->miss.beacon = pStats->cs_bmiss_cnt;
-        return pIwStats;
-    }
-
-    dev_hold(dev);   
-    rtnllocked = rtnl_is_locked();
-    if (rtnllocked) {
-        rtnl_unlock();
-    }
-    pIwStats->status = 0;
-
-    if (down_interruptible(&ar->arSem)) {
-        goto err_exit;
-    }
-    
-    do {
-
-        if (ar->bIsDestroyProgress || ar->arWlanState == WLAN_DISABLED) {
-            break;
-        }
-    
-        ar->statsUpdatePending = true;
-    
-        if(wmi_get_stats_cmd(ar->arWmi) != 0) {
-            break;
-        }
-    
-        wait_event_interruptible_timeout(arEvent, ar->statsUpdatePending == false, wmitimeout * HZ);
-        if (signal_pending(current)) {
-            AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("ar6000 : WMI get stats timeout \n"));
-            break;
-        }
-        pIwStats->status = 1 ;
-        pIwStats->qual.qual = pStats->cs_aveBeacon_rssi - 161;
-        pIwStats->qual.level =pStats->cs_aveBeacon_rssi;  /* noise is -95 dBm */
-        pIwStats->qual.noise = pStats->noise_floor_calibation;
-        pIwStats->discard.code = pStats->rx_decrypt_err;
-        pIwStats->discard.retries = pStats->tx_retry_cnt;
-        pIwStats->miss.beacon = pStats->cs_bmiss_cnt;
-    } while (0);
-    up(&ar->arSem);
-
-err_exit:
-    if (rtnllocked) {
-        rtnl_lock();
-    }
-    dev_put(dev);
-    return pIwStats;
-}
-
 void
 ar6000_ready_event(void *devt, u8 *datap, u8 phyCap, u32 sw_ver, u32 abi_ver)
 {
@@ -4254,6 +4119,29 @@
     wake_up(&arEvent);
 }
 
+void ar6000_install_static_wep_keys(struct ar6_softc *ar)
+{
+    u8 index;
+    u8 keyUsage;
+
+    for (index = WMI_MIN_KEY_INDEX; index <= WMI_MAX_KEY_INDEX; index++) {
+        if (ar->arWepKeyList[index].arKeyLen) {
+            keyUsage = GROUP_USAGE;
+            if (index == ar->arDefTxKeyIndex) {
+                keyUsage |= TX_USAGE;
+            }
+            wmi_addKey_cmd(ar->arWmi,
+                           index,
+                           WEP_CRYPT,
+                           keyUsage,
+                           ar->arWepKeyList[index].arKeyLen,
+                           NULL,
+                           ar->arWepKeyList[index].arKey, KEY_OP_INIT_VAL, NULL,
+                           NO_SYNC_WMIFLAG);
+        }
+    }
+}
+
 void
 add_new_sta(struct ar6_softc *ar, u8 *mac, u16 aid, u8 *wpaie,
             u8 ielen, u8 keymgmt, u8 ucipher, u8 auth)
@@ -4344,7 +4232,7 @@
             default:
                 A_PRINTF("AUTH: Unknown\n");
                 break;
-        };
+        }
         switch (listenInterval&0xFF) {
             case WPA_PSK_AUTH:
                 A_PRINTF("KeyMgmt: WPA-PSK\n");
@@ -4355,7 +4243,7 @@
             default:
                 A_PRINTF("KeyMgmt: NONE\n");
                 break;
-        };
+        }
         switch (beaconInterval) {
             case AES_CRYPT:
                 A_PRINTF("Cipher: AES\n");
@@ -4374,7 +4262,7 @@
             default:
                 A_PRINTF("Cipher: NONE\n");
                 break;
-        };
+        }
 
         add_new_sta(ar, bssid, channel /*aid*/,
             assocInfo /* WPA IE */, assocRespLen /* IE len */,
@@ -4392,13 +4280,11 @@
         return;
     }
 
-#ifdef ATH6K_CONFIG_CFG80211
     ar6k_cfg80211_connect_event(ar, channel, bssid,
                                 listenInterval, beaconInterval,
                                 networkType, beaconIeLen,
                                 assocReqLen, assocRespLen,
                                 assocInfo);
-#endif /* ATH6K_CONFIG_CFG80211 */
 
     memcpy(ar->arBssid, bssid, sizeof(ar->arBssid));
     ar->arBssChannel = channel;
@@ -4495,7 +4381,6 @@
         wireless_send_event(ar->arNetDev, IWEVCUSTOM, &wrqu, buf);
     }
 
-#ifdef USER_KEYS
     if (ar->user_savedkeys_stat == USER_SAVEDKEYS_STAT_RUN &&
         ar->user_saved_keys.keyOk == true)
     {
@@ -4508,30 +4393,9 @@
         }
         ar6000_reinstall_keys(ar, key_op_ctrl);
     }
-#endif /* USER_KEYS */
 
     netif_wake_queue(ar->arNetDev);
 
-    /* For CFG80211 the key configuration and the default key comes in after connect so no point in plumbing invalid keys */
-#ifndef ATH6K_CONFIG_CFG80211
-    if ((networkType & ADHOC_NETWORK)      &&
-        (OPEN_AUTH == ar->arDot11AuthMode) &&
-        (NONE_AUTH == ar->arAuthMode)      &&
-        (WEP_CRYPT == ar->arPairwiseCrypto))
-    {
-        if (!ar->arConnected) {
-            wmi_addKey_cmd(ar->arWmi,
-                           ar->arDefTxKeyIndex,
-                           WEP_CRYPT,
-                           GROUP_USAGE | TX_USAGE,
-                           ar->arWepKeyList[ar->arDefTxKeyIndex].arKeyLen,
-                           NULL,
-                           ar->arWepKeyList[ar->arDefTxKeyIndex].arKey, KEY_OP_INIT_VAL, NULL,
-                           NO_SYNC_WMIFLAG);
-        }
-    }
-#endif /* ATH6K_CONFIG_CFG80211 */
-
     /* Update connect & link status atomically */
     spin_lock_irqsave(&ar->arLock, flags);
     ar->arConnected  = true;
@@ -4661,11 +4525,9 @@
         return;
     }
 
-#ifdef ATH6K_CONFIG_CFG80211
     ar6k_cfg80211_disconnect_event(ar, reason, bssid,
                                    assocRespLen, assocInfo,
                                    protocolReasonStatus);
-#endif /* ATH6K_CONFIG_CFG80211 */
 
     /* Send disconnect event to supplicant */
     A_MEMZERO(&wrqu, sizeof(wrqu));
@@ -4751,13 +4613,11 @@
         reconnect_flag = 0;
     }
 
-#ifdef USER_KEYS
     if (reason != CSERV_DISCONNECT)
     {
         ar->user_savedkeys_stat = USER_SAVEDKEYS_STAT_INIT;
         ar->user_key_ctrl      = 0;
     }
-#endif /* USER_KEYS */
 
     netif_stop_queue(ar->arNetDev);
     A_MEMZERO(ar->arBssid, sizeof(ar->arBssid));
@@ -4774,7 +4634,6 @@
     ar->arRegCode = regCode;
 }
 
-#ifdef ATH_AR6K_11N_SUPPORT
 void
 ar6000_aggr_rcv_addba_req_evt(struct ar6_softc *ar, WMI_ADDBA_REQ_EVENT *evt)
 {
@@ -4796,7 +4655,6 @@
 {
     aggr_recv_delba_req_evt(ar->aggr_cntxt, evt->tid);
 }
-#endif
 
 void register_pal_cb(ar6k_pal_config_t *palConfig_p)
 {
@@ -4828,12 +4686,6 @@
     buf += sizeof(int);
     memcpy(buf, cmd->buf, cmd->evt_buf_sz);
 
-    if(ar6k_pal_config_g.fpar6k_pal_recv_pkt)
-    {
-      /* pass the cmd packet to PAL driver */
-      if((*ar6k_pal_config_g.fpar6k_pal_recv_pkt)(ar->hcipal_info, osbuf) == true)
-        return;
-    }
     ar6000_deliver_frames_to_nw_stack(ar->arNetDev, osbuf);
     if(loghci) {
         A_PRINTF_LOG("HCI Event From PAL <-- \n");
@@ -4883,7 +4735,7 @@
         memcpy(pmkcand->bssid.sa_data, info->bssid, ATH_MAC_LEN);
         wrqu.data.length = sizeof(struct iw_pmkid_cand);
         wireless_send_event(ar->arNetDev, IWEVPMKIDCAND, &wrqu, (char *)pmkcand);
-        A_FREE(pmkcand);
+        kfree(pmkcand);
 #else /* WIRELESS_EXT >= 18 */
         snprintf(buf, sizeof(buf), "%s%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x",
                  tag,
@@ -4918,9 +4770,7 @@
             tag, s->mac[0],s->mac[1],s->mac[2],s->mac[3],s->mac[4],s->mac[5]);
     } else {
 
-#ifdef ATH6K_CONFIG_CFG80211
     ar6k_cfg80211_tkip_micerr_event(ar, keyid, ismcast);
-#endif /* ATH6K_CONFIG_CFG80211 */
 
         A_PRINTF("AR6000 TKIP MIC error received for keyid %d %scast\n",
              keyid & 0x3, ismcast ? "multi": "uni");
@@ -4937,9 +4787,7 @@
 ar6000_scanComplete_event(struct ar6_softc *ar, int status)
 {
 
-#ifdef ATH6K_CONFIG_CFG80211
     ar6k_cfg80211_scanComplete_event(ar, status);
-#endif /* ATH6K_CONFIG_CFG80211 */
 
     if (!ar->arUserBssFilter) {
         wmi_bssfilter_cmd(ar->arWmi, NONE_BSS_FILTER, 0);
@@ -5097,19 +4945,13 @@
     userRssiThold.rssi = rssi;
     A_PRINTF("rssi Threshold range = %d tag = %d  rssi = %d\n", newThreshold,
              userRssiThold.tag, userRssiThold.rssi);
-
-    ar6000_send_event_to_app(ar, WMI_RSSI_THRESHOLD_EVENTID,(u8 *)&userRssiThold, sizeof(USER_RSSI_THOLD));
 }
 
 
 void
 ar6000_hbChallengeResp_event(struct ar6_softc *ar, u32 cookie, u32 source)
 {
-    if (source == APP_HB_CHALLENGE) {
-        /* Report it to the app in case it wants a positive acknowledgement */
-        ar6000_send_event_to_app(ar, WMIX_HB_CHALLENGE_RESP_EVENTID,
-                                 (u8 *)&cookie, sizeof(cookie));
-    } else {
+    if (source != APP_HB_CHALLENGE) {
         /* This would ignore the replys that come in after their due time */
         if (cookie == ar->arHBChallengeResp.seqNum) {
             ar->arHBChallengeResp.outstanding = false;
@@ -5562,100 +5404,6 @@
     return cookie;
 }
 
-#ifdef SEND_EVENT_TO_APP
-/*
- * This function is used to send event which come from taget to
- * the application. The buf which send to application is include
- * the event ID and event content.
- */
-#define EVENT_ID_LEN   2
-void ar6000_send_event_to_app(struct ar6_softc *ar, u16 eventId,
-                              u8 *datap, int len)
-{
-
-#if (WIRELESS_EXT >= 15)
-
-/* note: IWEVCUSTOM only exists in wireless extensions after version 15 */
-
-    char *buf;
-    u16 size;
-    union iwreq_data wrqu;
-
-    size = len + EVENT_ID_LEN;
-
-    if (size > IW_CUSTOM_MAX) {
-        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("WMI event ID : 0x%4.4X, len = %d too big for IWEVCUSTOM (max=%d) \n",
-                eventId, size, IW_CUSTOM_MAX));
-        return;
-    }
-
-    buf = A_MALLOC_NOWAIT(size);
-    if (NULL == buf){
-        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("%s: failed to allocate %d bytes\n", __func__, size));
-        return;
-    }
-
-    A_MEMZERO(buf, size);
-    memcpy(buf, &eventId, EVENT_ID_LEN);
-    memcpy(buf+EVENT_ID_LEN, datap, len);
-
-    //AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("event ID = %d,len = %d\n",*(u16 *)buf, size));
-    A_MEMZERO(&wrqu, sizeof(wrqu));
-    wrqu.data.length = size;
-    wireless_send_event(ar->arNetDev, IWEVCUSTOM, &wrqu, buf);
-    A_FREE(buf);
-#endif
-
-
-}
-
-/*
- * This function is used to send events larger than 256 bytes
- * to the application. The buf which is sent to application
- * includes the event ID and event content.
- */
-void ar6000_send_generic_event_to_app(struct ar6_softc *ar, u16 eventId,
-                                      u8 *datap, int len)
-{
-
-#if (WIRELESS_EXT >= 18)
-
-/* IWEVGENIE exists in wireless extensions version 18 onwards */
-
-    char *buf;
-    u16 size;
-    union iwreq_data wrqu;
-
-    size = len + EVENT_ID_LEN;
-
-    if (size > IW_GENERIC_IE_MAX) {
-        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("WMI event ID : 0x%4.4X, len = %d too big for IWEVGENIE (max=%d) \n",
-                        eventId, size, IW_GENERIC_IE_MAX));
-        return;
-    }
-
-    buf = A_MALLOC_NOWAIT(size);
-    if (NULL == buf){
-        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("%s: failed to allocate %d bytes\n", __func__, size));
-        return;
-    }
-
-    A_MEMZERO(buf, size);
-    memcpy(buf, &eventId, EVENT_ID_LEN);
-    memcpy(buf+EVENT_ID_LEN, datap, len);
-
-    A_MEMZERO(&wrqu, sizeof(wrqu));
-    wrqu.data.length = size;
-    wireless_send_event(ar->arNetDev, IWEVGENIE, &wrqu, buf);
-
-    A_FREE(buf);
-
-#endif /* (WIRELESS_EXT >= 18) */
-
-}
-#endif /* SEND_EVENT_TO_APP */
-
-
 void
 ar6000_tx_retry_err_event(void *devt)
 {
@@ -5666,13 +5414,9 @@
 ar6000_snrThresholdEvent_rx(void *devt, WMI_SNR_THRESHOLD_VAL newThreshold, u8 snr)
 {
     WMI_SNR_THRESHOLD_EVENT event;
-    struct ar6_softc *ar = (struct ar6_softc *)devt;
 
     event.range = newThreshold;
     event.snr = snr;
-
-    ar6000_send_event_to_app(ar, WMI_SNR_THRESHOLD_EVENTID, (u8 *)&event,
-                             sizeof(WMI_SNR_THRESHOLD_EVENT));
 }
 
 void
@@ -5999,9 +5743,7 @@
 }
 #endif
 
-#ifdef USER_KEYS
 static int
-
 ar6000_reinstall_keys(struct ar6_softc *ar, u8 key_op_ctrl)
 {
     int status = 0;
@@ -6046,7 +5788,6 @@
 
     return status;
 }
-#endif /* USER_KEYS */
 
 
 void
diff -druN linux-2.6.39-libre/drivers/staging/ath6kl/os/linux/ar6000_pm.c linux-3.0-rc7-libre/drivers/staging/ath6kl/os/linux/ar6000_pm.c
--- linux-2.6.39-libre/drivers/staging/ath6kl/os/linux/ar6000_pm.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/ath6kl/os/linux/ar6000_pm.c	2011-07-11 19:51:52.000000000 -0400
@@ -36,9 +36,6 @@
 extern unsigned int wmitimeout;
 extern wait_queue_head_t arEvent;
 
-#ifdef ANDROID_ENV
-extern void android_ar6k_check_wow_status(struct ar6_softc *ar, struct sk_buff *skb, bool isEvent);
-#endif
 #undef ATH_MODULE_NAME
 #define ATH_MODULE_NAME pm
 #define  ATH_DEBUG_PM       ATH_DEBUG_MAKE_MODULE_MASK(0)
@@ -283,10 +280,6 @@
         /* Wow resume from irq interrupt */
         AR_DEBUG_PRINTF(ATH_DEBUG_PM, ("%s: WoW resume from irq thread status %d\n", __func__, ar->arWlanPowerState));
         ar6000_wow_resume(ar);
-    } else {
-#ifdef ANDROID_ENV
-        android_ar6k_check_wow_status(ar, skb, isEvent);
-#endif
     }
 }
 
@@ -309,37 +302,6 @@
     return status;
 }
 
-static int ar6000_pm_probe(struct platform_device *pdev)
-{
-    plat_setup_power(1,1);
-    return 0;
-}
-
-static int ar6000_pm_remove(struct platform_device *pdev)
-{
-    plat_setup_power(0,1);
-    return 0;
-}
-
-static int ar6000_pm_suspend(struct platform_device *pdev, pm_message_t state)
-{
-    return 0;
-}
-
-static int ar6000_pm_resume(struct platform_device *pdev)
-{
-    return 0;
-}
-
-static struct platform_driver ar6000_pm_device = {
-    .probe      = ar6000_pm_probe,
-    .remove     = ar6000_pm_remove,
-    .suspend    = ar6000_pm_suspend,
-    .resume     = ar6000_pm_resume,
-    .driver     = {
-        .name = "wlan_ar6000_pm",
-    },
-};
 #endif /* CONFIG_PM */
 
 int
@@ -359,8 +321,6 @@
                 break;
             }
 
-            plat_setup_power(1,0);
-
             /* Change the state to ON */
             ar->arWlanPowerState = WLAN_POWER_STATE_ON;
 
@@ -373,17 +333,6 @@
                                 sizeof(HIF_DEVICE_POWER_CHANGE_TYPE));
 
             if (status == A_PENDING) {
-#ifdef ANDROID_ENV
-                 /* Wait for WMI ready event */
-                u32 timeleft = wait_event_interruptible_timeout(arEvent,
-                            (ar->arWmiReady == true), wmitimeout * HZ);
-                if (!timeleft || signal_pending(current)) {
-                    AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("ar6000 : Failed to get wmi ready \n"));
-                    status = A_ERROR;
-                    break;
-                }
-#endif
-                status = 0;
             } else if (status == 0) {
                 ar6000_restart_endpoint(ar->arNetDev);
                 status = 0;
@@ -403,8 +352,6 @@
                                 &config,
                                 sizeof(HIF_DEVICE_POWER_CHANGE_TYPE));
 
-            plat_setup_power(0,0);
-
             ar->arWlanPowerState = WLAN_POWER_STATE_CUT_PWR;
         }
     } while (0);
@@ -642,8 +589,6 @@
         }
         if (pSleepEvent) {
             AR_DEBUG_PRINTF(ATH_DEBUG_PM, ("SENT WLAN Sleep Event %d\n", wmiSleepEvent.sleepState));
-            ar6000_send_event_to_app(ar, WMI_REPORT_SLEEP_STATE_EVENTID, (u8 *)pSleepEvent,
-                                     sizeof(WMI_REPORT_SLEEP_STATE_EVENTID));
         }
     }
     up(&ar->arSem);
@@ -679,25 +624,3 @@
     status = ar6000_update_wlan_pwr_state(ar, state, false);
     return status;
 }
-
-void ar6000_pm_init()
-{
-    A_REGISTER_MODULE_DEBUG_INFO(pm);
-#ifdef CONFIG_PM
-    /*
-     * Register ar6000_pm_device into system.
-     * We should also add platform_device into the first item of array
-     * of devices[] in file arch/xxx/mach-xxx/board-xxxx.c
-     */
-    if (platform_driver_register(&ar6000_pm_device)) {
-        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("ar6000: fail to register the power control driver.\n"));
-    }
-#endif /* CONFIG_PM */
-}
-
-void ar6000_pm_exit()
-{
-#ifdef CONFIG_PM
-    platform_driver_unregister(&ar6000_pm_device);
-#endif /* CONFIG_PM */
-}
diff -druN linux-2.6.39-libre/drivers/staging/ath6kl/os/linux/ar6k_pal.c linux-3.0-rc7-libre/drivers/staging/ath6kl/os/linux/ar6k_pal.c
--- linux-2.6.39-libre/drivers/staging/ath6kl/os/linux/ar6k_pal.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/ath6kl/os/linux/ar6k_pal.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,479 +0,0 @@
-//------------------------------------------------------------------------------
-// Copyright (c) 2004-2010 Atheros Communications Inc.
-// All rights reserved.
-//
-// 
-//
-// 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.
-//
-//
-//
-// Author(s): ="Atheros"
-//------------------------------------------------------------------------------
-
-#include "ar6000_drv.h"
-#ifdef AR6K_ENABLE_HCI_PAL
-#include <net/bluetooth/bluetooth.h>
-#include <net/bluetooth/hci_core.h>
-#include <ar6k_pal.h>
-
-extern unsigned int setupbtdev;
-#define bt_check_bit(val, bit) (val & bit)
-#define bt_set_bit(val, bit) (val |= bit)
-#define bt_clear_bit(val, bit) (val &= ~bit)
-
-/* export ATH_AR6K_DEBUG_HCI_PAL=yes in host/localmake.linux.inc
- * to enable debug information */
-#ifdef HCIPAL_DEBUG
-#define PRIN_LOG(format, args...) printk(KERN_ALERT "%s:%d - %s Msg:" format "\n",__FUNCTION__, __LINE__, __FILE__, ## args) 
-#else
-#define PRIN_LOG(format, args...)
-#endif
-
-/**********************************
- * HCI PAL private info structure 
- *********************************/
-typedef struct ar6k_hci_pal_info_s{
-
-	unsigned long ulFlags;
-#define HCI_NORMAL_MODE (1)
-#define HCI_REGISTERED (1<<1)
-	struct hci_dev *hdev;            /* BT Stack HCI dev */
-	struct ar6_softc *ar;
-
-}ar6k_hci_pal_info_t;
-
-/*** BT Stack Entrypoints *******/
-/***************************************
- * bt_open - open a handle to the device
- ***************************************/
-static int bt_open(struct hci_dev *hdev)
-{
-	PRIN_LOG("HCI PAL: bt_open - enter - x\n");
-	set_bit(HCI_RUNNING, &hdev->flags);
-	set_bit(HCI_UP, &hdev->flags);
-	set_bit(HCI_INIT, &hdev->flags);         
-	return 0;
-}
-
-/***************************************
- * bt_close - close handle to the device
- ***************************************/
-static int bt_close(struct hci_dev *hdev)
-{
-	PRIN_LOG("HCI PAL: bt_close - enter\n");
-	clear_bit(HCI_RUNNING, &hdev->flags);
-	return 0;
-}
-
-/*****************************
- * bt_ioctl - ioctl processing
- *****************************/
-static int bt_ioctl(struct hci_dev *hdev, unsigned int cmd, unsigned long arg)
-{
-	PRIN_LOG("HCI PAL: bt_ioctl - enter\n");
-	return -ENOIOCTLCMD;
-}
-
-/**************************************
- * bt_flush - flush outstanding packets
- **************************************/
-static int bt_flush(struct hci_dev *hdev)
-{
-	PRIN_LOG("HCI PAL: bt_flush - enter\n");
-	return 0;
-}
-
-/***************
- * bt_destruct  
- ***************/
-static void bt_destruct(struct hci_dev *hdev)
-{
-	PRIN_LOG("HCI PAL: bt_destruct - enter\n");
-	/* nothing to do here */
-}
-
-/****************************************************
- * Invoked from bluetooth stack via hdev->send()
- * to send the packet out via ar6k to PAL firmware.
- *
- * For HCI command packet wmi_send_hci_cmd() is invoked.
- * wmi_send_hci_cmd adds WMI_CMD_HDR and sends the packet
- * to PAL firmware.
- *
- * For HCI ACL data packet wmi_data_hdr_add is invoked 
- * to add WMI_DATA_HDR to the packet.  ar6000_acl_data_tx 
- * is then invoked to send the packet to PAL firmware.
- ******************************************************/
-static int btpal_send_frame(struct sk_buff *skb)
-{
-	struct hci_dev *hdev = (struct hci_dev *)skb->dev;
-	HCI_TRANSPORT_PACKET_TYPE type;
-	ar6k_hci_pal_info_t *pHciPalInfo;
-	int status = 0;
-	struct sk_buff *txSkb = NULL;
-	struct ar6_softc *ar;
-
-	if (!hdev) {
-		PRIN_LOG("HCI PAL: btpal_send_frame - no device\n");
-		return -ENODEV;
-	}
-
-	if (!test_bit(HCI_RUNNING, &hdev->flags)) {
-		PRIN_LOG("HCI PAL: btpal_send_frame - not open\n");
-		return -EBUSY;
-	}
-
-	pHciPalInfo = (ar6k_hci_pal_info_t *)hdev->driver_data;   
-	A_ASSERT(pHciPalInfo != NULL);
-	ar = pHciPalInfo->ar;
-
-	PRIN_LOG("+btpal_send_frame type: %d \n",bt_cb(skb)->pkt_type);
-	type = HCI_COMMAND_TYPE;
-
-	switch (bt_cb(skb)->pkt_type) {
-		case HCI_COMMAND_PKT:
-			type = HCI_COMMAND_TYPE;
-			hdev->stat.cmd_tx++;
-			break;
-
-		case HCI_ACLDATA_PKT:
-			type = HCI_ACL_TYPE;
-			hdev->stat.acl_tx++;
-			break;
-
-		case HCI_SCODATA_PKT:
-			/* we don't support SCO over the pal */
-			kfree_skb(skb);
-			return 0;
-		default:
-			A_ASSERT(false);
-			kfree_skb(skb);
-			return 0;
-	} 
-
-	if (AR_DEBUG_LVL_CHECK(ATH_DEBUG_HCI_DUMP)) {
-		A_PRINTF(">>> Send HCI %s packet len: %d\n",
-				(type == HCI_COMMAND_TYPE) ? "COMMAND" : "ACL",
-				skb->len);
-		if (type == HCI_COMMAND_TYPE) {
-			PRIN_LOG("    HCI Command: OGF:0x%X OCF:0x%X \r\n", 
-					HCI_GET_OP_CODE(skb-data) >> 10, HCI_GET_OP_CODE(skb-data) & 0x3FF);
-		}
-		AR_DEBUG_PRINTBUF(skb->data,skb->len,"BT HCI SEND Packet Dump");
-	}
-
-	do {
-		if(type == HCI_COMMAND_TYPE)
-		{
-			PRIN_LOG("HCI command");
-
-			if (ar->arWmiReady == false)
-			{
-				PRIN_LOG("WMI not ready ");
-				break;
-			}
-
-			if (wmi_send_hci_cmd(ar->arWmi, skb->data, skb->len) != 0)
-			{
-				PRIN_LOG("send hci cmd error");
-				break;
-			}
-		}
-		else if(type == HCI_ACL_TYPE)
-		{
-			void *osbuf;
-
-			PRIN_LOG("ACL data");
-			if (ar->arWmiReady == false)
-			{
-				PRIN_LOG("WMI not ready");
-				break;
-			}
-
-			/* need to add WMI header so allocate a skb with more space */
-			txSkb = bt_skb_alloc(TX_PACKET_RSV_OFFSET + WMI_MAX_TX_META_SZ + 
-					sizeof(WMI_DATA_HDR) + skb->len, 
-					GFP_ATOMIC);
-
-			if (txSkb == NULL) {
-				status = A_NO_MEMORY;
-				PRIN_LOG("No memory");
-				break;
-			}
-
-			bt_cb(txSkb)->pkt_type = bt_cb(skb)->pkt_type;
-			txSkb->dev = (void *)pHciPalInfo->hdev;
-			skb_reserve(txSkb, TX_PACKET_RSV_OFFSET + WMI_MAX_TX_META_SZ + sizeof(WMI_DATA_HDR));
-			memcpy(txSkb->data, skb->data, skb->len);
-			skb_put(txSkb,skb->len);
-			/* Add WMI packet type */
-			osbuf = (void *)txSkb;
-
-			if (wmi_data_hdr_add(ar->arWmi, osbuf, DATA_MSGTYPE, 0, WMI_DATA_HDR_DATA_TYPE_ACL,0,NULL) != 0) {
-				PRIN_LOG("XIOCTL_ACL_DATA - wmi_data_hdr_add failed\n");
-			} else {
-				/* Send data buffer over HTC */
-				PRIN_LOG("acl data tx");
-				ar6000_acl_data_tx(osbuf, ar->arNetDev);
-			}
-			txSkb = NULL;
-		}
-	} while (false);
-
-	if (txSkb != NULL) {
-		PRIN_LOG("Free skb");
-		kfree_skb(txSkb);    
-	}
-	kfree_skb(skb);        
-	return 0;
-}
-
-
-/***********************************************
- * Unregister HCI device and free HCI device info
- ***********************************************/
-static void bt_cleanup_hci_pal(ar6k_hci_pal_info_t *pHciPalInfo)
-{   
-	int err;      
-
-	if (bt_check_bit(pHciPalInfo->ulFlags, HCI_REGISTERED)) {
-		bt_clear_bit(pHciPalInfo->ulFlags, HCI_REGISTERED);
-		clear_bit(HCI_RUNNING, &pHciPalInfo->hdev->flags);
-		clear_bit(HCI_UP, &pHciPalInfo->hdev->flags);
-		clear_bit(HCI_INIT, &pHciPalInfo->hdev->flags);   
-		A_ASSERT(pHciPalInfo->hdev != NULL);
-		/* unregister */
-		PRIN_LOG("Unregister PAL device");
-		if ((err = hci_unregister_dev(pHciPalInfo->hdev)) < 0) {
-			PRIN_LOG("HCI PAL: failed to unregister with bluetooth %d\n",err);
-		}          
-	}
-
-	kfree(pHciPalInfo->hdev);
-	pHciPalInfo->hdev = NULL;
-}
-
-/*********************************************************
- * Allocate HCI device and store in PAL private info structure.
- *********************************************************/
-static int bt_setup_hci_pal(ar6k_hci_pal_info_t *pHciPalInfo)
-{
-	int status = 0;
-	struct hci_dev *pHciDev = NULL;
-
-	if (!setupbtdev) {
-		return 0;
-	} 
-
-	do {
-		/* allocate a BT HCI struct for this device */
-		pHciDev = hci_alloc_dev();
-		if (NULL == pHciDev) {
-			PRIN_LOG("HCI PAL driver - failed to allocate BT HCI struct \n");
-			status = A_NO_MEMORY;
-			break;
-		}    
-
-		/* save the device, we'll register this later */
-		pHciPalInfo->hdev = pHciDev;       
-                SET_HCI_BUS_TYPE(pHciDev, HCI_VIRTUAL, HCI_80211);
-		pHciDev->driver_data = pHciPalInfo;
-		pHciDev->open     = bt_open;
-		pHciDev->close    = bt_close;
-		pHciDev->send     = btpal_send_frame;
-		pHciDev->ioctl    = bt_ioctl;
-		pHciDev->flush    = bt_flush;
-		pHciDev->destruct = bt_destruct;
-		pHciDev->owner = THIS_MODULE; 
-		/* driver is running in normal BT mode */
-		PRIN_LOG("Normal mode enabled");
-		bt_set_bit(pHciPalInfo->ulFlags, HCI_NORMAL_MODE);
-
-	} while (false);
-
-	if (status) {
-		bt_cleanup_hci_pal(pHciPalInfo);    
-	}
-	return status;
-}
-
-/**********************************************
- * Cleanup HCI device and free HCI PAL private info
- *********************************************/
-void ar6k_cleanup_hci_pal(void *ar_p)
-{
-	struct ar6_softc *ar = (struct ar6_softc *)ar_p;
-	ar6k_hci_pal_info_t *pHciPalInfo = (ar6k_hci_pal_info_t *)ar->hcipal_info;
-
-	if (pHciPalInfo != NULL) {
-		bt_cleanup_hci_pal(pHciPalInfo);   
-		A_FREE(pHciPalInfo);
-		ar->hcipal_info = NULL;
-	}
-}
-
-/****************************
- *  Register HCI device
- ****************************/
-static bool ar6k_pal_transport_ready(void *pHciPal)
-{
-	ar6k_hci_pal_info_t *pHciPalInfo = (ar6k_hci_pal_info_t *)pHciPal;
-
-	PRIN_LOG("HCI device transport ready");
-	if(pHciPalInfo == NULL)
-		return false;
-
-	if (hci_register_dev(pHciPalInfo->hdev) < 0) {
-		PRIN_LOG("Can't register HCI device");
-		hci_free_dev(pHciPalInfo->hdev);
-		return false;
-	}
-	PRIN_LOG("HCI device registered");
-	pHciPalInfo->ulFlags |= HCI_REGISTERED;
-	return true;
-}
-
-/**************************************************
- * Called from ar6k driver when command or ACL data 
- * packet is received. Pass the packet to bluetooth
- * stack via hci_recv_frame.
- **************************************************/
-bool ar6k_pal_recv_pkt(void *pHciPal, void *osbuf)
-{
-	struct sk_buff *skb = (struct sk_buff *)osbuf;
-	ar6k_hci_pal_info_t *pHciPalInfo;
-	bool success = false;
-	u8 btType = 0;
-	pHciPalInfo = (ar6k_hci_pal_info_t *)pHciPal;
-
-	do {
-
-		/* if normal mode is not enabled pass on to the stack
-		 * by returning failure */
-		if(!(pHciPalInfo->ulFlags & HCI_NORMAL_MODE))
-		{
-			PRIN_LOG("Normal mode not enabled");
-			break;
-		}
-
-		if (!test_bit(HCI_RUNNING, &pHciPalInfo->hdev->flags)) {
-			PRIN_LOG("HCI PAL: HCI - not running\n");
-			break;
-		}
-
-		if(*((short *)A_NETBUF_DATA(skb)) == WMI_ACL_DATA_EVENTID)
-			btType = HCI_ACLDATA_PKT;
-		else
-			btType = HCI_EVENT_PKT;
-		/* pull 4 bytes which contains WMI packet type */
-		A_NETBUF_PULL(skb, sizeof(int));
-		bt_cb(skb)->pkt_type = btType;
-		skb->dev = (void *)pHciPalInfo->hdev;
-
-		/* pass the received event packet up the stack */    
-		if (hci_recv_frame(skb) != 0) {
-			PRIN_LOG("HCI PAL: hci_recv_frame failed \n");
-			break;
-		} else {
-			PRIN_LOG("HCI PAL: Indicated RCV of type:%d, Length:%d \n",HCI_EVENT_PKT, skb->len);
-		}
-		PRIN_LOG("hci recv success");
-		success = true;
-	}while(false);
-	return success;
-}
-
-/**********************************************************
- * HCI PAL init function called from ar6k when it is loaded..
- * Allocates PAL private info, stores the same in ar6k private info.
- * Registers a HCI device.
- * Registers packet receive callback function with ar6k 
- **********************************************************/
-int ar6k_setup_hci_pal(void *ar_p)
-{
-	int status = 0;
-	ar6k_hci_pal_info_t *pHciPalInfo;
-	ar6k_pal_config_t ar6k_pal_config;
-	struct ar6_softc *ar = (struct ar6_softc *)ar_p;
-
-	do {
-
-		pHciPalInfo = (ar6k_hci_pal_info_t *)A_MALLOC(sizeof(ar6k_hci_pal_info_t));
-
-		if (NULL == pHciPalInfo) {
-			status = A_NO_MEMORY;
-			break;    
-		}
-
-		A_MEMZERO(pHciPalInfo, sizeof(ar6k_hci_pal_info_t));
-		ar->hcipal_info = pHciPalInfo;
-		pHciPalInfo->ar = ar;
-
-		status = bt_setup_hci_pal(pHciPalInfo);
-		if (status) {
-			break;    
-		}
-
-		if(bt_check_bit(pHciPalInfo->ulFlags, HCI_NORMAL_MODE))
-			PRIN_LOG("HCI PAL: running in normal mode... \n");    
-		else 
-			PRIN_LOG("HCI PAL: running in test mode... \n");     
-
-		ar6k_pal_config.fpar6k_pal_recv_pkt = ar6k_pal_recv_pkt;
-		register_pal_cb(&ar6k_pal_config);
-		ar6k_pal_transport_ready(ar->hcipal_info);
-	} while (false);
-
-	if (status) {
-		ar6k_cleanup_hci_pal(ar);    
-	}
-	return status;
-}
-#else  /* AR6K_ENABLE_HCI_PAL */
-int ar6k_setup_hci_pal(void *ar_p)
-{
-	return 0;
-}
-void ar6k_cleanup_hci_pal(void *ar_p)
-{
-}
-#endif /* AR6K_ENABLE_HCI_PAL */
-
-#ifdef EXPORT_HCI_PAL_INTERFACE
-/*****************************************************
- * Register init and callback function with ar6k
- * when PAL driver is a separate kernel module.
- ****************************************************/
-int ar6k_register_hci_pal(struct hci_transport_callbacks *hciTransCallbacks);
-static int __init pal_init_module(void)
-{
-	struct hci_transport_callbacks hciTransCallbacks;
-
-	hciTransCallbacks.setupTransport = ar6k_setup_hci_pal;
-	hciTransCallbacks.cleanupTransport = ar6k_cleanup_hci_pal;
-
-	if(ar6k_register_hci_pal(&hciTransCallbacks) != 0)
-		return -ENODEV;
-
-	return 0;
-}
-
-static void __exit pal_cleanup_module(void)
-{
-}
-
-module_init(pal_init_module);
-module_exit(pal_cleanup_module);
-MODULE_LICENSE("Dual BSD/GPL");
-#endif
diff -druN linux-2.6.39-libre/drivers/staging/ath6kl/os/linux/cfg80211.c linux-3.0-rc7-libre/drivers/staging/ath6kl/os/linux/cfg80211.c
--- linux-2.6.39-libre/drivers/staging/ath6kl/os/linux/cfg80211.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/ath6kl/os/linux/cfg80211.c	2011-07-11 19:51:52.000000000 -0400
@@ -172,6 +172,12 @@
     case NL80211_AUTHTYPE_NETWORK_EAP:
         ar->arDot11AuthMode = LEAP_AUTH;
         break;
+
+    case NL80211_AUTHTYPE_AUTOMATIC:
+        ar->arDot11AuthMode = OPEN_AUTH;
+        ar->arAutoAuthStage = AUTH_OPEN_IN_PROGRESS;
+        break;
+
     default:
         ar->arDot11AuthMode = OPEN_AUTH;
         AR_DEBUG_PRINTF(ATH_DEBUG_INFO,
@@ -460,6 +466,8 @@
     assocReqLen -= assocReqIeOffset;
     assocRespLen -= assocRespIeOffset;
 
+    ar->arAutoAuthStage = AUTH_IDLE;
+
     if((ADHOC_NETWORK & networkType)) {
         if(NL80211_IFTYPE_ADHOC != ar->wdev->iftype) {
             AR_DEBUG_PRINTF(ATH_DEBUG_INFO,
@@ -487,74 +495,83 @@
                            ((ADHOC_NETWORK & networkType) ? WLAN_CAPABILITY_IBSS : WLAN_CAPABILITY_ESS),
                            ((ADHOC_NETWORK & networkType) ? WLAN_CAPABILITY_IBSS : WLAN_CAPABILITY_ESS));
 
-    if(!bss) {
-        if (ADHOC_NETWORK & networkType) {
+    /*
+     * Earlier we were updating the cfg about bss by making a beacon frame
+     * only if the entry for bss is not there. This can have some issue if
+     * ROAM event is generated and a heavy traffic is ongoing. The ROAM
+     * event is handled through a work queue and by the time it really gets
+     * handled, BSS would have been aged out. So it is better to update the
+     * cfg about BSS irrespective of its entry being present right now or
+     * not.
+     */
+
+    if (ADHOC_NETWORK & networkType) {
             /* construct 802.11 mgmt beacon */
             if(ptr_ie_buf) {
-                *ptr_ie_buf++ = WLAN_EID_SSID;
-                *ptr_ie_buf++ = ar->arSsidLen;
-                memcpy(ptr_ie_buf, ar->arSsid, ar->arSsidLen);
-                ptr_ie_buf +=ar->arSsidLen;
+		    *ptr_ie_buf++ = WLAN_EID_SSID;
+		    *ptr_ie_buf++ = ar->arSsidLen;
+		    memcpy(ptr_ie_buf, ar->arSsid, ar->arSsidLen);
+		    ptr_ie_buf +=ar->arSsidLen;
 
-                *ptr_ie_buf++ = WLAN_EID_IBSS_PARAMS;
-                *ptr_ie_buf++ = 2; /* length */
-                *ptr_ie_buf++ = 0; /* ATIM window */
-                *ptr_ie_buf++ = 0; /* ATIM window */
+		    *ptr_ie_buf++ = WLAN_EID_IBSS_PARAMS;
+		    *ptr_ie_buf++ = 2; /* length */
+		    *ptr_ie_buf++ = 0; /* ATIM window */
+		    *ptr_ie_buf++ = 0; /* ATIM window */
 
-                /* TODO: update ibss params and include supported rates,
-                 * DS param set, extened support rates, wmm. */
+		    /* TODO: update ibss params and include supported rates,
+		     * DS param set, extened support rates, wmm. */
 
-                ie_buf_len = ptr_ie_buf - ie_buf;
+		    ie_buf_len = ptr_ie_buf - ie_buf;
             }
 
             capability |= IEEE80211_CAPINFO_IBSS;
             if(WEP_CRYPT == ar->arPairwiseCrypto) {
-                capability |= IEEE80211_CAPINFO_PRIVACY;
+		    capability |= IEEE80211_CAPINFO_PRIVACY;
             }
             memcpy(source_mac, ar->arNetDev->dev_addr, ATH_MAC_LEN);
             ptr_ie_buf = ie_buf;
-        } else {
+    } else {
             capability = *(u16 *)(&assocInfo[beaconIeLen]);
             memcpy(source_mac, bssid, ATH_MAC_LEN);
             ptr_ie_buf = assocReqIe;
             ie_buf_len = assocReqLen;
-        }
+    }
 
-        size = offsetof(struct ieee80211_mgmt, u)
-             + sizeof(mgmt->u.beacon)
-             + ie_buf_len;
+    size = offsetof(struct ieee80211_mgmt, u)
+	    + sizeof(mgmt->u.beacon)
+	    + ie_buf_len;
 
-        ieeemgmtbuf = A_MALLOC_NOWAIT(size);
-        if(!ieeemgmtbuf) {
+    ieeemgmtbuf = A_MALLOC_NOWAIT(size);
+    if(!ieeemgmtbuf) {
             AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
                             ("%s: ieeeMgmtbuf alloc error\n", __func__));
+	    cfg80211_put_bss(bss);
             return;
-        }
+    }
 
-        A_MEMZERO(ieeemgmtbuf, size);
-        mgmt = (struct ieee80211_mgmt *)ieeemgmtbuf;
-        mgmt->frame_control = (IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON);
-        memcpy(mgmt->da, bcast_mac, ATH_MAC_LEN);
-        memcpy(mgmt->sa, source_mac, ATH_MAC_LEN);
-        memcpy(mgmt->bssid, bssid, ATH_MAC_LEN);
-        mgmt->u.beacon.beacon_int = beaconInterval;
-        mgmt->u.beacon.capab_info = capability;
-        memcpy(mgmt->u.beacon.variable, ptr_ie_buf, ie_buf_len);
+    A_MEMZERO(ieeemgmtbuf, size);
+    mgmt = (struct ieee80211_mgmt *)ieeemgmtbuf;
+    mgmt->frame_control = (IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON);
+    memcpy(mgmt->da, bcast_mac, ATH_MAC_LEN);
+    memcpy(mgmt->sa, source_mac, ATH_MAC_LEN);
+    memcpy(mgmt->bssid, bssid, ATH_MAC_LEN);
+    mgmt->u.beacon.beacon_int = beaconInterval;
+    mgmt->u.beacon.capab_info = capability;
+    memcpy(mgmt->u.beacon.variable, ptr_ie_buf, ie_buf_len);
 
-        ibss_channel = ieee80211_get_channel(ar->wdev->wiphy, (int)channel);
+    ibss_channel = ieee80211_get_channel(ar->wdev->wiphy, (int)channel);
 
-	AR_DEBUG_PRINTF(ATH_DEBUG_INFO,
-		("%s: inform bss with bssid %pM channel %d beaconInterval %d "
-			"capability 0x%x\n", __func__, mgmt->bssid,
-			ibss_channel->hw_value, beaconInterval, capability));
+    AR_DEBUG_PRINTF(ATH_DEBUG_INFO,
+		    ("%s: inform bss with bssid %pM channel %d beaconInterval %d "
+		     "capability 0x%x\n", __func__, mgmt->bssid,
+		     ibss_channel->hw_value, beaconInterval, capability));
 
-        bss = cfg80211_inform_bss_frame(ar->wdev->wiphy,
-                                        ibss_channel, mgmt,
-                                        le16_to_cpu(size),
-                                        signal, GFP_KERNEL);
-        A_FREE(ieeemgmtbuf);
-        cfg80211_put_bss(bss);
-    }
+    bss = cfg80211_inform_bss_frame(ar->wdev->wiphy,
+				    ibss_channel, mgmt,
+				    le16_to_cpu(size),
+				    signal, GFP_KERNEL);
+    kfree(ieeemgmtbuf);
+    cfg80211_put_bss(bss);
 
     if((ADHOC_NETWORK & networkType)) {
         cfg80211_ibss_joined(ar->arNetDev, bssid, GFP_KERNEL);
@@ -570,7 +587,7 @@
                                 WLAN_STATUS_SUCCESS, GFP_KERNEL);
     } else {
         /* inform roam event to cfg80211 */
-        cfg80211_roamed(ar->arNetDev, bssid,
+	cfg80211_roamed(ar->arNetDev, ibss_channel, bssid,
                         assocReqIe, assocReqLen,
                         assocRespIe, assocRespLen,
                         GFP_KERNEL);
@@ -625,8 +642,14 @@
                                u8 *assocInfo, u16 protocolReasonStatus)
 {
 
+    u16 status;
+
     AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: reason=%u\n", __func__, reason));
 
+    if (ar->scan_request) {
+	cfg80211_scan_done(ar->scan_request, true);
+        ar->scan_request = NULL;
+    }
     if((ADHOC_NETWORK & ar->arNetworkType)) {
         if(NL80211_IFTYPE_ADHOC != ar->wdev->iftype) {
             AR_DEBUG_PRINTF(ATH_DEBUG_INFO,
@@ -651,23 +674,70 @@
             /* connect cmd failed */
             wmi_disconnect_cmd(ar->arWmi);
         } else if (reason == DISCONNECT_CMD) {
-            /* connection loss due to disconnect cmd or low rssi */
-            ar->arConnectPending = false;   
-            if (ar->smeState == SME_CONNECTING) {
-                cfg80211_connect_result(ar->arNetDev, bssid,
-                                        NULL, 0,
-                                        NULL, 0,
-                                        WLAN_STATUS_UNSPECIFIED_FAILURE,
-                                        GFP_KERNEL);
-            } else {
-                cfg80211_disconnected(ar->arNetDev, reason, NULL, 0, GFP_KERNEL);
-            }
-            ar->smeState = SME_DISCONNECTED;
-        }
+		if (ar->arAutoAuthStage) {
+			/*
+			 * If the current auth algorithm is open try shared
+			 * and make autoAuthStage idle. We do not make it
+			 * leap for now being.
+			 */
+			if (ar->arDot11AuthMode == OPEN_AUTH) {
+				struct ar_key *key = NULL;
+				key = &ar->keys[ar->arDefTxKeyIndex];
+				if (down_interruptible(&ar->arSem)) {
+					AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: busy, couldn't get access\n", __func__));
+					return;
+				}
+
+
+				ar->arDot11AuthMode = SHARED_AUTH;
+				ar->arAutoAuthStage = AUTH_IDLE;
+
+				wmi_addKey_cmd(ar->arWmi, ar->arDefTxKeyIndex,
+						ar->arPairwiseCrypto,
+						GROUP_USAGE | TX_USAGE,
+						key->key_len,
+						NULL,
+						key->key, KEY_OP_INIT_VAL, NULL,
+						NO_SYNC_WMIFLAG);
+
+				status = wmi_connect_cmd(ar->arWmi,
+							 ar->arNetworkType,
+							 ar->arDot11AuthMode,
+							 ar->arAuthMode,
+							 ar->arPairwiseCrypto,
+							 ar->arPairwiseCryptoLen,
+							 ar->arGroupCrypto,
+							 ar->arGroupCryptoLen,
+							 ar->arSsidLen,
+							 ar->arSsid,
+							 ar->arReqBssid,
+							 ar->arChannelHint,
+							 ar->arConnectCtrlFlags);
+				up(&ar->arSem);
+
+			} else if (ar->arDot11AuthMode == SHARED_AUTH) {
+				/* should not reach here */
+			}
+		} else {
+			ar->arConnectPending = false;
+			if (ar->smeState == SME_CONNECTING) {
+				cfg80211_connect_result(ar->arNetDev, bssid,
+							NULL, 0,
+							NULL, 0,
+							WLAN_STATUS_UNSPECIFIED_FAILURE,
+							GFP_KERNEL);
+			} else {
+				cfg80211_disconnected(ar->arNetDev,
+						      reason,
+						      NULL, 0,
+						      GFP_KERNEL);
+			}
+			ar->smeState = SME_DISCONNECTED;
+		}
+	}
     } else {
-        if (reason != DISCONNECT_CMD) {
-            wmi_disconnect_cmd(ar->arWmi);
-        }
+	    if (reason != DISCONNECT_CMD)
+		    wmi_disconnect_cmd(ar->arWmi);
     }
 }
 
@@ -729,7 +799,7 @@
                               le16_to_cpu(size),
                               signal, GFP_KERNEL);
 
-    A_FREE (ieeemgmtbuf);
+    kfree (ieeemgmtbuf);
 }
 
 static int
@@ -800,7 +870,8 @@
     if(ar->scan_request)
     {
         /* Translate data to cfg80211 mgmt format */
-        wmi_iterate_nodes(ar->arWmi, ar6k_cfg80211_scan_node, ar->wdev->wiphy);
+	if (ar->arWmi)
+		wmi_iterate_nodes(ar->arWmi, ar6k_cfg80211_scan_node, ar->wdev->wiphy);
 
         cfg80211_scan_done(ar->scan_request,
             ((status & A_ECANCELED) || (status & A_EBUSY)) ? true : false);
@@ -1205,10 +1276,10 @@
 
     if(pmgmt) {
         AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: Max Perf\n", __func__));
-        pwrMode.powerMode = MAX_PERF_POWER;
+        pwrMode.powerMode = REC_POWER;
     } else {
         AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: Rec Power\n", __func__));
-        pwrMode.powerMode = REC_POWER;
+        pwrMode.powerMode = MAX_PERF_POWER;
     }
 
     if(wmi_powermode_cmd(ar->arWmi, pwrMode.powerMode) != 0) {
@@ -1391,6 +1462,151 @@
     WLAN_CIPHER_SUITE_CCMP,
 };
 
+bool is_rate_legacy(s32 rate)
+{
+	static const s32 legacy[] = { 1000, 2000, 5500, 11000,
+				      6000, 9000, 12000, 18000, 24000,
+				      36000, 48000, 54000 };
+	u8 i;
+
+	for (i = 0; i < ARRAY_SIZE(legacy); i++) {
+		if (rate == legacy[i])
+			return true;
+	}
+
+	return false;
+}
+
+bool is_rate_ht20(s32 rate, u8 *mcs, bool *sgi)
+{
+	static const s32 ht20[] = { 6500, 13000, 19500, 26000, 39000,
+				    52000, 58500, 65000, 72200 };
+	u8 i;
+
+	for (i = 0; i < ARRAY_SIZE(ht20); i++) {
+		if (rate == ht20[i]) {
+			if (i == ARRAY_SIZE(ht20) - 1)
+				/* last rate uses sgi */
+				*sgi = true;
+			else
+				*sgi = false;
+
+			*mcs = i;
+			return true;
+		}
+	}
+	return false;
+}
+
+bool is_rate_ht40(s32 rate, u8 *mcs, bool *sgi)
+{
+	static const s32 ht40[] = { 13500, 27000, 40500, 54000,
+				    81000, 108000, 121500, 135000,
+				    150000 };
+	u8 i;
+
+	for (i = 0; i < ARRAY_SIZE(ht40); i++) {
+		if (rate == ht40[i]) {
+			if (i == ARRAY_SIZE(ht40) - 1)
+				/* last rate uses sgi */
+				*sgi = true;
+			else
+				*sgi = false;
+
+			*mcs = i;
+			return true;
+		}
+	}
+
+	return false;
+}
+
+static int ar6k_get_station(struct wiphy *wiphy, struct net_device *dev,
+			    u8 *mac, struct station_info *sinfo)
+{
+	struct ar6_softc *ar = ar6k_priv(dev);
+	long left;
+	bool sgi;
+	s32 rate;
+	int ret;
+	u8 mcs;
+
+	if (memcmp(mac, ar->arBssid, ETH_ALEN) != 0)
+		return -ENOENT;
+
+	if (down_interruptible(&ar->arSem))
+		return -EBUSY;
+
+	ar->statsUpdatePending = true;
+
+	ret = wmi_get_stats_cmd(ar->arWmi);
+
+	if (ret != 0) {
+		up(&ar->arSem);
+		return -EIO;
+	}
+
+	left = wait_event_interruptible_timeout(arEvent,
+						ar->statsUpdatePending == false,
+						wmitimeout * HZ);
+
+	up(&ar->arSem);
+
+	if (left == 0)
+		return -ETIMEDOUT;
+	else if (left < 0)
+		return left;
+
+	if (ar->arTargetStats.rx_bytes) {
+		sinfo->rx_bytes = ar->arTargetStats.rx_bytes;
+		sinfo->filled |= STATION_INFO_RX_BYTES;
+		sinfo->rx_packets = ar->arTargetStats.rx_packets;
+		sinfo->filled |= STATION_INFO_RX_PACKETS;
+	}
+
+	if (ar->arTargetStats.tx_bytes) {
+		sinfo->tx_bytes = ar->arTargetStats.tx_bytes;
+		sinfo->filled |= STATION_INFO_TX_BYTES;
+		sinfo->tx_packets = ar->arTargetStats.tx_packets;
+		sinfo->filled |= STATION_INFO_TX_PACKETS;
+	}
+
+	sinfo->signal = ar->arTargetStats.cs_rssi;
+	sinfo->filled |= STATION_INFO_SIGNAL;
+
+	rate = ar->arTargetStats.tx_unicast_rate;
+
+	if (is_rate_legacy(rate)) {
+		sinfo->txrate.legacy = rate / 100;
+	} else if (is_rate_ht20(rate, &mcs, &sgi)) {
+		if (sgi) {
+			sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
+			sinfo->txrate.mcs = mcs - 1;
+		} else {
+			sinfo->txrate.mcs = mcs;
+		}
+
+		sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
+	} else if (is_rate_ht40(rate, &mcs, &sgi)) {
+		if (sgi) {
+			sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
+			sinfo->txrate.mcs = mcs - 1;
+		} else {
+			sinfo->txrate.mcs = mcs;
+		}
+
+		sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
+		sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
+	} else {
+		WARN(1, "invalid rate: %d", rate);
+		return 0;
+	}
+
+	sinfo->filled |= STATION_INFO_TX_BITRATE;
+
+	return 0;
+}
+
 static struct
 cfg80211_ops ar6k_cfg80211_ops = {
     .change_virtual_intf = ar6k_cfg80211_change_iface,
@@ -1411,6 +1627,7 @@
     .set_power_mgmt = ar6k_cfg80211_set_power_mgmt,
     .join_ibss = ar6k_cfg80211_join_ibss,
     .leave_ibss = ar6k_cfg80211_leave_ibss,
+    .get_station = ar6k_get_station,
 };
 
 struct wireless_dev *
diff -druN linux-2.6.39-libre/drivers/staging/ath6kl/os/linux/eeprom.c linux-3.0-rc7-libre/drivers/staging/ath6kl/os/linux/eeprom.c
--- linux-2.6.39-libre/drivers/staging/ath6kl/os/linux/eeprom.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/ath6kl/os/linux/eeprom.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,574 +0,0 @@
-//------------------------------------------------------------------------------
-// Copyright (c) 2004-2010 Atheros Communications Inc.
-// All rights reserved.
-//
-// 
-//
-// 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.
-//
-//
-//
-// Author(s): ="Atheros"
-//------------------------------------------------------------------------------
-
-
-#include "ar6000_drv.h"
-#include "htc.h"
-#include <linux/fs.h>
-
-#include "AR6002/hw2.0/hw/gpio_reg.h"
-#include "AR6002/hw2.0/hw/si_reg.h"
-
-//
-// defines
-//
-
-#define MAX_FILENAME 1023
-#define EEPROM_WAIT_LIMIT 16 
-
-#define HOST_INTEREST_ITEM_ADDRESS(item)          \
-        (AR6002_HOST_INTEREST_ITEM_ADDRESS(item))
-
-#define EEPROM_SZ 768
-
-/* soft mac */
-#define ATH_MAC_LEN                         6
-#define ATH_SOFT_MAC_TMP_BUF_LEN            64
-unsigned char mac_addr[ATH_MAC_LEN];
-unsigned char soft_mac_tmp_buf[ATH_SOFT_MAC_TMP_BUF_LEN];
-char *p_mac = NULL;
-/* soft mac */
-
-//
-// static variables
-//
-
-static u8 eeprom_data[EEPROM_SZ];
-static u32 sys_sleep_reg;
-static struct hif_device *p_bmi_device;
-
-//
-// Functions
-//
-
-/* soft mac */
-static int
-wmic_ether_aton(const char *orig, u8 *eth)
-{
-  const char *bufp;
-  int i;
-
-  i = 0;
-  for(bufp = orig; *bufp != '\0'; ++bufp) {
-    unsigned int val;
-	int h, l;
-
-	h = hex_to_bin(*bufp++);
-
-	if (h < 0) {
-		printk("%s: MAC value is invalid\n", __FUNCTION__);
-		break;
-	}
-
-	l = hex_to_bin(*bufp++);
-	if (l < 0) {
-		printk("%s: MAC value is invalid\n", __FUNCTION__);
-		break;
-	}
-
-	val = (h << 4) | l;
-
-    eth[i] = (unsigned char) (val & 0377);
-    if(++i == ATH_MAC_LEN) {
-	    /* That's it.  Any trailing junk? */
-	    if (*bufp != '\0') {
-		    return 0;
-	    }
-	    return 1;
-    }
-    if (*bufp != ':')
-	    break;
-  }
-  return 0;
-}
-
-static void
-update_mac(unsigned char *eeprom, int size, unsigned char *macaddr)
-{
-	int i;
-	u16 *ptr = (u16 *)(eeprom+4);
-	u16 checksum = 0;
-
-	memcpy(eeprom+10,macaddr,6);
-
-	*ptr = 0;
-	ptr = (u16 *)eeprom;
-
-	for (i=0; i<size; i+=2) {
-		checksum ^= *ptr++;
-	}
-	checksum = ~checksum;
-
-	ptr = (u16 *)(eeprom+4);
-	*ptr = checksum;
-	return;
-}
-/* soft mac */
-
-/* Read a Target register and return its value. */
-inline void
-BMI_read_reg(u32 address, u32 *pvalue)
-{
-    BMIReadSOCRegister(p_bmi_device, address, pvalue);
-}
-
-/* Write a value to a Target register. */
-inline void
-BMI_write_reg(u32 address, u32 value)
-{
-    BMIWriteSOCRegister(p_bmi_device, address, value);
-}
-
-/* Read Target memory word and return its value. */
-inline void
-BMI_read_mem(u32 address, u32 *pvalue)
-{
-    BMIReadMemory(p_bmi_device, address, (u8*)(pvalue), 4);
-}
-
-/* Write a word to a Target memory. */
-inline void
-BMI_write_mem(u32 address, u8 *p_data, u32 sz)
-{
-    BMIWriteMemory(p_bmi_device, address, (u8*)(p_data), sz); 
-}
-
-/*
- * Enable and configure the Target's Serial Interface
- * so we can access the EEPROM.
- */
-static void
-enable_SI(struct hif_device *p_device)
-{
-    u32 regval;
-
-    printk("%s\n", __FUNCTION__);
-
-    p_bmi_device = p_device;
-
-    BMI_read_reg(RTC_BASE_ADDRESS+SYSTEM_SLEEP_OFFSET, &sys_sleep_reg);
-    BMI_write_reg(RTC_BASE_ADDRESS+SYSTEM_SLEEP_OFFSET, SYSTEM_SLEEP_DISABLE_SET(1)); //disable system sleep temporarily
-
-    BMI_read_reg(RTC_BASE_ADDRESS+CLOCK_CONTROL_OFFSET, &regval);
-    regval &= ~CLOCK_CONTROL_SI0_CLK_MASK;
-    BMI_write_reg(RTC_BASE_ADDRESS+CLOCK_CONTROL_OFFSET, regval);
-
-    BMI_read_reg(RTC_BASE_ADDRESS+RESET_CONTROL_OFFSET, &regval);
-    regval &= ~RESET_CONTROL_SI0_RST_MASK;
-    BMI_write_reg(RTC_BASE_ADDRESS+RESET_CONTROL_OFFSET, regval);
-
-
-    BMI_read_reg(GPIO_BASE_ADDRESS+GPIO_PIN0_OFFSET, &regval);
-    regval &= ~GPIO_PIN0_CONFIG_MASK;
-    BMI_write_reg(GPIO_BASE_ADDRESS+GPIO_PIN0_OFFSET, regval);
-
-    BMI_read_reg(GPIO_BASE_ADDRESS+GPIO_PIN1_OFFSET, &regval);
-    regval &= ~GPIO_PIN1_CONFIG_MASK;
-    BMI_write_reg(GPIO_BASE_ADDRESS+GPIO_PIN1_OFFSET, regval);
-
-    /* SI_CONFIG = 0x500a6; */
-    regval =    SI_CONFIG_BIDIR_OD_DATA_SET(1)  |
-                SI_CONFIG_I2C_SET(1)            |
-                SI_CONFIG_POS_SAMPLE_SET(1)     |
-                SI_CONFIG_INACTIVE_CLK_SET(1)   |
-                SI_CONFIG_INACTIVE_DATA_SET(1)   |
-                SI_CONFIG_DIVIDER_SET(6);
-    BMI_write_reg(SI_BASE_ADDRESS+SI_CONFIG_OFFSET, regval);
-    
-}
-
-static void
-disable_SI(void)
-{
-    u32 regval;
-    
-    printk("%s\n", __FUNCTION__);
-
-    BMI_write_reg(RTC_BASE_ADDRESS+RESET_CONTROL_OFFSET, RESET_CONTROL_SI0_RST_MASK);
-    BMI_read_reg(RTC_BASE_ADDRESS+CLOCK_CONTROL_OFFSET, &regval);
-    regval |= CLOCK_CONTROL_SI0_CLK_MASK;
-    BMI_write_reg(RTC_BASE_ADDRESS+CLOCK_CONTROL_OFFSET, regval);//Gate SI0 clock
-    BMI_write_reg(RTC_BASE_ADDRESS+SYSTEM_SLEEP_OFFSET, sys_sleep_reg); //restore system sleep setting
-}
-
-/*
- * Tell the Target to start an 8-byte read from EEPROM,
- * putting the results in Target RX_DATA registers.
- */
-static void
-request_8byte_read(int offset)
-{
-    u32 regval;
-
-//    printk("%s: request_8byte_read from offset 0x%x\n", __FUNCTION__, offset);
-
-    
-    /* SI_TX_DATA0 = read from offset */
-        regval =(0xa1<<16)|
-                ((offset & 0xff)<<8)    |
-                (0xa0 | ((offset & 0xff00)>>7));
-    
-        BMI_write_reg(SI_BASE_ADDRESS+SI_TX_DATA0_OFFSET, regval);
-
-        regval = SI_CS_START_SET(1)      |
-                SI_CS_RX_CNT_SET(8)     |
-                SI_CS_TX_CNT_SET(3);
-        BMI_write_reg(SI_BASE_ADDRESS+SI_CS_OFFSET, regval);
-}
-
-/*
- * Tell the Target to start a 4-byte write to EEPROM,
- * writing values from Target TX_DATA registers.
- */
-static void
-request_4byte_write(int offset, u32 data)
-{
-    u32 regval;
-
-    printk("%s: request_4byte_write (0x%x) to offset 0x%x\n", __FUNCTION__, data, offset);
-
-        /* SI_TX_DATA0 = write data to offset */
-        regval =    ((data & 0xffff) <<16)    |
-                ((offset & 0xff)<<8)    |
-                (0xa0 | ((offset & 0xff00)>>7));
-        BMI_write_reg(SI_BASE_ADDRESS+SI_TX_DATA0_OFFSET, regval);
-
-        regval =    data >> 16;
-        BMI_write_reg(SI_BASE_ADDRESS+SI_TX_DATA1_OFFSET, regval);
-
-        regval =    SI_CS_START_SET(1)      |
-                SI_CS_RX_CNT_SET(0)     |
-                SI_CS_TX_CNT_SET(6);
-        BMI_write_reg(SI_BASE_ADDRESS+SI_CS_OFFSET, regval);
-}
-
-/*
- * Check whether or not an EEPROM request that was started
- * earlier has completed yet.
- */
-static bool
-request_in_progress(void)
-{
-    u32 regval;
-
-    /* Wait for DONE_INT in SI_CS */
-    BMI_read_reg(SI_BASE_ADDRESS+SI_CS_OFFSET, &regval);
-
-//    printk("%s: request in progress SI_CS=0x%x\n", __FUNCTION__, regval);
-    if (regval & SI_CS_DONE_ERR_MASK) {
-        printk("%s: EEPROM signaled ERROR (0x%x)\n", __FUNCTION__, regval);
-    }
-
-    return (!(regval & SI_CS_DONE_INT_MASK));
-}
-
-/*
- * try to detect the type of EEPROM,16bit address or 8bit address
- */
-
-static void eeprom_type_detect(void)
-{
-    u32 regval;
-    u8 i = 0;
-
-    request_8byte_read(0x100);
-   /* Wait for DONE_INT in SI_CS */
-    do{
-        BMI_read_reg(SI_BASE_ADDRESS+SI_CS_OFFSET, &regval);
-        if (regval & SI_CS_DONE_ERR_MASK) {
-            printk("%s: ERROR : address type was wrongly set\n", __FUNCTION__);     
-            break;
-        }
-        if (i++ == EEPROM_WAIT_LIMIT) {
-            printk("%s: EEPROM not responding\n", __FUNCTION__);
-        }
-    } while(!(regval & SI_CS_DONE_INT_MASK));
-}
-
-/*
- * Extract the results of a completed EEPROM Read request
- * and return them to the caller.
- */
-inline void
-read_8byte_results(u32 *data)
-{
-    /* Read SI_RX_DATA0 and SI_RX_DATA1 */
-    BMI_read_reg(SI_BASE_ADDRESS+SI_RX_DATA0_OFFSET, &data[0]);
-    BMI_read_reg(SI_BASE_ADDRESS+SI_RX_DATA1_OFFSET, &data[1]);
-}
-
-
-/*
- * Wait for a previously started command to complete.
- * Timeout if the command is takes "too long".
- */
-static void
-wait_for_eeprom_completion(void)
-{
-    int i=0;
-
-    while (request_in_progress()) {
-        if (i++ == EEPROM_WAIT_LIMIT) {
-            printk("%s: EEPROM not responding\n", __FUNCTION__);
-        }
-    }
-}
-
-/*
- * High-level function which starts an 8-byte read,
- * waits for it to complete, and returns the result.
- */
-static void
-fetch_8bytes(int offset, u32 *data)
-{
-    request_8byte_read(offset);
-    wait_for_eeprom_completion();
-    read_8byte_results(data);
-
-    /* Clear any pending intr */
-    BMI_write_reg(SI_BASE_ADDRESS+SI_CS_OFFSET, SI_CS_DONE_INT_MASK);
-}
-
-/*
- * High-level function which starts a 4-byte write,
- * and waits for it to complete.
- */
-inline void
-commit_4bytes(int offset, u32 data)
-{
-    request_4byte_write(offset, data);
-    wait_for_eeprom_completion();
-}
-/* ATHENV */
-#ifdef ANDROID_ENV
-void eeprom_ar6000_transfer(struct hif_device *device, char *fake_file, char *p_mac)
-{
-    u32 first_word;
-    u32 board_data_addr;
-    int i;
-
-    printk("%s: Enter\n", __FUNCTION__);
-
-    enable_SI(device);
-    eeprom_type_detect();
-
-    if (fake_file) {
-        /*
-         * Transfer from file to Target RAM.
-         * Fetch source data from file.
-         */
-        mm_segment_t		oldfs;
-        struct file		*filp;
-        struct inode		*inode = NULL;
-        int			length;
-
-        /* open file */
-        oldfs = get_fs();
-        set_fs(KERNEL_DS);
-        filp = filp_open(fake_file, O_RDONLY, S_IRUSR);
-
-        if (IS_ERR(filp)) {
-            printk("%s: file %s filp_open error\n", __FUNCTION__, fake_file);
-            set_fs(oldfs);
-            return;
-        }
-
-        if (!filp->f_op) {
-            printk("%s: File Operation Method Error\n", __FUNCTION__);
-            filp_close(filp, NULL);
-            set_fs(oldfs);
-            return;
-        }
-
-        inode = GET_INODE_FROM_FILEP(filep);
-        if (!inode) {
-            printk("%s: Get inode from filp failed\n", __FUNCTION__);
-            filp_close(filp, NULL);
-            set_fs(oldfs);
-            return;
-        }
-
-        printk("%s file offset opsition: %xh\n", __FUNCTION__, (unsigned)filp->f_pos);
-
-        /* file's size */
-        length = i_size_read(inode->i_mapping->host);
-        printk("%s: length=%d\n", __FUNCTION__, length);
-        if (length != EEPROM_SZ) {
-            printk("%s: The file's size is not as expected\n", __FUNCTION__);
-            filp_close(filp, NULL);
-            set_fs(oldfs);
-            return;
-        }
-
-        /* read data */
-        if (filp->f_op->read(filp, eeprom_data, length, &filp->f_pos) != length) {
-            printk("%s: file read error\n", __FUNCTION__);
-            filp_close(filp, NULL);
-            set_fs(oldfs);
-            return;
-        }
-
-        /* read data out successfully */
-        filp_close(filp, NULL);
-        set_fs(oldfs);
-    } else {
-        /*
-         * Read from EEPROM to file OR transfer from EEPROM to Target RAM.
-         * Fetch EEPROM_SZ Bytes of Board Data, 8 bytes at a time.
-         */
-
-        fetch_8bytes(0, (u32 *)(&eeprom_data[0]));
-
-        /* Check the first word of EEPROM for validity */
-        first_word = *((u32 *)eeprom_data);
-
-        if ((first_word == 0) || (first_word == 0xffffffff)) {
-            printk("Did not find EEPROM with valid Board Data.\n");
-        }
-
-        for (i=8; i<EEPROM_SZ; i+=8) {
-            fetch_8bytes(i, (u32 *)(&eeprom_data[i]));
-        }
-    }
-
-    /* soft mac */
-    if (p_mac) {
-
-        mm_segment_t		oldfs;
-        struct file		*filp;
-        struct inode		*inode = NULL;
-        int			length;
-        
-        /* open file */
-        oldfs = get_fs();
-        set_fs(KERNEL_DS);
-        filp = filp_open(p_mac, O_RDONLY, S_IRUSR);
-        
-        printk("%s try to open file %s\n", __FUNCTION__, p_mac);
-
-        if (IS_ERR(filp)) {
-            printk("%s: file %s filp_open error\n", __FUNCTION__, p_mac);
-            set_fs(oldfs);
-            return;
-        }
-        
-        if (!filp->f_op) {
-            printk("%s: File Operation Method Error\n", __FUNCTION__);
-            filp_close(filp, NULL);
-            set_fs(oldfs);
-            return;
-        }
-        
-        inode = GET_INODE_FROM_FILEP(filep);
-        if (!inode) {
-            printk("%s: Get inode from filp failed\n", __FUNCTION__);
-            filp_close(filp, NULL);
-            set_fs(oldfs);
-            return;
-        }
-        
-        printk("%s file offset opsition: %xh\n", __FUNCTION__, (unsigned)filp->f_pos);
-        
-        /* file's size */
-        length = i_size_read(inode->i_mapping->host);
-        printk("%s: length=%d\n", __FUNCTION__, length);
-        if (length > ATH_SOFT_MAC_TMP_BUF_LEN) {
-            printk("%s: MAC file's size is not as expected\n", __FUNCTION__);
-            filp_close(filp, NULL);
-            set_fs(oldfs);
-            return;
-        }
-        
-        /* read data */
-        if (filp->f_op->read(filp, soft_mac_tmp_buf, length, &filp->f_pos) != length) {
-            printk("%s: file read error\n", __FUNCTION__);
-            filp_close(filp, NULL);
-            set_fs(oldfs);
-            return;
-        }
-
-#if 0
-        /* the data we just read */
-        printk("%s: mac address from the file:\n", __FUNCTION__);
-        for (i = 0; i < length; i++)
-            printk("[%c(0x%x)],", soft_mac_tmp_buf[i], soft_mac_tmp_buf[i]);
-        printk("\n");
-#endif
-
-        /* read data out successfully */
-        filp_close(filp, NULL);
-        set_fs(oldfs);
-
-        /* convert mac address */
-        if (!wmic_ether_aton(soft_mac_tmp_buf, mac_addr)) {
-            printk("%s: convert mac value fail\n", __FUNCTION__);
-            return;
-        }
-
-#if 0
-        /* the converted mac address */
-        printk("%s: the converted mac value\n", __FUNCTION__);
-        for (i = 0; i < ATH_MAC_LEN; i++)
-            printk("[0x%x],", mac_addr[i]);
-        printk("\n");
-#endif
-    }
-    /* soft mac */
-
-    /* Determine where in Target RAM to write Board Data */
-    BMI_read_mem( HOST_INTEREST_ITEM_ADDRESS(hi_board_data), &board_data_addr);
-    if (board_data_addr == 0) {
-        printk("hi_board_data is zero\n");
-    }
-
-    /* soft mac */
-#if 1
-    /* Update MAC address in RAM */
-    if (p_mac) {
-	    update_mac(eeprom_data, EEPROM_SZ, mac_addr);
-    }
-#endif
-#if 0
-    /* mac address in eeprom array */
-    printk("%s: mac values in eeprom array\n", __FUNCTION__);
-    for (i = 10; i < 10 + 6; i++)
-        printk("[0x%x],", eeprom_data[i]);
-    printk("\n");
-#endif
-    /* soft mac */
-
-    /* Write EEPROM data to Target RAM */
-    BMI_write_mem(board_data_addr, ((u8 *)eeprom_data), EEPROM_SZ);
-
-    /* Record the fact that Board Data IS initialized */
-    {
-       u32 one = 1;
-       BMI_write_mem(HOST_INTEREST_ITEM_ADDRESS(hi_board_data_initialized),
-                     (u8 *)&one, sizeof(u32));
-    }
-
-    disable_SI();
-}
-#endif
-/* ATHENV */
-
diff -druN linux-2.6.39-libre/drivers/staging/ath6kl/os/linux/export_hci_transport.c linux-3.0-rc7-libre/drivers/staging/ath6kl/os/linux/export_hci_transport.c
--- linux-2.6.39-libre/drivers/staging/ath6kl/os/linux/export_hci_transport.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/ath6kl/os/linux/export_hci_transport.c	2011-07-11 19:51:52.000000000 -0400
@@ -23,7 +23,6 @@
 //==============================================================================
 #include <a_config.h>
 #include <athdefs.h>
-#include "a_types.h"
 #include "a_osapi.h"
 #include "htc_api.h"
 #include "a_drv.h"
diff -druN linux-2.6.39-libre/drivers/staging/ath6kl/os/linux/hci_bridge.c linux-3.0-rc7-libre/drivers/staging/ath6kl/os/linux/hci_bridge.c
--- linux-2.6.39-libre/drivers/staging/ath6kl/os/linux/hci_bridge.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/ath6kl/os/linux/hci_bridge.c	2011-07-11 19:51:52.000000000 -0400
@@ -26,7 +26,6 @@
 #include <linux/etherdevice.h>
 #include <a_config.h>
 #include <athdefs.h>
-#include "a_types.h"
 #include "a_osapi.h"
 #include "htc_api.h"
 #include "wmi.h"
@@ -582,11 +581,11 @@
         } 
         
         if (pHcidevInfo->pHTCStructAlloc != NULL) {
-            A_FREE(pHcidevInfo->pHTCStructAlloc);
+            kfree(pHcidevInfo->pHTCStructAlloc);
             pHcidevInfo->pHTCStructAlloc = NULL;    
         }
         
-        A_FREE(pHcidevInfo);
+        kfree(pHcidevInfo);
 #ifndef EXPORT_HCI_BRIDGE_INTERFACE
         ar->hcidev_info = NULL;
 #endif
diff -druN linux-2.6.39-libre/drivers/staging/ath6kl/os/linux/include/ar6000_drv.h linux-3.0-rc7-libre/drivers/staging/ath6kl/os/linux/include/ar6000_drv.h
--- linux-2.6.39-libre/drivers/staging/ath6kl/os/linux/include/ar6000_drv.h	2011-05-19 02:15:01.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/ath6kl/os/linux/include/ar6000_drv.h	2011-07-21 06:57:28.000000000 -0400
@@ -33,15 +33,12 @@
 #include <linux/if_arp.h>
 #include <linux/ip.h>
 #include <linux/wireless.h>
-#ifdef ATH6K_CONFIG_CFG80211
 #include <net/cfg80211.h>
-#endif /* ATH6K_CONFIG_CFG80211 */
 #include <linux/module.h>
 #include <asm/io.h>
 
 #include <a_config.h>
 #include <athdefs.h>
-#include "a_types.h"
 #include "a_osapi.h"
 #include "htc_api.h"
 #include "wmi.h"
@@ -51,8 +48,6 @@
 #include <ieee80211_ioctl.h>
 #include <wlan_api.h>
 #include <wmi_api.h>
-#include "gpio_api.h"
-#include "gpio.h"
 #include "pkt_log.h"
 #include "aggr_recv_api.h"
 #include <host_version.h>
@@ -76,7 +71,7 @@
 #include "hw/apb_map.h"
 #include "hw/rtc_reg.h"
 #include "hw/mbox_reg.h"
-#include "hw/gpio_reg.h"
+#include "gpio_reg.h"
 
 #define  ATH_DEBUG_DBG_LOG       ATH_DEBUG_MAKE_MODULE_MASK(0)
 #define  ATH_DEBUG_WLAN_CONNECT  ATH_DEBUG_MAKE_MODULE_MASK(1)
@@ -94,8 +89,6 @@
 #endif
 
 
-#ifdef USER_KEYS
-
 #define USER_SAVEDKEYS_STAT_INIT     0
 #define USER_SAVEDKEYS_STAT_RUN      1
 
@@ -106,7 +99,6 @@
     CRYPTO_TYPE               keyType;
     bool                    keyOk;
 };
-#endif
 
 #define DBG_INFO        0x00000001
 #define DBG_ERROR       0x00000002
@@ -215,35 +207,42 @@
 #define SETUPHCI_DEFAULT           0
 #endif /* SETUPHCI_ENABLED */
 
-#ifdef SETUPHCIPAL_ENABLED
-#define SETUPHCIPAL_DEFAULT           1
-#else
-#define SETUPHCIPAL_DEFAULT           0
-#endif /* SETUPHCIPAL_ENABLED */
-
 #ifdef SETUPBTDEV_ENABLED
 #define SETUPBTDEV_DEFAULT         1
 #else
 #define SETUPBTDEV_DEFAULT         0
 #endif /* SETUPBTDEV_ENABLED */
 
-#ifdef BMIENABLE_SET
-#define BMIENABLE_DEFAULT          1
-#else
-#define BMIENABLE_DEFAULT          0
-#endif /* BMIENABLE_SET */
-
 #ifdef ENABLEUARTPRINT_SET
 #define ENABLEUARTPRINT_DEFAULT    1
 #else
 #define ENABLEUARTPRINT_DEFAULT    0
 #endif /* ENABLEARTPRINT_SET */
 
-#ifdef ATH6K_CONFIG_HIF_VIRTUAL_SCATTER
+#ifdef ATH6KL_CONFIG_HIF_VIRTUAL_SCATTER
 #define NOHIFSCATTERSUPPORT_DEFAULT    1
-#else /* ATH6K_CONFIG_HIF_VIRTUAL_SCATTER */
+#else /* ATH6KL_CONFIG_HIF_VIRTUAL_SCATTER */
 #define NOHIFSCATTERSUPPORT_DEFAULT    0
-#endif /* ATH6K_CONFIG_HIF_VIRTUAL_SCATTER */
+#endif /* ATH6KL_CONFIG_HIF_VIRTUAL_SCATTER */
+
+
+#if defined(CONFIG_ATH6KL_ENABLE_COEXISTENCE)
+
+#ifdef CONFIG_AR600x_BT_QCOM
+#define ATH6KL_BT_DEV 1
+#elif defined(CONFIG_AR600x_BT_CSR)
+#define ATH6KL_BT_DEV 2
+#else
+#define ATH6KL_BT_DEV 3
+#endif
+
+#ifdef CONFIG_AR600x_DUAL_ANTENNA
+#define ATH6KL_BT_ANTENNA 2
+#else
+#define ATH6KL_BT_ANTENNA 1
+#endif
+
+#endif /* CONFIG_ATH6KL_ENABLE_COEXISTENCE */
 
 #ifdef AR600x_BT_AR3001
 #define AR3KHCIBAUD_DEFAULT        3000000
@@ -255,11 +254,7 @@
 #define HCIUARTSTEP_DEFAULT        0
 #endif /* AR600x_BT_AR3001 */
 
-#ifdef INIT_MODE_DRV_ENABLED
 #define WLAN_INIT_MODE_DEFAULT     WLAN_INIT_MODE_DRV
-#else
-#define WLAN_INIT_MODE_DEFAULT     WLAN_INIT_MODE_USR
-#endif /* INIT_MODE_DRV_ENABLED */
 
 #define AR6K_PATCH_DOWNLOAD_ADDRESS(_param, _ver) do { \
     if ((_ver) == AR6003_REV1_VERSION) { \
@@ -283,15 +278,37 @@
     } \
 } while (0)
 
+#define AR6K_DATASET_PATCH_ADDRESS(_param, _ver) do { \
+        if ((_ver) == AR6003_REV2_VERSION) { \
+                (_param) = AR6003_REV2_DATASET_PATCH_ADDRESS; \
+        } else if ((_ver) == AR6003_REV3_VERSION) { \
+                (_param) = AR6003_REV3_DATASET_PATCH_ADDRESS; \
+        } else { \
+        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unknown Version: %d\n", _ver)); \
+        A_ASSERT(0); \
+        } \
+} while (0)
+
+#define AR6K_APP_LOAD_ADDRESS(_param, _ver) do { \
+        if ((_ver) == AR6003_REV2_VERSION) { \
+                (_param) = AR6003_REV2_APP_LOAD_ADDRESS; \
+        } else if ((_ver) == AR6003_REV3_VERSION) { \
+                (_param) = AR6003_REV3_APP_LOAD_ADDRESS; \
+        } else { \
+        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unknown Version: %d\n", _ver)); \
+        A_ASSERT(0); \
+        } \
+} while (0)
+
 #define AR6K_APP_START_OVERRIDE_ADDRESS(_param, _ver) do { \
-    if ((_ver) == AR6003_REV1_VERSION) { \
-        (_param) = AR6003_REV1_APP_START_OVERRIDE; \
-    } else if ((_ver) == AR6003_REV2_VERSION) { \
-        (_param) = AR6003_REV2_APP_START_OVERRIDE; \
-    } else { \
-       AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unknown Version: %d\n", _ver)); \
-       A_ASSERT(0); \
-    } \
+        if ((_ver) == AR6003_REV2_VERSION) { \
+                (_param) = AR6003_REV2_APP_START_OVERRIDE; \
+        } else if ((_ver) == AR6003_REV3_VERSION) { \
+                (_param) = AR6003_REV3_APP_START_OVERRIDE; \
+        } else { \
+        AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unknown Version: %d\n", _ver)); \
+        A_ASSERT(0); \
+        } \
 } while (0)
 
 /* AR6003 1.0 definitions */
@@ -304,11 +321,11 @@
 #define AR6003_REV1_ART_FIRMWARE_FILE       "/*(DEBLOBBED)*/"
 #define AR6003_REV1_PATCH_FILE              "/*(DEBLOBBED)*/"
 #define AR6003_REV1_EPPING_FIRMWARE_FILE    "/*(DEBLOBBED)*/"
-#ifdef AR600x_SD31_XXX
+#ifdef CONFIG_AR600x_SD31_XXX
 #define AR6003_REV1_BOARD_DATA_FILE         "/*(DEBLOBBED)*/"
-#elif defined(AR600x_SD32_XXX)
+#elif defined(CONFIG_AR600x_SD32_XXX)
 #define AR6003_REV1_BOARD_DATA_FILE         "/*(DEBLOBBED)*/"
-#elif defined(AR600x_WB31_XXX)
+#elif defined(CONFIG_AR600x_WB31_XXX)
 #define AR6003_REV1_BOARD_DATA_FILE         "/*(DEBLOBBED)*/"
 #else
 #define AR6003_REV1_BOARD_DATA_FILE         "/*(DEBLOBBED)*/"
@@ -324,16 +341,35 @@
 #define AR6003_REV2_ART_FIRMWARE_FILE       "/*(DEBLOBBED)*/"
 #define AR6003_REV2_PATCH_FILE              "/*(DEBLOBBED)*/"
 #define AR6003_REV2_EPPING_FIRMWARE_FILE    "/*(DEBLOBBED)*/"
-#ifdef AR600x_SD31_XXX
+#ifdef CONFIG_AR600x_SD31_XXX
 #define AR6003_REV2_BOARD_DATA_FILE         "/*(DEBLOBBED)*/"
-#elif defined(AR600x_SD32_XXX)
+#elif defined(CONFIG_AR600x_SD32_XXX)
 #define AR6003_REV2_BOARD_DATA_FILE         "/*(DEBLOBBED)*/"
-#elif defined(AR600x_WB31_XXX)
+#elif defined(CONFIG_AR600x_WB31_XXX)
 #define AR6003_REV2_BOARD_DATA_FILE         "/*(DEBLOBBED)*/"
 #else
 #define AR6003_REV2_BOARD_DATA_FILE         "/*(DEBLOBBED)*/"
 #endif /* Board Data File */
 
+/* AR6003 3.0 definitions */
+#define AR6003_REV3_VERSION                 0x30000582
+#define AR6003_REV3_OTP_FILE                "/*(DEBLOBBED)*/"
+#define AR6003_REV3_FIRMWARE_FILE           "/*(DEBLOBBED)*/"
+#define AR6003_REV3_TCMD_FIRMWARE_FILE    "/*(DEBLOBBED)*/"
+#define AR6003_REV3_ART_FIRMWARE_FILE       "/*(DEBLOBBED)*/"
+#define AR6003_REV3_PATCH_FILE            "/*(DEBLOBBED)*/"
+#define AR6003_REV3_EPPING_FIRMWARE_FILE "/*(DEBLOBBED)*/"
+#ifdef CONFIG_AR600x_SD31_XXX
+#define AR6003_REV3_BOARD_DATA_FILE       "/*(DEBLOBBED)*/"
+#elif defined(CONFIG_AR600x_SD32_XXX)
+#define AR6003_REV3_BOARD_DATA_FILE        "/*(DEBLOBBED)*/"
+#elif defined(CONFIG_AR600x_WB31_XXX)
+#define AR6003_REV3_BOARD_DATA_FILE        "/*(DEBLOBBED)*/"
+#else
+#define AR6003_REV3_BOARD_DATA_FILE      "/*(DEBLOBBED)*/"
+#endif /* Board Data File */
+
+
 /* Power states */
 enum {
     WLAN_PWR_CTRL_UP = 0,
@@ -385,7 +421,6 @@
     u8 arKey[64];
 } ;
 
-#ifdef ATH6K_CONFIG_CFG80211
 struct ar_key {
     u8 key[WLAN_MAX_KEY_LEN];
     u8 key_len;
@@ -399,8 +434,6 @@
     SME_CONNECTING,
     SME_CONNECTED
 };
-#endif /* ATH6K_CONFIG_CFG80211 */
-
 
 struct ar_node_mapping {
     u8 macAddress[6];
@@ -557,11 +590,9 @@
     u32 log_cnt;
     u32 dbglog_init_done;
     u32 arConnectCtrlFlags;
-#ifdef USER_KEYS
     s32 user_savedkeys_stat;
     u32 user_key_ctrl;
     struct USER_SAVEDKEYS   user_saved_keys;
-#endif
     USER_RSSI_THOLD rssi_map[12];
     u8 arUserBssFilter;
     u16 ap_profile_flag;    /* AP mode */
@@ -577,7 +608,6 @@
 #ifndef EXPORT_HCI_BRIDGE_INTERFACE
     void                    *hcidev_info;
 #endif
-    void                    *hcipal_info;
     WMI_AP_MODE_STAT        arAPStats;
     u8 ap_hidden_ssid;
     u8 ap_country_code[3];
@@ -597,12 +627,10 @@
 	WMI_BTCOEX_STATS_EVENT  arBtcoexStats;
     s32 (*exitCallback)(void *config);  /* generic callback at AR6K exit */
     struct hif_device_os_device_info   osDevInfo;
-#ifdef ATH6K_CONFIG_CFG80211
     struct wireless_dev *wdev;
     struct cfg80211_scan_request    *scan_request;
     struct ar_key   keys[WMI_MAX_KEY_INDEX + 1];
     u32 smeState;
-#endif /* ATH6K_CONFIG_CFG80211 */
     u16 arWlanPowerState;
     bool                  arWlanOff;
 #ifdef CONFIG_PM
@@ -622,6 +650,7 @@
 #ifdef CONFIG_AP_VIRTUAL_ADAPTER_SUPPORT
     void                    *arApDev;
 #endif
+    u8 arAutoAuthStage;
 };
 
 #ifdef CONFIG_AP_VIRTUAL_ADAPTER_SUPPORT
@@ -632,30 +661,10 @@
 };
 #endif /* CONFIG_AP_VIRTUAL_ADAPTER_SUPPORT */
 
-#ifdef ATH6K_CONFIG_CFG80211
 static inline void *ar6k_priv(struct net_device *dev)
 {
     return (wdev_priv(dev->ieee80211_ptr));
 }
-#else
-#ifdef CONFIG_AP_VIRTUAL_ADAPTER_SUPPORT
-static inline void *ar6k_priv(struct net_device *dev)
-{
-    extern struct net_device *arApNetDev;
-
-    if (arApNetDev == dev) {
-        /* return arDev saved in virtual interface context */
-        struct ar_virtual_interface *arVirDev;
-        arVirDev = netdev_priv(dev);
-        return arVirDev->arDev;   
-    } else {
-        return netdev_priv(dev);
-    }
-}
-#else
-#define ar6k_priv   netdev_priv
-#endif /* CONFIG_AP_VIRTUAL_ADAPTER_SUPPORT */
-#endif /* ATH6K_CONFIG_CFG80211 */
 
 #define SET_HCI_BUS_TYPE(pHciDev, __bus, __type) do { \
     (pHciDev)->bus = (__bus); \
@@ -701,9 +710,6 @@
     spin_unlock_bh(lock);                                               \
 } while (0)
 
-int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
-int ar6000_ioctl_dispatcher(struct net_device *dev, struct ifreq *rq, int cmd);
-void ar6000_gpio_init(void);
 void ar6000_init_profile_info(struct ar6_softc *ar);
 void ar6000_install_static_wep_keys(struct ar6_softc *ar);
 int ar6000_init(struct net_device *dev);
diff -druN linux-2.6.39-libre/drivers/staging/ath6kl/os/linux/include/ar6xapi_linux.h linux-3.0-rc7-libre/drivers/staging/ath6kl/os/linux/include/ar6xapi_linux.h
--- linux-2.6.39-libre/drivers/staging/ath6kl/os/linux/include/ar6xapi_linux.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/ath6kl/os/linux/include/ar6xapi_linux.h	2011-07-11 19:51:52.000000000 -0400
@@ -83,11 +83,6 @@
 
 void ar6000_dbglog_init_done(struct ar6_softc *ar);
 
-#ifdef SEND_EVENT_TO_APP
-void ar6000_send_event_to_app(struct ar6_softc *ar, u16 eventId, u8 *datap, int len);
-void ar6000_send_generic_event_to_app(struct ar6_softc *ar, u16 eventId, u8 *datap, int len);
-#endif
-
 #ifdef CONFIG_HOST_TCMD_SUPPORT
 void ar6000_tcmd_rx_report_event(void *devt, u8 *results, int len);
 #endif
@@ -183,9 +178,6 @@
 void ar6000_check_wow_status(struct ar6_softc *ar, struct sk_buff *skb, bool isEvent);
 #endif
 
-void ar6000_pm_init(void);
-void ar6000_pm_exit(void);
-
 #ifdef CONFIG_AP_VIRTUAL_ADAPTER_SUPPORT
 int ar6000_add_ap_interface(struct ar6_softc *ar, char *ifname);
 int ar6000_remove_ap_interface(struct ar6_softc *ar);
diff -druN linux-2.6.39-libre/drivers/staging/ath6kl/os/linux/include/athdrv_linux.h linux-3.0-rc7-libre/drivers/staging/ath6kl/os/linux/include/athdrv_linux.h
--- linux-2.6.39-libre/drivers/staging/ath6kl/os/linux/include/athdrv_linux.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/ath6kl/os/linux/include/athdrv_linux.h	2011-07-11 19:51:52.000000000 -0400
@@ -620,7 +620,6 @@
  */
 #define AR6000_XIOCTL_WMI_SET_TXOP                      57
 
-#ifdef USER_KEYS
 /*
  * arguments:
  * UINT32 cmd (AR6000_XIOCTL_USER_SETKEYS)
@@ -628,7 +627,6 @@
  * uses struct ar6000_user_setkeys_info
  */
 #define AR6000_XIOCTL_USER_SETKEYS                      58
-#endif /* USER_KEYS */
 
 #define AR6000_XIOCTL_WMI_SET_KEEPALIVE                 59
 /*
@@ -942,7 +940,7 @@
 
 #define AR6000_XIOCTL_HCI_CMD                       132
 
-#define AR6000_XIOCTL_ACL_DATA                      133
+#define AR6000_XIOCTL_ACL_DATA                      133 /* used to be used for PAL */
 
 #define AR6000_XIOCTL_WLAN_CONN_PRECEDENCE          134
 
diff -druN linux-2.6.39-libre/drivers/staging/ath6kl/os/linux/include/athtypes_linux.h linux-3.0-rc7-libre/drivers/staging/ath6kl/os/linux/include/athtypes_linux.h
--- linux-2.6.39-libre/drivers/staging/ath6kl/os/linux/include/athtypes_linux.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/ath6kl/os/linux/include/athtypes_linux.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,51 +0,0 @@
-//------------------------------------------------------------------------------
-//
-// This file contains the definitions of the basic atheros data types.
-// It is used to map the data types in atheros files to a platform specific
-// type.
-// Copyright (c) 2004-2010 Atheros Communications Inc.
-// All rights reserved.
-//
-// 
-//
-// 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.
-//
-//
-//
-// Author(s): ="Atheros"
-//------------------------------------------------------------------------------
-
-#ifndef _ATHTYPES_LINUX_H_
-#define _ATHTYPES_LINUX_H_
-
-#ifdef __KERNEL__
-#include <linux/types.h>
-#else
-#include <sys/types.h>
-#endif
-
-typedef int8_t      A_INT8;
-typedef int16_t     A_INT16;
-typedef int32_t     A_INT32;
-typedef int64_t     A_INT64;
-
-typedef u_int8_t     A_UINT8;
-typedef u_int16_t    A_UINT16;
-typedef u_int32_t    A_UINT32;
-typedef u_int64_t    A_UINT64;
-
-typedef char            A_CHAR;
-typedef unsigned long   A_ATH_TIMER;
-
-
-#endif /* _ATHTYPES_LINUX_H_ */
diff -druN linux-2.6.39-libre/drivers/staging/ath6kl/os/linux/include/config_linux.h linux-3.0-rc7-libre/drivers/staging/ath6kl/os/linux/include/config_linux.h
--- linux-2.6.39-libre/drivers/staging/ath6kl/os/linux/include/config_linux.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/ath6kl/os/linux/include/config_linux.h	2011-07-11 19:51:52.000000000 -0400
@@ -31,13 +31,6 @@
 #include <linux/version.h>
 
 /*
- * Host-side GPIO support is optional.
- * If run-time access to GPIO pins is not required, then
- * this should be changed to #undef.
- */
-#define CONFIG_HOST_GPIO_SUPPORT
-
-/*
  * Host side Test Command support
  */
 #define CONFIG_HOST_TCMD_SUPPORT
diff -druN linux-2.6.39-libre/drivers/staging/ath6kl/os/linux/include/osapi_linux.h linux-3.0-rc7-libre/drivers/staging/ath6kl/os/linux/include/osapi_linux.h
--- linux-2.6.39-libre/drivers/staging/ath6kl/os/linux/include/osapi_linux.h	2011-05-19 02:14:59.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/ath6kl/os/linux/include/osapi_linux.h	2011-07-21 06:57:26.000000000 -0400
@@ -79,33 +79,10 @@
 #define A_MEMZERO(addr, len)            memset(addr, 0, len)
 #define A_MALLOC(size)                  kmalloc((size), GFP_KERNEL)
 #define A_MALLOC_NOWAIT(size)           kmalloc((size), GFP_ATOMIC)
-#define A_FREE(addr)                    kfree(addr)
 
-#if defined(ANDROID_ENV) && defined(CONFIG_ANDROID_LOGGER)
-extern unsigned int enablelogcat;
-extern int android_logger_lv(void* module, int mask);
-enum logidx { LOG_MAIN_IDX = 0 };
-extern int logger_write(const enum logidx idx, 
-                const unsigned char prio,
-                const char __kernel * const tag,
-                const char __kernel * const fmt,
-                ...);
-#define A_ANDROID_PRINTF(mask, module, tags, args...) do {  \
-    if (enablelogcat) \
-        logger_write(LOG_MAIN_IDX, android_logger_lv(module, mask), tags, args); \
-    else \
-        printk(KERN_ALERT args); \
-} while (0)
-#ifdef DEBUG
-#define A_LOGGER_MODULE_NAME(x) #x
-#define A_LOGGER(mask, mod, args...) \
-    A_ANDROID_PRINTF(mask, &GET_ATH_MODULE_DEBUG_VAR_NAME(mod), "ar6k_" A_LOGGER_MODULE_NAME(mod), args);
-#endif 
-#define A_PRINTF(args...) A_ANDROID_PRINTF(ATH_DEBUG_INFO, NULL, "ar6k_driver", args)
-#else
 #define A_LOGGER(mask, mod, args...)    printk(KERN_ALERT args)
 #define A_PRINTF(args...)               printk(KERN_ALERT args)
-#endif /* ANDROID */
+
 #define A_PRINTF_LOG(args...)           printk(args)
 #define A_SPRINTF(buf, args...)			sprintf (buf, args)
 
@@ -211,17 +188,8 @@
 #define A_ASSERT(expr)
 #endif /* DEBUG */
 
-#ifdef ANDROID_ENV
-struct firmware;
-int android_reject_firmware(const struct firmware **firmware_p, const char *filename,
-                     struct device *device);
-void android_release_firmware(const struct firmware *firmware);
-#define A_REQUEST_FIRMWARE(_ppf, _pfile, _dev) android_reject_firmware(_ppf, _pfile, _dev)
-#define A_RELEASE_FIRMWARE(_pf) android_release_firmware(_pf)
-#else
 #define A_REQUEST_FIRMWARE(_ppf, _pfile, _dev) reject_firmware(_ppf, _pfile, _dev)
 #define A_RELEASE_FIRMWARE(_pf) release_firmware(_pf)
-#endif 
 
 /*
  * Initialization of the network buffer subsystem
@@ -364,19 +332,8 @@
 
 #define A_MEMZERO(addr, len)            memset((addr), 0, (len))
 #define A_MALLOC(size)                  malloc(size)
-#define A_FREE(addr)                    free(addr)
 
-#ifdef ANDROID
-#ifndef err
-#include <errno.h>
-#define err(_s, args...) do { \
-    fprintf(stderr, "%s: line %d ", __FILE__, __LINE__); \
-    fprintf(stderr, args); fprintf(stderr, ": %d\n", errno); \
-    exit(_s); } while (0)
-#endif
-#else
 #include <err.h>
-#endif
 
 #endif /* __KERNEL__ */
 
diff -druN linux-2.6.39-libre/drivers/staging/ath6kl/os/linux/include/wlan_config.h linux-3.0-rc7-libre/drivers/staging/ath6kl/os/linux/include/wlan_config.h
--- linux-2.6.39-libre/drivers/staging/ath6kl/os/linux/include/wlan_config.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/ath6kl/os/linux/include/wlan_config.h	2011-07-11 19:51:52.000000000 -0400
@@ -56,11 +56,7 @@
  * If the firmware successly roams within the disconnect timeout
  * it sends a new connect event
  */
-#ifdef ANDROID_ENV
-#define WLAN_CONFIG_DISCONNECT_TIMEOUT 3
-#else
 #define WLAN_CONFIG_DISCONNECT_TIMEOUT 10
-#endif /* ANDROID_ENV */ 
 
 /*
  * This configuration item disables 11n support. 
@@ -109,10 +105,4 @@
  */
 #define WLAN_CONFIG_DISABLE_TX_BURSTING     0
 
-/*
- * Platform specific function to power ON/OFF AR6000 
- * and enable/disable SDIO card detection
- */
-#define plat_setup_power(on, detect)
-
 #endif /* _HOST_WLAN_CONFIG_H_ */
diff -druN linux-2.6.39-libre/drivers/staging/ath6kl/os/linux/include/wmi_filter_linux.h linux-3.0-rc7-libre/drivers/staging/ath6kl/os/linux/include/wmi_filter_linux.h
--- linux-2.6.39-libre/drivers/staging/ath6kl/os/linux/include/wmi_filter_linux.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/ath6kl/os/linux/include/wmi_filter_linux.h	2011-07-11 19:51:52.000000000 -0400
@@ -266,7 +266,7 @@
 (0xFF),                                         /* AR6000_XIOCTL_DELE_AGGR                         130  */
 (0xFF),                                         /* AR6000_XIOCTL_FETCH_TARGET_REGS                 131  */
 (0xFF),                                         /* AR6000_XIOCTL_HCI_CMD                           132  */
-(0xFF),                                         /* AR6000_XIOCTL_ACL_DATA                          133  */
+(0xFF),                                         /* AR6000_XIOCTL_ACL_DATA(used to be used for PAL) 133  */
 (0xFF),                                         /* AR6000_XIOCTL_WLAN_CONN_PRECEDENCE              134  */
 (AP_NETWORK),                                   /* AR6000_XIOCTL_AP_SET_11BG_RATESET               135  */
 (0xFF),
diff -druN linux-2.6.39-libre/drivers/staging/ath6kl/os/linux/ioctl.c linux-3.0-rc7-libre/drivers/staging/ath6kl/os/linux/ioctl.c
--- linux-2.6.39-libre/drivers/staging/ath6kl/os/linux/ioctl.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/ath6kl/os/linux/ioctl.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,4767 +0,0 @@
-//------------------------------------------------------------------------------
-// Copyright (c) 2004-2010 Atheros Communications Inc.
-// All rights reserved.
-//
-// 
-//
-// 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.
-//
-//
-//
-// Author(s): ="Atheros"
-//------------------------------------------------------------------------------
-
-#include "ar6000_drv.h"
-#include "ieee80211_ioctl.h"
-#include "ar6kap_common.h"
-#include "targaddrs.h"
-#include "a_hci.h"
-#include "wlan_config.h"
-
-extern int enablerssicompensation;
-u32 tcmdRxFreq;
-extern unsigned int wmitimeout;
-extern A_WAITQUEUE_HEAD arEvent;
-extern int tspecCompliance;
-extern int bmienable;
-extern int loghci;
-
-static int
-ar6000_ioctl_get_roam_tbl(struct net_device *dev, struct ifreq *rq)
-{
-    struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev);
-
-    if (ar->arWmiReady == false) {
-        return -EIO;
-    }
-
-    if(wmi_get_roam_tbl_cmd(ar->arWmi) != 0) {
-        return -EIO;
-    }
-
-    return 0;
-}
-
-static int
-ar6000_ioctl_get_roam_data(struct net_device *dev, struct ifreq *rq)
-{
-    struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev);
-
-    if (ar->arWmiReady == false) {
-        return -EIO;
-    }
-
-
-    /* currently assume only roam times are required */
-    if(wmi_get_roam_data_cmd(ar->arWmi, ROAM_DATA_TIME) != 0) {
-        return -EIO;
-    }
-
-
-    return 0;
-}
-
-static int
-ar6000_ioctl_set_roam_ctrl(struct net_device *dev, char *userdata)
-{
-    struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev);
-    WMI_SET_ROAM_CTRL_CMD cmd;
-    u8 size = sizeof(cmd);
-
-    if (ar->arWmiReady == false) {
-        return -EIO;
-    }
-
-
-    if (copy_from_user(&cmd, userdata, size)) {
-        return -EFAULT;
-    }
-
-    if (cmd.roamCtrlType == WMI_SET_HOST_BIAS) {
-        if (cmd.info.bssBiasInfo.numBss > 1) {
-            size += (cmd.info.bssBiasInfo.numBss - 1) * sizeof(WMI_BSS_BIAS);
-        }
-    }
-
-    if (copy_from_user(&cmd, userdata, size)) {
-        return -EFAULT;
-    }
-
-    if(wmi_set_roam_ctrl_cmd(ar->arWmi, &cmd, size) != 0) {
-        return -EIO;
-    }
-
-    return 0;
-}
-
-static int
-ar6000_ioctl_set_powersave_timers(struct net_device *dev, char *userdata)
-{
-    struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev);
-    WMI_POWERSAVE_TIMERS_POLICY_CMD cmd;
-    u8 size = sizeof(cmd);
-
-    if (ar->arWmiReady == false) {
-        return -EIO;
-    }
-
-    if (copy_from_user(&cmd, userdata, size)) {
-        return -EFAULT;
-    }
-
-    if (copy_from_user(&cmd, userdata, size)) {
-        return -EFAULT;
-    }
-
-    if(wmi_set_powersave_timers_cmd(ar->arWmi, &cmd, size) != 0) {
-        return -EIO;
-    }
-
-    return 0;
-}
-
-static int
-ar6000_ioctl_set_qos_supp(struct net_device *dev, struct ifreq *rq)
-{
-    struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev);
-    WMI_SET_QOS_SUPP_CMD cmd;
-    int ret;
-
-    if ((dev->flags & IFF_UP) != IFF_UP) {
-        return -EIO;
-    }
-    if (ar->arWmiReady == false) {
-        return -EIO;
-    }
-
-    if (copy_from_user(&cmd, (char *)((unsigned int*)rq->ifr_data + 1),
-                                sizeof(cmd)))
-    {
-        return -EFAULT;
-    }
-
-    ret = wmi_set_qos_supp_cmd(ar->arWmi, cmd.status);
-
-    switch (ret) {
-        case 0:
-            return 0;
-        case A_EBUSY :
-            return -EBUSY;
-        case A_NO_MEMORY:
-            return -ENOMEM;
-        case A_EINVAL:
-        default:
-            return -EFAULT;
-    }
-}
-
-static int
-ar6000_ioctl_set_wmm(struct net_device *dev, struct ifreq *rq)
-{
-    struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev);
-    WMI_SET_WMM_CMD cmd;
-    int ret;
-
-    if ((dev->flags & IFF_UP) != IFF_UP) {
-        return -EIO;
-    }
-    if (ar->arWmiReady == false) {
-        return -EIO;
-    }
-
-    if (copy_from_user(&cmd, (char *)((unsigned int*)rq->ifr_data + 1),
-                                sizeof(cmd)))
-    {
-        return -EFAULT;
-    }
-
-    if (cmd.status == WMI_WMM_ENABLED) {
-        ar->arWmmEnabled = true;
-    } else {
-        ar->arWmmEnabled = false;
-    }
-
-    ret = wmi_set_wmm_cmd(ar->arWmi, cmd.status);
-
-    switch (ret) {
-        case 0:
-            return 0;
-        case A_EBUSY :
-            return -EBUSY;
-        case A_NO_MEMORY:
-            return -ENOMEM;
-        case A_EINVAL:
-        default:
-            return -EFAULT;
-    }
-}
-
-static int
-ar6000_ioctl_set_txop(struct net_device *dev, struct ifreq *rq)
-{
-    struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev);
-    WMI_SET_WMM_TXOP_CMD cmd;
-    int ret;
-
-    if ((dev->flags & IFF_UP) != IFF_UP) {
-        return -EIO;
-    }
-    if (ar->arWmiReady == false) {
-        return -EIO;
-    }
-
-    if (copy_from_user(&cmd, (char *)((unsigned int*)rq->ifr_data + 1),
-                                sizeof(cmd)))
-    {
-        return -EFAULT;
-    }
-
-    ret = wmi_set_wmm_txop(ar->arWmi, cmd.txopEnable);
-
-    switch (ret) {
-        case 0:
-            return 0;
-        case A_EBUSY :
-            return -EBUSY;
-        case A_NO_MEMORY:
-            return -ENOMEM;
-        case A_EINVAL:
-        default:
-            return -EFAULT;
-    }
-}
-
-static int
-ar6000_ioctl_get_rd(struct net_device *dev, struct ifreq *rq)
-{
-    struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev);
-    int ret = 0;
-
-    if ((dev->flags & IFF_UP) != IFF_UP || ar->arWmiReady == false) {
-        return -EIO;
-    }
-
-    if(copy_to_user((char *)((unsigned int*)rq->ifr_data + 1),
-                            &ar->arRegCode, sizeof(ar->arRegCode)))
-        ret = -EFAULT;
-
-    return ret;
-}
-
-static int
-ar6000_ioctl_set_country(struct net_device *dev, struct ifreq *rq)
-{
-    struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev);
-    WMI_AP_SET_COUNTRY_CMD cmd;
-    int ret;
-
-    if ((dev->flags & IFF_UP) != IFF_UP) {
-        return -EIO;
-    }
-    if (ar->arWmiReady == false) {
-        return -EIO;
-    }
-
-    if (copy_from_user(&cmd, (char *)((unsigned int*)rq->ifr_data + 1),
-                                sizeof(cmd)))
-    {
-        return -EFAULT;
-    }
-
-    ar->ap_profile_flag = 1; /* There is a change in profile */
-
-    ret = wmi_set_country(ar->arWmi, cmd.countryCode);
-    memcpy(ar->ap_country_code, cmd.countryCode, 3);
-
-    switch (ret) {
-        case 0:
-            return 0;
-        case A_EBUSY :
-            return -EBUSY;
-        case A_NO_MEMORY:
-            return -ENOMEM;
-        case A_EINVAL:
-        default:
-            return -EFAULT;
-    }
-}
-
-
-/* Get power mode command */
-static int
-ar6000_ioctl_get_power_mode(struct net_device *dev, struct ifreq *rq)
-{
-    struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev);
-    WMI_POWER_MODE_CMD power_mode;
-    int ret = 0;
-
-    if (ar->arWmiReady == false) {
-        return -EIO;
-    }
-
-    power_mode.powerMode = wmi_get_power_mode_cmd(ar->arWmi);
-    if (copy_to_user(rq->ifr_data, &power_mode, sizeof(WMI_POWER_MODE_CMD))) {
-        ret = -EFAULT;
-    }
-
-    return ret;
-}
-
-
-static int
-ar6000_ioctl_set_channelParams(struct net_device *dev, struct ifreq *rq)
-{
-    struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev);
-    WMI_CHANNEL_PARAMS_CMD cmd, *cmdp;
-    int ret = 0;
-
-    if (ar->arWmiReady == false) {
-        return -EIO;
-    }
-
-
-    if (copy_from_user(&cmd, rq->ifr_data, sizeof(cmd))) {
-        return -EFAULT;
-    }
-
-    if( (ar->arNextMode == AP_NETWORK) && (cmd.numChannels || cmd.scanParam) ) {
-        A_PRINTF("ERROR: Only wmode is allowed in AP mode\n");
-        return -EIO;
-    }
-
-    if (cmd.numChannels > 1) {
-        cmdp = A_MALLOC(130);
-        if (copy_from_user(cmdp, rq->ifr_data,
-                           sizeof (*cmdp) +
-                           ((cmd.numChannels - 1) * sizeof(u16))))
-        {
-            kfree(cmdp);
-            return -EFAULT;
-        }
-    } else {
-        cmdp = &cmd;
-    }
-
-    if ((ar->arPhyCapability == WMI_11G_CAPABILITY) &&
-        ((cmdp->phyMode == WMI_11A_MODE) || (cmdp->phyMode == WMI_11AG_MODE)))
-    {
-        ret = -EINVAL;
-    }
-
-    if (!ret &&
-        (wmi_set_channelParams_cmd(ar->arWmi, cmdp->scanParam, cmdp->phyMode,
-                                   cmdp->numChannels, cmdp->channelList)
-         != 0))
-    {
-        ret = -EIO;
-    }
-
-    if (cmd.numChannels > 1) {
-        kfree(cmdp);
-    }
-
-    ar->ap_wmode = cmdp->phyMode;
-    /* Set the profile change flag to allow a commit cmd */
-    ar->ap_profile_flag = 1;
-
-    return ret;
-}
-
-
-static int
-ar6000_ioctl_set_snr_threshold(struct net_device *dev, struct ifreq *rq)
-{
-
-    struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev);
-    WMI_SNR_THRESHOLD_PARAMS_CMD cmd;
-    int ret = 0;
-
-    if (ar->arWmiReady == false) {
-        return -EIO;
-    }
-
-    if (copy_from_user(&cmd, rq->ifr_data, sizeof(cmd))) {
-        return -EFAULT;
-    }
-
-    if( wmi_set_snr_threshold_params(ar->arWmi, &cmd) != 0 ) {
-        ret = -EIO;
-    }
-
-    return ret;
-}
-
-static int
-ar6000_ioctl_set_rssi_threshold(struct net_device *dev, struct ifreq *rq)
-{
-#define SWAP_THOLD(thold1, thold2) do { \
-    USER_RSSI_THOLD tmpThold;           \
-    tmpThold.tag = thold1.tag;          \
-    tmpThold.rssi = thold1.rssi;        \
-    thold1.tag = thold2.tag;            \
-    thold1.rssi = thold2.rssi;          \
-    thold2.tag = tmpThold.tag;          \
-    thold2.rssi = tmpThold.rssi;        \
-} while (0)
-
-    struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev);
-    WMI_RSSI_THRESHOLD_PARAMS_CMD cmd;
-    USER_RSSI_PARAMS rssiParams;
-    s32 i, j;
-    int ret = 0;
-
-    if (ar->arWmiReady == false) {
-        return -EIO;
-    }
-
-    if (copy_from_user((char *)&rssiParams, (char *)((unsigned int *)rq->ifr_data + 1), sizeof(USER_RSSI_PARAMS))) {
-        return -EFAULT;
-    }
-    cmd.weight = rssiParams.weight;
-    cmd.pollTime = rssiParams.pollTime;
-
-    memcpy(ar->rssi_map, &rssiParams.tholds, sizeof(ar->rssi_map));
-    /*
-     *  only 6 elements, so use bubble sorting, in ascending order
-     */
-    for (i = 5; i > 0; i--) {
-        for (j = 0; j < i; j++) { /* above tholds */
-            if (ar->rssi_map[j+1].rssi < ar->rssi_map[j].rssi) {
-                SWAP_THOLD(ar->rssi_map[j+1], ar->rssi_map[j]);
-            } else if (ar->rssi_map[j+1].rssi == ar->rssi_map[j].rssi) {
-                return -EFAULT;
-            }
-        }
-    }
-    for (i = 11; i > 6; i--) {
-        for (j = 6; j < i; j++) { /* below tholds */
-            if (ar->rssi_map[j+1].rssi < ar->rssi_map[j].rssi) {
-                SWAP_THOLD(ar->rssi_map[j+1], ar->rssi_map[j]);
-            } else if (ar->rssi_map[j+1].rssi == ar->rssi_map[j].rssi) {
-                return -EFAULT;
-            }
-        }
-    }
-
-#ifdef DEBUG
-    for (i = 0; i < 12; i++) {
-        AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("thold[%d].tag: %d, thold[%d].rssi: %d \n",
-                i, ar->rssi_map[i].tag, i, ar->rssi_map[i].rssi));
-    }
-#endif
-
-    if (enablerssicompensation) {
-        for (i = 0; i < 6; i++)
-            ar->rssi_map[i].rssi = rssi_compensation_reverse_calc(ar, ar->rssi_map[i].rssi, true);
-        for (i = 6; i < 12; i++)
-            ar->rssi_map[i].rssi = rssi_compensation_reverse_calc(ar, ar->rssi_map[i].rssi, false);
-    }
-
-    cmd.thresholdAbove1_Val = ar->rssi_map[0].rssi;
-    cmd.thresholdAbove2_Val = ar->rssi_map[1].rssi;
-    cmd.thresholdAbove3_Val = ar->rssi_map[2].rssi;
-    cmd.thresholdAbove4_Val = ar->rssi_map[3].rssi;
-    cmd.thresholdAbove5_Val = ar->rssi_map[4].rssi;
-    cmd.thresholdAbove6_Val = ar->rssi_map[5].rssi;
-    cmd.thresholdBelow1_Val = ar->rssi_map[6].rssi;
-    cmd.thresholdBelow2_Val = ar->rssi_map[7].rssi;
-    cmd.thresholdBelow3_Val = ar->rssi_map[8].rssi;
-    cmd.thresholdBelow4_Val = ar->rssi_map[9].rssi;
-    cmd.thresholdBelow5_Val = ar->rssi_map[10].rssi;
-    cmd.thresholdBelow6_Val = ar->rssi_map[11].rssi;
-
-    if( wmi_set_rssi_threshold_params(ar->arWmi, &cmd) != 0 ) {
-        ret = -EIO;
-    }
-
-    return ret;
-}
-
-static int
-ar6000_ioctl_set_lq_threshold(struct net_device *dev, struct ifreq *rq)
-{
-
-    struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev);
-    WMI_LQ_THRESHOLD_PARAMS_CMD cmd;
-    int ret = 0;
-
-    if (ar->arWmiReady == false) {
-        return -EIO;
-    }
-
-    if (copy_from_user(&cmd, (char *)((unsigned int *)rq->ifr_data + 1), sizeof(cmd))) {
-        return -EFAULT;
-    }
-
-    if( wmi_set_lq_threshold_params(ar->arWmi, &cmd) != 0 ) {
-        ret = -EIO;
-    }
-
-    return ret;
-}
-
-
-static int
-ar6000_ioctl_set_probedSsid(struct net_device *dev, struct ifreq *rq)
-{
-    struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev);
-    WMI_PROBED_SSID_CMD cmd;
-    int ret = 0;
-
-    if (ar->arWmiReady == false) {
-        return -EIO;
-    }
-
-    if (copy_from_user(&cmd, rq->ifr_data, sizeof(cmd))) {
-        return -EFAULT;
-    }
-
-    if (wmi_probedSsid_cmd(ar->arWmi, cmd.entryIndex, cmd.flag, cmd.ssidLength,
-                                  cmd.ssid) != 0)
-    {
-        ret = -EIO;
-    }
-
-    return ret;
-}
-
-static int
-ar6000_ioctl_set_badAp(struct net_device *dev, struct ifreq *rq)
-{
-    struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev);
-    WMI_ADD_BAD_AP_CMD cmd;
-    int ret = 0;
-
-    if (ar->arWmiReady == false) {
-        return -EIO;
-    }
-
-
-    if (copy_from_user(&cmd, rq->ifr_data, sizeof(cmd))) {
-        return -EFAULT;
-    }
-
-    if (cmd.badApIndex > WMI_MAX_BAD_AP_INDEX) {
-        return -EIO;
-    }
-
-    if (memcmp(cmd.bssid, null_mac, AR6000_ETH_ADDR_LEN) == 0) {
-        /*
-         * This is a delete badAP.
-         */
-        if (wmi_deleteBadAp_cmd(ar->arWmi, cmd.badApIndex) != 0) {
-            ret = -EIO;
-        }
-    } else {
-        if (wmi_addBadAp_cmd(ar->arWmi, cmd.badApIndex, cmd.bssid) != 0) {
-            ret = -EIO;
-        }
-    }
-
-    return ret;
-}
-
-static int
-ar6000_ioctl_create_qos(struct net_device *dev, struct ifreq *rq)
-{
-    struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev);
-    WMI_CREATE_PSTREAM_CMD cmd;
-    int ret;
-
-    if (ar->arWmiReady == false) {
-        return -EIO;
-    }
-
-
-    if (copy_from_user(&cmd, rq->ifr_data, sizeof(cmd))) {
-        return -EFAULT;
-    }
-
-    ret = wmi_verify_tspec_params(&cmd, tspecCompliance);
-    if (ret == 0)
-        ret = wmi_create_pstream_cmd(ar->arWmi, &cmd);
-
-    switch (ret) {
-        case 0:
-            return 0;
-        case A_EBUSY :
-            return -EBUSY;
-        case A_NO_MEMORY:
-            return -ENOMEM;
-        case A_EINVAL:
-        default:
-            return -EFAULT;
-    }
-}
-
-static int
-ar6000_ioctl_delete_qos(struct net_device *dev, struct ifreq *rq)
-{
-    struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev);
-    WMI_DELETE_PSTREAM_CMD cmd;
-    int ret = 0;
-
-    if (ar->arWmiReady == false) {
-        return -EIO;
-    }
-
-    if (copy_from_user(&cmd, rq->ifr_data, sizeof(cmd))) {
-        return -EFAULT;
-    }
-
-    ret = wmi_delete_pstream_cmd(ar->arWmi, cmd.trafficClass, cmd.tsid);
-
-    switch (ret) {
-        case 0:
-            return 0;
-        case A_EBUSY :
-            return -EBUSY;
-        case A_NO_MEMORY:
-            return -ENOMEM;
-        case A_EINVAL:
-        default:
-            return -EFAULT;
-    }
-}
-
-static int
-ar6000_ioctl_get_qos_queue(struct net_device *dev, struct ifreq *rq)
-{
-    struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev);
-    struct ar6000_queuereq qreq;
-    int ret = 0;
-
-    if (ar->arWmiReady == false) {
-        return -EIO;
-    }
-
-    if( copy_from_user(&qreq, rq->ifr_data,
-                  sizeof(struct ar6000_queuereq)))
-        return -EFAULT;
-
-    qreq.activeTsids = wmi_get_mapped_qos_queue(ar->arWmi, qreq.trafficClass);
-
-    if (copy_to_user(rq->ifr_data, &qreq,
-                 sizeof(struct ar6000_queuereq)))
-    {
-        ret = -EFAULT;
-    }
-
-    return ret;
-}
-
-#ifdef CONFIG_HOST_TCMD_SUPPORT
-static int
-ar6000_ioctl_tcmd_get_rx_report(struct net_device *dev,
-                                 struct ifreq *rq, u8 *data, u32 len)
-{
-    struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev);
-    u32 buf[4+TCMD_MAX_RATES];
-    int ret = 0;
-
-    if (ar->bIsDestroyProgress) {
-        return -EBUSY;
-    }
-
-    if (ar->arWmiReady == false) {
-        return -EIO;
-    }
-
-    if (down_interruptible(&ar->arSem)) {
-        return -ERESTARTSYS;
-    }
-
-    if (ar->bIsDestroyProgress) {
-        up(&ar->arSem);
-        return -EBUSY;
-    }
-
-    ar->tcmdRxReport = 0;
-    if (wmi_test_cmd(ar->arWmi, data, len) != 0) {
-        up(&ar->arSem);
-        return -EIO;
-    }
-
-    wait_event_interruptible_timeout(arEvent, ar->tcmdRxReport != 0, wmitimeout * HZ);
-
-    if (signal_pending(current)) {
-        ret = -EINTR;
-    }
-
-    buf[0] = ar->tcmdRxTotalPkt;
-    buf[1] = ar->tcmdRxRssi;
-    buf[2] = ar->tcmdRxcrcErrPkt;
-    buf[3] = ar->tcmdRxsecErrPkt;
-    memcpy(((u8 *)buf)+(4*sizeof(u32)), ar->tcmdRateCnt, sizeof(ar->tcmdRateCnt));
-    memcpy(((u8 *)buf)+(4*sizeof(u32))+(TCMD_MAX_RATES *sizeof(u16)), ar->tcmdRateCntShortGuard, sizeof(ar->tcmdRateCntShortGuard));
-
-    if (!ret && copy_to_user(rq->ifr_data, buf, sizeof(buf))) {
-        ret = -EFAULT;
-    }
-
-    up(&ar->arSem);
-
-    return ret;
-}
-
-void
-ar6000_tcmd_rx_report_event(void *devt, u8 *results, int len)
-{
-    struct ar6_softc *ar = (struct ar6_softc *)devt;
-    TCMD_CONT_RX * rx_rep = (TCMD_CONT_RX *)results;
-
-    if (enablerssicompensation) {
-        rx_rep->u.report.rssiInDBm = rssi_compensation_calc_tcmd(tcmdRxFreq, rx_rep->u.report.rssiInDBm,rx_rep->u.report.totalPkt);
-    }
-
-
-    ar->tcmdRxTotalPkt = rx_rep->u.report.totalPkt;
-    ar->tcmdRxRssi = rx_rep->u.report.rssiInDBm;
-    ar->tcmdRxcrcErrPkt = rx_rep->u.report.crcErrPkt;
-    ar->tcmdRxsecErrPkt = rx_rep->u.report.secErrPkt;
-    ar->tcmdRxReport = 1;
-    A_MEMZERO(ar->tcmdRateCnt,  sizeof(ar->tcmdRateCnt));
-    A_MEMZERO(ar->tcmdRateCntShortGuard,  sizeof(ar->tcmdRateCntShortGuard));
-    memcpy(ar->tcmdRateCnt, rx_rep->u.report.rateCnt, sizeof(ar->tcmdRateCnt));
-    memcpy(ar->tcmdRateCntShortGuard, rx_rep->u.report.rateCntShortGuard, sizeof(ar->tcmdRateCntShortGuard));
-
-    wake_up(&arEvent);
-}
-#endif /* CONFIG_HOST_TCMD_SUPPORT*/
-
-static int
-ar6000_ioctl_set_error_report_bitmask(struct net_device *dev, struct ifreq *rq)
-{
-    struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev);
-    WMI_TARGET_ERROR_REPORT_BITMASK cmd;
-    int ret = 0;
-
-    if (ar->arWmiReady == false) {
-        return -EIO;
-    }
-
-    if (copy_from_user(&cmd, rq->ifr_data, sizeof(cmd))) {
-        return -EFAULT;
-    }
-
-    ret = wmi_set_error_report_bitmask(ar->arWmi, cmd.bitmask);
-
-    return  (ret==0 ? ret : -EINVAL);
-}
-
-static int
-ar6000_clear_target_stats(struct net_device *dev)
-{
-    struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev);
-    TARGET_STATS *pStats = &ar->arTargetStats;
-    int ret = 0;
-
-    if (ar->arWmiReady == false) {
-       return -EIO;
-    }
-    AR6000_SPIN_LOCK(&ar->arLock, 0);
-    A_MEMZERO(pStats, sizeof(TARGET_STATS));
-    AR6000_SPIN_UNLOCK(&ar->arLock, 0);
-    return ret;
-}
-
-static int
-ar6000_ioctl_get_target_stats(struct net_device *dev, struct ifreq *rq)
-{
-    struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev);
-    TARGET_STATS_CMD cmd;
-    TARGET_STATS *pStats = &ar->arTargetStats;
-    int ret = 0;
-
-    if (ar->bIsDestroyProgress) {
-        return -EBUSY;
-    }
-    if (ar->arWmiReady == false) {
-        return -EIO;
-    }
-    if (copy_from_user(&cmd, rq->ifr_data, sizeof(cmd))) {
-        return -EFAULT;
-    }
-    if (down_interruptible(&ar->arSem)) {
-        return -ERESTARTSYS;
-    }
-    if (ar->bIsDestroyProgress) {
-        up(&ar->arSem);
-        return -EBUSY;
-    }
-
-    ar->statsUpdatePending = true;
-
-    if(wmi_get_stats_cmd(ar->arWmi) != 0) {
-        up(&ar->arSem);
-        return -EIO;
-    }
-
-    wait_event_interruptible_timeout(arEvent, ar->statsUpdatePending == false, wmitimeout * HZ);
-
-    if (signal_pending(current)) {
-        ret = -EINTR;
-    }
-
-    if (!ret && copy_to_user(rq->ifr_data, pStats, sizeof(*pStats))) {
-        ret = -EFAULT;
-    }
-
-    if (cmd.clearStats == 1) {
-        ret = ar6000_clear_target_stats(dev);
-    }
-
-    up(&ar->arSem);
-
-    return ret;
-}
-
-static int
-ar6000_ioctl_get_ap_stats(struct net_device *dev, struct ifreq *rq)
-{
-    struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev);
-    u32 action; /* Allocating only the desired space on the frame. Declaring is as a WMI_AP_MODE_STAT variable results in exceeding the compiler imposed limit on the maximum frame size */
-    WMI_AP_MODE_STAT *pStats = &ar->arAPStats;
-    int ret = 0;
-
-    if (ar->arWmiReady == false) {
-        return -EIO;
-    }
-    if (copy_from_user(&action, (char *)((unsigned int*)rq->ifr_data + 1),
-                                sizeof(u32)))
-    {
-        return -EFAULT;
-    }
-    if (action == AP_CLEAR_STATS) {
-        u8 i;
-        AR6000_SPIN_LOCK(&ar->arLock, 0);
-        for(i = 0; i < AP_MAX_NUM_STA; i++) {
-            pStats->sta[i].tx_bytes = 0;
-            pStats->sta[i].tx_pkts = 0;
-            pStats->sta[i].tx_error = 0;
-            pStats->sta[i].tx_discard = 0;
-            pStats->sta[i].rx_bytes = 0;
-            pStats->sta[i].rx_pkts = 0;
-            pStats->sta[i].rx_error = 0;
-            pStats->sta[i].rx_discard = 0;
-        }
-        AR6000_SPIN_UNLOCK(&ar->arLock, 0);
-        return ret;
-    }
-
-    if (down_interruptible(&ar->arSem)) {
-        return -ERESTARTSYS;
-    }
-
-    ar->statsUpdatePending = true;
-
-    if(wmi_get_stats_cmd(ar->arWmi) != 0) {
-        up(&ar->arSem);
-        return -EIO;
-    }
-
-    wait_event_interruptible_timeout(arEvent, ar->statsUpdatePending == false, wmitimeout * HZ);
-
-    if (signal_pending(current)) {
-        ret = -EINTR;
-    }
-
-    if (!ret && copy_to_user(rq->ifr_data, pStats, sizeof(*pStats))) {
-        ret = -EFAULT;
-    }
-
-    up(&ar->arSem);
-
-    return ret;
-}
-
-static int
-ar6000_ioctl_set_access_params(struct net_device *dev, struct ifreq *rq)
-{
-    struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev);
-    WMI_SET_ACCESS_PARAMS_CMD cmd;
-    int ret = 0;
-
-    if (ar->arWmiReady == false) {
-        return -EIO;
-    }
-
-    if (copy_from_user(&cmd, rq->ifr_data, sizeof(cmd))) {
-        return -EFAULT;
-    }
-
-    if (wmi_set_access_params_cmd(ar->arWmi, cmd.ac, cmd.txop, cmd.eCWmin, cmd.eCWmax,
-                                  cmd.aifsn) == 0)
-    {
-        ret = 0;
-    } else {
-        ret = -EINVAL;
-    }
-
-    return (ret);
-}
-
-static int
-ar6000_ioctl_set_disconnect_timeout(struct net_device *dev, struct ifreq *rq)
-{
-    struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev);
-    WMI_DISC_TIMEOUT_CMD cmd;
-    int ret = 0;
-
-    if (ar->arWmiReady == false) {
-        return -EIO;
-    }
-
-    if (copy_from_user(&cmd, rq->ifr_data, sizeof(cmd))) {
-        return -EFAULT;
-    }
-
-    if (wmi_disctimeout_cmd(ar->arWmi, cmd.disconnectTimeout) == 0)
-    {
-        ret = 0;
-    } else {
-        ret = -EINVAL;
-    }
-
-    return (ret);
-}
-
-static int
-ar6000_xioctl_set_voice_pkt_size(struct net_device *dev, char *userdata)
-{
-    struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev);
-    WMI_SET_VOICE_PKT_SIZE_CMD cmd;
-    int ret = 0;
-
-    if (ar->arWmiReady == false) {
-        return -EIO;
-    }
-
-    if (copy_from_user(&cmd, userdata, sizeof(cmd))) {
-        return -EFAULT;
-    }
-
-    if (wmi_set_voice_pkt_size_cmd(ar->arWmi, cmd.voicePktSize) == 0)
-    {
-        ret = 0;
-    } else {
-        ret = -EINVAL;
-    }
-
-
-    return (ret);
-}
-
-static int
-ar6000_xioctl_set_max_sp_len(struct net_device *dev, char *userdata)
-{
-    struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev);
-    WMI_SET_MAX_SP_LEN_CMD cmd;
-    int ret = 0;
-
-    if (ar->arWmiReady == false) {
-        return -EIO;
-    }
-
-    if (copy_from_user(&cmd, userdata, sizeof(cmd))) {
-        return -EFAULT;
-    }
-
-    if (wmi_set_max_sp_len_cmd(ar->arWmi, cmd.maxSPLen) == 0)
-    {
-        ret = 0;
-    } else {
-        ret = -EINVAL;
-    }
-
-    return (ret);
-}
-
-
-static int
-ar6000_xioctl_set_bt_status_cmd(struct net_device *dev, char *userdata)
-{
-    struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev);
-    WMI_SET_BT_STATUS_CMD cmd;
-    int ret = 0;
-
-    if (ar->arWmiReady == false) {
-        return -EIO;
-    }
-
-    if (copy_from_user(&cmd, userdata, sizeof(cmd))) {
-        return -EFAULT;
-    }
-
-    if (wmi_set_bt_status_cmd(ar->arWmi, cmd.streamType, cmd.status) == 0)
-    {
-        ret = 0;
-    } else {
-        ret = -EINVAL;
-    }
-
-    return (ret);
-}
-
-static int
-ar6000_xioctl_set_bt_params_cmd(struct net_device *dev, char *userdata)
-{
-    struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev);
-    WMI_SET_BT_PARAMS_CMD cmd;
-    int ret = 0;
-
-    if (ar->arWmiReady == false) {
-        return -EIO;
-    }
-
-    if (copy_from_user(&cmd, userdata, sizeof(cmd))) {
-        return -EFAULT;
-    }
-
-    if (wmi_set_bt_params_cmd(ar->arWmi, &cmd) == 0)
-    {
-        ret = 0;
-    } else {
-        ret = -EINVAL;
-    }
-
-    return (ret);
-}
-
-static int
-ar6000_xioctl_set_btcoex_fe_ant_cmd(struct net_device * dev, char *userdata)
-{
-	struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev);
-	WMI_SET_BTCOEX_FE_ANT_CMD cmd;
-    int ret = 0;
-
-	if (ar->arWmiReady == false) {
-		return -EIO;
-	}
-	if (copy_from_user(&cmd, userdata, sizeof(cmd))) {
-		return -EFAULT;
-	}
-
-    if (wmi_set_btcoex_fe_ant_cmd(ar->arWmi, &cmd) == 0)
-    {
-        ret = 0;
-    } else {
-        ret = -EINVAL;
-    }
-
-	return(ret);
-}
-
-static int
-ar6000_xioctl_set_btcoex_colocated_bt_dev_cmd(struct net_device * dev, char *userdata)
-{
-	struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev);
-	WMI_SET_BTCOEX_COLOCATED_BT_DEV_CMD cmd;
-    int ret = 0;
-
-	if (ar->arWmiReady == false) {
-		return -EIO;
-	}
-
-	if (copy_from_user(&cmd, userdata, sizeof(cmd))) {
-		return -EFAULT;
-	}
-
-    if (wmi_set_btcoex_colocated_bt_dev_cmd(ar->arWmi, &cmd) == 0)
-    {
-        ret = 0;
-    } else {
-        ret = -EINVAL;
-    }
-
-	return(ret);
-}
-
-static int
-ar6000_xioctl_set_btcoex_btinquiry_page_config_cmd(struct net_device * dev,  char *userdata)
-{
-	struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev);
-	WMI_SET_BTCOEX_BTINQUIRY_PAGE_CONFIG_CMD cmd;
-    int ret = 0;
-
-	if (ar->arWmiReady == false) {
-		return -EIO;
-	}
-
-	if (copy_from_user(&cmd, userdata, sizeof(cmd))) {
-		return -EFAULT;
-	}
-
-    if (wmi_set_btcoex_btinquiry_page_config_cmd(ar->arWmi, &cmd) == 0)
-    {
-        ret = 0;
-    } else {
-        ret = -EINVAL;
-    }
-
-	return(ret);
-}
-
-static int
-ar6000_xioctl_set_btcoex_sco_config_cmd(struct net_device * dev, char *userdata)
-{
-	struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev);
-	WMI_SET_BTCOEX_SCO_CONFIG_CMD cmd;
-    int ret = 0;
-
-	if (ar->arWmiReady == false) {
-		return -EIO;
-	}
-
-	if (copy_from_user(&cmd, userdata, sizeof(cmd))) {
-		return -EFAULT;
-	}
-
-    if (wmi_set_btcoex_sco_config_cmd(ar->arWmi, &cmd) == 0)
-    {
-        ret = 0;
-    } else {
-        ret = -EINVAL;
-    }
-
-	return(ret);
-}
-
-static int
-ar6000_xioctl_set_btcoex_a2dp_config_cmd(struct net_device * dev,
-														char *userdata)
-{
-	struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev);
-	WMI_SET_BTCOEX_A2DP_CONFIG_CMD cmd;
-    int ret = 0;
-
-	if (ar->arWmiReady == false) {
-		return -EIO;
-	}
-
-	if (copy_from_user(&cmd, userdata, sizeof(cmd))) {
-		return -EFAULT;
-	}
-
-    if (wmi_set_btcoex_a2dp_config_cmd(ar->arWmi, &cmd) == 0)
-    {
-        ret = 0;
-    } else {
-        ret = -EINVAL;
-    }
-
-	return(ret);
-}
-
-static int
-ar6000_xioctl_set_btcoex_aclcoex_config_cmd(struct net_device * dev, char *userdata)
-{
-	struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev);
-	WMI_SET_BTCOEX_ACLCOEX_CONFIG_CMD cmd;
-    int ret = 0;
-
-	if (ar->arWmiReady == false) {
-		return -EIO;
-	}
-
-	if (copy_from_user(&cmd, userdata, sizeof(cmd))) {
-		return -EFAULT;
-	}
-
-    if (wmi_set_btcoex_aclcoex_config_cmd(ar->arWmi, &cmd) == 0)
-    {
-        ret = 0;
-    } else {
-        ret = -EINVAL;
-    }
-
-	return(ret);
-}
-
-static int
-ar60000_xioctl_set_btcoex_debug_cmd(struct net_device * dev, char *userdata)
-{
-	struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev);
-	WMI_SET_BTCOEX_DEBUG_CMD cmd;
-    int ret = 0;
-
-	if (ar->arWmiReady == false) {
-		return -EIO;
-	}
-
-	if (copy_from_user(&cmd, userdata, sizeof(cmd))) {
-		return -EFAULT;
-	}
-
-    if (wmi_set_btcoex_debug_cmd(ar->arWmi, &cmd) == 0)
-    {
-        ret = 0;
-    } else {
-        ret = -EINVAL;
-    }
-
-	return(ret);
-}
-
-static int
-ar6000_xioctl_set_btcoex_bt_operating_status_cmd(struct net_device * dev, char *userdata)
-{
-     struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev);
-     WMI_SET_BTCOEX_BT_OPERATING_STATUS_CMD cmd;
-     int ret = 0;
-
-    if (ar->arWmiReady == false) {
-	return -EIO;
-    }
-
-    if (copy_from_user(&cmd, userdata, sizeof(cmd))) {
-	return -EFAULT;
-    }
-
-    if (wmi_set_btcoex_bt_operating_status_cmd(ar->arWmi, &cmd) == 0)
-    {
-        ret = 0;
-    } else {
-        ret = -EINVAL;
-    }
-    return(ret);
-}
-
-static int
-ar6000_xioctl_get_btcoex_config_cmd(struct net_device * dev, char *userdata,
-											struct ifreq *rq)
-{
-
-	struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev);
-    AR6000_BTCOEX_CONFIG btcoexConfig;
-    WMI_BTCOEX_CONFIG_EVENT *pbtcoexConfigEv = &ar->arBtcoexConfig;
-
-    int ret = 0;
-
-    if (ar->bIsDestroyProgress) {
-            return -EBUSY;
-    }
-    if (ar->arWmiReady == false) {
-            return -EIO;
-    }
-	if (copy_from_user(&btcoexConfig.configCmd, userdata, sizeof(AR6000_BTCOEX_CONFIG))) {
-		return -EFAULT;
-	}
-    if (down_interruptible(&ar->arSem)) {
-        return -ERESTARTSYS;
-    }
-
-    if (wmi_get_btcoex_config_cmd(ar->arWmi, (WMI_GET_BTCOEX_CONFIG_CMD *)&btcoexConfig.configCmd) != 0)
-    {
-    	up(&ar->arSem);
-    	return -EIO;
-    }
-
-    ar->statsUpdatePending = true;
-
-    wait_event_interruptible_timeout(arEvent, ar->statsUpdatePending == false, wmitimeout * HZ);
-
-    if (signal_pending(current)) {
-       ret = -EINTR;
-    }
-
-    if (!ret && copy_to_user(btcoexConfig.configEvent, pbtcoexConfigEv, sizeof(WMI_BTCOEX_CONFIG_EVENT))) {
-            ret = -EFAULT;
-    }
-    up(&ar->arSem);
-    return ret;
-}
-
-static int
-ar6000_xioctl_get_btcoex_stats_cmd(struct net_device * dev, char *userdata, struct ifreq *rq)
-{
-	struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev);
-    AR6000_BTCOEX_STATS btcoexStats;
-    WMI_BTCOEX_STATS_EVENT *pbtcoexStats = &ar->arBtcoexStats;
-    int ret = 0;
-
-    if (ar->bIsDestroyProgress) {
-            return -EBUSY;
-    }
-    if (ar->arWmiReady == false) {
-            return -EIO;
-    }
-
-    if (down_interruptible(&ar->arSem)) {
-        return -ERESTARTSYS;
-    }
-
-	if (copy_from_user(&btcoexStats.statsEvent, userdata, sizeof(AR6000_BTCOEX_CONFIG))) {
-		return -EFAULT;
-	}
-
-    if (wmi_get_btcoex_stats_cmd(ar->arWmi) != 0)
-    {
-    	up(&ar->arSem);
-    	return -EIO;
-    }
-
-    ar->statsUpdatePending = true;
-
-    wait_event_interruptible_timeout(arEvent, ar->statsUpdatePending == false, wmitimeout * HZ);
-
-    if (signal_pending(current)) {
-       ret = -EINTR;
-    }
-
-    if (!ret && copy_to_user(btcoexStats.statsEvent, pbtcoexStats, sizeof(WMI_BTCOEX_STATS_EVENT))) {
-            ret = -EFAULT;
-    }
-
-
-    up(&ar->arSem);
-
-	return(ret);
-}
-
-static int
-ar6000_xioctl_set_excess_tx_retry_thres_cmd(struct net_device * dev, char * userdata)
-{
-    struct ar6_softc     *ar     = (struct ar6_softc *)ar6k_priv(dev);
-    WMI_SET_EXCESS_TX_RETRY_THRES_CMD cmd;
-    int ret = 0;
-
-    if (ar->arWmiReady == false) {
-        return -EIO;
-    }
-
-    if (copy_from_user(&cmd, userdata, sizeof(cmd))) {
-        return -EFAULT;
-    }
-
-    if (wmi_set_excess_tx_retry_thres_cmd(ar->arWmi, &cmd) != 0)
-    {
-        ret = -EINVAL;
-    }
-    return(ret);
-}
-
-#ifdef CONFIG_HOST_GPIO_SUPPORT
-struct ar6000_gpio_intr_wait_cmd_s  gpio_intr_results;
-/* gpio_reg_results and gpio_data_available are protected by arSem */
-static struct ar6000_gpio_register_cmd_s gpio_reg_results;
-static bool gpio_data_available; /* Requested GPIO data available */
-static bool gpio_intr_available; /* GPIO interrupt info available */
-static bool gpio_ack_received;   /* GPIO ack was received */
-
-/* Host-side initialization for General Purpose I/O support */
-void ar6000_gpio_init(void)
-{
-    gpio_intr_available = false;
-    gpio_data_available = false;
-    gpio_ack_received   = false;
-}
-
-/*
- * Called when a GPIO interrupt is received from the Target.
- * intr_values shows which GPIO pins have interrupted.
- * input_values shows a recent value of GPIO pins.
- */
-void
-ar6000_gpio_intr_rx(u32 intr_mask, u32 input_values)
-{
-    gpio_intr_results.intr_mask = intr_mask;
-    gpio_intr_results.input_values = input_values;
-    *((volatile bool *)&gpio_intr_available) = true;
-    wake_up(&arEvent);
-}
-
-/*
- * This is called when a response is received from the Target
- * for a previous or ar6000_gpio_input_get or ar6000_gpio_register_get
- * call.
- */
-void
-ar6000_gpio_data_rx(u32 reg_id, u32 value)
-{
-    gpio_reg_results.gpioreg_id = reg_id;
-    gpio_reg_results.value = value;
-    *((volatile bool *)&gpio_data_available) = true;
-    wake_up(&arEvent);
-}
-
-/*
- * This is called when an acknowledgement is received from the Target
- * for a previous or ar6000_gpio_output_set or ar6000_gpio_register_set
- * call.
- */
-void
-ar6000_gpio_ack_rx(void)
-{
-    gpio_ack_received = true;
-    wake_up(&arEvent);
-}
-
-int
-ar6000_gpio_output_set(struct net_device *dev,
-                       u32 set_mask,
-                       u32 clear_mask,
-                       u32 enable_mask,
-                       u32 disable_mask)
-{
-    struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev);
-
-    gpio_ack_received = false;
-    return wmi_gpio_output_set(ar->arWmi,
-                set_mask, clear_mask, enable_mask, disable_mask);
-}
-
-static int
-ar6000_gpio_input_get(struct net_device *dev)
-{
-    struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev);
-
-    *((volatile bool *)&gpio_data_available) = false;
-    return wmi_gpio_input_get(ar->arWmi);
-}
-
-static int
-ar6000_gpio_register_set(struct net_device *dev,
-                         u32 gpioreg_id,
-                         u32 value)
-{
-    struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev);
-
-    gpio_ack_received = false;
-    return wmi_gpio_register_set(ar->arWmi, gpioreg_id, value);
-}
-
-static int
-ar6000_gpio_register_get(struct net_device *dev,
-                         u32 gpioreg_id)
-{
-    struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev);
-
-    *((volatile bool *)&gpio_data_available) = false;
-    return wmi_gpio_register_get(ar->arWmi, gpioreg_id);
-}
-
-static int
-ar6000_gpio_intr_ack(struct net_device *dev,
-                     u32 ack_mask)
-{
-    struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev);
-
-    gpio_intr_available = false;
-    return wmi_gpio_intr_ack(ar->arWmi, ack_mask);
-}
-#endif /* CONFIG_HOST_GPIO_SUPPORT */
-
-#if defined(CONFIG_TARGET_PROFILE_SUPPORT)
-static struct prof_count_s prof_count_results;
-static bool prof_count_available; /* Requested GPIO data available */
-
-static int
-prof_count_get(struct net_device *dev)
-{
-    struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev);
-
-    *((volatile bool *)&prof_count_available) = false;
-    return wmi_prof_count_get_cmd(ar->arWmi);
-}
-
-/*
- * This is called when a response is received from the Target
- * for a previous prof_count_get call.
- */
-void
-prof_count_rx(u32 addr, u32 count)
-{
-    prof_count_results.addr = addr;
-    prof_count_results.count = count;
-    *((volatile bool *)&prof_count_available) = true;
-    wake_up(&arEvent);
-}
-#endif /* CONFIG_TARGET_PROFILE_SUPPORT */
-
-
-static int
-ar6000_create_acl_data_osbuf(struct net_device *dev, u8 *userdata, void **p_osbuf)
-{
-    void *osbuf = NULL;
-    u8 tmp_space[8];
-    HCI_ACL_DATA_PKT *acl;
-    u8 hdr_size, *datap=NULL;
-    int ret = 0;
-
-    /* ACL is in data path. There is a need to create pool
-     * mechanism for allocating and freeing NETBUFs - ToDo later.
-     */
-
-    *p_osbuf = NULL;
-    acl = (HCI_ACL_DATA_PKT *)tmp_space;
-    hdr_size = sizeof(acl->hdl_and_flags) + sizeof(acl->data_len);
-
-    do {
-        if (a_copy_from_user(acl, userdata, hdr_size)) {
-            ret = A_EFAULT;
-            break;
-        }
-
-        osbuf = A_NETBUF_ALLOC(hdr_size + acl->data_len);
-        if (osbuf == NULL) {
-           ret = A_NO_MEMORY;
-           break;
-        }
-        A_NETBUF_PUT(osbuf, hdr_size + acl->data_len);
-        datap = (u8 *)A_NETBUF_DATA(osbuf);
-
-        /* Real copy to osbuf */
-        acl = (HCI_ACL_DATA_PKT *)(datap);
-        memcpy(acl, tmp_space, hdr_size);
-        if (a_copy_from_user(acl->data, userdata + hdr_size, acl->data_len)) {
-            ret = A_EFAULT;
-            break;
-        }
-    } while(false);
-
-    if (ret == 0) {
-        *p_osbuf = osbuf;
-    } else {
-        A_NETBUF_FREE(osbuf);
-    }
-    return ret;
-}
-
-
-
-int
-ar6000_ioctl_ap_setparam(struct ar6_softc *ar, int param, int value)
-{
-    int ret=0;
-
-    switch(param) {
-        case IEEE80211_PARAM_WPA:
-            switch (value) {
-                case WPA_MODE_WPA1:
-                    ar->arAuthMode = WPA_AUTH;
-                    break;
-                case WPA_MODE_WPA2:
-                    ar->arAuthMode = WPA2_AUTH;
-                    break;
-                case WPA_MODE_AUTO:
-                    ar->arAuthMode = WPA_AUTH | WPA2_AUTH;
-                    break;
-                case WPA_MODE_NONE:
-                    ar->arAuthMode = NONE_AUTH;
-                    break;
-            }
-            break;
-        case IEEE80211_PARAM_AUTHMODE:
-            if(value == IEEE80211_AUTH_WPA_PSK) {
-                if (WPA_AUTH == ar->arAuthMode) {
-                    ar->arAuthMode = WPA_PSK_AUTH;
-                } else if (WPA2_AUTH == ar->arAuthMode) {
-                    ar->arAuthMode = WPA2_PSK_AUTH;
-                } else if ((WPA_AUTH | WPA2_AUTH) == ar->arAuthMode) {
-                    ar->arAuthMode = WPA_PSK_AUTH | WPA2_PSK_AUTH;
-                } else {
-                    AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Error -  Setting PSK "\
-                        "mode when WPA param was set to %d\n",
-                        ar->arAuthMode));
-                    ret = -EIO;
-                }
-            }
-            break;
-        case IEEE80211_PARAM_UCASTCIPHER:
-            ar->arPairwiseCrypto = 0;
-            if(value & (1<<IEEE80211_CIPHER_AES_CCM)) {
-                ar->arPairwiseCrypto |= AES_CRYPT;
-            }
-            if(value & (1<<IEEE80211_CIPHER_TKIP)) {
-                ar->arPairwiseCrypto |= TKIP_CRYPT;
-            }
-            if(!ar->arPairwiseCrypto) {
-                AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
-                           ("Error - Invalid cipher in WPA \n"));
-                ret = -EIO;
-            }
-            break;
-        case IEEE80211_PARAM_PRIVACY:
-            if(value == 0) {
-                ar->arDot11AuthMode      = OPEN_AUTH;
-                ar->arAuthMode           = NONE_AUTH;
-                ar->arPairwiseCrypto     = NONE_CRYPT;
-                ar->arPairwiseCryptoLen  = 0;
-                ar->arGroupCrypto        = NONE_CRYPT;
-                ar->arGroupCryptoLen     = 0;
-            }
-            break;
-#ifdef WAPI_ENABLE
-        case IEEE80211_PARAM_WAPI:
-            A_PRINTF("WAPI Policy: %d\n", value);
-            ar->arDot11AuthMode      = OPEN_AUTH;
-            ar->arAuthMode           = NONE_AUTH;
-            if(value & 0x1) {
-                ar->arPairwiseCrypto     = WAPI_CRYPT;
-                ar->arGroupCrypto        = WAPI_CRYPT;
-            } else {
-                ar->arPairwiseCrypto     = NONE_CRYPT;
-                ar->arGroupCrypto        = NONE_CRYPT;
-            }
-            break;
-#endif
-    }
-    return ret;
-}
-
-int
-ar6000_ioctl_setparam(struct ar6_softc *ar, int param, int value)
-{
-    bool profChanged = false;
-    int ret=0;
-
-    if(ar->arNextMode == AP_NETWORK) {
-        ar->ap_profile_flag = 1; /* There is a change in profile */
-        switch (param) {
-            case IEEE80211_PARAM_WPA:
-            case IEEE80211_PARAM_AUTHMODE:
-            case IEEE80211_PARAM_UCASTCIPHER:
-            case IEEE80211_PARAM_PRIVACY:
-            case IEEE80211_PARAM_WAPI:
-                ret = ar6000_ioctl_ap_setparam(ar, param, value);
-                return ret;
-        }
-    }
-
-    switch (param) {
-        case IEEE80211_PARAM_WPA:
-            switch (value) {
-                case WPA_MODE_WPA1:
-                    ar->arAuthMode = WPA_AUTH;
-                    profChanged    = true;
-                    break;
-                case WPA_MODE_WPA2:
-                    ar->arAuthMode = WPA2_AUTH;
-                    profChanged    = true;
-                    break;
-                case WPA_MODE_NONE:
-                    ar->arAuthMode = NONE_AUTH;
-                    profChanged    = true;
-                    break;
-            }
-            break;
-        case IEEE80211_PARAM_AUTHMODE:
-            switch(value) {
-                case IEEE80211_AUTH_WPA_PSK:
-                    if (WPA_AUTH == ar->arAuthMode) {
-                        ar->arAuthMode = WPA_PSK_AUTH;
-                        profChanged    = true;
-                    } else if (WPA2_AUTH == ar->arAuthMode) {
-                        ar->arAuthMode = WPA2_PSK_AUTH;
-                        profChanged    = true;
-                    } else {
-                        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Error -  Setting PSK "\
-                            "mode when WPA param was set to %d\n",
-                            ar->arAuthMode));
-                        ret = -EIO;
-                    }
-                    break;
-                case IEEE80211_AUTH_WPA_CCKM:
-                    if (WPA2_AUTH == ar->arAuthMode) {
-                        ar->arAuthMode = WPA2_AUTH_CCKM;
-                    } else {
-                        ar->arAuthMode = WPA_AUTH_CCKM;
-                    }
-                    break;
-                default:
-                    break;
-            }
-            break;
-        case IEEE80211_PARAM_UCASTCIPHER:
-            switch (value) {
-                case IEEE80211_CIPHER_AES_CCM:
-                    ar->arPairwiseCrypto = AES_CRYPT;
-                    profChanged          = true;
-                    break;
-                case IEEE80211_CIPHER_TKIP:
-                    ar->arPairwiseCrypto = TKIP_CRYPT;
-                    profChanged          = true;
-                    break;
-                case IEEE80211_CIPHER_WEP:
-                    ar->arPairwiseCrypto = WEP_CRYPT;
-                    profChanged          = true;
-                    break;
-                case IEEE80211_CIPHER_NONE:
-                    ar->arPairwiseCrypto = NONE_CRYPT;
-                    profChanged          = true;
-                    break;
-            }
-            break;
-        case IEEE80211_PARAM_UCASTKEYLEN:
-            if (!IEEE80211_IS_VALID_WEP_CIPHER_LEN(value)) {
-                ret = -EIO;
-            } else {
-                ar->arPairwiseCryptoLen = value;
-            }
-            break;
-        case IEEE80211_PARAM_MCASTCIPHER:
-            switch (value) {
-                case IEEE80211_CIPHER_AES_CCM:
-                    ar->arGroupCrypto = AES_CRYPT;
-                    profChanged       = true;
-                    break;
-                case IEEE80211_CIPHER_TKIP:
-                    ar->arGroupCrypto = TKIP_CRYPT;
-                    profChanged       = true;
-                    break;
-                case IEEE80211_CIPHER_WEP:
-                    ar->arGroupCrypto = WEP_CRYPT;
-                    profChanged       = true;
-                    break;
-                case IEEE80211_CIPHER_NONE:
-                    ar->arGroupCrypto = NONE_CRYPT;
-                    profChanged       = true;
-                    break;
-            }
-            break;
-        case IEEE80211_PARAM_MCASTKEYLEN:
-            if (!IEEE80211_IS_VALID_WEP_CIPHER_LEN(value)) {
-                ret = -EIO;
-            } else {
-                ar->arGroupCryptoLen = value;
-            }
-            break;
-        case IEEE80211_PARAM_COUNTERMEASURES:
-            if (ar->arWmiReady == false) {
-                return -EIO;
-            }
-            wmi_set_tkip_countermeasures_cmd(ar->arWmi, value);
-            break;
-        default:
-            break;
-    }
-    if ((ar->arNextMode != AP_NETWORK) && (profChanged == true)) {
-        /*
-         * profile has changed.  Erase ssid to signal change
-         */
-        A_MEMZERO(ar->arSsid, sizeof(ar->arSsid));
-    }
-
-    return ret;
-}
-
-int
-ar6000_ioctl_setkey(struct ar6_softc *ar, struct ieee80211req_key *ik)
-{
-    KEY_USAGE keyUsage;
-    int status;
-    CRYPTO_TYPE keyType = NONE_CRYPT;
-
-#ifdef USER_KEYS
-    ar->user_saved_keys.keyOk = false;
-#endif
-    if ( (0 == memcmp(ik->ik_macaddr, null_mac, IEEE80211_ADDR_LEN)) ||
-         (0 == memcmp(ik->ik_macaddr, bcast_mac, IEEE80211_ADDR_LEN)) ) {
-        keyUsage = GROUP_USAGE;
-        if(ar->arNextMode == AP_NETWORK) {
-            memcpy(&ar->ap_mode_bkey, ik,
-                     sizeof(struct ieee80211req_key));
-#ifdef WAPI_ENABLE
-            if(ar->arPairwiseCrypto == WAPI_CRYPT) {
-                return ap_set_wapi_key(ar, ik);
-            }
-#endif
-        }
-#ifdef USER_KEYS
-        memcpy(&ar->user_saved_keys.bcast_ik, ik,
-                 sizeof(struct ieee80211req_key));
-#endif
-    } else {
-        keyUsage = PAIRWISE_USAGE;
-#ifdef USER_KEYS
-        memcpy(&ar->user_saved_keys.ucast_ik, ik,
-                 sizeof(struct ieee80211req_key));
-#endif
-#ifdef WAPI_ENABLE
-        if(ar->arNextMode == AP_NETWORK) {
-            if(ar->arPairwiseCrypto == WAPI_CRYPT) {
-                return ap_set_wapi_key(ar, ik);
-            }
-        }
-#endif
-    }
-
-    switch (ik->ik_type) {
-        case IEEE80211_CIPHER_WEP:
-            keyType = WEP_CRYPT;
-            break;
-        case IEEE80211_CIPHER_TKIP:
-            keyType = TKIP_CRYPT;
-            break;
-        case IEEE80211_CIPHER_AES_CCM:
-            keyType = AES_CRYPT;
-            break;
-        default:
-            break;
-    }
-#ifdef USER_KEYS
-    ar->user_saved_keys.keyType = keyType;
-#endif
-    if (IEEE80211_CIPHER_CCKM_KRK != ik->ik_type) {
-        if (NONE_CRYPT == keyType) {
-            return -EIO;
-        }
-
-        if ((WEP_CRYPT == keyType)&&(!ar->arConnected)) {
-             int index = ik->ik_keyix;
-
-            if (!IEEE80211_IS_VALID_WEP_CIPHER_LEN(ik->ik_keylen)) {
-                return -EIO;
-            }
-
-            A_MEMZERO(ar->arWepKeyList[index].arKey,
-                            sizeof(ar->arWepKeyList[index].arKey));
-            memcpy(ar->arWepKeyList[index].arKey, ik->ik_keydata, ik->ik_keylen);
-            ar->arWepKeyList[index].arKeyLen = ik->ik_keylen;
-
-            if(ik->ik_flags & IEEE80211_KEY_DEFAULT){
-                ar->arDefTxKeyIndex = index;
-            }
-
-            return 0;
-        }
-
-        if (((WPA_PSK_AUTH == ar->arAuthMode) || (WPA2_PSK_AUTH == ar->arAuthMode)) &&
-            (GROUP_USAGE & keyUsage))
-        {
-            A_UNTIMEOUT(&ar->disconnect_timer);
-        }
-
-        status = wmi_addKey_cmd(ar->arWmi, ik->ik_keyix, keyType, keyUsage,
-                                ik->ik_keylen, (u8 *)&ik->ik_keyrsc,
-                                ik->ik_keydata, KEY_OP_INIT_VAL, ik->ik_macaddr,
-                                SYNC_BOTH_WMIFLAG);
-
-        if (status) {
-            return -EIO;
-        }
-    } else {
-        status = wmi_add_krk_cmd(ar->arWmi, ik->ik_keydata);
-    }
-
-#ifdef USER_KEYS
-    ar->user_saved_keys.keyOk = true;
-#endif
-
-    return 0;
-}
-
-int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
-{
-    struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev);
-    struct hif_device *hifDevice = ar->arHifDevice;
-    int ret = 0, param;
-    unsigned int address = 0;
-    unsigned int length = 0;
-    unsigned char *buffer;
-    char *userdata;
-    u32 connectCtrlFlags;
-
-
-    WMI_SET_AKMP_PARAMS_CMD  akmpParams;
-    WMI_SET_PMKID_LIST_CMD   pmkidInfo;
-
-    WMI_SET_HT_CAP_CMD htCap;
-    WMI_SET_HT_OP_CMD htOp;
-
-    /*
-     * ioctl operations may have to wait for the Target, so we cannot hold rtnl.
-     * Prevent the device from disappearing under us and release the lock during
-     * the ioctl operation.
-     */
-    dev_hold(dev);
-    rtnl_unlock();
-
-    if (cmd == AR6000_IOCTL_EXTENDED) {
-        /*
-         * This allows for many more wireless ioctls than would otherwise
-         * be available.  Applications embed the actual ioctl command in
-         * the first word of the parameter block, and use the command
-         * AR6000_IOCTL_EXTENDED_CMD on the ioctl call.
-         */
-	if (get_user(cmd, (int *)rq->ifr_data)) {
-	    ret = -EFAULT;
-	    goto ioctl_done;
-	}
-        userdata = (char *)(((unsigned int *)rq->ifr_data)+1);
-        if(is_xioctl_allowed(ar->arNextMode, cmd) != 0) {
-            A_PRINTF("xioctl: cmd=%d not allowed in this mode\n",cmd);
-            ret = -EOPNOTSUPP;
-            goto ioctl_done;
-    }
-    } else {
-        int ret = is_iwioctl_allowed(ar->arNextMode, cmd);
-        if(ret == A_ENOTSUP) {
-            A_PRINTF("iwioctl: cmd=0x%x not allowed in this mode\n", cmd);
-            ret = -EOPNOTSUPP;
-            goto ioctl_done;
-        } else if (ret == A_ERROR) {
-            /* It is not our ioctl (out of range ioctl) */
-            ret = -EOPNOTSUPP;
-            goto ioctl_done;
-        }
-        userdata = (char *)rq->ifr_data;
-    }
-
-    if ((ar->arWlanState == WLAN_DISABLED) &&
-        ((cmd != AR6000_XIOCTRL_WMI_SET_WLAN_STATE) &&
-         (cmd != AR6000_XIOCTL_GET_WLAN_SLEEP_STATE) &&
-         (cmd != AR6000_XIOCTL_DIAG_READ) &&
-         (cmd != AR6000_XIOCTL_DIAG_WRITE) &&
-         (cmd != AR6000_XIOCTL_SET_BT_HW_POWER_STATE) &&
-         (cmd != AR6000_XIOCTL_GET_BT_HW_POWER_STATE) &&
-         (cmd != AR6000_XIOCTL_ADD_AP_INTERFACE) &&
-         (cmd != AR6000_XIOCTL_REMOVE_AP_INTERFACE) &&
-         (cmd != AR6000_IOCTL_WMI_GETREV)))
-    {
-        ret = -EIO;
-        goto ioctl_done;
-    }
-
-    ret = 0;
-    switch(cmd)
-    {
-        case IEEE80211_IOCTL_SETPARAM:
-        {
-            int param, value;
-            int *ptr = (int *)rq->ifr_ifru.ifru_newname;
-            if (ar->arWmiReady == false) {
-                ret = -EIO;
-            } else {
-                param = *ptr++;
-                value = *ptr;
-                ret = ar6000_ioctl_setparam(ar,param,value);
-            }
-            break;
-        }
-        case IEEE80211_IOCTL_SETKEY:
-        {
-            struct ieee80211req_key keydata;
-            if (ar->arWmiReady == false) {
-                ret = -EIO;
-            } else if (copy_from_user(&keydata, userdata,
-                            sizeof(struct ieee80211req_key))) {
-                ret = -EFAULT;
-            } else {
-                ar6000_ioctl_setkey(ar, &keydata);
-            }
-            break;
-        }
-        case IEEE80211_IOCTL_DELKEY:
-        case IEEE80211_IOCTL_SETOPTIE:
-        {
-            //ret = -EIO;
-            break;
-        }
-        case IEEE80211_IOCTL_SETMLME:
-        {
-            struct ieee80211req_mlme mlme;
-            if (ar->arWmiReady == false) {
-                ret = -EIO;
-            } else if (copy_from_user(&mlme, userdata,
-                            sizeof(struct ieee80211req_mlme))) {
-                ret = -EFAULT;
-            } else {
-                switch (mlme.im_op) {
-                    case IEEE80211_MLME_AUTHORIZE:
-                        A_PRINTF("setmlme AUTHORIZE %02X:%02X\n",
-                            mlme.im_macaddr[4], mlme.im_macaddr[5]);
-                        break;
-                    case IEEE80211_MLME_UNAUTHORIZE:
-                        A_PRINTF("setmlme UNAUTHORIZE %02X:%02X\n",
-                            mlme.im_macaddr[4], mlme.im_macaddr[5]);
-                        break;
-                    case IEEE80211_MLME_DEAUTH:
-                        A_PRINTF("setmlme DEAUTH %02X:%02X\n",
-                            mlme.im_macaddr[4], mlme.im_macaddr[5]);
-                        //remove_sta(ar, mlme.im_macaddr);
-                        break;
-                    case IEEE80211_MLME_DISASSOC:
-                        A_PRINTF("setmlme DISASSOC %02X:%02X\n",
-                            mlme.im_macaddr[4], mlme.im_macaddr[5]);
-                        //remove_sta(ar, mlme.im_macaddr);
-                        break;
-                    default:
-                        ret = 0;
-                        goto ioctl_done;
-                }
-
-                wmi_ap_set_mlme(ar->arWmi, mlme.im_op, mlme.im_macaddr,
-                                mlme.im_reason);
-            }
-            break;
-        }
-        case IEEE80211_IOCTL_ADDPMKID:
-        {
-            struct ieee80211req_addpmkid  req;
-            if (ar->arWmiReady == false) {
-                ret = -EIO;
-            } else if (copy_from_user(&req, userdata, sizeof(struct ieee80211req_addpmkid))) {
-                ret = -EFAULT;
-            } else {
-                int status;
-
-                AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_CONNECT,("Add pmkid for %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x en=%d\n",
-                    req.pi_bssid[0], req.pi_bssid[1], req.pi_bssid[2],
-                    req.pi_bssid[3], req.pi_bssid[4], req.pi_bssid[5],
-                    req.pi_enable));
-
-                status = wmi_setPmkid_cmd(ar->arWmi, req.pi_bssid, req.pi_pmkid,
-                              req.pi_enable);
-
-                if (status) {
-                    ret = -EIO;
-                    goto ioctl_done;
-                }
-            }
-            break;
-        }
-#ifdef CONFIG_HOST_TCMD_SUPPORT
-        case AR6000_XIOCTL_TCMD_CONT_TX:
-            {
-                TCMD_CONT_TX txCmd;
-
-                if ((ar->tcmdPm == TCMD_PM_SLEEP) ||
-                    (ar->tcmdPm == TCMD_PM_DEEPSLEEP))
-                {
-                    A_PRINTF("Can NOT send tx tcmd when target is asleep! \n");
-                    ret = -EFAULT;
-                    goto ioctl_done;
-                }
-
-                if(copy_from_user(&txCmd, userdata, sizeof(TCMD_CONT_TX))) {
-                    ret = -EFAULT;
-                    goto ioctl_done;
-                } else {
-                    wmi_test_cmd(ar->arWmi,(u8 *)&txCmd, sizeof(TCMD_CONT_TX));
-                }
-            }
-            break;
-        case AR6000_XIOCTL_TCMD_CONT_RX:
-            {
-                TCMD_CONT_RX rxCmd;
-
-                if ((ar->tcmdPm == TCMD_PM_SLEEP) ||
-                    (ar->tcmdPm == TCMD_PM_DEEPSLEEP))
-                {
-                    A_PRINTF("Can NOT send rx tcmd when target is asleep! \n");
-                    ret = -EFAULT;
-                    goto ioctl_done;
-                }
-                if(copy_from_user(&rxCmd, userdata, sizeof(TCMD_CONT_RX))) {
-                    ret = -EFAULT;
-                    goto ioctl_done;
-                }
-
-                switch(rxCmd.act)
-                {
-                    case TCMD_CONT_RX_PROMIS:
-                    case TCMD_CONT_RX_FILTER:
-                    case TCMD_CONT_RX_SETMAC:
-                    case TCMD_CONT_RX_SET_ANT_SWITCH_TABLE:
-                         wmi_test_cmd(ar->arWmi,(u8 *)&rxCmd,
-                                                sizeof(TCMD_CONT_RX));
-                         tcmdRxFreq = rxCmd.u.para.freq;
-                         break;
-                    case TCMD_CONT_RX_REPORT:
-                         ar6000_ioctl_tcmd_get_rx_report(dev, rq,
-                         (u8 *)&rxCmd, sizeof(TCMD_CONT_RX));
-                         break;
-                    default:
-                         A_PRINTF("Unknown Cont Rx mode: %d\n",rxCmd.act);
-                         ret = -EINVAL;
-                         goto ioctl_done;
-                }
-            }
-            break;
-        case AR6000_XIOCTL_TCMD_PM:
-            {
-                TCMD_PM pmCmd;
-
-                if(copy_from_user(&pmCmd, userdata, sizeof(TCMD_PM))) {
-                    ret = -EFAULT;
-                    goto ioctl_done;
-                }
-                ar->tcmdPm = pmCmd.mode;
-                wmi_test_cmd(ar->arWmi, (u8 *)&pmCmd, sizeof(TCMD_PM));
-            }
-            break;
-#endif /* CONFIG_HOST_TCMD_SUPPORT */
-
-        case AR6000_XIOCTL_BMI_DONE:
-            if(bmienable)
-            {
-                rtnl_lock(); /* ar6000_init expects to be called holding rtnl lock */
-                ret = ar6000_init(dev);
-                rtnl_unlock();
-            }
-            else
-            {
-                ret = BMIDone(hifDevice);
-            }
-            break;
-
-        case AR6000_XIOCTL_BMI_READ_MEMORY:
-	     if (get_user(address, (unsigned int *)userdata) ||
-		get_user(length, (unsigned int *)userdata + 1)) {
-		ret = -EFAULT;
-		break;
-	    }
-
-            AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("Read Memory (address: 0x%x, length: %d)\n",
-                             address, length));
-            if ((buffer = (unsigned char *)A_MALLOC(length)) != NULL) {
-                A_MEMZERO(buffer, length);
-                ret = BMIReadMemory(hifDevice, address, buffer, length);
-                if (copy_to_user(rq->ifr_data, buffer, length)) {
-                    ret = -EFAULT;
-                }
-                A_FREE(buffer);
-            } else {
-                ret = -ENOMEM;
-            }
-            break;
-
-        case AR6000_XIOCTL_BMI_WRITE_MEMORY:
-	     if (get_user(address, (unsigned int *)userdata) ||
-		get_user(length, (unsigned int *)userdata + 1)) {
-		ret = -EFAULT;
-		break;
-	    }
-            AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("Write Memory (address: 0x%x, length: %d)\n",
-                             address, length));
-            if ((buffer = (unsigned char *)A_MALLOC(length)) != NULL) {
-                A_MEMZERO(buffer, length);
-                if (copy_from_user(buffer, &userdata[sizeof(address) +
-                                   sizeof(length)], length))
-                {
-                    ret = -EFAULT;
-                } else {
-                    ret = BMIWriteMemory(hifDevice, address, buffer, length);
-                }
-                A_FREE(buffer);
-            } else {
-                ret = -ENOMEM;
-            }
-            break;
-
-        case AR6000_XIOCTL_BMI_TEST:
-           AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("No longer supported\n"));
-           ret = -EOPNOTSUPP;
-           break;
-
-        case AR6000_XIOCTL_BMI_EXECUTE:
-	     if (get_user(address, (unsigned int *)userdata) ||
-		get_user(param, (unsigned int *)userdata + 1)) {
-		ret = -EFAULT;
-		break;
-	    }
-            AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("Execute (address: 0x%x, param: %d)\n",
-                             address, param));
-            ret = BMIExecute(hifDevice, address, (u32 *)&param);
-	    /* return value */
-	    if (put_user(param, (unsigned int *)rq->ifr_data)) {
-		ret = -EFAULT;
-		break;
-	    }
-            break;
-
-        case AR6000_XIOCTL_BMI_SET_APP_START:
-	    if (get_user(address, (unsigned int *)userdata)) {
-		ret = -EFAULT;
-		break;
-	    }
-            AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("Set App Start (address: 0x%x)\n", address));
-            ret = BMISetAppStart(hifDevice, address);
-            break;
-
-        case AR6000_XIOCTL_BMI_READ_SOC_REGISTER:
-	    if (get_user(address, (unsigned int *)userdata)) {
-		ret = -EFAULT;
-		break;
-	    }
-            ret = BMIReadSOCRegister(hifDevice, address, (u32 *)&param);
-	    /* return value */
-	    if (put_user(param, (unsigned int *)rq->ifr_data)) {
-		ret = -EFAULT;
-		break;
-	    }
-            break;
-
-        case AR6000_XIOCTL_BMI_WRITE_SOC_REGISTER:
-	    if (get_user(address, (unsigned int *)userdata) ||
-		get_user(param, (unsigned int *)userdata + 1)) {
-		ret = -EFAULT;
-		break;
-	    }
-            ret = BMIWriteSOCRegister(hifDevice, address, param);
-            break;
-
-#ifdef HTC_RAW_INTERFACE
-        case AR6000_XIOCTL_HTC_RAW_OPEN:
-            ret = 0;
-            if (!arRawIfEnabled(ar)) {
-                /* make sure block size is set in case the target was reset since last
-                  * BMI phase (i.e. flashup downloads) */
-                ret = ar6000_set_htc_params(ar->arHifDevice,
-                                            ar->arTargetType,
-                                            0,  /* use default yield */
-                                            0   /* use default number of HTC ctrl buffers */
-                                            );
-                if (ret) {
-                    break;
-                }
-                /* Terminate the BMI phase */
-                ret = BMIDone(hifDevice);
-                if (ret == 0) {
-                    ret = ar6000_htc_raw_open(ar);
-                }
-            }
-            break;
-
-        case AR6000_XIOCTL_HTC_RAW_CLOSE:
-            if (arRawIfEnabled(ar)) {
-                ret = ar6000_htc_raw_close(ar);
-                arRawIfEnabled(ar) = false;
-            } else {
-                ret = A_ERROR;
-            }
-            break;
-
-        case AR6000_XIOCTL_HTC_RAW_READ:
-            if (arRawIfEnabled(ar)) {
-                unsigned int streamID;
-		if (get_user(streamID, (unsigned int *)userdata) ||
-		    get_user(length, (unsigned int *)userdata + 1)) {
-		    ret = -EFAULT;
-		    break;
-		}
-                buffer = (unsigned char*)rq->ifr_data + sizeof(length);
-                ret = ar6000_htc_raw_read(ar, (HTC_RAW_STREAM_ID)streamID,
-                                          (char*)buffer, length);
-		if (put_user(ret, (unsigned int *)rq->ifr_data)) {
-		    ret = -EFAULT;
-		    break;
-		}
-            } else {
-                ret = A_ERROR;
-            }
-            break;
-
-        case AR6000_XIOCTL_HTC_RAW_WRITE:
-            if (arRawIfEnabled(ar)) {
-                unsigned int streamID;
-		if (get_user(streamID, (unsigned int *)userdata) ||
-		    get_user(length, (unsigned int *)userdata + 1)) {
-		    ret = -EFAULT;
-		    break;
-		}
-                buffer = (unsigned char*)userdata + sizeof(streamID) + sizeof(length);
-                ret = ar6000_htc_raw_write(ar, (HTC_RAW_STREAM_ID)streamID,
-                                           (char*)buffer, length);
-		if (put_user(ret, (unsigned int *)rq->ifr_data)) {
-		    ret = -EFAULT;
-		    break;
-		}
-            } else {
-                ret = A_ERROR;
-            }
-            break;
-#endif /* HTC_RAW_INTERFACE */
-
-        case AR6000_XIOCTL_BMI_LZ_STREAM_START:
-	    if (get_user(address, (unsigned int *)userdata)) {
-		ret = -EFAULT;
-		break;
-	    }
-            AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("Start Compressed Stream (address: 0x%x)\n", address));
-            ret = BMILZStreamStart(hifDevice, address);
-            break;
-
-        case AR6000_XIOCTL_BMI_LZ_DATA:
-	    if (get_user(length, (unsigned int *)userdata)) {
-		ret = -EFAULT;
-		break;
-	    }
-            AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("Send Compressed Data (length: %d)\n", length));
-            if ((buffer = (unsigned char *)A_MALLOC(length)) != NULL) {
-                A_MEMZERO(buffer, length);
-                if (copy_from_user(buffer, &userdata[sizeof(length)], length))
-                {
-                    ret = -EFAULT;
-                } else {
-                    ret = BMILZData(hifDevice, buffer, length);
-                }
-                A_FREE(buffer);
-            } else {
-                ret = -ENOMEM;
-            }
-            break;
-
-#if defined(CONFIG_TARGET_PROFILE_SUPPORT)
-        /*
-         * Optional support for Target-side profiling.
-         * Not needed in production.
-         */
-
-        /* Configure Target-side profiling */
-        case AR6000_XIOCTL_PROF_CFG:
-        {
-            u32 period;
-            u32 nbins;
-	    if (get_user(period, (unsigned int *)userdata) ||
-		get_user(nbins, (unsigned int *)userdata + 1)) {
-		ret = -EFAULT;
-		break;
-	    }
-
-            if (wmi_prof_cfg_cmd(ar->arWmi, period, nbins) != 0) {
-                ret = -EIO;
-            }
-
-            break;
-        }
-
-        /* Start a profiling bucket/bin at the specified address */
-        case AR6000_XIOCTL_PROF_ADDR_SET:
-        {
-            u32 addr;
-	    if (get_user(addr, (unsigned int *)userdata)) {
-		ret = -EFAULT;
-		break;
-	    }
-
-            if (wmi_prof_addr_set_cmd(ar->arWmi, addr) != 0) {
-                ret = -EIO;
-            }
-
-            break;
-        }
-
-        /* START Target-side profiling */
-        case AR6000_XIOCTL_PROF_START:
-            wmi_prof_start_cmd(ar->arWmi);
-            break;
-
-        /* STOP Target-side profiling */
-        case AR6000_XIOCTL_PROF_STOP:
-            wmi_prof_stop_cmd(ar->arWmi);
-            break;
-        case AR6000_XIOCTL_PROF_COUNT_GET:
-        {
-            if (ar->bIsDestroyProgress) {
-                ret = -EBUSY;
-                goto ioctl_done;
-            }
-            if (ar->arWmiReady == false) {
-                ret = -EIO;
-                goto ioctl_done;
-            }
-            if (down_interruptible(&ar->arSem)) {
-                ret = -ERESTARTSYS;
-                goto ioctl_done;
-            }
-            if (ar->bIsDestroyProgress) {
-                up(&ar->arSem);
-                ret = -EBUSY;
-                goto ioctl_done;
-            }
-
-            prof_count_available = false;
-            ret = prof_count_get(dev);
-            if (ret != 0) {
-                up(&ar->arSem);
-                ret = -EIO;
-                goto ioctl_done;
-            }
-
-            /* Wait for Target to respond. */
-            wait_event_interruptible(arEvent, prof_count_available);
-            if (signal_pending(current)) {
-                ret = -EINTR;
-            } else {
-                if (copy_to_user(userdata, &prof_count_results,
-                                 sizeof(prof_count_results)))
-                {
-                    ret = -EFAULT;
-                }
-            }
-            up(&ar->arSem);
-            break;
-        }
-#endif /* CONFIG_TARGET_PROFILE_SUPPORT */
-
-        case AR6000_IOCTL_WMI_GETREV:
-        {
-            if (copy_to_user(rq->ifr_data, &ar->arVersion,
-                             sizeof(ar->arVersion)))
-            {
-                ret = -EFAULT;
-            }
-            break;
-        }
-        case AR6000_IOCTL_WMI_SETPWR:
-        {
-            WMI_POWER_MODE_CMD pwrModeCmd;
-
-            if (ar->arWmiReady == false) {
-                ret = -EIO;
-            } else if (copy_from_user(&pwrModeCmd, userdata,
-                                   sizeof(pwrModeCmd)))
-            {
-                ret = -EFAULT;
-            } else {
-                if (wmi_powermode_cmd(ar->arWmi, pwrModeCmd.powerMode)
-                       != 0)
-                {
-                    ret = -EIO;
-                }
-            }
-            break;
-        }
-        case AR6000_IOCTL_WMI_SET_IBSS_PM_CAPS:
-        {
-            WMI_IBSS_PM_CAPS_CMD ibssPmCaps;
-
-            if (ar->arWmiReady == false) {
-                ret = -EIO;
-            } else if (copy_from_user(&ibssPmCaps, userdata,
-                                   sizeof(ibssPmCaps)))
-            {
-                ret = -EFAULT;
-            } else {
-                if (wmi_ibsspmcaps_cmd(ar->arWmi, ibssPmCaps.power_saving, ibssPmCaps.ttl,
-                    ibssPmCaps.atim_windows, ibssPmCaps.timeout_value) != 0)
-                {
-                    ret = -EIO;
-                }
-                AR6000_SPIN_LOCK(&ar->arLock, 0);
-                ar->arIbssPsEnable = ibssPmCaps.power_saving;
-                AR6000_SPIN_UNLOCK(&ar->arLock, 0);
-            }
-            break;
-        }
-        case AR6000_XIOCTL_WMI_SET_AP_PS:
-        {
-            WMI_AP_PS_CMD apPsCmd;
-
-            if (ar->arWmiReady == false) {
-                ret = -EIO;
-            } else if (copy_from_user(&apPsCmd, userdata,
-                                   sizeof(apPsCmd)))
-            {
-                ret = -EFAULT;
-            } else {
-                if (wmi_apps_cmd(ar->arWmi, apPsCmd.psType, apPsCmd.idle_time,
-                    apPsCmd.ps_period, apPsCmd.sleep_period) != 0)
-                {
-                    ret = -EIO;
-                }
-            }
-            break;
-        }
-        case AR6000_IOCTL_WMI_SET_PMPARAMS:
-        {
-            WMI_POWER_PARAMS_CMD pmParams;
-
-            if (ar->arWmiReady == false) {
-                ret = -EIO;
-            } else if (copy_from_user(&pmParams, userdata,
-                                      sizeof(pmParams)))
-            {
-                ret = -EFAULT;
-            } else {
-                if (wmi_pmparams_cmd(ar->arWmi, pmParams.idle_period,
-                                     pmParams.pspoll_number,
-                                     pmParams.dtim_policy,
-                                     pmParams.tx_wakeup_policy,
-                                     pmParams.num_tx_to_wakeup,
-#if WLAN_CONFIG_IGNORE_POWER_SAVE_FAIL_EVENT_DURING_SCAN
-                                     IGNORE_POWER_SAVE_FAIL_EVENT_DURING_SCAN 
-#else
-                                     SEND_POWER_SAVE_FAIL_EVENT_ALWAYS
-#endif
-                                     ) != 0)
-                {
-                    ret = -EIO;
-                }
-            }
-            break;
-        }
-        case AR6000_IOCTL_WMI_SETSCAN:
-        {
-            if (ar->arWmiReady == false) {
-                ret = -EIO;
-            } else if (copy_from_user(&ar->scParams, userdata,
-                                      sizeof(ar->scParams)))
-            {
-                ret = -EFAULT;
-            } else {
-                if (CAN_SCAN_IN_CONNECT(ar->scParams.scanCtrlFlags)) {
-                    ar->arSkipScan = false;
-                } else {
-                    ar->arSkipScan = true;
-                }
-
-                if (wmi_scanparams_cmd(ar->arWmi, ar->scParams.fg_start_period,
-                                       ar->scParams.fg_end_period,
-                                       ar->scParams.bg_period,
-                                       ar->scParams.minact_chdwell_time,
-                                       ar->scParams.maxact_chdwell_time,
-                                       ar->scParams.pas_chdwell_time,
-                                       ar->scParams.shortScanRatio,
-                                       ar->scParams.scanCtrlFlags,
-                                       ar->scParams.max_dfsch_act_time,
-                                       ar->scParams.maxact_scan_per_ssid) != 0)
-                {
-                    ret = -EIO;
-                }
-            }
-            break;
-        }
-        case AR6000_IOCTL_WMI_SETLISTENINT:
-        {
-            WMI_LISTEN_INT_CMD listenCmd;
-
-            if (ar->arWmiReady == false) {
-                ret = -EIO;
-            } else if (copy_from_user(&listenCmd, userdata,
-                                      sizeof(listenCmd)))
-            {
-                ret = -EFAULT;
-            } else {
-                    if (wmi_listeninterval_cmd(ar->arWmi, listenCmd.listenInterval, listenCmd.numBeacons) != 0) {
-                        ret = -EIO;
-                    } else {
-                        AR6000_SPIN_LOCK(&ar->arLock, 0);
-                        ar->arListenIntervalT = listenCmd.listenInterval;
-                        ar->arListenIntervalB = listenCmd.numBeacons;
-                        AR6000_SPIN_UNLOCK(&ar->arLock, 0);
-                    }
-
-                }
-            break;
-        }
-        case AR6000_IOCTL_WMI_SET_BMISS_TIME:
-        {
-            WMI_BMISS_TIME_CMD bmissCmd;
-
-            if (ar->arWmiReady == false) {
-                ret = -EIO;
-            } else if (copy_from_user(&bmissCmd, userdata,
-                                      sizeof(bmissCmd)))
-            {
-                ret = -EFAULT;
-            } else {
-                if (wmi_bmisstime_cmd(ar->arWmi, bmissCmd.bmissTime, bmissCmd.numBeacons) != 0) {
-                    ret = -EIO;
-                }
-            }
-            break;
-        }
-        case AR6000_IOCTL_WMI_SETBSSFILTER:
-        {
-            WMI_BSS_FILTER_CMD filt;
-
-            if (ar->arWmiReady == false) {
-                ret = -EIO;
-            } else if (copy_from_user(&filt, userdata,
-                                   sizeof(filt)))
-            {
-                ret = -EFAULT;
-            } else {
-                if (wmi_bssfilter_cmd(ar->arWmi, filt.bssFilter, filt.ieMask)
-                        != 0) {
-                    ret = -EIO;
-                } else {
-                    ar->arUserBssFilter = filt.bssFilter;
-                }
-            }
-            break;
-        }
-
-        case AR6000_IOCTL_WMI_SET_SNRTHRESHOLD:
-        {
-            ret = ar6000_ioctl_set_snr_threshold(dev, rq);
-            break;
-        }
-        case AR6000_XIOCTL_WMI_SET_RSSITHRESHOLD:
-        {
-            ret = ar6000_ioctl_set_rssi_threshold(dev, rq);
-            break;
-        }
-        case AR6000_XIOCTL_WMI_CLR_RSSISNR:
-        {
-            if (ar->arWmiReady == false) {
-                ret = -EIO;
-            }
-            ret = wmi_clr_rssi_snr(ar->arWmi);
-            break;
-        }
-        case AR6000_XIOCTL_WMI_SET_LQTHRESHOLD:
-        {
-            ret = ar6000_ioctl_set_lq_threshold(dev, rq);
-            break;
-        }
-        case AR6000_XIOCTL_WMI_SET_LPREAMBLE:
-        {
-            WMI_SET_LPREAMBLE_CMD setLpreambleCmd;
-
-            if (ar->arWmiReady == false) {
-                ret = -EIO;
-            } else if (copy_from_user(&setLpreambleCmd, userdata,
-                                   sizeof(setLpreambleCmd)))
-            {
-                ret = -EFAULT;
-            } else {
-                if (wmi_set_lpreamble_cmd(ar->arWmi, setLpreambleCmd.status,
-#if WLAN_CONFIG_DONOT_IGNORE_BARKER_IN_ERP 
-                           WMI_DONOT_IGNORE_BARKER_IN_ERP
-#else
-                           WMI_IGNORE_BARKER_IN_ERP
-#endif
-                ) != 0)
-                {
-                    ret = -EIO;
-                }
-            }
-
-            break;
-        }
-        case AR6000_XIOCTL_WMI_SET_RTS:
-        {
-            WMI_SET_RTS_CMD rtsCmd;
-            if (ar->arWmiReady == false) {
-                ret = -EIO;
-            } else if (copy_from_user(&rtsCmd, userdata,
-                                   sizeof(rtsCmd)))
-            {
-                ret = -EFAULT;
-            } else {
-                ar->arRTS = rtsCmd.threshold;
-                if (wmi_set_rts_cmd(ar->arWmi, rtsCmd.threshold)
-                       != 0)
-                {
-                    ret = -EIO;
-                }
-            }
-
-            break;
-        }
-        case AR6000_XIOCTL_WMI_SET_WMM:
-        {
-            ret = ar6000_ioctl_set_wmm(dev, rq);
-            break;
-        }
-       case AR6000_XIOCTL_WMI_SET_QOS_SUPP:
-        {
-            ret = ar6000_ioctl_set_qos_supp(dev, rq);
-            break;
-        }
-        case AR6000_XIOCTL_WMI_SET_TXOP:
-        {
-            ret = ar6000_ioctl_set_txop(dev, rq);
-            break;
-        }
-        case AR6000_XIOCTL_WMI_GET_RD:
-        {
-            ret = ar6000_ioctl_get_rd(dev, rq);
-            break;
-        }
-        case AR6000_IOCTL_WMI_SET_CHANNELPARAMS:
-        {
-            ret = ar6000_ioctl_set_channelParams(dev, rq);
-            break;
-        }
-        case AR6000_IOCTL_WMI_SET_PROBEDSSID:
-        {
-            ret = ar6000_ioctl_set_probedSsid(dev, rq);
-            break;
-        }
-        case AR6000_IOCTL_WMI_SET_BADAP:
-        {
-            ret = ar6000_ioctl_set_badAp(dev, rq);
-            break;
-        }
-        case AR6000_IOCTL_WMI_CREATE_QOS:
-        {
-            ret = ar6000_ioctl_create_qos(dev, rq);
-            break;
-        }
-        case AR6000_IOCTL_WMI_DELETE_QOS:
-        {
-            ret = ar6000_ioctl_delete_qos(dev, rq);
-            break;
-        }
-        case AR6000_IOCTL_WMI_GET_QOS_QUEUE:
-        {
-            ret = ar6000_ioctl_get_qos_queue(dev, rq);
-            break;
-        }
-        case AR6000_IOCTL_WMI_GET_TARGET_STATS:
-        {
-            ret = ar6000_ioctl_get_target_stats(dev, rq);
-            break;
-        }
-        case AR6000_IOCTL_WMI_SET_ERROR_REPORT_BITMASK:
-        {
-            ret = ar6000_ioctl_set_error_report_bitmask(dev, rq);
-            break;
-        }
-        case AR6000_IOCTL_WMI_SET_ASSOC_INFO:
-        {
-            WMI_SET_ASSOC_INFO_CMD cmd;
-            u8 assocInfo[WMI_MAX_ASSOC_INFO_LEN];
-
-            if (ar->arWmiReady == false) {
-                ret = -EIO;
-		break;
-	    }
-
-	    if (get_user(cmd.ieType, userdata)) {
-		ret = -EFAULT;
-		break;
-	    }
-	    if (cmd.ieType >= WMI_MAX_ASSOC_INFO_TYPE) {
-		ret = -EIO;
-		break;
-	    }
-
-	    if (get_user(cmd.bufferSize, userdata + 1) ||
-		(cmd.bufferSize > WMI_MAX_ASSOC_INFO_LEN) ||
-		copy_from_user(assocInfo, userdata + 2, cmd.bufferSize)) {
-		ret = -EFAULT;
-		break;
-	    }
-	    if (wmi_associnfo_cmd(ar->arWmi, cmd.ieType,
-				  cmd.bufferSize, assocInfo) != 0) {
-		ret = -EIO;
-		break;
-	    }
-            break;
-        }
-        case AR6000_IOCTL_WMI_SET_ACCESS_PARAMS:
-        {
-            ret = ar6000_ioctl_set_access_params(dev, rq);
-            break;
-        }
-        case AR6000_IOCTL_WMI_SET_DISC_TIMEOUT:
-        {
-            ret = ar6000_ioctl_set_disconnect_timeout(dev, rq);
-            break;
-        }
-        case AR6000_XIOCTL_FORCE_TARGET_RESET:
-        {
-            if (ar->arHtcTarget)
-            {
-//                HTCForceReset(htcTarget);
-            }
-            else
-            {
-                AR_DEBUG_PRINTF(ATH_DEBUG_WARN,("ar6000_ioctl cannot attempt reset.\n"));
-            }
-            break;
-        }
-        case AR6000_XIOCTL_TARGET_INFO:
-        case AR6000_XIOCTL_CHECK_TARGET_READY: /* backwards compatibility */
-        {
-            /* If we made it to here, then the Target exists and is ready. */
-
-            if (cmd == AR6000_XIOCTL_TARGET_INFO) {
-                if (copy_to_user((u32 *)rq->ifr_data, &ar->arVersion.target_ver,
-                                 sizeof(ar->arVersion.target_ver)))
-                {
-                    ret = -EFAULT;
-                }
-                if (copy_to_user(((u32 *)rq->ifr_data)+1, &ar->arTargetType,
-                                 sizeof(ar->arTargetType)))
-                {
-                    ret = -EFAULT;
-                }
-            }
-            break;
-        }
-        case AR6000_XIOCTL_WMI_SET_HB_CHALLENGE_RESP_PARAMS:
-        {
-            WMI_SET_HB_CHALLENGE_RESP_PARAMS_CMD hbparam;
-
-            if (copy_from_user(&hbparam, userdata, sizeof(hbparam)))
-            {
-                ret = -EFAULT;
-            } else {
-                AR6000_SPIN_LOCK(&ar->arLock, 0);
-                /* Start a cyclic timer with the parameters provided. */
-                if (hbparam.frequency) {
-                    ar->arHBChallengeResp.frequency = hbparam.frequency;
-                }
-                if (hbparam.threshold) {
-                    ar->arHBChallengeResp.missThres = hbparam.threshold;
-                }
-
-                /* Delete the pending timer and start a new one */
-                if (timer_pending(&ar->arHBChallengeResp.timer)) {
-                    A_UNTIMEOUT(&ar->arHBChallengeResp.timer);
-                }
-                A_TIMEOUT_MS(&ar->arHBChallengeResp.timer, ar->arHBChallengeResp.frequency * 1000, 0);
-                AR6000_SPIN_UNLOCK(&ar->arLock, 0);
-            }
-            break;
-        }
-        case AR6000_XIOCTL_WMI_GET_HB_CHALLENGE_RESP:
-        {
-            u32 cookie;
-
-            if (copy_from_user(&cookie, userdata, sizeof(cookie))) {
-                ret = -EFAULT;
-                goto ioctl_done;
-            }
-
-            /* Send the challenge on the control channel */
-            if (wmi_get_challenge_resp_cmd(ar->arWmi, cookie, APP_HB_CHALLENGE) != 0) {
-                ret = -EIO;
-                goto ioctl_done;
-            }
-            break;
-        }
-#ifdef USER_KEYS
-        case AR6000_XIOCTL_USER_SETKEYS:
-        {
-
-            ar->user_savedkeys_stat = USER_SAVEDKEYS_STAT_RUN;
-
-            if (copy_from_user(&ar->user_key_ctrl, userdata,
-                               sizeof(ar->user_key_ctrl)))
-            {
-                ret = -EFAULT;
-                goto ioctl_done;
-            }
-
-            A_PRINTF("ar6000 USER set key %x\n", ar->user_key_ctrl);
-            break;
-        }
-#endif /* USER_KEYS */
-
-#ifdef CONFIG_HOST_GPIO_SUPPORT
-        case AR6000_XIOCTL_GPIO_OUTPUT_SET:
-        {
-            struct ar6000_gpio_output_set_cmd_s gpio_output_set_cmd;
-
-            if (ar->bIsDestroyProgress) {
-                ret = -EBUSY;
-                goto ioctl_done;
-            }
-            if (ar->arWmiReady == false) {
-                ret = -EIO;
-                goto ioctl_done;
-            }
-            if (down_interruptible(&ar->arSem)) {
-                ret = -ERESTARTSYS;
-                goto ioctl_done;
-            }
-            if (ar->bIsDestroyProgress) {
-                up(&ar->arSem);
-                ret = -EBUSY;
-                goto ioctl_done;
-            }
-
-            if (copy_from_user(&gpio_output_set_cmd, userdata,
-                                sizeof(gpio_output_set_cmd)))
-            {
-                ret = -EFAULT;
-            } else {
-                ret = ar6000_gpio_output_set(dev,
-                                             gpio_output_set_cmd.set_mask,
-                                             gpio_output_set_cmd.clear_mask,
-                                             gpio_output_set_cmd.enable_mask,
-                                             gpio_output_set_cmd.disable_mask);
-                if (ret != 0) {
-                    ret = -EIO;
-                }
-            }
-            up(&ar->arSem);
-            break;
-        }
-        case AR6000_XIOCTL_GPIO_INPUT_GET:
-        {
-            if (ar->bIsDestroyProgress) {
-                ret = -EBUSY;
-                goto ioctl_done;
-            }
-            if (ar->arWmiReady == false) {
-                ret = -EIO;
-                goto ioctl_done;
-            }
-            if (down_interruptible(&ar->arSem)) {
-                ret = -ERESTARTSYS;
-                goto ioctl_done;
-            }
-            if (ar->bIsDestroyProgress) {
-                up(&ar->arSem);
-                ret = -EBUSY;
-                goto ioctl_done;
-            }
-
-            ret = ar6000_gpio_input_get(dev);
-            if (ret != 0) {
-                up(&ar->arSem);
-                ret = -EIO;
-                goto ioctl_done;
-            }
-
-            /* Wait for Target to respond. */
-            wait_event_interruptible(arEvent, gpio_data_available);
-            if (signal_pending(current)) {
-                ret = -EINTR;
-            } else {
-                A_ASSERT(gpio_reg_results.gpioreg_id == GPIO_ID_NONE);
-
-                if (copy_to_user(userdata, &gpio_reg_results.value,
-                                 sizeof(gpio_reg_results.value)))
-                {
-                    ret = -EFAULT;
-                }
-            }
-            up(&ar->arSem);
-            break;
-        }
-        case AR6000_XIOCTL_GPIO_REGISTER_SET:
-        {
-            struct ar6000_gpio_register_cmd_s gpio_register_cmd;
-
-            if (ar->bIsDestroyProgress) {
-                ret = -EBUSY;
-                goto ioctl_done;
-            }
-            if (ar->arWmiReady == false) {
-                ret = -EIO;
-                goto ioctl_done;
-            }
-            if (down_interruptible(&ar->arSem)) {
-                ret = -ERESTARTSYS;
-                goto ioctl_done;
-            }
-            if (ar->bIsDestroyProgress) {
-                up(&ar->arSem);
-                ret = -EBUSY;
-                goto ioctl_done;
-            }
-
-            if (copy_from_user(&gpio_register_cmd, userdata,
-                                sizeof(gpio_register_cmd)))
-            {
-                ret = -EFAULT;
-            } else {
-                ret = ar6000_gpio_register_set(dev,
-                                               gpio_register_cmd.gpioreg_id,
-                                               gpio_register_cmd.value);
-                if (ret != 0) {
-                    ret = -EIO;
-                }
-
-                /* Wait for acknowledgement from Target */
-                wait_event_interruptible(arEvent, gpio_ack_received);
-                if (signal_pending(current)) {
-                    ret = -EINTR;
-                }
-            }
-            up(&ar->arSem);
-            break;
-        }
-        case AR6000_XIOCTL_GPIO_REGISTER_GET:
-        {
-            struct ar6000_gpio_register_cmd_s gpio_register_cmd;
-
-            if (ar->bIsDestroyProgress) {
-                ret = -EBUSY;
-                goto ioctl_done;
-            }
-            if (ar->arWmiReady == false) {
-                ret = -EIO;
-                goto ioctl_done;
-            }
-            if (down_interruptible(&ar->arSem)) {
-                ret = -ERESTARTSYS;
-                goto ioctl_done;
-            }
-            if (ar->bIsDestroyProgress) {
-                up(&ar->arSem);
-                ret = -EBUSY;
-                goto ioctl_done;
-            }
-
-            if (copy_from_user(&gpio_register_cmd, userdata,
-                                sizeof(gpio_register_cmd)))
-            {
-                ret = -EFAULT;
-            } else {
-                ret = ar6000_gpio_register_get(dev, gpio_register_cmd.gpioreg_id);
-                if (ret != 0) {
-                    up(&ar->arSem);
-                    ret = -EIO;
-                    goto ioctl_done;
-                }
-
-                /* Wait for Target to respond. */
-                wait_event_interruptible(arEvent, gpio_data_available);
-                if (signal_pending(current)) {
-                    ret = -EINTR;
-                } else {
-                    A_ASSERT(gpio_register_cmd.gpioreg_id == gpio_reg_results.gpioreg_id);
-                    if (copy_to_user(userdata, &gpio_reg_results,
-                                     sizeof(gpio_reg_results)))
-                    {
-                        ret = -EFAULT;
-                    }
-                }
-            }
-            up(&ar->arSem);
-            break;
-        }
-        case AR6000_XIOCTL_GPIO_INTR_ACK:
-        {
-            struct ar6000_gpio_intr_ack_cmd_s gpio_intr_ack_cmd;
-
-            if (ar->bIsDestroyProgress) {
-                ret = -EBUSY;
-                goto ioctl_done;
-            }
-            if (ar->arWmiReady == false) {
-                ret = -EIO;
-                goto ioctl_done;
-            }
-            if (down_interruptible(&ar->arSem)) {
-                ret = -ERESTARTSYS;
-                goto ioctl_done;
-            }
-            if (ar->bIsDestroyProgress) {
-                up(&ar->arSem);
-                ret = -EBUSY;
-                goto ioctl_done;
-            }
-
-            if (copy_from_user(&gpio_intr_ack_cmd, userdata,
-                                sizeof(gpio_intr_ack_cmd)))
-            {
-                ret = -EFAULT;
-            } else {
-                ret = ar6000_gpio_intr_ack(dev, gpio_intr_ack_cmd.ack_mask);
-                if (ret != 0) {
-                    ret = -EIO;
-                }
-            }
-            up(&ar->arSem);
-            break;
-        }
-        case AR6000_XIOCTL_GPIO_INTR_WAIT:
-        {
-            /* Wait for Target to report an interrupt. */
-            wait_event_interruptible(arEvent, gpio_intr_available);
-
-            if (signal_pending(current)) {
-                ret = -EINTR;
-            } else {
-                if (copy_to_user(userdata, &gpio_intr_results,
-                                 sizeof(gpio_intr_results)))
-                {
-                    ret = -EFAULT;
-                }
-            }
-            break;
-        }
-#endif /* CONFIG_HOST_GPIO_SUPPORT */
-
-        case AR6000_XIOCTL_DBGLOG_CFG_MODULE:
-        {
-            struct ar6000_dbglog_module_config_s config;
-
-            if (copy_from_user(&config, userdata, sizeof(config))) {
-                ret = -EFAULT;
-                goto ioctl_done;
-            }
-
-            /* Send the challenge on the control channel */
-            if (wmi_config_debug_module_cmd(ar->arWmi, config.mmask,
-                                            config.tsr, config.rep,
-                                            config.size, config.valid) != 0)
-            {
-                ret = -EIO;
-                goto ioctl_done;
-            }
-            break;
-        }
-
-        case AR6000_XIOCTL_DBGLOG_GET_DEBUG_LOGS:
-        {
-            /* Send the challenge on the control channel */
-            if (ar6000_dbglog_get_debug_logs(ar) != 0)
-            {
-                ret = -EIO;
-                goto ioctl_done;
-            }
-            break;
-        }
-
-        case AR6000_XIOCTL_SET_ADHOC_BSSID:
-        {
-            WMI_SET_ADHOC_BSSID_CMD adhocBssid;
-
-            if (ar->arWmiReady == false) {
-                ret = -EIO;
-            } else if (copy_from_user(&adhocBssid, userdata,
-                                      sizeof(adhocBssid)))
-            {
-                ret = -EFAULT;
-            } else if (memcmp(adhocBssid.bssid, bcast_mac,
-                                AR6000_ETH_ADDR_LEN) == 0)
-            {
-                ret = -EFAULT;
-            } else {
-
-                memcpy(ar->arReqBssid, adhocBssid.bssid, sizeof(ar->arReqBssid));
-        }
-            break;
-        }
-
-        case AR6000_XIOCTL_SET_OPT_MODE:
-        {
-        WMI_SET_OPT_MODE_CMD optModeCmd;
-            struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev);
-
-            if (ar->arWmiReady == false) {
-                ret = -EIO;
-            } else if (copy_from_user(&optModeCmd, userdata,
-                                      sizeof(optModeCmd)))
-            {
-                ret = -EFAULT;
-            } else if (ar->arConnected && optModeCmd.optMode == SPECIAL_ON) {
-                ret = -EFAULT;
-
-            } else if (wmi_set_opt_mode_cmd(ar->arWmi, optModeCmd.optMode)
-                       != 0)
-            {
-                ret = -EIO;
-            }
-            break;
-        }
-
-        case AR6000_XIOCTL_OPT_SEND_FRAME:
-        {
-            WMI_OPT_TX_FRAME_CMD optTxFrmCmd;
-            u8 data[MAX_OPT_DATA_LEN];
-
-            if (ar->arWmiReady == false) {
-                ret = -EIO;
-                break;
-            }
-
-            if (copy_from_user(&optTxFrmCmd, userdata, sizeof(optTxFrmCmd))) {
-                ret = -EFAULT;
-                break;
-            }
-
-            if (optTxFrmCmd.optIEDataLen > MAX_OPT_DATA_LEN) {
-                ret = -EINVAL;
-                break;
-            }
-
-            if (copy_from_user(data, userdata+sizeof(WMI_OPT_TX_FRAME_CMD) - 1,
-                                   optTxFrmCmd.optIEDataLen)) {
-                ret = -EFAULT;
-                break;
-            }
-
-            ret = wmi_opt_tx_frame_cmd(ar->arWmi,
-                                           optTxFrmCmd.frmType,
-                                           optTxFrmCmd.dstAddr,
-                                           optTxFrmCmd.bssid,
-                                           optTxFrmCmd.optIEDataLen,
-                                           data);
-            break;
-        }
-        case AR6000_XIOCTL_WMI_SETRETRYLIMITS:
-        {
-            WMI_SET_RETRY_LIMITS_CMD setRetryParams;
-
-            if (ar->arWmiReady == false) {
-                ret = -EIO;
-            } else if (copy_from_user(&setRetryParams, userdata,
-                                      sizeof(setRetryParams)))
-            {
-                ret = -EFAULT;
-            } else {
-                if (wmi_set_retry_limits_cmd(ar->arWmi, setRetryParams.frameType,
-                                          setRetryParams.trafficClass,
-                                          setRetryParams.maxRetries,
-                                          setRetryParams.enableNotify) != 0)
-                {
-                    ret = -EIO;
-                }
-                AR6000_SPIN_LOCK(&ar->arLock, 0);
-                ar->arMaxRetries = setRetryParams.maxRetries;
-                AR6000_SPIN_UNLOCK(&ar->arLock, 0);
-            }
-            break;
-        }
-
-        case AR6000_XIOCTL_SET_BEACON_INTVAL:
-        {
-            WMI_BEACON_INT_CMD bIntvlCmd;
-
-            if (ar->arWmiReady == false) {
-                ret = -EIO;
-            } else if (copy_from_user(&bIntvlCmd, userdata,
-                       sizeof(bIntvlCmd)))
-            {
-                ret = -EFAULT;
-            } else if (wmi_set_adhoc_bconIntvl_cmd(ar->arWmi, bIntvlCmd.beaconInterval)
-                        != 0)
-            {
-                ret = -EIO;
-            }
-            if(ret == 0) {
-                ar->ap_beacon_interval = bIntvlCmd.beaconInterval;
-                ar->ap_profile_flag = 1; /* There is a change in profile */
-            }
-            break;
-        }
-        case IEEE80211_IOCTL_SETAUTHALG:
-        {
-            struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev);
-            struct ieee80211req_authalg req;
-
-            if (ar->arWmiReady == false) {
-                ret = -EIO;
-            } else if (copy_from_user(&req, userdata,
-                       sizeof(struct ieee80211req_authalg)))
-            {
-                ret = -EFAULT;
-            } else {
-                if (req.auth_alg & AUTH_ALG_OPEN_SYSTEM) {
-                    ar->arDot11AuthMode  |= OPEN_AUTH;
-                    ar->arPairwiseCrypto  = NONE_CRYPT;
-                    ar->arGroupCrypto     = NONE_CRYPT;
-                }
-                if (req.auth_alg & AUTH_ALG_SHARED_KEY) {
-                    ar->arDot11AuthMode  |= SHARED_AUTH;
-                    ar->arPairwiseCrypto  = WEP_CRYPT;
-                    ar->arGroupCrypto     = WEP_CRYPT;
-                    ar->arAuthMode        = NONE_AUTH;
-                }
-                if (req.auth_alg == AUTH_ALG_LEAP) {
-                    ar->arDot11AuthMode   = LEAP_AUTH;
-                }
-            }
-            break;
-        }
-
-        case AR6000_XIOCTL_SET_VOICE_PKT_SIZE:
-            ret = ar6000_xioctl_set_voice_pkt_size(dev, userdata);
-            break;
-
-        case AR6000_XIOCTL_SET_MAX_SP:
-            ret = ar6000_xioctl_set_max_sp_len(dev, userdata);
-            break;
-
-        case AR6000_XIOCTL_WMI_GET_ROAM_TBL:
-            ret = ar6000_ioctl_get_roam_tbl(dev, rq);
-            break;
-        case AR6000_XIOCTL_WMI_SET_ROAM_CTRL:
-            ret = ar6000_ioctl_set_roam_ctrl(dev, userdata);
-            break;
-        case AR6000_XIOCTRL_WMI_SET_POWERSAVE_TIMERS:
-            ret = ar6000_ioctl_set_powersave_timers(dev, userdata);
-            break;
-        case AR6000_XIOCTRL_WMI_GET_POWER_MODE:
-            ret = ar6000_ioctl_get_power_mode(dev, rq);
-            break;
-        case AR6000_XIOCTRL_WMI_SET_WLAN_STATE:
-        {
-            AR6000_WLAN_STATE state;
-	    if (get_user(state, (unsigned int *)userdata))
-		ret = -EFAULT;
-	    else if (ar6000_set_wlan_state(ar, state) != 0)
-                ret = -EIO;
-            break;
-        }
-        case AR6000_XIOCTL_WMI_GET_ROAM_DATA:
-            ret = ar6000_ioctl_get_roam_data(dev, rq);
-            break;
-
-        case AR6000_XIOCTL_WMI_SET_BT_STATUS:
-            ret = ar6000_xioctl_set_bt_status_cmd(dev, userdata);
-            break;
-
-        case AR6000_XIOCTL_WMI_SET_BT_PARAMS:
-            ret = ar6000_xioctl_set_bt_params_cmd(dev, userdata);
-            break;
-
-		case AR6000_XIOCTL_WMI_SET_BTCOEX_FE_ANT:
-			ret = ar6000_xioctl_set_btcoex_fe_ant_cmd(dev, userdata);
-			break;
-
-		case AR6000_XIOCTL_WMI_SET_BTCOEX_COLOCATED_BT_DEV:
-			ret = ar6000_xioctl_set_btcoex_colocated_bt_dev_cmd(dev, userdata);
-			break;
-
-		case AR6000_XIOCTL_WMI_SET_BTCOEX_BTINQUIRY_PAGE_CONFIG:
-			ret = ar6000_xioctl_set_btcoex_btinquiry_page_config_cmd(dev, userdata);
-			break;
-
-		case AR6000_XIOCTL_WMI_SET_BTCOEX_SCO_CONFIG:
-			ret = ar6000_xioctl_set_btcoex_sco_config_cmd( dev, userdata);
-			break;
-
-		case AR6000_XIOCTL_WMI_SET_BTCOEX_A2DP_CONFIG:
-			ret = ar6000_xioctl_set_btcoex_a2dp_config_cmd(dev, userdata);
-			break;
-
-		case AR6000_XIOCTL_WMI_SET_BTCOEX_ACLCOEX_CONFIG:
-			ret = ar6000_xioctl_set_btcoex_aclcoex_config_cmd(dev, userdata);
-			break;
-
-		case AR6000_XIOCTL_WMI_SET_BTCOEX_DEBUG:
-			ret = ar60000_xioctl_set_btcoex_debug_cmd(dev, userdata);
-			break;
-
-		case AR6000_XIOCTL_WMI_SET_BT_OPERATING_STATUS:
-			ret = ar6000_xioctl_set_btcoex_bt_operating_status_cmd(dev, userdata);
-			break;
-
-		case AR6000_XIOCTL_WMI_GET_BTCOEX_CONFIG:
-			ret = ar6000_xioctl_get_btcoex_config_cmd(dev, userdata, rq);
-			break;
-
-		case AR6000_XIOCTL_WMI_GET_BTCOEX_STATS:
-			ret = ar6000_xioctl_get_btcoex_stats_cmd(dev, userdata, rq);
-			break;
-
-        case AR6000_XIOCTL_WMI_STARTSCAN:
-        {
-            WMI_START_SCAN_CMD setStartScanCmd, *cmdp;
-
-            if (ar->arWmiReady == false) {
-                    ret = -EIO;
-                } else if (copy_from_user(&setStartScanCmd, userdata,
-                                          sizeof(setStartScanCmd)))
-                {
-                    ret = -EFAULT;
-                } else {
-                    if (setStartScanCmd.numChannels > 1) {
-                        cmdp = A_MALLOC(130);
-                        if (copy_from_user(cmdp, userdata,
-                                           sizeof (*cmdp) +
-                                           ((setStartScanCmd.numChannels - 1) *
-                                           sizeof(u16))))
-                        {
-                            kfree(cmdp);
-                            ret = -EFAULT;
-                            goto ioctl_done;
-                        }
-                    } else {
-                        cmdp = &setStartScanCmd;
-                    }
-
-                    if (wmi_startscan_cmd(ar->arWmi, cmdp->scanType,
-                                          cmdp->forceFgScan,
-                                          cmdp->isLegacy,
-                                          cmdp->homeDwellTime,
-                                          cmdp->forceScanInterval,
-                                          cmdp->numChannels,
-                                          cmdp->channelList) != 0)
-                    {
-                        ret = -EIO;
-                    }
-                }
-            break;
-        }
-        case AR6000_XIOCTL_WMI_SETFIXRATES:
-        {
-            WMI_FIX_RATES_CMD setFixRatesCmd;
-            int returnStatus;
-
-            if (ar->arWmiReady == false) {
-                    ret = -EIO;
-                } else if (copy_from_user(&setFixRatesCmd, userdata,
-                                          sizeof(setFixRatesCmd)))
-                {
-                    ret = -EFAULT;
-                } else {
-                    returnStatus = wmi_set_fixrates_cmd(ar->arWmi, setFixRatesCmd.fixRateMask);
-                    if (returnStatus == A_EINVAL) {
-                        ret = -EINVAL;
-                    } else if(returnStatus != 0) {
-                        ret = -EIO;
-                    } else {
-                        ar->ap_profile_flag = 1; /* There is a change in profile */
-                    }
-                }
-            break;
-        }
-
-        case AR6000_XIOCTL_WMI_GETFIXRATES:
-        {
-            WMI_FIX_RATES_CMD getFixRatesCmd;
-            struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev);
-            int ret = 0;
-
-            if (ar->bIsDestroyProgress) {
-                ret = -EBUSY;
-                goto ioctl_done;
-            }
-            if (ar->arWmiReady == false) {
-                ret = -EIO;
-                goto ioctl_done;
-            }
-
-            if (down_interruptible(&ar->arSem)) {
-                ret = -ERESTARTSYS;
-                goto ioctl_done;
-            }
-            if (ar->bIsDestroyProgress) {
-                up(&ar->arSem);
-                ret = -EBUSY;
-                goto ioctl_done;
-            }
-            /* Used copy_from_user/copy_to_user to access user space data */
-            if (copy_from_user(&getFixRatesCmd, userdata, sizeof(getFixRatesCmd))) {
-                ret = -EFAULT;
-            } else {
-                ar->arRateMask = 0xFFFFFFFF;
-
-                if (wmi_get_ratemask_cmd(ar->arWmi) != 0) {
-                    up(&ar->arSem);
-                    ret = -EIO;
-                    goto ioctl_done;
-                }
-
-                wait_event_interruptible_timeout(arEvent, ar->arRateMask != 0xFFFFFFFF, wmitimeout * HZ);
-
-                if (signal_pending(current)) {
-                    ret = -EINTR;
-                }
-
-                if (!ret) {
-                    getFixRatesCmd.fixRateMask = ar->arRateMask;
-                }
-
-                if(copy_to_user(userdata, &getFixRatesCmd, sizeof(getFixRatesCmd))) {
-                   ret = -EFAULT;
-                }
-
-                up(&ar->arSem);
-            }
-            break;
-        }
-        case AR6000_XIOCTL_WMI_SET_AUTHMODE:
-        {
-            WMI_SET_AUTH_MODE_CMD setAuthMode;
-
-            if (ar->arWmiReady == false) {
-                ret = -EIO;
-            } else if (copy_from_user(&setAuthMode, userdata,
-                                      sizeof(setAuthMode)))
-            {
-                ret = -EFAULT;
-            } else {
-                if (wmi_set_authmode_cmd(ar->arWmi, setAuthMode.mode) != 0)
-                {
-                    ret = -EIO;
-                }
-            }
-            break;
-        }
-        case AR6000_XIOCTL_WMI_SET_REASSOCMODE:
-        {
-            WMI_SET_REASSOC_MODE_CMD setReassocMode;
-
-            if (ar->arWmiReady == false) {
-                ret = -EIO;
-            } else if (copy_from_user(&setReassocMode, userdata,
-                                      sizeof(setReassocMode)))
-            {
-                ret = -EFAULT;
-            } else {
-                if (wmi_set_reassocmode_cmd(ar->arWmi, setReassocMode.mode) != 0)
-                {
-                    ret = -EIO;
-                }
-            }
-            break;
-        }
-        case AR6000_XIOCTL_DIAG_READ:
-        {
-            u32 addr, data;
-	    if (get_user(addr, (unsigned int *)userdata)) {
-		ret = -EFAULT;
-		break;
-	    }
-            addr = TARG_VTOP(ar->arTargetType, addr);
-            if (ar6000_ReadRegDiag(ar->arHifDevice, &addr, &data) != 0) {
-                ret = -EIO;
-            }
-	    if (put_user(data, (unsigned int *)userdata + 1)) {
-		ret = -EFAULT;
-		break;
-	    }
-            break;
-        }
-        case AR6000_XIOCTL_DIAG_WRITE:
-        {
-            u32 addr, data;
-	    if (get_user(addr, (unsigned int *)userdata) ||
-		get_user(data, (unsigned int *)userdata + 1)) {
-		ret = -EFAULT;
-		break;
-	    }
-            addr = TARG_VTOP(ar->arTargetType, addr);
-            if (ar6000_WriteRegDiag(ar->arHifDevice, &addr, &data) != 0) {
-                ret = -EIO;
-            }
-            break;
-        }
-        case AR6000_XIOCTL_WMI_SET_KEEPALIVE:
-        {
-             WMI_SET_KEEPALIVE_CMD setKeepAlive;
-             if (ar->arWmiReady == false) {
-                 ret = -EIO;
-                 goto ioctl_done;
-             } else if (copy_from_user(&setKeepAlive, userdata,
-                        sizeof(setKeepAlive))){
-                 ret = -EFAULT;
-             } else {
-                 if (wmi_set_keepalive_cmd(ar->arWmi, setKeepAlive.keepaliveInterval) != 0) {
-                     ret = -EIO;
-               }
-             }
-             break;
-        }
-        case AR6000_XIOCTL_WMI_SET_PARAMS:
-        {
-             WMI_SET_PARAMS_CMD cmd;
-             if (ar->arWmiReady == false) {
-                 ret = -EIO;
-                 goto ioctl_done;
-             } else if (copy_from_user(&cmd, userdata,
-                        sizeof(cmd))){
-                 ret = -EFAULT;
-             } else if (copy_from_user(&cmd, userdata,
-                        sizeof(cmd) + cmd.length))
-            {
-                ret = -EFAULT;
-            } else {
-                 if (wmi_set_params_cmd(ar->arWmi, cmd.opcode, cmd.length, cmd.buffer) != 0) {
-                     ret = -EIO;
-               }
-             }
-             break;
-        }
-        case AR6000_XIOCTL_WMI_SET_MCAST_FILTER:
-        {
-             WMI_SET_MCAST_FILTER_CMD cmd;
-             if (ar->arWmiReady == false) {
-                 ret = -EIO;
-                 goto ioctl_done;
-             } else if (copy_from_user(&cmd, userdata,
-                        sizeof(cmd))){
-                 ret = -EFAULT;
-             } else {
-                 if (wmi_set_mcast_filter_cmd(ar->arWmi, cmd.multicast_mac[0],
-                                                                                     cmd.multicast_mac[1],
-                                                                                     cmd.multicast_mac[2],
-                                                                                     cmd.multicast_mac[3]) != 0) {
-                     ret = -EIO;
-               }
-             }
-             break;
-        }
-        case AR6000_XIOCTL_WMI_DEL_MCAST_FILTER:
-        {
-             WMI_SET_MCAST_FILTER_CMD cmd;
-             if (ar->arWmiReady == false) {
-                 ret = -EIO;
-                 goto ioctl_done;
-             } else if (copy_from_user(&cmd, userdata,
-                        sizeof(cmd))){
-                 ret = -EFAULT;
-             } else {
-                 if (wmi_del_mcast_filter_cmd(ar->arWmi, cmd.multicast_mac[0],
-                                                                                     cmd.multicast_mac[1],
-                                                                                     cmd.multicast_mac[2],
-                                                                                     cmd.multicast_mac[3]) != 0) {
-                     ret = -EIO;
-               }
-             }
-             break;
-        }
-        case AR6000_XIOCTL_WMI_MCAST_FILTER:
-        {
-             WMI_MCAST_FILTER_CMD cmd;
-             if (ar->arWmiReady == false) {
-                 ret = -EIO;
-                 goto ioctl_done;
-             } else if (copy_from_user(&cmd, userdata,
-                        sizeof(cmd))){
-                 ret = -EFAULT;
-             } else {
-                 if (wmi_mcast_filter_cmd(ar->arWmi, cmd.enable)  != 0) {
-                     ret = -EIO;
-               }
-             }
-             break;
-        }
-        case AR6000_XIOCTL_WMI_GET_KEEPALIVE:
-        {
-            struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev);
-            WMI_GET_KEEPALIVE_CMD getKeepAlive;
-            int ret = 0;
-            if (ar->bIsDestroyProgress) {
-                ret =-EBUSY;
-                goto ioctl_done;
-            }
-            if (ar->arWmiReady == false) {
-               ret = -EIO;
-               goto ioctl_done;
-            }
-            if (down_interruptible(&ar->arSem)) {
-                ret = -ERESTARTSYS;
-                goto ioctl_done;
-            }
-            if (ar->bIsDestroyProgress) {
-                up(&ar->arSem);
-                ret = -EBUSY;
-                goto ioctl_done;
-            }
-            if (copy_from_user(&getKeepAlive, userdata,sizeof(getKeepAlive))) {
-               ret = -EFAULT;
-            } else {
-            getKeepAlive.keepaliveInterval = wmi_get_keepalive_cmd(ar->arWmi);
-            ar->arKeepaliveConfigured = 0xFF;
-            if (wmi_get_keepalive_configured(ar->arWmi) != 0){
-                up(&ar->arSem);
-                ret = -EIO;
-                goto ioctl_done;
-            }
-            wait_event_interruptible_timeout(arEvent, ar->arKeepaliveConfigured != 0xFF, wmitimeout * HZ);
-            if (signal_pending(current)) {
-                ret = -EINTR;
-            }
-
-            if (!ret) {
-                getKeepAlive.configured = ar->arKeepaliveConfigured;
-            }
-            if (copy_to_user(userdata, &getKeepAlive, sizeof(getKeepAlive))) {
-               ret = -EFAULT;
-            }
-            up(&ar->arSem);
-            }
-            break;
-        }
-        case AR6000_XIOCTL_WMI_SET_APPIE:
-        {
-            WMI_SET_APPIE_CMD appIEcmd;
-            u8 appIeInfo[IEEE80211_APPIE_FRAME_MAX_LEN];
-            u32 fType,ieLen;
-
-            if (ar->arWmiReady == false) {
-                ret = -EIO;
-                goto ioctl_done;
-            }
-	    if (get_user(fType, (u32 *)userdata)) {
-		ret = -EFAULT;
-		break;
-	    }
-            appIEcmd.mgmtFrmType = fType;
-            if (appIEcmd.mgmtFrmType >= IEEE80211_APPIE_NUM_OF_FRAME) {
-                ret = -EIO;
-            } else {
-		if (get_user(ieLen, (u32 *)(userdata + 4))) {
-		    ret = -EFAULT;
-		    break;
-		}
-                appIEcmd.ieLen = ieLen;
-                A_PRINTF("WPSIE: Type-%d, Len-%d\n",appIEcmd.mgmtFrmType, appIEcmd.ieLen);
-                if (appIEcmd.ieLen > IEEE80211_APPIE_FRAME_MAX_LEN) {
-                    ret = -EIO;
-                    break;
-                }
-                if (copy_from_user(appIeInfo, userdata + 8, appIEcmd.ieLen)) {
-                    ret = -EFAULT;
-                } else {
-                    if (wmi_set_appie_cmd(ar->arWmi, appIEcmd.mgmtFrmType,
-                                          appIEcmd.ieLen,  appIeInfo) != 0)
-                    {
-                        ret = -EIO;
-                    }
-                }
-            }
-            break;
-        }
-        case AR6000_XIOCTL_WMI_SET_MGMT_FRM_RX_FILTER:
-        {
-            WMI_BSS_FILTER_CMD cmd;
-            u32 filterType;
-
-            if (copy_from_user(&filterType, userdata, sizeof(u32)))
-            {
-                ret = -EFAULT;
-                goto ioctl_done;
-            }
-            if (filterType & (IEEE80211_FILTER_TYPE_BEACON |
-                                    IEEE80211_FILTER_TYPE_PROBE_RESP))
-            {
-                cmd.bssFilter = ALL_BSS_FILTER;
-            } else {
-                cmd.bssFilter = NONE_BSS_FILTER;
-            }
-            if (wmi_bssfilter_cmd(ar->arWmi, cmd.bssFilter, 0) != 0) {
-                ret = -EIO;
-            } else {
-                ar->arUserBssFilter = cmd.bssFilter;
-            }
-
-            AR6000_SPIN_LOCK(&ar->arLock, 0);
-            ar->arMgmtFilter = filterType;
-            AR6000_SPIN_UNLOCK(&ar->arLock, 0);
-            break;
-        }
-        case AR6000_XIOCTL_WMI_SET_WSC_STATUS:
-        {
-            u32 wsc_status;
-
-            if (ar->arWmiReady == false) {
-                ret = -EIO;
-                goto ioctl_done;
-            } else if (copy_from_user(&wsc_status, userdata, sizeof(u32)))
-            {
-                ret = -EFAULT;
-                goto ioctl_done;
-            }
-            if (wmi_set_wsc_status_cmd(ar->arWmi, wsc_status) != 0) {
-                ret = -EIO;
-            }
-            break;
-        }
-        case AR6000_XIOCTL_BMI_ROMPATCH_INSTALL:
-        {
-            u32 ROM_addr;
-            u32 RAM_addr;
-            u32 nbytes;
-            u32 do_activate;
-            u32 rompatch_id;
-
-	    if (get_user(ROM_addr, (u32 *)userdata) ||
-		get_user(RAM_addr, (u32 *)userdata + 1) ||
-		get_user(nbytes, (u32 *)userdata + 2) ||
-		get_user(do_activate, (u32 *)userdata + 3)) {
-		ret = -EFAULT;
-		break;
-	    }
-            AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("Install rompatch from ROM: 0x%x to RAM: 0x%x  length: %d\n",
-                             ROM_addr, RAM_addr, nbytes));
-            ret = BMIrompatchInstall(hifDevice, ROM_addr, RAM_addr,
-                                        nbytes, do_activate, &rompatch_id);
-            if (ret == 0) {
-		/* return value */
-		if (put_user(rompatch_id, (unsigned int *)rq->ifr_data)) {
-		    ret = -EFAULT;
-		    break;
-		}
-            }
-            break;
-        }
-
-        case AR6000_XIOCTL_BMI_ROMPATCH_UNINSTALL:
-        {
-            u32 rompatch_id;
-
-	    if (get_user(rompatch_id, (u32 *)userdata)) {
-		ret = -EFAULT;
-		break;
-	    }
-            AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("UNinstall rompatch_id %d\n", rompatch_id));
-            ret = BMIrompatchUninstall(hifDevice, rompatch_id);
-            break;
-        }
-
-        case AR6000_XIOCTL_BMI_ROMPATCH_ACTIVATE:
-        case AR6000_XIOCTL_BMI_ROMPATCH_DEACTIVATE:
-        {
-            u32 rompatch_count;
-
-	    if (get_user(rompatch_count, (u32 *)userdata)) {
-		ret = -EFAULT;
-		break;
-	    }
-            AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("Change rompatch activation count=%d\n", rompatch_count));
-            length = sizeof(u32) * rompatch_count;
-            if ((buffer = (unsigned char *)A_MALLOC(length)) != NULL) {
-                A_MEMZERO(buffer, length);
-                if (copy_from_user(buffer, &userdata[sizeof(rompatch_count)], length))
-                {
-                    ret = -EFAULT;
-                } else {
-                    if (cmd == AR6000_XIOCTL_BMI_ROMPATCH_ACTIVATE) {
-                        ret = BMIrompatchActivate(hifDevice, rompatch_count, (u32 *)buffer);
-                    } else {
-                        ret = BMIrompatchDeactivate(hifDevice, rompatch_count, (u32 *)buffer);
-                    }
-                }
-                A_FREE(buffer);
-            } else {
-                ret = -ENOMEM;
-            }
-
-            break;
-        }
-        case AR6000_XIOCTL_SET_IP:
-        {
-            WMI_SET_IP_CMD setIP;
-
-            if (ar->arWmiReady == false) {
-                ret = -EIO;
-            } else if (copy_from_user(&setIP, userdata,
-                                      sizeof(setIP)))
-            {
-                ret = -EFAULT;
-            } else {
-                if (wmi_set_ip_cmd(ar->arWmi,
-                                &setIP) != 0)
-                {
-                    ret = -EIO;
-                }
-            }
-            break;
-        }
-
-        case AR6000_XIOCTL_WMI_SET_HOST_SLEEP_MODE:
-        {
-            WMI_SET_HOST_SLEEP_MODE_CMD setHostSleepMode;
-
-            if (ar->arWmiReady == false) {
-                ret = -EIO;
-            } else if (copy_from_user(&setHostSleepMode, userdata,
-                                      sizeof(setHostSleepMode)))
-            {
-                ret = -EFAULT;
-            } else {
-                if (wmi_set_host_sleep_mode_cmd(ar->arWmi,
-                                &setHostSleepMode) != 0)
-                {
-                    ret = -EIO;
-                }
-            }
-            break;
-        }
-        case AR6000_XIOCTL_WMI_SET_WOW_MODE:
-        {
-            WMI_SET_WOW_MODE_CMD setWowMode;
-
-            if (ar->arWmiReady == false) {
-                ret = -EIO;
-            } else if (copy_from_user(&setWowMode, userdata,
-                                      sizeof(setWowMode)))
-            {
-                ret = -EFAULT;
-            } else {
-                if (wmi_set_wow_mode_cmd(ar->arWmi,
-                                &setWowMode) != 0)
-                {
-                    ret = -EIO;
-                }
-            }
-            break;
-        }
-        case AR6000_XIOCTL_WMI_GET_WOW_LIST:
-        {
-            WMI_GET_WOW_LIST_CMD getWowList;
-
-            if (ar->arWmiReady == false) {
-                ret = -EIO;
-            } else if (copy_from_user(&getWowList, userdata,
-                                      sizeof(getWowList)))
-            {
-                ret = -EFAULT;
-            } else {
-                if (wmi_get_wow_list_cmd(ar->arWmi,
-                                &getWowList) != 0)
-                {
-                    ret = -EIO;
-                }
-            }
-            break;
-        }
-        case AR6000_XIOCTL_WMI_ADD_WOW_PATTERN:
-        {
-#define WOW_PATTERN_SIZE 64
-#define WOW_MASK_SIZE 64
-
-            WMI_ADD_WOW_PATTERN_CMD cmd;
-            u8 mask_data[WOW_PATTERN_SIZE]={0};
-            u8 pattern_data[WOW_PATTERN_SIZE]={0};
-
-            do {
-                if (ar->arWmiReady == false) {
-                    ret = -EIO;
-                    break;        
-                } 
-                if(copy_from_user(&cmd, userdata,
-                            sizeof(WMI_ADD_WOW_PATTERN_CMD))) 
-                {
-                    ret = -EFAULT;
-                    break;        
-                }
-                if (copy_from_user(pattern_data,
-                                      userdata + 3,
-                                      cmd.filter_size)) 
-                {
-                    ret = -EFAULT;
-                    break;        
-                }
-                if (copy_from_user(mask_data,
-                                  (userdata + 3 + cmd.filter_size),
-                                  cmd.filter_size))
-                {
-                    ret = -EFAULT;
-                    break;
-                }
-                if (wmi_add_wow_pattern_cmd(ar->arWmi,
-                            &cmd, pattern_data, mask_data, cmd.filter_size) != 0)
-                {
-                    ret = -EIO;
-                }
-            } while(false);
-#undef WOW_PATTERN_SIZE
-#undef WOW_MASK_SIZE
-            break;
-        }
-        case AR6000_XIOCTL_WMI_DEL_WOW_PATTERN:
-        {
-            WMI_DEL_WOW_PATTERN_CMD delWowPattern;
-
-            if (ar->arWmiReady == false) {
-                ret = -EIO;
-            } else if (copy_from_user(&delWowPattern, userdata,
-                                      sizeof(delWowPattern)))
-            {
-                ret = -EFAULT;
-            } else {
-                if (wmi_del_wow_pattern_cmd(ar->arWmi,
-                                &delWowPattern) != 0)
-                {
-                    ret = -EIO;
-                }
-            }
-            break;
-        }
-        case AR6000_XIOCTL_DUMP_HTC_CREDIT_STATE:
-            if (ar->arHtcTarget != NULL) {
-#ifdef ATH_DEBUG_MODULE
-                HTCDumpCreditStates(ar->arHtcTarget);
-#endif /* ATH_DEBUG_MODULE */
-#ifdef HTC_EP_STAT_PROFILING
-                {
-                    struct htc_endpoint_stats stats;
-                    int i;
-
-                    for (i = 0; i < 5; i++) {
-                        if (HTCGetEndpointStatistics(ar->arHtcTarget,
-                                                     i,
-                                                     HTC_EP_STAT_SAMPLE_AND_CLEAR,
-                                                     &stats)) {
-                            A_PRINTF(KERN_ALERT"------- Profiling Endpoint : %d \n", i);
-                            A_PRINTF(KERN_ALERT"TxCreditLowIndications : %d \n", stats.TxCreditLowIndications);
-                            A_PRINTF(KERN_ALERT"TxIssued : %d \n", stats.TxIssued);
-                            A_PRINTF(KERN_ALERT"TxDropped: %d \n", stats.TxDropped);
-                            A_PRINTF(KERN_ALERT"TxPacketsBundled : %d \n", stats.TxPacketsBundled);
-                            A_PRINTF(KERN_ALERT"TxBundles : %d \n", stats.TxBundles);
-                            A_PRINTF(KERN_ALERT"TxCreditRpts : %d \n", stats.TxCreditRpts);
-                            A_PRINTF(KERN_ALERT"TxCreditsRptsFromRx : %d \n", stats.TxCreditRptsFromRx);
-                            A_PRINTF(KERN_ALERT"TxCreditsRptsFromOther : %d \n", stats.TxCreditRptsFromOther);
-                            A_PRINTF(KERN_ALERT"TxCreditsRptsFromEp0 : %d \n", stats.TxCreditRptsFromEp0);
-                            A_PRINTF(KERN_ALERT"TxCreditsFromRx : %d \n", stats.TxCreditsFromRx);
-                            A_PRINTF(KERN_ALERT"TxCreditsFromOther : %d \n", stats.TxCreditsFromOther);
-                            A_PRINTF(KERN_ALERT"TxCreditsFromEp0 : %d \n", stats.TxCreditsFromEp0);
-                            A_PRINTF(KERN_ALERT"TxCreditsConsummed : %d \n", stats.TxCreditsConsummed);
-                            A_PRINTF(KERN_ALERT"TxCreditsReturned : %d \n", stats.TxCreditsReturned);
-                            A_PRINTF(KERN_ALERT"RxReceived : %d \n", stats.RxReceived);
-                            A_PRINTF(KERN_ALERT"RxPacketsBundled : %d \n", stats.RxPacketsBundled);
-                            A_PRINTF(KERN_ALERT"RxLookAheads : %d \n", stats.RxLookAheads);
-                            A_PRINTF(KERN_ALERT"RxBundleLookAheads : %d \n", stats.RxBundleLookAheads);
-                            A_PRINTF(KERN_ALERT"RxBundleIndFromHdr : %d \n", stats.RxBundleIndFromHdr);
-                            A_PRINTF(KERN_ALERT"RxAllocThreshHit : %d \n", stats.RxAllocThreshHit);
-                            A_PRINTF(KERN_ALERT"RxAllocThreshBytes : %d \n", stats.RxAllocThreshBytes);
-                            A_PRINTF(KERN_ALERT"---- \n");
-
-                        }
-            }
-                }
-#endif
-            }
-            break;
-        case AR6000_XIOCTL_TRAFFIC_ACTIVITY_CHANGE:
-            if (ar->arHtcTarget != NULL) {
-                struct ar6000_traffic_activity_change data;
-
-                if (copy_from_user(&data, userdata, sizeof(data)))
-                {
-                    ret = -EFAULT;
-                    goto ioctl_done;
-                }
-                    /* note, this is used for testing (mbox ping testing), indicate activity
-                     * change using the stream ID as the traffic class */
-                ar6000_indicate_tx_activity(ar,
-                                            (u8)data.StreamID,
-                                            data.Active ? true : false);
-            }
-            break;
-        case AR6000_XIOCTL_WMI_SET_CONNECT_CTRL_FLAGS:
-            if (ar->arWmiReady == false) {
-                ret = -EIO;
-            } else if (copy_from_user(&connectCtrlFlags, userdata,
-                                      sizeof(connectCtrlFlags)))
-            {
-                ret = -EFAULT;
-            } else {
-                ar->arConnectCtrlFlags = connectCtrlFlags;
-            }
-            break;
-        case AR6000_XIOCTL_WMI_SET_AKMP_PARAMS:
-            if (ar->arWmiReady == false) {
-                ret = -EIO;
-            } else if (copy_from_user(&akmpParams, userdata,
-                                      sizeof(WMI_SET_AKMP_PARAMS_CMD)))
-            {
-                ret = -EFAULT;
-            } else {
-                if (wmi_set_akmp_params_cmd(ar->arWmi, &akmpParams) != 0) {
-                    ret = -EIO;
-                }
-            }
-            break;
-        case AR6000_XIOCTL_WMI_SET_PMKID_LIST:
-            if (ar->arWmiReady == false) {
-                ret = -EIO;
-            } else {
-                if (copy_from_user(&pmkidInfo.numPMKID, userdata,
-                                      sizeof(pmkidInfo.numPMKID)))
-                {
-                    ret = -EFAULT;
-                    break;
-                }
-                if (copy_from_user(&pmkidInfo.pmkidList,
-                                   userdata + sizeof(pmkidInfo.numPMKID),
-                                   pmkidInfo.numPMKID * sizeof(WMI_PMKID)))
-                {
-                    ret = -EFAULT;
-                    break;
-                }
-                if (wmi_set_pmkid_list_cmd(ar->arWmi, &pmkidInfo) != 0) {
-                    ret = -EIO;
-                }
-            }
-            break;
-        case AR6000_XIOCTL_WMI_GET_PMKID_LIST:
-            if (ar->arWmiReady == false) {
-                ret = -EIO;
-            } else  {
-                if (wmi_get_pmkid_list_cmd(ar->arWmi) != 0) {
-                    ret = -EIO;
-                }
-            }
-            break;
-        case AR6000_XIOCTL_WMI_ABORT_SCAN:
-            if (ar->arWmiReady == false) {
-                ret = -EIO;
-            }
-            ret = wmi_abort_scan_cmd(ar->arWmi);
-            break;
-        case AR6000_XIOCTL_AP_HIDDEN_SSID:
-        {
-            u8 hidden_ssid;
-            if (ar->arWmiReady == false) {
-                ret = -EIO;
-            } else if (copy_from_user(&hidden_ssid, userdata, sizeof(hidden_ssid))) {
-                ret = -EFAULT;
-            } else {
-                wmi_ap_set_hidden_ssid(ar->arWmi, hidden_ssid);
-                ar->ap_hidden_ssid = hidden_ssid;
-                ar->ap_profile_flag = 1; /* There is a change in profile */
-            }
-            break;
-        }
-        case AR6000_XIOCTL_AP_GET_STA_LIST:
-        {
-            if (ar->arWmiReady == false) {
-                ret = -EIO;
-            } else {
-                u8 i;
-                ap_get_sta_t temp;
-                A_MEMZERO(&temp, sizeof(temp));
-                for(i=0;i<AP_MAX_NUM_STA;i++) {
-                    memcpy(temp.sta[i].mac, ar->sta_list[i].mac, ATH_MAC_LEN);
-                    temp.sta[i].aid = ar->sta_list[i].aid;
-                    temp.sta[i].keymgmt = ar->sta_list[i].keymgmt;
-                    temp.sta[i].ucipher = ar->sta_list[i].ucipher;
-                    temp.sta[i].auth = ar->sta_list[i].auth;
-                }
-                if(copy_to_user((ap_get_sta_t *)rq->ifr_data, &temp,
-                                 sizeof(ar->sta_list))) {
-                    ret = -EFAULT;
-                }
-            }
-            break;
-        }
-        case AR6000_XIOCTL_AP_SET_NUM_STA:
-        {
-            u8 num_sta;
-            if (ar->arWmiReady == false) {
-                ret = -EIO;
-            } else if (copy_from_user(&num_sta, userdata, sizeof(num_sta))) {
-                ret = -EFAULT;
-            } else if(num_sta > AP_MAX_NUM_STA) {
-                /* value out of range */
-                ret = -EINVAL;
-            } else {
-                wmi_ap_set_num_sta(ar->arWmi, num_sta);
-            }
-            break;
-        }
-        case AR6000_XIOCTL_AP_SET_ACL_POLICY:
-        {
-            u8 policy;
-            if (ar->arWmiReady == false) {
-                ret = -EIO;
-            } else if (copy_from_user(&policy, userdata, sizeof(policy))) {
-                ret = -EFAULT;
-            } else if(policy == ar->g_acl.policy) {
-                /* No change in policy */
-            } else {
-                if(!(policy & AP_ACL_RETAIN_LIST_MASK)) {
-                    /* clear ACL list */
-                    memset(&ar->g_acl,0,sizeof(WMI_AP_ACL));
-                }
-                ar->g_acl.policy = policy;
-                wmi_ap_set_acl_policy(ar->arWmi, policy);
-            }
-            break;
-        }
-        case AR6000_XIOCTL_AP_SET_ACL_MAC:
-        {
-            WMI_AP_ACL_MAC_CMD    acl;
-            if (ar->arWmiReady == false) {
-                ret = -EIO;
-            } else if (copy_from_user(&acl, userdata, sizeof(acl))) {
-                ret = -EFAULT;
-            } else {
-                if(acl_add_del_mac(&ar->g_acl, &acl)) {
-                    wmi_ap_acl_mac_list(ar->arWmi, &acl);
-                } else {
-                    A_PRINTF("ACL list error\n");
-                    ret = -EIO;
-                }
-            }
-            break;
-        }
-        case AR6000_XIOCTL_AP_GET_ACL_LIST:
-        {
-            if (ar->arWmiReady == false) {
-                ret = -EIO;
-            } else if(copy_to_user((WMI_AP_ACL *)rq->ifr_data, &ar->g_acl,
-                                 sizeof(WMI_AP_ACL))) {
-                    ret = -EFAULT;
-            }
-            break;
-        }
-        case AR6000_XIOCTL_AP_COMMIT_CONFIG:
-        {
-            ret = ar6000_ap_mode_profile_commit(ar);
-            break;
-        }
-        case IEEE80211_IOCTL_GETWPAIE:
-        {
-            struct ieee80211req_wpaie wpaie;
-            if (ar->arWmiReady == false) {
-                ret = -EIO;
-            } else if (copy_from_user(&wpaie, userdata, sizeof(wpaie))) {
-                ret = -EFAULT;
-            } else if (ar6000_ap_mode_get_wpa_ie(ar, &wpaie)) {
-                ret = -EFAULT;
-            } else if(copy_to_user(userdata, &wpaie, sizeof(wpaie))) {
-                ret = -EFAULT;
-            }
-            break;
-        }
-        case AR6000_XIOCTL_AP_CONN_INACT_TIME:
-        {
-            u32 period;
-            if (ar->arWmiReady == false) {
-                ret = -EIO;
-            } else if (copy_from_user(&period, userdata, sizeof(period))) {
-                ret = -EFAULT;
-            } else {
-                wmi_ap_conn_inact_time(ar->arWmi, period);
-            }
-            break;
-        }
-        case AR6000_XIOCTL_AP_PROT_SCAN_TIME:
-        {
-            WMI_AP_PROT_SCAN_TIME_CMD  bgscan;
-            if (ar->arWmiReady == false) {
-                ret = -EIO;
-            } else if (copy_from_user(&bgscan, userdata, sizeof(bgscan))) {
-                ret = -EFAULT;
-            } else {
-                wmi_ap_bgscan_time(ar->arWmi, bgscan.period_min, bgscan.dwell_ms);
-            }
-            break;
-        }
-        case AR6000_XIOCTL_AP_SET_COUNTRY:
-        {
-            ret = ar6000_ioctl_set_country(dev, rq);
-            break;
-        }
-        case AR6000_XIOCTL_AP_SET_DTIM:
-        {
-            WMI_AP_SET_DTIM_CMD  d;
-            if (ar->arWmiReady == false) {
-                ret = -EIO;
-            } else if (copy_from_user(&d, userdata, sizeof(d))) {
-                ret = -EFAULT;
-            } else {
-                if(d.dtim > 0 && d.dtim < 11) {
-                    ar->ap_dtim_period = d.dtim;
-                    wmi_ap_set_dtim(ar->arWmi, d.dtim);
-                    ar->ap_profile_flag = 1; /* There is a change in profile */
-                } else {
-                    A_PRINTF("DTIM out of range. Valid range is [1-10]\n");
-                    ret = -EIO;
-                }
-            }
-            break;
-        }
-        case AR6000_XIOCTL_WMI_TARGET_EVENT_REPORT:
-        {
-            WMI_SET_TARGET_EVENT_REPORT_CMD evtCfgCmd;
-
-            if (ar->arWmiReady == false) {
-                ret = -EIO;
-            }
-            if (copy_from_user(&evtCfgCmd, userdata,
-                               sizeof(evtCfgCmd))) {
-                ret = -EFAULT;
-                break;
-            }
-            ret = wmi_set_target_event_report_cmd(ar->arWmi, &evtCfgCmd);
-            break;
-        }
-        case AR6000_XIOCTL_AP_INTRA_BSS_COMM:
-        {
-            u8 intra=0;
-            if (ar->arWmiReady == false) {
-                ret = -EIO;
-            } else if (copy_from_user(&intra, userdata, sizeof(intra))) {
-                ret = -EFAULT;
-            } else {
-                ar->intra_bss = (intra?1:0);
-            }
-            break;
-        }
-        case AR6000_XIOCTL_DUMP_MODULE_DEBUG_INFO:
-        {
-            struct drv_debug_module_s moduleinfo;
-
-            if (copy_from_user(&moduleinfo, userdata, sizeof(moduleinfo))) {
-                ret = -EFAULT;
-                break;
-            }
-
-            a_dump_module_debug_info_by_name(moduleinfo.modulename);
-            ret = 0;
-            break;
-        }
-        case AR6000_XIOCTL_MODULE_DEBUG_SET_MASK:
-        {
-            struct drv_debug_module_s moduleinfo;
-
-            if (copy_from_user(&moduleinfo, userdata, sizeof(moduleinfo))) {
-                ret = -EFAULT;
-                break;
-            }
-
-            if (a_set_module_mask(moduleinfo.modulename, moduleinfo.mask)) {
-                ret = -EFAULT;
-            }
-
-            break;
-        }
-        case AR6000_XIOCTL_MODULE_DEBUG_GET_MASK:
-        {
-            struct drv_debug_module_s moduleinfo;
-
-            if (copy_from_user(&moduleinfo, userdata, sizeof(moduleinfo))) {
-                ret = -EFAULT;
-                break;
-            }
-
-            if (a_get_module_mask(moduleinfo.modulename, &moduleinfo.mask)) {
-                ret = -EFAULT;
-                break;
-            }
-
-            if (copy_to_user(userdata, &moduleinfo, sizeof(moduleinfo))) {
-                ret = -EFAULT;
-                break;
-            }
-
-            break;
-        }
-#ifdef ATH_AR6K_11N_SUPPORT
-        case AR6000_XIOCTL_DUMP_RCV_AGGR_STATS:
-        {
-            PACKET_LOG *copy_of_pkt_log;
-
-            aggr_dump_stats(ar->aggr_cntxt, &copy_of_pkt_log);
-            if (copy_to_user(rq->ifr_data, copy_of_pkt_log, sizeof(PACKET_LOG))) {
-                ret = -EFAULT;
-            }
-            break;
-        }
-        case AR6000_XIOCTL_SETUP_AGGR:
-        {
-            WMI_ADDBA_REQ_CMD cmd;
-
-            if (ar->arWmiReady == false) {
-                ret = -EIO;
-            } else if (copy_from_user(&cmd, userdata, sizeof(cmd))) {
-                ret = -EFAULT;
-            } else {
-                wmi_setup_aggr_cmd(ar->arWmi, cmd.tid);
-            }
-        }
-        break;
-
-        case AR6000_XIOCTL_DELE_AGGR:
-        {
-            WMI_DELBA_REQ_CMD cmd;
-
-            if (ar->arWmiReady == false) {
-                ret = -EIO;
-            } else if (copy_from_user(&cmd, userdata, sizeof(cmd))) {
-                ret = -EFAULT;
-            } else {
-                wmi_delete_aggr_cmd(ar->arWmi, cmd.tid, cmd.is_sender_initiator);
-            }
-        }
-        break;
-
-        case AR6000_XIOCTL_ALLOW_AGGR:
-        {
-            WMI_ALLOW_AGGR_CMD cmd;
-
-            if (ar->arWmiReady == false) {
-                ret = -EIO;
-            } else if (copy_from_user(&cmd, userdata, sizeof(cmd))) {
-                ret = -EFAULT;
-            } else {
-                wmi_allow_aggr_cmd(ar->arWmi, cmd.tx_allow_aggr, cmd.rx_allow_aggr);
-            }
-        }
-        break;
-
-        case AR6000_XIOCTL_SET_HT_CAP:
-        {
-            if (ar->arWmiReady == false) {
-                ret = -EIO;
-            } else if (copy_from_user(&htCap, userdata,
-                                      sizeof(htCap)))
-            {
-                ret = -EFAULT;
-            } else {
-
-                if (wmi_set_ht_cap_cmd(ar->arWmi, &htCap) != 0)
-                {
-                    ret = -EIO;
-                }
-            }
-            break;
-        }
-        case AR6000_XIOCTL_SET_HT_OP:
-        {
-             if (ar->arWmiReady == false) {
-                ret = -EIO;
-            } else if (copy_from_user(&htOp, userdata,
-                                      sizeof(htOp)))
-            {
-                 ret = -EFAULT;
-             } else {
-
-                if (wmi_set_ht_op_cmd(ar->arWmi, htOp.sta_chan_width) != 0)
-                {
-                     ret = -EIO;
-               }
-             }
-             break;
-        }
-#endif
-        case AR6000_XIOCTL_ACL_DATA:
-        {
-            void *osbuf = NULL;
-            if (ar->arWmiReady == false) {
-                ret = -EIO;
-            } else if (ar6000_create_acl_data_osbuf(dev, (u8 *)userdata, &osbuf) != 0) {
-                     ret = -EIO;
-            } else {
-                if (wmi_data_hdr_add(ar->arWmi, osbuf, DATA_MSGTYPE, 0, WMI_DATA_HDR_DATA_TYPE_ACL,0,NULL) != 0) {
-                    AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("XIOCTL_ACL_DATA - wmi_data_hdr_add failed\n"));
-                } else {
-                    /* Send data buffer over HTC */
-                    ar6000_acl_data_tx(osbuf, ar->arNetDev);
-                }
-            }
-            break;
-        }
-        case AR6000_XIOCTL_HCI_CMD:
-        {
-            char tmp_buf[512];
-            s8 i;
-            WMI_HCI_CMD *cmd = (WMI_HCI_CMD *)tmp_buf;
-            u8 size;
-
-            size = sizeof(cmd->cmd_buf_sz);
-            if (ar->arWmiReady == false) {
-                ret = -EIO;
-            } else if (copy_from_user(cmd, userdata, size)) {
-                 ret = -EFAULT;
-            } else if(copy_from_user(cmd->buf, userdata + size, cmd->cmd_buf_sz)) {
-                    ret = -EFAULT;
-            } else {
-                if (wmi_send_hci_cmd(ar->arWmi, cmd->buf, cmd->cmd_buf_sz) != 0) {
-                     ret = -EIO;
-                }else if(loghci) {
-                    A_PRINTF_LOG("HCI Command To PAL --> \n");
-                    for(i = 0; i < cmd->cmd_buf_sz; i++) {
-                        A_PRINTF_LOG("0x%02x ",cmd->buf[i]);
-                        if((i % 10) == 0) {
-                            A_PRINTF_LOG("\n");
-                        }
-                    }
-                    A_PRINTF_LOG("\n");
-                    A_PRINTF_LOG("==================================\n");
-                }
-            }
-            break;
-        }
-        case AR6000_XIOCTL_WLAN_CONN_PRECEDENCE:
-        {
-            WMI_SET_BT_WLAN_CONN_PRECEDENCE cmd;
-            if (ar->arWmiReady == false) {
-                ret = -EIO;
-            } else if (copy_from_user(&cmd, userdata, sizeof(cmd))) {
-                ret = -EFAULT;
-            } else {
-                if (cmd.precedence == BT_WLAN_CONN_PRECDENCE_WLAN ||
-                            cmd.precedence == BT_WLAN_CONN_PRECDENCE_PAL) {
-                    if ( wmi_set_wlan_conn_precedence_cmd(ar->arWmi, cmd.precedence) != 0) {
-                        ret = -EIO;
-                    }
-                } else {
-                    ret = -EINVAL;
-                }
-            }
-            break;
-        }
-        case AR6000_XIOCTL_AP_GET_STAT:
-        {
-            ret = ar6000_ioctl_get_ap_stats(dev, rq);
-            break;
-        }
-        case AR6000_XIOCTL_SET_TX_SELECT_RATES:
-        {
-            WMI_SET_TX_SELECT_RATES_CMD masks;
-
-             if (ar->arWmiReady == false) {
-                ret = -EIO;
-            } else if (copy_from_user(&masks, userdata,
-                                      sizeof(masks)))
-            {
-                 ret = -EFAULT;
-             } else {
-
-                if (wmi_set_tx_select_rates_cmd(ar->arWmi, masks.rateMasks) != 0)
-                {
-                     ret = -EIO;
-               }
-             }
-             break;
-        }
-        case AR6000_XIOCTL_AP_GET_HIDDEN_SSID:
-        {
-            WMI_AP_HIDDEN_SSID_CMD ssid;
-            ssid.hidden_ssid = ar->ap_hidden_ssid;
-
-            if (ar->arWmiReady == false) {
-                ret = -EIO;
-            } else if(copy_to_user((WMI_AP_HIDDEN_SSID_CMD *)rq->ifr_data,
-                                    &ssid, sizeof(WMI_AP_HIDDEN_SSID_CMD))) {
-                    ret = -EFAULT;
-            }
-            break;
-        }
-        case AR6000_XIOCTL_AP_GET_COUNTRY:
-        {
-            WMI_AP_SET_COUNTRY_CMD cty;
-            memcpy(cty.countryCode, ar->ap_country_code, 3);
-
-            if (ar->arWmiReady == false) {
-                ret = -EIO;
-            } else if(copy_to_user((WMI_AP_SET_COUNTRY_CMD *)rq->ifr_data,
-                                    &cty, sizeof(WMI_AP_SET_COUNTRY_CMD))) {
-                    ret = -EFAULT;
-            }
-            break;
-        }
-        case AR6000_XIOCTL_AP_GET_WMODE:
-        {
-            if (ar->arWmiReady == false) {
-                ret = -EIO;
-            } else if(copy_to_user((u8 *)rq->ifr_data,
-                                    &ar->ap_wmode, sizeof(u8))) {
-                    ret = -EFAULT;
-            }
-            break;
-        }
-        case AR6000_XIOCTL_AP_GET_DTIM:
-        {
-            WMI_AP_SET_DTIM_CMD dtim;
-            dtim.dtim = ar->ap_dtim_period;
-
-            if (ar->arWmiReady == false) {
-                ret = -EIO;
-            } else if(copy_to_user((WMI_AP_SET_DTIM_CMD *)rq->ifr_data,
-                                    &dtim, sizeof(WMI_AP_SET_DTIM_CMD))) {
-                    ret = -EFAULT;
-            }
-            break;
-        }
-        case AR6000_XIOCTL_AP_GET_BINTVL:
-        {
-            WMI_BEACON_INT_CMD bi;
-            bi.beaconInterval = ar->ap_beacon_interval;
-
-            if (ar->arWmiReady == false) {
-                ret = -EIO;
-            } else if(copy_to_user((WMI_BEACON_INT_CMD *)rq->ifr_data,
-                                    &bi, sizeof(WMI_BEACON_INT_CMD))) {
-                    ret = -EFAULT;
-            }
-            break;
-        }
-        case AR6000_XIOCTL_AP_GET_RTS:
-        {
-            WMI_SET_RTS_CMD rts;
-            rts.threshold = ar->arRTS;
-	     
-            if (ar->arWmiReady == false) {
-                ret = -EIO;
-            } else if(copy_to_user((WMI_SET_RTS_CMD *)rq->ifr_data,
-                                    &rts, sizeof(WMI_SET_RTS_CMD))) {
-                    ret = -EFAULT;
-            }
-            break;
-        }
-        case AR6000_XIOCTL_FETCH_TARGET_REGS:
-        {
-            u32 targregs[AR6003_FETCH_TARG_REGS_COUNT];
-
-            if (ar->arTargetType == TARGET_TYPE_AR6003) {
-                ar6k_FetchTargetRegs(hifDevice, targregs);
-                if (copy_to_user((u32 *)rq->ifr_data, &targregs, sizeof(targregs)))
-                {
-                    ret = -EFAULT;
-                }
-            } else {
-                ret = -EOPNOTSUPP;
-            }
-            break;
-        }
-        case AR6000_XIOCTL_AP_SET_11BG_RATESET:
-        {
-            WMI_AP_SET_11BG_RATESET_CMD  rate;
-            if (ar->arWmiReady == false) {
-                ret = -EIO;
-            } else if (copy_from_user(&rate, userdata, sizeof(rate))) {
-                ret = -EFAULT;
-            } else {
-                wmi_ap_set_rateset(ar->arWmi, rate.rateset);
-            }
-            break;
-        }
-        case AR6000_XIOCTL_GET_WLAN_SLEEP_STATE:
-        {
-            WMI_REPORT_SLEEP_STATE_EVENT  wmiSleepEvent ;
-
-            if (ar->arWlanState == WLAN_ENABLED) {
-                wmiSleepEvent.sleepState = WMI_REPORT_SLEEP_STATUS_IS_AWAKE;
-            } else {
-                wmiSleepEvent.sleepState = WMI_REPORT_SLEEP_STATUS_IS_DEEP_SLEEP;
-            }
-            rq->ifr_ifru.ifru_ivalue = ar->arWlanState; /* return value */
-
-            ar6000_send_event_to_app(ar, WMI_REPORT_SLEEP_STATE_EVENTID, (u8 *)&wmiSleepEvent,
-                                     sizeof(WMI_REPORT_SLEEP_STATE_EVENTID));
-            break;
-        }
-#ifdef CONFIG_PM
-        case AR6000_XIOCTL_SET_BT_HW_POWER_STATE:
-        {
-            unsigned int state;
-	    if (get_user(state, (unsigned int *)userdata)) {
-		ret = -EFAULT;
-		break;
-	    }
-            if (ar6000_set_bt_hw_state(ar, state)!= 0) {
-                ret = -EIO;
-            }       
-        }
-            break;
-        case AR6000_XIOCTL_GET_BT_HW_POWER_STATE:
-            rq->ifr_ifru.ifru_ivalue = !ar->arBTOff; /* return value */
-            break;
-#endif
-
-        case AR6000_XIOCTL_WMI_SET_TX_SGI_PARAM:
-        {
-             WMI_SET_TX_SGI_PARAM_CMD SGICmd;
-
-             if (ar->arWmiReady == false) {
-                 ret = -EIO;
-             } else if (copy_from_user(&SGICmd, userdata,
-                                       sizeof(SGICmd))){
-                 ret = -EFAULT;
-             } else{
-                     if (wmi_SGI_cmd(ar->arWmi, SGICmd.sgiMask, SGICmd.sgiPERThreshold) != 0) {
-                         ret = -EIO;
-                     }
-
-             }
-             break;
-        }
-
-        case AR6000_XIOCTL_ADD_AP_INTERFACE:
-#ifdef CONFIG_AP_VIRTUAL_ADAPTER_SUPPORT
-        {
-            char ap_ifname[IFNAMSIZ] = {0,};
-            if (copy_from_user(ap_ifname, userdata, IFNAMSIZ)) {
-                ret = -EFAULT;
-            } else {
-                if (ar6000_add_ap_interface(ar, ap_ifname) != 0) {
-                    ret = -EIO;
-                } 
-            }
-        }
-#else
-            ret = -EOPNOTSUPP;
-#endif
-            break;
-        case AR6000_XIOCTL_REMOVE_AP_INTERFACE:
-#ifdef CONFIG_AP_VIRTUAL_ADAPTER_SUPPORT
-            if (ar6000_remove_ap_interface(ar) != 0) {
-                ret = -EIO;
-            } 
-#else
-            ret = -EOPNOTSUPP;
-#endif
-            break;
-
-        case AR6000_XIOCTL_WMI_SET_EXCESS_TX_RETRY_THRES:
-        {
-            ret = ar6000_xioctl_set_excess_tx_retry_thres_cmd(dev, userdata);
-            break;
-        }
-
-        default:
-            ret = -EOPNOTSUPP;
-    }
-
-ioctl_done:
-    rtnl_lock(); /* restore rtnl state */
-    dev_put(dev);
-
-    return ret;
-}
-
-u8 mac_cmp_wild(u8 *mac, u8 *new_mac, u8 wild, u8 new_wild)
-{
-    u8 i;
-
-    for(i=0;i<ATH_MAC_LEN;i++) {
-        if((wild & 1<<i) && (new_wild & 1<<i)) continue;
-        if(mac[i] != new_mac[i]) return 1;
-    }
-    if((memcmp(new_mac, null_mac, 6)==0) && new_wild &&
-        (wild != new_wild)) {
-        return 1;
-    }
-
-    return 0;
-}
-
-u8 acl_add_del_mac(WMI_AP_ACL *a, WMI_AP_ACL_MAC_CMD *acl)
-{
-    s8 already_avail=-1, free_slot=-1, i;
-
-    /* To check whether this mac is already there in our list */
-    for(i=AP_ACL_SIZE-1;i>=0;i--)
-    {
-        if(mac_cmp_wild(a->acl_mac[i], acl->mac, a->wildcard[i],
-            acl->wildcard)==0)
-                already_avail = i;
-
-        if(!((1 << i) & a->index))
-            free_slot = i;
-    }
-
-    if(acl->action == ADD_MAC_ADDR)
-    {
-        /* Dont add mac if it is already available */
-        if((already_avail >= 0) || (free_slot == -1))
-            return 0;
-
-        memcpy(a->acl_mac[free_slot], acl->mac, ATH_MAC_LEN);
-        a->index = a->index | (1 << free_slot);
-        acl->index = free_slot;
-        a->wildcard[free_slot] = acl->wildcard;
-        return 1;
-    }
-    else if(acl->action == DEL_MAC_ADDR)
-    {
-        if(acl->index > AP_ACL_SIZE)
-            return 0;
-
-        if(!(a->index & (1 << acl->index)))
-            return 0;
-
-        A_MEMZERO(a->acl_mac[acl->index],ATH_MAC_LEN);
-        a->index = a->index & ~(1 << acl->index);
-        a->wildcard[acl->index] = 0;
-        return 1;
-    }
-
-    return 0;
-}
diff -druN linux-2.6.39-libre/drivers/staging/ath6kl/os/linux/netbuf.c linux-3.0-rc7-libre/drivers/staging/ath6kl/os/linux/netbuf.c
--- linux-2.6.39-libre/drivers/staging/ath6kl/os/linux/netbuf.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/ath6kl/os/linux/netbuf.c	2011-07-11 19:51:52.000000000 -0400
@@ -22,7 +22,6 @@
 //------------------------------------------------------------------------------
 #include <a_config.h>
 #include "athdefs.h"
-#include "a_types.h"
 #include "a_osapi.h"
 #include "htc_packet.h"
 
diff -druN linux-2.6.39-libre/drivers/staging/ath6kl/os/linux/wireless_ext.c linux-3.0-rc7-libre/drivers/staging/ath6kl/os/linux/wireless_ext.c
--- linux-2.6.39-libre/drivers/staging/ath6kl/os/linux/wireless_ext.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/ath6kl/os/linux/wireless_ext.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,2723 +0,0 @@
-//------------------------------------------------------------------------------
-// Copyright (c) 2004-2010 Atheros Communications Inc.
-// All rights reserved.
-//
-// 
-//
-// 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.
-//
-//
-//
-// Author(s): ="Atheros"
-//------------------------------------------------------------------------------
-
-#include "ar6000_drv.h"
-
-#define IWE_STREAM_ADD_EVENT(p1, p2, p3, p4, p5) \
-    iwe_stream_add_event((p1), (p2), (p3), (p4), (p5))
-
-#define IWE_STREAM_ADD_POINT(p1, p2, p3, p4, p5) \
-    iwe_stream_add_point((p1), (p2), (p3), (p4), (p5))
-
-#define IWE_STREAM_ADD_VALUE(p1, p2, p3, p4, p5, p6) \
-    iwe_stream_add_value((p1), (p2), (p3), (p4), (p5), (p6))
-
-static void ar6000_set_quality(struct iw_quality *iq, s8 rssi);
-extern unsigned int wmitimeout;
-extern A_WAITQUEUE_HEAD arEvent;
-
-#if WIRELESS_EXT > 14
-/*
- * Encode a WPA or RSN information element as a custom
- * element using the hostap format.
- */
-static u_int
-encode_ie(void *buf, size_t bufsize,
-    const u_int8_t *ie, size_t ielen,
-    const char *leader, size_t leader_len)
-{
-    u_int8_t *p;
-    int i;
-
-    if (bufsize < leader_len)
-        return 0;
-    p = buf;
-    memcpy(p, leader, leader_len);
-    bufsize -= leader_len;
-    p += leader_len;
-    for (i = 0; i < ielen && bufsize > 2; i++)
-    {
-        p += sprintf((char*)p, "%02x", ie[i]);
-        bufsize -= 2;
-    }
-    return (i == ielen ? p - (u_int8_t *)buf : 0);
-}
-#endif /* WIRELESS_EXT > 14 */
-
-static u8 get_bss_phy_capability(bss_t *bss)
-{
-    u8 capability = 0;
-    struct ieee80211_common_ie *cie = &bss->ni_cie;
-#define CHAN_IS_11A(x)              (!((x >= 2412) && (x <= 2484)))
-    if (CHAN_IS_11A(cie->ie_chan)) {
-        if (cie->ie_htcap) {
-            capability = WMI_11NA_CAPABILITY;
-        } else {
-            capability = WMI_11A_CAPABILITY;
-        }
-    } else if ((cie->ie_erp) || (cie->ie_xrates)) {
-        if (cie->ie_htcap) {
-            capability = WMI_11NG_CAPABILITY;
-        } else {
-            capability = WMI_11G_CAPABILITY;
-        }
-    }
-    return capability;
-}
-
-void
-ar6000_scan_node(void *arg, bss_t *ni)
-{
-    struct iw_event iwe;
-#if WIRELESS_EXT > 14
-    char buf[256];
-#endif
-    struct ar_giwscan_param *param;
-    char *current_ev;
-    char *end_buf;
-    struct ieee80211_common_ie  *cie;
-    char *current_val;
-    s32 j;
-    u32 rate_len, data_len = 0;
-
-    param = (struct ar_giwscan_param *)arg;
-
-    current_ev = param->current_ev;
-    end_buf = param->end_buf;
-
-    cie = &ni->ni_cie;
-
-    if ((end_buf - current_ev) > IW_EV_ADDR_LEN)
-    {
-        A_MEMZERO(&iwe, sizeof(iwe));
-        iwe.cmd = SIOCGIWAP;
-        iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
-        memcpy(iwe.u.ap_addr.sa_data, ni->ni_macaddr, 6);
-        current_ev = IWE_STREAM_ADD_EVENT(param->info, current_ev, end_buf,
-                                          &iwe, IW_EV_ADDR_LEN);
-    }
-    param->bytes_needed += IW_EV_ADDR_LEN;
-
-    data_len = cie->ie_ssid[1] + IW_EV_POINT_LEN;
-    if ((end_buf - current_ev) > data_len)
-    {
-        A_MEMZERO(&iwe, sizeof(iwe));
-        iwe.cmd = SIOCGIWESSID;
-        iwe.u.data.flags = 1;
-        iwe.u.data.length = cie->ie_ssid[1];
-        current_ev = IWE_STREAM_ADD_POINT(param->info, current_ev, end_buf,
-                                          &iwe, (char*)&cie->ie_ssid[2]);
-    }
-    param->bytes_needed += data_len;
-
-    if (cie->ie_capInfo & (IEEE80211_CAPINFO_ESS|IEEE80211_CAPINFO_IBSS)) {
-        if ((end_buf - current_ev) > IW_EV_UINT_LEN)
-        {
-            A_MEMZERO(&iwe, sizeof(iwe));
-            iwe.cmd = SIOCGIWMODE;
-            iwe.u.mode = cie->ie_capInfo & IEEE80211_CAPINFO_ESS ?
-                         IW_MODE_MASTER : IW_MODE_ADHOC;
-            current_ev = IWE_STREAM_ADD_EVENT(param->info, current_ev, end_buf,
-                                              &iwe, IW_EV_UINT_LEN);
-        }
-        param->bytes_needed += IW_EV_UINT_LEN;
-    }
-
-    if ((end_buf - current_ev) > IW_EV_FREQ_LEN)
-    {
-        A_MEMZERO(&iwe, sizeof(iwe));
-        iwe.cmd = SIOCGIWFREQ;
-        iwe.u.freq.m = cie->ie_chan * 100000;
-        iwe.u.freq.e = 1;
-        current_ev = IWE_STREAM_ADD_EVENT(param->info, current_ev, end_buf,
-                                          &iwe, IW_EV_FREQ_LEN);
-    }
-    param->bytes_needed += IW_EV_FREQ_LEN;
-
-    if ((end_buf - current_ev) > IW_EV_QUAL_LEN)
-    {
-        A_MEMZERO(&iwe, sizeof(iwe));
-        iwe.cmd = IWEVQUAL;
-        ar6000_set_quality(&iwe.u.qual, ni->ni_snr);
-        current_ev = IWE_STREAM_ADD_EVENT(param->info, current_ev, end_buf,
-                                          &iwe, IW_EV_QUAL_LEN);
-    }
-    param->bytes_needed += IW_EV_QUAL_LEN;
-
-    if ((end_buf - current_ev) > IW_EV_POINT_LEN)
-    {
-        A_MEMZERO(&iwe, sizeof(iwe));
-        iwe.cmd = SIOCGIWENCODE;
-        if (cie->ie_capInfo & IEEE80211_CAPINFO_PRIVACY) {
-            iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
-        } else {
-            iwe.u.data.flags = IW_ENCODE_DISABLED;
-        }
-        iwe.u.data.length = 0;
-        current_ev = IWE_STREAM_ADD_POINT(param->info, current_ev, end_buf,
-                                          &iwe, "");
-    }
-    param->bytes_needed += IW_EV_POINT_LEN;
-
-    /* supported bit rate */
-    A_MEMZERO(&iwe, sizeof(iwe));
-    iwe.cmd = SIOCGIWRATE;
-    iwe.u.bitrate.fixed = 0;
-    iwe.u.bitrate.disabled = 0;
-    iwe.u.bitrate.value = 0;
-    current_val = current_ev + IW_EV_LCP_LEN;
-    param->bytes_needed += IW_EV_LCP_LEN;
-
-    if (cie->ie_rates != NULL) {
-        rate_len = cie->ie_rates[1];
-        data_len = (rate_len * (IW_EV_PARAM_LEN - IW_EV_LCP_LEN));
-        if ((end_buf - current_ev) > data_len)
-        {
-            for (j = 0; j < rate_len; j++) {
-                    unsigned char val;
-                    val = cie->ie_rates[2 + j];
-                    iwe.u.bitrate.value =
-                        (val >= 0x80)? ((val - 0x80) * 500000): (val * 500000);
-                    current_val = IWE_STREAM_ADD_VALUE(param->info, current_ev,
-                                                       current_val, end_buf,
-                                                       &iwe, IW_EV_PARAM_LEN);
-            }
-        }
-        param->bytes_needed += data_len;
-    }
-
-    if (cie->ie_xrates != NULL) {
-        rate_len = cie->ie_xrates[1];
-        data_len = (rate_len * (IW_EV_PARAM_LEN - IW_EV_LCP_LEN));
-        if ((end_buf - current_ev) > data_len)
-        {
-            for (j = 0; j < rate_len; j++) {
-                    unsigned char val;
-                    val = cie->ie_xrates[2 + j];
-                    iwe.u.bitrate.value =
-                        (val >= 0x80)? ((val - 0x80) * 500000): (val * 500000);
-                    current_val = IWE_STREAM_ADD_VALUE(param->info, current_ev,
-                                                       current_val, end_buf,
-                                                       &iwe, IW_EV_PARAM_LEN);
-            }
-        }
-        param->bytes_needed += data_len;
-    }
-    /* remove fixed header if no rates were added */
-    if ((current_val - current_ev) > IW_EV_LCP_LEN)
-        current_ev = current_val;
-
-#if WIRELESS_EXT >= 18
-    /* IE */
-    if (cie->ie_wpa != NULL) {
-        data_len = cie->ie_wpa[1] + 2 + IW_EV_POINT_LEN;
-        if ((end_buf - current_ev) > data_len)
-        {
-            A_MEMZERO(&iwe, sizeof(iwe));
-            iwe.cmd = IWEVGENIE;
-            iwe.u.data.length = cie->ie_wpa[1] + 2;
-            current_ev = IWE_STREAM_ADD_POINT(param->info, current_ev, end_buf,
-                                              &iwe, (char*)cie->ie_wpa);
-        }
-        param->bytes_needed += data_len;
-    }
-
-    if (cie->ie_rsn != NULL && cie->ie_rsn[0] == IEEE80211_ELEMID_RSN) {
-        data_len = cie->ie_rsn[1] + 2 + IW_EV_POINT_LEN;
-        if ((end_buf - current_ev) > data_len)
-        {
-            A_MEMZERO(&iwe, sizeof(iwe));
-            iwe.cmd = IWEVGENIE;
-            iwe.u.data.length = cie->ie_rsn[1] + 2;
-            current_ev = IWE_STREAM_ADD_POINT(param->info, current_ev, end_buf,
-                                              &iwe, (char*)cie->ie_rsn);
-        }
-        param->bytes_needed += data_len;
-    }
-
-#endif /* WIRELESS_EXT >= 18 */
-
-    if ((end_buf - current_ev) > IW_EV_CHAR_LEN)
-    {
-        /* protocol */
-        A_MEMZERO(&iwe, sizeof(iwe));
-        iwe.cmd = SIOCGIWNAME;
-        switch (get_bss_phy_capability(ni)) {
-        case WMI_11A_CAPABILITY:
-            snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11a");
-            break;
-        case WMI_11G_CAPABILITY:
-            snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11g");
-            break;
-        case WMI_11NA_CAPABILITY:
-            snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11na");
-            break;
-        case WMI_11NG_CAPABILITY:
-            snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11ng");
-            break;
-        default:
-            snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11b");
-            break;
-        }
-        current_ev = IWE_STREAM_ADD_EVENT(param->info, current_ev, end_buf,
-                                          &iwe, IW_EV_CHAR_LEN);
-    }
-    param->bytes_needed += IW_EV_CHAR_LEN;
-
-#if WIRELESS_EXT > 14
-    A_MEMZERO(&iwe, sizeof(iwe));
-    iwe.cmd = IWEVCUSTOM;
-    iwe.u.data.length = snprintf(buf, sizeof(buf), "bcn_int=%d", cie->ie_beaconInt);
-    data_len = iwe.u.data.length + IW_EV_POINT_LEN;
-    if ((end_buf - current_ev) > data_len)
-    {
-        current_ev = IWE_STREAM_ADD_POINT(param->info, current_ev, end_buf,
-                                          &iwe, buf);
-    }
-    param->bytes_needed += data_len;
-
-#if WIRELESS_EXT < 18
-    if (cie->ie_wpa != NULL) {
-        static const char wpa_leader[] = "wpa_ie=";
-        data_len = (sizeof(wpa_leader) - 1) + ((cie->ie_wpa[1]+2) * 2) + IW_EV_POINT_LEN;
-        if ((end_buf - current_ev) > data_len)
-        {
-            A_MEMZERO(&iwe, sizeof(iwe));
-            iwe.cmd = IWEVCUSTOM;
-            iwe.u.data.length = encode_ie(buf, sizeof(buf), cie->ie_wpa,
-                                          cie->ie_wpa[1]+2,
-                                          wpa_leader, sizeof(wpa_leader)-1);
-
-            if (iwe.u.data.length != 0) {
-                current_ev = IWE_STREAM_ADD_POINT(param->info, current_ev, 
-                                                  end_buf, &iwe, buf);
-            }
-        }
-        param->bytes_needed += data_len;
-    }
-
-    if (cie->ie_rsn != NULL && cie->ie_rsn[0] == IEEE80211_ELEMID_RSN) {
-        static const char rsn_leader[] = "rsn_ie=";
-        data_len = (sizeof(rsn_leader) - 1) + ((cie->ie_rsn[1]+2) * 2) + IW_EV_POINT_LEN;
-        if ((end_buf - current_ev) > data_len)
-        {
-            A_MEMZERO(&iwe, sizeof(iwe));
-            iwe.cmd = IWEVCUSTOM;
-            iwe.u.data.length = encode_ie(buf, sizeof(buf), cie->ie_rsn,
-                                          cie->ie_rsn[1]+2,
-                                          rsn_leader, sizeof(rsn_leader)-1);
-
-            if (iwe.u.data.length != 0) {
-                current_ev = IWE_STREAM_ADD_POINT(param->info, current_ev, 
-                                                  end_buf, &iwe, buf);
-            }
-        }
-        param->bytes_needed += data_len;
-    }
-#endif /* WIRELESS_EXT < 18 */
-
-    if (cie->ie_wmm != NULL) {
-        static const char wmm_leader[] = "wmm_ie=";
-        data_len = (sizeof(wmm_leader) - 1) + ((cie->ie_wmm[1]+2) * 2) + IW_EV_POINT_LEN;
-        if ((end_buf - current_ev) > data_len)
-        {
-            A_MEMZERO(&iwe, sizeof(iwe));
-            iwe.cmd = IWEVCUSTOM;
-            iwe.u.data.length = encode_ie(buf, sizeof(buf), cie->ie_wmm,
-                                          cie->ie_wmm[1]+2,
-                                          wmm_leader, sizeof(wmm_leader)-1);
-            if (iwe.u.data.length != 0) {
-                current_ev = IWE_STREAM_ADD_POINT(param->info, current_ev,
-                                                  end_buf, &iwe, buf);
-            }
-        }
-        param->bytes_needed += data_len;
-    }
-
-    if (cie->ie_ath != NULL) {
-        static const char ath_leader[] = "ath_ie=";
-        data_len = (sizeof(ath_leader) - 1) + ((cie->ie_ath[1]+2) * 2) + IW_EV_POINT_LEN;
-        if ((end_buf - current_ev) > data_len)
-        {
-            A_MEMZERO(&iwe, sizeof(iwe));
-            iwe.cmd = IWEVCUSTOM;
-            iwe.u.data.length = encode_ie(buf, sizeof(buf), cie->ie_ath,
-                                          cie->ie_ath[1]+2,
-                                          ath_leader, sizeof(ath_leader)-1);
-            if (iwe.u.data.length != 0) {
-                current_ev = IWE_STREAM_ADD_POINT(param->info, current_ev,
-                                                  end_buf, &iwe, buf);
-            }
-        }
-        param->bytes_needed += data_len;
-    }
-
-#ifdef WAPI_ENABLE
-    if (cie->ie_wapi != NULL) {
-        static const char wapi_leader[] = "wapi_ie=";
-        data_len = (sizeof(wapi_leader) - 1) + ((cie->ie_wapi[1] + 2) * 2) + IW_EV_POINT_LEN;
-        if ((end_buf - current_ev) > data_len) {
-            A_MEMZERO(&iwe, sizeof(iwe));
-            iwe.cmd = IWEVCUSTOM;
-            iwe.u.data.length = encode_ie(buf, sizeof(buf), cie->ie_wapi,
-                                      cie->ie_wapi[1] + 2,
-                                      wapi_leader, sizeof(wapi_leader) - 1);
-            if (iwe.u.data.length != 0) {
-                current_ev = IWE_STREAM_ADD_POINT(param->info, current_ev,
-                                                  end_buf, &iwe, buf);
-            }
-        }
-        param->bytes_needed += data_len;
-    }
-#endif /* WAPI_ENABLE */
-
-#endif /* WIRELESS_EXT > 14 */
-
-#if WIRELESS_EXT >= 18
-    if (cie->ie_wsc != NULL) {
-        data_len = (cie->ie_wsc[1] + 2) + IW_EV_POINT_LEN;
-        if ((end_buf - current_ev) > data_len)
-        {
-            A_MEMZERO(&iwe, sizeof(iwe));
-            iwe.cmd = IWEVGENIE;
-            iwe.u.data.length = cie->ie_wsc[1] + 2;
-            current_ev = IWE_STREAM_ADD_POINT(param->info, current_ev, end_buf,
-                                              &iwe, (char*)cie->ie_wsc);
-        }
-        param->bytes_needed += data_len;
-    }
-#endif /* WIRELESS_EXT >= 18 */
-
-    param->current_ev = current_ev;
-}
-
-int
-ar6000_ioctl_giwscan(struct net_device *dev,
-            struct iw_request_info *info,
-            struct iw_point *data, char *extra)
-{
-    struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev);
-    struct ar_giwscan_param param;
-
-    if (is_iwioctl_allowed(ar->arNextMode, info->cmd) != 0) {
-        A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info->cmd);
-        return -EOPNOTSUPP;
-    }
-
-    if (ar->arWlanState == WLAN_DISABLED) {
-        return -EIO;
-    }
-
-    if (ar->arWmiReady == false) {
-        return -EIO;
-    }
-
-    param.current_ev = extra;
-    param.end_buf = extra + data->length;
-    param.bytes_needed = 0;
-    param.info = info;
-
-    /* Translate data to WE format */
-    wmi_iterate_nodes(ar->arWmi, ar6000_scan_node, &param);
-
-    /* check if bytes needed is greater than bytes consumed */
-    if (param.bytes_needed > (param.current_ev - extra))
-    {
-        /* Request one byte more than needed, because when "data->length" equals bytes_needed,
-        it is not possible to add the last event data as all iwe_stream_add_xxxxx() functions
-        checks whether (cur_ptr + ev_len) < end_ptr, due to this one more retry would happen*/
-        data->length = param.bytes_needed + 1;
-
-        return -E2BIG;
-    }
-
-    return 0;
-}
-
-extern int reconnect_flag;
-/* SIOCSIWESSID */
-static int
-ar6000_ioctl_siwessid(struct net_device *dev,
-                     struct iw_request_info *info,
-                     struct iw_point *data, char *ssid)
-{
-    struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev);
-    int status;
-    u8 arNetworkType;
-    u8 prevMode = ar->arNetworkType;
-
-    if (is_iwioctl_allowed(ar->arNextMode, info->cmd) != 0) {
-        A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info->cmd);
-        return -EOPNOTSUPP;
-    }
-
-    if (ar->bIsDestroyProgress) {
-        return -EBUSY;
-    }
-
-    if (ar->arWlanState == WLAN_DISABLED) {
-        return -EIO;
-    }
-
-    if (ar->arWmiReady == false) {
-        return -EIO;
-    }
-
-#if defined(WIRELESS_EXT)
-    if (WIRELESS_EXT >= 20) {
-        data->length += 1;
-    }
-#endif
-
-    /*
-     * iwconfig passes a null terminated string with length including this
-     * so we need to account for this
-     */
-    if (data->flags && (!data->length || (data->length == 1) ||
-        ((data->length - 1) > sizeof(ar->arSsid))))
-    {
-        /*
-         * ssid is invalid
-         */
-        return -EINVAL;
-    }
-
-    if (ar->arNextMode == AP_NETWORK) {
-        /* SSID change for AP network - Will take effect on commit */
-        if(memcmp(ar->arSsid,ssid,32) != 0) {
-             ar->arSsidLen = data->length - 1;
-            memcpy(ar->arSsid, ssid, ar->arSsidLen);
-            ar->ap_profile_flag = 1; /* There is a change in profile */
-        }
-        return 0;
-    } else if(ar->arNetworkType == AP_NETWORK) {
-        u8 ctr;
-        struct sk_buff *skb;
-
-        /* We are switching from AP to STA | IBSS mode, cleanup the AP state */
-        for (ctr=0; ctr < AP_MAX_NUM_STA; ctr++) {
-            remove_sta(ar, ar->sta_list[ctr].mac, 0);
-        }
-        A_MUTEX_LOCK(&ar->mcastpsqLock);
-        while (!A_NETBUF_QUEUE_EMPTY(&ar->mcastpsq)) {
-            skb = A_NETBUF_DEQUEUE(&ar->mcastpsq);
-            A_NETBUF_FREE(skb);
-        }
-        A_MUTEX_UNLOCK(&ar->mcastpsqLock);
-    }
-
-    /* Added for bug 25178, return an IOCTL error instead of target returning
-       Illegal parameter error when either the BSSID or channel is missing
-       and we cannot scan during connect.
-     */
-    if (data->flags) {
-        if (ar->arSkipScan == true &&
-            (ar->arChannelHint == 0 ||
-             (!ar->arReqBssid[0] && !ar->arReqBssid[1] && !ar->arReqBssid[2] &&
-              !ar->arReqBssid[3] && !ar->arReqBssid[4] && !ar->arReqBssid[5])))
-        {
-            return -EINVAL;
-        }
-    }
-
-    if (down_interruptible(&ar->arSem)) {
-        return -ERESTARTSYS;
-    }
-
-    if (ar->bIsDestroyProgress || ar->arWlanState == WLAN_DISABLED) {
-        up(&ar->arSem);
-        return -EBUSY;
-    }
-
-    if (ar->arTxPending[wmi_get_control_ep(ar->arWmi)]) {
-        /*
-         * sleep until the command queue drains
-         */
-        wait_event_interruptible_timeout(arEvent,
-            ar->arTxPending[wmi_get_control_ep(ar->arWmi)] == 0, wmitimeout * HZ);
-        if (signal_pending(current)) {
-            return -EINTR;
-        }
-    }
-
-    if (!data->flags) {
-        arNetworkType = ar->arNetworkType;
-#ifdef ATH6K_CONFIG_CFG80211
-        if (ar->arConnected) {
-#endif /* ATH6K_CONFIG_CFG80211 */
-            ar6000_init_profile_info(ar);
-#ifdef ATH6K_CONFIG_CFG80211
-        }
-#endif /* ATH6K_CONFIG_CFG80211 */
-        ar->arNetworkType = arNetworkType;
-    }
-
-    /* Update the arNetworkType */
-    ar->arNetworkType = ar->arNextMode;
-
-    if ((prevMode != AP_NETWORK) &&
-        ((ar->arSsidLen) || 
-        ((ar->arSsidLen == 0) && (ar->arConnected || ar->arConnectPending)) || 
-        (!data->flags)))
-    {
-        if ((!data->flags) ||
-            (memcmp(ar->arSsid, ssid, ar->arSsidLen) != 0) ||
-            (ar->arSsidLen != (data->length - 1)))
-        {
-            /*
-             * SSID set previously or essid off has been issued.
-             *
-             * Disconnect Command is issued in two cases after wmi is ready
-             * (1) ssid is different from the previous setting
-             * (2) essid off has been issued
-             *
-             */
-            if (ar->arWmiReady == true) {
-                reconnect_flag = 0;
-                status = wmi_setPmkid_cmd(ar->arWmi, ar->arBssid, NULL, 0);
-                ar6000_disconnect(ar);
-                A_MEMZERO(ar->arSsid, sizeof(ar->arSsid));
-                ar->arSsidLen = 0;
-                if (ar->arSkipScan == false) {
-                    A_MEMZERO(ar->arReqBssid, sizeof(ar->arReqBssid));
-                }
-                if (!data->flags) {
-                    up(&ar->arSem);
-                    return 0;
-                }
-            } else {
-                 up(&ar->arSem);
-            }
-        }
-        else
-        {
-            /*
-             * SSID is same, so we assume profile hasn't changed.
-             * If the interface is up and wmi is ready, we issue
-             * a reconnect cmd. Issue a reconnect only we are already
-             * connected.
-             */
-            if((ar->arConnected == true) && (ar->arWmiReady == true))
-            {
-                reconnect_flag = true;
-                status = wmi_reconnect_cmd(ar->arWmi,ar->arReqBssid,
-                                           ar->arChannelHint);
-                up(&ar->arSem);
-                if (status) {
-                    return -EIO;
-                }
-                return 0;
-            }
-            else{
-                /*
-                 * Dont return if connect is pending.
-                 */
-                if(!(ar->arConnectPending)) {
-                    up(&ar->arSem);
-                    return 0;
-                }
-            }
-        }
-    }
-
-    ar->arSsidLen = data->length - 1;
-    memcpy(ar->arSsid, ssid, ar->arSsidLen);
-
-    if (ar6000_connect_to_ap(ar)!= 0) {
-        up(&ar->arSem);
-        return -EIO;
-    }else{
-      up(&ar->arSem);
-    }
-    return 0;
-}
-
-/* SIOCGIWESSID */
-static int
-ar6000_ioctl_giwessid(struct net_device *dev,
-                     struct iw_request_info *info,
-                     struct iw_point *data, char *essid)
-{
-    struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev);
-
-    if (is_iwioctl_allowed(ar->arNextMode, info->cmd) != 0) {
-        A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info->cmd);
-        return -EOPNOTSUPP;
-    }
-
-    if (ar->arWlanState == WLAN_DISABLED) {
-        return -EIO;
-    }
-
-    if (!ar->arSsidLen) {
-        return -EINVAL;
-    }
-
-    data->flags = 1;
-    data->length = ar->arSsidLen;
-    memcpy(essid, ar->arSsid, ar->arSsidLen);
-
-    return 0;
-}
-
-
-void ar6000_install_static_wep_keys(struct ar6_softc *ar)
-{
-    u8 index;
-    u8 keyUsage;
-
-    for (index = WMI_MIN_KEY_INDEX; index <= WMI_MAX_KEY_INDEX; index++) {
-        if (ar->arWepKeyList[index].arKeyLen) {
-            keyUsage = GROUP_USAGE;
-            if (index == ar->arDefTxKeyIndex) {
-                keyUsage |= TX_USAGE;
-            }
-            wmi_addKey_cmd(ar->arWmi,
-                           index,
-                           WEP_CRYPT,
-                           keyUsage,
-                           ar->arWepKeyList[index].arKeyLen,
-                           NULL,
-                           ar->arWepKeyList[index].arKey, KEY_OP_INIT_VAL, NULL,
-                           NO_SYNC_WMIFLAG);
-        }
-    }
-}
-
-/*
- * SIOCSIWRATE
- */
-int
-ar6000_ioctl_siwrate(struct net_device *dev,
-            struct iw_request_info *info,
-            struct iw_param *rrq, char *extra)
-{
-    struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev);
-    u32 kbps;
-    s8 rate_idx;
-
-    if (is_iwioctl_allowed(ar->arNextMode, info->cmd) != 0) {
-        A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info->cmd);
-        return -EOPNOTSUPP;
-    }
-
-    if (rrq->fixed) {
-        kbps = rrq->value / 1000;           /* rrq->value is in bps */
-    } else {
-        kbps = -1;                          /* -1 indicates auto rate */
-    }
-    if(kbps != -1 && wmi_validate_bitrate(ar->arWmi, kbps, &rate_idx) != 0)
-    {
-        AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("BitRate is not Valid %d\n", kbps));
-        return -EINVAL;
-    }
-    ar->arBitRate = kbps;
-    if(ar->arWmiReady == true)
-    {
-        if (wmi_set_bitrate_cmd(ar->arWmi, kbps, -1, -1) != 0) {
-            return -EINVAL;
-        }
-    }
-    return 0;
-}
-
-/*
- * SIOCGIWRATE
- */
-int
-ar6000_ioctl_giwrate(struct net_device *dev,
-            struct iw_request_info *info,
-            struct iw_param *rrq, char *extra)
-{
-    struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev);
-    int ret = 0;
-
-    if (is_iwioctl_allowed(ar->arNextMode, info->cmd) != 0) {
-        A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info->cmd);
-        return -EOPNOTSUPP;
-    }
-
-    if (ar->bIsDestroyProgress) {
-        return -EBUSY;
-    }
-
-    if (ar->arWlanState == WLAN_DISABLED) {
-        return -EIO;
-    }
-
-    if ((ar->arNextMode != AP_NETWORK && !ar->arConnected) || ar->arWmiReady == false) {
-        rrq->value = 1000 * 1000;       
-        return 0;
-    }
-
-    if (down_interruptible(&ar->arSem)) {
-        return -ERESTARTSYS;
-    }
-
-    if (ar->bIsDestroyProgress || ar->arWlanState == WLAN_DISABLED) {
-        up(&ar->arSem);
-        return -EBUSY;
-    }
-
-    ar->arBitRate = 0xFFFF;
-    if (wmi_get_bitrate_cmd(ar->arWmi) != 0) {
-        up(&ar->arSem);
-        return -EIO;
-    }
-    wait_event_interruptible_timeout(arEvent, ar->arBitRate != 0xFFFF, wmitimeout * HZ);
-    if (signal_pending(current)) {
-        ret = -EINTR;
-    }
-    /* If the interface is down or wmi is not ready or the target is not
-       connected - return the value stored in the device structure */
-    if (!ret) {
-        if (ar->arBitRate == -1) {
-            rrq->fixed = true;
-            rrq->value = 0;
-        } else {
-            rrq->value = ar->arBitRate * 1000;
-        }
-    }
-
-    up(&ar->arSem);
-
-    return ret;
-}
-
-/*
- * SIOCSIWTXPOW
- */
-static int
-ar6000_ioctl_siwtxpow(struct net_device *dev,
-             struct iw_request_info *info,
-             struct iw_param *rrq, char *extra)
-{
-    struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev);
-    u8 dbM;
-
-    if (is_iwioctl_allowed(ar->arNextMode, info->cmd) != 0) {
-        A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info->cmd);
-        return -EOPNOTSUPP;
-    }
-
-    if (ar->arWlanState == WLAN_DISABLED) {
-        return -EIO;
-    }
-
-    if (rrq->disabled) {
-        return -EOPNOTSUPP;
-    }
-
-    if (rrq->fixed) {
-        if (rrq->flags != IW_TXPOW_DBM) {
-            return -EOPNOTSUPP;
-        }
-        ar->arTxPwr= dbM = rrq->value;
-        ar->arTxPwrSet = true;
-    } else {
-        ar->arTxPwr = dbM = 0;
-        ar->arTxPwrSet = false;
-    }
-    if(ar->arWmiReady == true)
-    {
-        AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_TX,("Set tx pwr cmd %d dbM\n", dbM));
-        wmi_set_txPwr_cmd(ar->arWmi, dbM);
-    }
-    return 0;
-}
-
-/*
- * SIOCGIWTXPOW
- */
-int
-ar6000_ioctl_giwtxpow(struct net_device *dev,
-            struct iw_request_info *info,
-            struct iw_param *rrq, char *extra)
-{
-    struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev);
-    int ret = 0;
-
-    if (is_iwioctl_allowed(ar->arNextMode, info->cmd) != 0) {
-        A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info->cmd);
-        return -EOPNOTSUPP;
-    }
-
-    if (ar->bIsDestroyProgress) {
-        return -EBUSY;
-    }
-
-    if (ar->arWlanState == WLAN_DISABLED) {
-        return -EIO;
-    }
-
-    if (down_interruptible(&ar->arSem)) {
-        return -ERESTARTSYS;
-    }
-
-    if (ar->bIsDestroyProgress) {
-        up(&ar->arSem);
-        return -EBUSY;
-    }
-
-    if((ar->arWmiReady == true) && (ar->arConnected == true))
-    {
-        ar->arTxPwr = 0;
-
-        if (wmi_get_txPwr_cmd(ar->arWmi) != 0) {
-            up(&ar->arSem);
-            return -EIO;
-        }
-
-        wait_event_interruptible_timeout(arEvent, ar->arTxPwr != 0, wmitimeout * HZ);
-
-        if (signal_pending(current)) {
-            ret = -EINTR;
-         }
-    }
-   /* If the interace is down or wmi is not ready or target is not connected
-      then return value stored in the device structure */
-
-    if (!ret) {
-         if (ar->arTxPwrSet == true) {
-            rrq->fixed = true;
-        }
-        rrq->value = ar->arTxPwr;
-        rrq->flags = IW_TXPOW_DBM;
-        //
-        // IWLIST need this flag to get TxPower
-        //
-        rrq->disabled = 0;
-    }
-
-    up(&ar->arSem);
-
-    return ret;
-}
-
-/*
- * SIOCSIWRETRY
- * since iwconfig only provides us with one max retry value, we use it
- * to apply to data frames of the BE traffic class.
- */
-static int
-ar6000_ioctl_siwretry(struct net_device *dev,
-             struct iw_request_info *info,
-             struct iw_param *rrq, char *extra)
-{
-    struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev);
-
-    if (is_iwioctl_allowed(ar->arNextMode, info->cmd) != 0) {
-        A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info->cmd);
-        return -EOPNOTSUPP;
-    }
-
-    if (ar->arWlanState == WLAN_DISABLED) {
-        return -EIO;
-    }
-
-    if (rrq->disabled) {
-        return -EOPNOTSUPP;
-    }
-
-    if ((rrq->flags & IW_RETRY_TYPE) != IW_RETRY_LIMIT) {
-        return -EOPNOTSUPP;
-    }
-
-    if ( !(rrq->value >= WMI_MIN_RETRIES) || !(rrq->value <= WMI_MAX_RETRIES)) {
-            return - EINVAL;
-    }
-    if(ar->arWmiReady == true)
-    {
-        if (wmi_set_retry_limits_cmd(ar->arWmi, DATA_FRAMETYPE, WMM_AC_BE,
-                                     rrq->value, 0) != 0){
-            return -EINVAL;
-        }
-    }
-    ar->arMaxRetries = rrq->value;
-    return 0;
-}
-
-/*
- * SIOCGIWRETRY
- */
-static int
-ar6000_ioctl_giwretry(struct net_device *dev,
-             struct iw_request_info *info,
-             struct iw_param *rrq, char *extra)
-{
-    struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev);
-
-    if (is_iwioctl_allowed(ar->arNextMode, info->cmd) != 0) {
-        A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info->cmd);
-        return -EOPNOTSUPP;
-    }
-
-    if (ar->arWlanState == WLAN_DISABLED) {
-        return -EIO;
-    }
-
-    rrq->disabled = 0;
-    switch (rrq->flags & IW_RETRY_TYPE) {
-    case IW_RETRY_LIFETIME:
-        return -EOPNOTSUPP;
-        break;
-    case IW_RETRY_LIMIT:
-        rrq->flags = IW_RETRY_LIMIT;
-        switch (rrq->flags & IW_RETRY_MODIFIER) {
-        case IW_RETRY_MIN:
-            rrq->flags |= IW_RETRY_MIN;
-            rrq->value = WMI_MIN_RETRIES;
-            break;
-        case IW_RETRY_MAX:
-            rrq->flags |= IW_RETRY_MAX;
-            rrq->value = ar->arMaxRetries;
-            break;
-        }
-        break;
-    }
-    return 0;
-}
-
-/*
- * SIOCSIWENCODE
- */
-static int
-ar6000_ioctl_siwencode(struct net_device *dev,
-              struct iw_request_info *info,
-              struct iw_point *erq, char *keybuf)
-{
-    struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev);
-    int index;
-    s32 auth = 0;
-
-    if (is_iwioctl_allowed(ar->arNextMode, info->cmd) != 0) {
-        A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info->cmd);
-        return -EOPNOTSUPP;
-    }
-
-    if(ar->arNextMode != AP_NETWORK) {
-    /*
-     *  Static WEP Keys should be configured before setting the SSID
-     */
-    if (ar->arSsid[0] && erq->length) {
-        return -EIO;
-    }
-    }
-
-    if (ar->arWlanState == WLAN_DISABLED) {
-        return -EIO;
-    }
-
-    index = erq->flags & IW_ENCODE_INDEX;
-
-    if (index && (((index - 1) < WMI_MIN_KEY_INDEX) ||
-                  ((index - 1) > WMI_MAX_KEY_INDEX)))
-    {
-        return -EIO;
-    }
-
-    if (erq->flags & IW_ENCODE_DISABLED) {
-        /*
-         * Encryption disabled
-         */
-        if (index) {
-            /*
-             * If key index was specified then clear the specified key
-             */
-            index--;
-            A_MEMZERO(ar->arWepKeyList[index].arKey,
-                      sizeof(ar->arWepKeyList[index].arKey));
-            ar->arWepKeyList[index].arKeyLen = 0;
-        }
-        ar->arDot11AuthMode       = OPEN_AUTH;
-        ar->arPairwiseCrypto      = NONE_CRYPT;
-        ar->arGroupCrypto         = NONE_CRYPT;
-        ar->arAuthMode            = NONE_AUTH;
-    } else {
-        /*
-         * Enabling WEP encryption
-         */
-        if (index) {
-            index--;                /* keyindex is off base 1 in iwconfig */
-        }
-
-        if (erq->flags & IW_ENCODE_OPEN) {
-            auth |= OPEN_AUTH;
-            ar->arDefTxKeyIndex = index;
-        }
-        if (erq->flags & IW_ENCODE_RESTRICTED) {
-            auth |= SHARED_AUTH;
-        }
-
-        if (!auth) {
-            auth = OPEN_AUTH;
-        }
-
-        if (erq->length) {
-            if (!IEEE80211_IS_VALID_WEP_CIPHER_LEN(erq->length)) {
-                return -EIO;
-            }
-
-            A_MEMZERO(ar->arWepKeyList[index].arKey,
-                      sizeof(ar->arWepKeyList[index].arKey));
-            memcpy(ar->arWepKeyList[index].arKey, keybuf, erq->length);
-            ar->arWepKeyList[index].arKeyLen = erq->length;
-            ar->arDot11AuthMode       = auth;
-        } else {
-            if (ar->arWepKeyList[index].arKeyLen == 0) {
-                return -EIO;
-            }
-            ar->arDefTxKeyIndex = index;
-
-            if(ar->arSsidLen && ar->arWepKeyList[index].arKeyLen) {
-                wmi_addKey_cmd(ar->arWmi,
-                               index,
-                               WEP_CRYPT,
-                               GROUP_USAGE | TX_USAGE,
-                               ar->arWepKeyList[index].arKeyLen,
-                               NULL,
-                               ar->arWepKeyList[index].arKey, KEY_OP_INIT_VAL, NULL,
-                               NO_SYNC_WMIFLAG);
-            }
-        }
-
-        ar->arPairwiseCrypto      = WEP_CRYPT;
-        ar->arGroupCrypto         = WEP_CRYPT;
-        ar->arAuthMode            = NONE_AUTH;
-    }
-
-    if(ar->arNextMode != AP_NETWORK) {
-    /*
-     * profile has changed.  Erase ssid to signal change
-     */
-        A_MEMZERO(ar->arSsid, sizeof(ar->arSsid));
-        ar->arSsidLen = 0;
-    }
-    ar->ap_profile_flag = 1; /* There is a change in profile */
-    return 0;
-}
-
-static int
-ar6000_ioctl_giwencode(struct net_device *dev,
-              struct iw_request_info *info,
-              struct iw_point *erq, char *key)
-{
-    struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev);
-    u8 keyIndex;
-    struct ar_wep_key *wk;
-
-    if (is_iwioctl_allowed(ar->arNextMode, info->cmd) != 0) {
-        A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info->cmd);
-        return -EOPNOTSUPP;
-    }
-
-    if (ar->arWlanState == WLAN_DISABLED) {
-        return -EIO;
-    }
-
-    if (ar->arPairwiseCrypto == NONE_CRYPT) {
-        erq->length = 0;
-        erq->flags = IW_ENCODE_DISABLED;
-    } else {
-        if (ar->arPairwiseCrypto == WEP_CRYPT) {
-            /* get the keyIndex */
-            keyIndex = erq->flags & IW_ENCODE_INDEX;
-            if (0 == keyIndex) {
-                keyIndex = ar->arDefTxKeyIndex;
-            } else if ((keyIndex - 1 < WMI_MIN_KEY_INDEX) ||
-                       (keyIndex - 1 > WMI_MAX_KEY_INDEX))
-            {
-                keyIndex = WMI_MIN_KEY_INDEX;
-            } else {
-                keyIndex--;
-            }
-            erq->flags = keyIndex + 1;
-            erq->flags &= ~IW_ENCODE_DISABLED;
-            wk = &ar->arWepKeyList[keyIndex];
-            if (erq->length > wk->arKeyLen) {
-                erq->length = wk->arKeyLen;
-            }
-            if (wk->arKeyLen) {
-                memcpy(key, wk->arKey, erq->length);
-            }
-        } else {
-            erq->flags &= ~IW_ENCODE_DISABLED;
-            if (ar->user_saved_keys.keyOk) {
-                erq->length = ar->user_saved_keys.ucast_ik.ik_keylen;
-                if (erq->length) {
-                    memcpy(key, ar->user_saved_keys.ucast_ik.ik_keydata, erq->length);
-                }
-            } else {
-                erq->length = 1;    // not really printing any key but let iwconfig know enc is on
-            }
-        }
-
-        if (ar->arDot11AuthMode & OPEN_AUTH) {
-            erq->flags |= IW_ENCODE_OPEN;
-        }
-        if (ar->arDot11AuthMode & SHARED_AUTH) {
-            erq->flags |= IW_ENCODE_RESTRICTED;
-        }
-    }
-
-    return 0;
-}
-
-#if WIRELESS_EXT >= 18
-/*
- * SIOCSIWGENIE
- */
-static int
-ar6000_ioctl_siwgenie(struct net_device *dev,
-              struct iw_request_info *info,
-              struct iw_point *erq, char *extra)
-{
-    struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev);
-
-#ifdef WAPI_ENABLE
-    u8 *ie = erq->pointer;
-    u8 ie_type = ie[0];
-    u16 ie_length = erq->length;
-    u8 wapi_ie[128];
-#endif
-
-    if (ar->arWmiReady == false) {
-        return -EIO;
-    }
-#ifdef WAPI_ENABLE
-    if (ie_type == IEEE80211_ELEMID_WAPI) {
-        if (ie_length > 0) {
-            if (copy_from_user(wapi_ie, ie, ie_length)) {
-                return -EIO;
-            }
-        }
-        wmi_set_appie_cmd(ar->arWmi, WMI_FRAME_ASSOC_REQ, ie_length, wapi_ie);
-    } else if (ie_length == 0) {
-        wmi_set_appie_cmd(ar->arWmi, WMI_FRAME_ASSOC_REQ, ie_length, wapi_ie);
-    }
-#endif
-    return 0;
-}
-
-
-/*
- * SIOCGIWGENIE
- */
-static int
-ar6000_ioctl_giwgenie(struct net_device *dev,
-              struct iw_request_info *info,
-              struct iw_point *erq, char *extra)
-{
-    struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev);
-
-    if (ar->arWmiReady == false) {
-        return -EIO;
-    }
-    erq->length = 0;
-    erq->flags = 0;
-
-    return 0;
-}
-
-/*
- * SIOCSIWAUTH
- */
-static int
-ar6000_ioctl_siwauth(struct net_device *dev,
-              struct iw_request_info *info,
-              struct iw_param *data, char *extra)
-{
-    struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev);
-
-    bool profChanged;
-    u16 param;
-    s32 ret;
-    s32 value;
-
-    if (ar->arWmiReady == false) {
-        return -EIO;
-    }
-
-    if (ar->arWlanState == WLAN_DISABLED) {
-        return -EIO;
-    }
-
-    param = data->flags & IW_AUTH_INDEX;
-    value = data->value;
-    profChanged = true;
-    ret = 0;
-
-    switch (param) {
-        case IW_AUTH_WPA_VERSION:
-            if (value & IW_AUTH_WPA_VERSION_DISABLED) {
-                ar->arAuthMode = NONE_AUTH;
-            } else if (value & IW_AUTH_WPA_VERSION_WPA) {
-                    ar->arAuthMode = WPA_AUTH;
-            } else if (value & IW_AUTH_WPA_VERSION_WPA2) {
-                    ar->arAuthMode = WPA2_AUTH;
-            } else {
-                ret = -1;
-                profChanged    = false;
-            }
-            break;
-        case IW_AUTH_CIPHER_PAIRWISE:
-            if (value & IW_AUTH_CIPHER_NONE) {
-                ar->arPairwiseCrypto = NONE_CRYPT;
-                ar->arPairwiseCryptoLen = 0;
-            } else if (value & IW_AUTH_CIPHER_WEP40) {
-                ar->arPairwiseCrypto = WEP_CRYPT;
-                ar->arPairwiseCryptoLen = 5;
-            } else if (value & IW_AUTH_CIPHER_TKIP) {
-                ar->arPairwiseCrypto = TKIP_CRYPT;
-                ar->arPairwiseCryptoLen = 0;
-            } else if (value & IW_AUTH_CIPHER_CCMP) {
-                ar->arPairwiseCrypto = AES_CRYPT;
-                ar->arPairwiseCryptoLen = 0;
-            } else if (value & IW_AUTH_CIPHER_WEP104) {
-                ar->arPairwiseCrypto = WEP_CRYPT;
-                ar->arPairwiseCryptoLen = 13;
-            } else {
-                ret = -1;
-                profChanged    = false;
-            }
-            break;
-        case IW_AUTH_CIPHER_GROUP:
-            if (value & IW_AUTH_CIPHER_NONE) {
-                ar->arGroupCrypto = NONE_CRYPT;
-                ar->arGroupCryptoLen = 0;
-            } else if (value & IW_AUTH_CIPHER_WEP40) {
-                ar->arGroupCrypto = WEP_CRYPT;
-                ar->arGroupCryptoLen = 5;
-            } else if (value & IW_AUTH_CIPHER_TKIP) {
-                ar->arGroupCrypto = TKIP_CRYPT;
-                ar->arGroupCryptoLen = 0;
-            } else if (value & IW_AUTH_CIPHER_CCMP) {
-                ar->arGroupCrypto = AES_CRYPT;
-                ar->arGroupCryptoLen = 0;
-            } else if (value & IW_AUTH_CIPHER_WEP104) {
-                ar->arGroupCrypto = WEP_CRYPT;
-                ar->arGroupCryptoLen = 13;
-            } else {
-                ret = -1;
-                profChanged    = false;
-            }
-            break;
-        case IW_AUTH_KEY_MGMT:
-            if (value & IW_AUTH_KEY_MGMT_PSK) {
-                if (WPA_AUTH == ar->arAuthMode) {
-                    ar->arAuthMode = WPA_PSK_AUTH;
-                } else if (WPA2_AUTH == ar->arAuthMode) {
-                    ar->arAuthMode = WPA2_PSK_AUTH;
-                } else {
-                    ret = -1;
-                }
-            } else if (!(value & IW_AUTH_KEY_MGMT_802_1X)) {
-                ar->arAuthMode = NONE_AUTH;
-            }
-            break;
-        case IW_AUTH_TKIP_COUNTERMEASURES:
-            wmi_set_tkip_countermeasures_cmd(ar->arWmi, value);
-            profChanged    = false;
-            break;
-        case IW_AUTH_DROP_UNENCRYPTED:
-            profChanged    = false;
-            break;
-        case IW_AUTH_80211_AUTH_ALG:
-            ar->arDot11AuthMode = 0;
-            if (value & IW_AUTH_ALG_OPEN_SYSTEM) {
-                ar->arDot11AuthMode  |= OPEN_AUTH;
-            }
-            if (value & IW_AUTH_ALG_SHARED_KEY) {
-                ar->arDot11AuthMode  |= SHARED_AUTH;
-            }
-            if (value & IW_AUTH_ALG_LEAP) {
-                ar->arDot11AuthMode   = LEAP_AUTH;
-            }
-            if(ar->arDot11AuthMode == 0) {
-                ret = -1;
-                profChanged    = false;
-            }
-            break;
-        case IW_AUTH_WPA_ENABLED:
-            if (!value) {
-                ar->arAuthMode = NONE_AUTH;
-                /* when the supplicant is stopped, it calls this
-                 * handler with value=0. The followings need to be
-                 * reset if the STA were to connect again
-                 * without security
-                 */
-                ar->arDot11AuthMode = OPEN_AUTH;
-                ar->arPairwiseCrypto = NONE_CRYPT;
-                ar->arPairwiseCryptoLen = 0;
-                ar->arGroupCrypto = NONE_CRYPT;
-                ar->arGroupCryptoLen = 0;
-            }
-            break;
-        case IW_AUTH_RX_UNENCRYPTED_EAPOL:
-            profChanged    = false;
-            break;
-        case IW_AUTH_ROAMING_CONTROL:
-            profChanged    = false;
-            break;
-        case IW_AUTH_PRIVACY_INVOKED:
-            if (!value) {
-                ar->arPairwiseCrypto = NONE_CRYPT;
-                ar->arPairwiseCryptoLen = 0;
-                ar->arGroupCrypto = NONE_CRYPT;
-                ar->arGroupCryptoLen = 0;
-            }
-            break;
-#ifdef WAPI_ENABLE
-        case IW_AUTH_WAPI_ENABLED:
-            ar->arWapiEnable = value;
-            break;
-#endif
-        default:
-           ret = -1;
-           profChanged    = false;
-           break;
-    }
-
-    if (profChanged == true) {
-        /*
-         * profile has changed.  Erase ssid to signal change
-         */
-        A_MEMZERO(ar->arSsid, sizeof(ar->arSsid));
-        ar->arSsidLen = 0;
-    }
-
-    return ret;
-}
-
-
-/*
- * SIOCGIWAUTH
- */
-static int
-ar6000_ioctl_giwauth(struct net_device *dev,
-              struct iw_request_info *info,
-              struct iw_param *data, char *extra)
-{
-    struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev);
-    u16 param;
-    s32 ret;
-
-    if (ar->arWmiReady == false) {
-        return -EIO;
-    }
-
-    if (ar->arWlanState == WLAN_DISABLED) {
-        return -EIO;
-    }
-
-    param = data->flags & IW_AUTH_INDEX;
-    ret = 0;
-    data->value = 0;
-
-
-    switch (param) {
-        case IW_AUTH_WPA_VERSION:
-            if (ar->arAuthMode == NONE_AUTH) {
-                data->value |= IW_AUTH_WPA_VERSION_DISABLED;
-            } else if (ar->arAuthMode == WPA_AUTH) {
-                data->value |= IW_AUTH_WPA_VERSION_WPA;
-            } else if (ar->arAuthMode == WPA2_AUTH) {
-                data->value |= IW_AUTH_WPA_VERSION_WPA2;
-            } else {
-                ret = -1;
-            }
-            break;
-        case IW_AUTH_CIPHER_PAIRWISE:
-            if (ar->arPairwiseCrypto == NONE_CRYPT) {
-                data->value |= IW_AUTH_CIPHER_NONE;
-            } else if (ar->arPairwiseCrypto == WEP_CRYPT) {
-                if (ar->arPairwiseCryptoLen == 13) {
-                    data->value |= IW_AUTH_CIPHER_WEP104;
-                } else {
-                    data->value |= IW_AUTH_CIPHER_WEP40;
-                }
-            } else if (ar->arPairwiseCrypto == TKIP_CRYPT) {
-                data->value |= IW_AUTH_CIPHER_TKIP;
-            } else if (ar->arPairwiseCrypto == AES_CRYPT) {
-                data->value |= IW_AUTH_CIPHER_CCMP;
-            } else {
-                ret = -1;
-            }
-            break;
-        case IW_AUTH_CIPHER_GROUP:
-            if (ar->arGroupCrypto == NONE_CRYPT) {
-                    data->value |= IW_AUTH_CIPHER_NONE;
-            } else if (ar->arGroupCrypto == WEP_CRYPT) {
-                if (ar->arGroupCryptoLen == 13) {
-                    data->value |= IW_AUTH_CIPHER_WEP104;
-                } else {
-                    data->value |= IW_AUTH_CIPHER_WEP40;
-                }
-            } else if (ar->arGroupCrypto == TKIP_CRYPT) {
-                data->value |= IW_AUTH_CIPHER_TKIP;
-            } else if (ar->arGroupCrypto == AES_CRYPT) {
-                data->value |= IW_AUTH_CIPHER_CCMP;
-            } else {
-                ret = -1;
-            }
-            break;
-        case IW_AUTH_KEY_MGMT:
-            if ((ar->arAuthMode == WPA_PSK_AUTH) ||
-                (ar->arAuthMode == WPA2_PSK_AUTH)) {
-                data->value |= IW_AUTH_KEY_MGMT_PSK;
-            } else if ((ar->arAuthMode == WPA_AUTH) ||
-                       (ar->arAuthMode == WPA2_AUTH)) {
-                data->value |= IW_AUTH_KEY_MGMT_802_1X;
-            }
-            break;
-        case IW_AUTH_TKIP_COUNTERMEASURES:
-            // TODO. Save countermeassure enable/disable
-            data->value = 0;
-            break;
-        case IW_AUTH_DROP_UNENCRYPTED:
-            break;
-        case IW_AUTH_80211_AUTH_ALG:
-            if (ar->arDot11AuthMode == OPEN_AUTH) {
-                data->value |= IW_AUTH_ALG_OPEN_SYSTEM;
-            } else if (ar->arDot11AuthMode == SHARED_AUTH) {
-                data->value |= IW_AUTH_ALG_SHARED_KEY;
-            } else if (ar->arDot11AuthMode == LEAP_AUTH) {
-                data->value |= IW_AUTH_ALG_LEAP;
-            } else {
-                ret = -1;
-            }
-            break;
-        case IW_AUTH_WPA_ENABLED:
-            if (ar->arAuthMode == NONE_AUTH) {
-                data->value = 0;
-            } else {
-                data->value = 1;
-            }
-            break;
-        case IW_AUTH_RX_UNENCRYPTED_EAPOL:
-            break;
-        case IW_AUTH_ROAMING_CONTROL:
-            break;
-        case IW_AUTH_PRIVACY_INVOKED:
-            if (ar->arPairwiseCrypto == NONE_CRYPT) {
-                data->value = 0;
-            } else {
-                data->value = 1;
-            }
-            break;
-#ifdef WAPI_ENABLE
-        case IW_AUTH_WAPI_ENABLED:
-            data->value = ar->arWapiEnable;
-            break;
-#endif
-        default:
-           ret = -1;
-           break;
-    }
-
-    return 0;
-}
-
-/*
- * SIOCSIWPMKSA
- */
-static int
-ar6000_ioctl_siwpmksa(struct net_device *dev,
-              struct iw_request_info *info,
-              struct iw_point *data, char *extra)
-{
-    struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev);
-    s32 ret;
-    int status;
-    struct iw_pmksa *pmksa;
-
-    pmksa = (struct iw_pmksa *)extra;
-
-    if (ar->arWmiReady == false) {
-        return -EIO;
-    }
-
-    ret = 0;
-    status = 0;
-
-    switch (pmksa->cmd) {
-        case IW_PMKSA_ADD:
-            status = wmi_setPmkid_cmd(ar->arWmi, (u8 *)pmksa->bssid.sa_data, pmksa->pmkid, true);
-            break;
-        case IW_PMKSA_REMOVE:
-            status = wmi_setPmkid_cmd(ar->arWmi, (u8 *)pmksa->bssid.sa_data, pmksa->pmkid, false);
-            break;
-        case IW_PMKSA_FLUSH:
-            if (ar->arConnected == true) {
-                status = wmi_setPmkid_cmd(ar->arWmi, ar->arBssid, NULL, 0);
-            }
-            break;
-        default:
-            ret=-1;
-            break;
-    }
-    if (status) {
-        ret = -1;
-    }
-
-    return ret;
-}
-
-#ifdef WAPI_ENABLE
-
-#define PN_INIT 0x5c365c36
-
-static int ar6000_set_wapi_key(struct net_device *dev,
-              struct iw_request_info *info,
-              struct iw_point *erq, char *extra)
-{
-    struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev);
-    struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
-    KEY_USAGE   keyUsage = 0;
-    s32 keyLen;
-    u8 *keyData;
-    s32 index;
-    u32 *PN;
-    s32 i;
-    int    status;
-    u8 wapiKeyRsc[16];
-    CRYPTO_TYPE keyType = WAPI_CRYPT;
-    const u8 broadcastMac[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
-
-    index = erq->flags & IW_ENCODE_INDEX;
-    if (index && (((index - 1) < WMI_MIN_KEY_INDEX) ||
-                ((index - 1) > WMI_MAX_KEY_INDEX))) {
-        return -EIO;
-    }
-
-    index--;
-    if (index < 0 || index > 4) {
-        return -EIO;
-    }
-    keyData = (u8 *)(ext + 1);
-    keyLen = erq->length - sizeof(struct iw_encode_ext);
-    memcpy(wapiKeyRsc, ext->tx_seq, sizeof(wapiKeyRsc));
-
-    if (memcmp(ext->addr.sa_data, broadcastMac, sizeof(broadcastMac)) == 0) {
-        keyUsage |= GROUP_USAGE;
-        PN = (u32 *)wapiKeyRsc;
-        for (i = 0; i < 4; i++) {
-            PN[i] = PN_INIT;
-        }
-    } else {
-        keyUsage |= PAIRWISE_USAGE;
-    }
-    status = wmi_addKey_cmd(ar->arWmi,
-                            index,
-                            keyType,
-                            keyUsage,
-                            keyLen,
-                            wapiKeyRsc,
-                            keyData,
-                            KEY_OP_INIT_WAPIPN,
-                            NULL,
-                            SYNC_BEFORE_WMIFLAG);
-    if (0 != status) {
-        return -EIO;
-    }
-    return 0;
-}
-
-#endif
-
-/*
- * SIOCSIWENCODEEXT
- */
-static int
-ar6000_ioctl_siwencodeext(struct net_device *dev,
-              struct iw_request_info *info,
-              struct iw_point *erq, char *extra)
-{
-    struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev);
-    s32 index;
-    struct iw_encode_ext *ext;
-    KEY_USAGE keyUsage;
-    s32 keyLen;
-    u8 *keyData;
-    u8 keyRsc[8];
-    int status;
-    CRYPTO_TYPE keyType;
-#ifdef USER_KEYS
-    struct ieee80211req_key ik;
-#endif /* USER_KEYS */
-
-    if (ar->arWlanState == WLAN_DISABLED) {
-        return -EIO;
-    }
-
-#ifdef USER_KEYS
-    ar->user_saved_keys.keyOk = false;
-#endif /* USER_KEYS */
-
-    index = erq->flags & IW_ENCODE_INDEX;
-
-    if (index && (((index - 1) < WMI_MIN_KEY_INDEX) ||
-                  ((index - 1) > WMI_MAX_KEY_INDEX)))
-    {
-        return -EIO;
-    }
-
-    ext = (struct iw_encode_ext *)extra;
-    if (erq->flags & IW_ENCODE_DISABLED) {
-        /*
-         * Encryption disabled
-         */
-        if (index) {
-            /*
-             * If key index was specified then clear the specified key
-             */
-            index--;
-            A_MEMZERO(ar->arWepKeyList[index].arKey,
-                      sizeof(ar->arWepKeyList[index].arKey));
-            ar->arWepKeyList[index].arKeyLen = 0;
-        }
-    } else {
-        /*
-         * Enabling WEP encryption
-         */
-        if (index) {
-            index--;                /* keyindex is off base 1 in iwconfig */
-        }
-
-        keyUsage = 0;
-        keyLen = erq->length - sizeof(struct iw_encode_ext);
-
-        if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) {
-            keyUsage = TX_USAGE;
-            ar->arDefTxKeyIndex = index;
-            // Just setting the key index
-            if (keyLen == 0) {
-                return 0;
-            }
-        }
-
-        if (keyLen <= 0) {
-            return -EIO;
-        }
-
-        /* key follows iw_encode_ext */
-        keyData = (u8 *)(ext + 1);
-
-        switch (ext->alg) {
-            case IW_ENCODE_ALG_WEP:
-                keyType = WEP_CRYPT;
-#ifdef USER_KEYS
-                ik.ik_type = IEEE80211_CIPHER_WEP;
-#endif /* USER_KEYS */
-                if (!IEEE80211_IS_VALID_WEP_CIPHER_LEN(keyLen)) {
-                    return -EIO;
-                }
-
-                /* Check whether it is static wep. */
-                if (!ar->arConnected) {
-                    A_MEMZERO(ar->arWepKeyList[index].arKey,
-                          sizeof(ar->arWepKeyList[index].arKey));
-                    memcpy(ar->arWepKeyList[index].arKey, keyData, keyLen);
-                    ar->arWepKeyList[index].arKeyLen = keyLen;
-
-                    return 0;
-                }
-                break;
-            case IW_ENCODE_ALG_TKIP:
-                keyType = TKIP_CRYPT;
-#ifdef USER_KEYS
-                ik.ik_type = IEEE80211_CIPHER_TKIP;
-#endif /* USER_KEYS */
-                break;
-            case IW_ENCODE_ALG_CCMP:
-                keyType = AES_CRYPT;
-#ifdef USER_KEYS
-                ik.ik_type = IEEE80211_CIPHER_AES_CCM;
-#endif /* USER_KEYS */
-                break;
-#ifdef WAPI_ENABLE
-            case IW_ENCODE_ALG_SM4:
-                if (ar->arWapiEnable) {
-                    return ar6000_set_wapi_key(dev, info, erq, extra);
-                } else {
-                    return -EIO;
-                }
-#endif
-            case IW_ENCODE_ALG_PMK:
-                ar->arConnectCtrlFlags |= CONNECT_DO_WPA_OFFLOAD;
-                return wmi_set_pmk_cmd(ar->arWmi, keyData);
-            default:
-                return -EIO;
-        }
-
-
-        if (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) {
-            keyUsage |= GROUP_USAGE;
-        } else {
-            keyUsage |= PAIRWISE_USAGE;
-        }
-
-        if (ext->ext_flags & IW_ENCODE_EXT_RX_SEQ_VALID) {
-            memcpy(keyRsc, ext->rx_seq, sizeof(keyRsc));
-        } else {
-            A_MEMZERO(keyRsc, sizeof(keyRsc));
-        }
-
-        if (((WPA_PSK_AUTH == ar->arAuthMode) || (WPA2_PSK_AUTH == ar->arAuthMode)) &&
-            (GROUP_USAGE & keyUsage))
-        {
-            A_UNTIMEOUT(&ar->disconnect_timer);
-        }
-
-         status = wmi_addKey_cmd(ar->arWmi, index, keyType, keyUsage,
-                            keyLen, keyRsc,
-                            keyData, KEY_OP_INIT_VAL,
-                            (u8 *)ext->addr.sa_data,
-                            SYNC_BOTH_WMIFLAG);
-         if (status) {
-            return -EIO;
-         }
-
-#ifdef USER_KEYS
-        ik.ik_keyix = index;
-        ik.ik_keylen = keyLen;
-        memcpy(ik.ik_keydata, keyData, keyLen);
-        memcpy(&ik.ik_keyrsc, keyRsc, sizeof(keyRsc));
-        memcpy(ik.ik_macaddr, ext->addr.sa_data, ETH_ALEN);
-        if (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) {
-            memcpy(&ar->user_saved_keys.bcast_ik, &ik,
-                       sizeof(struct ieee80211req_key));
-        } else {
-            memcpy(&ar->user_saved_keys.ucast_ik, &ik,
-                      sizeof(struct ieee80211req_key));
-        }
-        ar->user_saved_keys.keyOk = true;
-#endif /* USER_KEYS */
-    }
-
-
-    return 0;
-}
-
-/*
- * SIOCGIWENCODEEXT
- */
-static int
-ar6000_ioctl_giwencodeext(struct net_device *dev,
-              struct iw_request_info *info,
-              struct iw_point *erq, char *extra)
-{
-    struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev);
-
-    if (ar->arWlanState == WLAN_DISABLED) {
-        return -EIO;
-    }
-
-    if (ar->arPairwiseCrypto == NONE_CRYPT) {
-        erq->length = 0;
-        erq->flags = IW_ENCODE_DISABLED;
-    } else {
-        erq->length = 0;
-    }
-
-    return 0;
-}
-#endif // WIRELESS_EXT >= 18
-
-#if WIRELESS_EXT > 20
-static int ar6000_ioctl_siwpower(struct net_device *dev,
-                 struct iw_request_info *info,
-                 union iwreq_data *wrqu, char *extra)
-{
-#ifndef ATH6K_CONFIG_OTA_MODE
-    struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev);
-    WMI_POWER_MODE power_mode;
-
-    if (ar->arWmiReady == false) {
-        return -EIO;
-    }
-
-    if (ar->arWlanState == WLAN_DISABLED) {
-        return -EIO;
-    }
-
-    if (wrqu->power.disabled)
-        power_mode = MAX_PERF_POWER;
-    else
-        power_mode = REC_POWER;
-
-    if (wmi_powermode_cmd(ar->arWmi, power_mode) < 0)
-        return -EIO;
-#endif
-    return 0;
-}
-
-static int ar6000_ioctl_giwpower(struct net_device *dev,
-                 struct iw_request_info *info,
-                 union iwreq_data *wrqu, char *extra)
-{
-    struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev);
-    WMI_POWER_MODE power_mode;
-
-    if (ar->arWmiReady == false) {
-        return -EIO;
-    }
-
-    if (ar->arWlanState == WLAN_DISABLED) {
-        return -EIO;
-    }
-
-    power_mode = wmi_get_power_mode_cmd(ar->arWmi);
-
-    if (power_mode == MAX_PERF_POWER)
-        wrqu->power.disabled = 1;
-    else
-        wrqu->power.disabled = 0;
-
-    return 0;
-}
-#endif // WIRELESS_EXT > 20
-
-/*
- * SIOCGIWNAME
- */
-int
-ar6000_ioctl_giwname(struct net_device *dev,
-           struct iw_request_info *info,
-           char *name, char *extra)
-{
-    u8 capability;
-    struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev);
-
-    if (is_iwioctl_allowed(ar->arNextMode, info->cmd) != 0) {
-        A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info->cmd);
-        return -EOPNOTSUPP;
-    }
-
-    if (ar->arWlanState == WLAN_DISABLED) {
-        return -EIO;
-    }
-
-    capability = ar->arPhyCapability;
-    if(ar->arNetworkType == INFRA_NETWORK && ar->arConnected) {
-        bss_t *bss = wmi_find_node(ar->arWmi, ar->arBssid);
-        if (bss) {
-            capability = get_bss_phy_capability(bss);
-            wmi_node_return(ar->arWmi, bss);
-        }
-    }
-    switch (capability) {
-    case (WMI_11A_CAPABILITY):
-        strncpy(name, "AR6000 802.11a", IFNAMSIZ);
-        break;
-    case (WMI_11G_CAPABILITY):
-        strncpy(name, "AR6000 802.11g", IFNAMSIZ);
-        break;
-    case (WMI_11AG_CAPABILITY):
-        strncpy(name, "AR6000 802.11ag", IFNAMSIZ);
-        break;
-    case (WMI_11NA_CAPABILITY):
-        strncpy(name, "AR6000 802.11na", IFNAMSIZ);
-        break;
-    case (WMI_11NG_CAPABILITY):
-        strncpy(name, "AR6000 802.11ng", IFNAMSIZ);
-        break;
-    case (WMI_11NAG_CAPABILITY):
-        strncpy(name, "AR6000 802.11nag", IFNAMSIZ);
-        break;
-    default:
-        strncpy(name, "AR6000 802.11b", IFNAMSIZ);
-        break;
-    }
-
-    return 0;
-}
-
-/*
- * SIOCSIWFREQ
- */
-int
-ar6000_ioctl_siwfreq(struct net_device *dev,
-            struct iw_request_info *info,
-            struct iw_freq *freq, char *extra)
-{
-    struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev);
-
-    if (is_iwioctl_allowed(ar->arNextMode, info->cmd) != 0) {
-        A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info->cmd);
-        return -EOPNOTSUPP;
-    }
-
-    if (ar->arWlanState == WLAN_DISABLED) {
-        return -EIO;
-    }
-
-    /*
-     * We support limiting the channels via wmiconfig.
-     *
-     * We use this command to configure the channel hint for the connect cmd
-     * so it is possible the target will end up connecting to a different
-     * channel.
-     */
-    if (freq->e > 1) {
-        return -EINVAL;
-    } else if (freq->e == 1) {
-        ar->arChannelHint = freq->m / 100000;
-    } else {
-        if(freq->m) {
-            ar->arChannelHint = wlan_ieee2freq(freq->m);
-        } else {
-            /* Auto Channel Selection */
-            ar->arChannelHint = 0;
-        }
-    }
-
-    ar->ap_profile_flag = 1; /* There is a change in profile */
-
-    A_PRINTF("channel hint set to %d\n", ar->arChannelHint);
-    return 0;
-}
-
-/*
- * SIOCGIWFREQ
- */
-int
-ar6000_ioctl_giwfreq(struct net_device *dev,
-                struct iw_request_info *info,
-                struct iw_freq *freq, char *extra)
-{
-    struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev);
-
-    if (is_iwioctl_allowed(ar->arNextMode, info->cmd) != 0) {
-        A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info->cmd);
-        return -EOPNOTSUPP;
-    }
-
-    if (ar->arWlanState == WLAN_DISABLED) {
-        return -EIO;
-    }
-
-    if (ar->arNetworkType == AP_NETWORK) {
-        if(ar->arChannelHint) {
-            freq->m = ar->arChannelHint * 100000;
-        } else if(ar->arACS) {
-            freq->m = ar->arACS * 100000;
-        } else {
-            return -EINVAL;
-        }
-    } else {
-        if (ar->arConnected != true) {
-            return -EINVAL;
-        } else {
-            freq->m = ar->arBssChannel * 100000;
-        }
-    }
-
-    freq->e = 1;
-
-    return 0;
-}
-
-/*
- * SIOCSIWMODE
- */
-int
-ar6000_ioctl_siwmode(struct net_device *dev,
-            struct iw_request_info *info,
-            __u32 *mode, char *extra)
-{
-    struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev);
-
-    if (is_iwioctl_allowed(ar->arNextMode, info->cmd) != 0) {
-        A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info->cmd);
-        return -EOPNOTSUPP;
-    }
-
-    if (ar->arWlanState == WLAN_DISABLED) {
-        return -EIO;
-    }
-
-    /*
-     * clear SSID during mode switch in connected state
-     */
-    if(!(ar->arNetworkType == (((*mode) == IW_MODE_INFRA) ? INFRA_NETWORK : ADHOC_NETWORK)) && (ar->arConnected == true) ){
-        A_MEMZERO(ar->arSsid, sizeof(ar->arSsid));
-        ar->arSsidLen = 0;
-    }
-
-    switch (*mode) {
-    case IW_MODE_INFRA:
-        ar->arNextMode = INFRA_NETWORK;
-        break;
-    case IW_MODE_ADHOC:
-        ar->arNextMode = ADHOC_NETWORK;
-        break;
-    case IW_MODE_MASTER:
-        ar->arNextMode = AP_NETWORK;
-        break;
-    default:
-        return -EINVAL;
-    }
-
-    /* clear all shared parameters between AP and STA|IBSS modes when we
-     * switch between them. Switch between STA & IBSS modes does'nt clear
-     * the shared profile. This is as per the original design for switching
-     * between STA & IBSS.
-     */
-    if (ar->arNetworkType == AP_NETWORK || ar->arNextMode == AP_NETWORK) {
-        ar->arDot11AuthMode      = OPEN_AUTH;
-        ar->arAuthMode           = NONE_AUTH;
-        ar->arPairwiseCrypto     = NONE_CRYPT;
-        ar->arPairwiseCryptoLen  = 0;
-        ar->arGroupCrypto        = NONE_CRYPT;
-        ar->arGroupCryptoLen     = 0;
-        ar->arChannelHint        = 0;
-        ar->arBssChannel         = 0;
-        A_MEMZERO(ar->arBssid, sizeof(ar->arBssid));
-        A_MEMZERO(ar->arSsid, sizeof(ar->arSsid));
-        ar->arSsidLen = 0;
-    }
-
-    /* SSID has to be cleared to trigger a profile change while switching
-     * between STA & IBSS modes having the same SSID
-     */
-    if (ar->arNetworkType != ar->arNextMode) {
-        A_MEMZERO(ar->arSsid, sizeof(ar->arSsid));
-        ar->arSsidLen = 0;
-    }
-
-    return 0;
-}
-
-/*
- * SIOCGIWMODE
- */
-int
-ar6000_ioctl_giwmode(struct net_device *dev,
-            struct iw_request_info *info,
-            __u32 *mode, char *extra)
-{
-    struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev);
-
-    if (is_iwioctl_allowed(ar->arNextMode, info->cmd) != 0) {
-        A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info->cmd);
-        return -EOPNOTSUPP;
-    }
-
-    if (ar->arWlanState == WLAN_DISABLED) {
-        return -EIO;
-    }
-
-    switch (ar->arNetworkType) {
-    case INFRA_NETWORK:
-        *mode = IW_MODE_INFRA;
-        break;
-    case ADHOC_NETWORK:
-        *mode = IW_MODE_ADHOC;
-        break;
-    case AP_NETWORK:
-        *mode = IW_MODE_MASTER;
-        break;
-    default:
-        return -EIO;
-    }
-    return 0;
-}
-
-/*
- * SIOCSIWSENS
- */
-int
-ar6000_ioctl_siwsens(struct net_device *dev,
-            struct iw_request_info *info,
-            struct iw_param *sens, char *extra)
-{
-    return 0;
-}
-
-/*
- * SIOCGIWSENS
- */
-int
-ar6000_ioctl_giwsens(struct net_device *dev,
-            struct iw_request_info *info,
-            struct iw_param *sens, char *extra)
-{
-    sens->value = 0;
-    sens->fixed = 1;
-
-    return 0;
-}
-
-/*
- * SIOCGIWRANGE
- */
-int
-ar6000_ioctl_giwrange(struct net_device *dev,
-             struct iw_request_info *info,
-             struct iw_point *data, char *extra)
-{
-    struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev);
-    struct iw_range *range = (struct iw_range *) extra;
-    int i, ret = 0;
-
-    if (is_iwioctl_allowed(ar->arNextMode, info->cmd) != 0) {
-        A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info->cmd);
-        return -EOPNOTSUPP;
-    }
-
-    if (ar->bIsDestroyProgress) {
-        return -EBUSY;
-    }
-
-    if (ar->arWmiReady == false) {
-        return -EIO;
-    }
-
-    if (down_interruptible(&ar->arSem)) {
-        return -ERESTARTSYS;
-    }
-
-    if (ar->bIsDestroyProgress) {
-        up(&ar->arSem);
-        return -EBUSY;
-    }
-
-    ar->arNumChannels = -1;
-    A_MEMZERO(ar->arChannelList, sizeof (ar->arChannelList));
-
-    if (wmi_get_channelList_cmd(ar->arWmi) != 0) {
-        up(&ar->arSem);
-        return -EIO;
-    }
-
-    wait_event_interruptible_timeout(arEvent, ar->arNumChannels != -1, wmitimeout * HZ);
-
-    if (signal_pending(current)) {
-        up(&ar->arSem);
-        return -EINTR;
-    }
-
-    data->length = sizeof(struct iw_range);
-    A_MEMZERO(range, sizeof(struct iw_range));
-
-    range->txpower_capa = 0;
-
-    range->min_pmp = 1 * 1024;
-    range->max_pmp = 65535 * 1024;
-    range->min_pmt = 1 * 1024;
-    range->max_pmt = 1000 * 1024;
-    range->pmp_flags = IW_POWER_PERIOD;
-    range->pmt_flags = IW_POWER_TIMEOUT;
-    range->pm_capa = 0;
-
-    range->we_version_compiled = WIRELESS_EXT;
-    range->we_version_source = 13;
-
-    range->retry_capa = IW_RETRY_LIMIT;
-    range->retry_flags = IW_RETRY_LIMIT;
-    range->min_retry = 0;
-    range->max_retry = 255;
-
-    range->num_frequency = range->num_channels = ar->arNumChannels;
-    for (i = 0; i < ar->arNumChannels; i++) {
-        range->freq[i].i = wlan_freq2ieee(ar->arChannelList[i]);
-        range->freq[i].m = ar->arChannelList[i] * 100000;
-        range->freq[i].e = 1;
-         /*
-         * Linux supports max of 32 channels, bail out once you
-         * reach the max.
-         */
-        if (i == IW_MAX_FREQUENCIES) {
-            break;
-        }
-    }
-
-    /* Max quality is max field value minus noise floor */
-    range->max_qual.qual  = 0xff - 161;
-
-    /*
-     * In order to use dBm measurements, 'level' must be lower
-     * than any possible measurement (see iw_print_stats() in
-     * wireless tools).  It's unclear how this is meant to be
-     * done, but setting zero in these values forces dBm and
-     * the actual numbers are not used.
-     */
-    range->max_qual.level = 0;
-    range->max_qual.noise = 0;
-
-    range->sensitivity = 3;
-
-    range->max_encoding_tokens = 4;
-    /* XXX query driver to find out supported key sizes */
-    range->num_encoding_sizes = 3;
-    range->encoding_size[0] = 5;        /* 40-bit */
-    range->encoding_size[1] = 13;       /* 104-bit */
-    range->encoding_size[2] = 16;       /* 128-bit */
-
-    range->num_bitrates = 0;
-
-    /* estimated maximum TCP throughput values (bps) */
-    range->throughput = 22000000;
-
-    range->min_rts = 0;
-    range->max_rts = 2347;
-    range->min_frag = 256;
-    range->max_frag = 2346;
-
-    up(&ar->arSem);
-
-    return ret;
-}
-
-
-/*
- * SIOCSIWAP
- * This ioctl is used to set the desired bssid for the connect command.
- */
-int
-ar6000_ioctl_siwap(struct net_device *dev,
-              struct iw_request_info *info,
-              struct sockaddr *ap_addr, char *extra)
-{
-    struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev);
-
-    if (is_iwioctl_allowed(ar->arNextMode, info->cmd) != 0) {
-        A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info->cmd);
-        return -EOPNOTSUPP;
-    }
-
-    if (ar->arWlanState == WLAN_DISABLED) {
-        return -EIO;
-    }
-
-    if (ap_addr->sa_family != ARPHRD_ETHER) {
-        return -EIO;
-    }
-
-    if (memcmp(&ap_addr->sa_data, bcast_mac, AR6000_ETH_ADDR_LEN) == 0) {
-        A_MEMZERO(ar->arReqBssid, sizeof(ar->arReqBssid));
-    } else {
-        memcpy(ar->arReqBssid, &ap_addr->sa_data,  sizeof(ar->arReqBssid));
-    }
-
-    return 0;
-}
-
-/*
- * SIOCGIWAP
- */
-int
-ar6000_ioctl_giwap(struct net_device *dev,
-              struct iw_request_info *info,
-              struct sockaddr *ap_addr, char *extra)
-{
-    struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev);
-
-    if (is_iwioctl_allowed(ar->arNextMode, info->cmd) != 0) {
-        A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info->cmd);
-        return -EOPNOTSUPP;
-    }
-
-    if (ar->arWlanState == WLAN_DISABLED) {
-        return -EIO;
-    }
-
-    if (ar->arNetworkType == AP_NETWORK) {
-        memcpy(&ap_addr->sa_data, dev->dev_addr, ATH_MAC_LEN);
-        ap_addr->sa_family = ARPHRD_ETHER;
-        return 0;
-    }
-
-    if (ar->arConnected != true) {
-        return -EINVAL;
-    }
-
-    memcpy(&ap_addr->sa_data, ar->arBssid, sizeof(ar->arBssid));
-    ap_addr->sa_family = ARPHRD_ETHER;
-
-    return 0;
-}
-
-#if (WIRELESS_EXT >= 18)
-/*
- * SIOCSIWMLME
- */
-int
-ar6000_ioctl_siwmlme(struct net_device *dev,
-            struct iw_request_info *info,
-            struct iw_point *data, char *extra)
-{
-    struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev);
-
-    if (is_iwioctl_allowed(ar->arNextMode, info->cmd) != 0) {
-        A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info->cmd);
-        return -EOPNOTSUPP;
-    }
-
-    if (ar->bIsDestroyProgress) {
-        return -EBUSY;
-    }
-
-    if (ar->arWlanState == WLAN_DISABLED) {
-        return -EIO;
-    }
-
-    if (ar->arWmiReady == false) {
-        return -EIO;
-    }
-
-    if (down_interruptible(&ar->arSem)) {
-        return -ERESTARTSYS;
-    }
-
-    if (data->pointer && data->length == sizeof(struct iw_mlme)) {
-
-        u8 arNetworkType;
-        struct iw_mlme mlme;
-
-        if (copy_from_user(&mlme, data->pointer, sizeof(struct iw_mlme)))
-            return -EIO;
-
-        switch (mlme.cmd) {
-
-            case IW_MLME_DEAUTH:
-                /* fall through */
-            case IW_MLME_DISASSOC:
-                if ((ar->arConnected != true) ||
-                    (memcmp(ar->arBssid, mlme.addr.sa_data, 6) != 0)) {
-
-                    up(&ar->arSem);
-                    return -EINVAL;
-                }
-                wmi_setPmkid_cmd(ar->arWmi, ar->arBssid, NULL, 0);
-                arNetworkType = ar->arNetworkType;
-                ar6000_init_profile_info(ar);
-                ar->arNetworkType = arNetworkType;
-                reconnect_flag = 0;
-                ar6000_disconnect(ar);
-                A_MEMZERO(ar->arSsid, sizeof(ar->arSsid));
-                ar->arSsidLen = 0;
-                if (ar->arSkipScan == false) {
-                    A_MEMZERO(ar->arReqBssid, sizeof(ar->arReqBssid));
-                }
-                break;
-
-            case IW_MLME_AUTH:
-                /* fall through */
-            case IW_MLME_ASSOC:
-                /* fall through */
-            default:
-                up(&ar->arSem);
-                return -EOPNOTSUPP;
-        }
-    }
-
-    up(&ar->arSem);
-    return 0;
-}
-#endif /* WIRELESS_EXT >= 18 */
-
-/*
- * SIOCGIWAPLIST
- */
-int
-ar6000_ioctl_iwaplist(struct net_device *dev,
-            struct iw_request_info *info,
-            struct iw_point *data, char *extra)
-{
-    return -EIO;            /* for now */
-}
-
-/*
- * SIOCSIWSCAN
- */
-int
-ar6000_ioctl_siwscan(struct net_device *dev,
-                     struct iw_request_info *info,
-                     struct iw_point *data, char *extra)
-{
-#define ACT_DWELLTIME_DEFAULT   105
-#define HOME_TXDRAIN_TIME       100
-#define SCAN_INT                HOME_TXDRAIN_TIME + ACT_DWELLTIME_DEFAULT
-    struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev);
-    int ret = 0;
-
-    if (is_iwioctl_allowed(ar->arNextMode, info->cmd) != 0) {
-        A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info->cmd);
-        return -EOPNOTSUPP;
-    }
-
-    if (ar->arWmiReady == false) {
-        return -EIO;
-    }
-
-    if (ar->arWlanState == WLAN_DISABLED) {
-        return -EIO;
-    }
-
-    /* If scan is issued in the middle of ongoing scan or connect,
-       dont issue another one */
-    if ( ar->scan_triggered > 0 ) {
-        ++ar->scan_triggered;
-        if (ar->scan_triggered < 5) {
-            return 0;
-        } else {
-            AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_SCAN,("Scan request is triggered over 5 times. Not scan complete event\n"));
-        }
-    } 
-
-    if (!ar->arUserBssFilter) {
-        if (wmi_bssfilter_cmd(ar->arWmi, ALL_BSS_FILTER, 0) != 0) {
-            return -EIO;
-        }
-    }
-
-    if (ar->arConnected) {
-        if  (wmi_get_stats_cmd(ar->arWmi) != 0) {
-            return -EIO;
-        }
-    }
-
-#ifdef ANDROID_ENV
-#if WIRELESS_EXT >= 18
-    if (data->pointer && (data->length == sizeof(struct iw_scan_req)))
-    {
-        if ((data->flags & IW_SCAN_THIS_ESSID) == IW_SCAN_THIS_ESSID)
-        {
-            struct iw_scan_req req;
-            if (copy_from_user(&req, data->pointer, sizeof(struct iw_scan_req)))
-                return -EIO;
-            if (wmi_probedSsid_cmd(ar->arWmi, 1, SPECIFIC_SSID_FLAG, req.essid_len, req.essid) != 0)
-                return -EIO;
-            ar->scanSpecificSsid = true;
-        }
-        else
-        {
-            if (ar->scanSpecificSsid) {
-                if (wmi_probedSsid_cmd(ar->arWmi, 1, DISABLE_SSID_FLAG, 0, NULL) != 0)
-                    return -EIO;
-                 ar->scanSpecificSsid = false;
-            }
-        }
-    }
-    else
-    {
-        if (ar->scanSpecificSsid) {
-            if (wmi_probedSsid_cmd(ar->arWmi, 1, DISABLE_SSID_FLAG, 0, NULL) != 0)
-                return -EIO;
-             ar->scanSpecificSsid = false;
-        }
-    }
-#endif
-#endif /* ANDROID_ENV */
-
-    if (wmi_startscan_cmd(ar->arWmi, WMI_LONG_SCAN, false, false, \
-                          0, 0, 0, NULL) != 0) {
-        ret = -EIO;
-    }
-
-    if (ret == 0) {
-        ar->scan_triggered = 1;
-    }
-
-    return ret;
-#undef  ACT_DWELLTIME_DEFAULT
-#undef HOME_TXDRAIN_TIME
-#undef SCAN_INT
-}
-
-
-/*
- * Units are in db above the noise floor. That means the
- * rssi values reported in the tx/rx descriptors in the
- * driver are the SNR expressed in db.
- *
- * If you assume that the noise floor is -95, which is an
- * excellent assumption 99.5 % of the time, then you can
- * derive the absolute signal level (i.e. -95 + rssi).
- * There are some other slight factors to take into account
- * depending on whether the rssi measurement is from 11b,
- * 11g, or 11a.   These differences are at most 2db and
- * can be documented.
- *
- * NB: various calculations are based on the orinoco/wavelan
- *     drivers for compatibility
- */
-static void
-ar6000_set_quality(struct iw_quality *iq, s8 rssi)
-{
-    if (rssi < 0) {
-        iq->qual = 0;
-    } else {
-        iq->qual = rssi;
-    }
-
-    /* NB: max is 94 because noise is hardcoded to 161 */
-    if (iq->qual > 94)
-        iq->qual = 94;
-
-    iq->noise = 161;        /* -95dBm */
-    iq->level = iq->noise + iq->qual;
-    iq->updated = 7;
-}
-
-
-int
-ar6000_ioctl_siwcommit(struct net_device *dev,
-                     struct iw_request_info *info,
-                     struct iw_point *data, char *extra)
-{
-    struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev);
-
-    if (is_iwioctl_allowed(ar->arNextMode, info->cmd) != 0) {
-        A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info->cmd);
-        return -EOPNOTSUPP;
-    }
-
-    if (ar->arWmiReady == false) {
-        return -EIO;
-    }
-
-    if (ar->arWlanState == WLAN_DISABLED) {
-        return -EIO;
-    }
-
-    AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_CONNECT,("AP: SSID %s freq %d authmode %d dot11 auth %d"\
-                    " PW crypto %d GRP crypto %d\n",
-                    ar->arSsid, ar->arChannelHint,
-                    ar->arAuthMode, ar->arDot11AuthMode,
-                    ar->arPairwiseCrypto, ar->arGroupCrypto));
-
-    ar6000_ap_mode_profile_commit(ar);
-
-    /* if there is a profile switch from STA|IBSS mode to AP mode,
-     * update the host driver association state for the STA|IBSS mode.
-     */
-    if (ar->arNetworkType != AP_NETWORK && ar->arNextMode == AP_NETWORK) {
-        /* Stop getting pkts from upper stack */
-        netif_stop_queue(ar->arNetDev);
-        A_MEMZERO(ar->arBssid, sizeof(ar->arBssid));
-        ar->arBssChannel = 0;
-        ar->arBeaconInterval = 0;
-
-        /* Flush the Tx queues */
-        ar6000_TxDataCleanup(ar);
-
-        /* Start getting pkts from upper stack */
-        netif_wake_queue(ar->arNetDev);
-    }
-
-    return 0;
-}
-
-#define W_PROTO(_x) wait_ ## _x
-#define WAIT_HANDLER_IMPL(_x, type) \
-int wait_ ## _x (struct net_device *dev, struct iw_request_info *info, type wrqu, char *extra) {\
-    int ret; \
-    dev_hold(dev); \
-    rtnl_unlock(); \
-    ret = _x(dev, info, wrqu, extra); \
-    rtnl_lock(); \
-    dev_put(dev); \
-    return ret;\
-}
-
-WAIT_HANDLER_IMPL(ar6000_ioctl_siwessid, struct iw_point *)
-WAIT_HANDLER_IMPL(ar6000_ioctl_giwrate, struct iw_param *)
-WAIT_HANDLER_IMPL(ar6000_ioctl_giwtxpow, struct iw_param *)
-WAIT_HANDLER_IMPL(ar6000_ioctl_giwrange, struct iw_point*)
-
-/* Structures to export the Wireless Handlers */
-static const iw_handler ath_handlers[] = {
-    (iw_handler) ar6000_ioctl_siwcommit,        /* SIOCSIWCOMMIT */
-    (iw_handler) ar6000_ioctl_giwname,          /* SIOCGIWNAME */
-    (iw_handler) NULL,                          /* SIOCSIWNWID */
-    (iw_handler) NULL,                          /* SIOCGIWNWID */
-    (iw_handler) ar6000_ioctl_siwfreq,          /* SIOCSIWFREQ */
-    (iw_handler) ar6000_ioctl_giwfreq,          /* SIOCGIWFREQ */
-    (iw_handler) ar6000_ioctl_siwmode,          /* SIOCSIWMODE */
-    (iw_handler) ar6000_ioctl_giwmode,          /* SIOCGIWMODE */
-    (iw_handler) ar6000_ioctl_siwsens,          /* SIOCSIWSENS */
-    (iw_handler) ar6000_ioctl_giwsens,          /* SIOCGIWSENS */
-    (iw_handler) NULL /* not _used */,          /* SIOCSIWRANGE */
-    (iw_handler) W_PROTO(ar6000_ioctl_giwrange),/* SIOCGIWRANGE */
-    (iw_handler) NULL /* not used */,           /* SIOCSIWPRIV */
-    (iw_handler) NULL /* kernel code */,        /* SIOCGIWPRIV */
-    (iw_handler) NULL /* not used */,           /* SIOCSIWSTATS */
-    (iw_handler) NULL /* kernel code */,        /* SIOCGIWSTATS */
-    (iw_handler) NULL,                          /* SIOCSIWSPY */
-    (iw_handler) NULL,                          /* SIOCGIWSPY */
-    (iw_handler) NULL,                          /* SIOCSIWTHRSPY */
-    (iw_handler) NULL,                          /* SIOCGIWTHRSPY */
-    (iw_handler) ar6000_ioctl_siwap,            /* SIOCSIWAP */
-    (iw_handler) ar6000_ioctl_giwap,            /* SIOCGIWAP */
-#if (WIRELESS_EXT >= 18)
-    (iw_handler) ar6000_ioctl_siwmlme,          /* SIOCSIWMLME */
-#else
-    (iw_handler) NULL,                          /* -- hole -- */
-#endif  /* WIRELESS_EXT >= 18 */
-    (iw_handler) ar6000_ioctl_iwaplist,         /* SIOCGIWAPLIST */
-    (iw_handler) ar6000_ioctl_siwscan,          /* SIOCSIWSCAN */
-    (iw_handler) ar6000_ioctl_giwscan,          /* SIOCGIWSCAN */
-    (iw_handler) W_PROTO(ar6000_ioctl_siwessid),/* SIOCSIWESSID */
-    (iw_handler) ar6000_ioctl_giwessid,         /* SIOCGIWESSID */
-    (iw_handler) NULL,                          /* SIOCSIWNICKN */
-    (iw_handler) NULL,                          /* SIOCGIWNICKN */
-    (iw_handler) NULL,                          /* -- hole -- */
-    (iw_handler) NULL,                          /* -- hole -- */
-    (iw_handler) ar6000_ioctl_siwrate,          /* SIOCSIWRATE */
-    (iw_handler) W_PROTO(ar6000_ioctl_giwrate), /* SIOCGIWRATE */
-    (iw_handler) NULL,                          /* SIOCSIWRTS */
-    (iw_handler) NULL,                          /* SIOCGIWRTS */
-    (iw_handler) NULL,                          /* SIOCSIWFRAG */
-    (iw_handler) NULL,                          /* SIOCGIWFRAG */
-    (iw_handler) ar6000_ioctl_siwtxpow,         /* SIOCSIWTXPOW */
-    (iw_handler) W_PROTO(ar6000_ioctl_giwtxpow),/* SIOCGIWTXPOW */
-    (iw_handler) ar6000_ioctl_siwretry,         /* SIOCSIWRETRY */
-    (iw_handler) ar6000_ioctl_giwretry,         /* SIOCGIWRETRY */
-    (iw_handler) ar6000_ioctl_siwencode,        /* SIOCSIWENCODE */
-    (iw_handler) ar6000_ioctl_giwencode,        /* SIOCGIWENCODE */
-#if WIRELESS_EXT > 20
-    (iw_handler) ar6000_ioctl_siwpower,         /* SIOCSIWPOWER */
-    (iw_handler) ar6000_ioctl_giwpower,         /* SIOCGIWPOWER */
-#endif // WIRELESS_EXT > 20
-#if WIRELESS_EXT >= 18
-    (iw_handler) NULL,                          /* -- hole -- */
-    (iw_handler) NULL,                          /* -- hole -- */
-    (iw_handler) ar6000_ioctl_siwgenie,         /* SIOCSIWGENIE */
-    (iw_handler) ar6000_ioctl_giwgenie,         /* SIOCGIWGENIE */
-    (iw_handler) ar6000_ioctl_siwauth,          /* SIOCSIWAUTH */
-    (iw_handler) ar6000_ioctl_giwauth,          /* SIOCGIWAUTH */
-    (iw_handler) ar6000_ioctl_siwencodeext,     /* SIOCSIWENCODEEXT */
-    (iw_handler) ar6000_ioctl_giwencodeext,     /* SIOCGIWENCODEEXT */
-    (iw_handler) ar6000_ioctl_siwpmksa,         /* SIOCSIWPMKSA */
-#endif // WIRELESS_EXT >= 18
-};
-
-struct iw_handler_def ath_iw_handler_def = {
-    .standard         = (iw_handler *)ath_handlers,
-    .num_standard     = ARRAY_SIZE(ath_handlers),
-    .private          = NULL,
-    .num_private      = 0,
-};
diff -druN linux-2.6.39-libre/drivers/staging/ath6kl/reorder/rcv_aggr.c linux-3.0-rc7-libre/drivers/staging/ath6kl/reorder/rcv_aggr.c
--- linux-2.6.39-libre/drivers/staging/ath6kl/reorder/rcv_aggr.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/ath6kl/reorder/rcv_aggr.c	2011-07-11 19:51:52.000000000 -0400
@@ -21,11 +21,8 @@
  *
  */
 
-#ifdef  ATH_AR6K_11N_SUPPORT
-
 #include <a_config.h>
 #include <athdefs.h>
-#include <a_types.h>
 #include <a_osapi.h>
 #include <a_debug.h>
 #include "pkt_log.h"
@@ -40,7 +37,7 @@
 aggr_slice_amsdu(struct aggr_info *p_aggr, struct rxtid *rxtid, void **osbuf);
 
 static void
-aggr_timeout(A_ATH_TIMER arg);
+aggr_timeout(unsigned long arg);
 
 static void
 aggr_deque_frms(struct aggr_info *p_aggr, u8 tid, u16 seq_no, u8 order);
@@ -123,7 +120,7 @@
     rxtid->hold_q_sz = 0;
 
     if(rxtid->hold_q) {
-        A_FREE(rxtid->hold_q);
+        kfree(rxtid->hold_q);
         rxtid->hold_q = NULL;
     }
 
@@ -154,7 +151,7 @@
                         A_NETBUF_FREE(rxtid->hold_q[k].osbuf);
                     }
                 }
-                A_FREE(rxtid->hold_q);
+                kfree(rxtid->hold_q);
             }
             /* Free the dispatch q contents*/
             while(A_NETBUF_QUEUE_SIZE(&rxtid->q)) {
@@ -168,7 +165,7 @@
         while(A_NETBUF_QUEUE_SIZE(&p_aggr->freeQ)) {
             A_NETBUF_FREE(A_NETBUF_DEQUEUE(&p_aggr->freeQ));
         }
-        A_FREE(p_aggr);
+        kfree(p_aggr);
     }
     A_PRINTF("out aggr_module_destroy\n");
 }
@@ -573,7 +570,7 @@
 
 
 static void
-aggr_timeout(A_ATH_TIMER arg)
+aggr_timeout(unsigned long arg)
 {
     u8 i,j;
     struct aggr_info *p_aggr = (struct aggr_info *)arg;
@@ -662,5 +659,3 @@
     A_PRINTF("================================================\n\n");
 
 }
-
-#endif  /* ATH_AR6K_11N_SUPPORT */
diff -druN linux-2.6.39-libre/drivers/staging/ath6kl/wlan/include/ieee80211.h linux-3.0-rc7-libre/drivers/staging/ath6kl/wlan/include/ieee80211.h
--- linux-2.6.39-libre/drivers/staging/ath6kl/wlan/include/ieee80211.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/ath6kl/wlan/include/ieee80211.h	2011-07-11 19:51:52.000000000 -0400
@@ -23,8 +23,6 @@
 #ifndef _NET80211_IEEE80211_H_
 #define _NET80211_IEEE80211_H_
 
-#include "athstartpack.h"
-
 /*
  * 802.11 protocol definitions.
  */
@@ -396,6 +394,4 @@
 
 #define IEEE80211_PS_MAX_QUEUE    50 /*Maximum no of buffers that can be queues for PS*/
 
-#include "athendpack.h"
-
 #endif /* _NET80211_IEEE80211_H_ */
diff -druN linux-2.6.39-libre/drivers/staging/ath6kl/wlan/src/wlan_node.c linux-3.0-rc7-libre/drivers/staging/ath6kl/wlan/src/wlan_node.c
--- linux-2.6.39-libre/drivers/staging/ath6kl/wlan/src/wlan_node.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/ath6kl/wlan/src/wlan_node.c	2011-07-11 19:51:52.000000000 -0400
@@ -24,7 +24,6 @@
 //==============================================================================
 #include <a_config.h>
 #include <athdefs.h>
-#include <a_types.h>
 #include <a_osapi.h>
 #define ATH_MODULE_NAME wlan
 #include <a_debug.h>
@@ -54,7 +53,7 @@
 #endif
 
 #ifdef THREAD_X
-static void wlan_node_timeout(A_ATH_TIMER arg);
+static void wlan_node_timeout(unsigned long arg);
 #endif
 
 static bss_t * _ieee80211_find_node (struct ieee80211_node_table *nt,
@@ -72,7 +71,7 @@
         {
         ni->ni_buf = A_MALLOC_NOWAIT(wh_size);
         if (ni->ni_buf == NULL) {
-            A_FREE(ni);
+            kfree(ni);
             ni = NULL;
             return ni;
         }
@@ -104,9 +103,9 @@
 wlan_node_free(bss_t *ni)
 {
     if (ni->ni_buf != NULL) {
-        A_FREE(ni->ni_buf);
+        kfree(ni->ni_buf);
     }
-    A_FREE(ni);
+    kfree(ni);
 }
 
 void
@@ -375,7 +374,7 @@
 
 #ifdef THREAD_X
 static void
-wlan_node_timeout (A_ATH_TIMER arg)
+wlan_node_timeout (unsigned long arg)
 {
     struct ieee80211_node_table *nt = (struct ieee80211_node_table *)arg;
     bss_t *bss, *nextBss;
diff -druN linux-2.6.39-libre/drivers/staging/ath6kl/wlan/src/wlan_recv_beacon.c linux-3.0-rc7-libre/drivers/staging/ath6kl/wlan/src/wlan_recv_beacon.c
--- linux-2.6.39-libre/drivers/staging/ath6kl/wlan/src/wlan_recv_beacon.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/ath6kl/wlan/src/wlan_recv_beacon.c	2011-07-11 19:51:52.000000000 -0400
@@ -25,7 +25,6 @@
 
 #include "a_config.h"
 #include "athdefs.h"
-#include "a_types.h"
 #include "a_osapi.h"
 #include <wmi.h>
 #include <ieee80211.h>
diff -druN linux-2.6.39-libre/drivers/staging/ath6kl/wlan/src/wlan_utils.c linux-3.0-rc7-libre/drivers/staging/ath6kl/wlan/src/wlan_utils.c
--- linux-2.6.39-libre/drivers/staging/ath6kl/wlan/src/wlan_utils.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/ath6kl/wlan/src/wlan_utils.c	2011-07-11 19:51:52.000000000 -0400
@@ -24,7 +24,6 @@
 //==============================================================================
 #include <a_config.h>
 #include <athdefs.h>
-#include <a_types.h>
 #include <a_osapi.h>
 
 /*
diff -druN linux-2.6.39-libre/drivers/staging/ath6kl/wmi/wmi.c linux-3.0-rc7-libre/drivers/staging/ath6kl/wmi/wmi.c
--- linux-2.6.39-libre/drivers/staging/ath6kl/wmi/wmi.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/ath6kl/wmi/wmi.c	2011-07-11 19:51:52.000000000 -0400
@@ -25,7 +25,6 @@
 
 #include <a_config.h>
 #include <athdefs.h>
-#include <a_types.h>
 #include <a_osapi.h>
 #include "htc.h"
 #include "htc_api.h"
@@ -35,7 +34,6 @@
 #include <ieee80211.h>
 #include <ieee80211_node.h>
 #include "dset_api.h"
-#include "gpio_api.h"
 #include "wmi_host.h"
 #include "a_drv.h"
 #include "a_drv_api.h"
@@ -129,14 +127,6 @@
 static int
 wmi_set_params_event_rx(struct wmi_t *wmip, u8 *datap, u32 len);
 
-static int
-wmi_acm_reject_event_rx(struct wmi_t *wmip, u8 *datap, u32 len);
-
-#ifdef CONFIG_HOST_GPIO_SUPPORT
-static int wmi_gpio_intr_rx(struct wmi_t *wmip, u8 *datap, int len);
-static int wmi_gpio_data_rx(struct wmi_t *wmip, u8 *datap, int len);
-static int wmi_gpio_ack_rx(struct wmi_t *wmip, u8 *datap, int len);
-#endif /* CONFIG_HOST_GPIO_SUPPORT */
 
 #ifdef CONFIG_HOST_TCMD_SUPPORT
 static int
@@ -187,13 +177,11 @@
 
 static int wmi_peer_node_event_rx (struct wmi_t *wmip, u8 *datap,
                                         int len);
-#ifdef ATH_AR6K_11N_SUPPORT
 static int wmi_addba_req_event_rx(struct wmi_t *, u8 *, int);
 static int wmi_addba_resp_event_rx(struct wmi_t *, u8 *, int);
 static int wmi_delba_req_event_rx(struct wmi_t *, u8 *, int);
 static int wmi_btcoex_config_event_rx(struct wmi_t *wmip, u8 *datap, int len);
 static int wmi_btcoex_stats_event_rx(struct wmi_t *wmip, u8 *datap, int len);
-#endif
 static int wmi_hci_event_rx(struct wmi_t *, u8 *, int);
 
 #ifdef WAPI_ENABLE
@@ -273,8 +261,6 @@
                 WMM_AC_VO,
             };
 
-#include "athstartpack.h"
-
 /* This stuff is used when we want a simple layer-3 visibility */
 typedef PREPACK struct _iphdr {
     u8 ip_ver_hdrlen;          /* version and hdr length */
@@ -292,8 +278,6 @@
     u8 ip_dst[4];
 } POSTPACK iphdr;
 
-#include "athendpack.h"
-
 static s16 rssi_event_value = 0;
 static s16 snr_event_value = 0;
 
@@ -381,7 +365,7 @@
             A_MUTEX_DELETE(&wmip->wmi_lock);
 #endif
         }
-        A_FREE(wmip);
+        kfree(wmip);
     }
 }
 
@@ -475,7 +459,6 @@
         	*pVersion = WMI_META_VERSION_1;
 		return (0);
     		}
-#ifdef CONFIG_CHECKSUM_OFFLOAD
 	case WMI_META_VERSION_2:
 		{
      		WMI_TX_META_V2 *pV2 ;
@@ -487,7 +470,6 @@
          	memcpy(pV2,(WMI_TX_META_V2 *)pTxMetaS,sizeof(WMI_TX_META_V2));
 		return (0);
     		}
-#endif
 	default:
 		return (0);
     }
@@ -525,7 +507,8 @@
     }
 
     WMI_DATA_HDR_SET_META(dtHdr, metaVersion);
-    //dtHdr->rssi = 0;
+
+    dtHdr->info3 = 0;
 
     return (0);
 }
@@ -865,17 +848,6 @@
         status = wmi_dset_data_req_rx(wmip, datap, len);
         break;
 #endif /* CONFIG_HOST_DSET_SUPPORT */
-#ifdef CONFIG_HOST_GPIO_SUPPORT
-    case (WMIX_GPIO_INTR_EVENTID):
-        wmi_gpio_intr_rx(wmip, datap, len);
-        break;
-    case (WMIX_GPIO_DATA_EVENTID):
-        wmi_gpio_data_rx(wmip, datap, len);
-        break;
-    case (WMIX_GPIO_ACK_EVENTID):
-        wmi_gpio_ack_rx(wmip, datap, len);
-        break;
-#endif /* CONFIG_HOST_GPIO_SUPPORT */
     case (WMIX_HB_CHALLENGE_RESP_EVENTID):
         wmi_hbChallengeResp_rx(wmip, datap, len);
         break;
@@ -967,23 +939,19 @@
     case (WMI_READY_EVENTID):
         A_DPRINTF(DBG_WMI, (DBGFMT "WMI_READY_EVENTID\n", DBGARG));
         status = wmi_ready_event_rx(wmip, datap, len);
-        A_WMI_SEND_EVENT_TO_APP(wmip->wmi_devt, id, datap, len);
         A_WMI_DBGLOG_INIT_DONE(wmip->wmi_devt);
         break;
     case (WMI_CONNECT_EVENTID):
         A_DPRINTF(DBG_WMI, (DBGFMT "WMI_CONNECT_EVENTID\n", DBGARG));
         status = wmi_connect_event_rx(wmip, datap, len);
-        A_WMI_SEND_GENERIC_EVENT_TO_APP(wmip->wmi_devt, id, datap, len);
         break;
     case (WMI_DISCONNECT_EVENTID):
         A_DPRINTF(DBG_WMI, (DBGFMT "WMI_DISCONNECT_EVENTID\n", DBGARG));
         status = wmi_disconnect_event_rx(wmip, datap, len);
-        A_WMI_SEND_EVENT_TO_APP(wmip->wmi_devt, id, datap, len);
         break;
     case (WMI_PEER_NODE_EVENTID):
         A_DPRINTF (DBG_WMI, (DBGFMT "WMI_PEER_NODE_EVENTID\n", DBGARG));
         status = wmi_peer_node_event_rx(wmip, datap, len);
-        A_WMI_SEND_EVENT_TO_APP(wmip->wmi_devt, id, datap, len);
         break;
     case (WMI_TKIP_MICERR_EVENTID):
         A_DPRINTF(DBG_WMI, (DBGFMT "WMI_TKIP_MICERR_EVENTID\n", DBGARG));
@@ -1014,7 +982,6 @@
             memcpy(bih->bssid, bih2.bssid, ATH_MAC_LEN);
 
             status = wmi_bssInfo_event_rx(wmip, datap, len);
-            A_WMI_SEND_GENERIC_EVENT_TO_APP(wmip->wmi_devt, id, datap, len);
         }
         break;
     case (WMI_REGDOMAIN_EVENTID):
@@ -1024,13 +991,6 @@
     case (WMI_PSTREAM_TIMEOUT_EVENTID):
         A_DPRINTF(DBG_WMI, (DBGFMT "WMI_PSTREAM_TIMEOUT_EVENTID\n", DBGARG));
         status = wmi_pstream_timeout_event_rx(wmip, datap, len);
-            /* pstreams are fatpipe abstractions that get implicitly created.
-             * User apps only deal with thinstreams. creation of a thinstream
-             * by the user or data traffic flow in an AC triggers implicit
-             * pstream creation. Do we need to send this event to App..?
-             * no harm in sending it.
-             */
-        A_WMI_SEND_EVENT_TO_APP(wmip->wmi_devt, id, datap, len);
         break;
     case (WMI_NEIGHBOR_REPORT_EVENTID):
         A_DPRINTF(DBG_WMI, (DBGFMT "WMI_NEIGHBOR_REPORT_EVENTID\n", DBGARG));
@@ -1039,7 +999,6 @@
     case (WMI_SCAN_COMPLETE_EVENTID):
         A_DPRINTF(DBG_WMI, (DBGFMT "WMI_SCAN_COMPLETE_EVENTID\n", DBGARG));
         status = wmi_scanComplete_rx(wmip, datap, len);
-        A_WMI_SEND_EVENT_TO_APP(wmip->wmi_devt, id, datap, len);
         break;
     case (WMI_CMDERROR_EVENTID):
         A_DPRINTF(DBG_WMI, (DBGFMT "WMI_CMDERROR_EVENTID\n", DBGARG));
@@ -1056,7 +1015,6 @@
     case (WMI_ERROR_REPORT_EVENTID):
         A_DPRINTF(DBG_WMI, (DBGFMT "WMI_ERROR_REPORT_EVENTID\n", DBGARG));
         status = wmi_reportErrorEvent_rx(wmip, datap, len);
-        A_WMI_SEND_EVENT_TO_APP(wmip->wmi_devt, id, datap, len);
         break;
     case (WMI_OPT_RX_FRAME_EVENTID):
         A_DPRINTF(DBG_WMI, (DBGFMT "WMI_OPT_RX_FRAME_EVENTID\n", DBGARG));
@@ -1095,7 +1053,6 @@
     case (WMI_TX_RETRY_ERR_EVENTID):
         A_DPRINTF(DBG_WMI, (DBGFMT "WMI_TX_RETRY_ERR_EVENTID\n", DBGARG));
         status = wmi_txRetryErrEvent_rx(wmip, datap, len);
-        A_WMI_SEND_EVENT_TO_APP(wmip->wmi_devt, id, datap, len);
         break;
     case (WMI_SNR_THRESHOLD_EVENTID):
         A_DPRINTF(DBG_WMI, (DBGFMT "WMI_SNR_THRESHOLD_EVENTID\n", DBGARG));
@@ -1104,7 +1061,6 @@
     case (WMI_LQ_THRESHOLD_EVENTID):
         A_DPRINTF(DBG_WMI, (DBGFMT "WMI_LQ_THRESHOLD_EVENTID\n", DBGARG));
         status = wmi_lqThresholdEvent_rx(wmip, datap, len);
-        A_WMI_SEND_EVENT_TO_APP(wmip->wmi_devt, id, datap, len);
         break;
     case (WMI_APLIST_EVENTID):
         AR_DEBUG_PRINTF(ATH_DEBUG_WMI, ("Received APLIST Event\n"));
@@ -1133,11 +1089,6 @@
         A_DPRINTF(DBG_WMI, (DBGFMT "WMI_SET_PARAMS_REPLY Event\n", DBGARG));
         status = wmi_set_params_event_rx(wmip, datap, len);
         break;
-    case (WMI_ACM_REJECT_EVENTID):
-        A_DPRINTF(DBG_WMI, (DBGFMT "WMI_SET_PARAMS_REPLY Event\n", DBGARG));
-        status = wmi_acm_reject_event_rx(wmip, datap, len);
-        break;		
-#ifdef ATH_AR6K_11N_SUPPORT
     case (WMI_ADDBA_REQ_EVENTID):
         status = wmi_addba_req_event_rx(wmip, datap, len);
         break;
@@ -1155,7 +1106,6 @@
 	    A_DPRINTF(DBG_WMI, (DBGFMT "WMI_BTCOEX_STATS_EVENTID", DBGARG));
     	status = wmi_btcoex_stats_event_rx(wmip, datap, len);
 	    break;
-#endif
     case (WMI_TX_COMPLETE_EVENTID):
         {
             int index;
@@ -1208,7 +1158,7 @@
 /* Send a "simple" extended wmi command -- one with no arguments.
    Enabling this command only if GPIO or profiling support is enabled.
    This is to suppress warnings on some platforms */
-#if defined(CONFIG_HOST_GPIO_SUPPORT) || defined(CONFIG_TARGET_PROFILE_SUPPORT)
+#if defined(CONFIG_TARGET_PROFILE_SUPPORT)
 static int
 wmi_simple_cmd_xtnd(struct wmi_t *wmip, WMIX_COMMAND_ID cmdid)
 {
@@ -2298,46 +2248,6 @@
     return 0;
 }
 
-#ifdef CONFIG_HOST_GPIO_SUPPORT
-static int
-wmi_gpio_intr_rx(struct wmi_t *wmip, u8 *datap, int len)
-{
-    WMIX_GPIO_INTR_EVENT *gpio_intr = (WMIX_GPIO_INTR_EVENT *)datap;
-
-    A_DPRINTF(DBG_WMI,
-        (DBGFMT "Enter - intrmask=0x%x input=0x%x.\n", DBGARG,
-        gpio_intr->intr_mask, gpio_intr->input_values));
-
-    A_WMI_GPIO_INTR_RX(gpio_intr->intr_mask, gpio_intr->input_values);
-
-    return 0;
-}
-
-static int
-wmi_gpio_data_rx(struct wmi_t *wmip, u8 *datap, int len)
-{
-    WMIX_GPIO_DATA_EVENT *gpio_data = (WMIX_GPIO_DATA_EVENT *)datap;
-
-    A_DPRINTF(DBG_WMI,
-        (DBGFMT "Enter - reg=%d value=0x%x\n", DBGARG,
-        gpio_data->reg_id, gpio_data->value));
-
-    A_WMI_GPIO_DATA_RX(gpio_data->reg_id, gpio_data->value);
-
-    return 0;
-}
-
-static int
-wmi_gpio_ack_rx(struct wmi_t *wmip, u8 *datap, int len)
-{
-    A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
-
-    A_WMI_GPIO_ACK_RX();
-
-    return 0;
-}
-#endif /* CONFIG_HOST_GPIO_SUPPORT */
-
 /*
  * Called to send a wmi command. Command specific data is already built
  * on osbuf and current osbuf->data points to it.
@@ -3075,6 +2985,7 @@
     dtHdr->info =
       (SYNC_MSGTYPE & WMI_DATA_HDR_MSG_TYPE_MASK) << WMI_DATA_HDR_MSG_TYPE_SHIFT;
 
+    dtHdr->info3 = 0;
     A_DPRINTF(DBG_WMI, (DBGFMT "Enter - eid %d\n", DBGARG, eid));
 
     return (A_WMI_CONTROL_TX(wmip->wmi_devt, osbuf, eid));
@@ -4282,132 +4193,6 @@
                          NO_SYNC_WMIFLAG));
 }
 
-#ifdef CONFIG_HOST_GPIO_SUPPORT
-/* Send a command to Target to change GPIO output pins. */
-int
-wmi_gpio_output_set(struct wmi_t *wmip,
-                    u32 set_mask,
-                    u32 clear_mask,
-                    u32 enable_mask,
-                    u32 disable_mask)
-{
-    void *osbuf;
-    WMIX_GPIO_OUTPUT_SET_CMD *output_set;
-    int size;
-
-    size = sizeof(*output_set);
-
-    A_DPRINTF(DBG_WMI,
-        (DBGFMT "Enter - set=0x%x clear=0x%x enb=0x%x dis=0x%x\n", DBGARG,
-        set_mask, clear_mask, enable_mask, disable_mask));
-
-    osbuf = A_NETBUF_ALLOC(size);
-    if (osbuf == NULL) {
-        return A_NO_MEMORY;
-    }
-    A_NETBUF_PUT(osbuf, size);
-    output_set = (WMIX_GPIO_OUTPUT_SET_CMD *)(A_NETBUF_DATA(osbuf));
-
-    output_set->set_mask                   = set_mask;
-    output_set->clear_mask                 = clear_mask;
-    output_set->enable_mask                = enable_mask;
-    output_set->disable_mask               = disable_mask;
-
-    return (wmi_cmd_send_xtnd(wmip, osbuf, WMIX_GPIO_OUTPUT_SET_CMDID,
-                             NO_SYNC_WMIFLAG));
-}
-
-/* Send a command to the Target requesting state of the GPIO input pins */
-int
-wmi_gpio_input_get(struct wmi_t *wmip)
-{
-    A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
-
-    return wmi_simple_cmd_xtnd(wmip, WMIX_GPIO_INPUT_GET_CMDID);
-}
-
-/* Send a command to the Target that changes the value of a GPIO register. */
-int
-wmi_gpio_register_set(struct wmi_t *wmip,
-                      u32 gpioreg_id,
-                      u32 value)
-{
-    void *osbuf;
-    WMIX_GPIO_REGISTER_SET_CMD *register_set;
-    int size;
-
-    size = sizeof(*register_set);
-
-    A_DPRINTF(DBG_WMI,
-        (DBGFMT "Enter - reg=%d value=0x%x\n", DBGARG, gpioreg_id, value));
-
-    osbuf = A_NETBUF_ALLOC(size);
-    if (osbuf == NULL) {
-        return A_NO_MEMORY;
-    }
-    A_NETBUF_PUT(osbuf, size);
-    register_set = (WMIX_GPIO_REGISTER_SET_CMD *)(A_NETBUF_DATA(osbuf));
-
-    register_set->gpioreg_id               = gpioreg_id;
-    register_set->value                    = value;
-
-    return (wmi_cmd_send_xtnd(wmip, osbuf, WMIX_GPIO_REGISTER_SET_CMDID,
-                             NO_SYNC_WMIFLAG));
-}
-
-/* Send a command to the Target to fetch the value of a GPIO register. */
-int
-wmi_gpio_register_get(struct wmi_t *wmip,
-                      u32 gpioreg_id)
-{
-    void *osbuf;
-    WMIX_GPIO_REGISTER_GET_CMD *register_get;
-    int size;
-
-    size = sizeof(*register_get);
-
-    A_DPRINTF(DBG_WMI, (DBGFMT "Enter - reg=%d\n", DBGARG, gpioreg_id));
-
-    osbuf = A_NETBUF_ALLOC(size);
-    if (osbuf == NULL) {
-        return A_NO_MEMORY;
-    }
-    A_NETBUF_PUT(osbuf, size);
-    register_get = (WMIX_GPIO_REGISTER_GET_CMD *)(A_NETBUF_DATA(osbuf));
-
-    register_get->gpioreg_id               = gpioreg_id;
-
-    return (wmi_cmd_send_xtnd(wmip, osbuf, WMIX_GPIO_REGISTER_GET_CMDID,
-                             NO_SYNC_WMIFLAG));
-}
-
-/* Send a command to the Target acknowledging some GPIO interrupts. */
-int
-wmi_gpio_intr_ack(struct wmi_t *wmip,
-                  u32 ack_mask)
-{
-    void *osbuf;
-    WMIX_GPIO_INTR_ACK_CMD *intr_ack;
-    int size;
-
-    size = sizeof(*intr_ack);
-
-    A_DPRINTF(DBG_WMI, (DBGFMT "Enter ack_mask=0x%x\n", DBGARG, ack_mask));
-
-    osbuf = A_NETBUF_ALLOC(size);
-    if (osbuf == NULL) {
-        return A_NO_MEMORY;
-    }
-    A_NETBUF_PUT(osbuf, size);
-    intr_ack = (WMIX_GPIO_INTR_ACK_CMD *)(A_NETBUF_DATA(osbuf));
-
-    intr_ack->ack_mask               = ack_mask;
-
-    return (wmi_cmd_send_xtnd(wmip, osbuf, WMIX_GPIO_INTR_ACK_CMDID,
-                             NO_SYNC_WMIFLAG));
-}
-#endif /* CONFIG_HOST_GPIO_SUPPORT */
-
 int
 wmi_set_access_params_cmd(struct wmi_t *wmip, u8 ac,  u16 txop, u8 eCWmin,
                           u8 eCWmax, u8 aifsn)
@@ -4683,8 +4468,6 @@
 
    A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG));
 
-   A_WMI_TCMD_RX_REPORT_EVENT(wmip->wmi_devt, datap, len);
-
    return 0;
 }
 
@@ -5500,19 +5283,6 @@
 }
 
 
-
-static int
-wmi_acm_reject_event_rx(struct wmi_t *wmip, u8 *datap, u32 len)
-{
-    WMI_ACM_REJECT_EVENT *ev;
-
-    ev = (WMI_ACM_REJECT_EVENT *)datap;
-    wmip->wmi_traffic_class = ev->trafficClass;
-    printk("ACM REJECT %d\n",wmip->wmi_traffic_class);
-    return 0;
-}
-
-
 #ifdef CONFIG_HOST_DSET_SUPPORT
 int
 wmi_dset_data_reply(struct wmi_t *wmip,
@@ -5877,7 +5647,7 @@
 
     ar6000_scan_indication (wmip->wmi_devt, pAr6kScanIndEvent, size);
 
-    A_FREE(pAr6kScanIndEvent);
+    kfree(pAr6kScanIndEvent);
 }
 #endif
 
@@ -5995,7 +5765,6 @@
     return 0;
 }
 
-#ifdef ATH_AR6K_11N_SUPPORT
 static int
 wmi_addba_req_event_rx(struct wmi_t *wmip, u8 *datap, int len)
 {
@@ -6048,7 +5817,6 @@
      return 0;
 
 }
-#endif
 
 static int
 wmi_hci_event_rx(struct wmi_t *wmip, u8 *datap, int len)
@@ -6372,7 +6140,6 @@
     return (wmi_cmd_send(wmip, osbuf, WMI_AP_SET_11BG_RATESET_CMDID, NO_SYNC_WMIFLAG));
 }
 
-#ifdef ATH_AR6K_11N_SUPPORT
 int
 wmi_set_ht_cap_cmd(struct wmi_t *wmip, WMI_SET_HT_CAP_CMD *cmd)
 {
@@ -6418,7 +6185,6 @@
     return (wmi_cmd_send(wmip, osbuf, WMI_SET_HT_OP_CMDID,
                          NO_SYNC_WMIFLAG));
 }
-#endif
 
 int
 wmi_set_tx_select_rates_cmd(struct wmi_t *wmip, u32 *pMaskArray)
@@ -6460,7 +6226,6 @@
     return (wmi_cmd_send(wmip, osbuf, WMI_HCI_CMD_CMDID, NO_SYNC_WMIFLAG));
 }
 
-#ifdef ATH_AR6K_11N_SUPPORT
 int
 wmi_allow_aggr_cmd(struct wmi_t *wmip, u16 tx_tidmask, u16 rx_tidmask)
 {
@@ -6520,7 +6285,6 @@
     /* Delete the local aggr state, on host */
     return (wmi_cmd_send(wmip, osbuf, WMI_DELBA_REQ_CMDID, NO_SYNC_WMIFLAG));
 }
-#endif
 
 int
 wmi_set_rx_frame_format_cmd(struct wmi_t *wmip, u8 rxMetaVersion,
diff -druN linux-2.6.39-libre/drivers/staging/brcm80211/brcmfmac/bcmchip.h linux-3.0-rc7-libre/drivers/staging/brcm80211/brcmfmac/bcmchip.h
--- linux-2.6.39-libre/drivers/staging/brcm80211/brcmfmac/bcmchip.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/staging/brcm80211/brcmfmac/bcmchip.h	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2011 Broadcom Corporation
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef _bcmchip_h_
+#define _bcmchip_h_
+
+/* Core reg address translation */
+#define CORE_CC_REG(base, field)	(base + offsetof(chipcregs_t, field))
+#define CORE_BUS_REG(base, field)	(base + offsetof(sdpcmd_regs_t, field))
+#define CORE_SB(base, field) \
+		(base + SBCONFIGOFF + offsetof(sbconfig_t, field))
+
+/* bcm4329 */
+/* SDIO device core, ID 0x829 */
+#define BCM4329_CORE_BUS_BASE		0x18011000
+/* internal memory core, ID 0x80e */
+#define BCM4329_CORE_SOCRAM_BASE	0x18003000
+/* ARM Cortex M3 core, ID 0x82a */
+#define BCM4329_CORE_ARM_BASE		0x18002000
+#define BCM4329_RAMSIZE			0x48000
+
+#endif				/* _bcmchip_h_ */
diff -druN linux-2.6.39-libre/drivers/staging/brcm80211/brcmfmac/bcmsdh.c linux-3.0-rc7-libre/drivers/staging/brcm80211/brcmfmac/bcmsdh.c
--- linux-2.6.39-libre/drivers/staging/brcm80211/brcmfmac/bcmsdh.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/brcm80211/brcmfmac/bcmsdh.c	2011-07-11 19:51:52.000000000 -0400
@@ -17,11 +17,11 @@
 
 #include <linux/types.h>
 #include <linux/netdevice.h>
+#include <linux/pci_ids.h>
 #include <bcmdefs.h>
 #include <bcmdevs.h>
 #include <bcmutils.h>
 #include <hndsoc.h>
-#include <siutils.h>
 
 #include <bcmsdh.h>		/* BRCM API for SDIO
 			 clients (such as wl, dhd) */
@@ -29,6 +29,8 @@
 #include <sbsdio.h>		/* BRCM sdio device core */
 
 #include <sdio.h>		/* sdio spec */
+#include "dngl_stats.h"
+#include "dhd.h"
 
 #define SDIOH_API_ACCESS_RETRY_LIMIT	2
 const uint bcmsdh_msglevel = BCMSDH_ERROR_VAL;
@@ -126,7 +128,7 @@
 	ASSERT(bcmsdh);
 
 	status = sdioh_interrupt_set(bcmsdh->sdioh, true);
-	return SDIOH_API_SUCCESS(status) ? 0 : BCME_ERROR;
+	return SDIOH_API_SUCCESS(status) ? 0 : -EIO;
 }
 
 int bcmsdh_intr_disable(void *sdh)
@@ -136,7 +138,7 @@
 	ASSERT(bcmsdh);
 
 	status = sdioh_interrupt_set(bcmsdh->sdioh, false);
-	return SDIOH_API_SUCCESS(status) ? 0 : BCME_ERROR;
+	return SDIOH_API_SUCCESS(status) ? 0 : -EIO;
 }
 
 int bcmsdh_intr_reg(void *sdh, bcmsdh_cb_fn_t fn, void *argh)
@@ -146,7 +148,7 @@
 	ASSERT(bcmsdh);
 
 	status = sdioh_interrupt_register(bcmsdh->sdioh, fn, argh);
-	return SDIOH_API_SUCCESS(status) ? 0 : BCME_ERROR;
+	return SDIOH_API_SUCCESS(status) ? 0 : -EIO;
 }
 
 int bcmsdh_intr_dereg(void *sdh)
@@ -156,7 +158,7 @@
 	ASSERT(bcmsdh);
 
 	status = sdioh_interrupt_deregister(bcmsdh->sdioh);
-	return SDIOH_API_SUCCESS(status) ? 0 : BCME_ERROR;
+	return SDIOH_API_SUCCESS(status) ? 0 : -EIO;
 }
 
 #if defined(DHD_DEBUG)
@@ -174,7 +176,7 @@
 	ASSERT(sdh);
 
 	/* don't support yet */
-	return BCME_UNSUPPORTED;
+	return -ENOTSUPP;
 }
 
 u8 bcmsdh_cfg_read(void *sdh, uint fnc_num, u32 addr, int *err)
@@ -204,7 +206,7 @@
 		 && (retry++ < SDIOH_API_ACCESS_RETRY_LIMIT));
 #endif
 	if (err)
-		*err = (SDIOH_API_SUCCESS(status) ? 0 : BCME_SDIO_ERROR);
+		*err = (SDIOH_API_SUCCESS(status) ? 0 : -EIO);
 
 	BCMSDH_INFO(("%s:fun = %d, addr = 0x%x, u8data = 0x%x\n",
 		     __func__, fnc_num, addr, data));
@@ -239,7 +241,7 @@
 		 && (retry++ < SDIOH_API_ACCESS_RETRY_LIMIT));
 #endif
 	if (err)
-		*err = SDIOH_API_SUCCESS(status) ? 0 : BCME_SDIO_ERROR;
+		*err = SDIOH_API_SUCCESS(status) ? 0 : -EIO;
 
 	BCMSDH_INFO(("%s:fun = %d, addr = 0x%x, u8data = 0x%x\n",
 		     __func__, fnc_num, addr, data));
@@ -261,7 +263,7 @@
 			       fnc_num, addr, &data, 4);
 
 	if (err)
-		*err = (SDIOH_API_SUCCESS(status) ? 0 : BCME_SDIO_ERROR);
+		*err = (SDIOH_API_SUCCESS(status) ? 0 : -EIO);
 
 	BCMSDH_INFO(("%s:fun = %d, addr = 0x%x, u32data = 0x%x\n",
 		     __func__, fnc_num, addr, data));
@@ -286,7 +288,7 @@
 			       SDIOH_WRITE, fnc_num, addr, &data, 4);
 
 	if (err)
-		*err = (SDIOH_API_SUCCESS(status) ? 0 : BCME_SDIO_ERROR);
+		*err = (SDIOH_API_SUCCESS(status) ? 0 : -EIO);
 
 	BCMSDH_INFO(("%s:fun = %d, addr = 0x%x, u32data = 0x%x\n",
 		     __func__, fnc_num, addr, data));
@@ -317,7 +319,7 @@
 		tmp_buf = kmalloc(length, GFP_ATOMIC);
 		if (tmp_buf == NULL) {
 			BCMSDH_ERROR(("%s: out of memory\n", __func__));
-			return BCME_NOMEM;
+			return -ENOMEM;
 		}
 		memcpy(tmp_buf, cis, length);
 		for (tmp_ptr = tmp_buf, ptr = cis; ptr < (cis + length - 4);
@@ -329,7 +331,7 @@
 		kfree(tmp_buf);
 	}
 
-	return SDIOH_API_SUCCESS(status) ? 0 : BCME_ERROR;
+	return SDIOH_API_SUCCESS(status) ? 0 : -EIO;
 }
 
 static int bcmsdhsdio_set_sbaddr_window(void *sdh, u32 address)
@@ -467,7 +469,7 @@
 	/* Async not implemented yet */
 	ASSERT(!(flags & SDIO_REQ_ASYNC));
 	if (flags & SDIO_REQ_ASYNC)
-		return BCME_UNSUPPORTED;
+		return -ENOTSUPP;
 
 	if (bar0 != bcmsdh->sbwad) {
 		err = bcmsdhsdio_set_sbaddr_window(bcmsdh, bar0);
@@ -488,7 +490,7 @@
 				      SDIOH_READ, fn, addr, width, nbytes, buf,
 				      pkt);
 
-	return SDIOH_API_SUCCESS(status) ? 0 : BCME_SDIO_ERROR;
+	return SDIOH_API_SUCCESS(status) ? 0 : -EIO;
 }
 
 int
@@ -512,7 +514,7 @@
 	/* Async not implemented yet */
 	ASSERT(!(flags & SDIO_REQ_ASYNC));
 	if (flags & SDIO_REQ_ASYNC)
-		return BCME_UNSUPPORTED;
+		return -ENOTSUPP;
 
 	if (bar0 != bcmsdh->sbwad) {
 		err = bcmsdhsdio_set_sbaddr_window(bcmsdh, bar0);
@@ -533,7 +535,7 @@
 				      SDIOH_WRITE, fn, addr, width, nbytes, buf,
 				      pkt);
 
-	return SDIOH_API_SUCCESS(status) ? 0 : BCME_ERROR;
+	return SDIOH_API_SUCCESS(status) ? 0 : -EIO;
 }
 
 int bcmsdh_rwdata(void *sdh, uint rw, u32 addr, u8 *buf, uint nbytes)
@@ -553,7 +555,7 @@
 				 (rw ? SDIOH_WRITE : SDIOH_READ), SDIO_FUNC_1,
 				 addr, 4, nbytes, buf, NULL);
 
-	return SDIOH_API_SUCCESS(status) ? 0 : BCME_ERROR;
+	return SDIOH_API_SUCCESS(status) ? 0 : -EIO;
 }
 
 int bcmsdh_abort(void *sdh, uint fn)
@@ -580,7 +582,7 @@
 int bcmsdh_query_device(void *sdh)
 {
 	bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *) sdh;
-	bcmsdh->vendevid = (VENDOR_BROADCOM << 16) | 0;
+	bcmsdh->vendevid = (PCI_VENDOR_ID_BROADCOM << 16) | 0;
 	return bcmsdh->vendevid;
 }
 
diff -druN linux-2.6.39-libre/drivers/staging/brcm80211/brcmfmac/bcmsdh_linux.c linux-3.0-rc7-libre/drivers/staging/brcm80211/brcmfmac/bcmsdh_linux.c
--- linux-2.6.39-libre/drivers/staging/brcm80211/brcmfmac/bcmsdh_linux.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/brcm80211/brcmfmac/bcmsdh_linux.c	2011-07-11 19:51:52.000000000 -0400
@@ -43,6 +43,9 @@
 #include <linux/platform_device.h>
 #endif				/* CONFIG_MACH_SANDGATE2G */
 
+#include "dngl_stats.h"
+#include "dhd.h"
+
 /**
  * SDIO Host Controller info
  */
@@ -87,11 +90,11 @@
 		return true;
 
 	/* Check for BRCM 27XX Standard host controller */
-	if (device == BCM27XX_SDIOH_ID && vendor == VENDOR_BROADCOM)
+	if (device == BCM27XX_SDIOH_ID && vendor == PCI_VENDOR_ID_BROADCOM)
 		return true;
 
 	/* Check for BRCM Standard host controller */
-	if (device == SDIOH_FPGA_ID && vendor == VENDOR_BROADCOM)
+	if (device == SDIOH_FPGA_ID && vendor == PCI_VENDOR_ID_BROADCOM)
 		return true;
 
 	/* Check for TI PCIxx21 Standard host controller */
@@ -111,8 +114,7 @@
 #endif				/* BCMSDIOH_STD */
 #ifdef BCMSDIOH_SPI
 	/* This is the PciSpiHost. */
-	if (device == SPIH_FPGA_ID && vendor == VENDOR_BROADCOM) {
-		WL_NONE("Found PCI SPI Host Controller\n");
+	if (device == SPIH_FPGA_ID && vendor == PCI_VENDOR_ID_BROADCOM) {
 		return true;
 	}
 #endif				/* BCMSDIOH_SPI */
diff -druN linux-2.6.39-libre/drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc.c linux-3.0-rc7-libre/drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc.c
--- linux-2.6.39-libre/drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc.c	2011-07-11 19:51:52.000000000 -0400
@@ -26,14 +26,11 @@
 #include <linux/mmc/core.h>
 #include <linux/mmc/sdio_func.h>
 #include <linux/mmc/sdio_ids.h>
+#include <linux/suspend.h>
 
 #include <dngl_stats.h>
 #include <dhd.h>
 
-#if defined(CONFIG_PM_SLEEP)
-#include <linux/suspend.h>
-extern volatile bool dhd_mmc_suspend;
-#endif
 #include "bcmsdh_sdmmc.h"
 
 extern int sdio_function_init(void);
@@ -68,6 +65,13 @@
 int sdioh_sdmmc_card_regread(sdioh_info_t *sd, int func, u32 regaddr,
 			     int regsize, u32 *data);
 
+void sdioh_sdio_set_host_pm_flags(int flag)
+{
+	if (sdio_set_host_pm_flags(gInstance->func[1], flag))
+		printk(KERN_ERR "%s: Failed to set pm_flags 0x%08x\n",\
+			 __func__, (unsigned int)flag);
+}
+
 static int sdioh_sdmmc_card_enablefuncs(sdioh_info_t *sd)
 {
 	int err_ret;
@@ -416,7 +420,7 @@
 
 	vi = bcm_iovar_lookup(sdioh_iovars, name);
 	if (vi == NULL) {
-		bcmerror = BCME_UNSUPPORTED;
+		bcmerror = -ENOTSUPP;
 		goto exit;
 	}
 
@@ -465,7 +469,7 @@
 
 	case IOV_GVAL(IOV_BLOCKSIZE):
 		if ((u32) int_val > si->num_funcs) {
-			bcmerror = BCME_BADARG;
+			bcmerror = -EINVAL;
 			break;
 		}
 		int_val = (s32) si->client_block_size[int_val];
@@ -479,7 +483,7 @@
 			uint maxsize;
 
 			if (func > si->num_funcs) {
-				bcmerror = BCME_BADARG;
+				bcmerror = -EINVAL;
 				break;
 			}
 
@@ -497,7 +501,7 @@
 				maxsize = 0;
 			}
 			if (blksize > maxsize) {
-				bcmerror = BCME_BADARG;
+				bcmerror = -EINVAL;
 				break;
 			}
 			if (!blksize)
@@ -600,7 +604,7 @@
 			    || sd_ptr->offset > SD_MaxCurCap) {
 				sd_err(("%s: bad offset 0x%x\n", __func__,
 					sd_ptr->offset));
-				bcmerror = BCME_BADARG;
+				bcmerror = -EINVAL;
 				break;
 			}
 
@@ -630,7 +634,7 @@
 			    || sd_ptr->offset > SD_MaxCurCap) {
 				sd_err(("%s: bad offset 0x%x\n", __func__,
 					sd_ptr->offset));
-				bcmerror = BCME_BADARG;
+				bcmerror = -EINVAL;
 				break;
 			}
 
@@ -649,7 +653,7 @@
 
 			if (sdioh_cfg_read
 			    (si, sd_ptr->func, sd_ptr->offset, &data)) {
-				bcmerror = BCME_SDIO_ERROR;
+				bcmerror = -EIO;
 				break;
 			}
 
@@ -665,14 +669,14 @@
 
 			if (sdioh_cfg_write
 			    (si, sd_ptr->func, sd_ptr->offset, &data)) {
-				bcmerror = BCME_SDIO_ERROR;
+				bcmerror = -EIO;
 				break;
 			}
 			break;
 		}
 
 	default:
-		bcmerror = BCME_UNSUPPORTED;
+		bcmerror = -ENOTSUPP;
 		break;
 	}
 exit:
@@ -1006,17 +1010,16 @@
 
 /*
  * This function takes a buffer or packet, and fixes everything up
- * so that in the
- * end, a DMA-able packet is created.
+ * so that in the end, a DMA-able packet is created.
  *
  * A buffer does not have an associated packet pointer,
  * and may or may not be aligned.
  * A packet may consist of a single packet, or a packet chain.
- * If it is a packet chain,
- * then all the packets in the chain must be properly aligned.
- * If the packet data is not
- * aligned, then there may only be one packet, and in this case,
- * it is copied to a new
+ * If it is a packet chain, then all the packets in the chain
+ * must be properly aligned.
+ *
+ * If the packet data is not aligned, then there may only be
+ * one packet, and in this case,  it is copied to a new
  * aligned packet.
  *
  */
@@ -1036,9 +1039,9 @@
 	if (pkt == NULL) {
 		sd_data(("%s: Creating new %s Packet, len=%d\n",
 			 __func__, write ? "TX" : "RX", buflen_u));
-		mypkt = pkt_buf_get_skb(buflen_u);
+		mypkt = bcm_pkt_buf_get_skb(buflen_u);
 		if (!mypkt) {
-			sd_err(("%s: pkt_buf_get_skb failed: len %d\n",
+			sd_err(("%s: bcm_pkt_buf_get_skb failed: len %d\n",
 				__func__, buflen_u));
 			return SDIOH_API_RC_FAIL;
 		}
@@ -1054,7 +1057,7 @@
 		if (!write)
 			memcpy(buffer, mypkt->data, buflen_u);
 
-		pkt_buf_free_skb(mypkt);
+		bcm_pkt_buf_free_skb(mypkt);
 	} else if (((u32) (pkt->data) & DMA_ALIGN_MASK) != 0) {
 		/* Case 2: We have a packet, but it is unaligned. */
 
@@ -1063,9 +1066,9 @@
 
 		sd_data(("%s: Creating aligned %s Packet, len=%d\n",
 			 __func__, write ? "TX" : "RX", pkt->len));
-		mypkt = pkt_buf_get_skb(pkt->len);
+		mypkt = bcm_pkt_buf_get_skb(pkt->len);
 		if (!mypkt) {
-			sd_err(("%s: pkt_buf_get_skb failed: len %d\n",
+			sd_err(("%s: bcm_pkt_buf_get_skb failed: len %d\n",
 				__func__, pkt->len));
 			return SDIOH_API_RC_FAIL;
 		}
@@ -1081,7 +1084,7 @@
 		if (!write)
 			memcpy(pkt->data, mypkt->data, mypkt->len);
 
-		pkt_buf_free_skb(mypkt);
+		bcm_pkt_buf_free_skb(mypkt);
 	} else {		/* case 3: We have a packet and
 				 it is aligned. */
 		sd_data(("%s: Aligned %s Packet, direct DMA\n",
diff -druN linux-2.6.39-libre/drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc_linux.c linux-3.0-rc7-libre/drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc_linux.c
--- linux-2.6.39-libre/drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc_linux.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc_linux.c	2011-07-11 19:51:52.000000000 -0400
@@ -27,6 +27,9 @@
 #include <linux/mmc/sdio_func.h>
 #include <linux/mmc/sdio_ids.h>
 
+#include "dngl_stats.h"
+#include "dhd.h"
+
 #if !defined(SDIO_VENDOR_ID_BROADCOM)
 #define SDIO_VENDOR_ID_BROADCOM		0x02d0
 #endif				/* !defined(SDIO_VENDOR_ID_BROADCOM) */
@@ -151,11 +154,11 @@
 	sdos = kmalloc(sizeof(struct sdos_info), GFP_ATOMIC);
 	sd->sdos_info = (void *)sdos;
 	if (sdos == NULL)
-		return BCME_NOMEM;
+		return -ENOMEM;
 
 	sdos->sd = sd;
 	spin_lock_init(&sdos->lock);
-	return BCME_OK;
+	return 0;
 }
 
 void sdioh_sdmmc_osfree(sdioh_info_t *sd)
diff -druN linux-2.6.39-libre/drivers/staging/brcm80211/brcmfmac/bcmutils.c linux-3.0-rc7-libre/drivers/staging/brcm80211/brcmfmac/bcmutils.c
--- linux-2.6.39-libre/drivers/staging/brcm80211/brcmfmac/bcmutils.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/brcm80211/brcmfmac/bcmutils.c	1969-12-31 19:00:00.000000000 -0500
@@ -1 +0,0 @@
-#include "../util/bcmutils.c"
diff -druN linux-2.6.39-libre/drivers/staging/brcm80211/brcmfmac/bcmwifi.c linux-3.0-rc7-libre/drivers/staging/brcm80211/brcmfmac/bcmwifi.c
--- linux-2.6.39-libre/drivers/staging/brcm80211/brcmfmac/bcmwifi.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/brcm80211/brcmfmac/bcmwifi.c	1969-12-31 19:00:00.000000000 -0500
@@ -1 +0,0 @@
-#include "../util/bcmwifi.c"
diff -druN linux-2.6.39-libre/drivers/staging/brcm80211/brcmfmac/dhd_cdc.c linux-3.0-rc7-libre/drivers/staging/brcm80211/brcmfmac/dhd_cdc.c
--- linux-2.6.39-libre/drivers/staging/brcm80211/brcmfmac/dhd_cdc.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/brcm80211/brcmfmac/dhd_cdc.c	2011-07-11 19:51:52.000000000 -0400
@@ -111,7 +111,7 @@
 	/* Respond "bcmerror" and "bcmerrorstr" with local cache */
 	if (cmd == WLC_GET_VAR && buf) {
 		if (!strcmp((char *)buf, "bcmerrorstr")) {
-			strncpy((char *)buf, bcmerrorstr(dhd->dongle_error),
+			strncpy((char *)buf, "bcm_error",
 				BCME_STRLEN);
 			goto done;
 		} else if (!strcmp((char *)buf, "bcmerror")) {
@@ -253,9 +253,9 @@
 			"lastcmd=0x%x (%lu)\n",
 			ioc->cmd, (unsigned long)ioc->cmd, prot->lastcmd,
 			(unsigned long)prot->lastcmd));
-		if ((ioc->cmd == WLC_SET_VAR) || (ioc->cmd == WLC_GET_VAR)) {
+		if ((ioc->cmd == WLC_SET_VAR) || (ioc->cmd == WLC_GET_VAR))
 			DHD_TRACE(("iovar cmd=%s\n", (char *)buf));
-		}
+
 		goto done;
 	}
 
@@ -309,7 +309,7 @@
 dhd_prot_iovar_op(dhd_pub_t *dhdp, const char *name,
 		  void *params, int plen, void *arg, int len, bool set)
 {
-	return BCME_UNSUPPORTED;
+	return -ENOTSUPP;
 }
 
 void dhd_prot_dump(dhd_pub_t *dhdp, struct bcmstrbuf *strbuf)
@@ -357,7 +357,7 @@
 	if (pktbuf->len < BDC_HEADER_LEN) {
 		DHD_ERROR(("%s: rx data too short (%d < %d)\n", __func__,
 			   pktbuf->len, BDC_HEADER_LEN));
-		return BCME_ERROR;
+		return -EBADE;
 	}
 
 	h = (struct bdc_header *)(pktbuf->data);
@@ -366,14 +366,14 @@
 	if (*ifidx >= DHD_MAX_IFS) {
 		DHD_ERROR(("%s: rx data ifnum out of range (%d)\n",
 			   __func__, *ifidx));
-		return BCME_ERROR;
+		return -EBADE;
 	}
 
 	if (((h->flags & BDC_FLAG_VER_MASK) >> BDC_FLAG_VER_SHIFT) !=
 	    BDC_PROTO_VER) {
 		DHD_ERROR(("%s: non-BDC packet received, flags 0x%x\n",
 			   dhd_ifname(dhd, *ifidx), h->flags));
-		return BCME_ERROR;
+		return -EBADE;
 	}
 
 	if (h->flags & BDC_FLAG_SUM_GOOD) {
@@ -416,7 +416,7 @@
 
 fail:
 	kfree(cdc);
-	return BCME_NOMEM;
+	return -ENOMEM;
 }
 
 /* ~NOTE~ What if another thread is waiting on the semaphore?  Holding it? */
diff -druN linux-2.6.39-libre/drivers/staging/brcm80211/brcmfmac/dhd_common.c linux-3.0-rc7-libre/drivers/staging/brcm80211/brcmfmac/dhd_common.c
--- linux-2.6.39-libre/drivers/staging/brcm80211/brcmfmac/dhd_common.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/brcm80211/brcmfmac/dhd_common.c	2011-07-11 19:51:52.000000000 -0400
@@ -189,7 +189,7 @@
 	/* Add any bus info */
 	dhd_bus_dump(dhdp, strbuf);
 
-	return !strbuf->size ? BCME_BUFTOOSHORT : 0;
+	return !strbuf->size ? -EOVERFLOW : 0;
 }
 
 static int
@@ -225,7 +225,7 @@
 		break;
 
 	case IOV_GVAL(IOV_BCMERRORSTR):
-		strncpy((char *)arg, bcmerrorstr(dhd_pub->bcmerror),
+		strncpy((char *)arg, "bcm_error",
 			BCME_STRLEN);
 		((char *)arg)[BCME_STRLEN - 1] = 0x00;
 		break;
@@ -242,7 +242,7 @@
 
 	case IOV_SVAL(IOV_WDTICK):
 		if (!dhd_pub->up) {
-			bcmerror = BCME_NOTUP;
+			bcmerror = -ENOLINK;
 			break;
 		}
 		dhd_os_wd_timer(dhd_pub, (uint) int_val);
@@ -289,7 +289,7 @@
 
 	case IOV_SVAL(IOV_IOCTLTIMEOUT):{
 			if (int_val <= 0)
-				bcmerror = BCME_BADARG;
+				bcmerror = -EINVAL;
 			else
 				dhd_os_set_ioctl_resp_timeout((unsigned int)
 							      int_val);
@@ -297,7 +297,7 @@
 		}
 
 	default:
-		bcmerror = BCME_UNSUPPORTED;
+		bcmerror = -ENOTSUPP;
 		break;
 	}
 
@@ -316,7 +316,7 @@
 	 * exceeding total queue length
 	 */
 	if (!pktq_pfull(q, prec) && !pktq_full(q)) {
-		pktq_penq(q, prec, pkt);
+		bcm_pktq_penq(q, prec, pkt);
 		return true;
 	}
 
@@ -324,7 +324,7 @@
 	if (pktq_pfull(q, prec))
 		eprec = prec;
 	else if (pktq_full(q)) {
-		p = pktq_peek_tail(q, &eprec);
+		p = bcm_pktq_peek_tail(q, &eprec);
 		ASSERT(p);
 		if (eprec > prec)
 			return false;
@@ -338,21 +338,21 @@
 		if (eprec == prec && !discard_oldest)
 			return false;	/* refuse newer (incoming) packet */
 		/* Evict packet according to discard policy */
-		p = discard_oldest ? pktq_pdeq(q, eprec) : pktq_pdeq_tail(q,
-						  eprec);
+		p = discard_oldest ? bcm_pktq_pdeq(q, eprec) :
+			bcm_pktq_pdeq_tail(q, eprec);
 		if (p == NULL) {
-			DHD_ERROR(("%s: pktq_penq() failed, oldest %d.",
+			DHD_ERROR(("%s: bcm_pktq_penq() failed, oldest %d.",
 				   __func__, discard_oldest));
 			ASSERT(p);
 		}
 
-		pkt_buf_free_skb(p);
+		bcm_pkt_buf_free_skb(p);
 	}
 
 	/* Enqueue */
-	p = pktq_penq(q, prec, pkt);
+	p = bcm_pktq_penq(q, prec, pkt);
 	if (p == NULL) {
-		DHD_ERROR(("%s: pktq_penq() failed.", __func__));
+		DHD_ERROR(("%s: bcm_pktq_penq() failed.", __func__));
 		ASSERT(p);
 	}
 
@@ -381,7 +381,7 @@
 
 	vi = bcm_iovar_lookup(dhd_iovars, name);
 	if (vi == NULL) {
-		bcmerror = BCME_UNSUPPORTED;
+		bcmerror = -ENOTSUPP;
 		goto exit;
 	}
 
@@ -420,19 +420,19 @@
 	DHD_TRACE(("%s: Enter\n", __func__));
 
 	if (!buf)
-		return BCME_BADARG;
+		return -EINVAL;
 
 	switch (ioc->cmd) {
 	case DHD_GET_MAGIC:
 		if (buflen < sizeof(int))
-			bcmerror = BCME_BUFTOOSHORT;
+			bcmerror = -EOVERFLOW;
 		else
 			*(int *)buf = DHD_IOCTL_MAGIC;
 		break;
 
 	case DHD_GET_VERSION:
 		if (buflen < sizeof(int))
-			bcmerror = -BCME_BUFTOOSHORT;
+			bcmerror = -EOVERFLOW;
 		else
 			*(int *)buf = DHD_IOCTL_VERSION;
 		break;
@@ -448,7 +448,7 @@
 				;
 
 			if (*arg) {
-				bcmerror = BCME_BUFTOOSHORT;
+				bcmerror = -EOVERFLOW;
 				break;
 			}
 
@@ -464,7 +464,7 @@
 				bcmerror =
 				    dhd_iovar_op(dhd_pub, buf, NULL, 0, arg,
 						 arglen, IOV_SET);
-			if (bcmerror != BCME_UNSUPPORTED)
+			if (bcmerror != -ENOTSUPP)
 				break;
 
 			/* not in generic table, try protocol module */
@@ -476,7 +476,7 @@
 				bcmerror = dhd_prot_iovar_op(dhd_pub, buf,
 							     NULL, 0, arg,
 							     arglen, IOV_SET);
-			if (bcmerror != BCME_UNSUPPORTED)
+			if (bcmerror != -ENOTSUPP)
 				break;
 
 			/* if still not found, try bus module */
@@ -493,7 +493,7 @@
 		}
 
 	default:
-		bcmerror = BCME_UNSUPPORTED;
+		bcmerror = -ENOTSUPP;
 	}
 
 	return bcmerror;
@@ -586,6 +586,8 @@
 	}
 
 	DHD_EVENT(("EVENT: %s, event ID = %d\n", event_name, event_type));
+	DHD_EVENT(("flags 0x%04x, status %d, reason %d, auth_type %d MAC %s\n",
+				flags, status, reason, auth_type, eabuf));
 
 	if (flags & WLC_EVENT_MSG_LINK)
 		link = true;
@@ -815,14 +817,14 @@
 
 	if (memcmp(BRCM_OUI, &pvt_data->bcm_hdr.oui[0], DOT11_OUI_LEN)) {
 		DHD_ERROR(("%s: mismatched OUI, bailing\n", __func__));
-		return BCME_ERROR;
+		return -EBADE;
 	}
 
 	/* BRCM event pkt may be unaligned - use xxx_ua to load user_subtype. */
 	if (get_unaligned_be16(&pvt_data->bcm_hdr.usr_subtype) !=
 	    BCMILCP_BCM_SUBTYPE_EVENT) {
 		DHD_ERROR(("%s: mismatched subtype, bailing\n", __func__));
-		return BCME_ERROR;
+		return -EBADE;
 	}
 
 	*data_ptr = &pvt_data[1];
@@ -902,7 +904,7 @@
 	wl_show_host_event(event, event_data);
 #endif				/* SHOW_EVENTS */
 
-	return BCME_OK;
+	return 0;
 }
 
 /* Convert user's input in hex pattern to byte-size mask */
diff -druN linux-2.6.39-libre/drivers/staging/brcm80211/brcmfmac/dhd.h linux-3.0-rc7-libre/drivers/staging/brcm80211/brcmfmac/dhd.h
--- linux-2.6.39-libre/drivers/staging/brcm80211/brcmfmac/dhd.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/brcm80211/brcmfmac/dhd.h	2011-07-11 19:51:52.000000000 -0400
@@ -31,6 +31,7 @@
 #include <linux/random.h>
 #include <linux/spinlock.h>
 #include <linux/ethtool.h>
+#include <linux/suspend.h>
 #include <asm/uaccess.h>
 #include <asm/unaligned.h>
 /* The kernel threading is sdio-specific */
@@ -122,19 +123,22 @@
 } dhd_pub_t;
 
 #if defined(CONFIG_PM_SLEEP)
-
+extern atomic_t dhd_mmc_suspend;
 #define DHD_PM_RESUME_WAIT_INIT(a) DECLARE_WAIT_QUEUE_HEAD(a);
-#define _DHD_PM_RESUME_WAIT(a, b) do {\
-			int retry = 0; \
-			while (dhd_mmc_suspend && retry++ != b) { \
-				wait_event_timeout(a, false, HZ/100); \
-			} \
-		}	while (0)
+#define _DHD_PM_RESUME_WAIT(a, b) do { \
+		int retry = 0; \
+		while (atomic_read(&dhd_mmc_suspend) && retry++ != b) { \
+			wait_event_timeout(a, false, HZ/100); \
+		} \
+	}	while (0)
 #define DHD_PM_RESUME_WAIT(a)	_DHD_PM_RESUME_WAIT(a, 30)
 #define DHD_PM_RESUME_WAIT_FOREVER(a)	_DHD_PM_RESUME_WAIT(a, ~0)
 #define DHD_PM_RESUME_RETURN_ERROR(a)	\
-	do { if (dhd_mmc_suspend) return a; } while (0)
-#define DHD_PM_RESUME_RETURN	do { if (dhd_mmc_suspend) return; } while (0)
+	do { if (atomic_read(&dhd_mmc_suspend)) return a; } while (0)
+#define DHD_PM_RESUME_RETURN	do { \
+	if (atomic_read(&dhd_mmc_suspend)) \
+		return; \
+	} while (0)
 
 #define DHD_SPINWAIT_SLEEP_INIT(a) DECLARE_WAIT_QUEUE_HEAD(a);
 #define SPINWAIT_SLEEP(a, exp, us) do { \
@@ -397,4 +401,14 @@
 extern void dhd_wait_for_event(dhd_pub_t *dhd, bool * lockvar);
 extern void dhd_wait_event_wakeup(dhd_pub_t *dhd);
 
+extern u32 g_assert_type;
+
+#ifdef BCMDBG
+#define ASSERT(exp) \
+	  do { if (!(exp)) osl_assert(#exp, __FILE__, __LINE__); } while (0)
+extern void osl_assert(char *exp, char *file, int line);
+#else
+#define ASSERT(exp)	do {} while (0)
+#endif  /* defined(BCMDBG) */
+
 #endif				/* _dhd_h_ */
diff -druN linux-2.6.39-libre/drivers/staging/brcm80211/brcmfmac/dhd_linux.c linux-3.0-rc7-libre/drivers/staging/brcm80211/brcmfmac/dhd_linux.c
--- linux-2.6.39-libre/drivers/staging/brcm80211/brcmfmac/dhd_linux.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/brcm80211/brcmfmac/dhd_linux.c	2011-07-11 19:51:52.000000000 -0400
@@ -166,7 +166,7 @@
 
 #if defined(CONFIG_PM_SLEEP)
 #include <linux/suspend.h>
-volatile bool dhd_mmc_suspend = false;
+atomic_t dhd_mmc_suspend;
 DECLARE_WAIT_QUEUE_HEAD(dhd_dpc_wait);
 #endif	/*  defined(CONFIG_PM_SLEEP) */
 
@@ -325,7 +325,7 @@
 uint dhd_radio_up = 1;
 
 /* Network inteface name */
-char iface_name[IFNAMSIZ];
+char iface_name[IFNAMSIZ] = "wlan";
 module_param_string(iface_name, iface_name, IFNAMSIZ, 0);
 
 /* The following are specific to the SDIO dongle */
@@ -385,10 +385,6 @@
 #define DHD_COMPILED
 #endif
 
-#if defined(CONFIG_WIRELESS_EXT)
-struct iw_statistics *dhd_get_wireless_stats(struct net_device *dev);
-#endif				/* defined(CONFIG_WIRELESS_EXT) */
-
 static void dhd_dpc(unsigned long data);
 /* forward decl */
 extern int dhd_wait_pend8021x(struct net_device *dev);
@@ -411,11 +407,11 @@
 	switch (action) {
 	case PM_HIBERNATION_PREPARE:
 	case PM_SUSPEND_PREPARE:
-		dhd_mmc_suspend = true;
+		atomic_set(&dhd_mmc_suspend, true);
 		return NOTIFY_OK;
 	case PM_POST_HIBERNATION:
 	case PM_POST_SUSPEND:
-		dhd_mmc_suspend = false;
+		atomic_set(&dhd_mmc_suspend, false);
 		return NOTIFY_OK;
 	}
 	return 0;
@@ -1619,51 +1615,6 @@
 	return 0;
 }
 
-static s16 linuxbcmerrormap[] = { 0,	/* 0 */
-	-EINVAL,		/* BCME_ERROR */
-	-EINVAL,		/* BCME_BADARG */
-	-EINVAL,		/* BCME_BADOPTION */
-	-EINVAL,		/* BCME_NOTUP */
-	-EINVAL,		/* BCME_NOTDOWN */
-	-EINVAL,		/* BCME_NOTAP */
-	-EINVAL,		/* BCME_NOTSTA */
-	-EINVAL,		/* BCME_BADKEYIDX */
-	-EINVAL,		/* BCME_RADIOOFF */
-	-EINVAL,		/* BCME_NOTBANDLOCKED */
-	-EINVAL,		/* BCME_NOCLK */
-	-EINVAL,		/* BCME_BADRATESET */
-	-EINVAL,		/* BCME_BADBAND */
-	-E2BIG,			/* BCME_BUFTOOSHORT */
-	-E2BIG,			/* BCME_BUFTOOLONG */
-	-EBUSY,			/* BCME_BUSY */
-	-EINVAL,		/* BCME_NOTASSOCIATED */
-	-EINVAL,		/* BCME_BADSSIDLEN */
-	-EINVAL,		/* BCME_OUTOFRANGECHAN */
-	-EINVAL,		/* BCME_BADCHAN */
-	-EFAULT,		/* BCME_BADADDR */
-	-ENOMEM,		/* BCME_NORESOURCE */
-	-EOPNOTSUPP,		/* BCME_UNSUPPORTED */
-	-EMSGSIZE,		/* BCME_BADLENGTH */
-	-EINVAL,		/* BCME_NOTREADY */
-	-EPERM,			/* BCME_NOTPERMITTED */
-	-ENOMEM,		/* BCME_NOMEM */
-	-EINVAL,		/* BCME_ASSOCIATED */
-	-ERANGE,		/* BCME_RANGE */
-	-EINVAL,		/* BCME_NOTFOUND */
-	-EINVAL,		/* BCME_WME_NOT_ENABLED */
-	-EINVAL,		/* BCME_TSPEC_NOTFOUND */
-	-EINVAL,		/* BCME_ACM_NOTSUPPORTED */
-	-EINVAL,		/* BCME_NOT_WME_ASSOCIATION */
-	-EIO,			/* BCME_SDIO_ERROR */
-	-ENODEV,		/* BCME_DONGLE_DOWN */
-	-EINVAL,		/* BCME_VERSION */
-	-EIO,			/* BCME_TXFAIL */
-	-EIO,			/* BCME_RXFAIL */
-	-EINVAL,		/* BCME_NODEVICE */
-	-EINVAL,		/* BCME_NMODE_DISABLED */
-	-ENODATA,		/* BCME_NONRESIDENT */
-};
-
 static int dhd_ioctl_entry(struct net_device *net, struct ifreq *ifr, int cmd)
 {
 	dhd_info_t *dhd = *(dhd_info_t **) netdev_priv(net);
@@ -1699,7 +1650,7 @@
 
 	/* Copy the ioc control structure part of ioctl request */
 	if (copy_from_user(&ioc, ifr->ifr_data, sizeof(wl_ioctl_t))) {
-		bcmerror = -BCME_BADADDR;
+		bcmerror = -EINVAL;
 		goto done;
 	}
 
@@ -1715,11 +1666,11 @@
 		{
 			buf = kmalloc(buflen, GFP_ATOMIC);
 			if (!buf) {
-				bcmerror = -BCME_NOMEM;
+				bcmerror = -ENOMEM;
 				goto done;
 			}
 			if (copy_from_user(buf, ioc.buf, buflen)) {
-				bcmerror = -BCME_BADADDR;
+				bcmerror = -EINVAL;
 				goto done;
 			}
 		}
@@ -1728,12 +1679,12 @@
 	/* To differentiate between wl and dhd read 4 more byes */
 	if ((copy_from_user(&driver, (char *)ifr->ifr_data + sizeof(wl_ioctl_t),
 			    sizeof(uint)) != 0)) {
-		bcmerror = -BCME_BADADDR;
+		bcmerror = -EINVAL;
 		goto done;
 	}
 
 	if (!capable(CAP_NET_ADMIN)) {
-		bcmerror = -BCME_EPERM;
+		bcmerror = -EPERM;
 		goto done;
 	}
 
@@ -1748,12 +1699,12 @@
 	/* send to dongle (must be up, and wl) */
 	if ((dhd->pub.busstate != DHD_BUS_DATA)) {
 		DHD_ERROR(("%s DONGLE_DOWN,__func__\n", __func__));
-		bcmerror = BCME_DONGLE_DOWN;
+		bcmerror = -EIO;
 		goto done;
 	}
 
 	if (!dhd->pub.iswl) {
-		bcmerror = BCME_DONGLE_DOWN;
+		bcmerror = -EIO;
 		goto done;
 	}
 
@@ -1781,10 +1732,8 @@
 
 	if (bcmerror > 0)
 		bcmerror = 0;
-	else if (bcmerror < BCME_LAST)
-		bcmerror = BCME_ERROR;
 
-	return linuxbcmerrormap[-bcmerror];
+	return bcmerror;
 }
 
 static int dhd_stop(struct net_device *net)
@@ -1997,7 +1946,6 @@
 			strcpy(fw_path, wl_cfg80211_get_fwname());
 			strcpy(nv_path, wl_cfg80211_get_nvramname());
 		}
-		wl_cfg80211_dbg_level(DBG_CFG80211_GET());
 	}
 
 	/* Set up the watchdog timer */
@@ -2062,7 +2010,9 @@
 	g_bus = bus;
 #endif
 #if defined(CONFIG_PM_SLEEP)
-	register_pm_notifier(&dhd_sleep_pm_notifier);
+	atomic_set(&dhd_mmc_suspend, false);
+	if (!IS_CFG80211_FAVORITE())
+		register_pm_notifier(&dhd_sleep_pm_notifier);
 #endif	/* defined(CONFIG_PM_SLEEP) */
 	/* && defined(DHD_GPL) */
 	/* Init lock suspend to prevent kernel going to suspend */
@@ -2252,18 +2202,6 @@
 	net->hard_header_len = ETH_HLEN + dhd->pub.hdrlen;
 	net->ethtool_ops = &dhd_ethtool_ops;
 
-#if defined(CONFIG_WIRELESS_EXT)
-	if (!IS_CFG80211_FAVORITE()) {
-#if WIRELESS_EXT < 19
-		net->get_wireless_stats = dhd_get_wireless_stats;
-#endif				/* WIRELESS_EXT < 19 */
-#if WIRELESS_EXT > 12
-		net->wireless_handlers =
-		    (struct iw_handler_def *)&wl_iw_handler_def;
-#endif				/* WIRELESS_EXT > 12 */
-	}
-#endif				/* defined(CONFIG_WIRELESS_EXT) */
-
 	dhd->pub.rxsz = net->mtu + net->hard_header_len + dhd->pub.hdrlen;
 
 	memcpy(net->dev_addr, temp_addr, ETH_ALEN);
@@ -2280,7 +2218,7 @@
 
 fail:
 	net->netdev_ops = NULL;
-	return BCME_ERROR;
+	return -EBADE;
 }
 
 void dhd_bus_detach(dhd_pub_t *dhdp)
@@ -2368,7 +2306,8 @@
 				wl_cfg80211_detach();
 
 #if defined(CONFIG_PM_SLEEP)
-			unregister_pm_notifier(&dhd_sleep_pm_notifier);
+			if (!IS_CFG80211_FAVORITE())
+				unregister_pm_notifier(&dhd_sleep_pm_notifier);
 #endif	/* defined(CONFIG_PM_SLEEP) */
 			/* && defined(DHD_GPL) */
 			free_netdev(ifp->net);
@@ -2670,21 +2609,6 @@
 	dhd_os_sdunlock(pub);
 }
 
-#if defined(CONFIG_WIRELESS_EXT)
-struct iw_statistics *dhd_get_wireless_stats(struct net_device *dev)
-{
-	int res = 0;
-	dhd_info_t *dhd = *(dhd_info_t **) netdev_priv(dev);
-
-	res = wl_iw_get_wireless_stats(dev, &dhd->iw.wstats);
-
-	if (res == 0)
-		return &dhd->iw.wstats;
-	else
-		return NULL;
-}
-#endif	/* defined(CONFIG_WIRELESS_EXT) */
-
 static int
 dhd_wl_host_event(dhd_info_t *dhd, int *ifidx, void *pktdata,
 		  wl_event_msg_t *event, void **data)
@@ -2694,7 +2618,7 @@
 	ASSERT(dhd != NULL);
 
 	bcmerror = wl_host_event(dhd, ifidx, pktdata, event, data);
-	if (bcmerror != BCME_OK)
+	if (bcmerror != 0)
 		return bcmerror;
 
 #if defined(CONFIG_WIRELESS_EXT)
@@ -2894,6 +2818,13 @@
 	return pend;
 }
 
+void wl_os_wd_timer(struct net_device *ndev, uint wdtick)
+{
+	dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(ndev);
+
+	dhd_os_wd_timer(&dhd->pub, wdtick);
+}
+
 #ifdef DHD_DEBUG
 int write_to_file(dhd_pub_t *dhd, u8 *buf, int size)
 {
diff -druN linux-2.6.39-libre/drivers/staging/brcm80211/brcmfmac/dhd_sdio.c linux-3.0-rc7-libre/drivers/staging/brcm80211/brcmfmac/dhd_sdio.c
--- linux-2.6.39-libre/drivers/staging/brcm80211/brcmfmac/dhd_sdio.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/brcm80211/brcmfmac/dhd_sdio.c	2011-07-11 19:51:52.000000000 -0400
@@ -15,8 +15,11 @@
  */
 
 #include <linux/types.h>
-#include <bcmdefs.h>
+#include <linux/kernel.h>
+#include <linux/printk.h>
+#include <linux/pci_ids.h>
 #include <linux/netdevice.h>
+#include <bcmdefs.h>
 #include <bcmsdh.h>
 
 #ifdef BCMEMBEDIMAGE
@@ -27,8 +30,6 @@
 #include <bcmutils.h>
 #include <bcmdevs.h>
 
-#include <siutils.h>
-#include <hndpmu.h>
 #include <hndsoc.h>
 #ifdef DHD_DEBUG
 #include <hndrte_armtrap.h>
@@ -51,7 +52,7 @@
 #include <dhd_dbg.h>
 #include <dhdioctl.h>
 #include <sdiovar.h>
-#include <siutils_priv.h>
+#include <bcmchip.h>
 
 #ifndef DHDSDIO_MEM_DUMP_FNAME
 #define DHDSDIO_MEM_DUMP_FNAME         "mem_dump"
@@ -136,12 +137,6 @@
 /* Flags for SDH calls */
 #define F2SYNC	(SDIO_REQ_4BYTE | SDIO_REQ_FIXED)
 
-/* Packet free applicable unconditionally for sdio and sdspi.  Conditional if
- * bufpool was present for gspi bus.
- */
-#define PKTFREE2()		if ((bus->bus != SPI_BUS) || bus->usebufpool) \
-							pkt_buf_free_skb(pkt);
-
 /*
  * Conversion of 802.1D priority to precedence level
  */
@@ -165,12 +160,28 @@
 } dhd_console_t;
 #endif				/* DHD_DEBUG */
 
+/* misc chip info needed by some of the routines */
+struct chip_info {
+	u32 chip;
+	u32 chiprev;
+	u32 cccorebase;
+	u32 ccrev;
+	u32 cccaps;
+	u32 buscorebase;
+	u32 buscorerev;
+	u32 buscoretype;
+	u32 ramcorebase;
+	u32 armcorebase;
+	u32 pmurev;
+	u32 ramsize;
+};
+
 /* Private data for SDIO bus interaction */
 typedef struct dhd_bus {
 	dhd_pub_t *dhd;
 
 	bcmsdh_info_t *sdh;	/* Handle for BCMSDH calls */
-	si_t *sih;		/* Handle for SI calls */
+	struct chip_info *ci;	/* Chip info struct */
 	char *vars;		/* Variables (from CIS and/or other) */
 	uint varsz;		/* Size of variables buffer */
 	u32 sbaddr;		/* Current SB window pointer (-1, invalid) */
@@ -421,8 +432,6 @@
 
 #define HOSTINTMASK		(I_HMB_SW_MASK | I_CHIPACTIVE)
 
-#define GSPI_PR55150_BAILOUT
-
 #ifdef SDTEST
 static void dhdsdio_testrcv(dhd_bus_t *bus, void *pkt, uint seq);
 static void dhdsdio_sdtest_set(dhd_bus_t *bus, bool start);
@@ -447,10 +456,6 @@
 static uint process_nvram_vars(char *varbuf, uint len);
 
 static void dhd_dongle_setmemsize(struct dhd_bus *bus, int mem_size);
-static int dhd_bcmsdh_recv_buf(dhd_bus_t *bus, u32 addr, uint fn,
-			       uint flags, u8 *buf, uint nbytes,
-			       struct sk_buff *pkt, bcmsdh_cmplt_fn_t complete,
-			       void *handle);
 static int dhd_bcmsdh_send_buf(dhd_bus_t *bus, u32 addr, uint fn,
 			       uint flags, u8 *buf, uint nbytes,
 			       struct sk_buff *pkt, bcmsdh_cmplt_fn_t complete,
@@ -464,6 +469,23 @@
 #ifdef BCMEMBEDIMAGE
 static int dhdsdio_download_code_array(struct dhd_bus *bus);
 #endif
+static void dhdsdio_chip_disablecore(bcmsdh_info_t *sdh, u32 corebase);
+static int dhdsdio_chip_attach(struct dhd_bus *bus, void *regs);
+static void dhdsdio_chip_resetcore(bcmsdh_info_t *sdh, u32 corebase);
+static void dhdsdio_sdiod_drive_strength_init(struct dhd_bus *bus,
+					u32 drivestrength);
+static void dhdsdio_chip_detach(struct dhd_bus *bus);
+
+/* Packet free applicable unconditionally for sdio and sdspi.
+ * Conditional if bufpool was present for gspi bus.
+ */
+static void dhdsdio_pktfree2(dhd_bus_t *bus, struct sk_buff *pkt)
+{
+	dhd_os_sdlock_rxq(bus->dhd);
+	if ((bus->bus != SPI_BUS) || bus->usebufpool)
+		bcm_pkt_buf_free_skb(pkt);
+	dhd_os_sdunlock_rxq(bus->dhd);
+}
 
 static void dhd_dongle_setmemsize(struct dhd_bus *bus, int mem_size)
 {
@@ -511,8 +533,8 @@
 		clkreq =
 		    bus->alp_only ? SBSDIO_ALP_AVAIL_REQ : SBSDIO_HT_AVAIL_REQ;
 
-		if ((bus->sih->chip == BCM4329_CHIP_ID)
-		    && (bus->sih->chiprev == 0))
+		if ((bus->ci->chip == BCM4329_CHIP_ID)
+		    && (bus->ci->chiprev == 0))
 			clkreq |= SBSDIO_FORCE_ALP;
 
 		bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR,
@@ -520,11 +542,11 @@
 		if (err) {
 			DHD_ERROR(("%s: HT Avail request error: %d\n",
 				   __func__, err));
-			return BCME_ERROR;
+			return -EBADE;
 		}
 
-		if (pendok && ((bus->sih->buscoretype == PCMCIA_CORE_ID)
-			       && (bus->sih->buscorerev == 9))) {
+		if (pendok && ((bus->ci->buscoretype == PCMCIA_CORE_ID)
+			       && (bus->ci->buscorerev == 9))) {
 			u32 dummy, retries;
 			R_SDREG(dummy, &bus->regs->clockctlstatus, retries);
 		}
@@ -536,7 +558,7 @@
 		if (err) {
 			DHD_ERROR(("%s: HT Avail read error: %d\n",
 				   __func__, err));
-			return BCME_ERROR;
+			return -EBADE;
 		}
 
 		/* Go to pending and await interrupt if appropriate */
@@ -548,7 +570,7 @@
 			if (err) {
 				DHD_ERROR(("%s: Devctl error setting CA: %d\n",
 					__func__, err));
-				return BCME_ERROR;
+				return -EBADE;
 			}
 
 			devctl |= SBSDIO_DEVCTL_CA_INT_ONLY;
@@ -557,7 +579,7 @@
 			DHD_INFO(("CLKCTL: set PENDING\n"));
 			bus->clkstate = CLK_PENDING;
 
-			return BCME_OK;
+			return 0;
 		} else if (bus->clkstate == CLK_PENDING) {
 			/* Cancel CA-only interrupt filter */
 			devctl =
@@ -581,12 +603,12 @@
 		if (err) {
 			DHD_ERROR(("%s: HT Avail request error: %d\n",
 				   __func__, err));
-			return BCME_ERROR;
+			return -EBADE;
 		}
 		if (!SBSDIO_CLKAV(clkctl, bus->alp_only)) {
 			DHD_ERROR(("%s: HT Avail timeout (%d): clkctl 0x%02x\n",
 				   __func__, PMU_MAX_TRANSITION_DLY, clkctl));
-			return BCME_ERROR;
+			return -EBADE;
 		}
 
 		/* Mark clock available */
@@ -630,10 +652,10 @@
 		if (err) {
 			DHD_ERROR(("%s: Failed access turning clock off: %d\n",
 				   __func__, err));
-			return BCME_ERROR;
+			return -EBADE;
 		}
 	}
-	return BCME_OK;
+	return 0;
 }
 
 /* Change idle/active SD state */
@@ -653,7 +675,7 @@
 			if (err) {
 				DHD_ERROR(("%s: error enabling sd_clock: %d\n",
 					   __func__, err));
-				return BCME_ERROR;
+				return -EBADE;
 			}
 
 			iovalue = bus->sd_mode;
@@ -662,7 +684,7 @@
 			if (err) {
 				DHD_ERROR(("%s: error changing sd_mode: %d\n",
 					   __func__, err));
-				return BCME_ERROR;
+				return -EBADE;
 			}
 		} else if (bus->idleclock != DHD_IDLE_ACTIVE) {
 			/* Restore clock speed */
@@ -672,7 +694,7 @@
 			if (err) {
 				DHD_ERROR(("%s: error restoring sd_divisor: %d\n",
 					__func__, err));
-				return BCME_ERROR;
+				return -EBADE;
 			}
 		}
 		bus->clkstate = CLK_SDONLY;
@@ -681,7 +703,7 @@
 		if ((bus->sd_divisor == -1) || (bus->sd_mode == -1)) {
 			DHD_TRACE(("%s: can't idle clock, divisor %d mode %d\n",
 				   __func__, bus->sd_divisor, bus->sd_mode));
-			return BCME_ERROR;
+			return -EBADE;
 		}
 		if (bus->idleclock == DHD_IDLE_STOP) {
 			if (sd1idle) {
@@ -694,7 +716,7 @@
 				if (err) {
 					DHD_ERROR(("%s: error changing sd_clock: %d\n",
 						__func__, err));
-					return BCME_ERROR;
+					return -EBADE;
 				}
 			}
 
@@ -704,7 +726,7 @@
 			if (err) {
 				DHD_ERROR(("%s: error disabling sd_clock: %d\n",
 					   __func__, err));
-				return BCME_ERROR;
+				return -EBADE;
 			}
 		} else if (bus->idleclock != DHD_IDLE_ACTIVE) {
 			/* Set divisor to idle value */
@@ -714,13 +736,13 @@
 			if (err) {
 				DHD_ERROR(("%s: error changing sd_divisor: %d\n",
 					__func__, err));
-				return BCME_ERROR;
+				return -EBADE;
 			}
 		}
 		bus->clkstate = CLK_NONE;
 	}
 
-	return BCME_OK;
+	return 0;
 }
 
 /* Transition SD and backplane clock readiness */
@@ -738,7 +760,7 @@
 			dhd_os_wd_timer(bus->dhd, dhd_watchdog_ms);
 			bus->activity = true;
 		}
-		return BCME_OK;
+		return 0;
 	}
 
 	switch (target) {
@@ -777,7 +799,7 @@
 	DHD_INFO(("dhdsdio_clkctl: %d -> %d\n", oldstate, bus->clkstate));
 #endif				/* DHD_DEBUG */
 
-	return BCME_OK;
+	return 0;
 }
 
 int dhdsdio_bussleep(dhd_bus_t *bus, bool sleep)
@@ -792,13 +814,13 @@
 
 	/* Done if we're already in the requested state */
 	if (sleep == bus->sleeping)
-		return BCME_OK;
+		return 0;
 
 	/* Going to sleep: set the alarm and turn off the lights... */
 	if (sleep) {
 		/* Don't sleep if something is pending */
 		if (bus->dpc_sched || bus->rxskip || pktq_len(&bus->txq))
-			return BCME_BUSY;
+			return -EBUSY;
 
 		/* Disable SDIO interrupts (no longer interested) */
 		bcmsdh_intr_disable(bus->sdh);
@@ -818,8 +840,8 @@
 				 SBSDIO_FORCE_HW_CLKREQ_OFF, NULL);
 
 		/* Isolate the bus */
-		if (bus->sih->chip != BCM4329_CHIP_ID
-		    && bus->sih->chip != BCM4319_CHIP_ID) {
+		if (bus->ci->chip != BCM4329_CHIP_ID
+		    && bus->ci->chip != BCM4319_CHIP_ID) {
 			bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_DEVICE_CTL,
 					 SBSDIO_DEVCTL_PADS_ISO, NULL);
 		}
@@ -835,8 +857,8 @@
 
 		/* Force pad isolation off if possible
 			 (in case power never toggled) */
-		if ((bus->sih->buscoretype == PCMCIA_CORE_ID)
-		    && (bus->sih->buscorerev >= 10))
+		if ((bus->ci->buscoretype == PCMCIA_CORE_ID)
+		    && (bus->ci->buscorerev >= 10))
 			bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_DEVICE_CTL, 0,
 					 NULL);
 
@@ -864,7 +886,7 @@
 		}
 	}
 
-	return BCME_OK;
+	return 0;
 }
 
 #if defined(OOB_INTR_ONLY)
@@ -922,7 +944,7 @@
 	sdh = bus->sdh;
 
 	if (bus->dhd->dongle_reset) {
-		ret = BCME_NOTREADY;
+		ret = -EPERM;
 		goto done;
 	}
 
@@ -935,19 +957,19 @@
 			DHD_INFO(("%s: insufficient headroom %d for %d pad\n",
 				  __func__, skb_headroom(pkt), pad));
 			bus->dhd->tx_realloc++;
-			new = pkt_buf_get_skb(pkt->len + DHD_SDALIGN);
+			new = bcm_pkt_buf_get_skb(pkt->len + DHD_SDALIGN);
 			if (!new) {
 				DHD_ERROR(("%s: couldn't allocate new %d-byte "
 					"packet\n",
 					__func__, pkt->len + DHD_SDALIGN));
-				ret = BCME_NOMEM;
+				ret = -ENOMEM;
 				goto done;
 			}
 
 			PKTALIGN(new, pkt->len, DHD_SDALIGN);
 			memcpy(new->data, pkt->data, pkt->len);
 			if (free_pkt)
-				pkt_buf_free_skb(pkt);
+				bcm_pkt_buf_free_skb(pkt);
 			/* free the pkt if canned one is not used */
 			free_pkt = true;
 			pkt = new;
@@ -983,9 +1005,12 @@
 	if (DHD_BYTES_ON() &&
 	    (((DHD_CTL_ON() && (chan == SDPCM_CONTROL_CHANNEL)) ||
 	      (DHD_DATA_ON() && (chan != SDPCM_CONTROL_CHANNEL))))) {
-		prhex("Tx Frame", frame, len);
+		printk(KERN_DEBUG "Tx Frame:\n");
+		print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, frame, len);
 	} else if (DHD_HDRS_ON()) {
-		prhex("TxHdr", frame, min_t(u16, len, 16));
+		printk(KERN_DEBUG "TxHdr:\n");
+		print_hex_dump_bytes("", DUMP_PREFIX_OFFSET,
+				     frame, min_t(u16, len, 16));
 	}
 #endif
 
@@ -1019,7 +1044,7 @@
 		    dhd_bcmsdh_send_buf(bus, bcmsdh_cur_sbwad(sdh), SDIO_FUNC_2,
 					F2SYNC, frame, len, pkt, NULL, NULL);
 		bus->f2txdata++;
-		ASSERT(ret != BCME_PENDING);
+		ASSERT(ret != -BCME_PENDING);
 
 		if (ret < 0) {
 			/* On failure, abort the command
@@ -1061,14 +1086,14 @@
 	dhd_os_sdlock(bus->dhd);
 
 	if (free_pkt)
-		pkt_buf_free_skb(pkt);
+		bcm_pkt_buf_free_skb(pkt);
 
 	return ret;
 }
 
 int dhd_bus_txdata(struct dhd_bus *bus, struct sk_buff *pkt)
 {
-	int ret = BCME_ERROR;
+	int ret = -EBADE;
 	uint datalen, prec;
 
 	DHD_TRACE(("%s: Enter\n", __func__));
@@ -1110,11 +1135,11 @@
 		if (dhd_prec_enq(bus->dhd, &bus->txq, pkt, prec) == false) {
 			skb_pull(pkt, SDPCM_HDRLEN);
 			dhd_txcomplete(bus->dhd, pkt, false);
-			pkt_buf_free_skb(pkt);
+			bcm_pkt_buf_free_skb(pkt);
 			DHD_ERROR(("%s: out of bus->txq !!!\n", __func__));
-			ret = BCME_NORESOURCE;
+			ret = -ENOSR;
 		} else {
-			ret = BCME_OK;
+			ret = 0;
 		}
 		dhd_os_sdunlock_txq(bus->dhd);
 
@@ -1183,7 +1208,7 @@
 	/* Send frames until the limit or some other event */
 	for (cnt = 0; (cnt < maxframes) && DATAOK(bus); cnt++) {
 		dhd_os_sdlock_txq(bus->dhd);
-		pkt = pktq_mdeq(&bus->txq, tx_prec_map, &prec_out);
+		pkt = bcm_pktq_mdeq(&bus->txq, tx_prec_map, &prec_out);
 		if (pkt == NULL) {
 			dhd_os_sdunlock_txq(bus->dhd);
 			break;
@@ -1313,10 +1338,15 @@
 
 	if (ret == -1) {
 #ifdef DHD_DEBUG
-		if (DHD_BYTES_ON() && DHD_CTL_ON())
-			prhex("Tx Frame", frame, len);
-		else if (DHD_HDRS_ON())
-			prhex("TxHdr", frame, min_t(u16, len, 16));
+		if (DHD_BYTES_ON() && DHD_CTL_ON()) {
+			printk(KERN_DEBUG "Tx Frame:\n");
+			print_hex_dump_bytes("", DUMP_PREFIX_OFFSET,
+					     frame, len);
+		} else if (DHD_HDRS_ON()) {
+			printk(KERN_DEBUG "TxHdr:\n");
+			print_hex_dump_bytes("", DUMP_PREFIX_OFFSET,
+					     frame, min_t(u16, len, 16));
+		}
 #endif
 
 		do {
@@ -1326,7 +1356,7 @@
 						SDIO_FUNC_2, F2SYNC, frame, len,
 						NULL, NULL, NULL);
 
-			ASSERT(ret != BCME_PENDING);
+			ASSERT(ret != -BCME_PENDING);
 
 			if (ret < 0) {
 				/* On failure, abort the command and
@@ -1669,7 +1699,7 @@
 
 	memcpy(&pktgen, arg, sizeof(pktgen));
 	if (pktgen.version != DHD_PKTGEN_VERSION)
-		return BCME_BADARG;
+		return -EINVAL;
 
 	oldcnt = bus->pktgen_count;
 	oldmode = bus->pktgen_mode;
@@ -1778,7 +1808,7 @@
 	if (addr == 0 || ((~addr >> 16) & 0xffff) == (addr & 0xffff)) {
 		DHD_ERROR(("%s: address (0x%08x) of sdpcm_shared invalid\n",
 			   __func__, addr));
-		return BCME_ERROR;
+		return -EBADE;
 	}
 
 	/* Read hndrte_shared structure */
@@ -1801,10 +1831,10 @@
 			   "is different than sdpcm_shared version %d in dongle\n",
 			   __func__, SDPCM_SHARED_VERSION,
 			   sh->flags & SDPCM_SHARED_VERSION_MASK));
-		return BCME_ERROR;
+		return -EBADE;
 	}
 
-	return BCME_OK;
+	return 0;
 }
 
 static int dhdsdio_checkdied(dhd_bus_t *bus, u8 *data, uint size)
@@ -1830,7 +1860,7 @@
 		if (mbuffer == NULL) {
 			DHD_ERROR(("%s: kmalloc(%d) failed\n", __func__,
 				   msize));
-			bcmerror = BCME_NOMEM;
+			bcmerror = -ENOMEM;
 			goto done;
 		}
 	}
@@ -1838,7 +1868,7 @@
 	str = kmalloc(maxstrlen, GFP_ATOMIC);
 	if (str == NULL) {
 		DHD_ERROR(("%s: kmalloc(%d) failed\n", __func__, maxstrlen));
-		bcmerror = BCME_NOMEM;
+		bcmerror = -ENOMEM;
 		goto done;
 	}
 
@@ -2007,19 +2037,19 @@
 		c->bufsize = le32_to_cpu(c->log.buf_size);
 		c->buf = kmalloc(c->bufsize, GFP_ATOMIC);
 		if (c->buf == NULL)
-			return BCME_NOMEM;
+			return -ENOMEM;
 	}
 
 	idx = le32_to_cpu(c->log.idx);
 
 	/* Protect against corrupt value */
 	if (idx > c->bufsize)
-		return BCME_ERROR;
+		return -EBADE;
 
 	/* Skip reading the console buffer if the index pointer
 	 has not moved */
 	if (idx == c->last)
-		return BCME_OK;
+		return 0;
 
 	/* Read the console buffer */
 	addr = le32_to_cpu(c->log.buf);
@@ -2057,23 +2087,23 @@
 	}
 break2:
 
-	return BCME_OK;
+	return 0;
 }
 #endif				/* DHD_DEBUG */
 
 int dhdsdio_downloadvars(dhd_bus_t *bus, void *arg, int len)
 {
-	int bcmerror = BCME_OK;
+	int bcmerror = 0;
 
 	DHD_TRACE(("%s: Enter\n", __func__));
 
 	/* Basic sanity checks */
 	if (bus->dhd->up) {
-		bcmerror = BCME_NOTDOWN;
+		bcmerror = -EISCONN;
 		goto err;
 	}
 	if (!len) {
-		bcmerror = BCME_BUFTOOSHORT;
+		bcmerror = -EOVERFLOW;
 		goto err;
 	}
 
@@ -2083,7 +2113,7 @@
 	bus->vars = kmalloc(len, GFP_ATOMIC);
 	bus->varsz = bus->vars ? len : 0;
 	if (bus->vars == NULL) {
-		bcmerror = BCME_NOMEM;
+		bcmerror = -ENOMEM;
 		goto err;
 	}
 
@@ -2122,7 +2152,7 @@
 	/* Check if dongle is in reset. If so, only allow DEVRESET iovars */
 	if (bus->dhd->dongle_reset && !(actionid == IOV_SVAL(IOV_DEVRESET) ||
 					actionid == IOV_GVAL(IOV_DEVRESET))) {
-		bcmerror = BCME_NOTREADY;
+		bcmerror = -EPERM;
 		goto exit;
 	}
 
@@ -2182,7 +2212,7 @@
 
 	case IOV_SVAL(IOV_IDLETIME):
 		if ((int_val < 0) && (int_val != DHD_IDLE_IMMEDIATE))
-			bcmerror = BCME_BADARG;
+			bcmerror = -EINVAL;
 		else
 			bus->idletime = int_val;
 		break;
@@ -2228,7 +2258,7 @@
 				"0x%08x size %d dsize %d\n",
 				__func__, (set ? "set" : "get"),
 				address, size, dsize));
-				bcmerror = BCME_BADARG;
+				bcmerror = -EINVAL;
 				break;
 			}
 
@@ -2243,7 +2273,7 @@
 				DHD_ERROR(("%s: ramsize 0x%08x doesn't have %d "
 				"bytes at 0x%08x\n",
 				__func__, bus->orig_ramsize, size, address));
-				bcmerror = BCME_BADARG;
+				bcmerror = -EINVAL;
 				break;
 			}
 
@@ -2271,7 +2301,7 @@
 
 	case IOV_SVAL(IOV_SDIOD_DRIVE):
 		dhd_sdiod_drive_strength = int_val;
-		si_sdiod_drive_strength_init(bus->sih,
+		dhdsdio_sdiod_drive_strength_init(bus,
 					     dhd_sdiod_drive_strength);
 		break;
 
@@ -2301,7 +2331,7 @@
 
 	case IOV_SVAL(IOV_SDRXCHAIN):
 		if (bool_val && !bus->sd_rxchain)
-			bcmerror = BCME_UNSUPPORTED;
+			bcmerror = -ENOTSUPP;
 		else
 			bus->use_rxchain = bool_val;
 		break;
@@ -2324,7 +2354,7 @@
 		if (bus->varsz < (uint) len)
 			memcpy(arg, bus->vars, bus->varsz);
 		else
-			bcmerror = BCME_BUFTOOSHORT;
+			bcmerror = -EOVERFLOW;
 		break;
 #endif				/* DHD_DEBUG */
 
@@ -2340,7 +2370,7 @@
 			size = sd_ptr->func;
 			int_val = (s32) bcmsdh_reg_read(bus->sdh, addr, size);
 			if (bcmsdh_regfail(bus->sdh))
-				bcmerror = BCME_SDIO_ERROR;
+				bcmerror = -EIO;
 			memcpy(arg, &int_val, sizeof(s32));
 			break;
 		}
@@ -2356,7 +2386,7 @@
 			size = sd_ptr->func;
 			bcmsdh_reg_write(bus->sdh, addr, size, sd_ptr->value);
 			if (bcmsdh_regfail(bus->sdh))
-				bcmerror = BCME_SDIO_ERROR;
+				bcmerror = -EIO;
 			break;
 		}
 
@@ -2373,7 +2403,7 @@
 			size = sdreg.func;
 			int_val = (s32) bcmsdh_reg_read(bus->sdh, addr, size);
 			if (bcmsdh_regfail(bus->sdh))
-				bcmerror = BCME_SDIO_ERROR;
+				bcmerror = -EIO;
 			memcpy(arg, &int_val, sizeof(s32));
 			break;
 		}
@@ -2389,7 +2419,7 @@
 			size = sdreg.func;
 			bcmsdh_reg_write(bus->sdh, addr, size, sdreg.value);
 			if (bcmsdh_regfail(bus->sdh))
-				bcmerror = BCME_SDIO_ERROR;
+				bcmerror = -EIO;
 			break;
 		}
 
@@ -2488,7 +2518,7 @@
 		break;
 
 	default:
-		bcmerror = BCME_UNSUPPORTED;
+		bcmerror = -ENOTSUPP;
 		break;
 	}
 
@@ -2525,7 +2555,7 @@
 	if (bus->vars) {
 		vbuffer = kzalloc(varsize, GFP_ATOMIC);
 		if (!vbuffer)
-			return BCME_NOMEM;
+			return -ENOMEM;
 
 		memcpy(vbuffer, bus->vars, bus->varsz);
 
@@ -2537,7 +2567,7 @@
 		DHD_INFO(("Compare NVRAM dl & ul; varsize=%d\n", varsize));
 		nvram_ularray = kmalloc(varsize, GFP_ATOMIC);
 		if (!nvram_ularray)
-			return BCME_NOMEM;
+			return -ENOMEM;
 
 		/* Upload image to verify downloaded contents. */
 		memset(nvram_ularray, 0xaa, varsize);
@@ -2596,42 +2626,18 @@
 static int dhdsdio_download_state(dhd_bus_t *bus, bool enter)
 {
 	uint retries;
+	u32 regdata;
 	int bcmerror = 0;
 
 	/* To enter download state, disable ARM and reset SOCRAM.
 	 * To exit download state, simply reset ARM (default is RAM boot).
 	 */
 	if (enter) {
-
 		bus->alp_only = true;
 
-		if (!(si_setcore(bus->sih, ARM7S_CORE_ID, 0)) &&
-		    !(si_setcore(bus->sih, ARMCM3_CORE_ID, 0))) {
-			DHD_ERROR(("%s: Failed to find ARM core!\n", __func__));
-			bcmerror = BCME_ERROR;
-			goto fail;
-		}
-
-		si_core_disable(bus->sih, 0);
-		if (bcmsdh_regfail(bus->sdh)) {
-			bcmerror = BCME_SDIO_ERROR;
-			goto fail;
-		}
-
-		if (!(si_setcore(bus->sih, SOCRAM_CORE_ID, 0))) {
-			DHD_ERROR(("%s: Failed to find SOCRAM core!\n",
-				   __func__));
-			bcmerror = BCME_ERROR;
-			goto fail;
-		}
+		dhdsdio_chip_disablecore(bus->sdh, bus->ci->armcorebase);
 
-		si_core_reset(bus->sih, 0, 0);
-		if (bcmsdh_regfail(bus->sdh)) {
-			DHD_ERROR(("%s: Failure trying reset SOCRAM core?\n",
-				   __func__));
-			bcmerror = BCME_SDIO_ERROR;
-			goto fail;
-		}
+		dhdsdio_chip_resetcore(bus->sdh, bus->ci->ramcorebase);
 
 		/* Clear the top bit of memory */
 		if (bus->ramsize) {
@@ -2640,17 +2646,14 @@
 					 (u8 *)&zeros, 4);
 		}
 	} else {
-		if (!(si_setcore(bus->sih, SOCRAM_CORE_ID, 0))) {
-			DHD_ERROR(("%s: Failed to find SOCRAM core!\n",
-				   __func__));
-			bcmerror = BCME_ERROR;
-			goto fail;
-		}
-
-		if (!si_iscoreup(bus->sih)) {
+		regdata = bcmsdh_reg_read(bus->sdh,
+			CORE_SB(bus->ci->ramcorebase, sbtmstatelow), 4);
+		regdata &= (SBTML_RESET | SBTML_REJ_MASK |
+			(SICF_CLOCK_EN << SBTML_SICF_SHIFT));
+		if ((SICF_CLOCK_EN << SBTML_SICF_SHIFT) != regdata) {
 			DHD_ERROR(("%s: SOCRAM core is down after reset?\n",
 				   __func__));
-			bcmerror = BCME_ERROR;
+			bcmerror = -EBADE;
 			goto fail;
 		}
 
@@ -2660,41 +2663,16 @@
 			bcmerror = 0;
 		}
 
-		if (!si_setcore(bus->sih, PCMCIA_CORE_ID, 0) &&
-		    !si_setcore(bus->sih, SDIOD_CORE_ID, 0)) {
-			DHD_ERROR(("%s: Can't change back to SDIO core?\n",
-				   __func__));
-			bcmerror = BCME_ERROR;
-			goto fail;
-		}
 		W_SDREG(0xFFFFFFFF, &bus->regs->intstatus, retries);
 
-		if (!(si_setcore(bus->sih, ARM7S_CORE_ID, 0)) &&
-		    !(si_setcore(bus->sih, ARMCM3_CORE_ID, 0))) {
-			DHD_ERROR(("%s: Failed to find ARM core!\n", __func__));
-			bcmerror = BCME_ERROR;
-			goto fail;
-		}
-
-		si_core_reset(bus->sih, 0, 0);
-		if (bcmsdh_regfail(bus->sdh)) {
-			DHD_ERROR(("%s: Failure trying to reset ARM core?\n",
-				   __func__));
-			bcmerror = BCME_SDIO_ERROR;
-			goto fail;
-		}
+		dhdsdio_chip_resetcore(bus->sdh, bus->ci->armcorebase);
 
 		/* Allow HT Clock now that the ARM is running. */
 		bus->alp_only = false;
 
 		bus->dhd->busstate = DHD_BUS_LOAD;
 	}
-
 fail:
-	/* Always return to SDIOD core */
-	if (!si_setcore(bus->sih, PCMCIA_CORE_ID, 0))
-		si_setcore(bus->sih, SDIOD_CORE_ID, 0);
-
 	return bcmerror;
 }
 
@@ -2739,7 +2717,7 @@
 		if (set && strcmp(name, "sd_divisor") == 0) {
 			if (bcmsdh_iovar_op(bus->sdh, "sd_divisor", NULL, 0,
 					    &bus->sd_divisor, sizeof(s32),
-					    false) != BCME_OK) {
+					    false) != 0) {
 				bus->sd_divisor = -1;
 				DHD_ERROR(("%s: fail on %s get\n", __func__,
 					   name));
@@ -2752,7 +2730,7 @@
 		if (set && strcmp(name, "sd_mode") == 0) {
 			if (bcmsdh_iovar_op(bus->sdh, "sd_mode", NULL, 0,
 					    &bus->sd_mode, sizeof(s32),
-					    false) != BCME_OK) {
+					    false) != 0) {
 				bus->sd_mode = -1;
 				DHD_ERROR(("%s: fail on %s get\n", __func__,
 					   name));
@@ -2767,7 +2745,7 @@
 			if (bcmsdh_iovar_op
 			    (bus->sdh, "sd_blocksize", &fnum, sizeof(s32),
 			     &bus->blocksize, sizeof(s32),
-			     false) != BCME_OK) {
+			     false) != 0) {
 				bus->blocksize = 0;
 				DHD_ERROR(("%s: fail on %s get\n", __func__,
 					   "sd_blocksize"));
@@ -2867,14 +2845,14 @@
 	dhdsdio_clkctl(bus, CLK_SDONLY, false);
 
 	/* Clear the data packet queues */
-	pktq_flush(&bus->txq, true);
+	bcm_pktq_flush(&bus->txq, true, NULL, NULL);
 
 	/* Clear any held glomming stuff */
 	if (bus->glomd)
-		pkt_buf_free_skb(bus->glomd);
+		bcm_pkt_buf_free_skb(bus->glomd);
 
 	if (bus->glom)
-		pkt_buf_free_skb(bus->glom);
+		bcm_pkt_buf_free_skb(bus->glom);
 
 	bus->glom = bus->glomd = NULL;
 
@@ -2948,14 +2926,11 @@
 
 	/* If F2 successfully enabled, set core and enable interrupts */
 	if (ready == enable) {
-		/* Make sure we're talking to the core. */
-		bus->regs = si_setcore(bus->sih, PCMCIA_CORE_ID, 0);
-		if (!(bus->regs))
-			bus->regs = si_setcore(bus->sih, SDIOD_CORE_ID, 0);
-
 		/* Set up the interrupt mask and enable interrupts */
 		bus->hostintmask = HOSTINTMASK;
-		W_SDREG(bus->hostintmask, &bus->regs->hostintmask, retries);
+		W_SDREG(bus->hostintmask,
+			(unsigned int *)CORE_BUS_REG(bus->ci->buscorebase,
+			hostintmask), retries);
 
 		bcmsdh_cfg_write(bus->sdh, SDIO_FUNC_1, SBSDIO_WATERMARK,
 				 (u8) watermark, &err);
@@ -3134,12 +3109,11 @@
 	}
 
 	/* Read remainder of frame body into the rxctl buffer */
-	sdret =
-	    dhd_bcmsdh_recv_buf(bus, bcmsdh_cur_sbwad(sdh), SDIO_FUNC_2, F2SYNC,
-				(bus->rxctl + firstread), rdlen, NULL, NULL,
-				NULL);
+	sdret = bcmsdh_recv_buf(bus, bcmsdh_cur_sbwad(sdh), SDIO_FUNC_2,
+				F2SYNC, (bus->rxctl + firstread), rdlen,
+				NULL, NULL, NULL);
 	bus->f2rxdata++;
-	ASSERT(sdret != BCME_PENDING);
+	ASSERT(sdret != -BCME_PENDING);
 
 	/* Control frame failures need retransmission */
 	if (sdret < 0) {
@@ -3153,8 +3127,10 @@
 gotpkt:
 
 #ifdef DHD_DEBUG
-	if (DHD_BYTES_ON() && DHD_CTL_ON())
-		prhex("RxCtrl", bus->rxctl, len);
+	if (DHD_BYTES_ON() && DHD_CTL_ON()) {
+		printk(KERN_DEBUG "RxCtrl:\n");
+		print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, bus->rxctl, len);
+	}
 #endif
 
 	/* Point to valid data and indicate its length */
@@ -3228,10 +3204,11 @@
 			}
 
 			/* Allocate/chain packet for next subframe */
-			pnext = pkt_buf_get_skb(sublen + DHD_SDALIGN);
+			pnext = bcm_pkt_buf_get_skb(sublen + DHD_SDALIGN);
 			if (pnext == NULL) {
-				DHD_ERROR(("%s: pkt_buf_get_skb failed, num %d len %d\n",
-					   __func__, num, sublen));
+				DHD_ERROR(("%s: bcm_pkt_buf_get_skb failed, "
+					"num %d len %d\n", __func__,
+					num, sublen));
 				break;
 			}
 			ASSERT(!(pnext->prev));
@@ -3264,13 +3241,13 @@
 			pfirst = pnext = NULL;
 		} else {
 			if (pfirst)
-				pkt_buf_free_skb(pfirst);
+				bcm_pkt_buf_free_skb(pfirst);
 			bus->glom = NULL;
 			num = 0;
 		}
 
 		/* Done with descriptor packet */
-		pkt_buf_free_skb(bus->glomd);
+		bcm_pkt_buf_free_skb(bus->glomd);
 		bus->glomd = NULL;
 		bus->nextlen = 0;
 
@@ -3291,27 +3268,23 @@
 		}
 
 		pfirst = bus->glom;
-		dlen = (u16) pkttotlen(pfirst);
+		dlen = (u16) bcm_pkttotlen(pfirst);
 
 		/* Do an SDIO read for the superframe.  Configurable iovar to
 		 * read directly into the chained packet, or allocate a large
 		 * packet and and copy into the chain.
 		 */
 		if (usechain) {
-			errcode = dhd_bcmsdh_recv_buf(bus,
-						      bcmsdh_cur_sbwad
-						      (bus->sdh), SDIO_FUNC_2,
-						      F2SYNC,
-						      (u8 *) pfirst->data,
-						      dlen, pfirst, NULL, NULL);
+			errcode = bcmsdh_recv_buf(bus,
+					bcmsdh_cur_sbwad(bus->sdh), SDIO_FUNC_2,
+					F2SYNC, (u8 *) pfirst->data, dlen,
+					pfirst, NULL, NULL);
 		} else if (bus->dataptr) {
-			errcode = dhd_bcmsdh_recv_buf(bus,
-						      bcmsdh_cur_sbwad
-						      (bus->sdh), SDIO_FUNC_2,
-						      F2SYNC, bus->dataptr,
-						      dlen, NULL, NULL, NULL);
-			sublen =
-			    (u16) pktfrombuf(pfirst, 0, dlen,
+			errcode = bcmsdh_recv_buf(bus,
+					bcmsdh_cur_sbwad(bus->sdh), SDIO_FUNC_2,
+					F2SYNC, bus->dataptr, dlen,
+					NULL, NULL, NULL);
+			sublen = (u16) bcm_pktfrombuf(pfirst, 0, dlen,
 						bus->dataptr);
 			if (sublen != dlen) {
 				DHD_ERROR(("%s: FAILED TO COPY, dlen %d sublen %d\n",
@@ -3325,7 +3298,7 @@
 			errcode = -1;
 		}
 		bus->f2rxdata++;
-		ASSERT(errcode != BCME_PENDING);
+		ASSERT(errcode != -BCME_PENDING);
 
 		/* On failure, kill the superframe, allow a couple retries */
 		if (errcode < 0) {
@@ -3339,7 +3312,7 @@
 				bus->glomerr = 0;
 				dhdsdio_rxfail(bus, true, false);
 				dhd_os_sdlock_rxq(bus->dhd);
-				pkt_buf_free_skb(bus->glom);
+				bcm_pkt_buf_free_skb(bus->glom);
 				dhd_os_sdunlock_rxq(bus->dhd);
 				bus->rxglomfail++;
 				bus->glom = NULL;
@@ -3348,8 +3321,9 @@
 		}
 #ifdef DHD_DEBUG
 		if (DHD_GLOM_ON()) {
-			prhex("SUPERFRAME", pfirst->data,
-			      min_t(int, pfirst->len, 48));
+			printk(KERN_DEBUG "SUPERFRAME:\n");
+			print_hex_dump_bytes("", DUMP_PREFIX_OFFSET,
+				pfirst->data, min_t(int, pfirst->len, 48));
 		}
 #endif
 
@@ -3430,8 +3404,11 @@
 			chan = SDPCM_PACKET_CHANNEL(&dptr[SDPCM_FRAMETAG_LEN]);
 			doff = SDPCM_DOFFSET_VALUE(&dptr[SDPCM_FRAMETAG_LEN]);
 #ifdef DHD_DEBUG
-			if (DHD_GLOM_ON())
-				prhex("subframe", dptr, 32);
+			if (DHD_GLOM_ON()) {
+				printk(KERN_DEBUG "subframe:\n");
+				print_hex_dump_bytes("", DUMP_PREFIX_OFFSET,
+						     dptr, 32);
+			}
 #endif
 
 			if ((u16)~(sublen ^ check)) {
@@ -3468,7 +3445,7 @@
 				bus->glomerr = 0;
 				dhdsdio_rxfail(bus, true, false);
 				dhd_os_sdlock_rxq(bus->dhd);
-				pkt_buf_free_skb(bus->glom);
+				bcm_pkt_buf_free_skb(bus->glom);
 				dhd_os_sdunlock_rxq(bus->dhd);
 				bus->rxglomfail++;
 				bus->glom = NULL;
@@ -3508,15 +3485,18 @@
 				rxseq = seq;
 			}
 #ifdef DHD_DEBUG
-			if (DHD_BYTES_ON() && DHD_DATA_ON())
-				prhex("Rx Subframe Data", dptr, dlen);
+			if (DHD_BYTES_ON() && DHD_DATA_ON()) {
+				printk(KERN_DEBUG "Rx Subframe Data:\n");
+				print_hex_dump_bytes("", DUMP_PREFIX_OFFSET,
+						     dptr, dlen);
+			}
 #endif
 
 			__skb_trim(pfirst, sublen);
 			skb_pull(pfirst, doff);
 
 			if (pfirst->len == 0) {
-				pkt_buf_free_skb(pfirst);
+				bcm_pkt_buf_free_skb(pfirst);
 				if (plast) {
 					plast->next = pnext;
 				} else {
@@ -3529,7 +3509,7 @@
 				DHD_ERROR(("%s: rx protocol error\n",
 					   __func__));
 				bus->dhd->rx_errors++;
-				pkt_buf_free_skb(pfirst);
+				bcm_pkt_buf_free_skb(pfirst);
 				if (plast) {
 					plast->next = pnext;
 				} else {
@@ -3552,8 +3532,9 @@
 				__func__, num, pfirst, pfirst->data,
 				pfirst->len, pfirst->next,
 				pfirst->prev));
-				prhex("", (u8 *) pfirst->data,
-				      min_t(int, pfirst->len, 32));
+				print_hex_dump_bytes("", DUMP_PREFIX_OFFSET,
+						pfirst->data,
+						min_t(int, pfirst->len, 32));
 			}
 #endif				/* DHD_DEBUG */
 		}
@@ -3578,7 +3559,6 @@
 	u16 len, check;	/* Extracted hardware header fields */
 	u8 chan, seq, doff;	/* Extracted software header fields */
 	u8 fcbits;		/* Extracted fcbits from software header */
-	u8 delta;
 
 	struct sk_buff *pkt;		/* Packet for event or data frames */
 	u16 pad;		/* Number of pad bytes to read */
@@ -3667,7 +3647,7 @@
 			 */
 			/* Allocate a packet buffer */
 			dhd_os_sdlock_rxq(bus->dhd);
-			pkt = pkt_buf_get_skb(rdlen + DHD_SDALIGN);
+			pkt = bcm_pkt_buf_get_skb(rdlen + DHD_SDALIGN);
 			if (!pkt) {
 				if (bus->bus == SPI_BUS) {
 					bus->usebufpool = false;
@@ -3684,16 +3664,13 @@
 					ASSERT(bus->rxctl >= bus->rxbuf);
 					rxbuf = bus->rxctl;
 					/* Read the entire frame */
-					sdret = dhd_bcmsdh_recv_buf(bus,
-						    bcmsdh_cur_sbwad
-						    (sdh),
-						    SDIO_FUNC_2,
-						    F2SYNC,
-						    rxbuf,
-						    rdlen, NULL,
-						    NULL, NULL);
+					sdret = bcmsdh_recv_buf(bus,
+						    bcmsdh_cur_sbwad(sdh),
+						    SDIO_FUNC_2, F2SYNC,
+						    rxbuf, rdlen,
+						    NULL, NULL, NULL);
 					bus->f2rxdata++;
-					ASSERT(sdret != BCME_PENDING);
+					ASSERT(sdret != -BCME_PENDING);
 
 					/* Control frame failures need
 					 retransmission */
@@ -3713,8 +3690,11 @@
 				} else {
 					/* Give up on data,
 					request rtx of events */
-					DHD_ERROR(("%s (nextlen): pkt_buf_get_skb failed: len %d rdlen %d " "expected rxseq %d\n",
-						__func__, len, rdlen, rxseq));
+					DHD_ERROR(("%s (nextlen): "
+						   "bcm_pkt_buf_get_skb failed:"
+						   " len %d rdlen %d expected"
+						   " rxseq %d\n", __func__,
+						   len, rdlen, rxseq));
 					/* Just go try again w/normal
 					header read */
 					dhd_os_sdunlock_rxq(bus->dhd);
@@ -3728,19 +3708,18 @@
 				PKTALIGN(pkt, rdlen, DHD_SDALIGN);
 				rxbuf = (u8 *) (pkt->data);
 				/* Read the entire frame */
-				sdret =
-				    dhd_bcmsdh_recv_buf(bus,
+				sdret = bcmsdh_recv_buf(bus,
 						bcmsdh_cur_sbwad(sdh),
 						SDIO_FUNC_2, F2SYNC,
-						rxbuf, rdlen, pkt, NULL,
-						NULL);
+						rxbuf, rdlen,
+						pkt, NULL, NULL);
 				bus->f2rxdata++;
-				ASSERT(sdret != BCME_PENDING);
+				ASSERT(sdret != -BCME_PENDING);
 
 				if (sdret < 0) {
 					DHD_ERROR(("%s (nextlen): read %d bytes failed: %d\n",
 						__func__, rdlen, sdret));
-					pkt_buf_free_skb(pkt);
+					bcm_pkt_buf_free_skb(pkt);
 					bus->dhd->rx_errors++;
 					dhd_os_sdunlock_rxq(bus->dhd);
 					/* Force retry w/normal header read.
@@ -3767,23 +3746,19 @@
 			if (!(len | check)) {
 				DHD_INFO(("%s (nextlen): read zeros in HW "
 					"header???\n", __func__));
-				dhd_os_sdlock_rxq(bus->dhd);
-				PKTFREE2();
-				dhd_os_sdunlock_rxq(bus->dhd);
-				GSPI_PR55150_BAILOUT;
+				dhdsdio_pktfree2(bus, pkt);
 				continue;
 			}
 
 			/* Validate check bytes */
 			if ((u16)~(len ^ check)) {
-				DHD_ERROR(("%s (nextlen): HW hdr error: nextlen/len/check" " 0x%04x/0x%04x/0x%04x\n",
+				DHD_ERROR(("%s (nextlen): HW hdr error:"
+					" nextlen/len/check"
+					" 0x%04x/0x%04x/0x%04x\n",
 					__func__, nextlen, len, check));
-				dhd_os_sdlock_rxq(bus->dhd);
-				PKTFREE2();
-				dhd_os_sdunlock_rxq(bus->dhd);
 				bus->rx_badhdr++;
 				dhdsdio_rxfail(bus, false, false);
-				GSPI_PR55150_BAILOUT;
+				dhdsdio_pktfree2(bus, pkt);
 				continue;
 			}
 
@@ -3791,10 +3766,7 @@
 			if (len < SDPCM_HDRLEN) {
 				DHD_ERROR(("%s (nextlen): HW hdr length "
 					"invalid: %d\n", __func__, len));
-				dhd_os_sdlock_rxq(bus->dhd);
-				PKTFREE2();
-				dhd_os_sdunlock_rxq(bus->dhd);
-				GSPI_PR55150_BAILOUT;
+				dhdsdio_pktfree2(bus, pkt);
 				continue;
 			}
 
@@ -3803,31 +3775,25 @@
 			if (len_consistent) {
 				/* Mismatch, force retry w/normal
 					header (may be >4K) */
-				DHD_ERROR(("%s (nextlen): mismatch, nextlen %d len %d rnd %d; " "expected rxseq %d\n",
+				DHD_ERROR(("%s (nextlen): mismatch, "
+					"nextlen %d len %d rnd %d; "
+					"expected rxseq %d\n",
 					__func__, nextlen,
 					len, roundup(len, 16), rxseq));
-				dhd_os_sdlock_rxq(bus->dhd);
-				PKTFREE2();
-				dhd_os_sdunlock_rxq(bus->dhd);
-				dhdsdio_rxfail(bus, true,
-					       (bus->bus ==
-						SPI_BUS) ? false : true);
-				GSPI_PR55150_BAILOUT;
+				dhdsdio_rxfail(bus, true, (bus->bus != SPI_BUS));
+				dhdsdio_pktfree2(bus, pkt);
 				continue;
 			}
 
 			/* Extract software header fields */
-			chan =
-			    SDPCM_PACKET_CHANNEL(&bus->rxhdr
-						 [SDPCM_FRAMETAG_LEN]);
-			seq =
-			    SDPCM_PACKET_SEQUENCE(&bus->rxhdr
-						  [SDPCM_FRAMETAG_LEN]);
-			doff =
-			    SDPCM_DOFFSET_VALUE(&bus->rxhdr
-						[SDPCM_FRAMETAG_LEN]);
-			txmax =
-			    SDPCM_WINDOW_VALUE(&bus->rxhdr[SDPCM_FRAMETAG_LEN]);
+			chan = SDPCM_PACKET_CHANNEL(
+					&bus->rxhdr[SDPCM_FRAMETAG_LEN]);
+			seq = SDPCM_PACKET_SEQUENCE(
+					&bus->rxhdr[SDPCM_FRAMETAG_LEN]);
+			doff = SDPCM_DOFFSET_VALUE(
+					&bus->rxhdr[SDPCM_FRAMETAG_LEN]);
+			txmax = SDPCM_WINDOW_VALUE(
+					&bus->rxhdr[SDPCM_FRAMETAG_LEN]);
 
 			bus->nextlen =
 			    bus->rxhdr[SDPCM_FRAMETAG_LEN +
@@ -3839,21 +3805,18 @@
 			}
 
 			bus->dhd->rx_readahead_cnt++;
+
 			/* Handle Flow Control */
-			fcbits =
-			    SDPCM_FCMASK_VALUE(&bus->rxhdr[SDPCM_FRAMETAG_LEN]);
+			fcbits = SDPCM_FCMASK_VALUE(
+					&bus->rxhdr[SDPCM_FRAMETAG_LEN]);
 
-			delta = 0;
-			if (~bus->flowcontrol & fcbits) {
-				bus->fc_xoff++;
-				delta = 1;
-			}
-			if (bus->flowcontrol & ~fcbits) {
-				bus->fc_xon++;
-				delta = 1;
-			}
+			if (bus->flowcontrol != fcbits) {
+				if (~bus->flowcontrol & fcbits)
+					bus->fc_xoff++;
+
+				if (bus->flowcontrol & ~fcbits)
+					bus->fc_xon++;
 
-			if (delta) {
 				bus->fc_rcvd++;
 				bus->flowcontrol = fcbits;
 			}
@@ -3876,33 +3839,30 @@
 			bus->tx_max = txmax;
 
 #ifdef DHD_DEBUG
-			if (DHD_BYTES_ON() && DHD_DATA_ON())
-				prhex("Rx Data", rxbuf, len);
-			else if (DHD_HDRS_ON())
-				prhex("RxHdr", bus->rxhdr, SDPCM_HDRLEN);
+			if (DHD_BYTES_ON() && DHD_DATA_ON()) {
+				printk(KERN_DEBUG "Rx Data:\n");
+				print_hex_dump_bytes("", DUMP_PREFIX_OFFSET,
+						     rxbuf, len);
+			} else if (DHD_HDRS_ON()) {
+				printk(KERN_DEBUG "RxHdr:\n");
+				print_hex_dump_bytes("", DUMP_PREFIX_OFFSET,
+						     bus->rxhdr, SDPCM_HDRLEN);
+			}
 #endif
 
 			if (chan == SDPCM_CONTROL_CHANNEL) {
 				if (bus->bus == SPI_BUS) {
 					dhdsdio_read_control(bus, rxbuf, len,
 							     doff);
-					if (bus->usebufpool) {
-						dhd_os_sdlock_rxq(bus->dhd);
-						pkt_buf_free_skb(pkt);
-						dhd_os_sdunlock_rxq(bus->dhd);
-					}
-					continue;
 				} else {
 					DHD_ERROR(("%s (nextlen): readahead on control" " packet %d?\n",
 						__func__, seq));
 					/* Force retry w/normal header read */
 					bus->nextlen = 0;
 					dhdsdio_rxfail(bus, false, true);
-					dhd_os_sdlock_rxq(bus->dhd);
-					PKTFREE2();
-					dhd_os_sdunlock_rxq(bus->dhd);
-					continue;
 				}
+				dhdsdio_pktfree2(bus, pkt);
+				continue;
 			}
 
 			if ((bus->bus == SPI_BUS) && !bus->usebufpool) {
@@ -3915,11 +3875,8 @@
 			if ((doff < SDPCM_HDRLEN) || (doff > len)) {
 				DHD_ERROR(("%s (nextlen): bad data offset %d: HW len %d min %d\n",
 					__func__, doff, len, SDPCM_HDRLEN));
-				dhd_os_sdlock_rxq(bus->dhd);
-				PKTFREE2();
-				dhd_os_sdunlock_rxq(bus->dhd);
-				ASSERT(0);
 				dhdsdio_rxfail(bus, false, false);
+				dhdsdio_pktfree2(bus, pkt);
 				continue;
 			}
 
@@ -3931,12 +3888,11 @@
 			break;
 
 		/* Read frame header (hardware and software) */
-		sdret =
-		    dhd_bcmsdh_recv_buf(bus, bcmsdh_cur_sbwad(sdh), SDIO_FUNC_2,
-					F2SYNC, bus->rxhdr, firstread, NULL,
-					NULL, NULL);
+		sdret = bcmsdh_recv_buf(bus, bcmsdh_cur_sbwad(sdh),
+				SDIO_FUNC_2, F2SYNC, bus->rxhdr, firstread,
+				NULL, NULL, NULL);
 		bus->f2rxhdrs++;
-		ASSERT(sdret != BCME_PENDING);
+		ASSERT(sdret != -BCME_PENDING);
 
 		if (sdret < 0) {
 			DHD_ERROR(("%s: RXHEADER FAILED: %d\n", __func__,
@@ -3946,8 +3902,11 @@
 			continue;
 		}
 #ifdef DHD_DEBUG
-		if (DHD_BYTES_ON() || DHD_HDRS_ON())
-			prhex("RxHdr", bus->rxhdr, SDPCM_HDRLEN);
+		if (DHD_BYTES_ON() || DHD_HDRS_ON()) {
+			printk(KERN_DEBUG "RxHdr:\n");
+			print_hex_dump_bytes("", DUMP_PREFIX_OFFSET,
+					     bus->rxhdr, SDPCM_HDRLEN);
+		}
 #endif
 
 		/* Extract hardware header fields */
@@ -4006,17 +3965,13 @@
 		/* Handle Flow Control */
 		fcbits = SDPCM_FCMASK_VALUE(&bus->rxhdr[SDPCM_FRAMETAG_LEN]);
 
-		delta = 0;
-		if (~bus->flowcontrol & fcbits) {
-			bus->fc_xoff++;
-			delta = 1;
-		}
-		if (bus->flowcontrol & ~fcbits) {
-			bus->fc_xon++;
-			delta = 1;
-		}
+		if (bus->flowcontrol != fcbits) {
+			if (~bus->flowcontrol & fcbits)
+				bus->fc_xoff++;
+
+			if (bus->flowcontrol & ~fcbits)
+				bus->fc_xon++;
 
-		if (delta) {
 			bus->fc_rcvd++;
 			bus->flowcontrol = fcbits;
 		}
@@ -4077,11 +4032,11 @@
 		}
 
 		dhd_os_sdlock_rxq(bus->dhd);
-		pkt = pkt_buf_get_skb(rdlen + firstread + DHD_SDALIGN);
+		pkt = bcm_pkt_buf_get_skb(rdlen + firstread + DHD_SDALIGN);
 		if (!pkt) {
 			/* Give up on data, request rtx of events */
-			DHD_ERROR(("%s: pkt_buf_get_skb failed: rdlen %d chan %d\n",
-				   __func__, rdlen, chan));
+			DHD_ERROR(("%s: bcm_pkt_buf_get_skb failed: rdlen %d "
+				"chan %d\n", __func__, rdlen, chan));
 			bus->dhd->rx_dropped++;
 			dhd_os_sdunlock_rxq(bus->dhd);
 			dhdsdio_rxfail(bus, false, RETRYCHAN(chan));
@@ -4097,12 +4052,11 @@
 		PKTALIGN(pkt, rdlen, DHD_SDALIGN);
 
 		/* Read the remaining frame data */
-		sdret =
-		    dhd_bcmsdh_recv_buf(bus, bcmsdh_cur_sbwad(sdh), SDIO_FUNC_2,
+		sdret = bcmsdh_recv_buf(bus, bcmsdh_cur_sbwad(sdh), SDIO_FUNC_2,
 					F2SYNC, ((u8 *) (pkt->data)), rdlen,
 					pkt, NULL, NULL);
 		bus->f2rxdata++;
-		ASSERT(sdret != BCME_PENDING);
+		ASSERT(sdret != -BCME_PENDING);
 
 		if (sdret < 0) {
 			DHD_ERROR(("%s: read %d %s bytes failed: %d\n",
@@ -4113,7 +4067,7 @@
 				       ? "data" : "test")),
 				   sdret));
 			dhd_os_sdlock_rxq(bus->dhd);
-			pkt_buf_free_skb(pkt);
+			bcm_pkt_buf_free_skb(pkt);
 			dhd_os_sdunlock_rxq(bus->dhd);
 			bus->dhd->rx_errors++;
 			dhdsdio_rxfail(bus, true, RETRYCHAN(chan));
@@ -4125,8 +4079,11 @@
 		memcpy(pkt->data, bus->rxhdr, firstread);
 
 #ifdef DHD_DEBUG
-		if (DHD_BYTES_ON() && DHD_DATA_ON())
-			prhex("Rx Data", pkt->data, len);
+		if (DHD_BYTES_ON() && DHD_DATA_ON()) {
+			printk(KERN_DEBUG "Rx Data:\n");
+			print_hex_dump_bytes("", DUMP_PREFIX_OFFSET,
+					     pkt->data, len);
+		}
 #endif
 
 deliver:
@@ -4137,7 +4094,10 @@
 					__func__, len));
 #ifdef DHD_DEBUG
 				if (DHD_GLOM_ON()) {
-					prhex("Glom Data", pkt->data, len);
+					printk(KERN_DEBUG "Glom Data:\n");
+					print_hex_dump_bytes("",
+							     DUMP_PREFIX_OFFSET,
+							     pkt->data, len);
 				}
 #endif
 				__skb_trim(pkt, len);
@@ -4166,13 +4126,13 @@
 
 		if (pkt->len == 0) {
 			dhd_os_sdlock_rxq(bus->dhd);
-			pkt_buf_free_skb(pkt);
+			bcm_pkt_buf_free_skb(pkt);
 			dhd_os_sdunlock_rxq(bus->dhd);
 			continue;
 		} else if (dhd_prot_hdrpull(bus->dhd, &ifidx, pkt) != 0) {
 			DHD_ERROR(("%s: rx protocol error\n", __func__));
 			dhd_os_sdlock_rxq(bus->dhd);
-			pkt_buf_free_skb(pkt);
+			bcm_pkt_buf_free_skb(pkt);
 			dhd_os_sdunlock_rxq(bus->dhd);
 			bus->dhd->rx_errors++;
 			continue;
@@ -4245,16 +4205,16 @@
 
 	/*
 	 * Flow Control has been moved into the RX headers and this out of band
-	 * method isn't used any more.  Leae this here for possibly
-	 * remaining backward
-	 * compatible with older dongles
+	 * method isn't used any more.
+	 * remaining backward compatible with older dongles.
 	 */
 	if (hmb_data & HMB_DATA_FC) {
-		fcbits =
-		    (hmb_data & HMB_DATA_FCDATA_MASK) >> HMB_DATA_FCDATA_SHIFT;
+		fcbits = (hmb_data & HMB_DATA_FCDATA_MASK) >>
+							HMB_DATA_FCDATA_SHIFT;
 
 		if (fcbits & ~bus->flowcontrol)
 			bus->fc_xoff++;
+
 		if (bus->flowcontrol & ~fcbits)
 			bus->fc_xon++;
 
@@ -4454,7 +4414,7 @@
 					F2SYNC, (u8 *) bus->ctrl_frame_buf,
 					(u32) bus->ctrl_frame_len, NULL,
 					NULL, NULL);
-		ASSERT(ret != BCME_PENDING);
+		ASSERT(ret != -BCME_PENDING);
 
 		if (ret < 0) {
 			/* On failure, abort the command and
@@ -4493,7 +4453,7 @@
 	}
 	/* Send queued frames (limit 1 if rx may still be pending) */
 	else if ((bus->clkstate == CLK_AVAIL) && !bus->fcstate &&
-		 pktq_mlen(&bus->txq, ~bus->flowcontrol) && txlimit
+		 bcm_pktq_mlen(&bus->txq, ~bus->flowcontrol) && txlimit
 		 && DATAOK(bus)) {
 		framecnt = rxdone ? txlimit : min(txlimit, dhd_txminmax);
 		framecnt = dhdsdio_sendfromq(bus, framecnt);
@@ -4514,7 +4474,7 @@
 			"I_CHIPACTIVE interrupt\n", __func__));
 		resched = true;
 	} else if (bus->intstatus || bus->ipend ||
-		(!bus->fcstate && pktq_mlen(&bus->txq, ~bus->flowcontrol) &&
+		(!bus->fcstate && bcm_pktq_mlen(&bus->txq, ~bus->flowcontrol) &&
 			DATAOK(bus)) || PKT_AVAILABLE()) {
 		resched = true;
 	}
@@ -4648,11 +4608,12 @@
 
 		/* Allocate an appropriate-sized packet */
 		len = bus->pktgen_len;
-		pkt = pkt_buf_get_skb(
+		pkt = bcm_pkt_buf_get_skb(
 			(len + SDPCM_HDRLEN + SDPCM_TEST_HDRLEN + DHD_SDALIGN),
 			true);
 		if (!pkt) {
-			DHD_ERROR(("%s: pkt_buf_get_skb failed!\n", __func__));
+			DHD_ERROR(("%s: bcm_pkt_buf_get_skb failed!\n",
+				__func__));
 			break;
 		}
 		PKTALIGN(pkt, (len + SDPCM_HDRLEN + SDPCM_TEST_HDRLEN),
@@ -4679,7 +4640,7 @@
 		default:
 			DHD_ERROR(("Unrecognized pktgen mode %d\n",
 				   bus->pktgen_mode));
-			pkt_buf_free_skb(pkt, true);
+			bcm_pkt_buf_free_skb(pkt, true);
 			bus->pktgen_count = 0;
 			return;
 		}
@@ -4697,8 +4658,9 @@
 #ifdef DHD_DEBUG
 		if (DHD_BYTES_ON() && DHD_DATA_ON()) {
 			data = (u8 *) (pkt->data) + SDPCM_HDRLEN;
-			prhex("dhdsdio_pktgen: Tx Data", data,
-			      pkt->len - SDPCM_HDRLEN);
+			printk(KERN_DEBUG "dhdsdio_pktgen: Tx Data:\n");
+			print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, data,
+					     pkt->len - SDPCM_HDRLEN);
 		}
 #endif
 
@@ -4727,10 +4689,10 @@
 	u8 *data;
 
 	/* Allocate the packet */
-	pkt = pkt_buf_get_skb(SDPCM_HDRLEN + SDPCM_TEST_HDRLEN + DHD_SDALIGN,
-			true);
+	pkt = bcm_pkt_buf_get_skb(SDPCM_HDRLEN + SDPCM_TEST_HDRLEN +
+		DHD_SDALIGN, true);
 	if (!pkt) {
-		DHD_ERROR(("%s: pkt_buf_get_skb failed!\n", __func__));
+		DHD_ERROR(("%s: bcm_pkt_buf_get_skb failed!\n", __func__));
 		return;
 	}
 	PKTALIGN(pkt, (SDPCM_HDRLEN + SDPCM_TEST_HDRLEN), DHD_SDALIGN);
@@ -4762,7 +4724,7 @@
 	if (pktlen < SDPCM_TEST_HDRLEN) {
 		DHD_ERROR(("dhdsdio_restrcv: toss runt frame, pktlen %d\n",
 			   pktlen));
-		pkt_buf_free_skb(pkt, false);
+		bcm_pkt_buf_free_skb(pkt, false);
 		return;
 	}
 
@@ -4780,7 +4742,7 @@
 			DHD_ERROR(("dhdsdio_testrcv: frame length mismatch, "
 				"pktlen %d seq %d" " cmd %d extra %d len %d\n",
 				pktlen, seq, cmd, extra, len));
-			pkt_buf_free_skb(pkt, false);
+			bcm_pkt_buf_free_skb(pkt, false);
 			return;
 		}
 	}
@@ -4795,14 +4757,14 @@
 			bus->pktgen_sent++;
 		} else {
 			bus->pktgen_fail++;
-			pkt_buf_free_skb(pkt, false);
+			bcm_pkt_buf_free_skb(pkt, false);
 		}
 		bus->pktgen_rcvd++;
 		break;
 
 	case SDPCM_TEST_ECHORSP:
 		if (bus->ext_loop) {
-			pkt_buf_free_skb(pkt, false);
+			bcm_pkt_buf_free_skb(pkt, false);
 			bus->pktgen_rcvd++;
 			break;
 		}
@@ -4815,12 +4777,12 @@
 				break;
 			}
 		}
-		pkt_buf_free_skb(pkt, false);
+		bcm_pkt_buf_free_skb(pkt, false);
 		bus->pktgen_rcvd++;
 		break;
 
 	case SDPCM_TEST_DISCARD:
-		pkt_buf_free_skb(pkt, false);
+		bcm_pkt_buf_free_skb(pkt, false);
 		bus->pktgen_rcvd++;
 		break;
 
@@ -4830,7 +4792,7 @@
 		DHD_INFO(("dhdsdio_testrcv: unsupported or unknown command, "
 			"pktlen %d seq %d" " cmd %d extra %d len %d\n",
 			pktlen, seq, cmd, extra, len));
-		pkt_buf_free_skb(pkt, false);
+		bcm_pkt_buf_free_skb(pkt, false);
 		break;
 	}
 
@@ -4952,7 +4914,7 @@
 
 	/* Address could be zero if CONSOLE := 0 in dongle Makefile */
 	if (bus->console_addr == 0)
-		return BCME_UNSUPPORTED;
+		return -ENOTSUPP;
 
 	/* Exclusive bus access */
 	dhd_os_sdlock(bus->dhd);
@@ -4960,7 +4922,7 @@
 	/* Don't allow input if dongle is in reset */
 	if (bus->dhd->dongle_reset) {
 		dhd_os_sdunlock(bus->dhd);
-		return BCME_NOTREADY;
+		return -EPERM;
 	}
 
 	/* Request clock to allow SDIO accesses */
@@ -4991,7 +4953,7 @@
 	/* Bump dongle by sending an empty event pkt.
 	 * sdpcm_sendup (RX) checks for virtual console input.
 	 */
-	pkt = pkt_buf_get_skb(4 + SDPCM_RESERVE);
+	pkt = bcm_pkt_buf_get_skb(4 + SDPCM_RESERVE);
 	if ((pkt != NULL) && bus->clkstate == CLK_AVAIL)
 		dhdsdio_txpkt(bus, pkt, SDPCM_EVENT_CHANNEL, true);
 
@@ -5089,7 +5051,7 @@
 	/* Check the Vendor ID */
 	switch (venid) {
 	case 0x0000:
-	case VENDOR_BROADCOM:
+	case PCI_VENDOR_ID_BROADCOM:
 		break;
 	default:
 		DHD_ERROR(("%s: unknown vendor: 0x%04x\n", __func__, venid));
@@ -5179,7 +5141,7 @@
 	/* if firmware path present try to download and bring up bus */
 	ret = dhd_bus_start(bus->dhd);
 	if (ret != 0) {
-		if (ret == BCME_NOTUP) {
+		if (ret == -ENOLINK) {
 			DHD_ERROR(("%s: dongle is not responding\n", __func__));
 			goto fail;
 		}
@@ -5215,7 +5177,10 @@
 
 #endif				/* DHD_DEBUG */
 
-	/* Force PLL off until si_attach() programs PLL control regs */
+	/*
+	 * Force PLL off until dhdsdio_chip_attach()
+	 * programs PLL control regs
+	 */
 
 	bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR,
 			 DHD_INIT_CLKCTL1, &err);
@@ -5281,34 +5246,26 @@
 	}
 #endif				/* DHD_DEBUG */
 
-	/* si_attach() will provide an SI handle and scan the backplane */
-	bus->sih = si_attach((uint) devid, regsva, DHD_BUS, sdh,
-				   &bus->vars, &bus->varsz);
-	if (!(bus->sih)) {
-		DHD_ERROR(("%s: si_attach failed!\n", __func__));
+	if (dhdsdio_chip_attach(bus, regsva)) {
+		DHD_ERROR(("%s: dhdsdio_chip_attach failed!\n", __func__));
 		goto fail;
 	}
 
-	bcmsdh_chipinfo(sdh, bus->sih->chip, bus->sih->chiprev);
+	bcmsdh_chipinfo(sdh, bus->ci->chip, bus->ci->chiprev);
 
-	if (!dhdsdio_chipmatch((u16) bus->sih->chip)) {
+	if (!dhdsdio_chipmatch((u16) bus->ci->chip)) {
 		DHD_ERROR(("%s: unsupported chip: 0x%04x\n",
-			   __func__, bus->sih->chip));
+			   __func__, bus->ci->chip));
 		goto fail;
 	}
 
-	si_sdiod_drive_strength_init(bus->sih, dhd_sdiod_drive_strength);
+	dhdsdio_sdiod_drive_strength_init(bus, dhd_sdiod_drive_strength);
 
 	/* Get info on the ARM and SOCRAM cores... */
 	if (!DHD_NOPMU(bus)) {
-		if ((si_setcore(bus->sih, ARM7S_CORE_ID, 0)) ||
-		    (si_setcore(bus->sih, ARMCM3_CORE_ID, 0))) {
-			bus->armrev = si_corerev(bus->sih);
-		} else {
-			DHD_ERROR(("%s: failed to find ARM core!\n", __func__));
-			goto fail;
-		}
-		bus->orig_ramsize = si_socram_size(bus->sih);
+		bus->armrev = SBCOREREV(bcmsdh_reg_read(bus->sdh,
+			CORE_SB(bus->ci->armcorebase, sbidhigh), 4));
+		bus->orig_ramsize = bus->ci->ramsize;
 		if (!(bus->orig_ramsize)) {
 			DHD_ERROR(("%s: failed to find SOCRAM memory!\n",
 				   __func__));
@@ -5322,22 +5279,12 @@
 			   bus->ramsize, bus->orig_ramsize));
 	}
 
-	/* ...but normally deal with the SDPCMDEV core */
-	bus->regs = si_setcore(bus->sih, PCMCIA_CORE_ID, 0);
-	if (!bus->regs) {
-		bus->regs = si_setcore(bus->sih, SDIOD_CORE_ID, 0);
-		if (!bus->regs) {
-			DHD_ERROR(("%s: failed to find SDIODEV core!\n",
-					__func__));
-			goto fail;
-		}
-	}
-	bus->sdpcmrev = si_corerev(bus->sih);
+	bus->regs = (void *)bus->ci->buscorebase;
 
 	/* Set core control so an SDIO reset does a backplane reset */
 	OR_REG(&bus->regs->corecontrol, CC_BPRESEN);
 
-	pktq_init(&bus->txq, (PRIOMASK + 1), TXQLEN);
+	bcm_pktq_init(&bus->txq, (PRIOMASK + 1), TXQLEN);
 
 	/* Locate an appropriately-aligned portion of hdrbuf */
 	bus->rxhdr = (u8 *) roundup((unsigned long)&bus->hdrbuf[0], DHD_SDALIGN);
@@ -5425,7 +5372,7 @@
 	/* Query the SD clock speed */
 	if (bcmsdh_iovar_op(sdh, "sd_divisor", NULL, 0,
 			    &bus->sd_divisor, sizeof(s32),
-			    false) != BCME_OK) {
+			    false) != 0) {
 		DHD_ERROR(("%s: fail on %s get\n", __func__, "sd_divisor"));
 		bus->sd_divisor = -1;
 	} else {
@@ -5435,7 +5382,7 @@
 
 	/* Query the SD bus mode */
 	if (bcmsdh_iovar_op(sdh, "sd_mode", NULL, 0,
-			    &bus->sd_mode, sizeof(s32), false) != BCME_OK) {
+			    &bus->sd_mode, sizeof(s32), false) != 0) {
 		DHD_ERROR(("%s: fail on %s get\n", __func__, "sd_mode"));
 		bus->sd_mode = -1;
 	} else {
@@ -5446,7 +5393,7 @@
 	/* Query the F2 block size, set roundup accordingly */
 	fnum = 2;
 	if (bcmsdh_iovar_op(sdh, "sd_blocksize", &fnum, sizeof(s32),
-			    &bus->blocksize, sizeof(s32), false) != BCME_OK) {
+			    &bus->blocksize, sizeof(s32), false) != 0) {
 		bus->blocksize = 0;
 		DHD_ERROR(("%s: fail on %s get\n", __func__, "sd_blocksize"));
 	} else {
@@ -5459,7 +5406,7 @@
 		 default to use if supported */
 	if (bcmsdh_iovar_op(sdh, "sd_rxchain", NULL, 0,
 			    &bus->sd_rxchain, sizeof(s32),
-			    false) != BCME_OK) {
+			    false) != 0) {
 		bus->sd_rxchain = false;
 	} else {
 		DHD_INFO(("%s: bus module (through bcmsdh API) %s chaining\n",
@@ -5509,10 +5456,8 @@
 		bcmsdh_intr_dereg(bus->sdh);
 
 		if (bus->dhd) {
-
-			dhdsdio_release_dongle(bus);
-
 			dhd_detach(bus->dhd);
+			dhdsdio_release_dongle(bus);
 			bus->dhd = NULL;
 		}
 
@@ -5548,13 +5493,10 @@
 	if (bus->dhd && bus->dhd->dongle_reset)
 		return;
 
-	if (bus->sih) {
+	if (bus->ci) {
 		dhdsdio_clkctl(bus, CLK_AVAIL, false);
-#if !defined(BCMLXSDMMC)
-		si_watchdog(bus->sih, 4);
-#endif				/* !defined(BCMLXSDMMC) */
 		dhdsdio_clkctl(bus, CLK_NONE, false);
-		si_detach(bus->sih);
+		dhdsdio_chip_detach(bus);
 		if (bus->vars && bus->varsz)
 			kfree(bus->vars);
 		bus->vars = NULL;
@@ -5642,7 +5584,7 @@
 
 		ularray = kmalloc(bus->ramsize, GFP_ATOMIC);
 		if (!ularray) {
-			bcmerror = BCME_NOMEM;
+			bcmerror = -ENOMEM;
 			goto err;
 		}
 		/* Upload image to verify downloaded contents. */
@@ -5865,7 +5807,7 @@
 	} else {
 		DHD_ERROR(("%s: error reading nvram file: %d\n",
 			   __func__, len));
-		bcmerror = BCME_SDIO_ERROR;
+		bcmerror = -EIO;
 	}
 
 err:
@@ -5954,19 +5896,6 @@
 	return bcmerror;
 }
 
-static int
-dhd_bcmsdh_recv_buf(dhd_bus_t *bus, u32 addr, uint fn, uint flags,
-		    u8 *buf, uint nbytes, struct sk_buff *pkt,
-		    bcmsdh_cmplt_fn_t complete, void *handle)
-{
-	int status;
-
-	/* 4329: GSPI check */
-	status =
-	    bcmsdh_recv_buf(bus->sdh, addr, fn, flags, buf, nbytes, pkt,
-			    complete, handle);
-	return status;
-}
 
 static int
 dhd_bcmsdh_send_buf(dhd_bus_t *bus, u32 addr, uint fn, uint flags,
@@ -5980,8 +5909,8 @@
 
 uint dhd_bus_chip(struct dhd_bus *bus)
 {
-	ASSERT(bus->sih != NULL);
-	return bus->sih->chip;
+	ASSERT(bus->ci != NULL);
+	return bus->ci->chip;
 }
 
 void *dhd_bus_pub(struct dhd_bus *bus)
@@ -6023,7 +5952,7 @@
 			DHD_TRACE(("%s:  WLAN OFF DONE\n", __func__));
 			/* App can now remove power from device */
 		} else
-			bcmerror = BCME_SDIO_ERROR;
+			bcmerror = -EIO;
 	} else {
 		/* App must have restored power to device before calling */
 
@@ -6058,15 +5987,404 @@
 					DHD_TRACE(("%s: WLAN ON DONE\n",
 						   __func__));
 				} else
-					bcmerror = BCME_SDIO_ERROR;
+					bcmerror = -EIO;
 			} else
-				bcmerror = BCME_SDIO_ERROR;
+				bcmerror = -EIO;
 		} else {
-			bcmerror = BCME_NOTDOWN;
+			bcmerror = -EISCONN;
 			DHD_ERROR(("%s: Set DEVRESET=false invoked when device "
 				"is on\n", __func__));
-			bcmerror = BCME_SDIO_ERROR;
+			bcmerror = -EIO;
 		}
 	}
 	return bcmerror;
 }
+
+static int
+dhdsdio_chip_recognition(bcmsdh_info_t *sdh, struct chip_info *ci, void *regs)
+{
+	u32 regdata;
+
+	/*
+	 * Get CC core rev
+	 * Chipid is assume to be at offset 0 from regs arg
+	 * For different chiptypes or old sdio hosts w/o chipcommon,
+	 * other ways of recognition should be added here.
+	 */
+	ci->cccorebase = (u32)regs;
+	regdata = bcmsdh_reg_read(sdh, CORE_CC_REG(ci->cccorebase, chipid), 4);
+	ci->chip = regdata & CID_ID_MASK;
+	ci->chiprev = (regdata & CID_REV_MASK) >> CID_REV_SHIFT;
+
+	DHD_INFO(("%s: chipid=0x%x chiprev=%d\n",
+		__func__, ci->chip, ci->chiprev));
+
+	/* Address of cores for new chips should be added here */
+	switch (ci->chip) {
+	case BCM4329_CHIP_ID:
+		ci->buscorebase = BCM4329_CORE_BUS_BASE;
+		ci->ramcorebase = BCM4329_CORE_SOCRAM_BASE;
+		ci->armcorebase	= BCM4329_CORE_ARM_BASE;
+		ci->ramsize = BCM4329_RAMSIZE;
+		break;
+	default:
+		DHD_ERROR(("%s: chipid 0x%x is not supported\n",
+			__func__, ci->chip));
+		return -ENODEV;
+	}
+
+	regdata = bcmsdh_reg_read(sdh,
+		CORE_SB(ci->cccorebase, sbidhigh), 4);
+	ci->ccrev = SBCOREREV(regdata);
+
+	regdata = bcmsdh_reg_read(sdh,
+		CORE_CC_REG(ci->cccorebase, pmucapabilities), 4);
+	ci->pmurev = regdata & PCAP_REV_MASK;
+
+	regdata = bcmsdh_reg_read(sdh, CORE_SB(ci->buscorebase, sbidhigh), 4);
+	ci->buscorerev = SBCOREREV(regdata);
+	ci->buscoretype = (regdata & SBIDH_CC_MASK) >> SBIDH_CC_SHIFT;
+
+	DHD_INFO(("%s: ccrev=%d, pmurev=%d, buscore rev/type=%d/0x%x\n",
+		__func__, ci->ccrev, ci->pmurev,
+		ci->buscorerev, ci->buscoretype));
+
+	/* get chipcommon capabilites */
+	ci->cccaps = bcmsdh_reg_read(sdh,
+		CORE_CC_REG(ci->cccorebase, capabilities), 4);
+
+	return 0;
+}
+
+static void
+dhdsdio_chip_disablecore(bcmsdh_info_t *sdh, u32 corebase)
+{
+	u32 regdata;
+
+	regdata = bcmsdh_reg_read(sdh,
+		CORE_SB(corebase, sbtmstatelow), 4);
+	if (regdata & SBTML_RESET)
+		return;
+
+	regdata = bcmsdh_reg_read(sdh,
+		CORE_SB(corebase, sbtmstatelow), 4);
+	if ((regdata & (SICF_CLOCK_EN << SBTML_SICF_SHIFT)) != 0) {
+		/*
+		 * set target reject and spin until busy is clear
+		 * (preserve core-specific bits)
+		 */
+		regdata = bcmsdh_reg_read(sdh,
+			CORE_SB(corebase, sbtmstatelow), 4);
+		bcmsdh_reg_write(sdh, CORE_SB(corebase, sbtmstatelow), 4,
+			regdata | SBTML_REJ);
+
+		regdata = bcmsdh_reg_read(sdh,
+			CORE_SB(corebase, sbtmstatelow), 4);
+		udelay(1);
+		SPINWAIT((bcmsdh_reg_read(sdh,
+			CORE_SB(corebase, sbtmstatehigh), 4) &
+			SBTMH_BUSY), 100000);
+
+		regdata = bcmsdh_reg_read(sdh,
+			CORE_SB(corebase, sbtmstatehigh), 4);
+		if (regdata & SBTMH_BUSY)
+			DHD_ERROR(("%s: ARM core still busy\n", __func__));
+
+		regdata = bcmsdh_reg_read(sdh,
+			CORE_SB(corebase, sbidlow), 4);
+		if (regdata & SBIDL_INIT) {
+			regdata = bcmsdh_reg_read(sdh,
+				CORE_SB(corebase, sbimstate), 4) |
+				SBIM_RJ;
+			bcmsdh_reg_write(sdh,
+				CORE_SB(corebase, sbimstate), 4,
+				regdata);
+			regdata = bcmsdh_reg_read(sdh,
+				CORE_SB(corebase, sbimstate), 4);
+			udelay(1);
+			SPINWAIT((bcmsdh_reg_read(sdh,
+				CORE_SB(corebase, sbimstate), 4) &
+				SBIM_BY), 100000);
+		}
+
+		/* set reset and reject while enabling the clocks */
+		bcmsdh_reg_write(sdh,
+			CORE_SB(corebase, sbtmstatelow), 4,
+			(((SICF_FGC | SICF_CLOCK_EN) << SBTML_SICF_SHIFT) |
+			SBTML_REJ | SBTML_RESET));
+		regdata = bcmsdh_reg_read(sdh,
+			CORE_SB(corebase, sbtmstatelow), 4);
+		udelay(10);
+
+		/* clear the initiator reject bit */
+		regdata = bcmsdh_reg_read(sdh,
+			CORE_SB(corebase, sbidlow), 4);
+		if (regdata & SBIDL_INIT) {
+			regdata = bcmsdh_reg_read(sdh,
+				CORE_SB(corebase, sbimstate), 4) &
+				~SBIM_RJ;
+			bcmsdh_reg_write(sdh,
+				CORE_SB(corebase, sbimstate), 4,
+				regdata);
+		}
+	}
+
+	/* leave reset and reject asserted */
+	bcmsdh_reg_write(sdh, CORE_SB(corebase, sbtmstatelow), 4,
+		(SBTML_REJ | SBTML_RESET));
+	udelay(1);
+}
+
+static int
+dhdsdio_chip_attach(struct dhd_bus *bus, void *regs)
+{
+	struct chip_info *ci;
+	int err;
+	u8 clkval, clkset;
+
+	DHD_TRACE(("%s: Enter\n", __func__));
+
+	/* alloc chip_info_t */
+	ci = kmalloc(sizeof(struct chip_info), GFP_ATOMIC);
+	if (NULL == ci) {
+		DHD_ERROR(("%s: malloc failed!\n", __func__));
+		return -ENOMEM;
+	}
+
+	memset((unsigned char *)ci, 0, sizeof(struct chip_info));
+
+	/* bus/core/clk setup for register access */
+	/* Try forcing SDIO core to do ALPAvail request only */
+	clkset = SBSDIO_FORCE_HW_CLKREQ_OFF | SBSDIO_ALP_AVAIL_REQ;
+	bcmsdh_cfg_write(bus->sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR,
+			clkset, &err);
+	if (err) {
+		DHD_ERROR(("%s: error writing for HT off\n", __func__));
+		goto fail;
+	}
+
+	/* If register supported, wait for ALPAvail and then force ALP */
+	/* This may take up to 15 milliseconds */
+	clkval = bcmsdh_cfg_read(bus->sdh, SDIO_FUNC_1,
+			SBSDIO_FUNC1_CHIPCLKCSR, NULL);
+	if ((clkval & ~SBSDIO_AVBITS) == clkset) {
+		SPINWAIT(((clkval =
+				bcmsdh_cfg_read(bus->sdh, SDIO_FUNC_1,
+						SBSDIO_FUNC1_CHIPCLKCSR,
+						NULL)),
+				!SBSDIO_ALPAV(clkval)),
+				PMU_MAX_TRANSITION_DLY);
+		if (!SBSDIO_ALPAV(clkval)) {
+			DHD_ERROR(("%s: timeout on ALPAV wait, clkval 0x%02x\n",
+				__func__, clkval));
+			err = -EBUSY;
+			goto fail;
+		}
+		clkset = SBSDIO_FORCE_HW_CLKREQ_OFF |
+				SBSDIO_FORCE_ALP;
+		bcmsdh_cfg_write(bus->sdh, SDIO_FUNC_1,
+				SBSDIO_FUNC1_CHIPCLKCSR,
+				clkset, &err);
+		udelay(65);
+	} else {
+		DHD_ERROR(("%s: ChipClkCSR access: wrote 0x%02x read 0x%02x\n",
+			__func__, clkset, clkval));
+		err = -EACCES;
+		goto fail;
+	}
+
+	/* Also, disable the extra SDIO pull-ups */
+	bcmsdh_cfg_write(bus->sdh, SDIO_FUNC_1, SBSDIO_FUNC1_SDIOPULLUP, 0,
+			 NULL);
+
+	err = dhdsdio_chip_recognition(bus->sdh, ci, regs);
+	if (err)
+		goto fail;
+
+	/*
+	 * Make sure any on-chip ARM is off (in case strapping is wrong),
+	 * or downloaded code was already running.
+	 */
+	dhdsdio_chip_disablecore(bus->sdh, ci->armcorebase);
+
+	bcmsdh_reg_write(bus->sdh,
+		CORE_CC_REG(ci->cccorebase, gpiopullup), 4, 0);
+	bcmsdh_reg_write(bus->sdh,
+		CORE_CC_REG(ci->cccorebase, gpiopulldown), 4, 0);
+
+	/* Disable F2 to clear any intermediate frame state on the dongle */
+	bcmsdh_cfg_write(bus->sdh, SDIO_FUNC_0, SDIOD_CCCR_IOEN,
+		SDIO_FUNC_ENABLE_1, NULL);
+
+	/* WAR: cmd52 backplane read so core HW will drop ALPReq */
+	clkval = bcmsdh_cfg_read(bus->sdh, SDIO_FUNC_1,
+			0, NULL);
+
+	/* Done with backplane-dependent accesses, can drop clock... */
+	bcmsdh_cfg_write(bus->sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR, 0,
+			 NULL);
+
+	bus->ci = ci;
+	return 0;
+fail:
+	bus->ci = NULL;
+	kfree(ci);
+	return err;
+}
+
+static void
+dhdsdio_chip_resetcore(bcmsdh_info_t *sdh, u32 corebase)
+{
+	u32 regdata;
+
+	/*
+	 * Must do the disable sequence first to work for
+	 * arbitrary current core state.
+	 */
+	dhdsdio_chip_disablecore(sdh, corebase);
+
+	/*
+	 * Now do the initialization sequence.
+	 * set reset while enabling the clock and
+	 * forcing them on throughout the core
+	 */
+	bcmsdh_reg_write(sdh, CORE_SB(corebase, sbtmstatelow), 4,
+		((SICF_FGC | SICF_CLOCK_EN) << SBTML_SICF_SHIFT) |
+		SBTML_RESET);
+	udelay(1);
+
+	regdata = bcmsdh_reg_read(sdh, CORE_SB(corebase, sbtmstatehigh), 4);
+	if (regdata & SBTMH_SERR)
+		bcmsdh_reg_write(sdh, CORE_SB(corebase, sbtmstatehigh), 4, 0);
+
+	regdata = bcmsdh_reg_read(sdh, CORE_SB(corebase, sbimstate), 4);
+	if (regdata & (SBIM_IBE | SBIM_TO))
+		bcmsdh_reg_write(sdh, CORE_SB(corebase, sbimstate), 4,
+			regdata & ~(SBIM_IBE | SBIM_TO));
+
+	/* clear reset and allow it to propagate throughout the core */
+	bcmsdh_reg_write(sdh, CORE_SB(corebase, sbtmstatelow), 4,
+		(SICF_FGC << SBTML_SICF_SHIFT) |
+		(SICF_CLOCK_EN << SBTML_SICF_SHIFT));
+	udelay(1);
+
+	/* leave clock enabled */
+	bcmsdh_reg_write(sdh, CORE_SB(corebase, sbtmstatelow), 4,
+		(SICF_CLOCK_EN << SBTML_SICF_SHIFT));
+	udelay(1);
+}
+
+/* SDIO Pad drive strength to select value mappings */
+struct sdiod_drive_str {
+	u8 strength;	/* Pad Drive Strength in mA */
+	u8 sel;		/* Chip-specific select value */
+};
+
+/* SDIO Drive Strength to sel value table for PMU Rev 1 */
+static const struct sdiod_drive_str sdiod_drive_strength_tab1[] = {
+	{
+	4, 0x2}, {
+	2, 0x3}, {
+	1, 0x0}, {
+	0, 0x0}
+	};
+
+/* SDIO Drive Strength to sel value table for PMU Rev 2, 3 */
+static const struct sdiod_drive_str sdiod_drive_strength_tab2[] = {
+	{
+	12, 0x7}, {
+	10, 0x6}, {
+	8, 0x5}, {
+	6, 0x4}, {
+	4, 0x2}, {
+	2, 0x1}, {
+	0, 0x0}
+	};
+
+/* SDIO Drive Strength to sel value table for PMU Rev 8 (1.8V) */
+static const struct sdiod_drive_str sdiod_drive_strength_tab3[] = {
+	{
+	32, 0x7}, {
+	26, 0x6}, {
+	22, 0x5}, {
+	16, 0x4}, {
+	12, 0x3}, {
+	8, 0x2}, {
+	4, 0x1}, {
+	0, 0x0}
+	};
+
+#define SDIOD_DRVSTR_KEY(chip, pmu)     (((chip) << 16) | (pmu))
+
+static void
+dhdsdio_sdiod_drive_strength_init(struct dhd_bus *bus, u32 drivestrength) {
+	struct sdiod_drive_str *str_tab = NULL;
+	u32 str_mask = 0;
+	u32 str_shift = 0;
+	char chn[8];
+
+	if (!(bus->ci->cccaps & CC_CAP_PMU))
+		return;
+
+	switch (SDIOD_DRVSTR_KEY(bus->ci->chip, bus->ci->pmurev)) {
+	case SDIOD_DRVSTR_KEY(BCM4325_CHIP_ID, 1):
+		str_tab = (struct sdiod_drive_str *)&sdiod_drive_strength_tab1;
+		str_mask = 0x30000000;
+		str_shift = 28;
+		break;
+	case SDIOD_DRVSTR_KEY(BCM4325_CHIP_ID, 2):
+	case SDIOD_DRVSTR_KEY(BCM4325_CHIP_ID, 3):
+		str_tab = (struct sdiod_drive_str *)&sdiod_drive_strength_tab2;
+		str_mask = 0x00003800;
+		str_shift = 11;
+		break;
+	case SDIOD_DRVSTR_KEY(BCM4336_CHIP_ID, 8):
+		str_tab = (struct sdiod_drive_str *)&sdiod_drive_strength_tab3;
+		str_mask = 0x00003800;
+		str_shift = 11;
+		break;
+	default:
+		DHD_ERROR(("No SDIO Drive strength init"
+			"done for chip %s rev %d pmurev %d\n",
+			bcm_chipname(bus->ci->chip, chn, 8),
+			bus->ci->chiprev, bus->ci->pmurev));
+		break;
+	}
+
+	if (str_tab != NULL) {
+		u32 drivestrength_sel = 0;
+		u32 cc_data_temp;
+		int i;
+
+		for (i = 0; str_tab[i].strength != 0; i++) {
+			if (drivestrength >= str_tab[i].strength) {
+				drivestrength_sel = str_tab[i].sel;
+				break;
+			}
+		}
+
+		bcmsdh_reg_write(bus->sdh,
+			CORE_CC_REG(bus->ci->cccorebase, chipcontrol_addr),
+			4, 1);
+		cc_data_temp = bcmsdh_reg_read(bus->sdh,
+			CORE_CC_REG(bus->ci->cccorebase, chipcontrol_addr), 4);
+		cc_data_temp &= ~str_mask;
+		drivestrength_sel <<= str_shift;
+		cc_data_temp |= drivestrength_sel;
+		bcmsdh_reg_write(bus->sdh,
+			CORE_CC_REG(bus->ci->cccorebase, chipcontrol_addr),
+			4, cc_data_temp);
+
+		DHD_INFO(("SDIO: %dmA drive strength selected, set to 0x%08x\n",
+			drivestrength, cc_data_temp));
+	}
+}
+
+static void
+dhdsdio_chip_detach(struct dhd_bus *bus)
+{
+	DHD_TRACE(("%s: Enter\n", __func__));
+
+	kfree(bus->ci);
+	bus->ci = NULL;
+}
diff -druN linux-2.6.39-libre/drivers/staging/brcm80211/brcmfmac/hndpmu.c linux-3.0-rc7-libre/drivers/staging/brcm80211/brcmfmac/hndpmu.c
--- linux-2.6.39-libre/drivers/staging/brcm80211/brcmfmac/hndpmu.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/brcm80211/brcmfmac/hndpmu.c	1969-12-31 19:00:00.000000000 -0500
@@ -1 +0,0 @@
-#include "../util/hndpmu.c"
diff -druN linux-2.6.39-libre/drivers/staging/brcm80211/brcmfmac/Makefile linux-3.0-rc7-libre/drivers/staging/brcm80211/brcmfmac/Makefile
--- linux-2.6.39-libre/drivers/staging/brcm80211/brcmfmac/Makefile	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/brcm80211/brcmfmac/Makefile	2011-07-11 19:51:52.000000000 -0400
@@ -36,8 +36,7 @@
 
 ccflags-y += \
 	-Idrivers/staging/brcm80211/brcmfmac	\
-	-Idrivers/staging/brcm80211/include		\
-	-Idrivers/staging/brcm80211/util
+	-Idrivers/staging/brcm80211/include
 
 DHDOFILES = \
 	wl_cfg80211.o \
@@ -51,13 +50,7 @@
 	bcmsdh.o \
 	bcmsdh_linux.o	\
 	bcmsdh_sdmmc.o \
-	bcmsdh_sdmmc_linux.o \
-	aiutils.o \
-	siutils.o \
-	sbutils.o \
-	bcmutils.o \
-	bcmwifi.o \
-	hndpmu.o
+	bcmsdh_sdmmc_linux.o
 
-obj-m += brcmfmac.o
+obj-$(CONFIG_BRCMFMAC) += brcmfmac.o
 brcmfmac-objs += $(DHDOFILES)
diff -druN linux-2.6.39-libre/drivers/staging/brcm80211/brcmfmac/README linux-3.0-rc7-libre/drivers/staging/brcm80211/brcmfmac/README
--- linux-2.6.39-libre/drivers/staging/brcm80211/brcmfmac/README	2011-05-19 02:13:41.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/brcm80211/brcmfmac/README	2011-07-11 19:51:52.000000000 -0400
@@ -1,27 +1,2 @@
-Broadcom fullmac driver
-
-This is production driver.
 
-What's here
-===========
-- Completely open source host driver, no binary object files
-- Features Broadcom's OneDriver architecture (single source base for
-  supported chips and architectures)
-- On-chip firmware loaded using standard request_firmware()
-- Support for BCM4329(SDIO)
-
-What's done
-==========
-- Integration with cfg80211 stack
-- Most of Mac functionality is performed in dongle
-- A-MPDU single stream rates
-- BCM4329:	Dualband, Single stream, 20MHz channels
-
-/*(DEBLOBBED)*/
-
-Contact Info:
-=============
-Brett Rudley	brudley@broadcom.com
-Henry Ptasinski henryp@broadcom.com
-Nohee Ko	noheek@broadcom.com
 
diff -druN linux-2.6.39-libre/drivers/staging/brcm80211/brcmfmac/sbutils.c linux-3.0-rc7-libre/drivers/staging/brcm80211/brcmfmac/sbutils.c
--- linux-2.6.39-libre/drivers/staging/brcm80211/brcmfmac/sbutils.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/brcm80211/brcmfmac/sbutils.c	1969-12-31 19:00:00.000000000 -0500
@@ -1 +0,0 @@
-#include "../util/sbutils.c"
diff -druN linux-2.6.39-libre/drivers/staging/brcm80211/brcmfmac/siutils.c linux-3.0-rc7-libre/drivers/staging/brcm80211/brcmfmac/siutils.c
--- linux-2.6.39-libre/drivers/staging/brcm80211/brcmfmac/siutils.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/brcm80211/brcmfmac/siutils.c	1969-12-31 19:00:00.000000000 -0500
@@ -1 +0,0 @@
-#include "../util/siutils.c"
diff -druN linux-2.6.39-libre/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c linux-3.0-rc7-libre/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c
--- linux-2.6.39-libre/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c	2011-05-19 02:13:45.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c	2011-07-21 06:56:08.000000000 -0400
@@ -39,11 +39,13 @@
 #include <linux/firmware.h>
 #include <wl_cfg80211.h>
 
+void sdioh_sdio_set_host_pm_flags(int flag);
+
 static struct sdio_func *cfg80211_sdio_func;
 static struct wl_dev *wl_cfg80211_dev;
 static const u8 ether_bcast[ETH_ALEN] = {255, 255, 255, 255, 255, 255};
 
-u32 wl_dbg_level = WL_DBG_ERR | WL_DBG_INFO;
+u32 wl_dbg_level = WL_DBG_ERR;
 
 #define WL_4329_FW_FILE "/*(DEBLOBBED)*/"
 #define WL_4329_NVRAM_FILE "brcm/bcm4329-fullmac-4.txt"
@@ -180,41 +182,34 @@
 ** cfg80211 connect utilites
 */
 static s32 wl_set_wpa_version(struct net_device *dev,
-				struct cfg80211_connect_params *sme);
+			struct cfg80211_connect_params *sme);
 static s32 wl_set_auth_type(struct net_device *dev,
-			      struct cfg80211_connect_params *sme);
+			struct cfg80211_connect_params *sme);
 static s32 wl_set_set_cipher(struct net_device *dev,
-			       struct cfg80211_connect_params *sme);
+			struct cfg80211_connect_params *sme);
 static s32 wl_set_key_mgmt(struct net_device *dev,
-			     struct cfg80211_connect_params *sme);
+			struct cfg80211_connect_params *sme);
 static s32 wl_set_set_sharedkey(struct net_device *dev,
-				  struct cfg80211_connect_params *sme);
+			struct cfg80211_connect_params *sme);
 static s32 wl_get_assoc_ies(struct wl_priv *wl);
+static void wl_clear_assoc_ies(struct wl_priv *wl);
 static void wl_ch_to_chanspec(int ch,
 	struct wl_join_params *join_params, size_t *join_params_size);
 
 /*
 ** information element utilities
 */
-static void wl_rst_ie(struct wl_priv *wl);
 static __used s32 wl_add_ie(struct wl_priv *wl, u8 t, u8 l, u8 *v);
-static s32 wl_mrg_ie(struct wl_priv *wl, u8 *ie_stream, u16 ie_size);
-static s32 wl_cp_ie(struct wl_priv *wl, u8 *dst, u16 dst_size);
-static u32 wl_get_ielen(struct wl_priv *wl);
-
 static s32 wl_mode_to_nl80211_iftype(s32 mode);
-
 static struct wireless_dev *wl_alloc_wdev(s32 sizeof_iface,
-					  struct device *dev);
+			struct device *dev);
 static void wl_free_wdev(struct wl_priv *wl);
-
 static s32 wl_inform_bss(struct wl_priv *wl);
 static s32 wl_inform_single_bss(struct wl_priv *wl, struct wl_bss_info *bi);
 static s32 wl_update_bss_info(struct wl_priv *wl);
-
 static s32 wl_add_keyext(struct wiphy *wiphy, struct net_device *dev,
-			   u8 key_idx, const u8 *mac_addr,
-			   struct key_params *params);
+			u8 key_idx, const u8 *mac_addr,
+			struct key_params *params);
 
 /*
 ** key indianess swap utilities
@@ -240,7 +235,6 @@
 ** ibss mode utilities
 */
 static bool wl_is_ibssmode(struct wl_priv *wl);
-static bool wl_is_ibssstarter(struct wl_priv *wl);
 
 /*
 ** dongle up/down , default configuration utilities
@@ -248,7 +242,6 @@
 static bool wl_is_linkdown(struct wl_priv *wl, const wl_event_msg_t *e);
 static bool wl_is_linkup(struct wl_priv *wl, const wl_event_msg_t *e);
 static bool wl_is_nonetwork(struct wl_priv *wl, const wl_event_msg_t *e);
-static void wl_link_up(struct wl_priv *wl);
 static void wl_link_down(struct wl_priv *wl);
 static s32 wl_dongle_mode(struct net_device *ndev, s32 iftype);
 static s32 __wl_cfg80211_up(struct wl_priv *wl);
@@ -266,18 +259,19 @@
 static s32 wl_dongle_power(struct net_device *ndev, u32 power_mode);
 static s32 wl_dongle_glom(struct net_device *ndev, u32 glom,
 			    u32 dongle_align);
-static s32 wl_dongle_roam(struct net_device *ndev, u32 roamvar,
-			    u32 bcn_timeout);
-static s32 wl_dongle_eventmsg(struct net_device *ndev);
-static s32 wl_dongle_scantime(struct net_device *ndev, s32 scan_assoc_time,
-				s32 scan_unassoc_time);
 static s32 wl_dongle_offload(struct net_device *ndev, s32 arpoe,
 			       s32 arp_ol);
 static s32 wl_pattern_atoh(s8 *src, s8 *dst);
 static s32 wl_dongle_filter(struct net_device *ndev, u32 filter_mode);
 static s32 wl_update_wiphybands(struct wl_priv *wl);
 #endif				/* !EMBEDDED_PLATFORM */
+
+static s32 wl_dongle_eventmsg(struct net_device *ndev);
+static s32 wl_dongle_scantime(struct net_device *ndev, s32 scan_assoc_time,
+				s32 scan_unassoc_time, s32 scan_passive_time);
 static s32 wl_config_dongle(struct wl_priv *wl, bool need_lock);
+static s32 wl_dongle_roam(struct net_device *ndev, u32 roamvar,
+			    u32 bcn_timeout);
 
 /*
 ** iscan handler
@@ -352,30 +346,6 @@
 } while (0)
 
 extern int dhd_wait_pend8021x(struct net_device *dev);
-
-#if (WL_DBG_LEVEL > 0)
-#define WL_DBG_ESTR_MAX	32
-static s8 wl_dbg_estr[][WL_DBG_ESTR_MAX] = {
-	"SET_SSID", "JOIN", "START", "AUTH", "AUTH_IND",
-	"DEAUTH", "DEAUTH_IND", "ASSOC", "ASSOC_IND", "REASSOC",
-	"REASSOC_IND", "DISASSOC", "DISASSOC_IND", "QUIET_START", "QUIET_END",
-	"BEACON_RX", "LINK", "MIC_ERROR", "NDIS_LINK", "ROAM",
-	"TXFAIL", "PMKID_CACHE", "RETROGRADE_TSF", "PRUNE", "AUTOAUTH",
-	"EAPOL_MSG", "SCAN_COMPLETE", "ADDTS_IND", "DELTS_IND", "BCNSENT_IND",
-	"BCNRX_MSG", "BCNLOST_MSG", "ROAM_PREP", "PFN_NET_FOUND",
-	"PFN_NET_LOST",
-	"RESET_COMPLETE", "JOIN_START", "ROAM_START", "ASSOC_START",
-	"IBSS_ASSOC",
-	"RADIO", "PSM_WATCHDOG",
-	"PROBREQ_MSG",
-	"SCAN_CONFIRM_IND", "PSK_SUP", "COUNTRY_CODE_CHANGED",
-	"EXCEEDED_MEDIUM_TIME", "ICV_ERROR",
-	"UNICAST_DECODE_ERROR", "MULTICAST_DECODE_ERROR", "TRACE",
-	"IF",
-	"RSSI", "PFN_SCAN_COMPLETE", "ACTION_FRAME", "ACTION_FRAME_COMPLETE",
-};
-#endif				/* WL_DBG_LEVEL */
-
 #define CHAN2G(_channel, _freq, _flags) {			\
 	.band			= IEEE80211_BAND_2GHZ,		\
 	.center_freq		= (_freq),			\
@@ -604,10 +574,11 @@
 	struct wl_priv *wl = wiphy_to_wl(wiphy);
 	struct wireless_dev *wdev;
 	s32 infra = 0;
-	s32 ap = 0;
 	s32 err = 0;
 
+	WL_TRACE("Enter\n");
 	CHECK_SYS_UP();
+
 	switch (type) {
 	case NL80211_IFTYPE_MONITOR:
 	case NL80211_IFTYPE_WDS:
@@ -616,32 +587,34 @@
 		return -EOPNOTSUPP;
 	case NL80211_IFTYPE_ADHOC:
 		wl->conf->mode = WL_MODE_IBSS;
+		infra = 0;
 		break;
 	case NL80211_IFTYPE_STATION:
 		wl->conf->mode = WL_MODE_BSS;
 		infra = 1;
 		break;
 	default:
-		return -EINVAL;
+		err = -EINVAL;
+		goto done;
 	}
+
 	infra = cpu_to_le32(infra);
-	ap = cpu_to_le32(ap);
-	wdev = ndev->ieee80211_ptr;
-	wdev->iftype = type;
-	WL_DBG("%s : ap (%d), infra (%d)\n", ndev->name, ap, infra);
 	err = wl_dev_ioctl(ndev, WLC_SET_INFRA, &infra, sizeof(infra));
 	if (unlikely(err)) {
 		WL_ERR("WLC_SET_INFRA error (%d)\n", err);
-		return err;
-	}
-	err = wl_dev_ioctl(ndev, WLC_SET_AP, &ap, sizeof(ap));
-	if (unlikely(err)) {
-		WL_ERR("WLC_SET_AP error (%d)\n", err);
-		return err;
+		err = -EAGAIN;
+	} else {
+		wdev = ndev->ieee80211_ptr;
+		wdev->iftype = type;
 	}
 
-	/* -EINPROGRESS: Call commit handler */
-	return -EINPROGRESS;
+	WL_INFO("IF Type = %s\n",
+		(wl->conf->mode == WL_MODE_IBSS) ? "Adhoc" : "Infra");
+
+done:
+	WL_TRACE("Exit\n");
+
+	return err;
 }
 
 static void wl_iscan_prep(struct wl_scan_params *params, struct wlc_ssid *ssid)
@@ -740,7 +713,7 @@
 	err = wl_dev_ioctl(wl_to_ndev(wl), WLC_SET_PASSIVE_SCAN,
 			&passive_scan, sizeof(passive_scan));
 	if (unlikely(err)) {
-		WL_DBG("error (%d)\n", err);
+		WL_ERR("error (%d)\n", err);
 		return err;
 	}
 	wl_set_mpc(ndev, 0);
@@ -774,26 +747,25 @@
 		       (int)wl->status);
 		return -EAGAIN;
 	}
+	if (test_bit(WL_STATUS_CONNECTING, &wl->status)) {
+		WL_ERR("Connecting : status (%d)\n",
+		       (int)wl->status);
+		return -EAGAIN;
+	}
 
 	iscan_req = false;
 	spec_scan = false;
-	if (request) {		/* scan bss */
+	if (request) {
+		/* scan bss */
 		ssids = request->ssids;
-		if (wl->iscan_on && (!ssids || !ssids->ssid_len)) {	/* for
-							 * specific scan,
-							 * ssids->ssid_len has
-							 * non-zero(ssid string)
-							 * length.
-							 * Otherwise this is 0.
-							 * we do not iscan for
-							 * specific scan request
-							 */
+		if (wl->iscan_on && (!ssids || !ssids->ssid_len))
 			iscan_req = true;
-		}
-	} else {		/* scan in ibss */
+	} else {
+		/* scan in ibss */
 		/* we don't do iscan in ibss */
 		ssids = this_ssid;
 	}
+
 	wl->scan_request = request;
 	set_bit(WL_STATUS_SCANNING, &wl->status);
 	if (iscan_req) {
@@ -803,7 +775,7 @@
 		else
 			goto scan_out;
 	} else {
-		WL_DBG("ssid \"%s\", ssid_len (%d)\n",
+		WL_SCAN("ssid \"%s\", ssid_len (%d)\n",
 		       ssids->ssid, ssids->ssid_len);
 		memset(&sr->ssid, 0, sizeof(sr->ssid));
 		sr->ssid.SSID_len =
@@ -811,13 +783,11 @@
 		if (sr->ssid.SSID_len) {
 			memcpy(sr->ssid.SSID, ssids->ssid, sr->ssid.SSID_len);
 			sr->ssid.SSID_len = cpu_to_le32(sr->ssid.SSID_len);
-			WL_DBG("Specific scan ssid=\"%s\" len=%d\n",
-			       sr->ssid.SSID, sr->ssid.SSID_len);
 			spec_scan = true;
 		} else {
-			WL_DBG("Broadcast scan\n");
+			WL_SCAN("Broadcast scan\n");
 		}
-		WL_DBG("sr->ssid.SSID_len (%d)\n", sr->ssid.SSID_len);
+
 		passive_scan = wl->active_scan ? 0 : 1;
 		err = wl_dev_ioctl(ndev, WLC_SET_PASSIVE_SCAN,
 				&passive_scan, sizeof(passive_scan));
@@ -854,13 +824,15 @@
 {
 	s32 err = 0;
 
+	WL_TRACE("Enter\n");
+
 	CHECK_SYS_UP();
+
 	err = __wl_cfg80211_scan(wiphy, ndev, request, NULL);
-	if (unlikely(err)) {
-		WL_DBG("scan error (%d)\n", err);
-		return err;
-	}
+	if (unlikely(err))
+		WL_ERR("scan error (%d)\n", err);
 
+	WL_TRACE("Exit\n");
 	return err;
 }
 
@@ -875,9 +847,8 @@
 	BUG_ON(!len);
 
 	err = wl_dev_ioctl(dev, WLC_SET_VAR, buf, len);
-	if (unlikely(err)) {
+	if (unlikely(err))
 		WL_ERR("error (%d)\n", err);
-	}
 
 	return err;
 }
@@ -898,9 +869,9 @@
 			sizeof(var.buf));
 	BUG_ON(!len);
 	err = wl_dev_ioctl(dev, WLC_GET_VAR, &var, len);
-	if (unlikely(err)) {
+	if (unlikely(err))
 		WL_ERR("error (%d)\n", err);
-	}
+
 	*retval = le32_to_cpu(var.val);
 
 	return err;
@@ -911,10 +882,9 @@
 	s32 err = 0;
 
 	err = wl_dev_intvar_set(dev, "rtsthresh", rts_threshold);
-	if (unlikely(err)) {
+	if (unlikely(err))
 		WL_ERR("Error (%d)\n", err);
-		return err;
-	}
+
 	return err;
 }
 
@@ -923,10 +893,9 @@
 	s32 err = 0;
 
 	err = wl_dev_intvar_set(dev, "fragthresh", frag_threshold);
-	if (unlikely(err)) {
+	if (unlikely(err))
 		WL_ERR("Error (%d)\n", err);
-		return err;
-	}
+
 	return err;
 }
 
@@ -950,37 +919,40 @@
 	struct net_device *ndev = wl_to_ndev(wl);
 	s32 err = 0;
 
+	WL_TRACE("Enter\n");
 	CHECK_SYS_UP();
+
 	if (changed & WIPHY_PARAM_RTS_THRESHOLD &&
 	    (wl->conf->rts_threshold != wiphy->rts_threshold)) {
 		wl->conf->rts_threshold = wiphy->rts_threshold;
 		err = wl_set_rts(ndev, wl->conf->rts_threshold);
 		if (!err)
-			return err;
+			goto done;
 	}
 	if (changed & WIPHY_PARAM_FRAG_THRESHOLD &&
 	    (wl->conf->frag_threshold != wiphy->frag_threshold)) {
 		wl->conf->frag_threshold = wiphy->frag_threshold;
 		err = wl_set_frag(ndev, wl->conf->frag_threshold);
 		if (!err)
-			return err;
+			goto done;
 	}
 	if (changed & WIPHY_PARAM_RETRY_LONG
 	    && (wl->conf->retry_long != wiphy->retry_long)) {
 		wl->conf->retry_long = wiphy->retry_long;
 		err = wl_set_retry(ndev, wl->conf->retry_long, true);
 		if (!err)
-			return err;
+			goto done;
 	}
 	if (changed & WIPHY_PARAM_RETRY_SHORT
 	    && (wl->conf->retry_short != wiphy->retry_short)) {
 		wl->conf->retry_short = wiphy->retry_short;
 		err = wl_set_retry(ndev, wl->conf->retry_short, false);
-		if (!err) {
-			return err;
-		}
+		if (!err)
+			goto done;
 	}
 
+done:
+	WL_TRACE("Exit\n");
 	return err;
 }
 
@@ -989,68 +961,139 @@
 		      struct cfg80211_ibss_params *params)
 {
 	struct wl_priv *wl = wiphy_to_wl(wiphy);
-	struct cfg80211_bss *bss;
-	struct ieee80211_channel *chan;
 	struct wl_join_params join_params;
-	struct cfg80211_ssid ssid;
-	s32 scan_retry = 0;
+	size_t join_params_size = 0;
 	s32 err = 0;
+	s32 wsec = 0;
+	s32 bcnprd;
 
+	WL_TRACE("Enter\n");
 	CHECK_SYS_UP();
-	if (params->bssid) {
-		WL_ERR("Invalid bssid\n");
+
+	if (params->ssid)
+		WL_CONN("SSID: %s\n", params->ssid);
+	else {
+		WL_CONN("SSID: NULL, Not supported\n");
 		return -EOPNOTSUPP;
 	}
-	bss = cfg80211_get_ibss(wiphy, NULL, params->ssid, params->ssid_len);
-	if (!bss) {
-		memcpy(ssid.ssid, params->ssid, params->ssid_len);
-		ssid.ssid_len = params->ssid_len;
-		do {
-			if (unlikely
-			    (__wl_cfg80211_scan(wiphy, dev, NULL, &ssid) ==
-			     -EBUSY)) {
-				wl_delay(150);
-			} else {
-				break;
-			}
-		} while (++scan_retry < WL_SCAN_RETRY_MAX);
-		rtnl_unlock();	/* to allow scan_inform to paropagate
-					 to cfg80211 plane */
-		schedule_timeout_interruptible(4 * HZ);	/* wait 4 secons
-						 till scan done.... */
-		rtnl_lock();
-		bss = cfg80211_get_ibss(wiphy, NULL,
-					params->ssid, params->ssid_len);
+
+	if (params->bssid)
+		WL_CONN("BSSID: %02X %02X %02X %02X %02X %02X\n",
+		params->bssid[0], params->bssid[1], params->bssid[2],
+		params->bssid[3], params->bssid[4], params->bssid[5]);
+	else
+		WL_CONN("No BSSID specified\n");
+
+	if (params->channel)
+		WL_CONN("channel: %d\n", params->channel->center_freq);
+	else
+		WL_CONN("no channel specified\n");
+
+	if (params->channel_fixed)
+		WL_CONN("fixed channel required\n");
+	else
+		WL_CONN("no fixed channel required\n");
+
+	if (params->ie && params->ie_len)
+		WL_CONN("ie len: %d\n", params->ie_len);
+	else
+		WL_CONN("no ie specified\n");
+
+	if (params->beacon_interval)
+		WL_CONN("beacon interval: %d\n", params->beacon_interval);
+	else
+		WL_CONN("no beacon interval specified\n");
+
+	if (params->basic_rates)
+		WL_CONN("basic rates: %08X\n", params->basic_rates);
+	else
+		WL_CONN("no basic rates specified\n");
+
+	if (params->privacy)
+		WL_CONN("privacy required\n");
+	else
+		WL_CONN("no privacy required\n");
+
+	/* Configure Privacy for starter */
+	if (params->privacy)
+		wsec |= WEP_ENABLED;
+
+	err = wl_dev_intvar_set(dev, "wsec", wsec);
+	if (unlikely(err)) {
+		WL_ERR("wsec failed (%d)\n", err);
+		goto done;
 	}
-	if (bss) {
-		wl->ibss_starter = false;
-		WL_DBG("Found IBSS\n");
+
+	/* Configure Beacon Interval for starter */
+	if (params->beacon_interval)
+		bcnprd = cpu_to_le32(params->beacon_interval);
+	else
+		bcnprd = cpu_to_le32(100);
+
+	err = wl_dev_ioctl(dev, WLC_SET_BCNPRD, &bcnprd, sizeof(bcnprd));
+	if (unlikely(err)) {
+		WL_ERR("WLC_SET_BCNPRD failed (%d)\n", err);
+		goto done;
+	}
+
+	/* Configure required join parameter */
+	memset(&join_params, 0, sizeof(wl_join_params_t));
+
+	/* SSID */
+	join_params.ssid.SSID_len =
+			(params->ssid_len > 32) ? 32 : params->ssid_len;
+	memcpy(join_params.ssid.SSID, params->ssid, join_params.ssid.SSID_len);
+	join_params.ssid.SSID_len = cpu_to_le32(join_params.ssid.SSID_len);
+	join_params_size = sizeof(join_params.ssid);
+	wl_update_prof(wl, NULL, &join_params.ssid, WL_PROF_SSID);
+
+	/* BSSID */
+	if (params->bssid) {
+		memcpy(join_params.params.bssid, params->bssid, ETH_ALEN);
+		join_params_size =
+			sizeof(join_params.ssid) + WL_ASSOC_PARAMS_FIXED_SIZE;
 	} else {
-		wl->ibss_starter = true;
+		memcpy(join_params.params.bssid, ether_bcast, ETH_ALEN);
 	}
-	chan = params->channel;
-	if (chan)
-		wl->channel = ieee80211_frequency_to_channel(chan->center_freq);
-	/*
-	 ** Join with specific BSSID and cached SSID
-	 ** If SSID is zero join based on BSSID only
-	 */
-	memset(&join_params, 0, sizeof(join_params));
-	memcpy((void *)join_params.ssid.SSID, (void *)params->ssid,
-	       params->ssid_len);
-	join_params.ssid.SSID_len = cpu_to_le32(params->ssid_len);
-	if (params->bssid)
-		memcpy(&join_params.params.bssid, params->bssid,
-		       ETH_ALEN);
-	else
-		memset(&join_params.params.bssid, 0, ETH_ALEN);
+	wl_update_prof(wl, NULL, &join_params.params.bssid, WL_PROF_BSSID);
 
-	err = wl_dev_ioctl(dev, WLC_SET_SSID, &join_params,
-			sizeof(join_params));
+	/* Channel */
+	if (params->channel) {
+		u32 target_channel;
+
+		wl->channel =
+			ieee80211_frequency_to_channel(
+				params->channel->center_freq);
+		if (params->channel_fixed) {
+			/* adding chanspec */
+			wl_ch_to_chanspec(wl->channel,
+				&join_params, &join_params_size);
+		}
+
+		/* set channel for starter */
+		target_channel = cpu_to_le32(wl->channel);
+		err = wl_dev_ioctl(dev, WLC_SET_CHANNEL,
+			&target_channel, sizeof(target_channel));
+		if (unlikely(err)) {
+			WL_ERR("WLC_SET_CHANNEL failed (%d)\n", err);
+			goto done;
+		}
+	} else
+		wl->channel = 0;
+
+	wl->ibss_starter = false;
+
+
+	err = wl_dev_ioctl(dev, WLC_SET_SSID, &join_params, join_params_size);
 	if (unlikely(err)) {
-		WL_ERR("Error (%d)\n", err);
-		return err;
+		WL_ERR("WLC_SET_SSID failed (%d)\n", err);
+		goto done;
 	}
+
+	set_bit(WL_STATUS_CONNECTING, &wl->status);
+
+done:
+	WL_TRACE("Exit\n");
 	return err;
 }
 
@@ -1059,9 +1102,13 @@
 	struct wl_priv *wl = wiphy_to_wl(wiphy);
 	s32 err = 0;
 
+	WL_TRACE("Enter\n");
 	CHECK_SYS_UP();
+
 	wl_link_down(wl);
 
+	WL_TRACE("Exit\n");
+
 	return err;
 }
 
@@ -1079,7 +1126,7 @@
 		val = WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED;
 	else
 		val = WPA_AUTH_DISABLED;
-	WL_DBG("setting wpa_auth to 0x%0x\n", val);
+	WL_CONN("setting wpa_auth to 0x%0x\n", val);
 	err = wl_dev_intvar_set(dev, "wpa_auth", val);
 	if (unlikely(err)) {
 		WL_ERR("set wpa_auth failed (%d)\n", err);
@@ -1101,18 +1148,18 @@
 	switch (sme->auth_type) {
 	case NL80211_AUTHTYPE_OPEN_SYSTEM:
 		val = 0;
-		WL_DBG("open system\n");
+		WL_CONN("open system\n");
 		break;
 	case NL80211_AUTHTYPE_SHARED_KEY:
 		val = 1;
-		WL_DBG("shared key\n");
+		WL_CONN("shared key\n");
 		break;
 	case NL80211_AUTHTYPE_AUTOMATIC:
 		val = 2;
-		WL_DBG("automatic\n");
+		WL_CONN("automatic\n");
 		break;
 	case NL80211_AUTHTYPE_NETWORK_EAP:
-		WL_DBG("network eap\n");
+		WL_CONN("network eap\n");
 	default:
 		val = 2;
 		WL_ERR("invalid auth type (%d)\n", sme->auth_type);
@@ -1181,7 +1228,7 @@
 		}
 	}
 
-	WL_DBG("pval (%d) gval (%d)\n", pval, gval);
+	WL_CONN("pval (%d) gval (%d)\n", pval, gval);
 	err = wl_dev_intvar_set(dev, "wsec", pval | gval);
 	if (unlikely(err)) {
 		WL_ERR("error (%d)\n", err);
@@ -1237,7 +1284,7 @@
 			}
 		}
 
-		WL_DBG("setting wpa_auth to %d\n", val);
+		WL_CONN("setting wpa_auth to %d\n", val);
 		err = wl_dev_intvar_set(dev, "wpa_auth", val);
 		if (unlikely(err)) {
 			WL_ERR("could not set wpa_auth (%d)\n", err);
@@ -1260,10 +1307,10 @@
 	s32 val;
 	s32 err = 0;
 
-	WL_DBG("key len (%d)\n", sme->key_len);
+	WL_CONN("key len (%d)\n", sme->key_len);
 	if (sme->key_len) {
 		sec = wl_read_prof(wl, WL_PROF_SEC);
-		WL_DBG("wpa_versions 0x%x cipher_pairwise 0x%x\n",
+		WL_CONN("wpa_versions 0x%x cipher_pairwise 0x%x\n",
 		       sec->wpa_versions, sec->cipher_pairwise);
 		if (!
 		    (sec->wpa_versions & (NL80211_WPA_VERSION_1 |
@@ -1292,9 +1339,9 @@
 				return -EINVAL;
 			}
 			/* Set the new key/index */
-			WL_DBG("key length (%d) key index (%d) algo (%d)\n",
+			WL_CONN("key length (%d) key index (%d) algo (%d)\n",
 			       key.len, key.index, key.algo);
-			WL_DBG("key \"%s\"\n", key.data);
+			WL_CONN("key \"%s\"\n", key.data);
 			swap_key_from_BE(&key);
 			err = wl_dev_ioctl(dev, WLC_SET_KEY, &key,
 					sizeof(key));
@@ -1303,7 +1350,7 @@
 				return err;
 			}
 			if (sec->auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM) {
-				WL_DBG("set auth_type to shared key\n");
+				WL_CONN("set auth_type to shared key\n");
 				val = 1;	/* shared key */
 				err = wl_dev_intvar_set(dev, "auth", val);
 				if (unlikely(err)) {
@@ -1327,17 +1374,24 @@
 
 	s32 err = 0;
 
+	WL_TRACE("Enter\n");
 	CHECK_SYS_UP();
+
 	if (unlikely(!sme->ssid)) {
 		WL_ERR("Invalid ssid\n");
 		return -EOPNOTSUPP;
 	}
+
 	if (chan) {
-		wl->channel = ieee80211_frequency_to_channel(chan->center_freq);
-		WL_DBG("channel (%d), center_req (%d)\n",
-		       wl->channel, chan->center_freq);
-	}
-	WL_DBG("ie (%p), ie_len (%zd)\n", sme->ie, sme->ie_len);
+		wl->channel =
+			ieee80211_frequency_to_channel(chan->center_freq);
+		WL_CONN("channel (%d), center_req (%d)\n",
+			wl->channel, chan->center_freq);
+	} else
+		wl->channel = 0;
+
+	WL_INFO("ie (%p), ie_len (%zd)\n", sme->ie, sme->ie_len);
+
 	err = wl_set_wpa_version(dev, sme);
 	if (unlikely(err))
 		return err;
@@ -1370,15 +1424,18 @@
 	memcpy(&join_params.ssid.SSID, sme->ssid, join_params.ssid.SSID_len);
 	join_params.ssid.SSID_len = cpu_to_le32(join_params.ssid.SSID_len);
 	wl_update_prof(wl, NULL, &join_params.ssid, WL_PROF_SSID);
-	memcpy(join_params.params.bssid, ether_bcast, ETH_ALEN);
 
-	wl_ch_to_chanspec(wl->channel, &join_params, &join_params_size);
-	WL_DBG("join_param_size %zu\n", join_params_size);
+	if (sme->bssid)
+		memcpy(join_params.params.bssid, sme->bssid, ETH_ALEN);
+	else
+		memcpy(join_params.params.bssid, ether_bcast, ETH_ALEN);
 
 	if (join_params.ssid.SSID_len < IEEE80211_MAX_SSID_LEN) {
-		WL_DBG("ssid \"%s\", len (%d)\n",
+		WL_CONN("ssid \"%s\", len (%d)\n",
 		       join_params.ssid.SSID, join_params.ssid.SSID_len);
 	}
+
+	wl_ch_to_chanspec(wl->channel, &join_params, &join_params_size);
 	err = wl_dev_ioctl(dev, WLC_SET_SSID, &join_params, join_params_size);
 	if (unlikely(err)) {
 		WL_ERR("error (%d)\n", err);
@@ -1386,6 +1443,7 @@
 	}
 	set_bit(WL_STATUS_CONNECTING, &wl->status);
 
+	WL_TRACE("Exit\n");
 	return err;
 }
 
@@ -1395,24 +1453,24 @@
 {
 	struct wl_priv *wl = wiphy_to_wl(wiphy);
 	scb_val_t scbval;
-	bool act = false;
 	s32 err = 0;
 
-	WL_DBG("Reason %d\n", reason_code);
+	WL_TRACE("Enter. Reason code = %d\n", reason_code);
 	CHECK_SYS_UP();
-	act = *(bool *) wl_read_prof(wl, WL_PROF_ACT);
-	if (likely(act)) {
-		scbval.val = reason_code;
-		memcpy(&scbval.ea, &wl->bssid, ETH_ALEN);
-		scbval.val = cpu_to_le32(scbval.val);
-		err = wl_dev_ioctl(dev, WLC_DISASSOC, &scbval,
-				sizeof(scb_val_t));
-		if (unlikely(err)) {
-			WL_ERR("error (%d)\n", err);
-			return err;
-		}
-	}
 
+	clear_bit(WL_STATUS_CONNECTED, &wl->status);
+
+	scbval.val = reason_code;
+	memcpy(&scbval.ea, wl_read_prof(wl, WL_PROF_BSSID), ETH_ALEN);
+	scbval.val = cpu_to_le32(scbval.val);
+	err = wl_dev_ioctl(dev, WLC_DISASSOC, &scbval,
+			sizeof(scb_val_t));
+	if (unlikely(err))
+		WL_ERR("error (%d)\n", err);
+
+	wl->link_up = false;
+
+	WL_TRACE("Exit\n");
 	return err;
 }
 
@@ -1427,20 +1485,24 @@
 	s32 err = 0;
 	s32 disable = 0;
 
+	WL_TRACE("Enter\n");
 	CHECK_SYS_UP();
+
 	switch (type) {
 	case NL80211_TX_POWER_AUTOMATIC:
 		break;
 	case NL80211_TX_POWER_LIMITED:
 		if (dbm < 0) {
 			WL_ERR("TX_POWER_LIMITED - dbm is negative\n");
-			return -EINVAL;
+			err = -EINVAL;
+			goto done;
 		}
 		break;
 	case NL80211_TX_POWER_FIXED:
 		if (dbm < 0) {
 			WL_ERR("TX_POWER_FIXED - dbm is negative\n");
-			return -EINVAL;
+			err = -EINVAL;
+			goto done;
 		}
 		break;
 	}
@@ -1448,10 +1510,8 @@
 	disable = WL_RADIO_SW_DISABLE << 16;
 	disable = cpu_to_le32(disable);
 	err = wl_dev_ioctl(ndev, WLC_SET_RADIO, &disable, sizeof(disable));
-	if (unlikely(err)) {
+	if (unlikely(err))
 		WL_ERR("WLC_SET_RADIO error (%d)\n", err);
-		return err;
-	}
 
 	if (dbm > 0xffff)
 		txpwrmw = 0xffff;
@@ -1459,12 +1519,12 @@
 		txpwrmw = (u16) dbm;
 	err = wl_dev_intvar_set(ndev, "qtxpower",
 			(s32) (bcm_mw_to_qdbm(txpwrmw)));
-	if (unlikely(err)) {
+	if (unlikely(err))
 		WL_ERR("qtxpower error (%d)\n", err);
-		return err;
-	}
 	wl->conf->tx_power = dbm;
 
+done:
+	WL_TRACE("Exit\n");
 	return err;
 }
 
@@ -1476,15 +1536,20 @@
 	u8 result;
 	s32 err = 0;
 
+	WL_TRACE("Enter\n");
 	CHECK_SYS_UP();
+
 	err = wl_dev_intvar_get(ndev, "qtxpower", &txpwrdbm);
 	if (unlikely(err)) {
 		WL_ERR("error (%d)\n", err);
-		return err;
+		goto done;
 	}
+
 	result = (u8) (txpwrdbm & ~WL_TXPWR_OVERRIDE);
 	*dbm = (s32) bcm_qdbm_to_mw(result);
 
+done:
+	WL_TRACE("Exit\n");
 	return err;
 }
 
@@ -1496,14 +1561,16 @@
 	s32 wsec;
 	s32 err = 0;
 
-	WL_DBG("key index (%d)\n", key_idx);
+	WL_TRACE("Enter\n");
+	WL_CONN("key index (%d)\n", key_idx);
 	CHECK_SYS_UP();
 
 	err = wl_dev_ioctl(dev, WLC_GET_WSEC, &wsec, sizeof(wsec));
 	if (unlikely(err)) {
 		WL_ERR("WLC_GET_WSEC error (%d)\n", err);
-		return err;
+		goto done;
 	}
+
 	wsec = le32_to_cpu(wsec);
 	if (wsec & WEP_ENABLED) {
 		/* Just select a new current key */
@@ -1511,10 +1578,11 @@
 		index = cpu_to_le32(index);
 		err = wl_dev_ioctl(dev, WLC_SET_KEY_PRIMARY, &index,
 				sizeof(index));
-		if (unlikely(err)) {
+		if (unlikely(err))
 			WL_ERR("error (%d)\n", err);
-		}
 	}
+done:
+	WL_TRACE("Exit\n");
 	return err;
 }
 
@@ -1547,7 +1615,7 @@
 			return -EINVAL;
 		}
 
-		WL_DBG("Setting the key index %d\n", key.index);
+		WL_CONN("Setting the key index %d\n", key.index);
 		memcpy(key.data, params->key, key.len);
 
 		if (params->cipher == WLAN_CIPHER_SUITE_TKIP) {
@@ -1571,23 +1639,23 @@
 		switch (params->cipher) {
 		case WLAN_CIPHER_SUITE_WEP40:
 			key.algo = CRYPTO_ALGO_WEP1;
-			WL_DBG("WLAN_CIPHER_SUITE_WEP40\n");
+			WL_CONN("WLAN_CIPHER_SUITE_WEP40\n");
 			break;
 		case WLAN_CIPHER_SUITE_WEP104:
 			key.algo = CRYPTO_ALGO_WEP128;
-			WL_DBG("WLAN_CIPHER_SUITE_WEP104\n");
+			WL_CONN("WLAN_CIPHER_SUITE_WEP104\n");
 			break;
 		case WLAN_CIPHER_SUITE_TKIP:
 			key.algo = CRYPTO_ALGO_TKIP;
-			WL_DBG("WLAN_CIPHER_SUITE_TKIP\n");
+			WL_CONN("WLAN_CIPHER_SUITE_TKIP\n");
 			break;
 		case WLAN_CIPHER_SUITE_AES_CMAC:
 			key.algo = CRYPTO_ALGO_AES_CCM;
-			WL_DBG("WLAN_CIPHER_SUITE_AES_CMAC\n");
+			WL_CONN("WLAN_CIPHER_SUITE_AES_CMAC\n");
 			break;
 		case WLAN_CIPHER_SUITE_CCMP:
 			key.algo = CRYPTO_ALGO_AES_CCM;
-			WL_DBG("WLAN_CIPHER_SUITE_CCMP\n");
+			WL_CONN("WLAN_CIPHER_SUITE_CCMP\n");
 			break;
 		default:
 			WL_ERR("Invalid cipher (0x%x)\n", params->cipher);
@@ -1614,12 +1682,16 @@
 	s32 val;
 	s32 wsec;
 	s32 err = 0;
+	u8 keybuf[8];
 
-	WL_DBG("key index (%d)\n", key_idx);
+	WL_TRACE("Enter\n");
+	WL_CONN("key index (%d)\n", key_idx);
 	CHECK_SYS_UP();
 
-	if (mac_addr)
+	if (mac_addr) {
+		WL_TRACE("Exit");
 		return wl_add_keyext(wiphy, dev, key_idx, mac_addr, params);
+	}
 	memset(&key, 0, sizeof(key));
 
 	key.len = (u32) params->key_len;
@@ -1627,7 +1699,8 @@
 
 	if (unlikely(key.len > sizeof(key.data))) {
 		WL_ERR("Too long key length (%u)\n", key.len);
-		return -EINVAL;
+		err = -EINVAL;
+		goto done;
 	}
 	memcpy(key.data, params->key, key.len);
 
@@ -1635,27 +1708,31 @@
 	switch (params->cipher) {
 	case WLAN_CIPHER_SUITE_WEP40:
 		key.algo = CRYPTO_ALGO_WEP1;
-		WL_DBG("WLAN_CIPHER_SUITE_WEP40\n");
+		WL_CONN("WLAN_CIPHER_SUITE_WEP40\n");
 		break;
 	case WLAN_CIPHER_SUITE_WEP104:
 		key.algo = CRYPTO_ALGO_WEP128;
-		WL_DBG("WLAN_CIPHER_SUITE_WEP104\n");
+		WL_CONN("WLAN_CIPHER_SUITE_WEP104\n");
 		break;
 	case WLAN_CIPHER_SUITE_TKIP:
+		memcpy(keybuf, &key.data[24], sizeof(keybuf));
+		memcpy(&key.data[24], &key.data[16], sizeof(keybuf));
+		memcpy(&key.data[16], keybuf, sizeof(keybuf));
 		key.algo = CRYPTO_ALGO_TKIP;
-		WL_DBG("WLAN_CIPHER_SUITE_TKIP\n");
+		WL_CONN("WLAN_CIPHER_SUITE_TKIP\n");
 		break;
 	case WLAN_CIPHER_SUITE_AES_CMAC:
 		key.algo = CRYPTO_ALGO_AES_CCM;
-		WL_DBG("WLAN_CIPHER_SUITE_AES_CMAC\n");
+		WL_CONN("WLAN_CIPHER_SUITE_AES_CMAC\n");
 		break;
 	case WLAN_CIPHER_SUITE_CCMP:
 		key.algo = CRYPTO_ALGO_AES_CCM;
-		WL_DBG("WLAN_CIPHER_SUITE_CCMP\n");
+		WL_CONN("WLAN_CIPHER_SUITE_CCMP\n");
 		break;
 	default:
 		WL_ERR("Invalid cipher (0x%x)\n", params->cipher);
-		return -EINVAL;
+		err = -EINVAL;
+		goto done;
 	}
 
 	/* Set the new key/index */
@@ -1663,30 +1740,30 @@
 	err = wl_dev_ioctl(dev, WLC_SET_KEY, &key, sizeof(key));
 	if (unlikely(err)) {
 		WL_ERR("WLC_SET_KEY error (%d)\n", err);
-		return err;
+		goto done;
 	}
 
 	val = WEP_ENABLED;
 	err = wl_dev_intvar_get(dev, "wsec", &wsec);
 	if (unlikely(err)) {
 		WL_ERR("get wsec error (%d)\n", err);
-		return err;
+		goto done;
 	}
 	wsec &= ~(WEP_ENABLED);
 	wsec |= val;
 	err = wl_dev_intvar_set(dev, "wsec", wsec);
 	if (unlikely(err)) {
 		WL_ERR("set wsec error (%d)\n", err);
-		return err;
+		goto done;
 	}
 
 	val = 1;		/* assume shared key. otherwise 0 */
 	val = cpu_to_le32(val);
 	err = wl_dev_ioctl(dev, WLC_SET_AUTH, &val, sizeof(val));
-	if (unlikely(err)) {
+	if (unlikely(err))
 		WL_ERR("WLC_SET_AUTH error (%d)\n", err);
-		return err;
-	}
+done:
+	WL_TRACE("Exit\n");
 	return err;
 }
 
@@ -1699,6 +1776,7 @@
 	s32 val;
 	s32 wsec;
 
+	WL_TRACE("Enter\n");
 	CHECK_SYS_UP();
 	memset(&key, 0, sizeof(key));
 
@@ -1706,34 +1784,39 @@
 	key.flags = WL_PRIMARY_KEY;
 	key.algo = CRYPTO_ALGO_OFF;
 
-	WL_DBG("key index (%d)\n", key_idx);
+	WL_CONN("key index (%d)\n", key_idx);
 	/* Set the new key/index */
 	swap_key_from_BE(&key);
 	err = wl_dev_ioctl(dev, WLC_SET_KEY, &key, sizeof(key));
 	if (unlikely(err)) {
 		if (err == -EINVAL) {
-			if (key.index >= DOT11_MAX_DEFAULT_KEYS) {
+			if (key.index >= DOT11_MAX_DEFAULT_KEYS)
 				/* we ignore this key index in this case */
-				WL_DBG("invalid key index (%d)\n", key_idx);
-			}
-		} else {
+				WL_ERR("invalid key index (%d)\n", key_idx);
+		} else
 			WL_ERR("WLC_SET_KEY error (%d)\n", err);
-		}
-		return err;
+
+		/* Ignore this error, may happen during DISASSOC */
+		err = -EAGAIN;
+		goto done;
 	}
 
 	val = 0;
 	err = wl_dev_intvar_get(dev, "wsec", &wsec);
 	if (unlikely(err)) {
 		WL_ERR("get wsec error (%d)\n", err);
-		return err;
+		/* Ignore this error, may happen during DISASSOC */
+		err = -EAGAIN;
+		goto done;
 	}
 	wsec &= ~(WEP_ENABLED);
 	wsec |= val;
 	err = wl_dev_intvar_set(dev, "wsec", wsec);
 	if (unlikely(err)) {
 		WL_ERR("set wsec error (%d)\n", err);
-		return err;
+		/* Ignore this error, may happen during DISASSOC */
+		err = -EAGAIN;
+		goto done;
 	}
 
 	val = 0;		/* assume open key. otherwise 1 */
@@ -1741,8 +1824,11 @@
 	err = wl_dev_ioctl(dev, WLC_SET_AUTH, &val, sizeof(val));
 	if (unlikely(err)) {
 		WL_ERR("WLC_SET_AUTH error (%d)\n", err);
-		return err;
+		/* Ignore this error, may happen during DISASSOC */
+		err = -EAGAIN;
 	}
+done:
+	WL_TRACE("Exit\n");
 	return err;
 }
 
@@ -1758,7 +1844,8 @@
 	s32 wsec;
 	s32 err = 0;
 
-	WL_DBG("key index (%d)\n", key_idx);
+	WL_TRACE("Enter\n");
+	WL_CONN("key index (%d)\n", key_idx);
 	CHECK_SYS_UP();
 
 	memset(&key, 0, sizeof(key));
@@ -1771,7 +1858,9 @@
 	err = wl_dev_ioctl(dev, WLC_GET_WSEC, &wsec, sizeof(wsec));
 	if (unlikely(err)) {
 		WL_ERR("WLC_GET_WSEC error (%d)\n", err);
-		return err;
+		/* Ignore this error, may happen during DISASSOC */
+		err = -EAGAIN;
+		goto done;
 	}
 	wsec = le32_to_cpu(wsec);
 	switch (wsec) {
@@ -1779,26 +1868,29 @@
 		sec = wl_read_prof(wl, WL_PROF_SEC);
 		if (sec->cipher_pairwise & WLAN_CIPHER_SUITE_WEP40) {
 			params.cipher = WLAN_CIPHER_SUITE_WEP40;
-			WL_DBG("WLAN_CIPHER_SUITE_WEP40\n");
+			WL_CONN("WLAN_CIPHER_SUITE_WEP40\n");
 		} else if (sec->cipher_pairwise & WLAN_CIPHER_SUITE_WEP104) {
 			params.cipher = WLAN_CIPHER_SUITE_WEP104;
-			WL_DBG("WLAN_CIPHER_SUITE_WEP104\n");
+			WL_CONN("WLAN_CIPHER_SUITE_WEP104\n");
 		}
 		break;
 	case TKIP_ENABLED:
 		params.cipher = WLAN_CIPHER_SUITE_TKIP;
-		WL_DBG("WLAN_CIPHER_SUITE_TKIP\n");
+		WL_CONN("WLAN_CIPHER_SUITE_TKIP\n");
 		break;
 	case AES_ENABLED:
 		params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
-		WL_DBG("WLAN_CIPHER_SUITE_AES_CMAC\n");
+		WL_CONN("WLAN_CIPHER_SUITE_AES_CMAC\n");
 		break;
 	default:
 		WL_ERR("Invalid algo (0x%x)\n", wsec);
-		return -EINVAL;
+		err = -EINVAL;
+		goto done;
 	}
-
 	callback(cookie, &params);
+
+done:
+	WL_TRACE("Exit\n");
 	return err;
 }
 
@@ -1807,6 +1899,7 @@
 				    struct net_device *dev, u8 key_idx)
 {
 	WL_INFO("Not supported\n");
+
 	CHECK_SYS_UP();
 	return -EOPNOTSUPP;
 }
@@ -1820,12 +1913,20 @@
 	int rssi;
 	s32 rate;
 	s32 err = 0;
+	u8 *bssid = wl_read_prof(wl, WL_PROF_BSSID);
 
+	WL_TRACE("Enter\n");
 	CHECK_SYS_UP();
+
 	if (unlikely
-	    (memcmp(mac, wl_read_prof(wl, WL_PROF_BSSID), ETH_ALEN))) {
-		WL_ERR("Wrong Mac address\n");
-		return -ENOENT;
+	    (memcmp(mac, bssid, ETH_ALEN))) {
+		WL_ERR("Wrong Mac address cfg_mac-%X:%X:%X:%X:%X:%X"
+			"wl_bssid-%X:%X:%X:%X:%X:%X\n",
+			mac[0], mac[1], mac[2], mac[3], mac[4], mac[5],
+			bssid[0], bssid[1], bssid[2], bssid[3],
+			bssid[4], bssid[5]);
+		err = -ENOENT;
+		goto done;
 	}
 
 	/* Report the current tx rate */
@@ -1836,7 +1937,7 @@
 		rate = le32_to_cpu(rate);
 		sinfo->filled |= STATION_INFO_TX_BITRATE;
 		sinfo->txrate.legacy = rate * 5;
-		WL_DBG("Rate %d Mbps\n", rate / 2);
+		WL_CONN("Rate %d Mbps\n", rate / 2);
 	}
 
 	if (test_bit(WL_STATUS_CONNECTED, &wl->status)) {
@@ -1845,14 +1946,15 @@
 				sizeof(scb_val_t));
 		if (unlikely(err)) {
 			WL_ERR("Could not get rssi (%d)\n", err);
-			return err;
 		}
 		rssi = le32_to_cpu(scb_val.val);
 		sinfo->filled |= STATION_INFO_SIGNAL;
 		sinfo->signal = rssi;
-		WL_DBG("RSSI %d dBm\n", rssi);
+		WL_CONN("RSSI %d dBm\n", rssi);
 	}
 
+done:
+	WL_TRACE("Exit\n");
 	return err;
 }
 
@@ -1863,18 +1965,21 @@
 	s32 pm;
 	s32 err = 0;
 
+	WL_TRACE("Enter\n");
 	CHECK_SYS_UP();
+
 	pm = enabled ? PM_FAST : PM_OFF;
 	pm = cpu_to_le32(pm);
-	WL_DBG("power save %s\n", (pm ? "enabled" : "disabled"));
+	WL_INFO("power save %s\n", (pm ? "enabled" : "disabled"));
+
 	err = wl_dev_ioctl(dev, WLC_SET_PM, &pm, sizeof(pm));
 	if (unlikely(err)) {
 		if (err == -ENODEV)
-			WL_DBG("net_device is not ready yet\n");
+			WL_ERR("net_device is not ready yet\n");
 		else
 			WL_ERR("error (%d)\n", err);
-		return err;
 	}
+	WL_TRACE("Exit\n");
 	return err;
 }
 
@@ -1918,14 +2023,16 @@
 	u32 legacy;
 	s32 err = 0;
 
+	WL_TRACE("Enter\n");
 	CHECK_SYS_UP();
+
 	/* addr param is always NULL. ignore it */
 	/* Get current rateset */
 	err = wl_dev_ioctl(dev, WLC_GET_CURR_RATESET, &rateset,
 			sizeof(rateset));
 	if (unlikely(err)) {
 		WL_ERR("could not get current rateset (%d)\n", err);
-		return err;
+		goto done;
 	}
 
 	rateset.count = le32_to_cpu(rateset.count);
@@ -1936,15 +2043,14 @@
 
 	val = wl_g_rates[legacy - 1].bitrate * 100000;
 
-	if (val < rateset.count) {
+	if (val < rateset.count)
 		/* Select rate by rateset index */
 		rate = rateset.rates[val] & 0x7f;
-	} else {
+	else
 		/* Specified rate in bps */
 		rate = val / 500000;
-	}
 
-	WL_DBG("rate %d mbps\n", rate / 2);
+	WL_CONN("rate %d mbps\n", rate / 2);
 
 	/*
 	 *
@@ -1955,40 +2061,105 @@
 	err_a = wl_dev_intvar_set(dev, "a_rate", rate);
 	if (unlikely(err_bg && err_a)) {
 		WL_ERR("could not set fixed rate (%d) (%d)\n", err_bg, err_a);
-		return err_bg | err_a;
+		err = err_bg | err_a;
 	}
 
+done:
+	WL_TRACE("Exit\n");
 	return err;
 }
 
 static s32 wl_cfg80211_resume(struct wiphy *wiphy)
 {
-	s32 err = 0;
+	struct wl_priv *wl = wiphy_to_wl(wiphy);
+	struct net_device *ndev = wl_to_ndev(wl);
 
-	CHECK_SYS_UP();
-	wl_invoke_iscan(wiphy_to_wl(wiphy));
+	/*
+	 * Check for WL_STATUS_READY before any function call which
+	 * could result is bus access. Don't block the resume for
+	 * any driver error conditions
+	 */
+	WL_TRACE("Enter\n");
 
-	return err;
+#if defined(CONFIG_PM_SLEEP)
+	atomic_set(&dhd_mmc_suspend, false);
+#endif	/*  defined(CONFIG_PM_SLEEP) */
+
+	if (test_bit(WL_STATUS_READY, &wl->status)) {
+		/* Turn on Watchdog timer */
+		wl_os_wd_timer(ndev, dhd_watchdog_ms);
+		wl_invoke_iscan(wiphy_to_wl(wiphy));
+	}
+
+	WL_TRACE("Exit\n");
+	return 0;
 }
 
 static s32 wl_cfg80211_suspend(struct wiphy *wiphy)
 {
 	struct wl_priv *wl = wiphy_to_wl(wiphy);
 	struct net_device *ndev = wl_to_ndev(wl);
-	s32 err = 0;
+
+	WL_TRACE("Enter\n");
+
+	/*
+	 * Check for WL_STATUS_READY before any function call which
+	 * could result is bus access. Don't block the suspend for
+	 * any driver error conditions
+	 */
+
+	/*
+	 * While going to suspend if associated with AP disassociate
+	 * from AP to save power while system is in suspended state
+	 */
+	if (test_bit(WL_STATUS_CONNECTED, &wl->status) &&
+		test_bit(WL_STATUS_READY, &wl->status)) {
+		WL_INFO("Disassociating from AP"
+			" while entering suspend state\n");
+		wl_link_down(wl);
+
+		/*
+		 * Make sure WPA_Supplicant receives all the event
+		 * generated due to DISASSOC call to the fw to keep
+		 * the state fw and WPA_Supplicant state consistent
+		 */
+		rtnl_unlock();
+		wl_delay(500);
+		rtnl_lock();
+	}
 
 	set_bit(WL_STATUS_SCAN_ABORTING, &wl->status);
-	wl_term_iscan(wl);
+	if (test_bit(WL_STATUS_READY, &wl->status))
+		wl_term_iscan(wl);
+
 	if (wl->scan_request) {
-		cfg80211_scan_done(wl->scan_request, true);	/* true means
-								 abort */
-		wl_set_mpc(ndev, 1);
+		/* Indidate scan abort to cfg80211 layer */
+		WL_INFO("Terminating scan in progress\n");
+		cfg80211_scan_done(wl->scan_request, true);
 		wl->scan_request = NULL;
 	}
 	clear_bit(WL_STATUS_SCANNING, &wl->status);
 	clear_bit(WL_STATUS_SCAN_ABORTING, &wl->status);
+	clear_bit(WL_STATUS_CONNECTING, &wl->status);
+	clear_bit(WL_STATUS_CONNECTED, &wl->status);
 
-	return err;
+	/* Inform SDIO stack not to switch off power to the chip */
+	sdioh_sdio_set_host_pm_flags(MMC_PM_KEEP_POWER);
+
+	/* Turn off watchdog timer */
+	if (test_bit(WL_STATUS_READY, &wl->status)) {
+		WL_INFO("Terminate watchdog timer and enable MPC\n");
+		wl_set_mpc(ndev, 1);
+		wl_os_wd_timer(ndev, 0);
+	}
+
+#if defined(CONFIG_PM_SLEEP)
+	atomic_set(&dhd_mmc_suspend, true);
+#endif	/*  defined(CONFIG_PM_SLEEP) */
+
+	WL_TRACE("Exit\n");
+
+	return 0;
 }
 
 static __used s32
@@ -1997,18 +2168,17 @@
 {
 	int i, j;
 
-	WL_DBG("No of elements %d\n", pmk_list->pmkids.npmkid);
+	WL_CONN("No of elements %d\n", pmk_list->pmkids.npmkid);
 	for (i = 0; i < pmk_list->pmkids.npmkid; i++) {
-		WL_DBG("PMKID[%d]: %pM =\n", i,
+		WL_CONN("PMKID[%d]: %pM =\n", i,
 			&pmk_list->pmkids.pmkid[i].BSSID);
-		for (j = 0; j < WLAN_PMKID_LEN; j++) {
-			WL_DBG("%02x\n", pmk_list->pmkids.pmkid[i].PMKID[j]);
-		}
+		for (j = 0; j < WLAN_PMKID_LEN; j++)
+			WL_CONN("%02x\n", pmk_list->pmkids.pmkid[i].PMKID[j]);
 	}
-	if (likely(!err)) {
-		err = wl_dev_bufvar_set(dev, "pmkid_info", (char *)pmk_list,
+
+	if (likely(!err))
+		wl_dev_bufvar_set(dev, "pmkid_info", (char *)pmk_list,
 					sizeof(*pmk_list));
-	}
 
 	return err;
 }
@@ -2021,7 +2191,9 @@
 	s32 err = 0;
 	int i;
 
+	WL_TRACE("Enter\n");
 	CHECK_SYS_UP();
+
 	for (i = 0; i < wl->pmk_list->pmkids.npmkid; i++)
 		if (!memcmp(pmksa->bssid, &wl->pmk_list->pmkids.pmkid[i].BSSID,
 			    ETH_ALEN))
@@ -2033,19 +2205,19 @@
 		       WLAN_PMKID_LEN);
 		if (i == wl->pmk_list->pmkids.npmkid)
 			wl->pmk_list->pmkids.npmkid++;
-	} else {
+	} else
 		err = -EINVAL;
-	}
-	WL_DBG("set_pmksa,IW_PMKSA_ADD - PMKID: %pM =\n",
+
+	WL_CONN("set_pmksa,IW_PMKSA_ADD - PMKID: %pM =\n",
 	       &wl->pmk_list->pmkids.pmkid[wl->pmk_list->pmkids.npmkid].BSSID);
-	for (i = 0; i < WLAN_PMKID_LEN; i++) {
-		WL_DBG("%02x\n",
+	for (i = 0; i < WLAN_PMKID_LEN; i++)
+		WL_CONN("%02x\n",
 		       wl->pmk_list->pmkids.pmkid[wl->pmk_list->pmkids.npmkid].
 		       PMKID[i]);
-	}
 
 	err = wl_update_pmklist(dev, wl->pmk_list, err);
 
+	WL_TRACE("Exit\n");
 	return err;
 }
 
@@ -2058,15 +2230,15 @@
 	s32 err = 0;
 	int i;
 
+	WL_TRACE("Enter\n");
 	CHECK_SYS_UP();
 	memcpy(&pmkid.pmkid[0].BSSID, pmksa->bssid, ETH_ALEN);
 	memcpy(&pmkid.pmkid[0].PMKID, pmksa->pmkid, WLAN_PMKID_LEN);
 
-	WL_DBG("del_pmksa,IW_PMKSA_REMOVE - PMKID: %pM =\n",
+	WL_CONN("del_pmksa,IW_PMKSA_REMOVE - PMKID: %pM =\n",
 	       &pmkid.pmkid[0].BSSID);
-	for (i = 0; i < WLAN_PMKID_LEN; i++) {
-		WL_DBG("%02x\n", pmkid.pmkid[0].PMKID[i]);
-	}
+	for (i = 0; i < WLAN_PMKID_LEN; i++)
+		WL_CONN("%02x\n", pmkid.pmkid[0].PMKID[i]);
 
 	for (i = 0; i < wl->pmk_list->pmkids.npmkid; i++)
 		if (!memcmp
@@ -2086,12 +2258,12 @@
 			       WLAN_PMKID_LEN);
 		}
 		wl->pmk_list->pmkids.npmkid--;
-	} else {
+	} else
 		err = -EINVAL;
-	}
 
 	err = wl_update_pmklist(dev, wl->pmk_list, err);
 
+	WL_TRACE("Exit\n");
 	return err;
 
 }
@@ -2102,9 +2274,13 @@
 	struct wl_priv *wl = wiphy_to_wl(wiphy);
 	s32 err = 0;
 
+	WL_TRACE("Enter\n");
 	CHECK_SYS_UP();
+
 	memset(wl->pmk_list, 0, sizeof(*wl->pmk_list));
 	err = wl_update_pmklist(dev, wl->pmk_list, err);
+
+	WL_TRACE("Exit\n");
 	return err;
 
 }
@@ -2235,7 +2411,7 @@
 		       bss_list->version);
 		return -EOPNOTSUPP;
 	}
-	WL_DBG("scanned AP count (%d)\n", bss_list->count);
+	WL_SCAN("scanned AP count (%d)\n", bss_list->count);
 	bi = next_bss(bss_list, bi);
 	for_each_bss(bss_list, bi, i) {
 		err = wl_inform_single_bss(wl, bi);
@@ -2245,89 +2421,137 @@
 	return err;
 }
 
+
 static s32 wl_inform_single_bss(struct wl_priv *wl, struct wl_bss_info *bi)
 {
 	struct wiphy *wiphy = wl_to_wiphy(wl);
-	struct ieee80211_mgmt *mgmt;
-	struct ieee80211_channel *channel;
+	struct ieee80211_channel *notify_channel;
+	struct cfg80211_bss *bss;
 	struct ieee80211_supported_band *band;
-	struct wl_cfg80211_bss_info *notif_bss_info;
-	struct wl_scan_req *sr = wl_to_sr(wl);
-	struct beacon_proberesp *beacon_proberesp;
-	s32 mgmt_type;
-	u32 signal;
-	u32 freq;
 	s32 err = 0;
+	u16 channel;
+	u32 freq;
+	u64 notify_timestamp;
+	u16 notify_capability;
+	u16 notify_interval;
+	u8 *notify_ie;
+	size_t notify_ielen;
+	s32 notify_signal;
 
 	if (unlikely(le32_to_cpu(bi->length) > WL_BSS_INFO_MAX)) {
-		WL_DBG("Beacon is larger than buffer. Discarding\n");
-		return err;
-	}
-	notif_bss_info =
-	    kzalloc(sizeof(*notif_bss_info) + sizeof(*mgmt) - sizeof(u8) +
-		    WL_BSS_INFO_MAX, GFP_KERNEL);
-	if (unlikely(!notif_bss_info)) {
-		WL_ERR("notif_bss_info alloc failed\n");
-		return -ENOMEM;
+		WL_ERR("Bss info is larger than buffer. Discarding\n");
+		return 0;
 	}
-	mgmt = (struct ieee80211_mgmt *)notif_bss_info->frame_buf;
-	notif_bss_info->channel =
-		bi->ctl_ch ? bi->ctl_ch : CHSPEC_CHANNEL(bi->chanspec);
 
-	if (notif_bss_info->channel <= CH_MAX_2G_CHANNEL)
+	channel = bi->ctl_ch ? bi->ctl_ch :
+				CHSPEC_CHANNEL(le16_to_cpu(bi->chanspec));
+
+	if (channel <= CH_MAX_2G_CHANNEL)
 		band = wiphy->bands[IEEE80211_BAND_2GHZ];
 	else
 		band = wiphy->bands[IEEE80211_BAND_5GHZ];
-	notif_bss_info->rssi = bi->RSSI;
-	memcpy(mgmt->bssid, &bi->BSSID, ETH_ALEN);
-	mgmt_type = wl->active_scan ?
-		IEEE80211_STYPE_PROBE_RESP : IEEE80211_STYPE_BEACON;
-	if (!memcmp(bi->SSID, sr->ssid.SSID, bi->SSID_len)) {
-		mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
-							mgmt_type);
-	}
-	beacon_proberesp = wl->active_scan ?
-		(struct beacon_proberesp *)&mgmt->u.probe_resp :
-		(struct beacon_proberesp *)&mgmt->u.beacon;
-	beacon_proberesp->timestamp = 0;
-	beacon_proberesp->beacon_int = cpu_to_le16(bi->beacon_period);
-	beacon_proberesp->capab_info = cpu_to_le16(bi->capability);
-	wl_rst_ie(wl);
-	/*
-	* wl_add_ie is not necessary because it can only add duplicated
-	* SSID, rate information to frame_buf
-	*/
-	/*
-	* wl_add_ie(wl, WLAN_EID_SSID, bi->SSID_len, bi->SSID);
-	* wl_add_ie(wl, WLAN_EID_SUPP_RATES, bi->rateset.count,
-	* bi->rateset.rates);
-	*/
-	wl_mrg_ie(wl, ((u8 *) bi) + bi->ie_offset, bi->ie_length);
-	wl_cp_ie(wl, beacon_proberesp->variable, WL_BSS_INFO_MAX -
-		 offsetof(struct wl_cfg80211_bss_info, frame_buf));
-	notif_bss_info->frame_len =
-	    offsetof(struct ieee80211_mgmt,
-		     u.beacon.variable) + wl_get_ielen(wl);
-	freq = ieee80211_channel_to_frequency(notif_bss_info->channel,
-					      band->band);
 
-	channel = ieee80211_get_channel(wiphy, freq);
+	freq = ieee80211_channel_to_frequency(channel, band->band);
+	notify_channel = ieee80211_get_channel(wiphy, freq);
 
-	WL_DBG("SSID : \"%s\", rssi %d, channel %d, capability : 0x04%x, bssid %pM\n",
-	       bi->SSID,
-	       notif_bss_info->rssi, notif_bss_info->channel,
-	       mgmt->u.beacon.capab_info, &bi->BSSID);
+	notify_timestamp = jiffies_to_msecs(jiffies)*1000; /* uSec */
+	notify_capability = le16_to_cpu(bi->capability);
+	notify_interval = le16_to_cpu(bi->beacon_period);
+	notify_ie = (u8 *)bi + le16_to_cpu(bi->ie_offset);
+	notify_ielen = le16_to_cpu(bi->ie_length);
+	notify_signal = (s16)le16_to_cpu(bi->RSSI) * 100;
 
-	signal = notif_bss_info->rssi * 100;
-	if (unlikely(!cfg80211_inform_bss_frame(wiphy, channel, mgmt,
-						le16_to_cpu
-						(notif_bss_info->frame_len),
-						signal, GFP_KERNEL))) {
+	WL_CONN("bssid: %2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X\n",
+			bi->BSSID[0], bi->BSSID[1], bi->BSSID[2],
+			bi->BSSID[3], bi->BSSID[4], bi->BSSID[5]);
+	WL_CONN("Channel: %d(%d)\n", channel, freq);
+	WL_CONN("Capability: %X\n", notify_capability);
+	WL_CONN("Beacon interval: %d\n", notify_interval);
+	WL_CONN("Signal: %d\n", notify_signal);
+	WL_CONN("notify_timestamp: %#018llx\n", notify_timestamp);
+
+	bss = cfg80211_inform_bss(wiphy, notify_channel, (const u8 *)bi->BSSID,
+		notify_timestamp, notify_capability, notify_interval, notify_ie,
+		notify_ielen, notify_signal, GFP_KERNEL);
+
+	if (unlikely(!bss)) {
 		WL_ERR("cfg80211_inform_bss_frame error\n");
-		kfree(notif_bss_info);
 		return -EINVAL;
 	}
-	kfree(notif_bss_info);
+
+	return err;
+}
+
+static s32
+wl_inform_ibss(struct wl_priv *wl, struct net_device *dev, const u8 *bssid)
+{
+	struct wiphy *wiphy = wl_to_wiphy(wl);
+	struct ieee80211_channel *notify_channel;
+	struct wl_bss_info *bi = NULL;
+	struct ieee80211_supported_band *band;
+	u8 *buf = NULL;
+	s32 err = 0;
+	u16 channel;
+	u32 freq;
+	u64 notify_timestamp;
+	u16 notify_capability;
+	u16 notify_interval;
+	u8 *notify_ie;
+	size_t notify_ielen;
+	s32 notify_signal;
+
+	WL_TRACE("Enter\n");
+
+	buf = kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL);
+	if (buf == NULL) {
+		WL_ERR("kzalloc() failed\n");
+		err = -ENOMEM;
+		goto CleanUp;
+	}
+
+	*(u32 *)buf = cpu_to_le32(WL_BSS_INFO_MAX);
+
+	err = wl_dev_ioctl(dev, WLC_GET_BSS_INFO, buf, WL_BSS_INFO_MAX);
+	if (unlikely(err)) {
+		WL_ERR("WLC_GET_BSS_INFO failed: %d\n", err);
+		goto CleanUp;
+	}
+
+	bi = (wl_bss_info_t *)(buf + 4);
+
+	channel = bi->ctl_ch ? bi->ctl_ch :
+				CHSPEC_CHANNEL(le16_to_cpu(bi->chanspec));
+
+	if (channel <= CH_MAX_2G_CHANNEL)
+		band = wiphy->bands[IEEE80211_BAND_2GHZ];
+	else
+		band = wiphy->bands[IEEE80211_BAND_5GHZ];
+
+	freq = ieee80211_channel_to_frequency(channel, band->band);
+	notify_channel = ieee80211_get_channel(wiphy, freq);
+
+	notify_timestamp = jiffies_to_msecs(jiffies)*1000; /* uSec */
+	notify_capability = le16_to_cpu(bi->capability);
+	notify_interval = le16_to_cpu(bi->beacon_period);
+	notify_ie = (u8 *)bi + le16_to_cpu(bi->ie_offset);
+	notify_ielen = le16_to_cpu(bi->ie_length);
+	notify_signal = (s16)le16_to_cpu(bi->RSSI) * 100;
+
+	WL_CONN("channel: %d(%d)\n", channel, freq);
+	WL_CONN("capability: %X\n", notify_capability);
+	WL_CONN("beacon interval: %d\n", notify_interval);
+	WL_CONN("signal: %d\n", notify_signal);
+	WL_CONN("notify_timestamp: %#018llx\n", notify_timestamp);
+
+	cfg80211_inform_bss(wiphy, notify_channel, bssid,
+		notify_timestamp, notify_capability, notify_interval,
+		notify_ie, notify_ielen, notify_signal, GFP_KERNEL);
+
+CleanUp:
+
+	kfree(buf);
+
+	WL_TRACE("Exit\n");
 
 	return err;
 }
@@ -2335,17 +2559,12 @@
 static bool wl_is_linkup(struct wl_priv *wl, const wl_event_msg_t *e)
 {
 	u32 event = be32_to_cpu(e->event_type);
-	u16 flags = be16_to_cpu(e->flags);
+	u32 status = be32_to_cpu(e->status);
 
-	if (event == WLC_E_LINK) {
-		if (flags & WLC_EVENT_MSG_LINK) {
-			if (wl_is_ibssmode(wl)) {
-				if (wl_is_ibssstarter(wl)) {
-				}
-			} else {
-				return true;
-			}
-		}
+	if (event == WLC_E_SET_SSID && status == WLC_E_STATUS_SUCCESS) {
+		WL_CONN("Processing set ssid\n");
+		wl->link_up = true;
+		return true;
 	}
 
 	return false;
@@ -2356,13 +2575,10 @@
 	u32 event = be32_to_cpu(e->event_type);
 	u16 flags = be16_to_cpu(e->flags);
 
-	if (event == WLC_E_DEAUTH_IND || event == WLC_E_DISASSOC_IND) {
+	if (event == WLC_E_LINK && (!(flags & WLC_EVENT_MSG_LINK))) {
+		WL_CONN("Processing link down\n");
 		return true;
-	} else if (event == WLC_E_LINK) {
-		if (!(flags & WLC_EVENT_MSG_LINK))
-			return true;
 	}
-
 	return false;
 }
 
@@ -2370,10 +2586,17 @@
 {
 	u32 event = be32_to_cpu(e->event_type);
 	u32 status = be32_to_cpu(e->status);
+	u16 flags = be16_to_cpu(e->flags);
 
-	if (event == WLC_E_SET_SSID || event == WLC_E_LINK) {
-		if (status == WLC_E_STATUS_NO_NETWORKS)
-			return true;
+	if (event == WLC_E_LINK && status == WLC_E_STATUS_NO_NETWORKS) {
+		WL_CONN("Processing Link %s & no network found\n",
+				flags & WLC_EVENT_MSG_LINK ? "up" : "down");
+		return true;
+	}
+
+	if (event == WLC_E_SET_SSID && status != WLC_E_STATUS_SUCCESS) {
+		WL_CONN("Processing connecting & no network found\n");
+		return true;
 	}
 
 	return false;
@@ -2383,30 +2606,39 @@
 wl_notify_connect_status(struct wl_priv *wl, struct net_device *ndev,
 			 const wl_event_msg_t *e, void *data)
 {
-	bool act;
 	s32 err = 0;
 
 	if (wl_is_linkup(wl, e)) {
-		wl_link_up(wl);
+		WL_CONN("Linkup\n");
 		if (wl_is_ibssmode(wl)) {
-			cfg80211_ibss_joined(ndev, (s8 *)&e->addr,
-					     GFP_KERNEL);
-			WL_DBG("joined in IBSS network\n");
-		} else {
+			wl_update_prof(wl, NULL, (void *)e->addr,
+				WL_PROF_BSSID);
+			wl_inform_ibss(wl, ndev, e->addr);
+			cfg80211_ibss_joined(ndev, e->addr, GFP_KERNEL);
+			clear_bit(WL_STATUS_CONNECTING, &wl->status);
+			set_bit(WL_STATUS_CONNECTED, &wl->status);
+		} else
 			wl_bss_connect_done(wl, ndev, e, data, true);
-			WL_DBG("joined in BSS network \"%s\"\n",
-			       ((struct wlc_ssid *)
-				wl_read_prof(wl, WL_PROF_SSID))->SSID);
-		}
-		act = true;
-		wl_update_prof(wl, e, &act, WL_PROF_ACT);
 	} else if (wl_is_linkdown(wl, e)) {
-		cfg80211_disconnected(ndev, 0, NULL, 0, GFP_KERNEL);
-		clear_bit(WL_STATUS_CONNECTED, &wl->status);
-		wl_link_down(wl);
+		WL_CONN("Linkdown\n");
+		if (wl_is_ibssmode(wl)) {
+			if (test_and_clear_bit(WL_STATUS_CONNECTED,
+				&wl->status))
+				wl_link_down(wl);
+		} else {
+			if (test_and_clear_bit(WL_STATUS_CONNECTED,
+				&wl->status)) {
+				cfg80211_disconnected(ndev, 0, NULL, 0,
+					GFP_KERNEL);
+				wl_link_down(wl);
+			}
+		}
 		wl_init_prof(wl->profile);
 	} else if (wl_is_nonetwork(wl, e)) {
-		wl_bss_connect_done(wl, ndev, e, data, false);
+		if (wl_is_ibssmode(wl))
+			clear_bit(WL_STATUS_CONNECTING, &wl->status);
+		else
+			wl_bss_connect_done(wl, ndev, e, data, false);
 	}
 
 	return err;
@@ -2416,12 +2648,16 @@
 wl_notify_roaming_status(struct wl_priv *wl, struct net_device *ndev,
 			 const wl_event_msg_t *e, void *data)
 {
-	bool act;
 	s32 err = 0;
+	u32 event = be32_to_cpu(e->event_type);
+	u32 status = be32_to_cpu(e->status);
 
-	wl_bss_roaming_done(wl, ndev, e, data);
-	act = true;
-	wl_update_prof(wl, e, &act, WL_PROF_ACT);
+	if (event == WLC_E_ROAM && status == WLC_E_STATUS_SUCCESS) {
+		if (test_bit(WL_STATUS_CONNECTED, &wl->status))
+			wl_bss_roaming_done(wl, ndev, e, data);
+		else
+			wl_bss_connect_done(wl, ndev, e, data, true);
+	}
 
 	return err;
 }
@@ -2468,6 +2704,8 @@
 	u32 resp_len;
 	s32 err = 0;
 
+	wl_clear_assoc_ies(wl);
+
 	err = wl_dev_bufvar_get(ndev, "assoc_info", wl->extra_buf,
 				WL_ASSOC_INFO_MAX);
 	if (unlikely(err)) {
@@ -2505,12 +2743,25 @@
 		conn_info->resp_ie_len = 0;
 		conn_info->resp_ie = NULL;
 	}
-	WL_DBG("req len (%d) resp len (%d)\n",
+	WL_CONN("req len (%d) resp len (%d)\n",
 	       conn_info->req_ie_len, conn_info->resp_ie_len);
 
 	return err;
 }
 
+static void wl_clear_assoc_ies(struct wl_priv *wl)
+{
+	struct wl_connect_info *conn_info = wl_to_conn(wl);
+
+	kfree(conn_info->req_ie);
+	conn_info->req_ie = NULL;
+	conn_info->req_ie_len = 0;
+	kfree(conn_info->resp_ie);
+	conn_info->resp_ie = NULL;
+	conn_info->resp_ie_len = 0;
+}
+
+
 static void wl_ch_to_chanspec(int ch, struct wl_join_params *join_params,
 	size_t *join_params_size)
 {
@@ -2520,7 +2771,7 @@
 		join_params->params.chanspec_num = 1;
 		join_params->params.chanspec_list[0] = ch;
 
-		if (join_params->params.chanspec_list[0])
+		if (join_params->params.chanspec_list[0] <= CH_MAX_2G_CHANNEL)
 			chanspec |= WL_CHANSPEC_BAND_2G;
 		else
 			chanspec |= WL_CHANSPEC_BAND_5G;
@@ -2539,14 +2790,14 @@
 		join_params->params.chanspec_num =
 			cpu_to_le32(join_params->params.chanspec_num);
 
-		WL_DBG("join_params->params.chanspec_list[0]= %#X, channel %d, chanspec %#X\n",
+		WL_CONN("join_params->params.chanspec_list[0]= %#X,"
+			"channel %d, chanspec %#X\n",
 		       join_params->params.chanspec_list[0], ch, chanspec);
 	}
 }
 
 static s32 wl_update_bss_info(struct wl_priv *wl)
 {
-	struct cfg80211_bss *bss;
 	struct wl_bss_info *bi;
 	struct wlc_ssid *ssid;
 	struct bcm_tlv *tim;
@@ -2556,67 +2807,52 @@
 	u8 *ie;
 	s32 err = 0;
 
+	WL_TRACE("Enter\n");
 	if (wl_is_ibssmode(wl))
 		return err;
 
 	ssid = (struct wlc_ssid *)wl_read_prof(wl, WL_PROF_SSID);
-	bss =
-	    cfg80211_get_bss(wl_to_wiphy(wl), NULL, (s8 *)&wl->bssid,
-			     ssid->SSID, ssid->SSID_len, WLAN_CAPABILITY_ESS,
-			     WLAN_CAPABILITY_ESS);
 
-	rtnl_lock();
-	if (unlikely(!bss)) {
-		WL_DBG("Could not find the AP\n");
-		*(u32 *) wl->extra_buf = cpu_to_le32(WL_EXTRA_BUF_MAX);
-		err = wl_dev_ioctl(wl_to_ndev(wl), WLC_GET_BSS_INFO,
-				wl->extra_buf, WL_EXTRA_BUF_MAX);
-		if (unlikely(err)) {
-			WL_ERR("Could not get bss info %d\n", err);
-			goto update_bss_info_out;
-		}
-		bi = (struct wl_bss_info *)(wl->extra_buf + 4);
-		if (unlikely(memcmp(&bi->BSSID, &wl->bssid, ETH_ALEN))) {
-			err = -EIO;
-			goto update_bss_info_out;
-		}
-		err = wl_inform_single_bss(wl, bi);
-		if (unlikely(err))
-			goto update_bss_info_out;
-
-		ie = ((u8 *)bi) + bi->ie_offset;
-		ie_len = bi->ie_length;
-		beacon_interval = cpu_to_le16(bi->beacon_period);
-	} else {
-		WL_DBG("Found the AP in the list - BSSID %pM\n", bss->bssid);
-		ie = bss->information_elements;
-		ie_len = bss->len_information_elements;
-		beacon_interval = bss->beacon_interval;
-		cfg80211_put_bss(bss);
+	*(u32 *)wl->extra_buf = cpu_to_le32(WL_EXTRA_BUF_MAX);
+	err = wl_dev_ioctl(wl_to_ndev(wl), WLC_GET_BSS_INFO,
+			wl->extra_buf, WL_EXTRA_BUF_MAX);
+	if (unlikely(err)) {
+		WL_ERR("Could not get bss info %d\n", err);
+		goto update_bss_info_out;
 	}
 
+	bi = (struct wl_bss_info *)(wl->extra_buf + 4);
+	err = wl_inform_single_bss(wl, bi);
+	if (unlikely(err))
+		goto update_bss_info_out;
+
+	ie = ((u8 *)bi) + bi->ie_offset;
+	ie_len = bi->ie_length;
+	beacon_interval = cpu_to_le16(bi->beacon_period);
+
 	tim = bcm_parse_tlvs(ie, ie_len, WLAN_EID_TIM);
-	if (tim) {
+	if (tim)
 		dtim_period = tim->data[1];
-	} else {
+	else {
 		/*
 		* active scan was done so we could not get dtim
 		* information out of probe response.
 		* so we speficially query dtim information to dongle.
 		*/
-		err = wl_dev_ioctl(wl_to_ndev(wl), WLC_GET_DTIMPRD,
-			&dtim_period, sizeof(dtim_period));
+		u32 var;
+		err = wl_dev_intvar_get(wl_to_ndev(wl), "dtim_assoc", &var);
 		if (unlikely(err)) {
-			WL_ERR("WLC_GET_DTIMPRD error (%d)\n", err);
+			WL_ERR("wl dtim_assoc failed (%d)\n", err);
 			goto update_bss_info_out;
 		}
+		dtim_period = (u8)var;
 	}
 
 	wl_update_prof(wl, NULL, &beacon_interval, WL_PROF_BEACONINT);
 	wl_update_prof(wl, NULL, &dtim_period, WL_PROF_DTIMPERIOD);
 
 update_bss_info_out:
-	rtnl_unlock();
+	WL_TRACE("Exit");
 	return err;
 }
 
@@ -2627,17 +2863,20 @@
 	struct wl_connect_info *conn_info = wl_to_conn(wl);
 	s32 err = 0;
 
+	WL_TRACE("Enter\n");
+
 	wl_get_assoc_ies(wl);
-	memcpy(&wl->bssid, &e->addr, ETH_ALEN);
+	wl_update_prof(wl, NULL, &e->addr, WL_PROF_BSSID);
 	wl_update_bss_info(wl);
-	cfg80211_roamed(ndev,
-			(u8 *)&wl->bssid,
+
+	cfg80211_roamed(ndev, NULL,
+			(u8 *)wl_read_prof(wl, WL_PROF_BSSID),
 			conn_info->req_ie, conn_info->req_ie_len,
 			conn_info->resp_ie, conn_info->resp_ie_len, GFP_KERNEL);
-	WL_DBG("Report roaming result\n");
+	WL_CONN("Report roaming result\n");
 
 	set_bit(WL_STATUS_CONNECTED, &wl->status);
-
+	WL_TRACE("Exit\n");
 	return err;
 }
 
@@ -2648,30 +2887,28 @@
 	struct wl_connect_info *conn_info = wl_to_conn(wl);
 	s32 err = 0;
 
-	wl_get_assoc_ies(wl);
-	memcpy(&wl->bssid, &e->addr, ETH_ALEN);
-	wl_update_bss_info(wl);
+	WL_TRACE("Enter\n");
+
 	if (test_and_clear_bit(WL_STATUS_CONNECTING, &wl->status)) {
+		if (completed) {
+			wl_get_assoc_ies(wl);
+			wl_update_prof(wl, NULL, &e->addr, WL_PROF_BSSID);
+			wl_update_bss_info(wl);
+		}
 		cfg80211_connect_result(ndev,
-					(u8 *)&wl->bssid,
+					(u8 *)wl_read_prof(wl, WL_PROF_BSSID),
 					conn_info->req_ie,
 					conn_info->req_ie_len,
 					conn_info->resp_ie,
 					conn_info->resp_ie_len,
 					completed ? WLAN_STATUS_SUCCESS : WLAN_STATUS_AUTH_TIMEOUT,
 					GFP_KERNEL);
-		WL_DBG("Report connect result - connection %s\n",
-		       completed ? "succeeded" : "failed");
-	} else {
-		cfg80211_roamed(ndev,
-				(u8 *)&wl->bssid,
-				conn_info->req_ie, conn_info->req_ie_len,
-				conn_info->resp_ie, conn_info->resp_ie_len,
-				GFP_KERNEL);
-		WL_DBG("Report roaming result\n");
+		if (completed)
+			set_bit(WL_STATUS_CONNECTED, &wl->status);
+		WL_CONN("Report connect result - connection %s\n",
+				completed ? "succeeded" : "failed");
 	}
-	set_bit(WL_STATUS_CONNECTED, &wl->status);
-
+	WL_TRACE("Exit\n");
 	return err;
 }
 
@@ -2703,37 +2940,45 @@
 	struct wl_scan_results *bss_list;
 	u32 len = WL_SCAN_BUF_MAX;
 	s32 err = 0;
+	bool scan_abort = false;
 
-	if (wl->iscan_on && wl->iscan_kickstart)
+	WL_TRACE("Enter\n");
+
+	if (wl->iscan_on && wl->iscan_kickstart) {
+		WL_TRACE("Exit\n");
 		return wl_wakeup_iscan(wl_to_iscan(wl));
+	}
 
 	if (unlikely(!test_and_clear_bit(WL_STATUS_SCANNING, &wl->status))) {
 		WL_ERR("Scan complete while device not scanning\n");
-		return -EINVAL;
-	}
-	if (unlikely(!wl->scan_request)) {
+		scan_abort = true;
+		err = -EINVAL;
+		goto scan_done_out;
 	}
-	rtnl_lock();
+
 	err = wl_dev_ioctl(ndev, WLC_GET_CHANNEL, &channel_inform,
 			sizeof(channel_inform));
 	if (unlikely(err)) {
 		WL_ERR("scan busy (%d)\n", err);
+		scan_abort = true;
 		goto scan_done_out;
 	}
 	channel_inform.scan_channel = le32_to_cpu(channel_inform.scan_channel);
 	if (unlikely(channel_inform.scan_channel)) {
 
-		WL_DBG("channel_inform.scan_channel (%d)\n",
+		WL_CONN("channel_inform.scan_channel (%d)\n",
 		       channel_inform.scan_channel);
 	}
 	wl->bss_list = wl->scan_results;
 	bss_list = wl->bss_list;
 	memset(bss_list, 0, len);
 	bss_list->buflen = cpu_to_le32(len);
+
 	err = wl_dev_ioctl(ndev, WLC_SCAN_RESULTS, bss_list, len);
 	if (unlikely(err)) {
 		WL_ERR("%s Scan_results error (%d)\n", ndev->name, err);
 		err = -EINVAL;
+		scan_abort = true;
 		goto scan_done_out;
 	}
 	bss_list->buflen = le32_to_cpu(bss_list->buflen);
@@ -2741,16 +2986,21 @@
 	bss_list->count = le32_to_cpu(bss_list->count);
 
 	err = wl_inform_bss(wl);
-	if (err)
+	if (err) {
+		scan_abort = true;
 		goto scan_done_out;
+	}
 
 scan_done_out:
 	if (wl->scan_request) {
-		cfg80211_scan_done(wl->scan_request, false);
+		WL_SCAN("calling cfg80211_scan_done\n");
+		cfg80211_scan_done(wl->scan_request, scan_abort);
 		wl_set_mpc(ndev, 1);
 		wl->scan_request = NULL;
 	}
-	rtnl_unlock();
+
+	WL_TRACE("Exit\n");
+
 	return err;
 }
 
@@ -2773,12 +3023,7 @@
 {
 	memset(el, 0, sizeof(*el));
 	el->handler[WLC_E_SCAN_COMPLETE] = wl_notify_scan_status;
-	el->handler[WLC_E_JOIN] = wl_notify_connect_status;
 	el->handler[WLC_E_LINK] = wl_notify_connect_status;
-	el->handler[WLC_E_DEAUTH_IND] = wl_notify_connect_status;
-	el->handler[WLC_E_DISASSOC_IND] = wl_notify_connect_status;
-	el->handler[WLC_E_ASSOC_IND] = wl_notify_connect_status;
-	el->handler[WLC_E_REASSOC_IND] = wl_notify_connect_status;
 	el->handler[WLC_E_ROAM] = wl_notify_roaming_status;
 	el->handler[WLC_E_MIC_ERROR] = wl_notify_mic_status;
 	el->handler[WLC_E_SET_SSID] = wl_notify_connect_status;
@@ -2912,6 +3157,8 @@
 		return;
 	}
 	if (likely(wl->scan_request)) {
+		WL_SCAN("ISCAN Completed scan: %s\n",
+				aborted ? "Aborted" : "Done");
 		cfg80211_scan_done(wl->scan_request, aborted);
 		wl_set_mpc(ndev, 1);
 		wl->scan_request = NULL;
@@ -2922,7 +3169,7 @@
 static s32 wl_wakeup_iscan(struct wl_iscan_ctrl *iscan)
 {
 	if (likely(iscan->state != WL_ISCAN_STATE_IDLE)) {
-		WL_DBG("wake up iscan\n");
+		WL_SCAN("wake up iscan\n");
 		up(&iscan->sync);
 		return 0;
 	}
@@ -2958,8 +3205,8 @@
 	results->buflen = le32_to_cpu(results->buflen);
 	results->version = le32_to_cpu(results->version);
 	results->count = le32_to_cpu(results->count);
-	WL_DBG("results->count = %d\n", results->count);
-	WL_DBG("results->buflen = %d\n", results->buflen);
+	WL_SCAN("results->count = %d\n", results->count);
+	WL_SCAN("results->buflen = %d\n", results->buflen);
 	*status = le32_to_cpu(list_buf->status);
 	*bss_list = results;
 
@@ -3053,7 +3300,7 @@
 		del_timer_sync(&iscan->timer);
 		iscan->timer_on = 0;
 	}
-	WL_DBG("%s was terminated\n", __func__);
+	WL_SCAN("ISCAN thread terminated\n");
 
 	return 0;
 }
@@ -3064,7 +3311,7 @@
 
 	if (iscan) {
 		iscan->timer_on = 0;
-		WL_DBG("timer expired\n");
+		WL_SCAN("timer expired\n");
 		wl_wakeup_iscan(iscan);
 	}
 }
@@ -3191,7 +3438,7 @@
 		WL_ERR("wl_cfg80211_dev is invalid\n");
 		return -ENOMEM;
 	}
-	WL_DBG("func %p\n", wl_cfg80211_get_sdio_func());
+	WL_INFO("func %p\n", wl_cfg80211_get_sdio_func());
 	wdev = wl_alloc_wdev(sizeof(struct wl_iface), &wl_cfg80211_get_sdio_func()->dev);
 	if (IS_ERR(wdev))
 		return -ENOMEM;
@@ -3211,7 +3458,6 @@
 		goto cfg80211_attach_out;
 	}
 	wl_set_drvdata(wl_cfg80211_dev, ci);
-	set_bit(WL_STATUS_READY, &wl->status);
 
 	return err;
 
@@ -3255,16 +3501,16 @@
 			WL_ERR("event queue empty...\n");
 			BUG();
 		}
-		WL_DBG("event type (%d)\n", e->etype);
+		WL_INFO("event type (%d)\n", e->etype);
 		if (wl->el.handler[e->etype]) {
 			wl->el.handler[e->etype] (wl, wl_to_ndev(wl), &e->emsg,
 						  e->edata);
 		} else {
-			WL_DBG("Unknown Event (%d): ignoring\n", e->etype);
+			WL_INFO("Unknown Event (%d): ignoring\n", e->etype);
 		}
 		wl_put_event(e);
 	}
-	WL_DBG("%s was terminated\n", __func__);
+	WL_INFO("was terminated\n");
 	return 0;
 }
 
@@ -3273,11 +3519,7 @@
 {
 	u32 event_type = be32_to_cpu(e->event_type);
 	struct wl_priv *wl = ndev_to_wl(ndev);
-#if (WL_DBG_LEVEL > 0)
-	s8 *estr = (event_type <= sizeof(wl_dbg_estr) / WL_DBG_ESTR_MAX - 1) ?
-	    wl_dbg_estr[event_type] : (s8 *) "Unknown";
-#endif				/* (WL_DBG_LEVEL > 0) */
-	WL_DBG("event_type (%d):" "WLC_E_" "%s\n", event_type, estr);
+
 	if (likely(!wl_enq_event(wl, event_type, e, data)))
 		wl_wakeup_event(wl);
 }
@@ -3370,7 +3612,6 @@
 static s32 wl_dongle_mode(struct net_device *ndev, s32 iftype)
 {
 	s32 infra = 0;
-	s32 ap = 0;
 	s32 err = 0;
 
 	switch (iftype) {
@@ -3381,6 +3622,7 @@
 		err = -EINVAL;
 		return err;
 	case NL80211_IFTYPE_ADHOC:
+		infra = 0;
 		break;
 	case NL80211_IFTYPE_STATION:
 		infra = 1;
@@ -3391,20 +3633,13 @@
 		return err;
 	}
 	infra = cpu_to_le32(infra);
-	ap = cpu_to_le32(ap);
-	WL_DBG("%s ap (%d), infra (%d)\n", ndev->name, ap, infra);
 	err = wl_dev_ioctl(ndev, WLC_SET_INFRA, &infra, sizeof(infra));
 	if (unlikely(err)) {
 		WL_ERR("WLC_SET_INFRA error (%d)\n", err);
 		return err;
 	}
-	err = wl_dev_ioctl(ndev, WLC_SET_AP, &ap, sizeof(ap));
-	if (unlikely(err)) {
-		WL_ERR("WLC_SET_AP error (%d)\n", err);
-		return err;
-	}
 
-	return -EINPROGRESS;
+	return 0;
 }
 
 #ifndef EMBEDDED_PLATFORM
@@ -3465,116 +3700,6 @@
 }
 
 static s32
-wl_dongle_roam(struct net_device *ndev, u32 roamvar, u32 bcn_timeout)
-{
-	s8 iovbuf[WL_EVENTING_MASK_LEN + 12];	/*  Room for "event_msgs" +
-						 '\0' + bitvec  */
-	s32 err = 0;
-
-	/* Setup timeout if Beacons are lost and roam is
-		 off to report link down */
-	if (roamvar) {
-		bcm_mkiovar("bcn_timeout", (char *)&bcn_timeout, 4, iovbuf,
-			    sizeof(iovbuf));
-		err = wl_dev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf));
-		if (unlikely(err)) {
-			WL_ERR("bcn_timeout error (%d)\n", err);
-			goto dongle_rom_out;
-		}
-	}
-	/* Enable/Disable built-in roaming to allow supplicant
-		 to take care of roaming */
-	bcm_mkiovar("roam_off", (char *)&roamvar, 4, iovbuf, sizeof(iovbuf));
-	err = wl_dev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf));
-	if (unlikely(err)) {
-		WL_ERR("roam_off error (%d)\n", err);
-		goto dongle_rom_out;
-	}
-dongle_rom_out:
-	return err;
-}
-
-static s32 wl_dongle_eventmsg(struct net_device *ndev)
-{
-
-	s8 iovbuf[WL_EVENTING_MASK_LEN + 12];	/*  Room for "event_msgs" +
-						 '\0' + bitvec  */
-	s8 eventmask[WL_EVENTING_MASK_LEN];
-	s32 err = 0;
-
-	/* Setup event_msgs */
-	bcm_mkiovar("event_msgs", eventmask, WL_EVENTING_MASK_LEN, iovbuf,
-		    sizeof(iovbuf));
-	err = wl_dev_ioctl(ndev, WLC_GET_VAR, iovbuf, sizeof(iovbuf));
-	if (unlikely(err)) {
-		WL_ERR("Get event_msgs error (%d)\n", err);
-		goto dongle_eventmsg_out;
-	}
-	memcpy(eventmask, iovbuf, WL_EVENTING_MASK_LEN);
-
-	setbit(eventmask, WLC_E_SET_SSID);
-	setbit(eventmask, WLC_E_PRUNE);
-	setbit(eventmask, WLC_E_AUTH);
-	setbit(eventmask, WLC_E_REASSOC);
-	setbit(eventmask, WLC_E_REASSOC_IND);
-	setbit(eventmask, WLC_E_DEAUTH_IND);
-	setbit(eventmask, WLC_E_DISASSOC_IND);
-	setbit(eventmask, WLC_E_DISASSOC);
-	setbit(eventmask, WLC_E_JOIN);
-	setbit(eventmask, WLC_E_ASSOC_IND);
-	setbit(eventmask, WLC_E_PSK_SUP);
-	setbit(eventmask, WLC_E_LINK);
-	setbit(eventmask, WLC_E_NDIS_LINK);
-	setbit(eventmask, WLC_E_MIC_ERROR);
-	setbit(eventmask, WLC_E_PMKID_CACHE);
-	setbit(eventmask, WLC_E_TXFAIL);
-	setbit(eventmask, WLC_E_JOIN_START);
-	setbit(eventmask, WLC_E_SCAN_COMPLETE);
-
-	bcm_mkiovar("event_msgs", eventmask, WL_EVENTING_MASK_LEN, iovbuf,
-		    sizeof(iovbuf));
-	err = wl_dev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf));
-	if (unlikely(err)) {
-		WL_ERR("Set event_msgs error (%d)\n", err);
-		goto dongle_eventmsg_out;
-	}
-
-dongle_eventmsg_out:
-	return err;
-}
-
-static s32
-wl_dongle_scantime(struct net_device *ndev, s32 scan_assoc_time,
-		   s32 scan_unassoc_time)
-{
-	s32 err = 0;
-
-	err = wl_dev_ioctl(ndev, WLC_SET_SCAN_CHANNEL_TIME, &scan_assoc_time,
-			sizeof(scan_assoc_time));
-	if (err) {
-		if (err == -EOPNOTSUPP) {
-			WL_INFO("Scan assoc time is not supported\n");
-		} else {
-			WL_ERR("Scan assoc time error (%d)\n", err);
-		}
-		goto dongle_scantime_out;
-	}
-	err = wl_dev_ioctl(ndev, WLC_SET_SCAN_UNASSOC_TIME, &scan_unassoc_time,
-			sizeof(scan_unassoc_time));
-	if (err) {
-		if (err == -EOPNOTSUPP) {
-			WL_INFO("Scan unassoc time is not supported\n");
-		} else {
-			WL_ERR("Scan unassoc time error (%d)\n", err);
-		}
-		goto dongle_scantime_out;
-	}
-
-dongle_scantime_out:
-	return err;
-}
-
-static s32
 wl_dongle_offload(struct net_device *ndev, s32 arpoe, s32 arp_ol)
 {
 	s8 iovbuf[WL_EVENTING_MASK_LEN + 12];	/*  Room for "event_msgs" +
@@ -3722,6 +3847,154 @@
 }
 #endif				/* !EMBEDDED_PLATFORM */
 
+static s32 wl_dongle_eventmsg(struct net_device *ndev)
+{
+	s8 iovbuf[WL_EVENTING_MASK_LEN + 12];	/*  Room for "event_msgs" +
+						 '\0' + bitvec  */
+	s8 eventmask[WL_EVENTING_MASK_LEN];
+	s32 err = 0;
+
+	WL_TRACE("Enter\n");
+
+	/* Setup event_msgs */
+	bcm_mkiovar("event_msgs", eventmask, WL_EVENTING_MASK_LEN, iovbuf,
+		    sizeof(iovbuf));
+	err = wl_dev_ioctl(ndev, WLC_GET_VAR, iovbuf, sizeof(iovbuf));
+	if (unlikely(err)) {
+		WL_ERR("Get event_msgs error (%d)\n", err);
+		goto dongle_eventmsg_out;
+	}
+	memcpy(eventmask, iovbuf, WL_EVENTING_MASK_LEN);
+
+	setbit(eventmask, WLC_E_SET_SSID);
+	setbit(eventmask, WLC_E_ROAM);
+	setbit(eventmask, WLC_E_PRUNE);
+	setbit(eventmask, WLC_E_AUTH);
+	setbit(eventmask, WLC_E_REASSOC);
+	setbit(eventmask, WLC_E_REASSOC_IND);
+	setbit(eventmask, WLC_E_DEAUTH_IND);
+	setbit(eventmask, WLC_E_DISASSOC_IND);
+	setbit(eventmask, WLC_E_DISASSOC);
+	setbit(eventmask, WLC_E_JOIN);
+	setbit(eventmask, WLC_E_ASSOC_IND);
+	setbit(eventmask, WLC_E_PSK_SUP);
+	setbit(eventmask, WLC_E_LINK);
+	setbit(eventmask, WLC_E_NDIS_LINK);
+	setbit(eventmask, WLC_E_MIC_ERROR);
+	setbit(eventmask, WLC_E_PMKID_CACHE);
+	setbit(eventmask, WLC_E_TXFAIL);
+	setbit(eventmask, WLC_E_JOIN_START);
+	setbit(eventmask, WLC_E_SCAN_COMPLETE);
+
+	bcm_mkiovar("event_msgs", eventmask, WL_EVENTING_MASK_LEN, iovbuf,
+		    sizeof(iovbuf));
+	err = wl_dev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf));
+	if (unlikely(err)) {
+		WL_ERR("Set event_msgs error (%d)\n", err);
+		goto dongle_eventmsg_out;
+	}
+
+dongle_eventmsg_out:
+	WL_TRACE("Exit\n");
+	return err;
+}
+
+static s32
+wl_dongle_roam(struct net_device *ndev, u32 roamvar, u32 bcn_timeout)
+{
+	s8 iovbuf[32];
+	s32 roamtrigger[2];
+	s32 roam_delta[2];
+	s32 err = 0;
+
+	/*
+	 * Setup timeout if Beacons are lost and roam is
+	 * off to report link down
+	 */
+	if (roamvar) {
+		bcm_mkiovar("bcn_timeout", (char *)&bcn_timeout,
+			sizeof(bcn_timeout), iovbuf, sizeof(iovbuf));
+		err = wl_dev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf));
+		if (unlikely(err)) {
+			WL_ERR("bcn_timeout error (%d)\n", err);
+			goto dongle_rom_out;
+		}
+	}
+
+	/*
+	 * Enable/Disable built-in roaming to allow supplicant
+	 * to take care of roaming
+	 */
+	WL_INFO("Internal Roaming = %s\n", roamvar ? "Off" : "On");
+	bcm_mkiovar("roam_off", (char *)&roamvar,
+				sizeof(roamvar), iovbuf, sizeof(iovbuf));
+	err = wl_dev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf));
+	if (unlikely(err)) {
+		WL_ERR("roam_off error (%d)\n", err);
+		goto dongle_rom_out;
+	}
+
+	roamtrigger[0] = WL_ROAM_TRIGGER_LEVEL;
+	roamtrigger[1] = WLC_BAND_ALL;
+	err = wl_dev_ioctl(ndev, WLC_SET_ROAM_TRIGGER,
+			(void *)roamtrigger, sizeof(roamtrigger));
+	if (unlikely(err)) {
+		WL_ERR("WLC_SET_ROAM_TRIGGER error (%d)\n", err);
+		goto dongle_rom_out;
+	}
+
+	roam_delta[0] = WL_ROAM_DELTA;
+	roam_delta[1] = WLC_BAND_ALL;
+	err = wl_dev_ioctl(ndev, WLC_SET_ROAM_DELTA,
+				(void *)roam_delta, sizeof(roam_delta));
+	if (unlikely(err)) {
+		WL_ERR("WLC_SET_ROAM_DELTA error (%d)\n", err);
+		goto dongle_rom_out;
+	}
+
+dongle_rom_out:
+	return err;
+}
+
+static s32
+wl_dongle_scantime(struct net_device *ndev, s32 scan_assoc_time,
+		s32 scan_unassoc_time, s32 scan_passive_time)
+{
+	s32 err = 0;
+
+	err = wl_dev_ioctl(ndev, WLC_SET_SCAN_CHANNEL_TIME, &scan_assoc_time,
+			sizeof(scan_assoc_time));
+	if (err) {
+		if (err == -EOPNOTSUPP)
+			WL_INFO("Scan assoc time is not supported\n");
+		else
+			WL_ERR("Scan assoc time error (%d)\n", err);
+		goto dongle_scantime_out;
+	}
+	err = wl_dev_ioctl(ndev, WLC_SET_SCAN_UNASSOC_TIME, &scan_unassoc_time,
+			sizeof(scan_unassoc_time));
+	if (err) {
+		if (err == -EOPNOTSUPP)
+			WL_INFO("Scan unassoc time is not supported\n");
+		else
+			WL_ERR("Scan unassoc time error (%d)\n", err);
+		goto dongle_scantime_out;
+	}
+
+	err = wl_dev_ioctl(ndev, WLC_SET_SCAN_PASSIVE_TIME, &scan_passive_time,
+			sizeof(scan_passive_time));
+	if (err) {
+		if (err == -EOPNOTSUPP)
+			WL_INFO("Scan passive time is not supported\n");
+		else
+			WL_ERR("Scan passive time error (%d)\n", err);
+		goto dongle_scantime_out;
+	}
+
+dongle_scantime_out:
+	return err;
+}
+
 s32 wl_config_dongle(struct wl_priv *wl, bool need_lock)
 {
 #ifndef DHD_SDALIGN
@@ -3752,18 +4025,20 @@
 	err = wl_dongle_glom(ndev, 0, DHD_SDALIGN);
 	if (unlikely(err))
 		goto default_conf_out;
-	err = wl_dongle_roam(ndev, (wl->roam_on ? 0 : 1), 3);
-	if (unlikely(err))
-		goto default_conf_out;
-	err = wl_dongle_eventmsg(ndev);
-	if (unlikely(err))
-		goto default_conf_out;
 
-	wl_dongle_scantime(ndev, 40, 80);
 	wl_dongle_offload(ndev, 1, 0xf);
 	wl_dongle_filter(ndev, 1);
-#endif				/* !EMBEDDED_PLATFORM */
+#endif /* !EMBEDDED_PLATFORM */
 
+	wl_dongle_scantime(ndev, WL_SCAN_CHANNEL_TIME,
+			WL_SCAN_UNASSOC_TIME, WL_SCAN_PASSIVE_TIME);
+
+	err = wl_dongle_eventmsg(ndev);
+	if (unlikely(err))
+		goto default_conf_out;
+	err = wl_dongle_roam(ndev, (wl->roam_on ? 0 : 1), WL_BEACON_TIMEOUT);
+	if (unlikely(err))
+		goto default_conf_out;
 	err = wl_dongle_mode(ndev, wdev->iftype);
 	if (unlikely(err && err != -EINPROGRESS))
 		goto default_conf_out;
@@ -3798,7 +4073,7 @@
 	}
 
 	phy = ((char *)&phy_list)[1];
-	WL_DBG("%c phy\n", phy);
+	WL_INFO("%c phy\n", phy);
 	if (phy == 'n' || phy == 'a') {
 		wiphy = wl_to_wiphy(wl);
 		wiphy->bands[IEEE80211_BAND_5GHZ] = &__wl_band_5ghz_n;
@@ -3811,6 +4086,8 @@
 {
 	s32 err = 0;
 
+	set_bit(WL_STATUS_READY, &wl->status);
+
 	wl_debugfs_add_netdev_params(wl);
 
 	err = wl_config_dongle(wl, false);
@@ -3818,41 +4095,29 @@
 		return err;
 
 	wl_invoke_iscan(wl);
-	set_bit(WL_STATUS_READY, &wl->status);
+
 	return err;
 }
 
 static s32 __wl_cfg80211_down(struct wl_priv *wl)
 {
-	s32 err = 0;
-
-	/* Check if cfg80211 interface is already down */
-	if (!test_bit(WL_STATUS_READY, &wl->status))
-		return err;	/* it is even not ready */
-
 	set_bit(WL_STATUS_SCAN_ABORTING, &wl->status);
 	wl_term_iscan(wl);
 	if (wl->scan_request) {
-		cfg80211_scan_done(wl->scan_request, true);	/* true
-								 means abort */
-		/* wl_set_mpc(wl_to_ndev(wl), 1); */	/* BUG
-						* this operation cannot help
-						* but here because sdio
-						* is already down through
-						* rmmod process.
-						* Need to figure out how to
-						* address this issue
-						*/
+		cfg80211_scan_done(wl->scan_request, true);
+		/* May need to perform this to cover rmmod */
+		/* wl_set_mpc(wl_to_ndev(wl), 1); */
 		wl->scan_request = NULL;
 	}
 	clear_bit(WL_STATUS_READY, &wl->status);
 	clear_bit(WL_STATUS_SCANNING, &wl->status);
 	clear_bit(WL_STATUS_SCAN_ABORTING, &wl->status);
+	clear_bit(WL_STATUS_CONNECTING, &wl->status);
 	clear_bit(WL_STATUS_CONNECTED, &wl->status);
 
 	wl_debugfs_remove_netdev(wl);
 
-	return err;
+	return 0;
 }
 
 s32 wl_cfg80211_up(void)
@@ -3897,8 +4162,6 @@
 	switch (item) {
 	case WL_PROF_SEC:
 		return &wl->profile->sec;
-	case WL_PROF_ACT:
-		return &wl->profile->active;
 	case WL_PROF_BSSID:
 		return &wl->profile->bssid;
 	case WL_PROF_SSID:
@@ -3932,9 +4195,6 @@
 	case WL_PROF_SEC:
 		memcpy(&wl->profile->sec, data, sizeof(wl->profile->sec));
 		break;
-	case WL_PROF_ACT:
-		wl->profile->active = *(bool *)data;
-		break;
 	case WL_PROF_BEACONINT:
 		wl->profile->beacon_interval = *(u16 *)data;
 		break;
@@ -3950,34 +4210,11 @@
 	return err;
 }
 
-void wl_cfg80211_dbg_level(u32 level)
-{
-	/*
-	* prohibit to change debug level
-	* by insmod parameter.
-	* eventually debug level will be configured
-	* in compile time by using CONFIG_XXX
-	*/
-	/* wl_dbg_level = level; */
-}
-
 static bool wl_is_ibssmode(struct wl_priv *wl)
 {
 	return wl->conf->mode == WL_MODE_IBSS;
 }
 
-static bool wl_is_ibssstarter(struct wl_priv *wl)
-{
-	return wl->ibss_starter;
-}
-
-static void wl_rst_ie(struct wl_priv *wl)
-{
-	struct wl_ie *ie = wl_to_ie(wl);
-
-	ie->offset = 0;
-}
-
 static __used s32 wl_add_ie(struct wl_priv *wl, u8 t, u8 l, u8 *v)
 {
 	struct wl_ie *ie = wl_to_ie(wl);
@@ -3995,58 +4232,24 @@
 	return err;
 }
 
-static s32 wl_mrg_ie(struct wl_priv *wl, u8 *ie_stream, u16 ie_size)
-{
-	struct wl_ie *ie = wl_to_ie(wl);
-	s32 err = 0;
 
-	if (unlikely(ie->offset + ie_size > WL_TLV_INFO_MAX)) {
-		WL_ERR("ei_stream crosses buffer boundary\n");
-		return -ENOSPC;
-	}
-	memcpy(&ie->buf[ie->offset], ie_stream, ie_size);
-	ie->offset += ie_size;
-
-	return err;
-}
-
-static s32 wl_cp_ie(struct wl_priv *wl, u8 *dst, u16 dst_size)
+static void wl_link_down(struct wl_priv *wl)
 {
-	struct wl_ie *ie = wl_to_ie(wl);
+	struct net_device *dev = NULL;
 	s32 err = 0;
 
-	if (unlikely(ie->offset > dst_size)) {
-		WL_ERR("dst_size is not enough\n");
-		return -ENOSPC;
-	}
-	memcpy(dst, &ie->buf[0], ie->offset);
-
-	return err;
-}
-
-static u32 wl_get_ielen(struct wl_priv *wl)
-{
-	struct wl_ie *ie = wl_to_ie(wl);
-
-	return ie->offset;
-}
-
-static void wl_link_up(struct wl_priv *wl)
-{
-	wl->link_up = true;
-}
-
-static void wl_link_down(struct wl_priv *wl)
-{
-	struct wl_connect_info *conn_info = wl_to_conn(wl);
+	WL_TRACE("Enter\n");
+	clear_bit(WL_STATUS_CONNECTED, &wl->status);
 
-	wl->link_up = false;
-	kfree(conn_info->req_ie);
-	conn_info->req_ie = NULL;
-	conn_info->req_ie_len = 0;
-	kfree(conn_info->resp_ie);
-	conn_info->resp_ie = NULL;
-	conn_info->resp_ie_len = 0;
+	if (wl->link_up) {
+		dev = wl_to_ndev(wl);
+		WL_INFO("Call WLC_DISASSOC to stop excess roaming\n ");
+		err = wl_dev_ioctl(dev, WLC_DISASSOC, NULL, 0);
+		if (unlikely(err))
+			WL_ERR("WLC_DISASSOC failed (%d)\n", err);
+		wl->link_up = false;
+	}
+	WL_TRACE("Exit\n");
 }
 
 static void wl_lock_eq(struct wl_priv *wl)
@@ -4116,7 +4319,7 @@
 	const struct firmware *fw_entry = NULL;
 	s32 err = 0;
 
-	WL_DBG("file name : \"%s\"\n", file_name);
+	WL_INFO("file name : \"%s\"\n", file_name);
 	wl = WL_PRIV_GET();
 
 	if (!test_bit(WL_FW_LOADING_DONE, &wl->fw->status)) {
@@ -4129,7 +4332,7 @@
 		set_bit(WL_FW_LOADING_DONE, &wl->fw->status);
 		fw_entry = wl->fw->fw_entry;
 		if (fw_entry) {
-			WL_DBG("fw size (%zd), data (%p)\n",
+			WL_INFO("fw size (%zd), data (%p)\n",
 			       fw_entry->size, fw_entry->data);
 		}
 	} else if (!test_bit(WL_NVRAM_LOADING_DONE, &wl->fw->status)) {
@@ -4142,11 +4345,11 @@
 		set_bit(WL_NVRAM_LOADING_DONE, &wl->fw->status);
 		fw_entry = wl->fw->fw_entry;
 		if (fw_entry) {
-			WL_DBG("nvram size (%zd), data (%p)\n",
+			WL_INFO("nvram size (%zd), data (%p)\n",
 			       fw_entry->size, fw_entry->data);
 		}
 	} else {
-		WL_DBG("Downloading already done. Nothing to do more\n");
+		WL_INFO("Downloading already done. Nothing to do more\n");
 		err = -EPERM;
 	}
 
@@ -4179,13 +4382,16 @@
 static void wl_set_mpc(struct net_device *ndev, int mpc)
 {
 	s32 err = 0;
+	struct wl_priv *wl = ndev_to_wl(ndev);
 
-	err = wl_dev_intvar_set(ndev, "mpc", mpc);
-	if (unlikely(err)) {
-		WL_ERR("fail to set mpc\n");
-		return;
+	if (test_bit(WL_STATUS_READY, &wl->status)) {
+		err = wl_dev_intvar_set(ndev, "mpc", mpc);
+		if (unlikely(err)) {
+			WL_ERR("fail to set mpc\n");
+			return;
+		}
+		WL_INFO("MPC : %d\n", mpc);
 	}
-	WL_DBG("MPC : %d\n", mpc);
 }
 
 static int wl_debugfs_add_netdev_params(struct wl_priv *wl)
diff -druN linux-2.6.39-libre/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.h linux-3.0-rc7-libre/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.h
--- linux-2.6.39-libre/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.h	2011-07-11 19:51:52.000000000 -0400
@@ -28,45 +28,73 @@
 struct wl_security;
 struct wl_ibss;
 
-#define WL_DBG_NONE	0
-#define WL_DBG_DBG 	(1 << 2)
-#define WL_DBG_INFO	(1 << 1)
-#define WL_DBG_ERR	(1 << 0)
-#define WL_DBG_MASK ((WL_DBG_DBG | WL_DBG_INFO | WL_DBG_ERR) << 1)
+#define WL_DBG_NONE		0
+#define WL_DBG_CONN		(1 << 5)
+#define WL_DBG_SCAN		(1 << 4)
+#define WL_DBG_TRACE		(1 << 3)
+#define WL_DBG_INFO		(1 << 1)
+#define WL_DBG_ERR		(1 << 0)
+#define WL_DBG_MASK		((WL_DBG_INFO | WL_DBG_ERR | WL_DBG_TRACE) | \
+				(WL_DBG_SCAN) | (WL_DBG_CONN))
 
-#define WL_DBG_LEVEL 1		/* 0 invalidates all debug messages.
-				 default is 1 */
 #define	WL_ERR(fmt, args...)					\
 do {								\
 	if (wl_dbg_level & WL_DBG_ERR) {			\
 		if (net_ratelimit()) {				\
 			printk(KERN_ERR "ERROR @%s : " fmt,	\
-			       __func__, ##args);		\
+				__func__, ##args);		\
 		}						\
 	}							\
 } while (0)
 
+#if (defined BCMDBG)
 #define	WL_INFO(fmt, args...)					\
 do {								\
 	if (wl_dbg_level & WL_DBG_INFO) {			\
 		if (net_ratelimit()) {				\
 			printk(KERN_ERR "INFO @%s : " fmt,	\
-			       __func__, ##args);		\
+				__func__, ##args);		\
 		}						\
 	}							\
 } while (0)
 
-#if (WL_DBG_LEVEL > 0)
-#define	WL_DBG(fmt, args...)					\
+#define	WL_TRACE(fmt, args...)					\
 do {								\
-	if (wl_dbg_level & WL_DBG_DBG) {			\
-		printk(KERN_ERR "DEBUG @%s :" fmt,		\
-		       __func__, ##args);			\
+	if (wl_dbg_level & WL_DBG_TRACE) {			\
+		if (net_ratelimit()) {				\
+			printk(KERN_ERR "TRACE @%s : " fmt,	\
+				__func__, ##args);		\
+		}						\
 	}							\
 } while (0)
-#else				/* !(WL_DBG_LEVEL > 0) */
-#define	WL_DBG(fmt, args...) noprintk(fmt, ##args)
-#endif				/* (WL_DBG_LEVEL > 0) */
+
+#define	WL_SCAN(fmt, args...)					\
+do {								\
+	if (wl_dbg_level & WL_DBG_SCAN) {			\
+		if (net_ratelimit()) {				\
+			printk(KERN_ERR "SCAN @%s : " fmt,	\
+				__func__, ##args);		\
+		}						\
+	}							\
+} while (0)
+
+#define	WL_CONN(fmt, args...)					\
+do {								\
+	if (wl_dbg_level & WL_DBG_CONN) {			\
+		if (net_ratelimit()) {				\
+			printk(KERN_ERR "CONN @%s : " fmt,	\
+				__func__, ##args);		\
+		}						\
+	}							\
+} while (0)
+
+#else /* (defined BCMDBG) */
+#define	WL_INFO(fmt, args...)
+#define	WL_TRACE(fmt, args...)
+#define	WL_SCAN(fmt, args...)
+#define	WL_CONN(fmt, args...)
+#endif /* (defined BCMDBG) */
+
 
 #define WL_SCAN_RETRY_MAX	3	/* used for ibss scan */
 #define WL_NUM_SCAN_MAX		1
@@ -95,6 +123,14 @@
 				 */
 #define WL_FILE_NAME_MAX		256
 
+#define WL_ROAM_TRIGGER_LEVEL		-75
+#define WL_ROAM_DELTA			20
+#define WL_BEACON_TIMEOUT		3
+
+#define WL_SCAN_CHANNEL_TIME		40
+#define WL_SCAN_UNASSOC_TIME		40
+#define WL_SCAN_PASSIVE_TIME		120
+
 /* dongle status */
 enum wl_status {
 	WL_STATUS_READY,
@@ -227,7 +263,6 @@
 	struct wl_security sec;
 	struct wl_ibss ibss;
 	s32 band;
-	bool active;
 };
 
 /* dongle iscan event loop */
@@ -298,7 +333,6 @@
 						 cfg80211 layer */
 	struct wl_ie ie;	/* information element object for
 					 internal purpose */
-	u8 bssid[ETH_ALEN];	/* bssid of currently engaged network */
 	struct semaphore event_sync;	/* for synchronization of main event
 					 thread */
 	struct wl_profile *profile;	/* holding dongle profile */
@@ -375,5 +409,6 @@
 						 the dongle */
 extern s8 *wl_cfg80211_get_nvramname(void);	/* get nvram name for
 						 the dongle */
+extern void wl_os_wd_timer(struct net_device *ndev, uint wdtick);
 
 #endif				/* _wl_cfg80211_h_ */
diff -druN linux-2.6.39-libre/drivers/staging/brcm80211/brcmfmac/wl_iw.c linux-3.0-rc7-libre/drivers/staging/brcm80211/brcmfmac/wl_iw.c
--- linux-2.6.39-libre/drivers/staging/brcm80211/brcmfmac/wl_iw.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/brcm80211/brcmfmac/wl_iw.c	2011-07-11 19:51:52.000000000 -0400
@@ -64,13 +64,9 @@
 extern bool wl_iw_conn_status_str(u32 event_type, u32 status,
 				  u32 reason, char *stringBuf, uint buflen);
 
-uint wl_msg_level = WL_ERROR_VAL;
-
 #define MAX_WLIW_IOCTL_LEN 1024
 
 #ifdef CONFIG_WIRELESS_EXT
-
-extern struct iw_statistics *dhd_get_wireless_stats(struct net_device *dev);
 extern int dhd_wait_pend8021x(struct net_device *dev);
 #endif
 
@@ -119,6 +115,9 @@
 
 static const u8 ether_bcast[ETH_ALEN] = {255, 255, 255, 255, 255, 255};
 
+/* Global ASSERT type flag */
+u32 g_assert_type;
+
 static void wl_iw_timerfunc(unsigned long data);
 static void wl_iw_set_event_mask(struct net_device *dev);
 static int wl_iw_iscan(iscan_info_t *iscan, wlc_ssid_t *ssid, u16 action);
@@ -372,7 +371,7 @@
 		if (fwrq->m > 4000 && fwrq->m < 5000)
 			sf = WF_CHAN_FACTOR_4_G;
 
-		chan = wf_mhz2channel(fwrq->m, sf);
+		chan = bcm_mhz2channel(fwrq->m, sf);
 	}
 	chan = cpu_to_le32(chan);
 
@@ -495,9 +494,7 @@
 	list = (wl_u32_list_t *) channels;
 
 	dwrq->length = sizeof(struct iw_range);
-	memset(range, 0, sizeof(range));
-
-	range->min_nwid = range->max_nwid = 0;
+	memset(range, 0, sizeof(*range));
 
 	list->count = cpu_to_le32(MAXCHANNEL);
 	error = dev_wlc_ioctl(dev, WLC_GET_VALID_CHANNELS, channels,
@@ -3131,7 +3128,7 @@
 	.private_args = 0,
 
 #if WIRELESS_EXT >= 19
-	.get_wireless_stats = dhd_get_wireless_stats,
+	.get_wireless_stats = NULL,
 #endif
 };
 #endif				/* WIRELESS_EXT > 12 */
@@ -3548,103 +3545,6 @@
 #endif				/* WIRELESS_EXT > 13 */
 }
 
-int
-wl_iw_get_wireless_stats(struct net_device *dev, struct iw_statistics *wstats)
-{
-	int res = 0;
-	struct wl_cnt cnt;
-	int phy_noise;
-	int rssi;
-	scb_val_t scb_val;
-
-	phy_noise = 0;
-	res = dev_wlc_ioctl(dev, WLC_GET_PHY_NOISE, &phy_noise,
-				sizeof(phy_noise));
-	if (res)
-		goto done;
-
-	phy_noise = le32_to_cpu(phy_noise);
-	WL_TRACE("wl_iw_get_wireless_stats phy noise=%d\n", phy_noise);
-
-	memset(&scb_val, 0, sizeof(scb_val_t));
-	res = dev_wlc_ioctl(dev, WLC_GET_RSSI, &scb_val, sizeof(scb_val_t));
-	if (res)
-		goto done;
-
-	rssi = le32_to_cpu(scb_val.val);
-	WL_TRACE("wl_iw_get_wireless_stats rssi=%d\n", rssi);
-	if (rssi <= WL_IW_RSSI_NO_SIGNAL)
-		wstats->qual.qual = 0;
-	else if (rssi <= WL_IW_RSSI_VERY_LOW)
-		wstats->qual.qual = 1;
-	else if (rssi <= WL_IW_RSSI_LOW)
-		wstats->qual.qual = 2;
-	else if (rssi <= WL_IW_RSSI_GOOD)
-		wstats->qual.qual = 3;
-	else if (rssi <= WL_IW_RSSI_VERY_GOOD)
-		wstats->qual.qual = 4;
-	else
-		wstats->qual.qual = 5;
-
-	wstats->qual.level = 0x100 + rssi;
-	wstats->qual.noise = 0x100 + phy_noise;
-#if WIRELESS_EXT > 18
-	wstats->qual.updated |= (IW_QUAL_ALL_UPDATED | IW_QUAL_DBM);
-#else
-	wstats->qual.updated |= 7;
-#endif
-
-#if WIRELESS_EXT > 11
-	WL_TRACE("wl_iw_get_wireless_stats counters=%zu\n",
-		 sizeof(struct wl_cnt));
-
-	memset(&cnt, 0, sizeof(struct wl_cnt));
-	res =
-	    dev_wlc_bufvar_get(dev, "counters", (char *)&cnt,
-			       sizeof(struct wl_cnt));
-	if (res) {
-		WL_ERROR("wl_iw_get_wireless_stats counters failed error=%d\n",
-			 res);
-		goto done;
-	}
-
-	cnt.version = le16_to_cpu(cnt.version);
-	if (cnt.version != WL_CNT_T_VERSION) {
-		WL_TRACE("\tIncorrect counter version: expected %d; got %d\n",
-			 WL_CNT_T_VERSION, cnt.version);
-		goto done;
-	}
-
-	wstats->discard.nwid = 0;
-	wstats->discard.code = le32_to_cpu(cnt.rxundec);
-	wstats->discard.fragment = le32_to_cpu(cnt.rxfragerr);
-	wstats->discard.retries = le32_to_cpu(cnt.txfail);
-	wstats->discard.misc = le32_to_cpu(cnt.rxrunt) +
-		le32_to_cpu(cnt.rxgiant);
-	wstats->miss.beacon = 0;
-
-	WL_TRACE("wl_iw_get_wireless_stats counters txframe=%d txbyte=%d\n",
-		 le32_to_cpu(cnt.txframe), le32_to_cpu(cnt.txbyte));
-	WL_TRACE("wl_iw_get_wireless_stats counters rxfrmtoolong=%d\n",
-		  le32_to_cpu(cnt.rxfrmtoolong));
-	WL_TRACE("wl_iw_get_wireless_stats counters rxbadplcp=%d\n",
-		  le32_to_cpu(cnt.rxbadplcp));
-	WL_TRACE("wl_iw_get_wireless_stats counters rxundec=%d\n",
-		  le32_to_cpu(cnt.rxundec));
-	WL_TRACE("wl_iw_get_wireless_stats counters rxfragerr=%d\n",
-		  le32_to_cpu(cnt.rxfragerr));
-	WL_TRACE("wl_iw_get_wireless_stats counters txfail=%d\n",
-		  le32_to_cpu(cnt.txfail));
-	WL_TRACE("wl_iw_get_wireless_stats counters rxrunt=%d\n",
-		  le32_to_cpu(cnt.rxrunt));
-	WL_TRACE("wl_iw_get_wireless_stats counters rxgiant=%d\n",
-		  le32_to_cpu(cnt.rxgiant));
-#endif				/* WIRELESS_EXT > 11 */
-
-done:
-	return res;
-}
-
 int wl_iw_attach(struct net_device *dev, void *dhdp)
 {
 	int params_size;
@@ -3672,8 +3572,10 @@
 		return -ENOMEM;
 
 	iscan->iscan_ex_params_p = kmalloc(params_size, GFP_KERNEL);
-	if (!iscan->iscan_ex_params_p)
+	if (!iscan->iscan_ex_params_p) {
+		kfree(iscan);
 		return -ENOMEM;
+	}
 	iscan->iscan_ex_param_size = params_size;
 	iscan->sysioc_tsk = NULL;
 
@@ -3742,3 +3644,50 @@
 
 	g_scan = NULL;
 }
+
+#if defined(BCMDBG)
+void osl_assert(char *exp, char *file, int line)
+{
+	char tempbuf[256];
+	char *basename;
+
+	basename = strrchr(file, '/');
+	/* skip the '/' */
+	if (basename)
+		basename++;
+
+	if (!basename)
+		basename = file;
+
+	snprintf(tempbuf, 256,
+		 "assertion \"%s\" failed: file \"%s\", line %d\n", exp,
+		 basename, line);
+
+	/*
+	 * Print assert message and give it time to
+	 * be written to /var/log/messages
+	 */
+	if (!in_interrupt()) {
+		const int delay = 3;
+		printk(KERN_ERR "%s", tempbuf);
+		printk(KERN_ERR "panic in %d seconds\n", delay);
+		set_current_state(TASK_INTERRUPTIBLE);
+		schedule_timeout(delay * HZ);
+	}
+
+	switch (g_assert_type) {
+	case 0:
+		panic(KERN_ERR "%s", tempbuf);
+		break;
+	case 1:
+		printk(KERN_ERR "%s", tempbuf);
+		BUG();
+		break;
+	case 2:
+		printk(KERN_ERR "%s", tempbuf);
+		break;
+	default:
+		break;
+	}
+}
+#endif				/* defined(BCMDBG) */
diff -druN linux-2.6.39-libre/drivers/staging/brcm80211/brcmsmac/aiutils.c linux-3.0-rc7-libre/drivers/staging/brcm80211/brcmsmac/aiutils.c
--- linux-2.6.39-libre/drivers/staging/brcm80211/brcmsmac/aiutils.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/staging/brcm80211/brcmsmac/aiutils.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,2054 @@
+/*
+ * Copyright (c) 2010 Broadcom Corporation
+ *
+ * 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/delay.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <bcmdefs.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <bcmutils.h>
+#include <aiutils.h>
+#include <hndsoc.h>
+#include <sbchipc.h>
+#include <pcicfg.h>
+#include <bcmdevs.h>
+
+/* ********** from siutils.c *********** */
+#include <pci_core.h>
+#include <pcie_core.h>
+#include <nicpci.h>
+#include <bcmnvram.h>
+#include <bcmsrom.h>
+#include <wlc_pmu.h>
+
+#define BCM47162_DMP() ((sih->chip == BCM47162_CHIP_ID) && \
+		(sih->chiprev == 0) && \
+		(sii->coreid[sii->curidx] == MIPS74K_CORE_ID))
+
+/* EROM parsing */
+
+static u32
+get_erom_ent(si_t *sih, u32 **eromptr, u32 mask, u32 match)
+{
+	u32 ent;
+	uint inv = 0, nom = 0;
+
+	while (true) {
+		ent = R_REG(*eromptr);
+		(*eromptr)++;
+
+		if (mask == 0)
+			break;
+
+		if ((ent & ER_VALID) == 0) {
+			inv++;
+			continue;
+		}
+
+		if (ent == (ER_END | ER_VALID))
+			break;
+
+		if ((ent & mask) == match)
+			break;
+
+		nom++;
+	}
+
+	SI_VMSG(("%s: Returning ent 0x%08x\n", __func__, ent));
+	if (inv + nom) {
+		SI_VMSG(("  after %d invalid and %d non-matching entries\n",
+			 inv, nom));
+	}
+	return ent;
+}
+
+static u32
+get_asd(si_t *sih, u32 **eromptr, uint sp, uint ad, uint st,
+	u32 *addrl, u32 *addrh, u32 *sizel, u32 *sizeh)
+{
+	u32 asd, sz, szd;
+
+	asd = get_erom_ent(sih, eromptr, ER_VALID, ER_VALID);
+	if (((asd & ER_TAG1) != ER_ADD) ||
+	    (((asd & AD_SP_MASK) >> AD_SP_SHIFT) != sp) ||
+	    ((asd & AD_ST_MASK) != st)) {
+		/* This is not what we want, "push" it back */
+		(*eromptr)--;
+		return 0;
+	}
+	*addrl = asd & AD_ADDR_MASK;
+	if (asd & AD_AG32)
+		*addrh = get_erom_ent(sih, eromptr, 0, 0);
+	else
+		*addrh = 0;
+	*sizeh = 0;
+	sz = asd & AD_SZ_MASK;
+	if (sz == AD_SZ_SZD) {
+		szd = get_erom_ent(sih, eromptr, 0, 0);
+		*sizel = szd & SD_SZ_MASK;
+		if (szd & SD_SG32)
+			*sizeh = get_erom_ent(sih, eromptr, 0, 0);
+	} else
+		*sizel = AD_SZ_BASE << (sz >> AD_SZ_SHIFT);
+
+	SI_VMSG(("  SP %d, ad %d: st = %d, 0x%08x_0x%08x @ 0x%08x_0x%08x\n",
+		 sp, ad, st, *sizeh, *sizel, *addrh, *addrl));
+
+	return asd;
+}
+
+static void ai_hwfixup(si_info_t *sii)
+{
+}
+
+/* parse the enumeration rom to identify all cores */
+void ai_scan(si_t *sih, void *regs, uint devid)
+{
+	si_info_t *sii = SI_INFO(sih);
+	chipcregs_t *cc = (chipcregs_t *) regs;
+	u32 erombase, *eromptr, *eromlim;
+
+	erombase = R_REG(&cc->eromptr);
+
+	switch (sih->bustype) {
+	case SI_BUS:
+		eromptr = (u32 *) REG_MAP(erombase, SI_CORE_SIZE);
+		break;
+
+	case PCI_BUS:
+		/* Set wrappers address */
+		sii->curwrap = (void *)((unsigned long)regs + SI_CORE_SIZE);
+
+		/* Now point the window at the erom */
+		pci_write_config_dword(sii->pbus, PCI_BAR0_WIN, erombase);
+		eromptr = regs;
+		break;
+
+	case SPI_BUS:
+	case SDIO_BUS:
+		eromptr = (u32 *)(unsigned long)erombase;
+		break;
+
+	default:
+		SI_ERROR(("Don't know how to do AXI enumertion on bus %d\n",
+			  sih->bustype));
+		return;
+	}
+	eromlim = eromptr + (ER_REMAPCONTROL / sizeof(u32));
+
+	SI_VMSG(("ai_scan: regs = 0x%p, erombase = 0x%08x, eromptr = 0x%p, eromlim = 0x%p\n", regs, erombase, eromptr, eromlim));
+	while (eromptr < eromlim) {
+		u32 cia, cib, cid, mfg, crev, nmw, nsw, nmp, nsp;
+		u32 mpd, asd, addrl, addrh, sizel, sizeh;
+		u32 *base;
+		uint i, j, idx;
+		bool br;
+
+		br = false;
+
+		/* Grok a component */
+		cia = get_erom_ent(sih, &eromptr, ER_TAG, ER_CI);
+		if (cia == (ER_END | ER_VALID)) {
+			SI_VMSG(("Found END of erom after %d cores\n",
+				 sii->numcores));
+			ai_hwfixup(sii);
+			return;
+		}
+		base = eromptr - 1;
+		cib = get_erom_ent(sih, &eromptr, 0, 0);
+
+		if ((cib & ER_TAG) != ER_CI) {
+			SI_ERROR(("CIA not followed by CIB\n"));
+			goto error;
+		}
+
+		cid = (cia & CIA_CID_MASK) >> CIA_CID_SHIFT;
+		mfg = (cia & CIA_MFG_MASK) >> CIA_MFG_SHIFT;
+		crev = (cib & CIB_REV_MASK) >> CIB_REV_SHIFT;
+		nmw = (cib & CIB_NMW_MASK) >> CIB_NMW_SHIFT;
+		nsw = (cib & CIB_NSW_MASK) >> CIB_NSW_SHIFT;
+		nmp = (cib & CIB_NMP_MASK) >> CIB_NMP_SHIFT;
+		nsp = (cib & CIB_NSP_MASK) >> CIB_NSP_SHIFT;
+
+		SI_VMSG(("Found component 0x%04x/0x%04x rev %d at erom addr 0x%p, with nmw = %d, " "nsw = %d, nmp = %d & nsp = %d\n", mfg, cid, crev, base, nmw, nsw, nmp, nsp));
+
+		if (((mfg == MFGID_ARM) && (cid == DEF_AI_COMP)) || (nsp == 0))
+			continue;
+		if ((nmw + nsw == 0)) {
+			/* A component which is not a core */
+			if (cid == OOB_ROUTER_CORE_ID) {
+				asd = get_asd(sih, &eromptr, 0, 0, AD_ST_SLAVE,
+					      &addrl, &addrh, &sizel, &sizeh);
+				if (asd != 0) {
+					sii->oob_router = addrl;
+				}
+			}
+			continue;
+		}
+
+		idx = sii->numcores;
+/*		sii->eromptr[idx] = base; */
+		sii->cia[idx] = cia;
+		sii->cib[idx] = cib;
+		sii->coreid[idx] = cid;
+
+		for (i = 0; i < nmp; i++) {
+			mpd = get_erom_ent(sih, &eromptr, ER_VALID, ER_VALID);
+			if ((mpd & ER_TAG) != ER_MP) {
+				SI_ERROR(("Not enough MP entries for component 0x%x\n", cid));
+				goto error;
+			}
+			SI_VMSG(("  Master port %d, mp: %d id: %d\n", i,
+				 (mpd & MPD_MP_MASK) >> MPD_MP_SHIFT,
+				 (mpd & MPD_MUI_MASK) >> MPD_MUI_SHIFT));
+		}
+
+		/* First Slave Address Descriptor should be port 0:
+		 * the main register space for the core
+		 */
+		asd =
+		    get_asd(sih, &eromptr, 0, 0, AD_ST_SLAVE, &addrl, &addrh,
+			    &sizel, &sizeh);
+		if (asd == 0) {
+			/* Try again to see if it is a bridge */
+			asd =
+			    get_asd(sih, &eromptr, 0, 0, AD_ST_BRIDGE, &addrl,
+				    &addrh, &sizel, &sizeh);
+			if (asd != 0)
+				br = true;
+			else if ((addrh != 0) || (sizeh != 0)
+				 || (sizel != SI_CORE_SIZE)) {
+				SI_ERROR(("First Slave ASD for core 0x%04x malformed " "(0x%08x)\n", cid, asd));
+				goto error;
+			}
+		}
+		sii->coresba[idx] = addrl;
+		sii->coresba_size[idx] = sizel;
+		/* Get any more ASDs in port 0 */
+		j = 1;
+		do {
+			asd =
+			    get_asd(sih, &eromptr, 0, j, AD_ST_SLAVE, &addrl,
+				    &addrh, &sizel, &sizeh);
+			if ((asd != 0) && (j == 1) && (sizel == SI_CORE_SIZE)) {
+				sii->coresba2[idx] = addrl;
+				sii->coresba2_size[idx] = sizel;
+			}
+			j++;
+		} while (asd != 0);
+
+		/* Go through the ASDs for other slave ports */
+		for (i = 1; i < nsp; i++) {
+			j = 0;
+			do {
+				asd =
+				    get_asd(sih, &eromptr, i, j++, AD_ST_SLAVE,
+					    &addrl, &addrh, &sizel, &sizeh);
+			} while (asd != 0);
+			if (j == 0) {
+				SI_ERROR((" SP %d has no address descriptors\n",
+					  i));
+				goto error;
+			}
+		}
+
+		/* Now get master wrappers */
+		for (i = 0; i < nmw; i++) {
+			asd =
+			    get_asd(sih, &eromptr, i, 0, AD_ST_MWRAP, &addrl,
+				    &addrh, &sizel, &sizeh);
+			if (asd == 0) {
+				SI_ERROR(("Missing descriptor for MW %d\n", i));
+				goto error;
+			}
+			if ((sizeh != 0) || (sizel != SI_CORE_SIZE)) {
+				SI_ERROR(("Master wrapper %d is not 4KB\n", i));
+				goto error;
+			}
+			if (i == 0)
+				sii->wrapba[idx] = addrl;
+		}
+
+		/* And finally slave wrappers */
+		for (i = 0; i < nsw; i++) {
+			uint fwp = (nsp == 1) ? 0 : 1;
+			asd =
+			    get_asd(sih, &eromptr, fwp + i, 0, AD_ST_SWRAP,
+				    &addrl, &addrh, &sizel, &sizeh);
+			if (asd == 0) {
+				SI_ERROR(("Missing descriptor for SW %d\n", i));
+				goto error;
+			}
+			if ((sizeh != 0) || (sizel != SI_CORE_SIZE)) {
+				SI_ERROR(("Slave wrapper %d is not 4KB\n", i));
+				goto error;
+			}
+			if ((nmw == 0) && (i == 0))
+				sii->wrapba[idx] = addrl;
+		}
+
+		/* Don't record bridges */
+		if (br)
+			continue;
+
+		/* Done with core */
+		sii->numcores++;
+	}
+
+	SI_ERROR(("Reached end of erom without finding END"));
+
+ error:
+	sii->numcores = 0;
+	return;
+}
+
+/* This function changes the logical "focus" to the indicated core.
+ * Return the current core's virtual address.
+ */
+void *ai_setcoreidx(si_t *sih, uint coreidx)
+{
+	si_info_t *sii = SI_INFO(sih);
+	u32 addr = sii->coresba[coreidx];
+	u32 wrap = sii->wrapba[coreidx];
+	void *regs;
+
+	if (coreidx >= sii->numcores)
+		return NULL;
+
+	switch (sih->bustype) {
+	case SI_BUS:
+		/* map new one */
+		if (!sii->regs[coreidx]) {
+			sii->regs[coreidx] = REG_MAP(addr, SI_CORE_SIZE);
+		}
+		sii->curmap = regs = sii->regs[coreidx];
+		if (!sii->wrappers[coreidx]) {
+			sii->wrappers[coreidx] = REG_MAP(wrap, SI_CORE_SIZE);
+		}
+		sii->curwrap = sii->wrappers[coreidx];
+		break;
+
+	case PCI_BUS:
+		/* point bar0 window */
+		pci_write_config_dword(sii->pbus, PCI_BAR0_WIN, addr);
+		regs = sii->curmap;
+		/* point bar0 2nd 4KB window */
+		pci_write_config_dword(sii->pbus, PCI_BAR0_WIN2, wrap);
+		break;
+
+	case SPI_BUS:
+	case SDIO_BUS:
+		sii->curmap = regs = (void *)(unsigned long)addr;
+		sii->curwrap = (void *)(unsigned long)wrap;
+		break;
+
+	default:
+		regs = NULL;
+		break;
+	}
+
+	sii->curmap = regs;
+	sii->curidx = coreidx;
+
+	return regs;
+}
+
+/* Return the number of address spaces in current core */
+int ai_numaddrspaces(si_t *sih)
+{
+	return 2;
+}
+
+/* Return the address of the nth address space in the current core */
+u32 ai_addrspace(si_t *sih, uint asidx)
+{
+	si_info_t *sii;
+	uint cidx;
+
+	sii = SI_INFO(sih);
+	cidx = sii->curidx;
+
+	if (asidx == 0)
+		return sii->coresba[cidx];
+	else if (asidx == 1)
+		return sii->coresba2[cidx];
+	else {
+		SI_ERROR(("%s: Need to parse the erom again to find addr space %d\n", __func__, asidx));
+		return 0;
+	}
+}
+
+/* Return the size of the nth address space in the current core */
+u32 ai_addrspacesize(si_t *sih, uint asidx)
+{
+	si_info_t *sii;
+	uint cidx;
+
+	sii = SI_INFO(sih);
+	cidx = sii->curidx;
+
+	if (asidx == 0)
+		return sii->coresba_size[cidx];
+	else if (asidx == 1)
+		return sii->coresba2_size[cidx];
+	else {
+		SI_ERROR(("%s: Need to parse the erom again to find addr space %d\n", __func__, asidx));
+		return 0;
+	}
+}
+
+uint ai_flag(si_t *sih)
+{
+	si_info_t *sii;
+	aidmp_t *ai;
+
+	sii = SI_INFO(sih);
+	if (BCM47162_DMP()) {
+		SI_ERROR(("%s: Attempting to read MIPS DMP registers on 47162a0", __func__));
+		return sii->curidx;
+	}
+	ai = sii->curwrap;
+
+	return R_REG(&ai->oobselouta30) & 0x1f;
+}
+
+void ai_setint(si_t *sih, int siflag)
+{
+}
+
+uint ai_corevendor(si_t *sih)
+{
+	si_info_t *sii;
+	u32 cia;
+
+	sii = SI_INFO(sih);
+	cia = sii->cia[sii->curidx];
+	return (cia & CIA_MFG_MASK) >> CIA_MFG_SHIFT;
+}
+
+uint ai_corerev(si_t *sih)
+{
+	si_info_t *sii;
+	u32 cib;
+
+	sii = SI_INFO(sih);
+	cib = sii->cib[sii->curidx];
+	return (cib & CIB_REV_MASK) >> CIB_REV_SHIFT;
+}
+
+bool ai_iscoreup(si_t *sih)
+{
+	si_info_t *sii;
+	aidmp_t *ai;
+
+	sii = SI_INFO(sih);
+	ai = sii->curwrap;
+
+	return (((R_REG(&ai->ioctrl) & (SICF_FGC | SICF_CLOCK_EN)) ==
+		 SICF_CLOCK_EN)
+		&& ((R_REG(&ai->resetctrl) & AIRC_RESET) == 0));
+}
+
+void ai_core_cflags_wo(si_t *sih, u32 mask, u32 val)
+{
+	si_info_t *sii;
+	aidmp_t *ai;
+	u32 w;
+
+	sii = SI_INFO(sih);
+
+	if (BCM47162_DMP()) {
+		SI_ERROR(("%s: Accessing MIPS DMP register (ioctrl) on 47162a0",
+			  __func__));
+		return;
+	}
+
+	ai = sii->curwrap;
+
+	if (mask || val) {
+		w = ((R_REG(&ai->ioctrl) & ~mask) | val);
+		W_REG(&ai->ioctrl, w);
+	}
+}
+
+u32 ai_core_cflags(si_t *sih, u32 mask, u32 val)
+{
+	si_info_t *sii;
+	aidmp_t *ai;
+	u32 w;
+
+	sii = SI_INFO(sih);
+	if (BCM47162_DMP()) {
+		SI_ERROR(("%s: Accessing MIPS DMP register (ioctrl) on 47162a0",
+			  __func__));
+		return 0;
+	}
+
+	ai = sii->curwrap;
+
+	if (mask || val) {
+		w = ((R_REG(&ai->ioctrl) & ~mask) | val);
+		W_REG(&ai->ioctrl, w);
+	}
+
+	return R_REG(&ai->ioctrl);
+}
+
+u32 ai_core_sflags(si_t *sih, u32 mask, u32 val)
+{
+	si_info_t *sii;
+	aidmp_t *ai;
+	u32 w;
+
+	sii = SI_INFO(sih);
+	if (BCM47162_DMP()) {
+		SI_ERROR(("%s: Accessing MIPS DMP register (iostatus) on 47162a0", __func__));
+		return 0;
+	}
+
+	ai = sii->curwrap;
+
+	if (mask || val) {
+		w = ((R_REG(&ai->iostatus) & ~mask) | val);
+		W_REG(&ai->iostatus, w);
+	}
+
+	return R_REG(&ai->iostatus);
+}
+
+/* *************** from siutils.c ************** */
+/* local prototypes */
+static si_info_t *ai_doattach(si_info_t *sii, uint devid, void *regs,
+			      uint bustype, void *sdh, char **vars,
+			      uint *varsz);
+static bool ai_buscore_prep(si_info_t *sii, uint bustype, uint devid,
+			    void *sdh);
+static bool ai_buscore_setup(si_info_t *sii, chipcregs_t *cc, uint bustype,
+			     u32 savewin, uint *origidx, void *regs);
+static void ai_nvram_process(si_info_t *sii, char *pvars);
+
+/* dev path concatenation util */
+static char *ai_devpathvar(si_t *sih, char *var, int len, const char *name);
+static bool _ai_clkctl_cc(si_info_t *sii, uint mode);
+static bool ai_ispcie(si_info_t *sii);
+
+/* global variable to indicate reservation/release of gpio's */
+static u32 ai_gpioreservation;
+
+/*
+ * Allocate a si handle.
+ * devid - pci device id (used to determine chip#)
+ * osh - opaque OS handle
+ * regs - virtual address of initial core registers
+ * bustype - pci/sb/sdio/etc
+ * vars - pointer to a pointer area for "environment" variables
+ * varsz - pointer to int to return the size of the vars
+ */
+si_t *ai_attach(uint devid, void *regs, uint bustype,
+		void *sdh, char **vars, uint *varsz)
+{
+	si_info_t *sii;
+
+	/* alloc si_info_t */
+	sii = kmalloc(sizeof(si_info_t), GFP_ATOMIC);
+	if (sii == NULL) {
+		SI_ERROR(("si_attach: malloc failed!\n"));
+		return NULL;
+	}
+
+	if (ai_doattach(sii, devid, regs, bustype, sdh, vars, varsz) ==
+	    NULL) {
+		kfree(sii);
+		return NULL;
+	}
+	sii->vars = vars ? *vars : NULL;
+	sii->varsz = varsz ? *varsz : 0;
+
+	return (si_t *) sii;
+}
+
+/* global kernel resource */
+static si_info_t ksii;
+
+static bool ai_buscore_prep(si_info_t *sii, uint bustype, uint devid,
+			    void *sdh)
+{
+	/* kludge to enable the clock on the 4306 which lacks a slowclock */
+	if (bustype == PCI_BUS && !ai_ispcie(sii))
+		ai_clkctl_xtal(&sii->pub, XTAL | PLL, ON);
+	return true;
+}
+
+static bool ai_buscore_setup(si_info_t *sii, chipcregs_t *cc, uint bustype,
+			     u32 savewin, uint *origidx, void *regs)
+{
+	bool pci, pcie;
+	uint i;
+	uint pciidx, pcieidx, pcirev, pcierev;
+
+	cc = ai_setcoreidx(&sii->pub, SI_CC_IDX);
+
+	/* get chipcommon rev */
+	sii->pub.ccrev = (int)ai_corerev(&sii->pub);
+
+	/* get chipcommon chipstatus */
+	if (sii->pub.ccrev >= 11)
+		sii->pub.chipst = R_REG(&cc->chipstatus);
+
+	/* get chipcommon capabilites */
+	sii->pub.cccaps = R_REG(&cc->capabilities);
+	/* get chipcommon extended capabilities */
+
+	if (sii->pub.ccrev >= 35)
+		sii->pub.cccaps_ext = R_REG(&cc->capabilities_ext);
+
+	/* get pmu rev and caps */
+	if (sii->pub.cccaps & CC_CAP_PMU) {
+		sii->pub.pmucaps = R_REG(&cc->pmucapabilities);
+		sii->pub.pmurev = sii->pub.pmucaps & PCAP_REV_MASK;
+	}
+
+	/* figure out bus/orignal core idx */
+	sii->pub.buscoretype = NODEV_CORE_ID;
+	sii->pub.buscorerev = NOREV;
+	sii->pub.buscoreidx = BADIDX;
+
+	pci = pcie = false;
+	pcirev = pcierev = NOREV;
+	pciidx = pcieidx = BADIDX;
+
+	for (i = 0; i < sii->numcores; i++) {
+		uint cid, crev;
+
+		ai_setcoreidx(&sii->pub, i);
+		cid = ai_coreid(&sii->pub);
+		crev = ai_corerev(&sii->pub);
+
+		/* Display cores found */
+		SI_VMSG(("CORE[%d]: id 0x%x rev %d base 0x%x regs 0x%p\n",
+			 i, cid, crev, sii->coresba[i], sii->regs[i]));
+
+		if (bustype == PCI_BUS) {
+			if (cid == PCI_CORE_ID) {
+				pciidx = i;
+				pcirev = crev;
+				pci = true;
+			} else if (cid == PCIE_CORE_ID) {
+				pcieidx = i;
+				pcierev = crev;
+				pcie = true;
+			}
+		}
+
+		/* find the core idx before entering this func. */
+		if ((savewin && (savewin == sii->coresba[i])) ||
+		    (regs == sii->regs[i]))
+			*origidx = i;
+	}
+
+	if (pci && pcie) {
+		if (ai_ispcie(sii))
+			pci = false;
+		else
+			pcie = false;
+	}
+	if (pci) {
+		sii->pub.buscoretype = PCI_CORE_ID;
+		sii->pub.buscorerev = pcirev;
+		sii->pub.buscoreidx = pciidx;
+	} else if (pcie) {
+		sii->pub.buscoretype = PCIE_CORE_ID;
+		sii->pub.buscorerev = pcierev;
+		sii->pub.buscoreidx = pcieidx;
+	}
+
+	SI_VMSG(("Buscore id/type/rev %d/0x%x/%d\n", sii->pub.buscoreidx,
+		 sii->pub.buscoretype, sii->pub.buscorerev));
+
+	/* fixup necessary chip/core configurations */
+	if (sii->pub.bustype == PCI_BUS) {
+		if (SI_FAST(sii)) {
+			if (!sii->pch) {
+				sii->pch = (void *)pcicore_init(
+					&sii->pub, sii->pbus,
+					(void *)PCIEREGS(sii));
+				if (sii->pch == NULL)
+					return false;
+			}
+		}
+		if (ai_pci_fixcfg(&sii->pub)) {
+			SI_ERROR(("si_doattach: si_pci_fixcfg failed\n"));
+			return false;
+		}
+	}
+
+	/* return to the original core */
+	ai_setcoreidx(&sii->pub, *origidx);
+
+	return true;
+}
+
+static __used void ai_nvram_process(si_info_t *sii, char *pvars)
+{
+	uint w = 0;
+
+	/* get boardtype and boardrev */
+	switch (sii->pub.bustype) {
+	case PCI_BUS:
+		/* do a pci config read to get subsystem id and subvendor id */
+		pci_read_config_dword(sii->pbus, PCI_SUBSYSTEM_VENDOR_ID, &w);
+		/* Let nvram variables override subsystem Vend/ID */
+		sii->pub.boardvendor = (u16)ai_getdevpathintvar(&sii->pub,
+			"boardvendor");
+		if (sii->pub.boardvendor == 0)
+			sii->pub.boardvendor = w & 0xffff;
+		else
+			SI_ERROR(("Overriding boardvendor: 0x%x instead of "
+				  "0x%x\n", sii->pub.boardvendor, w & 0xffff));
+		sii->pub.boardtype = (u16)ai_getdevpathintvar(&sii->pub,
+			"boardtype");
+		if (sii->pub.boardtype == 0)
+			sii->pub.boardtype = (w >> 16) & 0xffff;
+		else
+			SI_ERROR(("Overriding boardtype: 0x%x instead of 0x%x\n"
+				  , sii->pub.boardtype, (w >> 16) & 0xffff));
+		break;
+
+		sii->pub.boardvendor = getintvar(pvars, "manfid");
+		sii->pub.boardtype = getintvar(pvars, "prodid");
+		break;
+
+	case SI_BUS:
+	case JTAG_BUS:
+		sii->pub.boardvendor = PCI_VENDOR_ID_BROADCOM;
+		sii->pub.boardtype = getintvar(pvars, "prodid");
+		if (pvars == NULL || (sii->pub.boardtype == 0)) {
+			sii->pub.boardtype = getintvar(NULL, "boardtype");
+			if (sii->pub.boardtype == 0)
+				sii->pub.boardtype = 0xffff;
+		}
+		break;
+	}
+
+	if (sii->pub.boardtype == 0) {
+		SI_ERROR(("si_doattach: unknown board type\n"));
+	}
+
+	sii->pub.boardflags = getintvar(pvars, "boardflags");
+}
+
+static si_info_t *ai_doattach(si_info_t *sii, uint devid,
+			      void *regs, uint bustype, void *pbus,
+			      char **vars, uint *varsz)
+{
+	struct si_pub *sih = &sii->pub;
+	u32 w, savewin;
+	chipcregs_t *cc;
+	char *pvars = NULL;
+	uint socitype;
+	uint origidx;
+
+	memset((unsigned char *) sii, 0, sizeof(si_info_t));
+
+	savewin = 0;
+
+	sih->buscoreidx = BADIDX;
+
+	sii->curmap = regs;
+	sii->pbus = pbus;
+
+	/* check to see if we are a si core mimic'ing a pci core */
+	if (bustype == PCI_BUS) {
+		pci_read_config_dword(sii->pbus, PCI_SPROM_CONTROL,  &w);
+		if (w == 0xffffffff) {
+			SI_ERROR(("%s: incoming bus is PCI but it's a lie, "
+				" switching to SI devid:0x%x\n",
+				__func__, devid));
+			bustype = SI_BUS;
+		}
+	}
+
+	/* find Chipcommon address */
+	if (bustype == PCI_BUS) {
+		pci_read_config_dword(sii->pbus, PCI_BAR0_WIN, &savewin);
+		if (!GOODCOREADDR(savewin, SI_ENUM_BASE))
+			savewin = SI_ENUM_BASE;
+		pci_write_config_dword(sii->pbus, PCI_BAR0_WIN,
+				       SI_ENUM_BASE);
+		cc = (chipcregs_t *) regs;
+	} else {
+		cc = (chipcregs_t *) REG_MAP(SI_ENUM_BASE, SI_CORE_SIZE);
+	}
+
+	sih->bustype = bustype;
+
+	/* bus/core/clk setup for register access */
+	if (!ai_buscore_prep(sii, bustype, devid, pbus)) {
+		SI_ERROR(("si_doattach: si_core_clk_prep failed %d\n",
+			  bustype));
+		return NULL;
+	}
+
+	/*
+	 * ChipID recognition.
+	 *   We assume we can read chipid at offset 0 from the regs arg.
+	 *   If we add other chiptypes (or if we need to support old sdio
+	 *   hosts w/o chipcommon), some way of recognizing them needs to
+	 *   be added here.
+	 */
+	w = R_REG(&cc->chipid);
+	socitype = (w & CID_TYPE_MASK) >> CID_TYPE_SHIFT;
+	/* Might as wll fill in chip id rev & pkg */
+	sih->chip = w & CID_ID_MASK;
+	sih->chiprev = (w & CID_REV_MASK) >> CID_REV_SHIFT;
+	sih->chippkg = (w & CID_PKG_MASK) >> CID_PKG_SHIFT;
+
+	sih->issim = IS_SIM(sih->chippkg);
+
+	/* scan for cores */
+	if (socitype == SOCI_AI) {
+		SI_MSG(("Found chip type AI (0x%08x)\n", w));
+		/* pass chipc address instead of original core base */
+		ai_scan(&sii->pub, (void *)cc, devid);
+	} else {
+		SI_ERROR(("Found chip of unknown type (0x%08x)\n", w));
+		return NULL;
+	}
+	/* no cores found, bail out */
+	if (sii->numcores == 0) {
+		SI_ERROR(("si_doattach: could not find any cores\n"));
+		return NULL;
+	}
+	/* bus/core/clk setup */
+	origidx = SI_CC_IDX;
+	if (!ai_buscore_setup(sii, cc, bustype, savewin, &origidx, regs)) {
+		SI_ERROR(("si_doattach: si_buscore_setup failed\n"));
+		goto exit;
+	}
+
+	/* assume current core is CC */
+	if ((sii->pub.ccrev == 0x25)
+	    &&
+	    ((sih->chip == BCM43236_CHIP_ID
+	      || sih->chip == BCM43235_CHIP_ID
+	      || sih->chip == BCM43238_CHIP_ID)
+	     && (sii->pub.chiprev <= 2))) {
+
+		if ((cc->chipstatus & CST43236_BP_CLK) != 0) {
+			uint clkdiv;
+			clkdiv = R_REG(&cc->clkdiv);
+			/* otp_clk_div is even number, 120/14 < 9mhz */
+			clkdiv = (clkdiv & ~CLKD_OTP) | (14 << CLKD_OTP_SHIFT);
+			W_REG(&cc->clkdiv, clkdiv);
+			SI_ERROR(("%s: set clkdiv to %x\n", __func__, clkdiv));
+		}
+		udelay(10);
+	}
+
+	/* Init nvram from flash if it exists */
+	nvram_init();
+
+	/* Init nvram from sprom/otp if they exist */
+	if (srom_var_init
+	    (&sii->pub, bustype, regs, vars, varsz)) {
+		SI_ERROR(("si_doattach: srom_var_init failed: bad srom\n"));
+		goto exit;
+	}
+	pvars = vars ? *vars : NULL;
+	ai_nvram_process(sii, pvars);
+
+	/* === NVRAM, clock is ready === */
+	cc = (chipcregs_t *) ai_setcore(sih, CC_CORE_ID, 0);
+	W_REG(&cc->gpiopullup, 0);
+	W_REG(&cc->gpiopulldown, 0);
+	ai_setcoreidx(sih, origidx);
+
+	/* PMU specific initializations */
+	if (PMUCTL_ENAB(sih)) {
+		u32 xtalfreq;
+		si_pmu_init(sih);
+		si_pmu_chip_init(sih);
+		xtalfreq = getintvar(pvars, "xtalfreq");
+		/* If xtalfreq var not available, try to measure it */
+		if (xtalfreq == 0)
+			xtalfreq = si_pmu_measure_alpclk(sih);
+		si_pmu_pll_init(sih, xtalfreq);
+		si_pmu_res_init(sih);
+		si_pmu_swreg_init(sih);
+	}
+
+	/* setup the GPIO based LED powersave register */
+	w = getintvar(pvars, "leddc");
+	if (w == 0)
+		w = DEFAULT_GPIOTIMERVAL;
+	ai_corereg(sih, SI_CC_IDX, offsetof(chipcregs_t, gpiotimerval), ~0, w);
+
+	if (PCIE(sii)) {
+		pcicore_attach(sii->pch, pvars, SI_DOATTACH);
+	}
+
+	if ((sih->chip == BCM43224_CHIP_ID) ||
+	    (sih->chip == BCM43421_CHIP_ID)) {
+		/*
+		 * enable 12 mA drive strenth for 43224 and
+		 * set chipControl register bit 15
+		 */
+		if (sih->chiprev == 0) {
+			SI_MSG(("Applying 43224A0 WARs\n"));
+			ai_corereg(sih, SI_CC_IDX,
+				   offsetof(chipcregs_t, chipcontrol),
+				   CCTRL43224_GPIO_TOGGLE,
+				   CCTRL43224_GPIO_TOGGLE);
+			si_pmu_chipcontrol(sih, 0, CCTRL_43224A0_12MA_LED_DRIVE,
+					   CCTRL_43224A0_12MA_LED_DRIVE);
+		}
+		if (sih->chiprev >= 1) {
+			SI_MSG(("Applying 43224B0+ WARs\n"));
+			si_pmu_chipcontrol(sih, 0, CCTRL_43224B0_12MA_LED_DRIVE,
+					   CCTRL_43224B0_12MA_LED_DRIVE);
+		}
+	}
+
+	if (sih->chip == BCM4313_CHIP_ID) {
+		/*
+		 * enable 12 mA drive strenth for 4313 and
+		 * set chipControl register bit 1
+		 */
+		SI_MSG(("Applying 4313 WARs\n"));
+		si_pmu_chipcontrol(sih, 0, CCTRL_4313_12MA_LED_DRIVE,
+				   CCTRL_4313_12MA_LED_DRIVE);
+	}
+
+	if (sih->chip == BCM4331_CHIP_ID) {
+		/* Enable Ext PA lines depending on chip package option */
+		ai_chipcontrl_epa4331(sih, true);
+	}
+
+	return sii;
+ exit:
+	if (sih->bustype == PCI_BUS) {
+		if (sii->pch)
+			pcicore_deinit(sii->pch);
+		sii->pch = NULL;
+	}
+
+	return NULL;
+}
+
+/* may be called with core in reset */
+void ai_detach(si_t *sih)
+{
+	si_info_t *sii;
+	uint idx;
+
+	struct si_pub *si_local = NULL;
+	bcopy(&sih, &si_local, sizeof(si_t **));
+
+	sii = SI_INFO(sih);
+
+	if (sii == NULL)
+		return;
+
+	if (sih->bustype == SI_BUS)
+		for (idx = 0; idx < SI_MAXCORES; idx++)
+			if (sii->regs[idx]) {
+				iounmap(sii->regs[idx]);
+				sii->regs[idx] = NULL;
+			}
+
+	nvram_exit();	/* free up nvram buffers */
+
+	if (sih->bustype == PCI_BUS) {
+		if (sii->pch)
+			pcicore_deinit(sii->pch);
+		sii->pch = NULL;
+	}
+
+	if (sii != &ksii)
+		kfree(sii);
+}
+
+/* register driver interrupt disabling and restoring callback functions */
+void
+ai_register_intr_callback(si_t *sih, void *intrsoff_fn, void *intrsrestore_fn,
+			  void *intrsenabled_fn, void *intr_arg)
+{
+	si_info_t *sii;
+
+	sii = SI_INFO(sih);
+	sii->intr_arg = intr_arg;
+	sii->intrsoff_fn = (si_intrsoff_t) intrsoff_fn;
+	sii->intrsrestore_fn = (si_intrsrestore_t) intrsrestore_fn;
+	sii->intrsenabled_fn = (si_intrsenabled_t) intrsenabled_fn;
+	/* save current core id.  when this function called, the current core
+	 * must be the core which provides driver functions(il, et, wl, etc.)
+	 */
+	sii->dev_coreid = sii->coreid[sii->curidx];
+}
+
+void ai_deregister_intr_callback(si_t *sih)
+{
+	si_info_t *sii;
+
+	sii = SI_INFO(sih);
+	sii->intrsoff_fn = NULL;
+}
+
+uint ai_coreid(si_t *sih)
+{
+	si_info_t *sii;
+
+	sii = SI_INFO(sih);
+	return sii->coreid[sii->curidx];
+}
+
+uint ai_coreidx(si_t *sih)
+{
+	si_info_t *sii;
+
+	sii = SI_INFO(sih);
+	return sii->curidx;
+}
+
+bool ai_backplane64(si_t *sih)
+{
+	return (sih->cccaps & CC_CAP_BKPLN64) != 0;
+}
+
+/* return index of coreid or BADIDX if not found */
+uint ai_findcoreidx(si_t *sih, uint coreid, uint coreunit)
+{
+	si_info_t *sii;
+	uint found;
+	uint i;
+
+	sii = SI_INFO(sih);
+
+	found = 0;
+
+	for (i = 0; i < sii->numcores; i++)
+		if (sii->coreid[i] == coreid) {
+			if (found == coreunit)
+				return i;
+			found++;
+		}
+
+	return BADIDX;
+}
+
+/*
+ * This function changes logical "focus" to the indicated core;
+ * must be called with interrupts off.
+ * Moreover, callers should keep interrupts off during switching
+ * out of and back to d11 core.
+ */
+void *ai_setcore(si_t *sih, uint coreid, uint coreunit)
+{
+	uint idx;
+
+	idx = ai_findcoreidx(sih, coreid, coreunit);
+	if (!GOODIDX(idx))
+		return NULL;
+
+	return ai_setcoreidx(sih, idx);
+}
+
+/* Turn off interrupt as required by ai_setcore, before switch core */
+void *ai_switch_core(si_t *sih, uint coreid, uint *origidx, uint *intr_val)
+{
+	void *cc;
+	si_info_t *sii;
+
+	sii = SI_INFO(sih);
+
+	if (SI_FAST(sii)) {
+		/* Overloading the origidx variable to remember the coreid,
+		 * this works because the core ids cannot be confused with
+		 * core indices.
+		 */
+		*origidx = coreid;
+		if (coreid == CC_CORE_ID)
+			return (void *)CCREGS_FAST(sii);
+		else if (coreid == sih->buscoretype)
+			return (void *)PCIEREGS(sii);
+	}
+	INTR_OFF(sii, *intr_val);
+	*origidx = sii->curidx;
+	cc = ai_setcore(sih, coreid, 0);
+	return cc;
+}
+
+/* restore coreidx and restore interrupt */
+void ai_restore_core(si_t *sih, uint coreid, uint intr_val)
+{
+	si_info_t *sii;
+
+	sii = SI_INFO(sih);
+	if (SI_FAST(sii)
+	    && ((coreid == CC_CORE_ID) || (coreid == sih->buscoretype)))
+		return;
+
+	ai_setcoreidx(sih, coreid);
+	INTR_RESTORE(sii, intr_val);
+}
+
+void ai_write_wrapperreg(si_t *sih, u32 offset, u32 val)
+{
+	si_info_t *sii = SI_INFO(sih);
+	u32 *w = (u32 *) sii->curwrap;
+	W_REG(w + (offset / 4), val);
+	return;
+}
+
+/*
+ * Switch to 'coreidx', issue a single arbitrary 32bit register mask&set
+ * operation, switch back to the original core, and return the new value.
+ *
+ * When using the silicon backplane, no fiddling with interrupts or core
+ * switches is needed.
+ *
+ * Also, when using pci/pcie, we can optimize away the core switching for pci
+ * registers and (on newer pci cores) chipcommon registers.
+ */
+uint ai_corereg(si_t *sih, uint coreidx, uint regoff, uint mask, uint val)
+{
+	uint origidx = 0;
+	u32 *r = NULL;
+	uint w;
+	uint intr_val = 0;
+	bool fast = false;
+	si_info_t *sii;
+
+	sii = SI_INFO(sih);
+
+	if (coreidx >= SI_MAXCORES)
+		return 0;
+
+	if (sih->bustype == SI_BUS) {
+		/* If internal bus, we can always get at everything */
+		fast = true;
+		/* map if does not exist */
+		if (!sii->regs[coreidx]) {
+			sii->regs[coreidx] = REG_MAP(sii->coresba[coreidx],
+						     SI_CORE_SIZE);
+		}
+		r = (u32 *) ((unsigned char *) sii->regs[coreidx] + regoff);
+	} else if (sih->bustype == PCI_BUS) {
+		/*
+		 * If pci/pcie, we can get at pci/pcie regs
+		 * and on newer cores to chipc
+		 */
+		if ((sii->coreid[coreidx] == CC_CORE_ID) && SI_FAST(sii)) {
+			/* Chipc registers are mapped at 12KB */
+
+			fast = true;
+			r = (u32 *) ((char *)sii->curmap +
+					PCI_16KB0_CCREGS_OFFSET + regoff);
+		} else if (sii->pub.buscoreidx == coreidx) {
+			/*
+			 * pci registers are at either in the last 2KB of
+			 * an 8KB window or, in pcie and pci rev 13 at 8KB
+			 */
+			fast = true;
+			if (SI_FAST(sii))
+				r = (u32 *) ((char *)sii->curmap +
+						PCI_16KB0_PCIREGS_OFFSET +
+						regoff);
+			else
+				r = (u32 *) ((char *)sii->curmap +
+						((regoff >= SBCONFIGOFF) ?
+						 PCI_BAR0_PCISBR_OFFSET :
+						 PCI_BAR0_PCIREGS_OFFSET) +
+						regoff);
+		}
+	}
+
+	if (!fast) {
+		INTR_OFF(sii, intr_val);
+
+		/* save current core index */
+		origidx = ai_coreidx(&sii->pub);
+
+		/* switch core */
+		r = (u32 *) ((unsigned char *) ai_setcoreidx(&sii->pub, coreidx)
+				+ regoff);
+	}
+
+	/* mask and set */
+	if (mask || val) {
+		w = (R_REG(r) & ~mask) | val;
+		W_REG(r, w);
+	}
+
+	/* readback */
+	w = R_REG(r);
+
+	if (!fast) {
+		/* restore core index */
+		if (origidx != coreidx)
+			ai_setcoreidx(&sii->pub, origidx);
+
+		INTR_RESTORE(sii, intr_val);
+	}
+
+	return w;
+}
+
+void ai_core_disable(si_t *sih, u32 bits)
+{
+	si_info_t *sii;
+	u32 dummy;
+	aidmp_t *ai;
+
+	sii = SI_INFO(sih);
+
+	ai = sii->curwrap;
+
+	/* if core is already in reset, just return */
+	if (R_REG(&ai->resetctrl) & AIRC_RESET)
+		return;
+
+	W_REG(&ai->ioctrl, bits);
+	dummy = R_REG(&ai->ioctrl);
+	udelay(10);
+
+	W_REG(&ai->resetctrl, AIRC_RESET);
+	udelay(1);
+}
+
+/* reset and re-enable a core
+ * inputs:
+ * bits - core specific bits that are set during and after reset sequence
+ * resetbits - core specific bits that are set only during reset sequence
+ */
+void ai_core_reset(si_t *sih, u32 bits, u32 resetbits)
+{
+	si_info_t *sii;
+	aidmp_t *ai;
+	u32 dummy;
+
+	sii = SI_INFO(sih);
+	ai = sii->curwrap;
+
+	/*
+	 * Must do the disable sequence first to work
+	 * for arbitrary current core state.
+	 */
+	ai_core_disable(sih, (bits | resetbits));
+
+	/*
+	 * Now do the initialization sequence.
+	 */
+	W_REG(&ai->ioctrl, (bits | SICF_FGC | SICF_CLOCK_EN));
+	dummy = R_REG(&ai->ioctrl);
+	W_REG(&ai->resetctrl, 0);
+	udelay(1);
+
+	W_REG(&ai->ioctrl, (bits | SICF_CLOCK_EN));
+	dummy = R_REG(&ai->ioctrl);
+	udelay(1);
+}
+
+/* return the slow clock source - LPO, XTAL, or PCI */
+static uint ai_slowclk_src(si_info_t *sii)
+{
+	chipcregs_t *cc;
+	u32 val;
+
+	if (sii->pub.ccrev < 6) {
+		if (sii->pub.bustype == PCI_BUS) {
+			pci_read_config_dword(sii->pbus, PCI_GPIO_OUT,
+					      &val);
+			if (val & PCI_CFG_GPIO_SCS)
+				return SCC_SS_PCI;
+		}
+		return SCC_SS_XTAL;
+	} else if (sii->pub.ccrev < 10) {
+		cc = (chipcregs_t *) ai_setcoreidx(&sii->pub, sii->curidx);
+		return R_REG(&cc->slow_clk_ctl) & SCC_SS_MASK;
+	} else			/* Insta-clock */
+		return SCC_SS_XTAL;
+}
+
+/*
+* return the ILP (slowclock) min or max frequency
+* precondition: we've established the chip has dynamic clk control
+*/
+static uint ai_slowclk_freq(si_info_t *sii, bool max_freq, chipcregs_t *cc)
+{
+	u32 slowclk;
+	uint div;
+
+	slowclk = ai_slowclk_src(sii);
+	if (sii->pub.ccrev < 6) {
+		if (slowclk == SCC_SS_PCI)
+			return max_freq ? (PCIMAXFREQ / 64)
+				: (PCIMINFREQ / 64);
+		else
+			return max_freq ? (XTALMAXFREQ / 32)
+				: (XTALMINFREQ / 32);
+	} else if (sii->pub.ccrev < 10) {
+		div = 4 *
+		    (((R_REG(&cc->slow_clk_ctl) & SCC_CD_MASK) >>
+		      SCC_CD_SHIFT) + 1);
+		if (slowclk == SCC_SS_LPO)
+			return max_freq ? LPOMAXFREQ : LPOMINFREQ;
+		else if (slowclk == SCC_SS_XTAL)
+			return max_freq ? (XTALMAXFREQ / div)
+				: (XTALMINFREQ / div);
+		else if (slowclk == SCC_SS_PCI)
+			return max_freq ? (PCIMAXFREQ / div)
+				: (PCIMINFREQ / div);
+	} else {
+		/* Chipc rev 10 is InstaClock */
+		div = R_REG(&cc->system_clk_ctl) >> SYCC_CD_SHIFT;
+		div = 4 * (div + 1);
+		return max_freq ? XTALMAXFREQ : (XTALMINFREQ / div);
+	}
+	return 0;
+}
+
+static void ai_clkctl_setdelay(si_info_t *sii, void *chipcregs)
+{
+	chipcregs_t *cc = (chipcregs_t *) chipcregs;
+	uint slowmaxfreq, pll_delay, slowclk;
+	uint pll_on_delay, fref_sel_delay;
+
+	pll_delay = PLL_DELAY;
+
+	/*
+	 * If the slow clock is not sourced by the xtal then
+	 * add the xtal_on_delay since the xtal will also be
+	 * powered down by dynamic clk control logic.
+	 */
+
+	slowclk = ai_slowclk_src(sii);
+	if (slowclk != SCC_SS_XTAL)
+		pll_delay += XTAL_ON_DELAY;
+
+	/* Starting with 4318 it is ILP that is used for the delays */
+	slowmaxfreq =
+	    ai_slowclk_freq(sii, (sii->pub.ccrev >= 10) ? false : true, cc);
+
+	pll_on_delay = ((slowmaxfreq * pll_delay) + 999999) / 1000000;
+	fref_sel_delay = ((slowmaxfreq * FREF_DELAY) + 999999) / 1000000;
+
+	W_REG(&cc->pll_on_delay, pll_on_delay);
+	W_REG(&cc->fref_sel_delay, fref_sel_delay);
+}
+
+/* initialize power control delay registers */
+void ai_clkctl_init(si_t *sih)
+{
+	si_info_t *sii;
+	uint origidx = 0;
+	chipcregs_t *cc;
+	bool fast;
+
+	if (!CCCTL_ENAB(sih))
+		return;
+
+	sii = SI_INFO(sih);
+	fast = SI_FAST(sii);
+	if (!fast) {
+		origidx = sii->curidx;
+		cc = (chipcregs_t *) ai_setcore(sih, CC_CORE_ID, 0);
+		if (cc == NULL)
+			return;
+	} else {
+		cc = (chipcregs_t *) CCREGS_FAST(sii);
+		if (cc == NULL)
+			return;
+	}
+
+	/* set all Instaclk chip ILP to 1 MHz */
+	if (sih->ccrev >= 10)
+		SET_REG(&cc->system_clk_ctl, SYCC_CD_MASK,
+			(ILP_DIV_1MHZ << SYCC_CD_SHIFT));
+
+	ai_clkctl_setdelay(sii, (void *)cc);
+
+	if (!fast)
+		ai_setcoreidx(sih, origidx);
+}
+
+/*
+ * return the value suitable for writing to the
+ * dot11 core FAST_PWRUP_DELAY register
+ */
+u16 ai_clkctl_fast_pwrup_delay(si_t *sih)
+{
+	si_info_t *sii;
+	uint origidx = 0;
+	chipcregs_t *cc;
+	uint slowminfreq;
+	u16 fpdelay;
+	uint intr_val = 0;
+	bool fast;
+
+	sii = SI_INFO(sih);
+	if (PMUCTL_ENAB(sih)) {
+		INTR_OFF(sii, intr_val);
+		fpdelay = si_pmu_fast_pwrup_delay(sih);
+		INTR_RESTORE(sii, intr_val);
+		return fpdelay;
+	}
+
+	if (!CCCTL_ENAB(sih))
+		return 0;
+
+	fast = SI_FAST(sii);
+	fpdelay = 0;
+	if (!fast) {
+		origidx = sii->curidx;
+		INTR_OFF(sii, intr_val);
+		cc = (chipcregs_t *) ai_setcore(sih, CC_CORE_ID, 0);
+		if (cc == NULL)
+			goto done;
+	} else {
+		cc = (chipcregs_t *) CCREGS_FAST(sii);
+		if (cc == NULL)
+			goto done;
+	}
+
+	slowminfreq = ai_slowclk_freq(sii, false, cc);
+	fpdelay = (((R_REG(&cc->pll_on_delay) + 2) * 1000000) +
+		   (slowminfreq - 1)) / slowminfreq;
+
+ done:
+	if (!fast) {
+		ai_setcoreidx(sih, origidx);
+		INTR_RESTORE(sii, intr_val);
+	}
+	return fpdelay;
+}
+
+/* turn primary xtal and/or pll off/on */
+int ai_clkctl_xtal(si_t *sih, uint what, bool on)
+{
+	si_info_t *sii;
+	u32 in, out, outen;
+
+	sii = SI_INFO(sih);
+
+	switch (sih->bustype) {
+
+	case PCI_BUS:
+		/* pcie core doesn't have any mapping to control the xtal pu */
+		if (PCIE(sii))
+			return -1;
+
+		pci_read_config_dword(sii->pbus, PCI_GPIO_IN, &in);
+		pci_read_config_dword(sii->pbus, PCI_GPIO_OUT, &out);
+		pci_read_config_dword(sii->pbus, PCI_GPIO_OUTEN, &outen);
+
+		/*
+		 * Avoid glitching the clock if GPRS is already using it.
+		 * We can't actually read the state of the PLLPD so we infer it
+		 * by the value of XTAL_PU which *is* readable via gpioin.
+		 */
+		if (on && (in & PCI_CFG_GPIO_XTAL))
+			return 0;
+
+		if (what & XTAL)
+			outen |= PCI_CFG_GPIO_XTAL;
+		if (what & PLL)
+			outen |= PCI_CFG_GPIO_PLL;
+
+		if (on) {
+			/* turn primary xtal on */
+			if (what & XTAL) {
+				out |= PCI_CFG_GPIO_XTAL;
+				if (what & PLL)
+					out |= PCI_CFG_GPIO_PLL;
+				pci_write_config_dword(sii->pbus,
+						       PCI_GPIO_OUT, out);
+				pci_write_config_dword(sii->pbus,
+						       PCI_GPIO_OUTEN, outen);
+				udelay(XTAL_ON_DELAY);
+			}
+
+			/* turn pll on */
+			if (what & PLL) {
+				out &= ~PCI_CFG_GPIO_PLL;
+				pci_write_config_dword(sii->pbus,
+						       PCI_GPIO_OUT, out);
+				mdelay(2);
+			}
+		} else {
+			if (what & XTAL)
+				out &= ~PCI_CFG_GPIO_XTAL;
+			if (what & PLL)
+				out |= PCI_CFG_GPIO_PLL;
+			pci_write_config_dword(sii->pbus,
+					       PCI_GPIO_OUT, out);
+			pci_write_config_dword(sii->pbus,
+					       PCI_GPIO_OUTEN, outen);
+		}
+
+	default:
+		return -1;
+	}
+
+	return 0;
+}
+
+/*
+ *  clock control policy function throught chipcommon
+ *
+ *    set dynamic clk control mode (forceslow, forcefast, dynamic)
+ *    returns true if we are forcing fast clock
+ *    this is a wrapper over the next internal function
+ *      to allow flexible policy settings for outside caller
+ */
+bool ai_clkctl_cc(si_t *sih, uint mode)
+{
+	si_info_t *sii;
+
+	sii = SI_INFO(sih);
+
+	/* chipcommon cores prior to rev6 don't support dynamic clock control */
+	if (sih->ccrev < 6)
+		return false;
+
+	if (PCI_FORCEHT(sii))
+		return mode == CLK_FAST;
+
+	return _ai_clkctl_cc(sii, mode);
+}
+
+/* clk control mechanism through chipcommon, no policy checking */
+static bool _ai_clkctl_cc(si_info_t *sii, uint mode)
+{
+	uint origidx = 0;
+	chipcregs_t *cc;
+	u32 scc;
+	uint intr_val = 0;
+	bool fast = SI_FAST(sii);
+
+	/* chipcommon cores prior to rev6 don't support dynamic clock control */
+	if (sii->pub.ccrev < 6)
+		return false;
+
+	if (!fast) {
+		INTR_OFF(sii, intr_val);
+		origidx = sii->curidx;
+
+		if ((sii->pub.bustype == SI_BUS) &&
+		    ai_setcore(&sii->pub, MIPS33_CORE_ID, 0) &&
+		    (ai_corerev(&sii->pub) <= 7) && (sii->pub.ccrev >= 10))
+			goto done;
+
+		cc = (chipcregs_t *) ai_setcore(&sii->pub, CC_CORE_ID, 0);
+	} else {
+		cc = (chipcregs_t *) CCREGS_FAST(sii);
+		if (cc == NULL)
+			goto done;
+	}
+
+	if (!CCCTL_ENAB(&sii->pub) && (sii->pub.ccrev < 20))
+		goto done;
+
+	switch (mode) {
+	case CLK_FAST:		/* FORCEHT, fast (pll) clock */
+		if (sii->pub.ccrev < 10) {
+			/*
+			 * don't forget to force xtal back
+			 * on before we clear SCC_DYN_XTAL..
+			 */
+			ai_clkctl_xtal(&sii->pub, XTAL, ON);
+			SET_REG(&cc->slow_clk_ctl,
+				(SCC_XC | SCC_FS | SCC_IP), SCC_IP);
+		} else if (sii->pub.ccrev < 20) {
+			OR_REG(&cc->system_clk_ctl, SYCC_HR);
+		} else {
+			OR_REG(&cc->clk_ctl_st, CCS_FORCEHT);
+		}
+
+		/* wait for the PLL */
+		if (PMUCTL_ENAB(&sii->pub)) {
+			u32 htavail = CCS_HTAVAIL;
+			SPINWAIT(((R_REG(&cc->clk_ctl_st) & htavail)
+				  == 0), PMU_MAX_TRANSITION_DLY);
+		} else {
+			udelay(PLL_DELAY);
+		}
+		break;
+
+	case CLK_DYNAMIC:	/* enable dynamic clock control */
+		if (sii->pub.ccrev < 10) {
+			scc = R_REG(&cc->slow_clk_ctl);
+			scc &= ~(SCC_FS | SCC_IP | SCC_XC);
+			if ((scc & SCC_SS_MASK) != SCC_SS_XTAL)
+				scc |= SCC_XC;
+			W_REG(&cc->slow_clk_ctl, scc);
+
+			/*
+			 * for dynamic control, we have to
+			 * release our xtal_pu "force on"
+			 */
+			if (scc & SCC_XC)
+				ai_clkctl_xtal(&sii->pub, XTAL, OFF);
+		} else if (sii->pub.ccrev < 20) {
+			/* Instaclock */
+			AND_REG(&cc->system_clk_ctl, ~SYCC_HR);
+		} else {
+			AND_REG(&cc->clk_ctl_st, ~CCS_FORCEHT);
+		}
+		break;
+
+	default:
+		break;
+	}
+
+ done:
+	if (!fast) {
+		ai_setcoreidx(&sii->pub, origidx);
+		INTR_RESTORE(sii, intr_val);
+	}
+	return mode == CLK_FAST;
+}
+
+/* Build device path. Support SI, PCI, and JTAG for now. */
+int ai_devpath(si_t *sih, char *path, int size)
+{
+	int slen;
+
+	if (!path || size <= 0)
+		return -1;
+
+	switch (sih->bustype) {
+	case SI_BUS:
+	case JTAG_BUS:
+		slen = snprintf(path, (size_t) size, "sb/%u/", ai_coreidx(sih));
+		break;
+	case PCI_BUS:
+		slen = snprintf(path, (size_t) size, "pci/%u/%u/",
+			((struct pci_dev *)((SI_INFO(sih))->pbus))->bus->number,
+			PCI_SLOT(
+			    ((struct pci_dev *)((SI_INFO(sih))->pbus))->devfn));
+		break;
+
+	default:
+		slen = -1;
+		break;
+	}
+
+	if (slen < 0 || slen >= size) {
+		path[0] = '\0';
+		return -1;
+	}
+
+	return 0;
+}
+
+/* Get a variable, but only if it has a devpath prefix */
+char *ai_getdevpathvar(si_t *sih, const char *name)
+{
+	char varname[SI_DEVPATH_BUFSZ + 32];
+
+	ai_devpathvar(sih, varname, sizeof(varname), name);
+
+	return getvar(NULL, varname);
+}
+
+/* Get a variable, but only if it has a devpath prefix */
+int ai_getdevpathintvar(si_t *sih, const char *name)
+{
+#if defined(BCMBUSTYPE) && (BCMBUSTYPE == SI_BUS)
+	return getintvar(NULL, name);
+#else
+	char varname[SI_DEVPATH_BUFSZ + 32];
+
+	ai_devpathvar(sih, varname, sizeof(varname), name);
+
+	return getintvar(NULL, varname);
+#endif
+}
+
+char *ai_getnvramflvar(si_t *sih, const char *name)
+{
+	return getvar(NULL, name);
+}
+
+/* Concatenate the dev path with a varname into the given 'var' buffer
+ * and return the 'var' pointer. Nothing is done to the arguments if
+ * len == 0 or var is NULL, var is still returned. On overflow, the
+ * first char will be set to '\0'.
+ */
+static char *ai_devpathvar(si_t *sih, char *var, int len, const char *name)
+{
+	uint path_len;
+
+	if (!var || len <= 0)
+		return var;
+
+	if (ai_devpath(sih, var, len) == 0) {
+		path_len = strlen(var);
+
+		if (strlen(name) + 1 > (uint) (len - path_len))
+			var[0] = '\0';
+		else
+			strncpy(var + path_len, name, len - path_len - 1);
+	}
+
+	return var;
+}
+
+/* return true if PCIE capability exists in the pci config space */
+static __used bool ai_ispcie(si_info_t *sii)
+{
+	u8 cap_ptr;
+
+	if (sii->pub.bustype != PCI_BUS)
+		return false;
+
+	cap_ptr =
+	    pcicore_find_pci_capability(sii->pbus, PCI_CAP_ID_EXP, NULL,
+					NULL);
+	if (!cap_ptr)
+		return false;
+
+	return true;
+}
+
+bool ai_pci_war16165(si_t *sih)
+{
+	si_info_t *sii;
+
+	sii = SI_INFO(sih);
+
+	return PCI(sii) && (sih->buscorerev <= 10);
+}
+
+void ai_pci_up(si_t *sih)
+{
+	si_info_t *sii;
+
+	sii = SI_INFO(sih);
+
+	/* if not pci bus, we're done */
+	if (sih->bustype != PCI_BUS)
+		return;
+
+	if (PCI_FORCEHT(sii))
+		_ai_clkctl_cc(sii, CLK_FAST);
+
+	if (PCIE(sii))
+		pcicore_up(sii->pch, SI_PCIUP);
+
+}
+
+/* Unconfigure and/or apply various WARs when system is going to sleep mode */
+void ai_pci_sleep(si_t *sih)
+{
+	si_info_t *sii;
+
+	sii = SI_INFO(sih);
+
+	pcicore_sleep(sii->pch);
+}
+
+/* Unconfigure and/or apply various WARs when going down */
+void ai_pci_down(si_t *sih)
+{
+	si_info_t *sii;
+
+	sii = SI_INFO(sih);
+
+	/* if not pci bus, we're done */
+	if (sih->bustype != PCI_BUS)
+		return;
+
+	/* release FORCEHT since chip is going to "down" state */
+	if (PCI_FORCEHT(sii))
+		_ai_clkctl_cc(sii, CLK_DYNAMIC);
+
+	pcicore_down(sii->pch, SI_PCIDOWN);
+}
+
+/*
+ * Configure the pci core for pci client (NIC) action
+ * coremask is the bitvec of cores by index to be enabled.
+ */
+void ai_pci_setup(si_t *sih, uint coremask)
+{
+	si_info_t *sii;
+	struct sbpciregs *pciregs = NULL;
+	u32 siflag = 0, w;
+	uint idx = 0;
+
+	sii = SI_INFO(sih);
+
+	if (sii->pub.bustype != PCI_BUS)
+		return;
+
+	if (PCI(sii)) {
+		/* get current core index */
+		idx = sii->curidx;
+
+		/* we interrupt on this backplane flag number */
+		siflag = ai_flag(sih);
+
+		/* switch over to pci core */
+		pciregs = ai_setcoreidx(sih, sii->pub.buscoreidx);
+	}
+
+	/*
+	 * Enable sb->pci interrupts.  Assume
+	 * PCI rev 2.3 support was added in pci core rev 6 and things changed..
+	 */
+	if (PCIE(sii) || (PCI(sii) && ((sii->pub.buscorerev) >= 6))) {
+		/* pci config write to set this core bit in PCIIntMask */
+		pci_read_config_dword(sii->pbus, PCI_INT_MASK, &w);
+		w |= (coremask << PCI_SBIM_SHIFT);
+		pci_write_config_dword(sii->pbus, PCI_INT_MASK, w);
+	} else {
+		/* set sbintvec bit for our flag number */
+		ai_setint(sih, siflag);
+	}
+
+	if (PCI(sii)) {
+		OR_REG(&pciregs->sbtopci2,
+		       (SBTOPCI_PREF | SBTOPCI_BURST));
+		if (sii->pub.buscorerev >= 11) {
+			OR_REG(&pciregs->sbtopci2,
+			       SBTOPCI_RC_READMULTI);
+			w = R_REG(&pciregs->clkrun);
+			W_REG(&pciregs->clkrun,
+			      (w | PCI_CLKRUN_DSBL));
+			w = R_REG(&pciregs->clkrun);
+		}
+
+		/* switch back to previous core */
+		ai_setcoreidx(sih, idx);
+	}
+}
+
+/*
+ * Fixup SROMless PCI device's configuration.
+ * The current core may be changed upon return.
+ */
+int ai_pci_fixcfg(si_t *sih)
+{
+	uint origidx, pciidx;
+	struct sbpciregs *pciregs = NULL;
+	sbpcieregs_t *pcieregs = NULL;
+	void *regs = NULL;
+	u16 val16, *reg16 = NULL;
+
+	si_info_t *sii = SI_INFO(sih);
+
+	/* Fixup PI in SROM shadow area to enable the correct PCI core access */
+	/* save the current index */
+	origidx = ai_coreidx(&sii->pub);
+
+	/* check 'pi' is correct and fix it if not */
+	if (sii->pub.buscoretype == PCIE_CORE_ID) {
+		pcieregs = ai_setcore(&sii->pub, PCIE_CORE_ID, 0);
+		regs = pcieregs;
+		reg16 = &pcieregs->sprom[SRSH_PI_OFFSET];
+	} else if (sii->pub.buscoretype == PCI_CORE_ID) {
+		pciregs = ai_setcore(&sii->pub, PCI_CORE_ID, 0);
+		regs = pciregs;
+		reg16 = &pciregs->sprom[SRSH_PI_OFFSET];
+	}
+	pciidx = ai_coreidx(&sii->pub);
+	val16 = R_REG(reg16);
+	if (((val16 & SRSH_PI_MASK) >> SRSH_PI_SHIFT) != (u16) pciidx) {
+		val16 =
+		    (u16) (pciidx << SRSH_PI_SHIFT) | (val16 &
+							  ~SRSH_PI_MASK);
+		W_REG(reg16, val16);
+	}
+
+	/* restore the original index */
+	ai_setcoreidx(&sii->pub, origidx);
+
+	pcicore_hwup(sii->pch);
+	return 0;
+}
+
+/* mask&set gpiocontrol bits */
+u32 ai_gpiocontrol(si_t *sih, u32 mask, u32 val, u8 priority)
+{
+	uint regoff;
+
+	regoff = 0;
+
+	/* gpios could be shared on router platforms
+	 * ignore reservation if it's high priority (e.g., test apps)
+	 */
+	if ((priority != GPIO_HI_PRIORITY) &&
+	    (sih->bustype == SI_BUS) && (val || mask)) {
+		mask = priority ? (ai_gpioreservation & mask) :
+		    ((ai_gpioreservation | mask) & ~(ai_gpioreservation));
+		val &= mask;
+	}
+
+	regoff = offsetof(chipcregs_t, gpiocontrol);
+	return ai_corereg(sih, SI_CC_IDX, regoff, mask, val);
+}
+
+void ai_chipcontrl_epa4331(si_t *sih, bool on)
+{
+	si_info_t *sii;
+	chipcregs_t *cc;
+	uint origidx;
+	u32 val;
+
+	sii = SI_INFO(sih);
+	origidx = ai_coreidx(sih);
+
+	cc = (chipcregs_t *) ai_setcore(sih, CC_CORE_ID, 0);
+
+	val = R_REG(&cc->chipcontrol);
+
+	if (on) {
+		if (sih->chippkg == 9 || sih->chippkg == 0xb) {
+			/* Ext PA Controls for 4331 12x9 Package */
+			W_REG(&cc->chipcontrol, val |
+			      (CCTRL4331_EXTPA_EN |
+			       CCTRL4331_EXTPA_ON_GPIO2_5));
+		} else {
+			/* Ext PA Controls for 4331 12x12 Package */
+			W_REG(&cc->chipcontrol,
+			      val | (CCTRL4331_EXTPA_EN));
+		}
+	} else {
+		val &= ~(CCTRL4331_EXTPA_EN | CCTRL4331_EXTPA_ON_GPIO2_5);
+		W_REG(&cc->chipcontrol, val);
+	}
+
+	ai_setcoreidx(sih, origidx);
+}
+
+/* Enable BT-COEX & Ex-PA for 4313 */
+void ai_epa_4313war(si_t *sih)
+{
+	si_info_t *sii;
+	chipcregs_t *cc;
+	uint origidx;
+
+	sii = SI_INFO(sih);
+	origidx = ai_coreidx(sih);
+
+	cc = (chipcregs_t *) ai_setcore(sih, CC_CORE_ID, 0);
+
+	/* EPA Fix */
+	W_REG(&cc->gpiocontrol,
+	      R_REG(&cc->gpiocontrol) | GPIO_CTRL_EPA_EN_MASK);
+
+	ai_setcoreidx(sih, origidx);
+}
+
+/* check if the device is removed */
+bool ai_deviceremoved(si_t *sih)
+{
+	u32 w;
+	si_info_t *sii;
+
+	sii = SI_INFO(sih);
+
+	switch (sih->bustype) {
+	case PCI_BUS:
+		pci_read_config_dword(sii->pbus, PCI_VENDOR_ID, &w);
+		if ((w & 0xFFFF) != PCI_VENDOR_ID_BROADCOM)
+			return true;
+		break;
+	}
+	return false;
+}
+
+bool ai_is_sprom_available(si_t *sih)
+{
+	if (sih->ccrev >= 31) {
+		si_info_t *sii;
+		uint origidx;
+		chipcregs_t *cc;
+		u32 sromctrl;
+
+		if ((sih->cccaps & CC_CAP_SROM) == 0)
+			return false;
+
+		sii = SI_INFO(sih);
+		origidx = sii->curidx;
+		cc = ai_setcoreidx(sih, SI_CC_IDX);
+		sromctrl = R_REG(&cc->sromcontrol);
+		ai_setcoreidx(sih, origidx);
+		return sromctrl & SRC_PRESENT;
+	}
+
+	switch (sih->chip) {
+	case BCM4329_CHIP_ID:
+		return (sih->chipst & CST4329_SPROM_SEL) != 0;
+	case BCM4319_CHIP_ID:
+		return (sih->chipst & CST4319_SPROM_SEL) != 0;
+	case BCM4336_CHIP_ID:
+		return (sih->chipst & CST4336_SPROM_PRESENT) != 0;
+	case BCM4330_CHIP_ID:
+		return (sih->chipst & CST4330_SPROM_PRESENT) != 0;
+	case BCM4313_CHIP_ID:
+		return (sih->chipst & CST4313_SPROM_PRESENT) != 0;
+	case BCM4331_CHIP_ID:
+		return (sih->chipst & CST4331_SPROM_PRESENT) != 0;
+	default:
+		return true;
+	}
+}
+
+bool ai_is_otp_disabled(si_t *sih)
+{
+	switch (sih->chip) {
+	case BCM4329_CHIP_ID:
+		return (sih->chipst & CST4329_SPROM_OTP_SEL_MASK) ==
+		    CST4329_OTP_PWRDN;
+	case BCM4319_CHIP_ID:
+		return (sih->chipst & CST4319_SPROM_OTP_SEL_MASK) ==
+		    CST4319_OTP_PWRDN;
+	case BCM4336_CHIP_ID:
+		return (sih->chipst & CST4336_OTP_PRESENT) == 0;
+	case BCM4330_CHIP_ID:
+		return (sih->chipst & CST4330_OTP_PRESENT) == 0;
+	case BCM4313_CHIP_ID:
+		return (sih->chipst & CST4313_OTP_PRESENT) == 0;
+		/* These chips always have their OTP on */
+	case BCM43224_CHIP_ID:
+	case BCM43225_CHIP_ID:
+	case BCM43421_CHIP_ID:
+	case BCM43235_CHIP_ID:
+	case BCM43236_CHIP_ID:
+	case BCM43238_CHIP_ID:
+	case BCM4331_CHIP_ID:
+	default:
+		return false;
+	}
+}
+
+bool ai_is_otp_powered(si_t *sih)
+{
+	if (PMUCTL_ENAB(sih))
+		return si_pmu_is_otp_powered(sih);
+	return true;
+}
+
+void ai_otp_power(si_t *sih, bool on)
+{
+	if (PMUCTL_ENAB(sih))
+		si_pmu_otp_power(sih, on);
+	udelay(1000);
+}
diff -druN linux-2.6.39-libre/drivers/staging/brcm80211/brcmsmac/aiutils.h linux-3.0-rc7-libre/drivers/staging/brcm80211/brcmsmac/aiutils.h
--- linux-2.6.39-libre/drivers/staging/brcm80211/brcmsmac/aiutils.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/staging/brcm80211/brcmsmac/aiutils.h	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,546 @@
+/*
+ * Copyright (c) 2011 Broadcom Corporation
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef	_aiutils_h_
+#define	_aiutils_h_
+
+/* cpp contortions to concatenate w/arg prescan */
+#ifndef PAD
+#define	_PADLINE(line)	pad ## line
+#define	_XSTR(line)	_PADLINE(line)
+#define	PAD		_XSTR(__LINE__)
+#endif
+
+/* Include the soci specific files */
+#include <aidmp.h>
+
+/*
+ * SOC Interconnect Address Map.
+ * All regions may not exist on all chips.
+ */
+/* Physical SDRAM */
+#define SI_SDRAM_BASE		0x00000000
+/* Host Mode sb2pcitranslation0 (64 MB) */
+#define SI_PCI_MEM		0x08000000
+#define SI_PCI_MEM_SZ		(64 * 1024 * 1024)
+/* Host Mode sb2pcitranslation1 (64 MB) */
+#define SI_PCI_CFG		0x0c000000
+/* Byteswapped Physical SDRAM */
+#define	SI_SDRAM_SWAPPED	0x10000000
+/* Region 2 for sdram (512 MB) */
+#define SI_SDRAM_R2		0x80000000
+
+#ifdef SI_ENUM_BASE_VARIABLE
+#define SI_ENUM_BASE		(sii->pub.si_enum_base)
+#else
+#define SI_ENUM_BASE		0x18000000	/* Enumeration space base */
+#endif				/* SI_ENUM_BASE_VARIABLE */
+
+/* Wrapper space base */
+#define SI_WRAP_BASE		0x18100000
+/* each core gets 4Kbytes for registers */
+#define SI_CORE_SIZE		0x1000
+/*
+ * Max cores (this is arbitrary, for software
+ * convenience and could be changed if we
+ * make any larger chips
+ */
+#define	SI_MAXCORES		16
+
+/* On-chip RAM on chips that also have DDR */
+#define	SI_FASTRAM		0x19000000
+#define	SI_FASTRAM_SWAPPED	0x19800000
+
+/* Flash Region 2 (region 1 shadowed here) */
+#define	SI_FLASH2		0x1c000000
+/* Size of Flash Region 2 */
+#define	SI_FLASH2_SZ		0x02000000
+/* ARM Cortex-M3 ROM */
+#define	SI_ARMCM3_ROM		0x1e000000
+/* MIPS Flash Region 1 */
+#define	SI_FLASH1		0x1fc00000
+/* MIPS Size of Flash Region 1 */
+#define	SI_FLASH1_SZ		0x00400000
+/* ARM7TDMI-S ROM */
+#define	SI_ARM7S_ROM		0x20000000
+/* ARM Cortex-M3 SRAM Region 2 */
+#define	SI_ARMCM3_SRAM2		0x60000000
+/* ARM7TDMI-S SRAM Region 2 */
+#define	SI_ARM7S_SRAM2		0x80000000
+/* ARM Flash Region 1 */
+#define	SI_ARM_FLASH1		0xffff0000
+/* ARM Size of Flash Region 1 */
+#define	SI_ARM_FLASH1_SZ	0x00010000
+
+/* Client Mode sb2pcitranslation2 (1 GB) */
+#define SI_PCI_DMA		0x40000000
+/* Client Mode sb2pcitranslation2 (1 GB) */
+#define SI_PCI_DMA2		0x80000000
+/* Client Mode sb2pcitranslation2 size in bytes */
+#define SI_PCI_DMA_SZ		0x40000000
+/* PCIE Client Mode sb2pcitranslation2 (2 ZettaBytes), low 32 bits */
+#define SI_PCIE_DMA_L32		0x00000000
+/* PCIE Client Mode sb2pcitranslation2 (2 ZettaBytes), high 32 bits */
+#define SI_PCIE_DMA_H32		0x80000000
+
+/* core codes */
+#define	NODEV_CORE_ID		0x700	/* Invalid coreid */
+#define	CC_CORE_ID		0x800	/* chipcommon core */
+#define	ILINE20_CORE_ID		0x801	/* iline20 core */
+#define	SRAM_CORE_ID		0x802	/* sram core */
+#define	SDRAM_CORE_ID		0x803	/* sdram core */
+#define	PCI_CORE_ID		0x804	/* pci core */
+#define	MIPS_CORE_ID		0x805	/* mips core */
+#define	ENET_CORE_ID		0x806	/* enet mac core */
+#define	CODEC_CORE_ID		0x807	/* v90 codec core */
+#define	USB_CORE_ID		0x808	/* usb 1.1 host/device core */
+#define	ADSL_CORE_ID		0x809	/* ADSL core */
+#define	ILINE100_CORE_ID	0x80a	/* iline100 core */
+#define	IPSEC_CORE_ID		0x80b	/* ipsec core */
+#define	UTOPIA_CORE_ID		0x80c	/* utopia core */
+#define	PCMCIA_CORE_ID		0x80d	/* pcmcia core */
+#define	SOCRAM_CORE_ID		0x80e	/* internal memory core */
+#define	MEMC_CORE_ID		0x80f	/* memc sdram core */
+#define	OFDM_CORE_ID		0x810	/* OFDM phy core */
+#define	EXTIF_CORE_ID		0x811	/* external interface core */
+#define	D11_CORE_ID		0x812	/* 802.11 MAC core */
+#define	APHY_CORE_ID		0x813	/* 802.11a phy core */
+#define	BPHY_CORE_ID		0x814	/* 802.11b phy core */
+#define	GPHY_CORE_ID		0x815	/* 802.11g phy core */
+#define	MIPS33_CORE_ID		0x816	/* mips3302 core */
+#define	USB11H_CORE_ID		0x817	/* usb 1.1 host core */
+#define	USB11D_CORE_ID		0x818	/* usb 1.1 device core */
+#define	USB20H_CORE_ID		0x819	/* usb 2.0 host core */
+#define	USB20D_CORE_ID		0x81a	/* usb 2.0 device core */
+#define	SDIOH_CORE_ID		0x81b	/* sdio host core */
+#define	ROBO_CORE_ID		0x81c	/* roboswitch core */
+#define	ATA100_CORE_ID		0x81d	/* parallel ATA core */
+#define	SATAXOR_CORE_ID		0x81e	/* serial ATA & XOR DMA core */
+#define	GIGETH_CORE_ID		0x81f	/* gigabit ethernet core */
+#define	PCIE_CORE_ID		0x820	/* pci express core */
+#define	NPHY_CORE_ID		0x821	/* 802.11n 2x2 phy core */
+#define	SRAMC_CORE_ID		0x822	/* SRAM controller core */
+#define	MINIMAC_CORE_ID		0x823	/* MINI MAC/phy core */
+#define	ARM11_CORE_ID		0x824	/* ARM 1176 core */
+#define	ARM7S_CORE_ID		0x825	/* ARM7tdmi-s core */
+#define	LPPHY_CORE_ID		0x826	/* 802.11a/b/g phy core */
+#define	PMU_CORE_ID		0x827	/* PMU core */
+#define	SSNPHY_CORE_ID		0x828	/* 802.11n single-stream phy core */
+#define	SDIOD_CORE_ID		0x829	/* SDIO device core */
+#define	ARMCM3_CORE_ID		0x82a	/* ARM Cortex M3 core */
+#define	HTPHY_CORE_ID		0x82b	/* 802.11n 4x4 phy core */
+#define	MIPS74K_CORE_ID		0x82c	/* mips 74k core */
+#define	GMAC_CORE_ID		0x82d	/* Gigabit MAC core */
+#define	DMEMC_CORE_ID		0x82e	/* DDR1/2 memory controller core */
+#define	PCIERC_CORE_ID		0x82f	/* PCIE Root Complex core */
+#define	OCP_CORE_ID		0x830	/* OCP2OCP bridge core */
+#define	SC_CORE_ID		0x831	/* shared common core */
+#define	AHB_CORE_ID		0x832	/* OCP2AHB bridge core */
+#define	SPIH_CORE_ID		0x833	/* SPI host core */
+#define	I2S_CORE_ID		0x834	/* I2S core */
+#define	DMEMS_CORE_ID		0x835	/* SDR/DDR1 memory controller core */
+#define	DEF_SHIM_COMP		0x837	/* SHIM component in ubus/6362 */
+#define OOB_ROUTER_CORE_ID	0x367	/* OOB router core ID */
+#define	DEF_AI_COMP		0xfff	/* Default component, in ai chips it
+					 * maps all unused address ranges
+					 */
+
+/* There are TWO constants on all HND chips: SI_ENUM_BASE above,
+ * and chipcommon being the first core:
+ */
+#define	SI_CC_IDX		0
+
+/* SOC Interconnect types (aka chip types) */
+#define	SOCI_AI			1
+
+/* Common core control flags */
+#define	SICF_BIST_EN		0x8000
+#define	SICF_PME_EN		0x4000
+#define	SICF_CORE_BITS		0x3ffc
+#define	SICF_FGC		0x0002
+#define	SICF_CLOCK_EN		0x0001
+
+/* Common core status flags */
+#define	SISF_BIST_DONE		0x8000
+#define	SISF_BIST_ERROR		0x4000
+#define	SISF_GATED_CLK		0x2000
+#define	SISF_DMA64		0x1000
+#define	SISF_CORE_BITS		0x0fff
+
+/* A register that is common to all cores to
+ * communicate w/PMU regarding clock control.
+ */
+#define SI_CLK_CTL_ST		0x1e0	/* clock control and status */
+
+/* clk_ctl_st register */
+#define	CCS_FORCEALP		0x00000001	/* force ALP request */
+#define	CCS_FORCEHT		0x00000002	/* force HT request */
+#define	CCS_FORCEILP		0x00000004	/* force ILP request */
+#define	CCS_ALPAREQ		0x00000008	/* ALP Avail Request */
+#define	CCS_HTAREQ		0x00000010	/* HT Avail Request */
+#define	CCS_FORCEHWREQOFF	0x00000020	/* Force HW Clock Request Off */
+#define CCS_ERSRC_REQ_MASK	0x00000700	/* external resource requests */
+#define CCS_ERSRC_REQ_SHIFT	8
+#define	CCS_ALPAVAIL		0x00010000	/* ALP is available */
+#define	CCS_HTAVAIL		0x00020000	/* HT is available */
+#define CCS_BP_ON_APL		0x00040000	/* RO: running on ALP clock */
+#define CCS_BP_ON_HT		0x00080000	/* RO: running on HT clock */
+#define CCS_ERSRC_STS_MASK	0x07000000	/* external resource status */
+#define CCS_ERSRC_STS_SHIFT	24
+
+/* HT avail in chipc and pcmcia on 4328a0 */
+#define	CCS0_HTAVAIL		0x00010000
+/* ALP avail in chipc and pcmcia on 4328a0 */
+#define	CCS0_ALPAVAIL		0x00020000
+
+/* Not really related to SOC Interconnect, but a couple of software
+ * conventions for the use the flash space:
+ */
+
+/* Minumum amount of flash we support */
+#define FLASH_MIN		0x00020000	/* Minimum flash size */
+
+/* A boot/binary may have an embedded block that describes its size  */
+#define	BISZ_OFFSET		0x3e0	/* At this offset into the binary */
+#define	BISZ_MAGIC		0x4249535a	/* Marked with value: 'BISZ' */
+#define	BISZ_MAGIC_IDX		0	/* Word 0: magic */
+#define	BISZ_TXTST_IDX		1	/*      1: text start */
+#define	BISZ_TXTEND_IDX		2	/*      2: text end */
+#define	BISZ_DATAST_IDX		3	/*      3: data start */
+#define	BISZ_DATAEND_IDX	4	/*      4: data end */
+#define	BISZ_BSSST_IDX		5	/*      5: bss start */
+#define	BISZ_BSSEND_IDX		6	/*      6: bss end */
+#define BISZ_SIZE		7	/* descriptor size in 32-bit integers */
+
+#define	SI_INFO(sih)	(si_info_t *)sih
+
+#define	GOODCOREADDR(x, b) \
+	(((x) >= (b)) && ((x) < ((b) + SI_MAXCORES * SI_CORE_SIZE)) && \
+		IS_ALIGNED((x), SI_CORE_SIZE))
+#define	GOODREGS(regs) \
+	((regs) != NULL && IS_ALIGNED((unsigned long)(regs), SI_CORE_SIZE))
+#define BADCOREADDR	0
+#define	GOODIDX(idx)	(((uint)idx) < SI_MAXCORES)
+#define	NOREV		-1	/* Invalid rev */
+
+/* Newer chips can access PCI/PCIE and CC core without requiring to change
+ * PCI BAR0 WIN
+ */
+#define SI_FAST(si) (((si)->pub.buscoretype == PCIE_CORE_ID) ||	\
+		     (((si)->pub.buscoretype == PCI_CORE_ID) && \
+		      (si)->pub.buscorerev >= 13))
+
+#define PCIEREGS(si) (((char *)((si)->curmap) + PCI_16KB0_PCIREGS_OFFSET))
+#define CCREGS_FAST(si) (((char *)((si)->curmap) + PCI_16KB0_CCREGS_OFFSET))
+
+/*
+ * Macros to disable/restore function core(D11, ENET, ILINE20, etc) interrupts
+ * before after core switching to avoid invalid register accesss inside ISR.
+ */
+#define INTR_OFF(si, intr_val) \
+	if ((si)->intrsoff_fn && \
+	    (si)->coreid[(si)->curidx] == (si)->dev_coreid) \
+		intr_val = (*(si)->intrsoff_fn)((si)->intr_arg)
+#define INTR_RESTORE(si, intr_val) \
+	if ((si)->intrsrestore_fn && \
+	    (si)->coreid[(si)->curidx] == (si)->dev_coreid) \
+		(*(si)->intrsrestore_fn)((si)->intr_arg, intr_val)
+
+/* dynamic clock control defines */
+#define	LPOMINFREQ		25000	/* low power oscillator min */
+#define	LPOMAXFREQ		43000	/* low power oscillator max */
+#define	XTALMINFREQ		19800000	/* 20 MHz - 1% */
+#define	XTALMAXFREQ		20200000	/* 20 MHz + 1% */
+#define	PCIMINFREQ		25000000	/* 25 MHz */
+#define	PCIMAXFREQ		34000000	/* 33 MHz + fudge */
+
+#define	ILP_DIV_5MHZ		0	/* ILP = 5 MHz */
+#define	ILP_DIV_1MHZ		4	/* ILP = 1 MHz */
+
+#define PCI(si)		(((si)->pub.bustype == PCI_BUS) &&	\
+			 ((si)->pub.buscoretype == PCI_CORE_ID))
+#define PCIE(si)	(((si)->pub.bustype == PCI_BUS) &&	\
+			 ((si)->pub.buscoretype == PCIE_CORE_ID))
+#define PCI_FORCEHT(si)	\
+	(PCIE(si) && (si->pub.chip == BCM4716_CHIP_ID))
+
+/* GPIO Based LED powersave defines */
+#define DEFAULT_GPIO_ONTIME	10	/* Default: 10% on */
+#define DEFAULT_GPIO_OFFTIME	90	/* Default: 10% on */
+
+#ifndef DEFAULT_GPIOTIMERVAL
+#define DEFAULT_GPIOTIMERVAL \
+	((DEFAULT_GPIO_ONTIME << GPIO_ONTIME_SHIFT) | DEFAULT_GPIO_OFFTIME)
+#endif
+
+/*
+ * Data structure to export all chip specific common variables
+ *   public (read-only) portion of aiutils handle returned by si_attach()
+ */
+struct si_pub {
+	uint bustype;		/* SI_BUS, PCI_BUS */
+	uint buscoretype;	/* PCI_CORE_ID, PCIE_CORE_ID, PCMCIA_CORE_ID */
+	uint buscorerev;	/* buscore rev */
+	uint buscoreidx;	/* buscore index */
+	int ccrev;		/* chip common core rev */
+	u32 cccaps;		/* chip common capabilities */
+	u32 cccaps_ext;	/* chip common capabilities extension */
+	int pmurev;		/* pmu core rev */
+	u32 pmucaps;		/* pmu capabilities */
+	uint boardtype;		/* board type */
+	uint boardvendor;	/* board vendor */
+	uint boardflags;	/* board flags */
+	uint boardflags2;	/* board flags2 */
+	uint chip;		/* chip number */
+	uint chiprev;		/* chip revision */
+	uint chippkg;		/* chip package option */
+	u32 chipst;		/* chip status */
+	bool issim;		/* chip is in simulation or emulation */
+	uint socirev;		/* SOC interconnect rev */
+	bool pci_pr32414;
+
+};
+
+/*
+ * for HIGH_ONLY driver, the si_t must be writable to allow states sync from
+ * BMAC to HIGH driver for monolithic driver, it is readonly to prevent accident
+ * change
+ */
+typedef const struct si_pub si_t;
+
+/*
+ * Many of the routines below take an 'sih' handle as their first arg.
+ * Allocate this by calling si_attach().  Free it by calling si_detach().
+ * At any one time, the sih is logically focused on one particular si core
+ * (the "current core").
+ * Use si_setcore() or si_setcoreidx() to change the association to another core
+ */
+
+#define	BADIDX		(SI_MAXCORES + 1)
+
+/* clkctl xtal what flags */
+#define	XTAL			0x1	/* primary crystal oscillator (2050) */
+#define	PLL			0x2	/* main chip pll */
+
+/* clkctl clk mode */
+#define	CLK_FAST		0	/* force fast (pll) clock */
+#define	CLK_DYNAMIC		2	/* enable dynamic clock control */
+
+/* GPIO usage priorities */
+#define GPIO_DRV_PRIORITY	0	/* Driver */
+#define GPIO_APP_PRIORITY	1	/* Application */
+#define GPIO_HI_PRIORITY	2	/* Highest priority. Ignore GPIO
+					 * reservation
+					 */
+
+/* GPIO pull up/down */
+#define GPIO_PULLUP		0
+#define GPIO_PULLDN		1
+
+/* GPIO event regtype */
+#define GPIO_REGEVT		0	/* GPIO register event */
+#define GPIO_REGEVT_INTMSK	1	/* GPIO register event int mask */
+#define GPIO_REGEVT_INTPOL	2	/* GPIO register event int polarity */
+
+/* device path */
+#define SI_DEVPATH_BUFSZ	16	/* min buffer size in bytes */
+
+/* SI routine enumeration: to be used by update function with multiple hooks */
+#define	SI_DOATTACH	1
+#define SI_PCIDOWN	2
+#define SI_PCIUP	3
+
+#define	ISSIM_ENAB(sih)	0
+
+/* PMU clock/power control */
+#if defined(BCMPMUCTL)
+#define PMUCTL_ENAB(sih)	(BCMPMUCTL)
+#else
+#define PMUCTL_ENAB(sih)	((sih)->cccaps & CC_CAP_PMU)
+#endif
+
+/* chipcommon clock/power control (exclusive with PMU's) */
+#if defined(BCMPMUCTL) && BCMPMUCTL
+#define CCCTL_ENAB(sih)		(0)
+#define CCPLL_ENAB(sih)		(0)
+#else
+#define CCCTL_ENAB(sih)		((sih)->cccaps & CC_CAP_PWR_CTL)
+#define CCPLL_ENAB(sih)		((sih)->cccaps & CC_CAP_PLL_MASK)
+#endif
+
+typedef void (*gpio_handler_t) (u32 stat, void *arg);
+
+/* External PA enable mask */
+#define GPIO_CTRL_EPA_EN_MASK 0x40
+
+#define	SI_ERROR(args)
+
+#ifdef BCMDBG
+#define	SI_MSG(args)	printk args
+#else
+#define	SI_MSG(args)
+#endif				/* BCMDBG */
+
+/* Define SI_VMSG to printf for verbose debugging, but don't check it in */
+#define	SI_VMSG(args)
+
+#define	IS_SIM(chippkg)	\
+	((chippkg == HDLSIM_PKG_ID) || (chippkg == HWSIM_PKG_ID))
+
+typedef u32(*si_intrsoff_t) (void *intr_arg);
+typedef void (*si_intrsrestore_t) (void *intr_arg, u32 arg);
+typedef bool(*si_intrsenabled_t) (void *intr_arg);
+
+typedef struct gpioh_item {
+	void *arg;
+	bool level;
+	gpio_handler_t handler;
+	u32 event;
+	struct gpioh_item *next;
+} gpioh_item_t;
+
+/* misc si info needed by some of the routines */
+typedef struct si_info {
+	struct si_pub pub;	/* back plane public state (must be first) */
+	void *pbus;		/* handle to bus (pci/sdio/..) */
+	uint dev_coreid;	/* the core provides driver functions */
+	void *intr_arg;		/* interrupt callback function arg */
+	si_intrsoff_t intrsoff_fn;	/* turns chip interrupts off */
+	si_intrsrestore_t intrsrestore_fn; /* restore chip interrupts */
+	si_intrsenabled_t intrsenabled_fn; /* check if interrupts are enabled */
+
+	void *pch;		/* PCI/E core handle */
+
+	gpioh_item_t *gpioh_head;	/* GPIO event handlers list */
+
+	bool memseg;		/* flag to toggle MEM_SEG register */
+
+	char *vars;
+	uint varsz;
+
+	void *curmap;		/* current regs va */
+	void *regs[SI_MAXCORES];	/* other regs va */
+
+	uint curidx;		/* current core index */
+	uint numcores;		/* # discovered cores */
+	uint coreid[SI_MAXCORES]; /* id of each core */
+	u32 coresba[SI_MAXCORES]; /* backplane address of each core */
+	void *regs2[SI_MAXCORES]; /* 2nd virtual address per core (usbh20) */
+	u32 coresba2[SI_MAXCORES]; /* 2nd phys address per core (usbh20) */
+	u32 coresba_size[SI_MAXCORES]; /* backplane address space size */
+	u32 coresba2_size[SI_MAXCORES];	/* second address space size */
+
+	void *curwrap;		/* current wrapper va */
+	void *wrappers[SI_MAXCORES];	/* other cores wrapper va */
+	u32 wrapba[SI_MAXCORES];	/* address of controlling wrapper */
+
+	u32 cia[SI_MAXCORES];	/* erom cia entry for each core */
+	u32 cib[SI_MAXCORES];	/* erom cia entry for each core */
+	u32 oob_router;	/* oob router registers for axi */
+} si_info_t;
+
+/* AMBA Interconnect exported externs */
+extern void ai_scan(si_t *sih, void *regs, uint devid);
+
+extern uint ai_flag(si_t *sih);
+extern void ai_setint(si_t *sih, int siflag);
+extern uint ai_coreidx(si_t *sih);
+extern uint ai_corevendor(si_t *sih);
+extern uint ai_corerev(si_t *sih);
+extern bool ai_iscoreup(si_t *sih);
+extern void *ai_setcoreidx(si_t *sih, uint coreidx);
+extern u32 ai_core_cflags(si_t *sih, u32 mask, u32 val);
+extern void ai_core_cflags_wo(si_t *sih, u32 mask, u32 val);
+extern u32 ai_core_sflags(si_t *sih, u32 mask, u32 val);
+extern uint ai_corereg(si_t *sih, uint coreidx, uint regoff, uint mask,
+		       uint val);
+extern void ai_core_reset(si_t *sih, u32 bits, u32 resetbits);
+extern void ai_core_disable(si_t *sih, u32 bits);
+extern int ai_numaddrspaces(si_t *sih);
+extern u32 ai_addrspace(si_t *sih, uint asidx);
+extern u32 ai_addrspacesize(si_t *sih, uint asidx);
+extern void ai_write_wrap_reg(si_t *sih, u32 offset, u32 val);
+
+/* === exported functions === */
+extern si_t *ai_attach(uint pcidev, void *regs, uint bustype,
+		       void *sdh, char **vars, uint *varsz);
+
+extern void ai_detach(si_t *sih);
+extern bool ai_pci_war16165(si_t *sih);
+
+extern uint ai_coreid(si_t *sih);
+extern uint ai_corerev(si_t *sih);
+extern uint ai_corereg(si_t *sih, uint coreidx, uint regoff, uint mask,
+		uint val);
+extern void ai_write_wrapperreg(si_t *sih, u32 offset, u32 val);
+extern u32 ai_core_cflags(si_t *sih, u32 mask, u32 val);
+extern u32 ai_core_sflags(si_t *sih, u32 mask, u32 val);
+extern bool ai_iscoreup(si_t *sih);
+extern uint ai_findcoreidx(si_t *sih, uint coreid, uint coreunit);
+extern void *ai_setcoreidx(si_t *sih, uint coreidx);
+extern void *ai_setcore(si_t *sih, uint coreid, uint coreunit);
+extern void *ai_switch_core(si_t *sih, uint coreid, uint *origidx,
+			    uint *intr_val);
+extern void ai_restore_core(si_t *sih, uint coreid, uint intr_val);
+extern void ai_core_reset(si_t *sih, u32 bits, u32 resetbits);
+extern void ai_core_disable(si_t *sih, u32 bits);
+extern u32 ai_alp_clock(si_t *sih);
+extern u32 ai_ilp_clock(si_t *sih);
+extern void ai_pci_setup(si_t *sih, uint coremask);
+extern void ai_setint(si_t *sih, int siflag);
+extern bool ai_backplane64(si_t *sih);
+extern void ai_register_intr_callback(si_t *sih, void *intrsoff_fn,
+				      void *intrsrestore_fn,
+				      void *intrsenabled_fn, void *intr_arg);
+extern void ai_deregister_intr_callback(si_t *sih);
+extern void ai_clkctl_init(si_t *sih);
+extern u16 ai_clkctl_fast_pwrup_delay(si_t *sih);
+extern bool ai_clkctl_cc(si_t *sih, uint mode);
+extern int ai_clkctl_xtal(si_t *sih, uint what, bool on);
+extern bool ai_deviceremoved(si_t *sih);
+extern u32 ai_gpiocontrol(si_t *sih, u32 mask, u32 val,
+			     u8 priority);
+
+/* OTP status */
+extern bool ai_is_otp_disabled(si_t *sih);
+extern bool ai_is_otp_powered(si_t *sih);
+extern void ai_otp_power(si_t *sih, bool on);
+
+/* SPROM availability */
+extern bool ai_is_sprom_available(si_t *sih);
+
+/*
+ * Build device path. Path size must be >= SI_DEVPATH_BUFSZ.
+ * The returned path is NULL terminated and has trailing '/'.
+ * Return 0 on success, nonzero otherwise.
+ */
+extern int ai_devpath(si_t *sih, char *path, int size);
+/* Read variable with prepending the devpath to the name */
+extern char *ai_getdevpathvar(si_t *sih, const char *name);
+extern int ai_getdevpathintvar(si_t *sih, const char *name);
+
+extern void ai_pci_sleep(si_t *sih);
+extern void ai_pci_down(si_t *sih);
+extern void ai_pci_up(si_t *sih);
+extern int ai_pci_fixcfg(si_t *sih);
+
+extern void ai_chipcontrl_epa4331(si_t *sih, bool on);
+/* Enable Ex-PA for 4313 */
+extern void ai_epa_4313war(si_t *sih);
+
+char *ai_getnvramflvar(si_t *sih, const char *name);
+
+#endif				/* _aiutils_h_ */
diff -druN linux-2.6.39-libre/drivers/staging/brcm80211/brcmsmac/bcmotp.c linux-3.0-rc7-libre/drivers/staging/brcm80211/brcmsmac/bcmotp.c
--- linux-2.6.39-libre/drivers/staging/brcm80211/brcmsmac/bcmotp.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/staging/brcm80211/brcmsmac/bcmotp.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,936 @@
+/*
+ * Copyright (c) 2010 Broadcom Corporation
+ *
+ * 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/delay.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/crc-ccitt.h>
+
+#include <bcmdefs.h>
+#include <bcmdevs.h>
+#include <bcmutils.h>
+#include <aiutils.h>
+#include <hndsoc.h>
+#include <sbchipc.h>
+#include <bcmotp.h>
+
+/*
+ * There are two different OTP controllers so far:
+ * 	1. new IPX OTP controller:	chipc 21, >=23
+ * 	2. older HND OTP controller:	chipc 12, 17, 22
+ *
+ * Define BCMHNDOTP to include support for the HND OTP controller.
+ * Define BCMIPXOTP to include support for the IPX OTP controller.
+ *
+ * NOTE 1: More than one may be defined
+ * NOTE 2: If none are defined, the default is to include them all.
+ */
+
+#if !defined(BCMHNDOTP) && !defined(BCMIPXOTP)
+#define BCMHNDOTP	1
+#define BCMIPXOTP	1
+#endif
+
+#define OTPTYPE_HND(ccrev)	((ccrev) < 21 || (ccrev) == 22)
+#define OTPTYPE_IPX(ccrev)	((ccrev) == 21 || (ccrev) >= 23)
+
+#define OTPP_TRIES	10000000	/* # of tries for OTPP */
+
+#ifdef BCMIPXOTP
+#define MAXNUMRDES		9	/* Maximum OTP redundancy entries */
+#endif
+
+/* OTP common function type */
+typedef int (*otp_status_t) (void *oh);
+typedef int (*otp_size_t) (void *oh);
+typedef void *(*otp_init_t) (si_t *sih);
+typedef u16(*otp_read_bit_t) (void *oh, chipcregs_t *cc, uint off);
+typedef int (*otp_read_region_t) (si_t *sih, int region, u16 *data,
+				  uint *wlen);
+typedef int (*otp_nvread_t) (void *oh, char *data, uint *len);
+
+/* OTP function struct */
+typedef struct otp_fn_s {
+	otp_size_t size;
+	otp_read_bit_t read_bit;
+	otp_init_t init;
+	otp_read_region_t read_region;
+	otp_nvread_t nvread;
+	otp_status_t status;
+} otp_fn_t;
+
+typedef struct {
+	uint ccrev;		/* chipc revision */
+	otp_fn_t *fn;		/* OTP functions */
+	si_t *sih;		/* Saved sb handle */
+
+#ifdef BCMIPXOTP
+	/* IPX OTP section */
+	u16 wsize;		/* Size of otp in words */
+	u16 rows;		/* Geometry */
+	u16 cols;		/* Geometry */
+	u32 status;		/* Flag bits (lock/prog/rv).
+				 * (Reflected only when OTP is power cycled)
+				 */
+	u16 hwbase;		/* hardware subregion offset */
+	u16 hwlim;		/* hardware subregion boundary */
+	u16 swbase;		/* software subregion offset */
+	u16 swlim;		/* software subregion boundary */
+	u16 fbase;		/* fuse subregion offset */
+	u16 flim;		/* fuse subregion boundary */
+	int otpgu_base;		/* offset to General Use Region */
+#endif				/* BCMIPXOTP */
+
+#ifdef BCMHNDOTP
+	/* HND OTP section */
+	uint size;		/* Size of otp in bytes */
+	uint hwprot;		/* Hardware protection bits */
+	uint signvalid;		/* Signature valid bits */
+	int boundary;		/* hw/sw boundary */
+#endif				/* BCMHNDOTP */
+} otpinfo_t;
+
+static otpinfo_t otpinfo;
+
+/*
+ * IPX OTP Code
+ *
+ *   Exported functions:
+ *	ipxotp_status()
+ *	ipxotp_size()
+ *	ipxotp_init()
+ *	ipxotp_read_bit()
+ *	ipxotp_read_region()
+ *	ipxotp_nvread()
+ *
+ */
+
+#ifdef BCMIPXOTP
+
+#define HWSW_RGN(rgn)		(((rgn) == OTP_HW_RGN) ? "h/w" : "s/w")
+
+/* OTP layout */
+/* CC revs 21, 24 and 27 OTP General Use Region word offset */
+#define REVA4_OTPGU_BASE	12
+
+/* CC revs 23, 25, 26, 28 and above OTP General Use Region word offset */
+#define REVB8_OTPGU_BASE	20
+
+/* CC rev 36 OTP General Use Region word offset */
+#define REV36_OTPGU_BASE	12
+
+/* Subregion word offsets in General Use region */
+#define OTPGU_HSB_OFF		0
+#define OTPGU_SFB_OFF		1
+#define OTPGU_CI_OFF		2
+#define OTPGU_P_OFF		3
+#define OTPGU_SROM_OFF		4
+
+/* Flag bit offsets in General Use region  */
+#define OTPGU_HWP_OFF		60
+#define OTPGU_SWP_OFF		61
+#define OTPGU_CIP_OFF		62
+#define OTPGU_FUSEP_OFF		63
+#define OTPGU_CIP_MSK		0x4000
+#define OTPGU_P_MSK		0xf000
+#define OTPGU_P_SHIFT		(OTPGU_HWP_OFF % 16)
+
+/* OTP Size */
+#define OTP_SZ_FU_324		((roundup(324, 8))/8)	/* 324 bits */
+#define OTP_SZ_FU_288		(288/8)	/* 288 bits */
+#define OTP_SZ_FU_216		(216/8)	/* 216 bits */
+#define OTP_SZ_FU_72		(72/8)	/* 72 bits */
+#define OTP_SZ_CHECKSUM		(16/8)	/* 16 bits */
+#define OTP4315_SWREG_SZ	178	/* 178 bytes */
+#define OTP_SZ_FU_144		(144/8)	/* 144 bits */
+
+static int ipxotp_status(void *oh)
+{
+	otpinfo_t *oi = (otpinfo_t *) oh;
+	return (int)(oi->status);
+}
+
+/* Return size in bytes */
+static int ipxotp_size(void *oh)
+{
+	otpinfo_t *oi = (otpinfo_t *) oh;
+	return (int)oi->wsize * 2;
+}
+
+static u16 ipxotp_otpr(void *oh, chipcregs_t *cc, uint wn)
+{
+	otpinfo_t *oi;
+
+	oi = (otpinfo_t *) oh;
+
+	return R_REG(&cc->sromotp[wn]);
+}
+
+static u16 ipxotp_read_bit(void *oh, chipcregs_t *cc, uint off)
+{
+	otpinfo_t *oi = (otpinfo_t *) oh;
+	uint k, row, col;
+	u32 otpp, st;
+
+	row = off / oi->cols;
+	col = off % oi->cols;
+
+	otpp = OTPP_START_BUSY |
+	    ((OTPPOC_READ << OTPP_OC_SHIFT) & OTPP_OC_MASK) |
+	    ((row << OTPP_ROW_SHIFT) & OTPP_ROW_MASK) |
+	    ((col << OTPP_COL_SHIFT) & OTPP_COL_MASK);
+	W_REG(&cc->otpprog, otpp);
+
+	for (k = 0;
+	     ((st = R_REG(&cc->otpprog)) & OTPP_START_BUSY)
+	     && (k < OTPP_TRIES); k++)
+		;
+	if (k >= OTPP_TRIES) {
+		return 0xffff;
+	}
+	if (st & OTPP_READERR) {
+		return 0xffff;
+	}
+	st = (st & OTPP_VALUE_MASK) >> OTPP_VALUE_SHIFT;
+
+	return (int)st;
+}
+
+/* Calculate max HW/SW region byte size by subtracting fuse region and checksum size,
+ * osizew is oi->wsize (OTP size - GU size) in words
+ */
+static int ipxotp_max_rgnsz(si_t *sih, int osizew)
+{
+	int ret = 0;
+
+	switch (sih->chip) {
+	case BCM43224_CHIP_ID:
+	case BCM43225_CHIP_ID:
+		ret = osizew * 2 - OTP_SZ_FU_72 - OTP_SZ_CHECKSUM;
+		break;
+	case BCM4313_CHIP_ID:
+		ret = osizew * 2 - OTP_SZ_FU_72 - OTP_SZ_CHECKSUM;
+		break;
+	default:
+		break;	/* Don't know about this chip */
+	}
+
+	return ret;
+}
+
+static void _ipxotp_init(otpinfo_t *oi, chipcregs_t *cc)
+{
+	uint k;
+	u32 otpp, st;
+
+	/* record word offset of General Use Region for various chipcommon revs */
+	if (oi->sih->ccrev == 21 || oi->sih->ccrev == 24
+	    || oi->sih->ccrev == 27) {
+		oi->otpgu_base = REVA4_OTPGU_BASE;
+	} else if (oi->sih->ccrev == 36) {
+		/* OTP size greater than equal to 2KB (128 words), otpgu_base is similar to rev23 */
+		if (oi->wsize >= 128)
+			oi->otpgu_base = REVB8_OTPGU_BASE;
+		else
+			oi->otpgu_base = REV36_OTPGU_BASE;
+	} else if (oi->sih->ccrev == 23 || oi->sih->ccrev >= 25) {
+		oi->otpgu_base = REVB8_OTPGU_BASE;
+	}
+
+	/* First issue an init command so the status is up to date */
+	otpp =
+	    OTPP_START_BUSY | ((OTPPOC_INIT << OTPP_OC_SHIFT) & OTPP_OC_MASK);
+
+	W_REG(&cc->otpprog, otpp);
+	for (k = 0;
+	     ((st = R_REG(&cc->otpprog)) & OTPP_START_BUSY)
+	     && (k < OTPP_TRIES); k++)
+		;
+	if (k >= OTPP_TRIES) {
+		return;
+	}
+
+	/* Read OTP lock bits and subregion programmed indication bits */
+	oi->status = R_REG(&cc->otpstatus);
+
+	if ((oi->sih->chip == BCM43224_CHIP_ID)
+	    || (oi->sih->chip == BCM43225_CHIP_ID)) {
+		u32 p_bits;
+		p_bits =
+		    (ipxotp_otpr(oi, cc, oi->otpgu_base + OTPGU_P_OFF) &
+		     OTPGU_P_MSK)
+		    >> OTPGU_P_SHIFT;
+		oi->status |= (p_bits << OTPS_GUP_SHIFT);
+	}
+
+	/*
+	 * h/w region base and fuse region limit are fixed to the top and
+	 * the bottom of the general use region. Everything else can be flexible.
+	 */
+	oi->hwbase = oi->otpgu_base + OTPGU_SROM_OFF;
+	oi->hwlim = oi->wsize;
+	if (oi->status & OTPS_GUP_HW) {
+		oi->hwlim =
+		    ipxotp_otpr(oi, cc, oi->otpgu_base + OTPGU_HSB_OFF) / 16;
+		oi->swbase = oi->hwlim;
+	} else
+		oi->swbase = oi->hwbase;
+
+	/* subtract fuse and checksum from beginning */
+	oi->swlim = ipxotp_max_rgnsz(oi->sih, oi->wsize) / 2;
+
+	if (oi->status & OTPS_GUP_SW) {
+		oi->swlim =
+		    ipxotp_otpr(oi, cc, oi->otpgu_base + OTPGU_SFB_OFF) / 16;
+		oi->fbase = oi->swlim;
+	} else
+		oi->fbase = oi->swbase;
+
+	oi->flim = oi->wsize;
+}
+
+static void *ipxotp_init(si_t *sih)
+{
+	uint idx;
+	chipcregs_t *cc;
+	otpinfo_t *oi;
+
+	/* Make sure we're running IPX OTP */
+	if (!OTPTYPE_IPX(sih->ccrev))
+		return NULL;
+
+	/* Make sure OTP is not disabled */
+	if (ai_is_otp_disabled(sih))
+		return NULL;
+
+	/* Make sure OTP is powered up */
+	if (!ai_is_otp_powered(sih))
+		return NULL;
+
+	oi = &otpinfo;
+
+	/* Check for otp size */
+	switch ((sih->cccaps & CC_CAP_OTPSIZE) >> CC_CAP_OTPSIZE_SHIFT) {
+	case 0:
+		/* Nothing there */
+		return NULL;
+	case 1:		/* 32x64 */
+		oi->rows = 32;
+		oi->cols = 64;
+		oi->wsize = 128;
+		break;
+	case 2:		/* 64x64 */
+		oi->rows = 64;
+		oi->cols = 64;
+		oi->wsize = 256;
+		break;
+	case 5:		/* 96x64 */
+		oi->rows = 96;
+		oi->cols = 64;
+		oi->wsize = 384;
+		break;
+	case 7:		/* 16x64 *//* 1024 bits */
+		oi->rows = 16;
+		oi->cols = 64;
+		oi->wsize = 64;
+		break;
+	default:
+		/* Don't know the geometry */
+		return NULL;
+	}
+
+	/* Retrieve OTP region info */
+	idx = ai_coreidx(sih);
+	cc = ai_setcoreidx(sih, SI_CC_IDX);
+
+	_ipxotp_init(oi, cc);
+
+	ai_setcoreidx(sih, idx);
+
+	return (void *)oi;
+}
+
+static int ipxotp_read_region(void *oh, int region, u16 *data, uint *wlen)
+{
+	otpinfo_t *oi = (otpinfo_t *) oh;
+	uint idx;
+	chipcregs_t *cc;
+	uint base, i, sz;
+
+	/* Validate region selection */
+	switch (region) {
+	case OTP_HW_RGN:
+		sz = (uint) oi->hwlim - oi->hwbase;
+		if (!(oi->status & OTPS_GUP_HW)) {
+			*wlen = sz;
+			return -ENODATA;
+		}
+		if (*wlen < sz) {
+			*wlen = sz;
+			return -EOVERFLOW;
+		}
+		base = oi->hwbase;
+		break;
+	case OTP_SW_RGN:
+		sz = ((uint) oi->swlim - oi->swbase);
+		if (!(oi->status & OTPS_GUP_SW)) {
+			*wlen = sz;
+			return -ENODATA;
+		}
+		if (*wlen < sz) {
+			*wlen = sz;
+			return -EOVERFLOW;
+		}
+		base = oi->swbase;
+		break;
+	case OTP_CI_RGN:
+		sz = OTPGU_CI_SZ;
+		if (!(oi->status & OTPS_GUP_CI)) {
+			*wlen = sz;
+			return -ENODATA;
+		}
+		if (*wlen < sz) {
+			*wlen = sz;
+			return -EOVERFLOW;
+		}
+		base = oi->otpgu_base + OTPGU_CI_OFF;
+		break;
+	case OTP_FUSE_RGN:
+		sz = (uint) oi->flim - oi->fbase;
+		if (!(oi->status & OTPS_GUP_FUSE)) {
+			*wlen = sz;
+			return -ENODATA;
+		}
+		if (*wlen < sz) {
+			*wlen = sz;
+			return -EOVERFLOW;
+		}
+		base = oi->fbase;
+		break;
+	case OTP_ALL_RGN:
+		sz = ((uint) oi->flim - oi->hwbase);
+		if (!(oi->status & (OTPS_GUP_HW | OTPS_GUP_SW))) {
+			*wlen = sz;
+			return -ENODATA;
+		}
+		if (*wlen < sz) {
+			*wlen = sz;
+			return -EOVERFLOW;
+		}
+		base = oi->hwbase;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	idx = ai_coreidx(oi->sih);
+	cc = ai_setcoreidx(oi->sih, SI_CC_IDX);
+
+	/* Read the data */
+	for (i = 0; i < sz; i++)
+		data[i] = ipxotp_otpr(oh, cc, base + i);
+
+	ai_setcoreidx(oi->sih, idx);
+	*wlen = sz;
+	return 0;
+}
+
+static int ipxotp_nvread(void *oh, char *data, uint *len)
+{
+	return -ENOTSUPP;
+}
+
+static otp_fn_t ipxotp_fn = {
+	(otp_size_t) ipxotp_size,
+	(otp_read_bit_t) ipxotp_read_bit,
+
+	(otp_init_t) ipxotp_init,
+	(otp_read_region_t) ipxotp_read_region,
+	(otp_nvread_t) ipxotp_nvread,
+
+	(otp_status_t) ipxotp_status
+};
+
+#endif				/* BCMIPXOTP */
+
+/*
+ * HND OTP Code
+ *
+ *   Exported functions:
+ *	hndotp_status()
+ *	hndotp_size()
+ *	hndotp_init()
+ *	hndotp_read_bit()
+ *	hndotp_read_region()
+ *	hndotp_nvread()
+ *
+ */
+
+#ifdef BCMHNDOTP
+
+/* Fields in otpstatus */
+#define	OTPS_PROGFAIL		0x80000000
+#define	OTPS_PROTECT		0x00000007
+#define	OTPS_HW_PROTECT		0x00000001
+#define	OTPS_SW_PROTECT		0x00000002
+#define	OTPS_CID_PROTECT	0x00000004
+#define	OTPS_RCEV_MSK		0x00003f00
+#define	OTPS_RCEV_SHIFT		8
+
+/* Fields in the otpcontrol register */
+#define	OTPC_RECWAIT		0xff000000
+#define	OTPC_PROGWAIT		0x00ffff00
+#define	OTPC_PRW_SHIFT		8
+#define	OTPC_MAXFAIL		0x00000038
+#define	OTPC_VSEL		0x00000006
+#define	OTPC_SELVL		0x00000001
+
+/* OTP regions (Word offsets from otp size) */
+#define	OTP_SWLIM_OFF	(-4)
+#define	OTP_CIDBASE_OFF	0
+#define	OTP_CIDLIM_OFF	4
+
+/* Predefined OTP words (Word offset from otp size) */
+#define	OTP_BOUNDARY_OFF (-4)
+#define	OTP_HWSIGN_OFF	(-3)
+#define	OTP_SWSIGN_OFF	(-2)
+#define	OTP_CIDSIGN_OFF	(-1)
+#define	OTP_CID_OFF	0
+#define	OTP_PKG_OFF	1
+#define	OTP_FID_OFF	2
+#define	OTP_RSV_OFF	3
+#define	OTP_LIM_OFF	4
+#define	OTP_RD_OFF	4	/* Redundancy row starts here */
+#define	OTP_RC0_OFF	28	/* Redundancy control word 1 */
+#define	OTP_RC1_OFF	32	/* Redundancy control word 2 */
+#define	OTP_RC_LIM_OFF	36	/* Redundancy control word end */
+
+#define	OTP_HW_REGION	OTPS_HW_PROTECT
+#define	OTP_SW_REGION	OTPS_SW_PROTECT
+#define	OTP_CID_REGION	OTPS_CID_PROTECT
+
+#if OTP_HW_REGION != OTP_HW_RGN
+#error "incompatible OTP_HW_RGN"
+#endif
+#if OTP_SW_REGION != OTP_SW_RGN
+#error "incompatible OTP_SW_RGN"
+#endif
+#if OTP_CID_REGION != OTP_CI_RGN
+#error "incompatible OTP_CI_RGN"
+#endif
+
+/* Redundancy entry definitions */
+#define	OTP_RCE_ROW_SZ		6
+#define	OTP_RCE_SIGN_MASK	0x7fff
+#define	OTP_RCE_ROW_MASK	0x3f
+#define	OTP_RCE_BITS		21
+#define	OTP_RCE_SIGN_SZ		15
+#define	OTP_RCE_BIT0		1
+
+#define	OTP_WPR		4
+#define	OTP_SIGNATURE	0x578a
+#define	OTP_MAGIC	0x4e56
+
+static int hndotp_status(void *oh)
+{
+	otpinfo_t *oi = (otpinfo_t *) oh;
+	return (int)(oi->hwprot | oi->signvalid);
+}
+
+static int hndotp_size(void *oh)
+{
+	otpinfo_t *oi = (otpinfo_t *) oh;
+	return (int)(oi->size);
+}
+
+static u16 hndotp_otpr(void *oh, chipcregs_t *cc, uint wn)
+{
+	volatile u16 *ptr;
+
+	ptr = (volatile u16 *)((volatile char *)cc + CC_SROM_OTP);
+	return R_REG(&ptr[wn]);
+}
+
+static u16 hndotp_otproff(void *oh, chipcregs_t *cc, int woff)
+{
+	otpinfo_t *oi = (otpinfo_t *) oh;
+	volatile u16 *ptr;
+
+	ptr = (volatile u16 *)((volatile char *)cc + CC_SROM_OTP);
+
+	return R_REG(&ptr[(oi->size / 2) + woff]);
+}
+
+static u16 hndotp_read_bit(void *oh, chipcregs_t *cc, uint idx)
+{
+	uint k, row, col;
+	u32 otpp, st;
+
+	row = idx / 65;
+	col = idx % 65;
+
+	otpp = OTPP_START_BUSY | OTPP_READ |
+	    ((row << OTPP_ROW_SHIFT) & OTPP_ROW_MASK) | (col & OTPP_COL_MASK);
+
+	W_REG(&cc->otpprog, otpp);
+	st = R_REG(&cc->otpprog);
+	for (k = 0;
+	     ((st & OTPP_START_BUSY) == OTPP_START_BUSY) && (k < OTPP_TRIES);
+	     k++)
+		st = R_REG(&cc->otpprog);
+
+	if (k >= OTPP_TRIES) {
+		return 0xffff;
+	}
+	if (st & OTPP_READERR) {
+		return 0xffff;
+	}
+	st = (st & OTPP_VALUE_MASK) >> OTPP_VALUE_SHIFT;
+	return (u16) st;
+}
+
+static void *hndotp_init(si_t *sih)
+{
+	uint idx;
+	chipcregs_t *cc;
+	otpinfo_t *oi;
+	u32 cap = 0, clkdiv, otpdiv = 0;
+	void *ret = NULL;
+
+	oi = &otpinfo;
+
+	idx = ai_coreidx(sih);
+
+	/* Check for otp */
+	cc = ai_setcoreidx(sih, SI_CC_IDX);
+	if (cc != NULL) {
+		cap = R_REG(&cc->capabilities);
+		if ((cap & CC_CAP_OTPSIZE) == 0) {
+			/* Nothing there */
+			goto out;
+		}
+
+		if (!((oi->ccrev == 12) || (oi->ccrev == 17)
+		     || (oi->ccrev == 22)))
+			return NULL;
+
+		/* Read the OTP byte size. chipcommon rev >= 18 has RCE so the size is
+		 * 8 row (64 bytes) smaller
+		 */
+		oi->size =
+		    1 << (((cap & CC_CAP_OTPSIZE) >> CC_CAP_OTPSIZE_SHIFT)
+			  + CC_CAP_OTPSIZE_BASE);
+		if (oi->ccrev >= 18)
+			oi->size -= ((OTP_RC0_OFF - OTP_BOUNDARY_OFF) * 2);
+
+		oi->hwprot = (int)(R_REG(&cc->otpstatus) & OTPS_PROTECT);
+		oi->boundary = -1;
+
+		/* Check the region signature */
+		if (hndotp_otproff(oi, cc, OTP_HWSIGN_OFF) == OTP_SIGNATURE) {
+			oi->signvalid |= OTP_HW_REGION;
+			oi->boundary = hndotp_otproff(oi, cc, OTP_BOUNDARY_OFF);
+		}
+
+		if (hndotp_otproff(oi, cc, OTP_SWSIGN_OFF) == OTP_SIGNATURE)
+			oi->signvalid |= OTP_SW_REGION;
+
+		if (hndotp_otproff(oi, cc, OTP_CIDSIGN_OFF) == OTP_SIGNATURE)
+			oi->signvalid |= OTP_CID_REGION;
+
+		/* Set OTP clkdiv for stability */
+		if (oi->ccrev == 22)
+			otpdiv = 12;
+
+		if (otpdiv) {
+			clkdiv = R_REG(&cc->clkdiv);
+			clkdiv =
+			    (clkdiv & ~CLKD_OTP) | (otpdiv << CLKD_OTP_SHIFT);
+			W_REG(&cc->clkdiv, clkdiv);
+		}
+		udelay(10);
+
+		ret = (void *)oi;
+	}
+
+ out:				/* All done */
+	ai_setcoreidx(sih, idx);
+
+	return ret;
+}
+
+static int hndotp_read_region(void *oh, int region, u16 *data, uint *wlen)
+{
+	otpinfo_t *oi = (otpinfo_t *) oh;
+	u32 idx, st;
+	chipcregs_t *cc;
+	int i;
+
+
+	if (region != OTP_HW_REGION) {
+		/*
+		 * Only support HW region
+		 * (no active chips use HND OTP SW region)
+		 * */
+		return -ENOTSUPP;
+	}
+
+	/* Region empty? */
+	st = oi->hwprot | oi->signvalid;
+	if ((st & region) == 0)
+		return -ENODATA;
+
+	*wlen =
+	    ((int)*wlen < oi->boundary / 2) ? *wlen : (uint) oi->boundary / 2;
+
+	idx = ai_coreidx(oi->sih);
+	cc = ai_setcoreidx(oi->sih, SI_CC_IDX);
+
+	for (i = 0; i < (int)*wlen; i++)
+		data[i] = hndotp_otpr(oh, cc, i);
+
+	ai_setcoreidx(oi->sih, idx);
+
+	return 0;
+}
+
+static int hndotp_nvread(void *oh, char *data, uint *len)
+{
+	int rc = 0;
+	otpinfo_t *oi = (otpinfo_t *) oh;
+	u32 base, bound, lim = 0, st;
+	int i, chunk, gchunks, tsz = 0;
+	u32 idx;
+	chipcregs_t *cc;
+	uint offset;
+	u16 *rawotp = NULL;
+
+	/* save the orig core */
+	idx = ai_coreidx(oi->sih);
+	cc = ai_setcoreidx(oi->sih, SI_CC_IDX);
+
+	st = hndotp_status(oh);
+	if (!(st & (OTP_HW_REGION | OTP_SW_REGION))) {
+		rc = -1;
+		goto out;
+	}
+
+	/* Read the whole otp so we can easily manipulate it */
+	lim = hndotp_size(oh);
+	rawotp = kmalloc(lim, GFP_ATOMIC);
+	if (rawotp == NULL) {
+		rc = -2;
+		goto out;
+	}
+	for (i = 0; i < (int)(lim / 2); i++)
+		rawotp[i] = hndotp_otpr(oh, cc, i);
+
+	if ((st & OTP_HW_REGION) == 0) {
+		/* This could be a programming failure in the first
+		 * chunk followed by one or more good chunks
+		 */
+		for (i = 0; i < (int)(lim / 2); i++)
+			if (rawotp[i] == OTP_MAGIC)
+				break;
+
+		if (i < (int)(lim / 2)) {
+			base = i;
+			bound = (i * 2) + rawotp[i + 1];
+		} else {
+			rc = -3;
+			goto out;
+		}
+	} else {
+		bound = rawotp[(lim / 2) + OTP_BOUNDARY_OFF];
+
+		/* There are two cases: 1) The whole otp is used as nvram
+		 * and 2) There is a hardware header followed by nvram.
+		 */
+		if (rawotp[0] == OTP_MAGIC) {
+			base = 0;
+		} else
+			base = bound;
+	}
+
+	/* Find and copy the data */
+
+	chunk = 0;
+	gchunks = 0;
+	i = base / 2;
+	offset = 0;
+	while ((i < (int)(lim / 2)) && (rawotp[i] == OTP_MAGIC)) {
+		int dsz, rsz = rawotp[i + 1];
+
+		if (((i * 2) + rsz) >= (int)lim) {
+			/* Bad length, try to find another chunk anyway */
+			rsz = 6;
+		}
+		if (crc_ccitt(CRC16_INIT_VALUE, (u8 *) &rawotp[i], rsz) ==
+			CRC16_GOOD_VALUE) {
+			/* Good crc, copy the vars */
+			gchunks++;
+			dsz = rsz - 6;
+			tsz += dsz;
+			if (offset + dsz >= *len) {
+				goto out;
+			}
+			memcpy(&data[offset], &rawotp[i + 2], dsz);
+			offset += dsz;
+			/* Remove extra null characters at the end */
+			while (offset > 1 &&
+			       data[offset - 1] == 0 && data[offset - 2] == 0)
+				offset--;
+			i += rsz / 2;
+		} else {
+			/* bad length or crc didn't check, try to find the next set */
+			if (rawotp[i + (rsz / 2)] == OTP_MAGIC) {
+				/* Assume length is good */
+				i += rsz / 2;
+			} else {
+				while (++i < (int)(lim / 2))
+					if (rawotp[i] == OTP_MAGIC)
+						break;
+			}
+		}
+		chunk++;
+	}
+
+	*len = offset;
+
+ out:
+	kfree(rawotp);
+	ai_setcoreidx(oi->sih, idx);
+
+	return rc;
+}
+
+static otp_fn_t hndotp_fn = {
+	(otp_size_t) hndotp_size,
+	(otp_read_bit_t) hndotp_read_bit,
+
+	(otp_init_t) hndotp_init,
+	(otp_read_region_t) hndotp_read_region,
+	(otp_nvread_t) hndotp_nvread,
+
+	(otp_status_t) hndotp_status
+};
+
+#endif				/* BCMHNDOTP */
+
+/*
+ * Common Code: Compiled for IPX / HND / AUTO
+ *	otp_status()
+ *	otp_size()
+ *	otp_read_bit()
+ *	otp_init()
+ * 	otp_read_region()
+ * 	otp_nvread()
+ */
+
+int otp_status(void *oh)
+{
+	otpinfo_t *oi = (otpinfo_t *) oh;
+
+	return oi->fn->status(oh);
+}
+
+int otp_size(void *oh)
+{
+	otpinfo_t *oi = (otpinfo_t *) oh;
+
+	return oi->fn->size(oh);
+}
+
+u16 otp_read_bit(void *oh, uint offset)
+{
+	otpinfo_t *oi = (otpinfo_t *) oh;
+	uint idx = ai_coreidx(oi->sih);
+	chipcregs_t *cc = ai_setcoreidx(oi->sih, SI_CC_IDX);
+	u16 readBit = (u16) oi->fn->read_bit(oh, cc, offset);
+	ai_setcoreidx(oi->sih, idx);
+	return readBit;
+}
+
+void *otp_init(si_t *sih)
+{
+	otpinfo_t *oi;
+	void *ret = NULL;
+
+	oi = &otpinfo;
+	memset(oi, 0, sizeof(otpinfo_t));
+
+	oi->ccrev = sih->ccrev;
+
+#ifdef BCMIPXOTP
+	if (OTPTYPE_IPX(oi->ccrev))
+		oi->fn = &ipxotp_fn;
+#endif
+
+#ifdef BCMHNDOTP
+	if (OTPTYPE_HND(oi->ccrev))
+		oi->fn = &hndotp_fn;
+#endif
+
+	if (oi->fn == NULL) {
+		return NULL;
+	}
+
+	oi->sih = sih;
+
+	ret = (oi->fn->init) (sih);
+
+	return ret;
+}
+
+int
+otp_read_region(si_t *sih, int region, u16 *data,
+				 uint *wlen) {
+	bool wasup = false;
+	void *oh;
+	int err = 0;
+
+	wasup = ai_is_otp_powered(sih);
+	if (!wasup)
+		ai_otp_power(sih, true);
+
+	if (!ai_is_otp_powered(sih) || ai_is_otp_disabled(sih)) {
+		err = -EPERM;
+		goto out;
+	}
+
+	oh = otp_init(sih);
+	if (oh == NULL) {
+		err = -EBADE;
+		goto out;
+	}
+
+	err = (((otpinfo_t *) oh)->fn->read_region) (oh, region, data, wlen);
+
+ out:
+	if (!wasup)
+		ai_otp_power(sih, false);
+
+	return err;
+}
+
+int otp_nvread(void *oh, char *data, uint *len)
+{
+	otpinfo_t *oi = (otpinfo_t *) oh;
+
+	return oi->fn->nvread(oh, data, len);
+}
diff -druN linux-2.6.39-libre/drivers/staging/brcm80211/brcmsmac/bcmsrom.c linux-3.0-rc7-libre/drivers/staging/brcm80211/brcmsmac/bcmsrom.c
--- linux-2.6.39-libre/drivers/staging/brcm80211/brcmsmac/bcmsrom.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/staging/brcm80211/brcmsmac/bcmsrom.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,714 @@
+/*
+ * Copyright (c) 2010 Broadcom Corporation
+ *
+ * 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/kernel.h>
+#include <linux/string.h>
+#include <linux/etherdevice.h>
+#include <bcmdefs.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <stdarg.h>
+#include <bcmutils.h>
+#include <hndsoc.h>
+#include <sbchipc.h>
+#include <bcmdevs.h>
+#include <pcicfg.h>
+#include <aiutils.h>
+#include <bcmsrom.h>
+#include <bcmsrom_tbl.h>
+
+#include <bcmnvram.h>
+#include <bcmotp.h>
+
+#define SROM_OFFSET(sih) ((sih->ccrev > 31) ? \
+	(((sih->cccaps & CC_CAP_SROM) == 0) ? NULL : \
+	 ((u8 *)curmap + PCI_16KB0_CCREGS_OFFSET + CC_SROM_OTP)) : \
+	((u8 *)curmap + PCI_BAR0_SPROM_OFFSET))
+
+#if defined(BCMDBG)
+#define WRITE_ENABLE_DELAY	500	/* 500 ms after write enable/disable toggle */
+#define WRITE_WORD_DELAY	20	/* 20 ms between each word write */
+#endif
+
+typedef struct varbuf {
+	char *base;		/* pointer to buffer base */
+	char *buf;		/* pointer to current position */
+	unsigned int size;	/* current (residual) size in bytes */
+} varbuf_t;
+extern char *_vars;
+extern uint _varsz;
+
+static int initvars_srom_si(si_t *sih, void *curmap, char **vars, uint *count);
+static void _initvars_srom_pci(u8 sromrev, u16 *srom, uint off, varbuf_t *b);
+static int initvars_srom_pci(si_t *sih, void *curmap, char **vars, uint *count);
+static int initvars_flash_si(si_t *sih, char **vars, uint *count);
+static int sprom_read_pci(si_t *sih, u16 *sprom,
+			  uint wordoff, u16 *buf, uint nwords, bool check_crc);
+#if defined(BCMNVRAMR)
+static int otp_read_pci(si_t *sih, u16 *buf, uint bufsz);
+#endif
+static u16 srom_cc_cmd(si_t *sih, void *ccregs, u32 cmd,
+			  uint wordoff, u16 data);
+
+static int initvars_table(char *start, char *end,
+			  char **vars, uint *count);
+static int initvars_flash(si_t *sih, char **vp,
+			  uint len);
+
+/* Initialization of varbuf structure */
+static void varbuf_init(varbuf_t *b, char *buf, uint size)
+{
+	b->size = size;
+	b->base = b->buf = buf;
+}
+
+/* append a null terminated var=value string */
+static int varbuf_append(varbuf_t *b, const char *fmt, ...)
+{
+	va_list ap;
+	int r;
+	size_t len;
+	char *s;
+
+	if (b->size < 2)
+		return 0;
+
+	va_start(ap, fmt);
+	r = vsnprintf(b->buf, b->size, fmt, ap);
+	va_end(ap);
+
+	/* C99 snprintf behavior returns r >= size on overflow,
+	 * others return -1 on overflow.
+	 * All return -1 on format error.
+	 * We need to leave room for 2 null terminations, one for the current var
+	 * string, and one for final null of the var table. So check that the
+	 * strlen written, r, leaves room for 2 chars.
+	 */
+	if ((r == -1) || (r > (int)(b->size - 2))) {
+		b->size = 0;
+		return 0;
+	}
+
+	/* Remove any earlier occurrence of the same variable */
+	s = strchr(b->buf, '=');
+	if (s != NULL) {
+		len = (size_t) (s - b->buf);
+		for (s = b->base; s < b->buf;) {
+			if ((memcmp(s, b->buf, len) == 0) && s[len] == '=') {
+				len = strlen(s) + 1;
+				memmove(s, (s + len),
+					((b->buf + r + 1) - (s + len)));
+				b->buf -= len;
+				b->size += (unsigned int)len;
+				break;
+			}
+
+			while (*s++)
+				;
+		}
+	}
+
+	/* skip over this string's null termination */
+	r++;
+	b->size -= r;
+	b->buf += r;
+
+	return r;
+}
+
+/*
+ * Initialize local vars from the right source for this platform.
+ * Return 0 on success, nonzero on error.
+ */
+int srom_var_init(si_t *sih, uint bustype, void *curmap,
+		  char **vars, uint *count)
+{
+	uint len;
+
+	len = 0;
+
+	if (vars == NULL || count == NULL)
+		return 0;
+
+	*vars = NULL;
+	*count = 0;
+
+	switch (bustype) {
+	case SI_BUS:
+	case JTAG_BUS:
+		return initvars_srom_si(sih, curmap, vars, count);
+
+	case PCI_BUS:
+		if (curmap == NULL)
+			return -1;
+
+		return initvars_srom_pci(sih, curmap, vars, count);
+
+	default:
+		break;
+	}
+	return -1;
+}
+
+/* In chips with chipcommon rev 32 and later, the srom is in chipcommon,
+ * not in the bus cores.
+ */
+static u16
+srom_cc_cmd(si_t *sih, void *ccregs, u32 cmd,
+	    uint wordoff, u16 data)
+{
+	chipcregs_t *cc = (chipcregs_t *) ccregs;
+	uint wait_cnt = 1000;
+
+	if ((cmd == SRC_OP_READ) || (cmd == SRC_OP_WRITE)) {
+		W_REG(&cc->sromaddress, wordoff * 2);
+		if (cmd == SRC_OP_WRITE)
+			W_REG(&cc->sromdata, data);
+	}
+
+	W_REG(&cc->sromcontrol, SRC_START | cmd);
+
+	while (wait_cnt--) {
+		if ((R_REG(&cc->sromcontrol) & SRC_BUSY) == 0)
+			break;
+	}
+
+	if (!wait_cnt) {
+		return 0xffff;
+	}
+	if (cmd == SRC_OP_READ)
+		return (u16) R_REG(&cc->sromdata);
+	else
+		return 0xffff;
+}
+
+static inline void ltoh16_buf(u16 *buf, unsigned int size)
+{
+	for (size /= 2; size; size--)
+		*(buf + size) = le16_to_cpu(*(buf + size));
+}
+
+static inline void htol16_buf(u16 *buf, unsigned int size)
+{
+	for (size /= 2; size; size--)
+		*(buf + size) = cpu_to_le16(*(buf + size));
+}
+
+/*
+ * Read in and validate sprom.
+ * Return 0 on success, nonzero on error.
+ */
+static int
+sprom_read_pci(si_t *sih, u16 *sprom, uint wordoff,
+	       u16 *buf, uint nwords, bool check_crc)
+{
+	int err = 0;
+	uint i;
+	void *ccregs = NULL;
+
+	/* read the sprom */
+	for (i = 0; i < nwords; i++) {
+
+		if (sih->ccrev > 31 && ISSIM_ENAB(sih)) {
+			/* use indirect since direct is too slow on QT */
+			if ((sih->cccaps & CC_CAP_SROM) == 0)
+				return 1;
+
+			ccregs = (void *)((u8 *) sprom - CC_SROM_OTP);
+			buf[i] =
+			    srom_cc_cmd(sih, ccregs, SRC_OP_READ,
+					wordoff + i, 0);
+
+		} else {
+			if (ISSIM_ENAB(sih))
+				buf[i] = R_REG(&sprom[wordoff + i]);
+
+			buf[i] = R_REG(&sprom[wordoff + i]);
+		}
+
+	}
+
+	/* bypass crc checking for simulation to allow srom hack */
+	if (ISSIM_ENAB(sih))
+		return err;
+
+	if (check_crc) {
+
+		if (buf[0] == 0xffff) {
+			/* The hardware thinks that an srom that starts with 0xffff
+			 * is blank, regardless of the rest of the content, so declare
+			 * it bad.
+			 */
+			return 1;
+		}
+
+		/* fixup the endianness so crc8 will pass */
+		htol16_buf(buf, nwords * 2);
+		if (bcm_crc8((u8 *) buf, nwords * 2, CRC8_INIT_VALUE) !=
+		    CRC8_GOOD_VALUE) {
+			/* DBG only pci always read srom4 first, then srom8/9 */
+			err = 1;
+		}
+		/* now correct the endianness of the byte array */
+		ltoh16_buf(buf, nwords * 2);
+	}
+	return err;
+}
+
+#if defined(BCMNVRAMR)
+static int otp_read_pci(si_t *sih, u16 *buf, uint bufsz)
+{
+	u8 *otp;
+	uint sz = OTP_SZ_MAX / 2;	/* size in words */
+	int err = 0;
+
+	otp = kzalloc(OTP_SZ_MAX, GFP_ATOMIC);
+	if (otp == NULL) {
+		return -EBADE;
+	}
+
+	err = otp_read_region(sih, OTP_HW_RGN, (u16 *) otp, &sz);
+
+	memcpy(buf, otp, bufsz);
+
+	kfree(otp);
+
+	/* Check CRC */
+	if (buf[0] == 0xffff) {
+		/* The hardware thinks that an srom that starts with 0xffff
+		 * is blank, regardless of the rest of the content, so declare
+		 * it bad.
+		 */
+		return 1;
+	}
+
+	/* fixup the endianness so crc8 will pass */
+	htol16_buf(buf, bufsz);
+	if (bcm_crc8((u8 *) buf, SROM4_WORDS * 2, CRC8_INIT_VALUE) !=
+	    CRC8_GOOD_VALUE) {
+		err = 1;
+	}
+	/* now correct the endianness of the byte array */
+	ltoh16_buf(buf, bufsz);
+
+	return err;
+}
+#endif				/* defined(BCMNVRAMR) */
+/*
+* Create variable table from memory.
+* Return 0 on success, nonzero on error.
+*/
+static int initvars_table(char *start, char *end,
+			  char **vars, uint *count)
+{
+	int c = (int)(end - start);
+
+	/* do it only when there is more than just the null string */
+	if (c > 1) {
+		char *vp = kmalloc(c, GFP_ATOMIC);
+		if (!vp)
+			return -ENOMEM;
+		memcpy(vp, start, c);
+		*vars = vp;
+		*count = c;
+	} else {
+		*vars = NULL;
+		*count = 0;
+	}
+
+	return 0;
+}
+
+/*
+ * Find variables with <devpath> from flash. 'base' points to the beginning
+ * of the table upon enter and to the end of the table upon exit when success.
+ * Return 0 on success, nonzero on error.
+ */
+static int initvars_flash(si_t *sih, char **base, uint len)
+{
+	char *vp = *base;
+	char *flash;
+	int err;
+	char *s;
+	uint l, dl, copy_len;
+	char devpath[SI_DEVPATH_BUFSZ];
+
+	/* allocate memory and read in flash */
+	flash = kmalloc(NVRAM_SPACE, GFP_ATOMIC);
+	if (!flash)
+		return -ENOMEM;
+	err = nvram_getall(flash, NVRAM_SPACE);
+	if (err)
+		goto exit;
+
+	ai_devpath(sih, devpath, sizeof(devpath));
+
+	/* grab vars with the <devpath> prefix in name */
+	dl = strlen(devpath);
+	for (s = flash; s && *s; s += l + 1) {
+		l = strlen(s);
+
+		/* skip non-matching variable */
+		if (strncmp(s, devpath, dl))
+			continue;
+
+		/* is there enough room to copy? */
+		copy_len = l - dl + 1;
+		if (len < copy_len) {
+			err = -EOVERFLOW;
+			goto exit;
+		}
+
+		/* no prefix, just the name=value */
+		strncpy(vp, &s[dl], copy_len);
+		vp += copy_len;
+		len -= copy_len;
+	}
+
+	/* add null string as terminator */
+	if (len < 1) {
+		err = -EOVERFLOW;
+		goto exit;
+	}
+	*vp++ = '\0';
+
+	*base = vp;
+
+ exit:	kfree(flash);
+	return err;
+}
+
+/*
+ * Initialize nonvolatile variable table from flash.
+ * Return 0 on success, nonzero on error.
+ */
+static int initvars_flash_si(si_t *sih, char **vars, uint *count)
+{
+	char *vp, *base;
+	int err;
+
+	base = vp = kmalloc(MAXSZ_NVRAM_VARS, GFP_ATOMIC);
+	if (!vp)
+		return -ENOMEM;
+
+	err = initvars_flash(sih, &vp, MAXSZ_NVRAM_VARS);
+	if (err == 0)
+		err = initvars_table(base, vp, vars, count);
+
+	kfree(base);
+
+	return err;
+}
+
+/* Parse SROM and create name=value pairs. 'srom' points to
+ * the SROM word array. 'off' specifies the offset of the
+ * first word 'srom' points to, which should be either 0 or
+ * SROM3_SWRG_OFF (full SROM or software region).
+ */
+
+static uint mask_shift(u16 mask)
+{
+	uint i;
+	for (i = 0; i < (sizeof(mask) << 3); i++) {
+		if (mask & (1 << i))
+			return i;
+	}
+	return 0;
+}
+
+static uint mask_width(u16 mask)
+{
+	int i;
+	for (i = (sizeof(mask) << 3) - 1; i >= 0; i--) {
+		if (mask & (1 << i))
+			return (uint) (i - mask_shift(mask) + 1);
+	}
+	return 0;
+}
+
+static void _initvars_srom_pci(u8 sromrev, u16 *srom, uint off, varbuf_t *b)
+{
+	u16 w;
+	u32 val;
+	const sromvar_t *srv;
+	uint width;
+	uint flags;
+	u32 sr = (1 << sromrev);
+
+	varbuf_append(b, "sromrev=%d", sromrev);
+
+	for (srv = pci_sromvars; srv->name != NULL; srv++) {
+		const char *name;
+
+		if ((srv->revmask & sr) == 0)
+			continue;
+
+		if (srv->off < off)
+			continue;
+
+		flags = srv->flags;
+		name = srv->name;
+
+		/* This entry is for mfgc only. Don't generate param for it, */
+		if (flags & SRFL_NOVAR)
+			continue;
+
+		if (flags & SRFL_ETHADDR) {
+			u8 ea[ETH_ALEN];
+
+			ea[0] = (srom[srv->off - off] >> 8) & 0xff;
+			ea[1] = srom[srv->off - off] & 0xff;
+			ea[2] = (srom[srv->off + 1 - off] >> 8) & 0xff;
+			ea[3] = srom[srv->off + 1 - off] & 0xff;
+			ea[4] = (srom[srv->off + 2 - off] >> 8) & 0xff;
+			ea[5] = srom[srv->off + 2 - off] & 0xff;
+
+			varbuf_append(b, "%s=%pM", name, ea);
+		} else {
+			w = srom[srv->off - off];
+			val = (w & srv->mask) >> mask_shift(srv->mask);
+			width = mask_width(srv->mask);
+
+			while (srv->flags & SRFL_MORE) {
+				srv++;
+				if (srv->off == 0 || srv->off < off)
+					continue;
+
+				w = srom[srv->off - off];
+				val +=
+				    ((w & srv->mask) >> mask_shift(srv->
+								   mask)) <<
+				    width;
+				width += mask_width(srv->mask);
+			}
+
+			if ((flags & SRFL_NOFFS)
+			    && ((int)val == (1 << width) - 1))
+				continue;
+
+			if (flags & SRFL_CCODE) {
+				if (val == 0)
+					varbuf_append(b, "ccode=");
+				else
+					varbuf_append(b, "ccode=%c%c",
+						      (val >> 8), (val & 0xff));
+			}
+			/* LED Powersave duty cycle has to be scaled:
+			 *(oncount >> 24) (offcount >> 8)
+			 */
+			else if (flags & SRFL_LEDDC) {
+				u32 w32 = (((val >> 8) & 0xff) << 24) |	/* oncount */
+				    (((val & 0xff)) << 8);	/* offcount */
+				varbuf_append(b, "leddc=%d", w32);
+			} else if (flags & SRFL_PRHEX)
+				varbuf_append(b, "%s=0x%x", name, val);
+			else if ((flags & SRFL_PRSIGN)
+				 && (val & (1 << (width - 1))))
+				varbuf_append(b, "%s=%d", name,
+					      (int)(val | (~0 << width)));
+			else
+				varbuf_append(b, "%s=%u", name, val);
+		}
+	}
+
+	if (sromrev >= 4) {
+		/* Do per-path variables */
+		uint p, pb, psz;
+
+		if (sromrev >= 8) {
+			pb = SROM8_PATH0;
+			psz = SROM8_PATH1 - SROM8_PATH0;
+		} else {
+			pb = SROM4_PATH0;
+			psz = SROM4_PATH1 - SROM4_PATH0;
+		}
+
+		for (p = 0; p < MAX_PATH_SROM; p++) {
+			for (srv = perpath_pci_sromvars; srv->name != NULL;
+			     srv++) {
+				if ((srv->revmask & sr) == 0)
+					continue;
+
+				if (pb + srv->off < off)
+					continue;
+
+				/* This entry is for mfgc only. Don't generate param for it, */
+				if (srv->flags & SRFL_NOVAR)
+					continue;
+
+				w = srom[pb + srv->off - off];
+				val = (w & srv->mask) >> mask_shift(srv->mask);
+				width = mask_width(srv->mask);
+
+				/* Cheating: no per-path var is more than 1 word */
+
+				if ((srv->flags & SRFL_NOFFS)
+				    && ((int)val == (1 << width) - 1))
+					continue;
+
+				if (srv->flags & SRFL_PRHEX)
+					varbuf_append(b, "%s%d=0x%x", srv->name,
+						      p, val);
+				else
+					varbuf_append(b, "%s%d=%d", srv->name,
+						      p, val);
+			}
+			pb += psz;
+		}
+	}
+}
+
+/*
+ * Initialize nonvolatile variable table from sprom.
+ * Return 0 on success, nonzero on error.
+ */
+static int initvars_srom_pci(si_t *sih, void *curmap, char **vars, uint *count)
+{
+	u16 *srom, *sromwindow;
+	u8 sromrev = 0;
+	u32 sr;
+	varbuf_t b;
+	char *vp, *base = NULL;
+	bool flash = false;
+	int err = 0;
+
+	/*
+	 * Apply CRC over SROM content regardless SROM is present or not,
+	 * and use variable <devpath>sromrev's existence in flash to decide
+	 * if we should return an error when CRC fails or read SROM variables
+	 * from flash.
+	 */
+	srom = kmalloc(SROM_MAX, GFP_ATOMIC);
+	if (!srom)
+		return -2;
+
+	sromwindow = (u16 *) SROM_OFFSET(sih);
+	if (ai_is_sprom_available(sih)) {
+		err =
+		    sprom_read_pci(sih, sromwindow, 0, srom, SROM_WORDS,
+				   true);
+
+		if ((srom[SROM4_SIGN] == SROM4_SIGNATURE) ||
+		    (((sih->buscoretype == PCIE_CORE_ID)
+		      && (sih->buscorerev >= 6))
+		     || ((sih->buscoretype == PCI_CORE_ID)
+			 && (sih->buscorerev >= 0xe)))) {
+			/* sromrev >= 4, read more */
+			err =
+			    sprom_read_pci(sih, sromwindow, 0, srom,
+					   SROM4_WORDS, true);
+			sromrev = srom[SROM4_CRCREV] & 0xff;
+		} else if (err == 0) {
+			/* srom is good and is rev < 4 */
+			/* top word of sprom contains version and crc8 */
+			sromrev = srom[SROM_CRCREV] & 0xff;
+			/* bcm4401 sroms misprogrammed */
+			if (sromrev == 0x10)
+				sromrev = 1;
+		}
+	}
+#if defined(BCMNVRAMR)
+	/* Use OTP if SPROM not available */
+	else {
+		err = otp_read_pci(sih, srom, SROM_MAX);
+		if (err == 0)
+			/* OTP only contain SROM rev8/rev9 for now */
+			sromrev = srom[SROM4_CRCREV] & 0xff;
+		else
+			err = 1;
+	}
+#else
+	else
+		err = 1;
+#endif
+
+	/*
+	 * We want internal/wltest driver to come up with default
+	 * sromvars so we can program a blank SPROM/OTP.
+	 */
+	if (err) {
+		char *value;
+		u32 val;
+		val = 0;
+
+		value = ai_getdevpathvar(sih, "sromrev");
+		if (value) {
+			sromrev = (u8) simple_strtoul(value, NULL, 0);
+			flash = true;
+			goto varscont;
+		}
+
+		value = ai_getnvramflvar(sih, "sromrev");
+		if (value) {
+			err = 0;
+			goto errout;
+		}
+
+		{
+			err = -1;
+			goto errout;
+		}
+	}
+
+ varscont:
+	/* Bitmask for the sromrev */
+	sr = 1 << sromrev;
+
+	/* srom version check: Current valid versions: 1, 2, 3, 4, 5, 8, 9 */
+	if ((sr & 0x33e) == 0) {
+		err = -2;
+		goto errout;
+	}
+
+	base = vp = kmalloc(MAXSZ_NVRAM_VARS, GFP_ATOMIC);
+	if (!vp) {
+		err = -2;
+		goto errout;
+	}
+
+	/* read variables from flash */
+	if (flash) {
+		err = initvars_flash(sih, &vp, MAXSZ_NVRAM_VARS);
+		if (err)
+			goto errout;
+		goto varsdone;
+	}
+
+	varbuf_init(&b, base, MAXSZ_NVRAM_VARS);
+
+	/* parse SROM into name=value pairs. */
+	_initvars_srom_pci(sromrev, srom, 0, &b);
+
+	/* final nullbyte terminator */
+	vp = b.buf;
+	*vp++ = '\0';
+
+ varsdone:
+	err = initvars_table(base, vp, vars, count);
+
+ errout:
+	if (base)
+		kfree(base);
+
+	kfree(srom);
+	return err;
+}
+
+
+static int initvars_srom_si(si_t *sih, void *curmap, char **vars, uint *varsz)
+{
+	/* Search flash nvram section for srom variables */
+	return initvars_flash_si(sih, vars, varsz);
+}
diff -druN linux-2.6.39-libre/drivers/staging/brcm80211/brcmsmac/bcmsrom_tbl.h linux-3.0-rc7-libre/drivers/staging/brcm80211/brcmsmac/bcmsrom_tbl.h
--- linux-2.6.39-libre/drivers/staging/brcm80211/brcmsmac/bcmsrom_tbl.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/staging/brcm80211/brcmsmac/bcmsrom_tbl.h	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,513 @@
+/*
+ * Copyright (c) 2010 Broadcom Corporation
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef	_bcmsrom_tbl_h_
+#define	_bcmsrom_tbl_h_
+
+#include "wlioctl.h"
+
+typedef struct {
+	const char *name;
+	u32 revmask;
+	u32 flags;
+	u16 off;
+	u16 mask;
+} sromvar_t;
+
+#define SRFL_MORE	1	/* value continues as described by the next entry */
+#define	SRFL_NOFFS	2	/* value bits can't be all one's */
+#define	SRFL_PRHEX	4	/* value is in hexdecimal format */
+#define	SRFL_PRSIGN	8	/* value is in signed decimal format */
+#define	SRFL_CCODE	0x10	/* value is in country code format */
+#define	SRFL_ETHADDR	0x20	/* value is an Ethernet address */
+#define SRFL_LEDDC	0x40	/* value is an LED duty cycle */
+#define SRFL_NOVAR	0x80	/* do not generate a nvram param, entry is for mfgc */
+
+/* Assumptions:
+ * - Ethernet address spans across 3 consective words
+ *
+ * Table rules:
+ * - Add multiple entries next to each other if a value spans across multiple words
+ *   (even multiple fields in the same word) with each entry except the last having
+ *   it's SRFL_MORE bit set.
+ * - Ethernet address entry does not follow above rule and must not have SRFL_MORE
+ *   bit set. Its SRFL_ETHADDR bit implies it takes multiple words.
+ * - The last entry's name field must be NULL to indicate the end of the table. Other
+ *   entries must have non-NULL name.
+ */
+
+static const sromvar_t pci_sromvars[] = {
+	{"devid", 0xffffff00, SRFL_PRHEX | SRFL_NOVAR, PCI_F0DEVID, 0xffff},
+	{"boardrev", 0x0000000e, SRFL_PRHEX, SROM_AABREV, SROM_BR_MASK},
+	{"boardrev", 0x000000f0, SRFL_PRHEX, SROM4_BREV, 0xffff},
+	{"boardrev", 0xffffff00, SRFL_PRHEX, SROM8_BREV, 0xffff},
+	{"boardflags", 0x00000002, SRFL_PRHEX, SROM_BFL, 0xffff},
+	{"boardflags", 0x00000004, SRFL_PRHEX | SRFL_MORE, SROM_BFL, 0xffff},
+	{"", 0, 0, SROM_BFL2, 0xffff},
+	{"boardflags", 0x00000008, SRFL_PRHEX | SRFL_MORE, SROM_BFL, 0xffff},
+	{"", 0, 0, SROM3_BFL2, 0xffff},
+	{"boardflags", 0x00000010, SRFL_PRHEX | SRFL_MORE, SROM4_BFL0, 0xffff},
+	{"", 0, 0, SROM4_BFL1, 0xffff},
+	{"boardflags", 0x000000e0, SRFL_PRHEX | SRFL_MORE, SROM5_BFL0, 0xffff},
+	{"", 0, 0, SROM5_BFL1, 0xffff},
+	{"boardflags", 0xffffff00, SRFL_PRHEX | SRFL_MORE, SROM8_BFL0, 0xffff},
+	{"", 0, 0, SROM8_BFL1, 0xffff},
+	{"boardflags2", 0x00000010, SRFL_PRHEX | SRFL_MORE, SROM4_BFL2, 0xffff},
+	{"", 0, 0, SROM4_BFL3, 0xffff},
+	{"boardflags2", 0x000000e0, SRFL_PRHEX | SRFL_MORE, SROM5_BFL2, 0xffff},
+	{"", 0, 0, SROM5_BFL3, 0xffff},
+	{"boardflags2", 0xffffff00, SRFL_PRHEX | SRFL_MORE, SROM8_BFL2, 0xffff},
+	{"", 0, 0, SROM8_BFL3, 0xffff},
+	{"boardtype", 0xfffffffc, SRFL_PRHEX, SROM_SSID, 0xffff},
+	{"boardnum", 0x00000006, 0, SROM_MACLO_IL0, 0xffff},
+	{"boardnum", 0x00000008, 0, SROM3_MACLO, 0xffff},
+	{"boardnum", 0x00000010, 0, SROM4_MACLO, 0xffff},
+	{"boardnum", 0x000000e0, 0, SROM5_MACLO, 0xffff},
+	{"boardnum", 0xffffff00, 0, SROM8_MACLO, 0xffff},
+	{"cc", 0x00000002, 0, SROM_AABREV, SROM_CC_MASK},
+	{"regrev", 0x00000008, 0, SROM_OPO, 0xff00},
+	{"regrev", 0x00000010, 0, SROM4_REGREV, 0x00ff},
+	{"regrev", 0x000000e0, 0, SROM5_REGREV, 0x00ff},
+	{"regrev", 0xffffff00, 0, SROM8_REGREV, 0x00ff},
+	{"ledbh0", 0x0000000e, SRFL_NOFFS, SROM_LEDBH10, 0x00ff},
+	{"ledbh1", 0x0000000e, SRFL_NOFFS, SROM_LEDBH10, 0xff00},
+	{"ledbh2", 0x0000000e, SRFL_NOFFS, SROM_LEDBH32, 0x00ff},
+	{"ledbh3", 0x0000000e, SRFL_NOFFS, SROM_LEDBH32, 0xff00},
+	{"ledbh0", 0x00000010, SRFL_NOFFS, SROM4_LEDBH10, 0x00ff},
+	{"ledbh1", 0x00000010, SRFL_NOFFS, SROM4_LEDBH10, 0xff00},
+	{"ledbh2", 0x00000010, SRFL_NOFFS, SROM4_LEDBH32, 0x00ff},
+	{"ledbh3", 0x00000010, SRFL_NOFFS, SROM4_LEDBH32, 0xff00},
+	{"ledbh0", 0x000000e0, SRFL_NOFFS, SROM5_LEDBH10, 0x00ff},
+	{"ledbh1", 0x000000e0, SRFL_NOFFS, SROM5_LEDBH10, 0xff00},
+	{"ledbh2", 0x000000e0, SRFL_NOFFS, SROM5_LEDBH32, 0x00ff},
+	{"ledbh3", 0x000000e0, SRFL_NOFFS, SROM5_LEDBH32, 0xff00},
+	{"ledbh0", 0xffffff00, SRFL_NOFFS, SROM8_LEDBH10, 0x00ff},
+	{"ledbh1", 0xffffff00, SRFL_NOFFS, SROM8_LEDBH10, 0xff00},
+	{"ledbh2", 0xffffff00, SRFL_NOFFS, SROM8_LEDBH32, 0x00ff},
+	{"ledbh3", 0xffffff00, SRFL_NOFFS, SROM8_LEDBH32, 0xff00},
+	{"pa0b0", 0x0000000e, SRFL_PRHEX, SROM_WL0PAB0, 0xffff},
+	{"pa0b1", 0x0000000e, SRFL_PRHEX, SROM_WL0PAB1, 0xffff},
+	{"pa0b2", 0x0000000e, SRFL_PRHEX, SROM_WL0PAB2, 0xffff},
+	{"pa0itssit", 0x0000000e, 0, SROM_ITT, 0x00ff},
+	{"pa0maxpwr", 0x0000000e, 0, SROM_WL10MAXP, 0x00ff},
+	{"pa0b0", 0xffffff00, SRFL_PRHEX, SROM8_W0_PAB0, 0xffff},
+	{"pa0b1", 0xffffff00, SRFL_PRHEX, SROM8_W0_PAB1, 0xffff},
+	{"pa0b2", 0xffffff00, SRFL_PRHEX, SROM8_W0_PAB2, 0xffff},
+	{"pa0itssit", 0xffffff00, 0, SROM8_W0_ITTMAXP, 0xff00},
+	{"pa0maxpwr", 0xffffff00, 0, SROM8_W0_ITTMAXP, 0x00ff},
+	{"opo", 0x0000000c, 0, SROM_OPO, 0x00ff},
+	{"opo", 0xffffff00, 0, SROM8_2G_OFDMPO, 0x00ff},
+	{"aa2g", 0x0000000e, 0, SROM_AABREV, SROM_AA0_MASK},
+	{"aa2g", 0x000000f0, 0, SROM4_AA, 0x00ff},
+	{"aa2g", 0xffffff00, 0, SROM8_AA, 0x00ff},
+	{"aa5g", 0x0000000e, 0, SROM_AABREV, SROM_AA1_MASK},
+	{"aa5g", 0x000000f0, 0, SROM4_AA, 0xff00},
+	{"aa5g", 0xffffff00, 0, SROM8_AA, 0xff00},
+	{"ag0", 0x0000000e, 0, SROM_AG10, 0x00ff},
+	{"ag1", 0x0000000e, 0, SROM_AG10, 0xff00},
+	{"ag0", 0x000000f0, 0, SROM4_AG10, 0x00ff},
+	{"ag1", 0x000000f0, 0, SROM4_AG10, 0xff00},
+	{"ag2", 0x000000f0, 0, SROM4_AG32, 0x00ff},
+	{"ag3", 0x000000f0, 0, SROM4_AG32, 0xff00},
+	{"ag0", 0xffffff00, 0, SROM8_AG10, 0x00ff},
+	{"ag1", 0xffffff00, 0, SROM8_AG10, 0xff00},
+	{"ag2", 0xffffff00, 0, SROM8_AG32, 0x00ff},
+	{"ag3", 0xffffff00, 0, SROM8_AG32, 0xff00},
+	{"pa1b0", 0x0000000e, SRFL_PRHEX, SROM_WL1PAB0, 0xffff},
+	{"pa1b1", 0x0000000e, SRFL_PRHEX, SROM_WL1PAB1, 0xffff},
+	{"pa1b2", 0x0000000e, SRFL_PRHEX, SROM_WL1PAB2, 0xffff},
+	{"pa1lob0", 0x0000000c, SRFL_PRHEX, SROM_WL1LPAB0, 0xffff},
+	{"pa1lob1", 0x0000000c, SRFL_PRHEX, SROM_WL1LPAB1, 0xffff},
+	{"pa1lob2", 0x0000000c, SRFL_PRHEX, SROM_WL1LPAB2, 0xffff},
+	{"pa1hib0", 0x0000000c, SRFL_PRHEX, SROM_WL1HPAB0, 0xffff},
+	{"pa1hib1", 0x0000000c, SRFL_PRHEX, SROM_WL1HPAB1, 0xffff},
+	{"pa1hib2", 0x0000000c, SRFL_PRHEX, SROM_WL1HPAB2, 0xffff},
+	{"pa1itssit", 0x0000000e, 0, SROM_ITT, 0xff00},
+	{"pa1maxpwr", 0x0000000e, 0, SROM_WL10MAXP, 0xff00},
+	{"pa1lomaxpwr", 0x0000000c, 0, SROM_WL1LHMAXP, 0xff00},
+	{"pa1himaxpwr", 0x0000000c, 0, SROM_WL1LHMAXP, 0x00ff},
+	{"pa1b0", 0xffffff00, SRFL_PRHEX, SROM8_W1_PAB0, 0xffff},
+	{"pa1b1", 0xffffff00, SRFL_PRHEX, SROM8_W1_PAB1, 0xffff},
+	{"pa1b2", 0xffffff00, SRFL_PRHEX, SROM8_W1_PAB2, 0xffff},
+	{"pa1lob0", 0xffffff00, SRFL_PRHEX, SROM8_W1_PAB0_LC, 0xffff},
+	{"pa1lob1", 0xffffff00, SRFL_PRHEX, SROM8_W1_PAB1_LC, 0xffff},
+	{"pa1lob2", 0xffffff00, SRFL_PRHEX, SROM8_W1_PAB2_LC, 0xffff},
+	{"pa1hib0", 0xffffff00, SRFL_PRHEX, SROM8_W1_PAB0_HC, 0xffff},
+	{"pa1hib1", 0xffffff00, SRFL_PRHEX, SROM8_W1_PAB1_HC, 0xffff},
+	{"pa1hib2", 0xffffff00, SRFL_PRHEX, SROM8_W1_PAB2_HC, 0xffff},
+	{"pa1itssit", 0xffffff00, 0, SROM8_W1_ITTMAXP, 0xff00},
+	{"pa1maxpwr", 0xffffff00, 0, SROM8_W1_ITTMAXP, 0x00ff},
+	{"pa1lomaxpwr", 0xffffff00, 0, SROM8_W1_MAXP_LCHC, 0xff00},
+	{"pa1himaxpwr", 0xffffff00, 0, SROM8_W1_MAXP_LCHC, 0x00ff},
+	{"bxa2g", 0x00000008, 0, SROM_BXARSSI2G, 0x1800},
+	{"rssisav2g", 0x00000008, 0, SROM_BXARSSI2G, 0x0700},
+	{"rssismc2g", 0x00000008, 0, SROM_BXARSSI2G, 0x00f0},
+	{"rssismf2g", 0x00000008, 0, SROM_BXARSSI2G, 0x000f},
+	{"bxa2g", 0xffffff00, 0, SROM8_BXARSSI2G, 0x1800},
+	{"rssisav2g", 0xffffff00, 0, SROM8_BXARSSI2G, 0x0700},
+	{"rssismc2g", 0xffffff00, 0, SROM8_BXARSSI2G, 0x00f0},
+	{"rssismf2g", 0xffffff00, 0, SROM8_BXARSSI2G, 0x000f},
+	{"bxa5g", 0x00000008, 0, SROM_BXARSSI5G, 0x1800},
+	{"rssisav5g", 0x00000008, 0, SROM_BXARSSI5G, 0x0700},
+	{"rssismc5g", 0x00000008, 0, SROM_BXARSSI5G, 0x00f0},
+	{"rssismf5g", 0x00000008, 0, SROM_BXARSSI5G, 0x000f},
+	{"bxa5g", 0xffffff00, 0, SROM8_BXARSSI5G, 0x1800},
+	{"rssisav5g", 0xffffff00, 0, SROM8_BXARSSI5G, 0x0700},
+	{"rssismc5g", 0xffffff00, 0, SROM8_BXARSSI5G, 0x00f0},
+	{"rssismf5g", 0xffffff00, 0, SROM8_BXARSSI5G, 0x000f},
+	{"tri2g", 0x00000008, 0, SROM_TRI52G, 0x00ff},
+	{"tri5g", 0x00000008, 0, SROM_TRI52G, 0xff00},
+	{"tri5gl", 0x00000008, 0, SROM_TRI5GHL, 0x00ff},
+	{"tri5gh", 0x00000008, 0, SROM_TRI5GHL, 0xff00},
+	{"tri2g", 0xffffff00, 0, SROM8_TRI52G, 0x00ff},
+	{"tri5g", 0xffffff00, 0, SROM8_TRI52G, 0xff00},
+	{"tri5gl", 0xffffff00, 0, SROM8_TRI5GHL, 0x00ff},
+	{"tri5gh", 0xffffff00, 0, SROM8_TRI5GHL, 0xff00},
+	{"rxpo2g", 0x00000008, SRFL_PRSIGN, SROM_RXPO52G, 0x00ff},
+	{"rxpo5g", 0x00000008, SRFL_PRSIGN, SROM_RXPO52G, 0xff00},
+	{"rxpo2g", 0xffffff00, SRFL_PRSIGN, SROM8_RXPO52G, 0x00ff},
+	{"rxpo5g", 0xffffff00, SRFL_PRSIGN, SROM8_RXPO52G, 0xff00},
+	{"txchain", 0x000000f0, SRFL_NOFFS, SROM4_TXRXC, SROM4_TXCHAIN_MASK},
+	{"rxchain", 0x000000f0, SRFL_NOFFS, SROM4_TXRXC, SROM4_RXCHAIN_MASK},
+	{"antswitch", 0x000000f0, SRFL_NOFFS, SROM4_TXRXC, SROM4_SWITCH_MASK},
+	{"txchain", 0xffffff00, SRFL_NOFFS, SROM8_TXRXC, SROM4_TXCHAIN_MASK},
+	{"rxchain", 0xffffff00, SRFL_NOFFS, SROM8_TXRXC, SROM4_RXCHAIN_MASK},
+	{"antswitch", 0xffffff00, SRFL_NOFFS, SROM8_TXRXC, SROM4_SWITCH_MASK},
+	{"tssipos2g", 0xffffff00, 0, SROM8_FEM2G, SROM8_FEM_TSSIPOS_MASK},
+	{"extpagain2g", 0xffffff00, 0, SROM8_FEM2G, SROM8_FEM_EXTPA_GAIN_MASK},
+	{"pdetrange2g", 0xffffff00, 0, SROM8_FEM2G, SROM8_FEM_PDET_RANGE_MASK},
+	{"triso2g", 0xffffff00, 0, SROM8_FEM2G, SROM8_FEM_TR_ISO_MASK},
+	{"antswctl2g", 0xffffff00, 0, SROM8_FEM2G, SROM8_FEM_ANTSWLUT_MASK},
+	{"tssipos5g", 0xffffff00, 0, SROM8_FEM5G, SROM8_FEM_TSSIPOS_MASK},
+	{"extpagain5g", 0xffffff00, 0, SROM8_FEM5G, SROM8_FEM_EXTPA_GAIN_MASK},
+	{"pdetrange5g", 0xffffff00, 0, SROM8_FEM5G, SROM8_FEM_PDET_RANGE_MASK},
+	{"triso5g", 0xffffff00, 0, SROM8_FEM5G, SROM8_FEM_TR_ISO_MASK},
+	{"antswctl5g", 0xffffff00, 0, SROM8_FEM5G, SROM8_FEM_ANTSWLUT_MASK},
+	{"tempthresh", 0xffffff00, 0, SROM8_THERMAL, 0xff00},
+	{"tempoffset", 0xffffff00, 0, SROM8_THERMAL, 0x00ff},
+	{"txpid2ga0", 0x000000f0, 0, SROM4_TXPID2G, 0x00ff},
+	{"txpid2ga1", 0x000000f0, 0, SROM4_TXPID2G, 0xff00},
+	{"txpid2ga2", 0x000000f0, 0, SROM4_TXPID2G + 1, 0x00ff},
+	{"txpid2ga3", 0x000000f0, 0, SROM4_TXPID2G + 1, 0xff00},
+	{"txpid5ga0", 0x000000f0, 0, SROM4_TXPID5G, 0x00ff},
+	{"txpid5ga1", 0x000000f0, 0, SROM4_TXPID5G, 0xff00},
+	{"txpid5ga2", 0x000000f0, 0, SROM4_TXPID5G + 1, 0x00ff},
+	{"txpid5ga3", 0x000000f0, 0, SROM4_TXPID5G + 1, 0xff00},
+	{"txpid5gla0", 0x000000f0, 0, SROM4_TXPID5GL, 0x00ff},
+	{"txpid5gla1", 0x000000f0, 0, SROM4_TXPID5GL, 0xff00},
+	{"txpid5gla2", 0x000000f0, 0, SROM4_TXPID5GL + 1, 0x00ff},
+	{"txpid5gla3", 0x000000f0, 0, SROM4_TXPID5GL + 1, 0xff00},
+	{"txpid5gha0", 0x000000f0, 0, SROM4_TXPID5GH, 0x00ff},
+	{"txpid5gha1", 0x000000f0, 0, SROM4_TXPID5GH, 0xff00},
+	{"txpid5gha2", 0x000000f0, 0, SROM4_TXPID5GH + 1, 0x00ff},
+	{"txpid5gha3", 0x000000f0, 0, SROM4_TXPID5GH + 1, 0xff00},
+
+	{"ccode", 0x0000000f, SRFL_CCODE, SROM_CCODE, 0xffff},
+	{"ccode", 0x00000010, SRFL_CCODE, SROM4_CCODE, 0xffff},
+	{"ccode", 0x000000e0, SRFL_CCODE, SROM5_CCODE, 0xffff},
+	{"ccode", 0xffffff00, SRFL_CCODE, SROM8_CCODE, 0xffff},
+	{"macaddr", 0xffffff00, SRFL_ETHADDR, SROM8_MACHI, 0xffff},
+	{"macaddr", 0x000000e0, SRFL_ETHADDR, SROM5_MACHI, 0xffff},
+	{"macaddr", 0x00000010, SRFL_ETHADDR, SROM4_MACHI, 0xffff},
+	{"macaddr", 0x00000008, SRFL_ETHADDR, SROM3_MACHI, 0xffff},
+	{"il0macaddr", 0x00000007, SRFL_ETHADDR, SROM_MACHI_IL0, 0xffff},
+	{"et1macaddr", 0x00000007, SRFL_ETHADDR, SROM_MACHI_ET1, 0xffff},
+	{"leddc", 0xffffff00, SRFL_NOFFS | SRFL_LEDDC, SROM8_LEDDC, 0xffff},
+	{"leddc", 0x000000e0, SRFL_NOFFS | SRFL_LEDDC, SROM5_LEDDC, 0xffff},
+	{"leddc", 0x00000010, SRFL_NOFFS | SRFL_LEDDC, SROM4_LEDDC, 0xffff},
+	{"leddc", 0x00000008, SRFL_NOFFS | SRFL_LEDDC, SROM3_LEDDC, 0xffff},
+	{"rawtempsense", 0xffffff00, SRFL_PRHEX, SROM8_MPWR_RAWTS, 0x01ff},
+	{"measpower", 0xffffff00, SRFL_PRHEX, SROM8_MPWR_RAWTS, 0xfe00},
+	{"tempsense_slope", 0xffffff00, SRFL_PRHEX, SROM8_TS_SLP_OPT_CORRX,
+	 0x00ff},
+	{"tempcorrx", 0xffffff00, SRFL_PRHEX, SROM8_TS_SLP_OPT_CORRX, 0xfc00},
+	{"tempsense_option", 0xffffff00, SRFL_PRHEX, SROM8_TS_SLP_OPT_CORRX,
+	 0x0300},
+	{"freqoffset_corr", 0xffffff00, SRFL_PRHEX, SROM8_FOC_HWIQ_IQSWP,
+	 0x000f},
+	{"iqcal_swp_dis", 0xffffff00, SRFL_PRHEX, SROM8_FOC_HWIQ_IQSWP, 0x0010},
+	{"hw_iqcal_en", 0xffffff00, SRFL_PRHEX, SROM8_FOC_HWIQ_IQSWP, 0x0020},
+	{"phycal_tempdelta", 0xffffff00, 0, SROM8_PHYCAL_TEMPDELTA, 0x00ff},
+
+	{"cck2gpo", 0x000000f0, 0, SROM4_2G_CCKPO, 0xffff},
+	{"cck2gpo", 0x00000100, 0, SROM8_2G_CCKPO, 0xffff},
+	{"ofdm2gpo", 0x000000f0, SRFL_MORE, SROM4_2G_OFDMPO, 0xffff},
+	{"", 0, 0, SROM4_2G_OFDMPO + 1, 0xffff},
+	{"ofdm5gpo", 0x000000f0, SRFL_MORE, SROM4_5G_OFDMPO, 0xffff},
+	{"", 0, 0, SROM4_5G_OFDMPO + 1, 0xffff},
+	{"ofdm5glpo", 0x000000f0, SRFL_MORE, SROM4_5GL_OFDMPO, 0xffff},
+	{"", 0, 0, SROM4_5GL_OFDMPO + 1, 0xffff},
+	{"ofdm5ghpo", 0x000000f0, SRFL_MORE, SROM4_5GH_OFDMPO, 0xffff},
+	{"", 0, 0, SROM4_5GH_OFDMPO + 1, 0xffff},
+	{"ofdm2gpo", 0x00000100, SRFL_MORE, SROM8_2G_OFDMPO, 0xffff},
+	{"", 0, 0, SROM8_2G_OFDMPO + 1, 0xffff},
+	{"ofdm5gpo", 0x00000100, SRFL_MORE, SROM8_5G_OFDMPO, 0xffff},
+	{"", 0, 0, SROM8_5G_OFDMPO + 1, 0xffff},
+	{"ofdm5glpo", 0x00000100, SRFL_MORE, SROM8_5GL_OFDMPO, 0xffff},
+	{"", 0, 0, SROM8_5GL_OFDMPO + 1, 0xffff},
+	{"ofdm5ghpo", 0x00000100, SRFL_MORE, SROM8_5GH_OFDMPO, 0xffff},
+	{"", 0, 0, SROM8_5GH_OFDMPO + 1, 0xffff},
+	{"mcs2gpo0", 0x000000f0, 0, SROM4_2G_MCSPO, 0xffff},
+	{"mcs2gpo1", 0x000000f0, 0, SROM4_2G_MCSPO + 1, 0xffff},
+	{"mcs2gpo2", 0x000000f0, 0, SROM4_2G_MCSPO + 2, 0xffff},
+	{"mcs2gpo3", 0x000000f0, 0, SROM4_2G_MCSPO + 3, 0xffff},
+	{"mcs2gpo4", 0x000000f0, 0, SROM4_2G_MCSPO + 4, 0xffff},
+	{"mcs2gpo5", 0x000000f0, 0, SROM4_2G_MCSPO + 5, 0xffff},
+	{"mcs2gpo6", 0x000000f0, 0, SROM4_2G_MCSPO + 6, 0xffff},
+	{"mcs2gpo7", 0x000000f0, 0, SROM4_2G_MCSPO + 7, 0xffff},
+	{"mcs5gpo0", 0x000000f0, 0, SROM4_5G_MCSPO, 0xffff},
+	{"mcs5gpo1", 0x000000f0, 0, SROM4_5G_MCSPO + 1, 0xffff},
+	{"mcs5gpo2", 0x000000f0, 0, SROM4_5G_MCSPO + 2, 0xffff},
+	{"mcs5gpo3", 0x000000f0, 0, SROM4_5G_MCSPO + 3, 0xffff},
+	{"mcs5gpo4", 0x000000f0, 0, SROM4_5G_MCSPO + 4, 0xffff},
+	{"mcs5gpo5", 0x000000f0, 0, SROM4_5G_MCSPO + 5, 0xffff},
+	{"mcs5gpo6", 0x000000f0, 0, SROM4_5G_MCSPO + 6, 0xffff},
+	{"mcs5gpo7", 0x000000f0, 0, SROM4_5G_MCSPO + 7, 0xffff},
+	{"mcs5glpo0", 0x000000f0, 0, SROM4_5GL_MCSPO, 0xffff},
+	{"mcs5glpo1", 0x000000f0, 0, SROM4_5GL_MCSPO + 1, 0xffff},
+	{"mcs5glpo2", 0x000000f0, 0, SROM4_5GL_MCSPO + 2, 0xffff},
+	{"mcs5glpo3", 0x000000f0, 0, SROM4_5GL_MCSPO + 3, 0xffff},
+	{"mcs5glpo4", 0x000000f0, 0, SROM4_5GL_MCSPO + 4, 0xffff},
+	{"mcs5glpo5", 0x000000f0, 0, SROM4_5GL_MCSPO + 5, 0xffff},
+	{"mcs5glpo6", 0x000000f0, 0, SROM4_5GL_MCSPO + 6, 0xffff},
+	{"mcs5glpo7", 0x000000f0, 0, SROM4_5GL_MCSPO + 7, 0xffff},
+	{"mcs5ghpo0", 0x000000f0, 0, SROM4_5GH_MCSPO, 0xffff},
+	{"mcs5ghpo1", 0x000000f0, 0, SROM4_5GH_MCSPO + 1, 0xffff},
+	{"mcs5ghpo2", 0x000000f0, 0, SROM4_5GH_MCSPO + 2, 0xffff},
+	{"mcs5ghpo3", 0x000000f0, 0, SROM4_5GH_MCSPO + 3, 0xffff},
+	{"mcs5ghpo4", 0x000000f0, 0, SROM4_5GH_MCSPO + 4, 0xffff},
+	{"mcs5ghpo5", 0x000000f0, 0, SROM4_5GH_MCSPO + 5, 0xffff},
+	{"mcs5ghpo6", 0x000000f0, 0, SROM4_5GH_MCSPO + 6, 0xffff},
+	{"mcs5ghpo7", 0x000000f0, 0, SROM4_5GH_MCSPO + 7, 0xffff},
+	{"mcs2gpo0", 0x00000100, 0, SROM8_2G_MCSPO, 0xffff},
+	{"mcs2gpo1", 0x00000100, 0, SROM8_2G_MCSPO + 1, 0xffff},
+	{"mcs2gpo2", 0x00000100, 0, SROM8_2G_MCSPO + 2, 0xffff},
+	{"mcs2gpo3", 0x00000100, 0, SROM8_2G_MCSPO + 3, 0xffff},
+	{"mcs2gpo4", 0x00000100, 0, SROM8_2G_MCSPO + 4, 0xffff},
+	{"mcs2gpo5", 0x00000100, 0, SROM8_2G_MCSPO + 5, 0xffff},
+	{"mcs2gpo6", 0x00000100, 0, SROM8_2G_MCSPO + 6, 0xffff},
+	{"mcs2gpo7", 0x00000100, 0, SROM8_2G_MCSPO + 7, 0xffff},
+	{"mcs5gpo0", 0x00000100, 0, SROM8_5G_MCSPO, 0xffff},
+	{"mcs5gpo1", 0x00000100, 0, SROM8_5G_MCSPO + 1, 0xffff},
+	{"mcs5gpo2", 0x00000100, 0, SROM8_5G_MCSPO + 2, 0xffff},
+	{"mcs5gpo3", 0x00000100, 0, SROM8_5G_MCSPO + 3, 0xffff},
+	{"mcs5gpo4", 0x00000100, 0, SROM8_5G_MCSPO + 4, 0xffff},
+	{"mcs5gpo5", 0x00000100, 0, SROM8_5G_MCSPO + 5, 0xffff},
+	{"mcs5gpo6", 0x00000100, 0, SROM8_5G_MCSPO + 6, 0xffff},
+	{"mcs5gpo7", 0x00000100, 0, SROM8_5G_MCSPO + 7, 0xffff},
+	{"mcs5glpo0", 0x00000100, 0, SROM8_5GL_MCSPO, 0xffff},
+	{"mcs5glpo1", 0x00000100, 0, SROM8_5GL_MCSPO + 1, 0xffff},
+	{"mcs5glpo2", 0x00000100, 0, SROM8_5GL_MCSPO + 2, 0xffff},
+	{"mcs5glpo3", 0x00000100, 0, SROM8_5GL_MCSPO + 3, 0xffff},
+	{"mcs5glpo4", 0x00000100, 0, SROM8_5GL_MCSPO + 4, 0xffff},
+	{"mcs5glpo5", 0x00000100, 0, SROM8_5GL_MCSPO + 5, 0xffff},
+	{"mcs5glpo6", 0x00000100, 0, SROM8_5GL_MCSPO + 6, 0xffff},
+	{"mcs5glpo7", 0x00000100, 0, SROM8_5GL_MCSPO + 7, 0xffff},
+	{"mcs5ghpo0", 0x00000100, 0, SROM8_5GH_MCSPO, 0xffff},
+	{"mcs5ghpo1", 0x00000100, 0, SROM8_5GH_MCSPO + 1, 0xffff},
+	{"mcs5ghpo2", 0x00000100, 0, SROM8_5GH_MCSPO + 2, 0xffff},
+	{"mcs5ghpo3", 0x00000100, 0, SROM8_5GH_MCSPO + 3, 0xffff},
+	{"mcs5ghpo4", 0x00000100, 0, SROM8_5GH_MCSPO + 4, 0xffff},
+	{"mcs5ghpo5", 0x00000100, 0, SROM8_5GH_MCSPO + 5, 0xffff},
+	{"mcs5ghpo6", 0x00000100, 0, SROM8_5GH_MCSPO + 6, 0xffff},
+	{"mcs5ghpo7", 0x00000100, 0, SROM8_5GH_MCSPO + 7, 0xffff},
+	{"cddpo", 0x000000f0, 0, SROM4_CDDPO, 0xffff},
+	{"stbcpo", 0x000000f0, 0, SROM4_STBCPO, 0xffff},
+	{"bw40po", 0x000000f0, 0, SROM4_BW40PO, 0xffff},
+	{"bwduppo", 0x000000f0, 0, SROM4_BWDUPPO, 0xffff},
+	{"cddpo", 0x00000100, 0, SROM8_CDDPO, 0xffff},
+	{"stbcpo", 0x00000100, 0, SROM8_STBCPO, 0xffff},
+	{"bw40po", 0x00000100, 0, SROM8_BW40PO, 0xffff},
+	{"bwduppo", 0x00000100, 0, SROM8_BWDUPPO, 0xffff},
+
+	/* power per rate from sromrev 9 */
+	{"cckbw202gpo", 0xfffffe00, 0, SROM9_2GPO_CCKBW20, 0xffff},
+	{"cckbw20ul2gpo", 0xfffffe00, 0, SROM9_2GPO_CCKBW20UL, 0xffff},
+	{"legofdmbw202gpo", 0xfffffe00, SRFL_MORE, SROM9_2GPO_LOFDMBW20,
+	 0xffff},
+	{"", 0, 0, SROM9_2GPO_LOFDMBW20 + 1, 0xffff},
+	{"legofdmbw20ul2gpo", 0xfffffe00, SRFL_MORE, SROM9_2GPO_LOFDMBW20UL,
+	 0xffff},
+	{"", 0, 0, SROM9_2GPO_LOFDMBW20UL + 1, 0xffff},
+	{"legofdmbw205glpo", 0xfffffe00, SRFL_MORE, SROM9_5GLPO_LOFDMBW20,
+	 0xffff},
+	{"", 0, 0, SROM9_5GLPO_LOFDMBW20 + 1, 0xffff},
+	{"legofdmbw20ul5glpo", 0xfffffe00, SRFL_MORE, SROM9_5GLPO_LOFDMBW20UL,
+	 0xffff},
+	{"", 0, 0, SROM9_5GLPO_LOFDMBW20UL + 1, 0xffff},
+	{"legofdmbw205gmpo", 0xfffffe00, SRFL_MORE, SROM9_5GMPO_LOFDMBW20,
+	 0xffff},
+	{"", 0, 0, SROM9_5GMPO_LOFDMBW20 + 1, 0xffff},
+	{"legofdmbw20ul5gmpo", 0xfffffe00, SRFL_MORE, SROM9_5GMPO_LOFDMBW20UL,
+	 0xffff},
+	{"", 0, 0, SROM9_5GMPO_LOFDMBW20UL + 1, 0xffff},
+	{"legofdmbw205ghpo", 0xfffffe00, SRFL_MORE, SROM9_5GHPO_LOFDMBW20,
+	 0xffff},
+	{"", 0, 0, SROM9_5GHPO_LOFDMBW20 + 1, 0xffff},
+	{"legofdmbw20ul5ghpo", 0xfffffe00, SRFL_MORE, SROM9_5GHPO_LOFDMBW20UL,
+	 0xffff},
+	{"", 0, 0, SROM9_5GHPO_LOFDMBW20UL + 1, 0xffff},
+	{"mcsbw202gpo", 0xfffffe00, SRFL_MORE, SROM9_2GPO_MCSBW20, 0xffff},
+	{"", 0, 0, SROM9_2GPO_MCSBW20 + 1, 0xffff},
+	{"mcsbw20ul2gpo", 0xfffffe00, SRFL_MORE, SROM9_2GPO_MCSBW20UL, 0xffff},
+	{"", 0, 0, SROM9_2GPO_MCSBW20UL + 1, 0xffff},
+	{"mcsbw402gpo", 0xfffffe00, SRFL_MORE, SROM9_2GPO_MCSBW40, 0xffff},
+	{"", 0, 0, SROM9_2GPO_MCSBW40 + 1, 0xffff},
+	{"mcsbw205glpo", 0xfffffe00, SRFL_MORE, SROM9_5GLPO_MCSBW20, 0xffff},
+	{"", 0, 0, SROM9_5GLPO_MCSBW20 + 1, 0xffff},
+	{"mcsbw20ul5glpo", 0xfffffe00, SRFL_MORE, SROM9_5GLPO_MCSBW20UL,
+	 0xffff},
+	{"", 0, 0, SROM9_5GLPO_MCSBW20UL + 1, 0xffff},
+	{"mcsbw405glpo", 0xfffffe00, SRFL_MORE, SROM9_5GLPO_MCSBW40, 0xffff},
+	{"", 0, 0, SROM9_5GLPO_MCSBW40 + 1, 0xffff},
+	{"mcsbw205gmpo", 0xfffffe00, SRFL_MORE, SROM9_5GMPO_MCSBW20, 0xffff},
+	{"", 0, 0, SROM9_5GMPO_MCSBW20 + 1, 0xffff},
+	{"mcsbw20ul5gmpo", 0xfffffe00, SRFL_MORE, SROM9_5GMPO_MCSBW20UL,
+	 0xffff},
+	{"", 0, 0, SROM9_5GMPO_MCSBW20UL + 1, 0xffff},
+	{"mcsbw405gmpo", 0xfffffe00, SRFL_MORE, SROM9_5GMPO_MCSBW40, 0xffff},
+	{"", 0, 0, SROM9_5GMPO_MCSBW40 + 1, 0xffff},
+	{"mcsbw205ghpo", 0xfffffe00, SRFL_MORE, SROM9_5GHPO_MCSBW20, 0xffff},
+	{"", 0, 0, SROM9_5GHPO_MCSBW20 + 1, 0xffff},
+	{"mcsbw20ul5ghpo", 0xfffffe00, SRFL_MORE, SROM9_5GHPO_MCSBW20UL,
+	 0xffff},
+	{"", 0, 0, SROM9_5GHPO_MCSBW20UL + 1, 0xffff},
+	{"mcsbw405ghpo", 0xfffffe00, SRFL_MORE, SROM9_5GHPO_MCSBW40, 0xffff},
+	{"", 0, 0, SROM9_5GHPO_MCSBW40 + 1, 0xffff},
+	{"mcs32po", 0xfffffe00, 0, SROM9_PO_MCS32, 0xffff},
+	{"legofdm40duppo", 0xfffffe00, 0, SROM9_PO_LOFDM40DUP, 0xffff},
+
+	{NULL, 0, 0, 0, 0}
+};
+
+static const sromvar_t perpath_pci_sromvars[] = {
+	{"maxp2ga", 0x000000f0, 0, SROM4_2G_ITT_MAXP, 0x00ff},
+	{"itt2ga", 0x000000f0, 0, SROM4_2G_ITT_MAXP, 0xff00},
+	{"itt5ga", 0x000000f0, 0, SROM4_5G_ITT_MAXP, 0xff00},
+	{"pa2gw0a", 0x000000f0, SRFL_PRHEX, SROM4_2G_PA, 0xffff},
+	{"pa2gw1a", 0x000000f0, SRFL_PRHEX, SROM4_2G_PA + 1, 0xffff},
+	{"pa2gw2a", 0x000000f0, SRFL_PRHEX, SROM4_2G_PA + 2, 0xffff},
+	{"pa2gw3a", 0x000000f0, SRFL_PRHEX, SROM4_2G_PA + 3, 0xffff},
+	{"maxp5ga", 0x000000f0, 0, SROM4_5G_ITT_MAXP, 0x00ff},
+	{"maxp5gha", 0x000000f0, 0, SROM4_5GLH_MAXP, 0x00ff},
+	{"maxp5gla", 0x000000f0, 0, SROM4_5GLH_MAXP, 0xff00},
+	{"pa5gw0a", 0x000000f0, SRFL_PRHEX, SROM4_5G_PA, 0xffff},
+	{"pa5gw1a", 0x000000f0, SRFL_PRHEX, SROM4_5G_PA + 1, 0xffff},
+	{"pa5gw2a", 0x000000f0, SRFL_PRHEX, SROM4_5G_PA + 2, 0xffff},
+	{"pa5gw3a", 0x000000f0, SRFL_PRHEX, SROM4_5G_PA + 3, 0xffff},
+	{"pa5glw0a", 0x000000f0, SRFL_PRHEX, SROM4_5GL_PA, 0xffff},
+	{"pa5glw1a", 0x000000f0, SRFL_PRHEX, SROM4_5GL_PA + 1, 0xffff},
+	{"pa5glw2a", 0x000000f0, SRFL_PRHEX, SROM4_5GL_PA + 2, 0xffff},
+	{"pa5glw3a", 0x000000f0, SRFL_PRHEX, SROM4_5GL_PA + 3, 0xffff},
+	{"pa5ghw0a", 0x000000f0, SRFL_PRHEX, SROM4_5GH_PA, 0xffff},
+	{"pa5ghw1a", 0x000000f0, SRFL_PRHEX, SROM4_5GH_PA + 1, 0xffff},
+	{"pa5ghw2a", 0x000000f0, SRFL_PRHEX, SROM4_5GH_PA + 2, 0xffff},
+	{"pa5ghw3a", 0x000000f0, SRFL_PRHEX, SROM4_5GH_PA + 3, 0xffff},
+	{"maxp2ga", 0xffffff00, 0, SROM8_2G_ITT_MAXP, 0x00ff},
+	{"itt2ga", 0xffffff00, 0, SROM8_2G_ITT_MAXP, 0xff00},
+	{"itt5ga", 0xffffff00, 0, SROM8_5G_ITT_MAXP, 0xff00},
+	{"pa2gw0a", 0xffffff00, SRFL_PRHEX, SROM8_2G_PA, 0xffff},
+	{"pa2gw1a", 0xffffff00, SRFL_PRHEX, SROM8_2G_PA + 1, 0xffff},
+	{"pa2gw2a", 0xffffff00, SRFL_PRHEX, SROM8_2G_PA + 2, 0xffff},
+	{"maxp5ga", 0xffffff00, 0, SROM8_5G_ITT_MAXP, 0x00ff},
+	{"maxp5gha", 0xffffff00, 0, SROM8_5GLH_MAXP, 0x00ff},
+	{"maxp5gla", 0xffffff00, 0, SROM8_5GLH_MAXP, 0xff00},
+	{"pa5gw0a", 0xffffff00, SRFL_PRHEX, SROM8_5G_PA, 0xffff},
+	{"pa5gw1a", 0xffffff00, SRFL_PRHEX, SROM8_5G_PA + 1, 0xffff},
+	{"pa5gw2a", 0xffffff00, SRFL_PRHEX, SROM8_5G_PA + 2, 0xffff},
+	{"pa5glw0a", 0xffffff00, SRFL_PRHEX, SROM8_5GL_PA, 0xffff},
+	{"pa5glw1a", 0xffffff00, SRFL_PRHEX, SROM8_5GL_PA + 1, 0xffff},
+	{"pa5glw2a", 0xffffff00, SRFL_PRHEX, SROM8_5GL_PA + 2, 0xffff},
+	{"pa5ghw0a", 0xffffff00, SRFL_PRHEX, SROM8_5GH_PA, 0xffff},
+	{"pa5ghw1a", 0xffffff00, SRFL_PRHEX, SROM8_5GH_PA + 1, 0xffff},
+	{"pa5ghw2a", 0xffffff00, SRFL_PRHEX, SROM8_5GH_PA + 2, 0xffff},
+	{NULL, 0, 0, 0, 0}
+};
+
+#if !(defined(PHY_TYPE_N) && defined(PHY_TYPE_LP))
+#define	PHY_TYPE_N		4	/* N-Phy value */
+#define	PHY_TYPE_LP		5	/* LP-Phy value */
+#endif				/* !(defined(PHY_TYPE_N) && defined(PHY_TYPE_LP)) */
+#if !defined(PHY_TYPE_NULL)
+#define	PHY_TYPE_NULL		0xf	/* Invalid Phy value */
+#endif				/* !defined(PHY_TYPE_NULL) */
+
+typedef struct {
+	u16 phy_type;
+	u16 bandrange;
+	u16 chain;
+	const char *vars;
+} pavars_t;
+
+static const pavars_t pavars[] = {
+	/* NPHY */
+	{PHY_TYPE_N, WL_CHAN_FREQ_RANGE_2G, 0, "pa2gw0a0 pa2gw1a0 pa2gw2a0"},
+	{PHY_TYPE_N, WL_CHAN_FREQ_RANGE_2G, 1, "pa2gw0a1 pa2gw1a1 pa2gw2a1"},
+	{PHY_TYPE_N, WL_CHAN_FREQ_RANGE_5GL, 0,
+	 "pa5glw0a0 pa5glw1a0 pa5glw2a0"},
+	{PHY_TYPE_N, WL_CHAN_FREQ_RANGE_5GL, 1,
+	 "pa5glw0a1 pa5glw1a1 pa5glw2a1"},
+	{PHY_TYPE_N, WL_CHAN_FREQ_RANGE_5GM, 0, "pa5gw0a0 pa5gw1a0 pa5gw2a0"},
+	{PHY_TYPE_N, WL_CHAN_FREQ_RANGE_5GM, 1, "pa5gw0a1 pa5gw1a1 pa5gw2a1"},
+	{PHY_TYPE_N, WL_CHAN_FREQ_RANGE_5GH, 0,
+	 "pa5ghw0a0 pa5ghw1a0 pa5ghw2a0"},
+	{PHY_TYPE_N, WL_CHAN_FREQ_RANGE_5GH, 1,
+	 "pa5ghw0a1 pa5ghw1a1 pa5ghw2a1"},
+	/* LPPHY */
+	{PHY_TYPE_LP, WL_CHAN_FREQ_RANGE_2G, 0, "pa0b0 pa0b1 pa0b2"},
+	{PHY_TYPE_LP, WL_CHAN_FREQ_RANGE_5GL, 0, "pa1lob0 pa1lob1 pa1lob2"},
+	{PHY_TYPE_LP, WL_CHAN_FREQ_RANGE_5GM, 0, "pa1b0 pa1b1 pa1b2"},
+	{PHY_TYPE_LP, WL_CHAN_FREQ_RANGE_5GH, 0, "pa1hib0 pa1hib1 pa1hib2"},
+	{PHY_TYPE_NULL, 0, 0, ""}
+};
+
+typedef struct {
+	u16 phy_type;
+	u16 bandrange;
+	const char *vars;
+} povars_t;
+
+static const povars_t povars[] = {
+	/* NPHY */
+	{PHY_TYPE_N, WL_CHAN_FREQ_RANGE_2G,
+	 "mcs2gpo0 mcs2gpo1 mcs2gpo2 mcs2gpo3 "
+	 "mcs2gpo4 mcs2gpo5 mcs2gpo6 mcs2gpo7"},
+	{PHY_TYPE_N, WL_CHAN_FREQ_RANGE_5GL,
+	 "mcs5glpo0 mcs5glpo1 mcs5glpo2 mcs5glpo3 "
+	 "mcs5glpo4 mcs5glpo5 mcs5glpo6 mcs5glpo7"},
+	{PHY_TYPE_N, WL_CHAN_FREQ_RANGE_5GM,
+	 "mcs5gpo0 mcs5gpo1 mcs5gpo2 mcs5gpo3 "
+	 "mcs5gpo4 mcs5gpo5 mcs5gpo6 mcs5gpo7"},
+	{PHY_TYPE_N, WL_CHAN_FREQ_RANGE_5GH,
+	 "mcs5ghpo0 mcs5ghpo1 mcs5ghpo2 mcs5ghpo3 "
+	 "mcs5ghpo4 mcs5ghpo5 mcs5ghpo6 mcs5ghpo7"},
+	{PHY_TYPE_NULL, 0, ""}
+};
+
+typedef struct {
+	u8 tag;		/* Broadcom subtag name */
+	u8 len;		/* Length field of the tuple, note that it includes the
+				 * subtag name (1 byte): 1 + tuple content length
+				 */
+	const char *params;
+} cis_tuple_t;
+
+#define OTP_RAW		(0xff - 1)	/* Reserved tuple number for wrvar Raw input */
+#define OTP_VERS_1	(0xff - 2)	/* CISTPL_VERS_1 */
+#define OTP_MANFID	(0xff - 3)	/* CISTPL_MANFID */
+#define OTP_RAW1	(0xff - 4)	/* Like RAW, but comes first */
+
+#endif				/* _bcmsrom_tbl_h_ */
diff -druN linux-2.6.39-libre/drivers/staging/brcm80211/brcmsmac/d11.h linux-3.0-rc7-libre/drivers/staging/brcm80211/brcmsmac/d11.h
--- linux-2.6.39-libre/drivers/staging/brcm80211/brcmsmac/d11.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/brcm80211/brcmsmac/d11.h	2011-07-11 19:51:52.000000000 -0400
@@ -17,6 +17,8 @@
 #ifndef	_D11_H
 #define	_D11_H
 
+#include <sbconfig.h>
+
 #ifndef WL_RSSI_ANT_MAX
 #define WL_RSSI_ANT_MAX		4	/* max possible rx antennas */
 #elif WL_RSSI_ANT_MAX != 4
diff -druN linux-2.6.39-libre/drivers/staging/brcm80211/brcmsmac/hnddma.c linux-3.0-rc7-libre/drivers/staging/brcm80211/brcmsmac/hnddma.c
--- linux-2.6.39-libre/drivers/staging/brcm80211/brcmsmac/hnddma.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/staging/brcm80211/brcmsmac/hnddma.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,1756 @@
+/*
+ * Copyright (c) 2010 Broadcom Corporation
+ *
+ * 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/kernel.h>
+#include <linux/string.h>
+#include <linux/netdevice.h>
+#include <linux/pci.h>
+#include <bcmdefs.h>
+#include <bcmdevs.h>
+#include <hndsoc.h>
+#include <bcmutils.h>
+#include <aiutils.h>
+
+#include <sbhnddma.h>
+#include <hnddma.h>
+
+#if defined(__mips__)
+#include <asm/addrspace.h>
+#endif
+
+#ifdef BRCM_FULLMAC
+#error "hnddma.c shouldn't be needed for FULLMAC"
+#endif
+
+/* debug/trace */
+#ifdef BCMDBG
+#define	DMA_ERROR(args) \
+	do { \
+		if (!(*di->msg_level & 1)) \
+			; \
+		else \
+			printk args; \
+	} while (0)
+#define	DMA_TRACE(args) \
+	do { \
+		if (!(*di->msg_level & 2)) \
+			; \
+		else \
+			printk args; \
+	} while (0)
+#else
+#define	DMA_ERROR(args)
+#define	DMA_TRACE(args)
+#endif				/* BCMDBG */
+
+#define	DMA_NONE(args)
+
+#define d64txregs	dregs.d64_u.txregs_64
+#define d64rxregs	dregs.d64_u.rxregs_64
+#define txd64		dregs.d64_u.txd_64
+#define rxd64		dregs.d64_u.rxd_64
+
+/* default dma message level (if input msg_level pointer is null in dma_attach()) */
+static uint dma_msg_level;
+
+#define	MAXNAMEL	8	/* 8 char names */
+
+#define	DI_INFO(dmah)	((dma_info_t *)dmah)
+
+#define R_SM(r)		(*(r))
+#define W_SM(r, v)	(*(r) = (v))
+
+/* dma engine software state */
+typedef struct dma_info {
+	struct hnddma_pub hnddma; /* exported structure */
+	uint *msg_level;	/* message level pointer */
+	char name[MAXNAMEL];	/* callers name for diag msgs */
+
+	void *pbus;		/* bus handle */
+
+	bool dma64;		/* this dma engine is operating in 64-bit mode */
+	bool addrext;		/* this dma engine supports DmaExtendedAddrChanges */
+
+	union {
+		struct {
+			dma64regs_t *txregs_64;	/* 64-bit dma tx engine registers */
+			dma64regs_t *rxregs_64;	/* 64-bit dma rx engine registers */
+			dma64dd_t *txd_64;	/* pointer to dma64 tx descriptor ring */
+			dma64dd_t *rxd_64;	/* pointer to dma64 rx descriptor ring */
+		} d64_u;
+	} dregs;
+
+	u16 dmadesc_align;	/* alignment requirement for dma descriptors */
+
+	u16 ntxd;		/* # tx descriptors tunable */
+	u16 txin;		/* index of next descriptor to reclaim */
+	u16 txout;		/* index of next descriptor to post */
+	void **txp;		/* pointer to parallel array of pointers to packets */
+	hnddma_seg_map_t *txp_dmah;	/* DMA MAP meta-data handle */
+	dmaaddr_t txdpa;	/* Aligned physical address of descriptor ring */
+	dmaaddr_t txdpaorig;	/* Original physical address of descriptor ring */
+	u16 txdalign;	/* #bytes added to alloc'd mem to align txd */
+	u32 txdalloc;	/* #bytes allocated for the ring */
+	u32 xmtptrbase;	/* When using unaligned descriptors, the ptr register
+				 * is not just an index, it needs all 13 bits to be
+				 * an offset from the addr register.
+				 */
+
+	u16 nrxd;		/* # rx descriptors tunable */
+	u16 rxin;		/* index of next descriptor to reclaim */
+	u16 rxout;		/* index of next descriptor to post */
+	void **rxp;		/* pointer to parallel array of pointers to packets */
+	hnddma_seg_map_t *rxp_dmah;	/* DMA MAP meta-data handle */
+	dmaaddr_t rxdpa;	/* Aligned physical address of descriptor ring */
+	dmaaddr_t rxdpaorig;	/* Original physical address of descriptor ring */
+	u16 rxdalign;	/* #bytes added to alloc'd mem to align rxd */
+	u32 rxdalloc;	/* #bytes allocated for the ring */
+	u32 rcvptrbase;	/* Base for ptr reg when using unaligned descriptors */
+
+	/* tunables */
+	unsigned int rxbufsize;	/* rx buffer size in bytes,
+				 * not including the extra headroom
+				 */
+	uint rxextrahdrroom;	/* extra rx headroom, reverseved to assist upper stack
+				 *  e.g. some rx pkt buffers will be bridged to tx side
+				 *  without byte copying. The extra headroom needs to be
+				 *  large enough to fit txheader needs.
+				 *  Some dongle driver may not need it.
+				 */
+	uint nrxpost;		/* # rx buffers to keep posted */
+	unsigned int rxoffset;	/* rxcontrol offset */
+	uint ddoffsetlow;	/* add to get dma address of descriptor ring, low 32 bits */
+	uint ddoffsethigh;	/*   high 32 bits */
+	uint dataoffsetlow;	/* add to get dma address of data buffer, low 32 bits */
+	uint dataoffsethigh;	/*   high 32 bits */
+	bool aligndesc_4k;	/* descriptor base need to be aligned or not */
+} dma_info_t;
+
+/* DMA Scatter-gather list is supported. Note this is limited to TX direction only */
+#ifdef BCMDMASGLISTOSL
+#define DMASGLIST_ENAB true
+#else
+#define DMASGLIST_ENAB false
+#endif				/* BCMDMASGLISTOSL */
+
+/* descriptor bumping macros */
+#define	XXD(x, n)	((x) & ((n) - 1))	/* faster than %, but n must be power of 2 */
+#define	TXD(x)		XXD((x), di->ntxd)
+#define	RXD(x)		XXD((x), di->nrxd)
+#define	NEXTTXD(i)	TXD((i) + 1)
+#define	PREVTXD(i)	TXD((i) - 1)
+#define	NEXTRXD(i)	RXD((i) + 1)
+#define	PREVRXD(i)	RXD((i) - 1)
+
+#define	NTXDACTIVE(h, t)	TXD((t) - (h))
+#define	NRXDACTIVE(h, t)	RXD((t) - (h))
+
+/* macros to convert between byte offsets and indexes */
+#define	B2I(bytes, type)	((bytes) / sizeof(type))
+#define	I2B(index, type)	((index) * sizeof(type))
+
+#define	PCI32ADDR_HIGH		0xc0000000	/* address[31:30] */
+#define	PCI32ADDR_HIGH_SHIFT	30	/* address[31:30] */
+
+#define	PCI64ADDR_HIGH		0x80000000	/* address[63] */
+#define	PCI64ADDR_HIGH_SHIFT	31	/* address[63] */
+
+/* Common prototypes */
+static bool _dma_isaddrext(dma_info_t *di);
+static bool _dma_descriptor_align(dma_info_t *di);
+static bool _dma_alloc(dma_info_t *di, uint direction);
+static void _dma_detach(dma_info_t *di);
+static void _dma_ddtable_init(dma_info_t *di, uint direction, dmaaddr_t pa);
+static void _dma_rxinit(dma_info_t *di);
+static void *_dma_rx(dma_info_t *di);
+static bool _dma_rxfill(dma_info_t *di);
+static void _dma_rxreclaim(dma_info_t *di);
+static void _dma_rxenable(dma_info_t *di);
+static void *_dma_getnextrxp(dma_info_t *di, bool forceall);
+static void _dma_rx_param_get(dma_info_t *di, u16 *rxoffset,
+			      u16 *rxbufsize);
+
+static void _dma_txblock(dma_info_t *di);
+static void _dma_txunblock(dma_info_t *di);
+static uint _dma_txactive(dma_info_t *di);
+static uint _dma_rxactive(dma_info_t *di);
+static uint _dma_txpending(dma_info_t *di);
+static uint _dma_txcommitted(dma_info_t *di);
+
+static void *_dma_peeknexttxp(dma_info_t *di);
+static void *_dma_peeknextrxp(dma_info_t *di);
+static unsigned long _dma_getvar(dma_info_t *di, const char *name);
+static void _dma_counterreset(dma_info_t *di);
+static void _dma_fifoloopbackenable(dma_info_t *di);
+static uint _dma_ctrlflags(dma_info_t *di, uint mask, uint flags);
+static u8 dma_align_sizetobits(uint size);
+static void *dma_ringalloc(dma_info_t *di, u32 boundary, uint size,
+			   u16 *alignbits, uint *alloced,
+			   dmaaddr_t *descpa);
+
+/* Prototypes for 64-bit routines */
+static bool dma64_alloc(dma_info_t *di, uint direction);
+static bool dma64_txreset(dma_info_t *di);
+static bool dma64_rxreset(dma_info_t *di);
+static bool dma64_txsuspendedidle(dma_info_t *di);
+static int dma64_txfast(dma_info_t *di, struct sk_buff *p0, bool commit);
+static int dma64_txunframed(dma_info_t *di, void *p0, uint len, bool commit);
+static void *dma64_getpos(dma_info_t *di, bool direction);
+static void *dma64_getnexttxp(dma_info_t *di, txd_range_t range);
+static void *dma64_getnextrxp(dma_info_t *di, bool forceall);
+static void dma64_txrotate(dma_info_t *di);
+
+static bool dma64_rxidle(dma_info_t *di);
+static void dma64_txinit(dma_info_t *di);
+static bool dma64_txenabled(dma_info_t *di);
+static void dma64_txsuspend(dma_info_t *di);
+static void dma64_txresume(dma_info_t *di);
+static bool dma64_txsuspended(dma_info_t *di);
+static void dma64_txreclaim(dma_info_t *di, txd_range_t range);
+static bool dma64_txstopped(dma_info_t *di);
+static bool dma64_rxstopped(dma_info_t *di);
+static bool dma64_rxenabled(dma_info_t *di);
+static bool _dma64_addrext(dma64regs_t *dma64regs);
+
+static inline u32 parity32(u32 data);
+
+const di_fcn_t dma64proc = {
+	(di_detach_t) _dma_detach,
+	(di_txinit_t) dma64_txinit,
+	(di_txreset_t) dma64_txreset,
+	(di_txenabled_t) dma64_txenabled,
+	(di_txsuspend_t) dma64_txsuspend,
+	(di_txresume_t) dma64_txresume,
+	(di_txsuspended_t) dma64_txsuspended,
+	(di_txsuspendedidle_t) dma64_txsuspendedidle,
+	(di_txfast_t) dma64_txfast,
+	(di_txunframed_t) dma64_txunframed,
+	(di_getpos_t) dma64_getpos,
+	(di_txstopped_t) dma64_txstopped,
+	(di_txreclaim_t) dma64_txreclaim,
+	(di_getnexttxp_t) dma64_getnexttxp,
+	(di_peeknexttxp_t) _dma_peeknexttxp,
+	(di_txblock_t) _dma_txblock,
+	(di_txunblock_t) _dma_txunblock,
+	(di_txactive_t) _dma_txactive,
+	(di_txrotate_t) dma64_txrotate,
+
+	(di_rxinit_t) _dma_rxinit,
+	(di_rxreset_t) dma64_rxreset,
+	(di_rxidle_t) dma64_rxidle,
+	(di_rxstopped_t) dma64_rxstopped,
+	(di_rxenable_t) _dma_rxenable,
+	(di_rxenabled_t) dma64_rxenabled,
+	(di_rx_t) _dma_rx,
+	(di_rxfill_t) _dma_rxfill,
+	(di_rxreclaim_t) _dma_rxreclaim,
+	(di_getnextrxp_t) _dma_getnextrxp,
+	(di_peeknextrxp_t) _dma_peeknextrxp,
+	(di_rxparam_get_t) _dma_rx_param_get,
+
+	(di_fifoloopbackenable_t) _dma_fifoloopbackenable,
+	(di_getvar_t) _dma_getvar,
+	(di_counterreset_t) _dma_counterreset,
+	(di_ctrlflags_t) _dma_ctrlflags,
+	NULL,
+	NULL,
+	NULL,
+	(di_rxactive_t) _dma_rxactive,
+	(di_txpending_t) _dma_txpending,
+	(di_txcommitted_t) _dma_txcommitted,
+	39
+};
+
+struct hnddma_pub *dma_attach(char *name, si_t *sih,
+		     void *dmaregstx, void *dmaregsrx, uint ntxd,
+		     uint nrxd, uint rxbufsize, int rxextheadroom,
+		     uint nrxpost, uint rxoffset, uint *msg_level)
+{
+	dma_info_t *di;
+	uint size;
+
+	/* allocate private info structure */
+	di = kzalloc(sizeof(dma_info_t), GFP_ATOMIC);
+	if (di == NULL) {
+#ifdef BCMDBG
+		printk(KERN_ERR "dma_attach: out of memory\n");
+#endif
+		return NULL;
+	}
+
+	di->msg_level = msg_level ? msg_level : &dma_msg_level;
+
+
+	di->dma64 = ((ai_core_sflags(sih, 0, 0) & SISF_DMA64) == SISF_DMA64);
+
+	/* init dma reg pointer */
+	di->d64txregs = (dma64regs_t *) dmaregstx;
+	di->d64rxregs = (dma64regs_t *) dmaregsrx;
+	di->hnddma.di_fn = (const di_fcn_t *)&dma64proc;
+
+	/* Default flags (which can be changed by the driver calling dma_ctrlflags
+	 * before enable): For backwards compatibility both Rx Overflow Continue
+	 * and Parity are DISABLED.
+	 * supports it.
+	 */
+	di->hnddma.di_fn->ctrlflags(&di->hnddma, DMA_CTRL_ROC | DMA_CTRL_PEN,
+				    0);
+
+	DMA_TRACE(("%s: dma_attach: %s flags 0x%x ntxd %d nrxd %d "
+		   "rxbufsize %d rxextheadroom %d nrxpost %d rxoffset %d "
+		   "dmaregstx %p dmaregsrx %p\n", name, "DMA64",
+		   di->hnddma.dmactrlflags, ntxd, nrxd, rxbufsize,
+		   rxextheadroom, nrxpost, rxoffset, dmaregstx, dmaregsrx));
+
+	/* make a private copy of our callers name */
+	strncpy(di->name, name, MAXNAMEL);
+	di->name[MAXNAMEL - 1] = '\0';
+
+	di->pbus = ((struct si_info *)sih)->pbus;
+
+	/* save tunables */
+	di->ntxd = (u16) ntxd;
+	di->nrxd = (u16) nrxd;
+
+	/* the actual dma size doesn't include the extra headroom */
+	di->rxextrahdrroom =
+	    (rxextheadroom == -1) ? BCMEXTRAHDROOM : rxextheadroom;
+	if (rxbufsize > BCMEXTRAHDROOM)
+		di->rxbufsize = (u16) (rxbufsize - di->rxextrahdrroom);
+	else
+		di->rxbufsize = (u16) rxbufsize;
+
+	di->nrxpost = (u16) nrxpost;
+	di->rxoffset = (u8) rxoffset;
+
+	/*
+	 * figure out the DMA physical address offset for dd and data
+	 *     PCI/PCIE: they map silicon backplace address to zero based memory, need offset
+	 *     Other bus: use zero
+	 *     SI_BUS BIGENDIAN kludge: use sdram swapped region for data buffer, not descriptor
+	 */
+	di->ddoffsetlow = 0;
+	di->dataoffsetlow = 0;
+	/* for pci bus, add offset */
+	if (sih->bustype == PCI_BUS) {
+		/* pcie with DMA64 */
+		di->ddoffsetlow = 0;
+		di->ddoffsethigh = SI_PCIE_DMA_H32;
+		di->dataoffsetlow = di->ddoffsetlow;
+		di->dataoffsethigh = di->ddoffsethigh;
+	}
+#if defined(__mips__) && defined(IL_BIGENDIAN)
+	di->dataoffsetlow = di->dataoffsetlow + SI_SDRAM_SWAPPED;
+#endif				/* defined(__mips__) && defined(IL_BIGENDIAN) */
+	/* WAR64450 : DMACtl.Addr ext fields are not supported in SDIOD core. */
+	if ((ai_coreid(sih) == SDIOD_CORE_ID)
+	    && ((ai_corerev(sih) > 0) && (ai_corerev(sih) <= 2)))
+		di->addrext = 0;
+	else if ((ai_coreid(sih) == I2S_CORE_ID) &&
+		 ((ai_corerev(sih) == 0) || (ai_corerev(sih) == 1)))
+		di->addrext = 0;
+	else
+		di->addrext = _dma_isaddrext(di);
+
+	/* does the descriptors need to be aligned and if yes, on 4K/8K or not */
+	di->aligndesc_4k = _dma_descriptor_align(di);
+	if (di->aligndesc_4k) {
+		di->dmadesc_align = D64RINGALIGN_BITS;
+		if ((ntxd < D64MAXDD / 2) && (nrxd < D64MAXDD / 2)) {
+			/* for smaller dd table, HW relax alignment reqmnt */
+			di->dmadesc_align = D64RINGALIGN_BITS - 1;
+		}
+	} else
+		di->dmadesc_align = 4;	/* 16 byte alignment */
+
+	DMA_NONE(("DMA descriptor align_needed %d, align %d\n",
+		  di->aligndesc_4k, di->dmadesc_align));
+
+	/* allocate tx packet pointer vector */
+	if (ntxd) {
+		size = ntxd * sizeof(void *);
+		di->txp = kzalloc(size, GFP_ATOMIC);
+		if (di->txp == NULL) {
+			DMA_ERROR(("%s: dma_attach: out of tx memory\n", di->name));
+			goto fail;
+		}
+	}
+
+	/* allocate rx packet pointer vector */
+	if (nrxd) {
+		size = nrxd * sizeof(void *);
+		di->rxp = kzalloc(size, GFP_ATOMIC);
+		if (di->rxp == NULL) {
+			DMA_ERROR(("%s: dma_attach: out of rx memory\n", di->name));
+			goto fail;
+		}
+	}
+
+	/* allocate transmit descriptor ring, only need ntxd descriptors but it must be aligned */
+	if (ntxd) {
+		if (!_dma_alloc(di, DMA_TX))
+			goto fail;
+	}
+
+	/* allocate receive descriptor ring, only need nrxd descriptors but it must be aligned */
+	if (nrxd) {
+		if (!_dma_alloc(di, DMA_RX))
+			goto fail;
+	}
+
+	if ((di->ddoffsetlow != 0) && !di->addrext) {
+		if (PHYSADDRLO(di->txdpa) > SI_PCI_DMA_SZ) {
+			DMA_ERROR(("%s: dma_attach: txdpa 0x%x: addrext not supported\n", di->name, (u32) PHYSADDRLO(di->txdpa)));
+			goto fail;
+		}
+		if (PHYSADDRLO(di->rxdpa) > SI_PCI_DMA_SZ) {
+			DMA_ERROR(("%s: dma_attach: rxdpa 0x%x: addrext not supported\n", di->name, (u32) PHYSADDRLO(di->rxdpa)));
+			goto fail;
+		}
+	}
+
+	DMA_TRACE(("ddoffsetlow 0x%x ddoffsethigh 0x%x dataoffsetlow 0x%x dataoffsethigh " "0x%x addrext %d\n", di->ddoffsetlow, di->ddoffsethigh, di->dataoffsetlow, di->dataoffsethigh, di->addrext));
+
+	/* allocate DMA mapping vectors */
+	if (DMASGLIST_ENAB) {
+		if (ntxd) {
+			size = ntxd * sizeof(hnddma_seg_map_t);
+			di->txp_dmah = kzalloc(size, GFP_ATOMIC);
+			if (di->txp_dmah == NULL)
+				goto fail;
+		}
+
+		if (nrxd) {
+			size = nrxd * sizeof(hnddma_seg_map_t);
+			di->rxp_dmah = kzalloc(size, GFP_ATOMIC);
+			if (di->rxp_dmah == NULL)
+				goto fail;
+		}
+	}
+
+	return (struct hnddma_pub *) di;
+
+ fail:
+	_dma_detach(di);
+	return NULL;
+}
+
+/* Check for odd number of 1's */
+static inline u32 parity32(u32 data)
+{
+	data ^= data >> 16;
+	data ^= data >> 8;
+	data ^= data >> 4;
+	data ^= data >> 2;
+	data ^= data >> 1;
+
+	return data & 1;
+}
+
+#define DMA64_DD_PARITY(dd)  parity32((dd)->addrlow ^ (dd)->addrhigh ^ (dd)->ctrl1 ^ (dd)->ctrl2)
+
+static inline void
+dma64_dd_upd(dma_info_t *di, dma64dd_t *ddring, dmaaddr_t pa, uint outidx,
+	     u32 *flags, u32 bufcount)
+{
+	u32 ctrl2 = bufcount & D64_CTRL2_BC_MASK;
+
+	/* PCI bus with big(>1G) physical address, use address extension */
+#if defined(__mips__) && defined(IL_BIGENDIAN)
+	if ((di->dataoffsetlow == SI_SDRAM_SWAPPED)
+	    || !(PHYSADDRLO(pa) & PCI32ADDR_HIGH)) {
+#else
+	if ((di->dataoffsetlow == 0) || !(PHYSADDRLO(pa) & PCI32ADDR_HIGH)) {
+#endif				/* defined(__mips__) && defined(IL_BIGENDIAN) */
+
+		W_SM(&ddring[outidx].addrlow,
+		     BUS_SWAP32(PHYSADDRLO(pa) + di->dataoffsetlow));
+		W_SM(&ddring[outidx].addrhigh,
+		     BUS_SWAP32(PHYSADDRHI(pa) + di->dataoffsethigh));
+		W_SM(&ddring[outidx].ctrl1, BUS_SWAP32(*flags));
+		W_SM(&ddring[outidx].ctrl2, BUS_SWAP32(ctrl2));
+	} else {
+		/* address extension for 32-bit PCI */
+		u32 ae;
+
+		ae = (PHYSADDRLO(pa) & PCI32ADDR_HIGH) >> PCI32ADDR_HIGH_SHIFT;
+		PHYSADDRLO(pa) &= ~PCI32ADDR_HIGH;
+
+		ctrl2 |= (ae << D64_CTRL2_AE_SHIFT) & D64_CTRL2_AE;
+		W_SM(&ddring[outidx].addrlow,
+		     BUS_SWAP32(PHYSADDRLO(pa) + di->dataoffsetlow));
+		W_SM(&ddring[outidx].addrhigh,
+		     BUS_SWAP32(0 + di->dataoffsethigh));
+		W_SM(&ddring[outidx].ctrl1, BUS_SWAP32(*flags));
+		W_SM(&ddring[outidx].ctrl2, BUS_SWAP32(ctrl2));
+	}
+	if (di->hnddma.dmactrlflags & DMA_CTRL_PEN) {
+		if (DMA64_DD_PARITY(&ddring[outidx])) {
+			W_SM(&ddring[outidx].ctrl2,
+			     BUS_SWAP32(ctrl2 | D64_CTRL2_PARITY));
+		}
+	}
+}
+
+static bool _dma_alloc(dma_info_t *di, uint direction)
+{
+	return dma64_alloc(di, direction);
+}
+
+void *dma_alloc_consistent(struct pci_dev *pdev, uint size, u16 align_bits,
+			       uint *alloced, unsigned long *pap)
+{
+	if (align_bits) {
+		u16 align = (1 << align_bits);
+		if (!IS_ALIGNED(PAGE_SIZE, align))
+			size += align;
+		*alloced = size;
+	}
+	return pci_alloc_consistent(pdev, size, (dma_addr_t *) pap);
+}
+
+/* !! may be called with core in reset */
+static void _dma_detach(dma_info_t *di)
+{
+
+	DMA_TRACE(("%s: dma_detach\n", di->name));
+
+	/* free dma descriptor rings */
+	if (di->txd64)
+		pci_free_consistent(di->pbus, di->txdalloc,
+				    ((s8 *)di->txd64 - di->txdalign),
+				    (di->txdpaorig));
+	if (di->rxd64)
+		pci_free_consistent(di->pbus, di->rxdalloc,
+				    ((s8 *)di->rxd64 - di->rxdalign),
+				    (di->rxdpaorig));
+
+	/* free packet pointer vectors */
+	kfree(di->txp);
+	kfree(di->rxp);
+
+	/* free tx packet DMA handles */
+	kfree(di->txp_dmah);
+
+	/* free rx packet DMA handles */
+	kfree(di->rxp_dmah);
+
+	/* free our private info structure */
+	kfree(di);
+
+}
+
+static bool _dma_descriptor_align(dma_info_t *di)
+{
+	u32 addrl;
+
+	/* Check to see if the descriptors need to be aligned on 4K/8K or not */
+	if (di->d64txregs != NULL) {
+		W_REG(&di->d64txregs->addrlow, 0xff0);
+		addrl = R_REG(&di->d64txregs->addrlow);
+		if (addrl != 0)
+			return false;
+	} else if (di->d64rxregs != NULL) {
+		W_REG(&di->d64rxregs->addrlow, 0xff0);
+		addrl = R_REG(&di->d64rxregs->addrlow);
+		if (addrl != 0)
+			return false;
+	}
+	return true;
+}
+
+/* return true if this dma engine supports DmaExtendedAddrChanges, otherwise false */
+static bool _dma_isaddrext(dma_info_t *di)
+{
+	/* DMA64 supports full 32- or 64-bit operation. AE is always valid */
+
+	/* not all tx or rx channel are available */
+	if (di->d64txregs != NULL) {
+		if (!_dma64_addrext(di->d64txregs)) {
+			DMA_ERROR(("%s: _dma_isaddrext: DMA64 tx doesn't have "
+				   "AE set\n", di->name));
+		}
+		return true;
+	} else if (di->d64rxregs != NULL) {
+		if (!_dma64_addrext(di->d64rxregs)) {
+			DMA_ERROR(("%s: _dma_isaddrext: DMA64 rx doesn't have "
+				   "AE set\n", di->name));
+		}
+		return true;
+	}
+	return false;
+}
+
+/* initialize descriptor table base address */
+static void _dma_ddtable_init(dma_info_t *di, uint direction, dmaaddr_t pa)
+{
+	if (!di->aligndesc_4k) {
+		if (direction == DMA_TX)
+			di->xmtptrbase = PHYSADDRLO(pa);
+		else
+			di->rcvptrbase = PHYSADDRLO(pa);
+	}
+
+	if ((di->ddoffsetlow == 0)
+	    || !(PHYSADDRLO(pa) & PCI32ADDR_HIGH)) {
+		if (direction == DMA_TX) {
+			W_REG(&di->d64txregs->addrlow,
+			      (PHYSADDRLO(pa) + di->ddoffsetlow));
+			W_REG(&di->d64txregs->addrhigh,
+			      (PHYSADDRHI(pa) + di->ddoffsethigh));
+		} else {
+			W_REG(&di->d64rxregs->addrlow,
+			      (PHYSADDRLO(pa) + di->ddoffsetlow));
+			W_REG(&di->d64rxregs->addrhigh,
+				(PHYSADDRHI(pa) + di->ddoffsethigh));
+		}
+	} else {
+		/* DMA64 32bits address extension */
+		u32 ae;
+
+		/* shift the high bit(s) from pa to ae */
+		ae = (PHYSADDRLO(pa) & PCI32ADDR_HIGH) >>
+		    PCI32ADDR_HIGH_SHIFT;
+		PHYSADDRLO(pa) &= ~PCI32ADDR_HIGH;
+
+		if (direction == DMA_TX) {
+			W_REG(&di->d64txregs->addrlow,
+			      (PHYSADDRLO(pa) + di->ddoffsetlow));
+			W_REG(&di->d64txregs->addrhigh,
+			      di->ddoffsethigh);
+			SET_REG(&di->d64txregs->control,
+				D64_XC_AE, (ae << D64_XC_AE_SHIFT));
+		} else {
+			W_REG(&di->d64rxregs->addrlow,
+			      (PHYSADDRLO(pa) + di->ddoffsetlow));
+			W_REG(&di->d64rxregs->addrhigh,
+			      di->ddoffsethigh);
+			SET_REG(&di->d64rxregs->control,
+				D64_RC_AE, (ae << D64_RC_AE_SHIFT));
+		}
+	}
+}
+
+static void _dma_fifoloopbackenable(dma_info_t *di)
+{
+	DMA_TRACE(("%s: dma_fifoloopbackenable\n", di->name));
+
+	OR_REG(&di->d64txregs->control, D64_XC_LE);
+}
+
+static void _dma_rxinit(dma_info_t *di)
+{
+	DMA_TRACE(("%s: dma_rxinit\n", di->name));
+
+	if (di->nrxd == 0)
+		return;
+
+	di->rxin = di->rxout = 0;
+
+	/* clear rx descriptor ring */
+	memset((void *)di->rxd64, '\0',
+		(di->nrxd * sizeof(dma64dd_t)));
+
+	/* DMA engine with out alignment requirement requires table to be inited
+	 * before enabling the engine
+	 */
+	if (!di->aligndesc_4k)
+		_dma_ddtable_init(di, DMA_RX, di->rxdpa);
+
+	_dma_rxenable(di);
+
+	if (di->aligndesc_4k)
+		_dma_ddtable_init(di, DMA_RX, di->rxdpa);
+}
+
+static void _dma_rxenable(dma_info_t *di)
+{
+	uint dmactrlflags = di->hnddma.dmactrlflags;
+	u32 control;
+
+	DMA_TRACE(("%s: dma_rxenable\n", di->name));
+
+	control =
+	    (R_REG(&di->d64rxregs->control) & D64_RC_AE) |
+	    D64_RC_RE;
+
+	if ((dmactrlflags & DMA_CTRL_PEN) == 0)
+		control |= D64_RC_PD;
+
+	if (dmactrlflags & DMA_CTRL_ROC)
+		control |= D64_RC_OC;
+
+	W_REG(&di->d64rxregs->control,
+		((di->rxoffset << D64_RC_RO_SHIFT) | control));
+}
+
+static void
+_dma_rx_param_get(dma_info_t *di, u16 *rxoffset, u16 *rxbufsize)
+{
+	/* the normal values fit into 16 bits */
+	*rxoffset = (u16) di->rxoffset;
+	*rxbufsize = (u16) di->rxbufsize;
+}
+
+/* !! rx entry routine
+ * returns a pointer to the next frame received, or NULL if there are no more
+ *   if DMA_CTRL_RXMULTI is defined, DMA scattering(multiple buffers) is supported
+ *      with pkts chain
+ *   otherwise, it's treated as giant pkt and will be tossed.
+ *   The DMA scattering starts with normal DMA header, followed by first buffer data.
+ *   After it reaches the max size of buffer, the data continues in next DMA descriptor
+ *   buffer WITHOUT DMA header
+ */
+static void *_dma_rx(dma_info_t *di)
+{
+	struct sk_buff *p, *head, *tail;
+	uint len;
+	uint pkt_len;
+	int resid = 0;
+
+ next_frame:
+	head = _dma_getnextrxp(di, false);
+	if (head == NULL)
+		return NULL;
+
+	len = le16_to_cpu(*(u16 *) (head->data));
+	DMA_TRACE(("%s: dma_rx len %d\n", di->name, len));
+	dma_spin_for_len(len, head);
+
+	/* set actual length */
+	pkt_len = min((di->rxoffset + len), di->rxbufsize);
+	__skb_trim(head, pkt_len);
+	resid = len - (di->rxbufsize - di->rxoffset);
+
+	/* check for single or multi-buffer rx */
+	if (resid > 0) {
+		tail = head;
+		while ((resid > 0) && (p = _dma_getnextrxp(di, false))) {
+			tail->next = p;
+			pkt_len = min(resid, (int)di->rxbufsize);
+			__skb_trim(p, pkt_len);
+
+			tail = p;
+			resid -= di->rxbufsize;
+		}
+
+#ifdef BCMDBG
+		if (resid > 0) {
+			uint cur;
+			cur =
+			    B2I(((R_REG(&di->d64rxregs->status0) &
+				  D64_RS0_CD_MASK) -
+				 di->rcvptrbase) & D64_RS0_CD_MASK,
+				dma64dd_t);
+			DMA_ERROR(("_dma_rx, rxin %d rxout %d, hw_curr %d\n",
+				   di->rxin, di->rxout, cur));
+		}
+#endif				/* BCMDBG */
+
+		if ((di->hnddma.dmactrlflags & DMA_CTRL_RXMULTI) == 0) {
+			DMA_ERROR(("%s: dma_rx: bad frame length (%d)\n",
+				   di->name, len));
+			bcm_pkt_buf_free_skb(head);
+			di->hnddma.rxgiants++;
+			goto next_frame;
+		}
+	}
+
+	return head;
+}
+
+/* post receive buffers
+ *  return false is refill failed completely and ring is empty
+ *  this will stall the rx dma and user might want to call rxfill again asap
+ *  This unlikely happens on memory-rich NIC, but often on memory-constrained dongle
+ */
+static bool _dma_rxfill(dma_info_t *di)
+{
+	struct sk_buff *p;
+	u16 rxin, rxout;
+	u32 flags = 0;
+	uint n;
+	uint i;
+	dmaaddr_t pa;
+	uint extra_offset = 0;
+	bool ring_empty;
+
+	ring_empty = false;
+
+	/*
+	 * Determine how many receive buffers we're lacking
+	 * from the full complement, allocate, initialize,
+	 * and post them, then update the chip rx lastdscr.
+	 */
+
+	rxin = di->rxin;
+	rxout = di->rxout;
+
+	n = di->nrxpost - NRXDACTIVE(rxin, rxout);
+
+	DMA_TRACE(("%s: dma_rxfill: post %d\n", di->name, n));
+
+	if (di->rxbufsize > BCMEXTRAHDROOM)
+		extra_offset = di->rxextrahdrroom;
+
+	for (i = 0; i < n; i++) {
+		/* the di->rxbufsize doesn't include the extra headroom, we need to add it to the
+		   size to be allocated
+		 */
+
+		p = bcm_pkt_buf_get_skb(di->rxbufsize + extra_offset);
+
+		if (p == NULL) {
+			DMA_ERROR(("%s: dma_rxfill: out of rxbufs\n",
+				   di->name));
+			if (i == 0 && dma64_rxidle(di)) {
+				DMA_ERROR(("%s: rxfill64: ring is empty !\n",
+					   di->name));
+				ring_empty = true;
+			}
+			di->hnddma.rxnobuf++;
+			break;
+		}
+		/* reserve an extra headroom, if applicable */
+		if (extra_offset)
+			skb_pull(p, extra_offset);
+
+		/* Do a cached write instead of uncached write since DMA_MAP
+		 * will flush the cache.
+		 */
+		*(u32 *) (p->data) = 0;
+
+		if (DMASGLIST_ENAB)
+			memset(&di->rxp_dmah[rxout], 0,
+				sizeof(hnddma_seg_map_t));
+
+		pa = pci_map_single(di->pbus, p->data,
+			di->rxbufsize, PCI_DMA_FROMDEVICE);
+
+		/* save the free packet pointer */
+		di->rxp[rxout] = p;
+
+		/* reset flags for each descriptor */
+		flags = 0;
+		if (rxout == (di->nrxd - 1))
+			flags = D64_CTRL1_EOT;
+
+		dma64_dd_upd(di, di->rxd64, pa, rxout, &flags,
+			     di->rxbufsize);
+		rxout = NEXTRXD(rxout);
+	}
+
+	di->rxout = rxout;
+
+	/* update the chip lastdscr pointer */
+	W_REG(&di->d64rxregs->ptr,
+	      di->rcvptrbase + I2B(rxout, dma64dd_t));
+
+	return ring_empty;
+}
+
+/* like getnexttxp but no reclaim */
+static void *_dma_peeknexttxp(dma_info_t *di)
+{
+	uint end, i;
+
+	if (di->ntxd == 0)
+		return NULL;
+
+	end =
+	    B2I(((R_REG(&di->d64txregs->status0) &
+		  D64_XS0_CD_MASK) - di->xmtptrbase) & D64_XS0_CD_MASK,
+		  dma64dd_t);
+
+	for (i = di->txin; i != end; i = NEXTTXD(i))
+		if (di->txp[i])
+			return di->txp[i];
+
+	return NULL;
+}
+
+/* like getnextrxp but not take off the ring */
+static void *_dma_peeknextrxp(dma_info_t *di)
+{
+	uint end, i;
+
+	if (di->nrxd == 0)
+		return NULL;
+
+	end =
+	    B2I(((R_REG(&di->d64rxregs->status0) &
+		  D64_RS0_CD_MASK) - di->rcvptrbase) & D64_RS0_CD_MASK,
+		  dma64dd_t);
+
+	for (i = di->rxin; i != end; i = NEXTRXD(i))
+		if (di->rxp[i])
+			return di->rxp[i];
+
+	return NULL;
+}
+
+static void _dma_rxreclaim(dma_info_t *di)
+{
+	void *p;
+
+	DMA_TRACE(("%s: dma_rxreclaim\n", di->name));
+
+	while ((p = _dma_getnextrxp(di, true)))
+		bcm_pkt_buf_free_skb(p);
+}
+
+static void *_dma_getnextrxp(dma_info_t *di, bool forceall)
+{
+	if (di->nrxd == 0)
+		return NULL;
+
+	return dma64_getnextrxp(di, forceall);
+}
+
+static void _dma_txblock(dma_info_t *di)
+{
+	di->hnddma.txavail = 0;
+}
+
+static void _dma_txunblock(dma_info_t *di)
+{
+	di->hnddma.txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1;
+}
+
+static uint _dma_txactive(dma_info_t *di)
+{
+	return NTXDACTIVE(di->txin, di->txout);
+}
+
+static uint _dma_txpending(dma_info_t *di)
+{
+	uint curr;
+
+	curr =
+	    B2I(((R_REG(&di->d64txregs->status0) &
+		  D64_XS0_CD_MASK) - di->xmtptrbase) & D64_XS0_CD_MASK,
+		  dma64dd_t);
+
+	return NTXDACTIVE(curr, di->txout);
+}
+
+static uint _dma_txcommitted(dma_info_t *di)
+{
+	uint ptr;
+	uint txin = di->txin;
+
+	if (txin == di->txout)
+		return 0;
+
+	ptr = B2I(R_REG(&di->d64txregs->ptr), dma64dd_t);
+
+	return NTXDACTIVE(di->txin, ptr);
+}
+
+static uint _dma_rxactive(dma_info_t *di)
+{
+	return NRXDACTIVE(di->rxin, di->rxout);
+}
+
+static void _dma_counterreset(dma_info_t *di)
+{
+	/* reset all software counter */
+	di->hnddma.rxgiants = 0;
+	di->hnddma.rxnobuf = 0;
+	di->hnddma.txnobuf = 0;
+}
+
+static uint _dma_ctrlflags(dma_info_t *di, uint mask, uint flags)
+{
+	uint dmactrlflags = di->hnddma.dmactrlflags;
+
+	if (di == NULL) {
+		DMA_ERROR(("%s: _dma_ctrlflags: NULL dma handle\n", di->name));
+		return 0;
+	}
+
+	dmactrlflags &= ~mask;
+	dmactrlflags |= flags;
+
+	/* If trying to enable parity, check if parity is actually supported */
+	if (dmactrlflags & DMA_CTRL_PEN) {
+		u32 control;
+
+		control = R_REG(&di->d64txregs->control);
+		W_REG(&di->d64txregs->control,
+		      control | D64_XC_PD);
+		if (R_REG(&di->d64txregs->control) & D64_XC_PD) {
+			/* We *can* disable it so it is supported,
+			 * restore control register
+			 */
+			W_REG(&di->d64txregs->control,
+			control);
+		} else {
+			/* Not supported, don't allow it to be enabled */
+			dmactrlflags &= ~DMA_CTRL_PEN;
+		}
+	}
+
+	di->hnddma.dmactrlflags = dmactrlflags;
+
+	return dmactrlflags;
+}
+
+/* get the address of the var in order to change later */
+static unsigned long _dma_getvar(dma_info_t *di, const char *name)
+{
+	if (!strcmp(name, "&txavail"))
+		return (unsigned long)&(di->hnddma.txavail);
+	return 0;
+}
+
+static
+u8 dma_align_sizetobits(uint size)
+{
+	u8 bitpos = 0;
+	while (size >>= 1) {
+		bitpos++;
+	}
+	return bitpos;
+}
+
+/* This function ensures that the DMA descriptor ring will not get allocated
+ * across Page boundary. If the allocation is done across the page boundary
+ * at the first time, then it is freed and the allocation is done at
+ * descriptor ring size aligned location. This will ensure that the ring will
+ * not cross page boundary
+ */
+static void *dma_ringalloc(dma_info_t *di, u32 boundary, uint size,
+			   u16 *alignbits, uint *alloced,
+			   dmaaddr_t *descpa)
+{
+	void *va;
+	u32 desc_strtaddr;
+	u32 alignbytes = 1 << *alignbits;
+
+	va = dma_alloc_consistent(di->pbus, size, *alignbits, alloced, descpa);
+
+	if (NULL == va)
+		return NULL;
+
+	desc_strtaddr = (u32) roundup((unsigned long)va, alignbytes);
+	if (((desc_strtaddr + size - 1) & boundary) != (desc_strtaddr
+							& boundary)) {
+		*alignbits = dma_align_sizetobits(size);
+		pci_free_consistent(di->pbus, size, va, *descpa);
+		va = dma_alloc_consistent(di->pbus, size, *alignbits,
+			alloced, descpa);
+	}
+	return va;
+}
+
+/* 64-bit DMA functions */
+
+static void dma64_txinit(dma_info_t *di)
+{
+	u32 control = D64_XC_XE;
+
+	DMA_TRACE(("%s: dma_txinit\n", di->name));
+
+	if (di->ntxd == 0)
+		return;
+
+	di->txin = di->txout = 0;
+	di->hnddma.txavail = di->ntxd - 1;
+
+	/* clear tx descriptor ring */
+	memset((void *)di->txd64, '\0', (di->ntxd * sizeof(dma64dd_t)));
+
+	/* DMA engine with out alignment requirement requires table to be inited
+	 * before enabling the engine
+	 */
+	if (!di->aligndesc_4k)
+		_dma_ddtable_init(di, DMA_TX, di->txdpa);
+
+	if ((di->hnddma.dmactrlflags & DMA_CTRL_PEN) == 0)
+		control |= D64_XC_PD;
+	OR_REG(&di->d64txregs->control, control);
+
+	/* DMA engine with alignment requirement requires table to be inited
+	 * before enabling the engine
+	 */
+	if (di->aligndesc_4k)
+		_dma_ddtable_init(di, DMA_TX, di->txdpa);
+}
+
+static bool dma64_txenabled(dma_info_t *di)
+{
+	u32 xc;
+
+	/* If the chip is dead, it is not enabled :-) */
+	xc = R_REG(&di->d64txregs->control);
+	return (xc != 0xffffffff) && (xc & D64_XC_XE);
+}
+
+static void dma64_txsuspend(dma_info_t *di)
+{
+	DMA_TRACE(("%s: dma_txsuspend\n", di->name));
+
+	if (di->ntxd == 0)
+		return;
+
+	OR_REG(&di->d64txregs->control, D64_XC_SE);
+}
+
+static void dma64_txresume(dma_info_t *di)
+{
+	DMA_TRACE(("%s: dma_txresume\n", di->name));
+
+	if (di->ntxd == 0)
+		return;
+
+	AND_REG(&di->d64txregs->control, ~D64_XC_SE);
+}
+
+static bool dma64_txsuspended(dma_info_t *di)
+{
+	return (di->ntxd == 0) ||
+	    ((R_REG(&di->d64txregs->control) & D64_XC_SE) ==
+	     D64_XC_SE);
+}
+
+static void dma64_txreclaim(dma_info_t *di, txd_range_t range)
+{
+	void *p;
+
+	DMA_TRACE(("%s: dma_txreclaim %s\n", di->name,
+		   (range == HNDDMA_RANGE_ALL) ? "all" :
+		   ((range ==
+		     HNDDMA_RANGE_TRANSMITTED) ? "transmitted" :
+		    "transferred")));
+
+	if (di->txin == di->txout)
+		return;
+
+	while ((p = dma64_getnexttxp(di, range))) {
+		/* For unframed data, we don't have any packets to free */
+		if (!(di->hnddma.dmactrlflags & DMA_CTRL_UNFRAMED))
+			bcm_pkt_buf_free_skb(p);
+	}
+}
+
+static bool dma64_txstopped(dma_info_t *di)
+{
+	return ((R_REG(&di->d64txregs->status0) & D64_XS0_XS_MASK) ==
+		D64_XS0_XS_STOPPED);
+}
+
+static bool dma64_rxstopped(dma_info_t *di)
+{
+	return ((R_REG(&di->d64rxregs->status0) & D64_RS0_RS_MASK) ==
+		D64_RS0_RS_STOPPED);
+}
+
+static bool dma64_alloc(dma_info_t *di, uint direction)
+{
+	u16 size;
+	uint ddlen;
+	void *va;
+	uint alloced = 0;
+	u16 align;
+	u16 align_bits;
+
+	ddlen = sizeof(dma64dd_t);
+
+	size = (direction == DMA_TX) ? (di->ntxd * ddlen) : (di->nrxd * ddlen);
+	align_bits = di->dmadesc_align;
+	align = (1 << align_bits);
+
+	if (direction == DMA_TX) {
+		va = dma_ringalloc(di, D64RINGALIGN, size, &align_bits,
+			&alloced, &di->txdpaorig);
+		if (va == NULL) {
+			DMA_ERROR(("%s: dma64_alloc: DMA_ALLOC_CONSISTENT(ntxd) failed\n", di->name));
+			return false;
+		}
+		align = (1 << align_bits);
+		di->txd64 = (dma64dd_t *) roundup((unsigned long)va, align);
+		di->txdalign = (uint) ((s8 *)di->txd64 - (s8 *) va);
+		PHYSADDRLOSET(di->txdpa,
+			      PHYSADDRLO(di->txdpaorig) + di->txdalign);
+		PHYSADDRHISET(di->txdpa, PHYSADDRHI(di->txdpaorig));
+		di->txdalloc = alloced;
+	} else {
+		va = dma_ringalloc(di, D64RINGALIGN, size, &align_bits,
+			&alloced, &di->rxdpaorig);
+		if (va == NULL) {
+			DMA_ERROR(("%s: dma64_alloc: DMA_ALLOC_CONSISTENT(nrxd) failed\n", di->name));
+			return false;
+		}
+		align = (1 << align_bits);
+		di->rxd64 = (dma64dd_t *) roundup((unsigned long)va, align);
+		di->rxdalign = (uint) ((s8 *)di->rxd64 - (s8 *) va);
+		PHYSADDRLOSET(di->rxdpa,
+			      PHYSADDRLO(di->rxdpaorig) + di->rxdalign);
+		PHYSADDRHISET(di->rxdpa, PHYSADDRHI(di->rxdpaorig));
+		di->rxdalloc = alloced;
+	}
+
+	return true;
+}
+
+static bool dma64_txreset(dma_info_t *di)
+{
+	u32 status;
+
+	if (di->ntxd == 0)
+		return true;
+
+	/* suspend tx DMA first */
+	W_REG(&di->d64txregs->control, D64_XC_SE);
+	SPINWAIT(((status =
+		   (R_REG(&di->d64txregs->status0) & D64_XS0_XS_MASK))
+		  != D64_XS0_XS_DISABLED) && (status != D64_XS0_XS_IDLE)
+		 && (status != D64_XS0_XS_STOPPED), 10000);
+
+	W_REG(&di->d64txregs->control, 0);
+	SPINWAIT(((status =
+		   (R_REG(&di->d64txregs->status0) & D64_XS0_XS_MASK))
+		  != D64_XS0_XS_DISABLED), 10000);
+
+	/* wait for the last transaction to complete */
+	udelay(300);
+
+	return status == D64_XS0_XS_DISABLED;
+}
+
+static bool dma64_rxidle(dma_info_t *di)
+{
+	DMA_TRACE(("%s: dma_rxidle\n", di->name));
+
+	if (di->nrxd == 0)
+		return true;
+
+	return ((R_REG(&di->d64rxregs->status0) & D64_RS0_CD_MASK) ==
+		(R_REG(&di->d64rxregs->ptr) & D64_RS0_CD_MASK));
+}
+
+static bool dma64_rxreset(dma_info_t *di)
+{
+	u32 status;
+
+	if (di->nrxd == 0)
+		return true;
+
+	W_REG(&di->d64rxregs->control, 0);
+	SPINWAIT(((status =
+		   (R_REG(&di->d64rxregs->status0) & D64_RS0_RS_MASK))
+		  != D64_RS0_RS_DISABLED), 10000);
+
+	return status == D64_RS0_RS_DISABLED;
+}
+
+static bool dma64_rxenabled(dma_info_t *di)
+{
+	u32 rc;
+
+	rc = R_REG(&di->d64rxregs->control);
+	return (rc != 0xffffffff) && (rc & D64_RC_RE);
+}
+
+static bool dma64_txsuspendedidle(dma_info_t *di)
+{
+
+	if (di->ntxd == 0)
+		return true;
+
+	if (!(R_REG(&di->d64txregs->control) & D64_XC_SE))
+		return 0;
+
+	if ((R_REG(&di->d64txregs->status0) & D64_XS0_XS_MASK) ==
+	    D64_XS0_XS_IDLE)
+		return 1;
+
+	return 0;
+}
+
+/* Useful when sending unframed data.  This allows us to get a progress report from the DMA.
+ * We return a pointer to the beginning of the DATA buffer of the current descriptor.
+ * If DMA is idle, we return NULL.
+ */
+static void *dma64_getpos(dma_info_t *di, bool direction)
+{
+	void *va;
+	bool idle;
+	u32 cd_offset;
+
+	if (direction == DMA_TX) {
+		cd_offset =
+		    R_REG(&di->d64txregs->status0) & D64_XS0_CD_MASK;
+		idle = !NTXDACTIVE(di->txin, di->txout);
+		va = di->txp[B2I(cd_offset, dma64dd_t)];
+	} else {
+		cd_offset =
+		    R_REG(&di->d64rxregs->status0) & D64_XS0_CD_MASK;
+		idle = !NRXDACTIVE(di->rxin, di->rxout);
+		va = di->rxp[B2I(cd_offset, dma64dd_t)];
+	}
+
+	/* If DMA is IDLE, return NULL */
+	if (idle) {
+		DMA_TRACE(("%s: DMA idle, return NULL\n", __func__));
+		va = NULL;
+	}
+
+	return va;
+}
+
+/* TX of unframed data
+ *
+ * Adds a DMA ring descriptor for the data pointed to by "buf".
+ * This is for DMA of a buffer of data and is unlike other hnddma TX functions
+ * that take a pointer to a "packet"
+ * Each call to this is results in a single descriptor being added for "len" bytes of
+ * data starting at "buf", it doesn't handle chained buffers.
+ */
+static int dma64_txunframed(dma_info_t *di, void *buf, uint len, bool commit)
+{
+	u16 txout;
+	u32 flags = 0;
+	dmaaddr_t pa;		/* phys addr */
+
+	txout = di->txout;
+
+	/* return nonzero if out of tx descriptors */
+	if (NEXTTXD(txout) == di->txin)
+		goto outoftxd;
+
+	if (len == 0)
+		return 0;
+
+	pa = pci_map_single(di->pbus, buf, len, PCI_DMA_TODEVICE);
+
+	flags = (D64_CTRL1_SOF | D64_CTRL1_IOC | D64_CTRL1_EOF);
+
+	if (txout == (di->ntxd - 1))
+		flags |= D64_CTRL1_EOT;
+
+	dma64_dd_upd(di, di->txd64, pa, txout, &flags, len);
+
+	/* save the buffer pointer - used by dma_getpos */
+	di->txp[txout] = buf;
+
+	txout = NEXTTXD(txout);
+	/* bump the tx descriptor index */
+	di->txout = txout;
+
+	/* kick the chip */
+	if (commit) {
+		W_REG(&di->d64txregs->ptr,
+		      di->xmtptrbase + I2B(txout, dma64dd_t));
+	}
+
+	/* tx flow control */
+	di->hnddma.txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1;
+
+	return 0;
+
+ outoftxd:
+	DMA_ERROR(("%s: %s: out of txds !!!\n", di->name, __func__));
+	di->hnddma.txavail = 0;
+	di->hnddma.txnobuf++;
+	return -1;
+}
+
+/* !! tx entry routine
+ * WARNING: call must check the return value for error.
+ *   the error(toss frames) could be fatal and cause many subsequent hard to debug problems
+ */
+static int dma64_txfast(dma_info_t *di, struct sk_buff *p0,
+				    bool commit)
+{
+	struct sk_buff *p, *next;
+	unsigned char *data;
+	uint len;
+	u16 txout;
+	u32 flags = 0;
+	dmaaddr_t pa;
+
+	DMA_TRACE(("%s: dma_txfast\n", di->name));
+
+	txout = di->txout;
+
+	/*
+	 * Walk the chain of packet buffers
+	 * allocating and initializing transmit descriptor entries.
+	 */
+	for (p = p0; p; p = next) {
+		uint nsegs, j;
+		hnddma_seg_map_t *map;
+
+		data = p->data;
+		len = p->len;
+		next = p->next;
+
+		/* return nonzero if out of tx descriptors */
+		if (NEXTTXD(txout) == di->txin)
+			goto outoftxd;
+
+		if (len == 0)
+			continue;
+
+		/* get physical address of buffer start */
+		if (DMASGLIST_ENAB)
+			memset(&di->txp_dmah[txout], 0,
+				sizeof(hnddma_seg_map_t));
+
+		pa = pci_map_single(di->pbus, data, len, PCI_DMA_TODEVICE);
+
+		if (DMASGLIST_ENAB) {
+			map = &di->txp_dmah[txout];
+
+			/* See if all the segments can be accounted for */
+			if (map->nsegs >
+			    (uint) (di->ntxd - NTXDACTIVE(di->txin, di->txout) -
+				    1))
+				goto outoftxd;
+
+			nsegs = map->nsegs;
+		} else
+			nsegs = 1;
+
+		for (j = 1; j <= nsegs; j++) {
+			flags = 0;
+			if (p == p0 && j == 1)
+				flags |= D64_CTRL1_SOF;
+
+			/* With a DMA segment list, Descriptor table is filled
+			 * using the segment list instead of looping over
+			 * buffers in multi-chain DMA. Therefore, EOF for SGLIST is when
+			 * end of segment list is reached.
+			 */
+			if ((!DMASGLIST_ENAB && next == NULL) ||
+			    (DMASGLIST_ENAB && j == nsegs))
+				flags |= (D64_CTRL1_IOC | D64_CTRL1_EOF);
+			if (txout == (di->ntxd - 1))
+				flags |= D64_CTRL1_EOT;
+
+			if (DMASGLIST_ENAB) {
+				len = map->segs[j - 1].length;
+				pa = map->segs[j - 1].addr;
+			}
+			dma64_dd_upd(di, di->txd64, pa, txout, &flags, len);
+
+			txout = NEXTTXD(txout);
+		}
+
+		/* See above. No need to loop over individual buffers */
+		if (DMASGLIST_ENAB)
+			break;
+	}
+
+	/* if last txd eof not set, fix it */
+	if (!(flags & D64_CTRL1_EOF))
+		W_SM(&di->txd64[PREVTXD(txout)].ctrl1,
+		     BUS_SWAP32(flags | D64_CTRL1_IOC | D64_CTRL1_EOF));
+
+	/* save the packet */
+	di->txp[PREVTXD(txout)] = p0;
+
+	/* bump the tx descriptor index */
+	di->txout = txout;
+
+	/* kick the chip */
+	if (commit)
+		W_REG(&di->d64txregs->ptr,
+		      di->xmtptrbase + I2B(txout, dma64dd_t));
+
+	/* tx flow control */
+	di->hnddma.txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1;
+
+	return 0;
+
+ outoftxd:
+	DMA_ERROR(("%s: dma_txfast: out of txds !!!\n", di->name));
+	bcm_pkt_buf_free_skb(p0);
+	di->hnddma.txavail = 0;
+	di->hnddma.txnobuf++;
+	return -1;
+}
+
+/*
+ * Reclaim next completed txd (txds if using chained buffers) in the range
+ * specified and return associated packet.
+ * If range is HNDDMA_RANGE_TRANSMITTED, reclaim descriptors that have be
+ * transmitted as noted by the hardware "CurrDescr" pointer.
+ * If range is HNDDMA_RANGE_TRANSFERED, reclaim descriptors that have be
+ * transferred by the DMA as noted by the hardware "ActiveDescr" pointer.
+ * If range is HNDDMA_RANGE_ALL, reclaim all txd(s) posted to the ring and
+ * return associated packet regardless of the value of hardware pointers.
+ */
+static void *dma64_getnexttxp(dma_info_t *di, txd_range_t range)
+{
+	u16 start, end, i;
+	u16 active_desc;
+	void *txp;
+
+	DMA_TRACE(("%s: dma_getnexttxp %s\n", di->name,
+		   (range == HNDDMA_RANGE_ALL) ? "all" :
+		   ((range ==
+		     HNDDMA_RANGE_TRANSMITTED) ? "transmitted" :
+		    "transferred")));
+
+	if (di->ntxd == 0)
+		return NULL;
+
+	txp = NULL;
+
+	start = di->txin;
+	if (range == HNDDMA_RANGE_ALL)
+		end = di->txout;
+	else {
+		dma64regs_t *dregs = di->d64txregs;
+
+		end =
+		    (u16) (B2I
+			      (((R_REG(&dregs->status0) &
+				 D64_XS0_CD_MASK) -
+				di->xmtptrbase) & D64_XS0_CD_MASK, dma64dd_t));
+
+		if (range == HNDDMA_RANGE_TRANSFERED) {
+			active_desc =
+			    (u16) (R_REG(&dregs->status1) &
+				      D64_XS1_AD_MASK);
+			active_desc =
+			    (active_desc - di->xmtptrbase) & D64_XS0_CD_MASK;
+			active_desc = B2I(active_desc, dma64dd_t);
+			if (end != active_desc)
+				end = PREVTXD(active_desc);
+		}
+	}
+
+	if ((start == 0) && (end > di->txout))
+		goto bogus;
+
+	for (i = start; i != end && !txp; i = NEXTTXD(i)) {
+		dmaaddr_t pa;
+		hnddma_seg_map_t *map = NULL;
+		uint size, j, nsegs;
+
+		PHYSADDRLOSET(pa,
+			      (BUS_SWAP32(R_SM(&di->txd64[i].addrlow)) -
+			       di->dataoffsetlow));
+		PHYSADDRHISET(pa,
+			      (BUS_SWAP32(R_SM(&di->txd64[i].addrhigh)) -
+			       di->dataoffsethigh));
+
+		if (DMASGLIST_ENAB) {
+			map = &di->txp_dmah[i];
+			size = map->origsize;
+			nsegs = map->nsegs;
+		} else {
+			size =
+			    (BUS_SWAP32(R_SM(&di->txd64[i].ctrl2)) &
+			     D64_CTRL2_BC_MASK);
+			nsegs = 1;
+		}
+
+		for (j = nsegs; j > 0; j--) {
+			W_SM(&di->txd64[i].addrlow, 0xdeadbeef);
+			W_SM(&di->txd64[i].addrhigh, 0xdeadbeef);
+
+			txp = di->txp[i];
+			di->txp[i] = NULL;
+			if (j > 1)
+				i = NEXTTXD(i);
+		}
+
+		pci_unmap_single(di->pbus, pa, size, PCI_DMA_TODEVICE);
+	}
+
+	di->txin = i;
+
+	/* tx flow control */
+	di->hnddma.txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1;
+
+	return txp;
+
+ bogus:
+	DMA_NONE(("dma_getnexttxp: bogus curr: start %d end %d txout %d force %d\n", start, end, di->txout, forceall));
+	return NULL;
+}
+
+static void *dma64_getnextrxp(dma_info_t *di, bool forceall)
+{
+	uint i, curr;
+	void *rxp;
+	dmaaddr_t pa;
+
+	i = di->rxin;
+
+	/* return if no packets posted */
+	if (i == di->rxout)
+		return NULL;
+
+	curr =
+	    B2I(((R_REG(&di->d64rxregs->status0) & D64_RS0_CD_MASK) -
+		 di->rcvptrbase) & D64_RS0_CD_MASK, dma64dd_t);
+
+	/* ignore curr if forceall */
+	if (!forceall && (i == curr))
+		return NULL;
+
+	/* get the packet pointer that corresponds to the rx descriptor */
+	rxp = di->rxp[i];
+	di->rxp[i] = NULL;
+
+	PHYSADDRLOSET(pa,
+		      (BUS_SWAP32(R_SM(&di->rxd64[i].addrlow)) -
+		       di->dataoffsetlow));
+	PHYSADDRHISET(pa,
+		      (BUS_SWAP32(R_SM(&di->rxd64[i].addrhigh)) -
+		       di->dataoffsethigh));
+
+	/* clear this packet from the descriptor ring */
+	pci_unmap_single(di->pbus, pa, di->rxbufsize, PCI_DMA_FROMDEVICE);
+
+	W_SM(&di->rxd64[i].addrlow, 0xdeadbeef);
+	W_SM(&di->rxd64[i].addrhigh, 0xdeadbeef);
+
+	di->rxin = NEXTRXD(i);
+
+	return rxp;
+}
+
+static bool _dma64_addrext(dma64regs_t *dma64regs)
+{
+	u32 w;
+	OR_REG(&dma64regs->control, D64_XC_AE);
+	w = R_REG(&dma64regs->control);
+	AND_REG(&dma64regs->control, ~D64_XC_AE);
+	return (w & D64_XC_AE) == D64_XC_AE;
+}
+
+/*
+ * Rotate all active tx dma ring entries "forward" by (ActiveDescriptor - txin).
+ */
+static void dma64_txrotate(dma_info_t *di)
+{
+	u16 ad;
+	uint nactive;
+	uint rot;
+	u16 old, new;
+	u32 w;
+	u16 first, last;
+
+	nactive = _dma_txactive(di);
+	ad = (u16) (B2I
+		       ((((R_REG(&di->d64txregs->status1) &
+			   D64_XS1_AD_MASK)
+			  - di->xmtptrbase) & D64_XS1_AD_MASK), dma64dd_t));
+	rot = TXD(ad - di->txin);
+
+	/* full-ring case is a lot harder - don't worry about this */
+	if (rot >= (di->ntxd - nactive)) {
+		DMA_ERROR(("%s: dma_txrotate: ring full - punt\n", di->name));
+		return;
+	}
+
+	first = di->txin;
+	last = PREVTXD(di->txout);
+
+	/* move entries starting at last and moving backwards to first */
+	for (old = last; old != PREVTXD(first); old = PREVTXD(old)) {
+		new = TXD(old + rot);
+
+		/*
+		 * Move the tx dma descriptor.
+		 * EOT is set only in the last entry in the ring.
+		 */
+		w = BUS_SWAP32(R_SM(&di->txd64[old].ctrl1)) & ~D64_CTRL1_EOT;
+		if (new == (di->ntxd - 1))
+			w |= D64_CTRL1_EOT;
+		W_SM(&di->txd64[new].ctrl1, BUS_SWAP32(w));
+
+		w = BUS_SWAP32(R_SM(&di->txd64[old].ctrl2));
+		W_SM(&di->txd64[new].ctrl2, BUS_SWAP32(w));
+
+		W_SM(&di->txd64[new].addrlow, R_SM(&di->txd64[old].addrlow));
+		W_SM(&di->txd64[new].addrhigh, R_SM(&di->txd64[old].addrhigh));
+
+		/* zap the old tx dma descriptor address field */
+		W_SM(&di->txd64[old].addrlow, BUS_SWAP32(0xdeadbeef));
+		W_SM(&di->txd64[old].addrhigh, BUS_SWAP32(0xdeadbeef));
+
+		/* move the corresponding txp[] entry */
+		di->txp[new] = di->txp[old];
+
+		/* Move the map */
+		if (DMASGLIST_ENAB) {
+			memcpy(&di->txp_dmah[new], &di->txp_dmah[old],
+			       sizeof(hnddma_seg_map_t));
+			memset(&di->txp_dmah[old], 0, sizeof(hnddma_seg_map_t));
+		}
+
+		di->txp[old] = NULL;
+	}
+
+	/* update txin and txout */
+	di->txin = ad;
+	di->txout = TXD(di->txout + rot);
+	di->hnddma.txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1;
+
+	/* kick the chip */
+	W_REG(&di->d64txregs->ptr,
+	      di->xmtptrbase + I2B(di->txout, dma64dd_t));
+}
+
+uint dma_addrwidth(si_t *sih, void *dmaregs)
+{
+	/* Perform 64-bit checks only if we want to advertise 64-bit (> 32bit) capability) */
+	/* DMA engine is 64-bit capable */
+	if ((ai_core_sflags(sih, 0, 0) & SISF_DMA64) == SISF_DMA64) {
+		/* backplane are 64-bit capable */
+		if (ai_backplane64(sih))
+			/* If bus is System Backplane or PCIE then we can access 64-bits */
+			if ((sih->bustype == SI_BUS) ||
+			    ((sih->bustype == PCI_BUS) &&
+			     (sih->buscoretype == PCIE_CORE_ID)))
+				return DMADDRWIDTH_64;
+	}
+	/* DMA hardware not supported by this driver*/
+	return DMADDRWIDTH_64;
+}
+
+/*
+ * Mac80211 initiated actions sometimes require packets in the DMA queue to be
+ * modified. The modified portion of the packet is not under control of the DMA
+ * engine. This function calls a caller-supplied function for each packet in
+ * the caller specified dma chain.
+ */
+void dma_walk_packets(struct hnddma_pub *dmah, void (*callback_fnc)
+		      (void *pkt, void *arg_a), void *arg_a)
+{
+	dma_info_t *di = (dma_info_t *) dmah;
+	uint i =   di->txin;
+	uint end = di->txout;
+	struct sk_buff *skb;
+	struct ieee80211_tx_info *tx_info;
+
+	while (i != end) {
+		skb = (struct sk_buff *)di->txp[i];
+		if (skb != NULL) {
+			tx_info = (struct ieee80211_tx_info *)skb->cb;
+			(callback_fnc)(tx_info, arg_a);
+		}
+		i = NEXTTXD(i);
+	}
+}
diff -druN linux-2.6.39-libre/drivers/staging/brcm80211/brcmsmac/Makefile linux-3.0-rc7-libre/drivers/staging/brcm80211/brcmsmac/Makefile
--- linux-2.6.39-libre/drivers/staging/brcm80211/brcmsmac/Makefile	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/brcm80211/brcmsmac/Makefile	2011-07-11 19:51:52.000000000 -0400
@@ -25,7 +25,6 @@
 	-DBCMNVRAMR				\
 	-Idrivers/staging/brcm80211/brcmsmac \
 	-Idrivers/staging/brcm80211/brcmsmac/phy \
-	-Idrivers/staging/brcm80211/util \
 	-Idrivers/staging/brcm80211/include
 
 BRCMSMAC_OFILES := \
@@ -38,26 +37,23 @@
 	wlc_channel.o \
 	wlc_main.o \
 	wlc_phy_shim.o \
+	wlc_pmu.o \
 	wlc_rate.o \
 	wlc_stf.o \
+	aiutils.o \
 	phy/wlc_phy_cmn.o \
 	phy/wlc_phy_lcn.o \
 	phy/wlc_phy_n.o \
 	phy/wlc_phytbl_lcn.o \
 	phy/wlc_phytbl_n.o \
-	../util/aiutils.o \
-	../util/siutils.o \
-	../util/bcmutils.o \
-	../util/bcmwifi.o \
-	../util/bcmotp.o \
-	../util/bcmsrom.o \
-	../util/hnddma.o \
-	../util/hndpmu.o \
-	../util/nicpci.o \
-	../util/qmath.o \
-	../util/nvram/nvram_ro.o
+	phy/wlc_phy_qmath.o \
+	bcmotp.o \
+	bcmsrom.o \
+	hnddma.o \
+	nicpci.o \
+	nvram.o
 
 MODULEPFX := brcmsmac
 
-obj-m	+= $(MODULEPFX).o
+obj-$(CONFIG_BRCMSMAC)	+= $(MODULEPFX).o
 $(MODULEPFX)-objs	= $(BRCMSMAC_OFILES)
diff -druN linux-2.6.39-libre/drivers/staging/brcm80211/brcmsmac/nicpci.c linux-3.0-rc7-libre/drivers/staging/brcm80211/brcmsmac/nicpci.c
--- linux-2.6.39-libre/drivers/staging/brcm80211/brcmsmac/nicpci.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/staging/brcm80211/brcmsmac/nicpci.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,836 @@
+/*
+ * Copyright (c) 2010 Broadcom Corporation
+ *
+ * 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/delay.h>
+#include <linux/string.h>
+#include <linux/pci.h>
+#include <bcmdefs.h>
+#include <bcmutils.h>
+#include <bcmnvram.h>
+#include <aiutils.h>
+#include <hndsoc.h>
+#include <bcmdevs.h>
+#include <sbchipc.h>
+#include <pci_core.h>
+#include <pcie_core.h>
+#include <nicpci.h>
+#include <pcicfg.h>
+
+typedef struct {
+	union {
+		sbpcieregs_t *pcieregs;
+		struct sbpciregs *pciregs;
+	} regs;			/* Memory mapped register to the core */
+
+	si_t *sih;		/* System interconnect handle */
+	struct pci_dev *dev;
+	u8 pciecap_lcreg_offset;	/* PCIE capability LCreg offset in the config space */
+	bool pcie_pr42767;
+	u8 pcie_polarity;
+	u8 pcie_war_aspm_ovr;	/* Override ASPM/Clkreq settings */
+
+	u8 pmecap_offset;	/* PM Capability offset in the config space */
+	bool pmecap;		/* Capable of generating PME */
+} pcicore_info_t;
+
+/* debug/trace */
+#define	PCI_ERROR(args)
+#define PCIE_PUB(sih) \
+	(((sih)->bustype == PCI_BUS) && ((sih)->buscoretype == PCIE_CORE_ID))
+
+/* routines to access mdio slave device registers */
+static bool pcie_mdiosetblock(pcicore_info_t *pi, uint blk);
+static int pcie_mdioop(pcicore_info_t *pi, uint physmedia, uint regaddr,
+		       bool write, uint *val);
+static int pcie_mdiowrite(pcicore_info_t *pi, uint physmedia, uint readdr,
+			  uint val);
+static int pcie_mdioread(pcicore_info_t *pi, uint physmedia, uint readdr,
+			 uint *ret_val);
+
+static void pcie_extendL1timer(pcicore_info_t *pi, bool extend);
+static void pcie_clkreq_upd(pcicore_info_t *pi, uint state);
+
+static void pcie_war_aspm_clkreq(pcicore_info_t *pi);
+static void pcie_war_serdes(pcicore_info_t *pi);
+static void pcie_war_noplldown(pcicore_info_t *pi);
+static void pcie_war_polarity(pcicore_info_t *pi);
+static void pcie_war_pci_setup(pcicore_info_t *pi);
+
+static bool pcicore_pmecap(pcicore_info_t *pi);
+
+#define PCIE_ASPM(sih)	((PCIE_PUB(sih)) && (((sih)->buscorerev >= 3) && ((sih)->buscorerev <= 5)))
+
+
+/* delay needed between the mdio control/ mdiodata register data access */
+#define PR28829_DELAY() udelay(10)
+
+/* Initialize the PCI core. It's caller's responsibility to make sure that this is done
+ * only once
+ */
+void *pcicore_init(si_t *sih, void *pdev, void *regs)
+{
+	pcicore_info_t *pi;
+
+	/* alloc pcicore_info_t */
+	pi = kzalloc(sizeof(pcicore_info_t), GFP_ATOMIC);
+	if (pi == NULL) {
+		PCI_ERROR(("pci_attach: malloc failed!\n"));
+		return NULL;
+	}
+
+	pi->sih = sih;
+	pi->dev = pdev;
+
+	if (sih->buscoretype == PCIE_CORE_ID) {
+		u8 cap_ptr;
+		pi->regs.pcieregs = (sbpcieregs_t *) regs;
+		cap_ptr = pcicore_find_pci_capability(pi->dev, PCI_CAP_ID_EXP,
+						      NULL, NULL);
+		pi->pciecap_lcreg_offset = cap_ptr + PCIE_CAP_LINKCTRL_OFFSET;
+	} else
+		pi->regs.pciregs = (struct sbpciregs *) regs;
+
+	return pi;
+}
+
+void pcicore_deinit(void *pch)
+{
+	pcicore_info_t *pi = (pcicore_info_t *) pch;
+
+	if (pi == NULL)
+		return;
+	kfree(pi);
+}
+
+/* return cap_offset if requested capability exists in the PCI config space */
+/* Note that it's caller's responsibility to make sure it's a pci bus */
+u8
+pcicore_find_pci_capability(void *dev, u8 req_cap_id,
+			    unsigned char *buf, u32 *buflen)
+{
+	u8 cap_id;
+	u8 cap_ptr = 0;
+	u32 bufsize;
+	u8 byte_val;
+
+	/* check for Header type 0 */
+	pci_read_config_byte(dev, PCI_HEADER_TYPE, &byte_val);
+	if ((byte_val & 0x7f) != PCI_HEADER_TYPE_NORMAL)
+		goto end;
+
+	/* check if the capability pointer field exists */
+	pci_read_config_byte(dev, PCI_STATUS, &byte_val);
+	if (!(byte_val & PCI_STATUS_CAP_LIST))
+		goto end;
+
+	pci_read_config_byte(dev, PCI_CAPABILITY_LIST, &cap_ptr);
+	/* check if the capability pointer is 0x00 */
+	if (cap_ptr == 0x00)
+		goto end;
+
+	/* loop thr'u the capability list and see if the pcie capabilty exists */
+
+	pci_read_config_byte(dev, cap_ptr, &cap_id);
+
+	while (cap_id != req_cap_id) {
+		pci_read_config_byte(dev, cap_ptr + 1, &cap_ptr);
+		if (cap_ptr == 0x00)
+			break;
+		pci_read_config_byte(dev, cap_ptr, &cap_id);
+	}
+	if (cap_id != req_cap_id) {
+		goto end;
+	}
+	/* found the caller requested capability */
+	if ((buf != NULL) && (buflen != NULL)) {
+		u8 cap_data;
+
+		bufsize = *buflen;
+		if (!bufsize)
+			goto end;
+		*buflen = 0;
+		/* copy the cpability data excluding cap ID and next ptr */
+		cap_data = cap_ptr + 2;
+		if ((bufsize + cap_data) > PCI_SZPCR)
+			bufsize = PCI_SZPCR - cap_data;
+		*buflen = bufsize;
+		while (bufsize--) {
+			pci_read_config_byte(dev, cap_data, buf);
+			cap_data++;
+			buf++;
+		}
+	}
+ end:
+	return cap_ptr;
+}
+
+/* ***** Register Access API */
+uint
+pcie_readreg(sbpcieregs_t *pcieregs, uint addrtype,
+	     uint offset)
+{
+	uint retval = 0xFFFFFFFF;
+
+	switch (addrtype) {
+	case PCIE_CONFIGREGS:
+		W_REG((&pcieregs->configaddr), offset);
+		(void)R_REG((&pcieregs->configaddr));
+		retval = R_REG(&(pcieregs->configdata));
+		break;
+	case PCIE_PCIEREGS:
+		W_REG(&(pcieregs->pcieindaddr), offset);
+		(void)R_REG((&pcieregs->pcieindaddr));
+		retval = R_REG(&(pcieregs->pcieinddata));
+		break;
+	default:
+		break;
+	}
+
+	return retval;
+}
+
+uint
+pcie_writereg(sbpcieregs_t *pcieregs, uint addrtype,
+	      uint offset, uint val)
+{
+	switch (addrtype) {
+	case PCIE_CONFIGREGS:
+		W_REG((&pcieregs->configaddr), offset);
+		W_REG((&pcieregs->configdata), val);
+		break;
+	case PCIE_PCIEREGS:
+		W_REG((&pcieregs->pcieindaddr), offset);
+		W_REG((&pcieregs->pcieinddata), val);
+		break;
+	default:
+		break;
+	}
+	return 0;
+}
+
+static bool pcie_mdiosetblock(pcicore_info_t *pi, uint blk)
+{
+	sbpcieregs_t *pcieregs = pi->regs.pcieregs;
+	uint mdiodata, i = 0;
+	uint pcie_serdes_spinwait = 200;
+
+	mdiodata =
+	    MDIODATA_START | MDIODATA_WRITE | (MDIODATA_DEV_ADDR <<
+					       MDIODATA_DEVADDR_SHF) |
+	    (MDIODATA_BLK_ADDR << MDIODATA_REGADDR_SHF) | MDIODATA_TA | (blk <<
+									 4);
+	W_REG(&pcieregs->mdiodata, mdiodata);
+
+	PR28829_DELAY();
+	/* retry till the transaction is complete */
+	while (i < pcie_serdes_spinwait) {
+		if (R_REG(&(pcieregs->mdiocontrol)) &
+		    MDIOCTL_ACCESS_DONE) {
+			break;
+		}
+		udelay(1000);
+		i++;
+	}
+
+	if (i >= pcie_serdes_spinwait) {
+		PCI_ERROR(("pcie_mdiosetblock: timed out\n"));
+		return false;
+	}
+
+	return true;
+}
+
+static int
+pcie_mdioop(pcicore_info_t *pi, uint physmedia, uint regaddr, bool write,
+	    uint *val)
+{
+	sbpcieregs_t *pcieregs = pi->regs.pcieregs;
+	uint mdiodata;
+	uint i = 0;
+	uint pcie_serdes_spinwait = 10;
+
+	/* enable mdio access to SERDES */
+	W_REG((&pcieregs->mdiocontrol),
+	      MDIOCTL_PREAM_EN | MDIOCTL_DIVISOR_VAL);
+
+	if (pi->sih->buscorerev >= 10) {
+		/* new serdes is slower in rw, using two layers of reg address mapping */
+		if (!pcie_mdiosetblock(pi, physmedia))
+			return 1;
+		mdiodata = (MDIODATA_DEV_ADDR << MDIODATA_DEVADDR_SHF) |
+		    (regaddr << MDIODATA_REGADDR_SHF);
+		pcie_serdes_spinwait *= 20;
+	} else {
+		mdiodata = (physmedia << MDIODATA_DEVADDR_SHF_OLD) |
+		    (regaddr << MDIODATA_REGADDR_SHF_OLD);
+	}
+
+	if (!write)
+		mdiodata |= (MDIODATA_START | MDIODATA_READ | MDIODATA_TA);
+	else
+		mdiodata |=
+		    (MDIODATA_START | MDIODATA_WRITE | MDIODATA_TA | *val);
+
+	W_REG(&pcieregs->mdiodata, mdiodata);
+
+	PR28829_DELAY();
+
+	/* retry till the transaction is complete */
+	while (i < pcie_serdes_spinwait) {
+		if (R_REG(&(pcieregs->mdiocontrol)) &
+		    MDIOCTL_ACCESS_DONE) {
+			if (!write) {
+				PR28829_DELAY();
+				*val =
+				    (R_REG(&(pcieregs->mdiodata)) &
+				     MDIODATA_MASK);
+			}
+			/* Disable mdio access to SERDES */
+			W_REG((&pcieregs->mdiocontrol), 0);
+			return 0;
+		}
+		udelay(1000);
+		i++;
+	}
+
+	PCI_ERROR(("pcie_mdioop: timed out op: %d\n", write));
+	/* Disable mdio access to SERDES */
+	W_REG((&pcieregs->mdiocontrol), 0);
+	return 1;
+}
+
+/* use the mdio interface to read from mdio slaves */
+static int
+pcie_mdioread(pcicore_info_t *pi, uint physmedia, uint regaddr, uint *regval)
+{
+	return pcie_mdioop(pi, physmedia, regaddr, false, regval);
+}
+
+/* use the mdio interface to write to mdio slaves */
+static int
+pcie_mdiowrite(pcicore_info_t *pi, uint physmedia, uint regaddr, uint val)
+{
+	return pcie_mdioop(pi, physmedia, regaddr, true, &val);
+}
+
+/* ***** Support functions ***** */
+u8 pcie_clkreq(void *pch, u32 mask, u32 val)
+{
+	pcicore_info_t *pi = (pcicore_info_t *) pch;
+	u32 reg_val;
+	u8 offset;
+
+	offset = pi->pciecap_lcreg_offset;
+	if (!offset)
+		return 0;
+
+	pci_read_config_dword(pi->dev, offset, &reg_val);
+	/* set operation */
+	if (mask) {
+		if (val)
+			reg_val |= PCIE_CLKREQ_ENAB;
+		else
+			reg_val &= ~PCIE_CLKREQ_ENAB;
+		pci_write_config_dword(pi->dev, offset, reg_val);
+		pci_read_config_dword(pi->dev, offset, &reg_val);
+	}
+	if (reg_val & PCIE_CLKREQ_ENAB)
+		return 1;
+	else
+		return 0;
+}
+
+static void pcie_extendL1timer(pcicore_info_t *pi, bool extend)
+{
+	u32 w;
+	si_t *sih = pi->sih;
+	sbpcieregs_t *pcieregs = pi->regs.pcieregs;
+
+	if (!PCIE_PUB(sih) || sih->buscorerev < 7)
+		return;
+
+	w = pcie_readreg(pcieregs, PCIE_PCIEREGS, PCIE_DLLP_PMTHRESHREG);
+	if (extend)
+		w |= PCIE_ASPMTIMER_EXTEND;
+	else
+		w &= ~PCIE_ASPMTIMER_EXTEND;
+	pcie_writereg(pcieregs, PCIE_PCIEREGS, PCIE_DLLP_PMTHRESHREG, w);
+	w = pcie_readreg(pcieregs, PCIE_PCIEREGS, PCIE_DLLP_PMTHRESHREG);
+}
+
+/* centralized clkreq control policy */
+static void pcie_clkreq_upd(pcicore_info_t *pi, uint state)
+{
+	si_t *sih = pi->sih;
+
+	switch (state) {
+	case SI_DOATTACH:
+		if (PCIE_ASPM(sih))
+			pcie_clkreq((void *)pi, 1, 0);
+		break;
+	case SI_PCIDOWN:
+		if (sih->buscorerev == 6) {	/* turn on serdes PLL down */
+			ai_corereg(sih, SI_CC_IDX,
+				   offsetof(chipcregs_t, chipcontrol_addr), ~0,
+				   0);
+			ai_corereg(sih, SI_CC_IDX,
+				   offsetof(chipcregs_t, chipcontrol_data),
+				   ~0x40, 0);
+		} else if (pi->pcie_pr42767) {
+			pcie_clkreq((void *)pi, 1, 1);
+		}
+		break;
+	case SI_PCIUP:
+		if (sih->buscorerev == 6) {	/* turn off serdes PLL down */
+			ai_corereg(sih, SI_CC_IDX,
+				   offsetof(chipcregs_t, chipcontrol_addr), ~0,
+				   0);
+			ai_corereg(sih, SI_CC_IDX,
+				   offsetof(chipcregs_t, chipcontrol_data),
+				   ~0x40, 0x40);
+		} else if (PCIE_ASPM(sih)) {	/* disable clkreq */
+			pcie_clkreq((void *)pi, 1, 0);
+		}
+		break;
+	default:
+		break;
+	}
+}
+
+/* ***** PCI core WARs ***** */
+/* Done only once at attach time */
+static void pcie_war_polarity(pcicore_info_t *pi)
+{
+	u32 w;
+
+	if (pi->pcie_polarity != 0)
+		return;
+
+	w = pcie_readreg(pi->regs.pcieregs, PCIE_PCIEREGS,
+			 PCIE_PLP_STATUSREG);
+
+	/* Detect the current polarity at attach and force that polarity and
+	 * disable changing the polarity
+	 */
+	if ((w & PCIE_PLP_POLARITYINV_STAT) == 0)
+		pi->pcie_polarity = (SERDES_RX_CTRL_FORCE);
+	else
+		pi->pcie_polarity =
+		    (SERDES_RX_CTRL_FORCE | SERDES_RX_CTRL_POLARITY);
+}
+
+/* enable ASPM and CLKREQ if srom doesn't have it */
+/* Needs to happen when update to shadow SROM is needed
+ *   : Coming out of 'standby'/'hibernate'
+ *   : If pcie_war_aspm_ovr state changed
+ */
+static void pcie_war_aspm_clkreq(pcicore_info_t *pi)
+{
+	sbpcieregs_t *pcieregs = pi->regs.pcieregs;
+	si_t *sih = pi->sih;
+	u16 val16, *reg16;
+	u32 w;
+
+	if (!PCIE_ASPM(sih))
+		return;
+
+	/* bypass this on QT or VSIM */
+	if (!ISSIM_ENAB(sih)) {
+
+		reg16 = &pcieregs->sprom[SRSH_ASPM_OFFSET];
+		val16 = R_REG(reg16);
+
+		val16 &= ~SRSH_ASPM_ENB;
+		if (pi->pcie_war_aspm_ovr == PCIE_ASPM_ENAB)
+			val16 |= SRSH_ASPM_ENB;
+		else if (pi->pcie_war_aspm_ovr == PCIE_ASPM_L1_ENAB)
+			val16 |= SRSH_ASPM_L1_ENB;
+		else if (pi->pcie_war_aspm_ovr == PCIE_ASPM_L0s_ENAB)
+			val16 |= SRSH_ASPM_L0s_ENB;
+
+		W_REG(reg16, val16);
+
+		pci_read_config_dword(pi->dev, pi->pciecap_lcreg_offset,
+					&w);
+		w &= ~PCIE_ASPM_ENAB;
+		w |= pi->pcie_war_aspm_ovr;
+		pci_write_config_dword(pi->dev,
+					pi->pciecap_lcreg_offset, w);
+	}
+
+	reg16 = &pcieregs->sprom[SRSH_CLKREQ_OFFSET_REV5];
+	val16 = R_REG(reg16);
+
+	if (pi->pcie_war_aspm_ovr != PCIE_ASPM_DISAB) {
+		val16 |= SRSH_CLKREQ_ENB;
+		pi->pcie_pr42767 = true;
+	} else
+		val16 &= ~SRSH_CLKREQ_ENB;
+
+	W_REG(reg16, val16);
+}
+
+/* Apply the polarity determined at the start */
+/* Needs to happen when coming out of 'standby'/'hibernate' */
+static void pcie_war_serdes(pcicore_info_t *pi)
+{
+	u32 w = 0;
+
+	if (pi->pcie_polarity != 0)
+		pcie_mdiowrite(pi, MDIODATA_DEV_RX, SERDES_RX_CTRL,
+			       pi->pcie_polarity);
+
+	pcie_mdioread(pi, MDIODATA_DEV_PLL, SERDES_PLL_CTRL, &w);
+	if (w & PLL_CTRL_FREQDET_EN) {
+		w &= ~PLL_CTRL_FREQDET_EN;
+		pcie_mdiowrite(pi, MDIODATA_DEV_PLL, SERDES_PLL_CTRL, w);
+	}
+}
+
+/* Fix MISC config to allow coming out of L2/L3-Ready state w/o PRST */
+/* Needs to happen when coming out of 'standby'/'hibernate' */
+static void pcie_misc_config_fixup(pcicore_info_t *pi)
+{
+	sbpcieregs_t *pcieregs = pi->regs.pcieregs;
+	u16 val16, *reg16;
+
+	reg16 = &pcieregs->sprom[SRSH_PCIE_MISC_CONFIG];
+	val16 = R_REG(reg16);
+
+	if ((val16 & SRSH_L23READY_EXIT_NOPERST) == 0) {
+		val16 |= SRSH_L23READY_EXIT_NOPERST;
+		W_REG(reg16, val16);
+	}
+}
+
+/* quick hack for testing */
+/* Needs to happen when coming out of 'standby'/'hibernate' */
+static void pcie_war_noplldown(pcicore_info_t *pi)
+{
+	sbpcieregs_t *pcieregs = pi->regs.pcieregs;
+	u16 *reg16;
+
+	/* turn off serdes PLL down */
+	ai_corereg(pi->sih, SI_CC_IDX, offsetof(chipcregs_t, chipcontrol),
+		   CHIPCTRL_4321_PLL_DOWN, CHIPCTRL_4321_PLL_DOWN);
+
+	/*  clear srom shadow backdoor */
+	reg16 = &pcieregs->sprom[SRSH_BD_OFFSET];
+	W_REG(reg16, 0);
+}
+
+/* Needs to happen when coming out of 'standby'/'hibernate' */
+static void pcie_war_pci_setup(pcicore_info_t *pi)
+{
+	si_t *sih = pi->sih;
+	sbpcieregs_t *pcieregs = pi->regs.pcieregs;
+	u32 w;
+
+	if ((sih->buscorerev == 0) || (sih->buscorerev == 1)) {
+		w = pcie_readreg(pcieregs, PCIE_PCIEREGS,
+				 PCIE_TLP_WORKAROUNDSREG);
+		w |= 0x8;
+		pcie_writereg(pcieregs, PCIE_PCIEREGS,
+			      PCIE_TLP_WORKAROUNDSREG, w);
+	}
+
+	if (sih->buscorerev == 1) {
+		w = pcie_readreg(pcieregs, PCIE_PCIEREGS, PCIE_DLLP_LCREG);
+		w |= (0x40);
+		pcie_writereg(pcieregs, PCIE_PCIEREGS, PCIE_DLLP_LCREG, w);
+	}
+
+	if (sih->buscorerev == 0) {
+		pcie_mdiowrite(pi, MDIODATA_DEV_RX, SERDES_RX_TIMER1, 0x8128);
+		pcie_mdiowrite(pi, MDIODATA_DEV_RX, SERDES_RX_CDR, 0x0100);
+		pcie_mdiowrite(pi, MDIODATA_DEV_RX, SERDES_RX_CDRBW, 0x1466);
+	} else if (PCIE_ASPM(sih)) {
+		/* Change the L1 threshold for better performance */
+		w = pcie_readreg(pcieregs, PCIE_PCIEREGS,
+				 PCIE_DLLP_PMTHRESHREG);
+		w &= ~(PCIE_L1THRESHOLDTIME_MASK);
+		w |= (PCIE_L1THRESHOLD_WARVAL << PCIE_L1THRESHOLDTIME_SHIFT);
+		pcie_writereg(pcieregs, PCIE_PCIEREGS,
+			      PCIE_DLLP_PMTHRESHREG, w);
+
+		pcie_war_serdes(pi);
+
+		pcie_war_aspm_clkreq(pi);
+	} else if (pi->sih->buscorerev == 7)
+		pcie_war_noplldown(pi);
+
+	/* Note that the fix is actually in the SROM, that's why this is open-ended */
+	if (pi->sih->buscorerev >= 6)
+		pcie_misc_config_fixup(pi);
+}
+
+void pcie_war_ovr_aspm_update(void *pch, u8 aspm)
+{
+	pcicore_info_t *pi = (pcicore_info_t *) pch;
+
+	if (!PCIE_ASPM(pi->sih))
+		return;
+
+	/* Validate */
+	if (aspm > PCIE_ASPM_ENAB)
+		return;
+
+	pi->pcie_war_aspm_ovr = aspm;
+
+	/* Update the current state */
+	pcie_war_aspm_clkreq(pi);
+}
+
+/* ***** Functions called during driver state changes ***** */
+void pcicore_attach(void *pch, char *pvars, int state)
+{
+	pcicore_info_t *pi = (pcicore_info_t *) pch;
+	si_t *sih = pi->sih;
+
+	/* Determine if this board needs override */
+	if (PCIE_ASPM(sih)) {
+		if ((u32) getintvar(pvars, "boardflags2") & BFL2_PCIEWAR_OVR) {
+			pi->pcie_war_aspm_ovr = PCIE_ASPM_DISAB;
+		} else {
+			pi->pcie_war_aspm_ovr = PCIE_ASPM_ENAB;
+		}
+	}
+
+	/* These need to happen in this order only */
+	pcie_war_polarity(pi);
+
+	pcie_war_serdes(pi);
+
+	pcie_war_aspm_clkreq(pi);
+
+	pcie_clkreq_upd(pi, state);
+
+}
+
+void pcicore_hwup(void *pch)
+{
+	pcicore_info_t *pi = (pcicore_info_t *) pch;
+
+	if (!pi || !PCIE_PUB(pi->sih))
+		return;
+
+	pcie_war_pci_setup(pi);
+}
+
+void pcicore_up(void *pch, int state)
+{
+	pcicore_info_t *pi = (pcicore_info_t *) pch;
+
+	if (!pi || !PCIE_PUB(pi->sih))
+		return;
+
+	/* Restore L1 timer for better performance */
+	pcie_extendL1timer(pi, true);
+
+	pcie_clkreq_upd(pi, state);
+}
+
+/* When the device is going to enter D3 state (or the system is going to enter S3/S4 states */
+void pcicore_sleep(void *pch)
+{
+	pcicore_info_t *pi = (pcicore_info_t *) pch;
+	u32 w;
+
+	if (!pi || !PCIE_ASPM(pi->sih))
+		return;
+
+	pci_read_config_dword(pi->dev, pi->pciecap_lcreg_offset, &w);
+	w &= ~PCIE_CAP_LCREG_ASPML1;
+	pci_write_config_dword(pi->dev, pi->pciecap_lcreg_offset, w);
+
+	pi->pcie_pr42767 = false;
+}
+
+void pcicore_down(void *pch, int state)
+{
+	pcicore_info_t *pi = (pcicore_info_t *) pch;
+
+	if (!pi || !PCIE_PUB(pi->sih))
+		return;
+
+	pcie_clkreq_upd(pi, state);
+
+	/* Reduce L1 timer for better power savings */
+	pcie_extendL1timer(pi, false);
+}
+
+/* ***** Wake-on-wireless-LAN (WOWL) support functions ***** */
+/* Just uses PCI config accesses to find out, when needed before sb_attach is done */
+bool pcicore_pmecap_fast(void *pch)
+{
+	pcicore_info_t *pi = (pcicore_info_t *) pch;
+	u8 cap_ptr;
+	u32 pmecap;
+
+	cap_ptr = pcicore_find_pci_capability(pi->dev, PCI_CAP_ID_PM, NULL,
+					      NULL);
+
+	if (!cap_ptr)
+		return false;
+
+	pci_read_config_dword(pi->dev, cap_ptr, &pmecap);
+
+	return (pmecap & (PCI_PM_CAP_PME_MASK << 16)) != 0;
+}
+
+/* return true if PM capability exists in the pci config space
+ * Uses and caches the information using core handle
+ */
+static bool pcicore_pmecap(pcicore_info_t *pi)
+{
+	u8 cap_ptr;
+	u32 pmecap;
+
+	if (!pi->pmecap_offset) {
+		cap_ptr = pcicore_find_pci_capability(pi->dev,
+						      PCI_CAP_ID_PM,
+						      NULL, NULL);
+		if (!cap_ptr)
+			return false;
+
+		pi->pmecap_offset = cap_ptr;
+
+		pci_read_config_dword(pi->dev, pi->pmecap_offset,
+					&pmecap);
+
+		/* At least one state can generate PME */
+		pi->pmecap = (pmecap & (PCI_PM_CAP_PME_MASK << 16)) != 0;
+	}
+
+	return pi->pmecap;
+}
+
+/* Enable PME generation */
+void pcicore_pmeen(void *pch)
+{
+	pcicore_info_t *pi = (pcicore_info_t *) pch;
+	u32 w;
+
+	/* if not pmecapable return */
+	if (!pcicore_pmecap(pi))
+		return;
+
+	pci_read_config_dword(pi->dev, pi->pmecap_offset + PCI_PM_CTRL,
+				&w);
+	w |= (PCI_PM_CTRL_PME_ENABLE);
+	pci_write_config_dword(pi->dev,
+				pi->pmecap_offset + PCI_PM_CTRL, w);
+}
+
+/*
+ * Return true if PME status set
+ */
+bool pcicore_pmestat(void *pch)
+{
+	pcicore_info_t *pi = (pcicore_info_t *) pch;
+	u32 w;
+
+	if (!pcicore_pmecap(pi))
+		return false;
+
+	pci_read_config_dword(pi->dev, pi->pmecap_offset + PCI_PM_CTRL,
+				&w);
+
+	return (w & PCI_PM_CTRL_PME_STATUS) == PCI_PM_CTRL_PME_STATUS;
+}
+
+/* Disable PME generation, clear the PME status bit if set
+ */
+void pcicore_pmeclr(void *pch)
+{
+	pcicore_info_t *pi = (pcicore_info_t *) pch;
+	u32 w;
+
+	if (!pcicore_pmecap(pi))
+		return;
+
+	pci_read_config_dword(pi->dev, pi->pmecap_offset + PCI_PM_CTRL,
+				&w);
+
+	PCI_ERROR(("pcicore_pci_pmeclr PMECSR : 0x%x\n", w));
+
+	/* PMESTAT is cleared by writing 1 to it */
+	w &= ~(PCI_PM_CTRL_PME_ENABLE);
+
+	pci_write_config_dword(pi->dev,
+				pi->pmecap_offset + PCI_PM_CTRL, w);
+}
+
+u32 pcie_lcreg(void *pch, u32 mask, u32 val)
+{
+	pcicore_info_t *pi = (pcicore_info_t *) pch;
+	u8 offset;
+	u32 tmpval;
+
+	offset = pi->pciecap_lcreg_offset;
+	if (!offset)
+		return 0;
+
+	/* set operation */
+	if (mask)
+		pci_write_config_dword(pi->dev, offset, val);
+
+	pci_read_config_dword(pi->dev, offset, &tmpval);
+	return tmpval;
+}
+
+u32
+pcicore_pciereg(void *pch, u32 offset, u32 mask, u32 val, uint type)
+{
+	u32 reg_val = 0;
+	pcicore_info_t *pi = (pcicore_info_t *) pch;
+	sbpcieregs_t *pcieregs = pi->regs.pcieregs;
+
+	if (mask) {
+		PCI_ERROR(("PCIEREG: 0x%x writeval  0x%x\n", offset, val));
+		pcie_writereg(pcieregs, type, offset, val);
+	}
+
+	/* Should not read register 0x154 */
+	if (pi->sih->buscorerev <= 5 && offset == PCIE_DLLP_PCIE11
+	    && type == PCIE_PCIEREGS)
+		return reg_val;
+
+	reg_val = pcie_readreg(pcieregs, type, offset);
+	PCI_ERROR(("PCIEREG: 0x%x readval is 0x%x\n", offset, reg_val));
+
+	return reg_val;
+}
+
+u32
+pcicore_pcieserdesreg(void *pch, u32 mdioslave, u32 offset, u32 mask,
+		      u32 val)
+{
+	u32 reg_val = 0;
+	pcicore_info_t *pi = (pcicore_info_t *) pch;
+
+	if (mask) {
+		PCI_ERROR(("PCIEMDIOREG: 0x%x writeval  0x%x\n", offset, val));
+		pcie_mdiowrite(pi, mdioslave, offset, val);
+	}
+
+	if (pcie_mdioread(pi, mdioslave, offset, &reg_val))
+		reg_val = 0xFFFFFFFF;
+	PCI_ERROR(("PCIEMDIOREG: dev 0x%x offset 0x%x read 0x%x\n", mdioslave,
+		   offset, reg_val));
+
+	return reg_val;
+}
diff -druN linux-2.6.39-libre/drivers/staging/brcm80211/brcmsmac/nvram.c linux-3.0-rc7-libre/drivers/staging/brcm80211/brcmsmac/nvram.c
--- linux-2.6.39-libre/drivers/staging/brcm80211/brcmsmac/nvram.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/staging/brcm80211/brcmsmac/nvram.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,215 @@
+/*
+ * Copyright (c) 2010 Broadcom Corporation
+ *
+ * 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 <linux/string.h>
+#include <bcmdefs.h>
+#include <bcmutils.h>
+#include <bcmnvram.h>
+#include <sbchipc.h>
+#include <bcmdevs.h>
+#include <hndsoc.h>
+
+#define NVR_MSG(x)
+
+typedef struct _vars {
+	struct _vars *next;
+	int bufsz;		/* allocated size */
+	int size;		/* actual vars size */
+	char *vars;
+} vars_t;
+
+#define	VARS_T_OH	sizeof(vars_t)
+
+static vars_t *vars;
+
+#define NVRAM_FILE	1
+
+static char *findvar(char *vars, char *lim, const char *name);
+
+int nvram_init(void)
+{
+
+	/* Make sure we read nvram in flash just once before freeing the memory */
+	if (vars != NULL) {
+		NVR_MSG(("nvram_init: called again without calling nvram_exit()\n"));
+		return 0;
+	}
+	return 0;
+}
+
+int nvram_append(char *varlst, uint varsz)
+{
+	uint bufsz = VARS_T_OH;
+	vars_t *new;
+
+	new = kmalloc(bufsz, GFP_ATOMIC);
+	if (new == NULL)
+		return -ENOMEM;
+
+	new->vars = varlst;
+	new->bufsz = bufsz;
+	new->size = varsz;
+	new->next = vars;
+	vars = new;
+
+	return 0;
+}
+
+void nvram_exit(void)
+{
+	vars_t *this, *next;
+
+	this = vars;
+	if (this)
+		kfree(this->vars);
+
+	while (this) {
+		next = this->next;
+		kfree(this);
+		this = next;
+	}
+	vars = NULL;
+}
+
+static char *findvar(char *vars, char *lim, const char *name)
+{
+	char *s;
+	int len;
+
+	len = strlen(name);
+
+	for (s = vars; (s < lim) && *s;) {
+		if ((memcmp(s, name, len) == 0) && (s[len] == '='))
+			return &s[len + 1];
+
+		while (*s++)
+			;
+	}
+
+	return NULL;
+}
+
+/*
+ * Search the name=value vars for a specific one and return its value.
+ * Returns NULL if not found.
+ */
+char *getvar(char *vars, const char *name)
+{
+	char *s;
+	int len;
+
+	if (!name)
+		return NULL;
+
+	len = strlen(name);
+	if (len == 0)
+		return NULL;
+
+	/* first look in vars[] */
+	for (s = vars; s && *s;) {
+		if ((memcmp(s, name, len) == 0) && (s[len] == '='))
+			return &s[len + 1];
+
+		while (*s++)
+			;
+	}
+	/* then query nvram */
+	return nvram_get(name);
+}
+
+/*
+ * Search the vars for a specific one and return its value as
+ * an integer. Returns 0 if not found.
+ */
+int getintvar(char *vars, const char *name)
+{
+	char *val;
+
+	val = getvar(vars, name);
+	if (val == NULL)
+		return 0;
+
+	return simple_strtoul(val, NULL, 0);
+}
+
+char *nvram_get(const char *name)
+{
+	char *v = NULL;
+	vars_t *cur;
+
+	for (cur = vars; cur; cur = cur->next) {
+		v = findvar(cur->vars, cur->vars + cur->size, name);
+		if (v)
+			break;
+	}
+
+	return v;
+}
+
+int nvram_set(const char *name, const char *value)
+{
+	return 0;
+}
+
+int nvram_unset(const char *name)
+{
+	return 0;
+}
+
+int nvram_reset(void)
+{
+	return 0;
+}
+
+int nvram_commit(void)
+{
+	return 0;
+}
+
+int nvram_getall(char *buf, int count)
+{
+	int len, resid = count;
+	vars_t *this;
+
+	this = vars;
+	while (this) {
+		char *from, *lim, *to;
+		int acc;
+
+		from = this->vars;
+		lim = (char *)(this->vars + this->size);
+		to = buf;
+		acc = 0;
+		while ((from < lim) && (*from)) {
+			len = strlen(from) + 1;
+			if (resid < (acc + len))
+				return -EOVERFLOW;
+			memcpy(to, from, len);
+			acc += len;
+			from += len;
+			to += len;
+		}
+
+		resid -= acc;
+		buf += acc;
+		this = this->next;
+	}
+	if (resid < 1)
+		return -EOVERFLOW;
+	*buf = '\0';
+	return 0;
+}
diff -druN linux-2.6.39-libre/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_cmn.c linux-3.0-rc7-libre/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_cmn.c
--- linux-2.6.39-libre/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_cmn.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_cmn.c	2011-07-11 19:51:52.000000000 -0400
@@ -18,10 +18,12 @@
 
 #include <linux/kernel.h>
 #include <linux/string.h>
-#include <bcmdefs.h>
+#include <linux/bitops.h>
 #include <linux/delay.h>
 #include <linux/module.h>
 #include <linux/pci.h>
+
+#include <bcmdefs.h>
 #include <bcmnvram.h>
 #include <sbchipc.h>
 #include <bcmdevs.h>
@@ -155,8 +157,6 @@
 	char *s;
 	int len;
 
-	ASSERT(pi->vars != (char *)&pi->vars);
-
 	if (!name)
 		return NULL;
 
@@ -241,7 +241,7 @@
 		break;
 
 	default:
-		ASSERT(VALID_PHYTYPE(pi->pubpi.phy_type));
+		break;
 	}
 
 	if ((D11REV_GE(pi->sh->corerev, 24)) ||
@@ -391,16 +391,6 @@
 	W_REG(&pi->regs->phychannel, val);
 }
 
-#if defined(BCMDBG)
-static bool wlc_phy_war41476(phy_info_t *pi)
-{
-	u32 mc = R_REG(&pi->regs->maccontrol);
-
-	return ((mc & MCTL_EN_MAC) == 0)
-	    || ((mc & MCTL_PHYLOCK) == MCTL_PHYLOCK);
-}
-#endif
-
 u16 read_phy_reg(phy_info_t *pi, u16 addr)
 {
 	d11regs_t *regs;
@@ -412,10 +402,6 @@
 	(void)R_REG(&regs->phyregaddr);
 #endif
 
-	ASSERT(!
-	       (D11REV_IS(pi->sh->corerev, 11)
-		|| D11REV_IS(pi->sh->corerev, 12)) || wlc_phy_war41476(pi));
-
 	pi->phy_wreg = 0;
 	return R_REG(&regs->phyregdata);
 }
@@ -455,10 +441,6 @@
 	(void)R_REG(&regs->phyregaddr);
 #endif
 
-	ASSERT(!
-	       (D11REV_IS(pi->sh->corerev, 11)
-		|| D11REV_IS(pi->sh->corerev, 12)) || wlc_phy_war41476(pi));
-
 	W_REG(&regs->phyregdata, (R_REG(&regs->phyregdata) & val));
 	pi->phy_wreg = 0;
 }
@@ -474,10 +456,6 @@
 	(void)R_REG(&regs->phyregaddr);
 #endif
 
-	ASSERT(!
-	       (D11REV_IS(pi->sh->corerev, 11)
-		|| D11REV_IS(pi->sh->corerev, 12)) || wlc_phy_war41476(pi));
-
 	W_REG(&regs->phyregdata, (R_REG(&regs->phyregdata) | val));
 	pi->phy_wreg = 0;
 }
@@ -493,10 +471,6 @@
 	(void)R_REG(&regs->phyregaddr);
 #endif
 
-	ASSERT(!
-	       (D11REV_IS(pi->sh->corerev, 11)
-		|| D11REV_IS(pi->sh->corerev, 12)) || wlc_phy_war41476(pi));
-
 	W_REG(&regs->phyregdata,
 	      ((R_REG(&regs->phyregdata) & ~mask) | (val & mask)));
 	pi->phy_wreg = 0;
@@ -579,14 +553,12 @@
 void wlc_phy_shared_detach(shared_phy_t *phy_sh)
 {
 	if (phy_sh) {
-		if (phy_sh->phy_head) {
-			ASSERT(!phy_sh->phy_head);
-		}
 		kfree(phy_sh);
 	}
 }
 
-wlc_phy_t *wlc_phy_attach(shared_phy_t *sh, void *regs, int bandtype, char *vars)
+wlc_phy_t *wlc_phy_attach(shared_phy_t *sh, void *regs, int bandtype,
+			  char *vars, struct wiphy *wiphy)
 {
 	phy_info_t *pi;
 	u32 sflags = 0;
@@ -596,7 +568,7 @@
 	if (D11REV_IS(sh->corerev, 4))
 		sflags = SISF_2G_PHY | SISF_5G_PHY;
 	else
-		sflags = si_core_sflags(sh->sih, 0, 0);
+		sflags = ai_core_sflags(sh->sih, 0, 0);
 
 	if (BAND_5G(bandtype)) {
 		if ((sflags & (SISF_5G_PHY | SISF_DB_PHY)) == 0) {
@@ -616,6 +588,7 @@
 	if (pi == NULL) {
 		return NULL;
 	}
+	pi->wiphy = wiphy;
 	pi->regs = (d11regs_t *) regs;
 	pi->sh = sh;
 	pi->phy_init_por = true;
@@ -781,8 +754,6 @@
 			pi->sh->phy_head = pi->next;
 		else if (pi->sh->phy_head->next == pi)
 			pi->sh->phy_head->next = NULL;
-		else
-			ASSERT(0);
 
 		if (pi->pi_fptr.detach)
 			(pi->pi_fptr.detach) (pi);
@@ -894,7 +865,6 @@
 			phy_bw_clkbits = SICF_BW40;
 			break;
 		default:
-			ASSERT(0);
 			break;
 		}
 	}
@@ -962,24 +932,20 @@
 	pi->radio_chanspec = chanspec;
 
 	mc = R_REG(&pi->regs->maccontrol);
-	if ((mc & MCTL_EN_MAC) != 0) {
-		ASSERT((const char *)
-		       "wlc_phy_init: Called with the MAC running!" == NULL);
-	}
-
-	ASSERT(pi != NULL);
+	if (WARN(mc & MCTL_EN_MAC, "HW error MAC running on init"))
+		return;
 
 	if (!(pi->measure_hold & PHY_HOLD_FOR_SCAN)) {
 		pi->measure_hold |= PHY_HOLD_FOR_NOT_ASSOC;
 	}
 
-	if (D11REV_GE(pi->sh->corerev, 5))
-		ASSERT(si_core_sflags(pi->sh->sih, 0, 0) & SISF_FCLKA);
+	if (WARN(!(ai_core_sflags(pi->sh->sih, 0, 0) & SISF_FCLKA),
+		 "HW error SISF_FCLKA\n"))
+		return;
 
 	phy_init = pi->pi_fptr.init;
 
 	if (phy_init == NULL) {
-		ASSERT(phy_init != NULL);
 		return;
 	}
 
@@ -1013,7 +979,9 @@
 	phy_info_t *pi = (phy_info_t *) pih;
 	initfn_t cal_init = NULL;
 
-	ASSERT((R_REG(&pi->regs->maccontrol) & MCTL_EN_MAC) == 0);
+	if (WARN((R_REG(&pi->regs->maccontrol) & MCTL_EN_MAC) != 0,
+		 "HW error: MAC enabled during phy cal\n"))
+		return;
 
 	if (!pi->initialized) {
 		cal_init = pi->pi_fptr.calinit;
@@ -1029,8 +997,6 @@
 	phy_info_t *pi = (phy_info_t *) pih;
 	int callbacks = 0;
 
-	ASSERT(pi->phytest_on == false);
-
 	if (pi->phycal_timer
 	    && !wlapi_del_timer(pi->sh->physhim, pi->phycal_timer))
 		callbacks++;
@@ -1070,8 +1036,6 @@
 
 void wlc_phy_table_data_write(phy_info_t *pi, uint width, u32 val)
 {
-	ASSERT((width == 8) || (width == 16) || (width == 32));
-
 	if ((pi->sh->chip == BCM43224_CHIP_ID ||
 	     pi->sh->chip == BCM43421_CHIP_ID) &&
 	    (pi->sh->chiprev == 1) &&
@@ -1105,8 +1069,6 @@
 	const u16 *ptbl_16b = (const u16 *)ptbl_info->tbl_ptr;
 	const u32 *ptbl_32b = (const u32 *)ptbl_info->tbl_ptr;
 
-	ASSERT((tbl_width == 8) || (tbl_width == 16) || (tbl_width == 32));
-
 	write_phy_reg(pi, tblAddr, (tbl_id << 10) | tbl_offset);
 
 	for (idx = 0; idx < ptbl_info->tbl_len; idx++) {
@@ -1148,8 +1110,6 @@
 	u16 *ptbl_16b = (u16 *)ptbl_info->tbl_ptr;
 	u32 *ptbl_32b = (u32 *)ptbl_info->tbl_ptr;
 
-	ASSERT((tbl_width == 8) || (tbl_width == 16) || (tbl_width == 32));
-
 	write_phy_reg(pi, tblAddr, (tbl_id << 10) | tbl_offset);
 
 	for (idx = 0; idx < ptbl_info->tbl_len; idx++) {
@@ -1243,8 +1203,6 @@
 	};
 	u32 *dummypkt;
 
-	ASSERT((R_REG(&pi->regs->maccontrol) & MCTL_EN_MAC) == 0);
-
 	dummypkt = (u32 *) (ofdm ? ofdmpkt : cckpkt);
 	wlapi_bmac_write_template_ram(pi->sh->physhim, 0, DUMMY_PKT_LEN,
 				      dummypkt);
@@ -1258,7 +1216,6 @@
 
 	W_REG(&regs->txe_phyctl, (ofdm ? 1 : 0) | PHY_TXC_ANT_0);
 	if (ISNPHY(pi) || ISLCNPHY(pi)) {
-		ASSERT(ofdm);
 		W_REG(&regs->txe_phyctl1, 0x1A02);
 	}
 
@@ -1317,7 +1274,6 @@
 void wlc_phy_hold_upd(wlc_phy_t *pih, mbool id, bool set)
 {
 	phy_info_t *pi = (phy_info_t *) pih;
-	ASSERT(id);
 
 	if (set) {
 		mboolset(pi->measure_hold, id);
@@ -1439,8 +1395,6 @@
 	u16 m_cur_channel;
 	chansetfn_t chanspec_set = NULL;
 
-	ASSERT(!wf_chspec_malformed(chanspec));
-
 	m_cur_channel = CHSPEC_CHANNEL(chanspec);
 	if (CHSPEC_IS5G(chanspec))
 		m_cur_channel |= D11_CURCHANNEL_5G;
@@ -1480,8 +1434,7 @@
 		range = wlc_phy_get_chan_freq_range_nphy(pi, channel);
 	} else if (ISLCNPHY(pi)) {
 		range = wlc_phy_chanspec_freq2bandrange_lpssn(freq);
-	} else
-		ASSERT(0);
+	}
 
 	return range;
 }
@@ -1511,8 +1464,6 @@
 	uint i;
 	uint channel;
 
-	ASSERT((band == WLC_BAND_2G) || (band == WLC_BAND_5G));
-
 	memset(channels, 0, sizeof(chanvec_t));
 
 	for (i = 0; i < ARRAY_SIZE(chan_info_all); i++) {
@@ -1535,8 +1486,6 @@
 	uint channel;
 	chanspec_t chspec;
 
-	ASSERT((band == WLC_BAND_2G) || (band == WLC_BAND_5G));
-
 	for (i = 0; i < ARRAY_SIZE(chan_info_all); i++) {
 		channel = chan_info_all[i].chan;
 
@@ -1572,8 +1521,6 @@
 			return chspec;
 	}
 
-	ASSERT(0);
-
 	return (chanspec_t) INVCHANSPEC;
 }
 
@@ -1581,7 +1528,6 @@
 {
 	phy_info_t *pi = (phy_info_t *) ppi;
 
-	ASSERT(qdbm != NULL);
 	*qdbm = pi->tx_user_target[0];
 	if (override != NULL)
 		*override = pi->txpwroverride;
@@ -1703,7 +1649,6 @@
 				break;
 			}
 		}
-		ASSERT(i < ARRAY_SIZE(chan_info_all));
 
 		if (pi->hwtxpwr) {
 			*max_pwr = pi->hwtxpwr[i];
@@ -2134,7 +2079,6 @@
 {
 	int j;
 	if (ISNPHY(pi)) {
-		ASSERT(0);
 		return;
 	}
 
@@ -2466,8 +2410,6 @@
 			mod_phy_reg(pi, 0x410, (0x1 << 1), 0x00 << 1);
 			mod_phy_reg(pi, 0x410, (0x1 << 0), (u16) val << 0);
 		}
-	} else {
-		ASSERT(0);
 	}
 
 	if (!suspend)
@@ -2483,7 +2425,6 @@
 	u8 i;
 
 	memset((u8 *) cmplx_pwr_dbm, 0, sizeof(cmplx_pwr_dbm));
-	ASSERT(pi->pubpi.phy_corenum <= PHY_CORE_MAX);
 	wlc_phy_compute_dB(cmplx_pwr, cmplx_pwr_dbm, pi->pubpi.phy_corenum);
 
 	for (i = 0; i < pi->pubpi.phy_corenum; i++) {
@@ -2529,7 +2470,6 @@
 		break;
 
 	default:
-		ASSERT(0);
 		break;
 	}
 
@@ -2678,7 +2618,6 @@
 	s8 noise_dbm = PHY_NOISE_FIXED_VAL_NPHY;
 	u8 idx, core;
 
-	ASSERT(pi->pubpi.phy_corenum <= PHY_CORE_MAX);
 	memset((u8 *) cmplx_pwr, 0, sizeof(cmplx_pwr));
 	memset((u8 *) noise_dbm_ant, 0, sizeof(noise_dbm_ant));
 
@@ -2760,8 +2699,6 @@
 		channel = jssi_aux & D11_CURCHANNEL_MAX;
 
 		noise_dbm = wlc_phy_noise_read_shmem(pi);
-	} else {
-		ASSERT(0);
 	}
 
 	wlc_phy_noise_cb(pi, channel, noise_dbm);
@@ -2811,25 +2748,20 @@
 
 void wlc_phy_compute_dB(u32 *cmplx_pwr, s8 *p_cmplx_pwr_dB, u8 core)
 {
-	u8 shift_ct, lsb, msb, secondmsb, i;
+	u8 msb, secondmsb, i;
 	u32 tmp;
 
 	for (i = 0; i < core; i++) {
+		secondmsb = 0;
 		tmp = cmplx_pwr[i];
-		shift_ct = msb = secondmsb = 0;
-		while (tmp != 0) {
-			tmp = tmp >> 1;
-			shift_ct++;
-			lsb = (u8) (tmp & 1);
-			if (lsb == 1)
-				msb = shift_ct;
-		}
-		secondmsb = (u8) ((cmplx_pwr[i] >> (msb - 1)) & 1);
+		msb = fls(tmp);
+		if (msb)
+			secondmsb = (u8) ((tmp >> (--msb - 1)) & 1);
 		p_cmplx_pwr_dB[i] = (s8) (3 * msb + 2 * secondmsb);
 	}
 }
 
-void BCMFASTPATH wlc_phy_rssi_compute(wlc_phy_t *pih, void *ctx)
+void wlc_phy_rssi_compute(wlc_phy_t *pih, void *ctx)
 {
 	wlc_d11rxhdr_t *wlc_rxhdr = (wlc_d11rxhdr_t *) ctx;
 	d11rxhdr_t *rxh = &wlc_rxhdr->rxhdr;
@@ -2871,10 +2803,7 @@
 			rssi -= 256;
 	} else if (radioid == BCM2055_ID || radioid == BCM2056_ID
 		   || radioid == BCM2057_ID) {
-		ASSERT(ISNPHY(pi));
 		rssi = wlc_phy_rssi_compute_nphy(pi, wlc_rxhdr);
-	} else {
-		ASSERT((const char *)"Unknown radio" == NULL);
 	}
 
  end:
@@ -2900,9 +2829,6 @@
 		wlc_lcnphy_deaf_mode(pi, true);
 	else if (ISNPHY(pi))
 		wlc_nphy_deaf_mode(pi, true);
-	else {
-		ASSERT(0);
-	}
 }
 
 void wlc_phy_watchdog(wlc_phy_t *pih)
@@ -3163,13 +3089,9 @@
 			} else if (pi->nphy_perical == PHY_PERICAL_SPHASE)
 				wlc_phy_cal_perical_nphy_run(pi,
 							     PHY_PERICAL_AUTO);
-			else {
-				ASSERT(0);
-			}
 		}
 		break;
 	default:
-		ASSERT(0);
 		break;
 	}
 }
@@ -3192,25 +3114,6 @@
 	return nbits;
 }
 
-u32 wlc_phy_sqrt_int(u32 value)
-{
-	u32 root = 0, shift = 0;
-
-	for (shift = 0; shift < 32; shift += 2) {
-		if (((0x40000000 >> shift) + root) <= value) {
-			value -= ((0x40000000 >> shift) + root);
-			root = (root >> 1) | (0x40000000 >> shift);
-		} else {
-			root = root >> 1;
-		}
-	}
-
-	if (root < value)
-		++root;
-
-	return root;
-}
-
 void wlc_phy_stf_chain_init(wlc_phy_t *pih, u8 txchain, u8 rxchain)
 {
 	phy_info_t *pi = (phy_info_t *) pih;
@@ -3311,12 +3214,12 @@
 				mod_phy_reg(pi, 0x44c, (0x1 << 2), (1) << 2);
 
 			}
-			si_corereg(pi->sh->sih, SI_CC_IDX,
+			ai_corereg(pi->sh->sih, SI_CC_IDX,
 				   offsetof(chipcregs_t, gpiocontrol), ~0x0,
 				   0x0);
-			si_corereg(pi->sh->sih, SI_CC_IDX,
+			ai_corereg(pi->sh->sih, SI_CC_IDX,
 				   offsetof(chipcregs_t, gpioout), 0x40, 0x40);
-			si_corereg(pi->sh->sih, SI_CC_IDX,
+			ai_corereg(pi->sh->sih, SI_CC_IDX,
 				   offsetof(chipcregs_t, gpioouten), 0x40,
 				   0x40);
 		} else {
@@ -3324,11 +3227,11 @@
 
 			mod_phy_reg(pi, 0x44d, (0x1 << 2), (0) << 2);
 
-			si_corereg(pi->sh->sih, SI_CC_IDX,
+			ai_corereg(pi->sh->sih, SI_CC_IDX,
 				   offsetof(chipcregs_t, gpioout), 0x40, 0x00);
-			si_corereg(pi->sh->sih, SI_CC_IDX,
+			ai_corereg(pi->sh->sih, SI_CC_IDX,
 				   offsetof(chipcregs_t, gpioouten), 0x40, 0x0);
-			si_corereg(pi->sh->sih, SI_CC_IDX,
+			ai_corereg(pi->sh->sih, SI_CC_IDX,
 				   offsetof(chipcregs_t, gpiocontrol), ~0x0,
 				   0x40);
 		}
@@ -3387,33 +3290,6 @@
 	*ofdmoffset = 0;
 }
 
-u32 wlc_phy_qdiv_roundup(u32 dividend, u32 divisor, u8 precision)
-{
-	u32 quotient, remainder, roundup, rbit;
-
-	ASSERT(divisor);
-
-	quotient = dividend / divisor;
-	remainder = dividend % divisor;
-	rbit = divisor & 1;
-	roundup = (divisor >> 1) + rbit;
-
-	while (precision--) {
-		quotient <<= 1;
-		if (remainder >= roundup) {
-			quotient++;
-			remainder = ((remainder - roundup) << 1) + rbit;
-		} else {
-			remainder <<= 1;
-		}
-	}
-
-	if (remainder >= roundup)
-		quotient++;
-
-	return quotient;
-}
-
 s8 wlc_phy_upd_rssi_offset(phy_info_t *pi, s8 rssi, chanspec_t chanspec)
 {
 
diff -druN linux-2.6.39-libre/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_hal.h linux-3.0-rc7-libre/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_hal.h
--- linux-2.6.39-libre/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_hal.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_hal.h	2011-07-11 19:51:52.000000000 -0400
@@ -18,9 +18,10 @@
 #define _wlc_phy_h_
 
 #include <wlioctl.h>
-#include <siutils.h>
+#include <aiutils.h>
 #include <d11.h>
 #include <wlc_phy_shim.h>
+#include <net/mac80211.h>	/* struct wiphy */
 
 #define	IDCODE_VER_MASK		0x0000000f
 #define	IDCODE_VER_SHIFT	0
@@ -149,7 +150,7 @@
 extern shared_phy_t *wlc_phy_shared_attach(shared_phy_params_t *shp);
 extern void wlc_phy_shared_detach(shared_phy_t *phy_sh);
 extern wlc_phy_t *wlc_phy_attach(shared_phy_t *sh, void *regs, int bandtype,
-				 char *vars);
+				 char *vars, struct wiphy *wiphy);
 extern void wlc_phy_detach(wlc_phy_t *ppi);
 
 extern bool wlc_phy_get_phyversion(wlc_phy_t *pih, u16 *phytype,
diff -druN linux-2.6.39-libre/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_int.h linux-3.0-rc7-libre/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_int.h
--- linux-2.6.39-libre/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_int.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_int.h	2011-07-11 19:51:52.000000000 -0400
@@ -936,6 +936,7 @@
 	u8 phycal_tempdelta;
 	u32 mcs20_po;
 	u32 mcs40_po;
+	struct wiphy *wiphy;
 };
 
 typedef s32 fixed;
@@ -1024,7 +1025,6 @@
 
 extern void wlc_phy_cordic(fixed theta, cs32 *val);
 extern u8 wlc_phy_nbits(s32 value);
-extern u32 wlc_phy_sqrt_int(u32 value);
 extern void wlc_phy_compute_dB(u32 *cmplx_pwr, s8 *p_dB, u8 core);
 
 extern uint wlc_phy_init_radio_regs_allbands(phy_info_t *pi,
@@ -1093,8 +1093,6 @@
 extern void wlc_2064_vco_cal(phy_info_t *pi);
 
 extern void wlc_phy_txpower_recalc_target(phy_info_t *pi);
-extern u32 wlc_phy_qdiv_roundup(u32 dividend, u32 divisor,
-				   u8 precision);
 
 #define LCNPHY_TBL_ID_PAPDCOMPDELTATBL	0x18
 #define LCNPHY_TX_POWER_TABLE_SIZE	128
diff -druN linux-2.6.39-libre/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_lcn.c linux-3.0-rc7-libre/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_lcn.c
--- linux-2.6.39-libre/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_lcn.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_lcn.c	2011-07-11 19:51:52.000000000 -0400
@@ -19,18 +19,19 @@
 #include <linux/bitops.h>
 #include <linux/delay.h>
 #include <wlc_cfg.h>
-#include <qmath.h>
 #include <linux/pci.h>
-#include <siutils.h>
-#include <hndpmu.h>
+#include <aiutils.h>
+#include <wlc_pmu.h>
+#include <bcmnvram.h>
 
 #include <bcmdevs.h>
 #include <sbhnddma.h>
 
-#include <wlc_phy_radio.h>
-#include <wlc_phy_int.h>
-#include <wlc_phy_lcn.h>
-#include <wlc_phytbl_lcn.h>
+#include "wlc_phy_radio.h"
+#include "wlc_phy_int.h"
+#include "wlc_phy_qmath.h"
+#include "wlc_phy_lcn.h"
+#include "wlc_phytbl_lcn.h"
 
 #define PLL_2064_NDIV		90
 #define PLL_2064_LOW_END_VCO 	3000
@@ -1081,8 +1082,6 @@
 {
 	u32 quotient, remainder, roundup, rbit;
 
-	ASSERT(divisor);
-
 	quotient = dividend / divisor;
 	remainder = dividend % divisor;
 	rbit = divisor & 1;
@@ -1780,11 +1779,6 @@
 	s8 index;
 	phy_info_lcnphy_t *pi_lcn = pi->u.pi_lcnphy;
 
-	ASSERT((LCNPHY_TX_PWR_CTRL_OFF == mode) ||
-	       (LCNPHY_TX_PWR_CTRL_SW == mode) ||
-	       (LCNPHY_TX_PWR_CTRL_HW == mode) ||
-	       (LCNPHY_TX_PWR_CTRL_TEMPBASED == mode));
-
 	mode = wlc_lcnphy_set_tx_pwr_ctrl_mode(pi, mode);
 	old_mode = wlc_lcnphy_set_tx_pwr_ctrl_mode(pi, old_mode);
 
@@ -1904,16 +1898,14 @@
 		break;
 
 	case LCNPHY_CAL_RECAL:
-		ASSERT(pi_lcn->lcnphy_cal_results.txiqlocal_bestcoeffs_valid);
-
 		start_coeffs = syst_coeffs;
-
 		cal_cmds = commands_recal;
 		n_cal_cmds = ARRAY_SIZE(commands_recal);
 		command_nums = command_nums_recal;
 		break;
+
 	default:
-		ASSERT(false);
+		break;
 	}
 
 	wlc_lcnphy_common_write_table(pi, LCNPHY_TBL_ID_IQLOCAL,
@@ -2460,8 +2452,6 @@
 	lcnphy_txgains_t gains;
 	phy_info_lcnphy_t *pi_lcn = pi->u.pi_lcnphy;
 
-	ASSERT(index <= LCNPHY_MAX_TX_POWER_INDEX);
-
 	pi_lcn->lcnphy_tx_power_idx_override = (s8) index;
 	pi_lcn->lcnphy_current_index = (u8) index;
 
@@ -2760,7 +2750,6 @@
 		do {
 			bw = phy_bw * 1000 * k;
 			num_samps = bw / ABS(f_kHz);
-			ASSERT(num_samps <= ARRAY_SIZE(data_buf));
 			k++;
 		} while ((num_samps * (u32) (ABS(f_kHz))) != bw);
 	} else
@@ -3255,7 +3244,7 @@
 	}
 	b /= temp;
 	b -= a * a;
-	b = (s32) wlc_phy_sqrt_int((u32) b);
+	b = (s32) int_sqrt((unsigned long) b);
 	b -= (1 << 10);
 	a0_new = (u16) (a & 0x3ff);
 	b0_new = (u16) (b & 0x3ff);
@@ -3298,8 +3287,6 @@
 		return false;
 	}
 	if (module == 2) {
-		ASSERT(iqcomp_sz);
-
 		while (iqcomp_sz--) {
 			if (iqcomp[iqcomp_sz].chan ==
 			    CHSPEC_CHANNEL(pi->radio_chanspec)) {
@@ -3313,7 +3300,6 @@
 				break;
 			}
 		}
-		ASSERT(result);
 		goto cal_done;
 	}
 
@@ -3584,9 +3570,6 @@
 		if (wlc_lcnphy_tempsense_based_pwr_ctrl_enabled(pi))
 			wlc_lcnphy_tx_power_adjustment((wlc_phy_t *) pi);
 		break;
-	default:
-		ASSERT(0);
-		break;
 	}
 }
 
@@ -5071,9 +5054,7 @@
 		pi->hwpwrctrl_capable = true;
 	}
 
-	pi->xtalfreq = si_alp_clock(pi->sh->sih);
-	ASSERT(0 == (pi->xtalfreq % 1000));
-
+	pi->xtalfreq = si_pmu_alp_clock(pi->sh->sih);
 	pi_lcn->lcnphy_papd_rxGnCtrl_init = 0;
 
 	pi->pi_fptr.init = wlc_phy_init_lcnphy;
@@ -5293,9 +5274,7 @@
 			}
 		}
 
-		if (filt_index == -1) {
-			ASSERT(false);
-		} else {
+		if (filt_index != -1) {
 			for (j = 0; j < LCNPHY_NUM_DIG_FILT_COEFFS; j++) {
 				write_phy_reg(pi, addr[j],
 					      LCNPHY_txdigfiltcoeffs_cck
@@ -5310,9 +5289,7 @@
 			}
 		}
 
-		if (filt_index == -1) {
-			ASSERT(false);
-		} else {
+		if (filt_index != -1) {
 			for (j = 0; j < LCNPHY_NUM_DIG_FILT_COEFFS; j++) {
 				write_phy_reg(pi, addr_ofdm[j],
 					      LCNPHY_txdigfiltcoeffs_ofdm
diff -druN linux-2.6.39-libre/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_n.c linux-3.0-rc7-libre/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_n.c
--- linux-2.6.39-libre/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_n.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_n.c	2011-07-11 19:51:52.000000000 -0400
@@ -20,9 +20,9 @@
 #include <wlc_cfg.h>
 #include <linux/delay.h>
 #include <linux/pci.h>
-#include <siutils.h>
+#include <aiutils.h>
 #include <sbchipc.h>
-#include <hndpmu.h>
+#include <wlc_pmu.h>
 
 #include <bcmdevs.h>
 #include <sbhnddma.h>
@@ -14218,8 +14218,6 @@
 {
 	u16 addr, val;
 
-	ASSERT(ISNPHY(pi));
-
 	val = 0x1e1f;
 	for (addr = (NPHY_TO_BPHY_OFF + BPHY_RSSI_LUT);
 	     addr <= (NPHY_TO_BPHY_OFF + BPHY_RSSI_LUT_END); addr++) {
@@ -14367,8 +14365,6 @@
 			break;
 
 		default:
-
-			ASSERT(0);
 			break;
 		}
 
@@ -14401,8 +14397,6 @@
 								 [idx]);
 					break;
 				default:
-
-					ASSERT(0);
 					break;
 				}
 			} else {
@@ -14550,7 +14544,7 @@
 	     (pi->sh->chippkg == BCM4718_PKG_ID))) {
 		if ((pi->sh->boardflags & BFL_EXTLNA) &&
 		    (CHSPEC_IS2G(pi->radio_chanspec))) {
-			si_corereg(pi->sh->sih, SI_CC_IDX,
+			ai_corereg(pi->sh->sih, SI_CC_IDX,
 				   offsetof(chipcregs_t, chipcontrol), 0x40,
 				   0x40);
 		}
@@ -14564,17 +14558,15 @@
 	if ((pi->nphy_gband_spurwar2_en) && CHSPEC_IS2G(pi->radio_chanspec) &&
 	    CHSPEC_IS40(pi->radio_chanspec)) {
 
-		regs = (d11regs_t *) si_switch_core(pi->sh->sih, D11_CORE_ID,
+		regs = (d11regs_t *) ai_switch_core(pi->sh->sih, D11_CORE_ID,
 						    &origidx, &intr_val);
-		ASSERT(regs != NULL);
-
 		d11_clk_ctl_st = R_REG(&regs->clk_ctl_st);
 		AND_REG(&regs->clk_ctl_st,
 			~(CCS_FORCEHT | CCS_HTAREQ));
 
 		W_REG(&regs->clk_ctl_st, d11_clk_ctl_st);
 
-		si_restore_core(pi->sh->sih, origidx, intr_val);
+		ai_restore_core(pi->sh->sih, origidx, intr_val);
 	}
 
 	pi->use_int_tx_iqlo_cal_nphy =
@@ -14783,10 +14775,7 @@
 						rfpwr_offset = (s16)
 						    nphy_papd_padgain_dlt_2g_2057rev7
 						    [pad_gn];
-					} else {
-						ASSERT(0);
 					}
-
 				} else {
 					if ((pi->pubpi.radiorev == 3) ||
 					    (pi->pubpi.radiorev == 4) ||
@@ -14800,8 +14789,6 @@
 						rfpwr_offset = (s16)
 						    nphy_papd_pgagain_dlt_5g_2057rev7
 						    [pga_gn];
-					} else {
-						ASSERT(0);
 					}
 				}
 				wlc_phy_table_write_nphy(pi,
@@ -14905,10 +14892,10 @@
 				}
 
 				if (wlc_phy_cal_txiqlo_nphy
-				    (pi, target_gain, true, false) == BCME_OK) {
+				    (pi, target_gain, true, false) == 0) {
 					if (wlc_phy_cal_rxiq_nphy
 					    (pi, target_gain, 2,
-					     false) == BCME_OK) {
+					     false) == 0) {
 						wlc_phy_savecal_nphy(pi);
 
 					}
@@ -14963,8 +14950,6 @@
 {
 	u16 val;
 
-	ASSERT(0 == (R_REG(&pi->regs->maccontrol) & MCTL_EN_MAC));
-
 	wlapi_bmac_phyclk_fgc(pi->sh->physhim, ON);
 
 	val = read_phy_reg(pi, 0x01);
@@ -16130,8 +16115,6 @@
 						 0x18, 16, bcm_adc_vmid);
 			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4,
 						 0x1c, 16, bcm_adc_gain);
-		} else {
-			ASSERT(0);
 		}
 
 		write_radio_reg(pi,
@@ -17418,8 +17401,10 @@
 	SPINWAIT(((read_radio_reg(pi, RADIO_2055_CAL_COUNTER_OUT2) &
 		   RADIO_2055_RCAL_DONE) != RADIO_2055_RCAL_DONE), 2000);
 
-	ASSERT((read_radio_reg(pi, RADIO_2055_CAL_COUNTER_OUT2) &
-		RADIO_2055_RCAL_DONE) == RADIO_2055_RCAL_DONE);
+	if (WARN((read_radio_reg(pi, RADIO_2055_CAL_COUNTER_OUT2) &
+		 RADIO_2055_RCAL_DONE) != RADIO_2055_RCAL_DONE,
+		 "HW error: radio calibration1\n"))
+		return;
 
 	and_radio_reg(pi, RADIO_2055_CAL_LPO_CNTRL,
 		      ~(RADIO_2055_CAL_LPO_ENABLE));
@@ -17510,7 +17495,6 @@
 			break;
 
 		default:
-			ASSERT(0);
 			break;
 		}
 	}
@@ -17571,7 +17555,6 @@
 
 				regs_2057_ptr = regs_2057_rev5v1;
 			} else {
-				ASSERT(0);
 				break;
 			}
 
@@ -17586,11 +17569,8 @@
 			break;
 
 		default:
-			ASSERT(0);
 			break;
 		}
-	} else {
-		ASSERT(0);
 	}
 
 	wlc_phy_init_radio_regs_allbands(pi, regs_2057_ptr);
@@ -17708,7 +17688,6 @@
 		}
 
 		if (i >= tbl_len) {
-			ASSERT(i < tbl_len);
 			goto fail;
 		}
 		if (pi->pubpi.radiorev == 5) {
@@ -17765,7 +17744,6 @@
 		}
 
 		if (i >= tbl_len) {
-			ASSERT(i < tbl_len);
 			goto fail;
 		}
 		*t1 = &chan_info_tbl_p_1[i];
@@ -17777,7 +17755,6 @@
 				break;
 
 		if (i >= ARRAY_SIZE(chan_info_nphy_2055)) {
-			ASSERT(i < ARRAY_SIZE(chan_info_nphy_2055));
 			goto fail;
 		}
 		*t3 = &chan_info_nphy_2055[i];
@@ -18276,7 +18253,9 @@
 			udelay(100);
 		}
 
-		ASSERT(i < MAX_205x_RCAL_WAITLOOPS);
+		if (WARN(i == MAX_205x_RCAL_WAITLOOPS,
+			 "HW error: radio calib2"))
+			return 0;
 
 		mod_radio_reg(pi, RADIO_2057_RCAL_CONFIG, 0x2, 0x0);
 
@@ -18325,7 +18304,9 @@
 			udelay(100);
 		}
 
-		ASSERT(i < MAX_205x_RCAL_WAITLOOPS);
+		if (WARN(i == MAX_205x_RCAL_WAITLOOPS,
+			 "HW error: radio calib3"))
+			return 0;
 
 		write_radio_reg(pi, RADIO_2056_SYN_RCAL_MASTER | RADIO_2056_SYN,
 				0x1);
@@ -18572,8 +18553,6 @@
 		udelay(500);
 	}
 
-	ASSERT(rccal_valid & 0x2);
-
 	write_radio_reg(pi, RADIO_2057_RCCAL_START_R1_Q1_P1, 0x15);
 
 	rccal_valid = 0;
@@ -18596,8 +18575,6 @@
 		udelay(500);
 	}
 
-	ASSERT(rccal_valid & 0x2);
-
 	write_radio_reg(pi, RADIO_2057_RCCAL_START_R1_Q1_P1, 0x15);
 
 	rccal_valid = 0;
@@ -18621,7 +18598,8 @@
 		udelay(500);
 	}
 
-	ASSERT(rccal_valid & 0x2);
+	if (WARN(!(rccal_valid & 0x2), "HW error: radio calib4"))
+		return 0;
 
 	write_radio_reg(pi, RADIO_2057_RCCAL_START_R1_Q1_P1, 0x15);
 
@@ -19585,8 +19563,6 @@
 						 1, 0x08, 16, &v2);
 			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_ANTSWCTRLLUT,
 						 1, 0x0C, 16, &v3);
-		} else {
-			ASSERT(0);
 		}
 
 		if (pi->srom_fem5g.antswctrllut == 0) {
@@ -19598,15 +19574,13 @@
 						 1, 0x18, 16, &v2);
 			wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_ANTSWCTRLLUT,
 						 1, 0x1C, 16, &v3);
-		} else {
-			ASSERT(0);
 		}
 	} else {
 
 		write_phy_reg(pi, 0xc8, 0x0);
 		write_phy_reg(pi, 0xc9, 0x0);
 
-		si_gpiocontrol(pi->sh->sih, mask, mask, GPIO_DRV_PRIORITY);
+		ai_gpiocontrol(pi->sh->sih, mask, mask, GPIO_DRV_PRIORITY);
 
 		mc = R_REG(&pi->regs->maccontrol);
 		mc &= ~MCTL_GPOUT_SEL_MASK;
@@ -19703,8 +19677,7 @@
 	or_phy_reg(pi, 0xa3, trigger_mask);
 	SPINWAIT((read_phy_reg(pi, 0xa4) & status_mask), 200000);
 	write_phy_reg(pi, 0xa1, orig_RfseqCoreActv);
-
-	ASSERT((read_phy_reg(pi, 0xa4) & status_mask) == 0);
+	WARN(read_phy_reg(pi, 0xa4) & status_mask, "HW error in rf");
 }
 
 static void
@@ -19718,8 +19691,6 @@
 		    3) ? NPHY_REV3_RFSEQ_CMD_END : NPHY_RFSEQ_CMD_END;
 	u8 end_dly = 1;
 
-	ASSERT(len <= 16);
-
 	if (pi->phyhang_avoid)
 		wlc_phy_stay_in_carriersearch_nphy(pi, true);
 
@@ -21467,7 +21438,7 @@
 	wlc_phy_resetcca_nphy(pi);
 }
 
-int BCMFASTPATH
+int
 wlc_phy_rssi_compute_nphy(phy_info_t *pi, wlc_d11rxhdr_t *wlc_rxh)
 {
 	d11rxhdr_t *rxh = &wlc_rxh->rxhdr;
@@ -21503,8 +21474,6 @@
 		rxpwr = (rxpwr0 < rxpwr1) ? rxpwr0 : rxpwr1;
 	else if (pi->sh->rssi_mode == RSSI_ANT_MERGE_AVG)
 		rxpwr = (rxpwr0 + rxpwr1) >> 1;
-	else
-		ASSERT(0);
 
 	return rxpwr;
 }
@@ -21588,8 +21557,9 @@
 
 					SPINWAIT(((read_phy_reg(pi, 0x78) & val)
 						  != 0), 10000);
-					ASSERT((read_phy_reg(pi, 0x78) & val) ==
-					       0);
+					if (WARN(read_phy_reg(pi, 0x78) & val,
+						"HW error: override failed"))
+						return;
 
 					mask = (0x1 << 0);
 					val = 0 << 0;
@@ -22233,8 +22203,6 @@
 
 static void wlc_phy_restore_rssical_nphy(phy_info_t *pi)
 {
-	ASSERT(NREV_GE(pi->pubpi.phy_rev, 3));
-
 	if (CHSPEC_IS2G(pi->radio_chanspec)) {
 		if (pi->nphy_rssical_chanspec_2G == 0)
 			return;
@@ -22399,13 +22367,13 @@
 	num_samps =
 		wlc_phy_gen_load_samples_nphy(pi, f_kHz, max_val, dac_test_mode);
 	if (num_samps == 0) {
-		return BCME_ERROR;
+		return -EBADE;
 	}
 
 	wlc_phy_runsamples_nphy(pi, num_samps, loops, wait, iqmode,
 				dac_test_mode, modify_bbmult);
 
-	return BCME_OK;
+	return 0;
 }
 
 static void
@@ -22775,8 +22743,6 @@
 			}
 		}
 
-		ASSERT(idx != -1);
-
 		params->txgm = tbl_iqcal_gainparams_nphy[band_idx][k][1];
 		params->pga = tbl_iqcal_gainparams_nphy[band_idx][k][2];
 		params->pad = tbl_iqcal_gainparams_nphy[band_idx][k][3];
@@ -23855,8 +23821,6 @@
 	if (PHY_MUTED(pi))
 		return;
 
-	ASSERT(pi->nphy_perical != PHY_PERICAL_DISABLE);
-
 	if (caltype == PHY_PERICAL_AUTO)
 		fullcal = (pi->radio_chanspec != pi->nphy_txiqlocal_chanspec);
 	else if (caltype == PHY_PERICAL_PARTIAL)
@@ -23913,7 +23877,7 @@
 
 			target_gain = pi->nphy_cal_target_gain;
 		}
-		if (BCME_OK ==
+		if (0 ==
 		    wlc_phy_cal_txiqlo_nphy(pi, target_gain, fullcal, mphase)) {
 			if (PHY_IPA(pi))
 				wlc_phy_a4(pi, true);
@@ -23925,7 +23889,7 @@
 			wlapi_suspend_mac_and_wait(pi->sh->physhim);
 			wlc_phyreg_enter((wlc_phy_t *) pi);
 
-			if (BCME_OK == wlc_phy_cal_rxiq_nphy(pi, target_gain,
+			if (0 == wlc_phy_cal_rxiq_nphy(pi, target_gain,
 							     (pi->
 							      first_cal_after_assoc
 							      || (pi->
@@ -23955,8 +23919,6 @@
 			wlc_phy_radio205x_vcocal_nphy(pi);
 		}
 	} else {
-		ASSERT(pi->nphy_perical >= PHY_PERICAL_MPHASE);
-
 		switch (pi->mphase_cal_phase_id) {
 		case MPHASE_CAL_STATE_INIT:
 			pi->nphy_perical_last = pi->sh->now;
@@ -23980,7 +23942,7 @@
 
 			if (wlc_phy_cal_txiqlo_nphy
 			    (pi, pi->nphy_cal_target_gain, fullcal,
-			     true) != BCME_OK) {
+			     true) != 0) {
 
 				wlc_phy_cal_perical_mphase_reset(pi);
 				break;
@@ -24012,7 +23974,7 @@
 						  (pi->first_cal_after_assoc ||
 						   (pi->cal_type_override ==
 						    PHY_PERICAL_FULL)) ? 2 : 0,
-						  false) == BCME_OK) {
+						  false) == 0) {
 				wlc_phy_savecal_nphy(pi);
 			}
 
@@ -24052,7 +24014,6 @@
 			break;
 
 		default:
-			ASSERT(0);
 			wlc_phy_cal_perical_mphase_reset(pi);
 			break;
 		}
@@ -24116,7 +24077,7 @@
 	void *tbl_ptr;
 	bool ladder_updated[2];
 	u8 mphase_cal_lastphase = 0;
-	int bcmerror = BCME_OK;
+	int bcmerror = 0;
 	bool phyhang_avoid_state = false;
 
 	u16 tbl_tx_iqlo_cal_loft_ladder_20[] = {
@@ -24242,13 +24203,13 @@
 
 	if (pi->mphase_cal_phase_id > MPHASE_CAL_STATE_TXPHASE0) {
 		wlc_phy_runsamples_nphy(pi, phy_bw * 8, 0xffff, 0, 1, 0, false);
-		bcmerror = BCME_OK;
+		bcmerror = 0;
 	} else {
 		bcmerror =
 		    wlc_phy_tx_tone_nphy(pi, tone_freq, max_val, 1, 0, false);
 	}
 
-	if (bcmerror == BCME_OK) {
+	if (bcmerror == 0) {
 
 		if (pi->mphase_cal_phase_id > MPHASE_CAL_STATE_TXPHASE0) {
 			tbl_ptr = pi->mphase_txcal_bestcoeffs;
@@ -24361,7 +24322,9 @@
 
 			SPINWAIT(((read_phy_reg(pi, 0xc0) & 0xc000) != 0),
 				 20000);
-			ASSERT((read_phy_reg(pi, 0xc0) & 0xc000) == 0);
+			if (WARN(read_phy_reg(pi, 0xc0) & 0xc000,
+				 "HW error: txiq calib"))
+				return -EIO;
 
 			wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_IQLOCAL,
 						tbl_len, 96, 16, tbl_buf);
@@ -24468,8 +24431,6 @@
 {
 	u16 tbl_buf[7];
 
-	ASSERT(NREV_LT(pi->pubpi.phy_rev, 2));
-
 	if ((pi->nphy_txiqlocal_chanspec == pi->radio_chanspec) &&
 	    (pi->nphy_txiqlocal_coeffsvalid)) {
 		wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_IQLOCAL,
@@ -24544,10 +24505,11 @@
 
 	SPINWAIT(((read_phy_reg(pi, 0x129) & NPHY_IqestCmd_iqstart) != 0),
 		 10000);
-	ASSERT((read_phy_reg(pi, 0x129) & NPHY_IqestCmd_iqstart) == 0);
+	if (WARN(read_phy_reg(pi, 0x129) & NPHY_IqestCmd_iqstart,
+		 "HW error: rxiq est"))
+		return;
 
 	if ((read_phy_reg(pi, 0x129) & NPHY_IqestCmd_iqstart) == 0) {
-		ASSERT(pi->pubpi.phy_corenum <= PHY_CORE_MAX);
 		for (core = 0; core < pi->pubpi.phy_corenum; core++) {
 			est[core].i_pwr =
 			    (read_phy_reg(pi, NPHY_IqestipwrAccHi(core)) << 16)
@@ -24572,7 +24534,7 @@
 	u32 ii = 0, qq = 0;
 	s16 iq_nbits, qq_nbits, brsh, arsh;
 	s32 a, b, temp;
-	int bcmerror = BCME_OK;
+	int bcmerror = 0;
 	uint cal_retry = 0;
 
 	if (core_mask == 0x0)
@@ -24602,7 +24564,7 @@
 		}
 
 		if ((ii + qq) < NPHY_MIN_RXIQ_PWR) {
-			bcmerror = BCME_ERROR;
+			bcmerror = -EBADE;
 			break;
 		}
 
@@ -24614,14 +24576,14 @@
 			a = (-(iq << (30 - iq_nbits)) + (ii >> (1 + arsh)));
 			temp = (s32) (ii >> arsh);
 			if (temp == 0) {
-				bcmerror = BCME_ERROR;
+				bcmerror = -EBADE;
 				break;
 			}
 		} else {
 			a = (-(iq << (30 - iq_nbits)) + (ii << (-1 - arsh)));
 			temp = (s32) (ii << -arsh);
 			if (temp == 0) {
-				bcmerror = BCME_ERROR;
+				bcmerror = -EBADE;
 				break;
 			}
 		}
@@ -24633,20 +24595,20 @@
 			b = (qq << (31 - qq_nbits));
 			temp = (s32) (ii >> brsh);
 			if (temp == 0) {
-				bcmerror = BCME_ERROR;
+				bcmerror = -EBADE;
 				break;
 			}
 		} else {
 			b = (qq << (31 - qq_nbits));
 			temp = (s32) (ii << -brsh);
 			if (temp == 0) {
-				bcmerror = BCME_ERROR;
+				bcmerror = -EBADE;
 				break;
 			}
 		}
 		b /= temp;
 		b -= a * a;
-		b = (s32) wlc_phy_sqrt_int((u32) b);
+		b = (s32) int_sqrt((unsigned long) b);
 		b -= (1 << 10);
 
 		if ((curr_core == PHY_CORE_0) && (core_mask & 0x1)) {
@@ -24671,7 +24633,7 @@
 		}
 	}
 
-	if (bcmerror != BCME_OK) {
+	if (bcmerror != 0) {
 		printk("%s: Failed, cnt = %d\n", __func__, cal_retry);
 
 		if (cal_retry < CAL_RETRY_CNT) {
@@ -25451,7 +25413,7 @@
 			break;
 
 		default:
-			ASSERT(0);
+			break;
 		}
 
 		if ((curr_gaintbl_index < 0) ||
@@ -25916,7 +25878,7 @@
 
 	wlc_phy_stay_in_carriersearch_nphy(pi, false);
 
-	return BCME_OK;
+	return 0;
 }
 
 static int
@@ -25941,7 +25903,7 @@
 	u16 cal_gain[2];
 	nphy_iqcal_params_t cal_params[2];
 	u8 phy_bw;
-	int bcmerror = BCME_OK;
+	int bcmerror = 0;
 	bool first_playtone = true;
 
 	wlc_phy_stay_in_carriersearch_nphy(pi, true);
@@ -26091,7 +26053,7 @@
 							0, 0, 0, true);
 			}
 
-			if (bcmerror == BCME_OK) {
+			if (bcmerror == 0) {
 				if (gain_pass < 3) {
 
 					wlc_phy_rx_iq_est_nphy(pi, est,
@@ -26114,7 +26076,7 @@
 				wlc_phy_stopplayback_nphy(pi);
 			}
 
-			if (bcmerror != BCME_OK)
+			if (bcmerror != 0)
 				break;
 		}
 
@@ -26130,7 +26092,7 @@
 			      0xa7, orig_AfectrlCore);
 		write_phy_reg(pi, 0xa2, orig_RfseqCoreActv);
 
-		if (bcmerror != BCME_OK)
+		if (bcmerror != 0)
 			break;
 	}
 
@@ -26270,8 +26232,6 @@
 
 				tx_pwrctrl_tbl =
 				    nphy_tpc_txgain_ipa_2g_2057rev7;
-			} else {
-				ASSERT(0);
 			}
 
 		} else if (NREV_IS(pi->pubpi.phy_rev, 6)) {
@@ -26303,8 +26263,6 @@
 
 				tx_pwrctrl_tbl =
 				    nphy_tpc_txgain_ipa_5g_2057rev7;
-			} else {
-				ASSERT(0);
 			}
 
 		} else {
@@ -26347,8 +26305,6 @@
 				   || (pi->pubpi.radiorev == 6)) {
 
 				mixgain = 0x00;
-			} else {
-				ASSERT(0);
 			}
 
 		} else {
@@ -26361,8 +26317,6 @@
 				   || (pi->pubpi.radiorev == 8)) {
 
 				mixgain = 0x0;
-			} else {
-				ASSERT(0);
 			}
 		}
 
@@ -26464,8 +26418,6 @@
 				WRITE_RADIO_REG3(pi, RADIO_2057, TX, core,
 						 TXRXCOUPLE_2G_ATTEN, 0xf0);
 
-			} else {
-				ASSERT(0);
 			}
 
 			WRITE_RADIO_REG3(pi, RADIO_2057, TX, off_core,
@@ -26724,8 +26676,6 @@
 	u32 *buf, *src, *dst, sz;
 
 	sz = end - start + 1;
-	ASSERT(end > start);
-	ASSERT(end < NPHY_PAPD_EPS_TBL_SIZE);
 
 	buf = kmalloc(2 * sizeof(u32) * NPHY_PAPD_EPS_TBL_SIZE, GFP_ATOMIC);
 	if (NULL == buf) {
@@ -26787,8 +26737,6 @@
 
 	phy_a7 = (core == PHY_CORE_0) ? 1 : 0;
 
-	ASSERT((cal_mode == CAL_FULL) || (cal_mode == CAL_GCTRL)
-	       || (cal_mode == CAL_SOFT));
 	phy_a6 = ((cal_mode == CAL_GCTRL)
 		  || (cal_mode == CAL_SOFT)) ? true : false;
 
@@ -27333,8 +27281,6 @@
 							    nphy_papd_cal_gain_index
 							    [phy_b5], phy_b5);
 
-				} else {
-					ASSERT(0);
 				}
 
 				phy_b1[phy_b5].gains.pad[phy_b5] =
@@ -27417,8 +27363,6 @@
 					    -(nphy_papd_padgain_dlt_2g_2057rev7
 					      [phy_b8]
 					      + 1) / 2;
-				} else {
-					ASSERT(0);
 				}
 			} else {
 				phy_b7 = phy_b1[phy_b5].gains.pga[phy_b5];
@@ -27435,8 +27379,6 @@
 					    -(nphy_papd_pgagain_dlt_5g_2057rev7
 					      [phy_b7]
 					      + 1) / 2;
-				} else {
-					ASSERT(0);
 				}
 
 				phy_b10 = -9;
@@ -27536,8 +27478,6 @@
 	u8 txpi[2], chan_freq_range;
 	s32 rfpwr_offset;
 
-	ASSERT(pi->nphy_txpwrctrl == PHY_TPC_HW_OFF);
-
 	if (pi->phyhang_avoid)
 		wlc_phy_stay_in_carriersearch_nphy(pi, true);
 
@@ -29179,7 +29119,6 @@
 		*max_pwr = pi->tx_srom_max_rate_5g_hi[txp_rate_idx];
 		break;
 	default:
-		ASSERT(0);
 		*max_pwr = pi->tx_srom_max_rate_2g[txp_rate_idx];
 		break;
 	}
@@ -29191,8 +29130,6 @@
 {
 	u16 clip_off[] = { 0xffff, 0xffff };
 
-	ASSERT(0 == (R_REG(&pi->regs->maccontrol) & MCTL_EN_MAC));
-
 	if (enable) {
 		if (pi->nphy_deaf_count == 0) {
 			pi->classifier_state =
@@ -29207,8 +29144,6 @@
 		wlc_phy_resetcca_nphy(pi);
 
 	} else {
-		ASSERT(pi->nphy_deaf_count > 0);
-
 		pi->nphy_deaf_count--;
 
 		if (pi->nphy_deaf_count == 0) {
diff -druN linux-2.6.39-libre/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_qmath.c linux-3.0-rc7-libre/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_qmath.c
--- linux-2.6.39-libre/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_qmath.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_qmath.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,296 @@
+/*
+ * Copyright (c) 2010 Broadcom Corporation
+ *
+ * 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/types.h>
+
+#include "wlc_phy_qmath.h"
+
+/*
+Description: This function make 16 bit unsigned multiplication. To fit the output into
+16 bits the 32 bit multiplication result is right shifted by 16 bits.
+*/
+u16 qm_mulu16(u16 op1, u16 op2)
+{
+	return (u16) (((u32) op1 * (u32) op2) >> 16);
+}
+
+/*
+Description: This function make 16 bit multiplication and return the result in 16 bits.
+To fit the multiplication result into 16 bits the multiplication result is right shifted by
+15 bits. Right shifting 15 bits instead of 16 bits is done to remove the extra sign bit formed
+due to the multiplication.
+When both the 16bit inputs are 0x8000 then the output is saturated to 0x7fffffff.
+*/
+s16 qm_muls16(s16 op1, s16 op2)
+{
+	s32 result;
+	if (op1 == (s16) 0x8000 && op2 == (s16) 0x8000) {
+		result = 0x7fffffff;
+	} else {
+		result = ((s32) (op1) * (s32) (op2));
+	}
+	return (s16) (result >> 15);
+}
+
+/*
+Description: This function add two 32 bit numbers and return the 32bit result.
+If the result overflow 32 bits, the output will be saturated to 32bits.
+*/
+s32 qm_add32(s32 op1, s32 op2)
+{
+	s32 result;
+	result = op1 + op2;
+	if (op1 < 0 && op2 < 0 && result > 0) {
+		result = 0x80000000;
+	} else if (op1 > 0 && op2 > 0 && result < 0) {
+		result = 0x7fffffff;
+	}
+	return result;
+}
+
+/*
+Description: This function add two 16 bit numbers and return the 16bit result.
+If the result overflow 16 bits, the output will be saturated to 16bits.
+*/
+s16 qm_add16(s16 op1, s16 op2)
+{
+	s16 result;
+	s32 temp = (s32) op1 + (s32) op2;
+	if (temp > (s32) 0x7fff) {
+		result = (s16) 0x7fff;
+	} else if (temp < (s32) 0xffff8000) {
+		result = (s16) 0xffff8000;
+	} else {
+		result = (s16) temp;
+	}
+	return result;
+}
+
+/*
+Description: This function make 16 bit subtraction and return the 16bit result.
+If the result overflow 16 bits, the output will be saturated to 16bits.
+*/
+s16 qm_sub16(s16 op1, s16 op2)
+{
+	s16 result;
+	s32 temp = (s32) op1 - (s32) op2;
+	if (temp > (s32) 0x7fff) {
+		result = (s16) 0x7fff;
+	} else if (temp < (s32) 0xffff8000) {
+		result = (s16) 0xffff8000;
+	} else {
+		result = (s16) temp;
+	}
+	return result;
+}
+
+/*
+Description: This function make a 32 bit saturated left shift when the specified shift
+is +ve. This function will make a 32 bit right shift when the specified shift is -ve.
+This function return the result after shifting operation.
+*/
+s32 qm_shl32(s32 op, int shift)
+{
+	int i;
+	s32 result;
+	result = op;
+	if (shift > 31)
+		shift = 31;
+	else if (shift < -31)
+		shift = -31;
+	if (shift >= 0) {
+		for (i = 0; i < shift; i++) {
+			result = qm_add32(result, result);
+		}
+	} else {
+		result = result >> (-shift);
+	}
+	return result;
+}
+
+/*
+Description: This function make a 16 bit saturated left shift when the specified shift
+is +ve. This function will make a 16 bit right shift when the specified shift is -ve.
+This function return the result after shifting operation.
+*/
+s16 qm_shl16(s16 op, int shift)
+{
+	int i;
+	s16 result;
+	result = op;
+	if (shift > 15)
+		shift = 15;
+	else if (shift < -15)
+		shift = -15;
+	if (shift > 0) {
+		for (i = 0; i < shift; i++) {
+			result = qm_add16(result, result);
+		}
+	} else {
+		result = result >> (-shift);
+	}
+	return result;
+}
+
+/*
+Description: This function make a 16 bit right shift when shift is +ve.
+This function make a 16 bit saturated left shift when shift is -ve. This function
+return the result of the shift operation.
+*/
+s16 qm_shr16(s16 op, int shift)
+{
+	return qm_shl16(op, -shift);
+}
+
+/*
+Description: This function return the number of redundant sign bits in a 32 bit number.
+Example: qm_norm32(0x00000080) = 23
+*/
+s16 qm_norm32(s32 op)
+{
+	u16 u16extraSignBits;
+	if (op == 0) {
+		return 31;
+	} else {
+		u16extraSignBits = 0;
+		while ((op >> 31) == (op >> 30)) {
+			u16extraSignBits++;
+			op = op << 1;
+		}
+	}
+	return u16extraSignBits;
+}
+
+/* This table is log2(1+(i/32)) where i=[0:1:31], in q.15 format */
+static const s16 log_table[] = {
+	0,
+	1455,
+	2866,
+	4236,
+	5568,
+	6863,
+	8124,
+	9352,
+	10549,
+	11716,
+	12855,
+	13968,
+	15055,
+	16117,
+	17156,
+	18173,
+	19168,
+	20143,
+	21098,
+	22034,
+	22952,
+	23852,
+	24736,
+	25604,
+	26455,
+	27292,
+	28114,
+	28922,
+	29717,
+	30498,
+	31267,
+	32024
+};
+
+#define LOG_TABLE_SIZE 32	/* log_table size */
+#define LOG2_LOG_TABLE_SIZE 5	/* log2(log_table size) */
+#define Q_LOG_TABLE 15		/* qformat of log_table */
+#define LOG10_2		19728	/* log10(2) in q.16 */
+
+/*
+Description:
+This routine takes the input number N and its q format qN and compute
+the log10(N). This routine first normalizes the input no N.	Then N is in mag*(2^x) format.
+mag is any number in the range 2^30-(2^31 - 1). Then log2(mag * 2^x) = log2(mag) + x is computed.
+From that log10(mag * 2^x) = log2(mag * 2^x) * log10(2) is computed.
+This routine looks the log2 value in the table considering LOG2_LOG_TABLE_SIZE+1 MSBs.
+As the MSB is always 1, only next LOG2_OF_LOG_TABLE_SIZE MSBs are used for table lookup.
+Next 16 MSBs are used for interpolation.
+Inputs:
+N - number to which log10 has to be found.
+qN - q format of N
+log10N - address where log10(N) will be written.
+qLog10N - address where log10N qformat will be written.
+Note/Problem:
+For accurate results input should be in normalized or near normalized form.
+*/
+void qm_log10(s32 N, s16 qN, s16 *log10N, s16 *qLog10N)
+{
+	s16 s16norm, s16tableIndex, s16errorApproximation;
+	u16 u16offset;
+	s32 s32log;
+
+	/* normalize the N. */
+	s16norm = qm_norm32(N);
+	N = N << s16norm;
+
+	/* The qformat of N after normalization.
+	 * -30 is added to treat the no as between 1.0 to 2.0
+	 * i.e. after adding the -30 to the qformat the decimal point will be
+	 * just rigtht of the MSB. (i.e. after sign bit and 1st MSB). i.e.
+	 * at the right side of 30th bit.
+	 */
+	qN = qN + s16norm - 30;
+
+	/* take the table index as the LOG2_OF_LOG_TABLE_SIZE bits right of the MSB */
+	s16tableIndex = (s16) (N >> (32 - (2 + LOG2_LOG_TABLE_SIZE)));
+
+	/* remove the MSB. the MSB is always 1 after normalization. */
+	s16tableIndex =
+	    s16tableIndex & (s16) ((1 << LOG2_LOG_TABLE_SIZE) - 1);
+
+	/* remove the (1+LOG2_OF_LOG_TABLE_SIZE) MSBs in the N. */
+	N = N & ((1 << (32 - (2 + LOG2_LOG_TABLE_SIZE))) - 1);
+
+	/* take the offset as the 16 MSBS after table index.
+	 */
+	u16offset = (u16) (N >> (32 - (2 + LOG2_LOG_TABLE_SIZE + 16)));
+
+	/* look the log value in the table. */
+	s32log = log_table[s16tableIndex];	/* q.15 format */
+
+	/* interpolate using the offset. */
+	s16errorApproximation = (s16) qm_mulu16(u16offset, (u16) (log_table[s16tableIndex + 1] - log_table[s16tableIndex]));	/* q.15 */
+
+	s32log = qm_add16((s16) s32log, s16errorApproximation);	/* q.15 format */
+
+	/* adjust for the qformat of the N as
+	 * log2(mag * 2^x) = log2(mag) + x
+	 */
+	s32log = qm_add32(s32log, ((s32) -qN) << 15);	/* q.15 format */
+
+	/* normalize the result. */
+	s16norm = qm_norm32(s32log);
+
+	/* bring all the important bits into lower 16 bits */
+	s32log = qm_shl32(s32log, s16norm - 16);	/* q.15+s16norm-16 format */
+
+	/* compute the log10(N) by multiplying log2(N) with log10(2).
+	 * as log10(mag * 2^x) = log2(mag * 2^x) * log10(2)
+	 * log10N in q.15+s16norm-16+1 (LOG10_2 is in q.16)
+	 */
+	*log10N = qm_muls16((s16) s32log, (s16) LOG10_2);
+
+	/* write the q format of the result. */
+	*qLog10N = 15 + s16norm - 16 + 1;
+
+	return;
+}
diff -druN linux-2.6.39-libre/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_qmath.h linux-3.0-rc7-libre/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_qmath.h
--- linux-2.6.39-libre/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_qmath.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/staging/brcm80211/brcmsmac/phy/wlc_phy_qmath.h	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2010 Broadcom Corporation
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef __QMATH_H__
+#define __QMATH_H__
+
+u16 qm_mulu16(u16 op1, u16 op2);
+
+s16 qm_muls16(s16 op1, s16 op2);
+
+s32 qm_add32(s32 op1, s32 op2);
+
+s16 qm_add16(s16 op1, s16 op2);
+
+s16 qm_sub16(s16 op1, s16 op2);
+
+s32 qm_shl32(s32 op, int shift);
+
+s16 qm_shl16(s16 op, int shift);
+
+s16 qm_shr16(s16 op, int shift);
+
+s16 qm_norm32(s32 op);
+
+void qm_log10(s32 N, s16 qN, s16 *log10N, s16 *qLog10N);
+
+#endif				/* #ifndef __QMATH_H__ */
diff -druN linux-2.6.39-libre/drivers/staging/brcm80211/brcmsmac/wlc_alloc.c linux-3.0-rc7-libre/drivers/staging/brcm80211/brcmsmac/wlc_alloc.c
--- linux-2.6.39-libre/drivers/staging/brcm80211/brcmsmac/wlc_alloc.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/brcm80211/brcmsmac/wlc_alloc.c	2011-07-11 19:51:52.000000000 -0400
@@ -18,7 +18,7 @@
 
 #include <bcmdefs.h>
 #include <bcmutils.h>
-#include <siutils.h>
+#include <aiutils.h>
 #include <wlioctl.h>
 #include <sbhnddma.h>
 
@@ -43,17 +43,7 @@
 static void wlc_pub_mfree(struct wlc_pub *pub);
 static void wlc_tunables_init(wlc_tunables_t *tunables, uint devid);
 
-void *wlc_calloc(uint unit, uint size)
-{
-	void *item;
-
-	item = kzalloc(size, GFP_ATOMIC);
-	if (item == NULL)
-		WL_ERROR("wl%d: %s: out of memory\n", unit, __func__);
-	return item;
-}
-
-void wlc_tunables_init(wlc_tunables_t *tunables, uint devid)
+static void wlc_tunables_init(wlc_tunables_t *tunables, uint devid)
 {
 	tunables->ntxd = NTXD;
 	tunables->nrxd = NRXD;
@@ -75,14 +65,13 @@
 {
 	struct wlc_pub *pub;
 
-	pub = wlc_calloc(unit, sizeof(struct wlc_pub));
+	pub = kzalloc(sizeof(struct wlc_pub), GFP_ATOMIC);
 	if (pub == NULL) {
 		*err = 1001;
 		goto fail;
 	}
 
-	pub->tunables = wlc_calloc(unit,
-		sizeof(wlc_tunables_t));
+	pub->tunables = kzalloc(sizeof(wlc_tunables_t), GFP_ATOMIC);
 	if (pub->tunables == NULL) {
 		*err = 1028;
 		goto fail;
@@ -91,12 +80,7 @@
 	/* need to init the tunables now */
 	wlc_tunables_init(pub->tunables, devid);
 
-	pub->_cnt = wlc_calloc(unit, sizeof(struct wl_cnt));
-	if (pub->_cnt == NULL)
-		goto fail;
-
-	pub->multicast = (u8 *)wlc_calloc(unit,
-		(ETH_ALEN * MAXMULTILIST));
+	pub->multicast = kzalloc(ETH_ALEN * MAXMULTILIST, GFP_ATOMIC);
 	if (pub->multicast == NULL) {
 		*err = 1003;
 		goto fail;
@@ -115,7 +99,6 @@
 		return;
 
 	kfree(pub->multicast);
-	kfree(pub->_cnt);
 	kfree(pub->tunables);
 	kfree(pub);
 }
@@ -124,12 +107,11 @@
 {
 	struct wlc_bsscfg *cfg;
 
-	cfg = (struct wlc_bsscfg *) wlc_calloc(unit, sizeof(struct wlc_bsscfg));
+	cfg = kzalloc(sizeof(struct wlc_bsscfg), GFP_ATOMIC);
 	if (cfg == NULL)
 		goto fail;
 
-	cfg->current_bss = (wlc_bss_info_t *)wlc_calloc(unit,
-		sizeof(wlc_bss_info_t));
+	cfg->current_bss = kzalloc(sizeof(wlc_bss_info_t), GFP_ATOMIC);
 	if (cfg->current_bss == NULL)
 		goto fail;
 
@@ -150,7 +132,8 @@
 	kfree(cfg);
 }
 
-void wlc_bsscfg_ID_assign(struct wlc_info *wlc, struct wlc_bsscfg *bsscfg)
+static void wlc_bsscfg_ID_assign(struct wlc_info *wlc,
+				 struct wlc_bsscfg *bsscfg)
 {
 	bsscfg->ID = wlc->next_bsscfg_ID;
 	wlc->next_bsscfg_ID++;
@@ -163,7 +146,7 @@
 {
 	struct wlc_info *wlc;
 
-	wlc = (struct wlc_info *) wlc_calloc(unit, sizeof(struct wlc_info));
+	wlc = kzalloc(sizeof(struct wlc_info), GFP_ATOMIC);
 	if (wlc == NULL) {
 		*err = 1002;
 		goto fail;
@@ -181,16 +164,15 @@
 
 	/* allocate struct wlc_hw_info state structure */
 
-	wlc->hw = (struct wlc_hw_info *)wlc_calloc(unit,
-			sizeof(struct wlc_hw_info));
+	wlc->hw = kzalloc(sizeof(struct wlc_hw_info), GFP_ATOMIC);
 	if (wlc->hw == NULL) {
 		*err = 1005;
 		goto fail;
 	}
 	wlc->hw->wlc = wlc;
 
-	wlc->hw->bandstate[0] = wlc_calloc(unit,
-		(sizeof(struct wlc_hwband) * MAXBANDS));
+	wlc->hw->bandstate[0] =
+		kzalloc(sizeof(struct wlc_hwband) * MAXBANDS, GFP_ATOMIC);
 	if (wlc->hw->bandstate[0] == NULL) {
 		*err = 1006;
 		goto fail;
@@ -204,15 +186,14 @@
 		}
 	}
 
-	wlc->modulecb = wlc_calloc(unit,
-		sizeof(struct modulecb) * WLC_MAXMODULES);
+	wlc->modulecb =
+		kzalloc(sizeof(struct modulecb) * WLC_MAXMODULES, GFP_ATOMIC);
 	if (wlc->modulecb == NULL) {
 		*err = 1009;
 		goto fail;
 	}
 
-	wlc->default_bss = (wlc_bss_info_t *)wlc_calloc(unit,
-		sizeof(wlc_bss_info_t));
+	wlc->default_bss = kzalloc(sizeof(wlc_bss_info_t), GFP_ATOMIC);
 	if (wlc->default_bss == NULL) {
 		*err = 1010;
 		goto fail;
@@ -225,15 +206,16 @@
 	}
 	wlc_bsscfg_ID_assign(wlc, wlc->cfg);
 
-	wlc->pkt_callback = wlc_calloc(unit,
-		(sizeof(struct pkt_cb) * (wlc->pub->tunables->maxpktcb + 1)));
+	wlc->pkt_callback = kzalloc(sizeof(struct pkt_cb) *
+				    (wlc->pub->tunables->maxpktcb + 1),
+				    GFP_ATOMIC);
 	if (wlc->pkt_callback == NULL) {
 		*err = 1013;
 		goto fail;
 	}
 
-	wlc->wsec_def_keys[0] = (wsec_key_t *)wlc_calloc(unit,
-		(sizeof(wsec_key_t) * WLC_DEFAULT_KEYS));
+	wlc->wsec_def_keys[0] =
+		kzalloc(sizeof(wsec_key_t) * WLC_DEFAULT_KEYS, GFP_ATOMIC);
 	if (wlc->wsec_def_keys[0] == NULL) {
 		*err = 1015;
 		goto fail;
@@ -246,21 +228,20 @@
 		}
 	}
 
-	wlc->protection = wlc_calloc(unit,
-		sizeof(struct wlc_protection));
+	wlc->protection = kzalloc(sizeof(struct wlc_protection), GFP_ATOMIC);
 	if (wlc->protection == NULL) {
 		*err = 1016;
 		goto fail;
 	}
 
-	wlc->stf = wlc_calloc(unit, sizeof(struct wlc_stf));
+	wlc->stf = kzalloc(sizeof(struct wlc_stf), GFP_ATOMIC);
 	if (wlc->stf == NULL) {
 		*err = 1017;
 		goto fail;
 	}
 
-	wlc->bandstate[0] = (struct wlcband *)wlc_calloc(unit,
-				(sizeof(struct wlcband)*MAXBANDS));
+	wlc->bandstate[0] =
+		kzalloc(sizeof(struct wlcband)*MAXBANDS, GFP_ATOMIC);
 	if (wlc->bandstate[0] == NULL) {
 		*err = 1025;
 		goto fail;
@@ -274,15 +255,14 @@
 		}
 	}
 
-	wlc->corestate = (struct wlccore *)wlc_calloc(unit,
-						      sizeof(struct wlccore));
+	wlc->corestate = kzalloc(sizeof(struct wlccore), GFP_ATOMIC);
 	if (wlc->corestate == NULL) {
 		*err = 1026;
 		goto fail;
 	}
 
 	wlc->corestate->macstat_snapshot =
-		(macstat_t *)wlc_calloc(unit, sizeof(macstat_t));
+		kzalloc(sizeof(macstat_t), GFP_ATOMIC);
 	if (wlc->corestate->macstat_snapshot == NULL) {
 		*err = 1027;
 		goto fail;
diff -druN linux-2.6.39-libre/drivers/staging/brcm80211/brcmsmac/wlc_alloc.h linux-3.0-rc7-libre/drivers/staging/brcm80211/brcmsmac/wlc_alloc.h
--- linux-2.6.39-libre/drivers/staging/brcm80211/brcmsmac/wlc_alloc.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/brcm80211/brcmsmac/wlc_alloc.h	2011-07-11 19:51:52.000000000 -0400
@@ -14,7 +14,5 @@
  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
-extern void *wlc_calloc(uint unit, uint size);
-
 extern struct wlc_info *wlc_attach_malloc(uint unit, uint *err, uint devid);
 extern void wlc_detach_mfree(struct wlc_info *wlc);
diff -druN linux-2.6.39-libre/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c linux-3.0-rc7-libre/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c
--- linux-2.6.39-libre/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c	2011-07-11 19:51:52.000000000 -0400
@@ -18,7 +18,7 @@
 
 #include <bcmdefs.h>
 #include <bcmutils.h>
-#include <siutils.h>
+#include <aiutils.h>
 #include <wlioctl.h>
 #include <sbhnddma.h>
 #include <hnddma.h>
@@ -38,12 +38,6 @@
 #include "wlc_main.h"
 #include "wlc_ampdu.h"
 
-/*
- *	Disable AMPDU statistics counters for now
- */
-#define WLCNTINCR(a)
-#define WLCNTADD(a, b)
-
 #define AMPDU_MAX_MPDU		32	/* max number of mpdus in an ampdu */
 #define AMPDU_NUM_MPDU_LEGACY	16	/* max number of mpdus in an ampdu to a legacy */
 #define AMPDU_TX_BA_MAX_WSIZE	64	/* max Tx ba window size (in pdu) */
@@ -76,16 +70,6 @@
 	AMPDU_DELIMITER_LEN + 3\
 	+ DOT11_A4_HDR_LEN + DOT11_QOS_LEN + DOT11_IV_MAX_LEN)
 
-#ifdef BCMDBG
-u32 wl_ampdu_dbg =
-    WL_AMPDU_UPDN_VAL |
-    WL_AMPDU_ERR_VAL |
-    WL_AMPDU_TX_VAL |
-    WL_AMPDU_RX_VAL |
-    WL_AMPDU_CTL_VAL |
-    WL_AMPDU_HW_VAL | WL_AMPDU_HWTXS_VAL | WL_AMPDU_HWDBG_VAL;
-#endif
-
 /* structure to hold tx fifo information and pre-loading state
  * counters specific to tx underflows of ampdus
  * some counters might be redundant with the ones in wlc or ampdu structures.
@@ -130,6 +114,12 @@
 
 };
 
+/* used for flushing ampdu packets */
+struct cb_del_ampdu_pars {
+	struct ieee80211_sta *sta;
+	u16 tid;
+};
+
 #define AMPDU_CLEANUPFLAG_RX   (0x1)
 #define AMPDU_CLEANUPFLAG_TX   (0x2)
 
@@ -143,9 +133,6 @@
 static scb_ampdu_tid_ini_t *wlc_ampdu_init_tid_ini(struct ampdu_info *ampdu,
 						   scb_ampdu_t *scb_ampdu,
 						   u8 tid, bool override);
-static void ampdu_cleanup_tid_ini(struct ampdu_info *ampdu,
-				  scb_ampdu_t *scb_ampdu,
-				  u8 tid, bool force);
 static void ampdu_update_max_txlen(struct ampdu_info *ampdu, u8 dur);
 static void scb_ampdu_update_config(struct ampdu_info *ampdu, struct scb *scb);
 static void scb_ampdu_update_config_all(struct ampdu_info *ampdu);
@@ -164,17 +151,10 @@
 	struct ampdu_info *ampdu;
 	int i;
 
-	/* some code depends on packed structures */
-	ASSERT(DOT11_MAXNUMFRAGS == NBITS(u16));
-	ASSERT(ISPOWEROF2(AMPDU_TX_BA_MAX_WSIZE));
-	ASSERT(ISPOWEROF2(AMPDU_RX_BA_MAX_WSIZE));
-	ASSERT(wlc->pub->tunables->ampdunummpdu <= AMPDU_MAX_MPDU);
-	ASSERT(wlc->pub->tunables->ampdunummpdu > 0);
-
 	ampdu = kzalloc(sizeof(struct ampdu_info), GFP_ATOMIC);
 	if (!ampdu) {
-		WL_ERROR("wl%d: wlc_ampdu_attach: out of mem\n",
-			 wlc->pub->unit);
+		wiphy_err(wlc->wiphy, "wl%d: wlc_ampdu_attach: out of mem\n",
+			  wlc->pub->unit);
 		return NULL;
 	}
 	ampdu->wlc = wlc;
@@ -237,27 +217,6 @@
 	kfree(ampdu);
 }
 
-void scb_ampdu_cleanup(struct ampdu_info *ampdu, struct scb *scb)
-{
-	scb_ampdu_t *scb_ampdu = SCB_AMPDU_CUBBY(ampdu, scb);
-	u8 tid;
-
-	WL_AMPDU_UPDN("scb_ampdu_cleanup: enter\n");
-	ASSERT(scb_ampdu);
-
-	for (tid = 0; tid < AMPDU_MAX_SCB_TID; tid++) {
-		ampdu_cleanup_tid_ini(ampdu, scb_ampdu, tid, false);
-	}
-}
-
-/* reset the ampdu state machine so that it can gracefully handle packets that were
- * freed from the dma and tx queues during reinit
- */
-void wlc_ampdu_reset(struct ampdu_info *ampdu)
-{
-	WL_NONE("%s: Entering\n", __func__);
-}
-
 static void scb_ampdu_update_config(struct ampdu_info *ampdu, struct scb *scb)
 {
 	scb_ampdu_t *scb_ampdu = SCB_AMPDU_CUBBY(ampdu, scb);
@@ -284,11 +243,9 @@
 	scb_ampdu->release = min(scb_ampdu->release,
 				 ampdu->fifo_tb[TX_AC_BE_FIFO].
 				 mcs2ampdu_table[FFPLD_MAX_MCS]);
-
-	ASSERT(scb_ampdu->release);
 }
 
-void scb_ampdu_update_config_all(struct ampdu_info *ampdu)
+static void scb_ampdu_update_config_all(struct ampdu_info *ampdu)
 {
 	scb_ampdu_update_config(ampdu, ampdu->wlc->pub->global_scb);
 }
@@ -336,7 +293,7 @@
 			 M_UCODE_MACSTAT + offsetof(macstat_t, txfunfl[fid]));
 	new_txunfl = (u16) (cur_txunfl - fifo->prev_txfunfl);
 	if (new_txunfl == 0) {
-		WL_FFPLD("check_txunfl : TX status FRAG set but no tx underflows\n");
+		BCMMSG(wlc->wiphy, "TX status FRAG set but no tx underflows\n");
 		return -1;
 	}
 	fifo->prev_txfunfl = cur_txunfl;
@@ -346,7 +303,6 @@
 
 	/* check if fifo is big enough */
 	if (wlc_xmtfifo_sz_get(wlc, fid, &xmtfifo_sz)) {
-		WL_FFPLD("check_txunfl : get xmtfifo_sz failed\n");
 		return -1;
 	}
 
@@ -360,8 +316,8 @@
 	if (fifo->accum_txfunfl < 10)
 		return 0;
 
-	WL_FFPLD("ampdu_count %d  tx_underflows %d\n",
-		 current_ampdu_cnt, fifo->accum_txfunfl);
+	BCMMSG(wlc->wiphy, "ampdu_count %d  tx_underflows %d\n",
+		current_ampdu_cnt, fifo->accum_txfunfl);
 
 	/*
 	   compute the current ratio of tx unfl per ampdu.
@@ -388,7 +344,6 @@
 	 */
 
 	if (fifo->ampdu_pld_size >= max_mpdu * FFPLD_MPDU_SIZE) {
-		WL_FFPLD(("tx fifo pld : max ampdu fits in fifo\n)"));
 		fifo->accum_txfunfl = 0;
 		return 0;
 	}
@@ -406,7 +361,7 @@
 		/*
 		   compute a new dma xfer rate for max_mpdu @ max mcs.
 		   This is the minimum dma rate that
-		   can achieve no unferflow condition for the current mpdu size.
+		   can achieve no underflow condition for the current mpdu size.
 		 */
 		/* note : we divide/multiply by 100 to avoid integer overflows */
 		fifo->dmaxferrate =
@@ -414,8 +369,9 @@
 		      (max_mpdu * FFPLD_MPDU_SIZE - fifo->ampdu_pld_size))
 		     / (max_mpdu * FFPLD_MPDU_SIZE)) * 100;
 
-		WL_FFPLD("DMA estimated transfer rate %d; pre-load size %d\n",
-			 fifo->dmaxferrate, fifo->ampdu_pld_size);
+		BCMMSG(wlc->wiphy, "DMA estimated transfer rate %d; "
+			"pre-load size %d\n",
+			fifo->dmaxferrate, fifo->ampdu_pld_size);
 	} else {
 
 		/* decrease ampdu size */
@@ -469,7 +425,7 @@
 	}
 }
 
-static void BCMFASTPATH
+static void
 wlc_ampdu_agg(struct ampdu_info *ampdu, struct scb *scb, struct sk_buff *p,
 	      uint prec)
 {
@@ -487,7 +443,7 @@
 	return;
 }
 
-int BCMFASTPATH
+int
 wlc_sendampdu(struct ampdu_info *ampdu, struct wlc_txq_info *qi,
 	      struct sk_buff **pdu, int prec)
 {
@@ -521,35 +477,31 @@
 	bool fbr_iscck;
 	struct ieee80211_tx_info *tx_info;
 	u16 qlen;
+	struct wiphy *wiphy;
 
 	wlc = ampdu->wlc;
+	wiphy = wlc->wiphy;
 	p = *pdu;
 
-	ASSERT(p);
-
 	tid = (u8) (p->priority);
-	ASSERT(tid < AMPDU_MAX_SCB_TID);
 
 	f = ampdu->fifo_tb + prio2fifo[tid];
 
 	scb = wlc->pub->global_scb;
-	ASSERT(scb->magic == SCB_MAGIC);
-
 	scb_ampdu = SCB_AMPDU_CUBBY(ampdu, scb);
-	ASSERT(scb_ampdu);
 	ini = &scb_ampdu->ini[tid];
 
 	/* Let pressure continue to build ... */
 	qlen = pktq_plen(&qi->q, prec);
 	if (ini->tx_in_transit > 0 && qlen < scb_ampdu->max_pdu) {
-		return BCME_BUSY;
+		return -EBUSY;
 	}
 
 	wlc_ampdu_agg(ampdu, scb, p, tid);
 
 	if (wlc->block_datafifo) {
-		WL_ERROR("%s: Fifo blocked\n", __func__);
-		return BCME_BUSY;
+		wiphy_err(wiphy, "%s: Fifo blocked\n", __func__);
+		return -EBUSY;
 	}
 	rr_retry_limit = ampdu->rr_retry_limit_tid[tid];
 	ampdu_len = 0;
@@ -563,32 +515,29 @@
 		if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) {
 			err = wlc_prep_pdu(wlc, p, &fifo);
 		} else {
-			WL_ERROR("%s: AMPDU flag is off!\n", __func__);
+			wiphy_err(wiphy, "%s: AMPDU flag is off!\n", __func__);
 			*pdu = NULL;
 			err = 0;
 			break;
 		}
 
 		if (err) {
-			if (err == BCME_BUSY) {
-				WL_ERROR("wl%d: wlc_sendampdu: prep_xdu retry; seq 0x%x\n",
-					 wlc->pub->unit, seq);
-				WLCNTINCR(ampdu->cnt->sduretry);
+			if (err == -EBUSY) {
+				wiphy_err(wiphy, "wl%d: wlc_sendampdu: "
+					  "prep_xdu retry; seq 0x%x\n",
+					  wlc->pub->unit, seq);
 				*pdu = p;
 				break;
 			}
 
 			/* error in the packet; reject it */
-			WL_AMPDU_ERR("wl%d: wlc_sendampdu: prep_xdu rejected; seq 0x%x\n",
-				     wlc->pub->unit, seq);
-			WLCNTINCR(ampdu->cnt->sdurejected);
-
+			wiphy_err(wiphy, "wl%d: wlc_sendampdu: prep_xdu "
+				  "rejected; seq 0x%x\n", wlc->pub->unit, seq);
 			*pdu = NULL;
 			break;
 		}
 
 		/* pkt is good to be aggregated */
-		ASSERT(tx_info->flags & IEEE80211_TX_CTL_AMPDU);
 		txh = (d11txh_t *) p->data;
 		plcp = (u8 *) (txh + 1);
 		h = (struct ieee80211_hdr *)(plcp + D11_PHY_HDR_LEN);
@@ -599,7 +548,6 @@
 		mcl = le16_to_cpu(txh->MacTxControlLow);
 		mcl &= ~TXC_AMPDU_MASK;
 		fbr_iscck = !(le16_to_cpu(txh->XtraFrameTypes) & 0x3);
-		ASSERT(!fbr_iscck);
 		txh->PreloadSize = 0;	/* always default to 0 */
 
 		/*  Handle retry limits */
@@ -607,7 +555,6 @@
 			txrate[0].count++;
 			rr = true;
 			fbr = false;
-			ASSERT(!fbr);
 		} else {
 			fbr = true;
 			rr = false;
@@ -622,8 +569,8 @@
 		ndelim = txh->RTSPLCPFallback[AMPDU_FBR_NULL_DELIM];
 		seg_cnt += 1;
 
-		WL_AMPDU_TX("wl%d: wlc_sendampdu: mpdu %d plcp_len %d\n",
-			    wlc->pub->unit, count, len);
+		BCMMSG(wlc->wiphy, "wl%d: mpdu %d plcp_len %d\n",
+			wlc->pub->unit, count, len);
 
 		/*
 		 * aggregateable mpdu. For ucode/hw agg,
@@ -651,10 +598,11 @@
 		len = roundup(len, 4);
 		ampdu_len += (len + (ndelim + 1) * AMPDU_DELIMITER_LEN);
 
-		dma_len += (u16) pkttotlen(p);
+		dma_len += (u16) bcm_pkttotlen(p);
 
-		WL_AMPDU_TX("wl%d: wlc_sendampdu: ampdu_len %d seg_cnt %d null delim %d\n",
-			    wlc->pub->unit, ampdu_len, seg_cnt, ndelim);
+		BCMMSG(wlc->wiphy, "wl%d: ampdu_len %d"
+			" seg_cnt %d null delim %d\n",
+			wlc->pub->unit, ampdu_len, seg_cnt, ndelim);
 
 		txh->MacTxControlLow = cpu_to_le16(mcl);
 
@@ -679,15 +627,14 @@
 			is40 = (plcp0 & MIMO_PLCP_40MHZ) ? 1 : 0;
 			sgi = PLCP3_ISSGI(plcp3) ? 1 : 0;
 			mcs = plcp0 & ~MIMO_PLCP_40MHZ;
-			ASSERT(mcs < MCS_TABLE_SIZE);
 			maxlen =
 			    min(scb_ampdu->max_rxlen,
 				ampdu->max_txlen[mcs][is40][sgi]);
 
-			WL_NONE("sendampdu: sgi %d, is40 %d, mcs %d\n",
-				sgi, is40, mcs);
-
-			maxlen = 64 * 1024;	/* XXX Fix me to honor real max_rxlen */
+			/* XXX Fix me to honor real max_rxlen */
+			/* can fix this as soon as ampdu_action() in mac80211.h
+			 * gets extra u8buf_size par */
+			maxlen = 64 * 1024;
 
 			if (is40)
 				mimo_ctlchbw =
@@ -728,14 +675,13 @@
 		/* test whether to add more */
 		if ((MCS_RATE(mcs, true, false) >= f->dmaxferrate) &&
 		    (count == f->mcs2ampdu_table[mcs])) {
-			WL_AMPDU_ERR("wl%d: PR 37644: stopping ampdu at %d for mcs %d\n",
-				     wlc->pub->unit, count, mcs);
+			BCMMSG(wlc->wiphy, "wl%d: PR 37644: stopping"
+				" ampdu at %d for mcs %d\n",
+				wlc->pub->unit, count, mcs);
 			break;
 		}
 
 		if (count == scb_ampdu->max_pdu) {
-			WL_NONE("Stop taking from q, reached %d deep\n",
-				scb_ampdu->max_pdu);
 			break;
 		}
 
@@ -748,26 +694,24 @@
 			    ((u8) (p->priority) == tid)) {
 
 				plen =
-				    pkttotlen(p) + AMPDU_MAX_MPDU_OVERHEAD;
+				    bcm_pkttotlen(p) + AMPDU_MAX_MPDU_OVERHEAD;
 				plen = max(scb_ampdu->min_len, plen);
 
 				if ((plen + ampdu_len) > maxlen) {
 					p = NULL;
-					WL_ERROR("%s: Bogus plen #1\n",
-						 __func__);
-					ASSERT(3 == 4);
+					wiphy_err(wiphy, "%s: Bogus plen #1\n",
+						__func__);
 					continue;
 				}
 
 				/* check if there are enough descriptors available */
 				if (TXAVAIL(wlc, fifo) <= (seg_cnt + 1)) {
-					WL_ERROR("%s: No fifo space   !!!!!!\n",
-						 __func__);
+					wiphy_err(wiphy, "%s: No fifo space  "
+						  "!!\n", __func__);
 					p = NULL;
 					continue;
 				}
-				p = pktq_pdeq(&qi->q, prec);
-				ASSERT(p);
+				p = bcm_pktq_pdeq(&qi->q, prec);
 			} else {
 				p = NULL;
 			}
@@ -777,8 +721,6 @@
 	ini->tx_in_transit += count;
 
 	if (count) {
-		WLCNTADD(ampdu->cnt->txmpdu, count);
-
 		/* patch up the last txh */
 		txh = (d11txh_t *) pkt[count - 1]->data;
 		mcl = le16_to_cpu(txh->MacTxControlLow);
@@ -861,22 +803,20 @@
 
 		/* set flag and plcp for fallback rate */
 		if (fbr) {
-			WLCNTADD(ampdu->cnt->txfbr_mpdu, count);
-			WLCNTINCR(ampdu->cnt->txfbr_ampdu);
 			mch |= TXC_AMPDU_FBR;
 			txh->MacTxControlHigh = cpu_to_le16(mch);
 			WLC_SET_MIMO_PLCP_AMPDU(plcp);
 			WLC_SET_MIMO_PLCP_AMPDU(txh->FragPLCPFallback);
 		}
 
-		WL_AMPDU_TX("wl%d: wlc_sendampdu: count %d ampdu_len %d\n",
-			    wlc->pub->unit, count, ampdu_len);
+		BCMMSG(wlc->wiphy, "wl%d: count %d ampdu_len %d\n",
+			wlc->pub->unit, count, ampdu_len);
 
 		/* inform rate_sel if it this is a rate probe pkt */
 		frameid = le16_to_cpu(txh->TxFrameID);
 		if (frameid & TXFID_RATE_PROBE_MASK) {
-			WL_ERROR("%s: XXX what to do with TXFID_RATE_PROBE_MASK!?\n",
-				 __func__);
+			wiphy_err(wiphy, "%s: XXX what to do with "
+				  "TXFID_RATE_PROBE_MASK!?\n", __func__);
 		}
 		for (i = 0; i < count; i++)
 			wlc_txfifo(wlc, fifo, pkt[i], i == (count - 1),
@@ -887,7 +827,7 @@
 	return err;
 }
 
-void BCMFASTPATH
+void
 wlc_ampdu_dotxstatus(struct ampdu_info *ampdu, struct scb *scb,
 		     struct sk_buff *p, tx_status_t *txs)
 {
@@ -898,8 +838,6 @@
 	struct ieee80211_tx_info *tx_info;
 
 	tx_info = IEEE80211_SKB_CB(p);
-	ASSERT(tx_info->flags & IEEE80211_TX_CTL_AMPDU);
-	ASSERT(txs->status & TX_STATUS_AMPDU);
 
 	/* BMAC_NOTE: For the split driver, second level txstatus comes later
 	 * So if the ACK was received then wait for the second level else just
@@ -913,22 +851,16 @@
 			udelay(1);
 			status_delay++;
 			if (status_delay > 10) {
-				ASSERT(status_delay <= 10);
-				return;
+				return; /* error condition */
 			}
 		}
 
-		ASSERT(!(s1 & TX_STATUS_INTERMEDIATE));
-		ASSERT(s1 & TX_STATUS_AMPDU);
 		s2 = R_REG(&wlc->regs->frmtxstatus2);
 	}
 
 	if (likely(scb)) {
-		ASSERT(scb->magic == SCB_MAGIC);
 		scb_ampdu = SCB_AMPDU_CUBBY(ampdu, scb);
-		ASSERT(scb_ampdu);
 		ini = SCB_AMPDU_INI(scb_ampdu, p->priority);
-		ASSERT(ini->scb == scb);
 		wlc_ampdu_dotxstatus_complete(ampdu, scb, p, txs, s1, s2);
 	} else {
 		/* loop through all pkts and free */
@@ -939,21 +871,19 @@
 			tx_info = IEEE80211_SKB_CB(p);
 			txh = (d11txh_t *) p->data;
 			mcl = le16_to_cpu(txh->MacTxControlLow);
-			ASSERT(tx_info->flags & IEEE80211_TX_CTL_AMPDU);
-			pkt_buf_free_skb(p);
+			bcm_pkt_buf_free_skb(p);
 			/* break out if last packet of ampdu */
 			if (((mcl & TXC_AMPDU_MASK) >> TXC_AMPDU_SHIFT) ==
 			    TXC_AMPDU_LAST)
 				break;
 			p = GETNEXTTXP(wlc, queue);
-			ASSERT(p != NULL);
 		}
 		wlc_txfifo_complete(wlc, queue, ampdu->txpkt_weight);
 	}
 	wlc_ampdu_txflowcontrol(wlc, scb_ampdu, ini);
 }
 
-void
+static void
 rate_status(struct wlc_info *wlc, struct ieee80211_tx_info *tx_info,
 	    tx_status_t *txs, u8 mcs)
 {
@@ -969,7 +899,7 @@
 
 #define SHORTNAME "AMPDU status"
 
-static void BCMFASTPATH
+static void
 wlc_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, struct scb *scb,
 			      struct sk_buff *p, tx_status_t *txs,
 			      u32 s1, u32 s2)
@@ -991,30 +921,21 @@
 	u8 antselid = 0;
 	u8 retry_limit, rr_retry_limit;
 	struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(p);
+	struct wiphy *wiphy = wlc->wiphy;
 
 #ifdef BCMDBG
 	u8 hole[AMPDU_MAX_MPDU];
 	memset(hole, 0, sizeof(hole));
 #endif
 
-	ASSERT(tx_info->flags & IEEE80211_TX_CTL_AMPDU);
-	ASSERT(txs->status & TX_STATUS_AMPDU);
-
 	scb_ampdu = SCB_AMPDU_CUBBY(ampdu, scb);
-	ASSERT(scb_ampdu);
-
 	tid = (u8) (p->priority);
 
 	ini = SCB_AMPDU_INI(scb_ampdu, tid);
 	retry_limit = ampdu->retry_limit_tid[tid];
 	rr_retry_limit = ampdu->rr_retry_limit_tid[tid];
-
-	ASSERT(ini->scb == scb);
-
 	memset(bitmap, 0, sizeof(bitmap));
 	queue = txs->frameid & TXFID_QUEUE_MASK;
-	ASSERT(queue < AC_COUNT);
-
 	supr_status = txs->status & TX_STATUS_SUPR_MASK;
 
 	if (txs->status & TX_STATUS_ACK_RCV) {
@@ -1022,13 +943,13 @@
 			update_rate = false;
 		}
 
-		ASSERT(txs->status & TX_STATUS_INTERMEDIATE);
+		WARN_ON(!(txs->status & TX_STATUS_INTERMEDIATE));
 		start_seq = txs->sequence >> SEQNUM_SHIFT;
 		bitmap[0] = (txs->status & TX_STATUS_BA_BMAP03_MASK) >>
 		    TX_STATUS_BA_BMAP03_SHIFT;
 
-		ASSERT(!(s1 & TX_STATUS_INTERMEDIATE));
-		ASSERT(s1 & TX_STATUS_AMPDU);
+		WARN_ON(s1 & TX_STATUS_INTERMEDIATE);
+		WARN_ON(!(s1 & TX_STATUS_AMPDU));
 
 		bitmap[0] |=
 		    (s1 & TX_STATUS_BA_BMAP47_MASK) <<
@@ -1044,30 +965,24 @@
 
 		ba_recd = true;
 	} else {
-		WLCNTINCR(ampdu->cnt->noba);
 		if (supr_status) {
 			update_rate = false;
 			if (supr_status == TX_STATUS_SUPR_BADCH) {
-				WL_ERROR("%s: Pkt tx suppressed, illegal channel possibly %d\n",
-					 __func__,
-					 CHSPEC_CHANNEL(wlc->default_bss->chanspec));
+				wiphy_err(wiphy, "%s: Pkt tx suppressed, "
+					  "illegal channel possibly %d\n",
+					  __func__, CHSPEC_CHANNEL(
+					  wlc->default_bss->chanspec));
 			} else {
-				if (supr_status == TX_STATUS_SUPR_FRAG)
-					WL_NONE("%s: AMPDU frag err\n",
-						__func__);
-				else
-					WL_ERROR("%s: wlc_ampdu_dotxstatus: supr_status 0x%x\n",
+				if (supr_status != TX_STATUS_SUPR_FRAG)
+					wiphy_err(wiphy, "%s: wlc_ampdu_dotx"
+						  "status:supr_status 0x%x\n",
 						 __func__, supr_status);
 			}
 			/* no need to retry for badch; will fail again */
 			if (supr_status == TX_STATUS_SUPR_BADCH ||
 			    supr_status == TX_STATUS_SUPR_EXPTIME) {
 				retry = false;
-				wlc->pub->_cnt->txchanrej++;
 			} else if (supr_status == TX_STATUS_SUPR_EXPTIME) {
-
-				wlc->pub->_cnt->txexptime++;
-
 				/* TX underflow : try tuning pre-loading or ampdu size */
 			} else if (supr_status == TX_STATUS_SUPR_FRAG) {
 				/* if there were underflows, but pre-loading is not active,
@@ -1080,12 +995,12 @@
 			}
 		} else if (txs->phyerr) {
 			update_rate = false;
-			wlc->pub->_cnt->txphyerr++;
-			WL_ERROR("wl%d: wlc_ampdu_dotxstatus: tx phy error (0x%x)\n",
-				 wlc->pub->unit, txs->phyerr);
+			wiphy_err(wiphy, "wl%d: wlc_ampdu_dotxstatus: tx phy "
+				  "error (0x%x)\n", wlc->pub->unit,
+				  txs->phyerr);
 
 			if (WL_ERROR_ON()) {
-				prpkt("txpkt (AMPDU)", p);
+				bcm_prpkt("txpkt (AMPDU)", p);
 				wlc_print_txdesc((d11txh_t *) p->data);
 			}
 			wlc_print_txstatus(txs);
@@ -1095,7 +1010,6 @@
 	/* loop through all pkts and retry if not acked */
 	while (p) {
 		tx_info = IEEE80211_SKB_CB(p);
-		ASSERT(tx_info->flags & IEEE80211_TX_CTL_AMPDU);
 		txh = (d11txh_t *) p->data;
 		mcl = le16_to_cpu(txh->MacTxControlLow);
 		plcp = (u8 *) (txh + 1);
@@ -1111,11 +1025,10 @@
 		ack_recd = false;
 		if (ba_recd) {
 			bindex = MODSUB_POW2(seq, start_seq, SEQNUM_MAX);
-
-			WL_AMPDU_TX("%s: tid %d seq is %d, start_seq is %d, bindex is %d set %d, index %d\n",
-				    __func__, tid, seq, start_seq, bindex,
-				    isset(bitmap, bindex), index);
-
+			BCMMSG(wlc->wiphy, "tid %d seq %d,"
+				" start_seq %d, bindex %d set %d, index %d\n",
+				tid, seq, start_seq, bindex,
+				isset(bitmap, bindex), index);
 			/* if acked then clear bit and free packet */
 			if ((bindex < AMPDU_TX_BA_MAX_WSIZE)
 			    && isset(bitmap, bindex)) {
@@ -1123,21 +1036,12 @@
 				ini->txretry[index] = 0;
 
 				/* ampdu_ack_len: number of acked aggregated frames */
-				/* ampdu_ack_map: block ack bit map for the aggregation */
 				/* ampdu_len: number of aggregated frames */
 				rate_status(wlc, tx_info, txs, mcs);
 				tx_info->flags |= IEEE80211_TX_STAT_ACK;
 				tx_info->flags |= IEEE80211_TX_STAT_AMPDU;
-
-				/* XXX TODO: Make these accurate. */
 				tx_info->status.ampdu_ack_len =
-				    (txs->
-				     status & TX_STATUS_FRM_RTX_MASK) >>
-				    TX_STATUS_FRM_RTX_SHIFT;
-				tx_info->status.ampdu_len =
-				    (txs->
-				     status & TX_STATUS_FRM_RTX_MASK) >>
-				    TX_STATUS_FRM_RTX_SHIFT;
+					tx_info->status.ampdu_len = 1;
 
 				skb_pull(p, D11_PHY_HDR_LEN);
 				skb_pull(p, D11_TXH_LEN);
@@ -1163,12 +1067,15 @@
 				/* Retry timeout */
 				ini->tx_in_transit--;
 				ieee80211_tx_info_clear_status(tx_info);
+				tx_info->status.ampdu_ack_len = 0;
+				tx_info->status.ampdu_len = 1;
 				tx_info->flags |=
 				    IEEE80211_TX_STAT_AMPDU_NO_BACK;
 				skb_pull(p, D11_PHY_HDR_LEN);
 				skb_pull(p, D11_TXH_LEN);
-				WL_ERROR("%s: BA Timeout, seq %d, in_transit %d\n",
-					 SHORTNAME, seq, ini->tx_in_transit);
+				wiphy_err(wiphy, "%s: BA Timeout, seq %d, in_"
+					"transit %d\n", SHORTNAME, seq,
+					ini->tx_in_transit);
 				ieee80211_tx_status_irqsafe(wlc->pub->ieee_hw,
 							    p);
 			}
@@ -1181,12 +1088,8 @@
 			break;
 
 		p = GETNEXTTXP(wlc, queue);
-		if (p == NULL) {
-			ASSERT(p);
-			break;
-		}
 	}
-	wlc_send_q(wlc, wlc->active_queue);
+	wlc_send_q(wlc);
 
 	/* update rate state */
 	antselid = wlc_antsel_antsel2id(wlc->asi, mimoantsel);
@@ -1194,28 +1097,6 @@
 	wlc_txfifo_complete(wlc, queue, ampdu->txpkt_weight);
 }
 
-static void
-ampdu_cleanup_tid_ini(struct ampdu_info *ampdu, scb_ampdu_t *scb_ampdu, u8 tid,
-		      bool force)
-{
-	scb_ampdu_tid_ini_t *ini;
-	ini = SCB_AMPDU_INI(scb_ampdu, tid);
-	if (!ini)
-		return;
-
-	WL_AMPDU_CTL("wl%d: ampdu_cleanup_tid_ini: tid %d\n",
-		     ampdu->wlc->pub->unit, tid);
-
-	if (ini->tx_in_transit && !force)
-		return;
-
-	scb_ampdu = SCB_AMPDU_CUBBY(ampdu, ini->scb);
-	ASSERT(ini == &scb_ampdu->ini[ini->tid]);
-
-	/* free all buffered tx packets */
-	pktq_pflush(&scb_ampdu->txq, ini->tid, true, NULL, 0);
-}
-
 /* initialize the initiator code for tid */
 static scb_ampdu_tid_ini_t *wlc_ampdu_init_tid_ini(struct ampdu_info *ampdu,
 						   scb_ampdu_t *scb_ampdu,
@@ -1223,14 +1104,10 @@
 {
 	scb_ampdu_tid_ini_t *ini;
 
-	ASSERT(scb_ampdu);
-	ASSERT(scb_ampdu->scb);
-	ASSERT(SCB_AMPDU(scb_ampdu->scb));
-	ASSERT(tid < AMPDU_MAX_SCB_TID);
-
 	/* check for per-tid control of ampdu */
 	if (!ampdu->ini_enable[tid]) {
-		WL_ERROR("%s: Rejecting tid %d\n", __func__, tid);
+		wiphy_err(ampdu->wlc->wiphy, "%s: Rejecting tid %d\n",
+			  __func__, tid);
 		return NULL;
 	}
 
@@ -1238,8 +1115,6 @@
 	ini->tid = tid;
 	ini->scb = scb_ampdu->scb;
 	ini->magic = INI_MAGIC;
-	WLCNTINCR(ampdu->cnt->txaddbareq);
-
 	return ini;
 }
 
@@ -1251,14 +1126,14 @@
 
 	if (on) {
 		if (!N_ENAB(wlc->pub)) {
-			WL_AMPDU_ERR("wl%d: driver not nmode enabled\n",
-				     wlc->pub->unit);
-			return BCME_UNSUPPORTED;
+			wiphy_err(ampdu->wlc->wiphy, "wl%d: driver not "
+				"nmode enabled\n", wlc->pub->unit);
+			return -ENOTSUPP;
 		}
 		if (!wlc_ampdu_cap(ampdu)) {
-			WL_AMPDU_ERR("wl%d: device not ampdu capable\n",
-				     wlc->pub->unit);
-			return BCME_UNSUPPORTED;
+			wiphy_err(ampdu->wlc->wiphy, "wl%d: device not "
+				"ampdu capable\n", wlc->pub->unit);
+			return -ENOTSUPP;
 		}
 		wlc->pub->_ampdu = on;
 	}
@@ -1295,43 +1170,6 @@
 	}
 }
 
-u8 BCMFASTPATH
-wlc_ampdu_null_delim_cnt(struct ampdu_info *ampdu, struct scb *scb,
-			 ratespec_t rspec, int phylen)
-{
-	scb_ampdu_t *scb_ampdu;
-	int bytes, cnt, tmp;
-	u8 tx_density;
-
-	ASSERT(scb);
-	ASSERT(SCB_AMPDU(scb));
-
-	scb_ampdu = SCB_AMPDU_CUBBY(ampdu, scb);
-	ASSERT(scb_ampdu);
-
-	if (scb_ampdu->mpdu_density == 0)
-		return 0;
-
-	/* RSPEC2RATE is in kbps units ==> ~RSPEC2RATE/2^13 is in bytes/usec
-	   density x is in 2^(x-4) usec
-	   ==> # of bytes needed for req density = rate/2^(17-x)
-	   ==> # of null delimiters = ceil(ceil(rate/2^(17-x)) - phylen)/4)
-	 */
-
-	tx_density = scb_ampdu->mpdu_density;
-
-	ASSERT(tx_density <= AMPDU_MAX_MPDU_DENSITY);
-	tmp = 1 << (17 - tx_density);
-	bytes = CEIL(RSPEC2RATE(rspec), tmp);
-
-	if (bytes > phylen) {
-		cnt = CEIL(bytes - phylen, AMPDU_DELIMITER_LEN);
-		ASSERT(cnt <= 255);
-		return (u8) cnt;
-	} else
-		return 0;
-}
-
 void wlc_ampdu_macaddr_upd(struct wlc_info *wlc)
 {
 	char template[T_RAM_ACCESS_SZ * 2];
@@ -1363,17 +1201,11 @@
 	}
 }
 
-struct cb_del_ampdu_pars {
-	struct ieee80211_sta *sta;
-	u16 tid;
-};
-
 /*
  * callback function that helps flushing ampdu packets from a priority queue
  */
-static bool cb_del_ampdu_pkt(void *p, int arg_a)
+static bool cb_del_ampdu_pkt(struct sk_buff *mpdu, void *arg_a)
 {
-	struct sk_buff *mpdu = (struct sk_buff *)p;
 	struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(mpdu);
 	struct cb_del_ampdu_pars *ampdu_pars =
 				 (struct cb_del_ampdu_pars *)arg_a;
@@ -1406,7 +1238,7 @@
 void wlc_ampdu_flush(struct wlc_info *wlc,
 		     struct ieee80211_sta *sta, u16 tid)
 {
-	struct wlc_txq_info *qi = wlc->active_queue;
+	struct wlc_txq_info *qi = wlc->pkt_queue;
 	struct pktq *pq = &qi->q;
 	int prec;
 	struct cb_del_ampdu_pars ampdu_pars;
@@ -1414,8 +1246,8 @@
 	ampdu_pars.sta = sta;
 	ampdu_pars.tid = tid;
 	for (prec = 0; prec < pq->num_prec; prec++) {
-		pktq_pflush(pq, prec, true, cb_del_ampdu_pkt,
-			    (int)&ampdu_pars);
+		bcm_pktq_pflush(pq, prec, true, cb_del_ampdu_pkt,
+			    (void *)&ampdu_pars);
 	}
 	wlc_inval_dma_pkts(wlc->hw, sta, dma_cb_fn_ampdu);
 }
diff -druN linux-2.6.39-libre/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.h linux-3.0-rc7-libre/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.h
--- linux-2.6.39-libre/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.h	2011-07-11 19:51:52.000000000 -0400
@@ -23,10 +23,7 @@
 			 struct sk_buff **aggp, int prec);
 extern void wlc_ampdu_dotxstatus(struct ampdu_info *ampdu, struct scb *scb,
 				 struct sk_buff *p, tx_status_t *txs);
-extern void wlc_ampdu_reset(struct ampdu_info *ampdu);
 extern void wlc_ampdu_macaddr_upd(struct wlc_info *wlc);
 extern void wlc_ampdu_shm_upd(struct ampdu_info *ampdu);
-extern u8 wlc_ampdu_null_delim_cnt(struct ampdu_info *ampdu, struct scb *scb,
-				      ratespec_t rspec, int phylen);
 
 #endif				/* _wlc_ampdu_h_ */
diff -druN linux-2.6.39-libre/drivers/staging/brcm80211/brcmsmac/wlc_antsel.c linux-3.0-rc7-libre/drivers/staging/brcm80211/brcmsmac/wlc_antsel.c
--- linux-2.6.39-libre/drivers/staging/brcm80211/brcmsmac/wlc_antsel.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/brcm80211/brcmsmac/wlc_antsel.c	2011-07-11 19:51:52.000000000 -0400
@@ -22,7 +22,8 @@
 
 #include <bcmdefs.h>
 #include <bcmutils.h>
-#include <siutils.h>
+#include <bcmnvram.h>
+#include <aiutils.h>
 #include <bcmdevs.h>
 #include <sbhnddma.h>
 #include <wlioctl.h>
@@ -98,8 +99,8 @@
 
 	asi = kzalloc(sizeof(struct antsel_info), GFP_ATOMIC);
 	if (!asi) {
-		WL_ERROR("wl%d: wlc_antsel_attach: out of mem\n",
-			 wlc->pub->unit);
+		wiphy_err(wlc->wiphy, "wl%d: wlc_antsel_attach: out of mem\n",
+			  wlc->pub->unit);
 		return NULL;
 	}
 
@@ -128,8 +129,8 @@
 				asi->antsel_avail = false;
 			} else {
 				asi->antsel_avail = false;
-				WL_ERROR("wlc_antsel_attach: 2o3 board cfg invalid\n");
-				ASSERT(0);
+				wiphy_err(wlc->wiphy, "wlc_antsel_attach: 2o3 "
+					  "board cfg invalid\n");
 			}
 			break;
 		default:
@@ -200,7 +201,7 @@
 	}
 }
 
-void BCMFASTPATH
+void
 wlc_antsel_antcfg_get(struct antsel_info *asi, bool usedef, bool sel,
 		      u8 antselid, u8 fbantselid, u8 *antcfg,
 		      u8 *fbantcfg)
@@ -297,8 +298,6 @@
 	u8 ant_cfg;
 	u16 mimo_antsel;
 
-	ASSERT(asi->antsel_type != ANTSEL_NA);
-
 	/* 1) Update TX antconfig for all frames that are not unicast data
 	 *    (aka default TX)
 	 */
diff -druN linux-2.6.39-libre/drivers/staging/brcm80211/brcmsmac/wlc_bmac.c linux-3.0-rc7-libre/drivers/staging/brcm80211/brcmsmac/wlc_bmac.c
--- linux-2.6.39-libre/drivers/staging/brcm80211/brcmsmac/wlc_bmac.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/brcm80211/brcmsmac/wlc_bmac.c	2011-07-11 19:51:52.000000000 -0400
@@ -25,19 +25,20 @@
 #include <bcmdefs.h>
 #include <bcmdevs.h>
 #include <bcmwifi.h>
-#include <siutils.h>
+#include <aiutils.h>
 #include <bcmsrom.h>
 #include <bcmotp.h>
 #include <bcmutils.h>
+#include <bcmnvram.h>
 #include <wlioctl.h>
 #include <sbconfig.h>
 #include <sbchipc.h>
 #include <pcicfg.h>
 #include <sbhnddma.h>
 #include <hnddma.h>
-#include <hndpmu.h>
 
 #include "wlc_types.h"
+#include "wlc_pmu.h"
 #include "d11.h"
 #include "wlc_cfg.h"
 #include "wlc_rate.h"
@@ -200,6 +201,8 @@
 
 static void WLBANDINITFN(wlc_ucode_bsinit) (struct wlc_hw_info *wlc_hw)
 {
+	struct wiphy *wiphy = wlc_hw->wlc->wiphy;
+
 	/* init microcode host flags */
 	wlc_write_mhf(wlc_hw, wlc_hw->band->mhfs);
 
@@ -208,20 +211,21 @@
 		if (WLCISNPHY(wlc_hw->band)) {
 			wlc_write_inits(wlc_hw, d11n0bsinitvals16);
 		} else {
-			WL_ERROR("%s: wl%d: unsupported phy in corerev %d\n",
-				 __func__, wlc_hw->unit, wlc_hw->corerev);
+			wiphy_err(wiphy, "%s: wl%d: unsupported phy in corerev"
+				  " %d\n", __func__, wlc_hw->unit,
+				  wlc_hw->corerev);
 		}
 	} else {
 		if (D11REV_IS(wlc_hw->corerev, 24)) {
 			if (WLCISLCNPHY(wlc_hw->band)) {
 				wlc_write_inits(wlc_hw, d11lcn0bsinitvals24);
 			} else
-				WL_ERROR("%s: wl%d: unsupported phy in corerev %d\n",
-					 __func__, wlc_hw->unit,
-					 wlc_hw->corerev);
+				wiphy_err(wiphy, "%s: wl%d: unsupported phy in"
+					  " core rev %d\n", __func__,
+					  wlc_hw->unit, wlc_hw->corerev);
 		} else {
-			WL_ERROR("%s: wl%d: unsupported corerev %d\n",
-				 __func__, wlc_hw->unit, wlc_hw->corerev);
+			wiphy_err(wiphy, "%s: wl%d: unsupported corerev %d\n",
+				__func__, wlc_hw->unit, wlc_hw->corerev);
 		}
 	}
 }
@@ -232,12 +236,9 @@
 	struct wlc_hw_info *wlc_hw = wlc->hw;
 	u32 macintmask;
 
-	WL_TRACE("wl%d: wlc_setband_inact\n", wlc_hw->unit);
+	BCMMSG(wlc->wiphy, "wl%d\n", wlc_hw->unit);
 
-	ASSERT(bandunit != wlc_hw->band->bandunit);
-	ASSERT(si_iscoreup(wlc_hw->sih));
-	ASSERT((R_REG(&wlc_hw->regs->maccontrol) & MCTL_EN_MAC) ==
-	       0);
+	WARN_ON((R_REG(&wlc_hw->regs->maccontrol) & MCTL_EN_MAC) != 0);
 
 	/* disable interrupts */
 	macintmask = wl_intrsoff(wlc->wl);
@@ -245,8 +246,6 @@
 	/* radio off */
 	wlc_phy_switch_radio(wlc_hw->band->pi, OFF);
 
-	ASSERT(wlc_hw->clk);
-
 	wlc_bmac_core_phy_clk(wlc_hw, OFF);
 
 	wlc_setxband(wlc_hw, bandunit);
@@ -259,7 +258,7 @@
  * Return true if more frames need to be processed. false otherwise.
  * Param 'bound' indicates max. # frames to process before break out.
  */
-static bool BCMFASTPATH
+static bool
 wlc_bmac_recv(struct wlc_hw_info *wlc_hw, uint fifo, bool bound)
 {
 	struct sk_buff *p;
@@ -267,10 +266,9 @@
 	struct sk_buff *tail = NULL;
 	uint n = 0;
 	uint bound_limit = bound ? wlc_hw->wlc->pub->tunables->rxbnd : -1;
-	u32 tsf_h, tsf_l;
 	wlc_d11rxhdr_t *wlc_rxhdr = NULL;
 
-	WL_TRACE("wl%d: %s\n", wlc_hw->unit, __func__);
+	BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit);
 	/* gather received frames */
 	while ((p = dma_rx(wlc_hw->di[fifo]))) {
 
@@ -286,9 +284,6 @@
 			break;
 	}
 
-	/* get the TSF REG reading */
-	wlc_bmac_read_tsf(wlc_hw, &tsf_l, &tsf_h);
-
 	/* post more rbufs */
 	dma_rxfill(wlc_hw->di[fifo]);
 
@@ -297,9 +292,7 @@
 		head = head->prev;
 		p->prev = NULL;
 
-		/* record the tsf_l in wlc_rxd11hdr */
 		wlc_rxhdr = (wlc_d11rxhdr_t *) p->data;
-		wlc_rxhdr->tsf_l = cpu_to_le32(tsf_l);
 
 		/* compute the RSSI from d11rxhdr and record it in wlc_rxd11hr */
 		wlc_phy_rssi_compute(wlc_hw->band->pi, wlc_rxhdr);
@@ -314,15 +307,17 @@
  *   Return true if another dpc needs to be re-scheduled. false otherwise.
  *   Param 'bounded' indicates if applicable loops should be bounded.
  */
-bool BCMFASTPATH wlc_dpc(struct wlc_info *wlc, bool bounded)
+bool wlc_dpc(struct wlc_info *wlc, bool bounded)
 {
 	u32 macintstatus;
 	struct wlc_hw_info *wlc_hw = wlc->hw;
 	d11regs_t *regs = wlc_hw->regs;
 	bool fatal = false;
+	struct wiphy *wiphy = wlc->wiphy;
 
 	if (DEVICEREMOVED(wlc)) {
-		WL_ERROR("wl%d: %s: dead chip\n", wlc_hw->unit, __func__);
+		wiphy_err(wiphy, "wl%d: %s: dead chip\n", wlc_hw->unit,
+			  __func__);
 		wl_down(wlc->wl);
 		return false;
 	}
@@ -331,13 +326,10 @@
 	macintstatus = wlc->macintstatus;
 	wlc->macintstatus = 0;
 
-	WL_TRACE("wl%d: wlc_dpc: macintstatus 0x%x\n",
-		 wlc_hw->unit, macintstatus);
+	BCMMSG(wlc->wiphy, "wl%d: macintstatus 0x%x\n",
+	       wlc_hw->unit, macintstatus);
 
-	if (macintstatus & MI_PRQ) {
-		/* Process probe request FIFO */
-		ASSERT(0 && "PRQ Interrupt in non-MBSS");
-	}
+	WARN_ON(macintstatus & MI_PRQ); /* PRQ Interrupt in non-MBSS */
 
 	/* BCN template is available */
 	/* ZZZ: Use AP_ACTIVE ? */
@@ -355,7 +347,7 @@
 		if (wlc_bmac_txstatus(wlc->hw, bounded, &fatal))
 			wlc->macintstatus |= MI_TFS;
 		if (fatal) {
-			WL_ERROR("MI_TFS: fatal\n");
+			wiphy_err(wiphy, "MI_TFS: fatal\n");
 			goto fatal;
 		}
 	}
@@ -365,17 +357,11 @@
 
 	/* ATIM window end */
 	if (macintstatus & MI_ATIMWINEND) {
-		WL_TRACE("wlc_isr: end of ATIM window\n");
-
+		BCMMSG(wlc->wiphy, "end of ATIM window\n");
 		OR_REG(&regs->maccommand, wlc->qvalid);
 		wlc->qvalid = 0;
 	}
 
-	/* phy tx error */
-	if (macintstatus & MI_PHYTXERR) {
-		wlc->pub->_cnt->txphyerr++;
-	}
-
 	/* received data or control frame, MI_DMAINT is indication of RX_FIFO interrupt */
 	if (macintstatus & MI_DMAINT) {
 		if (wlc_bmac_recv(wlc_hw, RX_FIFO, bounded)) {
@@ -386,7 +372,7 @@
 	/* TX FIFO suspend/flush completion */
 	if (macintstatus & MI_TXSTOP) {
 		if (wlc_bmac_tx_fifo_suspended(wlc_hw, TX_DATA_FIFO)) {
-			/*      WL_ERROR("dpc: fifo_suspend_comlete\n"); */
+			/* wiphy_err(wiphy, "dpc: fifo_suspend_comlete\n"); */
 		}
 	}
 
@@ -396,15 +382,12 @@
 	}
 
 	if (macintstatus & MI_GP0) {
-		WL_ERROR("wl%d: PSM microcode watchdog fired at %d (seconds). Resetting.\n",
-			 wlc_hw->unit, wlc_hw->now);
+		wiphy_err(wiphy, "wl%d: PSM microcode watchdog fired at %d "
+			"(seconds). Resetting.\n", wlc_hw->unit, wlc_hw->now);
 
 		printk_once("%s : PSM Watchdog, chipid 0x%x, chiprev 0x%x\n",
 					__func__, wlc_hw->sih->chip,
 					wlc_hw->sih->chiprev);
-
-		wlc->pub->_cnt->psmwds++;
-
 		/* big hammer */
 		wl_init(wlc->wl);
 	}
@@ -415,20 +398,14 @@
 	}
 
 	if (macintstatus & MI_RFDISABLE) {
-		WL_TRACE("wl%d: BMAC Detected a change on the RF Disable Input\n", wlc_hw->unit);
-
-		wlc->pub->_cnt->rfdisable++;
+		BCMMSG(wlc->wiphy, "wl%d: BMAC Detected a change on the"
+		       " RF Disable Input\n", wlc_hw->unit);
 		wl_rfkill_set_hw_state(wlc->wl);
 	}
 
 	/* send any enq'd tx packets. Just makes sure to jump start tx */
-	if (!pktq_empty(&wlc->active_queue->q))
-		wlc_send_q(wlc, wlc->active_queue);
-
-	ASSERT(wlc_ps_check(wlc));
-
-	/* make sure the bound indication and the implementation are in sync */
-	ASSERT(bounded == true || wlc->macintstatus == 0);
+	if (!pktq_empty(&wlc->pkt_queue->q))
+		wlc_send_q(wlc);
 
 	/* it isn't done and needs to be resched if macintstatus is non-zero */
 	return wlc->macintstatus != 0;
@@ -444,7 +421,7 @@
 	struct wlc_info *wlc = (struct wlc_info *) arg;
 	struct wlc_hw_info *wlc_hw = wlc->hw;
 
-	WL_TRACE("wl%d: wlc_bmac_watchdog\n", wlc_hw->unit);
+	BCMMSG(wlc->wiphy, "wl%d\n", wlc_hw->unit);
 
 	if (!wlc_hw->up)
 		return;
@@ -467,8 +444,7 @@
 {
 	uint bandunit;
 
-	WL_TRACE("wl%d: wlc_bmac_set_chanspec 0x%x\n",
-		 wlc_hw->unit, chanspec);
+	BCMMSG(wlc_hw->wlc->wiphy, "wl%d: 0x%x\n", wlc_hw->unit, chanspec);
 
 	wlc_hw->chanspec = chanspec;
 
@@ -522,6 +498,7 @@
 	struct wlc_hw_info *wlc_hw = wlc->hw;
 	uint unit = wlc_hw->unit;
 	wlc_tunables_t *tune = wlc->pub->tunables;
+	struct wiphy *wiphy = wlc->wiphy;
 
 	/* name and offsets for dma_attach */
 	snprintf(name, sizeof(name), "wl%d", unit);
@@ -537,8 +514,8 @@
 		    dma_addrwidth(wlc_hw->sih, DMAREG(wlc_hw, DMA_TX, 0));
 
 		if (!wl_alloc_dma_resources(wlc_hw->wlc->wl, addrwidth)) {
-			WL_ERROR("wl%d: wlc_attach: alloc_dma_resources failed\n",
-				 unit);
+			wiphy_err(wiphy, "wl%d: wlc_attach: alloc_dma_"
+				  "resources failed\n", unit);
 			return false;
 		}
 
@@ -547,8 +524,6 @@
 		 * TX: TX_AC_BK_FIFO (TX AC Background data packets)
 		 * RX: RX_FIFO (RX data packets)
 		 */
-		ASSERT(TX_AC_BK_FIFO == 0);
-		ASSERT(RX_FIFO == 0);
 		wlc_hw->di[0] = dma_attach(name, wlc_hw->sih,
 					   (wme ? DMAREG(wlc_hw, DMA_TX, 0) :
 					    NULL), DMAREG(wlc_hw, DMA_RX, 0),
@@ -563,8 +538,6 @@
 		 *   (legacy) TX_DATA_FIFO (TX data packets)
 		 * RX: UNUSED
 		 */
-		ASSERT(TX_AC_BE_FIFO == 1);
-		ASSERT(TX_DATA_FIFO == 1);
 		wlc_hw->di[1] = dma_attach(name, wlc_hw->sih,
 					   DMAREG(wlc_hw, DMA_TX, 1), NULL,
 					   tune->ntxd, 0, 0, -1, 0, 0,
@@ -576,7 +549,6 @@
 		 * TX: TX_AC_VI_FIFO (TX AC Video data packets)
 		 * RX: UNUSED
 		 */
-		ASSERT(TX_AC_VI_FIFO == 2);
 		wlc_hw->di[2] = dma_attach(name, wlc_hw->sih,
 					   DMAREG(wlc_hw, DMA_TX, 2), NULL,
 					   tune->ntxd, 0, 0, -1, 0, 0,
@@ -587,8 +559,6 @@
 		 * TX: TX_AC_VO_FIFO (TX AC Voice data packets)
 		 *   (legacy) TX_CTL_FIFO (TX control & mgmt packets)
 		 */
-		ASSERT(TX_AC_VO_FIFO == 3);
-		ASSERT(TX_CTL_FIFO == 3);
 		wlc_hw->di[3] = dma_attach(name, wlc_hw->sih,
 					   DMAREG(wlc_hw, DMA_TX, 3),
 					   NULL, tune->ntxd, 0, 0, -1,
@@ -597,7 +567,8 @@
 /* Cleaner to leave this as if with AP defined */
 
 		if (dma_attach_err) {
-			WL_ERROR("wl%d: wlc_attach: dma_attach failed\n", unit);
+			wiphy_err(wiphy, "wl%d: wlc_attach: dma_attach failed"
+				  "\n", unit);
 			return false;
 		}
 
@@ -644,11 +615,10 @@
 	uint j;
 	bool wme = false;
 	shared_phy_params_t sha_params;
+	struct wiphy *wiphy = wlc->wiphy;
 
-	WL_TRACE("wl%d: wlc_bmac_attach: vendor 0x%x device 0x%x\n",
-		 unit, vendor, device);
-
-	ASSERT(sizeof(wlc_d11rxhdr_t) <= WL_HWRXOFF);
+	BCMMSG(wlc->wiphy, "wl%d: vendor 0x%x device 0x%x\n", unit, vendor,
+		device);
 
 	wme = true;
 
@@ -666,10 +636,11 @@
 	 * Also initialize software state that depends on the particular hardware
 	 * we are running.
 	 */
-	wlc_hw->sih = si_attach((uint) device, regsva, bustype, btparam,
+	wlc_hw->sih = ai_attach((uint) device, regsva, bustype, btparam,
 				&wlc_hw->vars, &wlc_hw->vars_size);
 	if (wlc_hw->sih == NULL) {
-		WL_ERROR("wl%d: wlc_bmac_attach: si_attach failed\n", unit);
+		wiphy_err(wiphy, "wl%d: wlc_bmac_attach: si_attach failed\n",
+			  unit);
 		err = 11;
 		goto fail;
 	}
@@ -689,21 +660,23 @@
 		var = getvar(vars, "vendid");
 		if (var) {
 			vendor = (u16) simple_strtoul(var, NULL, 0);
-			WL_ERROR("Overriding vendor id = 0x%x\n", vendor);
+			wiphy_err(wiphy, "Overriding vendor id = 0x%x\n",
+				  vendor);
 		}
 		var = getvar(vars, "devid");
 		if (var) {
 			u16 devid = (u16) simple_strtoul(var, NULL, 0);
 			if (devid != 0xffff) {
 				device = devid;
-				WL_ERROR("Overriding device id = 0x%x\n",
-					 device);
+				wiphy_err(wiphy, "Overriding device id = 0x%x"
+					  "\n", device);
 			}
 		}
 
 		/* verify again the device is supported */
 		if (!wlc_chipmatch(vendor, device)) {
-			WL_ERROR("wl%d: wlc_bmac_attach: Unsupported vendor/device (0x%x/0x%x)\n",
+			wiphy_err(wiphy, "wl%d: wlc_bmac_attach: Unsupported "
+				"vendor/device (0x%x/0x%x)\n",
 				 unit, vendor, device);
 			err = 12;
 			goto fail;
@@ -714,8 +687,8 @@
 	wlc_hw->deviceid = device;
 
 	/* set bar0 window to point at D11 core */
-	wlc_hw->regs = (d11regs_t *) si_setcore(wlc_hw->sih, D11_CORE_ID, 0);
-	wlc_hw->corerev = si_corerev(wlc_hw->sih);
+	wlc_hw->regs = (d11regs_t *) ai_setcore(wlc_hw->sih, D11_CORE_ID, 0);
+	wlc_hw->corerev = ai_corerev(wlc_hw->sih);
 
 	regs = wlc_hw->regs;
 
@@ -728,7 +701,7 @@
 	}
 
 	/* initialize power control registers */
-	si_clkctl_init(wlc_hw->sih);
+	ai_clkctl_init(wlc_hw->sih);
 
 	/* request fastclock and force fastclock for the rest of attach
 	 * bring the d11 core out of reset.
@@ -739,8 +712,8 @@
 	wlc_bmac_corereset(wlc_hw, WLC_USE_COREFLAGS);
 
 	if (!wlc_bmac_validate_chip_access(wlc_hw)) {
-		WL_ERROR("wl%d: wlc_bmac_attach: validate_chip_access failed\n",
-			 unit);
+		wiphy_err(wiphy, "wl%d: wlc_bmac_attach: validate_chip_access "
+			"failed\n", unit);
 		err = 14;
 		goto fail;
 	}
@@ -752,7 +725,8 @@
 		j = BOARDREV_PROMOTED;
 	wlc_hw->boardrev = (u16) j;
 	if (!wlc_validboardtype(wlc_hw)) {
-		WL_ERROR("wl%d: wlc_bmac_attach: Unsupported Broadcom board type (0x%x)" " or revision level (0x%x)\n",
+		wiphy_err(wiphy, "wl%d: wlc_bmac_attach: Unsupported Broadcom "
+			"board type (0x%x)" " or revision level (0x%x)\n",
 			 unit, wlc_hw->sih->boardtype, wlc_hw->boardrev);
 		err = 15;
 		goto fail;
@@ -765,7 +739,7 @@
 		wlc_bmac_pllreq(wlc_hw, true, WLC_PLLREQ_SHARED);
 
 	if ((wlc_hw->sih->bustype == PCI_BUS)
-	    && (si_pci_war16165(wlc_hw->sih)))
+	    && (ai_pci_war16165(wlc_hw->sih)))
 		wlc->war16165 = true;
 
 	/* check device id(srom, nvram etc.) to set bands */
@@ -794,8 +768,8 @@
 	wlc_hw->physhim = wlc_phy_shim_attach(wlc_hw, wlc->wl, wlc);
 
 	if (wlc_hw->physhim == NULL) {
-		WL_ERROR("wl%d: wlc_bmac_attach: wlc_phy_shim_attach failed\n",
-			 unit);
+		wiphy_err(wiphy, "wl%d: wlc_bmac_attach: wlc_phy_shim_attach "
+			"failed\n", unit);
 		err = 25;
 		goto fail;
 	}
@@ -844,23 +818,22 @@
 		wlc_hw->band->bandtype = j ? WLC_BAND_5G : WLC_BAND_2G;
 		wlc->band->bandunit = j;
 		wlc->band->bandtype = j ? WLC_BAND_5G : WLC_BAND_2G;
-		wlc->core->coreidx = si_coreidx(wlc_hw->sih);
+		wlc->core->coreidx = ai_coreidx(wlc_hw->sih);
 
 		wlc_hw->machwcap = R_REG(&regs->machwcap);
 		wlc_hw->machwcap_backup = wlc_hw->machwcap;
 
 		/* init tx fifo size */
-		ASSERT((wlc_hw->corerev - XMTFIFOTBL_STARTREV) <
-		       ARRAY_SIZE(xmtfifo_sz));
 		wlc_hw->xmtfifo_sz =
 		    xmtfifo_sz[(wlc_hw->corerev - XMTFIFOTBL_STARTREV)];
 
 		/* Get a phy for this band */
 		wlc_hw->band->pi = wlc_phy_attach(wlc_hw->phy_sh,
-			(void *)regs, wlc_bmac_bandtype(wlc_hw), vars);
+			(void *)regs, wlc_bmac_bandtype(wlc_hw), vars,
+			wlc->wiphy);
 		if (wlc_hw->band->pi == NULL) {
-			WL_ERROR("wl%d: wlc_bmac_attach: wlc_phy_attach failed\n",
-				 unit);
+			wiphy_err(wiphy, "wl%d: wlc_bmac_attach: wlc_phy_"
+				  "attach failed\n", unit);
 			err = 17;
 			goto fail;
 		}
@@ -890,9 +863,9 @@
 				goto bad_phy;
 		} else {
  bad_phy:
-			WL_ERROR("wl%d: wlc_bmac_attach: unsupported phy type/rev (%d/%d)\n",
-				 unit,
-				 wlc_hw->band->phytype, wlc_hw->band->phyrev);
+			wiphy_err(wiphy, "wl%d: wlc_bmac_attach: unsupported "
+				  "phy type/rev (%d/%d)\n", unit,
+				  wlc_hw->band->phytype, wlc_hw->band->phyrev);
 			err = 18;
 			goto fail;
 		}
@@ -925,10 +898,10 @@
 
 	/* Match driver "down" state */
 	if (wlc_hw->sih->bustype == PCI_BUS)
-		si_pci_down(wlc_hw->sih);
+		ai_pci_down(wlc_hw->sih);
 
 	/* register sb interrupt callback functions */
-	si_register_intr_callback(wlc_hw->sih, (void *)wlc_wlintrsoff,
+	ai_register_intr_callback(wlc_hw->sih, (void *)wlc_wlintrsoff,
 				  (void *)wlc_wlintrsrestore, NULL, wlc);
 
 	/* turn off pll and xtal to match driver "down" state */
@@ -947,27 +920,30 @@
 	/* init etheraddr state variables */
 	macaddr = wlc_get_macaddr(wlc_hw);
 	if (macaddr == NULL) {
-		WL_ERROR("wl%d: wlc_bmac_attach: macaddr not found\n", unit);
+		wiphy_err(wiphy, "wl%d: wlc_bmac_attach: macaddr not found\n",
+			  unit);
 		err = 21;
 		goto fail;
 	}
 	bcm_ether_atoe(macaddr, wlc_hw->etheraddr);
 	if (is_broadcast_ether_addr(wlc_hw->etheraddr) ||
 	    is_zero_ether_addr(wlc_hw->etheraddr)) {
-		WL_ERROR("wl%d: wlc_bmac_attach: bad macaddr %s\n",
-			 unit, macaddr);
+		wiphy_err(wiphy, "wl%d: wlc_bmac_attach: bad macaddr %s\n",
+			  unit, macaddr);
 		err = 22;
 		goto fail;
 	}
 
-	WL_TRACE("%s:: deviceid 0x%x nbands %d board 0x%x macaddr: %s\n",
-		 __func__, wlc_hw->deviceid, wlc_hw->_nbands,
+	BCMMSG(wlc->wiphy,
+		 "deviceid 0x%x nbands %d board 0x%x macaddr: %s\n",
+		 wlc_hw->deviceid, wlc_hw->_nbands,
 		 wlc_hw->sih->boardtype, macaddr);
 
 	return err;
 
  fail:
-	WL_ERROR("wl%d: wlc_bmac_attach: failed with err %d\n", unit, err);
+	wiphy_err(wiphy, "wl%d: wlc_bmac_attach: failed with err %d\n", unit,
+		  err);
 	return err;
 }
 
@@ -1011,10 +987,10 @@
 		/* detach interrupt sync mechanism since interrupt is disabled and per-port
 		 * interrupt object may has been freed. this must be done before sb core switch
 		 */
-		si_deregister_intr_callback(wlc_hw->sih);
+		ai_deregister_intr_callback(wlc_hw->sih);
 
 		if (wlc_hw->sih->bustype == PCI_BUS)
-			si_pci_sleep(wlc_hw->sih);
+			ai_pci_sleep(wlc_hw->sih);
 	}
 
 	wlc_bmac_detach_dmapio(wlc_hw);
@@ -1039,7 +1015,7 @@
 	wlc_hw->vars = NULL;
 
 	if (wlc_hw->sih) {
-		si_detach(wlc_hw->sih);
+		ai_detach(wlc_hw->sih);
 		wlc_hw->sih = NULL;
 	}
 
@@ -1049,9 +1025,7 @@
 
 void wlc_bmac_reset(struct wlc_hw_info *wlc_hw)
 {
-	WL_TRACE("wl%d: wlc_bmac_reset\n", wlc_hw->unit);
-
-	wlc_hw->wlc->pub->_cnt->reset++;
+	BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit);
 
 	/* reset the core */
 	if (!DEVICEREMOVED(wlc_hw->wlc))
@@ -1070,7 +1044,7 @@
 	bool fastclk;
 	struct wlc_info *wlc = wlc_hw->wlc;
 
-	WL_TRACE("wl%d: wlc_bmac_init\n", wlc_hw->unit);
+	BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit);
 
 	/* request FAST clock if not on */
 	fastclk = wlc_hw->forcefastclk;
@@ -1119,16 +1093,14 @@
 {
 	uint coremask;
 
-	WL_TRACE("wl%d: %s:\n", wlc_hw->unit, __func__);
-
-	ASSERT(wlc_hw->wlc->pub->hw_up && wlc_hw->wlc->macintmask == 0);
+	BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit);
 
 	/*
 	 * Enable pll and xtal, initialize the power control registers,
 	 * and force fastclock for the remainder of wlc_up().
 	 */
 	wlc_bmac_xtal(wlc_hw, ON);
-	si_clkctl_init(wlc_hw->sih);
+	ai_clkctl_init(wlc_hw->sih);
 	wlc_clkctl_clk(wlc_hw, CLK_FAST);
 
 	/*
@@ -1138,9 +1110,7 @@
 	coremask = (1 << wlc_hw->wlc->core->coreidx);
 
 	if (wlc_hw->sih->bustype == PCI_BUS)
-		si_pci_setup(wlc_hw->sih, coremask);
-
-	ASSERT(si_coreid(wlc_hw->sih) == D11_CORE_ID);
+		ai_pci_setup(wlc_hw->sih, coremask);
 
 	/*
 	 * Need to read the hwradio status here to cover the case where the system
@@ -1149,13 +1119,13 @@
 	if (wlc_bmac_radio_read_hwdisabled(wlc_hw)) {
 		/* put SB PCI in down state again */
 		if (wlc_hw->sih->bustype == PCI_BUS)
-			si_pci_down(wlc_hw->sih);
+			ai_pci_down(wlc_hw->sih);
 		wlc_bmac_xtal(wlc_hw, OFF);
-		return BCME_RADIOOFF;
+		return -ENOMEDIUM;
 	}
 
 	if (wlc_hw->sih->bustype == PCI_BUS)
-		si_pci_up(wlc_hw->sih);
+		ai_pci_up(wlc_hw->sih);
 
 	/* reset the d11 core */
 	wlc_bmac_corereset(wlc_hw, WLC_USE_COREFLAGS);
@@ -1165,14 +1135,13 @@
 
 int wlc_bmac_up_finish(struct wlc_hw_info *wlc_hw)
 {
-	WL_TRACE("wl%d: %s:\n", wlc_hw->unit, __func__);
+	BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit);
 
 	wlc_hw->up = true;
 	wlc_phy_hw_state_upd(wlc_hw->band->pi, true);
 
 	/* FULLY enable dynamic power control and d11 core interrupt */
 	wlc_clkctl_clk(wlc_hw, CLK_DYNAMIC);
-	ASSERT(wlc_hw->wlc->macintmask == 0);
 	wl_intrson(wlc_hw->wlc->wl);
 	return 0;
 }
@@ -1182,7 +1151,7 @@
 	bool dev_gone;
 	uint callbacks = 0;
 
-	WL_TRACE("wl%d: %s:\n", wlc_hw->unit, __func__);
+	BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit);
 
 	if (!wlc_hw->up)
 		return callbacks;
@@ -1210,7 +1179,7 @@
 	uint callbacks = 0;
 	bool dev_gone;
 
-	WL_TRACE("wl%d: %s:\n", wlc_hw->unit, __func__);
+	BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit);
 
 	if (!wlc_hw->up)
 		return callbacks;
@@ -1230,7 +1199,7 @@
 	} else {
 
 		/* Reset and disable the core */
-		if (si_iscoreup(wlc_hw->sih)) {
+		if (ai_iscoreup(wlc_hw->sih)) {
 			if (R_REG(&wlc_hw->regs->maccontrol) &
 			    MCTL_EN_MAC)
 				wlc_suspend_mac_and_wait(wlc_hw->wlc);
@@ -1241,7 +1210,7 @@
 		/* turn off primary xtal and pll */
 		if (!wlc_hw->noreset) {
 			if (wlc_hw->sih->bustype == PCI_BUS)
-				si_pci_down(wlc_hw->sih);
+				ai_pci_down(wlc_hw->sih);
 			wlc_bmac_xtal(wlc_hw, OFF);
 		}
 	}
@@ -1257,8 +1226,6 @@
 	/* wait until ucode is no longer asleep */
 	SPINWAIT((wlc_bmac_read_shm(wlc_hw, M_UCODE_DBGST) ==
 		  DBGST_ASLEEP), wlc_hw->wlc->fastpwrup_dly);
-
-	ASSERT(wlc_bmac_read_shm(wlc_hw, M_UCODE_DBGST) != DBGST_ASLEEP);
 }
 
 void wlc_bmac_hw_etheraddr(struct wlc_hw_info *wlc_hw, u8 *ea)
@@ -1292,9 +1259,9 @@
 					   (&wlc_hw->regs->
 					    clk_ctl_st) & CCS_HTAVAIL) == 0),
 					 PMU_MAX_TRANSITION_DLY);
-				ASSERT(R_REG
-				       (&wlc_hw->regs->
-					clk_ctl_st) & CCS_HTAVAIL);
+				WARN_ON(!(R_REG
+					  (&wlc_hw->regs->
+					   clk_ctl_st) & CCS_HTAVAIL));
 			} else {
 				if ((wlc_hw->sih->pmurev == 0) &&
 				    (R_REG
@@ -1316,11 +1283,12 @@
 		 * then use FCA to verify mac is running fast clock
 		 */
 
-		wlc_hw->forcefastclk = si_clkctl_cc(wlc_hw->sih, mode);
+		wlc_hw->forcefastclk = ai_clkctl_cc(wlc_hw->sih, mode);
 
 		/* check fast clock is available (if core is not in reset) */
 		if (wlc_hw->forcefastclk && wlc_hw->clk)
-			ASSERT(si_core_sflags(wlc_hw->sih, 0, 0) & SISF_FCLKA);
+			WARN_ON(!(ai_core_sflags(wlc_hw->sih, 0, 0) &
+				  SISF_FCLKA));
 
 		/* keep the ucode wake bit on if forcefastclk is on
 		 * since we do not want ucode to put us back to slow clock
@@ -1382,9 +1350,8 @@
 	};
 	struct wlc_hwband *band;
 
-	ASSERT((val & ~mask) == 0);
-	ASSERT(idx < MHFMAX);
-	ASSERT(ARRAY_SIZE(addr) == MHFMAX);
+	if ((val & ~mask) || idx >= MHFMAX)
+		return; /* error condition */
 
 	switch (bands) {
 		/* Current band only or all bands,
@@ -1401,8 +1368,7 @@
 		band = wlc_hw->bandstate[BAND_2G_INDEX];
 		break;
 	default:
-		ASSERT(0);
-		band = NULL;
+		band = NULL;	/* error condition */
 	}
 
 	if (band) {
@@ -1429,8 +1395,9 @@
 u16 wlc_bmac_mhf_get(struct wlc_hw_info *wlc_hw, u8 idx, int bands)
 {
 	struct wlc_hwband *band;
-	ASSERT(idx < MHFMAX);
 
+	if (idx >= MHFMAX)
+		return 0; /* error condition */
 	switch (bands) {
 	case WLC_BAND_AUTO:
 		band = wlc_hw->band;
@@ -1442,8 +1409,7 @@
 		band = wlc_hw->bandstate[BAND_2G_INDEX];
 		break;
 	default:
-		ASSERT(0);
-		band = NULL;
+		band = NULL;		/* error condition */
 	}
 
 	if (!band)
@@ -1460,8 +1426,6 @@
 		M_HOST_FLAGS5
 	};
 
-	ASSERT(ARRAY_SIZE(addr) == MHFMAX);
-
 	for (idx = 0; idx < MHFMAX; idx++) {
 		wlc_bmac_write_shm(wlc_hw, addr[idx], mhfs[idx]);
 	}
@@ -1486,8 +1450,8 @@
 	u32 maccontrol;
 	u32 new_maccontrol;
 
-	ASSERT((val & ~mask) == 0);
-
+	if (val & ~mask)
+		return; /* error condition */
 	maccontrol = wlc_hw->maccontrol;
 	new_maccontrol = (maccontrol & ~mask) | val;
 
@@ -1522,8 +1486,6 @@
 
 void wlc_ucode_wake_override_set(struct wlc_hw_info *wlc_hw, u32 override_bit)
 {
-	ASSERT((wlc_hw->wake_override & override_bit) == 0);
-
 	if (wlc_hw->wake_override || (wlc_hw->maccontrol & MCTL_WAKE)) {
 		mboolset(wlc_hw->wake_override, override_bit);
 		return;
@@ -1539,8 +1501,6 @@
 
 void wlc_ucode_wake_override_clear(struct wlc_hw_info *wlc_hw, u32 override_bit)
 {
-	ASSERT(wlc_hw->wake_override & override_bit);
-
 	mboolclr(wlc_hw->wake_override, override_bit);
 
 	if (wlc_hw->wake_override || (wlc_hw->maccontrol & MCTL_WAKE))
@@ -1591,33 +1551,6 @@
 }
 
 /*
- * Write a MAC address to the rcmta structure
- */
-void
-wlc_bmac_set_rcmta(struct wlc_hw_info *wlc_hw, int idx,
-		   const u8 *addr)
-{
-	d11regs_t *regs = wlc_hw->regs;
-	volatile u16 *objdata16 = (volatile u16 *)&regs->objdata;
-	u32 mac_hm;
-	u16 mac_l;
-
-	WL_TRACE("wl%d: %s\n", wlc_hw->unit, __func__);
-
-	mac_hm =
-	    (addr[3] << 24) | (addr[2] << 16) |
-	    (addr[1] << 8) | addr[0];
-	mac_l = (addr[5] << 8) | addr[4];
-
-	W_REG(&regs->objaddr, (OBJADDR_RCMTA_SEL | (idx * 2)));
-	(void)R_REG(&regs->objaddr);
-	W_REG(&regs->objdata, mac_hm);
-	W_REG(&regs->objaddr, (OBJADDR_RCMTA_SEL | ((idx * 2) + 1)));
-	(void)R_REG(&regs->objaddr);
-	W_REG(objdata16, mac_l);
-}
-
-/*
  * Write a MAC address to the given match reg offset in the RXE match engine.
  */
 void
@@ -1629,9 +1562,8 @@
 	u16 mac_m;
 	u16 mac_h;
 
-	WL_TRACE("wl%d: wlc_bmac_set_addrmatch\n", wlc_hw->unit);
-
-	ASSERT(match_reg_offset < RCM_SIZE);
+	BCMMSG(wlc_hw->wlc->wiphy, "wl%d: wlc_bmac_set_addrmatch\n",
+		 wlc_hw->unit);
 
 	regs = wlc_hw->regs;
 	mac_l = addr[0] | (addr[1] << 8);
@@ -1653,17 +1585,9 @@
 	d11regs_t *regs;
 	u32 word;
 	bool be_bit;
-#ifdef IL_BIGENDIAN
-	volatile u16 *dptr = NULL;
-#endif				/* IL_BIGENDIAN */
-	WL_TRACE("wl%d: wlc_bmac_write_template_ram\n", wlc_hw->unit);
+	BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit);
 
 	regs = wlc_hw->regs;
-
-	ASSERT(IS_ALIGNED(offset, sizeof(u32)));
-	ASSERT(IS_ALIGNED(len, sizeof(u32)));
-	ASSERT((offset & ~0xffff) == 0);
-
 	W_REG(&regs->tplatewrptr, offset);
 
 	/* if MCTL_BIGEND bit set in mac control register,
@@ -1716,8 +1640,6 @@
 
 	wlc_phy_bw_state_set(wlc_hw->band->pi, bw);
 
-	ASSERT(wlc_hw->clk);
-
 	wlc_bmac_phy_reset(wlc_hw);
 	wlc_phy_init(wlc_hw->band->pi, wlc_phy_chanspec_get(wlc_hw->band->pi));
 
@@ -1734,7 +1656,6 @@
 	wlc_bmac_write_template_ram(wlc_hw, T_BCN0_TPL_BASE, (len + 3) & ~3,
 				    bcn);
 	/* write beacon length to SCR */
-	ASSERT(len < 65536);
 	wlc_bmac_write_shm(wlc_hw, M_BCN0_FRM_BYTESZ, (u16) len);
 	/* mark beacon0 valid */
 	OR_REG(&regs->maccommand, MCMD_BCN0VLD);
@@ -1748,7 +1669,6 @@
 	wlc_bmac_write_template_ram(wlc_hw, T_BCN1_TPL_BASE, (len + 3) & ~3,
 				    bcn);
 	/* write beacon length to SCR */
-	ASSERT(len < 65536);
 	wlc_bmac_write_shm(wlc_hw, M_BCN1_FRM_BYTESZ, (u16) len);
 	/* mark beacon1 valid */
 	OR_REG(&regs->maccommand, MCMD_BCN1VLD);
@@ -1772,8 +1692,6 @@
 		else if (!
 			 (R_REG(&regs->maccommand) & MCMD_BCN1VLD))
 			wlc_write_hw_bcntemplate1(wlc_hw, bcn, len);
-		else		/* one template should always have been available */
-			ASSERT(0);
 	}
 }
 
@@ -1800,15 +1718,8 @@
 {
 	struct wlc_hw_info *wlc_hw = wlc->hw;
 
-	WL_TRACE("wl%d: wlc_bmac_bsinit: bandunit %d\n",
-		 wlc_hw->unit, wlc_hw->band->bandunit);
-
-	/* sanity check */
-	if (PHY_TYPE(R_REG(&wlc_hw->regs->phyversion)) !=
-	    PHY_TYPE_LCNXN)
-		ASSERT((uint)
-		       PHY_TYPE(R_REG(&wlc_hw->regs->phyversion))
-		       == wlc_hw->band->phytype);
+	BCMMSG(wlc->wiphy, "wl%d: bandunit %d\n", wlc_hw->unit,
+		wlc_hw->band->bandunit);
 
 	wlc_ucode_bsinit(wlc_hw);
 
@@ -1837,23 +1748,23 @@
 
 static void wlc_bmac_core_phy_clk(struct wlc_hw_info *wlc_hw, bool clk)
 {
-	WL_TRACE("wl%d: wlc_bmac_core_phy_clk: clk %d\n", wlc_hw->unit, clk);
+	BCMMSG(wlc_hw->wlc->wiphy, "wl%d: clk %d\n", wlc_hw->unit, clk);
 
 	wlc_hw->phyclk = clk;
 
 	if (OFF == clk) {	/* clear gmode bit, put phy into reset */
 
-		si_core_cflags(wlc_hw->sih, (SICF_PRST | SICF_FGC | SICF_GMODE),
+		ai_core_cflags(wlc_hw->sih, (SICF_PRST | SICF_FGC | SICF_GMODE),
 			       (SICF_PRST | SICF_FGC));
 		udelay(1);
-		si_core_cflags(wlc_hw->sih, (SICF_PRST | SICF_FGC), SICF_PRST);
+		ai_core_cflags(wlc_hw->sih, (SICF_PRST | SICF_FGC), SICF_PRST);
 		udelay(1);
 
 	} else {		/* take phy out of reset */
 
-		si_core_cflags(wlc_hw->sih, (SICF_PRST | SICF_FGC), SICF_FGC);
+		ai_core_cflags(wlc_hw->sih, (SICF_PRST | SICF_FGC), SICF_FGC);
 		udelay(1);
-		si_core_cflags(wlc_hw->sih, (SICF_FGC), 0);
+		ai_core_cflags(wlc_hw->sih, (SICF_FGC), 0);
 		udelay(1);
 
 	}
@@ -1862,18 +1773,18 @@
 /* Perform a soft reset of the PHY PLL */
 void wlc_bmac_core_phypll_reset(struct wlc_hw_info *wlc_hw)
 {
-	WL_TRACE("wl%d: wlc_bmac_core_phypll_reset\n", wlc_hw->unit);
+	BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit);
 
-	si_corereg(wlc_hw->sih, SI_CC_IDX,
+	ai_corereg(wlc_hw->sih, SI_CC_IDX,
 		   offsetof(chipcregs_t, chipcontrol_addr), ~0, 0);
 	udelay(1);
-	si_corereg(wlc_hw->sih, SI_CC_IDX,
+	ai_corereg(wlc_hw->sih, SI_CC_IDX,
 		   offsetof(chipcregs_t, chipcontrol_data), 0x4, 0);
 	udelay(1);
-	si_corereg(wlc_hw->sih, SI_CC_IDX,
+	ai_corereg(wlc_hw->sih, SI_CC_IDX,
 		   offsetof(chipcregs_t, chipcontrol_data), 0x4, 4);
 	udelay(1);
-	si_corereg(wlc_hw->sih, SI_CC_IDX,
+	ai_corereg(wlc_hw->sih, SI_CC_IDX,
 		   offsetof(chipcregs_t, chipcontrol_data), 0x4, 0);
 	udelay(1);
 }
@@ -1888,18 +1799,18 @@
 		return;
 
 	if (ON == clk)
-		si_core_cflags(wlc_hw->sih, SICF_FGC, SICF_FGC);
+		ai_core_cflags(wlc_hw->sih, SICF_FGC, SICF_FGC);
 	else
-		si_core_cflags(wlc_hw->sih, SICF_FGC, 0);
+		ai_core_cflags(wlc_hw->sih, SICF_FGC, 0);
 
 }
 
 void wlc_bmac_macphyclk_set(struct wlc_hw_info *wlc_hw, bool clk)
 {
 	if (ON == clk)
-		si_core_cflags(wlc_hw->sih, SICF_MPCLKE, SICF_MPCLKE);
+		ai_core_cflags(wlc_hw->sih, SICF_MPCLKE, SICF_MPCLKE);
 	else
-		si_core_cflags(wlc_hw->sih, SICF_MPCLKE, 0);
+		ai_core_cflags(wlc_hw->sih, SICF_MPCLKE, 0);
 }
 
 void wlc_bmac_phy_reset(struct wlc_hw_info *wlc_hw)
@@ -1908,7 +1819,7 @@
 	u32 phy_bw_clkbits;
 	bool phy_in_reset = false;
 
-	WL_TRACE("wl%d: wlc_bmac_phy_reset\n", wlc_hw->unit);
+	BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit);
 
 	if (pih == NULL)
 		return;
@@ -1919,7 +1830,7 @@
 	if (WLCISNPHY(wlc_hw->band) && NREV_GE(wlc_hw->band->phyrev, 3) &&
 	    NREV_LE(wlc_hw->band->phyrev, 4)) {
 		/* Set the PHY bandwidth */
-		si_core_cflags(wlc_hw->sih, SICF_BWMASK, phy_bw_clkbits);
+		ai_core_cflags(wlc_hw->sih, SICF_BWMASK, phy_bw_clkbits);
 
 		udelay(1);
 
@@ -1927,12 +1838,12 @@
 		wlc_bmac_core_phypll_reset(wlc_hw);
 
 		/* reset the PHY */
-		si_core_cflags(wlc_hw->sih, (SICF_PRST | SICF_PCLKE),
+		ai_core_cflags(wlc_hw->sih, (SICF_PRST | SICF_PCLKE),
 			       (SICF_PRST | SICF_PCLKE));
 		phy_in_reset = true;
 	} else {
 
-		si_core_cflags(wlc_hw->sih,
+		ai_core_cflags(wlc_hw->sih,
 			       (SICF_PRST | SICF_PCLKE | SICF_BWMASK),
 			       (SICF_PRST | SICF_PCLKE | phy_bw_clkbits));
 	}
@@ -1951,13 +1862,9 @@
 	struct wlc_info *wlc = wlc_hw->wlc;
 	u32 macintmask;
 
-	ASSERT(NBANDS_HW(wlc_hw) > 1);
-	ASSERT(bandunit != wlc_hw->band->bandunit);
-
 	/* Enable the d11 core before accessing it */
-	if (!si_iscoreup(wlc_hw->sih)) {
-		si_core_reset(wlc_hw->sih, 0, 0);
-		ASSERT(si_iscoreup(wlc_hw->sih));
+	if (!ai_iscoreup(wlc_hw->sih)) {
+		ai_core_reset(wlc_hw->sih, 0, 0);
 		wlc_mctrl_reset(wlc_hw);
 	}
 
@@ -1983,14 +1890,14 @@
 	wl_intrsrestore(wlc->wl, macintmask);
 
 	/* ucode should still be suspended.. */
-	ASSERT((R_REG(&wlc_hw->regs->maccontrol) & MCTL_EN_MAC) ==
-	       0);
+	WARN_ON((R_REG(&wlc_hw->regs->maccontrol) & MCTL_EN_MAC) != 0);
 }
 
 /* low-level band switch utility routine */
 void WLBANDINITFN(wlc_setxband) (struct wlc_hw_info *wlc_hw, uint bandunit)
 {
-	WL_TRACE("wl%d: wlc_setxband: bandunit %d\n", wlc_hw->unit, bandunit);
+	BCMMSG(wlc_hw->wlc->wiphy, "wl%d: bandunit %d\n", wlc_hw->unit,
+		bandunit);
 
 	wlc_hw->band = wlc_hw->bandstate[bandunit];
 
@@ -1999,7 +1906,7 @@
 
 	/* set gmode core flag */
 	if (wlc_hw->sbclk && !wlc_hw->noreset) {
-		si_core_cflags(wlc_hw->sih, SICF_GMODE,
+		ai_core_cflags(wlc_hw->sih, SICF_GMODE,
 			       ((bandunit == 0) ? SICF_GMODE : 0));
 	}
 }
@@ -2009,7 +1916,8 @@
 
 	/* reject unsupported corerev */
 	if (!VALID_COREREV(wlc_hw->corerev)) {
-		WL_ERROR("unsupported core rev %d\n", wlc_hw->corerev);
+		wiphy_err(wlc_hw->wlc->wiphy, "unsupported core rev %d\n",
+			  wlc_hw->corerev);
 		return false;
 	}
 
@@ -2034,7 +1942,7 @@
 			goodboard = false;
 	}
 
-	if (wlc_hw->sih->boardvendor != VENDOR_BROADCOM)
+	if (wlc_hw->sih->boardvendor != PCI_VENDOR_ID_BROADCOM)
 		return goodboard;
 
 	return goodboard;
@@ -2057,8 +1965,8 @@
 
 	macaddr = getvar(wlc_hw->vars, varname);
 	if (macaddr == NULL) {
-		WL_ERROR("wl%d: wlc_get_macaddr: macaddr getvar(%s) not found\n",
-			 wlc_hw->unit, varname);
+		wiphy_err(wlc_hw->wlc->wiphy, "wl%d: wlc_get_macaddr: macaddr "
+			  "getvar(%s) not found\n", wlc_hw->unit, varname);
 	}
 
 	return macaddr;
@@ -2094,9 +2002,9 @@
 		    (wlc_hw->sih->chip == BCM43225_CHIP_ID) ||
 		    (wlc_hw->sih->chip == BCM43421_CHIP_ID))
 			wlc_hw->regs =
-			    (d11regs_t *) si_setcore(wlc_hw->sih, D11_CORE_ID,
+			    (d11regs_t *) ai_setcore(wlc_hw->sih, D11_CORE_ID,
 						     0);
-		si_core_reset(wlc_hw->sih, flags, resetbits);
+		ai_core_reset(wlc_hw->sih, flags, resetbits);
 		wlc_mctrl_reset(wlc_hw);
 	}
 
@@ -2104,7 +2012,7 @@
 
 	/* put core back into reset */
 	if (!clk)
-		si_core_disable(wlc_hw->sih, 0);
+		ai_core_disable(wlc_hw->sih, 0);
 
 	if (!xtal)
 		wlc_bmac_xtal(wlc_hw, OFF);
@@ -2118,25 +2026,25 @@
 	if (wlc_hw->wlc->pub->hw_up)
 		return;
 
-	WL_TRACE("wl%d: %s:\n", wlc_hw->unit, __func__);
+	BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit);
 
 	/*
 	 * Enable pll and xtal, initialize the power control registers,
 	 * and force fastclock for the remainder of wlc_up().
 	 */
 	wlc_bmac_xtal(wlc_hw, ON);
-	si_clkctl_init(wlc_hw->sih);
+	ai_clkctl_init(wlc_hw->sih);
 	wlc_clkctl_clk(wlc_hw, CLK_FAST);
 
 	if (wlc_hw->sih->bustype == PCI_BUS) {
-		si_pci_fixcfg(wlc_hw->sih);
+		ai_pci_fixcfg(wlc_hw->sih);
 
 		/* AI chip doesn't restore bar0win2 on hibernation/resume, need sw fixup */
 		if ((wlc_hw->sih->chip == BCM43224_CHIP_ID) ||
 		    (wlc_hw->sih->chip == BCM43225_CHIP_ID) ||
 		    (wlc_hw->sih->chip == BCM43421_CHIP_ID))
 			wlc_hw->regs =
-			    (d11regs_t *) si_setcore(wlc_hw->sih, D11_CORE_ID,
+			    (d11regs_t *) ai_setcore(wlc_hw->sih, D11_CORE_ID,
 						     0);
 	}
 
@@ -2151,7 +2059,7 @@
 		if (!
 		    (wlc_hw->boardrev >= 0x1250
 		     && (wlc_hw->boardflags & BFL_FEM_BT)))
-			si_epa_4313war(wlc_hw->sih);
+			ai_epa_4313war(wlc_hw->sih);
 	}
 }
 
@@ -2179,7 +2087,7 @@
 	if (flags == WLC_USE_COREFLAGS)
 		flags = (wlc_hw->band->pi ? wlc_hw->band->core_flags : 0);
 
-	WL_TRACE("wl%d: %s\n", wlc_hw->unit, __func__);
+	BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit);
 
 	regs = wlc_hw->regs;
 
@@ -2189,17 +2097,19 @@
 		wlc_clkctl_clk(wlc_hw, CLK_FAST);
 
 	/* reset the dma engines except first time thru */
-	if (si_iscoreup(wlc_hw->sih)) {
+	if (ai_iscoreup(wlc_hw->sih)) {
 		for (i = 0; i < NFIFO; i++)
 			if ((wlc_hw->di[i]) && (!dma_txreset(wlc_hw->di[i]))) {
-				WL_ERROR("wl%d: %s: dma_txreset[%d]: cannot stop dma\n",
-					 wlc_hw->unit, __func__, i);
+				wiphy_err(wlc_hw->wlc->wiphy, "wl%d: %s: "
+					  "dma_txreset[%d]: cannot stop dma\n",
+					   wlc_hw->unit, __func__, i);
 			}
 
 		if ((wlc_hw->di[RX_FIFO])
 		    && (!wlc_dma_rxreset(wlc_hw, RX_FIFO))) {
-			WL_ERROR("wl%d: %s: dma_rxreset[%d]: cannot stop dma\n",
-				 wlc_hw->unit, __func__, RX_FIFO);
+			wiphy_err(wlc_hw->wlc->wiphy, "wl%d: %s: dma_rxreset"
+				  "[%d]: cannot stop dma\n",
+				  wlc_hw->unit, __func__, RX_FIFO);
 		}
 	}
 	/* if noreset, just stop the psm and return */
@@ -2224,7 +2134,7 @@
 	 *  with other driver like mips/arm since they may touch chipcommon as well.
 	 */
 	wlc_hw->clk = false;
-	si_core_reset(wlc_hw->sih, flags, resetbits);
+	ai_core_reset(wlc_hw->sih, flags, resetbits);
 	wlc_hw->clk = true;
 	if (wlc_hw->band && wlc_hw->band->pi)
 		wlc_phy_hw_clk_state_upd(wlc_hw->band->pi, true);
@@ -2315,10 +2225,11 @@
 	bool fifosz_fixup = false;
 	int err = 0;
 	u16 buf[NFIFO];
+	struct wiphy *wiphy = wlc->wiphy;
 
 	regs = wlc_hw->regs;
 
-	WL_TRACE("wl%d: wlc_coreinit\n", wlc_hw->unit);
+	BCMMSG(wlc->wiphy, "wl%d\n", wlc_hw->unit);
 
 	/* reset PSM */
 	wlc_bmac_mctrl(wlc_hw, ~0, (MCTL_IHR_EN | MCTL_PSM_JMP_0 | MCTL_WAKE));
@@ -2338,29 +2249,31 @@
 	SPINWAIT(((R_REG(&regs->macintstatus) & MI_MACSSPNDD) == 0),
 		 1000 * 1000);
 	if ((R_REG(&regs->macintstatus) & MI_MACSSPNDD) == 0)
-		WL_ERROR("wl%d: wlc_coreinit: ucode did not self-suspend!\n",
-			 wlc_hw->unit);
+		wiphy_err(wiphy, "wl%d: wlc_coreinit: ucode did not self-"
+			  "suspend!\n", wlc_hw->unit);
 
 	wlc_gpio_init(wlc);
 
-	sflags = si_core_sflags(wlc_hw->sih, 0, 0);
+	sflags = ai_core_sflags(wlc_hw->sih, 0, 0);
 
 	if (D11REV_IS(wlc_hw->corerev, 23)) {
 		if (WLCISNPHY(wlc_hw->band))
 			wlc_write_inits(wlc_hw, d11n0initvals16);
 		else
-			WL_ERROR("%s: wl%d: unsupported phy in corerev %d\n",
-				 __func__, wlc_hw->unit, wlc_hw->corerev);
+			wiphy_err(wiphy, "%s: wl%d: unsupported phy in corerev"
+				  " %d\n", __func__, wlc_hw->unit,
+				  wlc_hw->corerev);
 	} else if (D11REV_IS(wlc_hw->corerev, 24)) {
 		if (WLCISLCNPHY(wlc_hw->band)) {
 			wlc_write_inits(wlc_hw, d11lcn0initvals24);
 		} else {
-			WL_ERROR("%s: wl%d: unsupported phy in corerev %d\n",
-				 __func__, wlc_hw->unit, wlc_hw->corerev);
+			wiphy_err(wiphy, "%s: wl%d: unsupported phy in corerev"
+				  " %d\n", __func__, wlc_hw->unit,
+				  wlc_hw->corerev);
 		}
 	} else {
-		WL_ERROR("%s: wl%d: unsupported corerev %d\n",
-			 __func__, wlc_hw->unit, wlc_hw->corerev);
+		wiphy_err(wiphy, "%s: wl%d: unsupported corerev %d\n",
+			  __func__, wlc_hw->unit, wlc_hw->corerev);
 	}
 
 	/* For old ucode, txfifo sizes needs to be modified(increased) */
@@ -2402,13 +2315,13 @@
 		err = -1;
 	}
 	if (err != 0) {
-		WL_ERROR("wlc_coreinit: txfifo mismatch: ucode size %d driver size %d index %d\n",
-			 buf[i], wlc_hw->xmtfifo_sz[i], i);
-		ASSERT(0);
+		wiphy_err(wiphy, "wlc_coreinit: txfifo mismatch: ucode size %d"
+			  " driver size %d index %d\n", buf[i],
+			  wlc_hw->xmtfifo_sz[i], i);
 	}
 
 	/* make sure we can still talk to the mac */
-	ASSERT(R_REG(&regs->maccontrol) != 0xffffffff);
+	WARN_ON(R_REG(&regs->maccontrol) == 0xffffffff);
 
 	/* band-specific inits done by wlc_bsinit() */
 
@@ -2437,7 +2350,7 @@
 	wlc_bmac_macphyclk_set(wlc_hw, ON);
 
 	/* program dynamic clock control fast powerup delay register */
-	wlc->fastpwrup_dly = si_clkctl_fast_pwrup_delay(wlc_hw->sih);
+	wlc->fastpwrup_dly = ai_clkctl_fast_pwrup_delay(wlc_hw->sih);
 	W_REG(&regs->scc_fastpwrup_dly, wlc->fastpwrup_dly);
 
 	/* tell the ucode the corerev */
@@ -2554,7 +2467,6 @@
 		wlc_phy_antsel_init(wlc_hw->band->pi, false);
 
 	} else if (wlc_hw->antsel_type == ANTSEL_2x4) {
-		ASSERT((gm & BOARD_GPIO_12) == 0);
 		gm |= gc |= (BOARD_GPIO_12 | BOARD_GPIO_13);
 		/*
 		 * The board itself is powered by these GPIOs
@@ -2581,7 +2493,7 @@
 		gm |= gc |= BOARD_GPIO_PACTRL;
 
 	/* apply to gpiocontrol register */
-	si_gpiocontrol(wlc_hw->sih, gm, gc, GPIO_DRV_PRIORITY);
+	ai_gpiocontrol(wlc_hw->sih, gm, gc, GPIO_DRV_PRIORITY);
 }
 
 static void wlc_ucode_download(struct wlc_hw_info *wlc_hw)
@@ -2598,16 +2510,18 @@
 					bcm43xx_16_mimosz);
 			wlc_hw->ucode_loaded = true;
 		} else
-			WL_ERROR("%s: wl%d: unsupported phy in corerev %d\n",
-				 __func__, wlc_hw->unit, wlc_hw->corerev);
+			wiphy_err(wlc->wiphy, "%s: wl%d: unsupported phy in "
+				  "corerev %d\n",
+				  __func__, wlc_hw->unit, wlc_hw->corerev);
 	} else if (D11REV_IS(wlc_hw->corerev, 24)) {
 		if (WLCISLCNPHY(wlc_hw->band)) {
 			wlc_ucode_write(wlc_hw, bcm43xx_24_lcn,
 					bcm43xx_24_lcnsz);
 			wlc_hw->ucode_loaded = true;
 		} else {
-			WL_ERROR("%s: wl%d: unsupported phy in corerev %d\n",
-				 __func__, wlc_hw->unit, wlc_hw->corerev);
+			wiphy_err(wlc->wiphy, "%s: wl%d: unsupported phy in "
+				  "corerev %d\n",
+				  __func__, wlc_hw->unit, wlc_hw->corerev);
 		}
 	}
 }
@@ -2618,9 +2532,7 @@
 	uint i;
 	uint count;
 
-	WL_TRACE("wl%d: wlc_ucode_write\n", wlc_hw->unit);
-
-	ASSERT(IS_ALIGNED(nbytes, sizeof(u32)));
+	BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit);
 
 	count = (nbytes / sizeof(u32));
 
@@ -2636,13 +2548,11 @@
 	int i;
 	volatile u8 *base;
 
-	WL_TRACE("wl%d: wlc_write_inits\n", wlc_hw->unit);
+	BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit);
 
 	base = (volatile u8 *)wlc_hw->regs;
 
 	for (i = 0; inits[i].addr != 0xffff; i++) {
-		ASSERT((inits[i].size == 2) || (inits[i].size == 4));
-
 		if (inits[i].size == 2)
 			W_REG((u16 *)(base + inits[i].addr),
 			      inits[i].value);
@@ -2700,6 +2610,7 @@
 	uint unit;
 	uint intstatus, idx;
 	d11regs_t *regs = wlc_hw->regs;
+	struct wiphy *wiphy = wlc_hw->wlc->wiphy;
 
 	unit = wlc_hw->unit;
 
@@ -2710,46 +2621,41 @@
 		if (!intstatus)
 			continue;
 
-		WL_TRACE("wl%d: wlc_bmac_fifoerrors: intstatus%d 0x%x\n",
-			 unit, idx, intstatus);
+		BCMMSG(wlc_hw->wlc->wiphy, "wl%d: intstatus%d 0x%x\n",
+			unit, idx, intstatus);
 
 		if (intstatus & I_RO) {
-			WL_ERROR("wl%d: fifo %d: receive fifo overflow\n",
-				 unit, idx);
-			wlc_hw->wlc->pub->_cnt->rxoflo++;
+			wiphy_err(wiphy, "wl%d: fifo %d: receive fifo "
+				  "overflow\n", unit, idx);
 			fatal = true;
 		}
 
 		if (intstatus & I_PC) {
-			WL_ERROR("wl%d: fifo %d: descriptor error\n",
+			wiphy_err(wiphy, "wl%d: fifo %d: descriptor error\n",
 				 unit, idx);
-			wlc_hw->wlc->pub->_cnt->dmade++;
 			fatal = true;
 		}
 
 		if (intstatus & I_PD) {
-			WL_ERROR("wl%d: fifo %d: data error\n", unit, idx);
-			wlc_hw->wlc->pub->_cnt->dmada++;
+			wiphy_err(wiphy, "wl%d: fifo %d: data error\n", unit,
+				  idx);
 			fatal = true;
 		}
 
 		if (intstatus & I_DE) {
-			WL_ERROR("wl%d: fifo %d: descriptor protocol error\n",
-				 unit, idx);
-			wlc_hw->wlc->pub->_cnt->dmape++;
+			wiphy_err(wiphy, "wl%d: fifo %d: descriptor protocol "
+				  "error\n", unit, idx);
 			fatal = true;
 		}
 
 		if (intstatus & I_RU) {
-			WL_ERROR("wl%d: fifo %d: receive descriptor underflow\n",
-				 idx, unit);
-			wlc_hw->wlc->pub->_cnt->rxuflo[idx]++;
+			wiphy_err(wiphy, "wl%d: fifo %d: receive descriptor "
+				  "underflow\n", idx, unit);
 		}
 
 		if (intstatus & I_XU) {
-			WL_ERROR("wl%d: fifo %d: transmit fifo underflow\n",
-				 idx, unit);
-			wlc_hw->wlc->pub->_cnt->txuflo++;
+			wiphy_err(wiphy, "wl%d: fifo %d: transmit fifo "
+				  "underflow\n", idx, unit);
 			fatal = true;
 		}
 
@@ -2765,7 +2671,6 @@
 void wlc_intrson(struct wlc_info *wlc)
 {
 	struct wlc_hw_info *wlc_hw = wlc->hw;
-	ASSERT(wlc->defmacintmask);
 	wlc->macintmask = wlc->defmacintmask;
 	W_REG(&wlc_hw->regs->macintmask, wlc->macintmask);
 }
@@ -2859,7 +2764,7 @@
 int wlc_bmac_xmtfifo_sz_get(struct wlc_hw_info *wlc_hw, uint fifo, uint *blocks)
 {
 	if (fifo >= NFIFO)
-		return BCME_RANGE;
+		return -EINVAL;
 
 	*blocks = wlc_hw->xmtfifo_sz[fifo];
 
@@ -2962,7 +2867,8 @@
 	/* macintstatus includes a DMA interrupt summary bit */
 	macintstatus = R_REG(&regs->macintstatus);
 
-	WL_TRACE("wl%d: macintstatus: 0x%x\n", wlc_hw->unit, macintstatus);
+	BCMMSG(wlc->wiphy, "wl%d: macintstatus: 0x%x\n", wlc_hw->unit,
+		 macintstatus);
 
 	/* detect cardbus removed, in power down(suspend) and in reset */
 	if (DEVICEREMOVED(wlc))
@@ -3013,8 +2919,6 @@
 {
 	u32 macintstatus;
 
-	ASSERT(wlc->macintstatus != 0);
-
 	/* read and clear macintstatus and intstatus registers */
 	macintstatus = wlc_intstatus(wlc, false);
 
@@ -3034,7 +2938,7 @@
  * *wantdpc will be set to true if further wlc_dpc() processing is required,
  * false otherwise.
  */
-bool BCMFASTPATH wlc_isr(struct wlc_info *wlc, bool *wantdpc)
+bool wlc_isr(struct wlc_info *wlc, bool *wantdpc)
 {
 	struct wlc_hw_info *wlc_hw = wlc->hw;
 	u32 macintstatus;
@@ -3048,7 +2952,8 @@
 	macintstatus = wlc_intstatus(wlc, true);
 
 	if (macintstatus == 0xffffffff)
-		WL_ERROR("DEVICEREMOVED detected in the ISR code path\n");
+		wiphy_err(wlc->wiphy, "DEVICEREMOVED detected in the ISR code"
+			  " path\n");
 
 	/* it is not for us */
 	if (macintstatus == 0)
@@ -3057,14 +2962,13 @@
 	*wantdpc = true;
 
 	/* save interrupt status bits */
-	ASSERT(wlc->macintstatus == 0);
 	wlc->macintstatus = macintstatus;
 
 	return true;
 
 }
 
-static bool BCMFASTPATH
+static bool
 wlc_bmac_dotxstatus(struct wlc_hw_info *wlc_hw, tx_status_t *txs, u32 s2)
 {
 	/* discard intermediate indications for ucode with one legitimate case:
@@ -3083,7 +2987,7 @@
 /* process tx completion events in BMAC
  * Return true if more tx status need to be processed. false otherwise.
  */
-static bool BCMFASTPATH
+static bool
 wlc_bmac_txstatus(struct wlc_hw_info *wlc_hw, bool bound, bool *fatal)
 {
 	bool morepending = false;
@@ -3098,7 +3002,7 @@
 	 */
 	uint max_tx_num = bound ? wlc->pub->tunables->txsbnd : -1;
 
-	WL_TRACE("wl%d: wlc_bmac_txstatus\n", wlc_hw->unit);
+	BCMMSG(wlc->wiphy, "wl%d\n", wlc_hw->unit);
 
 	txs = &txstatus;
 	regs = wlc_hw->regs;
@@ -3106,9 +3010,8 @@
 	       && (s1 = R_REG(&regs->frmtxstatus)) & TXS_V) {
 
 		if (s1 == 0xffffffff) {
-			WL_ERROR("wl%d: %s: dead chip\n",
+			wiphy_err(wlc->wiphy, "wl%d: %s: dead chip\n",
 				wlc_hw->unit, __func__);
-			ASSERT(s1 != 0xffffffff);
 			return morepending;
 		}
 
@@ -3133,8 +3036,8 @@
 	if (n >= max_tx_num)
 		morepending = true;
 
-	if (!pktq_empty(&wlc->active_queue->q))
-		wlc_send_q(wlc, wlc->active_queue);
+	if (!pktq_empty(&wlc->pkt_queue->q))
+		wlc_send_q(wlc);
 
 	return morepending;
 }
@@ -3144,9 +3047,10 @@
 	struct wlc_hw_info *wlc_hw = wlc->hw;
 	d11regs_t *regs = wlc_hw->regs;
 	u32 mc, mi;
+	struct wiphy *wiphy = wlc->wiphy;
 
-	WL_TRACE("wl%d: wlc_suspend_mac_and_wait: bandunit %d\n",
-		 wlc_hw->unit, wlc_hw->band->bandunit);
+	BCMMSG(wlc->wiphy, "wl%d: bandunit %d\n", wlc_hw->unit,
+		wlc_hw->band->bandunit);
 
 	/*
 	 * Track overlapping suspend requests
@@ -3161,21 +3065,23 @@
 	mc = R_REG(&regs->maccontrol);
 
 	if (mc == 0xffffffff) {
-		WL_ERROR("wl%d: %s: dead chip\n", wlc_hw->unit, __func__);
+		wiphy_err(wiphy, "wl%d: %s: dead chip\n", wlc_hw->unit,
+			  __func__);
 		wl_down(wlc->wl);
 		return;
 	}
-	ASSERT(!(mc & MCTL_PSM_JMP_0));
-	ASSERT(mc & MCTL_PSM_RUN);
-	ASSERT(mc & MCTL_EN_MAC);
+	WARN_ON(mc & MCTL_PSM_JMP_0);
+	WARN_ON(!(mc & MCTL_PSM_RUN));
+	WARN_ON(!(mc & MCTL_EN_MAC));
 
 	mi = R_REG(&regs->macintstatus);
 	if (mi == 0xffffffff) {
-		WL_ERROR("wl%d: %s: dead chip\n", wlc_hw->unit, __func__);
+		wiphy_err(wiphy, "wl%d: %s: dead chip\n", wlc_hw->unit,
+			  __func__);
 		wl_down(wlc->wl);
 		return;
 	}
-	ASSERT(!(mi & MI_MACSSPNDD));
+	WARN_ON(mi & MI_MACSSPNDD);
 
 	wlc_bmac_mctrl(wlc_hw, MCTL_EN_MAC, 0);
 
@@ -3183,24 +3089,26 @@
 		 WLC_MAX_MAC_SUSPEND);
 
 	if (!(R_REG(&regs->macintstatus) & MI_MACSSPNDD)) {
-		WL_ERROR("wl%d: wlc_suspend_mac_and_wait: waited %d uS and MI_MACSSPNDD is still not on.\n",
-			 wlc_hw->unit, WLC_MAX_MAC_SUSPEND);
-		WL_ERROR("wl%d: psmdebug 0x%08x, phydebug 0x%08x, psm_brc 0x%04x\n",
-			 wlc_hw->unit,
-			 R_REG(&regs->psmdebug),
-			 R_REG(&regs->phydebug),
-			 R_REG(&regs->psm_brc));
+		wiphy_err(wiphy, "wl%d: wlc_suspend_mac_and_wait: waited %d uS"
+			  " and MI_MACSSPNDD is still not on.\n",
+			  wlc_hw->unit, WLC_MAX_MAC_SUSPEND);
+		wiphy_err(wiphy, "wl%d: psmdebug 0x%08x, phydebug 0x%08x, "
+			  "psm_brc 0x%04x\n", wlc_hw->unit,
+			  R_REG(&regs->psmdebug),
+			  R_REG(&regs->phydebug),
+			  R_REG(&regs->psm_brc));
 	}
 
 	mc = R_REG(&regs->maccontrol);
 	if (mc == 0xffffffff) {
-		WL_ERROR("wl%d: %s: dead chip\n", wlc_hw->unit, __func__);
+		wiphy_err(wiphy, "wl%d: %s: dead chip\n", wlc_hw->unit,
+			  __func__);
 		wl_down(wlc->wl);
 		return;
 	}
-	ASSERT(!(mc & MCTL_PSM_JMP_0));
-	ASSERT(mc & MCTL_PSM_RUN);
-	ASSERT(!(mc & MCTL_EN_MAC));
+	WARN_ON(mc & MCTL_PSM_JMP_0);
+	WARN_ON(!(mc & MCTL_PSM_RUN));
+	WARN_ON(mc & MCTL_EN_MAC);
 }
 
 void wlc_enable_mac(struct wlc_info *wlc)
@@ -3209,32 +3117,31 @@
 	d11regs_t *regs = wlc_hw->regs;
 	u32 mc, mi;
 
-	WL_TRACE("wl%d: wlc_enable_mac: bandunit %d\n",
-		 wlc_hw->unit, wlc->band->bandunit);
+	BCMMSG(wlc->wiphy, "wl%d: bandunit %d\n", wlc_hw->unit,
+		wlc->band->bandunit);
 
 	/*
 	 * Track overlapping suspend requests
 	 */
-	ASSERT(wlc_hw->mac_suspend_depth > 0);
 	wlc_hw->mac_suspend_depth--;
 	if (wlc_hw->mac_suspend_depth > 0)
 		return;
 
 	mc = R_REG(&regs->maccontrol);
-	ASSERT(!(mc & MCTL_PSM_JMP_0));
-	ASSERT(!(mc & MCTL_EN_MAC));
-	ASSERT(mc & MCTL_PSM_RUN);
+	WARN_ON(mc & MCTL_PSM_JMP_0);
+	WARN_ON(mc & MCTL_EN_MAC);
+	WARN_ON(!(mc & MCTL_PSM_RUN));
 
 	wlc_bmac_mctrl(wlc_hw, MCTL_EN_MAC, MCTL_EN_MAC);
 	W_REG(&regs->macintstatus, MI_MACSSPNDD);
 
 	mc = R_REG(&regs->maccontrol);
-	ASSERT(!(mc & MCTL_PSM_JMP_0));
-	ASSERT(mc & MCTL_EN_MAC);
-	ASSERT(mc & MCTL_PSM_RUN);
+	WARN_ON(mc & MCTL_PSM_JMP_0);
+	WARN_ON(!(mc & MCTL_EN_MAC));
+	WARN_ON(!(mc & MCTL_PSM_RUN));
 
 	mi = R_REG(&regs->macintstatus);
-	ASSERT(!(mi & MI_MACSSPNDD));
+	WARN_ON(mi & MI_MACSSPNDD);
 
 	wlc_ucode_wake_override_clear(wlc_hw, WLC_WAKE_OVERRIDE_MACSUSPEND);
 }
@@ -3314,7 +3221,7 @@
 		wlc_upd_ofdm_pctl1_table(wlc_hw);
 }
 
-void BCMFASTPATH
+void
 wlc_bmac_read_tsf(struct wlc_hw_info *wlc_hw, u32 *tsf_l_ptr,
 		  u32 *tsf_h_ptr)
 {
@@ -3331,8 +3238,9 @@
 {
 	d11regs_t *regs;
 	u32 w, val;
+	struct wiphy *wiphy = wlc_hw->wlc->wiphy;
 
-	WL_TRACE("wl%d: validate_chip_access\n", wlc_hw->unit);
+	BCMMSG(wiphy, "wl%d\n", wlc_hw->unit);
 
 	regs = wlc_hw->regs;
 
@@ -3351,8 +3259,8 @@
 	(void)R_REG(&regs->objaddr);
 	val = R_REG(&regs->objdata);
 	if (val != (u32) 0xaa5555aa) {
-		WL_ERROR("wl%d: validate_chip_access: SHM = 0x%x, expected 0xaa5555aa\n",
-			 wlc_hw->unit, val);
+		wiphy_err(wiphy, "wl%d: validate_chip_access: SHM = 0x%x, "
+			  "expected 0xaa5555aa\n", wlc_hw->unit, val);
 		return false;
 	}
 
@@ -3364,8 +3272,8 @@
 	(void)R_REG(&regs->objaddr);
 	val = R_REG(&regs->objdata);
 	if (val != (u32) 0x55aaaa55) {
-		WL_ERROR("wl%d: validate_chip_access: SHM = 0x%x, expected 0x55aaaa55\n",
-			 wlc_hw->unit, val);
+		wiphy_err(wiphy, "wl%d: validate_chip_access: SHM = 0x%x, "
+			  "expected 0x55aaaa55\n", wlc_hw->unit, val);
 		return false;
 	}
 
@@ -3379,10 +3287,10 @@
 	w = R_REG(&regs->maccontrol);
 	if ((w != (MCTL_IHR_EN | MCTL_WAKE)) &&
 	    (w != (MCTL_IHR_EN | MCTL_GMODE | MCTL_WAKE))) {
-		WL_ERROR("wl%d: validate_chip_access: maccontrol = 0x%x, expected 0x%x or 0x%x\n",
-			 wlc_hw->unit, w,
-			 (MCTL_IHR_EN | MCTL_WAKE),
-			 (MCTL_IHR_EN | MCTL_GMODE | MCTL_WAKE));
+		wiphy_err(wiphy, "wl%d: validate_chip_access: maccontrol = "
+			  "0x%x, expected 0x%x or 0x%x\n", wlc_hw->unit, w,
+			  (MCTL_IHR_EN | MCTL_WAKE),
+			  (MCTL_IHR_EN | MCTL_GMODE | MCTL_WAKE));
 		return false;
 	}
 
@@ -3396,7 +3304,7 @@
 	d11regs_t *regs;
 	u32 tmp;
 
-	WL_TRACE("wl%d: wlc_bmac_core_phypll_ctl\n", wlc_hw->unit);
+	BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit);
 
 	tmp = 0;
 	regs = wlc_hw->regs;
@@ -3413,9 +3321,8 @@
 			tmp = R_REG(&regs->clk_ctl_st);
 			if ((tmp & (CCS_ERSRC_AVAIL_HT)) !=
 			    (CCS_ERSRC_AVAIL_HT)) {
-				WL_ERROR("%s: turn on PHY PLL failed\n",
-					 __func__);
-				ASSERT(0);
+				wiphy_err(wlc_hw->wlc->wiphy, "%s: turn on PHY"
+					  " PLL failed\n", __func__);
 			}
 		} else {
 			OR_REG(&regs->clk_ctl_st,
@@ -3431,9 +3338,8 @@
 			     (CCS_ERSRC_AVAIL_D11PLL | CCS_ERSRC_AVAIL_PHYPLL))
 			    !=
 			    (CCS_ERSRC_AVAIL_D11PLL | CCS_ERSRC_AVAIL_PHYPLL)) {
-				WL_ERROR("%s: turn on PHY PLL failed\n",
-					 __func__);
-				ASSERT(0);
+				wiphy_err(wlc_hw->wlc->wiphy, "%s: turn on "
+					  "PHY PLL failed\n", __func__);
 			}
 		}
 	} else {
@@ -3449,9 +3355,7 @@
 {
 	bool dev_gone;
 
-	WL_TRACE("wl%d: %s\n", wlc_hw->unit, __func__);
-
-	ASSERT(!wlc_hw->up);
+	BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit);
 
 	dev_gone = DEVICEREMOVED(wlc_hw->wlc);
 
@@ -3477,24 +3381,24 @@
 
 	/* remove gpio controls */
 	if (wlc_hw->ucode_dbgsel)
-		si_gpiocontrol(wlc_hw->sih, ~0, 0, GPIO_DRV_PRIORITY);
+		ai_gpiocontrol(wlc_hw->sih, ~0, 0, GPIO_DRV_PRIORITY);
 
 	wlc_hw->clk = false;
-	si_core_disable(wlc_hw->sih, 0);
+	ai_core_disable(wlc_hw->sih, 0);
 	wlc_phy_hw_clk_state_upd(wlc_hw->band->pi, false);
 }
 
 /* power both the pll and external oscillator on/off */
 static void wlc_bmac_xtal(struct wlc_hw_info *wlc_hw, bool want)
 {
-	WL_TRACE("wl%d: wlc_bmac_xtal: want %d\n", wlc_hw->unit, want);
+	BCMMSG(wlc_hw->wlc->wiphy, "wl%d: want %d\n", wlc_hw->unit, want);
 
 	/* dont power down if plldown is false or we must poll hw radio disable */
 	if (!want && wlc_hw->pllreq)
 		return;
 
 	if (wlc_hw->sih)
-		si_clkctl_xtal(wlc_hw->sih, XTAL | PLL, want);
+		ai_clkctl_xtal(wlc_hw->sih, XTAL | PLL, want);
 
 	wlc_hw->sbclk = want;
 	if (!wlc_hw->sbclk) {
@@ -3516,8 +3420,7 @@
 		if (wlc_hw->di[i]) {
 			dma_txreclaim(wlc_hw->di[i], HNDDMA_RANGE_ALL);
 			TXPKTPENDCLR(wlc, i);
-			WL_TRACE("wlc_flushqueues: pktpend fifo %d cleared\n",
-				 i);
+			BCMMSG(wlc->wiphy, "pktpend fifo %d clrd\n", i);
 		}
 
 	/* free any posted rx packets */
@@ -3534,26 +3437,6 @@
 	wlc_bmac_write_objmem(wlc_hw, offset, v, OBJADDR_SHM_SEL);
 }
 
-/* Set a range of shared memory to a value.
- * SHM 'offset' needs to be an even address and
- * Buffer length 'len' must be an even number of bytes
- */
-void wlc_bmac_set_shm(struct wlc_hw_info *wlc_hw, uint offset, u16 v, int len)
-{
-	int i;
-
-	/* offset and len need to be even */
-	ASSERT((offset & 1) == 0);
-	ASSERT((len & 1) == 0);
-
-	if (len <= 0)
-		return;
-
-	for (i = 0; i < len; i += 2) {
-		wlc_bmac_write_objmem(wlc_hw, offset + i, v, OBJADDR_SHM_SEL);
-	}
-}
-
 static u16
 wlc_bmac_read_objmem(struct wlc_hw_info *wlc_hw, uint offset, u32 sel)
 {
@@ -3562,8 +3445,6 @@
 	volatile u16 *objdata_hi = objdata_lo + 1;
 	u16 v;
 
-	ASSERT((offset & 1) == 0);
-
 	W_REG(&regs->objaddr, sel | (offset >> 2));
 	(void)R_REG(&regs->objaddr);
 	if (offset & 2) {
@@ -3582,8 +3463,6 @@
 	volatile u16 *objdata_lo = (volatile u16 *)&regs->objdata;
 	volatile u16 *objdata_hi = objdata_lo + 1;
 
-	ASSERT((offset & 1) == 0);
-
 	W_REG(&regs->objaddr, sel | (offset >> 2));
 	(void)R_REG(&regs->objaddr);
 	if (offset & 2) {
@@ -3606,11 +3485,7 @@
 	const u8 *p = (const u8 *)buf;
 	int i;
 
-	/* offset and len need to be even */
-	ASSERT((offset & 1) == 0);
-	ASSERT((len & 1) == 0);
-
-	if (len <= 0)
+	if (len <= 0 || (offset & 1) || (len & 1))
 		return;
 
 	for (i = 0; i < len; i += 2) {
@@ -3632,11 +3507,7 @@
 	u8 *p = (u8 *) buf;
 	int i;
 
-	/* offset and len need to be even */
-	ASSERT((offset & 1) == 0);
-	ASSERT((len & 1) == 0);
-
-	if (len <= 0)
+	if (len <= 0 || (offset & 1) || (len & 1))
 		return;
 
 	for (i = 0; i < len; i += 2) {
@@ -3648,8 +3519,8 @@
 
 void wlc_bmac_copyfrom_vars(struct wlc_hw_info *wlc_hw, char **buf, uint *len)
 {
-	WL_TRACE("wlc_bmac_copyfrom_vars, nvram vars totlen=%d\n",
-		 wlc_hw->vars_size);
+	BCMMSG(wlc_hw->wlc->wiphy, "nvram vars totlen=%d\n",
+		wlc_hw->vars_size);
 
 	*buf = wlc_hw->vars;
 	*len = wlc_hw->vars_size;
@@ -3673,15 +3544,8 @@
 	}
 }
 
-void wlc_bmac_set_noreset(struct wlc_hw_info *wlc_hw, bool noreset_flag)
-{
-	wlc_hw->noreset = noreset_flag;
-}
-
 void wlc_bmac_pllreq(struct wlc_hw_info *wlc_hw, bool set, mbool req_bit)
 {
-	ASSERT(req_bit);
-
 	if (set) {
 		if (mboolisset(wlc_hw->pllreq, req_bit))
 			return;
@@ -3709,12 +3573,6 @@
 	return;
 }
 
-/* this will be true for all ai chips */
-bool wlc_bmac_taclear(struct wlc_hw_info *wlc_hw, bool ta_ok)
-{
-	return true;
-}
-
 u16 wlc_bmac_rate_shm_offset(struct wlc_hw_info *wlc_hw, u8 rate)
 {
 	u16 table_ptr;
@@ -3730,7 +3588,7 @@
 	/* for a given rate, the LS-nibble of the PLCP SIGNAL field is
 	 * the index into the rate table.
 	 */
-	phy_rate = rate_info[rate] & RATE_MASK;
+	phy_rate = rate_info[rate] & WLC_RATE_MASK;
 	index = phy_rate & 0xf;
 
 	/* Find the SHM pointer to the rate table entry by looking in the
diff -druN linux-2.6.39-libre/drivers/staging/brcm80211/brcmsmac/wlc_bmac.h linux-3.0-rc7-libre/drivers/staging/brcm80211/brcmsmac/wlc_bmac.h
--- linux-2.6.39-libre/drivers/staging/brcm80211/brcmsmac/wlc_bmac.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/brcm80211/brcmsmac/wlc_bmac.h	2011-07-11 19:51:52.000000000 -0400
@@ -130,8 +130,6 @@
 			      wlc_bmac_state_t *state);
 extern void wlc_bmac_write_shm(struct wlc_hw_info *wlc_hw, uint offset, u16 v);
 extern u16 wlc_bmac_read_shm(struct wlc_hw_info *wlc_hw, uint offset);
-extern void wlc_bmac_set_shm(struct wlc_hw_info *wlc_hw, uint offset, u16 v,
-			     int len);
 extern void wlc_bmac_write_template_ram(struct wlc_hw_info *wlc_hw, int offset,
 					int len, void *buf);
 extern void wlc_bmac_copyfrom_vars(struct wlc_hw_info *wlc_hw, char **buf,
@@ -151,8 +149,6 @@
 extern void wlc_ucode_wake_override_clear(struct wlc_hw_info *wlc_hw,
 					  u32 override_bit);
 
-extern void wlc_bmac_set_rcmta(struct wlc_hw_info *wlc_hw, int idx,
-			       const u8 *addr);
 extern void wlc_bmac_set_addrmatch(struct wlc_hw_info *wlc_hw,
 				   int match_reg_offset,
 				   const u8 *addr);
@@ -163,7 +159,6 @@
 			      u32 *tsf_h_ptr);
 extern void wlc_bmac_set_cwmin(struct wlc_hw_info *wlc_hw, u16 newmin);
 extern void wlc_bmac_set_cwmax(struct wlc_hw_info *wlc_hw, u16 newmax);
-extern void wlc_bmac_set_noreset(struct wlc_hw_info *wlc, bool noreset_flag);
 
 extern void wlc_bmac_retrylimit_upd(struct wlc_hw_info *wlc_hw, u16 SRL,
 				    u16 LRL);
@@ -176,7 +171,6 @@
 extern void wlc_bmac_bw_set(struct wlc_hw_info *wlc_hw, u16 bw);
 extern void wlc_bmac_pllreq(struct wlc_hw_info *wlc_hw, bool set,
 			    mbool req_bit);
-extern bool wlc_bmac_taclear(struct wlc_hw_info *wlc_hw, bool ta_ok);
 extern void wlc_bmac_hw_up(struct wlc_hw_info *wlc_hw);
 extern u16 wlc_bmac_rate_shm_offset(struct wlc_hw_info *wlc_hw, u8 rate);
 extern void wlc_bmac_antsel_set(struct wlc_hw_info *wlc_hw, u32 antsel_avail);
diff -druN linux-2.6.39-libre/drivers/staging/brcm80211/brcmsmac/wlc_bsscfg.h linux-3.0-rc7-libre/drivers/staging/brcm80211/brcmsmac/wlc_bsscfg.h
--- linux-2.6.39-libre/drivers/staging/brcm80211/brcmsmac/wlc_bsscfg.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/brcm80211/brcmsmac/wlc_bsscfg.h	2011-07-11 19:51:52.000000000 -0400
@@ -122,9 +122,6 @@
 #define HWBCN_ENAB(cfg)		(((cfg)->flags & WLC_BSSCFG_HW_BCN) != 0)
 #define HWPRB_ENAB(cfg)		(((cfg)->flags & WLC_BSSCFG_HW_PRB) != 0)
 
-extern void wlc_bsscfg_ID_assign(struct wlc_info *wlc,
-				 struct wlc_bsscfg *bsscfg);
-
 /* Extend N_ENAB to per-BSS */
 #define BSS_N_ENAB(wlc, cfg) \
 	(N_ENAB((wlc)->pub) && !((cfg)->flags & WLC_BSSCFG_11N_DISABLE))
diff -druN linux-2.6.39-libre/drivers/staging/brcm80211/brcmsmac/wlc_channel.c linux-3.0-rc7-libre/drivers/staging/brcm80211/brcmsmac/wlc_channel.c
--- linux-2.6.39-libre/drivers/staging/brcm80211/brcmsmac/wlc_channel.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/brcm80211/brcmsmac/wlc_channel.c	2011-07-11 19:51:52.000000000 -0400
@@ -21,7 +21,8 @@
 
 #include <bcmdefs.h>
 #include <bcmutils.h>
-#include <siutils.h>
+#include <bcmnvram.h>
+#include <aiutils.h>
 #include <sbhnddma.h>
 #include <wlioctl.h>
 
@@ -106,7 +107,8 @@
 								 *txpwr,
 								 u8
 								 local_constraint_qdbm);
-void wlc_locale_add_channels(chanvec_t *target, const chanvec_t *channels);
+static void wlc_locale_add_channels(chanvec_t *target,
+				    const chanvec_t *channels);
 static const locale_mimo_info_t *wlc_get_mimo_2g(u8 locale_idx);
 static const locale_mimo_info_t *wlc_get_mimo_5g(u8 locale_idx);
 
@@ -396,7 +398,8 @@
 	&locale_5g_HIGH4
 };
 
-void wlc_locale_add_channels(chanvec_t *target, const chanvec_t *channels)
+static void wlc_locale_add_channels(chanvec_t *target,
+				    const chanvec_t *channels)
 {
 	u8 i;
 	for (i = 0; i < sizeof(chanvec_t); i++) {
@@ -594,10 +597,7 @@
 static const locale_info_t *wlc_get_locale_2g(u8 locale_idx)
 {
 	if (locale_idx >= ARRAY_SIZE(g_locale_2g_table)) {
-		WL_ERROR("%s: locale 2g index size out of range %d\n",
-			 __func__, locale_idx);
-		ASSERT(locale_idx < ARRAY_SIZE(g_locale_2g_table));
-		return NULL;
+		return NULL; /* error condition */
 	}
 	return g_locale_2g_table[locale_idx];
 }
@@ -605,29 +605,22 @@
 static const locale_info_t *wlc_get_locale_5g(u8 locale_idx)
 {
 	if (locale_idx >= ARRAY_SIZE(g_locale_5g_table)) {
-		WL_ERROR("%s: locale 5g index size out of range %d\n",
-			 __func__, locale_idx);
-		ASSERT(locale_idx < ARRAY_SIZE(g_locale_5g_table));
-		return NULL;
+		return NULL; /* error condition */
 	}
 	return g_locale_5g_table[locale_idx];
 }
 
-const locale_mimo_info_t *wlc_get_mimo_2g(u8 locale_idx)
+static const locale_mimo_info_t *wlc_get_mimo_2g(u8 locale_idx)
 {
 	if (locale_idx >= ARRAY_SIZE(g_mimo_2g_table)) {
-		WL_ERROR("%s: mimo 2g index size out of range %d\n",
-			 __func__, locale_idx);
 		return NULL;
 	}
 	return g_mimo_2g_table[locale_idx];
 }
 
-const locale_mimo_info_t *wlc_get_mimo_5g(u8 locale_idx)
+static const locale_mimo_info_t *wlc_get_mimo_5g(u8 locale_idx)
 {
 	if (locale_idx >= ARRAY_SIZE(g_mimo_5g_table)) {
-		WL_ERROR("%s: mimo 5g index size out of range %d\n",
-			 __func__, locale_idx);
 		return NULL;
 	}
 	return g_mimo_5g_table[locale_idx];
@@ -641,11 +634,12 @@
 	struct wlc_pub *pub = wlc->pub;
 	char *ccode;
 
-	WL_TRACE("wl%d: wlc_channel_mgr_attach\n", wlc->pub->unit);
+	BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit);
 
 	wlc_cm = kzalloc(sizeof(wlc_cm_info_t), GFP_ATOMIC);
 	if (wlc_cm == NULL) {
-		WL_ERROR("wl%d: %s: out of memory", pub->unit, __func__);
+		wiphy_err(wlc->wiphy, "wl%d: %s: out of memory", pub->unit,
+			  __func__);
 		return NULL;
 	}
 	wlc_cm->pub = pub;
@@ -656,9 +650,6 @@
 	ccode = getvar(wlc->pub->vars, "ccode");
 	if (ccode) {
 		strncpy(wlc->pub->srom_ccode, ccode, WLC_CNTRY_BUF_SZ - 1);
-		WL_NONE("%s: SROM country code is %c%c\n",
-			__func__,
-			wlc->pub->srom_ccode[0], wlc->pub->srom_ccode[1]);
 	}
 
 	/* internal country information which must match regulatory constraints in firmware */
@@ -666,8 +657,6 @@
 	strncpy(country_abbrev, "X2", sizeof(country_abbrev) - 1);
 	country = wlc_country_lookup(wlc, country_abbrev);
 
-	ASSERT(country != NULL);
-
 	/* save default country for exiting 11d regulatory mode */
 	strncpy(wlc->country_default, country_abbrev, WLC_CNTRY_BUF_SZ - 1);
 
@@ -708,10 +697,6 @@
 	char mapped_ccode[WLC_CNTRY_BUF_SZ];
 	uint mapped_regrev;
 
-	WL_NONE("%s: (country_abbrev \"%s\", ccode \"%s\", regrev %d) SPROM \"%s\"/%u\n",
-		__func__, country_abbrev, ccode, regrev,
-		wlc_cm->srom_ccode, wlc_cm->srom_regrev);
-
 	/* if regrev is -1, lookup the mapped country code,
 	 * otherwise use the ccode and regrev directly
 	 */
@@ -722,14 +707,13 @@
 					&mapped_regrev);
 	} else {
 		/* find the matching built-in country definition */
-		ASSERT(0);
 		country = wlc_country_lookup_direct(ccode, regrev);
 		strncpy(mapped_ccode, ccode, WLC_CNTRY_BUF_SZ);
 		mapped_regrev = regrev;
 	}
 
 	if (country == NULL)
-		return BCME_BADARG;
+		return -EINVAL;
 
 	/* set the driver state for the country */
 	wlc_set_country_common(wlc_cm, country_abbrev, mapped_ccode,
@@ -752,8 +736,6 @@
 	struct wlc_info *wlc = wlc_cm->wlc;
 	char prev_country_abbrev[WLC_CNTRY_BUF_SZ];
 
-	ASSERT(country != NULL);
-
 	/* save current country state */
 	wlc_cm->country = country;
 
@@ -821,8 +803,8 @@
 
 	/* check for currently supported ccode size */
 	if (strlen(ccode) > (WLC_CNTRY_BUF_SZ - 1)) {
-		WL_ERROR("wl%d: %s: ccode \"%s\" too long for match\n",
-			 wlc->pub->unit, __func__, ccode);
+		wiphy_err(wlc->wiphy, "wl%d: %s: ccode \"%s\" too long for "
+			  "match\n", wlc->pub->unit, __func__, ccode);
 		return NULL;
 	}
 
@@ -837,8 +819,7 @@
 	if (!strcmp(srom_ccode, ccode)) {
 		*mapped_regrev = srom_regrev;
 		mapped = 0;
-		WL_ERROR("srom_code == ccode %s\n", __func__);
-		ASSERT(0);
+		wiphy_err(wlc->wiphy, "srom_code == ccode %s\n", __func__);
 	} else {
 		mapped =
 		    wlc_country_aggregate_map(wlc_cm, ccode, mapped_ccode,
@@ -851,7 +832,6 @@
 	/* if there is not an exact rev match, default to rev zero */
 	if (country == NULL && *mapped_regrev != 0) {
 		*mapped_regrev = 0;
-		ASSERT(0);
 		country =
 		    wlc_country_lookup_direct(mapped_ccode, *mapped_regrev);
 	}
@@ -888,9 +868,6 @@
 			return &cntry_locales[i].country;
 		}
 	}
-
-	WL_ERROR("%s: Returning NULL\n", __func__);
-	ASSERT(0);
 	return NULL;
 }
 
@@ -911,12 +888,10 @@
 		li = BAND_5G(band->bandtype) ?
 		    wlc_get_locale_5g(country->locale_5G) :
 		    wlc_get_locale_2g(country->locale_2G);
-		ASSERT(li);
 		wlc_cm->bandstate[band->bandunit].locale_flags = li->flags;
 		li_mimo = BAND_5G(band->bandtype) ?
 		    wlc_get_mimo_5g(country->locale_mimo_5G) :
 		    wlc_get_mimo_2g(country->locale_mimo_2G);
-		ASSERT(li_mimo);
 
 		/* merge the mimo non-mimo locale flags */
 		wlc_cm->bandstate[band->bandunit].locale_flags |=
@@ -968,9 +943,10 @@
 	if (chan == INVCHANNEL) {
 		/* country/locale with no valid channels, set the radio disable bit */
 		mboolset(wlc->pub->radio_disabled, WL_RADIO_COUNTRY_DISABLE);
-		WL_ERROR("wl%d: %s: no valid channel for \"%s\" nbands %d bandlocked %d\n",
-			 wlc->pub->unit, __func__,
-			 wlc_cm->country_abbrev, NBANDS(wlc), wlc->bandlocked);
+		wiphy_err(wlc->wiphy, "wl%d: %s: no valid channel for \"%s\" "
+			  "nbands %d bandlocked %d\n", wlc->pub->unit,
+			  __func__, wlc_cm->country_abbrev, NBANDS(wlc),
+			  wlc->bandlocked);
 	} else
 	    if (mboolisset(wlc->pub->radio_disabled,
 		WL_RADIO_COUNTRY_DISABLE)) {
@@ -1520,10 +1496,9 @@
 	u8 channel = CHSPEC_CHANNEL(chspec);
 
 	/* check the chanspec */
-	if (wf_chspec_malformed(chspec)) {
-		WL_ERROR("wl%d: malformed chanspec 0x%x\n",
-			 wlc->pub->unit, chspec);
-		ASSERT(0);
+	if (bcm_chspec_malformed(chspec)) {
+		wiphy_err(wlc->wiphy, "wl%d: malformed chanspec 0x%x\n",
+			wlc->pub->unit, chspec);
 		return false;
 	}
 
diff -druN linux-2.6.39-libre/drivers/staging/brcm80211/brcmsmac/wlc_key.h linux-3.0-rc7-libre/drivers/staging/brcm80211/brcmsmac/wlc_key.h
--- linux-2.6.39-libre/drivers/staging/brcm80211/brcmsmac/wlc_key.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/brcm80211/brcmsmac/wlc_key.h	2011-07-11 19:51:52.000000000 -0400
@@ -115,7 +115,7 @@
 #define WSEC_IBSS_PEER_GROUP_KEY	(1 << 7)	/* Flag: group key for a IBSS PEER */
 #define WSEC_ICV_ERROR		(1 << 8)	/* Provoke deliberate ICV error */
 
-#define wlc_key_insert(a, b, c, d, e, f, g, h, i, j) (BCME_ERROR)
+#define wlc_key_insert(a, b, c, d, e, f, g, h, i, j) (-EBADE)
 #define wlc_key_update(a, b, c) do {} while (0)
 #define wlc_key_remove(a, b, c) do {} while (0)
 #define wlc_key_remove_all(a, b) do {} while (0)
@@ -126,12 +126,12 @@
 #define wlc_key_hw_init(a, b, c)  do {} while (0)
 #define wlc_key_hw_wowl_init(a, b, c, d) do {} while (0)
 #define wlc_key_sw_wowl_update(a, b, c, d, e) do {} while (0)
-#define wlc_key_sw_wowl_create(a, b, c) (BCME_ERROR)
+#define wlc_key_sw_wowl_create(a, b, c) (-EBADE)
 #define wlc_key_iv_update(a, b, c, d, e) do {(void)e; } while (0)
 #define wlc_key_iv_init(a, b, c) do {} while (0)
-#define wlc_key_set_error(a, b, c) (BCME_ERROR)
-#define wlc_key_dump_hw(a, b) (BCME_ERROR)
-#define wlc_key_dump_sw(a, b) (BCME_ERROR)
+#define wlc_key_set_error(a, b, c) (-EBADE)
+#define wlc_key_dump_hw(a, b) (-EBADE)
+#define wlc_key_dump_sw(a, b) (-EBADE)
 #define wlc_key_defkeyflag(a) (0)
 #define wlc_rcmta_add_bssid(a, b) do {} while (0)
 #define wlc_rcmta_del_bssid(a, b) do {} while (0)
diff -druN linux-2.6.39-libre/drivers/staging/brcm80211/brcmsmac/wlc_main.c linux-3.0-rc7-libre/drivers/staging/brcm80211/brcmsmac/wlc_main.c
--- linux-2.6.39-libre/drivers/staging/brcm80211/brcmsmac/wlc_main.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/brcm80211/brcmsmac/wlc_main.c	2011-07-11 19:51:52.000000000 -0400
@@ -16,20 +16,22 @@
 #include <linux/kernel.h>
 #include <linux/ctype.h>
 #include <linux/etherdevice.h>
+#include <linux/pci_ids.h>
 #include <net/mac80211.h>
 
 #include <bcmdefs.h>
 #include <bcmdevs.h>
 #include <bcmutils.h>
 #include <bcmwifi.h>
-#include <siutils.h>
+#include <bcmnvram.h>
+#include <aiutils.h>
 #include <pcicfg.h>
 #include <bcmsrom.h>
 #include <wlioctl.h>
 #include <sbhnddma.h>
 #include <hnddma.h>
-#include <hndpmu.h>
 
+#include "wlc_pmu.h"
 #include "d11.h"
 #include "wlc_types.h"
 #include "wlc_cfg.h"
@@ -51,12 +53,7 @@
 #include "wlc_alloc.h"
 #include "wl_dbg.h"
 
-/*
- *	Disable statistics counting for WME
- */
-#define WLCNTSET(a, b)
-#define WLCNTINCR(a)
-#define WLCNTADD(a, b)
+#include "wl_mac80211.h"
 
 /*
  * WPA(2) definitions
@@ -242,7 +239,7 @@
 #define WLC_REPLAY_CNTRS_VALUE	WPA_CAP_16_REPLAY_CNTRS
 
 /* local prototypes */
-static u16 BCMFASTPATH wlc_d11hdrs_mac80211(struct wlc_info *wlc,
+static u16 wlc_d11hdrs_mac80211(struct wlc_info *wlc,
 					       struct ieee80211_hw *hw,
 					       struct sk_buff *p,
 					       struct scb *scb, uint frag,
@@ -250,8 +247,6 @@
 					       uint next_frag_len,
 					       wsec_key_t *key,
 					       ratespec_t rspec_override);
-
-static void wlc_ctrupd_cache(u16 cur_stat, u16 *macstat_snapshot, u32 *macstat);
 static void wlc_bss_default_init(struct wlc_info *wlc);
 static void wlc_ucode_mac_upd(struct wlc_info *wlc);
 static ratespec_t mac80211_wlc_set_nrate(struct wlc_info *wlc,
@@ -273,13 +268,13 @@
 				     struct wlc_txq_info *qi,
 				     bool on, int prio);
 static void wlc_txflowcontrol_reset(struct wlc_info *wlc);
-static u16 wlc_compute_airtime(struct wlc_info *wlc, ratespec_t rspec,
-				  uint length);
-static void wlc_compute_cck_plcp(ratespec_t rate, uint length, u8 *plcp);
+static void wlc_compute_cck_plcp(struct wlc_info *wlc, ratespec_t rate,
+				 uint length, u8 *plcp);
 static void wlc_compute_ofdm_plcp(ratespec_t rate, uint length, u8 *plcp);
 static void wlc_compute_mimo_plcp(ratespec_t rate, uint length, u8 *plcp);
 static u16 wlc_compute_frame_dur(struct wlc_info *wlc, ratespec_t rate,
 				    u8 preamble_type, uint next_frag_len);
+static u64 wlc_recover_tsf64(struct wlc_info *wlc, struct wlc_d11rxhdr *rxh);
 static void wlc_recvctl(struct wlc_info *wlc,
 			d11rxhdr_t *rxh, struct sk_buff *p);
 static uint wlc_calc_frame_len(struct wlc_info *wlc, ratespec_t rate,
@@ -320,35 +315,6 @@
 static int _wlc_ioctl(struct wlc_info *wlc, int cmd, void *arg, int len,
 		      struct wlc_if *wlcif);
 
-#if defined(BCMDBG)
-void wlc_get_rcmta(struct wlc_info *wlc, int idx, u8 *addr)
-{
-	d11regs_t *regs = wlc->regs;
-	u32 v32;
-
-	WL_TRACE("wl%d: %s\n", WLCWLUNIT(wlc), __func__);
-
-	W_REG(&regs->objaddr, (OBJADDR_RCMTA_SEL | (idx * 2)));
-	(void)R_REG(&regs->objaddr);
-	v32 = R_REG(&regs->objdata);
-	addr[0] = (u8) v32;
-	addr[1] = (u8) (v32 >> 8);
-	addr[2] = (u8) (v32 >> 16);
-	addr[3] = (u8) (v32 >> 24);
-	W_REG(&regs->objaddr, (OBJADDR_RCMTA_SEL | ((idx * 2) + 1)));
-	(void)R_REG(&regs->objaddr);
-	v32 = R_REG(&regs->objdata);
-	addr[4] = (u8) v32;
-	addr[5] = (u8) (v32 >> 8);
-}
-#endif				/* defined(BCMDBG) */
-
-/* keep the chip awake if needed */
-bool wlc_stay_awake(struct wlc_info *wlc)
-{
-	return true;
-}
-
 /* conditions under which the PM bit should be set in outgoing frames and STAY_AWAKE is meaningful
  */
 bool wlc_ps_allowed(struct wlc_info *wlc)
@@ -380,7 +346,7 @@
 
 void wlc_reset(struct wlc_info *wlc)
 {
-	WL_TRACE("wl%d: wlc_reset\n", wlc->pub->unit);
+	BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit);
 
 	wlc->check_for_unaligned_tbtt = false;
 
@@ -392,14 +358,14 @@
 		sizeof(macstat_t));
 
 	wlc_bmac_reset(wlc->hw);
-	wlc_ampdu_reset(wlc->ampdu);
 	wlc->txretried = 0;
 
 }
 
 void wlc_fatal_error(struct wlc_info *wlc)
 {
-	WL_ERROR("wl%d: fatal error, reinitializing\n", wlc->pub->unit);
+	wiphy_err(wlc->wiphy, "wl%d: fatal error, reinitializing\n",
+		  wlc->pub->unit);
 	wl_init(wlc->wl);
 }
 
@@ -414,11 +380,6 @@
 	    1 | WL_CHANSPEC_BW_20 | WL_CHANSPEC_CTL_SB_NONE |
 	    WL_CHANSPEC_BAND_2G;
 
-	/* make sure the channel is on the supported band if we are band-restricted */
-	if (wlc->bandlocked || NBANDS(wlc) == 1) {
-		ASSERT(CHSPEC_WLCBANDUNIT(chanspec) == wlc->band->bandunit);
-	}
-	ASSERT(wlc_valid_chanspec_db(wlc->cmi, chanspec));
 	return chanspec;
 }
 
@@ -440,7 +401,7 @@
 	struct wlc_bsscfg *bsscfg;
 	bool mute = false;
 
-	WL_TRACE("wl%d: wlc_init\n", wlc->pub->unit);
+	BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit);
 
 	regs = wlc->regs;
 
@@ -463,7 +424,6 @@
 	wlc_bcn_li_upd(wlc);
 	wlc->bcn_wait_prd =
 	    (u8) (wlc_bmac_read_shm(wlc->hw, M_NOSLPZNATDTIM) >> 10);
-	ASSERT(wlc->bcn_wait_prd > 0);
 
 	/* the world is new again, so is our reported rate */
 	wlc_reprate_init(wlc);
@@ -524,7 +484,7 @@
 	/* Enable EDCF mode (while the MAC is suspended) */
 	if (EDCF_ENAB(wlc->pub)) {
 		OR_REG(&regs->ifs_ctl, IFS_USEEDCF);
-		wlc_edcf_setparams(wlc->cfg, false);
+		wlc_edcf_setparams(wlc, false);
 	}
 
 	/* Init precedence maps for empty FIFOs */
@@ -559,7 +519,6 @@
 	if (WLC_WME_RETRY_SHORT_GET(wlc, 0) == 0) {	/* Uninitialized; read from HW */
 		int ac;
 
-		ASSERT(wlc->clk);
 		for (ac = 0; ac < AC_COUNT; ac++) {
 			wlc->wme_retries[ac] =
 			    wlc_read_shm(wlc, M_AC_TXLMT_ADDR(ac));
@@ -604,82 +563,27 @@
 	wlc_mctrl(wlc, MCTL_PROMISC | MCTL_KEEPCONTROL, promisc_bits);
 }
 
-/* check if hps and wake states of sw and hw are in sync */
-bool wlc_ps_check(struct wlc_info *wlc)
-{
-	bool res = true;
-	bool hps, wake;
-	bool wake_ok;
-
-	if (!AP_ACTIVE(wlc)) {
-		u32 tmp;
-		tmp = R_REG(&wlc->regs->maccontrol);
-
-		/*
-		 * If deviceremoved is detected, then don't take any action as
-		 * this can be called in any context. Assume that caller will
-		 * take care of the condition. This is just to avoid assert
-		 */
-		if (tmp == 0xffffffff) {
-			WL_ERROR("wl%d: %s: dead chip\n",
-				 wlc->pub->unit, __func__);
-			return DEVICEREMOVED(wlc);
-		}
-
-		hps = PS_ALLOWED(wlc);
-
-		if (hps != ((tmp & MCTL_HPS) != 0)) {
-			int idx;
-			struct wlc_bsscfg *cfg;
-			WL_ERROR("wl%d: hps not sync, sw %d, maccontrol 0x%x\n",
-				 wlc->pub->unit, hps, tmp);
-			FOREACH_BSS(wlc, idx, cfg) {
-				if (!BSSCFG_STA(cfg))
-					continue;
-			}
-
-			res = false;
-		}
-		/* For a monolithic build the wake check can be exact since it looks at wake
-		 * override bits. The MCTL_WAKE bit should match the 'wake' value.
-		 */
-		wake = STAY_AWAKE(wlc) || wlc->hw->wake_override;
-		wake_ok = (wake == ((tmp & MCTL_WAKE) != 0));
-		if (hps && !wake_ok) {
-			WL_ERROR("wl%d: wake not sync, sw %d maccontrol 0x%x\n",
-				 wlc->pub->unit, wake, tmp);
-			res = false;
-		}
-	}
-	ASSERT(res);
-	return res;
-}
-
 /* push sw hps and wake state through hardware */
 void wlc_set_ps_ctrl(struct wlc_info *wlc)
 {
 	u32 v1, v2;
-	bool hps, wake;
+	bool hps;
 	bool awake_before;
 
 	hps = PS_ALLOWED(wlc);
-	wake = hps ? (STAY_AWAKE(wlc)) : true;
 
-	WL_TRACE("wl%d: wlc_set_ps_ctrl: hps %d wake %d\n",
-		 wlc->pub->unit, hps, wake);
+	BCMMSG(wlc->wiphy, "wl%d: hps %d\n", wlc->pub->unit, hps);
 
 	v1 = R_REG(&wlc->regs->maccontrol);
-	v2 = 0;
+	v2 = MCTL_WAKE;
 	if (hps)
 		v2 |= MCTL_HPS;
-	if (wake)
-		v2 |= MCTL_WAKE;
 
 	wlc_mctrl(wlc, MCTL_WAKE | MCTL_HPS, v2);
 
 	awake_before = ((v1 & MCTL_WAKE) || ((v1 & MCTL_HPS) == 0));
 
-	if (wake && !awake_before)
+	if (!awake_before)
 		wlc_bmac_wait_for_wake(wlc->hw);
 
 }
@@ -730,8 +634,6 @@
 	int idx;
 	struct wlc_bsscfg *cfg;
 
-	ASSERT(wlc->band->gmode);
-
 	/* use the override if it is set */
 	if (wlc->shortslot_override != WLC_SHORTSLOT_AUTO)
 		shortslot = (wlc->shortslot_override == WLC_SHORTSLOT_ON);
@@ -762,8 +664,8 @@
 
 	local = WLC_TXPWR_MAX;
 	if (wlc->pub->associated &&
-	    (wf_chspec_ctlchan(wlc->chanspec) ==
-	     wf_chspec_ctlchan(wlc->home_chanspec))) {
+	    (bcm_chspec_ctlchan(wlc->chanspec) ==
+	     bcm_chspec_ctlchan(wlc->home_chanspec))) {
 
 		/* get the local power constraint if we are on the AP's
 		 * channel [802.11h, 7.3.2.13]
@@ -826,9 +728,8 @@
 	chanspec_t old_chanspec = wlc->chanspec;
 
 	if (!wlc_valid_chanspec_db(wlc->cmi, chanspec)) {
-		WL_ERROR("wl%d: %s: Bad channel %d\n",
-			 wlc->pub->unit, __func__, CHSPEC_CHANNEL(chanspec));
-		ASSERT(wlc_valid_chanspec_db(wlc->cmi, chanspec));
+		wiphy_err(wlc->wiphy, "wl%d: %s: Bad channel %d\n",
+			  wlc->pub->unit, __func__, CHSPEC_CHANNEL(chanspec));
 		return;
 	}
 
@@ -838,9 +739,10 @@
 		if (wlc->band->bandunit != bandunit || wlc->bandinit_pending) {
 			switchband = true;
 			if (wlc->bandlocked) {
-				WL_ERROR("wl%d: %s: chspec %d band is locked!\n",
-					 wlc->pub->unit, __func__,
-					 CHSPEC_CHANNEL(chanspec));
+				wiphy_err(wlc->wiphy, "wl%d: %s: chspec %d "
+					  "band is locked!\n",
+					  wlc->pub->unit, __func__,
+					  CHSPEC_CHANNEL(chanspec));
 				return;
 			}
 			/* BMAC_NOTE: should the setband call come after the wlc_bmac_chanspec() ?
@@ -852,8 +754,6 @@
 		}
 	}
 
-	ASSERT(N_ENAB(wlc->pub) || !CHSPEC_IS40(chanspec));
-
 	/* sync up phy/radio chanspec */
 	wlc_set_phy_chanspec(wlc, chanspec);
 
@@ -887,7 +787,7 @@
 	if (len == sizeof(tx_power_legacy_t))
 		old_power = (tx_power_legacy_t *) pwr;
 	else if (len < sizeof(tx_power_t))
-		return BCME_BUFTOOSHORT;
+		return -EOVERFLOW;
 
 	memset(&power, 0, sizeof(tx_power_t));
 
@@ -1098,10 +998,10 @@
 	uint i;
 
 	/* Use the lowest basic rate */
-	lowest_basic_rspec = rs->rates[0] & RATE_MASK;
+	lowest_basic_rspec = rs->rates[0] & WLC_RATE_MASK;
 	for (i = 0; i < rs->count; i++) {
 		if (rs->rates[i] & WLC_RATE_FLAG) {
-			lowest_basic_rspec = rs->rates[i] & RATE_MASK;
+			lowest_basic_rspec = rs->rates[i] & WLC_RATE_MASK;
 			break;
 		}
 	}
@@ -1141,7 +1041,7 @@
 */
 void wlc_protection_upd(struct wlc_info *wlc, uint idx, int val)
 {
-	WL_TRACE("wlc_protection_upd: idx %d, val %d\n", idx, val);
+	BCMMSG(wlc->wiphy, "idx %d, val %d\n", idx, val);
 
 	switch (idx) {
 	case WLC_PROT_G_SPEC:
@@ -1179,7 +1079,6 @@
 		break;
 
 	default:
-		ASSERT(0);
 		break;
 	}
 
@@ -1252,14 +1151,12 @@
 	uint parkband;
 	uint i, band_order[2];
 
-	WL_TRACE("wl%d: wlc_bandinit_ordered\n", wlc->pub->unit);
+	BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit);
 	/*
 	 * We might have been bandlocked during down and the chip power-cycled (hibernate).
 	 * figure out the right band to park on
 	 */
 	if (wlc->bandlocked || NBANDS(wlc) == 1) {
-		ASSERT(CHSPEC_WLCBANDUNIT(chanspec) == wlc->band->bandunit);
-
 		parkband = wlc->band->bandunit;	/* updated in wlc_bandlock() */
 		band_order[0] = band_order[1] = parkband;
 	} else {
@@ -1281,7 +1178,7 @@
 
 		/* fill in hw_rate */
 		wlc_rateset_filter(&default_rateset, &wlc->band->hw_rateset,
-				   false, WLC_RATES_CCK_OFDM, RATE_MASK,
+				   false, WLC_RATES_CCK_OFDM, WLC_RATE_MASK,
 				   (bool) N_ENAB(wlc->pub));
 
 		/* init basic rate lookup */
@@ -1295,7 +1192,7 @@
 /* band-specific init */
 static void WLBANDINITFN(wlc_bsinit) (struct wlc_info *wlc)
 {
-	WL_TRACE("wl%d: wlc_bsinit: bandunit %d\n",
+	BCMMSG(wlc->wiphy, "wl%d: bandunit %d\n",
 		 wlc->pub->unit, wlc->band->bandunit);
 
 	/* write ucode ACK/CTS rate table */
@@ -1315,10 +1212,6 @@
 	int idx;
 	struct wlc_bsscfg *cfg;
 
-	ASSERT(NBANDS(wlc) > 1);
-	ASSERT(!wlc->bandlocked);
-	ASSERT(bandunit != wlc->band->bandunit || wlc->bandinit_pending);
-
 	wlc->band = wlc->bandstate[bandunit];
 
 	if (!wlc->pub->up)
@@ -1355,41 +1248,28 @@
 		  cpu_to_le16(EDCF_AC_VO_TXOP_STA)}
 		 }
 	};
-
-	ASSERT(sizeof(*pe) == WME_PARAM_IE_LEN);
 	memcpy(pe, &stadef, sizeof(*pe));
 }
 
-void wlc_wme_setparams(struct wlc_info *wlc, u16 aci, void *arg, bool suspend)
+void wlc_wme_setparams(struct wlc_info *wlc, u16 aci,
+		       const struct ieee80211_tx_queue_params *params,
+		       bool suspend)
 {
 	int i;
 	shm_acparams_t acp_shm;
 	u16 *shm_entry;
-	struct ieee80211_tx_queue_params *params = arg;
-
-	ASSERT(wlc);
 
 	/* Only apply params if the core is out of reset and has clocks */
 	if (!wlc->clk) {
-		WL_ERROR("wl%d: %s : no-clock\n", wlc->pub->unit, __func__);
+		wiphy_err(wlc->wiphy, "wl%d: %s : no-clock\n", wlc->pub->unit,
+			  __func__);
 		return;
 	}
 
-	/*
-	 * AP uses AC params from wme_param_ie_ap.
-	 * AP advertises AC params from wme_param_ie.
-	 * STA uses AC params from wme_param_ie.
-	 */
-
 	wlc->wme_admctl = 0;
 
 	do {
 		memset((char *)&acp_shm, 0, sizeof(shm_acparams_t));
-		/* find out which ac this set of params applies to */
-		ASSERT(aci < AC_COUNT);
-		/* set the admission control policy for this AC */
-		/* wlc->wme_admctl |= 1 << aci; *//* should be set ??  seems like off by default */
-
 		/* fill in shm ac params struct */
 		acp_shm.txop = le16_to_cpu(params->txop);
 		/* convert from units of 32us to us for ucode */
@@ -1403,8 +1283,8 @@
 
 		if (acp_shm.aifs < EDCF_AIFSN_MIN
 		    || acp_shm.aifs > EDCF_AIFSN_MAX) {
-			WL_ERROR("wl%d: wlc_edcf_setparams: bad aifs %d\n",
-				 wlc->pub->unit, acp_shm.aifs);
+			wiphy_err(wlc->wiphy, "wl%d: wlc_edcf_setparams: bad "
+				  "aifs %d\n", wlc->pub->unit, acp_shm.aifs);
 			continue;
 		}
 
@@ -1439,20 +1319,14 @@
 
 }
 
-void wlc_edcf_setparams(struct wlc_bsscfg *cfg, bool suspend)
+void wlc_edcf_setparams(struct wlc_info *wlc, bool suspend)
 {
-	struct wlc_info *wlc = cfg->wlc;
-	uint aci, i, j;
+	u16 aci;
+	int i_ac;
 	edcf_acparam_t *edcf_acp;
-	shm_acparams_t acp_shm;
-	u16 *shm_entry;
-
-	ASSERT(cfg);
-	ASSERT(wlc);
 
-	/* Only apply params if the core is out of reset and has clocks */
-	if (!wlc->clk)
-		return;
+	struct ieee80211_tx_queue_params txq_pars;
+	struct ieee80211_tx_queue_params *params = &txq_pars;
 
 	/*
 	 * AP uses AC params from wme_param_ie_ap.
@@ -1462,59 +1336,24 @@
 
 	edcf_acp = (edcf_acparam_t *) &wlc->wme_param_ie.acparam[0];
 
-	wlc->wme_admctl = 0;
-
-	for (i = 0; i < AC_COUNT; i++, edcf_acp++) {
-		memset((char *)&acp_shm, 0, sizeof(shm_acparams_t));
+	for (i_ac = 0; i_ac < AC_COUNT; i_ac++, edcf_acp++) {
 		/* find out which ac this set of params applies to */
 		aci = (edcf_acp->ACI & EDCF_ACI_MASK) >> EDCF_ACI_SHIFT;
-		ASSERT(aci < AC_COUNT);
 		/* set the admission control policy for this AC */
 		if (edcf_acp->ACI & EDCF_ACM_MASK) {
 			wlc->wme_admctl |= 1 << aci;
 		}
 
 		/* fill in shm ac params struct */
-		acp_shm.txop = le16_to_cpu(edcf_acp->TXOP);
-		/* convert from units of 32us to us for ucode */
-		wlc->edcf_txop[aci] = acp_shm.txop =
-		    EDCF_TXOP2USEC(acp_shm.txop);
-		acp_shm.aifs = (edcf_acp->ACI & EDCF_AIFSN_MASK);
-
-		if (aci == AC_VI && acp_shm.txop == 0
-		    && acp_shm.aifs < EDCF_AIFSN_MAX)
-			acp_shm.aifs++;
-
-		if (acp_shm.aifs < EDCF_AIFSN_MIN
-		    || acp_shm.aifs > EDCF_AIFSN_MAX) {
-			WL_ERROR("wl%d: wlc_edcf_setparams: bad aifs %d\n",
-				 wlc->pub->unit, acp_shm.aifs);
-			continue;
-		}
+		params->txop = edcf_acp->TXOP;
+		params->aifs = edcf_acp->ACI;
 
 		/* CWmin = 2^(ECWmin) - 1 */
-		acp_shm.cwmin = EDCF_ECW2CW(edcf_acp->ECW & EDCF_ECWMIN_MASK);
+		params->cw_min = EDCF_ECW2CW(edcf_acp->ECW & EDCF_ECWMIN_MASK);
 		/* CWmax = 2^(ECWmax) - 1 */
-		acp_shm.cwmax = EDCF_ECW2CW((edcf_acp->ECW & EDCF_ECWMAX_MASK)
+		params->cw_max = EDCF_ECW2CW((edcf_acp->ECW & EDCF_ECWMAX_MASK)
 					    >> EDCF_ECWMAX_SHIFT);
-		acp_shm.cwcur = acp_shm.cwmin;
-		acp_shm.bslots =
-		    R_REG(&wlc->regs->tsf_random) & acp_shm.cwcur;
-		acp_shm.reggap = acp_shm.bslots + acp_shm.aifs;
-		/* Indicate the new params to the ucode */
-		acp_shm.status = wlc_read_shm(wlc, (M_EDCF_QINFO +
-						    wme_shmemacindex(aci) *
-						    M_EDCF_QLEN +
-						    M_EDCF_STATUS_OFF));
-		acp_shm.status |= WME_STATUS_NEWAC;
-
-		/* Fill in shm acparam table */
-		shm_entry = (u16 *) &acp_shm;
-		for (j = 0; j < (int)sizeof(shm_acparams_t); j += 2)
-			wlc_write_shm(wlc,
-				      M_EDCF_QINFO +
-				      wme_shmemacindex(aci) * M_EDCF_QLEN + j,
-				      *shm_entry++);
+		wlc_wme_setparams(wlc, aci, params, suspend);
 	}
 
 	if (suspend)
@@ -1535,14 +1374,16 @@
 	wlc->wdtimer = wl_init_timer(wlc->wl, wlc_watchdog_by_timer,
 		wlc, "watchdog");
 	if (!wlc->wdtimer) {
-		WL_ERROR("wl%d:  wl_init_timer for wdtimer failed\n", unit);
+		wiphy_err(wlc->wiphy, "wl%d:  wl_init_timer for wdtimer "
+			  "failed\n", unit);
 		goto fail;
 	}
 
 	wlc->radio_timer = wl_init_timer(wlc->wl, wlc_radio_timer,
 		wlc, "radio");
 	if (!wlc->radio_timer) {
-		WL_ERROR("wl%d:  wl_init_timer for radio_timer failed\n", unit);
+		wiphy_err(wlc->wiphy, "wl%d:  wl_init_timer for radio_timer "
+			  "failed\n", unit);
 		goto fail;
 	}
 
@@ -1689,20 +1530,23 @@
 
 	wlc->asi = wlc_antsel_attach(wlc);
 	if (wlc->asi == NULL) {
-		WL_ERROR("wl%d: wlc_attach: wlc_antsel_attach failed\n", unit);
+		wiphy_err(wlc->wiphy, "wl%d: wlc_attach: wlc_antsel_attach "
+			  "failed\n", unit);
 		err = 44;
 		goto fail;
 	}
 
 	wlc->ampdu = wlc_ampdu_attach(wlc);
 	if (wlc->ampdu == NULL) {
-		WL_ERROR("wl%d: wlc_attach: wlc_ampdu_attach failed\n", unit);
+		wiphy_err(wlc->wiphy, "wl%d: wlc_attach: wlc_ampdu_attach "
+			  "failed\n", unit);
 		err = 50;
 		goto fail;
 	}
 
 	if ((wlc_stf_attach(wlc) != 0)) {
-		WL_ERROR("wl%d: wlc_attach: wlc_stf_attach failed\n", unit);
+		wiphy_err(wlc->wiphy, "wl%d: wlc_attach: wlc_stf_attach "
+			  "failed\n", unit);
 		err = 68;
 		goto fail;
 	}
@@ -1720,56 +1564,21 @@
 /*
  * The common driver entry routine. Error codes should be unique
  */
-void *wlc_attach(void *wl, u16 vendor, u16 device, uint unit, bool piomode,
-		 void *regsva, uint bustype, void *btparam, uint *perr)
+void *wlc_attach(struct wl_info *wl, u16 vendor, u16 device, uint unit,
+		 bool piomode, void *regsva, uint bustype, void *btparam,
+		 uint *perr)
 {
 	struct wlc_info *wlc;
 	uint err = 0;
 	uint j;
 	struct wlc_pub *pub;
-	struct wlc_txq_info *qi;
 	uint n_disabled;
 
-	WL_NONE("wl%d: %s: vendor 0x%x device 0x%x\n",
-		unit, __func__, vendor, device);
-
-	ASSERT(WSEC_MAX_RCMTA_KEYS <= WSEC_MAX_KEYS);
-	ASSERT(WSEC_MAX_DEFAULT_KEYS == WLC_DEFAULT_KEYS);
-
-	/* some code depends on packed structures */
-	ASSERT(sizeof(struct ethhdr) == ETH_HLEN);
-	ASSERT(sizeof(d11regs_t) == SI_CORE_SIZE);
-	ASSERT(sizeof(ofdm_phy_hdr_t) == D11_PHY_HDR_LEN);
-	ASSERT(sizeof(cck_phy_hdr_t) == D11_PHY_HDR_LEN);
-	ASSERT(sizeof(d11txh_t) == D11_TXH_LEN);
-	ASSERT(sizeof(d11rxhdr_t) == RXHDR_LEN);
-	ASSERT(sizeof(struct ieee80211_hdr) == DOT11_A4_HDR_LEN);
-	ASSERT(sizeof(struct ieee80211_rts) == DOT11_RTS_LEN);
-	ASSERT(sizeof(tx_status_t) == TXSTATUS_LEN);
-	ASSERT(sizeof(struct ieee80211_ht_cap) == HT_CAP_IE_LEN);
-#ifdef BRCM_FULLMAC
-	ASSERT(offsetof(wl_scan_params_t, channel_list) ==
-	       WL_SCAN_PARAMS_FIXED_SIZE);
-#endif
-	ASSERT(IS_ALIGNED(offsetof(wsec_key_t, data), sizeof(u32)));
-	ASSERT(ISPOWEROF2(MA_WINDOW_SZ));
-
-	ASSERT(sizeof(wlc_d11rxhdr_t) <= WL_HWRXOFF);
-
-	/*
-	 * Number of replay counters value used in WPA IE must match # rxivs
-	 * supported in wsec_key_t struct. See 802.11i/D3.0 sect. 7.3.2.17
-	 * 'RSN Information Element' figure 8 for this mapping.
-	 */
-	ASSERT((WPA_CAP_16_REPLAY_CNTRS == WLC_REPLAY_CNTRS_VALUE
-		&& 16 == WLC_NUMRXIVS)
-	       || (WPA_CAP_4_REPLAY_CNTRS == WLC_REPLAY_CNTRS_VALUE
-		   && 4 == WLC_NUMRXIVS));
-
 	/* allocate struct wlc_info state and its substructures */
 	wlc = (struct wlc_info *) wlc_attach_malloc(unit, &err, device);
 	if (wlc == NULL)
 		goto fail;
+	wlc->wiphy = wl->wiphy;
 	pub = wlc->pub;
 
 #if defined(BCMDBG)
@@ -1892,7 +1701,7 @@
 		/* fill in hw_rateset (used early by WLC_SET_RATESET) */
 		wlc_rateset_filter(&wlc->band->defrateset,
 				   &wlc->band->hw_rateset, false,
-				   WLC_RATES_CCK_OFDM, RATE_MASK,
+				   WLC_RATES_CCK_OFDM, WLC_RATE_MASK,
 				   (bool) N_ENAB(wlc->pub));
 	}
 
@@ -1905,7 +1714,8 @@
 		goto fail;
 
 	if (!wlc_timers_init(wlc, unit)) {
-		WL_ERROR("wl%d: %s: wlc_init_timer failed\n", unit, __func__);
+		wiphy_err(wl->wiphy, "wl%d: %s: wlc_init_timer failed\n", unit,
+			  __func__);
 		err = 32;
 		goto fail;
 	}
@@ -1913,8 +1723,8 @@
 	/* depend on rateset, gmode */
 	wlc->cmi = wlc_channel_mgr_attach(wlc);
 	if (!wlc->cmi) {
-		WL_ERROR("wl%d: %s: wlc_channel_mgr_attach failed\n",
-			 unit, __func__);
+		wiphy_err(wl->wiphy, "wl%d: %s: wlc_channel_mgr_attach failed"
+			  "\n", unit, __func__);
 		err = 33;
 		goto fail;
 	}
@@ -1927,26 +1737,19 @@
 	 */
 
 	/* allocate our initial queue */
-	qi = wlc_txq_alloc(wlc);
-	if (qi == NULL) {
-		WL_ERROR("wl%d: %s: failed to malloc tx queue\n",
-			 unit, __func__);
+	wlc->pkt_queue = wlc_txq_alloc(wlc);
+	if (wlc->pkt_queue == NULL) {
+		wiphy_err(wl->wiphy, "wl%d: %s: failed to malloc tx queue\n",
+			  unit, __func__);
 		err = 100;
 		goto fail;
 	}
-	wlc->active_queue = qi;
 
 	wlc->bsscfg[0] = wlc->cfg;
 	wlc->cfg->_idx = 0;
 	wlc->cfg->wlc = wlc;
 	pub->txmaxpkts = MAXTXPKTS;
 
-	pub->_cnt->version = WL_CNT_T_VERSION;
-	pub->_cnt->length = sizeof(struct wl_cnt);
-
-	WLCNTSET(pub->_wme_cnt->version, WL_WME_CNT_VERSION);
-	WLCNTSET(pub->_wme_cnt->length, sizeof(wl_wme_cnt_t));
-
 	wlc_wme_initparams_sta(wlc, &wlc->wme_param_ie);
 
 	wlc->mimoft = FT_HT;
@@ -2014,7 +1817,8 @@
 	return (void *)wlc;
 
  fail:
-	WL_ERROR("wl%d: %s: failed with err %d\n", unit, __func__, err);
+	wiphy_err(wl->wiphy, "wl%d: %s: failed with err %d\n",
+		  unit, __func__, err);
 	if (wlc)
 		wlc_detach(wlc);
 
@@ -2032,8 +1836,8 @@
 		/* default antenna gain for srom rev 1 is 2 dBm (8 qdbm) */
 		wlc->band->antgain = 8;
 	} else if (wlc->band->antgain == -1) {
-		WL_ERROR("wl%d: %s: Invalid antennas available in srom, using 2dB\n",
-			 unit, __func__);
+		wiphy_err(wlc->wiphy, "wl%d: %s: Invalid antennas available in"
+			  " srom, using 2dB\n", unit, __func__);
 		wlc->band->antgain = 8;
 	} else {
 		s8 gain, fract;
@@ -2072,8 +1876,8 @@
 		aa = (s8) getintvar(vars,
 				      (BAND_5G(bandtype) ? "aa1" : "aa0"));
 	if ((aa < 1) || (aa > 15)) {
-		WL_ERROR("wl%d: %s: Invalid antennas available in srom (0x%x), using 3\n",
-			 unit, __func__, aa);
+		wiphy_err(wlc->wiphy, "wl%d: %s: Invalid antennas available in"
+			  " srom (0x%x), using 3\n", unit, __func__, aa);
 		aa = 3;
 	}
 
@@ -2134,15 +1938,12 @@
  */
 uint wlc_detach(struct wlc_info *wlc)
 {
-	uint i;
 	uint callbacks = 0;
 
 	if (wlc == NULL)
 		return 0;
 
-	WL_TRACE("wl%d: %s\n", wlc->pub->unit, __func__);
-
-	ASSERT(!wlc->pub->up);
+	BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit);
 
 	callbacks += wlc_bmac_detach(wlc);
 
@@ -2182,13 +1983,6 @@
 	while (wlc->tx_queues != NULL)
 		wlc_txq_free(wlc, wlc->tx_queues);
 
-	/*
-	 * consistency check: wlc_module_register/wlc_module_unregister calls
-	 * should match therefore nothing should be left here.
-	 */
-	for (i = 0; i < WLC_MAXMODULES; i++)
-		ASSERT(wlc->modulecb[i].name[0] == '\0');
-
 	wlc_detach_mfree(wlc);
 	return callbacks;
 }
@@ -2300,8 +2094,6 @@
 /* maintain LED behavior in down state */
 static void wlc_down_led_upd(struct wlc_info *wlc)
 {
-	ASSERT(!wlc->pub->up);
-
 	/* maintain LEDs while in down state, turn on sbclk if not available yet */
 	/* turn on sbclk if necessary */
 	if (!AP_ENAB(wlc->pub)) {
@@ -2349,7 +2141,8 @@
 	struct wlc_info *wlc = (struct wlc_info *) arg;
 
 	if (DEVICEREMOVED(wlc)) {
-		WL_ERROR("wl%d: %s: dead chip\n", wlc->pub->unit, __func__);
+		wiphy_err(wlc->wiphy, "wl%d: %s: dead chip\n", wlc->pub->unit,
+			__func__);
 		wl_down(wlc->wl);
 		return;
 	}
@@ -2358,8 +2151,6 @@
 	if (wlc->mpc_offcnt < WLC_MPC_MAX_DELAYCNT)
 		wlc->mpc_offcnt++;
 
-	/* validate all the reasons driver could be down and running this radio_timer */
-	ASSERT(wlc->pub->radio_disabled || wlc->down_override);
 	wlc_radio_hwdisable_upd(wlc);
 	wlc_radio_upd(wlc);
 }
@@ -2381,56 +2172,11 @@
 	if (!wlc->radio_monitor)
 		return true;
 
-	ASSERT((wlc->pub->wlfeatureflag & WL_SWFL_NOHWRADIO) !=
-	       WL_SWFL_NOHWRADIO);
-
 	wlc->radio_monitor = false;
 	wlc_pllreq(wlc, false, WLC_PLLREQ_RADIO_MON);
 	return wl_del_timer(wlc->wl, wlc->radio_timer);
 }
 
-/* bring the driver down, but don't reset hardware */
-void wlc_out(struct wlc_info *wlc)
-{
-	wlc_bmac_set_noreset(wlc->hw, true);
-	wlc_radio_upd(wlc);
-	wl_down(wlc->wl);
-	wlc_bmac_set_noreset(wlc->hw, false);
-
-	/* core clk is true in BMAC driver due to noreset, need to mirror it in HIGH */
-	wlc->clk = true;
-
-	/* This will make sure that when 'up' is done
-	 * after 'out' it'll restore hardware (especially gpios)
-	 */
-	wlc->pub->hw_up = false;
-}
-
-#if defined(BCMDBG)
-/* Verify the sanity of wlc->tx_prec_map. This can be done only by making sure that
- * if there is no packet pending for the FIFO, then the corresponding prec bits should be set
- * in prec_map. Of course, ignore this rule when block_datafifo is set
- */
-static bool wlc_tx_prec_map_verify(struct wlc_info *wlc)
-{
-	/* For non-WME, both fifos have overlapping prec_map. So it's an error only if both
-	 * fail the check.
-	 */
-	if (!EDCF_ENAB(wlc->pub)) {
-		if (!(WLC_TX_FIFO_CHECK(wlc, TX_DATA_FIFO) ||
-		      WLC_TX_FIFO_CHECK(wlc, TX_CTL_FIFO)))
-			return false;
-		else
-			return true;
-	}
-
-	return WLC_TX_FIFO_CHECK(wlc, TX_AC_BK_FIFO)
-		&& WLC_TX_FIFO_CHECK(wlc, TX_AC_BE_FIFO)
-		&& WLC_TX_FIFO_CHECK(wlc, TX_AC_VI_FIFO)
-		&& WLC_TX_FIFO_CHECK(wlc, TX_AC_VO_FIFO);
-}
-#endif				/* BCMDBG */
-
 static void wlc_watchdog_by_timer(void *arg)
 {
 	struct wlc_info *wlc = (struct wlc_info *) arg;
@@ -2450,13 +2196,14 @@
 	int i;
 	struct wlc_bsscfg *cfg;
 
-	WL_TRACE("wl%d: wlc_watchdog\n", wlc->pub->unit);
+	BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit);
 
 	if (!wlc->pub->up)
 		return;
 
 	if (DEVICEREMOVED(wlc)) {
-		WL_ERROR("wl%d: %s: dead chip\n", wlc->pub->unit, __func__);
+		wiphy_err(wlc->wiphy, "wl%d: %s: dead chip\n", wlc->pub->unit,
+			  __func__);
 		wl_down(wlc->wl);
 		return;
 	}
@@ -2480,9 +2227,6 @@
 	/* radio sync: sw/hw/mpc --> radio_disable/radio_enable */
 	wlc_radio_hwdisable_upd(wlc);
 	wlc_radio_upd(wlc);
-	/* if ismpc, driver should be in down state if up/down is allowed */
-	if (wlc->mpc && wlc_ismpc(wlc))
-		ASSERT(!wlc->pub->up);
 	/* if radio is disable, driver may be down, quit here */
 	if (wlc->pub->radio_disabled)
 		return;
@@ -2515,23 +2259,16 @@
 		wlc->tempsense_lasttime = wlc->pub->now;
 		wlc_tempsense_upd(wlc);
 	}
-	/* BMAC_NOTE: for HIGH_ONLY driver, this seems being called after RPC bus failed */
-	ASSERT(wlc_bmac_taclear(wlc->hw, true));
-
-	/* Verify that tx_prec_map and fifos are in sync to avoid lock ups */
-	ASSERT(wlc_tx_prec_map_verify(wlc));
-
-	ASSERT(wlc_ps_check(wlc));
 }
 
 /* make interface operational */
 int wlc_up(struct wlc_info *wlc)
 {
-	WL_TRACE("wl%d: %s:\n", wlc->pub->unit, __func__);
+	BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit);
 
 	/* HW is turned off so don't try to access it */
 	if (wlc->pub->hw_off || DEVICEREMOVED(wlc))
-		return BCME_RADIOOFF;
+		return -ENOMEDIUM;
 
 	if (!wlc->pub->hw_up) {
 		wlc_bmac_hw_up(wlc->hw);
@@ -2556,11 +2293,11 @@
 	 * if radio is disabled, abort up, lower power, start radio timer and return 0(for NDIS)
 	 * don't call radio_update to avoid looping wlc_up.
 	 *
-	 * wlc_bmac_up_prep() returns either 0 or BCME_RADIOOFF only
+	 * wlc_bmac_up_prep() returns either 0 or -BCME_RADIOOFF only
 	 */
 	if (!wlc->pub->radio_disabled) {
 		int status = wlc_bmac_up_prep(wlc->hw);
-		if (status == BCME_RADIOOFF) {
+		if (status == -ENOMEDIUM) {
 			if (!mboolisset
 			    (wlc->pub->radio_disabled, WL_RADIO_HW_DISABLE)) {
 				int idx;
@@ -2572,12 +2309,13 @@
 					if (!BSSCFG_STA(bsscfg)
 					    || !bsscfg->enable || !bsscfg->BSS)
 						continue;
-					WL_ERROR("wl%d.%d: wlc_up: rfdisable -> " "wlc_bsscfg_disable()\n",
-						 wlc->pub->unit, idx);
+					wiphy_err(wlc->wiphy, "wl%d.%d: wlc_up"
+						  ": rfdisable -> "
+						  "wlc_bsscfg_disable()\n",
+						   wlc->pub->unit, idx);
 				}
 			}
-		} else
-			ASSERT(!status);
+		}
 	}
 
 	if (wlc->pub->radio_disabled) {
@@ -2621,7 +2359,6 @@
 	wlc_wme_retries_write(wlc);
 
 	/* start one second watchdog timer */
-	ASSERT(!wlc->WDarmed);
 	wl_add_timer(wlc->wl, wlc->wdtimer, TIMER_INTERVAL_WATCHDOG, true);
 	wlc->WDarmed = true;
 
@@ -2673,12 +2410,12 @@
 	bool dev_gone = false;
 	struct wlc_txq_info *qi;
 
-	WL_TRACE("wl%d: %s:\n", wlc->pub->unit, __func__);
+	BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit);
 
 	/* check if we are already in the going down path */
 	if (wlc->going_down) {
-		WL_ERROR("wl%d: %s: Driver going down so return\n",
-			 wlc->pub->unit, __func__);
+		wiphy_err(wlc->wiphy, "wl%d: %s: Driver going down so return"
+			  "\n", wlc->pub->unit, __func__);
 		return 0;
 	}
 	if (!wlc->pub->up)
@@ -2707,9 +2444,6 @@
 	/* cancel all other timers */
 	callbacks += wlc_down_del_timer(wlc);
 
-	/* interrupt must have been blocked */
-	ASSERT((wlc->macintmask == 0) || !wlc->pub->up);
-
 	wlc->pub->up = false;
 
 	wlc_phy_mute_upd(wlc->band->pi, false, PHY_MUTE_ALL);
@@ -2719,8 +2453,7 @@
 
 	/* flush tx queues */
 	for (qi = wlc->tx_queues; qi != NULL; qi = qi->next) {
-		pktq_flush(&qi->q, true, NULL, 0);
-		ASSERT(pktq_empty(&qi->q));
+		bcm_pktq_flush(&qi->q, true, NULL, NULL);
 	}
 
 	callbacks += wlc_bmac_down_finish(wlc->hw);
@@ -2728,13 +2461,6 @@
 	/* wlc_bmac_down_finish has done wlc_coredisable(). so clk is off */
 	wlc->clk = false;
 
-#ifdef BCMDBG
-	/* Since all the packets should have been freed,
-	 * all callbacks should have been called
-	 */
-	for (i = 1; i <= wlc->pub->tunables->maxpktcb; i++)
-		ASSERT(wlc->pkt_callback[i].fn == NULL);
-#endif
 	wlc->going_down = false;
 	return callbacks;
 }
@@ -2761,7 +2487,7 @@
 	 * Gmode is not GMODE_LEGACY_B
 	 */
 	if (N_ENAB(wlc->pub) && gmode == GMODE_LEGACY_B)
-		return BCME_UNSUPPORTED;
+		return -ENOTSUPP;
 
 	/* verify that we are dealing with 2G band and grab the band pointer */
 	if (wlc->band->bandtype == WLC_BAND_2G)
@@ -2770,12 +2496,12 @@
 		 (wlc->bandstate[OTHERBANDUNIT(wlc)]->bandtype == WLC_BAND_2G))
 		band = wlc->bandstate[OTHERBANDUNIT(wlc)];
 	else
-		return BCME_BADBAND;
+		return -EINVAL;
 
 	/* Legacy or bust when no OFDM is supported by regulatory */
 	if ((wlc_channel_locale_flags_in_band(wlc->cmi, band->bandunit) &
 	     WLC_NO_OFDM) && (gmode != GMODE_LEGACY_B))
-		return BCME_RANGE;
+		return -EINVAL;
 
 	/* update configuration value */
 	if (config == true)
@@ -2823,9 +2549,9 @@
 
 	default:
 		/* Error */
-		WL_ERROR("wl%d: %s: invalid gmode %d\n",
-			 wlc->pub->unit, __func__, gmode);
-		return BCME_UNSUPPORTED;
+		wiphy_err(wlc->wiphy, "wl%d: %s: invalid gmode %d\n",
+			  wlc->pub->unit, __func__, gmode);
+		return -ENOTSUPP;
 	}
 
 	/*
@@ -2904,11 +2630,11 @@
 	case WL_11N_2x2:
 	case WL_11N_3x3:
 		if (!(WLC_PHY_11N_CAP(wlc->band)))
-			err = BCME_BADBAND;
+			err = -EINVAL;
 		break;
 
 	default:
-		err = BCME_RANGE;
+		err = -EINVAL;
 		break;
 	}
 
@@ -2921,7 +2647,6 @@
 	int err;
 
 	err = wlc_nmode_validate(wlc, nmode);
-	ASSERT(err == 0);
 	if (err)
 		return err;
 
@@ -2950,7 +2675,6 @@
 			nmode = WL_11N_2x2;
 	case WL_11N_2x2:
 	case WL_11N_3x3:
-		ASSERT(WLC_PHY_11N_CAP(wlc->band));
 		/* force GMODE_AUTO if NMODE is ON */
 		wlc_set_gmode(wlc, GMODE_AUTO, true);
 		if (nmode == WL_11N_3x3)
@@ -2967,7 +2691,6 @@
 		break;
 
 	default:
-		ASSERT(0);
 		break;
 	}
 
@@ -2983,7 +2706,7 @@
 
 	/* check for bad count value */
 	if ((rs.count == 0) || (rs.count > WLC_NUMRATES))
-		return BCME_BADRATESET;
+		return -EINVAL;
 
 	/* try the current band */
 	bandunit = wlc->band->bandunit;
@@ -3005,7 +2728,7 @@
 			goto good;
 	}
 
-	return BCME_ERROR;
+	return -EBADE;
 
  good:
 	/* apply new rateset */
@@ -3067,8 +2790,8 @@
 	wlc_bss_info_t *current_bss;
 
 	/* update bsscfg pointer */
-	bsscfg = NULL;		/* XXX: Hack bsscfg to be size one and use this globally */
-	current_bss = NULL;
+	bsscfg = wlc->cfg;
+	current_bss = bsscfg->current_bss;
 
 	/* initialize the following to get rid of compiler warning */
 	nextscb = NULL;
@@ -3078,13 +2801,12 @@
 
 	/* If the device is turned off, then it's not "removed" */
 	if (!wlc->pub->hw_off && DEVICEREMOVED(wlc)) {
-		WL_ERROR("wl%d: %s: dead chip\n", wlc->pub->unit, __func__);
+		wiphy_err(wlc->wiphy, "wl%d: %s: dead chip\n", wlc->pub->unit,
+			  __func__);
 		wl_down(wlc->wl);
-		return BCME_ERROR;
+		return -EBADE;
 	}
 
-	ASSERT(!(wlc->pub->hw_off && wlc->pub->up));
-
 	/* default argument is generic integer */
 	pval = arg ? (int *)arg:NULL;
 
@@ -3096,11 +2818,6 @@
 
 	/* bool conversion to avoid duplication below */
 	bool_val = val != 0;
-
-	if (cmd != WLC_SET_CHANNEL)
-		WL_NONE("WLC_IOCTL: cmd %d val 0x%x (%d) len %d\n",
-			cmd, (uint)val, val, len);
-
 	bcmerror = 0;
 	regs = wlc->regs;
 
@@ -3118,9 +2835,10 @@
 
 	default:
 		if ((arg == NULL) || (len <= 0)) {
-			WL_ERROR("wl%d: %s: Command %d needs arguments\n",
-				 wlc->pub->unit, __func__, cmd);
-			bcmerror = BCME_BADARG;
+			wiphy_err(wlc->wiphy, "wl%d: %s: Command %d needs "
+				  "arguments\n",
+				  wlc->pub->unit, __func__, cmd);
+			bcmerror = -EINVAL;
 			goto done;
 		}
 	}
@@ -3144,7 +2862,10 @@
 	case WLC_GET_CHANNEL:{
 			channel_info_t *ci = (channel_info_t *) arg;
 
-			ASSERT(len > (int)sizeof(ci));
+			if (len <= (int)sizeof(ci)) {
+				bcmerror = EOVERFLOW;
+				goto done;
+			}
 
 			ci->hw_channel =
 			    CHSPEC_CHANNEL(WLC_BAND_PI_RADIO_CHANSPEC);
@@ -3159,12 +2880,12 @@
 			chanspec_t chspec = CH20MHZ_CHSPEC(val);
 
 			if (val < 0 || val > MAXCHANNEL) {
-				bcmerror = BCME_OUTOFRANGECHAN;
+				bcmerror = -EINVAL;
 				break;
 			}
 
 			if (!wlc_valid_chanspec_db(wlc->cmi, chspec)) {
-				bcmerror = BCME_BADCHAN;
+				bcmerror = -EINVAL;
 				break;
 			}
 
@@ -3191,7 +2912,7 @@
 #if defined(BCMDBG)
 	case WLC_GET_UCFLAGS:
 		if (!wlc->pub->up) {
-			bcmerror = BCME_NOTUP;
+			bcmerror = -ENOLINK;
 			break;
 		}
 
@@ -3206,7 +2927,7 @@
 			break;
 
 		if (val >= MHFMAX) {
-			bcmerror = BCME_RANGE;
+			bcmerror = -EINVAL;
 			break;
 		}
 
@@ -3215,7 +2936,7 @@
 
 	case WLC_SET_UCFLAGS:
 		if (!wlc->pub->up) {
-			bcmerror = BCME_NOTUP;
+			bcmerror = -ENOLINK;
 			break;
 		}
 
@@ -3231,7 +2952,7 @@
 
 		i = (u16) val;
 		if (i >= MHFMAX) {
-			bcmerror = BCME_RANGE;
+			bcmerror = -EINVAL;
 			break;
 		}
 
@@ -3253,7 +2974,7 @@
 			break;
 
 		if (val & 1) {
-			bcmerror = BCME_BADADDR;
+			bcmerror = -EINVAL;
 			break;
 		}
 
@@ -3274,7 +2995,7 @@
 			break;
 
 		if (val & 1) {
-			bcmerror = BCME_BADADDR;
+			bcmerror = -EINVAL;
 			break;
 		}
 
@@ -3288,7 +3009,7 @@
 		band = WLC_BAND_AUTO;
 
 		if (len < (int)(sizeof(rw_reg_t) - sizeof(uint))) {
-			bcmerror = BCME_BUFTOOSHORT;
+			bcmerror = -EOVERFLOW;
 			break;
 		}
 
@@ -3301,7 +3022,7 @@
 			break;
 
 		if ((r->byteoff + r->size) > sizeof(d11regs_t)) {
-			bcmerror = BCME_BADADDR;
+			bcmerror = -EINVAL;
 			break;
 		}
 		if (r->size == sizeof(u32))
@@ -3313,7 +3034,7 @@
 			    R_REG((u16 *)((unsigned char *)(unsigned long)regs +
 					      r->byteoff));
 		else
-			bcmerror = BCME_BADADDR;
+			bcmerror = -EINVAL;
 		break;
 
 	case WLC_W_REG:
@@ -3322,7 +3043,7 @@
 		band = WLC_BAND_AUTO;
 
 		if (len < (int)(sizeof(rw_reg_t) - sizeof(uint))) {
-			bcmerror = BCME_BUFTOOSHORT;
+			bcmerror = -EOVERFLOW;
 			break;
 		}
 
@@ -3335,7 +3056,7 @@
 			break;
 
 		if (r->byteoff + r->size > sizeof(d11regs_t)) {
-			bcmerror = BCME_BADADDR;
+			bcmerror = -EINVAL;
 			break;
 		}
 		if (r->size == sizeof(u32))
@@ -3345,7 +3066,7 @@
 			W_REG((u16 *)((unsigned char *)(unsigned long) regs +
 					  r->byteoff), r->val);
 		else
-			bcmerror = BCME_BADADDR;
+			bcmerror = -EINVAL;
 		break;
 #endif				/* BCMDBG */
 
@@ -3393,7 +3114,7 @@
 	case WLC_SET_ANTDIV:
 		/* values are -1=driver default, 0=force0, 1=force1, 2=start1, 3=start0 */
 		if ((val < -1) || (val > 3)) {
-			bcmerror = BCME_RANGE;
+			bcmerror = -EINVAL;
 			break;
 		}
 
@@ -3408,13 +3129,13 @@
 			u16 rxstatus;
 
 			if (!wlc->pub->up) {
-				bcmerror = BCME_NOTUP;
+				bcmerror = -ENOLINK;
 				break;
 			}
 
 			rxstatus = R_REG(&wlc->regs->phyrxstatus0);
 			if (rxstatus == 0xdead || rxstatus == (u16) -1) {
-				bcmerror = BCME_ERROR;
+				bcmerror = -EBADE;
 				break;
 			}
 			*pval = (rxstatus & PRXS0_RXANT_UPSUBBAND) ? 1 : 0;
@@ -3424,7 +3145,7 @@
 #if defined(BCMDBG)
 	case WLC_GET_UCANTDIV:
 		if (!wlc->clk) {
-			bcmerror = BCME_NOCLK;
+			bcmerror = -EIO;
 			break;
 		}
 
@@ -3435,13 +3156,13 @@
 
 	case WLC_SET_UCANTDIV:{
 			if (!wlc->pub->up) {
-				bcmerror = BCME_NOTUP;
+				bcmerror = -ENOLINK;
 				break;
 			}
 
 			/* if multiband, band must be locked */
 			if (IS_MBAND_UNLOCKED(wlc)) {
-				bcmerror = BCME_NOTBANDLOCKED;
+				bcmerror = -ENOMEDIUM;
 				break;
 			}
 
@@ -3467,7 +3188,7 @@
 			}
 			wlc_wme_retries_write(wlc);
 		} else
-			bcmerror = BCME_RANGE;
+			bcmerror = -EINVAL;
 		break;
 
 	case WLC_GET_LRL:
@@ -3486,7 +3207,7 @@
 			}
 			wlc_wme_retries_write(wlc);
 		} else
-			bcmerror = BCME_RANGE;
+			bcmerror = -EINVAL;
 		break;
 
 	case WLC_GET_CWMIN:
@@ -3495,14 +3216,14 @@
 
 	case WLC_SET_CWMIN:
 		if (!wlc->clk) {
-			bcmerror = BCME_NOCLK;
+			bcmerror = -EIO;
 			break;
 		}
 
 		if (val >= 1 && val <= 255) {
 			wlc_set_cwmin(wlc, (u16) val);
 		} else
-			bcmerror = BCME_RANGE;
+			bcmerror = -EINVAL;
 		break;
 
 	case WLC_GET_CWMAX:
@@ -3511,14 +3232,14 @@
 
 	case WLC_SET_CWMAX:
 		if (!wlc->clk) {
-			bcmerror = BCME_NOCLK;
+			bcmerror = -EIO;
 			break;
 		}
 
 		if (val >= 255 && val <= 2047) {
 			wlc_set_cwmax(wlc, (u16) val);
 		} else
-			bcmerror = BCME_RANGE;
+			bcmerror = -EINVAL;
 		break;
 
 	case WLC_GET_RADIO:	/* use mask if don't want to expose some internal bits */
@@ -3539,9 +3260,9 @@
 			if ((radiomask == 0) || (radiomask & ~validbits)
 			    || (radioval & ~validbits)
 			    || ((radioval & ~radiomask) != 0)) {
-				WL_ERROR("SET_RADIO with wrong bits 0x%x\n",
-					 val);
-				bcmerror = BCME_RANGE;
+				wiphy_err(wlc->wiphy, "SET_RADIO with wrong "
+					  "bits 0x%x\n", val);
+				bcmerror = -EINVAL;
 				break;
 			}
 
@@ -3566,7 +3287,7 @@
 			wsec_key_t *src_key = wlc->wsec_keys[val];
 
 			if (len < (int)sizeof(key)) {
-				bcmerror = BCME_BUFTOOSHORT;
+				bcmerror = -EOVERFLOW;
 				break;
 			}
 
@@ -3586,7 +3307,7 @@
 
 			memcpy(arg, &key, sizeof(key));
 		} else
-			bcmerror = BCME_BADKEYIDX;
+			bcmerror = -EINVAL;
 		break;
 #endif				/* defined(BCMDBG) */
 
@@ -3600,7 +3321,7 @@
 			wsec_key_t *key;
 
 			if (len < DOT11_WPA_KEY_RSC_LEN) {
-				bcmerror = BCME_BUFTOOSHORT;
+				bcmerror = -EOVERFLOW;
 				break;
 			}
 
@@ -3637,7 +3358,7 @@
 
 				memcpy(arg, seq, sizeof(seq));
 			} else {
-				bcmerror = BCME_BADKEYIDX;
+				bcmerror = -EINVAL;
 			}
 			break;
 		}
@@ -3646,13 +3367,13 @@
 			wl_rateset_t *ret_rs = (wl_rateset_t *) arg;
 			wlc_rateset_t *rs;
 
-			if (bsscfg->associated)
+			if (wlc->pub->associated)
 				rs = &current_bss->rateset;
 			else
 				rs = &wlc->default_bss->rateset;
 
 			if (len < (int)(rs->count + sizeof(rs->count))) {
-				bcmerror = BCME_BUFTOOSHORT;
+				bcmerror = -EOVERFLOW;
 				break;
 			}
 
@@ -3670,7 +3391,7 @@
 			wlc_default_rateset(wlc, (wlc_rateset_t *) &rs);
 
 			if (len < (int)(rs.count + sizeof(rs.count))) {
-				bcmerror = BCME_BUFTOOSHORT;
+				bcmerror = -EOVERFLOW;
 				break;
 			}
 
@@ -3685,12 +3406,12 @@
 			wl_rateset_t *in_rs = (wl_rateset_t *) arg;
 
 			if (len < (int)(in_rs->count + sizeof(in_rs->count))) {
-				bcmerror = BCME_BUFTOOSHORT;
+				bcmerror = -EOVERFLOW;
 				break;
 			}
 
 			if (in_rs->count > WLC_NUMRATES) {
-				bcmerror = BCME_BUFTOOLONG;
+				bcmerror = -ENOBUFS;
 				break;
 			}
 
@@ -3733,7 +3454,7 @@
 		    && val <= DOT11_MAX_BEACON_PERIOD) {
 			wlc->default_bss->beacon_period = (u16) val;
 		} else
-			bcmerror = BCME_RANGE;
+			bcmerror = -EINVAL;
 		break;
 
 	case WLC_GET_DTIMPRD:
@@ -3749,7 +3470,7 @@
 		    && val <= DOT11_MAX_DTIM_PERIOD) {
 			wlc->default_bss->dtim_period = (u8) val;
 		} else
-			bcmerror = BCME_RANGE;
+			bcmerror = -EINVAL;
 		break;
 
 #ifdef SUPPORT_PS
@@ -3765,7 +3486,7 @@
 			/* Change watchdog driver to align watchdog with tbtt if possible */
 			wlc_watchdog_upd(wlc, PS_ALLOWED(wlc));
 		} else
-			bcmerror = BCME_ERROR;
+			bcmerror = -EBADE;
 		break;
 #endif				/* SUPPORT_PS */
 
@@ -3773,7 +3494,7 @@
 #ifdef BCMDBG
 	case WLC_GET_WAKE:
 		if (AP_ENAB(wlc->pub)) {
-			bcmerror = BCME_NOTSTA;
+			bcmerror = -BCME_NOTSTA;
 			break;
 		}
 		*pval = wlc->wake;
@@ -3781,7 +3502,7 @@
 
 	case WLC_SET_WAKE:
 		if (AP_ENAB(wlc->pub)) {
-			bcmerror = BCME_NOTSTA;
+			bcmerror = -BCME_NOTSTA;
 			break;
 		}
 
@@ -3816,24 +3537,6 @@
 		wlc->default_bss->atim_window = (u32) val;
 		break;
 
-	case WLC_GET_PKTCNTS:{
-			get_pktcnt_t *pktcnt = (get_pktcnt_t *) pval;
-			wlc_statsupd(wlc);
-			pktcnt->rx_good_pkt = wlc->pub->_cnt->rxframe;
-			pktcnt->rx_bad_pkt = wlc->pub->_cnt->rxerror;
-			pktcnt->tx_good_pkt =
-			    wlc->pub->_cnt->txfrmsnt;
-			pktcnt->tx_bad_pkt =
-			    wlc->pub->_cnt->txerror +
-			    wlc->pub->_cnt->txfail;
-			if (len >= (int)sizeof(get_pktcnt_t)) {
-				/* Be backward compatible - only if buffer is large enough  */
-				pktcnt->rx_ocast_good_pkt =
-				    wlc->pub->_cnt->rxmfrmocast;
-			}
-			break;
-		}
-
 #ifdef SUPPORT_HWKEY
 	case WLC_GET_WSEC:
 		bcmerror =
@@ -3876,7 +3579,7 @@
 		{
 			unsigned char *cp = arg;
 			if (len < 3) {
-				bcmerror = BCME_BUFTOOSHORT;
+				bcmerror = -EOVERFLOW;
 				break;
 			}
 
@@ -3902,7 +3605,7 @@
 	case WLC_SET_SHORTSLOT_OVERRIDE:
 		if ((val != WLC_SHORTSLOT_AUTO) &&
 		    (val != WLC_SHORTSLOT_OFF) && (val != WLC_SHORTSLOT_ON)) {
-			bcmerror = BCME_RANGE;
+			bcmerror = -EINVAL;
 			break;
 		}
 
@@ -3959,7 +3662,7 @@
 		if (!wlc->pub->associated)
 			bcmerror = wlc_set_gmode(wlc, (u8) val, true);
 		else {
-			bcmerror = BCME_ASSOCIATED;
+			bcmerror = -EISCONN;
 			break;
 		}
 		break;
@@ -3976,7 +3679,7 @@
 		if ((val != WLC_PROTECTION_CTL_OFF) &&
 		    (val != WLC_PROTECTION_CTL_LOCAL) &&
 		    (val != WLC_PROTECTION_CTL_OVERLAP)) {
-			bcmerror = BCME_RANGE;
+			bcmerror = -EINVAL;
 			break;
 		}
 
@@ -3995,7 +3698,7 @@
 	case WLC_SET_GMODE_PROTECTION_OVERRIDE:
 		if ((val != WLC_PROTECTION_AUTO) &&
 		    (val != WLC_PROTECTION_OFF) && (val != WLC_PROTECTION_ON)) {
-			bcmerror = BCME_RANGE;
+			bcmerror = -EINVAL;
 			break;
 		}
 
@@ -4008,14 +3711,14 @@
 
 			/* copyin */
 			if (len < (int)sizeof(wlc_rateset_t)) {
-				bcmerror = BCME_BUFTOOSHORT;
+				bcmerror = -EOVERFLOW;
 				break;
 			}
 			memcpy(&rs, arg, sizeof(wlc_rateset_t));
 
 			/* check for bad count value */
 			if (rs.count > WLC_NUMRATES) {
-				bcmerror = BCME_BADRATESET;	/* invalid rateset */
+				bcmerror = -EINVAL;
 				break;
 			}
 
@@ -4023,7 +3726,8 @@
 			if (!(wlc->band->gmode ||
 			      ((NBANDS(wlc) > 1)
 			       && wlc->bandstate[OTHERBANDUNIT(wlc)]->gmode))) {
-				bcmerror = BCME_BADBAND;	/* gmode only command when not in gmode */
+				/* gmode only command when not in gmode */
+				bcmerror = -EINVAL;
 				break;
 			}
 
@@ -4034,15 +3738,19 @@
 				break;
 			}
 
-			/* validate rateset by comparing pre and post sorted against 11g hw rates */
-			wlc_rateset_filter(&rs, &new, false, WLC_RATES_CCK_OFDM,
-					   RATE_MASK, BSS_N_ENAB(wlc, bsscfg));
+			/*
+			 * validate rateset by comparing pre and
+			 * post sorted against 11g hw rates
+			 */
+			wlc_rateset_filter(&rs, &new, false,
+					   WLC_RATES_CCK_OFDM, WLC_RATE_MASK,
+					   BSS_N_ENAB(wlc, bsscfg));
 			wlc_rate_hwrs_filter_sort_validate(&new,
 							   &cck_ofdm_rates,
 							   false,
 							   wlc->stf->txstreams);
 			if (rs.count != new.count) {
-				bcmerror = BCME_BADRATESET;	/* invalid rateset */
+				bcmerror = -EINVAL;
 				break;
 			}
 
@@ -4064,11 +3772,12 @@
 		if (!(wlc->band->gmode ||
 		      ((NBANDS(wlc) > 1)
 		       && wlc->bandstate[OTHERBANDUNIT(wlc)]->gmode))) {
-			bcmerror = BCME_BADBAND;	/* gmode only command when not in gmode */
+			/* gmode only command when not in gmode */
+			bcmerror = -EINVAL;
 			break;
 		}
 		if (len < (int)sizeof(wlc_rateset_t)) {
-			bcmerror = BCME_BUFTOOSHORT;
+			bcmerror = -EOVERFLOW;
 			break;
 		}
 		memcpy(arg, &wlc->sup_rates_override, sizeof(wlc_rateset_t));
@@ -4081,11 +3790,11 @@
 
 	case WLC_SET_PRB_RESP_TIMEOUT:
 		if (wlc->pub->up) {
-			bcmerror = BCME_NOTDOWN;
+			bcmerror = -EISCONN;
 			break;
 		}
 		if (val < 0 || val >= 0xFFFF) {
-			bcmerror = BCME_RANGE;	/* bad value */
+			bcmerror = -EINVAL;	/* bad value */
 			break;
 		}
 		wlc->prb_resp_timeout = (u16) val;
@@ -4099,7 +3808,7 @@
 			if (key != NULL) {
 				*pval = key->id == val ? true : false;
 			} else {
-				bcmerror = BCME_BADKEYIDX;
+				bcmerror = -EINVAL;
 			}
 			break;
 		}
@@ -4107,7 +3816,7 @@
 	case WLC_SET_KEY_PRIMARY:{
 			wsec_key_t *key, *old_key;
 
-			bcmerror = BCME_BADKEYIDX;
+			bcmerror = -EINVAL;
 
 			/* treat the 'val' parm as the key id */
 			for (i = 0; i < WSEC_MAX_DEFAULT_KEYS; i++) {
@@ -4119,7 +3828,7 @@
 						    ~WSEC_PRIMARY_KEY;
 					key->flags |= WSEC_PRIMARY_KEY;
 					bsscfg->wsec_index = i;
-					bcmerror = BCME_OK;
+					bcmerror = 0;
 				}
 			}
 			break;
@@ -4141,7 +3850,7 @@
 				;
 
 			if (i == (uint) len) {
-				bcmerror = BCME_BUFTOOSHORT;
+				bcmerror = -EOVERFLOW;
 				break;
 			}
 			i++;	/* include the null in the string length */
@@ -4162,37 +3871,25 @@
 		}
 
 	case WLC_SET_WSEC_PMK:
-		bcmerror = BCME_UNSUPPORTED;
+		bcmerror = -ENOTSUPP;
 		break;
 
 #if defined(BCMDBG)
 	case WLC_CURRENT_PWR:
 		if (!wlc->pub->up)
-			bcmerror = BCME_NOTUP;
+			bcmerror = -ENOLINK;
 		else
 			bcmerror = wlc_get_current_txpwr(wlc, arg, len);
 		break;
 #endif
 
 	case WLC_LAST:
-		WL_ERROR("%s: WLC_LAST\n", __func__);
+		wiphy_err(wlc->wiphy, "%s: WLC_LAST\n", __func__);
 	}
  done:
 
-	if (bcmerror) {
-		if (VALID_BCMERROR(bcmerror))
-			wlc->pub->bcmerror = bcmerror;
-		else {
-			bcmerror = 0;
-		}
-
-	}
-	/* BMAC_NOTE: for HIGH_ONLY driver, this seems being called after RPC bus failed */
-	/* In hw_off condition, IOCTLs that reach here are deemed safe but taclear would
-	 * certainly result in getting -1 for register reads. So skip ta_clear altogether
-	 */
-	if (!(wlc->pub->hw_off))
-		ASSERT(wlc_bmac_taclear(wlc->hw, ta_ok) || !ta_ok);
+	if (bcmerror)
+		wlc->pub->bcmerror = bcmerror;
 
 	return bcmerror;
 }
@@ -4203,30 +3900,20 @@
 {
 	/* if band is specified, it must be the current band */
 	if ((band != WLC_BAND_AUTO) && (band != (uint) wlc->band->bandtype))
-		return BCME_BADBAND;
+		return -EINVAL;
 
 	/* if multiband and band is not specified, band must be locked */
 	if ((band == WLC_BAND_AUTO) && IS_MBAND_UNLOCKED(wlc))
-		return BCME_NOTBANDLOCKED;
+		return -ENOMEDIUM;
 
 	/* must have core clocks */
 	if (!wlc->clk)
-		return BCME_NOCLK;
+		return -EIO;
 
 	return 0;
 }
 #endif				/* defined(BCMDBG) */
 
-#if defined(BCMDBG)
-/* For some ioctls, make sure that the pi pointer matches the current phy */
-int wlc_iocpichk(struct wlc_info *wlc, uint phytype)
-{
-	if (wlc->band->phytype != phytype)
-		return BCME_BADBAND;
-	return 0;
-}
-#endif
-
 /* Look up the given var name in the given table */
 static const bcm_iovar_t *wlc_iovar_lookup(const bcm_iovar_t *table,
 					   const char *name)
@@ -4241,8 +3928,6 @@
 	else
 		lookup_name = name;
 
-	ASSERT(table != NULL);
-
 	for (vi = table; vi->name; vi++) {
 		if (!strcmp(vi->name, lookup_name))
 			return vi;
@@ -4266,21 +3951,6 @@
 			    IOV_SET, NULL);
 }
 
-/* simplified s8 get interface for common WLC_GET_VAR ioctl handler */
-int wlc_iovar_gets8(struct wlc_info *wlc, const char *name, s8 *arg)
-{
-	int iovar_int;
-	int err;
-
-	err =
-	    wlc_iovar_op(wlc, name, NULL, 0, &iovar_int, sizeof(iovar_int),
-			 IOV_GET, NULL);
-	if (!err)
-		*arg = (s8) iovar_int;
-
-	return err;
-}
-
 /*
  * register iovar table, watchdog and down handlers.
  * calling function must keep 'iovars' until wlc_module_unregister is called.
@@ -4293,9 +3963,6 @@
 	struct wlc_info *wlc = (struct wlc_info *) pub->wlc;
 	int i;
 
-	ASSERT(name != NULL);
-	ASSERT(i_fn != NULL || w_fn != NULL || d_fn != NULL);
-
 	/* find an empty entry and just add, no duplication check! */
 	for (i = 0; i < WLC_MAXMODULES; i++) {
 		if (wlc->modulecb[i].name[0] == '\0') {
@@ -4310,9 +3977,7 @@
 		}
 	}
 
-	/* it is time to increase the capacity */
-	ASSERT(i < WLC_MAXMODULES);
-	return BCME_NORESOURCE;
+	return -ENOSR;
 }
 
 /* unregister module callbacks */
@@ -4322,9 +3987,7 @@
 	int i;
 
 	if (wlc == NULL)
-		return BCME_NOTFOUND;
-
-	ASSERT(name != NULL);
+		return -ENODATA;
 
 	for (i = 0; i < WLC_MAXMODULES; i++) {
 		if (!strcmp(wlc->modulecb[i].name, name) &&
@@ -4335,7 +3998,7 @@
 	}
 
 	/* table not found! */
-	return BCME_NOTFOUND;
+	return -ENODATA;
 }
 
 /* Write WME tunable parameters for retransmit/max rate from wlc struct to ucode */
@@ -4371,23 +4034,11 @@
 	u32 actionid;
 	int i;
 
-	ASSERT(name != NULL);
-
-	ASSERT(len >= 0);
-
-	/* Get MUST have return space */
-	ASSERT(set || (arg && len));
-
-	ASSERT(!(wlc->pub->hw_off && wlc->pub->up));
-
-	/* Set does NOT take qualifiers */
-	ASSERT(!set || (!params && !p_len));
-
 	if (!set && (len == sizeof(int)) &&
 	    !(IS_ALIGNED((unsigned long)(arg), (uint) sizeof(int)))) {
-		WL_ERROR("wl%d: %s unaligned get ptr for %s\n",
-			 wlc->pub->unit, __func__, name);
-		ASSERT(0);
+		wiphy_err(wlc->wiphy, "wl%d: %s unaligned get ptr for %s\n",
+			  wlc->pub->unit, __func__, name);
+		return -ENOTSUPP;
 	}
 
 	/* find the given iovar name */
@@ -4400,8 +4051,7 @@
 	}
 	/* iovar name not found */
 	if (i >= WLC_MAXMODULES) {
-		err = BCME_UNSUPPORTED;
-		goto exit;
+		return -ENOTSUPP;
 	}
 
 	/* set up 'params' pointer in case this is a set command so that
@@ -4426,8 +4076,6 @@
 	err = wlc->modulecb[i].iovar_fn(wlc->modulecb[i].hdl, vi, actionid,
 					name, params, p_len, arg, len, val_size,
 					wlcif);
-
- exit:
 	return err;
 }
 
@@ -4443,22 +4091,22 @@
 	if (set) {
 		if (((vi->flags & IOVF_SET_DOWN) && wlc->pub->up) ||
 		    ((vi->flags & IOVF_SET_UP) && !wlc->pub->up)) {
-			err = (wlc->pub->up ? BCME_NOTDOWN : BCME_NOTUP);
+			err = (wlc->pub->up ? -EISCONN : -ENOLINK);
 		} else if ((vi->flags & IOVF_SET_BAND)
 			   && IS_MBAND_UNLOCKED(wlc)) {
-			err = BCME_NOTBANDLOCKED;
+			err = -ENOMEDIUM;
 		} else if ((vi->flags & IOVF_SET_CLK) && !wlc->clk) {
-			err = BCME_NOCLK;
+			err = -EIO;
 		}
 	} else {
 		if (((vi->flags & IOVF_GET_DOWN) && wlc->pub->up) ||
 		    ((vi->flags & IOVF_GET_UP) && !wlc->pub->up)) {
-			err = (wlc->pub->up ? BCME_NOTDOWN : BCME_NOTUP);
+			err = (wlc->pub->up ? -EISCONN : -ENOLINK);
 		} else if ((vi->flags & IOVF_GET_BAND)
 			   && IS_MBAND_UNLOCKED(wlc)) {
-			err = BCME_NOTBANDLOCKED;
+			err = -ENOMEDIUM;
 		} else if ((vi->flags & IOVF_GET_CLK) && !wlc->clk) {
-			err = BCME_NOCLK;
+			err = -EIO;
 		}
 	}
 
@@ -4513,7 +4161,7 @@
 	bool bool_val2;
 	wlc_bss_info_t *current_bss;
 
-	WL_TRACE("wl%d: %s\n", wlc->pub->unit, __func__);
+	BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit);
 
 	bsscfg = NULL;
 	current_bss = NULL;
@@ -4537,8 +4185,7 @@
 	bool_val = (int_val != 0) ? true : false;
 	bool_val2 = (int_val2 != 0) ? true : false;
 
-	WL_TRACE("wl%d: %s: id %d\n",
-		 wlc->pub->unit, __func__, IOV_ID(actionid));
+	BCMMSG(wlc->wiphy, "wl%d: id %d\n", wlc->pub->unit, IOV_ID(actionid));
 	/* Do the actual parameter implementation */
 	switch (actionid) {
 	case IOV_SVAL(IOV_RTSTHRESH):
@@ -4551,7 +4198,7 @@
 
 			err = wlc_phy_txpower_get(wlc->band->pi, &qdbm,
 				&override);
-			if (err != BCME_OK)
+			if (err != 0)
 				return err;
 
 			/* Return qdbm units */
@@ -4599,8 +4246,9 @@
 		break;
 
 	default:
-		WL_ERROR("wl%d: %s: unsupported\n", wlc->pub->unit, __func__);
-		err = BCME_UNSUPPORTED;
+		wiphy_err(wlc->wiphy, "wl%d: %s: unsupported\n",
+			  wlc->pub->unit, __func__);
+		err = -ENOTSUPP;
 		break;
 	}
 
@@ -4635,7 +4283,7 @@
 		/* Signed values are checked against max_val and min_val */
 		if ((s32) val < (s32) min_val
 		    || (s32) val > (s32) max_val)
-			err = BCME_RANGE;
+			err = -EINVAL;
 		break;
 
 	case IOVT_UINT32:
@@ -4649,7 +4297,7 @@
 		if (vi->flags & IOVF_NTRL)
 			min_val = 1;
 		if ((val < min_val) || (val > max_val))
-			err = BCME_RANGE;
+			err = -EINVAL;
 		break;
 	}
 
@@ -4708,24 +4356,6 @@
 #endif				/* defined(BCMDBG) */
 }
 
-static void
-wlc_ctrupd_cache(u16 cur_stat, u16 *macstat_snapshot, u32 *macstat)
-{
-	u16 v;
-	u16 delta;
-
-	v = le16_to_cpu(cur_stat);
-	delta = (u16)(v - *macstat_snapshot);
-
-	if (delta != 0) {
-		*macstat += delta;
-		*macstat_snapshot = v;
-	}
-}
-
-#define MACSTATUPD(name) \
-	wlc_ctrupd_cache(macstats.name, &wlc->core->macstat_snapshot->name, &wlc->pub->_cnt->name)
-
 void wlc_statsupd(struct wlc_info *wlc)
 {
 	int i;
@@ -4753,68 +4383,12 @@
 	wlc_bmac_copyfrom_shm(wlc->hw, M_UCODE_MACSTAT,
 			      &macstats, sizeof(macstat_t));
 
-	/* update mac stats */
-	MACSTATUPD(txallfrm);
-	MACSTATUPD(txrtsfrm);
-	MACSTATUPD(txctsfrm);
-	MACSTATUPD(txackfrm);
-	MACSTATUPD(txdnlfrm);
-	MACSTATUPD(txbcnfrm);
-	for (i = 0; i < NFIFO; i++)
-		MACSTATUPD(txfunfl[i]);
-	MACSTATUPD(txtplunfl);
-	MACSTATUPD(txphyerr);
-	MACSTATUPD(rxfrmtoolong);
-	MACSTATUPD(rxfrmtooshrt);
-	MACSTATUPD(rxinvmachdr);
-	MACSTATUPD(rxbadfcs);
-	MACSTATUPD(rxbadplcp);
-	MACSTATUPD(rxcrsglitch);
-	MACSTATUPD(rxstrt);
-	MACSTATUPD(rxdfrmucastmbss);
-	MACSTATUPD(rxmfrmucastmbss);
-	MACSTATUPD(rxcfrmucast);
-	MACSTATUPD(rxrtsucast);
-	MACSTATUPD(rxctsucast);
-	MACSTATUPD(rxackucast);
-	MACSTATUPD(rxdfrmocast);
-	MACSTATUPD(rxmfrmocast);
-	MACSTATUPD(rxcfrmocast);
-	MACSTATUPD(rxrtsocast);
-	MACSTATUPD(rxctsocast);
-	MACSTATUPD(rxdfrmmcast);
-	MACSTATUPD(rxmfrmmcast);
-	MACSTATUPD(rxcfrmmcast);
-	MACSTATUPD(rxbeaconmbss);
-	MACSTATUPD(rxdfrmucastobss);
-	MACSTATUPD(rxbeaconobss);
-	MACSTATUPD(rxrsptmout);
-	MACSTATUPD(bcntxcancl);
-	MACSTATUPD(rxf0ovfl);
-	MACSTATUPD(rxf1ovfl);
-	MACSTATUPD(rxf2ovfl);
-	MACSTATUPD(txsfovfl);
-	MACSTATUPD(pmqovfl);
-	MACSTATUPD(rxcgprqfrm);
-	MACSTATUPD(rxcgprsqovfl);
-	MACSTATUPD(txcgprsfail);
-	MACSTATUPD(txcgprssuc);
-	MACSTATUPD(prs_timeout);
-	MACSTATUPD(rxnack);
-	MACSTATUPD(frmscons);
-	MACSTATUPD(txnack);
-	MACSTATUPD(txglitch_nack);
-	MACSTATUPD(txburst);
-	MACSTATUPD(phywatchdog);
-	MACSTATUPD(pktengrxducast);
-	MACSTATUPD(pktengrxdmcast);
-
 #ifdef BCMDBG
 	/* check for rx fifo 0 overflow */
 	delta = (u16) (wlc->core->macstat_snapshot->rxf0ovfl - rxf0ovfl);
 	if (delta)
-		WL_ERROR("wl%d: %u rx fifo 0 overflows!\n",
-			 wlc->pub->unit, delta);
+		wiphy_err(wlc->wiphy, "wl%d: %u rx fifo 0 overflows!\n",
+			  wlc->pub->unit, delta);
 
 	/* check for tx fifo underflows */
 	for (i = 0; i < NFIFO; i++) {
@@ -4822,57 +4396,23 @@
 		    (u16) (wlc->core->macstat_snapshot->txfunfl[i] -
 			      txfunfl[i]);
 		if (delta)
-			WL_ERROR("wl%d: %u tx fifo %d underflows!\n",
-				 wlc->pub->unit, delta, i);
+			wiphy_err(wlc->wiphy, "wl%d: %u tx fifo %d underflows!"
+				  "\n", wlc->pub->unit, delta, i);
 	}
 #endif				/* BCMDBG */
 
-	/* dot11 counter update */
-
-	WLCNTSET(wlc->pub->_cnt->txrts,
-		 (wlc->pub->_cnt->rxctsucast -
-		  wlc->pub->_cnt->d11cnt_txrts_off));
-	WLCNTSET(wlc->pub->_cnt->rxcrc,
-		 (wlc->pub->_cnt->rxbadfcs - wlc->pub->_cnt->d11cnt_rxcrc_off));
-	WLCNTSET(wlc->pub->_cnt->txnocts,
-		 ((wlc->pub->_cnt->txrtsfrm - wlc->pub->_cnt->rxctsucast) -
-		  wlc->pub->_cnt->d11cnt_txnocts_off));
-
 	/* merge counters from dma module */
 	for (i = 0; i < NFIFO; i++) {
 		if (wlc->hw->di[i]) {
-			WLCNTADD(wlc->pub->_cnt->txnobuf,
-				 (wlc->hw->di[i])->txnobuf);
-			WLCNTADD(wlc->pub->_cnt->rxnobuf,
-				 (wlc->hw->di[i])->rxnobuf);
-			WLCNTADD(wlc->pub->_cnt->rxgiant,
-				 (wlc->hw->di[i])->rxgiants);
 			dma_counterreset(wlc->hw->di[i]);
 		}
 	}
-
-	/*
-	 * Aggregate transmit and receive errors that probably resulted
-	 * in the loss of a frame are computed on the fly.
-	 */
-	WLCNTSET(wlc->pub->_cnt->txerror,
-		 wlc->pub->_cnt->txnobuf + wlc->pub->_cnt->txnoassoc +
-		 wlc->pub->_cnt->txuflo + wlc->pub->_cnt->txrunt +
-		 wlc->pub->_cnt->dmade + wlc->pub->_cnt->dmada +
-		 wlc->pub->_cnt->dmape);
-	WLCNTSET(wlc->pub->_cnt->rxerror,
-		 wlc->pub->_cnt->rxoflo + wlc->pub->_cnt->rxnobuf +
-		 wlc->pub->_cnt->rxfragerr + wlc->pub->_cnt->rxrunt +
-		 wlc->pub->_cnt->rxgiant + wlc->pub->_cnt->rxnoscb +
-		 wlc->pub->_cnt->rxbadsrcmac);
-	for (i = 0; i < NFIFO; i++)
-		wlc->pub->_cnt->rxerror += wlc->pub->_cnt->rxuflo[i];
 }
 
 bool wlc_chipmatch(u16 vendor, u16 device)
 {
-	if (vendor != VENDOR_BROADCOM) {
-		WL_ERROR("wlc_chipmatch: unknown vendor id %04x\n", vendor);
+	if (vendor != PCI_VENDOR_ID_BROADCOM) {
+		pr_err("wlc_chipmatch: unknown vendor id %04x\n", vendor);
 		return false;
 	}
 
@@ -4884,7 +4424,7 @@
 	if ((device == BCM43236_D11N_ID) || (device == BCM43236_D11N2G_ID))
 		return true;
 
-	WL_ERROR("wlc_chipmatch: unknown device id %04x\n", device);
+	pr_err("wlc_chipmatch: unknown device id %04x\n", device);
 	return false;
 }
 
@@ -4923,7 +4463,9 @@
 	char hexbuf[256];
 
 	/* add plcp header along with txh descriptor */
-	prhex("Raw TxDesc + plcp header", (unsigned char *) txh, sizeof(d11txh_t) + 48);
+	printk(KERN_DEBUG "Raw TxDesc + plcp header:\n");
+	print_hex_dump_bytes("", DUMP_PREFIX_OFFSET,
+			     txh, sizeof(d11txh_t) + 48);
 
 	printk(KERN_DEBUG "TxCtlLow: %04x ", mtcl);
 	printk(KERN_DEBUG "TxCtlHigh: %04x ", mtch);
@@ -4994,7 +4536,8 @@
 		{0, NULL}
 	};
 
-	prhex("Raw RxDesc", (unsigned char *) rxh, sizeof(d11rxhdr_t));
+	printk(KERN_DEBUG "Raw RxDesc:\n");
+	print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, rxh, sizeof(d11rxhdr_t));
 
 	bcm_format_flags(macstat_flags, macstatus1, flagstr, 64);
 
@@ -5033,8 +4576,6 @@
 		}
 	}
 	*p = '\0';
-	ASSERT(p < endp);
-
 	return (int)(p - buf);
 }
 #endif				/* defined(BCMDBG) */
@@ -5055,13 +4596,13 @@
  *
  * Returns true if packet consumed (queued), false if not.
  */
-bool BCMFASTPATH
+bool
 wlc_prec_enq(struct wlc_info *wlc, struct pktq *q, void *pkt, int prec)
 {
 	return wlc_prec_enq_head(wlc, q, pkt, prec, false);
 }
 
-bool BCMFASTPATH
+bool
 wlc_prec_enq_head(struct wlc_info *wlc, struct pktq *q, struct sk_buff *pkt,
 		  int prec, bool head)
 {
@@ -5072,11 +4613,10 @@
 	if (pktq_pfull(q, prec))
 		eprec = prec;
 	else if (pktq_full(q)) {
-		p = pktq_peek_tail(q, &eprec);
-		ASSERT(p != NULL);
+		p = bcm_pktq_peek_tail(q, &eprec);
 		if (eprec > prec) {
-			WL_ERROR("%s: Failing: eprec %d > prec %d\n",
-				 __func__, eprec, prec);
+			wiphy_err(wlc->wiphy, "%s: Failing: eprec %d > prec %d"
+				  "\n", __func__, eprec, prec);
 			return false;
 		}
 	}
@@ -5085,69 +4625,51 @@
 	if (eprec >= 0) {
 		bool discard_oldest;
 
-		/* Detect queueing to unconfigured precedence */
-		ASSERT(!pktq_pempty(q, eprec));
-
 		discard_oldest = AC_BITMAP_TST(wlc->wme_dp, eprec);
 
 		/* Refuse newer packet unless configured to discard oldest */
 		if (eprec == prec && !discard_oldest) {
-			WL_ERROR("%s: No where to go, prec == %d\n",
-				 __func__, prec);
+			wiphy_err(wlc->wiphy, "%s: No where to go, prec == %d"
+				  "\n", __func__, prec);
 			return false;
 		}
 
 		/* Evict packet according to discard policy */
-		p = discard_oldest ? pktq_pdeq(q, eprec) : pktq_pdeq_tail(q,
-									  eprec);
-		ASSERT(p != NULL);
-
-		/* Increment wme stats */
-		if (WME_ENAB(wlc->pub)) {
-			WLCNTINCR(wlc->pub->_wme_cnt->
-				  tx_failed[WME_PRIO2AC(p->priority)].packets);
-			WLCNTADD(wlc->pub->_wme_cnt->
-				 tx_failed[WME_PRIO2AC(p->priority)].bytes,
-				 pkttotlen(p));
-		}
-		pkt_buf_free_skb(p);
-		wlc->pub->_cnt->txnobuf++;
+		p = discard_oldest ? bcm_pktq_pdeq(q, eprec) :
+			bcm_pktq_pdeq_tail(q, eprec);
+		bcm_pkt_buf_free_skb(p);
 	}
 
 	/* Enqueue */
 	if (head)
-		p = pktq_penq_head(q, prec, pkt);
+		p = bcm_pktq_penq_head(q, prec, pkt);
 	else
-		p = pktq_penq(q, prec, pkt);
-	ASSERT(p != NULL);
+		p = bcm_pktq_penq(q, prec, pkt);
 
 	return true;
 }
 
-void BCMFASTPATH wlc_txq_enq(void *ctx, struct scb *scb, struct sk_buff *sdu,
+void wlc_txq_enq(void *ctx, struct scb *scb, struct sk_buff *sdu,
 			     uint prec)
 {
 	struct wlc_info *wlc = (struct wlc_info *) ctx;
-	struct wlc_txq_info *qi = wlc->active_queue;	/* Check me */
+	struct wlc_txq_info *qi = wlc->pkt_queue;	/* Check me */
 	struct pktq *q = &qi->q;
 	int prio;
 
 	prio = sdu->priority;
 
-	ASSERT(pktq_max(q) >= wlc->pub->tunables->datahiwat);
-
 	if (!wlc_prec_enq(wlc, q, sdu, prec)) {
 		if (!EDCF_ENAB(wlc->pub)
 		    || (wlc->pub->wlfeatureflag & WL_SWFL_FLOWCONTROL))
-			WL_ERROR("wl%d: wlc_txq_enq: txq overflow\n",
-				 wlc->pub->unit);
+			wiphy_err(wlc->wiphy, "wl%d: wlc_txq_enq: txq overflow"
+				  "\n", wlc->pub->unit);
 
 		/*
 		 * XXX we might hit this condtion in case
 		 * packet flooding from mac80211 stack
 		 */
-		pkt_buf_free_skb(sdu);
-		wlc->pub->_cnt->txnobuf++;
+		bcm_pkt_buf_free_skb(sdu);
 	}
 
 	/* Check if flow control needs to be turned on after enqueuing the packet
@@ -5167,7 +4689,7 @@
 	}
 }
 
-bool BCMFASTPATH
+bool
 wlc_sendpkt_mac80211(struct wlc_info *wlc, struct sk_buff *sdu,
 		     struct ieee80211_hw *hw)
 {
@@ -5177,43 +4699,30 @@
 	struct scb *scb = &global_scb;
 	struct ieee80211_hdr *d11_header = (struct ieee80211_hdr *)(sdu->data);
 
-	ASSERT(sdu);
-
 	/* 802.11 standard requires management traffic to go at highest priority */
 	prio = ieee80211_is_data(d11_header->frame_control) ? sdu->priority :
 		MAXPRIO;
 	fifo = prio2fifo[prio];
-
-	ASSERT((uint) skb_headroom(sdu) >= TXOFF);
-	ASSERT(!(sdu->next));
-	ASSERT(!(sdu->prev));
-	ASSERT(fifo < NFIFO);
-
 	pkt = sdu;
 	if (unlikely
 	    (wlc_d11hdrs_mac80211(wlc, hw, pkt, scb, 0, 1, fifo, 0, NULL, 0)))
 		return -EINVAL;
 	wlc_txq_enq(wlc, scb, pkt, WLC_PRIO_TO_PREC(prio));
-	wlc_send_q(wlc, wlc->active_queue);
-
-	wlc->pub->_cnt->ieee_tx++;
+	wlc_send_q(wlc);
 	return 0;
 }
 
-void BCMFASTPATH wlc_send_q(struct wlc_info *wlc, struct wlc_txq_info *qi)
+void wlc_send_q(struct wlc_info *wlc)
 {
 	struct sk_buff *pkt[DOT11_MAXNUMFRAGS];
 	int prec;
 	u16 prec_map;
 	int err = 0, i, count;
 	uint fifo;
+	struct wlc_txq_info *qi = wlc->pkt_queue;
 	struct pktq *q = &qi->q;
 	struct ieee80211_tx_info *tx_info;
 
-	/* only do work for the active queue */
-	if (qi != wlc->active_queue)
-		return;
-
 	if (in_send_q)
 		return;
 	else
@@ -5224,7 +4733,7 @@
 	/* Send all the enq'd pkts that we can.
 	 * Dequeue packets with precedence with empty HW fifo only
 	 */
-	while (prec_map && (pkt[0] = pktq_mdeq(q, prec_map, &prec))) {
+	while (prec_map && (pkt[0] = bcm_pktq_mdeq(q, prec_map, &prec))) {
 		tx_info = IEEE80211_SKB_CB(pkt[0]);
 		if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) {
 			err = wlc_sendampdu(wlc->ampdu, qi, pkt, prec);
@@ -5238,8 +4747,8 @@
 			}
 		}
 
-		if (err == BCME_BUSY) {
-			pktq_penq_head(q, prec, pkt[0]);
+		if (err == -EBUSY) {
+			bcm_pktq_penq_head(q, prec, pkt[0]);
 			/* If send failed due to any other reason than a change in
 			 * HW FIFO condition, quit. Otherwise, read the new prec_map!
 			 */
@@ -5290,14 +4799,13 @@
 	return frameid;
 }
 
-void BCMFASTPATH
+void
 wlc_txfifo(struct wlc_info *wlc, uint fifo, struct sk_buff *p, bool commit,
 	   s8 txpktpend)
 {
 	u16 frameid = INVALIDFID;
 	d11txh_t *txh;
 
-	ASSERT(fifo < NFIFO);
 	txh = (d11txh_t *) (p->data);
 
 	/* When a BC/MC frame is being committed to the BCMC fifo via DMA (NOT PIO), update
@@ -5317,7 +4825,7 @@
 	 */
 	if (commit) {
 		TXPKTPENDINC(wlc, fifo, txpktpend);
-		WL_TRACE("wlc_txfifo, pktpend inc %d to %d\n",
+		BCMMSG(wlc->wiphy, "pktpend inc %d to %d\n",
 			 txpktpend, TXPKTPENDGET(wlc, fifo));
 	}
 
@@ -5326,57 +4834,11 @@
 		BCMCFID(wlc, frameid);
 
 	if (dma_txfast(wlc->hw->di[fifo], p, commit) < 0) {
-		WL_ERROR("wlc_txfifo: fatal, toss frames !!!\n");
-	}
-}
-
-static u16
-wlc_compute_airtime(struct wlc_info *wlc, ratespec_t rspec, uint length)
-{
-	u16 usec = 0;
-	uint mac_rate = RSPEC2RATE(rspec);
-	uint nsyms;
-
-	if (IS_MCS(rspec)) {
-		/* not supported yet */
-		ASSERT(0);
-	} else if (IS_OFDM(rspec)) {
-		/* nsyms = Ceiling(Nbits / (Nbits/sym))
-		 *
-		 * Nbits = length * 8
-		 * Nbits/sym = Mbps * 4 = mac_rate * 2
-		 */
-		nsyms = CEIL((length * 8), (mac_rate * 2));
-
-		/* usec = symbols * usec/symbol */
-		usec = (u16) (nsyms * APHY_SYMBOL_TIME);
-		return usec;
-	} else {
-		switch (mac_rate) {
-		case WLC_RATE_1M:
-			usec = length << 3;
-			break;
-		case WLC_RATE_2M:
-			usec = length << 2;
-			break;
-		case WLC_RATE_5M5:
-			usec = (length << 4) / 11;
-			break;
-		case WLC_RATE_11M:
-			usec = (length << 3) / 11;
-			break;
-		default:
-			WL_ERROR("wl%d: wlc_compute_airtime: unsupported rspec 0x%x\n",
-				 wlc->pub->unit, rspec);
-			ASSERT((const char *)"Bad phy_rate" == NULL);
-			break;
-		}
+		wiphy_err(wlc->wiphy, "wlc_txfifo: fatal, toss frames !!!\n");
 	}
-
-	return usec;
 }
 
-void BCMFASTPATH
+void
 wlc_compute_plcp(struct wlc_info *wlc, ratespec_t rspec, uint length, u8 *plcp)
 {
 	if (IS_MCS(rspec)) {
@@ -5384,7 +4846,7 @@
 	} else if (IS_OFDM(rspec)) {
 		wlc_compute_ofdm_plcp(rspec, length, plcp);
 	} else {
-		wlc_compute_cck_plcp(rspec, length, plcp);
+		wlc_compute_cck_plcp(wlc, rspec, length, plcp);
 	}
 	return;
 }
@@ -5393,7 +4855,6 @@
 static void wlc_compute_mimo_plcp(ratespec_t rspec, uint length, u8 *plcp)
 {
 	u8 mcs = (u8) (rspec & RSPEC_RATE_MASK);
-	ASSERT(IS_MCS(rspec));
 	plcp[0] = mcs;
 	if (RSPEC_IS40MHZ(rspec) || (mcs == 32))
 		plcp[0] |= MIMO_PLCP_40MHZ;
@@ -5405,19 +4866,15 @@
 }
 
 /* Rate: 802.11 rate code, length: PSDU length in octets */
-static void BCMFASTPATH
+static void
 wlc_compute_ofdm_plcp(ratespec_t rspec, u32 length, u8 *plcp)
 {
 	u8 rate_signal;
 	u32 tmp = 0;
 	int rate = RSPEC2RATE(rspec);
 
-	ASSERT(IS_OFDM(rspec));
-
 	/* encode rate per 802.11a-1999 sec 17.3.4.1, with lsb transmitted first */
-	rate_signal = rate_info[rate] & RATE_MASK;
-	ASSERT(rate_signal != 0);
-
+	rate_signal = rate_info[rate] & WLC_RATE_MASK;
 	memset(plcp, 0, D11_PHY_HDR_LEN);
 	D11A_PHY_HDR_SRATE((ofdm_phy_hdr_t *) plcp, rate_signal);
 
@@ -5436,7 +4893,8 @@
  * Broken out for PRQ.
  */
 
-static void wlc_cck_plcp_set(int rate_500, uint length, u8 *plcp)
+static void wlc_cck_plcp_set(struct wlc_info *wlc, int rate_500, uint length,
+			     u8 *plcp)
 {
 	u16 usec = 0;
 	u8 le = 0;
@@ -5463,7 +4921,8 @@
 		break;
 
 	default:
-		WL_ERROR("wlc_cck_plcp_set: unsupported rate %d\n", rate_500);
+		wiphy_err(wlc->wiphy, "wlc_cck_plcp_set: unsupported rate %d"
+			  "\n", rate_500);
 		rate_500 = WLC_RATE_1M;
 		usec = length << 3;
 		break;
@@ -5481,13 +4940,12 @@
 }
 
 /* Rate: 802.11 rate code, length: PSDU length in octets */
-static void wlc_compute_cck_plcp(ratespec_t rspec, uint length, u8 *plcp)
+static void wlc_compute_cck_plcp(struct wlc_info *wlc, ratespec_t rspec,
+				 uint length, u8 *plcp)
 {
 	int rate = RSPEC2RATE(rspec);
 
-	ASSERT(IS_CCK(rspec));
-
-	wlc_cck_plcp_set(rate, length, plcp);
+	wlc_cck_plcp_set(wlc, rate, length, plcp);
 }
 
 /* wlc_compute_frame_dur()
@@ -5500,7 +4958,7 @@
  * next_frag_len	next MPDU length in bytes
  * preamble_type	use short/GF or long/MM PLCP header
  */
-static u16 BCMFASTPATH
+static u16
 wlc_compute_frame_dur(struct wlc_info *wlc, ratespec_t rate, u8 preamble_type,
 		      uint next_frag_len)
 {
@@ -5534,7 +4992,7 @@
  * rate			next MPDU rate in unit of 500kbps
  * frame_len		next MPDU frame length in bytes
  */
-u16 BCMFASTPATH
+u16
 wlc_compute_rtscts_dur(struct wlc_info *wlc, bool cts_only, ratespec_t rts_rate,
 		       ratespec_t frame_rate, u8 rts_preamble_type,
 		       u8 frame_preamble_type, uint frame_len, bool ba)
@@ -5566,33 +5024,7 @@
 	return dur;
 }
 
-static bool wlc_phy_rspec_check(struct wlc_info *wlc, u16 bw, ratespec_t rspec)
-{
-	if (IS_MCS(rspec)) {
-		uint mcs = rspec & RSPEC_RATE_MASK;
-
-		if (mcs < 8) {
-			ASSERT(RSPEC_STF(rspec) < PHY_TXC1_MODE_SDM);
-		} else if ((mcs >= 8) && (mcs <= 23)) {
-			ASSERT(RSPEC_STF(rspec) == PHY_TXC1_MODE_SDM);
-		} else if (mcs == 32) {
-			ASSERT(RSPEC_STF(rspec) < PHY_TXC1_MODE_SDM);
-			ASSERT(bw == PHY_TXC1_BW_40MHZ_DUP);
-		}
-	} else if (IS_OFDM(rspec)) {
-		ASSERT(RSPEC_STF(rspec) < PHY_TXC1_MODE_STBC);
-	} else {
-		ASSERT(IS_CCK(rspec));
-
-		ASSERT((bw == PHY_TXC1_BW_20MHZ)
-		       || (bw == PHY_TXC1_BW_20MHZ_UP));
-		ASSERT(RSPEC_STF(rspec) == PHY_TXC1_MODE_SISO);
-	}
-
-	return true;
-}
-
-u16 BCMFASTPATH wlc_phytxctl1_calc(struct wlc_info *wlc, ratespec_t rspec)
+u16 wlc_phytxctl1_calc(struct wlc_info *wlc, ratespec_t rspec)
 {
 	u16 phyctl1 = 0;
 	u16 bw;
@@ -5603,12 +5035,10 @@
 		bw = RSPEC_GET_BW(rspec);
 		/* 10Mhz is not supported yet */
 		if (bw < PHY_TXC1_BW_20MHZ) {
-			WL_ERROR("wlc_phytxctl1_calc: bw %d is not supported yet, set to 20L\n",
-				 bw);
+			wiphy_err(wlc->wiphy, "wlc_phytxctl1_calc: bw %d is "
+				  "not supported yet, set to 20L\n", bw);
 			bw = PHY_TXC1_BW_20MHZ;
 		}
-
-		wlc_phy_rspec_check(wlc, bw, rspec);
 	}
 
 	if (IS_MCS(rspec)) {
@@ -5629,8 +5059,8 @@
 		/* get the phyctl byte from rate phycfg table */
 		phycfg = wlc_rate_legacy_phyctl(RSPEC2RATE(rspec));
 		if (phycfg == -1) {
-			WL_ERROR("wlc_phytxctl1_calc: wrong legacy OFDM/CCK rate\n");
-			ASSERT(0);
+			wiphy_err(wlc->wiphy, "wlc_phytxctl1_calc: wrong "
+				  "legacy OFDM/CCK rate\n");
 			phycfg = 0;
 		}
 		/* set the upper byte of phyctl1 */
@@ -5638,18 +5068,10 @@
 		    (bw | (phycfg << 8) |
 		     (RSPEC_STF(rspec) << PHY_TXC1_MODE_SHIFT));
 	}
-
-#ifdef BCMDBG
-	/* phy clock must support 40Mhz if tx descriptor uses it */
-	if ((phyctl1 & PHY_TXC1_BW_MASK) >= PHY_TXC1_BW_40MHZ) {
-		ASSERT(CHSPEC_WLC_BW(wlc->chanspec) == WLC_40_MHZ);
-		ASSERT(wlc->chanspec == wlc_phy_chanspec_get(wlc->band->pi));
-	}
-#endif				/* BCMDBG */
 	return phyctl1;
 }
 
-ratespec_t BCMFASTPATH
+ratespec_t
 wlc_rspec_to_rts_rspec(struct wlc_info *wlc, ratespec_t rspec, bool use_rspec,
 		       u16 mimo_ctlchbw)
 {
@@ -5705,7 +5127,7 @@
  * headroom == D11_PHY_HDR_LEN + D11_TXH_LEN (D11_TXH_LEN is now 104 bytes)
  *
  */
-static u16 BCMFASTPATH
+static u16
 wlc_d11hdrs_mac80211(struct wlc_info *wlc, struct ieee80211_hw *hw,
 		     struct sk_buff *p, struct scb *scb, uint frag,
 		     uint nfrags, uint queue, uint next_frag_len,
@@ -5744,14 +5166,12 @@
 	u16 mimo_txbw;
 	u8 mimo_preamble_type;
 
-	ASSERT(queue < NFIFO);
-
 	/* locate 802.11 MAC header */
 	h = (struct ieee80211_hdr *)(p->data);
 	qos = ieee80211_is_data_qos(h->frame_control);
 
 	/* compute length of frame in bytes for use in PLCP computations */
-	len = pkttotlen(p);
+	len = bcm_pkttotlen(p);
 	phylen = len + FCS_LEN;
 
 	/* If WEP enabled, add room in phylen for the additional bytes of
@@ -5765,7 +5185,6 @@
 
 	/* Get tx_info */
 	tx_info = IEEE80211_SKB_CB(p);
-	ASSERT(tx_info);
 
 	/* add PLCP */
 	plcp = skb_push(p, D11_PHY_HDR_LEN);
@@ -5777,10 +5196,9 @@
 	/* setup frameid */
 	if (tx_info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) {
 		/* non-AP STA should never use BCMC queue */
-		ASSERT(queue != TX_BCMC_FIFO);
 		if (queue == TX_BCMC_FIFO) {
-			WL_ERROR("wl%d: %s: ASSERT queue == TX_BCMC!\n",
-				 WLCWLUNIT(wlc), __func__);
+			wiphy_err(wlc->wiphy, "wl%d: %s: ASSERT queue == "
+				  "TX_BCMC!\n", WLCWLUNIT(wlc), __func__);
 			frameid = bcmc_fid_generate(wlc, NULL, txh);
 		} else {
 			/* Increment the counter for first fragment */
@@ -5803,13 +5221,9 @@
 	if (SCB_PS(scb) || ieee80211_is_beacon(h->frame_control))
 		mcl |= TXC_IGNOREPMQ;
 
-	ASSERT(hw->max_rates <= IEEE80211_TX_MAX_RATES);
-	ASSERT(hw->max_rates == 2);
-
 	txrate[0] = tx_info->control.rates;
 	txrate[1] = txrate[0] + 1;
 
-	ASSERT(txrate[0]->idx >= 0);
 	/* if rate control algorithm didn't give us a fallback rate, use the primary rate */
 	if (txrate[1]->idx < 0) {
 		txrate[1] = txrate[0];
@@ -5819,7 +5233,6 @@
 		is_mcs[k] =
 		    txrate[k]->flags & IEEE80211_TX_RC_MCS ? true : false;
 		if (!is_mcs[k]) {
-			ASSERT(!(tx_info->flags & IEEE80211_TX_CTL_AMPDU));
 			if ((txrate[k]->idx >= 0)
 			    && (txrate[k]->idx <
 				hw->wiphy->bands[tx_info->band]->n_bitrates)) {
@@ -5831,10 +5244,6 @@
 				    flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE ?
 				    true : false;
 			} else {
-				ASSERT((txrate[k]->idx >= 0) &&
-				       (txrate[k]->idx <
-					hw->wiphy->bands[tx_info->band]->
-					n_bitrates));
 				rate_val[k] = WLC_RATE_1M;
 			}
 		} else {
@@ -5857,7 +5266,6 @@
 
 		/* (1) RATE: determine and validate primary rate and fallback rates */
 		if (!RSPEC_ACTIVE(rspec[k])) {
-			ASSERT(RSPEC_ACTIVE(rspec[k]));
 			rspec[k] = WLC_RATE_1M;
 		} else {
 			if (!is_multicast_ether_addr(h->addr1)) {
@@ -5885,7 +5293,6 @@
 				    && WLC_STF_SS_STBC_TX(wlc, scb)) {
 					u8 stc;
 
-					ASSERT(WLC_STBC_CAP_PHY(wlc));
 					stc = 1;	/* Nss for single stream is always 1 */
 					rspec[k] |=
 					    (PHY_TXC1_MODE_STBC <<
@@ -5918,7 +5325,6 @@
 					if (wlc->ofdm_40txbw != AUTO)
 						mimo_txbw = wlc->ofdm_40txbw;
 				} else {
-					ASSERT(IS_CCK(rspec[k]));
 					if (wlc->cck_40txbw != AUTO)
 						mimo_txbw = wlc->cck_40txbw;
 				}
@@ -5957,9 +5363,9 @@
 
 			if ((txrate[k]->flags & IEEE80211_TX_RC_MCS)
 			    && (!IS_MCS(rspec[k]))) {
-				WL_ERROR("wl%d: %s: IEEE80211_TX_RC_MCS != IS_MCS(rspec)\n",
-					 WLCWLUNIT(wlc), __func__);
-				ASSERT(0 && "Rate mismatch");
+				wiphy_err(wlc->wiphy, "wl%d: %s: IEEE80211_TX_"
+					  "RC_MCS != IS_MCS(rspec)\n",
+					  WLCWLUNIT(wlc), __func__);
 			}
 
 			if (IS_MCS(rspec[k])) {
@@ -5973,22 +5379,15 @@
 				}
 			}
 
-			/* mimo bw field MUST now be valid in the rspec (it affects duration calculations) */
-			ASSERT(VALID_RATE_DBG(wlc, rspec[0]));
-
 			/* should be better conditionalized */
 			if (!IS_MCS(rspec[0])
 			    && (tx_info->control.rates[0].
 				flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE))
 				preamble_type[k] = WLC_SHORT_PREAMBLE;
-
-			ASSERT(!IS_MCS(rspec[0])
-			       || WLC_IS_MIMO_PREAMBLE(preamble_type[k]));
 		}
 	} else {
 		for (k = 0; k < hw->max_rates; k++) {
 			/* Set ctrlchbw as 20Mhz */
-			ASSERT(!IS_MCS(rspec[k]));
 			rspec[k] &= ~RSPEC_BW_MASK;
 			rspec[k] |= (PHY_TXC1_BW_20MHZ << RSPEC_BW_SHIFT);
 
@@ -6080,8 +5479,6 @@
 	/* Set fallback rate preamble type */
 	if ((preamble_type[1] == WLC_SHORT_PREAMBLE) ||
 	    (preamble_type[1] == WLC_GF_PREAMBLE)) {
-		ASSERT((preamble_type[1] == WLC_GF_PREAMBLE) ||
-		       (!IS_MCS(rspec[1])));
 		if (RSPEC2RATE(rspec[1]) != WLC_RATE_1M)
 			mch |= TXC_PREAMBLE_DATA_FB_SHORT;
 	}
@@ -6146,7 +5543,6 @@
 		}
 
 		/* RTS PLCP header */
-		ASSERT(IS_ALIGNED((unsigned long)txh->RTSPhyHeader, sizeof(u16)));
 		rts_plcp = txh->RTSPhyHeader;
 		if (use_cts)
 			rts_phylen = DOT11_CTS_LEN + FCS_LEN;
@@ -6229,11 +5625,8 @@
 	phyctl = FRAMETYPE(rspec[0], wlc->mimoft);
 	if ((preamble_type[0] == WLC_SHORT_PREAMBLE) ||
 	    (preamble_type[0] == WLC_GF_PREAMBLE)) {
-		ASSERT((preamble_type[0] == WLC_GF_PREAMBLE)
-		       || !IS_MCS(rspec[0]));
 		if (RSPEC2RATE(rspec[0]) != WLC_RATE_1M)
 			phyctl |= PHY_TXC_SHORT_HDR;
-		wlc->pub->_cnt->txprshort++;
 	}
 
 	/* phytxant is properly bit shifted */
@@ -6274,21 +5667,10 @@
 		}
 	}
 
-	if (IS_MCS(rspec[0]))
-		ASSERT(IS_MCS(rspec[1]));
-
-	ASSERT(!IS_MCS(rspec[0]) ||
-	       ((preamble_type[0] == WLC_MM_PREAMBLE) == (txh->MModeLen != 0)));
-	ASSERT(!IS_MCS(rspec[1]) ||
-	       ((preamble_type[1] == WLC_MM_PREAMBLE) ==
-		(txh->MModeFbrLen != 0)));
-
 	ac = skb_get_queue_mapping(p);
 	if (SCB_WME(scb) && qos && wlc->edcf_txop[ac]) {
 		uint frag_dur, dur, dur_fallback;
 
-		ASSERT(!is_multicast_ether_addr(h->addr1));
-
 		/* WME: Update TXOP threshold */
 		if ((!(tx_info->flags & IEEE80211_TX_CTL_AMPDU)) && (frag == 0)) {
 			frag_dur =
@@ -6359,16 +5741,18 @@
 					}
 				}
 			} else
-				WL_ERROR("wl%d: %s txop invalid for rate %d\n",
-					 wlc->pub->unit, fifo_names[queue],
-					 RSPEC2RATE(rspec[0]));
+				wiphy_err(wlc->wiphy, "wl%d: %s txop invalid "
+					  "for rate %d\n",
+					  wlc->pub->unit, fifo_names[queue],
+					  RSPEC2RATE(rspec[0]));
 
 			if (dur > wlc->edcf_txop[ac])
-				WL_ERROR("wl%d: %s: %s txop exceeded phylen %d/%d dur %d/%d\n",
-					 wlc->pub->unit, __func__,
-					 fifo_names[queue],
-					 phylen, wlc->fragthresh[queue],
-					 dur, wlc->edcf_txop[ac]);
+				wiphy_err(wlc->wiphy, "wl%d: %s: %s txop "
+					  "exceeded phylen %d/%d dur %d/%d\n",
+					  wlc->pub->unit, __func__,
+					  fifo_names[queue],
+					  phylen, wlc->fragthresh[queue],
+					  dur, wlc->edcf_txop[ac]);
 		}
 	}
 
@@ -6379,8 +5763,6 @@
 {
 	struct wlc_bsscfg *cfg = wlc->cfg;
 
-	wlc->pub->_cnt->tbtt++;
-
 	if (BSSCFG_STA(cfg)) {
 		/* run watchdog here if the watchdog timer is not armed */
 		if (WLC_WATCHDOG_TBTT(wlc)) {
@@ -6410,127 +5792,6 @@
 	}
 }
 
-/* GP timer is a freerunning 32 bit counter, decrements at 1 us rate */
-void wlc_hwtimer_gptimer_set(struct wlc_info *wlc, uint us)
-{
-	W_REG(&wlc->regs->gptimer, us);
-}
-
-void wlc_hwtimer_gptimer_abort(struct wlc_info *wlc)
-{
-	W_REG(&wlc->regs->gptimer, 0);
-}
-
-static void wlc_hwtimer_gptimer_cb(struct wlc_info *wlc)
-{
-	/* when interrupt is generated, the counter is loaded with last value
-	 * written and continue to decrement. So it has to be cleaned first
-	 */
-	W_REG(&wlc->regs->gptimer, 0);
-}
-
-/*
- * This fn has all the high level dpc processing from wlc_dpc.
- * POLICY: no macinstatus change, no bounding loop.
- *         All dpc bounding should be handled in BMAC dpc, like txstatus and rxint
- */
-void wlc_high_dpc(struct wlc_info *wlc, u32 macintstatus)
-{
-	d11regs_t *regs = wlc->regs;
-#ifdef BCMDBG
-	char flagstr[128];
-	static const bcm_bit_desc_t int_flags[] = {
-		{MI_MACSSPNDD, "MACSSPNDD"},
-		{MI_BCNTPL, "BCNTPL"},
-		{MI_TBTT, "TBTT"},
-		{MI_BCNSUCCESS, "BCNSUCCESS"},
-		{MI_BCNCANCLD, "BCNCANCLD"},
-		{MI_ATIMWINEND, "ATIMWINEND"},
-		{MI_PMQ, "PMQ"},
-		{MI_NSPECGEN_0, "NSPECGEN_0"},
-		{MI_NSPECGEN_1, "NSPECGEN_1"},
-		{MI_MACTXERR, "MACTXERR"},
-		{MI_NSPECGEN_3, "NSPECGEN_3"},
-		{MI_PHYTXERR, "PHYTXERR"},
-		{MI_PME, "PME"},
-		{MI_GP0, "GP0"},
-		{MI_GP1, "GP1"},
-		{MI_DMAINT, "DMAINT"},
-		{MI_TXSTOP, "TXSTOP"},
-		{MI_CCA, "CCA"},
-		{MI_BG_NOISE, "BG_NOISE"},
-		{MI_DTIM_TBTT, "DTIM_TBTT"},
-		{MI_PRQ, "PRQ"},
-		{MI_PWRUP, "PWRUP"},
-		{MI_RFDISABLE, "RFDISABLE"},
-		{MI_TFS, "TFS"},
-		{MI_PHYCHANGED, "PHYCHANGED"},
-		{MI_TO, "TO"},
-		{0, NULL}
-	};
-
-	if (macintstatus & ~(MI_TBTT | MI_TXSTOP)) {
-		bcm_format_flags(int_flags, macintstatus, flagstr,
-				 sizeof(flagstr));
-		WL_TRACE("wl%d: macintstatus 0x%x %s\n",
-			 wlc->pub->unit, macintstatus, flagstr);
-	}
-#endif				/* BCMDBG */
-
-	if (macintstatus & MI_PRQ) {
-		/* Process probe request FIFO */
-		ASSERT(0 && "PRQ Interrupt in non-MBSS");
-	}
-
-	/* TBTT indication */
-	/* ucode only gives either TBTT or DTIM_TBTT, not both */
-	if (macintstatus & (MI_TBTT | MI_DTIM_TBTT))
-		wlc_tbtt(wlc, regs);
-
-	if (macintstatus & MI_GP0) {
-		WL_ERROR("wl%d: PSM microcode watchdog fired at %d (seconds). Resetting.\n",
-			 wlc->pub->unit, wlc->pub->now);
-
-		printk_once("%s : PSM Watchdog, chipid 0x%x, chiprev 0x%x\n",
-					__func__, wlc->pub->sih->chip,
-					wlc->pub->sih->chiprev);
-
-		wlc->pub->_cnt->psmwds++;
-
-		/* big hammer */
-		wl_init(wlc->wl);
-	}
-
-	/* gptimer timeout */
-	if (macintstatus & MI_TO) {
-		wlc_hwtimer_gptimer_cb(wlc);
-	}
-
-	if (macintstatus & MI_RFDISABLE) {
-		WL_ERROR("wl%d: MAC Detected a change on the RF Disable Input 0x%x\n",
-			 wlc->pub->unit,
-			 R_REG(&regs->phydebug) & PDBG_RFD);
-		/* delay the cleanup to wl_down in IBSS case */
-		if ((R_REG(&regs->phydebug) & PDBG_RFD)) {
-			int idx;
-			struct wlc_bsscfg *bsscfg;
-			FOREACH_BSS(wlc, idx, bsscfg) {
-				if (!BSSCFG_STA(bsscfg) || !bsscfg->enable
-				    || !bsscfg->BSS)
-					continue;
-				WL_ERROR("wl%d: wlc_dpc: rfdisable -> wlc_bsscfg_disable()\n",
-					 wlc->pub->unit);
-			}
-		}
-	}
-
-	/* send any enq'd tx packets. Just makes sure to jump start tx */
-	if (!pktq_empty(&wlc->active_queue->q))
-		wlc_send_q(wlc, wlc->active_queue);
-
-	ASSERT(wlc_ps_check(wlc));
-}
-
 static void wlc_war16165(struct wlc_info *wlc, bool tx)
 {
 	if (tx) {
@@ -6546,7 +5807,7 @@
 
 /* process an individual tx_status_t */
 /* WLC_HIGH_API */
-bool BCMFASTPATH
+bool
 wlc_dotxstatus(struct wlc_info *wlc, tx_status_t *txs, u32 frm_tx2)
 {
 	struct sk_buff *p;
@@ -6572,16 +5833,12 @@
 	 */
 	if (!(txs->status & TX_STATUS_AMPDU)
 	    && (txs->status & TX_STATUS_INTERMEDIATE)) {
-		WLCNTADD(wlc->pub->_cnt->txnoack,
-			 ((txs->
-			   status & TX_STATUS_FRM_RTX_MASK) >>
-			  TX_STATUS_FRM_RTX_SHIFT));
-		WL_ERROR("%s: INTERMEDIATE but not AMPDU\n", __func__);
+		wiphy_err(wlc->wiphy, "%s: INTERMEDIATE but not AMPDU\n",
+			  __func__);
 		return false;
 	}
 
 	queue = txs->frameid & TXFID_QUEUE_MASK;
-	ASSERT(queue < NFIFO);
 	if (queue >= NFIFO) {
 		p = NULL;
 		goto fatal;
@@ -6598,41 +5855,31 @@
 
 	if (txs->phyerr) {
 		if (WL_ERROR_ON()) {
-			WL_ERROR("phyerr 0x%x, rate 0x%x\n",
-				 txs->phyerr, txh->MainRates);
+			wiphy_err(wlc->wiphy, "phyerr 0x%x, rate 0x%x\n",
+				  txs->phyerr, txh->MainRates);
 			wlc_print_txdesc(txh);
 		}
 		wlc_print_txstatus(txs);
 	}
 
-	ASSERT(txs->frameid == cpu_to_le16(txh->TxFrameID));
 	if (txs->frameid != cpu_to_le16(txh->TxFrameID))
 		goto fatal;
-
 	tx_info = IEEE80211_SKB_CB(p);
 	h = (struct ieee80211_hdr *)((u8 *) (txh + 1) + D11_PHY_HDR_LEN);
 
 	if (tx_info->control.sta)
 		scb = (struct scb *)tx_info->control.sta->drv_priv;
 
-	if (N_ENAB(wlc->pub)) {
-		u8 *plcp = (u8 *) (txh + 1);
-		if (PLCP3_ISSGI(plcp[3]))
-			wlc->pub->_cnt->txmpdu_sgi++;
-		if (PLCP3_ISSTBC(plcp[3]))
-			wlc->pub->_cnt->txmpdu_stbc++;
-	}
-
 	if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) {
-		ASSERT((mcl & TXC_AMPDU_MASK) != TXC_AMPDU_NONE);
 		wlc_ampdu_dotxstatus(wlc->ampdu, scb, p, txs);
 		return false;
 	}
 
 	supr_status = txs->status & TX_STATUS_SUPR_MASK;
 	if (supr_status == TX_STATUS_SUPR_BADCH)
-		WL_NONE("%s: Pkt tx suppressed, possibly channel %d\n",
-			__func__, CHSPEC_CHANNEL(wlc->default_bss->chanspec));
+		BCMMSG(wlc->wiphy,
+		       "%s: Pkt tx suppressed, possibly channel %d\n",
+		       __func__, CHSPEC_CHANNEL(wlc->default_bss->chanspec));
 
 	tx_rts = cpu_to_le16(txh->MacTxControlLow) & TXC_SENDRTS;
 	tx_frame_count =
@@ -6643,7 +5890,7 @@
 	lastframe = !ieee80211_has_morefrags(h->frame_control);
 
 	if (!lastframe) {
-		WL_ERROR("Not last frame!\n");
+		wiphy_err(wlc->wiphy, "Not last frame!\n");
 	} else {
 		u16 sfbl, lfbl;
 		ieee80211_tx_info_clear_status(tx_info);
@@ -6679,7 +5926,7 @@
 			tx_info->flags |= IEEE80211_TX_STAT_ACK;
 	}
 
-	totlen = pkttotlen(p);
+	totlen = bcm_pkttotlen(p);
 	free_pdu = true;
 
 	wlc_txfifo_complete(wlc, queue, 1);
@@ -6692,33 +5939,30 @@
 		skb_pull(p, D11_PHY_HDR_LEN);
 		skb_pull(p, D11_TXH_LEN);
 		ieee80211_tx_status_irqsafe(wlc->pub->ieee_hw, p);
-		wlc->pub->_cnt->ieee_tx_status++;
 	} else {
-		WL_ERROR("%s: Not last frame => not calling tx_status\n",
-			 __func__);
+		wiphy_err(wlc->wiphy, "%s: Not last frame => not calling "
+			  "tx_status\n", __func__);
 	}
 
 	return false;
 
  fatal:
-	ASSERT(0);
 	if (p)
-		pkt_buf_free_skb(p);
+		bcm_pkt_buf_free_skb(p);
 
 	return true;
 
 }
 
-void BCMFASTPATH
+void
 wlc_txfifo_complete(struct wlc_info *wlc, uint fifo, s8 txpktpend)
 {
 	TXPKTPENDDEC(wlc, fifo, txpktpend);
-	WL_TRACE("wlc_txfifo_complete, pktpend dec %d to %d\n",
-		 txpktpend, TXPKTPENDGET(wlc, fifo));
+	BCMMSG(wlc->wiphy, "pktpend dec %d to %d\n", txpktpend,
+		TXPKTPENDGET(wlc, fifo));
 
 	/* There is more room; mark precedences related to this FIFO sendable */
 	WLC_TX_FIFO_ENAB(wlc, fifo);
-	ASSERT(TXPKTPENDGET(wlc, fifo) >= 0);
 
 	if (!TXPKTPENDTOT(wlc)) {
 		if (wlc->block_datafifo & DATA_BLOCK_TX_SUPR)
@@ -6735,84 +5979,6 @@
 	/* figure out which bsscfg is being worked on... */
 }
 
-/* Given the beacon interval in kus, and a 64 bit TSF in us,
- * return the offset (in us) of the TSF from the last TBTT
- */
-u32 wlc_calc_tbtt_offset(u32 bp, u32 tsf_h, u32 tsf_l)
-{
-	u32 k, btklo, btkhi, offset;
-
-	/* TBTT is always an even multiple of the beacon_interval,
-	 * so the TBTT less than or equal to the beacon timestamp is
-	 * the beacon timestamp minus the beacon timestamp modulo
-	 * the beacon interval.
-	 *
-	 * TBTT = BT - (BT % BIu)
-	 *      = (BTk - (BTk % BP)) * 2^10
-	 *
-	 * BT = beacon timestamp (usec, 64bits)
-	 * BTk = beacon timestamp (Kusec, 54bits)
-	 * BP = beacon interval (Kusec, 16bits)
-	 * BIu = BP * 2^10 = beacon interval (usec, 26bits)
-	 *
-	 * To keep the calculations in u32s, the modulo operation
-	 * on the high part of BT needs to be done in parts using the
-	 * relations:
-	 * X*Y mod Z = ((X mod Z) * (Y mod Z)) mod Z
-	 * and
-	 * (X + Y) mod Z = ((X mod Z) + (Y mod Z)) mod Z
-	 *
-	 * So, if BTk[n] = u16 n [0,3] of BTk.
-	 * BTk % BP = SUM((BTk[n] * 2^16n) % BP , 0<=n<4) % BP
-	 * and the SUM term can be broken down:
-	 * (BTk[n] *     2^16n)    % BP
-	 * (BTk[n] * (2^16n % BP)) % BP
-	 *
-	 * Create a set of power of 2 mod BP constants:
-	 * K[n] = 2^(16n) % BP
-	 *      = (K[n-1] * 2^16) % BP
-	 * K[2] = 2^32 % BP = ((2^16 % BP) * 2^16) % BP
-	 *
-	 * BTk % BP = BTk[0-1] % BP +
-	 *            (BTk[2] * K[2]) % BP +
-	 *            (BTk[3] * K[3]) % BP
-	 *
-	 * Since K[n] < 2^16 and BTk[n] is < 2^16, then BTk[n] * K[n] < 2^32
-	 */
-
-	/* BTk = BT >> 10, btklo = BTk[0-3], bkthi = BTk[4-6] */
-	btklo = (tsf_h << 22) | (tsf_l >> 10);
-	btkhi = tsf_h >> 10;
-
-	/* offset = BTk % BP */
-	offset = btklo % bp;
-
-	/* K[2] = ((2^16 % BP) * 2^16) % BP */
-	k = (u32) (1 << 16) % bp;
-	k = (u32) (k * 1 << 16) % (u32) bp;
-
-	/* offset += (BTk[2] * K[2]) % BP */
-	offset += ((btkhi & 0xffff) * k) % bp;
-
-	/* BTk[3] */
-	btkhi = btkhi >> 16;
-
-	/* k[3] = (K[2] * 2^16) % BP */
-	k = (k << 16) % bp;
-
-	/* offset += (BTk[3] * K[3]) % BP */
-	offset += ((btkhi & 0xffff) * k) % bp;
-
-	offset = offset % bp;
-
-	/* convert offset from kus to us by shifting up 10 bits and
-	 * add in the low 10 bits of tsf that we ignored
-	 */
-	offset = (offset << 10) + (tsf_l & 0x3FF);
-
-	return offset;
-}
-
 /* Update beacon listen interval in shared memory */
 void wlc_bcn_li_upd(struct wlc_info *wlc)
 {
@@ -6827,25 +5993,56 @@
 			      (wlc->bcn_li_dtim << 8) | wlc->bcn_li_bcn);
 }
 
+/*
+ * recover 64bit TSF value from the 16bit TSF value in the rx header
+ * given the assumption that the TSF passed in header is within 65ms
+ * of the current tsf.
+ *
+ * 6       5       4       4       3       2       1
+ * 3.......6.......8.......0.......2.......4.......6.......8......0
+ * |<---------- tsf_h ----------->||<--- tsf_l -->||<-RxTSFTime ->|
+ *
+ * The RxTSFTime are the lowest 16 bits and provided by the ucode. The
+ * tsf_l is filled in by wlc_bmac_recv, which is done earlier in the
+ * receive call sequence after rx interrupt. Only the higher 16 bits
+ * are used. Finally, the tsf_h is read from the tsf register.
+ */
+static u64 wlc_recover_tsf64(struct wlc_info *wlc, struct wlc_d11rxhdr *rxh)
+{
+	u32 tsf_h, tsf_l;
+	u16 rx_tsf_0_15, rx_tsf_16_31;
+
+	wlc_bmac_read_tsf(wlc->hw, &tsf_l, &tsf_h);
+
+	rx_tsf_16_31 = (u16)(tsf_l >> 16);
+	rx_tsf_0_15 = rxh->rxhdr.RxTSFTime;
+
+	/*
+	 * a greater tsf time indicates the low 16 bits of
+	 * tsf_l wrapped, so decrement the high 16 bits.
+	 */
+	if ((u16)tsf_l < rx_tsf_0_15) {
+		rx_tsf_16_31 -= 1;
+		if (rx_tsf_16_31 == 0xffff)
+			tsf_h -= 1;
+	}
+
+	return ((u64)tsf_h << 32) | (((u32)rx_tsf_16_31 << 16) + rx_tsf_0_15);
+}
+
 static void
 prep_mac80211_status(struct wlc_info *wlc, d11rxhdr_t *rxh, struct sk_buff *p,
 		     struct ieee80211_rx_status *rx_status)
 {
-	u32 tsf_l, tsf_h;
 	wlc_d11rxhdr_t *wlc_rxh = (wlc_d11rxhdr_t *) rxh;
 	int preamble;
 	int channel;
 	ratespec_t rspec;
 	unsigned char *plcp;
 
-#if 0
-	/* Clearly, this is bogus -- reading the TSF now is wrong */
-	wlc_read_tsf(wlc, &tsf_l, &tsf_h);	/* mactime */
-	rx_status->mactime = tsf_h;
-	rx_status->mactime <<= 32;
-	rx_status->mactime |= tsf_l;
-	rx_status->flag |= RX_FLAG_MACTIME_MPDU; /* clearly wrong */
-#endif
+	/* fill in TSF and flag its presence */
+	rx_status->mactime = wlc_recover_tsf64(wlc, wlc_rxh);
+	rx_status->flag |= RX_FLAG_MACTIME_MPDU;
 
 	channel = WLC_CHAN_CHANNEL(rxh->RxChan);
 
@@ -6912,7 +6109,7 @@
 			rx_status->rate_idx = 11;
 			break;
 		default:
-			WL_ERROR("%s: Unknown rate\n", __func__);
+			wiphy_err(wlc->wiphy, "%s: Unknown rate\n", __func__);
 		}
 
 		/* Determine short preamble and rate_idx */
@@ -6923,7 +6120,8 @@
 		} else if (IS_OFDM(rspec)) {
 			rx_status->flag |= RX_FLAG_SHORTPRE;
 		} else {
-			WL_ERROR("%s: Unknown modulation\n", __func__);
+			wiphy_err(wlc->wiphy, "%s: Unknown modulation\n",
+				  __func__);
 		}
 	}
 
@@ -6932,11 +6130,13 @@
 
 	if (rxh->RxStatus1 & RXS_DECERR) {
 		rx_status->flag |= RX_FLAG_FAILED_PLCP_CRC;
-		WL_ERROR("%s:  RX_FLAG_FAILED_PLCP_CRC\n", __func__);
+		wiphy_err(wlc->wiphy, "%s:  RX_FLAG_FAILED_PLCP_CRC\n",
+			  __func__);
 	}
 	if (rxh->RxStatus1 & RXS_FCSERR) {
 		rx_status->flag |= RX_FLAG_FAILED_FCS_CRC;
-		WL_ERROR("%s:  RX_FLAG_FAILED_FCS_CRC\n", __func__);
+		wiphy_err(wlc->wiphy, "%s:  RX_FLAG_FAILED_FCS_CRC\n",
+			  __func__);
 	}
 }
 
@@ -6945,14 +6145,6 @@
 {
 	int len_mpdu;
 	struct ieee80211_rx_status rx_status;
-#if defined(BCMDBG)
-	struct sk_buff *skb = p;
-#endif				/* BCMDBG */
-	/* Todo:
-	 * Cache plcp for first MPDU of AMPD and use chacched version for INTERMEDIATE.
-	 * Test for INTERMEDIATE  like so:
-	 * if (!(plcp[0] | plcp[1] | plcp[2]))
-	 */
 
 	memset(&rx_status, 0, sizeof(rx_status));
 	prep_mac80211_status(wlc, rxh, p, &rx_status);
@@ -6962,48 +6154,25 @@
 	skb_pull(p, D11_PHY_HDR_LEN);
 	__skb_trim(p, len_mpdu);
 
-	ASSERT(!(p->next));
-	ASSERT(!(p->prev));
-
-	ASSERT(IS_ALIGNED((unsigned long)skb->data, 2));
-
 	memcpy(IEEE80211_SKB_RXCB(p), &rx_status, sizeof(rx_status));
 	ieee80211_rx_irqsafe(wlc->pub->ieee_hw, p);
-
-	wlc->pub->_cnt->ieee_rx++;
 	return;
 }
 
-void wlc_bss_list_free(struct wlc_info *wlc, struct wlc_bss_list *bss_list)
-{
-	uint index;
-
-	if (!bss_list) {
-		WL_ERROR("%s: Attempting to free NULL list\n", __func__);
-		return;
-	}
-	/* inspect all BSS descriptor */
-	for (index = 0; index < bss_list->count; index++) {
-		kfree(bss_list->ptrs[index]);
-		bss_list->ptrs[index] = NULL;
-	}
-	bss_list->count = 0;
-}
-
 /* Process received frames */
 /*
  * Return true if more frames need to be processed. false otherwise.
  * Param 'bound' indicates max. # frames to process before break out.
  */
 /* WLC_HIGH_API */
-void BCMFASTPATH wlc_recv(struct wlc_info *wlc, struct sk_buff *p)
+void wlc_recv(struct wlc_info *wlc, struct sk_buff *p)
 {
 	d11rxhdr_t *rxh;
 	struct ieee80211_hdr *h;
 	uint len;
 	bool is_amsdu;
 
-	WL_TRACE("wl%d: wlc_recv\n", wlc->pub->unit);
+	BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit);
 
 	/* frame starts with rxhdr */
 	rxh = (d11rxhdr_t *) (p->data);
@@ -7027,9 +6196,8 @@
 	/* MAC inserts 2 pad bytes for a4 headers or QoS or A-MSDU subframes */
 	if (rxh->RxStatus1 & RXS_PBPRES) {
 		if (p->len < 2) {
-			wlc->pub->_cnt->rxrunt++;
-			WL_ERROR("wl%d: wlc_recv: rcvd runt of len %d\n",
-				 wlc->pub->unit, p->len);
+			wiphy_err(wlc->wiphy, "wl%d: wlc_recv: rcvd runt of "
+				  "len %d\n", wlc->pub->unit, p->len);
 			goto toss;
 		}
 		skb_pull(p, 2);
@@ -7040,17 +6208,17 @@
 
 	if (rxh->RxStatus1 & RXS_FCSERR) {
 		if (wlc->pub->mac80211_state & MAC80211_PROMISC_BCNS) {
-			WL_ERROR("FCSERR while scanning******* - tossing\n");
+			wiphy_err(wlc->wiphy, "FCSERR while scanning******* -"
+				  " tossing\n");
 			goto toss;
 		} else {
-			WL_ERROR("RCSERR!!!\n");
+			wiphy_err(wlc->wiphy, "RCSERR!!!\n");
 			goto toss;
 		}
 	}
 
 	/* check received pkt has at least frame control field */
 	if (len < D11_PHY_HDR_LEN + sizeof(h->frame_control)) {
-		wlc->pub->_cnt->rxrunt++;
 		goto toss;
 	}
 
@@ -7064,13 +6232,12 @@
 		    ieee80211_is_mgmt(h->frame_control)) {
 			if ((is_zero_ether_addr(h->addr2) ||
 			     is_multicast_ether_addr(h->addr2))) {
-				WL_ERROR("wl%d: %s: dropping a frame with "
-					 "invalid src mac address, a2: %pM\n",
+				wiphy_err(wlc->wiphy, "wl%d: %s: dropping a "
+					  "frame with invalid src mac address,"
+					  " a2: %pM\n",
 					 wlc->pub->unit, __func__, h->addr2);
-				wlc->pub->_cnt->rxbadsrcmac++;
 				goto toss;
 			}
-			wlc->pub->_cnt->rxfrag++;
 		}
 	}
 
@@ -7085,7 +6252,7 @@
 	return;
 
  toss:
-	pkt_buf_free_skb(p);
+	bcm_pkt_buf_free_skb(p);
 }
 
 /* calculate frame duration for Mixed-mode L-SIG spoofing, return
@@ -7094,12 +6261,12 @@
  * Formula given by HT PHY Spec v 1.13
  *   len = 3(nsyms + nstream + 3) - 3
  */
-u16 BCMFASTPATH
+u16
 wlc_calc_lsig_len(struct wlc_info *wlc, ratespec_t ratespec, uint mac_len)
 {
 	uint nsyms, len = 0, kNdps;
 
-	WL_TRACE("wl%d: wlc_calc_lsig_len: rate %d, len%d\n",
+	BCMMSG(wlc->wiphy, "wl%d: rate %d, len%d\n",
 		 wlc->pub->unit, RSPEC2RATE(ratespec), mac_len);
 
 	if (IS_MCS(ratespec)) {
@@ -7107,7 +6274,6 @@
 		/* MCS_TXS(mcs) returns num tx streams - 1 */
 		int tot_streams = (MCS_TXS(mcs) + 1) + RSPEC_STC(ratespec);
 
-		ASSERT(WLC_PHY_11N_CAP(wlc->band));
 		/* the payload duration calculation matches that of regular ofdm */
 		/* 1000Ndbps = kbps * 4 */
 		kNdps =
@@ -7135,7 +6301,7 @@
 }
 
 /* calculate frame duration of a given rate and length, return time in usec unit */
-uint BCMFASTPATH
+uint
 wlc_calc_frame_time(struct wlc_info *wlc, ratespec_t ratespec, u8 preamble_type,
 		    uint mac_len)
 {
@@ -7143,19 +6309,17 @@
 	uint rate = RSPEC2RATE(ratespec);
 
 	if (rate == 0) {
-		ASSERT(0);
-		WL_ERROR("wl%d: WAR: using rate of 1 mbps\n", wlc->pub->unit);
+		wiphy_err(wlc->wiphy, "wl%d: WAR: using rate of 1 mbps\n",
+			  wlc->pub->unit);
 		rate = WLC_RATE_1M;
 	}
 
-	WL_TRACE("wl%d: wlc_calc_frame_time: rspec 0x%x, preamble_type %d, len%d\n",
+	BCMMSG(wlc->wiphy, "wl%d: rspec 0x%x, preamble_type %d, len%d\n",
 		 wlc->pub->unit, ratespec, preamble_type, mac_len);
 
 	if (IS_MCS(ratespec)) {
 		uint mcs = ratespec & RSPEC_RATE_MASK;
 		int tot_streams = MCS_TXS(mcs) + RSPEC_STC(ratespec);
-		ASSERT(WLC_PHY_11N_CAP(wlc->band));
-		ASSERT(WLC_IS_MIMO_PREAMBLE(preamble_type));
 
 		dur = PREN_PREAMBLE + (tot_streams * PREN_PREAMBLE_EXT);
 		if (preamble_type == WLC_MM_PREAMBLE)
@@ -7213,13 +6377,12 @@
 	uint nsyms, mac_len, Ndps, kNdps;
 	uint rate = RSPEC2RATE(ratespec);
 
-	WL_TRACE("wl%d: wlc_calc_frame_len: rspec 0x%x, preamble_type %d, dur %d\n",
+	BCMMSG(wlc->wiphy, "wl%d: rspec 0x%x, preamble_type %d, dur %d\n",
 		 wlc->pub->unit, ratespec, preamble_type, dur);
 
 	if (IS_MCS(ratespec)) {
 		uint mcs = ratespec & RSPEC_RATE_MASK;
 		int tot_streams = MCS_TXS(mcs) + RSPEC_STC(ratespec);
-		ASSERT(WLC_PHY_11N_CAP(wlc->band));
 		dur -= PREN_PREAMBLE + (tot_streams * PREN_PREAMBLE_EXT);
 		/* payload calculation matches that of regular ofdm */
 		if (BAND_2G(wlc->band->bandtype))
@@ -7256,33 +6419,29 @@
 static uint
 wlc_calc_ba_time(struct wlc_info *wlc, ratespec_t rspec, u8 preamble_type)
 {
-	WL_TRACE("wl%d: wlc_calc_ba_time: rspec 0x%x, preamble_type %d\n",
-		 wlc->pub->unit, rspec, preamble_type);
+	BCMMSG(wlc->wiphy, "wl%d: rspec 0x%x, "
+		 "preamble_type %d\n", wlc->pub->unit, rspec, preamble_type);
 	/* Spec 9.6: ack rate is the highest rate in BSSBasicRateSet that is less than
 	 * or equal to the rate of the immediately previous frame in the FES
 	 */
 	rspec = WLC_BASIC_RATE(wlc, rspec);
-	ASSERT(VALID_RATE_DBG(wlc, rspec));
-
 	/* BA len == 32 == 16(ctl hdr) + 4(ba len) + 8(bitmap) + 4(fcs) */
 	return wlc_calc_frame_time(wlc, rspec, preamble_type,
 				   (DOT11_BA_LEN + DOT11_BA_BITMAP_LEN +
 				    FCS_LEN));
 }
 
-static uint BCMFASTPATH
+static uint
 wlc_calc_ack_time(struct wlc_info *wlc, ratespec_t rspec, u8 preamble_type)
 {
 	uint dur = 0;
 
-	WL_TRACE("wl%d: wlc_calc_ack_time: rspec 0x%x, preamble_type %d\n",
-		 wlc->pub->unit, rspec, preamble_type);
+	BCMMSG(wlc->wiphy, "wl%d: rspec 0x%x, preamble_type %d\n",
+		wlc->pub->unit, rspec, preamble_type);
 	/* Spec 9.6: ack rate is the highest rate in BSSBasicRateSet that is less than
 	 * or equal to the rate of the immediately previous frame in the FES
 	 */
 	rspec = WLC_BASIC_RATE(wlc, rspec);
-	ASSERT(VALID_RATE_DBG(wlc, rspec));
-
 	/* ACK frame len == 14 == 2(fc) + 2(dur) + 6(ra) + 4(fcs) */
 	dur =
 	    wlc_calc_frame_time(wlc, rspec, preamble_type,
@@ -7293,8 +6452,8 @@
 static uint
 wlc_calc_cts_time(struct wlc_info *wlc, ratespec_t rspec, u8 preamble_type)
 {
-	WL_TRACE("wl%d: wlc_calc_cts_time: ratespec 0x%x, preamble_type %d\n",
-		 wlc->pub->unit, rspec, preamble_type);
+	BCMMSG(wlc->wiphy, "wl%d: ratespec 0x%x, preamble_type %d\n",
+		wlc->pub->unit, rspec, preamble_type);
 	return wlc_calc_ack_time(wlc, rspec, preamble_type);
 }
 
@@ -7320,11 +6479,12 @@
 			continue;
 
 		/* mask off basic bit */
-		rate = (rateset->rates[i] & RATE_MASK);
+		rate = (rateset->rates[i] & WLC_RATE_MASK);
 
 		if (rate > WLC_MAXRATE) {
-			WL_ERROR("wlc_rate_lookup_init: invalid rate 0x%X in rate set\n",
-				 rateset->rates[i]);
+			wiphy_err(wlc->wiphy, "wlc_rate_lookup_init: invalid "
+				  "rate 0x%X in rate set\n",
+				  rateset->rates[i]);
 			continue;
 		}
 
@@ -7347,7 +6507,6 @@
 
 	for (i = 0; i < wlc->band->hw_rateset.count; i++) {
 		rate = wlc->band->hw_rateset.rates[i];
-		ASSERT(rate <= WLC_MAXRATE);
 
 		if (br[rate] != 0) {
 			/* This rate is a basic rate.
@@ -7406,8 +6565,8 @@
 	 * for a given rate, the LS-nibble of the PLCP SIGNAL field is
 	 * the index into the rate table.
 	 */
-	phy_rate = rate_info[rate] & RATE_MASK;
-	basic_phy_rate = rate_info[basic_rate] & RATE_MASK;
+	phy_rate = rate_info[rate] & WLC_RATE_MASK;
+	basic_phy_rate = rate_info[basic_rate] & WLC_RATE_MASK;
 	index = phy_rate & 0xf;
 	basic_index = basic_phy_rate & 0xf;
 
@@ -7447,14 +6606,13 @@
 	uint i;
 
 	rs_dflt = wlc_rateset_get_hwrs(wlc);
-	ASSERT(rs_dflt != NULL);
 
 	wlc_rateset_copy(rs_dflt, &rs);
 	wlc_rateset_mcs_upd(&rs, wlc->stf->txstreams);
 
 	/* walk the phy rate table and update SHM basic rate lookup table */
 	for (i = 0; i < rs.count; i++) {
-		rate = rs.rates[i] & RATE_MASK;
+		rate = rs.rates[i] & WLC_RATE_MASK;
 
 		/* for a given rate WLC_BASIC_RATE returns the rate at
 		 * which a response ACK/CTS should be sent.
@@ -7464,7 +6622,7 @@
 			/* This should only happen if we are using a
 			 * restricted rateset.
 			 */
-			basic_rate = rs.rates[0] & RATE_MASK;
+			basic_rate = rs.rates[0] & WLC_RATE_MASK;
 		}
 
 		wlc_write_rate_shm(wlc, rate, basic_rate);
@@ -7503,8 +6661,8 @@
 			return true;
  error:
 	if (verbose) {
-		WL_ERROR("wl%d: wlc_valid_rate: rate spec 0x%x not in hw_rateset\n",
-			 wlc->pub->unit, rspec);
+		wiphy_err(wlc->wiphy, "wl%d: wlc_valid_rate: rate spec 0x%x "
+			  "not in hw_rateset\n", wlc->pub->unit, rspec);
 	}
 
 	return false;
@@ -7526,7 +6684,6 @@
 			else
 				band->mimo_cap_40 = false;
 		} else {
-			ASSERT(band->bandtype == WLC_BAND_2G);
 			if (bwcap == WLC_N_BW_40ALL)
 				band->mimo_cap_40 = true;
 			else
@@ -7550,14 +6707,13 @@
 	sifs = SIFS(wlc->band);
 
 	rs_dflt = wlc_rateset_get_hwrs(wlc);
-	ASSERT(rs_dflt != NULL);
 
 	wlc_rateset_copy(rs_dflt, &rs);
 	wlc_rateset_mcs_upd(&rs, wlc->stf->txstreams);
 
 	/* walk the phy rate table and update MAC core SHM basic rate table entries */
 	for (i = 0; i < rs.count; i++) {
-		rate = rs.rates[i] & RATE_MASK;
+		rate = rs.rates[i] & WLC_RATE_MASK;
 
 		entry_ptr = wlc_rate_shm_offset(wlc, rate);
 
@@ -7579,41 +6735,6 @@
 	}
 }
 
-u16
-wlc_compute_bcntsfoff(struct wlc_info *wlc, ratespec_t rspec,
-		      bool short_preamble, bool phydelay)
-{
-	uint bcntsfoff = 0;
-
-	if (IS_MCS(rspec)) {
-		WL_ERROR("wl%d: recd beacon with mcs rate; rspec 0x%x\n",
-			 wlc->pub->unit, rspec);
-	} else if (IS_OFDM(rspec)) {
-		/* tx delay from MAC through phy to air (2.1 usec) +
-		 * phy header time (preamble + PLCP SIGNAL == 20 usec) +
-		 * PLCP SERVICE + MAC header time (SERVICE + FC + DUR + A1 + A2 + A3 + SEQ == 26
-		 * bytes at beacon rate)
-		 */
-		bcntsfoff += phydelay ? D11A_PHY_TX_DELAY : 0;
-		bcntsfoff += APHY_PREAMBLE_TIME + APHY_SIGNAL_TIME;
-		bcntsfoff +=
-		    wlc_compute_airtime(wlc, rspec,
-					APHY_SERVICE_NBITS / 8 +
-					DOT11_MAC_HDR_LEN);
-	} else {
-		/* tx delay from MAC through phy to air (3.4 usec) +
-		 * phy header time (long preamble + PLCP == 192 usec) +
-		 * MAC header time (FC + DUR + A1 + A2 + A3 + SEQ == 24 bytes at beacon rate)
-		 */
-		bcntsfoff += phydelay ? D11B_PHY_TX_DELAY : 0;
-		bcntsfoff +=
-		    short_preamble ? D11B_PHY_SPREHDR_TIME :
-		    D11B_PHY_LPREHDR_TIME;
-		bcntsfoff += wlc_compute_airtime(wlc, rspec, DOT11_MAC_HDR_LEN);
-	}
-	return (u16) (bcntsfoff);
-}
-
 /*	Max buffering needed for beacon template/prb resp template is 142 bytes.
  *
  *	PLCP header is 6 bytes.
@@ -7635,10 +6756,6 @@
 	struct ieee80211_mgmt *h;
 	int hdr_len, body_len;
 
-	ASSERT(*len >= 142);
-	ASSERT(type == IEEE80211_STYPE_BEACON ||
-	       type == IEEE80211_STYPE_PROBE_RESP);
-
 	if (MBSS_BCN_ENAB(cfg) && type == IEEE80211_STYPE_BEACON)
 		hdr_len = DOT11_MAC_HDR_LEN;
 	else
@@ -7730,12 +6847,6 @@
 
 		wlc->bcn_rspec =
 		    wlc_lowest_basic_rspec(wlc, &cfg->current_bss->rateset);
-		ASSERT(wlc_valid_rate
-		       (wlc, wlc->bcn_rspec,
-			CHSPEC_IS2G(cfg->current_bss->
-				    chanspec) ? WLC_BAND_2G : WLC_BAND_5G,
-			true));
-
 		/* update the template and ucode shm */
 		wlc_bcn_prb_template(wlc, IEEE80211_STYPE_BEACON,
 				     wlc->bcn_rspec, cfg, bcn, &len);
@@ -7825,7 +6936,7 @@
 		if (suspend)
 			wlc_enable_mac(wlc);
 	} else {		/* Generating probe resp in sw; update local template */
-		ASSERT(0 && "No software probe response support without MBSS");
+		/* error: No software probe response support without MBSS */
 	}
 }
 
@@ -7837,11 +6948,8 @@
 	struct ieee80211_hdr *h;
 	struct scb *scb;
 
-	ASSERT(pdu);
 	txh = (d11txh_t *) (pdu->data);
-	ASSERT(txh);
 	h = (struct ieee80211_hdr *)((u8 *) (txh + 1) + D11_PHY_HDR_LEN);
-	ASSERT(h);
 
 	/* get the pkt queue info. This was put at wlc_sendctl or wlc_send for PDU */
 	fifo = le16_to_cpu(txh->TxFrameID) & TXFID_QUEUE_MASK;
@@ -7854,12 +6962,8 @@
 	if (TXAVAIL(wlc, fifo) < MAX_DMA_SEGS) {
 		/* Mark precedences related to this FIFO, unsendable */
 		WLC_TX_FIFO_CLEAR(wlc, fifo);
-		return BCME_BUSY;
+		return -EBUSY;
 	}
-
-	if (!ieee80211_is_data(txh->MacFrameControl))
-		wlc->pub->_cnt->txctl++;
-
 	return 0;
 }
 
@@ -7889,7 +6993,7 @@
 	wlc_rev_info_t *rinfo = (wlc_rev_info_t *) buf;
 
 	if (len < WL_REV_INFO_LEGACY_LENGTH)
-		return BCME_BUFTOOSHORT;
+		return -EOVERFLOW;
 
 	rinfo->vendorid = wlc->vendorid;
 	rinfo->deviceid = wlc->deviceid;
@@ -7915,13 +7019,13 @@
 		rinfo->chippkg = wlc->pub->sih->chippkg;
 	}
 
-	return BCME_OK;
+	return 0;
 }
 
 void wlc_default_rateset(struct wlc_info *wlc, wlc_rateset_t *rs)
 {
 	wlc_rateset_default(rs, NULL, wlc->band->phytype, wlc->band->bandtype,
-			    false, RATE_MASK_FULL, (bool) N_ENAB(wlc->pub),
+			    false, WLC_RATE_MASK_FULL, (bool) N_ENAB(wlc->pub),
 			    CHSPEC_WLC_BW(wlc->default_bss->chanspec),
 			    wlc->stf->txstreams);
 }
@@ -7943,8 +7047,6 @@
 	 * starting from the 2G channels
 	 */
 	chanspec = CH20MHZ_CHSPEC(1);
-	ASSERT(chanspec != INVCHANSPEC);
-
 	wlc->home_chanspec = bi->chanspec = chanspec;
 
 	/* find the band of our default channel */
@@ -7954,24 +7056,13 @@
 
 	/* init bss rates to the band specific default rate set */
 	wlc_rateset_default(&bi->rateset, NULL, band->phytype, band->bandtype,
-			    false, RATE_MASK_FULL, (bool) N_ENAB(wlc->pub),
+			    false, WLC_RATE_MASK_FULL, (bool) N_ENAB(wlc->pub),
 			    CHSPEC_WLC_BW(chanspec), wlc->stf->txstreams);
 
 	if (N_ENAB(wlc->pub))
 		bi->flags |= WLC_BSS_HT;
 }
 
-void
-wlc_uint64_sub(u32 *a_high, u32 *a_low, u32 b_high, u32 b_low)
-{
-	if (b_low > *a_low) {
-		/* low half needs a carry */
-		b_high += 1;
-	}
-	*a_low -= b_low;
-	*a_high -= b_high;
-}
-
 static ratespec_t
 mac80211_wlc_set_nrate(struct wlc_info *wlc, struct wlcband *cur_band,
 		       u32 int_val)
@@ -7993,9 +7084,9 @@
 	if (N_ENAB(wlc->pub) && ismcs) {
 		/* mcs only allowed when nmode */
 		if (stf > PHY_TXC1_MODE_SDM) {
-			WL_ERROR("wl%d: %s: Invalid stf\n",
+			wiphy_err(wlc->wiphy, "wl%d: %s: Invalid stf\n",
 				 WLCWLUNIT(wlc), __func__);
-			bcmerror = BCME_RANGE;
+			bcmerror = -EINVAL;
 			goto done;
 		}
 
@@ -8004,17 +7095,18 @@
 			if (!CHSPEC_IS40(wlc->home_chanspec) ||
 			    ((stf != PHY_TXC1_MODE_SISO)
 			     && (stf != PHY_TXC1_MODE_CDD))) {
-				WL_ERROR("wl%d: %s: Invalid mcs 32\n",
-					 WLCWLUNIT(wlc), __func__);
-				bcmerror = BCME_RANGE;
+				wiphy_err(wlc->wiphy, "wl%d: %s: Invalid mcs "
+					  "32\n", WLCWLUNIT(wlc), __func__);
+				bcmerror = -EINVAL;
 				goto done;
 			}
 			/* mcs > 7 must use stf SDM */
 		} else if (rate > HIGHEST_SINGLE_STREAM_MCS) {
 			/* mcs > 7 must use stf SDM */
 			if (stf != PHY_TXC1_MODE_SDM) {
-				WL_TRACE("wl%d: %s: enabling SDM mode for mcs %d\n",
-					 WLCWLUNIT(wlc), __func__, rate);
+				BCMMSG(wlc->wiphy, "wl%d: enabling "
+					 "SDM mode for mcs %d\n",
+					 WLCWLUNIT(wlc), rate);
 				stf = PHY_TXC1_MODE_SDM;
 			}
 		} else {
@@ -8022,38 +7114,38 @@
 			if ((stf > PHY_TXC1_MODE_STBC) ||
 			    (!WLC_STBC_CAP_PHY(wlc)
 			     && (stf == PHY_TXC1_MODE_STBC))) {
-				WL_ERROR("wl%d: %s: Invalid STBC\n",
-					 WLCWLUNIT(wlc), __func__);
-				bcmerror = BCME_RANGE;
+				wiphy_err(wlc->wiphy, "wl%d: %s: Invalid STBC"
+					  "\n", WLCWLUNIT(wlc), __func__);
+				bcmerror = -EINVAL;
 				goto done;
 			}
 		}
 	} else if (IS_OFDM(rate)) {
 		if ((stf != PHY_TXC1_MODE_CDD) && (stf != PHY_TXC1_MODE_SISO)) {
-			WL_ERROR("wl%d: %s: Invalid OFDM\n",
-				 WLCWLUNIT(wlc), __func__);
-			bcmerror = BCME_RANGE;
+			wiphy_err(wlc->wiphy, "wl%d: %s: Invalid OFDM\n",
+				  WLCWLUNIT(wlc), __func__);
+			bcmerror = -EINVAL;
 			goto done;
 		}
 	} else if (IS_CCK(rate)) {
 		if ((cur_band->bandtype != WLC_BAND_2G)
 		    || (stf != PHY_TXC1_MODE_SISO)) {
-			WL_ERROR("wl%d: %s: Invalid CCK\n",
-				 WLCWLUNIT(wlc), __func__);
-			bcmerror = BCME_RANGE;
+			wiphy_err(wlc->wiphy, "wl%d: %s: Invalid CCK\n",
+				  WLCWLUNIT(wlc), __func__);
+			bcmerror = -EINVAL;
 			goto done;
 		}
 	} else {
-		WL_ERROR("wl%d: %s: Unknown rate type\n",
-			 WLCWLUNIT(wlc), __func__);
-		bcmerror = BCME_RANGE;
+		wiphy_err(wlc->wiphy, "wl%d: %s: Unknown rate type\n",
+			  WLCWLUNIT(wlc), __func__);
+		bcmerror = -EINVAL;
 		goto done;
 	}
 	/* make sure multiple antennae are available for non-siso rates */
 	if ((stf != PHY_TXC1_MODE_SISO) && (wlc->stf->txstreams == 1)) {
-		WL_ERROR("wl%d: %s: SISO antenna but !SISO request\n",
-			 WLCWLUNIT(wlc), __func__);
-		bcmerror = BCME_RANGE;
+		wiphy_err(wlc->wiphy, "wl%d: %s: SISO antenna but !SISO "
+			  "request\n", WLCWLUNIT(wlc), __func__);
+		bcmerror = -EINVAL;
 		goto done;
 	}
 
@@ -8082,8 +7174,7 @@
 	}
 
 	return rspec;
- done:
-	WL_ERROR("Hoark\n");
+done:
 	return rate;
 }
 
@@ -8097,8 +7188,9 @@
 	    isOFDM ? M_TX_IDLE_BUSY_RATIO_X_16_OFDM :
 	    M_TX_IDLE_BUSY_RATIO_X_16_CCK;
 	if (duty_cycle > 100 || duty_cycle < 0) {
-		WL_ERROR("wl%d:  duty cycle value off limit\n", wlc->pub->unit);
-		return BCME_RANGE;
+		wiphy_err(wlc->wiphy, "wl%d:  duty cycle value off limit\n",
+			  wlc->pub->unit);
+		return -EINVAL;
 	}
 	if (duty_cycle)
 		idle_busy_ratio_x_16 = (100 - duty_cycle) * 16 / duty_cycle;
@@ -8111,7 +7203,7 @@
 	else
 		wlc->tx_duty_cycle_cck = (u16) duty_cycle;
 
-	return BCME_OK;
+	return 0;
 }
 
 /* Read a single u16 from shared memory.
@@ -8130,22 +7222,6 @@
 	wlc_bmac_write_shm(wlc->hw, offset, v);
 }
 
-/* Set a range of shared memory to a value.
- * SHM 'offset' needs to be an even address and
- * Range length 'len' must be an even number of bytes
- */
-void wlc_set_shm(struct wlc_info *wlc, uint offset, u16 v, int len)
-{
-	/* offset and len need to be even */
-	ASSERT((offset & 1) == 0);
-	ASSERT((len & 1) == 0);
-
-	if (len <= 0)
-		return;
-
-	wlc_bmac_set_shm(wlc->hw, offset, v, len);
-}
-
 /* Copy a buffer to shared memory.
  * SHM 'offset' needs to be an even address and
  * Buffer length 'len' must be an even number of bytes
@@ -8153,29 +7229,11 @@
 void wlc_copyto_shm(struct wlc_info *wlc, uint offset, const void *buf, int len)
 {
 	/* offset and len need to be even */
-	ASSERT((offset & 1) == 0);
-	ASSERT((len & 1) == 0);
-
-	if (len <= 0)
+	if (len <= 0 || (offset & 1) || (len & 1))
 		return;
-	wlc_bmac_copyto_objmem(wlc->hw, offset, buf, len, OBJADDR_SHM_SEL);
 
-}
-
-/* Copy from shared memory to a buffer.
- * SHM 'offset' needs to be an even address and
- * Buffer length 'len' must be an even number of bytes
- */
-void wlc_copyfrom_shm(struct wlc_info *wlc, uint offset, void *buf, int len)
-{
-	/* offset and len need to be even */
-	ASSERT((offset & 1) == 0);
-	ASSERT((len & 1) == 0);
-
-	if (len <= 0)
-		return;
+	wlc_bmac_copyto_objmem(wlc->hw, offset, buf, len, OBJADDR_SHM_SEL);
 
-	wlc_bmac_copyfrom_objmem(wlc->hw, offset, buf, len, OBJADDR_SHM_SEL);
 }
 
 /* wrapper BMAC functions to for HIGH driver access */
@@ -8184,21 +7242,11 @@
 	wlc_bmac_mctrl(wlc->hw, mask, val);
 }
 
-void wlc_corereset(struct wlc_info *wlc, u32 flags)
-{
-	wlc_bmac_corereset(wlc->hw, flags);
-}
-
 void wlc_mhf(struct wlc_info *wlc, u8 idx, u16 mask, u16 val, int bands)
 {
 	wlc_bmac_mhf(wlc->hw, idx, mask, val, bands);
 }
 
-u16 wlc_mhf_get(struct wlc_info *wlc, u8 idx, int bands)
-{
-	return wlc_bmac_mhf_get(wlc->hw, idx, bands);
-}
-
 int wlc_xmtfifo_sz_get(struct wlc_info *wlc, uint fifo, uint *blocks)
 {
 	return wlc_bmac_xmtfifo_sz_get(wlc->hw, fifo, blocks);
@@ -8225,16 +7273,6 @@
 		memcpy(wlc->cfg->BSSID, addr, ETH_ALEN);
 }
 
-void wlc_set_rcmta(struct wlc_info *wlc, int idx, const u8 *addr)
-{
-	wlc_bmac_set_rcmta(wlc->hw, idx, addr);
-}
-
-void wlc_read_tsf(struct wlc_info *wlc, u32 *tsf_l_ptr, u32 *tsf_h_ptr)
-{
-	wlc_bmac_read_tsf(wlc->hw, tsf_l_ptr, tsf_h_ptr);
-}
-
 void wlc_set_cwmin(struct wlc_info *wlc, u16 newmin)
 {
 	wlc->band->CWmin = newmin;
@@ -8247,12 +7285,6 @@
 	wlc_bmac_set_cwmax(wlc->hw, newmax);
 }
 
-void wlc_fifoerrors(struct wlc_info *wlc)
-{
-
-	wlc_bmac_fifoerrors(wlc->hw);
-}
-
 /* Search mem rw utilities */
 
 void wlc_pllreq(struct wlc_info *wlc, bool set, mbool req_bit)
@@ -8264,17 +7296,6 @@
 {
 }
 
-void wlc_ht_mimops_cap_update(struct wlc_info *wlc, u8 mimops_mode)
-{
-	wlc->ht_cap.cap_info &= ~IEEE80211_HT_CAP_SM_PS;
-	wlc->ht_cap.cap_info |= (mimops_mode << IEEE80211_HT_CAP_SM_PS_SHIFT);
-
-	if (AP_ENAB(wlc->pub) && wlc->clk) {
-		wlc_update_beacon(wlc);
-		wlc_update_probe_resp(wlc, true);
-	}
-}
-
 /* check for the particular priority flow control bit being set */
 bool
 wlc_txflowcontrol_prio_isset(struct wlc_info *wlc, struct wlc_txq_info *q,
@@ -8285,7 +7306,6 @@
 	if (prio == ALLPRIO) {
 		prio_mask = TXQ_STOP_FOR_PRIOFC_MASK;
 	} else {
-		ASSERT(prio >= 0 && prio <= MAXPRIO);
 		prio_mask = NBITVAL(prio);
 	}
 
@@ -8299,12 +7319,11 @@
 	uint prio_bits;
 	uint cur_bits;
 
-	WL_TRACE("%s: flow control kicks in\n", __func__);
+	BCMMSG(wlc->wiphy, "flow control kicks in\n");
 
 	if (prio == ALLPRIO) {
 		prio_bits = TXQ_STOP_FOR_PRIOFC_MASK;
 	} else {
-		ASSERT(prio >= 0 && prio <= MAXPRIO);
 		prio_bits = NBITVAL(prio);
 	}
 
@@ -8341,9 +7360,6 @@
 {
 	uint prev_override;
 
-	ASSERT(override != 0);
-	ASSERT((override & TXQ_STOP_FOR_PRIOFC_MASK) == 0);
-
 	prev_override = (qi->stopped & ~TXQ_STOP_FOR_PRIOFC_MASK);
 
 	/* Update the flow control bits and do an early return if there is
@@ -8411,7 +7427,7 @@
 {
 	struct wlc_txq_info *qi, *p;
 
-	qi = wlc_calloc(wlc->pub->unit, sizeof(struct wlc_txq_info));
+	qi = kzalloc(sizeof(struct wlc_txq_info), GFP_ATOMIC);
 	if (qi != NULL) {
 		/*
 		 * Have enough room for control packets along with HI watermark
@@ -8419,7 +7435,7 @@
 		 * leave PS mode. The watermark for flowcontrol to OS packets
 		 * will remain the same
 		 */
-		pktq_init(&qi->q, WLC_PREC_COUNT,
+		bcm_pktq_init(&qi->q, WLC_PREC_COUNT,
 			  (2 * wlc->pub->tunables->datahiwat) + PKTQ_LEN_DEFAULT
 			  + wlc->pub->psq_pkts_total);
 
@@ -8450,7 +7466,6 @@
 	else {
 		while (p != NULL && p->next != qi)
 			p = p->next;
-		ASSERT(p->next == qi);
 		if (p != NULL)
 			p->next = p->next->next;
 	}
@@ -8494,3 +7509,21 @@
 			dma_walk_packets(dmah, dma_callback_fn, sta);
 	}
 }
+
+int wlc_get_curband(struct wlc_info *wlc)
+{
+	return wlc->band->bandunit;
+}
+
+void wlc_wait_for_tx_completion(struct wlc_info *wlc, bool drop)
+{
+	/* flush packet queue when requested */
+	if (drop)
+		bcm_pktq_flush(&wlc->pkt_queue->q, false, NULL, NULL);
+
+	/* wait for queue and DMA fifos to run dry */
+	while (!pktq_empty(&wlc->pkt_queue->q) ||
+	       TXPKTPENDTOT(wlc) > 0) {
+		wl_msleep(wlc->wl, 1);
+	}
+}
diff -druN linux-2.6.39-libre/drivers/staging/brcm80211/brcmsmac/wlc_main.h linux-3.0-rc7-libre/drivers/staging/brcm80211/brcmsmac/wlc_main.h
--- linux-2.6.39-libre/drivers/staging/brcm80211/brcmsmac/wlc_main.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/brcm80211/brcmsmac/wlc_main.h	2011-07-11 19:51:52.000000000 -0400
@@ -98,7 +98,6 @@
 	(cfg)->wsec_portopen : true)
 
 #define PS_ALLOWED(wlc)	wlc_ps_allowed(wlc)
-#define STAY_AWAKE(wlc) wlc_stay_awake(wlc)
 
 #define DATA_BLOCK_TX_SUPR	(1 << 4)
 
@@ -166,9 +165,6 @@
 #define WLC_PLLREQ_RADIO_MON	0x2	/* hold pll for radio monitor register checking */
 #define WLC_PLLREQ_FLIP		0x4	/* hold/release pll for some short operation */
 
-/* Do we support this rate? */
-#define VALID_RATE_DBG(wlc, rspec) wlc_valid_rate(wlc, rspec, WLC_BAND_AUTO, true)
-
 /*
  * Macros to check if AP or STA is active.
  * AP Active means more than just configured: driver and BSS are "up";
@@ -196,7 +192,7 @@
 	((wlc->hw->clk) ?   \
 	((R_REG(&wlc->hw->regs->maccontrol) & \
 	(MCTL_PSM_JMP_0 | MCTL_IHR_EN)) != MCTL_IHR_EN) : \
-	(si_deviceremoved(wlc->hw->sih)))
+	(ai_deviceremoved(wlc->hw->sih)))
 
 #define WLCWLUNIT(wlc)		((wlc)->pub->unit)
 
@@ -746,9 +742,7 @@
 	u16 next_bsscfg_ID;
 
 	struct wlc_if *wlcif_list;	/* linked list of wlc_if structs */
-	struct wlc_txq_info *active_queue; /* txq for the currently active
-					    * transmit context
-					    */
+	struct wlc_txq_info *pkt_queue; /* txq for transmit packets */
 	u32 mpc_dur;		/* total time (ms) in mpc mode except for the
 				 * portion since radio is turned off last time
 				 */
@@ -757,6 +751,7 @@
 				 */
 	bool pr80838_war;
 	uint hwrxoff;
+	struct wiphy *wiphy;
 };
 
 /* antsel module specific state */
@@ -794,7 +789,6 @@
 #define WLC_IS_MATCH_SSID(wlc, ssid1, ssid2, len1, len2) \
 	((len1 == len2) && !memcmp(ssid1, ssid2, len1))
 
-extern void wlc_high_dpc(struct wlc_info *wlc, u32 macintstatus);
 extern void wlc_fatal_error(struct wlc_info *wlc);
 extern void wlc_bmac_rpc_watchdog(struct wlc_info *wlc);
 extern void wlc_recv(struct wlc_info *wlc, struct sk_buff *p);
@@ -811,21 +805,10 @@
 				   void *buf);
 extern void wlc_write_hw_bcntemplates(struct wlc_info *wlc, void *bcn, int len,
 				      bool both);
-#if defined(BCMDBG)
-extern void wlc_get_rcmta(struct wlc_info *wlc, int idx,
-			  u8 *addr);
-#endif
-extern void wlc_set_rcmta(struct wlc_info *wlc, int idx,
-			  const u8 *addr);
-extern void wlc_read_tsf(struct wlc_info *wlc, u32 *tsf_l_ptr,
-			 u32 *tsf_h_ptr);
 extern void wlc_set_cwmin(struct wlc_info *wlc, u16 newmin);
 extern void wlc_set_cwmax(struct wlc_info *wlc, u16 newmax);
-extern void wlc_fifoerrors(struct wlc_info *wlc);
 extern void wlc_pllreq(struct wlc_info *wlc, bool set, mbool req_bit);
 extern void wlc_reset_bmac_done(struct wlc_info *wlc);
-extern void wlc_hwtimer_gptimer_set(struct wlc_info *wlc, uint us);
-extern void wlc_hwtimer_gptimer_abort(struct wlc_info *wlc);
 
 #if defined(BCMDBG)
 extern void wlc_print_rxh(d11rxhdr_t *rxh);
@@ -860,7 +843,7 @@
 				       bool on, uint override);
 extern bool wlc_txflowcontrol_prio_isset(struct wlc_info *wlc,
 					 struct wlc_txq_info *qi, int prio);
-extern void wlc_send_q(struct wlc_info *wlc, struct wlc_txq_info *qi);
+extern void wlc_send_q(struct wlc_info *wlc);
 extern int wlc_prep_pdu(struct wlc_info *wlc, struct sk_buff *pdu, uint *fifo);
 
 extern u16 wlc_calc_lsig_len(struct wlc_info *wlc, ratespec_t ratespec,
@@ -883,21 +866,14 @@
 			struct bcmstrbuf *b);
 #endif
 
-extern bool wlc_ps_check(struct wlc_info *wlc);
 extern void wlc_reprate_init(struct wlc_info *wlc);
 extern void wlc_bsscfg_reprate_init(struct wlc_bsscfg *bsscfg);
-extern void wlc_uint64_sub(u32 *a_high, u32 *a_low, u32 b_high,
-			   u32 b_low);
-extern u32 wlc_calc_tbtt_offset(u32 bi, u32 tsf_h, u32 tsf_l);
 
 /* Shared memory access */
 extern void wlc_write_shm(struct wlc_info *wlc, uint offset, u16 v);
 extern u16 wlc_read_shm(struct wlc_info *wlc, uint offset);
-extern void wlc_set_shm(struct wlc_info *wlc, uint offset, u16 v, int len);
 extern void wlc_copyto_shm(struct wlc_info *wlc, uint offset, const void *buf,
 			   int len);
-extern void wlc_copyfrom_shm(struct wlc_info *wlc, uint offset, void *buf,
-			     int len);
 
 extern void wlc_update_beacon(struct wlc_info *wlc);
 extern void wlc_bss_update_beacon(struct wlc_info *wlc,
@@ -935,14 +911,13 @@
 #endif
 
 extern int wlc_set_nmode(struct wlc_info *wlc, s32 nmode);
-extern void wlc_ht_mimops_cap_update(struct wlc_info *wlc, u8 mimops_mode);
 extern void wlc_mimops_action_ht_send(struct wlc_info *wlc,
 				      struct wlc_bsscfg *bsscfg,
 				      u8 mimops_mode);
 
 extern void wlc_switch_shortslot(struct wlc_info *wlc, bool shortslot);
 extern void wlc_set_bssid(struct wlc_bsscfg *cfg);
-extern void wlc_edcf_setparams(struct wlc_bsscfg *cfg, bool suspend);
+extern void wlc_edcf_setparams(struct wlc_info *wlc, bool suspend);
 
 extern void wlc_set_ratetable(struct wlc_info *wlc);
 extern int wlc_set_mac(struct wlc_bsscfg *cfg);
@@ -951,20 +926,14 @@
 extern void wlc_mod_prb_rsp_rate_table(struct wlc_info *wlc, uint frame_len);
 extern ratespec_t wlc_lowest_basic_rspec(struct wlc_info *wlc,
 					 wlc_rateset_t *rs);
-extern u16 wlc_compute_bcntsfoff(struct wlc_info *wlc, ratespec_t rspec,
-				    bool short_preamble, bool phydelay);
 extern void wlc_radio_disable(struct wlc_info *wlc);
 extern void wlc_bcn_li_upd(struct wlc_info *wlc);
 
 extern int wlc_get_revision_info(struct wlc_info *wlc, void *buf, uint len);
-extern void wlc_out(struct wlc_info *wlc);
 extern void wlc_set_home_chanspec(struct wlc_info *wlc, chanspec_t chanspec);
 extern void wlc_watchdog_upd(struct wlc_info *wlc, bool tbtt);
 extern bool wlc_ps_allowed(struct wlc_info *wlc);
 extern bool wlc_stay_awake(struct wlc_info *wlc);
 extern void wlc_wme_initparams_sta(struct wlc_info *wlc, wme_param_ie_t *pe);
 
-extern void wlc_bss_list_free(struct wlc_info *wlc,
-			      struct wlc_bss_list *bss_list);
-extern void wlc_ht_mimops_cap_update(struct wlc_info *wlc, u8 mimops_mode);
 #endif				/* _wlc_h_ */
diff -druN linux-2.6.39-libre/drivers/staging/brcm80211/brcmsmac/wlc_phy_shim.c linux-3.0-rc7-libre/drivers/staging/brcm80211/brcmsmac/wlc_phy_shim.c
--- linux-2.6.39-libre/drivers/staging/brcm80211/brcmsmac/wlc_phy_shim.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/brcm80211/brcmsmac/wlc_phy_shim.c	2011-07-11 19:51:52.000000000 -0400
@@ -29,14 +29,14 @@
 #include <bcmdefs.h>
 #include <bcmutils.h>
 #include <bcmwifi.h>
-#include <siutils.h>
+#include <aiutils.h>
 #include <wlioctl.h>
 #include <sbconfig.h>
 #include <sbchipc.h>
 #include <pcicfg.h>
 #include <sbhnddma.h>
 #include <hnddma.h>
-#include <hndpmu.h>
+#include <wlc_pmu.h>
 
 #include "wlc_types.h"
 #include "wl_dbg.h"
@@ -68,8 +68,9 @@
 
 	physhim = kzalloc(sizeof(wlc_phy_shim_info_t), GFP_ATOMIC);
 	if (!physhim) {
-		WL_ERROR("wl%d: wlc_phy_shim_attach: out of mem\n",
-			 wlc_hw->unit);
+		wiphy_err(wlc_hw->wlc->wiphy,
+			  "wl%d: wlc_phy_shim_attach: out of mem\n",
+			  wlc_hw->unit);
 		return NULL;
 	}
 	physhim->wlc_hw = wlc_hw;
diff -druN linux-2.6.39-libre/drivers/staging/brcm80211/brcmsmac/wlc_pmu.c linux-3.0-rc7-libre/drivers/staging/brcm80211/brcmsmac/wlc_pmu.c
--- linux-2.6.39-libre/drivers/staging/brcm80211/brcmsmac/wlc_pmu.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/staging/brcm80211/brcmsmac/wlc_pmu.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,1929 @@
+/*
+ * Copyright (c) 2011 Broadcom Corporation
+ *
+ * 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/kernel.h>
+#include <linux/types.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+
+#include <bcmdevs.h>
+#include <sbchipc.h>
+#include <bcmutils.h>
+#include <bcmnvram.h>
+#include "wlc_pmu.h"
+
+/*
+ * d11 slow to fast clock transition time in slow clock cycles
+ */
+#define D11SCC_SLOW2FAST_TRANSITION	2
+
+/*
+ * external LPO crystal frequency
+ */
+#define EXT_ILP_HZ 32768
+
+/*
+ * Duration for ILP clock frequency measurment in milliseconds
+ *
+ * remark: 1000 must be an integer multiple of this duration
+ */
+#define ILP_CALC_DUR	10
+
+/*
+ * FVCO frequency
+ */
+#define FVCO_880	880000	/* 880MHz */
+#define FVCO_1760	1760000	/* 1760MHz */
+#define FVCO_1440	1440000	/* 1440MHz */
+#define FVCO_960	960000	/* 960MHz */
+
+/*
+ * PMU crystal table indices for 1440MHz fvco
+ */
+#define PMU1_XTALTAB0_1440_12000K	0
+#define PMU1_XTALTAB0_1440_13000K	1
+#define PMU1_XTALTAB0_1440_14400K	2
+#define PMU1_XTALTAB0_1440_15360K	3
+#define PMU1_XTALTAB0_1440_16200K	4
+#define PMU1_XTALTAB0_1440_16800K	5
+#define PMU1_XTALTAB0_1440_19200K	6
+#define PMU1_XTALTAB0_1440_19800K	7
+#define PMU1_XTALTAB0_1440_20000K	8
+#define PMU1_XTALTAB0_1440_25000K	9
+#define PMU1_XTALTAB0_1440_26000K	10
+#define PMU1_XTALTAB0_1440_30000K	11
+#define PMU1_XTALTAB0_1440_37400K	12
+#define PMU1_XTALTAB0_1440_38400K	13
+#define PMU1_XTALTAB0_1440_40000K	14
+#define PMU1_XTALTAB0_1440_48000K	15
+
+/*
+ * PMU crystal table indices for 960MHz fvco
+ */
+#define PMU1_XTALTAB0_960_12000K	0
+#define PMU1_XTALTAB0_960_13000K	1
+#define PMU1_XTALTAB0_960_14400K	2
+#define PMU1_XTALTAB0_960_15360K	3
+#define PMU1_XTALTAB0_960_16200K	4
+#define PMU1_XTALTAB0_960_16800K	5
+#define PMU1_XTALTAB0_960_19200K	6
+#define PMU1_XTALTAB0_960_19800K	7
+#define PMU1_XTALTAB0_960_20000K	8
+#define PMU1_XTALTAB0_960_25000K	9
+#define PMU1_XTALTAB0_960_26000K	10
+#define PMU1_XTALTAB0_960_30000K	11
+#define PMU1_XTALTAB0_960_37400K	12
+#define PMU1_XTALTAB0_960_38400K	13
+#define PMU1_XTALTAB0_960_40000K	14
+#define PMU1_XTALTAB0_960_48000K	15
+
+/*
+ * PMU crystal table indices for 880MHz fvco
+ */
+#define PMU1_XTALTAB0_880_12000K	0
+#define PMU1_XTALTAB0_880_13000K	1
+#define PMU1_XTALTAB0_880_14400K	2
+#define PMU1_XTALTAB0_880_15360K	3
+#define PMU1_XTALTAB0_880_16200K	4
+#define PMU1_XTALTAB0_880_16800K	5
+#define PMU1_XTALTAB0_880_19200K	6
+#define PMU1_XTALTAB0_880_19800K	7
+#define PMU1_XTALTAB0_880_20000K	8
+#define PMU1_XTALTAB0_880_24000K	9
+#define PMU1_XTALTAB0_880_25000K	10
+#define PMU1_XTALTAB0_880_26000K	11
+#define PMU1_XTALTAB0_880_30000K	12
+#define PMU1_XTALTAB0_880_37400K	13
+#define PMU1_XTALTAB0_880_38400K	14
+#define PMU1_XTALTAB0_880_40000K	15
+
+/*
+ * crystal frequency values
+ */
+#define XTAL_FREQ_24000MHZ		24000
+#define XTAL_FREQ_30000MHZ		30000
+#define XTAL_FREQ_37400MHZ		37400
+#define XTAL_FREQ_48000MHZ		48000
+
+/*
+ * Resource dependancies mask change action
+ *
+ * @RES_DEPEND_SET: Override the dependancies mask
+ * @RES_DEPEND_ADD: Add to the  dependancies mask
+ * @RES_DEPEND_REMOVE: Remove from the dependancies mask
+ */
+#define RES_DEPEND_SET		0
+#define RES_DEPEND_ADD		1
+#define RES_DEPEND_REMOVE	-1
+
+/* d11 slow to fast clock transition time in slow clock cycles */
+#define D11SCC_SLOW2FAST_TRANSITION	2
+
+/* Setup resource up/down timers */
+typedef struct {
+	u8 resnum;
+	u16 updown;
+} pmu_res_updown_t;
+
+/* Change resource dependancies masks */
+typedef struct {
+	u32 res_mask;	/* resources (chip specific) */
+	s8 action;		/* action */
+	u32 depend_mask;	/* changes to the dependancies mask */
+	 bool(*filter) (si_t *sih);	/* action is taken when filter is NULL or return true */
+} pmu_res_depend_t;
+
+/* setup pll and query clock speed */
+typedef struct {
+	u16 fref;
+	u8 xf;
+	u8 p1div;
+	u8 p2div;
+	u8 ndiv_int;
+	u32 ndiv_frac;
+} pmu1_xtaltab0_t;
+
+/*
+ * prototypes used in resource tables
+ */
+static bool si_pmu_res_depfltr_bb(si_t *sih);
+static bool si_pmu_res_depfltr_ncb(si_t *sih);
+static bool si_pmu_res_depfltr_paldo(si_t *sih);
+static bool si_pmu_res_depfltr_npaldo(si_t *sih);
+
+static const pmu_res_updown_t bcm4328a0_res_updown[] = {
+	{
+	RES4328_EXT_SWITCHER_PWM, 0x0101}, {
+	RES4328_BB_SWITCHER_PWM, 0x1f01}, {
+	RES4328_BB_SWITCHER_BURST, 0x010f}, {
+	RES4328_BB_EXT_SWITCHER_BURST, 0x0101}, {
+	RES4328_ILP_REQUEST, 0x0202}, {
+	RES4328_RADIO_SWITCHER_PWM, 0x0f01}, {
+	RES4328_RADIO_SWITCHER_BURST, 0x0f01}, {
+	RES4328_ROM_SWITCH, 0x0101}, {
+	RES4328_PA_REF_LDO, 0x0f01}, {
+	RES4328_RADIO_LDO, 0x0f01}, {
+	RES4328_AFE_LDO, 0x0f01}, {
+	RES4328_PLL_LDO, 0x0f01}, {
+	RES4328_BG_FILTBYP, 0x0101}, {
+	RES4328_TX_FILTBYP, 0x0101}, {
+	RES4328_RX_FILTBYP, 0x0101}, {
+	RES4328_XTAL_PU, 0x0101}, {
+	RES4328_XTAL_EN, 0xa001}, {
+	RES4328_BB_PLL_FILTBYP, 0x0101}, {
+	RES4328_RF_PLL_FILTBYP, 0x0101}, {
+	RES4328_BB_PLL_PU, 0x0701}
+};
+
+static const pmu_res_depend_t bcm4328a0_res_depend[] = {
+	/* Adjust ILP request resource not to force ext/BB switchers into burst mode */
+	{
+	PMURES_BIT(RES4328_ILP_REQUEST),
+		    RES_DEPEND_SET,
+		    PMURES_BIT(RES4328_EXT_SWITCHER_PWM) |
+		    PMURES_BIT(RES4328_BB_SWITCHER_PWM), NULL}
+};
+
+static const pmu_res_updown_t bcm4325a0_res_updown_qt[] = {
+	{
+	RES4325_HT_AVAIL, 0x0300}, {
+	RES4325_BBPLL_PWRSW_PU, 0x0101}, {
+	RES4325_RFPLL_PWRSW_PU, 0x0101}, {
+	RES4325_ALP_AVAIL, 0x0100}, {
+	RES4325_XTAL_PU, 0x1000}, {
+	RES4325_LNLDO1_PU, 0x0800}, {
+	RES4325_CLDO_CBUCK_PWM, 0x0101}, {
+	RES4325_CBUCK_PWM, 0x0803}
+};
+
+static const pmu_res_updown_t bcm4325a0_res_updown[] = {
+	{
+	RES4325_XTAL_PU, 0x1501}
+};
+
+static const pmu_res_depend_t bcm4325a0_res_depend[] = {
+	/* Adjust OTP PU resource dependencies - remove BB BURST */
+	{
+	PMURES_BIT(RES4325_OTP_PU),
+		    RES_DEPEND_REMOVE,
+		    PMURES_BIT(RES4325_BUCK_BOOST_BURST), NULL},
+	    /* Adjust ALP/HT Avail resource dependencies - bring up BB along if it is used. */
+	{
+	PMURES_BIT(RES4325_ALP_AVAIL) | PMURES_BIT(RES4325_HT_AVAIL),
+		    RES_DEPEND_ADD,
+		    PMURES_BIT(RES4325_BUCK_BOOST_BURST) |
+		    PMURES_BIT(RES4325_BUCK_BOOST_PWM), si_pmu_res_depfltr_bb},
+	    /* Adjust HT Avail resource dependencies - bring up RF switches along with HT. */
+	{
+	PMURES_BIT(RES4325_HT_AVAIL),
+		    RES_DEPEND_ADD,
+		    PMURES_BIT(RES4325_RX_PWRSW_PU) |
+		    PMURES_BIT(RES4325_TX_PWRSW_PU) |
+		    PMURES_BIT(RES4325_LOGEN_PWRSW_PU) |
+		    PMURES_BIT(RES4325_AFE_PWRSW_PU), NULL},
+	    /* Adjust ALL resource dependencies - remove CBUCK dependancies if it is not used. */
+	{
+	PMURES_BIT(RES4325_ILP_REQUEST) |
+		    PMURES_BIT(RES4325_ABUCK_BURST) |
+		    PMURES_BIT(RES4325_ABUCK_PWM) |
+		    PMURES_BIT(RES4325_LNLDO1_PU) |
+		    PMURES_BIT(RES4325C1_LNLDO2_PU) |
+		    PMURES_BIT(RES4325_XTAL_PU) |
+		    PMURES_BIT(RES4325_ALP_AVAIL) |
+		    PMURES_BIT(RES4325_RX_PWRSW_PU) |
+		    PMURES_BIT(RES4325_TX_PWRSW_PU) |
+		    PMURES_BIT(RES4325_RFPLL_PWRSW_PU) |
+		    PMURES_BIT(RES4325_LOGEN_PWRSW_PU) |
+		    PMURES_BIT(RES4325_AFE_PWRSW_PU) |
+		    PMURES_BIT(RES4325_BBPLL_PWRSW_PU) |
+		    PMURES_BIT(RES4325_HT_AVAIL), RES_DEPEND_REMOVE,
+		    PMURES_BIT(RES4325B0_CBUCK_LPOM) |
+		    PMURES_BIT(RES4325B0_CBUCK_BURST) |
+		    PMURES_BIT(RES4325B0_CBUCK_PWM), si_pmu_res_depfltr_ncb}
+};
+
+static const pmu_res_updown_t bcm4315a0_res_updown_qt[] = {
+	{
+	RES4315_HT_AVAIL, 0x0101}, {
+	RES4315_XTAL_PU, 0x0100}, {
+	RES4315_LNLDO1_PU, 0x0100}, {
+	RES4315_PALDO_PU, 0x0100}, {
+	RES4315_CLDO_PU, 0x0100}, {
+	RES4315_CBUCK_PWM, 0x0100}, {
+	RES4315_CBUCK_BURST, 0x0100}, {
+	RES4315_CBUCK_LPOM, 0x0100}
+};
+
+static const pmu_res_updown_t bcm4315a0_res_updown[] = {
+	{
+	RES4315_XTAL_PU, 0x2501}
+};
+
+static const pmu_res_depend_t bcm4315a0_res_depend[] = {
+	/* Adjust OTP PU resource dependencies - not need PALDO unless write */
+	{
+	PMURES_BIT(RES4315_OTP_PU),
+		    RES_DEPEND_REMOVE,
+		    PMURES_BIT(RES4315_PALDO_PU), si_pmu_res_depfltr_npaldo},
+	    /* Adjust ALP/HT Avail resource dependencies - bring up PALDO along if it is used. */
+	{
+	PMURES_BIT(RES4315_ALP_AVAIL) | PMURES_BIT(RES4315_HT_AVAIL),
+		    RES_DEPEND_ADD,
+		    PMURES_BIT(RES4315_PALDO_PU), si_pmu_res_depfltr_paldo},
+	    /* Adjust HT Avail resource dependencies - bring up RF switches along with HT. */
+	{
+	PMURES_BIT(RES4315_HT_AVAIL),
+		    RES_DEPEND_ADD,
+		    PMURES_BIT(RES4315_RX_PWRSW_PU) |
+		    PMURES_BIT(RES4315_TX_PWRSW_PU) |
+		    PMURES_BIT(RES4315_LOGEN_PWRSW_PU) |
+		    PMURES_BIT(RES4315_AFE_PWRSW_PU), NULL},
+	    /* Adjust ALL resource dependencies - remove CBUCK dependancies if it is not used. */
+	{
+	PMURES_BIT(RES4315_CLDO_PU) | PMURES_BIT(RES4315_ILP_REQUEST) |
+		    PMURES_BIT(RES4315_LNLDO1_PU) |
+		    PMURES_BIT(RES4315_OTP_PU) |
+		    PMURES_BIT(RES4315_LNLDO2_PU) |
+		    PMURES_BIT(RES4315_XTAL_PU) |
+		    PMURES_BIT(RES4315_ALP_AVAIL) |
+		    PMURES_BIT(RES4315_RX_PWRSW_PU) |
+		    PMURES_BIT(RES4315_TX_PWRSW_PU) |
+		    PMURES_BIT(RES4315_RFPLL_PWRSW_PU) |
+		    PMURES_BIT(RES4315_LOGEN_PWRSW_PU) |
+		    PMURES_BIT(RES4315_AFE_PWRSW_PU) |
+		    PMURES_BIT(RES4315_BBPLL_PWRSW_PU) |
+		    PMURES_BIT(RES4315_HT_AVAIL), RES_DEPEND_REMOVE,
+		    PMURES_BIT(RES4315_CBUCK_LPOM) |
+		    PMURES_BIT(RES4315_CBUCK_BURST) |
+		    PMURES_BIT(RES4315_CBUCK_PWM), si_pmu_res_depfltr_ncb}
+};
+
+	/* 4329 specific. needs to come back this issue later */
+static const pmu_res_updown_t bcm4329_res_updown[] = {
+	{
+	RES4329_XTAL_PU, 0x1501}
+};
+
+static const pmu_res_depend_t bcm4329_res_depend[] = {
+	/* Adjust HT Avail resource dependencies */
+	{
+	PMURES_BIT(RES4329_HT_AVAIL),
+		    RES_DEPEND_ADD,
+		    PMURES_BIT(RES4329_CBUCK_LPOM) |
+		    PMURES_BIT(RES4329_CBUCK_BURST) |
+		    PMURES_BIT(RES4329_CBUCK_PWM) |
+		    PMURES_BIT(RES4329_CLDO_PU) |
+		    PMURES_BIT(RES4329_PALDO_PU) |
+		    PMURES_BIT(RES4329_LNLDO1_PU) |
+		    PMURES_BIT(RES4329_XTAL_PU) |
+		    PMURES_BIT(RES4329_ALP_AVAIL) |
+		    PMURES_BIT(RES4329_RX_PWRSW_PU) |
+		    PMURES_BIT(RES4329_TX_PWRSW_PU) |
+		    PMURES_BIT(RES4329_RFPLL_PWRSW_PU) |
+		    PMURES_BIT(RES4329_LOGEN_PWRSW_PU) |
+		    PMURES_BIT(RES4329_AFE_PWRSW_PU) |
+		    PMURES_BIT(RES4329_BBPLL_PWRSW_PU), NULL}
+};
+
+static const pmu_res_updown_t bcm4319a0_res_updown_qt[] = {
+	{
+	RES4319_HT_AVAIL, 0x0101}, {
+	RES4319_XTAL_PU, 0x0100}, {
+	RES4319_LNLDO1_PU, 0x0100}, {
+	RES4319_PALDO_PU, 0x0100}, {
+	RES4319_CLDO_PU, 0x0100}, {
+	RES4319_CBUCK_PWM, 0x0100}, {
+	RES4319_CBUCK_BURST, 0x0100}, {
+	RES4319_CBUCK_LPOM, 0x0100}
+};
+
+static const pmu_res_updown_t bcm4319a0_res_updown[] = {
+	{
+	RES4319_XTAL_PU, 0x3f01}
+};
+
+static const pmu_res_depend_t bcm4319a0_res_depend[] = {
+	/* Adjust OTP PU resource dependencies - not need PALDO unless write */
+	{
+	PMURES_BIT(RES4319_OTP_PU),
+		    RES_DEPEND_REMOVE,
+		    PMURES_BIT(RES4319_PALDO_PU), si_pmu_res_depfltr_npaldo},
+	    /* Adjust HT Avail resource dependencies - bring up PALDO along if it is used. */
+	{
+	PMURES_BIT(RES4319_HT_AVAIL),
+		    RES_DEPEND_ADD,
+		    PMURES_BIT(RES4319_PALDO_PU), si_pmu_res_depfltr_paldo},
+	    /* Adjust HT Avail resource dependencies - bring up RF switches along with HT. */
+	{
+	PMURES_BIT(RES4319_HT_AVAIL),
+		    RES_DEPEND_ADD,
+		    PMURES_BIT(RES4319_RX_PWRSW_PU) |
+		    PMURES_BIT(RES4319_TX_PWRSW_PU) |
+		    PMURES_BIT(RES4319_RFPLL_PWRSW_PU) |
+		    PMURES_BIT(RES4319_LOGEN_PWRSW_PU) |
+		    PMURES_BIT(RES4319_AFE_PWRSW_PU), NULL}
+};
+
+static const pmu_res_updown_t bcm4336a0_res_updown_qt[] = {
+	{
+	RES4336_HT_AVAIL, 0x0101}, {
+	RES4336_XTAL_PU, 0x0100}, {
+	RES4336_CLDO_PU, 0x0100}, {
+	RES4336_CBUCK_PWM, 0x0100}, {
+	RES4336_CBUCK_BURST, 0x0100}, {
+	RES4336_CBUCK_LPOM, 0x0100}
+};
+
+static const pmu_res_updown_t bcm4336a0_res_updown[] = {
+	{
+	RES4336_HT_AVAIL, 0x0D01}
+};
+
+static const pmu_res_depend_t bcm4336a0_res_depend[] = {
+	/* Just a dummy entry for now */
+	{
+	PMURES_BIT(RES4336_RSVD), RES_DEPEND_ADD, 0, NULL}
+};
+
+static const pmu_res_updown_t bcm4330a0_res_updown_qt[] = {
+	{
+	RES4330_HT_AVAIL, 0x0101}, {
+	RES4330_XTAL_PU, 0x0100}, {
+	RES4330_CLDO_PU, 0x0100}, {
+	RES4330_CBUCK_PWM, 0x0100}, {
+	RES4330_CBUCK_BURST, 0x0100}, {
+	RES4330_CBUCK_LPOM, 0x0100}
+};
+
+static const pmu_res_updown_t bcm4330a0_res_updown[] = {
+	{
+	RES4330_HT_AVAIL, 0x0e02}
+};
+
+static const pmu_res_depend_t bcm4330a0_res_depend[] = {
+	/* Just a dummy entry for now */
+	{
+	PMURES_BIT(RES4330_HT_AVAIL), RES_DEPEND_ADD, 0, NULL}
+};
+
+/* the following table is based on 1440Mhz fvco */
+static const pmu1_xtaltab0_t pmu1_xtaltab0_1440[] = {
+	{
+	12000, 1, 1, 1, 0x78, 0x0}, {
+	13000, 2, 1, 1, 0x6E, 0xC4EC4E}, {
+	14400, 3, 1, 1, 0x64, 0x0}, {
+	15360, 4, 1, 1, 0x5D, 0xC00000}, {
+	16200, 5, 1, 1, 0x58, 0xE38E38}, {
+	16800, 6, 1, 1, 0x55, 0xB6DB6D}, {
+	19200, 7, 1, 1, 0x4B, 0}, {
+	19800, 8, 1, 1, 0x48, 0xBA2E8B}, {
+	20000, 9, 1, 1, 0x48, 0x0}, {
+	25000, 10, 1, 1, 0x39, 0x999999}, {
+	26000, 11, 1, 1, 0x37, 0x627627}, {
+	30000, 12, 1, 1, 0x30, 0x0}, {
+	37400, 13, 2, 1, 0x4D, 0x15E76}, {
+	38400, 13, 2, 1, 0x4B, 0x0}, {
+	40000, 14, 2, 1, 0x48, 0x0}, {
+	48000, 15, 2, 1, 0x3c, 0x0}, {
+	0, 0, 0, 0, 0, 0}
+};
+
+static const pmu1_xtaltab0_t pmu1_xtaltab0_960[] = {
+	{
+	12000, 1, 1, 1, 0x50, 0x0}, {
+	13000, 2, 1, 1, 0x49, 0xD89D89}, {
+	14400, 3, 1, 1, 0x42, 0xAAAAAA}, {
+	15360, 4, 1, 1, 0x3E, 0x800000}, {
+	16200, 5, 1, 1, 0x39, 0x425ED0}, {
+	16800, 6, 1, 1, 0x39, 0x249249}, {
+	19200, 7, 1, 1, 0x32, 0x0}, {
+	19800, 8, 1, 1, 0x30, 0x7C1F07}, {
+	20000, 9, 1, 1, 0x30, 0x0}, {
+	25000, 10, 1, 1, 0x26, 0x666666}, {
+	26000, 11, 1, 1, 0x24, 0xEC4EC4}, {
+	30000, 12, 1, 1, 0x20, 0x0}, {
+	37400, 13, 2, 1, 0x33, 0x563EF9}, {
+	38400, 14, 2, 1, 0x32, 0x0}, {
+	40000, 15, 2, 1, 0x30, 0x0}, {
+	48000, 16, 2, 1, 0x28, 0x0}, {
+	0, 0, 0, 0, 0, 0}
+};
+
+static const pmu1_xtaltab0_t pmu1_xtaltab0_880_4329[] = {
+	{
+	12000, 1, 3, 22, 0x9, 0xFFFFEF}, {
+	13000, 2, 1, 6, 0xb, 0x483483}, {
+	14400, 3, 1, 10, 0xa, 0x1C71C7}, {
+	15360, 4, 1, 5, 0xb, 0x755555}, {
+	16200, 5, 1, 10, 0x5, 0x6E9E06}, {
+	16800, 6, 1, 10, 0x5, 0x3Cf3Cf}, {
+	19200, 7, 1, 4, 0xb, 0x755555}, {
+	19800, 8, 1, 11, 0x4, 0xA57EB}, {
+	20000, 9, 1, 11, 0x4, 0x0}, {
+	24000, 10, 3, 11, 0xa, 0x0}, {
+	25000, 11, 5, 16, 0xb, 0x0}, {
+	26000, 12, 1, 1, 0x21, 0xD89D89}, {
+	30000, 13, 3, 8, 0xb, 0x0}, {
+	37400, 14, 3, 1, 0x46, 0x969696}, {
+	38400, 15, 1, 1, 0x16, 0xEAAAAA}, {
+	40000, 16, 1, 2, 0xb, 0}, {
+	0, 0, 0, 0, 0, 0}
+};
+
+/* the following table is based on 880Mhz fvco */
+static const pmu1_xtaltab0_t pmu1_xtaltab0_880[] = {
+	{
+	12000, 1, 3, 22, 0x9, 0xFFFFEF}, {
+	13000, 2, 1, 6, 0xb, 0x483483}, {
+	14400, 3, 1, 10, 0xa, 0x1C71C7}, {
+	15360, 4, 1, 5, 0xb, 0x755555}, {
+	16200, 5, 1, 10, 0x5, 0x6E9E06}, {
+	16800, 6, 1, 10, 0x5, 0x3Cf3Cf}, {
+	19200, 7, 1, 4, 0xb, 0x755555}, {
+	19800, 8, 1, 11, 0x4, 0xA57EB}, {
+	20000, 9, 1, 11, 0x4, 0x0}, {
+	24000, 10, 3, 11, 0xa, 0x0}, {
+	25000, 11, 5, 16, 0xb, 0x0}, {
+	26000, 12, 1, 2, 0x10, 0xEC4EC4}, {
+	30000, 13, 3, 8, 0xb, 0x0}, {
+	33600, 14, 1, 2, 0xd, 0x186186}, {
+	38400, 15, 1, 2, 0xb, 0x755555}, {
+	40000, 16, 1, 2, 0xb, 0}, {
+	0, 0, 0, 0, 0, 0}
+};
+
+/* true if the power topology uses the buck boost to provide 3.3V to VDDIO_RF and WLAN PA */
+static bool si_pmu_res_depfltr_bb(si_t *sih)
+{
+	return (sih->boardflags & BFL_BUCKBOOST) != 0;
+}
+
+/* true if the power topology doesn't use the cbuck. Key on chiprev also if the chip is BCM4325. */
+static bool si_pmu_res_depfltr_ncb(si_t *sih)
+{
+
+	return (sih->boardflags & BFL_NOCBUCK) != 0;
+}
+
+/* true if the power topology uses the PALDO */
+static bool si_pmu_res_depfltr_paldo(si_t *sih)
+{
+	return (sih->boardflags & BFL_PALDO) != 0;
+}
+
+/* true if the power topology doesn't use the PALDO */
+static bool si_pmu_res_depfltr_npaldo(si_t *sih)
+{
+	return (sih->boardflags & BFL_PALDO) == 0;
+}
+
+/* Return dependancies (direct or all/indirect) for the given resources */
+static u32
+si_pmu_res_deps(si_t *sih, chipcregs_t *cc, u32 rsrcs,
+		bool all)
+{
+	u32 deps = 0;
+	u32 i;
+
+	for (i = 0; i <= PMURES_MAX_RESNUM; i++) {
+		if (!(rsrcs & PMURES_BIT(i)))
+			continue;
+		W_REG(&cc->res_table_sel, i);
+		deps |= R_REG(&cc->res_dep_mask);
+	}
+
+	return !all ? deps : (deps
+			      ? (deps |
+				 si_pmu_res_deps(sih, cc, deps,
+						 true)) : 0);
+}
+
+/* Determine min/max rsrc masks. Value 0 leaves hardware at default. */
+static void si_pmu_res_masks(si_t *sih, u32 * pmin, u32 * pmax)
+{
+	u32 min_mask = 0, max_mask = 0;
+	uint rsrcs;
+	char *val;
+
+	/* # resources */
+	rsrcs = (sih->pmucaps & PCAP_RC_MASK) >> PCAP_RC_SHIFT;
+
+	/* determine min/max rsrc masks */
+	switch (sih->chip) {
+	case BCM43224_CHIP_ID:
+	case BCM43225_CHIP_ID:
+	case BCM43421_CHIP_ID:
+	case BCM43235_CHIP_ID:
+	case BCM43236_CHIP_ID:
+	case BCM43238_CHIP_ID:
+	case BCM4331_CHIP_ID:
+	case BCM6362_CHIP_ID:
+		/* ??? */
+		break;
+
+	case BCM4329_CHIP_ID:
+		/* 4329 spedific issue. Needs to come back this issue later */
+		/* Down to save the power. */
+		min_mask =
+		    PMURES_BIT(RES4329_CBUCK_LPOM) |
+		    PMURES_BIT(RES4329_CLDO_PU);
+		/* Allow (but don't require) PLL to turn on */
+		max_mask = 0x3ff63e;
+		break;
+	case BCM4319_CHIP_ID:
+		/* We only need a few resources to be kept on all the time */
+		min_mask = PMURES_BIT(RES4319_CBUCK_LPOM) |
+		    PMURES_BIT(RES4319_CLDO_PU);
+
+		/* Allow everything else to be turned on upon requests */
+		max_mask = ~(~0 << rsrcs);
+		break;
+	case BCM4336_CHIP_ID:
+		/* Down to save the power. */
+		min_mask =
+		    PMURES_BIT(RES4336_CBUCK_LPOM) | PMURES_BIT(RES4336_CLDO_PU)
+		    | PMURES_BIT(RES4336_LDO3P3_PU) | PMURES_BIT(RES4336_OTP_PU)
+		    | PMURES_BIT(RES4336_DIS_INT_RESET_PD);
+		/* Allow (but don't require) PLL to turn on */
+		max_mask = 0x1ffffff;
+		break;
+
+	case BCM4330_CHIP_ID:
+		/* Down to save the power. */
+		min_mask =
+		    PMURES_BIT(RES4330_CBUCK_LPOM) | PMURES_BIT(RES4330_CLDO_PU)
+		    | PMURES_BIT(RES4330_DIS_INT_RESET_PD) |
+		    PMURES_BIT(RES4330_LDO3P3_PU) | PMURES_BIT(RES4330_OTP_PU);
+		/* Allow (but don't require) PLL to turn on */
+		max_mask = 0xfffffff;
+		break;
+
+	case BCM4313_CHIP_ID:
+		min_mask = PMURES_BIT(RES4313_BB_PU_RSRC) |
+		    PMURES_BIT(RES4313_XTAL_PU_RSRC) |
+		    PMURES_BIT(RES4313_ALP_AVAIL_RSRC) |
+		    PMURES_BIT(RES4313_BB_PLL_PWRSW_RSRC);
+		max_mask = 0xffff;
+		break;
+	default:
+		break;
+	}
+
+	/* Apply nvram override to min mask */
+	val = getvar(NULL, "rmin");
+	if (val != NULL) {
+		min_mask = (u32) simple_strtoul(val, NULL, 0);
+	}
+	/* Apply nvram override to max mask */
+	val = getvar(NULL, "rmax");
+	if (val != NULL) {
+		max_mask = (u32) simple_strtoul(val, NULL, 0);
+	}
+
+	*pmin = min_mask;
+	*pmax = max_mask;
+}
+
+/* Return up time in ILP cycles for the given resource. */
+static uint
+si_pmu_res_uptime(si_t *sih, chipcregs_t *cc, u8 rsrc) {
+	u32 deps;
+	uint up, i, dup, dmax;
+	u32 min_mask = 0, max_mask = 0;
+
+	/* uptime of resource 'rsrc' */
+	W_REG(&cc->res_table_sel, rsrc);
+	up = (R_REG(&cc->res_updn_timer) >> 8) & 0xff;
+
+	/* direct dependancies of resource 'rsrc' */
+	deps = si_pmu_res_deps(sih, cc, PMURES_BIT(rsrc), false);
+	for (i = 0; i <= PMURES_MAX_RESNUM; i++) {
+		if (!(deps & PMURES_BIT(i)))
+			continue;
+		deps &= ~si_pmu_res_deps(sih, cc, PMURES_BIT(i), true);
+	}
+	si_pmu_res_masks(sih, &min_mask, &max_mask);
+	deps &= ~min_mask;
+
+	/* max uptime of direct dependancies */
+	dmax = 0;
+	for (i = 0; i <= PMURES_MAX_RESNUM; i++) {
+		if (!(deps & PMURES_BIT(i)))
+			continue;
+		dup = si_pmu_res_uptime(sih, cc, (u8) i);
+		if (dmax < dup)
+			dmax = dup;
+	}
+
+	return up + dmax + PMURES_UP_TRANSITION;
+}
+
+static void
+si_pmu_spuravoid_pllupdate(si_t *sih, chipcregs_t *cc, u8 spuravoid)
+{
+	u32 tmp = 0;
+	u8 phypll_offset = 0;
+	u8 bcm5357_bcm43236_p1div[] = { 0x1, 0x5, 0x5 };
+	u8 bcm5357_bcm43236_ndiv[] = { 0x30, 0xf6, 0xfc };
+
+	switch (sih->chip) {
+	case BCM5357_CHIP_ID:
+	case BCM43235_CHIP_ID:
+	case BCM43236_CHIP_ID:
+	case BCM43238_CHIP_ID:
+
+		/*
+		 * BCM5357 needs to touch PLL1_PLLCTL[02],
+		 * so offset PLL0_PLLCTL[02] by 6
+		 */
+		phypll_offset = (sih->chip == BCM5357_CHIP_ID) ? 6 : 0;
+
+		/* RMW only the P1 divider */
+		W_REG(&cc->pllcontrol_addr,
+		      PMU1_PLL0_PLLCTL0 + phypll_offset);
+		tmp = R_REG(&cc->pllcontrol_data);
+		tmp &= (~(PMU1_PLL0_PC0_P1DIV_MASK));
+		tmp |=
+		    (bcm5357_bcm43236_p1div[spuravoid] <<
+		     PMU1_PLL0_PC0_P1DIV_SHIFT);
+		W_REG(&cc->pllcontrol_data, tmp);
+
+		/* RMW only the int feedback divider */
+		W_REG(&cc->pllcontrol_addr,
+		      PMU1_PLL0_PLLCTL2 + phypll_offset);
+		tmp = R_REG(&cc->pllcontrol_data);
+		tmp &= ~(PMU1_PLL0_PC2_NDIV_INT_MASK);
+		tmp |=
+		    (bcm5357_bcm43236_ndiv[spuravoid]) <<
+		    PMU1_PLL0_PC2_NDIV_INT_SHIFT;
+		W_REG(&cc->pllcontrol_data, tmp);
+
+		tmp = 1 << 10;
+		break;
+
+	case BCM4331_CHIP_ID:
+		if (spuravoid == 2) {
+			W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0);
+			W_REG(&cc->pllcontrol_data, 0x11500014);
+			W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2);
+			W_REG(&cc->pllcontrol_data, 0x0FC00a08);
+		} else if (spuravoid == 1) {
+			W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0);
+			W_REG(&cc->pllcontrol_data, 0x11500014);
+			W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2);
+			W_REG(&cc->pllcontrol_data, 0x0F600a08);
+		} else {
+			W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0);
+			W_REG(&cc->pllcontrol_data, 0x11100014);
+			W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2);
+			W_REG(&cc->pllcontrol_data, 0x03000a08);
+		}
+		tmp = 1 << 10;
+		break;
+
+	case BCM43224_CHIP_ID:
+	case BCM43225_CHIP_ID:
+	case BCM43421_CHIP_ID:
+	case BCM6362_CHIP_ID:
+		if (spuravoid == 1) {
+			W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0);
+			W_REG(&cc->pllcontrol_data, 0x11500010);
+			W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL1);
+			W_REG(&cc->pllcontrol_data, 0x000C0C06);
+			W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2);
+			W_REG(&cc->pllcontrol_data, 0x0F600a08);
+			W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL3);
+			W_REG(&cc->pllcontrol_data, 0x00000000);
+			W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL4);
+			W_REG(&cc->pllcontrol_data, 0x2001E920);
+			W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL5);
+			W_REG(&cc->pllcontrol_data, 0x88888815);
+		} else {
+			W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0);
+			W_REG(&cc->pllcontrol_data, 0x11100010);
+			W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL1);
+			W_REG(&cc->pllcontrol_data, 0x000c0c06);
+			W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2);
+			W_REG(&cc->pllcontrol_data, 0x03000a08);
+			W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL3);
+			W_REG(&cc->pllcontrol_data, 0x00000000);
+			W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL4);
+			W_REG(&cc->pllcontrol_data, 0x200005c0);
+			W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL5);
+			W_REG(&cc->pllcontrol_data, 0x88888815);
+		}
+		tmp = 1 << 10;
+		break;
+
+		W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0);
+		W_REG(&cc->pllcontrol_data, 0x11100008);
+		W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL1);
+		W_REG(&cc->pllcontrol_data, 0x0c000c06);
+		W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2);
+		W_REG(&cc->pllcontrol_data, 0x03000a08);
+		W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL3);
+		W_REG(&cc->pllcontrol_data, 0x00000000);
+		W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL4);
+		W_REG(&cc->pllcontrol_data, 0x200005c0);
+		W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL5);
+		W_REG(&cc->pllcontrol_data, 0x88888855);
+
+		tmp = 1 << 10;
+		break;
+
+	case BCM4716_CHIP_ID:
+	case BCM4748_CHIP_ID:
+	case BCM47162_CHIP_ID:
+		if (spuravoid == 1) {
+			W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0);
+			W_REG(&cc->pllcontrol_data, 0x11500060);
+			W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL1);
+			W_REG(&cc->pllcontrol_data, 0x080C0C06);
+			W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2);
+			W_REG(&cc->pllcontrol_data, 0x0F600000);
+			W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL3);
+			W_REG(&cc->pllcontrol_data, 0x00000000);
+			W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL4);
+			W_REG(&cc->pllcontrol_data, 0x2001E924);
+			W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL5);
+			W_REG(&cc->pllcontrol_data, 0x88888815);
+		} else {
+			W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0);
+			W_REG(&cc->pllcontrol_data, 0x11100060);
+			W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL1);
+			W_REG(&cc->pllcontrol_data, 0x080c0c06);
+			W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2);
+			W_REG(&cc->pllcontrol_data, 0x03000000);
+			W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL3);
+			W_REG(&cc->pllcontrol_data, 0x00000000);
+			W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL4);
+			W_REG(&cc->pllcontrol_data, 0x200005c0);
+			W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL5);
+			W_REG(&cc->pllcontrol_data, 0x88888815);
+		}
+
+		tmp = 3 << 9;
+		break;
+
+	case BCM4319_CHIP_ID:
+		W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0);
+		W_REG(&cc->pllcontrol_data, 0x11100070);
+		W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL1);
+		W_REG(&cc->pllcontrol_data, 0x1014140a);
+		W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL5);
+		W_REG(&cc->pllcontrol_data, 0x88888854);
+
+		if (spuravoid == 1) {
+			/* spur_avoid ON, so enable 41/82/164Mhz clock mode */
+			W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2);
+			W_REG(&cc->pllcontrol_data, 0x05201828);
+		} else {
+			/* enable 40/80/160Mhz clock mode */
+			W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2);
+			W_REG(&cc->pllcontrol_data, 0x05001828);
+		}
+		break;
+	case BCM4336_CHIP_ID:
+		/* Looks like these are only for default xtal freq 26MHz */
+		W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0);
+		W_REG(&cc->pllcontrol_data, 0x02100020);
+
+		W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL1);
+		W_REG(&cc->pllcontrol_data, 0x0C0C0C0C);
+
+		W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2);
+		W_REG(&cc->pllcontrol_data, 0x01240C0C);
+
+		W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL4);
+		W_REG(&cc->pllcontrol_data, 0x202C2820);
+
+		W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL5);
+		W_REG(&cc->pllcontrol_data, 0x88888825);
+
+		W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL3);
+		if (spuravoid == 1)
+			W_REG(&cc->pllcontrol_data, 0x00EC4EC4);
+		else
+			W_REG(&cc->pllcontrol_data, 0x00762762);
+
+		tmp = PCTL_PLL_PLLCTL_UPD;
+		break;
+
+	default:
+		/* bail out */
+		return;
+	}
+
+	tmp |= R_REG(&cc->pmucontrol);
+	W_REG(&cc->pmucontrol, tmp);
+}
+
+/* select default xtal frequency for each chip */
+static const pmu1_xtaltab0_t *si_pmu1_xtaldef0(si_t *sih)
+{
+	switch (sih->chip) {
+	case BCM4329_CHIP_ID:
+		/* Default to 38400Khz */
+		return &pmu1_xtaltab0_880_4329[PMU1_XTALTAB0_880_38400K];
+	case BCM4319_CHIP_ID:
+		/* Default to 30000Khz */
+		return &pmu1_xtaltab0_1440[PMU1_XTALTAB0_1440_30000K];
+	case BCM4336_CHIP_ID:
+		/* Default to 26000Khz */
+		return &pmu1_xtaltab0_960[PMU1_XTALTAB0_960_26000K];
+	case BCM4330_CHIP_ID:
+		/* Default to 37400Khz */
+		if (CST4330_CHIPMODE_SDIOD(sih->chipst))
+			return &pmu1_xtaltab0_960[PMU1_XTALTAB0_960_37400K];
+		else
+			return &pmu1_xtaltab0_1440[PMU1_XTALTAB0_1440_37400K];
+	default:
+		break;
+	}
+	return NULL;
+}
+
+/* select xtal table for each chip */
+static const pmu1_xtaltab0_t *si_pmu1_xtaltab0(si_t *sih)
+{
+	switch (sih->chip) {
+	case BCM4329_CHIP_ID:
+		return pmu1_xtaltab0_880_4329;
+	case BCM4319_CHIP_ID:
+		return pmu1_xtaltab0_1440;
+	case BCM4336_CHIP_ID:
+		return pmu1_xtaltab0_960;
+	case BCM4330_CHIP_ID:
+		if (CST4330_CHIPMODE_SDIOD(sih->chipst))
+			return pmu1_xtaltab0_960;
+		else
+			return pmu1_xtaltab0_1440;
+	default:
+		break;
+	}
+	return NULL;
+}
+
+/* query alp/xtal clock frequency */
+static u32
+si_pmu1_alpclk0(si_t *sih, chipcregs_t *cc)
+{
+	const pmu1_xtaltab0_t *xt;
+	u32 xf;
+
+	/* Find the frequency in the table */
+	xf = (R_REG(&cc->pmucontrol) & PCTL_XTALFREQ_MASK) >>
+	    PCTL_XTALFREQ_SHIFT;
+	for (xt = si_pmu1_xtaltab0(sih); xt != NULL && xt->fref != 0; xt++)
+		if (xt->xf == xf)
+			break;
+	/* Could not find it so assign a default value */
+	if (xt == NULL || xt->fref == 0)
+		xt = si_pmu1_xtaldef0(sih);
+	return xt->fref * 1000;
+}
+
+/* select default pll fvco for each chip */
+static u32 si_pmu1_pllfvco0(si_t *sih)
+{
+	switch (sih->chip) {
+	case BCM4329_CHIP_ID:
+		return FVCO_880;
+	case BCM4319_CHIP_ID:
+		return FVCO_1440;
+	case BCM4336_CHIP_ID:
+		return FVCO_960;
+	case BCM4330_CHIP_ID:
+		if (CST4330_CHIPMODE_SDIOD(sih->chipst))
+			return FVCO_960;
+		else
+			return FVCO_1440;
+	default:
+		break;
+	}
+	return 0;
+}
+
+static void si_pmu_set_4330_plldivs(si_t *sih)
+{
+	u32 FVCO = si_pmu1_pllfvco0(sih) / 1000;
+	u32 m1div, m2div, m3div, m4div, m5div, m6div;
+	u32 pllc1, pllc2;
+
+	m2div = m3div = m4div = m6div = FVCO / 80;
+	m5div = FVCO / 160;
+
+	if (CST4330_CHIPMODE_SDIOD(sih->chipst))
+		m1div = FVCO / 80;
+	else
+		m1div = FVCO / 90;
+	pllc1 =
+	    (m1div << PMU1_PLL0_PC1_M1DIV_SHIFT) | (m2div <<
+						    PMU1_PLL0_PC1_M2DIV_SHIFT) |
+	    (m3div << PMU1_PLL0_PC1_M3DIV_SHIFT) | (m4div <<
+						    PMU1_PLL0_PC1_M4DIV_SHIFT);
+	si_pmu_pllcontrol(sih, PMU1_PLL0_PLLCTL1, ~0, pllc1);
+
+	pllc2 = si_pmu_pllcontrol(sih, PMU1_PLL0_PLLCTL1, 0, 0);
+	pllc2 &= ~(PMU1_PLL0_PC2_M5DIV_MASK | PMU1_PLL0_PC2_M6DIV_MASK);
+	pllc2 |=
+	    ((m5div << PMU1_PLL0_PC2_M5DIV_SHIFT) |
+	     (m6div << PMU1_PLL0_PC2_M6DIV_SHIFT));
+	si_pmu_pllcontrol(sih, PMU1_PLL0_PLLCTL2, ~0, pllc2);
+}
+
+/* Set up PLL registers in the PMU as per the crystal speed.
+ * XtalFreq field in pmucontrol register being 0 indicates the PLL
+ * is not programmed and the h/w default is assumed to work, in which
+ * case the xtal frequency is unknown to the s/w so we need to call
+ * si_pmu1_xtaldef0() wherever it is needed to return a default value.
+ */
+static void si_pmu1_pllinit0(si_t *sih, chipcregs_t *cc, u32 xtal)
+{
+	const pmu1_xtaltab0_t *xt;
+	u32 tmp;
+	u32 buf_strength = 0;
+	u8 ndiv_mode = 1;
+
+	/* Use h/w default PLL config */
+	if (xtal == 0) {
+		return;
+	}
+
+	/* Find the frequency in the table */
+	for (xt = si_pmu1_xtaltab0(sih); xt != NULL && xt->fref != 0; xt++)
+		if (xt->fref == xtal)
+			break;
+
+	/* Check current PLL state, bail out if it has been programmed or
+	 * we don't know how to program it.
+	 */
+	if (xt == NULL || xt->fref == 0) {
+		return;
+	}
+	/* for 4319 bootloader already programs the PLL but bootloader does not
+	 * program the PLL4 and PLL5. So Skip this check for 4319
+	 */
+	if ((((R_REG(&cc->pmucontrol) & PCTL_XTALFREQ_MASK) >>
+	      PCTL_XTALFREQ_SHIFT) == xt->xf) &&
+	    !((sih->chip == BCM4319_CHIP_ID)
+	      || (sih->chip == BCM4330_CHIP_ID)))
+		return;
+
+	switch (sih->chip) {
+	case BCM4329_CHIP_ID:
+		/* Change the BBPLL drive strength to 8 for all channels */
+		buf_strength = 0x888888;
+		AND_REG(&cc->min_res_mask,
+			~(PMURES_BIT(RES4329_BBPLL_PWRSW_PU) |
+			  PMURES_BIT(RES4329_HT_AVAIL)));
+		AND_REG(&cc->max_res_mask,
+			~(PMURES_BIT(RES4329_BBPLL_PWRSW_PU) |
+			  PMURES_BIT(RES4329_HT_AVAIL)));
+		SPINWAIT(R_REG(&cc->clk_ctl_st) & CCS_HTAVAIL,
+			 PMU_MAX_TRANSITION_DLY);
+		W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL4);
+		if (xt->fref == 38400)
+			tmp = 0x200024C0;
+		else if (xt->fref == 37400)
+			tmp = 0x20004500;
+		else if (xt->fref == 26000)
+			tmp = 0x200024C0;
+		else
+			tmp = 0x200005C0;	/* Chip Dflt Settings */
+		W_REG(&cc->pllcontrol_data, tmp);
+		W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL5);
+		tmp =
+		    R_REG(&cc->pllcontrol_data) & PMU1_PLL0_PC5_CLK_DRV_MASK;
+		if ((xt->fref == 38400) || (xt->fref == 37400)
+		    || (xt->fref == 26000))
+			tmp |= 0x15;
+		else
+			tmp |= 0x25;	/* Chip Dflt Settings */
+		W_REG(&cc->pllcontrol_data, tmp);
+		break;
+
+	case BCM4319_CHIP_ID:
+		/* Change the BBPLL drive strength to 2 for all channels */
+		buf_strength = 0x222222;
+
+		/* Make sure the PLL is off */
+		/* WAR65104: Disable the HT_AVAIL resource first and then
+		 * after a delay (more than downtime for HT_AVAIL) remove the
+		 * BBPLL resource; backplane clock moves to ALP from HT.
+		 */
+		AND_REG(&cc->min_res_mask,
+			~(PMURES_BIT(RES4319_HT_AVAIL)));
+		AND_REG(&cc->max_res_mask,
+			~(PMURES_BIT(RES4319_HT_AVAIL)));
+
+		udelay(100);
+		AND_REG(&cc->min_res_mask,
+			~(PMURES_BIT(RES4319_BBPLL_PWRSW_PU)));
+		AND_REG(&cc->max_res_mask,
+			~(PMURES_BIT(RES4319_BBPLL_PWRSW_PU)));
+
+		udelay(100);
+		SPINWAIT(R_REG(&cc->clk_ctl_st) & CCS_HTAVAIL,
+			 PMU_MAX_TRANSITION_DLY);
+		W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL4);
+		tmp = 0x200005c0;
+		W_REG(&cc->pllcontrol_data, tmp);
+		break;
+
+	case BCM4336_CHIP_ID:
+		AND_REG(&cc->min_res_mask,
+			~(PMURES_BIT(RES4336_HT_AVAIL) |
+			  PMURES_BIT(RES4336_MACPHY_CLKAVAIL)));
+		AND_REG(&cc->max_res_mask,
+			~(PMURES_BIT(RES4336_HT_AVAIL) |
+			  PMURES_BIT(RES4336_MACPHY_CLKAVAIL)));
+		udelay(100);
+		SPINWAIT(R_REG(&cc->clk_ctl_st) & CCS_HTAVAIL,
+			 PMU_MAX_TRANSITION_DLY);
+		break;
+
+	case BCM4330_CHIP_ID:
+		AND_REG(&cc->min_res_mask,
+			~(PMURES_BIT(RES4330_HT_AVAIL) |
+			  PMURES_BIT(RES4330_MACPHY_CLKAVAIL)));
+		AND_REG(&cc->max_res_mask,
+			~(PMURES_BIT(RES4330_HT_AVAIL) |
+			  PMURES_BIT(RES4330_MACPHY_CLKAVAIL)));
+		udelay(100);
+		SPINWAIT(R_REG(&cc->clk_ctl_st) & CCS_HTAVAIL,
+			 PMU_MAX_TRANSITION_DLY);
+		break;
+
+	default:
+		break;
+	}
+
+	/* Write p1div and p2div to pllcontrol[0] */
+	W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0);
+	tmp = R_REG(&cc->pllcontrol_data) &
+	    ~(PMU1_PLL0_PC0_P1DIV_MASK | PMU1_PLL0_PC0_P2DIV_MASK);
+	tmp |=
+	    ((xt->
+	      p1div << PMU1_PLL0_PC0_P1DIV_SHIFT) & PMU1_PLL0_PC0_P1DIV_MASK) |
+	    ((xt->
+	      p2div << PMU1_PLL0_PC0_P2DIV_SHIFT) & PMU1_PLL0_PC0_P2DIV_MASK);
+	W_REG(&cc->pllcontrol_data, tmp);
+
+	if ((sih->chip == BCM4330_CHIP_ID))
+		si_pmu_set_4330_plldivs(sih);
+
+	if ((sih->chip == BCM4329_CHIP_ID)
+	    && (sih->chiprev == 0)) {
+
+		W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL1);
+		tmp = R_REG(&cc->pllcontrol_data);
+		tmp = tmp & (~DOT11MAC_880MHZ_CLK_DIVISOR_MASK);
+		tmp = tmp | DOT11MAC_880MHZ_CLK_DIVISOR_VAL;
+		W_REG(&cc->pllcontrol_data, tmp);
+	}
+	if ((sih->chip == BCM4319_CHIP_ID) ||
+	    (sih->chip == BCM4336_CHIP_ID) ||
+	    (sih->chip == BCM4330_CHIP_ID))
+		ndiv_mode = PMU1_PLL0_PC2_NDIV_MODE_MFB;
+	else
+		ndiv_mode = PMU1_PLL0_PC2_NDIV_MODE_MASH;
+
+	/* Write ndiv_int and ndiv_mode to pllcontrol[2] */
+	W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2);
+	tmp = R_REG(&cc->pllcontrol_data) &
+	    ~(PMU1_PLL0_PC2_NDIV_INT_MASK | PMU1_PLL0_PC2_NDIV_MODE_MASK);
+	tmp |=
+	    ((xt->
+	      ndiv_int << PMU1_PLL0_PC2_NDIV_INT_SHIFT) &
+	     PMU1_PLL0_PC2_NDIV_INT_MASK) | ((ndiv_mode <<
+					      PMU1_PLL0_PC2_NDIV_MODE_SHIFT) &
+					     PMU1_PLL0_PC2_NDIV_MODE_MASK);
+	W_REG(&cc->pllcontrol_data, tmp);
+
+	/* Write ndiv_frac to pllcontrol[3] */
+	W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL3);
+	tmp = R_REG(&cc->pllcontrol_data) & ~PMU1_PLL0_PC3_NDIV_FRAC_MASK;
+	tmp |= ((xt->ndiv_frac << PMU1_PLL0_PC3_NDIV_FRAC_SHIFT) &
+		PMU1_PLL0_PC3_NDIV_FRAC_MASK);
+	W_REG(&cc->pllcontrol_data, tmp);
+
+	/* Write clock driving strength to pllcontrol[5] */
+	if (buf_strength) {
+		W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL5);
+		tmp =
+		    R_REG(&cc->pllcontrol_data) & ~PMU1_PLL0_PC5_CLK_DRV_MASK;
+		tmp |= (buf_strength << PMU1_PLL0_PC5_CLK_DRV_SHIFT);
+		W_REG(&cc->pllcontrol_data, tmp);
+	}
+
+	/* to operate the 4319 usb in 24MHz/48MHz; chipcontrol[2][84:83] needs
+	 * to be updated.
+	 */
+	if ((sih->chip == BCM4319_CHIP_ID)
+	    && (xt->fref != XTAL_FREQ_30000MHZ)) {
+		W_REG(&cc->chipcontrol_addr, PMU1_PLL0_CHIPCTL2);
+		tmp =
+		    R_REG(&cc->chipcontrol_data) & ~CCTL_4319USB_XTAL_SEL_MASK;
+		if (xt->fref == XTAL_FREQ_24000MHZ) {
+			tmp |=
+			    (CCTL_4319USB_24MHZ_PLL_SEL <<
+			     CCTL_4319USB_XTAL_SEL_SHIFT);
+		} else if (xt->fref == XTAL_FREQ_48000MHZ) {
+			tmp |=
+			    (CCTL_4319USB_48MHZ_PLL_SEL <<
+			     CCTL_4319USB_XTAL_SEL_SHIFT);
+		}
+		W_REG(&cc->chipcontrol_data, tmp);
+	}
+
+	/* Flush deferred pll control registers writes */
+	if (sih->pmurev >= 2)
+		OR_REG(&cc->pmucontrol, PCTL_PLL_PLLCTL_UPD);
+
+	/* Write XtalFreq. Set the divisor also. */
+	tmp = R_REG(&cc->pmucontrol) &
+	    ~(PCTL_ILP_DIV_MASK | PCTL_XTALFREQ_MASK);
+	tmp |= (((((xt->fref + 127) / 128) - 1) << PCTL_ILP_DIV_SHIFT) &
+		PCTL_ILP_DIV_MASK) |
+	    ((xt->xf << PCTL_XTALFREQ_SHIFT) & PCTL_XTALFREQ_MASK);
+
+	if ((sih->chip == BCM4329_CHIP_ID)
+	    && sih->chiprev == 0) {
+		/* clear the htstretch before clearing HTReqEn */
+		AND_REG(&cc->clkstretch, ~CSTRETCH_HT);
+		tmp &= ~PCTL_HT_REQ_EN;
+	}
+
+	W_REG(&cc->pmucontrol, tmp);
+}
+
+u32 si_pmu_ilp_clock(si_t *sih)
+{
+	static u32 ilpcycles_per_sec;
+
+	if (ISSIM_ENAB(sih) || !PMUCTL_ENAB(sih))
+		return ILP_CLOCK;
+
+	if (ilpcycles_per_sec == 0) {
+		u32 start, end, delta;
+		u32 origidx = ai_coreidx(sih);
+		chipcregs_t *cc = ai_setcoreidx(sih, SI_CC_IDX);
+		start = R_REG(&cc->pmutimer);
+		mdelay(ILP_CALC_DUR);
+		end = R_REG(&cc->pmutimer);
+		delta = end - start;
+		ilpcycles_per_sec = delta * (1000 / ILP_CALC_DUR);
+		ai_setcoreidx(sih, origidx);
+	}
+
+	return ilpcycles_per_sec;
+}
+
+void si_pmu_set_ldo_voltage(si_t *sih, u8 ldo, u8 voltage)
+{
+	u8 sr_cntl_shift = 0, rc_shift = 0, shift = 0, mask = 0;
+	u8 addr = 0;
+
+	switch (sih->chip) {
+	case BCM4336_CHIP_ID:
+		switch (ldo) {
+		case SET_LDO_VOLTAGE_CLDO_PWM:
+			addr = 4;
+			rc_shift = 1;
+			mask = 0xf;
+			break;
+		case SET_LDO_VOLTAGE_CLDO_BURST:
+			addr = 4;
+			rc_shift = 5;
+			mask = 0xf;
+			break;
+		case SET_LDO_VOLTAGE_LNLDO1:
+			addr = 4;
+			rc_shift = 17;
+			mask = 0xf;
+			break;
+		default:
+			return;
+		}
+		break;
+	case BCM4330_CHIP_ID:
+		switch (ldo) {
+		case SET_LDO_VOLTAGE_CBUCK_PWM:
+			addr = 3;
+			rc_shift = 0;
+			mask = 0x1f;
+			break;
+		default:
+			return;
+		}
+		break;
+	default:
+		return;
+	}
+
+	shift = sr_cntl_shift + rc_shift;
+
+	ai_corereg(sih, SI_CC_IDX, offsetof(chipcregs_t, regcontrol_addr),
+		   ~0, addr);
+	ai_corereg(sih, SI_CC_IDX, offsetof(chipcregs_t, regcontrol_data),
+		   mask << shift, (voltage & mask) << shift);
+}
+
+u16 si_pmu_fast_pwrup_delay(si_t *sih)
+{
+	uint delay = PMU_MAX_TRANSITION_DLY;
+	chipcregs_t *cc;
+	uint origidx;
+#ifdef BCMDBG
+	char chn[8];
+	chn[0] = 0;		/* to suppress compile error */
+#endif
+
+	/* Remember original core before switch to chipc */
+	origidx = ai_coreidx(sih);
+	cc = ai_setcoreidx(sih, SI_CC_IDX);
+
+	switch (sih->chip) {
+	case BCM43224_CHIP_ID:
+	case BCM43225_CHIP_ID:
+	case BCM43421_CHIP_ID:
+	case BCM43235_CHIP_ID:
+	case BCM43236_CHIP_ID:
+	case BCM43238_CHIP_ID:
+	case BCM4331_CHIP_ID:
+	case BCM6362_CHIP_ID:
+	case BCM4313_CHIP_ID:
+		delay = ISSIM_ENAB(sih) ? 70 : 3700;
+		break;
+	case BCM4329_CHIP_ID:
+		if (ISSIM_ENAB(sih))
+			delay = 70;
+		else {
+			u32 ilp = si_pmu_ilp_clock(sih);
+			delay =
+			    (si_pmu_res_uptime(sih, cc, RES4329_HT_AVAIL) +
+			     D11SCC_SLOW2FAST_TRANSITION) * ((1000000 + ilp -
+							      1) / ilp);
+			delay = (11 * delay) / 10;
+		}
+		break;
+	case BCM4319_CHIP_ID:
+		delay = ISSIM_ENAB(sih) ? 70 : 3700;
+		break;
+	case BCM4336_CHIP_ID:
+		if (ISSIM_ENAB(sih))
+			delay = 70;
+		else {
+			u32 ilp = si_pmu_ilp_clock(sih);
+			delay =
+			    (si_pmu_res_uptime(sih, cc, RES4336_HT_AVAIL) +
+			     D11SCC_SLOW2FAST_TRANSITION) * ((1000000 + ilp -
+							      1) / ilp);
+			delay = (11 * delay) / 10;
+		}
+		break;
+	case BCM4330_CHIP_ID:
+		if (ISSIM_ENAB(sih))
+			delay = 70;
+		else {
+			u32 ilp = si_pmu_ilp_clock(sih);
+			delay =
+			    (si_pmu_res_uptime(sih, cc, RES4330_HT_AVAIL) +
+			     D11SCC_SLOW2FAST_TRANSITION) * ((1000000 + ilp -
+							      1) / ilp);
+			delay = (11 * delay) / 10;
+		}
+		break;
+	default:
+		break;
+	}
+	/* Return to original core */
+	ai_setcoreidx(sih, origidx);
+
+	return (u16) delay;
+}
+
+void si_pmu_sprom_enable(si_t *sih, bool enable)
+{
+	chipcregs_t *cc;
+	uint origidx;
+
+	/* Remember original core before switch to chipc */
+	origidx = ai_coreidx(sih);
+	cc = ai_setcoreidx(sih, SI_CC_IDX);
+
+	/* Return to original core */
+	ai_setcoreidx(sih, origidx);
+}
+
+/* Read/write a chipcontrol reg */
+u32 si_pmu_chipcontrol(si_t *sih, uint reg, u32 mask, u32 val)
+{
+	ai_corereg(sih, SI_CC_IDX, offsetof(chipcregs_t, chipcontrol_addr), ~0,
+		   reg);
+	return ai_corereg(sih, SI_CC_IDX,
+			  offsetof(chipcregs_t, chipcontrol_data), mask, val);
+}
+
+/* Read/write a regcontrol reg */
+u32 si_pmu_regcontrol(si_t *sih, uint reg, u32 mask, u32 val)
+{
+	ai_corereg(sih, SI_CC_IDX, offsetof(chipcregs_t, regcontrol_addr), ~0,
+		   reg);
+	return ai_corereg(sih, SI_CC_IDX,
+			  offsetof(chipcregs_t, regcontrol_data), mask, val);
+}
+
+/* Read/write a pllcontrol reg */
+u32 si_pmu_pllcontrol(si_t *sih, uint reg, u32 mask, u32 val)
+{
+	ai_corereg(sih, SI_CC_IDX, offsetof(chipcregs_t, pllcontrol_addr), ~0,
+		   reg);
+	return ai_corereg(sih, SI_CC_IDX,
+			  offsetof(chipcregs_t, pllcontrol_data), mask, val);
+}
+
+/* PMU PLL update */
+void si_pmu_pllupd(si_t *sih)
+{
+	ai_corereg(sih, SI_CC_IDX, offsetof(chipcregs_t, pmucontrol),
+		   PCTL_PLL_PLLCTL_UPD, PCTL_PLL_PLLCTL_UPD);
+}
+
+/* query alp/xtal clock frequency */
+u32 si_pmu_alp_clock(si_t *sih)
+{
+	chipcregs_t *cc;
+	uint origidx;
+	u32 clock = ALP_CLOCK;
+
+	/* bail out with default */
+	if (!PMUCTL_ENAB(sih))
+		return clock;
+
+	/* Remember original core before switch to chipc */
+	origidx = ai_coreidx(sih);
+	cc = ai_setcoreidx(sih, SI_CC_IDX);
+
+	switch (sih->chip) {
+	case BCM43224_CHIP_ID:
+	case BCM43225_CHIP_ID:
+	case BCM43421_CHIP_ID:
+	case BCM43235_CHIP_ID:
+	case BCM43236_CHIP_ID:
+	case BCM43238_CHIP_ID:
+	case BCM4331_CHIP_ID:
+	case BCM6362_CHIP_ID:
+	case BCM4716_CHIP_ID:
+	case BCM4748_CHIP_ID:
+	case BCM47162_CHIP_ID:
+	case BCM4313_CHIP_ID:
+	case BCM5357_CHIP_ID:
+		/* always 20Mhz */
+		clock = 20000 * 1000;
+		break;
+	case BCM4329_CHIP_ID:
+	case BCM4319_CHIP_ID:
+	case BCM4336_CHIP_ID:
+	case BCM4330_CHIP_ID:
+
+		clock = si_pmu1_alpclk0(sih, cc);
+		break;
+	case BCM5356_CHIP_ID:
+		/* always 25Mhz */
+		clock = 25000 * 1000;
+		break;
+	default:
+		break;
+	}
+
+	/* Return to original core */
+	ai_setcoreidx(sih, origidx);
+	return clock;
+}
+
+void si_pmu_spuravoid(si_t *sih, u8 spuravoid)
+{
+	chipcregs_t *cc;
+	uint origidx, intr_val;
+	u32 tmp = 0;
+
+	/* Remember original core before switch to chipc */
+	cc = (chipcregs_t *) ai_switch_core(sih, CC_CORE_ID, &origidx,
+					    &intr_val);
+
+	/* force the HT off  */
+	if (sih->chip == BCM4336_CHIP_ID) {
+		tmp = R_REG(&cc->max_res_mask);
+		tmp &= ~RES4336_HT_AVAIL;
+		W_REG(&cc->max_res_mask, tmp);
+		/* wait for the ht to really go away */
+		SPINWAIT(((R_REG(&cc->clk_ctl_st) & CCS_HTAVAIL) == 0),
+			 10000);
+	}
+
+	/* update the pll changes */
+	si_pmu_spuravoid_pllupdate(sih, cc, spuravoid);
+
+	/* enable HT back on  */
+	if (sih->chip == BCM4336_CHIP_ID) {
+		tmp = R_REG(&cc->max_res_mask);
+		tmp |= RES4336_HT_AVAIL;
+		W_REG(&cc->max_res_mask, tmp);
+	}
+
+	/* Return to original core */
+	ai_restore_core(sih, origidx, intr_val);
+}
+
+/* initialize PMU */
+void si_pmu_init(si_t *sih)
+{
+	chipcregs_t *cc;
+	uint origidx;
+
+	/* Remember original core before switch to chipc */
+	origidx = ai_coreidx(sih);
+	cc = ai_setcoreidx(sih, SI_CC_IDX);
+
+	if (sih->pmurev == 1)
+		AND_REG(&cc->pmucontrol, ~PCTL_NOILP_ON_WAIT);
+	else if (sih->pmurev >= 2)
+		OR_REG(&cc->pmucontrol, PCTL_NOILP_ON_WAIT);
+
+	if ((sih->chip == BCM4329_CHIP_ID) && (sih->chiprev == 2)) {
+		/* Fix for 4329b0 bad LPOM state. */
+		W_REG(&cc->regcontrol_addr, 2);
+		OR_REG(&cc->regcontrol_data, 0x100);
+
+		W_REG(&cc->regcontrol_addr, 3);
+		OR_REG(&cc->regcontrol_data, 0x4);
+	}
+
+	/* Return to original core */
+	ai_setcoreidx(sih, origidx);
+}
+
+/* initialize PMU chip controls and other chip level stuff */
+void si_pmu_chip_init(si_t *sih)
+{
+	uint origidx;
+
+	/* Gate off SPROM clock and chip select signals */
+	si_pmu_sprom_enable(sih, false);
+
+	/* Remember original core */
+	origidx = ai_coreidx(sih);
+
+	/* Return to original core */
+	ai_setcoreidx(sih, origidx);
+}
+
+/* initialize PMU switch/regulators */
+void si_pmu_swreg_init(si_t *sih)
+{
+	switch (sih->chip) {
+	case BCM4336_CHIP_ID:
+		/* Reduce CLDO PWM output voltage to 1.2V */
+		si_pmu_set_ldo_voltage(sih, SET_LDO_VOLTAGE_CLDO_PWM, 0xe);
+		/* Reduce CLDO BURST output voltage to 1.2V */
+		si_pmu_set_ldo_voltage(sih, SET_LDO_VOLTAGE_CLDO_BURST,
+				       0xe);
+		/* Reduce LNLDO1 output voltage to 1.2V */
+		si_pmu_set_ldo_voltage(sih, SET_LDO_VOLTAGE_LNLDO1, 0xe);
+		if (sih->chiprev == 0)
+			si_pmu_regcontrol(sih, 2, 0x400000, 0x400000);
+		break;
+
+	case BCM4330_CHIP_ID:
+		/* CBUCK Voltage is 1.8 by default and set that to 1.5 */
+		si_pmu_set_ldo_voltage(sih, SET_LDO_VOLTAGE_CBUCK_PWM, 0);
+		break;
+	default:
+		break;
+	}
+}
+
+/* initialize PLL */
+void si_pmu_pll_init(si_t *sih, uint xtalfreq)
+{
+	chipcregs_t *cc;
+	uint origidx;
+
+	/* Remember original core before switch to chipc */
+	origidx = ai_coreidx(sih);
+	cc = ai_setcoreidx(sih, SI_CC_IDX);
+
+	switch (sih->chip) {
+	case BCM4329_CHIP_ID:
+		if (xtalfreq == 0)
+			xtalfreq = 38400;
+		si_pmu1_pllinit0(sih, cc, xtalfreq);
+		break;
+	case BCM4313_CHIP_ID:
+	case BCM43224_CHIP_ID:
+	case BCM43225_CHIP_ID:
+	case BCM43421_CHIP_ID:
+	case BCM43235_CHIP_ID:
+	case BCM43236_CHIP_ID:
+	case BCM43238_CHIP_ID:
+	case BCM4331_CHIP_ID:
+	case BCM6362_CHIP_ID:
+		/* ??? */
+		break;
+	case BCM4319_CHIP_ID:
+	case BCM4336_CHIP_ID:
+	case BCM4330_CHIP_ID:
+		si_pmu1_pllinit0(sih, cc, xtalfreq);
+		break;
+	default:
+		break;
+	}
+
+	/* Return to original core */
+	ai_setcoreidx(sih, origidx);
+}
+
+/* initialize PMU resources */
+void si_pmu_res_init(si_t *sih)
+{
+	chipcregs_t *cc;
+	uint origidx;
+	const pmu_res_updown_t *pmu_res_updown_table = NULL;
+	uint pmu_res_updown_table_sz = 0;
+	const pmu_res_depend_t *pmu_res_depend_table = NULL;
+	uint pmu_res_depend_table_sz = 0;
+	u32 min_mask = 0, max_mask = 0;
+	char name[8], *val;
+	uint i, rsrcs;
+
+	/* Remember original core before switch to chipc */
+	origidx = ai_coreidx(sih);
+	cc = ai_setcoreidx(sih, SI_CC_IDX);
+
+	switch (sih->chip) {
+	case BCM4329_CHIP_ID:
+		/* Optimize resources up/down timers */
+		if (ISSIM_ENAB(sih)) {
+			pmu_res_updown_table = NULL;
+			pmu_res_updown_table_sz = 0;
+		} else {
+			pmu_res_updown_table = bcm4329_res_updown;
+			pmu_res_updown_table_sz =
+				ARRAY_SIZE(bcm4329_res_updown);
+		}
+		/* Optimize resources dependencies */
+		pmu_res_depend_table = bcm4329_res_depend;
+		pmu_res_depend_table_sz = ARRAY_SIZE(bcm4329_res_depend);
+		break;
+
+	case BCM4319_CHIP_ID:
+		/* Optimize resources up/down timers */
+		if (ISSIM_ENAB(sih)) {
+			pmu_res_updown_table = bcm4319a0_res_updown_qt;
+			pmu_res_updown_table_sz =
+			    ARRAY_SIZE(bcm4319a0_res_updown_qt);
+		} else {
+			pmu_res_updown_table = bcm4319a0_res_updown;
+			pmu_res_updown_table_sz =
+			    ARRAY_SIZE(bcm4319a0_res_updown);
+		}
+		/* Optimize resources dependancies masks */
+		pmu_res_depend_table = bcm4319a0_res_depend;
+		pmu_res_depend_table_sz = ARRAY_SIZE(bcm4319a0_res_depend);
+		break;
+
+	case BCM4336_CHIP_ID:
+		/* Optimize resources up/down timers */
+		if (ISSIM_ENAB(sih)) {
+			pmu_res_updown_table = bcm4336a0_res_updown_qt;
+			pmu_res_updown_table_sz =
+			    ARRAY_SIZE(bcm4336a0_res_updown_qt);
+		} else {
+			pmu_res_updown_table = bcm4336a0_res_updown;
+			pmu_res_updown_table_sz =
+			    ARRAY_SIZE(bcm4336a0_res_updown);
+		}
+		/* Optimize resources dependancies masks */
+		pmu_res_depend_table = bcm4336a0_res_depend;
+		pmu_res_depend_table_sz = ARRAY_SIZE(bcm4336a0_res_depend);
+		break;
+
+	case BCM4330_CHIP_ID:
+		/* Optimize resources up/down timers */
+		if (ISSIM_ENAB(sih)) {
+			pmu_res_updown_table = bcm4330a0_res_updown_qt;
+			pmu_res_updown_table_sz =
+			    ARRAY_SIZE(bcm4330a0_res_updown_qt);
+		} else {
+			pmu_res_updown_table = bcm4330a0_res_updown;
+			pmu_res_updown_table_sz =
+			    ARRAY_SIZE(bcm4330a0_res_updown);
+		}
+		/* Optimize resources dependancies masks */
+		pmu_res_depend_table = bcm4330a0_res_depend;
+		pmu_res_depend_table_sz = ARRAY_SIZE(bcm4330a0_res_depend);
+		break;
+
+	default:
+		break;
+	}
+
+	/* # resources */
+	rsrcs = (sih->pmucaps & PCAP_RC_MASK) >> PCAP_RC_SHIFT;
+
+	/* Program up/down timers */
+	while (pmu_res_updown_table_sz--) {
+		W_REG(&cc->res_table_sel,
+		      pmu_res_updown_table[pmu_res_updown_table_sz].resnum);
+		W_REG(&cc->res_updn_timer,
+		      pmu_res_updown_table[pmu_res_updown_table_sz].updown);
+	}
+	/* Apply nvram overrides to up/down timers */
+	for (i = 0; i < rsrcs; i++) {
+		snprintf(name, sizeof(name), "r%dt", i);
+		val = getvar(NULL, name);
+		if (val == NULL)
+			continue;
+		W_REG(&cc->res_table_sel, (u32) i);
+		W_REG(&cc->res_updn_timer,
+		      (u32) simple_strtoul(val, NULL, 0));
+	}
+
+	/* Program resource dependencies table */
+	while (pmu_res_depend_table_sz--) {
+		if (pmu_res_depend_table[pmu_res_depend_table_sz].filter != NULL
+		    && !(pmu_res_depend_table[pmu_res_depend_table_sz].
+			 filter) (sih))
+			continue;
+		for (i = 0; i < rsrcs; i++) {
+			if ((pmu_res_depend_table[pmu_res_depend_table_sz].
+			     res_mask & PMURES_BIT(i)) == 0)
+				continue;
+			W_REG(&cc->res_table_sel, i);
+			switch (pmu_res_depend_table[pmu_res_depend_table_sz].
+				action) {
+			case RES_DEPEND_SET:
+				W_REG(&cc->res_dep_mask,
+				      pmu_res_depend_table
+				      [pmu_res_depend_table_sz].depend_mask);
+				break;
+			case RES_DEPEND_ADD:
+				OR_REG(&cc->res_dep_mask,
+				       pmu_res_depend_table
+				       [pmu_res_depend_table_sz].depend_mask);
+				break;
+			case RES_DEPEND_REMOVE:
+				AND_REG(&cc->res_dep_mask,
+					~pmu_res_depend_table
+					[pmu_res_depend_table_sz].depend_mask);
+				break;
+			default:
+				break;
+			}
+		}
+	}
+	/* Apply nvram overrides to dependancies masks */
+	for (i = 0; i < rsrcs; i++) {
+		snprintf(name, sizeof(name), "r%dd", i);
+		val = getvar(NULL, name);
+		if (val == NULL)
+			continue;
+		W_REG(&cc->res_table_sel, (u32) i);
+		W_REG(&cc->res_dep_mask,
+		      (u32) simple_strtoul(val, NULL, 0));
+	}
+
+	/* Determine min/max rsrc masks */
+	si_pmu_res_masks(sih, &min_mask, &max_mask);
+
+	/* It is required to program max_mask first and then min_mask */
+
+	/* Program max resource mask */
+
+	if (max_mask)
+		W_REG(&cc->max_res_mask, max_mask);
+
+	/* Program min resource mask */
+
+	if (min_mask)
+		W_REG(&cc->min_res_mask, min_mask);
+
+	/* Add some delay; allow resources to come up and settle. */
+	mdelay(2);
+
+	/* Return to original core */
+	ai_setcoreidx(sih, origidx);
+}
+
+u32 si_pmu_measure_alpclk(si_t *sih)
+{
+	chipcregs_t *cc;
+	uint origidx;
+	u32 alp_khz;
+
+	if (sih->pmurev < 10)
+		return 0;
+
+	/* Remember original core before switch to chipc */
+	origidx = ai_coreidx(sih);
+	cc = ai_setcoreidx(sih, SI_CC_IDX);
+
+	if (R_REG(&cc->pmustatus) & PST_EXTLPOAVAIL) {
+		u32 ilp_ctr, alp_hz;
+
+		/*
+		 * Enable the reg to measure the freq,
+		 * in case it was disabled before
+		 */
+		W_REG(&cc->pmu_xtalfreq,
+		      1U << PMU_XTALFREQ_REG_MEASURE_SHIFT);
+
+		/* Delay for well over 4 ILP clocks */
+		udelay(1000);
+
+		/* Read the latched number of ALP ticks per 4 ILP ticks */
+		ilp_ctr =
+		    R_REG(&cc->pmu_xtalfreq) & PMU_XTALFREQ_REG_ILPCTR_MASK;
+
+		/*
+		 * Turn off the PMU_XTALFREQ_REG_MEASURE_SHIFT
+		 * bit to save power
+		 */
+		W_REG(&cc->pmu_xtalfreq, 0);
+
+		/* Calculate ALP frequency */
+		alp_hz = (ilp_ctr * EXT_ILP_HZ) / 4;
+
+		/*
+		 * Round to nearest 100KHz, and at
+		 * the same time convert to KHz
+		 */
+		alp_khz = (alp_hz + 50000) / 100000 * 100;
+	} else
+		alp_khz = 0;
+
+	/* Return to original core */
+	ai_setcoreidx(sih, origidx);
+
+	return alp_khz;
+}
+
+bool si_pmu_is_otp_powered(si_t *sih)
+{
+	uint idx;
+	chipcregs_t *cc;
+	bool st;
+
+	/* Remember original core before switch to chipc */
+	idx = ai_coreidx(sih);
+	cc = ai_setcoreidx(sih, SI_CC_IDX);
+
+	switch (sih->chip) {
+	case BCM4329_CHIP_ID:
+		st = (R_REG(&cc->res_state) & PMURES_BIT(RES4329_OTP_PU))
+		    != 0;
+		break;
+	case BCM4319_CHIP_ID:
+		st = (R_REG(&cc->res_state) & PMURES_BIT(RES4319_OTP_PU))
+		    != 0;
+		break;
+	case BCM4336_CHIP_ID:
+		st = (R_REG(&cc->res_state) & PMURES_BIT(RES4336_OTP_PU))
+		    != 0;
+		break;
+	case BCM4330_CHIP_ID:
+		st = (R_REG(&cc->res_state) & PMURES_BIT(RES4330_OTP_PU))
+		    != 0;
+		break;
+
+		/* These chip doesn't use PMU bit to power up/down OTP. OTP always on.
+		 * Use OTP_INIT command to reset/refresh state.
+		 */
+	case BCM43224_CHIP_ID:
+	case BCM43225_CHIP_ID:
+	case BCM43421_CHIP_ID:
+	case BCM43236_CHIP_ID:
+	case BCM43235_CHIP_ID:
+	case BCM43238_CHIP_ID:
+		st = true;
+		break;
+	default:
+		st = true;
+		break;
+	}
+
+	/* Return to original core */
+	ai_setcoreidx(sih, idx);
+	return st;
+}
+
+/* power up/down OTP through PMU resources */
+void si_pmu_otp_power(si_t *sih, bool on)
+{
+	chipcregs_t *cc;
+	uint origidx;
+	u32 rsrcs = 0;	/* rsrcs to turn on/off OTP power */
+
+	/* Don't do anything if OTP is disabled */
+	if (ai_is_otp_disabled(sih))
+		return;
+
+	/* Remember original core before switch to chipc */
+	origidx = ai_coreidx(sih);
+	cc = ai_setcoreidx(sih, SI_CC_IDX);
+
+	switch (sih->chip) {
+	case BCM4329_CHIP_ID:
+		rsrcs = PMURES_BIT(RES4329_OTP_PU);
+		break;
+	case BCM4319_CHIP_ID:
+		rsrcs = PMURES_BIT(RES4319_OTP_PU);
+		break;
+	case BCM4336_CHIP_ID:
+		rsrcs = PMURES_BIT(RES4336_OTP_PU);
+		break;
+	case BCM4330_CHIP_ID:
+		rsrcs = PMURES_BIT(RES4330_OTP_PU);
+		break;
+	default:
+		break;
+	}
+
+	if (rsrcs != 0) {
+		u32 otps;
+
+		/* Figure out the dependancies (exclude min_res_mask) */
+		u32 deps = si_pmu_res_deps(sih, cc, rsrcs, true);
+		u32 min_mask = 0, max_mask = 0;
+		si_pmu_res_masks(sih, &min_mask, &max_mask);
+		deps &= ~min_mask;
+		/* Turn on/off the power */
+		if (on) {
+			OR_REG(&cc->min_res_mask, (rsrcs | deps));
+			SPINWAIT(!(R_REG(&cc->res_state) & rsrcs),
+				 PMU_MAX_TRANSITION_DLY);
+		} else {
+			AND_REG(&cc->min_res_mask, ~(rsrcs | deps));
+		}
+
+		SPINWAIT((((otps = R_REG(&cc->otpstatus)) & OTPS_READY) !=
+			  (on ? OTPS_READY : 0)), 100);
+	}
+
+	/* Return to original core */
+	ai_setcoreidx(sih, origidx);
+}
diff -druN linux-2.6.39-libre/drivers/staging/brcm80211/brcmsmac/wlc_pmu.h linux-3.0-rc7-libre/drivers/staging/brcm80211/brcmsmac/wlc_pmu.h
--- linux-2.6.39-libre/drivers/staging/brcm80211/brcmsmac/wlc_pmu.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/staging/brcm80211/brcmsmac/wlc_pmu.h	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2010 Broadcom Corporation
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+
+#ifndef WLC_PMU_H_
+#define WLC_PMU_H_
+
+#include <linux/types.h>
+
+#include <aiutils.h>
+
+/*
+ * LDO selections used in si_pmu_set_ldo_voltage
+ */
+#define SET_LDO_VOLTAGE_LDO1	1
+#define SET_LDO_VOLTAGE_LDO2	2
+#define SET_LDO_VOLTAGE_LDO3	3
+#define SET_LDO_VOLTAGE_PAREF	4
+#define SET_LDO_VOLTAGE_CLDO_PWM	5
+#define SET_LDO_VOLTAGE_CLDO_BURST	6
+#define SET_LDO_VOLTAGE_CBUCK_PWM	7
+#define SET_LDO_VOLTAGE_CBUCK_BURST	8
+#define SET_LDO_VOLTAGE_LNLDO1	9
+#define SET_LDO_VOLTAGE_LNLDO2_SEL	10
+
+extern void si_pmu_set_ldo_voltage(si_t *sih, u8 ldo, u8 voltage);
+extern u16 si_pmu_fast_pwrup_delay(si_t *sih);
+extern void si_pmu_sprom_enable(si_t *sih, bool enable);
+extern u32 si_pmu_chipcontrol(si_t *sih, uint reg, u32 mask, u32 val);
+extern u32 si_pmu_regcontrol(si_t *sih, uint reg, u32 mask, u32 val);
+extern u32 si_pmu_ilp_clock(si_t *sih);
+extern u32 si_pmu_alp_clock(si_t *sih);
+extern void si_pmu_pllupd(si_t *sih);
+extern void si_pmu_spuravoid(si_t *sih, u8 spuravoid);
+extern u32 si_pmu_pllcontrol(si_t *sih, uint reg, u32 mask, u32 val);
+extern void si_pmu_init(si_t *sih);
+extern void si_pmu_chip_init(si_t *sih);
+extern void si_pmu_pll_init(si_t *sih, u32 xtalfreq);
+extern void si_pmu_res_init(si_t *sih);
+extern void si_pmu_swreg_init(si_t *sih);
+extern u32 si_pmu_measure_alpclk(si_t *sih);
+extern bool si_pmu_is_otp_powered(si_t *sih);
+extern void si_pmu_otp_power(si_t *sih, bool on);
+
+#endif /* WLC_PMU_H_ */
diff -druN linux-2.6.39-libre/drivers/staging/brcm80211/brcmsmac/wlc_pub.h linux-3.0-rc7-libre/drivers/staging/brcm80211/brcmsmac/wlc_pub.h
--- linux-2.6.39-libre/drivers/staging/brcm80211/brcmsmac/wlc_pub.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/brcm80211/brcmsmac/wlc_pub.h	2011-07-11 19:51:52.000000000 -0400
@@ -59,6 +59,10 @@
  */
 #define WLC_TXPWR_MAX		(127)	/* ~32 dBm = 1,500 mW */
 
+/* rate related definitions */
+#define	WLC_RATE_FLAG	0x80	/* Flag to indicate it is a basic rate */
+#define	WLC_RATE_MASK	0x7f	/* Rate value mask w/o basic rate flag */
+
 /* legacy rx Antenna diversity for SISO rates */
 #define	ANT_RX_DIV_FORCE_0		0	/* Use antenna 0 */
 #define	ANT_RX_DIV_FORCE_1		1	/* Use antenna 1 */
@@ -92,6 +96,8 @@
 #define AIDMAPSZ	(roundup(MAXSCB, NBBY)/NBBY)	/* aid bitmap size in bytes */
 #endif				/* AIDMAPSZ */
 
+struct ieee80211_tx_queue_params;
+
 typedef struct wlc_tunables {
 	int ntxd;		/* size of tx descriptor table */
 	int nrxd;		/* size of rx descriptor table */
@@ -478,7 +484,7 @@
 #define	WLC_PROT_N_OBSS		16	/* non-HT OBSS present */
 
 /* common functions for every port */
-extern void *wlc_attach(void *wl, u16 vendor, u16 device, uint unit,
+extern void *wlc_attach(struct wl_info *wl, u16 vendor, u16 device, uint unit,
 			bool piomode, void *regsva, uint bustype, void *btparam,
 			uint *perr);
 extern uint wlc_detach(struct wlc_info *wlc);
@@ -499,8 +505,6 @@
 extern bool wlc_intrsupd(struct wlc_info *wlc);
 extern bool wlc_isr(struct wlc_info *wlc, bool *wantdpc);
 extern bool wlc_dpc(struct wlc_info *wlc, bool bounded);
-extern bool wlc_send80211_raw(struct wlc_info *wlc, struct wlc_if *wlcif,
-			      void *p, uint ac);
 extern bool wlc_sendpkt_mac80211(struct wlc_info *wlc, struct sk_buff *sdu,
 				 struct ieee80211_hw *hw);
 extern int wlc_iovar_op(struct wlc_info *wlc, const char *name, void *params,
@@ -508,6 +512,8 @@
 			struct wlc_if *wlcif);
 extern int wlc_ioctl(struct wlc_info *wlc, int cmd, void *arg, int len,
 		     struct wlc_if *wlcif);
+extern bool wlc_aggregatable(struct wlc_info *wlc, u8 tid);
+
 /* helper functions */
 extern void wlc_statsupd(struct wlc_info *wlc);
 extern void wlc_protection_upd(struct wlc_info *wlc, uint idx, int val);
@@ -515,24 +521,14 @@
 extern void wlc_mac_bcn_promisc_change(struct wlc_info *wlc, bool promisc);
 extern void wlc_set_addrmatch(struct wlc_info *wlc, int match_reg_offset,
 			      const u8 *addr);
-extern void wlc_wme_setparams(struct wlc_info *wlc, u16 aci, void *arg,
+extern void wlc_wme_setparams(struct wlc_info *wlc, u16 aci,
+			      const struct ieee80211_tx_queue_params *arg,
 			      bool suspend);
-
 extern struct wlc_pub *wlc_pub(void *wlc);
 
 /* common functions for every port */
-extern int wlc_bmac_up_prep(struct wlc_hw_info *wlc_hw);
-extern int wlc_bmac_up_finish(struct wlc_hw_info *wlc_hw);
-extern int wlc_bmac_down_prep(struct wlc_hw_info *wlc_hw);
-extern int wlc_bmac_down_finish(struct wlc_hw_info *wlc_hw);
-
-extern u32 wlc_reg_read(struct wlc_info *wlc, void *r, uint size);
-extern void wlc_reg_write(struct wlc_info *wlc, void *r, u32 v, uint size);
-extern void wlc_corereset(struct wlc_info *wlc, u32 flags);
 extern void wlc_mhf(struct wlc_info *wlc, u8 idx, u16 mask, u16 val,
 		    int bands);
-extern u16 wlc_mhf_get(struct wlc_info *wlc, u8 idx, int bands);
-extern u32 wlc_delta_txfunfl(struct wlc_info *wlc, int fifo);
 extern void wlc_rate_lookup_init(struct wlc_info *wlc, wlc_rateset_t *rateset);
 extern void wlc_default_rateset(struct wlc_info *wlc, wlc_rateset_t *rs);
 
@@ -543,11 +539,8 @@
 /* wlc_phy.c helper functions */
 extern void wlc_set_ps_ctrl(struct wlc_info *wlc);
 extern void wlc_mctrl(struct wlc_info *wlc, u32 mask, u32 val);
-extern void wlc_scb_ratesel_init_all(struct wlc_info *wlc);
 
 /* ioctl */
-extern int wlc_iovar_gets8(struct wlc_info *wlc, const char *name,
-			     s8 *arg);
 extern int wlc_iovar_check(struct wlc_pub *pub, const bcm_iovar_t *vi,
 			   void *arg,
 			   int len, bool set);
@@ -562,31 +555,12 @@
 extern void wlc_associate_upd(struct wlc_info *wlc, bool state);
 extern void wlc_scan_start(struct wlc_info *wlc);
 extern void wlc_scan_stop(struct wlc_info *wlc);
-
-static inline int wlc_iovar_getuint(struct wlc_info *wlc, const char *name,
-				    uint *arg)
-{
-	return wlc_iovar_getint(wlc, name, (int *)arg);
-}
-
-static inline int wlc_iovar_getu8(struct wlc_info *wlc, const char *name,
-				     u8 *arg)
-{
-	return wlc_iovar_gets8(wlc, name, (s8 *) arg);
-}
-
-static inline int wlc_iovar_setuint(struct wlc_info *wlc, const char *name,
-				    uint arg)
-{
-	return wlc_iovar_setint(wlc, name, (int)arg);
-}
+extern int wlc_get_curband(struct wlc_info *wlc);
+extern void wlc_wait_for_tx_completion(struct wlc_info *wlc, bool drop);
 
 #if defined(BCMDBG)
 extern int wlc_iocregchk(struct wlc_info *wlc, uint band);
 #endif
-#if defined(BCMDBG)
-extern int wlc_iocpichk(struct wlc_info *wlc, uint phytype);
-#endif
 
 /* helper functions */
 extern bool wlc_check_radio_disabled(struct wlc_info *wlc);
diff -druN linux-2.6.39-libre/drivers/staging/brcm80211/brcmsmac/wlc_rate.c linux-3.0-rc7-libre/drivers/staging/brcm80211/brcmsmac/wlc_rate.c
--- linux-2.6.39-libre/drivers/staging/brcm80211/brcmsmac/wlc_rate.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/brcm80211/brcmsmac/wlc_rate.c	2011-07-11 19:51:52.000000000 -0400
@@ -19,7 +19,7 @@
 #include <proto/802.11.h>
 #include <bcmdefs.h>
 #include <bcmutils.h>
-#include <siutils.h>
+#include <aiutils.h>
 #include <wlioctl.h>
 #include <sbhnddma.h>
 
@@ -304,7 +304,7 @@
 
 	for (i = 0; i < count; i++) {
 		/* mask off "basic rate" bit, WLC_RATE_FLAG */
-		r = (int)rs->rates[i] & RATE_MASK;
+		r = (int)rs->rates[i] & WLC_RATE_MASK;
 		if ((r > WLC_MAXRATE) || (rate_info[r] == 0)) {
 			continue;
 		}
@@ -314,8 +314,7 @@
 	/* fill out the rates in order, looking at only supported rates */
 	count = 0;
 	for (i = 0; i < hw_rs->count; i++) {
-		r = hw_rs->rates[i] & RATE_MASK;
-		ASSERT(r <= WLC_MAXRATE);
+		r = hw_rs->rates[i] & WLC_RATE_MASK;
 		if (rateset[r])
 			rs->rates[count++] = rateset[r];
 	}
@@ -333,7 +332,7 @@
 }
 
 /* calculate the rate of a rx'd frame and return it as a ratespec */
-ratespec_t BCMFASTPATH wlc_compute_rspec(d11rxhdr_t *rxh, u8 *plcp)
+ratespec_t wlc_compute_rspec(d11rxhdr_t *rxh, u8 *plcp)
 {
 	int phy_type;
 	ratespec_t rspec = PHY_TXC1_BW_20MHZ << RSPEC_BW_SHIFT;
@@ -364,8 +363,7 @@
 		case PRXS0_STDN:
 			/* fallthru */
 		default:
-			/* not supported */
-			ASSERT(0);
+			/* not supported, error condition */
 			break;
 		}
 		if (PLCP3_ISSGI(plcp[3]))
@@ -407,9 +405,9 @@
 		r = src->rates[i];
 		if (basic_only && !(r & WLC_RATE_FLAG))
 			continue;
-		if ((rates == WLC_RATES_CCK) && IS_OFDM((r & RATE_MASK)))
+		if ((rates == WLC_RATES_CCK) && IS_OFDM((r & WLC_RATE_MASK)))
 			continue;
-		if ((rates == WLC_RATES_OFDM) && IS_CCK((r & RATE_MASK)))
+		if ((rates == WLC_RATES_OFDM) && IS_CCK((r & WLC_RATE_MASK)))
 			continue;
 		dst->rates[count++] = r & xmask;
 	}
@@ -451,7 +449,7 @@
 	} else if (PHYTYPE_IS(phy_type, PHY_TYPE_G)) {
 		rs_dflt = &cck_ofdm_rates;
 	} else {
-		ASSERT(0);	/* should not happen */
+		/* should not happen, error condition */
 		rs_dflt = &cck_rates;	/* force cck */
 	}
 
@@ -468,7 +466,7 @@
 					   mcsallow ? txstreams : 1);
 }
 
-s16 BCMFASTPATH wlc_rate_legacy_phyctl(uint rate)
+s16 wlc_rate_legacy_phyctl(uint rate)
 {
 	uint i;
 	for (i = 0; i < LEGACY_PHYCFG_TABLE_SIZE; i++)
diff -druN linux-2.6.39-libre/drivers/staging/brcm80211/brcmsmac/wlc_rate.h linux-3.0-rc7-libre/drivers/staging/brcm80211/brcmsmac/wlc_rate.h
--- linux-2.6.39-libre/drivers/staging/brcm80211/brcmsmac/wlc_rate.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/brcm80211/brcmsmac/wlc_rate.h	2011-07-11 19:51:52.000000000 -0400
@@ -54,11 +54,8 @@
 	(_is40 ? mcs_table[_mcs].phy_rate_40 : mcs_table[_mcs].phy_rate_20))
 #define VALID_MCS(_mcs)	((_mcs < MCS_TABLE_SIZE))
 
-#define	WLC_RATE_FLAG	0x80	/* Rate flag: basic or ofdm */
-
-/* Macros to use the rate_info table */
-#define	RATE_MASK	0x7f	/* Rate value mask w/o basic rate flag */
-#define	RATE_MASK_FULL	0xff	/* Rate value mask with basic rate flag */
+/* Macro to use the rate_info table */
+#define	WLC_RATE_MASK_FULL 0xff	/* Rate value mask with basic rate flag */
 
 #define WLC_RATE_500K_TO_BPS(rate)	((rate) * 500000)	/* convert 500kbps to bps */
 
@@ -115,9 +112,11 @@
 /* Rate info table; takes a legacy rate or ratespec_t */
 #define	IS_MCS(r)     	(r & RSPEC_MIMORATE)
 #define	IS_OFDM(r)     	(!IS_MCS(r) && (rate_info[(r) & RSPEC_RATE_MASK] & WLC_RATE_FLAG))
-#define	IS_CCK(r)	(!IS_MCS(r) && (((r) & RATE_MASK) == WLC_RATE_1M || \
-			 ((r) & RATE_MASK) == WLC_RATE_2M || \
-			 ((r) & RATE_MASK) == WLC_RATE_5M5 || ((r) & RATE_MASK) == WLC_RATE_11M))
+#define	IS_CCK(r)	(!IS_MCS(r) && ( \
+			 ((r) & WLC_RATE_MASK) == WLC_RATE_1M || \
+			 ((r) & WLC_RATE_MASK) == WLC_RATE_2M || \
+			 ((r) & WLC_RATE_MASK) == WLC_RATE_5M5 || \
+			 ((r) & WLC_RATE_MASK) == WLC_RATE_11M))
 #define IS_SINGLE_STREAM(mcs)	(((mcs) <= HIGHEST_SINGLE_STREAM_MCS) || ((mcs) == 32))
 #define CCK_RSPEC(cck)		((cck) & RSPEC_RATE_MASK)
 #define OFDM_RSPEC(ofdm)	(((ofdm) & RSPEC_RATE_MASK) |\
diff -druN linux-2.6.39-libre/drivers/staging/brcm80211/brcmsmac/wlc_scb.h linux-3.0-rc7-libre/drivers/staging/brcm80211/brcmsmac/wlc_scb.h
--- linux-2.6.39-libre/drivers/staging/brcm80211/brcmsmac/wlc_scb.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/brcm80211/brcmsmac/wlc_scb.h	2011-07-11 19:51:52.000000000 -0400
@@ -17,8 +17,6 @@
 #ifndef _wlc_scb_h_
 #define _wlc_scb_h_
 
-extern bool wlc_aggregatable(struct wlc_info *wlc, u8 tid);
-
 #define AMPDU_TX_BA_MAX_WSIZE	64	/* max Tx ba window size (in pdu) */
 /* structure to store per-tid state for the ampdu initiator */
 typedef struct scb_ampdu_tid_ini {
diff -druN linux-2.6.39-libre/drivers/staging/brcm80211/brcmsmac/wlc_stf.c linux-3.0-rc7-libre/drivers/staging/brcm80211/brcmsmac/wlc_stf.c
--- linux-2.6.39-libre/drivers/staging/brcm80211/brcmsmac/wlc_stf.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/brcm80211/brcmsmac/wlc_stf.c	2011-07-11 19:51:52.000000000 -0400
@@ -21,9 +21,10 @@
 
 #include <bcmdefs.h>
 #include <bcmutils.h>
-#include <siutils.h>
+#include <aiutils.h>
 #include <wlioctl.h>
 #include <bcmwifi.h>
+#include <bcmnvram.h>
 #include <sbhnddma.h>
 
 #include "wlc_types.h"
@@ -69,9 +70,6 @@
 
 static void wlc_stf_stbc_rx_ht_update(struct wlc_info *wlc, int val)
 {
-	ASSERT((val == HT_CAP_RX_STBC_NO)
-	       || (val == HT_CAP_RX_STBC_ONE_STREAM));
-
 	/* MIMOPHYs rev3-6 cannot receive STBC with only one rx core active */
 	if (WLC_STF_SS_STBC_RX(wlc)) {
 		if ((wlc->stf->rxstreams == 1) && (val != HT_CAP_RX_STBC_NO))
@@ -193,10 +191,8 @@
 
 static int wlc_stf_txcore_set(struct wlc_info *wlc, u8 Nsts, u8 core_mask)
 {
-	WL_TRACE("wl%d: %s: Nsts %d core_mask %x\n",
-		 wlc->pub->unit, __func__, Nsts, core_mask);
-
-	ASSERT((Nsts > 0) && (Nsts <= MAX_STREAMS_SUPPORTED));
+	BCMMSG(wlc->wiphy, "wl%d: Nsts %d core_mask %x\n",
+		 wlc->pub->unit, Nsts, core_mask);
 
 	if (WLC_BITSCNT(core_mask) > wlc->stf->txstreams) {
 		core_mask = 0;
@@ -208,8 +204,6 @@
 		core_mask = wlc->stf->txchain;
 	}
 
-	ASSERT(!core_mask || Nsts <= WLC_BITSCNT(core_mask));
-
 	wlc->stf->txcore[Nsts] = core_mask;
 	/* Nsts = 1..4, txcore index = 1..4 */
 	if (Nsts == 1) {
@@ -225,7 +219,7 @@
 		}
 	}
 
-	return BCME_OK;
+	return 0;
 }
 
 static int wlc_stf_spatial_policy_set(struct wlc_info *wlc, int val)
@@ -233,7 +227,7 @@
 	int i;
 	u8 core_mask = 0;
 
-	WL_TRACE("wl%d: %s: val %x\n", wlc->pub->unit, __func__, val);
+	BCMMSG(wlc->wiphy, "wl%d: val %x\n", wlc->pub->unit, val);
 
 	wlc->stf->spatial_policy = (s8) val;
 	for (i = 1; i <= MAX_STREAMS_SUPPORTED; i++) {
@@ -241,7 +235,7 @@
 		    wlc->stf->txchain : txcore_default[i];
 		wlc_stf_txcore_set(wlc, (u8) i, core_mask);
 	}
-	return BCME_OK;
+	return 0;
 }
 
 int wlc_stf_txchain_set(struct wlc_info *wlc, s32 int_val, bool force)
@@ -251,16 +245,16 @@
 	uint i;
 
 	if (wlc->stf->txchain == txchain)
-		return BCME_OK;
+		return 0;
 
 	if ((txchain & ~wlc->stf->hw_txchain)
 	    || !(txchain & wlc->stf->hw_txchain))
-		return BCME_RANGE;
+		return -EINVAL;
 
 	/* if nrate override is configured to be non-SISO STF mode, reject reducing txchain to 1 */
 	txstreams = (u8) WLC_BITSCNT(txchain);
 	if (txstreams > MAX_STREAMS_SUPPORTED)
-		return BCME_RANGE;
+		return -EINVAL;
 
 	if (txstreams == 1) {
 		for (i = 0; i < NBANDS(wlc); i++)
@@ -269,21 +263,25 @@
 			    || (RSPEC_STF(wlc->bandstate[i]->mrspec_override) !=
 				PHY_TXC1_MODE_SISO)) {
 				if (!force)
-					return BCME_ERROR;
+					return -EBADE;
 
 				/* over-write the override rspec */
 				if (RSPEC_STF(wlc->bandstate[i]->rspec_override)
 				    != PHY_TXC1_MODE_SISO) {
 					wlc->bandstate[i]->rspec_override = 0;
-					WL_ERROR("%s(): temp sense override non-SISO rspec_override\n",
-						 __func__);
+					wiphy_err(wlc->wiphy, "%s(): temp "
+						  "sense override non-SISO "
+						  "rspec_override\n",
+						  __func__);
 				}
 				if (RSPEC_STF
 				    (wlc->bandstate[i]->mrspec_override) !=
 				    PHY_TXC1_MODE_SISO) {
 					wlc->bandstate[i]->mrspec_override = 0;
-					WL_ERROR("%s(): temp sense override non-SISO mrspec_override\n",
-						 __func__);
+					wiphy_err(wlc->wiphy, "%s(): temp "
+						  "sense override non-SISO "
+						  "mrspec_override\n",
+						  __func__);
 				}
 			}
 	}
@@ -303,7 +301,7 @@
 	for (i = 1; i <= MAX_STREAMS_SUPPORTED; i++)
 		wlc_stf_txcore_set(wlc, (u8) i, txcore_default[i]);
 
-	return BCME_OK;
+	return 0;
 }
 
 /* update wlc->stf->ss_opmode which represents the operational stf_ss mode we're using */
@@ -319,9 +317,6 @@
 	if (WLC_STBC_CAP_PHY(wlc) &&
 	    wlc->stf->ss_algosel_auto
 	    && (wlc->stf->ss_algo_channel != (u16) -1)) {
-		ASSERT(isset(&wlc->stf->ss_algo_channel, PHY_TXC1_MODE_CDD)
-		       || isset(&wlc->stf->ss_algo_channel,
-				PHY_TXC1_MODE_SISO));
 		upd_stf_ss = (wlc->stf->no_cddstbc || (wlc->stf->txstreams == 1)
 			      || isset(&wlc->stf->ss_algo_channel,
 				       PHY_TXC1_MODE_SISO)) ? PHY_TXC1_MODE_SISO
@@ -371,11 +366,11 @@
 
 int wlc_stf_ant_txant_validate(struct wlc_info *wlc, s8 val)
 {
-	int bcmerror = BCME_OK;
+	int bcmerror = 0;
 
 	/* when there is only 1 tx_streams, don't allow to change the txant */
 	if (WLCISNPHY(wlc->band) && (wlc->stf->txstreams == 1))
-		return ((val == wlc->stf->txant) ? bcmerror : BCME_RANGE);
+		return ((val == wlc->stf->txant) ? bcmerror : -EINVAL);
 
 	switch (val) {
 	case -1:
@@ -391,11 +386,11 @@
 		val = ANT_TX_LAST_RX;
 		break;
 	default:
-		bcmerror = BCME_RANGE;
+		bcmerror = -EINVAL;
 		break;
 	}
 
-	if (bcmerror == BCME_OK)
+	if (bcmerror == 0)
 		wlc->stf->txant = (s8) val;
 
 	return bcmerror;
@@ -421,9 +416,6 @@
 	s8 txant;
 
 	txant = (s8) wlc->stf->txant;
-	ASSERT(txant == ANT_TX_FORCE_0 || txant == ANT_TX_FORCE_1
-	       || txant == ANT_TX_LAST_RX);
-
 	if (WLC_PHY_11N_CAP(wlc->band)) {
 		if (txant == ANT_TX_FORCE_0) {
 			wlc->stf->phytxant = PHY_TXC_ANT_0;
@@ -439,8 +431,8 @@
 			if (WLCISLCNPHY(wlc->band) || WLCISSSLPNPHY(wlc->band))
 				wlc->stf->phytxant = PHY_TXC_LCNPHY_ANT_LAST;
 			else {
-				/* keep this assert to catch out of sync wlc->stf->txcore */
-				ASSERT(wlc->stf->txchain > 0);
+				/* catch out of sync wlc->stf->txcore */
+				WARN_ON(wlc->stf->txchain <= 0);
 				wlc->stf->phytxant =
 				    wlc->stf->txchain << PHY_TXC_ANT_SHIFT;
 			}
@@ -504,7 +496,6 @@
 	u16 phytxant = wlc->stf->phytxant;
 
 	if (RSPEC_STF(rspec) != PHY_TXC1_MODE_SISO) {
-		ASSERT(wlc->stf->txstreams > 1);
 		phytxant = wlc->stf->txchain << PHY_TXC_ANT_SHIFT;
 	} else if (wlc->stf->txant == ANT_TX_DEF)
 		phytxant = wlc->stf->txchain << PHY_TXC_ANT_SHIFT;
@@ -524,7 +515,6 @@
 
 	/* for non-siso rates or default setting, use the available chains */
 	if (WLCISNPHY(wlc->band)) {
-		ASSERT(wlc->stf->txchain != 0);
 		phytxant = _wlc_stf_phytxchain_sel(wlc, rspec);
 		mask = PHY_TXC_HTANT_MASK;
 	}
diff -druN linux-2.6.39-libre/drivers/staging/brcm80211/brcmsmac/wl_dbg.h linux-3.0-rc7-libre/drivers/staging/brcm80211/brcmsmac/wl_dbg.h
--- linux-2.6.39-libre/drivers/staging/brcm80211/brcmsmac/wl_dbg.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/brcm80211/brcmsmac/wl_dbg.h	2011-07-11 19:51:52.000000000 -0400
@@ -17,25 +17,19 @@
 #ifndef _wl_dbg_h_
 #define _wl_dbg_h_
 
+#include <linux/device.h>			/* dev_err() */
+
 /* wl_msg_level is a bit vector with defs in wlioctl.h */
 extern u32 wl_msg_level;
 
-#define WL_NONE(fmt, args...) no_printk(fmt, ##args)
-
-#define WL_PRINT(level, fmt, args...)		\
+#define BCMMSG(dev, fmt, args...)		\
 do {						\
-	if (wl_msg_level & level)		\
-		printk(fmt, ##args);		\
+	if (wl_msg_level & WL_TRACE_VAL)	\
+		wiphy_err(dev, "%s: " fmt, __func__, ##args);	\
 } while (0)
 
 #ifdef BCMDBG
 
-#define	WL_ERROR(fmt, args...)	WL_PRINT(WL_ERROR_VAL, fmt, ##args)
-#define	WL_TRACE(fmt, args...)	WL_PRINT(WL_TRACE_VAL, fmt, ##args)
-#define WL_AMPDU(fmt, args...)	WL_PRINT(WL_AMPDU_VAL, fmt, ##args)
-#define WL_FFPLD(fmt, args...)	WL_PRINT(WL_FFPLD_VAL, fmt, ##args)
-
-#define WL_ERROR_ON()		(wl_msg_level & WL_ERROR_VAL)
 
 /* Extra message control for AMPDU debugging */
 #define   WL_AMPDU_UPDN_VAL	0x00000001	/* Config up/down related  */
@@ -78,12 +72,6 @@
 
 #else				/* BCMDBG */
 
-#define	WL_ERROR(fmt, args...)		no_printk(fmt, ##args)
-#define	WL_TRACE(fmt, args...)		no_printk(fmt, ##args)
-#define WL_AMPDU(fmt, args...)		no_printk(fmt, ##args)
-#define WL_FFPLD(fmt, args...)		no_printk(fmt, ##args)
-
-#define WL_ERROR_ON()		0
 
 #define WL_AMPDU_UPDN(fmt, args...)	no_printk(fmt, ##args)
 #define WL_AMPDU_RX(fmt, args...)	no_printk(fmt, ##args)
@@ -99,4 +87,6 @@
 
 #endif				/* BCMDBG */
 
+#define WL_ERROR_ON()		(wl_msg_level & WL_ERROR_VAL)
+
 #endif				/* _wl_dbg_h_ */
diff -druN linux-2.6.39-libre/drivers/staging/brcm80211/brcmsmac/wl_export.h linux-3.0-rc7-libre/drivers/staging/brcm80211/brcmsmac/wl_export.h
--- linux-2.6.39-libre/drivers/staging/brcm80211/brcmsmac/wl_export.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/brcm80211/brcmsmac/wl_export.h	2011-07-11 19:51:52.000000000 -0400
@@ -42,5 +42,6 @@
 extern void wl_add_timer(struct wl_info *wl, struct wl_timer *timer, uint ms,
 			 int periodic);
 extern bool wl_del_timer(struct wl_info *wl, struct wl_timer *timer);
+extern void wl_msleep(struct wl_info *wl, uint ms);
 
 #endif				/* _wl_export_h_ */
diff -druN linux-2.6.39-libre/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c linux-3.0-rc7-libre/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c
--- linux-2.6.39-libre/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c	2011-05-19 02:13:39.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/brcm80211/brcmsmac/wl_mac80211.c	2011-07-21 06:56:04.000000000 -0400
@@ -30,6 +30,7 @@
 #include <bcmdefs.h>
 #include <bcmwifi.h>
 #include <bcmutils.h>
+#include <bcmnvram.h>
 #include <pcicfg.h>
 #include <wlioctl.h>
 #include <sbhnddma.h>
@@ -48,6 +49,8 @@
 #include "wl_ucode.h"
 #include "wl_mac80211.h"
 
+#define N_TX_QUEUES	4 /* #tx queues on mac80211<->driver interface */
+
 static void wl_timer(unsigned long data);
 static void _wl_timer(struct wl_timer *t);
 
@@ -81,6 +84,7 @@
 				  const struct pci_device_id *ent);
 static void wl_remove(struct pci_dev *pdev);
 static void wl_free(struct wl_info *wl);
+static void wl_set_basic_rate(struct wl_rateset *rs, u16 rate, bool is_br);
 
 MODULE_AUTHOR("Broadcom Corporation");
 MODULE_DESCRIPTION("Broadcom 802.11n wireless LAN driver.");
@@ -129,7 +133,6 @@
 static void wl_ops_set_tsf(struct ieee80211_hw *hw, u64 tsf);
 static int wl_ops_get_stats(struct ieee80211_hw *hw,
 			    struct ieee80211_low_level_stats *stats);
-static int wl_ops_set_rts_threshold(struct ieee80211_hw *hw, u32 value);
 static void wl_ops_sta_notify(struct ieee80211_hw *hw,
 			      struct ieee80211_vif *vif,
 			      enum sta_notify_cmd cmd,
@@ -147,6 +150,7 @@
 			       struct ieee80211_sta *sta, u16 tid, u16 *ssn,
 			       u8 buf_size);
 static void wl_ops_rfkill_poll(struct ieee80211_hw *hw);
+static void wl_ops_flush(struct ieee80211_hw *hw, bool drop);
 
 static void wl_ops_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
 {
@@ -154,7 +158,7 @@
 
 	WL_LOCK(wl);
 	if (!wl->pub->up) {
-		WL_ERROR("ops->tx called while down\n");
+		wiphy_err(wl->wiphy, "ops->tx called while down\n");
 		kfree_skb(skb);
 		goto done;
 	}
@@ -169,7 +173,6 @@
 	bool blocked;
 	/*
 	  struct ieee80211_channel *curchan = hw->conf.channel;
-	  WL_NONE("%s : Initial channel: %d\n", __func__, curchan->hw_value);
 	*/
 
 	ieee80211_wake_queues(hw);
@@ -184,10 +187,6 @@
 
 static void wl_ops_stop(struct ieee80211_hw *hw)
 {
-#ifdef BRCMDBG
-	struct wl_info *wl = hw->priv;
-	ASSERT(wl);
-#endif /*BRCMDBG*/
 	ieee80211_stop_queues(hw);
 }
 
@@ -203,8 +202,8 @@
 	    vif->type != NL80211_IFTYPE_STATION &&
 	    vif->type != NL80211_IFTYPE_WDS &&
 	    vif->type != NL80211_IFTYPE_ADHOC) {
-		WL_ERROR("%s: Attempt to add type %d, only STA for now\n",
-			 __func__, vif->type);
+		wiphy_err(hw->wiphy, "%s: Attempt to add type %d, only"
+			  " STA for now\n", __func__, vif->type);
 		return -EOPNOTSUPP;
 	}
 
@@ -214,7 +213,8 @@
 	WL_UNLOCK(wl);
 
 	if (err != 0) {
-		WL_ERROR("%s: wl_up() returned %d\n", __func__, err);
+		wiphy_err(hw->wiphy, "%s: wl_up() returned %d\n", __func__,
+			  err);
 	}
 	return err;
 }
@@ -249,7 +249,8 @@
 		break;
 	case NL80211_CHAN_HT40MINUS:
 	case NL80211_CHAN_HT40PLUS:
-		WL_ERROR("%s: Need to implement 40 Mhz Channels!\n", __func__);
+		wiphy_err(hw->wiphy,
+			  "%s: Need to implement 40 Mhz Channels!\n", __func__);
 		err = 1;
 		break;
 	}
@@ -265,39 +266,41 @@
 	struct wl_info *wl = HW_TO_WL(hw);
 	int err = 0;
 	int new_int;
+	struct wiphy *wiphy = hw->wiphy;
 
 	WL_LOCK(wl);
 	if (changed & IEEE80211_CONF_CHANGE_LISTEN_INTERVAL) {
 		if (wlc_iovar_setint
 		    (wl->wlc, "bcn_li_bcn", conf->listen_interval)) {
-			WL_ERROR("%s: Error setting listen_interval\n",
-				 __func__);
+			wiphy_err(wiphy, "%s: Error setting listen_interval\n",
+				  __func__);
 			err = -EIO;
 			goto config_out;
 		}
 		wlc_iovar_getint(wl->wlc, "bcn_li_bcn", &new_int);
-		ASSERT(new_int == conf->listen_interval);
 	}
 	if (changed & IEEE80211_CONF_CHANGE_MONITOR)
-		WL_ERROR("%s: change monitor mode: %s (implement)\n", __func__,
-			 conf->flags & IEEE80211_CONF_MONITOR ?
-				"true" : "false");
+		wiphy_err(wiphy, "%s: change monitor mode: %s (implement)\n",
+			  __func__, conf->flags & IEEE80211_CONF_MONITOR ?
+			  "true" : "false");
 	if (changed & IEEE80211_CONF_CHANGE_PS)
-		WL_ERROR("%s: change power-save mode: %s (implement)\n",
-			 __func__, conf->flags & IEEE80211_CONF_PS ?
-				"true" : "false");
+		wiphy_err(wiphy, "%s: change power-save mode: %s (implement)\n",
+			  __func__, conf->flags & IEEE80211_CONF_PS ?
+			  "true" : "false");
 
 	if (changed & IEEE80211_CONF_CHANGE_POWER) {
 		if (wlc_iovar_setint
 		    (wl->wlc, "qtxpower", conf->power_level * 4)) {
-			WL_ERROR("%s: Error setting power_level\n", __func__);
+			wiphy_err(wiphy, "%s: Error setting power_level\n",
+				  __func__);
 			err = -EIO;
 			goto config_out;
 		}
 		wlc_iovar_getint(wl->wlc, "qtxpower", &new_int);
 		if (new_int != (conf->power_level * 4))
-			WL_ERROR("%s: Power level req != actual, %d %d\n",
-				 __func__, conf->power_level * 4, new_int);
+			wiphy_err(wiphy, "%s: Power level req != actual, %d %d"
+				  "\n", __func__, conf->power_level * 4,
+				  new_int);
 	}
 	if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
 		err = ieee_set_channel(hw, conf->channel, conf->channel_type);
@@ -306,13 +309,13 @@
 		if (wlc_set
 		    (wl->wlc, WLC_SET_SRL,
 		     conf->short_frame_max_tx_count) < 0) {
-			WL_ERROR("%s: Error setting srl\n", __func__);
+			wiphy_err(wiphy, "%s: Error setting srl\n", __func__);
 			err = -EIO;
 			goto config_out;
 		}
 		if (wlc_set(wl->wlc, WLC_SET_LRL, conf->long_frame_max_tx_count)
 		    < 0) {
-			WL_ERROR("%s: Error setting lrl\n", __func__);
+			wiphy_err(wiphy, "%s: Error setting lrl\n", __func__);
 			err = -EIO;
 			goto config_out;
 		}
@@ -329,25 +332,18 @@
 			struct ieee80211_bss_conf *info, u32 changed)
 {
 	struct wl_info *wl = HW_TO_WL(hw);
+	struct wiphy *wiphy = hw->wiphy;
 	int val;
 
 	if (changed & BSS_CHANGED_ASSOC) {
 		/* association status changed (associated/disassociated)
 		 * also implies a change in the AID.
 		 */
-		WL_ERROR("%s: %s: %sassociated\n", KBUILD_MODNAME, __func__,
-			 info->assoc ? "" : "dis");
+		wiphy_err(wiphy, "%s: %s: %sassociated\n", KBUILD_MODNAME,
+			  __func__, info->assoc ? "" : "dis");
+		WL_LOCK(wl);
 		wlc_associate_upd(wl->wlc, info->assoc);
-	}
-	if (changed & BSS_CHANGED_ERP_CTS_PROT) {
-		/* CTS protection changed */
-		WL_ERROR("%s: use_cts_prot: %s (implement)\n", __func__,
-			info->use_cts_prot ? "true" : "false");
-	}
-	if (changed & BSS_CHANGED_ERP_PREAMBLE) {
-		/* preamble changed */
-		WL_ERROR("%s: short preamble: %s (implement)\n", __func__,
-			info->use_short_preamble ? "true" : "false");
+		WL_UNLOCK(wl);
 	}
 	if (changed & BSS_CHANGED_ERP_SLOT) {
 		/* slot timing changed */
@@ -363,29 +359,57 @@
 	if (changed & BSS_CHANGED_HT) {
 		/* 802.11n parameters changed */
 		u16 mode = info->ht_operation_mode;
-		WL_NONE("%s: HT mode: 0x%04X\n", __func__, mode);
+
+		WL_LOCK(wl);
 		wlc_protection_upd(wl->wlc, WLC_PROT_N_CFG,
 			mode & IEEE80211_HT_OP_MODE_PROTECTION);
 		wlc_protection_upd(wl->wlc, WLC_PROT_N_NONGF,
 			mode & IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT);
 		wlc_protection_upd(wl->wlc, WLC_PROT_N_OBSS,
 			mode & IEEE80211_HT_OP_MODE_NON_HT_STA_PRSNT);
+		WL_UNLOCK(wl);
 	}
 	if (changed & BSS_CHANGED_BASIC_RATES) {
-		/* Basic rateset changed */
-		WL_ERROR("%s: Need to change Basic Rates: 0x%x (implement)\n",
-			 __func__, (u32) info->basic_rates);
+		struct ieee80211_supported_band *bi;
+		u32 br_mask, i;
+		u16 rate;
+		struct wl_rateset rs;
+		int error;
+
+		/* retrieve the current rates */
+		WL_LOCK(wl);
+		error = wlc_ioctl(wl->wlc, WLC_GET_CURR_RATESET,
+				  &rs, sizeof(rs), NULL);
+		WL_UNLOCK(wl);
+		if (error) {
+			wiphy_err(wiphy, "%s: retrieve rateset failed: %d\n",
+				  __func__, error);
+			return;
+		}
+		br_mask = info->basic_rates;
+		bi = hw->wiphy->bands[wlc_get_curband(wl->wlc)];
+		for (i = 0; i < bi->n_bitrates; i++) {
+			/* convert to internal rate value */
+			rate = (bi->bitrates[i].bitrate << 1) / 10;
+
+			/* set/clear basic rate flag */
+			wl_set_basic_rate(&rs, rate, br_mask & 1);
+			br_mask >>= 1;
+		}
+
+		/* update the rate set */
+		WL_LOCK(wl);
+		wlc_ioctl(wl->wlc, WLC_SET_RATESET, &rs, sizeof(rs), NULL);
+		WL_UNLOCK(wl);
 	}
 	if (changed & BSS_CHANGED_BEACON_INT) {
 		/* Beacon interval changed */
-		WL_NONE("%s: Beacon Interval: %d\n",
-			__func__, info->beacon_int);
+		WL_LOCK(wl);
 		wlc_set(wl->wlc, WLC_SET_BCNPRD, info->beacon_int);
+		WL_UNLOCK(wl);
 	}
 	if (changed & BSS_CHANGED_BSSID) {
 		/* BSSID changed, for whatever reason (IBSS and managed mode) */
-		WL_NONE("%s: new BSSID: aid %d  bss:%pM\n", __func__,
-			info->aid, info->bssid);
 		WL_LOCK(wl);
 		wlc_set_addrmatch(wl->wlc, RCM_BSSID_OFFSET,
 				  info->bssid);
@@ -393,41 +417,42 @@
 	}
 	if (changed & BSS_CHANGED_BEACON) {
 		/* Beacon data changed, retrieve new beacon (beaconing modes) */
-		WL_ERROR("%s: beacon changed\n", __func__);
+		wiphy_err(wiphy, "%s: beacon changed\n", __func__);
 	}
 	if (changed & BSS_CHANGED_BEACON_ENABLED) {
 		/* Beaconing should be enabled/disabled (beaconing modes) */
-		WL_ERROR("%s: Beacon enabled: %s\n", __func__,
-			 info->enable_beacon ? "true" : "false");
+		wiphy_err(wiphy, "%s: Beacon enabled: %s\n", __func__,
+			  info->enable_beacon ? "true" : "false");
 	}
 	if (changed & BSS_CHANGED_CQM) {
 		/* Connection quality monitor config changed */
-		WL_ERROR("%s: cqm change: threshold %d, hys %d (implement)\n",
-			__func__, info->cqm_rssi_thold, info->cqm_rssi_hyst);
+		wiphy_err(wiphy, "%s: cqm change: threshold %d, hys %d "
+			  " (implement)\n", __func__, info->cqm_rssi_thold,
+			  info->cqm_rssi_hyst);
 	}
 	if (changed & BSS_CHANGED_IBSS) {
 		/* IBSS join status changed */
-		WL_ERROR("%s: IBSS joined: %s (implement)\n", __func__,
-			info->ibss_joined ? "true" : "false");
+		wiphy_err(wiphy, "%s: IBSS joined: %s (implement)\n", __func__,
+			  info->ibss_joined ? "true" : "false");
 	}
 	if (changed & BSS_CHANGED_ARP_FILTER) {
 		/* Hardware ARP filter address list or state changed */
-		WL_ERROR("%s: arp filtering: enabled %s, count %d (implement)\n",
-			__func__, info->arp_filter_enabled ? "true" : "false",
-			info->arp_addr_cnt);
+		wiphy_err(wiphy, "%s: arp filtering: enabled %s, count %d"
+			  " (implement)\n", __func__, info->arp_filter_enabled ?
+			  "true" : "false", info->arp_addr_cnt);
 	}
 	if (changed & BSS_CHANGED_QOS) {
 		/*
 		 * QoS for this association was enabled/disabled.
 		 * Note that it is only ever disabled for station mode.
 		 */
-		WL_ERROR("%s: qos enabled: %s (implement)\n", __func__,
-			info->qos ? "true" : "false");
+		wiphy_err(wiphy, "%s: qos enabled: %s (implement)\n", __func__,
+			  info->qos ? "true" : "false");
 	}
 	if (changed & BSS_CHANGED_IDLE) {
 		/* Idle changed for this BSS/interface */
-		WL_ERROR("%s: BSS idle: %s (implement)\n", __func__,
-			info->idle ? "true" : "false");
+		wiphy_err(wiphy, "%s: BSS idle: %s (implement)\n", __func__,
+			  info->idle ? "true" : "false");
 	}
 	return;
 }
@@ -438,23 +463,23 @@
 			unsigned int *total_flags, u64 multicast)
 {
 	struct wl_info *wl = hw->priv;
+	struct wiphy *wiphy = hw->wiphy;
 
 	changed_flags &= MAC_FILTERS;
 	*total_flags &= MAC_FILTERS;
 	if (changed_flags & FIF_PROMISC_IN_BSS)
-		WL_ERROR("FIF_PROMISC_IN_BSS\n");
+		wiphy_err(wiphy, "FIF_PROMISC_IN_BSS\n");
 	if (changed_flags & FIF_ALLMULTI)
-		WL_ERROR("FIF_ALLMULTI\n");
+		wiphy_err(wiphy, "FIF_ALLMULTI\n");
 	if (changed_flags & FIF_FCSFAIL)
-		WL_ERROR("FIF_FCSFAIL\n");
+		wiphy_err(wiphy, "FIF_FCSFAIL\n");
 	if (changed_flags & FIF_PLCPFAIL)
-		WL_ERROR("FIF_PLCPFAIL\n");
+		wiphy_err(wiphy, "FIF_PLCPFAIL\n");
 	if (changed_flags & FIF_CONTROL)
-		WL_ERROR("FIF_CONTROL\n");
+		wiphy_err(wiphy, "FIF_CONTROL\n");
 	if (changed_flags & FIF_OTHER_BSS)
-		WL_ERROR("FIF_OTHER_BSS\n");
+		wiphy_err(wiphy, "FIF_OTHER_BSS\n");
 	if (changed_flags & FIF_BCN_PRBRESP_PROMISC) {
-		WL_NONE("FIF_BCN_PRBRESP_PROMISC\n");
 		WL_LOCK(wl);
 		if (*total_flags & FIF_BCN_PRBRESP_PROMISC) {
 			wl->pub->mac80211_state |= MAC80211_PROMISC_BCNS;
@@ -471,14 +496,12 @@
 static int
 wl_ops_set_tim(struct ieee80211_hw *hw, struct ieee80211_sta *sta, bool set)
 {
-	WL_NONE("%s: Enter\n", __func__);
 	return 0;
 }
 
 static void wl_ops_sw_scan_start(struct ieee80211_hw *hw)
 {
 	struct wl_info *wl = hw->priv;
-	WL_NONE("Scan Start\n");
 	WL_LOCK(wl);
 	wlc_scan_start(wl->wlc);
 	WL_UNLOCK(wl);
@@ -488,7 +511,6 @@
 static void wl_ops_sw_scan_complete(struct ieee80211_hw *hw)
 {
 	struct wl_info *wl = hw->priv;
-	WL_NONE("Scan Complete\n");
 	WL_LOCK(wl);
 	wlc_scan_stop(wl->wlc);
 	WL_UNLOCK(wl);
@@ -497,7 +519,7 @@
 
 static void wl_ops_set_tsf(struct ieee80211_hw *hw, u64 tsf)
 {
-	WL_ERROR("%s: Enter\n", __func__);
+	wiphy_err(hw->wiphy, "%s: Enter\n", __func__);
 	return;
 }
 
@@ -510,20 +532,10 @@
 
 	WL_LOCK(wl);
 	cnt = wl->pub->_cnt;
-	stats->dot11ACKFailureCount = cnt->txnoack;
-	stats->dot11RTSFailureCount = cnt->txnocts;
-	stats->dot11FCSErrorCount = cnt->rxcrc;
-	stats->dot11RTSSuccessCount = cnt->txrts;
-	WL_UNLOCK(wl);
-	return 0;
-}
-
-static int wl_ops_set_rts_threshold(struct ieee80211_hw *hw, u32 value)
-{
-	struct wl_info *wl = hw->priv;
-
-	WL_LOCK(wl);
-	wlc_iovar_setint(wl->wlc, "rtsthresh", value & 0xFFFF);
+	stats->dot11ACKFailureCount = 0;
+	stats->dot11RTSFailureCount = 0;
+	stats->dot11FCSErrorCount = 0;
+	stats->dot11RTSSuccessCount = 0;
 	WL_UNLOCK(wl);
 	return 0;
 }
@@ -532,10 +544,10 @@
 wl_ops_sta_notify(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
 		  enum sta_notify_cmd cmd, struct ieee80211_sta *sta)
 {
-	WL_NONE("%s: Enter\n", __func__);
 	switch (cmd) {
 	default:
-		WL_ERROR("%s: Unknown cmd = %d\n", __func__, cmd);
+		wiphy_err(hw->wiphy, "%s: Unknown cmd = %d\n", __func__,
+			  cmd);
 		break;
 	}
 	return;
@@ -547,12 +559,8 @@
 {
 	struct wl_info *wl = hw->priv;
 
-	WL_NONE("%s: Enter (WME config)\n", __func__);
-	WL_NONE("queue %d, txop %d, cwmin %d, cwmax %d, aifs %d\n", queue,
-		 params->txop, params->cw_min, params->cw_max, params->aifs);
-
 	WL_LOCK(wl);
-	wlc_wme_setparams(wl->wlc, queue, (void *)params, true);
+	wlc_wme_setparams(wl->wlc, queue, params, true);
 	WL_UNLOCK(wl);
 
 	return 0;
@@ -560,7 +568,7 @@
 
 static u64 wl_ops_get_tsf(struct ieee80211_hw *hw)
 {
-	WL_ERROR("%s: Enter\n", __func__);
+	wiphy_err(hw->wiphy, "%s: Enter\n", __func__);
 	return 0;
 }
 
@@ -585,7 +593,7 @@
 	wl->pub->global_ampdu = &(scb->scb_ampdu);
 	wl->pub->global_ampdu->scb = scb;
 	wl->pub->global_ampdu->max_pdu = 16;
-	pktq_init(&scb->scb_ampdu.txq, AMPDU_MAX_SCB_TID,
+	bcm_pktq_init(&scb->scb_ampdu.txq, AMPDU_MAX_SCB_TID,
 		  AMPDU_MAX_SCB_TID * PKTQ_LEN_DEFAULT);
 
 	sta->ht_cap.ht_supported = true;
@@ -603,7 +611,6 @@
 wl_ops_sta_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
 		  struct ieee80211_sta *sta)
 {
-	WL_NONE("%s: Enter\n", __func__);
 	return 0;
 }
 
@@ -614,27 +621,25 @@
 		    struct ieee80211_sta *sta, u16 tid, u16 *ssn,
 		    u8 buf_size)
 {
-#if defined(BCMDBG)
 	struct scb *scb = (struct scb *)sta->drv_priv;
-#endif
 	struct wl_info *wl = hw->priv;
 	int status;
 
-	ASSERT(scb->magic == SCB_MAGIC);
+	if (WARN_ON(scb->magic != SCB_MAGIC))
+		return -EIDRM;
 	switch (action) {
 	case IEEE80211_AMPDU_RX_START:
-		WL_NONE("%s: action = IEEE80211_AMPDU_RX_START\n", __func__);
 		break;
 	case IEEE80211_AMPDU_RX_STOP:
-		WL_NONE("%s: action = IEEE80211_AMPDU_RX_STOP\n", __func__);
 		break;
 	case IEEE80211_AMPDU_TX_START:
 		WL_LOCK(wl);
 		status = wlc_aggregatable(wl->wlc, tid);
 		WL_UNLOCK(wl);
 		if (!status) {
-			/* WL_ERROR("START: tid %d is not agg' able, return FAILURE to stack\n", tid); */
-			return -1;
+			wiphy_err(wl->wiphy, "START: tid %d is not agg\'able\n",
+				  tid);
+			return -EINVAL;
 		}
 		/* XXX: Use the starting sequence number provided ... */
 		*ssn = 0;
@@ -650,11 +655,10 @@
 	case IEEE80211_AMPDU_TX_OPERATIONAL:
 		/* Not sure what to do here */
 		/* Power save wakeup */
-		WL_NONE("%s: action = IEEE80211_AMPDU_TX_OPERATIONAL\n",
-			__func__);
 		break;
 	default:
-		WL_ERROR("%s: Invalid command, ignoring\n", __func__);
+		wiphy_err(wl->wiphy, "%s: Invalid command, ignoring\n",
+			  __func__);
 	}
 
 	return 0;
@@ -669,10 +673,21 @@
 	blocked = wlc_check_radio_disabled(wl->wlc);
 	WL_UNLOCK(wl);
 
-	WL_NONE("wl: rfkill_poll: %d\n", blocked);
 	wiphy_rfkill_set_hw_state(wl->pub->ieee_hw->wiphy, blocked);
 }
 
+static void wl_ops_flush(struct ieee80211_hw *hw, bool drop)
+{
+	struct wl_info *wl = HW_TO_WL(hw);
+
+	no_printk("%s: drop = %s\n", __func__, drop ? "true" : "false");
+
+	/* wait for packet queue and dma fifos to run empty */
+	WL_LOCK(wl);
+	wlc_wait_for_tx_completion(wl->wlc, drop);
+	WL_UNLOCK(wl);
+}
+
 static const struct ieee80211_ops wl_ops = {
 	.tx = wl_ops_tx,
 	.start = wl_ops_start,
@@ -687,7 +702,6 @@
 	.sw_scan_complete = wl_ops_sw_scan_complete,
 	.set_tsf = wl_ops_set_tsf,
 	.get_stats = wl_ops_get_stats,
-	.set_rts_threshold = wl_ops_set_rts_threshold,
 	.sta_notify = wl_ops_sta_notify,
 	.conf_tx = wl_ops_conf_tx,
 	.get_tsf = wl_ops_get_tsf,
@@ -695,6 +709,7 @@
 	.sta_remove = wl_ops_sta_remove,
 	.ampdu_action = wl_ops_ampdu_action,
 	.rfkill_poll = wl_ops_rfkill_poll,
+	.flush = wl_ops_flush,
 };
 
 /*
@@ -702,8 +717,6 @@
  */
 static int wl_set_hint(struct wl_info *wl, char *abbrev)
 {
-	WL_NONE("%s: Sending country code %c%c to MAC80211\n",
-		 __func__, abbrev[0], abbrev[1]);
 	return regulatory_hint(wl->pub->ieee_hw->wiphy, abbrev);
 }
 
@@ -724,7 +737,7 @@
 static struct wl_info *wl_attach(u16 vendor, u16 device, unsigned long regs,
 			    uint bustype, void *btparam, uint irq)
 {
-	struct wl_info *wl;
+	struct wl_info *wl = NULL;
 	int unit, err;
 
 	unsigned long base_addr;
@@ -735,14 +748,16 @@
 	err = 0;
 
 	if (unit < 0) {
-		WL_ERROR("wl%d: unit number overflow, exiting\n", unit);
 		return NULL;
 	}
 
 	/* allocate private info */
 	hw = pci_get_drvdata(btparam);	/* btparam == pdev */
-	wl = hw->priv;
-	ASSERT(wl);
+	if (hw != NULL)
+		wl = hw->priv;
+	if (WARN_ON(hw == NULL) || WARN_ON(wl == NULL))
+		return NULL;
+	wl->wiphy = hw->wiphy;
 
 	atomic_set(&wl->callbacks, 0);
 
@@ -759,13 +774,13 @@
 		/* Do nothing */
 	} else {
 		bustype = PCI_BUS;
-		WL_TRACE("force to PCI\n");
+		BCMMSG(wl->wiphy, "force to PCI\n");
 	}
 	wl->bcm_bustype = bustype;
 
 	wl->regsva = ioremap_nocache(base_addr, PCI_BAR0_WINSZ);
 	if (wl->regsva == NULL) {
-		WL_ERROR("wl%d: ioremap() failed\n", unit);
+		wiphy_err(wl->wiphy, "wl%d: ioremap() failed\n", unit);
 		goto fail;
 	}
 	spin_lock_init(&wl->lock);
@@ -773,11 +788,11 @@
 
 	/* prepare ucode */
 	if (wl_request_fw(wl, (struct pci_dev *)btparam) < 0) {
-		WL_ERROR("%s: Failed to find firmware usually in %s\n",
-			 KBUILD_MODNAME, "/lib/firmware/brcm");
+		wiphy_err(wl->wiphy, "%s: Failed to find firmware usually in "
+			  "%s\n", KBUILD_MODNAME, "/lib/firmware/brcm");
 		wl_release_fw(wl);
 		wl_remove((struct pci_dev *)btparam);
-		goto fail1;
+		return NULL;
 	}
 
 	/* common load-time initialization */
@@ -785,24 +800,22 @@
 			     wl->regsva, wl->bcm_bustype, btparam, &err);
 	wl_release_fw(wl);
 	if (!wl->wlc) {
-		WL_ERROR("%s: wlc_attach() failed with code %d\n",
-			 KBUILD_MODNAME, err);
+		wiphy_err(wl->wiphy, "%s: wlc_attach() failed with code %d\n",
+			  KBUILD_MODNAME, err);
 		goto fail;
 	}
 	wl->pub = wlc_pub(wl->wlc);
 
 	wl->pub->ieee_hw = hw;
-	ASSERT(wl->pub->ieee_hw);
-	ASSERT(wl->pub->ieee_hw->priv == wl);
-
 
 	if (wlc_iovar_setint(wl->wlc, "mpc", 0)) {
-		WL_ERROR("wl%d: Error setting MPC variable to 0\n", unit);
+		wiphy_err(wl->wiphy, "wl%d: Error setting MPC variable to 0\n",
+			  unit);
 	}
 
 	/* register our interrupt handler */
 	if (request_irq(irq, wl_isr, IRQF_SHARED, KBUILD_MODNAME, wl)) {
-		WL_ERROR("wl%d: request_irq() failed\n", unit);
+		wiphy_err(wl->wiphy, "wl%d: request_irq() failed\n", unit);
 		goto fail;
 	}
 	wl->irq = irq;
@@ -812,18 +825,20 @@
 			    NULL);
 
 	if (ieee_hw_init(hw)) {
-		WL_ERROR("wl%d: %s: ieee_hw_init failed!\n", unit, __func__);
+		wiphy_err(wl->wiphy, "wl%d: %s: ieee_hw_init failed!\n", unit,
+			  __func__);
 		goto fail;
 	}
 
 	memcpy(perm, &wl->pub->cur_etheraddr, ETH_ALEN);
-	ASSERT(is_valid_ether_addr(perm));
+	if (WARN_ON(!is_valid_ether_addr(perm)))
+		goto fail;
 	SET_IEEE80211_PERM_ADDR(hw, perm);
 
 	err = ieee80211_register_hw(hw);
 	if (err) {
-		WL_ERROR("%s: ieee80211_register_hw failed, status %d\n",
-			 __func__, err);
+		wiphy_err(wl->wiphy, "%s: ieee80211_register_hw failed, status"
+			  "%d\n", __func__, err);
 	}
 
 	if (wl->pub->srom_ccode[0])
@@ -831,8 +846,8 @@
 	else
 		err = wl_set_hint(wl, "US");
 	if (err) {
-		WL_ERROR("%s: regulatory_hint failed, status %d\n",
-			 __func__, err);
+		wiphy_err(wl->wiphy, "%s: regulatory_hint failed, status %d\n",
+			  __func__, err);
 	}
 
 	wl_found++;
@@ -840,7 +855,6 @@
 
 fail:
 	wl_free(wl);
-fail1:
 	return NULL;
 }
 
@@ -1027,9 +1041,8 @@
 	hw->wiphy->bands[IEEE80211_BAND_5GHZ] = NULL;
 
 	if (wlc_get(wl->wlc, WLC_GET_PHYLIST, (int *)&phy_list) < 0) {
-		WL_ERROR("Phy list failed\n");
+		wiphy_err(hw->wiphy, "Phy list failed\n");
 	}
-	WL_NONE("%s: phylist = %c\n", __func__, phy_list[0]);
 
 	if (phy_list[0] == 'n' || phy_list[0] == 'c') {
 		if (phy_list[0] == 'c') {
@@ -1039,8 +1052,7 @@
 		}
 		hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &wl_band_2GHz_nphy;
 	} else {
-		BUG();
-		return -1;
+		return -EPERM;
 	}
 
 	/* Assume all bands use the same phy.  True for 11n devices. */
@@ -1050,12 +1062,9 @@
 			hw->wiphy->bands[IEEE80211_BAND_5GHZ] =
 			    &wl_band_5GHz_nphy;
 		} else {
-			return -1;
+			return -EPERM;
 		}
 	}
-
-	WL_NONE("%s: 2ghz = %d, 5ghz = %d\n", __func__, 1, has_5g);
-
 	return 0;
 }
 
@@ -1070,8 +1079,7 @@
 	    | IEEE80211_HW_AMPDU_AGGREGATION;
 
 	hw->extra_tx_headroom = wlc_get_header_len();
-	/* FIXME: should get this from wlc->machwcap */
-	hw->queues = 4;
+	hw->queues = N_TX_QUEUES;
 	/* FIXME: this doesn't seem to be used properly in minstrel_ht.
 	 * mac80211/status.c:ieee80211_tx_status() checks this value,
 	 * but mac80211/rc80211_minstrel_ht.c:minstrel_ht_get_rate()
@@ -1104,11 +1112,9 @@
 	struct ieee80211_hw *hw;
 	u32 val;
 
-	ASSERT(pdev);
-
-	WL_TRACE("%s: bus %d slot %d func %d irq %d\n",
-		 __func__, pdev->bus->number, PCI_SLOT(pdev->devfn),
-		 PCI_FUNC(pdev->devfn), pdev->irq);
+	dev_info(&pdev->dev, "bus %d slot %d func %d irq %d\n",
+	       pdev->bus->number, PCI_SLOT(pdev->devfn),
+	       PCI_FUNC(pdev->devfn), pdev->irq);
 
 	if ((pdev->vendor != PCI_VENDOR_ID_BROADCOM) ||
 	    (((pdev->device & 0xff00) != 0x4300) &&
@@ -1118,9 +1124,9 @@
 
 	rc = pci_enable_device(pdev);
 	if (rc) {
-		WL_ERROR("%s: Cannot enable device %d-%d_%d\n",
-			 __func__, pdev->bus->number, PCI_SLOT(pdev->devfn),
-			 PCI_FUNC(pdev->devfn));
+		pr_err("%s: Cannot enable device %d-%d_%d\n",
+		       __func__, pdev->bus->number, PCI_SLOT(pdev->devfn),
+		       PCI_FUNC(pdev->devfn));
 		return -ENODEV;
 	}
 	pci_set_master(pdev);
@@ -1131,9 +1137,8 @@
 
 	hw = ieee80211_alloc_hw(sizeof(struct wl_info), &wl_ops);
 	if (!hw) {
-		WL_ERROR("%s: ieee80211_alloc_hw failed\n", __func__);
-		rc = -ENOMEM;
-		goto err_1;
+		pr_err("%s: ieee80211_alloc_hw failed\n", __func__);
+		return -ENOMEM;
 	}
 
 	SET_IEEE80211_DEV(hw, &pdev->dev);
@@ -1146,14 +1151,11 @@
 		       PCI_BUS, pdev, pdev->irq);
 
 	if (!wl) {
-		WL_ERROR("%s: %s: wl_attach failed!\n",
-			 KBUILD_MODNAME, __func__);
+		pr_err("%s: %s: wl_attach failed!\n", KBUILD_MODNAME,
+		       __func__);
 		return -ENODEV;
 	}
 	return 0;
- err_1:
-	WL_ERROR("%s: err_1: Major hoarkage\n", __func__);
-	return 0;
 }
 
 static int wl_suspend(struct pci_dev *pdev, pm_message_t state)
@@ -1161,12 +1163,11 @@
 	struct wl_info *wl;
 	struct ieee80211_hw *hw;
 
-	WL_TRACE("wl: wl_suspend\n");
-
 	hw = pci_get_drvdata(pdev);
 	wl = HW_TO_WL(hw);
 	if (!wl) {
-		WL_ERROR("wl: wl_suspend: pci_get_drvdata failed\n");
+		wiphy_err(wl->wiphy,
+			  "wl_suspend: pci_get_drvdata failed\n");
 		return -ENODEV;
 	}
 
@@ -1187,11 +1188,11 @@
 	int err = 0;
 	u32 val;
 
-	WL_TRACE("wl: wl_resume\n");
 	hw = pci_get_drvdata(pdev);
 	wl = HW_TO_WL(hw);
 	if (!wl) {
-		WL_ERROR("wl: wl_resume: pci_get_drvdata failed\n");
+		wiphy_err(wl->wiphy,
+			  "wl: wl_resume: pci_get_drvdata failed\n");
 		return -ENODEV;
 	}
 
@@ -1231,7 +1232,7 @@
 	hw = pci_get_drvdata(pdev);
 	wl = HW_TO_WL(hw);
 	if (!wl) {
-		WL_ERROR("wl: wl_remove: pci_get_drvdata failed\n");
+		pr_err("wl: wl_remove: pci_get_drvdata failed\n");
 		return;
 	}
 
@@ -1239,7 +1240,7 @@
 	status = wlc_chipmatch(pdev->vendor, pdev->device);
 	WL_UNLOCK(wl);
 	if (!status) {
-		WL_ERROR("wl: wl_remove: wlc_chipmatch failed\n");
+		wiphy_err(wl->wiphy, "wl: wl_remove: wlc_chipmatch failed\n");
 		return;
 	}
 	if (wl->wlc) {
@@ -1249,7 +1250,6 @@
 		WL_LOCK(wl);
 		wl_down(wl);
 		WL_UNLOCK(wl);
-		WL_NONE("%s: Down\n", __func__);
 	}
 	pci_disable_device(pdev);
 
@@ -1342,7 +1342,6 @@
 {
 	struct wl_timer *t, *next;
 
-	ASSERT(wl);
 	/* free ucode data */
 	if (wl->fw.fw_cnt)
 		wl_ucode_data_free();
@@ -1389,13 +1388,30 @@
 	wl->regsva = NULL;
 }
 
+/* flags the given rate in rateset as requested */
+static void wl_set_basic_rate(struct wl_rateset *rs, u16 rate, bool is_br)
+{
+	u32 i;
+
+	for (i = 0; i < rs->count; i++) {
+		if (rate != (rs->rates[i] & 0x7f))
+			continue;
+
+		if (is_br)
+			rs->rates[i] |= WLC_RATE_FLAG;
+		else
+			rs->rates[i] &= WLC_RATE_MASK;
+		return;
+	}
+}
+
 /*
  * precondition: perimeter lock has been acquired
  */
 void wl_txflowcontrol(struct wl_info *wl, struct wl_if *wlif, bool state,
 		      int prio)
 {
-	WL_ERROR("Shouldn't be here %s\n", __func__);
+	wiphy_err(wl->wiphy, "Shouldn't be here %s\n", __func__);
 }
 
 /*
@@ -1403,8 +1419,7 @@
  */
 void wl_init(struct wl_info *wl)
 {
-	WL_TRACE("wl%d: wl_init\n", wl->pub->unit);
-
+	BCMMSG(WL_TO_HW(wl)->wiphy, "wl%d\n", wl->pub->unit);
 	wl_reset(wl);
 
 	wlc_init(wl->wlc);
@@ -1415,8 +1430,7 @@
  */
 uint wl_reset(struct wl_info *wl)
 {
-	WL_TRACE("wl%d: wl_reset\n", wl->pub->unit);
-
+	BCMMSG(WL_TO_HW(wl)->wiphy, "wl%d\n", wl->pub->unit);
 	wlc_reset(wl->wlc);
 
 	/* dpc will not be rescheduled */
@@ -1429,7 +1443,7 @@
  * These are interrupt on/off entry points. Disable interrupts
  * during interrupt state transition.
  */
-void BCMFASTPATH wl_intrson(struct wl_info *wl)
+void wl_intrson(struct wl_info *wl)
 {
 	unsigned long flags;
 
@@ -1446,7 +1460,7 @@
 	return true;
 }
 
-u32 BCMFASTPATH wl_intrsoff(struct wl_info *wl)
+u32 wl_intrsoff(struct wl_info *wl)
 {
 	unsigned long flags;
 	u32 status;
@@ -1503,7 +1517,7 @@
 	WL_LOCK(wl);
 }
 
-static irqreturn_t BCMFASTPATH wl_isr(int irq, void *dev_id)
+static irqreturn_t wl_isr(int irq, void *dev_id)
 {
 	struct wl_info *wl;
 	bool ours, wantdpc;
@@ -1521,7 +1535,6 @@
 
 			/* ...and call the second level interrupt handler */
 			/* schedule dpc */
-			ASSERT(wl->resched == false);
 			tasklet_schedule(&wl->tasklet);
 		}
 	}
@@ -1531,7 +1544,7 @@
 	return IRQ_RETVAL(ours);
 }
 
-static void BCMFASTPATH wl_dpc(unsigned long data)
+static void wl_dpc(unsigned long data)
 {
 	struct wl_info *wl;
 
@@ -1613,7 +1626,8 @@
 
 	t = kzalloc(sizeof(struct wl_timer), GFP_ATOMIC);
 	if (!t) {
-		WL_ERROR("wl%d: wl_init_timer: out of memory\n", wl->pub->unit);
+		wiphy_err(wl->wiphy, "wl%d: wl_init_timer: out of memory\n",
+			  wl->pub->unit);
 		return 0;
 	}
 
@@ -1644,12 +1658,10 @@
 {
 #ifdef BCMDBG
 	if (t->set) {
-		WL_ERROR("%s: Already set. Name: %s, per %d\n",
-			 __func__, t->name, periodic);
+		wiphy_err(wl->wiphy, "%s: Already set. Name: %s, per %d\n",
+			  __func__, t->name, periodic);
 	}
 #endif
-	ASSERT(!t->set);
-
 	t->ms = ms;
 	t->periodic = (bool) periodic;
 	t->set = true;
@@ -1719,37 +1731,6 @@
  */
 static int wl_linux_watchdog(void *ctx)
 {
-	struct wl_info *wl = (struct wl_info *) ctx;
-	struct wl_cnt *cnt;
-	struct net_device_stats *stats = NULL;
-	uint id;
-	/* refresh stats */
-	if (wl->pub->up) {
-		ASSERT(wl->stats_id < 2);
-
-		cnt = wl->pub->_cnt;
-		id = 1 - wl->stats_id;
-		stats = &wl->stats_watchdog[id];
-		stats->rx_packets = cnt->rxframe;
-		stats->tx_packets = cnt->txframe;
-		stats->rx_bytes = cnt->rxbyte;
-		stats->tx_bytes = cnt->txbyte;
-		stats->rx_errors = cnt->rxerror;
-		stats->tx_errors = cnt->txerror;
-		stats->collisions = 0;
-
-		stats->rx_length_errors = 0;
-		stats->rx_over_errors = cnt->rxoflo;
-		stats->rx_crc_errors = cnt->rxcrc;
-		stats->rx_frame_errors = 0;
-		stats->rx_fifo_errors = cnt->rxoflo;
-		stats->rx_missed_errors = 0;
-
-		stats->tx_fifo_errors = cnt->txuflo;
-
-		wl->stats_id = id;
-	}
-
 	return 0;
 }
 
@@ -1780,8 +1761,8 @@
 				pdata = wl->fw.fw_bin[i]->data + hdr->offset;
 				*pbuf = kmalloc(hdr->len, GFP_ATOMIC);
 				if (*pbuf == NULL) {
-					WL_ERROR("fail to alloc %d bytes\n",
-						 hdr->len);
+					wiphy_err(wl->wiphy, "fail to alloc %d"
+						  " bytes\n", hdr->len);
 					goto fail;
 				}
 				memcpy(*pbuf, pdata, hdr->len);
@@ -1789,10 +1770,11 @@
 			}
 		}
 	}
-	WL_ERROR("ERROR: ucode buf tag:%d can not be found!\n", idx);
+	wiphy_err(wl->wiphy, "ERROR: ucode buf tag:%d can not be found!\n",
+		  idx);
 	*pbuf = NULL;
 fail:
-	return BCME_NOTFOUND;
+	return -ENODATA;
 }
 
 /*
@@ -1810,14 +1792,18 @@
 		     entry++, hdr++) {
 			if (hdr->idx == idx) {
 				pdata = wl->fw.fw_bin[i]->data + hdr->offset;
-				ASSERT(hdr->len == 4);
+				if (hdr->len != 4) {
+					wiphy_err(wl->wiphy,
+						  "ERROR: fw hdr len\n");
+					return -ENOMSG;
+				}
 				*data = *((u32 *) pdata);
 				return 0;
 			}
 		}
 	}
-	WL_ERROR("ERROR: ucode tag:%d can not be found!\n", idx);
-	return -1;
+	wiphy_err(wl->wiphy, "ERROR: ucode tag:%d can not be found!\n", idx);
+	return -ENOMSG;
 }
 
 /*
@@ -1837,26 +1823,22 @@
 			break;
 		sprintf(fw_name, "/*(DEBLOBBED)*/", wl_firmwares[i],
 			UCODE_LOADER_API_VER);
-		WL_NONE("request fw %s\n", fw_name);
 		status = reject_firmware(&wl->fw.fw_bin[i], fw_name, device);
 		if (status) {
-			WL_ERROR("%s: fail to load firmware %s\n",
-				 KBUILD_MODNAME, fw_name);
+			wiphy_err(wl->wiphy, "%s: fail to load firmware %s\n",
+				  KBUILD_MODNAME, fw_name);
 			return status;
 		}
-		WL_NONE("request fw %s\n", fw_name);
 		sprintf(fw_name, "/*(DEBLOBBED)*/", wl_firmwares[i],
 			UCODE_LOADER_API_VER);
 		status = reject_firmware(&wl->fw.fw_hdr[i], fw_name, device);
 		if (status) {
-			WL_ERROR("%s: fail to load firmware %s\n",
-				 KBUILD_MODNAME, fw_name);
+			wiphy_err(wl->wiphy, "%s: fail to load firmware %s\n",
+				  KBUILD_MODNAME, fw_name);
 			return status;
 		}
 		wl->fw.hdr_num_entries[i] =
 		    wl->fw.fw_hdr[i]->size / (sizeof(struct wl_fw_hdr));
-		WL_NONE("request fw %s find: %d entries\n",
-			fw_name, wl->fw.hdr_num_entries[i]);
 	}
 	wl->fw.fw_cnt = i;
 	return wl_ucode_data_init(wl);
@@ -1904,16 +1886,17 @@
 		if (fw == NULL && fw_hdr == NULL) {
 			break;
 		} else if (fw == NULL || fw_hdr == NULL) {
-			WL_ERROR("%s: invalid bin/hdr fw\n", __func__);
+			wiphy_err(wl->wiphy, "%s: invalid bin/hdr fw\n",
+				  __func__);
 			rc = -EBADF;
 		} else if (fw_hdr->size % sizeof(struct wl_fw_hdr)) {
-			WL_ERROR("%s: non integral fw hdr file size %zu/%zu\n",
-				 __func__, fw_hdr->size,
-				 sizeof(struct wl_fw_hdr));
+			wiphy_err(wl->wiphy, "%s: non integral fw hdr file "
+				"size %zu/%zu\n", __func__, fw_hdr->size,
+				sizeof(struct wl_fw_hdr));
 			rc = -EBADF;
 		} else if (fw->size < MIN_FW_SIZE || fw->size > MAX_FW_SIZE) {
-			WL_ERROR("%s: out of bounds fw file size %zu\n",
-				 __func__, fw->size);
+			wiphy_err(wl->wiphy, "%s: out of bounds fw file size "
+				  "%zu\n", __func__, fw->size);
 			rc = -EBADF;
 		} else {
 			/* check if ucode section overruns firmware image */
@@ -1922,15 +1905,17 @@
 			     !rc; entry++, ucode_hdr++) {
 				if (ucode_hdr->offset + ucode_hdr->len >
 				    fw->size) {
-					WL_ERROR("%s: conflicting bin/hdr\n",
-						 __func__);
+					wiphy_err(wl->wiphy,
+						  "%s: conflicting bin/hdr\n",
+						  __func__);
 					rc = -EBADF;
 				}
 			}
 		}
 	}
 	if (rc == 0 && wl->fw.fw_cnt != i) {
-		WL_ERROR("%s: invalid fw_cnt=%d\n", __func__, wl->fw.fw_cnt);
+		wiphy_err(wl->wiphy, "%s: invalid fw_cnt=%d\n", __func__,
+			wl->fw.fw_cnt);
 		rc = -EBADF;
 	}
 	return rc;
@@ -1943,8 +1928,6 @@
 {
 	bool blocked = wlc_check_radio_disabled(wl->wlc);
 
-	WL_NONE("%s: update hw state: blocked=%s\n", __func__,
-		blocked ? "true" : "false");
 	WL_UNLOCK(wl);
 	wiphy_rfkill_set_hw_state(wl->pub->ieee_hw->wiphy, blocked);
 	if (blocked)
@@ -1952,3 +1935,13 @@
 	WL_LOCK(wl);
 	return blocked;
 }
+
+/*
+ * precondition: perimeter lock has been acquired
+ */
+void wl_msleep(struct wl_info *wl, uint ms)
+{
+	WL_UNLOCK(wl);
+	msleep(ms);
+	WL_LOCK(wl);
+}
diff -druN linux-2.6.39-libre/drivers/staging/brcm80211/brcmsmac/wl_mac80211.h linux-3.0-rc7-libre/drivers/staging/brcm80211/brcmsmac/wl_mac80211.h
--- linux-2.6.39-libre/drivers/staging/brcm80211/brcmsmac/wl_mac80211.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/brcm80211/brcmsmac/wl_mac80211.h	2011-07-11 19:51:52.000000000 -0400
@@ -67,11 +67,8 @@
 #ifdef LINUXSTA_PS
 	u32 pci_psstate[16];	/* pci ps-state save/restore */
 #endif
-	/* RPC, handle, lock, txq, workitem */
-	uint stats_id;		/* the current set of stats */
-	/* ping-pong stats counters updated by Linux watchdog */
-	struct net_device_stats stats_watchdog[2];
 	struct wl_firmware fw;
+	struct wiphy *wiphy;
 };
 
 #define WL_LOCK(wl)	spin_lock_bh(&(wl)->lock)
diff -druN linux-2.6.39-libre/drivers/staging/brcm80211/include/aidmp.h linux-3.0-rc7-libre/drivers/staging/brcm80211/include/aidmp.h
--- linux-2.6.39-libre/drivers/staging/brcm80211/include/aidmp.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/brcm80211/include/aidmp.h	2011-07-11 19:51:52.000000000 -0400
@@ -292,7 +292,7 @@
 #define	AI_OOBDINWIDTH		0x364
 #define	AI_OOBDOUTWIDTH		0x368
 
-#if	defined(IL_BIGENDIAN) && defined(BCMHND74K)
+#if	defined(__BIG_ENDIAN) && defined(BCMHND74K)
 /* Selective swapped defines for those registers we need in
  * big-endian code.
  */
@@ -303,7 +303,7 @@
 #define	AI_RESETCTRL		0x804
 #define	AI_RESETSTATUS		0x800
 
-#else				/* !IL_BIGENDIAN || !BCMHND74K */
+#else				/* !__BIG_ENDIAN || !BCMHND74K */
 
 #define	AI_IOCTRLSET		0x400
 #define	AI_IOCTRLCLEAR		0x404
@@ -312,7 +312,7 @@
 #define	AI_RESETCTRL		0x800
 #define	AI_RESETSTATUS		0x804
 
-#endif				/* IL_BIGENDIAN && BCMHND74K */
+#endif				/* __BIG_ENDIAN && BCMHND74K */
 
 #define	AI_IOCTRLWIDTH		0x700
 #define	AI_IOSTATUSWIDTH	0x704
diff -druN linux-2.6.39-libre/drivers/staging/brcm80211/include/bcmdefs.h linux-3.0-rc7-libre/drivers/staging/brcm80211/include/bcmdefs.h
--- linux-2.6.39-libre/drivers/staging/brcm80211/include/bcmdefs.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/brcm80211/include/bcmdefs.h	2011-07-11 19:51:52.000000000 -0400
@@ -36,12 +36,6 @@
 
 #define	AUTO	(-1)		/* Auto = -1 */
 
-#ifdef mips
-#define BCMFASTPATH		__attribute__ ((__section__(".text.fastpath")))
-#else
-#define BCMFASTPATH
-#endif
-
 /* Bus types */
 #define	SI_BUS			0	/* SOC Interconnect */
 #define	PCI_BUS			1	/* PCI target */
@@ -114,12 +108,6 @@
 
 #define BCMEXTRAHDROOM 172
 
-#ifdef BCMDBG
-#ifndef BCMDBG_ASSERT
-#define BCMDBG_ASSERT
-#endif	/* BCMDBG_ASSERT */
-#endif	/* BCMDBG */
-
 /* Macros for doing definition and get/set of bitfields
  * Usage example, e.g. a three-bit field (bits 4-6):
  *    #define <NAME>_M	BITFIELD_MASK(3)
diff -druN linux-2.6.39-libre/drivers/staging/brcm80211/include/bcmdevs.h linux-3.0-rc7-libre/drivers/staging/brcm80211/include/bcmdevs.h
--- linux-2.6.39-libre/drivers/staging/brcm80211/include/bcmdevs.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/brcm80211/include/bcmdevs.h	2011-07-11 19:51:52.000000000 -0400
@@ -17,17 +17,10 @@
 #ifndef	_BCMDEVS_H
 #define	_BCMDEVS_H
 
-/* PCI vendor IDs */
-#define	VENDOR_BROADCOM		0x14e4
-
-/* DONGLE VID/PIDs */
-#define BCM_DNGL_VID		0x0a5c
-#define BCM_DNGL_BDC_PID	0x0bdc
-
 #define	BCM4325_D11DUAL_ID	0x431b
 #define	BCM4325_D11G_ID		0x431c
 #define	BCM4325_D11A_ID		0x431d
-#define BCM4329_D11N_ID		0x432e	/* 4329 802.11n dualband device */
+
 #define BCM4329_D11N2G_ID	0x432f	/* 4329 802.11n 2.4G device */
 #define BCM4329_D11N5G_ID	0x4330	/* 4329 802.11n 5G device */
 #define BCM4329_D11NDUAL_ID	0x432e
@@ -37,22 +30,13 @@
 #define BCM4319_D11N5G_ID	0x4339	/* 4319 802.11n 5G device */
 
 #define BCM43224_D11N_ID	0x4353	/* 43224 802.11n dualband device */
+
 #define BCM43225_D11N2G_ID	0x4357	/* 43225 802.11n 2.4GHz device */
 
 #define BCM43236_D11N_ID	0x4346	/* 43236 802.11n dualband device */
 #define BCM43236_D11N2G_ID	0x4347	/* 43236 802.11n 2.4GHz device */
-#define BCM43236_D11N5G_ID	0x4348	/* 43236 802.11n 5GHz device */
 
-#define BCM43421_D11N_ID	0xA99D	/* 43421 802.11n dualband device */
 #define BCM4313_D11N2G_ID	0x4727	/* 4313 802.11n 2.4G device */
-#define BCM4330_D11N_ID         0x4360	/* 4330 802.11n dualband device */
-#define BCM4330_D11N2G_ID       0x4361	/* 4330 802.11n 2.4G device */
-#define BCM4330_D11N5G_ID       0x4362	/* 4330 802.11n 5G device */
-#define BCM4336_D11N_ID		0x4343	/* 4336 802.11n 2.4GHz device */
-#define BCM6362_D11N_ID		0x435f	/* 6362 802.11n dualband device */
-#define BCM4331_D11N_ID		0x4331	/* 4331 802.11n dualband id */
-#define BCM4331_D11N2G_ID	0x4332	/* 4331 802.11n 2.4Ghz band id */
-#define BCM4331_D11N5G_ID	0x4333	/* 4331 802.11n 5Ghz band id */
 
 /* Chip IDs */
 #define BCM4313_CHIP_ID		0x4313	/* 4313 chip id */
@@ -60,7 +44,6 @@
 
 #define	BCM43224_CHIP_ID	43224	/* 43224 chipcommon chipid */
 #define	BCM43225_CHIP_ID	43225	/* 43225 chipcommon chipid */
-#define	BCM43228_CHIP_ID	43228	/* 43228 chipcommon chipid */
 #define	BCM43421_CHIP_ID	43421	/* 43421 chipcommon chipid */
 #define	BCM43235_CHIP_ID	43235	/* 43235 chipcommon chipid */
 #define	BCM43236_CHIP_ID	43236	/* 43236 chipcommon chipid */
@@ -82,57 +65,23 @@
 /* Package IDs */
 #define BCM4329_289PIN_PKG_ID	0	/* 4329 289-pin package id */
 #define BCM4329_182PIN_PKG_ID	1	/* 4329N 182-pin package id */
-#define	BCM4716_PKG_ID		8	/* 4716 package id */
 #define	BCM4717_PKG_ID		9	/* 4717 package id */
 #define	BCM4718_PKG_ID		10	/* 4718 package id */
-#define BCM5356_PKG_NONMODE	1	/* 5356 package without nmode suppport */
-#define BCM5358U_PKG_ID		8	/* 5358U package id */
-#define BCM5358_PKG_ID		9	/* 5358 package id */
-#define BCM47186_PKG_ID		10	/* 47186 package id */
-#define BCM5357_PKG_ID		11	/* 5357 package id */
-#define BCM5356U_PKG_ID		12	/* 5356U package id */
-#define HDLSIM5350_PKG_ID	1	/* HDL simulator package id for a 5350 */
 #define HDLSIM_PKG_ID		14	/* HDL simulator package id */
 #define HWSIM_PKG_ID		15	/* Hardware simulator package id */
-#define BCM43224_FAB_CSM	0x8	/* the chip is manufactured by CSM */
 #define BCM43224_FAB_SMIC	0xa	/* the chip is manufactured by SMIC */
-#define BCM4336_WLBGA_PKG_ID 0x8
 
 /* boardflags */
-#define	BFL_RESERVED1		0x00000001
 #define	BFL_PACTRL		0x00000002	/* Board has gpio 9 controlling the PA */
-#define	BFL_AIRLINEMODE		0x00000004	/* Board implements gpio 13 radio disable indication */
-#define	BFL_ADCDIV		0x00000008	/* Board has the rssi ADC divider */
-#define	BFL_ENETROBO		0x00000010	/* Board has robo switch or core */
 #define	BFL_NOPLLDOWN		0x00000020	/* Not ok to power down the chip pll and oscillator */
-#define	BFL_CCKHIPWR		0x00000040	/* Can do high-power CCK transmission */
-#define	BFL_ENETADM		0x00000080	/* Board has ADMtek switch */
-#define	BFL_ENETVLAN		0x00000100	/* Board has VLAN capability */
-#define BFL_NOPCI		0x00000400	/* Board leaves PCI floating */
 #define BFL_FEM			0x00000800	/* Board supports the Front End Module */
 #define BFL_EXTLNA		0x00001000	/* Board has an external LNA in 2.4GHz band */
-#define BFL_HGPA		0x00002000	/* Board has a high gain PA */
-#define	BFL_RESERVED2		0x00004000
-#define	BFL_ALTIQ		0x00008000	/* Alternate I/Q settings */
 #define BFL_NOPA		0x00010000	/* Board has no PA */
-#define BFL_RSSIINV		0x00020000	/* Board's RSSI uses positive slope(not TSSI) */
-#define BFL_PAREF		0x00040000	/* Board uses the PARef LDO */
-#define BFL_3TSWITCH		0x00080000	/* Board uses a triple throw switch shared with BT */
-#define BFL_PHASESHIFT		0x00100000	/* Board can support phase shifter */
 #define BFL_BUCKBOOST		0x00200000	/* Power topology uses BUCKBOOST */
 #define BFL_FEM_BT		0x00400000	/* Board has FEM and switch to share antenna w/ BT */
 #define BFL_NOCBUCK		0x00800000	/* Power topology doesn't use CBUCK */
-#define BFL_CCKFAVOREVM		0x01000000	/* Favor CCK EVM over spectral mask */
 #define BFL_PALDO		0x02000000	/* Power topology uses PALDO */
-#define BFL_LNLDO2_2P5		0x04000000	/* Select 2.5V as LNLDO2 output voltage */
-#define BFL_FASTPWR		0x08000000
-#define BFL_UCPWRCTL_MININDX	0x08000000	/* Enforce min power index to avoid FEM damage */
 #define BFL_EXTLNA_5GHz		0x10000000	/* Board has an external LNA in 5GHz band */
-#define BFL_TRSW_1by2		0x20000000	/* Board has 2 TRSW's in 1by2 designs */
-#define BFL_LO_TRSW_R_5GHz	0x40000000	/* In 5G do not throw TRSW to T for clipLO gain */
-#define BFL_ELNA_GAINDEF	0x80000000	/* Backoff InitGain based on elna_2g/5g field
-						 * when this flag is set
-						 */
 
 /* boardflags2 */
 #define BFL2_RXBB_INT_REG_DIS	0x00000001	/* Board has an external rxbb regulator */
@@ -141,16 +90,12 @@
 #define BFL2_2X4_DIV		0x00000008	/* Board supports the 2X4 diversity switch */
 #define BFL2_5G_PWRGAIN		0x00000010	/* Board supports 5G band power gain */
 #define BFL2_PCIEWAR_OVR	0x00000020	/* Board overrides ASPM and Clkreq settings */
-#define BFL2_CAESERS_BRD	0x00000040	/* Board is Caesers brd (unused by sw) */
 #define BFL2_LEGACY		0x00000080
 #define BFL2_SKWRKFEM_BRD	0x00000100	/* 4321mcm93 board uses Skyworks FEM */
 #define BFL2_SPUR_WAR		0x00000200	/* Board has a WAR for clock-harmonic spurs */
 #define BFL2_GPLL_WAR		0x00000400	/* Flag to narrow G-band PLL loop b/w */
-#define BFL2_TRISTATE_LED	0x00000800	/* Tri-state the LED */
 #define BFL2_SINGLEANT_CCK	0x00001000	/* Tx CCK pkts on Ant 0 only */
 #define BFL2_2G_SPUR_WAR	0x00002000	/* WAR to reduce and avoid clock-harmonic spurs in 2G */
-#define BFL2_BPHY_ALL_TXCORES	0x00004000	/* Transmit bphy frames using all tx cores */
-#define BFL2_FCC_BANDEDGE_WAR	0x00008000	/* using 40Mhz LPF for 20Mhz bandedge channels */
 #define BFL2_GPLL_WAR2	        0x00010000	/* Flag to widen G-band PLL loop b/w */
 #define BFL2_IPALVLSHIFT_3P3    0x00020000
 #define BFL2_INTERNDET_TXIQCAL  0x00040000	/* Use internal envelope detector for TX IQCAL */
@@ -160,32 +105,19 @@
 						 */
 
 /* board specific GPIO assignment, gpio 0-3 are also customer-configurable led */
-#define	BOARD_GPIO_RESERVED1	0x010
-#define	BOARD_GPIO_RESERVED2	0x020
-#define	BOARD_GPIO_RESERVED3	0x080
-#define	BOARD_GPIO_RESERVED4	0x100
 #define	BOARD_GPIO_PACTRL	0x200	/* bit 9 controls the PA on new 4306 boards */
 #define BOARD_GPIO_12		0x1000	/* gpio 12 */
 #define BOARD_GPIO_13		0x2000	/* gpio 13 */
-#define BOARD_GPIO_RESERVED5	0x0800
-#define BOARD_GPIO_RESERVED6	0x2000
-#define BOARD_GPIO_RESERVED7	0x4000
-#define BOARD_GPIO_RESERVED8	0x8000
 
 #define	PCI_CFG_GPIO_SCS	0x10	/* PCI config space bit 4 for 4306c0 slow clock source */
-#define PCI_CFG_GPIO_HWRAD	0x20	/* PCI config space GPIO 13 for hw radio disable */
 #define PCI_CFG_GPIO_XTAL	0x40	/* PCI config space GPIO 14 for Xtal power-up */
 #define PCI_CFG_GPIO_PLL	0x80	/* PCI config space GPIO 15 for PLL power-down */
 
 /* power control defines */
 #define PLL_DELAY		150	/* us pll on delay */
 #define FREF_DELAY		200	/* us fref change delay */
-#define MIN_SLOW_CLK		32	/* us Slow clock period */
 #define	XTAL_ON_DELAY		1000	/* us crystal power-on delay */
 
-/* # of GPIO pins */
-#define GPIO_NUMPINS		16
-
 /* Reference board types */
 #define	SPI_BOARD		0x0402
 
diff -druN linux-2.6.39-libre/drivers/staging/brcm80211/include/bcmnvram.h linux-3.0-rc7-libre/drivers/staging/brcm80211/include/bcmnvram.h
--- linux-2.6.39-libre/drivers/staging/brcm80211/include/bcmnvram.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/brcm80211/include/bcmnvram.h	2011-07-11 19:51:52.000000000 -0400
@@ -30,31 +30,26 @@
 };
 
 /*
- * Get default value for an NVRAM variable
- */
-extern char *nvram_default_get(const char *name);
-
-/*
  * Initialize NVRAM access. May be unnecessary or undefined on certain
  * platforms.
  */
-extern int nvram_init(void *sih);
+extern int nvram_init(void);
 
 /*
  * Append a chunk of nvram variables to the global list
  */
-extern int nvram_append(void *si, char *vars, uint varsz);
+extern int nvram_append(char *vars, uint varsz);
 
 /*
  * Check for reset button press for restoring factory defaults.
  */
-extern int nvram_reset(void *sih);
+extern int nvram_reset(void);
 
 /*
  * Disable NVRAM access. May be unnecessary or undefined on certain
  * platforms.
  */
-extern void nvram_exit(void *sih);
+extern void nvram_exit(void);
 
 /*
  * Get the value of an NVRAM variable. The pointer returned may be
@@ -65,12 +60,6 @@
 extern char *nvram_get(const char *name);
 
 /*
- * Read the reset GPIO value from the nvram and set the GPIO
- * as input
- */
-extern int nvram_resetgpio_init(void *sih);
-
-/*
  * Get the value of an NVRAM variable.
  * @param	name	name of variable to get
  * @return	value of variable or NUL if undefined
@@ -139,14 +128,12 @@
  */
 extern int nvram_getall(char *nvram_buf, int count);
 
-/*
- * returns the crc value of the nvram
- * @param	nvh	nvram header pointer
- */
-u8 nvram_calc_crc(struct nvram_header *nvh);
-
 #endif				/* _LANGUAGE_ASSEMBLY */
 
+/* variable access */
+extern char *getvar(char *vars, const char *name);
+extern int getintvar(char *vars, const char *name);
+
 /* The NVRAM version number stored as an NVRAM variable */
 #define NVRAM_SOFTWARE_VERSION	"1"
 
diff -druN linux-2.6.39-libre/drivers/staging/brcm80211/include/bcmsdpcm.h linux-3.0-rc7-libre/drivers/staging/brcm80211/include/bcmsdpcm.h
--- linux-2.6.39-libre/drivers/staging/brcm80211/include/bcmsdpcm.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/brcm80211/include/bcmsdpcm.h	2011-07-11 19:51:52.000000000 -0400
@@ -186,7 +186,7 @@
  * Shared structure between dongle and the host.
  * The structure contains pointers to trap or assert information.
  */
-#define SDPCM_SHARED_VERSION       0x0001
+#define SDPCM_SHARED_VERSION       0x0002
 #define SDPCM_SHARED_VERSION_MASK  0x00FF
 #define SDPCM_SHARED_ASSERT_BUILT  0x0100
 #define SDPCM_SHARED_ASSERT        0x0200
@@ -200,6 +200,7 @@
 	u32 assert_line;
 	u32 console_addr;	/* Address of hndrte_cons_t */
 	u32 msgtrace_addr;
+	u8 tag[32];
 } sdpcm_shared_t;
 
 extern sdpcm_shared_t sdpcm_shared;
diff -druN linux-2.6.39-libre/drivers/staging/brcm80211/include/bcmsrom_fmt.h linux-3.0-rc7-libre/drivers/staging/brcm80211/include/bcmsrom_fmt.h
--- linux-2.6.39-libre/drivers/staging/brcm80211/include/bcmsrom_fmt.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/brcm80211/include/bcmsrom_fmt.h	2011-07-11 19:51:52.000000000 -0400
@@ -105,7 +105,7 @@
 
 /* SROM Rev 4: Reallocate the software part of the srom to accommodate
  * MIMO features. It assumes up to two PCIE functions and 440 bytes
- * of useable srom i.e. the useable storage in chips with OTP that
+ * of usable srom i.e. the usable storage in chips with OTP that
  * implements hardware redundancy.
  */
 
diff -druN linux-2.6.39-libre/drivers/staging/brcm80211/include/bcmutils.h linux-3.0-rc7-libre/drivers/staging/brcm80211/include/bcmutils.h
--- linux-2.6.39-libre/drivers/staging/brcm80211/include/bcmutils.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/brcm80211/include/bcmutils.h	2011-07-11 19:51:52.000000000 -0400
@@ -74,7 +74,7 @@
 #define PKTQ_PREC_ITER(pq, prec)        for (prec = (pq)->num_prec - 1; prec >= 0; prec--)
 
 /* fn(pkt, arg).  return true if pkt belongs to if */
-	typedef bool(*ifpkt_cb_t) (void *, int);
+typedef bool(*ifpkt_cb_t) (struct sk_buff *, void *);
 
 /* operations on a specific precedence in packet queue */
 
@@ -87,30 +87,26 @@
 #define pktq_ppeek(pq, prec)            ((pq)->q[prec].head)
 #define pktq_ppeek_tail(pq, prec)       ((pq)->q[prec].tail)
 
-extern struct sk_buff *pktq_penq(struct pktq *pq, int prec,
+extern struct sk_buff *bcm_pktq_penq(struct pktq *pq, int prec,
 				 struct sk_buff *p);
-extern struct sk_buff *pktq_penq_head(struct pktq *pq, int prec,
+extern struct sk_buff *bcm_pktq_penq_head(struct pktq *pq, int prec,
 				      struct sk_buff *p);
-extern struct sk_buff *pktq_pdeq(struct pktq *pq, int prec);
-extern struct sk_buff *pktq_pdeq_tail(struct pktq *pq, int prec);
+extern struct sk_buff *bcm_pktq_pdeq(struct pktq *pq, int prec);
+extern struct sk_buff *bcm_pktq_pdeq_tail(struct pktq *pq, int prec);
 
 /* packet primitives */
-extern struct sk_buff *pkt_buf_get_skb(uint len);
-extern void pkt_buf_free_skb(struct sk_buff *skb);
+extern struct sk_buff *bcm_pkt_buf_get_skb(uint len);
+extern void bcm_pkt_buf_free_skb(struct sk_buff *skb);
 
 /* Empty the queue at particular precedence level */
-#ifdef BRCM_FULLMAC
-	extern void pktq_pflush(struct pktq *pq, int prec,
-		bool dir);
-#else
-	extern void pktq_pflush(struct pktq *pq, int prec,
-		bool dir, ifpkt_cb_t fn, int arg);
-#endif /* BRCM_FULLMAC */
+extern void bcm_pktq_pflush(struct pktq *pq, int prec,
+	bool dir, ifpkt_cb_t fn, void *arg);
 
 /* operations on a set of precedences in packet queue */
 
-extern int pktq_mlen(struct pktq *pq, uint prec_bmp);
-extern struct sk_buff *pktq_mdeq(struct pktq *pq, uint prec_bmp, int *prec_out);
+extern int bcm_pktq_mlen(struct pktq *pq, uint prec_bmp);
+extern struct sk_buff *bcm_pktq_mdeq(struct pktq *pq, uint prec_bmp,
+	int *prec_out);
 
 /* operations on packet queue as a whole */
 
@@ -121,46 +117,38 @@
 #define pktq_empty(pq)                  ((pq)->len == 0)
 
 /* operations for single precedence queues */
-#define pktenq(pq, p)		pktq_penq(((struct pktq *)pq), 0, (p))
-#define pktenq_head(pq, p)	pktq_penq_head(((struct pktq *)pq), 0, (p))
-#define pktdeq(pq)		pktq_pdeq(((struct pktq *)pq), 0)
-#define pktdeq_tail(pq)		pktq_pdeq_tail(((struct pktq *)pq), 0)
-#define pktqinit(pq, len) pktq_init(((struct pktq *)pq), 1, len)
+#define pktenq(pq, p)		bcm_pktq_penq(((struct pktq *)pq), 0, (p))
+#define pktenq_head(pq, p)	bcm_pktq_penq_head(((struct pktq *)pq), 0, (p))
+#define pktdeq(pq)		bcm_pktq_pdeq(((struct pktq *)pq), 0)
+#define pktdeq_tail(pq)		bcm_pktq_pdeq_tail(((struct pktq *)pq), 0)
+#define pktqinit(pq, len)	bcm_pktq_init(((struct pktq *)pq), 1, len)
 
-	extern void pktq_init(struct pktq *pq, int num_prec, int max_len);
+extern void bcm_pktq_init(struct pktq *pq, int num_prec, int max_len);
 /* prec_out may be NULL if caller is not interested in return value */
-	extern struct sk_buff *pktq_peek_tail(struct pktq *pq, int *prec_out);
-#ifdef BRCM_FULLMAC
-	extern void pktq_flush(struct pktq *pq, bool dir);
-#else
-	extern void pktq_flush(struct pktq *pq, bool dir,
-		ifpkt_cb_t fn, int arg);
-#endif
+extern struct sk_buff *bcm_pktq_peek_tail(struct pktq *pq, int *prec_out);
+extern void bcm_pktq_flush(struct pktq *pq, bool dir,
+	ifpkt_cb_t fn, void *arg);
 
 /* externs */
 /* packet */
-	extern uint pktfrombuf(struct sk_buff *p,
-			       uint offset, int len, unsigned char *buf);
-	extern uint pkttotlen(struct sk_buff *p);
+extern uint bcm_pktfrombuf(struct sk_buff *p,
+	uint offset, int len, unsigned char *buf);
+extern uint bcm_pkttotlen(struct sk_buff *p);
 
 /* ethernet address */
-	extern int bcm_ether_atoe(char *p, u8 *ea);
+extern int bcm_ether_atoe(char *p, u8 *ea);
 
 /* ip address */
 	struct ipv4_addr;
 	extern char *bcm_ip_ntoa(struct ipv4_addr *ia, char *buf);
 
-/* variable access */
-	extern char *getvar(char *vars, const char *name);
-	extern int getintvar(char *vars, const char *name);
 #ifdef BCMDBG
-	extern void prpkt(const char *msg, struct sk_buff *p0);
+extern void bcm_prpkt(const char *msg, struct sk_buff *p0);
 #else
-#define prpkt(a, b)
+#define bcm_prpkt(a, b)
 #endif				/* BCMDBG */
 
 #define bcm_perf_enable()
-#define bcmstats(fmt)
 #define	bcmlog(fmt, a1, a2)
 #define	bcmdumplog(buf, size)	(*buf = '\0')
 #define	bcmdumplogent(buf, idx)	-1
@@ -241,107 +229,6 @@
 /* ** driver/apps-shared section ** */
 
 #define BCME_STRLEN 		64	/* Max string length for BCM errors */
-#define VALID_BCMERROR(e)  ((e <= 0) && (e >= BCME_LAST))
-
-/*
- * error codes could be added but the defined ones shouldn't be changed/deleted
- * these error codes are exposed to the user code
- * when ever a new error code is added to this list
- * please update errorstring table with the related error string and
- * update osl files with os specific errorcode map
-*/
-
-#define BCME_OK				0	/* Success */
-#define BCME_ERROR			-1	/* Error generic */
-#define BCME_BADARG			-2	/* Bad Argument */
-#define BCME_BADOPTION			-3	/* Bad option */
-#define BCME_NOTUP			-4	/* Not up */
-#define BCME_NOTDOWN			-5	/* Not down */
-#define BCME_NOTAP			-6	/* Not AP */
-#define BCME_NOTSTA			-7	/* Not STA  */
-#define BCME_BADKEYIDX			-8	/* BAD Key Index */
-#define BCME_RADIOOFF 			-9	/* Radio Off */
-#define BCME_NOTBANDLOCKED		-10	/* Not  band locked */
-#define BCME_NOCLK			-11	/* No Clock */
-#define BCME_BADRATESET			-12	/* BAD Rate valueset */
-#define BCME_BADBAND			-13	/* BAD Band */
-#define BCME_BUFTOOSHORT		-14	/* Buffer too short */
-#define BCME_BUFTOOLONG			-15	/* Buffer too long */
-#define BCME_BUSY			-16	/* Busy */
-#define BCME_NOTASSOCIATED		-17	/* Not Associated */
-#define BCME_BADSSIDLEN			-18	/* Bad SSID len */
-#define BCME_OUTOFRANGECHAN		-19	/* Out of Range Channel */
-#define BCME_BADCHAN			-20	/* Bad Channel */
-#define BCME_BADADDR			-21	/* Bad Address */
-#define BCME_NORESOURCE			-22	/* Not Enough Resources */
-#define BCME_UNSUPPORTED		-23	/* Unsupported */
-#define BCME_BADLEN			-24	/* Bad length */
-#define BCME_NOTREADY			-25	/* Not Ready */
-#define BCME_EPERM			-26	/* Not Permitted */
-#define BCME_NOMEM			-27	/* No Memory */
-#define BCME_ASSOCIATED			-28	/* Associated */
-#define BCME_RANGE			-29	/* Not In Range */
-#define BCME_NOTFOUND			-30	/* Not Found */
-#define BCME_WME_NOT_ENABLED		-31	/* WME Not Enabled */
-#define BCME_TSPEC_NOTFOUND		-32	/* TSPEC Not Found */
-#define BCME_ACM_NOTSUPPORTED		-33	/* ACM Not Supported */
-#define BCME_NOT_WME_ASSOCIATION	-34	/* Not WME Association */
-#define BCME_SDIO_ERROR			-35	/* SDIO Bus Error */
-#define BCME_DONGLE_DOWN		-36	/* Dongle Not Accessible */
-#define BCME_VERSION			-37	/* Incorrect version */
-#define BCME_TXFAIL			-38	/* TX failure */
-#define BCME_RXFAIL			-39	/* RX failure */
-#define BCME_NODEVICE			-40	/* Device not present */
-#define BCME_NMODE_DISABLED		-41	/* NMODE disabled */
-#define BCME_NONRESIDENT		-42	/* access to nonresident overlay */
-#define BCME_LAST			BCME_NONRESIDENT
-
-/* These are collection of BCME Error strings */
-#define BCMERRSTRINGTABLE {		\
-	"OK",				\
-	"Undefined error",		\
-	"Bad Argument",			\
-	"Bad Option",			\
-	"Not up",			\
-	"Not down",			\
-	"Not AP",			\
-	"Not STA",			\
-	"Bad Key Index",		\
-	"Radio Off",			\
-	"Not band locked",		\
-	"No clock",			\
-	"Bad Rate valueset",		\
-	"Bad Band",			\
-	"Buffer too short",		\
-	"Buffer too long",		\
-	"Busy",				\
-	"Not Associated",		\
-	"Bad SSID len",			\
-	"Out of Range Channel",		\
-	"Bad Channel",			\
-	"Bad Address",			\
-	"Not Enough Resources",		\
-	"Unsupported",			\
-	"Bad length",			\
-	"Not Ready",			\
-	"Not Permitted",		\
-	"No Memory",			\
-	"Associated",			\
-	"Not In Range",			\
-	"Not Found",			\
-	"WME Not Enabled",		\
-	"TSPEC Not Found",		\
-	"ACM Not Supported",		\
-	"Not WME Association",		\
-	"SDIO Bus Error",		\
-	"Dongle Not Accessible",	\
-	"Incorrect version",		\
-	"TX Failure",			\
-	"RX Failure",			\
-	"Device Not Present",		\
-	"NMODE Disabled",		\
-	"Nonresident overlay access", \
-}
 
 #ifndef ABS
 #define	ABS(a)			(((a) < 0) ? -(a) : (a))
@@ -358,16 +245,6 @@
 #define REG_MAP(pa, size)       (void *)(0)
 #endif
 
-extern u32 g_assert_type;
-
-#if defined(BCMDBG_ASSERT)
-#define ASSERT(exp) \
-	  do { if (!(exp)) osl_assert(#exp, __FILE__, __LINE__); } while (0)
-extern void osl_assert(char *exp, char *file, int line);
-#else
-#define ASSERT(exp)	do {} while (0)
-#endif  /* defined(BCMDBG_ASSERT) */
-
 /* register access macros */
 #if defined(BCMSDIO)
 #ifdef BRCM_FULLMAC
@@ -399,7 +276,7 @@
 #define	bcopy(src, dst, len)	memcpy((dst), (src), (len))
 
 /* register access macros */
-#ifndef IL_BIGENDIAN
+#ifndef __BIG_ENDIAN
 #ifndef __mips__
 #define R_REG(r) (\
 	SELECT_BUS_READ(sizeof(*(r)) == sizeof(u8) ? \
@@ -450,7 +327,7 @@
 		}, \
 		(OSL_WRITE_REG(r, v))); \
 	} while (0)
-#else				/* IL_BIGENDIAN */
+#else				/* __BIG_ENDIAN */
 #define R_REG(r) (\
 	SELECT_BUS_READ( \
 		({ \
@@ -487,7 +364,7 @@
 		}, \
 		(OSL_WRITE_REG(r, v))); \
 	} while (0)
-#endif				/* IL_BIGENDIAN */
+#endif				/* __BIG_ENDIAN */
 
 #define AND_REG(r, v)	W_REG((r), R_REG(r) & (v))
 #define OR_REG(r, v)	W_REG((r), R_REG(r) | (v))
@@ -590,8 +467,7 @@
 
 /* externs */
 /* crc */
-	extern u8 hndcrc8(u8 *p, uint nbytes, u8 crc);
-	extern u16 hndcrc16(u8 *p, uint nbytes, u16 crc);
+extern u8 bcm_crc8(u8 *p, uint nbytes, u8 crc);
 /* format/print */
 #if defined(BCMDBG)
 	extern int bcm_format_flags(const bcm_bit_desc_t *bd, u32 flags,
@@ -599,12 +475,9 @@
 	extern int bcm_format_hex(char *str, const void *bytes, int len);
 #endif
 	extern char *bcm_chipname(uint chipid, char *buf, uint len);
-	extern void prhex(const char *msg, unsigned char *buf, uint len);
 
 	extern bcm_tlv_t *bcm_parse_tlvs(void *buf, int buflen,
 						    uint key);
-/* bcmerror */
-	extern const char *bcmerrorstr(int bcmerror);
 
 /* multi-bool data type: set of bools, mbool is true if any is set */
 	typedef u32 mbool;
diff -druN linux-2.6.39-libre/drivers/staging/brcm80211/include/bcmwifi.h linux-3.0-rc7-libre/drivers/staging/brcm80211/include/bcmwifi.h
--- linux-2.6.39-libre/drivers/staging/brcm80211/include/bcmwifi.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/brcm80211/include/bcmwifi.h	2011-07-11 19:51:52.000000000 -0400
@@ -134,14 +134,14 @@
  * combination could be legal given any set of circumstances.
  * RETURNS: true is the chanspec is malformed, false if it looks good.
  */
-extern bool wf_chspec_malformed(chanspec_t chanspec);
+extern bool bcm_chspec_malformed(chanspec_t chanspec);
 
 /*
  * This function returns the channel number that control traffic is being sent on, for legacy
  * channels this is just the channel number, for 40MHZ channels it is the upper or lowre 20MHZ
  * sideband depending on the chanspec selected
  */
-extern u8 wf_chspec_ctlchan(chanspec_t chspec);
+extern u8 bcm_chspec_ctlchan(chanspec_t chspec);
 
 /*
  * Return the channel number for a given frequency and base frequency.
@@ -162,6 +162,6 @@
  *
  * Reference 802.11 REVma, section 17.3.8.3, and 802.11B section 18.4.6.2
  */
-extern int wf_mhz2channel(uint freq, uint start_factor);
+extern int bcm_mhz2channel(uint freq, uint start_factor);
 
 #endif				/* _bcmwifi_h_ */
diff -druN linux-2.6.39-libre/drivers/staging/brcm80211/include/hnddma.h linux-3.0-rc7-libre/drivers/staging/brcm80211/include/hnddma.h
--- linux-2.6.39-libre/drivers/staging/brcm80211/include/hnddma.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/brcm80211/include/hnddma.h	2011-07-11 19:51:52.000000000 -0400
@@ -204,4 +204,23 @@
 extern uint dma_addrwidth(si_t *sih, void *dmaregs);
 void dma_walk_packets(struct hnddma_pub *dmah, void (*callback_fnc)
 		      (void *pkt, void *arg_a), void *arg_a);
+
+/*
+ * DMA(Bug) on some chips seems to declare that the packet is ready, but the
+ * packet length is not updated yet (by DMA) on the expected time.
+ * Workaround is to hold processor till DMA updates the length, and stay off
+ * the bus to allow DMA update the length in buffer
+ */
+static inline void dma_spin_for_len(uint len, struct sk_buff *head)
+{
+#if defined(__mips__)
+	if (!len) {
+		while (!(len = *(u16 *) KSEG1ADDR(head->data)))
+			udelay(1);
+
+		*(u16 *) (head->data) = cpu_to_le16((u16) len);
+	}
+#endif				/* defined(__mips__) */
+}
+
 #endif				/* _hnddma_h_ */
diff -druN linux-2.6.39-libre/drivers/staging/brcm80211/include/hndpmu.h linux-3.0-rc7-libre/drivers/staging/brcm80211/include/hndpmu.h
--- linux-2.6.39-libre/drivers/staging/brcm80211/include/hndpmu.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/brcm80211/include/hndpmu.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,68 +0,0 @@
-/*
- * Copyright (c) 2010 Broadcom Corporation
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#ifndef _hndpmu_h_
-#define _hndpmu_h_
-
-#define SET_LDO_VOLTAGE_LDO1	1
-#define SET_LDO_VOLTAGE_LDO2	2
-#define SET_LDO_VOLTAGE_LDO3	3
-#define SET_LDO_VOLTAGE_PAREF	4
-#define SET_LDO_VOLTAGE_CLDO_PWM	5
-#define SET_LDO_VOLTAGE_CLDO_BURST	6
-#define SET_LDO_VOLTAGE_CBUCK_PWM	7
-#define SET_LDO_VOLTAGE_CBUCK_BURST	8
-#define SET_LDO_VOLTAGE_LNLDO1	9
-#define SET_LDO_VOLTAGE_LNLDO2_SEL	10
-
-extern void si_pmu_init(si_t *sih);
-extern void si_pmu_chip_init(si_t *sih);
-extern void si_pmu_pll_init(si_t *sih, u32 xtalfreq);
-extern void si_pmu_res_init(si_t *sih);
-extern void si_pmu_swreg_init(si_t *sih);
-
-extern u32 si_pmu_force_ilp(si_t *sih, bool force);
-
-extern u32 si_pmu_si_clock(si_t *sih);
-extern u32 si_pmu_cpu_clock(si_t *sih);
-extern u32 si_pmu_mem_clock(si_t *sih);
-extern u32 si_pmu_alp_clock(si_t *sih);
-extern u32 si_pmu_ilp_clock(si_t *sih);
-
-extern void si_pmu_set_switcher_voltage(si_t *sih,
-					u8 bb_voltage, u8 rf_voltage);
-extern void si_pmu_set_ldo_voltage(si_t *sih, u8 ldo, u8 voltage);
-extern u16 si_pmu_fast_pwrup_delay(si_t *sih);
-extern void si_pmu_rcal(si_t *sih);
-extern void si_pmu_pllupd(si_t *sih);
-extern void si_pmu_spuravoid(si_t *sih, u8 spuravoid);
-
-extern bool si_pmu_is_otp_powered(si_t *sih);
-extern u32 si_pmu_measure_alpclk(si_t *sih);
-
-extern u32 si_pmu_chipcontrol(si_t *sih, uint reg, u32 mask, u32 val);
-extern u32 si_pmu_regcontrol(si_t *sih, uint reg, u32 mask, u32 val);
-extern u32 si_pmu_pllcontrol(si_t *sih, uint reg, u32 mask, u32 val);
-extern void si_pmu_pllupd(si_t *sih);
-extern void si_pmu_sprom_enable(si_t *sih, bool enable);
-
-extern void si_pmu_radio_enable(si_t *sih, bool enable);
-extern u32 si_pmu_waitforclk_on_backplane(si_t *sih, u32 clk, u32 delay);
-
-extern void si_pmu_otp_power(si_t *sih, bool on);
-extern void si_sdiod_drive_strength_init(si_t *sih, u32 drivestrength);
-
-#endif				/* _hndpmu_h_ */
diff -druN linux-2.6.39-libre/drivers/staging/brcm80211/include/pcicfg.h linux-3.0-rc7-libre/drivers/staging/brcm80211/include/pcicfg.h
--- linux-2.6.39-libre/drivers/staging/brcm80211/include/pcicfg.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/brcm80211/include/pcicfg.h	2011-07-11 19:51:52.000000000 -0400
@@ -17,508 +17,34 @@
 #ifndef	_h_pcicfg_
 #define	_h_pcicfg_
 
-/* The following inside ifndef's so we don't collide with NTDDK.H */
-#ifndef PCI_MAX_BUS
-#define PCI_MAX_BUS		0x100
-#endif
-#ifndef PCI_MAX_DEVICES
-#define PCI_MAX_DEVICES		0x20
-#endif
-#ifndef PCI_MAX_FUNCTION
-#define PCI_MAX_FUNCTION	0x8
-#endif
-
-#ifndef PCI_INVALID_VENDORID
-#define PCI_INVALID_VENDORID	0xffff
-#endif
-#ifndef PCI_INVALID_DEVICEID
-#define PCI_INVALID_DEVICEID	0xffff
-#endif
-
-/* Convert between bus-slot-function-register and config addresses */
-
-#define	PCICFG_BUS_SHIFT	16	/* Bus shift */
-#define	PCICFG_SLOT_SHIFT	11	/* Slot shift */
-#define	PCICFG_FUN_SHIFT	8	/* Function shift */
-#define	PCICFG_OFF_SHIFT	0	/* Register shift */
-
-#define	PCICFG_BUS_MASK		0xff	/* Bus mask */
-#define	PCICFG_SLOT_MASK	0x1f	/* Slot mask */
-#define	PCICFG_FUN_MASK		7	/* Function mask */
-#define	PCICFG_OFF_MASK		0xff	/* Bus mask */
-
-#define	PCI_CONFIG_ADDR(b, s, f, o)					\
-		((((b) & PCICFG_BUS_MASK) << PCICFG_BUS_SHIFT)		\
-		 | (((s) & PCICFG_SLOT_MASK) << PCICFG_SLOT_SHIFT)	\
-		 | (((f) & PCICFG_FUN_MASK) << PCICFG_FUN_SHIFT)	\
-		 | (((o) & PCICFG_OFF_MASK) << PCICFG_OFF_SHIFT))
-
-#define	PCI_CONFIG_BUS(a)	(((a) >> PCICFG_BUS_SHIFT) & PCICFG_BUS_MASK)
-#define	PCI_CONFIG_SLOT(a)	(((a) >> PCICFG_SLOT_SHIFT) & PCICFG_SLOT_MASK)
-#define	PCI_CONFIG_FUN(a)	(((a) >> PCICFG_FUN_SHIFT) & PCICFG_FUN_MASK)
-#define	PCI_CONFIG_OFF(a)	(((a) >> PCICFG_OFF_SHIFT) & PCICFG_OFF_MASK)
-
-/* PCIE Config space accessing MACROS */
-
-#define	PCIECFG_BUS_SHIFT	24	/* Bus shift */
-#define	PCIECFG_SLOT_SHIFT	19	/* Slot/Device shift */
-#define	PCIECFG_FUN_SHIFT	16	/* Function shift */
-#define	PCIECFG_OFF_SHIFT	0	/* Register shift */
-
-#define	PCIECFG_BUS_MASK	0xff	/* Bus mask */
-#define	PCIECFG_SLOT_MASK	0x1f	/* Slot/Device mask */
-#define	PCIECFG_FUN_MASK	7	/* Function mask */
-#define	PCIECFG_OFF_MASK	0xfff	/* Register mask */
-
-#define	PCIE_CONFIG_ADDR(b, s, f, o)					\
-		((((b) & PCIECFG_BUS_MASK) << PCIECFG_BUS_SHIFT)		\
-		 | (((s) & PCIECFG_SLOT_MASK) << PCIECFG_SLOT_SHIFT)	\
-		 | (((f) & PCIECFG_FUN_MASK) << PCIECFG_FUN_SHIFT)	\
-		 | (((o) & PCIECFG_OFF_MASK) << PCIECFG_OFF_SHIFT))
-
-#define	PCIE_CONFIG_BUS(a)	(((a) >> PCIECFG_BUS_SHIFT) & PCIECFG_BUS_MASK)
-#define	PCIE_CONFIG_SLOT(a)	(((a) >> PCIECFG_SLOT_SHIFT) & PCIECFG_SLOT_MASK)
-#define	PCIE_CONFIG_FUN(a)	(((a) >> PCIECFG_FUN_SHIFT) & PCIECFG_FUN_MASK)
-#define	PCIE_CONFIG_OFF(a)	(((a) >> PCIECFG_OFF_SHIFT) & PCIECFG_OFF_MASK)
-
-/* The actual config space */
-
-#define	PCI_BAR_MAX		6
-
-#define	PCI_ROM_BAR		8
-
-#define	PCR_RSVDA_MAX		2
-
-/* Bits in PCI bars' flags */
-
-#define	PCIBAR_FLAGS		0xf
-#define	PCIBAR_IO		0x1
-#define	PCIBAR_MEM1M		0x2
-#define	PCIBAR_MEM64		0x4
-#define	PCIBAR_PREFETCH		0x8
-#define	PCIBAR_MEM32_MASK	0xFFFFFF80
-
-/* pci config status reg has a bit to indicate that capability ptr is present */
-
-#define PCI_CAPPTR_PRESENT	0x0010
-
-typedef struct _pci_config_regs {
-	u16 vendor;
-	u16 device;
-	u16 command;
-	u16 status;
-	u8 rev_id;
-	u8 prog_if;
-	u8 sub_class;
-	u8 base_class;
-	u8 cache_line_size;
-	u8 latency_timer;
-	u8 header_type;
-	u8 bist;
-	u32 base[PCI_BAR_MAX];
-	u32 cardbus_cis;
-	u16 subsys_vendor;
-	u16 subsys_id;
-	u32 baserom;
-	u32 rsvd_a[PCR_RSVDA_MAX];
-	u8 int_line;
-	u8 int_pin;
-	u8 min_gnt;
-	u8 max_lat;
-	u8 dev_dep[192];
-} pci_config_regs;
-
-#define	SZPCR		(sizeof (pci_config_regs))
-#define	MINSZPCR	64	/* offsetof (dev_dep[0] */
-
-/* A structure for the config registers is nice, but in most
- * systems the config space is not memory mapped, so we need
- * field offsetts. :-(
- */
-#define	PCI_CFG_VID		0
-#define	PCI_CFG_DID		2
-#define	PCI_CFG_CMD		4
-#define	PCI_CFG_STAT		6
-#define	PCI_CFG_REV		8
-#define	PCI_CFG_PROGIF		9
-#define	PCI_CFG_SUBCL		0xa
-#define	PCI_CFG_BASECL		0xb
-#define	PCI_CFG_CLSZ		0xc
-#define	PCI_CFG_LATTIM		0xd
-#define	PCI_CFG_HDR		0xe
-#define	PCI_CFG_BIST		0xf
-#define	PCI_CFG_BAR0		0x10
-#define	PCI_CFG_BAR1		0x14
-#define	PCI_CFG_BAR2		0x18
-#define	PCI_CFG_BAR3		0x1c
-#define	PCI_CFG_BAR4		0x20
-#define	PCI_CFG_BAR5		0x24
-#define	PCI_CFG_CIS		0x28
-#define	PCI_CFG_SVID		0x2c
-#define	PCI_CFG_SSID		0x2e
-#define	PCI_CFG_ROMBAR		0x30
-#define PCI_CFG_CAPPTR		0x34
-#define	PCI_CFG_INT		0x3c
-#define	PCI_CFG_PIN		0x3d
-#define	PCI_CFG_MINGNT		0x3e
-#define	PCI_CFG_MAXLAT		0x3f
-
-/* Classes and subclasses */
-
-typedef enum {
-	PCI_CLASS_OLD = 0,
-	PCI_CLASS_DASDI,
-	PCI_CLASS_NET,
-	PCI_CLASS_DISPLAY,
-	PCI_CLASS_MMEDIA,
-	PCI_CLASS_MEMORY,
-	PCI_CLASS_BRIDGE,
-	PCI_CLASS_COMM,
-	PCI_CLASS_BASE,
-	PCI_CLASS_INPUT,
-	PCI_CLASS_DOCK,
-	PCI_CLASS_CPU,
-	PCI_CLASS_SERIAL,
-	PCI_CLASS_INTELLIGENT = 0xe,
-	PCI_CLASS_SATELLITE,
-	PCI_CLASS_CRYPT,
-	PCI_CLASS_DSP,
-	PCI_CLASS_XOR = 0xfe
-} pci_classes;
-
-typedef enum {
-	PCI_DASDI_SCSI,
-	PCI_DASDI_IDE,
-	PCI_DASDI_FLOPPY,
-	PCI_DASDI_IPI,
-	PCI_DASDI_RAID,
-	PCI_DASDI_OTHER = 0x80
-} pci_dasdi_subclasses;
-
-typedef enum {
-	PCI_NET_ETHER,
-	PCI_NET_TOKEN,
-	PCI_NET_FDDI,
-	PCI_NET_ATM,
-	PCI_NET_OTHER = 0x80
-} pci_net_subclasses;
-
-typedef enum {
-	PCI_DISPLAY_VGA,
-	PCI_DISPLAY_XGA,
-	PCI_DISPLAY_3D,
-	PCI_DISPLAY_OTHER = 0x80
-} pci_display_subclasses;
-
-typedef enum {
-	PCI_MMEDIA_VIDEO,
-	PCI_MMEDIA_AUDIO,
-	PCI_MMEDIA_PHONE,
-	PCI_MEDIA_OTHER = 0x80
-} pci_mmedia_subclasses;
-
-typedef enum {
-	PCI_MEMORY_RAM,
-	PCI_MEMORY_FLASH,
-	PCI_MEMORY_OTHER = 0x80
-} pci_memory_subclasses;
-
-typedef enum {
-	PCI_BRIDGE_HOST,
-	PCI_BRIDGE_ISA,
-	PCI_BRIDGE_EISA,
-	PCI_BRIDGE_MC,
-	PCI_BRIDGE_PCI,
-	PCI_BRIDGE_PCMCIA,
-	PCI_BRIDGE_NUBUS,
-	PCI_BRIDGE_CARDBUS,
-	PCI_BRIDGE_RACEWAY,
-	PCI_BRIDGE_OTHER = 0x80
-} pci_bridge_subclasses;
-
-typedef enum {
-	PCI_COMM_UART,
-	PCI_COMM_PARALLEL,
-	PCI_COMM_MULTIUART,
-	PCI_COMM_MODEM,
-	PCI_COMM_OTHER = 0x80
-} pci_comm_subclasses;
-
-typedef enum {
-	PCI_BASE_PIC,
-	PCI_BASE_DMA,
-	PCI_BASE_TIMER,
-	PCI_BASE_RTC,
-	PCI_BASE_PCI_HOTPLUG,
-	PCI_BASE_OTHER = 0x80
-} pci_base_subclasses;
-
-typedef enum {
-	PCI_INPUT_KBD,
-	PCI_INPUT_PEN,
-	PCI_INPUT_MOUSE,
-	PCI_INPUT_SCANNER,
-	PCI_INPUT_GAMEPORT,
-	PCI_INPUT_OTHER = 0x80
-} pci_input_subclasses;
-
-typedef enum {
-	PCI_DOCK_GENERIC,
-	PCI_DOCK_OTHER = 0x80
-} pci_dock_subclasses;
-
-typedef enum {
-	PCI_CPU_386,
-	PCI_CPU_486,
-	PCI_CPU_PENTIUM,
-	PCI_CPU_ALPHA = 0x10,
-	PCI_CPU_POWERPC = 0x20,
-	PCI_CPU_MIPS = 0x30,
-	PCI_CPU_COPROC = 0x40,
-	PCI_CPU_OTHER = 0x80
-} pci_cpu_subclasses;
-
-typedef enum {
-	PCI_SERIAL_IEEE1394,
-	PCI_SERIAL_ACCESS,
-	PCI_SERIAL_SSA,
-	PCI_SERIAL_USB,
-	PCI_SERIAL_FIBER,
-	PCI_SERIAL_SMBUS,
-	PCI_SERIAL_OTHER = 0x80
-} pci_serial_subclasses;
-
-typedef enum {
-	PCI_INTELLIGENT_I2O
-} pci_intelligent_subclasses;
-
-typedef enum {
-	PCI_SATELLITE_TV,
-	PCI_SATELLITE_AUDIO,
-	PCI_SATELLITE_VOICE,
-	PCI_SATELLITE_DATA,
-	PCI_SATELLITE_OTHER = 0x80
-} pci_satellite_subclasses;
-
-typedef enum {
-	PCI_CRYPT_NETWORK,
-	PCI_CRYPT_ENTERTAINMENT,
-	PCI_CRYPT_OTHER = 0x80
-} pci_crypt_subclasses;
-
-typedef enum {
-	PCI_DSP_DPIO,
-	PCI_DSP_OTHER = 0x80
-} pci_dsp_subclasses;
-
-typedef enum {
-	PCI_XOR_QDMA,
-	PCI_XOR_OTHER = 0x80
-} pci_xor_subclasses;
-
-/* Header types */
-#define	PCI_HEADER_MULTI	0x80
-#define	PCI_HEADER_MASK		0x7f
-typedef enum {
-	PCI_HEADER_NORMAL,
-	PCI_HEADER_BRIDGE,
-	PCI_HEADER_CARDBUS
-} pci_header_types;
-
-/* Overlay for a PCI-to-PCI bridge */
-
-#define	PPB_RSVDA_MAX		2
-#define	PPB_RSVDD_MAX		8
-
-typedef struct _ppb_config_regs {
-	u16 vendor;
-	u16 device;
-	u16 command;
-	u16 status;
-	u8 rev_id;
-	u8 prog_if;
-	u8 sub_class;
-	u8 base_class;
-	u8 cache_line_size;
-	u8 latency_timer;
-	u8 header_type;
-	u8 bist;
-	u32 rsvd_a[PPB_RSVDA_MAX];
-	u8 prim_bus;
-	u8 sec_bus;
-	u8 sub_bus;
-	u8 sec_lat;
-	u8 io_base;
-	u8 io_lim;
-	u16 sec_status;
-	u16 mem_base;
-	u16 mem_lim;
-	u16 pf_mem_base;
-	u16 pf_mem_lim;
-	u32 pf_mem_base_hi;
-	u32 pf_mem_lim_hi;
-	u16 io_base_hi;
-	u16 io_lim_hi;
-	u16 subsys_vendor;
-	u16 subsys_id;
-	u32 rsvd_b;
-	u8 rsvd_c;
-	u8 int_pin;
-	u16 bridge_ctrl;
-	u8 chip_ctrl;
-	u8 diag_ctrl;
-	u16 arb_ctrl;
-	u32 rsvd_d[PPB_RSVDD_MAX];
-	u8 dev_dep[192];
-} ppb_config_regs;
-
-/* PCI CAPABILITY DEFINES */
-#define PCI_CAP_POWERMGMTCAP_ID		0x01
-#define PCI_CAP_MSICAP_ID		0x05
-#define PCI_CAP_VENDSPEC_ID		0x09
-#define PCI_CAP_PCIECAP_ID		0x10
-
-/* Data structure to define the Message Signalled Interrupt facility
- * Valid for PCI and PCIE configurations
- */
-typedef struct _pciconfig_cap_msi {
-	u8 capID;
-	u8 nextptr;
-	u16 msgctrl;
-	u32 msgaddr;
-} pciconfig_cap_msi;
-
-/* Data structure to define the Power management facility
- * Valid for PCI and PCIE configurations
- */
-typedef struct _pciconfig_cap_pwrmgmt {
-	u8 capID;
-	u8 nextptr;
-	u16 pme_cap;
-	u16 pme_sts_ctrl;
-	u8 pme_bridge_ext;
-	u8 data;
-} pciconfig_cap_pwrmgmt;
-
-#define PME_CAP_PM_STATES (0x1f << 27)	/* Bits 31:27 states that can generate PME */
-#define PME_CSR_OFFSET	    0x4	/* 4-bytes offset */
-#define PME_CSR_PME_EN	  (1 << 8)	/* Bit 8 Enable generating of PME */
-#define PME_CSR_PME_STAT  (1 << 15)	/* Bit 15 PME got asserted */
-
-/* Data structure to define the PCIE capability */
-typedef struct _pciconfig_cap_pcie {
-	u8 capID;
-	u8 nextptr;
-	u16 pcie_cap;
-	u32 dev_cap;
-	u16 dev_ctrl;
-	u16 dev_status;
-	u32 link_cap;
-	u16 link_ctrl;
-	u16 link_status;
-	u32 slot_cap;
-	u16 slot_ctrl;
-	u16 slot_status;
-	u16 root_ctrl;
-	u16 root_cap;
-	u32 root_status;
-} pciconfig_cap_pcie;
-
-/* PCIE Enhanced CAPABILITY DEFINES */
-#define PCIE_EXTCFG_OFFSET	0x100
-#define PCIE_ADVERRREP_CAPID	0x0001
-#define PCIE_VC_CAPID		0x0002
-#define PCIE_DEVSNUM_CAPID	0x0003
-#define PCIE_PWRBUDGET_CAPID	0x0004
-
-/* PCIE Extended configuration */
-#define PCIE_ADV_CORR_ERR_MASK	0x114
-#define CORR_ERR_RE	(1 << 0)	/* Receiver  */
-#define CORR_ERR_BT 	(1 << 6)	/* Bad TLP  */
-#define CORR_ERR_BD	(1 << 7)	/* Bad DLLP */
-#define CORR_ERR_RR	(1 << 8)	/* REPLAY_NUM rollover */
-#define CORR_ERR_RT	(1 << 12)	/* Reply timer timeout */
-#define ALL_CORR_ERRORS (CORR_ERR_RE | CORR_ERR_BT | CORR_ERR_BD | \
-			 CORR_ERR_RR | CORR_ERR_RT)
-
-/* PCIE Root Control Register bits (Host mode only) */
-#define	PCIE_RC_CORR_SERR_EN		0x0001
-#define	PCIE_RC_NONFATAL_SERR_EN	0x0002
-#define	PCIE_RC_FATAL_SERR_EN		0x0004
-#define	PCIE_RC_PME_INT_EN		0x0008
-#define	PCIE_RC_CRS_EN			0x0010
-
-/* PCIE Root Capability Register bits (Host mode only) */
-#define	PCIE_RC_CRS_VISIBILITY		0x0001
+#include <linux/pci_regs.h>
 
-/* Header to define the PCIE specific capabilities in the extended config space */
-typedef struct _pcie_enhanced_caphdr {
-	u16 capID;
-	u16 cap_ver:4;
-	u16 next_ptr:12;
-} pcie_enhanced_caphdr;
+/* PCI configuration address space size */
+#define PCI_SZPCR		256
 
 /* Everything below is BRCM HND proprietary */
 
 /* Brcm PCI configuration registers */
-#define cap_list	rsvd_a[0]
-#define bar0_window	dev_dep[0x80 - 0x40]
-#define bar1_window	dev_dep[0x84 - 0x40]
-#define sprom_control	dev_dep[0x88 - 0x40]
-#define	PCI_BAR0_WIN		0x80	/* backplane address space accessed by BAR0 */
-#define	PCI_BAR1_WIN		0x84	/* backplane address space accessed by BAR1 */
-#define	PCI_SPROM_CONTROL	0x88	/* sprom property control */
-#define	PCI_BAR1_CONTROL	0x8c	/* BAR1 region burst control */
-#define	PCI_INT_STATUS		0x90	/* PCI and other cores interrupts */
-#define	PCI_INT_MASK		0x94	/* mask of PCI and other cores interrupts */
-#define PCI_TO_SB_MB		0x98	/* signal backplane interrupts */
-#define PCI_BACKPLANE_ADDR	0xa0	/* address an arbitrary location on the system backplane */
-#define PCI_BACKPLANE_DATA	0xa4	/* data at the location specified by above address */
-#define	PCI_CLK_CTL_ST		0xa8	/* pci config space clock control/status (>=rev14) */
-#define	PCI_BAR0_WIN2		0xac	/* backplane address space accessed by second 4KB of BAR0 */
-#define	PCI_GPIO_IN		0xb0	/* pci config space gpio input (>=rev3) */
-#define	PCI_GPIO_OUT		0xb4	/* pci config space gpio output (>=rev3) */
-#define	PCI_GPIO_OUTEN		0xb8	/* pci config space gpio output enable (>=rev3) */
+#define PCI_BAR0_WIN		0x80	/* backplane address space accessed by BAR0 */
+#define PCI_SPROM_CONTROL	0x88	/* sprom property control */
+#define PCI_INT_MASK		0x94	/* mask of PCI and other cores interrupts */
+#define  PCI_SBIM_SHIFT		8	/* backplane core interrupt mask bits offset */
+#define PCI_BAR0_WIN2		0xac	/* backplane address space accessed by second 4KB of BAR0 */
+#define PCI_GPIO_IN		0xb0	/* pci config space gpio input (>=rev3) */
+#define PCI_GPIO_OUT		0xb4	/* pci config space gpio output (>=rev3) */
+#define PCI_GPIO_OUTEN		0xb8	/* pci config space gpio output enable (>=rev3) */
 
-#define	PCI_BAR0_SHADOW_OFFSET	(2 * 1024)	/* bar0 + 2K accesses sprom shadow (in pci core) */
-#define	PCI_BAR0_SPROM_OFFSET	(4 * 1024)	/* bar0 + 4K accesses external sprom */
-#define	PCI_BAR0_PCIREGS_OFFSET	(6 * 1024)	/* bar0 + 6K accesses pci core registers */
-#define	PCI_BAR0_PCISBR_OFFSET	(4 * 1024)	/* pci core SB registers are at the end of the
+#define PCI_BAR0_SPROM_OFFSET	(4 * 1024)	/* bar0 + 4K accesses external sprom */
+#define PCI_BAR0_PCIREGS_OFFSET	(6 * 1024)	/* bar0 + 6K accesses pci core registers */
+#define PCI_BAR0_PCISBR_OFFSET	(4 * 1024)	/* pci core SB registers are at the end of the
 						 * 8KB window, so their address is the "regular"
 						 * address plus 4K
 						 */
 #define PCI_BAR0_WINSZ		(16 * 1024)	/* bar0 window size Match with corerev 13 */
 /* On pci corerev >= 13 and all pcie, the bar0 is now 16KB and it maps: */
-#define	PCI_16KB0_PCIREGS_OFFSET (8 * 1024)	/* bar0 + 8K accesses pci/pcie core registers */
-#define	PCI_16KB0_CCREGS_OFFSET	(12 * 1024)	/* bar0 + 12K accesses chipc core registers */
-#define PCI_16KBB0_WINSZ	(16 * 1024)	/* bar0 window size */
-
-/* On AI chips we have a second window to map DMP regs are mapped: */
-#define	PCI_16KB0_WIN2_OFFSET	(4 * 1024)	/* bar0 + 4K is "Window 2" */
-
-/* PCI_INT_STATUS */
-#define	PCI_SBIM_STATUS_SERR	0x4	/* backplane SBErr interrupt status */
-
-/* PCI_INT_MASK */
-#define	PCI_SBIM_SHIFT		8	/* backplane core interrupt mask bits offset */
-#define	PCI_SBIM_MASK		0xff00	/* backplane core interrupt mask */
-#define	PCI_SBIM_MASK_SERR	0x4	/* backplane SBErr interrupt mask */
+#define PCI_16KB0_PCIREGS_OFFSET (8 * 1024)	/* bar0 + 8K accesses pci/pcie core registers */
+#define PCI_16KB0_CCREGS_OFFSET	(12 * 1024)	/* bar0 + 12K accesses chipc core registers */
 
-/* PCI_SPROM_CONTROL */
-#define SPROM_SZ_MSK		0x02	/* SPROM Size Mask */
-#define SPROM_LOCKED		0x08	/* SPROM Locked */
-#define	SPROM_BLANK		0x04	/* indicating a blank SPROM */
-#define SPROM_WRITEEN		0x10	/* SPROM write enable */
-#define SPROM_BOOTROM_WE	0x20	/* external bootrom write enable */
-#define SPROM_BACKPLANE_EN	0x40	/* Enable indirect backplane access */
-#define SPROM_OTPIN_USE		0x80	/* device OTP In use */
+#define PCI_SBIM_STATUS_SERR	0x4	/* backplane SBErr interrupt status */
 
-/* Bits in PCI command and status regs */
-#define PCI_CMD_IO		0x00000001	/* I/O enable */
-#define PCI_CMD_MEMORY		0x00000002	/* Memory enable */
-#define PCI_CMD_MASTER		0x00000004	/* Master enable */
-#define PCI_CMD_SPECIAL		0x00000008	/* Special cycles enable */
-#define PCI_CMD_INVALIDATE	0x00000010	/* Invalidate? */
-#define PCI_CMD_VGA_PAL		0x00000040	/* VGA Palate */
-#define PCI_STAT_TA		0x08000000	/* target abort status */
 #endif				/* _h_pcicfg_ */
diff -druN linux-2.6.39-libre/drivers/staging/brcm80211/include/pci_core.h linux-3.0-rc7-libre/drivers/staging/brcm80211/include/pci_core.h
--- linux-2.6.39-libre/drivers/staging/brcm80211/include/pci_core.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/staging/brcm80211/include/pci_core.h	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,122 @@
+/*
+ * Copyright (c) 2010 Broadcom Corporation
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef	_PCI_CORE_H_
+#define	_PCI_CORE_H_
+
+#ifndef _LANGUAGE_ASSEMBLY
+
+/* cpp contortions to concatenate w/arg prescan */
+#ifndef PAD
+#define	_PADLINE(line)	pad ## line
+#define	_XSTR(line)	_PADLINE(line)
+#define	PAD		_XSTR(__LINE__)
+#endif
+
+/* Sonics side: PCI core and host control registers */
+struct sbpciregs {
+	u32 control;		/* PCI control */
+	u32 PAD[3];
+	u32 arbcontrol;	/* PCI arbiter control */
+	u32 clkrun;		/* Clkrun Control (>=rev11) */
+	u32 PAD[2];
+	u32 intstatus;	/* Interrupt status */
+	u32 intmask;		/* Interrupt mask */
+	u32 sbtopcimailbox;	/* Sonics to PCI mailbox */
+	u32 PAD[9];
+	u32 bcastaddr;	/* Sonics broadcast address */
+	u32 bcastdata;	/* Sonics broadcast data */
+	u32 PAD[2];
+	u32 gpioin;		/* ro: gpio input (>=rev2) */
+	u32 gpioout;		/* rw: gpio output (>=rev2) */
+	u32 gpioouten;	/* rw: gpio output enable (>= rev2) */
+	u32 gpiocontrol;	/* rw: gpio control (>= rev2) */
+	u32 PAD[36];
+	u32 sbtopci0;	/* Sonics to PCI translation 0 */
+	u32 sbtopci1;	/* Sonics to PCI translation 1 */
+	u32 sbtopci2;	/* Sonics to PCI translation 2 */
+	u32 PAD[189];
+	u32 pcicfg[4][64];	/* 0x400 - 0x7FF, PCI Cfg Space (>=rev8) */
+	u16 sprom[36];	/* SPROM shadow Area */
+	u32 PAD[46];
+};
+
+#endif				/* _LANGUAGE_ASSEMBLY */
+
+/* PCI control */
+#define PCI_RST_OE	0x01	/* When set, drives PCI_RESET out to pin */
+#define PCI_RST		0x02	/* Value driven out to pin */
+#define PCI_CLK_OE	0x04	/* When set, drives clock as gated by PCI_CLK out to pin */
+#define PCI_CLK		0x08	/* Gate for clock driven out to pin */
+
+/* PCI arbiter control */
+#define PCI_INT_ARB	0x01	/* When set, use an internal arbiter */
+#define PCI_EXT_ARB	0x02	/* When set, use an external arbiter */
+/* ParkID - for PCI corerev >= 8 */
+#define PCI_PARKID_MASK		0x1c	/* Selects which agent is parked on an idle bus */
+#define PCI_PARKID_SHIFT	2
+#define PCI_PARKID_EXT0		0	/* External master 0 */
+#define PCI_PARKID_EXT1		1	/* External master 1 */
+#define PCI_PARKID_EXT2		2	/* External master 2 */
+#define PCI_PARKID_EXT3		3	/* External master 3 (rev >= 11) */
+#define PCI_PARKID_INT		3	/* Internal master (rev < 11) */
+#define PCI11_PARKID_INT	4	/* Internal master (rev >= 11) */
+#define PCI_PARKID_LAST		4	/* Last active master (rev < 11) */
+#define PCI11_PARKID_LAST	5	/* Last active master (rev >= 11) */
+
+#define PCI_CLKRUN_DSBL	0x8000	/* Bit 15 forceClkrun */
+
+/* Interrupt status/mask */
+#define PCI_INTA	0x01	/* PCI INTA# is asserted */
+#define PCI_INTB	0x02	/* PCI INTB# is asserted */
+#define PCI_SERR	0x04	/* PCI SERR# has been asserted (write one to clear) */
+#define PCI_PERR	0x08	/* PCI PERR# has been asserted (write one to clear) */
+#define PCI_PME		0x10	/* PCI PME# is asserted */
+
+/* (General) PCI/SB mailbox interrupts, two bits per pci function */
+#define	MAILBOX_F0_0	0x100	/* function 0, int 0 */
+#define	MAILBOX_F0_1	0x200	/* function 0, int 1 */
+#define	MAILBOX_F1_0	0x400	/* function 1, int 0 */
+#define	MAILBOX_F1_1	0x800	/* function 1, int 1 */
+#define	MAILBOX_F2_0	0x1000	/* function 2, int 0 */
+#define	MAILBOX_F2_1	0x2000	/* function 2, int 1 */
+#define	MAILBOX_F3_0	0x4000	/* function 3, int 0 */
+#define	MAILBOX_F3_1	0x8000	/* function 3, int 1 */
+
+/* Sonics broadcast address */
+#define BCAST_ADDR_MASK	0xff	/* Broadcast register address */
+
+/* Sonics to PCI translation types */
+#define SBTOPCI0_MASK	0xfc000000
+#define SBTOPCI1_MASK	0xfc000000
+#define SBTOPCI2_MASK	0xc0000000
+#define SBTOPCI_MEM	0
+#define SBTOPCI_IO	1
+#define SBTOPCI_CFG0	2
+#define SBTOPCI_CFG1	3
+#define	SBTOPCI_PREF	0x4	/* prefetch enable */
+#define	SBTOPCI_BURST	0x8	/* burst enable */
+#define	SBTOPCI_RC_MASK		0x30	/* read command (>= rev11) */
+#define	SBTOPCI_RC_READ		0x00	/* memory read */
+#define	SBTOPCI_RC_READLINE	0x10	/* memory read line */
+#define	SBTOPCI_RC_READMULTI	0x20	/* memory read multiple */
+
+/* PCI core index in SROM shadow area */
+#define SRSH_PI_OFFSET	0	/* first word */
+#define SRSH_PI_MASK	0xf000	/* bit 15:12 */
+#define SRSH_PI_SHIFT	12	/* bit 15:12 */
+
+#endif				/* _PCI_CORE_H_ */
diff -druN linux-2.6.39-libre/drivers/staging/brcm80211/include/qmath.h linux-3.0-rc7-libre/drivers/staging/brcm80211/include/qmath.h
--- linux-2.6.39-libre/drivers/staging/brcm80211/include/qmath.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/brcm80211/include/qmath.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,78 +0,0 @@
-/*
- * Copyright (c) 2010 Broadcom Corporation
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#ifndef __QMATH_H__
-#define __QMATH_H__
-
-s16 qm_sat32(s32 op);
-
-s32 qm_mul321616(s16 op1, s16 op2);
-
-s16 qm_mul16(s16 op1, s16 op2);
-
-s32 qm_muls321616(s16 op1, s16 op2);
-
-u16 qm_mulu16(u16 op1, u16 op2);
-
-s16 qm_muls16(s16 op1, s16 op2);
-
-s32 qm_add32(s32 op1, s32 op2);
-
-s16 qm_add16(s16 op1, s16 op2);
-
-s16 qm_sub16(s16 op1, s16 op2);
-
-s32 qm_sub32(s32 op1, s32 op2);
-
-s32 qm_mac321616(s32 acc, s16 op1, s16 op2);
-
-s32 qm_shl32(s32 op, int shift);
-
-s32 qm_shr32(s32 op, int shift);
-
-s16 qm_shl16(s16 op, int shift);
-
-s16 qm_shr16(s16 op, int shift);
-
-s16 qm_norm16(s16 op);
-
-s16 qm_norm32(s32 op);
-
-s16 qm_div_s(s16 num, s16 denom);
-
-s16 qm_abs16(s16 op);
-
-s16 qm_div16(s16 num, s16 denom, s16 *qQuotient);
-
-s32 qm_abs32(s32 op);
-
-s16 qm_div163232(s32 num, s32 denom, s16 *qquotient);
-
-s32 qm_mul323216(s32 op1, s16 op2);
-
-s32 qm_mulsu321616(s16 op1, u16 op2);
-
-s32 qm_muls323216(s32 op1, s16 op2);
-
-s32 qm_mul32(s32 a, s32 b);
-
-s32 qm_muls32(s32 a, s32 b);
-
-void qm_log10(s32 N, s16 qN, s16 *log10N, s16 *qLog10N);
-
-void qm_1byN(s32 N, s16 qN, s32 *result, s16 *qResult);
-
-#endif				/* #ifndef __QMATH_H__ */
diff -druN linux-2.6.39-libre/drivers/staging/brcm80211/include/sbchipc.h linux-3.0-rc7-libre/drivers/staging/brcm80211/include/sbchipc.h
--- linux-2.6.39-libre/drivers/staging/brcm80211/include/sbchipc.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/brcm80211/include/sbchipc.h	2011-07-11 19:51:52.000000000 -0400
@@ -225,7 +225,7 @@
 
 #endif				/* _LANGUAGE_ASSEMBLY */
 
-#if	defined(IL_BIGENDIAN) && defined(BCMHND74K)
+#if	defined(__BIG_ENDIAN) && defined(BCMHND74K)
 /* Selective swapped defines for those registers we need in
  * big-endian code.
  */
@@ -234,14 +234,14 @@
 #define	CC_CHIPST		0x28
 #define	CC_EROMPTR		0xf8
 
-#else				/* !IL_BIGENDIAN || !BCMHND74K */
+#else				/* !__BIG_ENDIAN || !BCMHND74K */
 
 #define	CC_CHIPID		0
 #define	CC_CAPABILITIES		4
 #define	CC_CHIPST		0x2c
 #define	CC_EROMPTR		0xfc
 
-#endif				/* IL_BIGENDIAN && BCMHND74K */
+#endif				/* __BIG_ENDIAN && BCMHND74K */
 
 #define CC_OTPST		0x10
 #define	CC_JTAGCMD		0x30
diff -druN linux-2.6.39-libre/drivers/staging/brcm80211/include/siutils.h linux-3.0-rc7-libre/drivers/staging/brcm80211/include/siutils.h
--- linux-2.6.39-libre/drivers/staging/brcm80211/include/siutils.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/brcm80211/include/siutils.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,361 +0,0 @@
-/*
- * Copyright (c) 2010 Broadcom Corporation
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#ifndef	_siutils_h_
-#define	_siutils_h_
-
-#include <hndsoc.h>
-
-/*
- * Data structure to export all chip specific common variables
- *   public (read-only) portion of siutils handle returned by si_attach()
- */
-struct si_pub {
-	uint socitype;		/* SOCI_SB, SOCI_AI */
-
-	uint bustype;		/* SI_BUS, PCI_BUS */
-	uint buscoretype;	/* PCI_CORE_ID, PCIE_CORE_ID, PCMCIA_CORE_ID */
-	uint buscorerev;	/* buscore rev */
-	uint buscoreidx;	/* buscore index */
-	int ccrev;		/* chip common core rev */
-	u32 cccaps;		/* chip common capabilities */
-	u32 cccaps_ext;	/* chip common capabilities extension */
-	int pmurev;		/* pmu core rev */
-	u32 pmucaps;		/* pmu capabilities */
-	uint boardtype;		/* board type */
-	uint boardvendor;	/* board vendor */
-	uint boardflags;	/* board flags */
-	uint boardflags2;	/* board flags2 */
-	uint chip;		/* chip number */
-	uint chiprev;		/* chip revision */
-	uint chippkg;		/* chip package option */
-	u32 chipst;		/* chip status */
-	bool issim;		/* chip is in simulation or emulation */
-	uint socirev;		/* SOC interconnect rev */
-	bool pci_pr32414;
-
-};
-
-/* for HIGH_ONLY driver, the si_t must be writable to allow states sync from BMAC to HIGH driver
- * for monolithic driver, it is readonly to prevent accident change
- */
-typedef const struct si_pub si_t;
-
-/*
- * Many of the routines below take an 'sih' handle as their first arg.
- * Allocate this by calling si_attach().  Free it by calling si_detach().
- * At any one time, the sih is logically focused on one particular si core
- * (the "current core").
- * Use si_setcore() or si_setcoreidx() to change the association to another core.
- */
-
-#define	BADIDX		(SI_MAXCORES + 1)
-
-/* clkctl xtal what flags */
-#define	XTAL			0x1	/* primary crystal oscillator (2050) */
-#define	PLL			0x2	/* main chip pll */
-
-/* clkctl clk mode */
-#define	CLK_FAST		0	/* force fast (pll) clock */
-#define	CLK_DYNAMIC		2	/* enable dynamic clock control */
-
-/* GPIO usage priorities */
-#define GPIO_DRV_PRIORITY	0	/* Driver */
-#define GPIO_APP_PRIORITY	1	/* Application */
-#define GPIO_HI_PRIORITY	2	/* Highest priority. Ignore GPIO reservation */
-
-/* GPIO pull up/down */
-#define GPIO_PULLUP		0
-#define GPIO_PULLDN		1
-
-/* GPIO event regtype */
-#define GPIO_REGEVT		0	/* GPIO register event */
-#define GPIO_REGEVT_INTMSK	1	/* GPIO register event int mask */
-#define GPIO_REGEVT_INTPOL	2	/* GPIO register event int polarity */
-
-/* device path */
-#define SI_DEVPATH_BUFSZ	16	/* min buffer size in bytes */
-
-/* SI routine enumeration: to be used by update function with multiple hooks */
-#define	SI_DOATTACH	1
-#define SI_PCIDOWN	2
-#define SI_PCIUP	3
-
-#define	ISSIM_ENAB(sih)	0
-
-/* PMU clock/power control */
-#if defined(BCMPMUCTL)
-#define PMUCTL_ENAB(sih)	(BCMPMUCTL)
-#else
-#define PMUCTL_ENAB(sih)	((sih)->cccaps & CC_CAP_PMU)
-#endif
-
-/* chipcommon clock/power control (exclusive with PMU's) */
-#if defined(BCMPMUCTL) && BCMPMUCTL
-#define CCCTL_ENAB(sih)		(0)
-#define CCPLL_ENAB(sih)		(0)
-#else
-#define CCCTL_ENAB(sih)		((sih)->cccaps & CC_CAP_PWR_CTL)
-#define CCPLL_ENAB(sih)		((sih)->cccaps & CC_CAP_PLL_MASK)
-#endif
-
-typedef void (*gpio_handler_t) (u32 stat, void *arg);
-
-/* External PA enable mask */
-#define GPIO_CTRL_EPA_EN_MASK 0x40
-
-/* === exported functions === */
-extern si_t *si_attach(uint pcidev, void *regs, uint bustype,
-		       void *sdh, char **vars, uint *varsz);
-
-extern void si_detach(si_t *sih);
-extern bool si_pci_war16165(si_t *sih);
-
-extern uint si_coreid(si_t *sih);
-extern uint si_flag(si_t *sih);
-extern uint si_coreidx(si_t *sih);
-extern uint si_corerev(si_t *sih);
-extern uint si_corereg(si_t *sih, uint coreidx, uint regoff, uint mask,
-		uint val);
-extern void si_write_wrapperreg(si_t *sih, u32 offset, u32 val);
-extern u32 si_core_cflags(si_t *sih, u32 mask, u32 val);
-extern u32 si_core_sflags(si_t *sih, u32 mask, u32 val);
-extern bool si_iscoreup(si_t *sih);
-extern uint si_findcoreidx(si_t *sih, uint coreid, uint coreunit);
-#ifndef BCMSDIO
-extern void *si_setcoreidx(si_t *sih, uint coreidx);
-#endif
-extern void *si_setcore(si_t *sih, uint coreid, uint coreunit);
-extern void *si_switch_core(si_t *sih, uint coreid, uint *origidx,
-			    uint *intr_val);
-extern void si_restore_core(si_t *sih, uint coreid, uint intr_val);
-extern void si_core_reset(si_t *sih, u32 bits, u32 resetbits);
-extern void si_core_disable(si_t *sih, u32 bits);
-extern u32 si_alp_clock(si_t *sih);
-extern u32 si_ilp_clock(si_t *sih);
-extern void si_pci_setup(si_t *sih, uint coremask);
-extern void si_setint(si_t *sih, int siflag);
-extern bool si_backplane64(si_t *sih);
-extern void si_register_intr_callback(si_t *sih, void *intrsoff_fn,
-				      void *intrsrestore_fn,
-				      void *intrsenabled_fn, void *intr_arg);
-extern void si_deregister_intr_callback(si_t *sih);
-extern void si_clkctl_init(si_t *sih);
-extern u16 si_clkctl_fast_pwrup_delay(si_t *sih);
-extern bool si_clkctl_cc(si_t *sih, uint mode);
-extern int si_clkctl_xtal(si_t *sih, uint what, bool on);
-extern bool si_deviceremoved(si_t *sih);
-extern u32 si_socram_size(si_t *sih);
-
-extern void si_watchdog(si_t *sih, uint ticks);
-extern u32 si_gpiocontrol(si_t *sih, u32 mask, u32 val,
-			     u8 priority);
-
-#ifdef BCMSDIO
-extern void si_sdio_init(si_t *sih);
-#endif
-
-#define si_eci(sih) 0
-#define si_eci_init(sih) (0)
-#define si_eci_notify_bt(sih, type, val)  (0)
-#define si_seci(sih) 0
-
-/* OTP status */
-extern bool si_is_otp_disabled(si_t *sih);
-extern bool si_is_otp_powered(si_t *sih);
-extern void si_otp_power(si_t *sih, bool on);
-
-/* SPROM availability */
-extern bool si_is_sprom_available(si_t *sih);
-#ifdef SI_SPROM_PROBE
-extern void si_sprom_init(si_t *sih);
-#endif				/* SI_SPROM_PROBE */
-
-#define	SI_ERROR(args)
-
-#ifdef BCMDBG
-#define	SI_MSG(args)	printk args
-#else
-#define	SI_MSG(args)
-#endif				/* BCMDBG */
-
-/* Define SI_VMSG to printf for verbose debugging, but don't check it in */
-#define	SI_VMSG(args)
-
-#define	IS_SIM(chippkg)	((chippkg == HDLSIM_PKG_ID) || (chippkg == HWSIM_PKG_ID))
-
-typedef u32(*si_intrsoff_t) (void *intr_arg);
-typedef void (*si_intrsrestore_t) (void *intr_arg, u32 arg);
-typedef bool(*si_intrsenabled_t) (void *intr_arg);
-
-typedef struct gpioh_item {
-	void *arg;
-	bool level;
-	gpio_handler_t handler;
-	u32 event;
-	struct gpioh_item *next;
-} gpioh_item_t;
-
-/* misc si info needed by some of the routines */
-typedef struct si_info {
-	struct si_pub pub;	/* back plane public state (must be first) */
-	void *pbus;		/* handle to bus (pci/sdio/..) */
-	uint dev_coreid;	/* the core provides driver functions */
-	void *intr_arg;		/* interrupt callback function arg */
-	si_intrsoff_t intrsoff_fn;	/* turns chip interrupts off */
-	si_intrsrestore_t intrsrestore_fn;	/* restore chip interrupts */
-	si_intrsenabled_t intrsenabled_fn;	/* check if interrupts are enabled */
-
-	void *pch;		/* PCI/E core handle */
-
-	gpioh_item_t *gpioh_head;	/* GPIO event handlers list */
-
-	bool memseg;		/* flag to toggle MEM_SEG register */
-
-	char *vars;
-	uint varsz;
-
-	void *curmap;		/* current regs va */
-	void *regs[SI_MAXCORES];	/* other regs va */
-
-	uint curidx;		/* current core index */
-	uint numcores;		/* # discovered cores */
-	uint coreid[SI_MAXCORES];	/* id of each core */
-	u32 coresba[SI_MAXCORES];	/* backplane address of each core */
-	void *regs2[SI_MAXCORES];	/* va of each core second register set (usbh20) */
-	u32 coresba2[SI_MAXCORES];	/* address of each core second register set (usbh20) */
-	u32 coresba_size[SI_MAXCORES];	/* backplane address space size */
-	u32 coresba2_size[SI_MAXCORES];	/* second address space size */
-
-	void *curwrap;		/* current wrapper va */
-	void *wrappers[SI_MAXCORES];	/* other cores wrapper va */
-	u32 wrapba[SI_MAXCORES];	/* address of controlling wrapper */
-
-	u32 cia[SI_MAXCORES];	/* erom cia entry for each core */
-	u32 cib[SI_MAXCORES];	/* erom cia entry for each core */
-	u32 oob_router;	/* oob router registers for axi */
-} si_info_t;
-
-#define	SI_INFO(sih)	((si_info_t *)(sih))
-
-#define	GOODCOREADDR(x, b) (((x) >= (b)) && ((x) < ((b) + SI_MAXCORES * SI_CORE_SIZE)) && \
-		IS_ALIGNED((x), SI_CORE_SIZE))
-#define	GOODREGS(regs)	((regs) != NULL && IS_ALIGNED((unsigned long)(regs), SI_CORE_SIZE))
-#define BADCOREADDR	0
-#define	GOODIDX(idx)	(((uint)idx) < SI_MAXCORES)
-#define	NOREV		-1	/* Invalid rev */
-
-/* Newer chips can access PCI/PCIE and CC core without requiring to change
- * PCI BAR0 WIN
- */
-#define SI_FAST(si) (((si)->pub.buscoretype == PCIE_CORE_ID) ||	\
-		     (((si)->pub.buscoretype == PCI_CORE_ID) && (si)->pub.buscorerev >= 13))
-
-#define PCIEREGS(si) (((char *)((si)->curmap) + PCI_16KB0_PCIREGS_OFFSET))
-#define CCREGS_FAST(si) (((char *)((si)->curmap) + PCI_16KB0_CCREGS_OFFSET))
-
-/*
- * Macros to disable/restore function core(D11, ENET, ILINE20, etc) interrupts
- * before after core switching to avoid invalid register access inside ISR.
- */
-#define INTR_OFF(si, intr_val) \
-	if ((si)->intrsoff_fn && (si)->coreid[(si)->curidx] == (si)->dev_coreid) {	\
-		intr_val = (*(si)->intrsoff_fn)((si)->intr_arg); }
-#define INTR_RESTORE(si, intr_val) \
-	if ((si)->intrsrestore_fn && (si)->coreid[(si)->curidx] == (si)->dev_coreid) {	\
-		(*(si)->intrsrestore_fn)((si)->intr_arg, intr_val); }
-
-/* dynamic clock control defines */
-#define	LPOMINFREQ		25000	/* low power oscillator min */
-#define	LPOMAXFREQ		43000	/* low power oscillator max */
-#define	XTALMINFREQ		19800000	/* 20 MHz - 1% */
-#define	XTALMAXFREQ		20200000	/* 20 MHz + 1% */
-#define	PCIMINFREQ		25000000	/* 25 MHz */
-#define	PCIMAXFREQ		34000000	/* 33 MHz + fudge */
-
-#define	ILP_DIV_5MHZ		0	/* ILP = 5 MHz */
-#define	ILP_DIV_1MHZ		4	/* ILP = 1 MHz */
-
-#define PCI(si)		(((si)->pub.bustype == PCI_BUS) &&	\
-			 ((si)->pub.buscoretype == PCI_CORE_ID))
-#define PCIE(si)	(((si)->pub.bustype == PCI_BUS) &&	\
-			 ((si)->pub.buscoretype == PCIE_CORE_ID))
-#define PCI_FORCEHT(si)	\
-	(PCIE(si) && (si->pub.chip == BCM4716_CHIP_ID))
-
-/* GPIO Based LED powersave defines */
-#define DEFAULT_GPIO_ONTIME	10	/* Default: 10% on */
-#define DEFAULT_GPIO_OFFTIME	90	/* Default: 10% on */
-
-#ifndef DEFAULT_GPIOTIMERVAL
-#define DEFAULT_GPIOTIMERVAL  ((DEFAULT_GPIO_ONTIME << GPIO_ONTIME_SHIFT) | DEFAULT_GPIO_OFFTIME)
-#endif
-
-/*
- * Build device path. Path size must be >= SI_DEVPATH_BUFSZ.
- * The returned path is NULL terminated and has trailing '/'.
- * Return 0 on success, nonzero otherwise.
- */
-extern int si_devpath(si_t *sih, char *path, int size);
-/* Read variable with prepending the devpath to the name */
-extern char *si_getdevpathvar(si_t *sih, const char *name);
-extern int si_getdevpathintvar(si_t *sih, const char *name);
-
-extern void si_war42780_clkreq(si_t *sih, bool clkreq);
-extern void si_pci_sleep(si_t *sih);
-extern void si_pci_down(si_t *sih);
-extern void si_pci_up(si_t *sih);
-extern void si_pcie_extendL1timer(si_t *sih, bool extend);
-extern int si_pci_fixcfg(si_t *sih);
-
-extern void si_chipcontrl_epa4331(si_t *sih, bool on);
-/* Enable Ex-PA for 4313 */
-extern void si_epa_4313war(si_t *sih);
-
-char *si_getnvramflvar(si_t *sih, const char *name);
-
-/* AMBA Interconnect exported externs */
-extern si_t *ai_attach(uint pcidev, void *regs, uint bustype,
-		       void *sdh, char **vars, uint *varsz);
-extern si_t *ai_kattach(void);
-extern void ai_scan(si_t *sih, void *regs, uint devid);
-
-extern uint ai_flag(si_t *sih);
-extern void ai_setint(si_t *sih, int siflag);
-extern uint ai_coreidx(si_t *sih);
-extern uint ai_corevendor(si_t *sih);
-extern uint ai_corerev(si_t *sih);
-extern bool ai_iscoreup(si_t *sih);
-extern void *ai_setcoreidx(si_t *sih, uint coreidx);
-extern u32 ai_core_cflags(si_t *sih, u32 mask, u32 val);
-extern void ai_core_cflags_wo(si_t *sih, u32 mask, u32 val);
-extern u32 ai_core_sflags(si_t *sih, u32 mask, u32 val);
-extern uint ai_corereg(si_t *sih, uint coreidx, uint regoff, uint mask,
-		       uint val);
-extern void ai_core_reset(si_t *sih, u32 bits, u32 resetbits);
-extern void ai_core_disable(si_t *sih, u32 bits);
-extern int ai_numaddrspaces(si_t *sih);
-extern u32 ai_addrspace(si_t *sih, uint asidx);
-extern u32 ai_addrspacesize(si_t *sih, uint asidx);
-extern void ai_write_wrap_reg(si_t *sih, u32 offset, u32 val);
-
-#ifdef BCMSDIO
-#define si_setcoreidx(sih, idx) sb_setcoreidx(sih, idx)
-#define si_coreid(sih) sb_coreid(sih)
-#define si_corerev(sih) sb_corerev(sih)
-#endif
-
-#endif				/* _siutils_h_ */
diff -druN linux-2.6.39-libre/drivers/staging/brcm80211/include/wlioctl.h linux-3.0-rc7-libre/drivers/staging/brcm80211/include/wlioctl.h
--- linux-2.6.39-libre/drivers/staging/brcm80211/include/wlioctl.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/brcm80211/include/wlioctl.h	2011-07-11 19:51:52.000000000 -0400
@@ -259,6 +259,7 @@
 /* used for association with a specific BSSID and chanspec list */
 typedef struct wl_assoc_params {
 	u8 bssid[ETH_ALEN];	/* 00:00:00:00:00:00: broadcast scan */
+	u16 bssid_cnt;
 	s32 chanspec_num;	/* 0: all available channels,
 				 * otherwise count of chanspecs in chanspec_list
 				 */
@@ -585,15 +586,6 @@
 	u8 ea[1][ETH_ALEN];	/* variable length array of MAC addresses */
 };
 
-/* get pkt count struct passed through ioctl */
-typedef struct get_pktcnt {
-	uint rx_good_pkt;
-	uint rx_bad_pkt;
-	uint tx_good_pkt;
-	uint tx_bad_pkt;
-	uint rx_ocast_good_pkt;	/* unicast packets destined for others */
-} get_pktcnt_t;
-
 #ifdef BRCM_FULLMAC
 /* Linux network driver ioctl encoding */
 typedef struct wl_ioctl {
@@ -1247,8 +1239,6 @@
 /* Message levels */
 #define WL_ERROR_VAL		0x00000001
 #define WL_TRACE_VAL		0x00000002
-#define WL_AMPDU_VAL		0x20000000
-#define WL_FFPLD_VAL		0x40000000
 
 /* maximum channels returned by the get valid channels iovar */
 #define WL_NUMCHANNELS		64
@@ -1260,348 +1250,11 @@
 
 #define	NFIFO			6	/* # tx/rx fifopairs */
 
-#define	WL_CNT_T_VERSION	7	/* current version of wl_cnt_t struct */
-
-struct wl_cnt {
-	u16 version;		/* see definition of WL_CNT_T_VERSION */
-	u16 length;		/* length of entire structure */
-
-	/* transmit stat counters */
-	u32 txframe;		/* tx data frames */
-	u32 txbyte;		/* tx data bytes */
-	u32 txretrans;	/* tx mac retransmits */
-	u32 txerror;		/* tx data errors (derived: sum of others) */
-	u32 txctl;		/* tx management frames */
-	u32 txprshort;	/* tx short preamble frames */
-	u32 txserr;		/* tx status errors */
-	u32 txnobuf;		/* tx out of buffers errors */
-	u32 txnoassoc;	/* tx discard because we're not associated */
-	u32 txrunt;		/* tx runt frames */
-	u32 txchit;		/* tx header cache hit (fastpath) */
-	u32 txcmiss;		/* tx header cache miss (slowpath) */
-	u32 ieee_tx_status;	/* calls to ieee80211_tx_status */
-	u32 ieee_tx;		/* tx calls frm mac0211 */
-	u32 ieee_rx;		/* calls to ieee_rx */
-
-	/* transmit chip error counters */
-	u32 txuflo;		/* tx fifo underflows */
-	u32 txphyerr;	/* tx phy errors (indicated in tx status) */
-	u32 txphycrs;
-
-	/* receive stat counters */
-	u32 rxframe;		/* rx data frames */
-	u32 rxbyte;		/* rx data bytes */
-	u32 rxerror;		/* rx data errors (derived: sum of others) */
-	u32 rxctl;		/* rx management frames */
-	u32 rxnobuf;		/* rx out of buffers errors */
-	u32 rxnondata;	/* rx non data frames in the data channel errors */
-	u32 rxbadds;		/* rx bad DS errors */
-	u32 rxbadcm;		/* rx bad control or management frames */
-	u32 rxfragerr;	/* rx fragmentation errors */
-	u32 rxrunt;		/* rx runt frames */
-	u32 rxgiant;		/* rx giant frames */
-	u32 rxnoscb;		/* rx no scb error */
-	u32 rxbadproto;	/* rx invalid frames */
-	u32 rxbadsrcmac;	/* rx frames with Invalid Src Mac */
-	u32 rxbadda;		/* rx frames tossed for invalid da */
-	u32 rxfilter;	/* rx frames filtered out */
-
-	/* receive chip error counters */
-	u32 rxoflo;		/* rx fifo overflow errors */
-	u32 rxuflo[NFIFO];	/* rx dma descriptor underflow errors */
-
-	u32 d11cnt_txrts_off;	/* d11cnt txrts value when reset d11cnt */
-	u32 d11cnt_rxcrc_off;	/* d11cnt rxcrc value when reset d11cnt */
-	u32 d11cnt_txnocts_off;	/* d11cnt txnocts value when reset d11cnt */
-
-	/* misc counters */
-	u32 dmade;		/* tx/rx dma descriptor errors */
-	u32 dmada;		/* tx/rx dma data errors */
-	u32 dmape;		/* tx/rx dma descriptor protocol errors */
-	u32 reset;		/* reset count */
-	u32 tbtt;		/* cnts the TBTT int's */
-	u32 txdmawar;
-	u32 pkt_callback_reg_fail;	/* callbacks register failure */
-
-	/* MAC counters: 32-bit version of d11.h's macstat_t */
-	u32 txallfrm;	/* total number of frames sent, incl. Data, ACK, RTS, CTS,
-				 * Control Management (includes retransmissions)
-				 */
-	u32 txrtsfrm;	/* number of RTS sent out by the MAC */
-	u32 txctsfrm;	/* number of CTS sent out by the MAC */
-	u32 txackfrm;	/* number of ACK frames sent out */
-	u32 txdnlfrm;	/* Not used */
-	u32 txbcnfrm;	/* beacons transmitted */
-	u32 txfunfl[8];	/* per-fifo tx underflows */
-	u32 txtplunfl;	/* Template underflows (mac was too slow to transmit ACK/CTS
-				 * or BCN)
-				 */
-	u32 txphyerror;	/* Transmit phy error, type of error is reported in tx-status for
-				 * driver enqueued frames
-				 */
-	u32 rxfrmtoolong;	/* Received frame longer than legal limit (2346 bytes) */
-	u32 rxfrmtooshrt;	/* Received frame did not contain enough bytes for its frame type */
-	u32 rxinvmachdr;	/* Either the protocol version != 0 or frame type not
-				 * data/control/management
-				 */
-	u32 rxbadfcs;	/* number of frames for which the CRC check failed in the MAC */
-	u32 rxbadplcp;	/* parity check of the PLCP header failed */
-	u32 rxcrsglitch;	/* PHY was able to correlate the preamble but not the header */
-	u32 rxstrt;		/* Number of received frames with a good PLCP
-				 * (i.e. passing parity check)
-				 */
-	u32 rxdfrmucastmbss;	/* Number of received DATA frames with good FCS and matching RA */
-	u32 rxmfrmucastmbss;	/* number of received mgmt frames with good FCS and matching RA */
-	u32 rxcfrmucast;	/* number of received CNTRL frames with good FCS and matching RA */
-	u32 rxrtsucast;	/* number of unicast RTS addressed to the MAC (good FCS) */
-	u32 rxctsucast;	/* number of unicast CTS addressed to the MAC (good FCS) */
-	u32 rxackucast;	/* number of ucast ACKS received (good FCS) */
-	u32 rxdfrmocast;	/* number of received DATA frames (good FCS and not matching RA) */
-	u32 rxmfrmocast;	/* number of received MGMT frames (good FCS and not matching RA) */
-	u32 rxcfrmocast;	/* number of received CNTRL frame (good FCS and not matching RA) */
-	u32 rxrtsocast;	/* number of received RTS not addressed to the MAC */
-	u32 rxctsocast;	/* number of received CTS not addressed to the MAC */
-	u32 rxdfrmmcast;	/* number of RX Data multicast frames received by the MAC */
-	u32 rxmfrmmcast;	/* number of RX Management multicast frames received by the MAC */
-	u32 rxcfrmmcast;	/* number of RX Control multicast frames received by the MAC
-				 * (unlikely to see these)
-				 */
-	u32 rxbeaconmbss;	/* beacons received from member of BSS */
-	u32 rxdfrmucastobss;	/* number of unicast frames addressed to the MAC from
-				 * other BSS (WDS FRAME)
-				 */
-	u32 rxbeaconobss;	/* beacons received from other BSS */
-	u32 rxrsptmout;	/* Number of response timeouts for transmitted frames
-				 * expecting a response
-				 */
-	u32 bcntxcancl;	/* transmit beacons canceled due to receipt of beacon (IBSS) */
-	u32 rxf0ovfl;	/* Number of receive fifo 0 overflows */
-	u32 rxf1ovfl;	/* Number of receive fifo 1 overflows (obsolete) */
-	u32 rxf2ovfl;	/* Number of receive fifo 2 overflows (obsolete) */
-	u32 txsfovfl;	/* Number of transmit status fifo overflows (obsolete) */
-	u32 pmqovfl;		/* Number of PMQ overflows */
-	u32 rxcgprqfrm;	/* Number of received Probe requests that made it into
-				 * the PRQ fifo
-				 */
-	u32 rxcgprsqovfl;	/* Rx Probe Request Que overflow in the AP */
-	u32 txcgprsfail;	/* Tx Probe Response Fail. AP sent probe response but did
-				 * not get ACK
-				 */
-	u32 txcgprssuc;	/* Tx Probe Response Success (ACK was received) */
-	u32 prs_timeout;	/* Number of probe requests that were dropped from the PRQ
-				 * fifo because a probe response could not be sent out within
-				 * the time limit defined in M_PRS_MAXTIME
-				 */
-	u32 rxnack;
-	u32 frmscons;
-	u32 txnack;
-	u32 txglitch_nack;	/* obsolete */
-	u32 txburst;		/* obsolete */
-
-	/* 802.11 MIB counters, pp. 614 of 802.11 reaff doc. */
-	u32 txfrag;		/* dot11TransmittedFragmentCount */
-	u32 txmulti;		/* dot11MulticastTransmittedFrameCount */
-	u32 txfail;		/* dot11FailedCount */
-	u32 txretry;		/* dot11RetryCount */
-	u32 txretrie;	/* dot11MultipleRetryCount */
-	u32 rxdup;		/* dot11FrameduplicateCount */
-	u32 txrts;		/* dot11RTSSuccessCount */
-	u32 txnocts;		/* dot11RTSFailureCount */
-	u32 txnoack;		/* dot11ACKFailureCount */
-	u32 rxfrag;		/* dot11ReceivedFragmentCount */
-	u32 rxmulti;		/* dot11MulticastReceivedFrameCount */
-	u32 rxcrc;		/* dot11FCSErrorCount */
-	u32 txfrmsnt;	/* dot11TransmittedFrameCount (bogus MIB?) */
-	u32 rxundec;		/* dot11WEPUndecryptableCount */
-
-	/* WPA2 counters (see rxundec for DecryptFailureCount) */
-	u32 tkipmicfaill;	/* TKIPLocalMICFailures */
-	u32 tkipcntrmsr;	/* TKIPCounterMeasuresInvoked */
-	u32 tkipreplay;	/* TKIPReplays */
-	u32 ccmpfmterr;	/* CCMPFormatErrors */
-	u32 ccmpreplay;	/* CCMPReplays */
-	u32 ccmpundec;	/* CCMPDecryptErrors */
-	u32 fourwayfail;	/* FourWayHandshakeFailures */
-	u32 wepundec;	/* dot11WEPUndecryptableCount */
-	u32 wepicverr;	/* dot11WEPICVErrorCount */
-	u32 decsuccess;	/* DecryptSuccessCount */
-	u32 tkipicverr;	/* TKIPICVErrorCount */
-	u32 wepexcluded;	/* dot11WEPExcludedCount */
-
-	u32 rxundec_mcst;	/* dot11WEPUndecryptableCount */
-
-	/* WPA2 counters (see rxundec for DecryptFailureCount) */
-	u32 tkipmicfaill_mcst;	/* TKIPLocalMICFailures */
-	u32 tkipcntrmsr_mcst;	/* TKIPCounterMeasuresInvoked */
-	u32 tkipreplay_mcst;	/* TKIPReplays */
-	u32 ccmpfmterr_mcst;	/* CCMPFormatErrors */
-	u32 ccmpreplay_mcst;	/* CCMPReplays */
-	u32 ccmpundec_mcst;	/* CCMPDecryptErrors */
-	u32 fourwayfail_mcst;	/* FourWayHandshakeFailures */
-	u32 wepundec_mcst;	/* dot11WEPUndecryptableCount */
-	u32 wepicverr_mcst;	/* dot11WEPICVErrorCount */
-	u32 decsuccess_mcst;	/* DecryptSuccessCount */
-	u32 tkipicverr_mcst;	/* TKIPICVErrorCount */
-	u32 wepexcluded_mcst;	/* dot11WEPExcludedCount */
-
-	u32 txchanrej;	/* Tx frames suppressed due to channel rejection */
-	u32 txexptime;	/* Tx frames suppressed due to timer expiration */
-	u32 psmwds;		/* Count PSM watchdogs */
-	u32 phywatchdog;	/* Count Phy watchdogs (triggered by ucode) */
-
-	/* MBSS counters, AP only */
-	u32 prq_entries_handled;	/* PRQ entries read in */
-	u32 prq_undirected_entries;	/*    which were bcast bss & ssid */
-	u32 prq_bad_entries;	/*    which could not be translated to info */
-	u32 atim_suppress_count;	/* TX suppressions on ATIM fifo */
-	u32 bcn_template_not_ready;	/* Template marked in use on send bcn ... */
-	u32 bcn_template_not_ready_done;	/* ...but "DMA done" interrupt rcvd */
-	u32 late_tbtt_dpc;	/* TBTT DPC did not happen in time */
-
-	/* per-rate receive stat counters */
-	u32 rx1mbps;		/* packets rx at 1Mbps */
-	u32 rx2mbps;		/* packets rx at 2Mbps */
-	u32 rx5mbps5;	/* packets rx at 5.5Mbps */
-	u32 rx6mbps;		/* packets rx at 6Mbps */
-	u32 rx9mbps;		/* packets rx at 9Mbps */
-	u32 rx11mbps;	/* packets rx at 11Mbps */
-	u32 rx12mbps;	/* packets rx at 12Mbps */
-	u32 rx18mbps;	/* packets rx at 18Mbps */
-	u32 rx24mbps;	/* packets rx at 24Mbps */
-	u32 rx36mbps;	/* packets rx at 36Mbps */
-	u32 rx48mbps;	/* packets rx at 48Mbps */
-	u32 rx54mbps;	/* packets rx at 54Mbps */
-	u32 rx108mbps;	/* packets rx at 108mbps */
-	u32 rx162mbps;	/* packets rx at 162mbps */
-	u32 rx216mbps;	/* packets rx at 216 mbps */
-	u32 rx270mbps;	/* packets rx at 270 mbps */
-	u32 rx324mbps;	/* packets rx at 324 mbps */
-	u32 rx378mbps;	/* packets rx at 378 mbps */
-	u32 rx432mbps;	/* packets rx at 432 mbps */
-	u32 rx486mbps;	/* packets rx at 486 mbps */
-	u32 rx540mbps;	/* packets rx at 540 mbps */
-
-	/* pkteng rx frame stats */
-	u32 pktengrxducast;	/* unicast frames rxed by the pkteng code */
-	u32 pktengrxdmcast;	/* multicast frames rxed by the pkteng code */
-
-	u32 rfdisable;	/* count of radio disables */
-	u32 bphy_rxcrsglitch;	/* PHY count of bphy glitches */
-
-	u32 txmpdu_sgi;	/* count for sgi transmit */
-	u32 rxmpdu_sgi;	/* count for sgi received */
-	u32 txmpdu_stbc;	/* count for stbc transmit */
-	u32 rxmpdu_stbc;	/* count for stbc received */
-};
-
-#define	WL_DELTA_STATS_T_VERSION	1	/* current version of wl_delta_stats_t struct */
-
-typedef struct {
-	u16 version;		/* see definition of WL_DELTA_STATS_T_VERSION */
-	u16 length;		/* length of entire structure */
-
-	/* transmit stat counters */
-	u32 txframe;		/* tx data frames */
-	u32 txbyte;		/* tx data bytes */
-	u32 txretrans;	/* tx mac retransmits */
-	u32 txfail;		/* tx failures */
-
-	/* receive stat counters */
-	u32 rxframe;		/* rx data frames */
-	u32 rxbyte;		/* rx data bytes */
-
-	/* per-rate receive stat counters */
-	u32 rx1mbps;		/* packets rx at 1Mbps */
-	u32 rx2mbps;		/* packets rx at 2Mbps */
-	u32 rx5mbps5;	/* packets rx at 5.5Mbps */
-	u32 rx6mbps;		/* packets rx at 6Mbps */
-	u32 rx9mbps;		/* packets rx at 9Mbps */
-	u32 rx11mbps;	/* packets rx at 11Mbps */
-	u32 rx12mbps;	/* packets rx at 12Mbps */
-	u32 rx18mbps;	/* packets rx at 18Mbps */
-	u32 rx24mbps;	/* packets rx at 24Mbps */
-	u32 rx36mbps;	/* packets rx at 36Mbps */
-	u32 rx48mbps;	/* packets rx at 48Mbps */
-	u32 rx54mbps;	/* packets rx at 54Mbps */
-	u32 rx108mbps;	/* packets rx at 108mbps */
-	u32 rx162mbps;	/* packets rx at 162mbps */
-	u32 rx216mbps;	/* packets rx at 216 mbps */
-	u32 rx270mbps;	/* packets rx at 270 mbps */
-	u32 rx324mbps;	/* packets rx at 324 mbps */
-	u32 rx378mbps;	/* packets rx at 378 mbps */
-	u32 rx432mbps;	/* packets rx at 432 mbps */
-	u32 rx486mbps;	/* packets rx at 486 mbps */
-	u32 rx540mbps;	/* packets rx at 540 mbps */
-} wl_delta_stats_t;
-
-#define WL_WME_CNT_VERSION	1	/* current version of wl_wme_cnt_t */
-
-typedef struct {
-	u32 packets;
-	u32 bytes;
-} wl_traffic_stats_t;
-
-typedef struct {
-	u16 version;		/* see definition of WL_WME_CNT_VERSION */
-	u16 length;		/* length of entire structure */
-
-	wl_traffic_stats_t tx[AC_COUNT];	/* Packets transmitted */
-	wl_traffic_stats_t tx_failed[AC_COUNT];	/* Packets dropped or failed to transmit */
-	wl_traffic_stats_t rx[AC_COUNT];	/* Packets received */
-	wl_traffic_stats_t rx_failed[AC_COUNT];	/* Packets failed to receive */
-
-	wl_traffic_stats_t forward[AC_COUNT];	/* Packets forwarded by AP */
-
-	wl_traffic_stats_t tx_expired[AC_COUNT];	/* packets dropped due to lifetime expiry */
-
-} wl_wme_cnt_t;
-
 struct wl_msglevel2 {
 	u32 low;
 	u32 high;
 };
 
-#ifdef WLBA
-
-#define	WLC_BA_CNT_VERSION	1	/* current version of wlc_ba_cnt_t */
-
-/* block ack related stats */
-typedef struct wlc_ba_cnt {
-	u16 version;		/* WLC_BA_CNT_VERSION */
-	u16 length;		/* length of entire structure */
-
-	/* transmit stat counters */
-	u32 txpdu;		/* pdus sent */
-	u32 txsdu;		/* sdus sent */
-	u32 txfc;		/* tx side flow controlled packets */
-	u32 txfci;		/* tx side flow control initiated */
-	u32 txretrans;	/* retransmitted pdus */
-	u32 txbatimer;	/* ba resend due to timer */
-	u32 txdrop;		/* dropped packets */
-	u32 txaddbareq;	/* addba req sent */
-	u32 txaddbaresp;	/* addba resp sent */
-	u32 txdelba;		/* delba sent */
-	u32 txba;		/* ba sent */
-	u32 txbar;		/* bar sent */
-	u32 txpad[4];	/* future */
-
-	/* receive side counters */
-	u32 rxpdu;		/* pdus recd */
-	u32 rxqed;		/* pdus buffered before sending up */
-	u32 rxdup;		/* duplicate pdus */
-	u32 rxnobuf;		/* pdus discarded due to no buf */
-	u32 rxaddbareq;	/* addba req recd */
-	u32 rxaddbaresp;	/* addba resp recd */
-	u32 rxdelba;		/* delba recd */
-	u32 rxba;		/* ba recd */
-	u32 rxbar;		/* bar recd */
-	u32 rxinvba;		/* invalid ba recd */
-	u32 rxbaholes;	/* ba recd with holes */
-	u32 rxunexp;		/* unexpected packets */
-	u32 rxpad[4];	/* future */
-} wlc_ba_cnt_t;
-#endif				/* WLBA */
-
 /* structure for per-tid ampdu control */
 struct ampdu_tid_control {
 	u8 tid;		/* tid */
diff -druN linux-2.6.39-libre/drivers/staging/brcm80211/Kconfig linux-3.0-rc7-libre/drivers/staging/brcm80211/Kconfig
--- linux-2.6.39-libre/drivers/staging/brcm80211/Kconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/brcm80211/Kconfig	2011-07-11 19:51:52.000000000 -0400
@@ -1,21 +1,28 @@
-menuconfig BRCM80211
-	tristate "Broadcom IEEE802.11n WLAN drivers"
-	depends on WLAN
+config BRCMUTIL
+	tristate
+	default n
 
 config BRCMSMAC
-	bool "Broadcom IEEE802.11n PCIe SoftMAC WLAN driver"
+	tristate "Broadcom IEEE802.11n PCIe SoftMAC WLAN driver"
+	default n
 	depends on PCI
-	depends on BRCM80211 && MAC80211
+	depends on WLAN && MAC80211
+	depends on X86 || MIPS
+	select BRCMUTIL
 	select FW_LOADER
+	select CRC_CCITT
 	---help---
 	  This module adds support for PCIe wireless adapters based on Broadcom
 	  IEEE802.11n SoftMAC chipsets.  If you choose to build a module, it'll
 	  be called brcmsmac.ko.
 
 config BRCMFMAC
-	bool "Broadcom IEEE802.11n embedded FullMAC WLAN driver"
+	tristate "Broadcom IEEE802.11n embedded FullMAC WLAN driver"
+	default n
 	depends on MMC
-	depends on BRCM80211 && CFG80211
+	depends on WLAN && CFG80211
+	depends on X86 || MIPS
+	select BRCMUTIL
 	select FW_LOADER
 	select WIRELESS_EXT
 	select WEXT_PRIV
@@ -28,6 +35,6 @@
 config BRCMDBG
 	bool "Broadcom driver debug functions"
 	default n
-	depends on BRCM80211
+	depends on BRCMSMAC || BRCMFMAC
 	---help---
 	  Selecting this enables additional code for debug purposes.
diff -druN linux-2.6.39-libre/drivers/staging/brcm80211/Makefile linux-3.0-rc7-libre/drivers/staging/brcm80211/Makefile
--- linux-2.6.39-libre/drivers/staging/brcm80211/Makefile	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/brcm80211/Makefile	2011-07-11 19:51:52.000000000 -0400
@@ -19,5 +19,6 @@
 subdir-ccflags-y					:= -DBCMDMA32
 subdir-ccflags-$(CONFIG_BRCMDBG)	+= -DBCMDBG -DBCMDBG_ASSERT
 
+obj-$(CONFIG_BRCMUTIL)	+= util/
 obj-$(CONFIG_BRCMFMAC)	+= brcmfmac/
 obj-$(CONFIG_BRCMSMAC)	+= brcmsmac/
diff -druN linux-2.6.39-libre/drivers/staging/brcm80211/README linux-3.0-rc7-libre/drivers/staging/brcm80211/README
--- linux-2.6.39-libre/drivers/staging/brcm80211/README	2011-05-19 02:13:36.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/brcm80211/README	2011-07-21 06:56:01.000000000 -0400
@@ -1,81 +1,56 @@
-Broadcom Mac80211 driver
-
-This is a driver in progress.  It has features still to be implemented well as
-bugs in current code.
+Broadcom brcmsmac (mac80211-based softmac PCIe) and brcmfmac (SDIO) drivers.
 
+Completely open source host drivers, no binary object files.
 
-What's here and not here
-=======================
-- Completely open source host driver, no binary object files
-- Features Broadcom's OneDriver architecture (single source base for
-  supported chips and architectures)
-- On-chip firmware loaded using standard request_firmware()
-- Support for BCM43224, BCM43225, BCM4313 (PCIe NIC)
-- Framework for supporting new chips, including mac80211-aware embedded chips
-- Does not support older PCI/PCIe chips with SSB backplane
-- Driver includes BMAC interface for transparent dongle support
-- Uses minstrel_ht rate algorithm
-- HW based encryption not enabled yet
+Support for the following chips:
+===============================
 
+    brcmsmac (PCIe)
+    Name        Device ID
+    BCM4313     0x4727
+    BCM43224    0x4353
+    BCM43225    0x4357
 
-What's done
-==========
-- Integration with mac80211 stack
-- A-MPDU single & dual stream rates
-- BCM43224:	Dualband, Dual stream, 20MHz channels
-	Throughput (in chamber): ~85-90 Mbits/sec (in both 2.4 & 5 GHz bands)
-- BCM43225:	2.4 GHz, Dual Stream, 20MHz channels
-	Throughput (in chamber): ~85-90 Mbits/sec
-- BCM4313:		2.4 GHz, Single Stream
-	Throughput (in chamber): ~40 Mbits/sec
+    brcmfmac (SDIO)
+    Name
+    BCM4329
 
+Both brcmsmac and brcmfmac drivers require firmware files that need to be
+separately downloaded.
 
-Things To Be Done
-=================
-See the TODO file
+Firmware
+======================
+Firmware is available from the Linux firmware repository at:
 
+    git://git.kernel.org/pub/scm/linux/kernel/git/dwmw2//*(DEBLOBBED)*/
+    http://git.kernel.org/?p=linux/kernel/git/dwmw2//*(DEBLOBBED)*/
+    https://git.kernel.org/?p=linux/kernel/git/dwmw2//*(DEBLOBBED)*/
 
-/*(DEBLOBBED)*/
 
-Currently supported chips
-==============
-PCI
-Name		Device ID
-BCM4313		0x4727
-BCM43224	0x4353
-BCM43225	0x4357
+===============================================================
+Broadcom brcmsmac driver
+===============================================================
+- Support for both 32 and 64 bit Linux kernels
 
 
-Bugs/Problems
-==============
-- Driver can get confused while scanning during high throughput, can cause
-  burping, hanging, and possible crashing.
-- Occasional hangs & burps with BCM43224 on 2.4 GHz with dual stream rates.
-- Occasional crashes with BCM43224 on multicore machines.
+/*(DEBLOBBED)*/
 
 
-Note on Regulatory Implementation
-================================
-This generation of chips contain additional regulatory support independent of
-the driver. The devices use a single worldwide regulatory domain, with channels
-12-14 (2.4 GHz band) and channels 52-64 and 100-140 (5 GHz band) restricted to
-passive operation. Transmission on those channels is suppressed until
-appropriate other traffic is observed on those channels.
+===============================================================
+Broadcom brcmfmac driver
+===============================================================
+- Support for 32 bit Linux kernel, 64 bit untested
 
-Within the driver, we use the fictitious country code "X2" to represent this
-worldwide regulatory domain. There is currently no interface to configure a
-different domain.
 
-The driver reads the SROM country code from the chip and hands it up to
-mac80211 as the regulatory hint, however this information is otherwise unused
-with the driver.
+/*(DEBLOBBED)*/
 
 
 Contact Info:
 =============
 Brett Rudley		brudley@broadcom.com
 Henry Ptasinski		henryp@broadcom.com
-Dowan Kim			dowan@broadcom.com
+Dowan Kim		dowan@broadcom.com
 Roland Vossen		rvossen@broadcom.com
 Arend van Spriel	arend@broadcom.com
 
+For more info, refer to: http://linuxwireless.org/en/users/Drivers/brcm80211
diff -druN linux-2.6.39-libre/drivers/staging/brcm80211/TODO linux-3.0-rc7-libre/drivers/staging/brcm80211/TODO
--- linux-2.6.39-libre/drivers/staging/brcm80211/TODO	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/brcm80211/TODO	2011-07-11 19:51:52.000000000 -0400
@@ -1,51 +1,15 @@
-To Do List for Broadcom Mac80211 driver
-
-Features to be added
-=====================
-- 40 MHz channels
-- Power Save
-- AP
-- IBSS
-- HW-based encryption
-- LED support
-- RFKILL
-- Debugfs and debugability
-
-Code cleanup
-============
-- Use proper kernel coding standards
-- Remove overlap with system header files. (ie much of include/proto/*.h should
-  be removed)
-- Purge unused variables/data structs/functions BUT keep code related to
-  features that are being added (ie AP mode, 40 Mhz channels, IBSS etc).
-- Replace proprietary utility functions with public kernel versions.
+To Do List for Broadcom Mac80211 driver before getting in mainline
 
 Bugs
 ====
-- Various occasional asserts/hangs
-- Scanning during data transfer sometimes causes major slowdowns.  Sometimes
-  revcovers when scan is done, other times not.
-- Mac80211 API not completely implemented (ie ops_bss_info_changed,
-  ops_get_stats, etc)
-
-Other
-=====
-- wlc_mac80211.[ch], wl_mac80211.[ch] and linux_osl.c all need to be refactored
-    and combined.
-- Merge files that are partially duplicated between the softmac and fullmac
-  drivers
-- Replace driver's proprietary ssb interface with generic kernel ssb module
-  (only used when compiling for SDIO).
-- PCI and SDIO support are currently #ifdef'ed exclusive of each other, which
-  leads to a separate wl.ko for each.  This should be changed to runtime
-  handling of different interfaces so that a single binary driver can be built.
-- Add support for new chips (obviously an ongoing item).
+- Oops on AMPDU traffic, to be solved by new ucode (currently under test)
 
-Contact
-=====
-Brett Rudley <brudley@broadcom.com>
-Henry Ptasinski <henryp@broadcom.com>
-Dowan Kim <dowan@broadcom.com>
-Roland Vossen <rvossen@broadcom.com>
-Arend van Spriel <arend@broadcom.com>
+brcmfmac and brcmsmac
+=====================
+- ASSERTS not allowed in mainline, replace by warning + error handling
+- Replace printk and WL_ERROR() with proper routines
 
+brcmfmac
+=====================
+- Replace driver's proprietary ssb interface with generic kernel ssb module
+- Build and test on 64 bit linux kernel
diff -druN linux-2.6.39-libre/drivers/staging/brcm80211/util/aiutils.c linux-3.0-rc7-libre/drivers/staging/brcm80211/util/aiutils.c
--- linux-2.6.39-libre/drivers/staging/brcm80211/util/aiutils.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/brcm80211/util/aiutils.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,705 +0,0 @@
-/*
- * Copyright (c) 2010 Broadcom Corporation
- *
- * 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/delay.h>
-#include <linux/kernel.h>
-#include <linux/string.h>
-#include <bcmdefs.h>
-#include <linux/module.h>
-#include <linux/pci.h>
-#include <bcmutils.h>
-#include <siutils.h>
-#include <hndsoc.h>
-#include <sbchipc.h>
-#include <pcicfg.h>
-#include <bcmdevs.h>
-
-#define BCM47162_DMP() ((sih->chip == BCM47162_CHIP_ID) && \
-		(sih->chiprev == 0) && \
-		(sii->coreid[sii->curidx] == MIPS74K_CORE_ID))
-
-/* EROM parsing */
-
-static u32
-get_erom_ent(si_t *sih, u32 **eromptr, u32 mask, u32 match)
-{
-	u32 ent;
-	uint inv = 0, nom = 0;
-
-	while (true) {
-		ent = R_REG(*eromptr);
-		(*eromptr)++;
-
-		if (mask == 0)
-			break;
-
-		if ((ent & ER_VALID) == 0) {
-			inv++;
-			continue;
-		}
-
-		if (ent == (ER_END | ER_VALID))
-			break;
-
-		if ((ent & mask) == match)
-			break;
-
-		nom++;
-	}
-
-	SI_VMSG(("%s: Returning ent 0x%08x\n", __func__, ent));
-	if (inv + nom) {
-		SI_VMSG(("  after %d invalid and %d non-matching entries\n",
-			 inv, nom));
-	}
-	return ent;
-}
-
-static u32
-get_asd(si_t *sih, u32 **eromptr, uint sp, uint ad, uint st,
-	u32 *addrl, u32 *addrh, u32 *sizel, u32 *sizeh)
-{
-	u32 asd, sz, szd;
-
-	asd = get_erom_ent(sih, eromptr, ER_VALID, ER_VALID);
-	if (((asd & ER_TAG1) != ER_ADD) ||
-	    (((asd & AD_SP_MASK) >> AD_SP_SHIFT) != sp) ||
-	    ((asd & AD_ST_MASK) != st)) {
-		/* This is not what we want, "push" it back */
-		(*eromptr)--;
-		return 0;
-	}
-	*addrl = asd & AD_ADDR_MASK;
-	if (asd & AD_AG32)
-		*addrh = get_erom_ent(sih, eromptr, 0, 0);
-	else
-		*addrh = 0;
-	*sizeh = 0;
-	sz = asd & AD_SZ_MASK;
-	if (sz == AD_SZ_SZD) {
-		szd = get_erom_ent(sih, eromptr, 0, 0);
-		*sizel = szd & SD_SZ_MASK;
-		if (szd & SD_SG32)
-			*sizeh = get_erom_ent(sih, eromptr, 0, 0);
-	} else
-		*sizel = AD_SZ_BASE << (sz >> AD_SZ_SHIFT);
-
-	SI_VMSG(("  SP %d, ad %d: st = %d, 0x%08x_0x%08x @ 0x%08x_0x%08x\n",
-		 sp, ad, st, *sizeh, *sizel, *addrh, *addrl));
-
-	return asd;
-}
-
-static void ai_hwfixup(si_info_t *sii)
-{
-}
-
-/* parse the enumeration rom to identify all cores */
-void ai_scan(si_t *sih, void *regs, uint devid)
-{
-	si_info_t *sii = SI_INFO(sih);
-	chipcregs_t *cc = (chipcregs_t *) regs;
-	u32 erombase, *eromptr, *eromlim;
-
-	erombase = R_REG(&cc->eromptr);
-
-	switch (sih->bustype) {
-	case SI_BUS:
-		eromptr = (u32 *) REG_MAP(erombase, SI_CORE_SIZE);
-		break;
-
-	case PCI_BUS:
-		/* Set wrappers address */
-		sii->curwrap = (void *)((unsigned long)regs + SI_CORE_SIZE);
-
-		/* Now point the window at the erom */
-		pci_write_config_dword(sii->pbus, PCI_BAR0_WIN, erombase);
-		eromptr = regs;
-		break;
-
-	case SPI_BUS:
-	case SDIO_BUS:
-		eromptr = (u32 *)(unsigned long)erombase;
-		break;
-
-	default:
-		SI_ERROR(("Don't know how to do AXI enumertion on bus %d\n",
-			  sih->bustype));
-		ASSERT(0);
-		return;
-	}
-	eromlim = eromptr + (ER_REMAPCONTROL / sizeof(u32));
-
-	SI_VMSG(("ai_scan: regs = 0x%p, erombase = 0x%08x, eromptr = 0x%p, eromlim = 0x%p\n", regs, erombase, eromptr, eromlim));
-	while (eromptr < eromlim) {
-		u32 cia, cib, cid, mfg, crev, nmw, nsw, nmp, nsp;
-		u32 mpd, asd, addrl, addrh, sizel, sizeh;
-		u32 *base;
-		uint i, j, idx;
-		bool br;
-
-		br = false;
-
-		/* Grok a component */
-		cia = get_erom_ent(sih, &eromptr, ER_TAG, ER_CI);
-		if (cia == (ER_END | ER_VALID)) {
-			SI_VMSG(("Found END of erom after %d cores\n",
-				 sii->numcores));
-			ai_hwfixup(sii);
-			return;
-		}
-		base = eromptr - 1;
-		cib = get_erom_ent(sih, &eromptr, 0, 0);
-
-		if ((cib & ER_TAG) != ER_CI) {
-			SI_ERROR(("CIA not followed by CIB\n"));
-			goto error;
-		}
-
-		cid = (cia & CIA_CID_MASK) >> CIA_CID_SHIFT;
-		mfg = (cia & CIA_MFG_MASK) >> CIA_MFG_SHIFT;
-		crev = (cib & CIB_REV_MASK) >> CIB_REV_SHIFT;
-		nmw = (cib & CIB_NMW_MASK) >> CIB_NMW_SHIFT;
-		nsw = (cib & CIB_NSW_MASK) >> CIB_NSW_SHIFT;
-		nmp = (cib & CIB_NMP_MASK) >> CIB_NMP_SHIFT;
-		nsp = (cib & CIB_NSP_MASK) >> CIB_NSP_SHIFT;
-
-		SI_VMSG(("Found component 0x%04x/0x%04x rev %d at erom addr 0x%p, with nmw = %d, " "nsw = %d, nmp = %d & nsp = %d\n", mfg, cid, crev, base, nmw, nsw, nmp, nsp));
-
-		if (((mfg == MFGID_ARM) && (cid == DEF_AI_COMP)) || (nsp == 0))
-			continue;
-		if ((nmw + nsw == 0)) {
-			/* A component which is not a core */
-			if (cid == OOB_ROUTER_CORE_ID) {
-				asd = get_asd(sih, &eromptr, 0, 0, AD_ST_SLAVE,
-					      &addrl, &addrh, &sizel, &sizeh);
-				if (asd != 0) {
-					sii->oob_router = addrl;
-				}
-			}
-			continue;
-		}
-
-		idx = sii->numcores;
-/*		sii->eromptr[idx] = base; */
-		sii->cia[idx] = cia;
-		sii->cib[idx] = cib;
-		sii->coreid[idx] = cid;
-
-		for (i = 0; i < nmp; i++) {
-			mpd = get_erom_ent(sih, &eromptr, ER_VALID, ER_VALID);
-			if ((mpd & ER_TAG) != ER_MP) {
-				SI_ERROR(("Not enough MP entries for component 0x%x\n", cid));
-				goto error;
-			}
-			SI_VMSG(("  Master port %d, mp: %d id: %d\n", i,
-				 (mpd & MPD_MP_MASK) >> MPD_MP_SHIFT,
-				 (mpd & MPD_MUI_MASK) >> MPD_MUI_SHIFT));
-		}
-
-		/* First Slave Address Descriptor should be port 0:
-		 * the main register space for the core
-		 */
-		asd =
-		    get_asd(sih, &eromptr, 0, 0, AD_ST_SLAVE, &addrl, &addrh,
-			    &sizel, &sizeh);
-		if (asd == 0) {
-			/* Try again to see if it is a bridge */
-			asd =
-			    get_asd(sih, &eromptr, 0, 0, AD_ST_BRIDGE, &addrl,
-				    &addrh, &sizel, &sizeh);
-			if (asd != 0)
-				br = true;
-			else if ((addrh != 0) || (sizeh != 0)
-				 || (sizel != SI_CORE_SIZE)) {
-				SI_ERROR(("First Slave ASD for core 0x%04x malformed " "(0x%08x)\n", cid, asd));
-				goto error;
-			}
-		}
-		sii->coresba[idx] = addrl;
-		sii->coresba_size[idx] = sizel;
-		/* Get any more ASDs in port 0 */
-		j = 1;
-		do {
-			asd =
-			    get_asd(sih, &eromptr, 0, j, AD_ST_SLAVE, &addrl,
-				    &addrh, &sizel, &sizeh);
-			if ((asd != 0) && (j == 1) && (sizel == SI_CORE_SIZE)) {
-				sii->coresba2[idx] = addrl;
-				sii->coresba2_size[idx] = sizel;
-			}
-			j++;
-		} while (asd != 0);
-
-		/* Go through the ASDs for other slave ports */
-		for (i = 1; i < nsp; i++) {
-			j = 0;
-			do {
-				asd =
-				    get_asd(sih, &eromptr, i, j++, AD_ST_SLAVE,
-					    &addrl, &addrh, &sizel, &sizeh);
-			} while (asd != 0);
-			if (j == 0) {
-				SI_ERROR((" SP %d has no address descriptors\n",
-					  i));
-				goto error;
-			}
-		}
-
-		/* Now get master wrappers */
-		for (i = 0; i < nmw; i++) {
-			asd =
-			    get_asd(sih, &eromptr, i, 0, AD_ST_MWRAP, &addrl,
-				    &addrh, &sizel, &sizeh);
-			if (asd == 0) {
-				SI_ERROR(("Missing descriptor for MW %d\n", i));
-				goto error;
-			}
-			if ((sizeh != 0) || (sizel != SI_CORE_SIZE)) {
-				SI_ERROR(("Master wrapper %d is not 4KB\n", i));
-				goto error;
-			}
-			if (i == 0)
-				sii->wrapba[idx] = addrl;
-		}
-
-		/* And finally slave wrappers */
-		for (i = 0; i < nsw; i++) {
-			uint fwp = (nsp == 1) ? 0 : 1;
-			asd =
-			    get_asd(sih, &eromptr, fwp + i, 0, AD_ST_SWRAP,
-				    &addrl, &addrh, &sizel, &sizeh);
-			if (asd == 0) {
-				SI_ERROR(("Missing descriptor for SW %d\n", i));
-				goto error;
-			}
-			if ((sizeh != 0) || (sizel != SI_CORE_SIZE)) {
-				SI_ERROR(("Slave wrapper %d is not 4KB\n", i));
-				goto error;
-			}
-			if ((nmw == 0) && (i == 0))
-				sii->wrapba[idx] = addrl;
-		}
-
-		/* Don't record bridges */
-		if (br)
-			continue;
-
-		/* Done with core */
-		sii->numcores++;
-	}
-
-	SI_ERROR(("Reached end of erom without finding END"));
-
- error:
-	sii->numcores = 0;
-	return;
-}
-
-/* This function changes the logical "focus" to the indicated core.
- * Return the current core's virtual address.
- */
-void *ai_setcoreidx(si_t *sih, uint coreidx)
-{
-	si_info_t *sii = SI_INFO(sih);
-	u32 addr = sii->coresba[coreidx];
-	u32 wrap = sii->wrapba[coreidx];
-	void *regs;
-
-	if (coreidx >= sii->numcores)
-		return NULL;
-
-	/*
-	 * If the user has provided an interrupt mask enabled function,
-	 * then assert interrupts are disabled before switching the core.
-	 */
-	ASSERT((sii->intrsenabled_fn == NULL)
-	       || !(*(sii)->intrsenabled_fn) ((sii)->intr_arg));
-
-	switch (sih->bustype) {
-	case SI_BUS:
-		/* map new one */
-		if (!sii->regs[coreidx]) {
-			sii->regs[coreidx] = REG_MAP(addr, SI_CORE_SIZE);
-			ASSERT(GOODREGS(sii->regs[coreidx]));
-		}
-		sii->curmap = regs = sii->regs[coreidx];
-		if (!sii->wrappers[coreidx]) {
-			sii->wrappers[coreidx] = REG_MAP(wrap, SI_CORE_SIZE);
-			ASSERT(GOODREGS(sii->wrappers[coreidx]));
-		}
-		sii->curwrap = sii->wrappers[coreidx];
-		break;
-
-	case PCI_BUS:
-		/* point bar0 window */
-		pci_write_config_dword(sii->pbus, PCI_BAR0_WIN, addr);
-		regs = sii->curmap;
-		/* point bar0 2nd 4KB window */
-		pci_write_config_dword(sii->pbus, PCI_BAR0_WIN2, wrap);
-		break;
-
-	case SPI_BUS:
-	case SDIO_BUS:
-		sii->curmap = regs = (void *)(unsigned long)addr;
-		sii->curwrap = (void *)(unsigned long)wrap;
-		break;
-
-	default:
-		ASSERT(0);
-		regs = NULL;
-		break;
-	}
-
-	sii->curmap = regs;
-	sii->curidx = coreidx;
-
-	return regs;
-}
-
-/* Return the number of address spaces in current core */
-int ai_numaddrspaces(si_t *sih)
-{
-	return 2;
-}
-
-/* Return the address of the nth address space in the current core */
-u32 ai_addrspace(si_t *sih, uint asidx)
-{
-	si_info_t *sii;
-	uint cidx;
-
-	sii = SI_INFO(sih);
-	cidx = sii->curidx;
-
-	if (asidx == 0)
-		return sii->coresba[cidx];
-	else if (asidx == 1)
-		return sii->coresba2[cidx];
-	else {
-		SI_ERROR(("%s: Need to parse the erom again to find addr space %d\n", __func__, asidx));
-		return 0;
-	}
-}
-
-/* Return the size of the nth address space in the current core */
-u32 ai_addrspacesize(si_t *sih, uint asidx)
-{
-	si_info_t *sii;
-	uint cidx;
-
-	sii = SI_INFO(sih);
-	cidx = sii->curidx;
-
-	if (asidx == 0)
-		return sii->coresba_size[cidx];
-	else if (asidx == 1)
-		return sii->coresba2_size[cidx];
-	else {
-		SI_ERROR(("%s: Need to parse the erom again to find addr space %d\n", __func__, asidx));
-		return 0;
-	}
-}
-
-uint ai_flag(si_t *sih)
-{
-	si_info_t *sii;
-	aidmp_t *ai;
-
-	sii = SI_INFO(sih);
-	if (BCM47162_DMP()) {
-		SI_ERROR(("%s: Attempting to read MIPS DMP registers on 47162a0", __func__));
-		return sii->curidx;
-	}
-	ai = sii->curwrap;
-
-	return R_REG(&ai->oobselouta30) & 0x1f;
-}
-
-void ai_setint(si_t *sih, int siflag)
-{
-}
-
-void ai_write_wrap_reg(si_t *sih, u32 offset, u32 val)
-{
-	si_info_t *sii = SI_INFO(sih);
-	u32 *w = (u32 *) sii->curwrap;
-	W_REG(w + (offset / 4), val);
-	return;
-}
-
-uint ai_corevendor(si_t *sih)
-{
-	si_info_t *sii;
-	u32 cia;
-
-	sii = SI_INFO(sih);
-	cia = sii->cia[sii->curidx];
-	return (cia & CIA_MFG_MASK) >> CIA_MFG_SHIFT;
-}
-
-uint ai_corerev(si_t *sih)
-{
-	si_info_t *sii;
-	u32 cib;
-
-	sii = SI_INFO(sih);
-	cib = sii->cib[sii->curidx];
-	return (cib & CIB_REV_MASK) >> CIB_REV_SHIFT;
-}
-
-bool ai_iscoreup(si_t *sih)
-{
-	si_info_t *sii;
-	aidmp_t *ai;
-
-	sii = SI_INFO(sih);
-	ai = sii->curwrap;
-
-	return (((R_REG(&ai->ioctrl) & (SICF_FGC | SICF_CLOCK_EN)) ==
-		 SICF_CLOCK_EN)
-		&& ((R_REG(&ai->resetctrl) & AIRC_RESET) == 0));
-}
-
-/*
- * Switch to 'coreidx', issue a single arbitrary 32bit register mask&set operation,
- * switch back to the original core, and return the new value.
- *
- * When using the silicon backplane, no fiddling with interrupts or core switches is needed.
- *
- * Also, when using pci/pcie, we can optimize away the core switching for pci registers
- * and (on newer pci cores) chipcommon registers.
- */
-uint ai_corereg(si_t *sih, uint coreidx, uint regoff, uint mask, uint val)
-{
-	uint origidx = 0;
-	u32 *r = NULL;
-	uint w;
-	uint intr_val = 0;
-	bool fast = false;
-	si_info_t *sii;
-
-	sii = SI_INFO(sih);
-
-	ASSERT(GOODIDX(coreidx));
-	ASSERT(regoff < SI_CORE_SIZE);
-	ASSERT((val & ~mask) == 0);
-
-	if (coreidx >= SI_MAXCORES)
-		return 0;
-
-	if (sih->bustype == SI_BUS) {
-		/* If internal bus, we can always get at everything */
-		fast = true;
-		/* map if does not exist */
-		if (!sii->regs[coreidx]) {
-			sii->regs[coreidx] = REG_MAP(sii->coresba[coreidx],
-						     SI_CORE_SIZE);
-			ASSERT(GOODREGS(sii->regs[coreidx]));
-		}
-		r = (u32 *) ((unsigned char *) sii->regs[coreidx] + regoff);
-	} else if (sih->bustype == PCI_BUS) {
-		/* If pci/pcie, we can get at pci/pcie regs and on newer cores to chipc */
-
-		if ((sii->coreid[coreidx] == CC_CORE_ID) && SI_FAST(sii)) {
-			/* Chipc registers are mapped at 12KB */
-
-			fast = true;
-			r = (u32 *) ((char *)sii->curmap +
-					PCI_16KB0_CCREGS_OFFSET + regoff);
-		} else if (sii->pub.buscoreidx == coreidx) {
-			/* pci registers are at either in the last 2KB of an 8KB window
-			 * or, in pcie and pci rev 13 at 8KB
-			 */
-			fast = true;
-			if (SI_FAST(sii))
-				r = (u32 *) ((char *)sii->curmap +
-						PCI_16KB0_PCIREGS_OFFSET +
-						regoff);
-			else
-				r = (u32 *) ((char *)sii->curmap +
-						((regoff >= SBCONFIGOFF) ?
-						 PCI_BAR0_PCISBR_OFFSET :
-						 PCI_BAR0_PCIREGS_OFFSET) +
-						regoff);
-		}
-	}
-
-	if (!fast) {
-		INTR_OFF(sii, intr_val);
-
-		/* save current core index */
-		origidx = si_coreidx(&sii->pub);
-
-		/* switch core */
-		r = (u32 *) ((unsigned char *) ai_setcoreidx(&sii->pub, coreidx) +
-				regoff);
-	}
-	ASSERT(r != NULL);
-
-	/* mask and set */
-	if (mask || val) {
-		w = (R_REG(r) & ~mask) | val;
-		W_REG(r, w);
-	}
-
-	/* readback */
-	w = R_REG(r);
-
-	if (!fast) {
-		/* restore core index */
-		if (origidx != coreidx)
-			ai_setcoreidx(&sii->pub, origidx);
-
-		INTR_RESTORE(sii, intr_val);
-	}
-
-	return w;
-}
-
-void ai_core_disable(si_t *sih, u32 bits)
-{
-	si_info_t *sii;
-	volatile u32 dummy;
-	aidmp_t *ai;
-
-	sii = SI_INFO(sih);
-
-	ASSERT(GOODREGS(sii->curwrap));
-	ai = sii->curwrap;
-
-	/* if core is already in reset, just return */
-	if (R_REG(&ai->resetctrl) & AIRC_RESET)
-		return;
-
-	W_REG(&ai->ioctrl, bits);
-	dummy = R_REG(&ai->ioctrl);
-	udelay(10);
-
-	W_REG(&ai->resetctrl, AIRC_RESET);
-	udelay(1);
-}
-
-/* reset and re-enable a core
- * inputs:
- * bits - core specific bits that are set during and after reset sequence
- * resetbits - core specific bits that are set only during reset sequence
- */
-void ai_core_reset(si_t *sih, u32 bits, u32 resetbits)
-{
-	si_info_t *sii;
-	aidmp_t *ai;
-	volatile u32 dummy;
-
-	sii = SI_INFO(sih);
-	ASSERT(GOODREGS(sii->curwrap));
-	ai = sii->curwrap;
-
-	/*
-	 * Must do the disable sequence first to work for arbitrary current core state.
-	 */
-	ai_core_disable(sih, (bits | resetbits));
-
-	/*
-	 * Now do the initialization sequence.
-	 */
-	W_REG(&ai->ioctrl, (bits | SICF_FGC | SICF_CLOCK_EN));
-	dummy = R_REG(&ai->ioctrl);
-	W_REG(&ai->resetctrl, 0);
-	udelay(1);
-
-	W_REG(&ai->ioctrl, (bits | SICF_CLOCK_EN));
-	dummy = R_REG(&ai->ioctrl);
-	udelay(1);
-}
-
-void ai_core_cflags_wo(si_t *sih, u32 mask, u32 val)
-{
-	si_info_t *sii;
-	aidmp_t *ai;
-	u32 w;
-
-	sii = SI_INFO(sih);
-
-	if (BCM47162_DMP()) {
-		SI_ERROR(("%s: Accessing MIPS DMP register (ioctrl) on 47162a0",
-			  __func__));
-		return;
-	}
-
-	ASSERT(GOODREGS(sii->curwrap));
-	ai = sii->curwrap;
-
-	ASSERT((val & ~mask) == 0);
-
-	if (mask || val) {
-		w = ((R_REG(&ai->ioctrl) & ~mask) | val);
-		W_REG(&ai->ioctrl, w);
-	}
-}
-
-u32 ai_core_cflags(si_t *sih, u32 mask, u32 val)
-{
-	si_info_t *sii;
-	aidmp_t *ai;
-	u32 w;
-
-	sii = SI_INFO(sih);
-	if (BCM47162_DMP()) {
-		SI_ERROR(("%s: Accessing MIPS DMP register (ioctrl) on 47162a0",
-			  __func__));
-		return 0;
-	}
-
-	ASSERT(GOODREGS(sii->curwrap));
-	ai = sii->curwrap;
-
-	ASSERT((val & ~mask) == 0);
-
-	if (mask || val) {
-		w = ((R_REG(&ai->ioctrl) & ~mask) | val);
-		W_REG(&ai->ioctrl, w);
-	}
-
-	return R_REG(&ai->ioctrl);
-}
-
-u32 ai_core_sflags(si_t *sih, u32 mask, u32 val)
-{
-	si_info_t *sii;
-	aidmp_t *ai;
-	u32 w;
-
-	sii = SI_INFO(sih);
-	if (BCM47162_DMP()) {
-		SI_ERROR(("%s: Accessing MIPS DMP register (iostatus) on 47162a0", __func__));
-		return 0;
-	}
-
-	ASSERT(GOODREGS(sii->curwrap));
-	ai = sii->curwrap;
-
-	ASSERT((val & ~mask) == 0);
-	ASSERT((mask & ~SISF_CORE_BITS) == 0);
-
-	if (mask || val) {
-		w = ((R_REG(&ai->iostatus) & ~mask) | val);
-		W_REG(&ai->iostatus, w);
-	}
-
-	return R_REG(&ai->iostatus);
-}
-
diff -druN linux-2.6.39-libre/drivers/staging/brcm80211/util/bcmotp.c linux-3.0-rc7-libre/drivers/staging/brcm80211/util/bcmotp.c
--- linux-2.6.39-libre/drivers/staging/brcm80211/util/bcmotp.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/brcm80211/util/bcmotp.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,953 +0,0 @@
-/*
- * Copyright (c) 2010 Broadcom Corporation
- *
- * 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/delay.h>
-#include <linux/kernel.h>
-#include <linux/string.h>
-#include <bcmdefs.h>
-#include <linux/module.h>
-#include <linux/pci.h>
-#include <bcmdevs.h>
-#include <bcmutils.h>
-#include <siutils.h>
-#include <hndsoc.h>
-#include <sbchipc.h>
-#include <bcmotp.h>
-#include "siutils_priv.h"
-
-/*
- * There are two different OTP controllers so far:
- * 	1. new IPX OTP controller:	chipc 21, >=23
- * 	2. older HND OTP controller:	chipc 12, 17, 22
- *
- * Define BCMHNDOTP to include support for the HND OTP controller.
- * Define BCMIPXOTP to include support for the IPX OTP controller.
- *
- * NOTE 1: More than one may be defined
- * NOTE 2: If none are defined, the default is to include them all.
- */
-
-#if !defined(BCMHNDOTP) && !defined(BCMIPXOTP)
-#define BCMHNDOTP	1
-#define BCMIPXOTP	1
-#endif
-
-#define OTPTYPE_HND(ccrev)	((ccrev) < 21 || (ccrev) == 22)
-#define OTPTYPE_IPX(ccrev)	((ccrev) == 21 || (ccrev) >= 23)
-
-#define OTPP_TRIES	10000000	/* # of tries for OTPP */
-
-#ifdef BCMIPXOTP
-#define MAXNUMRDES		9	/* Maximum OTP redundancy entries */
-#endif
-
-/* OTP common function type */
-typedef int (*otp_status_t) (void *oh);
-typedef int (*otp_size_t) (void *oh);
-typedef void *(*otp_init_t) (si_t *sih);
-typedef u16(*otp_read_bit_t) (void *oh, chipcregs_t *cc, uint off);
-typedef int (*otp_read_region_t) (si_t *sih, int region, u16 *data,
-				  uint *wlen);
-typedef int (*otp_nvread_t) (void *oh, char *data, uint *len);
-
-/* OTP function struct */
-typedef struct otp_fn_s {
-	otp_size_t size;
-	otp_read_bit_t read_bit;
-	otp_init_t init;
-	otp_read_region_t read_region;
-	otp_nvread_t nvread;
-	otp_status_t status;
-} otp_fn_t;
-
-typedef struct {
-	uint ccrev;		/* chipc revision */
-	otp_fn_t *fn;		/* OTP functions */
-	si_t *sih;		/* Saved sb handle */
-
-#ifdef BCMIPXOTP
-	/* IPX OTP section */
-	u16 wsize;		/* Size of otp in words */
-	u16 rows;		/* Geometry */
-	u16 cols;		/* Geometry */
-	u32 status;		/* Flag bits (lock/prog/rv).
-				 * (Reflected only when OTP is power cycled)
-				 */
-	u16 hwbase;		/* hardware subregion offset */
-	u16 hwlim;		/* hardware subregion boundary */
-	u16 swbase;		/* software subregion offset */
-	u16 swlim;		/* software subregion boundary */
-	u16 fbase;		/* fuse subregion offset */
-	u16 flim;		/* fuse subregion boundary */
-	int otpgu_base;		/* offset to General Use Region */
-#endif				/* BCMIPXOTP */
-
-#ifdef BCMHNDOTP
-	/* HND OTP section */
-	uint size;		/* Size of otp in bytes */
-	uint hwprot;		/* Hardware protection bits */
-	uint signvalid;		/* Signature valid bits */
-	int boundary;		/* hw/sw boundary */
-#endif				/* BCMHNDOTP */
-} otpinfo_t;
-
-static otpinfo_t otpinfo;
-
-/*
- * IPX OTP Code
- *
- *   Exported functions:
- *	ipxotp_status()
- *	ipxotp_size()
- *	ipxotp_init()
- *	ipxotp_read_bit()
- *	ipxotp_read_region()
- *	ipxotp_nvread()
- *
- */
-
-#ifdef BCMIPXOTP
-
-#define HWSW_RGN(rgn)		(((rgn) == OTP_HW_RGN) ? "h/w" : "s/w")
-
-/* OTP layout */
-/* CC revs 21, 24 and 27 OTP General Use Region word offset */
-#define REVA4_OTPGU_BASE	12
-
-/* CC revs 23, 25, 26, 28 and above OTP General Use Region word offset */
-#define REVB8_OTPGU_BASE	20
-
-/* CC rev 36 OTP General Use Region word offset */
-#define REV36_OTPGU_BASE	12
-
-/* Subregion word offsets in General Use region */
-#define OTPGU_HSB_OFF		0
-#define OTPGU_SFB_OFF		1
-#define OTPGU_CI_OFF		2
-#define OTPGU_P_OFF		3
-#define OTPGU_SROM_OFF		4
-
-/* Flag bit offsets in General Use region  */
-#define OTPGU_HWP_OFF		60
-#define OTPGU_SWP_OFF		61
-#define OTPGU_CIP_OFF		62
-#define OTPGU_FUSEP_OFF		63
-#define OTPGU_CIP_MSK		0x4000
-#define OTPGU_P_MSK		0xf000
-#define OTPGU_P_SHIFT		(OTPGU_HWP_OFF % 16)
-
-/* OTP Size */
-#define OTP_SZ_FU_324		((roundup(324, 8))/8)	/* 324 bits */
-#define OTP_SZ_FU_288		(288/8)	/* 288 bits */
-#define OTP_SZ_FU_216		(216/8)	/* 216 bits */
-#define OTP_SZ_FU_72		(72/8)	/* 72 bits */
-#define OTP_SZ_CHECKSUM		(16/8)	/* 16 bits */
-#define OTP4315_SWREG_SZ	178	/* 178 bytes */
-#define OTP_SZ_FU_144		(144/8)	/* 144 bits */
-
-static int ipxotp_status(void *oh)
-{
-	otpinfo_t *oi = (otpinfo_t *) oh;
-	return (int)(oi->status);
-}
-
-/* Return size in bytes */
-static int ipxotp_size(void *oh)
-{
-	otpinfo_t *oi = (otpinfo_t *) oh;
-	return (int)oi->wsize * 2;
-}
-
-static u16 ipxotp_otpr(void *oh, chipcregs_t *cc, uint wn)
-{
-	otpinfo_t *oi;
-
-	oi = (otpinfo_t *) oh;
-
-	ASSERT(wn < oi->wsize);
-	ASSERT(cc != NULL);
-
-	return R_REG(&cc->sromotp[wn]);
-}
-
-static u16 ipxotp_read_bit(void *oh, chipcregs_t *cc, uint off)
-{
-	otpinfo_t *oi = (otpinfo_t *) oh;
-	uint k, row, col;
-	u32 otpp, st;
-
-	row = off / oi->cols;
-	col = off % oi->cols;
-
-	otpp = OTPP_START_BUSY |
-	    ((OTPPOC_READ << OTPP_OC_SHIFT) & OTPP_OC_MASK) |
-	    ((row << OTPP_ROW_SHIFT) & OTPP_ROW_MASK) |
-	    ((col << OTPP_COL_SHIFT) & OTPP_COL_MASK);
-	W_REG(&cc->otpprog, otpp);
-
-	for (k = 0;
-	     ((st = R_REG(&cc->otpprog)) & OTPP_START_BUSY)
-	     && (k < OTPP_TRIES); k++)
-		;
-	if (k >= OTPP_TRIES) {
-		return 0xffff;
-	}
-	if (st & OTPP_READERR) {
-		return 0xffff;
-	}
-	st = (st & OTPP_VALUE_MASK) >> OTPP_VALUE_SHIFT;
-
-	return (int)st;
-}
-
-/* Calculate max HW/SW region byte size by subtracting fuse region and checksum size,
- * osizew is oi->wsize (OTP size - GU size) in words
- */
-static int ipxotp_max_rgnsz(si_t *sih, int osizew)
-{
-	int ret = 0;
-
-	switch (sih->chip) {
-	case BCM43224_CHIP_ID:
-	case BCM43225_CHIP_ID:
-		ret = osizew * 2 - OTP_SZ_FU_72 - OTP_SZ_CHECKSUM;
-		break;
-	case BCM4313_CHIP_ID:
-		ret = osizew * 2 - OTP_SZ_FU_72 - OTP_SZ_CHECKSUM;
-		break;
-	default:
-		ASSERT(0);	/* Don't know about this chip */
-	}
-
-	return ret;
-}
-
-static void _ipxotp_init(otpinfo_t *oi, chipcregs_t *cc)
-{
-	uint k;
-	u32 otpp, st;
-
-	/* record word offset of General Use Region for various chipcommon revs */
-	if (oi->sih->ccrev == 21 || oi->sih->ccrev == 24
-	    || oi->sih->ccrev == 27) {
-		oi->otpgu_base = REVA4_OTPGU_BASE;
-	} else if (oi->sih->ccrev == 36) {
-		/* OTP size greater than equal to 2KB (128 words), otpgu_base is similar to rev23 */
-		if (oi->wsize >= 128)
-			oi->otpgu_base = REVB8_OTPGU_BASE;
-		else
-			oi->otpgu_base = REV36_OTPGU_BASE;
-	} else if (oi->sih->ccrev == 23 || oi->sih->ccrev >= 25) {
-		oi->otpgu_base = REVB8_OTPGU_BASE;
-	}
-
-	/* First issue an init command so the status is up to date */
-	otpp =
-	    OTPP_START_BUSY | ((OTPPOC_INIT << OTPP_OC_SHIFT) & OTPP_OC_MASK);
-
-	W_REG(&cc->otpprog, otpp);
-	for (k = 0;
-	     ((st = R_REG(&cc->otpprog)) & OTPP_START_BUSY)
-	     && (k < OTPP_TRIES); k++)
-		;
-	if (k >= OTPP_TRIES) {
-		return;
-	}
-
-	/* Read OTP lock bits and subregion programmed indication bits */
-	oi->status = R_REG(&cc->otpstatus);
-
-	if ((oi->sih->chip == BCM43224_CHIP_ID)
-	    || (oi->sih->chip == BCM43225_CHIP_ID)) {
-		u32 p_bits;
-		p_bits =
-		    (ipxotp_otpr(oi, cc, oi->otpgu_base + OTPGU_P_OFF) &
-		     OTPGU_P_MSK)
-		    >> OTPGU_P_SHIFT;
-		oi->status |= (p_bits << OTPS_GUP_SHIFT);
-	}
-
-	/*
-	 * h/w region base and fuse region limit are fixed to the top and
-	 * the bottom of the general use region. Everything else can be flexible.
-	 */
-	oi->hwbase = oi->otpgu_base + OTPGU_SROM_OFF;
-	oi->hwlim = oi->wsize;
-	if (oi->status & OTPS_GUP_HW) {
-		oi->hwlim =
-		    ipxotp_otpr(oi, cc, oi->otpgu_base + OTPGU_HSB_OFF) / 16;
-		oi->swbase = oi->hwlim;
-	} else
-		oi->swbase = oi->hwbase;
-
-	/* subtract fuse and checksum from beginning */
-	oi->swlim = ipxotp_max_rgnsz(oi->sih, oi->wsize) / 2;
-
-	if (oi->status & OTPS_GUP_SW) {
-		oi->swlim =
-		    ipxotp_otpr(oi, cc, oi->otpgu_base + OTPGU_SFB_OFF) / 16;
-		oi->fbase = oi->swlim;
-	} else
-		oi->fbase = oi->swbase;
-
-	oi->flim = oi->wsize;
-}
-
-static void *ipxotp_init(si_t *sih)
-{
-	uint idx;
-	chipcregs_t *cc;
-	otpinfo_t *oi;
-
-	/* Make sure we're running IPX OTP */
-	ASSERT(OTPTYPE_IPX(sih->ccrev));
-	if (!OTPTYPE_IPX(sih->ccrev))
-		return NULL;
-
-	/* Make sure OTP is not disabled */
-	if (si_is_otp_disabled(sih)) {
-		return NULL;
-	}
-
-	/* Make sure OTP is powered up */
-	if (!si_is_otp_powered(sih)) {
-		return NULL;
-	}
-
-	oi = &otpinfo;
-
-	/* Check for otp size */
-	switch ((sih->cccaps & CC_CAP_OTPSIZE) >> CC_CAP_OTPSIZE_SHIFT) {
-	case 0:
-		/* Nothing there */
-		return NULL;
-	case 1:		/* 32x64 */
-		oi->rows = 32;
-		oi->cols = 64;
-		oi->wsize = 128;
-		break;
-	case 2:		/* 64x64 */
-		oi->rows = 64;
-		oi->cols = 64;
-		oi->wsize = 256;
-		break;
-	case 5:		/* 96x64 */
-		oi->rows = 96;
-		oi->cols = 64;
-		oi->wsize = 384;
-		break;
-	case 7:		/* 16x64 *//* 1024 bits */
-		oi->rows = 16;
-		oi->cols = 64;
-		oi->wsize = 64;
-		break;
-	default:
-		/* Don't know the geometry */
-		return NULL;
-	}
-
-	/* Retrieve OTP region info */
-	idx = si_coreidx(sih);
-	cc = si_setcoreidx(sih, SI_CC_IDX);
-	ASSERT(cc != NULL);
-
-	_ipxotp_init(oi, cc);
-
-	si_setcoreidx(sih, idx);
-
-	return (void *)oi;
-}
-
-static int ipxotp_read_region(void *oh, int region, u16 *data, uint *wlen)
-{
-	otpinfo_t *oi = (otpinfo_t *) oh;
-	uint idx;
-	chipcregs_t *cc;
-	uint base, i, sz;
-
-	/* Validate region selection */
-	switch (region) {
-	case OTP_HW_RGN:
-		sz = (uint) oi->hwlim - oi->hwbase;
-		if (!(oi->status & OTPS_GUP_HW)) {
-			*wlen = sz;
-			return BCME_NOTFOUND;
-		}
-		if (*wlen < sz) {
-			*wlen = sz;
-			return BCME_BUFTOOSHORT;
-		}
-		base = oi->hwbase;
-		break;
-	case OTP_SW_RGN:
-		sz = ((uint) oi->swlim - oi->swbase);
-		if (!(oi->status & OTPS_GUP_SW)) {
-			*wlen = sz;
-			return BCME_NOTFOUND;
-		}
-		if (*wlen < sz) {
-			*wlen = sz;
-			return BCME_BUFTOOSHORT;
-		}
-		base = oi->swbase;
-		break;
-	case OTP_CI_RGN:
-		sz = OTPGU_CI_SZ;
-		if (!(oi->status & OTPS_GUP_CI)) {
-			*wlen = sz;
-			return BCME_NOTFOUND;
-		}
-		if (*wlen < sz) {
-			*wlen = sz;
-			return BCME_BUFTOOSHORT;
-		}
-		base = oi->otpgu_base + OTPGU_CI_OFF;
-		break;
-	case OTP_FUSE_RGN:
-		sz = (uint) oi->flim - oi->fbase;
-		if (!(oi->status & OTPS_GUP_FUSE)) {
-			*wlen = sz;
-			return BCME_NOTFOUND;
-		}
-		if (*wlen < sz) {
-			*wlen = sz;
-			return BCME_BUFTOOSHORT;
-		}
-		base = oi->fbase;
-		break;
-	case OTP_ALL_RGN:
-		sz = ((uint) oi->flim - oi->hwbase);
-		if (!(oi->status & (OTPS_GUP_HW | OTPS_GUP_SW))) {
-			*wlen = sz;
-			return BCME_NOTFOUND;
-		}
-		if (*wlen < sz) {
-			*wlen = sz;
-			return BCME_BUFTOOSHORT;
-		}
-		base = oi->hwbase;
-		break;
-	default:
-		return BCME_BADARG;
-	}
-
-	idx = si_coreidx(oi->sih);
-	cc = si_setcoreidx(oi->sih, SI_CC_IDX);
-	ASSERT(cc != NULL);
-
-	/* Read the data */
-	for (i = 0; i < sz; i++)
-		data[i] = ipxotp_otpr(oh, cc, base + i);
-
-	si_setcoreidx(oi->sih, idx);
-	*wlen = sz;
-	return 0;
-}
-
-static int ipxotp_nvread(void *oh, char *data, uint *len)
-{
-	return BCME_UNSUPPORTED;
-}
-
-static otp_fn_t ipxotp_fn = {
-	(otp_size_t) ipxotp_size,
-	(otp_read_bit_t) ipxotp_read_bit,
-
-	(otp_init_t) ipxotp_init,
-	(otp_read_region_t) ipxotp_read_region,
-	(otp_nvread_t) ipxotp_nvread,
-
-	(otp_status_t) ipxotp_status
-};
-
-#endif				/* BCMIPXOTP */
-
-/*
- * HND OTP Code
- *
- *   Exported functions:
- *	hndotp_status()
- *	hndotp_size()
- *	hndotp_init()
- *	hndotp_read_bit()
- *	hndotp_read_region()
- *	hndotp_nvread()
- *
- */
-
-#ifdef BCMHNDOTP
-
-/* Fields in otpstatus */
-#define	OTPS_PROGFAIL		0x80000000
-#define	OTPS_PROTECT		0x00000007
-#define	OTPS_HW_PROTECT		0x00000001
-#define	OTPS_SW_PROTECT		0x00000002
-#define	OTPS_CID_PROTECT	0x00000004
-#define	OTPS_RCEV_MSK		0x00003f00
-#define	OTPS_RCEV_SHIFT		8
-
-/* Fields in the otpcontrol register */
-#define	OTPC_RECWAIT		0xff000000
-#define	OTPC_PROGWAIT		0x00ffff00
-#define	OTPC_PRW_SHIFT		8
-#define	OTPC_MAXFAIL		0x00000038
-#define	OTPC_VSEL		0x00000006
-#define	OTPC_SELVL		0x00000001
-
-/* OTP regions (Word offsets from otp size) */
-#define	OTP_SWLIM_OFF	(-4)
-#define	OTP_CIDBASE_OFF	0
-#define	OTP_CIDLIM_OFF	4
-
-/* Predefined OTP words (Word offset from otp size) */
-#define	OTP_BOUNDARY_OFF (-4)
-#define	OTP_HWSIGN_OFF	(-3)
-#define	OTP_SWSIGN_OFF	(-2)
-#define	OTP_CIDSIGN_OFF	(-1)
-#define	OTP_CID_OFF	0
-#define	OTP_PKG_OFF	1
-#define	OTP_FID_OFF	2
-#define	OTP_RSV_OFF	3
-#define	OTP_LIM_OFF	4
-#define	OTP_RD_OFF	4	/* Redundancy row starts here */
-#define	OTP_RC0_OFF	28	/* Redundancy control word 1 */
-#define	OTP_RC1_OFF	32	/* Redundancy control word 2 */
-#define	OTP_RC_LIM_OFF	36	/* Redundancy control word end */
-
-#define	OTP_HW_REGION	OTPS_HW_PROTECT
-#define	OTP_SW_REGION	OTPS_SW_PROTECT
-#define	OTP_CID_REGION	OTPS_CID_PROTECT
-
-#if OTP_HW_REGION != OTP_HW_RGN
-#error "incompatible OTP_HW_RGN"
-#endif
-#if OTP_SW_REGION != OTP_SW_RGN
-#error "incompatible OTP_SW_RGN"
-#endif
-#if OTP_CID_REGION != OTP_CI_RGN
-#error "incompatible OTP_CI_RGN"
-#endif
-
-/* Redundancy entry definitions */
-#define	OTP_RCE_ROW_SZ		6
-#define	OTP_RCE_SIGN_MASK	0x7fff
-#define	OTP_RCE_ROW_MASK	0x3f
-#define	OTP_RCE_BITS		21
-#define	OTP_RCE_SIGN_SZ		15
-#define	OTP_RCE_BIT0		1
-
-#define	OTP_WPR		4
-#define	OTP_SIGNATURE	0x578a
-#define	OTP_MAGIC	0x4e56
-
-static int hndotp_status(void *oh)
-{
-	otpinfo_t *oi = (otpinfo_t *) oh;
-	return (int)(oi->hwprot | oi->signvalid);
-}
-
-static int hndotp_size(void *oh)
-{
-	otpinfo_t *oi = (otpinfo_t *) oh;
-	return (int)(oi->size);
-}
-
-static u16 hndotp_otpr(void *oh, chipcregs_t *cc, uint wn)
-{
-#ifdef BCMDBG
-	otpinfo_t *oi = (otpinfo_t *) oh;
-#endif
-	volatile u16 *ptr;
-
-	ASSERT(wn < ((oi->size / 2) + OTP_RC_LIM_OFF));
-	ASSERT(cc != NULL);
-
-	ptr = (volatile u16 *)((volatile char *)cc + CC_SROM_OTP);
-	return R_REG(&ptr[wn]);
-}
-
-static u16 hndotp_otproff(void *oh, chipcregs_t *cc, int woff)
-{
-	otpinfo_t *oi = (otpinfo_t *) oh;
-	volatile u16 *ptr;
-
-	ASSERT(woff >= (-((int)oi->size / 2)));
-	ASSERT(woff < OTP_LIM_OFF);
-	ASSERT(cc != NULL);
-
-	ptr = (volatile u16 *)((volatile char *)cc + CC_SROM_OTP);
-
-	return R_REG(&ptr[(oi->size / 2) + woff]);
-}
-
-static u16 hndotp_read_bit(void *oh, chipcregs_t *cc, uint idx)
-{
-	uint k, row, col;
-	u32 otpp, st;
-
-	row = idx / 65;
-	col = idx % 65;
-
-	otpp = OTPP_START_BUSY | OTPP_READ |
-	    ((row << OTPP_ROW_SHIFT) & OTPP_ROW_MASK) | (col & OTPP_COL_MASK);
-
-	W_REG(&cc->otpprog, otpp);
-	st = R_REG(&cc->otpprog);
-	for (k = 0;
-	     ((st & OTPP_START_BUSY) == OTPP_START_BUSY) && (k < OTPP_TRIES);
-	     k++)
-		st = R_REG(&cc->otpprog);
-
-	if (k >= OTPP_TRIES) {
-		return 0xffff;
-	}
-	if (st & OTPP_READERR) {
-		return 0xffff;
-	}
-	st = (st & OTPP_VALUE_MASK) >> OTPP_VALUE_SHIFT;
-	return (u16) st;
-}
-
-static void *hndotp_init(si_t *sih)
-{
-	uint idx;
-	chipcregs_t *cc;
-	otpinfo_t *oi;
-	u32 cap = 0, clkdiv, otpdiv = 0;
-	void *ret = NULL;
-
-	oi = &otpinfo;
-
-	idx = si_coreidx(sih);
-
-	/* Check for otp */
-	cc = si_setcoreidx(sih, SI_CC_IDX);
-	if (cc != NULL) {
-		cap = R_REG(&cc->capabilities);
-		if ((cap & CC_CAP_OTPSIZE) == 0) {
-			/* Nothing there */
-			goto out;
-		}
-
-		/* As of right now, support only 4320a2, 4311a1 and 4312 */
-		ASSERT((oi->ccrev == 12) || (oi->ccrev == 17)
-		       || (oi->ccrev == 22));
-		if (!
-		    ((oi->ccrev == 12) || (oi->ccrev == 17)
-		     || (oi->ccrev == 22)))
-			return NULL;
-
-		/* Read the OTP byte size. chipcommon rev >= 18 has RCE so the size is
-		 * 8 row (64 bytes) smaller
-		 */
-		oi->size =
-		    1 << (((cap & CC_CAP_OTPSIZE) >> CC_CAP_OTPSIZE_SHIFT)
-			  + CC_CAP_OTPSIZE_BASE);
-		if (oi->ccrev >= 18)
-			oi->size -= ((OTP_RC0_OFF - OTP_BOUNDARY_OFF) * 2);
-
-		oi->hwprot = (int)(R_REG(&cc->otpstatus) & OTPS_PROTECT);
-		oi->boundary = -1;
-
-		/* Check the region signature */
-		if (hndotp_otproff(oi, cc, OTP_HWSIGN_OFF) == OTP_SIGNATURE) {
-			oi->signvalid |= OTP_HW_REGION;
-			oi->boundary = hndotp_otproff(oi, cc, OTP_BOUNDARY_OFF);
-		}
-
-		if (hndotp_otproff(oi, cc, OTP_SWSIGN_OFF) == OTP_SIGNATURE)
-			oi->signvalid |= OTP_SW_REGION;
-
-		if (hndotp_otproff(oi, cc, OTP_CIDSIGN_OFF) == OTP_SIGNATURE)
-			oi->signvalid |= OTP_CID_REGION;
-
-		/* Set OTP clkdiv for stability */
-		if (oi->ccrev == 22)
-			otpdiv = 12;
-
-		if (otpdiv) {
-			clkdiv = R_REG(&cc->clkdiv);
-			clkdiv =
-			    (clkdiv & ~CLKD_OTP) | (otpdiv << CLKD_OTP_SHIFT);
-			W_REG(&cc->clkdiv, clkdiv);
-		}
-		udelay(10);
-
-		ret = (void *)oi;
-	}
-
- out:				/* All done */
-	si_setcoreidx(sih, idx);
-
-	return ret;
-}
-
-static int hndotp_read_region(void *oh, int region, u16 *data, uint *wlen)
-{
-	otpinfo_t *oi = (otpinfo_t *) oh;
-	u32 idx, st;
-	chipcregs_t *cc;
-	int i;
-
-	/* Only support HW region (no active chips use HND OTP SW region) */
-	ASSERT(region == OTP_HW_REGION);
-
-	/* Region empty? */
-	st = oi->hwprot | oi->signvalid;
-	if ((st & region) == 0)
-		return BCME_NOTFOUND;
-
-	*wlen =
-	    ((int)*wlen < oi->boundary / 2) ? *wlen : (uint) oi->boundary / 2;
-
-	idx = si_coreidx(oi->sih);
-	cc = si_setcoreidx(oi->sih, SI_CC_IDX);
-	ASSERT(cc != NULL);
-
-	for (i = 0; i < (int)*wlen; i++)
-		data[i] = hndotp_otpr(oh, cc, i);
-
-	si_setcoreidx(oi->sih, idx);
-
-	return 0;
-}
-
-static int hndotp_nvread(void *oh, char *data, uint *len)
-{
-	int rc = 0;
-	otpinfo_t *oi = (otpinfo_t *) oh;
-	u32 base, bound, lim = 0, st;
-	int i, chunk, gchunks, tsz = 0;
-	u32 idx;
-	chipcregs_t *cc;
-	uint offset;
-	u16 *rawotp = NULL;
-
-	/* save the orig core */
-	idx = si_coreidx(oi->sih);
-	cc = si_setcoreidx(oi->sih, SI_CC_IDX);
-	ASSERT(cc != NULL);
-
-	st = hndotp_status(oh);
-	if (!(st & (OTP_HW_REGION | OTP_SW_REGION))) {
-		rc = -1;
-		goto out;
-	}
-
-	/* Read the whole otp so we can easily manipulate it */
-	lim = hndotp_size(oh);
-	rawotp = kmalloc(lim, GFP_ATOMIC);
-	if (rawotp == NULL) {
-		rc = -2;
-		goto out;
-	}
-	for (i = 0; i < (int)(lim / 2); i++)
-		rawotp[i] = hndotp_otpr(oh, cc, i);
-
-	if ((st & OTP_HW_REGION) == 0) {
-		/* This could be a programming failure in the first
-		 * chunk followed by one or more good chunks
-		 */
-		for (i = 0; i < (int)(lim / 2); i++)
-			if (rawotp[i] == OTP_MAGIC)
-				break;
-
-		if (i < (int)(lim / 2)) {
-			base = i;
-			bound = (i * 2) + rawotp[i + 1];
-		} else {
-			rc = -3;
-			goto out;
-		}
-	} else {
-		bound = rawotp[(lim / 2) + OTP_BOUNDARY_OFF];
-
-		/* There are two cases: 1) The whole otp is used as nvram
-		 * and 2) There is a hardware header followed by nvram.
-		 */
-		if (rawotp[0] == OTP_MAGIC) {
-			base = 0;
-		} else
-			base = bound;
-	}
-
-	/* Find and copy the data */
-
-	chunk = 0;
-	gchunks = 0;
-	i = base / 2;
-	offset = 0;
-	while ((i < (int)(lim / 2)) && (rawotp[i] == OTP_MAGIC)) {
-		int dsz, rsz = rawotp[i + 1];
-
-		if (((i * 2) + rsz) >= (int)lim) {
-			/* Bad length, try to find another chunk anyway */
-			rsz = 6;
-		}
-		if (hndcrc16((u8 *) &rawotp[i], rsz,
-			     CRC16_INIT_VALUE) == CRC16_GOOD_VALUE) {
-			/* Good crc, copy the vars */
-			gchunks++;
-			dsz = rsz - 6;
-			tsz += dsz;
-			if (offset + dsz >= *len) {
-				goto out;
-			}
-			memcpy(&data[offset], &rawotp[i + 2], dsz);
-			offset += dsz;
-			/* Remove extra null characters at the end */
-			while (offset > 1 &&
-			       data[offset - 1] == 0 && data[offset - 2] == 0)
-				offset--;
-			i += rsz / 2;
-		} else {
-			/* bad length or crc didn't check, try to find the next set */
-			if (rawotp[i + (rsz / 2)] == OTP_MAGIC) {
-				/* Assume length is good */
-				i += rsz / 2;
-			} else {
-				while (++i < (int)(lim / 2))
-					if (rawotp[i] == OTP_MAGIC)
-						break;
-			}
-		}
-		chunk++;
-	}
-
-	*len = offset;
-
- out:
-	kfree(rawotp);
-	si_setcoreidx(oi->sih, idx);
-
-	return rc;
-}
-
-static otp_fn_t hndotp_fn = {
-	(otp_size_t) hndotp_size,
-	(otp_read_bit_t) hndotp_read_bit,
-
-	(otp_init_t) hndotp_init,
-	(otp_read_region_t) hndotp_read_region,
-	(otp_nvread_t) hndotp_nvread,
-
-	(otp_status_t) hndotp_status
-};
-
-#endif				/* BCMHNDOTP */
-
-/*
- * Common Code: Compiled for IPX / HND / AUTO
- *	otp_status()
- *	otp_size()
- *	otp_read_bit()
- *	otp_init()
- * 	otp_read_region()
- * 	otp_nvread()
- */
-
-int otp_status(void *oh)
-{
-	otpinfo_t *oi = (otpinfo_t *) oh;
-
-	return oi->fn->status(oh);
-}
-
-int otp_size(void *oh)
-{
-	otpinfo_t *oi = (otpinfo_t *) oh;
-
-	return oi->fn->size(oh);
-}
-
-u16 otp_read_bit(void *oh, uint offset)
-{
-	otpinfo_t *oi = (otpinfo_t *) oh;
-	uint idx = si_coreidx(oi->sih);
-	chipcregs_t *cc = si_setcoreidx(oi->sih, SI_CC_IDX);
-	u16 readBit = (u16) oi->fn->read_bit(oh, cc, offset);
-	si_setcoreidx(oi->sih, idx);
-	return readBit;
-}
-
-void *otp_init(si_t *sih)
-{
-	otpinfo_t *oi;
-	void *ret = NULL;
-
-	oi = &otpinfo;
-	memset(oi, 0, sizeof(otpinfo_t));
-
-	oi->ccrev = sih->ccrev;
-
-#ifdef BCMIPXOTP
-	if (OTPTYPE_IPX(oi->ccrev))
-		oi->fn = &ipxotp_fn;
-#endif
-
-#ifdef BCMHNDOTP
-	if (OTPTYPE_HND(oi->ccrev))
-		oi->fn = &hndotp_fn;
-#endif
-
-	if (oi->fn == NULL) {
-		return NULL;
-	}
-
-	oi->sih = sih;
-
-	ret = (oi->fn->init) (sih);
-
-	return ret;
-}
-
-int
-otp_read_region(si_t *sih, int region, u16 *data,
-				 uint *wlen) {
-	bool wasup = false;
-	void *oh;
-	int err = 0;
-
-	wasup = si_is_otp_powered(sih);
-	if (!wasup)
-		si_otp_power(sih, true);
-
-	if (!si_is_otp_powered(sih) || si_is_otp_disabled(sih)) {
-		err = BCME_NOTREADY;
-		goto out;
-	}
-
-	oh = otp_init(sih);
-	if (oh == NULL) {
-		err = BCME_ERROR;
-		goto out;
-	}
-
-	err = (((otpinfo_t *) oh)->fn->read_region) (oh, region, data, wlen);
-
- out:
-	if (!wasup)
-		si_otp_power(sih, false);
-
-	return err;
-}
-
-int otp_nvread(void *oh, char *data, uint *len)
-{
-	otpinfo_t *oi = (otpinfo_t *) oh;
-
-	return oi->fn->nvread(oh, data, len);
-}
diff -druN linux-2.6.39-libre/drivers/staging/brcm80211/util/bcmsrom.c linux-3.0-rc7-libre/drivers/staging/brcm80211/util/bcmsrom.c
--- linux-2.6.39-libre/drivers/staging/brcm80211/util/bcmsrom.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/brcm80211/util/bcmsrom.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,2088 +0,0 @@
-/*
- * Copyright (c) 2010 Broadcom Corporation
- *
- * 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/kernel.h>
-#include <linux/string.h>
-#include <linux/etherdevice.h>
-#include <bcmdefs.h>
-#include <linux/module.h>
-#include <linux/pci.h>
-#include <stdarg.h>
-#include <bcmutils.h>
-#include <hndsoc.h>
-#include <sbchipc.h>
-#include <bcmdevs.h>
-#include <pcicfg.h>
-#include <siutils.h>
-#include <bcmsrom.h>
-#include <bcmsrom_tbl.h>
-#ifdef BCMSDIO
-#include <bcmsdh.h>
-#include <sdio.h>
-#endif
-
-#include <bcmnvram.h>
-#include <bcmotp.h>
-
-#if defined(BCMSDIO)
-#include <sbsdio.h>
-#include <sbhnddma.h>
-#include <sbsdpcmdev.h>
-#endif
-
-#include <linux/if_ether.h>
-
-#define	BS_ERROR(args)
-
-#define SROM_OFFSET(sih) ((sih->ccrev > 31) ? \
-	(((sih->cccaps & CC_CAP_SROM) == 0) ? NULL : \
-	 ((u8 *)curmap + PCI_16KB0_CCREGS_OFFSET + CC_SROM_OTP)) : \
-	((u8 *)curmap + PCI_BAR0_SPROM_OFFSET))
-
-#if defined(BCMDBG)
-#define WRITE_ENABLE_DELAY	500	/* 500 ms after write enable/disable toggle */
-#define WRITE_WORD_DELAY	20	/* 20 ms between each word write */
-#endif
-
-typedef struct varbuf {
-	char *base;		/* pointer to buffer base */
-	char *buf;		/* pointer to current position */
-	unsigned int size;	/* current (residual) size in bytes */
-} varbuf_t;
-extern char *_vars;
-extern uint _varsz;
-
-#define SROM_CIS_SINGLE	1
-
-static int initvars_srom_si(si_t *sih, void *curmap, char **vars, uint *count);
-static void _initvars_srom_pci(u8 sromrev, u16 *srom, uint off, varbuf_t *b);
-static int initvars_srom_pci(si_t *sih, void *curmap, char **vars, uint *count);
-static int initvars_flash_si(si_t *sih, char **vars, uint *count);
-#ifdef BCMSDIO
-static int initvars_cis_sdio(char **vars, uint *count);
-static int sprom_cmd_sdio(u8 cmd);
-static int sprom_read_sdio(u16 addr, u16 *data);
-#endif				/* BCMSDIO */
-static int sprom_read_pci(si_t *sih, u16 *sprom,
-			  uint wordoff, u16 *buf, uint nwords, bool check_crc);
-#if defined(BCMNVRAMR)
-static int otp_read_pci(si_t *sih, u16 *buf, uint bufsz);
-#endif
-static u16 srom_cc_cmd(si_t *sih, void *ccregs, u32 cmd,
-			  uint wordoff, u16 data);
-
-static int initvars_table(char *start, char *end,
-			  char **vars, uint *count);
-static int initvars_flash(si_t *sih, char **vp,
-			  uint len);
-
-/* Initialization of varbuf structure */
-static void varbuf_init(varbuf_t *b, char *buf, uint size)
-{
-	b->size = size;
-	b->base = b->buf = buf;
-}
-
-/* append a null terminated var=value string */
-static int varbuf_append(varbuf_t *b, const char *fmt, ...)
-{
-	va_list ap;
-	int r;
-	size_t len;
-	char *s;
-
-	if (b->size < 2)
-		return 0;
-
-	va_start(ap, fmt);
-	r = vsnprintf(b->buf, b->size, fmt, ap);
-	va_end(ap);
-
-	/* C99 snprintf behavior returns r >= size on overflow,
-	 * others return -1 on overflow.
-	 * All return -1 on format error.
-	 * We need to leave room for 2 null terminations, one for the current var
-	 * string, and one for final null of the var table. So check that the
-	 * strlen written, r, leaves room for 2 chars.
-	 */
-	if ((r == -1) || (r > (int)(b->size - 2))) {
-		b->size = 0;
-		return 0;
-	}
-
-	/* Remove any earlier occurrence of the same variable */
-	s = strchr(b->buf, '=');
-	if (s != NULL) {
-		len = (size_t) (s - b->buf);
-		for (s = b->base; s < b->buf;) {
-			if ((memcmp(s, b->buf, len) == 0) && s[len] == '=') {
-				len = strlen(s) + 1;
-				memmove(s, (s + len),
-					((b->buf + r + 1) - (s + len)));
-				b->buf -= len;
-				b->size += (unsigned int)len;
-				break;
-			}
-
-			while (*s++)
-				;
-		}
-	}
-
-	/* skip over this string's null termination */
-	r++;
-	b->size -= r;
-	b->buf += r;
-
-	return r;
-}
-
-/*
- * Initialize local vars from the right source for this platform.
- * Return 0 on success, nonzero on error.
- */
-int srom_var_init(si_t *sih, uint bustype, void *curmap,
-		  char **vars, uint *count)
-{
-	uint len;
-
-	len = 0;
-
-	ASSERT(bustype == bustype);
-	if (vars == NULL || count == NULL)
-		return 0;
-
-	*vars = NULL;
-	*count = 0;
-
-	switch (bustype) {
-	case SI_BUS:
-	case JTAG_BUS:
-		return initvars_srom_si(sih, curmap, vars, count);
-
-	case PCI_BUS:
-		ASSERT(curmap != NULL);
-		if (curmap == NULL)
-			return -1;
-
-		return initvars_srom_pci(sih, curmap, vars, count);
-
-#ifdef BCMSDIO
-	case SDIO_BUS:
-		return initvars_cis_sdio(vars, count);
-#endif				/* BCMSDIO */
-
-	default:
-		ASSERT(0);
-	}
-	return -1;
-}
-
-/* support only 16-bit word read from srom */
-int
-srom_read(si_t *sih, uint bustype, void *curmap,
-	  uint byteoff, uint nbytes, u16 *buf, bool check_crc)
-{
-	uint off, nw;
-#ifdef BCMSDIO
-	uint i;
-#endif				/* BCMSDIO */
-
-	ASSERT(bustype == bustype);
-
-	/* check input - 16-bit access only */
-	if (byteoff & 1 || nbytes & 1 || (byteoff + nbytes) > SROM_MAX)
-		return 1;
-
-	off = byteoff / 2;
-	nw = nbytes / 2;
-
-	if (bustype == PCI_BUS) {
-		if (!curmap)
-			return 1;
-
-		if (si_is_sprom_available(sih)) {
-			u16 *srom;
-
-			srom = (u16 *) SROM_OFFSET(sih);
-			if (srom == NULL)
-				return 1;
-
-			if (sprom_read_pci
-			    (sih, srom, off, buf, nw, check_crc))
-				return 1;
-		}
-#if defined(BCMNVRAMR)
-		else {
-			if (otp_read_pci(sih, buf, SROM_MAX))
-				return 1;
-		}
-#endif
-#ifdef BCMSDIO
-	} else if (bustype == SDIO_BUS) {
-		off = byteoff / 2;
-		nw = nbytes / 2;
-		for (i = 0; i < nw; i++) {
-			if (sprom_read_sdio
-			    ((u16) (off + i), (u16 *) (buf + i)))
-				return 1;
-		}
-#endif				/* BCMSDIO */
-	} else if (bustype == SI_BUS) {
-		return 1;
-	} else {
-		return 1;
-	}
-
-	return 0;
-}
-
-static const char vstr_manf[] = "manf=%s";
-static const char vstr_productname[] = "productname=%s";
-static const char vstr_manfid[] = "manfid=0x%x";
-static const char vstr_prodid[] = "prodid=0x%x";
-#ifdef BCMSDIO
-static const char vstr_sdmaxspeed[] = "sdmaxspeed=%d";
-static const char vstr_sdmaxblk[][13] = {
-"sdmaxblk0=%d", "sdmaxblk1=%d", "sdmaxblk2=%d"};
-#endif
-static const char vstr_regwindowsz[] = "regwindowsz=%d";
-static const char vstr_sromrev[] = "sromrev=%d";
-static const char vstr_chiprev[] = "chiprev=%d";
-static const char vstr_subvendid[] = "subvendid=0x%x";
-static const char vstr_subdevid[] = "subdevid=0x%x";
-static const char vstr_boardrev[] = "boardrev=0x%x";
-static const char vstr_aa2g[] = "aa2g=0x%x";
-static const char vstr_aa5g[] = "aa5g=0x%x";
-static const char vstr_ag[] = "ag%d=0x%x";
-static const char vstr_cc[] = "cc=%d";
-static const char vstr_opo[] = "opo=%d";
-static const char vstr_pa0b[][9] = {
-"pa0b0=%d", "pa0b1=%d", "pa0b2=%d"};
-
-static const char vstr_pa0itssit[] = "pa0itssit=%d";
-static const char vstr_pa0maxpwr[] = "pa0maxpwr=%d";
-static const char vstr_pa1b[][9] = {
-"pa1b0=%d", "pa1b1=%d", "pa1b2=%d"};
-
-static const char vstr_pa1lob[][11] = {
-"pa1lob0=%d", "pa1lob1=%d", "pa1lob2=%d"};
-
-static const char vstr_pa1hib[][11] = {
-"pa1hib0=%d", "pa1hib1=%d", "pa1hib2=%d"};
-
-static const char vstr_pa1itssit[] = "pa1itssit=%d";
-static const char vstr_pa1maxpwr[] = "pa1maxpwr=%d";
-static const char vstr_pa1lomaxpwr[] = "pa1lomaxpwr=%d";
-static const char vstr_pa1himaxpwr[] = "pa1himaxpwr=%d";
-static const char vstr_oem[] =
-    "oem=%02x%02x%02x%02x%02x%02x%02x%02x";
-static const char vstr_boardflags[] = "boardflags=0x%x";
-static const char vstr_boardflags2[] = "boardflags2=0x%x";
-static const char vstr_ledbh[] = "ledbh%d=0x%x";
-static const char vstr_noccode[] = "ccode=0x0";
-static const char vstr_ccode[] = "ccode=%c%c";
-static const char vstr_cctl[] = "cctl=0x%x";
-static const char vstr_cckpo[] = "cckpo=0x%x";
-static const char vstr_ofdmpo[] = "ofdmpo=0x%x";
-static const char vstr_rdlid[] = "rdlid=0x%x";
-static const char vstr_rdlrndis[] = "rdlrndis=%d";
-static const char vstr_rdlrwu[] = "rdlrwu=%d";
-static const char vstr_usbfs[] = "usbfs=%d";
-static const char vstr_wpsgpio[] = "wpsgpio=%d";
-static const char vstr_wpsled[] = "wpsled=%d";
-static const char vstr_rdlsn[] = "rdlsn=%d";
-static const char vstr_rssismf2g[] = "rssismf2g=%d";
-static const char vstr_rssismc2g[] = "rssismc2g=%d";
-static const char vstr_rssisav2g[] = "rssisav2g=%d";
-static const char vstr_bxa2g[] = "bxa2g=%d";
-static const char vstr_rssismf5g[] = "rssismf5g=%d";
-static const char vstr_rssismc5g[] = "rssismc5g=%d";
-static const char vstr_rssisav5g[] = "rssisav5g=%d";
-static const char vstr_bxa5g[] = "bxa5g=%d";
-static const char vstr_tri2g[] = "tri2g=%d";
-static const char vstr_tri5gl[] = "tri5gl=%d";
-static const char vstr_tri5g[] = "tri5g=%d";
-static const char vstr_tri5gh[] = "tri5gh=%d";
-static const char vstr_rxpo2g[] = "rxpo2g=%d";
-static const char vstr_rxpo5g[] = "rxpo5g=%d";
-static const char vstr_boardtype[] = "boardtype=0x%x";
-static const char vstr_leddc[] = "leddc=0x%04x";
-static const char vstr_vendid[] = "vendid=0x%x";
-static const char vstr_devid[] = "devid=0x%x";
-static const char vstr_xtalfreq[] = "xtalfreq=%d";
-static const char vstr_txchain[] = "txchain=0x%x";
-static const char vstr_rxchain[] = "rxchain=0x%x";
-static const char vstr_antswitch[] = "antswitch=0x%x";
-static const char vstr_regrev[] = "regrev=0x%x";
-static const char vstr_antswctl2g[] = "antswctl2g=0x%x";
-static const char vstr_triso2g[] = "triso2g=0x%x";
-static const char vstr_pdetrange2g[] = "pdetrange2g=0x%x";
-static const char vstr_extpagain2g[] = "extpagain2g=0x%x";
-static const char vstr_tssipos2g[] = "tssipos2g=0x%x";
-static const char vstr_antswctl5g[] = "antswctl5g=0x%x";
-static const char vstr_triso5g[] = "triso5g=0x%x";
-static const char vstr_pdetrange5g[] = "pdetrange5g=0x%x";
-static const char vstr_extpagain5g[] = "extpagain5g=0x%x";
-static const char vstr_tssipos5g[] = "tssipos5g=0x%x";
-static const char vstr_maxp2ga0[] = "maxp2ga0=0x%x";
-static const char vstr_itt2ga0[] = "itt2ga0=0x%x";
-static const char vstr_pa[] = "pa%dgw%da%d=0x%x";
-static const char vstr_pahl[] = "pa%dg%cw%da%d=0x%x";
-static const char vstr_maxp5ga0[] = "maxp5ga0=0x%x";
-static const char vstr_itt5ga0[] = "itt5ga0=0x%x";
-static const char vstr_maxp5gha0[] = "maxp5gha0=0x%x";
-static const char vstr_maxp5gla0[] = "maxp5gla0=0x%x";
-static const char vstr_maxp2ga1[] = "maxp2ga1=0x%x";
-static const char vstr_itt2ga1[] = "itt2ga1=0x%x";
-static const char vstr_maxp5ga1[] = "maxp5ga1=0x%x";
-static const char vstr_itt5ga1[] = "itt5ga1=0x%x";
-static const char vstr_maxp5gha1[] = "maxp5gha1=0x%x";
-static const char vstr_maxp5gla1[] = "maxp5gla1=0x%x";
-static const char vstr_cck2gpo[] = "cck2gpo=0x%x";
-static const char vstr_ofdm2gpo[] = "ofdm2gpo=0x%x";
-static const char vstr_ofdm5gpo[] = "ofdm5gpo=0x%x";
-static const char vstr_ofdm5glpo[] = "ofdm5glpo=0x%x";
-static const char vstr_ofdm5ghpo[] = "ofdm5ghpo=0x%x";
-static const char vstr_cddpo[] = "cddpo=0x%x";
-static const char vstr_stbcpo[] = "stbcpo=0x%x";
-static const char vstr_bw40po[] = "bw40po=0x%x";
-static const char vstr_bwduppo[] = "bwduppo=0x%x";
-static const char vstr_mcspo[] = "mcs%dgpo%d=0x%x";
-static const char vstr_mcspohl[] = "mcs%dg%cpo%d=0x%x";
-static const char vstr_custom[] = "customvar%d=0x%x";
-static const char vstr_cckdigfilttype[] = "cckdigfilttype=%d";
-static const char vstr_boardnum[] = "boardnum=%d";
-static const char vstr_macaddr[] = "macaddr=%s";
-static const char vstr_usbepnum[] = "usbepnum=0x%x";
-static const char vstr_end[] = "END\0";
-
-u8 patch_pair;
-
-/* For dongle HW, accept partial calibration parameters */
-#define BCMDONGLECASE(n)
-
-int srom_parsecis(u8 *pcis[], uint ciscnt, char **vars,
-		  uint *count)
-{
-	char eabuf[32];
-	char *base;
-	varbuf_t b;
-	u8 *cis, tup, tlen, sromrev = 1;
-	int i, j;
-	bool ag_init = false;
-	u32 w32;
-	uint funcid;
-	uint cisnum;
-	s32 boardnum;
-	int err;
-	bool standard_cis;
-
-	ASSERT(vars != NULL);
-	ASSERT(count != NULL);
-
-	boardnum = -1;
-
-	base = kmalloc(MAXSZ_NVRAM_VARS, GFP_ATOMIC);
-	ASSERT(base != NULL);
-	if (!base)
-		return -2;
-
-	varbuf_init(&b, base, MAXSZ_NVRAM_VARS);
-	memset(base, 0, MAXSZ_NVRAM_VARS);
-	eabuf[0] = '\0';
-	for (cisnum = 0; cisnum < ciscnt; cisnum++) {
-		cis = *pcis++;
-		i = 0;
-		funcid = 0;
-		standard_cis = true;
-		do {
-			if (standard_cis) {
-				tup = cis[i++];
-				if (tup == CISTPL_NULL || tup == CISTPL_END)
-					tlen = 0;
-				else
-					tlen = cis[i++];
-			} else {
-				if (cis[i] == CISTPL_NULL
-				    || cis[i] == CISTPL_END) {
-					tlen = 0;
-					tup = cis[i];
-				} else {
-					tlen = cis[i];
-					tup = CISTPL_BRCM_HNBU;
-				}
-				++i;
-			}
-			if ((i + tlen) >= CIS_SIZE)
-				break;
-
-			switch (tup) {
-			case CISTPL_VERS_1:
-				/* assume the strings are good if the version field checks out */
-				if (((cis[i + 1] << 8) + cis[i]) >= 0x0008) {
-					varbuf_append(&b, vstr_manf,
-						      &cis[i + 2]);
-					varbuf_append(&b, vstr_productname,
-						      &cis[i + 3 +
-							   strlen((char *)
-								  &cis[i +
-								       2])]);
-					break;
-				}
-
-			case CISTPL_MANFID:
-				varbuf_append(&b, vstr_manfid,
-					      (cis[i + 1] << 8) + cis[i]);
-				varbuf_append(&b, vstr_prodid,
-					      (cis[i + 3] << 8) + cis[i + 2]);
-				break;
-
-			case CISTPL_FUNCID:
-				funcid = cis[i];
-				break;
-
-			case CISTPL_FUNCE:
-				switch (funcid) {
-				case CISTPL_FID_SDIO:
-#ifdef BCMSDIO
-					if (cis[i] == 0) {
-						u8 spd = cis[i + 3];
-						static int base[] = {
-							-1, 10, 12, 13, 15, 20,
-							    25, 30,
-							35, 40, 45, 50, 55, 60,
-							    70, 80
-						};
-						static int mult[] = {
-							10, 100, 1000, 10000,
-							-1, -1, -1, -1
-						};
-						ASSERT((mult[spd & 0x7] != -1)
-						       &&
-						       (base
-							[(spd >> 3) & 0x0f]));
-						varbuf_append(&b,
-							      vstr_sdmaxblk[0],
-							      (cis[i + 2] << 8)
-							      + cis[i + 1]);
-						varbuf_append(&b,
-							      vstr_sdmaxspeed,
-							      (mult[spd & 0x7] *
-							       base[(spd >> 3) &
-								    0x0f]));
-					} else if (cis[i] == 1) {
-						varbuf_append(&b,
-							      vstr_sdmaxblk
-							      [cisnum],
-							      (cis[i + 13] << 8)
-							      | cis[i + 12]);
-					}
-#endif				/* BCMSDIO */
-					funcid = 0;
-					break;
-				default:
-					/* set macaddr if HNBU_MACADDR not seen yet */
-					if (eabuf[0] == '\0' &&
-					    cis[i] == LAN_NID &&
-					    !is_zero_ether_addr(&cis[i + 2]) &&
-					    !is_multicast_ether_addr(&cis[i + 2])) {
-						ASSERT(cis[i + 1] ==
-						       ETH_ALEN);
-						snprintf(eabuf, sizeof(eabuf),
-							"%pM", &cis[i + 2]);
-
-						/* set boardnum if HNBU_BOARDNUM not seen yet */
-						if (boardnum == -1)
-							boardnum =
-							    (cis[i + 6] << 8) +
-							    cis[i + 7];
-					}
-					break;
-				}
-				break;
-
-			case CISTPL_CFTABLE:
-				varbuf_append(&b, vstr_regwindowsz,
-					      (cis[i + 7] << 8) | cis[i + 6]);
-				break;
-
-			case CISTPL_BRCM_HNBU:
-				switch (cis[i]) {
-				case HNBU_SROMREV:
-					sromrev = cis[i + 1];
-					varbuf_append(&b, vstr_sromrev,
-						      sromrev);
-					break;
-
-				case HNBU_XTALFREQ:
-					varbuf_append(&b, vstr_xtalfreq,
-						      (cis[i + 4] << 24) |
-						      (cis[i + 3] << 16) |
-						      (cis[i + 2] << 8) |
-						      cis[i + 1]);
-					break;
-
-				case HNBU_CHIPID:
-					varbuf_append(&b, vstr_vendid,
-						      (cis[i + 2] << 8) +
-						      cis[i + 1]);
-					varbuf_append(&b, vstr_devid,
-						      (cis[i + 4] << 8) +
-						      cis[i + 3]);
-					if (tlen >= 7) {
-						varbuf_append(&b, vstr_chiprev,
-							      (cis[i + 6] << 8)
-							      + cis[i + 5]);
-					}
-					if (tlen >= 9) {
-						varbuf_append(&b,
-							      vstr_subvendid,
-							      (cis[i + 8] << 8)
-							      + cis[i + 7]);
-					}
-					if (tlen >= 11) {
-						varbuf_append(&b, vstr_subdevid,
-							      (cis[i + 10] << 8)
-							      + cis[i + 9]);
-						/* subdevid doubles for boardtype */
-						varbuf_append(&b,
-							      vstr_boardtype,
-							      (cis[i + 10] << 8)
-							      + cis[i + 9]);
-					}
-					break;
-
-				case HNBU_BOARDNUM:
-					boardnum =
-					    (cis[i + 2] << 8) + cis[i + 1];
-					break;
-
-				case HNBU_PATCH:
-					{
-						char vstr_paddr[16];
-						char vstr_pdata[16];
-
-						/* retrieve the patch pairs
-						 * from tlen/6; where 6 is
-						 * sizeof(patch addr(2)) +
-						 * sizeof(patch data(4)).
-						 */
-						patch_pair = tlen / 6;
-
-						for (j = 0; j < patch_pair; j++) {
-							snprintf(vstr_paddr,
-								 sizeof
-								 (vstr_paddr),
-								 "pa%d=0x%%x",
-								 j);
-							snprintf(vstr_pdata,
-								 sizeof
-								 (vstr_pdata),
-								 "pd%d=0x%%x",
-								 j);
-
-							varbuf_append(&b,
-								      vstr_paddr,
-								      (cis
-								       [i +
-									(j *
-									 6) +
-									2] << 8)
-								      | cis[i +
-									    (j *
-									     6)
-									    +
-									    1]);
-
-							varbuf_append(&b,
-								      vstr_pdata,
-								      (cis
-								       [i +
-									(j *
-									 6) +
-									6] <<
-								       24) |
-								      (cis
-								       [i +
-									(j *
-									 6) +
-									5] <<
-								       16) |
-								      (cis
-								       [i +
-									(j *
-									 6) +
-									4] << 8)
-								      | cis[i +
-									    (j *
-									     6)
-									    +
-									    3]);
-						}
-					}
-					break;
-
-				case HNBU_BOARDREV:
-					if (tlen == 2)
-						varbuf_append(&b, vstr_boardrev,
-							      cis[i + 1]);
-					else
-						varbuf_append(&b, vstr_boardrev,
-							      (cis[i + 2] << 8)
-							      + cis[i + 1]);
-					break;
-
-				case HNBU_BOARDFLAGS:
-					w32 = (cis[i + 2] << 8) + cis[i + 1];
-					if (tlen >= 5)
-						w32 |=
-						    ((cis[i + 4] << 24) +
-						     (cis[i + 3] << 16));
-					varbuf_append(&b, vstr_boardflags, w32);
-
-					if (tlen >= 7) {
-						w32 =
-						    (cis[i + 6] << 8) + cis[i +
-									    5];
-						if (tlen >= 9)
-							w32 |=
-							    ((cis[i + 8] << 24)
-							     +
-							     (cis[i + 7] <<
-							      16));
-						varbuf_append(&b,
-							      vstr_boardflags2,
-							      w32);
-					}
-					break;
-
-				case HNBU_USBFS:
-					varbuf_append(&b, vstr_usbfs,
-						      cis[i + 1]);
-					break;
-
-				case HNBU_BOARDTYPE:
-					varbuf_append(&b, vstr_boardtype,
-						      (cis[i + 2] << 8) +
-						      cis[i + 1]);
-					break;
-
-				case HNBU_HNBUCIS:
-					/*
-					 * what follows is a nonstandard HNBU CIS
-					 * that lacks CISTPL_BRCM_HNBU tags
-					 *
-					 * skip 0xff (end of standard CIS)
-					 * after this tuple
-					 */
-					tlen++;
-					standard_cis = false;
-					break;
-
-				case HNBU_USBEPNUM:
-					varbuf_append(&b, vstr_usbepnum,
-						      (cis[i + 2] << 8) | cis[i
-									      +
-									      1]);
-					break;
-
-				case HNBU_AA:
-					varbuf_append(&b, vstr_aa2g,
-						      cis[i + 1]);
-					if (tlen >= 3)
-						varbuf_append(&b, vstr_aa5g,
-							      cis[i + 2]);
-					break;
-
-				case HNBU_AG:
-					varbuf_append(&b, vstr_ag, 0,
-						      cis[i + 1]);
-					if (tlen >= 3)
-						varbuf_append(&b, vstr_ag, 1,
-							      cis[i + 2]);
-					if (tlen >= 4)
-						varbuf_append(&b, vstr_ag, 2,
-							      cis[i + 3]);
-					if (tlen >= 5)
-						varbuf_append(&b, vstr_ag, 3,
-							      cis[i + 4]);
-					ag_init = true;
-					break;
-
-				case HNBU_ANT5G:
-					varbuf_append(&b, vstr_aa5g,
-						      cis[i + 1]);
-					varbuf_append(&b, vstr_ag, 1,
-						      cis[i + 2]);
-					break;
-
-				case HNBU_CC:
-					ASSERT(sromrev == 1);
-					varbuf_append(&b, vstr_cc, cis[i + 1]);
-					break;
-
-				case HNBU_PAPARMS:
-					switch (tlen) {
-					case 2:
-						ASSERT(sromrev == 1);
-						varbuf_append(&b,
-							      vstr_pa0maxpwr,
-							      cis[i + 1]);
-						break;
-					case 10:
-						ASSERT(sromrev >= 2);
-						varbuf_append(&b, vstr_opo,
-							      cis[i + 9]);
-						/* FALLTHROUGH */
-					case 9:
-						varbuf_append(&b,
-							      vstr_pa0maxpwr,
-							      cis[i + 8]);
-						/* FALLTHROUGH */
-						BCMDONGLECASE(8)
-						    varbuf_append(&b,
-								  vstr_pa0itssit,
-								  cis[i + 7]);
-						/* FALLTHROUGH */
-						BCMDONGLECASE(7)
-						    for (j = 0; j < 3; j++) {
-							varbuf_append(&b,
-								      vstr_pa0b
-								      [j],
-								      (cis
-								       [i +
-									(j *
-									 2) +
-									2] << 8)
-								      + cis[i +
-									    (j *
-									     2)
-									    +
-									    1]);
-						}
-						break;
-					default:
-						ASSERT((tlen == 2)
-						       || (tlen == 9)
-						       || (tlen == 10));
-						break;
-					}
-					break;
-
-				case HNBU_PAPARMS5G:
-					ASSERT((sromrev == 2)
-					       || (sromrev == 3));
-					switch (tlen) {
-					case 23:
-						varbuf_append(&b,
-							      vstr_pa1himaxpwr,
-							      cis[i + 22]);
-						varbuf_append(&b,
-							      vstr_pa1lomaxpwr,
-							      cis[i + 21]);
-						varbuf_append(&b,
-							      vstr_pa1maxpwr,
-							      cis[i + 20]);
-						/* FALLTHROUGH */
-					case 20:
-						varbuf_append(&b,
-							      vstr_pa1itssit,
-							      cis[i + 19]);
-						/* FALLTHROUGH */
-					case 19:
-						for (j = 0; j < 3; j++) {
-							varbuf_append(&b,
-								      vstr_pa1b
-								      [j],
-								      (cis
-								       [i +
-									(j *
-									 2) +
-									2] << 8)
-								      + cis[i +
-									    (j *
-									     2)
-									    +
-									    1]);
-						}
-						for (j = 3; j < 6; j++) {
-							varbuf_append(&b,
-								      vstr_pa1lob
-								      [j - 3],
-								      (cis
-								       [i +
-									(j *
-									 2) +
-									2] << 8)
-								      + cis[i +
-									    (j *
-									     2)
-									    +
-									    1]);
-						}
-						for (j = 6; j < 9; j++) {
-							varbuf_append(&b,
-								      vstr_pa1hib
-								      [j - 6],
-								      (cis
-								       [i +
-									(j *
-									 2) +
-									2] << 8)
-								      + cis[i +
-									    (j *
-									     2)
-									    +
-									    1]);
-						}
-						break;
-					default:
-						ASSERT((tlen == 19) ||
-						       (tlen == 20)
-						       || (tlen == 23));
-						break;
-					}
-					break;
-
-				case HNBU_OEM:
-					ASSERT(sromrev == 1);
-					varbuf_append(&b, vstr_oem,
-						      cis[i + 1], cis[i + 2],
-						      cis[i + 3], cis[i + 4],
-						      cis[i + 5], cis[i + 6],
-						      cis[i + 7], cis[i + 8]);
-					break;
-
-				case HNBU_LEDS:
-					for (j = 1; j <= 4; j++) {
-						if (cis[i + j] != 0xff) {
-							varbuf_append(&b,
-								      vstr_ledbh,
-								      j - 1,
-								      cis[i +
-									  j]);
-						}
-					}
-					break;
-
-				case HNBU_CCODE:
-					ASSERT(sromrev > 1);
-					if ((cis[i + 1] == 0)
-					    || (cis[i + 2] == 0))
-						varbuf_append(&b, vstr_noccode);
-					else
-						varbuf_append(&b, vstr_ccode,
-							      cis[i + 1],
-							      cis[i + 2]);
-					varbuf_append(&b, vstr_cctl,
-						      cis[i + 3]);
-					break;
-
-				case HNBU_CCKPO:
-					ASSERT(sromrev > 2);
-					varbuf_append(&b, vstr_cckpo,
-						      (cis[i + 2] << 8) | cis[i
-									      +
-									      1]);
-					break;
-
-				case HNBU_OFDMPO:
-					ASSERT(sromrev > 2);
-					varbuf_append(&b, vstr_ofdmpo,
-						      (cis[i + 4] << 24) |
-						      (cis[i + 3] << 16) |
-						      (cis[i + 2] << 8) |
-						      cis[i + 1]);
-					break;
-
-				case HNBU_WPS:
-					varbuf_append(&b, vstr_wpsgpio,
-						      cis[i + 1]);
-					if (tlen >= 3)
-						varbuf_append(&b, vstr_wpsled,
-							      cis[i + 2]);
-					break;
-
-				case HNBU_RSSISMBXA2G:
-					ASSERT(sromrev == 3);
-					varbuf_append(&b, vstr_rssismf2g,
-						      cis[i + 1] & 0xf);
-					varbuf_append(&b, vstr_rssismc2g,
-						      (cis[i + 1] >> 4) & 0xf);
-					varbuf_append(&b, vstr_rssisav2g,
-						      cis[i + 2] & 0x7);
-					varbuf_append(&b, vstr_bxa2g,
-						      (cis[i + 2] >> 3) & 0x3);
-					break;
-
-				case HNBU_RSSISMBXA5G:
-					ASSERT(sromrev == 3);
-					varbuf_append(&b, vstr_rssismf5g,
-						      cis[i + 1] & 0xf);
-					varbuf_append(&b, vstr_rssismc5g,
-						      (cis[i + 1] >> 4) & 0xf);
-					varbuf_append(&b, vstr_rssisav5g,
-						      cis[i + 2] & 0x7);
-					varbuf_append(&b, vstr_bxa5g,
-						      (cis[i + 2] >> 3) & 0x3);
-					break;
-
-				case HNBU_TRI2G:
-					ASSERT(sromrev == 3);
-					varbuf_append(&b, vstr_tri2g,
-						      cis[i + 1]);
-					break;
-
-				case HNBU_TRI5G:
-					ASSERT(sromrev == 3);
-					varbuf_append(&b, vstr_tri5gl,
-						      cis[i + 1]);
-					varbuf_append(&b, vstr_tri5g,
-						      cis[i + 2]);
-					varbuf_append(&b, vstr_tri5gh,
-						      cis[i + 3]);
-					break;
-
-				case HNBU_RXPO2G:
-					ASSERT(sromrev == 3);
-					varbuf_append(&b, vstr_rxpo2g,
-						      cis[i + 1]);
-					break;
-
-				case HNBU_RXPO5G:
-					ASSERT(sromrev == 3);
-					varbuf_append(&b, vstr_rxpo5g,
-						      cis[i + 1]);
-					break;
-
-				case HNBU_MACADDR:
-					if (!is_zero_ether_addr(&cis[i + 1]) &&
-					    !is_multicast_ether_addr(&cis[i + 1])) {
-						snprintf(eabuf, sizeof(eabuf),
-							"%pM", &cis[i + 1]);
-
-						/* set boardnum if HNBU_BOARDNUM not seen yet */
-						if (boardnum == -1)
-							boardnum =
-							    (cis[i + 5] << 8) +
-							    cis[i + 6];
-					}
-					break;
-
-				case HNBU_LEDDC:
-					/* CIS leddc only has 16bits, convert it to 32bits */
-					w32 = ((cis[i + 2] << 24) |	/* oncount */
-					       (cis[i + 1] << 8));	/* offcount */
-					varbuf_append(&b, vstr_leddc, w32);
-					break;
-
-				case HNBU_CHAINSWITCH:
-					varbuf_append(&b, vstr_txchain,
-						      cis[i + 1]);
-					varbuf_append(&b, vstr_rxchain,
-						      cis[i + 2]);
-					varbuf_append(&b, vstr_antswitch,
-						      (cis[i + 4] << 8) +
-						      cis[i + 3]);
-					break;
-
-				case HNBU_REGREV:
-					varbuf_append(&b, vstr_regrev,
-						      cis[i + 1]);
-					break;
-
-				case HNBU_FEM:{
-						u16 fem =
-						    (cis[i + 2] << 8) + cis[i +
-									    1];
-						varbuf_append(&b,
-							      vstr_antswctl2g,
-							      (fem &
-							       SROM8_FEM_ANTSWLUT_MASK)
-							      >>
-							      SROM8_FEM_ANTSWLUT_SHIFT);
-						varbuf_append(&b, vstr_triso2g,
-							      (fem &
-							       SROM8_FEM_TR_ISO_MASK)
-							      >>
-							      SROM8_FEM_TR_ISO_SHIFT);
-						varbuf_append(&b,
-							      vstr_pdetrange2g,
-							      (fem &
-							       SROM8_FEM_PDET_RANGE_MASK)
-							      >>
-							      SROM8_FEM_PDET_RANGE_SHIFT);
-						varbuf_append(&b,
-							      vstr_extpagain2g,
-							      (fem &
-							       SROM8_FEM_EXTPA_GAIN_MASK)
-							      >>
-							      SROM8_FEM_EXTPA_GAIN_SHIFT);
-						varbuf_append(&b,
-							      vstr_tssipos2g,
-							      (fem &
-							       SROM8_FEM_TSSIPOS_MASK)
-							      >>
-							      SROM8_FEM_TSSIPOS_SHIFT);
-						if (tlen < 5)
-							break;
-
-						fem =
-						    (cis[i + 4] << 8) + cis[i +
-									    3];
-						varbuf_append(&b,
-							      vstr_antswctl5g,
-							      (fem &
-							       SROM8_FEM_ANTSWLUT_MASK)
-							      >>
-							      SROM8_FEM_ANTSWLUT_SHIFT);
-						varbuf_append(&b, vstr_triso5g,
-							      (fem &
-							       SROM8_FEM_TR_ISO_MASK)
-							      >>
-							      SROM8_FEM_TR_ISO_SHIFT);
-						varbuf_append(&b,
-							      vstr_pdetrange5g,
-							      (fem &
-							       SROM8_FEM_PDET_RANGE_MASK)
-							      >>
-							      SROM8_FEM_PDET_RANGE_SHIFT);
-						varbuf_append(&b,
-							      vstr_extpagain5g,
-							      (fem &
-							       SROM8_FEM_EXTPA_GAIN_MASK)
-							      >>
-							      SROM8_FEM_EXTPA_GAIN_SHIFT);
-						varbuf_append(&b,
-							      vstr_tssipos5g,
-							      (fem &
-							       SROM8_FEM_TSSIPOS_MASK)
-							      >>
-							      SROM8_FEM_TSSIPOS_SHIFT);
-						break;
-					}
-
-				case HNBU_PAPARMS_C0:
-					varbuf_append(&b, vstr_maxp2ga0,
-						      cis[i + 1]);
-					varbuf_append(&b, vstr_itt2ga0,
-						      cis[i + 2]);
-					varbuf_append(&b, vstr_pa, 2, 0, 0,
-						      (cis[i + 4] << 8) +
-						      cis[i + 3]);
-					varbuf_append(&b, vstr_pa, 2, 1, 0,
-						      (cis[i + 6] << 8) +
-						      cis[i + 5]);
-					varbuf_append(&b, vstr_pa, 2, 2, 0,
-						      (cis[i + 8] << 8) +
-						      cis[i + 7]);
-					if (tlen < 31)
-						break;
-
-					varbuf_append(&b, vstr_maxp5ga0,
-						      cis[i + 9]);
-					varbuf_append(&b, vstr_itt5ga0,
-						      cis[i + 10]);
-					varbuf_append(&b, vstr_maxp5gha0,
-						      cis[i + 11]);
-					varbuf_append(&b, vstr_maxp5gla0,
-						      cis[i + 12]);
-					varbuf_append(&b, vstr_pa, 5, 0, 0,
-						      (cis[i + 14] << 8) +
-						      cis[i + 13]);
-					varbuf_append(&b, vstr_pa, 5, 1, 0,
-						      (cis[i + 16] << 8) +
-						      cis[i + 15]);
-					varbuf_append(&b, vstr_pa, 5, 2, 0,
-						      (cis[i + 18] << 8) +
-						      cis[i + 17]);
-					varbuf_append(&b, vstr_pahl, 5, 'l', 0,
-						      0,
-						      (cis[i + 20] << 8) +
-						      cis[i + 19]);
-					varbuf_append(&b, vstr_pahl, 5, 'l', 1,
-						      0,
-						      (cis[i + 22] << 8) +
-						      cis[i + 21]);
-					varbuf_append(&b, vstr_pahl, 5, 'l', 2,
-						      0,
-						      (cis[i + 24] << 8) +
-						      cis[i + 23]);
-					varbuf_append(&b, vstr_pahl, 5, 'h', 0,
-						      0,
-						      (cis[i + 26] << 8) +
-						      cis[i + 25]);
-					varbuf_append(&b, vstr_pahl, 5, 'h', 1,
-						      0,
-						      (cis[i + 28] << 8) +
-						      cis[i + 27]);
-					varbuf_append(&b, vstr_pahl, 5, 'h', 2,
-						      0,
-						      (cis[i + 30] << 8) +
-						      cis[i + 29]);
-					break;
-
-				case HNBU_PAPARMS_C1:
-					varbuf_append(&b, vstr_maxp2ga1,
-						      cis[i + 1]);
-					varbuf_append(&b, vstr_itt2ga1,
-						      cis[i + 2]);
-					varbuf_append(&b, vstr_pa, 2, 0, 1,
-						      (cis[i + 4] << 8) +
-						      cis[i + 3]);
-					varbuf_append(&b, vstr_pa, 2, 1, 1,
-						      (cis[i + 6] << 8) +
-						      cis[i + 5]);
-					varbuf_append(&b, vstr_pa, 2, 2, 1,
-						      (cis[i + 8] << 8) +
-						      cis[i + 7]);
-					if (tlen < 31)
-						break;
-
-					varbuf_append(&b, vstr_maxp5ga1,
-						      cis[i + 9]);
-					varbuf_append(&b, vstr_itt5ga1,
-						      cis[i + 10]);
-					varbuf_append(&b, vstr_maxp5gha1,
-						      cis[i + 11]);
-					varbuf_append(&b, vstr_maxp5gla1,
-						      cis[i + 12]);
-					varbuf_append(&b, vstr_pa, 5, 0, 1,
-						      (cis[i + 14] << 8) +
-						      cis[i + 13]);
-					varbuf_append(&b, vstr_pa, 5, 1, 1,
-						      (cis[i + 16] << 8) +
-						      cis[i + 15]);
-					varbuf_append(&b, vstr_pa, 5, 2, 1,
-						      (cis[i + 18] << 8) +
-						      cis[i + 17]);
-					varbuf_append(&b, vstr_pahl, 5, 'l', 0,
-						      1,
-						      (cis[i + 20] << 8) +
-						      cis[i + 19]);
-					varbuf_append(&b, vstr_pahl, 5, 'l', 1,
-						      1,
-						      (cis[i + 22] << 8) +
-						      cis[i + 21]);
-					varbuf_append(&b, vstr_pahl, 5, 'l', 2,
-						      1,
-						      (cis[i + 24] << 8) +
-						      cis[i + 23]);
-					varbuf_append(&b, vstr_pahl, 5, 'h', 0,
-						      1,
-						      (cis[i + 26] << 8) +
-						      cis[i + 25]);
-					varbuf_append(&b, vstr_pahl, 5, 'h', 1,
-						      1,
-						      (cis[i + 28] << 8) +
-						      cis[i + 27]);
-					varbuf_append(&b, vstr_pahl, 5, 'h', 2,
-						      1,
-						      (cis[i + 30] << 8) +
-						      cis[i + 29]);
-					break;
-
-				case HNBU_PO_CCKOFDM:
-					varbuf_append(&b, vstr_cck2gpo,
-						      (cis[i + 2] << 8) +
-						      cis[i + 1]);
-					varbuf_append(&b, vstr_ofdm2gpo,
-						      (cis[i + 6] << 24) +
-						      (cis[i + 5] << 16) +
-						      (cis[i + 4] << 8) +
-						      cis[i + 3]);
-					if (tlen < 19)
-						break;
-
-					varbuf_append(&b, vstr_ofdm5gpo,
-						      (cis[i + 10] << 24) +
-						      (cis[i + 9] << 16) +
-						      (cis[i + 8] << 8) +
-						      cis[i + 7]);
-					varbuf_append(&b, vstr_ofdm5glpo,
-						      (cis[i + 14] << 24) +
-						      (cis[i + 13] << 16) +
-						      (cis[i + 12] << 8) +
-						      cis[i + 11]);
-					varbuf_append(&b, vstr_ofdm5ghpo,
-						      (cis[i + 18] << 24) +
-						      (cis[i + 17] << 16) +
-						      (cis[i + 16] << 8) +
-						      cis[i + 15]);
-					break;
-
-				case HNBU_PO_MCS2G:
-					for (j = 0; j <= (tlen / 2); j++) {
-						varbuf_append(&b, vstr_mcspo, 2,
-							      j,
-							      (cis
-							       [i + 2 +
-								2 * j] << 8) +
-							      cis[i + 1 +
-								  2 * j]);
-					}
-					break;
-
-				case HNBU_PO_MCS5GM:
-					for (j = 0; j <= (tlen / 2); j++) {
-						varbuf_append(&b, vstr_mcspo, 5,
-							      j,
-							      (cis
-							       [i + 2 +
-								2 * j] << 8) +
-							      cis[i + 1 +
-								  2 * j]);
-					}
-					break;
-
-				case HNBU_PO_MCS5GLH:
-					for (j = 0; j <= (tlen / 4); j++) {
-						varbuf_append(&b, vstr_mcspohl,
-							      5, 'l', j,
-							      (cis
-							       [i + 2 +
-								2 * j] << 8) +
-							      cis[i + 1 +
-								  2 * j]);
-					}
-
-					for (j = 0; j <= (tlen / 4); j++) {
-						varbuf_append(&b, vstr_mcspohl,
-							      5, 'h', j,
-							      (cis
-							       [i +
-								((tlen / 2) +
-								 2) +
-								2 * j] << 8) +
-							      cis[i +
-								  ((tlen / 2) +
-								   1) + 2 * j]);
-					}
-
-					break;
-
-				case HNBU_PO_CDD:
-					varbuf_append(&b, vstr_cddpo,
-						      (cis[i + 2] << 8) +
-						      cis[i + 1]);
-					break;
-
-				case HNBU_PO_STBC:
-					varbuf_append(&b, vstr_stbcpo,
-						      (cis[i + 2] << 8) +
-						      cis[i + 1]);
-					break;
-
-				case HNBU_PO_40M:
-					varbuf_append(&b, vstr_bw40po,
-						      (cis[i + 2] << 8) +
-						      cis[i + 1]);
-					break;
-
-				case HNBU_PO_40MDUP:
-					varbuf_append(&b, vstr_bwduppo,
-						      (cis[i + 2] << 8) +
-						      cis[i + 1]);
-					break;
-
-				case HNBU_OFDMPO5G:
-					varbuf_append(&b, vstr_ofdm5gpo,
-						      (cis[i + 4] << 24) +
-						      (cis[i + 3] << 16) +
-						      (cis[i + 2] << 8) +
-						      cis[i + 1]);
-					varbuf_append(&b, vstr_ofdm5glpo,
-						      (cis[i + 8] << 24) +
-						      (cis[i + 7] << 16) +
-						      (cis[i + 6] << 8) +
-						      cis[i + 5]);
-					varbuf_append(&b, vstr_ofdm5ghpo,
-						      (cis[i + 12] << 24) +
-						      (cis[i + 11] << 16) +
-						      (cis[i + 10] << 8) +
-						      cis[i + 9]);
-					break;
-
-				case HNBU_CUSTOM1:
-					varbuf_append(&b, vstr_custom, 1,
-						      ((cis[i + 4] << 24) +
-						       (cis[i + 3] << 16) +
-						       (cis[i + 2] << 8) +
-						       cis[i + 1]));
-					break;
-
-#if defined(BCMSDIO)
-				case HNBU_SROM3SWRGN:
-					if (tlen >= 73) {
-						u16 srom[35];
-						u8 srev = cis[i + 1 + 70];
-						ASSERT(srev == 3);
-						/* make tuple value 16-bit aligned and parse it */
-						memcpy(srom, &cis[i + 1],
-						       sizeof(srom));
-						_initvars_srom_pci(srev, srom,
-								   SROM3_SWRGN_OFF,
-								   &b);
-						/* 2.4G antenna gain is included in SROM */
-						ag_init = true;
-						/* Ethernet MAC address is included in SROM */
-						eabuf[0] = 0;
-						boardnum = -1;
-					}
-					/* create extra variables */
-					if (tlen >= 75)
-						varbuf_append(&b, vstr_vendid,
-							      (cis[i + 1 + 73]
-							       << 8) + cis[i +
-									   1 +
-									   72]);
-					if (tlen >= 77)
-						varbuf_append(&b, vstr_devid,
-							      (cis[i + 1 + 75]
-							       << 8) + cis[i +
-									   1 +
-									   74]);
-					if (tlen >= 79)
-						varbuf_append(&b, vstr_xtalfreq,
-							      (cis[i + 1 + 77]
-							       << 8) + cis[i +
-									   1 +
-									   76]);
-					break;
-#endif				/* defined(BCMSDIO) */
-
-				case HNBU_CCKFILTTYPE:
-					varbuf_append(&b, vstr_cckdigfilttype,
-						      (cis[i + 1]));
-					break;
-				}
-
-				break;
-			}
-			i += tlen;
-		} while (tup != CISTPL_END);
-	}
-
-	if (boardnum != -1) {
-		varbuf_append(&b, vstr_boardnum, boardnum);
-	}
-
-	if (eabuf[0]) {
-		varbuf_append(&b, vstr_macaddr, eabuf);
-	}
-
-	/* if there is no antenna gain field, set default */
-	if (getvar(NULL, "ag0") == NULL && ag_init == false) {
-		varbuf_append(&b, vstr_ag, 0, 0xff);
-	}
-
-	/* final nullbyte terminator */
-	ASSERT(b.size >= 1);
-	*b.buf++ = '\0';
-
-	ASSERT(b.buf - base <= MAXSZ_NVRAM_VARS);
-	err = initvars_table(base, b.buf, vars, count);
-
-	kfree(base);
-	return err;
-}
-
-/* In chips with chipcommon rev 32 and later, the srom is in chipcommon,
- * not in the bus cores.
- */
-static u16
-srom_cc_cmd(si_t *sih, void *ccregs, u32 cmd,
-	    uint wordoff, u16 data)
-{
-	chipcregs_t *cc = (chipcregs_t *) ccregs;
-	uint wait_cnt = 1000;
-
-	if ((cmd == SRC_OP_READ) || (cmd == SRC_OP_WRITE)) {
-		W_REG(&cc->sromaddress, wordoff * 2);
-		if (cmd == SRC_OP_WRITE)
-			W_REG(&cc->sromdata, data);
-	}
-
-	W_REG(&cc->sromcontrol, SRC_START | cmd);
-
-	while (wait_cnt--) {
-		if ((R_REG(&cc->sromcontrol) & SRC_BUSY) == 0)
-			break;
-	}
-
-	if (!wait_cnt) {
-		BS_ERROR(("%s: Command 0x%x timed out\n", __func__, cmd));
-		return 0xffff;
-	}
-	if (cmd == SRC_OP_READ)
-		return (u16) R_REG(&cc->sromdata);
-	else
-		return 0xffff;
-}
-
-static inline void ltoh16_buf(u16 *buf, unsigned int size)
-{
-	for (size /= 2; size; size--)
-		*(buf + size) = le16_to_cpu(*(buf + size));
-}
-
-static inline void htol16_buf(u16 *buf, unsigned int size)
-{
-	for (size /= 2; size; size--)
-		*(buf + size) = cpu_to_le16(*(buf + size));
-}
-
-/*
- * Read in and validate sprom.
- * Return 0 on success, nonzero on error.
- */
-static int
-sprom_read_pci(si_t *sih, u16 *sprom, uint wordoff,
-	       u16 *buf, uint nwords, bool check_crc)
-{
-	int err = 0;
-	uint i;
-	void *ccregs = NULL;
-
-	/* read the sprom */
-	for (i = 0; i < nwords; i++) {
-
-		if (sih->ccrev > 31 && ISSIM_ENAB(sih)) {
-			/* use indirect since direct is too slow on QT */
-			if ((sih->cccaps & CC_CAP_SROM) == 0)
-				return 1;
-
-			ccregs = (void *)((u8 *) sprom - CC_SROM_OTP);
-			buf[i] =
-			    srom_cc_cmd(sih, ccregs, SRC_OP_READ,
-					wordoff + i, 0);
-
-		} else {
-			if (ISSIM_ENAB(sih))
-				buf[i] = R_REG(&sprom[wordoff + i]);
-
-			buf[i] = R_REG(&sprom[wordoff + i]);
-		}
-
-	}
-
-	/* bypass crc checking for simulation to allow srom hack */
-	if (ISSIM_ENAB(sih))
-		return err;
-
-	if (check_crc) {
-
-		if (buf[0] == 0xffff) {
-			/* The hardware thinks that an srom that starts with 0xffff
-			 * is blank, regardless of the rest of the content, so declare
-			 * it bad.
-			 */
-			BS_ERROR(("%s: buf[0] = 0x%x, returning bad-crc\n",
-				  __func__, buf[0]));
-			return 1;
-		}
-
-		/* fixup the endianness so crc8 will pass */
-		htol16_buf(buf, nwords * 2);
-		if (hndcrc8((u8 *) buf, nwords * 2, CRC8_INIT_VALUE) !=
-		    CRC8_GOOD_VALUE) {
-			/* DBG only pci always read srom4 first, then srom8/9 */
-			/* BS_ERROR(("%s: bad crc\n", __func__)); */
-			err = 1;
-		}
-		/* now correct the endianness of the byte array */
-		ltoh16_buf(buf, nwords * 2);
-	}
-	return err;
-}
-
-#if defined(BCMNVRAMR)
-static int otp_read_pci(si_t *sih, u16 *buf, uint bufsz)
-{
-	u8 *otp;
-	uint sz = OTP_SZ_MAX / 2;	/* size in words */
-	int err = 0;
-
-	ASSERT(bufsz <= OTP_SZ_MAX);
-
-	otp = kzalloc(OTP_SZ_MAX, GFP_ATOMIC);
-	if (otp == NULL) {
-		return BCME_ERROR;
-	}
-
-	err = otp_read_region(sih, OTP_HW_RGN, (u16 *) otp, &sz);
-
-	memcpy(buf, otp, bufsz);
-
-	kfree(otp);
-
-	/* Check CRC */
-	if (buf[0] == 0xffff) {
-		/* The hardware thinks that an srom that starts with 0xffff
-		 * is blank, regardless of the rest of the content, so declare
-		 * it bad.
-		 */
-		BS_ERROR(("%s: buf[0] = 0x%x, returning bad-crc\n", __func__,
-			  buf[0]));
-		return 1;
-	}
-
-	/* fixup the endianness so crc8 will pass */
-	htol16_buf(buf, bufsz);
-	if (hndcrc8((u8 *) buf, SROM4_WORDS * 2, CRC8_INIT_VALUE) !=
-	    CRC8_GOOD_VALUE) {
-		BS_ERROR(("%s: bad crc\n", __func__));
-		err = 1;
-	}
-	/* now correct the endianness of the byte array */
-	ltoh16_buf(buf, bufsz);
-
-	return err;
-}
-#endif				/* defined(BCMNVRAMR) */
-/*
-* Create variable table from memory.
-* Return 0 on success, nonzero on error.
-*/
-static int initvars_table(char *start, char *end,
-			  char **vars, uint *count)
-{
-	int c = (int)(end - start);
-
-	/* do it only when there is more than just the null string */
-	if (c > 1) {
-		char *vp = kmalloc(c, GFP_ATOMIC);
-		ASSERT(vp != NULL);
-		if (!vp)
-			return BCME_NOMEM;
-		memcpy(vp, start, c);
-		*vars = vp;
-		*count = c;
-	} else {
-		*vars = NULL;
-		*count = 0;
-	}
-
-	return 0;
-}
-
-/*
- * Find variables with <devpath> from flash. 'base' points to the beginning
- * of the table upon enter and to the end of the table upon exit when success.
- * Return 0 on success, nonzero on error.
- */
-static int initvars_flash(si_t *sih, char **base, uint len)
-{
-	char *vp = *base;
-	char *flash;
-	int err;
-	char *s;
-	uint l, dl, copy_len;
-	char devpath[SI_DEVPATH_BUFSZ];
-
-	/* allocate memory and read in flash */
-	flash = kmalloc(NVRAM_SPACE, GFP_ATOMIC);
-	if (!flash)
-		return BCME_NOMEM;
-	err = nvram_getall(flash, NVRAM_SPACE);
-	if (err)
-		goto exit;
-
-	si_devpath(sih, devpath, sizeof(devpath));
-
-	/* grab vars with the <devpath> prefix in name */
-	dl = strlen(devpath);
-	for (s = flash; s && *s; s += l + 1) {
-		l = strlen(s);
-
-		/* skip non-matching variable */
-		if (strncmp(s, devpath, dl))
-			continue;
-
-		/* is there enough room to copy? */
-		copy_len = l - dl + 1;
-		if (len < copy_len) {
-			err = BCME_BUFTOOSHORT;
-			goto exit;
-		}
-
-		/* no prefix, just the name=value */
-		strncpy(vp, &s[dl], copy_len);
-		vp += copy_len;
-		len -= copy_len;
-	}
-
-	/* add null string as terminator */
-	if (len < 1) {
-		err = BCME_BUFTOOSHORT;
-		goto exit;
-	}
-	*vp++ = '\0';
-
-	*base = vp;
-
- exit:	kfree(flash);
-	return err;
-}
-
-/*
- * Initialize nonvolatile variable table from flash.
- * Return 0 on success, nonzero on error.
- */
-static int initvars_flash_si(si_t *sih, char **vars, uint *count)
-{
-	char *vp, *base;
-	int err;
-
-	ASSERT(vars != NULL);
-	ASSERT(count != NULL);
-
-	base = vp = kmalloc(MAXSZ_NVRAM_VARS, GFP_ATOMIC);
-	ASSERT(vp != NULL);
-	if (!vp)
-		return BCME_NOMEM;
-
-	err = initvars_flash(sih, &vp, MAXSZ_NVRAM_VARS);
-	if (err == 0)
-		err = initvars_table(base, vp, vars, count);
-
-	kfree(base);
-
-	return err;
-}
-
-/* Parse SROM and create name=value pairs. 'srom' points to
- * the SROM word array. 'off' specifies the offset of the
- * first word 'srom' points to, which should be either 0 or
- * SROM3_SWRG_OFF (full SROM or software region).
- */
-
-static uint mask_shift(u16 mask)
-{
-	uint i;
-	for (i = 0; i < (sizeof(mask) << 3); i++) {
-		if (mask & (1 << i))
-			return i;
-	}
-	ASSERT(mask);
-	return 0;
-}
-
-static uint mask_width(u16 mask)
-{
-	int i;
-	for (i = (sizeof(mask) << 3) - 1; i >= 0; i--) {
-		if (mask & (1 << i))
-			return (uint) (i - mask_shift(mask) + 1);
-	}
-	ASSERT(mask);
-	return 0;
-}
-
-#if defined(BCMDBG)
-static bool mask_valid(u16 mask)
-{
-	uint shift = mask_shift(mask);
-	uint width = mask_width(mask);
-	return mask == ((~0 << shift) & ~(~0 << (shift + width)));
-}
-#endif				/* BCMDBG */
-
-static void _initvars_srom_pci(u8 sromrev, u16 *srom, uint off, varbuf_t *b)
-{
-	u16 w;
-	u32 val;
-	const sromvar_t *srv;
-	uint width;
-	uint flags;
-	u32 sr = (1 << sromrev);
-
-	varbuf_append(b, "sromrev=%d", sromrev);
-
-	for (srv = pci_sromvars; srv->name != NULL; srv++) {
-		const char *name;
-
-		if ((srv->revmask & sr) == 0)
-			continue;
-
-		if (srv->off < off)
-			continue;
-
-		flags = srv->flags;
-		name = srv->name;
-
-		/* This entry is for mfgc only. Don't generate param for it, */
-		if (flags & SRFL_NOVAR)
-			continue;
-
-		if (flags & SRFL_ETHADDR) {
-			u8 ea[ETH_ALEN];
-
-			ea[0] = (srom[srv->off - off] >> 8) & 0xff;
-			ea[1] = srom[srv->off - off] & 0xff;
-			ea[2] = (srom[srv->off + 1 - off] >> 8) & 0xff;
-			ea[3] = srom[srv->off + 1 - off] & 0xff;
-			ea[4] = (srom[srv->off + 2 - off] >> 8) & 0xff;
-			ea[5] = srom[srv->off + 2 - off] & 0xff;
-
-			varbuf_append(b, "%s=%pM", name, ea);
-		} else {
-			ASSERT(mask_valid(srv->mask));
-			ASSERT(mask_width(srv->mask));
-
-			w = srom[srv->off - off];
-			val = (w & srv->mask) >> mask_shift(srv->mask);
-			width = mask_width(srv->mask);
-
-			while (srv->flags & SRFL_MORE) {
-				srv++;
-				ASSERT(srv->name != NULL);
-
-				if (srv->off == 0 || srv->off < off)
-					continue;
-
-				ASSERT(mask_valid(srv->mask));
-				ASSERT(mask_width(srv->mask));
-
-				w = srom[srv->off - off];
-				val +=
-				    ((w & srv->mask) >> mask_shift(srv->
-								   mask)) <<
-				    width;
-				width += mask_width(srv->mask);
-			}
-
-			if ((flags & SRFL_NOFFS)
-			    && ((int)val == (1 << width) - 1))
-				continue;
-
-			if (flags & SRFL_CCODE) {
-				if (val == 0)
-					varbuf_append(b, "ccode=");
-				else
-					varbuf_append(b, "ccode=%c%c",
-						      (val >> 8), (val & 0xff));
-			}
-			/* LED Powersave duty cycle has to be scaled:
-			 *(oncount >> 24) (offcount >> 8)
-			 */
-			else if (flags & SRFL_LEDDC) {
-				u32 w32 = (((val >> 8) & 0xff) << 24) |	/* oncount */
-				    (((val & 0xff)) << 8);	/* offcount */
-				varbuf_append(b, "leddc=%d", w32);
-			} else if (flags & SRFL_PRHEX)
-				varbuf_append(b, "%s=0x%x", name, val);
-			else if ((flags & SRFL_PRSIGN)
-				 && (val & (1 << (width - 1))))
-				varbuf_append(b, "%s=%d", name,
-					      (int)(val | (~0 << width)));
-			else
-				varbuf_append(b, "%s=%u", name, val);
-		}
-	}
-
-	if (sromrev >= 4) {
-		/* Do per-path variables */
-		uint p, pb, psz;
-
-		if (sromrev >= 8) {
-			pb = SROM8_PATH0;
-			psz = SROM8_PATH1 - SROM8_PATH0;
-		} else {
-			pb = SROM4_PATH0;
-			psz = SROM4_PATH1 - SROM4_PATH0;
-		}
-
-		for (p = 0; p < MAX_PATH_SROM; p++) {
-			for (srv = perpath_pci_sromvars; srv->name != NULL;
-			     srv++) {
-				if ((srv->revmask & sr) == 0)
-					continue;
-
-				if (pb + srv->off < off)
-					continue;
-
-				/* This entry is for mfgc only. Don't generate param for it, */
-				if (srv->flags & SRFL_NOVAR)
-					continue;
-
-				w = srom[pb + srv->off - off];
-
-				ASSERT(mask_valid(srv->mask));
-				val = (w & srv->mask) >> mask_shift(srv->mask);
-				width = mask_width(srv->mask);
-
-				/* Cheating: no per-path var is more than 1 word */
-
-				if ((srv->flags & SRFL_NOFFS)
-				    && ((int)val == (1 << width) - 1))
-					continue;
-
-				if (srv->flags & SRFL_PRHEX)
-					varbuf_append(b, "%s%d=0x%x", srv->name,
-						      p, val);
-				else
-					varbuf_append(b, "%s%d=%d", srv->name,
-						      p, val);
-			}
-			pb += psz;
-		}
-	}
-}
-
-/*
- * Initialize nonvolatile variable table from sprom.
- * Return 0 on success, nonzero on error.
- */
-static int initvars_srom_pci(si_t *sih, void *curmap, char **vars, uint *count)
-{
-	u16 *srom, *sromwindow;
-	u8 sromrev = 0;
-	u32 sr;
-	varbuf_t b;
-	char *vp, *base = NULL;
-	bool flash = false;
-	int err = 0;
-
-	/*
-	 * Apply CRC over SROM content regardless SROM is present or not,
-	 * and use variable <devpath>sromrev's existence in flash to decide
-	 * if we should return an error when CRC fails or read SROM variables
-	 * from flash.
-	 */
-	srom = kmalloc(SROM_MAX, GFP_ATOMIC);
-	ASSERT(srom != NULL);
-	if (!srom)
-		return -2;
-
-	sromwindow = (u16 *) SROM_OFFSET(sih);
-	if (si_is_sprom_available(sih)) {
-		err =
-		    sprom_read_pci(sih, sromwindow, 0, srom, SROM_WORDS,
-				   true);
-
-		if ((srom[SROM4_SIGN] == SROM4_SIGNATURE) ||
-		    (((sih->buscoretype == PCIE_CORE_ID)
-		      && (sih->buscorerev >= 6))
-		     || ((sih->buscoretype == PCI_CORE_ID)
-			 && (sih->buscorerev >= 0xe)))) {
-			/* sromrev >= 4, read more */
-			err =
-			    sprom_read_pci(sih, sromwindow, 0, srom,
-					   SROM4_WORDS, true);
-			sromrev = srom[SROM4_CRCREV] & 0xff;
-			if (err)
-				BS_ERROR(("%s: srom %d, bad crc\n", __func__,
-					  sromrev));
-
-		} else if (err == 0) {
-			/* srom is good and is rev < 4 */
-			/* top word of sprom contains version and crc8 */
-			sromrev = srom[SROM_CRCREV] & 0xff;
-			/* bcm4401 sroms misprogrammed */
-			if (sromrev == 0x10)
-				sromrev = 1;
-		}
-	}
-#if defined(BCMNVRAMR)
-	/* Use OTP if SPROM not available */
-	else {
-		err = otp_read_pci(sih, srom, SROM_MAX);
-		if (err == 0)
-			/* OTP only contain SROM rev8/rev9 for now */
-			sromrev = srom[SROM4_CRCREV] & 0xff;
-		else
-			err = 1;
-	}
-#else
-	else
-		err = 1;
-#endif
-
-	/*
-	 * We want internal/wltest driver to come up with default
-	 * sromvars so we can program a blank SPROM/OTP.
-	 */
-	if (err) {
-		char *value;
-		u32 val;
-		val = 0;
-
-		BS_ERROR(("Neither SPROM nor OTP has valid image\n"));
-		value = si_getdevpathvar(sih, "sromrev");
-		if (value) {
-			sromrev = (u8) simple_strtoul(value, NULL, 0);
-			flash = true;
-			goto varscont;
-		}
-
-		BS_ERROR(("%s, SROM CRC Error\n", __func__));
-
-		value = si_getnvramflvar(sih, "sromrev");
-		if (value) {
-			err = 0;
-			goto errout;
-		}
-
-		{
-			err = -1;
-			goto errout;
-		}
-	}
-
- varscont:
-	/* Bitmask for the sromrev */
-	sr = 1 << sromrev;
-
-	/* srom version check: Current valid versions: 1, 2, 3, 4, 5, 8, 9 */
-	if ((sr & 0x33e) == 0) {
-		err = -2;
-		goto errout;
-	}
-
-	ASSERT(vars != NULL);
-	ASSERT(count != NULL);
-
-	base = vp = kmalloc(MAXSZ_NVRAM_VARS, GFP_ATOMIC);
-	ASSERT(vp != NULL);
-	if (!vp) {
-		err = -2;
-		goto errout;
-	}
-
-	/* read variables from flash */
-	if (flash) {
-		err = initvars_flash(sih, &vp, MAXSZ_NVRAM_VARS);
-		if (err)
-			goto errout;
-		goto varsdone;
-	}
-
-	varbuf_init(&b, base, MAXSZ_NVRAM_VARS);
-
-	/* parse SROM into name=value pairs. */
-	_initvars_srom_pci(sromrev, srom, 0, &b);
-
-	/* final nullbyte terminator */
-	ASSERT(b.size >= 1);
-	vp = b.buf;
-	*vp++ = '\0';
-
-	ASSERT((vp - base) <= MAXSZ_NVRAM_VARS);
-
- varsdone:
-	err = initvars_table(base, vp, vars, count);
-
- errout:
-	if (base)
-		kfree(base);
-
-	kfree(srom);
-	return err;
-}
-
-#ifdef BCMSDIO
-/*
- * Read the SDIO cis and call parsecis to initialize the vars.
- * Return 0 on success, nonzero on error.
- */
-static int initvars_cis_sdio(char **vars, uint *count)
-{
-	u8 *cis[SBSDIO_NUM_FUNCTION + 1];
-	uint fn, numfn;
-	int rc = 0;
-
-	numfn = bcmsdh_query_iofnum(NULL);
-	ASSERT(numfn <= SDIOD_MAX_IOFUNCS);
-
-	for (fn = 0; fn <= numfn; fn++) {
-		cis[fn] = kzalloc(SBSDIO_CIS_SIZE_LIMIT, GFP_ATOMIC);
-		if (cis[fn] == NULL) {
-			rc = -1;
-			break;
-		}
-
-		if (bcmsdh_cis_read(NULL, fn, cis[fn], SBSDIO_CIS_SIZE_LIMIT) !=
-		    0) {
-			kfree(cis[fn]);
-			rc = -2;
-			break;
-		}
-	}
-
-	if (!rc)
-		rc = srom_parsecis(cis, fn, vars, count);
-
-	while (fn-- > 0)
-		kfree(cis[fn]);
-
-	return rc;
-}
-
-/* set SDIO sprom command register */
-static int sprom_cmd_sdio(u8 cmd)
-{
-	u8 status = 0;
-	uint wait_cnt = 1000;
-
-	/* write sprom command register */
-	bcmsdh_cfg_write(NULL, SDIO_FUNC_1, SBSDIO_SPROM_CS, cmd, NULL);
-
-	/* wait status */
-	while (wait_cnt--) {
-		status =
-		    bcmsdh_cfg_read(NULL, SDIO_FUNC_1, SBSDIO_SPROM_CS, NULL);
-		if (status & SBSDIO_SPROM_DONE)
-			return 0;
-	}
-
-	return 1;
-}
-
-/* read a word from the SDIO srom */
-static int sprom_read_sdio(u16 addr, u16 *data)
-{
-	u8 addr_l, addr_h, data_l, data_h;
-
-	addr_l = (u8) ((addr * 2) & 0xff);
-	addr_h = (u8) (((addr * 2) >> 8) & 0xff);
-
-	/* set address */
-	bcmsdh_cfg_write(NULL, SDIO_FUNC_1, SBSDIO_SPROM_ADDR_HIGH, addr_h,
-			 NULL);
-	bcmsdh_cfg_write(NULL, SDIO_FUNC_1, SBSDIO_SPROM_ADDR_LOW, addr_l,
-			 NULL);
-
-	/* do read */
-	if (sprom_cmd_sdio(SBSDIO_SPROM_READ))
-		return 1;
-
-	/* read data */
-	data_h =
-	    bcmsdh_cfg_read(NULL, SDIO_FUNC_1, SBSDIO_SPROM_DATA_HIGH, NULL);
-	data_l =
-	    bcmsdh_cfg_read(NULL, SDIO_FUNC_1, SBSDIO_SPROM_DATA_LOW, NULL);
-
-	*data = (data_h << 8) | data_l;
-	return 0;
-}
-#endif				/* BCMSDIO */
-
-static int initvars_srom_si(si_t *sih, void *curmap, char **vars, uint *varsz)
-{
-	/* Search flash nvram section for srom variables */
-	return initvars_flash_si(sih, vars, varsz);
-}
diff -druN linux-2.6.39-libre/drivers/staging/brcm80211/util/bcmsrom_tbl.h linux-3.0-rc7-libre/drivers/staging/brcm80211/util/bcmsrom_tbl.h
--- linux-2.6.39-libre/drivers/staging/brcm80211/util/bcmsrom_tbl.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/brcm80211/util/bcmsrom_tbl.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,583 +0,0 @@
-/*
- * Copyright (c) 2010 Broadcom Corporation
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#ifndef	_bcmsrom_tbl_h_
-#define	_bcmsrom_tbl_h_
-
-#include "sbpcmcia.h"
-#include "wlioctl.h"
-
-typedef struct {
-	const char *name;
-	u32 revmask;
-	u32 flags;
-	u16 off;
-	u16 mask;
-} sromvar_t;
-
-#define SRFL_MORE	1	/* value continues as described by the next entry */
-#define	SRFL_NOFFS	2	/* value bits can't be all one's */
-#define	SRFL_PRHEX	4	/* value is in hexdecimal format */
-#define	SRFL_PRSIGN	8	/* value is in signed decimal format */
-#define	SRFL_CCODE	0x10	/* value is in country code format */
-#define	SRFL_ETHADDR	0x20	/* value is an Ethernet address */
-#define SRFL_LEDDC	0x40	/* value is an LED duty cycle */
-#define SRFL_NOVAR	0x80	/* do not generate a nvram param, entry is for mfgc */
-
-/* Assumptions:
- * - Ethernet address spans across 3 consective words
- *
- * Table rules:
- * - Add multiple entries next to each other if a value spans across multiple words
- *   (even multiple fields in the same word) with each entry except the last having
- *   it's SRFL_MORE bit set.
- * - Ethernet address entry does not follow above rule and must not have SRFL_MORE
- *   bit set. Its SRFL_ETHADDR bit implies it takes multiple words.
- * - The last entry's name field must be NULL to indicate the end of the table. Other
- *   entries must have non-NULL name.
- */
-
-static const sromvar_t pci_sromvars[] = {
-	{"devid", 0xffffff00, SRFL_PRHEX | SRFL_NOVAR, PCI_F0DEVID, 0xffff},
-	{"boardrev", 0x0000000e, SRFL_PRHEX, SROM_AABREV, SROM_BR_MASK},
-	{"boardrev", 0x000000f0, SRFL_PRHEX, SROM4_BREV, 0xffff},
-	{"boardrev", 0xffffff00, SRFL_PRHEX, SROM8_BREV, 0xffff},
-	{"boardflags", 0x00000002, SRFL_PRHEX, SROM_BFL, 0xffff},
-	{"boardflags", 0x00000004, SRFL_PRHEX | SRFL_MORE, SROM_BFL, 0xffff},
-	{"", 0, 0, SROM_BFL2, 0xffff},
-	{"boardflags", 0x00000008, SRFL_PRHEX | SRFL_MORE, SROM_BFL, 0xffff},
-	{"", 0, 0, SROM3_BFL2, 0xffff},
-	{"boardflags", 0x00000010, SRFL_PRHEX | SRFL_MORE, SROM4_BFL0, 0xffff},
-	{"", 0, 0, SROM4_BFL1, 0xffff},
-	{"boardflags", 0x000000e0, SRFL_PRHEX | SRFL_MORE, SROM5_BFL0, 0xffff},
-	{"", 0, 0, SROM5_BFL1, 0xffff},
-	{"boardflags", 0xffffff00, SRFL_PRHEX | SRFL_MORE, SROM8_BFL0, 0xffff},
-	{"", 0, 0, SROM8_BFL1, 0xffff},
-	{"boardflags2", 0x00000010, SRFL_PRHEX | SRFL_MORE, SROM4_BFL2, 0xffff},
-	{"", 0, 0, SROM4_BFL3, 0xffff},
-	{"boardflags2", 0x000000e0, SRFL_PRHEX | SRFL_MORE, SROM5_BFL2, 0xffff},
-	{"", 0, 0, SROM5_BFL3, 0xffff},
-	{"boardflags2", 0xffffff00, SRFL_PRHEX | SRFL_MORE, SROM8_BFL2, 0xffff},
-	{"", 0, 0, SROM8_BFL3, 0xffff},
-	{"boardtype", 0xfffffffc, SRFL_PRHEX, SROM_SSID, 0xffff},
-	{"boardnum", 0x00000006, 0, SROM_MACLO_IL0, 0xffff},
-	{"boardnum", 0x00000008, 0, SROM3_MACLO, 0xffff},
-	{"boardnum", 0x00000010, 0, SROM4_MACLO, 0xffff},
-	{"boardnum", 0x000000e0, 0, SROM5_MACLO, 0xffff},
-	{"boardnum", 0xffffff00, 0, SROM8_MACLO, 0xffff},
-	{"cc", 0x00000002, 0, SROM_AABREV, SROM_CC_MASK},
-	{"regrev", 0x00000008, 0, SROM_OPO, 0xff00},
-	{"regrev", 0x00000010, 0, SROM4_REGREV, 0x00ff},
-	{"regrev", 0x000000e0, 0, SROM5_REGREV, 0x00ff},
-	{"regrev", 0xffffff00, 0, SROM8_REGREV, 0x00ff},
-	{"ledbh0", 0x0000000e, SRFL_NOFFS, SROM_LEDBH10, 0x00ff},
-	{"ledbh1", 0x0000000e, SRFL_NOFFS, SROM_LEDBH10, 0xff00},
-	{"ledbh2", 0x0000000e, SRFL_NOFFS, SROM_LEDBH32, 0x00ff},
-	{"ledbh3", 0x0000000e, SRFL_NOFFS, SROM_LEDBH32, 0xff00},
-	{"ledbh0", 0x00000010, SRFL_NOFFS, SROM4_LEDBH10, 0x00ff},
-	{"ledbh1", 0x00000010, SRFL_NOFFS, SROM4_LEDBH10, 0xff00},
-	{"ledbh2", 0x00000010, SRFL_NOFFS, SROM4_LEDBH32, 0x00ff},
-	{"ledbh3", 0x00000010, SRFL_NOFFS, SROM4_LEDBH32, 0xff00},
-	{"ledbh0", 0x000000e0, SRFL_NOFFS, SROM5_LEDBH10, 0x00ff},
-	{"ledbh1", 0x000000e0, SRFL_NOFFS, SROM5_LEDBH10, 0xff00},
-	{"ledbh2", 0x000000e0, SRFL_NOFFS, SROM5_LEDBH32, 0x00ff},
-	{"ledbh3", 0x000000e0, SRFL_NOFFS, SROM5_LEDBH32, 0xff00},
-	{"ledbh0", 0xffffff00, SRFL_NOFFS, SROM8_LEDBH10, 0x00ff},
-	{"ledbh1", 0xffffff00, SRFL_NOFFS, SROM8_LEDBH10, 0xff00},
-	{"ledbh2", 0xffffff00, SRFL_NOFFS, SROM8_LEDBH32, 0x00ff},
-	{"ledbh3", 0xffffff00, SRFL_NOFFS, SROM8_LEDBH32, 0xff00},
-	{"pa0b0", 0x0000000e, SRFL_PRHEX, SROM_WL0PAB0, 0xffff},
-	{"pa0b1", 0x0000000e, SRFL_PRHEX, SROM_WL0PAB1, 0xffff},
-	{"pa0b2", 0x0000000e, SRFL_PRHEX, SROM_WL0PAB2, 0xffff},
-	{"pa0itssit", 0x0000000e, 0, SROM_ITT, 0x00ff},
-	{"pa0maxpwr", 0x0000000e, 0, SROM_WL10MAXP, 0x00ff},
-	{"pa0b0", 0xffffff00, SRFL_PRHEX, SROM8_W0_PAB0, 0xffff},
-	{"pa0b1", 0xffffff00, SRFL_PRHEX, SROM8_W0_PAB1, 0xffff},
-	{"pa0b2", 0xffffff00, SRFL_PRHEX, SROM8_W0_PAB2, 0xffff},
-	{"pa0itssit", 0xffffff00, 0, SROM8_W0_ITTMAXP, 0xff00},
-	{"pa0maxpwr", 0xffffff00, 0, SROM8_W0_ITTMAXP, 0x00ff},
-	{"opo", 0x0000000c, 0, SROM_OPO, 0x00ff},
-	{"opo", 0xffffff00, 0, SROM8_2G_OFDMPO, 0x00ff},
-	{"aa2g", 0x0000000e, 0, SROM_AABREV, SROM_AA0_MASK},
-	{"aa2g", 0x000000f0, 0, SROM4_AA, 0x00ff},
-	{"aa2g", 0xffffff00, 0, SROM8_AA, 0x00ff},
-	{"aa5g", 0x0000000e, 0, SROM_AABREV, SROM_AA1_MASK},
-	{"aa5g", 0x000000f0, 0, SROM4_AA, 0xff00},
-	{"aa5g", 0xffffff00, 0, SROM8_AA, 0xff00},
-	{"ag0", 0x0000000e, 0, SROM_AG10, 0x00ff},
-	{"ag1", 0x0000000e, 0, SROM_AG10, 0xff00},
-	{"ag0", 0x000000f0, 0, SROM4_AG10, 0x00ff},
-	{"ag1", 0x000000f0, 0, SROM4_AG10, 0xff00},
-	{"ag2", 0x000000f0, 0, SROM4_AG32, 0x00ff},
-	{"ag3", 0x000000f0, 0, SROM4_AG32, 0xff00},
-	{"ag0", 0xffffff00, 0, SROM8_AG10, 0x00ff},
-	{"ag1", 0xffffff00, 0, SROM8_AG10, 0xff00},
-	{"ag2", 0xffffff00, 0, SROM8_AG32, 0x00ff},
-	{"ag3", 0xffffff00, 0, SROM8_AG32, 0xff00},
-	{"pa1b0", 0x0000000e, SRFL_PRHEX, SROM_WL1PAB0, 0xffff},
-	{"pa1b1", 0x0000000e, SRFL_PRHEX, SROM_WL1PAB1, 0xffff},
-	{"pa1b2", 0x0000000e, SRFL_PRHEX, SROM_WL1PAB2, 0xffff},
-	{"pa1lob0", 0x0000000c, SRFL_PRHEX, SROM_WL1LPAB0, 0xffff},
-	{"pa1lob1", 0x0000000c, SRFL_PRHEX, SROM_WL1LPAB1, 0xffff},
-	{"pa1lob2", 0x0000000c, SRFL_PRHEX, SROM_WL1LPAB2, 0xffff},
-	{"pa1hib0", 0x0000000c, SRFL_PRHEX, SROM_WL1HPAB0, 0xffff},
-	{"pa1hib1", 0x0000000c, SRFL_PRHEX, SROM_WL1HPAB1, 0xffff},
-	{"pa1hib2", 0x0000000c, SRFL_PRHEX, SROM_WL1HPAB2, 0xffff},
-	{"pa1itssit", 0x0000000e, 0, SROM_ITT, 0xff00},
-	{"pa1maxpwr", 0x0000000e, 0, SROM_WL10MAXP, 0xff00},
-	{"pa1lomaxpwr", 0x0000000c, 0, SROM_WL1LHMAXP, 0xff00},
-	{"pa1himaxpwr", 0x0000000c, 0, SROM_WL1LHMAXP, 0x00ff},
-	{"pa1b0", 0xffffff00, SRFL_PRHEX, SROM8_W1_PAB0, 0xffff},
-	{"pa1b1", 0xffffff00, SRFL_PRHEX, SROM8_W1_PAB1, 0xffff},
-	{"pa1b2", 0xffffff00, SRFL_PRHEX, SROM8_W1_PAB2, 0xffff},
-	{"pa1lob0", 0xffffff00, SRFL_PRHEX, SROM8_W1_PAB0_LC, 0xffff},
-	{"pa1lob1", 0xffffff00, SRFL_PRHEX, SROM8_W1_PAB1_LC, 0xffff},
-	{"pa1lob2", 0xffffff00, SRFL_PRHEX, SROM8_W1_PAB2_LC, 0xffff},
-	{"pa1hib0", 0xffffff00, SRFL_PRHEX, SROM8_W1_PAB0_HC, 0xffff},
-	{"pa1hib1", 0xffffff00, SRFL_PRHEX, SROM8_W1_PAB1_HC, 0xffff},
-	{"pa1hib2", 0xffffff00, SRFL_PRHEX, SROM8_W1_PAB2_HC, 0xffff},
-	{"pa1itssit", 0xffffff00, 0, SROM8_W1_ITTMAXP, 0xff00},
-	{"pa1maxpwr", 0xffffff00, 0, SROM8_W1_ITTMAXP, 0x00ff},
-	{"pa1lomaxpwr", 0xffffff00, 0, SROM8_W1_MAXP_LCHC, 0xff00},
-	{"pa1himaxpwr", 0xffffff00, 0, SROM8_W1_MAXP_LCHC, 0x00ff},
-	{"bxa2g", 0x00000008, 0, SROM_BXARSSI2G, 0x1800},
-	{"rssisav2g", 0x00000008, 0, SROM_BXARSSI2G, 0x0700},
-	{"rssismc2g", 0x00000008, 0, SROM_BXARSSI2G, 0x00f0},
-	{"rssismf2g", 0x00000008, 0, SROM_BXARSSI2G, 0x000f},
-	{"bxa2g", 0xffffff00, 0, SROM8_BXARSSI2G, 0x1800},
-	{"rssisav2g", 0xffffff00, 0, SROM8_BXARSSI2G, 0x0700},
-	{"rssismc2g", 0xffffff00, 0, SROM8_BXARSSI2G, 0x00f0},
-	{"rssismf2g", 0xffffff00, 0, SROM8_BXARSSI2G, 0x000f},
-	{"bxa5g", 0x00000008, 0, SROM_BXARSSI5G, 0x1800},
-	{"rssisav5g", 0x00000008, 0, SROM_BXARSSI5G, 0x0700},
-	{"rssismc5g", 0x00000008, 0, SROM_BXARSSI5G, 0x00f0},
-	{"rssismf5g", 0x00000008, 0, SROM_BXARSSI5G, 0x000f},
-	{"bxa5g", 0xffffff00, 0, SROM8_BXARSSI5G, 0x1800},
-	{"rssisav5g", 0xffffff00, 0, SROM8_BXARSSI5G, 0x0700},
-	{"rssismc5g", 0xffffff00, 0, SROM8_BXARSSI5G, 0x00f0},
-	{"rssismf5g", 0xffffff00, 0, SROM8_BXARSSI5G, 0x000f},
-	{"tri2g", 0x00000008, 0, SROM_TRI52G, 0x00ff},
-	{"tri5g", 0x00000008, 0, SROM_TRI52G, 0xff00},
-	{"tri5gl", 0x00000008, 0, SROM_TRI5GHL, 0x00ff},
-	{"tri5gh", 0x00000008, 0, SROM_TRI5GHL, 0xff00},
-	{"tri2g", 0xffffff00, 0, SROM8_TRI52G, 0x00ff},
-	{"tri5g", 0xffffff00, 0, SROM8_TRI52G, 0xff00},
-	{"tri5gl", 0xffffff00, 0, SROM8_TRI5GHL, 0x00ff},
-	{"tri5gh", 0xffffff00, 0, SROM8_TRI5GHL, 0xff00},
-	{"rxpo2g", 0x00000008, SRFL_PRSIGN, SROM_RXPO52G, 0x00ff},
-	{"rxpo5g", 0x00000008, SRFL_PRSIGN, SROM_RXPO52G, 0xff00},
-	{"rxpo2g", 0xffffff00, SRFL_PRSIGN, SROM8_RXPO52G, 0x00ff},
-	{"rxpo5g", 0xffffff00, SRFL_PRSIGN, SROM8_RXPO52G, 0xff00},
-	{"txchain", 0x000000f0, SRFL_NOFFS, SROM4_TXRXC, SROM4_TXCHAIN_MASK},
-	{"rxchain", 0x000000f0, SRFL_NOFFS, SROM4_TXRXC, SROM4_RXCHAIN_MASK},
-	{"antswitch", 0x000000f0, SRFL_NOFFS, SROM4_TXRXC, SROM4_SWITCH_MASK},
-	{"txchain", 0xffffff00, SRFL_NOFFS, SROM8_TXRXC, SROM4_TXCHAIN_MASK},
-	{"rxchain", 0xffffff00, SRFL_NOFFS, SROM8_TXRXC, SROM4_RXCHAIN_MASK},
-	{"antswitch", 0xffffff00, SRFL_NOFFS, SROM8_TXRXC, SROM4_SWITCH_MASK},
-	{"tssipos2g", 0xffffff00, 0, SROM8_FEM2G, SROM8_FEM_TSSIPOS_MASK},
-	{"extpagain2g", 0xffffff00, 0, SROM8_FEM2G, SROM8_FEM_EXTPA_GAIN_MASK},
-	{"pdetrange2g", 0xffffff00, 0, SROM8_FEM2G, SROM8_FEM_PDET_RANGE_MASK},
-	{"triso2g", 0xffffff00, 0, SROM8_FEM2G, SROM8_FEM_TR_ISO_MASK},
-	{"antswctl2g", 0xffffff00, 0, SROM8_FEM2G, SROM8_FEM_ANTSWLUT_MASK},
-	{"tssipos5g", 0xffffff00, 0, SROM8_FEM5G, SROM8_FEM_TSSIPOS_MASK},
-	{"extpagain5g", 0xffffff00, 0, SROM8_FEM5G, SROM8_FEM_EXTPA_GAIN_MASK},
-	{"pdetrange5g", 0xffffff00, 0, SROM8_FEM5G, SROM8_FEM_PDET_RANGE_MASK},
-	{"triso5g", 0xffffff00, 0, SROM8_FEM5G, SROM8_FEM_TR_ISO_MASK},
-	{"antswctl5g", 0xffffff00, 0, SROM8_FEM5G, SROM8_FEM_ANTSWLUT_MASK},
-	{"tempthresh", 0xffffff00, 0, SROM8_THERMAL, 0xff00},
-	{"tempoffset", 0xffffff00, 0, SROM8_THERMAL, 0x00ff},
-	{"txpid2ga0", 0x000000f0, 0, SROM4_TXPID2G, 0x00ff},
-	{"txpid2ga1", 0x000000f0, 0, SROM4_TXPID2G, 0xff00},
-	{"txpid2ga2", 0x000000f0, 0, SROM4_TXPID2G + 1, 0x00ff},
-	{"txpid2ga3", 0x000000f0, 0, SROM4_TXPID2G + 1, 0xff00},
-	{"txpid5ga0", 0x000000f0, 0, SROM4_TXPID5G, 0x00ff},
-	{"txpid5ga1", 0x000000f0, 0, SROM4_TXPID5G, 0xff00},
-	{"txpid5ga2", 0x000000f0, 0, SROM4_TXPID5G + 1, 0x00ff},
-	{"txpid5ga3", 0x000000f0, 0, SROM4_TXPID5G + 1, 0xff00},
-	{"txpid5gla0", 0x000000f0, 0, SROM4_TXPID5GL, 0x00ff},
-	{"txpid5gla1", 0x000000f0, 0, SROM4_TXPID5GL, 0xff00},
-	{"txpid5gla2", 0x000000f0, 0, SROM4_TXPID5GL + 1, 0x00ff},
-	{"txpid5gla3", 0x000000f0, 0, SROM4_TXPID5GL + 1, 0xff00},
-	{"txpid5gha0", 0x000000f0, 0, SROM4_TXPID5GH, 0x00ff},
-	{"txpid5gha1", 0x000000f0, 0, SROM4_TXPID5GH, 0xff00},
-	{"txpid5gha2", 0x000000f0, 0, SROM4_TXPID5GH + 1, 0x00ff},
-	{"txpid5gha3", 0x000000f0, 0, SROM4_TXPID5GH + 1, 0xff00},
-
-	{"ccode", 0x0000000f, SRFL_CCODE, SROM_CCODE, 0xffff},
-	{"ccode", 0x00000010, SRFL_CCODE, SROM4_CCODE, 0xffff},
-	{"ccode", 0x000000e0, SRFL_CCODE, SROM5_CCODE, 0xffff},
-	{"ccode", 0xffffff00, SRFL_CCODE, SROM8_CCODE, 0xffff},
-	{"macaddr", 0xffffff00, SRFL_ETHADDR, SROM8_MACHI, 0xffff},
-	{"macaddr", 0x000000e0, SRFL_ETHADDR, SROM5_MACHI, 0xffff},
-	{"macaddr", 0x00000010, SRFL_ETHADDR, SROM4_MACHI, 0xffff},
-	{"macaddr", 0x00000008, SRFL_ETHADDR, SROM3_MACHI, 0xffff},
-	{"il0macaddr", 0x00000007, SRFL_ETHADDR, SROM_MACHI_IL0, 0xffff},
-	{"et1macaddr", 0x00000007, SRFL_ETHADDR, SROM_MACHI_ET1, 0xffff},
-	{"leddc", 0xffffff00, SRFL_NOFFS | SRFL_LEDDC, SROM8_LEDDC, 0xffff},
-	{"leddc", 0x000000e0, SRFL_NOFFS | SRFL_LEDDC, SROM5_LEDDC, 0xffff},
-	{"leddc", 0x00000010, SRFL_NOFFS | SRFL_LEDDC, SROM4_LEDDC, 0xffff},
-	{"leddc", 0x00000008, SRFL_NOFFS | SRFL_LEDDC, SROM3_LEDDC, 0xffff},
-	{"rawtempsense", 0xffffff00, SRFL_PRHEX, SROM8_MPWR_RAWTS, 0x01ff},
-	{"measpower", 0xffffff00, SRFL_PRHEX, SROM8_MPWR_RAWTS, 0xfe00},
-	{"tempsense_slope", 0xffffff00, SRFL_PRHEX, SROM8_TS_SLP_OPT_CORRX,
-	 0x00ff},
-	{"tempcorrx", 0xffffff00, SRFL_PRHEX, SROM8_TS_SLP_OPT_CORRX, 0xfc00},
-	{"tempsense_option", 0xffffff00, SRFL_PRHEX, SROM8_TS_SLP_OPT_CORRX,
-	 0x0300},
-	{"freqoffset_corr", 0xffffff00, SRFL_PRHEX, SROM8_FOC_HWIQ_IQSWP,
-	 0x000f},
-	{"iqcal_swp_dis", 0xffffff00, SRFL_PRHEX, SROM8_FOC_HWIQ_IQSWP, 0x0010},
-	{"hw_iqcal_en", 0xffffff00, SRFL_PRHEX, SROM8_FOC_HWIQ_IQSWP, 0x0020},
-	{"phycal_tempdelta", 0xffffff00, 0, SROM8_PHYCAL_TEMPDELTA, 0x00ff},
-
-	{"cck2gpo", 0x000000f0, 0, SROM4_2G_CCKPO, 0xffff},
-	{"cck2gpo", 0x00000100, 0, SROM8_2G_CCKPO, 0xffff},
-	{"ofdm2gpo", 0x000000f0, SRFL_MORE, SROM4_2G_OFDMPO, 0xffff},
-	{"", 0, 0, SROM4_2G_OFDMPO + 1, 0xffff},
-	{"ofdm5gpo", 0x000000f0, SRFL_MORE, SROM4_5G_OFDMPO, 0xffff},
-	{"", 0, 0, SROM4_5G_OFDMPO + 1, 0xffff},
-	{"ofdm5glpo", 0x000000f0, SRFL_MORE, SROM4_5GL_OFDMPO, 0xffff},
-	{"", 0, 0, SROM4_5GL_OFDMPO + 1, 0xffff},
-	{"ofdm5ghpo", 0x000000f0, SRFL_MORE, SROM4_5GH_OFDMPO, 0xffff},
-	{"", 0, 0, SROM4_5GH_OFDMPO + 1, 0xffff},
-	{"ofdm2gpo", 0x00000100, SRFL_MORE, SROM8_2G_OFDMPO, 0xffff},
-	{"", 0, 0, SROM8_2G_OFDMPO + 1, 0xffff},
-	{"ofdm5gpo", 0x00000100, SRFL_MORE, SROM8_5G_OFDMPO, 0xffff},
-	{"", 0, 0, SROM8_5G_OFDMPO + 1, 0xffff},
-	{"ofdm5glpo", 0x00000100, SRFL_MORE, SROM8_5GL_OFDMPO, 0xffff},
-	{"", 0, 0, SROM8_5GL_OFDMPO + 1, 0xffff},
-	{"ofdm5ghpo", 0x00000100, SRFL_MORE, SROM8_5GH_OFDMPO, 0xffff},
-	{"", 0, 0, SROM8_5GH_OFDMPO + 1, 0xffff},
-	{"mcs2gpo0", 0x000000f0, 0, SROM4_2G_MCSPO, 0xffff},
-	{"mcs2gpo1", 0x000000f0, 0, SROM4_2G_MCSPO + 1, 0xffff},
-	{"mcs2gpo2", 0x000000f0, 0, SROM4_2G_MCSPO + 2, 0xffff},
-	{"mcs2gpo3", 0x000000f0, 0, SROM4_2G_MCSPO + 3, 0xffff},
-	{"mcs2gpo4", 0x000000f0, 0, SROM4_2G_MCSPO + 4, 0xffff},
-	{"mcs2gpo5", 0x000000f0, 0, SROM4_2G_MCSPO + 5, 0xffff},
-	{"mcs2gpo6", 0x000000f0, 0, SROM4_2G_MCSPO + 6, 0xffff},
-	{"mcs2gpo7", 0x000000f0, 0, SROM4_2G_MCSPO + 7, 0xffff},
-	{"mcs5gpo0", 0x000000f0, 0, SROM4_5G_MCSPO, 0xffff},
-	{"mcs5gpo1", 0x000000f0, 0, SROM4_5G_MCSPO + 1, 0xffff},
-	{"mcs5gpo2", 0x000000f0, 0, SROM4_5G_MCSPO + 2, 0xffff},
-	{"mcs5gpo3", 0x000000f0, 0, SROM4_5G_MCSPO + 3, 0xffff},
-	{"mcs5gpo4", 0x000000f0, 0, SROM4_5G_MCSPO + 4, 0xffff},
-	{"mcs5gpo5", 0x000000f0, 0, SROM4_5G_MCSPO + 5, 0xffff},
-	{"mcs5gpo6", 0x000000f0, 0, SROM4_5G_MCSPO + 6, 0xffff},
-	{"mcs5gpo7", 0x000000f0, 0, SROM4_5G_MCSPO + 7, 0xffff},
-	{"mcs5glpo0", 0x000000f0, 0, SROM4_5GL_MCSPO, 0xffff},
-	{"mcs5glpo1", 0x000000f0, 0, SROM4_5GL_MCSPO + 1, 0xffff},
-	{"mcs5glpo2", 0x000000f0, 0, SROM4_5GL_MCSPO + 2, 0xffff},
-	{"mcs5glpo3", 0x000000f0, 0, SROM4_5GL_MCSPO + 3, 0xffff},
-	{"mcs5glpo4", 0x000000f0, 0, SROM4_5GL_MCSPO + 4, 0xffff},
-	{"mcs5glpo5", 0x000000f0, 0, SROM4_5GL_MCSPO + 5, 0xffff},
-	{"mcs5glpo6", 0x000000f0, 0, SROM4_5GL_MCSPO + 6, 0xffff},
-	{"mcs5glpo7", 0x000000f0, 0, SROM4_5GL_MCSPO + 7, 0xffff},
-	{"mcs5ghpo0", 0x000000f0, 0, SROM4_5GH_MCSPO, 0xffff},
-	{"mcs5ghpo1", 0x000000f0, 0, SROM4_5GH_MCSPO + 1, 0xffff},
-	{"mcs5ghpo2", 0x000000f0, 0, SROM4_5GH_MCSPO + 2, 0xffff},
-	{"mcs5ghpo3", 0x000000f0, 0, SROM4_5GH_MCSPO + 3, 0xffff},
-	{"mcs5ghpo4", 0x000000f0, 0, SROM4_5GH_MCSPO + 4, 0xffff},
-	{"mcs5ghpo5", 0x000000f0, 0, SROM4_5GH_MCSPO + 5, 0xffff},
-	{"mcs5ghpo6", 0x000000f0, 0, SROM4_5GH_MCSPO + 6, 0xffff},
-	{"mcs5ghpo7", 0x000000f0, 0, SROM4_5GH_MCSPO + 7, 0xffff},
-	{"mcs2gpo0", 0x00000100, 0, SROM8_2G_MCSPO, 0xffff},
-	{"mcs2gpo1", 0x00000100, 0, SROM8_2G_MCSPO + 1, 0xffff},
-	{"mcs2gpo2", 0x00000100, 0, SROM8_2G_MCSPO + 2, 0xffff},
-	{"mcs2gpo3", 0x00000100, 0, SROM8_2G_MCSPO + 3, 0xffff},
-	{"mcs2gpo4", 0x00000100, 0, SROM8_2G_MCSPO + 4, 0xffff},
-	{"mcs2gpo5", 0x00000100, 0, SROM8_2G_MCSPO + 5, 0xffff},
-	{"mcs2gpo6", 0x00000100, 0, SROM8_2G_MCSPO + 6, 0xffff},
-	{"mcs2gpo7", 0x00000100, 0, SROM8_2G_MCSPO + 7, 0xffff},
-	{"mcs5gpo0", 0x00000100, 0, SROM8_5G_MCSPO, 0xffff},
-	{"mcs5gpo1", 0x00000100, 0, SROM8_5G_MCSPO + 1, 0xffff},
-	{"mcs5gpo2", 0x00000100, 0, SROM8_5G_MCSPO + 2, 0xffff},
-	{"mcs5gpo3", 0x00000100, 0, SROM8_5G_MCSPO + 3, 0xffff},
-	{"mcs5gpo4", 0x00000100, 0, SROM8_5G_MCSPO + 4, 0xffff},
-	{"mcs5gpo5", 0x00000100, 0, SROM8_5G_MCSPO + 5, 0xffff},
-	{"mcs5gpo6", 0x00000100, 0, SROM8_5G_MCSPO + 6, 0xffff},
-	{"mcs5gpo7", 0x00000100, 0, SROM8_5G_MCSPO + 7, 0xffff},
-	{"mcs5glpo0", 0x00000100, 0, SROM8_5GL_MCSPO, 0xffff},
-	{"mcs5glpo1", 0x00000100, 0, SROM8_5GL_MCSPO + 1, 0xffff},
-	{"mcs5glpo2", 0x00000100, 0, SROM8_5GL_MCSPO + 2, 0xffff},
-	{"mcs5glpo3", 0x00000100, 0, SROM8_5GL_MCSPO + 3, 0xffff},
-	{"mcs5glpo4", 0x00000100, 0, SROM8_5GL_MCSPO + 4, 0xffff},
-	{"mcs5glpo5", 0x00000100, 0, SROM8_5GL_MCSPO + 5, 0xffff},
-	{"mcs5glpo6", 0x00000100, 0, SROM8_5GL_MCSPO + 6, 0xffff},
-	{"mcs5glpo7", 0x00000100, 0, SROM8_5GL_MCSPO + 7, 0xffff},
-	{"mcs5ghpo0", 0x00000100, 0, SROM8_5GH_MCSPO, 0xffff},
-	{"mcs5ghpo1", 0x00000100, 0, SROM8_5GH_MCSPO + 1, 0xffff},
-	{"mcs5ghpo2", 0x00000100, 0, SROM8_5GH_MCSPO + 2, 0xffff},
-	{"mcs5ghpo3", 0x00000100, 0, SROM8_5GH_MCSPO + 3, 0xffff},
-	{"mcs5ghpo4", 0x00000100, 0, SROM8_5GH_MCSPO + 4, 0xffff},
-	{"mcs5ghpo5", 0x00000100, 0, SROM8_5GH_MCSPO + 5, 0xffff},
-	{"mcs5ghpo6", 0x00000100, 0, SROM8_5GH_MCSPO + 6, 0xffff},
-	{"mcs5ghpo7", 0x00000100, 0, SROM8_5GH_MCSPO + 7, 0xffff},
-	{"cddpo", 0x000000f0, 0, SROM4_CDDPO, 0xffff},
-	{"stbcpo", 0x000000f0, 0, SROM4_STBCPO, 0xffff},
-	{"bw40po", 0x000000f0, 0, SROM4_BW40PO, 0xffff},
-	{"bwduppo", 0x000000f0, 0, SROM4_BWDUPPO, 0xffff},
-	{"cddpo", 0x00000100, 0, SROM8_CDDPO, 0xffff},
-	{"stbcpo", 0x00000100, 0, SROM8_STBCPO, 0xffff},
-	{"bw40po", 0x00000100, 0, SROM8_BW40PO, 0xffff},
-	{"bwduppo", 0x00000100, 0, SROM8_BWDUPPO, 0xffff},
-
-	/* power per rate from sromrev 9 */
-	{"cckbw202gpo", 0xfffffe00, 0, SROM9_2GPO_CCKBW20, 0xffff},
-	{"cckbw20ul2gpo", 0xfffffe00, 0, SROM9_2GPO_CCKBW20UL, 0xffff},
-	{"legofdmbw202gpo", 0xfffffe00, SRFL_MORE, SROM9_2GPO_LOFDMBW20,
-	 0xffff},
-	{"", 0, 0, SROM9_2GPO_LOFDMBW20 + 1, 0xffff},
-	{"legofdmbw20ul2gpo", 0xfffffe00, SRFL_MORE, SROM9_2GPO_LOFDMBW20UL,
-	 0xffff},
-	{"", 0, 0, SROM9_2GPO_LOFDMBW20UL + 1, 0xffff},
-	{"legofdmbw205glpo", 0xfffffe00, SRFL_MORE, SROM9_5GLPO_LOFDMBW20,
-	 0xffff},
-	{"", 0, 0, SROM9_5GLPO_LOFDMBW20 + 1, 0xffff},
-	{"legofdmbw20ul5glpo", 0xfffffe00, SRFL_MORE, SROM9_5GLPO_LOFDMBW20UL,
-	 0xffff},
-	{"", 0, 0, SROM9_5GLPO_LOFDMBW20UL + 1, 0xffff},
-	{"legofdmbw205gmpo", 0xfffffe00, SRFL_MORE, SROM9_5GMPO_LOFDMBW20,
-	 0xffff},
-	{"", 0, 0, SROM9_5GMPO_LOFDMBW20 + 1, 0xffff},
-	{"legofdmbw20ul5gmpo", 0xfffffe00, SRFL_MORE, SROM9_5GMPO_LOFDMBW20UL,
-	 0xffff},
-	{"", 0, 0, SROM9_5GMPO_LOFDMBW20UL + 1, 0xffff},
-	{"legofdmbw205ghpo", 0xfffffe00, SRFL_MORE, SROM9_5GHPO_LOFDMBW20,
-	 0xffff},
-	{"", 0, 0, SROM9_5GHPO_LOFDMBW20 + 1, 0xffff},
-	{"legofdmbw20ul5ghpo", 0xfffffe00, SRFL_MORE, SROM9_5GHPO_LOFDMBW20UL,
-	 0xffff},
-	{"", 0, 0, SROM9_5GHPO_LOFDMBW20UL + 1, 0xffff},
-	{"mcsbw202gpo", 0xfffffe00, SRFL_MORE, SROM9_2GPO_MCSBW20, 0xffff},
-	{"", 0, 0, SROM9_2GPO_MCSBW20 + 1, 0xffff},
-	{"mcsbw20ul2gpo", 0xfffffe00, SRFL_MORE, SROM9_2GPO_MCSBW20UL, 0xffff},
-	{"", 0, 0, SROM9_2GPO_MCSBW20UL + 1, 0xffff},
-	{"mcsbw402gpo", 0xfffffe00, SRFL_MORE, SROM9_2GPO_MCSBW40, 0xffff},
-	{"", 0, 0, SROM9_2GPO_MCSBW40 + 1, 0xffff},
-	{"mcsbw205glpo", 0xfffffe00, SRFL_MORE, SROM9_5GLPO_MCSBW20, 0xffff},
-	{"", 0, 0, SROM9_5GLPO_MCSBW20 + 1, 0xffff},
-	{"mcsbw20ul5glpo", 0xfffffe00, SRFL_MORE, SROM9_5GLPO_MCSBW20UL,
-	 0xffff},
-	{"", 0, 0, SROM9_5GLPO_MCSBW20UL + 1, 0xffff},
-	{"mcsbw405glpo", 0xfffffe00, SRFL_MORE, SROM9_5GLPO_MCSBW40, 0xffff},
-	{"", 0, 0, SROM9_5GLPO_MCSBW40 + 1, 0xffff},
-	{"mcsbw205gmpo", 0xfffffe00, SRFL_MORE, SROM9_5GMPO_MCSBW20, 0xffff},
-	{"", 0, 0, SROM9_5GMPO_MCSBW20 + 1, 0xffff},
-	{"mcsbw20ul5gmpo", 0xfffffe00, SRFL_MORE, SROM9_5GMPO_MCSBW20UL,
-	 0xffff},
-	{"", 0, 0, SROM9_5GMPO_MCSBW20UL + 1, 0xffff},
-	{"mcsbw405gmpo", 0xfffffe00, SRFL_MORE, SROM9_5GMPO_MCSBW40, 0xffff},
-	{"", 0, 0, SROM9_5GMPO_MCSBW40 + 1, 0xffff},
-	{"mcsbw205ghpo", 0xfffffe00, SRFL_MORE, SROM9_5GHPO_MCSBW20, 0xffff},
-	{"", 0, 0, SROM9_5GHPO_MCSBW20 + 1, 0xffff},
-	{"mcsbw20ul5ghpo", 0xfffffe00, SRFL_MORE, SROM9_5GHPO_MCSBW20UL,
-	 0xffff},
-	{"", 0, 0, SROM9_5GHPO_MCSBW20UL + 1, 0xffff},
-	{"mcsbw405ghpo", 0xfffffe00, SRFL_MORE, SROM9_5GHPO_MCSBW40, 0xffff},
-	{"", 0, 0, SROM9_5GHPO_MCSBW40 + 1, 0xffff},
-	{"mcs32po", 0xfffffe00, 0, SROM9_PO_MCS32, 0xffff},
-	{"legofdm40duppo", 0xfffffe00, 0, SROM9_PO_LOFDM40DUP, 0xffff},
-
-	{NULL, 0, 0, 0, 0}
-};
-
-static const sromvar_t perpath_pci_sromvars[] = {
-	{"maxp2ga", 0x000000f0, 0, SROM4_2G_ITT_MAXP, 0x00ff},
-	{"itt2ga", 0x000000f0, 0, SROM4_2G_ITT_MAXP, 0xff00},
-	{"itt5ga", 0x000000f0, 0, SROM4_5G_ITT_MAXP, 0xff00},
-	{"pa2gw0a", 0x000000f0, SRFL_PRHEX, SROM4_2G_PA, 0xffff},
-	{"pa2gw1a", 0x000000f0, SRFL_PRHEX, SROM4_2G_PA + 1, 0xffff},
-	{"pa2gw2a", 0x000000f0, SRFL_PRHEX, SROM4_2G_PA + 2, 0xffff},
-	{"pa2gw3a", 0x000000f0, SRFL_PRHEX, SROM4_2G_PA + 3, 0xffff},
-	{"maxp5ga", 0x000000f0, 0, SROM4_5G_ITT_MAXP, 0x00ff},
-	{"maxp5gha", 0x000000f0, 0, SROM4_5GLH_MAXP, 0x00ff},
-	{"maxp5gla", 0x000000f0, 0, SROM4_5GLH_MAXP, 0xff00},
-	{"pa5gw0a", 0x000000f0, SRFL_PRHEX, SROM4_5G_PA, 0xffff},
-	{"pa5gw1a", 0x000000f0, SRFL_PRHEX, SROM4_5G_PA + 1, 0xffff},
-	{"pa5gw2a", 0x000000f0, SRFL_PRHEX, SROM4_5G_PA + 2, 0xffff},
-	{"pa5gw3a", 0x000000f0, SRFL_PRHEX, SROM4_5G_PA + 3, 0xffff},
-	{"pa5glw0a", 0x000000f0, SRFL_PRHEX, SROM4_5GL_PA, 0xffff},
-	{"pa5glw1a", 0x000000f0, SRFL_PRHEX, SROM4_5GL_PA + 1, 0xffff},
-	{"pa5glw2a", 0x000000f0, SRFL_PRHEX, SROM4_5GL_PA + 2, 0xffff},
-	{"pa5glw3a", 0x000000f0, SRFL_PRHEX, SROM4_5GL_PA + 3, 0xffff},
-	{"pa5ghw0a", 0x000000f0, SRFL_PRHEX, SROM4_5GH_PA, 0xffff},
-	{"pa5ghw1a", 0x000000f0, SRFL_PRHEX, SROM4_5GH_PA + 1, 0xffff},
-	{"pa5ghw2a", 0x000000f0, SRFL_PRHEX, SROM4_5GH_PA + 2, 0xffff},
-	{"pa5ghw3a", 0x000000f0, SRFL_PRHEX, SROM4_5GH_PA + 3, 0xffff},
-	{"maxp2ga", 0xffffff00, 0, SROM8_2G_ITT_MAXP, 0x00ff},
-	{"itt2ga", 0xffffff00, 0, SROM8_2G_ITT_MAXP, 0xff00},
-	{"itt5ga", 0xffffff00, 0, SROM8_5G_ITT_MAXP, 0xff00},
-	{"pa2gw0a", 0xffffff00, SRFL_PRHEX, SROM8_2G_PA, 0xffff},
-	{"pa2gw1a", 0xffffff00, SRFL_PRHEX, SROM8_2G_PA + 1, 0xffff},
-	{"pa2gw2a", 0xffffff00, SRFL_PRHEX, SROM8_2G_PA + 2, 0xffff},
-	{"maxp5ga", 0xffffff00, 0, SROM8_5G_ITT_MAXP, 0x00ff},
-	{"maxp5gha", 0xffffff00, 0, SROM8_5GLH_MAXP, 0x00ff},
-	{"maxp5gla", 0xffffff00, 0, SROM8_5GLH_MAXP, 0xff00},
-	{"pa5gw0a", 0xffffff00, SRFL_PRHEX, SROM8_5G_PA, 0xffff},
-	{"pa5gw1a", 0xffffff00, SRFL_PRHEX, SROM8_5G_PA + 1, 0xffff},
-	{"pa5gw2a", 0xffffff00, SRFL_PRHEX, SROM8_5G_PA + 2, 0xffff},
-	{"pa5glw0a", 0xffffff00, SRFL_PRHEX, SROM8_5GL_PA, 0xffff},
-	{"pa5glw1a", 0xffffff00, SRFL_PRHEX, SROM8_5GL_PA + 1, 0xffff},
-	{"pa5glw2a", 0xffffff00, SRFL_PRHEX, SROM8_5GL_PA + 2, 0xffff},
-	{"pa5ghw0a", 0xffffff00, SRFL_PRHEX, SROM8_5GH_PA, 0xffff},
-	{"pa5ghw1a", 0xffffff00, SRFL_PRHEX, SROM8_5GH_PA + 1, 0xffff},
-	{"pa5ghw2a", 0xffffff00, SRFL_PRHEX, SROM8_5GH_PA + 2, 0xffff},
-	{NULL, 0, 0, 0, 0}
-};
-
-#if !(defined(PHY_TYPE_N) && defined(PHY_TYPE_LP))
-#define	PHY_TYPE_N		4	/* N-Phy value */
-#define	PHY_TYPE_LP		5	/* LP-Phy value */
-#endif				/* !(defined(PHY_TYPE_N) && defined(PHY_TYPE_LP)) */
-#if !defined(PHY_TYPE_NULL)
-#define	PHY_TYPE_NULL		0xf	/* Invalid Phy value */
-#endif				/* !defined(PHY_TYPE_NULL) */
-
-typedef struct {
-	u16 phy_type;
-	u16 bandrange;
-	u16 chain;
-	const char *vars;
-} pavars_t;
-
-static const pavars_t pavars[] = {
-	/* NPHY */
-	{PHY_TYPE_N, WL_CHAN_FREQ_RANGE_2G, 0, "pa2gw0a0 pa2gw1a0 pa2gw2a0"},
-	{PHY_TYPE_N, WL_CHAN_FREQ_RANGE_2G, 1, "pa2gw0a1 pa2gw1a1 pa2gw2a1"},
-	{PHY_TYPE_N, WL_CHAN_FREQ_RANGE_5GL, 0,
-	 "pa5glw0a0 pa5glw1a0 pa5glw2a0"},
-	{PHY_TYPE_N, WL_CHAN_FREQ_RANGE_5GL, 1,
-	 "pa5glw0a1 pa5glw1a1 pa5glw2a1"},
-	{PHY_TYPE_N, WL_CHAN_FREQ_RANGE_5GM, 0, "pa5gw0a0 pa5gw1a0 pa5gw2a0"},
-	{PHY_TYPE_N, WL_CHAN_FREQ_RANGE_5GM, 1, "pa5gw0a1 pa5gw1a1 pa5gw2a1"},
-	{PHY_TYPE_N, WL_CHAN_FREQ_RANGE_5GH, 0,
-	 "pa5ghw0a0 pa5ghw1a0 pa5ghw2a0"},
-	{PHY_TYPE_N, WL_CHAN_FREQ_RANGE_5GH, 1,
-	 "pa5ghw0a1 pa5ghw1a1 pa5ghw2a1"},
-	/* LPPHY */
-	{PHY_TYPE_LP, WL_CHAN_FREQ_RANGE_2G, 0, "pa0b0 pa0b1 pa0b2"},
-	{PHY_TYPE_LP, WL_CHAN_FREQ_RANGE_5GL, 0, "pa1lob0 pa1lob1 pa1lob2"},
-	{PHY_TYPE_LP, WL_CHAN_FREQ_RANGE_5GM, 0, "pa1b0 pa1b1 pa1b2"},
-	{PHY_TYPE_LP, WL_CHAN_FREQ_RANGE_5GH, 0, "pa1hib0 pa1hib1 pa1hib2"},
-	{PHY_TYPE_NULL, 0, 0, ""}
-};
-
-typedef struct {
-	u16 phy_type;
-	u16 bandrange;
-	const char *vars;
-} povars_t;
-
-static const povars_t povars[] = {
-	/* NPHY */
-	{PHY_TYPE_N, WL_CHAN_FREQ_RANGE_2G,
-	 "mcs2gpo0 mcs2gpo1 mcs2gpo2 mcs2gpo3 "
-	 "mcs2gpo4 mcs2gpo5 mcs2gpo6 mcs2gpo7"},
-	{PHY_TYPE_N, WL_CHAN_FREQ_RANGE_5GL,
-	 "mcs5glpo0 mcs5glpo1 mcs5glpo2 mcs5glpo3 "
-	 "mcs5glpo4 mcs5glpo5 mcs5glpo6 mcs5glpo7"},
-	{PHY_TYPE_N, WL_CHAN_FREQ_RANGE_5GM,
-	 "mcs5gpo0 mcs5gpo1 mcs5gpo2 mcs5gpo3 "
-	 "mcs5gpo4 mcs5gpo5 mcs5gpo6 mcs5gpo7"},
-	{PHY_TYPE_N, WL_CHAN_FREQ_RANGE_5GH,
-	 "mcs5ghpo0 mcs5ghpo1 mcs5ghpo2 mcs5ghpo3 "
-	 "mcs5ghpo4 mcs5ghpo5 mcs5ghpo6 mcs5ghpo7"},
-	{PHY_TYPE_NULL, 0, ""}
-};
-
-typedef struct {
-	u8 tag;		/* Broadcom subtag name */
-	u8 len;		/* Length field of the tuple, note that it includes the
-				 * subtag name (1 byte): 1 + tuple content length
-				 */
-	const char *params;
-} cis_tuple_t;
-
-#define OTP_RAW		(0xff - 1)	/* Reserved tuple number for wrvar Raw input */
-#define OTP_VERS_1	(0xff - 2)	/* CISTPL_VERS_1 */
-#define OTP_MANFID	(0xff - 3)	/* CISTPL_MANFID */
-#define OTP_RAW1	(0xff - 4)	/* Like RAW, but comes first */
-
-static const cis_tuple_t cis_hnbuvars[] = {
-	{OTP_RAW1, 0, ""},	/* special case */
-	{OTP_VERS_1, 0, "smanf sproductname"},	/* special case (non BRCM tuple) */
-	{OTP_MANFID, 4, "2manfid 2prodid"},	/* special case (non BRCM tuple) */
-	{HNBU_SROMREV, 2, "1sromrev"},
-	/* NOTE: subdevid is also written to boardtype.
-	 *       Need to write HNBU_BOARDTYPE to change it if it is different.
-	 */
-	{HNBU_CHIPID, 11, "2vendid 2devid 2chiprev 2subvendid 2subdevid"},
-	{HNBU_BOARDREV, 3, "2boardrev"},
-	{HNBU_PAPARMS, 10, "2pa0b0 2pa0b1 2pa0b2 1pa0itssit 1pa0maxpwr 1opo"},
-	{HNBU_AA, 3, "1aa2g 1aa5g"},
-	{HNBU_AA, 3, "1aa0 1aa1"},	/* backward compatibility */
-	{HNBU_AG, 5, "1ag0 1ag1 1ag2 1ag3"},
-	{HNBU_BOARDFLAGS, 9, "4boardflags 4boardflags2"},
-	{HNBU_LEDS, 5, "1ledbh0 1ledbh1 1ledbh2 1ledbh3"},
-	{HNBU_CCODE, 4, "2ccode 1cctl"},
-	{HNBU_CCKPO, 3, "2cckpo"},
-	{HNBU_OFDMPO, 5, "4ofdmpo"},
-	{HNBU_RDLID, 3, "2rdlid"},
-	{HNBU_RSSISMBXA2G, 3, "0rssismf2g 0rssismc2g 0rssisav2g 0bxa2g"},	/* special case */
-	{HNBU_RSSISMBXA5G, 3, "0rssismf5g 0rssismc5g 0rssisav5g 0bxa5g"},	/* special case */
-	{HNBU_XTALFREQ, 5, "4xtalfreq"},
-	{HNBU_TRI2G, 2, "1tri2g"},
-	{HNBU_TRI5G, 4, "1tri5gl 1tri5g 1tri5gh"},
-	{HNBU_RXPO2G, 2, "1rxpo2g"},
-	{HNBU_RXPO5G, 2, "1rxpo5g"},
-	{HNBU_BOARDNUM, 3, "2boardnum"},
-	{HNBU_MACADDR, 7, "6macaddr"},	/* special case */
-	{HNBU_RDLSN, 3, "2rdlsn"},
-	{HNBU_BOARDTYPE, 3, "2boardtype"},
-	{HNBU_LEDDC, 3, "2leddc"},
-	{HNBU_RDLRNDIS, 2, "1rdlndis"},
-	{HNBU_CHAINSWITCH, 5, "1txchain 1rxchain 2antswitch"},
-	{HNBU_REGREV, 2, "1regrev"},
-	{HNBU_FEM, 5, "0antswctl2g, 0triso2g, 0pdetrange2g, 0extpagain2g, 0tssipos2g" "0antswctl5g, 0triso5g, 0pdetrange5g, 0extpagain5g, 0tssipos5g"},	/* special case */
-	{HNBU_PAPARMS_C0, 31, "1maxp2ga0 1itt2ga0 2pa2gw0a0 2pa2gw1a0 "
-	 "2pa2gw2a0 1maxp5ga0 1itt5ga0 1maxp5gha0 1maxp5gla0 2pa5gw0a0 "
-	 "2pa5gw1a0 2pa5gw2a0 2pa5glw0a0 2pa5glw1a0 2pa5glw2a0 2pa5ghw0a0 "
-	 "2pa5ghw1a0 2pa5ghw2a0"},
-	{HNBU_PAPARMS_C1, 31, "1maxp2ga1 1itt2ga1 2pa2gw0a1 2pa2gw1a1 "
-	 "2pa2gw2a1 1maxp5ga1 1itt5ga1 1maxp5gha1 1maxp5gla1 2pa5gw0a1 "
-	 "2pa5gw1a1 2pa5gw2a1 2pa5glw0a1 2pa5glw1a1 2pa5glw2a1 2pa5ghw0a1 "
-	 "2pa5ghw1a1 2pa5ghw2a1"},
-	{HNBU_PO_CCKOFDM, 19, "2cck2gpo 4ofdm2gpo 4ofdm5gpo 4ofdm5glpo "
-	 "4ofdm5ghpo"},
-	{HNBU_PO_MCS2G, 17, "2mcs2gpo0 2mcs2gpo1 2mcs2gpo2 2mcs2gpo3 "
-	 "2mcs2gpo4 2mcs2gpo5 2mcs2gpo6 2mcs2gpo7"},
-	{HNBU_PO_MCS5GM, 17, "2mcs5gpo0 2mcs5gpo1 2mcs5gpo2 2mcs5gpo3 "
-	 "2mcs5gpo4 2mcs5gpo5 2mcs5gpo6 2mcs5gpo7"},
-	{HNBU_PO_MCS5GLH, 33, "2mcs5glpo0 2mcs5glpo1 2mcs5glpo2 2mcs5glpo3 "
-	 "2mcs5glpo4 2mcs5glpo5 2mcs5glpo6 2mcs5glpo7 "
-	 "2mcs5ghpo0 2mcs5ghpo1 2mcs5ghpo2 2mcs5ghpo3 "
-	 "2mcs5ghpo4 2mcs5ghpo5 2mcs5ghpo6 2mcs5ghpo7"},
-	{HNBU_CCKFILTTYPE, 2, "1cckdigfilttype"},
-	{HNBU_PO_CDD, 3, "2cddpo"},
-	{HNBU_PO_STBC, 3, "2stbcpo"},
-	{HNBU_PO_40M, 3, "2bw40po"},
-	{HNBU_PO_40MDUP, 3, "2bwduppo"},
-	{HNBU_RDLRWU, 2, "1rdlrwu"},
-	{HNBU_WPS, 3, "1wpsgpio 1wpsled"},
-	{HNBU_USBFS, 2, "1usbfs"},
-	{HNBU_CUSTOM1, 5, "4customvar1"},
-	{OTP_RAW, 0, ""},	/* special case */
-	{HNBU_OFDMPO5G, 13, "4ofdm5gpo 4ofdm5glpo 4ofdm5ghpo"},
-	{HNBU_USBEPNUM, 3, "2usbepnum"},
-	{0xFF, 0, ""}
-};
-
-#endif				/* _bcmsrom_tbl_h_ */
diff -druN linux-2.6.39-libre/drivers/staging/brcm80211/util/bcmutils.c linux-3.0-rc7-libre/drivers/staging/brcm80211/util/bcmutils.c
--- linux-2.6.39-libre/drivers/staging/brcm80211/util/bcmutils.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/brcm80211/util/bcmutils.c	2011-07-11 19:51:52.000000000 -0400
@@ -21,18 +21,20 @@
 #include <linux/pci.h>
 #include <linux/netdevice.h>
 #include <linux/sched.h>
+#include <linux/printk.h>
 #include <bcmdefs.h>
 #include <stdarg.h>
 #include <bcmutils.h>
-#include <siutils.h>
 #include <bcmnvram.h>
 #include <bcmdevs.h>
 #include <proto/802.11.h>
 
-/* Global ASSERT type flag */
-u32 g_assert_type;
+MODULE_AUTHOR("Broadcom Corporation");
+MODULE_DESCRIPTION("Broadcom 802.11n wireless LAN driver utilities.");
+MODULE_SUPPORTED_DEVICE("Broadcom 802.11n WLAN cards");
+MODULE_LICENSE("Dual BSD/GPL");
 
-struct sk_buff *BCMFASTPATH pkt_buf_get_skb(uint len)
+struct sk_buff *bcm_pkt_buf_get_skb(uint len)
 {
 	struct sk_buff *skb;
 
@@ -44,15 +46,14 @@
 
 	return skb;
 }
+EXPORT_SYMBOL(bcm_pkt_buf_get_skb);
 
 /* Free the driver packet. Free the tag if present */
-void BCMFASTPATH pkt_buf_free_skb(struct sk_buff *skb)
+void bcm_pkt_buf_free_skb(struct sk_buff *skb)
 {
 	struct sk_buff *nskb;
 	int nest = 0;
 
-	ASSERT(skb);
-
 	/* perversion: we use skb->next to chain multi-skb packets */
 	while (skb) {
 		nskb = skb->next;
@@ -73,9 +74,11 @@
 		skb = nskb;
 	}
 }
+EXPORT_SYMBOL(bcm_pkt_buf_free_skb);
+
 
 /* copy a buffer into a pkt buffer chain */
-uint pktfrombuf(struct sk_buff *p, uint offset, int len,
+uint bcm_pktfrombuf(struct sk_buff *p, uint offset, int len,
 		unsigned char *buf)
 {
 	uint n, ret = 0;
@@ -102,8 +105,10 @@
 
 	return ret;
 }
+EXPORT_SYMBOL(bcm_pktfrombuf);
+
 /* return total length of buffer chain */
-uint BCMFASTPATH pkttotlen(struct sk_buff *p)
+uint bcm_pkttotlen(struct sk_buff *p)
 {
 	uint total;
 
@@ -112,21 +117,19 @@
 		total += p->len;
 	return total;
 }
+EXPORT_SYMBOL(bcm_pkttotlen);
 
 /*
  * osl multiple-precedence packet queue
  * hi_prec is always >= the number of the highest non-empty precedence
  */
-struct sk_buff *BCMFASTPATH pktq_penq(struct pktq *pq, int prec,
+struct sk_buff *bcm_pktq_penq(struct pktq *pq, int prec,
 				      struct sk_buff *p)
 {
 	struct pktq_prec *q;
 
-	ASSERT(prec >= 0 && prec < pq->num_prec);
-	ASSERT(p->prev == NULL);	/* queueing chains not allowed */
-
-	ASSERT(!pktq_full(pq));
-	ASSERT(!pktq_pfull(pq, prec));
+	if (pktq_full(pq) || pktq_pfull(pq, prec))
+		return NULL;
 
 	q = &pq->q[prec];
 
@@ -145,17 +148,15 @@
 
 	return p;
 }
+EXPORT_SYMBOL(bcm_pktq_penq);
 
-struct sk_buff *BCMFASTPATH pktq_penq_head(struct pktq *pq, int prec,
+struct sk_buff *bcm_pktq_penq_head(struct pktq *pq, int prec,
 					   struct sk_buff *p)
 {
 	struct pktq_prec *q;
 
-	ASSERT(prec >= 0 && prec < pq->num_prec);
-	ASSERT(p->prev == NULL);	/* queueing chains not allowed */
-
-	ASSERT(!pktq_full(pq));
-	ASSERT(!pktq_pfull(pq, prec));
+	if (pktq_full(pq) || pktq_pfull(pq, prec))
+		return NULL;
 
 	q = &pq->q[prec];
 
@@ -173,14 +174,13 @@
 
 	return p;
 }
+EXPORT_SYMBOL(bcm_pktq_penq_head);
 
-struct sk_buff *BCMFASTPATH pktq_pdeq(struct pktq *pq, int prec)
+struct sk_buff *bcm_pktq_pdeq(struct pktq *pq, int prec)
 {
 	struct pktq_prec *q;
 	struct sk_buff *p;
 
-	ASSERT(prec >= 0 && prec < pq->num_prec);
-
 	q = &pq->q[prec];
 
 	p = q->head;
@@ -199,14 +199,13 @@
 
 	return p;
 }
+EXPORT_SYMBOL(bcm_pktq_pdeq);
 
-struct sk_buff *BCMFASTPATH pktq_pdeq_tail(struct pktq *pq, int prec)
+struct sk_buff *bcm_pktq_pdeq_tail(struct pktq *pq, int prec)
 {
 	struct pktq_prec *q;
 	struct sk_buff *p, *prev;
 
-	ASSERT(prec >= 0 && prec < pq->num_prec);
-
 	q = &pq->q[prec];
 
 	p = q->head;
@@ -228,38 +227,11 @@
 
 	return p;
 }
+EXPORT_SYMBOL(bcm_pktq_pdeq_tail);
 
-#ifdef BRCM_FULLMAC
-void pktq_pflush(struct pktq *pq, int prec, bool dir)
-{
-	struct pktq_prec *q;
-	struct sk_buff *p;
-
-	q = &pq->q[prec];
-	p = q->head;
-	while (p) {
-		q->head = p->prev;
-		p->prev = NULL;
-		pkt_buf_free_skb(p);
-		q->len--;
-		pq->len--;
-		p = q->head;
-	}
-	ASSERT(q->len == 0);
-	q->tail = NULL;
-}
-
-void pktq_flush(struct pktq *pq, bool dir)
-{
-	int prec;
-	for (prec = 0; prec < pq->num_prec; prec++)
-		pktq_pflush(pq, prec, dir);
-	ASSERT(pq->len == 0);
-}
-#else /* !BRCM_FULLMAC */
 void
-pktq_pflush(struct pktq *pq, int prec, bool dir,
-	    ifpkt_cb_t fn, int arg)
+bcm_pktq_pflush(struct pktq *pq, int prec, bool dir,
+	    ifpkt_cb_t fn, void *arg)
 {
 	struct pktq_prec *q;
 	struct sk_buff *p, *prev = NULL;
@@ -274,7 +246,7 @@
 			else
 				prev->prev = p->prev;
 			p->prev = NULL;
-			pkt_buf_free_skb(p);
+			bcm_pkt_buf_free_skb(p);
 			q->len--;
 			pq->len--;
 			p = (head ? q->head : prev->prev);
@@ -285,28 +257,24 @@
 	}
 
 	if (q->head == NULL) {
-		ASSERT(q->len == 0);
 		q->tail = NULL;
 	}
 }
+EXPORT_SYMBOL(bcm_pktq_pflush);
 
-void pktq_flush(struct pktq *pq, bool dir,
-		ifpkt_cb_t fn, int arg)
+void bcm_pktq_flush(struct pktq *pq, bool dir,
+		ifpkt_cb_t fn, void *arg)
 {
 	int prec;
 	for (prec = 0; prec < pq->num_prec; prec++)
-		pktq_pflush(pq, prec, dir, fn, arg);
-	if (fn == NULL)
-		ASSERT(pq->len == 0);
+		bcm_pktq_pflush(pq, prec, dir, fn, arg);
 }
-#endif /* BRCM_FULLMAC */
+EXPORT_SYMBOL(bcm_pktq_flush);
 
-void pktq_init(struct pktq *pq, int num_prec, int max_len)
+void bcm_pktq_init(struct pktq *pq, int num_prec, int max_len)
 {
 	int prec;
 
-	ASSERT(num_prec > 0 && num_prec <= PKTQ_MAX_PREC);
-
 	/* pq is variable size; only zero out what's requested */
 	memset(pq, 0,
 	      offsetof(struct pktq, q) + (sizeof(struct pktq_prec) * num_prec));
@@ -318,8 +286,9 @@
 	for (prec = 0; prec < num_prec; prec++)
 		pq->q[prec].max = pq->max;
 }
+EXPORT_SYMBOL(bcm_pktq_init);
 
-struct sk_buff *pktq_peek_tail(struct pktq *pq, int *prec_out)
+struct sk_buff *bcm_pktq_peek_tail(struct pktq *pq, int *prec_out)
 {
 	int prec;
 
@@ -335,9 +304,10 @@
 
 	return pq->q[prec].tail;
 }
+EXPORT_SYMBOL(bcm_pktq_peek_tail);
 
 /* Return sum of lengths of a specific set of precedences */
-int pktq_mlen(struct pktq *pq, uint prec_bmp)
+int bcm_pktq_mlen(struct pktq *pq, uint prec_bmp)
 {
 	int prec, len;
 
@@ -349,8 +319,10 @@
 
 	return len;
 }
+EXPORT_SYMBOL(bcm_pktq_mlen);
+
 /* Priority dequeue from a specific set of precedences */
-struct sk_buff *BCMFASTPATH pktq_mdeq(struct pktq *pq, uint prec_bmp,
+struct sk_buff *bcm_pktq_mdeq(struct pktq *pq, uint prec_bmp,
 				      int *prec_out)
 {
 	struct pktq_prec *q;
@@ -388,6 +360,7 @@
 
 	return p;
 }
+EXPORT_SYMBOL(bcm_pktq_mdeq);
 
 /* parse a xx:xx:xx:xx:xx:xx format ethernet address */
 int bcm_ether_atoe(char *p, u8 *ea)
@@ -402,57 +375,11 @@
 
 	return i == 6;
 }
-
-/*
- * Search the name=value vars for a specific one and return its value.
- * Returns NULL if not found.
- */
-char *getvar(char *vars, const char *name)
-{
-	char *s;
-	int len;
-
-	if (!name)
-		return NULL;
-
-	len = strlen(name);
-	if (len == 0)
-		return NULL;
-
-	/* first look in vars[] */
-	for (s = vars; s && *s;) {
-		if ((memcmp(s, name, len) == 0) && (s[len] == '='))
-			return &s[len + 1];
-
-		while (*s++)
-			;
-	}
-#ifdef BRCM_FULLMAC
-	return NULL;
-#else
-	/* then query nvram */
-	return nvram_get(name);
-#endif
-}
-
-/*
- * Search the vars for a specific one and return its value as
- * an integer. Returns 0 if not found.
- */
-int getintvar(char *vars, const char *name)
-{
-	char *val;
-
-	val = getvar(vars, name);
-	if (val == NULL)
-		return 0;
-
-	return simple_strtoul(val, NULL, 0);
-}
+EXPORT_SYMBOL(bcm_ether_atoe);
 
 #if defined(BCMDBG)
 /* pretty hex print a pkt buffer chain */
-void prpkt(const char *msg, struct sk_buff *p0)
+void bcm_prpkt(const char *msg, struct sk_buff *p0)
 {
 	struct sk_buff *p;
 
@@ -460,32 +387,11 @@
 		printk(KERN_DEBUG "%s:\n", msg);
 
 	for (p = p0; p; p = p->next)
-		prhex(NULL, p->data, p->len);
+		print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, p->data, p->len);
 }
+EXPORT_SYMBOL(bcm_prpkt);
 #endif				/* defined(BCMDBG) */
 
-static char bcm_undeferrstr[BCME_STRLEN];
-
-static const char *bcmerrorstrtable[] = BCMERRSTRINGTABLE;
-
-/* Convert the error codes into related error strings  */
-const char *bcmerrorstr(int bcmerror)
-{
-	/* check if someone added a bcmerror code but
-		 forgot to add errorstring */
-	ASSERT(ABS(BCME_LAST) == (ARRAY_SIZE(bcmerrorstrtable) - 1));
-
-	if (bcmerror > 0 || bcmerror < BCME_LAST) {
-		snprintf(bcm_undeferrstr, BCME_STRLEN, "Undefined error %d",
-			 bcmerror);
-		return bcm_undeferrstr;
-	}
-
-	ASSERT(strlen(bcmerrorstrtable[-bcmerror]) < BCME_STRLEN);
-
-	return bcmerrorstrtable[-bcmerror];
-}
-
 /* iovar table lookup */
 const bcm_iovar_t *bcm_iovar_lookup(const bcm_iovar_t *table, const char *name)
 {
@@ -499,8 +405,6 @@
 	else
 		lookup_name = name;
 
-	ASSERT(table != NULL);
-
 	for (vi = table; vi->name; vi++) {
 		if (!strcmp(vi->name, lookup_name))
 			return vi;
@@ -509,6 +413,7 @@
 
 	return NULL;		/* var name not found */
 }
+EXPORT_SYMBOL(bcm_iovar_lookup);
 
 int bcm_iovar_lencheck(const bcm_iovar_t *vi, void *arg, int len, bool set)
 {
@@ -525,35 +430,35 @@
 	case IOVT_UINT32:
 		/* all integers are s32 sized args at the ioctl interface */
 		if (len < (int)sizeof(int)) {
-			bcmerror = BCME_BUFTOOSHORT;
+			bcmerror = -EOVERFLOW;
 		}
 		break;
 
 	case IOVT_BUFFER:
 		/* buffer must meet minimum length requirement */
 		if (len < vi->minlen) {
-			bcmerror = BCME_BUFTOOSHORT;
+			bcmerror = -EOVERFLOW;
 		}
 		break;
 
 	case IOVT_VOID:
 		if (!set) {
 			/* Cannot return nil... */
-			bcmerror = BCME_UNSUPPORTED;
+			bcmerror = -ENOTSUPP;
 		} else if (len) {
 			/* Set is an action w/o parameters */
-			bcmerror = BCME_BUFTOOLONG;
+			bcmerror = -ENOBUFS;
 		}
 		break;
 
 	default:
 		/* unknown type for length check in iovar info */
-		ASSERT(0);
-		bcmerror = BCME_UNSUPPORTED;
+		bcmerror = -ENOTSUPP;
 	}
 
 	return bcmerror;
 }
+EXPORT_SYMBOL(bcm_iovar_lencheck);
 
 /*******************************************************************************
  * crc8
@@ -612,195 +517,18 @@
 	0xF4, 0x03, 0x4D, 0xBA, 0xD1, 0x26, 0x68, 0x9F
 };
 
-#define CRC_INNER_LOOP(n, c, x) \
-	((c) = ((c) >> 8) ^ crc##n##_table[((c) ^ (x)) & 0xff])
-
-u8 hndcrc8(u8 *pdata,	/* pointer to array of data to process */
+u8 bcm_crc8(u8 *pdata,	/* pointer to array of data to process */
 			 uint nbytes,	/* number of input data bytes to process */
 			 u8 crc	/* either CRC8_INIT_VALUE or previous return value */
     ) {
-	/* hard code the crc loop instead of using CRC_INNER_LOOP macro
-	 * to avoid the undefined and unnecessary (u8 >> 8) operation.
-	 */
+	/* loop over the buffer data */
 	while (nbytes-- > 0)
 		crc = crc8_table[(crc ^ *pdata++) & 0xff];
 
 	return crc;
 }
+EXPORT_SYMBOL(bcm_crc8);
 
-/*******************************************************************************
- * crc16
- *
- * Computes a crc16 over the input data using the polynomial:
- *
- *       x^16 + x^12 +x^5 + 1
- *
- * The caller provides the initial value (either CRC16_INIT_VALUE
- * or the previous returned value) to allow for processing of
- * discontiguous blocks of data.  When generating the CRC the
- * caller is responsible for complementing the final return value
- * and inserting it into the byte stream.  When checking, a final
- * return value of CRC16_GOOD_VALUE indicates a valid CRC.
- *
- * Reference: Dallas Semiconductor Application Note 27
- *   Williams, Ross N., "A Painless Guide to CRC Error Detection Algorithms",
- *     ver 3, Aug 1993, ross@guest.adelaide.edu.au, Rocksoft Pty Ltd.,
- *     ftp://ftp.rocksoft.com/clients/rocksoft/papers/crc_v3.txt
- *
- * ****************************************************************************
- */
-
-static const u16 crc16_table[256] = {
-	0x0000, 0x1189, 0x2312, 0x329B, 0x4624, 0x57AD, 0x6536, 0x74BF,
-	0x8C48, 0x9DC1, 0xAF5A, 0xBED3, 0xCA6C, 0xDBE5, 0xE97E, 0xF8F7,
-	0x1081, 0x0108, 0x3393, 0x221A, 0x56A5, 0x472C, 0x75B7, 0x643E,
-	0x9CC9, 0x8D40, 0xBFDB, 0xAE52, 0xDAED, 0xCB64, 0xF9FF, 0xE876,
-	0x2102, 0x308B, 0x0210, 0x1399, 0x6726, 0x76AF, 0x4434, 0x55BD,
-	0xAD4A, 0xBCC3, 0x8E58, 0x9FD1, 0xEB6E, 0xFAE7, 0xC87C, 0xD9F5,
-	0x3183, 0x200A, 0x1291, 0x0318, 0x77A7, 0x662E, 0x54B5, 0x453C,
-	0xBDCB, 0xAC42, 0x9ED9, 0x8F50, 0xFBEF, 0xEA66, 0xD8FD, 0xC974,
-	0x4204, 0x538D, 0x6116, 0x709F, 0x0420, 0x15A9, 0x2732, 0x36BB,
-	0xCE4C, 0xDFC5, 0xED5E, 0xFCD7, 0x8868, 0x99E1, 0xAB7A, 0xBAF3,
-	0x5285, 0x430C, 0x7197, 0x601E, 0x14A1, 0x0528, 0x37B3, 0x263A,
-	0xDECD, 0xCF44, 0xFDDF, 0xEC56, 0x98E9, 0x8960, 0xBBFB, 0xAA72,
-	0x6306, 0x728F, 0x4014, 0x519D, 0x2522, 0x34AB, 0x0630, 0x17B9,
-	0xEF4E, 0xFEC7, 0xCC5C, 0xDDD5, 0xA96A, 0xB8E3, 0x8A78, 0x9BF1,
-	0x7387, 0x620E, 0x5095, 0x411C, 0x35A3, 0x242A, 0x16B1, 0x0738,
-	0xFFCF, 0xEE46, 0xDCDD, 0xCD54, 0xB9EB, 0xA862, 0x9AF9, 0x8B70,
-	0x8408, 0x9581, 0xA71A, 0xB693, 0xC22C, 0xD3A5, 0xE13E, 0xF0B7,
-	0x0840, 0x19C9, 0x2B52, 0x3ADB, 0x4E64, 0x5FED, 0x6D76, 0x7CFF,
-	0x9489, 0x8500, 0xB79B, 0xA612, 0xD2AD, 0xC324, 0xF1BF, 0xE036,
-	0x18C1, 0x0948, 0x3BD3, 0x2A5A, 0x5EE5, 0x4F6C, 0x7DF7, 0x6C7E,
-	0xA50A, 0xB483, 0x8618, 0x9791, 0xE32E, 0xF2A7, 0xC03C, 0xD1B5,
-	0x2942, 0x38CB, 0x0A50, 0x1BD9, 0x6F66, 0x7EEF, 0x4C74, 0x5DFD,
-	0xB58B, 0xA402, 0x9699, 0x8710, 0xF3AF, 0xE226, 0xD0BD, 0xC134,
-	0x39C3, 0x284A, 0x1AD1, 0x0B58, 0x7FE7, 0x6E6E, 0x5CF5, 0x4D7C,
-	0xC60C, 0xD785, 0xE51E, 0xF497, 0x8028, 0x91A1, 0xA33A, 0xB2B3,
-	0x4A44, 0x5BCD, 0x6956, 0x78DF, 0x0C60, 0x1DE9, 0x2F72, 0x3EFB,
-	0xD68D, 0xC704, 0xF59F, 0xE416, 0x90A9, 0x8120, 0xB3BB, 0xA232,
-	0x5AC5, 0x4B4C, 0x79D7, 0x685E, 0x1CE1, 0x0D68, 0x3FF3, 0x2E7A,
-	0xE70E, 0xF687, 0xC41C, 0xD595, 0xA12A, 0xB0A3, 0x8238, 0x93B1,
-	0x6B46, 0x7ACF, 0x4854, 0x59DD, 0x2D62, 0x3CEB, 0x0E70, 0x1FF9,
-	0xF78F, 0xE606, 0xD49D, 0xC514, 0xB1AB, 0xA022, 0x92B9, 0x8330,
-	0x7BC7, 0x6A4E, 0x58D5, 0x495C, 0x3DE3, 0x2C6A, 0x1EF1, 0x0F78
-};
-
-u16 hndcrc16(u8 *pdata,	/* pointer to array of data to process */
-	uint nbytes,	/* number of input data bytes to process */
-	u16 crc	/* either CRC16_INIT_VALUE or previous return value */
-    ) {
-	while (nbytes-- > 0)
-		CRC_INNER_LOOP(16, crc, *pdata++);
-	return crc;
-}
-
-static const u32 crc32_table[256] = {
-	0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA,
-	0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3,
-	0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988,
-	0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91,
-	0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE,
-	0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7,
-	0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC,
-	0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5,
-	0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172,
-	0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B,
-	0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940,
-	0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59,
-	0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116,
-	0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F,
-	0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924,
-	0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D,
-	0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A,
-	0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433,
-	0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818,
-	0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01,
-	0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E,
-	0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457,
-	0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C,
-	0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65,
-	0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2,
-	0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB,
-	0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0,
-	0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9,
-	0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086,
-	0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F,
-	0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4,
-	0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD,
-	0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A,
-	0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683,
-	0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8,
-	0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1,
-	0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE,
-	0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7,
-	0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC,
-	0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5,
-	0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252,
-	0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B,
-	0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60,
-	0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79,
-	0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236,
-	0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F,
-	0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04,
-	0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D,
-	0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A,
-	0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713,
-	0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38,
-	0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21,
-	0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E,
-	0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777,
-	0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C,
-	0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45,
-	0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2,
-	0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB,
-	0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0,
-	0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9,
-	0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6,
-	0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF,
-	0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94,
-	0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D
-};
-
-u32 hndcrc32(u8 *pdata,	/* pointer to array of data to process */
-		uint nbytes,	/* number of input data bytes to process */
-		u32 crc	/* either CRC32_INIT_VALUE or previous
-					 return value */
-)
-{
-	u8 *pend;
-#ifdef __mips__
-	u8 tmp[4];
-	unsigned long *tptr = (unsigned long *) tmp;
-
-	/* in case the beginning of the buffer isn't aligned */
-	pend = (u8 *) ((uint) (pdata + 3) & 0xfffffffc);
-	nbytes -= (pend - pdata);
-	while (pdata < pend)
-		CRC_INNER_LOOP(32, crc, *pdata++);
-
-	/* handle bulk of data as 32-bit words */
-	pend = pdata + (nbytes & 0xfffffffc);
-	while (pdata < pend) {
-		*tptr = *(unsigned long *) pdata;
-		pdata += sizeof(unsigned long *);
-		CRC_INNER_LOOP(32, crc, tmp[0]);
-		CRC_INNER_LOOP(32, crc, tmp[1]);
-		CRC_INNER_LOOP(32, crc, tmp[2]);
-		CRC_INNER_LOOP(32, crc, tmp[3]);
-	}
-
-	/* 1-3 bytes at end of buffer */
-	pend = pdata + (nbytes & 0x03);
-	while (pdata < pend)
-		CRC_INNER_LOOP(32, crc, *pdata++);
-#else
-	pend = pdata + nbytes;
-	while (pdata < pend)
-		CRC_INNER_LOOP(32, crc, *pdata++);
-#endif				/* __mips__ */
-
-	return crc;
-}
 /*
  * Traverse a string of 1-byte tag/1-byte length/variable-length value
  * triples, returning a pointer to the substring whose first element
@@ -828,6 +556,7 @@
 
 	return NULL;
 }
+EXPORT_SYMBOL(bcm_parse_tlvs);
 
 
 #if defined(BCMDBG)
@@ -883,6 +612,7 @@
 
 	return (int)(p - buf);
 }
+EXPORT_SYMBOL(bcm_format_flags);
 
 /* print bytes formatted as hex to a string. return the resulting string length */
 int bcm_format_hex(char *str, const void *bytes, int len)
@@ -897,44 +627,9 @@
 	}
 	return (int)(p - str);
 }
+EXPORT_SYMBOL(bcm_format_hex);
 #endif				/* defined(BCMDBG) */
 
-/* pretty hex print a contiguous buffer */
-void prhex(const char *msg, unsigned char *buf, uint nbytes)
-{
-	char line[128], *p;
-	int len = sizeof(line);
-	int nchar;
-	uint i;
-
-	if (msg && (msg[0] != '\0'))
-		printk(KERN_DEBUG "%s:\n", msg);
-
-	p = line;
-	for (i = 0; i < nbytes; i++) {
-		if (i % 16 == 0) {
-			nchar = snprintf(p, len, "  %04d: ", i);	/* line prefix */
-			p += nchar;
-			len -= nchar;
-		}
-		if (len > 0) {
-			nchar = snprintf(p, len, "%02x ", buf[i]);
-			p += nchar;
-			len -= nchar;
-		}
-
-		if (i % 16 == 15) {
-			printk(KERN_DEBUG "%s\n", line);	/* flush line */
-			p = line;
-			len = sizeof(line);
-		}
-	}
-
-	/* flush last partial line */
-	if (p != line)
-		printk(KERN_DEBUG "%s\n", line);
-}
-
 char *bcm_chipname(uint chipid, char *buf, uint len)
 {
 	const char *fmt;
@@ -943,6 +638,7 @@
 	snprintf(buf, len, fmt, chipid);
 	return buf;
 }
+EXPORT_SYMBOL(bcm_chipname);
 
 uint bcm_mkiovar(char *name, char *data, uint datalen, char *buf, uint buflen)
 {
@@ -961,6 +657,7 @@
 
 	return len;
 }
+EXPORT_SYMBOL(bcm_mkiovar);
 
 /* Quarter dBm units to mW
  * Table starts at QDBM_OFFSET, so the first entry is mW for qdBm=153
@@ -1015,6 +712,8 @@
 	 */
 	return (nqdBm_to_mW_map[idx] + factor / 2) / factor;
 }
+EXPORT_SYMBOL(bcm_qdbm_to_mw);
+
 u8 bcm_mw_to_qdbm(u16 mw)
 {
 	u8 qdbm;
@@ -1045,6 +744,8 @@
 
 	return qdbm;
 }
+EXPORT_SYMBOL(bcm_mw_to_qdbm);
+
 uint bcm_bitcount(u8 *bitmap, uint length)
 {
 	uint bitcount = 0, i;
@@ -1058,12 +759,15 @@
 	}
 	return bitcount;
 }
+EXPORT_SYMBOL(bcm_bitcount);
+
 /* Initialization of bcmstrbuf structure */
 void bcm_binit(struct bcmstrbuf *b, char *buf, uint size)
 {
 	b->origsize = b->size = size;
 	b->origbuf = b->buf = buf;
 }
+EXPORT_SYMBOL(bcm_binit);
 
 /* Buffer sprintf wrapper to guard against buffer overflow */
 int bcm_bprintf(struct bcmstrbuf *b, const char *fmt, ...)
@@ -1089,50 +793,4 @@
 
 	return r;
 }
-
-#if defined(BCMDBG_ASSERT)
-void osl_assert(char *exp, char *file, int line)
-{
-	char tempbuf[256];
-	char *basename;
-
-	basename = strrchr(file, '/');
-	/* skip the '/' */
-	if (basename)
-		basename++;
-
-	if (!basename)
-		basename = file;
-
-	snprintf(tempbuf, 256,
-		 "assertion \"%s\" failed: file \"%s\", line %d\n", exp,
-		 basename, line);
-
-	/*
-	 * Print assert message and give it time to
-	 * be written to /var/log/messages
-	 */
-	if (!in_interrupt()) {
-		const int delay = 3;
-		printk(KERN_ERR "%s", tempbuf);
-		printk(KERN_ERR "panic in %d seconds\n", delay);
-		set_current_state(TASK_INTERRUPTIBLE);
-		schedule_timeout(delay * HZ);
-	}
-
-	switch (g_assert_type) {
-	case 0:
-		panic(KERN_ERR "%s", tempbuf);
-		break;
-	case 1:
-		printk(KERN_ERR "%s", tempbuf);
-		BUG();
-		break;
-	case 2:
-		printk(KERN_ERR "%s", tempbuf);
-		break;
-	default:
-		break;
-	}
-}
-#endif				/* defined(BCMDBG_ASSERT) */
+EXPORT_SYMBOL(bcm_bprintf);
diff -druN linux-2.6.39-libre/drivers/staging/brcm80211/util/bcmwifi.c linux-3.0-rc7-libre/drivers/staging/brcm80211/util/bcmwifi.c
--- linux-2.6.39-libre/drivers/staging/brcm80211/util/bcmwifi.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/brcm80211/util/bcmwifi.c	2011-07-11 19:51:52.000000000 -0400
@@ -15,6 +15,7 @@
  */
 #include <linux/ctype.h>
 #include <linux/kernel.h>
+#include <linux/module.h>
 #include <bcmdefs.h>
 #include <bcmutils.h>
 #include <bcmwifi.h>
@@ -25,7 +26,7 @@
  * combination could be legal given any set of circumstances.
  * RETURNS: true is the chanspec is malformed, false if it looks good.
  */
-bool wf_chspec_malformed(chanspec_t chanspec)
+bool bcm_chspec_malformed(chanspec_t chanspec)
 {
 	/* must be 2G or 5G band */
 	if (!CHSPEC_IS5G(chanspec) && !CHSPEC_IS2G(chanspec))
@@ -45,13 +46,14 @@
 
 	return false;
 }
+EXPORT_SYMBOL(bcm_chspec_malformed);
 
 /*
  * This function returns the channel number that control traffic is being sent on, for legacy
  * channels this is just the channel number, for 40MHZ channels it is the upper or lowre 20MHZ
  * sideband depending on the chanspec selected
  */
-u8 wf_chspec_ctlchan(chanspec_t chspec)
+u8 bcm_chspec_ctlchan(chanspec_t chspec)
 {
 	u8 ctl_chan;
 
@@ -60,7 +62,6 @@
 		return CHSPEC_CHANNEL(chspec);
 	} else {
 		/* we only support 40MHZ with sidebands */
-		ASSERT(CHSPEC_BW(chspec) == WL_CHANSPEC_BW_40);
 		/* chanspec channel holds the centre frequency, use that and the
 		 * side band information to reconstruct the control channel number
 		 */
@@ -68,8 +69,6 @@
 			/* control chan is the upper 20 MHZ SB of the 40MHZ channel */
 			ctl_chan = UPPER_20_SB(CHSPEC_CHANNEL(chspec));
 		} else {
-			ASSERT(CHSPEC_CTL_SB(chspec) ==
-			       WL_CHANSPEC_CTL_SB_LOWER);
 			/* control chan is the lower 20 MHZ SB of the 40MHZ channel */
 			ctl_chan = LOWER_20_SB(CHSPEC_CHANNEL(chspec));
 		}
@@ -77,6 +76,7 @@
 
 	return ctl_chan;
 }
+EXPORT_SYMBOL(bcm_chspec_ctlchan);
 
 /*
  * Return the channel number for a given frequency and base frequency.
@@ -97,7 +97,7 @@
  *
  * Reference 802.11 REVma, section 17.3.8.3, and 802.11B section 18.4.6.2
  */
-int wf_mhz2channel(uint freq, uint start_factor)
+int bcm_mhz2channel(uint freq, uint start_factor)
 {
 	int ch = -1;
 	uint base;
@@ -133,4 +133,5 @@
 
 	return ch;
 }
+EXPORT_SYMBOL(bcm_mhz2channel);
 
diff -druN linux-2.6.39-libre/drivers/staging/brcm80211/util/hnddma.c linux-3.0-rc7-libre/drivers/staging/brcm80211/util/hnddma.c
--- linux-2.6.39-libre/drivers/staging/brcm80211/util/hnddma.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/brcm80211/util/hnddma.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,1822 +0,0 @@
-/*
- * Copyright (c) 2010 Broadcom Corporation
- *
- * 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/kernel.h>
-#include <linux/string.h>
-#include <linux/netdevice.h>
-#include <linux/pci.h>
-#include <bcmdefs.h>
-#include <bcmdevs.h>
-#include <hndsoc.h>
-#include <bcmutils.h>
-#include <siutils.h>
-
-#include <sbhnddma.h>
-#include <hnddma.h>
-
-#if defined(__mips__)
-#include <asm/addrspace.h>
-#endif
-
-#ifdef BRCM_FULLMAC
-#error "hnddma.c shouldn't be needed for FULLMAC"
-#endif
-
-/* debug/trace */
-#ifdef BCMDBG
-#define	DMA_ERROR(args) \
-	do { \
-		if (!(*di->msg_level & 1)) \
-			; \
-		else \
-			printk args; \
-	} while (0)
-#define	DMA_TRACE(args) \
-	do { \
-		if (!(*di->msg_level & 2)) \
-			; \
-		else \
-			printk args; \
-	} while (0)
-#else
-#define	DMA_ERROR(args)
-#define	DMA_TRACE(args)
-#endif				/* BCMDBG */
-
-#define	DMA_NONE(args)
-
-#define d64txregs	dregs.d64_u.txregs_64
-#define d64rxregs	dregs.d64_u.rxregs_64
-#define txd64		dregs.d64_u.txd_64
-#define rxd64		dregs.d64_u.rxd_64
-
-/* default dma message level (if input msg_level pointer is null in dma_attach()) */
-static uint dma_msg_level;
-
-#define	MAXNAMEL	8	/* 8 char names */
-
-#define	DI_INFO(dmah)	((dma_info_t *)dmah)
-
-#define R_SM(r)		(*(r))
-#define W_SM(r, v)	(*(r) = (v))
-
-/* dma engine software state */
-typedef struct dma_info {
-	struct hnddma_pub hnddma; /* exported structure */
-	uint *msg_level;	/* message level pointer */
-	char name[MAXNAMEL];	/* callers name for diag msgs */
-
-	void *pbus;		/* bus handle */
-
-	bool dma64;		/* this dma engine is operating in 64-bit mode */
-	bool addrext;		/* this dma engine supports DmaExtendedAddrChanges */
-
-	union {
-		struct {
-			dma64regs_t *txregs_64;	/* 64-bit dma tx engine registers */
-			dma64regs_t *rxregs_64;	/* 64-bit dma rx engine registers */
-			dma64dd_t *txd_64;	/* pointer to dma64 tx descriptor ring */
-			dma64dd_t *rxd_64;	/* pointer to dma64 rx descriptor ring */
-		} d64_u;
-	} dregs;
-
-	u16 dmadesc_align;	/* alignment requirement for dma descriptors */
-
-	u16 ntxd;		/* # tx descriptors tunable */
-	u16 txin;		/* index of next descriptor to reclaim */
-	u16 txout;		/* index of next descriptor to post */
-	void **txp;		/* pointer to parallel array of pointers to packets */
-	hnddma_seg_map_t *txp_dmah;	/* DMA MAP meta-data handle */
-	dmaaddr_t txdpa;	/* Aligned physical address of descriptor ring */
-	dmaaddr_t txdpaorig;	/* Original physical address of descriptor ring */
-	u16 txdalign;	/* #bytes added to alloc'd mem to align txd */
-	u32 txdalloc;	/* #bytes allocated for the ring */
-	u32 xmtptrbase;	/* When using unaligned descriptors, the ptr register
-				 * is not just an index, it needs all 13 bits to be
-				 * an offset from the addr register.
-				 */
-
-	u16 nrxd;		/* # rx descriptors tunable */
-	u16 rxin;		/* index of next descriptor to reclaim */
-	u16 rxout;		/* index of next descriptor to post */
-	void **rxp;		/* pointer to parallel array of pointers to packets */
-	hnddma_seg_map_t *rxp_dmah;	/* DMA MAP meta-data handle */
-	dmaaddr_t rxdpa;	/* Aligned physical address of descriptor ring */
-	dmaaddr_t rxdpaorig;	/* Original physical address of descriptor ring */
-	u16 rxdalign;	/* #bytes added to alloc'd mem to align rxd */
-	u32 rxdalloc;	/* #bytes allocated for the ring */
-	u32 rcvptrbase;	/* Base for ptr reg when using unaligned descriptors */
-
-	/* tunables */
-	unsigned int rxbufsize;	/* rx buffer size in bytes,
-				 * not including the extra headroom
-				 */
-	uint rxextrahdrroom;	/* extra rx headroom, reverseved to assist upper stack
-				 *  e.g. some rx pkt buffers will be bridged to tx side
-				 *  without byte copying. The extra headroom needs to be
-				 *  large enough to fit txheader needs.
-				 *  Some dongle driver may not need it.
-				 */
-	uint nrxpost;		/* # rx buffers to keep posted */
-	unsigned int rxoffset;	/* rxcontrol offset */
-	uint ddoffsetlow;	/* add to get dma address of descriptor ring, low 32 bits */
-	uint ddoffsethigh;	/*   high 32 bits */
-	uint dataoffsetlow;	/* add to get dma address of data buffer, low 32 bits */
-	uint dataoffsethigh;	/*   high 32 bits */
-	bool aligndesc_4k;	/* descriptor base need to be aligned or not */
-} dma_info_t;
-
-/* DMA Scatter-gather list is supported. Note this is limited to TX direction only */
-#ifdef BCMDMASGLISTOSL
-#define DMASGLIST_ENAB true
-#else
-#define DMASGLIST_ENAB false
-#endif				/* BCMDMASGLISTOSL */
-
-/* descriptor bumping macros */
-#define	XXD(x, n)	((x) & ((n) - 1))	/* faster than %, but n must be power of 2 */
-#define	TXD(x)		XXD((x), di->ntxd)
-#define	RXD(x)		XXD((x), di->nrxd)
-#define	NEXTTXD(i)	TXD((i) + 1)
-#define	PREVTXD(i)	TXD((i) - 1)
-#define	NEXTRXD(i)	RXD((i) + 1)
-#define	PREVRXD(i)	RXD((i) - 1)
-
-#define	NTXDACTIVE(h, t)	TXD((t) - (h))
-#define	NRXDACTIVE(h, t)	RXD((t) - (h))
-
-/* macros to convert between byte offsets and indexes */
-#define	B2I(bytes, type)	((bytes) / sizeof(type))
-#define	I2B(index, type)	((index) * sizeof(type))
-
-#define	PCI32ADDR_HIGH		0xc0000000	/* address[31:30] */
-#define	PCI32ADDR_HIGH_SHIFT	30	/* address[31:30] */
-
-#define	PCI64ADDR_HIGH		0x80000000	/* address[63] */
-#define	PCI64ADDR_HIGH_SHIFT	31	/* address[63] */
-
-/* Common prototypes */
-static bool _dma_isaddrext(dma_info_t *di);
-static bool _dma_descriptor_align(dma_info_t *di);
-static bool _dma_alloc(dma_info_t *di, uint direction);
-static void _dma_detach(dma_info_t *di);
-static void _dma_ddtable_init(dma_info_t *di, uint direction, dmaaddr_t pa);
-static void _dma_rxinit(dma_info_t *di);
-static void *_dma_rx(dma_info_t *di);
-static bool _dma_rxfill(dma_info_t *di);
-static void _dma_rxreclaim(dma_info_t *di);
-static void _dma_rxenable(dma_info_t *di);
-static void *_dma_getnextrxp(dma_info_t *di, bool forceall);
-static void _dma_rx_param_get(dma_info_t *di, u16 *rxoffset,
-			      u16 *rxbufsize);
-
-static void _dma_txblock(dma_info_t *di);
-static void _dma_txunblock(dma_info_t *di);
-static uint _dma_txactive(dma_info_t *di);
-static uint _dma_rxactive(dma_info_t *di);
-static uint _dma_txpending(dma_info_t *di);
-static uint _dma_txcommitted(dma_info_t *di);
-
-static void *_dma_peeknexttxp(dma_info_t *di);
-static void *_dma_peeknextrxp(dma_info_t *di);
-static unsigned long _dma_getvar(dma_info_t *di, const char *name);
-static void _dma_counterreset(dma_info_t *di);
-static void _dma_fifoloopbackenable(dma_info_t *di);
-static uint _dma_ctrlflags(dma_info_t *di, uint mask, uint flags);
-static u8 dma_align_sizetobits(uint size);
-static void *dma_ringalloc(dma_info_t *di, u32 boundary, uint size,
-			   u16 *alignbits, uint *alloced,
-			   dmaaddr_t *descpa);
-
-/* Prototypes for 64-bit routines */
-static bool dma64_alloc(dma_info_t *di, uint direction);
-static bool dma64_txreset(dma_info_t *di);
-static bool dma64_rxreset(dma_info_t *di);
-static bool dma64_txsuspendedidle(dma_info_t *di);
-static int dma64_txfast(dma_info_t *di, struct sk_buff *p0, bool commit);
-static int dma64_txunframed(dma_info_t *di, void *p0, uint len, bool commit);
-static void *dma64_getpos(dma_info_t *di, bool direction);
-static void *dma64_getnexttxp(dma_info_t *di, txd_range_t range);
-static void *dma64_getnextrxp(dma_info_t *di, bool forceall);
-static void dma64_txrotate(dma_info_t *di);
-
-static bool dma64_rxidle(dma_info_t *di);
-static void dma64_txinit(dma_info_t *di);
-static bool dma64_txenabled(dma_info_t *di);
-static void dma64_txsuspend(dma_info_t *di);
-static void dma64_txresume(dma_info_t *di);
-static bool dma64_txsuspended(dma_info_t *di);
-static void dma64_txreclaim(dma_info_t *di, txd_range_t range);
-static bool dma64_txstopped(dma_info_t *di);
-static bool dma64_rxstopped(dma_info_t *di);
-static bool dma64_rxenabled(dma_info_t *di);
-static bool _dma64_addrext(dma64regs_t *dma64regs);
-
-static inline u32 parity32(u32 data);
-
-const di_fcn_t dma64proc = {
-	(di_detach_t) _dma_detach,
-	(di_txinit_t) dma64_txinit,
-	(di_txreset_t) dma64_txreset,
-	(di_txenabled_t) dma64_txenabled,
-	(di_txsuspend_t) dma64_txsuspend,
-	(di_txresume_t) dma64_txresume,
-	(di_txsuspended_t) dma64_txsuspended,
-	(di_txsuspendedidle_t) dma64_txsuspendedidle,
-	(di_txfast_t) dma64_txfast,
-	(di_txunframed_t) dma64_txunframed,
-	(di_getpos_t) dma64_getpos,
-	(di_txstopped_t) dma64_txstopped,
-	(di_txreclaim_t) dma64_txreclaim,
-	(di_getnexttxp_t) dma64_getnexttxp,
-	(di_peeknexttxp_t) _dma_peeknexttxp,
-	(di_txblock_t) _dma_txblock,
-	(di_txunblock_t) _dma_txunblock,
-	(di_txactive_t) _dma_txactive,
-	(di_txrotate_t) dma64_txrotate,
-
-	(di_rxinit_t) _dma_rxinit,
-	(di_rxreset_t) dma64_rxreset,
-	(di_rxidle_t) dma64_rxidle,
-	(di_rxstopped_t) dma64_rxstopped,
-	(di_rxenable_t) _dma_rxenable,
-	(di_rxenabled_t) dma64_rxenabled,
-	(di_rx_t) _dma_rx,
-	(di_rxfill_t) _dma_rxfill,
-	(di_rxreclaim_t) _dma_rxreclaim,
-	(di_getnextrxp_t) _dma_getnextrxp,
-	(di_peeknextrxp_t) _dma_peeknextrxp,
-	(di_rxparam_get_t) _dma_rx_param_get,
-
-	(di_fifoloopbackenable_t) _dma_fifoloopbackenable,
-	(di_getvar_t) _dma_getvar,
-	(di_counterreset_t) _dma_counterreset,
-	(di_ctrlflags_t) _dma_ctrlflags,
-	NULL,
-	NULL,
-	NULL,
-	(di_rxactive_t) _dma_rxactive,
-	(di_txpending_t) _dma_txpending,
-	(di_txcommitted_t) _dma_txcommitted,
-	39
-};
-
-struct hnddma_pub *dma_attach(char *name, si_t *sih,
-		     void *dmaregstx, void *dmaregsrx, uint ntxd,
-		     uint nrxd, uint rxbufsize, int rxextheadroom,
-		     uint nrxpost, uint rxoffset, uint *msg_level)
-{
-	dma_info_t *di;
-	uint size;
-
-	/* allocate private info structure */
-	di = kzalloc(sizeof(dma_info_t), GFP_ATOMIC);
-	if (di == NULL) {
-#ifdef BCMDBG
-		printk(KERN_ERR "dma_attach: out of memory\n");
-#endif
-		return NULL;
-	}
-
-	di->msg_level = msg_level ? msg_level : &dma_msg_level;
-
-	/* old chips w/o sb is no longer supported */
-	ASSERT(sih != NULL);
-
-	di->dma64 = ((si_core_sflags(sih, 0, 0) & SISF_DMA64) == SISF_DMA64);
-
-	/* check arguments */
-	ASSERT(ISPOWEROF2(ntxd));
-	ASSERT(ISPOWEROF2(nrxd));
-
-	if (nrxd == 0)
-		ASSERT(dmaregsrx == NULL);
-	if (ntxd == 0)
-		ASSERT(dmaregstx == NULL);
-
-	/* init dma reg pointer */
-	ASSERT(ntxd <= D64MAXDD);
-	ASSERT(nrxd <= D64MAXDD);
-	di->d64txregs = (dma64regs_t *) dmaregstx;
-	di->d64rxregs = (dma64regs_t *) dmaregsrx;
-	di->hnddma.di_fn = (const di_fcn_t *)&dma64proc;
-
-	/* Default flags (which can be changed by the driver calling dma_ctrlflags
-	 * before enable): For backwards compatibility both Rx Overflow Continue
-	 * and Parity are DISABLED.
-	 * supports it.
-	 */
-	di->hnddma.di_fn->ctrlflags(&di->hnddma, DMA_CTRL_ROC | DMA_CTRL_PEN,
-				    0);
-
-	DMA_TRACE(("%s: dma_attach: %s flags 0x%x ntxd %d nrxd %d "
-		   "rxbufsize %d rxextheadroom %d nrxpost %d rxoffset %d "
-		   "dmaregstx %p dmaregsrx %p\n", name, "DMA64",
-		   di->hnddma.dmactrlflags, ntxd, nrxd, rxbufsize,
-		   rxextheadroom, nrxpost, rxoffset, dmaregstx, dmaregsrx));
-
-	/* make a private copy of our callers name */
-	strncpy(di->name, name, MAXNAMEL);
-	di->name[MAXNAMEL - 1] = '\0';
-
-	di->pbus = ((struct si_info *)sih)->pbus;
-
-	/* save tunables */
-	di->ntxd = (u16) ntxd;
-	di->nrxd = (u16) nrxd;
-
-	/* the actual dma size doesn't include the extra headroom */
-	di->rxextrahdrroom =
-	    (rxextheadroom == -1) ? BCMEXTRAHDROOM : rxextheadroom;
-	if (rxbufsize > BCMEXTRAHDROOM)
-		di->rxbufsize = (u16) (rxbufsize - di->rxextrahdrroom);
-	else
-		di->rxbufsize = (u16) rxbufsize;
-
-	di->nrxpost = (u16) nrxpost;
-	di->rxoffset = (u8) rxoffset;
-
-	/*
-	 * figure out the DMA physical address offset for dd and data
-	 *     PCI/PCIE: they map silicon backplace address to zero based memory, need offset
-	 *     Other bus: use zero
-	 *     SI_BUS BIGENDIAN kludge: use sdram swapped region for data buffer, not descriptor
-	 */
-	di->ddoffsetlow = 0;
-	di->dataoffsetlow = 0;
-	/* for pci bus, add offset */
-	if (sih->bustype == PCI_BUS) {
-		/* pcie with DMA64 */
-		di->ddoffsetlow = 0;
-		di->ddoffsethigh = SI_PCIE_DMA_H32;
-		di->dataoffsetlow = di->ddoffsetlow;
-		di->dataoffsethigh = di->ddoffsethigh;
-	}
-#if defined(__mips__) && defined(IL_BIGENDIAN)
-	di->dataoffsetlow = di->dataoffsetlow + SI_SDRAM_SWAPPED;
-#endif				/* defined(__mips__) && defined(IL_BIGENDIAN) */
-	/* WAR64450 : DMACtl.Addr ext fields are not supported in SDIOD core. */
-	if ((si_coreid(sih) == SDIOD_CORE_ID)
-	    && ((si_corerev(sih) > 0) && (si_corerev(sih) <= 2)))
-		di->addrext = 0;
-	else if ((si_coreid(sih) == I2S_CORE_ID) &&
-		 ((si_corerev(sih) == 0) || (si_corerev(sih) == 1)))
-		di->addrext = 0;
-	else
-		di->addrext = _dma_isaddrext(di);
-
-	/* does the descriptors need to be aligned and if yes, on 4K/8K or not */
-	di->aligndesc_4k = _dma_descriptor_align(di);
-	if (di->aligndesc_4k) {
-		di->dmadesc_align = D64RINGALIGN_BITS;
-		if ((ntxd < D64MAXDD / 2) && (nrxd < D64MAXDD / 2)) {
-			/* for smaller dd table, HW relax alignment reqmnt */
-			di->dmadesc_align = D64RINGALIGN_BITS - 1;
-		}
-	} else
-		di->dmadesc_align = 4;	/* 16 byte alignment */
-
-	DMA_NONE(("DMA descriptor align_needed %d, align %d\n",
-		  di->aligndesc_4k, di->dmadesc_align));
-
-	/* allocate tx packet pointer vector */
-	if (ntxd) {
-		size = ntxd * sizeof(void *);
-		di->txp = kzalloc(size, GFP_ATOMIC);
-		if (di->txp == NULL) {
-			DMA_ERROR(("%s: dma_attach: out of tx memory\n", di->name));
-			goto fail;
-		}
-	}
-
-	/* allocate rx packet pointer vector */
-	if (nrxd) {
-		size = nrxd * sizeof(void *);
-		di->rxp = kzalloc(size, GFP_ATOMIC);
-		if (di->rxp == NULL) {
-			DMA_ERROR(("%s: dma_attach: out of rx memory\n", di->name));
-			goto fail;
-		}
-	}
-
-	/* allocate transmit descriptor ring, only need ntxd descriptors but it must be aligned */
-	if (ntxd) {
-		if (!_dma_alloc(di, DMA_TX))
-			goto fail;
-	}
-
-	/* allocate receive descriptor ring, only need nrxd descriptors but it must be aligned */
-	if (nrxd) {
-		if (!_dma_alloc(di, DMA_RX))
-			goto fail;
-	}
-
-	if ((di->ddoffsetlow != 0) && !di->addrext) {
-		if (PHYSADDRLO(di->txdpa) > SI_PCI_DMA_SZ) {
-			DMA_ERROR(("%s: dma_attach: txdpa 0x%x: addrext not supported\n", di->name, (u32) PHYSADDRLO(di->txdpa)));
-			goto fail;
-		}
-		if (PHYSADDRLO(di->rxdpa) > SI_PCI_DMA_SZ) {
-			DMA_ERROR(("%s: dma_attach: rxdpa 0x%x: addrext not supported\n", di->name, (u32) PHYSADDRLO(di->rxdpa)));
-			goto fail;
-		}
-	}
-
-	DMA_TRACE(("ddoffsetlow 0x%x ddoffsethigh 0x%x dataoffsetlow 0x%x dataoffsethigh " "0x%x addrext %d\n", di->ddoffsetlow, di->ddoffsethigh, di->dataoffsetlow, di->dataoffsethigh, di->addrext));
-
-	/* allocate DMA mapping vectors */
-	if (DMASGLIST_ENAB) {
-		if (ntxd) {
-			size = ntxd * sizeof(hnddma_seg_map_t);
-			di->txp_dmah = kzalloc(size, GFP_ATOMIC);
-			if (di->txp_dmah == NULL)
-				goto fail;
-		}
-
-		if (nrxd) {
-			size = nrxd * sizeof(hnddma_seg_map_t);
-			di->rxp_dmah = kzalloc(size, GFP_ATOMIC);
-			if (di->rxp_dmah == NULL)
-				goto fail;
-		}
-	}
-
-	return (struct hnddma_pub *) di;
-
- fail:
-	_dma_detach(di);
-	return NULL;
-}
-
-/* Check for odd number of 1's */
-static inline u32 parity32(u32 data)
-{
-	data ^= data >> 16;
-	data ^= data >> 8;
-	data ^= data >> 4;
-	data ^= data >> 2;
-	data ^= data >> 1;
-
-	return data & 1;
-}
-
-#define DMA64_DD_PARITY(dd)  parity32((dd)->addrlow ^ (dd)->addrhigh ^ (dd)->ctrl1 ^ (dd)->ctrl2)
-
-static inline void
-dma64_dd_upd(dma_info_t *di, dma64dd_t *ddring, dmaaddr_t pa, uint outidx,
-	     u32 *flags, u32 bufcount)
-{
-	u32 ctrl2 = bufcount & D64_CTRL2_BC_MASK;
-
-	/* PCI bus with big(>1G) physical address, use address extension */
-#if defined(__mips__) && defined(IL_BIGENDIAN)
-	if ((di->dataoffsetlow == SI_SDRAM_SWAPPED)
-	    || !(PHYSADDRLO(pa) & PCI32ADDR_HIGH)) {
-#else
-	if ((di->dataoffsetlow == 0) || !(PHYSADDRLO(pa) & PCI32ADDR_HIGH)) {
-#endif				/* defined(__mips__) && defined(IL_BIGENDIAN) */
-		ASSERT((PHYSADDRHI(pa) & PCI64ADDR_HIGH) == 0);
-
-		W_SM(&ddring[outidx].addrlow,
-		     BUS_SWAP32(PHYSADDRLO(pa) + di->dataoffsetlow));
-		W_SM(&ddring[outidx].addrhigh,
-		     BUS_SWAP32(PHYSADDRHI(pa) + di->dataoffsethigh));
-		W_SM(&ddring[outidx].ctrl1, BUS_SWAP32(*flags));
-		W_SM(&ddring[outidx].ctrl2, BUS_SWAP32(ctrl2));
-	} else {
-		/* address extension for 32-bit PCI */
-		u32 ae;
-		ASSERT(di->addrext);
-
-		ae = (PHYSADDRLO(pa) & PCI32ADDR_HIGH) >> PCI32ADDR_HIGH_SHIFT;
-		PHYSADDRLO(pa) &= ~PCI32ADDR_HIGH;
-		ASSERT(PHYSADDRHI(pa) == 0);
-
-		ctrl2 |= (ae << D64_CTRL2_AE_SHIFT) & D64_CTRL2_AE;
-		W_SM(&ddring[outidx].addrlow,
-		     BUS_SWAP32(PHYSADDRLO(pa) + di->dataoffsetlow));
-		W_SM(&ddring[outidx].addrhigh,
-		     BUS_SWAP32(0 + di->dataoffsethigh));
-		W_SM(&ddring[outidx].ctrl1, BUS_SWAP32(*flags));
-		W_SM(&ddring[outidx].ctrl2, BUS_SWAP32(ctrl2));
-	}
-	if (di->hnddma.dmactrlflags & DMA_CTRL_PEN) {
-		if (DMA64_DD_PARITY(&ddring[outidx])) {
-			W_SM(&ddring[outidx].ctrl2,
-			     BUS_SWAP32(ctrl2 | D64_CTRL2_PARITY));
-		}
-	}
-}
-
-static bool _dma_alloc(dma_info_t *di, uint direction)
-{
-	return dma64_alloc(di, direction);
-}
-
-void *dma_alloc_consistent(struct pci_dev *pdev, uint size, u16 align_bits,
-			       uint *alloced, unsigned long *pap)
-{
-	if (align_bits) {
-		u16 align = (1 << align_bits);
-		if (!IS_ALIGNED(PAGE_SIZE, align))
-			size += align;
-		*alloced = size;
-	}
-	return pci_alloc_consistent(pdev, size, (dma_addr_t *) pap);
-}
-
-/* !! may be called with core in reset */
-static void _dma_detach(dma_info_t *di)
-{
-
-	DMA_TRACE(("%s: dma_detach\n", di->name));
-
-	/* shouldn't be here if descriptors are unreclaimed */
-	ASSERT(di->txin == di->txout);
-	ASSERT(di->rxin == di->rxout);
-
-	/* free dma descriptor rings */
-	if (di->txd64)
-		pci_free_consistent(di->pbus, di->txdalloc,
-				    ((s8 *)di->txd64 - di->txdalign),
-				    (di->txdpaorig));
-	if (di->rxd64)
-		pci_free_consistent(di->pbus, di->rxdalloc,
-				    ((s8 *)di->rxd64 - di->rxdalign),
-				    (di->rxdpaorig));
-
-	/* free packet pointer vectors */
-	kfree(di->txp);
-	kfree(di->rxp);
-
-	/* free tx packet DMA handles */
-	kfree(di->txp_dmah);
-
-	/* free rx packet DMA handles */
-	kfree(di->rxp_dmah);
-
-	/* free our private info structure */
-	kfree(di);
-
-}
-
-static bool _dma_descriptor_align(dma_info_t *di)
-{
-	u32 addrl;
-
-	/* Check to see if the descriptors need to be aligned on 4K/8K or not */
-	if (di->d64txregs != NULL) {
-		W_REG(&di->d64txregs->addrlow, 0xff0);
-		addrl = R_REG(&di->d64txregs->addrlow);
-		if (addrl != 0)
-			return false;
-	} else if (di->d64rxregs != NULL) {
-		W_REG(&di->d64rxregs->addrlow, 0xff0);
-		addrl = R_REG(&di->d64rxregs->addrlow);
-		if (addrl != 0)
-			return false;
-	}
-	return true;
-}
-
-/* return true if this dma engine supports DmaExtendedAddrChanges, otherwise false */
-static bool _dma_isaddrext(dma_info_t *di)
-{
-	/* DMA64 supports full 32- or 64-bit operation. AE is always valid */
-
-	/* not all tx or rx channel are available */
-	if (di->d64txregs != NULL) {
-		if (!_dma64_addrext(di->d64txregs)) {
-			DMA_ERROR(("%s: _dma_isaddrext: DMA64 tx doesn't have "
-				   "AE set\n", di->name));
-			ASSERT(0);
-		}
-		return true;
-	} else if (di->d64rxregs != NULL) {
-		if (!_dma64_addrext(di->d64rxregs)) {
-			DMA_ERROR(("%s: _dma_isaddrext: DMA64 rx doesn't have "
-				   "AE set\n", di->name));
-			ASSERT(0);
-		}
-		return true;
-	}
-	return false;
-}
-
-/* initialize descriptor table base address */
-static void _dma_ddtable_init(dma_info_t *di, uint direction, dmaaddr_t pa)
-{
-	if (!di->aligndesc_4k) {
-		if (direction == DMA_TX)
-			di->xmtptrbase = PHYSADDRLO(pa);
-		else
-			di->rcvptrbase = PHYSADDRLO(pa);
-	}
-
-	if ((di->ddoffsetlow == 0)
-	    || !(PHYSADDRLO(pa) & PCI32ADDR_HIGH)) {
-		if (direction == DMA_TX) {
-			W_REG(&di->d64txregs->addrlow,
-			      (PHYSADDRLO(pa) + di->ddoffsetlow));
-			W_REG(&di->d64txregs->addrhigh,
-			      (PHYSADDRHI(pa) + di->ddoffsethigh));
-		} else {
-			W_REG(&di->d64rxregs->addrlow,
-			      (PHYSADDRLO(pa) + di->ddoffsetlow));
-			W_REG(&di->d64rxregs->addrhigh,
-				(PHYSADDRHI(pa) + di->ddoffsethigh));
-		}
-	} else {
-		/* DMA64 32bits address extension */
-		u32 ae;
-		ASSERT(di->addrext);
-		ASSERT(PHYSADDRHI(pa) == 0);
-
-		/* shift the high bit(s) from pa to ae */
-		ae = (PHYSADDRLO(pa) & PCI32ADDR_HIGH) >>
-		    PCI32ADDR_HIGH_SHIFT;
-		PHYSADDRLO(pa) &= ~PCI32ADDR_HIGH;
-
-		if (direction == DMA_TX) {
-			W_REG(&di->d64txregs->addrlow,
-			      (PHYSADDRLO(pa) + di->ddoffsetlow));
-			W_REG(&di->d64txregs->addrhigh,
-			      di->ddoffsethigh);
-			SET_REG(&di->d64txregs->control,
-				D64_XC_AE, (ae << D64_XC_AE_SHIFT));
-		} else {
-			W_REG(&di->d64rxregs->addrlow,
-			      (PHYSADDRLO(pa) + di->ddoffsetlow));
-			W_REG(&di->d64rxregs->addrhigh,
-			      di->ddoffsethigh);
-			SET_REG(&di->d64rxregs->control,
-				D64_RC_AE, (ae << D64_RC_AE_SHIFT));
-		}
-	}
-}
-
-static void _dma_fifoloopbackenable(dma_info_t *di)
-{
-	DMA_TRACE(("%s: dma_fifoloopbackenable\n", di->name));
-
-	OR_REG(&di->d64txregs->control, D64_XC_LE);
-}
-
-static void _dma_rxinit(dma_info_t *di)
-{
-	DMA_TRACE(("%s: dma_rxinit\n", di->name));
-
-	if (di->nrxd == 0)
-		return;
-
-	di->rxin = di->rxout = 0;
-
-	/* clear rx descriptor ring */
-	memset((void *)di->rxd64, '\0',
-		(di->nrxd * sizeof(dma64dd_t)));
-
-	/* DMA engine with out alignment requirement requires table to be inited
-	 * before enabling the engine
-	 */
-	if (!di->aligndesc_4k)
-		_dma_ddtable_init(di, DMA_RX, di->rxdpa);
-
-	_dma_rxenable(di);
-
-	if (di->aligndesc_4k)
-		_dma_ddtable_init(di, DMA_RX, di->rxdpa);
-}
-
-static void _dma_rxenable(dma_info_t *di)
-{
-	uint dmactrlflags = di->hnddma.dmactrlflags;
-	u32 control;
-
-	DMA_TRACE(("%s: dma_rxenable\n", di->name));
-
-	control =
-	    (R_REG(&di->d64rxregs->control) & D64_RC_AE) |
-	    D64_RC_RE;
-
-	if ((dmactrlflags & DMA_CTRL_PEN) == 0)
-		control |= D64_RC_PD;
-
-	if (dmactrlflags & DMA_CTRL_ROC)
-		control |= D64_RC_OC;
-
-	W_REG(&di->d64rxregs->control,
-		((di->rxoffset << D64_RC_RO_SHIFT) | control));
-}
-
-static void
-_dma_rx_param_get(dma_info_t *di, u16 *rxoffset, u16 *rxbufsize)
-{
-	/* the normal values fit into 16 bits */
-	*rxoffset = (u16) di->rxoffset;
-	*rxbufsize = (u16) di->rxbufsize;
-}
-
-/* !! rx entry routine
- * returns a pointer to the next frame received, or NULL if there are no more
- *   if DMA_CTRL_RXMULTI is defined, DMA scattering(multiple buffers) is supported
- *      with pkts chain
- *   otherwise, it's treated as giant pkt and will be tossed.
- *   The DMA scattering starts with normal DMA header, followed by first buffer data.
- *   After it reaches the max size of buffer, the data continues in next DMA descriptor
- *   buffer WITHOUT DMA header
- */
-static void *BCMFASTPATH _dma_rx(dma_info_t *di)
-{
-	struct sk_buff *p, *head, *tail;
-	uint len;
-	uint pkt_len;
-	int resid = 0;
-
- next_frame:
-	head = _dma_getnextrxp(di, false);
-	if (head == NULL)
-		return NULL;
-
-	len = le16_to_cpu(*(u16 *) (head->data));
-	DMA_TRACE(("%s: dma_rx len %d\n", di->name, len));
-
-#if defined(__mips__)
-#define OSL_UNCACHED(va)        ((void *)KSEG1ADDR((va)))
-	if (!len) {
-		while (!(len = *(u16 *) OSL_UNCACHED(head->data)))
-			udelay(1);
-
-		*(u16 *) (head->data) = cpu_to_le16((u16) len);
-	}
-#endif				/* defined(__mips__) */
-
-	/* set actual length */
-	pkt_len = min((di->rxoffset + len), di->rxbufsize);
-	__skb_trim(head, pkt_len);
-	resid = len - (di->rxbufsize - di->rxoffset);
-
-	/* check for single or multi-buffer rx */
-	if (resid > 0) {
-		tail = head;
-		while ((resid > 0) && (p = _dma_getnextrxp(di, false))) {
-			tail->next = p;
-			pkt_len = min(resid, (int)di->rxbufsize);
-			__skb_trim(p, pkt_len);
-
-			tail = p;
-			resid -= di->rxbufsize;
-		}
-
-#ifdef BCMDBG
-		if (resid > 0) {
-			uint cur;
-			ASSERT(p == NULL);
-			cur =
-			    B2I(((R_REG(&di->d64rxregs->status0) &
-				  D64_RS0_CD_MASK) -
-				 di->rcvptrbase) & D64_RS0_CD_MASK,
-				dma64dd_t);
-			DMA_ERROR(("_dma_rx, rxin %d rxout %d, hw_curr %d\n",
-				   di->rxin, di->rxout, cur));
-		}
-#endif				/* BCMDBG */
-
-		if ((di->hnddma.dmactrlflags & DMA_CTRL_RXMULTI) == 0) {
-			DMA_ERROR(("%s: dma_rx: bad frame length (%d)\n",
-				   di->name, len));
-			pkt_buf_free_skb(head);
-			di->hnddma.rxgiants++;
-			goto next_frame;
-		}
-	}
-
-	return head;
-}
-
-/* post receive buffers
- *  return false is refill failed completely and ring is empty
- *  this will stall the rx dma and user might want to call rxfill again asap
- *  This unlikely happens on memory-rich NIC, but often on memory-constrained dongle
- */
-static bool BCMFASTPATH _dma_rxfill(dma_info_t *di)
-{
-	struct sk_buff *p;
-	u16 rxin, rxout;
-	u32 flags = 0;
-	uint n;
-	uint i;
-	dmaaddr_t pa;
-	uint extra_offset = 0;
-	bool ring_empty;
-
-	ring_empty = false;
-
-	/*
-	 * Determine how many receive buffers we're lacking
-	 * from the full complement, allocate, initialize,
-	 * and post them, then update the chip rx lastdscr.
-	 */
-
-	rxin = di->rxin;
-	rxout = di->rxout;
-
-	n = di->nrxpost - NRXDACTIVE(rxin, rxout);
-
-	DMA_TRACE(("%s: dma_rxfill: post %d\n", di->name, n));
-
-	if (di->rxbufsize > BCMEXTRAHDROOM)
-		extra_offset = di->rxextrahdrroom;
-
-	for (i = 0; i < n; i++) {
-		/* the di->rxbufsize doesn't include the extra headroom, we need to add it to the
-		   size to be allocated
-		 */
-
-		p = pkt_buf_get_skb(di->rxbufsize + extra_offset);
-
-		if (p == NULL) {
-			DMA_ERROR(("%s: dma_rxfill: out of rxbufs\n",
-				   di->name));
-			if (i == 0 && dma64_rxidle(di)) {
-				DMA_ERROR(("%s: rxfill64: ring is empty !\n",
-					   di->name));
-				ring_empty = true;
-			}
-			di->hnddma.rxnobuf++;
-			break;
-		}
-		/* reserve an extra headroom, if applicable */
-		if (extra_offset)
-			skb_pull(p, extra_offset);
-
-		/* Do a cached write instead of uncached write since DMA_MAP
-		 * will flush the cache.
-		 */
-		*(u32 *) (p->data) = 0;
-
-		if (DMASGLIST_ENAB)
-			memset(&di->rxp_dmah[rxout], 0,
-				sizeof(hnddma_seg_map_t));
-
-		pa = pci_map_single(di->pbus, p->data,
-			di->rxbufsize, PCI_DMA_FROMDEVICE);
-
-		ASSERT(IS_ALIGNED(PHYSADDRLO(pa), 4));
-
-		/* save the free packet pointer */
-		ASSERT(di->rxp[rxout] == NULL);
-		di->rxp[rxout] = p;
-
-		/* reset flags for each descriptor */
-		flags = 0;
-		if (rxout == (di->nrxd - 1))
-			flags = D64_CTRL1_EOT;
-
-		dma64_dd_upd(di, di->rxd64, pa, rxout, &flags,
-			     di->rxbufsize);
-		rxout = NEXTRXD(rxout);
-	}
-
-	di->rxout = rxout;
-
-	/* update the chip lastdscr pointer */
-	W_REG(&di->d64rxregs->ptr,
-	      di->rcvptrbase + I2B(rxout, dma64dd_t));
-
-	return ring_empty;
-}
-
-/* like getnexttxp but no reclaim */
-static void *_dma_peeknexttxp(dma_info_t *di)
-{
-	uint end, i;
-
-	if (di->ntxd == 0)
-		return NULL;
-
-	end =
-	    B2I(((R_REG(&di->d64txregs->status0) &
-		  D64_XS0_CD_MASK) - di->xmtptrbase) & D64_XS0_CD_MASK,
-		  dma64dd_t);
-
-	for (i = di->txin; i != end; i = NEXTTXD(i))
-		if (di->txp[i])
-			return di->txp[i];
-
-	return NULL;
-}
-
-/* like getnextrxp but not take off the ring */
-static void *_dma_peeknextrxp(dma_info_t *di)
-{
-	uint end, i;
-
-	if (di->nrxd == 0)
-		return NULL;
-
-	end =
-	    B2I(((R_REG(&di->d64rxregs->status0) &
-		  D64_RS0_CD_MASK) - di->rcvptrbase) & D64_RS0_CD_MASK,
-		  dma64dd_t);
-
-	for (i = di->rxin; i != end; i = NEXTRXD(i))
-		if (di->rxp[i])
-			return di->rxp[i];
-
-	return NULL;
-}
-
-static void _dma_rxreclaim(dma_info_t *di)
-{
-	void *p;
-
-	DMA_TRACE(("%s: dma_rxreclaim\n", di->name));
-
-	while ((p = _dma_getnextrxp(di, true)))
-		pkt_buf_free_skb(p);
-}
-
-static void *BCMFASTPATH _dma_getnextrxp(dma_info_t *di, bool forceall)
-{
-	if (di->nrxd == 0)
-		return NULL;
-
-	return dma64_getnextrxp(di, forceall);
-}
-
-static void _dma_txblock(dma_info_t *di)
-{
-	di->hnddma.txavail = 0;
-}
-
-static void _dma_txunblock(dma_info_t *di)
-{
-	di->hnddma.txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1;
-}
-
-static uint _dma_txactive(dma_info_t *di)
-{
-	return NTXDACTIVE(di->txin, di->txout);
-}
-
-static uint _dma_txpending(dma_info_t *di)
-{
-	uint curr;
-
-	curr =
-	    B2I(((R_REG(&di->d64txregs->status0) &
-		  D64_XS0_CD_MASK) - di->xmtptrbase) & D64_XS0_CD_MASK,
-		  dma64dd_t);
-
-	return NTXDACTIVE(curr, di->txout);
-}
-
-static uint _dma_txcommitted(dma_info_t *di)
-{
-	uint ptr;
-	uint txin = di->txin;
-
-	if (txin == di->txout)
-		return 0;
-
-	ptr = B2I(R_REG(&di->d64txregs->ptr), dma64dd_t);
-
-	return NTXDACTIVE(di->txin, ptr);
-}
-
-static uint _dma_rxactive(dma_info_t *di)
-{
-	return NRXDACTIVE(di->rxin, di->rxout);
-}
-
-static void _dma_counterreset(dma_info_t *di)
-{
-	/* reset all software counter */
-	di->hnddma.rxgiants = 0;
-	di->hnddma.rxnobuf = 0;
-	di->hnddma.txnobuf = 0;
-}
-
-static uint _dma_ctrlflags(dma_info_t *di, uint mask, uint flags)
-{
-	uint dmactrlflags = di->hnddma.dmactrlflags;
-
-	if (di == NULL) {
-		DMA_ERROR(("%s: _dma_ctrlflags: NULL dma handle\n", di->name));
-		return 0;
-	}
-
-	ASSERT((flags & ~mask) == 0);
-
-	dmactrlflags &= ~mask;
-	dmactrlflags |= flags;
-
-	/* If trying to enable parity, check if parity is actually supported */
-	if (dmactrlflags & DMA_CTRL_PEN) {
-		u32 control;
-
-		control = R_REG(&di->d64txregs->control);
-		W_REG(&di->d64txregs->control,
-		      control | D64_XC_PD);
-		if (R_REG(&di->d64txregs->control) & D64_XC_PD) {
-			/* We *can* disable it so it is supported,
-			 * restore control register
-			 */
-			W_REG(&di->d64txregs->control,
-			control);
-		} else {
-			/* Not supported, don't allow it to be enabled */
-			dmactrlflags &= ~DMA_CTRL_PEN;
-		}
-	}
-
-	di->hnddma.dmactrlflags = dmactrlflags;
-
-	return dmactrlflags;
-}
-
-/* get the address of the var in order to change later */
-static unsigned long _dma_getvar(dma_info_t *di, const char *name)
-{
-	if (!strcmp(name, "&txavail"))
-		return (unsigned long)&(di->hnddma.txavail);
-	else {
-		ASSERT(0);
-	}
-	return 0;
-}
-
-static
-u8 dma_align_sizetobits(uint size)
-{
-	u8 bitpos = 0;
-	ASSERT(size);
-	ASSERT(!(size & (size - 1)));
-	while (size >>= 1) {
-		bitpos++;
-	}
-	return bitpos;
-}
-
-/* This function ensures that the DMA descriptor ring will not get allocated
- * across Page boundary. If the allocation is done across the page boundary
- * at the first time, then it is freed and the allocation is done at
- * descriptor ring size aligned location. This will ensure that the ring will
- * not cross page boundary
- */
-static void *dma_ringalloc(dma_info_t *di, u32 boundary, uint size,
-			   u16 *alignbits, uint *alloced,
-			   dmaaddr_t *descpa)
-{
-	void *va;
-	u32 desc_strtaddr;
-	u32 alignbytes = 1 << *alignbits;
-
-	va = dma_alloc_consistent(di->pbus, size, *alignbits, alloced, descpa);
-
-	if (NULL == va)
-		return NULL;
-
-	desc_strtaddr = (u32) roundup((unsigned long)va, alignbytes);
-	if (((desc_strtaddr + size - 1) & boundary) != (desc_strtaddr
-							& boundary)) {
-		*alignbits = dma_align_sizetobits(size);
-		pci_free_consistent(di->pbus, size, va, *descpa);
-		va = dma_alloc_consistent(di->pbus, size, *alignbits,
-			alloced, descpa);
-	}
-	return va;
-}
-
-/* 64-bit DMA functions */
-
-static void dma64_txinit(dma_info_t *di)
-{
-	u32 control = D64_XC_XE;
-
-	DMA_TRACE(("%s: dma_txinit\n", di->name));
-
-	if (di->ntxd == 0)
-		return;
-
-	di->txin = di->txout = 0;
-	di->hnddma.txavail = di->ntxd - 1;
-
-	/* clear tx descriptor ring */
-	memset((void *)di->txd64, '\0', (di->ntxd * sizeof(dma64dd_t)));
-
-	/* DMA engine with out alignment requirement requires table to be inited
-	 * before enabling the engine
-	 */
-	if (!di->aligndesc_4k)
-		_dma_ddtable_init(di, DMA_TX, di->txdpa);
-
-	if ((di->hnddma.dmactrlflags & DMA_CTRL_PEN) == 0)
-		control |= D64_XC_PD;
-	OR_REG(&di->d64txregs->control, control);
-
-	/* DMA engine with alignment requirement requires table to be inited
-	 * before enabling the engine
-	 */
-	if (di->aligndesc_4k)
-		_dma_ddtable_init(di, DMA_TX, di->txdpa);
-}
-
-static bool dma64_txenabled(dma_info_t *di)
-{
-	u32 xc;
-
-	/* If the chip is dead, it is not enabled :-) */
-	xc = R_REG(&di->d64txregs->control);
-	return (xc != 0xffffffff) && (xc & D64_XC_XE);
-}
-
-static void dma64_txsuspend(dma_info_t *di)
-{
-	DMA_TRACE(("%s: dma_txsuspend\n", di->name));
-
-	if (di->ntxd == 0)
-		return;
-
-	OR_REG(&di->d64txregs->control, D64_XC_SE);
-}
-
-static void dma64_txresume(dma_info_t *di)
-{
-	DMA_TRACE(("%s: dma_txresume\n", di->name));
-
-	if (di->ntxd == 0)
-		return;
-
-	AND_REG(&di->d64txregs->control, ~D64_XC_SE);
-}
-
-static bool dma64_txsuspended(dma_info_t *di)
-{
-	return (di->ntxd == 0) ||
-	    ((R_REG(&di->d64txregs->control) & D64_XC_SE) ==
-	     D64_XC_SE);
-}
-
-static void BCMFASTPATH dma64_txreclaim(dma_info_t *di, txd_range_t range)
-{
-	void *p;
-
-	DMA_TRACE(("%s: dma_txreclaim %s\n", di->name,
-		   (range == HNDDMA_RANGE_ALL) ? "all" :
-		   ((range ==
-		     HNDDMA_RANGE_TRANSMITTED) ? "transmitted" :
-		    "transferred")));
-
-	if (di->txin == di->txout)
-		return;
-
-	while ((p = dma64_getnexttxp(di, range))) {
-		/* For unframed data, we don't have any packets to free */
-		if (!(di->hnddma.dmactrlflags & DMA_CTRL_UNFRAMED))
-			pkt_buf_free_skb(p);
-	}
-}
-
-static bool dma64_txstopped(dma_info_t *di)
-{
-	return ((R_REG(&di->d64txregs->status0) & D64_XS0_XS_MASK) ==
-		D64_XS0_XS_STOPPED);
-}
-
-static bool dma64_rxstopped(dma_info_t *di)
-{
-	return ((R_REG(&di->d64rxregs->status0) & D64_RS0_RS_MASK) ==
-		D64_RS0_RS_STOPPED);
-}
-
-static bool dma64_alloc(dma_info_t *di, uint direction)
-{
-	u16 size;
-	uint ddlen;
-	void *va;
-	uint alloced = 0;
-	u16 align;
-	u16 align_bits;
-
-	ddlen = sizeof(dma64dd_t);
-
-	size = (direction == DMA_TX) ? (di->ntxd * ddlen) : (di->nrxd * ddlen);
-	align_bits = di->dmadesc_align;
-	align = (1 << align_bits);
-
-	if (direction == DMA_TX) {
-		va = dma_ringalloc(di, D64RINGALIGN, size, &align_bits,
-			&alloced, &di->txdpaorig);
-		if (va == NULL) {
-			DMA_ERROR(("%s: dma64_alloc: DMA_ALLOC_CONSISTENT(ntxd) failed\n", di->name));
-			return false;
-		}
-		align = (1 << align_bits);
-		di->txd64 = (dma64dd_t *) roundup((unsigned long)va, align);
-		di->txdalign = (uint) ((s8 *)di->txd64 - (s8 *) va);
-		PHYSADDRLOSET(di->txdpa,
-			      PHYSADDRLO(di->txdpaorig) + di->txdalign);
-		/* Make sure that alignment didn't overflow */
-		ASSERT(PHYSADDRLO(di->txdpa) >= PHYSADDRLO(di->txdpaorig));
-
-		PHYSADDRHISET(di->txdpa, PHYSADDRHI(di->txdpaorig));
-		di->txdalloc = alloced;
-		ASSERT(IS_ALIGNED((unsigned long)di->txd64, align));
-	} else {
-		va = dma_ringalloc(di, D64RINGALIGN, size, &align_bits,
-			&alloced, &di->rxdpaorig);
-		if (va == NULL) {
-			DMA_ERROR(("%s: dma64_alloc: DMA_ALLOC_CONSISTENT(nrxd) failed\n", di->name));
-			return false;
-		}
-		align = (1 << align_bits);
-		di->rxd64 = (dma64dd_t *) roundup((unsigned long)va, align);
-		di->rxdalign = (uint) ((s8 *)di->rxd64 - (s8 *) va);
-		PHYSADDRLOSET(di->rxdpa,
-			      PHYSADDRLO(di->rxdpaorig) + di->rxdalign);
-		/* Make sure that alignment didn't overflow */
-		ASSERT(PHYSADDRLO(di->rxdpa) >= PHYSADDRLO(di->rxdpaorig));
-
-		PHYSADDRHISET(di->rxdpa, PHYSADDRHI(di->rxdpaorig));
-		di->rxdalloc = alloced;
-		ASSERT(IS_ALIGNED((unsigned long)di->rxd64, align));
-	}
-
-	return true;
-}
-
-static bool dma64_txreset(dma_info_t *di)
-{
-	u32 status;
-
-	if (di->ntxd == 0)
-		return true;
-
-	/* suspend tx DMA first */
-	W_REG(&di->d64txregs->control, D64_XC_SE);
-	SPINWAIT(((status =
-		   (R_REG(&di->d64txregs->status0) & D64_XS0_XS_MASK))
-		  != D64_XS0_XS_DISABLED) && (status != D64_XS0_XS_IDLE)
-		 && (status != D64_XS0_XS_STOPPED), 10000);
-
-	W_REG(&di->d64txregs->control, 0);
-	SPINWAIT(((status =
-		   (R_REG(&di->d64txregs->status0) & D64_XS0_XS_MASK))
-		  != D64_XS0_XS_DISABLED), 10000);
-
-	/* wait for the last transaction to complete */
-	udelay(300);
-
-	return status == D64_XS0_XS_DISABLED;
-}
-
-static bool dma64_rxidle(dma_info_t *di)
-{
-	DMA_TRACE(("%s: dma_rxidle\n", di->name));
-
-	if (di->nrxd == 0)
-		return true;
-
-	return ((R_REG(&di->d64rxregs->status0) & D64_RS0_CD_MASK) ==
-		(R_REG(&di->d64rxregs->ptr) & D64_RS0_CD_MASK));
-}
-
-static bool dma64_rxreset(dma_info_t *di)
-{
-	u32 status;
-
-	if (di->nrxd == 0)
-		return true;
-
-	W_REG(&di->d64rxregs->control, 0);
-	SPINWAIT(((status =
-		   (R_REG(&di->d64rxregs->status0) & D64_RS0_RS_MASK))
-		  != D64_RS0_RS_DISABLED), 10000);
-
-	return status == D64_RS0_RS_DISABLED;
-}
-
-static bool dma64_rxenabled(dma_info_t *di)
-{
-	u32 rc;
-
-	rc = R_REG(&di->d64rxregs->control);
-	return (rc != 0xffffffff) && (rc & D64_RC_RE);
-}
-
-static bool dma64_txsuspendedidle(dma_info_t *di)
-{
-
-	if (di->ntxd == 0)
-		return true;
-
-	if (!(R_REG(&di->d64txregs->control) & D64_XC_SE))
-		return 0;
-
-	if ((R_REG(&di->d64txregs->status0) & D64_XS0_XS_MASK) ==
-	    D64_XS0_XS_IDLE)
-		return 1;
-
-	return 0;
-}
-
-/* Useful when sending unframed data.  This allows us to get a progress report from the DMA.
- * We return a pointer to the beginning of the DATA buffer of the current descriptor.
- * If DMA is idle, we return NULL.
- */
-static void *dma64_getpos(dma_info_t *di, bool direction)
-{
-	void *va;
-	bool idle;
-	u32 cd_offset;
-
-	if (direction == DMA_TX) {
-		cd_offset =
-		    R_REG(&di->d64txregs->status0) & D64_XS0_CD_MASK;
-		idle = !NTXDACTIVE(di->txin, di->txout);
-		va = di->txp[B2I(cd_offset, dma64dd_t)];
-	} else {
-		cd_offset =
-		    R_REG(&di->d64rxregs->status0) & D64_XS0_CD_MASK;
-		idle = !NRXDACTIVE(di->rxin, di->rxout);
-		va = di->rxp[B2I(cd_offset, dma64dd_t)];
-	}
-
-	/* If DMA is IDLE, return NULL */
-	if (idle) {
-		DMA_TRACE(("%s: DMA idle, return NULL\n", __func__));
-		va = NULL;
-	}
-
-	return va;
-}
-
-/* TX of unframed data
- *
- * Adds a DMA ring descriptor for the data pointed to by "buf".
- * This is for DMA of a buffer of data and is unlike other hnddma TX functions
- * that take a pointer to a "packet"
- * Each call to this is results in a single descriptor being added for "len" bytes of
- * data starting at "buf", it doesn't handle chained buffers.
- */
-static int dma64_txunframed(dma_info_t *di, void *buf, uint len, bool commit)
-{
-	u16 txout;
-	u32 flags = 0;
-	dmaaddr_t pa;		/* phys addr */
-
-	txout = di->txout;
-
-	/* return nonzero if out of tx descriptors */
-	if (NEXTTXD(txout) == di->txin)
-		goto outoftxd;
-
-	if (len == 0)
-		return 0;
-
-	pa = pci_map_single(di->pbus, buf, len, PCI_DMA_TODEVICE);
-
-	flags = (D64_CTRL1_SOF | D64_CTRL1_IOC | D64_CTRL1_EOF);
-
-	if (txout == (di->ntxd - 1))
-		flags |= D64_CTRL1_EOT;
-
-	dma64_dd_upd(di, di->txd64, pa, txout, &flags, len);
-	ASSERT(di->txp[txout] == NULL);
-
-	/* save the buffer pointer - used by dma_getpos */
-	di->txp[txout] = buf;
-
-	txout = NEXTTXD(txout);
-	/* bump the tx descriptor index */
-	di->txout = txout;
-
-	/* kick the chip */
-	if (commit) {
-		W_REG(&di->d64txregs->ptr,
-		      di->xmtptrbase + I2B(txout, dma64dd_t));
-	}
-
-	/* tx flow control */
-	di->hnddma.txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1;
-
-	return 0;
-
- outoftxd:
-	DMA_ERROR(("%s: %s: out of txds !!!\n", di->name, __func__));
-	di->hnddma.txavail = 0;
-	di->hnddma.txnobuf++;
-	return -1;
-}
-
-/* !! tx entry routine
- * WARNING: call must check the return value for error.
- *   the error(toss frames) could be fatal and cause many subsequent hard to debug problems
- */
-static int BCMFASTPATH dma64_txfast(dma_info_t *di, struct sk_buff *p0,
-				    bool commit)
-{
-	struct sk_buff *p, *next;
-	unsigned char *data;
-	uint len;
-	u16 txout;
-	u32 flags = 0;
-	dmaaddr_t pa;
-
-	DMA_TRACE(("%s: dma_txfast\n", di->name));
-
-	txout = di->txout;
-
-	/*
-	 * Walk the chain of packet buffers
-	 * allocating and initializing transmit descriptor entries.
-	 */
-	for (p = p0; p; p = next) {
-		uint nsegs, j;
-		hnddma_seg_map_t *map;
-
-		data = p->data;
-		len = p->len;
-#ifdef BCM_DMAPAD
-		len += PKTDMAPAD(di->osh, p);
-#endif				/* BCM_DMAPAD */
-		next = p->next;
-
-		/* return nonzero if out of tx descriptors */
-		if (NEXTTXD(txout) == di->txin)
-			goto outoftxd;
-
-		if (len == 0)
-			continue;
-
-		/* get physical address of buffer start */
-		if (DMASGLIST_ENAB)
-			memset(&di->txp_dmah[txout], 0,
-				sizeof(hnddma_seg_map_t));
-
-		pa = pci_map_single(di->pbus, data, len, PCI_DMA_TODEVICE);
-
-		if (DMASGLIST_ENAB) {
-			map = &di->txp_dmah[txout];
-
-			/* See if all the segments can be accounted for */
-			if (map->nsegs >
-			    (uint) (di->ntxd - NTXDACTIVE(di->txin, di->txout) -
-				    1))
-				goto outoftxd;
-
-			nsegs = map->nsegs;
-		} else
-			nsegs = 1;
-
-		for (j = 1; j <= nsegs; j++) {
-			flags = 0;
-			if (p == p0 && j == 1)
-				flags |= D64_CTRL1_SOF;
-
-			/* With a DMA segment list, Descriptor table is filled
-			 * using the segment list instead of looping over
-			 * buffers in multi-chain DMA. Therefore, EOF for SGLIST is when
-			 * end of segment list is reached.
-			 */
-			if ((!DMASGLIST_ENAB && next == NULL) ||
-			    (DMASGLIST_ENAB && j == nsegs))
-				flags |= (D64_CTRL1_IOC | D64_CTRL1_EOF);
-			if (txout == (di->ntxd - 1))
-				flags |= D64_CTRL1_EOT;
-
-			if (DMASGLIST_ENAB) {
-				len = map->segs[j - 1].length;
-				pa = map->segs[j - 1].addr;
-			}
-			dma64_dd_upd(di, di->txd64, pa, txout, &flags, len);
-			ASSERT(di->txp[txout] == NULL);
-
-			txout = NEXTTXD(txout);
-		}
-
-		/* See above. No need to loop over individual buffers */
-		if (DMASGLIST_ENAB)
-			break;
-	}
-
-	/* if last txd eof not set, fix it */
-	if (!(flags & D64_CTRL1_EOF))
-		W_SM(&di->txd64[PREVTXD(txout)].ctrl1,
-		     BUS_SWAP32(flags | D64_CTRL1_IOC | D64_CTRL1_EOF));
-
-	/* save the packet */
-	di->txp[PREVTXD(txout)] = p0;
-
-	/* bump the tx descriptor index */
-	di->txout = txout;
-
-	/* kick the chip */
-	if (commit)
-		W_REG(&di->d64txregs->ptr,
-		      di->xmtptrbase + I2B(txout, dma64dd_t));
-
-	/* tx flow control */
-	di->hnddma.txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1;
-
-	return 0;
-
- outoftxd:
-	DMA_ERROR(("%s: dma_txfast: out of txds !!!\n", di->name));
-	pkt_buf_free_skb(p0);
-	di->hnddma.txavail = 0;
-	di->hnddma.txnobuf++;
-	return -1;
-}
-
-/*
- * Reclaim next completed txd (txds if using chained buffers) in the range
- * specified and return associated packet.
- * If range is HNDDMA_RANGE_TRANSMITTED, reclaim descriptors that have be
- * transmitted as noted by the hardware "CurrDescr" pointer.
- * If range is HNDDMA_RANGE_TRANSFERED, reclaim descriptors that have be
- * transferred by the DMA as noted by the hardware "ActiveDescr" pointer.
- * If range is HNDDMA_RANGE_ALL, reclaim all txd(s) posted to the ring and
- * return associated packet regardless of the value of hardware pointers.
- */
-static void *BCMFASTPATH dma64_getnexttxp(dma_info_t *di, txd_range_t range)
-{
-	u16 start, end, i;
-	u16 active_desc;
-	void *txp;
-
-	DMA_TRACE(("%s: dma_getnexttxp %s\n", di->name,
-		   (range == HNDDMA_RANGE_ALL) ? "all" :
-		   ((range ==
-		     HNDDMA_RANGE_TRANSMITTED) ? "transmitted" :
-		    "transferred")));
-
-	if (di->ntxd == 0)
-		return NULL;
-
-	txp = NULL;
-
-	start = di->txin;
-	if (range == HNDDMA_RANGE_ALL)
-		end = di->txout;
-	else {
-		dma64regs_t *dregs = di->d64txregs;
-
-		end =
-		    (u16) (B2I
-			      (((R_REG(&dregs->status0) &
-				 D64_XS0_CD_MASK) -
-				di->xmtptrbase) & D64_XS0_CD_MASK, dma64dd_t));
-
-		if (range == HNDDMA_RANGE_TRANSFERED) {
-			active_desc =
-			    (u16) (R_REG(&dregs->status1) &
-				      D64_XS1_AD_MASK);
-			active_desc =
-			    (active_desc - di->xmtptrbase) & D64_XS0_CD_MASK;
-			active_desc = B2I(active_desc, dma64dd_t);
-			if (end != active_desc)
-				end = PREVTXD(active_desc);
-		}
-	}
-
-	if ((start == 0) && (end > di->txout))
-		goto bogus;
-
-	for (i = start; i != end && !txp; i = NEXTTXD(i)) {
-		dmaaddr_t pa;
-		hnddma_seg_map_t *map = NULL;
-		uint size, j, nsegs;
-
-		PHYSADDRLOSET(pa,
-			      (BUS_SWAP32(R_SM(&di->txd64[i].addrlow)) -
-			       di->dataoffsetlow));
-		PHYSADDRHISET(pa,
-			      (BUS_SWAP32(R_SM(&di->txd64[i].addrhigh)) -
-			       di->dataoffsethigh));
-
-		if (DMASGLIST_ENAB) {
-			map = &di->txp_dmah[i];
-			size = map->origsize;
-			nsegs = map->nsegs;
-		} else {
-			size =
-			    (BUS_SWAP32(R_SM(&di->txd64[i].ctrl2)) &
-			     D64_CTRL2_BC_MASK);
-			nsegs = 1;
-		}
-
-		for (j = nsegs; j > 0; j--) {
-			W_SM(&di->txd64[i].addrlow, 0xdeadbeef);
-			W_SM(&di->txd64[i].addrhigh, 0xdeadbeef);
-
-			txp = di->txp[i];
-			di->txp[i] = NULL;
-			if (j > 1)
-				i = NEXTTXD(i);
-		}
-
-		pci_unmap_single(di->pbus, pa, size, PCI_DMA_TODEVICE);
-	}
-
-	di->txin = i;
-
-	/* tx flow control */
-	di->hnddma.txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1;
-
-	return txp;
-
- bogus:
-	DMA_NONE(("dma_getnexttxp: bogus curr: start %d end %d txout %d force %d\n", start, end, di->txout, forceall));
-	return NULL;
-}
-
-static void *BCMFASTPATH dma64_getnextrxp(dma_info_t *di, bool forceall)
-{
-	uint i, curr;
-	void *rxp;
-	dmaaddr_t pa;
-
-	/* if forcing, dma engine must be disabled */
-	ASSERT(!forceall || !dma64_rxenabled(di));
-
-	i = di->rxin;
-
-	/* return if no packets posted */
-	if (i == di->rxout)
-		return NULL;
-
-	curr =
-	    B2I(((R_REG(&di->d64rxregs->status0) & D64_RS0_CD_MASK) -
-		 di->rcvptrbase) & D64_RS0_CD_MASK, dma64dd_t);
-
-	/* ignore curr if forceall */
-	if (!forceall && (i == curr))
-		return NULL;
-
-	/* get the packet pointer that corresponds to the rx descriptor */
-	rxp = di->rxp[i];
-	ASSERT(rxp);
-	di->rxp[i] = NULL;
-
-	PHYSADDRLOSET(pa,
-		      (BUS_SWAP32(R_SM(&di->rxd64[i].addrlow)) -
-		       di->dataoffsetlow));
-	PHYSADDRHISET(pa,
-		      (BUS_SWAP32(R_SM(&di->rxd64[i].addrhigh)) -
-		       di->dataoffsethigh));
-
-	/* clear this packet from the descriptor ring */
-	pci_unmap_single(di->pbus, pa, di->rxbufsize, PCI_DMA_FROMDEVICE);
-
-	W_SM(&di->rxd64[i].addrlow, 0xdeadbeef);
-	W_SM(&di->rxd64[i].addrhigh, 0xdeadbeef);
-
-	di->rxin = NEXTRXD(i);
-
-	return rxp;
-}
-
-static bool _dma64_addrext(dma64regs_t *dma64regs)
-{
-	u32 w;
-	OR_REG(&dma64regs->control, D64_XC_AE);
-	w = R_REG(&dma64regs->control);
-	AND_REG(&dma64regs->control, ~D64_XC_AE);
-	return (w & D64_XC_AE) == D64_XC_AE;
-}
-
-/*
- * Rotate all active tx dma ring entries "forward" by (ActiveDescriptor - txin).
- */
-static void dma64_txrotate(dma_info_t *di)
-{
-	u16 ad;
-	uint nactive;
-	uint rot;
-	u16 old, new;
-	u32 w;
-	u16 first, last;
-
-	ASSERT(dma64_txsuspendedidle(di));
-
-	nactive = _dma_txactive(di);
-	ad = (u16) (B2I
-		       ((((R_REG(&di->d64txregs->status1) &
-			   D64_XS1_AD_MASK)
-			  - di->xmtptrbase) & D64_XS1_AD_MASK), dma64dd_t));
-	rot = TXD(ad - di->txin);
-
-	ASSERT(rot < di->ntxd);
-
-	/* full-ring case is a lot harder - don't worry about this */
-	if (rot >= (di->ntxd - nactive)) {
-		DMA_ERROR(("%s: dma_txrotate: ring full - punt\n", di->name));
-		return;
-	}
-
-	first = di->txin;
-	last = PREVTXD(di->txout);
-
-	/* move entries starting at last and moving backwards to first */
-	for (old = last; old != PREVTXD(first); old = PREVTXD(old)) {
-		new = TXD(old + rot);
-
-		/*
-		 * Move the tx dma descriptor.
-		 * EOT is set only in the last entry in the ring.
-		 */
-		w = BUS_SWAP32(R_SM(&di->txd64[old].ctrl1)) & ~D64_CTRL1_EOT;
-		if (new == (di->ntxd - 1))
-			w |= D64_CTRL1_EOT;
-		W_SM(&di->txd64[new].ctrl1, BUS_SWAP32(w));
-
-		w = BUS_SWAP32(R_SM(&di->txd64[old].ctrl2));
-		W_SM(&di->txd64[new].ctrl2, BUS_SWAP32(w));
-
-		W_SM(&di->txd64[new].addrlow, R_SM(&di->txd64[old].addrlow));
-		W_SM(&di->txd64[new].addrhigh, R_SM(&di->txd64[old].addrhigh));
-
-		/* zap the old tx dma descriptor address field */
-		W_SM(&di->txd64[old].addrlow, BUS_SWAP32(0xdeadbeef));
-		W_SM(&di->txd64[old].addrhigh, BUS_SWAP32(0xdeadbeef));
-
-		/* move the corresponding txp[] entry */
-		ASSERT(di->txp[new] == NULL);
-		di->txp[new] = di->txp[old];
-
-		/* Move the map */
-		if (DMASGLIST_ENAB) {
-			memcpy(&di->txp_dmah[new], &di->txp_dmah[old],
-			       sizeof(hnddma_seg_map_t));
-			memset(&di->txp_dmah[old], 0, sizeof(hnddma_seg_map_t));
-		}
-
-		di->txp[old] = NULL;
-	}
-
-	/* update txin and txout */
-	di->txin = ad;
-	di->txout = TXD(di->txout + rot);
-	di->hnddma.txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1;
-
-	/* kick the chip */
-	W_REG(&di->d64txregs->ptr,
-	      di->xmtptrbase + I2B(di->txout, dma64dd_t));
-}
-
-uint dma_addrwidth(si_t *sih, void *dmaregs)
-{
-	/* Perform 64-bit checks only if we want to advertise 64-bit (> 32bit) capability) */
-	/* DMA engine is 64-bit capable */
-	if ((si_core_sflags(sih, 0, 0) & SISF_DMA64) == SISF_DMA64) {
-		/* backplane are 64-bit capable */
-		if (si_backplane64(sih))
-			/* If bus is System Backplane or PCIE then we can access 64-bits */
-			if ((sih->bustype == SI_BUS) ||
-			    ((sih->bustype == PCI_BUS) &&
-			     (sih->buscoretype == PCIE_CORE_ID)))
-				return DMADDRWIDTH_64;
-	}
-	ASSERT(0); /* DMA hardware not supported by this driver*/
-	return DMADDRWIDTH_64;
-}
-
-/*
- * Mac80211 initiated actions sometimes require packets in the DMA queue to be
- * modified. The modified portion of the packet is not under control of the DMA
- * engine. This function calls a caller-supplied function for each packet in
- * the caller specified dma chain.
- */
-void dma_walk_packets(struct hnddma_pub *dmah, void (*callback_fnc)
-		      (void *pkt, void *arg_a), void *arg_a)
-{
-	dma_info_t *di = (dma_info_t *) dmah;
-	uint i =   di->txin;
-	uint end = di->txout;
-	struct sk_buff *skb;
-	struct ieee80211_tx_info *tx_info;
-
-	while (i != end) {
-		skb = (struct sk_buff *)di->txp[i];
-		if (skb != NULL) {
-			tx_info = (struct ieee80211_tx_info *)skb->cb;
-			(callback_fnc)(tx_info, arg_a);
-		}
-		i = NEXTTXD(i);
-	}
-}
diff -druN linux-2.6.39-libre/drivers/staging/brcm80211/util/hndpmu.c linux-3.0-rc7-libre/drivers/staging/brcm80211/util/hndpmu.c
--- linux-2.6.39-libre/drivers/staging/brcm80211/util/hndpmu.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/brcm80211/util/hndpmu.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,2675 +0,0 @@
-/*
- * Copyright (c) 2010 Broadcom Corporation
- *
- * 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/delay.h>
-#include <linux/kernel.h>
-#include <linux/string.h>
-#include <linux/module.h>
-#include <linux/pci.h>
-#include <bcmdefs.h>
-#include <bcmutils.h>
-#include <siutils.h>
-#include <bcmdevs.h>
-#include <hndsoc.h>
-#include <sbchipc.h>
-#include <hndpmu.h>
-#include "siutils_priv.h"
-
-#define	PMU_ERROR(args)
-
-#ifdef BCMDBG
-#define	PMU_MSG(args)	printk args
-
-/* debug-only definitions */
-/* #define BCMDBG_FORCEHT */
-/* #define CHIPC_UART_ALWAYS_ON */
-#else
-#define	PMU_MSG(args)
-#endif				/* BCMDBG */
-
-/* To check in verbose debugging messages not intended
- * to be on except on private builds.
- */
-#define	PMU_NONE(args)
-
-/* PLL controls/clocks */
-static void si_pmu1_pllinit0(si_t *sih, chipcregs_t *cc, u32 xtal);
-static u32 si_pmu1_cpuclk0(si_t *sih, chipcregs_t *cc);
-static u32 si_pmu1_alpclk0(si_t *sih, chipcregs_t *cc);
-
-/* PMU resources */
-static bool si_pmu_res_depfltr_bb(si_t *sih);
-static bool si_pmu_res_depfltr_ncb(si_t *sih);
-static bool si_pmu_res_depfltr_paldo(si_t *sih);
-static bool si_pmu_res_depfltr_npaldo(si_t *sih);
-static u32 si_pmu_res_deps(si_t *sih, chipcregs_t *cc, u32 rsrcs, bool all);
-static uint si_pmu_res_uptime(si_t *sih, chipcregs_t *cc, u8 rsrc);
-static void si_pmu_res_masks(si_t *sih, u32 * pmin, u32 * pmax);
-static void si_pmu_spuravoid_pllupdate(si_t *sih, chipcregs_t *cc,
-				       u8 spuravoid);
-
-static void si_pmu_set_4330_plldivs(si_t *sih);
-
-/* FVCO frequency */
-#define FVCO_880	880000	/* 880MHz */
-#define FVCO_1760	1760000	/* 1760MHz */
-#define FVCO_1440	1440000	/* 1440MHz */
-#define FVCO_960	960000	/* 960MHz */
-
-/* Read/write a chipcontrol reg */
-u32 si_pmu_chipcontrol(si_t *sih, uint reg, u32 mask, u32 val)
-{
-	si_corereg(sih, SI_CC_IDX, offsetof(chipcregs_t, chipcontrol_addr), ~0,
-		   reg);
-	return si_corereg(sih, SI_CC_IDX,
-			  offsetof(chipcregs_t, chipcontrol_data), mask, val);
-}
-
-/* Read/write a regcontrol reg */
-u32 si_pmu_regcontrol(si_t *sih, uint reg, u32 mask, u32 val)
-{
-	si_corereg(sih, SI_CC_IDX, offsetof(chipcregs_t, regcontrol_addr), ~0,
-		   reg);
-	return si_corereg(sih, SI_CC_IDX,
-			  offsetof(chipcregs_t, regcontrol_data), mask, val);
-}
-
-/* Read/write a pllcontrol reg */
-u32 si_pmu_pllcontrol(si_t *sih, uint reg, u32 mask, u32 val)
-{
-	si_corereg(sih, SI_CC_IDX, offsetof(chipcregs_t, pllcontrol_addr), ~0,
-		   reg);
-	return si_corereg(sih, SI_CC_IDX,
-			  offsetof(chipcregs_t, pllcontrol_data), mask, val);
-}
-
-/* PMU PLL update */
-void si_pmu_pllupd(si_t *sih)
-{
-	si_corereg(sih, SI_CC_IDX, offsetof(chipcregs_t, pmucontrol),
-		   PCTL_PLL_PLLCTL_UPD, PCTL_PLL_PLLCTL_UPD);
-}
-
-/* Setup switcher voltage */
-void si_pmu_set_switcher_voltage(si_t *sih, u8 bb_voltage, u8 rf_voltage)
-{
-	chipcregs_t *cc;
-	uint origidx;
-
-	ASSERT(sih->cccaps & CC_CAP_PMU);
-
-	/* Remember original core before switch to chipc */
-	origidx = si_coreidx(sih);
-	cc = si_setcoreidx(sih, SI_CC_IDX);
-	ASSERT(cc != NULL);
-
-	W_REG(&cc->regcontrol_addr, 0x01);
-	W_REG(&cc->regcontrol_data, (u32) (bb_voltage & 0x1f) << 22);
-
-	W_REG(&cc->regcontrol_addr, 0x00);
-	W_REG(&cc->regcontrol_data, (u32) (rf_voltage & 0x1f) << 14);
-
-	/* Return to original core */
-	si_setcoreidx(sih, origidx);
-}
-
-void si_pmu_set_ldo_voltage(si_t *sih, u8 ldo, u8 voltage)
-{
-	u8 sr_cntl_shift = 0, rc_shift = 0, shift = 0, mask = 0;
-	u8 addr = 0;
-
-	ASSERT(sih->cccaps & CC_CAP_PMU);
-
-	switch (sih->chip) {
-	case BCM4336_CHIP_ID:
-		switch (ldo) {
-		case SET_LDO_VOLTAGE_CLDO_PWM:
-			addr = 4;
-			rc_shift = 1;
-			mask = 0xf;
-			break;
-		case SET_LDO_VOLTAGE_CLDO_BURST:
-			addr = 4;
-			rc_shift = 5;
-			mask = 0xf;
-			break;
-		case SET_LDO_VOLTAGE_LNLDO1:
-			addr = 4;
-			rc_shift = 17;
-			mask = 0xf;
-			break;
-		default:
-			ASSERT(false);
-			return;
-		}
-		break;
-	case BCM4330_CHIP_ID:
-		switch (ldo) {
-		case SET_LDO_VOLTAGE_CBUCK_PWM:
-			addr = 3;
-			rc_shift = 0;
-			mask = 0x1f;
-			break;
-		default:
-			ASSERT(false);
-			break;
-		}
-		break;
-	default:
-		ASSERT(false);
-		return;
-	}
-
-	shift = sr_cntl_shift + rc_shift;
-
-	si_corereg(sih, SI_CC_IDX, offsetof(chipcregs_t, regcontrol_addr),
-		   ~0, addr);
-	si_corereg(sih, SI_CC_IDX, offsetof(chipcregs_t, regcontrol_data),
-		   mask << shift, (voltage & mask) << shift);
-}
-
-/* d11 slow to fast clock transition time in slow clock cycles */
-#define D11SCC_SLOW2FAST_TRANSITION	2
-
-u16 si_pmu_fast_pwrup_delay(si_t *sih)
-{
-	uint delay = PMU_MAX_TRANSITION_DLY;
-	chipcregs_t *cc;
-	uint origidx;
-#ifdef BCMDBG
-	char chn[8];
-	chn[0] = 0;		/* to suppress compile error */
-#endif
-
-	ASSERT(sih->cccaps & CC_CAP_PMU);
-
-	/* Remember original core before switch to chipc */
-	origidx = si_coreidx(sih);
-	cc = si_setcoreidx(sih, SI_CC_IDX);
-	ASSERT(cc != NULL);
-
-	switch (sih->chip) {
-	case BCM43224_CHIP_ID:
-	case BCM43225_CHIP_ID:
-	case BCM43421_CHIP_ID:
-	case BCM43235_CHIP_ID:
-	case BCM43236_CHIP_ID:
-	case BCM43238_CHIP_ID:
-	case BCM4331_CHIP_ID:
-	case BCM6362_CHIP_ID:
-	case BCM4313_CHIP_ID:
-		delay = ISSIM_ENAB(sih) ? 70 : 3700;
-		break;
-	case BCM4329_CHIP_ID:
-		if (ISSIM_ENAB(sih))
-			delay = 70;
-		else {
-			u32 ilp = si_ilp_clock(sih);
-			delay =
-			    (si_pmu_res_uptime(sih, cc, RES4329_HT_AVAIL) +
-			     D11SCC_SLOW2FAST_TRANSITION) * ((1000000 + ilp -
-							      1) / ilp);
-			delay = (11 * delay) / 10;
-		}
-		break;
-	case BCM4319_CHIP_ID:
-		delay = ISSIM_ENAB(sih) ? 70 : 3700;
-		break;
-	case BCM4336_CHIP_ID:
-		if (ISSIM_ENAB(sih))
-			delay = 70;
-		else {
-			u32 ilp = si_ilp_clock(sih);
-			delay =
-			    (si_pmu_res_uptime(sih, cc, RES4336_HT_AVAIL) +
-			     D11SCC_SLOW2FAST_TRANSITION) * ((1000000 + ilp -
-							      1) / ilp);
-			delay = (11 * delay) / 10;
-		}
-		break;
-	case BCM4330_CHIP_ID:
-		if (ISSIM_ENAB(sih))
-			delay = 70;
-		else {
-			u32 ilp = si_ilp_clock(sih);
-			delay =
-			    (si_pmu_res_uptime(sih, cc, RES4330_HT_AVAIL) +
-			     D11SCC_SLOW2FAST_TRANSITION) * ((1000000 + ilp -
-							      1) / ilp);
-			delay = (11 * delay) / 10;
-		}
-		break;
-	default:
-		break;
-	}
-	/* Return to original core */
-	si_setcoreidx(sih, origidx);
-
-	return (u16) delay;
-}
-
-u32 si_pmu_force_ilp(si_t *sih, bool force)
-{
-	chipcregs_t *cc;
-	uint origidx;
-	u32 oldpmucontrol;
-
-	ASSERT(sih->cccaps & CC_CAP_PMU);
-
-	/* Remember original core before switch to chipc */
-	origidx = si_coreidx(sih);
-	cc = si_setcoreidx(sih, SI_CC_IDX);
-	ASSERT(cc != NULL);
-
-	oldpmucontrol = R_REG(&cc->pmucontrol);
-	if (force)
-		W_REG(&cc->pmucontrol, oldpmucontrol &
-		      ~(PCTL_HT_REQ_EN | PCTL_ALP_REQ_EN));
-	else
-		W_REG(&cc->pmucontrol, oldpmucontrol |
-		      (PCTL_HT_REQ_EN | PCTL_ALP_REQ_EN));
-
-	/* Return to original core */
-	si_setcoreidx(sih, origidx);
-
-	return oldpmucontrol;
-}
-
-/* Setup resource up/down timers */
-typedef struct {
-	u8 resnum;
-	u16 updown;
-} pmu_res_updown_t;
-
-/* Change resource dependancies masks */
-typedef struct {
-	u32 res_mask;	/* resources (chip specific) */
-	s8 action;		/* action */
-	u32 depend_mask;	/* changes to the dependancies mask */
-	 bool(*filter) (si_t *sih);	/* action is taken when filter is NULL or return true */
-} pmu_res_depend_t;
-
-/* Resource dependancies mask change action */
-#define RES_DEPEND_SET		0	/* Override the dependancies mask */
-#define RES_DEPEND_ADD		1	/* Add to the  dependancies mask */
-#define RES_DEPEND_REMOVE	-1	/* Remove from the dependancies mask */
-
-static const pmu_res_updown_t bcm4328a0_res_updown[] = {
-	{
-	RES4328_EXT_SWITCHER_PWM, 0x0101}, {
-	RES4328_BB_SWITCHER_PWM, 0x1f01}, {
-	RES4328_BB_SWITCHER_BURST, 0x010f}, {
-	RES4328_BB_EXT_SWITCHER_BURST, 0x0101}, {
-	RES4328_ILP_REQUEST, 0x0202}, {
-	RES4328_RADIO_SWITCHER_PWM, 0x0f01}, {
-	RES4328_RADIO_SWITCHER_BURST, 0x0f01}, {
-	RES4328_ROM_SWITCH, 0x0101}, {
-	RES4328_PA_REF_LDO, 0x0f01}, {
-	RES4328_RADIO_LDO, 0x0f01}, {
-	RES4328_AFE_LDO, 0x0f01}, {
-	RES4328_PLL_LDO, 0x0f01}, {
-	RES4328_BG_FILTBYP, 0x0101}, {
-	RES4328_TX_FILTBYP, 0x0101}, {
-	RES4328_RX_FILTBYP, 0x0101}, {
-	RES4328_XTAL_PU, 0x0101}, {
-	RES4328_XTAL_EN, 0xa001}, {
-	RES4328_BB_PLL_FILTBYP, 0x0101}, {
-	RES4328_RF_PLL_FILTBYP, 0x0101}, {
-	RES4328_BB_PLL_PU, 0x0701}
-};
-
-static const pmu_res_depend_t bcm4328a0_res_depend[] = {
-	/* Adjust ILP request resource not to force ext/BB switchers into burst mode */
-	{
-	PMURES_BIT(RES4328_ILP_REQUEST),
-		    RES_DEPEND_SET,
-		    PMURES_BIT(RES4328_EXT_SWITCHER_PWM) |
-		    PMURES_BIT(RES4328_BB_SWITCHER_PWM), NULL}
-};
-
-static const pmu_res_updown_t bcm4325a0_res_updown_qt[] = {
-	{
-	RES4325_HT_AVAIL, 0x0300}, {
-	RES4325_BBPLL_PWRSW_PU, 0x0101}, {
-	RES4325_RFPLL_PWRSW_PU, 0x0101}, {
-	RES4325_ALP_AVAIL, 0x0100}, {
-	RES4325_XTAL_PU, 0x1000}, {
-	RES4325_LNLDO1_PU, 0x0800}, {
-	RES4325_CLDO_CBUCK_PWM, 0x0101}, {
-	RES4325_CBUCK_PWM, 0x0803}
-};
-
-static const pmu_res_updown_t bcm4325a0_res_updown[] = {
-	{
-	RES4325_XTAL_PU, 0x1501}
-};
-
-static const pmu_res_depend_t bcm4325a0_res_depend[] = {
-	/* Adjust OTP PU resource dependencies - remove BB BURST */
-	{
-	PMURES_BIT(RES4325_OTP_PU),
-		    RES_DEPEND_REMOVE,
-		    PMURES_BIT(RES4325_BUCK_BOOST_BURST), NULL},
-	    /* Adjust ALP/HT Avail resource dependencies - bring up BB along if it is used. */
-	{
-	PMURES_BIT(RES4325_ALP_AVAIL) | PMURES_BIT(RES4325_HT_AVAIL),
-		    RES_DEPEND_ADD,
-		    PMURES_BIT(RES4325_BUCK_BOOST_BURST) |
-		    PMURES_BIT(RES4325_BUCK_BOOST_PWM), si_pmu_res_depfltr_bb},
-	    /* Adjust HT Avail resource dependencies - bring up RF switches along with HT. */
-	{
-	PMURES_BIT(RES4325_HT_AVAIL),
-		    RES_DEPEND_ADD,
-		    PMURES_BIT(RES4325_RX_PWRSW_PU) |
-		    PMURES_BIT(RES4325_TX_PWRSW_PU) |
-		    PMURES_BIT(RES4325_LOGEN_PWRSW_PU) |
-		    PMURES_BIT(RES4325_AFE_PWRSW_PU), NULL},
-	    /* Adjust ALL resource dependencies - remove CBUCK dependancies if it is not used. */
-	{
-	PMURES_BIT(RES4325_ILP_REQUEST) |
-		    PMURES_BIT(RES4325_ABUCK_BURST) |
-		    PMURES_BIT(RES4325_ABUCK_PWM) |
-		    PMURES_BIT(RES4325_LNLDO1_PU) |
-		    PMURES_BIT(RES4325C1_LNLDO2_PU) |
-		    PMURES_BIT(RES4325_XTAL_PU) |
-		    PMURES_BIT(RES4325_ALP_AVAIL) |
-		    PMURES_BIT(RES4325_RX_PWRSW_PU) |
-		    PMURES_BIT(RES4325_TX_PWRSW_PU) |
-		    PMURES_BIT(RES4325_RFPLL_PWRSW_PU) |
-		    PMURES_BIT(RES4325_LOGEN_PWRSW_PU) |
-		    PMURES_BIT(RES4325_AFE_PWRSW_PU) |
-		    PMURES_BIT(RES4325_BBPLL_PWRSW_PU) |
-		    PMURES_BIT(RES4325_HT_AVAIL), RES_DEPEND_REMOVE,
-		    PMURES_BIT(RES4325B0_CBUCK_LPOM) |
-		    PMURES_BIT(RES4325B0_CBUCK_BURST) |
-		    PMURES_BIT(RES4325B0_CBUCK_PWM), si_pmu_res_depfltr_ncb}
-};
-
-static const pmu_res_updown_t bcm4315a0_res_updown_qt[] = {
-	{
-	RES4315_HT_AVAIL, 0x0101}, {
-	RES4315_XTAL_PU, 0x0100}, {
-	RES4315_LNLDO1_PU, 0x0100}, {
-	RES4315_PALDO_PU, 0x0100}, {
-	RES4315_CLDO_PU, 0x0100}, {
-	RES4315_CBUCK_PWM, 0x0100}, {
-	RES4315_CBUCK_BURST, 0x0100}, {
-	RES4315_CBUCK_LPOM, 0x0100}
-};
-
-static const pmu_res_updown_t bcm4315a0_res_updown[] = {
-	{
-	RES4315_XTAL_PU, 0x2501}
-};
-
-static const pmu_res_depend_t bcm4315a0_res_depend[] = {
-	/* Adjust OTP PU resource dependencies - not need PALDO unless write */
-	{
-	PMURES_BIT(RES4315_OTP_PU),
-		    RES_DEPEND_REMOVE,
-		    PMURES_BIT(RES4315_PALDO_PU), si_pmu_res_depfltr_npaldo},
-	    /* Adjust ALP/HT Avail resource dependencies - bring up PALDO along if it is used. */
-	{
-	PMURES_BIT(RES4315_ALP_AVAIL) | PMURES_BIT(RES4315_HT_AVAIL),
-		    RES_DEPEND_ADD,
-		    PMURES_BIT(RES4315_PALDO_PU), si_pmu_res_depfltr_paldo},
-	    /* Adjust HT Avail resource dependencies - bring up RF switches along with HT. */
-	{
-	PMURES_BIT(RES4315_HT_AVAIL),
-		    RES_DEPEND_ADD,
-		    PMURES_BIT(RES4315_RX_PWRSW_PU) |
-		    PMURES_BIT(RES4315_TX_PWRSW_PU) |
-		    PMURES_BIT(RES4315_LOGEN_PWRSW_PU) |
-		    PMURES_BIT(RES4315_AFE_PWRSW_PU), NULL},
-	    /* Adjust ALL resource dependencies - remove CBUCK dependancies if it is not used. */
-	{
-	PMURES_BIT(RES4315_CLDO_PU) | PMURES_BIT(RES4315_ILP_REQUEST) |
-		    PMURES_BIT(RES4315_LNLDO1_PU) |
-		    PMURES_BIT(RES4315_OTP_PU) |
-		    PMURES_BIT(RES4315_LNLDO2_PU) |
-		    PMURES_BIT(RES4315_XTAL_PU) |
-		    PMURES_BIT(RES4315_ALP_AVAIL) |
-		    PMURES_BIT(RES4315_RX_PWRSW_PU) |
-		    PMURES_BIT(RES4315_TX_PWRSW_PU) |
-		    PMURES_BIT(RES4315_RFPLL_PWRSW_PU) |
-		    PMURES_BIT(RES4315_LOGEN_PWRSW_PU) |
-		    PMURES_BIT(RES4315_AFE_PWRSW_PU) |
-		    PMURES_BIT(RES4315_BBPLL_PWRSW_PU) |
-		    PMURES_BIT(RES4315_HT_AVAIL), RES_DEPEND_REMOVE,
-		    PMURES_BIT(RES4315_CBUCK_LPOM) |
-		    PMURES_BIT(RES4315_CBUCK_BURST) |
-		    PMURES_BIT(RES4315_CBUCK_PWM), si_pmu_res_depfltr_ncb}
-};
-
-	/* 4329 specific. needs to come back this issue later */
-static const pmu_res_updown_t bcm4329_res_updown[] = {
-	{
-	RES4329_XTAL_PU, 0x1501}
-};
-
-static const pmu_res_depend_t bcm4329_res_depend[] = {
-	/* Adjust HT Avail resource dependencies */
-	{
-	PMURES_BIT(RES4329_HT_AVAIL),
-		    RES_DEPEND_ADD,
-		    PMURES_BIT(RES4329_CBUCK_LPOM) |
-		    PMURES_BIT(RES4329_CBUCK_BURST) |
-		    PMURES_BIT(RES4329_CBUCK_PWM) |
-		    PMURES_BIT(RES4329_CLDO_PU) |
-		    PMURES_BIT(RES4329_PALDO_PU) |
-		    PMURES_BIT(RES4329_LNLDO1_PU) |
-		    PMURES_BIT(RES4329_XTAL_PU) |
-		    PMURES_BIT(RES4329_ALP_AVAIL) |
-		    PMURES_BIT(RES4329_RX_PWRSW_PU) |
-		    PMURES_BIT(RES4329_TX_PWRSW_PU) |
-		    PMURES_BIT(RES4329_RFPLL_PWRSW_PU) |
-		    PMURES_BIT(RES4329_LOGEN_PWRSW_PU) |
-		    PMURES_BIT(RES4329_AFE_PWRSW_PU) |
-		    PMURES_BIT(RES4329_BBPLL_PWRSW_PU), NULL}
-};
-
-static const pmu_res_updown_t bcm4319a0_res_updown_qt[] = {
-	{
-	RES4319_HT_AVAIL, 0x0101}, {
-	RES4319_XTAL_PU, 0x0100}, {
-	RES4319_LNLDO1_PU, 0x0100}, {
-	RES4319_PALDO_PU, 0x0100}, {
-	RES4319_CLDO_PU, 0x0100}, {
-	RES4319_CBUCK_PWM, 0x0100}, {
-	RES4319_CBUCK_BURST, 0x0100}, {
-	RES4319_CBUCK_LPOM, 0x0100}
-};
-
-static const pmu_res_updown_t bcm4319a0_res_updown[] = {
-	{
-	RES4319_XTAL_PU, 0x3f01}
-};
-
-static const pmu_res_depend_t bcm4319a0_res_depend[] = {
-	/* Adjust OTP PU resource dependencies - not need PALDO unless write */
-	{
-	PMURES_BIT(RES4319_OTP_PU),
-		    RES_DEPEND_REMOVE,
-		    PMURES_BIT(RES4319_PALDO_PU), si_pmu_res_depfltr_npaldo},
-	    /* Adjust HT Avail resource dependencies - bring up PALDO along if it is used. */
-	{
-	PMURES_BIT(RES4319_HT_AVAIL),
-		    RES_DEPEND_ADD,
-		    PMURES_BIT(RES4319_PALDO_PU), si_pmu_res_depfltr_paldo},
-	    /* Adjust HT Avail resource dependencies - bring up RF switches along with HT. */
-	{
-	PMURES_BIT(RES4319_HT_AVAIL),
-		    RES_DEPEND_ADD,
-		    PMURES_BIT(RES4319_RX_PWRSW_PU) |
-		    PMURES_BIT(RES4319_TX_PWRSW_PU) |
-		    PMURES_BIT(RES4319_RFPLL_PWRSW_PU) |
-		    PMURES_BIT(RES4319_LOGEN_PWRSW_PU) |
-		    PMURES_BIT(RES4319_AFE_PWRSW_PU), NULL}
-};
-
-static const pmu_res_updown_t bcm4336a0_res_updown_qt[] = {
-	{
-	RES4336_HT_AVAIL, 0x0101}, {
-	RES4336_XTAL_PU, 0x0100}, {
-	RES4336_CLDO_PU, 0x0100}, {
-	RES4336_CBUCK_PWM, 0x0100}, {
-	RES4336_CBUCK_BURST, 0x0100}, {
-	RES4336_CBUCK_LPOM, 0x0100}
-};
-
-static const pmu_res_updown_t bcm4336a0_res_updown[] = {
-	{
-	RES4336_HT_AVAIL, 0x0D01}
-};
-
-static const pmu_res_depend_t bcm4336a0_res_depend[] = {
-	/* Just a dummy entry for now */
-	{
-	PMURES_BIT(RES4336_RSVD), RES_DEPEND_ADD, 0, NULL}
-};
-
-static const pmu_res_updown_t bcm4330a0_res_updown_qt[] = {
-	{
-	RES4330_HT_AVAIL, 0x0101}, {
-	RES4330_XTAL_PU, 0x0100}, {
-	RES4330_CLDO_PU, 0x0100}, {
-	RES4330_CBUCK_PWM, 0x0100}, {
-	RES4330_CBUCK_BURST, 0x0100}, {
-	RES4330_CBUCK_LPOM, 0x0100}
-};
-
-static const pmu_res_updown_t bcm4330a0_res_updown[] = {
-	{
-	RES4330_HT_AVAIL, 0x0e02}
-};
-
-static const pmu_res_depend_t bcm4330a0_res_depend[] = {
-	/* Just a dummy entry for now */
-	{
-	PMURES_BIT(RES4330_HT_AVAIL), RES_DEPEND_ADD, 0, NULL}
-};
-
-/* true if the power topology uses the buck boost to provide 3.3V to VDDIO_RF and WLAN PA */
-static bool si_pmu_res_depfltr_bb(si_t *sih)
-{
-	return (sih->boardflags & BFL_BUCKBOOST) != 0;
-}
-
-/* true if the power topology doesn't use the cbuck. Key on chiprev also if the chip is BCM4325. */
-static bool si_pmu_res_depfltr_ncb(si_t *sih)
-{
-
-	return (sih->boardflags & BFL_NOCBUCK) != 0;
-}
-
-/* true if the power topology uses the PALDO */
-static bool si_pmu_res_depfltr_paldo(si_t *sih)
-{
-	return (sih->boardflags & BFL_PALDO) != 0;
-}
-
-/* true if the power topology doesn't use the PALDO */
-static bool si_pmu_res_depfltr_npaldo(si_t *sih)
-{
-	return (sih->boardflags & BFL_PALDO) == 0;
-}
-
-#define BCM94325_BBVDDIOSD_BOARDS(sih) (sih->boardtype == BCM94325DEVBU_BOARD || \
-					sih->boardtype == BCM94325BGABU_BOARD)
-
-/* Determine min/max rsrc masks. Value 0 leaves hardware at default. */
-static void si_pmu_res_masks(si_t *sih, u32 * pmin, u32 * pmax)
-{
-	u32 min_mask = 0, max_mask = 0;
-	uint rsrcs;
-	char *val;
-
-	/* # resources */
-	rsrcs = (sih->pmucaps & PCAP_RC_MASK) >> PCAP_RC_SHIFT;
-
-	/* determine min/max rsrc masks */
-	switch (sih->chip) {
-	case BCM43224_CHIP_ID:
-	case BCM43225_CHIP_ID:
-	case BCM43421_CHIP_ID:
-	case BCM43235_CHIP_ID:
-	case BCM43236_CHIP_ID:
-	case BCM43238_CHIP_ID:
-	case BCM4331_CHIP_ID:
-	case BCM6362_CHIP_ID:
-		/* ??? */
-		break;
-
-	case BCM4329_CHIP_ID:
-		/* 4329 spedific issue. Needs to come back this issue later */
-		/* Down to save the power. */
-		min_mask =
-		    PMURES_BIT(RES4329_CBUCK_LPOM) |
-		    PMURES_BIT(RES4329_CLDO_PU);
-		/* Allow (but don't require) PLL to turn on */
-		max_mask = 0x3ff63e;
-		break;
-	case BCM4319_CHIP_ID:
-		/* We only need a few resources to be kept on all the time */
-		min_mask = PMURES_BIT(RES4319_CBUCK_LPOM) |
-		    PMURES_BIT(RES4319_CLDO_PU);
-
-		/* Allow everything else to be turned on upon requests */
-		max_mask = ~(~0 << rsrcs);
-		break;
-	case BCM4336_CHIP_ID:
-		/* Down to save the power. */
-		min_mask =
-		    PMURES_BIT(RES4336_CBUCK_LPOM) | PMURES_BIT(RES4336_CLDO_PU)
-		    | PMURES_BIT(RES4336_LDO3P3_PU) | PMURES_BIT(RES4336_OTP_PU)
-		    | PMURES_BIT(RES4336_DIS_INT_RESET_PD);
-		/* Allow (but don't require) PLL to turn on */
-		max_mask = 0x1ffffff;
-		break;
-
-	case BCM4330_CHIP_ID:
-		/* Down to save the power. */
-		min_mask =
-		    PMURES_BIT(RES4330_CBUCK_LPOM) | PMURES_BIT(RES4330_CLDO_PU)
-		    | PMURES_BIT(RES4330_DIS_INT_RESET_PD) |
-		    PMURES_BIT(RES4330_LDO3P3_PU) | PMURES_BIT(RES4330_OTP_PU);
-		/* Allow (but don't require) PLL to turn on */
-		max_mask = 0xfffffff;
-		break;
-
-	case BCM4313_CHIP_ID:
-		min_mask = PMURES_BIT(RES4313_BB_PU_RSRC) |
-		    PMURES_BIT(RES4313_XTAL_PU_RSRC) |
-		    PMURES_BIT(RES4313_ALP_AVAIL_RSRC) |
-		    PMURES_BIT(RES4313_BB_PLL_PWRSW_RSRC);
-		max_mask = 0xffff;
-		break;
-	default:
-		break;
-	}
-
-	/* Apply nvram override to min mask */
-	val = getvar(NULL, "rmin");
-	if (val != NULL) {
-		PMU_MSG(("Applying rmin=%s to min_mask\n", val));
-		min_mask = (u32) simple_strtoul(val, NULL, 0);
-	}
-	/* Apply nvram override to max mask */
-	val = getvar(NULL, "rmax");
-	if (val != NULL) {
-		PMU_MSG(("Applying rmax=%s to max_mask\n", val));
-		max_mask = (u32) simple_strtoul(val, NULL, 0);
-	}
-
-	*pmin = min_mask;
-	*pmax = max_mask;
-}
-
-/* initialize PMU resources */
-void si_pmu_res_init(si_t *sih)
-{
-	chipcregs_t *cc;
-	uint origidx;
-	const pmu_res_updown_t *pmu_res_updown_table = NULL;
-	uint pmu_res_updown_table_sz = 0;
-	const pmu_res_depend_t *pmu_res_depend_table = NULL;
-	uint pmu_res_depend_table_sz = 0;
-	u32 min_mask = 0, max_mask = 0;
-	char name[8], *val;
-	uint i, rsrcs;
-
-	ASSERT(sih->cccaps & CC_CAP_PMU);
-
-	/* Remember original core before switch to chipc */
-	origidx = si_coreidx(sih);
-	cc = si_setcoreidx(sih, SI_CC_IDX);
-	ASSERT(cc != NULL);
-
-	switch (sih->chip) {
-	case BCM4329_CHIP_ID:
-		/* Optimize resources up/down timers */
-		if (ISSIM_ENAB(sih)) {
-			pmu_res_updown_table = NULL;
-			pmu_res_updown_table_sz = 0;
-		} else {
-			pmu_res_updown_table = bcm4329_res_updown;
-			pmu_res_updown_table_sz = ARRAY_SIZE(bcm4329_res_updown);
-		}
-		/* Optimize resources dependencies */
-		pmu_res_depend_table = bcm4329_res_depend;
-		pmu_res_depend_table_sz = ARRAY_SIZE(bcm4329_res_depend);
-		break;
-
-	case BCM4319_CHIP_ID:
-		/* Optimize resources up/down timers */
-		if (ISSIM_ENAB(sih)) {
-			pmu_res_updown_table = bcm4319a0_res_updown_qt;
-			pmu_res_updown_table_sz =
-			    ARRAY_SIZE(bcm4319a0_res_updown_qt);
-		} else {
-			pmu_res_updown_table = bcm4319a0_res_updown;
-			pmu_res_updown_table_sz =
-			    ARRAY_SIZE(bcm4319a0_res_updown);
-		}
-		/* Optimize resources dependancies masks */
-		pmu_res_depend_table = bcm4319a0_res_depend;
-		pmu_res_depend_table_sz = ARRAY_SIZE(bcm4319a0_res_depend);
-		break;
-
-	case BCM4336_CHIP_ID:
-		/* Optimize resources up/down timers */
-		if (ISSIM_ENAB(sih)) {
-			pmu_res_updown_table = bcm4336a0_res_updown_qt;
-			pmu_res_updown_table_sz =
-			    ARRAY_SIZE(bcm4336a0_res_updown_qt);
-		} else {
-			pmu_res_updown_table = bcm4336a0_res_updown;
-			pmu_res_updown_table_sz =
-			    ARRAY_SIZE(bcm4336a0_res_updown);
-		}
-		/* Optimize resources dependancies masks */
-		pmu_res_depend_table = bcm4336a0_res_depend;
-		pmu_res_depend_table_sz = ARRAY_SIZE(bcm4336a0_res_depend);
-		break;
-
-	case BCM4330_CHIP_ID:
-		/* Optimize resources up/down timers */
-		if (ISSIM_ENAB(sih)) {
-			pmu_res_updown_table = bcm4330a0_res_updown_qt;
-			pmu_res_updown_table_sz =
-			    ARRAY_SIZE(bcm4330a0_res_updown_qt);
-		} else {
-			pmu_res_updown_table = bcm4330a0_res_updown;
-			pmu_res_updown_table_sz =
-			    ARRAY_SIZE(bcm4330a0_res_updown);
-		}
-		/* Optimize resources dependancies masks */
-		pmu_res_depend_table = bcm4330a0_res_depend;
-		pmu_res_depend_table_sz = ARRAY_SIZE(bcm4330a0_res_depend);
-		break;
-
-	default:
-		break;
-	}
-
-	/* # resources */
-	rsrcs = (sih->pmucaps & PCAP_RC_MASK) >> PCAP_RC_SHIFT;
-
-	/* Program up/down timers */
-	while (pmu_res_updown_table_sz--) {
-		ASSERT(pmu_res_updown_table != NULL);
-		PMU_MSG(("Changing rsrc %d res_updn_timer to 0x%x\n",
-			 pmu_res_updown_table[pmu_res_updown_table_sz].resnum,
-			 pmu_res_updown_table[pmu_res_updown_table_sz].updown));
-		W_REG(&cc->res_table_sel,
-		      pmu_res_updown_table[pmu_res_updown_table_sz].resnum);
-		W_REG(&cc->res_updn_timer,
-		      pmu_res_updown_table[pmu_res_updown_table_sz].updown);
-	}
-	/* Apply nvram overrides to up/down timers */
-	for (i = 0; i < rsrcs; i++) {
-		snprintf(name, sizeof(name), "r%dt", i);
-		val = getvar(NULL, name);
-		if (val == NULL)
-			continue;
-		PMU_MSG(("Applying %s=%s to rsrc %d res_updn_timer\n", name,
-			 val, i));
-		W_REG(&cc->res_table_sel, (u32) i);
-		W_REG(&cc->res_updn_timer,
-		      (u32) simple_strtoul(val, NULL, 0));
-	}
-
-	/* Program resource dependencies table */
-	while (pmu_res_depend_table_sz--) {
-		ASSERT(pmu_res_depend_table != NULL);
-		if (pmu_res_depend_table[pmu_res_depend_table_sz].filter != NULL
-		    && !(pmu_res_depend_table[pmu_res_depend_table_sz].
-			 filter) (sih))
-			continue;
-		for (i = 0; i < rsrcs; i++) {
-			if ((pmu_res_depend_table[pmu_res_depend_table_sz].
-			     res_mask & PMURES_BIT(i)) == 0)
-				continue;
-			W_REG(&cc->res_table_sel, i);
-			switch (pmu_res_depend_table[pmu_res_depend_table_sz].
-				action) {
-			case RES_DEPEND_SET:
-				PMU_MSG(("Changing rsrc %d res_dep_mask to 0x%x\n", i, pmu_res_depend_table[pmu_res_depend_table_sz].depend_mask));
-				W_REG(&cc->res_dep_mask,
-				      pmu_res_depend_table
-				      [pmu_res_depend_table_sz].depend_mask);
-				break;
-			case RES_DEPEND_ADD:
-				PMU_MSG(("Adding 0x%x to rsrc %d res_dep_mask\n", pmu_res_depend_table[pmu_res_depend_table_sz].depend_mask, i));
-				OR_REG(&cc->res_dep_mask,
-				       pmu_res_depend_table
-				       [pmu_res_depend_table_sz].depend_mask);
-				break;
-			case RES_DEPEND_REMOVE:
-				PMU_MSG(("Removing 0x%x from rsrc %d res_dep_mask\n", pmu_res_depend_table[pmu_res_depend_table_sz].depend_mask, i));
-				AND_REG(&cc->res_dep_mask,
-					~pmu_res_depend_table
-					[pmu_res_depend_table_sz].depend_mask);
-				break;
-			default:
-				ASSERT(0);
-				break;
-			}
-		}
-	}
-	/* Apply nvram overrides to dependancies masks */
-	for (i = 0; i < rsrcs; i++) {
-		snprintf(name, sizeof(name), "r%dd", i);
-		val = getvar(NULL, name);
-		if (val == NULL)
-			continue;
-		PMU_MSG(("Applying %s=%s to rsrc %d res_dep_mask\n", name, val,
-			 i));
-		W_REG(&cc->res_table_sel, (u32) i);
-		W_REG(&cc->res_dep_mask,
-		      (u32) simple_strtoul(val, NULL, 0));
-	}
-
-	/* Determine min/max rsrc masks */
-	si_pmu_res_masks(sih, &min_mask, &max_mask);
-
-	/* It is required to program max_mask first and then min_mask */
-
-	/* Program max resource mask */
-
-	if (max_mask) {
-		PMU_MSG(("Changing max_res_mask to 0x%x\n", max_mask));
-		W_REG(&cc->max_res_mask, max_mask);
-	}
-
-	/* Program min resource mask */
-
-	if (min_mask) {
-		PMU_MSG(("Changing min_res_mask to 0x%x\n", min_mask));
-		W_REG(&cc->min_res_mask, min_mask);
-	}
-
-	/* Add some delay; allow resources to come up and settle. */
-	mdelay(2);
-
-	/* Return to original core */
-	si_setcoreidx(sih, origidx);
-}
-
-/* setup pll and query clock speed */
-typedef struct {
-	u16 freq;
-	u8 xf;
-	u8 wbint;
-	u32 wbfrac;
-} pmu0_xtaltab0_t;
-
-/* the following table is based on 880Mhz fvco */
-static const pmu0_xtaltab0_t pmu0_xtaltab0[] = {
-	{
-	12000, 1, 73, 349525}, {
-	13000, 2, 67, 725937}, {
-	14400, 3, 61, 116508}, {
-	15360, 4, 57, 305834}, {
-	16200, 5, 54, 336579}, {
-	16800, 6, 52, 399457}, {
-	19200, 7, 45, 873813}, {
-	19800, 8, 44, 466033}, {
-	20000, 9, 44, 0}, {
-	25000, 10, 70, 419430}, {
-	26000, 11, 67, 725937}, {
-	30000, 12, 58, 699050}, {
-	38400, 13, 45, 873813}, {
-	40000, 14, 45, 0}, {
-	0, 0, 0, 0}
-};
-
-#define PMU0_XTAL0_DEFAULT	8
-
-/* setup pll and query clock speed */
-typedef struct {
-	u16 fref;
-	u8 xf;
-	u8 p1div;
-	u8 p2div;
-	u8 ndiv_int;
-	u32 ndiv_frac;
-} pmu1_xtaltab0_t;
-
-static const pmu1_xtaltab0_t pmu1_xtaltab0_880_4329[] = {
-	{
-	12000, 1, 3, 22, 0x9, 0xFFFFEF}, {
-	13000, 2, 1, 6, 0xb, 0x483483}, {
-	14400, 3, 1, 10, 0xa, 0x1C71C7}, {
-	15360, 4, 1, 5, 0xb, 0x755555}, {
-	16200, 5, 1, 10, 0x5, 0x6E9E06}, {
-	16800, 6, 1, 10, 0x5, 0x3Cf3Cf}, {
-	19200, 7, 1, 4, 0xb, 0x755555}, {
-	19800, 8, 1, 11, 0x4, 0xA57EB}, {
-	20000, 9, 1, 11, 0x4, 0x0}, {
-	24000, 10, 3, 11, 0xa, 0x0}, {
-	25000, 11, 5, 16, 0xb, 0x0}, {
-	26000, 12, 1, 1, 0x21, 0xD89D89}, {
-	30000, 13, 3, 8, 0xb, 0x0}, {
-	37400, 14, 3, 1, 0x46, 0x969696}, {
-	38400, 15, 1, 1, 0x16, 0xEAAAAA}, {
-	40000, 16, 1, 2, 0xb, 0}, {
-	0, 0, 0, 0, 0, 0}
-};
-
-/* the following table is based on 880Mhz fvco */
-static const pmu1_xtaltab0_t pmu1_xtaltab0_880[] = {
-	{
-	12000, 1, 3, 22, 0x9, 0xFFFFEF}, {
-	13000, 2, 1, 6, 0xb, 0x483483}, {
-	14400, 3, 1, 10, 0xa, 0x1C71C7}, {
-	15360, 4, 1, 5, 0xb, 0x755555}, {
-	16200, 5, 1, 10, 0x5, 0x6E9E06}, {
-	16800, 6, 1, 10, 0x5, 0x3Cf3Cf}, {
-	19200, 7, 1, 4, 0xb, 0x755555}, {
-	19800, 8, 1, 11, 0x4, 0xA57EB}, {
-	20000, 9, 1, 11, 0x4, 0x0}, {
-	24000, 10, 3, 11, 0xa, 0x0}, {
-	25000, 11, 5, 16, 0xb, 0x0}, {
-	26000, 12, 1, 2, 0x10, 0xEC4EC4}, {
-	30000, 13, 3, 8, 0xb, 0x0}, {
-	33600, 14, 1, 2, 0xd, 0x186186}, {
-	38400, 15, 1, 2, 0xb, 0x755555}, {
-	40000, 16, 1, 2, 0xb, 0}, {
-	0, 0, 0, 0, 0, 0}
-};
-
-#define PMU1_XTALTAB0_880_12000K	0
-#define PMU1_XTALTAB0_880_13000K	1
-#define PMU1_XTALTAB0_880_14400K	2
-#define PMU1_XTALTAB0_880_15360K	3
-#define PMU1_XTALTAB0_880_16200K	4
-#define PMU1_XTALTAB0_880_16800K	5
-#define PMU1_XTALTAB0_880_19200K	6
-#define PMU1_XTALTAB0_880_19800K	7
-#define PMU1_XTALTAB0_880_20000K	8
-#define PMU1_XTALTAB0_880_24000K	9
-#define PMU1_XTALTAB0_880_25000K	10
-#define PMU1_XTALTAB0_880_26000K	11
-#define PMU1_XTALTAB0_880_30000K	12
-#define PMU1_XTALTAB0_880_37400K	13
-#define PMU1_XTALTAB0_880_38400K	14
-#define PMU1_XTALTAB0_880_40000K	15
-
-/* the following table is based on 1760Mhz fvco */
-static const pmu1_xtaltab0_t pmu1_xtaltab0_1760[] = {
-	{
-	12000, 1, 3, 44, 0x9, 0xFFFFEF}, {
-	13000, 2, 1, 12, 0xb, 0x483483}, {
-	14400, 3, 1, 20, 0xa, 0x1C71C7}, {
-	15360, 4, 1, 10, 0xb, 0x755555}, {
-	16200, 5, 1, 20, 0x5, 0x6E9E06}, {
-	16800, 6, 1, 20, 0x5, 0x3Cf3Cf}, {
-	19200, 7, 1, 18, 0x5, 0x17B425}, {
-	19800, 8, 1, 22, 0x4, 0xA57EB}, {
-	20000, 9, 1, 22, 0x4, 0x0}, {
-	24000, 10, 3, 22, 0xa, 0x0}, {
-	25000, 11, 5, 32, 0xb, 0x0}, {
-	26000, 12, 1, 4, 0x10, 0xEC4EC4}, {
-	30000, 13, 3, 16, 0xb, 0x0}, {
-	38400, 14, 1, 10, 0x4, 0x955555}, {
-	40000, 15, 1, 4, 0xb, 0}, {
-	0, 0, 0, 0, 0, 0}
-};
-
-/* table index */
-#define PMU1_XTALTAB0_1760_12000K	0
-#define PMU1_XTALTAB0_1760_13000K	1
-#define PMU1_XTALTAB0_1760_14400K	2
-#define PMU1_XTALTAB0_1760_15360K	3
-#define PMU1_XTALTAB0_1760_16200K	4
-#define PMU1_XTALTAB0_1760_16800K	5
-#define PMU1_XTALTAB0_1760_19200K	6
-#define PMU1_XTALTAB0_1760_19800K	7
-#define PMU1_XTALTAB0_1760_20000K	8
-#define PMU1_XTALTAB0_1760_24000K	9
-#define PMU1_XTALTAB0_1760_25000K	10
-#define PMU1_XTALTAB0_1760_26000K	11
-#define PMU1_XTALTAB0_1760_30000K	12
-#define PMU1_XTALTAB0_1760_38400K	13
-#define PMU1_XTALTAB0_1760_40000K	14
-
-/* the following table is based on 1440Mhz fvco */
-static const pmu1_xtaltab0_t pmu1_xtaltab0_1440[] = {
-	{
-	12000, 1, 1, 1, 0x78, 0x0}, {
-	13000, 2, 1, 1, 0x6E, 0xC4EC4E}, {
-	14400, 3, 1, 1, 0x64, 0x0}, {
-	15360, 4, 1, 1, 0x5D, 0xC00000}, {
-	16200, 5, 1, 1, 0x58, 0xE38E38}, {
-	16800, 6, 1, 1, 0x55, 0xB6DB6D}, {
-	19200, 7, 1, 1, 0x4B, 0}, {
-	19800, 8, 1, 1, 0x48, 0xBA2E8B}, {
-	20000, 9, 1, 1, 0x48, 0x0}, {
-	25000, 10, 1, 1, 0x39, 0x999999}, {
-	26000, 11, 1, 1, 0x37, 0x627627}, {
-	30000, 12, 1, 1, 0x30, 0x0}, {
-	37400, 13, 2, 1, 0x4D, 0x15E76}, {
-	38400, 13, 2, 1, 0x4B, 0x0}, {
-	40000, 14, 2, 1, 0x48, 0x0}, {
-	48000, 15, 2, 1, 0x3c, 0x0}, {
-	0, 0, 0, 0, 0, 0}
-};
-
-/* table index */
-#define PMU1_XTALTAB0_1440_12000K	0
-#define PMU1_XTALTAB0_1440_13000K	1
-#define PMU1_XTALTAB0_1440_14400K	2
-#define PMU1_XTALTAB0_1440_15360K	3
-#define PMU1_XTALTAB0_1440_16200K	4
-#define PMU1_XTALTAB0_1440_16800K	5
-#define PMU1_XTALTAB0_1440_19200K	6
-#define PMU1_XTALTAB0_1440_19800K	7
-#define PMU1_XTALTAB0_1440_20000K	8
-#define PMU1_XTALTAB0_1440_25000K	9
-#define PMU1_XTALTAB0_1440_26000K	10
-#define PMU1_XTALTAB0_1440_30000K	11
-#define PMU1_XTALTAB0_1440_37400K	12
-#define PMU1_XTALTAB0_1440_38400K	13
-#define PMU1_XTALTAB0_1440_40000K	14
-#define PMU1_XTALTAB0_1440_48000K	15
-
-#define XTAL_FREQ_24000MHZ		24000
-#define XTAL_FREQ_30000MHZ		30000
-#define XTAL_FREQ_37400MHZ		37400
-#define XTAL_FREQ_48000MHZ		48000
-
-static const pmu1_xtaltab0_t pmu1_xtaltab0_960[] = {
-	{
-	12000, 1, 1, 1, 0x50, 0x0}, {
-	13000, 2, 1, 1, 0x49, 0xD89D89}, {
-	14400, 3, 1, 1, 0x42, 0xAAAAAA}, {
-	15360, 4, 1, 1, 0x3E, 0x800000}, {
-	16200, 5, 1, 1, 0x39, 0x425ED0}, {
-	16800, 6, 1, 1, 0x39, 0x249249}, {
-	19200, 7, 1, 1, 0x32, 0x0}, {
-	19800, 8, 1, 1, 0x30, 0x7C1F07}, {
-	20000, 9, 1, 1, 0x30, 0x0}, {
-	25000, 10, 1, 1, 0x26, 0x666666}, {
-	26000, 11, 1, 1, 0x24, 0xEC4EC4}, {
-	30000, 12, 1, 1, 0x20, 0x0}, {
-	37400, 13, 2, 1, 0x33, 0x563EF9}, {
-	38400, 14, 2, 1, 0x32, 0x0}, {
-	40000, 15, 2, 1, 0x30, 0x0}, {
-	48000, 16, 2, 1, 0x28, 0x0}, {
-	0, 0, 0, 0, 0, 0}
-};
-
-/* table index */
-#define PMU1_XTALTAB0_960_12000K	0
-#define PMU1_XTALTAB0_960_13000K	1
-#define PMU1_XTALTAB0_960_14400K	2
-#define PMU1_XTALTAB0_960_15360K	3
-#define PMU1_XTALTAB0_960_16200K	4
-#define PMU1_XTALTAB0_960_16800K	5
-#define PMU1_XTALTAB0_960_19200K	6
-#define PMU1_XTALTAB0_960_19800K	7
-#define PMU1_XTALTAB0_960_20000K	8
-#define PMU1_XTALTAB0_960_25000K	9
-#define PMU1_XTALTAB0_960_26000K	10
-#define PMU1_XTALTAB0_960_30000K	11
-#define PMU1_XTALTAB0_960_37400K	12
-#define PMU1_XTALTAB0_960_38400K	13
-#define PMU1_XTALTAB0_960_40000K	14
-#define PMU1_XTALTAB0_960_48000K	15
-
-/* select xtal table for each chip */
-static const pmu1_xtaltab0_t *si_pmu1_xtaltab0(si_t *sih)
-{
-#ifdef BCMDBG
-	char chn[8];
-#endif
-	switch (sih->chip) {
-	case BCM4329_CHIP_ID:
-		return pmu1_xtaltab0_880_4329;
-	case BCM4319_CHIP_ID:
-		return pmu1_xtaltab0_1440;
-	case BCM4336_CHIP_ID:
-		return pmu1_xtaltab0_960;
-	case BCM4330_CHIP_ID:
-		if (CST4330_CHIPMODE_SDIOD(sih->chipst))
-			return pmu1_xtaltab0_960;
-		else
-			return pmu1_xtaltab0_1440;
-	default:
-		PMU_MSG(("si_pmu1_xtaltab0: Unknown chipid %s\n",
-			 bcm_chipname(sih->chip, chn, 8)));
-		break;
-	}
-	ASSERT(0);
-	return NULL;
-}
-
-/* select default xtal frequency for each chip */
-static const pmu1_xtaltab0_t *si_pmu1_xtaldef0(si_t *sih)
-{
-#ifdef BCMDBG
-	char chn[8];
-#endif
-
-	switch (sih->chip) {
-	case BCM4329_CHIP_ID:
-		/* Default to 38400Khz */
-		return &pmu1_xtaltab0_880_4329[PMU1_XTALTAB0_880_38400K];
-	case BCM4319_CHIP_ID:
-		/* Default to 30000Khz */
-		return &pmu1_xtaltab0_1440[PMU1_XTALTAB0_1440_30000K];
-	case BCM4336_CHIP_ID:
-		/* Default to 26000Khz */
-		return &pmu1_xtaltab0_960[PMU1_XTALTAB0_960_26000K];
-	case BCM4330_CHIP_ID:
-		/* Default to 37400Khz */
-		if (CST4330_CHIPMODE_SDIOD(sih->chipst))
-			return &pmu1_xtaltab0_960[PMU1_XTALTAB0_960_37400K];
-		else
-			return &pmu1_xtaltab0_1440[PMU1_XTALTAB0_1440_37400K];
-	default:
-		PMU_MSG(("si_pmu1_xtaldef0: Unknown chipid %s\n",
-			 bcm_chipname(sih->chip, chn, 8)));
-		break;
-	}
-	ASSERT(0);
-	return NULL;
-}
-
-/* select default pll fvco for each chip */
-static u32 si_pmu1_pllfvco0(si_t *sih)
-{
-#ifdef BCMDBG
-	char chn[8];
-#endif
-
-	switch (sih->chip) {
-	case BCM4329_CHIP_ID:
-		return FVCO_880;
-	case BCM4319_CHIP_ID:
-		return FVCO_1440;
-	case BCM4336_CHIP_ID:
-		return FVCO_960;
-	case BCM4330_CHIP_ID:
-		if (CST4330_CHIPMODE_SDIOD(sih->chipst))
-			return FVCO_960;
-		else
-			return FVCO_1440;
-	default:
-		PMU_MSG(("si_pmu1_pllfvco0: Unknown chipid %s\n",
-			 bcm_chipname(sih->chip, chn, 8)));
-		break;
-	}
-	ASSERT(0);
-	return 0;
-}
-
-/* query alp/xtal clock frequency */
-static u32
-si_pmu1_alpclk0(si_t *sih, chipcregs_t *cc)
-{
-	const pmu1_xtaltab0_t *xt;
-	u32 xf;
-
-	/* Find the frequency in the table */
-	xf = (R_REG(&cc->pmucontrol) & PCTL_XTALFREQ_MASK) >>
-	    PCTL_XTALFREQ_SHIFT;
-	for (xt = si_pmu1_xtaltab0(sih); xt != NULL && xt->fref != 0; xt++)
-		if (xt->xf == xf)
-			break;
-	/* Could not find it so assign a default value */
-	if (xt == NULL || xt->fref == 0)
-		xt = si_pmu1_xtaldef0(sih);
-	ASSERT(xt != NULL && xt->fref != 0);
-
-	return xt->fref * 1000;
-}
-
-/* Set up PLL registers in the PMU as per the crystal speed.
- * XtalFreq field in pmucontrol register being 0 indicates the PLL
- * is not programmed and the h/w default is assumed to work, in which
- * case the xtal frequency is unknown to the s/w so we need to call
- * si_pmu1_xtaldef0() wherever it is needed to return a default value.
- */
-static void si_pmu1_pllinit0(si_t *sih, chipcregs_t *cc, u32 xtal)
-{
-	const pmu1_xtaltab0_t *xt;
-	u32 tmp;
-	u32 buf_strength = 0;
-	u8 ndiv_mode = 1;
-
-	/* Use h/w default PLL config */
-	if (xtal == 0) {
-		PMU_MSG(("Unspecified xtal frequency, skip PLL configuration\n"));
-		return;
-	}
-
-	/* Find the frequency in the table */
-	for (xt = si_pmu1_xtaltab0(sih); xt != NULL && xt->fref != 0; xt++)
-		if (xt->fref == xtal)
-			break;
-
-	/* Check current PLL state, bail out if it has been programmed or
-	 * we don't know how to program it.
-	 */
-	if (xt == NULL || xt->fref == 0) {
-		PMU_MSG(("Unsupported xtal frequency %d.%d MHz, skip PLL configuration\n", xtal / 1000, xtal % 1000));
-		return;
-	}
-	/*  for 4319 bootloader already programs the PLL but bootloader does not program the
-	   PLL4 and PLL5. So Skip this check for 4319
-	 */
-	if ((((R_REG(&cc->pmucontrol) & PCTL_XTALFREQ_MASK) >>
-	      PCTL_XTALFREQ_SHIFT) == xt->xf) &&
-	    !((sih->chip == BCM4319_CHIP_ID)
-	      || (sih->chip == BCM4330_CHIP_ID))) {
-		PMU_MSG(("PLL already programmed for %d.%d MHz\n",
-			 xt->fref / 1000, xt->fref % 1000));
-		return;
-	}
-
-	PMU_MSG(("XTAL %d.%d MHz (%d)\n", xtal / 1000, xtal % 1000, xt->xf));
-	PMU_MSG(("Programming PLL for %d.%d MHz\n", xt->fref / 1000,
-		 xt->fref % 1000));
-
-	switch (sih->chip) {
-	case BCM4329_CHIP_ID:
-		/* Change the BBPLL drive strength to 8 for all channels */
-		buf_strength = 0x888888;
-		AND_REG(&cc->min_res_mask,
-			~(PMURES_BIT(RES4329_BBPLL_PWRSW_PU) |
-			  PMURES_BIT(RES4329_HT_AVAIL)));
-		AND_REG(&cc->max_res_mask,
-			~(PMURES_BIT(RES4329_BBPLL_PWRSW_PU) |
-			  PMURES_BIT(RES4329_HT_AVAIL)));
-		SPINWAIT(R_REG(&cc->clk_ctl_st) & CCS_HTAVAIL,
-			 PMU_MAX_TRANSITION_DLY);
-		ASSERT(!(R_REG(&cc->clk_ctl_st) & CCS_HTAVAIL));
-		W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL4);
-		if (xt->fref == 38400)
-			tmp = 0x200024C0;
-		else if (xt->fref == 37400)
-			tmp = 0x20004500;
-		else if (xt->fref == 26000)
-			tmp = 0x200024C0;
-		else
-			tmp = 0x200005C0;	/* Chip Dflt Settings */
-		W_REG(&cc->pllcontrol_data, tmp);
-		W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL5);
-		tmp =
-		    R_REG(&cc->pllcontrol_data) & PMU1_PLL0_PC5_CLK_DRV_MASK;
-		if ((xt->fref == 38400) || (xt->fref == 37400)
-		    || (xt->fref == 26000))
-			tmp |= 0x15;
-		else
-			tmp |= 0x25;	/* Chip Dflt Settings */
-		W_REG(&cc->pllcontrol_data, tmp);
-		break;
-
-	case BCM4319_CHIP_ID:
-		/* Change the BBPLL drive strength to 2 for all channels */
-		buf_strength = 0x222222;
-
-		/* Make sure the PLL is off */
-		/* WAR65104: Disable the HT_AVAIL resource first and then
-		 * after a delay (more than downtime for HT_AVAIL) remove the
-		 * BBPLL resource; backplane clock moves to ALP from HT.
-		 */
-		AND_REG(&cc->min_res_mask,
-			~(PMURES_BIT(RES4319_HT_AVAIL)));
-		AND_REG(&cc->max_res_mask,
-			~(PMURES_BIT(RES4319_HT_AVAIL)));
-
-		udelay(100);
-		AND_REG(&cc->min_res_mask,
-			~(PMURES_BIT(RES4319_BBPLL_PWRSW_PU)));
-		AND_REG(&cc->max_res_mask,
-			~(PMURES_BIT(RES4319_BBPLL_PWRSW_PU)));
-
-		udelay(100);
-		SPINWAIT(R_REG(&cc->clk_ctl_st) & CCS_HTAVAIL,
-			 PMU_MAX_TRANSITION_DLY);
-		ASSERT(!(R_REG(&cc->clk_ctl_st) & CCS_HTAVAIL));
-		W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL4);
-		tmp = 0x200005c0;
-		W_REG(&cc->pllcontrol_data, tmp);
-		break;
-
-	case BCM4336_CHIP_ID:
-		AND_REG(&cc->min_res_mask,
-			~(PMURES_BIT(RES4336_HT_AVAIL) |
-			  PMURES_BIT(RES4336_MACPHY_CLKAVAIL)));
-		AND_REG(&cc->max_res_mask,
-			~(PMURES_BIT(RES4336_HT_AVAIL) |
-			  PMURES_BIT(RES4336_MACPHY_CLKAVAIL)));
-		udelay(100);
-		SPINWAIT(R_REG(&cc->clk_ctl_st) & CCS_HTAVAIL,
-			 PMU_MAX_TRANSITION_DLY);
-		ASSERT(!(R_REG(&cc->clk_ctl_st) & CCS_HTAVAIL));
-		break;
-
-	case BCM4330_CHIP_ID:
-		AND_REG(&cc->min_res_mask,
-			~(PMURES_BIT(RES4330_HT_AVAIL) |
-			  PMURES_BIT(RES4330_MACPHY_CLKAVAIL)));
-		AND_REG(&cc->max_res_mask,
-			~(PMURES_BIT(RES4330_HT_AVAIL) |
-			  PMURES_BIT(RES4330_MACPHY_CLKAVAIL)));
-		udelay(100);
-		SPINWAIT(R_REG(&cc->clk_ctl_st) & CCS_HTAVAIL,
-			 PMU_MAX_TRANSITION_DLY);
-		ASSERT(!(R_REG(&cc->clk_ctl_st) & CCS_HTAVAIL));
-		break;
-
-	default:
-		ASSERT(0);
-	}
-
-	PMU_MSG(("Done masking\n"));
-
-	/* Write p1div and p2div to pllcontrol[0] */
-	W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0);
-	tmp = R_REG(&cc->pllcontrol_data) &
-	    ~(PMU1_PLL0_PC0_P1DIV_MASK | PMU1_PLL0_PC0_P2DIV_MASK);
-	tmp |=
-	    ((xt->
-	      p1div << PMU1_PLL0_PC0_P1DIV_SHIFT) & PMU1_PLL0_PC0_P1DIV_MASK) |
-	    ((xt->
-	      p2div << PMU1_PLL0_PC0_P2DIV_SHIFT) & PMU1_PLL0_PC0_P2DIV_MASK);
-	W_REG(&cc->pllcontrol_data, tmp);
-
-	if ((sih->chip == BCM4330_CHIP_ID))
-		si_pmu_set_4330_plldivs(sih);
-
-	if ((sih->chip == BCM4329_CHIP_ID)
-	    && (sih->chiprev == 0)) {
-
-		W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL1);
-		tmp = R_REG(&cc->pllcontrol_data);
-		tmp = tmp & (~DOT11MAC_880MHZ_CLK_DIVISOR_MASK);
-		tmp = tmp | DOT11MAC_880MHZ_CLK_DIVISOR_VAL;
-		W_REG(&cc->pllcontrol_data, tmp);
-	}
-	if ((sih->chip == BCM4319_CHIP_ID) ||
-	    (sih->chip == BCM4336_CHIP_ID) ||
-	    (sih->chip == BCM4330_CHIP_ID))
-		ndiv_mode = PMU1_PLL0_PC2_NDIV_MODE_MFB;
-	else
-		ndiv_mode = PMU1_PLL0_PC2_NDIV_MODE_MASH;
-
-	/* Write ndiv_int and ndiv_mode to pllcontrol[2] */
-	W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2);
-	tmp = R_REG(&cc->pllcontrol_data) &
-	    ~(PMU1_PLL0_PC2_NDIV_INT_MASK | PMU1_PLL0_PC2_NDIV_MODE_MASK);
-	tmp |=
-	    ((xt->
-	      ndiv_int << PMU1_PLL0_PC2_NDIV_INT_SHIFT) &
-	     PMU1_PLL0_PC2_NDIV_INT_MASK) | ((ndiv_mode <<
-					      PMU1_PLL0_PC2_NDIV_MODE_SHIFT) &
-					     PMU1_PLL0_PC2_NDIV_MODE_MASK);
-	W_REG(&cc->pllcontrol_data, tmp);
-
-	/* Write ndiv_frac to pllcontrol[3] */
-	W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL3);
-	tmp = R_REG(&cc->pllcontrol_data) & ~PMU1_PLL0_PC3_NDIV_FRAC_MASK;
-	tmp |= ((xt->ndiv_frac << PMU1_PLL0_PC3_NDIV_FRAC_SHIFT) &
-		PMU1_PLL0_PC3_NDIV_FRAC_MASK);
-	W_REG(&cc->pllcontrol_data, tmp);
-
-	/* Write clock driving strength to pllcontrol[5] */
-	if (buf_strength) {
-		PMU_MSG(("Adjusting PLL buffer drive strength: %x\n",
-			 buf_strength));
-
-		W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL5);
-		tmp =
-		    R_REG(&cc->pllcontrol_data) & ~PMU1_PLL0_PC5_CLK_DRV_MASK;
-		tmp |= (buf_strength << PMU1_PLL0_PC5_CLK_DRV_SHIFT);
-		W_REG(&cc->pllcontrol_data, tmp);
-	}
-
-	PMU_MSG(("Done pll\n"));
-
-	/* to operate the 4319 usb in 24MHz/48MHz; chipcontrol[2][84:83] needs
-	 * to be updated.
-	 */
-	if ((sih->chip == BCM4319_CHIP_ID)
-	    && (xt->fref != XTAL_FREQ_30000MHZ)) {
-		W_REG(&cc->chipcontrol_addr, PMU1_PLL0_CHIPCTL2);
-		tmp =
-		    R_REG(&cc->chipcontrol_data) & ~CCTL_4319USB_XTAL_SEL_MASK;
-		if (xt->fref == XTAL_FREQ_24000MHZ) {
-			tmp |=
-			    (CCTL_4319USB_24MHZ_PLL_SEL <<
-			     CCTL_4319USB_XTAL_SEL_SHIFT);
-		} else if (xt->fref == XTAL_FREQ_48000MHZ) {
-			tmp |=
-			    (CCTL_4319USB_48MHZ_PLL_SEL <<
-			     CCTL_4319USB_XTAL_SEL_SHIFT);
-		}
-		W_REG(&cc->chipcontrol_data, tmp);
-	}
-
-	/* Flush deferred pll control registers writes */
-	if (sih->pmurev >= 2)
-		OR_REG(&cc->pmucontrol, PCTL_PLL_PLLCTL_UPD);
-
-	/* Write XtalFreq. Set the divisor also. */
-	tmp = R_REG(&cc->pmucontrol) &
-	    ~(PCTL_ILP_DIV_MASK | PCTL_XTALFREQ_MASK);
-	tmp |= (((((xt->fref + 127) / 128) - 1) << PCTL_ILP_DIV_SHIFT) &
-		PCTL_ILP_DIV_MASK) |
-	    ((xt->xf << PCTL_XTALFREQ_SHIFT) & PCTL_XTALFREQ_MASK);
-
-	if ((sih->chip == BCM4329_CHIP_ID)
-	    && sih->chiprev == 0) {
-		/* clear the htstretch before clearing HTReqEn */
-		AND_REG(&cc->clkstretch, ~CSTRETCH_HT);
-		tmp &= ~PCTL_HT_REQ_EN;
-	}
-
-	W_REG(&cc->pmucontrol, tmp);
-}
-
-/* query the CPU clock frequency */
-static u32
-si_pmu1_cpuclk0(si_t *sih, chipcregs_t *cc)
-{
-	u32 tmp, m1div;
-#ifdef BCMDBG
-	u32 ndiv_int, ndiv_frac, p2div, p1div, fvco;
-	u32 fref;
-#endif
-	u32 FVCO = si_pmu1_pllfvco0(sih);
-
-	/* Read m1div from pllcontrol[1] */
-	W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL1);
-	tmp = R_REG(&cc->pllcontrol_data);
-	m1div = (tmp & PMU1_PLL0_PC1_M1DIV_MASK) >> PMU1_PLL0_PC1_M1DIV_SHIFT;
-
-#ifdef BCMDBG
-	/* Read p2div/p1div from pllcontrol[0] */
-	W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0);
-	tmp = R_REG(&cc->pllcontrol_data);
-	p2div = (tmp & PMU1_PLL0_PC0_P2DIV_MASK) >> PMU1_PLL0_PC0_P2DIV_SHIFT;
-	p1div = (tmp & PMU1_PLL0_PC0_P1DIV_MASK) >> PMU1_PLL0_PC0_P1DIV_SHIFT;
-
-	/* Calculate fvco based on xtal freq and ndiv and pdiv */
-	W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2);
-	tmp = R_REG(&cc->pllcontrol_data);
-	ndiv_int =
-	    (tmp & PMU1_PLL0_PC2_NDIV_INT_MASK) >> PMU1_PLL0_PC2_NDIV_INT_SHIFT;
-
-	W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL3);
-	tmp = R_REG(&cc->pllcontrol_data);
-	ndiv_frac =
-	    (tmp & PMU1_PLL0_PC3_NDIV_FRAC_MASK) >>
-	    PMU1_PLL0_PC3_NDIV_FRAC_SHIFT;
-
-	fref = si_pmu1_alpclk0(sih, cc) / 1000;
-
-	fvco = (fref * ndiv_int) << 8;
-	fvco += (fref * (ndiv_frac >> 12)) >> 4;
-	fvco += (fref * (ndiv_frac & 0xfff)) >> 12;
-	fvco >>= 8;
-	fvco *= p2div;
-	fvco /= p1div;
-	fvco /= 1000;
-	fvco *= 1000;
-
-	PMU_MSG(("si_pmu1_cpuclk0: ndiv_int %u ndiv_frac %u p2div %u p1div %u fvco %u\n", ndiv_int, ndiv_frac, p2div, p1div, fvco));
-
-	FVCO = fvco;
-#endif				/* BCMDBG */
-
-	/* Return ARM/SB clock */
-	return FVCO / m1div * 1000;
-}
-
-/* initialize PLL */
-void si_pmu_pll_init(si_t *sih, uint xtalfreq)
-{
-	chipcregs_t *cc;
-	uint origidx;
-#ifdef BCMDBG
-	char chn[8];
-#endif
-
-	ASSERT(sih->cccaps & CC_CAP_PMU);
-
-	/* Remember original core before switch to chipc */
-	origidx = si_coreidx(sih);
-	cc = si_setcoreidx(sih, SI_CC_IDX);
-	ASSERT(cc != NULL);
-
-	switch (sih->chip) {
-	case BCM4329_CHIP_ID:
-		if (xtalfreq == 0)
-			xtalfreq = 38400;
-		si_pmu1_pllinit0(sih, cc, xtalfreq);
-		break;
-	case BCM4313_CHIP_ID:
-	case BCM43224_CHIP_ID:
-	case BCM43225_CHIP_ID:
-	case BCM43421_CHIP_ID:
-	case BCM43235_CHIP_ID:
-	case BCM43236_CHIP_ID:
-	case BCM43238_CHIP_ID:
-	case BCM4331_CHIP_ID:
-	case BCM6362_CHIP_ID:
-		/* ??? */
-		break;
-	case BCM4319_CHIP_ID:
-	case BCM4336_CHIP_ID:
-	case BCM4330_CHIP_ID:
-		si_pmu1_pllinit0(sih, cc, xtalfreq);
-		break;
-	default:
-		PMU_MSG(("No PLL init done for chip %s rev %d pmurev %d\n",
-			 bcm_chipname(sih->chip, chn, 8), sih->chiprev,
-			 sih->pmurev));
-		break;
-	}
-
-#ifdef BCMDBG_FORCEHT
-	OR_REG(&cc->clk_ctl_st, CCS_FORCEHT);
-#endif
-
-	/* Return to original core */
-	si_setcoreidx(sih, origidx);
-}
-
-/* query alp/xtal clock frequency */
-u32 si_pmu_alp_clock(si_t *sih)
-{
-	chipcregs_t *cc;
-	uint origidx;
-	u32 clock = ALP_CLOCK;
-#ifdef BCMDBG
-	char chn[8];
-#endif
-
-	ASSERT(sih->cccaps & CC_CAP_PMU);
-
-	/* Remember original core before switch to chipc */
-	origidx = si_coreidx(sih);
-	cc = si_setcoreidx(sih, SI_CC_IDX);
-	ASSERT(cc != NULL);
-
-	switch (sih->chip) {
-	case BCM43224_CHIP_ID:
-	case BCM43225_CHIP_ID:
-	case BCM43421_CHIP_ID:
-	case BCM43235_CHIP_ID:
-	case BCM43236_CHIP_ID:
-	case BCM43238_CHIP_ID:
-	case BCM4331_CHIP_ID:
-	case BCM6362_CHIP_ID:
-	case BCM4716_CHIP_ID:
-	case BCM4748_CHIP_ID:
-	case BCM47162_CHIP_ID:
-	case BCM4313_CHIP_ID:
-	case BCM5357_CHIP_ID:
-		/* always 20Mhz */
-		clock = 20000 * 1000;
-		break;
-	case BCM4329_CHIP_ID:
-	case BCM4319_CHIP_ID:
-	case BCM4336_CHIP_ID:
-	case BCM4330_CHIP_ID:
-
-		clock = si_pmu1_alpclk0(sih, cc);
-		break;
-	case BCM5356_CHIP_ID:
-		/* always 25Mhz */
-		clock = 25000 * 1000;
-		break;
-	default:
-		PMU_MSG(("No ALP clock specified "
-			 "for chip %s rev %d pmurev %d, using default %d Hz\n",
-			 bcm_chipname(sih->chip, chn, 8), sih->chiprev,
-			 sih->pmurev, clock));
-		break;
-	}
-
-	/* Return to original core */
-	si_setcoreidx(sih, origidx);
-	return clock;
-}
-
-/* Find the output of the "m" pll divider given pll controls that start with
- * pllreg "pll0" i.e. 12 for main 6 for phy, 0 for misc.
- */
-static u32
-si_pmu5_clock(si_t *sih, chipcregs_t *cc, uint pll0, uint m) {
-	u32 tmp, div, ndiv, p1, p2, fc;
-
-	if ((pll0 & 3) || (pll0 > PMU4716_MAINPLL_PLL0)) {
-		PMU_ERROR(("%s: Bad pll0: %d\n", __func__, pll0));
-		return 0;
-	}
-
-	/* Strictly there is an m5 divider, but I'm not sure we use it */
-	if ((m == 0) || (m > 4)) {
-		PMU_ERROR(("%s: Bad m divider: %d\n", __func__, m));
-		return 0;
-	}
-
-	if (sih->chip == BCM5357_CHIP_ID) {
-		/* Detect failure in clock setting */
-		if ((R_REG(&cc->chipstatus) & 0x40000) != 0)
-			return 133 * 1000000;
-	}
-
-	W_REG(&cc->pllcontrol_addr, pll0 + PMU5_PLL_P1P2_OFF);
-	(void)R_REG(&cc->pllcontrol_addr);
-	tmp = R_REG(&cc->pllcontrol_data);
-	p1 = (tmp & PMU5_PLL_P1_MASK) >> PMU5_PLL_P1_SHIFT;
-	p2 = (tmp & PMU5_PLL_P2_MASK) >> PMU5_PLL_P2_SHIFT;
-
-	W_REG(&cc->pllcontrol_addr, pll0 + PMU5_PLL_M14_OFF);
-	(void)R_REG(&cc->pllcontrol_addr);
-	tmp = R_REG(&cc->pllcontrol_data);
-	div = (tmp >> ((m - 1) * PMU5_PLL_MDIV_WIDTH)) & PMU5_PLL_MDIV_MASK;
-
-	W_REG(&cc->pllcontrol_addr, pll0 + PMU5_PLL_NM5_OFF);
-	(void)R_REG(&cc->pllcontrol_addr);
-	tmp = R_REG(&cc->pllcontrol_data);
-	ndiv = (tmp & PMU5_PLL_NDIV_MASK) >> PMU5_PLL_NDIV_SHIFT;
-
-	/* Do calculation in Mhz */
-	fc = si_pmu_alp_clock(sih) / 1000000;
-	fc = (p1 * ndiv * fc) / p2;
-
-	PMU_NONE(("%s: p1=%d, p2=%d, ndiv=%d(0x%x), m%d=%d; fc=%d, clock=%d\n",
-		  __func__, p1, p2, ndiv, ndiv, m, div, fc, fc / div));
-
-	/* Return clock in Hertz */
-	return (fc / div) * 1000000;
-}
-
-/* query backplane clock frequency */
-/* For designs that feed the same clock to both backplane
- * and CPU just return the CPU clock speed.
- */
-u32 si_pmu_si_clock(si_t *sih)
-{
-	chipcregs_t *cc;
-	uint origidx;
-	u32 clock = HT_CLOCK;
-#ifdef BCMDBG
-	char chn[8];
-#endif
-
-	ASSERT(sih->cccaps & CC_CAP_PMU);
-
-	/* Remember original core before switch to chipc */
-	origidx = si_coreidx(sih);
-	cc = si_setcoreidx(sih, SI_CC_IDX);
-	ASSERT(cc != NULL);
-
-	switch (sih->chip) {
-	case BCM43224_CHIP_ID:
-	case BCM43225_CHIP_ID:
-	case BCM43421_CHIP_ID:
-	case BCM4331_CHIP_ID:
-	case BCM6362_CHIP_ID:
-		/* 96MHz backplane clock */
-		clock = 96000 * 1000;
-		break;
-	case BCM4716_CHIP_ID:
-	case BCM4748_CHIP_ID:
-	case BCM47162_CHIP_ID:
-		clock =
-		    si_pmu5_clock(sih, cc, PMU4716_MAINPLL_PLL0,
-				  PMU5_MAINPLL_SI);
-		break;
-	case BCM4329_CHIP_ID:
-		if (sih->chiprev == 0)
-			clock = 38400 * 1000;
-		else
-			clock = si_pmu1_cpuclk0(sih, cc);
-		break;
-	case BCM4319_CHIP_ID:
-	case BCM4336_CHIP_ID:
-	case BCM4330_CHIP_ID:
-		clock = si_pmu1_cpuclk0(sih, cc);
-		break;
-	case BCM4313_CHIP_ID:
-		/* 80MHz backplane clock */
-		clock = 80000 * 1000;
-		break;
-	case BCM43235_CHIP_ID:
-	case BCM43236_CHIP_ID:
-	case BCM43238_CHIP_ID:
-		clock =
-		    (cc->chipstatus & CST43236_BP_CLK) ? (120000 *
-							  1000) : (96000 *
-								   1000);
-		break;
-	case BCM5356_CHIP_ID:
-		clock =
-		    si_pmu5_clock(sih, cc, PMU5356_MAINPLL_PLL0,
-				  PMU5_MAINPLL_SI);
-		break;
-	case BCM5357_CHIP_ID:
-		clock =
-		    si_pmu5_clock(sih, cc, PMU5357_MAINPLL_PLL0,
-				  PMU5_MAINPLL_SI);
-		break;
-	default:
-		PMU_MSG(("No backplane clock specified "
-			 "for chip %s rev %d pmurev %d, using default %d Hz\n",
-			 bcm_chipname(sih->chip, chn, 8), sih->chiprev,
-			 sih->pmurev, clock));
-		break;
-	}
-
-	/* Return to original core */
-	si_setcoreidx(sih, origidx);
-	return clock;
-}
-
-/* query CPU clock frequency */
-u32 si_pmu_cpu_clock(si_t *sih)
-{
-	chipcregs_t *cc;
-	uint origidx;
-	u32 clock;
-
-	ASSERT(sih->cccaps & CC_CAP_PMU);
-
-	if ((sih->pmurev >= 5) &&
-	    !((sih->chip == BCM4329_CHIP_ID) ||
-	      (sih->chip == BCM4319_CHIP_ID) ||
-	      (sih->chip == BCM43236_CHIP_ID) ||
-	      (sih->chip == BCM4336_CHIP_ID) ||
-	      (sih->chip == BCM4330_CHIP_ID))) {
-		uint pll;
-
-		switch (sih->chip) {
-		case BCM5356_CHIP_ID:
-			pll = PMU5356_MAINPLL_PLL0;
-			break;
-		case BCM5357_CHIP_ID:
-			pll = PMU5357_MAINPLL_PLL0;
-			break;
-		default:
-			pll = PMU4716_MAINPLL_PLL0;
-			break;
-		}
-
-		/* Remember original core before switch to chipc */
-		origidx = si_coreidx(sih);
-		cc = si_setcoreidx(sih, SI_CC_IDX);
-		ASSERT(cc != NULL);
-
-		clock = si_pmu5_clock(sih, cc, pll, PMU5_MAINPLL_CPU);
-
-		/* Return to original core */
-		si_setcoreidx(sih, origidx);
-	} else
-		clock = si_pmu_si_clock(sih);
-
-	return clock;
-}
-
-/* query memory clock frequency */
-u32 si_pmu_mem_clock(si_t *sih)
-{
-	chipcregs_t *cc;
-	uint origidx;
-	u32 clock;
-
-	ASSERT(sih->cccaps & CC_CAP_PMU);
-
-	if ((sih->pmurev >= 5) &&
-	    !((sih->chip == BCM4329_CHIP_ID) ||
-	      (sih->chip == BCM4319_CHIP_ID) ||
-	      (sih->chip == BCM4330_CHIP_ID) ||
-	      (sih->chip == BCM4336_CHIP_ID) ||
-	      (sih->chip == BCM43236_CHIP_ID))) {
-		uint pll;
-
-		switch (sih->chip) {
-		case BCM5356_CHIP_ID:
-			pll = PMU5356_MAINPLL_PLL0;
-			break;
-		case BCM5357_CHIP_ID:
-			pll = PMU5357_MAINPLL_PLL0;
-			break;
-		default:
-			pll = PMU4716_MAINPLL_PLL0;
-			break;
-		}
-
-		/* Remember original core before switch to chipc */
-		origidx = si_coreidx(sih);
-		cc = si_setcoreidx(sih, SI_CC_IDX);
-		ASSERT(cc != NULL);
-
-		clock = si_pmu5_clock(sih, cc, pll, PMU5_MAINPLL_MEM);
-
-		/* Return to original core */
-		si_setcoreidx(sih, origidx);
-	} else {
-		clock = si_pmu_si_clock(sih);
-	}
-
-	return clock;
-}
-
-/* Measure ILP clock frequency */
-#define ILP_CALC_DUR	10	/* ms, make sure 1000 can be divided by it. */
-
-static u32 ilpcycles_per_sec;
-
-u32 si_pmu_ilp_clock(si_t *sih)
-{
-	if (ISSIM_ENAB(sih))
-		return ILP_CLOCK;
-
-	if (ilpcycles_per_sec == 0) {
-		u32 start, end, delta;
-		u32 origidx = si_coreidx(sih);
-		chipcregs_t *cc = si_setcoreidx(sih, SI_CC_IDX);
-		ASSERT(cc != NULL);
-		start = R_REG(&cc->pmutimer);
-		mdelay(ILP_CALC_DUR);
-		end = R_REG(&cc->pmutimer);
-		delta = end - start;
-		ilpcycles_per_sec = delta * (1000 / ILP_CALC_DUR);
-		si_setcoreidx(sih, origidx);
-	}
-
-	return ilpcycles_per_sec;
-}
-
-/* SDIO Pad drive strength to select value mappings */
-typedef struct {
-	u8 strength;		/* Pad Drive Strength in mA */
-	u8 sel;		/* Chip-specific select value */
-} sdiod_drive_str_t;
-
-/* SDIO Drive Strength to sel value table for PMU Rev 1 */
-static const sdiod_drive_str_t sdiod_drive_strength_tab1[] = {
-	{
-	4, 0x2}, {
-	2, 0x3}, {
-	1, 0x0}, {
-	0, 0x0}
-	};
-
-/* SDIO Drive Strength to sel value table for PMU Rev 2, 3 */
-static const sdiod_drive_str_t sdiod_drive_strength_tab2[] = {
-	{
-	12, 0x7}, {
-	10, 0x6}, {
-	8, 0x5}, {
-	6, 0x4}, {
-	4, 0x2}, {
-	2, 0x1}, {
-	0, 0x0}
-	};
-
-/* SDIO Drive Strength to sel value table for PMU Rev 8 (1.8V) */
-static const sdiod_drive_str_t sdiod_drive_strength_tab3[] = {
-	{
-	32, 0x7}, {
-	26, 0x6}, {
-	22, 0x5}, {
-	16, 0x4}, {
-	12, 0x3}, {
-	8, 0x2}, {
-	4, 0x1}, {
-	0, 0x0}
-	};
-
-#define SDIOD_DRVSTR_KEY(chip, pmu)	(((chip) << 16) | (pmu))
-
-void
-si_sdiod_drive_strength_init(si_t *sih, u32 drivestrength) {
-	chipcregs_t *cc;
-	uint origidx, intr_val = 0;
-	sdiod_drive_str_t *str_tab = NULL;
-	u32 str_mask = 0;
-	u32 str_shift = 0;
-#ifdef BCMDBG
-	char chn[8];
-#endif
-
-	if (!(sih->cccaps & CC_CAP_PMU)) {
-		return;
-	}
-
-	/* Remember original core before switch to chipc */
-	cc = (chipcregs_t *) si_switch_core(sih, CC_CORE_ID, &origidx,
-					    &intr_val);
-
-	switch (SDIOD_DRVSTR_KEY(sih->chip, sih->pmurev)) {
-	case SDIOD_DRVSTR_KEY(BCM4325_CHIP_ID, 1):
-		str_tab = (sdiod_drive_str_t *)&sdiod_drive_strength_tab1;
-		str_mask = 0x30000000;
-		str_shift = 28;
-		break;
-	case SDIOD_DRVSTR_KEY(BCM4325_CHIP_ID, 2):
-	case SDIOD_DRVSTR_KEY(BCM4325_CHIP_ID, 3):
-		str_tab = (sdiod_drive_str_t *)&sdiod_drive_strength_tab2;
-		str_mask = 0x00003800;
-		str_shift = 11;
-		break;
-	case SDIOD_DRVSTR_KEY(BCM4336_CHIP_ID, 8):
-		str_tab = (sdiod_drive_str_t *) &sdiod_drive_strength_tab3;
-		str_mask = 0x00003800;
-		str_shift = 11;
-		break;
-
-	default:
-		PMU_MSG(("No SDIO Drive strength init done for chip %s rev %d pmurev %d\n", bcm_chipname(sih->chip, chn, 8), sih->chiprev, sih->pmurev));
-
-		break;
-	}
-
-	if (str_tab != NULL) {
-		u32 drivestrength_sel = 0;
-		u32 cc_data_temp;
-		int i;
-
-		for (i = 0; str_tab[i].strength != 0; i++) {
-			if (drivestrength >= str_tab[i].strength) {
-				drivestrength_sel = str_tab[i].sel;
-				break;
-			}
-		}
-
-		W_REG(&cc->chipcontrol_addr, 1);
-		cc_data_temp = R_REG(&cc->chipcontrol_data);
-		cc_data_temp &= ~str_mask;
-		drivestrength_sel <<= str_shift;
-		cc_data_temp |= drivestrength_sel;
-		W_REG(&cc->chipcontrol_data, cc_data_temp);
-
-		PMU_MSG(("SDIO: %dmA drive strength selected, set to 0x%08x\n",
-			 drivestrength, cc_data_temp));
-	}
-
-	/* Return to original core */
-	si_restore_core(sih, origidx, intr_val);
-}
-
-/* initialize PMU */
-void si_pmu_init(si_t *sih)
-{
-	chipcregs_t *cc;
-	uint origidx;
-
-	ASSERT(sih->cccaps & CC_CAP_PMU);
-
-	/* Remember original core before switch to chipc */
-	origidx = si_coreidx(sih);
-	cc = si_setcoreidx(sih, SI_CC_IDX);
-	ASSERT(cc != NULL);
-
-	if (sih->pmurev == 1)
-		AND_REG(&cc->pmucontrol, ~PCTL_NOILP_ON_WAIT);
-	else if (sih->pmurev >= 2)
-		OR_REG(&cc->pmucontrol, PCTL_NOILP_ON_WAIT);
-
-	if ((sih->chip == BCM4329_CHIP_ID) && (sih->chiprev == 2)) {
-		/* Fix for 4329b0 bad LPOM state. */
-		W_REG(&cc->regcontrol_addr, 2);
-		OR_REG(&cc->regcontrol_data, 0x100);
-
-		W_REG(&cc->regcontrol_addr, 3);
-		OR_REG(&cc->regcontrol_data, 0x4);
-	}
-
-	/* Return to original core */
-	si_setcoreidx(sih, origidx);
-}
-
-/* Return up time in ILP cycles for the given resource. */
-static uint
-si_pmu_res_uptime(si_t *sih, chipcregs_t *cc, u8 rsrc) {
-	u32 deps;
-	uint up, i, dup, dmax;
-	u32 min_mask = 0, max_mask = 0;
-
-	/* uptime of resource 'rsrc' */
-	W_REG(&cc->res_table_sel, rsrc);
-	up = (R_REG(&cc->res_updn_timer) >> 8) & 0xff;
-
-	/* direct dependancies of resource 'rsrc' */
-	deps = si_pmu_res_deps(sih, cc, PMURES_BIT(rsrc), false);
-	for (i = 0; i <= PMURES_MAX_RESNUM; i++) {
-		if (!(deps & PMURES_BIT(i)))
-			continue;
-		deps &= ~si_pmu_res_deps(sih, cc, PMURES_BIT(i), true);
-	}
-	si_pmu_res_masks(sih, &min_mask, &max_mask);
-	deps &= ~min_mask;
-
-	/* max uptime of direct dependancies */
-	dmax = 0;
-	for (i = 0; i <= PMURES_MAX_RESNUM; i++) {
-		if (!(deps & PMURES_BIT(i)))
-			continue;
-		dup = si_pmu_res_uptime(sih, cc, (u8) i);
-		if (dmax < dup)
-			dmax = dup;
-	}
-
-	PMU_MSG(("si_pmu_res_uptime: rsrc %u uptime %u(deps 0x%08x uptime %u)\n", rsrc, up, deps, dmax));
-
-	return up + dmax + PMURES_UP_TRANSITION;
-}
-
-/* Return dependancies (direct or all/indirect) for the given resources */
-static u32
-si_pmu_res_deps(si_t *sih, chipcregs_t *cc, u32 rsrcs,
-		bool all)
-{
-	u32 deps = 0;
-	u32 i;
-
-	for (i = 0; i <= PMURES_MAX_RESNUM; i++) {
-		if (!(rsrcs & PMURES_BIT(i)))
-			continue;
-		W_REG(&cc->res_table_sel, i);
-		deps |= R_REG(&cc->res_dep_mask);
-	}
-
-	return !all ? deps : (deps
-			      ? (deps |
-				 si_pmu_res_deps(sih, cc, deps,
-						 true)) : 0);
-}
-
-/* power up/down OTP through PMU resources */
-void si_pmu_otp_power(si_t *sih, bool on)
-{
-	chipcregs_t *cc;
-	uint origidx;
-	u32 rsrcs = 0;	/* rsrcs to turn on/off OTP power */
-
-	ASSERT(sih->cccaps & CC_CAP_PMU);
-
-	/* Don't do anything if OTP is disabled */
-	if (si_is_otp_disabled(sih)) {
-		PMU_MSG(("si_pmu_otp_power: OTP is disabled\n"));
-		return;
-	}
-
-	/* Remember original core before switch to chipc */
-	origidx = si_coreidx(sih);
-	cc = si_setcoreidx(sih, SI_CC_IDX);
-	ASSERT(cc != NULL);
-
-	switch (sih->chip) {
-	case BCM4329_CHIP_ID:
-		rsrcs = PMURES_BIT(RES4329_OTP_PU);
-		break;
-	case BCM4319_CHIP_ID:
-		rsrcs = PMURES_BIT(RES4319_OTP_PU);
-		break;
-	case BCM4336_CHIP_ID:
-		rsrcs = PMURES_BIT(RES4336_OTP_PU);
-		break;
-	case BCM4330_CHIP_ID:
-		rsrcs = PMURES_BIT(RES4330_OTP_PU);
-		break;
-	default:
-		break;
-	}
-
-	if (rsrcs != 0) {
-		u32 otps;
-
-		/* Figure out the dependancies (exclude min_res_mask) */
-		u32 deps = si_pmu_res_deps(sih, cc, rsrcs, true);
-		u32 min_mask = 0, max_mask = 0;
-		si_pmu_res_masks(sih, &min_mask, &max_mask);
-		deps &= ~min_mask;
-		/* Turn on/off the power */
-		if (on) {
-			PMU_MSG(("Adding rsrc 0x%x to min_res_mask\n",
-				 rsrcs | deps));
-			OR_REG(&cc->min_res_mask, (rsrcs | deps));
-			SPINWAIT(!(R_REG(&cc->res_state) & rsrcs),
-				 PMU_MAX_TRANSITION_DLY);
-			ASSERT(R_REG(&cc->res_state) & rsrcs);
-		} else {
-			PMU_MSG(("Removing rsrc 0x%x from min_res_mask\n",
-				 rsrcs | deps));
-			AND_REG(&cc->min_res_mask, ~(rsrcs | deps));
-		}
-
-		SPINWAIT((((otps = R_REG(&cc->otpstatus)) & OTPS_READY) !=
-			  (on ? OTPS_READY : 0)), 100);
-		ASSERT((otps & OTPS_READY) == (on ? OTPS_READY : 0));
-		if ((otps & OTPS_READY) != (on ? OTPS_READY : 0))
-			PMU_MSG(("OTP ready bit not %s after wait\n",
-				 (on ? "ON" : "OFF")));
-	}
-
-	/* Return to original core */
-	si_setcoreidx(sih, origidx);
-}
-
-void si_pmu_rcal(si_t *sih)
-{
-	chipcregs_t *cc;
-	uint origidx;
-
-	ASSERT(sih->cccaps & CC_CAP_PMU);
-
-	/* Remember original core before switch to chipc */
-	origidx = si_coreidx(sih);
-	cc = si_setcoreidx(sih, SI_CC_IDX);
-	ASSERT(cc != NULL);
-
-	switch (sih->chip) {
-	case BCM4329_CHIP_ID:{
-			u8 rcal_code;
-			u32 val;
-
-			/* Kick RCal */
-			W_REG(&cc->chipcontrol_addr, 1);
-
-			/* Power Down RCAL Block */
-			AND_REG(&cc->chipcontrol_data, ~0x04);
-
-			/* Power Up RCAL block */
-			OR_REG(&cc->chipcontrol_data, 0x04);
-
-			/* Wait for completion */
-			SPINWAIT(0 == (R_REG(&cc->chipstatus) & 0x08),
-				 10 * 1000 * 1000);
-			ASSERT(R_REG(&cc->chipstatus) & 0x08);
-
-			/* Drop the LSB to convert from 5 bit code to 4 bit code */
-			rcal_code =
-			    (u8) (R_REG(&cc->chipstatus) >> 5) & 0x0f;
-
-			PMU_MSG(("RCal completed, status 0x%x, code 0x%x\n",
-				 R_REG(&cc->chipstatus), rcal_code));
-
-			/* Write RCal code into pmu_vreg_ctrl[32:29] */
-			W_REG(&cc->regcontrol_addr, 0);
-			val =
-			    R_REG(&cc->regcontrol_data) & ~((u32) 0x07 << 29);
-			val |= (u32) (rcal_code & 0x07) << 29;
-			W_REG(&cc->regcontrol_data, val);
-			W_REG(&cc->regcontrol_addr, 1);
-			val = R_REG(&cc->regcontrol_data) & ~(u32) 0x01;
-			val |= (u32) ((rcal_code >> 3) & 0x01);
-			W_REG(&cc->regcontrol_data, val);
-
-			/* Write RCal code into pmu_chip_ctrl[33:30] */
-			W_REG(&cc->chipcontrol_addr, 0);
-			val =
-			    R_REG(&cc->chipcontrol_data) & ~((u32) 0x03 << 30);
-			val |= (u32) (rcal_code & 0x03) << 30;
-			W_REG(&cc->chipcontrol_data, val);
-			W_REG(&cc->chipcontrol_addr, 1);
-			val =
-			    R_REG(&cc->chipcontrol_data) & ~(u32) 0x03;
-			val |= (u32) ((rcal_code >> 2) & 0x03);
-			W_REG(&cc->chipcontrol_data, val);
-
-			/* Set override in pmu_chip_ctrl[29] */
-			W_REG(&cc->chipcontrol_addr, 0);
-			OR_REG(&cc->chipcontrol_data, (0x01 << 29));
-
-			/* Power off RCal block */
-			W_REG(&cc->chipcontrol_addr, 1);
-			AND_REG(&cc->chipcontrol_data, ~0x04);
-
-			break;
-		}
-	default:
-		break;
-	}
-
-	/* Return to original core */
-	si_setcoreidx(sih, origidx);
-}
-
-void si_pmu_spuravoid(si_t *sih, u8 spuravoid)
-{
-	chipcregs_t *cc;
-	uint origidx, intr_val;
-	u32 tmp = 0;
-
-	/* Remember original core before switch to chipc */
-	cc = (chipcregs_t *) si_switch_core(sih, CC_CORE_ID, &origidx,
-					    &intr_val);
-	ASSERT(cc != NULL);
-
-	/* force the HT off  */
-	if (sih->chip == BCM4336_CHIP_ID) {
-		tmp = R_REG(&cc->max_res_mask);
-		tmp &= ~RES4336_HT_AVAIL;
-		W_REG(&cc->max_res_mask, tmp);
-		/* wait for the ht to really go away */
-		SPINWAIT(((R_REG(&cc->clk_ctl_st) & CCS_HTAVAIL) == 0),
-			 10000);
-		ASSERT((R_REG(&cc->clk_ctl_st) & CCS_HTAVAIL) == 0);
-	}
-
-	/* update the pll changes */
-	si_pmu_spuravoid_pllupdate(sih, cc, spuravoid);
-
-	/* enable HT back on  */
-	if (sih->chip == BCM4336_CHIP_ID) {
-		tmp = R_REG(&cc->max_res_mask);
-		tmp |= RES4336_HT_AVAIL;
-		W_REG(&cc->max_res_mask, tmp);
-	}
-
-	/* Return to original core */
-	si_restore_core(sih, origidx, intr_val);
-}
-
-static void
-si_pmu_spuravoid_pllupdate(si_t *sih, chipcregs_t *cc, u8 spuravoid)
-{
-	u32 tmp = 0;
-	u8 phypll_offset = 0;
-	u8 bcm5357_bcm43236_p1div[] = { 0x1, 0x5, 0x5 };
-	u8 bcm5357_bcm43236_ndiv[] = { 0x30, 0xf6, 0xfc };
-
-	switch (sih->chip) {
-	case BCM5357_CHIP_ID:
-	case BCM43235_CHIP_ID:
-	case BCM43236_CHIP_ID:
-	case BCM43238_CHIP_ID:
-
-		/* BCM5357 needs to touch PLL1_PLLCTL[02], so offset PLL0_PLLCTL[02] by 6 */
-		phypll_offset = (sih->chip == BCM5357_CHIP_ID) ? 6 : 0;
-
-		/* RMW only the P1 divider */
-		W_REG(&cc->pllcontrol_addr,
-		      PMU1_PLL0_PLLCTL0 + phypll_offset);
-		tmp = R_REG(&cc->pllcontrol_data);
-		tmp &= (~(PMU1_PLL0_PC0_P1DIV_MASK));
-		tmp |=
-		    (bcm5357_bcm43236_p1div[spuravoid] <<
-		     PMU1_PLL0_PC0_P1DIV_SHIFT);
-		W_REG(&cc->pllcontrol_data, tmp);
-
-		/* RMW only the int feedback divider */
-		W_REG(&cc->pllcontrol_addr,
-		      PMU1_PLL0_PLLCTL2 + phypll_offset);
-		tmp = R_REG(&cc->pllcontrol_data);
-		tmp &= ~(PMU1_PLL0_PC2_NDIV_INT_MASK);
-		tmp |=
-		    (bcm5357_bcm43236_ndiv[spuravoid]) <<
-		    PMU1_PLL0_PC2_NDIV_INT_SHIFT;
-		W_REG(&cc->pllcontrol_data, tmp);
-
-		tmp = 1 << 10;
-		break;
-
-	case BCM4331_CHIP_ID:
-		if (spuravoid == 2) {
-			W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0);
-			W_REG(&cc->pllcontrol_data, 0x11500014);
-			W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2);
-			W_REG(&cc->pllcontrol_data, 0x0FC00a08);
-		} else if (spuravoid == 1) {
-			W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0);
-			W_REG(&cc->pllcontrol_data, 0x11500014);
-			W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2);
-			W_REG(&cc->pllcontrol_data, 0x0F600a08);
-		} else {
-			W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0);
-			W_REG(&cc->pllcontrol_data, 0x11100014);
-			W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2);
-			W_REG(&cc->pllcontrol_data, 0x03000a08);
-		}
-		tmp = 1 << 10;
-		break;
-
-	case BCM43224_CHIP_ID:
-	case BCM43225_CHIP_ID:
-	case BCM43421_CHIP_ID:
-	case BCM6362_CHIP_ID:
-		if (spuravoid == 1) {
-			W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0);
-			W_REG(&cc->pllcontrol_data, 0x11500010);
-			W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL1);
-			W_REG(&cc->pllcontrol_data, 0x000C0C06);
-			W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2);
-			W_REG(&cc->pllcontrol_data, 0x0F600a08);
-			W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL3);
-			W_REG(&cc->pllcontrol_data, 0x00000000);
-			W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL4);
-			W_REG(&cc->pllcontrol_data, 0x2001E920);
-			W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL5);
-			W_REG(&cc->pllcontrol_data, 0x88888815);
-		} else {
-			W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0);
-			W_REG(&cc->pllcontrol_data, 0x11100010);
-			W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL1);
-			W_REG(&cc->pllcontrol_data, 0x000c0c06);
-			W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2);
-			W_REG(&cc->pllcontrol_data, 0x03000a08);
-			W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL3);
-			W_REG(&cc->pllcontrol_data, 0x00000000);
-			W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL4);
-			W_REG(&cc->pllcontrol_data, 0x200005c0);
-			W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL5);
-			W_REG(&cc->pllcontrol_data, 0x88888815);
-		}
-		tmp = 1 << 10;
-		break;
-
-		W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0);
-		W_REG(&cc->pllcontrol_data, 0x11100008);
-		W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL1);
-		W_REG(&cc->pllcontrol_data, 0x0c000c06);
-		W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2);
-		W_REG(&cc->pllcontrol_data, 0x03000a08);
-		W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL3);
-		W_REG(&cc->pllcontrol_data, 0x00000000);
-		W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL4);
-		W_REG(&cc->pllcontrol_data, 0x200005c0);
-		W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL5);
-		W_REG(&cc->pllcontrol_data, 0x88888855);
-
-		tmp = 1 << 10;
-		break;
-
-	case BCM4716_CHIP_ID:
-	case BCM4748_CHIP_ID:
-	case BCM47162_CHIP_ID:
-		if (spuravoid == 1) {
-			W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0);
-			W_REG(&cc->pllcontrol_data, 0x11500060);
-			W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL1);
-			W_REG(&cc->pllcontrol_data, 0x080C0C06);
-			W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2);
-			W_REG(&cc->pllcontrol_data, 0x0F600000);
-			W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL3);
-			W_REG(&cc->pllcontrol_data, 0x00000000);
-			W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL4);
-			W_REG(&cc->pllcontrol_data, 0x2001E924);
-			W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL5);
-			W_REG(&cc->pllcontrol_data, 0x88888815);
-		} else {
-			W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0);
-			W_REG(&cc->pllcontrol_data, 0x11100060);
-			W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL1);
-			W_REG(&cc->pllcontrol_data, 0x080c0c06);
-			W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2);
-			W_REG(&cc->pllcontrol_data, 0x03000000);
-			W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL3);
-			W_REG(&cc->pllcontrol_data, 0x00000000);
-			W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL4);
-			W_REG(&cc->pllcontrol_data, 0x200005c0);
-			W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL5);
-			W_REG(&cc->pllcontrol_data, 0x88888815);
-		}
-
-		tmp = 3 << 9;
-		break;
-
-	case BCM4319_CHIP_ID:
-		W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0);
-		W_REG(&cc->pllcontrol_data, 0x11100070);
-		W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL1);
-		W_REG(&cc->pllcontrol_data, 0x1014140a);
-		W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL5);
-		W_REG(&cc->pllcontrol_data, 0x88888854);
-
-		if (spuravoid == 1) {	/* spur_avoid ON, enable 41/82/164Mhz clock mode */
-			W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2);
-			W_REG(&cc->pllcontrol_data, 0x05201828);
-		} else {	/* enable 40/80/160Mhz clock mode */
-			W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2);
-			W_REG(&cc->pllcontrol_data, 0x05001828);
-		}
-		break;
-	case BCM4336_CHIP_ID:
-		/* Looks like these are only for default xtal freq 26MHz */
-		W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL0);
-		W_REG(&cc->pllcontrol_data, 0x02100020);
-
-		W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL1);
-		W_REG(&cc->pllcontrol_data, 0x0C0C0C0C);
-
-		W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL2);
-		W_REG(&cc->pllcontrol_data, 0x01240C0C);
-
-		W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL4);
-		W_REG(&cc->pllcontrol_data, 0x202C2820);
-
-		W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL5);
-		W_REG(&cc->pllcontrol_data, 0x88888825);
-
-		W_REG(&cc->pllcontrol_addr, PMU1_PLL0_PLLCTL3);
-		if (spuravoid == 1) {
-			W_REG(&cc->pllcontrol_data, 0x00EC4EC4);
-		} else {
-			W_REG(&cc->pllcontrol_data, 0x00762762);
-		}
-
-		tmp = PCTL_PLL_PLLCTL_UPD;
-		break;
-
-	default:
-		PMU_ERROR(("%s: unknown spuravoidance settings for chip %s, not changing PLL\n", __func__, bcm_chipname(sih->chip, chn, 8)));
-		break;
-	}
-
-	tmp |= R_REG(&cc->pmucontrol);
-	W_REG(&cc->pmucontrol, tmp);
-}
-
-bool si_pmu_is_otp_powered(si_t *sih)
-{
-	uint idx;
-	chipcregs_t *cc;
-	bool st;
-
-	/* Remember original core before switch to chipc */
-	idx = si_coreidx(sih);
-	cc = si_setcoreidx(sih, SI_CC_IDX);
-	ASSERT(cc != NULL);
-
-	switch (sih->chip) {
-	case BCM4329_CHIP_ID:
-		st = (R_REG(&cc->res_state) & PMURES_BIT(RES4329_OTP_PU))
-		    != 0;
-		break;
-	case BCM4319_CHIP_ID:
-		st = (R_REG(&cc->res_state) & PMURES_BIT(RES4319_OTP_PU))
-		    != 0;
-		break;
-	case BCM4336_CHIP_ID:
-		st = (R_REG(&cc->res_state) & PMURES_BIT(RES4336_OTP_PU))
-		    != 0;
-		break;
-	case BCM4330_CHIP_ID:
-		st = (R_REG(&cc->res_state) & PMURES_BIT(RES4330_OTP_PU))
-		    != 0;
-		break;
-
-		/* These chip doesn't use PMU bit to power up/down OTP. OTP always on.
-		 * Use OTP_INIT command to reset/refresh state.
-		 */
-	case BCM43224_CHIP_ID:
-	case BCM43225_CHIP_ID:
-	case BCM43421_CHIP_ID:
-	case BCM43236_CHIP_ID:
-	case BCM43235_CHIP_ID:
-	case BCM43238_CHIP_ID:
-		st = true;
-		break;
-	default:
-		st = true;
-		break;
-	}
-
-	/* Return to original core */
-	si_setcoreidx(sih, idx);
-	return st;
-}
-
-void si_pmu_sprom_enable(si_t *sih, bool enable)
-{
-	chipcregs_t *cc;
-	uint origidx;
-
-	/* Remember original core before switch to chipc */
-	origidx = si_coreidx(sih);
-	cc = si_setcoreidx(sih, SI_CC_IDX);
-	ASSERT(cc != NULL);
-
-	/* Return to original core */
-	si_setcoreidx(sih, origidx);
-}
-
-/* initialize PMU chip controls and other chip level stuff */
-void si_pmu_chip_init(si_t *sih)
-{
-	uint origidx;
-
-	ASSERT(sih->cccaps & CC_CAP_PMU);
-
-#ifdef CHIPC_UART_ALWAYS_ON
-	si_corereg(sih, SI_CC_IDX, offsetof(chipcregs_t, clk_ctl_st),
-		   CCS_FORCEALP, CCS_FORCEALP);
-#endif				/* CHIPC_UART_ALWAYS_ON */
-
-	/* Gate off SPROM clock and chip select signals */
-	si_pmu_sprom_enable(sih, false);
-
-	/* Remember original core */
-	origidx = si_coreidx(sih);
-
-	/* Return to original core */
-	si_setcoreidx(sih, origidx);
-}
-
-/* initialize PMU switch/regulators */
-void si_pmu_swreg_init(si_t *sih)
-{
-	ASSERT(sih->cccaps & CC_CAP_PMU);
-
-	switch (sih->chip) {
-	case BCM4336_CHIP_ID:
-		/* Reduce CLDO PWM output voltage to 1.2V */
-		si_pmu_set_ldo_voltage(sih, SET_LDO_VOLTAGE_CLDO_PWM, 0xe);
-		/* Reduce CLDO BURST output voltage to 1.2V */
-		si_pmu_set_ldo_voltage(sih, SET_LDO_VOLTAGE_CLDO_BURST,
-				       0xe);
-		/* Reduce LNLDO1 output voltage to 1.2V */
-		si_pmu_set_ldo_voltage(sih, SET_LDO_VOLTAGE_LNLDO1, 0xe);
-		if (sih->chiprev == 0)
-			si_pmu_regcontrol(sih, 2, 0x400000, 0x400000);
-		break;
-
-	case BCM4330_CHIP_ID:
-		/* CBUCK Voltage is 1.8 by default and set that to 1.5 */
-		si_pmu_set_ldo_voltage(sih, SET_LDO_VOLTAGE_CBUCK_PWM, 0);
-		break;
-	default:
-		break;
-	}
-}
-
-void si_pmu_radio_enable(si_t *sih, bool enable)
-{
-	ASSERT(sih->cccaps & CC_CAP_PMU);
-
-	switch (sih->chip) {
-	case BCM4319_CHIP_ID:
-		if (enable)
-			si_write_wrapperreg(sih, AI_OOBSELOUTB74,
-					    (u32) 0x868584);
-		else
-			si_write_wrapperreg(sih, AI_OOBSELOUTB74,
-					    (u32) 0x060584);
-		break;
-	}
-}
-
-/* Wait for a particular clock level to be on the backplane */
-u32
-si_pmu_waitforclk_on_backplane(si_t *sih, u32 clk, u32 delay)
-{
-	chipcregs_t *cc;
-	uint origidx;
-
-	ASSERT(sih->cccaps & CC_CAP_PMU);
-
-	/* Remember original core before switch to chipc */
-	origidx = si_coreidx(sih);
-	cc = si_setcoreidx(sih, SI_CC_IDX);
-	ASSERT(cc != NULL);
-
-	if (delay)
-		SPINWAIT(((R_REG(&cc->pmustatus) & clk) != clk), delay);
-
-	/* Return to original core */
-	si_setcoreidx(sih, origidx);
-
-	return R_REG(&cc->pmustatus) & clk;
-}
-
-/*
- * Measures the ALP clock frequency in KHz.  Returns 0 if not possible.
- * Possible only if PMU rev >= 10 and there is an external LPO 32768Hz crystal.
- */
-
-#define EXT_ILP_HZ 32768
-
-u32 si_pmu_measure_alpclk(si_t *sih)
-{
-	chipcregs_t *cc;
-	uint origidx;
-	u32 alp_khz;
-
-	if (sih->pmurev < 10)
-		return 0;
-
-	ASSERT(sih->cccaps & CC_CAP_PMU);
-
-	/* Remember original core before switch to chipc */
-	origidx = si_coreidx(sih);
-	cc = si_setcoreidx(sih, SI_CC_IDX);
-	ASSERT(cc != NULL);
-
-	if (R_REG(&cc->pmustatus) & PST_EXTLPOAVAIL) {
-		u32 ilp_ctr, alp_hz;
-
-		/* Enable the reg to measure the freq, in case disabled before */
-		W_REG(&cc->pmu_xtalfreq,
-		      1U << PMU_XTALFREQ_REG_MEASURE_SHIFT);
-
-		/* Delay for well over 4 ILP clocks */
-		udelay(1000);
-
-		/* Read the latched number of ALP ticks per 4 ILP ticks */
-		ilp_ctr =
-		    R_REG(&cc->pmu_xtalfreq) & PMU_XTALFREQ_REG_ILPCTR_MASK;
-
-		/* Turn off the PMU_XTALFREQ_REG_MEASURE_SHIFT bit to save power */
-		W_REG(&cc->pmu_xtalfreq, 0);
-
-		/* Calculate ALP frequency */
-		alp_hz = (ilp_ctr * EXT_ILP_HZ) / 4;
-
-		/* Round to nearest 100KHz, and at the same time convert to KHz */
-		alp_khz = (alp_hz + 50000) / 100000 * 100;
-	} else
-		alp_khz = 0;
-
-	/* Return to original core */
-	si_setcoreidx(sih, origidx);
-
-	return alp_khz;
-}
-
-static void si_pmu_set_4330_plldivs(si_t *sih)
-{
-	u32 FVCO = si_pmu1_pllfvco0(sih) / 1000;
-	u32 m1div, m2div, m3div, m4div, m5div, m6div;
-	u32 pllc1, pllc2;
-
-	m2div = m3div = m4div = m6div = FVCO / 80;
-	m5div = FVCO / 160;
-
-	if (CST4330_CHIPMODE_SDIOD(sih->chipst))
-		m1div = FVCO / 80;
-	else
-		m1div = FVCO / 90;
-	pllc1 =
-	    (m1div << PMU1_PLL0_PC1_M1DIV_SHIFT) | (m2div <<
-						    PMU1_PLL0_PC1_M2DIV_SHIFT) |
-	    (m3div << PMU1_PLL0_PC1_M3DIV_SHIFT) | (m4div <<
-						    PMU1_PLL0_PC1_M4DIV_SHIFT);
-	si_pmu_pllcontrol(sih, PMU1_PLL0_PLLCTL1, ~0, pllc1);
-
-	pllc2 = si_pmu_pllcontrol(sih, PMU1_PLL0_PLLCTL1, 0, 0);
-	pllc2 &= ~(PMU1_PLL0_PC2_M5DIV_MASK | PMU1_PLL0_PC2_M6DIV_MASK);
-	pllc2 |=
-	    ((m5div << PMU1_PLL0_PC2_M5DIV_SHIFT) |
-	     (m6div << PMU1_PLL0_PC2_M6DIV_SHIFT));
-	si_pmu_pllcontrol(sih, PMU1_PLL0_PLLCTL2, ~0, pllc2);
-}
diff -druN linux-2.6.39-libre/drivers/staging/brcm80211/util/Makefile linux-3.0-rc7-libre/drivers/staging/brcm80211/util/Makefile
--- linux-2.6.39-libre/drivers/staging/brcm80211/util/Makefile	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/staging/brcm80211/util/Makefile	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,29 @@
+#
+# Makefile fragment for Broadcom 802.11n Networking Device Driver Utilities
+#
+# Copyright (c) 2011 Broadcom Corporation
+#
+# 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.
+
+ccflags-y :=				\
+	-Idrivers/staging/brcm80211/util \
+	-Idrivers/staging/brcm80211/include
+
+BRCMUTIL_OFILES := \
+	bcmutils.o \
+	bcmwifi.o
+
+MODULEPFX := brcmutil
+
+obj-$(CONFIG_BRCMUTIL)	+= $(MODULEPFX).o
+$(MODULEPFX)-objs	= $(BRCMUTIL_OFILES)
diff -druN linux-2.6.39-libre/drivers/staging/brcm80211/util/nicpci.c linux-3.0-rc7-libre/drivers/staging/brcm80211/util/nicpci.c
--- linux-2.6.39-libre/drivers/staging/brcm80211/util/nicpci.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/brcm80211/util/nicpci.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,851 +0,0 @@
-/*
- * Copyright (c) 2010 Broadcom Corporation
- *
- * 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/delay.h>
-#include <linux/string.h>
-#include <linux/pci.h>
-#include <bcmdefs.h>
-#include <bcmutils.h>
-#include <siutils.h>
-#include <hndsoc.h>
-#include <bcmdevs.h>
-#include <sbchipc.h>
-#include <pci_core.h>
-#include <pcie_core.h>
-#include <nicpci.h>
-#include <pcicfg.h>
-
-typedef struct {
-	union {
-		sbpcieregs_t *pcieregs;
-		struct sbpciregs *pciregs;
-	} regs;			/* Memory mapped register to the core */
-
-	si_t *sih;		/* System interconnect handle */
-	struct pci_dev *dev;
-	u8 pciecap_lcreg_offset;	/* PCIE capability LCreg offset in the config space */
-	bool pcie_pr42767;
-	u8 pcie_polarity;
-	u8 pcie_war_aspm_ovr;	/* Override ASPM/Clkreq settings */
-
-	u8 pmecap_offset;	/* PM Capability offset in the config space */
-	bool pmecap;		/* Capable of generating PME */
-} pcicore_info_t;
-
-/* debug/trace */
-#define	PCI_ERROR(args)
-#define PCIE_PUB(sih) \
-	(((sih)->bustype == PCI_BUS) && ((sih)->buscoretype == PCIE_CORE_ID))
-
-/* routines to access mdio slave device registers */
-static bool pcie_mdiosetblock(pcicore_info_t *pi, uint blk);
-static int pcie_mdioop(pcicore_info_t *pi, uint physmedia, uint regaddr,
-		       bool write, uint *val);
-static int pcie_mdiowrite(pcicore_info_t *pi, uint physmedia, uint readdr,
-			  uint val);
-static int pcie_mdioread(pcicore_info_t *pi, uint physmedia, uint readdr,
-			 uint *ret_val);
-
-static void pcie_extendL1timer(pcicore_info_t *pi, bool extend);
-static void pcie_clkreq_upd(pcicore_info_t *pi, uint state);
-
-static void pcie_war_aspm_clkreq(pcicore_info_t *pi);
-static void pcie_war_serdes(pcicore_info_t *pi);
-static void pcie_war_noplldown(pcicore_info_t *pi);
-static void pcie_war_polarity(pcicore_info_t *pi);
-static void pcie_war_pci_setup(pcicore_info_t *pi);
-
-static bool pcicore_pmecap(pcicore_info_t *pi);
-
-#define PCIE_ASPM(sih)	((PCIE_PUB(sih)) && (((sih)->buscorerev >= 3) && ((sih)->buscorerev <= 5)))
-
-
-/* delay needed between the mdio control/ mdiodata register data access */
-#define PR28829_DELAY() udelay(10)
-
-/* Initialize the PCI core. It's caller's responsibility to make sure that this is done
- * only once
- */
-void *pcicore_init(si_t *sih, void *pdev, void *regs)
-{
-	pcicore_info_t *pi;
-
-	ASSERT(sih->bustype == PCI_BUS);
-
-	/* alloc pcicore_info_t */
-	pi = kzalloc(sizeof(pcicore_info_t), GFP_ATOMIC);
-	if (pi == NULL) {
-		PCI_ERROR(("pci_attach: malloc failed!\n"));
-		return NULL;
-	}
-
-	pi->sih = sih;
-	pi->dev = pdev;
-
-	if (sih->buscoretype == PCIE_CORE_ID) {
-		u8 cap_ptr;
-		pi->regs.pcieregs = (sbpcieregs_t *) regs;
-		cap_ptr =
-		    pcicore_find_pci_capability(pi->dev, PCI_CAP_PCIECAP_ID,
-						NULL, NULL);
-		ASSERT(cap_ptr);
-		pi->pciecap_lcreg_offset = cap_ptr + PCIE_CAP_LINKCTRL_OFFSET;
-	} else
-		pi->regs.pciregs = (struct sbpciregs *) regs;
-
-	return pi;
-}
-
-void pcicore_deinit(void *pch)
-{
-	pcicore_info_t *pi = (pcicore_info_t *) pch;
-
-	if (pi == NULL)
-		return;
-	kfree(pi);
-}
-
-/* return cap_offset if requested capability exists in the PCI config space */
-/* Note that it's caller's responsibility to make sure it's a pci bus */
-u8
-pcicore_find_pci_capability(void *dev, u8 req_cap_id,
-			    unsigned char *buf, u32 *buflen)
-{
-	u8 cap_id;
-	u8 cap_ptr = 0;
-	u32 bufsize;
-	u8 byte_val;
-
-	/* check for Header type 0 */
-	pci_read_config_byte(dev, PCI_CFG_HDR, &byte_val);
-	if ((byte_val & 0x7f) != PCI_HEADER_NORMAL)
-		goto end;
-
-	/* check if the capability pointer field exists */
-	pci_read_config_byte(dev, PCI_CFG_STAT, &byte_val);
-	if (!(byte_val & PCI_CAPPTR_PRESENT))
-		goto end;
-
-	pci_read_config_byte(dev, PCI_CFG_CAPPTR, &cap_ptr);
-	/* check if the capability pointer is 0x00 */
-	if (cap_ptr == 0x00)
-		goto end;
-
-	/* loop thr'u the capability list and see if the pcie capabilty exists */
-
-	pci_read_config_byte(dev, cap_ptr, &cap_id);
-
-	while (cap_id != req_cap_id) {
-		pci_read_config_byte(dev, cap_ptr + 1, &cap_ptr);
-		if (cap_ptr == 0x00)
-			break;
-		pci_read_config_byte(dev, cap_ptr, &cap_id);
-	}
-	if (cap_id != req_cap_id) {
-		goto end;
-	}
-	/* found the caller requested capability */
-	if ((buf != NULL) && (buflen != NULL)) {
-		u8 cap_data;
-
-		bufsize = *buflen;
-		if (!bufsize)
-			goto end;
-		*buflen = 0;
-		/* copy the cpability data excluding cap ID and next ptr */
-		cap_data = cap_ptr + 2;
-		if ((bufsize + cap_data) > SZPCR)
-			bufsize = SZPCR - cap_data;
-		*buflen = bufsize;
-		while (bufsize--) {
-			pci_read_config_byte(dev, cap_data, buf);
-			cap_data++;
-			buf++;
-		}
-	}
- end:
-	return cap_ptr;
-}
-
-/* ***** Register Access API */
-uint
-pcie_readreg(sbpcieregs_t *pcieregs, uint addrtype,
-	     uint offset)
-{
-	uint retval = 0xFFFFFFFF;
-
-	ASSERT(pcieregs != NULL);
-
-	switch (addrtype) {
-	case PCIE_CONFIGREGS:
-		W_REG((&pcieregs->configaddr), offset);
-		(void)R_REG((&pcieregs->configaddr));
-		retval = R_REG(&(pcieregs->configdata));
-		break;
-	case PCIE_PCIEREGS:
-		W_REG(&(pcieregs->pcieindaddr), offset);
-		(void)R_REG((&pcieregs->pcieindaddr));
-		retval = R_REG(&(pcieregs->pcieinddata));
-		break;
-	default:
-		ASSERT(0);
-		break;
-	}
-
-	return retval;
-}
-
-uint
-pcie_writereg(sbpcieregs_t *pcieregs, uint addrtype,
-	      uint offset, uint val)
-{
-	ASSERT(pcieregs != NULL);
-
-	switch (addrtype) {
-	case PCIE_CONFIGREGS:
-		W_REG((&pcieregs->configaddr), offset);
-		W_REG((&pcieregs->configdata), val);
-		break;
-	case PCIE_PCIEREGS:
-		W_REG((&pcieregs->pcieindaddr), offset);
-		W_REG((&pcieregs->pcieinddata), val);
-		break;
-	default:
-		ASSERT(0);
-		break;
-	}
-	return 0;
-}
-
-static bool pcie_mdiosetblock(pcicore_info_t *pi, uint blk)
-{
-	sbpcieregs_t *pcieregs = pi->regs.pcieregs;
-	uint mdiodata, i = 0;
-	uint pcie_serdes_spinwait = 200;
-
-	mdiodata =
-	    MDIODATA_START | MDIODATA_WRITE | (MDIODATA_DEV_ADDR <<
-					       MDIODATA_DEVADDR_SHF) |
-	    (MDIODATA_BLK_ADDR << MDIODATA_REGADDR_SHF) | MDIODATA_TA | (blk <<
-									 4);
-	W_REG(&pcieregs->mdiodata, mdiodata);
-
-	PR28829_DELAY();
-	/* retry till the transaction is complete */
-	while (i < pcie_serdes_spinwait) {
-		if (R_REG(&(pcieregs->mdiocontrol)) &
-		    MDIOCTL_ACCESS_DONE) {
-			break;
-		}
-		udelay(1000);
-		i++;
-	}
-
-	if (i >= pcie_serdes_spinwait) {
-		PCI_ERROR(("pcie_mdiosetblock: timed out\n"));
-		return false;
-	}
-
-	return true;
-}
-
-static int
-pcie_mdioop(pcicore_info_t *pi, uint physmedia, uint regaddr, bool write,
-	    uint *val)
-{
-	sbpcieregs_t *pcieregs = pi->regs.pcieregs;
-	uint mdiodata;
-	uint i = 0;
-	uint pcie_serdes_spinwait = 10;
-
-	/* enable mdio access to SERDES */
-	W_REG((&pcieregs->mdiocontrol),
-	      MDIOCTL_PREAM_EN | MDIOCTL_DIVISOR_VAL);
-
-	if (pi->sih->buscorerev >= 10) {
-		/* new serdes is slower in rw, using two layers of reg address mapping */
-		if (!pcie_mdiosetblock(pi, physmedia))
-			return 1;
-		mdiodata = (MDIODATA_DEV_ADDR << MDIODATA_DEVADDR_SHF) |
-		    (regaddr << MDIODATA_REGADDR_SHF);
-		pcie_serdes_spinwait *= 20;
-	} else {
-		mdiodata = (physmedia << MDIODATA_DEVADDR_SHF_OLD) |
-		    (regaddr << MDIODATA_REGADDR_SHF_OLD);
-	}
-
-	if (!write)
-		mdiodata |= (MDIODATA_START | MDIODATA_READ | MDIODATA_TA);
-	else
-		mdiodata |=
-		    (MDIODATA_START | MDIODATA_WRITE | MDIODATA_TA | *val);
-
-	W_REG(&pcieregs->mdiodata, mdiodata);
-
-	PR28829_DELAY();
-
-	/* retry till the transaction is complete */
-	while (i < pcie_serdes_spinwait) {
-		if (R_REG(&(pcieregs->mdiocontrol)) &
-		    MDIOCTL_ACCESS_DONE) {
-			if (!write) {
-				PR28829_DELAY();
-				*val =
-				    (R_REG(&(pcieregs->mdiodata)) &
-				     MDIODATA_MASK);
-			}
-			/* Disable mdio access to SERDES */
-			W_REG((&pcieregs->mdiocontrol), 0);
-			return 0;
-		}
-		udelay(1000);
-		i++;
-	}
-
-	PCI_ERROR(("pcie_mdioop: timed out op: %d\n", write));
-	/* Disable mdio access to SERDES */
-	W_REG((&pcieregs->mdiocontrol), 0);
-	return 1;
-}
-
-/* use the mdio interface to read from mdio slaves */
-static int
-pcie_mdioread(pcicore_info_t *pi, uint physmedia, uint regaddr, uint *regval)
-{
-	return pcie_mdioop(pi, physmedia, regaddr, false, regval);
-}
-
-/* use the mdio interface to write to mdio slaves */
-static int
-pcie_mdiowrite(pcicore_info_t *pi, uint physmedia, uint regaddr, uint val)
-{
-	return pcie_mdioop(pi, physmedia, regaddr, true, &val);
-}
-
-/* ***** Support functions ***** */
-u8 pcie_clkreq(void *pch, u32 mask, u32 val)
-{
-	pcicore_info_t *pi = (pcicore_info_t *) pch;
-	u32 reg_val;
-	u8 offset;
-
-	offset = pi->pciecap_lcreg_offset;
-	if (!offset)
-		return 0;
-
-	pci_read_config_dword(pi->dev, offset, &reg_val);
-	/* set operation */
-	if (mask) {
-		if (val)
-			reg_val |= PCIE_CLKREQ_ENAB;
-		else
-			reg_val &= ~PCIE_CLKREQ_ENAB;
-		pci_write_config_dword(pi->dev, offset, reg_val);
-		pci_read_config_dword(pi->dev, offset, &reg_val);
-	}
-	if (reg_val & PCIE_CLKREQ_ENAB)
-		return 1;
-	else
-		return 0;
-}
-
-static void pcie_extendL1timer(pcicore_info_t *pi, bool extend)
-{
-	u32 w;
-	si_t *sih = pi->sih;
-	sbpcieregs_t *pcieregs = pi->regs.pcieregs;
-
-	if (!PCIE_PUB(sih) || sih->buscorerev < 7)
-		return;
-
-	w = pcie_readreg(pcieregs, PCIE_PCIEREGS, PCIE_DLLP_PMTHRESHREG);
-	if (extend)
-		w |= PCIE_ASPMTIMER_EXTEND;
-	else
-		w &= ~PCIE_ASPMTIMER_EXTEND;
-	pcie_writereg(pcieregs, PCIE_PCIEREGS, PCIE_DLLP_PMTHRESHREG, w);
-	w = pcie_readreg(pcieregs, PCIE_PCIEREGS, PCIE_DLLP_PMTHRESHREG);
-}
-
-/* centralized clkreq control policy */
-static void pcie_clkreq_upd(pcicore_info_t *pi, uint state)
-{
-	si_t *sih = pi->sih;
-	ASSERT(PCIE_PUB(sih));
-
-	switch (state) {
-	case SI_DOATTACH:
-		if (PCIE_ASPM(sih))
-			pcie_clkreq((void *)pi, 1, 0);
-		break;
-	case SI_PCIDOWN:
-		if (sih->buscorerev == 6) {	/* turn on serdes PLL down */
-			si_corereg(sih, SI_CC_IDX,
-				   offsetof(chipcregs_t, chipcontrol_addr), ~0,
-				   0);
-			si_corereg(sih, SI_CC_IDX,
-				   offsetof(chipcregs_t, chipcontrol_data),
-				   ~0x40, 0);
-		} else if (pi->pcie_pr42767) {
-			pcie_clkreq((void *)pi, 1, 1);
-		}
-		break;
-	case SI_PCIUP:
-		if (sih->buscorerev == 6) {	/* turn off serdes PLL down */
-			si_corereg(sih, SI_CC_IDX,
-				   offsetof(chipcregs_t, chipcontrol_addr), ~0,
-				   0);
-			si_corereg(sih, SI_CC_IDX,
-				   offsetof(chipcregs_t, chipcontrol_data),
-				   ~0x40, 0x40);
-		} else if (PCIE_ASPM(sih)) {	/* disable clkreq */
-			pcie_clkreq((void *)pi, 1, 0);
-		}
-		break;
-	default:
-		ASSERT(0);
-		break;
-	}
-}
-
-/* ***** PCI core WARs ***** */
-/* Done only once at attach time */
-static void pcie_war_polarity(pcicore_info_t *pi)
-{
-	u32 w;
-
-	if (pi->pcie_polarity != 0)
-		return;
-
-	w = pcie_readreg(pi->regs.pcieregs, PCIE_PCIEREGS,
-			 PCIE_PLP_STATUSREG);
-
-	/* Detect the current polarity at attach and force that polarity and
-	 * disable changing the polarity
-	 */
-	if ((w & PCIE_PLP_POLARITYINV_STAT) == 0)
-		pi->pcie_polarity = (SERDES_RX_CTRL_FORCE);
-	else
-		pi->pcie_polarity =
-		    (SERDES_RX_CTRL_FORCE | SERDES_RX_CTRL_POLARITY);
-}
-
-/* enable ASPM and CLKREQ if srom doesn't have it */
-/* Needs to happen when update to shadow SROM is needed
- *   : Coming out of 'standby'/'hibernate'
- *   : If pcie_war_aspm_ovr state changed
- */
-static void pcie_war_aspm_clkreq(pcicore_info_t *pi)
-{
-	sbpcieregs_t *pcieregs = pi->regs.pcieregs;
-	si_t *sih = pi->sih;
-	u16 val16, *reg16;
-	u32 w;
-
-	if (!PCIE_ASPM(sih))
-		return;
-
-	/* bypass this on QT or VSIM */
-	if (!ISSIM_ENAB(sih)) {
-
-		reg16 = &pcieregs->sprom[SRSH_ASPM_OFFSET];
-		val16 = R_REG(reg16);
-
-		val16 &= ~SRSH_ASPM_ENB;
-		if (pi->pcie_war_aspm_ovr == PCIE_ASPM_ENAB)
-			val16 |= SRSH_ASPM_ENB;
-		else if (pi->pcie_war_aspm_ovr == PCIE_ASPM_L1_ENAB)
-			val16 |= SRSH_ASPM_L1_ENB;
-		else if (pi->pcie_war_aspm_ovr == PCIE_ASPM_L0s_ENAB)
-			val16 |= SRSH_ASPM_L0s_ENB;
-
-		W_REG(reg16, val16);
-
-		pci_read_config_dword(pi->dev, pi->pciecap_lcreg_offset,
-					&w);
-		w &= ~PCIE_ASPM_ENAB;
-		w |= pi->pcie_war_aspm_ovr;
-		pci_write_config_dword(pi->dev,
-					pi->pciecap_lcreg_offset, w);
-	}
-
-	reg16 = &pcieregs->sprom[SRSH_CLKREQ_OFFSET_REV5];
-	val16 = R_REG(reg16);
-
-	if (pi->pcie_war_aspm_ovr != PCIE_ASPM_DISAB) {
-		val16 |= SRSH_CLKREQ_ENB;
-		pi->pcie_pr42767 = true;
-	} else
-		val16 &= ~SRSH_CLKREQ_ENB;
-
-	W_REG(reg16, val16);
-}
-
-/* Apply the polarity determined at the start */
-/* Needs to happen when coming out of 'standby'/'hibernate' */
-static void pcie_war_serdes(pcicore_info_t *pi)
-{
-	u32 w = 0;
-
-	if (pi->pcie_polarity != 0)
-		pcie_mdiowrite(pi, MDIODATA_DEV_RX, SERDES_RX_CTRL,
-			       pi->pcie_polarity);
-
-	pcie_mdioread(pi, MDIODATA_DEV_PLL, SERDES_PLL_CTRL, &w);
-	if (w & PLL_CTRL_FREQDET_EN) {
-		w &= ~PLL_CTRL_FREQDET_EN;
-		pcie_mdiowrite(pi, MDIODATA_DEV_PLL, SERDES_PLL_CTRL, w);
-	}
-}
-
-/* Fix MISC config to allow coming out of L2/L3-Ready state w/o PRST */
-/* Needs to happen when coming out of 'standby'/'hibernate' */
-static void pcie_misc_config_fixup(pcicore_info_t *pi)
-{
-	sbpcieregs_t *pcieregs = pi->regs.pcieregs;
-	u16 val16, *reg16;
-
-	reg16 = &pcieregs->sprom[SRSH_PCIE_MISC_CONFIG];
-	val16 = R_REG(reg16);
-
-	if ((val16 & SRSH_L23READY_EXIT_NOPERST) == 0) {
-		val16 |= SRSH_L23READY_EXIT_NOPERST;
-		W_REG(reg16, val16);
-	}
-}
-
-/* quick hack for testing */
-/* Needs to happen when coming out of 'standby'/'hibernate' */
-static void pcie_war_noplldown(pcicore_info_t *pi)
-{
-	sbpcieregs_t *pcieregs = pi->regs.pcieregs;
-	u16 *reg16;
-
-	ASSERT(pi->sih->buscorerev == 7);
-
-	/* turn off serdes PLL down */
-	si_corereg(pi->sih, SI_CC_IDX, offsetof(chipcregs_t, chipcontrol),
-		   CHIPCTRL_4321_PLL_DOWN, CHIPCTRL_4321_PLL_DOWN);
-
-	/*  clear srom shadow backdoor */
-	reg16 = &pcieregs->sprom[SRSH_BD_OFFSET];
-	W_REG(reg16, 0);
-}
-
-/* Needs to happen when coming out of 'standby'/'hibernate' */
-static void pcie_war_pci_setup(pcicore_info_t *pi)
-{
-	si_t *sih = pi->sih;
-	sbpcieregs_t *pcieregs = pi->regs.pcieregs;
-	u32 w;
-
-	if ((sih->buscorerev == 0) || (sih->buscorerev == 1)) {
-		w = pcie_readreg(pcieregs, PCIE_PCIEREGS,
-				 PCIE_TLP_WORKAROUNDSREG);
-		w |= 0x8;
-		pcie_writereg(pcieregs, PCIE_PCIEREGS,
-			      PCIE_TLP_WORKAROUNDSREG, w);
-	}
-
-	if (sih->buscorerev == 1) {
-		w = pcie_readreg(pcieregs, PCIE_PCIEREGS, PCIE_DLLP_LCREG);
-		w |= (0x40);
-		pcie_writereg(pcieregs, PCIE_PCIEREGS, PCIE_DLLP_LCREG, w);
-	}
-
-	if (sih->buscorerev == 0) {
-		pcie_mdiowrite(pi, MDIODATA_DEV_RX, SERDES_RX_TIMER1, 0x8128);
-		pcie_mdiowrite(pi, MDIODATA_DEV_RX, SERDES_RX_CDR, 0x0100);
-		pcie_mdiowrite(pi, MDIODATA_DEV_RX, SERDES_RX_CDRBW, 0x1466);
-	} else if (PCIE_ASPM(sih)) {
-		/* Change the L1 threshold for better performance */
-		w = pcie_readreg(pcieregs, PCIE_PCIEREGS,
-				 PCIE_DLLP_PMTHRESHREG);
-		w &= ~(PCIE_L1THRESHOLDTIME_MASK);
-		w |= (PCIE_L1THRESHOLD_WARVAL << PCIE_L1THRESHOLDTIME_SHIFT);
-		pcie_writereg(pcieregs, PCIE_PCIEREGS,
-			      PCIE_DLLP_PMTHRESHREG, w);
-
-		pcie_war_serdes(pi);
-
-		pcie_war_aspm_clkreq(pi);
-	} else if (pi->sih->buscorerev == 7)
-		pcie_war_noplldown(pi);
-
-	/* Note that the fix is actually in the SROM, that's why this is open-ended */
-	if (pi->sih->buscorerev >= 6)
-		pcie_misc_config_fixup(pi);
-}
-
-void pcie_war_ovr_aspm_update(void *pch, u8 aspm)
-{
-	pcicore_info_t *pi = (pcicore_info_t *) pch;
-
-	if (!PCIE_ASPM(pi->sih))
-		return;
-
-	/* Validate */
-	if (aspm > PCIE_ASPM_ENAB)
-		return;
-
-	pi->pcie_war_aspm_ovr = aspm;
-
-	/* Update the current state */
-	pcie_war_aspm_clkreq(pi);
-}
-
-/* ***** Functions called during driver state changes ***** */
-void pcicore_attach(void *pch, char *pvars, int state)
-{
-	pcicore_info_t *pi = (pcicore_info_t *) pch;
-	si_t *sih = pi->sih;
-
-	/* Determine if this board needs override */
-	if (PCIE_ASPM(sih)) {
-		if ((u32) getintvar(pvars, "boardflags2") & BFL2_PCIEWAR_OVR) {
-			pi->pcie_war_aspm_ovr = PCIE_ASPM_DISAB;
-		} else {
-			pi->pcie_war_aspm_ovr = PCIE_ASPM_ENAB;
-		}
-	}
-
-	/* These need to happen in this order only */
-	pcie_war_polarity(pi);
-
-	pcie_war_serdes(pi);
-
-	pcie_war_aspm_clkreq(pi);
-
-	pcie_clkreq_upd(pi, state);
-
-}
-
-void pcicore_hwup(void *pch)
-{
-	pcicore_info_t *pi = (pcicore_info_t *) pch;
-
-	if (!pi || !PCIE_PUB(pi->sih))
-		return;
-
-	pcie_war_pci_setup(pi);
-}
-
-void pcicore_up(void *pch, int state)
-{
-	pcicore_info_t *pi = (pcicore_info_t *) pch;
-
-	if (!pi || !PCIE_PUB(pi->sih))
-		return;
-
-	/* Restore L1 timer for better performance */
-	pcie_extendL1timer(pi, true);
-
-	pcie_clkreq_upd(pi, state);
-}
-
-/* When the device is going to enter D3 state (or the system is going to enter S3/S4 states */
-void pcicore_sleep(void *pch)
-{
-	pcicore_info_t *pi = (pcicore_info_t *) pch;
-	u32 w;
-
-	if (!pi || !PCIE_ASPM(pi->sih))
-		return;
-
-	pci_read_config_dword(pi->dev, pi->pciecap_lcreg_offset, &w);
-	w &= ~PCIE_CAP_LCREG_ASPML1;
-	pci_write_config_dword(pi->dev, pi->pciecap_lcreg_offset, w);
-
-	pi->pcie_pr42767 = false;
-}
-
-void pcicore_down(void *pch, int state)
-{
-	pcicore_info_t *pi = (pcicore_info_t *) pch;
-
-	if (!pi || !PCIE_PUB(pi->sih))
-		return;
-
-	pcie_clkreq_upd(pi, state);
-
-	/* Reduce L1 timer for better power savings */
-	pcie_extendL1timer(pi, false);
-}
-
-/* ***** Wake-on-wireless-LAN (WOWL) support functions ***** */
-/* Just uses PCI config accesses to find out, when needed before sb_attach is done */
-bool pcicore_pmecap_fast(void *pch)
-{
-	pcicore_info_t *pi = (pcicore_info_t *) pch;
-	u8 cap_ptr;
-	u32 pmecap;
-
-	cap_ptr =
-	    pcicore_find_pci_capability(pi->dev, PCI_CAP_POWERMGMTCAP_ID, NULL,
-					NULL);
-
-	if (!cap_ptr)
-		return false;
-
-	pci_read_config_dword(pi->dev, cap_ptr, &pmecap);
-
-	return (pmecap & PME_CAP_PM_STATES) != 0;
-}
-
-/* return true if PM capability exists in the pci config space
- * Uses and caches the information using core handle
- */
-static bool pcicore_pmecap(pcicore_info_t *pi)
-{
-	u8 cap_ptr;
-	u32 pmecap;
-
-	if (!pi->pmecap_offset) {
-		cap_ptr =
-		    pcicore_find_pci_capability(pi->dev,
-						PCI_CAP_POWERMGMTCAP_ID, NULL,
-						NULL);
-		if (!cap_ptr)
-			return false;
-
-		pi->pmecap_offset = cap_ptr;
-
-		pci_read_config_dword(pi->dev, pi->pmecap_offset,
-					&pmecap);
-
-		/* At least one state can generate PME */
-		pi->pmecap = (pmecap & PME_CAP_PM_STATES) != 0;
-	}
-
-	return pi->pmecap;
-}
-
-/* Enable PME generation */
-void pcicore_pmeen(void *pch)
-{
-	pcicore_info_t *pi = (pcicore_info_t *) pch;
-	u32 w;
-
-	/* if not pmecapable return */
-	if (!pcicore_pmecap(pi))
-		return;
-
-	pci_read_config_dword(pi->dev, pi->pmecap_offset + PME_CSR_OFFSET,
-				&w);
-	w |= (PME_CSR_PME_EN);
-	pci_write_config_dword(pi->dev,
-				pi->pmecap_offset + PME_CSR_OFFSET, w);
-}
-
-/*
- * Return true if PME status set
- */
-bool pcicore_pmestat(void *pch)
-{
-	pcicore_info_t *pi = (pcicore_info_t *) pch;
-	u32 w;
-
-	if (!pcicore_pmecap(pi))
-		return false;
-
-	pci_read_config_dword(pi->dev, pi->pmecap_offset + PME_CSR_OFFSET,
-				&w);
-
-	return (w & PME_CSR_PME_STAT) == PME_CSR_PME_STAT;
-}
-
-/* Disable PME generation, clear the PME status bit if set
- */
-void pcicore_pmeclr(void *pch)
-{
-	pcicore_info_t *pi = (pcicore_info_t *) pch;
-	u32 w;
-
-	if (!pcicore_pmecap(pi))
-		return;
-
-	pci_read_config_dword(pi->dev, pi->pmecap_offset + PME_CSR_OFFSET,
-				&w);
-
-	PCI_ERROR(("pcicore_pci_pmeclr PMECSR : 0x%x\n", w));
-
-	/* PMESTAT is cleared by writing 1 to it */
-	w &= ~(PME_CSR_PME_EN);
-
-	pci_write_config_dword(pi->dev,
-				pi->pmecap_offset + PME_CSR_OFFSET, w);
-}
-
-u32 pcie_lcreg(void *pch, u32 mask, u32 val)
-{
-	pcicore_info_t *pi = (pcicore_info_t *) pch;
-	u8 offset;
-	u32 tmpval;
-
-	offset = pi->pciecap_lcreg_offset;
-	if (!offset)
-		return 0;
-
-	/* set operation */
-	if (mask)
-		pci_write_config_dword(pi->dev, offset, val);
-
-	pci_read_config_dword(pi->dev, offset, &tmpval);
-	return tmpval;
-}
-
-u32
-pcicore_pciereg(void *pch, u32 offset, u32 mask, u32 val, uint type)
-{
-	u32 reg_val = 0;
-	pcicore_info_t *pi = (pcicore_info_t *) pch;
-	sbpcieregs_t *pcieregs = pi->regs.pcieregs;
-
-	if (mask) {
-		PCI_ERROR(("PCIEREG: 0x%x writeval  0x%x\n", offset, val));
-		pcie_writereg(pcieregs, type, offset, val);
-	}
-
-	/* Should not read register 0x154 */
-	if (pi->sih->buscorerev <= 5 && offset == PCIE_DLLP_PCIE11
-	    && type == PCIE_PCIEREGS)
-		return reg_val;
-
-	reg_val = pcie_readreg(pcieregs, type, offset);
-	PCI_ERROR(("PCIEREG: 0x%x readval is 0x%x\n", offset, reg_val));
-
-	return reg_val;
-}
-
-u32
-pcicore_pcieserdesreg(void *pch, u32 mdioslave, u32 offset, u32 mask,
-		      u32 val)
-{
-	u32 reg_val = 0;
-	pcicore_info_t *pi = (pcicore_info_t *) pch;
-
-	if (mask) {
-		PCI_ERROR(("PCIEMDIOREG: 0x%x writeval  0x%x\n", offset, val));
-		pcie_mdiowrite(pi, mdioslave, offset, val);
-	}
-
-	if (pcie_mdioread(pi, mdioslave, offset, &reg_val))
-		reg_val = 0xFFFFFFFF;
-	PCI_ERROR(("PCIEMDIOREG: dev 0x%x offset 0x%x read 0x%x\n", mdioslave,
-		   offset, reg_val));
-
-	return reg_val;
-}
diff -druN linux-2.6.39-libre/drivers/staging/brcm80211/util/nvram/nvram_ro.c linux-3.0-rc7-libre/drivers/staging/brcm80211/util/nvram/nvram_ro.c
--- linux-2.6.39-libre/drivers/staging/brcm80211/util/nvram/nvram_ro.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/brcm80211/util/nvram/nvram_ro.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,207 +0,0 @@
-/*
- * Copyright (c) 2010 Broadcom Corporation
- *
- * 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 <linux/string.h>
-#include <bcmdefs.h>
-#include <bcmutils.h>
-#include <siutils.h>
-#include <bcmnvram.h>
-#include <sbchipc.h>
-#include <bcmsrom.h>
-#include <bcmotp.h>
-#include <bcmdevs.h>
-#include <hndsoc.h>
-
-#define NVR_MSG(x)
-
-typedef struct _vars {
-	struct _vars *next;
-	int bufsz;		/* allocated size */
-	int size;		/* actual vars size */
-	char *vars;
-} vars_t;
-
-#define	VARS_T_OH	sizeof(vars_t)
-
-static vars_t *vars;
-
-#define NVRAM_FILE	1
-
-static char *findvar(char *vars, char *lim, const char *name);
-
-#if defined(FLASH)
-/* copy flash to ram */
-static void get_flash_nvram(si_t *sih, struct nvram_header *nvh)
-{
-	uint nvs, bufsz;
-	vars_t *new;
-
-	nvs = R_REG(&nvh->len) - sizeof(struct nvram_header);
-	bufsz = nvs + VARS_T_OH;
-
-	new = kmalloc(bufsz, GFP_ATOMIC);
-	if (new == NULL) {
-		NVR_MSG(("Out of memory for flash vars\n"));
-		return;
-	}
-	new->vars = (char *)new + VARS_T_OH;
-
-	new->bufsz = bufsz;
-	new->size = nvs;
-	new->next = vars;
-	vars = new;
-
-	memcpy(new->vars, &nvh[1], nvs);
-
-	NVR_MSG(("%s: flash nvram @ %p, copied %d bytes to %p\n", __func__,
-		 nvh, nvs, new->vars));
-}
-#endif				/* FLASH */
-
-int nvram_init(void *si)
-{
-
-	/* Make sure we read nvram in flash just once before freeing the memory */
-	if (vars != NULL) {
-		NVR_MSG(("nvram_init: called again without calling nvram_exit()\n"));
-		return 0;
-	}
-	return 0;
-}
-
-int nvram_append(void *si, char *varlst, uint varsz)
-{
-	uint bufsz = VARS_T_OH;
-	vars_t *new;
-
-	new = kmalloc(bufsz, GFP_ATOMIC);
-	if (new == NULL)
-		return BCME_NOMEM;
-
-	new->vars = varlst;
-	new->bufsz = bufsz;
-	new->size = varsz;
-	new->next = vars;
-	vars = new;
-
-	return BCME_OK;
-}
-
-void nvram_exit(void *si)
-{
-	vars_t *this, *next;
-	si_t *sih;
-
-	sih = (si_t *) si;
-	this = vars;
-
-	if (this)
-		kfree(this->vars);
-
-	while (this) {
-		next = this->next;
-		kfree(this);
-		this = next;
-	}
-	vars = NULL;
-}
-
-static char *findvar(char *vars, char *lim, const char *name)
-{
-	char *s;
-	int len;
-
-	len = strlen(name);
-
-	for (s = vars; (s < lim) && *s;) {
-		if ((memcmp(s, name, len) == 0) && (s[len] == '='))
-			return &s[len + 1];
-
-		while (*s++)
-			;
-	}
-
-	return NULL;
-}
-
-char *nvram_get(const char *name)
-{
-	char *v = NULL;
-	vars_t *cur;
-
-	for (cur = vars; cur; cur = cur->next) {
-		v = findvar(cur->vars, cur->vars + cur->size, name);
-		if (v)
-			break;
-	}
-
-	return v;
-}
-
-int nvram_set(const char *name, const char *value)
-{
-	return 0;
-}
-
-int nvram_unset(const char *name)
-{
-	return 0;
-}
-
-int nvram_reset(void *si)
-{
-	return 0;
-}
-
-int nvram_commit(void)
-{
-	return 0;
-}
-
-int nvram_getall(char *buf, int count)
-{
-	int len, resid = count;
-	vars_t *this;
-
-	this = vars;
-	while (this) {
-		char *from, *lim, *to;
-		int acc;
-
-		from = this->vars;
-		lim = (char *)(this->vars + this->size);
-		to = buf;
-		acc = 0;
-		while ((from < lim) && (*from)) {
-			len = strlen(from) + 1;
-			if (resid < (acc + len))
-				return BCME_BUFTOOSHORT;
-			memcpy(to, from, len);
-			acc += len;
-			from += len;
-			to += len;
-		}
-
-		resid -= acc;
-		buf += acc;
-		this = this->next;
-	}
-	if (resid < 1)
-		return BCME_BUFTOOSHORT;
-	*buf = '\0';
-	return 0;
-}
diff -druN linux-2.6.39-libre/drivers/staging/brcm80211/util/pci_core.h linux-3.0-rc7-libre/drivers/staging/brcm80211/util/pci_core.h
--- linux-2.6.39-libre/drivers/staging/brcm80211/util/pci_core.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/brcm80211/util/pci_core.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,122 +0,0 @@
-/*
- * Copyright (c) 2010 Broadcom Corporation
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#ifndef	_PCI_CORE_H_
-#define	_PCI_CORE_H_
-
-#ifndef _LANGUAGE_ASSEMBLY
-
-/* cpp contortions to concatenate w/arg prescan */
-#ifndef PAD
-#define	_PADLINE(line)	pad ## line
-#define	_XSTR(line)	_PADLINE(line)
-#define	PAD		_XSTR(__LINE__)
-#endif
-
-/* Sonics side: PCI core and host control registers */
-struct sbpciregs {
-	u32 control;		/* PCI control */
-	u32 PAD[3];
-	u32 arbcontrol;	/* PCI arbiter control */
-	u32 clkrun;		/* Clkrun Control (>=rev11) */
-	u32 PAD[2];
-	u32 intstatus;	/* Interrupt status */
-	u32 intmask;		/* Interrupt mask */
-	u32 sbtopcimailbox;	/* Sonics to PCI mailbox */
-	u32 PAD[9];
-	u32 bcastaddr;	/* Sonics broadcast address */
-	u32 bcastdata;	/* Sonics broadcast data */
-	u32 PAD[2];
-	u32 gpioin;		/* ro: gpio input (>=rev2) */
-	u32 gpioout;		/* rw: gpio output (>=rev2) */
-	u32 gpioouten;	/* rw: gpio output enable (>= rev2) */
-	u32 gpiocontrol;	/* rw: gpio control (>= rev2) */
-	u32 PAD[36];
-	u32 sbtopci0;	/* Sonics to PCI translation 0 */
-	u32 sbtopci1;	/* Sonics to PCI translation 1 */
-	u32 sbtopci2;	/* Sonics to PCI translation 2 */
-	u32 PAD[189];
-	u32 pcicfg[4][64];	/* 0x400 - 0x7FF, PCI Cfg Space (>=rev8) */
-	u16 sprom[36];	/* SPROM shadow Area */
-	u32 PAD[46];
-};
-
-#endif				/* _LANGUAGE_ASSEMBLY */
-
-/* PCI control */
-#define PCI_RST_OE	0x01	/* When set, drives PCI_RESET out to pin */
-#define PCI_RST		0x02	/* Value driven out to pin */
-#define PCI_CLK_OE	0x04	/* When set, drives clock as gated by PCI_CLK out to pin */
-#define PCI_CLK		0x08	/* Gate for clock driven out to pin */
-
-/* PCI arbiter control */
-#define PCI_INT_ARB	0x01	/* When set, use an internal arbiter */
-#define PCI_EXT_ARB	0x02	/* When set, use an external arbiter */
-/* ParkID - for PCI corerev >= 8 */
-#define PCI_PARKID_MASK		0x1c	/* Selects which agent is parked on an idle bus */
-#define PCI_PARKID_SHIFT	2
-#define PCI_PARKID_EXT0		0	/* External master 0 */
-#define PCI_PARKID_EXT1		1	/* External master 1 */
-#define PCI_PARKID_EXT2		2	/* External master 2 */
-#define PCI_PARKID_EXT3		3	/* External master 3 (rev >= 11) */
-#define PCI_PARKID_INT		3	/* Internal master (rev < 11) */
-#define PCI11_PARKID_INT	4	/* Internal master (rev >= 11) */
-#define PCI_PARKID_LAST		4	/* Last active master (rev < 11) */
-#define PCI11_PARKID_LAST	5	/* Last active master (rev >= 11) */
-
-#define PCI_CLKRUN_DSBL	0x8000	/* Bit 15 forceClkrun */
-
-/* Interrupt status/mask */
-#define PCI_INTA	0x01	/* PCI INTA# is asserted */
-#define PCI_INTB	0x02	/* PCI INTB# is asserted */
-#define PCI_SERR	0x04	/* PCI SERR# has been asserted (write one to clear) */
-#define PCI_PERR	0x08	/* PCI PERR# has been asserted (write one to clear) */
-#define PCI_PME		0x10	/* PCI PME# is asserted */
-
-/* (General) PCI/SB mailbox interrupts, two bits per pci function */
-#define	MAILBOX_F0_0	0x100	/* function 0, int 0 */
-#define	MAILBOX_F0_1	0x200	/* function 0, int 1 */
-#define	MAILBOX_F1_0	0x400	/* function 1, int 0 */
-#define	MAILBOX_F1_1	0x800	/* function 1, int 1 */
-#define	MAILBOX_F2_0	0x1000	/* function 2, int 0 */
-#define	MAILBOX_F2_1	0x2000	/* function 2, int 1 */
-#define	MAILBOX_F3_0	0x4000	/* function 3, int 0 */
-#define	MAILBOX_F3_1	0x8000	/* function 3, int 1 */
-
-/* Sonics broadcast address */
-#define BCAST_ADDR_MASK	0xff	/* Broadcast register address */
-
-/* Sonics to PCI translation types */
-#define SBTOPCI0_MASK	0xfc000000
-#define SBTOPCI1_MASK	0xfc000000
-#define SBTOPCI2_MASK	0xc0000000
-#define SBTOPCI_MEM	0
-#define SBTOPCI_IO	1
-#define SBTOPCI_CFG0	2
-#define SBTOPCI_CFG1	3
-#define	SBTOPCI_PREF	0x4	/* prefetch enable */
-#define	SBTOPCI_BURST	0x8	/* burst enable */
-#define	SBTOPCI_RC_MASK		0x30	/* read command (>= rev11) */
-#define	SBTOPCI_RC_READ		0x00	/* memory read */
-#define	SBTOPCI_RC_READLINE	0x10	/* memory read line */
-#define	SBTOPCI_RC_READMULTI	0x20	/* memory read multiple */
-
-/* PCI core index in SROM shadow area */
-#define SRSH_PI_OFFSET	0	/* first word */
-#define SRSH_PI_MASK	0xf000	/* bit 15:12 */
-#define SRSH_PI_SHIFT	12	/* bit 15:12 */
-
-#endif				/* _PCI_CORE_H_ */
diff -druN linux-2.6.39-libre/drivers/staging/brcm80211/util/qmath.c linux-3.0-rc7-libre/drivers/staging/brcm80211/util/qmath.c
--- linux-2.6.39-libre/drivers/staging/brcm80211/util/qmath.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/brcm80211/util/qmath.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,681 +0,0 @@
-/*
- * Copyright (c) 2010 Broadcom Corporation
- *
- * 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/types.h>
-#include "qmath.h"
-
-/*
-Description: This function saturate input 32 bit number into a 16 bit number.
-If input number is greater than 0x7fff then output is saturated to 0x7fff.
-else if input number is less than 0xffff8000 then output is saturated to 0xffff8000
-else output is same as input.
-*/
-s16 qm_sat32(s32 op)
-{
-	s16 result;
-	if (op > (s32) 0x7fff) {
-		result = 0x7fff;
-	} else if (op < (s32) 0xffff8000) {
-		result = (s16) (0x8000);
-	} else {
-		result = (s16) op;
-	}
-	return result;
-}
-
-/*
-Description: This function multiply two input 16 bit numbers and return the 32 bit result.
-This multiplication is similar to compiler multiplication. This operation is defined if
-16 bit multiplication on the processor platform is cheaper than 32 bit multiplication (as
-the most of qmath functions can be replaced with processor intrinsic instructions).
-*/
-s32 qm_mul321616(s16 op1, s16 op2)
-{
-	return (s32) (op1) * (s32) (op2);
-}
-
-/*
-Description: This function make 16 bit multiplication and return the result in 16 bits.
-To fit the result into 16 bits the 32 bit multiplication result is right
-shifted by 16 bits.
-*/
-s16 qm_mul16(s16 op1, s16 op2)
-{
-	s32 result;
-	result = ((s32) (op1) * (s32) (op2));
-	return (s16) (result >> 16);
-}
-
-/*
-Description: This function multiply two 16 bit numbers and return the result in 32 bits.
-This function remove the extra sign bit created by the multiplication by leftshifting the
-32 bit multiplication result by 1 bit before returning the result. So the output is
-twice that of compiler multiplication. (i.e. qm_muls321616(2,3)=12).
-When both input 16 bit numbers are 0x8000, then the result is saturated to 0x7fffffff.
-*/
-s32 qm_muls321616(s16 op1, s16 op2)
-{
-	s32 result;
-	if (op1 == (s16) (0x8000) && op2 == (s16) (0x8000)) {
-		result = 0x7fffffff;
-	} else {
-		result = ((s32) (op1) * (s32) (op2));
-		result = result << 1;
-	}
-	return result;
-}
-
-/*
-Description: This function make 16 bit unsigned multiplication. To fit the output into
-16 bits the 32 bit multiplication result is right shifted by 16 bits.
-*/
-u16 qm_mulu16(u16 op1, u16 op2)
-{
-	return (u16) (((u32) op1 * (u32) op2) >> 16);
-}
-
-/*
-Description: This function make 16 bit multiplication and return the result in 16 bits.
-To fit the multiplication result into 16 bits the multiplication result is right shifted by
-15 bits. Right shifting 15 bits instead of 16 bits is done to remove the extra sign bit formed
-due to the multiplication.
-When both the 16bit inputs are 0x8000 then the output is saturated to 0x7fffffff.
-*/
-s16 qm_muls16(s16 op1, s16 op2)
-{
-	s32 result;
-	if (op1 == (s16) 0x8000 && op2 == (s16) 0x8000) {
-		result = 0x7fffffff;
-	} else {
-		result = ((s32) (op1) * (s32) (op2));
-	}
-	return (s16) (result >> 15);
-}
-
-/*
-Description: This function add two 32 bit numbers and return the 32bit result.
-If the result overflow 32 bits, the output will be saturated to 32bits.
-*/
-s32 qm_add32(s32 op1, s32 op2)
-{
-	s32 result;
-	result = op1 + op2;
-	if (op1 < 0 && op2 < 0 && result > 0) {
-		result = 0x80000000;
-	} else if (op1 > 0 && op2 > 0 && result < 0) {
-		result = 0x7fffffff;
-	}
-	return result;
-}
-
-/*
-Description: This function add two 16 bit numbers and return the 16bit result.
-If the result overflow 16 bits, the output will be saturated to 16bits.
-*/
-s16 qm_add16(s16 op1, s16 op2)
-{
-	s16 result;
-	s32 temp = (s32) op1 + (s32) op2;
-	if (temp > (s32) 0x7fff) {
-		result = (s16) 0x7fff;
-	} else if (temp < (s32) 0xffff8000) {
-		result = (s16) 0xffff8000;
-	} else {
-		result = (s16) temp;
-	}
-	return result;
-}
-
-/*
-Description: This function make 16 bit subtraction and return the 16bit result.
-If the result overflow 16 bits, the output will be saturated to 16bits.
-*/
-s16 qm_sub16(s16 op1, s16 op2)
-{
-	s16 result;
-	s32 temp = (s32) op1 - (s32) op2;
-	if (temp > (s32) 0x7fff) {
-		result = (s16) 0x7fff;
-	} else if (temp < (s32) 0xffff8000) {
-		result = (s16) 0xffff8000;
-	} else {
-		result = (s16) temp;
-	}
-	return result;
-}
-
-/*
-Description: This function make 32 bit subtraction and return the 32bit result.
-If the result overflow 32 bits, the output will be saturated to 32bits.
-*/
-s32 qm_sub32(s32 op1, s32 op2)
-{
-	s32 result;
-	result = op1 - op2;
-	if (op1 >= 0 && op2 < 0 && result < 0) {
-		result = 0x7fffffff;
-	} else if (op1 < 0 && op2 > 0 && result > 0) {
-		result = 0x80000000;
-	}
-	return result;
-}
-
-/*
-Description: This function multiply input 16 bit numbers and accumulate the result
-into the input 32 bit number and return the 32 bit accumulated result.
-If the accumulation result in overflow, then the output will be saturated.
-*/
-s32 qm_mac321616(s32 acc, s16 op1, s16 op2)
-{
-	s32 result;
-	result = qm_add32(acc, qm_mul321616(op1, op2));
-	return result;
-}
-
-/*
-Description: This function make a 32 bit saturated left shift when the specified shift
-is +ve. This function will make a 32 bit right shift when the specified shift is -ve.
-This function return the result after shifting operation.
-*/
-s32 qm_shl32(s32 op, int shift)
-{
-	int i;
-	s32 result;
-	result = op;
-	if (shift > 31)
-		shift = 31;
-	else if (shift < -31)
-		shift = -31;
-	if (shift >= 0) {
-		for (i = 0; i < shift; i++) {
-			result = qm_add32(result, result);
-		}
-	} else {
-		result = result >> (-shift);
-	}
-	return result;
-}
-
-/*
-Description: This function make a 32 bit right shift when shift is +ve.
-This function make a 32 bit saturated left shift when shift is -ve. This function
-return the result of the shift operation.
-*/
-s32 qm_shr32(s32 op, int shift)
-{
-	return qm_shl32(op, -shift);
-}
-
-/*
-Description: This function make a 16 bit saturated left shift when the specified shift
-is +ve. This function will make a 16 bit right shift when the specified shift is -ve.
-This function return the result after shifting operation.
-*/
-s16 qm_shl16(s16 op, int shift)
-{
-	int i;
-	s16 result;
-	result = op;
-	if (shift > 15)
-		shift = 15;
-	else if (shift < -15)
-		shift = -15;
-	if (shift > 0) {
-		for (i = 0; i < shift; i++) {
-			result = qm_add16(result, result);
-		}
-	} else {
-		result = result >> (-shift);
-	}
-	return result;
-}
-
-/*
-Description: This function make a 16 bit right shift when shift is +ve.
-This function make a 16 bit saturated left shift when shift is -ve. This function
-return the result of the shift operation.
-*/
-s16 qm_shr16(s16 op, int shift)
-{
-	return qm_shl16(op, -shift);
-}
-
-/*
-Description: This function return the number of redundant sign bits in a 16 bit number.
-Example: qm_norm16(0x0080) = 7.
-*/
-s16 qm_norm16(s16 op)
-{
-	u16 u16extraSignBits;
-	if (op == 0) {
-		return 15;
-	} else {
-		u16extraSignBits = 0;
-		while ((op >> 15) == (op >> 14)) {
-			u16extraSignBits++;
-			op = op << 1;
-		}
-	}
-	return u16extraSignBits;
-}
-
-/*
-Description: This function return the number of redundant sign bits in a 32 bit number.
-Example: qm_norm32(0x00000080) = 23
-*/
-s16 qm_norm32(s32 op)
-{
-	u16 u16extraSignBits;
-	if (op == 0) {
-		return 31;
-	} else {
-		u16extraSignBits = 0;
-		while ((op >> 31) == (op >> 30)) {
-			u16extraSignBits++;
-			op = op << 1;
-		}
-	}
-	return u16extraSignBits;
-}
-
-/*
-Description: This function divide two 16 bit unsigned numbers.
-The numerator should be less than denominator. So the quotient is always less than 1.
-This function return the quotient in q.15 format.
-*/
-s16 qm_div_s(s16 num, s16 denom)
-{
-	s16 var_out;
-	s16 iteration;
-	s32 L_num;
-	s32 L_denom;
-	L_num = (num) << 15;
-	L_denom = (denom) << 15;
-	for (iteration = 0; iteration < 15; iteration++) {
-		L_num <<= 1;
-		if (L_num >= L_denom) {
-			L_num = qm_sub32(L_num, L_denom);
-			L_num = qm_add32(L_num, 1);
-		}
-	}
-	var_out = (s16) (L_num & 0x7fff);
-	return var_out;
-}
-
-/*
-Description: This function compute the absolute value of a 16 bit number.
-*/
-s16 qm_abs16(s16 op)
-{
-	if (op < 0) {
-		if (op == (s16) 0xffff8000) {
-			return 0x7fff;
-		} else {
-			return -op;
-		}
-	} else {
-		return op;
-	}
-}
-
-/*
-Description: This function divide two 16 bit numbers.
-The quotient is returned through return value.
-The qformat of the quotient is returned through the pointer (qQuotient) passed
-to this function. The qformat of quotient is adjusted appropriately such that
-the quotient occupies all 16 bits.
-*/
-s16 qm_div16(s16 num, s16 denom, s16 *qQuotient)
-{
-	s16 sign;
-	s16 nNum, nDenom;
-	sign = num ^ denom;
-	num = qm_abs16(num);
-	denom = qm_abs16(denom);
-	nNum = qm_norm16(num);
-	nDenom = qm_norm16(denom);
-	num = qm_shl16(num, nNum - 1);
-	denom = qm_shl16(denom, nDenom);
-	*qQuotient = nNum - 1 - nDenom + 15;
-	if (sign >= 0) {
-		return qm_div_s(num, denom);
-	} else {
-		return -qm_div_s(num, denom);
-	}
-}
-
-/*
-Description: This function compute absolute value of a 32 bit number.
-*/
-s32 qm_abs32(s32 op)
-{
-	if (op < 0) {
-		if (op == (s32) 0x80000000) {
-			return 0x7fffffff;
-		} else {
-			return -op;
-		}
-	} else {
-		return op;
-	}
-}
-
-/*
-Description: This function divide two 32 bit numbers. The division is performed
-by considering only important 16 bits in 32 bit numbers.
-The quotient is returned through return value.
-The qformat of the quotient is returned through the pointer (qquotient) passed
-to this function. The qformat of quotient is adjusted appropriately such that
-the quotient occupies all 16 bits.
-*/
-s16 qm_div163232(s32 num, s32 denom, s16 *qquotient)
-{
-	s32 sign;
-	s16 nNum, nDenom;
-	sign = num ^ denom;
-	num = qm_abs32(num);
-	denom = qm_abs32(denom);
-	nNum = qm_norm32(num);
-	nDenom = qm_norm32(denom);
-	num = qm_shl32(num, nNum - 1);
-	denom = qm_shl32(denom, nDenom);
-	*qquotient = nNum - 1 - nDenom + 15;
-	if (sign >= 0) {
-		return qm_div_s((s16) (num >> 16), (s16) (denom >> 16));
-	} else {
-		return -qm_div_s((s16) (num >> 16), (s16) (denom >> 16));
-	}
-}
-
-/*
-Description: This function multiply a 32 bit number with a 16 bit number.
-The multiplicaton result is right shifted by 16 bits to fit the result
-into 32 bit output.
-*/
-s32 qm_mul323216(s32 op1, s16 op2)
-{
-	s16 hi;
-	u16 lo;
-	s32 result;
-	hi = op1 >> 16;
-	lo = (s16) (op1 & 0xffff);
-	result = qm_mul321616(hi, op2);
-	result = result + (qm_mulsu321616(op2, lo) >> 16);
-	return result;
-}
-
-/*
-Description: This function multiply signed 16 bit number with unsigned 16 bit number and return
-the result in 32 bits.
-*/
-s32 qm_mulsu321616(s16 op1, u16 op2)
-{
-	return (s32) (op1) * op2;
-}
-
-/*
-Description: This function multiply 32 bit number with 16 bit number. The multiplication result is
-right shifted by 15 bits to fit the result into 32 bits. Right shifting by only 15 bits instead of
-16 bits is done to remove the extra sign bit formed by multiplication from the return value.
-When the input numbers are 0x80000000, 0x8000 the return value is saturated to 0x7fffffff.
-*/
-s32 qm_muls323216(s32 op1, s16 op2)
-{
-	s16 hi;
-	u16 lo;
-	s32 result;
-	hi = op1 >> 16;
-	lo = (s16) (op1 & 0xffff);
-	result = qm_muls321616(hi, op2);
-	result = qm_add32(result, (qm_mulsu321616(op2, lo) >> 15));
-	return result;
-}
-
-/*
-Description: This function multiply two 32 bit numbers. The multiplication result is right
-shifted by 32 bits to fit the multiplication result into 32 bits. The right shifted
-multiplication result is returned as output.
-*/
-s32 qm_mul32(s32 a, s32 b)
-{
-	s16 hi1, hi2;
-	u16 lo1, lo2;
-	s32 result;
-	hi1 = a >> 16;
-	hi2 = b >> 16;
-	lo1 = (u16) (a & 0xffff);
-	lo2 = (u16) (b & 0xffff);
-	result = qm_mul321616(hi1, hi2);
-	result = result + (qm_mulsu321616(hi1, lo2) >> 16);
-	result = result + (qm_mulsu321616(hi2, lo1) >> 16);
-	return result;
-}
-
-/*
-Description: This function multiply two 32 bit numbers. The multiplication result is
-right shifted by 31 bits to fit the multiplication result into 32 bits. The right
-shifted multiplication result is returned as output. Right shifting by only 31 bits
-instead of 32 bits is done to remove the extra sign bit formed by multiplication.
-When the input numbers are 0x80000000, 0x80000000 the return value is saturated to
-0x7fffffff.
-*/
-s32 qm_muls32(s32 a, s32 b)
-{
-	s16 hi1, hi2;
-	u16 lo1, lo2;
-	s32 result;
-	hi1 = a >> 16;
-	hi2 = b >> 16;
-	lo1 = (u16) (a & 0xffff);
-	lo2 = (u16) (b & 0xffff);
-	result = qm_muls321616(hi1, hi2);
-	result = qm_add32(result, (qm_mulsu321616(hi1, lo2) >> 15));
-	result = qm_add32(result, (qm_mulsu321616(hi2, lo1) >> 15));
-	result = qm_add32(result, (qm_mulu16(lo1, lo2) >> 15));
-	return result;
-}
-
-/* This table is log2(1+(i/32)) where i=[0:1:31], in q.15 format */
-static const s16 log_table[] = {
-	0,
-	1455,
-	2866,
-	4236,
-	5568,
-	6863,
-	8124,
-	9352,
-	10549,
-	11716,
-	12855,
-	13968,
-	15055,
-	16117,
-	17156,
-	18173,
-	19168,
-	20143,
-	21098,
-	22034,
-	22952,
-	23852,
-	24736,
-	25604,
-	26455,
-	27292,
-	28114,
-	28922,
-	29717,
-	30498,
-	31267,
-	32024
-};
-
-#define LOG_TABLE_SIZE 32	/* log_table size */
-#define LOG2_LOG_TABLE_SIZE 5	/* log2(log_table size) */
-#define Q_LOG_TABLE 15		/* qformat of log_table */
-#define LOG10_2		19728	/* log10(2) in q.16 */
-
-/*
-Description:
-This routine takes the input number N and its q format qN and compute
-the log10(N). This routine first normalizes the input no N.	Then N is in mag*(2^x) format.
-mag is any number in the range 2^30-(2^31 - 1). Then log2(mag * 2^x) = log2(mag) + x is computed.
-From that log10(mag * 2^x) = log2(mag * 2^x) * log10(2) is computed.
-This routine looks the log2 value in the table considering LOG2_LOG_TABLE_SIZE+1 MSBs.
-As the MSB is always 1, only next LOG2_OF_LOG_TABLE_SIZE MSBs are used for table lookup.
-Next 16 MSBs are used for interpolation.
-Inputs:
-N - number to which log10 has to be found.
-qN - q format of N
-log10N - address where log10(N) will be written.
-qLog10N - address where log10N qformat will be written.
-Note/Problem:
-For accurate results input should be in normalized or near normalized form.
-*/
-void qm_log10(s32 N, s16 qN, s16 *log10N, s16 *qLog10N)
-{
-	s16 s16norm, s16tableIndex, s16errorApproximation;
-	u16 u16offset;
-	s32 s32log;
-
-	/* Logerithm of negative values is undefined.
-	 * assert N is greater than 0.
-	 */
-	/* ASSERT(N > 0); */
-
-	/* normalize the N. */
-	s16norm = qm_norm32(N);
-	N = N << s16norm;
-
-	/* The qformat of N after normalization.
-	 * -30 is added to treat the no as between 1.0 to 2.0
-	 * i.e. after adding the -30 to the qformat the decimal point will be
-	 * just rigtht of the MSB. (i.e. after sign bit and 1st MSB). i.e.
-	 * at the right side of 30th bit.
-	 */
-	qN = qN + s16norm - 30;
-
-	/* take the table index as the LOG2_OF_LOG_TABLE_SIZE bits right of the MSB */
-	s16tableIndex = (s16) (N >> (32 - (2 + LOG2_LOG_TABLE_SIZE)));
-
-	/* remove the MSB. the MSB is always 1 after normalization. */
-	s16tableIndex =
-	    s16tableIndex & (s16) ((1 << LOG2_LOG_TABLE_SIZE) - 1);
-
-	/* remove the (1+LOG2_OF_LOG_TABLE_SIZE) MSBs in the N. */
-	N = N & ((1 << (32 - (2 + LOG2_LOG_TABLE_SIZE))) - 1);
-
-	/* take the offset as the 16 MSBS after table index.
-	 */
-	u16offset = (u16) (N >> (32 - (2 + LOG2_LOG_TABLE_SIZE + 16)));
-
-	/* look the log value in the table. */
-	s32log = log_table[s16tableIndex];	/* q.15 format */
-
-	/* interpolate using the offset. */
-	s16errorApproximation = (s16) qm_mulu16(u16offset, (u16) (log_table[s16tableIndex + 1] - log_table[s16tableIndex]));	/* q.15 */
-
-	s32log = qm_add16((s16) s32log, s16errorApproximation);	/* q.15 format */
-
-	/* adjust for the qformat of the N as
-	 * log2(mag * 2^x) = log2(mag) + x
-	 */
-	s32log = qm_add32(s32log, ((s32) -qN) << 15);	/* q.15 format */
-
-	/* normalize the result. */
-	s16norm = qm_norm32(s32log);
-
-	/* bring all the important bits into lower 16 bits */
-	s32log = qm_shl32(s32log, s16norm - 16);	/* q.15+s16norm-16 format */
-
-	/* compute the log10(N) by multiplying log2(N) with log10(2).
-	 * as log10(mag * 2^x) = log2(mag * 2^x) * log10(2)
-	 * log10N in q.15+s16norm-16+1 (LOG10_2 is in q.16)
-	 */
-	*log10N = qm_muls16((s16) s32log, (s16) LOG10_2);
-
-	/* write the q format of the result. */
-	*qLog10N = 15 + s16norm - 16 + 1;
-
-	return;
-}
-
-/*
-Description:
-This routine compute 1/N.
-This routine reformates the given no N as N * 2^qN where N is in between 0.5 and 1.0
-in q.15 format in 16 bits. So the problem now boils down to finding the inverse of a
-q.15 no in 16 bits which is in the range of 0.5 to 1.0. The output is always between
-2.0 to 1. So the output is 2.0 to 1.0 in q.30 format. Once the final output format is found
-by taking the qN into account. Inverse is found with newton rapson method. Initially
-inverse (x) is guessed as 1/0.75 (with appropriate sign). The new guess is calculated
-using the formula x' = 2*x - N*x*x. After 4 or 5 iterations the inverse is very close to
-inverse of N.
-Inputs:
-N - number to which 1/N has to be found.
-qn - q format of N.
-sqrtN - address where 1/N has to be written.
-qsqrtN - address where q format of 1/N has to be written.
-*/
-#define qx 29
-void qm_1byN(s32 N, s16 qN, s32 *result, s16 *qResult)
-{
-	s16 normN;
-	s32 s32firstTerm, s32secondTerm, x;
-	int i;
-
-	normN = qm_norm32(N);
-
-	/* limit N to least significant 16 bits. 15th bit is the sign bit. */
-	N = qm_shl32(N, normN - 16);
-	qN = qN + normN - 16 - 15;
-	/* -15 is added to treat N as 16 bit q.15 number in the range from 0.5 to 1 */
-
-	/* Take the initial guess as 1/0.75 in qx format with appropriate sign. */
-	if (N >= 0) {
-		x = (s32) ((1 / 0.75) * (1 << qx));
-		/* input no is in the range 0.5 to 1. So 1/0.75 is taken as initial guess. */
-	} else {
-		x = (s32) ((1 / -0.75) * (1 << qx));
-		/* input no is in the range -0.5 to -1. So 1/-0.75 is taken as initial guess. */
-	}
-
-	/* iterate the equation x = 2*x - N*x*x for 4 times. */
-	for (i = 0; i < 4; i++) {
-		s32firstTerm = qm_shl32(x, 1);	/* s32firstTerm = 2*x in q.29 */
-		s32secondTerm =
-		    qm_muls321616((s16) (s32firstTerm >> 16),
-				  (s16) (s32firstTerm >> 16));
-		/* s32secondTerm = x*x in q.(29+1-16)*2+1 */
-		s32secondTerm =
-		    qm_muls321616((s16) (s32secondTerm >> 16), (s16) N);
-		/* s32secondTerm = N*x*x in q.((29+1-16)*2+1)-16+15+1 i.e. in q.29 */
-		x = qm_sub32(s32firstTerm, s32secondTerm);
-		/* can be added directly as both are in q.29 */
-	}
-
-	/* Bring the x to q.30 format. */
-	*result = qm_shl32(x, 1);
-	/* giving the output in q.30 format for q.15 input in 16 bits. */
-
-	/* compute the final q format of the result. */
-	*qResult = -qN + 30;	/* adjusting the q format of actual output */
-
-	return;
-}
-
-#undef qx
diff -druN linux-2.6.39-libre/drivers/staging/brcm80211/util/sbpcmcia.h linux-3.0-rc7-libre/drivers/staging/brcm80211/util/sbpcmcia.h
--- linux-2.6.39-libre/drivers/staging/brcm80211/util/sbpcmcia.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/brcm80211/util/sbpcmcia.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,217 +0,0 @@
-/*
- * Copyright (c) 2010 Broadcom Corporation
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#ifndef	_SBPCMCIA_H
-#define	_SBPCMCIA_H
-
-/* All the addresses that are offsets in attribute space are divided
- * by two to account for the fact that odd bytes are invalid in
- * attribute space and our read/write routines make the space appear
- * as if they didn't exist. Still we want to show the original numbers
- * as documented in the hnd_pcmcia core manual.
- */
-
-/* PCMCIA Function Configuration Registers */
-#define	PCMCIA_FCR		(0x700 / 2)
-
-#define	FCR0_OFF		0
-#define	FCR1_OFF		(0x40 / 2)
-#define	FCR2_OFF		(0x80 / 2)
-#define	FCR3_OFF		(0xc0 / 2)
-
-#define	PCMCIA_FCR0		(0x700 / 2)
-#define	PCMCIA_FCR1		(0x740 / 2)
-#define	PCMCIA_FCR2		(0x780 / 2)
-#define	PCMCIA_FCR3		(0x7c0 / 2)
-
-/* Standard PCMCIA FCR registers */
-
-#define	PCMCIA_COR		0
-
-#define	COR_RST			0x80
-#define	COR_LEV			0x40
-#define	COR_IRQEN		0x04
-#define	COR_BLREN		0x01
-#define	COR_FUNEN		0x01
-
-#define	PCICIA_FCSR		(2 / 2)
-#define	PCICIA_PRR		(4 / 2)
-#define	PCICIA_SCR		(6 / 2)
-#define	PCICIA_ESR		(8 / 2)
-
-#define PCM_MEMOFF		0x0000
-#define F0_MEMOFF		0x1000
-#define F1_MEMOFF		0x2000
-#define F2_MEMOFF		0x3000
-#define F3_MEMOFF		0x4000
-
-/* Memory base in the function fcr's */
-#define MEM_ADDR0		(0x728 / 2)
-#define MEM_ADDR1		(0x72a / 2)
-#define MEM_ADDR2		(0x72c / 2)
-
-/* PCMCIA base plus Srom access in fcr0: */
-#define PCMCIA_ADDR0		(0x072e / 2)
-#define PCMCIA_ADDR1		(0x0730 / 2)
-#define PCMCIA_ADDR2		(0x0732 / 2)
-
-#define MEM_SEG			(0x0734 / 2)
-#define SROM_CS			(0x0736 / 2)
-#define SROM_DATAL		(0x0738 / 2)
-#define SROM_DATAH		(0x073a / 2)
-#define SROM_ADDRL		(0x073c / 2)
-#define SROM_ADDRH		(0x073e / 2)
-#define	SROM_INFO2		(0x0772 / 2)	/* Corerev >= 2 && <= 5 */
-#define	SROM_INFO		(0x07be / 2)	/* Corerev >= 6 */
-
-/*  Values for srom_cs: */
-#define SROM_IDLE		0
-#define SROM_WRITE		1
-#define SROM_READ		2
-#define SROM_WEN		4
-#define SROM_WDS		7
-#define SROM_DONE		8
-
-/* Fields in srom_info: */
-#define	SRI_SZ_MASK		0x03
-#define	SRI_BLANK		0x04
-#define	SRI_OTP			0x80
-
-#if !defined(ESTA_POSTMOGRIFY_REMOVAL)
-/* CIS stuff */
-
-/* The CIS stops where the FCRs start */
-#define	CIS_SIZE		PCMCIA_FCR
-
-/* CIS tuple length field max */
-#define CIS_TUPLE_LEN_MAX	0xff
-
-/* Standard tuples we know about */
-
-#define CISTPL_NULL			0x00
-#define	CISTPL_VERS_1		0x15	/* CIS ver, manf, dev & ver strings */
-#define	CISTPL_MANFID		0x20	/* Manufacturer and device id */
-#define CISTPL_FUNCID		0x21	/* Function identification */
-#define	CISTPL_FUNCE		0x22	/* Function extensions */
-#define	CISTPL_CFTABLE		0x1b	/* Config table entry */
-#define	CISTPL_END		0xff	/* End of the CIS tuple chain */
-
-/* Function identifier provides context for the function extensions tuple */
-#define CISTPL_FID_SDIO		0x0c	/* Extensions defined by SDIO spec */
-
-/* Function extensions for LANs (assumed for extensions other than SDIO) */
-#define	LAN_TECH		1	/* Technology type */
-#define	LAN_SPEED		2	/* Raw bit rate */
-#define	LAN_MEDIA		3	/* Transmission media */
-#define	LAN_NID			4	/* Node identification (aka MAC addr) */
-#define	LAN_CONN		5	/* Connector standard */
-
-/* CFTable */
-#define CFTABLE_REGWIN_2K	0x08	/* 2k reg windows size */
-#define CFTABLE_REGWIN_4K	0x10	/* 4k reg windows size */
-#define CFTABLE_REGWIN_8K	0x20	/* 8k reg windows size */
-
-/* Vendor unique tuples are 0x80-0x8f. Within Broadcom we'll
- * take one for HNBU, and use "extensions" (a la FUNCE) within it.
- */
-
-#define	CISTPL_BRCM_HNBU	0x80
-
-/* Subtypes of BRCM_HNBU: */
-
-#define HNBU_SROMREV		0x00	/* A byte with sromrev, 1 if not present */
-#define HNBU_CHIPID		0x01	/* Two 16bit values: PCI vendor & device id */
-#define HNBU_BOARDREV		0x02	/* One byte board revision */
-#define HNBU_PAPARMS		0x03	/* PA parameters: 8 (sromrev == 1)
-					 * or 9 (sromrev > 1) bytes
-					 */
-#define HNBU_OEM		0x04	/* Eight bytes OEM data (sromrev == 1) */
-#define HNBU_CC			0x05	/* Default country code (sromrev == 1) */
-#define	HNBU_AA			0x06	/* Antennas available */
-#define	HNBU_AG			0x07	/* Antenna gain */
-#define HNBU_BOARDFLAGS		0x08	/* board flags (2 or 4 bytes) */
-#define HNBU_LEDS		0x09	/* LED set */
-#define HNBU_CCODE		0x0a	/* Country code (2 bytes ascii + 1 byte cctl)
-					 * in rev 2
-					 */
-#define HNBU_CCKPO		0x0b	/* 2 byte cck power offsets in rev 3 */
-#define HNBU_OFDMPO		0x0c	/* 4 byte 11g ofdm power offsets in rev 3 */
-#define HNBU_GPIOTIMER		0x0d	/* 2 bytes with on/off values in rev 3 */
-#define HNBU_PAPARMS5G		0x0e	/* 5G PA params */
-#define HNBU_ANT5G		0x0f	/* 4328 5G antennas available/gain */
-#define HNBU_RDLID		0x10	/* 2 byte USB remote downloader (RDL) product Id */
-#define HNBU_RSSISMBXA2G	0x11	/* 4328 2G RSSI mid pt sel & board switch arch,
-					 * 2 bytes, rev 3.
-					 */
-#define HNBU_RSSISMBXA5G	0x12	/* 4328 5G RSSI mid pt sel & board switch arch,
-					 * 2 bytes, rev 3.
-					 */
-#define HNBU_XTALFREQ		0x13	/* 4 byte Crystal frequency in kilohertz */
-#define HNBU_TRI2G		0x14	/* 4328 2G TR isolation, 1 byte */
-#define HNBU_TRI5G		0x15	/* 4328 5G TR isolation, 3 bytes */
-#define HNBU_RXPO2G		0x16	/* 4328 2G RX power offset, 1 byte */
-#define HNBU_RXPO5G		0x17	/* 4328 5G RX power offset, 1 byte */
-#define HNBU_BOARDNUM		0x18	/* board serial number, independent of mac addr */
-#define HNBU_MACADDR		0x19	/* mac addr override for the standard CIS LAN_NID */
-#define HNBU_RDLSN		0x1a	/* 2 bytes; serial # advertised in USB descriptor */
-#define HNBU_BOARDTYPE		0x1b	/* 2 bytes; boardtype */
-#define HNBU_LEDDC		0x1c	/* 2 bytes; LED duty cycle */
-#define HNBU_HNBUCIS		0x1d	/* what follows is proprietary HNBU CIS format */
-#define HNBU_PAPARMS_SSLPNPHY	0x1e	/* SSLPNPHY PA params */
-#define HNBU_RSSISMBXA2G_SSLPNPHY 0x1f	/* SSLPNPHY RSSI mid pt sel & board switch arch */
-#define HNBU_RDLRNDIS		0x20	/* 1 byte; 1 = RDL advertises RNDIS config */
-#define HNBU_CHAINSWITCH	0x21	/* 2 byte; txchain, rxchain */
-#define HNBU_REGREV		0x22	/* 1 byte; */
-#define HNBU_FEM		0x23	/* 2 or 4 byte: 11n frontend specification */
-#define HNBU_PAPARMS_C0		0x24	/* 8 or 30 bytes: 11n pa paramater for chain 0 */
-#define HNBU_PAPARMS_C1		0x25	/* 8 or 30 bytes: 11n pa paramater for chain 1 */
-#define HNBU_PAPARMS_C2		0x26	/* 8 or 30 bytes: 11n pa paramater for chain 2 */
-#define HNBU_PAPARMS_C3		0x27	/* 8 or 30 bytes: 11n pa paramater for chain 3 */
-#define HNBU_PO_CCKOFDM		0x28	/* 6 or 18 bytes: cck2g/ofdm2g/ofdm5g power offset */
-#define HNBU_PO_MCS2G		0x29	/* 8 bytes: mcs2g power offset */
-#define HNBU_PO_MCS5GM		0x2a	/* 8 bytes: mcs5g mid band power offset */
-#define HNBU_PO_MCS5GLH		0x2b	/* 16 bytes: mcs5g low-high band power offset */
-#define HNBU_PO_CDD		0x2c	/* 2 bytes: cdd2g/5g power offset */
-#define HNBU_PO_STBC		0x2d	/* 2 bytes: stbc2g/5g power offset */
-#define HNBU_PO_40M		0x2e	/* 2 bytes: 40Mhz channel 2g/5g power offset */
-#define HNBU_PO_40MDUP		0x2f	/* 2 bytes: 40Mhz channel dup 2g/5g power offset */
-
-#define HNBU_RDLRWU		0x30	/* 1 byte; 1 = RDL advertises Remote Wake-up */
-#define HNBU_WPS		0x31	/* 1 byte; GPIO pin for WPS button */
-#define HNBU_USBFS		0x32	/* 1 byte; 1 = USB advertises FS mode only */
-#define HNBU_BRMIN		0x33	/* 4 byte bootloader min resource mask */
-#define HNBU_BRMAX		0x34	/* 4 byte bootloader max resource mask */
-#define HNBU_PATCH		0x35	/* bootloader patch addr(2b) & data(4b) pair */
-#define HNBU_CCKFILTTYPE	0x36	/* CCK digital filter selection options */
-#define HNBU_OFDMPO5G		0x37	/* 4 * 3 = 12 byte 11a ofdm power offsets in rev 3 */
-
-#define HNBU_USBEPNUM		0x40	/* USB endpoint numbers */
-#define HNBU_SROM3SWRGN		0x80	/* 78 bytes; srom rev 3 s/w region without crc8
-					 * plus extra info appended.
-					 */
-#define HNBU_RESERVED		0x81	/* Reserved for non-BRCM post-mfg additions */
-#define HNBU_CUSTOM1		0x82	/* 4 byte; For non-BRCM post-mfg additions */
-#define HNBU_CUSTOM2		0x83	/* Reserved; For non-BRCM post-mfg additions */
-#endif				/* !defined(ESTA_POSTMOGRIFY_REMOVAL) */
-
-/* sbtmstatelow */
-#define SBTML_INT_ACK		0x40000	/* ack the sb interrupt */
-#define SBTML_INT_EN		0x20000	/* enable sb interrupt */
-
-/* sbtmstatehigh */
-#define SBTMH_INT_STATUS	0x40000	/* sb interrupt status */
-
-#endif				/* _SBPCMCIA_H */
diff -druN linux-2.6.39-libre/drivers/staging/brcm80211/util/sbsocram.h linux-3.0-rc7-libre/drivers/staging/brcm80211/util/sbsocram.h
--- linux-2.6.39-libre/drivers/staging/brcm80211/util/sbsocram.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/brcm80211/util/sbsocram.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,175 +0,0 @@
-/*
- * Copyright (c) 2010 Broadcom Corporation
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#ifndef	_SBSOCRAM_H
-#define	_SBSOCRAM_H
-
-#ifndef _LANGUAGE_ASSEMBLY
-
-/* cpp contortions to concatenate w/arg prescan */
-#ifndef PAD
-#define	_PADLINE(line)	pad ## line
-#define	_XSTR(line)	_PADLINE(line)
-#define	PAD		_XSTR(__LINE__)
-#endif				/* PAD */
-
-/* Memcsocram core registers */
-typedef volatile struct sbsocramregs {
-	u32 coreinfo;
-	u32 bwalloc;
-	u32 extracoreinfo;
-	u32 biststat;
-	u32 bankidx;
-	u32 standbyctrl;
-
-	u32 errlogstatus;	/* rev 6 */
-	u32 errlogaddr;	/* rev 6 */
-	/* used for patching rev 3 & 5 */
-	u32 cambankidx;
-	u32 cambankstandbyctrl;
-	u32 cambankpatchctrl;
-	u32 cambankpatchtblbaseaddr;
-	u32 cambankcmdreg;
-	u32 cambankdatareg;
-	u32 cambankmaskreg;
-	u32 PAD[1];
-	u32 bankinfo;	/* corev 8 */
-	u32 PAD[15];
-	u32 extmemconfig;
-	u32 extmemparitycsr;
-	u32 extmemparityerrdata;
-	u32 extmemparityerrcnt;
-	u32 extmemwrctrlandsize;
-	u32 PAD[84];
-	u32 workaround;
-	u32 pwrctl;		/* corerev >= 2 */
-} sbsocramregs_t;
-
-#endif				/* _LANGUAGE_ASSEMBLY */
-
-/* Register offsets */
-#define	SR_COREINFO		0x00
-#define	SR_BWALLOC		0x04
-#define	SR_BISTSTAT		0x0c
-#define	SR_BANKINDEX		0x10
-#define	SR_BANKSTBYCTL		0x14
-#define SR_PWRCTL		0x1e8
-
-/* Coreinfo register */
-#define	SRCI_PT_MASK		0x00070000	/* corerev >= 6; port type[18:16] */
-#define	SRCI_PT_SHIFT		16
-/* port types : SRCI_PT_<processorPT>_<backplanePT> */
-#define SRCI_PT_OCP_OCP		0
-#define SRCI_PT_AXI_OCP		1
-#define SRCI_PT_ARM7AHB_OCP	2
-#define SRCI_PT_CM3AHB_OCP	3
-#define SRCI_PT_AXI_AXI		4
-#define SRCI_PT_AHB_AXI		5
-/* corerev >= 3 */
-#define SRCI_LSS_MASK		0x00f00000
-#define SRCI_LSS_SHIFT		20
-#define SRCI_LRS_MASK		0x0f000000
-#define SRCI_LRS_SHIFT		24
-
-/* In corerev 0, the memory size is 2 to the power of the
- * base plus 16 plus to the contents of the memsize field plus 1.
- */
-#define	SRCI_MS0_MASK		0xf
-#define SR_MS0_BASE		16
-
-/*
- * In corerev 1 the bank size is 2 ^ the bank size field plus 14,
- * the memory size is number of banks times bank size.
- * The same applies to rom size.
- */
-#define	SRCI_ROMNB_MASK		0xf000
-#define	SRCI_ROMNB_SHIFT	12
-#define	SRCI_ROMBSZ_MASK	0xf00
-#define	SRCI_ROMBSZ_SHIFT	8
-#define	SRCI_SRNB_MASK		0xf0
-#define	SRCI_SRNB_SHIFT		4
-#define	SRCI_SRBSZ_MASK		0xf
-#define	SRCI_SRBSZ_SHIFT	0
-
-#define SR_BSZ_BASE		14
-
-/* Standby control register */
-#define	SRSC_SBYOVR_MASK	0x80000000
-#define	SRSC_SBYOVR_SHIFT	31
-#define	SRSC_SBYOVRVAL_MASK	0x60000000
-#define	SRSC_SBYOVRVAL_SHIFT	29
-#define	SRSC_SBYEN_MASK		0x01000000	/* rev >= 3 */
-#define	SRSC_SBYEN_SHIFT	24
-
-/* Power control register */
-#define SRPC_PMU_STBYDIS_MASK	0x00000010	/* rev >= 3 */
-#define SRPC_PMU_STBYDIS_SHIFT	4
-#define SRPC_STBYOVRVAL_MASK	0x00000008
-#define SRPC_STBYOVRVAL_SHIFT	3
-#define SRPC_STBYOVR_MASK	0x00000007
-#define SRPC_STBYOVR_SHIFT	0
-
-/* Extra core capability register */
-#define SRECC_NUM_BANKS_MASK   0x000000F0
-#define SRECC_NUM_BANKS_SHIFT  4
-#define SRECC_BANKSIZE_MASK    0x0000000F
-#define SRECC_BANKSIZE_SHIFT   0
-
-#define SRECC_BANKSIZE(value)	 (1 << (value))
-
-/* CAM bank patch control */
-#define SRCBPC_PATCHENABLE 0x80000000
-
-#define SRP_ADDRESS   0x0001FFFC
-#define SRP_VALID     0x8000
-
-/* CAM bank command reg */
-#define SRCMD_WRITE  0x00020000
-#define SRCMD_READ   0x00010000
-#define SRCMD_DONE   0x80000000
-
-#define SRCMD_DONE_DLY	1000
-
-/* bankidx and bankinfo reg defines corerev >= 8 */
-#define SOCRAM_BANKINFO_SZMASK		0x3f
-#define SOCRAM_BANKIDX_ROM_MASK		0x100
-
-#define SOCRAM_BANKIDX_MEMTYPE_SHIFT	8
-/* socram bankinfo memtype */
-#define SOCRAM_MEMTYPE_RAM		0
-#define SOCRAM_MEMTYPE_R0M		1
-#define SOCRAM_MEMTYPE_DEVRAM		2
-
-#define	SOCRAM_BANKINFO_REG		0x40
-#define	SOCRAM_BANKIDX_REG		0x10
-#define	SOCRAM_BANKINFO_STDBY_MASK	0x400
-#define	SOCRAM_BANKINFO_STDBY_TIMER	0x800
-
-/* bankinfo rev >= 10 */
-#define SOCRAM_BANKINFO_DEVRAMSEL_SHIFT	13
-#define SOCRAM_BANKINFO_DEVRAMSEL_MASK	0x2000
-#define SOCRAM_BANKINFO_DEVRAMPRO_SHIFT	14
-#define SOCRAM_BANKINFO_DEVRAMPRO_MASK	0x4000
-
-/* extracoreinfo register */
-#define SOCRAM_DEVRAMBANK_MASK		0xF000
-#define SOCRAM_DEVRAMBANK_SHIFT		12
-
-/* bank info to calculate bank size */
-#define	SOCRAM_BANKINFO_SZBASE		8192
-#define SOCRAM_BANKSIZE_SHIFT		13	/* SOCRAM_BANKINFO_SZBASE */
-
-#endif				/* _SBSOCRAM_H */
diff -druN linux-2.6.39-libre/drivers/staging/brcm80211/util/sbutils.c linux-3.0-rc7-libre/drivers/staging/brcm80211/util/sbutils.c
--- linux-2.6.39-libre/drivers/staging/brcm80211/util/sbutils.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/brcm80211/util/sbutils.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,476 +0,0 @@
-/*
- * Copyright (c) 2010 Broadcom Corporation
- *
- * 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/types.h>
-#include <bcmdefs.h>
-#ifdef BRCM_FULLMAC
-#include <linux/netdevice.h>
-#endif
-#include <bcmutils.h>
-#include <siutils.h>
-#include <bcmdevs.h>
-#include <hndsoc.h>
-#include <sbchipc.h>
-#include <pci_core.h>
-#include <pcicfg.h>
-#include <sbpcmcia.h>
-#include "siutils_priv.h"
-
-/* local prototypes */
-static uint _sb_coreidx(si_info_t *sii, u32 sba);
-static uint _sb_scan(si_info_t *sii, u32 sba, void *regs, uint bus,
-		     u32 sbba, uint ncores);
-static u32 _sb_coresba(si_info_t *sii);
-static void *_sb_setcoreidx(si_info_t *sii, uint coreidx);
-
-#define	SET_SBREG(sii, r, mask, val)	\
-		W_SBREG((sii), (r), ((R_SBREG((sii), (r)) & ~(mask)) | (val)))
-#define	REGS2SB(va)	(sbconfig_t *) ((s8 *)(va) + SBCONFIGOFF)
-
-/* sonicsrev */
-#define	SONICS_2_2	(SBIDL_RV_2_2 >> SBIDL_RV_SHIFT)
-#define	SONICS_2_3	(SBIDL_RV_2_3 >> SBIDL_RV_SHIFT)
-
-#define	R_SBREG(sii, sbr)	sb_read_sbreg((sii), (sbr))
-#define	W_SBREG(sii, sbr, v)	sb_write_sbreg((sii), (sbr), (v))
-#define	AND_SBREG(sii, sbr, v)	\
-	W_SBREG((sii), (sbr), (R_SBREG((sii), (sbr)) & (v)))
-#define	OR_SBREG(sii, sbr, v)	\
-	W_SBREG((sii), (sbr), (R_SBREG((sii), (sbr)) | (v)))
-
-static u32 sb_read_sbreg(si_info_t *sii, volatile u32 *sbr)
-{
-	return R_REG(sbr);
-}
-
-static void sb_write_sbreg(si_info_t *sii, volatile u32 *sbr, u32 v)
-{
-	W_REG(sbr, v);
-}
-
-uint sb_coreid(si_t *sih)
-{
-	si_info_t *sii;
-	sbconfig_t *sb;
-
-	sii = SI_INFO(sih);
-	sb = REGS2SB(sii->curmap);
-
-	return (R_SBREG(sii, &sb->sbidhigh) & SBIDH_CC_MASK) >>
-		SBIDH_CC_SHIFT;
-}
-
-/* return core index of the core with address 'sba' */
-static uint _sb_coreidx(si_info_t *sii, u32 sba)
-{
-	uint i;
-
-	for (i = 0; i < sii->numcores; i++)
-		if (sba == sii->coresba[i])
-			return i;
-	return BADIDX;
-}
-
-/* return core address of the current core */
-static u32 _sb_coresba(si_info_t *sii)
-{
-	u32 sbaddr = 0;
-
-	switch (sii->pub.bustype) {
-	case SPI_BUS:
-	case SDIO_BUS:
-		sbaddr = (u32)(unsigned long)sii->curmap;
-		break;
-	default:
-		ASSERT(0);
-		break;
-	}
-
-	return sbaddr;
-}
-
-uint sb_corerev(si_t *sih)
-{
-	si_info_t *sii;
-	sbconfig_t *sb;
-	uint sbidh;
-
-	sii = SI_INFO(sih);
-	sb = REGS2SB(sii->curmap);
-	sbidh = R_SBREG(sii, &sb->sbidhigh);
-
-	return SBCOREREV(sbidh);
-}
-
-bool sb_iscoreup(si_t *sih)
-{
-	si_info_t *sii;
-	sbconfig_t *sb;
-
-	sii = SI_INFO(sih);
-	sb = REGS2SB(sii->curmap);
-
-	return (R_SBREG(sii, &sb->sbtmstatelow) &
-		 (SBTML_RESET | SBTML_REJ_MASK |
-		  (SICF_CLOCK_EN << SBTML_SICF_SHIFT))) ==
-		(SICF_CLOCK_EN << SBTML_SICF_SHIFT);
-}
-
-/*
- * Switch to 'coreidx', issue a single arbitrary 32bit
- * register mask&set operation,
- * switch back to the original core, and return the new value.
- *
- * When using the silicon backplane, no fidleing with interrupts
- * or core switches are needed.
- *
- * Also, when using pci/pcie, we can optimize away the core switching
- * for pci registers
- * and (on newer pci cores) chipcommon registers.
- */
-uint sb_corereg(si_t *sih, uint coreidx, uint regoff, uint mask, uint val)
-{
-	uint origidx = 0;
-	u32 *r = NULL;
-	uint w;
-	uint intr_val = 0;
-	bool fast = false;
-	si_info_t *sii;
-
-	sii = SI_INFO(sih);
-
-	ASSERT(GOODIDX(coreidx));
-	ASSERT(regoff < SI_CORE_SIZE);
-	ASSERT((val & ~mask) == 0);
-
-	if (coreidx >= SI_MAXCORES)
-		return 0;
-
-	if (!fast) {
-		INTR_OFF(sii, intr_val);
-
-		/* save current core index */
-		origidx = si_coreidx(&sii->pub);
-
-		/* switch core */
-		r = (u32 *) ((unsigned char *) sb_setcoreidx(&sii->pub, coreidx) +
-				regoff);
-	}
-	ASSERT(r != NULL);
-
-	/* mask and set */
-	if (mask || val) {
-		if (regoff >= SBCONFIGOFF) {
-			w = (R_SBREG(sii, r) & ~mask) | val;
-			W_SBREG(sii, r, w);
-		} else {
-			w = (R_REG(r) & ~mask) | val;
-			W_REG(r, w);
-		}
-	}
-
-	/* readback */
-	if (regoff >= SBCONFIGOFF)
-		w = R_SBREG(sii, r);
-	else
-		w = R_REG(r);
-
-	if (!fast) {
-		/* restore core index */
-		if (origidx != coreidx)
-			sb_setcoreidx(&sii->pub, origidx);
-
-		INTR_RESTORE(sii, intr_val);
-	}
-
-	return w;
-}
-
-/* Scan the enumeration space to find all cores starting from the given
- * bus 'sbba'. Append coreid and other info to the lists in 'si'. 'sba'
- * is the default core address at chip POR time and 'regs' is the virtual
- * address that the default core is mapped at. 'ncores' is the number of
- * cores expected on bus 'sbba'. It returns the total number of cores
- * starting from bus 'sbba', inclusive.
- */
-#define SB_MAXBUSES	2
-static uint _sb_scan(si_info_t *sii, u32 sba, void *regs, uint bus, u32 sbba,
-		     uint numcores)
-{
-	uint next;
-	uint ncc = 0;
-	uint i;
-
-	if (bus >= SB_MAXBUSES) {
-		SI_ERROR(("_sb_scan: bus 0x%08x at level %d is too deep to "
-			"scan\n", sbba, bus));
-		return 0;
-	}
-	SI_MSG(("_sb_scan: scan bus 0x%08x assume %u cores\n",
-		sbba, numcores));
-
-	/* Scan all cores on the bus starting from core 0.
-	 * Core addresses must be contiguous on each bus.
-	 */
-	for (i = 0, next = sii->numcores;
-	     i < numcores && next < SB_BUS_MAXCORES; i++, next++) {
-		sii->coresba[next] = sbba + (i * SI_CORE_SIZE);
-
-		/* change core to 'next' and read its coreid */
-		sii->curmap = _sb_setcoreidx(sii, next);
-		sii->curidx = next;
-
-		sii->coreid[next] = sb_coreid(&sii->pub);
-
-		/* core specific processing... */
-		/* chipc provides # cores */
-		if (sii->coreid[next] == CC_CORE_ID) {
-			chipcregs_t *cc = (chipcregs_t *) sii->curmap;
-			u32 ccrev = sb_corerev(&sii->pub);
-
-			/* determine numcores - this is the
-				 total # cores in the chip */
-			if (((ccrev == 4) || (ccrev >= 6)))
-				numcores =
-				    (R_REG(&cc->chipid) & CID_CC_MASK)
-				    >> CID_CC_SHIFT;
-			else {
-				/* Older chips */
-				SI_ERROR(("sb_chip2numcores: unsupported chip "
-						  "0x%x\n", sii->pub.chip));
-				ASSERT(0);
-				numcores = 1;
-			}
-
-			SI_VMSG(("_sb_scan: %u cores in the chip %s\n",
-			numcores, sii->pub.issim ? "QT" : ""));
-		}
-		/* scan bridged SB(s) and add results to the end of the list */
-		else if (sii->coreid[next] == OCP_CORE_ID) {
-			sbconfig_t *sb = REGS2SB(sii->curmap);
-			u32 nsbba = R_SBREG(sii, &sb->sbadmatch1);
-			uint nsbcc;
-
-			sii->numcores = next + 1;
-
-			if ((nsbba & 0xfff00000) != SI_ENUM_BASE)
-				continue;
-			nsbba &= 0xfffff000;
-			if (_sb_coreidx(sii, nsbba) != BADIDX)
-				continue;
-
-			nsbcc =
-			    (R_SBREG(sii, &sb->sbtmstatehigh) & 0x000f0000) >>
-			    16;
-			nsbcc = _sb_scan(sii, sba, regs, bus + 1, nsbba, nsbcc);
-			if (sbba == SI_ENUM_BASE)
-				numcores -= nsbcc;
-			ncc += nsbcc;
-		}
-	}
-
-	SI_MSG(("_sb_scan: found %u cores on bus 0x%08x\n", i, sbba));
-
-	sii->numcores = i + ncc;
-	return sii->numcores;
-}
-
-/* scan the sb enumerated space to identify all cores */
-void sb_scan(si_t *sih, void *regs, uint devid)
-{
-	si_info_t *sii;
-	u32 origsba;
-	sbconfig_t *sb;
-
-	sii = SI_INFO(sih);
-	sb = REGS2SB(sii->curmap);
-
-	sii->pub.socirev =
-	    (R_SBREG(sii, &sb->sbidlow) & SBIDL_RV_MASK) >> SBIDL_RV_SHIFT;
-
-	/* Save the current core info and validate it later till we know
-	 * for sure what is good and what is bad.
-	 */
-	origsba = _sb_coresba(sii);
-
-	/* scan all SB(s) starting from SI_ENUM_BASE */
-	sii->numcores = _sb_scan(sii, origsba, regs, 0, SI_ENUM_BASE, 1);
-}
-
-/*
- * This function changes logical "focus" to the indicated core;
- * must be called with interrupts off.
- * Moreover, callers should keep interrupts off during switching out of
- * and back to d11 core
- */
-void *sb_setcoreidx(si_t *sih, uint coreidx)
-{
-	si_info_t *sii;
-
-	sii = SI_INFO(sih);
-
-	if (coreidx >= sii->numcores)
-		return NULL;
-
-	/*
-	 * If the user has provided an interrupt mask enabled function,
-	 * then assert interrupts are disabled before switching the core.
-	 */
-	ASSERT((sii->intrsenabled_fn == NULL)
-	       || !(*(sii)->intrsenabled_fn) ((sii)->intr_arg));
-
-	sii->curmap = _sb_setcoreidx(sii, coreidx);
-	sii->curidx = coreidx;
-
-	return sii->curmap;
-}
-
-/* This function changes the logical "focus" to the indicated core.
- * Return the current core's virtual address.
- */
-static void *_sb_setcoreidx(si_info_t *sii, uint coreidx)
-{
-	u32 sbaddr = sii->coresba[coreidx];
-	void *regs;
-
-	switch (sii->pub.bustype) {
-#ifdef BCMSDIO
-	case SPI_BUS:
-	case SDIO_BUS:
-		/* map new one */
-		if (!sii->regs[coreidx]) {
-			sii->regs[coreidx] = (void *)sbaddr;
-			ASSERT(GOODREGS(sii->regs[coreidx]));
-		}
-		regs = sii->regs[coreidx];
-		break;
-#endif				/* BCMSDIO */
-	default:
-		ASSERT(0);
-		regs = NULL;
-		break;
-	}
-
-	return regs;
-}
-
-void sb_core_disable(si_t *sih, u32 bits)
-{
-	si_info_t *sii;
-	volatile u32 dummy;
-	sbconfig_t *sb;
-
-	sii = SI_INFO(sih);
-
-	ASSERT(GOODREGS(sii->curmap));
-	sb = REGS2SB(sii->curmap);
-
-	/* if core is already in reset, just return */
-	if (R_SBREG(sii, &sb->sbtmstatelow) & SBTML_RESET)
-		return;
-
-	/* if clocks are not enabled, put into reset and return */
-	if ((R_SBREG(sii, &sb->sbtmstatelow) &
-	     (SICF_CLOCK_EN << SBTML_SICF_SHIFT)) == 0)
-		goto disable;
-
-	/* set target reject and spin until busy is clear
-	   (preserve core-specific bits) */
-	OR_SBREG(sii, &sb->sbtmstatelow, SBTML_REJ);
-	dummy = R_SBREG(sii, &sb->sbtmstatelow);
-	udelay(1);
-	SPINWAIT((R_SBREG(sii, &sb->sbtmstatehigh) & SBTMH_BUSY), 100000);
-	if (R_SBREG(sii, &sb->sbtmstatehigh) & SBTMH_BUSY)
-		SI_ERROR(("%s: target state still busy\n", __func__));
-
-	if (R_SBREG(sii, &sb->sbidlow) & SBIDL_INIT) {
-		OR_SBREG(sii, &sb->sbimstate, SBIM_RJ);
-		dummy = R_SBREG(sii, &sb->sbimstate);
-		udelay(1);
-		SPINWAIT((R_SBREG(sii, &sb->sbimstate) & SBIM_BY), 100000);
-	}
-
-	/* set reset and reject while enabling the clocks */
-	W_SBREG(sii, &sb->sbtmstatelow,
-		(((bits | SICF_FGC | SICF_CLOCK_EN) << SBTML_SICF_SHIFT) |
-		 SBTML_REJ | SBTML_RESET));
-	dummy = R_SBREG(sii, &sb->sbtmstatelow);
-	udelay(10);
-
-	/* don't forget to clear the initiator reject bit */
-	if (R_SBREG(sii, &sb->sbidlow) & SBIDL_INIT)
-		AND_SBREG(sii, &sb->sbimstate, ~SBIM_RJ);
-
-disable:
-	/* leave reset and reject asserted */
-	W_SBREG(sii, &sb->sbtmstatelow,
-		((bits << SBTML_SICF_SHIFT) | SBTML_REJ | SBTML_RESET));
-	udelay(1);
-}
-
-/* reset and re-enable a core
- * inputs:
- * bits - core specific bits that are set during and after reset sequence
- * resetbits - core specific bits that are set only during reset sequence
- */
-void sb_core_reset(si_t *sih, u32 bits, u32 resetbits)
-{
-	si_info_t *sii;
-	sbconfig_t *sb;
-	volatile u32 dummy;
-
-	sii = SI_INFO(sih);
-	ASSERT(GOODREGS(sii->curmap));
-	sb = REGS2SB(sii->curmap);
-
-	/*
-	 * Must do the disable sequence first to work for
-	 * arbitrary current core state.
-	 */
-	sb_core_disable(sih, (bits | resetbits));
-
-	/*
-	 * Now do the initialization sequence.
-	 */
-
-	/* set reset while enabling the clock and
-		 forcing them on throughout the core */
-	W_SBREG(sii, &sb->sbtmstatelow,
-		(((bits | resetbits | SICF_FGC | SICF_CLOCK_EN) <<
-		  SBTML_SICF_SHIFT) | SBTML_RESET));
-	dummy = R_SBREG(sii, &sb->sbtmstatelow);
-	udelay(1);
-
-	if (R_SBREG(sii, &sb->sbtmstatehigh) & SBTMH_SERR)
-		W_SBREG(sii, &sb->sbtmstatehigh, 0);
-
-	dummy = R_SBREG(sii, &sb->sbimstate);
-	if (dummy & (SBIM_IBE | SBIM_TO))
-		AND_SBREG(sii, &sb->sbimstate, ~(SBIM_IBE | SBIM_TO));
-
-	/* clear reset and allow it to propagate throughout the core */
-	W_SBREG(sii, &sb->sbtmstatelow,
-		((bits | resetbits | SICF_FGC | SICF_CLOCK_EN) <<
-		 SBTML_SICF_SHIFT));
-	dummy = R_SBREG(sii, &sb->sbtmstatelow);
-	udelay(1);
-
-	/* leave clock enabled */
-	W_SBREG(sii, &sb->sbtmstatelow,
-		((bits | SICF_CLOCK_EN) << SBTML_SICF_SHIFT));
-	dummy = R_SBREG(sii, &sb->sbtmstatelow);
-	udelay(1);
-}
diff -druN linux-2.6.39-libre/drivers/staging/brcm80211/util/siutils.c linux-3.0-rc7-libre/drivers/staging/brcm80211/util/siutils.c
--- linux-2.6.39-libre/drivers/staging/brcm80211/util/siutils.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/brcm80211/util/siutils.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,2006 +0,0 @@
-/*
- * Copyright (c) 2010 Broadcom Corporation
- *
- * 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/delay.h>
-#include <linux/kernel.h>
-#include <linux/string.h>
-#include <bcmdefs.h>
-#include <linux/module.h>
-#include <linux/pci.h>
-#include <bcmutils.h>
-#include <siutils.h>
-#include <bcmdevs.h>
-#include <hndsoc.h>
-#include <sbchipc.h>
-#include <pci_core.h>
-#include <pcie_core.h>
-#include <nicpci.h>
-#include <bcmnvram.h>
-#include <bcmsrom.h>
-#include <pcicfg.h>
-#include <sbsocram.h>
-#ifdef BCMSDIO
-#include <bcmsdh.h>
-#include <sdio.h>
-#include <sbsdio.h>
-#include <sbhnddma.h>
-#include <sbsdpcmdev.h>
-#include <bcmsdpcm.h>
-#endif				/* BCMSDIO */
-#include <hndpmu.h>
-
-/* this file now contains only definitions for sb functions, only necessary
-*for devices using Sonics backplanes (bcm4329)
-*/
-
-/* if an amba SDIO device is supported, please further restrict the inclusion
- * of this file
- */
-#ifdef BCMSDIO
-#include "siutils_priv.h"
-#endif
-
-/* local prototypes */
-static si_info_t *si_doattach(si_info_t *sii, uint devid, void *regs,
-			      uint bustype, void *sdh, char **vars,
-			      uint *varsz);
-static bool si_buscore_prep(si_info_t *sii, uint bustype, uint devid,
-			    void *sdh);
-static bool si_buscore_setup(si_info_t *sii, chipcregs_t *cc, uint bustype,
-			     u32 savewin, uint *origidx, void *regs);
-static void si_nvram_process(si_info_t *sii, char *pvars);
-
-/* dev path concatenation util */
-static char *si_devpathvar(si_t *sih, char *var, int len, const char *name);
-static bool _si_clkctl_cc(si_info_t *sii, uint mode);
-static bool si_ispcie(si_info_t *sii);
-static uint socram_banksize(si_info_t *sii, sbsocramregs_t *r,
-					u8 idx, u8 mtype);
-
-/* global variable to indicate reservation/release of gpio's */
-static u32 si_gpioreservation;
-
-/*
- * Allocate a si handle.
- * devid - pci device id (used to determine chip#)
- * osh - opaque OS handle
- * regs - virtual address of initial core registers
- * bustype - pci/sb/sdio/etc
- * vars - pointer to a pointer area for "environment" variables
- * varsz - pointer to int to return the size of the vars
- */
-si_t *si_attach(uint devid, void *regs, uint bustype,
-		void *sdh, char **vars, uint *varsz)
-{
-	si_info_t *sii;
-
-	/* alloc si_info_t */
-	sii = kmalloc(sizeof(si_info_t), GFP_ATOMIC);
-	if (sii == NULL) {
-		SI_ERROR(("si_attach: malloc failed!\n"));
-		return NULL;
-	}
-
-	if (si_doattach(sii, devid, regs, bustype, sdh, vars, varsz) ==
-	    NULL) {
-		kfree(sii);
-		return NULL;
-	}
-	sii->vars = vars ? *vars : NULL;
-	sii->varsz = varsz ? *varsz : 0;
-
-	return (si_t *) sii;
-}
-
-/* global kernel resource */
-static si_info_t ksii;
-
-static bool si_buscore_prep(si_info_t *sii, uint bustype, uint devid,
-			    void *sdh)
-{
-
-#ifndef BRCM_FULLMAC
-	/* kludge to enable the clock on the 4306 which lacks a slowclock */
-	if (bustype == PCI_BUS && !si_ispcie(sii))
-		si_clkctl_xtal(&sii->pub, XTAL | PLL, ON);
-#endif
-
-#if defined(BCMSDIO)
-	if (bustype == SDIO_BUS) {
-		int err;
-		u8 clkset;
-
-		/* Try forcing SDIO core to do ALPAvail request only */
-		clkset = SBSDIO_FORCE_HW_CLKREQ_OFF | SBSDIO_ALP_AVAIL_REQ;
-		bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR,
-				 clkset, &err);
-		if (!err) {
-			u8 clkval;
-
-			/* If register supported, wait for ALPAvail and then force ALP */
-			clkval =
-			    bcmsdh_cfg_read(sdh, SDIO_FUNC_1,
-					    SBSDIO_FUNC1_CHIPCLKCSR, NULL);
-			if ((clkval & ~SBSDIO_AVBITS) == clkset) {
-				SPINWAIT(((clkval =
-					   bcmsdh_cfg_read(sdh, SDIO_FUNC_1,
-							   SBSDIO_FUNC1_CHIPCLKCSR,
-							   NULL)),
-					  !SBSDIO_ALPAV(clkval)),
-					 PMU_MAX_TRANSITION_DLY);
-				if (!SBSDIO_ALPAV(clkval)) {
-					SI_ERROR(("timeout on ALPAV wait, clkval 0x%02x\n", clkval));
-					return false;
-				}
-				clkset =
-				    SBSDIO_FORCE_HW_CLKREQ_OFF |
-				    SBSDIO_FORCE_ALP;
-				bcmsdh_cfg_write(sdh, SDIO_FUNC_1,
-						 SBSDIO_FUNC1_CHIPCLKCSR,
-						 clkset, &err);
-				udelay(65);
-			}
-		}
-
-		/* Also, disable the extra SDIO pull-ups */
-		bcmsdh_cfg_write(sdh, SDIO_FUNC_1, SBSDIO_FUNC1_SDIOPULLUP, 0,
-				 NULL);
-	}
-#endif				/* defined(BCMSDIO) */
-
-	return true;
-}
-
-static bool si_buscore_setup(si_info_t *sii, chipcregs_t *cc, uint bustype,
-			     u32 savewin, uint *origidx, void *regs)
-{
-	bool pci, pcie;
-	uint i;
-	uint pciidx, pcieidx, pcirev, pcierev;
-
-	cc = si_setcoreidx(&sii->pub, SI_CC_IDX);
-	ASSERT(cc);
-
-	/* get chipcommon rev */
-	sii->pub.ccrev = (int)si_corerev(&sii->pub);
-
-	/* get chipcommon chipstatus */
-	if (sii->pub.ccrev >= 11)
-		sii->pub.chipst = R_REG(&cc->chipstatus);
-
-	/* get chipcommon capabilites */
-	sii->pub.cccaps = R_REG(&cc->capabilities);
-	/* get chipcommon extended capabilities */
-
-#ifndef BRCM_FULLMAC
-	if (sii->pub.ccrev >= 35)
-		sii->pub.cccaps_ext = R_REG(&cc->capabilities_ext);
-#endif
-	/* get pmu rev and caps */
-	if (sii->pub.cccaps & CC_CAP_PMU) {
-		sii->pub.pmucaps = R_REG(&cc->pmucapabilities);
-		sii->pub.pmurev = sii->pub.pmucaps & PCAP_REV_MASK;
-	}
-
-	/*
-	   SI_MSG(("Chipc: rev %d, caps 0x%x, chipst 0x%x pmurev %d, pmucaps 0x%x\n",
-	   sii->pub.ccrev, sii->pub.cccaps, sii->pub.chipst, sii->pub.pmurev,
-	   sii->pub.pmucaps));
-	 */
-
-	/* figure out bus/orignal core idx */
-	sii->pub.buscoretype = NODEV_CORE_ID;
-	sii->pub.buscorerev = NOREV;
-	sii->pub.buscoreidx = BADIDX;
-
-	pci = pcie = false;
-	pcirev = pcierev = NOREV;
-	pciidx = pcieidx = BADIDX;
-
-	for (i = 0; i < sii->numcores; i++) {
-		uint cid, crev;
-
-		si_setcoreidx(&sii->pub, i);
-		cid = si_coreid(&sii->pub);
-		crev = si_corerev(&sii->pub);
-
-		/* Display cores found */
-		SI_VMSG(("CORE[%d]: id 0x%x rev %d base 0x%x regs 0x%p\n",
-			 i, cid, crev, sii->coresba[i], sii->regs[i]));
-
-		if (bustype == PCI_BUS) {
-			if (cid == PCI_CORE_ID) {
-				pciidx = i;
-				pcirev = crev;
-				pci = true;
-			} else if (cid == PCIE_CORE_ID) {
-				pcieidx = i;
-				pcierev = crev;
-				pcie = true;
-			}
-		}
-#ifdef BCMSDIO
-		else if (((bustype == SDIO_BUS) ||
-			  (bustype == SPI_BUS)) &&
-			 ((cid == PCMCIA_CORE_ID) || (cid == SDIOD_CORE_ID))) {
-			sii->pub.buscorerev = crev;
-			sii->pub.buscoretype = cid;
-			sii->pub.buscoreidx = i;
-		}
-#endif				/* BCMSDIO */
-
-		/* find the core idx before entering this func. */
-		if ((savewin && (savewin == sii->coresba[i])) ||
-		    (regs == sii->regs[i]))
-			*origidx = i;
-	}
-
-#ifdef BRCM_FULLMAC
-	SI_MSG(("Buscore id/type/rev %d/0x%x/%d\n", sii->pub.buscoreidx,
-		sii->pub.buscoretype, sii->pub.buscorerev));
-
-	/* Make sure any on-chip ARM is off (in case strapping is wrong),
-	* or downloaded code was
-	* already running.
-	*/
-	if ((bustype == SDIO_BUS) || (bustype == SPI_BUS)) {
-		if (si_setcore(&sii->pub, ARM7S_CORE_ID, 0) ||
-			si_setcore(&sii->pub, ARMCM3_CORE_ID, 0))
-			si_core_disable(&sii->pub, 0);
-	}
-#else
-	if (pci && pcie) {
-		if (si_ispcie(sii))
-			pci = false;
-		else
-			pcie = false;
-	}
-	if (pci) {
-		sii->pub.buscoretype = PCI_CORE_ID;
-		sii->pub.buscorerev = pcirev;
-		sii->pub.buscoreidx = pciidx;
-	} else if (pcie) {
-		sii->pub.buscoretype = PCIE_CORE_ID;
-		sii->pub.buscorerev = pcierev;
-		sii->pub.buscoreidx = pcieidx;
-	}
-
-	SI_VMSG(("Buscore id/type/rev %d/0x%x/%d\n", sii->pub.buscoreidx,
-		 sii->pub.buscoretype, sii->pub.buscorerev));
-
-	/* fixup necessary chip/core configurations */
-	if (sii->pub.bustype == PCI_BUS) {
-		if (SI_FAST(sii)) {
-			if (!sii->pch) {
-				sii->pch = (void *)pcicore_init(
-					&sii->pub, sii->pbus,
-					(void *)PCIEREGS(sii));
-				if (sii->pch == NULL)
-					return false;
-			}
-		}
-		if (si_pci_fixcfg(&sii->pub)) {
-			SI_ERROR(("si_doattach: sb_pci_fixcfg failed\n"));
-			return false;
-		}
-	}
-#endif
-	/* return to the original core */
-	si_setcoreidx(&sii->pub, *origidx);
-
-	return true;
-}
-
-static __used void si_nvram_process(si_info_t *sii, char *pvars)
-{
-	uint w = 0;
-
-	/* get boardtype and boardrev */
-	switch (sii->pub.bustype) {
-	case PCI_BUS:
-		/* do a pci config read to get subsystem id and subvendor id */
-		pci_read_config_dword(sii->pbus, PCI_CFG_SVID, &w);
-		/* Let nvram variables override subsystem Vend/ID */
-		sii->pub.boardvendor = (u16)si_getdevpathintvar(&sii->pub,
-			"boardvendor");
-		if (sii->pub.boardvendor == 0)
-			sii->pub.boardvendor = w & 0xffff;
-		else
-			SI_ERROR(("Overriding boardvendor: 0x%x instead of 0x%x\n", sii->pub.boardvendor, w & 0xffff));
-		sii->pub.boardtype = (u16)si_getdevpathintvar(&sii->pub,
-			"boardtype");
-		if (sii->pub.boardtype == 0)
-			sii->pub.boardtype = (w >> 16) & 0xffff;
-		else
-			SI_ERROR(("Overriding boardtype: 0x%x instead of 0x%x\n", sii->pub.boardtype, (w >> 16) & 0xffff));
-		break;
-
-#ifdef BCMSDIO
-	case SDIO_BUS:
-#endif
-		sii->pub.boardvendor = getintvar(pvars, "manfid");
-		sii->pub.boardtype = getintvar(pvars, "prodid");
-		break;
-
-#ifdef BCMSDIO
-	case SPI_BUS:
-		sii->pub.boardvendor = VENDOR_BROADCOM;
-		sii->pub.boardtype = SPI_BOARD;
-		break;
-#endif
-
-	case SI_BUS:
-	case JTAG_BUS:
-		sii->pub.boardvendor = VENDOR_BROADCOM;
-		sii->pub.boardtype = getintvar(pvars, "prodid");
-		if (pvars == NULL || (sii->pub.boardtype == 0)) {
-			sii->pub.boardtype = getintvar(NULL, "boardtype");
-			if (sii->pub.boardtype == 0)
-				sii->pub.boardtype = 0xffff;
-		}
-		break;
-	}
-
-	if (sii->pub.boardtype == 0) {
-		SI_ERROR(("si_doattach: unknown board type\n"));
-		ASSERT(sii->pub.boardtype);
-	}
-
-	sii->pub.boardflags = getintvar(pvars, "boardflags");
-}
-
-/* this is will make Sonics calls directly, since Sonics is no longer supported in the Si abstraction */
-/* this has been customized for the bcm 4329 ONLY */
-#ifdef BCMSDIO
-static si_info_t *si_doattach(si_info_t *sii, uint devid,
-			      void *regs, uint bustype, void *pbus,
-			      char **vars, uint *varsz)
-{
-	struct si_pub *sih = &sii->pub;
-	u32 w, savewin;
-	chipcregs_t *cc;
-	char *pvars = NULL;
-	uint origidx;
-
-	ASSERT(GOODREGS(regs));
-
-	memset((unsigned char *) sii, 0, sizeof(si_info_t));
-
-	savewin = 0;
-
-	sih->buscoreidx = BADIDX;
-
-	sii->curmap = regs;
-	sii->pbus = pbus;
-
-	/* find Chipcommon address */
-	cc = (chipcregs_t *) sii->curmap;
-	sih->bustype = bustype;
-
-	/* bus/core/clk setup for register access */
-	if (!si_buscore_prep(sii, bustype, devid, pbus)) {
-		SI_ERROR(("si_doattach: si_core_clk_prep failed %d\n",
-			  bustype));
-		return NULL;
-	}
-
-	/* ChipID recognition.
-	 *   We assume we can read chipid at offset 0 from the regs arg.
-	 *   If we add other chiptypes (or if we need to support old sdio hosts w/o chipcommon),
-	 *   some way of recognizing them needs to be added here.
-	 */
-	w = R_REG(&cc->chipid);
-	sih->socitype = (w & CID_TYPE_MASK) >> CID_TYPE_SHIFT;
-	/* Might as wll fill in chip id rev & pkg */
-	sih->chip = w & CID_ID_MASK;
-	sih->chiprev = (w & CID_REV_MASK) >> CID_REV_SHIFT;
-	sih->chippkg = (w & CID_PKG_MASK) >> CID_PKG_SHIFT;
-
-	if ((sih->chip == BCM4329_CHIP_ID) &&
-		(sih->chippkg != BCM4329_289PIN_PKG_ID))
-			sih->chippkg = BCM4329_182PIN_PKG_ID;
-
-	sih->issim = IS_SIM(sih->chippkg);
-
-	/* scan for cores */
-	/* SI_MSG(("Found chip type SB (0x%08x)\n", w)); */
-	sb_scan(&sii->pub, regs, devid);
-
-	/* no cores found, bail out */
-	if (sii->numcores == 0) {
-		SI_ERROR(("si_doattach: could not find any cores\n"));
-		return NULL;
-	}
-	/* bus/core/clk setup */
-	origidx = SI_CC_IDX;
-	if (!si_buscore_setup(sii, cc, bustype, savewin, &origidx, regs)) {
-		SI_ERROR(("si_doattach: si_buscore_setup failed\n"));
-		goto exit;
-	}
-
-#ifdef BRCM_FULLMAC
-	pvars = NULL;
-#else
-	/* Init nvram from flash if it exists */
-	nvram_init((void *)&(sii->pub));
-
-	/* Init nvram from sprom/otp if they exist */
-	if (srom_var_init
-	    (&sii->pub, bustype, regs, sii->osh, vars, varsz)) {
-		SI_ERROR(("si_doattach: srom_var_init failed: bad srom\n"));
-		goto exit;
-	}
-	pvars = vars ? *vars : NULL;
-	si_nvram_process(sii, pvars);
-#endif
-
-	/* === NVRAM, clock is ready === */
-
-#ifdef BRCM_FULLMAC
-	if (sii->pub.ccrev >= 20) {
-#endif
-	cc = (chipcregs_t *) si_setcore(sih, CC_CORE_ID, 0);
-	W_REG(&cc->gpiopullup, 0);
-	W_REG(&cc->gpiopulldown, 0);
-	sb_setcoreidx(sih, origidx);
-#ifdef BRCM_FULLMAC
-	}
-#endif
-
-#ifndef BRCM_FULLMAC
-	/* PMU specific initializations */
-	if (PMUCTL_ENAB(sih)) {
-		u32 xtalfreq;
-		si_pmu_init(sih);
-		si_pmu_chip_init(sih);
-		xtalfreq = getintvar(pvars, "xtalfreq");
-		/* If xtalfreq var not available, try to measure it */
-		if (xtalfreq == 0)
-			xtalfreq = si_pmu_measure_alpclk(sih);
-		si_pmu_pll_init(sih, xtalfreq);
-		si_pmu_res_init(sih);
-		si_pmu_swreg_init(sih);
-	}
-
-	/* setup the GPIO based LED powersave register */
-	w = getintvar(pvars, "leddc");
-	if (w == 0)
-		w = DEFAULT_GPIOTIMERVAL;
-	sb_corereg(sih, SI_CC_IDX, offsetof(chipcregs_t, gpiotimerval), ~0, w);
-
-#ifdef BCMDBG
-	/* clear any previous epidiag-induced target abort */
-	sb_taclear(sih, false);
-#endif				/* BCMDBG */
-#endif
-
-	return sii;
-
- exit:
-	return NULL;
-}
-
-#else				/* BCMSDIO */
-static si_info_t *si_doattach(si_info_t *sii, uint devid,
-			      void *regs, uint bustype, void *pbus,
-			      char **vars, uint *varsz)
-{
-	struct si_pub *sih = &sii->pub;
-	u32 w, savewin;
-	chipcregs_t *cc;
-	char *pvars = NULL;
-	uint origidx;
-
-	ASSERT(GOODREGS(regs));
-
-	memset((unsigned char *) sii, 0, sizeof(si_info_t));
-
-	savewin = 0;
-
-	sih->buscoreidx = BADIDX;
-
-	sii->curmap = regs;
-	sii->pbus = pbus;
-
-	/* check to see if we are a si core mimic'ing a pci core */
-	if (bustype == PCI_BUS) {
-		pci_read_config_dword(sii->pbus, PCI_SPROM_CONTROL,  &w);
-		if (w == 0xffffffff) {
-			SI_ERROR(("%s: incoming bus is PCI but it's a lie, "
-				" switching to SI devid:0x%x\n",
-				__func__, devid));
-			bustype = SI_BUS;
-		}
-	}
-
-	/* find Chipcommon address */
-	if (bustype == PCI_BUS) {
-		pci_read_config_dword(sii->pbus, PCI_BAR0_WIN, &savewin);
-		if (!GOODCOREADDR(savewin, SI_ENUM_BASE))
-			savewin = SI_ENUM_BASE;
-		pci_write_config_dword(sii->pbus, PCI_BAR0_WIN,
-				       SI_ENUM_BASE);
-		cc = (chipcregs_t *) regs;
-	} else {
-		cc = (chipcregs_t *) REG_MAP(SI_ENUM_BASE, SI_CORE_SIZE);
-	}
-
-	sih->bustype = bustype;
-
-	/* bus/core/clk setup for register access */
-	if (!si_buscore_prep(sii, bustype, devid, pbus)) {
-		SI_ERROR(("si_doattach: si_core_clk_prep failed %d\n",
-			  bustype));
-		return NULL;
-	}
-
-	/* ChipID recognition.
-	 *   We assume we can read chipid at offset 0 from the regs arg.
-	 *   If we add other chiptypes (or if we need to support old sdio hosts w/o chipcommon),
-	 *   some way of recognizing them needs to be added here.
-	 */
-	w = R_REG(&cc->chipid);
-	sih->socitype = (w & CID_TYPE_MASK) >> CID_TYPE_SHIFT;
-	/* Might as wll fill in chip id rev & pkg */
-	sih->chip = w & CID_ID_MASK;
-	sih->chiprev = (w & CID_REV_MASK) >> CID_REV_SHIFT;
-	sih->chippkg = (w & CID_PKG_MASK) >> CID_PKG_SHIFT;
-
-	sih->issim = IS_SIM(sih->chippkg);
-
-	/* scan for cores */
-	if (sii->pub.socitype == SOCI_AI) {
-		SI_MSG(("Found chip type AI (0x%08x)\n", w));
-		/* pass chipc address instead of original core base */
-		ai_scan(&sii->pub, (void *)cc, devid);
-	} else {
-		SI_ERROR(("Found chip of unknown type (0x%08x)\n", w));
-		return NULL;
-	}
-	/* no cores found, bail out */
-	if (sii->numcores == 0) {
-		SI_ERROR(("si_doattach: could not find any cores\n"));
-		return NULL;
-	}
-	/* bus/core/clk setup */
-	origidx = SI_CC_IDX;
-	if (!si_buscore_setup(sii, cc, bustype, savewin, &origidx, regs)) {
-		SI_ERROR(("si_doattach: si_buscore_setup failed\n"));
-		goto exit;
-	}
-
-	/* assume current core is CC */
-	if ((sii->pub.ccrev == 0x25)
-	    &&
-	    ((sih->chip == BCM43236_CHIP_ID
-	      || sih->chip == BCM43235_CHIP_ID
-	      || sih->chip == BCM43238_CHIP_ID)
-	     && (sii->pub.chiprev <= 2))) {
-
-		if ((cc->chipstatus & CST43236_BP_CLK) != 0) {
-			uint clkdiv;
-			clkdiv = R_REG(&cc->clkdiv);
-			/* otp_clk_div is even number, 120/14 < 9mhz */
-			clkdiv = (clkdiv & ~CLKD_OTP) | (14 << CLKD_OTP_SHIFT);
-			W_REG(&cc->clkdiv, clkdiv);
-			SI_ERROR(("%s: set clkdiv to %x\n", __func__, clkdiv));
-		}
-		udelay(10);
-	}
-
-	/* Init nvram from flash if it exists */
-	nvram_init((void *)&(sii->pub));
-
-	/* Init nvram from sprom/otp if they exist */
-	if (srom_var_init
-	    (&sii->pub, bustype, regs, vars, varsz)) {
-		SI_ERROR(("si_doattach: srom_var_init failed: bad srom\n"));
-		goto exit;
-	}
-	pvars = vars ? *vars : NULL;
-	si_nvram_process(sii, pvars);
-
-	/* === NVRAM, clock is ready === */
-	cc = (chipcregs_t *) si_setcore(sih, CC_CORE_ID, 0);
-	W_REG(&cc->gpiopullup, 0);
-	W_REG(&cc->gpiopulldown, 0);
-	si_setcoreidx(sih, origidx);
-
-	/* PMU specific initializations */
-	if (PMUCTL_ENAB(sih)) {
-		u32 xtalfreq;
-		si_pmu_init(sih);
-		si_pmu_chip_init(sih);
-		xtalfreq = getintvar(pvars, "xtalfreq");
-		/* If xtalfreq var not available, try to measure it */
-		if (xtalfreq == 0)
-			xtalfreq = si_pmu_measure_alpclk(sih);
-		si_pmu_pll_init(sih, xtalfreq);
-		si_pmu_res_init(sih);
-		si_pmu_swreg_init(sih);
-	}
-
-	/* setup the GPIO based LED powersave register */
-	w = getintvar(pvars, "leddc");
-	if (w == 0)
-		w = DEFAULT_GPIOTIMERVAL;
-	si_corereg(sih, SI_CC_IDX, offsetof(chipcregs_t, gpiotimerval), ~0, w);
-
-	if (PCIE(sii)) {
-		ASSERT(sii->pch != NULL);
-		pcicore_attach(sii->pch, pvars, SI_DOATTACH);
-	}
-
-	if ((sih->chip == BCM43224_CHIP_ID) ||
-	    (sih->chip == BCM43421_CHIP_ID)) {
-		/* enable 12 mA drive strenth for 43224 and set chipControl register bit 15 */
-		if (sih->chiprev == 0) {
-			SI_MSG(("Applying 43224A0 WARs\n"));
-			si_corereg(sih, SI_CC_IDX,
-				   offsetof(chipcregs_t, chipcontrol),
-				   CCTRL43224_GPIO_TOGGLE,
-				   CCTRL43224_GPIO_TOGGLE);
-			si_pmu_chipcontrol(sih, 0, CCTRL_43224A0_12MA_LED_DRIVE,
-					   CCTRL_43224A0_12MA_LED_DRIVE);
-		}
-		if (sih->chiprev >= 1) {
-			SI_MSG(("Applying 43224B0+ WARs\n"));
-			si_pmu_chipcontrol(sih, 0, CCTRL_43224B0_12MA_LED_DRIVE,
-					   CCTRL_43224B0_12MA_LED_DRIVE);
-		}
-	}
-
-	if (sih->chip == BCM4313_CHIP_ID) {
-		/* enable 12 mA drive strenth for 4313 and set chipControl register bit 1 */
-		SI_MSG(("Applying 4313 WARs\n"));
-		si_pmu_chipcontrol(sih, 0, CCTRL_4313_12MA_LED_DRIVE,
-				   CCTRL_4313_12MA_LED_DRIVE);
-	}
-
-	if (sih->chip == BCM4331_CHIP_ID) {
-		/* Enable Ext PA lines depending on chip package option */
-		si_chipcontrl_epa4331(sih, true);
-	}
-
-	return sii;
- exit:
-	if (sih->bustype == PCI_BUS) {
-		if (sii->pch)
-			pcicore_deinit(sii->pch);
-		sii->pch = NULL;
-	}
-
-	return NULL;
-}
-#endif				/* BCMSDIO */
-
-/* may be called with core in reset */
-void si_detach(si_t *sih)
-{
-	si_info_t *sii;
-	uint idx;
-
-	struct si_pub *si_local = NULL;
-	memcpy(&si_local, &sih, sizeof(si_t **));
-
-	sii = SI_INFO(sih);
-
-	if (sii == NULL)
-		return;
-
-	if (sih->bustype == SI_BUS)
-		for (idx = 0; idx < SI_MAXCORES; idx++)
-			if (sii->regs[idx]) {
-				iounmap(sii->regs[idx]);
-				sii->regs[idx] = NULL;
-			}
-
-#ifndef BRCM_FULLMAC
-	nvram_exit((void *)si_local);	/* free up nvram buffers */
-
-	if (sih->bustype == PCI_BUS) {
-		if (sii->pch)
-			pcicore_deinit(sii->pch);
-		sii->pch = NULL;
-	}
-#endif
-#if !defined(BCMBUSTYPE) || (BCMBUSTYPE == SI_BUS)
-	if (sii != &ksii)
-#endif				/* !BCMBUSTYPE || (BCMBUSTYPE == SI_BUS) */
-		kfree(sii);
-}
-
-/* register driver interrupt disabling and restoring callback functions */
-void
-si_register_intr_callback(si_t *sih, void *intrsoff_fn, void *intrsrestore_fn,
-			  void *intrsenabled_fn, void *intr_arg)
-{
-	si_info_t *sii;
-
-	sii = SI_INFO(sih);
-	sii->intr_arg = intr_arg;
-	sii->intrsoff_fn = (si_intrsoff_t) intrsoff_fn;
-	sii->intrsrestore_fn = (si_intrsrestore_t) intrsrestore_fn;
-	sii->intrsenabled_fn = (si_intrsenabled_t) intrsenabled_fn;
-	/* save current core id.  when this function called, the current core
-	 * must be the core which provides driver functions(il, et, wl, etc.)
-	 */
-	sii->dev_coreid = sii->coreid[sii->curidx];
-}
-
-void si_deregister_intr_callback(si_t *sih)
-{
-	si_info_t *sii;
-
-	sii = SI_INFO(sih);
-	sii->intrsoff_fn = NULL;
-}
-
-uint si_flag(si_t *sih)
-{
-	if (sih->socitype == SOCI_AI)
-		return ai_flag(sih);
-	else {
-		ASSERT(0);
-		return 0;
-	}
-}
-
-void si_setint(si_t *sih, int siflag)
-{
-	if (sih->socitype == SOCI_AI)
-		ai_setint(sih, siflag);
-	else
-		ASSERT(0);
-}
-
-#ifndef BCMSDIO
-uint si_coreid(si_t *sih)
-{
-	si_info_t *sii;
-
-	sii = SI_INFO(sih);
-	return sii->coreid[sii->curidx];
-}
-#endif
-
-uint si_coreidx(si_t *sih)
-{
-	si_info_t *sii;
-
-	sii = SI_INFO(sih);
-	return sii->curidx;
-}
-
-bool si_backplane64(si_t *sih)
-{
-	return (sih->cccaps & CC_CAP_BKPLN64) != 0;
-}
-
-#ifndef BCMSDIO
-uint si_corerev(si_t *sih)
-{
-	if (sih->socitype == SOCI_AI)
-		return ai_corerev(sih);
-	else {
-		ASSERT(0);
-		return 0;
-	}
-}
-#endif
-
-/* return index of coreid or BADIDX if not found */
-uint si_findcoreidx(si_t *sih, uint coreid, uint coreunit)
-{
-	si_info_t *sii;
-	uint found;
-	uint i;
-
-	sii = SI_INFO(sih);
-
-	found = 0;
-
-	for (i = 0; i < sii->numcores; i++)
-		if (sii->coreid[i] == coreid) {
-			if (found == coreunit)
-				return i;
-			found++;
-		}
-
-	return BADIDX;
-}
-
-/*
- * This function changes logical "focus" to the indicated core;
- * must be called with interrupts off.
- * Moreover, callers should keep interrupts off during switching out of and back to d11 core
- */
-void *si_setcore(si_t *sih, uint coreid, uint coreunit)
-{
-	uint idx;
-
-	idx = si_findcoreidx(sih, coreid, coreunit);
-	if (!GOODIDX(idx))
-		return NULL;
-
-	if (sih->socitype == SOCI_AI)
-		return ai_setcoreidx(sih, idx);
-	else {
-#ifdef BCMSDIO
-		return sb_setcoreidx(sih, idx);
-#else
-		ASSERT(0);
-		return NULL;
-#endif
-	}
-}
-
-#ifndef BCMSDIO
-void *si_setcoreidx(si_t *sih, uint coreidx)
-{
-	if (sih->socitype == SOCI_AI)
-		return ai_setcoreidx(sih, coreidx);
-	else {
-		ASSERT(0);
-		return NULL;
-	}
-}
-#endif
-
-/* Turn off interrupt as required by sb_setcore, before switch core */
-void *si_switch_core(si_t *sih, uint coreid, uint *origidx, uint *intr_val)
-{
-	void *cc;
-	si_info_t *sii;
-
-	sii = SI_INFO(sih);
-
-	if (SI_FAST(sii)) {
-		/* Overloading the origidx variable to remember the coreid,
-		 * this works because the core ids cannot be confused with
-		 * core indices.
-		 */
-		*origidx = coreid;
-		if (coreid == CC_CORE_ID)
-			return (void *)CCREGS_FAST(sii);
-		else if (coreid == sih->buscoretype)
-			return (void *)PCIEREGS(sii);
-	}
-	INTR_OFF(sii, *intr_val);
-	*origidx = sii->curidx;
-	cc = si_setcore(sih, coreid, 0);
-	ASSERT(cc != NULL);
-
-	return cc;
-}
-
-/* restore coreidx and restore interrupt */
-void si_restore_core(si_t *sih, uint coreid, uint intr_val)
-{
-	si_info_t *sii;
-
-	sii = SI_INFO(sih);
-	if (SI_FAST(sii)
-	    && ((coreid == CC_CORE_ID) || (coreid == sih->buscoretype)))
-		return;
-
-	si_setcoreidx(sih, coreid);
-	INTR_RESTORE(sii, intr_val);
-}
-
-u32 si_core_cflags(si_t *sih, u32 mask, u32 val)
-{
-	if (sih->socitype == SOCI_AI)
-		return ai_core_cflags(sih, mask, val);
-	else {
-		ASSERT(0);
-		return 0;
-	}
-}
-
-u32 si_core_sflags(si_t *sih, u32 mask, u32 val)
-{
-	if (sih->socitype == SOCI_AI)
-		return ai_core_sflags(sih, mask, val);
-	else {
-		ASSERT(0);
-		return 0;
-	}
-}
-
-bool si_iscoreup(si_t *sih)
-{
-	if (sih->socitype == SOCI_AI)
-		return ai_iscoreup(sih);
-	else {
-#ifdef BCMSDIO
-		return sb_iscoreup(sih);
-#else
-		ASSERT(0);
-		return false;
-#endif
-	}
-}
-
-void si_write_wrapperreg(si_t *sih, u32 offset, u32 val)
-{
-	/* only for 4319, no requirement for SOCI_SB */
-	if (sih->socitype == SOCI_AI) {
-		ai_write_wrap_reg(sih, offset, val);
-	}
-}
-
-uint si_corereg(si_t *sih, uint coreidx, uint regoff, uint mask, uint val)
-{
-
-	if (sih->socitype == SOCI_AI)
-		return ai_corereg(sih, coreidx, regoff, mask, val);
-	else {
-#ifdef BCMSDIO
-		return sb_corereg(sih, coreidx, regoff, mask, val);
-#else
-		ASSERT(0);
-		return 0;
-#endif
-	}
-}
-
-void si_core_disable(si_t *sih, u32 bits)
-{
-
-	if (sih->socitype == SOCI_AI)
-		ai_core_disable(sih, bits);
-#ifdef BCMSDIO
-	else
-		sb_core_disable(sih, bits);
-#endif
-}
-
-void si_core_reset(si_t *sih, u32 bits, u32 resetbits)
-{
-	if (sih->socitype == SOCI_AI)
-		ai_core_reset(sih, bits, resetbits);
-#ifdef BCMSDIO
-	else
-		sb_core_reset(sih, bits, resetbits);
-#endif
-}
-
-u32 si_alp_clock(si_t *sih)
-{
-	if (PMUCTL_ENAB(sih))
-		return si_pmu_alp_clock(sih);
-
-	return ALP_CLOCK;
-}
-
-u32 si_ilp_clock(si_t *sih)
-{
-	if (PMUCTL_ENAB(sih))
-		return si_pmu_ilp_clock(sih);
-
-	return ILP_CLOCK;
-}
-
-/* set chip watchdog reset timer to fire in 'ticks' */
-#ifdef BRCM_FULLMAC
-void
-si_watchdog(si_t *sih, uint ticks)
-{
-	if (PMUCTL_ENAB(sih)) {
-
-		if ((sih->chip == BCM4319_CHIP_ID) && (sih->chiprev == 0) &&
-			(ticks != 0)) {
-			si_corereg(sih, SI_CC_IDX, offsetof(chipcregs_t,
-			clk_ctl_st), ~0, 0x2);
-			si_setcore(sih, USB20D_CORE_ID, 0);
-			si_core_disable(sih, 1);
-			si_setcore(sih, CC_CORE_ID, 0);
-		}
-
-		if (ticks == 1)
-			ticks = 2;
-		si_corereg(sih, SI_CC_IDX, offsetof(chipcregs_t, pmuwatchdog),
-			~0, ticks);
-	} else {
-		/* instant NMI */
-		si_corereg(sih, SI_CC_IDX, offsetof(chipcregs_t, watchdog),
-			~0, ticks);
-	}
-}
-#else
-void si_watchdog(si_t *sih, uint ticks)
-{
-	uint nb, maxt;
-
-	if (PMUCTL_ENAB(sih)) {
-
-		if ((sih->chip == BCM4319_CHIP_ID) &&
-		    (sih->chiprev == 0) && (ticks != 0)) {
-			si_corereg(sih, SI_CC_IDX,
-				   offsetof(chipcregs_t, clk_ctl_st), ~0, 0x2);
-			si_setcore(sih, USB20D_CORE_ID, 0);
-			si_core_disable(sih, 1);
-			si_setcore(sih, CC_CORE_ID, 0);
-		}
-
-		nb = (sih->ccrev < 26) ? 16 : ((sih->ccrev >= 37) ? 32 : 24);
-		/* The mips compiler uses the sllv instruction,
-		 * so we specially handle the 32-bit case.
-		 */
-		if (nb == 32)
-			maxt = 0xffffffff;
-		else
-			maxt = ((1 << nb) - 1);
-
-		if (ticks == 1)
-			ticks = 2;
-		else if (ticks > maxt)
-			ticks = maxt;
-
-		si_corereg(sih, SI_CC_IDX, offsetof(chipcregs_t, pmuwatchdog),
-			   ~0, ticks);
-	} else {
-		/* make sure we come up in fast clock mode; or if clearing, clear clock */
-		si_clkctl_cc(sih, ticks ? CLK_FAST : CLK_DYNAMIC);
-		maxt = (1 << 28) - 1;
-		if (ticks > maxt)
-			ticks = maxt;
-
-		si_corereg(sih, SI_CC_IDX, offsetof(chipcregs_t, watchdog), ~0,
-			   ticks);
-	}
-}
-#endif
-
-/* return the slow clock source - LPO, XTAL, or PCI */
-static uint si_slowclk_src(si_info_t *sii)
-{
-	chipcregs_t *cc;
-	u32 val;
-
-	ASSERT(SI_FAST(sii) || si_coreid(&sii->pub) == CC_CORE_ID);
-
-	if (sii->pub.ccrev < 6) {
-		if (sii->pub.bustype == PCI_BUS) {
-			pci_read_config_dword(sii->pbus, PCI_GPIO_OUT,
-					      &val);
-			if (val & PCI_CFG_GPIO_SCS)
-				return SCC_SS_PCI;
-		}
-		return SCC_SS_XTAL;
-	} else if (sii->pub.ccrev < 10) {
-		cc = (chipcregs_t *) si_setcoreidx(&sii->pub, sii->curidx);
-		return R_REG(&cc->slow_clk_ctl) & SCC_SS_MASK;
-	} else			/* Insta-clock */
-		return SCC_SS_XTAL;
-}
-
-/* return the ILP (slowclock) min or max frequency */
-static uint si_slowclk_freq(si_info_t *sii, bool max_freq, chipcregs_t *cc)
-{
-	u32 slowclk;
-	uint div;
-
-	ASSERT(SI_FAST(sii) || si_coreid(&sii->pub) == CC_CORE_ID);
-
-	/* shouldn't be here unless we've established the chip has dynamic clk control */
-	ASSERT(R_REG(&cc->capabilities) & CC_CAP_PWR_CTL);
-
-	slowclk = si_slowclk_src(sii);
-	if (sii->pub.ccrev < 6) {
-		if (slowclk == SCC_SS_PCI)
-			return max_freq ? (PCIMAXFREQ / 64)
-				: (PCIMINFREQ / 64);
-		else
-			return max_freq ? (XTALMAXFREQ / 32)
-				: (XTALMINFREQ / 32);
-	} else if (sii->pub.ccrev < 10) {
-		div = 4 *
-		    (((R_REG(&cc->slow_clk_ctl) & SCC_CD_MASK) >>
-		      SCC_CD_SHIFT) + 1);
-		if (slowclk == SCC_SS_LPO)
-			return max_freq ? LPOMAXFREQ : LPOMINFREQ;
-		else if (slowclk == SCC_SS_XTAL)
-			return max_freq ? (XTALMAXFREQ / div)
-				: (XTALMINFREQ / div);
-		else if (slowclk == SCC_SS_PCI)
-			return max_freq ? (PCIMAXFREQ / div)
-				: (PCIMINFREQ / div);
-		else
-			ASSERT(0);
-	} else {
-		/* Chipc rev 10 is InstaClock */
-		div = R_REG(&cc->system_clk_ctl) >> SYCC_CD_SHIFT;
-		div = 4 * (div + 1);
-		return max_freq ? XTALMAXFREQ : (XTALMINFREQ / div);
-	}
-	return 0;
-}
-
-static void si_clkctl_setdelay(si_info_t *sii, void *chipcregs)
-{
-	chipcregs_t *cc = (chipcregs_t *) chipcregs;
-	uint slowmaxfreq, pll_delay, slowclk;
-	uint pll_on_delay, fref_sel_delay;
-
-	pll_delay = PLL_DELAY;
-
-	/* If the slow clock is not sourced by the xtal then add the xtal_on_delay
-	 * since the xtal will also be powered down by dynamic clk control logic.
-	 */
-
-	slowclk = si_slowclk_src(sii);
-	if (slowclk != SCC_SS_XTAL)
-		pll_delay += XTAL_ON_DELAY;
-
-	/* Starting with 4318 it is ILP that is used for the delays */
-	slowmaxfreq =
-	    si_slowclk_freq(sii, (sii->pub.ccrev >= 10) ? false : true, cc);
-
-	pll_on_delay = ((slowmaxfreq * pll_delay) + 999999) / 1000000;
-	fref_sel_delay = ((slowmaxfreq * FREF_DELAY) + 999999) / 1000000;
-
-	W_REG(&cc->pll_on_delay, pll_on_delay);
-	W_REG(&cc->fref_sel_delay, fref_sel_delay);
-}
-
-/* initialize power control delay registers */
-void si_clkctl_init(si_t *sih)
-{
-	si_info_t *sii;
-	uint origidx = 0;
-	chipcregs_t *cc;
-	bool fast;
-
-	if (!CCCTL_ENAB(sih))
-		return;
-
-	sii = SI_INFO(sih);
-	fast = SI_FAST(sii);
-	if (!fast) {
-		origidx = sii->curidx;
-		cc = (chipcregs_t *) si_setcore(sih, CC_CORE_ID, 0);
-		if (cc == NULL)
-			return;
-	} else {
-		cc = (chipcregs_t *) CCREGS_FAST(sii);
-		if (cc == NULL)
-			return;
-	}
-	ASSERT(cc != NULL);
-
-	/* set all Instaclk chip ILP to 1 MHz */
-	if (sih->ccrev >= 10)
-		SET_REG(&cc->system_clk_ctl, SYCC_CD_MASK,
-			(ILP_DIV_1MHZ << SYCC_CD_SHIFT));
-
-	si_clkctl_setdelay(sii, (void *)cc);
-
-	if (!fast)
-		si_setcoreidx(sih, origidx);
-}
-
-/* return the value suitable for writing to the dot11 core FAST_PWRUP_DELAY register */
-u16 si_clkctl_fast_pwrup_delay(si_t *sih)
-{
-	si_info_t *sii;
-	uint origidx = 0;
-	chipcregs_t *cc;
-	uint slowminfreq;
-	u16 fpdelay;
-	uint intr_val = 0;
-	bool fast;
-
-	sii = SI_INFO(sih);
-	if (PMUCTL_ENAB(sih)) {
-		INTR_OFF(sii, intr_val);
-		fpdelay = si_pmu_fast_pwrup_delay(sih);
-		INTR_RESTORE(sii, intr_val);
-		return fpdelay;
-	}
-
-	if (!CCCTL_ENAB(sih))
-		return 0;
-
-	fast = SI_FAST(sii);
-	fpdelay = 0;
-	if (!fast) {
-		origidx = sii->curidx;
-		INTR_OFF(sii, intr_val);
-		cc = (chipcregs_t *) si_setcore(sih, CC_CORE_ID, 0);
-		if (cc == NULL)
-			goto done;
-	} else {
-		cc = (chipcregs_t *) CCREGS_FAST(sii);
-		if (cc == NULL)
-			goto done;
-	}
-	ASSERT(cc != NULL);
-
-	slowminfreq = si_slowclk_freq(sii, false, cc);
-	fpdelay = (((R_REG(&cc->pll_on_delay) + 2) * 1000000) +
-		   (slowminfreq - 1)) / slowminfreq;
-
- done:
-	if (!fast) {
-		si_setcoreidx(sih, origidx);
-		INTR_RESTORE(sii, intr_val);
-	}
-	return fpdelay;
-}
-
-/* turn primary xtal and/or pll off/on */
-int si_clkctl_xtal(si_t *sih, uint what, bool on)
-{
-	si_info_t *sii;
-	u32 in, out, outen;
-
-	sii = SI_INFO(sih);
-
-	switch (sih->bustype) {
-
-#ifdef BCMSDIO
-	case SDIO_BUS:
-		return -1;
-#endif				/* BCMSDIO */
-
-	case PCI_BUS:
-		/* pcie core doesn't have any mapping to control the xtal pu */
-		if (PCIE(sii))
-			return -1;
-
-		pci_read_config_dword(sii->pbus, PCI_GPIO_IN, &in);
-		pci_read_config_dword(sii->pbus, PCI_GPIO_OUT, &out);
-		pci_read_config_dword(sii->pbus, PCI_GPIO_OUTEN, &outen);
-
-		/*
-		 * Avoid glitching the clock if GPRS is already using it.
-		 * We can't actually read the state of the PLLPD so we infer it
-		 * by the value of XTAL_PU which *is* readable via gpioin.
-		 */
-		if (on && (in & PCI_CFG_GPIO_XTAL))
-			return 0;
-
-		if (what & XTAL)
-			outen |= PCI_CFG_GPIO_XTAL;
-		if (what & PLL)
-			outen |= PCI_CFG_GPIO_PLL;
-
-		if (on) {
-			/* turn primary xtal on */
-			if (what & XTAL) {
-				out |= PCI_CFG_GPIO_XTAL;
-				if (what & PLL)
-					out |= PCI_CFG_GPIO_PLL;
-				pci_write_config_dword(sii->pbus,
-						       PCI_GPIO_OUT, out);
-				pci_write_config_dword(sii->pbus,
-						       PCI_GPIO_OUTEN, outen);
-				udelay(XTAL_ON_DELAY);
-			}
-
-			/* turn pll on */
-			if (what & PLL) {
-				out &= ~PCI_CFG_GPIO_PLL;
-				pci_write_config_dword(sii->pbus,
-						       PCI_GPIO_OUT, out);
-				mdelay(2);
-			}
-		} else {
-			if (what & XTAL)
-				out &= ~PCI_CFG_GPIO_XTAL;
-			if (what & PLL)
-				out |= PCI_CFG_GPIO_PLL;
-			pci_write_config_dword(sii->pbus,
-					       PCI_GPIO_OUT, out);
-			pci_write_config_dword(sii->pbus,
-					       PCI_GPIO_OUTEN, outen);
-		}
-
-	default:
-		return -1;
-	}
-
-	return 0;
-}
-
-/*
- *  clock control policy function through chipcommon
- *
- *    set dynamic clk control mode (forceslow, forcefast, dynamic)
- *    returns true if we are forcing fast clock
- *    this is a wrapper over the next internal function
- *      to allow flexible policy settings for outside caller
- */
-bool si_clkctl_cc(si_t *sih, uint mode)
-{
-	si_info_t *sii;
-
-	sii = SI_INFO(sih);
-
-	/* chipcommon cores prior to rev6 don't support dynamic clock control */
-	if (sih->ccrev < 6)
-		return false;
-
-	if (PCI_FORCEHT(sii))
-		return mode == CLK_FAST;
-
-	return _si_clkctl_cc(sii, mode);
-}
-
-/* clk control mechanism through chipcommon, no policy checking */
-static bool _si_clkctl_cc(si_info_t *sii, uint mode)
-{
-	uint origidx = 0;
-	chipcregs_t *cc;
-	u32 scc;
-	uint intr_val = 0;
-	bool fast = SI_FAST(sii);
-
-	/* chipcommon cores prior to rev6 don't support dynamic clock control */
-	if (sii->pub.ccrev < 6)
-		return false;
-
-	/* Chips with ccrev 10 are EOL and they don't have SYCC_HR which we use below */
-	ASSERT(sii->pub.ccrev != 10);
-
-	if (!fast) {
-		INTR_OFF(sii, intr_val);
-		origidx = sii->curidx;
-
-		if ((sii->pub.bustype == SI_BUS) &&
-		    si_setcore(&sii->pub, MIPS33_CORE_ID, 0) &&
-		    (si_corerev(&sii->pub) <= 7) && (sii->pub.ccrev >= 10))
-			goto done;
-
-		cc = (chipcregs_t *) si_setcore(&sii->pub, CC_CORE_ID, 0);
-	} else {
-		cc = (chipcregs_t *) CCREGS_FAST(sii);
-		if (cc == NULL)
-			goto done;
-	}
-	ASSERT(cc != NULL);
-
-	if (!CCCTL_ENAB(&sii->pub) && (sii->pub.ccrev < 20))
-		goto done;
-
-	switch (mode) {
-	case CLK_FAST:		/* FORCEHT, fast (pll) clock */
-		if (sii->pub.ccrev < 10) {
-			/* don't forget to force xtal back on before we clear SCC_DYN_XTAL.. */
-			si_clkctl_xtal(&sii->pub, XTAL, ON);
-			SET_REG(&cc->slow_clk_ctl,
-				(SCC_XC | SCC_FS | SCC_IP), SCC_IP);
-		} else if (sii->pub.ccrev < 20) {
-			OR_REG(&cc->system_clk_ctl, SYCC_HR);
-		} else {
-			OR_REG(&cc->clk_ctl_st, CCS_FORCEHT);
-		}
-
-		/* wait for the PLL */
-		if (PMUCTL_ENAB(&sii->pub)) {
-			u32 htavail = CCS_HTAVAIL;
-			SPINWAIT(((R_REG(&cc->clk_ctl_st) & htavail)
-				  == 0), PMU_MAX_TRANSITION_DLY);
-			ASSERT(R_REG(&cc->clk_ctl_st) & htavail);
-		} else {
-			udelay(PLL_DELAY);
-		}
-		break;
-
-	case CLK_DYNAMIC:	/* enable dynamic clock control */
-		if (sii->pub.ccrev < 10) {
-			scc = R_REG(&cc->slow_clk_ctl);
-			scc &= ~(SCC_FS | SCC_IP | SCC_XC);
-			if ((scc & SCC_SS_MASK) != SCC_SS_XTAL)
-				scc |= SCC_XC;
-			W_REG(&cc->slow_clk_ctl, scc);
-
-			/* for dynamic control, we have to release our xtal_pu "force on" */
-			if (scc & SCC_XC)
-				si_clkctl_xtal(&sii->pub, XTAL, OFF);
-		} else if (sii->pub.ccrev < 20) {
-			/* Instaclock */
-			AND_REG(&cc->system_clk_ctl, ~SYCC_HR);
-		} else {
-			AND_REG(&cc->clk_ctl_st, ~CCS_FORCEHT);
-		}
-		break;
-
-	default:
-		ASSERT(0);
-	}
-
- done:
-	if (!fast) {
-		si_setcoreidx(&sii->pub, origidx);
-		INTR_RESTORE(sii, intr_val);
-	}
-	return mode == CLK_FAST;
-}
-
-/* Build device path. Support SI, PCI, and JTAG for now. */
-int si_devpath(si_t *sih, char *path, int size)
-{
-	int slen;
-
-	ASSERT(path != NULL);
-	ASSERT(size >= SI_DEVPATH_BUFSZ);
-
-	if (!path || size <= 0)
-		return -1;
-
-	switch (sih->bustype) {
-	case SI_BUS:
-	case JTAG_BUS:
-		slen = snprintf(path, (size_t) size, "sb/%u/", si_coreidx(sih));
-		break;
-	case PCI_BUS:
-		ASSERT((SI_INFO(sih))->pbus != NULL);
-		slen = snprintf(path, (size_t) size, "pci/%u/%u/",
-			((struct pci_dev *)((SI_INFO(sih))->pbus))->bus->number,
-			PCI_SLOT(
-			    ((struct pci_dev *)((SI_INFO(sih))->pbus))->devfn));
-		break;
-
-#ifdef BCMSDIO
-	case SDIO_BUS:
-		SI_ERROR(("si_devpath: device 0 assumed\n"));
-		slen = snprintf(path, (size_t) size, "sd/%u/", si_coreidx(sih));
-		break;
-#endif
-	default:
-		slen = -1;
-		ASSERT(0);
-		break;
-	}
-
-	if (slen < 0 || slen >= size) {
-		path[0] = '\0';
-		return -1;
-	}
-
-	return 0;
-}
-
-/* Get a variable, but only if it has a devpath prefix */
-char *si_getdevpathvar(si_t *sih, const char *name)
-{
-	char varname[SI_DEVPATH_BUFSZ + 32];
-
-	si_devpathvar(sih, varname, sizeof(varname), name);
-
-	return getvar(NULL, varname);
-}
-
-/* Get a variable, but only if it has a devpath prefix */
-int si_getdevpathintvar(si_t *sih, const char *name)
-{
-#if defined(BCMBUSTYPE) && (BCMBUSTYPE == SI_BUS)
-	return getintvar(NULL, name);
-#else
-	char varname[SI_DEVPATH_BUFSZ + 32];
-
-	si_devpathvar(sih, varname, sizeof(varname), name);
-
-	return getintvar(NULL, varname);
-#endif
-}
-
-char *si_getnvramflvar(si_t *sih, const char *name)
-{
-	return getvar(NULL, name);
-}
-
-/* Concatenate the dev path with a varname into the given 'var' buffer
- * and return the 'var' pointer.
- * Nothing is done to the arguments if len == 0 or var is NULL, var is still returned.
- * On overflow, the first char will be set to '\0'.
- */
-static char *si_devpathvar(si_t *sih, char *var, int len, const char *name)
-{
-	uint path_len;
-
-	if (!var || len <= 0)
-		return var;
-
-	if (si_devpath(sih, var, len) == 0) {
-		path_len = strlen(var);
-
-		if (strlen(name) + 1 > (uint) (len - path_len))
-			var[0] = '\0';
-		else
-			strncpy(var + path_len, name, len - path_len - 1);
-	}
-
-	return var;
-}
-
-/* return true if PCIE capability exists in the pci config space */
-static __used bool si_ispcie(si_info_t *sii)
-{
-	u8 cap_ptr;
-
-	if (sii->pub.bustype != PCI_BUS)
-		return false;
-
-	cap_ptr =
-	    pcicore_find_pci_capability(sii->pbus, PCI_CAP_PCIECAP_ID, NULL,
-					NULL);
-	if (!cap_ptr)
-		return false;
-
-	return true;
-}
-
-#ifdef BCMSDIO
-/* initialize the sdio core */
-void si_sdio_init(si_t *sih)
-{
-	si_info_t *sii = SI_INFO(sih);
-
-	if (((sih->buscoretype == PCMCIA_CORE_ID) && (sih->buscorerev >= 8)) ||
-	    (sih->buscoretype == SDIOD_CORE_ID)) {
-		uint idx;
-		sdpcmd_regs_t *sdpregs;
-
-		/* get the current core index */
-		idx = sii->curidx;
-		ASSERT(idx == si_findcoreidx(sih, D11_CORE_ID, 0));
-
-		/* switch to sdio core */
-		sdpregs = (sdpcmd_regs_t *) si_setcore(sih, PCMCIA_CORE_ID, 0);
-		if (!sdpregs)
-			sdpregs =
-			    (sdpcmd_regs_t *) si_setcore(sih, SDIOD_CORE_ID, 0);
-		ASSERT(sdpregs);
-
-		SI_MSG(("si_sdio_init: For PCMCIA/SDIO Corerev %d, enable ints from core %d " "through SD core %d (%p)\n", sih->buscorerev, idx, sii->curidx, sdpregs));
-
-		/* enable backplane error and core interrupts */
-		W_REG(&sdpregs->hostintmask, I_SBINT);
-		W_REG(&sdpregs->sbintmask,
-		      (I_SB_SERR | I_SB_RESPERR | (1 << idx)));
-
-		/* switch back to previous core */
-		si_setcoreidx(sih, idx);
-	}
-
-	/* enable interrupts */
-	bcmsdh_intr_enable(sii->pbus);
-
-}
-#endif				/* BCMSDIO */
-
-bool si_pci_war16165(si_t *sih)
-{
-	si_info_t *sii;
-
-	sii = SI_INFO(sih);
-
-	return PCI(sii) && (sih->buscorerev <= 10);
-}
-
-void si_pci_up(si_t *sih)
-{
-	si_info_t *sii;
-
-	sii = SI_INFO(sih);
-
-	/* if not pci bus, we're done */
-	if (sih->bustype != PCI_BUS)
-		return;
-
-	if (PCI_FORCEHT(sii))
-		_si_clkctl_cc(sii, CLK_FAST);
-
-	if (PCIE(sii))
-		pcicore_up(sii->pch, SI_PCIUP);
-
-}
-
-/* Unconfigure and/or apply various WARs when system is going to sleep mode */
-void si_pci_sleep(si_t *sih)
-{
-	si_info_t *sii;
-
-	sii = SI_INFO(sih);
-
-	pcicore_sleep(sii->pch);
-}
-
-/* Unconfigure and/or apply various WARs when going down */
-void si_pci_down(si_t *sih)
-{
-	si_info_t *sii;
-
-	sii = SI_INFO(sih);
-
-	/* if not pci bus, we're done */
-	if (sih->bustype != PCI_BUS)
-		return;
-
-	/* release FORCEHT since chip is going to "down" state */
-	if (PCI_FORCEHT(sii))
-		_si_clkctl_cc(sii, CLK_DYNAMIC);
-
-	pcicore_down(sii->pch, SI_PCIDOWN);
-}
-
-/*
- * Configure the pci core for pci client (NIC) action
- * coremask is the bitvec of cores by index to be enabled.
- */
-void si_pci_setup(si_t *sih, uint coremask)
-{
-	si_info_t *sii;
-	struct sbpciregs *pciregs = NULL;
-	u32 siflag = 0, w;
-	uint idx = 0;
-
-	sii = SI_INFO(sih);
-
-	if (sii->pub.bustype != PCI_BUS)
-		return;
-
-	ASSERT(PCI(sii) || PCIE(sii));
-	ASSERT(sii->pub.buscoreidx != BADIDX);
-
-	if (PCI(sii)) {
-		/* get current core index */
-		idx = sii->curidx;
-
-		/* we interrupt on this backplane flag number */
-		siflag = si_flag(sih);
-
-		/* switch over to pci core */
-		pciregs = (struct sbpciregs *)si_setcoreidx(sih, sii->pub.buscoreidx);
-	}
-
-	/*
-	 * Enable sb->pci interrupts.  Assume
-	 * PCI rev 2.3 support was added in pci core rev 6 and things changed..
-	 */
-	if (PCIE(sii) || (PCI(sii) && ((sii->pub.buscorerev) >= 6))) {
-		/* pci config write to set this core bit in PCIIntMask */
-		pci_read_config_dword(sii->pbus, PCI_INT_MASK, &w);
-		w |= (coremask << PCI_SBIM_SHIFT);
-		pci_write_config_dword(sii->pbus, PCI_INT_MASK, w);
-	} else {
-		/* set sbintvec bit for our flag number */
-		si_setint(sih, siflag);
-	}
-
-	if (PCI(sii)) {
-		OR_REG(&pciregs->sbtopci2,
-		       (SBTOPCI_PREF | SBTOPCI_BURST));
-		if (sii->pub.buscorerev >= 11) {
-			OR_REG(&pciregs->sbtopci2,
-			       SBTOPCI_RC_READMULTI);
-			w = R_REG(&pciregs->clkrun);
-			W_REG(&pciregs->clkrun,
-			      (w | PCI_CLKRUN_DSBL));
-			w = R_REG(&pciregs->clkrun);
-		}
-
-		/* switch back to previous core */
-		si_setcoreidx(sih, idx);
-	}
-}
-
-/*
- * Fixup SROMless PCI device's configuration.
- * The current core may be changed upon return.
- */
-int si_pci_fixcfg(si_t *sih)
-{
-	uint origidx, pciidx;
-	struct sbpciregs *pciregs = NULL;
-	sbpcieregs_t *pcieregs = NULL;
-	void *regs = NULL;
-	u16 val16, *reg16 = NULL;
-
-	si_info_t *sii = SI_INFO(sih);
-
-	ASSERT(sii->pub.bustype == PCI_BUS);
-
-	/* Fixup PI in SROM shadow area to enable the correct PCI core access */
-	/* save the current index */
-	origidx = si_coreidx(&sii->pub);
-
-	/* check 'pi' is correct and fix it if not */
-	if (sii->pub.buscoretype == PCIE_CORE_ID) {
-		pcieregs =
-		    (sbpcieregs_t *) si_setcore(&sii->pub, PCIE_CORE_ID, 0);
-		regs = pcieregs;
-		ASSERT(pcieregs != NULL);
-		reg16 = &pcieregs->sprom[SRSH_PI_OFFSET];
-	} else if (sii->pub.buscoretype == PCI_CORE_ID) {
-		pciregs = (struct sbpciregs *)si_setcore(&sii->pub, PCI_CORE_ID, 0);
-		regs = pciregs;
-		ASSERT(pciregs != NULL);
-		reg16 = &pciregs->sprom[SRSH_PI_OFFSET];
-	}
-	pciidx = si_coreidx(&sii->pub);
-	val16 = R_REG(reg16);
-	if (((val16 & SRSH_PI_MASK) >> SRSH_PI_SHIFT) != (u16) pciidx) {
-		val16 =
-		    (u16) (pciidx << SRSH_PI_SHIFT) | (val16 &
-							  ~SRSH_PI_MASK);
-		W_REG(reg16, val16);
-	}
-
-	/* restore the original index */
-	si_setcoreidx(&sii->pub, origidx);
-
-	pcicore_hwup(sii->pch);
-	return 0;
-}
-
-/* mask&set gpiocontrol bits */
-u32 si_gpiocontrol(si_t *sih, u32 mask, u32 val, u8 priority)
-{
-	uint regoff;
-
-	regoff = 0;
-
-	/* gpios could be shared on router platforms
-	 * ignore reservation if it's high priority (e.g., test apps)
-	 */
-	if ((priority != GPIO_HI_PRIORITY) &&
-	    (sih->bustype == SI_BUS) && (val || mask)) {
-		mask = priority ? (si_gpioreservation & mask) :
-		    ((si_gpioreservation | mask) & ~(si_gpioreservation));
-		val &= mask;
-	}
-
-	regoff = offsetof(chipcregs_t, gpiocontrol);
-	return si_corereg(sih, SI_CC_IDX, regoff, mask, val);
-}
-
-/* Return the size of the specified SOCRAM bank */
-static uint
-socram_banksize(si_info_t *sii, sbsocramregs_t *regs, u8 index,
-		u8 mem_type)
-{
-	uint banksize, bankinfo;
-	uint bankidx = index | (mem_type << SOCRAM_BANKIDX_MEMTYPE_SHIFT);
-
-	ASSERT(mem_type <= SOCRAM_MEMTYPE_DEVRAM);
-
-	W_REG(&regs->bankidx, bankidx);
-	bankinfo = R_REG(&regs->bankinfo);
-	banksize =
-	    SOCRAM_BANKINFO_SZBASE * ((bankinfo & SOCRAM_BANKINFO_SZMASK) + 1);
-	return banksize;
-}
-
-/* Return the RAM size of the SOCRAM core */
-u32 si_socram_size(si_t *sih)
-{
-	si_info_t *sii;
-	uint origidx;
-	uint intr_val = 0;
-
-	sbsocramregs_t *regs;
-	bool wasup;
-	uint corerev;
-	u32 coreinfo;
-	uint memsize = 0;
-
-	sii = SI_INFO(sih);
-
-	/* Block ints and save current core */
-	INTR_OFF(sii, intr_val);
-	origidx = si_coreidx(sih);
-
-	/* Switch to SOCRAM core */
-	regs = si_setcore(sih, SOCRAM_CORE_ID, 0);
-	if (!regs)
-		goto done;
-
-	/* Get info for determining size */
-	wasup = si_iscoreup(sih);
-	if (!wasup)
-		si_core_reset(sih, 0, 0);
-	corerev = si_corerev(sih);
-	coreinfo = R_REG(&regs->coreinfo);
-
-	/* Calculate size from coreinfo based on rev */
-	if (corerev == 0)
-		memsize = 1 << (16 + (coreinfo & SRCI_MS0_MASK));
-	else if (corerev < 3) {
-		memsize = 1 << (SR_BSZ_BASE + (coreinfo & SRCI_SRBSZ_MASK));
-		memsize *= (coreinfo & SRCI_SRNB_MASK) >> SRCI_SRNB_SHIFT;
-	} else if ((corerev <= 7) || (corerev == 12)) {
-		uint nb = (coreinfo & SRCI_SRNB_MASK) >> SRCI_SRNB_SHIFT;
-		uint bsz = (coreinfo & SRCI_SRBSZ_MASK);
-		uint lss = (coreinfo & SRCI_LSS_MASK) >> SRCI_LSS_SHIFT;
-		if (lss != 0)
-			nb--;
-		memsize = nb * (1 << (bsz + SR_BSZ_BASE));
-		if (lss != 0)
-			memsize += (1 << ((lss - 1) + SR_BSZ_BASE));
-	} else {
-		u8 i;
-		uint nb = (coreinfo & SRCI_SRNB_MASK) >> SRCI_SRNB_SHIFT;
-		for (i = 0; i < nb; i++)
-			memsize +=
-			    socram_banksize(sii, regs, i, SOCRAM_MEMTYPE_RAM);
-	}
-
-	/* Return to previous state and core */
-	if (!wasup)
-		si_core_disable(sih, 0);
-	si_setcoreidx(sih, origidx);
-
- done:
-	INTR_RESTORE(sii, intr_val);
-
-	return memsize;
-}
-
-void si_chipcontrl_epa4331(si_t *sih, bool on)
-{
-	si_info_t *sii;
-	chipcregs_t *cc;
-	uint origidx;
-	u32 val;
-
-	sii = SI_INFO(sih);
-	origidx = si_coreidx(sih);
-
-	cc = (chipcregs_t *) si_setcore(sih, CC_CORE_ID, 0);
-
-	val = R_REG(&cc->chipcontrol);
-
-	if (on) {
-		if (sih->chippkg == 9 || sih->chippkg == 0xb) {
-			/* Ext PA Controls for 4331 12x9 Package */
-			W_REG(&cc->chipcontrol, val |
-			      (CCTRL4331_EXTPA_EN |
-			       CCTRL4331_EXTPA_ON_GPIO2_5));
-		} else {
-			/* Ext PA Controls for 4331 12x12 Package */
-			W_REG(&cc->chipcontrol,
-			      val | (CCTRL4331_EXTPA_EN));
-		}
-	} else {
-		val &= ~(CCTRL4331_EXTPA_EN | CCTRL4331_EXTPA_ON_GPIO2_5);
-		W_REG(&cc->chipcontrol, val);
-	}
-
-	si_setcoreidx(sih, origidx);
-}
-
-/* Enable BT-COEX & Ex-PA for 4313 */
-void si_epa_4313war(si_t *sih)
-{
-	si_info_t *sii;
-	chipcregs_t *cc;
-	uint origidx;
-
-	sii = SI_INFO(sih);
-	origidx = si_coreidx(sih);
-
-	cc = (chipcregs_t *) si_setcore(sih, CC_CORE_ID, 0);
-
-	/* EPA Fix */
-	W_REG(&cc->gpiocontrol,
-	      R_REG(&cc->gpiocontrol) | GPIO_CTRL_EPA_EN_MASK);
-
-	si_setcoreidx(sih, origidx);
-}
-
-/* check if the device is removed */
-bool si_deviceremoved(si_t *sih)
-{
-	u32 w;
-	si_info_t *sii;
-
-	sii = SI_INFO(sih);
-
-	switch (sih->bustype) {
-	case PCI_BUS:
-		ASSERT(sii->pbus != NULL);
-		pci_read_config_dword(sii->pbus, PCI_CFG_VID, &w);
-		if ((w & 0xFFFF) != VENDOR_BROADCOM)
-			return true;
-		break;
-	}
-	return false;
-}
-
-bool si_is_sprom_available(si_t *sih)
-{
-	if (sih->ccrev >= 31) {
-		si_info_t *sii;
-		uint origidx;
-		chipcregs_t *cc;
-		u32 sromctrl;
-
-		if ((sih->cccaps & CC_CAP_SROM) == 0)
-			return false;
-
-		sii = SI_INFO(sih);
-		origidx = sii->curidx;
-		cc = si_setcoreidx(sih, SI_CC_IDX);
-		sromctrl = R_REG(&cc->sromcontrol);
-		si_setcoreidx(sih, origidx);
-		return sromctrl & SRC_PRESENT;
-	}
-
-	switch (sih->chip) {
-	case BCM4329_CHIP_ID:
-		return (sih->chipst & CST4329_SPROM_SEL) != 0;
-	case BCM4319_CHIP_ID:
-		return (sih->chipst & CST4319_SPROM_SEL) != 0;
-	case BCM4336_CHIP_ID:
-		return (sih->chipst & CST4336_SPROM_PRESENT) != 0;
-	case BCM4330_CHIP_ID:
-		return (sih->chipst & CST4330_SPROM_PRESENT) != 0;
-	case BCM4313_CHIP_ID:
-		return (sih->chipst & CST4313_SPROM_PRESENT) != 0;
-	case BCM4331_CHIP_ID:
-		return (sih->chipst & CST4331_SPROM_PRESENT) != 0;
-	default:
-		return true;
-	}
-}
-
-bool si_is_otp_disabled(si_t *sih)
-{
-	switch (sih->chip) {
-	case BCM4329_CHIP_ID:
-		return (sih->chipst & CST4329_SPROM_OTP_SEL_MASK) ==
-		    CST4329_OTP_PWRDN;
-	case BCM4319_CHIP_ID:
-		return (sih->chipst & CST4319_SPROM_OTP_SEL_MASK) ==
-		    CST4319_OTP_PWRDN;
-	case BCM4336_CHIP_ID:
-		return (sih->chipst & CST4336_OTP_PRESENT) == 0;
-	case BCM4330_CHIP_ID:
-		return (sih->chipst & CST4330_OTP_PRESENT) == 0;
-	case BCM4313_CHIP_ID:
-		return (sih->chipst & CST4313_OTP_PRESENT) == 0;
-		/* These chips always have their OTP on */
-	case BCM43224_CHIP_ID:
-	case BCM43225_CHIP_ID:
-	case BCM43421_CHIP_ID:
-	case BCM43235_CHIP_ID:
-	case BCM43236_CHIP_ID:
-	case BCM43238_CHIP_ID:
-	case BCM4331_CHIP_ID:
-	default:
-		return false;
-	}
-}
-
-bool si_is_otp_powered(si_t *sih)
-{
-	if (PMUCTL_ENAB(sih))
-		return si_pmu_is_otp_powered(sih);
-	return true;
-}
-
-void si_otp_power(si_t *sih, bool on)
-{
-	if (PMUCTL_ENAB(sih))
-		si_pmu_otp_power(sih, on);
-	udelay(1000);
-}
-
diff -druN linux-2.6.39-libre/drivers/staging/brcm80211/util/siutils_priv.h linux-3.0-rc7-libre/drivers/staging/brcm80211/util/siutils_priv.h
--- linux-2.6.39-libre/drivers/staging/brcm80211/util/siutils_priv.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/brcm80211/util/siutils_priv.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,30 +0,0 @@
-/*
- * Copyright (c) 2010 Broadcom Corporation
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#ifndef	_siutils_priv_h_
-#define	_siutils_priv_h_
-
-/* Silicon Backplane externs */
-extern void sb_scan(si_t *sih, void *regs, uint devid);
-uint sb_coreid(si_t *sih);
-uint sb_corerev(si_t *sih);
-extern uint sb_corereg(si_t *sih, uint coreidx, uint regoff, uint mask,
-		       uint val);
-extern bool sb_iscoreup(si_t *sih);
-void *sb_setcoreidx(si_t *sih, uint coreidx);
-extern void sb_core_reset(si_t *sih, u32 bits, u32 resetbits);
-extern void sb_core_disable(si_t *sih, u32 bits);
-#endif				/* _siutils_priv_h_ */
diff -druN linux-2.6.39-libre/drivers/staging/comedi/drivers/addi-data/addi_common.c linux-3.0-rc7-libre/drivers/staging/comedi/drivers/addi-data/addi_common.c
--- linux-2.6.39-libre/drivers/staging/comedi/drivers/addi-data/addi_common.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/comedi/drivers/addi-data/addi_common.c	2011-07-11 19:51:52.000000000 -0400
@@ -77,7 +77,7 @@
 /* Update-0.7.57->0.7.68MODULE_LICENSE("GPL"); */
 
 #define devpriv ((struct addi_private *)dev->private)
-#define this_board ((struct addi_board *)dev->board_ptr)
+#define this_board ((const struct addi_board *)dev->board_ptr)
 
 #if defined(CONFIG_APCI_1710) || defined(CONFIG_APCI_3200) || defined(CONFIG_APCI_3300)
 /* BYTE b_SaveFPUReg [94]; */
@@ -2666,13 +2666,11 @@
 		devpriv->i_IobaseAmcc = (int) iobase_a;	/* AMCC base address... */
 		devpriv->i_IobaseAddon = (int) iobase_addon;	/* ADD ON base address.... */
 		devpriv->i_IobaseReserved = (int) iobase_reserved;
-		devpriv->ps_BoardInfo = this_board;
 	} else {
 		dev->board_name = this_board->pc_DriverName;
 		dev->iobase = (unsigned long)io_addr[2];
 		devpriv->amcc = card;
 		devpriv->iobase = (int) io_addr[2];
-		devpriv->ps_BoardInfo = this_board;
 		devpriv->i_IobaseReserved = (int) io_addr[3];
 		printk("\nioremap begin");
 		devpriv->dw_AiBase = ioremap(io_addr[3],
@@ -2680,6 +2678,21 @@
 		printk("\nioremap end");
 	}
 
+	/* Initialize parameters that can be overridden in EEPROM */
+	devpriv->s_EeParameters.i_NbrAiChannel = this_board->i_NbrAiChannel;
+	devpriv->s_EeParameters.i_NbrAoChannel = this_board->i_NbrAoChannel;
+	devpriv->s_EeParameters.i_AiMaxdata = this_board->i_AiMaxdata;
+	devpriv->s_EeParameters.i_AoMaxdata = this_board->i_AoMaxdata;
+	devpriv->s_EeParameters.i_NbrDiChannel = this_board->i_NbrDiChannel;
+	devpriv->s_EeParameters.i_NbrDoChannel = this_board->i_NbrDoChannel;
+	devpriv->s_EeParameters.i_DoMaxdata = this_board->i_DoMaxdata;
+	devpriv->s_EeParameters.i_Dma = this_board->i_Dma;
+	devpriv->s_EeParameters.i_Timer = this_board->i_Timer;
+	devpriv->s_EeParameters.ui_MinAcquisitiontimeNs =
+		this_board->ui_MinAcquisitiontimeNs;
+	devpriv->s_EeParameters.ui_MinDelaytimeNs =
+		this_board->ui_MinDelaytimeNs;
+
 	/* ## */
 
 	if (irq > 0) {
@@ -2728,7 +2741,7 @@
 		devpriv->us_UseDma = ADDI_ENABLE;
 	}
 
-	if (this_board->i_Dma) {
+	if (devpriv->s_EeParameters.i_Dma) {
 		printk("\nDMA used");
 		if (devpriv->us_UseDma == ADDI_ENABLE) {
 			/*  alloc DMA buffers */
@@ -2787,21 +2800,22 @@
 
 		/*  Allocate and Initialise AI Subdevice Structures */
 		s = dev->subdevices + 0;
-		if ((this_board->i_NbrAiChannel)
+		if ((devpriv->s_EeParameters.i_NbrAiChannel)
 			|| (this_board->i_NbrAiChannelDiff)) {
 			dev->read_subdev = s;
 			s->type = COMEDI_SUBD_AI;
 			s->subdev_flags =
 				SDF_READABLE | SDF_COMMON | SDF_GROUND
 				| SDF_DIFF;
-			if (this_board->i_NbrAiChannel) {
-				s->n_chan = this_board->i_NbrAiChannel;
+			if (devpriv->s_EeParameters.i_NbrAiChannel) {
+				s->n_chan =
+					devpriv->s_EeParameters.i_NbrAiChannel;
 				devpriv->b_SingelDiff = 0;
 			} else {
 				s->n_chan = this_board->i_NbrAiChannelDiff;
 				devpriv->b_SingelDiff = 1;
 			}
-			s->maxdata = this_board->i_AiMaxdata;
+			s->maxdata = devpriv->s_EeParameters.i_AiMaxdata;
 			s->len_chanlist = this_board->i_AiChannelList;
 			s->range_table = this_board->pr_AiRangelist;
 
@@ -2825,12 +2839,13 @@
 
 		/*  Allocate and Initialise AO Subdevice Structures */
 		s = dev->subdevices + 1;
-		if (this_board->i_NbrAoChannel) {
+		if (devpriv->s_EeParameters.i_NbrAoChannel) {
 			s->type = COMEDI_SUBD_AO;
 			s->subdev_flags = SDF_WRITEABLE | SDF_GROUND | SDF_COMMON;
-			s->n_chan = this_board->i_NbrAoChannel;
-			s->maxdata = this_board->i_AoMaxdata;
-			s->len_chanlist = this_board->i_NbrAoChannel;
+			s->n_chan = devpriv->s_EeParameters.i_NbrAoChannel;
+			s->maxdata = devpriv->s_EeParameters.i_AoMaxdata;
+			s->len_chanlist =
+				devpriv->s_EeParameters.i_NbrAoChannel;
 			s->range_table = this_board->pr_AoRangelist;
 			s->insn_config =
 				this_board->i_hwdrv_InsnConfigAnalogOutput;
@@ -2841,12 +2856,13 @@
 		}
 		/*  Allocate and Initialise DI Subdevice Structures */
 		s = dev->subdevices + 2;
-		if (this_board->i_NbrDiChannel) {
+		if (devpriv->s_EeParameters.i_NbrDiChannel) {
 			s->type = COMEDI_SUBD_DI;
 			s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_COMMON;
-			s->n_chan = this_board->i_NbrDiChannel;
+			s->n_chan = devpriv->s_EeParameters.i_NbrDiChannel;
 			s->maxdata = 1;
-			s->len_chanlist = this_board->i_NbrDiChannel;
+			s->len_chanlist =
+				devpriv->s_EeParameters.i_NbrDiChannel;
 			s->range_table = &range_digital;
 			s->io_bits = 0;	/* all bits input */
 			s->insn_config =
@@ -2860,13 +2876,14 @@
 		}
 		/*  Allocate and Initialise DO Subdevice Structures */
 		s = dev->subdevices + 3;
-		if (this_board->i_NbrDoChannel) {
+		if (devpriv->s_EeParameters.i_NbrDoChannel) {
 			s->type = COMEDI_SUBD_DO;
 			s->subdev_flags =
 				SDF_READABLE | SDF_WRITEABLE | SDF_GROUND | SDF_COMMON;
-			s->n_chan = this_board->i_NbrDoChannel;
-			s->maxdata = this_board->i_DoMaxdata;
-			s->len_chanlist = this_board->i_NbrDoChannel;
+			s->n_chan = devpriv->s_EeParameters.i_NbrDoChannel;
+			s->maxdata = devpriv->s_EeParameters.i_DoMaxdata;
+			s->len_chanlist =
+				devpriv->s_EeParameters.i_NbrDoChannel;
 			s->range_table = &range_digital;
 			s->io_bits = 0xf;	/* all bits output */
 
@@ -2883,7 +2900,7 @@
 
 		/*  Allocate and Initialise Timer Subdevice Structures */
 		s = dev->subdevices + 4;
-		if (this_board->i_Timer) {
+		if (devpriv->s_EeParameters.i_Timer) {
 			s->type = COMEDI_SUBD_TIMER;
 			s->subdev_flags = SDF_WRITEABLE | SDF_GROUND | SDF_COMMON;
 			s->n_chan = 1;
@@ -2968,8 +2985,8 @@
 			free_irq(dev->irq, dev);
 		}
 
-		if ((devpriv->ps_BoardInfo->pc_EepromChip == NULL)
-			|| (strcmp(devpriv->ps_BoardInfo->pc_EepromChip,
+		if ((this_board->pc_EepromChip == NULL)
+			|| (strcmp(this_board->pc_EepromChip,
 					ADDIDATA_9054) != 0)) {
 			if (devpriv->allocated) {
 				i_pci_card_free(devpriv->amcc);
diff -druN linux-2.6.39-libre/drivers/staging/comedi/drivers/addi-data/addi_common.h linux-3.0-rc7-libre/drivers/staging/comedi/drivers/addi-data/addi_common.h
--- linux-2.6.39-libre/drivers/staging/comedi/drivers/addi-data/addi_common.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/comedi/drivers/addi-data/addi_common.h	2011-07-11 19:51:52.000000000 -0400
@@ -406,7 +406,6 @@
 
 	/* Pointer to the current process */
 	struct task_struct *tsk_Current;
-	struct addi_board *ps_BoardInfo;
 
 	/* Hardware board infos for 1710 */
 	struct {
@@ -434,6 +433,22 @@
 	union str_ModuleInfo s_ModuleInfo[4];
 	unsigned int ul_TTLPortConfiguration[10];
 
+	/* Parameters read from EEPROM overriding static board info */
+	struct {
+		int i_NbrAiChannel;	/*  num of A/D chans */
+		int i_NbrAoChannel;	/*  num of D/A chans */
+		int i_AiMaxdata;	/*  resolution of A/D */
+		int i_AoMaxdata;	/*  resolution of D/A */
+		int i_NbrDiChannel;	/*  Number of DI channels */
+		int i_NbrDoChannel;	/*  Number of DO channels */
+		int i_DoMaxdata;	/*  data to set all channels high */
+		int i_Dma;		/*  dma present or not */
+		int i_Timer;		/*  timer subdevice present or not */
+		unsigned int ui_MinAcquisitiontimeNs;
+					/*  Minimum Acquisition in Nano secs */
+		unsigned int ui_MinDelaytimeNs;
+					/*  Minimum Delay in Nano secs */
+	} s_EeParameters;
 };
 
 static unsigned short pci_list_builded;	/* set to 1 when list of card is known */
diff -druN linux-2.6.39-libre/drivers/staging/comedi/drivers/addi-data/addi_eeprom.c linux-3.0-rc7-libre/drivers/staging/comedi/drivers/addi-data/addi_eeprom.c
--- linux-2.6.39-libre/drivers/staging/comedi/drivers/addi-data/addi_eeprom.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/comedi/drivers/addi-data/addi_eeprom.c	2011-07-11 19:51:52.000000000 -0400
@@ -847,7 +847,7 @@
 				pc_PCIChipInformation,
 				s_MainHeader.s_Functions[i].w_Address,
 				&s_DigitalInputHeader);
-			this_board->i_NbrDiChannel =
+			devpriv->s_EeParameters.i_NbrDiChannel =
 				s_DigitalInputHeader.w_Nchannel;
 			break;
 
@@ -856,11 +856,12 @@
 				pc_PCIChipInformation,
 				s_MainHeader.s_Functions[i].w_Address,
 				&s_DigitalOutputHeader);
-			this_board->i_NbrDoChannel =
+			devpriv->s_EeParameters.i_NbrDoChannel =
 				s_DigitalOutputHeader.w_Nchannel;
 			ui_Temp = 0xffffffff;
-			this_board->i_DoMaxdata =
-				ui_Temp >> (32 - this_board->i_NbrDoChannel);
+			devpriv->s_EeParameters.i_DoMaxdata =
+				ui_Temp >> (32 -
+					devpriv->s_EeParameters.i_NbrDoChannel);
 			break;
 
 		case EEPROM_ANALOGINPUT:
@@ -869,20 +870,21 @@
 				s_MainHeader.s_Functions[i].w_Address,
 				&s_AnalogInputHeader);
 			if (!(strcmp(this_board->pc_DriverName, "apci3200")))
-				this_board->i_NbrAiChannel =
+				devpriv->s_EeParameters.i_NbrAiChannel =
 					s_AnalogInputHeader.w_Nchannel * 4;
 			else
-				this_board->i_NbrAiChannel =
+				devpriv->s_EeParameters.i_NbrAiChannel =
 					s_AnalogInputHeader.w_Nchannel;
-			this_board->i_Dma = s_AnalogInputHeader.b_HasDma;
-			this_board->ui_MinAcquisitiontimeNs =
+			devpriv->s_EeParameters.i_Dma =
+				s_AnalogInputHeader.b_HasDma;
+			devpriv->s_EeParameters.ui_MinAcquisitiontimeNs =
 				(unsigned int) s_AnalogInputHeader.w_MinConvertTiming *
 				1000;
-			this_board->ui_MinDelaytimeNs =
+			devpriv->s_EeParameters.ui_MinDelaytimeNs =
 				(unsigned int) s_AnalogInputHeader.w_MinDelayTiming *
 				1000;
 			ui_Temp = 0xffff;
-			this_board->i_AiMaxdata =
+			devpriv->s_EeParameters.i_AiMaxdata =
 				ui_Temp >> (16 -
 				s_AnalogInputHeader.b_Resolution);
 			break;
@@ -892,24 +894,28 @@
 				pc_PCIChipInformation,
 				s_MainHeader.s_Functions[i].w_Address,
 				&s_AnalogOutputHeader);
-			this_board->i_NbrAoChannel =
+			devpriv->s_EeParameters.i_NbrAoChannel =
 				s_AnalogOutputHeader.w_Nchannel;
 			ui_Temp = 0xffff;
-			this_board->i_AoMaxdata =
+			devpriv->s_EeParameters.i_AoMaxdata =
 				ui_Temp >> (16 -
 				s_AnalogOutputHeader.b_Resolution);
 			break;
 
 		case EEPROM_TIMER:
-			this_board->i_Timer = 1;	/* Timer subdevice present */
+			/* Timer subdevice present */
+			devpriv->s_EeParameters.i_Timer = 1;
 			break;
 
 		case EEPROM_WATCHDOG:
-			this_board->i_Timer = 1;	/* Timer subdevice present */
+			/* Timer subdevice present */
+			devpriv->s_EeParameters.i_Timer = 1;
 			break;
 
 		case EEPROM_TIMER_WATCHDOG_COUNTER:
-			this_board->i_Timer = 1;	/* Timer subdevice present */
+			/* Timer subdevice present */
+			devpriv->s_EeParameters.i_Timer = 1;
+			break;
 		}
 	}
 
diff -druN linux-2.6.39-libre/drivers/staging/comedi/drivers/addi-data/APCI1710_Ssi.c linux-3.0-rc7-libre/drivers/staging/comedi/drivers/addi-data/APCI1710_Ssi.c
--- linux-2.6.39-libre/drivers/staging/comedi/drivers/addi-data/APCI1710_Ssi.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/comedi/drivers/addi-data/APCI1710_Ssi.c	2011-07-11 19:51:52.000000000 -0400
@@ -35,22 +35,8 @@
   | Project manager: Eric Stolz   | Date     :  02/12/2002                |
   +-----------------------------------------------------------------------+
   | Description :   APCI-1710 SSI counter module                          |
-  |                                                                       |
-  |                                                                       |
-  +-----------------------------------------------------------------------+
-  |                             UPDATES                                   |
-  +-----------------------------------------------------------------------+
-  |   Date   |   Author  |          Description of updates                |
-  +----------+-----------+------------------------------------------------+
-  | 13/05/98 | S. Weber  | SSI digital input / output implementation      |
-  |----------|-----------|------------------------------------------------|
-  | 22/03/00 | C.Guinot  | 0100/0226 -> 0200/0227                         |
-  |          |           | Änderung in InitSSI Funktion                   |
-  |          |           | b_SSIProfile >= 2 anstatt b_SSIProfile > 2     |
-  |          |           |                                                |
   +-----------------------------------------------------------------------+
-  | 08/05/00 | Guinot C  | - 0400/0228 All Function in RING 0             |
-  |          |           |   available                                    |
+  | several changes done by S. Weber in 1998 and C. Guinot in 2000        |
   +-----------------------------------------------------------------------+
 */
 
diff -druN linux-2.6.39-libre/drivers/staging/comedi/drivers/addi-data/hwdrv_apci16xx.c linux-3.0-rc7-libre/drivers/staging/comedi/drivers/addi-data/hwdrv_apci16xx.c
--- linux-2.6.39-libre/drivers/staging/comedi/drivers/addi-data/hwdrv_apci16xx.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/comedi/drivers/addi-data/hwdrv_apci16xx.c	2011-07-11 19:51:52.000000000 -0400
@@ -97,7 +97,7 @@
 	unsigned char b_Command = 0;
 	unsigned char b_Cpt = 0;
 	unsigned char b_NumberOfPort =
-		(unsigned char) (devpriv->ps_BoardInfo->i_NbrTTLChannel / 8);
+		(unsigned char) (this_board->i_NbrTTLChannel / 8);
 
 	/************************/
 	/* Test the buffer size */
@@ -289,7 +289,7 @@
 	int i_ReturnValue = insn->n;
 	unsigned char b_Command = 0;
 	unsigned char b_NumberOfPort =
-		(unsigned char) (devpriv->ps_BoardInfo->i_NbrTTLChannel / 8);
+		(unsigned char) (this_board->i_NbrTTLChannel / 8);
 	unsigned char b_SelectedPort = CR_RANGE(insn->chanspec);
 	unsigned char b_InputChannel = CR_CHAN(insn->chanspec);
 	unsigned char *pb_Status;
@@ -450,9 +450,9 @@
 	   /**********************************/
 
 		b_NumberOfPort =
-			(unsigned char) (devpriv->ps_BoardInfo->i_NbrTTLChannel / 32);
+			(unsigned char) (this_board->i_NbrTTLChannel / 32);
 		if ((b_NumberOfPort * 32) <
-			devpriv->ps_BoardInfo->i_NbrTTLChannel) {
+			this_board->i_NbrTTLChannel) {
 			b_NumberOfPort = b_NumberOfPort + 1;
 		}
 
@@ -576,7 +576,7 @@
 	int i_ReturnValue = insn->n;
 	unsigned char b_Command = 0;
 	unsigned char b_NumberOfPort =
-		(unsigned char) (devpriv->ps_BoardInfo->i_NbrTTLChannel / 8);
+		(unsigned char) (this_board->i_NbrTTLChannel / 8);
 	unsigned char b_SelectedPort = CR_RANGE(insn->chanspec);
 	unsigned char b_OutputChannel = CR_CHAN(insn->chanspec);
 	unsigned int dw_Status = 0;
diff -druN linux-2.6.39-libre/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c linux-3.0-rc7-libre/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c
--- linux-2.6.39-libre/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c	2011-07-11 19:51:52.000000000 -0400
@@ -90,7 +90,8 @@
 		/* Test the number of the channel */
 		for (i = 0; i < data[3]; i++) {
 
-			if (CR_CHAN(data[4 + i]) >= this_board->i_NbrAiChannel) {
+			if (CR_CHAN(data[4 + i]) >=
+				devpriv->s_EeParameters.i_NbrAiChannel) {
 				printk("bad channel list\n");
 				return -2;
 			}
@@ -541,8 +542,10 @@
 	}
 
 	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;
+		if (cmd->scan_begin_arg <
+				devpriv->s_EeParameters.ui_MinDelaytimeNs) {
+			cmd->scan_begin_arg =
+				devpriv->s_EeParameters.ui_MinDelaytimeNs;
 			err++;
 		}
 	}
@@ -551,16 +554,18 @@
 		if (cmd->scan_begin_src == TRIG_TIMER) {
 			if ((cmd->convert_arg)
 				&& (cmd->convert_arg <
-					this_board->ui_MinAcquisitiontimeNs)) {
-				cmd->convert_arg =
-					this_board->ui_MinAcquisitiontimeNs;
+					devpriv->s_EeParameters.
+						ui_MinAcquisitiontimeNs)) {
+				cmd->convert_arg = devpriv->s_EeParameters.
+					ui_MinAcquisitiontimeNs;
 				err++;
 			}
 		} else {
 			if (cmd->convert_arg <
-				this_board->ui_MinAcquisitiontimeNs) {
-				cmd->convert_arg =
-					this_board->ui_MinAcquisitiontimeNs;
+				devpriv->s_EeParameters.ui_MinAcquisitiontimeNs
+				) {
+				cmd->convert_arg = devpriv->s_EeParameters.
+					ui_MinAcquisitiontimeNs;
 				err++;
 
 			}
@@ -2452,7 +2457,7 @@
 				     struct comedi_insn *insn,
 				     unsigned int *data)
 {
-	if ((data[0] > this_board->i_DoMaxdata) || (data[0] < 0)) {
+	if ((data[0] > devpriv->s_EeParameters.i_DoMaxdata) || (data[0] < 0)) {
 
 		comedi_error(dev, "Data is not valid !!! \n");
 		return -EINVAL;
@@ -2515,7 +2520,7 @@
 			"Not a valid Data !!! ,Data should be 1 or 0\n");
 		return -EINVAL;
 	}
-	if (ui_NoOfChannel > this_board->i_NbrDoChannel - 1) {
+	if (ui_NoOfChannel > devpriv->s_EeParameters.i_NbrDoChannel - 1) {
 		comedi_error(dev,
 			"This board doesn't have specified channel !!! \n");
 		return -EINVAL;
diff -druN linux-2.6.39-libre/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3xxx.c linux-3.0-rc7-libre/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3xxx.c
--- linux-2.6.39-libre/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3xxx.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3xxx.c	2011-07-11 19:51:52.000000000 -0400
@@ -141,8 +141,7 @@
 		/* Test the time base */
 	   /**********************/
 
-		if ((devpriv->ps_BoardInfo->
-				b_AvailableConvertUnit & (1 << b_TimeBase)) !=
+		if ((this_board->b_AvailableConvertUnit & (1 << b_TimeBase)) !=
 			0) {
 	      /*******************************/
 			/* Test the convert time value */
@@ -165,12 +164,16 @@
 		 /*******************************/
 
 				if (dw_TestReloadValue >=
-					devpriv->ps_BoardInfo->
+					devpriv->s_EeParameters.
 					ui_MinAcquisitiontimeNs) {
 					if ((b_SingleDiff == APCI3XXX_SINGLE)
 						|| (b_SingleDiff ==
 							APCI3XXX_DIFF)) {
-						if (((b_SingleDiff == APCI3XXX_SINGLE) && (devpriv->ps_BoardInfo->i_NbrAiChannel == 0)) || ((b_SingleDiff == APCI3XXX_DIFF) && (devpriv->ps_BoardInfo->i_NbrAiChannelDiff == 0))) {
+						if (((b_SingleDiff == APCI3XXX_SINGLE)
+						        && (devpriv->s_EeParameters.i_NbrAiChannel == 0))
+						    || ((b_SingleDiff == APCI3XXX_DIFF)
+							&& (this_board->i_NbrAiChannelDiff == 0))
+						    ) {
 			   /*******************************/
 							/* Single/Diff selection error */
 			   /*******************************/
@@ -372,10 +375,9 @@
 		/* Test the channel number */
 	   /***************************/
 
-		if (((b_Channel < devpriv->ps_BoardInfo->i_NbrAiChannel)
+		if (((b_Channel < devpriv->s_EeParameters.i_NbrAiChannel)
 				&& (devpriv->b_SingelDiff == APCI3XXX_SINGLE))
-			|| ((b_Channel < devpriv->ps_BoardInfo->
-					i_NbrAiChannelDiff)
+			|| ((b_Channel < this_board->i_NbrAiChannelDiff)
 				&& (devpriv->b_SingelDiff == APCI3XXX_DIFF))) {
 	      /**********************************/
 			/* Test the channel configuration */
@@ -663,7 +665,7 @@
 		/* Test the channel number */
 	   /***************************/
 
-		if (b_Channel < devpriv->ps_BoardInfo->i_NbrAoChannel) {
+		if (b_Channel < devpriv->s_EeParameters.i_NbrAoChannel) {
 	      /**********************************/
 			/* Test the channel configuration */
 	      /**********************************/
@@ -1273,7 +1275,7 @@
 	/* Test the channel number */
 	/***************************/
 
-	if (b_Channel <= devpriv->ps_BoardInfo->i_NbrDiChannel) {
+	if (b_Channel <= devpriv->s_EeParameters.i_NbrDiChannel) {
 	   /************************/
 		/* Test the buffer size */
 	   /************************/
@@ -1492,7 +1494,7 @@
 		/* Test the channel number */
 	   /***************************/
 
-		if (b_Channel < devpriv->ps_BoardInfo->i_NbrDoChannel) {
+		if (b_Channel < devpriv->s_EeParameters.i_NbrDoChannel) {
 	      /*******************/
 			/* Get the command */
 	      /*******************/
@@ -1568,7 +1570,7 @@
 		/* Test the channel number */
 	   /***************************/
 
-		if (b_Channel < devpriv->ps_BoardInfo->i_NbrDoChannel) {
+		if (b_Channel < devpriv->s_EeParameters.i_NbrDoChannel) {
 	      /********************************/
 			/* Read the digital output port */
 	      /********************************/
diff -druN linux-2.6.39-libre/drivers/staging/comedi/drivers/adl_pci9118.c linux-3.0-rc7-libre/drivers/staging/comedi/drivers/adl_pci9118.c
--- linux-2.6.39-libre/drivers/staging/comedi/drivers/adl_pci9118.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/comedi/drivers/adl_pci9118.c	2011-07-11 19:51:52.000000000 -0400
@@ -1417,7 +1417,7 @@
 		comedi_error(dev,
 			     "pci9118_ai_docmd_sampl() mode number bug!\n");
 		return -EIO;
-	};
+	}
 
 	devpriv->int_ai_func = interrupt_pci9118_ai_onesample;
 						/* transfer function */
@@ -1496,7 +1496,7 @@
 	default:
 		comedi_error(dev, "pci9118_ai_docmd_dma() mode number bug!\n");
 		return -EIO;
-	};
+	}
 
 	if (devpriv->ai12_startstop) {
 		pci9118_exttrg_add(dev, EXTTRG_AI);
diff -druN linux-2.6.39-libre/drivers/staging/comedi/drivers/adv_pci_dio.c linux-3.0-rc7-libre/drivers/staging/comedi/drivers/adv_pci_dio.c
--- linux-2.6.39-libre/drivers/staging/comedi/drivers/adv_pci_dio.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/comedi/drivers/adv_pci_dio.c	2011-07-11 19:51:52.000000000 -0400
@@ -117,6 +117,7 @@
 
 /*  Advantech PCI-1751/3/3E */
 #define PCI1751_DIO	   0	/* R/W: begin of 8255 registers block */
+#define PCI1751_CNT	  24	/* R/W: begin of 8254 registers block */
 #define PCI1751_ICR	  32	/* W:   Interrupt control register */
 #define PCI1751_ISR	  32	/* R:   Interrupt status register */
 #define PCI1753_DIO	   0	/* R/W: begin of 8255 registers block */
@@ -329,7 +330,7 @@
 	 { {0, 0, 0, 0}, {0, 0, 0, 0} },
 	 { {48, PCI1751_DIO, 2, 0}, {0, 0, 0, 0} },
 	 {0, 0, 0, 0},
-	 { {0, 0, 0, 0} },
+	 { {3, PCI1751_CNT, 1, 0} },
 	 IO_8b},
 	{"pci1752", PCI_VENDOR_ID_ADVANTECH, 0x1752, PCIDIO_MAINREG,
 	 TYPE_PCI1752,
diff -druN linux-2.6.39-libre/drivers/staging/comedi/drivers/cb_das16_cs.c linux-3.0-rc7-libre/drivers/staging/comedi/drivers/cb_das16_cs.c
--- linux-2.6.39-libre/drivers/staging/comedi/drivers/cb_das16_cs.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/comedi/drivers/cb_das16_cs.c	2011-07-11 19:51:52.000000000 -0400
@@ -772,7 +772,7 @@
 
 /*====================================================================*/
 
-static struct pcmcia_device_id das16cs_id_table[] = {
+static const struct pcmcia_device_id das16cs_id_table[] = {
 	PCMCIA_DEVICE_MANF_CARD(0x01c5, 0x0039),
 	PCMCIA_DEVICE_MANF_CARD(0x01c5, 0x4009),
 	PCMCIA_DEVICE_NULL
diff -druN linux-2.6.39-libre/drivers/staging/comedi/drivers/cb_pcidda.c linux-3.0-rc7-libre/drivers/staging/comedi/drivers/cb_pcidda.c
--- linux-2.6.39-libre/drivers/staging/comedi/drivers/cb_pcidda.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/comedi/drivers/cb_pcidda.c	2011-07-11 19:51:52.000000000 -0400
@@ -650,7 +650,7 @@
 	case 5:
 		command |= UNIP | RANGE2V5;
 		break;
-	};
+	}
 
 	/* output channel specification */
 	command |= channel << 2;
diff -druN linux-2.6.39-libre/drivers/staging/comedi/drivers/cb_pcimdas.c linux-3.0-rc7-libre/drivers/staging/comedi/drivers/cb_pcimdas.c
--- linux-2.6.39-libre/drivers/staging/comedi/drivers/cb_pcimdas.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/comedi/drivers/cb_pcimdas.c	2011-07-11 19:51:52.000000000 -0400
@@ -264,7 +264,7 @@
 	default:
 		printk("THIS CARD IS UNSUPPORTED.\n"
 		       "PLEASE REPORT USAGE TO <mocelet@sucs.org>\n");
-	};
+	}
 
 	if (comedi_pci_enable(pcidev, "cb_pcimdas")) {
 		printk(" Failed to enable PCI device and request regions\n");
diff -druN linux-2.6.39-libre/drivers/staging/comedi/drivers/das08_cs.c linux-3.0-rc7-libre/drivers/staging/comedi/drivers/das08_cs.c
--- linux-2.6.39-libre/drivers/staging/comedi/drivers/das08_cs.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/comedi/drivers/das08_cs.c	2011-07-11 19:51:52.000000000 -0400
@@ -219,7 +219,7 @@
 
 /*====================================================================*/
 
-static struct pcmcia_device_id das08_cs_id_table[] = {
+static const struct pcmcia_device_id das08_cs_id_table[] = {
 	PCMCIA_DEVICE_MANF_CARD(0x01c5, 0x4001),
 	PCMCIA_DEVICE_NULL
 };
diff -druN linux-2.6.39-libre/drivers/staging/comedi/drivers/jr3_pci.c linux-3.0-rc7-libre/drivers/staging/comedi/drivers/jr3_pci.c
--- linux-2.6.39-libre/drivers/staging/comedi/drivers/jr3_pci.c	2011-05-19 02:17:22.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/comedi/drivers/jr3_pci.c	2011-07-21 06:59:20.000000000 -0400
@@ -193,9 +193,8 @@
 		set_s16(&channel->transforms[num].link[i].link_amount,
 			transf.link[i].link_amount);
 		udelay(1);
-		if (transf.link[i].link_type == end_x_form) {
+		if (transf.link[i].link_type == end_x_form)
 			break;
-		}
 	}
 }
 
@@ -460,9 +459,8 @@
 				unsigned int count, addr;
 				more = more
 				    && read_idm_word(data, size, &pos, &count);
-				if (more && count == 0xffff) {
+				if (more && count == 0xffff)
 					break;
-				}
 				more = more
 				    && read_idm_word(data, size, &pos, &addr);
 				printk("Loading#%d %4.4x bytes at %4.4x\n", i,
@@ -793,9 +791,8 @@
 	}
 
 	result = alloc_private(dev, sizeof(struct jr3_pci_dev_private));
-	if (result < 0) {
+	if (result < 0)
 		return -ENOMEM;
-	}
 	card = NULL;
 	devpriv = dev->private;
 	init_timer(&devpriv->timer);
@@ -851,9 +848,8 @@
 	}
 
 	result = comedi_pci_enable(card, "jr3_pci");
-	if (result < 0) {
+	if (result < 0)
 		return -EIO;
-	}
 
 	devpriv->pci_enabled = 1;
 	devpriv->iobase = ioremap(pci_resource_start(card, 0),
@@ -922,9 +918,8 @@
 	result = comedi_load_firmware(dev, "/*(DEBLOBBED)*/", jr3_download_firmware);
 	printk("Firmare load %d\n", result);
 
-	if (result < 0) {
+	if (result < 0)
 		goto out;
-	}
 /*
  * TODO: use firmware to load preferred offset tables. Suggested
  * format:
@@ -973,21 +968,17 @@
 		del_timer_sync(&devpriv->timer);
 
 		if (dev->subdevices) {
-			for (i = 0; i < devpriv->n_channels; i++) {
+			for (i = 0; i < devpriv->n_channels; i++)
 				kfree(dev->subdevices[i].private);
-			}
 		}
 
-		if (devpriv->iobase) {
+		if (devpriv->iobase)
 			iounmap((void *)devpriv->iobase);
-		}
-		if (devpriv->pci_enabled) {
+		if (devpriv->pci_enabled)
 			comedi_pci_disable(devpriv->pci_dev);
-		}
 
-		if (devpriv->pci_dev) {
+		if (devpriv->pci_dev)
 			pci_dev_put(devpriv->pci_dev);
-		}
 	}
 	return 0;
 }
diff -druN linux-2.6.39-libre/drivers/staging/comedi/drivers/ni_660x.c linux-3.0-rc7-libre/drivers/staging/comedi/drivers/ni_660x.c
--- linux-2.6.39-libre/drivers/staging/comedi/drivers/ni_660x.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/comedi/drivers/ni_660x.c	2011-07-11 19:51:52.000000000 -0400
@@ -1418,7 +1418,7 @@
 	default:
 		return -EINVAL;
 		break;
-	};
+	}
 	return 0;
 }
 
diff -druN linux-2.6.39-libre/drivers/staging/comedi/drivers/ni_daq_700.c linux-3.0-rc7-libre/drivers/staging/comedi/drivers/ni_daq_700.c
--- linux-2.6.39-libre/drivers/staging/comedi/drivers/ni_daq_700.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/comedi/drivers/ni_daq_700.c	2011-07-11 19:51:52.000000000 -0400
@@ -552,7 +552,7 @@
 
 /*====================================================================*/
 
-static struct pcmcia_device_id dio700_cs_ids[] = {
+static const struct pcmcia_device_id dio700_cs_ids[] = {
 	/* N.B. These IDs should match those in dio700_boards */
 	PCMCIA_DEVICE_MANF_CARD(0x010b, 0x4743),	/* daqcard-700 */
 	PCMCIA_DEVICE_NULL
diff -druN linux-2.6.39-libre/drivers/staging/comedi/drivers/ni_daq_dio24.c linux-3.0-rc7-libre/drivers/staging/comedi/drivers/ni_daq_dio24.c
--- linux-2.6.39-libre/drivers/staging/comedi/drivers/ni_daq_dio24.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/comedi/drivers/ni_daq_dio24.c	2011-07-11 19:51:52.000000000 -0400
@@ -304,7 +304,7 @@
 
 /*====================================================================*/
 
-static struct pcmcia_device_id dio24_cs_ids[] = {
+static const struct pcmcia_device_id dio24_cs_ids[] = {
 	/* N.B. These IDs should match those in dio24_boards */
 	PCMCIA_DEVICE_MANF_CARD(0x010b, 0x475c),	/* daqcard-dio24 */
 	PCMCIA_DEVICE_NULL
diff -druN linux-2.6.39-libre/drivers/staging/comedi/drivers/ni_labpc_cs.c linux-3.0-rc7-libre/drivers/staging/comedi/drivers/ni_labpc_cs.c
--- linux-2.6.39-libre/drivers/staging/comedi/drivers/ni_labpc_cs.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/comedi/drivers/ni_labpc_cs.c	2011-07-11 19:51:52.000000000 -0400
@@ -267,7 +267,7 @@
 	return 0;
 }				/* labpc_cs_resume */
 
-static struct pcmcia_device_id labpc_cs_ids[] = {
+static const struct pcmcia_device_id labpc_cs_ids[] = {
 	/* N.B. These IDs should match those in labpc_cs_boards (ni_labpc.c) */
 	PCMCIA_DEVICE_MANF_CARD(0x010b, 0x0103),	/* daqcard-1200 */
 	PCMCIA_DEVICE_NULL
diff -druN linux-2.6.39-libre/drivers/staging/comedi/drivers/ni_mio_common.c linux-3.0-rc7-libre/drivers/staging/comedi/drivers/ni_mio_common.c
--- linux-2.6.39-libre/drivers/staging/comedi/drivers/ni_mio_common.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/comedi/drivers/ni_mio_common.c	2011-07-11 19:51:52.000000000 -0400
@@ -1627,7 +1627,7 @@
 	default:
 		mite_prep_dma(devpriv->ai_mite_chan, 16, 16);
 		break;
-	};
+	}
 	/*start the MITE */
 	mite_dma_arm(devpriv->ai_mite_chan);
 	spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
@@ -2156,7 +2156,7 @@
 	default:
 		/*  multiplexed inputs */
 		break;
-	};
+	}
 	return boardtype.ai_speed * num_channels;
 }
 
@@ -5173,7 +5173,7 @@
 		devpriv->stc_writew(dev, devpriv->an_trig_etc_reg,
 				    Analog_Trigger_Etc_Register);
 		break;
-	};
+	}
 
 	devpriv->gpct_mode[chan] = 0;
 	devpriv->gpct_input_select[chan] = 0;
diff -druN linux-2.6.39-libre/drivers/staging/comedi/drivers/ni_mio_cs.c linux-3.0-rc7-libre/drivers/staging/comedi/drivers/ni_mio_cs.c
--- linux-2.6.39-libre/drivers/staging/comedi/drivers/ni_mio_cs.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/comedi/drivers/ni_mio_cs.c	2011-07-11 19:51:52.000000000 -0400
@@ -416,7 +416,7 @@
 
 #ifdef MODULE
 
-static struct pcmcia_device_id ni_mio_cs_ids[] = {
+static const struct pcmcia_device_id ni_mio_cs_ids[] = {
 	PCMCIA_DEVICE_MANF_CARD(0x010b, 0x010d),	/* DAQCard-ai-16xe-50 */
 	PCMCIA_DEVICE_MANF_CARD(0x010b, 0x010c),	/* DAQCard-ai-16e-4 */
 	PCMCIA_DEVICE_MANF_CARD(0x010b, 0x02c4),	/* DAQCard-6062E */
diff -druN linux-2.6.39-libre/drivers/staging/comedi/drivers/ni_tio.c linux-3.0-rc7-libre/drivers/staging/comedi/drivers/ni_tio.c
--- linux-2.6.39-libre/drivers/staging/comedi/drivers/ni_tio.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/comedi/drivers/ni_tio.c	2011-07-11 19:51:52.000000000 -0400
@@ -1181,7 +1181,7 @@
 			break;
 		return -EINVAL;
 		break;
-	};
+	}
 	counter_dev->regs[second_gate_reg] |= Gi_Second_Gate_Mode_Bit;
 	counter_dev->regs[second_gate_reg] &= ~Gi_Second_Gate_Select_Mask;
 	counter_dev->regs[second_gate_reg] |=
@@ -1209,7 +1209,7 @@
 		ni_m_series_second_gate_select =
 		    selected_second_gate & selected_second_gate_mask;
 		break;
-	};
+	}
 	counter_dev->regs[second_gate_reg] |= Gi_Second_Gate_Mode_Bit;
 	counter_dev->regs[second_gate_reg] &= ~Gi_Second_Gate_Select_Mask;
 	counter_dev->regs[second_gate_reg] |=
@@ -1674,7 +1674,7 @@
 		    counter_dev->
 		    regs[NITIO_Gi_LoadB_Reg(counter->counter_index)];
 		break;
-	};
+	}
 	return 0;
 }
 EXPORT_SYMBOL_GPL(ni_tio_rinsn);
diff -druN linux-2.6.39-libre/drivers/staging/comedi/drivers/pcl724.c linux-3.0-rc7-libre/drivers/staging/comedi/drivers/pcl724.c
--- linux-2.6.39-libre/drivers/staging/comedi/drivers/pcl724.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/comedi/drivers/pcl724.c	2011-07-11 19:51:52.000000000 -0400
@@ -209,7 +209,7 @@
 					 subdev_8255_cb,
 					 (unsigned long)(dev->iobase +
 							 SIZE_8255 * i));
-	};
+	}
 
 	return 0;
 }
diff -druN linux-2.6.39-libre/drivers/staging/comedi/drivers/pcl818.c linux-3.0-rc7-libre/drivers/staging/comedi/drivers/pcl818.c
--- linux-2.6.39-libre/drivers/staging/comedi/drivers/pcl818.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/comedi/drivers/pcl818.c	2011-07-11 19:51:52.000000000 -0400
@@ -1662,7 +1662,7 @@
 		tmp = (CMOS_READ(RTC_INTR_FLAGS) & 0xF0);	/* restart */
 		restore_flags(flags);
 		break;
-	};
+	}
 }
 
 /*
diff -druN linux-2.6.39-libre/drivers/staging/comedi/drivers/pcm3724.c linux-3.0-rc7-libre/drivers/staging/comedi/drivers/pcm3724.c
--- linux-2.6.39-libre/drivers/staging/comedi/drivers/pcm3724.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/comedi/drivers/pcm3724.c	2011-07-11 19:51:52.000000000 -0400
@@ -301,7 +301,7 @@
 		subdev_8255_init(dev, dev->subdevices + i, subdev_8255_cb,
 				 (unsigned long)(dev->iobase + SIZE_8255 * i));
 		((dev->subdevices) + i)->insn_config = subdev_3724_insn_config;
-	};
+	}
 	return 0;
 }
 
diff -druN linux-2.6.39-libre/drivers/staging/comedi/drivers/quatech_daqp_cs.c linux-3.0-rc7-libre/drivers/staging/comedi/drivers/quatech_daqp_cs.c
--- linux-2.6.39-libre/drivers/staging/comedi/drivers/quatech_daqp_cs.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/comedi/drivers/quatech_daqp_cs.c	2011-07-11 19:51:52.000000000 -0400
@@ -1087,7 +1087,7 @@
 
 #ifdef MODULE
 
-static struct pcmcia_device_id daqp_cs_id_table[] = {
+static const struct pcmcia_device_id daqp_cs_id_table[] = {
 	PCMCIA_DEVICE_MANF_CARD(0x0137, 0x0027),
 	PCMCIA_DEVICE_NULL
 };
diff -druN linux-2.6.39-libre/drivers/staging/comedi/drivers/usbdux.c linux-3.0-rc7-libre/drivers/staging/comedi/drivers/usbdux.c
--- linux-2.6.39-libre/drivers/staging/comedi/drivers/usbdux.c	2011-05-19 02:17:26.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/comedi/drivers/usbdux.c	2011-07-21 06:59:23.000000000 -0400
@@ -1530,7 +1530,7 @@
 	/* we always output at 1kHz just now all channels at once */
 	if (0) {		/* (this_usbduxsub->high_speed) */
 		/*
-		 * in usb-2.0 only one conversion it tranmitted but with 8kHz/n
+		 * in usb-2.0 only one conversion it transmitted but with 8kHz/n
 		 */
 		cmd->convert_src &= TRIG_TIMER;
 	} else {
diff -druN linux-2.6.39-libre/drivers/staging/comedi/drivers/vmk80xx.c linux-3.0-rc7-libre/drivers/staging/comedi/drivers/vmk80xx.c
--- linux-2.6.39-libre/drivers/staging/comedi/drivers/vmk80xx.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/comedi/drivers/vmk80xx.c	2011-07-11 19:51:52.000000000 -0400
@@ -64,6 +64,8 @@
 
 #include "../comedidev.h"
 
+#define BOARDNAME "vmk80xx"
+
 MODULE_AUTHOR("Manuel Gebele <forensixs@gmx.de>");
 MODULE_DESCRIPTION("Velleman USB Board Low-Level Driver");
 MODULE_SUPPORTED_DEVICE("K8055/K8061 aka VM110/VM140");
@@ -305,8 +307,10 @@
 
 static int vmk80xx_check_data_link(struct vmk80xx_usb *dev)
 {
-	unsigned int tx_pipe, rx_pipe;
-	unsigned char tx[1], rx[2];
+	unsigned int tx_pipe;
+	unsigned int rx_pipe;
+	unsigned char tx[1];
+	unsigned char rx[2];
 
 	dbgvm("vmk80xx: %s\n", __func__);
 
@@ -315,9 +319,11 @@
 
 	tx[0] = VMK8061_CMD_RD_PWR_STAT;
 
-	/* Check that IC6 (PIC16F871) is powered and
+	/*
+	 * Check that IC6 (PIC16F871) is powered and
 	 * running and the data link between IC3 and
-	 * IC6 is working properly */
+	 * IC6 is working properly
+	 */
 	usb_bulk_msg(dev->udev, tx_pipe, tx, 1, NULL, dev->ep_tx->bInterval);
 	usb_bulk_msg(dev->udev, rx_pipe, rx, 2, NULL, HZ * 10);
 
@@ -326,8 +332,10 @@
 
 static void vmk80xx_read_eeprom(struct vmk80xx_usb *dev, int flag)
 {
-	unsigned int tx_pipe, rx_pipe;
-	unsigned char tx[1], rx[64];
+	unsigned int tx_pipe;
+	unsigned int rx_pipe;
+	unsigned char tx[1];
+	unsigned char rx[64];
 	int cnt;
 
 	dbgvm("vmk80xx: %s\n", __func__);
@@ -337,8 +345,10 @@
 
 	tx[0] = VMK8061_CMD_RD_VERSION;
 
-	/* Read the firmware version info of IC3 and
-	 * IC6 from the internal EEPROM of the IC */
+	/*
+	 * Read the firmware version info of IC3 and
+	 * IC6 from the internal EEPROM of the IC
+	 */
 	usb_bulk_msg(dev->udev, tx_pipe, tx, 1, NULL, dev->ep_tx->bInterval);
 	usb_bulk_msg(dev->udev, rx_pipe, rx, 64, &cnt, HZ * 10);
 
@@ -388,7 +398,8 @@
 static void vmk80xx_build_int_urb(struct urb *urb, int flag)
 {
 	struct vmk80xx_usb *dev = urb->context;
-	__u8 rx_addr, tx_addr;
+	__u8 rx_addr;
+	__u8 tx_addr;
 	unsigned int pipe;
 	unsigned char *buf;
 	size_t size;
@@ -418,8 +429,10 @@
 
 static void vmk80xx_do_bulk_msg(struct vmk80xx_usb *dev)
 {
-	__u8 tx_addr, rx_addr;
-	unsigned int tx_pipe, rx_pipe;
+	__u8 tx_addr;
+	__u8 rx_addr;
+	unsigned int tx_pipe;
+	unsigned int rx_pipe;
 	size_t size;
 
 	dbgvm("vmk80xx: %s\n", __func__);
@@ -432,8 +445,10 @@
 	tx_pipe = usb_sndbulkpipe(dev->udev, tx_addr);
 	rx_pipe = usb_rcvbulkpipe(dev->udev, rx_addr);
 
-	/* The max packet size attributes of the K8061
-	 * input/output endpoints are identical */
+	/*
+	 * The max packet size attributes of the K8061
+	 * input/output endpoints are identical
+	 */
 	size = le16_to_cpu(dev->ep_tx->wMaxPacketSize);
 
 	usb_bulk_msg(dev->udev, tx_pipe, dev->usb_tx_buf,
@@ -544,34 +559,40 @@
 #define DIR_IN  1
 #define DIR_OUT 2
 
-#define rudimentary_check(dir)                             \
-do {                                                       \
-	if (!dev)                                          \
-		return -EFAULT;                            \
-	if (!dev->probed)                                  \
-		return -ENODEV;                            \
-	if (!dev->attached)                                \
-		return -ENODEV;                            \
-	if ((dir) & DIR_IN) {                              \
-		if (test_bit(TRANS_IN_BUSY, &dev->flags))  \
-			return -EBUSY;                     \
-	} else {  /* DIR_OUT */                            \
-		if (test_bit(TRANS_OUT_BUSY, &dev->flags)) \
-			return -EBUSY;                     \
-	}                                                  \
-} while (0)
+static int rudimentary_check(struct vmk80xx_usb *dev, int dir)
+{
+	if (!dev)
+		return -EFAULT;
+	if (!dev->probed)
+		return -ENODEV;
+	if (!dev->attached)
+		return -ENODEV;
+	if (dir & DIR_IN) {
+		if (test_bit(TRANS_IN_BUSY, &dev->flags))
+			return -EBUSY;
+	}
+	if (dir & DIR_OUT) {
+		if (test_bit(TRANS_OUT_BUSY, &dev->flags))
+			return -EBUSY;
+	}
+
+	return 0;
+}
 
 static int vmk80xx_ai_rinsn(struct comedi_device *cdev,
 			    struct comedi_subdevice *s,
 			    struct comedi_insn *insn, unsigned int *data)
 {
 	struct vmk80xx_usb *dev = cdev->private;
-	int chan, reg[2];
+	int chan;
+	int reg[2];
 	int n;
 
 	dbgvm("vmk80xx: %s\n", __func__);
 
-	rudimentary_check(DIR_IN);
+	n = rudimentary_check(dev, DIR_IN);
+	if (n)
+		return n;
 
 	down(&dev->limit_sem);
 	chan = CR_CHAN(insn->chanspec);
@@ -615,12 +636,16 @@
 			    struct comedi_insn *insn, unsigned int *data)
 {
 	struct vmk80xx_usb *dev = cdev->private;
-	int chan, cmd, reg;
+	int chan;
+	int cmd;
+	int reg;
 	int n;
 
 	dbgvm("vmk80xx: %s\n", __func__);
 
-	rudimentary_check(DIR_OUT);
+	n = rudimentary_check(dev, DIR_OUT);
+	if (n)
+		return n;
 
 	down(&dev->limit_sem);
 	chan = CR_CHAN(insn->chanspec);
@@ -657,12 +682,15 @@
 			    struct comedi_insn *insn, unsigned int *data)
 {
 	struct vmk80xx_usb *dev = cdev->private;
-	int chan, reg;
+	int chan;
+	int reg;
 	int n;
 
 	dbgvm("vmk80xx: %s\n", __func__);
 
-	rudimentary_check(DIR_IN);
+	n = rudimentary_check(dev, DIR_IN);
+	if (n)
+		return n;
 
 	down(&dev->limit_sem);
 	chan = CR_CHAN(insn->chanspec);
@@ -683,6 +711,50 @@
 	return n;
 }
 
+static int vmk80xx_di_bits(struct comedi_device *cdev,
+			   struct comedi_subdevice *s,
+			   struct comedi_insn *insn, unsigned int *data)
+{
+	struct vmk80xx_usb *dev = cdev->private;
+	unsigned char *rx_buf;
+	int reg;
+	int retval;
+
+	dbgvm("vmk80xx: %s\n", __func__);
+
+	retval = rudimentary_check(dev, DIR_IN);
+	if (retval)
+		return retval;
+
+	down(&dev->limit_sem);
+
+	rx_buf = dev->usb_rx_buf;
+
+	if (dev->board.model == VMK8061_MODEL) {
+		reg = VMK8061_DI_REG;
+		dev->usb_tx_buf[0] = VMK8061_CMD_RD_DI;
+	} else {
+		reg = VMK8055_DI_REG;
+	}
+
+	retval = vmk80xx_read_packet(dev);
+
+	if (!retval) {
+		if (dev->board.model == VMK8055_MODEL)
+			data[1] = (((rx_buf[reg] >> 4) & 0x03) |
+				  ((rx_buf[reg] << 2) & 0x04) |
+				  ((rx_buf[reg] >> 3) & 0x18));
+		else
+			data[1] = rx_buf[reg];
+
+		retval = 2;
+	}
+
+	up(&dev->limit_sem);
+
+	return retval;
+}
+
 static int vmk80xx_di_rinsn(struct comedi_device *cdev,
 			    struct comedi_subdevice *s,
 			    struct comedi_insn *insn, unsigned int *data)
@@ -690,12 +762,15 @@
 	struct vmk80xx_usb *dev = cdev->private;
 	int chan;
 	unsigned char *rx_buf;
-	int reg, inp;
+	int reg;
+	int inp;
 	int n;
 
 	dbgvm("vmk80xx: %s\n", __func__);
 
-	rudimentary_check(DIR_IN);
+	n = rudimentary_check(dev, DIR_IN);
+	if (n)
+		return n;
 
 	down(&dev->limit_sem);
 	chan = CR_CHAN(insn->chanspec);
@@ -705,9 +780,9 @@
 	if (dev->board.model == VMK8061_MODEL) {
 		reg = VMK8061_DI_REG;
 		dev->usb_tx_buf[0] = VMK8061_CMD_RD_DI;
-	} else
+	} else {
 		reg = VMK8055_DI_REG;
-
+	}
 	for (n = 0; n < insn->n; n++) {
 		if (vmk80xx_read_packet(dev))
 			break;
@@ -719,7 +794,7 @@
 		else
 			inp = rx_buf[reg];
 
-		data[n] = ((inp & (1 << chan)) > 0);
+		data[n] = (inp >> chan) & 1;
 	}
 
 	up(&dev->limit_sem);
@@ -731,16 +806,18 @@
 			    struct comedi_subdevice *s,
 			    struct comedi_insn *insn, unsigned int *data)
 {
-
 	struct vmk80xx_usb *dev = cdev->private;
 	int chan;
 	unsigned char *tx_buf;
-	int reg, cmd;
+	int reg;
+	int cmd;
 	int n;
 
 	dbgvm("vmk80xx: %s\n", __func__);
 
-	rudimentary_check(DIR_OUT);
+	n = rudimentary_check(dev, DIR_OUT);
+	if (n)
+		return n;
 
 	down(&dev->limit_sem);
 	chan = CR_CHAN(insn->chanspec);
@@ -755,21 +832,17 @@
 				tx_buf[reg] |= (1 << chan);
 			else
 				tx_buf[reg] ^= (1 << chan);
-
-			goto write_packet;
-		}
-
-		/* VMK8061_MODEL */
-		reg = VMK8061_DO_REG;
-		if (data[n] == 1) {
-			cmd = VMK8061_CMD_SET_DO;
-			tx_buf[reg] = 1 << chan;
-		} else {
-			cmd = VMK8061_CMD_CLR_DO;
-			tx_buf[reg] = 0xff - (1 << chan);
+		} else { /* VMK8061_MODEL */
+			reg = VMK8061_DO_REG;
+			if (data[n] == 1) {
+				cmd = VMK8061_CMD_SET_DO;
+				tx_buf[reg] = 1 << chan;
+			} else {
+				cmd = VMK8061_CMD_CLR_DO;
+				tx_buf[reg] = 0xff - (1 << chan);
+			}
 		}
 
-write_packet:
 		if (vmk80xx_write_packet(dev, cmd))
 			break;
 	}
@@ -784,18 +857,20 @@
 			    struct comedi_insn *insn, unsigned int *data)
 {
 	struct vmk80xx_usb *dev = cdev->private;
-	int chan, reg, mask;
+	int chan;
+	int reg;
 	int n;
 
 	dbgvm("vmk80xx: %s\n", __func__);
 
-	rudimentary_check(DIR_IN);
+	n = rudimentary_check(dev, DIR_IN);
+	if (n)
+		return n;
 
 	down(&dev->limit_sem);
 	chan = CR_CHAN(insn->chanspec);
 
 	reg = VMK8061_DO_REG;
-	mask = 1 << chan;
 
 	dev->usb_tx_buf[0] = VMK8061_CMD_RD_DO;
 
@@ -803,7 +878,7 @@
 		if (vmk80xx_read_packet(dev))
 			break;
 
-		data[n] = (dev->usb_rx_buf[reg] & mask) >> chan;
+		data[n] = (dev->usb_rx_buf[reg] >> chan) & 1;
 	}
 
 	up(&dev->limit_sem);
@@ -811,17 +886,87 @@
 	return n;
 }
 
+static int vmk80xx_do_bits(struct comedi_device *cdev,
+			   struct comedi_subdevice *s,
+			   struct comedi_insn *insn, unsigned int *data)
+{
+	struct vmk80xx_usb *dev = cdev->private;
+	unsigned char *rx_buf, *tx_buf;
+	int dir, reg, cmd;
+	int retval;
+
+	dbgvm("vmk80xx: %s\n", __func__);
+
+	dir = 0;
+
+	if (data[0])
+		dir |= DIR_OUT;
+
+	if (dev->board.model == VMK8061_MODEL)
+		dir |= DIR_IN;
+
+	retval = rudimentary_check(dev, dir);
+	if (retval)
+		return retval;
+
+	down(&dev->limit_sem);
+
+	rx_buf = dev->usb_rx_buf;
+	tx_buf = dev->usb_tx_buf;
+
+	if (data[0]) {
+		if (dev->board.model == VMK8055_MODEL) {
+			reg = VMK8055_DO_REG;
+			cmd = VMK8055_CMD_WRT_AD;
+		} else { /* VMK8061_MODEL */
+			reg = VMK8061_DO_REG;
+			cmd = VMK8061_CMD_DO;
+		}
+
+		tx_buf[reg] &= ~data[0];
+		tx_buf[reg] |= (data[0] & data[1]);
+
+		retval = vmk80xx_write_packet(dev, cmd);
+
+		if (retval)
+			goto out;
+	}
+
+	if (dev->board.model == VMK8061_MODEL) {
+		reg = VMK8061_DO_REG;
+		tx_buf[0] = VMK8061_CMD_RD_DO;
+
+		retval = vmk80xx_read_packet(dev);
+
+		if (!retval) {
+			data[1] = rx_buf[reg];
+			retval = 2;
+		}
+	} else {
+		data[1] = tx_buf[reg];
+		retval = 2;
+	}
+
+out:
+	up(&dev->limit_sem);
+
+	return retval;
+}
+
 static int vmk80xx_cnt_rinsn(struct comedi_device *cdev,
 			     struct comedi_subdevice *s,
 			     struct comedi_insn *insn, unsigned int *data)
 {
 	struct vmk80xx_usb *dev = cdev->private;
-	int chan, reg[2];
+	int chan;
+	int reg[2];
 	int n;
 
 	dbgvm("vmk80xx: %s\n", __func__);
 
-	rudimentary_check(DIR_IN);
+	n = rudimentary_check(dev, DIR_IN);
+	if (n)
+		return n;
 
 	down(&dev->limit_sem);
 	chan = CR_CHAN(insn->chanspec);
@@ -844,14 +989,11 @@
 		if (vmk80xx_read_packet(dev))
 			break;
 
-		if (dev->board.model == VMK8055_MODEL) {
+		if (dev->board.model == VMK8055_MODEL)
 			data[n] = dev->usb_rx_buf[reg[0]];
-			continue;
-		}
-
-		/* VMK8061_MODEL */
-		data[n] = dev->usb_rx_buf[reg[0] * (chan + 1) + 1]
-		    + 256 * dev->usb_rx_buf[reg[1] * 2 + 2];
+		else /* VMK8061_MODEL */
+			data[n] = dev->usb_rx_buf[reg[0] * (chan + 1) + 1]
+			    + 256 * dev->usb_rx_buf[reg[1] * 2 + 2];
 	}
 
 	up(&dev->limit_sem);
@@ -865,12 +1007,16 @@
 {
 	struct vmk80xx_usb *dev = cdev->private;
 	unsigned int insn_cmd;
-	int chan, cmd, reg;
+	int chan;
+	int cmd;
+	int reg;
 	int n;
 
 	dbgvm("vmk80xx: %s\n", __func__);
 
-	rudimentary_check(DIR_OUT);
+	n = rudimentary_check(dev, DIR_OUT);
+	if (n)
+		return n;
 
 	down(&dev->limit_sem);
 
@@ -890,8 +1036,9 @@
 		}
 
 		dev->usb_tx_buf[reg] = 0x00;
-	} else
+	} else {
 		cmd = VMK8061_CMD_RST_CNT;
+	}
 
 	for (n = 0; n < insn->n; n++)
 		if (vmk80xx_write_packet(dev, cmd))
@@ -907,13 +1054,17 @@
 			     struct comedi_insn *insn, unsigned int *data)
 {
 	struct vmk80xx_usb *dev = cdev->private;
-	unsigned long debtime, val;
-	int chan, cmd;
+	unsigned long debtime;
+	unsigned long val;
+	int chan;
+	int cmd;
 	int n;
 
 	dbgvm("vmk80xx: %s\n", __func__);
 
-	rudimentary_check(DIR_OUT);
+	n = rudimentary_check(dev, DIR_OUT);
+	if (n)
+		return n;
 
 	down(&dev->limit_sem);
 	chan = CR_CHAN(insn->chanspec);
@@ -957,7 +1108,9 @@
 
 	dbgvm("vmk80xx: %s\n", __func__);
 
-	rudimentary_check(DIR_IN);
+	n = rudimentary_check(dev, DIR_IN);
+	if (n)
+		return n;
 
 	down(&dev->limit_sem);
 
@@ -984,12 +1137,15 @@
 {
 	struct vmk80xx_usb *dev = cdev->private;
 	unsigned char *tx_buf;
-	int reg[2], cmd;
+	int reg[2];
+	int cmd;
 	int n;
 
 	dbgvm("vmk80xx: %s\n", __func__);
 
-	rudimentary_check(DIR_OUT);
+	n = rudimentary_check(dev, DIR_OUT);
+	if (n)
+		return n;
 
 	down(&dev->limit_sem);
 
@@ -1026,8 +1182,8 @@
 	return n;
 }
 
-static int
-vmk80xx_attach(struct comedi_device *cdev, struct comedi_devconfig *it)
+static int vmk80xx_attach(struct comedi_device *cdev,
+			  struct comedi_devconfig *it)
 {
 	int i;
 	struct vmk80xx_usb *dev;
@@ -1094,16 +1250,18 @@
 	s->type = COMEDI_SUBD_DI;
 	s->subdev_flags = SDF_READABLE | SDF_GROUND;
 	s->n_chan = dev->board.di_chans;
-	s->maxdata = (1 << dev->board.di_bits) - 1;
+	s->maxdata = 1;
 	s->insn_read = vmk80xx_di_rinsn;
+	s->insn_bits = vmk80xx_di_bits;
 
 	/* Digital output subdevice */
 	s = cdev->subdevices + VMK80XX_SUBD_DO;
 	s->type = COMEDI_SUBD_DO;
 	s->subdev_flags = SDF_WRITEABLE | SDF_GROUND;
 	s->n_chan = dev->board.do_chans;
-	s->maxdata = (1 << dev->board.do_bits) - 1;
+	s->maxdata = 1;
 	s->insn_write = vmk80xx_do_winsn;
+	s->insn_bits = vmk80xx_do_bits;
 
 	if (dev->board.model == VMK8061_MODEL) {
 		s->subdev_flags |= SDF_READABLE;
@@ -1179,8 +1337,8 @@
 	return 0;
 }
 
-static int
-vmk80xx_probe(struct usb_interface *intf, const struct usb_device_id *id)
+static int vmk80xx_probe(struct usb_interface *intf,
+			 const struct usb_device_id *id)
 {
 	int i;
 	struct vmk80xx_usb *dev;
@@ -1309,8 +1467,9 @@
 			vmk80xx_read_eeprom(dev, IC6_VERSION);
 			printk(KERN_INFO "comedi#: vmk80xx: %s\n",
 			       dev->fw.ic6_vers);
-		} else
+		} else {
 			dbgcm("comedi#: vmk80xx: no conn. to CPU\n");
+		}
 	}
 
 	if (dev->board.model == VMK8055_MODEL)
@@ -1323,6 +1482,8 @@
 
 	mutex_unlock(&glb_mutex);
 
+	comedi_usb_auto_config(dev->udev, BOARDNAME);
+
 	return 0;
 error:
 	mutex_unlock(&glb_mutex);
@@ -1339,6 +1500,8 @@
 	if (!dev)
 		return;
 
+	comedi_usb_auto_unconfig(dev->udev);
+
 	mutex_lock(&glb_mutex);
 	down(&dev->limit_sem);
 
@@ -1376,10 +1539,16 @@
 
 static int __init vmk80xx_init(void)
 {
+	int retval;
+
 	printk(KERN_INFO "vmk80xx: version 0.8.01 "
 	       "Manuel Gebele <forensixs@gmx.de>\n");
-	usb_register(&vmk80xx_driver);
-	return comedi_driver_register(&driver_vmk80xx);
+
+	retval = comedi_driver_register(&driver_vmk80xx);
+	if (retval < 0)
+		return retval;
+
+	return usb_register(&vmk80xx_driver);
 }
 
 static void __exit vmk80xx_exit(void)
diff -druN linux-2.6.39-libre/drivers/staging/comedi/Kconfig linux-3.0-rc7-libre/drivers/staging/comedi/Kconfig
--- linux-2.6.39-libre/drivers/staging/comedi/Kconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/comedi/Kconfig	2011-07-11 19:51:52.000000000 -0400
@@ -2,6 +2,7 @@
 	tristate "Data acquisition support (comedi)"
 	default N
 	depends on m
+	depends on BROKEN || FRV || M32R || MN10300 || SUPERH || TILE || X86
 	---help---
 	  Enable support a wide range of data acquisition devices
 	  for Linux.
@@ -160,6 +161,7 @@
 
 config COMEDI_PCL812
 	tristate "Advantech PCL-812/813 and ADlink ACL-8112/8113/8113/8216"
+	depends on VIRT_TO_BUS
 	default N
 	---help---
 	  Enable support for Advantech PCL-812/PG, PCL-813/B, ADLink
@@ -171,6 +173,7 @@
 
 config COMEDI_PCL816
 	tristate "Advantech PCL-814 and PCL-816 ISA card support"
+	depends on VIRT_TO_BUS
 	default N
 	---help---
 	  Enable support for Advantech PCL-814 and PCL-816 ISA cards
@@ -180,6 +183,7 @@
 
 config COMEDI_PCL818
 	tristate "Advantech PCL-718 and PCL-818 ISA card support"
+	depends on VIRT_TO_BUS
 	default N
 	---help---
 	  Enable support for Advantech PCL-818 ISA cards
@@ -269,6 +273,7 @@
 
 config COMEDI_DAS1800
 	tristate "DAS1800 and compatible ISA card support"
+	depends on VIRT_TO_BUS
 	select COMEDI_FC
 	default N
 	---help---
@@ -340,6 +345,7 @@
 config COMEDI_DT282X
 	tristate "Data Translation DT2821 series and DT-EZ ISA card support"
 	select COMEDI_FC
+	depends on VIRT_TO_BUS
 	default N
 	---help---
 	  Enable support for Data Translation DT2821 series including DT-EZ
@@ -419,6 +425,7 @@
 config COMEDI_NI_AT_A2150
 	tristate "NI AT-A2150 ISA card support"
 	depends on COMEDI_NI_COMMON
+	depends on VIRT_TO_BUS
 	default N
 	---help---
 	  Enable support for National Instruments AT-A2150 cards
@@ -536,6 +543,7 @@
 
 config COMEDI_ADDI_APCI_035
 	tristate "ADDI-DATA APCI_035 support"
+	depends on VIRT_TO_BUS
 	default N
 	---help---
 	  Enable support for ADDI-DATA APCI_035 cards
@@ -545,6 +553,7 @@
 
 config COMEDI_ADDI_APCI_1032
 	tristate "ADDI-DATA APCI_1032 support"
+	depends on VIRT_TO_BUS
 	default N
 	---help---
 	  Enable support for ADDI-DATA APCI_1032 cards
@@ -554,6 +563,7 @@
 
 config COMEDI_ADDI_APCI_1500
 	tristate "ADDI-DATA APCI_1500 support"
+	depends on VIRT_TO_BUS
 	default N
 	---help---
 	  Enable support for ADDI-DATA APCI_1500 cards
@@ -563,6 +573,7 @@
 
 config COMEDI_ADDI_APCI_1516
 	tristate "ADDI-DATA APCI_1516 support"
+	depends on VIRT_TO_BUS
 	default N
 	---help---
 	  Enable support for ADDI-DATA APCI_1516 cards
@@ -572,6 +583,7 @@
 
 config COMEDI_ADDI_APCI_1564
 	tristate "ADDI-DATA APCI_1564 support"
+	depends on VIRT_TO_BUS
 	default N
 	---help---
 	  Enable support for ADDI-DATA APCI_1564 cards
@@ -581,6 +593,7 @@
 
 config COMEDI_ADDI_APCI_16XX
 	tristate "ADDI-DATA APCI_16xx support"
+	depends on VIRT_TO_BUS
 	default N
 	---help---
 	  Enable support for ADDI-DATA APCI_16xx cards
@@ -590,6 +603,7 @@
 
 config COMEDI_ADDI_APCI_2016
 	tristate "ADDI-DATA APCI_2016 support"
+	depends on VIRT_TO_BUS
 	default N
 	---help---
 	  Enable support for ADDI-DATA APCI_2016 cards
@@ -599,6 +613,7 @@
 
 config COMEDI_ADDI_APCI_2032
 	tristate "ADDI-DATA APCI_2032 support"
+	depends on VIRT_TO_BUS
 	default N
 	---help---
 	  Enable support for ADDI-DATA APCI_2032 cards
@@ -608,6 +623,7 @@
 
 config COMEDI_ADDI_APCI_2200
 	tristate "ADDI-DATA APCI_2200 support"
+	depends on VIRT_TO_BUS
 	default N
 	---help---
 	  Enable support for ADDI-DATA APCI_2200 cards
@@ -617,6 +633,7 @@
 
 config COMEDI_ADDI_APCI_3001
 	tristate "ADDI-DATA APCI_3001 support"
+	depends on VIRT_TO_BUS
 	select COMEDI_FC
 	default N
 	---help---
@@ -627,6 +644,7 @@
 
 config COMEDI_ADDI_APCI_3120
 	tristate "ADDI-DATA APCI_3520 support"
+	depends on VIRT_TO_BUS
 	select COMEDI_FC
 	default N
 	---help---
@@ -637,6 +655,7 @@
 
 config COMEDI_ADDI_APCI_3501
 	tristate "ADDI-DATA APCI_3501 support"
+	depends on VIRT_TO_BUS
 	default N
 	---help---
 	  Enable support for ADDI-DATA APCI_3501 cards
@@ -646,6 +665,7 @@
 
 config COMEDI_ADDI_APCI_3XXX
 	tristate "ADDI-DATA APCI_3xxx support"
+	depends on VIRT_TO_BUS
 	default N
 	---help---
 	  Enable support for ADDI-DATA APCI_3xxx cards
@@ -712,6 +732,7 @@
 config COMEDI_ADL_PCI9118
 	tristate "ADLink PCI-9118DG, PCI-9118HG, PCI-9118HR support"
 	select COMEDI_FC
+	depends on VIRT_TO_BUS
 	default N
 	---help---
 	  Enable support for ADlink PCI-9118DG, PCI-9118HG, PCI-9118HR cards
@@ -1287,6 +1308,7 @@
 	depends on COMEDI_MITE
 	select COMEDI_8255
 	select COMEDI_FC
+	depends on VIRT_TO_BUS
 	default N
 	---help---
 	  Enable support for National Instruments Lab-PC and compatibles
diff -druN linux-2.6.39-libre/drivers/staging/cptm1217/clearpad_tm1217.c linux-3.0-rc7-libre/drivers/staging/cptm1217/clearpad_tm1217.c
--- linux-2.6.39-libre/drivers/staging/cptm1217/clearpad_tm1217.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/cptm1217/clearpad_tm1217.c	2011-07-11 19:51:52.000000000 -0400
@@ -462,8 +462,8 @@
 		if (input_dev == NULL) {
 			dev_err(ts->dev,
 				"cp_tm1217:Input Device Struct alloc failed\n");
-			kfree(ts);
-			return -ENOMEM;
+			retval = -ENOMEM;
+			goto fail;
 		}
 		input_info = &ts->cp_input_info[i];
 		snprintf(input_info->name, sizeof(input_info->name),
@@ -486,6 +486,7 @@
 			dev_err(ts->dev,
 				"Input dev registration failed for %s\n",
 					input_dev->name);
+			input_free_device(input_dev);
 			goto fail;
 		}
 		input_info->input = input_dev;
diff -druN linux-2.6.39-libre/drivers/staging/crystalhd/bc_dts_types.h linux-3.0-rc7-libre/drivers/staging/crystalhd/bc_dts_types.h
--- linux-2.6.39-libre/drivers/staging/crystalhd/bc_dts_types.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/crystalhd/bc_dts_types.h	2011-07-11 19:51:52.000000000 -0400
@@ -65,7 +65,6 @@
 #else
 
 /* For Kernel usage.. */
-typedef bool	bc_bool_t;
 #endif
 
 #else
diff -druN linux-2.6.39-libre/drivers/staging/crystalhd/crystalhd_misc.c linux-3.0-rc7-libre/drivers/staging/crystalhd/crystalhd_misc.c
--- linux-2.6.39-libre/drivers/staging/crystalhd/crystalhd_misc.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/crystalhd/crystalhd_misc.c	2011-07-11 19:51:52.000000000 -0400
@@ -311,7 +311,7 @@
 		rc = -EINVAL;
 		sts = BC_STS_INV_ARG;
 		BCMLOG_ERR("Invalid len:%d\n", len);
-	};
+	}
 
 	if (rc && (sts == BC_STS_SUCCESS))
 		sts = BC_STS_ERROR;
@@ -356,7 +356,7 @@
 		rc = -EINVAL;
 		sts = BC_STS_INV_ARG;
 		BCMLOG_ERR("Invalid len:%d\n", len);
-	};
+	}
 
 	if (rc && (sts == BC_STS_SUCCESS))
 		sts = BC_STS_ERROR;
diff -druN linux-2.6.39-libre/drivers/staging/cx25821/cx25821-video.c linux-3.0-rc7-libre/drivers/staging/cx25821/cx25821-video.c
--- linux-2.6.39-libre/drivers/staging/cx25821/cx25821-video.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/cx25821/cx25821-video.c	2011-07-11 19:51:52.000000000 -0400
@@ -832,6 +832,7 @@
 
        if (NULL == dev) {
 		mutex_unlock(&cx25821_devlist_mutex);
+		kfree(fh);
 		return -ENODEV;
        }
 
@@ -1573,7 +1574,7 @@
 		break;
 	default:
 		/* nothing */ ;
-	};
+	}
 
 	switch (ctl->id) {
 	case V4L2_CID_BRIGHTNESS:
diff -druN linux-2.6.39-libre/drivers/staging/easycap/easycap_main.c linux-3.0-rc7-libre/drivers/staging/easycap/easycap_main.c
--- linux-2.6.39-libre/drivers/staging/easycap/easycap_main.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/easycap/easycap_main.c	2011-07-11 19:51:52.000000000 -0400
@@ -201,9 +201,9 @@
 static int reset(struct easycap *peasycap)
 {
 	struct easycap_standard const *peasycap_standard;
-	int i, rc, input, rate;
+	int fmtidx, input, rate;
 	bool ntsc, other;
-	int fmtidx;
+	int rc;
 
 	if (!peasycap) {
 		SAY("ERROR: peasycap is NULL\n");
@@ -226,33 +226,27 @@
 	JOM(8, "peasycap->ntsc=%d\n", peasycap->ntsc);
 
 	rate = ready_saa(peasycap->pusb_device);
-	if (0 > rate) {
-		JOM(8, "not ready to capture after %i ms ...\n", PATIENCE);
-		if (peasycap->ntsc) {
-			JOM(8, "... trying PAL ...\n");  ntsc = false;
-		} else {
-			JOM(8, "... trying NTSC ...\n"); ntsc = true;
-	}
-	rc = setup_stk(peasycap->pusb_device, ntsc);
-	if (0 == rc)
-		JOM(4, "setup_stk() OK\n");
-	else {
-		SAM("ERROR: setup_stk() rc = %i\n", rc);
-		return -EFAULT;
-	}
-	rc = setup_saa(peasycap->pusb_device, ntsc);
-	if (0 == rc)
-		JOM(4, "setup_saa() OK\n");
-	else {
-		SAM("ERROR: setup_saa() rc = %i\n", rc);
-		return -EFAULT;
-	}
-	rate = ready_saa(peasycap->pusb_device);
-	if (0 > rate) {
+	if (rate < 0) {
 		JOM(8, "not ready to capture after %i ms ...\n", PATIENCE);
-		JOM(8, "... saa register 0x1F has 0x%02X\n",
+		ntsc = !peasycap->ntsc;
+		JOM(8, "... trying  %s ..\n", ntsc ? "NTSC" : "PAL");
+		rc = setup_stk(peasycap->pusb_device, ntsc);
+		if (rc) {
+			SAM("ERROR: setup_stk() rc = %i\n", rc);
+			return -EFAULT;
+		}
+		rc = setup_saa(peasycap->pusb_device, ntsc);
+		if (rc) {
+			SAM("ERROR: setup_saa() rc = %i\n", rc);
+			return -EFAULT;
+		}
+
+		rate = ready_saa(peasycap->pusb_device);
+		if (rate < 0) {
+			JOM(8, "not ready to capture after %i ms\n", PATIENCE);
+			JOM(8, "... saa register 0x1F has 0x%02X\n",
 					read_saa(peasycap->pusb_device, 0x1F));
-		ntsc = peasycap->ntsc;
+			ntsc = peasycap->ntsc;
 		} else {
 			JOM(8, "... success at second try:  %i=rate\n", rate);
 			ntsc = (0 < (rate/2)) ? true : false ;
@@ -266,22 +260,17 @@
 /*---------------------------------------------------------------------------*/
 
 	rc = setup_stk(peasycap->pusb_device, ntsc);
-	if (0 == rc)
-		JOM(4, "setup_stk() OK\n");
-	else {
+	if (rc) {
 		SAM("ERROR: setup_stk() rc = %i\n", rc);
 		return -EFAULT;
 	}
 	rc = setup_saa(peasycap->pusb_device, ntsc);
-	if (0 == rc)
-		JOM(4, "setup_saa() OK\n");
-	else {
+	if (rc) {
 		SAM("ERROR: setup_saa() rc = %i\n", rc);
 		return -EFAULT;
 	}
 
-	for (i = 0; i < 180; i++)
-		peasycap->merit[i] = 0;
+	memset(peasycap->merit, 0, sizeof(peasycap->merit));
 
 	peasycap->video_eof = 0;
 	peasycap->audio_eof = 0;
@@ -2986,26 +2975,18 @@
  *  TIMES, ONCE FOR EACH OF THE THREE INTERFACES.  BEWARE.
  */
 /*---------------------------------------------------------------------------*/
-static int easycap_usb_probe(struct usb_interface *pusb_interface,
-			    const struct usb_device_id *pusb_device_id)
+static int easycap_usb_probe(struct usb_interface *intf,
+			    const struct usb_device_id *id)
 {
-	struct usb_device *pusb_device;
-	struct usb_host_interface *pusb_host_interface;
-	struct usb_endpoint_descriptor *pepd;
-	struct usb_interface_descriptor *pusb_interface_descriptor;
+	struct usb_device *usbdev;
+	struct usb_host_interface *alt;
+	struct usb_endpoint_descriptor *ep;
+	struct usb_interface_descriptor *interface;
 	struct urb *purb;
 	struct easycap *peasycap;
 	int ndong;
 	struct data_urb *pdata_urb;
-	size_t wMaxPacketSize;
-	int ISOCwMaxPacketSize;
-	int BULKwMaxPacketSize;
-	int INTwMaxPacketSize;
-	int CTRLwMaxPacketSize;
-	u8 bEndpointAddress;
-	u8 ISOCbEndpointAddress;
-	u8 INTbEndpointAddress;
-	int isin, i, j, k, m, rc;
+	int i, j, k, m, rc;
 	u8 bInterfaceNumber;
 	u8 bInterfaceClass;
 	u8 bInterfaceSubClass;
@@ -3021,23 +3002,17 @@
 	struct inputset *inputset;
 	struct v4l2_device *pv4l2_device;
 
-/*---------------------------------------------------------------------------*/
-/*
- *  GET POINTER TO STRUCTURE usb_device
- */
-/*---------------------------------------------------------------------------*/
-	pusb_device = interface_to_usbdev(pusb_interface);
+	usbdev = interface_to_usbdev(intf);
 
-	JOT(4, "bNumConfigurations=%i\n", pusb_device->descriptor.bNumConfigurations);
 /*---------------------------------------------------------------------------*/
-	pusb_host_interface = pusb_interface->cur_altsetting;
-	if (!pusb_host_interface) {
-		SAY("ERROR: pusb_host_interface is NULL\n");
+	alt = usb_altnum_to_altsetting(intf, 0);
+	if (!alt) {
+		SAY("ERROR: usb_host_interface not found\n");
 		return -EFAULT;
 	}
-	pusb_interface_descriptor = &(pusb_host_interface->desc);
-	if (!pusb_interface_descriptor) {
-		SAY("ERROR: pusb_interface_descriptor is NULL\n");
+	interface = &alt->desc;
+	if (!interface) {
+		SAY("ERROR: intf_descriptor is NULL\n");
 		return -EFAULT;
 	}
 /*---------------------------------------------------------------------------*/
@@ -3045,16 +3020,15 @@
  *  GET PROPERTIES OF PROBED INTERFACE
  */
 /*---------------------------------------------------------------------------*/
-	bInterfaceNumber = pusb_interface_descriptor->bInterfaceNumber;
-	bInterfaceClass = pusb_interface_descriptor->bInterfaceClass;
-	bInterfaceSubClass = pusb_interface_descriptor->bInterfaceSubClass;
+	bInterfaceNumber = interface->bInterfaceNumber;
+	bInterfaceClass = interface->bInterfaceClass;
+	bInterfaceSubClass = interface->bInterfaceSubClass;
 
 	JOT(4, "intf[%i]: num_altsetting=%i\n",
-			bInterfaceNumber, pusb_interface->num_altsetting);
+			bInterfaceNumber, intf->num_altsetting);
 	JOT(4, "intf[%i]: cur_altsetting - altsetting=%li\n",
 		bInterfaceNumber,
-		(long int)(pusb_interface->cur_altsetting -
-				pusb_interface->altsetting));
+		(long int)(intf->cur_altsetting - intf->altsetting));
 	JOT(4, "intf[%i]: bInterfaceClass=0x%02X bInterfaceSubClass=0x%02X\n",
 			bInterfaceNumber, bInterfaceClass, bInterfaceSubClass);
 /*---------------------------------------------------------------------------*/
@@ -3140,8 +3114,8 @@
  *  ... AND FURTHER INITIALIZE THE STRUCTURE
 */
 /*---------------------------------------------------------------------------*/
-		peasycap->pusb_device = pusb_device;
-		peasycap->pusb_interface = pusb_interface;
+		peasycap->pusb_device = usbdev;
+		peasycap->pusb_interface = intf;
 
 		peasycap->ilk = 0;
 		peasycap->microphone = false;
@@ -3275,7 +3249,7 @@
  */
 /*---------------------------------------------------------------------------*/
 		for (ndong = 0; ndong < DONGLE_MANY; ndong++) {
-			if (pusb_device == easycapdc60_dongle[ndong].peasycap->
+			if (usbdev == easycapdc60_dongle[ndong].peasycap->
 									pusb_device) {
 				peasycap = easycapdc60_dongle[ndong].peasycap;
 				JOT(8, "intf[%i]: dongle[%i].peasycap\n",
@@ -3302,7 +3276,7 @@
 */
 /*---------------------------------------------------------------------------*/
 		if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) {
-			pv4l2_device = usb_get_intfdata(pusb_interface);
+			pv4l2_device = usb_get_intfdata(intf);
 			if (!pv4l2_device) {
 				SAY("ERROR: pv4l2_device is NULL\n");
 				return -ENODEV;
@@ -3351,220 +3325,155 @@
 /*---------------------------------------------------------------------------*/
 	isokalt = 0;
 
-	for (i = 0; i < pusb_interface->num_altsetting; i++) {
-		pusb_host_interface = &(pusb_interface->altsetting[i]);
-		if (!pusb_host_interface) {
-			SAM("ERROR: pusb_host_interface is NULL\n");
+	for (i = 0; i < intf->num_altsetting; i++) {
+		alt = usb_altnum_to_altsetting(intf, i);
+		if (!alt) {
+			SAM("ERROR: alt is NULL\n");
 			return -EFAULT;
 		}
-		pusb_interface_descriptor = &(pusb_host_interface->desc);
-		if (!pusb_interface_descriptor) {
-			SAM("ERROR: pusb_interface_descriptor is NULL\n");
+		interface = &alt->desc;
+		if (!interface) {
+			SAM("ERROR: intf_descriptor is NULL\n");
 			return -EFAULT;
 		}
 
-		JOM(4, "intf[%i]alt[%i]: desc.bDescriptorType=0x%02X\n",
-		bInterfaceNumber, i, pusb_interface_descriptor->bDescriptorType);
-		JOM(4, "intf[%i]alt[%i]: desc.bInterfaceNumber=0x%02X\n",
-		bInterfaceNumber, i, pusb_interface_descriptor->bInterfaceNumber);
-		JOM(4, "intf[%i]alt[%i]: desc.bAlternateSetting=0x%02X\n",
-		bInterfaceNumber, i, pusb_interface_descriptor->bAlternateSetting);
-		JOM(4, "intf[%i]alt[%i]: desc.bNumEndpoints=0x%02X\n",
-		bInterfaceNumber, i, pusb_interface_descriptor->bNumEndpoints);
-		JOM(4, "intf[%i]alt[%i]: desc.bInterfaceClass=0x%02X\n",
-		bInterfaceNumber, i, pusb_interface_descriptor->bInterfaceClass);
-		JOM(4, "intf[%i]alt[%i]: desc.bInterfaceSubClass=0x%02X\n",
-		bInterfaceNumber, i, pusb_interface_descriptor->bInterfaceSubClass);
-		JOM(4, "intf[%i]alt[%i]: desc.bInterfaceProtocol=0x%02X\n",
-		bInterfaceNumber, i, pusb_interface_descriptor->bInterfaceProtocol);
-		JOM(4, "intf[%i]alt[%i]: desc.iInterface=0x%02X\n",
-		bInterfaceNumber, i, pusb_interface_descriptor->iInterface);
-
-		ISOCwMaxPacketSize = -1;
-		BULKwMaxPacketSize = -1;
-		INTwMaxPacketSize = -1;
-		CTRLwMaxPacketSize = -1;
-		ISOCbEndpointAddress = 0;
-		INTbEndpointAddress = 0;
-
-		if (0 == pusb_interface_descriptor->bNumEndpoints)
+		if (0 == interface->bNumEndpoints)
 			JOM(4, "intf[%i]alt[%i] has no endpoints\n",
 						bInterfaceNumber, i);
 /*---------------------------------------------------------------------------*/
-		for (j = 0; j < pusb_interface_descriptor->bNumEndpoints; j++) {
-			pepd = &(pusb_host_interface->endpoint[j].desc);
-			if (!pepd) {
-				SAM("ERROR:  pepd is NULL.\n");
+		for (j = 0; j < interface->bNumEndpoints; j++) {
+			ep = &alt->endpoint[j].desc;
+			if (!ep) {
+				SAM("ERROR:  ep is NULL.\n");
 				SAM("...... skipping\n");
 				continue;
 			}
-			wMaxPacketSize = le16_to_cpu(pepd->wMaxPacketSize);
-			bEndpointAddress = pepd->bEndpointAddress;
 
-			JOM(4, "intf[%i]alt[%i]end[%i]: bEndpointAddress=0x%X\n",
-					bInterfaceNumber, i, j,
-					pepd->bEndpointAddress);
-			JOM(4, "intf[%i]alt[%i]end[%i]: bmAttributes=0x%X\n",
-					bInterfaceNumber, i, j,
-					pepd->bmAttributes);
-			JOM(4, "intf[%i]alt[%i]end[%i]: wMaxPacketSize=%i\n",
-					bInterfaceNumber, i, j,
-					pepd->wMaxPacketSize);
-			JOM(4, "intf[%i]alt[%i]end[%i]: bInterval=%i\n",
-					bInterfaceNumber, i, j,
-					pepd->bInterval);
-
-			if (pepd->bEndpointAddress & USB_DIR_IN) {
-				JOM(4, "intf[%i]alt[%i]end[%i] is an  IN  endpoint\n",
-							bInterfaceNumber, i, j);
-				isin = 1;
-			} else {
-				JOM(4, "intf[%i]alt[%i]end[%i] is an  OUT endpoint\n",
-							bInterfaceNumber, i, j);
-				SAM("ERROR: OUT endpoint unexpected\n");
-				SAM("...... continuing\n");
-				isin = 0;
+			if (!usb_endpoint_is_isoc_in(ep)) {
+				JOM(4, "intf[%i]alt[%i]end[%i] is a %d endpoint\n",
+						bInterfaceNumber,
+						i, j, ep->bmAttributes);
+				if (usb_endpoint_dir_out(ep)) {
+					SAM("ERROR: OUT endpoint unexpected\n");
+					SAM("...... continuing\n");
+				}
+				continue;
 			}
-			if ((pepd->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) ==
-						USB_ENDPOINT_XFER_ISOC) {
-				JOM(4, "intf[%i]alt[%i]end[%i] is an ISOC endpoint\n",
-							bInterfaceNumber, i, j);
-				if (isin) {
-					switch (bInterfaceClass) {
-					case USB_CLASS_VIDEO:
-					case USB_CLASS_VENDOR_SPEC: {
-						if (!peasycap) {
-							SAM("MISTAKE: "
-								"peasycap is NULL\n");
-							return -EFAULT;
-						}
-						if (pepd->wMaxPacketSize) {
-							if (8 > isokalt) {
-								okalt[isokalt] = i;
-								JOM(4,
-								"%i=okalt[%i]\n",
-								okalt[isokalt],
-								isokalt);
-								okepn[isokalt] =
-								pepd->
-								bEndpointAddress &
-								0x0F;
-								JOM(4,
-								"%i=okepn[%i]\n",
-								okepn[isokalt],
-								isokalt);
-								okmps[isokalt] =
-								le16_to_cpu(pepd->
-								wMaxPacketSize);
-								JOM(4,
-								"%i=okmps[%i]\n",
-								okmps[isokalt],
-								isokalt);
-								isokalt++;
-							}
-						} else {
-							if (-1 == peasycap->
-								video_altsetting_off) {
-								peasycap->
-								video_altsetting_off =
-										 i;
-								JOM(4, "%i=video_"
-								"altsetting_off "
-									"<====\n",
-								peasycap->
-								video_altsetting_off);
-							} else {
-								SAM("ERROR: peasycap"
-								"->video_altsetting_"
-								"off already set\n");
-								SAM("...... "
-								"continuing with "
-								"%i=peasycap->video_"
-								"altsetting_off\n",
-								peasycap->
-								video_altsetting_off);
-							}
-						}
-						break;
+			switch (bInterfaceClass) {
+			case USB_CLASS_VIDEO:
+			case USB_CLASS_VENDOR_SPEC: {
+				if (ep->wMaxPacketSize) {
+					if (8 > isokalt) {
+						okalt[isokalt] = i;
+						JOM(4,
+						"%i=okalt[%i]\n",
+						okalt[isokalt],
+						isokalt);
+						okepn[isokalt] =
+						ep->
+						bEndpointAddress &
+						0x0F;
+						JOM(4,
+						"%i=okepn[%i]\n",
+						okepn[isokalt],
+						isokalt);
+						okmps[isokalt] =
+						le16_to_cpu(ep->
+						wMaxPacketSize);
+						JOM(4,
+						"%i=okmps[%i]\n",
+						okmps[isokalt],
+						isokalt);
+						isokalt++;
 					}
-					case USB_CLASS_AUDIO: {
-						if (bInterfaceSubClass !=
-						    USB_SUBCLASS_AUDIOSTREAMING)
-							break;
-						if (!peasycap) {
-							SAM("MISTAKE: "
-							"peasycap is NULL\n");
-							return -EFAULT;
-						}
-						if (pepd->wMaxPacketSize) {
-							if (8 > isokalt) {
-								okalt[isokalt] = i ;
-								JOM(4,
-								"%i=okalt[%i]\n",
-								okalt[isokalt],
-								isokalt);
-								okepn[isokalt] =
-								pepd->
-								bEndpointAddress &
-								0x0F;
-								JOM(4,
-								"%i=okepn[%i]\n",
-								okepn[isokalt],
-								isokalt);
-								okmps[isokalt] =
-								le16_to_cpu(pepd->
-								wMaxPacketSize);
-								JOM(4,
-								"%i=okmps[%i]\n",
-								okmps[isokalt],
-								isokalt);
-								isokalt++;
-							}
-						} else {
-							if (-1 == peasycap->
-								audio_altsetting_off) {
-								peasycap->
-								audio_altsetting_off =
-										 i;
-								JOM(4, "%i=audio_"
-								"altsetting_off "
-								"<====\n",
-								peasycap->
-								audio_altsetting_off);
-							} else {
-								SAM("ERROR: peasycap"
-								"->audio_altsetting_"
-								"off already set\n");
-								SAM("...... "
-								"continuing with "
-								"%i=peasycap->"
-								"audio_altsetting_"
-								"off\n",
-								peasycap->
-								audio_altsetting_off);
-							}
-						}
+				} else {
+					if (-1 == peasycap->
+						video_altsetting_off) {
+						peasycap->
+						video_altsetting_off =
+								 i;
+						JOM(4, "%i=video_"
+						"altsetting_off "
+							"<====\n",
+						peasycap->
+						video_altsetting_off);
+					} else {
+						SAM("ERROR: peasycap"
+						"->video_altsetting_"
+						"off already set\n");
+						SAM("...... "
+						"continuing with "
+						"%i=peasycap->video_"
+						"altsetting_off\n",
+						peasycap->
+						video_altsetting_off);
+					}
+				}
+				break;
+			}
+			case USB_CLASS_AUDIO: {
+				if (bInterfaceSubClass !=
+				    USB_SUBCLASS_AUDIOSTREAMING)
 					break;
+				if (!peasycap) {
+					SAM("MISTAKE: "
+					"peasycap is NULL\n");
+					return -EFAULT;
+				}
+				if (ep->wMaxPacketSize) {
+					if (8 > isokalt) {
+						okalt[isokalt] = i ;
+						JOM(4,
+						"%i=okalt[%i]\n",
+						okalt[isokalt],
+						isokalt);
+						okepn[isokalt] =
+						ep->
+						bEndpointAddress &
+						0x0F;
+						JOM(4,
+						"%i=okepn[%i]\n",
+						okepn[isokalt],
+						isokalt);
+						okmps[isokalt] =
+						le16_to_cpu(ep->
+						wMaxPacketSize);
+						JOM(4,
+						"%i=okmps[%i]\n",
+						okmps[isokalt],
+						isokalt);
+						isokalt++;
 					}
-					default:
-						break;
+				} else {
+					if (-1 == peasycap->
+						audio_altsetting_off) {
+						peasycap->
+						audio_altsetting_off =
+								 i;
+						JOM(4, "%i=audio_"
+						"altsetting_off "
+						"<====\n",
+						peasycap->
+						audio_altsetting_off);
+					} else {
+						SAM("ERROR: peasycap"
+						"->audio_altsetting_"
+						"off already set\n");
+						SAM("...... "
+						"continuing with "
+						"%i=peasycap->"
+						"audio_altsetting_"
+						"off\n",
+						peasycap->
+						audio_altsetting_off);
 					}
 				}
-			} else if ((pepd->bmAttributes &
-							USB_ENDPOINT_XFERTYPE_MASK) ==
-							USB_ENDPOINT_XFER_BULK) {
-				JOM(4, "intf[%i]alt[%i]end[%i] is a  BULK endpoint\n",
-							bInterfaceNumber, i, j);
-			} else if ((pepd->bmAttributes &
-							USB_ENDPOINT_XFERTYPE_MASK) ==
-							USB_ENDPOINT_XFER_INT) {
-				JOM(4, "intf[%i]alt[%i]end[%i] is an  INT endpoint\n",
-							bInterfaceNumber, i, j);
-			} else {
-				JOM(4, "intf[%i]alt[%i]end[%i] is a  CTRL endpoint\n",
-							bInterfaceNumber, i, j);
+			break;
 			}
-			if (0 == pepd->wMaxPacketSize) {
+			default:
+				break;
+			}
+			if (0 == ep->wMaxPacketSize) {
 				JOM(4, "intf[%i]alt[%i]end[%i] "
 							"has zero packet size\n",
 							bInterfaceNumber, i, j);
@@ -3577,7 +3486,7 @@
  */
 /*---------------------------------------------------------------------------*/
 	JOM(4, "initialization begins for interface %i\n",
-		pusb_interface_descriptor->bInterfaceNumber);
+		interface->bInterfaceNumber);
 	switch (bInterfaceNumber) {
 /*---------------------------------------------------------------------------*/
 /*
@@ -3844,7 +3753,7 @@
  *  SAVE POINTER peasycap IN THIS INTERFACE.
  */
 /*--------------------------------------------------------------------------*/
-		usb_set_intfdata(pusb_interface, peasycap);
+		usb_set_intfdata(intf, peasycap);
 /*---------------------------------------------------------------------------*/
 /*
  *  IT IS ESSENTIAL TO INITIALIZE THE HARDWARE BEFORE, RATHER THAN AFTER,
@@ -3866,7 +3775,7 @@
  *  THE VIDEO DEVICE CAN BE REGISTERED NOW, AS IT IS READY.
  */
 /*--------------------------------------------------------------------------*/
-		if (0 != (v4l2_device_register(&(pusb_interface->dev),
+		if (0 != (v4l2_device_register(&(intf->dev),
 							&(peasycap->v4l2_device)))) {
 			SAM("v4l2_device_register() failed\n");
 			return -ENODEV;
@@ -3924,9 +3833,9 @@
  *  SAVE POINTER peasycap IN INTERFACE 1
  */
 /*--------------------------------------------------------------------------*/
-		usb_set_intfdata(pusb_interface, peasycap);
+		usb_set_intfdata(intf, peasycap);
 		JOM(4, "no initialization required for interface %i\n",
-					pusb_interface_descriptor->bInterfaceNumber);
+					interface->bInterfaceNumber);
 		break;
 	}
 /*--------------------------------------------------------------------------*/
@@ -4188,7 +4097,7 @@
  *  SAVE POINTER peasycap IN THIS INTERFACE.
  */
 /*---------------------------------------------------------------------------*/
-		usb_set_intfdata(pusb_interface, peasycap);
+		usb_set_intfdata(intf, peasycap);
 /*---------------------------------------------------------------------------*/
 /*
  *  THE AUDIO DEVICE CAN BE REGISTERED NOW, AS IT IS READY.
@@ -4201,28 +4110,22 @@
 		if (rc) {
 			err("easycap_alsa_probe() rc = %i\n", rc);
 			return -ENODEV;
-		} else {
-			JOM(8, "kref_get() with %i=kref.refcount.counter\n",
-					peasycap->kref.refcount.counter);
-			kref_get(&peasycap->kref);
-			peasycap->registered_audio++;
 		}
 
 #else /* CONFIG_EASYCAP_OSS */
-		rc = usb_register_dev(pusb_interface, &easyoss_class);
+		rc = usb_register_dev(intf, &easyoss_class);
 		if (rc) {
 			SAY("ERROR: usb_register_dev() failed\n");
-			usb_set_intfdata(pusb_interface, NULL);
+			usb_set_intfdata(intf, NULL);
 			return -ENODEV;
-		} else {
-			JOM(8, "kref_get() with %i=kref.refcount.counter\n",
-					peasycap->kref.refcount.counter);
-			kref_get(&peasycap->kref);
-			peasycap->registered_audio++;
 		}
-		SAM("easyoss attached to minor #%d\n", pusb_interface->minor);
+		SAM("easyoss attached to minor #%d\n", intf->minor);
 #endif /* CONFIG_EASYCAP_OSS */
 
+		JOM(8, "kref_get() with %i=kref.refcount.counter\n",
+				peasycap->kref.refcount.counter);
+		kref_get(&peasycap->kref);
+		peasycap->registered_audio++;
 		break;
 	}
 /*---------------------------------------------------------------------------*/
diff -druN linux-2.6.39-libre/drivers/staging/echo/echo.c linux-3.0-rc7-libre/drivers/staging/echo/echo.c
--- linux-2.6.39-libre/drivers/staging/echo/echo.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/echo/echo.c	2011-07-11 19:51:52.000000000 -0400
@@ -113,12 +113,10 @@
 #define DTD_HANGOVER			600	/* 600 samples, or 75ms     */
 #define DC_LOG2BETA			3	/* log2() of DC filter Beta */
 
-
 /* adapting coeffs using the traditional stochastic descent (N)LMS algorithm */
 
 #ifdef __bfin__
-static inline void lms_adapt_bg(struct oslec_state *ec, int clean,
-				    int shift)
+static inline void lms_adapt_bg(struct oslec_state *ec, int clean, int shift)
 {
 	int i, j;
 	int offset1;
@@ -189,8 +187,7 @@
 */
 
 #else
-static inline void lms_adapt_bg(struct oslec_state *ec, int clean,
-				    int shift)
+static inline void lms_adapt_bg(struct oslec_state *ec, int clean, int shift)
 {
 	int i;
 
@@ -225,7 +222,7 @@
 	if (bits == 0)
 		return -1;
 	else
-		return (int)fls((int32_t)bits)-1;
+		return (int)fls((int32_t) bits) - 1;
 }
 
 struct oslec_state *oslec_create(int len, int adaption_mode)
@@ -279,6 +276,7 @@
 	kfree(ec);
 	return NULL;
 }
+
 EXPORT_SYMBOL_GPL(oslec_create);
 
 void oslec_free(struct oslec_state *ec)
@@ -292,12 +290,14 @@
 	kfree(ec->snapshot);
 	kfree(ec);
 }
+
 EXPORT_SYMBOL_GPL(oslec_free);
 
 void oslec_adaption_mode(struct oslec_state *ec, int adaption_mode)
 {
 	ec->adaption_mode = adaption_mode;
 }
+
 EXPORT_SYMBOL_GPL(oslec_adaption_mode);
 
 void oslec_flush(struct oslec_state *ec)
@@ -324,12 +324,14 @@
 	ec->curr_pos = ec->taps - 1;
 	ec->Pstates = 0;
 }
+
 EXPORT_SYMBOL_GPL(oslec_flush);
 
 void oslec_snapshot(struct oslec_state *ec)
 {
 	memcpy(ec->snapshot, ec->fir_taps16[0], ec->taps * sizeof(int16_t));
 }
+
 EXPORT_SYMBOL_GPL(oslec_snapshot);
 
 /* Dual Path Echo Canceller */
@@ -404,11 +406,11 @@
 		/* efficient "out with the old and in with the new" algorithm so
 		   we don't have to recalculate over the whole block of
 		   samples. */
-		new = (int)tx * (int)tx;
+		new = (int)tx *(int)tx;
 		old = (int)ec->fir_state.history[ec->fir_state.curr_pos] *
 		    (int)ec->fir_state.history[ec->fir_state.curr_pos];
 		ec->Pstates +=
-		    ((new - old) + (1 << (ec->log2taps-1))) >> ec->log2taps;
+		    ((new - old) + (1 << (ec->log2taps - 1))) >> ec->log2taps;
 		if (ec->Pstates < 0)
 			ec->Pstates = 0;
 	}
@@ -466,7 +468,7 @@
 
 		   factor      = (2^30) * (2^-2) * clean_bg_rx/P
 
-						(30 - 2 - log2(P))
+		   (30 - 2 - log2(P))
 		   factor      = clean_bg_rx 2                     ----- (3)
 
 		   To avoid a divide we approximate log2(P) as top_bit(P),
@@ -514,7 +516,7 @@
 			 */
 			ec->adapt = 1;
 			memcpy(ec->fir_taps16[0], ec->fir_taps16[1],
-				ec->taps * sizeof(int16_t));
+			       ec->taps * sizeof(int16_t));
 		} else
 			ec->cond_met++;
 	} else
@@ -601,6 +603,7 @@
 
 	return (int16_t) ec->clean_nlp << 1;
 }
+
 EXPORT_SYMBOL_GPL(oslec_update);
 
 /* This function is separated from the echo canceller is it is usually called
@@ -625,7 +628,7 @@
    giving very clean DC removal.
 */
 
-int16_t oslec_hpf_tx(struct oslec_state *ec, int16_t tx)
+int16_t oslec_hpf_tx(struct oslec_state * ec, int16_t tx)
 {
 	int tmp, tmp1;
 
@@ -654,6 +657,7 @@
 
 	return tx;
 }
+
 EXPORT_SYMBOL_GPL(oslec_hpf_tx);
 
 MODULE_LICENSE("GPL");
diff -druN linux-2.6.39-libre/drivers/staging/ft1000/ft1000-pcmcia/ft1000_cs.c linux-3.0-rc7-libre/drivers/staging/ft1000/ft1000-pcmcia/ft1000_cs.c
--- linux-2.6.39-libre/drivers/staging/ft1000/ft1000-pcmcia/ft1000_cs.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/ft1000/ft1000-pcmcia/ft1000_cs.c	2011-07-11 19:51:52.000000000 -0400
@@ -284,7 +284,7 @@
 
 /*====================================================================*/
 
-static struct pcmcia_device_id ft1000_ids[] = {
+static const struct pcmcia_device_id ft1000_ids[] = {
 	PCMCIA_DEVICE_MANF_CARD(0x02cc, 0x0100),
 	PCMCIA_DEVICE_MANF_CARD(0x02cc, 0x1000),
 	PCMCIA_DEVICE_MANF_CARD(0x02cc, 0x1300),
diff -druN linux-2.6.39-libre/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c linux-3.0-rc7-libre/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c
--- linux-2.6.39-libre/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c	2011-07-11 19:51:52.000000000 -0400
@@ -6,8 +6,6 @@
 //
 // $Id:
 //====================================================
-// 20090926; aelias; removed compiler warnings & errors; ubuntu 9.04; 2.6.28-15-generic
-
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
@@ -38,8 +36,6 @@
 static struct net_device_stats *ft1000_netdev_stats(struct net_device *dev);
 static int ft1000_chkcard (struct ft1000_device *dev);
 
-//Jim
-
 static u8 tempbuffer[1600];
 
 #define MAX_RCV_LOOP   100
@@ -492,8 +488,6 @@
 	commandbuf = (unsigned char *)kmalloc(size + 2, GFP_KERNEL);
 	memcpy((void *)commandbuf + 2, (void *)ptempbuffer, size);
 
-	//DEBUG("card_send_command: Command Send\n");
-
 	ft1000_read_register(ft1000dev, &temp, FT1000_REG_DOORBELL);
 
 	if (temp & 0x0100)
@@ -506,16 +500,14 @@
 	if (size % 4)
 		size += 4 - (size % 4);
 
-	//DEBUG("card_send_command: write dpram ... size=%d\n", size);
 	ft1000_write_dpram32(ft1000dev, 0, commandbuf, size);
 	msleep(1);
-	//DEBUG("card_send_command: write into doorbell ...\n");
 	ft1000_write_register(ft1000dev, FT1000_DB_DPRAM_TX,
 			      FT1000_REG_DOORBELL);
 	msleep(1);
 
 	ft1000_read_register(ft1000dev, &temp, FT1000_REG_DOORBELL);
-	//DEBUG("card_send_command: read doorbell ...temp=%x\n", temp);
+
 	if ((temp & 0x0100) == 0) {
 		//DEBUG("card_send_command: Message sent\n");
 	}
@@ -601,8 +593,6 @@
 
 	DEBUG("ft1000_hw:ft1000_reset_asic called\n");
 
-	info->ASICResetNum++;
-
 	/* Let's use the register provided by the Magnemite ASIC to reset the
 	 * ASIC and DSP.
 	 */
@@ -660,8 +650,6 @@
 	DEBUG("ft1000_hw:ft1000_reset_card: reset asic\n");
 	ft1000_reset_asic(dev);
 
-	info->DSPResetNum++;
-
 	DEBUG("ft1000_hw:ft1000_reset_card: call dsp_reload\n");
 	dsp_reload(ft1000dev);
 
@@ -683,8 +671,6 @@
 	return TRUE;
 }
 
-
-//mbelian
 #ifdef HAVE_NET_DEVICE_OPS
 static const struct net_device_ops ftnet_ops =
 {
@@ -758,14 +744,11 @@
 	spin_lock_init(&pInfo->dpram_lock);
 	pInfo->pFt1000Dev = ft1000dev;
 	pInfo->DrvErrNum = 0;
-	pInfo->ASICResetNum = 0;
 	pInfo->registered = 1;
 	pInfo->ft1000_reset = ft1000_reset;
 	pInfo->mediastate = 0;
 	pInfo->fifo_cnt = 0;
 	pInfo->DeviceCreated = FALSE;
-	pInfo->CurrentInterruptEnableMask = ISR_DEFAULT_MASK;
-	pInfo->InterruptsEnabled = FALSE;
 	pInfo->CardReady = 0;
 	pInfo->DSP_TIME[0] = 0;
 	pInfo->DSP_TIME[1] = 0;
@@ -904,14 +887,10 @@
 
 	struct ft1000_device *ft1000dev = urb->context;
 
-    //DEBUG("ft1000_usb_transmit_complete entered\n");
-
 	if (urb->status)
 		pr_err("%s: TX status %d\n", ft1000dev->net->name, urb->status);
 
 	netif_wake_queue(ft1000dev->net);
-
-    //DEBUG("Return from ft1000_usb_transmit_complete\n");
 }
 
 //---------------------------------------------------------------------------
@@ -943,8 +922,6 @@
 		return -ENODEV;
 	}
 
-	//DEBUG("ft1000_copy_down_pkt() entered, len = %d\n", len);
-
 	count = sizeof(struct pseudo_hdr) + len;
 	if (count > MAX_BUF_SIZE) {
 		DEBUG("Error:ft1000_copy_down_pkt:Message Size Overflow!\n");
@@ -973,8 +950,6 @@
 
 	netif_stop_queue(netdev);
 
-	//DEBUG ("ft1000_copy_down_pkt: count = %d\n", count);
-
 	usb_fill_bulk_urb(pFt1000Dev->tx_urb,
 			  pFt1000Dev->dev,
 			  usb_sndbulkpipe(pFt1000Dev->dev,
@@ -983,11 +958,6 @@
 			  ft1000_usb_transmit_complete, (void *)pFt1000Dev);
 
 	t = (u8 *) pFt1000Dev->tx_urb->transfer_buffer;
-	//DEBUG("transfer_length=%d\n", pFt1000Dev->tx_urb->transfer_buffer_length);
-	/*for (i=0; i<count; i++ )
-	   {
-	   DEBUG("%x    ", *t++ );
-	   } */
 
 	ret = usb_submit_urb(pFt1000Dev->tx_urb, GFP_ATOMIC);
 
@@ -999,8 +969,6 @@
 		pInfo->stats.tx_bytes += (len + 14);
 	}
 
-	//DEBUG("ft1000_copy_down_pkt() exit\n");
-
 	return 0;
 }
 
@@ -1026,8 +994,6 @@
 	u8 *pdata;
 	int maxlen, pipe;
 
-	//DEBUG(" ft1000_start_xmit() entered\n");
-
 	if (skb == NULL) {
 		DEBUG("ft1000_hw: ft1000_start_xmit:skb == NULL!!!\n");
 		return NETDEV_TX_OK;
@@ -1037,17 +1003,12 @@
 		DEBUG("network driver is closed, return\n");
 		goto err;
 	}
-	//DEBUG("ft1000_start_xmit 1:length of packet = %d\n", skb->len);
+
 	pipe =
 	    usb_sndbulkpipe(pFt1000Dev->dev, pFt1000Dev->bulk_out_endpointAddr);
 	maxlen = usb_maxpacket(pFt1000Dev->dev, pipe, usb_pipeout(pipe));
-	//DEBUG("ft1000_start_xmit 2: pipe=%d dev->maxpacket  = %d\n", pipe, maxlen);
 
 	pdata = (u8 *) skb->data;
-	/*for (i=0; i<skb->len; i++)
-	   DEBUG("skb->data[%d]=%x    ", i, *(skb->data+i));
-
-	   DEBUG("\n"); */
 
 	if (pInfo->mediastate == 0) {
 		/* Drop packet is mediastate is down */
@@ -1060,13 +1021,12 @@
 		DEBUG("ft1000_hw:ft1000_start_xmit:invalid ethernet length\n");
 		goto err;
 	}
-//mbelian
+
 	ft1000_copy_down_pkt(dev, (pdata + ENET_HEADER_SIZE - 2),
 			     skb->len - ENET_HEADER_SIZE + 2);
 
 err:
 	dev_kfree_skb(skb);
-	//DEBUG(" ft1000_start_xmit() exit\n");
 
 	return NETDEV_TX_OK;
 }
@@ -1093,24 +1053,20 @@
 
 	u16 tempword;
 	u16 len;
-	u16 lena;		//mbelian
+	u16 lena;
 	struct sk_buff *skb;
 	u16 i;
 	u8 *pbuffer = NULL;
 	u8 *ptemp = NULL;
 	u16 *chksum;
 
-	//DEBUG("ft1000_copy_up_pkt entered\n");
-
 	if (ft1000dev->status & FT1000_STATUS_CLOSING) {
 		DEBUG("network driver is closed, return\n");
 		return STATUS_SUCCESS;
 	}
 	// Read length
 	len = urb->transfer_buffer_length;
-	lena = urb->actual_length;	//mbelian
-	//DEBUG("ft1000_copy_up_pkt: transfer_buffer_length=%d, actual_buffer_len=%d\n",
-	//       urb->transfer_buffer_length, urb->actual_length);
+	lena = urb->actual_length;
 
 	chksum = (u16 *) ft1000dev->rx_buf;
 
@@ -1124,8 +1080,6 @@
 		return STATUS_FAILURE;
 	}
 
-	//DEBUG("ft1000_copy_up_pkt: checksum is correct %x\n", *chksum);
-
 	skb = dev_alloc_skb(len + 12 + 2);
 
 	if (skb == NULL) {
@@ -1157,12 +1111,6 @@
 	memcpy(pbuffer, ft1000dev->rx_buf + sizeof(struct pseudo_hdr),
 	       len - sizeof(struct pseudo_hdr));
 
-	//DEBUG("ft1000_copy_up_pkt: Data passed to Protocol layer\n");
-	/*for (i=0; i<len+12; i++)
-	   {
-	   DEBUG("ft1000_copy_up_pkt: Protocol Data: 0x%x\n ", *ptemp++);
-	   } */
-
 	skb->dev = net;
 
 	skb->protocol = eth_type_trans(skb, net);
@@ -1171,10 +1119,10 @@
 
 	info->stats.rx_packets++;
 	/* Add on 12 bytes for MAC address which was removed */
-	info->stats.rx_bytes += (lena + 12);	//mbelian
+	info->stats.rx_bytes += (lena + 12);
 
 	ft1000_submit_rx_urb(info);
-	//DEBUG("ft1000_copy_up_pkt exited\n");
+
 	return SUCCESS;
 }
 
@@ -1197,10 +1145,8 @@
 	int result;
 	struct ft1000_device *pFt1000Dev = info->pFt1000Dev;
 
-	//DEBUG ("ft1000_submit_rx_urb entered: sizeof rx_urb is %d\n", sizeof(*pFt1000Dev->rx_urb));
 	if (pFt1000Dev->status & FT1000_STATUS_CLOSING) {
 		DEBUG("network driver is closed, return\n");
-		//usb_kill_urb(pFt1000Dev->rx_urb); //mbelian
 		return -ENODEV;
 	}
 
@@ -1218,7 +1164,6 @@
 		       result);
 		return result;
 	}
-	//DEBUG("ft1000_submit_rx_urb exit: result=%d\n", result);
 
 	return 0;
 }
@@ -1241,23 +1186,22 @@
 static int ft1000_open(struct net_device *dev)
 {
 	struct ft1000_info *pInfo = netdev_priv(dev);
-	struct timeval tv;	//mbelian
+	struct timeval tv;
 	int ret;
 
 	DEBUG("ft1000_open is called for card %d\n", pInfo->CardNumber);
-	//DEBUG("ft1000_open: dev->addr=%x, dev->addr_len=%d\n", dev->addr, dev->addr_len);
 
-	pInfo->stats.rx_bytes = 0;	//mbelian
-	pInfo->stats.tx_bytes = 0;	//mbelian
-	pInfo->stats.rx_packets = 0;	//mbelian
-	pInfo->stats.tx_packets = 0;	//mbelian
+	pInfo->stats.rx_bytes = 0;
+	pInfo->stats.tx_bytes = 0;
+	pInfo->stats.rx_packets = 0;
+	pInfo->stats.tx_packets = 0;
 	do_gettimeofday(&tv);
 	pInfo->ConTm = tv.tv_sec;
-	pInfo->ProgConStat = 0;	//mbelian
+	pInfo->ProgConStat = 0;
 
 	netif_start_queue(dev);
 
-	netif_carrier_on(dev);	//mbelian
+	netif_carrier_on(dev);
 
 	ret = ft1000_submit_rx_urb(pInfo);
 
@@ -1283,19 +1227,14 @@
 	struct ft1000_info *pInfo = netdev_priv(net);
 	struct ft1000_device *ft1000dev = pInfo->pFt1000Dev;
 
-	//DEBUG ("ft1000_close: netdev->refcnt=%d\n", net->refcnt);
-
 	ft1000dev->status |= FT1000_STATUS_CLOSING;
 
-	//DEBUG("ft1000_close: calling usb_kill_urb \n");
-
 	DEBUG("ft1000_close: pInfo=%p, ft1000dev=%p\n", pInfo, ft1000dev);
-	netif_carrier_off(net);	//mbelian
+	netif_carrier_off(net);
 	netif_stop_queue(net);
-	//DEBUG("ft1000_close: netif_stop_queue called\n");
 	ft1000dev->status &= ~FT1000_STATUS_CLOSING;
 
-	pInfo->ProgConStat = 0xff;	//mbelian
+	pInfo->ProgConStat = 0xff;
 
 	return 0;
 }
@@ -1304,15 +1243,10 @@
 {
 	struct ft1000_info *info = netdev_priv(dev);
 
-	return &(info->stats); //mbelian
+	return &(info->stats);
 }
 
 
-/*********************************************************************************
-Jim
-*/
-
-
 //---------------------------------------------------------------------------
 //
 // Function:   ft1000_chkcard
@@ -1340,7 +1274,6 @@
 	 * set to zero.
 	 */
 	status = ft1000_read_register(dev, &tempword, FT1000_REG_SUP_IMASK);
-	//DEBUG("ft1000_hw:ft1000_chkcard: read FT1000_REG_SUP_IMASK = %x\n", tempword);
 	if (tempword == 0) {
 		DEBUG
 		    ("ft1000_hw:ft1000_chkcard: IMASK = 0 Card not detected\n");
@@ -1350,9 +1283,8 @@
 	 * if the device is not present.
 	 */
 	status = ft1000_read_register(dev, &tempword, FT1000_REG_ASIC_ID);
-	//DEBUG("ft1000_hw:ft1000_chkcard: read FT1000_REG_ASIC_ID = %x\n", tempword);
 	if (tempword != 0x1b01) {
-		dev->status |= FT1000_STATUS_CLOSING;	//mbelian
+		dev->status |= FT1000_STATUS_CLOSING;
 		DEBUG
 		    ("ft1000_hw:ft1000_chkcard: Version = 0xffff Card not detected\n");
 		return FALSE;
@@ -1395,7 +1327,6 @@
 				      FT1000_REG_DPRAM_ADDR);
 		ret =
 		    ft1000_read_register(dev, pbuffer, FT1000_REG_MAG_DPDATAH);
-		//DEBUG("ft1000_hw:received data = 0x%x\n", *pbuffer);
 		pbuffer++;
 		ft1000_write_register(dev, FT1000_DPRAM_MAG_RX_BASE + 1,
 				      FT1000_REG_DPRAM_ADDR);
@@ -1412,11 +1343,11 @@
 		/* copy odd aligned word */
 		ret =
 		    ft1000_read_register(dev, pbuffer, FT1000_REG_MAG_DPDATAL);
-		//DEBUG("ft1000_hw:received data = 0x%x\n", *pbuffer);
+
 		pbuffer++;
 		ret =
 		    ft1000_read_register(dev, pbuffer, FT1000_REG_MAG_DPDATAH);
-		//DEBUG("ft1000_hw:received data = 0x%x\n", *pbuffer);
+
 		pbuffer++;
 		if (size & 0x0001) {
 			/* copy odd byte from fifo */
@@ -1495,10 +1426,8 @@
 			ppseudo_hdr->portsrc = 0;
 			/* Calculate new checksum */
 			ppseudo_hdr->checksum = *pmsg++;
-			//DEBUG("checksum = 0x%x\n", ppseudo_hdr->checksum);
 			for (i = 1; i < 7; i++) {
 				ppseudo_hdr->checksum ^= *pmsg++;
-				//DEBUG("checksum = 0x%x\n", ppseudo_hdr->checksum);
 			}
 
 			TempShortBuf[0] = 0;
@@ -1582,21 +1511,16 @@
 					DEBUG("Media is up\n");
 					if (info->mediastate == 0) {
 						if (info->NetDevRegDone) {
-							//netif_carrier_on(dev->net);//mbelian
 							netif_wake_queue(dev->
 									 net);
 						}
 						info->mediastate = 1;
-						/*do_gettimeofday(&tv);
-						   info->ConTm = tv.tv_sec; *///mbelian
 					}
 				} else {
 					DEBUG("Media is down\n");
 					if (info->mediastate == 1) {
 						info->mediastate = 0;
 						if (info->NetDevRegDone) {
-							//netif_carrier_off(dev->net); mbelian
-							//netif_stop_queue(dev->net);
 						}
 						info->ConTm = 0;
 					}
@@ -1605,10 +1529,6 @@
 				DEBUG("Media is down\n");
 				if (info->mediastate == 1) {
 					info->mediastate = 0;
-					if (info->NetDevRegDone) {
-						//netif_carrier_off(dev->net); //mbelian
-						//netif_stop_queue(dev->net);
-					}
 					info->ConTm = 0;
 				}
 			}
@@ -1860,31 +1780,26 @@
 	struct pseudo_hdr *ppseudo_hdr;
     unsigned long flags;
 
-    //DEBUG("Enter ft1000_poll...\n");
     if (ft1000_chkcard(dev) == FALSE) {
         DEBUG("ft1000_poll::ft1000_chkcard: failed\n");
         return STATUS_FAILURE;
     }
 
     status = ft1000_read_register (dev, &tempword, FT1000_REG_DOORBELL);
-   // DEBUG("ft1000_poll: read FT1000_REG_DOORBELL message 0x%x\n", tempword);
 
     if ( !status )
     {
 
         if (tempword & FT1000_DB_DPRAM_RX) {
-            //DEBUG("ft1000_poll: FT1000_REG_DOORBELL message type:  FT1000_DB_DPRAM_RX\n");
 
             status = ft1000_read_dpram16(dev, 0x200, (u8 *)&data, 0);
-            //DEBUG("ft1000_poll:FT1000_DB_DPRAM_RX:ft1000_read_dpram16:size = 0x%x\n", data);
-            size = ntohs(data) + 16 + 2; //wai
+            size = ntohs(data) + 16 + 2;
             if (size % 4) {
                 modulo = 4 - (size % 4);
                 size = size + modulo;
             }
             status = ft1000_read_dpram16(dev, 0x201, (u8 *)&portid, 1);
             portid &= 0xff;
-            //DEBUG("ft1000_poll: FT1000_REG_DOORBELL message type: FT1000_DB_DPRAM_RX : portid 0x%x\n", portid);
 
             if (size < MAX_CMD_SQSIZE) {
                 switch (portid)
@@ -1899,13 +1814,11 @@
                     case DSPBCMSGID:
                         // This is a dsp broadcast message
                         // Check which application has registered for dsp broadcast messages
-                        //DEBUG("ft1000_poll: FT1000_REG_DOORBELL message type: FT1000_DB_DPRAM_RX : portid DSPBCMSGID\n");
 
     	    	        for (i=0; i<MAX_NUM_APP; i++) {
         	           if ( (info->app_info[i].DspBCMsgFlag) && (info->app_info[i].fileobject) &&
                                          (info->app_info[i].NumOfMsg < MAX_MSG_LIMIT)  )
 			   {
-			       //DEBUG("Dsp broadcast message detected for app id %d\n", i);
 			       nxtph = FT1000_DPRAM_RX_BASE + 2;
 			       pdpram_blk = ft1000_get_buffer (&freercvpool);
 			       if (pdpram_blk != NULL) {
@@ -1929,15 +1842,13 @@
                                else {
                                    DEBUG("Out of memory in free receive command pool\n");
                                    info->app_info[i].nRxMsgMiss++;
-                               }//endof if (pdpram_blk != NULL)
-                           }//endof if
-    		           //else
-    		           //    DEBUG("app_info mismatch\n");
-	                }// endof for
+                               }
+                           }
+	                }
                         break;
                     default:
                         pdpram_blk = ft1000_get_buffer (&freercvpool);
-                        //DEBUG("Memory allocated = 0x%8x\n", (u32)pdpram_blk);
+
                         if (pdpram_blk != NULL) {
                            if ( ft1000_receive_cmd(dev, pdpram_blk->pbuffer, MAX_CMD_SQSIZE, &nxtph) ) {
 				ppseudo_hdr = (struct pseudo_hdr *)pdpram_blk->pbuffer;
@@ -1961,11 +1872,8 @@
                                    else {
                                        info->app_info[i].nRxMsg++;
                                        // Put message into the appropriate application block
-                                       //pxu spin_lock_irqsave(&free_buff_lock, flags);
                                        list_add_tail(&pdpram_blk->list, &info->app_info[i].app_sqlist);
             			       info->app_info[i].NumOfMsg++;
-                                       //pxu spin_unlock_irqrestore(&free_buff_lock, flags);
-                                       //pxu wake_up_interruptible(&info->app_info[i].wait_dpram_msg);
                                    }
                                }
                            }
@@ -1978,15 +1886,14 @@
                             DEBUG("Out of memory in free receive command pool\n");
                         }
                         break;
-                } //end of switch
-            } //endof if (size < MAX_CMD_SQSIZE)
+                }
+            }
             else {
                 DEBUG("FT1000:dpc:Invalid total length for SlowQ = %d\n", size);
             }
             status = ft1000_write_register (dev, FT1000_DB_DPRAM_RX, FT1000_REG_DOORBELL);
         }
         else if (tempword & FT1000_DSP_ASIC_RESET) {
-            //DEBUG("ft1000_poll: FT1000_REG_DOORBELL message type:  FT1000_DSP_ASIC_RESET\n");
 
             // Let's reset the ASIC from the Host side as well
             status = ft1000_write_register (dev, ASIC_RESET_BIT, FT1000_REG_RESET);
@@ -2025,10 +1932,8 @@
         }
         else if (tempword & FT1000_DB_COND_RESET) {
             DEBUG("ft1000_poll: FT1000_REG_DOORBELL message type:  FT1000_DB_COND_RESET\n");
-//By Jim
-// Reset ASIC and DSP
-//MAG
-            if (info->fAppMsgPend == 0) {
+
+	    if (info->fAppMsgPend == 0) {
                // Reset ASIC and DSP
 
                 status    = ft1000_read_dpram16(dev, FT1000_MAG_DSP_TIMER0, (u8 *)&(info->DSP_TIME[0]), FT1000_MAG_DSP_TIMER0_INDX);
@@ -2048,11 +1953,8 @@
             ft1000_write_register(dev, FT1000_DB_COND_RESET, FT1000_REG_DOORBELL);
         }
 
-    }//endof if ( !status )
+    }
 
-    //DEBUG("return from ft1000_poll.\n");
     return STATUS_SUCCESS;
 
 }
-
-/*end of Jim*/
diff -druN linux-2.6.39-libre/drivers/staging/ft1000/ft1000-usb/ft1000_usb.h linux-3.0-rc7-libre/drivers/staging/ft1000/ft1000-usb/ft1000_usb.h
--- linux-2.6.39-libre/drivers/staging/ft1000/ft1000-usb/ft1000_usb.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/ft1000/ft1000-usb/ft1000_usb.h	2011-07-11 19:51:52.000000000 -0400
@@ -494,21 +494,9 @@
     bool fProvComplete;
     bool fCondResetPend;
     bool fAppMsgPend;
-    char *pfwimg;
-    int fwimgsz;
     u16 DrvErrNum;
-    u8  *pTestImage;
     u16 AsicID;
-    unsigned long TestImageIndx;
-    unsigned long TestImageSz;
-    u8  TestImageEnable;
-    u8  TestImageReady;
-    int ASICResetNum;
     int DspAsicReset;
-    int PktIntfErr;
-    int DSPResetNum;
-    int NumIOCTLBufs;
-    int IOCTLBufLvl;
     int DeviceCreated;
     int CardReady;
     int NetDevRegDone;
@@ -517,13 +505,9 @@
     struct ft1000_debug_dirs nodes;
     int registered;
     int mediastate;
-    int dhcpflg;
-    u16 packetseqnum;
     u8 squeseqnum;                 // sequence number on slow queue
     spinlock_t dpram_lock;
     spinlock_t fifo_lock;
-    u16 CurrentInterruptEnableMask;
-    int InterruptsEnabled;
     u16 fifo_cnt;
     u8 DspVer[DSPVERSZ];        // DSP version number
     u8 HwSerNum[HWSERNUMSZ];    // Hardware Serial Number
@@ -534,7 +518,6 @@
     u8 RfCalVer[CALVERSZ];
     u8 RfCalDate[CALDATESZ];
     u16 DSP_TIME[4];
-    u16 ProgSnr;
     u16 LedStat;	//mbelian
     u16 ConStat;	//mbelian
     u16 ProgConStat;
@@ -586,8 +569,6 @@
 struct dpram_blk *ft1000_get_buffer(struct list_head *bufflist);
 void ft1000_free_buffer(struct dpram_blk *pdpram_blk, struct list_head *plist);
 
-char *getfw (char *fn, size_t *pimgsz);
-
 int dsp_reload(struct ft1000_device *ft1000dev);
 int init_ft1000_netdev(struct ft1000_device *ft1000dev);
 struct usb_interface;
diff -druN linux-2.6.39-libre/drivers/staging/generic_serial/rio/rioinit.c linux-3.0-rc7-libre/drivers/staging/generic_serial/rio/rioinit.c
--- linux-2.6.39-libre/drivers/staging/generic_serial/rio/rioinit.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/generic_serial/rio/rioinit.c	2011-07-11 19:51:52.000000000 -0400
@@ -381,7 +381,7 @@
 {
     strlcpy(stVersion.version, "RIO driver for linux V1.0",
 	    sizeof(stVersion.version));
-    strlcpy(stVersion.buildDate, __DATE__,
+    strlcpy(stVersion.buildDate, "Aug 15 2010",
 	    sizeof(stVersion.buildDate));
 
     return &stVersion;
diff -druN linux-2.6.39-libre/drivers/staging/gma500/Makefile linux-3.0-rc7-libre/drivers/staging/gma500/Makefile
--- linux-2.6.39-libre/drivers/staging/gma500/Makefile	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/gma500/Makefile	2011-07-11 19:51:52.000000000 -0400
@@ -5,6 +5,7 @@
 
 psb_gfx-y += psb_bl.o \
 	  psb_drv.o \
+	  psb_gem.o \
 	  psb_fb.o \
 	  psb_2d.o \
 	  psb_gtt.o \
@@ -15,17 +16,11 @@
 	  psb_intel_lvds.o \
 	  psb_intel_modes.o \
 	  psb_intel_sdvo.o \
-	  psb_reset.o \
-	  psb_sgx.o \
-	  psb_pvr_glue.o \
-	  psb_buffer.o \
-	  psb_fence.o \
+	  psb_lid.o \
 	  psb_mmu.o \
-	  psb_ttm_glue.o \
-	  psb_ttm_fence.o \
-	  psb_ttm_fence_user.o \
-	  psb_ttm_placement_user.o \
 	  psb_powermgmt.o \
-	  psb_irq.o
+	  psb_irq.o \
+	  mrst_crtc.o \
+	  mrst_lvds.o
 
 obj-$(CONFIG_DRM_PSB) += psb_gfx.o
diff -druN linux-2.6.39-libre/drivers/staging/gma500/mrst_crtc.c linux-3.0-rc7-libre/drivers/staging/gma500/mrst_crtc.c
--- linux-2.6.39-libre/drivers/staging/gma500/mrst_crtc.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/staging/gma500/mrst_crtc.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,619 @@
+/*
+ * Copyright © 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.
+ */
+
+#include <linux/i2c.h>
+#include <linux/pm_runtime.h>
+
+#include <drm/drmP.h>
+#include "psb_fb.h"
+#include "psb_drv.h"
+#include "psb_intel_drv.h"
+#include "psb_intel_reg.h"
+#include "psb_intel_display.h"
+#include "psb_powermgmt.h"
+
+struct psb_intel_range_t {
+	int min, max;
+};
+
+struct mrst_limit_t {
+	struct psb_intel_range_t dot, m, p1;
+};
+
+struct mrst_clock_t {
+	/* derived values */
+	int dot;
+	int m;
+	int p1;
+};
+
+#define MRST_LIMIT_LVDS_100L	    0
+#define MRST_LIMIT_LVDS_83	    1
+#define MRST_LIMIT_LVDS_100	    2
+
+#define MRST_DOT_MIN		  19750
+#define MRST_DOT_MAX		  120000
+#define MRST_M_MIN_100L		    20
+#define MRST_M_MIN_100		    10
+#define MRST_M_MIN_83		    12
+#define MRST_M_MAX_100L		    34
+#define MRST_M_MAX_100		    17
+#define MRST_M_MAX_83		    20
+#define MRST_P1_MIN		    2
+#define MRST_P1_MAX_0		    7
+#define MRST_P1_MAX_1		    8
+
+static const struct mrst_limit_t mrst_limits[] = {
+	{			/* MRST_LIMIT_LVDS_100L */
+	 .dot = {.min = MRST_DOT_MIN, .max = MRST_DOT_MAX},
+	 .m = {.min = MRST_M_MIN_100L, .max = MRST_M_MAX_100L},
+	 .p1 = {.min = MRST_P1_MIN, .max = MRST_P1_MAX_1},
+	 },
+	{			/* MRST_LIMIT_LVDS_83L */
+	 .dot = {.min = MRST_DOT_MIN, .max = MRST_DOT_MAX},
+	 .m = {.min = MRST_M_MIN_83, .max = MRST_M_MAX_83},
+	 .p1 = {.min = MRST_P1_MIN, .max = MRST_P1_MAX_0},
+	 },
+	{			/* MRST_LIMIT_LVDS_100 */
+	 .dot = {.min = MRST_DOT_MIN, .max = MRST_DOT_MAX},
+	 .m = {.min = MRST_M_MIN_100, .max = MRST_M_MAX_100},
+	 .p1 = {.min = MRST_P1_MIN, .max = MRST_P1_MAX_1},
+	 },
+};
+
+#define MRST_M_MIN	    10
+static const u32 mrst_m_converts[] = {
+	0x2B, 0x15, 0x2A, 0x35, 0x1A, 0x0D, 0x26, 0x33, 0x19, 0x2C,
+	0x36, 0x3B, 0x1D, 0x2E, 0x37, 0x1B, 0x2D, 0x16, 0x0B, 0x25,
+	0x12, 0x09, 0x24, 0x32, 0x39, 0x1c,
+};
+
+static const struct mrst_limit_t *mrst_limit(struct drm_crtc *crtc)
+{
+	const struct mrst_limit_t *limit = NULL;
+	struct drm_device *dev = crtc->dev;
+	DRM_DRIVER_PRIVATE_T *dev_priv = dev->dev_private;
+
+	if (psb_intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)
+	    || psb_intel_pipe_has_type(crtc, INTEL_OUTPUT_MIPI)) {
+		switch (dev_priv->core_freq) {
+		case 100:
+			limit = &mrst_limits[MRST_LIMIT_LVDS_100L];
+			break;
+		case 166:
+			limit = &mrst_limits[MRST_LIMIT_LVDS_83];
+			break;
+		case 200:
+			limit = &mrst_limits[MRST_LIMIT_LVDS_100];
+			break;
+		}
+	} else {
+		limit = NULL;
+		PSB_DEBUG_ENTRY("mrst_limit Wrong display type.\n");
+	}
+
+	return limit;
+}
+
+/** Derive the pixel clock for the given refclk and divisors for 8xx chips. */
+static void mrst_clock(int refclk, struct mrst_clock_t *clock)
+{
+	clock->dot = (refclk * clock->m) / (14 * clock->p1);
+}
+
+void mrstPrintPll(char *prefix, struct mrst_clock_t *clock)
+{
+	PSB_DEBUG_ENTRY("%s: dotclock = %d,  m = %d, p1 = %d.\n",
+	     prefix, clock->dot, clock->m, clock->p1);
+}
+
+/**
+ * Returns a set of divisors for the desired target clock with the given refclk,
+ * or FALSE.  Divisor values are the actual divisors for
+ */
+static bool
+mrstFindBestPLL(struct drm_crtc *crtc, int target, int refclk,
+		struct mrst_clock_t *best_clock)
+{
+	struct mrst_clock_t clock;
+	const struct mrst_limit_t *limit = mrst_limit(crtc);
+	int err = target;
+
+	memset(best_clock, 0, sizeof(*best_clock));
+
+	for (clock.m = limit->m.min; clock.m <= limit->m.max; clock.m++) {
+		for (clock.p1 = limit->p1.min; clock.p1 <= limit->p1.max;
+		     clock.p1++) {
+			int this_err;
+
+			mrst_clock(refclk, &clock);
+
+			this_err = abs(clock.dot - target);
+			if (this_err < err) {
+				*best_clock = clock;
+				err = this_err;
+			}
+		}
+	}
+	DRM_DEBUG("mrstFindBestPLL err = %d.\n", err);
+
+	return err != target;
+}
+
+/**
+ * Sets the power management mode of the pipe and plane.
+ *
+ * This code should probably grow support for turning the cursor off and back
+ * on appropriately at the same time as we're turning the pipe off/on.
+ */
+static void mrst_crtc_dpms(struct drm_crtc *crtc, int mode)
+{
+	struct drm_device *dev = crtc->dev;
+	struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
+	int pipe = psb_intel_crtc->pipe;
+	int dpll_reg = (pipe == 0) ? MRST_DPLL_A : DPLL_B;
+	int dspcntr_reg = (pipe == 0) ? DSPACNTR : DSPBCNTR;
+	int dspbase_reg = (pipe == 0) ? MRST_DSPABASE : DSPBBASE;
+	int pipeconf_reg = (pipe == 0) ? PIPEACONF : PIPEBCONF;
+	u32 temp;
+	bool enabled;
+
+	PSB_DEBUG_ENTRY("mode = %d, pipe = %d\n", mode, pipe);
+
+	if (!gma_power_begin(dev, true))
+		return;
+
+	/* XXX: When our outputs are all unaware of DPMS modes other than off
+	 * and on, we should map those modes to DRM_MODE_DPMS_OFF in the CRTC.
+	 */
+	switch (mode) {
+	case DRM_MODE_DPMS_ON:
+	case DRM_MODE_DPMS_STANDBY:
+	case DRM_MODE_DPMS_SUSPEND:
+		/* Enable the DPLL */
+		temp = REG_READ(dpll_reg);
+		if ((temp & DPLL_VCO_ENABLE) == 0) {
+			REG_WRITE(dpll_reg, temp);
+			REG_READ(dpll_reg);
+			/* Wait for the clocks to stabilize. */
+			udelay(150);
+			REG_WRITE(dpll_reg, temp | DPLL_VCO_ENABLE);
+			REG_READ(dpll_reg);
+			/* Wait for the clocks to stabilize. */
+			udelay(150);
+			REG_WRITE(dpll_reg, temp | DPLL_VCO_ENABLE);
+			REG_READ(dpll_reg);
+			/* Wait for the clocks to stabilize. */
+			udelay(150);
+		}
+		/* Enable the pipe */
+		temp = REG_READ(pipeconf_reg);
+		if ((temp & PIPEACONF_ENABLE) == 0)
+			REG_WRITE(pipeconf_reg, temp | PIPEACONF_ENABLE);
+		/* Enable the plane */
+		temp = REG_READ(dspcntr_reg);
+		if ((temp & DISPLAY_PLANE_ENABLE) == 0) {
+			REG_WRITE(dspcntr_reg,
+				  temp | DISPLAY_PLANE_ENABLE);
+			/* Flush the plane changes */
+			REG_WRITE(dspbase_reg, REG_READ(dspbase_reg));
+		}
+
+		psb_intel_crtc_load_lut(crtc);
+
+		/* Give the overlay scaler a chance to enable
+		   if it's on this pipe */
+		/* psb_intel_crtc_dpms_video(crtc, true); TODO */
+		break;
+	case DRM_MODE_DPMS_OFF:
+		/* Give the overlay scaler a chance to disable
+		 * if it's on this pipe */
+		/* psb_intel_crtc_dpms_video(crtc, FALSE); TODO */
+
+		/* Disable the VGA plane that we never use */
+		REG_WRITE(VGACNTRL, VGA_DISP_DISABLE);
+		/* Disable display plane */
+		temp = REG_READ(dspcntr_reg);
+		if ((temp & DISPLAY_PLANE_ENABLE) != 0) {
+			REG_WRITE(dspcntr_reg,
+				  temp & ~DISPLAY_PLANE_ENABLE);
+			/* Flush the plane changes */
+			REG_WRITE(dspbase_reg, REG_READ(dspbase_reg));
+			REG_READ(dspbase_reg);
+		}
+
+		/* Next, disable display pipes */
+		temp = REG_READ(pipeconf_reg);
+		if ((temp & PIPEACONF_ENABLE) != 0) {
+			REG_WRITE(pipeconf_reg, temp & ~PIPEACONF_ENABLE);
+			REG_READ(pipeconf_reg);
+		}
+		/* Wait for for the pipe disable to take effect. */
+		psb_intel_wait_for_vblank(dev);
+
+		temp = REG_READ(dpll_reg);
+		if ((temp & DPLL_VCO_ENABLE) != 0) {
+			REG_WRITE(dpll_reg, temp & ~DPLL_VCO_ENABLE);
+			REG_READ(dpll_reg);
+		}
+
+		/* Wait for the clocks to turn off. */
+		udelay(150);
+		break;
+	}
+
+	enabled = crtc->enabled && mode != DRM_MODE_DPMS_OFF;
+
+	/*Set FIFO Watermarks*/
+	REG_WRITE(DSPARB, 0x3FFF);
+	REG_WRITE(DSPFW1, 0x3F88080A);
+	REG_WRITE(DSPFW2, 0x0b060808);
+	REG_WRITE(DSPFW3, 0x0);
+	REG_WRITE(DSPFW4, 0x08030404);
+	REG_WRITE(DSPFW5, 0x04040404);
+	REG_WRITE(DSPFW6, 0x78);
+	REG_WRITE(0x70400, REG_READ(0x70400) | 0x4000);
+	/* Must write Bit 14 of the Chicken Bit Register */
+
+	gma_power_end(dev);
+}
+
+/**
+ * Return the pipe currently connected to the panel fitter,
+ * or -1 if the panel fitter is not present or not in use
+ */
+static int mrst_panel_fitter_pipe(struct drm_device *dev)
+{
+	u32 pfit_control;
+
+	pfit_control = REG_READ(PFIT_CONTROL);
+
+	/* See if the panel fitter is in use */
+	if ((pfit_control & PFIT_ENABLE) == 0)
+		return -1;
+	return (pfit_control >> 29) & 3;
+}
+
+static int mrst_crtc_mode_set(struct drm_crtc *crtc,
+			      struct drm_display_mode *mode,
+			      struct drm_display_mode *adjusted_mode,
+			      int x, int y,
+			      struct drm_framebuffer *old_fb)
+{
+	struct drm_device *dev = crtc->dev;
+	struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
+	DRM_DRIVER_PRIVATE_T *dev_priv = dev->dev_private;
+	int pipe = psb_intel_crtc->pipe;
+	int fp_reg = (pipe == 0) ? MRST_FPA0 : FPB0;
+	int dpll_reg = (pipe == 0) ? MRST_DPLL_A : DPLL_B;
+	int dspcntr_reg = (pipe == 0) ? DSPACNTR : DSPBCNTR;
+	int pipeconf_reg = (pipe == 0) ? PIPEACONF : PIPEBCONF;
+	int htot_reg = (pipe == 0) ? HTOTAL_A : HTOTAL_B;
+	int hblank_reg = (pipe == 0) ? HBLANK_A : HBLANK_B;
+	int hsync_reg = (pipe == 0) ? HSYNC_A : HSYNC_B;
+	int vtot_reg = (pipe == 0) ? VTOTAL_A : VTOTAL_B;
+	int vblank_reg = (pipe == 0) ? VBLANK_A : VBLANK_B;
+	int vsync_reg = (pipe == 0) ? VSYNC_A : VSYNC_B;
+	int pipesrc_reg = (pipe == 0) ? PIPEASRC : PIPEBSRC;
+	int refclk = 0;
+	struct mrst_clock_t clock;
+	u32 dpll = 0, fp = 0, dspcntr, pipeconf;
+	bool ok, is_sdvo = false;
+	bool is_crt = false, is_lvds = false, is_tv = false;
+	bool is_mipi = false;
+	struct drm_mode_config *mode_config = &dev->mode_config;
+	struct psb_intel_output *psb_intel_output = NULL;
+	uint64_t scalingType = DRM_MODE_SCALE_FULLSCREEN;
+	struct drm_encoder *encoder;
+
+	PSB_DEBUG_ENTRY("pipe = 0x%x\n", pipe);
+
+	if (!gma_power_begin(dev, true))
+		return 0;
+
+	memcpy(&psb_intel_crtc->saved_mode,
+		mode,
+		sizeof(struct drm_display_mode));
+	memcpy(&psb_intel_crtc->saved_adjusted_mode,
+		adjusted_mode,
+		sizeof(struct drm_display_mode));
+
+	list_for_each_entry(encoder, &mode_config->encoder_list, head) {
+
+		if (encoder->crtc != crtc)
+			continue;
+
+		psb_intel_output = enc_to_psb_intel_output(encoder);
+		switch (psb_intel_output->type) {
+		case INTEL_OUTPUT_LVDS:
+			is_lvds = true;
+			break;
+		case INTEL_OUTPUT_SDVO:
+			is_sdvo = true;
+			break;
+		case INTEL_OUTPUT_TVOUT:
+			is_tv = true;
+			break;
+		case INTEL_OUTPUT_ANALOG:
+			is_crt = true;
+			break;
+		case INTEL_OUTPUT_MIPI:
+			is_mipi = true;
+			break;
+		}
+	}
+
+	/* Disable the VGA plane that we never use */
+	REG_WRITE(VGACNTRL, VGA_DISP_DISABLE);
+
+	/* Disable the panel fitter if it was on our pipe */
+	if (mrst_panel_fitter_pipe(dev) == pipe)
+		REG_WRITE(PFIT_CONTROL, 0);
+
+	REG_WRITE(pipesrc_reg,
+		  ((mode->crtc_hdisplay - 1) << 16) |
+		  (mode->crtc_vdisplay - 1));
+
+	if (psb_intel_output)
+		drm_connector_property_get_value(&psb_intel_output->base,
+			dev->mode_config.scaling_mode_property, &scalingType);
+
+	if (scalingType == DRM_MODE_SCALE_NO_SCALE) {
+		/* Moorestown doesn't have register support for centering so
+		 * we need to mess with the h/vblank and h/vsync start and
+		 * ends to get centering */
+		int offsetX = 0, offsetY = 0;
+
+		offsetX = (adjusted_mode->crtc_hdisplay -
+			   mode->crtc_hdisplay) / 2;
+		offsetY = (adjusted_mode->crtc_vdisplay -
+			   mode->crtc_vdisplay) / 2;
+
+		REG_WRITE(htot_reg, (mode->crtc_hdisplay - 1) |
+			((adjusted_mode->crtc_htotal - 1) << 16));
+		REG_WRITE(vtot_reg, (mode->crtc_vdisplay - 1) |
+			((adjusted_mode->crtc_vtotal - 1) << 16));
+		REG_WRITE(hblank_reg,
+			(adjusted_mode->crtc_hblank_start - offsetX - 1) |
+			((adjusted_mode->crtc_hblank_end - offsetX - 1) << 16));
+		REG_WRITE(hsync_reg,
+			(adjusted_mode->crtc_hsync_start - offsetX - 1) |
+			((adjusted_mode->crtc_hsync_end - offsetX - 1) << 16));
+		REG_WRITE(vblank_reg,
+			(adjusted_mode->crtc_vblank_start - offsetY - 1) |
+			((adjusted_mode->crtc_vblank_end - offsetY - 1) << 16));
+		REG_WRITE(vsync_reg,
+			(adjusted_mode->crtc_vsync_start - offsetY - 1) |
+			((adjusted_mode->crtc_vsync_end - offsetY - 1) << 16));
+	} else {
+		REG_WRITE(htot_reg, (adjusted_mode->crtc_hdisplay - 1) |
+			((adjusted_mode->crtc_htotal - 1) << 16));
+		REG_WRITE(vtot_reg, (adjusted_mode->crtc_vdisplay - 1) |
+			((adjusted_mode->crtc_vtotal - 1) << 16));
+		REG_WRITE(hblank_reg, (adjusted_mode->crtc_hblank_start - 1) |
+			((adjusted_mode->crtc_hblank_end - 1) << 16));
+		REG_WRITE(hsync_reg, (adjusted_mode->crtc_hsync_start - 1) |
+			((adjusted_mode->crtc_hsync_end - 1) << 16));
+		REG_WRITE(vblank_reg, (adjusted_mode->crtc_vblank_start - 1) |
+			((adjusted_mode->crtc_vblank_end - 1) << 16));
+		REG_WRITE(vsync_reg, (adjusted_mode->crtc_vsync_start - 1) |
+			((adjusted_mode->crtc_vsync_end - 1) << 16));
+	}
+
+	/* Flush the plane changes */
+	{
+		struct drm_crtc_helper_funcs *crtc_funcs =
+		    crtc->helper_private;
+		crtc_funcs->mode_set_base(crtc, x, y, old_fb);
+	}
+
+	/* setup pipeconf */
+	pipeconf = REG_READ(pipeconf_reg);
+
+	/* Set up the display plane register */
+	dspcntr = REG_READ(dspcntr_reg);
+	dspcntr |= DISPPLANE_GAMMA_ENABLE;
+
+	if (pipe == 0)
+		dspcntr |= DISPPLANE_SEL_PIPE_A;
+	else
+		dspcntr |= DISPPLANE_SEL_PIPE_B;
+
+	dev_priv->dspcntr = dspcntr |= DISPLAY_PLANE_ENABLE;
+	dev_priv->pipeconf = pipeconf |= PIPEACONF_ENABLE;
+
+	if (is_mipi)
+		goto mrst_crtc_mode_set_exit;
+
+	refclk = dev_priv->core_freq * 1000;
+
+	dpll = 0;		/*BIT16 = 0 for 100MHz reference */
+
+	ok = mrstFindBestPLL(crtc, adjusted_mode->clock, refclk, &clock);
+
+	if (!ok) {
+		PSB_DEBUG_ENTRY(
+			"mrstFindBestPLL fail in mrst_crtc_mode_set.\n");
+	} else {
+		PSB_DEBUG_ENTRY("mrst_crtc_mode_set pixel clock = %d,"
+			 "m = %x, p1 = %x.\n", clock.dot, clock.m,
+			 clock.p1);
+	}
+
+	fp = mrst_m_converts[(clock.m - MRST_M_MIN)] << 8;
+
+	dpll |= DPLL_VGA_MODE_DIS;
+
+
+	dpll |= DPLL_VCO_ENABLE;
+
+	if (is_lvds)
+		dpll |= DPLLA_MODE_LVDS;
+	else
+		dpll |= DPLLB_MODE_DAC_SERIAL;
+
+	if (is_sdvo) {
+		int sdvo_pixel_multiply =
+		    adjusted_mode->clock / mode->clock;
+
+		dpll |= DPLL_DVO_HIGH_SPEED;
+		dpll |=
+		    (sdvo_pixel_multiply -
+		     1) << SDVO_MULTIPLIER_SHIFT_HIRES;
+	}
+
+
+	/* compute bitmask from p1 value */
+	dpll |= (1 << (clock.p1 - 2)) << 17;
+
+	dpll |= DPLL_VCO_ENABLE;
+
+	mrstPrintPll("chosen", &clock);
+
+	if (dpll & DPLL_VCO_ENABLE) {
+		REG_WRITE(fp_reg, fp);
+		REG_WRITE(dpll_reg, dpll & ~DPLL_VCO_ENABLE);
+		REG_READ(dpll_reg);
+		/* Check the DPLLA lock bit PIPEACONF[29] */
+		udelay(150);
+	}
+
+	REG_WRITE(fp_reg, fp);
+	REG_WRITE(dpll_reg, dpll);
+	REG_READ(dpll_reg);
+	/* Wait for the clocks to stabilize. */
+	udelay(150);
+
+	/* write it again -- the BIOS does, after all */
+	REG_WRITE(dpll_reg, dpll);
+	REG_READ(dpll_reg);
+	/* Wait for the clocks to stabilize. */
+	udelay(150);
+
+	REG_WRITE(pipeconf_reg, pipeconf);
+	REG_READ(pipeconf_reg);
+	psb_intel_wait_for_vblank(dev);
+
+	REG_WRITE(dspcntr_reg, dspcntr);
+	psb_intel_wait_for_vblank(dev);
+
+mrst_crtc_mode_set_exit:
+	gma_power_end(dev);
+	return 0;
+}
+
+static bool mrst_crtc_mode_fixup(struct drm_crtc *crtc,
+				  struct drm_display_mode *mode,
+				  struct drm_display_mode *adjusted_mode)
+{
+	return true;
+}
+
+int mrst_pipe_set_base(struct drm_crtc *crtc,
+			    int x, int y, struct drm_framebuffer *old_fb)
+{
+	struct drm_device *dev = crtc->dev;
+	/* struct drm_i915_master_private *master_priv; */
+	struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
+	struct psb_framebuffer *psbfb = to_psb_fb(crtc->fb);
+	int pipe = psb_intel_crtc->pipe;
+	unsigned long start, offset;
+	/* FIXME: check if we need this surely MRST is pipe 0 only */
+	int dspbase = (pipe == 0 ? DSPALINOFF : DSPBBASE);
+	int dspsurf = (pipe == 0 ? DSPASURF : DSPBSURF);
+	int dspstride = (pipe == 0) ? DSPASTRIDE : DSPBSTRIDE;
+	int dspcntr_reg = (pipe == 0) ? DSPACNTR : DSPBCNTR;
+	u32 dspcntr;
+	int ret = 0;
+
+	PSB_DEBUG_ENTRY("\n");
+
+	/* no fb bound */
+	if (!crtc->fb) {
+		DRM_DEBUG("No FB bound\n");
+		return 0;
+	}
+
+	if (!gma_power_begin(dev, true))
+		return 0;
+
+	start = psbfb->gtt->offset;
+	offset = y * crtc->fb->pitch + x * (crtc->fb->bits_per_pixel / 8);
+
+	REG_WRITE(dspstride, crtc->fb->pitch);
+
+	dspcntr = REG_READ(dspcntr_reg);
+	dspcntr &= ~DISPPLANE_PIXFORMAT_MASK;
+
+	switch (crtc->fb->bits_per_pixel) {
+	case 8:
+		dspcntr |= DISPPLANE_8BPP;
+		break;
+	case 16:
+		if (crtc->fb->depth == 15)
+			dspcntr |= DISPPLANE_15_16BPP;
+		else
+			dspcntr |= DISPPLANE_16BPP;
+		break;
+	case 24:
+	case 32:
+		dspcntr |= DISPPLANE_32BPP_NO_ALPHA;
+		break;
+	default:
+		DRM_ERROR("Unknown color depth\n");
+		ret = -EINVAL;
+		goto pipe_set_base_exit;
+	}
+	REG_WRITE(dspcntr_reg, dspcntr);
+
+	DRM_DEBUG("Writing base %08lX %08lX %d %d\n", start, offset, x, y);
+	if (0 /* FIXMEAC - check what PSB needs */) {
+		REG_WRITE(dspbase, offset);
+		REG_READ(dspbase);
+		REG_WRITE(dspsurf, start);
+		REG_READ(dspsurf);
+	} else {
+		REG_WRITE(dspbase, start + offset);
+		REG_READ(dspbase);
+	}
+
+pipe_set_base_exit:
+	gma_power_end(dev);
+	return ret;
+}
+
+static void mrst_crtc_prepare(struct drm_crtc *crtc)
+{
+	struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
+	crtc_funcs->dpms(crtc, DRM_MODE_DPMS_OFF);
+}
+
+static void mrst_crtc_commit(struct drm_crtc *crtc)
+{
+	struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
+	crtc_funcs->dpms(crtc, DRM_MODE_DPMS_ON);
+}
+
+const struct drm_crtc_helper_funcs mrst_helper_funcs = {
+	.dpms = mrst_crtc_dpms,
+	.mode_fixup = mrst_crtc_mode_fixup,
+	.mode_set = mrst_crtc_mode_set,
+	.mode_set_base = mrst_pipe_set_base,
+	.prepare = mrst_crtc_prepare,
+	.commit = mrst_crtc_commit,
+};
+
diff -druN linux-2.6.39-libre/drivers/staging/gma500/mrst.h linux-3.0-rc7-libre/drivers/staging/gma500/mrst.h
--- linux-2.6.39-libre/drivers/staging/gma500/mrst.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/staging/gma500/mrst.h	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,217 @@
+/**************************************************************************
+ * Copyright (c) 2007-2011, Intel Corporation.
+ * All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ **************************************************************************/
+
+/* MID device specific descriptors */
+
+struct mrst_vbt {
+	s8 signature[4];	/*4 bytes,"$GCT" */
+	u8 revision;
+	u8 size;
+	u8 checksum;
+	void *mrst_gct;
+} __attribute__ ((packed));
+
+struct mrst_timing_info {
+	u16 pixel_clock;
+	u8 hactive_lo;
+	u8 hblank_lo;
+	u8 hblank_hi:4;
+	u8 hactive_hi:4;
+	u8 vactive_lo;
+	u8 vblank_lo;
+	u8 vblank_hi:4;
+	u8 vactive_hi:4;
+	u8 hsync_offset_lo;
+	u8 hsync_pulse_width_lo;
+	u8 vsync_pulse_width_lo:4;
+	u8 vsync_offset_lo:4;
+	u8 vsync_pulse_width_hi:2;
+	u8 vsync_offset_hi:2;
+	u8 hsync_pulse_width_hi:2;
+	u8 hsync_offset_hi:2;
+	u8 width_mm_lo;
+	u8 height_mm_lo;
+	u8 height_mm_hi:4;
+	u8 width_mm_hi:4;
+	u8 hborder;
+	u8 vborder;
+	u8 unknown0:1;
+	u8 hsync_positive:1;
+	u8 vsync_positive:1;
+	u8 separate_sync:2;
+	u8 stereo:1;
+	u8 unknown6:1;
+	u8 interlaced:1;
+} __attribute__((packed));
+
+struct gct_r10_timing_info {
+	u16 pixel_clock;
+	u32 hactive_lo:8;
+	u32 hactive_hi:4;
+	u32 hblank_lo:8;
+	u32 hblank_hi:4;
+	u32 hsync_offset_lo:8;
+	u16 hsync_offset_hi:2;
+	u16 hsync_pulse_width_lo:8;
+	u16 hsync_pulse_width_hi:2;
+	u16 hsync_positive:1;
+	u16 rsvd_1:3;
+	u8  vactive_lo:8;
+	u16 vactive_hi:4;
+	u16 vblank_lo:8;
+	u16 vblank_hi:4;
+	u16 vsync_offset_lo:4;
+	u16 vsync_offset_hi:2;
+	u16 vsync_pulse_width_lo:4;
+	u16 vsync_pulse_width_hi:2;
+	u16 vsync_positive:1;
+	u16 rsvd_2:3;
+} __attribute__((packed));
+
+struct mrst_panel_descriptor_v1 {
+	u32 Panel_Port_Control; /* 1 dword, Register 0x61180 if LVDS */
+				/* 0x61190 if MIPI */
+	u32 Panel_Power_On_Sequencing;/*1 dword,Register 0x61208,*/
+	u32 Panel_Power_Off_Sequencing;/*1 dword,Register 0x6120C,*/
+	u32 Panel_Power_Cycle_Delay_and_Reference_Divisor;/* 1 dword */
+						/* Register 0x61210 */
+	struct mrst_timing_info DTD;/*18 bytes, Standard definition */
+	u16 Panel_Backlight_Inverter_Descriptor;/* 16 bits, as follows */
+				/* Bit 0, Frequency, 15 bits,0 - 32767Hz */
+			/* Bit 15, Polarity, 1 bit, 0: Normal, 1: Inverted */
+	u16 Panel_MIPI_Display_Descriptor;
+			/*16 bits, Defined as follows: */
+			/* if MIPI, 0x0000 if LVDS */
+			/* Bit 0, Type, 2 bits, */
+			/* 0: Type-1, */
+			/* 1: Type-2, */
+			/* 2: Type-3, */
+			/* 3: Type-4 */
+			/* Bit 2, Pixel Format, 4 bits */
+			/* Bit0: 16bpp (not supported in LNC), */
+			/* Bit1: 18bpp loosely packed, */
+			/* Bit2: 18bpp packed, */
+			/* Bit3: 24bpp */
+			/* Bit 6, Reserved, 2 bits, 00b */
+			/* Bit 8, Minimum Supported Frame Rate, 6 bits, 0 - 63Hz */
+			/* Bit 14, Reserved, 2 bits, 00b */
+} __attribute__ ((packed));
+
+struct mrst_panel_descriptor_v2 {
+	u32 Panel_Port_Control; /* 1 dword, Register 0x61180 if LVDS */
+				/* 0x61190 if MIPI */
+	u32 Panel_Power_On_Sequencing;/*1 dword,Register 0x61208,*/
+	u32 Panel_Power_Off_Sequencing;/*1 dword,Register 0x6120C,*/
+	u8 Panel_Power_Cycle_Delay_and_Reference_Divisor;/* 1 byte */
+						/* Register 0x61210 */
+	struct mrst_timing_info DTD;/*18 bytes, Standard definition */
+	u16 Panel_Backlight_Inverter_Descriptor;/*16 bits, as follows*/
+				/*Bit 0, Frequency, 16 bits, 0 - 32767Hz*/
+	u8 Panel_Initial_Brightness;/* [7:0] 0 - 100% */
+			/*Bit 7, Polarity, 1 bit,0: Normal, 1: Inverted*/
+	u16 Panel_MIPI_Display_Descriptor;
+			/*16 bits, Defined as follows: */
+			/* if MIPI, 0x0000 if LVDS */
+			/* Bit 0, Type, 2 bits, */
+			/* 0: Type-1, */
+			/* 1: Type-2, */
+			/* 2: Type-3, */
+			/* 3: Type-4 */
+			/* Bit 2, Pixel Format, 4 bits */
+			/* Bit0: 16bpp (not supported in LNC), */
+			/* Bit1: 18bpp loosely packed, */
+			/* Bit2: 18bpp packed, */
+			/* Bit3: 24bpp */
+			/* Bit 6, Reserved, 2 bits, 00b */
+			/* Bit 8, Minimum Supported Frame Rate, 6 bits, 0 - 63Hz */
+			/* Bit 14, Reserved, 2 bits, 00b */
+} __attribute__ ((packed));
+
+union mrst_panel_rx {
+	struct{
+		u16 NumberOfLanes:2; /*Num of Lanes, 2 bits,0 = 1 lane,*/
+			/* 1 = 2 lanes, 2 = 3 lanes, 3 = 4 lanes. */
+		u16 MaxLaneFreq:3; /* 0: 100MHz, 1: 200MHz, 2: 300MHz, */
+		/*3: 400MHz, 4: 500MHz, 5: 600MHz, 6: 700MHz, 7: 800MHz.*/
+		u16 SupportedVideoTransferMode:2; /*0: Non-burst only */
+					/* 1: Burst and non-burst */
+					/* 2/3: Reserved */
+		u16 HSClkBehavior:1; /*0: Continuous, 1: Non-continuous*/
+		u16 DuoDisplaySupport:1; /*1 bit,0: No, 1: Yes*/
+		u16 ECC_ChecksumCapabilities:1;/*1 bit,0: No, 1: Yes*/
+		u16 BidirectionalCommunication:1;/*1 bit,0: No, 1: Yes */
+		u16 Rsvd:5;/*5 bits,00000b */
+	} panelrx;
+	u16 panel_receiver;
+} __attribute__ ((packed));
+
+struct mrst_gct_v1 {
+	union{ /*8 bits,Defined as follows: */
+		struct {
+			u8 PanelType:4; /*4 bits, Bit field for panels*/
+					/* 0 - 3: 0 = LVDS, 1 = MIPI*/
+					/*2 bits,Specifies which of the*/
+			u8 BootPanelIndex:2;
+					/* 4 panels to use by default*/
+			u8 BootMIPI_DSI_RxIndex:2;/*Specifies which of*/
+					/* the 4 MIPI DSI receivers to use*/
+		} PD;
+		u8 PanelDescriptor;
+	};
+	struct mrst_panel_descriptor_v1 panel[4];/*panel descrs,38 bytes each*/
+	union mrst_panel_rx panelrx[4]; /* panel receivers*/
+} __attribute__ ((packed));
+
+struct mrst_gct_v2 {
+	union{ /*8 bits,Defined as follows: */
+		struct {
+			u8 PanelType:4; /*4 bits, Bit field for panels*/
+					/* 0 - 3: 0 = LVDS, 1 = MIPI*/
+					/*2 bits,Specifies which of the*/
+			u8 BootPanelIndex:2;
+					/* 4 panels to use by default*/
+			u8 BootMIPI_DSI_RxIndex:2;/*Specifies which of*/
+					/* the 4 MIPI DSI receivers to use*/
+		} PD;
+		u8 PanelDescriptor;
+	};
+	struct mrst_panel_descriptor_v2 panel[4];/*panel descrs,38 bytes each*/
+	union mrst_panel_rx panelrx[4]; /* panel receivers*/
+} __attribute__ ((packed));
+
+struct mrst_gct_data {
+	u8 bpi; /* boot panel index, number of panel used during boot */
+	u8 pt; /* panel type, 4 bit field, 0=lvds, 1=mipi */
+	struct mrst_timing_info DTD; /* timing info for the selected panel */
+	u32 Panel_Port_Control;
+	u32 PP_On_Sequencing;/*1 dword,Register 0x61208,*/
+	u32 PP_Off_Sequencing;/*1 dword,Register 0x6120C,*/
+	u32 PP_Cycle_Delay;
+	u16 Panel_Backlight_Inverter_Descriptor;
+	u16 Panel_MIPI_Display_Descriptor;
+} __attribute__ ((packed));
+
+#define MODE_SETTING_IN_CRTC 	0x1
+#define MODE_SETTING_IN_ENCODER 0x2
+#define MODE_SETTING_ON_GOING 	0x3
+#define MODE_SETTING_IN_DSR 	0x4
+#define MODE_SETTING_ENCODER_DONE 0x8
+#define GCT_R10_HEADER_SIZE	16
+#define GCT_R10_DISPLAY_DESC_SIZE	28
+
diff -druN linux-2.6.39-libre/drivers/staging/gma500/mrst_lvds.c linux-3.0-rc7-libre/drivers/staging/gma500/mrst_lvds.c
--- linux-2.6.39-libre/drivers/staging/gma500/mrst_lvds.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/staging/gma500/mrst_lvds.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,371 @@
+/*
+ * Copyright © 2006-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.
+ *
+ * Authors:
+ *	Eric Anholt <eric@anholt.net>
+ *	Dave Airlie <airlied@linux.ie>
+ *	Jesse Barnes <jesse.barnes@intel.com>
+ */
+
+#include <linux/i2c.h>
+#include <drm/drmP.h>
+#include <asm/mrst.h>
+
+#include "psb_intel_bios.h"
+#include "psb_drv.h"
+#include "psb_intel_drv.h"
+#include "psb_intel_reg.h"
+#include "psb_powermgmt.h"
+#include <linux/pm_runtime.h>
+
+/* The max/min PWM frequency in BPCR[31:17] - */
+/* The smallest number is 1 (not 0) that can fit in the
+ * 15-bit field of the and then*/
+/* shifts to the left by one bit to get the actual 16-bit
+ * value that the 15-bits correspond to.*/
+#define MRST_BLC_MAX_PWM_REG_FREQ	    0xFFFF
+#define BRIGHTNESS_MAX_LEVEL 100
+
+/**
+ * Sets the power state for the panel.
+ */
+static void mrst_lvds_set_power(struct drm_device *dev,
+				struct psb_intel_output *output, bool on)
+{
+	u32 pp_status;
+	DRM_DRIVER_PRIVATE_T *dev_priv = dev->dev_private;
+	PSB_DEBUG_ENTRY("\n");
+
+	if (!gma_power_begin(dev, true))
+		return;
+
+	if (on) {
+		REG_WRITE(PP_CONTROL, REG_READ(PP_CONTROL) |
+			  POWER_TARGET_ON);
+		do {
+			pp_status = REG_READ(PP_STATUS);
+		} while ((pp_status & (PP_ON | PP_READY)) == PP_READY);
+		dev_priv->is_lvds_on = true;
+	} else {
+		REG_WRITE(PP_CONTROL, REG_READ(PP_CONTROL) &
+			  ~POWER_TARGET_ON);
+		do {
+			pp_status = REG_READ(PP_STATUS);
+		} while (pp_status & PP_ON);
+		dev_priv->is_lvds_on = false;
+		pm_request_idle(&dev->pdev->dev);
+	}
+
+	gma_power_end(dev);
+}
+
+static void mrst_lvds_dpms(struct drm_encoder *encoder, int mode)
+{
+	struct drm_device *dev = encoder->dev;
+	struct psb_intel_output *output = enc_to_psb_intel_output(encoder);
+
+	PSB_DEBUG_ENTRY("\n");
+
+	if (mode == DRM_MODE_DPMS_ON)
+		mrst_lvds_set_power(dev, output, true);
+	else
+		mrst_lvds_set_power(dev, output, false);
+
+	/* XXX: We never power down the LVDS pairs. */
+}
+
+static void mrst_lvds_mode_set(struct drm_encoder *encoder,
+			       struct drm_display_mode *mode,
+			       struct drm_display_mode *adjusted_mode)
+{
+	struct psb_intel_mode_device *mode_dev =
+				enc_to_psb_intel_output(encoder)->mode_dev;
+	struct drm_device *dev = encoder->dev;
+	u32 lvds_port;
+	uint64_t v = DRM_MODE_SCALE_FULLSCREEN;
+
+	PSB_DEBUG_ENTRY("\n");
+
+	if (!gma_power_begin(dev, true))
+		return;
+
+	/*
+	 * The LVDS pin pair will already have been turned on in the
+	 * psb_intel_crtc_mode_set since it has a large impact on the DPLL
+	 * settings.
+	 */
+	lvds_port = (REG_READ(LVDS) &
+		    (~LVDS_PIPEB_SELECT)) |
+		    LVDS_PORT_EN |
+		    LVDS_BORDER_EN;
+
+	if (mode_dev->panel_wants_dither)
+		lvds_port |= MRST_PANEL_8TO6_DITHER_ENABLE;
+
+	REG_WRITE(LVDS, lvds_port);
+
+	drm_connector_property_get_value(
+		&enc_to_psb_intel_output(encoder)->base,
+		dev->mode_config.scaling_mode_property,
+		&v);
+
+	if (v == DRM_MODE_SCALE_NO_SCALE)
+		REG_WRITE(PFIT_CONTROL, 0);
+	else if (v == DRM_MODE_SCALE_ASPECT) {
+		if ((mode->vdisplay != adjusted_mode->crtc_vdisplay) ||
+		    (mode->hdisplay != adjusted_mode->crtc_hdisplay)) {
+			if ((adjusted_mode->crtc_hdisplay * mode->vdisplay) ==
+			    (mode->hdisplay * adjusted_mode->crtc_vdisplay))
+				REG_WRITE(PFIT_CONTROL, PFIT_ENABLE);
+			else if ((adjusted_mode->crtc_hdisplay *
+				mode->vdisplay) > (mode->hdisplay *
+				adjusted_mode->crtc_vdisplay))
+				REG_WRITE(PFIT_CONTROL, PFIT_ENABLE |
+					  PFIT_SCALING_MODE_PILLARBOX);
+			else
+				REG_WRITE(PFIT_CONTROL, PFIT_ENABLE |
+					  PFIT_SCALING_MODE_LETTERBOX);
+		} else
+			REG_WRITE(PFIT_CONTROL, PFIT_ENABLE);
+	} else /*(v == DRM_MODE_SCALE_FULLSCREEN)*/
+		REG_WRITE(PFIT_CONTROL, PFIT_ENABLE);
+
+	gma_power_end(dev);
+}
+
+
+static const struct drm_encoder_helper_funcs mrst_lvds_helper_funcs = {
+	.dpms = mrst_lvds_dpms,
+	.mode_fixup = psb_intel_lvds_mode_fixup,
+	.prepare = psb_intel_lvds_prepare,
+	.mode_set = mrst_lvds_mode_set,
+	.commit = psb_intel_lvds_commit,
+};
+
+static struct drm_display_mode lvds_configuration_modes[] = {
+	/* hard coded fixed mode for TPO LTPS LPJ040K001A */
+	{ DRM_MODE("800x480",  DRM_MODE_TYPE_DRIVER, 33264, 800, 836,
+		   846, 1056, 0, 480, 489, 491, 525, 0, 0) },
+	/* hard coded fixed mode for LVDS 800x480 */
+	{ DRM_MODE("800x480",  DRM_MODE_TYPE_DRIVER, 30994, 800, 801,
+		   802, 1024, 0, 480, 481, 482, 525, 0, 0) },
+	/* hard coded fixed mode for Samsung 480wsvga LVDS 1024x600@75 */
+	{ DRM_MODE("1024x600", DRM_MODE_TYPE_DRIVER, 53990, 1024, 1072,
+		   1104, 1184, 0, 600, 603, 604, 608, 0, 0) },
+	/* hard coded fixed mode for Samsung 480wsvga LVDS 1024x600@75 */
+	{ DRM_MODE("1024x600", DRM_MODE_TYPE_DRIVER, 53990, 1024, 1104,
+		   1136, 1184, 0, 600, 603, 604, 608, 0, 0) },
+	/* hard coded fixed mode for Sharp wsvga LVDS 1024x600 */
+	{ DRM_MODE("1024x600", DRM_MODE_TYPE_DRIVER, 48885, 1024, 1124,
+		   1204, 1312, 0, 600, 607, 610, 621, 0, 0) },
+	/* hard coded fixed mode for LVDS 1024x768 */
+	{ DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 65000, 1024, 1048,
+		   1184, 1344, 0, 768, 771, 777, 806, 0, 0) },
+	/* hard coded fixed mode for LVDS 1366x768 */
+	{ DRM_MODE("1366x768", DRM_MODE_TYPE_DRIVER, 77500, 1366, 1430,
+		   1558, 1664, 0, 768, 769, 770, 776, 0, 0) },
+};
+
+/* Returns the panel fixed mode from configuration. */
+
+static struct drm_display_mode *
+mrst_lvds_get_configuration_mode(struct drm_device *dev)
+{
+	struct drm_display_mode *mode = NULL;
+	struct drm_psb_private *dev_priv = dev->dev_private;
+	struct mrst_timing_info *ti = &dev_priv->gct_data.DTD;
+
+	if (dev_priv->vbt_data.size != 0x00) { /*if non-zero, then use vbt*/
+		mode = kzalloc(sizeof(*mode), GFP_KERNEL);
+		if (!mode)
+			return NULL;
+
+		mode->hdisplay = (ti->hactive_hi << 8) | ti->hactive_lo;
+		mode->vdisplay = (ti->vactive_hi << 8) | ti->vactive_lo;
+		mode->hsync_start = mode->hdisplay + \
+				((ti->hsync_offset_hi << 8) | \
+				ti->hsync_offset_lo);
+		mode->hsync_end = mode->hsync_start + \
+				((ti->hsync_pulse_width_hi << 8) | \
+				ti->hsync_pulse_width_lo);
+		mode->htotal = mode->hdisplay + ((ti->hblank_hi << 8) | \
+							ti->hblank_lo);
+		mode->vsync_start = \
+			mode->vdisplay + ((ti->vsync_offset_hi << 4) | \
+						ti->vsync_offset_lo);
+		mode->vsync_end = \
+			mode->vsync_start + ((ti->vsync_pulse_width_hi << 4) | \
+						ti->vsync_pulse_width_lo);
+		mode->vtotal = mode->vdisplay + \
+				((ti->vblank_hi << 8) | ti->vblank_lo);
+		mode->clock = ti->pixel_clock * 10;
+#if 0
+		printk(KERN_INFO "hdisplay is %d\n", mode->hdisplay);
+		printk(KERN_INFO "vdisplay is %d\n", mode->vdisplay);
+		printk(KERN_INFO "HSS is %d\n", mode->hsync_start);
+		printk(KERN_INFO "HSE is %d\n", mode->hsync_end);
+		printk(KERN_INFO "htotal is %d\n", mode->htotal);
+		printk(KERN_INFO "VSS is %d\n", mode->vsync_start);
+		printk(KERN_INFO "VSE is %d\n", mode->vsync_end);
+		printk(KERN_INFO "vtotal is %d\n", mode->vtotal);
+		printk(KERN_INFO "clock is %d\n", mode->clock);
+#endif
+	} else
+		mode = drm_mode_duplicate(dev, &lvds_configuration_modes[2]);
+
+	drm_mode_set_name(mode);
+	drm_mode_set_crtcinfo(mode, 0);
+
+	return mode;
+}
+
+/**
+ * mrst_lvds_init - setup LVDS connectors on this device
+ * @dev: drm device
+ *
+ * Create the connector, register the LVDS DDC bus, and try to figure out what
+ * modes we can display on the LVDS panel (if present).
+ */
+void mrst_lvds_init(struct drm_device *dev,
+		    struct psb_intel_mode_device *mode_dev)
+{
+	struct psb_intel_output *psb_intel_output;
+	struct drm_connector *connector;
+	struct drm_encoder *encoder;
+	struct drm_psb_private *dev_priv =
+				(struct drm_psb_private *) dev->dev_private;
+	struct edid *edid;
+	int ret = 0;
+	struct i2c_adapter *i2c_adap;
+	struct drm_display_mode *scan;	/* *modes, *bios_mode; */
+
+	PSB_DEBUG_ENTRY("\n");
+
+	psb_intel_output = kzalloc(sizeof(struct psb_intel_output), GFP_KERNEL);
+	if (!psb_intel_output)
+		return;
+
+	psb_intel_output->mode_dev = mode_dev;
+	connector = &psb_intel_output->base;
+	encoder = &psb_intel_output->enc;
+	dev_priv->is_lvds_on = true;
+	drm_connector_init(dev, &psb_intel_output->base,
+			   &psb_intel_lvds_connector_funcs,
+			   DRM_MODE_CONNECTOR_LVDS);
+
+	drm_encoder_init(dev, &psb_intel_output->enc, &psb_intel_lvds_enc_funcs,
+			 DRM_MODE_ENCODER_LVDS);
+
+	drm_mode_connector_attach_encoder(&psb_intel_output->base,
+					  &psb_intel_output->enc);
+	psb_intel_output->type = INTEL_OUTPUT_LVDS;
+
+	drm_encoder_helper_add(encoder, &mrst_lvds_helper_funcs);
+	drm_connector_helper_add(connector,
+				 &psb_intel_lvds_connector_helper_funcs);
+	connector->display_info.subpixel_order = SubPixelHorizontalRGB;
+	connector->interlace_allowed = false;
+	connector->doublescan_allowed = false;
+
+	drm_connector_attach_property(connector,
+					dev->mode_config.scaling_mode_property,
+					DRM_MODE_SCALE_FULLSCREEN);
+	drm_connector_attach_property(connector,
+					dev_priv->backlight_property,
+					BRIGHTNESS_MAX_LEVEL);
+
+	mode_dev->panel_wants_dither = false;
+	if (dev_priv->vbt_data.size != 0x00)
+		mode_dev->panel_wants_dither = (dev_priv->gct_data.
+			Panel_Port_Control & MRST_PANEL_8TO6_DITHER_ENABLE);
+
+	/*
+	 * LVDS discovery:
+	 * 1) check for EDID on DDC
+	 * 2) check for VBT data
+	 * 3) check to see if LVDS is already on
+	 *    if none of the above, no panel
+	 * 4) make sure lid is open
+	 *    if closed, act like it's not there for now
+	 */
+
+	 /* This ifdef can go once the cpu ident stuff is cleaned up in arch */
+#if defined(CONFIG_X86_MRST)
+	if (mrst_identify_cpu())
+        	i2c_adap = i2c_get_adapter(2);
+        else	/* Oaktrail uses I2C 1 */
+#endif        
+        	i2c_adap = i2c_get_adapter(1);
+
+	if (i2c_adap == NULL)
+		printk(KERN_ALERT "No ddc adapter available!\n");
+	/*
+	 * Attempt to get the fixed panel mode from DDC.  Assume that the
+	 * preferred mode is the right one.
+	 */
+	if (i2c_adap) {
+		edid = drm_get_edid(connector, i2c_adap);
+		if (edid) {
+			drm_mode_connector_update_edid_property(connector,
+									edid);
+			ret = drm_add_edid_modes(connector, edid);
+			kfree(edid);
+		}
+
+		list_for_each_entry(scan, &connector->probed_modes, head) {
+			if (scan->type & DRM_MODE_TYPE_PREFERRED) {
+				mode_dev->panel_fixed_mode =
+				    drm_mode_duplicate(dev, scan);
+				goto out;	/* FIXME: check for quirks */
+			}
+		}
+	}
+
+	/*
+	 * If we didn't get EDID, try geting panel timing
+	 * from configuration data
+	 */
+	mode_dev->panel_fixed_mode = mrst_lvds_get_configuration_mode(dev);
+
+	if (mode_dev->panel_fixed_mode) {
+		mode_dev->panel_fixed_mode->type |=
+		    DRM_MODE_TYPE_PREFERRED;
+		goto out;	/* FIXME: check for quirks */
+	}
+
+	/* If we still don't have a mode after all that, give up. */
+	if (!mode_dev->panel_fixed_mode) {
+		DRM_DEBUG
+		    ("Found no modes on the lvds, ignoring the LVDS\n");
+		goto failed_find;
+	}
+
+out:
+	drm_sysfs_connector_add(connector);
+	return;
+
+failed_find:
+	DRM_DEBUG("No LVDS modes found, disabling.\n");
+	if (psb_intel_output->ddc_bus)
+		psb_intel_i2c_destroy(psb_intel_output->ddc_bus);
+
+/* failed_ddc: */
+
+	drm_encoder_cleanup(encoder);
+	drm_connector_cleanup(connector);
+	kfree(connector);
+}
+
diff -druN linux-2.6.39-libre/drivers/staging/gma500/psb_2d.c linux-3.0-rc7-libre/drivers/staging/gma500/psb_2d.c
--- linux-2.6.39-libre/drivers/staging/gma500/psb_2d.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/gma500/psb_2d.c	2011-07-11 19:51:52.000000000 -0400
@@ -40,7 +40,6 @@
 #include "psb_reg.h"
 #include "psb_drv.h"
 #include "psb_fb.h"
-#include "psb_sgx.h"
 
 void psb_spank(struct drm_psb_private *dev_priv)
 {
@@ -85,7 +84,7 @@
 /* FIXME: Remember if we expose the 2D engine to the DRM we need to serialize
    it with console use */
 
-static int psbfb_2d_submit(struct drm_psb_private *dev_priv, uint32_t *cmdbuf,
+int psbfb_2d_submit(struct drm_psb_private *dev_priv, uint32_t *cmdbuf,
 	 	  	   unsigned size)
 {
 	int ret = 0;
@@ -161,7 +160,7 @@
 	if (!fb)
 		return;
 
-	offset = psbfb->offset;
+	offset = psbfb->gtt->offset;
 	stride = fb->pitch;
 
 	switch (fb->depth) {
@@ -304,7 +303,7 @@
 	if (!fb)
 		return;
 
-	offset = psbfb->offset;
+	offset = psbfb->gtt->offset;
 	stride = fb->pitch;
 
 	switch (fb->depth) {
@@ -344,7 +343,7 @@
 	if (unlikely(info->state != FBINFO_STATE_RUNNING))
 		return;
 
-	if (1 || (info->flags & FBINFO_HWACCEL_DISABLED))
+	if (info->flags & FBINFO_HWACCEL_DISABLED)
 		return cfb_copyarea(info, region);
 
 	/* psb_check_power_state(dev, PSB_DEVICE_SGX); */
diff -druN linux-2.6.39-libre/drivers/staging/gma500/psb_bl.c linux-3.0-rc7-libre/drivers/staging/gma500/psb_bl.c
--- linux-2.6.39-libre/drivers/staging/gma500/psb_bl.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/gma500/psb_bl.c	2011-07-11 19:51:52.000000000 -0400
@@ -33,7 +33,6 @@
 #define BLC_PWM_FREQ_CALC_CONSTANT 32
 #define MHz 1000000
 #define BRIGHTNESS_MIN_LEVEL 1
-#define BRIGHTNESS_MAX_LEVEL 100
 #define BRIGHTNESS_MASK	0xFF
 #define BLC_POLARITY_NORMAL 0
 #define BLC_POLARITY_INVERSE 1
@@ -59,15 +58,57 @@
 
 	DRM_DEBUG_DRIVER("backlight level set to %d\n", level);
 
-	/* Perform value bounds checking */
-	if (level < BRIGHTNESS_MIN_LEVEL)
-		level = BRIGHTNESS_MIN_LEVEL;
+	/* Percentage 1-100% being valid */
+	if (level < 1)
+		level = 1;
 
 	psb_intel_lvds_set_brightness(dev, level);
 	psb_brightness = level;
 	return 0;
 }
 
+int mrst_set_brightness(struct backlight_device *bd)
+{
+	struct drm_device *dev = bl_get_data(psb_backlight_device);
+	struct drm_psb_private *dev_priv = dev->dev_private;
+	int level = bd->props.brightness;
+	u32 blc_pwm_ctl;
+	u32 max_pwm_blc;
+
+	DRM_DEBUG_DRIVER("backlight level set to %d\n", level);
+
+	/* Percentage 1-100% being valid */
+	if (level < 1)
+		level = 1;
+
+	if (gma_power_begin(dev, 0)) {
+		/* Calculate and set the brightness value */
+		max_pwm_blc = REG_READ(BLC_PWM_CTL) >> 16;
+		blc_pwm_ctl = level * max_pwm_blc / 100;
+
+		/* Adjust the backlight level with the percent in
+		 * dev_priv->blc_adj1;
+		 */
+		blc_pwm_ctl = blc_pwm_ctl * dev_priv->blc_adj1;
+		blc_pwm_ctl = blc_pwm_ctl / 100;
+
+		/* Adjust the backlight level with the percent in
+		 * dev_priv->blc_adj2;
+		 */
+		blc_pwm_ctl = blc_pwm_ctl * dev_priv->blc_adj2;
+		blc_pwm_ctl = blc_pwm_ctl / 100;
+
+		if (blc_pol == BLC_POLARITY_INVERSE)
+			blc_pwm_ctl = max_pwm_blc - blc_pwm_ctl;
+		/* force PWM bit on */
+		REG_WRITE(BLC_PWM_CTL2, (0x80000000 | REG_READ(BLC_PWM_CTL2)));
+		REG_WRITE(BLC_PWM_CTL, (max_pwm_blc << 16) | blc_pwm_ctl);
+		gma_power_end(dev);
+	}
+	psb_brightness = level;
+	return 0;
+}
+
 int psb_get_brightness(struct backlight_device *bd)
 {
 	DRM_DEBUG_DRIVER("brightness = 0x%x\n", psb_brightness);
@@ -85,24 +126,33 @@
 
 static int device_backlight_init(struct drm_device *dev)
 {
+	struct drm_psb_private *dev_priv = dev->dev_private;
 	unsigned long core_clock;
 	/* u32 bl_max_freq; */
 	/* unsigned long value; */
 	u16 bl_max_freq;
 	uint32_t value;
 	uint32_t blc_pwm_precision_factor;
-	struct drm_psb_private *dev_priv = dev->dev_private;
 
-	/* get bl_max_freq and pol from dev_priv*/
-	if (!dev_priv->lvds_bl) {
-		DRM_ERROR("Has no valid LVDS backlight info\n");
-		return 1;
+	if (IS_MRST(dev)) {
+		dev_priv->blc_adj1 = BLC_ADJUSTMENT_MAX;
+		dev_priv->blc_adj2 = BLC_ADJUSTMENT_MAX;
+		bl_max_freq = 256;
+		/* this needs to be set elsewhere */
+		blc_pol = BLC_POLARITY_NORMAL;
+		blc_pwm_precision_factor = BLC_PWM_PRECISION_FACTOR;
+	} else {
+		/* get bl_max_freq and pol from dev_priv*/
+		if (!dev_priv->lvds_bl) {
+			DRM_ERROR("Has no valid LVDS backlight info\n");
+			return 1;
+		}
+		bl_max_freq = dev_priv->lvds_bl->freq;
+		blc_pol = dev_priv->lvds_bl->pol;
+		blc_pwm_precision_factor = PSB_BLC_PWM_PRECISION_FACTOR;
+		blc_brightnesscmd = dev_priv->lvds_bl->brightnesscmd;
+		blc_type = dev_priv->lvds_bl->type;
 	}
-	bl_max_freq = dev_priv->lvds_bl->freq;
-	blc_pol = dev_priv->lvds_bl->pol;
-	blc_pwm_precision_factor = PSB_BLC_PWM_PRECISION_FACTOR;
-	blc_brightnesscmd = dev_priv->lvds_bl->brightnesscmd;
-	blc_type = dev_priv->lvds_bl->type;
 
 	core_clock = dev_priv->core_freq;
 
@@ -111,20 +161,27 @@
 	value /= bl_max_freq;
 	value /= blc_pwm_precision_factor;
 
-	if (ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND,
-						OSPM_UHB_ONLY_IF_ON)) {
-		/* Check: may be MFLD only */
-		if (
-		 value > (unsigned long long)PSB_BLC_MAX_PWM_REG_FREQ ||
-		 value < (unsigned long long)PSB_BLC_MIN_PWM_REG_FREQ)
-			return 2;
-		else {
-			value &= PSB_BACKLIGHT_PWM_POLARITY_BIT_CLEAR;
-			REG_WRITE(BLC_PWM_CTL,
-				(value << PSB_BACKLIGHT_PWM_CTL_SHIFT) |
-				(value));
+	if (gma_power_begin(dev, false)) {
+		if (IS_MRST(dev)) {
+			if (value > (unsigned long long)MRST_BLC_MAX_PWM_REG_FREQ)
+				return 2;
+			else {
+				REG_WRITE(BLC_PWM_CTL2,
+					(0x80000000 | REG_READ(BLC_PWM_CTL2)));
+				REG_WRITE(BLC_PWM_CTL, value | (value << 16));
+			}
+		} else {
+			if (value > (unsigned long long)PSB_BLC_MAX_PWM_REG_FREQ ||
+			 value < (unsigned long long)PSB_BLC_MIN_PWM_REG_FREQ)
+				return 2;
+			else {
+				value &= PSB_BACKLIGHT_PWM_POLARITY_BIT_CLEAR;
+				REG_WRITE(BLC_PWM_CTL,
+					(value << PSB_BACKLIGHT_PWM_CTL_SHIFT) |
+					(value));
+			}
 		}
-		ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
+		gma_power_end(dev);
 	}
 	return 0;
 }
@@ -136,7 +193,8 @@
 
 	struct backlight_properties props;
 	memset(&props, 0, sizeof(struct backlight_properties));
-	props.max_brightness = BRIGHTNESS_MAX_LEVEL;
+	props.max_brightness = 100;
+	props.type = BACKLIGHT_PLATFORM;
 
 	psb_backlight_device = backlight_device_register("psb-bl", NULL,
 						(void *)dev, &psb_ops, &props);
@@ -147,8 +205,8 @@
 	if (ret < 0)
 		return ret;
 
-	psb_backlight_device->props.brightness = BRIGHTNESS_MAX_LEVEL;
-	psb_backlight_device->props.max_brightness = BRIGHTNESS_MAX_LEVEL;
+	psb_backlight_device->props.brightness = 100;
+	psb_backlight_device->props.max_brightness = 100;
 	backlight_update_status(psb_backlight_device);
 #endif
 	return 0;
diff -druN linux-2.6.39-libre/drivers/staging/gma500/psb_buffer.c linux-3.0-rc7-libre/drivers/staging/gma500/psb_buffer.c
--- linux-2.6.39-libre/drivers/staging/gma500/psb_buffer.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/gma500/psb_buffer.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,450 +0,0 @@
-/**************************************************************************
- * Copyright (c) 2007, 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.
- *
- **************************************************************************/
-/*
- * Authors: Thomas Hellstrom <thomas-at-tungstengraphics.com>
- */
-#include "ttm/ttm_placement.h"
-#include "ttm/ttm_execbuf_util.h"
-#include "psb_ttm_fence_api.h"
-#include <drm/drmP.h>
-#include "psb_drv.h"
-
-#define DRM_MEM_TTM       26
-
-struct drm_psb_ttm_backend {
-	struct ttm_backend base;
-	struct page **pages;
-	unsigned int desired_tile_stride;
-	unsigned int hw_tile_stride;
-	int mem_type;
-	unsigned long offset;
-	unsigned long num_pages;
-};
-
-/*
- * MSVDX/TOPAZ GPU virtual space looks like this
- * (We currently use only one MMU context).
- * PSB_MEM_MMU_START: from 0x00000000~0xe000000, for generic buffers
- * TTM_PL_CI: from 0xe0000000+half GTT space, for camear/video buffer sharing
- * TTM_PL_RAR: from TTM_PL_CI+CI size, for RAR/video buffer sharing
- * TTM_PL_TT: from TTM_PL_RAR+RAR size, for buffers need to mapping into GTT
- */
-static int psb_init_mem_type(struct ttm_bo_device *bdev, uint32_t type,
-			     struct ttm_mem_type_manager *man)
-{
-
-	struct drm_psb_private *dev_priv =
-	    container_of(bdev, struct drm_psb_private, bdev);
-	struct psb_gtt *pg = dev_priv->pg;
-
-	switch (type) {
-	case TTM_PL_SYSTEM:
-		man->flags = TTM_MEMTYPE_FLAG_MAPPABLE;
-		man->available_caching = TTM_PL_FLAG_CACHED |
-		    TTM_PL_FLAG_UNCACHED | TTM_PL_FLAG_WC;
-		man->default_caching = TTM_PL_FLAG_CACHED;
-		break;
-	case DRM_PSB_MEM_MMU:
-		man->func = &ttm_bo_manager_func;
-		man->flags = TTM_MEMTYPE_FLAG_MAPPABLE |
-		    TTM_MEMTYPE_FLAG_CMA;
-		man->gpu_offset = PSB_MEM_MMU_START;
-		man->available_caching = TTM_PL_FLAG_CACHED |
-		    TTM_PL_FLAG_UNCACHED | TTM_PL_FLAG_WC;
-		man->default_caching = TTM_PL_FLAG_WC;
-		break;
-	case TTM_PL_CI:
-		man->func = &ttm_bo_manager_func;
-		man->flags = TTM_MEMTYPE_FLAG_MAPPABLE |
-			TTM_MEMTYPE_FLAG_FIXED;
-		man->gpu_offset = pg->mmu_gatt_start + (pg->ci_start);
-		man->available_caching = TTM_PL_FLAG_UNCACHED;
-		man->default_caching = TTM_PL_FLAG_UNCACHED;
-		break;
-	case TTM_PL_RAR:	/* Unmappable RAR memory */
-		man->func = &ttm_bo_manager_func;
-		man->flags = TTM_MEMTYPE_FLAG_MAPPABLE |
-			TTM_MEMTYPE_FLAG_FIXED;
-		man->available_caching = TTM_PL_FLAG_UNCACHED;
-		man->default_caching = TTM_PL_FLAG_UNCACHED;
-		man->gpu_offset = pg->mmu_gatt_start + (pg->rar_start);
-		break;
-	case TTM_PL_TT:	/* Mappable GATT memory */
-		man->func = &ttm_bo_manager_func;
-#ifdef PSB_WORKING_HOST_MMU_ACCESS
-		man->flags = TTM_MEMTYPE_FLAG_MAPPABLE;
-#else
-		man->flags = TTM_MEMTYPE_FLAG_MAPPABLE |
-		    TTM_MEMTYPE_FLAG_CMA;
-#endif
-		man->available_caching = TTM_PL_FLAG_CACHED |
-		    TTM_PL_FLAG_UNCACHED | TTM_PL_FLAG_WC;
-		man->default_caching = TTM_PL_FLAG_WC;
-		man->gpu_offset = pg->mmu_gatt_start +
-				(pg->rar_start + dev_priv->rar_region_size);
-		break;
-	default:
-		DRM_ERROR("Unsupported memory type %u\n", (unsigned) type);
-		return -EINVAL;
-	}
-	return 0;
-}
-
-
-static void psb_evict_mask(struct ttm_buffer_object *bo,
-					struct ttm_placement *placement)
-{
-	static uint32_t cur_placement;
-
-	cur_placement = bo->mem.placement & ~TTM_PL_MASK_MEM;
-	cur_placement |= TTM_PL_FLAG_SYSTEM;
-
-	placement->fpfn = 0;
-	placement->lpfn = 0;
-	placement->num_placement = 1;
-	placement->placement = &cur_placement;
-	placement->num_busy_placement = 0;
-	placement->busy_placement = NULL;
-
-	/* all buffers evicted to system memory */
-	/* return cur_placement | TTM_PL_FLAG_SYSTEM; */
-}
-
-static int psb_invalidate_caches(struct ttm_bo_device *bdev,
-				 uint32_t placement)
-{
-	return 0;
-}
-
-static int psb_move_blit(struct ttm_buffer_object *bo,
-			 bool evict, bool no_wait,
-			 struct ttm_mem_reg *new_mem)
-{
-	BUG();
-	return 0;
-}
-
-/*
- * Flip destination ttm into GATT,
- * then blit and subsequently move out again.
- */
-
-static int psb_move_flip(struct ttm_buffer_object *bo,
-			 bool evict, bool interruptible, bool no_wait,
-			 struct ttm_mem_reg *new_mem)
-{
-	/*struct ttm_bo_device *bdev = bo->bdev;*/
-	struct ttm_mem_reg tmp_mem;
-	int ret;
-	struct ttm_placement placement;
-	uint32_t flags = TTM_PL_FLAG_TT;
-
-	tmp_mem = *new_mem;
-	tmp_mem.mm_node = NULL;
-
-	placement.fpfn = 0;
-	placement.lpfn = 0;
-	placement.num_placement = 1;
-	placement.placement = &flags;
-	placement.num_busy_placement = 0; /* FIXME */
-	placement.busy_placement = NULL;
-
-	ret = ttm_bo_mem_space(bo, &placement, &tmp_mem, interruptible,
-							false, no_wait);
-	if (ret)
-		return ret;
-	ret = ttm_tt_bind(bo->ttm, &tmp_mem);
-	if (ret)
-		goto out_cleanup;
-	ret = psb_move_blit(bo, true, no_wait, &tmp_mem);
-	if (ret)
-		goto out_cleanup;
-
-	ret = ttm_bo_move_ttm(bo, evict, false, no_wait, new_mem);
-out_cleanup:
-	if (tmp_mem.mm_node) {
-		drm_mm_put_block(tmp_mem.mm_node);
-		tmp_mem.mm_node = NULL;
-	}
-	return ret;
-}
-
-static int psb_move(struct ttm_buffer_object *bo,
-		    bool evict, bool interruptible, bool no_wait_reserve,
-		    bool no_wait, struct ttm_mem_reg *new_mem)
-{
-	struct ttm_mem_reg *old_mem = &bo->mem;
-
-	if ((old_mem->mem_type == TTM_PL_RAR) ||
-	    (new_mem->mem_type == TTM_PL_RAR)) {
-		if (old_mem->mm_node) {
-			spin_lock(&bo->glob->lru_lock);
-			drm_mm_put_block(old_mem->mm_node);
-			spin_unlock(&bo->glob->lru_lock);
-		}
-		old_mem->mm_node = NULL;
-		*old_mem = *new_mem;
-	} else if (old_mem->mem_type == TTM_PL_SYSTEM) {
-		return ttm_bo_move_memcpy(bo, evict, false, no_wait, new_mem);
-	} else if (new_mem->mem_type == TTM_PL_SYSTEM) {
-		int ret = psb_move_flip(bo, evict, interruptible,
-					no_wait, new_mem);
-		if (unlikely(ret != 0)) {
-			if (ret == -ERESTART)
-				return ret;
-			else
-				return ttm_bo_move_memcpy(bo, evict, false,
-						no_wait, new_mem);
-		}
-	} else {
-		if (psb_move_blit(bo, evict, no_wait, new_mem))
-			return ttm_bo_move_memcpy(bo, evict, false, no_wait,
-						  new_mem);
-	}
-	return 0;
-}
-
-static int drm_psb_tbe_populate(struct ttm_backend *backend,
-				unsigned long num_pages,
-				struct page **pages,
-				struct page *dummy_read_page,
-				dma_addr_t *dma_addrs)
-{
-	struct drm_psb_ttm_backend *psb_be =
-	    container_of(backend, struct drm_psb_ttm_backend, base);
-
-	psb_be->pages = pages;
-	return 0;
-}
-
-static int drm_psb_tbe_unbind(struct ttm_backend *backend)
-{
-	struct ttm_bo_device *bdev = backend->bdev;
-	struct drm_psb_private *dev_priv =
-	    container_of(bdev, struct drm_psb_private, bdev);
-	struct drm_psb_ttm_backend *psb_be =
-	    container_of(backend, struct drm_psb_ttm_backend, base);
-	struct psb_mmu_pd *pd = psb_mmu_get_default_pd(dev_priv->mmu);
-	/* struct ttm_mem_type_manager *man = &bdev->man[psb_be->mem_type]; */
-
-	if (psb_be->mem_type == TTM_PL_TT) {
-		uint32_t gatt_p_offset =
-			(psb_be->offset - dev_priv->pg->mmu_gatt_start)
-								>> PAGE_SHIFT;
-
-		(void) psb_gtt_remove_pages(dev_priv->pg, gatt_p_offset,
-					    psb_be->num_pages,
-					    psb_be->desired_tile_stride,
-					    psb_be->hw_tile_stride, 0);
-	}
-
-	psb_mmu_remove_pages(pd, psb_be->offset,
-			     psb_be->num_pages,
-			     psb_be->desired_tile_stride,
-			     psb_be->hw_tile_stride);
-
-	return 0;
-}
-
-static int drm_psb_tbe_bind(struct ttm_backend *backend,
-			    struct ttm_mem_reg *bo_mem)
-{
-	struct ttm_bo_device *bdev = backend->bdev;
-	struct drm_psb_private *dev_priv =
-	    container_of(bdev, struct drm_psb_private, bdev);
-	struct drm_psb_ttm_backend *psb_be =
-	    container_of(backend, struct drm_psb_ttm_backend, base);
-	struct psb_mmu_pd *pd = psb_mmu_get_default_pd(dev_priv->mmu);
-	struct ttm_mem_type_manager *man = &bdev->man[bo_mem->mem_type];
-	struct drm_mm_node *mm_node = bo_mem->mm_node;
-	int type;
-	int ret = 0;
-
-	psb_be->mem_type = bo_mem->mem_type;
-	psb_be->num_pages = bo_mem->num_pages;
-	psb_be->desired_tile_stride = 0;
-	psb_be->hw_tile_stride = 0;
-	psb_be->offset = (mm_node->start << PAGE_SHIFT) +
-	    man->gpu_offset;
-
-	type =
-	    (bo_mem->
-	     placement & TTM_PL_FLAG_CACHED) ? PSB_MMU_CACHED_MEMORY : 0;
-
-	if (psb_be->mem_type == TTM_PL_TT) {
-		uint32_t gatt_p_offset =
-				(psb_be->offset - dev_priv->pg->mmu_gatt_start)
-								>> PAGE_SHIFT;
-
-		ret = psb_gtt_insert_pages(dev_priv->pg, psb_be->pages,
-					   gatt_p_offset,
-					   psb_be->num_pages,
-					   psb_be->desired_tile_stride,
-					   psb_be->hw_tile_stride, type);
-	}
-
-	ret = psb_mmu_insert_pages(pd, psb_be->pages,
-				   psb_be->offset, psb_be->num_pages,
-				   psb_be->desired_tile_stride,
-				   psb_be->hw_tile_stride, type);
-	if (ret)
-		goto out_err;
-
-	return 0;
-out_err:
-	drm_psb_tbe_unbind(backend);
-	return ret;
-
-}
-
-static void drm_psb_tbe_clear(struct ttm_backend *backend)
-{
-	struct drm_psb_ttm_backend *psb_be =
-	    container_of(backend, struct drm_psb_ttm_backend, base);
-
-	psb_be->pages = NULL;
-	return;
-}
-
-static void drm_psb_tbe_destroy(struct ttm_backend *backend)
-{
-	struct drm_psb_ttm_backend *psb_be =
-	    container_of(backend, struct drm_psb_ttm_backend, base);
-
-	if (backend)
-		kfree(psb_be);
-}
-
-static struct ttm_backend_func psb_ttm_backend = {
-	.populate = drm_psb_tbe_populate,
-	.clear = drm_psb_tbe_clear,
-	.bind = drm_psb_tbe_bind,
-	.unbind = drm_psb_tbe_unbind,
-	.destroy = drm_psb_tbe_destroy,
-};
-
-static struct ttm_backend *drm_psb_tbe_init(struct ttm_bo_device *bdev)
-{
-	struct drm_psb_ttm_backend *psb_be;
-
-	psb_be = kzalloc(sizeof(*psb_be), GFP_KERNEL);
-	if (!psb_be)
-		return NULL;
-	psb_be->pages = NULL;
-	psb_be->base.func = &psb_ttm_backend;
-	psb_be->base.bdev = bdev;
-	return &psb_be->base;
-}
-
-static int psb_ttm_io_mem_reserve(struct ttm_bo_device *bdev,
-						struct ttm_mem_reg *mem)
-{
-	struct ttm_mem_type_manager *man = &bdev->man[mem->mem_type];
-	struct drm_psb_private *dev_priv =
-	    container_of(bdev, struct drm_psb_private, bdev);
-	struct psb_gtt *pg = dev_priv->pg;
-	struct drm_mm_node *mm_node = mem->mm_node;
-
-	mem->bus.addr = NULL;
-	mem->bus.offset = 0;
-	mem->bus.size = mem->num_pages << PAGE_SHIFT;
-	mem->bus.base = 0;
-	mem->bus.is_iomem = false;
-	if (!(man->flags & TTM_MEMTYPE_FLAG_MAPPABLE))
-		return -EINVAL;
-	switch (mem->mem_type) {
-	case TTM_PL_SYSTEM:
-		/* system memory */
-		return 0;
-	case TTM_PL_TT:
-		mem->bus.offset = mm_node->start << PAGE_SHIFT;
-		mem->bus.base = pg->gatt_start;
-		mem->bus.is_iomem = false;
-		/* Don't know whether it is IO_MEM, this flag
-						used in vm_fault handle */
-		break;
-	case DRM_PSB_MEM_MMU:
-		mem->bus.offset = mm_node->start << PAGE_SHIFT;
-		mem->bus.base = 0x00000000;
-		break;
-	case TTM_PL_CI:
-		mem->bus.offset = mm_node->start << PAGE_SHIFT;
-		mem->bus.base = dev_priv->ci_region_start;;
-		mem->bus.is_iomem = true;
-		break;
-	case TTM_PL_RAR:
-		mem->bus.offset = mm_node->start << PAGE_SHIFT;
-		mem->bus.base = dev_priv->rar_region_start;;
-		mem->bus.is_iomem = true;
-		break;
-	default:
-		return -EINVAL;
-	}
-	return 0;
-}
-
-static void psb_ttm_io_mem_free(struct ttm_bo_device *bdev,
-						struct ttm_mem_reg *mem)
-{
-}
-
-/*
- * Use this memory type priority if no eviction is needed.
- */
-/*
-static uint32_t psb_mem_prios[] = {
-	TTM_PL_CI,
-	TTM_PL_RAR,
-	TTM_PL_TT,
-	DRM_PSB_MEM_MMU,
-	TTM_PL_SYSTEM
-};
-*/
-/*
- * Use this memory type priority if need to evict.
- */
-/*
-static uint32_t psb_busy_prios[] = {
-	TTM_PL_TT,
-	TTM_PL_CI,
-	TTM_PL_RAR,
-	DRM_PSB_MEM_MMU,
-	TTM_PL_SYSTEM
-};
-*/
-struct ttm_bo_driver psb_ttm_bo_driver = {
-/*
-	.mem_type_prio = psb_mem_prios,
-	.mem_busy_prio = psb_busy_prios,
-	.num_mem_type_prio = ARRAY_SIZE(psb_mem_prios),
-	.num_mem_busy_prio = ARRAY_SIZE(psb_busy_prios),
-*/
-	.create_ttm_backend_entry = &drm_psb_tbe_init,
-	.invalidate_caches = &psb_invalidate_caches,
-	.init_mem_type = &psb_init_mem_type,
-	.evict_flags = &psb_evict_mask,
-	.move = &psb_move,
-	.verify_access = &psb_verify_access,
-	.sync_obj_signaled = &ttm_fence_sync_obj_signaled,
-	.sync_obj_wait = &ttm_fence_sync_obj_wait,
-	.sync_obj_flush = &ttm_fence_sync_obj_flush,
-	.sync_obj_unref = &ttm_fence_sync_obj_unref,
-	.sync_obj_ref = &ttm_fence_sync_obj_ref,
-	.io_mem_reserve = &psb_ttm_io_mem_reserve,
-	.io_mem_free = &psb_ttm_io_mem_free
-};
diff -druN linux-2.6.39-libre/drivers/staging/gma500/psb_drm.h linux-3.0-rc7-libre/drivers/staging/gma500/psb_drm.h
--- linux-2.6.39-libre/drivers/staging/gma500/psb_drm.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/gma500/psb_drm.h	2011-07-11 19:51:52.000000000 -0400
@@ -28,9 +28,6 @@
 #include "drm_mode.h"
 #endif
 
-#include "psb_ttm_fence_user.h"
-#include "psb_ttm_placement_user.h"
-
 #define DRM_PSB_SAREA_MAJOR 0
 #define DRM_PSB_SAREA_MINOR 2
 #define PSB_FIXED_SHIFT 16
@@ -41,15 +38,6 @@
  * Public memory types.
  */
 
-#define DRM_PSB_MEM_MMU 	TTM_PL_PRIV1
-#define DRM_PSB_FLAG_MEM_MMU	TTM_PL_FLAG_PRIV1
-
-#define TTM_PL_CI               TTM_PL_PRIV0
-#define TTM_PL_FLAG_CI          TTM_PL_FLAG_PRIV0
-
-#define TTM_PL_RAR              TTM_PL_PRIV2
-#define TTM_PL_FLAG_RAR         TTM_PL_FLAG_PRIV2
-
 typedef s32 psb_fixed;
 typedef u32 psb_ufixed;
 
@@ -112,111 +100,12 @@
 	u32 num_active_scanouts;
 };
 
-#define PSB_RELOC_MAGIC         0x67676767
-#define PSB_RELOC_SHIFT_MASK    0x0000FFFF
-#define PSB_RELOC_SHIFT_SHIFT   0
-#define PSB_RELOC_ALSHIFT_MASK  0xFFFF0000
-#define PSB_RELOC_ALSHIFT_SHIFT 16
-
-#define PSB_RELOC_OP_OFFSET     0	/* Offset of the indicated
-					 * buffer
-					 */
-
-struct drm_psb_reloc {
-	u32 reloc_op;
-	u32 where;		/* offset in destination buffer */
-	u32 buffer;	/* Buffer reloc applies to */
-	u32 mask;		/* Destination format: */
-	u32 shift;		/* Destination format: */
-	u32 pre_add;	/* Destination format: */
-	u32 background;	/* Destination add */
-	u32 dst_buffer;	/* Destination buffer. Index into buffer_list */
-	u32 arg0;		/* Reloc-op dependent */
-	u32 arg1;
-};
-
-
 #define PSB_GPU_ACCESS_READ         (1ULL << 32)
 #define PSB_GPU_ACCESS_WRITE        (1ULL << 33)
 #define PSB_GPU_ACCESS_MASK         (PSB_GPU_ACCESS_READ | PSB_GPU_ACCESS_WRITE)
 
 #define PSB_BO_FLAG_COMMAND         (1ULL << 52)
 
-#define PSB_ENGINE_2D 0
-#define PSB_ENGINE_VIDEO 1
-#define LNC_ENGINE_ENCODE 5
-
-/*
- * For this fence class we have a couple of
- * fence types.
- */
-
-#define _PSB_FENCE_EXE_SHIFT           0
-#define _PSB_FENCE_FEEDBACK_SHIFT      4
-
-#define _PSB_FENCE_TYPE_EXE         (1 << _PSB_FENCE_EXE_SHIFT)
-#define _PSB_FENCE_TYPE_FEEDBACK    (1 << _PSB_FENCE_FEEDBACK_SHIFT)
-
-#define PSB_NUM_ENGINES 6
-
-
-#define PSB_FEEDBACK_OP_VISTEST (1 << 0)
-
-struct drm_psb_extension_rep {
-	s32 exists;
-	u32 driver_ioctl_offset;
-	u32 sarea_offset;
-	u32 major;
-	u32 minor;
-	u32 pl;
-};
-
-#define DRM_PSB_EXT_NAME_LEN 128
-
-union drm_psb_extension_arg {
-	char extension[DRM_PSB_EXT_NAME_LEN];
-	struct drm_psb_extension_rep rep;
-};
-
-struct psb_validate_req {
-	u64 set_flags;
-	u64 clear_flags;
-	u64 next;
-	u64 presumed_gpu_offset;
-	u32 buffer_handle;
-	u32 presumed_flags;
-	u32 group;
-	u32 pad64;
-};
-
-struct psb_validate_rep {
-	u64 gpu_offset;
-	u32 placement;
-	u32 fence_type_mask;
-};
-
-#define PSB_USE_PRESUMED     (1 << 0)
-
-struct psb_validate_arg {
-	int handled;
-	int ret;
-	union {
-		struct psb_validate_req req;
-		struct psb_validate_rep rep;
-	} d;
-};
-
-
-#define DRM_PSB_FENCE_NO_USER        (1 << 0)
-
-struct psb_ttm_fence_rep {
-	u32 handle;
-	u32 fence_class;
-	u32 fence_type;
-	u32 signaled_types;
-	u32 error;
-};
-
 /*
  * Feedback components:
  */
@@ -330,17 +219,6 @@
 	u32 subpicture_disable_mask;
 };
 
-struct psb_gtt_mapping_arg {
-	void *hKernelMemInfo;
-	u32 offset_pages;
-};
-
-struct drm_psb_getpageaddrs_arg {
-	u32 handle;
-	unsigned long *page_addrs;
-	unsigned long gtt_offset;
-};
-
 /* Controlling the kernel modesetting buffers */
 
 #define DRM_PSB_KMS_OFF		0x00
diff -druN linux-2.6.39-libre/drivers/staging/gma500/psb_drv.c linux-3.0-rc7-libre/drivers/staging/gma500/psb_drv.c
--- linux-2.6.39-libre/drivers/staging/gma500/psb_drv.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/gma500/psb_drv.c	2011-07-11 19:51:52.000000000 -0400
@@ -38,30 +38,29 @@
 int drm_psb_debug;
 static int drm_psb_trap_pagefaults;
 
-int drm_psb_disable_vsync = 1;
 int drm_psb_no_fb;
-int gfxrtdelay = 2 * 1000;
 
 static int psb_probe(struct pci_dev *pdev, const struct pci_device_id *ent);
 
 MODULE_PARM_DESC(debug, "Enable debug output");
 MODULE_PARM_DESC(no_fb, "Disable FBdev");
 MODULE_PARM_DESC(trap_pagefaults, "Error and reset on MMU pagefaults");
-MODULE_PARM_DESC(disable_vsync, "Disable vsync interrupts");
-MODULE_PARM_DESC(force_pipeb, "Forces PIPEB to become primary fb");
-MODULE_PARM_DESC(ta_mem_size, "TA memory size in kiB");
-MODULE_PARM_DESC(ospm, "switch for ospm support");
-MODULE_PARM_DESC(rtpm, "Specifies Runtime PM delay for GFX");
-MODULE_PARM_DESC(hdmi_edid, "EDID info for HDMI monitor");
 module_param_named(debug, drm_psb_debug, int, 0600);
 module_param_named(no_fb, drm_psb_no_fb, int, 0600);
 module_param_named(trap_pagefaults, drm_psb_trap_pagefaults, int, 0600);
-module_param_named(rtpm, gfxrtdelay, int, 0600);
 
 
 static struct pci_device_id pciidlist[] = {
 	{ 0x8086, 0x8108, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_PSB_8108 },
 	{ 0x8086, 0x8109, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_PSB_8109 },
+	{ 0x8086, 0x4100, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_MRST_4100},
+	{ 0x8086, 0x4101, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_MRST_4100},
+	{ 0x8086, 0x4102, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_MRST_4100},
+	{ 0x8086, 0x4103, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_MRST_4100},
+	{ 0x8086, 0x4104, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_MRST_4100},
+	{ 0x8086, 0x4105, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_MRST_4100},
+	{ 0x8086, 0x4106, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_MRST_4100},
+	{ 0x8086, 0x4107, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_MRST_4100},
 	{ 0, 0, 0}
 };
 MODULE_DEVICE_TABLE(pci, pciidlist);
@@ -74,10 +73,6 @@
 		DRM_IO(DRM_PSB_KMS_OFF + DRM_COMMAND_BASE)
 #define DRM_IOCTL_PSB_KMS_ON	\
 		DRM_IO(DRM_PSB_KMS_ON + DRM_COMMAND_BASE)
-#define DRM_IOCTL_PSB_VT_LEAVE	\
-		DRM_IO(DRM_PSB_VT_LEAVE + DRM_COMMAND_BASE)
-#define DRM_IOCTL_PSB_VT_ENTER	\
-		DRM_IO(DRM_PSB_VT_ENTER + DRM_COMMAND_BASE)
 #define DRM_IOCTL_PSB_SIZES	\
 		DRM_IOR(DRM_PSB_SIZES + DRM_COMMAND_BASE, \
 			struct drm_psb_sizes_arg)
@@ -97,18 +92,6 @@
 #define DRM_IOCTL_PSB_REGISTER_RW	\
 		DRM_IOWR(DRM_PSB_REGISTER_RW + DRM_COMMAND_BASE, \
 			 struct drm_psb_register_rw_arg)
-#define DRM_IOCTL_PSB_GTT_MAP	\
-		DRM_IOWR(DRM_PSB_GTT_MAP + DRM_COMMAND_BASE, \
-			 struct psb_gtt_mapping_arg)
-#define DRM_IOCTL_PSB_GTT_UNMAP	\
-		DRM_IOW(DRM_PSB_GTT_UNMAP + DRM_COMMAND_BASE, \
-			struct psb_gtt_mapping_arg)
-#define DRM_IOCTL_PSB_GETPAGEADDRS	\
-		DRM_IOWR(DRM_COMMAND_BASE + DRM_PSB_GETPAGEADDRS,\
-			 struct drm_psb_getpageaddrs_arg)
-#define DRM_IOCTL_PSB_UPDATE_GUARD	\
-		DRM_IOWR(DRM_PSB_UPDATE_GUARD + DRM_COMMAND_BASE, \
-			 uint32_t)
 #define DRM_IOCTL_PSB_DPST	\
 		DRM_IOWR(DRM_PSB_DPST + DRM_COMMAND_BASE, \
 			 uint32_t)
@@ -122,74 +105,6 @@
 		DRM_IOWR(DRM_PSB_GET_PIPE_FROM_CRTC_ID + DRM_COMMAND_BASE, \
 			 struct drm_psb_get_pipe_from_crtc_id_arg)
 
-/*
- * TTM execbuf extension.
- */
-
-#define DRM_PSB_CMDBUF		  0x23
-#define DRM_PSB_SCENE_UNREF	  0x24
-#define DRM_IOCTL_PSB_KMS_OFF	  DRM_IO(DRM_PSB_KMS_OFF + DRM_COMMAND_BASE)
-#define DRM_IOCTL_PSB_KMS_ON	  DRM_IO(DRM_PSB_KMS_ON + DRM_COMMAND_BASE)
-/*
- * TTM placement user extension.
- */
-
-#define DRM_PSB_PLACEMENT_OFFSET   (DRM_PSB_SCENE_UNREF + 1)
-
-#define DRM_PSB_TTM_PL_CREATE	 (TTM_PL_CREATE + DRM_PSB_PLACEMENT_OFFSET)
-#define DRM_PSB_TTM_PL_REFERENCE (TTM_PL_REFERENCE + DRM_PSB_PLACEMENT_OFFSET)
-#define DRM_PSB_TTM_PL_UNREF	 (TTM_PL_UNREF + DRM_PSB_PLACEMENT_OFFSET)
-#define DRM_PSB_TTM_PL_SYNCCPU	 (TTM_PL_SYNCCPU + DRM_PSB_PLACEMENT_OFFSET)
-#define DRM_PSB_TTM_PL_WAITIDLE  (TTM_PL_WAITIDLE + DRM_PSB_PLACEMENT_OFFSET)
-#define DRM_PSB_TTM_PL_SETSTATUS (TTM_PL_SETSTATUS + DRM_PSB_PLACEMENT_OFFSET)
-#define DRM_PSB_TTM_PL_CREATE_UB (TTM_PL_CREATE_UB + DRM_PSB_PLACEMENT_OFFSET)
-
-/*
- * TTM fence extension.
- */
-
-#define DRM_PSB_FENCE_OFFSET	   (DRM_PSB_TTM_PL_CREATE_UB + 1)
-#define DRM_PSB_TTM_FENCE_SIGNALED (TTM_FENCE_SIGNALED + DRM_PSB_FENCE_OFFSET)
-#define DRM_PSB_TTM_FENCE_FINISH   (TTM_FENCE_FINISH + DRM_PSB_FENCE_OFFSET)
-#define DRM_PSB_TTM_FENCE_UNREF    (TTM_FENCE_UNREF + DRM_PSB_FENCE_OFFSET)
-
-#define DRM_PSB_FLIP	   (DRM_PSB_TTM_FENCE_UNREF + 1)	/*20*/
-
-#define DRM_IOCTL_PSB_TTM_PL_CREATE    \
-	DRM_IOWR(DRM_COMMAND_BASE + DRM_PSB_TTM_PL_CREATE,\
-		 union ttm_pl_create_arg)
-#define DRM_IOCTL_PSB_TTM_PL_REFERENCE \
-	DRM_IOWR(DRM_COMMAND_BASE + DRM_PSB_TTM_PL_REFERENCE,\
-		 union ttm_pl_reference_arg)
-#define DRM_IOCTL_PSB_TTM_PL_UNREF    \
-	DRM_IOW(DRM_COMMAND_BASE + DRM_PSB_TTM_PL_UNREF,\
-		struct ttm_pl_reference_req)
-#define DRM_IOCTL_PSB_TTM_PL_SYNCCPU	\
-	DRM_IOW(DRM_COMMAND_BASE + DRM_PSB_TTM_PL_SYNCCPU,\
-		struct ttm_pl_synccpu_arg)
-#define DRM_IOCTL_PSB_TTM_PL_WAITIDLE	 \
-	DRM_IOW(DRM_COMMAND_BASE + DRM_PSB_TTM_PL_WAITIDLE,\
-		struct ttm_pl_waitidle_arg)
-#define DRM_IOCTL_PSB_TTM_PL_SETSTATUS \
-	DRM_IOWR(DRM_COMMAND_BASE + DRM_PSB_TTM_PL_SETSTATUS,\
-		 union ttm_pl_setstatus_arg)
-#define DRM_IOCTL_PSB_TTM_PL_CREATE_UB    \
-	DRM_IOWR(DRM_COMMAND_BASE + DRM_PSB_TTM_PL_CREATE_UB,\
-		 union ttm_pl_create_ub_arg)
-#define DRM_IOCTL_PSB_TTM_FENCE_SIGNALED \
-	DRM_IOWR(DRM_COMMAND_BASE + DRM_PSB_TTM_FENCE_SIGNALED,	\
-		  union ttm_fence_signaled_arg)
-#define DRM_IOCTL_PSB_TTM_FENCE_FINISH \
-	DRM_IOWR(DRM_COMMAND_BASE + DRM_PSB_TTM_FENCE_FINISH,	\
-		 union ttm_fence_finish_arg)
-#define DRM_IOCTL_PSB_TTM_FENCE_UNREF \
-	DRM_IOW(DRM_COMMAND_BASE + DRM_PSB_TTM_FENCE_UNREF,	\
-		 struct ttm_fence_unref_arg)
-
-static int psb_vt_leave_ioctl(struct drm_device *dev, void *data,
-			      struct drm_file *file_priv);
-static int psb_vt_enter_ioctl(struct drm_device *dev, void *data,
-			      struct drm_file *file_priv);
 static int psb_sizes_ioctl(struct drm_device *dev, void *data,
 			   struct drm_file *file_priv);
 static int psb_dc_state_ioctl(struct drm_device *dev, void * data,
@@ -218,11 +133,6 @@
 	PSB_IOCTL_DEF(DRM_IOCTL_PSB_KMS_ON,
 			psbfb_kms_on_ioctl,
 			DRM_ROOT_ONLY),
-	PSB_IOCTL_DEF(DRM_IOCTL_PSB_VT_LEAVE, psb_vt_leave_ioctl,
-		      DRM_ROOT_ONLY),
-	PSB_IOCTL_DEF(DRM_IOCTL_PSB_VT_ENTER,
-			psb_vt_enter_ioctl,
-			DRM_ROOT_ONLY),
 	PSB_IOCTL_DEF(DRM_IOCTL_PSB_SIZES, psb_sizes_ioctl, DRM_AUTH),
 	PSB_IOCTL_DEF(DRM_IOCTL_PSB_DC_STATE, psb_dc_state_ioctl, DRM_AUTH),
 	PSB_IOCTL_DEF(DRM_IOCTL_PSB_ADB, psb_adb_ioctl, DRM_AUTH),
@@ -232,92 +142,226 @@
 		      DRM_AUTH),
 	PSB_IOCTL_DEF(DRM_IOCTL_PSB_REGISTER_RW, psb_register_rw_ioctl,
 		      DRM_AUTH),
-	PSB_IOCTL_DEF(DRM_IOCTL_PSB_GTT_MAP,
-			psb_gtt_map_meminfo_ioctl,
-			DRM_AUTH),
-	PSB_IOCTL_DEF(DRM_IOCTL_PSB_GTT_UNMAP,
-			psb_gtt_unmap_meminfo_ioctl,
-			DRM_AUTH),
-	PSB_IOCTL_DEF(DRM_IOCTL_PSB_GETPAGEADDRS,
-			psb_getpageaddrs_ioctl,
-			DRM_AUTH),
 	PSB_IOCTL_DEF(DRM_IOCTL_PSB_DPST, psb_dpst_ioctl, DRM_AUTH),
 	PSB_IOCTL_DEF(DRM_IOCTL_PSB_GAMMA, psb_gamma_ioctl, DRM_AUTH),
 	PSB_IOCTL_DEF(DRM_IOCTL_PSB_DPST_BL, psb_dpst_bl_ioctl, DRM_AUTH),
 	PSB_IOCTL_DEF(DRM_IOCTL_PSB_GET_PIPE_FROM_CRTC_ID,
 					psb_intel_get_pipe_from_crtc_id, 0),
 
-	PSB_IOCTL_DEF(DRM_IOCTL_PSB_TTM_PL_CREATE, psb_pl_create_ioctl,
-		      DRM_AUTH),
-	PSB_IOCTL_DEF(DRM_IOCTL_PSB_TTM_PL_REFERENCE, psb_pl_reference_ioctl,
-		      DRM_AUTH),
-	PSB_IOCTL_DEF(DRM_IOCTL_PSB_TTM_PL_UNREF, psb_pl_unref_ioctl,
-		      DRM_AUTH),
-	PSB_IOCTL_DEF(DRM_IOCTL_PSB_TTM_PL_SYNCCPU, psb_pl_synccpu_ioctl,
-		      DRM_AUTH),
-	PSB_IOCTL_DEF(DRM_IOCTL_PSB_TTM_PL_WAITIDLE, psb_pl_waitidle_ioctl,
-		      DRM_AUTH),
-	PSB_IOCTL_DEF(DRM_IOCTL_PSB_TTM_PL_SETSTATUS, psb_pl_setstatus_ioctl,
-		      DRM_AUTH),
-	PSB_IOCTL_DEF(DRM_IOCTL_PSB_TTM_PL_CREATE_UB, psb_pl_ub_create_ioctl,
-		      DRM_AUTH),
-	PSB_IOCTL_DEF(DRM_IOCTL_PSB_TTM_FENCE_SIGNALED,
-		      psb_fence_signaled_ioctl, DRM_AUTH),
-	PSB_IOCTL_DEF(DRM_IOCTL_PSB_TTM_FENCE_FINISH, psb_fence_finish_ioctl,
-		      DRM_AUTH),
-	PSB_IOCTL_DEF(DRM_IOCTL_PSB_TTM_FENCE_UNREF, psb_fence_unref_ioctl,
-		      DRM_AUTH),
 };
 
-static void psb_set_uopt(struct drm_psb_uopt *uopt)
+static void psb_lastclose(struct drm_device *dev)
 {
 	return;
 }
 
-static void psb_lastclose(struct drm_device *dev)
+static void psb_do_takedown(struct drm_device *dev)
 {
-	struct drm_psb_private *dev_priv =
-	    (struct drm_psb_private *) dev->dev_private;
+	/* FIXME: do we need to clean up the gtt here ? */
+}
 
-	return;
+void mrst_get_fuse_settings(struct drm_device *dev)
+{
+	struct drm_psb_private *dev_priv = dev->dev_private;
+	struct pci_dev *pci_root = pci_get_bus_and_slot(0, 0);
+	uint32_t fuse_value = 0;
+	uint32_t fuse_value_tmp = 0;
 
-	if (!dev->dev_private)
-		return;
+#define FB_REG06 0xD0810600
+#define FB_MIPI_DISABLE  (1 << 11)
+#define FB_REG09 0xD0810900
+#define FB_REG09 0xD0810900
+#define FB_SKU_MASK  0x7000
+#define FB_SKU_SHIFT 12
+#define FB_SKU_100 0
+#define FB_SKU_100L 1
+#define FB_SKU_83 2
+	pci_write_config_dword(pci_root, 0xD0, FB_REG06);
+	pci_read_config_dword(pci_root, 0xD4, &fuse_value);
 
-	mutex_lock(&dev_priv->cmdbuf_mutex);
-	if (dev_priv->context.buffers) {
-		vfree(dev_priv->context.buffers);
-		dev_priv->context.buffers = NULL;
+	dev_priv->iLVDS_enable = fuse_value & FB_MIPI_DISABLE;
+
+	DRM_INFO("internal display is %s\n",
+		 dev_priv->iLVDS_enable ? "LVDS display" : "MIPI display");
+
+	 /*prevent Runtime suspend at start*/
+	 if (dev_priv->iLVDS_enable) {
+		dev_priv->is_lvds_on = true;
+		dev_priv->is_mipi_on = false;
 	}
-	mutex_unlock(&dev_priv->cmdbuf_mutex);
+	else {
+		dev_priv->is_mipi_on = true;
+		dev_priv->is_lvds_on = false;
+	}
+
+	dev_priv->video_device_fuse = fuse_value;
+
+	pci_write_config_dword(pci_root, 0xD0, FB_REG09);
+	pci_read_config_dword(pci_root, 0xD4, &fuse_value);
+
+	DRM_INFO("SKU values is 0x%x. \n", fuse_value);
+	fuse_value_tmp = (fuse_value & FB_SKU_MASK) >> FB_SKU_SHIFT;
+
+	dev_priv->fuse_reg_value = fuse_value;
+
+	switch (fuse_value_tmp) {
+	case FB_SKU_100:
+		dev_priv->core_freq = 200;
+		break;
+	case FB_SKU_100L:
+		dev_priv->core_freq = 100;
+		break;
+	case FB_SKU_83:
+		dev_priv->core_freq = 166;
+		break;
+	default:
+		DRM_ERROR("Invalid SKU values, SKU value = 0x%08x\n", fuse_value_tmp);
+		dev_priv->core_freq = 0;
+	}
+	DRM_INFO("LNC core clk is %dMHz.\n", dev_priv->core_freq);
+	pci_dev_put(pci_root);
 }
 
-static void psb_do_takedown(struct drm_device *dev)
+void mid_get_pci_revID (struct drm_psb_private *dev_priv)
 {
-	struct drm_psb_private *dev_priv =
-	    (struct drm_psb_private *) dev->dev_private;
-	struct ttm_bo_device *bdev = &dev_priv->bdev;
+	uint32_t platform_rev_id = 0;
+	struct pci_dev *pci_gfx_root = pci_get_bus_and_slot(0, PCI_DEVFN(2, 0));
 
+	/*get the revison ID, B0:D2:F0;0x08 */
+	pci_read_config_dword(pci_gfx_root, 0x08, &platform_rev_id);
+	dev_priv->platform_rev_id = (uint8_t) platform_rev_id;
+	pci_dev_put(pci_gfx_root);
+	PSB_DEBUG_ENTRY("platform_rev_id is %x\n",	dev_priv->platform_rev_id);
+}
 
-	if (dev_priv->have_mem_mmu) {
-		ttm_bo_clean_mm(bdev, DRM_PSB_MEM_MMU);
-		dev_priv->have_mem_mmu = 0;
-	}
+void mrst_get_vbt_data(struct drm_psb_private *dev_priv)
+{
+	struct mrst_vbt *vbt = &dev_priv->vbt_data;
+	u32 platform_config_address;
+	u16 new_size;
+	u8 *vbt_virtual;
+	u8 bpi;
+	u8 number_desc = 0;
+	struct mrst_timing_info *dp_ti = &dev_priv->gct_data.DTD;
+	struct gct_r10_timing_info ti;
+	void *pGCT;
+	struct pci_dev *pci_gfx_root = pci_get_bus_and_slot(0, PCI_DEVFN(2, 0));
 
-	if (dev_priv->have_tt) {
-		ttm_bo_clean_mm(bdev, TTM_PL_TT);
-		dev_priv->have_tt = 0;
-	}
+	/*get the address of the platform config vbt, B0:D2:F0;0xFC */
+	pci_read_config_dword(pci_gfx_root, 0xFC, &platform_config_address);
+	pci_dev_put(pci_gfx_root);
+	DRM_INFO("drm platform config address is %x\n",
+			platform_config_address);
 
-	if (dev_priv->have_camera) {
-		ttm_bo_clean_mm(bdev, TTM_PL_CI);
-		dev_priv->have_camera = 0;
-	}
-	if (dev_priv->have_rar) {
-		ttm_bo_clean_mm(bdev, TTM_PL_RAR);
-		dev_priv->have_rar = 0;
+	/* check for platform config address == 0. */
+	/* this means fw doesn't support vbt */
+
+	if (platform_config_address == 0) {
+		vbt->size = 0;
+		return;
 	}
 
+	/* get the virtual address of the vbt */
+	vbt_virtual = ioremap(platform_config_address, sizeof(*vbt));
+
+	memcpy(vbt, vbt_virtual, sizeof(*vbt));
+	iounmap(vbt_virtual); /* Free virtual address space */
+
+	printk(KERN_ALERT "GCT revision is %x\n", vbt->revision);
+
+	switch (vbt->revision) {
+	case 0:
+		vbt->mrst_gct = NULL;
+		vbt->mrst_gct = \
+			ioremap(platform_config_address + sizeof(*vbt) - 4,
+					vbt->size - sizeof(*vbt) + 4);
+		pGCT = vbt->mrst_gct;
+		bpi = ((struct mrst_gct_v1 *)pGCT)->PD.BootPanelIndex;
+		dev_priv->gct_data.bpi = bpi;
+		dev_priv->gct_data.pt =
+			((struct mrst_gct_v1 *)pGCT)->PD.PanelType;
+		memcpy(&dev_priv->gct_data.DTD,
+			&((struct mrst_gct_v1 *)pGCT)->panel[bpi].DTD,
+				sizeof(struct mrst_timing_info));
+		dev_priv->gct_data.Panel_Port_Control =
+		  ((struct mrst_gct_v1 *)pGCT)->panel[bpi].Panel_Port_Control;
+		dev_priv->gct_data.Panel_MIPI_Display_Descriptor =
+		  ((struct mrst_gct_v1 *)pGCT)->panel[bpi].Panel_MIPI_Display_Descriptor;
+		break;
+	case 1:
+		vbt->mrst_gct = NULL;
+		vbt->mrst_gct = \
+			ioremap(platform_config_address + sizeof(*vbt) - 4,
+					vbt->size - sizeof(*vbt) + 4);
+		pGCT = vbt->mrst_gct;
+		bpi = ((struct mrst_gct_v2 *)pGCT)->PD.BootPanelIndex;
+		dev_priv->gct_data.bpi = bpi;
+		dev_priv->gct_data.pt =
+			((struct mrst_gct_v2 *)pGCT)->PD.PanelType;
+		memcpy(&dev_priv->gct_data.DTD,
+			&((struct mrst_gct_v2 *)pGCT)->panel[bpi].DTD,
+				sizeof(struct mrst_timing_info));
+		dev_priv->gct_data.Panel_Port_Control =
+		  ((struct mrst_gct_v2 *)pGCT)->panel[bpi].Panel_Port_Control;
+		dev_priv->gct_data.Panel_MIPI_Display_Descriptor =
+		  ((struct mrst_gct_v2 *)pGCT)->panel[bpi].Panel_MIPI_Display_Descriptor;
+		break;
+	case 0x10:
+		/*header definition changed from rev 01 (v2) to rev 10h. */
+		/*so, some values have changed location*/
+		new_size = vbt->checksum; /*checksum contains lo size byte*/
+		/*LSB of mrst_gct contains hi size byte*/
+		new_size |= ((0xff & (unsigned int)vbt->mrst_gct)) << 8;
+
+		vbt->checksum = vbt->size; /*size contains the checksum*/
+		if (new_size > 0xff)
+			vbt->size = 0xff; /*restrict size to 255*/
+		else
+			vbt->size = new_size;
+
+		/* number of descriptors defined in the GCT */
+		number_desc = ((0xff00 & (unsigned int)vbt->mrst_gct)) >> 8;
+		bpi = ((0xff0000 & (unsigned int)vbt->mrst_gct)) >> 16;
+		vbt->mrst_gct = NULL;
+		vbt->mrst_gct = \
+			ioremap(platform_config_address + GCT_R10_HEADER_SIZE,
+				GCT_R10_DISPLAY_DESC_SIZE * number_desc);
+		pGCT = vbt->mrst_gct;
+		pGCT = (u8 *)pGCT + (bpi*GCT_R10_DISPLAY_DESC_SIZE);
+		dev_priv->gct_data.bpi = bpi; /*save boot panel id*/
+
+		/*copy the GCT display timings into a temp structure*/
+		memcpy(&ti, pGCT, sizeof(struct gct_r10_timing_info));
+
+		/*now copy the temp struct into the dev_priv->gct_data*/
+		dp_ti->pixel_clock = ti.pixel_clock;
+		dp_ti->hactive_hi = ti.hactive_hi;
+		dp_ti->hactive_lo = ti.hactive_lo;
+		dp_ti->hblank_hi = ti.hblank_hi;
+		dp_ti->hblank_lo = ti.hblank_lo;
+		dp_ti->hsync_offset_hi = ti.hsync_offset_hi;
+		dp_ti->hsync_offset_lo = ti.hsync_offset_lo;
+		dp_ti->hsync_pulse_width_hi = ti.hsync_pulse_width_hi;
+		dp_ti->hsync_pulse_width_lo = ti.hsync_pulse_width_lo;
+		dp_ti->vactive_hi = ti.vactive_hi;
+		dp_ti->vactive_lo = ti.vactive_lo;
+		dp_ti->vblank_hi = ti.vblank_hi;
+		dp_ti->vblank_lo = ti.vblank_lo;
+		dp_ti->vsync_offset_hi = ti.vsync_offset_hi;
+		dp_ti->vsync_offset_lo = ti.vsync_offset_lo;
+		dp_ti->vsync_pulse_width_hi = ti.vsync_pulse_width_hi;
+		dp_ti->vsync_pulse_width_lo = ti.vsync_pulse_width_lo;
+
+		/*mov the MIPI_Display_Descriptor data from GCT to dev priv*/
+		dev_priv->gct_data.Panel_MIPI_Display_Descriptor =
+							*((u8 *)pGCT + 0x0d);
+		dev_priv->gct_data.Panel_MIPI_Display_Descriptor |=
+						(*((u8 *)pGCT + 0x0e)) << 8;
+		break;
+	default:
+		printk(KERN_ERR "Unknown revision of GCT!\n");
+		vbt->size = 0;
+	}
 }
 
 static void psb_get_core_freq(struct drm_device *dev)
@@ -358,36 +402,10 @@
 	}
 }
 
-#define FB_REG06 0xD0810600
-#define FB_TOPAZ_DISABLE BIT0
-#define FB_MIPI_DISABLE  BIT11
-#define FB_REG09 0xD0810900
-#define FB_SKU_MASK  (BIT12|BIT13|BIT14)
-#define FB_SKU_SHIFT 12
-#define FB_SKU_100 0
-#define FB_SKU_100L 1
-#define FB_SKU_83 2
-
-bool mid_get_pci_revID(struct drm_psb_private *dev_priv)
-{
-	uint32_t platform_rev_id = 0;
-	struct pci_dev *pci_gfx_root = pci_get_bus_and_slot(0, PCI_DEVFN(2, 0));
-
-	/*get the revison ID, B0:D2:F0;0x08 */
-	pci_read_config_dword(pci_gfx_root, 0x08, &platform_rev_id);
-	dev_priv->platform_rev_id = (uint8_t) platform_rev_id;
-	pci_dev_put(pci_gfx_root);
-	PSB_DEBUG_ENTRY("platform_rev_id is %x\n",
-					dev_priv->platform_rev_id);
-
-	return true;
-}
-
 static int psb_do_init(struct drm_device *dev)
 {
 	struct drm_psb_private *dev_priv =
 	    (struct drm_psb_private *) dev->dev_private;
-	struct ttm_bo_device *bdev = &dev_priv->bdev;
 	struct psb_gtt *pg = dev_priv->pg;
 
 	uint32_t stolen_gtt;
@@ -396,16 +414,6 @@
 
 	int ret = -ENOMEM;
 
-
-	/*
-	 * Initialize sequence numbers for the different command
-	 * submission mechanisms.
-	 */
-
-	dev_priv->sequence[PSB_ENGINE_2D] = 0;
-	dev_priv->sequence[PSB_ENGINE_VIDEO] = 0;
-	dev_priv->sequence[LNC_ENGINE_ENCODE] = 0;
-
 	if (pg->mmu_gatt_start & 0x0FFFFFFF) {
 		DRM_ERROR("Gatt must be 256M aligned. This is a bug.\n");
 		ret = -EINVAL;
@@ -445,6 +453,7 @@
 	    pg->gatt_pages : PSB_TT_PRIV0_PLIMIT;
 	tt_start = dev_priv->gatt_free_offset - pg->mmu_gatt_start;
 	tt_pages -= tt_start >> PAGE_SHIFT;
+	/* FIXME: can we kill ta_mem_size ? */
 	dev_priv->sizes.ta_mem_size = 0;
 
 	PSB_WSGX32(0x00000000, PSB_CR_BIF_BANK0);
@@ -453,30 +462,10 @@
         PSB_WSGX32(PSB_RSGX32(PSB_CR_BIF_CTRL) | _PSB_MMU_ER_MASK,
 							PSB_CR_BIF_CTRL);
 	psb_spank(dev_priv);
-       
-      	PSB_WSGX32(pg->mmu_gatt_start, PSB_CR_BIF_TWOD_REQ_BASE);
 
-	/* TT region managed by TTM. */
-	if (!ttm_bo_init_mm(bdev, TTM_PL_TT,
-			pg->gatt_pages -
-			(pg->ci_start >> PAGE_SHIFT) -
-			((dev_priv->ci_region_size + dev_priv->rar_region_size)
-			 >> PAGE_SHIFT))) {
-
-		dev_priv->have_tt = 1;
-		dev_priv->sizes.tt_size =
-			(tt_pages << PAGE_SHIFT) / (1024 * 1024) / 2;
-	}
-
-	if (!ttm_bo_init_mm(bdev,
-			DRM_PSB_MEM_MMU,
-			PSB_MEM_TT_START >> PAGE_SHIFT)) {
-		dev_priv->have_mem_mmu = 1;
-		dev_priv->sizes.mmu_size =
-			PSB_MEM_TT_START / (1024*1024);
-	}
+	/* mmu_gatt ?? */
+      	PSB_WSGX32(pg->gatt_start, PSB_CR_BIF_TWOD_REQ_BASE);
 
-	PSB_DEBUG_INIT("Init MSVDX\n");
 	return 0;
 out_err:
 	psb_do_takedown(dev);
@@ -510,39 +499,19 @@
 
 			down_read(&pg->sem);
 			psb_mmu_remove_pfn_sequence(
-					psb_mmu_get_default_pd
-					(dev_priv->mmu),
-					pg->mmu_gatt_start,
-					pg->vram_stolen_size >> PAGE_SHIFT);
-			if (pg->ci_stolen_size != 0)
-				psb_mmu_remove_pfn_sequence(
-					psb_mmu_get_default_pd
-					(dev_priv->mmu),
-					pg->ci_start,
-					pg->ci_stolen_size >> PAGE_SHIFT);
-			if (pg->rar_stolen_size != 0)
-				psb_mmu_remove_pfn_sequence(
-					psb_mmu_get_default_pd
-					(dev_priv->mmu),
-					pg->rar_start,
-					pg->rar_stolen_size >> PAGE_SHIFT);
+				psb_mmu_get_default_pd
+				(dev_priv->mmu),
+				pg->mmu_gatt_start,
+				dev_priv->vram_stolen_size >> PAGE_SHIFT);
 			up_read(&pg->sem);
 			psb_mmu_driver_takedown(dev_priv->mmu);
 			dev_priv->mmu = NULL;
 		}
-		psb_gtt_takedown(dev_priv->pg, 1);
+		psb_gtt_takedown(dev);
 		if (dev_priv->scratch_page) {
 			__free_page(dev_priv->scratch_page);
 			dev_priv->scratch_page = NULL;
 		}
-		if (dev_priv->has_bo_device) {
-			ttm_bo_device_release(&dev_priv->bdev);
-			dev_priv->has_bo_device = 0;
-		}
-		if (dev_priv->has_fence_device) {
-			ttm_fence_device_release(&dev_priv->fdev);
-			dev_priv->has_fence_device = 0;
-		}
 		if (dev_priv->vdc_reg) {
 			iounmap(dev_priv->vdc_reg);
 			dev_priv->vdc_reg = NULL;
@@ -552,12 +521,6 @@
 			dev_priv->sgx_reg = NULL;
 		}
 
-		if (dev_priv->tdev)
-			ttm_object_device_release(&dev_priv->tdev);
-
-		if (dev_priv->has_global)
-			psb_ttm_global_release(dev_priv);
-
 		kfree(dev_priv);
 		dev->dev_private = NULL;
 
@@ -565,7 +528,7 @@
 		psb_intel_destroy_bios(dev);
 	}
 
-	ospm_power_uninit();
+	gma_power_uninit(dev);
 
 	return 0;
 }
@@ -574,49 +537,27 @@
 static int psb_driver_load(struct drm_device *dev, unsigned long chipset)
 {
 	struct drm_psb_private *dev_priv;
-	struct ttm_bo_device *bdev;
 	unsigned long resource_start;
 	struct psb_gtt *pg;
 	unsigned long irqflags;
 	int ret = -ENOMEM;
 	uint32_t tt_pages;
+	struct drm_connector *connector;
+	struct psb_intel_output *psb_intel_output;
 
 	dev_priv = kzalloc(sizeof(*dev_priv), GFP_KERNEL);
 	if (dev_priv == NULL)
 		return -ENOMEM;
-	INIT_LIST_HEAD(&dev_priv->video_ctx);
-
-	dev_priv->num_pipe = 2;
 
+	if (IS_MRST(dev))
+		dev_priv->num_pipe = 1;
+	else
+		dev_priv->num_pipe = 2;
 
 	dev_priv->dev = dev;
-	bdev = &dev_priv->bdev;
-
-	ret = psb_ttm_global_init(dev_priv);
-	if (unlikely(ret != 0))
-		goto out_err;
-	dev_priv->has_global = 1;
-
-	dev_priv->tdev = ttm_object_device_init
-		(dev_priv->mem_global_ref.object, PSB_OBJECT_HASH_ORDER);
-	if (unlikely(dev_priv->tdev == NULL))
-		goto out_err;
-
-	mutex_init(&dev_priv->temp_mem);
-	mutex_init(&dev_priv->cmdbuf_mutex);
-	mutex_init(&dev_priv->reset_mutex);
-	INIT_LIST_HEAD(&dev_priv->context.validate_list);
-	INIT_LIST_HEAD(&dev_priv->context.kern_validate_list);
-
-/*	mutex_init(&dev_priv->dsr_mutex); */
-
-	spin_lock_init(&dev_priv->reloc_lock);
-
-	DRM_INIT_WAITQUEUE(&dev_priv->rel_mapped_queue);
 
 	dev->dev_private = (void *) dev_priv;
 	dev_priv->chipset = chipset;
-	psb_set_uopt(&dev_priv->uopt);
 
 	PSB_DEBUG_INIT("Mapping MMIO\n");
 	resource_start = pci_resource_start(dev->pdev, PSB_MMIO_RESOURCE);
@@ -626,34 +567,28 @@
 	if (!dev_priv->vdc_reg)
 		goto out_err;
 
-	dev_priv->sgx_reg = ioremap(resource_start + PSB_SGX_OFFSET,
+	if (IS_MRST(dev))
+		dev_priv->sgx_reg = ioremap(resource_start + MRST_SGX_OFFSET,
+							PSB_SGX_SIZE);
+	else
+		dev_priv->sgx_reg = ioremap(resource_start + PSB_SGX_OFFSET,
 							PSB_SGX_SIZE);
 
 	if (!dev_priv->sgx_reg)
 		goto out_err;
 
-	psb_get_core_freq(dev);
-	psb_intel_opregion_init(dev);
-	psb_intel_init_bios(dev);
-
-	PSB_DEBUG_INIT("Init TTM fence and BO driver\n");
+	if (IS_MRST(dev)) {
+		mrst_get_fuse_settings(dev);
+		mrst_get_vbt_data(dev_priv);
+		mid_get_pci_revID(dev_priv);
+	} else {
+		psb_get_core_freq(dev);
+		psb_intel_opregion_init(dev);
+		psb_intel_init_bios(dev);
+	}
 
 	/* Init OSPM support */
-	ospm_power_init(dev);
-
-	ret = psb_ttm_fence_device_init(&dev_priv->fdev);
-	if (unlikely(ret != 0))
-		goto out_err;
-
-	dev_priv->has_fence_device = 1;
-	ret = ttm_bo_device_init(bdev,
-				 dev_priv->bo_global_ref.ref.object,
-				 &psb_ttm_bo_driver,
-				 DRM_PSB_FILE_PAGE_OFFSET, false);
-	if (unlikely(ret != 0))
-		goto out_err;
-	dev_priv->has_bo_device = 1;
-	ttm_lock_init(&dev_priv->ttm_lock);
+	gma_power_init(dev);
 
 	ret = -ENOMEM;
 
@@ -663,15 +598,7 @@
 
 	set_pages_uc(dev_priv->scratch_page, 1);
 
-	dev_priv->pg = psb_gtt_alloc(dev);
-	if (!dev_priv->pg)
-		goto out_err;
-
-	ret = psb_gtt_init(dev_priv->pg, 0);
-	if (ret)
-		goto out_err;
-
-	ret = psb_gtt_mm_init(dev_priv->pg);
+	ret = psb_gtt_init(dev, 0);
 	if (ret)
 		goto out_err;
 
@@ -686,40 +613,6 @@
 	tt_pages = (pg->gatt_pages < PSB_TT_PRIV0_PLIMIT) ?
 		(pg->gatt_pages) : PSB_TT_PRIV0_PLIMIT;
 
-	/* CI/RAR use the lower half of TT. */
-	pg->ci_start = (tt_pages / 2) << PAGE_SHIFT;
-	pg->rar_start = pg->ci_start + pg->ci_stolen_size;
-
-
-	/*
-	 * Make MSVDX/TOPAZ MMU aware of the CI stolen memory area.
-	 */
-	if (dev_priv->pg->ci_stolen_size != 0) {
-		down_read(&pg->sem);
-		ret = psb_mmu_insert_pfn_sequence(psb_mmu_get_default_pd
-				(dev_priv->mmu),
-				dev_priv->ci_region_start >> PAGE_SHIFT,
-				pg->mmu_gatt_start + pg->ci_start,
-				pg->ci_stolen_size >> PAGE_SHIFT, 0);
-		up_read(&pg->sem);
-		if (ret)
-			goto out_err;
-	}
-
-	/*
-	 * Make MSVDX/TOPAZ MMU aware of the rar stolen memory area.
-	 */
-	if (dev_priv->pg->rar_stolen_size != 0) {
-		down_read(&pg->sem);
-		ret = psb_mmu_insert_pfn_sequence(
-				psb_mmu_get_default_pd(dev_priv->mmu),
-				dev_priv->rar_region_start >> PAGE_SHIFT,
-				pg->mmu_gatt_start + pg->rar_start,
-				pg->rar_stolen_size >> PAGE_SHIFT, 0);
-		up_read(&pg->sem);
-		if (ret)
-			goto out_err;
-	}
 
 	dev_priv->pf_pd = psb_mmu_alloc_pd(dev_priv->mmu, 1, 0);
 	if (!dev_priv->pf_pd)
@@ -728,14 +621,13 @@
 	psb_mmu_set_pd_context(psb_mmu_get_default_pd(dev_priv->mmu), 0);
 	psb_mmu_set_pd_context(dev_priv->pf_pd, 1);
 
-	spin_lock_init(&dev_priv->sequence_lock);
-
-	PSB_DEBUG_INIT("Begin to init MSVDX/Topaz\n");
-
 	ret = psb_do_init(dev);
 	if (ret)
 		return ret;
 
+	PSB_WSGX32(0x20000000, PSB_CR_PDS_EXEC_BASE);
+	PSB_WSGX32(0x30000000, PSB_CR_BIF_3D_REQ_BASE);
+
 /*	igd_opregion_init(&dev_priv->opregion_dev); */
 	acpi_video_register();
 	if (dev_priv->lid_state)
@@ -773,7 +665,18 @@
 		drm_kms_helper_poll_init(dev);
 	}
 
-	ret = psb_backlight_init(dev);
+	/* Only add backlight support if we have LVDS output */
+	list_for_each_entry(connector, &dev->mode_config.connector_list,
+			    head) {
+		psb_intel_output = to_psb_intel_output(connector);
+
+		switch (psb_intel_output->type) {
+		case INTEL_OUTPUT_LVDS:
+			ret = psb_backlight_init(dev);
+			break;
+		}
+	}
+
 	if (ret)
 		return ret;
 #if 0
@@ -783,11 +686,6 @@
 #endif
 	/*Intel drm driver load is done, continue doing pvr load*/
 	DRM_DEBUG("Pvr driver load\n");
-
-/*	if (PVRCore_Init() < 0)
-		goto out_err; */
-/*	if (MRSTLFBInit(dev) < 0)
-		goto out_err;*/
 	return 0;
 out_err:
 	psb_driver_unload(dev);
@@ -800,45 +698,6 @@
 }
 
 
-static int psb_vt_leave_ioctl(struct drm_device *dev, void *data,
-			      struct drm_file *file_priv)
-{
-	struct drm_psb_private *dev_priv = psb_priv(dev);
-	struct ttm_bo_device *bdev = &dev_priv->bdev;
-	struct ttm_mem_type_manager *man;
-	int ret;
-
-	ret = ttm_vt_lock(&dev_priv->ttm_lock, 1,
-			     psb_fpriv(file_priv)->tfile);
-	if (unlikely(ret != 0))
-		return ret;
-
-	ret = ttm_bo_evict_mm(&dev_priv->bdev, TTM_PL_TT);
-	if (unlikely(ret != 0))
-		goto out_unlock;
-
-	man = &bdev->man[TTM_PL_TT];
-
-#if 0		/* What to do with this ? */
-	if (unlikely(!drm_mm_clean(&man->manager)))
-		DRM_INFO("Warning: GATT was not clean after VT switch.\n");
-#endif
-
-	ttm_bo_swapout_all(&dev_priv->bdev);
-
-	return 0;
-out_unlock:
-	(void) ttm_vt_unlock(&dev_priv->ttm_lock);
-	return ret;
-}
-
-static int psb_vt_enter_ioctl(struct drm_device *dev, void *data,
-			      struct drm_file *file_priv)
-{
-	struct drm_psb_private *dev_priv = psb_priv(dev);
-	return ttm_vt_unlock(&dev_priv->ttm_lock);
-}
-
 static int psb_sizes_ioctl(struct drm_device *dev, void *data,
 			   struct drm_file *file_priv)
 {
@@ -945,13 +804,12 @@
 	uint32_t y;
 	uint32_t reg;
 
-	if (!ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND,
-							OSPM_UHB_ONLY_IF_ON))
-		return 0;
+	if (!gma_power_begin(dev, 0))
+		return -EIO;
 
 	reg = PSB_RVDC32(PIPEASRC);
 
-	ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
+	gma_power_end(dev);
 
 	/* horizontal is the left 16 bits */
 	x = reg >> 16;
@@ -1028,13 +886,12 @@
 		drm_fb = obj_to_fb(obj);
 		psb_fb = to_psb_fb(drm_fb);
 
-		if (ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND,
-					      OSPM_UHB_ONLY_IF_ON)) {
-			REG_WRITE(DSPASURF, psb_fb->offset);
+		if (gma_power_begin(dev, 0)) {
+			REG_WRITE(DSPASURF, psb_fb->gtt->offset);
 			REG_READ(DSPASURF);
-			ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
+			gma_power_end(dev);
 		} else {
-			dev_priv->saveDSPASURF = psb_fb->offset;
+			dev_priv->saveDSPASURF = psb_fb->gtt->offset;
 		}
 
 		return 0;
@@ -1107,8 +964,8 @@
 	struct drm_psb_private *dev_priv = psb_priv(dev);
 	struct drm_psb_stolen_memory_arg *arg = data;
 
-	arg->base = dev_priv->pg->stolen_base;
-	arg->size = dev_priv->pg->vram_stolen_size;
+	arg->base = dev_priv->stolen_base;
+	arg->size = dev_priv->vram_stolen_size;
 
 	return 0;
 }
@@ -1118,11 +975,10 @@
 {
 	struct drm_psb_private *dev_priv = psb_priv(dev);
 	struct drm_psb_register_rw_arg *arg = data;
-	UHBUsage usage =
-	  arg->b_force_hw_on ? OSPM_UHB_FORCE_POWER_ON : OSPM_UHB_ONLY_IF_ON;
+	bool usage = arg->b_force_hw_on ? true : false;
 
 	if (arg->display_write_mask != 0) {
-		if (ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND, usage)) {
+		if (gma_power_begin(dev, usage)) {
 			if (arg->display_write_mask & REGRWBITS_PFIT_CONTROLS)
 				PSB_WVDC32(arg->display.pfit_controls,
 					   PFIT_CONTROL);
@@ -1147,7 +1003,7 @@
 			if (arg->display_write_mask & REGRWBITS_VTOTAL_B)
 				PSB_WVDC32(arg->display.vtotal_b,
 					   VTOTAL_B);
-			ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
+			gma_power_end(dev);
 		} else {
 			if (arg->display_write_mask & REGRWBITS_PFIT_CONTROLS)
 				dev_priv->savePFIT_CONTROL =
@@ -1172,7 +1028,7 @@
 	}
 
 	if (arg->display_read_mask != 0) {
-		if (ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND, usage)) {
+		if (gma_power_begin(dev, usage)) {
 			if (arg->display_read_mask &
 			    REGRWBITS_PFIT_CONTROLS)
 				arg->display.pfit_controls =
@@ -1193,7 +1049,7 @@
 				arg->display.vtotal_a = PSB_RVDC32(VTOTAL_A);
 			if (arg->display_read_mask & REGRWBITS_VTOTAL_B)
 				arg->display.vtotal_b = PSB_RVDC32(VTOTAL_B);
-			ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
+			gma_power_end(dev);
 		} else {
 			if (arg->display_read_mask &
 			    REGRWBITS_PFIT_CONTROLS)
@@ -1219,7 +1075,7 @@
 	}
 
 	if (arg->overlay_write_mask != 0) {
-		if (ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND, usage)) {
+		if (gma_power_begin(dev, usage)) {
 			if (arg->overlay_write_mask & OV_REGRWBITS_OGAM_ALL) {
 				PSB_WVDC32(arg->overlay.OGAMC5, OV_OGAMC5);
 				PSB_WVDC32(arg->overlay.OGAMC4, OV_OGAMC4);
@@ -1270,7 +1126,7 @@
 					}
 				}
 			}
-			ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
+			gma_power_end(dev);
 		} else {
 			if (arg->overlay_write_mask & OV_REGRWBITS_OGAM_ALL) {
 				dev_priv->saveOV_OGAMC5 = arg->overlay.OGAMC5;
@@ -1296,7 +1152,7 @@
 	}
 
 	if (arg->overlay_read_mask != 0) {
-		if (ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND, usage)) {
+		if (gma_power_begin(dev, usage)) {
 			if (arg->overlay_read_mask & OV_REGRWBITS_OGAM_ALL) {
 				arg->overlay.OGAMC5 = PSB_RVDC32(OV_OGAMC5);
 				arg->overlay.OGAMC4 = PSB_RVDC32(OV_OGAMC4);
@@ -1317,7 +1173,7 @@
 				arg->overlay.OVADD = PSB_RVDC32(OV_OVADD);
 			if (arg->overlay_read_mask & OVC_REGRWBITS_OVADD)
 				arg->overlay.OVADD = PSB_RVDC32(OVC_OVADD);
-			ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
+			gma_power_end(dev);
 		} else {
 			if (arg->overlay_read_mask & OV_REGRWBITS_OGAM_ALL) {
 				arg->overlay.OGAMC5 = dev_priv->saveOV_OGAMC5;
@@ -1343,7 +1199,7 @@
 	}
 
 	if (arg->sprite_enable_mask != 0) {
-		if (ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND, usage)) {
+		if (gma_power_begin(dev, usage)) {
 			PSB_WVDC32(0x1F3E, DSPARB);
 			PSB_WVDC32(arg->sprite.dspa_control
 					| PSB_RVDC32(DSPACNTR), DSPACNTR);
@@ -1358,22 +1214,22 @@
 			PSB_WVDC32(arg->sprite.dspc_size, DSPCSIZE);
 			PSB_WVDC32(arg->sprite.dspc_surface, DSPCSURF);
 			PSB_RVDC32(DSPCSURF);
-			ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
+			gma_power_end(dev);
 		}
 	}
 
 	if (arg->sprite_disable_mask != 0) {
-		if (ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND, usage)) {
+		if (gma_power_begin(dev, usage)) {
 			PSB_WVDC32(0x3F3E, DSPARB);
 			PSB_WVDC32(0x0, DSPCCNTR);
 			PSB_WVDC32(arg->sprite.dspc_surface, DSPCSURF);
 			PSB_RVDC32(DSPCSURF);
-			ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
+			gma_power_end(dev);
 		}
 	}
 
 	if (arg->subpicture_enable_mask != 0) {
-		if (ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND, usage)) {
+		if (gma_power_begin(dev, usage)) {
 			uint32_t temp;
 			if (arg->subpicture_enable_mask & REGRWBITS_DSPACNTR) {
 				temp =  PSB_RVDC32(DSPACNTR);
@@ -1417,12 +1273,12 @@
 				PSB_WVDC32(temp, DSPCSURF);
 				PSB_RVDC32(DSPCSURF);
 			}
-			ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
+			gma_power_end(dev);
 		}
 	}
 
 	if (arg->subpicture_disable_mask != 0) {
-		if (ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND, usage)) {
+		if (gma_power_begin(dev, usage)) {
 			uint32_t temp;
 			if (arg->subpicture_disable_mask & REGRWBITS_DSPACNTR) {
 				temp =  PSB_RVDC32(DSPACNTR);
@@ -1463,42 +1319,20 @@
 				PSB_WVDC32(temp, DSPCSURF);
 				PSB_RVDC32(DSPCSURF);
 			}
-			ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
+			gma_power_end(dev);
 		}
 	}
 
 	return 0;
 }
 
-/* always available as we are SIGIO'd */
-static unsigned int psb_poll(struct file *filp,
-			     struct poll_table_struct *wait)
-{
-	return POLLIN | POLLRDNORM;
-}
-
-/* Not sure what we will need yet - in the PVR driver this disappears into
-   a tangle of abstracted handlers and per process crap */
-
-struct psb_priv {
-	int dummy;
-};
-
 static int psb_driver_open(struct drm_device *dev, struct drm_file *priv)
 {
-	struct psb_priv *psb = kzalloc(sizeof(struct psb_priv), GFP_KERNEL);
-	if (psb == NULL)
-		return -ENOMEM;
-	priv->driver_priv = psb;
-	DRM_DEBUG("\n");
-	/*return PVRSRVOpen(dev, priv);*/
 	return 0;
 }
 
 static void psb_driver_close(struct drm_device *dev, struct drm_file *priv)
 {
-	kfree(priv->driver_priv);
-	priv->driver_priv = NULL;
 }
 
 static long psb_unlocked_ioctl(struct file *filp, unsigned int cmd,
@@ -1517,30 +1351,9 @@
 		pm_runtime_allow(&dev->pdev->dev);
 		dev_priv->rpm_enabled = 1;
 	}
-	/*
-	 * The driver private ioctls and TTM ioctls should be
-	 * thread-safe.
-	 */
-
-	if ((nr >= DRM_COMMAND_BASE) && (nr < DRM_COMMAND_END)
-	     && (nr < DRM_COMMAND_BASE + dev->driver->num_ioctls)) {
-		struct drm_ioctl_desc *ioctl =
-					&psb_ioctls[nr - DRM_COMMAND_BASE];
-
-		if (unlikely(ioctl->cmd != cmd)) {
-			DRM_ERROR(
-				"Invalid drm cmnd %d ioctl->cmd %x, cmd %x\n",
-				nr - DRM_COMMAND_BASE, ioctl->cmd, cmd);
-			return -EINVAL;
-		}
-
-		return drm_ioctl(filp, cmd, arg);
-	}
-	/*
-	 * Not all old drm ioctls are thread-safe.
-	 */
-
 	return drm_ioctl(filp, cmd, arg);
+	
+	/* FIXME: do we need to wrap the other side of this */
 }
 
 
@@ -1557,16 +1370,21 @@
 	drm_put_dev(dev);
 }
 
-
 static const struct dev_pm_ops psb_pm_ops = {
 	.runtime_suspend = psb_runtime_suspend,
 	.runtime_resume = psb_runtime_resume,
 	.runtime_idle = psb_runtime_idle,
 };
 
+static struct vm_operations_struct psb_gem_vm_ops = {
+	.fault = psb_gem_fault,
+	.open = drm_gem_vm_open,
+	.close = drm_gem_vm_close,
+};
+
 static struct drm_driver driver = {
 	.driver_features = DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | \
-			   DRIVER_IRQ_VBL | DRIVER_MODESET,
+			   DRIVER_IRQ_VBL | DRIVER_MODESET| DRIVER_GEM ,
 	.load = psb_driver_load,
 	.unload = psb_driver_unload,
 
@@ -1580,27 +1398,29 @@
 	.enable_vblank = psb_enable_vblank,
 	.disable_vblank = psb_disable_vblank,
 	.get_vblank_counter = psb_get_vblank_counter,
-	.firstopen = NULL,
 	.lastclose = psb_lastclose,
 	.open = psb_driver_open,
-	.postclose = psb_driver_close,
-#if 0	/* ACFIXME */
-	.get_map_ofs = drm_core_get_map_ofs,
-	.get_reg_ofs = drm_core_get_reg_ofs,
-	.proc_init = psb_proc_init,
-	.proc_cleanup = psb_proc_cleanup,
-#endif
 	.preclose = psb_driver_preclose,
+	.postclose = psb_driver_close,
+	.reclaim_buffers = drm_core_reclaim_buffers,
+
+	.gem_init_object = psb_gem_init_object,
+	.gem_free_object = psb_gem_free_object,
+	.gem_vm_ops = &psb_gem_vm_ops,
+	.dumb_create = psb_gem_dumb_create,
+	.dumb_map_offset = psb_gem_dumb_map_gtt,
+	.dumb_destroy = psb_gem_dumb_destroy,
+
 	.fops = {
 		 .owner = THIS_MODULE,
-		 .open = psb_open,
-		 .release = psb_release,
+		 .open = drm_open,
+		 .release = drm_release,
 		 .unlocked_ioctl = psb_unlocked_ioctl,
-		 .mmap = psb_mmap,
-		 .poll = psb_poll,
+		 .mmap = drm_gem_mmap,
+		 .poll = drm_poll,
 		 .fasync = drm_fasync,
 		 .read = drm_read,
-		 },
+	 },
 	.name = DRIVER_NAME,
 	.desc = DRIVER_DESC,
 	.date = PSB_DRM_DRIVER_DATE,
@@ -1612,8 +1432,8 @@
 static struct pci_driver psb_pci_driver = {
 	.name = DRIVER_NAME,
 	.id_table = pciidlist,
-	.resume = ospm_power_resume,
-	.suspend = ospm_power_suspend,
+	.resume = gma_power_resume,
+	.suspend = gma_power_suspend,
 	.probe = psb_probe,
 	.remove = psb_remove,
 #ifdef CONFIG_PM
diff -druN linux-2.6.39-libre/drivers/staging/gma500/psb_drv.h linux-3.0-rc7-libre/drivers/staging/gma500/psb_drv.h
--- linux-2.6.39-libre/drivers/staging/gma500/psb_drv.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/gma500/psb_drv.h	2011-07-11 19:51:52.000000000 -0400
@@ -21,6 +21,7 @@
 #define _PSB_DRV_H_
 
 #include <linux/version.h>
+#include <linux/kref.h>
 
 #include <drm/drmP.h>
 #include "drm_global.h"
@@ -29,22 +30,19 @@
 #include "psb_intel_drv.h"
 #include "psb_gtt.h"
 #include "psb_powermgmt.h"
-#include "ttm/ttm_object.h"
-#include "psb_ttm_fence_driver.h"
-#include "psb_ttm_userobj_api.h"
-#include "ttm/ttm_bo_driver.h"
-#include "ttm/ttm_lock.h"
+#include "mrst.h"
 
 /*Append new drm mode definition here, align with libdrm definition*/
 #define DRM_MODE_SCALE_NO_SCALE   2
 
-extern struct ttm_bo_driver psb_ttm_bo_driver;
-
 enum {
 	CHIP_PSB_8108 = 0,
 	CHIP_PSB_8109 = 1,
+	CHIP_MRST_4100 = 2,
 };
 
+#define IS_MRST(dev) (((dev)->pci_device & 0xfffc) == 0x4100)
+
 /*
  *Hardware bugfixes
  */
@@ -52,10 +50,6 @@
 #define DRIVER_NAME "pvrsrvkm"
 #define DRIVER_DESC "drm driver for the Intel GMA500"
 #define DRIVER_AUTHOR "Intel Corporation"
-#define OSPM_PROC_ENTRY "ospm"
-#define RTPM_PROC_ENTRY "rtpm"
-#define BLC_PROC_ENTRY "mrst_blc"
-#define DISPLAY_PROC_ENTRY "display_status"
 
 #define PSB_DRM_DRIVER_DATE "2009-03-10"
 #define PSB_DRM_DRIVER_MAJOR 8
@@ -92,26 +86,10 @@
 #define PSB_TT_PRIV0_PLIMIT	 (PSB_TT_PRIV0_LIMIT >> PAGE_SHIFT)
 #define PSB_NUM_VALIDATE_BUFFERS 2048
 
-#define PSB_MEM_MMU_START       0x00000000
-#define PSB_MEM_TT_START        0xE0000000
-
-#define PSB_GL3_CACHE_CTL	0x2100
-#define PSB_GL3_CACHE_STAT	0x2108
-
 /*
  *Flags for external memory type field.
  */
 
-#define MRST_MSVDX_OFFSET	0x90000	/*MSVDX Base offset */
-#define PSB_MSVDX_OFFSET	0x50000	/*MSVDX Base offset */
-/* MSVDX MMIO region is 0x50000 - 0x57fff ==> 32KB */
-#define PSB_MSVDX_SIZE		0x10000
-
-#define LNC_TOPAZ_OFFSET	0xA0000
-#define PNW_TOPAZ_OFFSET	0xC0000
-#define PNW_GL3_OFFSET		0xB0000
-#define LNC_TOPAZ_SIZE		0x10000
-#define PNW_TOPAZ_SIZE		0x30000 /* PNW VXE285 has two cores */
 #define PSB_MMU_CACHED_MEMORY	  0x0001	/* Bind to MMU only */
 #define PSB_MMU_RO_MEMORY	  0x0002	/* MMU RO memory */
 #define PSB_MMU_WO_MEMORY	  0x0004	/* MMU WO memory */
@@ -223,20 +201,6 @@
 #define MDFLD_PNW_B0 0x04
 #define MDFLD_PNW_C0 0x08
 
-#define MDFLD_DSR_2D_3D_0 BIT0
-#define MDFLD_DSR_2D_3D_2 BIT1
-#define MDFLD_DSR_CURSOR_0 BIT2
-#define MDFLD_DSR_CURSOR_2 BIT3
-#define MDFLD_DSR_OVERLAY_0 BIT4
-#define MDFLD_DSR_OVERLAY_2 BIT5
-#define MDFLD_DSR_MIPI_CONTROL	BIT6
-#define MDFLD_DSR_2D_3D 	(MDFLD_DSR_2D_3D_0 | MDFLD_DSR_2D_3D_2)
-
-#define MDFLD_DSR_RR 45
-#define MDFLD_DPU_ENABLE BIT31
-#define MDFLD_DSR_FULLSCREEN BIT30
-#define MDFLD_DSR_DELAY (DRM_HZ / MDFLD_DSR_RR)
-
 #define PSB_PWR_STATE_ON		1
 #define PSB_PWR_STATE_OFF		2
 
@@ -250,9 +214,6 @@
 #define PSB_PCIx_MSI_ADDR_LOC		0x94
 #define PSB_PCIx_MSI_DATA_LOC		0x98
 
-#define MDFLD_PLANE_MAX_WIDTH		2048
-#define MDFLD_PLANE_MAX_HEIGHT		2048
-
 struct opregion_header;
 struct opregion_acpi;
 struct opregion_swsci;
@@ -266,142 +227,55 @@
 	int enabled;
 };
 
-/*
- *User options.
- */
-
-struct drm_psb_uopt {
-	int pad; /*keep it here in case we use it in future*/
-};
-
-/**
- *struct psb_context
- *
- *@buffers:	 array of pre-allocated validate buffers.
- *@used_buffers: number of buffers in @buffers array currently in use.
- *@validate_buffer: buffers validated from user-space.
- *@kern_validate_buffers : buffers validated from kernel-space.
- *@fence_flags : Fence flags to be used for fence creation.
- *
- *This structure is used during execbuf validation.
- */
-
-struct psb_context {
-	struct psb_validate_buffer *buffers;
-	uint32_t used_buffers;
-	struct list_head validate_list;
-	struct list_head kern_validate_list;
-	uint32_t fence_types;
-	uint32_t val_seq;
-};
-
-struct psb_validate_buffer;
-
-/* Currently defined profiles */
-enum VAProfile {
-	VAProfileMPEG2Simple		= 0,
-	VAProfileMPEG2Main		= 1,
-	VAProfileMPEG4Simple		= 2,
-	VAProfileMPEG4AdvancedSimple	= 3,
-	VAProfileMPEG4Main		= 4,
-	VAProfileH264Baseline		= 5,
-	VAProfileH264Main		= 6,
-	VAProfileH264High		= 7,
-	VAProfileVC1Simple		= 8,
-	VAProfileVC1Main		= 9,
-	VAProfileVC1Advanced		= 10,
-	VAProfileH263Baseline		= 11,
-	VAProfileJPEGBaseline           = 12,
-	VAProfileH264ConstrainedBaseline = 13
-};
-
-/* Currently defined entrypoints */
-enum VAEntrypoint {
-	VAEntrypointVLD		= 1,
-	VAEntrypointIZZ		= 2,
-	VAEntrypointIDCT	= 3,
-	VAEntrypointMoComp	= 4,
-	VAEntrypointDeblocking	= 5,
-	VAEntrypointEncSlice	= 6,	/* slice level encode */
-	VAEntrypointEncPicture 	= 7	/* pictuer encode, JPEG, etc */
-};
-
-
-struct psb_video_ctx {
-	struct list_head head;
-	struct file *filp; /* DRM device file pointer */
-	int ctx_type; /* profile<<8|entrypoint */
-	/* todo: more context specific data for multi-context support */
-};
-
-#define MODE_SETTING_IN_CRTC 	0x1
-#define MODE_SETTING_IN_ENCODER 0x2
-#define MODE_SETTING_ON_GOING 	0x3
-#define MODE_SETTING_IN_DSR 	0x4
-#define MODE_SETTING_ENCODER_DONE 0x8
-#define GCT_R10_HEADER_SIZE	16
-#define GCT_R10_DISPLAY_DESC_SIZE	28
 
 struct drm_psb_private {
-	/*
-	 * DSI info.
-	 */
-	void * dbi_dsr_info;
-	void * dsi_configs[2];
-
-	/*
-	 *TTM Glue.
-	 */
-
-	struct drm_global_reference mem_global_ref;
-	struct ttm_bo_global_ref bo_global_ref;
-	int has_global;
-
 	struct drm_device *dev;
-	struct ttm_object_device *tdev;
-	struct ttm_fence_device fdev;
-	struct ttm_bo_device bdev;
-	struct ttm_lock ttm_lock;
-	struct vm_operations_struct *ttm_vm_ops;
-	int has_fence_device;
-	int has_bo_device;
 
 	unsigned long chipset;
 
-	struct drm_psb_uopt uopt;
-
 	struct psb_gtt *pg;
 
-	/*GTT Memory manager*/
+	/* GTT Memory manager */
 	struct psb_gtt_mm *gtt_mm;
-
 	struct page *scratch_page;
-	uint32_t sequence[PSB_NUM_ENGINES];
-	uint32_t last_sequence[PSB_NUM_ENGINES];
-	uint32_t last_submitted_seq[PSB_NUM_ENGINES];
+	u32 *gtt_map;
+	uint32_t stolen_base;
+	void *vram_addr;
+	unsigned long vram_stolen_size;
+	int gtt_initialized;
+	u16 gmch_ctrl;		/* Saved GTT setup */
+	u32 pge_ctl;
+
+	struct mutex gtt_mutex;
+	struct resource *gtt_mem;	/* Our PCI resource */
 
 	struct psb_mmu_driver *mmu;
 	struct psb_mmu_pd *pf_pd;
 
+	/*
+	 * Register base
+	 */
+
 	uint8_t *sgx_reg;
 	uint8_t *vdc_reg;
 	uint32_t gatt_free_offset;
 
-	/* IMG video context */
-	struct list_head video_ctx;
-
-
-
 	/*
-	 *Fencing / irq.
+	 * Fencing / irq.
 	 */
 
 	uint32_t vdc_irq_mask;
 	uint32_t pipestat[PSB_NUM_PIPE];
-	bool vblanksEnabledForFlips;
 
 	spinlock_t irqmask_lock;
-	spinlock_t sequence_lock;
+
+	/*
+	 * Power
+         */
+
+	bool suspended;
+	bool display_power;
+	int display_count;
 
 	/*
 	 *Modesetting
@@ -413,40 +287,9 @@
 	uint32_t num_pipe;
 
 	/*
-	 * CI share buffer
-	 */
-	unsigned int ci_region_start;
-	unsigned int ci_region_size;
-
-	/*
-	 * RAR share buffer;
-	 */
-	unsigned int rar_region_start;
-	unsigned int rar_region_size;
-
-	/*
 	 *Memory managers
 	 */
 
-	int have_camera;
-	int have_rar;
-	int have_tt;
-	int have_mem_mmu;
-	struct mutex temp_mem;
-
-	/*
-	 *Relocation buffer mapping.
-	 */
-
-	spinlock_t reloc_lock;
-	unsigned int rel_mapped_pages;
-	wait_queue_head_t rel_mapped_queue;
-
-	/*
-	 *SAREA
-	 */
-	struct drm_psb_sarea *sarea_priv;
-
 	/*
 	*OSPM info
 	*/
@@ -458,7 +301,8 @@
 
 	struct drm_psb_sizes_arg sizes;
 
-	uint32_t fuse_reg_value;
+	u32 fuse_reg_value;
+	u32 video_device_fuse;
 
 	/* pci revision id for B0:D2:F0 */
 	uint8_t platform_rev_id;
@@ -483,6 +327,7 @@
 	unsigned int lvds_use_ssc:1;
 	int lvds_ssc_freq;
 	bool is_lvds_on;
+	bool is_mipi_on;
 
 	unsigned int core_freq;
 	uint32_t iLVDS_enable;
@@ -490,6 +335,20 @@
 	/*runtime PM state*/
 	int rpm_enabled;
 
+	/* Moorestown specific */
+	struct mrst_vbt vbt_data;
+	struct mrst_gct_data gct_data;
+
+	/* Moorestown pipe config register value cache */
+	uint32_t pipeconf;
+	uint32_t pipeconf1;
+	uint32_t pipeconf2;
+
+	/* Moorestown plane control register value cache */
+	uint32_t dspcntr;
+	uint32_t dspcntr1;
+	uint32_t dspcntr2;
+
 	/*
 	 *Register state
 	 */
@@ -595,98 +454,11 @@
 	uint32_t saveOVC_OGAMC4;
 	uint32_t saveOVC_OGAMC5;
 
-	/*
-	 * extra MDFLD Register state
-	 */
-	uint32_t saveHDMIPHYMISCCTL;
-	uint32_t saveHDMIB_CONTROL;
-	uint32_t saveDSPCCNTR;
-	uint32_t savePIPECCONF;
-	uint32_t savePIPECSRC;
-	uint32_t saveHTOTAL_C;
-	uint32_t saveHBLANK_C;
-	uint32_t saveHSYNC_C;
-	uint32_t saveVTOTAL_C;
-	uint32_t saveVBLANK_C;
-	uint32_t saveVSYNC_C;
-	uint32_t saveDSPCSTRIDE;
-	uint32_t saveDSPCSIZE;
-	uint32_t saveDSPCPOS;
-	uint32_t saveDSPCSURF;
-	uint32_t saveDSPCLINOFF;
-	uint32_t saveDSPCTILEOFF;
-	uint32_t saveDSPCCURSOR_CTRL;
-	uint32_t saveDSPCCURSOR_BASE;
-	uint32_t saveDSPCCURSOR_POS;
-	uint32_t save_palette_c[256];
-	uint32_t saveOV_OVADD_C;
-	uint32_t saveOV_OGAMC0_C;
-	uint32_t saveOV_OGAMC1_C;
-	uint32_t saveOV_OGAMC2_C;
-	uint32_t saveOV_OGAMC3_C;
-	uint32_t saveOV_OGAMC4_C;
-	uint32_t saveOV_OGAMC5_C;
-
-	/* DSI reg save */
-	uint32_t saveDEVICE_READY_REG;
-	uint32_t saveINTR_EN_REG;
-	uint32_t saveDSI_FUNC_PRG_REG;
-	uint32_t saveHS_TX_TIMEOUT_REG;
-	uint32_t saveLP_RX_TIMEOUT_REG;
-	uint32_t saveTURN_AROUND_TIMEOUT_REG;
-	uint32_t saveDEVICE_RESET_REG;
-	uint32_t saveDPI_RESOLUTION_REG;
-	uint32_t saveHORIZ_SYNC_PAD_COUNT_REG;
-	uint32_t saveHORIZ_BACK_PORCH_COUNT_REG;
-	uint32_t saveHORIZ_FRONT_PORCH_COUNT_REG;
-	uint32_t saveHORIZ_ACTIVE_AREA_COUNT_REG;
-	uint32_t saveVERT_SYNC_PAD_COUNT_REG;
-	uint32_t saveVERT_BACK_PORCH_COUNT_REG;
-	uint32_t saveVERT_FRONT_PORCH_COUNT_REG;
-	uint32_t saveHIGH_LOW_SWITCH_COUNT_REG;
-	uint32_t saveINIT_COUNT_REG;
-	uint32_t saveMAX_RET_PAK_REG;
-	uint32_t saveVIDEO_FMT_REG;
-	uint32_t saveEOT_DISABLE_REG;
-	uint32_t saveLP_BYTECLK_REG;
-	uint32_t saveHS_LS_DBI_ENABLE_REG;
-	uint32_t saveTXCLKESC_REG;
-	uint32_t saveDPHY_PARAM_REG;
-	uint32_t saveMIPI_CONTROL_REG;
-	uint32_t saveMIPI;
-	uint32_t saveMIPI_C;
-	void (*init_drvIC)(struct drm_device *dev);
-	void (*dsi_prePowerState)(struct drm_device *dev);
-	void (*dsi_postPowerState)(struct drm_device *dev);
-
-	/* DPST Register Save */
-	uint32_t saveHISTOGRAM_INT_CONTROL_REG;
-	uint32_t saveHISTOGRAM_LOGIC_CONTROL_REG;
-	uint32_t savePWM_CONTROL_LOGIC;
-
 	/* MSI reg save */
-
 	uint32_t msi_addr;
 	uint32_t msi_data;
 
 	/*
-	 *Scheduling.
-	 */
-
-	struct mutex reset_mutex;
-	struct mutex cmdbuf_mutex;
-	/*uint32_t ta_mem_pages;
-	struct psb_ta_mem *ta_mem;
-	int force_ta_mem_load;*/
-	atomic_t val_seq;
-
-	/*
-	 *TODO: change this to be per drm-context.
-	 */
-
-	struct psb_context context;
-
-	/*
 	 * LID-Switch
 	 */
 	spinlock_t lid_lock;
@@ -699,8 +471,6 @@
 	 *Watchdog
 	 */
 
-	int timer_available;
-
 	uint32_t apm_reg;
 	uint16_t apm_base;
 
@@ -716,73 +486,17 @@
 };
 
 
-struct psb_file_data {	/* TODO: Audit this, remove the indirection and set
-			   it up properly in open/postclose  ACFIXME */
-	void *priv;
-};
-
-struct psb_fpriv {
-	struct ttm_object_file *tfile;
-};
-
 struct psb_mmu_driver;
 
 extern int drm_crtc_probe_output_modes(struct drm_device *dev, int, int);
 extern int drm_pick_crtcs(struct drm_device *dev);
 
-static inline struct psb_fpriv *psb_fpriv(struct drm_file *file_priv)
-{
-	struct psb_file_data *pvr_file_priv
-			= (struct psb_file_data *)file_priv->driver_priv;
-	return (struct psb_fpriv *) pvr_file_priv->priv;
-}
-
 static inline struct drm_psb_private *psb_priv(struct drm_device *dev)
 {
 	return (struct drm_psb_private *) dev->dev_private;
 }
 
 /*
- *TTM glue. psb_ttm_glue.c
- */
-
-extern int psb_open(struct inode *inode, struct file *filp);
-extern int psb_release(struct inode *inode, struct file *filp);
-extern int psb_mmap(struct file *filp, struct vm_area_struct *vma);
-
-extern int psb_fence_signaled_ioctl(struct drm_device *dev, void *data,
-				    struct drm_file *file_priv);
-extern int psb_verify_access(struct ttm_buffer_object *bo,
-			     struct file *filp);
-extern ssize_t psb_ttm_read(struct file *filp, char __user *buf,
-			    size_t count, loff_t *f_pos);
-extern ssize_t psb_ttm_write(struct file *filp, const char __user *buf,
-			    size_t count, loff_t *f_pos);
-extern int psb_fence_finish_ioctl(struct drm_device *dev, void *data,
-				  struct drm_file *file_priv);
-extern int psb_fence_unref_ioctl(struct drm_device *dev, void *data,
-				 struct drm_file *file_priv);
-extern int psb_pl_waitidle_ioctl(struct drm_device *dev, void *data,
-				 struct drm_file *file_priv);
-extern int psb_pl_setstatus_ioctl(struct drm_device *dev, void *data,
-				  struct drm_file *file_priv);
-extern int psb_pl_synccpu_ioctl(struct drm_device *dev, void *data,
-				struct drm_file *file_priv);
-extern int psb_pl_unref_ioctl(struct drm_device *dev, void *data,
-			      struct drm_file *file_priv);
-extern int psb_pl_reference_ioctl(struct drm_device *dev, void *data,
-				  struct drm_file *file_priv);
-extern int psb_pl_create_ioctl(struct drm_device *dev, void *data,
-			       struct drm_file *file_priv);
-extern int psb_pl_ub_create_ioctl(struct drm_device *dev, void *data,
-			       struct drm_file *file_priv);
-extern int psb_extension_ioctl(struct drm_device *dev, void *data,
-			       struct drm_file *file_priv);
-extern int psb_ttm_global_init(struct drm_psb_private *dev_priv);
-extern void psb_ttm_global_release(struct drm_psb_private *dev_priv);
-extern int psb_getpageaddrs_ioctl(struct drm_device *dev, void *data,
-				struct drm_file *file_priv);
-/*
  *MMU stuff.
  */
 
@@ -825,31 +539,6 @@
 				 uint32_t desired_tile_stride,
 				 uint32_t hw_tile_stride);
 /*
- *psb_sgx.c
- */
-
-
-
-extern int psb_cmdbuf_ioctl(struct drm_device *dev, void *data,
-			    struct drm_file *file_priv);
-extern int psb_reg_submit(struct drm_psb_private *dev_priv,
-			  uint32_t *regs, unsigned int cmds);
-
-
-extern void psb_fence_or_sync(struct drm_file *file_priv,
-			      uint32_t engine,
-			      uint32_t fence_types,
-			      uint32_t fence_flags,
-			      struct list_head *list,
-			      struct psb_ttm_fence_rep *fence_arg,
-			      struct ttm_fence_object **fence_p);
-extern int psb_validate_kernel_buffer(struct psb_context *context,
-				      struct ttm_buffer_object *bo,
-				      uint32_t fence_class,
-				      uint64_t set_flags,
-				      uint64_t clr_flags);
-
-/*
  *psb_irq.c
  */
 
@@ -859,8 +548,6 @@
 extern void psb_irq_preinstall(struct drm_device *dev);
 extern int psb_irq_postinstall(struct drm_device *dev);
 extern void psb_irq_uninstall(struct drm_device *dev);
-extern void psb_irq_preinstall_islands(struct drm_device *dev, int hw_islands);
-extern int psb_irq_postinstall_islands(struct drm_device *dev, int hw_islands);
 extern void psb_irq_turn_on_dpst(struct drm_device *dev);
 extern void psb_irq_turn_off_dpst(struct drm_device *dev);
 
@@ -878,29 +565,6 @@
 extern u32 psb_get_vblank_counter(struct drm_device *dev, int crtc);
 
 /*
- *psb_fence.c
- */
-
-extern void psb_fence_handler(struct drm_device *dev, uint32_t class);
-
-extern int psb_fence_emit_sequence(struct ttm_fence_device *fdev,
-				   uint32_t fence_class,
-				   uint32_t flags, uint32_t *sequence,
-				   unsigned long *timeout_jiffies);
-extern void psb_fence_error(struct drm_device *dev,
-			    uint32_t class,
-			    uint32_t sequence, uint32_t type, int error);
-extern int psb_ttm_fence_device_init(struct ttm_fence_device *fdev);
-
-/* MSVDX/Topaz stuff */
-extern int psb_remove_videoctx(struct drm_psb_private *dev_priv, struct file *filp);
-
-extern int lnc_video_frameskip(struct drm_device *dev,
-			       uint64_t user_pointer);
-extern int lnc_video_getparam(struct drm_device *dev, void *data,
-			      struct drm_file *file_priv);
-
-/*
  * psb_opregion.c
  */
 extern int psb_intel_opregion_init(struct drm_device *dev);
@@ -930,6 +594,9 @@
 
 extern void psb_spank(struct drm_psb_private *dev_priv);
 
+extern int psbfb_2d_submit(struct drm_psb_private *dev_priv, uint32_t *cmdbuf,
+	 	  	   unsigned size);
+
 /*
  *psb_reset.c
  */
@@ -950,8 +617,36 @@
 int psb_get_brightness(struct backlight_device *bd);
 struct backlight_device * psb_get_backlight_device(void);
 
+/* mrst_crtc.c */
+extern const struct drm_crtc_helper_funcs mrst_helper_funcs;
+
+/* mrst_lvds.c */
+extern void mrst_lvds_init(struct drm_device *dev,
+		    struct psb_intel_mode_device *mode_dev);
+
+/* psb_intel_lvds.c */
+extern void psb_intel_lvds_prepare(struct drm_encoder *encoder);
+extern void psb_intel_lvds_commit(struct drm_encoder *encoder);
+extern const struct drm_connector_helper_funcs
+					psb_intel_lvds_connector_helper_funcs;
+extern const struct drm_connector_funcs psb_intel_lvds_connector_funcs;
+
+/* psb_gem.c */
+extern int psb_gem_init_object(struct drm_gem_object *obj);
+extern void psb_gem_free_object(struct drm_gem_object *obj);
+extern int psb_gem_get_aperture(struct drm_device *dev, void *data,
+				struct drm_file *file);
+extern int psb_gem_dumb_create(struct drm_file *file, struct drm_device *dev,
+			struct drm_mode_create_dumb *args);
+extern int psb_gem_dumb_destroy(struct drm_file *file, struct drm_device *dev,
+			uint32_t handle);
+extern int psb_gem_dumb_map_gtt(struct drm_file *file, struct drm_device *dev,
+			 uint32_t handle, uint64_t *offset);
+extern int psb_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf);
+
+
 /*
- *Debug print bits setting
+ * Debug print bits setting
  */
 #define PSB_D_GENERAL (1 << 0)
 #define PSB_D_INIT    (1 << 1)
@@ -975,7 +670,6 @@
 
 extern int drm_psb_debug;
 extern int drm_psb_no_fb;
-extern int drm_psb_disable_vsync;
 extern int drm_idle_check_interval;
 
 #define PSB_DEBUG_GENERAL(_fmt, _arg...) \
diff -druN linux-2.6.39-libre/drivers/staging/gma500/psb_fb.c linux-3.0-rc7-libre/drivers/staging/gma500/psb_fb.c
--- linux-2.6.39-libre/drivers/staging/gma500/psb_fb.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/gma500/psb_fb.c	2011-07-11 19:51:52.000000000 -0400
@@ -36,10 +36,7 @@
 #include "psb_drv.h"
 #include "psb_intel_reg.h"
 #include "psb_intel_drv.h"
-#include "psb_ttm_userobj_api.h"
 #include "psb_fb.h"
-#include "psb_sgx.h"
-#include "psb_pvr_glue.h"
 
 static void psb_user_framebuffer_destroy(struct drm_framebuffer *fb);
 static int psb_user_framebuffer_create_handle(struct drm_framebuffer *fb,
@@ -193,8 +190,7 @@
 	struct psb_framebuffer *psbfb = vma->vm_private_data;
 	struct drm_device *dev = psbfb->base.dev;
 	struct drm_psb_private *dev_priv = dev->dev_private;
-	struct psb_gtt *pg = dev_priv->pg;
-	unsigned long phys_addr = (unsigned long)pg->stolen_base;;
+	unsigned long phys_addr = (unsigned long)dev_priv->stolen_base;
 
 	page_num = (vma->vm_end - vma->vm_start) >> PAGE_SHIFT;
 
@@ -243,7 +239,6 @@
 	char *fb_screen_base = NULL;
 	struct drm_device *dev = psbfb->base.dev;
 	struct drm_psb_private *dev_priv = dev->dev_private;
-	struct psb_gtt *pg = dev_priv->pg;
 
 	if (vma->vm_pgoff != 0)
 		return -EINVAL;
@@ -256,22 +251,48 @@
 	fb_screen_base = (char *)info->screen_base;
 
 	DRM_DEBUG("vm_pgoff 0x%lx, screen base %p vram_addr %p\n",
-				vma->vm_pgoff, fb_screen_base, pg->vram_addr);
+				vma->vm_pgoff, fb_screen_base,
+                                dev_priv->vram_addr);
 
-	/*if using stolen memory, */
-	if (fb_screen_base == pg->vram_addr) {
+        /* FIXME: ultimately this needs to become 'if entirely stolen memory' */
+	if (1 || fb_screen_base == dev_priv->vram_addr) {
 		vma->vm_ops = &psbfb_vm_ops;
 		vma->vm_private_data = (void *)psbfb;
 		vma->vm_flags |= VM_RESERVED | VM_IO |
 						VM_MIXEDMAP | VM_DONTEXPAND;
 	} else {
-	/*using IMG meminfo, can I use pvrmmap to map it?*/
-
+	        /* GTT memory backed by kernel/user pages, needs a different
+	           approach ? - GEM ? */
 	}
 
 	return 0;
 }
 
+static int psbfb_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg)
+{
+	struct psb_fbdev *fbdev = info->par;
+	struct psb_framebuffer *psbfb = fbdev->pfb;
+	struct drm_device *dev = psbfb->base.dev;
+	struct drm_psb_private *dev_priv = dev->dev_private;
+	u32 __user *p = (u32 __user *)arg;
+	u32 l;
+	u32 buf[32];
+	switch (cmd) {
+	case 0x12345678:
+		if (!capable(CAP_SYS_RAWIO))
+			return -EPERM;
+		if (get_user(l, p))
+			return -EFAULT;
+		if (l > 32)
+			return -EMSGSIZE;
+		if (copy_from_user(buf, p + 1, l * sizeof(u32)))
+			return -EFAULT;
+		psbfb_2d_submit(dev_priv, buf, l);
+		return 0;
+	default:
+		return -ENOTTY;
+	}
+}
 
 static struct fb_ops psbfb_ops = {
 	.owner = THIS_MODULE,
@@ -284,11 +305,12 @@
 	.fb_imageblit = psbfb_imageblit,
 	.fb_mmap = psbfb_mmap,
 	.fb_sync = psbfb_sync,
+	.fb_ioctl = psbfb_ioctl,
 };
 
 static struct drm_framebuffer *psb_framebuffer_create
 			(struct drm_device *dev, struct drm_mode_fb_cmd *r,
-			 void *mm_private)
+			 struct gtt_range *gt)
 {
 	struct psb_framebuffer *fb;
 	int ret;
@@ -304,7 +326,7 @@
 
 	drm_helper_mode_fill_fb_struct(&fb->base, r);
 
-	fb->bo = mm_private;
+	fb->gtt = gt;
 
 	return &fb->base;
 
@@ -313,136 +335,58 @@
 	return NULL;
 }
 
-static struct drm_framebuffer *psb_user_framebuffer_create
-			(struct drm_device *dev, struct drm_file *filp,
-			 struct drm_mode_fb_cmd *r)
+/**
+ *	psbfb_alloc		-	allocate frame buffer memory
+ *	@dev: the DRM device
+ *	@aligned_size: space needed
+ *
+ *	Allocate the frame buffer. In the usual case we get a GTT range that
+ *	is stolen memory backed and life is simple. If there isn't sufficient
+ *	stolen memory or the system has no stolen memory we allocate a range
+ *	and back it with a GEM object.
+ *
+ *	In this case the GEM object has no handle. 
+ */
+static struct gtt_range *psbfb_alloc(struct drm_device *dev, int aligned_size)
 {
-	struct ttm_buffer_object *bo = NULL;
-	uint64_t size;
-
-	bo = ttm_buffer_object_lookup(psb_fpriv(filp)->tfile, r->handle);
-	if (!bo)
-		return NULL;
-
-	/* JB: TODO not drop, make smarter */
-	size = ((uint64_t) bo->num_pages) << PAGE_SHIFT;
-	if (size < r->width * r->height * 4)
-		return NULL;
-
-	/* JB: TODO not drop, refcount buffer */
-	return psb_framebuffer_create(dev, r, bo);
-
-#if 0
-	struct psb_framebuffer *psbfb;
-	struct drm_framebuffer *fb;
-	struct fb_info *info;
-	void *psKernelMemInfo = NULL;
-	void * hKernelMemInfo = (void *)r->handle;
-	struct drm_psb_private *dev_priv
-		= (struct drm_psb_private *)dev->dev_private;
-	struct psb_fbdev *fbdev = dev_priv->fbdev;
-	struct psb_gtt *pg = dev_priv->pg;
-	int ret;
-	uint32_t offset;
-	uint64_t size;
-
-	ret = psb_get_meminfo_by_handle(hKernelMemInfo, &psKernelMemInfo);
-	if (ret) {
-		DRM_ERROR("Cannot get meminfo for handle 0x%x\n",
-						(u32)hKernelMemInfo);
-		return NULL;
-	}
-
-	DRM_DEBUG("Got Kernel MemInfo for handle %lx\n",
-		  (u32)hKernelMemInfo);
-
-	/* JB: TODO not drop, make smarter */
-	size = psKernelMemInfo->ui32AllocSize;
-	if (size < r->height * r->pitch)
+	struct gtt_range *backing;
+	/* Begin by trying to use stolen memory backing */
+	backing = psb_gtt_alloc_range(dev, aligned_size, "fb", 1);
+	if (backing)
+		return backing;
+	/* Next try using GEM host memory */
+	backing = psb_gtt_alloc_range(dev, aligned_size, "fb(gem)", 0);
+	if (backing == NULL)
 		return NULL;
 
-	/* JB: TODO not drop, refcount buffer */
-	/* return psb_framebuffer_create(dev, r, bo); */
-
-	fb = psb_framebuffer_create(dev, r, (void *)psKernelMemInfo);
-	if (!fb) {
-		DRM_ERROR("failed to allocate fb.\n");
+	/* Now back it with an object */
+	if (drm_gem_object_init(dev, &backing->gem, aligned_size) != 0) {
+		psb_gtt_free_range(dev, backing);
 		return NULL;
 	}
-
-	psbfb = to_psb_fb(fb);
-	psbfb->size = size;
-	psbfb->hKernelMemInfo = hKernelMemInfo;
-
-	DRM_DEBUG("Mapping to gtt..., KernelMemInfo %p\n", psKernelMemInfo);
-
-	/*if not VRAM, map it into tt aperture*/
-	if (psKernelMemInfo->pvLinAddrKM != pg->vram_addr) {
-		ret = psb_gtt_map_meminfo(dev, hKernelMemInfo, &offset);
-		if (ret) {
-			DRM_ERROR("map meminfo for 0x%x failed\n",
-				  (u32)hKernelMemInfo);
-			return NULL;
-		}
-		psbfb->offset = (offset << PAGE_SHIFT);
-	} else {
-		psbfb->offset = 0;
-	}
-	info = framebuffer_alloc(0, &dev->pdev->dev);
-	if (!info)
-		return NULL;
-
-	strcpy(info->fix.id, "psbfb");
-
-	info->flags = FBINFO_DEFAULT;
-	info->fix.accel = FB_ACCEL_I830;	/*FIXMEAC*/
-	info->fbops = &psbfb_ops;
-
-	info->fix.smem_start = dev->mode_config.fb_base;
-	info->fix.smem_len = size;
-
-	info->screen_base = psKernelMemInfo->pvLinAddrKM;
-	info->screen_size = size;
-
-	drm_fb_helper_fill_fix(info, fb->pitch, fb->depth);
-	drm_fb_helper_fill_var(info, &fbdev->psb_fb_helper,
-							fb->width, fb->height);
-
-	info->fix.mmio_start = pci_resource_start(dev->pdev, 0);
-	info->fix.mmio_len = pci_resource_len(dev->pdev, 0);
-
-	info->pixmap.size = 64 * 1024;
-	info->pixmap.buf_align = 8;
-	info->pixmap.access_align = 32;
-	info->pixmap.flags = FB_PIXMAP_SYSTEM;
-	info->pixmap.scan_align = 1;
-
-	psbfb->fbdev = info;
-	fbdev->pfb = psbfb;
-
-	fbdev->psb_fb_helper.fb = fb;
-	fbdev->psb_fb_helper.fbdev = info;
-	MRSTLFBHandleChangeFB(dev, psbfb);
-
-	return fb;
-#endif
+	return backing;
 }
-
+	
+/**
+ *	psbfb_create		-	create a framebuffer
+ *	@fbdev: the framebuffer device
+ *	@sizes: specification of the layout
+ *
+ *	Create a framebuffer to the specifications provided
+ */
 static int psbfb_create(struct psb_fbdev *fbdev,
 				struct drm_fb_helper_surface_size *sizes)
 {
 	struct drm_device *dev = fbdev->psb_fb_helper.dev;
 	struct drm_psb_private *dev_priv = dev->dev_private;
-	struct psb_gtt *pg = dev_priv->pg;
 	struct fb_info *info;
 	struct drm_framebuffer *fb;
 	struct psb_framebuffer *psbfb;
 	struct drm_mode_fb_cmd mode_cmd;
 	struct device *device = &dev->pdev->dev;
-
-	struct ttm_buffer_object *fbo = NULL;
 	int size, aligned_size;
 	int ret;
+	struct gtt_range *backing;
 
 	mode_cmd.width = sizes->surface_width;
 	mode_cmd.height = sizes->surface_height;
@@ -455,15 +399,19 @@
 	size = mode_cmd.pitch * mode_cmd.height;
 	aligned_size = ALIGN(size, PAGE_SIZE);
 
+	/* Allocate the framebuffer in the GTT with stolen page backing */
+	backing = psbfb_alloc(dev, aligned_size);
+	if (backing == NULL)
+	        return -ENOMEM;
+
 	mutex_lock(&dev->struct_mutex);
-	fb = psb_framebuffer_create(dev, &mode_cmd, fbo);
+	fb = psb_framebuffer_create(dev, &mode_cmd, backing);
 	if (!fb) {
 		DRM_ERROR("failed to allocate fb.\n");
 		ret = -ENOMEM;
 		goto out_err1;
 	}
 	psbfb = to_psb_fb(fb);
-	psbfb->size = size;
 
 	info = framebuffer_alloc(sizeof(struct psb_fbdev), device);
 	if (!info) {
@@ -485,10 +433,24 @@
 	info->fbops = &psbfb_ops;
 	info->fix.smem_start = dev->mode_config.fb_base;
 	info->fix.smem_len = size;
-	info->screen_base = (char *)pg->vram_addr;
+
+	/* Accessed via stolen memory directly, This only works for stolem
+	   memory however. Need to address this once we start using gtt
+	   pages we allocate */
+	info->screen_base = (char *)dev_priv->vram_addr + backing->offset;
 	info->screen_size = size;
 	memset(info->screen_base, 0, size);
 
+	if (dev_priv->pg->stolen_size) {
+		info->apertures = alloc_apertures(1);
+		if (!info->apertures) {
+			ret = -ENOMEM;
+			goto out_err0;
+		}
+		info->apertures->ranges[0].base = dev->mode_config.fb_base;
+		info->apertures->ranges[0].size = dev_priv->pg->stolen_size;
+	}
+
 	drm_fb_helper_fill_fix(info, fb->pitch, fb->depth);
 	drm_fb_helper_fill_var(info, &fbdev->psb_fb_helper,
 				sizes->fb_width, sizes->fb_height);
@@ -515,9 +477,51 @@
 	fb->funcs->destroy(fb);
 out_err1:
 	mutex_unlock(&dev->struct_mutex);
+	psb_gtt_free_range(dev, backing);
 	return ret;
 }
 
+/**
+ *	psb_user_framebuffer_create	-	create framebuffer
+ *	@dev: our DRM device
+ *	@filp: client file
+ *	@cmd: mode request
+ *
+ *	Create a new framebuffer backed by a userspace GEM object
+ */
+static struct drm_framebuffer *psb_user_framebuffer_create
+			(struct drm_device *dev, struct drm_file *filp,
+			 struct drm_mode_fb_cmd *cmd)
+{
+        struct gtt_range *r;
+        struct drm_gem_object *obj;
+        struct psb_framebuffer *psbfb;
+
+        /* Find the GEM object and thus the gtt range object that is
+           to back this space */
+	obj = drm_gem_object_lookup(dev, filp, cmd->handle);
+	if (obj == NULL)
+	        return ERR_PTR(-ENOENT);
+
+        /* Allocate a framebuffer */
+        psbfb = kzalloc(sizeof(*psbfb), GFP_KERNEL);
+        if (psbfb == NULL) {
+                drm_gem_object_unreference_unlocked(obj);
+                return ERR_PTR(-ENOMEM);
+        }
+        
+        /* Let the core code do all the work */
+        r = container_of(obj, struct gtt_range, gem);
+	if (psb_framebuffer_create(dev, cmd, r) == NULL) {
+                drm_gem_object_unreference_unlocked(obj);
+                kfree(psbfb);
+                return ERR_PTR(-EINVAL);
+        }
+        /* Return the drm_framebuffer contained within the psb fbdev which
+           has been initialized by the framebuffer creation */
+        return &psbfb->base;
+}
+
 static void psbfb_gamma_set(struct drm_crtc *crtc, u16 red, u16 green,
 							u16 blue, int regno)
 {
@@ -561,15 +565,20 @@
 
 	if (fbdev->psb_fb_helper.fbdev) {
 		info = fbdev->psb_fb_helper.fbdev;
+		/* FIXME: this is a bit more inside knowledge than I'd like
+		   but I don't see how to make a fake GEM object of the
+		   stolen space nicely */
+		if (psbfb->gtt->stolen)
+			psb_gtt_free_range(dev, psbfb->gtt);
+		else
+			drm_gem_object_unreference(&psbfb->gtt->gem);
 		unregister_framebuffer(info);
 		iounmap(info->screen_base);
 		framebuffer_release(info);
 	}
 
 	drm_fb_helper_fini(&fbdev->psb_fb_helper);
-
 	drm_framebuffer_cleanup(&psbfb->base);
-
 	return 0;
 }
 
@@ -610,7 +619,6 @@
 	dev_priv->fbdev = NULL;
 }
 
-
 static void psbfb_output_poll_changed(struct drm_device *dev)
 {
 	struct drm_psb_private *dev_priv = dev->dev_private;
@@ -627,7 +635,6 @@
 		return 0;
 
 	info = psbfb->fbdev;
-	psbfb->pvrBO = NULL;
 
 	if (info)
 		framebuffer_release(info);
@@ -635,28 +642,48 @@
 }
 /*EXPORT_SYMBOL(psbfb_remove); */
 
+/**
+ *	psb_user_framebuffer_create_handle - add hamdle to a framebuffer
+ *	@fb: framebuffer
+ *	@file_priv: our DRM file
+ *	@handle: returned handle
+ *
+ *	Our framebuffer object is a GTT range which also contains a GEM
+ *	object. We need to turn it into a handle for userspace. GEM will do
+ *	the work for us
+ */
 static int psb_user_framebuffer_create_handle(struct drm_framebuffer *fb,
 					      struct drm_file *file_priv,
 					      unsigned int *handle)
 {
-	/* JB: TODO currently we can't go from a bo to a handle with ttm */
-	(void) file_priv;
-	*handle = 0;
-	return 0;
+        struct psb_framebuffer *psbfb = to_psb_fb(fb);
+        struct gtt_range *r = psbfb->gtt;
+        if (r->stolen)
+                return -EOPNOTSUPP;
+        return drm_gem_handle_create(file_priv, &r->gem, handle);
 }
 
+/**
+ *	psb_user_framebuffer_destroy	-	destruct user created fb
+ *	@fb: framebuffer
+ *
+ *	User framebuffers are backed by GEM objects so all we have to do is
+ *	clean up a bit and drop the reference, GEM will handle the fallout
+ */
 static void psb_user_framebuffer_destroy(struct drm_framebuffer *fb)
 {
 	struct drm_device *dev = fb->dev;
 	struct psb_framebuffer *psbfb = to_psb_fb(fb);
+	struct gtt_range *r = psbfb->gtt;
 
-	/*ummap gtt pages*/
-	psb_gtt_unmap_meminfo(dev, psbfb->hKernelMemInfo);
 	if (psbfb->fbdev)
 		psbfb_remove(dev, fb);
 
-	/* JB: TODO not drop, refcount buffer */
+        /* Let DRM do its clean up */
 	drm_framebuffer_cleanup(fb);
+	/*  We are no longer using the resource in GEM */
+	drm_gem_object_unreference_unlocked(&r->gem);
+
 	kfree(fb);
 }
 
@@ -698,8 +725,15 @@
 
 	psb_create_backlight_property(dev);
 
-	psb_intel_lvds_init(dev, &dev_priv->mode_dev);
-	/* psb_intel_sdvo_init(dev, SDVOB); */
+	if (IS_MRST(dev)) {
+		if (dev_priv->iLVDS_enable)
+			mrst_lvds_init(dev, &dev_priv->mode_dev);
+		else
+			DRM_ERROR("DSI is not supported\n");
+	} else {
+		psb_intel_lvds_init(dev, &dev_priv->mode_dev);
+		psb_intel_sdvo_init(dev, SDVOB);
+	}
 
 	list_for_each_entry(connector, &dev->mode_config.connector_list,
 			    head) {
@@ -716,7 +750,10 @@
 			break;
 		case INTEL_OUTPUT_LVDS:
 			PSB_DEBUG_ENTRY("LVDS.\n");
-			crtc_mask = (1 << 1);
+			if (IS_MRST(dev))
+				crtc_mask = (1 << 0);
+			else
+				crtc_mask = (1 << 1);
 			clone_mask = (1 << INTEL_OUTPUT_LVDS);
 			break;
 		case INTEL_OUTPUT_MIPI:
@@ -743,52 +780,6 @@
 	}
 }
 
-static void *psb_bo_from_handle(struct drm_device *dev,
-				struct drm_file *file_priv,
-				unsigned int handle)
-{
-	void *psKernelMemInfo = NULL;
-	void * hKernelMemInfo = (void *)handle;
-	int ret;
-
-	ret = psb_get_meminfo_by_handle(hKernelMemInfo, &psKernelMemInfo);
-	if (ret) {
-		DRM_ERROR("Cannot get meminfo for handle 0x%x\n",
-			  (u32)hKernelMemInfo);
-		return NULL;
-	}
-
-	return (void *)psKernelMemInfo;
-}
-
-static size_t psb_bo_size(struct drm_device *dev, void *bof)
-{
-#if 0
-	void *psKernelMemInfo	= (void *)bof;
-	return (size_t)psKernelMemInfo->ui32AllocSize;
-#else
-	return 0;
-#endif
-}
-
-static size_t psb_bo_offset(struct drm_device *dev, void *bof)
-{
-	struct psb_framebuffer *psbfb
-		= (struct psb_framebuffer *)bof;
-
-	return (size_t)psbfb->offset;
-}
-
-static int psb_bo_pin_for_scanout(struct drm_device *dev, void *bo)
-{
-	 return 0;
-}
-
-static int psb_bo_unpin_for_scanout(struct drm_device *dev, void *bo)
-{
-	return 0;
-}
-
 void psb_modeset_init(struct drm_device *dev)
 {
 	struct drm_psb_private *dev_priv =
@@ -797,12 +788,6 @@
 	int i;
 
 	PSB_DEBUG_ENTRY("\n");
-	/* Init mm functions */
-	mode_dev->bo_from_handle = psb_bo_from_handle;
-	mode_dev->bo_size = psb_bo_size;
-	mode_dev->bo_offset = psb_bo_offset;
-	mode_dev->bo_pin_for_scanout = psb_bo_pin_for_scanout;
-	mode_dev->bo_unpin_for_scanout = psb_bo_unpin_for_scanout;
 
 	drm_mode_config_init(dev);
 
diff -druN linux-2.6.39-libre/drivers/staging/gma500/psb_fb.h linux-3.0-rc7-libre/drivers/staging/gma500/psb_fb.h
--- linux-2.6.39-libre/drivers/staging/gma500/psb_fb.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/gma500/psb_fb.h	2011-07-11 19:51:52.000000000 -0400
@@ -28,32 +28,22 @@
 
 #include "psb_drv.h"
 
-/*IMG Headers*/
-/*#include "servicesint.h"*/
-
 struct psb_framebuffer {
 	struct drm_framebuffer base;
 	struct address_space *addr_space;
-	struct ttm_buffer_object *bo;
-	struct fb_info * fbdev;
-	/* struct ttm_bo_kmap_obj kmap; */
-	void *pvrBO;	/* FIXME: sort this out */
-	void * hKernelMemInfo;
-	uint32_t size;
-	uint32_t offset;
+	struct fb_info *fbdev;
+	struct gtt_range *gtt;
 };
 
 struct psb_fbdev {
 	struct drm_fb_helper psb_fb_helper;
-	struct psb_framebuffer * pfb;
+	struct psb_framebuffer *pfb;
 };
 
 
 #define to_psb_fb(x) container_of(x, struct psb_framebuffer, base)
 
-
 extern int psb_intel_connector_clones(struct drm_device *dev, int type_mask);
 
-
 #endif
 
diff -druN linux-2.6.39-libre/drivers/staging/gma500/psb_fence.c linux-3.0-rc7-libre/drivers/staging/gma500/psb_fence.c
--- linux-2.6.39-libre/drivers/staging/gma500/psb_fence.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/gma500/psb_fence.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,122 +0,0 @@
-/*
- * Copyright (c) 2007, Intel Corporation.
- * All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- *
- *
- * Authors: Thomas Hellstrom <thomas-at-tungstengraphics-dot-com>
- */
-
-#include <drm/drmP.h>
-#include "psb_drv.h"
-
-
-static void psb_fence_poll(struct ttm_fence_device *fdev,
-			   uint32_t fence_class, uint32_t waiting_types)
-{
-	struct drm_psb_private *dev_priv =
-	    container_of(fdev, struct drm_psb_private, fdev);
-
-
-	if (unlikely(!dev_priv))
-		return;
-
-	if (waiting_types == 0)
-		return;
-
-	/* DRM_ERROR("Polling fence sequence, got 0x%08x\n", sequence); */
-	ttm_fence_handler(fdev, fence_class, 0 /* Sequence */,
-			_PSB_FENCE_TYPE_EXE, 0);
-}
-
-void psb_fence_error(struct drm_device *dev,
-		     uint32_t fence_class,
-		     uint32_t sequence, uint32_t type, int error)
-{
-	struct drm_psb_private *dev_priv = psb_priv(dev);
-	struct ttm_fence_device *fdev = &dev_priv->fdev;
-	unsigned long irq_flags;
-	struct ttm_fence_class_manager *fc =
-	    &fdev->fence_class[fence_class];
-
-	BUG_ON(fence_class >= PSB_NUM_ENGINES);
-	write_lock_irqsave(&fc->lock, irq_flags);
-	ttm_fence_handler(fdev, fence_class, sequence, type, error);
-	write_unlock_irqrestore(&fc->lock, irq_flags);
-}
-
-int psb_fence_emit_sequence(struct ttm_fence_device *fdev,
-			    uint32_t fence_class,
-			    uint32_t flags, uint32_t *sequence,
-			    unsigned long *timeout_jiffies)
-{
-	struct drm_psb_private *dev_priv =
-	    container_of(fdev, struct drm_psb_private, fdev);
-
-	if (!dev_priv)
-		return -EINVAL;
-
-	if (fence_class >= PSB_NUM_ENGINES)
-		return -EINVAL;
-
-	DRM_ERROR("Unexpected fence class\n");
-	return -EINVAL;
-}
-
-static void psb_fence_lockup(struct ttm_fence_object *fence,
-			     uint32_t fence_types)
-{
-	DRM_ERROR("Unsupported fence class\n");
-}
-
-void psb_fence_handler(struct drm_device *dev, uint32_t fence_class)
-{
-	struct drm_psb_private *dev_priv = psb_priv(dev);
-	struct ttm_fence_device *fdev = &dev_priv->fdev;
-	struct ttm_fence_class_manager *fc =
-	    &fdev->fence_class[fence_class];
-	unsigned long irq_flags;
-
-	write_lock_irqsave(&fc->lock, irq_flags);
-	psb_fence_poll(fdev, fence_class, fc->waiting_types);
-	write_unlock_irqrestore(&fc->lock, irq_flags);
-}
-
-
-static struct ttm_fence_driver psb_ttm_fence_driver = {
-	.has_irq = NULL,
-	.emit = psb_fence_emit_sequence,
-	.flush = NULL,
-	.poll = psb_fence_poll,
-	.needed_flush = NULL,
-	.wait = NULL,
-	.signaled = NULL,
-	.lockup = psb_fence_lockup,
-};
-
-int psb_ttm_fence_device_init(struct ttm_fence_device *fdev)
-{
-	struct drm_psb_private *dev_priv =
-		container_of(fdev, struct drm_psb_private, fdev);
-	struct ttm_fence_class_init fci = {.wrap_diff = (1 << 30),
-		.flush_diff = (1 << 29),
-		.sequence_mask = 0xFFFFFFFF
-	};
-
-	return ttm_fence_device_init(PSB_NUM_ENGINES,
-				     dev_priv->mem_global_ref.object,
-				     fdev, &fci, 1,
-				     &psb_ttm_fence_driver);
-}
diff -druN linux-2.6.39-libre/drivers/staging/gma500/psb_gem.c linux-3.0-rc7-libre/drivers/staging/gma500/psb_gem.c
--- linux-2.6.39-libre/drivers/staging/gma500/psb_gem.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/staging/gma500/psb_gem.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,320 @@
+/*
+ *  psb GEM interface
+ *
+ * Copyright (c) 2011, 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.
+ *
+ * Authors: Alan Cox
+ *
+ * TODO:
+ *	-	we don't actually put GEM objects into the GART yet
+ *	-	we need to work out if the MMU is relevant as well (eg for
+ *		accelerated operations on a GEM object)
+ *	-	cache coherency
+ *
+ * ie this is just an initial framework to get us going.
+ */
+
+#include <drm/drmP.h>
+#include <drm/drm.h>
+#include "psb_drm.h"
+#include "psb_drv.h"
+
+int psb_gem_init_object(struct drm_gem_object *obj)
+{
+	return -EINVAL;
+}
+
+void psb_gem_free_object(struct drm_gem_object *obj)
+{
+	struct gtt_range *gtt = container_of(obj, struct gtt_range, gem);
+	psb_gtt_free_range(obj->dev, gtt);
+	if (obj->map_list.map) {
+		/* Do things GEM should do for us */
+		struct drm_gem_mm *mm = obj->dev->mm_private;
+		struct drm_map_list *list = &obj->map_list;
+		drm_ht_remove_item(&mm->offset_hash, &list->hash);
+		drm_mm_put_block(list->file_offset_node);
+		kfree(list->map);
+		list->map = NULL;
+	}
+	drm_gem_object_release(obj);
+}
+
+int psb_gem_get_aperture(struct drm_device *dev, void *data,
+				struct drm_file *file)
+{
+	return -EINVAL;
+}
+
+/**
+ *	psb_gem_create_mmap_offset	-	invent an mmap offset
+ *	@obj: our object
+ *
+ *	This is basically doing by hand a pile of ugly crap which should
+ *	be done automatically by the GEM library code but isn't
+ */
+static int psb_gem_create_mmap_offset(struct drm_gem_object *obj)
+{
+	struct drm_device *dev = obj->dev;
+	struct drm_gem_mm *mm = dev->mm_private;
+	struct drm_map_list *list;
+	struct drm_local_map *map;
+	int ret;
+
+	list = &obj->map_list;
+	list->map = kzalloc(sizeof(struct drm_map_list), GFP_KERNEL);
+	if (list->map == NULL)
+		return -ENOMEM;
+	map = list->map;
+	map->type = _DRM_GEM;
+	map->size = obj->size;
+	map->handle =obj;
+
+	list->file_offset_node = drm_mm_search_free(&mm->offset_manager,
+					obj->size / PAGE_SIZE, 0, 0);
+	if (!list->file_offset_node) {
+		DRM_ERROR("failed to allocate offset for bo %d\n", obj->name);
+		ret = -ENOSPC;
+		goto free_it;
+	}
+	list->file_offset_node = drm_mm_get_block(list->file_offset_node,
+					obj->size / PAGE_SIZE, 0);
+	if (!list->file_offset_node) {
+		ret = -ENOMEM;
+		goto free_it;
+	}
+	list->hash.key = list->file_offset_node->start;
+	ret = drm_ht_insert_item(&mm->offset_hash, &list->hash);
+	if (ret) {
+		DRM_ERROR("failed to add to map hash\n");
+		goto free_mm;
+	}
+	return 0;
+
+free_mm:
+	drm_mm_put_block(list->file_offset_node);
+free_it:
+	kfree(list->map);
+	list->map = NULL;
+	return ret;
+}
+
+/**
+ *	psb_gem_dumb_map_gtt	-	buffer mapping for dumb interface
+ *	@file: our drm client file
+ *	@dev: drm device
+ *	@handle: GEM handle to the object (from dumb_create)
+ *
+ *	Do the necessary setup to allow the mapping of the frame buffer
+ *	into user memory. We don't have to do much here at the moment.
+ */
+int psb_gem_dumb_map_gtt(struct drm_file *file, struct drm_device *dev,
+			 uint32_t handle, uint64_t *offset)
+{
+	int ret = 0;
+	struct drm_gem_object *obj;
+
+	if (!(dev->driver->driver_features & DRIVER_GEM))
+		return -ENODEV;
+		
+	mutex_lock(&dev->struct_mutex);
+
+	/* GEM does all our handle to object mapping */
+	obj = drm_gem_object_lookup(dev, file, handle);
+	if (obj == NULL) {
+		ret = -ENOENT;
+		goto unlock;
+	}
+	/* What validation is needed here ? */
+	
+	/* Make it mmapable */
+	if (!obj->map_list.map) {
+		ret = psb_gem_create_mmap_offset(obj);
+		if (ret)
+			goto out;
+	}
+	/* GEM should really work out the hash offsets for us */
+	*offset = (u64)obj->map_list.hash.key << PAGE_SHIFT;
+out:
+	drm_gem_object_unreference(obj);
+unlock:
+	mutex_unlock(&dev->struct_mutex);
+	return ret;
+}
+
+/**
+ *	psb_gem_create		-	create a mappable object
+ *	@file: the DRM file of the client
+ *	@dev: our device
+ *	@size: the size requested
+ *	@handlep: returned handle (opaque number)
+ *
+ *	Create a GEM object, fill in the boilerplate and attach a handle to
+ *	it so that userspace can speak about it. This does the core work
+ *	for the various methods that do/will create GEM objects for things
+ */
+static int psb_gem_create(struct drm_file *file,
+	struct drm_device *dev, uint64_t size, uint32_t *handlep)
+{
+	struct gtt_range *r;
+	int ret;
+	u32 handle;
+
+	size = roundup(size, PAGE_SIZE);
+
+	/* Allocate our object - for now a direct gtt range which is not 
+	   stolen memory backed */
+	r = psb_gtt_alloc_range(dev, size, "gem", 0);
+	if (r == NULL)
+		return -ENOSPC;
+	/* Initialize the extra goodies GEM needs to do all the hard work */
+	if (drm_gem_object_init(dev, &r->gem, size) != 0) {
+		psb_gtt_free_range(dev, r);
+		/* GEM doesn't give an error code and we don't have an
+		   EGEMSUCKS so make something up for now - FIXME */
+		return -ENOMEM;
+	}
+	/* Give the object a handle so we can carry it more easily */
+	ret = drm_gem_handle_create(file, &r->gem, &handle);
+	if (ret) {
+		drm_gem_object_release(&r->gem);
+		psb_gtt_free_range(dev, r);
+		return ret;
+	}
+	/* We have the initial and handle reference but need only one now */
+	drm_gem_object_unreference(&r->gem);
+	*handlep = handle;
+	return 0;
+}
+
+/**
+ *	psb_gem_dumb_create	-	create a dumb buffer
+ *	@drm_file: our client file
+ *	@dev: our device
+ *	@args: the requested arguments copied from userspace
+ *
+ *	Allocate a buffer suitable for use for a frame buffer of the
+ *	form described by user space. Give userspace a handle by which
+ *	to reference it.
+ */
+int psb_gem_dumb_create(struct drm_file *file, struct drm_device *dev,
+			struct drm_mode_create_dumb *args)
+{
+	args->pitch = ALIGN(args->width * ((args->bpp + 7) / 8), 64);
+	args->size = args->pitch * args->height;
+	return psb_gem_create(file, dev, args->size, &args->handle);
+}
+
+/**
+ *	psb_gem_dumb_destroy	-	destroy a dumb buffer
+ *	@file: client file
+ *	@dev: our DRM device
+ *	@handle: the object handle
+ *
+ *	Destroy a handle that was created via psb_gem_dumb_create, at least
+ *	we hope it was created that way. i915 seems to assume the caller
+ *	does the checking but that might be worth review ! FIXME
+ */
+int psb_gem_dumb_destroy(struct drm_file *file, struct drm_device *dev,
+			uint32_t handle)
+{
+	/* No special work needed, drop the reference and see what falls out */
+	return drm_gem_handle_delete(file, handle);
+}
+
+/**
+ *	psb_gem_fault		-	pagefault handler for GEM objects
+ *	@vma: the VMA of the GEM object
+ *	@vmf: fault detail
+ *
+ *	Invoked when a fault occurs on an mmap of a GEM managed area. GEM
+ *	does most of the work for us including the actual map/unmap calls
+ *	but we need to do the actual page work.
+ *
+ *	This code eventually needs to handle faulting objects in and out
+ *	of the GART and repacking it when we run out of space. We can put
+ *	that off for now and for our simple uses
+ *
+ *	The VMA was set up by GEM. In doing so it also ensured that the
+ *	vma->vm_private_data points to the GEM object that is backing this
+ *	mapping.
+ *
+ *	To avoid aliasing and cache funnies we want to map the object
+ *	through the GART. For the moment this is slightly hackish. It would
+ *	be nicer if GEM provided mmap opened/closed hooks for us giving
+ *	the object so that we could track things nicely. That needs changes
+ *	to the core GEM code so must be tackled post staging
+ *
+ *	FIXME
+ */
+int psb_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
+{
+	struct drm_gem_object *obj;
+	struct gtt_range *r;
+	int ret;
+	unsigned long pfn;
+	pgoff_t page_offset;
+	struct drm_device *dev;
+
+	obj = vma->vm_private_data;	/* GEM object */
+	dev = obj->dev;
+
+	r = container_of(obj, struct gtt_range, gem);	/* Get the gtt range */
+
+	/* Make sure we don't parallel update on a fault, nor move or remove
+	   something from beneath our feet */
+	mutex_lock(&dev->struct_mutex);
+
+	/* For now the mmap pins the object and it stays pinned. As things
+	   stand that will do us no harm */
+	if (r->mmapping == 0) {
+		ret = psb_gtt_pin(r);
+		if (ret < 0) {
+		        DRM_ERROR("gma500: pin failed: %d\n", ret);
+		        goto fail;
+                }
+		r->mmapping = 1;
+	}
+
+	/* FIXME: Locking. We may also need to repack the GART sometimes */
+
+	/* Page relative to the VMA start */
+	page_offset = ((unsigned long) vmf->virtual_address - vma->vm_start)
+				>> PAGE_SHIFT;
+
+	/* Bus address of the page is gart + object offset + page offset */
+	/* Assumes gtt allocations are page aligned */
+	pfn = (r->resource.start >> PAGE_SHIFT) + page_offset;
+
+	pr_debug("Object GTT base at %p\n", (void *)(r->resource.start));
+	pr_debug("Inserting %p pfn %lx, pa %lx\n", vmf->virtual_address,
+	        pfn, pfn << PAGE_SHIFT);
+
+	ret = vm_insert_pfn(vma, (unsigned long)vmf->virtual_address, pfn);
+
+fail:
+        mutex_unlock(&dev->struct_mutex);
+	switch (ret) {
+	case 0:
+	case -ERESTARTSYS:
+	case -EINTR:
+		return VM_FAULT_NOPAGE;
+	case -ENOMEM:
+		return VM_FAULT_OOM;
+	default:
+		return VM_FAULT_SIGBUS;
+	}
+}
diff -druN linux-2.6.39-libre/drivers/staging/gma500/psb_gtt.c linux-3.0-rc7-libre/drivers/staging/gma500/psb_gtt.c
--- linux-2.6.39-libre/drivers/staging/gma500/psb_gtt.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/gma500/psb_gtt.c	2011-07-11 19:51:52.000000000 -0400
@@ -16,12 +16,24 @@
  * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
  *
  * Authors: Thomas Hellstrom <thomas-at-tungstengraphics.com>
+ *	    Alan Cox <alan@linux.intel.com>
  */
 
 #include <drm/drmP.h>
 #include "psb_drv.h"
-#include "psb_pvr_glue.h"
 
+
+/*
+ *	GTT resource allocator - manage page mappings in GTT space
+ */
+
+/**
+ *	psb_gtt_mask_pte	-	generate GART pte entry
+ *	@pfn: page number to encode
+ *	@type: type of memory in the GART
+ *
+ *	Set the GART entry for the appropriate memory type.
+ */
 static inline uint32_t psb_gtt_mask_pte(uint32_t pfn, int type)
 {
 	uint32_t mask = PSB_PTE_VALID;
@@ -36,999 +48,492 @@
 	return (pfn << PAGE_SHIFT) | mask;
 }
 
-struct psb_gtt *psb_gtt_alloc(struct drm_device *dev)
-{
-	struct psb_gtt *tmp = kzalloc(sizeof(*tmp), GFP_KERNEL);
-
-	if (!tmp)
-		return NULL;
-
-	init_rwsem(&tmp->sem);
-	tmp->dev = dev;
-
-	return tmp;
-}
-
-void psb_gtt_takedown(struct psb_gtt *pg, int free)
+/**
+ *	psb_gtt_entry		-	find the GART entries for a gtt_range
+ *	@dev: our DRM device
+ *	@r: our GTT range
+ * 
+ *	Given a gtt_range object return the GART offset of the page table
+ *	entries for this gtt_range
+ */
+u32 *psb_gtt_entry(struct drm_device *dev, struct gtt_range *r)
 {
-	struct drm_psb_private *dev_priv = pg->dev->dev_private;
+        struct drm_psb_private *dev_priv = dev->dev_private;
+	unsigned long offset;
 
-	if (!pg)
-		return;
+	offset = r->resource.start - dev_priv->gtt_mem->start;
 
-	if (pg->gtt_map) {
-		iounmap(pg->gtt_map);
-		pg->gtt_map = NULL;
-	}
-	if (pg->initialized) {
-		pci_write_config_word(pg->dev->pdev, PSB_GMCH_CTRL,
-				      pg->gmch_ctrl);
-		PSB_WVDC32(pg->pge_ctl, PSB_PGETBL_CTL);
-		(void) PSB_RVDC32(PSB_PGETBL_CTL);
-	}
-	if (free)
-		kfree(pg);
+	return dev_priv->gtt_map + (offset >> PAGE_SHIFT);
 }
 
-int psb_gtt_init(struct psb_gtt *pg, int resume)
+/**
+ *	psb_gtt_insert	-	put an object into the GART
+ *	@dev: our DRM device
+ *	@r: our GTT range
+ *
+ *	Take our preallocated GTT range and insert the GEM object into
+ *	the GART.
+ *
+ *	FIXME: gtt lock ?
+ */
+static int psb_gtt_insert(struct drm_device *dev, struct gtt_range *r)
 {
-	struct drm_device *dev = pg->dev;
-	struct drm_psb_private *dev_priv = dev->dev_private;
-	unsigned gtt_pages;
-	unsigned long stolen_size, vram_stolen_size, ci_stolen_size;
-	unsigned long rar_stolen_size;
-	unsigned i, num_pages;
-	unsigned pfn_base;
-	uint32_t ci_pages, vram_pages;
-	uint32_t tt_pages;
-	uint32_t *ttm_gtt_map;
-	uint32_t dvmt_mode = 0;
-
-	int ret = 0;
-	uint32_t pte;
-
-	pci_read_config_word(dev->pdev, PSB_GMCH_CTRL, &pg->gmch_ctrl);
-	pci_write_config_word(dev->pdev, PSB_GMCH_CTRL,
-			      pg->gmch_ctrl | _PSB_GMCH_ENABLED);
-
-	pg->pge_ctl = PSB_RVDC32(PSB_PGETBL_CTL);
-	PSB_WVDC32(pg->pge_ctl | _PSB_PGETBL_ENABLED, PSB_PGETBL_CTL);
-	(void) PSB_RVDC32(PSB_PGETBL_CTL);
-
-	pg->initialized = 1;
-
-	pg->gtt_phys_start = pg->pge_ctl & PAGE_MASK;
-
-	pg->gatt_start = pci_resource_start(dev->pdev, PSB_GATT_RESOURCE);
-	/* fix me: video mmu has hw bug to access 0x0D0000000,
-	 * then make gatt start at 0x0e000,0000 */
-	pg->mmu_gatt_start = PSB_MEM_TT_START;
-	pg->gtt_start = pci_resource_start(dev->pdev, PSB_GTT_RESOURCE);
-	gtt_pages =
-	    pci_resource_len(dev->pdev, PSB_GTT_RESOURCE) >> PAGE_SHIFT;
-	pg->gatt_pages = pci_resource_len(dev->pdev, PSB_GATT_RESOURCE)
-	    >> PAGE_SHIFT;
-
-	pci_read_config_dword(dev->pdev, PSB_BSM, &pg->stolen_base);
-	vram_stolen_size = pg->gtt_phys_start - pg->stolen_base - PAGE_SIZE;
-
-	/* CI is not included in the stolen size since the TOPAZ MMU bug */
-	ci_stolen_size = dev_priv->ci_region_size;
-	/* Don't add CI & RAR share buffer space
-	 * managed by TTM to stolen_size */
-	stolen_size = vram_stolen_size;
-
-	rar_stolen_size = dev_priv->rar_region_size;
-
-	printk(KERN_INFO"GMMADR(region 0) start: 0x%08x (%dM).\n",
-		pg->gatt_start, pg->gatt_pages/256);
-	printk(KERN_INFO"GTTADR(region 3) start: 0x%08x (can map %dM RAM), and actual RAM base 0x%08x.\n",
-		pg->gtt_start, gtt_pages * 4, pg->gtt_phys_start);
-	printk(KERN_INFO "Stole memory information\n");
-	printk(KERN_INFO "      base in RAM: 0x%x\n", pg->stolen_base);
-	printk(KERN_INFO "      size: %luK, calculated by (GTT RAM base) - (Stolen base), seems wrong\n",
-		vram_stolen_size/1024);
-	dvmt_mode = (pg->gmch_ctrl >> 4) & 0x7;
-	printk(KERN_INFO "      the correct size should be: %dM(dvmt mode=%d)\n",
-		(dvmt_mode == 1) ? 1 : (2 << (dvmt_mode - 1)), dvmt_mode);
-
-	if (ci_stolen_size > 0)
-		printk(KERN_INFO"CI Stole memory: RAM base = 0x%08x, size = %lu M\n",
-				dev_priv->ci_region_start,
-				ci_stolen_size / 1024 / 1024);
-	if (rar_stolen_size > 0)
-		printk(KERN_INFO "RAR Stole memory: RAM base = 0x%08x, size = %lu M\n",
-			dev_priv->rar_region_start,
-			rar_stolen_size / 1024 / 1024);
-
-	if (resume && (gtt_pages != pg->gtt_pages) &&
-	    (stolen_size != pg->stolen_size)) {
-		DRM_ERROR("GTT resume error.\n");
-		ret = -EINVAL;
-		goto out_err;
-	}
-
-	pg->gtt_pages = gtt_pages;
-	pg->stolen_size = stolen_size;
-	pg->vram_stolen_size = vram_stolen_size;
-	pg->ci_stolen_size = ci_stolen_size;
-	pg->rar_stolen_size = rar_stolen_size;
-	pg->gtt_map =
-	    ioremap_nocache(pg->gtt_phys_start, gtt_pages << PAGE_SHIFT);
-	if (!pg->gtt_map) {
-		DRM_ERROR("Failure to map gtt.\n");
-		ret = -ENOMEM;
-		goto out_err;
-	}
-
-	pg->vram_addr = ioremap_wc(pg->stolen_base, stolen_size);
-	if (!pg->vram_addr) {
-		DRM_ERROR("Failure to map stolen base.\n");
-		ret = -ENOMEM;
-		goto out_err;
-	}
-
-	DRM_DEBUG("%s: vram kernel virtual address %p\n", pg->vram_addr);
-
-	tt_pages = (pg->gatt_pages < PSB_TT_PRIV0_PLIMIT) ?
-		(pg->gatt_pages) : PSB_TT_PRIV0_PLIMIT;
-
-	ttm_gtt_map = pg->gtt_map + tt_pages / 2;
-
-	/*
-	 * insert vram stolen pages.
-	 */
-
-	pfn_base = pg->stolen_base >> PAGE_SHIFT;
-	vram_pages = num_pages = vram_stolen_size >> PAGE_SHIFT;
-	printk(KERN_INFO"Set up %d stolen pages starting at 0x%08x, GTT offset %dK\n",
-		num_pages, pfn_base, 0);
-	for (i = 0; i < num_pages; ++i) {
-		pte = psb_gtt_mask_pte(pfn_base + i, 0);
-		iowrite32(pte, pg->gtt_map + i);
-	}
-
-	/*
-	 * Init rest of gtt managed by IMG.
-	 */
-	pfn_base = page_to_pfn(dev_priv->scratch_page);
-	pte = psb_gtt_mask_pte(pfn_base, 0);
-	for (; i < tt_pages / 2 - 1; ++i)
-		iowrite32(pte, pg->gtt_map + i);
-
-	/*
-	 * insert CI stolen pages
-	 */
-
-	pfn_base = dev_priv->ci_region_start >> PAGE_SHIFT;
-	ci_pages = num_pages = ci_stolen_size >> PAGE_SHIFT;
-	printk(KERN_INFO"Set up %d CI stolen pages starting at 0x%08x, GTT offset %dK\n",
-	       num_pages, pfn_base, (ttm_gtt_map - pg->gtt_map) * 4);
-	for (i = 0; i < num_pages; ++i) {
-		pte = psb_gtt_mask_pte(pfn_base + i, 0);
-		iowrite32(pte, ttm_gtt_map + i);
-	}
+        struct drm_psb_private *dev_priv = dev->dev_private;
+	u32 *gtt_slot, pte;
+	int numpages = (r->resource.end + 1 - r->resource.start) >> PAGE_SHIFT;
+	struct page **pages;
+	int i;
 
-	/*
-	 * insert RAR stolen pages
-	 */
-	if (rar_stolen_size != 0) {
-		pfn_base = dev_priv->rar_region_start >> PAGE_SHIFT;
-		num_pages = rar_stolen_size >> PAGE_SHIFT;
-		printk(KERN_INFO"Set up %d RAR stolen pages starting at 0x%08x, GTT offset %dK\n",
-			num_pages, pfn_base,
-			(ttm_gtt_map - pg->gtt_map + i) * 4);
-		for (; i < num_pages + ci_pages; ++i) {
-			pte = psb_gtt_mask_pte(pfn_base + i - ci_pages, 0);
-			iowrite32(pte, ttm_gtt_map + i);
-		}
+	if (r->pages == NULL) {
+		WARN_ON(1);
+		return -EINVAL;
 	}
-	/*
-	 * Init rest of gtt managed by TTM.
-	 */
-
-	pfn_base = page_to_pfn(dev_priv->scratch_page);
-	pte = psb_gtt_mask_pte(pfn_base, 0);
-	PSB_DEBUG_INIT("Initializing the rest of a total "
-		       "of %d gtt pages.\n", pg->gatt_pages);
-
-	for (; i < pg->gatt_pages - tt_pages / 2; ++i)
-		iowrite32(pte, ttm_gtt_map + i);
-	(void) ioread32(pg->gtt_map + i - 1);
 
-	return 0;
-
-out_err:
-	psb_gtt_takedown(pg, 0);
-	return ret;
-}
-
-int psb_gtt_insert_pages(struct psb_gtt *pg, struct page **pages,
-			 unsigned offset_pages, unsigned num_pages,
-			 unsigned desired_tile_stride,
-			 unsigned hw_tile_stride, int type)
-{
-	unsigned rows = 1;
-	unsigned add;
-	unsigned row_add;
-	unsigned i;
-	unsigned j;
-	uint32_t *cur_page = NULL;
-	uint32_t pte;
+	WARN_ON(r->stolen);	/* refcount these maybe ? */
 
-	if (hw_tile_stride)
-		rows = num_pages / desired_tile_stride;
-	else
-		desired_tile_stride = num_pages;
+	gtt_slot = psb_gtt_entry(dev, r);
+	pages = r->pages;
 
-	add = desired_tile_stride;
-	row_add = hw_tile_stride;
+	/* Make sure we have no alias present */
+	wbinvd();
 
-	down_read(&pg->sem);
-	for (i = 0; i < rows; ++i) {
-		cur_page = pg->gtt_map + offset_pages;
-		for (j = 0; j < desired_tile_stride; ++j) {
-			pte =
-			    psb_gtt_mask_pte(page_to_pfn(*pages++), type);
-			iowrite32(pte, cur_page++);
-		}
-		offset_pages += add;
+	/* Write our page entries into the GART itself */
+	for (i = 0; i < numpages; i++) {
+		pte = psb_gtt_mask_pte(page_to_pfn(*pages++), 0/*type*/);
+		iowrite32(pte, gtt_slot++);
 	}
-	(void) ioread32(cur_page - 1);
-	up_read(&pg->sem);
-
+	/* Make sure all the entries are set before we return */
+	ioread32(gtt_slot - 1);
+	
 	return 0;
 }
 
-int psb_gtt_insert_phys_addresses(struct psb_gtt *pg, dma_addr_t *pPhysFrames,
-			unsigned offset_pages, unsigned num_pages, int type)
-{
-	unsigned j;
-	uint32_t *cur_page = NULL;
-	uint32_t pte;
-	u32 ba;
-
-	down_read(&pg->sem);
-	cur_page = pg->gtt_map + offset_pages;
-	for (j = 0; j < num_pages; ++j) {
-		ba = *pPhysFrames++;
-		pte =  psb_gtt_mask_pte(ba >> PAGE_SHIFT, type);
-		iowrite32(pte, cur_page++);
-	}
-	(void) ioread32(cur_page - 1);
-	up_read(&pg->sem);
-	return 0;
-}
+/**
+ *	psb_gtt_remove	-	remove an object from the GART
+ *	@dev: our DRM device
+ *	@r: our GTT range
+ *
+ *	Remove a preallocated GTT range from the GART. Overwrite all the
+ *	page table entries with the dummy page
+ */
 
-int psb_gtt_remove_pages(struct psb_gtt *pg, unsigned offset_pages,
-			 unsigned num_pages, unsigned desired_tile_stride,
-			 unsigned hw_tile_stride, int rc_prot)
+static void psb_gtt_remove(struct drm_device *dev, struct gtt_range *r)
 {
-	struct drm_psb_private *dev_priv = pg->dev->dev_private;
-	unsigned rows = 1;
-	unsigned add;
-	unsigned row_add;
-	unsigned i;
-	unsigned j;
-	uint32_t *cur_page = NULL;
-	unsigned pfn_base = page_to_pfn(dev_priv->scratch_page);
-	uint32_t pte = psb_gtt_mask_pte(pfn_base, 0);
-
-	if (hw_tile_stride)
-		rows = num_pages / desired_tile_stride;
-	else
-		desired_tile_stride = num_pages;
-
-	add = desired_tile_stride;
-	row_add = hw_tile_stride;
+	struct drm_psb_private *dev_priv = dev->dev_private;
+	u32 *gtt_slot, pte;
+	int numpages = (r->resource.end + 1 - r->resource.start) >> PAGE_SHIFT;
+	int i;
 
-	if (rc_prot)
-		down_read(&pg->sem);
-	for (i = 0; i < rows; ++i) {
-		cur_page = pg->gtt_map + offset_pages;
-		for (j = 0; j < desired_tile_stride; ++j)
-			iowrite32(pte, cur_page++);
+	WARN_ON(r->stolen);
 
-		offset_pages += add;
-	}
-	(void) ioread32(cur_page - 1);
-	if (rc_prot)
-		up_read(&pg->sem);
+	gtt_slot = psb_gtt_entry(dev, r);
+	pte = psb_gtt_mask_pte(page_to_pfn(dev_priv->scratch_page), 0);;
 
-	return 0;
+	for (i = 0; i < numpages; i++)
+		iowrite32(pte, gtt_slot++);
+	ioread32(gtt_slot - 1);
 }
 
-int psb_gtt_mm_init(struct psb_gtt *pg)
+/**
+ *	psb_gtt_attach_pages	-	attach and pin GEM pages
+ *	@gt: the gtt range
+ *
+ *	Pin and build an in kernel list of the pages that back our GEM object.
+ *	While we hold this the pages cannot be swapped out
+ *
+ *	FIXME: Do we need to cache flush when we update the GTT
+ */
+static int psb_gtt_attach_pages(struct gtt_range *gt)
 {
-	struct psb_gtt_mm *gtt_mm;
-	struct drm_psb_private *dev_priv = pg->dev->dev_private;
-	struct drm_open_hash *ht;
-	struct drm_mm *mm;
-	int ret;
-	uint32_t tt_start;
-	uint32_t tt_size;
-
-	if (!pg || !pg->initialized) {
-		DRM_DEBUG("Invalid gtt struct\n");
-		return -EINVAL;
-	}
-
-	gtt_mm =  kzalloc(sizeof(struct psb_gtt_mm), GFP_KERNEL);
-	if (!gtt_mm)
-		return -ENOMEM;
-
-	spin_lock_init(&gtt_mm->lock);
-
-	ht = &gtt_mm->hash;
-	ret = drm_ht_create(ht, 20);
-	if (ret) {
-		DRM_DEBUG("Create hash table failed(%d)\n", ret);
-		goto err_free;
-	}
+	struct inode *inode;
+	struct address_space *mapping;
+	int i;
+	struct page *p;
+	int pages = (gt->resource.end + 1 - gt->resource.start) >> PAGE_SHIFT;
 
-	tt_start = (pg->stolen_size + PAGE_SIZE - 1) >> PAGE_SHIFT;
-	tt_start = (tt_start < pg->gatt_pages) ? tt_start : pg->gatt_pages;
-	tt_size = (pg->gatt_pages < PSB_TT_PRIV0_PLIMIT) ?
-			(pg->gatt_pages) : PSB_TT_PRIV0_PLIMIT;
+	WARN_ON(gt->pages);
 
-	mm = &gtt_mm->base;
+	/* This is the shared memory object that backs the GEM resource */
+	inode = gt->gem.filp->f_path.dentry->d_inode;
+	mapping = inode->i_mapping;
 
-	/*will use tt_start ~ 128M for IMG TT buffers*/
-	ret = drm_mm_init(mm, tt_start, ((tt_size / 2) - tt_start));
-	if (ret) {
-		DRM_DEBUG("drm_mm_int error(%d)\n", ret);
-		goto err_mm_init;
+	gt->pages = kmalloc(pages * sizeof(struct page *), GFP_KERNEL);
+	if (gt->pages == NULL)
+		return -ENOMEM;
+	for (i = 0; i < pages; i++) {
+		/* FIXME: review flags later */
+		p = read_cache_page_gfp(mapping, i,
+					__GFP_COLD | GFP_KERNEL);
+		if (IS_ERR(p))
+			goto err;
+		gt->pages[i] = p;
 	}
-
-	gtt_mm->count = 0;
-
-	dev_priv->gtt_mm = gtt_mm;
-
-	DRM_INFO("PSB GTT mem manager ready, tt_start %ld, tt_size %ld pages\n",
-		(unsigned long)tt_start,
-		(unsigned long)((tt_size / 2) - tt_start));
 	return 0;
-err_mm_init:
-	drm_ht_remove(ht);
 
-err_free:
-	kfree(gtt_mm);
-	return ret;
+err:
+	while (i--)
+		page_cache_release(gt->pages[i]);
+	kfree(gt->pages);
+	gt->pages = NULL;
+	return PTR_ERR(p);
 }
 
 /**
- * Delete all hash entries;
+ *	psb_gtt_detach_pages	-	attach and pin GEM pages
+ *	@gt: the gtt range
+ *
+ *	Undo the effect of psb_gtt_attach_pages. At this point the pages
+ *	must have been removed from the GART as they could now be paged out
+ *	and move bus address.
+ *
+ *	FIXME: Do we need to cache flush when we update the GTT
  */
-void psb_gtt_mm_takedown(void)
-{
-	return;
-}
-
-static int psb_gtt_mm_get_ht_by_pid_locked(struct psb_gtt_mm *mm,
-				    u32 tgid,
-				    struct psb_gtt_hash_entry **hentry)
+static void psb_gtt_detach_pages(struct gtt_range *gt)
 {
-	struct drm_hash_item *entry;
-	struct psb_gtt_hash_entry *psb_entry;
-	int ret;
-
-	ret = drm_ht_find_item(&mm->hash, tgid, &entry);
-	if (ret) {
-		DRM_DEBUG("Cannot find entry pid=%ld\n", tgid);
-		return ret;
-	}
+	int i;
+	int pages = (gt->resource.end + 1 - gt->resource.start) >> PAGE_SHIFT;
 
-	psb_entry = container_of(entry, struct psb_gtt_hash_entry, item);
-	if (!psb_entry) {
-		DRM_DEBUG("Invalid entry");
-		return -EINVAL;
+	for (i = 0; i < pages; i++) {
+		/* FIXME: do we need to force dirty */
+		set_page_dirty(gt->pages[i]);
+		/* Undo the reference we took when populating the table */
+		page_cache_release(gt->pages[i]);
 	}
-
-	*hentry = psb_entry;
-	return 0;
+	kfree(gt->pages);
+	gt->pages = NULL;
 }
 
-
-static int psb_gtt_mm_insert_ht_locked(struct psb_gtt_mm *mm,
-				       u32 tgid,
-				       struct psb_gtt_hash_entry *hentry)
+/**
+ *	psb_gtt_pin		-	pin pages into the GTT
+ *	@gt: range to pin
+ *
+ *	Pin a set of pages into the GTT. The pins are refcounted so that
+ *	multiple pins need multiple unpins to undo.
+ *
+ *	Non GEM backed objects treat this as a no-op as they are always GTT
+ *	backed objects.
+ */
+int psb_gtt_pin(struct gtt_range *gt)
 {
-	struct drm_hash_item *item;
 	int ret;
+	struct drm_device *dev = gt->gem.dev;
+	struct drm_psb_private *dev_priv = dev->dev_private;
 
-	if (!hentry) {
-		DRM_DEBUG("Invalid parameters\n");
-		return -EINVAL;
-	}
-
-	item = &hentry->item;
-	item->key = tgid;
-
-	/**
-	 * NOTE: drm_ht_insert_item will perform such a check
-	ret = psb_gtt_mm_get_ht_by_pid(mm, tgid, &tmp);
-	if (!ret) {
-		DRM_DEBUG("Entry already exists for pid %ld\n", tgid);
-		return -EAGAIN;
-	}
-	*/
+	mutex_lock(&dev_priv->gtt_mutex);
 
-	/*Insert the given entry*/
-	ret = drm_ht_insert_item(&mm->hash, item);
-	if (ret) {
-		DRM_DEBUG("Insert failure\n");
-		return ret;
+	if (gt->in_gart == 0 && gt->stolen == 0) {
+		ret = psb_gtt_attach_pages(gt);
+		if (ret < 0)
+			goto out;
+		ret = psb_gtt_insert(dev, gt);
+		if (ret < 0) {
+			psb_gtt_detach_pages(gt);
+			goto out;
+		}
 	}
-
-	mm->count++;
-
-	return 0;
+	gt->in_gart++;
+out:
+	mutex_unlock(&dev_priv->gtt_mutex);
+	return ret;
 }
 
-static int psb_gtt_mm_alloc_insert_ht(struct psb_gtt_mm *mm,
-				      u32 tgid,
-				      struct psb_gtt_hash_entry **entry)
+/**
+ *	psb_gtt_unpin		-	Drop a GTT pin requirement
+ *	@gt: range to pin
+ *
+ *	Undoes the effect of psb_gtt_pin. On the last drop the GEM object
+ *	will be removed from the GTT which will also drop the page references
+ *	and allow the VM to clean up or page stuff.
+ *
+ *	Non GEM backed objects treat this as a no-op as they are always GTT
+ *	backed objects.
+ */
+void psb_gtt_unpin(struct gtt_range *gt)
 {
-	struct psb_gtt_hash_entry *hentry;
-	int ret;
-
-	/*if the hentry for this tgid exists, just get it and return*/
-	spin_lock(&mm->lock);
-	ret = psb_gtt_mm_get_ht_by_pid_locked(mm, tgid, &hentry);
-	if (!ret) {
-		DRM_DEBUG("Entry for tgid %ld exist, hentry %p\n",
-			  tgid, hentry);
-		*entry = hentry;
-		spin_unlock(&mm->lock);
-		return 0;
-	}
-	spin_unlock(&mm->lock);
+	struct drm_device *dev = gt->gem.dev;
+	struct drm_psb_private *dev_priv = dev->dev_private;
 
-	DRM_DEBUG("Entry for tgid %ld doesn't exist, will create it\n", tgid);
+	mutex_lock(&dev_priv->gtt_mutex);
 
-	hentry = kzalloc(sizeof(struct psb_gtt_hash_entry), GFP_KERNEL);
-	if (!hentry) {
-		DRM_DEBUG("Kmalloc failled\n");
-		return -ENOMEM;
-	}
+	WARN_ON(!gt->in_gart);
 
-	ret = drm_ht_create(&hentry->ht, 20);
-	if (ret) {
-		DRM_DEBUG("Create hash table failed\n");
-		return ret;
+	gt->in_gart--;
+	if (gt->in_gart == 0 && gt->stolen == 0) {
+		psb_gtt_remove(dev, gt);
+		psb_gtt_detach_pages(gt);
 	}
-
-	spin_lock(&mm->lock);
-	ret = psb_gtt_mm_insert_ht_locked(mm, tgid, hentry);
-	spin_unlock(&mm->lock);
-
-	if (!ret)
-		*entry = hentry;
-
-	return ret;
+	mutex_unlock(&dev_priv->gtt_mutex);
 }
+	
+/*
+ *	GTT resource allocator - allocate and manage GTT address space
+ */
 
-static struct psb_gtt_hash_entry *
-psb_gtt_mm_remove_ht_locked(struct psb_gtt_mm *mm, u32 tgid)
+/**
+ *	psb_gtt_alloc_range	-	allocate GTT address space
+ *	@dev: Our DRM device
+ *	@len: length (bytes) of address space required
+ *	@name: resource name
+ *	@backed: resource should be backed by stolen pages
+ *
+ *	Ask the kernel core to find us a suitable range of addresses
+ *	to use for a GTT mapping.
+ *
+ *	Returns a gtt_range structure describing the object, or NULL on
+ *	error. On successful return the resource is both allocated and marked
+ *	as in use.
+ */
+struct gtt_range *psb_gtt_alloc_range(struct drm_device *dev, int len,
+						const char *name, int backed)
 {
-	struct psb_gtt_hash_entry *tmp;
+	struct drm_psb_private *dev_priv = dev->dev_private;
+	struct gtt_range *gt;
+	struct resource *r = dev_priv->gtt_mem;
 	int ret;
+	unsigned long start, end;
+	
+	if (backed) {
+	        /* The start of the GTT is the stolen pages */
+	        start = r->start;
+	        end = r->start + dev_priv->pg->stolen_size - 1;
+        } else {
+                /* The rest we will use for GEM backed objects */
+                start = r->start + dev_priv->pg->stolen_size;
+                end = r->end;
+        }
 
-	ret = psb_gtt_mm_get_ht_by_pid_locked(mm, tgid, &tmp);
-	if (ret) {
-		DRM_DEBUG("Cannot find entry pid %ld\n", tgid);
+	gt = kzalloc(sizeof(struct gtt_range), GFP_KERNEL);
+	if (gt == NULL)
 		return NULL;
-	}
-
-	/*remove it from ht*/
-	drm_ht_remove_item(&mm->hash, &tmp->item);
-
-	mm->count--;
+        gt->resource.name = name;
+        gt->stolen = backed;
+        gt->in_gart = backed;
+        /* Ensure this is set for non GEM objects */
+        gt->gem.dev = dev;
+	kref_init(&gt->kref);
 
-	return tmp;
+	ret = allocate_resource(dev_priv->gtt_mem, &gt->resource,
+				len, start, end, PAGE_SIZE, NULL, NULL);
+	if (ret == 0) {
+	        gt->offset = gt->resource.start - r->start;
+		return gt;
+        }
+	kfree(gt);
+	return NULL;
 }
 
-static int psb_gtt_mm_remove_free_ht_locked(struct psb_gtt_mm *mm, u32 tgid)
+/**
+ *	psb_gtt_destroy		-	final free up of a gtt
+ *	@kref: the kref of the gtt
+ *
+ *	Called from the kernel kref put when the final reference to our
+ *	GTT object is dropped. At that point we can free up the resources.
+ *
+ *	For now we handle mmap clean up here to work around limits in GEM
+ */
+static void psb_gtt_destroy(struct kref *kref)
 {
-	struct psb_gtt_hash_entry *entry;
-
-	entry = psb_gtt_mm_remove_ht_locked(mm, tgid);
+	struct gtt_range *gt = container_of(kref, struct gtt_range, kref);
 
-	if (!entry) {
-		DRM_DEBUG("Invalid entry");
-		return -EINVAL;
+	/* Undo the mmap pin if we are destroying the object */
+	if (gt->mmapping) {
+		psb_gtt_unpin(gt);
+		gt->mmapping = 0;
 	}
-
-	/*delete ht*/
-	drm_ht_remove(&entry->ht);
-
-	/*free this entry*/
-	kfree(entry);
-	return 0;
+	WARN_ON(gt->in_gart && !gt->stolen);
+	release_resource(&gt->resource);
+	kfree(gt);
 }
 
-static int
-psb_gtt_mm_get_mem_mapping_locked(struct drm_open_hash *ht,
-			   u32 key,
-			   struct psb_gtt_mem_mapping **hentry)
+/**
+ *	psb_gtt_kref_put	-	drop reference to a GTT object
+ *	@gt: the GT being dropped
+ *
+ *	Drop a reference to a psb gtt
+ */
+void psb_gtt_kref_put(struct gtt_range *gt)
 {
-	struct drm_hash_item *entry;
-	struct psb_gtt_mem_mapping *mapping;
-	int ret;
-
-	ret = drm_ht_find_item(ht, key, &entry);
-	if (ret) {
-		DRM_DEBUG("Cannot find key %ld\n", key);
-		return ret;
-	}
-
-	mapping =  container_of(entry, struct psb_gtt_mem_mapping, item);
-	if (!mapping) {
-		DRM_DEBUG("Invalid entry\n");
-		return -EINVAL;
-	}
-
-	*hentry = mapping;
-	return 0;
+	kref_put(&gt->kref, psb_gtt_destroy);
 }
 
-static int
-psb_gtt_mm_insert_mem_mapping_locked(struct drm_open_hash *ht,
-			      u32 key,
-			      struct psb_gtt_mem_mapping *hentry)
+/**
+ *	psb_gtt_free_range	-	release GTT address space
+ *	@dev: our DRM device
+ *	@gt: a mapping created with psb_gtt_alloc_range
+ *
+ *	Release a resource that was allocated with psb_gtt_alloc_range
+ */
+void psb_gtt_free_range(struct drm_device *dev, struct gtt_range *gt)
 {
-	struct drm_hash_item *item;
-	struct psb_gtt_hash_entry *entry;
-	int ret;
-
-	if (!hentry) {
-		DRM_DEBUG("hentry is NULL\n");
-		return -EINVAL;
-	}
-
-	item = &hentry->item;
-	item->key = key;
-
-	ret = drm_ht_insert_item(ht, item);
-	if (ret) {
-		DRM_DEBUG("insert_item failed\n");
-		return ret;
-	}
-
-	entry = container_of(ht, struct psb_gtt_hash_entry, ht);
-	if (entry)
-		entry->count++;
-
-	return 0;
+	psb_gtt_kref_put(gt);
 }
 
-static int
-psb_gtt_mm_alloc_insert_mem_mapping(struct psb_gtt_mm *mm,
-				    struct drm_open_hash *ht,
-				    u32 key,
-				    struct drm_mm_node *node,
-				    struct psb_gtt_mem_mapping **entry)
-{
-	struct psb_gtt_mem_mapping *mapping;
-	int ret;
 
-	if (!node || !ht) {
-		DRM_DEBUG("parameter error\n");
-		return -EINVAL;
-	}
-
-	/*try to get this mem_map */
-	spin_lock(&mm->lock);
-	ret = psb_gtt_mm_get_mem_mapping_locked(ht, key, &mapping);
-	if (!ret) {
-		DRM_DEBUG("mapping entry for key %ld exists, entry %p\n",
-			  key, mapping);
-		*entry = mapping;
-		spin_unlock(&mm->lock);
-		return 0;
-	}
-	spin_unlock(&mm->lock);
-
-	DRM_DEBUG("Mapping entry for key %ld doesn't exist, will create it\n",
-		  key);
-
-	mapping = kzalloc(sizeof(struct psb_gtt_mem_mapping), GFP_KERNEL);
-	if (!mapping) {
-		DRM_DEBUG("kmalloc failed\n");
-		return -ENOMEM;
-	}
-
-	mapping->node = node;
-
-	spin_lock(&mm->lock);
-	ret = psb_gtt_mm_insert_mem_mapping_locked(ht, key, mapping);
-	spin_unlock(&mm->lock);
-
-	if (!ret)
-		*entry = mapping;
-
-	return ret;
-}
-
-static struct psb_gtt_mem_mapping *
-psb_gtt_mm_remove_mem_mapping_locked(struct drm_open_hash *ht, u32 key)
+struct psb_gtt *psb_gtt_alloc(struct drm_device *dev)
 {
-	struct psb_gtt_mem_mapping *tmp;
-	struct psb_gtt_hash_entry *entry;
-	int ret;
+	struct psb_gtt *tmp = kzalloc(sizeof(*tmp), GFP_KERNEL);
 
-	ret = psb_gtt_mm_get_mem_mapping_locked(ht, key, &tmp);
-	if (ret) {
-		DRM_DEBUG("Cannot find key %ld\n", key);
+	if (!tmp)
 		return NULL;
-	}
-
-	drm_ht_remove_item(ht, &tmp->item);
 
-	entry = container_of(ht, struct psb_gtt_hash_entry, ht);
-	if (entry)
-		entry->count--;
+	init_rwsem(&tmp->sem);
+	tmp->dev = dev;
 
 	return tmp;
 }
 
-static int psb_gtt_mm_remove_free_mem_mapping_locked(struct drm_open_hash *ht,
-					      u32 key,
-					      struct drm_mm_node **node)
-{
-	struct psb_gtt_mem_mapping *entry;
-
-	entry = psb_gtt_mm_remove_mem_mapping_locked(ht, key);
-	if (!entry) {
-		DRM_DEBUG("entry is NULL\n");
-		return -EINVAL;
-	}
-
-	*node = entry->node;
-
-	kfree(entry);
-	return 0;
-}
-
-static int psb_gtt_add_node(struct psb_gtt_mm *mm,
-			    u32 tgid,
-			    u32 key,
-			    struct drm_mm_node *node,
-			    struct psb_gtt_mem_mapping **entry)
-{
-	struct psb_gtt_hash_entry *hentry;
-	struct psb_gtt_mem_mapping *mapping;
-	int ret;
-
-	ret = psb_gtt_mm_alloc_insert_ht(mm, tgid, &hentry);
-	if (ret) {
-		DRM_DEBUG("alloc_insert failed\n");
-		return ret;
-	}
-
-	ret = psb_gtt_mm_alloc_insert_mem_mapping(mm,
-						  &hentry->ht,
-						  key,
-						  node,
-						  &mapping);
-	if (ret) {
-		DRM_DEBUG("mapping alloc_insert failed\n");
-		return ret;
-	}
-
-	*entry = mapping;
-
-	return 0;
-}
-
-static int psb_gtt_remove_node(struct psb_gtt_mm *mm,
-			       u32 tgid,
-			       u32 key,
-			       struct drm_mm_node **node)
+void psb_gtt_takedown(struct drm_device *dev)
 {
-	struct psb_gtt_hash_entry *hentry;
-	struct drm_mm_node *tmp;
-	int ret;
-
-	spin_lock(&mm->lock);
-	ret = psb_gtt_mm_get_ht_by_pid_locked(mm, tgid, &hentry);
-	if (ret) {
-		DRM_DEBUG("Cannot find entry for pid %ld\n", tgid);
-		spin_unlock(&mm->lock);
-		return ret;
-	}
-	spin_unlock(&mm->lock);
+	struct drm_psb_private *dev_priv = dev->dev_private;
 
-	/*remove mapping entry*/
-	spin_lock(&mm->lock);
-	ret = psb_gtt_mm_remove_free_mem_mapping_locked(&hentry->ht,
-							key,
-							&tmp);
-	if (ret) {
-		DRM_DEBUG("remove_free failed\n");
-		spin_unlock(&mm->lock);
-		return ret;
+	/* FIXME: iounmap dev_priv->vram_addr etc */
+	if (dev_priv->gtt_map) {
+		iounmap(dev_priv->gtt_map);
+		dev_priv->gtt_map = NULL;
 	}
-
-	*node = tmp;
-
-	/*check the count of mapping entry*/
-	if (!hentry->count) {
-		DRM_DEBUG("count of mapping entry is zero, tgid=%ld\n", tgid);
-		psb_gtt_mm_remove_free_ht_locked(mm, tgid);
+	if (dev_priv->gtt_initialized) {
+		pci_write_config_word(dev->pdev, PSB_GMCH_CTRL,
+				      dev_priv->gmch_ctrl);
+		PSB_WVDC32(dev_priv->pge_ctl, PSB_PGETBL_CTL);
+		(void) PSB_RVDC32(PSB_PGETBL_CTL);
 	}
-
-	spin_unlock(&mm->lock);
-
-	return 0;
+	kfree(dev_priv->pg);
+	dev_priv->pg = NULL;
 }
 
-static int psb_gtt_mm_alloc_mem(struct psb_gtt_mm *mm,
-				uint32_t pages,
-				uint32_t align,
-				struct drm_mm_node **node)
+int psb_gtt_init(struct drm_device *dev, int resume)
 {
-	struct drm_mm_node *tmp_node;
-	int ret;
-
-	do {
-		ret = drm_mm_pre_get(&mm->base);
-		if (unlikely(ret)) {
-			DRM_DEBUG("drm_mm_pre_get error\n");
-			return ret;
-		}
+	struct drm_psb_private *dev_priv = dev->dev_private;
+	unsigned gtt_pages;
+	unsigned long stolen_size, vram_stolen_size;
+	unsigned i, num_pages;
+	unsigned pfn_base;
+	uint32_t vram_pages;
+	uint32_t tt_pages;
+	uint32_t *ttm_gtt_map;
+	uint32_t dvmt_mode = 0;
+	struct psb_gtt *pg;
 
-		spin_lock(&mm->lock);
-		tmp_node = drm_mm_search_free(&mm->base, pages, align, 1);
-		if (unlikely(!tmp_node)) {
-			DRM_DEBUG("No free node found\n");
-			spin_unlock(&mm->lock);
-			break;
-		}
+	int ret = 0;
+	uint32_t pte;
 
-		tmp_node = drm_mm_get_block_atomic(tmp_node, pages, align);
-		spin_unlock(&mm->lock);
-	} while (!tmp_node);
+	mutex_init(&dev_priv->gtt_mutex);
 
-	if (!tmp_node) {
-		DRM_DEBUG("Node allocation failed\n");
-		return -ENOMEM;
-	}
+	dev_priv->pg = pg = psb_gtt_alloc(dev);
+	if (pg == NULL)
+	        return -ENOMEM;
 
-	*node = tmp_node;
-	return 0;
-}
+	pci_read_config_word(dev->pdev, PSB_GMCH_CTRL, &dev_priv->gmch_ctrl);
+	pci_write_config_word(dev->pdev, PSB_GMCH_CTRL,
+			      dev_priv->gmch_ctrl | _PSB_GMCH_ENABLED);
 
-static void psb_gtt_mm_free_mem(struct psb_gtt_mm *mm, struct drm_mm_node *node)
-{
-	spin_lock(&mm->lock);
-	drm_mm_put_block(node);
-	spin_unlock(&mm->lock);
-}
+	dev_priv->pge_ctl = PSB_RVDC32(PSB_PGETBL_CTL);
+	PSB_WVDC32(dev_priv->pge_ctl | _PSB_PGETBL_ENABLED, PSB_PGETBL_CTL);
+	(void) PSB_RVDC32(PSB_PGETBL_CTL);
 
-int psb_gtt_map_meminfo(struct drm_device *dev,
-			void *hKernelMemInfo,
-			uint32_t *offset)
-{
-	return -EINVAL;
-	/* FIXMEAC */
-#if 0
-	struct drm_psb_private *dev_priv
-	       = (struct drm_psb_private *)dev->dev_private;
-	void *psKernelMemInfo;
-	struct psb_gtt_mm *mm = dev_priv->gtt_mm;
-	struct psb_gtt *pg = dev_priv->pg;
-	uint32_t size, pages, offset_pages;
-	void *kmem;
-	struct drm_mm_node *node;
-	struct page **page_list;
-	struct psb_gtt_mem_mapping *mapping = NULL;
-	int ret;
+	/* The root resource we allocate address space from */
+	dev_priv->gtt_mem = &dev->pdev->resource[PSB_GATT_RESOURCE];
 
-	ret = psb_get_meminfo_by_handle(hKernelMemInfo, &psKernelMemInfo);
-	if (ret) {
-		DRM_DEBUG("Cannot find kernelMemInfo handle %ld\n",
-			  hKernelMemInfo);
-		return -EINVAL;
-	}
+	dev_priv->gtt_initialized = 1;
 
-	DRM_DEBUG("Got psKernelMemInfo %p for handle %lx\n",
-		  psKernelMemInfo, (u32)hKernelMemInfo);
-	size = psKernelMemInfo->ui32AllocSize;
-	kmem = psKernelMemInfo->pvLinAddrKM;
-	pages = (size + PAGE_SIZE - 1) >> PAGE_SHIFT;
+	pg->gtt_phys_start = dev_priv->pge_ctl & PAGE_MASK;
 
-	DRM_DEBUG("KerMemInfo size %ld, cpuVadr %lx, pages %ld, osMemHdl %lx\n",
-		  size, kmem, pages, psKernelMemInfo->sMemBlk.hOSMemHandle);
+	pg->gatt_start = pci_resource_start(dev->pdev, PSB_GATT_RESOURCE);
+	/* fix me: video mmu has hw bug to access 0x0D0000000,
+	 * then make gatt start at 0x0e000,0000 */
+	pg->mmu_gatt_start = 0xE0000000;
+	pg->gtt_start = pci_resource_start(dev->pdev, PSB_GTT_RESOURCE);
+	gtt_pages =
+	    pci_resource_len(dev->pdev, PSB_GTT_RESOURCE) >> PAGE_SHIFT;
+	pg->gatt_pages = pci_resource_len(dev->pdev, PSB_GATT_RESOURCE)
+	    >> PAGE_SHIFT;
 
-	if (!kmem)
-		DRM_DEBUG("kmem is NULL");
+	pci_read_config_dword(dev->pdev, PSB_BSM, &dev_priv->stolen_base);
+	vram_stolen_size = pg->gtt_phys_start - dev_priv->stolen_base - PAGE_SIZE;
 
-	/*get pages*/
-	ret = psb_get_pages_by_mem_handle(psKernelMemInfo->sMemBlk.hOSMemHandle,
-					  &page_list);
-	if (ret) {
-		DRM_DEBUG("get pages error\n");
-		return ret;
-	}
+	stolen_size = vram_stolen_size;
 
-	DRM_DEBUG("get %ld pages\n", pages);
+	printk(KERN_INFO"GMMADR(region 0) start: 0x%08x (%dM).\n",
+		pg->gatt_start, pg->gatt_pages/256);
+	printk(KERN_INFO"GTTADR(region 3) start: 0x%08x (can map %dM RAM), and actual RAM base 0x%08x.\n",
+		pg->gtt_start, gtt_pages * 4, pg->gtt_phys_start);
+	printk(KERN_INFO "Stolen memory information\n");
+	printk(KERN_INFO "       base in RAM: 0x%x\n", dev_priv->stolen_base);
+	printk(KERN_INFO "       size: %luK, calculated by (GTT RAM base) - (Stolen base), seems wrong\n",
+		vram_stolen_size/1024);
+	dvmt_mode = (dev_priv->gmch_ctrl >> 4) & 0x7;
+	printk(KERN_INFO "      the correct size should be: %dM(dvmt mode=%d)\n",
+		(dvmt_mode == 1) ? 1 : (2 << (dvmt_mode - 1)), dvmt_mode);
 
-	/*alloc memory in TT apeture*/
-	ret = psb_gtt_mm_alloc_mem(mm, pages, 0, &node);
-	if (ret) {
-		DRM_DEBUG("alloc TT memory error\n");
-		goto failed_pages_alloc;
+	if (resume && (gtt_pages != pg->gtt_pages) &&
+	    (stolen_size != pg->stolen_size)) {
+		DRM_ERROR("GTT resume error.\n");
+		ret = -EINVAL;
+		goto out_err;
 	}
 
-	/*update psb_gtt_mm*/
-	ret = psb_gtt_add_node(mm,
-			       task_tgid_nr(current),
-			       (u32)hKernelMemInfo,
-			       node,
-			       &mapping);
-	if (ret) {
-		DRM_DEBUG("add_node failed");
-		goto failed_add_node;
+	pg->gtt_pages = gtt_pages;
+	pg->stolen_size = stolen_size;
+	dev_priv->vram_stolen_size = vram_stolen_size;
+	dev_priv->gtt_map =
+	    ioremap_nocache(pg->gtt_phys_start, gtt_pages << PAGE_SHIFT);
+	if (!dev_priv->gtt_map) {
+		DRM_ERROR("Failure to map gtt.\n");
+		ret = -ENOMEM;
+		goto out_err;
 	}
 
-	node = mapping->node;
-	offset_pages = node->start;
-
-	DRM_DEBUG("get free node for %ld pages, offset %ld pages",
-		  pages, offset_pages);
-
-	/*update gtt*/
-	psb_gtt_insert_pages(pg, page_list,
-			     (unsigned)offset_pages,
-			     (unsigned)pages,
-			     0,
-			     0,
-			     0);
-
-	*offset = offset_pages;
-	return 0;
-
-failed_add_node:
-	psb_gtt_mm_free_mem(mm, node);
-failed_pages_alloc:
-	kfree(page_list);
-	return ret;
-#endif
-}
-
-int psb_gtt_unmap_meminfo(struct drm_device *dev, void * hKernelMemInfo)
-{
-	struct drm_psb_private *dev_priv
-	       = (struct drm_psb_private *)dev->dev_private;
-	struct psb_gtt_mm *mm = dev_priv->gtt_mm;
-	struct psb_gtt *pg = dev_priv->pg;
-	uint32_t pages, offset_pages;
-	struct drm_mm_node *node;
-	int ret;
-
-	ret = psb_gtt_remove_node(mm,
-			task_tgid_nr(current),
-			(u32)hKernelMemInfo,
-			&node);
-	if (ret) {
-		DRM_DEBUG("remove node failed\n");
-		return ret;
+	dev_priv->vram_addr = ioremap_wc(dev_priv->stolen_base, stolen_size);
+	if (!dev_priv->vram_addr) {
+		DRM_ERROR("Failure to map stolen base.\n");
+		ret = -ENOMEM;
+		goto out_err;
 	}
 
-	/*remove gtt entries*/
-	offset_pages = node->start;
-	pages = node->size;
-
-	psb_gtt_remove_pages(pg, offset_pages, pages, 0, 0, 1);
-
-
-	/*free tt node*/
-
-	psb_gtt_mm_free_mem(mm, node);
-	return 0;
-}
-
-int psb_gtt_map_meminfo_ioctl(struct drm_device *dev, void *data,
-			       struct drm_file *file_priv)
-{
-	struct psb_gtt_mapping_arg *arg
-	       = (struct psb_gtt_mapping_arg *)data;
-	uint32_t *offset_pages = &arg->offset_pages;
-
-	DRM_DEBUG("\n");
-
-	return psb_gtt_map_meminfo(dev, arg->hKernelMemInfo, offset_pages);
-}
-
-int psb_gtt_unmap_meminfo_ioctl(struct drm_device *dev, void *data,
-				struct drm_file *file_priv)
-{
-
-	struct psb_gtt_mapping_arg *arg
-	       = (struct psb_gtt_mapping_arg *)data;
-
-	DRM_DEBUG("\n");
+	DRM_DEBUG("%s: vram kernel virtual address %p\n", dev_priv->vram_addr);
 
-	return psb_gtt_unmap_meminfo(dev, arg->hKernelMemInfo);
-}
+	tt_pages = (pg->gatt_pages < PSB_TT_PRIV0_PLIMIT) ?
+		(pg->gatt_pages) : PSB_TT_PRIV0_PLIMIT;
 
-int psb_gtt_map_pvr_memory(struct drm_device *dev,  unsigned int hHandle,
-			unsigned int ui32TaskId, dma_addr_t *pPages,
-			unsigned int ui32PagesNum, unsigned int *ui32Offset)
-{
-	struct drm_psb_private *dev_priv = dev->dev_private;
-	struct psb_gtt_mm *mm = dev_priv->gtt_mm;
-	struct psb_gtt *pg = dev_priv->pg;
-	uint32_t size, pages, offset_pages;
-	struct drm_mm_node *node = NULL;
-	struct psb_gtt_mem_mapping *mapping = NULL;
-	int ret;
+	ttm_gtt_map = dev_priv->gtt_map + tt_pages / 2;
 
-	size = ui32PagesNum * PAGE_SIZE;
-	pages = 0;
+	/*
+	 * insert vram stolen pages.
+	 */
 
-	/*alloc memory in TT apeture*/
-	ret = psb_gtt_mm_alloc_mem(mm, ui32PagesNum, 0, &node);
-	if (ret) {
-		DRM_DEBUG("alloc TT memory error\n");
-		goto failed_pages_alloc;
+	pfn_base = dev_priv->stolen_base >> PAGE_SHIFT;
+	vram_pages = num_pages = vram_stolen_size >> PAGE_SHIFT;
+	printk(KERN_INFO"Set up %d stolen pages starting at 0x%08x, GTT offset %dK\n",
+		num_pages, pfn_base, 0);
+	for (i = 0; i < num_pages; ++i) {
+		pte = psb_gtt_mask_pte(pfn_base + i, 0);
+		iowrite32(pte, dev_priv->gtt_map + i);
 	}
 
-   /*update psb_gtt_mm*/
-	ret = psb_gtt_add_node(mm,
-						   (u32)ui32TaskId,
-						   (u32)hHandle,
-						   node,
-						   &mapping);
-	if (ret) {
-		DRM_DEBUG("add_node failed");
-		goto failed_add_node;
-	}
+	/*
+	 * Init rest of gtt managed by IMG.
+	 */
+	pfn_base = page_to_pfn(dev_priv->scratch_page);
+	pte = psb_gtt_mask_pte(pfn_base, 0);
+	for (; i < tt_pages / 2 - 1; ++i)
+		iowrite32(pte, dev_priv->gtt_map + i);
 
-	node = mapping->node;
-	offset_pages = node->start;
+	/*
+	 * Init rest of gtt managed by TTM.
+	 */
 
-	DRM_DEBUG("get free node for %ld pages, offset %ld pages",
-							pages, offset_pages);
+	pfn_base = page_to_pfn(dev_priv->scratch_page);
+	pte = psb_gtt_mask_pte(pfn_base, 0);
+	PSB_DEBUG_INIT("Initializing the rest of a total "
+		       "of %d gtt pages.\n", pg->gatt_pages);
 
-	/*update gtt*/
-	psb_gtt_insert_phys_addresses(pg, pPages, (unsigned)offset_pages,
-						(unsigned)ui32PagesNum, 0);
+	for (; i < pg->gatt_pages - tt_pages / 2; ++i)
+		iowrite32(pte, ttm_gtt_map + i);
+	(void) ioread32(dev_priv->gtt_map + i - 1);
 
-	*ui32Offset = offset_pages;
 	return 0;
 
-failed_add_node:
-	psb_gtt_mm_free_mem(mm, node);
-failed_pages_alloc:
+out_err:
+	psb_gtt_takedown(dev);
 	return ret;
 }
-
-
-int psb_gtt_unmap_pvr_memory(struct drm_device *dev, unsigned int hHandle,
-						unsigned int ui32TaskId)
-{
-	struct drm_psb_private *dev_priv = dev->dev_private;
-	struct psb_gtt_mm *mm = dev_priv->gtt_mm;
-	struct psb_gtt *pg = dev_priv->pg;
-	uint32_t pages, offset_pages;
-	struct drm_mm_node *node;
-	int ret;
-
-	ret = psb_gtt_remove_node(mm, (u32)ui32TaskId, (u32)hHandle, &node);
-	if (ret) {
-		printk(KERN_ERR "remove node failed\n");
-		return ret;
-	}
-
-	/*remove gtt entries*/
-	offset_pages = node->start;
-	pages = node->size;
-
-	psb_gtt_remove_pages(pg, offset_pages, pages, 0, 0, 1);
-
-	/*free tt node*/
-	psb_gtt_mm_free_mem(mm, node);
-	return 0;
-}
diff -druN linux-2.6.39-libre/drivers/staging/gma500/psb_gtt.h linux-3.0-rc7-libre/drivers/staging/gma500/psb_gtt.h
--- linux-2.6.39-libre/drivers/staging/gma500/psb_gtt.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/gma500/psb_gtt.h	2011-07-11 19:51:52.000000000 -0400
@@ -22,84 +22,40 @@
 
 #include <drm/drmP.h>
 
-/*#include "img_types.h"*/
-
 struct psb_gtt {
 	struct drm_device *dev;
-	int initialized;
 	uint32_t gatt_start;
 	uint32_t mmu_gatt_start;
-	uint32_t ci_start;
-	uint32_t rar_start;
 	uint32_t gtt_start;
 	uint32_t gtt_phys_start;
 	unsigned gtt_pages;
 	unsigned gatt_pages;
-	uint32_t stolen_base;
-	void *vram_addr;
-	uint32_t pge_ctl;
-	u16 gmch_ctrl;
 	unsigned long stolen_size;
 	unsigned long vram_stolen_size;
-	unsigned long ci_stolen_size;
-	unsigned long rar_stolen_size;
-	uint32_t *gtt_map;
 	struct rw_semaphore sem;
 };
 
-struct psb_gtt_mm {
-	struct drm_mm base;
-	struct drm_open_hash hash;
-	uint32_t count;
-	spinlock_t lock;
-};
-
-struct psb_gtt_hash_entry {
-	struct drm_open_hash ht;
-	uint32_t count;
-	struct drm_hash_item item;
-};
-
-struct psb_gtt_mem_mapping {
-	struct drm_mm_node *node;
-	struct drm_hash_item item;
-};
-
 /*Exported functions*/
-extern int psb_gtt_init(struct psb_gtt *pg, int resume);
-extern int psb_gtt_insert_pages(struct psb_gtt *pg, struct page **pages,
-				unsigned offset_pages, unsigned num_pages,
-				unsigned desired_tile_stride,
-				unsigned hw_tile_stride, int type);
-extern int psb_gtt_remove_pages(struct psb_gtt *pg, unsigned offset_pages,
-				unsigned num_pages,
-				unsigned desired_tile_stride,
-				unsigned hw_tile_stride,
-				int rc_prot);
-
-extern struct psb_gtt *psb_gtt_alloc(struct drm_device *dev);
-extern void psb_gtt_takedown(struct psb_gtt *pg, int free);
-extern int psb_gtt_map_meminfo(struct drm_device *dev,
-				void * hKernelMemInfo,
-				uint32_t *offset);
-extern int psb_gtt_unmap_meminfo(struct drm_device *dev,
-				 void * hKernelMemInfo);
-extern int psb_gtt_map_meminfo_ioctl(struct drm_device *dev, void *data,
-				     struct drm_file *file_priv);
-extern int psb_gtt_unmap_meminfo_ioctl(struct drm_device *dev, void *data,
-				       struct drm_file *file_priv);
-extern int psb_gtt_mm_init(struct psb_gtt *pg);
-extern void psb_gtt_mm_takedown(void);
+extern int psb_gtt_init(struct drm_device *dev, int resume);
+extern void psb_gtt_takedown(struct drm_device *dev);
 
-extern int psb_gtt_map_pvr_memory(struct drm_device *dev,
-                                                                  unsigned int hHandle,
-                                                                  unsigned int ui32TaskId,
-                                                                  dma_addr_t *pPages,
-                                                                  unsigned int ui32PagesNum,
-                                                                  unsigned int *ui32Offset);
+/* Each gtt_range describes an allocation in the GTT area */
+struct gtt_range {
+	struct resource resource;
+	u32 offset;
+	struct kref kref;
+	struct drm_gem_object gem;	/* GEM high level stuff */
+	int in_gart;			/* Currently in the GART (ref ct) */
+        bool stolen;			/* Backed from stolen RAM */
+        bool mmapping;			/* Is mmappable */
+	struct page **pages;		/* Backing pages if present */
+};
 
-extern int psb_gtt_unmap_pvr_memory(struct drm_device *dev,
-                                                                        unsigned int hHandle,
-                                                                        unsigned int ui32TaskId);
+extern struct gtt_range *psb_gtt_alloc_range(struct drm_device *dev, int len,
+						const char *name, int backed);
+extern void psb_gtt_kref_put(struct gtt_range *gt);
+extern void psb_gtt_free_range(struct drm_device *dev, struct gtt_range *gt);
+extern int psb_gtt_pin(struct gtt_range *gt);
+extern void psb_gtt_unpin(struct gtt_range *gt);
 
 #endif
diff -druN linux-2.6.39-libre/drivers/staging/gma500/psb_intel_bios.c linux-3.0-rc7-libre/drivers/staging/gma500/psb_intel_bios.c
--- linux-2.6.39-libre/drivers/staging/gma500/psb_intel_bios.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/gma500/psb_intel_bios.c	2011-07-11 19:51:52.000000000 -0400
@@ -154,10 +154,15 @@
 
 	fill_detail_timing_data(panel_fixed_mode, dvo_timing);
 
-	dev_priv->lfp_lvds_vbt_mode = panel_fixed_mode;
-
-	DRM_DEBUG("Found panel mode in BIOS VBT tables:\n");
-	drm_mode_debug_printmodeline(panel_fixed_mode);
+	if (panel_fixed_mode->htotal > 0 && panel_fixed_mode->vtotal > 0) {
+		dev_priv->lfp_lvds_vbt_mode = panel_fixed_mode;
+		DRM_DEBUG("Found panel mode in BIOS VBT tables:\n");
+		drm_mode_debug_printmodeline(panel_fixed_mode);
+	} else {
+		DRM_DEBUG("Ignoring bogus LVDS VBT mode.\n");
+		dev_priv->lvds_vbt = 0;
+		kfree(panel_fixed_mode);
+	}
 
 	return;
 }
diff -druN linux-2.6.39-libre/drivers/staging/gma500/psb_intel_display.c linux-3.0-rc7-libre/drivers/staging/gma500/psb_intel_display.c
--- linux-2.6.39-libre/drivers/staging/gma500/psb_intel_display.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/gma500/psb_intel_display.c	2011-07-11 19:51:52.000000000 -0400
@@ -341,9 +341,8 @@
 	/* struct drm_i915_master_private *master_priv; */
 	struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
 	struct psb_framebuffer *psbfb = to_psb_fb(crtc->fb);
-	struct psb_intel_mode_device *mode_dev = psb_intel_crtc->mode_dev;
 	int pipe = psb_intel_crtc->pipe;
-	unsigned long Start, Offset;
+	unsigned long start, offset;
 	int dspbase = (pipe == 0 ? DSPABASE : DSPBBASE);
 	int dspsurf = (pipe == 0 ? DSPASURF : DSPBSURF);
 	int dspstride = (pipe == 0) ? DSPASTRIDE : DSPBSTRIDE;
@@ -359,12 +358,17 @@
 		return 0;
 	}
 
-	if (!ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND,
-				       OSPM_UHB_FORCE_POWER_ON))
+	if (!gma_power_begin(dev, true))
 		return 0;
 
-	Start = mode_dev->bo_offset(dev, psbfb);
-	Offset = y * crtc->fb->pitch + x * (crtc->fb->bits_per_pixel / 8);
+	/* We are displaying this buffer, make sure it is actually loaded
+	   into the GTT */
+	ret = psb_gtt_pin(psbfb->gtt);
+	if (ret < 0)
+		goto psb_intel_pipe_set_base_exit;
+	start = psbfb->gtt->offset;
+
+	offset = y * crtc->fb->pitch + x * (crtc->fb->bits_per_pixel / 8);
 
 	REG_WRITE(dspstride, crtc->fb->pitch);
 
@@ -388,25 +392,29 @@
 	default:
 		DRM_ERROR("Unknown color depth\n");
 		ret = -EINVAL;
+		psb_gtt_unpin(psbfb->gtt);
 		goto psb_intel_pipe_set_base_exit;
 	}
 	REG_WRITE(dspcntr_reg, dspcntr);
 
-	DRM_DEBUG("Writing base %08lX %08lX %d %d\n", Start, Offset, x, y);
+
+	DRM_DEBUG("Writing base %08lX %08lX %d %d\n", start, offset, x, y);
 	if (0 /* FIXMEAC - check what PSB needs */) {
-		REG_WRITE(dspbase, Offset);
+		REG_WRITE(dspbase, offset);
 		REG_READ(dspbase);
-		REG_WRITE(dspsurf, Start);
+		REG_WRITE(dspsurf, start);
 		REG_READ(dspsurf);
 	} else {
-		REG_WRITE(dspbase, Start + Offset);
+		REG_WRITE(dspbase, start + offset);
 		REG_READ(dspbase);
 	}
 
-psb_intel_pipe_set_base_exit:
-
-	ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
+	/* If there was a previous display we can now unpin it */
+	if (old_fb)
+		psb_gtt_unpin(to_psb_fb(old_fb)->gtt);
 
+psb_intel_pipe_set_base_exit:
+	gma_power_end(dev);
 	return ret;
 }
 
@@ -816,8 +824,7 @@
 		return;
 	}
 
-	if (ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND,
-				      OSPM_UHB_ONLY_IF_ON)) {
+	if (gma_power_begin(dev, false)) {
 		for (i = 0; i < 256; i++) {
 			REG_WRITE(palreg + 4 * i,
 				  ((psb_intel_crtc->lut_r[i] +
@@ -827,7 +834,7 @@
 				  (psb_intel_crtc->lut_b[i] +
 				  psb_intel_crtc->lut_adj[i]));
 		}
-		ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
+		gma_power_end(dev);
 	} else {
 		for (i = 0; i < 256; i++) {
 			dev_priv->save_palette_a[i] =
@@ -1022,19 +1029,14 @@
 				 uint32_t width, uint32_t height)
 {
 	struct drm_device *dev = crtc->dev;
-	struct drm_psb_private *dev_priv =
-				(struct drm_psb_private *)dev->dev_private;
-	struct psb_gtt *pg = dev_priv->pg;
 	struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
-	struct psb_intel_mode_device *mode_dev = psb_intel_crtc->mode_dev;
 	int pipe = psb_intel_crtc->pipe;
 	uint32_t control = (pipe == 0) ? CURACNTR : CURBCNTR;
 	uint32_t base = (pipe == 0) ? CURABASE : CURBBASE;
 	uint32_t temp;
 	size_t addr = 0;
-	uint32_t page_offset;
-	size_t size;
-	void *bo;
+	struct gtt_range *gt;
+	struct drm_gem_object *obj;
 	int ret;
 
 	DRM_DEBUG("\n");
@@ -1043,22 +1045,21 @@
 	if (!handle) {
 		DRM_DEBUG("cursor off\n");
 		/* turn off the cursor */
-		temp = 0;
-		temp |= CURSOR_MODE_DISABLE;
+		temp = CURSOR_MODE_DISABLE;
 
-		if (ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND,
-					      OSPM_UHB_ONLY_IF_ON)) {
+		if (gma_power_begin(dev, false)) {
 			REG_WRITE(control, temp);
 			REG_WRITE(base, 0);
-			ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
+			gma_power_end(dev);
 		}
 
-		/* unpin the old bo */
-		if (psb_intel_crtc->cursor_bo) {
-			mode_dev->bo_unpin_for_scanout(dev,
-						       psb_intel_crtc->
-						       cursor_bo);
-			psb_intel_crtc->cursor_bo = NULL;
+		/* Unpin the old GEM object */
+		if (psb_intel_crtc->cursor_obj) {
+			gt = container_of(psb_intel_crtc->cursor_obj,
+							struct gtt_range, gem);
+			psb_gtt_unpin(gt);
+			drm_gem_object_unreference(psb_intel_crtc->cursor_obj);
+			psb_intel_crtc->cursor_obj = NULL;
 		}
 
 		return 0;
@@ -1070,32 +1071,26 @@
 		return -EINVAL;
 	}
 
-	bo = mode_dev->bo_from_handle(dev, file_priv, handle);
-	if (!bo)
+	obj = drm_gem_object_lookup(dev, file_priv, handle);
+	if (!obj)
 		return -ENOENT;
 
-	ret = mode_dev->bo_pin_for_scanout(dev, bo);
-	if (ret)
-		return ret;
-	size = mode_dev->bo_size(dev, bo);
-	if (size < width * height * 4) {
+	if (obj->size < width * height * 4) {
 		DRM_ERROR("buffer is to small\n");
 		return -ENOMEM;
 	}
 
-	/*insert this bo into gtt*/
-	DRM_DEBUG("%s: map meminfo for hw cursor. handle %x\n",
-						__func__, handle);
+	gt = container_of(obj, struct gtt_range, gem);
 
-	ret = psb_gtt_map_meminfo(dev, (void *)handle, &page_offset);
+	/* Pin the memory into the GTT */
+	ret = psb_gtt_pin(gt);
 	if (ret) {
-		DRM_ERROR("Can not map meminfo to GTT. handle 0x%x\n", handle);
+		DRM_ERROR("Can not pin down handle 0x%x\n", handle);
 		return ret;
 	}
 
-	addr = page_offset << PAGE_SHIFT;
 
-	addr += pg->stolen_base;
+	addr = gt->offset;	/* Or resource.start ??? */
 
 	psb_intel_crtc->cursor_addr = addr;
 
@@ -1104,17 +1099,19 @@
 	temp |= (pipe << 28);
 	temp |= CURSOR_MODE_64_ARGB_AX | MCURSOR_GAMMA_ENABLE;
 
-	if (ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND,
-				      OSPM_UHB_ONLY_IF_ON)) {
+	if (gma_power_begin(dev, false)) {
 		REG_WRITE(control, temp);
 		REG_WRITE(base, addr);
-		ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
+		gma_power_end(dev);
 	}
 
 	/* unpin the old bo */
-	if (psb_intel_crtc->cursor_bo && psb_intel_crtc->cursor_bo != bo) {
-		mode_dev->bo_unpin_for_scanout(dev, psb_intel_crtc->cursor_bo);
-		psb_intel_crtc->cursor_bo = bo;
+	if (psb_intel_crtc->cursor_obj && psb_intel_crtc->cursor_obj != obj) {
+		gt = container_of(psb_intel_crtc->cursor_obj,
+							struct gtt_range, gem);
+		psb_gtt_unpin(gt);
+		drm_gem_object_unreference(psb_intel_crtc->cursor_obj);
+		psb_intel_crtc->cursor_obj = obj;
 	}
 
 	return 0;
@@ -1126,7 +1123,7 @@
 	struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
 	int pipe = psb_intel_crtc->pipe;
 	uint32_t temp = 0;
-	uint32_t adder;
+	uint32_t addr;
 
 
 	if (x < 0) {
@@ -1141,13 +1138,12 @@
 	temp |= ((x & CURSOR_POS_MASK) << CURSOR_X_SHIFT);
 	temp |= ((y & CURSOR_POS_MASK) << CURSOR_Y_SHIFT);
 
-	adder = psb_intel_crtc->cursor_addr;
+	addr = psb_intel_crtc->cursor_addr;
 
-	if (ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND,
-				      OSPM_UHB_ONLY_IF_ON)) {
+	if (gma_power_begin(dev, false)) {
 		REG_WRITE((pipe == 0) ? CURAPOS : CURBPOS, temp);
-		REG_WRITE((pipe == 0) ? CURABASE : CURBBASE, adder);
-		ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
+		REG_WRITE((pipe == 0) ? CURABASE : CURBBASE, addr);
+		gma_power_end(dev);
 	}
 	return 0;
 }
@@ -1197,15 +1193,14 @@
 	bool is_lvds;
 	struct drm_psb_private *dev_priv = dev->dev_private;
 
-	if (ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND,
-				      OSPM_UHB_ONLY_IF_ON)) {
+	if (gma_power_begin(dev, false)) {
 		dpll = REG_READ((pipe == 0) ? DPLL_A : DPLL_B);
 		if ((dpll & DISPLAY_RATE_SELECT_FPA1) == 0)
 			fp = REG_READ((pipe == 0) ? FPA0 : FPB0);
 		else
 			fp = REG_READ((pipe == 0) ? FPA1 : FPB1);
 		is_lvds = (pipe == 1) && (REG_READ(LVDS) & LVDS_PORT_EN);
-		ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
+		gma_power_end(dev);
 	} else {
 		dpll = (pipe == 0) ?
 			dev_priv->saveDPLL_A : dev_priv->saveDPLL_B;
@@ -1277,13 +1272,12 @@
 	int vsync;
 	struct drm_psb_private *dev_priv = dev->dev_private;
 
-	if (ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND,
-				      OSPM_UHB_ONLY_IF_ON)) {
+	if (gma_power_begin(dev, false)) {
 		htot = REG_READ((pipe == 0) ? HTOTAL_A : HTOTAL_B);
 		hsync = REG_READ((pipe == 0) ? HSYNC_A : HSYNC_B);
 		vtot = REG_READ((pipe == 0) ? VTOTAL_A : VTOTAL_B);
 		vsync = REG_READ((pipe == 0) ? VSYNC_A : VSYNC_B);
-		ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
+		gma_power_end(dev);
 	} else {
 		htot = (pipe == 0) ?
 			dev_priv->saveHTOTAL_A : dev_priv->saveHTOTAL_B;
@@ -1318,7 +1312,16 @@
 static void psb_intel_crtc_destroy(struct drm_crtc *crtc)
 {
 	struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
+	struct gtt_range *gt;
 
+	/* Unpin the old GEM object */
+	if (psb_intel_crtc->cursor_obj) {
+		gt = container_of(psb_intel_crtc->cursor_obj,
+						struct gtt_range, gem);
+		psb_gtt_unpin(gt);
+		drm_gem_object_unreference(psb_intel_crtc->cursor_obj);
+		psb_intel_crtc->cursor_obj = NULL;
+	}
 	kfree(psb_intel_crtc->crtc_state);
 	drm_crtc_cleanup(crtc);
 	kfree(psb_intel_crtc);
@@ -1333,10 +1336,6 @@
 	.commit = psb_intel_crtc_commit,
 };
 
-static const struct drm_crtc_helper_funcs mrst_helper_funcs;
-static const struct drm_crtc_helper_funcs mdfld_helper_funcs;
-const struct drm_crtc_funcs mdfld_intel_crtc_funcs;
-
 const struct drm_crtc_funcs psb_intel_crtc_funcs = {
 	.save = psb_intel_crtc_save,
 	.restore = psb_intel_crtc_restore,
@@ -1397,7 +1396,11 @@
 	psb_intel_crtc->mode_dev = mode_dev;
 	psb_intel_crtc->cursor_addr = 0;
 
-	drm_crtc_helper_add(&psb_intel_crtc->base,
+	if (IS_MRST(dev))
+		drm_crtc_helper_add(&psb_intel_crtc->base,
+				    &mrst_helper_funcs);
+	else
+		drm_crtc_helper_add(&psb_intel_crtc->base,
 				    &psb_intel_helper_funcs);
 
 	/* Setup the array of drm_connector pointer array */
diff -druN linux-2.6.39-libre/drivers/staging/gma500/psb_intel_drv.h linux-3.0-rc7-libre/drivers/staging/gma500/psb_intel_drv.h
--- linux-2.6.39-libre/drivers/staging/gma500/psb_intel_drv.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/gma500/psb_intel_drv.h	2011-07-11 19:51:52.000000000 -0400
@@ -76,13 +76,7 @@
 	/*
 	 * Abstracted memory manager operations
 	 */
-	void *(*bo_from_handle) (struct drm_device *dev,
-				 struct drm_file *file_priv,
-				 unsigned int handle);
-	 size_t(*bo_size) (struct drm_device *dev, void *bo);
 	 size_t(*bo_offset) (struct drm_device *dev, void *bo);
-	int (*bo_pin_for_scanout) (struct drm_device *dev, void *bo);
-	int (*bo_unpin_for_scanout) (struct drm_device *dev, void *bo);
 
 	/*
 	 * Cursor
@@ -156,11 +150,8 @@
 	/* a mode_set for fbdev users on this crtc */
 	struct drm_mode_set mode_set;
 
-	/* current bo we scanout from */
-	void *scanout_bo;
-
-	/* current bo we cursor from */
-	void *cursor_bo;
+	/* GEM object that holds our cursor */
+	struct drm_gem_object *cursor_obj;
 
 	struct drm_display_mode saved_mode;
 	struct drm_display_mode saved_adjusted_mode;
diff -druN linux-2.6.39-libre/drivers/staging/gma500/psb_intel_lvds.c linux-3.0-rc7-libre/drivers/staging/gma500/psb_intel_lvds.c
--- linux-2.6.39-libre/drivers/staging/gma500/psb_intel_lvds.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/gma500/psb_intel_lvds.c	2011-07-11 19:51:52.000000000 -0400
@@ -32,13 +32,6 @@
 #include "psb_powermgmt.h"
 #include <linux/pm_runtime.h>
 
-/* MRST defines start */
-uint8_t blc_freq;
-uint8_t blc_minbrightness;
-uint8_t blc_i2caddr;
-uint8_t blc_brightnesscmd;
-int lvds_backlight;		/* restore backlight to this value */
-
 u32 CoreClock;
 u32 PWMControlRegFreq;
 
@@ -83,13 +76,12 @@
 	struct drm_psb_private *dev_priv = dev->dev_private;
 	u32 retVal;
 
-	if (ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND,
-					OSPM_UHB_ONLY_IF_ON)) {
+	if (gma_power_begin(dev, false)) {
 		retVal = ((REG_READ(BLC_PWM_CTL) &
 			  BACKLIGHT_MODULATION_FREQ_MASK) >>
 			  BACKLIGHT_MODULATION_FREQ_SHIFT) * 2;
 
-		ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
+		gma_power_end(dev);
 	} else
 		retVal = ((dev_priv->saveBLC_PWM_CTL &
 			  BACKLIGHT_MODULATION_FREQ_MASK) >>
@@ -98,8 +90,11 @@
 	return retVal;
 }
 
-/**
+/*
  * Set LVDS backlight level by I2C command
+ *
+ * FIXME: at some point we need to both track this for PM and also
+ * disable runtime pm on MRST if the brightness is nil (ie blanked)
  */
 static int psb_lvds_i2c_set_brightness(struct drm_device *dev,
 					unsigned int level)
@@ -132,7 +127,7 @@
 
 	if (i2c_transfer(&lvds_i2c_bus->adapter, msgs, 1) == 1) {
 		DRM_DEBUG("I2C set brightness.(command, value) (%d, %d)\n",
-			blc_brightnesscmd,
+			dev_priv->lvds_bl->brightnesscmd,
 			blc_i2c_brightness);
 		return 0;
 	}
@@ -200,14 +195,13 @@
 	struct drm_psb_private *dev_priv = dev->dev_private;
 	u32 blc_pwm_ctl;
 
-	if (ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND,
-					OSPM_UHB_ONLY_IF_ON)) {
+	if (gma_power_begin(dev, false)) {
 		blc_pwm_ctl =
 			REG_READ(BLC_PWM_CTL) & ~BACKLIGHT_DUTY_CYCLE_MASK;
 		REG_WRITE(BLC_PWM_CTL,
 				(blc_pwm_ctl |
 				(level << BACKLIGHT_DUTY_CYCLE_SHIFT)));
-		ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
+		gma_power_end(dev);
 	} else {
 		blc_pwm_ctl = dev_priv->saveBLC_PWM_CTL &
 				~BACKLIGHT_DUTY_CYCLE_MASK;
@@ -224,8 +218,7 @@
 {
 	u32 pp_status;
 
-	if (!ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND,
-					OSPM_UHB_FORCE_POWER_ON))
+	if (!gma_power_begin(dev, true))
 		return;
 
 	if (on) {
@@ -248,7 +241,7 @@
 		} while (pp_status & PP_ON);
 	}
 
-	ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
+	gma_power_end(dev);
 }
 
 static void psb_intel_lvds_encoder_dpms(struct drm_encoder *encoder, int mode)
@@ -400,11 +393,15 @@
 	if (psb_intel_output->type == INTEL_OUTPUT_MIPI2)
 		panel_fixed_mode = mode_dev->panel_fixed_mode2;
 
-	/* PSB doesn't appear to be GEN4 */
-	if (psb_intel_crtc->pipe == 0) {
+	/* PSB requires the LVDS is on pipe B, MRST has only one pipe anyway */
+	if (!IS_MRST(dev) && psb_intel_crtc->pipe == 0) {
 		printk(KERN_ERR "Can't support LVDS on pipe A\n");
 		return false;
 	}
+	if (IS_MRST(dev) && psb_intel_crtc->pipe != 0) {
+		printk(KERN_ERR "Must use PIPE A\n");
+		return false;
+	}
 	/* Should never happen!! */
 	list_for_each_entry(tmp_encoder, &dev->mode_config.encoder_list,
 			    head) {
@@ -445,7 +442,7 @@
 	return true;
 }
 
-static void psb_intel_lvds_prepare(struct drm_encoder *encoder)
+void psb_intel_lvds_prepare(struct drm_encoder *encoder)
 {
 	struct drm_device *dev = encoder->dev;
 	struct psb_intel_output *output = enc_to_psb_intel_output(encoder);
@@ -453,8 +450,7 @@
 
 	PSB_DEBUG_ENTRY("\n");
 
-	if (!ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND,
-					OSPM_UHB_FORCE_POWER_ON))
+	if (!gma_power_begin(dev, true))
 		return;
 
 	mode_dev->saveBLC_PWM_CTL = REG_READ(BLC_PWM_CTL);
@@ -463,10 +459,10 @@
 
 	psb_intel_lvds_set_power(dev, output, false);
 
-	ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
+	gma_power_end(dev);
 }
 
-static void psb_intel_lvds_commit(struct drm_encoder *encoder)
+void psb_intel_lvds_commit(struct drm_encoder *encoder)
 {
 	struct drm_device *dev = encoder->dev;
 	struct psb_intel_output *output = enc_to_psb_intel_output(encoder);
@@ -669,14 +665,14 @@
 	.commit = psb_intel_lvds_commit,
 };
 
-static const struct drm_connector_helper_funcs
+const struct drm_connector_helper_funcs
 				psb_intel_lvds_connector_helper_funcs = {
 	.get_modes = psb_intel_lvds_get_modes,
 	.mode_valid = psb_intel_lvds_mode_valid,
 	.best_encoder = psb_intel_best_encoder,
 };
 
-static const struct drm_connector_funcs psb_intel_lvds_connector_funcs = {
+const struct drm_connector_funcs psb_intel_lvds_connector_funcs = {
 	.dpms = drm_helper_connector_dpms,
 	.save = psb_intel_lvds_save,
 	.restore = psb_intel_lvds_restore,
diff -druN linux-2.6.39-libre/drivers/staging/gma500/psb_intel_sdvo.c linux-3.0-rc7-libre/drivers/staging/gma500/psb_intel_sdvo.c
--- linux-2.6.39-libre/drivers/staging/gma500/psb_intel_sdvo.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/gma500/psb_intel_sdvo.c	2011-07-11 19:51:52.000000000 -0400
@@ -204,7 +204,7 @@
 	struct psb_intel_sdvo_priv *sdvo_priv = psb_intel_output->dev_priv;
 	int i;
 
-	if (1) {
+	if (0) {
 		DRM_DEBUG("%s: W: %02X ", SDVO_NAME(sdvo_priv), cmd);
 		for (i = 0; i < args_len; i++)
 			printk(KERN_INFO"%02X ", ((u8 *) args)[i]);
@@ -266,7 +266,7 @@
 					 SDVO_I2C_CMD_STATUS,
 					 &status);
 
-		if (1) {
+		if (0) {
 			DRM_DEBUG("%s: R: ", SDVO_NAME(sdvo_priv));
 			for (i = 0; i < response_len; i++)
 				printk(KERN_INFO"%02X ", ((u8 *) response)[i]);
diff -druN linux-2.6.39-libre/drivers/staging/gma500/psb_irq.c linux-3.0-rc7-libre/drivers/staging/gma500/psb_irq.c
--- linux-2.6.39-libre/drivers/staging/gma500/psb_irq.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/gma500/psb_irq.c	2011-07-11 19:51:52.000000000 -0400
@@ -88,13 +88,12 @@
 		u32 reg = psb_pipestat(pipe);
 		dev_priv->pipestat[pipe] |= mask;
 		/* Enable the interrupt, clear any pending status */
-		if (ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND,
-							OSPM_UHB_ONLY_IF_ON)) {
+		if (gma_power_begin(dev_priv->dev, false)) {
 			u32 writeVal = PSB_RVDC32(reg);
 			writeVal |= (mask | (mask >> 16));
 			PSB_WVDC32(writeVal, reg);
 			(void) PSB_RVDC32(reg);
-			ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
+			gma_power_end(dev_priv->dev);
 		}
 	}
 }
@@ -105,39 +104,36 @@
 	if ((dev_priv->pipestat[pipe] & mask) != 0) {
 		u32 reg = psb_pipestat(pipe);
 		dev_priv->pipestat[pipe] &= ~mask;
-		if (ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND,
-							OSPM_UHB_ONLY_IF_ON)) {
+		if (gma_power_begin(dev_priv->dev, false)) {
 			u32 writeVal = PSB_RVDC32(reg);
 			writeVal &= ~mask;
 			PSB_WVDC32(writeVal, reg);
 			(void) PSB_RVDC32(reg);
-			ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
+			gma_power_end(dev_priv->dev);
 		}
 	}
 }
 
 void mid_enable_pipe_event(struct drm_psb_private *dev_priv, int pipe)
 {
-	if (ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND,
-							OSPM_UHB_ONLY_IF_ON)) {
+	if (gma_power_begin(dev_priv->dev, false)) {
 		u32 pipe_event = mid_pipe_event(pipe);
 		dev_priv->vdc_irq_mask |= pipe_event;
 		PSB_WVDC32(~dev_priv->vdc_irq_mask, PSB_INT_MASK_R);
 		PSB_WVDC32(dev_priv->vdc_irq_mask, PSB_INT_ENABLE_R);
-		ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
+		gma_power_end(dev_priv->dev);
 	}
 }
 
 void mid_disable_pipe_event(struct drm_psb_private *dev_priv, int pipe)
 {
 	if (dev_priv->pipestat[pipe] == 0) {
-		if (ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND,
-							OSPM_UHB_ONLY_IF_ON)) {
+		if (gma_power_begin(dev_priv->dev, false)) {
 			u32 pipe_event = mid_pipe_event(pipe);
 			dev_priv->vdc_irq_mask &= ~pipe_event;
 			PSB_WVDC32(~dev_priv->vdc_irq_mask, PSB_INT_MASK_R);
 			PSB_WVDC32(dev_priv->vdc_irq_mask, PSB_INT_ENABLE_R);
-			ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
+			gma_power_end(dev_priv->dev);
 		}
 	}
 }
@@ -242,7 +238,7 @@
 	vdc_stat &= dev_priv->vdc_irq_mask;
 	spin_unlock(&dev_priv->irqmask_lock);
 
-	if (dsp_int && ospm_power_is_hw_on(OSPM_DISPLAY_ISLAND)) {
+	if (dsp_int && gma_power_is_on(dev)) {
 		psb_vdc_interrupt(dev, vdc_stat);
 		handled = 1;
 	}
@@ -271,54 +267,28 @@
 
 void psb_irq_preinstall(struct drm_device *dev)
 {
-	psb_irq_preinstall_islands(dev, OSPM_ALL_ISLANDS);
-}
-
-/**
- * FIXME: should I remove display irq enable here??
- */
-void psb_irq_preinstall_islands(struct drm_device *dev, int hw_islands)
-{
 	struct drm_psb_private *dev_priv =
 	    (struct drm_psb_private *) dev->dev_private;
 	unsigned long irqflags;
 
-	PSB_DEBUG_ENTRY("\n");
-
 	spin_lock_irqsave(&dev_priv->irqmask_lock, irqflags);
 
-	if (hw_islands & OSPM_DISPLAY_ISLAND) {
-		if (ospm_power_is_hw_on(OSPM_DISPLAY_ISLAND)) {
-			PSB_WVDC32(0xFFFFFFFF, PSB_HWSTAM);
-			if (dev->vblank_enabled[0])
-				dev_priv->vdc_irq_mask |=
-						_PSB_PIPEA_EVENT_FLAG;
-			if (dev->vblank_enabled[1])
-				dev_priv->vdc_irq_mask |=
-						_MDFLD_PIPEB_EVENT_FLAG;
-			if (dev->vblank_enabled[2])
-				dev_priv->vdc_irq_mask |=
-						_MDFLD_PIPEC_EVENT_FLAG;
-		}
-	}
-/* NO I DONT WANT ANY IRQS GRRR FIXMEAC */
-	if (hw_islands & OSPM_GRAPHICS_ISLAND)
-		dev_priv->vdc_irq_mask |= _PSB_IRQ_SGX_FLAG;
-/* */
+	if (gma_power_is_on(dev))
+		PSB_WVDC32(0xFFFFFFFF, PSB_HWSTAM);
+	if (dev->vblank_enabled[0])
+		dev_priv->vdc_irq_mask |= _PSB_PIPEA_EVENT_FLAG;
+	if (dev->vblank_enabled[1])
+		dev_priv->vdc_irq_mask |= _MDFLD_PIPEB_EVENT_FLAG;
+	if (dev->vblank_enabled[2])
+		dev_priv->vdc_irq_mask |= _MDFLD_PIPEC_EVENT_FLAG;
+
 	/*This register is safe even if display island is off*/
 	PSB_WVDC32(~dev_priv->vdc_irq_mask, PSB_INT_MASK_R);
-
 	spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags);
 }
 
 int psb_irq_postinstall(struct drm_device *dev)
 {
-	return psb_irq_postinstall_islands(dev, OSPM_ALL_ISLANDS);
-}
-
-int psb_irq_postinstall_islands(struct drm_device *dev, int hw_islands)
-{
-
 	struct drm_psb_private *dev_priv =
 	    (struct drm_psb_private *) dev->dev_private;
 	unsigned long irqflags;
@@ -327,48 +297,31 @@
 
 	spin_lock_irqsave(&dev_priv->irqmask_lock, irqflags);
 
-	/*This register is safe even if display island is off*/
+	/* This register is safe even if display island is off */
 	PSB_WVDC32(dev_priv->vdc_irq_mask, PSB_INT_ENABLE_R);
+	PSB_WVDC32(0xFFFFFFFF, PSB_HWSTAM);
 
-	if (hw_islands & OSPM_DISPLAY_ISLAND) {
-		if (true/*powermgmt_is_hw_on(dev->pdev, PSB_DISPLAY_ISLAND)*/) {
-			PSB_WVDC32(0xFFFFFFFF, PSB_HWSTAM);
-
-			if (dev->vblank_enabled[0])
-				psb_enable_pipestat(dev_priv, 0,
-				    PIPE_VBLANK_INTERRUPT_ENABLE);
-			else
-				psb_disable_pipestat(dev_priv, 0,
-				    PIPE_VBLANK_INTERRUPT_ENABLE);
+	if (dev->vblank_enabled[0])
+		psb_enable_pipestat(dev_priv, 0, PIPE_VBLANK_INTERRUPT_ENABLE);
+	else
+		psb_disable_pipestat(dev_priv, 0, PIPE_VBLANK_INTERRUPT_ENABLE);
 
-			if (dev->vblank_enabled[1])
-					psb_enable_pipestat(dev_priv, 1,
-					    PIPE_VBLANK_INTERRUPT_ENABLE);
-			else
-				psb_disable_pipestat(dev_priv, 1,
-				    PIPE_VBLANK_INTERRUPT_ENABLE);
+	if (dev->vblank_enabled[1])
+		psb_enable_pipestat(dev_priv, 1, PIPE_VBLANK_INTERRUPT_ENABLE);
+	else
+		psb_disable_pipestat(dev_priv, 1, PIPE_VBLANK_INTERRUPT_ENABLE);
 
-			if (dev->vblank_enabled[2])
-				psb_enable_pipestat(dev_priv, 2,
-				    PIPE_VBLANK_INTERRUPT_ENABLE);
-			else
-				psb_disable_pipestat(dev_priv, 2,
-				    PIPE_VBLANK_INTERRUPT_ENABLE);
-		}
-	}
+	if (dev->vblank_enabled[2])
+		psb_enable_pipestat(dev_priv, 2, PIPE_VBLANK_INTERRUPT_ENABLE);
+	else
+		psb_disable_pipestat(dev_priv, 2, PIPE_VBLANK_INTERRUPT_ENABLE);
 
 	spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags);
-
 	return 0;
 }
 
 void psb_irq_uninstall(struct drm_device *dev)
 {
-	psb_irq_uninstall_islands(dev, OSPM_ALL_ISLANDS);
-}
-
-void psb_irq_uninstall_islands(struct drm_device *dev, int hw_islands)
-{
 	struct drm_psb_private *dev_priv =
 	    (struct drm_psb_private *) dev->dev_private;
 	unsigned long irqflags;
@@ -377,39 +330,29 @@
 
 	spin_lock_irqsave(&dev_priv->irqmask_lock, irqflags);
 
-	if (hw_islands & OSPM_DISPLAY_ISLAND) {
-		if (true/*powermgmt_is_hw_on(dev->pdev, PSB_DISPLAY_ISLAND)*/) {
-			PSB_WVDC32(0xFFFFFFFF, PSB_HWSTAM);
+	PSB_WVDC32(0xFFFFFFFF, PSB_HWSTAM);
 
-			if (dev->vblank_enabled[0])
-				psb_disable_pipestat(dev_priv, 0,
-				    PIPE_VBLANK_INTERRUPT_ENABLE);
+	if (dev->vblank_enabled[0])
+		psb_disable_pipestat(dev_priv, 0, PIPE_VBLANK_INTERRUPT_ENABLE);
 
-			if (dev->vblank_enabled[1])
-				psb_disable_pipestat(dev_priv, 1,
-				    PIPE_VBLANK_INTERRUPT_ENABLE);
+	if (dev->vblank_enabled[1])
+		psb_disable_pipestat(dev_priv, 1, PIPE_VBLANK_INTERRUPT_ENABLE);
 
-			if (dev->vblank_enabled[2])
-				psb_disable_pipestat(dev_priv, 2,
-				    PIPE_VBLANK_INTERRUPT_ENABLE);
-		}
-		dev_priv->vdc_irq_mask &= _PSB_IRQ_SGX_FLAG |
-					  _PSB_IRQ_MSVDX_FLAG |
-					  _LNC_IRQ_TOPAZ_FLAG;
-	}
-	/*TODO: remove following code*/
-	if (hw_islands & OSPM_GRAPHICS_ISLAND)
-		dev_priv->vdc_irq_mask &= ~_PSB_IRQ_SGX_FLAG;
+	if (dev->vblank_enabled[2])
+		psb_disable_pipestat(dev_priv, 2, PIPE_VBLANK_INTERRUPT_ENABLE);
 
-	/*These two registers are safe even if display island is off*/
+	dev_priv->vdc_irq_mask &= _PSB_IRQ_SGX_FLAG |
+				  _PSB_IRQ_MSVDX_FLAG |
+				  _LNC_IRQ_TOPAZ_FLAG;
+
+	/* These two registers are safe even if display island is off */
 	PSB_WVDC32(~dev_priv->vdc_irq_mask, PSB_INT_MASK_R);
 	PSB_WVDC32(dev_priv->vdc_irq_mask, PSB_INT_ENABLE_R);
 
 	wmb();
 
-	/*This register is safe even if display island is off*/
+	/* This register is safe even if display island is off */
 	PSB_WVDC32(PSB_RVDC32(PSB_INT_IDENTITY_R), PSB_INT_IDENTITY_R);
-
 	spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags);
 }
 
@@ -420,8 +363,7 @@
 	u32 hist_reg;
 	u32 pwm_reg;
 
-	if (ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND,
-							OSPM_UHB_ONLY_IF_ON)) {
+	if (gma_power_begin(dev, false)) {
 		PSB_WVDC32(1 << 31, HISTOGRAM_LOGIC_CONTROL);
 		hist_reg = PSB_RVDC32(HISTOGRAM_LOGIC_CONTROL);
 		PSB_WVDC32(1 << 31, HISTOGRAM_INT_CONTROL);
@@ -443,7 +385,7 @@
 		PSB_WVDC32(pwm_reg | 0x80010100 | PWM_PHASEIN_ENABLE,
 							PWM_CONTROL_LOGIC);
 
-		ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
+		gma_power_end(dev);
 	}
 }
 
@@ -472,8 +414,7 @@
 	u32 hist_reg;
 	u32 pwm_reg;
 
-	if (ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND,
-							OSPM_UHB_ONLY_IF_ON)) {
+	if (gma_power_begin(dev, false)) {
 		PSB_WVDC32(0x00000000, HISTOGRAM_INT_CONTROL);
 		hist_reg = PSB_RVDC32(HISTOGRAM_INT_CONTROL);
 
@@ -484,7 +425,7 @@
 							PWM_CONTROL_LOGIC);
 		pwm_reg = PSB_RVDC32(PWM_CONTROL_LOGIC);
 
-		ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
+		gma_power_end(dev);
 	}
 }
 
@@ -526,18 +467,16 @@
  */
 int psb_enable_vblank(struct drm_device *dev, int pipe)
 {
-	struct drm_psb_private *dev_priv =
-	    (struct drm_psb_private *) dev->dev_private;
+	struct drm_psb_private *dev_priv = dev->dev_private;
 	unsigned long irqflags;
 	uint32_t reg_val = 0;
 	uint32_t pipeconf_reg = mid_pipeconf(pipe);
 
 	PSB_DEBUG_ENTRY("\n");
 
-	if (ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND,
-							OSPM_UHB_ONLY_IF_ON)) {
+	if (gma_power_begin(dev, false)) {
 		reg_val = REG_READ(pipeconf_reg);
-		ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
+		gma_power_end(dev);
 	}
 
 	if (!(reg_val & PIPEACONF_ENABLE))
@@ -545,7 +484,6 @@
 
 	spin_lock_irqsave(&dev_priv->irqmask_lock, irqflags);
 
-	drm_psb_disable_vsync = 0;
 	mid_enable_pipe_event(dev_priv, pipe);
 	psb_enable_pipestat(dev_priv, pipe, PIPE_VBLANK_INTERRUPT_ENABLE);
 
@@ -559,15 +497,13 @@
  */
 void psb_disable_vblank(struct drm_device *dev, int pipe)
 {
-	struct drm_psb_private *dev_priv =
-	    (struct drm_psb_private *) dev->dev_private;
+	struct drm_psb_private *dev_priv = dev->dev_private;
 	unsigned long irqflags;
 
 	PSB_DEBUG_ENTRY("\n");
 
 	spin_lock_irqsave(&dev_priv->irqmask_lock, irqflags);
 
-	drm_psb_disable_vsync = 1;
 	mid_disable_pipe_event(dev_priv, pipe);
 	psb_disable_pipestat(dev_priv, pipe, PIPE_VBLANK_INTERRUPT_ENABLE);
 
@@ -603,7 +539,7 @@
 		return 0;
 	}
 
-	if (!ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND, false))
+	if (!gma_power_begin(dev, false))
 		return 0;
 
 	reg_val = REG_READ(pipeconf_reg);
@@ -632,7 +568,7 @@
 
 psb_get_vblank_counter_exit:
 
-	ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
+	gma_power_end(dev);
 
 	return count;
 }
diff -druN linux-2.6.39-libre/drivers/staging/gma500/psb_lid.c linux-3.0-rc7-libre/drivers/staging/gma500/psb_lid.c
--- linux-2.6.39-libre/drivers/staging/gma500/psb_lid.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/staging/gma500/psb_lid.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,90 @@
+/**************************************************************************
+ * Copyright (c) 2007, 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.
+ *
+ * Authors: Thomas Hellstrom <thomas-at-tungstengraphics-dot-com>
+ **************************************************************************/
+
+#include <drm/drmP.h>
+#include "psb_drv.h"
+#include "psb_reg.h"
+#include "psb_intel_reg.h"
+#include <linux/spinlock.h>
+
+static void psb_lid_timer_func(unsigned long data)
+{
+	struct drm_psb_private * dev_priv = (struct drm_psb_private *)data;
+	struct drm_device *dev = (struct drm_device *)dev_priv->dev;
+	struct timer_list *lid_timer = &dev_priv->lid_timer;
+	unsigned long irq_flags;
+	u32 *lid_state = dev_priv->lid_state;
+	u32 pp_status;
+
+	if (*lid_state == dev_priv->lid_last_state)
+		goto lid_timer_schedule;
+
+	if ((*lid_state) & 0x01) {
+		/*lid state is open*/
+		REG_WRITE(PP_CONTROL, REG_READ(PP_CONTROL) | POWER_TARGET_ON);
+		do {
+			pp_status = REG_READ(PP_STATUS);
+		} while ((pp_status & PP_ON) == 0);
+
+		/*FIXME: should be backlight level before*/
+		psb_intel_lvds_set_brightness(dev, 100);
+	} else {
+		psb_intel_lvds_set_brightness(dev, 0);
+
+		REG_WRITE(PP_CONTROL, REG_READ(PP_CONTROL) & ~POWER_TARGET_ON);
+		do {
+			pp_status = REG_READ(PP_STATUS);
+		} while ((pp_status & PP_ON) == 0);
+	}
+		/* printk(KERN_INFO"%s: lid: closed\n", __FUNCTION__); */
+
+	dev_priv->lid_last_state =  *lid_state;
+
+lid_timer_schedule:
+	spin_lock_irqsave(&dev_priv->lid_lock, irq_flags);
+	if (!timer_pending(lid_timer)) {
+		lid_timer->expires = jiffies + PSB_LID_DELAY;
+		add_timer(lid_timer);
+	}
+	spin_unlock_irqrestore(&dev_priv->lid_lock, irq_flags);
+}
+
+void psb_lid_timer_init(struct drm_psb_private *dev_priv)
+{
+	struct timer_list *lid_timer = &dev_priv->lid_timer;
+	unsigned long irq_flags;
+
+	spin_lock_init(&dev_priv->lid_lock);
+	spin_lock_irqsave(&dev_priv->lid_lock, irq_flags);
+
+	init_timer(lid_timer);
+
+	lid_timer->data = (unsigned long)dev_priv;
+	lid_timer->function = psb_lid_timer_func;
+	lid_timer->expires = jiffies + PSB_LID_DELAY;
+
+	add_timer(lid_timer);
+	spin_unlock_irqrestore(&dev_priv->lid_lock, irq_flags);
+}
+
+void psb_lid_timer_takedown(struct drm_psb_private *dev_priv)
+{
+	del_timer_sync(&dev_priv->lid_timer);
+}
+
diff -druN linux-2.6.39-libre/drivers/staging/gma500/psb_mmu.c linux-3.0-rc7-libre/drivers/staging/gma500/psb_mmu.c
--- linux-2.6.39-libre/drivers/staging/gma500/psb_mmu.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/gma500/psb_mmu.c	2011-07-11 19:51:52.000000000 -0400
@@ -444,67 +444,6 @@
 	pt->v[psb_mmu_pt_index(addr)] = pt->pd->invalid_pte;
 }
 
-#if 0
-static uint32_t psb_mmu_check_pte_locked(struct psb_mmu_pd *pd,
-					 uint32_t mmu_offset)
-{
-	uint32_t *v;
-	uint32_t pfn;
-
-	v = kmap_atomic(pd->p, KM_USER0);
-	if (!v) {
-		printk(KERN_INFO "Could not kmap pde page.\n");
-		return 0;
-	}
-	pfn = v[psb_mmu_pd_index(mmu_offset)];
-	/*      printk(KERN_INFO "pde is 0x%08x\n",pfn); */
-	kunmap_atomic(v, KM_USER0);
-	if (((pfn & 0x0F) != PSB_PTE_VALID)) {
-		printk(KERN_INFO "Strange pde at 0x%08x: 0x%08x.\n",
-		       mmu_offset, pfn);
-	}
-	v = ioremap(pfn & 0xFFFFF000, 4096);
-	if (!v) {
-		printk(KERN_INFO "Could not kmap pte page.\n");
-		return 0;
-	}
-	pfn = v[psb_mmu_pt_index(mmu_offset)];
-	/* printk(KERN_INFO "pte is 0x%08x\n",pfn); */
-	iounmap(v);
-	if (((pfn & 0x0F) != PSB_PTE_VALID)) {
-		printk(KERN_INFO "Strange pte at 0x%08x: 0x%08x.\n",
-		       mmu_offset, pfn);
-	}
-	return pfn >> PAGE_SHIFT;
-}
-
-static void psb_mmu_check_mirrored_gtt(struct psb_mmu_pd *pd,
-				       uint32_t mmu_offset,
-				       uint32_t gtt_pages)
-{
-	uint32_t start;
-	uint32_t next;
-
-	printk(KERN_INFO "Checking mirrored gtt 0x%08x %d\n",
-	       mmu_offset, gtt_pages);
-	down_read(&pd->driver->sem);
-	start = psb_mmu_check_pte_locked(pd, mmu_offset);
-	mmu_offset += PAGE_SIZE;
-	gtt_pages -= 1;
-	while (gtt_pages--) {
-		next = psb_mmu_check_pte_locked(pd, mmu_offset);
-		if (next != start + 1) {
-			printk(KERN_INFO
-			       "Ptes out of order: 0x%08x, 0x%08x.\n",
-			       start, next);
-		}
-		start = next;
-		mmu_offset += PAGE_SIZE;
-	}
-	up_read(&pd->driver->sem);
-}
-
-#endif
 
 void psb_mmu_mirror_gtt(struct psb_mmu_pd *pd,
 			uint32_t mmu_offset, uint32_t gtt_start,
diff -druN linux-2.6.39-libre/drivers/staging/gma500/psb_powermgmt.c linux-3.0-rc7-libre/drivers/staging/gma500/psb_powermgmt.c
--- linux-2.6.39-libre/drivers/staging/gma500/psb_powermgmt.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/gma500/psb_powermgmt.c	2011-07-11 19:51:52.000000000 -0400
@@ -24,83 +24,73 @@
  * Authors:
  *    Benjamin Defnet <benjamin.r.defnet@intel.com>
  *    Rajesh Poornachandran <rajesh.poornachandran@intel.com>
- *
+ * Massively reworked
+ *    Alan Cox <alan@linux.intel.com>
  */
 #include "psb_powermgmt.h"
 #include "psb_drv.h"
+#include "psb_reg.h"
 #include "psb_intel_reg.h"
 #include <linux/mutex.h>
 #include <linux/pm_runtime.h>
 
-#undef OSPM_GFX_DPK
-
-extern u32 gui32SGXDeviceID;
-extern u32 gui32MRSTDisplayDeviceID;
-extern u32 gui32MRSTMSVDXDeviceID;
-extern u32 gui32MRSTTOPAZDeviceID;
-
-struct drm_device *gpDrmDevice = NULL;
 static struct mutex power_mutex;
-static bool gbSuspendInProgress = false;
-static bool gbResumeInProgress = false;
-static int g_hw_power_status_mask;
-static atomic_t g_display_access_count;
-static atomic_t g_graphics_access_count;
-static atomic_t g_videoenc_access_count;
-static atomic_t g_videodec_access_count;
-int allow_runtime_pm = 0;
-
-void ospm_power_island_up(int hw_islands);
-void ospm_power_island_down(int hw_islands);
-static bool gbSuspended = false;
-bool gbgfxsuspended = false;
 
-/*
- * ospm_power_init
+/**
+ *	gma_power_init		-	initialise power manager
+ *	@dev: our device
  *
- * Description: Initialize this ospm power management module
+ *	Set up for power management tracking of our hardware.
  */
-void ospm_power_init(struct drm_device *dev)
+void gma_power_init(struct drm_device *dev)
 {
-	struct drm_psb_private *dev_priv = (struct drm_psb_private *)dev->dev_private;
-
-	gpDrmDevice = dev;
+	struct drm_psb_private *dev_priv = dev->dev_private;
 
 	dev_priv->apm_base = dev_priv->apm_reg & 0xffff;
 	dev_priv->ospm_base &= 0xffff;
 
+	dev_priv->display_power = true;	/* We start active */
+	dev_priv->display_count = 0;	/* Currently no users */
+	dev_priv->suspended = false;	/* And not suspended */
 	mutex_init(&power_mutex);
-	g_hw_power_status_mask = OSPM_ALL_ISLANDS;
-	atomic_set(&g_display_access_count, 0);
-	atomic_set(&g_graphics_access_count, 0);
-	atomic_set(&g_videoenc_access_count, 0);
-	atomic_set(&g_videodec_access_count, 0);
+
+	if (!IS_MRST(dev)) {
+		/* FIXME: wants further review */
+		u32 gating = PSB_RSGX32(PSB_CR_CLKGATECTL);
+		/* Disable 2D clock gating */
+		gating &= ~3;
+		gating |= 1;
+		PSB_WSGX32(gating, PSB_CR_CLKGATECTL);
+		PSB_RSGX32(PSB_CR_CLKGATECTL);
+	}
 }
 
-/*
- * ospm_power_uninit
+/**
+ *	gma_power_uninit	-	end power manager
+ *	@dev: device to end for
  *
- * Description: Uninitialize this ospm power management module
+ *	Undo the effects of gma_power_init
  */
-void ospm_power_uninit(void)
+void gma_power_uninit(struct drm_device *dev)
 {
 	mutex_destroy(&power_mutex);
-    	pm_runtime_disable(&gpDrmDevice->pdev->dev);
-	pm_runtime_set_suspended(&gpDrmDevice->pdev->dev);
+	pm_runtime_disable(&dev->pdev->dev);
+	pm_runtime_set_suspended(&dev->pdev->dev);
 }
 
 
-/*
- * save_display_registers
+/**
+ *	save_display_registers	-	save registers lost on suspend
+ *	@dev: our DRM device
  *
- * Description: We are going to suspend so save current display
- * register state.
+ *	Save the state we need in order to be able to restore the interface
+ *	upon resume from suspend
  */
 static int save_display_registers(struct drm_device *dev)
 {
 	struct drm_psb_private *dev_priv = dev->dev_private;
-	struct drm_crtc * crtc;
-	struct drm_connector * connector;
+	struct drm_crtc *crtc;
+	struct drm_connector *connector;
 
 	/* Display arbitration control + watermarks */
 	dev_priv->saveDSPARB = PSB_RVDC32(DSPARB);
@@ -112,37 +102,31 @@
 	dev_priv->saveDSPFW6 = PSB_RVDC32(DSPFW6);
 	dev_priv->saveCHICKENBIT = PSB_RVDC32(DSPCHICKENBIT);
 
-	/*save crtc and output state*/
+	/* Save crtc and output state */
 	mutex_lock(&dev->mode_config.mutex);
 	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
-		if(drm_helper_crtc_in_use(crtc)) {
+		if (drm_helper_crtc_in_use(crtc))
 			crtc->funcs->save(crtc);
-		}
 	}
 
-	list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
+	list_for_each_entry(connector, &dev->mode_config.connector_list, head)
 		connector->funcs->save(connector);
-	}
-	mutex_unlock(&dev->mode_config.mutex);
-
-	/* Interrupt state */
-	/*
-	 * Handled in psb_irq.c
-	 */
 
+	mutex_unlock(&dev->mode_config.mutex);
 	return 0;
 }
 
-/*
- * restore_display_registers
+/**
+ *	restore_display_registers	-	restore lost register state
+ *	@dev: our DRM device
  *
- * Description: We are going to resume so restore display register state.
+ *	Restore register state that was lost during suspend and resume.
  */
 static int restore_display_registers(struct drm_device *dev)
 {
 	struct drm_psb_private *dev_priv = dev->dev_private;
-	struct drm_crtc * crtc;
-	struct drm_connector * connector;
+	struct drm_crtc *crtc;
+	struct drm_connector *connector;
 
 	/* Display arbitration + watermarks */
 	PSB_WVDC32(dev_priv->saveDSPARB, DSPARB);
@@ -158,39 +142,57 @@
 	PSB_WVDC32(0x80000000, VGACNTRL);
 
 	mutex_lock(&dev->mode_config.mutex);
-	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
-		if(drm_helper_crtc_in_use(crtc))
+	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head)
+		if (drm_helper_crtc_in_use(crtc))
 			crtc->funcs->restore(crtc);
-	}
-	list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
-		connector->funcs->restore(connector);
-	}
-	mutex_unlock(&dev->mode_config.mutex);
 
-	/*Interrupt state*/
-	/*
-	 * Handled in psb_irq.c
-	 */
+	list_for_each_entry(connector, &dev->mode_config.connector_list, head)
+		connector->funcs->restore(connector);
 
+	mutex_unlock(&dev->mode_config.mutex);
 	return 0;
 }
-/*
- * powermgmt_suspend_display
+
+/**
+ *	power_down	-	power down the display island
+ *	@dev: our DRM device
  *
- * Description: Suspend the display hardware saving state and disabling
- * as necessary.
+ *	Power down the display interface of our device
  */
-void ospm_suspend_display(struct drm_device *dev)
+static void power_down(struct drm_device *dev)
 {
 	struct drm_psb_private *dev_priv = dev->dev_private;
-	int pp_stat, ret=0;
+	u32 pwr_mask ;
+	u32 pwr_sts;
 
-	printk(KERN_ALERT "%s \n", __func__);
+	if (IS_MRST(dev)) {
+		pwr_mask = PSB_PWRGT_DISPLAY_MASK;
+		outl(pwr_mask, dev_priv->ospm_base + PSB_PM_SSC);
 
-#ifdef OSPM_GFX_DPK
-	printk(KERN_ALERT "%s \n", __func__);
-#endif
-	if (!(g_hw_power_status_mask & OSPM_DISPLAY_ISLAND))
+		while (true) {
+			pwr_sts = inl(dev_priv->ospm_base + PSB_PM_SSS);
+			if ((pwr_sts & pwr_mask) == pwr_mask)
+				break;
+			else
+				udelay(10);
+		}
+		dev_priv->display_power = false;
+	}
+}
+
+
+/**
+ *	gma_suspend_display	-	suspend the display logic
+ *	@dev: our DRM device
+ *
+ *	Suspend the display logic of the graphics interface
+ */
+static void gma_suspend_display(struct drm_device *dev)
+{
+	struct drm_psb_private *dev_priv = dev->dev_private;
+	int pp_stat;
+
+	if (dev_priv->suspended)
 		return;
 
 	save_display_registers(dev);
@@ -225,37 +227,58 @@
 			!= DPI_FIFO_EMPTY);
 		PSB_WVDC32(0, DEVICE_READY_REG);
 			/* turn off panel power */
-		ret = 0;
 	}
-	ospm_power_island_down(OSPM_DISPLAY_ISLAND);
+	power_down(dev);
 }
 
 /*
- * ospm_resume_display
+ * power_up
  *
- * Description: Resume the display hardware restoring state and enabling
- * as necessary.
+ * Description: Restore power to the specified island(s) (powergating)
  */
-void ospm_resume_display(struct pci_dev *pdev)
+static void power_up(struct drm_device *dev)
 {
-	struct drm_device *dev = pci_get_drvdata(pdev);
 	struct drm_psb_private *dev_priv = dev->dev_private;
-	struct psb_gtt *pg = dev_priv->pg;
+	u32 pwr_mask = PSB_PWRGT_DISPLAY_MASK;
+	u32 pwr_sts, pwr_cnt;
 
-	printk(KERN_ALERT "%s \n", __func__);
+	if (IS_MRST(dev)) {
+		pwr_cnt = inl(dev_priv->ospm_base + PSB_PM_SSC);
+		pwr_cnt &= ~pwr_mask;
+		outl(pwr_cnt, (dev_priv->ospm_base + PSB_PM_SSC));
 
-#ifdef OSPM_GFX_DPK
-	printk(KERN_ALERT "%s \n", __func__);
-#endif
-	if (g_hw_power_status_mask & OSPM_DISPLAY_ISLAND)
+		while (true) {
+			pwr_sts = inl(dev_priv->ospm_base + PSB_PM_SSS);
+			if ((pwr_sts & pwr_mask) == 0)
+				break;
+			else
+				udelay(10);
+		}
+	}
+	dev_priv->suspended = false;
+	dev_priv->display_power = true;
+}
+
+/**
+ *	gma_resume_display	-	resume display side logic
+ *
+ *	Resume the display hardware restoring state and enabling
+ *	as necessary.
+ */
+static void gma_resume_display(struct pci_dev *pdev)
+{
+	struct drm_device *dev = pci_get_drvdata(pdev);
+	struct drm_psb_private *dev_priv = dev->dev_private;
+
+	if (dev_priv->suspended == false)
 		return;
 
 	/* turn on the display power island */
-	ospm_power_island_up(OSPM_DISPLAY_ISLAND);
+	power_up(dev);
 
-	PSB_WVDC32(pg->pge_ctl | _PSB_PGETBL_ENABLED, PSB_PGETBL_CTL);
+	PSB_WVDC32(dev_priv->pge_ctl | _PSB_PGETBL_ENABLED, PSB_PGETBL_CTL);
 	pci_write_config_word(pdev, PSB_GMCH_CTRL,
-			pg->gmch_ctrl | _PSB_GMCH_ENABLED);
+			dev_priv->gmch_ctrl | _PSB_GMCH_ENABLED);
 
 	/* Don't reinitialize the GTT as it is unnecessary.  The gtt is
 	 * stored in memory so it will automatically be restored.  All
@@ -267,26 +290,21 @@
 	restore_display_registers(dev);
 }
 
-#if 1
-/*
- * ospm_suspend_pci
+/**
+ *	gma_suspend_pci		-	suspend PCI side
+ *	@pdev: PCI device
  *
- * Description: Suspend the pci device saving state and disabling
- * as necessary.
+ *	Perform the suspend processing on our PCI device state
  */
-static void ospm_suspend_pci(struct pci_dev *pdev)
+static void gma_suspend_pci(struct pci_dev *pdev)
 {
 	struct drm_device *dev = pci_get_drvdata(pdev);
 	struct drm_psb_private *dev_priv = dev->dev_private;
 	int bsm, vbt;
 
-	if (gbSuspended)
+	if (dev_priv->suspended)
 		return;
 
-#ifdef OSPM_GFX_DPK
-	printk(KERN_ALERT "ospm_suspend_pci\n");
-#endif
-
 	pci_save_state(pdev);
 	pci_read_config_dword(pdev, 0x5C, &bsm);
 	dev_priv->saveBSM = bsm;
@@ -298,29 +316,25 @@
 	pci_disable_device(pdev);
 	pci_set_power_state(pdev, PCI_D3hot);
 
-	gbSuspended = true;
-	gbgfxsuspended = true;
+	dev_priv->suspended = true;
 }
 
-/*
- * ospm_resume_pci
+/**
+ *	gma_resume_pci		-	resume helper
+ *	@dev: our PCI device
  *
- * Description: Resume the pci device restoring state and enabling
- * as necessary.
+ *	Perform the resume processing on our PCI device state - rewrite
+ *	register state and re-enable the PCI device
  */
-static bool ospm_resume_pci(struct pci_dev *pdev)
+static bool gma_resume_pci(struct pci_dev *pdev)
 {
 	struct drm_device *dev = pci_get_drvdata(pdev);
 	struct drm_psb_private *dev_priv = dev->dev_private;
-	int ret = 0;
+	int ret;
 
-	if (!gbSuspended)
+	if (!dev_priv->suspended)
 		return true;
 
-#ifdef OSPM_GFX_DPK
-	printk(KERN_ALERT "ospm_resume_pci\n");
-#endif
-
 	pci_set_power_state(pdev, PCI_D0);
 	pci_restore_state(pdev);
 	pci_write_config_dword(pdev, 0x5c, dev_priv->saveBSM);
@@ -331,448 +345,131 @@
 	ret = pci_enable_device(pdev);
 
 	if (ret != 0)
-		printk(KERN_ALERT "ospm_resume_pci: pci_enable_device failed: %d\n", ret);
+		dev_err(&pdev->dev, "pci_enable failed: %d\n", ret);
 	else
-		gbSuspended = false;
-
-	return !gbSuspended;
-}
-#endif
-/*
- * ospm_power_suspend
- *
- * Description: OSPM is telling our driver to suspend so save state
- * and power down all hardware.
- */
-int ospm_power_suspend(struct pci_dev *pdev, pm_message_t state)
-{
-        int ret = 0;
-        int graphics_access_count;
-        int videoenc_access_count;
-        int videodec_access_count;
-        int display_access_count;
-    	bool suspend_pci = true;
-
-	if(gbSuspendInProgress || gbResumeInProgress)
-        {
-#ifdef OSPM_GFX_DPK
-                printk(KERN_ALERT "OSPM_GFX_DPK: %s system BUSY \n", __func__);
-#endif
-                return  -EBUSY;
-        }
-
-        mutex_lock(&power_mutex);
-
-        if (!gbSuspended) {
-                graphics_access_count = atomic_read(&g_graphics_access_count);
-                videoenc_access_count = atomic_read(&g_videoenc_access_count);
-                videodec_access_count = atomic_read(&g_videodec_access_count);
-                display_access_count = atomic_read(&g_display_access_count);
-
-                if (graphics_access_count ||
-			videoenc_access_count ||
-			videodec_access_count ||
-			display_access_count)
-                        ret = -EBUSY;
-
-                if (!ret) {
-                        gbSuspendInProgress = true;
-
-                        psb_irq_uninstall_islands(gpDrmDevice, OSPM_DISPLAY_ISLAND);
-                        ospm_suspend_display(gpDrmDevice);
-                        if (suspend_pci == true) {
-				ospm_suspend_pci(pdev);
-                        }
-                        gbSuspendInProgress = false;
-                } else {
-                        printk(KERN_ALERT "ospm_power_suspend: device busy: graphics %d videoenc %d videodec %d display %d\n", graphics_access_count, videoenc_access_count, videodec_access_count, display_access_count);
-                }
-        }
-
-
-        mutex_unlock(&power_mutex);
-        return ret;
+		dev_priv->suspended = false;
+	return !dev_priv->suspended;
 }
 
-/*
- * ospm_power_island_up
+/**
+ *	gma_power_suspend		-	bus callback for suspend
+ *	@pdev: our PCI device
+ *	@state: suspend type
  *
- * Description: Restore power to the specified island(s) (powergating)
+ *	Called back by the PCI layer during a suspend of the system. We
+ *	perform the necessary shut down steps and save enough state that
+ *	we can undo this when resume is called.
  */
-void ospm_power_island_up(int hw_islands)
+int gma_power_suspend(struct pci_dev *pdev, pm_message_t state)
 {
-	u32 pwr_cnt = 0;
-	u32 pwr_sts = 0;
-	u32 pwr_mask = 0;
-
-	struct drm_psb_private *dev_priv =
-		(struct drm_psb_private *) gpDrmDevice->dev_private;
-
-
-	if (hw_islands & OSPM_DISPLAY_ISLAND) {
-		pwr_mask = PSB_PWRGT_DISPLAY_MASK;
-
-		pwr_cnt = inl(dev_priv->ospm_base + PSB_PM_SSC);
-		pwr_cnt &= ~pwr_mask;
-		outl(pwr_cnt, (dev_priv->ospm_base + PSB_PM_SSC));
+	struct drm_device *dev = pci_get_drvdata(pdev);
+	struct drm_psb_private *dev_priv = dev->dev_private;
 
-		while (true) {
-			pwr_sts = inl(dev_priv->ospm_base + PSB_PM_SSS);
-			if ((pwr_sts & pwr_mask) == 0)
-				break;
-			else
-				udelay(10);
+	mutex_lock(&power_mutex);
+	if (!dev_priv->suspended) {
+		if (dev_priv->display_count) {
+			mutex_unlock(&power_mutex);
+			return -EBUSY;
 		}
+		psb_irq_uninstall(dev);
+		gma_suspend_display(dev);
+		gma_suspend_pci(pdev);
 	}
-
-	g_hw_power_status_mask |= hw_islands;
-}
-
-/*
- * ospm_power_resume
- */
-int ospm_power_resume(struct pci_dev *pdev)
-{
-	if(gbSuspendInProgress || gbResumeInProgress)
-        {
-#ifdef OSPM_GFX_DPK
-                printk(KERN_ALERT "OSPM_GFX_DPK: %s hw_island: Suspend || gbResumeInProgress!!!! \n", __func__);
-#endif
-                return 0;
-        }
-
-        mutex_lock(&power_mutex);
-
-#ifdef OSPM_GFX_DPK
-	printk(KERN_ALERT "OSPM_GFX_DPK: ospm_power_resume \n");
-#endif
-
-  	gbResumeInProgress = true;
-
-        ospm_resume_pci(pdev);
-
-	ospm_resume_display(gpDrmDevice->pdev);
-        psb_irq_preinstall_islands(gpDrmDevice, OSPM_DISPLAY_ISLAND);
-        psb_irq_postinstall_islands(gpDrmDevice, OSPM_DISPLAY_ISLAND);
-
-	gbResumeInProgress = false;
-
-        mutex_unlock(&power_mutex);
-
+	mutex_unlock(&power_mutex);
 	return 0;
 }
 
 
-/*
- * ospm_power_island_down
+/**
+ *	gma_power_resume		-	resume power
+ *	@pdev: PCI device
  *
- * Description: Cut power to the specified island(s) (powergating)
+ *	Resume the PCI side of the graphics and then the displays
  */
-void ospm_power_island_down(int islands)
+int gma_power_resume(struct pci_dev *pdev)
 {
-#if 0
-	u32 pwr_cnt = 0;
-	u32 pwr_mask = 0;
-	u32 pwr_sts = 0;
-
-	struct drm_psb_private *dev_priv =
-		(struct drm_psb_private *) gpDrmDevice->dev_private;
-
-	g_hw_power_status_mask &= ~islands;
-
-	if (islands & OSPM_GRAPHICS_ISLAND) {
-		pwr_cnt |= PSB_PWRGT_GFX_MASK;
-		pwr_mask |= PSB_PWRGT_GFX_MASK;
-		if (dev_priv->graphics_state == PSB_PWR_STATE_ON) {
-			dev_priv->gfx_on_time += (jiffies - dev_priv->gfx_last_mode_change) * 1000 / HZ;
-			dev_priv->gfx_last_mode_change = jiffies;
-			dev_priv->graphics_state = PSB_PWR_STATE_OFF;
-			dev_priv->gfx_off_cnt++;
-		}
-	}
-	if (islands & OSPM_VIDEO_ENC_ISLAND) {
-		pwr_cnt |= PSB_PWRGT_VID_ENC_MASK;
-		pwr_mask |= PSB_PWRGT_VID_ENC_MASK;
-	}
-	if (islands & OSPM_VIDEO_DEC_ISLAND) {
-		pwr_cnt |= PSB_PWRGT_VID_DEC_MASK;
-		pwr_mask |= PSB_PWRGT_VID_DEC_MASK;
-	}
-	if (pwr_cnt) {
-		pwr_cnt |= inl(dev_priv->apm_base);
-		outl(pwr_cnt, dev_priv->apm_base  + PSB_APM_CMD);
-		while (true) {
-			pwr_sts = inl(dev_priv->apm_base + PSB_APM_STS);
-
-			if ((pwr_sts & pwr_mask) == pwr_mask)
-				break;
-			else
-				udelay(10);
-		}
-	}
-
-	if (islands & OSPM_DISPLAY_ISLAND) {
-		pwr_mask = PSB_PWRGT_DISPLAY_MASK;
-
-		outl(pwr_mask, (dev_priv->ospm_base + PSB_PM_SSC));
+	struct drm_device *dev = pci_get_drvdata(pdev);
 
-		while (true) {
-			pwr_sts = inl(dev_priv->ospm_base + PSB_PM_SSS);
-			if ((pwr_sts & pwr_mask) == pwr_mask)
-				break;
-			else
-				udelay(10);
-		}
-	}
-#endif
+	mutex_lock(&power_mutex);
+	gma_resume_pci(pdev);
+	gma_resume_display(pdev);
+	psb_irq_preinstall(dev);
+	psb_irq_postinstall(dev);
+	mutex_unlock(&power_mutex);
+	return 0;
 }
 
 
-/*
- * ospm_power_is_hw_on
+
+/**
+ *	gma_power_is_on		-	returne true if power is on
+ *	@dev: our DRM device
  *
- * Description: do an instantaneous check for if the specified islands
- * are on.  Only use this in cases where you know the g_state_change_mutex
- * is already held such as in irq install/uninstall.  Otherwise, use
- * ospm_power_using_hw_begin().
+ *	Returns true if the display island power is on at this moment
  */
-bool ospm_power_is_hw_on(int hw_islands)
+bool gma_power_is_on(struct drm_device *dev)
 {
-	return ((g_hw_power_status_mask & hw_islands) == hw_islands) ? true:false;
+	struct drm_psb_private *dev_priv = dev->dev_private;
+	return dev_priv->display_power;
 }
 
-/*
- * ospm_power_using_hw_begin
+
+/**
+ *	gma_power_begin		-	begin requiring power
+ *	@dev: our DRM device
+ *	@force_on: true to force power on
  *
- * Description: Notify PowerMgmt module that you will be accessing the
- * specified island's hw so don't power it off.  If force_on is true,
- * this will power on the specified island if it is off.
- * Otherwise, this will return false and the caller is expected to not
- * access the hw.
+ *	Begin an action that requires the display power island is enabled.
+ *	We refcount the islands.
  *
- * NOTE *** If this is called from and interrupt handler or other atomic
- * context, then it will return false if we are in the middle of a
- * power state transition and the caller will be expected to handle that
- * even if force_on is set to true.
+ *	FIXME: locking
  */
-bool ospm_power_using_hw_begin(int hw_island, UHBUsage usage)
+bool gma_power_begin(struct drm_device *dev, bool force_on)
 {
-        return 1;	/*FIXMEAC */
-#if 0
-	bool ret = true;
-	bool island_is_off = false;
-	bool b_atomic = (in_interrupt() || in_atomic());
-	bool locked = true;
-	struct pci_dev *pdev = gpDrmDevice->pdev;
-	u32 deviceID = 0;
-	bool force_on = usage ? true: false;
-	/*quick path, not 100% race safe, but should be enough comapre to current other code in this file */
-	if (!force_on) {
-		if (hw_island & (OSPM_ALL_ISLANDS & ~g_hw_power_status_mask))
-			return false;
-		else {
-			locked = false;
-#ifdef CONFIG_PM_RUNTIME
-			/* increment pm_runtime_refcount */
-			pm_runtime_get(&pdev->dev);
-#endif
-			goto increase_count;
-		}
-	}
-
-
-	if (!b_atomic)
-		mutex_lock(&power_mutex);
-
-	island_is_off = hw_island & (OSPM_ALL_ISLANDS & ~g_hw_power_status_mask);
-
-	if (b_atomic && (gbSuspendInProgress || gbResumeInProgress || gbSuspended) && force_on && island_is_off)
-		ret = false;
-
-	if (ret && island_is_off && !force_on)
-		ret = false;
-
-	if (ret && island_is_off && force_on) {
-		gbResumeInProgress = true;
-
-		ret = ospm_resume_pci(pdev);
-
-		if (ret) {
-			switch(hw_island)
-			{
-			case OSPM_DISPLAY_ISLAND:
-				deviceID = gui32MRSTDisplayDeviceID;
-				ospm_resume_display(pdev);
-				psb_irq_preinstall_islands(gpDrmDevice, OSPM_DISPLAY_ISLAND);
-				psb_irq_postinstall_islands(gpDrmDevice, OSPM_DISPLAY_ISLAND);
-				break;
-			case OSPM_GRAPHICS_ISLAND:
-				deviceID = gui32SGXDeviceID;
-				ospm_power_island_up(OSPM_GRAPHICS_ISLAND);
-				psb_irq_preinstall_islands(gpDrmDevice, OSPM_GRAPHICS_ISLAND);
-				psb_irq_postinstall_islands(gpDrmDevice, OSPM_GRAPHICS_ISLAND);
-				break;
-#if 1
-			case OSPM_VIDEO_DEC_ISLAND:
-				if(!ospm_power_is_hw_on(OSPM_DISPLAY_ISLAND)) {
-					//printk(KERN_ALERT "%s power on display for video decode use\n", __func__);
-					deviceID = gui32MRSTDisplayDeviceID;
-					ospm_resume_display(pdev);
-					psb_irq_preinstall_islands(gpDrmDevice, OSPM_DISPLAY_ISLAND);
-					psb_irq_postinstall_islands(gpDrmDevice, OSPM_DISPLAY_ISLAND);
-				}
-				else{
-					//printk(KERN_ALERT "%s display is already on for video decode use\n", __func__);
-				}
-
-				if(!ospm_power_is_hw_on(OSPM_VIDEO_DEC_ISLAND)) {
-					//printk(KERN_ALERT "%s power on video decode\n", __func__);
-					deviceID = gui32MRSTMSVDXDeviceID;
-					ospm_power_island_up(OSPM_VIDEO_DEC_ISLAND);
-					psb_irq_preinstall_islands(gpDrmDevice, OSPM_VIDEO_DEC_ISLAND);
-					psb_irq_postinstall_islands(gpDrmDevice, OSPM_VIDEO_DEC_ISLAND);
-				}
-				else{
-					//printk(KERN_ALERT "%s video decode is already on\n", __func__);
-				}
-
-				break;
-			case OSPM_VIDEO_ENC_ISLAND:
-				if(!ospm_power_is_hw_on(OSPM_DISPLAY_ISLAND)) {
-					//printk(KERN_ALERT "%s power on display for video encode\n", __func__);
-					deviceID = gui32MRSTDisplayDeviceID;
-					ospm_resume_display(pdev);
-					psb_irq_preinstall_islands(gpDrmDevice, OSPM_DISPLAY_ISLAND);
-					psb_irq_postinstall_islands(gpDrmDevice, OSPM_DISPLAY_ISLAND);
-				}
-				else{
-					//printk(KERN_ALERT "%s display is already on for video encode use\n", __func__);
-				}
-
-				if(!ospm_power_is_hw_on(OSPM_VIDEO_ENC_ISLAND)) {
-					//printk(KERN_ALERT "%s power on video encode\n", __func__);
-					deviceID = gui32MRSTTOPAZDeviceID;
-					ospm_power_island_up(OSPM_VIDEO_ENC_ISLAND);
-					psb_irq_preinstall_islands(gpDrmDevice, OSPM_VIDEO_ENC_ISLAND);
-					psb_irq_postinstall_islands(gpDrmDevice, OSPM_VIDEO_ENC_ISLAND);
-				}
-				else{
-					//printk(KERN_ALERT "%s video decode is already on\n", __func__);
-				}
-#endif
-				break;
-
-			default:
-				printk(KERN_ALERT "%s unknown island !!!! \n", __func__);
-				break;
-			}
-
-		}
-
-		if (!ret)
-			printk(KERN_ALERT "ospm_power_using_hw_begin: forcing on %d failed\n", hw_island);
+	struct drm_psb_private *dev_priv = dev->dev_private;
+	int ret;
 
-		gbResumeInProgress = false;
-	}
-increase_count:
-	if (ret) {
-		switch(hw_island)
-		{
-		case OSPM_GRAPHICS_ISLAND:
-			atomic_inc(&g_graphics_access_count);
-			break;
-		case OSPM_VIDEO_ENC_ISLAND:
-			atomic_inc(&g_videoenc_access_count);
-			break;
-		case OSPM_VIDEO_DEC_ISLAND:
-			atomic_inc(&g_videodec_access_count);
-			break;
-		case OSPM_DISPLAY_ISLAND:
-			atomic_inc(&g_display_access_count);
-			break;
-		}
+	/* Power already on ? */
+	if (dev_priv->display_power) {
+		dev_priv->display_count++;
+		pm_runtime_get(&dev->pdev->dev);
+		return true;
 	}
+	if (force_on == false)
+		return false;
 
-	if (!b_atomic && locked)
-		mutex_unlock(&power_mutex);
-
-	return ret;
-#endif
+	/* Ok power up needed */
+	ret = gma_resume_pci(dev->pdev);
+	if (ret == 0) {
+		psb_irq_preinstall(dev);
+		psb_irq_postinstall(dev);
+		pm_runtime_get(&dev->pdev->dev);
+		dev_priv->display_count++;
+		return true;
+	}
+	return false;
 }
 
 
-/*
- * ospm_power_using_hw_end
+/**
+ *	gma_power_end		-	end use of power
+ *	@dev: Our DRM device
  *
- * Description: Notify PowerMgmt module that you are done accessing the
- * specified island's hw so feel free to power it off.  Note that this
- * function doesn't actually power off the islands.
+ *	Indicate that one of our gma_power_begin() requested periods when
+ *	the diplay island power is needed has completed.
  */
-void ospm_power_using_hw_end(int hw_island)
-{
-#if 0 /* FIXMEAC */
-	switch(hw_island)
-	{
-	case OSPM_GRAPHICS_ISLAND:
-		atomic_dec(&g_graphics_access_count);
-		break;
-	case OSPM_VIDEO_ENC_ISLAND:
-		atomic_dec(&g_videoenc_access_count);
-		break;
-	case OSPM_VIDEO_DEC_ISLAND:
-		atomic_dec(&g_videodec_access_count);
-		break;
-	case OSPM_DISPLAY_ISLAND:
-		atomic_dec(&g_display_access_count);
-		break;
-	}
-
-	//decrement runtime pm ref count
-	pm_runtime_put(&gpDrmDevice->pdev->dev);
-
-	WARN_ON(atomic_read(&g_graphics_access_count) < 0);
-	WARN_ON(atomic_read(&g_videoenc_access_count) < 0);
-	WARN_ON(atomic_read(&g_videodec_access_count) < 0);
-	WARN_ON(atomic_read(&g_display_access_count) < 0);
-#endif
-}
-
-int ospm_runtime_pm_allow(struct drm_device * dev)
-{
-	return 0;
-}
-
-void ospm_runtime_pm_forbid(struct drm_device * dev)
+void gma_power_end(struct drm_device *dev)
 {
-	struct drm_psb_private * dev_priv = dev->dev_private;
-
-	DRM_INFO("%s\n", __FUNCTION__);
-
-	pm_runtime_forbid(&dev->pdev->dev);
-	dev_priv->rpm_enabled = 0;
+	struct drm_psb_private *dev_priv = dev->dev_private;
+	dev_priv->display_count--;
+	WARN_ON(dev_priv->display_count < 0);
+	pm_runtime_put(&dev->pdev->dev);
 }
 
 int psb_runtime_suspend(struct device *dev)
 {
-	pm_message_t state;
-	int ret = 0;
-	state.event = 0;
-
-#ifdef OSPM_GFX_DPK
-	printk(KERN_ALERT "OSPM_GFX_DPK: %s \n", __func__);
-#endif
-        if (atomic_read(&g_graphics_access_count) || atomic_read(&g_videoenc_access_count)
-		|| atomic_read(&g_videodec_access_count) || atomic_read(&g_display_access_count)){
-#ifdef OSPM_GFX_DPK
-                printk(KERN_ALERT "OSPM_GFX_DPK: GFX: %d VEC: %d VED: %d DC: %d DSR: %d \n", atomic_read(&g_graphics_access_count),
-			atomic_read(&g_videoenc_access_count), atomic_read(&g_videodec_access_count), atomic_read(&g_display_access_count));
-#endif
-                return -EBUSY;
-        }
-        else
-		ret = ospm_power_suspend(gpDrmDevice->pdev, state);
-
-	return ret;
+	static pm_message_t dummy;
+	return gma_power_suspend(to_pci_dev(dev), dummy);
 }
 
 int psb_runtime_resume(struct device *dev)
@@ -782,11 +479,11 @@
 
 int psb_runtime_idle(struct device *dev)
 {
-	/*printk (KERN_ALERT "lvds:%d,mipi:%d\n", dev_priv->is_lvds_on, dev_priv->is_mipi_on);*/
-	if (atomic_read(&g_graphics_access_count) || atomic_read(&g_videoenc_access_count)
-		|| atomic_read(&g_videodec_access_count) || atomic_read(&g_display_access_count))
-		return 1;
-	else
+	struct drm_device *drmdev = pci_get_drvdata(to_pci_dev(dev));
+	struct drm_psb_private *dev_priv = drmdev->dev_private;
+	if (dev_priv->display_count)
 		return 0;
+	else
+		return 1;
 }
 
diff -druN linux-2.6.39-libre/drivers/staging/gma500/psb_powermgmt.h linux-3.0-rc7-libre/drivers/staging/gma500/psb_powermgmt.h
--- linux-2.6.39-libre/drivers/staging/gma500/psb_powermgmt.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/gma500/psb_powermgmt.h	2011-07-11 19:51:52.000000000 -0400
@@ -24,7 +24,8 @@
  * Authors:
  *    Benjamin Defnet <benjamin.r.defnet@intel.com>
  *    Rajesh Poornachandran <rajesh.poornachandran@intel.com>
- *
+ * Massively reworked
+ *    Alan Cox <alan@linux.intel.com>
  */
 #ifndef _PSB_POWERMGMT_H_
 #define _PSB_POWERMGMT_H_
@@ -32,65 +33,35 @@
 #include <linux/pci.h>
 #include <drm/drmP.h>
 
-#define OSPM_GRAPHICS_ISLAND	0x1
-#define OSPM_VIDEO_ENC_ISLAND	0x2
-#define OSPM_VIDEO_DEC_ISLAND	0x4
-#define OSPM_DISPLAY_ISLAND	0x8
-#define OSPM_GL3_CACHE_ISLAND	0x10
-#define OSPM_ALL_ISLANDS	0x1f
-
-/* IPC message and command defines used to enable/disable mipi panel voltages */
-#define IPC_MSG_PANEL_ON_OFF    0xE9
-#define IPC_CMD_PANEL_ON        1
-#define IPC_CMD_PANEL_OFF       0
-
-typedef enum _UHBUsage
-{
-    OSPM_UHB_ONLY_IF_ON = 0,
-    OSPM_UHB_FORCE_POWER_ON,
-} UHBUsage;
-
-/* Use these functions to power down video HW for D0i3 purpose  */
-
-void ospm_power_init(struct drm_device *dev);
-void ospm_power_uninit(void);
-
+void gma_power_init(struct drm_device *dev);
+void gma_power_uninit(struct drm_device *dev);
 
 /*
- * OSPM will call these functions
+ * The kernel bus power management  will call these functions
  */
-int ospm_power_suspend(struct pci_dev *pdev, pm_message_t state);
-int ospm_power_resume(struct pci_dev *pdev);
+int gma_power_suspend(struct pci_dev *pdev, pm_message_t state);
+int gma_power_resume(struct pci_dev *pdev);
 
 /*
  * These are the functions the driver should use to wrap all hw access
  * (i.e. register reads and writes)
  */
-bool ospm_power_using_hw_begin(int hw_island, UHBUsage usage);
-void ospm_power_using_hw_end(int hw_island);
+bool gma_power_begin(struct drm_device *dev, bool force);
+void gma_power_end(struct drm_device *dev);
 
 /*
  * Use this function to do an instantaneous check for if the hw is on.
- * Only use this in cases where you know the g_state_change_mutex
- * is already held such as in irq install/uninstall and you need to
- * prevent a deadlock situation.  Otherwise use ospm_power_using_hw_begin().
+ * Only use this in cases where you know the mutex is already held such
+ * as in irq install/uninstall and you need to
+ * prevent a deadlock situation.  Otherwise use gma_power_begin().
  */
-bool ospm_power_is_hw_on(int hw_islands);
+bool gma_power_is_on(struct drm_device *dev);
 
 /*
- * Power up/down different hw component rails/islands
- */
-void ospm_power_island_down(int hw_islands);
-void ospm_power_island_up(int hw_islands);
-void ospm_suspend_graphics(void);
-/*
  * GFX-Runtime PM callbacks
  */
 int psb_runtime_suspend(struct device *dev);
 int psb_runtime_resume(struct device *dev);
 int psb_runtime_idle(struct device *dev);
-int ospm_runtime_pm_allow(struct drm_device * dev);
-void ospm_runtime_pm_forbid(struct drm_device * dev);
-
 
 #endif /*_PSB_POWERMGMT_H_*/
diff -druN linux-2.6.39-libre/drivers/staging/gma500/psb_pvr_glue.c linux-3.0-rc7-libre/drivers/staging/gma500/psb_pvr_glue.c
--- linux-2.6.39-libre/drivers/staging/gma500/psb_pvr_glue.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/gma500/psb_pvr_glue.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,73 +0,0 @@
-/*
- * Copyright (c) 2009, Intel Corporation.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- *
- */
-
-#include "psb_pvr_glue.h"
-
-/**
- * FIXME: should NOT use these file under env/linux directly
- */
-
-int psb_get_meminfo_by_handle(void *hKernelMemInfo,
-				void **ppsKernelMemInfo)
-{
-	return -EINVAL;
-#if 0
-	void *psKernelMemInfo = IMG_NULL;
-	PVRSRV_PER_PROCESS_DATA *psPerProc = IMG_NULL;
-	PVRSRV_ERROR eError;
-
-	psPerProc = PVRSRVPerProcessData(task_tgid_nr(current));
-	eError = PVRSRVLookupHandle(psPerProc->psHandleBase,
-				    (IMG_VOID *)&psKernelMemInfo,
-				    hKernelMemInfo,
-				    PVRSRV_HANDLE_TYPE_MEM_INFO);
-	if (eError != PVRSRV_OK) {
-		DRM_ERROR("Cannot find kernel meminfo for handle 0x%x\n",
-			  (u32)hKernelMemInfo);
-		return -EINVAL;
-	}
-
-	*ppsKernelMemInfo = psKernelMemInfo;
-
-	DRM_DEBUG("Got Kernel MemInfo for handle %lx\n",
-		  (u32)hKernelMemInfo);
-	return 0;
-#endif
-}
-
-int psb_get_pages_by_mem_handle(void *hOSMemHandle, struct page ***pages)
-{
-	return -EINVAL;
-#if 0
-	LinuxMemArea *psLinuxMemArea = (LinuxMemArea *)hOSMemHandle;
-	struct page **page_list;
-	if (psLinuxMemArea->eAreaType != LINUX_MEM_AREA_ALLOC_PAGES) {
-		DRM_ERROR("MemArea type is not LINUX_MEM_AREA_ALLOC_PAGES\n");
-		return -EINVAL;
-	}
-
-	page_list = psLinuxMemArea->uData.sPageList.pvPageList;
-	if (!page_list) {
-		DRM_DEBUG("Page List is NULL\n");
-		return -ENOMEM;
-	}
-
-	*pages = page_list;
-	return 0;
-#endif
-}
diff -druN linux-2.6.39-libre/drivers/staging/gma500/psb_pvr_glue.h linux-3.0-rc7-libre/drivers/staging/gma500/psb_pvr_glue.h
--- linux-2.6.39-libre/drivers/staging/gma500/psb_pvr_glue.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/gma500/psb_pvr_glue.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,25 +0,0 @@
-/*
- * Copyright (c) 2009, Intel Corporation.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- *
- */
-
-#include "psb_drv.h"
-
-extern int psb_get_meminfo_by_handle(void * hKernelMemInfo,
-				void **ppsKernelMemInfo);
-extern u32 psb_get_tgid(void);
-extern int psb_get_pages_by_mem_handle(void * hOSMemHandle,
-					struct page ***pages);
diff -druN linux-2.6.39-libre/drivers/staging/gma500/psb_reset.c linux-3.0-rc7-libre/drivers/staging/gma500/psb_reset.c
--- linux-2.6.39-libre/drivers/staging/gma500/psb_reset.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/gma500/psb_reset.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,90 +0,0 @@
-/**************************************************************************
- * Copyright (c) 2007, 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.
- *
- * Authors: Thomas Hellstrom <thomas-at-tungstengraphics-dot-com>
- **************************************************************************/
-
-#include <drm/drmP.h>
-#include "psb_drv.h"
-#include "psb_reg.h"
-#include "psb_intel_reg.h"
-#include <linux/spinlock.h>
-
-static void psb_lid_timer_func(unsigned long data)
-{
-	struct drm_psb_private * dev_priv = (struct drm_psb_private *)data;
-	struct drm_device *dev = (struct drm_device *)dev_priv->dev;
-	struct timer_list *lid_timer = &dev_priv->lid_timer;
-	unsigned long irq_flags;
-	u32 *lid_state = dev_priv->lid_state;
-	u32 pp_status;
-
-	if (*lid_state == dev_priv->lid_last_state)
-		goto lid_timer_schedule;
-
-	if ((*lid_state) & 0x01) {
-		/*lid state is open*/
-		REG_WRITE(PP_CONTROL, REG_READ(PP_CONTROL) | POWER_TARGET_ON);
-		do {
-			pp_status = REG_READ(PP_STATUS);
-		} while ((pp_status & PP_ON) == 0);
-
-		/*FIXME: should be backlight level before*/
-		psb_intel_lvds_set_brightness(dev, 100);
-	} else {
-		psb_intel_lvds_set_brightness(dev, 0);
-
-		REG_WRITE(PP_CONTROL, REG_READ(PP_CONTROL) & ~POWER_TARGET_ON);
-		do {
-			pp_status = REG_READ(PP_STATUS);
-		} while ((pp_status & PP_ON) == 0);
-	}
-		/* printk(KERN_INFO"%s: lid: closed\n", __FUNCTION__); */
-
-	dev_priv->lid_last_state =  *lid_state;
-
-lid_timer_schedule:
-	spin_lock_irqsave(&dev_priv->lid_lock, irq_flags);
-	if (!timer_pending(lid_timer)) {
-		lid_timer->expires = jiffies + PSB_LID_DELAY;
-		add_timer(lid_timer);
-	}
-	spin_unlock_irqrestore(&dev_priv->lid_lock, irq_flags);
-}
-
-void psb_lid_timer_init(struct drm_psb_private *dev_priv)
-{
-	struct timer_list *lid_timer = &dev_priv->lid_timer;
-	unsigned long irq_flags;
-
-	spin_lock_init(&dev_priv->lid_lock);
-	spin_lock_irqsave(&dev_priv->lid_lock, irq_flags);
-
-	init_timer(lid_timer);
-
-	lid_timer->data = (unsigned long)dev_priv;
-	lid_timer->function = psb_lid_timer_func;
-	lid_timer->expires = jiffies + PSB_LID_DELAY;
-
-	add_timer(lid_timer);
-	spin_unlock_irqrestore(&dev_priv->lid_lock, irq_flags);
-}
-
-void psb_lid_timer_takedown(struct drm_psb_private *dev_priv)
-{
-	del_timer_sync(&dev_priv->lid_timer);
-}
-
diff -druN linux-2.6.39-libre/drivers/staging/gma500/psb_sgx.c linux-3.0-rc7-libre/drivers/staging/gma500/psb_sgx.c
--- linux-2.6.39-libre/drivers/staging/gma500/psb_sgx.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/gma500/psb_sgx.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,238 +0,0 @@
-/**************************************************************************
- * Copyright (c) 2007, Intel Corporation.
- * All Rights Reserved.
- * Copyright (c) 2008, Tungsten Graphics, Inc. Cedar Park, TX. USA.
- * All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- *
- **************************************************************************/
-
-#include <drm/drmP.h>
-#include "psb_drv.h"
-#include "psb_drm.h"
-#include "psb_reg.h"
-#include "ttm/ttm_bo_api.h"
-#include "ttm/ttm_execbuf_util.h"
-#include "psb_ttm_userobj_api.h"
-#include "ttm/ttm_placement.h"
-#include "psb_sgx.h"
-#include "psb_intel_reg.h"
-#include "psb_powermgmt.h"
-
-
-static inline int psb_same_page(unsigned long offset,
-				unsigned long offset2)
-{
-	return (offset & PAGE_MASK) == (offset2 & PAGE_MASK);
-}
-
-static inline unsigned long psb_offset_end(unsigned long offset,
-					      unsigned long end)
-{
-	offset = (offset + PAGE_SIZE) & PAGE_MASK;
-	return (end < offset) ? end : offset;
-}
-
-struct psb_dstbuf_cache {
-	unsigned int dst;
-	struct ttm_buffer_object *dst_buf;
-	unsigned long dst_offset;
-	uint32_t *dst_page;
-	unsigned int dst_page_offset;
-	struct ttm_bo_kmap_obj dst_kmap;
-	bool dst_is_iomem;
-};
-
-struct psb_validate_buffer {
-	struct ttm_validate_buffer base;
-	struct psb_validate_req req;
-	int ret;
-	struct psb_validate_arg __user *user_val_arg;
-	uint32_t flags;
-	uint32_t offset;
-	int po_correct;
-};
-static int
-psb_placement_fence_type(struct ttm_buffer_object *bo,
-			 uint64_t set_val_flags,
-			 uint64_t clr_val_flags,
-			 uint32_t new_fence_class,
-			 uint32_t *new_fence_type)
-{
-	int ret;
-	uint32_t n_fence_type;
-	/*
-	uint32_t set_flags = set_val_flags & 0xFFFFFFFF;
-	uint32_t clr_flags = clr_val_flags & 0xFFFFFFFF;
-	*/
-	struct ttm_fence_object *old_fence;
-	uint32_t old_fence_type;
-	struct ttm_placement placement;
-
-	if (unlikely
-	    (!(set_val_flags &
-	       (PSB_GPU_ACCESS_READ | PSB_GPU_ACCESS_WRITE)))) {
-		DRM_ERROR
-		    ("GPU access type (read / write) is not indicated.\n");
-		return -EINVAL;
-	}
-
-	/* User space driver doesn't set any TTM placement flags in
-					set_val_flags or clr_val_flags */
-	placement.num_placement = 0;/* FIXME  */
-	placement.num_busy_placement = 0;
-	placement.fpfn = 0;
-	placement.lpfn = 0;
-	ret = psb_ttm_bo_check_placement(bo, &placement);
-	if (unlikely(ret != 0))
-		return ret;
-
-	switch (new_fence_class) {
-	default:
-		n_fence_type = _PSB_FENCE_TYPE_EXE;
-	}
-
-	*new_fence_type = n_fence_type;
-	old_fence = (struct ttm_fence_object *) bo->sync_obj;
-	old_fence_type = (uint32_t) (unsigned long) bo->sync_obj_arg;
-
-	if (old_fence && ((new_fence_class != old_fence->fence_class) ||
-			  ((n_fence_type ^ old_fence_type) &
-			   old_fence_type))) {
-		ret = ttm_bo_wait(bo, 0, 1, 0);
-		if (unlikely(ret != 0))
-			return ret;
-	}
-	/*
-	bo->proposed_flags = (bo->proposed_flags | set_flags)
-		& ~clr_flags & TTM_PL_MASK_MEMTYPE;
-	*/
-	return 0;
-}
-
-int psb_validate_kernel_buffer(struct psb_context *context,
-			       struct ttm_buffer_object *bo,
-			       uint32_t fence_class,
-			       uint64_t set_flags, uint64_t clr_flags)
-{
-	struct psb_validate_buffer *item;
-	uint32_t cur_fence_type;
-	int ret;
-
-	if (unlikely(context->used_buffers >= PSB_NUM_VALIDATE_BUFFERS)) {
-		DRM_ERROR("Out of free validation buffer entries for "
-			  "kernel buffer validation.\n");
-		return -ENOMEM;
-	}
-
-	item = &context->buffers[context->used_buffers];
-	item->user_val_arg = NULL;
-	item->base.reserved = 0;
-
-	ret = ttm_bo_reserve(bo, 1, 0, 1, context->val_seq);
-	if (unlikely(ret != 0))
-	        return ret;
-
-	ret = psb_placement_fence_type(bo, set_flags, clr_flags, fence_class,
-				       &cur_fence_type);
-	if (unlikely(ret != 0)) {
-		ttm_bo_unreserve(bo);
-		return ret;
-	}
-
-	item->base.bo = ttm_bo_reference(bo);
-	item->base.new_sync_obj_arg = (void *) (unsigned long) cur_fence_type;
-	item->base.reserved = 1;
-
-	/* Internal locking ??? FIXMEAC */
-	list_add_tail(&item->base.head, &context->kern_validate_list);
-	context->used_buffers++;
-	/*
-	ret = ttm_bo_validate(bo, 1, 0, 0);
-	if (unlikely(ret != 0))
-		goto out_unlock;
-	*/
-	item->offset = bo->offset;
-	item->flags = bo->mem.placement;
-	context->fence_types |= cur_fence_type;
-
-	return ret;
-}
-
-void psb_fence_or_sync(struct drm_file *file_priv,
-		       uint32_t engine,
-		       uint32_t fence_types,
-		       uint32_t fence_flags,
-		       struct list_head *list,
-		       struct psb_ttm_fence_rep *fence_arg,
-		       struct ttm_fence_object **fence_p)
-{
-	struct drm_device *dev = file_priv->minor->dev;
-	struct drm_psb_private *dev_priv = psb_priv(dev);
-	struct ttm_fence_device *fdev = &dev_priv->fdev;
-	int ret;
-	struct ttm_fence_object *fence;
-	struct ttm_object_file *tfile = psb_fpriv(file_priv)->tfile;
-	uint32_t handle;
-
-	ret = ttm_fence_user_create(fdev, tfile,
-				    engine, fence_types,
-				    TTM_FENCE_FLAG_EMIT, &fence, &handle);
-	if (ret) {
-
-		/*
-		 * Fence creation failed.
-		 * Fall back to synchronous operation and idle the engine.
-		 */
-
-		if (!(fence_flags & DRM_PSB_FENCE_NO_USER)) {
-
-			/*
-			 * Communicate to user-space that
-			 * fence creation has failed and that
-			 * the engine is idle.
-			 */
-
-			fence_arg->handle = ~0;
-			fence_arg->error = ret;
-		}
-
-		ttm_eu_backoff_reservation(list);
-		if (fence_p)
-			*fence_p = NULL;
-		return;
-	}
-
-	ttm_eu_fence_buffer_objects(list, fence);
-	if (!(fence_flags & DRM_PSB_FENCE_NO_USER)) {
-		struct ttm_fence_info info = ttm_fence_get_info(fence);
-		fence_arg->handle = handle;
-		fence_arg->fence_class = ttm_fence_class(fence);
-		fence_arg->fence_type = ttm_fence_types(fence);
-		fence_arg->signaled_types = info.signaled_types;
-		fence_arg->error = 0;
-	} else {
-		ret =
-		    ttm_ref_object_base_unref(tfile, handle,
-					      ttm_fence_type);
-		BUG_ON(ret);
-	}
-
-	if (fence_p)
-		*fence_p = fence;
-	else if (fence)
-		ttm_fence_object_unref(&fence);
-}
-
diff -druN linux-2.6.39-libre/drivers/staging/gma500/psb_sgx.h linux-3.0-rc7-libre/drivers/staging/gma500/psb_sgx.h
--- linux-2.6.39-libre/drivers/staging/gma500/psb_sgx.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/gma500/psb_sgx.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,32 +0,0 @@
-/*
- * Copyright (c) 2008, 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.
- *
- * Authors:
- *    Eric Anholt <eric@anholt.net>
- *
- **/
-#ifndef _PSB_SGX_H_
-#define _PSB_SGX_H_
-
-extern int psb_submit_video_cmdbuf(struct drm_device *dev,
-			       struct ttm_buffer_object *cmd_buffer,
-			       unsigned long cmd_offset,
-			       unsigned long cmd_size,
-			       struct ttm_fence_object *fence);
-
-extern int drm_idle_check_interval;
-
-#endif
diff -druN linux-2.6.39-libre/drivers/staging/gma500/psb_ttm_fence_api.h linux-3.0-rc7-libre/drivers/staging/gma500/psb_ttm_fence_api.h
--- linux-2.6.39-libre/drivers/staging/gma500/psb_ttm_fence_api.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/gma500/psb_ttm_fence_api.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,272 +0,0 @@
-/**************************************************************************
- *
- * Copyright (c) 2006-2008 Tungsten Graphics, Inc., Cedar Park, TX., USA
- * All Rights Reserved.
- * Copyright (c) 2009 VMware, Inc., Palo Alto, CA., USA
- * All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- *
- **************************************************************************/
-/*
- * Authors: Thomas Hellstrom <thomas-at-tungstengraphics-dot-com>
- */
-#ifndef _TTM_FENCE_API_H_
-#define _TTM_FENCE_API_H_
-
-#include <linux/list.h>
-#include <linux/kref.h>
-
-#define TTM_FENCE_FLAG_EMIT (1 << 0)
-#define TTM_FENCE_TYPE_EXE  (1 << 0)
-
-struct ttm_fence_device;
-
-/**
- * struct ttm_fence_info
- *
- * @fence_class:    The fence class.
- * @fence_type:     Bitfield indicating types for this fence.
- * @signaled_types: Bitfield indicating which types are signaled.
- * @error:          Last error reported from the device.
- *
- * Used as output from the ttm_fence_get_info
- */
-
-struct ttm_fence_info {
-	uint32_t signaled_types;
-	uint32_t error;
-};
-
-/**
- * struct ttm_fence_object
- *
- * @fdev:            Pointer to the fence device struct.
- * @kref:            Holds the reference count of this fence object.
- * @ring:            List head used for the circular list of not-completely
- *                   signaled fences.
- * @info:            Data for fast retrieval using the ttm_fence_get_info()
- * function.
- * @timeout_jiffies: Absolute jiffies value indicating when this fence
- *                   object times out and, if waited on, calls ttm_fence_lockup
- *                   to check for and resolve a GPU lockup.
- * @sequence:        Fence sequence number.
- * @waiting_types:   Types currently waited on.
- * @destroy:         Called to free the fence object, when its refcount has
- *                   reached zero. If NULL, kfree is used.
- *
- * This struct is provided in the driver interface so that drivers can
- * derive from it and create their own fence implementation. All members
- * are private to the fence implementation and the fence driver callbacks.
- * Otherwise a driver may access the derived object using container_of().
- */
-
-struct ttm_fence_object {
-	struct ttm_fence_device *fdev;
-	struct kref kref;
-	uint32_t fence_class;
-	uint32_t fence_type;
-
-	/*
-	 * The below fields are protected by the fence class
-	 * manager spinlock.
-	 */
-
-	struct list_head ring;
-	struct ttm_fence_info info;
-	unsigned long timeout_jiffies;
-	uint32_t sequence;
-	uint32_t waiting_types;
-	void (*destroy) (struct ttm_fence_object *);
-};
-
-/**
- * ttm_fence_object_init
- *
- * @fdev: Pointer to a struct ttm_fence_device.
- * @fence_class: Fence class for this fence.
- * @type: Fence type for this fence.
- * @create_flags: Flags indicating varios actions at init time. At this point
- * there's only TTM_FENCE_FLAG_EMIT, which triggers a sequence emission to
- * the command stream.
- * @destroy: Destroy function. If NULL, kfree() is used.
- * @fence: The struct ttm_fence_object to initialize.
- *
- * Initialize a pre-allocated fence object. This function, together with the
- * destroy function makes it possible to derive driver-specific fence objects.
- */
-
-extern int
-ttm_fence_object_init(struct ttm_fence_device *fdev,
-		      uint32_t fence_class,
-		      uint32_t type,
-		      uint32_t create_flags,
-		      void (*destroy) (struct ttm_fence_object *fence),
-		      struct ttm_fence_object *fence);
-
-/**
- * ttm_fence_object_create
- *
- * @fdev: Pointer to a struct ttm_fence_device.
- * @fence_class: Fence class for this fence.
- * @type: Fence type for this fence.
- * @create_flags: Flags indicating varios actions at init time. At this point
- * there's only TTM_FENCE_FLAG_EMIT, which triggers a sequence emission to
- * the command stream.
- * @c_fence: On successful termination, *(@c_fence) will point to the created
- * fence object.
- *
- * Create and initialize a struct ttm_fence_object. The destroy function will
- * be set to kfree().
- */
-
-extern int
-ttm_fence_object_create(struct ttm_fence_device *fdev,
-			uint32_t fence_class,
-			uint32_t type,
-			uint32_t create_flags,
-			struct ttm_fence_object **c_fence);
-
-/**
- * ttm_fence_object_wait
- *
- * @fence: The fence object to wait on.
- * @lazy: Allow sleeps to reduce the cpu-usage if polling.
- * @interruptible: Sleep interruptible when waiting.
- * @type_mask: Wait for the given type_mask to signal.
- *
- * Wait for a fence to signal the given type_mask. The function will
- * perform a fence_flush using type_mask. (See ttm_fence_object_flush).
- *
- * Returns
- * -ERESTART if interrupted by a signal.
- * May return driver-specific error codes if timed-out.
- */
-
-extern int
-ttm_fence_object_wait(struct ttm_fence_object *fence,
-		      bool lazy, bool interruptible, uint32_t type_mask);
-
-/**
- * ttm_fence_object_flush
- *
- * @fence: The fence object to flush.
- * @flush_mask: Fence types to flush.
- *
- * Make sure that the given fence eventually signals the
- * types indicated by @flush_mask. Note that this may or may not
- * map to a CPU or GPU flush.
- */
-
-extern int
-ttm_fence_object_flush(struct ttm_fence_object *fence, uint32_t flush_mask);
-
-/**
- * ttm_fence_get_info
- *
- * @fence: The fence object.
- *
- * Copy the info block from the fence while holding relevant locks.
- */
-
-struct ttm_fence_info ttm_fence_get_info(struct ttm_fence_object *fence);
-
-/**
- * ttm_fence_object_ref
- *
- * @fence: The fence object.
- *
- * Return a ref-counted pointer to the fence object indicated by @fence.
- */
-
-static inline struct ttm_fence_object *ttm_fence_object_ref(struct
-							    ttm_fence_object
-							    *fence)
-{
-	kref_get(&fence->kref);
-	return fence;
-}
-
-/**
- * ttm_fence_object_unref
- *
- * @p_fence: Pointer to a ref-counted pinter to a struct ttm_fence_object.
- *
- * Unreference the fence object pointed to by *(@p_fence), clearing
- * *(p_fence).
- */
-
-extern void ttm_fence_object_unref(struct ttm_fence_object **p_fence);
-
-/**
- * ttm_fence_object_signaled
- *
- * @fence: Pointer to the struct ttm_fence_object.
- * @mask: Type mask to check whether signaled.
- *
- * This function checks (without waiting) whether the fence object
- * pointed to by @fence has signaled the types indicated by @mask,
- * and returns 1 if true, 0 if false. This function does NOT perform
- * an implicit fence flush.
- */
-
-extern bool
-ttm_fence_object_signaled(struct ttm_fence_object *fence, uint32_t mask);
-
-/**
- * ttm_fence_class
- *
- * @fence: Pointer to the struct ttm_fence_object.
- *
- * Convenience function that returns the fence class of a
- * struct ttm_fence_object.
- */
-
-static inline uint32_t ttm_fence_class(const struct ttm_fence_object *fence)
-{
-	return fence->fence_class;
-}
-
-/**
- * ttm_fence_types
- *
- * @fence: Pointer to the struct ttm_fence_object.
- *
- * Convenience function that returns the fence types of a
- * struct ttm_fence_object.
- */
-
-static inline uint32_t ttm_fence_types(const struct ttm_fence_object *fence)
-{
-	return fence->fence_type;
-}
-
-/*
- * The functions below are wrappers to the above functions, with
- * similar names but with sync_obj omitted. These wrappers are intended
- * to be plugged directly into the buffer object driver's sync object
- * API, if the driver chooses to use ttm_fence_objects as buffer object
- * sync objects. In the prototypes below, a sync_obj is cast to a
- * struct ttm_fence_object, whereas a sync_arg is cast to an
- * uint32_t representing a fence_type argument.
- */
-
-extern bool ttm_fence_sync_obj_signaled(void *sync_obj, void *sync_arg);
-extern int ttm_fence_sync_obj_wait(void *sync_obj, void *sync_arg,
-				   bool lazy, bool interruptible);
-extern int ttm_fence_sync_obj_flush(void *sync_obj, void *sync_arg);
-extern void ttm_fence_sync_obj_unref(void **sync_obj);
-extern void *ttm_fence_sync_obj_ref(void *sync_obj);
-
-#endif
diff -druN linux-2.6.39-libre/drivers/staging/gma500/psb_ttm_fence.c linux-3.0-rc7-libre/drivers/staging/gma500/psb_ttm_fence.c
--- linux-2.6.39-libre/drivers/staging/gma500/psb_ttm_fence.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/gma500/psb_ttm_fence.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,605 +0,0 @@
-/**************************************************************************
- *
- * Copyright (c) 2006-2008 Tungsten Graphics, Inc., Cedar Park, TX., USA
- * All Rights Reserved.
- * Copyright (c) 2009 VMware, Inc., Palo Alto, CA., USA
- * All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- *
- **************************************************************************/
-/*
- * Authors: Thomas Hellstrom <thomas-at-tungstengraphics-dot-com>
- */
-
-#include "psb_ttm_fence_api.h"
-#include "psb_ttm_fence_driver.h"
-#include <linux/wait.h>
-#include <linux/sched.h>
-
-#include <drm/drmP.h>
-
-/*
- * Simple implementation for now.
- */
-
-static void ttm_fence_lockup(struct ttm_fence_object *fence, uint32_t mask)
-{
-	struct ttm_fence_class_manager *fc = ttm_fence_fc(fence);
-
-	printk(KERN_ERR "GPU lockup dectected on engine %u "
-	       "fence type 0x%08x\n",
-	       (unsigned int)fence->fence_class, (unsigned int)mask);
-	/*
-	 * Give engines some time to idle?
-	 */
-
-	write_lock(&fc->lock);
-	ttm_fence_handler(fence->fdev, fence->fence_class,
-			  fence->sequence, mask, -EBUSY);
-	write_unlock(&fc->lock);
-}
-
-/*
- * Convenience function to be called by fence::wait methods that
- * need polling.
- */
-
-int ttm_fence_wait_polling(struct ttm_fence_object *fence, bool lazy,
-			   bool interruptible, uint32_t mask)
-{
-	struct ttm_fence_class_manager *fc = ttm_fence_fc(fence);
-	const struct ttm_fence_driver *driver = ttm_fence_driver(fence);
-	uint32_t count = 0;
-	int ret;
-	unsigned long end_jiffies = fence->timeout_jiffies;
-
-	DECLARE_WAITQUEUE(entry, current);
-	add_wait_queue(&fc->fence_queue, &entry);
-
-	ret = 0;
-
-	for (;;) {
-		__set_current_state((interruptible) ?
-				    TASK_INTERRUPTIBLE : TASK_UNINTERRUPTIBLE);
-		if (ttm_fence_object_signaled(fence, mask))
-			break;
-		if (time_after_eq(jiffies, end_jiffies)) {
-			if (driver->lockup)
-				driver->lockup(fence, mask);
-			else
-				ttm_fence_lockup(fence, mask);
-			continue;
-		}
-		if (lazy)
-			schedule_timeout(1);
-		else if ((++count & 0x0F) == 0) {
-			__set_current_state(TASK_RUNNING);
-			schedule();
-			__set_current_state((interruptible) ?
-					    TASK_INTERRUPTIBLE :
-					    TASK_UNINTERRUPTIBLE);
-		}
-		if (interruptible && signal_pending(current)) {
-			ret = -ERESTART;
-			break;
-		}
-	}
-	__set_current_state(TASK_RUNNING);
-	remove_wait_queue(&fc->fence_queue, &entry);
-	return ret;
-}
-
-/*
- * Typically called by the IRQ handler.
- */
-
-void ttm_fence_handler(struct ttm_fence_device *fdev, uint32_t fence_class,
-		       uint32_t sequence, uint32_t type, uint32_t error)
-{
-	int wake = 0;
-	uint32_t diff;
-	uint32_t relevant_type;
-	uint32_t new_type;
-	struct ttm_fence_class_manager *fc = &fdev->fence_class[fence_class];
-	const struct ttm_fence_driver *driver = ttm_fence_driver_from_dev(fdev);
-	struct list_head *head;
-	struct ttm_fence_object *fence, *next;
-	bool found = false;
-
-	if (list_empty(&fc->ring))
-		return;
-
-	list_for_each_entry(fence, &fc->ring, ring) {
-		diff = (sequence - fence->sequence) & fc->sequence_mask;
-		if (diff > fc->wrap_diff) {
-			found = true;
-			break;
-		}
-	}
-
-	fc->waiting_types &= ~type;
-	head = (found) ? &fence->ring : &fc->ring;
-
-	list_for_each_entry_safe_reverse(fence, next, head, ring) {
-		if (&fence->ring == &fc->ring)
-			break;
-
-		DRM_DEBUG("Fence 0x%08lx, sequence 0x%08x, type 0x%08x\n",
-			  (unsigned long)fence, fence->sequence,
-			  fence->fence_type);
-
-		if (error) {
-			fence->info.error = error;
-			fence->info.signaled_types = fence->fence_type;
-			list_del_init(&fence->ring);
-			wake = 1;
-			break;
-		}
-
-		relevant_type = type & fence->fence_type;
-		new_type = (fence->info.signaled_types | relevant_type) ^
-		    fence->info.signaled_types;
-
-		if (new_type) {
-			fence->info.signaled_types |= new_type;
-			DRM_DEBUG("Fence 0x%08lx signaled 0x%08x\n",
-				  (unsigned long)fence,
-				  fence->info.signaled_types);
-
-			if (unlikely(driver->signaled))
-				driver->signaled(fence);
-
-			if (driver->needed_flush)
-				fc->pending_flush |=
-				    driver->needed_flush(fence);
-
-			if (new_type & fence->waiting_types)
-				wake = 1;
-		}
-
-		fc->waiting_types |=
-		    fence->waiting_types & ~fence->info.signaled_types;
-
-		if (!(fence->fence_type & ~fence->info.signaled_types)) {
-			DRM_DEBUG("Fence completely signaled 0x%08lx\n",
-				  (unsigned long)fence);
-			list_del_init(&fence->ring);
-		}
-	}
-
-	/*
-	 * Reinstate lost waiting types.
-	 */
-
-	if ((fc->waiting_types & type) != type) {
-		head = head->prev;
-		list_for_each_entry(fence, head, ring) {
-			if (&fence->ring == &fc->ring)
-				break;
-			diff =
-			    (fc->highest_waiting_sequence -
-			     fence->sequence) & fc->sequence_mask;
-			if (diff > fc->wrap_diff)
-				break;
-
-			fc->waiting_types |=
-			    fence->waiting_types & ~fence->info.signaled_types;
-		}
-	}
-
-	if (wake)
-		wake_up_all(&fc->fence_queue);
-}
-
-static void ttm_fence_unring(struct ttm_fence_object *fence)
-{
-	struct ttm_fence_class_manager *fc = ttm_fence_fc(fence);
-	unsigned long irq_flags;
-
-	write_lock_irqsave(&fc->lock, irq_flags);
-	list_del_init(&fence->ring);
-	write_unlock_irqrestore(&fc->lock, irq_flags);
-}
-
-bool ttm_fence_object_signaled(struct ttm_fence_object *fence, uint32_t mask)
-{
-	unsigned long flags;
-	bool signaled;
-	const struct ttm_fence_driver *driver = ttm_fence_driver(fence);
-	struct ttm_fence_class_manager *fc = ttm_fence_fc(fence);
-
-	mask &= fence->fence_type;
-	read_lock_irqsave(&fc->lock, flags);
-	signaled = (mask & fence->info.signaled_types) == mask;
-	read_unlock_irqrestore(&fc->lock, flags);
-	if (!signaled && driver->poll) {
-		write_lock_irqsave(&fc->lock, flags);
-		driver->poll(fence->fdev, fence->fence_class, mask);
-		signaled = (mask & fence->info.signaled_types) == mask;
-		write_unlock_irqrestore(&fc->lock, flags);
-	}
-	return signaled;
-}
-
-int ttm_fence_object_flush(struct ttm_fence_object *fence, uint32_t type)
-{
-	const struct ttm_fence_driver *driver = ttm_fence_driver(fence);
-	struct ttm_fence_class_manager *fc = ttm_fence_fc(fence);
-	unsigned long irq_flags;
-	uint32_t saved_pending_flush;
-	uint32_t diff;
-	bool call_flush;
-
-	if (type & ~fence->fence_type) {
-		DRM_ERROR("Flush trying to extend fence type, "
-			  "0x%x, 0x%x\n", type, fence->fence_type);
-		return -EINVAL;
-	}
-
-	write_lock_irqsave(&fc->lock, irq_flags);
-	fence->waiting_types |= type;
-	fc->waiting_types |= fence->waiting_types;
-	diff = (fence->sequence - fc->highest_waiting_sequence) &
-	    fc->sequence_mask;
-
-	if (diff < fc->wrap_diff)
-		fc->highest_waiting_sequence = fence->sequence;
-
-	/*
-	 * fence->waiting_types has changed. Determine whether
-	 * we need to initiate some kind of flush as a result of this.
-	 */
-
-	saved_pending_flush = fc->pending_flush;
-	if (driver->needed_flush)
-		fc->pending_flush |= driver->needed_flush(fence);
-
-	if (driver->poll)
-		driver->poll(fence->fdev, fence->fence_class,
-			     fence->waiting_types);
-
-	call_flush = (fc->pending_flush != 0);
-	write_unlock_irqrestore(&fc->lock, irq_flags);
-
-	if (call_flush && driver->flush)
-		driver->flush(fence->fdev, fence->fence_class);
-
-	return 0;
-}
-
-/*
- * Make sure old fence objects are signaled before their fence sequences are
- * wrapped around and reused.
- */
-
-void ttm_fence_flush_old(struct ttm_fence_device *fdev,
-			 uint32_t fence_class, uint32_t sequence)
-{
-	struct ttm_fence_class_manager *fc = &fdev->fence_class[fence_class];
-	struct ttm_fence_object *fence;
-	unsigned long irq_flags;
-	const struct ttm_fence_driver *driver = fdev->driver;
-	bool call_flush;
-
-	uint32_t diff;
-
-	write_lock_irqsave(&fc->lock, irq_flags);
-
-	list_for_each_entry_reverse(fence, &fc->ring, ring) {
-		diff = (sequence - fence->sequence) & fc->sequence_mask;
-		if (diff <= fc->flush_diff)
-			break;
-
-		fence->waiting_types = fence->fence_type;
-		fc->waiting_types |= fence->fence_type;
-
-		if (driver->needed_flush)
-			fc->pending_flush |= driver->needed_flush(fence);
-	}
-
-	if (driver->poll)
-		driver->poll(fdev, fence_class, fc->waiting_types);
-
-	call_flush = (fc->pending_flush != 0);
-	write_unlock_irqrestore(&fc->lock, irq_flags);
-
-	if (call_flush && driver->flush)
-		driver->flush(fdev, fence->fence_class);
-
-	/*
-	 * FIXME: Shold we implement a wait here for really old fences?
-	 */
-
-}
-
-int ttm_fence_object_wait(struct ttm_fence_object *fence,
-			  bool lazy, bool interruptible, uint32_t mask)
-{
-	const struct ttm_fence_driver *driver = ttm_fence_driver(fence);
-	struct ttm_fence_class_manager *fc = ttm_fence_fc(fence);
-	int ret = 0;
-	unsigned long timeout;
-	unsigned long cur_jiffies;
-	unsigned long to_jiffies;
-
-	if (mask & ~fence->fence_type) {
-		DRM_ERROR("Wait trying to extend fence type"
-			  " 0x%08x 0x%08x\n", mask, fence->fence_type);
-		BUG();
-		return -EINVAL;
-	}
-
-	if (driver->wait)
-		return driver->wait(fence, lazy, interruptible, mask);
-
-	ttm_fence_object_flush(fence, mask);
-retry:
-	if (!driver->has_irq ||
-	    driver->has_irq(fence->fdev, fence->fence_class, mask)) {
-
-		cur_jiffies = jiffies;
-		to_jiffies = fence->timeout_jiffies;
-
-		timeout = (time_after(to_jiffies, cur_jiffies)) ?
-		    to_jiffies - cur_jiffies : 1;
-
-		if (interruptible)
-			ret = wait_event_interruptible_timeout
-			    (fc->fence_queue,
-			     ttm_fence_object_signaled(fence, mask), timeout);
-		else
-			ret = wait_event_timeout
-			    (fc->fence_queue,
-			     ttm_fence_object_signaled(fence, mask), timeout);
-
-		if (unlikely(ret == -ERESTARTSYS))
-			return -ERESTART;
-
-		if (unlikely(ret == 0)) {
-			if (driver->lockup)
-				driver->lockup(fence, mask);
-			else
-				ttm_fence_lockup(fence, mask);
-			goto retry;
-		}
-
-		return 0;
-	}
-
-	return ttm_fence_wait_polling(fence, lazy, interruptible, mask);
-}
-
-int ttm_fence_object_emit(struct ttm_fence_object *fence, uint32_t fence_flags,
-			  uint32_t fence_class, uint32_t type)
-{
-	const struct ttm_fence_driver *driver = ttm_fence_driver(fence);
-	struct ttm_fence_class_manager *fc = ttm_fence_fc(fence);
-	unsigned long flags;
-	uint32_t sequence;
-	unsigned long timeout;
-	int ret;
-
-	ttm_fence_unring(fence);
-	ret = driver->emit(fence->fdev,
-			   fence_class, fence_flags, &sequence, &timeout);
-	if (ret)
-		return ret;
-
-	write_lock_irqsave(&fc->lock, flags);
-	fence->fence_class = fence_class;
-	fence->fence_type = type;
-	fence->waiting_types = 0;
-	fence->info.signaled_types = 0;
-	fence->info.error = 0;
-	fence->sequence = sequence;
-	fence->timeout_jiffies = timeout;
-	if (list_empty(&fc->ring))
-		fc->highest_waiting_sequence = sequence - 1;
-	list_add_tail(&fence->ring, &fc->ring);
-	fc->latest_queued_sequence = sequence;
-	write_unlock_irqrestore(&fc->lock, flags);
-	return 0;
-}
-
-int ttm_fence_object_init(struct ttm_fence_device *fdev,
-			  uint32_t fence_class,
-			  uint32_t type,
-			  uint32_t create_flags,
-			  void (*destroy) (struct ttm_fence_object *),
-			  struct ttm_fence_object *fence)
-{
-	int ret = 0;
-
-	kref_init(&fence->kref);
-	fence->fence_class = fence_class;
-	fence->fence_type = type;
-	fence->info.signaled_types = 0;
-	fence->waiting_types = 0;
-	fence->sequence = 0;
-	fence->info.error = 0;
-	fence->fdev = fdev;
-	fence->destroy = destroy;
-	INIT_LIST_HEAD(&fence->ring);
-	atomic_inc(&fdev->count);
-
-	if (create_flags & TTM_FENCE_FLAG_EMIT) {
-		ret = ttm_fence_object_emit(fence, create_flags,
-					    fence->fence_class, type);
-	}
-
-	return ret;
-}
-
-int ttm_fence_object_create(struct ttm_fence_device *fdev,
-			    uint32_t fence_class,
-			    uint32_t type,
-			    uint32_t create_flags,
-			    struct ttm_fence_object **c_fence)
-{
-	struct ttm_fence_object *fence;
-	int ret;
-
-	ret = ttm_mem_global_alloc(fdev->mem_glob,
-				   sizeof(*fence),
-				   false,
-				   false);
-	if (unlikely(ret != 0)) {
-		printk(KERN_ERR "Out of memory creating fence object\n");
-		return ret;
-	}
-
-	fence = kmalloc(sizeof(*fence), GFP_KERNEL);
-	if (!fence) {
-		printk(KERN_ERR "Out of memory creating fence object\n");
-		ttm_mem_global_free(fdev->mem_glob, sizeof(*fence));
-		return -ENOMEM;
-	}
-
-	ret = ttm_fence_object_init(fdev, fence_class, type,
-				    create_flags, NULL, fence);
-	if (ret) {
-		ttm_fence_object_unref(&fence);
-		return ret;
-	}
-	*c_fence = fence;
-
-	return 0;
-}
-
-static void ttm_fence_object_destroy(struct kref *kref)
-{
-	struct ttm_fence_object *fence =
-	    container_of(kref, struct ttm_fence_object, kref);
-	struct ttm_fence_class_manager *fc = ttm_fence_fc(fence);
-	unsigned long irq_flags;
-
-	write_lock_irqsave(&fc->lock, irq_flags);
-	list_del_init(&fence->ring);
-	write_unlock_irqrestore(&fc->lock, irq_flags);
-
-	atomic_dec(&fence->fdev->count);
-	if (fence->destroy)
-		fence->destroy(fence);
-	else {
-		ttm_mem_global_free(fence->fdev->mem_glob,
-				    sizeof(*fence));
-		kfree(fence);
-	}
-}
-
-void ttm_fence_device_release(struct ttm_fence_device *fdev)
-{
-	kfree(fdev->fence_class);
-}
-
-int
-ttm_fence_device_init(int num_classes,
-		      struct ttm_mem_global *mem_glob,
-		      struct ttm_fence_device *fdev,
-		      const struct ttm_fence_class_init *init,
-		      bool replicate_init,
-		      const struct ttm_fence_driver *driver)
-{
-	struct ttm_fence_class_manager *fc;
-	const struct ttm_fence_class_init *fci;
-	int i;
-
-	fdev->mem_glob = mem_glob;
-	fdev->fence_class = kzalloc(num_classes *
-				    sizeof(*fdev->fence_class), GFP_KERNEL);
-
-	if (unlikely(!fdev->fence_class))
-		return -ENOMEM;
-
-	fdev->num_classes = num_classes;
-	atomic_set(&fdev->count, 0);
-	fdev->driver = driver;
-
-	for (i = 0; i < fdev->num_classes; ++i) {
-		fc = &fdev->fence_class[i];
-		fci = &init[(replicate_init) ? 0 : i];
-
-		fc->wrap_diff = fci->wrap_diff;
-		fc->flush_diff = fci->flush_diff;
-		fc->sequence_mask = fci->sequence_mask;
-
-		rwlock_init(&fc->lock);
-		INIT_LIST_HEAD(&fc->ring);
-		init_waitqueue_head(&fc->fence_queue);
-	}
-
-	return 0;
-}
-
-struct ttm_fence_info ttm_fence_get_info(struct ttm_fence_object *fence)
-{
-	struct ttm_fence_class_manager *fc = ttm_fence_fc(fence);
-	struct ttm_fence_info tmp;
-	unsigned long irq_flags;
-
-	read_lock_irqsave(&fc->lock, irq_flags);
-	tmp = fence->info;
-	read_unlock_irqrestore(&fc->lock, irq_flags);
-
-	return tmp;
-}
-
-void ttm_fence_object_unref(struct ttm_fence_object **p_fence)
-{
-	struct ttm_fence_object *fence = *p_fence;
-
-	*p_fence = NULL;
-	(void)kref_put(&fence->kref, &ttm_fence_object_destroy);
-}
-
-/*
- * Placement / BO sync object glue.
- */
-
-bool ttm_fence_sync_obj_signaled(void *sync_obj, void *sync_arg)
-{
-	struct ttm_fence_object *fence = (struct ttm_fence_object *)sync_obj;
-	uint32_t fence_types = (uint32_t) (unsigned long)sync_arg;
-
-	return ttm_fence_object_signaled(fence, fence_types);
-}
-
-int ttm_fence_sync_obj_wait(void *sync_obj, void *sync_arg,
-			    bool lazy, bool interruptible)
-{
-	struct ttm_fence_object *fence = (struct ttm_fence_object *)sync_obj;
-	uint32_t fence_types = (uint32_t) (unsigned long)sync_arg;
-
-	return ttm_fence_object_wait(fence, lazy, interruptible, fence_types);
-}
-
-int ttm_fence_sync_obj_flush(void *sync_obj, void *sync_arg)
-{
-	struct ttm_fence_object *fence = (struct ttm_fence_object *)sync_obj;
-	uint32_t fence_types = (uint32_t) (unsigned long)sync_arg;
-
-	return ttm_fence_object_flush(fence, fence_types);
-}
-
-void ttm_fence_sync_obj_unref(void **sync_obj)
-{
-	ttm_fence_object_unref((struct ttm_fence_object **)sync_obj);
-}
-
-void *ttm_fence_sync_obj_ref(void *sync_obj)
-{
-	return (void *)
-	    ttm_fence_object_ref((struct ttm_fence_object *)sync_obj);
-}
diff -druN linux-2.6.39-libre/drivers/staging/gma500/psb_ttm_fence_driver.h linux-3.0-rc7-libre/drivers/staging/gma500/psb_ttm_fence_driver.h
--- linux-2.6.39-libre/drivers/staging/gma500/psb_ttm_fence_driver.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/gma500/psb_ttm_fence_driver.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,302 +0,0 @@
-/**************************************************************************
- *
- * Copyright (c) 2006-2008 Tungsten Graphics, Inc., Cedar Park, TX., USA
- * All Rights Reserved.
- * Copyright (c) 2009 VMware, Inc., Palo Alto, CA., USA
- * All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- *
- **************************************************************************/
-/*
- * Authors: Thomas Hellstrom <thomas-at-tungstengraphics-dot-com>
- */
-#ifndef _TTM_FENCE_DRIVER_H_
-#define _TTM_FENCE_DRIVER_H_
-
-#include <linux/kref.h>
-#include <linux/spinlock.h>
-#include <linux/wait.h>
-#include "psb_ttm_fence_api.h"
-#include "ttm/ttm_memory.h"
-
-/** @file ttm_fence_driver.h
- *
- * Definitions needed for a driver implementing the
- * ttm_fence subsystem.
- */
-
-/**
- * struct ttm_fence_class_manager:
- *
- * @wrap_diff: Sequence difference to catch 32-bit wrapping.
- * if (seqa - seqb) > @wrap_diff, then seqa < seqb.
- * @flush_diff: Sequence difference to trigger fence flush.
- * if (cur_seq - seqa) > @flush_diff, then consider fence object with
- * seqa as old an needing a flush.
- * @sequence_mask: Mask of valid bits in a fence sequence.
- * @lock: Lock protecting this struct as well as fence objects
- * associated with this struct.
- * @ring: Circular sequence-ordered list of fence objects.
- * @pending_flush: Fence types currently needing a flush.
- * @waiting_types: Fence types that are currently waited for.
- * @fence_queue: Queue of waiters on fences belonging to this fence class.
- * @highest_waiting_sequence: Sequence number of the fence with highest
- * sequence number and that is waited for.
- * @latest_queued_sequence: Sequence number of the fence latest queued
- * on the ring.
- */
-
-struct ttm_fence_class_manager {
-
-	/*
-	 * Unprotected constant members.
-	 */
-
-	uint32_t wrap_diff;
-	uint32_t flush_diff;
-	uint32_t sequence_mask;
-
-	/*
-	 * The rwlock protects this structure as well as
-	 * the data in all fence objects belonging to this
-	 * class. This should be OK as most fence objects are
-	 * only read from once they're created.
-	 */
-
-	rwlock_t lock;
-	struct list_head ring;
-	uint32_t pending_flush;
-	uint32_t waiting_types;
-	wait_queue_head_t fence_queue;
-	uint32_t highest_waiting_sequence;
-	uint32_t latest_queued_sequence;
-};
-
-/**
- * struct ttm_fence_device
- *
- * @fence_class:  Array of fence class managers.
- * @num_classes:  Array dimension of @fence_class.
- * @count:        Current number of fence objects for statistics.
- * @driver:       Driver struct.
- *
- * Provided in the driver interface so that the driver can derive
- * from this struct for its driver_private, and accordingly
- * access the driver_private from the fence driver callbacks.
- *
- * All members except "count" are initialized at creation and
- * never touched after that. No protection needed.
- *
- * This struct is private to the fence implementation and to the fence
- * driver callbacks, and may otherwise be used by drivers only to
- * obtain the derived device_private object using container_of().
- */
-
-struct ttm_fence_device {
-	struct ttm_mem_global *mem_glob;
-	struct ttm_fence_class_manager *fence_class;
-	uint32_t num_classes;
-	atomic_t count;
-	const struct ttm_fence_driver *driver;
-};
-
-/**
- * struct ttm_fence_class_init
- *
- * @wrap_diff:    Fence sequence number wrap indicator. If
- * (sequence1 - sequence2) > @wrap_diff, then sequence1 is
- * considered to be older than sequence2.
- * @flush_diff:   Fence sequence number flush indicator.
- * If a non-completely-signaled fence has a fence sequence number
- * sequence1 and (sequence1 - current_emit_sequence) > @flush_diff,
- * the fence is considered too old and it will be flushed upon the
- * next call of ttm_fence_flush_old(), to make sure no fences with
- * stale sequence numbers remains unsignaled. @flush_diff should
- * be sufficiently less than @wrap_diff.
- * @sequence_mask: Mask with valid bits of the fence sequence
- * number set to 1.
- *
- * This struct is used as input to ttm_fence_device_init.
- */
-
-struct ttm_fence_class_init {
-	uint32_t wrap_diff;
-	uint32_t flush_diff;
-	uint32_t sequence_mask;
-};
-
-/**
- * struct ttm_fence_driver
- *
- * @has_irq: Called by a potential waiter. Should return 1 if a
- * fence object with indicated parameters is expected to signal
- * automatically, and 0 if the fence implementation needs to
- * repeatedly call @poll to make it signal.
- * @emit:    Make sure a fence with the given parameters is
- * present in the indicated command stream. Return its sequence number
- * in "breadcrumb".
- * @poll:    Check and report sequences of the given "fence_class"
- *           that have signaled "types"
- * @flush:   Make sure that the types indicated by the bitfield
- *           ttm_fence_class_manager::pending_flush will eventually
- *           signal. These bits have been put together using the
- *           result from the needed_flush function described below.
- * @needed_flush: Given the fence_class and fence_types indicated by
- *           "fence", and the last received fence sequence of this
- *           fence class, indicate what types need a fence flush to
- *           signal. Return as a bitfield.
- * @wait:    Set to non-NULL if the driver wants to override the fence
- *           wait implementation. Return 0 on success, -EBUSY on failure,
- *           and -ERESTART if interruptible and a signal is pending.
- * @signaled:  Driver callback that is called whenever a
- *           ttm_fence_object::signaled_types has changed status.
- *           This function is called from atomic context,
- *           with the ttm_fence_class_manager::lock held in write mode.
- * @lockup:  Driver callback that is called whenever a wait has exceeded
- *           the lifetime of a fence object.
- *           If there is a GPU lockup,
- *           this function should, if possible, reset the GPU,
- *           call the ttm_fence_handler with an error status, and
- *           return. If no lockup was detected, simply extend the
- *           fence timeout_jiffies and return. The driver might
- *           want to protect the lockup check with a mutex and cache a
- *           non-locked-up status for a while to avoid an excessive
- *           amount of lockup checks from every waiting thread.
- */
-
-struct ttm_fence_driver {
-	bool (*has_irq) (struct ttm_fence_device *fdev,
-			uint32_t fence_class, uint32_t flags);
-	int (*emit) (struct ttm_fence_device *fdev,
-		     uint32_t fence_class,
-		     uint32_t flags,
-		     uint32_t *breadcrumb, unsigned long *timeout_jiffies);
-	void (*flush) (struct ttm_fence_device *fdev, uint32_t fence_class);
-	void (*poll) (struct ttm_fence_device *fdev,
-		      uint32_t fence_class, uint32_t types);
-	 uint32_t(*needed_flush)
-	 (struct ttm_fence_object *fence);
-	int (*wait) (struct ttm_fence_object *fence, bool lazy,
-		     bool interruptible, uint32_t mask);
-	void (*signaled) (struct ttm_fence_object *fence);
-	void (*lockup) (struct ttm_fence_object *fence, uint32_t fence_types);
-};
-
-/**
- * function ttm_fence_device_init
- *
- * @num_classes:      Number of fence classes for this fence implementation.
- * @mem_global:       Pointer to the global memory accounting info.
- * @fdev:             Pointer to an uninitialised struct ttm_fence_device.
- * @init:             Array of initialization info for each fence class.
- * @replicate_init:   Use the first @init initialization info for all classes.
- * @driver:           Driver callbacks.
- *
- * Initialize a struct ttm_fence_driver structure. Returns -ENOMEM if
- * out-of-memory. Otherwise returns 0.
- */
-extern int
-ttm_fence_device_init(int num_classes,
-		      struct ttm_mem_global *mem_glob,
-		      struct ttm_fence_device *fdev,
-		      const struct ttm_fence_class_init *init,
-		      bool replicate_init,
-		      const struct ttm_fence_driver *driver);
-
-/**
- * function ttm_fence_device_release
- *
- * @fdev:             Pointer to the fence device.
- *
- * Release all resources held by a fence device. Note that before
- * this function is called, the caller must have made sure all fence
- * objects belonging to this fence device are completely signaled.
- */
-
-extern void ttm_fence_device_release(struct ttm_fence_device *fdev);
-
-/**
- * ttm_fence_handler - the fence handler.
- *
- * @fdev:        Pointer to the fence device.
- * @fence_class: Fence class that signals.
- * @sequence:    Signaled sequence.
- * @type:        Types that signal.
- * @error:       Error from the engine.
- *
- * This function signals all fences with a sequence previous to the
- * @sequence argument, and belonging to @fence_class. The signaled fence
- * types are provided in @type. If error is non-zero, the error member
- * of the fence with sequence = @sequence is set to @error. This value
- * may be reported back to user-space, indicating, for example an illegal
- * 3D command or illegal mpeg data.
- *
- * This function is typically called from the driver::poll method when the
- * command sequence preceding the fence marker has executed. It should be
- * called with the ttm_fence_class_manager::lock held in write mode and
- * may be called from interrupt context.
- */
-
-extern void
-ttm_fence_handler(struct ttm_fence_device *fdev,
-		  uint32_t fence_class,
-		  uint32_t sequence, uint32_t type, uint32_t error);
-
-/**
- * ttm_fence_driver_from_dev
- *
- * @fdev:        The ttm fence device.
- *
- * Returns a pointer to the fence driver struct.
- */
-
-static inline const struct ttm_fence_driver *ttm_fence_driver_from_dev(
-						struct ttm_fence_device *fdev)
-{
-	return fdev->driver;
-}
-
-/**
- * ttm_fence_driver
- *
- * @fence:        Pointer to a ttm fence object.
- *
- * Returns a pointer to the fence driver struct.
- */
-
-static inline const struct ttm_fence_driver *ttm_fence_driver(struct
-							      ttm_fence_object
-							      *fence)
-{
-	return ttm_fence_driver_from_dev(fence->fdev);
-}
-
-/**
- * ttm_fence_fc
- *
- * @fence:        Pointer to a ttm fence object.
- *
- * Returns a pointer to the struct ttm_fence_class_manager for the
- * fence class of @fence.
- */
-
-static inline struct ttm_fence_class_manager *ttm_fence_fc(struct
-							   ttm_fence_object
-							   *fence)
-{
-	return &fence->fdev->fence_class[fence->fence_class];
-}
-
-#endif
diff -druN linux-2.6.39-libre/drivers/staging/gma500/psb_ttm_fence_user.c linux-3.0-rc7-libre/drivers/staging/gma500/psb_ttm_fence_user.c
--- linux-2.6.39-libre/drivers/staging/gma500/psb_ttm_fence_user.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/gma500/psb_ttm_fence_user.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,237 +0,0 @@
-/**************************************************************************
- *
- * Copyright (c) 2006-2008 Tungsten Graphics, Inc., Cedar Park, TX., USA
- * All Rights Reserved.
- * Copyright (c) 2009 VMware, Inc., Palo Alto, CA., USA
- * All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- *
- **************************************************************************/
-/*
- * Authors: Thomas Hellstrom <thomas-at-tungstengraphics-dot-com>
- */
-
-#include <drm/drmP.h>
-#include "psb_ttm_fence_user.h"
-#include "ttm/ttm_object.h"
-#include "psb_ttm_fence_driver.h"
-#include "psb_ttm_userobj_api.h"
-
-/**
- * struct ttm_fence_user_object
- *
- * @base:    The base object used for user-space visibility and refcounting.
- *
- * @fence:   The fence object itself.
- *
- */
-
-struct ttm_fence_user_object {
-	struct ttm_base_object base;
-	struct ttm_fence_object fence;
-};
-
-static struct ttm_fence_user_object *ttm_fence_user_object_lookup(
-					struct ttm_object_file *tfile,
-					uint32_t handle)
-{
-	struct ttm_base_object *base;
-
-	base = ttm_base_object_lookup(tfile, handle);
-	if (unlikely(base == NULL)) {
-		printk(KERN_ERR "Invalid fence handle 0x%08lx\n",
-		       (unsigned long)handle);
-		return NULL;
-	}
-
-	if (unlikely(base->object_type != ttm_fence_type)) {
-		ttm_base_object_unref(&base);
-		printk(KERN_ERR "Invalid fence handle 0x%08lx\n",
-		       (unsigned long)handle);
-		return NULL;
-	}
-
-	return container_of(base, struct ttm_fence_user_object, base);
-}
-
-/*
- * The fence object destructor.
- */
-
-static void ttm_fence_user_destroy(struct ttm_fence_object *fence)
-{
-	struct ttm_fence_user_object *ufence =
-	    container_of(fence, struct ttm_fence_user_object, fence);
-
-	ttm_mem_global_free(fence->fdev->mem_glob, sizeof(*ufence));
-	kfree(ufence);
-}
-
-/*
- * The base object destructor. We basically unly unreference the
- * attached fence object.
- */
-
-static void ttm_fence_user_release(struct ttm_base_object **p_base)
-{
-	struct ttm_fence_user_object *ufence;
-	struct ttm_base_object *base = *p_base;
-	struct ttm_fence_object *fence;
-
-	*p_base = NULL;
-
-	if (unlikely(base == NULL))
-		return;
-
-	ufence = container_of(base, struct ttm_fence_user_object, base);
-	fence = &ufence->fence;
-	ttm_fence_object_unref(&fence);
-}
-
-int
-ttm_fence_user_create(struct ttm_fence_device *fdev,
-		      struct ttm_object_file *tfile,
-		      uint32_t fence_class,
-		      uint32_t fence_types,
-		      uint32_t create_flags,
-		      struct ttm_fence_object **fence,
-		      uint32_t *user_handle)
-{
-	int ret;
-	struct ttm_fence_object *tmp;
-	struct ttm_fence_user_object *ufence;
-
-	ret = ttm_mem_global_alloc(fdev->mem_glob,
-				   sizeof(*ufence),
-				   false,
-				   false);
-	if (unlikely(ret != 0))
-		return -ENOMEM;
-
-	ufence = kmalloc(sizeof(*ufence), GFP_KERNEL);
-	if (unlikely(ufence == NULL)) {
-		ttm_mem_global_free(fdev->mem_glob, sizeof(*ufence));
-		return -ENOMEM;
-	}
-
-	ret = ttm_fence_object_init(fdev,
-				    fence_class,
-				    fence_types, create_flags,
-				    &ttm_fence_user_destroy, &ufence->fence);
-
-	if (unlikely(ret != 0))
-		goto out_err0;
-
-	/*
-	 * One fence ref is held by the fence ptr we return.
-	 * The other one by the base object. Need to up the
-	 * fence refcount before we publish this object to
-	 * user-space.
-	 */
-
-	tmp = ttm_fence_object_ref(&ufence->fence);
-	ret = ttm_base_object_init(tfile, &ufence->base,
-				   false, ttm_fence_type,
-				   &ttm_fence_user_release, NULL);
-
-	if (unlikely(ret != 0))
-		goto out_err1;
-
-	*fence = &ufence->fence;
-	*user_handle = ufence->base.hash.key;
-
-	return 0;
-out_err1:
-	ttm_fence_object_unref(&tmp);
-	tmp = &ufence->fence;
-	ttm_fence_object_unref(&tmp);
-	return ret;
-out_err0:
-	ttm_mem_global_free(fdev->mem_glob, sizeof(*ufence));
-	kfree(ufence);
-	return ret;
-}
-
-int ttm_fence_signaled_ioctl(struct ttm_object_file *tfile, void *data)
-{
-	int ret;
-	union ttm_fence_signaled_arg *arg = data;
-	struct ttm_fence_object *fence;
-	struct ttm_fence_info info;
-	struct ttm_fence_user_object *ufence;
-	struct ttm_base_object *base;
-	ret = 0;
-
-	ufence = ttm_fence_user_object_lookup(tfile, arg->req.handle);
-	if (unlikely(ufence == NULL))
-		return -EINVAL;
-
-	fence = &ufence->fence;
-
-	if (arg->req.flush) {
-		ret = ttm_fence_object_flush(fence, arg->req.fence_type);
-		if (unlikely(ret != 0))
-			goto out;
-	}
-
-	info = ttm_fence_get_info(fence);
-	arg->rep.signaled_types = info.signaled_types;
-	arg->rep.fence_error = info.error;
-
-out:
-	base = &ufence->base;
-	ttm_base_object_unref(&base);
-	return ret;
-}
-
-int ttm_fence_finish_ioctl(struct ttm_object_file *tfile, void *data)
-{
-	int ret;
-	union ttm_fence_finish_arg *arg = data;
-	struct ttm_fence_user_object *ufence;
-	struct ttm_base_object *base;
-	struct ttm_fence_object *fence;
-	ret = 0;
-
-	ufence = ttm_fence_user_object_lookup(tfile, arg->req.handle);
-	if (unlikely(ufence == NULL))
-		return -EINVAL;
-
-	fence = &ufence->fence;
-
-	ret = ttm_fence_object_wait(fence,
-				    arg->req.mode & TTM_FENCE_FINISH_MODE_LAZY,
-				    true, arg->req.fence_type);
-	if (likely(ret == 0)) {
-		struct ttm_fence_info info = ttm_fence_get_info(fence);
-
-		arg->rep.signaled_types = info.signaled_types;
-		arg->rep.fence_error = info.error;
-	}
-
-	base = &ufence->base;
-	ttm_base_object_unref(&base);
-
-	return ret;
-}
-
-int ttm_fence_unref_ioctl(struct ttm_object_file *tfile, void *data)
-{
-	struct ttm_fence_unref_arg *arg = data;
-	int ret = 0;
-
-	ret = ttm_ref_object_base_unref(tfile, arg->handle, ttm_fence_type);
-	return ret;
-}
diff -druN linux-2.6.39-libre/drivers/staging/gma500/psb_ttm_fence_user.h linux-3.0-rc7-libre/drivers/staging/gma500/psb_ttm_fence_user.h
--- linux-2.6.39-libre/drivers/staging/gma500/psb_ttm_fence_user.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/gma500/psb_ttm_fence_user.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,140 +0,0 @@
-/**************************************************************************
- *
- * Copyright 2006-2008 Tungsten Graphics, Inc., Cedar Park, TX., USA
- * All Rights Reserved.
- * Copyright (c) 2009 VMware, Inc., Palo Alto, CA., USA
- * All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- *
- **************************************************************************/
-/*
- * Authors
- * Thomas Hellström <thomas-at-tungstengraphics-dot-com>
- */
-
-#ifndef TTM_FENCE_USER_H
-#define TTM_FENCE_USER_H
-
-#if !defined(__KERNEL__) && !defined(_KERNEL)
-#include <stdint.h>
-#endif
-
-#define TTM_FENCE_MAJOR 0
-#define TTM_FENCE_MINOR 1
-#define TTM_FENCE_PL    0
-#define TTM_FENCE_DATE  "080819"
-
-/**
- * struct ttm_fence_signaled_req
- *
- * @handle: Handle to the fence object. Input.
- *
- * @fence_type: Fence types we want to flush. Input.
- *
- * @flush: Boolean. Flush the indicated fence_types. Input.
- *
- * Argument to the TTM_FENCE_SIGNALED ioctl.
- */
-
-struct ttm_fence_signaled_req {
-	uint32_t handle;
-	uint32_t fence_type;
-	int32_t flush;
-	uint32_t pad64;
-};
-
-/**
- * struct ttm_fence_rep
- *
- * @signaled_types: Fence type that has signaled.
- *
- * @fence_error: Command execution error.
- * Hardware errors that are consequences of the execution
- * of the command stream preceding the fence are reported
- * here.
- *
- * Output argument to the TTM_FENCE_SIGNALED and
- * TTM_FENCE_FINISH ioctls.
- */
-
-struct ttm_fence_rep {
-	uint32_t signaled_types;
-	uint32_t fence_error;
-};
-
-union ttm_fence_signaled_arg {
-	struct ttm_fence_signaled_req req;
-	struct ttm_fence_rep rep;
-};
-
-/*
- * Waiting mode flags for the TTM_FENCE_FINISH ioctl.
- *
- * TTM_FENCE_FINISH_MODE_LAZY: Allow for sleeps during polling
- * wait.
- *
- * TTM_FENCE_FINISH_MODE_NO_BLOCK: Don't block waiting for GPU,
- * but return -EBUSY if the buffer is busy.
- */
-
-#define TTM_FENCE_FINISH_MODE_LAZY     (1 << 0)
-#define TTM_FENCE_FINISH_MODE_NO_BLOCK (1 << 1)
-
-/**
- * struct ttm_fence_finish_req
- *
- * @handle: Handle to the fence object. Input.
- *
- * @fence_type: Fence types we want to finish.
- *
- * @mode: Wait mode.
- *
- * Input to the TTM_FENCE_FINISH ioctl.
- */
-
-struct ttm_fence_finish_req {
-	uint32_t handle;
-	uint32_t fence_type;
-	uint32_t mode;
-	uint32_t pad64;
-};
-
-union ttm_fence_finish_arg {
-	struct ttm_fence_finish_req req;
-	struct ttm_fence_rep rep;
-};
-
-/**
- * struct ttm_fence_unref_arg
- *
- * @handle: Handle to the fence object.
- *
- * Argument to the TTM_FENCE_UNREF ioctl.
- */
-
-struct ttm_fence_unref_arg {
-	uint32_t handle;
-	uint32_t pad64;
-};
-
-/*
- * Ioctl offsets from extenstion start.
- */
-
-#define TTM_FENCE_SIGNALED 0x01
-#define TTM_FENCE_FINISH   0x02
-#define TTM_FENCE_UNREF    0x03
-
-#endif
diff -druN linux-2.6.39-libre/drivers/staging/gma500/psb_ttm_glue.c linux-3.0-rc7-libre/drivers/staging/gma500/psb_ttm_glue.c
--- linux-2.6.39-libre/drivers/staging/gma500/psb_ttm_glue.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/gma500/psb_ttm_glue.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,349 +0,0 @@
-/**************************************************************************
- * Copyright (c) 2008, Intel Corporation.
- * All Rights Reserved.
- * Copyright (c) 2008, Tungsten Graphics Inc.  Cedar Park, TX., USA.
- * All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- *
- **************************************************************************/
-
-
-#include <drm/drmP.h>
-#include "psb_drv.h"
-#include "psb_ttm_userobj_api.h"
-#include <linux/io.h>
-
-
-static struct vm_operations_struct psb_ttm_vm_ops;
-
-/**
- * NOTE: driver_private of drm_file is now a struct psb_file_data struct
- * pPriv in struct psb_file_data contains the original psb_fpriv;
- */
-int psb_open(struct inode *inode, struct file *filp)
-{
-	struct drm_file *file_priv;
-	struct drm_psb_private *dev_priv;
-	struct psb_fpriv *psb_fp;
-	struct psb_file_data *pvr_file_priv;
-	int ret;
-
-	DRM_DEBUG("\n");
-
-	ret = drm_open(inode, filp);
-	if (unlikely(ret))
-		return ret;
-
-	psb_fp = kzalloc(sizeof(*psb_fp), GFP_KERNEL);
-
-	if (unlikely(psb_fp == NULL))
-		goto out_err0;
-
-	file_priv = (struct drm_file *) filp->private_data;
-	dev_priv = psb_priv(file_priv->minor->dev);
-
-	DRM_DEBUG("is_master %d\n", file_priv->is_master ? 1 : 0);
-
-	psb_fp->tfile = ttm_object_file_init(dev_priv->tdev,
-					     PSB_FILE_OBJECT_HASH_ORDER);
-	if (unlikely(psb_fp->tfile == NULL))
-		goto out_err1;
-
-	pvr_file_priv = (struct psb_file_data *)file_priv->driver_priv;
-	if (!pvr_file_priv) {
-		DRM_ERROR("drm file private is NULL\n");
-		goto out_err1;
-	}
-
-	pvr_file_priv->priv = psb_fp;
-	if (unlikely(dev_priv->bdev.dev_mapping == NULL))
-		dev_priv->bdev.dev_mapping = dev_priv->dev->dev_mapping;
-
-	return 0;
-
-out_err1:
-	kfree(psb_fp);
-out_err0:
-	(void) drm_release(inode, filp);
-	return ret;
-}
-
-int psb_release(struct inode *inode, struct file *filp)
-{
-	struct drm_file *file_priv;
-	struct psb_fpriv *psb_fp;
-	struct drm_psb_private *dev_priv;
-	int ret;
-	file_priv = (struct drm_file *) filp->private_data;
-	psb_fp = psb_fpriv(file_priv);
-	dev_priv = psb_priv(file_priv->minor->dev);
-
-	ttm_object_file_release(&psb_fp->tfile);
-	kfree(psb_fp);
-
-	ret = drm_release(inode, filp);
-
-	return ret;
-}
-
-int psb_fence_signaled_ioctl(struct drm_device *dev, void *data,
-			     struct drm_file *file_priv)
-{
-
-	return ttm_fence_signaled_ioctl(psb_fpriv(file_priv)->tfile, data);
-}
-
-int psb_fence_finish_ioctl(struct drm_device *dev, void *data,
-			   struct drm_file *file_priv)
-{
-	return ttm_fence_finish_ioctl(psb_fpriv(file_priv)->tfile, data);
-}
-
-int psb_fence_unref_ioctl(struct drm_device *dev, void *data,
-			  struct drm_file *file_priv)
-{
-	return ttm_fence_unref_ioctl(psb_fpriv(file_priv)->tfile, data);
-}
-
-int psb_pl_waitidle_ioctl(struct drm_device *dev, void *data,
-			  struct drm_file *file_priv)
-{
-	return ttm_pl_waitidle_ioctl(psb_fpriv(file_priv)->tfile, data);
-}
-
-int psb_pl_setstatus_ioctl(struct drm_device *dev, void *data,
-			   struct drm_file *file_priv)
-{
-	return ttm_pl_setstatus_ioctl(psb_fpriv(file_priv)->tfile,
-				      &psb_priv(dev)->ttm_lock, data);
-
-}
-
-int psb_pl_synccpu_ioctl(struct drm_device *dev, void *data,
-			 struct drm_file *file_priv)
-{
-	return ttm_pl_synccpu_ioctl(psb_fpriv(file_priv)->tfile, data);
-}
-
-int psb_pl_unref_ioctl(struct drm_device *dev, void *data,
-		       struct drm_file *file_priv)
-{
-	return ttm_pl_unref_ioctl(psb_fpriv(file_priv)->tfile, data);
-
-}
-
-int psb_pl_reference_ioctl(struct drm_device *dev, void *data,
-			   struct drm_file *file_priv)
-{
-	return  ttm_pl_reference_ioctl(psb_fpriv(file_priv)->tfile, data);
-
-}
-
-int psb_pl_create_ioctl(struct drm_device *dev, void *data,
-			struct drm_file *file_priv)
-{
-	struct drm_psb_private *dev_priv = psb_priv(dev);
-
-	return ttm_pl_create_ioctl(psb_fpriv(file_priv)->tfile,
-				   &dev_priv->bdev, &dev_priv->ttm_lock, data);
-
-}
-
-int psb_pl_ub_create_ioctl(struct drm_device *dev, void *data,
-			struct drm_file *file_priv)
-{
-	struct drm_psb_private *dev_priv = psb_priv(dev);
-
-	return ttm_pl_ub_create_ioctl(psb_fpriv(file_priv)->tfile,
-				   &dev_priv->bdev, &dev_priv->ttm_lock, data);
-
-}
-/**
- * psb_ttm_fault - Wrapper around the ttm fault method.
- *
- * @vma: The struct vm_area_struct as in the vm fault() method.
- * @vmf: The struct vm_fault as in the vm fault() method.
- *
- * Since ttm_fault() will reserve buffers while faulting,
- * we need to take the ttm read lock around it, as this driver
- * relies on the ttm_lock in write mode to exclude all threads from
- * reserving and thus validating buffers in aperture- and memory shortage
- * situations.
- */
-
-static int psb_ttm_fault(struct vm_area_struct *vma,
-			 struct vm_fault *vmf)
-{
-	struct ttm_buffer_object *bo = (struct ttm_buffer_object *)
-		vma->vm_private_data;
-	struct drm_psb_private *dev_priv =
-		container_of(bo->bdev, struct drm_psb_private, bdev);
-	int ret;
-
-	ret = ttm_read_lock(&dev_priv->ttm_lock, true);
-	if (unlikely(ret != 0))
-		return VM_FAULT_NOPAGE;
-
-	ret = dev_priv->ttm_vm_ops->fault(vma, vmf);
-
-	ttm_read_unlock(&dev_priv->ttm_lock);
-	return ret;
-}
-
-/**
- * if vm_pgoff < DRM_PSB_FILE_PAGE_OFFSET call directly to
- * PVRMMap
- */
-int psb_mmap(struct file *filp, struct vm_area_struct *vma)
-{
-	struct drm_file *file_priv;
-	struct drm_psb_private *dev_priv;
-	int ret;
-
-	if (vma->vm_pgoff < DRM_PSB_FILE_PAGE_OFFSET ||
-	    vma->vm_pgoff > 2 * DRM_PSB_FILE_PAGE_OFFSET)
-#if 0		/* FIXMEAC */
-		return PVRMMap(filp, vma);
-#else
-		return -EINVAL;
-#endif
-
-	file_priv = (struct drm_file *) filp->private_data;
-	dev_priv = psb_priv(file_priv->minor->dev);
-
-	ret = ttm_bo_mmap(filp, vma, &dev_priv->bdev);
-	if (unlikely(ret != 0))
-		return ret;
-
-	if (unlikely(dev_priv->ttm_vm_ops == NULL)) {
-		dev_priv->ttm_vm_ops = (struct vm_operations_struct *)
-								vma->vm_ops;
-		psb_ttm_vm_ops = *vma->vm_ops;
-		psb_ttm_vm_ops.fault = &psb_ttm_fault;
-	}
-
-	vma->vm_ops = &psb_ttm_vm_ops;
-
-	return 0;
-}
-/*
-ssize_t psb_ttm_write(struct file *filp, const char __user *buf,
-		      size_t count, loff_t *f_pos)
-{
-	struct drm_file *file_priv = (struct drm_file *)filp->private_data;
-	struct drm_psb_private *dev_priv = psb_priv(file_priv->minor->dev);
-
-	return ttm_bo_io(&dev_priv->bdev, filp, buf, NULL, count, f_pos, 1);
-}
-
-ssize_t psb_ttm_read(struct file *filp, char __user *buf,
-		     size_t count, loff_t *f_pos)
-{
-	struct drm_file *file_priv = (struct drm_file *)filp->private_data;
-	struct drm_psb_private *dev_priv = psb_priv(file_priv->minor->dev);
-
-	return ttm_bo_io(&dev_priv->bdev, filp, NULL, buf, count, f_pos, 1);
-}
-*/
-int psb_verify_access(struct ttm_buffer_object *bo,
-		      struct file *filp)
-{
-	struct drm_file *file_priv = (struct drm_file *)filp->private_data;
-
-	if (capable(CAP_SYS_ADMIN))
-		return 0;
-
-	if (unlikely(!file_priv->authenticated))
-		return -EPERM;
-
-	return ttm_pl_verify_access(bo, psb_fpriv(file_priv)->tfile);
-}
-
-static int psb_ttm_mem_global_init(struct drm_global_reference *ref)
-{
-	return ttm_mem_global_init(ref->object);
-}
-
-static void psb_ttm_mem_global_release(struct drm_global_reference *ref)
-{
-	ttm_mem_global_release(ref->object);
-}
-
-int psb_ttm_global_init(struct drm_psb_private *dev_priv)
-{
-	struct drm_global_reference *global_ref;
-	int ret;
-
-	global_ref = &dev_priv->mem_global_ref;
-	global_ref->global_type = DRM_GLOBAL_TTM_MEM;
-	global_ref->size = sizeof(struct ttm_mem_global);
-	global_ref->init = &psb_ttm_mem_global_init;
-	global_ref->release = &psb_ttm_mem_global_release;
-
-	ret = drm_global_item_ref(global_ref);
-	if (unlikely(ret != 0)) {
-		DRM_ERROR("Failed referencing a global TTM memory object.\n");
-		return ret;
-	}
-
-	dev_priv->bo_global_ref.mem_glob = dev_priv->mem_global_ref.object;
-	global_ref = &dev_priv->bo_global_ref.ref;
-	global_ref->global_type = DRM_GLOBAL_TTM_BO;
-	global_ref->size = sizeof(struct ttm_bo_global);
-	global_ref->init = &ttm_bo_global_init;
-	global_ref->release = &ttm_bo_global_release;
-	ret = drm_global_item_ref(global_ref);
-	if (ret != 0) {
-		DRM_ERROR("Failed setting up TTM BO subsystem.\n");
-		drm_global_item_unref(global_ref);
-		return ret;
-	}
-	return 0;
-}
-
-void psb_ttm_global_release(struct drm_psb_private *dev_priv)
-{
-	drm_global_item_unref(&dev_priv->mem_global_ref);
-}
-
-int psb_getpageaddrs_ioctl(struct drm_device *dev, void *data,
-		struct drm_file *file_priv)
-{
-	struct drm_psb_getpageaddrs_arg *arg = data;
-	struct ttm_buffer_object *bo;
-	struct ttm_tt *ttm;
-	struct page **tt_pages;
-	unsigned long i, num_pages;
-	unsigned long *p = arg->page_addrs;
-	int ret = 0;
-
-	bo = ttm_buffer_object_lookup(psb_fpriv(file_priv)->tfile,
-					arg->handle);
-	if (unlikely(bo == NULL)) {
-		printk(KERN_ERR
-			"Could not find buffer object for getpageaddrs.\n");
-		return -EINVAL;
-	}
-
-	arg->gtt_offset = bo->offset;
-	ttm = bo->ttm;
-	num_pages = ttm->num_pages;
-	tt_pages = ttm->pages;
-
-	for (i = 0; i < num_pages; i++)
-		p[i] = (unsigned long)page_to_phys(tt_pages[i]);
-
-	return ret;
-}
diff -druN linux-2.6.39-libre/drivers/staging/gma500/psb_ttm_placement_user.c linux-3.0-rc7-libre/drivers/staging/gma500/psb_ttm_placement_user.c
--- linux-2.6.39-libre/drivers/staging/gma500/psb_ttm_placement_user.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/gma500/psb_ttm_placement_user.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,628 +0,0 @@
-/**************************************************************************
- *
- * Copyright (c) 2006-2008 Tungsten Graphics, Inc., Cedar Park, TX., USA
- * All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- *
- **************************************************************************/
-/*
- * Authors: Thomas Hellstrom <thomas-at-tungstengraphics-dot-com>
- */
-
-#include "psb_ttm_placement_user.h"
-#include "ttm/ttm_bo_driver.h"
-#include "ttm/ttm_object.h"
-#include "psb_ttm_userobj_api.h"
-#include "ttm/ttm_lock.h"
-#include <linux/slab.h>
-#include <linux/sched.h>
-
-struct ttm_bo_user_object {
-	struct ttm_base_object base;
-	struct ttm_buffer_object bo;
-};
-
-static size_t pl_bo_size;
-
-static uint32_t psb_busy_prios[] = {
-	TTM_PL_TT,
-	TTM_PL_PRIV0, /* CI */
-	TTM_PL_PRIV2, /* RAR */
-	TTM_PL_PRIV1, /* DRM_PSB_MEM_MMU */
-	TTM_PL_SYSTEM
-};
-
-static const struct ttm_placement default_placement = {
-				0, 0, 0, NULL, 5, psb_busy_prios
-};
-
-static size_t ttm_pl_size(struct ttm_bo_device *bdev, unsigned long num_pages)
-{
-	size_t page_array_size =
-	    (num_pages * sizeof(void *) + PAGE_SIZE - 1) & PAGE_MASK;
-
-	if (unlikely(pl_bo_size == 0)) {
-		pl_bo_size = bdev->glob->ttm_bo_extra_size +
-		    ttm_round_pot(sizeof(struct ttm_bo_user_object));
-	}
-
-	return bdev->glob->ttm_bo_size + 2 * page_array_size;
-}
-
-static struct ttm_bo_user_object *ttm_bo_user_lookup(struct ttm_object_file
-						     *tfile, uint32_t handle)
-{
-	struct ttm_base_object *base;
-
-	base = ttm_base_object_lookup(tfile, handle);
-	if (unlikely(base == NULL)) {
-		printk(KERN_ERR "Invalid buffer object handle 0x%08lx.\n",
-		       (unsigned long)handle);
-		return NULL;
-	}
-
-	if (unlikely(base->object_type != ttm_buffer_type)) {
-		ttm_base_object_unref(&base);
-		printk(KERN_ERR "Invalid buffer object handle 0x%08lx.\n",
-		       (unsigned long)handle);
-		return NULL;
-	}
-
-	return container_of(base, struct ttm_bo_user_object, base);
-}
-
-struct ttm_buffer_object *ttm_buffer_object_lookup(struct ttm_object_file
-						   *tfile, uint32_t handle)
-{
-	struct ttm_bo_user_object *user_bo;
-	struct ttm_base_object *base;
-
-	user_bo = ttm_bo_user_lookup(tfile, handle);
-	if (unlikely(user_bo == NULL))
-		return NULL;
-
-	(void)ttm_bo_reference(&user_bo->bo);
-	base = &user_bo->base;
-	ttm_base_object_unref(&base);
-	return &user_bo->bo;
-}
-
-static void ttm_bo_user_destroy(struct ttm_buffer_object *bo)
-{
-	struct ttm_bo_user_object *user_bo =
-	    container_of(bo, struct ttm_bo_user_object, bo);
-
-	ttm_mem_global_free(bo->glob->mem_glob, bo->acc_size);
-	kfree(user_bo);
-}
-
-static void ttm_bo_user_release(struct ttm_base_object **p_base)
-{
-	struct ttm_bo_user_object *user_bo;
-	struct ttm_base_object *base = *p_base;
-	struct ttm_buffer_object *bo;
-
-	*p_base = NULL;
-
-	if (unlikely(base == NULL))
-		return;
-
-	user_bo = container_of(base, struct ttm_bo_user_object, base);
-	bo = &user_bo->bo;
-	ttm_bo_unref(&bo);
-}
-
-static void ttm_bo_user_ref_release(struct ttm_base_object *base,
-				    enum ttm_ref_type ref_type)
-{
-	struct ttm_bo_user_object *user_bo =
-	    container_of(base, struct ttm_bo_user_object, base);
-	struct ttm_buffer_object *bo = &user_bo->bo;
-
-	switch (ref_type) {
-	case TTM_REF_SYNCCPU_WRITE:
-		ttm_bo_synccpu_write_release(bo);
-		break;
-	default:
-		BUG();
-	}
-}
-
-static void ttm_pl_fill_rep(struct ttm_buffer_object *bo,
-			    struct ttm_pl_rep *rep)
-{
-	struct ttm_bo_user_object *user_bo =
-	    container_of(bo, struct ttm_bo_user_object, bo);
-
-	rep->gpu_offset = bo->offset;
-	rep->bo_size = bo->num_pages << PAGE_SHIFT;
-	rep->map_handle = bo->addr_space_offset;
-	rep->placement = bo->mem.placement;
-	rep->handle = user_bo->base.hash.key;
-	rep->sync_object_arg = (uint32_t) (unsigned long)bo->sync_obj_arg;
-}
-
-/* FIXME Copy from upstream TTM */
-static inline size_t ttm_bo_size(struct ttm_bo_global *glob,
-				 unsigned long num_pages)
-{
-	size_t page_array_size = (num_pages * sizeof(void *) + PAGE_SIZE - 1) &
-	    PAGE_MASK;
-
-	return glob->ttm_bo_size + 2 * page_array_size;
-}
-
-/* FIXME Copy from upstream TTM "ttm_bo_create", upstream TTM does not
-   export this, so copy it here */
-static int ttm_bo_create_private(struct ttm_bo_device *bdev,
-			unsigned long size,
-			enum ttm_bo_type type,
-			struct ttm_placement *placement,
-			uint32_t page_alignment,
-			unsigned long buffer_start,
-			bool interruptible,
-			struct file *persistant_swap_storage,
-			struct ttm_buffer_object **p_bo)
-{
-	struct ttm_buffer_object *bo;
-	struct ttm_mem_global *mem_glob = bdev->glob->mem_glob;
-	int ret;
-
-	size_t acc_size =
-	    ttm_bo_size(bdev->glob, (size + PAGE_SIZE - 1) >> PAGE_SHIFT);
-	ret = ttm_mem_global_alloc(mem_glob, acc_size, false, false);
-	if (unlikely(ret != 0))
-		return ret;
-
-	bo = kzalloc(sizeof(*bo), GFP_KERNEL);
-
-	if (unlikely(bo == NULL)) {
-		ttm_mem_global_free(mem_glob, acc_size);
-		return -ENOMEM;
-	}
-
-	ret = ttm_bo_init(bdev, bo, size, type, placement, page_alignment,
-				buffer_start, interruptible,
-				persistant_swap_storage, acc_size, NULL);
-	if (likely(ret == 0))
-		*p_bo = bo;
-
-	return ret;
-}
-
-int psb_ttm_bo_check_placement(struct ttm_buffer_object *bo,
-				struct ttm_placement *placement)
-{
-	int i;
-
-	for (i = 0; i < placement->num_placement; i++) {
-		if (!capable(CAP_SYS_ADMIN)) {
-			if (placement->placement[i] & TTM_PL_FLAG_NO_EVICT) {
-				printk(KERN_ERR TTM_PFX "Need to be root to "
-					"modify NO_EVICT status.\n");
-				return -EINVAL;
-			}
-		}
-	}
-	for (i = 0; i < placement->num_busy_placement; i++) {
-		if (!capable(CAP_SYS_ADMIN)) {
-			if (placement->busy_placement[i]
-						& TTM_PL_FLAG_NO_EVICT) {
-				printk(KERN_ERR TTM_PFX "Need to be root to modify NO_EVICT status.\n");
-				return -EINVAL;
-			}
-		}
-	}
-	return 0;
-}
-
-int ttm_buffer_object_create(struct ttm_bo_device *bdev,
-			unsigned long size,
-			enum ttm_bo_type type,
-			uint32_t flags,
-			uint32_t page_alignment,
-			unsigned long buffer_start,
-			bool interruptible,
-			struct file *persistant_swap_storage,
-			struct ttm_buffer_object **p_bo)
-{
-	struct ttm_placement placement = default_placement;
-	int ret;
-
-	if ((flags & TTM_PL_MASK_CACHING) == 0)
-		flags |= TTM_PL_FLAG_WC | TTM_PL_FLAG_UNCACHED;
-
-	placement.num_placement = 1;
-	placement.placement = &flags;
-
-	ret = ttm_bo_create_private(bdev,
-			size,
-			type,
-			&placement,
-			page_alignment,
-			buffer_start,
-			interruptible,
-			persistant_swap_storage,
-			p_bo);
-
-	return ret;
-}
-
-
-int ttm_pl_create_ioctl(struct ttm_object_file *tfile,
-			struct ttm_bo_device *bdev,
-			struct ttm_lock *lock, void *data)
-{
-	union ttm_pl_create_arg *arg = data;
-	struct ttm_pl_create_req *req = &arg->req;
-	struct ttm_pl_rep *rep = &arg->rep;
-	struct ttm_buffer_object *bo;
-	struct ttm_buffer_object *tmp;
-	struct ttm_bo_user_object *user_bo;
-	uint32_t flags;
-	int ret = 0;
-	struct ttm_mem_global *mem_glob = bdev->glob->mem_glob;
-	struct ttm_placement placement = default_placement;
-	size_t acc_size =
-	    ttm_pl_size(bdev, (req->size + PAGE_SIZE - 1) >> PAGE_SHIFT);
-	ret = ttm_mem_global_alloc(mem_glob, acc_size, false, false);
-	if (unlikely(ret != 0))
-		return ret;
-
-	flags = req->placement;
-	user_bo = kzalloc(sizeof(*user_bo), GFP_KERNEL);
-	if (unlikely(user_bo == NULL)) {
-		ttm_mem_global_free(mem_glob, acc_size);
-		return -ENOMEM;
-	}
-
-	bo = &user_bo->bo;
-	ret = ttm_read_lock(lock, true);
-	if (unlikely(ret != 0)) {
-		ttm_mem_global_free(mem_glob, acc_size);
-		kfree(user_bo);
-		return ret;
-	}
-
-	placement.num_placement = 1;
-	placement.placement = &flags;
-
-	if ((flags & TTM_PL_MASK_CACHING) == 0)
-		flags |=  TTM_PL_FLAG_WC | TTM_PL_FLAG_UNCACHED;
-
-	ret = ttm_bo_init(bdev, bo, req->size,
-				     ttm_bo_type_device, &placement,
-				     req->page_alignment, 0, true,
-				     NULL, acc_size, &ttm_bo_user_destroy);
-	ttm_read_unlock(lock);
-
-	/*
-	 * Note that the ttm_buffer_object_init function
-	 * would've called the destroy function on failure!!
-	 */
-
-	if (unlikely(ret != 0))
-		goto out;
-
-	tmp = ttm_bo_reference(bo);
-	ret = ttm_base_object_init(tfile, &user_bo->base,
-				   flags & TTM_PL_FLAG_SHARED,
-				   ttm_buffer_type,
-				   &ttm_bo_user_release,
-				   &ttm_bo_user_ref_release);
-	if (unlikely(ret != 0))
-		goto out_err;
-
-	ttm_pl_fill_rep(bo, rep);
-	ttm_bo_unref(&bo);
-out:
-	return 0;
-out_err:
-	ttm_bo_unref(&tmp);
-	ttm_bo_unref(&bo);
-	return ret;
-}
-
-int ttm_pl_ub_create_ioctl(struct ttm_object_file *tfile,
-			   struct ttm_bo_device *bdev,
-			   struct ttm_lock *lock, void *data)
-{
-	union ttm_pl_create_ub_arg *arg = data;
-	struct ttm_pl_create_ub_req *req = &arg->req;
-	struct ttm_pl_rep *rep = &arg->rep;
-	struct ttm_buffer_object *bo;
-	struct ttm_buffer_object *tmp;
-	struct ttm_bo_user_object *user_bo;
-	uint32_t flags;
-	int ret = 0;
-	struct ttm_mem_global *mem_glob = bdev->glob->mem_glob;
-	struct ttm_placement placement = default_placement;
-	size_t acc_size =
-	    ttm_pl_size(bdev, (req->size + PAGE_SIZE - 1) >> PAGE_SHIFT);
-	ret = ttm_mem_global_alloc(mem_glob, acc_size, false, false);
-	if (unlikely(ret != 0))
-		return ret;
-
-	flags = req->placement;
-	user_bo = kzalloc(sizeof(*user_bo), GFP_KERNEL);
-	if (unlikely(user_bo == NULL)) {
-		ttm_mem_global_free(mem_glob, acc_size);
-		return -ENOMEM;
-	}
-	ret = ttm_read_lock(lock, true);
-	if (unlikely(ret != 0)) {
-		ttm_mem_global_free(mem_glob, acc_size);
-		kfree(user_bo);
-		return ret;
-	}
-	bo = &user_bo->bo;
-
-	placement.num_placement = 1;
-	placement.placement = &flags;
-
-	ret = ttm_bo_init(bdev,
-					bo,
-					req->size,
-					ttm_bo_type_user,
-					&placement,
-					req->page_alignment,
-					req->user_address,
-					true,
-					NULL,
-					acc_size,
-					&ttm_bo_user_destroy);
-
-	/*
-	 * Note that the ttm_buffer_object_init function
-	 * would've called the destroy function on failure!!
-	 */
-	ttm_read_unlock(lock);
-	if (unlikely(ret != 0))
-		goto out;
-
-	tmp = ttm_bo_reference(bo);
-	ret = ttm_base_object_init(tfile, &user_bo->base,
-				   flags & TTM_PL_FLAG_SHARED,
-				   ttm_buffer_type,
-				   &ttm_bo_user_release,
-				   &ttm_bo_user_ref_release);
-	if (unlikely(ret != 0))
-		goto out_err;
-
-	ttm_pl_fill_rep(bo, rep);
-	ttm_bo_unref(&bo);
-out:
-	return 0;
-out_err:
-	ttm_bo_unref(&tmp);
-	ttm_bo_unref(&bo);
-	return ret;
-}
-
-int ttm_pl_reference_ioctl(struct ttm_object_file *tfile, void *data)
-{
-	union ttm_pl_reference_arg *arg = data;
-	struct ttm_pl_rep *rep = &arg->rep;
-	struct ttm_bo_user_object *user_bo;
-	struct ttm_buffer_object *bo;
-	struct ttm_base_object *base;
-	int ret;
-
-	user_bo = ttm_bo_user_lookup(tfile, arg->req.handle);
-	if (unlikely(user_bo == NULL)) {
-		printk(KERN_ERR "Could not reference buffer object.\n");
-		return -EINVAL;
-	}
-
-	bo = &user_bo->bo;
-	ret = ttm_ref_object_add(tfile, &user_bo->base, TTM_REF_USAGE, NULL);
-	if (unlikely(ret != 0)) {
-		printk(KERN_ERR
-		       "Could not add a reference to buffer object.\n");
-		goto out;
-	}
-
-	ttm_pl_fill_rep(bo, rep);
-
-out:
-	base = &user_bo->base;
-	ttm_base_object_unref(&base);
-	return ret;
-}
-
-int ttm_pl_unref_ioctl(struct ttm_object_file *tfile, void *data)
-{
-	struct ttm_pl_reference_req *arg = data;
-
-	return ttm_ref_object_base_unref(tfile, arg->handle, TTM_REF_USAGE);
-}
-
-int ttm_pl_synccpu_ioctl(struct ttm_object_file *tfile, void *data)
-{
-	struct ttm_pl_synccpu_arg *arg = data;
-	struct ttm_bo_user_object *user_bo;
-	struct ttm_buffer_object *bo;
-	struct ttm_base_object *base;
-	bool existed;
-	int ret;
-
-	switch (arg->op) {
-	case TTM_PL_SYNCCPU_OP_GRAB:
-		user_bo = ttm_bo_user_lookup(tfile, arg->handle);
-		if (unlikely(user_bo == NULL)) {
-			printk(KERN_ERR
-			       "Could not find buffer object for synccpu.\n");
-			return -EINVAL;
-		}
-		bo = &user_bo->bo;
-		base = &user_bo->base;
-		ret = ttm_bo_synccpu_write_grab(bo,
-						arg->access_mode &
-						TTM_PL_SYNCCPU_MODE_NO_BLOCK);
-		if (unlikely(ret != 0)) {
-			ttm_base_object_unref(&base);
-			goto out;
-		}
-		ret = ttm_ref_object_add(tfile, &user_bo->base,
-					 TTM_REF_SYNCCPU_WRITE, &existed);
-		if (existed || ret != 0)
-			ttm_bo_synccpu_write_release(bo);
-		ttm_base_object_unref(&base);
-		break;
-	case TTM_PL_SYNCCPU_OP_RELEASE:
-		ret = ttm_ref_object_base_unref(tfile, arg->handle,
-						TTM_REF_SYNCCPU_WRITE);
-		break;
-	default:
-		ret = -EINVAL;
-		break;
-	}
-out:
-	return ret;
-}
-
-int ttm_pl_setstatus_ioctl(struct ttm_object_file *tfile,
-			   struct ttm_lock *lock, void *data)
-{
-	union ttm_pl_setstatus_arg *arg = data;
-	struct ttm_pl_setstatus_req *req = &arg->req;
-	struct ttm_pl_rep *rep = &arg->rep;
-	struct ttm_buffer_object *bo;
-	struct ttm_bo_device *bdev;
-	struct ttm_placement placement = default_placement;
-	uint32_t flags[2];
-	int ret;
-
-	bo = ttm_buffer_object_lookup(tfile, req->handle);
-	if (unlikely(bo == NULL)) {
-		printk(KERN_ERR
-		       "Could not find buffer object for setstatus.\n");
-		return -EINVAL;
-	}
-
-	bdev = bo->bdev;
-
-	ret = ttm_read_lock(lock, true);
-	if (unlikely(ret != 0))
-		goto out_err0;
-
-	ret = ttm_bo_reserve(bo, true, false, false, 0);
-	if (unlikely(ret != 0))
-		goto out_err1;
-
-	ret = ttm_bo_wait_cpu(bo, false);
-	if (unlikely(ret != 0))
-		goto out_err2;
-
-	flags[0] = req->set_placement;
-	flags[1] = req->clr_placement;
-
-	placement.num_placement = 2;
-	placement.placement = flags;
-
-	/* Review internal locking ? FIXMEAC */
-	ret = psb_ttm_bo_check_placement(bo, &placement);
-	if (unlikely(ret != 0))
-		goto out_err2;
-
-	placement.num_placement = 1;
-	flags[0] = (req->set_placement | bo->mem.placement)
-						& ~req->clr_placement;
-
-	ret = ttm_bo_validate(bo, &placement, true, false, false);
-	if (unlikely(ret != 0))
-		goto out_err2;
-
-	ttm_pl_fill_rep(bo, rep);
-out_err2:
-	ttm_bo_unreserve(bo);
-out_err1:
-	ttm_read_unlock(lock);
-out_err0:
-	ttm_bo_unref(&bo);
-	return ret;
-}
-
-static int psb_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 -ERESTART;
-		} else {
-			wait_event(bo->event_queue,
-				atomic_read(&bo->reserved) == 0);
-		}
-	}
-	return 0;
-}
-
-static void psb_ttm_bo_unblock_reservation(struct ttm_buffer_object *bo)
-{
-	atomic_set(&bo->reserved, 0);
-	wake_up_all(&bo->event_queue);
-}
-
-int ttm_pl_waitidle_ioctl(struct ttm_object_file *tfile, void *data)
-{
-	struct ttm_pl_waitidle_arg *arg = data;
-	struct ttm_buffer_object *bo;
-	int ret;
-
-	bo = ttm_buffer_object_lookup(tfile, arg->handle);
-	if (unlikely(bo == NULL)) {
-		printk(KERN_ERR "Could not find buffer object for waitidle.\n");
-		return -EINVAL;
-	}
-
-	ret =
-	    psb_ttm_bo_block_reservation(bo, true,
-				     arg->mode & TTM_PL_WAITIDLE_MODE_NO_BLOCK);
-	if (unlikely(ret != 0))
-		goto out;
-	ret = ttm_bo_wait(bo,
-			  arg->mode & TTM_PL_WAITIDLE_MODE_LAZY,
-			  true, arg->mode & TTM_PL_WAITIDLE_MODE_NO_BLOCK);
-	psb_ttm_bo_unblock_reservation(bo);
-out:
-	ttm_bo_unref(&bo);
-	return ret;
-}
-
-int ttm_pl_verify_access(struct ttm_buffer_object *bo,
-			 struct ttm_object_file *tfile)
-{
-	struct ttm_bo_user_object *ubo;
-
-	/*
-	 * Check bo subclass.
-	 */
-
-	if (unlikely(bo->destroy != &ttm_bo_user_destroy))
-		return -EPERM;
-
-	ubo = container_of(bo, struct ttm_bo_user_object, bo);
-	if (likely(ubo->base.shareable || ubo->base.tfile == tfile))
-		return 0;
-
-	return -EPERM;
-}
diff -druN linux-2.6.39-libre/drivers/staging/gma500/psb_ttm_placement_user.h linux-3.0-rc7-libre/drivers/staging/gma500/psb_ttm_placement_user.h
--- linux-2.6.39-libre/drivers/staging/gma500/psb_ttm_placement_user.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/gma500/psb_ttm_placement_user.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,252 +0,0 @@
-/**************************************************************************
- *
- * Copyright 2006-2008 Tungsten Graphics, Inc., Cedar Park, TX., USA
- * All Rights Reserved.
- * Copyright (c) 2009 VMware, Inc., Palo Alto, CA., USA
- * All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- *
- **************************************************************************/
-/*
- * Authors
- * Thomas Hellström <thomas-at-tungstengraphics-dot-com>
- */
-
-#ifndef _TTM_PLACEMENT_USER_H_
-#define _TTM_PLACEMENT_USER_H_
-
-#if !defined(__KERNEL__) && !defined(_KERNEL)
-#include <stdint.h>
-#else
-#include <linux/kernel.h>
-#endif
-
-#include "ttm/ttm_placement.h"
-
-#define TTM_PLACEMENT_MAJOR 0
-#define TTM_PLACEMENT_MINOR 1
-#define TTM_PLACEMENT_PL    0
-#define TTM_PLACEMENT_DATE  "080819"
-
-/**
- * struct ttm_pl_create_req
- *
- * @size: The buffer object size.
- * @placement: Flags that indicate initial acceptable
- *  placement.
- * @page_alignment: Required alignment in pages.
- *
- * Input to the TTM_BO_CREATE ioctl.
- */
-
-struct ttm_pl_create_req {
-	uint64_t size;
-	uint32_t placement;
-	uint32_t page_alignment;
-};
-
-/**
- * struct ttm_pl_create_ub_req
- *
- * @size: The buffer object size.
- * @user_address: User-space address of the memory area that
- * should be used to back the buffer object cast to 64-bit.
- * @placement: Flags that indicate initial acceptable
- *  placement.
- * @page_alignment: Required alignment in pages.
- *
- * Input to the TTM_BO_CREATE_UB ioctl.
- */
-
-struct ttm_pl_create_ub_req {
-	uint64_t size;
-	uint64_t user_address;
-	uint32_t placement;
-	uint32_t page_alignment;
-};
-
-/**
- * struct ttm_pl_rep
- *
- * @gpu_offset: The current offset into the memory region used.
- * This can be used directly by the GPU if there are no
- * additional GPU mapping procedures used by the driver.
- *
- * @bo_size: Actual buffer object size.
- *
- * @map_handle: Offset into the device address space.
- * Used for map, seek, read, write. This will never change
- * during the lifetime of an object.
- *
- * @placement: Flag indicating the placement status of
- * the buffer object using the TTM_PL flags above.
- *
- * @sync_object_arg: Used for user-space synchronization and
- * depends on the synchronization model used. If fences are
- * used, this is the buffer_object::fence_type_mask
- *
- * Output from the TTM_PL_CREATE and TTM_PL_REFERENCE, and
- * TTM_PL_SETSTATUS ioctls.
- */
-
-struct ttm_pl_rep {
-	uint64_t gpu_offset;
-	uint64_t bo_size;
-	uint64_t map_handle;
-	uint32_t placement;
-	uint32_t handle;
-	uint32_t sync_object_arg;
-	uint32_t pad64;
-};
-
-/**
- * struct ttm_pl_setstatus_req
- *
- * @set_placement: Placement flags to set.
- *
- * @clr_placement: Placement flags to clear.
- *
- * @handle: The object handle
- *
- * Input to the TTM_PL_SETSTATUS ioctl.
- */
-
-struct ttm_pl_setstatus_req {
-	uint32_t set_placement;
-	uint32_t clr_placement;
-	uint32_t handle;
-	uint32_t pad64;
-};
-
-/**
- * struct ttm_pl_reference_req
- *
- * @handle: The object to put a reference on.
- *
- * Input to the TTM_PL_REFERENCE and the TTM_PL_UNREFERENCE ioctls.
- */
-
-struct ttm_pl_reference_req {
-	uint32_t handle;
-	uint32_t pad64;
-};
-
-/*
- * ACCESS mode flags for SYNCCPU.
- *
- * TTM_SYNCCPU_MODE_READ will guarantee that the GPU is not
- * writing to the buffer.
- *
- * TTM_SYNCCPU_MODE_WRITE will guarantee that the GPU is not
- * accessing the buffer.
- *
- * TTM_SYNCCPU_MODE_NO_BLOCK makes sure the call does not wait
- * for GPU accesses to finish but return -EBUSY.
- *
- * TTM_SYNCCPU_MODE_TRYCACHED Try to place the buffer in cacheable
- * memory while synchronized for CPU.
- */
-
-#define TTM_PL_SYNCCPU_MODE_READ      TTM_ACCESS_READ
-#define TTM_PL_SYNCCPU_MODE_WRITE     TTM_ACCESS_WRITE
-#define TTM_PL_SYNCCPU_MODE_NO_BLOCK  (1 << 2)
-#define TTM_PL_SYNCCPU_MODE_TRYCACHED (1 << 3)
-
-/**
- * struct ttm_pl_synccpu_arg
- *
- * @handle: The object to synchronize.
- *
- * @access_mode: access mode indicated by the
- * TTM_SYNCCPU_MODE flags.
- *
- * @op: indicates whether to grab or release the
- * buffer for cpu usage.
- *
- * Input to the TTM_PL_SYNCCPU ioctl.
- */
-
-struct ttm_pl_synccpu_arg {
-	uint32_t handle;
-	uint32_t access_mode;
-	enum {
-		TTM_PL_SYNCCPU_OP_GRAB,
-		TTM_PL_SYNCCPU_OP_RELEASE
-	} op;
-	uint32_t pad64;
-};
-
-/*
- * Waiting mode flags for the TTM_BO_WAITIDLE ioctl.
- *
- * TTM_WAITIDLE_MODE_LAZY: Allow for sleeps during polling
- * wait.
- *
- * TTM_WAITIDLE_MODE_NO_BLOCK: Don't block waiting for GPU,
- * but return -EBUSY if the buffer is busy.
- */
-
-#define TTM_PL_WAITIDLE_MODE_LAZY     (1 << 0)
-#define TTM_PL_WAITIDLE_MODE_NO_BLOCK (1 << 1)
-
-/**
- * struct ttm_waitidle_arg
- *
- * @handle: The object to synchronize.
- *
- * @mode: wait mode indicated by the
- * TTM_SYNCCPU_MODE flags.
- *
- * Argument to the TTM_BO_WAITIDLE ioctl.
- */
-
-struct ttm_pl_waitidle_arg {
-	uint32_t handle;
-	uint32_t mode;
-};
-
-union ttm_pl_create_arg {
-	struct ttm_pl_create_req req;
-	struct ttm_pl_rep rep;
-};
-
-union ttm_pl_reference_arg {
-	struct ttm_pl_reference_req req;
-	struct ttm_pl_rep rep;
-};
-
-union ttm_pl_setstatus_arg {
-	struct ttm_pl_setstatus_req req;
-	struct ttm_pl_rep rep;
-};
-
-union ttm_pl_create_ub_arg {
-	struct ttm_pl_create_ub_req req;
-	struct ttm_pl_rep rep;
-};
-
-/*
- * Ioctl offsets.
- */
-
-#define TTM_PL_CREATE      0x00
-#define TTM_PL_REFERENCE   0x01
-#define TTM_PL_UNREF       0x02
-#define TTM_PL_SYNCCPU     0x03
-#define TTM_PL_WAITIDLE    0x04
-#define TTM_PL_SETSTATUS   0x05
-#define TTM_PL_CREATE_UB   0x06
-
-#endif
diff -druN linux-2.6.39-libre/drivers/staging/gma500/psb_ttm_userobj_api.h linux-3.0-rc7-libre/drivers/staging/gma500/psb_ttm_userobj_api.h
--- linux-2.6.39-libre/drivers/staging/gma500/psb_ttm_userobj_api.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/gma500/psb_ttm_userobj_api.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,85 +0,0 @@
-/**************************************************************************
- *
- * Copyright (c) 2006-2008 Tungsten Graphics, Inc., Cedar Park, TX., USA
- * All Rights Reserved.
- * Copyright (c) 2009 VMware, Inc., Palo Alto, CA., USA
- * All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- *
- **************************************************************************/
-/*
- * Authors: Thomas Hellstrom <thomas-at-tungstengraphics-dot-com>
- */
-
-#ifndef _TTM_USEROBJ_API_H_
-#define _TTM_USEROBJ_API_H_
-
-#include "psb_ttm_placement_user.h"
-#include "psb_ttm_fence_user.h"
-#include "ttm/ttm_object.h"
-#include "psb_ttm_fence_api.h"
-#include "ttm/ttm_bo_api.h"
-
-struct ttm_lock;
-
-/*
- * User ioctls.
- */
-
-extern int ttm_pl_create_ioctl(struct ttm_object_file *tfile,
-			       struct ttm_bo_device *bdev,
-			       struct ttm_lock *lock, void *data);
-extern int ttm_pl_ub_create_ioctl(struct ttm_object_file *tfile,
-				  struct ttm_bo_device *bdev,
-				  struct ttm_lock *lock, void *data);
-extern int ttm_pl_reference_ioctl(struct ttm_object_file *tfile, void *data);
-extern int ttm_pl_unref_ioctl(struct ttm_object_file *tfile, void *data);
-extern int ttm_pl_synccpu_ioctl(struct ttm_object_file *tfile, void *data);
-extern int ttm_pl_setstatus_ioctl(struct ttm_object_file *tfile,
-				  struct ttm_lock *lock, void *data);
-extern int ttm_pl_waitidle_ioctl(struct ttm_object_file *tfile, void *data);
-extern int ttm_fence_signaled_ioctl(struct ttm_object_file *tfile, void *data);
-extern int ttm_fence_finish_ioctl(struct ttm_object_file *tfile, void *data);
-extern int ttm_fence_unref_ioctl(struct ttm_object_file *tfile, void *data);
-
-extern int
-ttm_fence_user_create(struct ttm_fence_device *fdev,
-		      struct ttm_object_file *tfile,
-		      uint32_t fence_class,
-		      uint32_t fence_types,
-		      uint32_t create_flags,
-		      struct ttm_fence_object **fence, uint32_t * user_handle);
-
-extern struct ttm_buffer_object *ttm_buffer_object_lookup(struct ttm_object_file
-							  *tfile,
-							  uint32_t handle);
-
-extern int
-ttm_pl_verify_access(struct ttm_buffer_object *bo,
-		     struct ttm_object_file *tfile);
-
-extern int ttm_buffer_object_create(struct ttm_bo_device *bdev,
-			unsigned long size,
-			enum ttm_bo_type type,
-			uint32_t flags,
-			uint32_t page_alignment,
-			unsigned long buffer_start,
-			bool interruptible,
-			struct file *persistant_swap_storage,
-			struct ttm_buffer_object **p_bo);
-
-extern int psb_ttm_bo_check_placement(struct ttm_buffer_object *bo,
-				struct ttm_placement *placement);
-#endif
diff -druN linux-2.6.39-libre/drivers/staging/hv/blkvsc.c linux-3.0-rc7-libre/drivers/staging/hv/blkvsc.c
--- linux-2.6.39-libre/drivers/staging/hv/blkvsc.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/hv/blkvsc.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,102 +0,0 @@
-/*
- *
- * Copyright (c) 2009, Microsoft 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., 59 Temple
- * Place - Suite 330, Boston, MA 02111-1307 USA.
- *
- * Authors:
- *   Haiyang Zhang <haiyangz@microsoft.com>
- *   Hank Janssen  <hjanssen@microsoft.com>
- *
- */
-#include <linux/kernel.h>
-#include <linux/mm.h>
-#include "hv_api.h"
-#include "storvsc.c"
-
-static const char *g_blk_driver_name = "blkvsc";
-
-/* {32412632-86cb-44a2-9b5c-50d1417354f5} */
-static const struct hv_guid g_blk_device_type = {
-	.data = {
-		0x32, 0x26, 0x41, 0x32, 0xcb, 0x86, 0xa2, 0x44,
-		0x9b, 0x5c, 0x50, 0xd1, 0x41, 0x73, 0x54, 0xf5
-	}
-};
-
-static int blk_vsc_on_device_add(struct hv_device *device, void *additional_info)
-{
-	struct storvsc_device_info *device_info;
-	int ret = 0;
-
-	device_info = (struct storvsc_device_info *)additional_info;
-
-	ret = stor_vsc_on_device_add(device, additional_info);
-	if (ret != 0)
-		return ret;
-
-	/*
-	 * We need to use the device instance guid to set the path and target
-	 * id. For IDE devices, the device instance id is formatted as
-	 * <bus id> * - <device id> - 8899 - 000000000000.
-	 */
-	device_info->path_id = device->dev_instance.data[3] << 24 |
-			     device->dev_instance.data[2] << 16 |
-			     device->dev_instance.data[1] << 8  |
-			     device->dev_instance.data[0];
-
-	device_info->target_id = device->dev_instance.data[5] << 8 |
-			       device->dev_instance.data[4];
-
-	return ret;
-}
-
-int blk_vsc_initialize(struct hv_driver *driver)
-{
-	struct storvsc_driver_object *stor_driver;
-	int ret = 0;
-
-	stor_driver = (struct storvsc_driver_object *)driver;
-
-	/* Make sure we are at least 2 pages since 1 page is used for control */
-	/* ASSERT(stor_driver->RingBufferSize >= (PAGE_SIZE << 1)); */
-
-	driver->name = g_blk_driver_name;
-	memcpy(&driver->dev_type, &g_blk_device_type, sizeof(struct hv_guid));
-
-	stor_driver->request_ext_size = sizeof(struct storvsc_request_extension);
-
-	/*
-	 * Divide the ring buffer data size (which is 1 page less than the ring
-	 * buffer size since that page is reserved for the ring buffer indices)
-	 * by the max request size (which is
-	 * vmbus_channel_packet_multipage_buffer + struct vstor_packet + u64)
-	 */
-	stor_driver->max_outstanding_req_per_channel =
-		((stor_driver->ring_buffer_size - PAGE_SIZE) /
-		  ALIGN(MAX_MULTIPAGE_BUFFER_PACKET +
-			   sizeof(struct vstor_packet) + sizeof(u64),
-			   sizeof(u64)));
-
-	DPRINT_INFO(BLKVSC, "max io outstd %u",
-		    stor_driver->max_outstanding_req_per_channel);
-
-	/* Setup the dispatch table */
-	stor_driver->base.dev_add = blk_vsc_on_device_add;
-	stor_driver->base.dev_rm = stor_vsc_on_device_remove;
-	stor_driver->base.cleanup = stor_vsc_on_cleanup;
-	stor_driver->on_io_request = stor_vsc_on_io_request;
-
-	return ret;
-}
diff -druN linux-2.6.39-libre/drivers/staging/hv/blkvsc_drv.c linux-3.0-rc7-libre/drivers/staging/hv/blkvsc_drv.c
--- linux-2.6.39-libre/drivers/staging/hv/blkvsc_drv.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/hv/blkvsc_drv.c	2011-07-11 19:51:52.000000000 -0400
@@ -17,6 +17,7 @@
  * Authors:
  *   Haiyang Zhang <haiyangz@microsoft.com>
  *   Hank Janssen  <hjanssen@microsoft.com>
+ *   K. Y. Srinivasan <kys@microsoft.com>
  */
 #include <linux/init.h>
 #include <linux/module.h>
@@ -25,17 +26,14 @@
 #include <linux/major.h>
 #include <linux/delay.h>
 #include <linux/hdreg.h>
-#include <linux/mutex.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 "hv_api.h"
-#include "logging.h"
-#include "version_info.h"
-#include "vmbus.h"
-#include "storvsc_api.h"
+
+#include "hyperv.h"
+#include "hyperv_storage.h"
 
 
 #define BLKVSC_MINORS	64
@@ -46,6 +44,12 @@
 	DVD_TYPE,
 };
 
+enum blkvsc_op_type {
+	DO_INQUIRY,
+	DO_CAPACITY,
+	DO_FLUSH,
+};
+
 /*
  * This request ties the struct request and struct
  * blkvsc_request/hv_storvsc_request together A struct request may be
@@ -72,9 +76,6 @@
 	/* The group this request is part of. Maybe null */
 	struct blkvsc_request_group *group;
 
-	wait_queue_head_t wevent;
-	int cond;
-
 	int write;
 	sector_t sector_start;
 	unsigned long sector_count;
@@ -84,12 +85,6 @@
 	unsigned char cmnd[MAX_COMMAND_SIZE];
 
 	struct hv_storvsc_request request;
-	/*
-	 * !!!DO NOT ADD ANYTHING BELOW HERE!!! Otherwise, memory can overlap,
-	 * because - The extension buffer falls right here and is pointed to by
-	 * request.Extension;
-	 * Which sounds like a horrible idea, who designed this?
-	 */
 };
 
 /* Per device structure */
@@ -106,7 +101,6 @@
 	unsigned int device_id_len;
 	int num_outstanding_reqs;
 	int shutting_down;
-	int media_not_present;
 	unsigned int sector_size;
 	sector_t capacity;
 	unsigned int port;
@@ -115,515 +109,314 @@
 	int users;
 };
 
+static const char *drv_name = "blkvsc";
 
-/* Static decl */
-static DEFINE_MUTEX(blkvsc_mutex);
-static int blkvsc_probe(struct device *dev);
-static int blkvsc_remove(struct device *device);
-static void blkvsc_shutdown(struct device *device);
+/* {32412632-86cb-44a2-9b5c-50d1417354f5} */
+static const struct hv_guid dev_type = {
+	.data = {
+		0x32, 0x26, 0x41, 0x32, 0xcb, 0x86, 0xa2, 0x44,
+		0x9b, 0x5c, 0x50, 0xd1, 0x41, 0x73, 0x54, 0xf5
+	}
+};
 
-static int blkvsc_open(struct block_device *bdev,  fmode_t mode);
-static int blkvsc_release(struct gendisk *disk, fmode_t mode);
-static unsigned int blkvsc_check_events(struct gendisk *gd,
-					unsigned int clearing);
-static int blkvsc_revalidate_disk(struct gendisk *gd);
-static int blkvsc_getgeo(struct block_device *bd, struct hd_geometry *hg);
-static int blkvsc_ioctl(struct block_device *bd, fmode_t mode,
-			unsigned cmd, unsigned long argument);
-static void blkvsc_request(struct request_queue *queue);
+/*
+ * There is a circular dependency involving blkvsc_request_completion()
+ * and blkvsc_do_request().
+ */
 static void blkvsc_request_completion(struct hv_storvsc_request *request);
-static int blkvsc_do_request(struct block_device_context *blkdev,
-			     struct request *req);
-static int blkvsc_submit_request(struct blkvsc_request *blkvsc_req,
-		void (*request_completion)(struct hv_storvsc_request *));
-static void blkvsc_init_rw(struct blkvsc_request *blkvsc_req);
-static void blkvsc_cmd_completion(struct hv_storvsc_request *request);
-static int blkvsc_do_inquiry(struct block_device_context *blkdev);
-static int blkvsc_do_read_capacity(struct block_device_context *blkdev);
-static int blkvsc_do_read_capacity16(struct block_device_context *blkdev);
-static int blkvsc_do_flush(struct block_device_context *blkdev);
-static int blkvsc_cancel_pending_reqs(struct block_device_context *blkdev);
-static int blkvsc_do_pending_reqs(struct block_device_context *blkdev);
 
 static int blkvsc_ringbuffer_size = BLKVSC_RING_BUFFER_SIZE;
+
 module_param(blkvsc_ringbuffer_size, int, S_IRUGO);
 MODULE_PARM_DESC(ring_size, "Ring buffer size (in bytes)");
 
-/* The one and only one */
-static  struct storvsc_driver_object g_blkvsc_drv;
-
-static const struct block_device_operations block_ops = {
-	.owner = THIS_MODULE,
-	.open = blkvsc_open,
-	.release = blkvsc_release,
-	.check_events = blkvsc_check_events,
-	.revalidate_disk = blkvsc_revalidate_disk,
-	.getgeo = blkvsc_getgeo,
-	.ioctl  = blkvsc_ioctl,
-};
-
 /*
- * blkvsc_drv_init -  BlkVsc driver initialization.
+ * There is a circular dependency involving blkvsc_probe()
+ * and block_ops.
  */
-static int blkvsc_drv_init(int (*drv_init)(struct hv_driver *drv))
-{
-	struct storvsc_driver_object *storvsc_drv_obj = &g_blkvsc_drv;
-	struct hv_driver *drv = &g_blkvsc_drv.base;
-	int ret;
+static int blkvsc_probe(struct hv_device *dev);
 
-	storvsc_drv_obj->ring_buffer_size = blkvsc_ringbuffer_size;
+static int blkvsc_device_add(struct hv_device *device,
+				void *additional_info)
+{
+	struct storvsc_device_info *device_info;
+	int ret = 0;
 
-	drv->priv = storvsc_drv_obj;
+	device_info = (struct storvsc_device_info *)additional_info;
 
-	/* Callback to client driver to complete the initialization */
-	drv_init(&storvsc_drv_obj->base);
+	device_info->ring_buffer_size = blkvsc_ringbuffer_size;
 
-	drv->driver.name = storvsc_drv_obj->base.name;
+	ret = storvsc_dev_add(device, additional_info);
+	if (ret != 0)
+		return ret;
 
-	drv->driver.probe = blkvsc_probe;
-	drv->driver.remove = blkvsc_remove;
-	drv->driver.shutdown = blkvsc_shutdown;
+	/*
+	 * We need to use the device instance guid to set the path and target
+	 * id. For IDE devices, the device instance id is formatted as
+	 * <bus id> * - <device id> - 8899 - 000000000000.
+	 */
+	device_info->path_id = device->dev_instance.data[3] << 24 |
+			     device->dev_instance.data[2] << 16 |
+			     device->dev_instance.data[1] << 8  |
+			     device->dev_instance.data[0];
 
-	/* The driver belongs to vmbus */
-	ret = vmbus_child_driver_register(&drv->driver);
+	device_info->target_id = device->dev_instance.data[5] << 8 |
+			       device->dev_instance.data[4];
 
 	return ret;
 }
 
-static int blkvsc_drv_exit_cb(struct device *dev, void *data)
-{
-	struct device **curr = (struct device **)data;
-	*curr = dev;
-	return 1; /* stop iterating */
-}
-
-static void blkvsc_drv_exit(void)
+static int blkvsc_submit_request(struct blkvsc_request *blkvsc_req,
+			void (*request_completion)(struct hv_storvsc_request *))
 {
-	struct storvsc_driver_object *storvsc_drv_obj = &g_blkvsc_drv;
-	struct hv_driver *drv = &g_blkvsc_drv.base;
-	struct device *current_dev;
+	struct block_device_context *blkdev = blkvsc_req->dev;
+	struct hv_storvsc_request *storvsc_req;
+	struct vmscsi_request *vm_srb;
 	int ret;
 
-	while (1) {
-		current_dev = NULL;
 
-		/* Get the device */
-		ret = driver_for_each_device(&drv->driver, NULL,
-					     (void *) &current_dev,
-					     blkvsc_drv_exit_cb);
-
-		if (ret)
-			DPRINT_WARN(BLKVSC_DRV,
-				    "driver_for_each_device returned %d", ret);
-
-
-		if (current_dev == NULL)
-			break;
-
-		/* Initiate removal from the top-down */
-		device_unregister(current_dev);
-	}
-
-	if (storvsc_drv_obj->base.cleanup)
-		storvsc_drv_obj->base.cleanup(&storvsc_drv_obj->base);
-
-	vmbus_child_driver_unregister(&drv->driver);
-
-	return;
-}
-
-/*
- * blkvsc_probe - Add a new device for this driver
- */
-static int blkvsc_probe(struct device *device)
-{
-	struct hv_driver *drv =
-				drv_to_hv_drv(device->driver);
-	struct storvsc_driver_object *storvsc_drv_obj =
-				drv->priv;
-	struct hv_device *device_obj = device_to_hv_device(device);
-
-	struct block_device_context *blkdev = NULL;
-	struct storvsc_device_info device_info;
-	int major = 0;
-	int devnum = 0;
-	int ret = 0;
-	static int ide0_registered;
-	static int ide1_registered;
+	storvsc_req = &blkvsc_req->request;
+	vm_srb = &storvsc_req->vstor_packet.vm_srb;
 
-	DPRINT_DBG(BLKVSC_DRV, "blkvsc_probe - enter");
+	vm_srb->data_in = blkvsc_req->write ? WRITE_TYPE : READ_TYPE;
 
-	if (!storvsc_drv_obj->base.dev_add) {
-		DPRINT_ERR(BLKVSC_DRV, "OnDeviceAdd() not set");
-		ret = -1;
-		goto Cleanup;
-	}
+	storvsc_req->on_io_completion = request_completion;
+	storvsc_req->context = blkvsc_req;
 
-	blkdev = kzalloc(sizeof(struct block_device_context), GFP_KERNEL);
-	if (!blkdev) {
-		ret = -ENOMEM;
-		goto Cleanup;
-	}
+	vm_srb->port_number = blkdev->port;
+	vm_srb->path_id = blkdev->path;
+	vm_srb->target_id = blkdev->target;
+	vm_srb->lun = 0;	 /* this is not really used at all */
 
-	INIT_LIST_HEAD(&blkdev->pending_list);
+	vm_srb->cdb_length = blkvsc_req->cmd_len;
 
-	/* Initialize what we can here */
-	spin_lock_init(&blkdev->lock);
+	memcpy(vm_srb->cdb, blkvsc_req->cmnd, vm_srb->cdb_length);
 
-	/* ASSERT(sizeof(struct blkvsc_request_group) <= */
-	/* 	sizeof(struct blkvsc_request)); */
+	storvsc_req->sense_buffer = blkvsc_req->sense_buffer;
 
-	blkdev->request_pool = kmem_cache_create(dev_name(&device_obj->device),
-					sizeof(struct blkvsc_request) +
-					storvsc_drv_obj->request_ext_size, 0,
-					SLAB_HWCACHE_ALIGN, NULL);
-	if (!blkdev->request_pool) {
-		ret = -ENOMEM;
-		goto Cleanup;
-	}
+	ret =  storvsc_do_io(blkdev->device_ctx,
+					   &blkvsc_req->request);
+	if (ret == 0)
+		blkdev->num_outstanding_reqs++;
 
+	return ret;
+}
 
-	/* Call to the vsc driver to add the device */
-	ret = storvsc_drv_obj->base.dev_add(device_obj, &device_info);
-	if (ret != 0) {
-		DPRINT_ERR(BLKVSC_DRV, "unable to add blkvsc device");
-		goto Cleanup;
-	}
 
-	blkdev->device_ctx = device_obj;
-	/* this identified the device 0 or 1 */
-	blkdev->target = device_info.target_id;
-	/* this identified the ide ctrl 0 or 1 */
-	blkdev->path = device_info.path_id;
+static int blkvsc_open(struct block_device *bdev, fmode_t mode)
+{
+	struct block_device_context *blkdev = bdev->bd_disk->private_data;
+	unsigned long flags;
 
-	dev_set_drvdata(device, blkdev);
+	spin_lock_irqsave(&blkdev->lock, flags);
 
-	/* Calculate the major and device num */
-	if (blkdev->path == 0) {
-		major = IDE0_MAJOR;
-		devnum = blkdev->path + blkdev->target;		/* 0 or 1 */
+	blkdev->users++;
 
-		if (!ide0_registered) {
-			ret = register_blkdev(major, "ide");
-			if (ret != 0) {
-				DPRINT_ERR(BLKVSC_DRV,
-					   "register_blkdev() failed! ret %d",
-					   ret);
-				goto Remove;
-			}
+	spin_unlock_irqrestore(&blkdev->lock, flags);
 
-			ide0_registered = 1;
-		}
-	} else if (blkdev->path == 1) {
-		major = IDE1_MAJOR;
-		devnum = blkdev->path + blkdev->target + 1; /* 2 or 3 */
+	return 0;
+}
 
-		if (!ide1_registered) {
-			ret = register_blkdev(major, "ide");
-			if (ret != 0) {
-				DPRINT_ERR(BLKVSC_DRV,
-					   "register_blkdev() failed! ret %d",
-					   ret);
-				goto Remove;
-			}
 
-			ide1_registered = 1;
-		}
-	} else {
-		DPRINT_ERR(BLKVSC_DRV, "invalid pathid");
-		ret = -1;
-		goto Cleanup;
-	}
+static int blkvsc_getgeo(struct block_device *bd, struct hd_geometry *hg)
+{
+	sector_t nsect = get_capacity(bd->bd_disk);
+	sector_t cylinders = nsect;
 
-	DPRINT_INFO(BLKVSC_DRV, "blkvsc registered for major %d!!", major);
+	/*
+	 * We are making up these values; let us keep it simple.
+	 */
+	hg->heads = 0xff;
+	hg->sectors = 0x3f;
+	sector_div(cylinders, hg->heads * hg->sectors);
+	hg->cylinders = cylinders;
+	if ((sector_t)(hg->cylinders + 1) * hg->heads * hg->sectors < nsect)
+		hg->cylinders = 0xffff;
+	return 0;
 
-	blkdev->gd = alloc_disk(BLKVSC_MINORS);
-	if (!blkdev->gd) {
-		DPRINT_ERR(BLKVSC_DRV, "register_blkdev() failed! ret %d", ret);
-		ret = -1;
-		goto Cleanup;
-	}
+}
 
-	blkdev->gd->queue = blk_init_queue(blkvsc_request, &blkdev->lock);
 
-	blk_queue_max_segment_size(blkdev->gd->queue, PAGE_SIZE);
-	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);
+static void blkvsc_init_rw(struct blkvsc_request *blkvsc_req)
+{
 
-	blkdev->gd->major = major;
-	if (devnum == 1 || devnum == 3)
-		blkdev->gd->first_minor = BLKVSC_MINORS;
-	else
-		blkdev->gd->first_minor = 0;
-	blkdev->gd->fops = &block_ops;
-	blkdev->gd->events = DISK_EVENT_MEDIA_CHANGE;
-	blkdev->gd->private_data = blkdev;
-	blkdev->gd->driverfs_dev = &(blkdev->device_ctx->device);
-	sprintf(blkdev->gd->disk_name, "hd%c", 'a' + devnum);
+	blkvsc_req->cmd_len = 16;
 
-	blkvsc_do_inquiry(blkdev);
-	if (blkdev->device_type == DVD_TYPE) {
-		set_disk_ro(blkdev->gd, 1);
-		blkdev->gd->flags |= GENHD_FL_REMOVABLE;
-		blkvsc_do_read_capacity(blkdev);
+	if (rq_data_dir(blkvsc_req->req)) {
+		blkvsc_req->write = 1;
+		blkvsc_req->cmnd[0] = WRITE_16;
 	} else {
-		blkvsc_do_read_capacity16(blkdev);
+		blkvsc_req->write = 0;
+		blkvsc_req->cmnd[0] = READ_16;
 	}
 
-	set_capacity(blkdev->gd, blkdev->capacity * (blkdev->sector_size/512));
-	blk_queue_logical_block_size(blkdev->gd->queue, blkdev->sector_size);
-	/* go! */
-	add_disk(blkdev->gd);
+	blkvsc_req->cmnd[1] |=
+	(blkvsc_req->req->cmd_flags & REQ_FUA) ? 0x8 : 0;
 
-	DPRINT_INFO(BLKVSC_DRV, "%s added!! capacity %lu sector_size %d",
-		    blkdev->gd->disk_name, (unsigned long)blkdev->capacity,
-		    blkdev->sector_size);
+	*(unsigned long long *)&blkvsc_req->cmnd[2] =
+	cpu_to_be64(blkvsc_req->sector_start);
+	*(unsigned int *)&blkvsc_req->cmnd[10] =
+	cpu_to_be32(blkvsc_req->sector_count);
+}
 
-	return ret;
 
-Remove:
-	storvsc_drv_obj->base.dev_rm(device_obj);
+static int blkvsc_ioctl(struct block_device *bd, fmode_t mode,
+			unsigned cmd, unsigned long arg)
+{
+	struct block_device_context *blkdev = bd->bd_disk->private_data;
+	int ret = 0;
 
-Cleanup:
-	if (blkdev) {
-		if (blkdev->request_pool) {
-			kmem_cache_destroy(blkdev->request_pool);
-			blkdev->request_pool = NULL;
-		}
-		kfree(blkdev);
-		blkdev = NULL;
+	switch (cmd) {
+	case HDIO_GET_IDENTITY:
+		if (copy_to_user((void __user *)arg, blkdev->device_id,
+				 blkdev->device_id_len))
+			ret = -EFAULT;
+		break;
+	default:
+		ret = -EINVAL;
+		break;
 	}
 
 	return ret;
 }
 
-static void blkvsc_shutdown(struct device *device)
+static void blkvsc_cmd_completion(struct hv_storvsc_request *request)
 {
-	struct block_device_context *blkdev = dev_get_drvdata(device);
+	struct blkvsc_request *blkvsc_req =
+			(struct blkvsc_request *)request->context;
+	struct block_device_context *blkdev =
+			(struct block_device_context *)blkvsc_req->dev;
+	struct scsi_sense_hdr sense_hdr;
+	struct vmscsi_request *vm_srb;
 	unsigned long flags;
 
-	if (!blkdev)
-		return;
 
-	DPRINT_DBG(BLKVSC_DRV, "blkvsc_shutdown - users %d disk %s\n",
-		   blkdev->users, blkdev->gd->disk_name);
+	vm_srb = &blkvsc_req->request.vstor_packet.vm_srb;
 
 	spin_lock_irqsave(&blkdev->lock, flags);
-
-	blkdev->shutting_down = 1;
-
-	blk_stop_queue(blkdev->gd->queue);
-
+	blkdev->num_outstanding_reqs--;
 	spin_unlock_irqrestore(&blkdev->lock, flags);
 
-	while (blkdev->num_outstanding_reqs) {
-		DPRINT_INFO(STORVSC, "waiting for %d requests to complete...",
-			    blkdev->num_outstanding_reqs);
-		udelay(100);
-	}
-
-	blkvsc_do_flush(blkdev);
-
-	spin_lock_irqsave(&blkdev->lock, flags);
-
-	blkvsc_cancel_pending_reqs(blkdev);
+	if (vm_srb->scsi_status)
+		if (scsi_normalize_sense(blkvsc_req->sense_buffer,
+					 SCSI_SENSE_BUFFERSIZE, &sense_hdr))
+			scsi_print_sense_hdr("blkvsc", &sense_hdr);
 
-	spin_unlock_irqrestore(&blkdev->lock, flags);
+	complete(&blkvsc_req->request.wait_event);
 }
 
-static int blkvsc_do_flush(struct block_device_context *blkdev)
-{
-	struct blkvsc_request *blkvsc_req;
-
-	DPRINT_DBG(BLKVSC_DRV, "blkvsc_do_flush()\n");
-
-	if (blkdev->device_type != HARDDISK_TYPE)
-		return 0;
-
-	blkvsc_req = kmem_cache_alloc(blkdev->request_pool, GFP_KERNEL);
-	if (!blkvsc_req)
-		return -ENOMEM;
-
-	memset(blkvsc_req, 0, sizeof(struct blkvsc_request));
-	init_waitqueue_head(&blkvsc_req->wevent);
-	blkvsc_req->dev = blkdev;
-	blkvsc_req->req = NULL;
-	blkvsc_req->write = 0;
-
-	blkvsc_req->request.data_buffer.pfn_array[0] = 0;
-	blkvsc_req->request.data_buffer.offset = 0;
-	blkvsc_req->request.data_buffer.len = 0;
-
-	blkvsc_req->cmnd[0] = SYNCHRONIZE_CACHE;
-	blkvsc_req->cmd_len = 10;
-
-	/*
-	 * Set this here since the completion routine may be invoked and
-	 * completed before we return
-	 */
-	blkvsc_req->cond = 0;
-	blkvsc_submit_request(blkvsc_req, blkvsc_cmd_completion);
-
-	wait_event_interruptible(blkvsc_req->wevent, blkvsc_req->cond);
-
-	kmem_cache_free(blkvsc_req->dev->request_pool, blkvsc_req);
-
-	return 0;
-}
 
-/* Do a scsi INQUIRY cmd here to get the device type (ie disk or dvd) */
-static int blkvsc_do_inquiry(struct block_device_context *blkdev)
+static int blkvsc_do_operation(struct block_device_context *blkdev,
+				enum blkvsc_op_type op)
 {
 	struct blkvsc_request *blkvsc_req;
 	struct page *page_buf;
 	unsigned char *buf;
 	unsigned char device_type;
+	struct scsi_sense_hdr sense_hdr;
+	struct vmscsi_request *vm_srb;
+	unsigned long flags;
 
-	DPRINT_DBG(BLKVSC_DRV, "blkvsc_do_inquiry()\n");
+	int ret = 0;
 
-	blkvsc_req = kmem_cache_alloc(blkdev->request_pool, GFP_KERNEL);
+	blkvsc_req = kmem_cache_zalloc(blkdev->request_pool, GFP_KERNEL);
 	if (!blkvsc_req)
 		return -ENOMEM;
 
-	memset(blkvsc_req, 0, sizeof(struct blkvsc_request));
 	page_buf = alloc_page(GFP_KERNEL);
 	if (!page_buf) {
 		kmem_cache_free(blkvsc_req->dev->request_pool, blkvsc_req);
 		return -ENOMEM;
 	}
 
-	init_waitqueue_head(&blkvsc_req->wevent);
+	vm_srb = &blkvsc_req->request.vstor_packet.vm_srb;
+	init_completion(&blkvsc_req->request.wait_event);
 	blkvsc_req->dev = blkdev;
 	blkvsc_req->req = NULL;
 	blkvsc_req->write = 0;
 
-	blkvsc_req->request.data_buffer.pfn_array[0] = page_to_pfn(page_buf);
+	blkvsc_req->request.data_buffer.pfn_array[0] =
+	page_to_pfn(page_buf);
 	blkvsc_req->request.data_buffer.offset = 0;
-	blkvsc_req->request.data_buffer.len = 64;
-
-	blkvsc_req->cmnd[0] = INQUIRY;
-	blkvsc_req->cmnd[1] = 0x1;		/* Get product data */
-	blkvsc_req->cmnd[2] = 0x83;		/* mode page 83 */
-	blkvsc_req->cmnd[4] = 64;
-	blkvsc_req->cmd_len = 6;
 
-	/*
-	 * Set this here since the completion routine may be invoked and
-	 * completed before we return
-	 */
-	blkvsc_req->cond = 0;
-
-	blkvsc_submit_request(blkvsc_req, blkvsc_cmd_completion);
-
-	DPRINT_DBG(BLKVSC_DRV, "waiting %p to complete - cond %d\n",
-		   blkvsc_req, blkvsc_req->cond);
-
-	wait_event_interruptible(blkvsc_req->wevent, blkvsc_req->cond);
+	switch (op) {
+	case DO_INQUIRY:
+		blkvsc_req->cmnd[0] = INQUIRY;
+		blkvsc_req->cmnd[1] = 0x1;		/* Get product data */
+		blkvsc_req->cmnd[2] = 0x83;		/* mode page 83 */
+		blkvsc_req->cmnd[4] = 64;
+		blkvsc_req->cmd_len = 6;
+		blkvsc_req->request.data_buffer.len = 64;
+		break;
 
-	buf = kmap(page_buf);
+	case DO_CAPACITY:
+		blkdev->sector_size = 0;
+		blkdev->capacity = 0;
 
-	/* print_hex_dump_bytes("", DUMP_PREFIX_NONE, buf, 64); */
-	/* be to le */
-	device_type = buf[0] & 0x1F;
+		blkvsc_req->cmnd[0] = READ_CAPACITY;
+		blkvsc_req->cmd_len = 16;
+		blkvsc_req->request.data_buffer.len = 8;
+		break;
 
-	if (device_type == 0x0) {
-		blkdev->device_type = HARDDISK_TYPE;
-	} else if (device_type == 0x5) {
-		blkdev->device_type = DVD_TYPE;
-	} else {
-		/* TODO: this is currently unsupported device type */
-		blkdev->device_type = UNKNOWN_DEV_TYPE;
+	case DO_FLUSH:
+		blkvsc_req->cmnd[0] = SYNCHRONIZE_CACHE;
+		blkvsc_req->cmd_len = 10;
+		blkvsc_req->request.data_buffer.pfn_array[0] = 0;
+		blkvsc_req->request.data_buffer.len = 0;
+		break;
+	default:
+		ret = -EINVAL;
+		goto cleanup;
 	}
 
-	DPRINT_DBG(BLKVSC_DRV, "device type %d\n", device_type);
-
-	blkdev->device_id_len = buf[7];
-	if (blkdev->device_id_len > 64)
-		blkdev->device_id_len = 64;
-
-	memcpy(blkdev->device_id, &buf[8], blkdev->device_id_len);
-	/* printk_hex_dump_bytes("", DUMP_PREFIX_NONE, blkdev->device_id,
-	 * blkdev->device_id_len); */
-
-	kunmap(page_buf);
-
-	__free_page(page_buf);
-
-	kmem_cache_free(blkvsc_req->dev->request_pool, blkvsc_req);
-
-	return 0;
-}
-
-/* Do a scsi READ_CAPACITY cmd here to get the size of the disk */
-static int blkvsc_do_read_capacity(struct block_device_context *blkdev)
-{
-	struct blkvsc_request *blkvsc_req;
-	struct page *page_buf;
-	unsigned char *buf;
-	struct scsi_sense_hdr sense_hdr;
-
-	DPRINT_DBG(BLKVSC_DRV, "blkvsc_do_read_capacity()\n");
+	spin_lock_irqsave(&blkdev->lock, flags);
+	blkvsc_submit_request(blkvsc_req, blkvsc_cmd_completion);
+	spin_unlock_irqrestore(&blkdev->lock, flags);
 
-	blkdev->sector_size = 0;
-	blkdev->capacity = 0;
-	blkdev->media_not_present = 0; /* assume a disk is present */
+	wait_for_completion_interruptible(&blkvsc_req->request.wait_event);
 
-	blkvsc_req = kmem_cache_alloc(blkdev->request_pool, GFP_KERNEL);
-	if (!blkvsc_req)
-		return -ENOMEM;
+	/* check error */
+	if (vm_srb->scsi_status) {
+		scsi_normalize_sense(blkvsc_req->sense_buffer,
+				     SCSI_SENSE_BUFFERSIZE, &sense_hdr);
 
-	memset(blkvsc_req, 0, sizeof(struct blkvsc_request));
-	page_buf = alloc_page(GFP_KERNEL);
-	if (!page_buf) {
-		kmem_cache_free(blkvsc_req->dev->request_pool, blkvsc_req);
-		return -ENOMEM;
+		return 0;
 	}
 
-	init_waitqueue_head(&blkvsc_req->wevent);
-	blkvsc_req->dev = blkdev;
-	blkvsc_req->req = NULL;
-	blkvsc_req->write = 0;
-
-	blkvsc_req->request.data_buffer.pfn_array[0] = page_to_pfn(page_buf);
-	blkvsc_req->request.data_buffer.offset = 0;
-	blkvsc_req->request.data_buffer.len = 8;
+	buf = kmap(page_buf);
 
-	blkvsc_req->cmnd[0] = READ_CAPACITY;
-	blkvsc_req->cmd_len = 16;
+	switch (op) {
+	case DO_INQUIRY:
+		device_type = buf[0] & 0x1F;
 
-	/*
-	 * Set this here since the completion routine may be invoked
-	 * and completed before we return
-	 */
-	blkvsc_req->cond = 0;
+		if (device_type == 0x0)
+			blkdev->device_type = HARDDISK_TYPE;
+		 else
+			blkdev->device_type = UNKNOWN_DEV_TYPE;
 
-	blkvsc_submit_request(blkvsc_req, blkvsc_cmd_completion);
+		blkdev->device_id_len = buf[7];
+		if (blkdev->device_id_len > 64)
+			blkdev->device_id_len = 64;
 
-	DPRINT_DBG(BLKVSC_DRV, "waiting %p to complete - cond %d\n",
-		   blkvsc_req, blkvsc_req->cond);
+		memcpy(blkdev->device_id, &buf[8], blkdev->device_id_len);
+		break;
 
-	wait_event_interruptible(blkvsc_req->wevent, blkvsc_req->cond);
+	case DO_CAPACITY:
+		/* be to le */
+		blkdev->capacity =
+		((buf[0] << 24) | (buf[1] << 16) |
+		(buf[2] << 8) | buf[3]) + 1;
 
-	/* check error */
-	if (blkvsc_req->request.status) {
-		scsi_normalize_sense(blkvsc_req->sense_buffer,
-				     SCSI_SENSE_BUFFERSIZE, &sense_hdr);
+		blkdev->sector_size =
+		(buf[4] << 24) | (buf[5] << 16) |
+		(buf[6] << 8) | buf[7];
+		break;
+	default:
+		break;
 
-		if (sense_hdr.asc == 0x3A) {
-			/* Medium not present */
-			blkdev->media_not_present = 1;
-		}
-		return 0;
 	}
-	buf = kmap(page_buf);
 
-	/* be to le */
-	blkdev->capacity = ((buf[0] << 24) | (buf[1] << 16) |
-			    (buf[2] << 8) | buf[3]) + 1;
-	blkdev->sector_size = (buf[4] << 24) | (buf[5] << 16) |
-			      (buf[6] << 8) | buf[7];
+cleanup:
 
 	kunmap(page_buf);
 
@@ -631,119 +424,86 @@
 
 	kmem_cache_free(blkvsc_req->dev->request_pool, blkvsc_req);
 
-	return 0;
+	return ret;
 }
 
-static int blkvsc_do_read_capacity16(struct block_device_context *blkdev)
-{
-	struct blkvsc_request *blkvsc_req;
-	struct page *page_buf;
-	unsigned char *buf;
-	struct scsi_sense_hdr sense_hdr;
-
-	DPRINT_DBG(BLKVSC_DRV, "blkvsc_do_read_capacity16()\n");
-
-	blkdev->sector_size = 0;
-	blkdev->capacity = 0;
-	blkdev->media_not_present = 0; /* assume a disk is present */
 
-	blkvsc_req = kmem_cache_alloc(blkdev->request_pool, GFP_KERNEL);
-	if (!blkvsc_req)
-		return -ENOMEM;
-
-	memset(blkvsc_req, 0, sizeof(struct blkvsc_request));
-	page_buf = alloc_page(GFP_KERNEL);
-	if (!page_buf) {
-		kmem_cache_free(blkvsc_req->dev->request_pool, blkvsc_req);
-		return -ENOMEM;
-	}
+static int blkvsc_cancel_pending_reqs(struct block_device_context *blkdev)
+{
+	struct blkvsc_request *pend_req, *tmp;
+	struct blkvsc_request *comp_req, *tmp2;
+	struct vmscsi_request *vm_srb;
 
-	init_waitqueue_head(&blkvsc_req->wevent);
-	blkvsc_req->dev = blkdev;
-	blkvsc_req->req = NULL;
-	blkvsc_req->write = 0;
+	int ret = 0;
 
-	blkvsc_req->request.data_buffer.pfn_array[0] = page_to_pfn(page_buf);
-	blkvsc_req->request.data_buffer.offset = 0;
-	blkvsc_req->request.data_buffer.len = 12;
 
-	blkvsc_req->cmnd[0] = 0x9E; /* READ_CAPACITY16; */
-	blkvsc_req->cmd_len = 16;
+	/* Flush the pending list first */
+	list_for_each_entry_safe(pend_req, tmp, &blkdev->pending_list,
+				 pend_entry) {
+		/*
+		 * The pend_req could be part of a partially completed
+		 * request. If so, complete those req first until we
+		 * hit the pend_req
+		 */
+		list_for_each_entry_safe(comp_req, tmp2,
+					 &pend_req->group->blkvsc_req_list,
+					 req_entry) {
 
-	/*
-	 * Set this here since the completion routine may be invoked
-	 * and completed before we return
-	 */
-	blkvsc_req->cond = 0;
+			if (comp_req == pend_req)
+				break;
 
-	blkvsc_submit_request(blkvsc_req, blkvsc_cmd_completion);
+			list_del(&comp_req->req_entry);
 
-	DPRINT_DBG(BLKVSC_DRV, "waiting %p to complete - cond %d\n",
-		   blkvsc_req, blkvsc_req->cond);
+			if (comp_req->req) {
+				vm_srb =
+				&comp_req->request.vstor_packet.
+				vm_srb;
+				ret = __blk_end_request(comp_req->req,
+					(!vm_srb->scsi_status ? 0 : -EIO),
+					comp_req->sector_count *
+					blkdev->sector_size);
 
-	wait_event_interruptible(blkvsc_req->wevent, blkvsc_req->cond);
+				/* FIXME: shouldn't this do more than return? */
+				if (ret)
+					goto out;
+			}
 
-	/* check error */
-	if (blkvsc_req->request.status) {
-		scsi_normalize_sense(blkvsc_req->sense_buffer,
-				     SCSI_SENSE_BUFFERSIZE, &sense_hdr);
-		if (sense_hdr.asc == 0x3A) {
-			/* Medium not present */
-			blkdev->media_not_present = 1;
+			kmem_cache_free(blkdev->request_pool, comp_req);
 		}
-		return 0;
-	}
-	buf = kmap(page_buf);
 
-	/* be to le */
-	blkdev->capacity = be64_to_cpu(*(unsigned long long *) &buf[0]) + 1;
-	blkdev->sector_size = be32_to_cpu(*(unsigned int *)&buf[8]);
-
-#if 0
-	blkdev->capacity = ((buf[0] << 24) | (buf[1] << 16) |
-			    (buf[2] << 8) | buf[3]) + 1;
-	blkdev->sector_size = (buf[4] << 24) | (buf[5] << 16) |
-			      (buf[6] << 8) | buf[7];
-#endif
+		list_del(&pend_req->pend_entry);
 
-	kunmap(page_buf);
+		list_del(&pend_req->req_entry);
 
-	__free_page(page_buf);
+		if (comp_req->req) {
+			if (!__blk_end_request(pend_req->req, -EIO,
+					       pend_req->sector_count *
+					       blkdev->sector_size)) {
+				/*
+				 * All the sectors have been xferred ie the
+				 * request is done
+				 */
+				kmem_cache_free(blkdev->request_pool,
+						pend_req->group);
+			}
+		}
 
-	kmem_cache_free(blkvsc_req->dev->request_pool, blkvsc_req);
+		kmem_cache_free(blkdev->request_pool, pend_req);
+	}
 
-	return 0;
+out:
+	return ret;
 }
 
+
 /*
  * blkvsc_remove() - Callback when our device is removed
  */
-static int blkvsc_remove(struct device *device)
+static int blkvsc_remove(struct hv_device *dev)
 {
-	struct hv_driver *drv =
-				drv_to_hv_drv(device->driver);
-	struct storvsc_driver_object *storvsc_drv_obj =
-				drv->priv;
-	struct hv_device *device_obj = device_to_hv_device(device);
-	struct block_device_context *blkdev = dev_get_drvdata(device);
+	struct block_device_context *blkdev = dev_get_drvdata(&dev->device);
 	unsigned long flags;
-	int ret;
-
-	DPRINT_DBG(BLKVSC_DRV, "blkvsc_remove()\n");
-
-	if (!storvsc_drv_obj->base.dev_rm)
-		return -1;
 
-	/*
-	 * Call to the vsc driver to let it know that the device is being
-	 * removed
-	 */
-	ret = storvsc_drv_obj->base.dev_rm(device_obj);
-	if (ret != 0) {
-		/* TODO: */
-		DPRINT_ERR(BLKVSC_DRV,
-			   "unable to remove blkvsc device (ret %d)", ret);
-	}
 
 	/* Get to a known state */
 	spin_lock_irqsave(&blkdev->lock, flags);
@@ -752,149 +512,77 @@
 
 	blk_stop_queue(blkdev->gd->queue);
 
-	spin_unlock_irqrestore(&blkdev->lock, flags);
-
-	while (blkdev->num_outstanding_reqs) {
-		DPRINT_INFO(STORVSC, "waiting for %d requests to complete...",
-			    blkdev->num_outstanding_reqs);
-		udelay(100);
-	}
-
-	blkvsc_do_flush(blkdev);
-
-	spin_lock_irqsave(&blkdev->lock, flags);
-
 	blkvsc_cancel_pending_reqs(blkdev);
 
 	spin_unlock_irqrestore(&blkdev->lock, flags);
 
+	blkvsc_do_operation(blkdev, DO_FLUSH);
+
 	blk_cleanup_queue(blkdev->gd->queue);
 
+	/*
+	 * Call to the vsc driver to let it know that the device is being
+	 * removed
+	 */
+	storvsc_dev_remove(dev);
+
 	del_gendisk(blkdev->gd);
 
 	kmem_cache_destroy(blkdev->request_pool);
 
 	kfree(blkdev);
 
-	return ret;
+	return 0;
+
 }
 
-static void blkvsc_init_rw(struct blkvsc_request *blkvsc_req)
+static void blkvsc_shutdown(struct hv_device *dev)
 {
-	/* ASSERT(blkvsc_req->req); */
-	/* ASSERT(blkvsc_req->sector_count <= (MAX_MULTIPAGE_BUFFER_COUNT*8)); */
+	struct block_device_context *blkdev = dev_get_drvdata(&dev->device);
+	unsigned long flags;
 
-	blkvsc_req->cmd_len = 16;
+	if (!blkdev)
+		return;
 
-	if (blkvsc_req->sector_start > 0xffffffff) {
-		if (rq_data_dir(blkvsc_req->req)) {
-			blkvsc_req->write = 1;
-			blkvsc_req->cmnd[0] = WRITE_16;
-		} else {
-			blkvsc_req->write = 0;
-			blkvsc_req->cmnd[0] = READ_16;
-		}
+	spin_lock_irqsave(&blkdev->lock, flags);
 
-		blkvsc_req->cmnd[1] |=
-			(blkvsc_req->req->cmd_flags & REQ_FUA) ? 0x8 : 0;
+	blkdev->shutting_down = 1;
 
-		*(unsigned long long *)&blkvsc_req->cmnd[2] =
-				cpu_to_be64(blkvsc_req->sector_start);
-		*(unsigned int *)&blkvsc_req->cmnd[10] =
-				cpu_to_be32(blkvsc_req->sector_count);
-	} else if ((blkvsc_req->sector_count > 0xff) ||
-		   (blkvsc_req->sector_start > 0x1fffff)) {
-		if (rq_data_dir(blkvsc_req->req)) {
-			blkvsc_req->write = 1;
-			blkvsc_req->cmnd[0] = WRITE_10;
-		} else {
-			blkvsc_req->write = 0;
-			blkvsc_req->cmnd[0] = READ_10;
-		}
+	blk_stop_queue(blkdev->gd->queue);
 
-		blkvsc_req->cmnd[1] |=
-			(blkvsc_req->req->cmd_flags & REQ_FUA) ? 0x8 : 0;
+	blkvsc_cancel_pending_reqs(blkdev);
 
-		*(unsigned int *)&blkvsc_req->cmnd[2] =
-				cpu_to_be32(blkvsc_req->sector_start);
-		*(unsigned short *)&blkvsc_req->cmnd[7] =
-				cpu_to_be16(blkvsc_req->sector_count);
-	} else {
-		if (rq_data_dir(blkvsc_req->req)) {
-			blkvsc_req->write = 1;
-			blkvsc_req->cmnd[0] = WRITE_6;
-		} else {
-			blkvsc_req->write = 0;
-			blkvsc_req->cmnd[0] = READ_6;
-		}
+	spin_unlock_irqrestore(&blkdev->lock, flags);
+
+	blkvsc_do_operation(blkdev, DO_FLUSH);
+
+	/*
+	 * Now wait for all outgoing I/O to be drained.
+	 */
+	storvsc_wait_to_drain((struct storvsc_device *)dev->ext);
 
-		*(unsigned int *)&blkvsc_req->cmnd[1] =
-				cpu_to_be32(blkvsc_req->sector_start) >> 8;
-		blkvsc_req->cmnd[1] &= 0x1f;
-		blkvsc_req->cmnd[4] = (unsigned char)blkvsc_req->sector_count;
-	}
 }
 
-static int blkvsc_submit_request(struct blkvsc_request *blkvsc_req,
-			void (*request_completion)(struct hv_storvsc_request *))
+static int blkvsc_release(struct gendisk *disk, fmode_t mode)
 {
-	struct block_device_context *blkdev = blkvsc_req->dev;
-	struct hv_device *device_ctx = blkdev->device_ctx;
-	struct hv_driver *drv =
-			drv_to_hv_drv(device_ctx->device.driver);
-	struct storvsc_driver_object *storvsc_drv_obj =
-			drv->priv;
-	struct hv_storvsc_request *storvsc_req;
-	int ret;
+	struct block_device_context *blkdev = disk->private_data;
+	unsigned long flags;
 
-	DPRINT_DBG(BLKVSC_DRV, "blkvsc_submit_request() - "
-		   "req %p type %s start_sector %lu count %ld offset %d "
-		   "len %d\n", blkvsc_req,
-		   (blkvsc_req->write) ? "WRITE" : "READ",
-		   (unsigned long) blkvsc_req->sector_start,
-		   blkvsc_req->sector_count,
-		   blkvsc_req->request.data_buffer.offset,
-		   blkvsc_req->request.data_buffer.len);
-#if 0
-	for (i = 0; i < (blkvsc_req->request.data_buffer.len >> 12); i++) {
-		DPRINT_DBG(BLKVSC_DRV, "blkvsc_submit_request() - "
-			   "req %p pfn[%d] %llx\n",
-			   blkvsc_req, i,
-			   blkvsc_req->request.data_buffer.pfn_array[i]);
+	if (blkdev->users == 1) {
+		blkvsc_do_operation(blkdev, DO_FLUSH);
 	}
-#endif
 
-	storvsc_req = &blkvsc_req->request;
-	storvsc_req->extension = (void *)((unsigned long)blkvsc_req +
-					  sizeof(struct blkvsc_request));
-
-	storvsc_req->type = blkvsc_req->write ? WRITE_TYPE : READ_TYPE;
-
-	storvsc_req->on_io_completion = request_completion;
-	storvsc_req->context = blkvsc_req;
-
-	storvsc_req->host = blkdev->port;
-	storvsc_req->bus = blkdev->path;
-	storvsc_req->target_id = blkdev->target;
-	storvsc_req->lun_id = 0;	 /* this is not really used at all */
-
-	storvsc_req->cdb_len = blkvsc_req->cmd_len;
-	storvsc_req->cdb = blkvsc_req->cmnd;
-
-	storvsc_req->sense_buffer = blkvsc_req->sense_buffer;
-	storvsc_req->sense_buffer_size = SCSI_SENSE_BUFFERSIZE;
-
-	ret = storvsc_drv_obj->on_io_request(blkdev->device_ctx,
-					   &blkvsc_req->request);
-	if (ret == 0)
-		blkdev->num_outstanding_reqs++;
+	spin_lock_irqsave(&blkdev->lock, flags);
+	blkdev->users--;
+	spin_unlock_irqrestore(&blkdev->lock, flags);
 
-	return ret;
+	return 0;
 }
 
+
 /*
  * We break the request into 1 or more blkvsc_requests and submit
- * them.  If we can't submit them all, we put them on the
+ * them.  If we cant submit them all, we put them on the
  * pending_list. The blkvsc_request() will work on the pending_list.
  */
 static int blkvsc_do_request(struct block_device_context *blkdev,
@@ -913,11 +601,8 @@
 	int pending = 0;
 	struct blkvsc_request_group *group = NULL;
 
-	DPRINT_DBG(BLKVSC_DRV, "blkdev %p req %p sect %lu\n", blkdev, req,
-		  (unsigned long)blk_rq_pos(req));
-
 	/* Create a group to tie req to list of blkvsc_reqs */
-	group = kmem_cache_alloc(blkdev->request_pool, GFP_ATOMIC);
+	group = kmem_cache_zalloc(blkdev->request_pool, GFP_ATOMIC);
 	if (!group)
 		return -ENOMEM;
 
@@ -933,11 +618,6 @@
 			 * Map this bio into an existing or new storvsc request
 			 */
 			bio_for_each_segment(bvec, bio, seg_idx) {
-				DPRINT_DBG(BLKVSC_DRV, "bio_for_each_segment() "
-					   "- req %p bio %p bvec %p seg_idx %d "
-					   "databuf_idx %d\n", req, bio, bvec,
-					   seg_idx, databuf_idx);
-
 				/* Get a new storvsc request */
 				/* 1st-time */
 				if ((!blkvsc_req) ||
@@ -949,10 +629,15 @@
 				     (prev_bvec->bv_len != PAGE_SIZE))) {
 					/* submit the prev one */
 					if (blkvsc_req) {
-						blkvsc_req->sector_start = start_sector;
-						sector_div(blkvsc_req->sector_start, (blkdev->sector_size >> 9));
+						blkvsc_req->sector_start =
+						start_sector;
+						sector_div(
+						blkvsc_req->sector_start,
+						(blkdev->sector_size >> 9));
 
-						blkvsc_req->sector_count = num_sectors / (blkdev->sector_size >> 9);
+						blkvsc_req->sector_count =
+						num_sectors /
+						(blkdev->sector_size >> 9);
 						blkvsc_init_rw(blkvsc_req);
 					}
 
@@ -960,18 +645,24 @@
 					 * Create new blkvsc_req to represent
 					 * the current bvec
 					 */
-					blkvsc_req = kmem_cache_alloc(blkdev->request_pool, GFP_ATOMIC);
+					blkvsc_req =
+					kmem_cache_zalloc(
+					blkdev->request_pool, GFP_ATOMIC);
 					if (!blkvsc_req) {
 						/* free up everything */
 						list_for_each_entry_safe(
 							blkvsc_req, tmp,
 							&group->blkvsc_req_list,
 							req_entry) {
-							list_del(&blkvsc_req->req_entry);
-							kmem_cache_free(blkdev->request_pool, blkvsc_req);
+							list_del(
+							&blkvsc_req->req_entry);
+							kmem_cache_free(
+							blkdev->request_pool,
+							blkvsc_req);
 						}
 
-						kmem_cache_free(blkdev->request_pool, group);
+						kmem_cache_free(
+						blkdev->request_pool, group);
 						return -ENOMEM;
 					}
 
@@ -980,23 +671,27 @@
 
 					blkvsc_req->dev = blkdev;
 					blkvsc_req->req = req;
-					blkvsc_req->request.data_buffer.offset
-						= bvec->bv_offset;
-					blkvsc_req->request.data_buffer.len
-						= 0;
+					blkvsc_req->request.
+					data_buffer.offset
+					= bvec->bv_offset;
+					blkvsc_req->request.
+					data_buffer.len = 0;
 
 					/* Add to the group */
 					blkvsc_req->group = group;
 					blkvsc_req->group->outstanding++;
 					list_add_tail(&blkvsc_req->req_entry,
-						&blkvsc_req->group->blkvsc_req_list);
+					&blkvsc_req->group->blkvsc_req_list);
 
 					start_sector += num_sectors;
 					num_sectors = 0;
 					databuf_idx = 0;
 				}
 
-				/* Add the curr bvec/segment to the curr blkvsc_req */
+				/*
+				 * Add the curr bvec/segment to the curr
+				 * blkvsc_req
+				 */
 				blkvsc_req->request.data_buffer.
 					pfn_array[databuf_idx]
 						= page_to_pfn(bvec->bv_page);
@@ -1015,10 +710,6 @@
 
 	/* Handle the last one */
 	if (blkvsc_req) {
-		DPRINT_DBG(BLKVSC_DRV, "blkdev %p req %p group %p count %d\n",
-			   blkdev, req, blkvsc_req->group,
-			   blkvsc_req->group->outstanding);
-
 		blkvsc_req->sector_start = start_sector;
 		sector_div(blkvsc_req->sector_start,
 			   (blkdev->sector_size >> 9));
@@ -1031,13 +722,6 @@
 
 	list_for_each_entry(blkvsc_req, &group->blkvsc_req_list, req_entry) {
 		if (pending) {
-			DPRINT_DBG(BLKVSC_DRV, "adding blkvsc_req to "
-				   "pending_list - blkvsc_req %p start_sect %lu"
-				   " sect_count %ld (%lu %ld)\n", blkvsc_req,
-				   (unsigned long)blkvsc_req->sector_start,
-				   blkvsc_req->sector_count,
-				   (unsigned long)start_sector,
-				   (unsigned long)num_sectors);
 
 			list_add_tail(&blkvsc_req->pend_entry,
 				      &blkdev->pending_list);
@@ -1050,186 +734,12 @@
 					      &blkdev->pending_list);
 			}
 
-			DPRINT_DBG(BLKVSC_DRV, "submitted blkvsc_req %p "
-				   "start_sect %lu sect_count %ld (%lu %ld) "
-				   "ret %d\n", blkvsc_req,
-				   (unsigned long)blkvsc_req->sector_start,
-				   blkvsc_req->sector_count,
-				   (unsigned long)start_sector,
-				   num_sectors, ret);
 		}
 	}
 
 	return pending;
 }
 
-static void blkvsc_cmd_completion(struct hv_storvsc_request *request)
-{
-	struct blkvsc_request *blkvsc_req =
-			(struct blkvsc_request *)request->context;
-	struct block_device_context *blkdev =
-			(struct block_device_context *)blkvsc_req->dev;
-	struct scsi_sense_hdr sense_hdr;
-
-	DPRINT_DBG(BLKVSC_DRV, "blkvsc_cmd_completion() - req %p\n",
-		   blkvsc_req);
-
-	blkdev->num_outstanding_reqs--;
-
-	if (blkvsc_req->request.status)
-		if (scsi_normalize_sense(blkvsc_req->sense_buffer,
-					 SCSI_SENSE_BUFFERSIZE, &sense_hdr))
-			scsi_print_sense_hdr("blkvsc", &sense_hdr);
-
-	blkvsc_req->cond = 1;
-	wake_up_interruptible(&blkvsc_req->wevent);
-}
-
-static void blkvsc_request_completion(struct hv_storvsc_request *request)
-{
-	struct blkvsc_request *blkvsc_req =
-			(struct blkvsc_request *)request->context;
-	struct block_device_context *blkdev =
-			(struct block_device_context *)blkvsc_req->dev;
-	unsigned long flags;
-	struct blkvsc_request *comp_req, *tmp;
-
-	/* ASSERT(blkvsc_req->group); */
-
-	DPRINT_DBG(BLKVSC_DRV, "blkdev %p blkvsc_req %p group %p type %s "
-		   "sect_start %lu sect_count %ld len %d group outstd %d "
-		   "total outstd %d\n",
-		   blkdev, blkvsc_req, blkvsc_req->group,
-		   (blkvsc_req->write) ? "WRITE" : "READ",
-		   (unsigned long)blkvsc_req->sector_start,
-		   blkvsc_req->sector_count,
-		   blkvsc_req->request.data_buffer.len,
-		   blkvsc_req->group->outstanding,
-		   blkdev->num_outstanding_reqs);
-
-	spin_lock_irqsave(&blkdev->lock, flags);
-
-	blkdev->num_outstanding_reqs--;
-	blkvsc_req->group->outstanding--;
-
-	/*
-	 * Only start processing when all the blkvsc_reqs are
-	 * completed. This guarantees no out-of-order blkvsc_req
-	 * completion when calling end_that_request_first()
-	 */
-	if (blkvsc_req->group->outstanding == 0) {
-		list_for_each_entry_safe(comp_req, tmp,
-					 &blkvsc_req->group->blkvsc_req_list,
-					 req_entry) {
-			DPRINT_DBG(BLKVSC_DRV, "completing blkvsc_req %p "
-				   "sect_start %lu sect_count %ld\n",
-				   comp_req,
-				   (unsigned long)comp_req->sector_start,
-				   comp_req->sector_count);
-
-			list_del(&comp_req->req_entry);
-
-			if (!__blk_end_request(comp_req->req,
-				(!comp_req->request.status ? 0 : -EIO),
-				comp_req->sector_count * blkdev->sector_size)) {
-				/*
-				 * All the sectors have been xferred ie the
-				 * request is done
-				 */
-				DPRINT_DBG(BLKVSC_DRV, "req %p COMPLETED\n",
-					   comp_req->req);
-				kmem_cache_free(blkdev->request_pool,
-						comp_req->group);
-			}
-
-			kmem_cache_free(blkdev->request_pool, comp_req);
-		}
-
-		if (!blkdev->shutting_down) {
-			blkvsc_do_pending_reqs(blkdev);
-			blk_start_queue(blkdev->gd->queue);
-			blkvsc_request(blkdev->gd->queue);
-		}
-	}
-
-	spin_unlock_irqrestore(&blkdev->lock, flags);
-}
-
-static int blkvsc_cancel_pending_reqs(struct block_device_context *blkdev)
-{
-	struct blkvsc_request *pend_req, *tmp;
-	struct blkvsc_request *comp_req, *tmp2;
-
-	int ret = 0;
-
-	DPRINT_DBG(BLKVSC_DRV, "blkvsc_cancel_pending_reqs()");
-
-	/* Flush the pending list first */
-	list_for_each_entry_safe(pend_req, tmp, &blkdev->pending_list,
-				 pend_entry) {
-		/*
-		 * The pend_req could be part of a partially completed
-		 * request. If so, complete those req first until we
-		 * hit the pend_req
-		 */
-		list_for_each_entry_safe(comp_req, tmp2,
-					 &pend_req->group->blkvsc_req_list,
-					 req_entry) {
-			DPRINT_DBG(BLKVSC_DRV, "completing blkvsc_req %p "
-				   "sect_start %lu sect_count %ld\n",
-				   comp_req,
-				   (unsigned long) comp_req->sector_start,
-				   comp_req->sector_count);
-
-			if (comp_req == pend_req)
-				break;
-
-			list_del(&comp_req->req_entry);
-
-			if (comp_req->req) {
-				ret = __blk_end_request(comp_req->req,
-					(!comp_req->request.status ? 0 : -EIO),
-					comp_req->sector_count *
-					blkdev->sector_size);
-
-				/* FIXME: shouldn't this do more than return? */
-				if (ret)
-					goto out;
-			}
-
-			kmem_cache_free(blkdev->request_pool, comp_req);
-		}
-
-		DPRINT_DBG(BLKVSC_DRV, "cancelling pending request - %p\n",
-			   pend_req);
-
-		list_del(&pend_req->pend_entry);
-
-		list_del(&pend_req->req_entry);
-
-		if (comp_req->req) {
-			if (!__blk_end_request(pend_req->req, -EIO,
-					       pend_req->sector_count *
-					       blkdev->sector_size)) {
-				/*
-				 * All the sectors have been xferred ie the
-				 * request is done
-				 */
-				DPRINT_DBG(BLKVSC_DRV,
-					   "blkvsc_cancel_pending_reqs() - "
-					   "req %p COMPLETED\n", pend_req->req);
-				kmem_cache_free(blkdev->request_pool,
-						pend_req->group);
-			}
-		}
-
-		kmem_cache_free(blkdev->request_pool, pend_req);
-	}
-
-out:
-	return ret;
-}
-
 static int blkvsc_do_pending_reqs(struct block_device_context *blkdev)
 {
 	struct blkvsc_request *pend_req, *tmp;
@@ -1238,8 +748,6 @@
 	/* Flush the pending list first */
 	list_for_each_entry_safe(pend_req, tmp, &blkdev->pending_list,
 				 pend_entry) {
-		DPRINT_DBG(BLKVSC_DRV, "working off pending_list - %p\n",
-			   pend_req);
 
 		ret = blkvsc_submit_request(pend_req,
 					    blkvsc_request_completion);
@@ -1252,19 +760,17 @@
 	return ret;
 }
 
+
 static void blkvsc_request(struct request_queue *queue)
 {
 	struct block_device_context *blkdev = NULL;
 	struct request *req;
 	int ret = 0;
 
-	DPRINT_DBG(BLKVSC_DRV, "- enter\n");
 	while ((req = blk_peek_request(queue)) != NULL) {
-		DPRINT_DBG(BLKVSC_DRV, "- req %p\n", req);
 
 		blkdev = req->rq_disk->private_data;
-		if (blkdev->shutting_down || req->cmd_type != REQ_TYPE_FS ||
-		    blkdev->media_not_present) {
+		if (blkdev->shutting_down || req->cmd_type != REQ_TYPE_FS) {
 			__blk_end_request_cur(req, 0);
 			continue;
 		}
@@ -1272,8 +778,6 @@
 		ret = blkvsc_do_pending_reqs(blkdev);
 
 		if (ret != 0) {
-			DPRINT_DBG(BLKVSC_DRV,
-				   "- stop queue - pending_list not empty\n");
 			blk_stop_queue(queue);
 			break;
 		}
@@ -1282,11 +786,9 @@
 
 		ret = blkvsc_do_request(blkdev, req);
 		if (ret > 0) {
-			DPRINT_DBG(BLKVSC_DRV, "- stop queue - no room\n");
 			blk_stop_queue(queue);
 			break;
 		} else if (ret < 0) {
-			DPRINT_DBG(BLKVSC_DRV, "- stop queue - no mem\n");
 			blk_requeue_request(queue, req);
 			blk_stop_queue(queue);
 			break;
@@ -1294,191 +796,218 @@
 	}
 }
 
-static int blkvsc_open(struct block_device *bdev, fmode_t mode)
-{
-	struct block_device_context *blkdev = bdev->bd_disk->private_data;
-
-	DPRINT_DBG(BLKVSC_DRV, "- users %d disk %s\n", blkdev->users,
-		   blkdev->gd->disk_name);
-
-	mutex_lock(&blkvsc_mutex);
-	spin_lock(&blkdev->lock);
 
-	if (!blkdev->users && blkdev->device_type == DVD_TYPE) {
-		spin_unlock(&blkdev->lock);
-		check_disk_change(bdev);
-		spin_lock(&blkdev->lock);
-	}
 
-	blkdev->users++;
+/* The one and only one */
+static  struct hv_driver blkvsc_drv = {
+	.probe =  blkvsc_probe,
+	.remove =  blkvsc_remove,
+	.shutdown = blkvsc_shutdown,
+};
 
-	spin_unlock(&blkdev->lock);
-	mutex_unlock(&blkvsc_mutex);
-	return 0;
-}
+static const struct block_device_operations block_ops = {
+	.owner = THIS_MODULE,
+	.open = blkvsc_open,
+	.release = blkvsc_release,
+	.getgeo = blkvsc_getgeo,
+	.ioctl  = blkvsc_ioctl,
+};
 
-static int blkvsc_release(struct gendisk *disk, fmode_t mode)
+/*
+ * blkvsc_drv_init -  BlkVsc driver initialization.
+ */
+static int blkvsc_drv_init(void)
 {
-	struct block_device_context *blkdev = disk->private_data;
+	struct hv_driver *drv = &blkvsc_drv;
+	int ret;
 
-	DPRINT_DBG(BLKVSC_DRV, "- users %d disk %s\n", blkdev->users,
-		   blkdev->gd->disk_name);
+	BUILD_BUG_ON(sizeof(sector_t) != 8);
 
-	mutex_lock(&blkvsc_mutex);
-	spin_lock(&blkdev->lock);
-	if (blkdev->users == 1) {
-		spin_unlock(&blkdev->lock);
-		blkvsc_do_flush(blkdev);
-		spin_lock(&blkdev->lock);
-	}
+	memcpy(&drv->dev_type, &dev_type, sizeof(struct hv_guid));
+	drv->name = drv_name;
+	drv->driver.name = drv_name;
 
-	blkdev->users--;
+	/* The driver belongs to vmbus */
+	ret = vmbus_child_driver_register(&drv->driver);
 
-	spin_unlock(&blkdev->lock);
-	mutex_unlock(&blkvsc_mutex);
-	return 0;
+	return ret;
 }
 
-static unsigned int blkvsc_check_events(struct gendisk *gd,
-					unsigned int clearing)
+
+static void blkvsc_drv_exit(void)
 {
-	DPRINT_DBG(BLKVSC_DRV, "- enter\n");
-	return DISK_EVENT_MEDIA_CHANGE;
+
+	vmbus_child_driver_unregister(&blkvsc_drv.driver);
 }
 
-static int blkvsc_revalidate_disk(struct gendisk *gd)
+/*
+ * blkvsc_probe - Add a new device for this driver
+ */
+static int blkvsc_probe(struct hv_device *dev)
 {
-	struct block_device_context *blkdev = gd->private_data;
-
-	DPRINT_DBG(BLKVSC_DRV, "- enter\n");
+	struct block_device_context *blkdev = NULL;
+	struct storvsc_device_info device_info;
+	struct storvsc_major_info major_info;
+	int ret = 0;
 
-	if (blkdev->device_type == DVD_TYPE) {
-		blkvsc_do_read_capacity(blkdev);
-		set_capacity(blkdev->gd, blkdev->capacity *
-			    (blkdev->sector_size/512));
-		blk_queue_logical_block_size(gd->queue, blkdev->sector_size);
+	blkdev = kzalloc(sizeof(struct block_device_context), GFP_KERNEL);
+	if (!blkdev) {
+		ret = -ENOMEM;
+		goto cleanup;
 	}
-	return 0;
-}
 
-static int blkvsc_getgeo(struct block_device *bd, struct hd_geometry *hg)
-{
-	sector_t total_sectors = get_capacity(bd->bd_disk);
-	sector_t cylinder_times_heads = 0;
-	sector_t temp = 0;
+	INIT_LIST_HEAD(&blkdev->pending_list);
 
-	int sectors_per_track = 0;
-	int heads = 0;
-	int cylinders = 0;
-	int rem = 0;
+	/* Initialize what we can here */
+	spin_lock_init(&blkdev->lock);
 
-	if (total_sectors > (65535 * 16 * 255))
-		total_sectors = (65535 * 16 * 255);
 
-	if (total_sectors >= (65535 * 16 * 63)) {
-		sectors_per_track = 255;
-		heads = 16;
+	blkdev->request_pool = kmem_cache_create(dev_name(&dev->device),
+					sizeof(struct blkvsc_request), 0,
+					SLAB_HWCACHE_ALIGN, NULL);
+	if (!blkdev->request_pool) {
+		ret = -ENOMEM;
+		goto cleanup;
+	}
 
-		cylinder_times_heads = total_sectors;
-		/* sector_div stores the quotient in cylinder_times_heads */
-		rem = sector_div(cylinder_times_heads, sectors_per_track);
-	} else {
-		sectors_per_track = 17;
 
-		cylinder_times_heads = total_sectors;
-		/* sector_div stores the quotient in cylinder_times_heads */
-		rem = sector_div(cylinder_times_heads, sectors_per_track);
+	ret = blkvsc_device_add(dev, &device_info);
+	if (ret != 0)
+		goto cleanup;
 
-		temp = cylinder_times_heads + 1023;
-		/* sector_div stores the quotient in temp */
-		rem = sector_div(temp, 1024);
+	blkdev->device_ctx = dev;
+	/* this identified the device 0 or 1 */
+	blkdev->target = device_info.target_id;
+	/* this identified the ide ctrl 0 or 1 */
+	blkdev->path = device_info.path_id;
 
-		heads = temp;
+	dev_set_drvdata(&dev->device, blkdev);
 
-		if (heads < 4)
-			heads = 4;
+	ret = storvsc_get_major_info(&device_info, &major_info);
 
+	if (ret)
+		goto cleanup;
 
-		if (cylinder_times_heads >= (heads * 1024) || (heads > 16)) {
-			sectors_per_track = 31;
-			heads = 16;
+	if (major_info.do_register) {
+		ret = register_blkdev(major_info.major, major_info.devname);
 
-			cylinder_times_heads = total_sectors;
-			/*
-			 * sector_div stores the quotient in
-			 * cylinder_times_heads
-			 */
-			rem = sector_div(cylinder_times_heads,
-					 sectors_per_track);
+		if (ret != 0) {
+			DPRINT_ERR(BLKVSC_DRV,
+				   "register_blkdev() failed! ret %d", ret);
+			goto remove;
 		}
+	}
 
-		if (cylinder_times_heads >= (heads * 1024)) {
-			sectors_per_track = 63;
-			heads = 16;
+	DPRINT_INFO(BLKVSC_DRV, "blkvsc registered for major %d!!",
+			major_info.major);
 
-			cylinder_times_heads = total_sectors;
-			/*
-			 * sector_div stores the quotient in
-			 * cylinder_times_heads
-			 */
-			rem = sector_div(cylinder_times_heads,
-					 sectors_per_track);
-		}
+	blkdev->gd = alloc_disk(BLKVSC_MINORS);
+	if (!blkdev->gd) {
+		ret = -1;
+		goto cleanup;
 	}
 
-	temp = cylinder_times_heads;
-	/* sector_div stores the quotient in temp */
-	rem = sector_div(temp, heads);
-	cylinders = temp;
+	blkdev->gd->queue = blk_init_queue(blkvsc_request, &blkdev->lock);
 
-	hg->heads = heads;
-	hg->sectors = sectors_per_track;
-	hg->cylinders = cylinders;
+	blk_queue_max_segment_size(blkdev->gd->queue, PAGE_SIZE);
+	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);
 
-	DPRINT_INFO(BLKVSC_DRV, "CHS (%d, %d, %d)", cylinders, heads,
-		    sectors_per_track);
+	blkdev->gd->major = major_info.major;
+	if (major_info.index == 1 || major_info.index == 3)
+		blkdev->gd->first_minor = BLKVSC_MINORS;
+	else
+		blkdev->gd->first_minor = 0;
+	blkdev->gd->fops = &block_ops;
+	blkdev->gd->events = DISK_EVENT_MEDIA_CHANGE;
+	blkdev->gd->private_data = blkdev;
+	blkdev->gd->driverfs_dev = &(blkdev->device_ctx->device);
+	sprintf(blkdev->gd->disk_name, "hd%c", 'a' + major_info.index);
 
-    return 0;
-}
+	blkvsc_do_operation(blkdev, DO_INQUIRY);
+	blkvsc_do_operation(blkdev, DO_CAPACITY);
 
-static int blkvsc_ioctl(struct block_device *bd, fmode_t mode,
-			unsigned cmd, unsigned long argument)
-{
-/*	struct block_device_context *blkdev = bd->bd_disk->private_data; */
-	int ret;
+	set_capacity(blkdev->gd, blkdev->capacity * (blkdev->sector_size/512));
+	blk_queue_logical_block_size(blkdev->gd->queue, blkdev->sector_size);
+	/* go! */
+	add_disk(blkdev->gd);
 
-	switch (cmd) {
-	/*
-	 * TODO: I think there is certain format for HDIO_GET_IDENTITY rather
-	 * than just a GUID. Commented it out for now.
-	 */
-#if 0
-	case HDIO_GET_IDENTITY:
-		DPRINT_INFO(BLKVSC_DRV, "HDIO_GET_IDENTITY\n");
-		if (copy_to_user((void __user *)arg, blkdev->device_id,
-				 blkdev->device_id_len))
-			ret = -EFAULT;
-		break;
-#endif
-	default:
-		ret = -EINVAL;
-		break;
+	DPRINT_INFO(BLKVSC_DRV, "%s added!! capacity %lu sector_size %d",
+		    blkdev->gd->disk_name, (unsigned long)blkdev->capacity,
+		    blkdev->sector_size);
+
+	return ret;
+
+remove:
+	storvsc_dev_remove(dev);
+
+cleanup:
+	if (blkdev) {
+		if (blkdev->request_pool) {
+			kmem_cache_destroy(blkdev->request_pool);
+			blkdev->request_pool = NULL;
+		}
+		kfree(blkdev);
+		blkdev = NULL;
 	}
 
 	return ret;
 }
 
-static int __init blkvsc_init(void)
+static void blkvsc_request_completion(struct hv_storvsc_request *request)
 {
-	int ret;
+	struct blkvsc_request *blkvsc_req =
+			(struct blkvsc_request *)request->context;
+	struct block_device_context *blkdev =
+			(struct block_device_context *)blkvsc_req->dev;
+	unsigned long flags;
+	struct blkvsc_request *comp_req, *tmp;
+	struct vmscsi_request *vm_srb;
 
-	BUILD_BUG_ON(sizeof(sector_t) != 8);
 
-	DPRINT_INFO(BLKVSC_DRV, "Blkvsc initializing....");
+	spin_lock_irqsave(&blkdev->lock, flags);
 
-	ret = blkvsc_drv_init(blk_vsc_initialize);
+	blkdev->num_outstanding_reqs--;
+	blkvsc_req->group->outstanding--;
 
-	return ret;
+	/*
+	 * Only start processing when all the blkvsc_reqs are
+	 * completed. This guarantees no out-of-order blkvsc_req
+	 * completion when calling end_that_request_first()
+	 */
+	if (blkvsc_req->group->outstanding == 0) {
+		list_for_each_entry_safe(comp_req, tmp,
+					 &blkvsc_req->group->blkvsc_req_list,
+					 req_entry) {
+
+			list_del(&comp_req->req_entry);
+
+			vm_srb =
+			&comp_req->request.vstor_packet.vm_srb;
+			if (!__blk_end_request(comp_req->req,
+				(!vm_srb->scsi_status ? 0 : -EIO),
+				comp_req->sector_count * blkdev->sector_size)) {
+				/*
+				 * All the sectors have been xferred ie the
+				 * request is done
+				 */
+				kmem_cache_free(blkdev->request_pool,
+						comp_req->group);
+			}
+
+			kmem_cache_free(blkdev->request_pool, comp_req);
+		}
+
+		if (!blkdev->shutting_down) {
+			blkvsc_do_pending_reqs(blkdev);
+			blk_start_queue(blkdev->gd->queue);
+			blkvsc_request(blkdev->gd->queue);
+		}
+	}
+
+	spin_unlock_irqrestore(&blkdev->lock, flags);
 }
 
 static void __exit blkvsc_exit(void)
@@ -1489,5 +1018,5 @@
 MODULE_LICENSE("GPL");
 MODULE_VERSION(HV_DRV_VERSION);
 MODULE_DESCRIPTION("Microsoft Hyper-V virtual block driver");
-module_init(blkvsc_init);
+module_init(blkvsc_drv_init);
 module_exit(blkvsc_exit);
diff -druN linux-2.6.39-libre/drivers/staging/hv/channel.c linux-3.0-rc7-libre/drivers/staging/hv/channel.c
--- linux-2.6.39-libre/drivers/staging/hv/channel.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/hv/channel.c	2011-07-11 19:51:52.000000000 -0400
@@ -18,15 +18,17 @@
  *   Haiyang Zhang <haiyangz@microsoft.com>
  *   Hank Janssen  <hjanssen@microsoft.com>
  */
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/kernel.h>
 #include <linux/sched.h>
 #include <linux/wait.h>
 #include <linux/mm.h>
 #include <linux/slab.h>
 #include <linux/module.h>
-#include "hv_api.h"
-#include "logging.h"
-#include "vmbus_private.h"
+
+#include "hyperv.h"
+#include "hyperv_vmbus.h"
 
 #define NUM_PAGES_SPANNED(addr, len) \
 ((PAGE_ALIGN(addr + len) >> PAGE_SHIFT) - (addr >> PAGE_SHIFT))
@@ -40,37 +42,6 @@
 static void dump_vmbus_channel(struct vmbus_channel *channel);
 static void vmbus_setevent(struct vmbus_channel *channel);
 
-
-#if 0
-static void DumpMonitorPage(struct hv_monitor_page *MonitorPage)
-{
-	int i = 0;
-	int j = 0;
-
-	DPRINT_DBG(VMBUS, "monitorPage - %p, trigger state - %d",
-		   MonitorPage, MonitorPage->trigger_state);
-
-	for (i = 0; i < 4; i++)
-		DPRINT_DBG(VMBUS, "trigger group (%d) - %llx", i,
-			   MonitorPage->trigger_group[i].as_uint64);
-
-	for (i = 0; i < 4; i++) {
-		for (j = 0; j < 32; j++) {
-			DPRINT_DBG(VMBUS, "latency (%d)(%d) - %llx", i, j,
-				   MonitorPage->latency[i][j]);
-		}
-	}
-	for (i = 0; i < 4; i++) {
-		for (j = 0; j < 32; j++) {
-			DPRINT_DBG(VMBUS, "param-conn id (%d)(%d) - %d", i, j,
-			       MonitorPage->parameter[i][j].connectionid.asu32);
-			DPRINT_DBG(VMBUS, "param-flag (%d)(%d) - %d", i, j,
-				MonitorPage->parameter[i][j].flag_number);
-		}
-	}
-}
-#endif
-
 /*
  * vmbus_setevent- Trigger an event notification on the specified
  * channel.
@@ -97,28 +68,6 @@
 	}
 }
 
-#if 0
-static void VmbusChannelClearEvent(struct vmbus_channel *channel)
-{
-	struct hv_monitor_page *monitorPage;
-
-	if (Channel->offermsg.monitor_allocated) {
-		/* Each u32 represents 32 channels */
-		sync_clear_bit(Channel->offermsg.child_relid & 31,
-			  (unsigned long *)vmbus_connection.send_int_page +
-			  (Channel->offermsg.child_relid >> 5));
-
-		monitorPage = (struct hv_monitor_page *)
-			vmbus_connection.monitor_pages;
-		monitorPage++; /* Get the child to parent monitor page */
-
-		sync_clear_bit(Channel->monitor_bit,
-			  (unsigned long *)&monitorPage->trigger_group
-					[Channel->monitor_grp].Pending);
-	}
-}
-
-#endif
 /*
  * vmbus_get_debug_info -Retrieve various channel debug info
  */
@@ -160,8 +109,8 @@
 			monitorpage->parameter[monitor_group]
 					[monitor_offset].connectionid.u.id;
 
-	ringbuffer_get_debuginfo(&channel->inbound, &debuginfo->inbound);
-	ringbuffer_get_debuginfo(&channel->outbound, &debuginfo->outbound);
+	hv_ringbuffer_get_debuginfo(&channel->inbound, &debuginfo->inbound);
+	hv_ringbuffer_get_debuginfo(&channel->outbound, &debuginfo->outbound);
 }
 
 /*
@@ -175,11 +124,7 @@
 	struct vmbus_channel_msginfo *openInfo = NULL;
 	void *in, *out;
 	unsigned long flags;
-	int ret, err = 0;
-
-	/* Aligned to page size */
-	/* ASSERT(!(SendRingBufferSize & (PAGE_SIZE - 1))); */
-	/* ASSERT(!(RecvRingBufferSize & (PAGE_SIZE - 1))); */
+	int ret, t, err = 0;
 
 	newchannel->onchannel_callback = onchannelcallback;
 	newchannel->channel_callback_context = context;
@@ -191,7 +136,6 @@
 	if (!out)
 		return -ENOMEM;
 
-	/* ASSERT(((unsigned long)out & (PAGE_SIZE-1)) == 0); */
 
 	in = (void *)((unsigned long)out + send_ringbuffer_size);
 
@@ -199,13 +143,16 @@
 	newchannel->ringbuffer_pagecount = (send_ringbuffer_size +
 					   recv_ringbuffer_size) >> PAGE_SHIFT;
 
-	ret = ringbuffer_init(&newchannel->outbound, out, send_ringbuffer_size);
+	ret = hv_ringbuffer_init(
+		&newchannel->outbound, out, send_ringbuffer_size);
+
 	if (ret != 0) {
 		err = ret;
 		goto errorout;
 	}
 
-	ret = ringbuffer_init(&newchannel->inbound, in, recv_ringbuffer_size);
+	ret = hv_ringbuffer_init(
+		&newchannel->inbound, in, recv_ringbuffer_size);
 	if (ret != 0) {
 		err = ret;
 		goto errorout;
@@ -213,9 +160,6 @@
 
 
 	/* Establish the gpadl for the ring buffer */
-	DPRINT_DBG(VMBUS, "Establishing ring buffer's gpadl for channel %p...",
-		   newchannel);
-
 	newchannel->ringbuffer_gpadlhandle = 0;
 
 	ret = vmbus_establish_gpadl(newchannel,
@@ -229,16 +173,6 @@
 		goto errorout;
 	}
 
-	DPRINT_DBG(VMBUS, "channel %p <relid %d gpadl 0x%x send ring %p "
-		   "size %d recv ring %p size %d, downstreamoffset %d>",
-		   newchannel, newchannel->offermsg.child_relid,
-		   newchannel->ringbuffer_gpadlhandle,
-		   newchannel->outbound.ring_buffer,
-		   newchannel->outbound.ring_size,
-		   newchannel->inbound.ring_buffer,
-		   newchannel->inbound.ring_size,
-		   send_ringbuffer_size);
-
 	/* Create and init the channel open message */
 	openInfo = kmalloc(sizeof(*openInfo) +
 			   sizeof(struct vmbus_channel_open_channel),
@@ -248,7 +182,7 @@
 		goto errorout;
 	}
 
-	init_waitqueue_head(&openInfo->waitevent);
+	init_completion(&openInfo->waitevent);
 
 	openMsg = (struct vmbus_channel_open_channel *)openInfo->msg;
 	openMsg->header.msgtype = CHANNELMSG_OPENCHANNEL;
@@ -272,30 +206,21 @@
 		      &vmbus_connection.chn_msg_list);
 	spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags);
 
-	DPRINT_DBG(VMBUS, "Sending channel open msg...");
-
 	ret = vmbus_post_msg(openMsg,
 			       sizeof(struct vmbus_channel_open_channel));
-	if (ret != 0) {
-		DPRINT_ERR(VMBUS, "unable to open channel - %d", ret);
+
+	if (ret != 0)
 		goto Cleanup;
-	}
 
-	openInfo->wait_condition = 0;
-	wait_event_timeout(openInfo->waitevent,
-			openInfo->wait_condition,
-			msecs_to_jiffies(1000));
-	if (openInfo->wait_condition == 0) {
+	t = wait_for_completion_timeout(&openInfo->waitevent, HZ);
+	if (t == 0) {
 		err = -ETIMEDOUT;
 		goto errorout;
 	}
 
 
-	if (openInfo->response.open_result.status == 0)
-		DPRINT_INFO(VMBUS, "channel <%p> open success!!", newchannel);
-	else
-		DPRINT_INFO(VMBUS, "channel <%p> open failed - %d!!",
-			    newchannel, openInfo->response.open_result.status);
+	if (openInfo->response.open_result.status)
+		err = openInfo->response.open_result.status;
 
 Cleanup:
 	spin_lock_irqsave(&vmbus_connection.channelmsg_lock, flags);
@@ -303,11 +228,11 @@
 	spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags);
 
 	kfree(openInfo);
-	return 0;
+	return err;
 
 errorout:
-	ringbuffer_cleanup(&newchannel->outbound);
-	ringbuffer_cleanup(&newchannel->inbound);
+	hv_ringbuffer_cleanup(&newchannel->outbound);
+	hv_ringbuffer_cleanup(&newchannel->inbound);
 	free_pages((unsigned long)out,
 		get_order(send_ringbuffer_size + recv_ringbuffer_size));
 	kfree(openInfo);
@@ -326,6 +251,7 @@
 
 	pfncount = (len - sizeof(struct vmbus_channel_gpadl_body)) /
 		   sizeof(u64);
+
 	DPRINT_DBG(VMBUS, "gpadl body - len %d pfn count %d", len, pfncount);
 
 	for (i = 0; i < pfncount; i++)
@@ -377,9 +303,6 @@
 
 	int pfnsum, pfncount, pfnleft, pfncurr, pfnsize;
 
-	/* ASSERT((kbuffer & (PAGE_SIZE-1)) == 0); */
-	/* ASSERT((Size & (PAGE_SIZE-1)) == 0); */
-
 	pagecount = size >> PAGE_SHIFT;
 	pfn = virt_to_phys(kbuffer) >> PAGE_SHIFT;
 
@@ -508,6 +431,7 @@
 	u32 next_gpadl_handle;
 	unsigned long flags;
 	int ret = 0;
+	int t;
 
 	next_gpadl_handle = atomic_read(&vmbus_connection.next_gpadl_handle);
 	atomic_inc(&vmbus_connection.next_gpadl_handle);
@@ -516,7 +440,7 @@
 	if (ret)
 		return ret;
 
-	init_waitqueue_head(&msginfo->waitevent);
+	init_completion(&msginfo->waitevent);
 
 	gpadlmsg = (struct vmbus_channel_gpadl_header *)msginfo->msg;
 	gpadlmsg->header.msgtype = CHANNELMSG_GPADL_HEADER;
@@ -530,19 +454,11 @@
 		      &vmbus_connection.chn_msg_list);
 
 	spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags);
-	DPRINT_DBG(VMBUS, "buffer %p, size %d msg cnt %d",
-		   kbuffer, size, msgcount);
 
-	DPRINT_DBG(VMBUS, "Sending GPADL Header - len %zd",
-		   msginfo->msgsize - sizeof(*msginfo));
-
-	msginfo->wait_condition = 0;
 	ret = vmbus_post_msg(gpadlmsg, msginfo->msgsize -
 			       sizeof(*msginfo));
-	if (ret != 0) {
-		DPRINT_ERR(VMBUS, "Unable to open channel - %d", ret);
+	if (ret != 0)
 		goto Cleanup;
-	}
 
 	if (msgcount > 1) {
 		list_for_each(curr, &msginfo->submsglist) {
@@ -556,10 +472,6 @@
 				CHANNELMSG_GPADL_BODY;
 			gpadl_body->gpadl = next_gpadl_handle;
 
-			DPRINT_DBG(VMBUS, "Sending GPADL Body - len %zd",
-				   submsginfo->msgsize -
-				   sizeof(*submsginfo));
-
 			dump_gpadl_body(gpadl_body, submsginfo->msgsize -
 				      sizeof(*submsginfo));
 			ret = vmbus_post_msg(gpadl_body,
@@ -570,19 +482,11 @@
 
 		}
 	}
-	wait_event_timeout(msginfo->waitevent,
-				msginfo->wait_condition,
-				msecs_to_jiffies(1000));
-	BUG_ON(msginfo->wait_condition == 0);
+	t = wait_for_completion_timeout(&msginfo->waitevent, HZ);
+	BUG_ON(t == 0);
 
 
 	/* At this point, we received the gpadl created msg */
-	DPRINT_DBG(VMBUS, "Received GPADL created "
-		   "(relid %d, status %d handle %x)",
-		   channel->offermsg.child_relid,
-		   msginfo->response.gpadl_created.creation_status,
-		   gpadlmsg->gpadl);
-
 	*gpadl_handle = gpadlmsg->gpadl;
 
 Cleanup:
@@ -603,7 +507,7 @@
 	struct vmbus_channel_gpadl_teardown *msg;
 	struct vmbus_channel_msginfo *info;
 	unsigned long flags;
-	int ret;
+	int ret, t;
 
 	/* ASSERT(gpadl_handle != 0); */
 
@@ -612,7 +516,7 @@
 	if (!info)
 		return -ENOMEM;
 
-	init_waitqueue_head(&info->waitevent);
+	init_completion(&info->waitevent);
 
 	msg = (struct vmbus_channel_gpadl_teardown *)info->msg;
 
@@ -624,14 +528,12 @@
 	list_add_tail(&info->msglistentry,
 		      &vmbus_connection.chn_msg_list);
 	spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags);
-	info->wait_condition = 0;
 	ret = vmbus_post_msg(msg,
 			       sizeof(struct vmbus_channel_gpadl_teardown));
 
 	BUG_ON(ret != 0);
-	wait_event_timeout(info->waitevent,
-			info->wait_condition, msecs_to_jiffies(1000));
-	BUG_ON(info->wait_condition == 0);
+	t = wait_for_completion_timeout(&info->waitevent, HZ);
+	BUG_ON(t == 0);
 
 	/* Received a torndown response */
 	spin_lock_irqsave(&vmbus_connection.channelmsg_lock, flags);
@@ -681,8 +583,8 @@
 	/* TODO: Send a msg to release the childRelId */
 
 	/* Cleanup the ring buffers for this channel */
-	ringbuffer_cleanup(&channel->outbound);
-	ringbuffer_cleanup(&channel->inbound);
+	hv_ringbuffer_cleanup(&channel->outbound);
+	hv_ringbuffer_cleanup(&channel->inbound);
 
 	free_pages((unsigned long)channel->ringbuffer_pages,
 		get_order(channel->ringbuffer_pagecount * PAGE_SIZE));
@@ -730,13 +632,8 @@
 	u64 aligned_data = 0;
 	int ret;
 
-	DPRINT_DBG(VMBUS, "channel %p buffer %p len %d",
-		   channel, buffer, bufferlen);
-
 	dump_vmbus_channel(channel);
 
-	/* ASSERT((packetLenAligned - packetLen) < sizeof(u64)); */
-
 	/* Setup the descriptor */
 	desc.type = type; /* VmbusPacketTypeDataInBand; */
 	desc.flags = flags; /* VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED; */
@@ -751,10 +648,10 @@
 	sg_set_buf(&bufferlist[2], &aligned_data,
 		   packetlen_aligned - packetlen);
 
-	ret = ringbuffer_write(&channel->outbound, bufferlist, 3);
+	ret = hv_ringbuffer_write(&channel->outbound, bufferlist, 3);
 
 	/* TODO: We should determine if this is optional */
-	if (ret == 0 && !get_ringbuffer_interrupt_mask(&channel->outbound))
+	if (ret == 0 && !hv_get_ringbuffer_interrupt_mask(&channel->outbound))
 		vmbus_setevent(channel);
 
 	return ret;
@@ -794,8 +691,6 @@
 	packetlen = descsize + bufferlen;
 	packetlen_aligned = ALIGN(packetlen, sizeof(u64));
 
-	/* ASSERT((packetLenAligned - packetLen) < sizeof(u64)); */
-
 	/* Setup the descriptor */
 	desc.type = VM_PKT_DATA_USING_GPA_DIRECT;
 	desc.flags = VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED;
@@ -816,10 +711,10 @@
 	sg_set_buf(&bufferlist[2], &aligned_data,
 		packetlen_aligned - packetlen);
 
-	ret = ringbuffer_write(&channel->outbound, bufferlist, 3);
+	ret = hv_ringbuffer_write(&channel->outbound, bufferlist, 3);
 
 	/* TODO: We should determine if this is optional */
-	if (ret == 0 && !get_ringbuffer_interrupt_mask(&channel->outbound))
+	if (ret == 0 && !hv_get_ringbuffer_interrupt_mask(&channel->outbound))
 		vmbus_setevent(channel);
 
 	return ret;
@@ -846,10 +741,6 @@
 
 	dump_vmbus_channel(channel);
 
-	DPRINT_DBG(VMBUS, "data buffer - offset %u len %u pfn count %u",
-		multi_pagebuffer->offset,
-		multi_pagebuffer->len, pfncount);
-
 	if ((pfncount < 0) || (pfncount > MAX_MULTIPAGE_BUFFER_COUNT))
 		return -EINVAL;
 
@@ -863,7 +754,6 @@
 	packetlen = descsize + bufferlen;
 	packetlen_aligned = ALIGN(packetlen, sizeof(u64));
 
-	/* ASSERT((packetLenAligned - packetLen) < sizeof(u64)); */
 
 	/* Setup the descriptor */
 	desc.type = VM_PKT_DATA_USING_GPA_DIRECT;
@@ -885,10 +775,10 @@
 	sg_set_buf(&bufferlist[2], &aligned_data,
 		packetlen_aligned - packetlen);
 
-	ret = ringbuffer_write(&channel->outbound, bufferlist, 3);
+	ret = hv_ringbuffer_write(&channel->outbound, bufferlist, 3);
 
 	/* TODO: We should determine if this is optional */
-	if (ret == 0 && !get_ringbuffer_interrupt_mask(&channel->outbound))
+	if (ret == 0 && !hv_get_ringbuffer_interrupt_mask(&channel->outbound))
 		vmbus_setevent(channel);
 
 	return ret;
@@ -922,32 +812,22 @@
 
 	spin_lock_irqsave(&channel->inbound_lock, flags);
 
-	ret = ringbuffer_peek(&channel->inbound, &desc,
+	ret = hv_ringbuffer_peek(&channel->inbound, &desc,
 			     sizeof(struct vmpacket_descriptor));
 	if (ret != 0) {
 		spin_unlock_irqrestore(&channel->inbound_lock, flags);
-
-		/* DPRINT_DBG(VMBUS, "nothing to read!!"); */
 		return 0;
 	}
 
-	/* VmbusChannelClearEvent(Channel); */
-
 	packetlen = desc.len8 << 3;
 	userlen = packetlen - (desc.offset8 << 3);
-	/* ASSERT(userLen > 0); */
-
-	DPRINT_DBG(VMBUS, "packet received on channel %p relid %d <type %d "
-		   "flag %d tid %llx pktlen %d datalen %d> ",
-		   channel, channel->offermsg.child_relid, desc.type,
-		   desc.flags, desc.trans_id, packetlen, userlen);
 
 	*buffer_actual_len = userlen;
 
 	if (userlen > bufferlen) {
 		spin_unlock_irqrestore(&channel->inbound_lock, flags);
 
-		DPRINT_ERR(VMBUS, "buffer too small - got %d needs %d",
+		pr_err("Buffer too small - got %d needs %d\n",
 			   bufferlen, userlen);
 		return -1;
 	}
@@ -955,7 +835,7 @@
 	*requestid = desc.trans_id;
 
 	/* Copy over the packet to the user buffer */
-	ret = ringbuffer_read(&channel->inbound, buffer, userlen,
+	ret = hv_ringbuffer_read(&channel->inbound, buffer, userlen,
 			     (desc.offset8 << 3));
 
 	spin_unlock_irqrestore(&channel->inbound_lock, flags);
@@ -982,39 +862,32 @@
 
 	spin_lock_irqsave(&channel->inbound_lock, flags);
 
-	ret = ringbuffer_peek(&channel->inbound, &desc,
+	ret = hv_ringbuffer_peek(&channel->inbound, &desc,
 			     sizeof(struct vmpacket_descriptor));
 	if (ret != 0) {
 		spin_unlock_irqrestore(&channel->inbound_lock, flags);
-
-		/* DPRINT_DBG(VMBUS, "nothing to read!!"); */
 		return 0;
 	}
 
-	/* VmbusChannelClearEvent(Channel); */
 
 	packetlen = desc.len8 << 3;
 	userlen = packetlen - (desc.offset8 << 3);
 
-	DPRINT_DBG(VMBUS, "packet received on channel %p relid %d <type %d "
-		   "flag %d tid %llx pktlen %d datalen %d> ",
-		   channel, channel->offermsg.child_relid, desc.type,
-		   desc.flags, desc.trans_id, packetlen, userlen);
-
 	*buffer_actual_len = packetlen;
 
 	if (packetlen > bufferlen) {
 		spin_unlock_irqrestore(&channel->inbound_lock, flags);
 
-		DPRINT_ERR(VMBUS, "buffer too small - needed %d bytes but "
-			   "got space for only %d bytes", packetlen, bufferlen);
+		pr_err("Buffer too small - needed %d bytes but "
+			"got space for only %d bytes\n",
+			packetlen, bufferlen);
 		return -2;
 	}
 
 	*requestid = desc.trans_id;
 
 	/* Copy over the entire packet to the user buffer */
-	ret = ringbuffer_read(&channel->inbound, buffer, packetlen, 0);
+	ret = hv_ringbuffer_read(&channel->inbound, buffer, packetlen, 0);
 
 	spin_unlock_irqrestore(&channel->inbound_lock, flags);
 	return 0;
@@ -1027,7 +900,6 @@
 void vmbus_onchannel_event(struct vmbus_channel *channel)
 {
 	dump_vmbus_channel(channel);
-	/* ASSERT(Channel->OnChannelCallback); */
 
 	channel->onchannel_callback(channel->channel_callback_context);
 
@@ -1051,6 +923,6 @@
 static void dump_vmbus_channel(struct vmbus_channel *channel)
 {
 	DPRINT_DBG(VMBUS, "Channel (%d)", channel->offermsg.child_relid);
-	dump_ring_info(&channel->outbound, "Outbound ");
-	dump_ring_info(&channel->inbound, "Inbound ");
+	hv_dump_ring_info(&channel->outbound, "Outbound ");
+	hv_dump_ring_info(&channel->inbound, "Inbound ");
 }
diff -druN linux-2.6.39-libre/drivers/staging/hv/channel.h linux-3.0-rc7-libre/drivers/staging/hv/channel.h
--- linux-2.6.39-libre/drivers/staging/hv/channel.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/hv/channel.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,112 +0,0 @@
-/*
- *
- * Copyright (c) 2009, Microsoft 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., 59 Temple
- * Place - Suite 330, Boston, MA 02111-1307 USA.
- *
- * Authors:
- *   Haiyang Zhang <haiyangz@microsoft.com>
- *   Hank Janssen  <hjanssen@microsoft.com>
- *
- */
-
-
-#ifndef _CHANNEL_H_
-#define _CHANNEL_H_
-
-#include "channel_mgmt.h"
-
-/* The format must be the same as struct vmdata_gpa_direct */
-struct vmbus_channel_packet_page_buffer {
-	u16 type;
-	u16 dataoffset8;
-	u16 length8;
-	u16 flags;
-	u64 transactionid;
-	u32 reserved;
-	u32 rangecount;
-	struct hv_page_buffer range[MAX_PAGE_BUFFER_COUNT];
-} __packed;
-
-/* The format must be the same as struct vmdata_gpa_direct */
-struct vmbus_channel_packet_multipage_buffer {
-	u16 type;
-	u16 dataoffset8;
-	u16 length8;
-	u16 flags;
-	u64 transactionid;
-	u32 reserved;
-	u32 rangecount;		/* Always 1 in this case */
-	struct hv_multipage_buffer range;
-} __packed;
-
-
-extern int vmbus_open(struct vmbus_channel *channel,
-			    u32 send_ringbuffersize,
-			    u32 recv_ringbuffersize,
-			    void *userdata,
-			    u32 userdatalen,
-			    void(*onchannel_callback)(void *context),
-			    void *context);
-
-extern void vmbus_close(struct vmbus_channel *channel);
-
-extern int vmbus_sendpacket(struct vmbus_channel *channel,
-				  const void *buffer,
-				  u32 bufferLen,
-				  u64 requestid,
-				  enum vmbus_packet_type type,
-				  u32 flags);
-
-extern int vmbus_sendpacket_pagebuffer(struct vmbus_channel *channel,
-					    struct hv_page_buffer pagebuffers[],
-					    u32 pagecount,
-					    void *buffer,
-					    u32 bufferlen,
-					    u64 requestid);
-
-extern int vmbus_sendpacket_multipagebuffer(struct vmbus_channel *channel,
-					struct hv_multipage_buffer *mpb,
-					void *buffer,
-					u32 bufferlen,
-					u64 requestid);
-
-extern int vmbus_establish_gpadl(struct vmbus_channel *channel,
-				      void *kbuffer,
-				      u32 size,
-				      u32 *gpadl_handle);
-
-extern int vmbus_teardown_gpadl(struct vmbus_channel *channel,
-				     u32 gpadl_handle);
-
-extern int vmbus_recvpacket(struct vmbus_channel *channel,
-				  void *buffer,
-				  u32 bufferlen,
-				  u32 *buffer_actual_len,
-				  u64 *requestid);
-
-extern int vmbus_recvpacket_raw(struct vmbus_channel *channel,
-				     void *buffer,
-				     u32 bufferlen,
-				     u32 *buffer_actual_len,
-				     u64 *requestid);
-
-extern void vmbus_onchannel_event(struct vmbus_channel *channel);
-
-extern void vmbus_get_debug_info(struct vmbus_channel *channel,
-				     struct vmbus_channel_debug_info *debug);
-
-extern void vmbus_ontimer(unsigned long data);
-
-#endif /* _CHANNEL_H_ */
diff -druN linux-2.6.39-libre/drivers/staging/hv/channel_mgmt.c linux-3.0-rc7-libre/drivers/staging/hv/channel_mgmt.c
--- linux-2.6.39-libre/drivers/staging/hv/channel_mgmt.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/hv/channel_mgmt.c	2011-07-11 19:51:52.000000000 -0400
@@ -18,6 +18,8 @@
  *   Haiyang Zhang <haiyangz@microsoft.com>
  *   Hank Janssen  <hjanssen@microsoft.com>
  */
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/kernel.h>
 #include <linux/sched.h>
 #include <linux/wait.h>
@@ -26,21 +28,20 @@
 #include <linux/list.h>
 #include <linux/module.h>
 #include <linux/completion.h>
-#include "hv_api.h"
-#include "logging.h"
-#include "vmbus_private.h"
-#include "utils.h"
+
+#include "hyperv.h"
+#include "hyperv_vmbus.h"
 
 struct vmbus_channel_message_table_entry {
-	enum vmbus_channel_message_type messageType;
-	void (*messageHandler)(struct vmbus_channel_message_header *msg);
+	enum vmbus_channel_message_type message_type;
+	void (*message_handler)(struct vmbus_channel_message_header *msg);
 };
 
 #define MAX_MSG_TYPES                    4
 #define MAX_NUM_DEVICE_CLASSES_SUPPORTED 8
 
 static const struct hv_guid
-	gSupportedDeviceClasses[MAX_NUM_DEVICE_CLASSES_SUPPORTED] = {
+	supported_device_classes[MAX_NUM_DEVICE_CLASSES_SUPPORTED] = {
 	/* {ba6163d9-04a1-4d29-b605-72e2ffb1dc7f} */
 	/* Storage - SCSI */
 	{
@@ -180,6 +181,24 @@
 	struct icmsg_hdr *icmsghdrp;
 	struct icmsg_negotiate *negop = NULL;
 
+	if (channel->util_index >= 0) {
+		/*
+		 * This is a properly initialized util channel.
+		 * Route this callback appropriately and setup state
+		 * so that we don't need to reroute again.
+		 */
+		if (hv_cb_utils[channel->util_index].callback != NULL) {
+			/*
+			 * The util driver has established a handler for
+			 * this service; do the magic.
+			 */
+			channel->onchannel_callback =
+			hv_cb_utils[channel->util_index].callback;
+			(hv_cb_utils[channel->util_index].callback)(channel);
+			return;
+		}
+	}
+
 	buflen = PAGE_SIZE;
 	buf = kmalloc(buflen, GFP_ATOMIC);
 
@@ -216,7 +235,6 @@
 			0x31, 0x60, 0x0B, 0X0E, 0x13, 0x52, 0x34, 0x49,
 			0x81, 0x8B, 0x38, 0XD9, 0x0C, 0xED, 0x39, 0xDB
 		},
-		.callback = chn_cb_negotiate,
 		.log_msg = "Shutdown channel functionality initialized"
 	},
 
@@ -228,7 +246,6 @@
 			0x30, 0xe6, 0x27, 0x95, 0xae, 0xd0, 0x7b, 0x49,
 			0xad, 0xce, 0xe8, 0x0a, 0xb0, 0x17, 0x5c, 0xaf
 		},
-		.callback = chn_cb_negotiate,
 		.log_msg = "Timesync channel functionality initialized"
 	},
 	/* {57164f39-9115-4e78-ab55-382f3bd5422d} */
@@ -239,7 +256,6 @@
 			0x39, 0x4f, 0x16, 0x57, 0x15, 0x91, 0x78, 0x4e,
 			0xab, 0x55, 0x38, 0x2f, 0x3b, 0xd5, 0x42, 0x2d
 		},
-		.callback = chn_cb_negotiate,
 		.log_msg = "Heartbeat channel functionality initialized"
 	},
 	/* {A9A0F4E7-5A45-4d96-B827-8A841E8C03E6} */
@@ -249,7 +265,6 @@
 			0xe7, 0xf4, 0xa0, 0xa9, 0x45, 0x5a, 0x96, 0x4d,
 			0xb8, 0x27, 0x8a, 0x84, 0x1e, 0x8c, 0x3,  0xe6
 		},
-		.callback = chn_cb_negotiate,
 		.log_msg = "KVP channel functionality initialized"
 	},
 };
@@ -290,9 +305,7 @@
 						     struct vmbus_channel,
 						     work);
 
-	DPRINT_DBG(VMBUS, "releasing channel (%p)", channel);
 	destroy_workqueue(channel->controlwq);
-	DPRINT_DBG(VMBUS, "channel released (%p)", channel);
 
 	kfree(channel);
 }
@@ -314,22 +327,6 @@
 }
 
 
-DECLARE_COMPLETION(hv_channel_ready);
-
-/*
- * Count initialized channels, and ensure all channels are ready when hv_vmbus
- * module loading completes.
- */
-static void count_hv_channel(void)
-{
-	static int counter;
-	unsigned long flags;
-
-	spin_lock_irqsave(&vmbus_connection.channel_lock, flags);
-	if (++counter == MAX_MSG_TYPES)
-		complete(&hv_channel_ready);
-	spin_unlock_irqrestore(&vmbus_connection.channel_lock, flags);
-}
 
 /*
  * vmbus_process_rescind_offer -
@@ -384,8 +381,6 @@
 	spin_unlock_irqrestore(&vmbus_connection.channel_lock, flags);
 
 	if (!fnew) {
-		DPRINT_DBG(VMBUS, "Ignoring duplicate offer for relid (%d)",
-			   newchannel->offermsg.child_relid);
 		free_channel(newchannel);
 		return;
 	}
@@ -400,9 +395,6 @@
 		&newchannel->offermsg.offer.if_instance,
 		newchannel);
 
-	DPRINT_DBG(VMBUS, "child device object allocated - %p",
-		   newchannel->device_obj);
-
 	/*
 	 * Add the new device to the bus. This will kick off device-driver
 	 * binding which eventually invokes the device driver's AddDevice()
@@ -410,8 +402,7 @@
 	 */
 	ret = vmbus_child_device_register(newchannel->device_obj);
 	if (ret != 0) {
-		DPRINT_ERR(VMBUS,
-			   "unable to add child device object (relid %d)",
+		pr_err("unable to add child device object (relid %d)\n",
 			   newchannel->offermsg.child_relid);
 
 		spin_lock_irqsave(&vmbus_connection.channel_lock, flags);
@@ -426,6 +417,7 @@
 		 * can cleanup properly
 		 */
 		newchannel->state = CHANNEL_OPEN_STATE;
+		newchannel->util_index = -1; /* Invalid index */
 
 		/* Open IC channels */
 		for (cnt = 0; cnt < MAX_MSG_TYPES; cnt++) {
@@ -434,12 +426,13 @@
 				   sizeof(struct hv_guid)) == 0 &&
 				vmbus_open(newchannel, 2 * PAGE_SIZE,
 						 2 * PAGE_SIZE, NULL, 0,
-						 hv_cb_utils[cnt].callback,
+						 chn_cb_negotiate,
 						 newchannel) == 0) {
 				hv_cb_utils[cnt].channel = newchannel;
-				DPRINT_INFO(VMBUS, "%s",
-						hv_cb_utils[cnt].log_msg);
-				count_hv_channel();
+				newchannel->util_index = cnt;
+
+				pr_info("%s\n", hv_cb_utils[cnt].log_msg);
+
 			}
 		}
 	}
@@ -464,55 +457,26 @@
 	offer = (struct vmbus_channel_offer_channel *)hdr;
 	for (i = 0; i < MAX_NUM_DEVICE_CLASSES_SUPPORTED; i++) {
 		if (memcmp(&offer->offer.if_type,
-		    &gSupportedDeviceClasses[i], sizeof(struct hv_guid)) == 0) {
+			&supported_device_classes[i],
+			sizeof(struct hv_guid)) == 0) {
 			fsupported = 1;
 			break;
 		}
 	}
 
-	if (!fsupported) {
-		DPRINT_DBG(VMBUS, "Ignoring channel offer notification for "
-			   "child relid %d", offer->child_relid);
+	if (!fsupported)
 		return;
-	}
 
 	guidtype = &offer->offer.if_type;
 	guidinstance = &offer->offer.if_instance;
 
-	DPRINT_INFO(VMBUS, "Channel offer notification - "
-		    "child relid %d monitor id %d allocated %d, "
-		    "type {%02x%02x%02x%02x-%02x%02x-%02x%02x-"
-		    "%02x%02x%02x%02x%02x%02x%02x%02x} "
-		    "instance {%02x%02x%02x%02x-%02x%02x-%02x%02x-"
-		    "%02x%02x%02x%02x%02x%02x%02x%02x}",
-		    offer->child_relid, offer->monitorid,
-		    offer->monitor_allocated,
-		    guidtype->data[3], guidtype->data[2],
-		    guidtype->data[1], guidtype->data[0],
-		    guidtype->data[5], guidtype->data[4],
-		    guidtype->data[7], guidtype->data[6],
-		    guidtype->data[8], guidtype->data[9],
-		    guidtype->data[10], guidtype->data[11],
-		    guidtype->data[12], guidtype->data[13],
-		    guidtype->data[14], guidtype->data[15],
-		    guidinstance->data[3], guidinstance->data[2],
-		    guidinstance->data[1], guidinstance->data[0],
-		    guidinstance->data[5], guidinstance->data[4],
-		    guidinstance->data[7], guidinstance->data[6],
-		    guidinstance->data[8], guidinstance->data[9],
-		    guidinstance->data[10], guidinstance->data[11],
-		    guidinstance->data[12], guidinstance->data[13],
-		    guidinstance->data[14], guidinstance->data[15]);
-
 	/* Allocate the channel object and save this offer. */
 	newchannel = alloc_channel();
 	if (!newchannel) {
-		DPRINT_ERR(VMBUS, "unable to allocate channel object");
+		pr_err("Unable to allocate channel object\n");
 		return;
 	}
 
-	DPRINT_DBG(VMBUS, "channel object allocated - %p", newchannel);
-
 	memcpy(&newchannel->offermsg, offer,
 	       sizeof(struct vmbus_channel_offer_channel));
 	newchannel->monitor_grp = (u8)offer->monitorid / 32;
@@ -535,11 +499,10 @@
 
 	rescind = (struct vmbus_channel_rescind_offer *)hdr;
 	channel = relid2channel(rescind->child_relid);
-	if (channel == NULL) {
-		DPRINT_DBG(VMBUS, "channel not found for relId %d",
-			   rescind->child_relid);
+
+	if (channel == NULL)
+		/* Just return here, no channel found */
 		return;
-	}
 
 	/* work is initialized for vmbus_process_rescind_offer() from
 	 * vmbus_process_offer() where the channel got created */
@@ -573,7 +536,6 @@
 	unsigned long flags;
 
 	result = (struct vmbus_channel_open_result *)hdr;
-	DPRINT_DBG(VMBUS, "vmbus open result - %d", result->status);
 
 	/*
 	 * Find the open msg, copy the result and signal/unblock the wait event
@@ -592,9 +554,9 @@
 			    openmsg->openid == result->openid) {
 				memcpy(&msginfo->response.open_result,
 				       result,
-				       sizeof(struct vmbus_channel_open_result));
-				msginfo->wait_condition = 1;
-				wake_up(&msginfo->waitevent);
+				       sizeof(
+					struct vmbus_channel_open_result));
+				complete(&msginfo->waitevent);
 				break;
 			}
 		}
@@ -618,8 +580,6 @@
 	unsigned long flags;
 
 	gpadlcreated = (struct vmbus_channel_gpadl_created *)hdr;
-	DPRINT_DBG(VMBUS, "vmbus gpadl created result - %d",
-		   gpadlcreated->creation_status);
 
 	/*
 	 * Find the establish msg, copy the result and signal/unblock the wait
@@ -641,9 +601,9 @@
 			    (gpadlcreated->gpadl == gpadlheader->gpadl)) {
 				memcpy(&msginfo->response.gpadl_created,
 				       gpadlcreated,
-				       sizeof(struct vmbus_channel_gpadl_created));
-				msginfo->wait_condition = 1;
-				wake_up(&msginfo->waitevent);
+				       sizeof(
+					struct vmbus_channel_gpadl_created));
+				complete(&msginfo->waitevent);
 				break;
 			}
 		}
@@ -686,9 +646,9 @@
 			if (gpadl_torndown->gpadl == gpadl_teardown->gpadl) {
 				memcpy(&msginfo->response.gpadl_torndown,
 				       gpadl_torndown,
-				       sizeof(struct vmbus_channel_gpadl_torndown));
-				msginfo->wait_condition = 1;
-				wake_up(&msginfo->waitevent);
+				       sizeof(
+					struct vmbus_channel_gpadl_torndown));
+				complete(&msginfo->waitevent);
 				break;
 			}
 		}
@@ -727,8 +687,7 @@
 			memcpy(&msginfo->response.version_response,
 			      version_response,
 			      sizeof(struct vmbus_channel_version_response));
-			msginfo->wait_condition = 1;
-			wake_up(&msginfo->waitevent);
+			complete(&msginfo->waitevent);
 		}
 	}
 	spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags);
@@ -736,7 +695,7 @@
 
 /* Channel message dispatch table */
 static struct vmbus_channel_message_table_entry
-	gChannelMessageTable[CHANNELMSG_COUNT] = {
+	channel_message_table[CHANNELMSG_COUNT] = {
 	{CHANNELMSG_INVALID,			NULL},
 	{CHANNELMSG_OFFERCHANNEL,		vmbus_onoffer},
 	{CHANNELMSG_RESCIND_CHANNELOFFER,	vmbus_onoffer_rescind},
@@ -770,22 +729,18 @@
 	hdr = (struct vmbus_channel_message_header *)msg->u.payload;
 	size = msg->header.payload_size;
 
-	DPRINT_DBG(VMBUS, "message type %d size %d", hdr->msgtype, size);
-
 	if (hdr->msgtype >= CHANNELMSG_COUNT) {
-		DPRINT_ERR(VMBUS,
-			   "Received invalid channel message type %d size %d",
+		pr_err("Received invalid channel message type %d size %d\n",
 			   hdr->msgtype, size);
 		print_hex_dump_bytes("", DUMP_PREFIX_NONE,
 				     (unsigned char *)msg->u.payload, size);
 		return;
 	}
 
-	if (gChannelMessageTable[hdr->msgtype].messageHandler)
-		gChannelMessageTable[hdr->msgtype].messageHandler(hdr);
+	if (channel_message_table[hdr->msgtype].message_handler)
+		channel_message_table[hdr->msgtype].message_handler(hdr);
 	else
-		DPRINT_ERR(VMBUS, "Unhandled channel message type %d",
-			   hdr->msgtype);
+		pr_err("Unhandled channel message type %d\n", hdr->msgtype);
 }
 
 /*
@@ -795,7 +750,7 @@
 {
 	struct vmbus_channel_message_header *msg;
 	struct vmbus_channel_msginfo *msginfo;
-	int ret;
+	int ret, t;
 
 	msginfo = kmalloc(sizeof(*msginfo) +
 			  sizeof(struct vmbus_channel_message_header),
@@ -803,7 +758,7 @@
 	if (!msginfo)
 		return -ENOMEM;
 
-	init_waitqueue_head(&msginfo->waitevent);
+	init_completion(&msginfo->waitevent);
 
 	msg = (struct vmbus_channel_message_header *)msginfo->msg;
 
@@ -813,15 +768,13 @@
 	ret = vmbus_post_msg(msg,
 			       sizeof(struct vmbus_channel_message_header));
 	if (ret != 0) {
-		DPRINT_ERR(VMBUS, "Unable to request offers - %d", ret);
+		pr_err("Unable to request offers - %d\n", ret);
 
 		goto cleanup;
 	}
 
-	msginfo->wait_condition = 0;
-	wait_event_timeout(msginfo->waitevent, msginfo->wait_condition,
-			msecs_to_jiffies(1000));
-	if (msginfo->wait_condition == 0) {
+	t = wait_for_completion_timeout(&msginfo->waitevent, HZ);
+	if (t == 0) {
 		ret = -ETIMEDOUT;
 		goto cleanup;
 	}
@@ -834,38 +787,4 @@
 	return ret;
 }
 
-/*
- * vmbus_release_unattached_channels - Release channels that are
- * unattached/unconnected ie (no drivers associated)
- */
-void vmbus_release_unattached_channels(void)
-{
-	struct vmbus_channel *channel, *pos;
-	struct vmbus_channel *start = NULL;
-	unsigned long flags;
-
-	spin_lock_irqsave(&vmbus_connection.channel_lock, flags);
-
-	list_for_each_entry_safe(channel, pos, &vmbus_connection.chn_list,
-				 listentry) {
-		if (channel == start)
-			break;
-
-		if (!channel->device_obj->drv) {
-			list_del(&channel->listentry);
-			DPRINT_INFO(VMBUS,
-				    "Releasing unattached device object %p",
-				    channel->device_obj);
-
-			vmbus_child_device_unregister(channel->device_obj);
-			free_channel(channel);
-		} else {
-			if (!start)
-				start = channel;
-		}
-	}
-
-	spin_unlock_irqrestore(&vmbus_connection.channel_lock, flags);
-}
-
 /* eof */
diff -druN linux-2.6.39-libre/drivers/staging/hv/channel_mgmt.h linux-3.0-rc7-libre/drivers/staging/hv/channel_mgmt.h
--- linux-2.6.39-libre/drivers/staging/hv/channel_mgmt.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/hv/channel_mgmt.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,320 +0,0 @@
-/*
- *
- * Copyright (c) 2009, Microsoft 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., 59 Temple
- * Place - Suite 330, Boston, MA 02111-1307 USA.
- *
- * Authors:
- *   Haiyang Zhang <haiyangz@microsoft.com>
- *   Hank Janssen  <hjanssen@microsoft.com>
- *
- */
-
-
-#ifndef _CHANNEL_MGMT_H_
-#define _CHANNEL_MGMT_H_
-
-#include <linux/list.h>
-#include <linux/timer.h>
-#include <linux/workqueue.h>
-#include "ring_buffer.h"
-#include "vmbus_channel_interface.h"
-#include "vmbus_packet_format.h"
-
-/* Version 1 messages */
-enum vmbus_channel_message_type {
-	CHANNELMSG_INVALID			=  0,
-	CHANNELMSG_OFFERCHANNEL		=  1,
-	CHANNELMSG_RESCIND_CHANNELOFFER	=  2,
-	CHANNELMSG_REQUESTOFFERS		=  3,
-	CHANNELMSG_ALLOFFERS_DELIVERED	=  4,
-	CHANNELMSG_OPENCHANNEL		=  5,
-	CHANNELMSG_OPENCHANNEL_RESULT		=  6,
-	CHANNELMSG_CLOSECHANNEL		=  7,
-	CHANNELMSG_GPADL_HEADER		=  8,
-	CHANNELMSG_GPADL_BODY			=  9,
-	CHANNELMSG_GPADL_CREATED		= 10,
-	CHANNELMSG_GPADL_TEARDOWN		= 11,
-	CHANNELMSG_GPADL_TORNDOWN		= 12,
-	CHANNELMSG_RELID_RELEASED		= 13,
-	CHANNELMSG_INITIATE_CONTACT		= 14,
-	CHANNELMSG_VERSION_RESPONSE		= 15,
-	CHANNELMSG_UNLOAD			= 16,
-#ifdef VMBUS_FEATURE_PARENT_OR_PEER_MEMORY_MAPPED_INTO_A_CHILD
-	CHANNELMSG_VIEWRANGE_ADD		= 17,
-	CHANNELMSG_VIEWRANGE_REMOVE		= 18,
-#endif
-	CHANNELMSG_COUNT
-};
-
-struct vmbus_channel_message_header {
-	enum vmbus_channel_message_type msgtype;
-	u32 padding;
-} __packed;
-
-/* Query VMBus Version parameters */
-struct vmbus_channel_query_vmbus_version {
-	struct vmbus_channel_message_header header;
-	u32 version;
-} __packed;
-
-/* VMBus Version Supported parameters */
-struct vmbus_channel_version_supported {
-	struct vmbus_channel_message_header header;
-	bool version_supported;
-} __packed;
-
-/* Offer Channel parameters */
-struct vmbus_channel_offer_channel {
-	struct vmbus_channel_message_header header;
-	struct vmbus_channel_offer offer;
-	u32 child_relid;
-	u8 monitorid;
-	bool monitor_allocated;
-} __packed;
-
-/* Rescind Offer parameters */
-struct vmbus_channel_rescind_offer {
-	struct vmbus_channel_message_header header;
-	u32 child_relid;
-} __packed;
-
-/*
- * Request Offer -- no parameters, SynIC message contains the partition ID
- * Set Snoop -- no parameters, SynIC message contains the partition ID
- * Clear Snoop -- no parameters, SynIC message contains the partition ID
- * All Offers Delivered -- no parameters, SynIC message contains the partition
- *		           ID
- * Flush Client -- no parameters, SynIC message contains the partition ID
- */
-
-/* Open Channel parameters */
-struct vmbus_channel_open_channel {
-	struct vmbus_channel_message_header header;
-
-	/* Identifies the specific VMBus channel that is being opened. */
-	u32 child_relid;
-
-	/* ID making a particular open request at a channel offer unique. */
-	u32 openid;
-
-	/* GPADL for the channel's ring buffer. */
-	u32 ringbuffer_gpadlhandle;
-
-	/* GPADL for the channel's server context save area. */
-	u32 server_contextarea_gpadlhandle;
-
-	/*
-	* The upstream ring buffer begins at offset zero in the memory
-	* described by RingBufferGpadlHandle. The downstream ring buffer
-	* follows it at this offset (in pages).
-	*/
-	u32 downstream_ringbuffer_pageoffset;
-
-	/* User-specific data to be passed along to the server endpoint. */
-	unsigned char userdata[MAX_USER_DEFINED_BYTES];
-} __packed;
-
-/* Open Channel Result parameters */
-struct vmbus_channel_open_result {
-	struct vmbus_channel_message_header header;
-	u32 child_relid;
-	u32 openid;
-	u32 status;
-} __packed;
-
-/* Close channel parameters; */
-struct vmbus_channel_close_channel {
-	struct vmbus_channel_message_header header;
-	u32 child_relid;
-} __packed;
-
-/* Channel Message GPADL */
-#define GPADL_TYPE_RING_BUFFER		1
-#define GPADL_TYPE_SERVER_SAVE_AREA	2
-#define GPADL_TYPE_TRANSACTION		8
-
-/*
- * The number of PFNs in a GPADL message is defined by the number of
- * pages that would be spanned by ByteCount and ByteOffset.  If the
- * implied number of PFNs won't fit in this packet, there will be a
- * follow-up packet that contains more.
- */
-struct vmbus_channel_gpadl_header {
-	struct vmbus_channel_message_header header;
-	u32 child_relid;
-	u32 gpadl;
-	u16 range_buflen;
-	u16 rangecount;
-	struct gpa_range range[0];
-} __packed;
-
-/* This is the followup packet that contains more PFNs. */
-struct vmbus_channel_gpadl_body {
-	struct vmbus_channel_message_header header;
-	u32 msgnumber;
-	u32 gpadl;
-	u64 pfn[0];
-} __packed;
-
-struct vmbus_channel_gpadl_created {
-	struct vmbus_channel_message_header header;
-	u32 child_relid;
-	u32 gpadl;
-	u32 creation_status;
-} __packed;
-
-struct vmbus_channel_gpadl_teardown {
-	struct vmbus_channel_message_header header;
-	u32 child_relid;
-	u32 gpadl;
-} __packed;
-
-struct vmbus_channel_gpadl_torndown {
-	struct vmbus_channel_message_header header;
-	u32 gpadl;
-} __packed;
-
-#ifdef VMBUS_FEATURE_PARENT_OR_PEER_MEMORY_MAPPED_INTO_A_CHILD
-struct vmbus_channel_view_range_add {
-	struct vmbus_channel_message_header header;
-	PHYSICAL_ADDRESS viewrange_base;
-	u64 viewrange_length;
-	u32 child_relid;
-} __packed;
-
-struct vmbus_channel_view_range_remove {
-	struct vmbus_channel_message_header header;
-	PHYSICAL_ADDRESS viewrange_base;
-	u32 child_relid;
-} __packed;
-#endif
-
-struct vmbus_channel_relid_released {
-	struct vmbus_channel_message_header header;
-	u32 child_relid;
-} __packed;
-
-struct vmbus_channel_initiate_contact {
-	struct vmbus_channel_message_header header;
-	u32 vmbus_version_requested;
-	u32 padding2;
-	u64 interrupt_page;
-	u64 monitor_page1;
-	u64 monitor_page2;
-} __packed;
-
-struct vmbus_channel_version_response {
-	struct vmbus_channel_message_header header;
-	bool version_supported;
-} __packed;
-
-enum vmbus_channel_state {
-	CHANNEL_OFFER_STATE,
-	CHANNEL_OPENING_STATE,
-	CHANNEL_OPEN_STATE,
-};
-
-struct vmbus_channel {
-	struct list_head listentry;
-
-	struct hv_device *device_obj;
-
-	struct timer_list poll_timer; /* SA-111 workaround */
-	struct work_struct work;
-
-	enum vmbus_channel_state state;
-
-	struct vmbus_channel_offer_channel offermsg;
-	/*
-	 * These are based on the OfferMsg.MonitorId.
-	 * Save it here for easy access.
-	 */
-	u8 monitor_grp;
-	u8 monitor_bit;
-
-	u32 ringbuffer_gpadlhandle;
-
-	/* Allocated memory for ring buffer */
-	void *ringbuffer_pages;
-	u32 ringbuffer_pagecount;
-	struct hv_ring_buffer_info outbound;	/* send to parent */
-	struct hv_ring_buffer_info inbound;	/* receive from parent */
-	spinlock_t inbound_lock;
-	struct workqueue_struct *controlwq;
-
-	/* Channel callback are invoked in this workqueue context */
-	/* HANDLE dataWorkQueue; */
-
-	void (*onchannel_callback)(void *context);
-	void *channel_callback_context;
-};
-
-struct vmbus_channel_debug_info {
-	u32 relid;
-	enum vmbus_channel_state state;
-	struct hv_guid interfacetype;
-	struct hv_guid interface_instance;
-	u32 monitorid;
-	u32 servermonitor_pending;
-	u32 servermonitor_latency;
-	u32 servermonitor_connectionid;
-	u32 clientmonitor_pending;
-	u32 clientmonitor_latency;
-	u32 clientmonitor_connectionid;
-
-	struct hv_ring_buffer_debug_info inbound;
-	struct hv_ring_buffer_debug_info outbound;
-};
-
-/*
- * Represents each channel msg on the vmbus connection This is a
- * variable-size data structure depending on the msg type itself
- */
-struct vmbus_channel_msginfo {
-	/* Bookkeeping stuff */
-	struct list_head msglistentry;
-
-	/* So far, this is only used to handle gpadl body message */
-	struct list_head submsglist;
-
-	/* Synchronize the request/response if needed */
-	int wait_condition;
-	wait_queue_head_t waitevent;
-	union {
-		struct vmbus_channel_version_supported version_supported;
-		struct vmbus_channel_open_result open_result;
-		struct vmbus_channel_gpadl_torndown gpadl_torndown;
-		struct vmbus_channel_gpadl_created gpadl_created;
-		struct vmbus_channel_version_response version_response;
-	} response;
-
-	u32 msgsize;
-	/*
-	 * The channel message that goes out on the "wire".
-	 * It will contain at minimum the VMBUS_CHANNEL_MESSAGE_HEADER header
-	 */
-	unsigned char msg[0];
-};
-
-
-void free_channel(struct vmbus_channel *channel);
-
-void vmbus_onmessage(void *context);
-
-int vmbus_request_offers(void);
-
-void vmbus_release_unattached_channels(void);
-
-#endif /* _CHANNEL_MGMT_H_ */
diff -druN linux-2.6.39-libre/drivers/staging/hv/connection.c linux-3.0-rc7-libre/drivers/staging/hv/connection.c
--- linux-2.6.39-libre/drivers/staging/hv/connection.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/hv/connection.c	2011-07-11 19:51:52.000000000 -0400
@@ -20,15 +20,17 @@
  *   Hank Janssen  <hjanssen@microsoft.com>
  *
  */
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/kernel.h>
 #include <linux/sched.h>
 #include <linux/wait.h>
 #include <linux/mm.h>
 #include <linux/slab.h>
 #include <linux/vmalloc.h>
-#include "hv_api.h"
-#include "logging.h"
-#include "vmbus_private.h"
+
+#include "hyperv.h"
+#include "hyperv_vmbus.h"
 
 
 struct vmbus_connection vmbus_connection = {
@@ -42,6 +44,7 @@
 int vmbus_connect(void)
 {
 	int ret = 0;
+	int t;
 	struct vmbus_channel_msginfo *msginfo = NULL;
 	struct vmbus_channel_initiate_contact *msg;
 	unsigned long flags;
@@ -55,7 +58,7 @@
 	vmbus_connection.work_queue = create_workqueue("hv_vmbus_con");
 	if (!vmbus_connection.work_queue) {
 		ret = -1;
-		goto Cleanup;
+		goto cleanup;
 	}
 
 	INIT_LIST_HEAD(&vmbus_connection.chn_msg_list);
@@ -72,7 +75,7 @@
 	(void *)__get_free_pages(GFP_KERNEL|__GFP_ZERO, 0);
 	if (vmbus_connection.int_page == NULL) {
 		ret = -1;
-		goto Cleanup;
+		goto cleanup;
 	}
 
 	vmbus_connection.recv_int_page = vmbus_connection.int_page;
@@ -88,7 +91,7 @@
 	(void *)__get_free_pages((GFP_KERNEL|__GFP_ZERO), 1);
 	if (vmbus_connection.monitor_pages == NULL) {
 		ret = -1;
-		goto Cleanup;
+		goto cleanup;
 	}
 
 	msginfo = kzalloc(sizeof(*msginfo) +
@@ -96,10 +99,10 @@
 			  GFP_KERNEL);
 	if (msginfo == NULL) {
 		ret = -ENOMEM;
-		goto Cleanup;
+		goto cleanup;
 	}
 
-	init_waitqueue_head(&msginfo->waitevent);
+	init_completion(&msginfo->waitevent);
 
 	msg = (struct vmbus_channel_initiate_contact *)msginfo->msg;
 
@@ -121,11 +124,6 @@
 
 	spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags);
 
-	DPRINT_DBG(VMBUS, "Vmbus connection - interrupt pfn %llx, "
-		   "monitor1 pfn %llx,, monitor2 pfn %llx",
-		   msg->interrupt_page, msg->monitor_page1, msg->monitor_page2);
-
-	DPRINT_DBG(VMBUS, "Sending channel initiate msg...");
 	ret = vmbus_post_msg(msg,
 			       sizeof(struct vmbus_channel_initiate_contact));
 	if (ret != 0) {
@@ -133,21 +131,19 @@
 		list_del(&msginfo->msglistentry);
 		spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock,
 					flags);
-		goto Cleanup;
+		goto cleanup;
 	}
 
 	/* Wait for the connection response */
-	msginfo->wait_condition = 0;
-	wait_event_timeout(msginfo->waitevent, msginfo->wait_condition,
-			msecs_to_jiffies(1000));
-	if (msginfo->wait_condition == 0) {
+	t =  wait_for_completion_timeout(&msginfo->waitevent, HZ);
+	if (t == 0) {
 		spin_lock_irqsave(&vmbus_connection.channelmsg_lock,
 				flags);
 		list_del(&msginfo->msglistentry);
 		spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock,
 					flags);
 		ret = -ETIMEDOUT;
-		goto Cleanup;
+		goto cleanup;
 	}
 
 	spin_lock_irqsave(&vmbus_connection.channelmsg_lock, flags);
@@ -156,21 +152,19 @@
 
 	/* Check if successful */
 	if (msginfo->response.version_response.version_supported) {
-		DPRINT_INFO(VMBUS, "Vmbus connected!!");
 		vmbus_connection.conn_state = CONNECTED;
-
 	} else {
-		DPRINT_ERR(VMBUS, "Vmbus connection failed!!..."
-			   "current version (%d) not supported",
-			   VMBUS_REVISION_NUMBER);
+		pr_err("Unable to connect, "
+			"Version %d not supported by Hyper-V\n",
+			VMBUS_REVISION_NUMBER);
 		ret = -1;
-		goto Cleanup;
+		goto cleanup;
 	}
 
 	kfree(msginfo);
 	return 0;
 
-Cleanup:
+cleanup:
 	vmbus_connection.conn_state = DISCONNECTED;
 
 	if (vmbus_connection.work_queue)
@@ -213,7 +207,7 @@
 	ret = vmbus_post_msg(msg,
 			       sizeof(struct vmbus_channel_message_header));
 	if (ret != 0)
-		goto Cleanup;
+		goto cleanup;
 
 	free_pages((unsigned long)vmbus_connection.int_page, 0);
 	free_pages((unsigned long)vmbus_connection.monitor_pages, 1);
@@ -223,9 +217,9 @@
 
 	vmbus_connection.conn_state = DISCONNECTED;
 
-	DPRINT_INFO(VMBUS, "Vmbus disconnected!!");
+	pr_info("hv_vmbus disconnected\n");
 
-Cleanup:
+cleanup:
 	kfree(msg);
 	return ret;
 }
@@ -255,10 +249,9 @@
 /*
  * process_chn_event - Process a channel event notification
  */
-static void process_chn_event(void *context)
+static void process_chn_event(u32 relid)
 {
 	struct vmbus_channel *channel;
-	u32 relid = (u32)(unsigned long)context;
 
 	/* ASSERT(relId > 0); */
 
@@ -270,13 +263,8 @@
 
 	if (channel) {
 		vmbus_onchannel_event(channel);
-		/*
-		 * WorkQueueQueueWorkItem(channel->dataWorkQueue,
-		 *			  vmbus_onchannel_event,
-		 *			  (void*)channel);
-		 */
 	} else {
-		DPRINT_ERR(VMBUS, "channel not found for relid - %d.", relid);
+		pr_err("channel not found for relid - %u\n", relid);
 	}
 }
 
@@ -285,39 +273,33 @@
  */
 void vmbus_on_event(unsigned long data)
 {
-	int dword;
-	int maxdword = MAX_NUM_CHANNELS_SUPPORTED >> 5;
+	u32 dword;
+	u32 maxdword = MAX_NUM_CHANNELS_SUPPORTED >> 5;
 	int bit;
-	int relid;
+	u32 relid;
 	u32 *recv_int_page = vmbus_connection.recv_int_page;
 
 	/* Check events */
-	if (recv_int_page) {
-		for (dword = 0; dword < maxdword; dword++) {
-			if (recv_int_page[dword]) {
-				for (bit = 0; bit < 32; bit++) {
-					if (sync_test_and_clear_bit(bit,
-						(unsigned long *)
-						&recv_int_page[dword])) {
-						relid = (dword << 5) + bit;
-						DPRINT_DBG(VMBUS, "event detected for relid - %d", relid);
+	if (!recv_int_page)
+		return;
+	for (dword = 0; dword < maxdword; dword++) {
+		if (!recv_int_page[dword])
+			continue;
+		for (bit = 0; bit < 32; bit++) {
+			if (sync_test_and_clear_bit(bit, (unsigned long *)&recv_int_page[dword])) {
+				relid = (dword << 5) + bit;
 
-						if (relid == 0) {
-							/* special case - vmbus channel protocol msg */
-							DPRINT_DBG(VMBUS, "invalid relid - %d", relid);
-							continue;
-						} else {
-							/* QueueWorkItem(VmbusProcessEvent, (void*)relid); */
-							/* ret = WorkQueueQueueWorkItem(gVmbusConnection.workQueue, VmbusProcessChannelEvent, (void*)relid); */
-						process_chn_event((void *)
-						(unsigned long)relid);
-						}
-					}
+				if (relid == 0) {
+					/*
+					 * Special case - vmbus
+					 * channel protocol msg
+					 */
+					continue;
 				}
+				process_chn_event(relid);
 			}
-		 }
+		}
 	}
-	return;
 }
 
 /*
diff -druN linux-2.6.39-libre/drivers/staging/hv/hv_api.h linux-3.0-rc7-libre/drivers/staging/hv/hv_api.h
--- linux-2.6.39-libre/drivers/staging/hv/hv_api.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/hv/hv_api.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,910 +0,0 @@
-/*
- *
- * Copyright (c) 2009, Microsoft 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., 59 Temple
- * Place - Suite 330, Boston, MA 02111-1307 USA.
- *
- * Authors:
- *   Haiyang Zhang <haiyangz@microsoft.com>
- *   Hank Janssen  <hjanssen@microsoft.com>
- *
- */
-#ifndef __HV_API_H
-#define __HV_API_H
-
-struct hv_guid {
-	unsigned char data[16];
-};
-
-
-
-/* Status codes for hypervisor operations. */
-
-/*
- * HV_STATUS_SUCCESS
- * The specified hypercall succeeded
- */
-#define HV_STATUS_SUCCESS				((u16)0x0000)
-
-/*
- * HV_STATUS_INVALID_HYPERCALL_CODE
- * The hypervisor does not support the operation because the specified
- * hypercall code is not supported.
- */
-#define HV_STATUS_INVALID_HYPERCALL_CODE		((u16)0x0002)
-
-/*
- * HV_STATUS_INVALID_HYPERCALL_INPUT
- * The hypervisor does not support the operation because the encoding for the
- * hypercall input register is not supported.
- */
-#define HV_STATUS_INVALID_HYPERCALL_INPUT		((u16)0x0003)
-
-/*
- * HV_STATUS_INVALID_ALIGNMENT
- * The hypervisor could not perform the operation because a parameter has an
- * invalid alignment.
- */
-#define HV_STATUS_INVALID_ALIGNMENT			((u16)0x0004)
-
-/*
- * HV_STATUS_INVALID_PARAMETER
- * The hypervisor could not perform the operation because an invalid parameter
- * was specified.
- */
-#define HV_STATUS_INVALID_PARAMETER			((u16)0x0005)
-
-/*
- * HV_STATUS_ACCESS_DENIED
- * Access to the specified object was denied.
- */
-#define HV_STATUS_ACCESS_DENIED				((u16)0x0006)
-
-/*
- * HV_STATUS_INVALID_PARTITION_STATE
- * The hypervisor could not perform the operation because the partition is
- * entering or in an invalid state.
- */
-#define HV_STATUS_INVALID_PARTITION_STATE		((u16)0x0007)
-
-/*
- * HV_STATUS_OPERATION_DENIED
- * The operation is not allowed in the current state.
- */
-#define HV_STATUS_OPERATION_DENIED			((u16)0x0008)
-
-/*
- * HV_STATUS_UNKNOWN_PROPERTY
- * The hypervisor does not recognize the specified partition property.
- */
-#define HV_STATUS_UNKNOWN_PROPERTY			((u16)0x0009)
-
-/*
- * HV_STATUS_PROPERTY_VALUE_OUT_OF_RANGE
- * The specified value of a partition property is out of range or violates an
- * invariant.
- */
-#define HV_STATUS_PROPERTY_VALUE_OUT_OF_RANGE		((u16)0x000A)
-
-/*
- * HV_STATUS_INSUFFICIENT_MEMORY
- * There is not enough memory in the hypervisor pool to complete the operation.
- */
-#define HV_STATUS_INSUFFICIENT_MEMORY			((u16)0x000B)
-
-/*
- * HV_STATUS_PARTITION_TOO_DEEP
- * The maximum partition depth has been exceeded for the partition hierarchy.
- */
-#define HV_STATUS_PARTITION_TOO_DEEP			((u16)0x000C)
-
-/*
- * HV_STATUS_INVALID_PARTITION_ID
- * A partition with the specified partition Id does not exist.
- */
-#define HV_STATUS_INVALID_PARTITION_ID			((u16)0x000D)
-
-/*
- * HV_STATUS_INVALID_VP_INDEX
- * The hypervisor could not perform the operation because the specified VP
- * index is invalid.
- */
-#define HV_STATUS_INVALID_VP_INDEX			((u16)0x000E)
-
-/*
- * HV_STATUS_NOT_FOUND
- * The iteration is complete; no addition items in the iteration could be
- * found.
- */
-#define HV_STATUS_NOT_FOUND				((u16)0x0010)
-
-/*
- * HV_STATUS_INVALID_PORT_ID
- * The hypervisor could not perform the operation because the specified port
- * identifier is invalid.
- */
-#define HV_STATUS_INVALID_PORT_ID			((u16)0x0011)
-
-/*
- * HV_STATUS_INVALID_CONNECTION_ID
- * The hypervisor could not perform the operation because the specified
- * connection identifier is invalid.
- */
-#define HV_STATUS_INVALID_CONNECTION_ID			((u16)0x0012)
-
-/*
- * HV_STATUS_INSUFFICIENT_BUFFERS
- * You did not supply enough message buffers to send a message.
- */
-#define HV_STATUS_INSUFFICIENT_BUFFERS			((u16)0x0013)
-
-/*
- * HV_STATUS_NOT_ACKNOWLEDGED
- * The previous virtual interrupt has not been acknowledged.
- */
-#define HV_STATUS_NOT_ACKNOWLEDGED			((u16)0x0014)
-
-/*
- * HV_STATUS_INVALID_VP_STATE
- * A virtual processor is not in the correct state for the performance of the
- * indicated operation.
- */
-#define HV_STATUS_INVALID_VP_STATE			((u16)0x0015)
-
-/*
- * HV_STATUS_ACKNOWLEDGED
- * The previous virtual interrupt has already been acknowledged.
- */
-#define HV_STATUS_ACKNOWLEDGED				((u16)0x0016)
-
-/*
- * HV_STATUS_INVALID_SAVE_RESTORE_STATE
- * The indicated partition is not in a valid state for saving or restoring.
- */
-#define HV_STATUS_INVALID_SAVE_RESTORE_STATE		((u16)0x0017)
-
-/*
- * HV_STATUS_INVALID_SYNIC_STATE
- * The hypervisor could not complete the operation because a required feature
- * of the synthetic interrupt controller (SynIC) was disabled.
- */
-#define HV_STATUS_INVALID_SYNIC_STATE			((u16)0x0018)
-
-/*
- * HV_STATUS_OBJECT_IN_USE
- * The hypervisor could not perform the operation because the object or value
- * was either already in use or being used for a purpose that would not permit
- * completing the operation.
- */
-#define HV_STATUS_OBJECT_IN_USE				((u16)0x0019)
-
-/*
- * HV_STATUS_INVALID_PROXIMITY_DOMAIN_INFO
- * The proximity domain information is invalid.
- */
-#define HV_STATUS_INVALID_PROXIMITY_DOMAIN_INFO		((u16)0x001A)
-
-/*
- * HV_STATUS_NO_DATA
- * An attempt to retrieve debugging data failed because none was available.
- */
-#define HV_STATUS_NO_DATA				((u16)0x001B)
-
-/*
- * HV_STATUS_INACTIVE
- * The physical connection being used for debuggging has not recorded any
- * receive activity since the last operation.
- */
-#define HV_STATUS_INACTIVE				((u16)0x001C)
-
-/*
- * HV_STATUS_NO_RESOURCES
- * There are not enough resources to complete the operation.
- */
-#define HV_STATUS_NO_RESOURCES				((u16)0x001D)
-
-/*
- * HV_STATUS_FEATURE_UNAVAILABLE
- * A hypervisor feature is not available to the user.
- */
-#define HV_STATUS_FEATURE_UNAVAILABLE			((u16)0x001E)
-
-/*
- * HV_STATUS_UNSUCCESSFUL
- * {Operation Failed} The requested operation was unsuccessful.
- */
-#define HV_STATUS_UNSUCCESSFUL				((u16)0x1001)
-
-/*
- * HV_STATUS_INSUFFICIENT_BUFFER
- * The specified buffer was too small to contain all of the requested data.
- */
-#define HV_STATUS_INSUFFICIENT_BUFFER			((u16)0x1002)
-
-/*
- * HV_STATUS_GPA_NOT_PRESENT
- * The guest physical address is not currently associated with a system
- * physical address.
- */
-#define HV_STATUS_GPA_NOT_PRESENT			((u16)0x1003)
-
-/*
- * HV_STATUS_GUEST_PAGE_FAULT
- * The operation would have resulted in a page fault in the guest.
- */
-#define HV_STATUS_GUEST_PAGE_FAULT			((u16)0x1004)
-
-/*
- * HV_STATUS_RUNDOWN_DISABLED
- * The operation cannot proceed as the rundown object was marked disabled.
- */
-#define HV_STATUS_RUNDOWN_DISABLED			((u16)0x1005)
-
-/*
- * HV_STATUS_KEY_ALREADY_EXISTS
- * The entry cannot be added as another entry with the same key already exists.
- */
-#define HV_STATUS_KEY_ALREADY_EXISTS			((u16)0x1006)
-
-/*
- * HV_STATUS_GPA_INTERCEPT
- * The operation resulted an intercept on a region of guest physical memory.
- */
-#define HV_STATUS_GPA_INTERCEPT				((u16)0x1007)
-
-/*
- * HV_STATUS_GUEST_GENERAL_PROTECTION_FAULT
- * The operation would have resulted in a general protection fault in the
- * guest.
- */
-#define HV_STATUS_GUEST_GENERAL_PROTECTION_FAULT	((u16)0x1008)
-
-/*
- * HV_STATUS_GUEST_STACK_FAULT
- * The operation would have resulted in a stack fault in the guest.
- */
-#define HV_STATUS_GUEST_STACK_FAULT			((u16)0x1009)
-
-/*
- * HV_STATUS_GUEST_INVALID_OPCODE_FAULT
- * The operation would have resulted in an invalid opcode fault in the guest.
- */
-#define HV_STATUS_GUEST_INVALID_OPCODE_FAULT		((u16)0x100A)
-
-/*
- * HV_STATUS_FINALIZE_INCOMPLETE
- * The partition is not completely finalized.
- */
-#define HV_STATUS_FINALIZE_INCOMPLETE			((u16)0x100B)
-
-/*
- * HV_STATUS_GUEST_MACHINE_CHECK_ABORT
- * The operation would have resulted in an machine check abort in the guest.
- */
-#define HV_STATUS_GUEST_MACHINE_CHECK_ABORT		((u16)0x100C)
-
-/*
- * HV_STATUS_ILLEGAL_OVERLAY_ACCESS
- * An illegal access was attempted to an overlay page.
- */
-#define HV_STATUS_ILLEGAL_OVERLAY_ACCESS		((u16)0x100D)
-
-/*
- * HV_STATUS_INSUFFICIENT_SYSTEM_VA
- * There is not enough system VA space available to satisfy the request,
- */
-#define HV_STATUS_INSUFFICIENT_SYSTEM_VA		((u16)0x100E)
-
-/*
- * HV_STATUS_VIRTUAL_ADDRESS_NOT_MAPPED
- * The passed virtual address was not mapped in the hypervisor address space.
- */
-#define HV_STATUS_VIRTUAL_ADDRESS_NOT_MAPPED		((u16)0x100F)
-
-/*
- * HV_STATUS_NOT_IMPLEMENTED
- * The requested operation is not implemented in this version of the
- * hypervisor.
- */
-#define HV_STATUS_NOT_IMPLEMENTED			((u16)0x1010)
-
-/*
- * HV_STATUS_VMX_INSTRUCTION_FAILED
- * The requested VMX instruction failed to complete successfully.
- */
-#define HV_STATUS_VMX_INSTRUCTION_FAILED		((u16)0x1011)
-
-/*
- * HV_STATUS_VMX_INSTRUCTION_FAILED_WITH_STATUS
- * The requested VMX instruction failed to complete successfully indicating
- * status.
- */
-#define HV_STATUS_VMX_INSTRUCTION_FAILED_WITH_STATUS	((u16)0x1012)
-
-/*
- * HV_STATUS_MSR_ACCESS_FAILED
- * The requested access to the model specific register failed.
- */
-#define HV_STATUS_MSR_ACCESS_FAILED		((u16)0x1013)
-
-/*
- * HV_STATUS_CR_ACCESS_FAILED
- * The requested access to the control register failed.
- */
-#define HV_STATUS_CR_ACCESS_FAILED		((u16)0x1014)
-
-/*
- * HV_STATUS_TIMEOUT
- * The specified timeout expired before the operation completed.
- */
-#define HV_STATUS_TIMEOUT			((u16)0x1016)
-
-/*
- * HV_STATUS_MSR_INTERCEPT
- * The requested access to the model specific register generated an intercept.
- */
-#define HV_STATUS_MSR_INTERCEPT			((u16)0x1017)
-
-/*
- * HV_STATUS_CPUID_INTERCEPT
- * The CPUID instruction generated an intercept.
- */
-#define HV_STATUS_CPUID_INTERCEPT		((u16)0x1018)
-
-/*
- * HV_STATUS_REPEAT_INSTRUCTION
- * The current instruction should be repeated and the instruction pointer not
- * advanced.
- */
-#define HV_STATUS_REPEAT_INSTRUCTION		((u16)0x1019)
-
-/*
- * HV_STATUS_PAGE_PROTECTION_VIOLATION
- * The current instruction should be repeated and the instruction pointer not
- * advanced.
- */
-#define HV_STATUS_PAGE_PROTECTION_VIOLATION	((u16)0x101A)
-
-/*
- * HV_STATUS_PAGE_TABLE_INVALID
- * The current instruction should be repeated and the instruction pointer not
- * advanced.
- */
-#define HV_STATUS_PAGE_TABLE_INVALID		((u16)0x101B)
-
-/*
- * HV_STATUS_PAGE_NOT_PRESENT
- * The current instruction should be repeated and the instruction pointer not
- * advanced.
- */
-#define HV_STATUS_PAGE_NOT_PRESENT		((u16)0x101C)
-
-/*
- * HV_STATUS_IO_INTERCEPT
- * The requested access to the I/O port generated an intercept.
- */
-#define HV_STATUS_IO_INTERCEPT				((u16)0x101D)
-
-/*
- * HV_STATUS_NOTHING_TO_DO
- * There is nothing to do.
- */
-#define HV_STATUS_NOTHING_TO_DO				((u16)0x101E)
-
-/*
- * HV_STATUS_THREAD_TERMINATING
- * The requested thread is terminating.
- */
-#define HV_STATUS_THREAD_TERMINATING			((u16)0x101F)
-
-/*
- * HV_STATUS_SECTION_ALREADY_CONSTRUCTED
- * The specified section was already constructed.
- */
-#define HV_STATUS_SECTION_ALREADY_CONSTRUCTED		((u16)0x1020)
-
-/* HV_STATUS_SECTION_NOT_ALREADY_CONSTRUCTED
- * The specified section was not already constructed.
- */
-#define HV_STATUS_SECTION_NOT_ALREADY_CONSTRUCTED	((u16)0x1021)
-
-/*
- * HV_STATUS_PAGE_ALREADY_COMMITTED
- * The specified virtual address was already backed by physical memory.
- */
-#define HV_STATUS_PAGE_ALREADY_COMMITTED		((u16)0x1022)
-
-/*
- * HV_STATUS_PAGE_NOT_ALREADY_COMMITTED
- * The specified virtual address was not already backed by physical memory.
- */
-#define HV_STATUS_PAGE_NOT_ALREADY_COMMITTED		((u16)0x1023)
-
-/*
- * HV_STATUS_COMMITTED_PAGES_REMAIN
- * Committed pages remain in the section.
- */
-#define HV_STATUS_COMMITTED_PAGES_REMAIN		((u16)0x1024)
-
-/*
- * HV_STATUS_NO_REMAINING_COMMITTED_PAGES
- * No additional committed pages beyond the specified page exist in the
- * section.
- */
-#define HV_STATUS_NO_REMAINING_COMMITTED_PAGES		((u16)0x1025)
-
-/*
- * HV_STATUS_INSUFFICIENT_COMPARTMENT_VA
- * The VA space of the compartment is exhausted.
- */
-#define HV_STATUS_INSUFFICIENT_COMPARTMENT_VA		((u16)0x1026)
-
-/*
- * HV_STATUS_DEREF_SPA_LIST_FULL
- * The SPA dereference list is full, and there are additional entries to be
- * added to it.
- */
-#define HV_STATUS_DEREF_SPA_LIST_FULL			((u16)0x1027)
-
-/*
- * HV_STATUS_GPA_OUT_OF_RANGE
- * The supplied GPA is out of range.
- */
-#define HV_STATUS_GPA_OUT_OF_RANGE			((u16)0x1027)
-
-/*
- * HV_STATUS_NONVOLATILE_XMM_STALE
- * The XMM register that was being accessed is stale.
- */
-#define HV_STATUS_NONVOLATILE_XMM_STALE			((u16)0x1028)
-
-/* HV_STATUS_UNSUPPORTED_PROCESSOR
- * The hypervisor does not support the processors in this system.
- */
-#define HV_STATUS_UNSUPPORTED_PROCESSOR			((u16)0x1029)
-
-/*
- * HV_STATUS_INSUFFICIENT_CROM_SPACE
- * Insufficient space existed for copying over the CROM contents.
- */
-#define HV_STATUS_INSUFFICIENT_CROM_SPACE		((u16)0x2000)
-
-/*
- * HV_STATUS_BAD_CROM_FORMAT
- * The contents of the CROM failed validation attempts.
- */
-#define HV_STATUS_BAD_CROM_FORMAT			((u16)0x2001)
-
-/*
- * HV_STATUS_UNSUPPORTED_CROM_FORMAT
- * The contents of the CROM contain contents the parser doesn't support.
- */
-#define HV_STATUS_UNSUPPORTED_CROM_FORMAT		((u16)0x2002)
-
-/*
- * HV_STATUS_UNSUPPORTED_CONTROLLER
- * The register format of the OHCI controller specified for debugging is not
- * supported.
- */
-#define HV_STATUS_UNSUPPORTED_CONTROLLER		((u16)0x2003)
-
-/*
- * HV_STATUS_CROM_TOO_LARGE
- * The CROM contents were to large to copy over.
- */
-#define HV_STATUS_CROM_TOO_LARGE			((u16)0x2004)
-
-/*
- * HV_STATUS_CONTROLLER_IN_USE
- * The OHCI controller specified for debugging cannot be used as it is already
- * in use.
- */
-#define HV_STATUS_CONTROLLER_IN_USE			((u16)0x2005)
-
-
-/*
- * The below CPUID leaves are present if VersionAndFeatures.HypervisorPresent
- * is set by CPUID(HVCPUID_VERSION_FEATURES).
- */
-enum hv_cpuid_function {
-	HVCPUID_VERSION_FEATURES		= 0x00000001,
-	HVCPUID_VENDOR_MAXFUNCTION		= 0x40000000,
-	HVCPUID_INTERFACE			= 0x40000001,
-
-	/*
-	 * The remaining functions depend on the value of
-	 * HVCPUID_INTERFACE
-	 */
-	HVCPUID_VERSION			= 0x40000002,
-	HVCPUID_FEATURES			= 0x40000003,
-	HVCPUID_ENLIGHTENMENT_INFO	= 0x40000004,
-	HVCPUID_IMPLEMENTATION_LIMITS		= 0x40000005,
-};
-
-/* 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 version of the synthetic interrupt controller. */
-#define HV_SYNIC_VERSION		(1)
-
-/* 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 the expected SynIC version. */
-#define HV_SYNIC_VERSION_1		(0x1)
-
-/* Define synthetic interrupt controller message constants. */
-#define HV_MESSAGE_SIZE			(256)
-#define HV_MESSAGE_PAYLOAD_BYTE_COUNT	(240)
-#define HV_MESSAGE_PAYLOAD_QWORD_COUNT	(30)
-#define HV_ANY_VP			(0xFFFFFFFF)
-
-/* Define synthetic interrupt controller flag constants. */
-#define HV_EVENT_FLAGS_COUNT		(256 * 8)
-#define HV_EVENT_FLAGS_BYTE_COUNT	(256)
-#define HV_EVENT_FLAGS_DWORD_COUNT	(256 / sizeof(u32))
-
-/* Define hypervisor message types. */
-enum hv_message_type {
-	HVMSG_NONE			= 0x00000000,
-
-	/* Memory access messages. */
-	HVMSG_UNMAPPED_GPA		= 0x80000000,
-	HVMSG_GPA_INTERCEPT		= 0x80000001,
-
-	/* Timer notification messages. */
-	HVMSG_TIMER_EXPIRED			= 0x80000010,
-
-	/* Error messages. */
-	HVMSG_INVALID_VP_REGISTER_VALUE	= 0x80000020,
-	HVMSG_UNRECOVERABLE_EXCEPTION	= 0x80000021,
-	HVMSG_UNSUPPORTED_FEATURE		= 0x80000022,
-
-	/* Trace buffer complete messages. */
-	HVMSG_EVENTLOG_BUFFERCOMPLETE	= 0x80000040,
-
-	/* Platform-specific processor intercept messages. */
-	HVMSG_X64_IOPORT_INTERCEPT		= 0x80010000,
-	HVMSG_X64_MSR_INTERCEPT		= 0x80010001,
-	HVMSG_X64_CPUID_INTERCEPT		= 0x80010002,
-	HVMSG_X64_EXCEPTION_INTERCEPT	= 0x80010003,
-	HVMSG_X64_APIC_EOI			= 0x80010004,
-	HVMSG_X64_LEGACY_FP_ERROR		= 0x80010005
-};
-
-/* Define the number of synthetic interrupt sources. */
-#define HV_SYNIC_SINT_COUNT		(16)
-#define HV_SYNIC_STIMER_COUNT		(4)
-
-/* Define invalid partition identifier. */
-#define HV_PARTITION_ID_INVALID		((u64)0x0)
-
-/* Define connection identifier type. */
-union hv_connection_id {
-	u32 asu32;
-	struct {
-		u32 id:24;
-		u32 reserved:8;
-	} u;
-};
-
-/* Define port identifier type. */
-union hv_port_id {
-	u32 asu32;
-	struct {
-		u32 id:24;
-		u32 reserved:8;
-	} u ;
-};
-
-/* Define port type. */
-enum hv_port_type {
-	HVPORT_MSG	= 1,
-	HVPORT_EVENT		= 2,
-	HVPORT_MONITOR	= 3
-};
-
-/* Define port information structure. */
-struct hv_port_info {
-	enum hv_port_type port_type;
-	u32 padding;
-	union {
-		struct {
-			u32 target_sint;
-			u32 target_vp;
-			u64 rsvdz;
-		} message_port_info;
-		struct {
-			u32 target_sint;
-			u32 target_vp;
-			u16 base_flag_bumber;
-			u16 flag_count;
-			u32 rsvdz;
-		} event_port_info;
-		struct {
-			u64 monitor_address;
-			u64 rsvdz;
-		} monitor_port_info;
-	};
-};
-
-struct hv_connection_info {
-	enum hv_port_type port_type;
-	u32 padding;
-	union {
-		struct {
-			u64 rsvdz;
-		} message_connection_info;
-		struct {
-			u64 rsvdz;
-		} event_connection_info;
-		struct {
-			u64 monitor_address;
-		} monitor_connection_info;
-	};
-};
-
-/* Define synthetic interrupt controller message flags. */
-union hv_message_flags {
-	u8 asu8;
-	struct {
-		u8 msg_pending:1;
-		u8 reserved:7;
-	};
-};
-
-/* Define synthetic interrupt controller message header. */
-struct hv_message_header {
-	enum hv_message_type message_type;
-	u8 payload_size;
-	union hv_message_flags message_flags;
-	u8 reserved[2];
-	union {
-		u64 sender;
-		union hv_port_id port;
-	};
-};
-
-/* Define timer message payload structure. */
-struct hv_timer_message_payload {
-	u32 timer_index;
-	u32 reserved;
-	u64 expiration_time;	/* When the timer expired */
-	u64 delivery_time;	/* When the message was delivered */
-};
-
-/* Define synthetic interrupt controller message format. */
-struct hv_message {
-	struct hv_message_header header;
-	union {
-		u64 payload[HV_MESSAGE_PAYLOAD_QWORD_COUNT];
-	} u ;
-};
-
-/* Define the number of message buffers associated with each port. */
-#define HV_PORT_MESSAGE_BUFFER_COUNT	(16)
-
-/* Define the synthetic interrupt message page layout. */
-struct hv_message_page {
-	struct hv_message sint_message[HV_SYNIC_SINT_COUNT];
-};
-
-/* Define the synthetic interrupt controller event flags format. */
-union hv_synic_event_flags {
-	u8 flags8[HV_EVENT_FLAGS_BYTE_COUNT];
-	u32 flags32[HV_EVENT_FLAGS_DWORD_COUNT];
-};
-
-/* Define the synthetic interrupt flags page layout. */
-struct hv_synic_event_flags_page {
-	union hv_synic_event_flags sintevent_flags[HV_SYNIC_SINT_COUNT];
-};
-
-/* Define SynIC control register. */
-union hv_synic_scontrol {
-	u64 as_uint64;
-	struct {
-		u64 enable:1;
-		u64 reserved:63;
-	};
-};
-
-/* Define synthetic interrupt source. */
-union hv_synic_sint {
-	u64 as_uint64;
-	struct {
-		u64 vector:8;
-		u64 reserved1:8;
-		u64 masked:1;
-		u64 auto_eoi:1;
-		u64 reserved2:46;
-	};
-};
-
-/* Define the format of the SIMP register */
-union hv_synic_simp {
-	u64 as_uint64;
-	struct {
-		u64 simp_enabled:1;
-		u64 preserved:11;
-		u64 base_simp_gpa:52;
-	};
-};
-
-/* Define the format of the SIEFP register */
-union hv_synic_siefp {
-	u64 as_uint64;
-	struct {
-		u64 siefp_enabled:1;
-		u64 preserved:11;
-		u64 base_siefp_gpa:52;
-	};
-};
-
-/* Definitions for the monitored notification facility */
-union hv_monitor_trigger_group {
-	u64 as_uint64;
-	struct {
-		u32 pending;
-		u32 armed;
-	};
-};
-
-struct hv_monitor_parameter {
-	union hv_connection_id connectionid;
-	u16 flagnumber;
-	u16 rsvdz;
-};
-
-union hv_monitor_trigger_state {
-	u32 asu32;
-
-	struct {
-		u32 group_enable:4;
-		u32 rsvdz:28;
-	};
-};
-
-/* struct hv_monitor_page Layout */
-/* ------------------------------------------------------ */
-/* | 0   | TriggerState (4 bytes) | Rsvd1 (4 bytes)     | */
-/* | 8   | TriggerGroup[0]                              | */
-/* | 10  | TriggerGroup[1]                              | */
-/* | 18  | TriggerGroup[2]                              | */
-/* | 20  | TriggerGroup[3]                              | */
-/* | 28  | Rsvd2[0]                                     | */
-/* | 30  | Rsvd2[1]                                     | */
-/* | 38  | Rsvd2[2]                                     | */
-/* | 40  | NextCheckTime[0][0]    | NextCheckTime[0][1] | */
-/* | ...                                                | */
-/* | 240 | Latency[0][0..3]                             | */
-/* | 340 | Rsvz3[0]                                     | */
-/* | 440 | Parameter[0][0]                              | */
-/* | 448 | Parameter[0][1]                              | */
-/* | ...                                                | */
-/* | 840 | Rsvd4[0]                                     | */
-/* ------------------------------------------------------ */
-struct hv_monitor_page {
-	union hv_monitor_trigger_state trigger_state;
-	u32 rsvdz1;
-
-	union hv_monitor_trigger_group trigger_group[4];
-	u64 rsvdz2[3];
-
-	s32 next_checktime[4][32];
-
-	u16 latency[4][32];
-	u64 rsvdz3[32];
-
-	struct hv_monitor_parameter parameter[4][32];
-
-	u8 rsvdz4[1984];
-};
-
-/* Declare the various hypercall operations. */
-enum hv_call_code {
-	HVCALL_POST_MESSAGE	= 0x005c,
-	HVCALL_SIGNAL_EVENT	= 0x005d,
-};
-
-/* Definition of the hv_post_message hypercall input structure. */
-struct hv_input_post_message {
-	union hv_connection_id connectionid;
-	u32 reserved;
-	enum hv_message_type message_type;
-	u32 payload_size;
-	u64 payload[HV_MESSAGE_PAYLOAD_QWORD_COUNT];
-};
-
-/* Definition of the hv_signal_event hypercall input structure. */
-struct hv_input_signal_event {
-	union hv_connection_id connectionid;
-	u16 flag_number;
-	u16 rsvdz;
-};
-
-/*
- * Versioning definitions used for guests reporting themselves to the
- * hypervisor, and visa versa.
- */
-
-/* Version info reported by guest OS's */
-enum hv_guest_os_vendor {
-	HVGUESTOS_VENDOR_MICROSOFT	= 0x0001
-};
-
-enum hv_guest_os_microsoft_ids {
-	HVGUESTOS_MICROSOFT_UNDEFINED	= 0x00,
-	HVGUESTOS_MICROSOFT_MSDOS		= 0x01,
-	HVGUESTOS_MICROSOFT_WINDOWS3X	= 0x02,
-	HVGUESTOS_MICROSOFT_WINDOWS9X	= 0x03,
-	HVGUESTOS_MICROSOFT_WINDOWSNT	= 0x04,
-	HVGUESTOS_MICROSOFT_WINDOWSCE	= 0x05
-};
-
-/*
- * Declare the MSR used to identify the guest OS.
- */
-#define HV_X64_MSR_GUEST_OS_ID	0x40000000
-
-union hv_x64_msr_guest_os_id_contents {
-	u64 as_uint64;
-	struct {
-		u64 build_number:16;
-		u64 service_version:8; /* Service Pack, etc. */
-		u64 minor_version:8;
-		u64 major_version:8;
-		u64 os_id:8; /* enum hv_guest_os_microsoft_ids (if Vendor=MS) */
-		u64 vendor_id:16; /* enum hv_guest_os_vendor */
-	};
-};
-
-/*
- * Declare the MSR used to setup pages used to communicate with the hypervisor.
- */
-#define HV_X64_MSR_HYPERCALL	0x40000001
-
-union hv_x64_msr_hypercall_contents {
-	u64 as_uint64;
-	struct {
-		u64 enable:1;
-		u64 reserved:11;
-		u64 guest_physical_address:52;
-	};
-};
-
-#endif
diff -druN linux-2.6.39-libre/drivers/staging/hv/hv.c linux-3.0-rc7-libre/drivers/staging/hv/hv.c
--- linux-2.6.39-libre/drivers/staging/hv/hv.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/hv/hv.c	2011-07-11 19:51:52.000000000 -0400
@@ -19,13 +19,15 @@
  *   Hank Janssen  <hjanssen@microsoft.com>
  *
  */
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/kernel.h>
 #include <linux/mm.h>
 #include <linux/slab.h>
 #include <linux/vmalloc.h>
-#include "hv_api.h"
-#include "logging.h"
-#include "vmbus_private.h"
+
+#include "hyperv.h"
+#include "hyperv_vmbus.h"
 
 /* The one and only */
 struct hv_context hv_context = {
@@ -80,33 +82,7 @@
 	op = HVCPUID_VENDOR_MAXFUNCTION;
 	cpuid(op, &eax, &ebx, &ecx, &edx);
 
-	DPRINT_INFO(VMBUS, "Vendor ID: %c%c%c%c%c%c%c%c%c%c%c%c",
-		    (ebx & 0xFF),
-		    ((ebx >> 8) & 0xFF),
-		    ((ebx >> 16) & 0xFF),
-		    ((ebx >> 24) & 0xFF),
-		    (ecx & 0xFF),
-		    ((ecx >> 8) & 0xFF),
-		    ((ecx >> 16) & 0xFF),
-		    ((ecx >> 24) & 0xFF),
-		    (edx & 0xFF),
-		    ((edx >> 8) & 0xFF),
-		    ((edx >> 16) & 0xFF),
-		    ((edx >> 24) & 0xFF));
-
 	max_leaf = eax;
-	eax = 0;
-	ebx = 0;
-	ecx = 0;
-	edx = 0;
-	op = HVCPUID_INTERFACE;
-	cpuid(op, &eax, &ebx, &ecx, &edx);
-
-	DPRINT_INFO(VMBUS, "Interface ID: %c%c%c%c",
-		    (eax & 0xFF),
-		    ((eax >> 8) & 0xFF),
-		    ((eax >> 16) & 0xFF),
-		    ((eax >> 24) & 0xFF));
 
 	if (max_leaf >= HVCPUID_VERSION) {
 		eax = 0;
@@ -115,7 +91,7 @@
 		edx = 0;
 		op = HVCPUID_VERSION;
 		cpuid(op, &eax, &ebx, &ecx, &edx);
-		DPRINT_INFO(VMBUS, "OS Build:%d-%d.%d-%d-%d.%d",\
+		pr_info("Hyper-V Host OS Build:%d-%d.%d-%d-%d.%d\n",
 			    eax,
 			    ebx >> 16,
 			    ebx & 0xFFFF,
@@ -137,18 +113,11 @@
 	u64 output_address = (output) ? virt_to_phys(output) : 0;
 	volatile void *hypercall_page = hv_context.hypercall_page;
 
-	DPRINT_DBG(VMBUS, "Hypercall <control %llx input phys %llx virt %p "
-		   "output phys %llx virt %p hypercall %p>",
-		   control, input_address, input,
-		   output_address, output, hypercall_page);
-
 	__asm__ __volatile__("mov %0, %%r8" : : "r" (output_address) : "r8");
 	__asm__ __volatile__("call *%3" : "=a" (hv_status) :
 			     "c" (control), "d" (input_address),
 			     "m" (hypercall_page));
 
-	DPRINT_DBG(VMBUS, "Hypercall <return %llx>",  hv_status);
-
 	return hv_status;
 
 #else
@@ -165,18 +134,12 @@
 	u32 output_address_lo = output_address & 0xFFFFFFFF;
 	volatile void *hypercall_page = hv_context.hypercall_page;
 
-	DPRINT_DBG(VMBUS, "Hypercall <control %llx input %p output %p>",
-		   control, input, output);
-
 	__asm__ __volatile__ ("call *%8" : "=d"(hv_status_hi),
 			      "=a"(hv_status_lo) : "d" (control_hi),
 			      "a" (control_lo), "b" (input_address_hi),
 			      "c" (input_address_lo), "D"(output_address_hi),
 			      "S"(output_address_lo), "m" (hypercall_page));
 
-	DPRINT_DBG(VMBUS, "Hypercall <return %llx>",
-		   hv_status_lo | ((u64)hv_status_hi << 32));
-
 	return hv_status_lo | ((u64)hv_status_hi << 32);
 #endif /* !x86_64 */
 }
@@ -197,13 +160,8 @@
 	memset(hv_context.synic_message_page, 0,
 	       sizeof(void *) * MAX_NUM_CPUS);
 
-	if (!query_hypervisor_presence()) {
-		DPRINT_ERR(VMBUS, "No Windows hypervisor detected!!");
-		goto Cleanup;
-	}
-
-	DPRINT_INFO(VMBUS,
-		    "Windows hypervisor detected! Retrieving more info...");
+	if (!query_hypervisor_presence())
+		goto cleanup;
 
 	max_leaf = query_hypervisor_info();
 	/* HvQueryHypervisorFeatures(maxLeaf); */
@@ -213,11 +171,8 @@
 	 */
 	rdmsrl(HV_X64_MSR_GUEST_OS_ID, hv_context.guestid);
 
-	if (hv_context.guestid != 0) {
-		DPRINT_ERR(VMBUS, "Unknown guest id (0x%llx)!!",
-				hv_context.guestid);
-		goto Cleanup;
-	}
+	if (hv_context.guestid != 0)
+		goto cleanup;
 
 	/* Write our OS info */
 	wrmsrl(HV_X64_MSR_GUEST_OS_ID, HV_LINUX_GUEST_ID);
@@ -232,11 +187,8 @@
 	*/
 	virtaddr = __vmalloc(PAGE_SIZE, GFP_KERNEL, PAGE_KERNEL_EXEC);
 
-	if (!virtaddr) {
-		DPRINT_ERR(VMBUS,
-			   "unable to allocate hypercall page!!");
-		goto Cleanup;
-	}
+	if (!virtaddr)
+		goto cleanup;
 
 	hypercall_msr.enable = 1;
 
@@ -247,23 +199,17 @@
 	hypercall_msr.as_uint64 = 0;
 	rdmsrl(HV_X64_MSR_HYPERCALL, hypercall_msr.as_uint64);
 
-	if (!hypercall_msr.enable) {
-		DPRINT_ERR(VMBUS, "unable to set hypercall page!!");
-		goto Cleanup;
-	}
+	if (!hypercall_msr.enable)
+		goto cleanup;
 
 	hv_context.hypercall_page = virtaddr;
 
-	DPRINT_INFO(VMBUS, "Hypercall page VA=%p, PA=0x%0llx",
-		    hv_context.hypercall_page,
-		    (u64)hypercall_msr.guest_physical_address << PAGE_SHIFT);
-
 	/* Setup the global signal event param for the signal event hypercall */
 	hv_context.signal_event_buffer =
 			kmalloc(sizeof(struct hv_input_signal_event_buffer),
 				GFP_KERNEL);
 	if (!hv_context.signal_event_buffer)
-		goto Cleanup;
+		goto cleanup;
 
 	hv_context.signal_event_param =
 		(struct hv_input_signal_event *)
@@ -278,7 +224,7 @@
 
 	return ret;
 
-Cleanup:
+cleanup:
 	if (virtaddr) {
 		if (hypercall_msr.enable) {
 			hypercall_msr.as_uint64 = 0;
@@ -394,24 +340,20 @@
 	/* Check the version */
 	rdmsrl(HV_X64_MSR_SVERSION, version);
 
-	DPRINT_INFO(VMBUS, "SynIC version: %llx", version);
-
 	hv_context.synic_message_page[cpu] =
 		(void *)get_zeroed_page(GFP_ATOMIC);
 
 	if (hv_context.synic_message_page[cpu] == NULL) {
-		DPRINT_ERR(VMBUS,
-			   "unable to allocate SYNIC message page!!");
-		goto Cleanup;
+		pr_err("Unable to allocate SYNIC message page\n");
+		goto cleanup;
 	}
 
 	hv_context.synic_event_page[cpu] =
 		(void *)get_zeroed_page(GFP_ATOMIC);
 
 	if (hv_context.synic_event_page[cpu] == NULL) {
-		DPRINT_ERR(VMBUS,
-			   "unable to allocate SYNIC event page!!");
-		goto Cleanup;
+		pr_err("Unable to allocate SYNIC event page\n");
+		goto cleanup;
 	}
 
 	/* Setup the Synic's message page */
@@ -420,8 +362,6 @@
 	simp.base_simp_gpa = virt_to_phys(hv_context.synic_message_page[cpu])
 		>> PAGE_SHIFT;
 
-	DPRINT_DBG(VMBUS, "HV_X64_MSR_SIMP msr set to: %llx", simp.as_uint64);
-
 	wrmsrl(HV_X64_MSR_SIMP, simp.as_uint64);
 
 	/* Setup the Synic's event page */
@@ -430,14 +370,8 @@
 	siefp.base_siefp_gpa = virt_to_phys(hv_context.synic_event_page[cpu])
 		>> PAGE_SHIFT;
 
-	DPRINT_DBG(VMBUS, "HV_X64_MSR_SIEFP msr set to: %llx", siefp.as_uint64);
-
 	wrmsrl(HV_X64_MSR_SIEFP, siefp.as_uint64);
 
-	/* Setup the interception SINT. */
-	/* wrmsrl((HV_X64_MSR_SINT0 + HV_SYNIC_INTERCEPTION_SINT_INDEX), */
-	/*	  interceptionSint.as_uint64); */
-
 	/* Setup the shared SINT. */
 	rdmsrl(HV_X64_MSR_SINT0 + VMBUS_MESSAGE_SINT, shared_sint.as_uint64);
 
@@ -446,9 +380,6 @@
 	shared_sint.masked = false;
 	shared_sint.auto_eoi = true;
 
-	DPRINT_DBG(VMBUS, "HV_X64_MSR_SINT1 msr set to: %llx",
-		   shared_sint.as_uint64);
-
 	wrmsrl(HV_X64_MSR_SINT0 + VMBUS_MESSAGE_SINT, shared_sint.as_uint64);
 
 	/* Enable the global synic bit */
@@ -460,7 +391,7 @@
 	hv_context.synic_initialized = true;
 	return;
 
-Cleanup:
+cleanup:
 	if (hv_context.synic_event_page[cpu])
 		free_page((unsigned long)hv_context.synic_event_page[cpu]);
 
diff -druN linux-2.6.39-libre/drivers/staging/hv/hv.h linux-3.0-rc7-libre/drivers/staging/hv/hv.h
--- linux-2.6.39-libre/drivers/staging/hv/hv.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/hv/hv.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,140 +0,0 @@
-/*
- *
- * Copyright (c) 2009, Microsoft 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., 59 Temple
- * Place - Suite 330, Boston, MA 02111-1307 USA.
- *
- * Authors:
- *   Haiyang Zhang <haiyangz@microsoft.com>
- *   Hank Janssen  <hjanssen@microsoft.com>
- *
- */
-
-
-#ifndef __HV_H__
-#define __HV_H__
-
-#include "hv_api.h"
-
-enum {
-	VMBUS_MESSAGE_CONNECTION_ID	= 1,
-	VMBUS_MESSAGE_PORT_ID		= 1,
-	VMBUS_EVENT_CONNECTION_ID	= 2,
-	VMBUS_EVENT_PORT_ID		= 2,
-	VMBUS_MONITOR_CONNECTION_ID	= 3,
-	VMBUS_MONITOR_PORT_ID		= 3,
-	VMBUS_MESSAGE_SINT		= 2,
-};
-
-/* #defines */
-
-#define HV_PRESENT_BIT			0x80000000
-
-#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) | \
-					   HV_LINUX_GUEST_ID_LO)
-
-#define HV_CPU_POWER_MANAGEMENT		(1 << 0)
-#define HV_RECOMMENDATIONS_MAX		4
-
-#define HV_X64_MAX			5
-#define HV_CAPS_MAX			8
-
-
-#define HV_HYPERCALL_PARAM_ALIGN	sizeof(u64)
-
-
-/* Service definitions */
-
-#define HV_SERVICE_PARENT_PORT				(0)
-#define HV_SERVICE_PARENT_CONNECTION			(0)
-
-#define HV_SERVICE_CONNECT_RESPONSE_SUCCESS		(0)
-#define HV_SERVICE_CONNECT_RESPONSE_INVALID_PARAMETER	(1)
-#define HV_SERVICE_CONNECT_RESPONSE_UNKNOWN_SERVICE	(2)
-#define HV_SERVICE_CONNECT_RESPONSE_CONNECTION_REJECTED	(3)
-
-#define HV_SERVICE_CONNECT_REQUEST_MESSAGE_ID		(1)
-#define HV_SERVICE_CONNECT_RESPONSE_MESSAGE_ID		(2)
-#define HV_SERVICE_DISCONNECT_REQUEST_MESSAGE_ID	(3)
-#define HV_SERVICE_DISCONNECT_RESPONSE_MESSAGE_ID	(4)
-#define HV_SERVICE_MAX_MESSAGE_ID				(4)
-
-#define HV_SERVICE_PROTOCOL_VERSION (0x0010)
-#define HV_CONNECT_PAYLOAD_BYTE_COUNT 64
-
-/* #define VMBUS_REVISION_NUMBER	6 */
-
-/* Our local vmbus's port and connection id. Anything >0 is fine */
-/* #define VMBUS_PORT_ID		11 */
-
-/* 628180B8-308D-4c5e-B7DB-1BEB62E62EF4 */
-static const struct hv_guid VMBUS_SERVICE_ID = {
-	.data = {
-		0xb8, 0x80, 0x81, 0x62, 0x8d, 0x30, 0x5e, 0x4c,
-		0xb7, 0xdb, 0x1b, 0xeb, 0x62, 0xe6, 0x2e, 0xf4
-	},
-};
-
-#define MAX_NUM_CPUS	32
-
-
-struct hv_input_signal_event_buffer {
-	u64 align8;
-	struct hv_input_signal_event event;
-};
-
-struct hv_context {
-	/* 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 *hypercall_page;
-
-	bool synic_initialized;
-
-	/*
-	 * This is used as an input param to HvCallSignalEvent hypercall. The
-	 * input param is immutable in our usage and must be dynamic mem (vs
-	 * stack or global). */
-	struct hv_input_signal_event_buffer *signal_event_buffer;
-	/* 8-bytes aligned of the buffer above */
-	struct hv_input_signal_event *signal_event_param;
-
-	void *synic_message_page[MAX_NUM_CPUS];
-	void *synic_event_page[MAX_NUM_CPUS];
-};
-
-extern struct hv_context hv_context;
-
-
-/* Hv Interface */
-
-extern int hv_init(void);
-
-extern void hv_cleanup(void);
-
-extern u16 hv_post_message(union hv_connection_id connection_id,
-			 enum hv_message_type message_type,
-			 void *payload, size_t payload_size);
-
-extern u16 hv_signal_event(void);
-
-extern void hv_synic_init(void *irqarg);
-
-extern void hv_synic_cleanup(void *arg);
-
-#endif /* __HV_H__ */
diff -druN linux-2.6.39-libre/drivers/staging/hv/hv_kvp.c linux-3.0-rc7-libre/drivers/staging/hv/hv_kvp.c
--- linux-2.6.39-libre/drivers/staging/hv/hv_kvp.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/hv/hv_kvp.c	2011-07-11 19:51:52.000000000 -0400
@@ -20,23 +20,14 @@
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  *
  */
-
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 
 #include <linux/net.h>
 #include <linux/nls.h>
 #include <linux/connector.h>
 #include <linux/workqueue.h>
 
-#include "logging.h"
-#include "hv_api.h"
-#include "vmbus.h"
-#include "vmbus_packet_format.h"
-#include "vmbus_channel_interface.h"
-#include "version_info.h"
-#include "channel.h"
-#include "vmbus_private.h"
-#include "vmbus_api.h"
-#include "utils.h"
+#include "hyperv.h"
 #include "hv_kvp.h"
 
 
@@ -114,7 +105,7 @@
 
 	message = (struct hv_ku_msg *)msg->data;
 	if (msg->seq == KVP_REGISTER) {
-		printk(KERN_INFO "KVP: user-mode registering done.\n");
+		pr_info("KVP: user-mode registering done.\n");
 		kvp_register();
 	}
 
@@ -174,7 +165,7 @@
 		/*
 		 * This is a spurious call!
 		 */
-		printk(KERN_WARNING "KVP: Transaction not active\n");
+		pr_warn("KVP: Transaction not active\n");
 		return;
 	}
 	/*
@@ -259,9 +250,6 @@
 	vmbus_recvpacket(channel, recv_buffer, PAGE_SIZE, &recvlen, &requestid);
 
 	if (recvlen > 0) {
-		DPRINT_DBG(VMBUS, "KVP packet: len=%d, requestid=%lld",
-			   recvlen, requestid);
-
 		icmsghdrp = (struct icmsg_hdr *)&recv_buffer[
 			sizeof(struct vmbuspipe_hdr)];
 
diff -druN linux-2.6.39-libre/drivers/staging/hv/hv_mouse.c linux-3.0-rc7-libre/drivers/staging/hv/hv_mouse.c
--- linux-2.6.39-libre/drivers/staging/hv/hv_mouse.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/hv/hv_mouse.c	2011-07-11 19:51:52.000000000 -0400
@@ -26,13 +26,7 @@
 #include <linux/dmi.h>
 #include <linux/delay.h>
 
-#include "hv_api.h"
-#include "logging.h"
-#include "version_info.h"
-#include "vmbus.h"
-#include "vmbus_api.h"
-#include "channel.h"
-#include "vmbus_packet_format.h"
+#include "hyperv.h"
 
 
 /*
@@ -45,13 +39,6 @@
 	char name[128];
 };
 
-/* Represents the input vsc driver */
-/* FIXME - can be removed entirely */
-struct mousevsc_drv_obj {
-	struct hv_driver Base;
-};
-
-
 /* The maximum size of a synthetic input message. */
 #define SYNTHHID_MAX_INPUT_REPORT_SIZE 16
 
@@ -169,23 +156,23 @@
  * Represents an mousevsc device
  */
 struct mousevsc_dev {
-	struct hv_device	*Device;
+	struct hv_device	*device;
 	/* 0 indicates the device is being destroyed */
-	atomic_t		RefCount;
-	int			NumOutstandingRequests;
-	unsigned char		bInitializeComplete;
-	struct mousevsc_prt_msg	ProtocolReq;
-	struct mousevsc_prt_msg	ProtocolResp;
+	atomic_t		ref_count;
+	int			num_outstanding_req;
+	unsigned char		init_complete;
+	struct mousevsc_prt_msg	protocol_req;
+	struct mousevsc_prt_msg	protocol_resp;
 	/* Synchronize the request/response if needed */
-	wait_queue_head_t	ProtocolWaitEvent;
-	wait_queue_head_t	DeviceInfoWaitEvent;
+	wait_queue_head_t	protocol_wait_event;
+	wait_queue_head_t	dev_info_wait_event;
 	int			protocol_wait_condition;
 	int			device_wait_condition;
-	int			DeviceInfoStatus;
+	int			dev_info_status;
 
-	struct hid_descriptor	*HidDesc;
-	unsigned char		*ReportDesc;
-	u32			ReportDescSize;
+	struct hid_descriptor	*hid_desc;
+	unsigned char		*report_desc;
+	u32			report_desc_size;
 	struct hv_input_dev_info hid_dev_info;
 };
 
@@ -202,41 +189,41 @@
 static void inputreport_callback(struct hv_device *dev, void *packet, u32 len);
 static void reportdesc_callback(struct hv_device *dev, void *packet, u32 len);
 
-static struct mousevsc_dev *AllocInputDevice(struct hv_device *Device)
+static struct mousevsc_dev *alloc_input_device(struct hv_device *device)
 {
-	struct mousevsc_dev *inputDevice;
+	struct mousevsc_dev *input_dev;
 
-	inputDevice = kzalloc(sizeof(struct mousevsc_dev), GFP_KERNEL);
+	input_dev = kzalloc(sizeof(struct mousevsc_dev), GFP_KERNEL);
 
-	if (!inputDevice)
+	if (!input_dev)
 		return NULL;
 
 	/*
 	 * Set to 2 to allow both inbound and outbound traffics
-	 * (ie GetInputDevice() and MustGetInputDevice()) to proceed.
+	 * (ie get_input_device() and must_get_input_device()) to proceed.
 	 */
-	atomic_cmpxchg(&inputDevice->RefCount, 0, 2);
+	atomic_cmpxchg(&input_dev->ref_count, 0, 2);
 
-	inputDevice->Device = Device;
-	Device->ext = inputDevice;
+	input_dev->device = device;
+	device->ext = input_dev;
 
-	return inputDevice;
+	return input_dev;
 }
 
-static void FreeInputDevice(struct mousevsc_dev *Device)
+static void free_input_device(struct mousevsc_dev *device)
 {
-	WARN_ON(atomic_read(&Device->RefCount) == 0);
-	kfree(Device);
+	WARN_ON(atomic_read(&device->ref_count) == 0);
+	kfree(device);
 }
 
 /*
  * Get the inputdevice object if exists and its refcount > 1
  */
-static struct mousevsc_dev *GetInputDevice(struct hv_device *Device)
+static struct mousevsc_dev *get_input_device(struct hv_device *device)
 {
-	struct mousevsc_dev *inputDevice;
+	struct mousevsc_dev *input_dev;
 
-	inputDevice = (struct mousevsc_dev *)Device->ext;
+	input_dev = (struct mousevsc_dev *)device->ext;
 
 /*
  *	FIXME
@@ -244,134 +231,137 @@
  *	what the intention is...
  *
  *	printk(KERN_ERR "-------------------------> REFCOUNT = %d",
- *	       inputDevice->RefCount);
+ *	       input_dev->ref_count);
  */
 
-	if (inputDevice && atomic_read(&inputDevice->RefCount) > 1)
-		atomic_inc(&inputDevice->RefCount);
+	if (input_dev && atomic_read(&input_dev->ref_count) > 1)
+		atomic_inc(&input_dev->ref_count);
 	else
-		inputDevice = NULL;
+		input_dev = NULL;
 
-	return inputDevice;
+	return input_dev;
 }
 
 /*
  * Get the inputdevice object iff exists and its refcount > 0
  */
-static struct mousevsc_dev *MustGetInputDevice(struct hv_device *Device)
+static struct mousevsc_dev *must_get_input_device(struct hv_device *device)
 {
-	struct mousevsc_dev *inputDevice;
+	struct mousevsc_dev *input_dev;
 
-	inputDevice = (struct mousevsc_dev *)Device->ext;
+	input_dev = (struct mousevsc_dev *)device->ext;
 
-	if (inputDevice && atomic_read(&inputDevice->RefCount))
-		atomic_inc(&inputDevice->RefCount);
+	if (input_dev && atomic_read(&input_dev->ref_count))
+		atomic_inc(&input_dev->ref_count);
 	else
-		inputDevice = NULL;
+		input_dev = NULL;
 
-	return inputDevice;
+	return input_dev;
 }
 
-static void PutInputDevice(struct hv_device *Device)
+static void put_input_device(struct hv_device *device)
 {
-	struct mousevsc_dev *inputDevice;
+	struct mousevsc_dev *input_dev;
 
-	inputDevice = (struct mousevsc_dev *)Device->ext;
+	input_dev = (struct mousevsc_dev *)device->ext;
 
-	atomic_dec(&inputDevice->RefCount);
+	atomic_dec(&input_dev->ref_count);
 }
 
 /*
- * Drop ref count to 1 to effectively disable GetInputDevice()
+ * Drop ref count to 1 to effectively disable get_input_device()
  */
-static struct mousevsc_dev *ReleaseInputDevice(struct hv_device *Device)
+static struct mousevsc_dev *release_input_device(struct hv_device *device)
 {
-	struct mousevsc_dev *inputDevice;
+	struct mousevsc_dev *input_dev;
 
-	inputDevice = (struct mousevsc_dev *)Device->ext;
+	input_dev = (struct mousevsc_dev *)device->ext;
 
 	/* Busy wait until the ref drop to 2, then set it to 1  */
-	while (atomic_cmpxchg(&inputDevice->RefCount, 2, 1) != 2)
+	while (atomic_cmpxchg(&input_dev->ref_count, 2, 1) != 2)
 		udelay(100);
 
-	return inputDevice;
+	return input_dev;
 }
 
 /*
- * Drop ref count to 0. No one can use InputDevice object.
+ * Drop ref count to 0. No one can use input_device object.
  */
-static struct mousevsc_dev *FinalReleaseInputDevice(struct hv_device *Device)
+static struct mousevsc_dev *final_release_input_device(struct hv_device *device)
 {
-	struct mousevsc_dev *inputDevice;
+	struct mousevsc_dev *input_dev;
 
-	inputDevice = (struct mousevsc_dev *)Device->ext;
+	input_dev = (struct mousevsc_dev *)device->ext;
 
 	/* Busy wait until the ref drop to 1, then set it to 0  */
-	while (atomic_cmpxchg(&inputDevice->RefCount, 1, 0) != 1)
+	while (atomic_cmpxchg(&input_dev->ref_count, 1, 0) != 1)
 		udelay(100);
 
-	Device->ext = NULL;
-	return inputDevice;
+	device->ext = NULL;
+	return input_dev;
 }
 
-static void MousevscOnSendCompletion(struct hv_device *Device, struct vmpacket_descriptor *Packet)
+static void mousevsc_on_send_completion(struct hv_device *device,
+					struct vmpacket_descriptor *packet)
 {
-	struct mousevsc_dev *inputDevice;
+	struct mousevsc_dev *input_dev;
 	void *request;
 
-	inputDevice = MustGetInputDevice(Device);
-	if (!inputDevice) {
+	input_dev = must_get_input_device(device);
+	if (!input_dev) {
 		pr_err("unable to get input device...device being destroyed?");
 		return;
 	}
 
-	request = (void *)(unsigned long)Packet->trans_id;
+	request = (void *)(unsigned long)packet->trans_id;
 
-	if (request == &inputDevice->ProtocolReq) {
+	if (request == &input_dev->protocol_req) {
 		/* FIXME */
 		/* Shouldn't we be doing something here? */
 	}
 
-	PutInputDevice(Device);
+	put_input_device(device);
 }
 
-static void MousevscOnReceiveDeviceInfo(struct mousevsc_dev *InputDevice, struct synthhid_device_info *DeviceInfo)
+static void mousevsc_on_receive_device_info(struct mousevsc_dev *input_device,
+				struct synthhid_device_info *device_info)
 {
 	int ret = 0;
 	struct hid_descriptor *desc;
 	struct mousevsc_prt_msg ack;
 
 	/* Assume success for now */
-	InputDevice->DeviceInfoStatus = 0;
+	input_device->dev_info_status = 0;
 
 	/* Save the device attr */
-	memcpy(&InputDevice->hid_dev_info, &DeviceInfo->hid_dev_info, sizeof(struct hv_input_dev_info));
+	memcpy(&input_device->hid_dev_info, &device_info->hid_dev_info,
+		sizeof(struct hv_input_dev_info));
 
 	/* Save the hid desc */
-	desc = &DeviceInfo->hid_descriptor;
+	desc = &device_info->hid_descriptor;
 	WARN_ON(desc->bLength > 0);
 
-	InputDevice->HidDesc = kzalloc(desc->bLength, GFP_KERNEL);
+	input_device->hid_desc = kzalloc(desc->bLength, GFP_KERNEL);
 
-	if (!InputDevice->HidDesc) {
+	if (!input_device->hid_desc) {
 		pr_err("unable to allocate hid descriptor - size %d", desc->bLength);
 		goto Cleanup;
 	}
 
-	memcpy(InputDevice->HidDesc, desc, desc->bLength);
+	memcpy(input_device->hid_desc, desc, desc->bLength);
 
 	/* Save the report desc */
-	InputDevice->ReportDescSize = desc->desc[0].wDescriptorLength;
-	InputDevice->ReportDesc = kzalloc(InputDevice->ReportDescSize,
+	input_device->report_desc_size = desc->desc[0].wDescriptorLength;
+	input_device->report_desc = kzalloc(input_device->report_desc_size,
 					  GFP_KERNEL);
 
-	if (!InputDevice->ReportDesc) {
+	if (!input_device->report_desc) {
 		pr_err("unable to allocate report descriptor - size %d",
-			   InputDevice->ReportDescSize);
+			   input_device->report_desc_size);
 		goto Cleanup;
 	}
 
-	memcpy(InputDevice->ReportDesc,
+	memcpy(input_device->report_desc,
 	       ((unsigned char *)desc) + desc->bLength,
 	       desc->desc[0].wDescriptorLength);
 
@@ -385,7 +375,7 @@
 	ack.ack.header.size = 1;
 	ack.ack.reserved = 0;
 
-	ret = vmbus_sendpacket(InputDevice->Device->channel,
+	ret = vmbus_sendpacket(input_device->device->channel,
 			&ack,
 			sizeof(struct pipe_prt_msg) - sizeof(unsigned char) +
 			sizeof(struct synthhid_device_info_ack),
@@ -398,138 +388,143 @@
 		goto Cleanup;
 	}
 
-	InputDevice->device_wait_condition = 1;
-	wake_up(&InputDevice->DeviceInfoWaitEvent);
+	input_device->device_wait_condition = 1;
+	wake_up(&input_device->dev_info_wait_event);
 
 	return;
 
 Cleanup:
-	kfree(InputDevice->HidDesc);
-	InputDevice->HidDesc = NULL;
+	kfree(input_device->hid_desc);
+	input_device->hid_desc = NULL;
 
-	kfree(InputDevice->ReportDesc);
-	InputDevice->ReportDesc = NULL;
+	kfree(input_device->report_desc);
+	input_device->report_desc = NULL;
 
-	InputDevice->DeviceInfoStatus = -1;
-	InputDevice->device_wait_condition = 1;
-	wake_up(&InputDevice->DeviceInfoWaitEvent);
+	input_device->dev_info_status = -1;
+	input_device->device_wait_condition = 1;
+	wake_up(&input_device->dev_info_wait_event);
 }
 
-static void MousevscOnReceiveInputReport(struct mousevsc_dev *InputDevice, struct synthhid_input_report *InputReport)
+static void mousevsc_on_receive_input_report(struct mousevsc_dev *input_device,
+				struct synthhid_input_report *input_report)
 {
-	struct mousevsc_drv_obj *inputDriver;
+	struct hv_driver *input_drv;
 
-	if (!InputDevice->bInitializeComplete) {
-		pr_info("Initialization incomplete...ignoring InputReport msg");
+	if (!input_device->init_complete) {
+		pr_info("Initialization incomplete...ignoring input_report msg");
 		return;
 	}
 
-	inputDriver = (struct mousevsc_drv_obj *)InputDevice->Device->drv;
+	input_drv = drv_to_hv_drv(input_device->device->device.driver);
 
-	inputreport_callback(InputDevice->Device,
-			     InputReport->buffer,
-			     InputReport->header.size);
+	inputreport_callback(input_device->device,
+			     input_report->buffer,
+			     input_report->header.size);
 }
 
-static void MousevscOnReceive(struct hv_device *Device, struct vmpacket_descriptor *Packet)
+static void mousevsc_on_receive(struct hv_device *device,
+				struct vmpacket_descriptor *packet)
 {
-	struct pipe_prt_msg *pipeMsg;
-	struct synthhid_msg *hidMsg;
-	struct mousevsc_dev *inputDevice;
+	struct pipe_prt_msg *pipe_msg;
+	struct synthhid_msg *hid_msg;
+	struct mousevsc_dev *input_dev;
 
-	inputDevice = MustGetInputDevice(Device);
-	if (!inputDevice) {
+	input_dev = must_get_input_device(device);
+	if (!input_dev) {
 		pr_err("unable to get input device...device being destroyed?");
 		return;
 	}
 
-	pipeMsg = (struct pipe_prt_msg *)((unsigned long)Packet + (Packet->offset8 << 3));
+	pipe_msg = (struct pipe_prt_msg *)((unsigned long)packet +
+						(packet->offset8 << 3));
 
-	if (pipeMsg->type != PipeMessageData) {
+	if (pipe_msg->type != PipeMessageData) {
 		pr_err("unknown pipe msg type - type %d len %d",
-			   pipeMsg->type, pipeMsg->size);
-		PutInputDevice(Device);
+			   pipe_msg->type, pipe_msg->size);
+		put_input_device(device);
 		return ;
 	}
 
-	hidMsg = (struct synthhid_msg *)&pipeMsg->data[0];
+	hid_msg = (struct synthhid_msg *)&pipe_msg->data[0];
 
-	switch (hidMsg->header.type) {
+	switch (hid_msg->header.type) {
 	case SynthHidProtocolResponse:
-		memcpy(&inputDevice->ProtocolResp, pipeMsg,
-		       pipeMsg->size + sizeof(struct pipe_prt_msg) -
+		memcpy(&input_dev->protocol_resp, pipe_msg,
+		       pipe_msg->size + sizeof(struct pipe_prt_msg) -
 		       sizeof(unsigned char));
-		inputDevice->protocol_wait_condition = 1;
-		wake_up(&inputDevice->ProtocolWaitEvent);
+		input_dev->protocol_wait_condition = 1;
+		wake_up(&input_dev->protocol_wait_event);
 		break;
 
 	case SynthHidInitialDeviceInfo:
-		WARN_ON(pipeMsg->size >= sizeof(struct hv_input_dev_info));
+		WARN_ON(pipe_msg->size >= sizeof(struct hv_input_dev_info));
 
 		/*
 		 * Parse out the device info into device attr,
 		 * hid desc and report desc
 		 */
-		MousevscOnReceiveDeviceInfo(inputDevice,
-					    (struct synthhid_device_info *)&pipeMsg->data[0]);
+		mousevsc_on_receive_device_info(input_dev,
+			(struct synthhid_device_info *)&pipe_msg->data[0]);
 		break;
 	case SynthHidInputReport:
-		MousevscOnReceiveInputReport(inputDevice,
-					     (struct synthhid_input_report *)&pipeMsg->data[0]);
+		mousevsc_on_receive_input_report(input_dev,
+			(struct synthhid_input_report *)&pipe_msg->data[0]);
 
 		break;
 	default:
 		pr_err("unsupported hid msg type - type %d len %d",
-		       hidMsg->header.type, hidMsg->header.size);
+		       hid_msg->header.type, hid_msg->header.size);
 		break;
 	}
 
-	PutInputDevice(Device);
+	put_input_device(device);
 }
 
-static void MousevscOnChannelCallback(void *Context)
+static void mousevsc_on_channel_callback(void *context)
 {
 	const int packetSize = 0x100;
 	int ret = 0;
-	struct hv_device *device = (struct hv_device *)Context;
-	struct mousevsc_dev *inputDevice;
+	struct hv_device *device = (struct hv_device *)context;
+	struct mousevsc_dev *input_dev;
 
-	u32 bytesRecvd;
-	u64 requestId;
-	unsigned char packet[packetSize];
+	u32 bytes_recvd;
+	u64 req_id;
+	unsigned char packet[0x100];
 	struct vmpacket_descriptor *desc;
 	unsigned char	*buffer = packet;
 	int	bufferlen = packetSize;
 
-	inputDevice = MustGetInputDevice(device);
+	input_dev = must_get_input_device(device);
 
-	if (!inputDevice) {
+	if (!input_dev) {
 		pr_err("unable to get input device...device being destroyed?");
 		return;
 	}
 
 	do {
-		ret = vmbus_recvpacket_raw(device->channel, buffer, bufferlen, &bytesRecvd, &requestId);
+		ret = vmbus_recvpacket_raw(device->channel, buffer,
+					bufferlen, &bytes_recvd, &req_id);
 
 		if (ret == 0) {
-			if (bytesRecvd > 0) {
+			if (bytes_recvd > 0) {
 				desc = (struct vmpacket_descriptor *)buffer;
 
 				switch (desc->type) {
 					case VM_PKT_COMP:
-						MousevscOnSendCompletion(device,
-									 desc);
+						mousevsc_on_send_completion(
+							device, desc);
 						break;
 
 					case VM_PKT_DATA_INBAND:
-						MousevscOnReceive(device, desc);
+						mousevsc_on_receive(
+							device, desc);
 						break;
 
 					default:
 						pr_err("unhandled packet type %d, tid %llx len %d\n",
 							   desc->type,
-							   requestId,
-							   bytesRecvd);
+							   req_id,
+							   bytes_recvd);
 						break;
 				}
 
@@ -555,8 +550,8 @@
 			}
 		} else if (ret == -2) {
 			/* Handle large packet */
-			bufferlen = bytesRecvd;
-			buffer = kzalloc(bytesRecvd, GFP_KERNEL);
+			bufferlen = bytes_recvd;
+			buffer = kzalloc(bytes_recvd, GFP_KERNEL);
 
 			if (buffer == NULL) {
 				buffer = packet;
@@ -564,35 +559,35 @@
 
 				/* Try again next time around */
 				pr_err("unable to allocate buffer of size %d!",
-				       bytesRecvd);
+				       bytes_recvd);
 				break;
 			}
 		}
 	} while (1);
 
-	PutInputDevice(device);
+	put_input_device(device);
 
 	return;
 }
 
-static int MousevscConnectToVsp(struct hv_device *Device)
+static int mousevsc_connect_to_vsp(struct hv_device *device)
 {
 	int ret = 0;
-	struct mousevsc_dev *inputDevice;
+	struct mousevsc_dev *input_dev;
 	struct mousevsc_prt_msg *request;
 	struct mousevsc_prt_msg *response;
 
-	inputDevice = GetInputDevice(Device);
+	input_dev = get_input_device(device);
 
-	if (!inputDevice) {
+	if (!input_dev) {
 		pr_err("unable to get input device...device being destroyed?");
 		return -1;
 	}
 
-	init_waitqueue_head(&inputDevice->ProtocolWaitEvent);
-	init_waitqueue_head(&inputDevice->DeviceInfoWaitEvent);
+	init_waitqueue_head(&input_dev->protocol_wait_event);
+	init_waitqueue_head(&input_dev->dev_info_wait_event);
 
-	request = &inputDevice->ProtocolReq;
+	request = &input_dev->protocol_req;
 
 	/*
 	 * Now, initiate the vsc/vsp initialization protocol on the open channel
@@ -608,7 +603,7 @@
 
 	pr_info("synthhid protocol request...");
 
-	ret = vmbus_sendpacket(Device->channel, request,
+	ret = vmbus_sendpacket(device->channel, request,
 					sizeof(struct pipe_prt_msg) -
 					sizeof(unsigned char) +
 					sizeof(struct synthhid_protocol_request),
@@ -620,14 +615,15 @@
 		goto Cleanup;
 	}
 
-	inputDevice->protocol_wait_condition = 0;
-	wait_event_timeout(inputDevice->ProtocolWaitEvent, inputDevice->protocol_wait_condition, msecs_to_jiffies(1000));
-	if (inputDevice->protocol_wait_condition == 0) {
+	input_dev->protocol_wait_condition = 0;
+	wait_event_timeout(input_dev->protocol_wait_event,
+		input_dev->protocol_wait_condition, msecs_to_jiffies(1000));
+	if (input_dev->protocol_wait_condition == 0) {
 		ret = -ETIMEDOUT;
 		goto Cleanup;
 	}
 
-	response = &inputDevice->ProtocolResp;
+	response = &input_dev->protocol_resp;
 
 	if (!response->response.approved) {
 		pr_err("synthhid protocol request failed (version %d)",
@@ -636,9 +632,10 @@
 		goto Cleanup;
 	}
 
-	inputDevice->device_wait_condition = 0;
-	wait_event_timeout(inputDevice->DeviceInfoWaitEvent, inputDevice->device_wait_condition, msecs_to_jiffies(1000));
-	if (inputDevice->device_wait_condition == 0) {
+	input_dev->device_wait_condition = 0;
+	wait_event_timeout(input_dev->dev_info_wait_event,
+		input_dev->device_wait_condition, msecs_to_jiffies(1000));
+	if (input_dev->device_wait_condition == 0) {
 		ret = -ETIMEDOUT;
 		goto Cleanup;
 	}
@@ -647,94 +644,95 @@
 	 * We should have gotten the device attr, hid desc and report
 	 * desc at this point
 	 */
-	if (!inputDevice->DeviceInfoStatus)
+	if (!input_dev->dev_info_status)
 		pr_info("**** input channel up and running!! ****");
 	else
 		ret = -1;
 
 Cleanup:
-	PutInputDevice(Device);
+	put_input_device(device);
 
 	return ret;
 }
 
-static int MousevscOnDeviceAdd(struct hv_device *Device, void *AdditionalInfo)
+static int mousevsc_on_device_add(struct hv_device *device,
+					void *additional_info)
 {
 	int ret = 0;
-	struct mousevsc_dev *inputDevice;
-	struct mousevsc_drv_obj *inputDriver;
+	struct mousevsc_dev *input_dev;
+	struct hv_driver *input_drv;
 	struct hv_input_dev_info dev_info;
 
-	inputDevice = AllocInputDevice(Device);
+	input_dev = alloc_input_device(device);
 
-	if (!inputDevice) {
+	if (!input_dev) {
 		ret = -1;
 		goto Cleanup;
 	}
 
-	inputDevice->bInitializeComplete = false;
+	input_dev->init_complete = false;
 
 	/* Open the channel */
-	ret = vmbus_open(Device->channel,
+	ret = vmbus_open(device->channel,
 		INPUTVSC_SEND_RING_BUFFER_SIZE,
 		INPUTVSC_RECV_RING_BUFFER_SIZE,
 		NULL,
 		0,
-		MousevscOnChannelCallback,
-		Device
+		mousevsc_on_channel_callback,
+		device
 		);
 
 	if (ret != 0) {
 		pr_err("unable to open channel: %d", ret);
-		FreeInputDevice(inputDevice);
+		free_input_device(input_dev);
 		return -1;
 	}
 
 	pr_info("InputVsc channel open: %d", ret);
 
-	ret = MousevscConnectToVsp(Device);
+	ret = mousevsc_connect_to_vsp(device);
 
 	if (ret != 0) {
 		pr_err("unable to connect channel: %d", ret);
 
-		vmbus_close(Device->channel);
-		FreeInputDevice(inputDevice);
+		vmbus_close(device->channel);
+		free_input_device(input_dev);
 		return ret;
 	}
 
-	inputDriver = (struct mousevsc_drv_obj *)inputDevice->Device->drv;
+	input_drv = drv_to_hv_drv(input_dev->device->device.driver);
 
-	dev_info.vendor = inputDevice->hid_dev_info.vendor;
-	dev_info.product = inputDevice->hid_dev_info.product;
-	dev_info.version = inputDevice->hid_dev_info.version;
+	dev_info.vendor = input_dev->hid_dev_info.vendor;
+	dev_info.product = input_dev->hid_dev_info.product;
+	dev_info.version = input_dev->hid_dev_info.version;
 	strcpy(dev_info.name, "Microsoft Vmbus HID-compliant Mouse");
 
 	/* Send the device info back up */
-	deviceinfo_callback(Device, &dev_info);
+	deviceinfo_callback(device, &dev_info);
 
 	/* Send the report desc back up */
 	/* workaround SA-167 */
-	if (inputDevice->ReportDesc[14] == 0x25)
-		inputDevice->ReportDesc[14] = 0x29;
+	if (input_dev->report_desc[14] == 0x25)
+		input_dev->report_desc[14] = 0x29;
 
-	reportdesc_callback(Device, inputDevice->ReportDesc,
-			    inputDevice->ReportDescSize);
+	reportdesc_callback(device, input_dev->report_desc,
+			    input_dev->report_desc_size);
 
-	inputDevice->bInitializeComplete = true;
+	input_dev->init_complete = true;
 
 Cleanup:
 	return ret;
 }
 
-static int MousevscOnDeviceRemove(struct hv_device *Device)
+static int mousevsc_on_device_remove(struct hv_device *device)
 {
-	struct mousevsc_dev *inputDevice;
+	struct mousevsc_dev *input_dev;
 	int ret = 0;
 
 	pr_info("disabling input device (%p)...",
-		    Device->ext);
+		    device->ext);
 
-	inputDevice = ReleaseInputDevice(Device);
+	input_dev = release_input_device(device);
 
 
 	/*
@@ -743,29 +741,27 @@
 	 *
 	 * so that outstanding requests can be completed.
 	 */
-	while (inputDevice->NumOutstandingRequests) {
-		pr_info("waiting for %d requests to complete...", inputDevice->NumOutstandingRequests);
+	while (input_dev->num_outstanding_req) {
+		pr_info("waiting for %d requests to complete...",
+			input_dev->num_outstanding_req);
 
 		udelay(100);
 	}
 
-	pr_info("removing input device (%p)...", Device->ext);
+	pr_info("removing input device (%p)...", device->ext);
 
-	inputDevice = FinalReleaseInputDevice(Device);
+	input_dev = final_release_input_device(device);
 
-	pr_info("input device (%p) safe to remove", inputDevice);
+	pr_info("input device (%p) safe to remove", input_dev);
 
 	/* Close the channel */
-	vmbus_close(Device->channel);
+	vmbus_close(device->channel);
 
-	FreeInputDevice(inputDevice);
+	free_input_device(input_dev);
 
 	return ret;
 }
 
-static void MousevscOnCleanup(struct hv_driver *drv)
-{
-}
 
 /*
  * Data types
@@ -778,8 +774,6 @@
 };
 
 
-static struct  mousevsc_drv_obj g_mousevsc_drv;
-
 static void deviceinfo_callback(struct hv_device *dev, struct hv_input_dev_info *info)
 {
 	struct input_device_context *input_device_ctx =
@@ -813,24 +807,19 @@
 {
 }
 
-static int mousevsc_probe(struct device *device)
+static int mousevsc_probe(struct hv_device *dev)
 {
 	int ret = 0;
 
-	struct hv_driver *drv =
-		drv_to_hv_drv(device->driver);
-	struct mousevsc_drv_obj *mousevsc_drv_obj = drv->priv;
-
-	struct hv_device *device_obj = device_to_hv_device(device);
 	struct input_device_context *input_dev_ctx;
 
 	input_dev_ctx = kmalloc(sizeof(struct input_device_context),
 				GFP_KERNEL);
 
-	dev_set_drvdata(device, input_dev_ctx);
+	dev_set_drvdata(&dev->device, input_dev_ctx);
 
 	/* Call to the vsc driver to add the device */
-	ret = mousevsc_drv_obj->Base.dev_add(device_obj, NULL);
+	ret = mousevsc_on_device_add(dev, NULL);
 
 	if (ret != 0) {
 		DPRINT_ERR(INPUTVSC_DRV, "unable to add input vsc device");
@@ -841,35 +830,27 @@
 	return 0;
 }
 
-static int mousevsc_remove(struct device *device)
+static int mousevsc_remove(struct hv_device *dev)
 {
 	int ret = 0;
 
-	struct hv_driver *drv =
-		drv_to_hv_drv(device->driver);
-	struct mousevsc_drv_obj *mousevsc_drv_obj = drv->priv;
-
-	struct hv_device *device_obj = device_to_hv_device(device);
 	struct input_device_context *input_dev_ctx;
 
 	input_dev_ctx = kmalloc(sizeof(struct input_device_context),
 				GFP_KERNEL);
 
-	dev_set_drvdata(device, input_dev_ctx);
+	dev_set_drvdata(&dev->device, input_dev_ctx);
 
 	if (input_dev_ctx->connected) {
 		hidinput_disconnect(input_dev_ctx->hid_device);
 		input_dev_ctx->connected = 0;
 	}
 
-	if (!mousevsc_drv_obj->Base.dev_rm)
-		return -1;
-
 	/*
 	 * Call to the vsc driver to let it know that the device
 	 * is being removed
 	 */
-	ret = mousevsc_drv_obj->Base.dev_rm(device_obj);
+	ret = mousevsc_on_device_remove(dev);
 
 	if (ret != 0) {
 		DPRINT_ERR(INPUTVSC_DRV,
@@ -934,81 +915,28 @@
 	kfree(hid_dev);
 }
 
-static int mousevsc_drv_exit_cb(struct device *dev, void *data)
-{
-	struct device **curr = (struct device **)data;
-	*curr = dev;
 
-	return 1;
-}
+static struct  hv_driver mousevsc_drv = {
+	.probe = mousevsc_probe,
+	.remove = mousevsc_remove,
+};
 
 static void mousevsc_drv_exit(void)
 {
-	struct mousevsc_drv_obj *mousevsc_drv_obj = &g_mousevsc_drv;
-	struct hv_driver *drv = &g_mousevsc_drv.Base;
-	int ret;
-
-	struct device *current_dev = NULL;
-
-	while (1) {
-		current_dev = NULL;
-
-		/* Get the device */
-		ret = driver_for_each_device(&drv->driver, NULL,
-					     (void *)&current_dev,
-					     mousevsc_drv_exit_cb);
-		if (ret)
-			printk(KERN_ERR "Can't find mouse device!\n");
-
-		if (current_dev == NULL)
-			break;
-
-		/* Initiate removal from the top-down */
-		device_unregister(current_dev);
-	}
-
-	if (mousevsc_drv_obj->Base.cleanup)
-		mousevsc_drv_obj->Base.cleanup(&mousevsc_drv_obj->Base);
-
-	vmbus_child_driver_unregister(&drv->driver);
-
-	return;
-}
-
-static int mouse_vsc_initialize(struct hv_driver *Driver)
-{
-	struct mousevsc_drv_obj *inputDriver =
-		(struct mousevsc_drv_obj *)Driver;
-	int ret = 0;
-
-	Driver->name = driver_name;
-	memcpy(&Driver->dev_type, &mouse_guid,
-	       sizeof(struct hv_guid));
-
-	/* Setup the dispatch table */
-	inputDriver->Base.dev_add = MousevscOnDeviceAdd;
-	inputDriver->Base.dev_rm = MousevscOnDeviceRemove;
-	inputDriver->Base.cleanup = MousevscOnCleanup;
-
-	return ret;
+	vmbus_child_driver_unregister(&mousevsc_drv.driver);
 }
 
-
 static int __init mousevsc_init(void)
 {
-	struct mousevsc_drv_obj *input_drv_obj = &g_mousevsc_drv;
-	struct hv_driver *drv = &g_mousevsc_drv.Base;
+	struct hv_driver *drv = &mousevsc_drv;
 
 	DPRINT_INFO(INPUTVSC_DRV, "Hyper-V Mouse driver initializing.");
 
-	/* Callback to client driver to complete the initialization */
-	mouse_vsc_initialize(&input_drv_obj->Base);
-
-	drv->driver.name = input_drv_obj->Base.name;
-	drv->priv = input_drv_obj;
+	memcpy(&drv->dev_type, &mouse_guid,
+	       sizeof(struct hv_guid));
 
-	drv->driver.probe = mousevsc_probe;
-	drv->driver.remove = mousevsc_remove;
+	drv->driver.name = driver_name;
+	drv->name = driver_name;
 
 	/* The driver belongs to vmbus */
 	vmbus_child_driver_register(&drv->driver);
diff -druN linux-2.6.39-libre/drivers/staging/hv/hv_timesource.c linux-3.0-rc7-libre/drivers/staging/hv/hv_timesource.c
--- linux-2.6.39-libre/drivers/staging/hv/hv_timesource.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/hv/hv_timesource.c	2011-07-11 19:51:52.000000000 -0400
@@ -20,6 +20,7 @@
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  *
  */
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 
 #include <linux/version.h>
 #include <linux/clocksource.h>
@@ -91,7 +92,7 @@
 	if (!dmi_check_system(hv_timesource_dmi_table))
 		return -ENODEV;
 
-	printk(KERN_INFO "Registering HyperV clock source\n");
+	pr_info("Registering HyperV clock source\n");
 	return clocksource_register(&hyperv_cs);
 }
 
diff -druN linux-2.6.39-libre/drivers/staging/hv/hv_util.c linux-3.0-rc7-libre/drivers/staging/hv/hv_util.c
--- linux-2.6.39-libre/drivers/staging/hv/hv_util.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/hv/hv_util.c	2011-07-11 19:51:52.000000000 -0400
@@ -18,6 +18,8 @@
  *   Haiyang Zhang <haiyangz@microsoft.com>
  *   Hank Janssen  <hjanssen@microsoft.com>
  */
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/module.h>
@@ -27,16 +29,7 @@
 #include <linux/dmi.h>
 #include <linux/pci.h>
 
-#include "logging.h"
-#include "hv_api.h"
-#include "vmbus.h"
-#include "vmbus_packet_format.h"
-#include "vmbus_channel_interface.h"
-#include "version_info.h"
-#include "channel.h"
-#include "vmbus_private.h"
-#include "vmbus_api.h"
-#include "utils.h"
+#include "hyperv.h"
 #include "hv_kvp.h"
 
 static u8 *shut_txf_buf;
@@ -59,9 +52,6 @@
 			 PAGE_SIZE, &recvlen, &requestid);
 
 	if (recvlen > 0) {
-		DPRINT_DBG(VMBUS, "shutdown packet: len=%d, requestid=%lld",
-			   recvlen, requestid);
-
 		icmsghdrp = (struct icmsg_hdr *)&shut_txf_buf[
 			sizeof(struct vmbuspipe_hdr)];
 
@@ -79,17 +69,17 @@
 				icmsghdrp->status = HV_S_OK;
 				execute_shutdown = true;
 
-				DPRINT_INFO(VMBUS, "Shutdown request received -"
-					    " graceful shutdown initiated");
+				pr_info("Shutdown request received -"
+					    " graceful shutdown initiated\n");
 				break;
 			default:
 				icmsghdrp->status = HV_E_FAIL;
 				execute_shutdown = false;
 
-				DPRINT_INFO(VMBUS, "Shutdown request received -"
-					    " Invalid request");
+				pr_info("Shutdown request received -"
+					    " Invalid request\n");
 				break;
-			};
+			}
 		}
 
 		icmsghdrp->icflags = ICMSGHDRFLAG_TRANSACTION
@@ -159,9 +149,6 @@
 			 PAGE_SIZE, &recvlen, &requestid);
 
 	if (recvlen > 0) {
-		DPRINT_DBG(VMBUS, "timesync packet: recvlen=%d, requestid=%lld",
-			recvlen, requestid);
-
 		icmsghdrp = (struct icmsg_hdr *)&time_txf_buf[
 				sizeof(struct vmbuspipe_hdr)];
 
@@ -200,9 +187,6 @@
 			 PAGE_SIZE, &recvlen, &requestid);
 
 	if (recvlen > 0) {
-		DPRINT_DBG(VMBUS, "heartbeat packet: len=%d, requestid=%lld",
-			   recvlen, requestid);
-
 		icmsghdrp = (struct icmsg_hdr *)&hbeat_txf_buf[
 				sizeof(struct vmbuspipe_hdr)];
 
@@ -214,9 +198,6 @@
 					sizeof(struct vmbuspipe_hdr) +
 					sizeof(struct icmsg_hdr)];
 
-			DPRINT_DBG(VMBUS, "heartbeat seq = %lld",
-				   heartbeat_msg->seq_num);
-
 			heartbeat_msg->seq_num += 1;
 		}
 
@@ -254,7 +235,7 @@
 
 static int __init init_hyperv_utils(void)
 {
-	printk(KERN_INFO "Registering HyperV Utility Driver\n");
+	pr_info("Registering HyperV Utility Driver\n");
 
 	if (hv_kvp_init())
 		return -ENODEV;
@@ -268,52 +249,48 @@
 	hbeat_txf_buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
 
 	if (!shut_txf_buf || !time_txf_buf || !hbeat_txf_buf) {
-		printk(KERN_INFO
-		       "Unable to allocate memory for receive buffer\n");
+		pr_info("Unable to allocate memory for receive buffer\n");
 		kfree(shut_txf_buf);
 		kfree(time_txf_buf);
 		kfree(hbeat_txf_buf);
 		return -ENOMEM;
 	}
 
-	hv_cb_utils[HV_SHUTDOWN_MSG].channel->onchannel_callback =
-		&shutdown_onchannelcallback;
 	hv_cb_utils[HV_SHUTDOWN_MSG].callback = &shutdown_onchannelcallback;
 
-	hv_cb_utils[HV_TIMESYNC_MSG].channel->onchannel_callback =
-		&timesync_onchannelcallback;
 	hv_cb_utils[HV_TIMESYNC_MSG].callback = &timesync_onchannelcallback;
 
-	hv_cb_utils[HV_HEARTBEAT_MSG].channel->onchannel_callback =
-		&heartbeat_onchannelcallback;
 	hv_cb_utils[HV_HEARTBEAT_MSG].callback = &heartbeat_onchannelcallback;
 
-	hv_cb_utils[HV_KVP_MSG].channel->onchannel_callback =
-		&hv_kvp_onchannelcallback;
-
-
+	hv_cb_utils[HV_KVP_MSG].callback = &hv_kvp_onchannelcallback;
 
 	return 0;
 }
 
 static void exit_hyperv_utils(void)
 {
-	printk(KERN_INFO "De-Registered HyperV Utility Driver\n");
+	pr_info("De-Registered HyperV Utility Driver\n");
 
-	hv_cb_utils[HV_SHUTDOWN_MSG].channel->onchannel_callback =
-		&chn_cb_negotiate;
-	hv_cb_utils[HV_SHUTDOWN_MSG].callback = &chn_cb_negotiate;
+	if (hv_cb_utils[HV_SHUTDOWN_MSG].channel != NULL)
+		hv_cb_utils[HV_SHUTDOWN_MSG].channel->onchannel_callback =
+			&chn_cb_negotiate;
+	hv_cb_utils[HV_SHUTDOWN_MSG].callback = NULL;
 
-	hv_cb_utils[HV_TIMESYNC_MSG].channel->onchannel_callback =
-		&chn_cb_negotiate;
-	hv_cb_utils[HV_TIMESYNC_MSG].callback = &chn_cb_negotiate;
+	if (hv_cb_utils[HV_TIMESYNC_MSG].channel != NULL)
+		hv_cb_utils[HV_TIMESYNC_MSG].channel->onchannel_callback =
+			&chn_cb_negotiate;
+	hv_cb_utils[HV_TIMESYNC_MSG].callback = NULL;
 
-	hv_cb_utils[HV_HEARTBEAT_MSG].channel->onchannel_callback =
-		&chn_cb_negotiate;
-	hv_cb_utils[HV_HEARTBEAT_MSG].callback = &chn_cb_negotiate;
+	if (hv_cb_utils[HV_HEARTBEAT_MSG].channel != NULL)
+		hv_cb_utils[HV_HEARTBEAT_MSG].channel->onchannel_callback =
+			&chn_cb_negotiate;
+	hv_cb_utils[HV_HEARTBEAT_MSG].callback = NULL;
+
+	if (hv_cb_utils[HV_KVP_MSG].channel != NULL)
+		hv_cb_utils[HV_KVP_MSG].channel->onchannel_callback =
+			&chn_cb_negotiate;
+	hv_cb_utils[HV_KVP_MSG].callback = NULL;
 
-	hv_cb_utils[HV_KVP_MSG].channel->onchannel_callback =
-		&chn_cb_negotiate;
 	hv_kvp_deinit();
 
 	kfree(shut_txf_buf);
diff -druN linux-2.6.39-libre/drivers/staging/hv/hyperv.h linux-3.0-rc7-libre/drivers/staging/hv/hyperv.h
--- linux-2.6.39-libre/drivers/staging/hv/hyperv.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/staging/hv/hyperv.h	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,944 @@
+/*
+ *
+ * Copyright (c) 2011, Microsoft 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., 59 Temple
+ * Place - Suite 330, Boston, MA 02111-1307 USA.
+ *
+ * Authors:
+ *   Haiyang Zhang <haiyangz@microsoft.com>
+ *   Hank Janssen  <hjanssen@microsoft.com>
+ *   K. Y. Srinivasan <kys@microsoft.com>
+ *
+ */
+
+#ifndef _HYPERV_H
+#define _HYPERV_H
+
+#include <linux/scatterlist.h>
+#include <linux/list.h>
+#include <linux/timer.h>
+#include <linux/workqueue.h>
+#include <linux/completion.h>
+#include <linux/device.h>
+
+
+#include <asm/hyperv.h>
+
+struct hv_guid {
+	unsigned char data[16];
+};
+
+#define MAX_PAGE_BUFFER_COUNT				16
+#define MAX_MULTIPAGE_BUFFER_COUNT			32 /* 128K */
+
+#pragma pack(push, 1)
+
+/* Single-page buffer */
+struct hv_page_buffer {
+	u32 len;
+	u32 offset;
+	u64 pfn;
+};
+
+/* Multiple-page buffer */
+struct hv_multipage_buffer {
+	/* Length and Offset determines the # of pfns in the array */
+	u32 len;
+	u32 offset;
+	u64 pfn_array[MAX_MULTIPAGE_BUFFER_COUNT];
+};
+
+/* 0x18 includes the proprietary packet header */
+#define MAX_PAGE_BUFFER_PACKET		(0x18 +			\
+					(sizeof(struct hv_page_buffer) * \
+					 MAX_PAGE_BUFFER_COUNT))
+#define MAX_MULTIPAGE_BUFFER_PACKET	(0x18 +			\
+					 sizeof(struct hv_multipage_buffer))
+
+
+#pragma pack(pop)
+
+struct hv_ring_buffer {
+	/* Offset in bytes from the start of ring data below */
+	u32 write_index;
+
+	/* Offset in bytes from the start of ring data below */
+	u32 read_index;
+
+	u32 interrupt_mask;
+
+	/* Pad it to PAGE_SIZE so that data starts on page boundary */
+	u8	reserved[4084];
+
+	/* NOTE:
+	 * The interrupt_mask field is used only for channels but since our
+	 * vmbus connection also uses this data structure and its data starts
+	 * here, we commented out this field.
+	 */
+
+	/*
+	 * Ring data starts here + RingDataStartOffset
+	 * !!! DO NOT place any fields below this !!!
+	 */
+	u8 buffer[0];
+} __packed;
+
+struct hv_ring_buffer_info {
+	struct hv_ring_buffer *ring_buffer;
+	u32 ring_size;			/* Include the shared header */
+	spinlock_t ring_lock;
+
+	u32 ring_datasize;		/* < ring_size */
+	u32 ring_data_startoffset;
+};
+
+struct hv_ring_buffer_debug_info {
+	u32 current_interrupt_mask;
+	u32 current_read_index;
+	u32 current_write_index;
+	u32 bytes_avail_toread;
+	u32 bytes_avail_towrite;
+};
+
+/*
+ * 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.
+ *
+ * 3.1 - Added completed hv_utils driver. Shutdown/Heartbeat/Timesync
+ */
+#define HV_DRV_VERSION           "3.1"
+
+
+/*
+ * A revision number of vmbus that is used for ensuring both ends on a
+ * partition are using compatible versions.
+ */
+#define VMBUS_REVISION_NUMBER		13
+
+/* Make maximum size of pipe payload of 16K */
+#define MAX_PIPE_DATA_PAYLOAD		(sizeof(u8) * 16384)
+
+/* Define PipeMode values. */
+#define VMBUS_PIPE_TYPE_BYTE		0x00000000
+#define VMBUS_PIPE_TYPE_MESSAGE		0x00000004
+
+/* The size of the user defined data buffer for non-pipe offers. */
+#define MAX_USER_DEFINED_BYTES		120
+
+/* The size of the user defined data buffer for pipe offers. */
+#define MAX_PIPE_USER_DEFINED_BYTES	116
+
+/*
+ * At the center of the Channel Management library is the Channel Offer. This
+ * struct contains the fundamental information about an offer.
+ */
+struct vmbus_channel_offer {
+	struct hv_guid if_type;
+	struct hv_guid if_instance;
+	u64 int_latency; /* in 100ns units */
+	u32 if_revision;
+	u32 server_ctx_size;	/* in bytes */
+	u16 chn_flags;
+	u16 mmio_megabytes;		/* in bytes * 1024 * 1024 */
+
+	union {
+		/* Non-pipes: The user has MAX_USER_DEFINED_BYTES bytes. */
+		struct {
+			unsigned char user_def[MAX_USER_DEFINED_BYTES];
+		} std;
+
+		/*
+		 * Pipes:
+		 * The following sructure is an integrated pipe protocol, which
+		 * is implemented on top of standard user-defined data. Pipe
+		 * clients have MAX_PIPE_USER_DEFINED_BYTES left for their own
+		 * use.
+		 */
+		struct {
+			u32  pipe_mode;
+			unsigned char user_def[MAX_PIPE_USER_DEFINED_BYTES];
+		} pipe;
+	} u;
+	u32 padding;
+} __packed;
+
+/* Server Flags */
+#define VMBUS_CHANNEL_ENUMERATE_DEVICE_INTERFACE	1
+#define VMBUS_CHANNEL_SERVER_SUPPORTS_TRANSFER_PAGES	2
+#define VMBUS_CHANNEL_SERVER_SUPPORTS_GPADLS		4
+#define VMBUS_CHANNEL_NAMED_PIPE_MODE			0x10
+#define VMBUS_CHANNEL_LOOPBACK_OFFER			0x100
+#define VMBUS_CHANNEL_PARENT_OFFER			0x200
+#define VMBUS_CHANNEL_REQUEST_MONITORED_NOTIFICATION	0x400
+
+struct vmpacket_descriptor {
+	u16 type;
+	u16 offset8;
+	u16 len8;
+	u16 flags;
+	u64 trans_id;
+} __packed;
+
+struct vmpacket_header {
+	u32 prev_pkt_start_offset;
+	struct vmpacket_descriptor descriptor;
+} __packed;
+
+struct vmtransfer_page_range {
+	u32 byte_count;
+	u32 byte_offset;
+} __packed;
+
+struct vmtransfer_page_packet_header {
+	struct vmpacket_descriptor d;
+	u16 xfer_pageset_id;
+	bool sender_owns_set;
+	u8 reserved;
+	u32 range_cnt;
+	struct vmtransfer_page_range ranges[1];
+} __packed;
+
+struct vmgpadl_packet_header {
+	struct vmpacket_descriptor d;
+	u32 gpadl;
+	u32 reserved;
+} __packed;
+
+struct vmadd_remove_transfer_page_set {
+	struct vmpacket_descriptor d;
+	u32 gpadl;
+	u16 xfer_pageset_id;
+	u16 reserved;
+} __packed;
+
+/*
+ * This structure defines a range in guest physical space that can be made to
+ * look virtually contiguous.
+ */
+struct gpa_range {
+	u32 byte_count;
+	u32 byte_offset;
+	u64 pfn_array[0];
+};
+
+/*
+ * This is the format for an Establish Gpadl packet, which contains a handle by
+ * which this GPADL will be known and a set of GPA ranges associated with it.
+ * This can be converted to a MDL by the guest OS.  If there are multiple GPA
+ * ranges, then the resulting MDL will be "chained," representing multiple VA
+ * ranges.
+ */
+struct vmestablish_gpadl {
+	struct vmpacket_descriptor d;
+	u32 gpadl;
+	u32 range_cnt;
+	struct gpa_range range[1];
+} __packed;
+
+/*
+ * This is the format for a Teardown Gpadl packet, which indicates that the
+ * GPADL handle in the Establish Gpadl packet will never be referenced again.
+ */
+struct vmteardown_gpadl {
+	struct vmpacket_descriptor d;
+	u32 gpadl;
+	u32 reserved;	/* for alignment to a 8-byte boundary */
+} __packed;
+
+/*
+ * This is the format for a GPA-Direct packet, which contains a set of GPA
+ * ranges, in addition to commands and/or data.
+ */
+struct vmdata_gpa_direct {
+	struct vmpacket_descriptor d;
+	u32 reserved;
+	u32 range_cnt;
+	struct gpa_range range[1];
+} __packed;
+
+/* This is the format for a Additional Data Packet. */
+struct vmadditional_data {
+	struct vmpacket_descriptor d;
+	u64 total_bytes;
+	u32 offset;
+	u32 byte_cnt;
+	unsigned char data[1];
+} __packed;
+
+union vmpacket_largest_possible_header {
+	struct vmpacket_descriptor simple_hdr;
+	struct vmtransfer_page_packet_header xfer_page_hdr;
+	struct vmgpadl_packet_header gpadl_hdr;
+	struct vmadd_remove_transfer_page_set add_rm_xfer_page_hdr;
+	struct vmestablish_gpadl establish_gpadl_hdr;
+	struct vmteardown_gpadl teardown_gpadl_hdr;
+	struct vmdata_gpa_direct data_gpa_direct_hdr;
+};
+
+#define VMPACKET_DATA_START_ADDRESS(__packet)	\
+	(void *)(((unsigned char *)__packet) +	\
+	 ((struct vmpacket_descriptor)__packet)->offset8 * 8)
+
+#define VMPACKET_DATA_LENGTH(__packet)		\
+	((((struct vmpacket_descriptor)__packet)->len8 -	\
+	  ((struct vmpacket_descriptor)__packet)->offset8) * 8)
+
+#define VMPACKET_TRANSFER_MODE(__packet)	\
+	(((struct IMPACT)__packet)->type)
+
+enum vmbus_packet_type {
+	VM_PKT_INVALID				= 0x0,
+	VM_PKT_SYNCH				= 0x1,
+	VM_PKT_ADD_XFER_PAGESET			= 0x2,
+	VM_PKT_RM_XFER_PAGESET			= 0x3,
+	VM_PKT_ESTABLISH_GPADL			= 0x4,
+	VM_PKT_TEARDOWN_GPADL			= 0x5,
+	VM_PKT_DATA_INBAND			= 0x6,
+	VM_PKT_DATA_USING_XFER_PAGES		= 0x7,
+	VM_PKT_DATA_USING_GPADL			= 0x8,
+	VM_PKT_DATA_USING_GPA_DIRECT		= 0x9,
+	VM_PKT_CANCEL_REQUEST			= 0xa,
+	VM_PKT_COMP				= 0xb,
+	VM_PKT_DATA_USING_ADDITIONAL_PKT	= 0xc,
+	VM_PKT_ADDITIONAL_DATA			= 0xd
+};
+
+#define VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED	1
+
+
+/* Version 1 messages */
+enum vmbus_channel_message_type {
+	CHANNELMSG_INVALID			=  0,
+	CHANNELMSG_OFFERCHANNEL		=  1,
+	CHANNELMSG_RESCIND_CHANNELOFFER	=  2,
+	CHANNELMSG_REQUESTOFFERS		=  3,
+	CHANNELMSG_ALLOFFERS_DELIVERED	=  4,
+	CHANNELMSG_OPENCHANNEL		=  5,
+	CHANNELMSG_OPENCHANNEL_RESULT		=  6,
+	CHANNELMSG_CLOSECHANNEL		=  7,
+	CHANNELMSG_GPADL_HEADER		=  8,
+	CHANNELMSG_GPADL_BODY			=  9,
+	CHANNELMSG_GPADL_CREATED		= 10,
+	CHANNELMSG_GPADL_TEARDOWN		= 11,
+	CHANNELMSG_GPADL_TORNDOWN		= 12,
+	CHANNELMSG_RELID_RELEASED		= 13,
+	CHANNELMSG_INITIATE_CONTACT		= 14,
+	CHANNELMSG_VERSION_RESPONSE		= 15,
+	CHANNELMSG_UNLOAD			= 16,
+#ifdef VMBUS_FEATURE_PARENT_OR_PEER_MEMORY_MAPPED_INTO_A_CHILD
+	CHANNELMSG_VIEWRANGE_ADD		= 17,
+	CHANNELMSG_VIEWRANGE_REMOVE		= 18,
+#endif
+	CHANNELMSG_COUNT
+};
+
+struct vmbus_channel_message_header {
+	enum vmbus_channel_message_type msgtype;
+	u32 padding;
+} __packed;
+
+/* Query VMBus Version parameters */
+struct vmbus_channel_query_vmbus_version {
+	struct vmbus_channel_message_header header;
+	u32 version;
+} __packed;
+
+/* VMBus Version Supported parameters */
+struct vmbus_channel_version_supported {
+	struct vmbus_channel_message_header header;
+	bool version_supported;
+} __packed;
+
+/* Offer Channel parameters */
+struct vmbus_channel_offer_channel {
+	struct vmbus_channel_message_header header;
+	struct vmbus_channel_offer offer;
+	u32 child_relid;
+	u8 monitorid;
+	bool monitor_allocated;
+} __packed;
+
+/* Rescind Offer parameters */
+struct vmbus_channel_rescind_offer {
+	struct vmbus_channel_message_header header;
+	u32 child_relid;
+} __packed;
+
+/*
+ * Request Offer -- no parameters, SynIC message contains the partition ID
+ * Set Snoop -- no parameters, SynIC message contains the partition ID
+ * Clear Snoop -- no parameters, SynIC message contains the partition ID
+ * All Offers Delivered -- no parameters, SynIC message contains the partition
+ *		           ID
+ * Flush Client -- no parameters, SynIC message contains the partition ID
+ */
+
+/* Open Channel parameters */
+struct vmbus_channel_open_channel {
+	struct vmbus_channel_message_header header;
+
+	/* Identifies the specific VMBus channel that is being opened. */
+	u32 child_relid;
+
+	/* ID making a particular open request at a channel offer unique. */
+	u32 openid;
+
+	/* GPADL for the channel's ring buffer. */
+	u32 ringbuffer_gpadlhandle;
+
+	/* GPADL for the channel's server context save area. */
+	u32 server_contextarea_gpadlhandle;
+
+	/*
+	* The upstream ring buffer begins at offset zero in the memory
+	* described by RingBufferGpadlHandle. The downstream ring buffer
+	* follows it at this offset (in pages).
+	*/
+	u32 downstream_ringbuffer_pageoffset;
+
+	/* User-specific data to be passed along to the server endpoint. */
+	unsigned char userdata[MAX_USER_DEFINED_BYTES];
+} __packed;
+
+/* Open Channel Result parameters */
+struct vmbus_channel_open_result {
+	struct vmbus_channel_message_header header;
+	u32 child_relid;
+	u32 openid;
+	u32 status;
+} __packed;
+
+/* Close channel parameters; */
+struct vmbus_channel_close_channel {
+	struct vmbus_channel_message_header header;
+	u32 child_relid;
+} __packed;
+
+/* Channel Message GPADL */
+#define GPADL_TYPE_RING_BUFFER		1
+#define GPADL_TYPE_SERVER_SAVE_AREA	2
+#define GPADL_TYPE_TRANSACTION		8
+
+/*
+ * The number of PFNs in a GPADL message is defined by the number of
+ * pages that would be spanned by ByteCount and ByteOffset.  If the
+ * implied number of PFNs won't fit in this packet, there will be a
+ * follow-up packet that contains more.
+ */
+struct vmbus_channel_gpadl_header {
+	struct vmbus_channel_message_header header;
+	u32 child_relid;
+	u32 gpadl;
+	u16 range_buflen;
+	u16 rangecount;
+	struct gpa_range range[0];
+} __packed;
+
+/* This is the followup packet that contains more PFNs. */
+struct vmbus_channel_gpadl_body {
+	struct vmbus_channel_message_header header;
+	u32 msgnumber;
+	u32 gpadl;
+	u64 pfn[0];
+} __packed;
+
+struct vmbus_channel_gpadl_created {
+	struct vmbus_channel_message_header header;
+	u32 child_relid;
+	u32 gpadl;
+	u32 creation_status;
+} __packed;
+
+struct vmbus_channel_gpadl_teardown {
+	struct vmbus_channel_message_header header;
+	u32 child_relid;
+	u32 gpadl;
+} __packed;
+
+struct vmbus_channel_gpadl_torndown {
+	struct vmbus_channel_message_header header;
+	u32 gpadl;
+} __packed;
+
+#ifdef VMBUS_FEATURE_PARENT_OR_PEER_MEMORY_MAPPED_INTO_A_CHILD
+struct vmbus_channel_view_range_add {
+	struct vmbus_channel_message_header header;
+	PHYSICAL_ADDRESS viewrange_base;
+	u64 viewrange_length;
+	u32 child_relid;
+} __packed;
+
+struct vmbus_channel_view_range_remove {
+	struct vmbus_channel_message_header header;
+	PHYSICAL_ADDRESS viewrange_base;
+	u32 child_relid;
+} __packed;
+#endif
+
+struct vmbus_channel_relid_released {
+	struct vmbus_channel_message_header header;
+	u32 child_relid;
+} __packed;
+
+struct vmbus_channel_initiate_contact {
+	struct vmbus_channel_message_header header;
+	u32 vmbus_version_requested;
+	u32 padding2;
+	u64 interrupt_page;
+	u64 monitor_page1;
+	u64 monitor_page2;
+} __packed;
+
+struct vmbus_channel_version_response {
+	struct vmbus_channel_message_header header;
+	bool version_supported;
+} __packed;
+
+enum vmbus_channel_state {
+	CHANNEL_OFFER_STATE,
+	CHANNEL_OPENING_STATE,
+	CHANNEL_OPEN_STATE,
+};
+
+struct vmbus_channel {
+	struct list_head listentry;
+
+	struct hv_device *device_obj;
+
+	struct timer_list poll_timer; /* SA-111 workaround */
+	struct work_struct work;
+
+	enum vmbus_channel_state state;
+	/*
+	 * For util channels, stash the
+	 * the service index for easy access.
+	 */
+	s8 util_index;
+
+	struct vmbus_channel_offer_channel offermsg;
+	/*
+	 * These are based on the OfferMsg.MonitorId.
+	 * Save it here for easy access.
+	 */
+	u8 monitor_grp;
+	u8 monitor_bit;
+
+	u32 ringbuffer_gpadlhandle;
+
+	/* Allocated memory for ring buffer */
+	void *ringbuffer_pages;
+	u32 ringbuffer_pagecount;
+	struct hv_ring_buffer_info outbound;	/* send to parent */
+	struct hv_ring_buffer_info inbound;	/* receive from parent */
+	spinlock_t inbound_lock;
+	struct workqueue_struct *controlwq;
+
+	/* Channel callback are invoked in this workqueue context */
+	/* HANDLE dataWorkQueue; */
+
+	void (*onchannel_callback)(void *context);
+	void *channel_callback_context;
+};
+
+struct vmbus_channel_debug_info {
+	u32 relid;
+	enum vmbus_channel_state state;
+	struct hv_guid interfacetype;
+	struct hv_guid interface_instance;
+	u32 monitorid;
+	u32 servermonitor_pending;
+	u32 servermonitor_latency;
+	u32 servermonitor_connectionid;
+	u32 clientmonitor_pending;
+	u32 clientmonitor_latency;
+	u32 clientmonitor_connectionid;
+
+	struct hv_ring_buffer_debug_info inbound;
+	struct hv_ring_buffer_debug_info outbound;
+};
+
+/*
+ * Represents each channel msg on the vmbus connection This is a
+ * variable-size data structure depending on the msg type itself
+ */
+struct vmbus_channel_msginfo {
+	/* Bookkeeping stuff */
+	struct list_head msglistentry;
+
+	/* So far, this is only used to handle gpadl body message */
+	struct list_head submsglist;
+
+	/* Synchronize the request/response if needed */
+	struct completion  waitevent;
+	union {
+		struct vmbus_channel_version_supported version_supported;
+		struct vmbus_channel_open_result open_result;
+		struct vmbus_channel_gpadl_torndown gpadl_torndown;
+		struct vmbus_channel_gpadl_created gpadl_created;
+		struct vmbus_channel_version_response version_response;
+	} response;
+
+	u32 msgsize;
+	/*
+	 * The channel message that goes out on the "wire".
+	 * It will contain at minimum the VMBUS_CHANNEL_MESSAGE_HEADER header
+	 */
+	unsigned char msg[0];
+};
+
+
+void free_channel(struct vmbus_channel *channel);
+
+void vmbus_onmessage(void *context);
+
+int vmbus_request_offers(void);
+
+/* The format must be the same as struct vmdata_gpa_direct */
+struct vmbus_channel_packet_page_buffer {
+	u16 type;
+	u16 dataoffset8;
+	u16 length8;
+	u16 flags;
+	u64 transactionid;
+	u32 reserved;
+	u32 rangecount;
+	struct hv_page_buffer range[MAX_PAGE_BUFFER_COUNT];
+} __packed;
+
+/* The format must be the same as struct vmdata_gpa_direct */
+struct vmbus_channel_packet_multipage_buffer {
+	u16 type;
+	u16 dataoffset8;
+	u16 length8;
+	u16 flags;
+	u64 transactionid;
+	u32 reserved;
+	u32 rangecount;		/* Always 1 in this case */
+	struct hv_multipage_buffer range;
+} __packed;
+
+
+extern int vmbus_open(struct vmbus_channel *channel,
+			    u32 send_ringbuffersize,
+			    u32 recv_ringbuffersize,
+			    void *userdata,
+			    u32 userdatalen,
+			    void(*onchannel_callback)(void *context),
+			    void *context);
+
+extern void vmbus_close(struct vmbus_channel *channel);
+
+extern int vmbus_sendpacket(struct vmbus_channel *channel,
+				  const void *buffer,
+				  u32 bufferLen,
+				  u64 requestid,
+				  enum vmbus_packet_type type,
+				  u32 flags);
+
+extern int vmbus_sendpacket_pagebuffer(struct vmbus_channel *channel,
+					    struct hv_page_buffer pagebuffers[],
+					    u32 pagecount,
+					    void *buffer,
+					    u32 bufferlen,
+					    u64 requestid);
+
+extern int vmbus_sendpacket_multipagebuffer(struct vmbus_channel *channel,
+					struct hv_multipage_buffer *mpb,
+					void *buffer,
+					u32 bufferlen,
+					u64 requestid);
+
+extern int vmbus_establish_gpadl(struct vmbus_channel *channel,
+				      void *kbuffer,
+				      u32 size,
+				      u32 *gpadl_handle);
+
+extern int vmbus_teardown_gpadl(struct vmbus_channel *channel,
+				     u32 gpadl_handle);
+
+extern int vmbus_recvpacket(struct vmbus_channel *channel,
+				  void *buffer,
+				  u32 bufferlen,
+				  u32 *buffer_actual_len,
+				  u64 *requestid);
+
+extern int vmbus_recvpacket_raw(struct vmbus_channel *channel,
+				     void *buffer,
+				     u32 bufferlen,
+				     u32 *buffer_actual_len,
+				     u64 *requestid);
+
+extern void vmbus_onchannel_event(struct vmbus_channel *channel);
+
+extern void vmbus_get_debug_info(struct vmbus_channel *channel,
+				     struct vmbus_channel_debug_info *debug);
+
+extern void vmbus_ontimer(unsigned long data);
+
+
+#define LOWORD(dw) ((unsigned short)(dw))
+#define HIWORD(dw) ((unsigned short)(((unsigned int) (dw) >> 16) & 0xFFFF))
+
+
+#define VMBUS				0x0001
+#define STORVSC				0x0002
+#define NETVSC				0x0004
+#define INPUTVSC			0x0008
+#define BLKVSC				0x0010
+#define VMBUS_DRV			0x0100
+#define STORVSC_DRV			0x0200
+#define NETVSC_DRV			0x0400
+#define INPUTVSC_DRV		0x0800
+#define BLKVSC_DRV			0x1000
+
+#define ALL_MODULES			(VMBUS		|\
+							STORVSC		|\
+							NETVSC		|\
+							INPUTVSC	|\
+							BLKVSC		|\
+							VMBUS_DRV	|\
+							STORVSC_DRV	|\
+							NETVSC_DRV	|\
+							INPUTVSC_DRV|\
+							BLKVSC_DRV)
+
+/* Logging Level */
+#define ERROR_LVL				3
+#define WARNING_LVL				4
+#define INFO_LVL				6
+#define DEBUG_LVL				7
+#define DEBUG_LVL_ENTEREXIT			8
+#define DEBUG_RING_LVL				9
+
+extern unsigned int vmbus_loglevel;
+
+#define DPRINT(mod, lvl, fmt, args...) do {\
+	if ((mod & (HIWORD(vmbus_loglevel))) &&	\
+	    (lvl <= LOWORD(vmbus_loglevel)))	\
+		printk(KERN_DEBUG #mod": %s() " fmt "\n", __func__, ## args);\
+	} while (0)
+
+#define DPRINT_DBG(mod, fmt, args...) do {\
+	if ((mod & (HIWORD(vmbus_loglevel))) &&		\
+	    (DEBUG_LVL <= LOWORD(vmbus_loglevel)))	\
+		printk(KERN_DEBUG #mod": %s() " fmt "\n", __func__, ## args);\
+	} while (0)
+
+#define DPRINT_INFO(mod, fmt, args...) do {\
+	if ((mod & (HIWORD(vmbus_loglevel))) &&		\
+	    (INFO_LVL <= LOWORD(vmbus_loglevel)))	\
+		printk(KERN_INFO #mod": " fmt "\n", ## args);\
+	} while (0)
+
+#define DPRINT_WARN(mod, fmt, args...) do {\
+	if ((mod & (HIWORD(vmbus_loglevel))) &&		\
+	    (WARNING_LVL <= LOWORD(vmbus_loglevel)))	\
+		printk(KERN_WARNING #mod": WARNING! " fmt "\n", ## args);\
+	} while (0)
+
+#define DPRINT_ERR(mod, fmt, args...) do {\
+	if ((mod & (HIWORD(vmbus_loglevel))) &&		\
+	    (ERROR_LVL <= LOWORD(vmbus_loglevel)))	\
+		printk(KERN_ERR #mod": %s() ERROR!! " fmt "\n",	\
+		       __func__, ## args);\
+	} while (0)
+
+
+
+struct hv_driver;
+struct hv_device;
+
+struct hv_dev_port_info {
+	u32 int_mask;
+	u32 read_idx;
+	u32 write_idx;
+	u32 bytes_avail_toread;
+	u32 bytes_avail_towrite;
+};
+
+struct hv_device_info {
+	u32 chn_id;
+	u32 chn_state;
+	struct hv_guid chn_type;
+	struct hv_guid chn_instance;
+
+	u32 monitor_id;
+	u32 server_monitor_pending;
+	u32 server_monitor_latency;
+	u32 server_monitor_conn_id;
+	u32 client_monitor_pending;
+	u32 client_monitor_latency;
+	u32 client_monitor_conn_id;
+
+	struct hv_dev_port_info inbound;
+	struct hv_dev_port_info outbound;
+};
+
+/* Base driver object */
+struct hv_driver {
+	const char *name;
+
+	/* the device type supported by this driver */
+	struct hv_guid dev_type;
+
+	struct device_driver driver;
+
+	int (*probe)(struct hv_device *);
+	int (*remove)(struct hv_device *);
+	void (*shutdown)(struct hv_device *);
+
+};
+
+/* Base device object */
+struct hv_device {
+	/* the device type id of this device */
+	struct hv_guid dev_type;
+
+	/* the device instance id of this device */
+	struct hv_guid dev_instance;
+
+	struct device device;
+
+	struct vmbus_channel *channel;
+
+	/* Device extension; */
+	void *ext;
+};
+
+
+static inline struct hv_device *device_to_hv_device(struct device *d)
+{
+	return container_of(d, struct hv_device, device);
+}
+
+static inline struct hv_driver *drv_to_hv_drv(struct device_driver *d)
+{
+	return container_of(d, struct hv_driver, driver);
+}
+
+
+/* Vmbus interface */
+int vmbus_child_driver_register(struct device_driver *drv);
+void vmbus_child_driver_unregister(struct device_driver *drv);
+
+/*
+ * Common header for Hyper-V ICs
+ */
+
+#define ICMSGTYPE_NEGOTIATE		0
+#define ICMSGTYPE_HEARTBEAT		1
+#define ICMSGTYPE_KVPEXCHANGE		2
+#define ICMSGTYPE_SHUTDOWN		3
+#define ICMSGTYPE_TIMESYNC		4
+#define ICMSGTYPE_VSS			5
+
+#define ICMSGHDRFLAG_TRANSACTION	1
+#define ICMSGHDRFLAG_REQUEST		2
+#define ICMSGHDRFLAG_RESPONSE		4
+
+#define HV_S_OK				0x00000000
+#define HV_E_FAIL			0x80004005
+#define HV_ERROR_NOT_SUPPORTED		0x80070032
+#define HV_ERROR_MACHINE_LOCKED		0x800704F7
+
+struct vmbuspipe_hdr {
+	u32 flags;
+	u32 msgsize;
+} __packed;
+
+struct ic_version {
+	u16 major;
+	u16 minor;
+} __packed;
+
+struct icmsg_hdr {
+	struct ic_version icverframe;
+	u16 icmsgtype;
+	struct ic_version icvermsg;
+	u16 icmsgsize;
+	u32 status;
+	u8 ictransaction_id;
+	u8 icflags;
+	u8 reserved[2];
+} __packed;
+
+struct icmsg_negotiate {
+	u16 icframe_vercnt;
+	u16 icmsg_vercnt;
+	u32 reserved;
+	struct ic_version icversion_data[1]; /* any size array */
+} __packed;
+
+struct shutdown_msg_data {
+	u32 reason_code;
+	u32 timeout_seconds;
+	u32 flags;
+	u8  display_message[2048];
+} __packed;
+
+struct heartbeat_msg_data {
+	u64 seq_num;
+	u32 reserved[8];
+} __packed;
+
+/* Time Sync IC defs */
+#define ICTIMESYNCFLAG_PROBE	0
+#define ICTIMESYNCFLAG_SYNC	1
+#define ICTIMESYNCFLAG_SAMPLE	2
+
+#ifdef __x86_64__
+#define WLTIMEDELTA	116444736000000000L	/* in 100ns unit */
+#else
+#define WLTIMEDELTA	116444736000000000LL
+#endif
+
+struct ictimesync_data {
+	u64 parenttime;
+	u64 childtime;
+	u64 roundtriptime;
+	u8 flags;
+} __packed;
+
+/* Index for each IC struct in array hv_cb_utils[] */
+#define HV_SHUTDOWN_MSG		0
+#define HV_TIMESYNC_MSG		1
+#define HV_HEARTBEAT_MSG	2
+#define HV_KVP_MSG		3
+
+struct hyperv_service_callback {
+	u8 msg_type;
+	char *log_msg;
+	unsigned char data[16];
+	struct vmbus_channel *channel;
+	void (*callback) (void *context);
+};
+
+extern void prep_negotiate_resp(struct icmsg_hdr *,
+				struct icmsg_negotiate *, u8 *);
+extern void chn_cb_negotiate(void *);
+extern struct hyperv_service_callback hv_cb_utils[];
+
+#endif /* _HYPERV_H */
diff -druN linux-2.6.39-libre/drivers/staging/hv/hyperv_net.h linux-3.0-rc7-libre/drivers/staging/hv/hyperv_net.h
--- linux-2.6.39-libre/drivers/staging/hv/hyperv_net.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/staging/hv/hyperv_net.h	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,1067 @@
+/*
+ *
+ * Copyright (c) 2011, Microsoft 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., 59 Temple
+ * Place - Suite 330, Boston, MA 02111-1307 USA.
+ *
+ * Authors:
+ *   Haiyang Zhang <haiyangz@microsoft.com>
+ *   Hank Janssen  <hjanssen@microsoft.com>
+ *   K. Y. Srinivasan <kys@microsoft.com>
+ *
+ */
+
+#ifndef _HYPERV_NET_H
+#define _HYPERV_NET_H
+
+#include <linux/list.h>
+#include "hyperv.h"
+
+/* Fwd declaration */
+struct hv_netvsc_packet;
+
+/* Represent the xfer page packet which contains 1 or more netvsc packet */
+struct xferpage_packet {
+	struct list_head list_ent;
+
+	/* # of netvsc packets this xfer packet contains */
+	u32 count;
+};
+
+/* The number of pages which are enough to cover jumbo frame buffer. */
+#define NETVSC_PACKET_MAXPAGE		4
+
+/*
+ * Represent netvsc packet which contains 1 RNDIS and 1 ethernet frame
+ * within the RNDIS
+ */
+struct hv_netvsc_packet {
+	/* Bookkeeping stuff */
+	struct list_head list_ent;
+
+	struct hv_device *device;
+	bool is_data_pkt;
+
+	/*
+	 * Valid only for receives when we break a xfer page packet
+	 * into multiple netvsc packets
+	 */
+	struct xferpage_packet *xfer_page_pkt;
+
+	union {
+		struct {
+			u64 recv_completion_tid;
+			void *recv_completion_ctx;
+			void (*recv_completion)(void *context);
+		} recv;
+		struct {
+			u64 send_completion_tid;
+			void *send_completion_ctx;
+			void (*send_completion)(void *context);
+		} send;
+	} completion;
+
+	/* This points to the memory after page_buf */
+	void *extension;
+
+	u32 total_data_buflen;
+	/* Points to the send/receive buffer where the ethernet frame is */
+	u32 page_buf_cnt;
+	struct hv_page_buffer page_buf[NETVSC_PACKET_MAXPAGE];
+};
+
+struct netvsc_device_info {
+	unsigned char mac_adr[6];
+	bool link_state;	/* 0 - link up, 1 - link down */
+	int  ring_size;
+};
+
+/* Interface */
+int netvsc_device_add(struct hv_device *device, void *additional_info);
+int netvsc_device_remove(struct hv_device *device);
+int netvsc_send(struct hv_device *device,
+		struct hv_netvsc_packet *packet);
+void netvsc_linkstatus_callback(struct hv_device *device_obj,
+				unsigned int status);
+int netvsc_recv_callback(struct hv_device *device_obj,
+			struct hv_netvsc_packet *packet);
+int netvsc_initialize(struct hv_driver *drv);
+int rndis_filter_open(struct hv_device *dev);
+int rndis_filter_close(struct hv_device *dev);
+int rndis_filte_device_add(struct hv_device *dev,
+			void *additional_info);
+int rndis_filter_device_remove(struct hv_device *dev);
+int rndis_filter_receive(struct hv_device *dev,
+			struct hv_netvsc_packet *pkt);
+
+
+
+int rndis_filter_send(struct hv_device *dev,
+			struct hv_netvsc_packet *pkt);
+
+#define NVSP_INVALID_PROTOCOL_VERSION	((u32)0xFFFFFFFF)
+
+#define NVSP_PROTOCOL_VERSION_1		2
+#define NVSP_MIN_PROTOCOL_VERSION	NVSP_PROTOCOL_VERSION_1
+#define NVSP_MAX_PROTOCOL_VERSION	NVSP_PROTOCOL_VERSION_1
+
+enum {
+	NVSP_MSG_TYPE_NONE = 0,
+
+	/* Init Messages */
+	NVSP_MSG_TYPE_INIT			= 1,
+	NVSP_MSG_TYPE_INIT_COMPLETE		= 2,
+
+	NVSP_VERSION_MSG_START			= 100,
+
+	/* Version 1 Messages */
+	NVSP_MSG1_TYPE_SEND_NDIS_VER		= NVSP_VERSION_MSG_START,
+
+	NVSP_MSG1_TYPE_SEND_RECV_BUF,
+	NVSP_MSG1_TYPE_SEND_RECV_BUF_COMPLETE,
+	NVSP_MSG1_TYPE_REVOKE_RECV_BUF,
+
+	NVSP_MSG1_TYPE_SEND_SEND_BUF,
+	NVSP_MSG1_TYPE_SEND_SEND_BUF_COMPLETE,
+	NVSP_MSG1_TYPE_REVOKE_SEND_BUF,
+
+	NVSP_MSG1_TYPE_SEND_RNDIS_PKT,
+	NVSP_MSG1_TYPE_SEND_RNDIS_PKT_COMPLETE,
+
+	/*
+	 * This should be set to the number of messages for the version with
+	 * the maximum number of messages.
+	 */
+	NVSP_NUM_MSG_PER_VERSION		= 9,
+};
+
+enum {
+	NVSP_STAT_NONE = 0,
+	NVSP_STAT_SUCCESS,
+	NVSP_STAT_FAIL,
+	NVSP_STAT_PROTOCOL_TOO_NEW,
+	NVSP_STAT_PROTOCOL_TOO_OLD,
+	NVSP_STAT_INVALID_RNDIS_PKT,
+	NVSP_STAT_BUSY,
+	NVSP_STAT_MAX,
+};
+
+struct nvsp_message_header {
+	u32 msg_type;
+};
+
+/* Init Messages */
+
+/*
+ * This message is used by the VSC to initialize the channel after the channels
+ * has been opened. This message should never include anything other then
+ * versioning (i.e. this message will be the same for ever).
+ */
+struct nvsp_message_init {
+	u32 min_protocol_ver;
+	u32 max_protocol_ver;
+} __packed;
+
+/*
+ * This message is used by the VSP to complete the initialization of the
+ * channel. This message should never include anything other then versioning
+ * (i.e. this message will be the same for ever).
+ */
+struct nvsp_message_init_complete {
+	u32 negotiated_protocol_ver;
+	u32 max_mdl_chain_len;
+	u32 status;
+} __packed;
+
+union nvsp_message_init_uber {
+	struct nvsp_message_init init;
+	struct nvsp_message_init_complete init_complete;
+} __packed;
+
+/* Version 1 Messages */
+
+/*
+ * This message is used by the VSC to send the NDIS version to the VSP. The VSP
+ * can use this information when handling OIDs sent by the VSC.
+ */
+struct nvsp_1_message_send_ndis_version {
+	u32 ndis_major_ver;
+	u32 ndis_minor_ver;
+} __packed;
+
+/*
+ * This message is used by the VSC to send a receive buffer to the VSP. The VSP
+ * can then use the receive buffer to send data to the VSC.
+ */
+struct nvsp_1_message_send_receive_buffer {
+	u32 gpadl_handle;
+	u16 id;
+} __packed;
+
+struct nvsp_1_receive_buffer_section {
+	u32 offset;
+	u32 sub_alloc_size;
+	u32 num_sub_allocs;
+	u32 end_offset;
+} __packed;
+
+/*
+ * This message is used by the VSP to acknowledge a receive buffer send by the
+ * VSC. This message must be sent by the VSP before the VSP uses the receive
+ * buffer.
+ */
+struct nvsp_1_message_send_receive_buffer_complete {
+	u32 status;
+	u32 num_sections;
+
+	/*
+	 * The receive buffer is split into two parts, a large suballocation
+	 * section and a small suballocation section. These sections are then
+	 * suballocated by a certain size.
+	 */
+
+	/*
+	 * For example, the following break up of the receive buffer has 6
+	 * large suballocations and 10 small suballocations.
+	 */
+
+	/*
+	 * |            Large Section          |  |   Small Section   |
+	 * ------------------------------------------------------------
+	 * |     |     |     |     |     |     |  | | | | | | | | | | |
+	 * |                                      |
+	 *  LargeOffset                            SmallOffset
+	 */
+
+	struct nvsp_1_receive_buffer_section sections[1];
+} __packed;
+
+/*
+ * This message is sent by the VSC to revoke the receive buffer.  After the VSP
+ * completes this transaction, the vsp should never use the receive buffer
+ * again.
+ */
+struct nvsp_1_message_revoke_receive_buffer {
+	u16 id;
+};
+
+/*
+ * This message is used by the VSC to send a send buffer to the VSP. The VSC
+ * can then use the send buffer to send data to the VSP.
+ */
+struct nvsp_1_message_send_send_buffer {
+	u32 gpadl_handle;
+	u16 id;
+} __packed;
+
+/*
+ * This message is used by the VSP to acknowledge a send buffer sent by the
+ * VSC. This message must be sent by the VSP before the VSP uses the sent
+ * buffer.
+ */
+struct nvsp_1_message_send_send_buffer_complete {
+	u32 status;
+
+	/*
+	 * The VSC gets to choose the size of the send buffer and the VSP gets
+	 * to choose the sections size of the buffer.  This was done to enable
+	 * dynamic reconfigurations when the cost of GPA-direct buffers
+	 * decreases.
+	 */
+	u32 section_size;
+} __packed;
+
+/*
+ * This message is sent by the VSC to revoke the send buffer.  After the VSP
+ * completes this transaction, the vsp should never use the send buffer again.
+ */
+struct nvsp_1_message_revoke_send_buffer {
+	u16 id;
+};
+
+/*
+ * This message is used by both the VSP and the VSC to send a RNDIS message to
+ * the opposite channel endpoint.
+ */
+struct nvsp_1_message_send_rndis_packet {
+	/*
+	 * This field is specified by RNIDS. They assume there's two different
+	 * channels of communication. However, the Network VSP only has one.
+	 * Therefore, the channel travels with the RNDIS packet.
+	 */
+	u32 channel_type;
+
+	/*
+	 * This field is used to send part or all of the data through a send
+	 * buffer. This values specifies an index into the send buffer. If the
+	 * index is 0xFFFFFFFF, then the send buffer is not being used and all
+	 * of the data was sent through other VMBus mechanisms.
+	 */
+	u32 send_buf_section_index;
+	u32 send_buf_section_size;
+} __packed;
+
+/*
+ * This message is used by both the VSP and the VSC to complete a RNDIS message
+ * to the opposite channel endpoint. At this point, the initiator of this
+ * message cannot use any resources associated with the original RNDIS packet.
+ */
+struct nvsp_1_message_send_rndis_packet_complete {
+	u32 status;
+};
+
+union nvsp_1_message_uber {
+	struct nvsp_1_message_send_ndis_version send_ndis_ver;
+
+	struct nvsp_1_message_send_receive_buffer send_recv_buf;
+	struct nvsp_1_message_send_receive_buffer_complete
+						send_recv_buf_complete;
+	struct nvsp_1_message_revoke_receive_buffer revoke_recv_buf;
+
+	struct nvsp_1_message_send_send_buffer send_send_buf;
+	struct nvsp_1_message_send_send_buffer_complete send_send_buf_complete;
+	struct nvsp_1_message_revoke_send_buffer revoke_send_buf;
+
+	struct nvsp_1_message_send_rndis_packet send_rndis_pkt;
+	struct nvsp_1_message_send_rndis_packet_complete
+						send_rndis_pkt_complete;
+} __packed;
+
+union nvsp_all_messages {
+	union nvsp_message_init_uber init_msg;
+	union nvsp_1_message_uber v1_msg;
+} __packed;
+
+/* ALL Messages */
+struct nvsp_message {
+	struct nvsp_message_header hdr;
+	union nvsp_all_messages msg;
+} __packed;
+
+
+
+
+/* #define NVSC_MIN_PROTOCOL_VERSION		1 */
+/* #define NVSC_MAX_PROTOCOL_VERSION		1 */
+
+#define NETVSC_SEND_BUFFER_SIZE			(64*1024)	/* 64K */
+#define NETVSC_SEND_BUFFER_ID			0xface
+
+
+#define NETVSC_RECEIVE_BUFFER_SIZE		(1024*1024)	/* 1MB */
+
+#define NETVSC_RECEIVE_BUFFER_ID		0xcafe
+
+#define NETVSC_RECEIVE_SG_COUNT			1
+
+/* Preallocated receive packets */
+#define NETVSC_RECEIVE_PACKETLIST_COUNT		256
+
+#define NETVSC_PACKET_SIZE                      2048
+
+/* Per netvsc channel-specific */
+struct netvsc_device {
+	struct hv_device *dev;
+
+	atomic_t refcnt;
+	atomic_t num_outstanding_sends;
+	/*
+	 * List of free preallocated hv_netvsc_packet to represent receive
+	 * packet
+	 */
+	struct list_head recv_pkt_list;
+	spinlock_t recv_pkt_list_lock;
+
+	/* Send buffer allocated by us but manages by NetVSP */
+	void *send_buf;
+	u32 send_buf_size;
+	u32 send_buf_gpadl_handle;
+	u32 send_section_size;
+
+	/* Receive buffer allocated by us but manages by NetVSP */
+	void *recv_buf;
+	u32 recv_buf_size;
+	u32 recv_buf_gpadl_handle;
+	u32 recv_section_cnt;
+	struct nvsp_1_receive_buffer_section *recv_section;
+
+	/* Used for NetVSP initialization protocol */
+	struct completion channel_init_wait;
+	struct nvsp_message channel_init_pkt;
+
+	struct nvsp_message revoke_packet;
+	/* unsigned char HwMacAddr[HW_MACADDR_LEN]; */
+
+	/* Holds rndis device info */
+	void *extension;
+};
+
+
+/*  Status codes */
+
+
+#ifndef STATUS_SUCCESS
+#define STATUS_SUCCESS				(0x00000000L)
+#endif
+
+#ifndef STATUS_UNSUCCESSFUL
+#define STATUS_UNSUCCESSFUL			(0xC0000001L)
+#endif
+
+#ifndef STATUS_PENDING
+#define STATUS_PENDING				(0x00000103L)
+#endif
+
+#ifndef STATUS_INSUFFICIENT_RESOURCES
+#define STATUS_INSUFFICIENT_RESOURCES		(0xC000009AL)
+#endif
+
+#ifndef STATUS_BUFFER_OVERFLOW
+#define STATUS_BUFFER_OVERFLOW			(0x80000005L)
+#endif
+
+#ifndef STATUS_NOT_SUPPORTED
+#define STATUS_NOT_SUPPORTED			(0xC00000BBL)
+#endif
+
+#define RNDIS_STATUS_SUCCESS			(STATUS_SUCCESS)
+#define RNDIS_STATUS_PENDING			(STATUS_PENDING)
+#define RNDIS_STATUS_NOT_RECOGNIZED		(0x00010001L)
+#define RNDIS_STATUS_NOT_COPIED			(0x00010002L)
+#define RNDIS_STATUS_NOT_ACCEPTED		(0x00010003L)
+#define RNDIS_STATUS_CALL_ACTIVE		(0x00010007L)
+
+#define RNDIS_STATUS_ONLINE			(0x40010003L)
+#define RNDIS_STATUS_RESET_START		(0x40010004L)
+#define RNDIS_STATUS_RESET_END			(0x40010005L)
+#define RNDIS_STATUS_RING_STATUS		(0x40010006L)
+#define RNDIS_STATUS_CLOSED			(0x40010007L)
+#define RNDIS_STATUS_WAN_LINE_UP		(0x40010008L)
+#define RNDIS_STATUS_WAN_LINE_DOWN		(0x40010009L)
+#define RNDIS_STATUS_WAN_FRAGMENT		(0x4001000AL)
+#define RNDIS_STATUS_MEDIA_CONNECT		(0x4001000BL)
+#define RNDIS_STATUS_MEDIA_DISCONNECT		(0x4001000CL)
+#define RNDIS_STATUS_HARDWARE_LINE_UP		(0x4001000DL)
+#define RNDIS_STATUS_HARDWARE_LINE_DOWN		(0x4001000EL)
+#define RNDIS_STATUS_INTERFACE_UP		(0x4001000FL)
+#define RNDIS_STATUS_INTERFACE_DOWN		(0x40010010L)
+#define RNDIS_STATUS_MEDIA_BUSY			(0x40010011L)
+#define RNDIS_STATUS_MEDIA_SPECIFIC_INDICATION	(0x40010012L)
+#define RNDIS_STATUS_WW_INDICATION		RDIA_SPECIFIC_INDICATION
+#define RNDIS_STATUS_LINK_SPEED_CHANGE		(0x40010013L)
+
+#define RNDIS_STATUS_NOT_RESETTABLE		(0x80010001L)
+#define RNDIS_STATUS_SOFT_ERRORS		(0x80010003L)
+#define RNDIS_STATUS_HARD_ERRORS		(0x80010004L)
+#define RNDIS_STATUS_BUFFER_OVERFLOW		(STATUS_BUFFER_OVERFLOW)
+
+#define RNDIS_STATUS_FAILURE			(STATUS_UNSUCCESSFUL)
+#define RNDIS_STATUS_RESOURCES			(STATUS_INSUFFICIENT_RESOURCES)
+#define RNDIS_STATUS_CLOSING			(0xC0010002L)
+#define RNDIS_STATUS_BAD_VERSION		(0xC0010004L)
+#define RNDIS_STATUS_BAD_CHARACTERISTICS	(0xC0010005L)
+#define RNDIS_STATUS_ADAPTER_NOT_FOUND		(0xC0010006L)
+#define RNDIS_STATUS_OPEN_FAILED		(0xC0010007L)
+#define RNDIS_STATUS_DEVICE_FAILED		(0xC0010008L)
+#define RNDIS_STATUS_MULTICAST_FULL		(0xC0010009L)
+#define RNDIS_STATUS_MULTICAST_EXISTS		(0xC001000AL)
+#define RNDIS_STATUS_MULTICAST_NOT_FOUND	(0xC001000BL)
+#define RNDIS_STATUS_REQUEST_ABORTED		(0xC001000CL)
+#define RNDIS_STATUS_RESET_IN_PROGRESS		(0xC001000DL)
+#define RNDIS_STATUS_CLOSING_INDICATING		(0xC001000EL)
+#define RNDIS_STATUS_NOT_SUPPORTED		(STATUS_NOT_SUPPORTED)
+#define RNDIS_STATUS_INVALID_PACKET		(0xC001000FL)
+#define RNDIS_STATUS_OPEN_LIST_FULL		(0xC0010010L)
+#define RNDIS_STATUS_ADAPTER_NOT_READY		(0xC0010011L)
+#define RNDIS_STATUS_ADAPTER_NOT_OPEN		(0xC0010012L)
+#define RNDIS_STATUS_NOT_INDICATING		(0xC0010013L)
+#define RNDIS_STATUS_INVALID_LENGTH		(0xC0010014L)
+#define RNDIS_STATUS_INVALID_DATA		(0xC0010015L)
+#define RNDIS_STATUS_BUFFER_TOO_SHORT		(0xC0010016L)
+#define RNDIS_STATUS_INVALID_OID		(0xC0010017L)
+#define RNDIS_STATUS_ADAPTER_REMOVED		(0xC0010018L)
+#define RNDIS_STATUS_UNSUPPORTED_MEDIA		(0xC0010019L)
+#define RNDIS_STATUS_GROUP_ADDRESS_IN_USE	(0xC001001AL)
+#define RNDIS_STATUS_FILE_NOT_FOUND		(0xC001001BL)
+#define RNDIS_STATUS_ERROR_READING_FILE		(0xC001001CL)
+#define RNDIS_STATUS_ALREADY_MAPPED		(0xC001001DL)
+#define RNDIS_STATUS_RESOURCE_CONFLICT		(0xC001001EL)
+#define RNDIS_STATUS_NO_CABLE			(0xC001001FL)
+
+#define RNDIS_STATUS_INVALID_SAP		(0xC0010020L)
+#define RNDIS_STATUS_SAP_IN_USE			(0xC0010021L)
+#define RNDIS_STATUS_INVALID_ADDRESS		(0xC0010022L)
+#define RNDIS_STATUS_VC_NOT_ACTIVATED		(0xC0010023L)
+#define RNDIS_STATUS_DEST_OUT_OF_ORDER		(0xC0010024L)
+#define RNDIS_STATUS_VC_NOT_AVAILABLE		(0xC0010025L)
+#define RNDIS_STATUS_CELLRATE_NOT_AVAILABLE	(0xC0010026L)
+#define RNDIS_STATUS_INCOMPATABLE_QOS		(0xC0010027L)
+#define RNDIS_STATUS_AAL_PARAMS_UNSUPPORTED	(0xC0010028L)
+#define RNDIS_STATUS_NO_ROUTE_TO_DESTINATION	(0xC0010029L)
+
+#define RNDIS_STATUS_TOKEN_RING_OPEN_ERROR	(0xC0011000L)
+
+/* Object Identifiers used by NdisRequest Query/Set Information */
+/* General Objects */
+#define RNDIS_OID_GEN_SUPPORTED_LIST		0x00010101
+#define RNDIS_OID_GEN_HARDWARE_STATUS		0x00010102
+#define RNDIS_OID_GEN_MEDIA_SUPPORTED		0x00010103
+#define RNDIS_OID_GEN_MEDIA_IN_USE		0x00010104
+#define RNDIS_OID_GEN_MAXIMUM_LOOKAHEAD		0x00010105
+#define RNDIS_OID_GEN_MAXIMUM_FRAME_SIZE	0x00010106
+#define RNDIS_OID_GEN_LINK_SPEED		0x00010107
+#define RNDIS_OID_GEN_TRANSMIT_BUFFER_SPACE	0x00010108
+#define RNDIS_OID_GEN_RECEIVE_BUFFER_SPACE	0x00010109
+#define RNDIS_OID_GEN_TRANSMIT_BLOCK_SIZE	0x0001010A
+#define RNDIS_OID_GEN_RECEIVE_BLOCK_SIZE	0x0001010B
+#define RNDIS_OID_GEN_VENDOR_ID			0x0001010C
+#define RNDIS_OID_GEN_VENDOR_DESCRIPTION	0x0001010D
+#define RNDIS_OID_GEN_CURRENT_PACKET_FILTER	0x0001010E
+#define RNDIS_OID_GEN_CURRENT_LOOKAHEAD		0x0001010F
+#define RNDIS_OID_GEN_DRIVER_VERSION		0x00010110
+#define RNDIS_OID_GEN_MAXIMUM_TOTAL_SIZE	0x00010111
+#define RNDIS_OID_GEN_PROTOCOL_OPTIONS		0x00010112
+#define RNDIS_OID_GEN_MAC_OPTIONS		0x00010113
+#define RNDIS_OID_GEN_MEDIA_CONNECT_STATUS	0x00010114
+#define RNDIS_OID_GEN_MAXIMUM_SEND_PACKETS	0x00010115
+#define RNDIS_OID_GEN_VENDOR_DRIVER_VERSION	0x00010116
+#define RNDIS_OID_GEN_NETWORK_LAYER_ADDRESSES	0x00010118
+#define RNDIS_OID_GEN_TRANSPORT_HEADER_OFFSET	0x00010119
+#define RNDIS_OID_GEN_MACHINE_NAME		0x0001021A
+#define RNDIS_OID_GEN_RNDIS_CONFIG_PARAMETER	0x0001021B
+
+#define RNDIS_OID_GEN_XMIT_OK			0x00020101
+#define RNDIS_OID_GEN_RCV_OK			0x00020102
+#define RNDIS_OID_GEN_XMIT_ERROR		0x00020103
+#define RNDIS_OID_GEN_RCV_ERROR			0x00020104
+#define RNDIS_OID_GEN_RCV_NO_BUFFER		0x00020105
+
+#define RNDIS_OID_GEN_DIRECTED_BYTES_XMIT	0x00020201
+#define RNDIS_OID_GEN_DIRECTED_FRAMES_XMIT	0x00020202
+#define RNDIS_OID_GEN_MULTICAST_BYTES_XMIT	0x00020203
+#define RNDIS_OID_GEN_MULTICAST_FRAMES_XMIT	0x00020204
+#define RNDIS_OID_GEN_BROADCAST_BYTES_XMIT	0x00020205
+#define RNDIS_OID_GEN_BROADCAST_FRAMES_XMIT	0x00020206
+#define RNDIS_OID_GEN_DIRECTED_BYTES_RCV	0x00020207
+#define RNDIS_OID_GEN_DIRECTED_FRAMES_RCV	0x00020208
+#define RNDIS_OID_GEN_MULTICAST_BYTES_RCV	0x00020209
+#define RNDIS_OID_GEN_MULTICAST_FRAMES_RCV	0x0002020A
+#define RNDIS_OID_GEN_BROADCAST_BYTES_RCV	0x0002020B
+#define RNDIS_OID_GEN_BROADCAST_FRAMES_RCV	0x0002020C
+
+#define RNDIS_OID_GEN_RCV_CRC_ERROR		0x0002020D
+#define RNDIS_OID_GEN_TRANSMIT_QUEUE_LENGTH	0x0002020E
+
+#define RNDIS_OID_GEN_GET_TIME_CAPS		0x0002020F
+#define RNDIS_OID_GEN_GET_NETCARD_TIME		0x00020210
+
+/* These are connection-oriented general OIDs. */
+/* These replace the above OIDs for connection-oriented media. */
+#define RNDIS_OID_GEN_CO_SUPPORTED_LIST		0x00010101
+#define RNDIS_OID_GEN_CO_HARDWARE_STATUS	0x00010102
+#define RNDIS_OID_GEN_CO_MEDIA_SUPPORTED	0x00010103
+#define RNDIS_OID_GEN_CO_MEDIA_IN_USE		0x00010104
+#define RNDIS_OID_GEN_CO_LINK_SPEED		0x00010105
+#define RNDIS_OID_GEN_CO_VENDOR_ID		0x00010106
+#define RNDIS_OID_GEN_CO_VENDOR_DESCRIPTION	0x00010107
+#define RNDIS_OID_GEN_CO_DRIVER_VERSION		0x00010108
+#define RNDIS_OID_GEN_CO_PROTOCOL_OPTIONS	0x00010109
+#define RNDIS_OID_GEN_CO_MAC_OPTIONS		0x0001010A
+#define RNDIS_OID_GEN_CO_MEDIA_CONNECT_STATUS	0x0001010B
+#define RNDIS_OID_GEN_CO_VENDOR_DRIVER_VERSION	0x0001010C
+#define RNDIS_OID_GEN_CO_MINIMUM_LINK_SPEED	0x0001010D
+
+#define RNDIS_OID_GEN_CO_GET_TIME_CAPS		0x00010201
+#define RNDIS_OID_GEN_CO_GET_NETCARD_TIME	0x00010202
+
+/* These are connection-oriented statistics OIDs. */
+#define RNDIS_OID_GEN_CO_XMIT_PDUS_OK		0x00020101
+#define RNDIS_OID_GEN_CO_RCV_PDUS_OK		0x00020102
+#define RNDIS_OID_GEN_CO_XMIT_PDUS_ERROR	0x00020103
+#define RNDIS_OID_GEN_CO_RCV_PDUS_ERROR		0x00020104
+#define RNDIS_OID_GEN_CO_RCV_PDUS_NO_BUFFER	0x00020105
+
+
+#define RNDIS_OID_GEN_CO_RCV_CRC_ERROR		0x00020201
+#define RNDIS_OID_GEN_CO_TRANSMIT_QUEUE_LENGTH	0x00020202
+#define RNDIS_OID_GEN_CO_BYTES_XMIT		0x00020203
+#define RNDIS_OID_GEN_CO_BYTES_RCV		0x00020204
+#define RNDIS_OID_GEN_CO_BYTES_XMIT_OUTSTANDING	0x00020205
+#define RNDIS_OID_GEN_CO_NETCARD_LOAD		0x00020206
+
+/* These are objects for Connection-oriented media call-managers. */
+#define RNDIS_OID_CO_ADD_PVC			0xFF000001
+#define RNDIS_OID_CO_DELETE_PVC			0xFF000002
+#define RNDIS_OID_CO_GET_CALL_INFORMATION	0xFF000003
+#define RNDIS_OID_CO_ADD_ADDRESS		0xFF000004
+#define RNDIS_OID_CO_DELETE_ADDRESS		0xFF000005
+#define RNDIS_OID_CO_GET_ADDRESSES		0xFF000006
+#define RNDIS_OID_CO_ADDRESS_CHANGE		0xFF000007
+#define RNDIS_OID_CO_SIGNALING_ENABLED		0xFF000008
+#define RNDIS_OID_CO_SIGNALING_DISABLED		0xFF000009
+
+/* 802.3 Objects (Ethernet) */
+#define RNDIS_OID_802_3_PERMANENT_ADDRESS	0x01010101
+#define RNDIS_OID_802_3_CURRENT_ADDRESS		0x01010102
+#define RNDIS_OID_802_3_MULTICAST_LIST		0x01010103
+#define RNDIS_OID_802_3_MAXIMUM_LIST_SIZE	0x01010104
+#define RNDIS_OID_802_3_MAC_OPTIONS		0x01010105
+
+#define NDIS_802_3_MAC_OPTION_PRIORITY		0x00000001
+
+#define RNDIS_OID_802_3_RCV_ERROR_ALIGNMENT	0x01020101
+#define RNDIS_OID_802_3_XMIT_ONE_COLLISION	0x01020102
+#define RNDIS_OID_802_3_XMIT_MORE_COLLISIONS	0x01020103
+
+#define RNDIS_OID_802_3_XMIT_DEFERRED		0x01020201
+#define RNDIS_OID_802_3_XMIT_MAX_COLLISIONS	0x01020202
+#define RNDIS_OID_802_3_RCV_OVERRUN		0x01020203
+#define RNDIS_OID_802_3_XMIT_UNDERRUN		0x01020204
+#define RNDIS_OID_802_3_XMIT_HEARTBEAT_FAILURE	0x01020205
+#define RNDIS_OID_802_3_XMIT_TIMES_CRS_LOST	0x01020206
+#define RNDIS_OID_802_3_XMIT_LATE_COLLISIONS	0x01020207
+
+/* Remote NDIS message types */
+#define REMOTE_NDIS_PACKET_MSG			0x00000001
+#define REMOTE_NDIS_INITIALIZE_MSG		0x00000002
+#define REMOTE_NDIS_HALT_MSG			0x00000003
+#define REMOTE_NDIS_QUERY_MSG			0x00000004
+#define REMOTE_NDIS_SET_MSG			0x00000005
+#define REMOTE_NDIS_RESET_MSG			0x00000006
+#define REMOTE_NDIS_INDICATE_STATUS_MSG		0x00000007
+#define REMOTE_NDIS_KEEPALIVE_MSG		0x00000008
+
+#define REMOTE_CONDIS_MP_CREATE_VC_MSG		0x00008001
+#define REMOTE_CONDIS_MP_DELETE_VC_MSG		0x00008002
+#define REMOTE_CONDIS_MP_ACTIVATE_VC_MSG	0x00008005
+#define REMOTE_CONDIS_MP_DEACTIVATE_VC_MSG	0x00008006
+#define REMOTE_CONDIS_INDICATE_STATUS_MSG	0x00008007
+
+/* Remote NDIS message completion types */
+#define REMOTE_NDIS_INITIALIZE_CMPLT		0x80000002
+#define REMOTE_NDIS_QUERY_CMPLT			0x80000004
+#define REMOTE_NDIS_SET_CMPLT			0x80000005
+#define REMOTE_NDIS_RESET_CMPLT			0x80000006
+#define REMOTE_NDIS_KEEPALIVE_CMPLT		0x80000008
+
+#define REMOTE_CONDIS_MP_CREATE_VC_CMPLT	0x80008001
+#define REMOTE_CONDIS_MP_DELETE_VC_CMPLT	0x80008002
+#define REMOTE_CONDIS_MP_ACTIVATE_VC_CMPLT	0x80008005
+#define REMOTE_CONDIS_MP_DEACTIVATE_VC_CMPLT	0x80008006
+
+/*
+ * Reserved message type for private communication between lower-layer host
+ * driver and remote device, if necessary.
+ */
+#define REMOTE_NDIS_BUS_MSG			0xff000001
+
+/*  Defines for DeviceFlags in struct rndis_initialize_complete */
+#define RNDIS_DF_CONNECTIONLESS			0x00000001
+#define RNDIS_DF_CONNECTION_ORIENTED		0x00000002
+#define RNDIS_DF_RAW_DATA			0x00000004
+
+/*  Remote NDIS medium types. */
+#define RNDIS_MEDIUM_802_3			0x00000000
+#define RNDIS_MEDIUM_802_5			0x00000001
+#define RNDIS_MEDIUM_FDDI				0x00000002
+#define RNDIS_MEDIUM_WAN				0x00000003
+#define RNDIS_MEDIUM_LOCAL_TALK			0x00000004
+#define RNDIS_MEDIUM_ARCNET_RAW			0x00000006
+#define RNDIS_MEDIUM_ARCNET_878_2			0x00000007
+#define RNDIS_MEDIUM_ATM				0x00000008
+#define RNDIS_MEDIUM_WIRELESS_WAN			0x00000009
+#define RNDIS_MEDIUM_IRDA				0x0000000a
+#define RNDIS_MEDIUM_CO_WAN			0x0000000b
+/* Not a real medium, defined as an upper-bound */
+#define RNDIS_MEDIUM_MAX				0x0000000d
+
+
+/* Remote NDIS medium connection states. */
+#define RNDIS_MEDIA_STATE_CONNECTED		0x00000000
+#define RNDIS_MEDIA_STATE_DISCONNECTED		0x00000001
+
+/*  Remote NDIS version numbers */
+#define RNDIS_MAJOR_VERSION			0x00000001
+#define RNDIS_MINOR_VERSION			0x00000000
+
+
+/* NdisInitialize message */
+struct rndis_initialize_request {
+	u32 req_id;
+	u32 major_ver;
+	u32 minor_ver;
+	u32 max_xfer_size;
+};
+
+/* Response to NdisInitialize */
+struct rndis_initialize_complete {
+	u32 req_id;
+	u32 status;
+	u32 major_ver;
+	u32 minor_ver;
+	u32 dev_flags;
+	u32 medium;
+	u32 max_pkt_per_msg;
+	u32 max_xfer_size;
+	u32 pkt_alignment_factor;
+	u32 af_list_offset;
+	u32 af_list_size;
+};
+
+/* Call manager devices only: Information about an address family */
+/* supported by the device is appended to the response to NdisInitialize. */
+struct rndis_co_address_family {
+	u32 address_family;
+	u32 major_ver;
+	u32 minor_ver;
+};
+
+/* NdisHalt message */
+struct rndis_halt_request {
+	u32 req_id;
+};
+
+/* NdisQueryRequest message */
+struct rndis_query_request {
+	u32 req_id;
+	u32 oid;
+	u32 info_buflen;
+	u32 info_buf_offset;
+	u32 dev_vc_handle;
+};
+
+/* Response to NdisQueryRequest */
+struct rndis_query_complete {
+	u32 req_id;
+	u32 status;
+	u32 info_buflen;
+	u32 info_buf_offset;
+};
+
+/* NdisSetRequest message */
+struct rndis_set_request {
+	u32 req_id;
+	u32 oid;
+	u32 info_buflen;
+	u32 info_buf_offset;
+	u32 dev_vc_handle;
+};
+
+/* Response to NdisSetRequest */
+struct rndis_set_complete {
+	u32 req_id;
+	u32 status;
+};
+
+/* NdisReset message */
+struct rndis_reset_request {
+	u32 reserved;
+};
+
+/* Response to NdisReset */
+struct rndis_reset_complete {
+	u32 status;
+	u32 addressing_reset;
+};
+
+/* NdisMIndicateStatus message */
+struct rndis_indicate_status {
+	u32 status;
+	u32 status_buflen;
+	u32 status_buf_offset;
+};
+
+/* Diagnostic information passed as the status buffer in */
+/* struct rndis_indicate_status messages signifying error conditions. */
+struct rndis_diagnostic_info {
+	u32 diag_status;
+	u32 error_offset;
+};
+
+/* NdisKeepAlive message */
+struct rndis_keepalive_request {
+	u32 req_id;
+};
+
+/* Response to NdisKeepAlive */
+struct rndis_keepalive_complete {
+	u32 req_id;
+	u32 status;
+};
+
+/*
+ * Data message. All Offset fields contain byte offsets from the beginning of
+ * struct rndis_packet. All Length fields are in bytes.  VcHandle is set
+ * to 0 for connectionless data, otherwise it contains the VC handle.
+ */
+struct rndis_packet {
+	u32 data_offset;
+	u32 data_len;
+	u32 oob_data_offset;
+	u32 oob_data_len;
+	u32 num_oob_data_elements;
+	u32 per_pkt_info_offset;
+	u32 per_pkt_info_len;
+	u32 vc_handle;
+	u32 reserved;
+};
+
+/* Optional Out of Band data associated with a Data message. */
+struct rndis_oobd {
+	u32 size;
+	u32 type;
+	u32 class_info_offset;
+};
+
+/* Packet extension field contents associated with a Data message. */
+struct rndis_per_packet_info {
+	u32 size;
+	u32 type;
+	u32 per_pkt_info_offset;
+};
+
+/* Format of Information buffer passed in a SetRequest for the OID */
+/* OID_GEN_RNDIS_CONFIG_PARAMETER. */
+struct rndis_config_parameter_info {
+	u32 parameter_name_offset;
+	u32 parameter_name_length;
+	u32 parameter_type;
+	u32 parameter_value_offset;
+	u32 parameter_value_length;
+};
+
+/* Values for ParameterType in struct rndis_config_parameter_info */
+#define RNDIS_CONFIG_PARAM_TYPE_INTEGER     0
+#define RNDIS_CONFIG_PARAM_TYPE_STRING      2
+
+/* CONDIS Miniport messages for connection oriented devices */
+/* that do not implement a call manager. */
+
+/* CoNdisMiniportCreateVc message */
+struct rcondis_mp_create_vc {
+	u32 req_id;
+	u32 ndis_vc_handle;
+};
+
+/* Response to CoNdisMiniportCreateVc */
+struct rcondis_mp_create_vc_complete {
+	u32 req_id;
+	u32 dev_vc_handle;
+	u32 status;
+};
+
+/* CoNdisMiniportDeleteVc message */
+struct rcondis_mp_delete_vc {
+	u32 req_id;
+	u32 dev_vc_handle;
+};
+
+/* Response to CoNdisMiniportDeleteVc */
+struct rcondis_mp_delete_vc_complete {
+	u32 req_id;
+	u32 status;
+};
+
+/* CoNdisMiniportQueryRequest message */
+struct rcondis_mp_query_request {
+	u32 req_id;
+	u32 request_type;
+	u32 oid;
+	u32 dev_vc_handle;
+	u32 info_buflen;
+	u32 info_buf_offset;
+};
+
+/* CoNdisMiniportSetRequest message */
+struct rcondis_mp_set_request {
+	u32 req_id;
+	u32 request_type;
+	u32 oid;
+	u32 dev_vc_handle;
+	u32 info_buflen;
+	u32 info_buf_offset;
+};
+
+/* CoNdisIndicateStatus message */
+struct rcondis_indicate_status {
+	u32 ndis_vc_handle;
+	u32 status;
+	u32 status_buflen;
+	u32 status_buf_offset;
+};
+
+/* CONDIS Call/VC parameters */
+struct rcondis_specific_parameters {
+	u32 parameter_type;
+	u32 parameter_length;
+	u32 parameter_lffset;
+};
+
+struct rcondis_media_parameters {
+	u32 flags;
+	u32 reserved1;
+	u32 reserved2;
+	struct rcondis_specific_parameters media_specific;
+};
+
+struct rndis_flowspec {
+	u32 token_rate;
+	u32 token_bucket_size;
+	u32 peak_bandwidth;
+	u32 latency;
+	u32 delay_variation;
+	u32 service_type;
+	u32 max_sdu_size;
+	u32 minimum_policed_size;
+};
+
+struct rcondis_call_manager_parameters {
+	struct rndis_flowspec transmit;
+	struct rndis_flowspec receive;
+	struct rcondis_specific_parameters call_mgr_specific;
+};
+
+/* CoNdisMiniportActivateVc message */
+struct rcondis_mp_activate_vc_request {
+	u32 req_id;
+	u32 flags;
+	u32 dev_vc_handle;
+	u32 media_params_offset;
+	u32 media_params_length;
+	u32 call_mgr_params_offset;
+	u32 call_mgr_params_length;
+};
+
+/* Response to CoNdisMiniportActivateVc */
+struct rcondis_mp_activate_vc_complete {
+	u32 req_id;
+	u32 status;
+};
+
+/* CoNdisMiniportDeactivateVc message */
+struct rcondis_mp_deactivate_vc_request {
+	u32 req_id;
+	u32 flags;
+	u32 dev_vc_handle;
+};
+
+/* Response to CoNdisMiniportDeactivateVc */
+struct rcondis_mp_deactivate_vc_complete {
+	u32 req_id;
+	u32 status;
+};
+
+
+/* union with all of the RNDIS messages */
+union rndis_message_container {
+	struct rndis_packet pkt;
+	struct rndis_initialize_request init_req;
+	struct rndis_halt_request halt_req;
+	struct rndis_query_request query_req;
+	struct rndis_set_request set_req;
+	struct rndis_reset_request reset_req;
+	struct rndis_keepalive_request keep_alive_req;
+	struct rndis_indicate_status indicate_status;
+	struct rndis_initialize_complete init_complete;
+	struct rndis_query_complete query_complete;
+	struct rndis_set_complete set_complete;
+	struct rndis_reset_complete reset_complete;
+	struct rndis_keepalive_complete keep_alive_complete;
+	struct rcondis_mp_create_vc co_miniport_create_vc;
+	struct rcondis_mp_delete_vc co_miniport_delete_vc;
+	struct rcondis_indicate_status co_indicate_status;
+	struct rcondis_mp_activate_vc_request co_miniport_activate_vc;
+	struct rcondis_mp_deactivate_vc_request co_miniport_deactivate_vc;
+	struct rcondis_mp_create_vc_complete co_miniport_create_vc_complete;
+	struct rcondis_mp_delete_vc_complete co_miniport_delete_vc_complete;
+	struct rcondis_mp_activate_vc_complete co_miniport_activate_vc_complete;
+	struct rcondis_mp_deactivate_vc_complete
+		co_miniport_deactivate_vc_complete;
+};
+
+/* Remote NDIS message format */
+struct rndis_message {
+	u32 ndis_msg_type;
+
+	/* Total length of this message, from the beginning */
+	/* of the sruct rndis_message, in bytes. */
+	u32 msg_len;
+
+	/* Actual message */
+	union rndis_message_container msg;
+};
+
+
+struct rndis_filter_packet {
+	void *completion_ctx;
+	void (*completion)(void *context);
+	struct rndis_message msg;
+};
+
+/* Handy macros */
+
+/* get the size of an RNDIS message. Pass in the message type, */
+/* struct rndis_set_request, struct rndis_packet for example */
+#define RNDIS_MESSAGE_SIZE(msg)				\
+	(sizeof(msg) + (sizeof(struct rndis_message) -	\
+	 sizeof(union rndis_message_container)))
+
+/* get pointer to info buffer with message pointer */
+#define MESSAGE_TO_INFO_BUFFER(msg)				\
+	(((unsigned char *)(msg)) + msg->info_buf_offset)
+
+/* get pointer to status buffer with message pointer */
+#define MESSAGE_TO_STATUS_BUFFER(msg)			\
+	(((unsigned char *)(msg)) + msg->status_buf_offset)
+
+/* get pointer to OOBD buffer with message pointer */
+#define MESSAGE_TO_OOBD_BUFFER(msg)				\
+	(((unsigned char *)(msg)) + msg->oob_data_offset)
+
+/* get pointer to data buffer with message pointer */
+#define MESSAGE_TO_DATA_BUFFER(msg)				\
+	(((unsigned char *)(msg)) + msg->per_pkt_info_offset)
+
+/* get pointer to contained message from NDIS_MESSAGE pointer */
+#define RNDIS_MESSAGE_PTR_TO_MESSAGE_PTR(rndis_msg)		\
+	((void *) &rndis_msg->msg)
+
+/* get pointer to contained message from NDIS_MESSAGE pointer */
+#define RNDIS_MESSAGE_RAW_PTR_TO_MESSAGE_PTR(rndis_msg)	\
+	((void *) rndis_msg)
+
+
+#define __struct_bcount(x)
+
+
+
+#define RNDIS_HEADER_SIZE	(sizeof(struct rndis_message) - \
+				 sizeof(union rndis_message_container))
+
+#define NDIS_PACKET_TYPE_DIRECTED	0x00000001
+#define NDIS_PACKET_TYPE_MULTICAST	0x00000002
+#define NDIS_PACKET_TYPE_ALL_MULTICAST	0x00000004
+#define NDIS_PACKET_TYPE_BROADCAST	0x00000008
+#define NDIS_PACKET_TYPE_SOURCE_ROUTING	0x00000010
+#define NDIS_PACKET_TYPE_PROMISCUOUS	0x00000020
+#define NDIS_PACKET_TYPE_SMT		0x00000040
+#define NDIS_PACKET_TYPE_ALL_LOCAL	0x00000080
+#define NDIS_PACKET_TYPE_GROUP		0x00000100
+#define NDIS_PACKET_TYPE_ALL_FUNCTIONAL	0x00000200
+#define NDIS_PACKET_TYPE_FUNCTIONAL	0x00000400
+#define NDIS_PACKET_TYPE_MAC_FRAME	0x00000800
+
+
+
+#endif /* _HYPERV_NET_H */
diff -druN linux-2.6.39-libre/drivers/staging/hv/hyperv_storage.h linux-3.0-rc7-libre/drivers/staging/hv/hyperv_storage.h
--- linux-2.6.39-libre/drivers/staging/hv/hyperv_storage.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/staging/hv/hyperv_storage.h	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,334 @@
+/*
+ *
+ * Copyright (c) 2011, Microsoft 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., 59 Temple
+ * Place - Suite 330, Boston, MA 02111-1307 USA.
+ *
+ * Authors:
+ *   Haiyang Zhang <haiyangz@microsoft.com>
+ *   Hank Janssen  <hjanssen@microsoft.com>
+ *   K. Y. Srinivasan <kys@microsoft.com>
+ *
+ */
+
+#ifndef _HYPERV_STORAGE_H
+#define _HYPERV_STORAGE_H
+
+
+/* vstorage.w revision number.  This is used in the case of a version match, */
+/* to alert the user that structure sizes may be mismatched even though the */
+/* protocol versions match. */
+
+
+#define REVISION_STRING(REVISION_) #REVISION_
+#define FILL_VMSTOR_REVISION(RESULT_LVALUE_)				\
+	do {								\
+		char *revision_string					\
+			= REVISION_STRING($Rev : 6 $) + 6;		\
+		RESULT_LVALUE_ = 0;					\
+		while (*revision_string >= '0'				\
+			&& *revision_string <= '9') {			\
+			RESULT_LVALUE_ *= 10;				\
+			RESULT_LVALUE_ += *revision_string - '0';	\
+			revision_string++;				\
+		}							\
+	} while (0)
+
+/* Major/minor macros.  Minor version is in LSB, meaning that earlier flat */
+/* version numbers will be interpreted as "0.x" (i.e., 1 becomes 0.1). */
+#define VMSTOR_PROTOCOL_MAJOR(VERSION_)		(((VERSION_) >> 8) & 0xff)
+#define VMSTOR_PROTOCOL_MINOR(VERSION_)		(((VERSION_))      & 0xff)
+#define VMSTOR_PROTOCOL_VERSION(MAJOR_, MINOR_)	((((MAJOR_) & 0xff) << 8) | \
+						 (((MINOR_) & 0xff)))
+#define VMSTOR_INVALID_PROTOCOL_VERSION		(-1)
+
+/* Version history: */
+/* V1 Beta                    0.1 */
+/* V1 RC < 2008/1/31          1.0 */
+/* V1 RC > 2008/1/31          2.0 */
+#define VMSTOR_PROTOCOL_VERSION_CURRENT VMSTOR_PROTOCOL_VERSION(2, 0)
+
+
+
+
+/*  This will get replaced with the max transfer length that is possible on */
+/*  the host adapter. */
+/*  The max transfer length will be published when we offer a vmbus channel. */
+#define MAX_TRANSFER_LENGTH	0x40000
+#define DEFAULT_PACKET_SIZE (sizeof(struct vmdata_gpa_direct) +	\
+			sizeof(struct vstor_packet) +		\
+			sizesizeof(u64) * (MAX_TRANSFER_LENGTH / PAGE_SIZE)))
+
+
+/*  Packet structure describing virtual storage requests. */
+enum vstor_packet_operation {
+	VSTOR_OPERATION_COMPLETE_IO		= 1,
+	VSTOR_OPERATION_REMOVE_DEVICE		= 2,
+	VSTOR_OPERATION_EXECUTE_SRB		= 3,
+	VSTOR_OPERATION_RESET_LUN		= 4,
+	VSTOR_OPERATION_RESET_ADAPTER		= 5,
+	VSTOR_OPERATION_RESET_BUS		= 6,
+	VSTOR_OPERATION_BEGIN_INITIALIZATION	= 7,
+	VSTOR_OPERATION_END_INITIALIZATION	= 8,
+	VSTOR_OPERATION_QUERY_PROTOCOL_VERSION	= 9,
+	VSTOR_OPERATION_QUERY_PROPERTIES	= 10,
+	VSTOR_OPERATION_MAXIMUM			= 10
+};
+
+/*
+ * Platform neutral description of a scsi request -
+ * this remains the same across the write regardless of 32/64 bit
+ * note: it's patterned off the SCSI_PASS_THROUGH structure
+ */
+#define CDB16GENERIC_LENGTH			0x10
+
+#ifndef SENSE_BUFFER_SIZE
+#define SENSE_BUFFER_SIZE			0x12
+#endif
+
+#define MAX_DATA_BUF_LEN_WITH_PADDING		0x14
+
+struct vmscsi_request {
+	unsigned short length;
+	unsigned char srb_status;
+	unsigned char scsi_status;
+
+	unsigned char port_number;
+	unsigned char path_id;
+	unsigned char target_id;
+	unsigned char lun;
+
+	unsigned char cdb_length;
+	unsigned char sense_info_length;
+	unsigned char data_in;
+	unsigned char reserved;
+
+	unsigned int data_transfer_length;
+
+	union {
+		unsigned char cdb[CDB16GENERIC_LENGTH];
+		unsigned char sense_data[SENSE_BUFFER_SIZE];
+		unsigned char reserved_array[MAX_DATA_BUF_LEN_WITH_PADDING];
+	};
+} __attribute((packed));
+
+
+/*
+ * This structure is sent during the intialization phase to get the different
+ * properties of the channel.
+ */
+struct vmstorage_channel_properties {
+	unsigned short protocol_version;
+	unsigned char path_id;
+	unsigned char target_id;
+
+	/* Note: port number is only really known on the client side */
+	unsigned int port_number;
+	unsigned int flags;
+	unsigned int max_transfer_bytes;
+
+	/*  This id is unique for each channel and will correspond with */
+	/*  vendor specific data in the inquirydata */
+	unsigned long long unique_id;
+} __packed;
+
+/*  This structure is sent during the storage protocol negotiations. */
+struct vmstorage_protocol_version {
+	/* Major (MSW) and minor (LSW) version numbers. */
+	unsigned short major_minor;
+
+	/*
+	 * Revision number is auto-incremented whenever this file is changed
+	 * (See FILL_VMSTOR_REVISION macro above).  Mismatch does not
+	 * definitely indicate incompatibility--but it does indicate mismatched
+	 * builds.
+	 */
+	unsigned short revision;
+} __packed;
+
+/* Channel Property Flags */
+#define STORAGE_CHANNEL_REMOVABLE_FLAG		0x1
+#define STORAGE_CHANNEL_EMULATED_IDE_FLAG	0x2
+
+struct vstor_packet {
+	/* Requested operation type */
+	enum vstor_packet_operation operation;
+
+	/*  Flags - see below for values */
+	unsigned int flags;
+
+	/* Status of the request returned from the server side. */
+	unsigned int status;
+
+	/* Data payload area */
+	union {
+		/*
+		 * Structure used to forward SCSI commands from the
+		 * client to the server.
+		 */
+		struct vmscsi_request vm_srb;
+
+		/* Structure used to query channel properties. */
+		struct vmstorage_channel_properties storage_channel_properties;
+
+		/* Used during version negotiations. */
+		struct vmstorage_protocol_version version;
+	};
+} __packed;
+
+/* Packet flags */
+/*
+ * This flag indicates that the server should send back a completion for this
+ * packet.
+ */
+#define REQUEST_COMPLETION_FLAG	0x1
+
+/*  This is the set of flags that the vsc can set in any packets it sends */
+#define VSC_LEGAL_FLAGS		(REQUEST_COMPLETION_FLAG)
+
+
+#include <linux/kernel.h>
+#include <linux/wait.h>
+#include "hyperv_storage.h"
+#include "hyperv.h"
+
+/* Defines */
+#define STORVSC_RING_BUFFER_SIZE			(20*PAGE_SIZE)
+#define BLKVSC_RING_BUFFER_SIZE				(20*PAGE_SIZE)
+
+#define STORVSC_MAX_IO_REQUESTS				128
+
+/*
+ * In Hyper-V, each port/path/target maps to 1 scsi host adapter.  In
+ * reality, the path/target is not used (ie always set to 0) so our
+ * scsi host adapter essentially has 1 bus with 1 target that contains
+ * up to 256 luns.
+ */
+#define STORVSC_MAX_LUNS_PER_TARGET			64
+#define STORVSC_MAX_TARGETS				1
+#define STORVSC_MAX_CHANNELS				1
+
+struct hv_storvsc_request;
+
+/* Matches Windows-end */
+enum storvsc_request_type {
+	WRITE_TYPE,
+	READ_TYPE,
+	UNKNOWN_TYPE,
+};
+
+
+struct hv_storvsc_request {
+	struct hv_storvsc_request *request;
+	struct hv_device *device;
+
+	/* Synchronize the request/response if needed */
+	struct completion wait_event;
+
+	unsigned char *sense_buffer;
+	void *context;
+	void (*on_io_completion)(struct hv_storvsc_request *request);
+	struct hv_multipage_buffer data_buffer;
+
+	struct vstor_packet vstor_packet;
+};
+
+
+struct storvsc_device_info {
+	u32 ring_buffer_size;
+	unsigned int port_number;
+	unsigned char path_id;
+	unsigned char target_id;
+};
+
+struct storvsc_major_info {
+	int major;
+	int index;
+	bool do_register;
+	char *devname;
+	char *diskname;
+};
+
+/* A storvsc device is a device object that contains a vmbus channel */
+struct storvsc_device {
+	struct hv_device *device;
+
+	/* 0 indicates the device is being destroyed */
+	atomic_t ref_count;
+
+	bool	 drain_notify;
+	atomic_t num_outstanding_req;
+
+	wait_queue_head_t waiting_to_drain;
+
+	/*
+	 * Each unique Port/Path/Target represents 1 channel ie scsi
+	 * controller. In reality, the pathid, targetid is always 0
+	 * and the port is set by us
+	 */
+	unsigned int port_number;
+	unsigned char path_id;
+	unsigned char target_id;
+
+	/* Used for vsc/vsp channel reset process */
+	struct hv_storvsc_request init_request;
+	struct hv_storvsc_request reset_request;
+};
+
+
+/* Get the stordevice object iff exists and its refcount > 1 */
+static inline struct storvsc_device *get_stor_device(struct hv_device *device)
+{
+	struct storvsc_device *stor_device;
+
+	stor_device = (struct storvsc_device *)device->ext;
+	if (stor_device && atomic_read(&stor_device->ref_count) > 1)
+		atomic_inc(&stor_device->ref_count);
+	else
+		stor_device = NULL;
+
+	return stor_device;
+}
+
+
+static inline void put_stor_device(struct hv_device *device)
+{
+	struct storvsc_device *stor_device;
+
+	stor_device = (struct storvsc_device *)device->ext;
+
+	atomic_dec(&stor_device->ref_count);
+}
+
+static inline void storvsc_wait_to_drain(struct storvsc_device *dev)
+{
+	dev->drain_notify = true;
+	wait_event(dev->waiting_to_drain,
+		   atomic_read(&dev->num_outstanding_req) == 0);
+	dev->drain_notify = false;
+}
+
+/* Interface */
+
+int storvsc_dev_add(struct hv_device *device,
+				void *additional_info);
+int storvsc_dev_remove(struct hv_device *device);
+
+int storvsc_do_io(struct hv_device *device,
+				struct hv_storvsc_request *request);
+
+int storvsc_get_major_info(struct storvsc_device_info *device_info,
+				struct storvsc_major_info *major_info);
+
+#endif /* _HYPERV_STORAGE_H */
diff -druN linux-2.6.39-libre/drivers/staging/hv/hyperv_vmbus.h linux-3.0-rc7-libre/drivers/staging/hv/hyperv_vmbus.h
--- linux-2.6.39-libre/drivers/staging/hv/hyperv_vmbus.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/staging/hv/hyperv_vmbus.h	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,631 @@
+/*
+ *
+ * Copyright (c) 2011, Microsoft 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., 59 Temple
+ * Place - Suite 330, Boston, MA 02111-1307 USA.
+ *
+ * Authors:
+ *   Haiyang Zhang <haiyangz@microsoft.com>
+ *   Hank Janssen  <hjanssen@microsoft.com>
+ *   K. Y. Srinivasan <kys@microsoft.com>
+ *
+ */
+
+#ifndef _HYPERV_VMBUS_H
+#define _HYPERV_VMBUS_H
+
+#include <linux/list.h>
+#include <asm/sync_bitops.h>
+#include <linux/atomic.h>
+
+#include "hyperv.h"
+
+/*
+ * The below CPUID leaves are present if VersionAndFeatures.HypervisorPresent
+ * is set by CPUID(HVCPUID_VERSION_FEATURES).
+ */
+enum hv_cpuid_function {
+	HVCPUID_VERSION_FEATURES		= 0x00000001,
+	HVCPUID_VENDOR_MAXFUNCTION		= 0x40000000,
+	HVCPUID_INTERFACE			= 0x40000001,
+
+	/*
+	 * The remaining functions depend on the value of
+	 * HVCPUID_INTERFACE
+	 */
+	HVCPUID_VERSION			= 0x40000002,
+	HVCPUID_FEATURES			= 0x40000003,
+	HVCPUID_ENLIGHTENMENT_INFO	= 0x40000004,
+	HVCPUID_IMPLEMENTATION_LIMITS		= 0x40000005,
+};
+
+/* Define version of the synthetic interrupt controller. */
+#define HV_SYNIC_VERSION		(1)
+
+/* Define the expected SynIC version. */
+#define HV_SYNIC_VERSION_1		(0x1)
+
+/* Define synthetic interrupt controller message constants. */
+#define HV_MESSAGE_SIZE			(256)
+#define HV_MESSAGE_PAYLOAD_BYTE_COUNT	(240)
+#define HV_MESSAGE_PAYLOAD_QWORD_COUNT	(30)
+#define HV_ANY_VP			(0xFFFFFFFF)
+
+/* Define synthetic interrupt controller flag constants. */
+#define HV_EVENT_FLAGS_COUNT		(256 * 8)
+#define HV_EVENT_FLAGS_BYTE_COUNT	(256)
+#define HV_EVENT_FLAGS_DWORD_COUNT	(256 / sizeof(u32))
+
+/* Define hypervisor message types. */
+enum hv_message_type {
+	HVMSG_NONE			= 0x00000000,
+
+	/* Memory access messages. */
+	HVMSG_UNMAPPED_GPA		= 0x80000000,
+	HVMSG_GPA_INTERCEPT		= 0x80000001,
+
+	/* Timer notification messages. */
+	HVMSG_TIMER_EXPIRED			= 0x80000010,
+
+	/* Error messages. */
+	HVMSG_INVALID_VP_REGISTER_VALUE	= 0x80000020,
+	HVMSG_UNRECOVERABLE_EXCEPTION	= 0x80000021,
+	HVMSG_UNSUPPORTED_FEATURE		= 0x80000022,
+
+	/* Trace buffer complete messages. */
+	HVMSG_EVENTLOG_BUFFERCOMPLETE	= 0x80000040,
+
+	/* Platform-specific processor intercept messages. */
+	HVMSG_X64_IOPORT_INTERCEPT		= 0x80010000,
+	HVMSG_X64_MSR_INTERCEPT		= 0x80010001,
+	HVMSG_X64_CPUID_INTERCEPT		= 0x80010002,
+	HVMSG_X64_EXCEPTION_INTERCEPT	= 0x80010003,
+	HVMSG_X64_APIC_EOI			= 0x80010004,
+	HVMSG_X64_LEGACY_FP_ERROR		= 0x80010005
+};
+
+/* Define the number of synthetic interrupt sources. */
+#define HV_SYNIC_SINT_COUNT		(16)
+#define HV_SYNIC_STIMER_COUNT		(4)
+
+/* Define invalid partition identifier. */
+#define HV_PARTITION_ID_INVALID		((u64)0x0)
+
+/* Define connection identifier type. */
+union hv_connection_id {
+	u32 asu32;
+	struct {
+		u32 id:24;
+		u32 reserved:8;
+	} u;
+};
+
+/* Define port identifier type. */
+union hv_port_id {
+	u32 asu32;
+	struct {
+		u32 id:24;
+		u32 reserved:8;
+	} u ;
+};
+
+/* Define port type. */
+enum hv_port_type {
+	HVPORT_MSG	= 1,
+	HVPORT_EVENT		= 2,
+	HVPORT_MONITOR	= 3
+};
+
+/* Define port information structure. */
+struct hv_port_info {
+	enum hv_port_type port_type;
+	u32 padding;
+	union {
+		struct {
+			u32 target_sint;
+			u32 target_vp;
+			u64 rsvdz;
+		} message_port_info;
+		struct {
+			u32 target_sint;
+			u32 target_vp;
+			u16 base_flag_bumber;
+			u16 flag_count;
+			u32 rsvdz;
+		} event_port_info;
+		struct {
+			u64 monitor_address;
+			u64 rsvdz;
+		} monitor_port_info;
+	};
+};
+
+struct hv_connection_info {
+	enum hv_port_type port_type;
+	u32 padding;
+	union {
+		struct {
+			u64 rsvdz;
+		} message_connection_info;
+		struct {
+			u64 rsvdz;
+		} event_connection_info;
+		struct {
+			u64 monitor_address;
+		} monitor_connection_info;
+	};
+};
+
+/* Define synthetic interrupt controller message flags. */
+union hv_message_flags {
+	u8 asu8;
+	struct {
+		u8 msg_pending:1;
+		u8 reserved:7;
+	};
+};
+
+/* Define synthetic interrupt controller message header. */
+struct hv_message_header {
+	enum hv_message_type message_type;
+	u8 payload_size;
+	union hv_message_flags message_flags;
+	u8 reserved[2];
+	union {
+		u64 sender;
+		union hv_port_id port;
+	};
+};
+
+/* Define timer message payload structure. */
+struct hv_timer_message_payload {
+	u32 timer_index;
+	u32 reserved;
+	u64 expiration_time;	/* When the timer expired */
+	u64 delivery_time;	/* When the message was delivered */
+};
+
+/* Define synthetic interrupt controller message format. */
+struct hv_message {
+	struct hv_message_header header;
+	union {
+		u64 payload[HV_MESSAGE_PAYLOAD_QWORD_COUNT];
+	} u ;
+};
+
+/* Define the number of message buffers associated with each port. */
+#define HV_PORT_MESSAGE_BUFFER_COUNT	(16)
+
+/* Define the synthetic interrupt message page layout. */
+struct hv_message_page {
+	struct hv_message sint_message[HV_SYNIC_SINT_COUNT];
+};
+
+/* Define the synthetic interrupt controller event flags format. */
+union hv_synic_event_flags {
+	u8 flags8[HV_EVENT_FLAGS_BYTE_COUNT];
+	u32 flags32[HV_EVENT_FLAGS_DWORD_COUNT];
+};
+
+/* Define the synthetic interrupt flags page layout. */
+struct hv_synic_event_flags_page {
+	union hv_synic_event_flags sintevent_flags[HV_SYNIC_SINT_COUNT];
+};
+
+/* Define SynIC control register. */
+union hv_synic_scontrol {
+	u64 as_uint64;
+	struct {
+		u64 enable:1;
+		u64 reserved:63;
+	};
+};
+
+/* Define synthetic interrupt source. */
+union hv_synic_sint {
+	u64 as_uint64;
+	struct {
+		u64 vector:8;
+		u64 reserved1:8;
+		u64 masked:1;
+		u64 auto_eoi:1;
+		u64 reserved2:46;
+	};
+};
+
+/* Define the format of the SIMP register */
+union hv_synic_simp {
+	u64 as_uint64;
+	struct {
+		u64 simp_enabled:1;
+		u64 preserved:11;
+		u64 base_simp_gpa:52;
+	};
+};
+
+/* Define the format of the SIEFP register */
+union hv_synic_siefp {
+	u64 as_uint64;
+	struct {
+		u64 siefp_enabled:1;
+		u64 preserved:11;
+		u64 base_siefp_gpa:52;
+	};
+};
+
+/* Definitions for the monitored notification facility */
+union hv_monitor_trigger_group {
+	u64 as_uint64;
+	struct {
+		u32 pending;
+		u32 armed;
+	};
+};
+
+struct hv_monitor_parameter {
+	union hv_connection_id connectionid;
+	u16 flagnumber;
+	u16 rsvdz;
+};
+
+union hv_monitor_trigger_state {
+	u32 asu32;
+
+	struct {
+		u32 group_enable:4;
+		u32 rsvdz:28;
+	};
+};
+
+/* struct hv_monitor_page Layout */
+/* ------------------------------------------------------ */
+/* | 0   | TriggerState (4 bytes) | Rsvd1 (4 bytes)     | */
+/* | 8   | TriggerGroup[0]                              | */
+/* | 10  | TriggerGroup[1]                              | */
+/* | 18  | TriggerGroup[2]                              | */
+/* | 20  | TriggerGroup[3]                              | */
+/* | 28  | Rsvd2[0]                                     | */
+/* | 30  | Rsvd2[1]                                     | */
+/* | 38  | Rsvd2[2]                                     | */
+/* | 40  | NextCheckTime[0][0]    | NextCheckTime[0][1] | */
+/* | ...                                                | */
+/* | 240 | Latency[0][0..3]                             | */
+/* | 340 | Rsvz3[0]                                     | */
+/* | 440 | Parameter[0][0]                              | */
+/* | 448 | Parameter[0][1]                              | */
+/* | ...                                                | */
+/* | 840 | Rsvd4[0]                                     | */
+/* ------------------------------------------------------ */
+struct hv_monitor_page {
+	union hv_monitor_trigger_state trigger_state;
+	u32 rsvdz1;
+
+	union hv_monitor_trigger_group trigger_group[4];
+	u64 rsvdz2[3];
+
+	s32 next_checktime[4][32];
+
+	u16 latency[4][32];
+	u64 rsvdz3[32];
+
+	struct hv_monitor_parameter parameter[4][32];
+
+	u8 rsvdz4[1984];
+};
+
+/* Declare the various hypercall operations. */
+enum hv_call_code {
+	HVCALL_POST_MESSAGE	= 0x005c,
+	HVCALL_SIGNAL_EVENT	= 0x005d,
+};
+
+/* Definition of the hv_post_message hypercall input structure. */
+struct hv_input_post_message {
+	union hv_connection_id connectionid;
+	u32 reserved;
+	enum hv_message_type message_type;
+	u32 payload_size;
+	u64 payload[HV_MESSAGE_PAYLOAD_QWORD_COUNT];
+};
+
+/* Definition of the hv_signal_event hypercall input structure. */
+struct hv_input_signal_event {
+	union hv_connection_id connectionid;
+	u16 flag_number;
+	u16 rsvdz;
+};
+
+/*
+ * Versioning definitions used for guests reporting themselves to the
+ * hypervisor, and visa versa.
+ */
+
+/* Version info reported by guest OS's */
+enum hv_guest_os_vendor {
+	HVGUESTOS_VENDOR_MICROSOFT	= 0x0001
+};
+
+enum hv_guest_os_microsoft_ids {
+	HVGUESTOS_MICROSOFT_UNDEFINED	= 0x00,
+	HVGUESTOS_MICROSOFT_MSDOS		= 0x01,
+	HVGUESTOS_MICROSOFT_WINDOWS3X	= 0x02,
+	HVGUESTOS_MICROSOFT_WINDOWS9X	= 0x03,
+	HVGUESTOS_MICROSOFT_WINDOWSNT	= 0x04,
+	HVGUESTOS_MICROSOFT_WINDOWSCE	= 0x05
+};
+
+/*
+ * Declare the MSR used to identify the guest OS.
+ */
+#define HV_X64_MSR_GUEST_OS_ID	0x40000000
+
+union hv_x64_msr_guest_os_id_contents {
+	u64 as_uint64;
+	struct {
+		u64 build_number:16;
+		u64 service_version:8; /* Service Pack, etc. */
+		u64 minor_version:8;
+		u64 major_version:8;
+		u64 os_id:8; /* enum hv_guest_os_microsoft_ids (if Vendor=MS) */
+		u64 vendor_id:16; /* enum hv_guest_os_vendor */
+	};
+};
+
+/*
+ * Declare the MSR used to setup pages used to communicate with the hypervisor.
+ */
+#define HV_X64_MSR_HYPERCALL	0x40000001
+
+union hv_x64_msr_hypercall_contents {
+	u64 as_uint64;
+	struct {
+		u64 enable:1;
+		u64 reserved:11;
+		u64 guest_physical_address:52;
+	};
+};
+
+
+enum {
+	VMBUS_MESSAGE_CONNECTION_ID	= 1,
+	VMBUS_MESSAGE_PORT_ID		= 1,
+	VMBUS_EVENT_CONNECTION_ID	= 2,
+	VMBUS_EVENT_PORT_ID		= 2,
+	VMBUS_MONITOR_CONNECTION_ID	= 3,
+	VMBUS_MONITOR_PORT_ID		= 3,
+	VMBUS_MESSAGE_SINT		= 2,
+};
+
+/* #defines */
+
+#define HV_PRESENT_BIT			0x80000000
+
+#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) | \
+					   HV_LINUX_GUEST_ID_LO)
+
+#define HV_CPU_POWER_MANAGEMENT		(1 << 0)
+#define HV_RECOMMENDATIONS_MAX		4
+
+#define HV_X64_MAX			5
+#define HV_CAPS_MAX			8
+
+
+#define HV_HYPERCALL_PARAM_ALIGN	sizeof(u64)
+
+
+/* Service definitions */
+
+#define HV_SERVICE_PARENT_PORT				(0)
+#define HV_SERVICE_PARENT_CONNECTION			(0)
+
+#define HV_SERVICE_CONNECT_RESPONSE_SUCCESS		(0)
+#define HV_SERVICE_CONNECT_RESPONSE_INVALID_PARAMETER	(1)
+#define HV_SERVICE_CONNECT_RESPONSE_UNKNOWN_SERVICE	(2)
+#define HV_SERVICE_CONNECT_RESPONSE_CONNECTION_REJECTED	(3)
+
+#define HV_SERVICE_CONNECT_REQUEST_MESSAGE_ID		(1)
+#define HV_SERVICE_CONNECT_RESPONSE_MESSAGE_ID		(2)
+#define HV_SERVICE_DISCONNECT_REQUEST_MESSAGE_ID	(3)
+#define HV_SERVICE_DISCONNECT_RESPONSE_MESSAGE_ID	(4)
+#define HV_SERVICE_MAX_MESSAGE_ID				(4)
+
+#define HV_SERVICE_PROTOCOL_VERSION (0x0010)
+#define HV_CONNECT_PAYLOAD_BYTE_COUNT 64
+
+/* #define VMBUS_REVISION_NUMBER	6 */
+
+/* Our local vmbus's port and connection id. Anything >0 is fine */
+/* #define VMBUS_PORT_ID		11 */
+
+/* 628180B8-308D-4c5e-B7DB-1BEB62E62EF4 */
+static const struct hv_guid VMBUS_SERVICE_ID = {
+	.data = {
+		0xb8, 0x80, 0x81, 0x62, 0x8d, 0x30, 0x5e, 0x4c,
+		0xb7, 0xdb, 0x1b, 0xeb, 0x62, 0xe6, 0x2e, 0xf4
+	},
+};
+
+#define MAX_NUM_CPUS	32
+
+
+struct hv_input_signal_event_buffer {
+	u64 align8;
+	struct hv_input_signal_event event;
+};
+
+struct hv_context {
+	/* 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 *hypercall_page;
+
+	bool synic_initialized;
+
+	/*
+	 * This is used as an input param to HvCallSignalEvent hypercall. The
+	 * input param is immutable in our usage and must be dynamic mem (vs
+	 * stack or global). */
+	struct hv_input_signal_event_buffer *signal_event_buffer;
+	/* 8-bytes aligned of the buffer above */
+	struct hv_input_signal_event *signal_event_param;
+
+	void *synic_message_page[MAX_NUM_CPUS];
+	void *synic_event_page[MAX_NUM_CPUS];
+};
+
+extern struct hv_context hv_context;
+
+
+/* Hv Interface */
+
+extern int hv_init(void);
+
+extern void hv_cleanup(void);
+
+extern u16 hv_post_message(union hv_connection_id connection_id,
+			 enum hv_message_type message_type,
+			 void *payload, size_t payload_size);
+
+extern u16 hv_signal_event(void);
+
+extern void hv_synic_init(void *irqarg);
+
+extern void hv_synic_cleanup(void *arg);
+
+
+/* Interface */
+
+
+int hv_ringbuffer_init(struct hv_ring_buffer_info *ring_info, void *buffer,
+		   u32 buflen);
+
+void hv_ringbuffer_cleanup(struct hv_ring_buffer_info *ring_info);
+
+int hv_ringbuffer_write(struct hv_ring_buffer_info *ring_info,
+		    struct scatterlist *sglist,
+		    u32 sgcount);
+
+int hv_ringbuffer_peek(struct hv_ring_buffer_info *ring_info, void *buffer,
+		   u32 buflen);
+
+int hv_ringbuffer_read(struct hv_ring_buffer_info *ring_info,
+		   void *buffer,
+		   u32 buflen,
+		   u32 offset);
+
+u32 hv_get_ringbuffer_interrupt_mask(struct hv_ring_buffer_info *ring_info);
+
+void hv_dump_ring_info(struct hv_ring_buffer_info *ring_info, char *prefix);
+
+void hv_ringbuffer_get_debuginfo(struct hv_ring_buffer_info *ring_info,
+			    struct hv_ring_buffer_debug_info *debug_info);
+
+/*
+ * Maximum channels is determined by the size of the interrupt page
+ * which is PAGE_SIZE. 1/2 of PAGE_SIZE is for send endpoint interrupt
+ * and the other is receive endpoint interrupt
+ */
+#define MAX_NUM_CHANNELS	((PAGE_SIZE >> 1) << 3)	/* 16348 channels */
+
+/* The value here must be in multiple of 32 */
+/* TODO: Need to make this configurable */
+#define MAX_NUM_CHANNELS_SUPPORTED	256
+
+
+enum vmbus_connect_state {
+	DISCONNECTED,
+	CONNECTING,
+	CONNECTED,
+	DISCONNECTING
+};
+
+#define MAX_SIZE_CHANNEL_MESSAGE	HV_MESSAGE_PAYLOAD_BYTE_COUNT
+
+struct vmbus_connection {
+	enum vmbus_connect_state conn_state;
+
+	atomic_t next_gpadl_handle;
+
+	/*
+	 * Represents channel interrupts. Each bit position represents a
+	 * channel.  When a channel sends an interrupt via VMBUS, it finds its
+	 * bit in the sendInterruptPage, set it and calls Hv to generate a port
+	 * event. The other end receives the port event and parse the
+	 * recvInterruptPage to see which bit is set
+	 */
+	void *int_page;
+	void *send_int_page;
+	void *recv_int_page;
+
+	/*
+	 * 2 pages - 1st page for parent->child notification and 2nd
+	 * is child->parent notification
+	 */
+	void *monitor_pages;
+	struct list_head chn_msg_list;
+	spinlock_t channelmsg_lock;
+
+	/* List of channels */
+	struct list_head chn_list;
+	spinlock_t channel_lock;
+
+	struct workqueue_struct *work_queue;
+};
+
+
+struct vmbus_msginfo {
+	/* Bookkeeping stuff */
+	struct list_head msglist_entry;
+
+	/* The message itself */
+	unsigned char msg[0];
+};
+
+
+extern struct vmbus_connection vmbus_connection;
+
+/* General vmbus interface */
+
+struct hv_device *vmbus_child_device_create(struct hv_guid *type,
+					 struct hv_guid *instance,
+					 struct vmbus_channel *channel);
+
+int vmbus_child_device_register(struct hv_device *child_device_obj);
+void vmbus_child_device_unregister(struct hv_device *device_obj);
+
+/* static void */
+/* VmbusChildDeviceDestroy( */
+/* struct hv_device *); */
+
+struct vmbus_channel *relid2channel(u32 relid);
+
+
+/* Connection interface */
+
+int vmbus_connect(void);
+
+int vmbus_disconnect(void);
+
+int vmbus_post_msg(void *buffer, size_t buflen);
+
+int vmbus_set_event(u32 child_relid);
+
+void vmbus_on_event(unsigned long data);
+
+
+#endif /* _HYPERV_VMBUS_H */
diff -druN linux-2.6.39-libre/drivers/staging/hv/Kconfig linux-3.0-rc7-libre/drivers/staging/hv/Kconfig
--- linux-2.6.39-libre/drivers/staging/hv/Kconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/hv/Kconfig	2011-07-11 19:51:52.000000000 -0400
@@ -1,6 +1,6 @@
 config HYPERV
 	tristate "Microsoft Hyper-V client drivers"
-	depends on X86 && m
+	depends on X86 && ACPI && PCI && m
 	default n
 	help
 	  Select this option to run Linux as a Hyper-V client operating
@@ -31,7 +31,7 @@
 
 config HYPERV_UTILS
 	tristate "Microsoft Hyper-V Utilities driver"
-	depends on CONNECTOR
+	depends on CONNECTOR && NLS
 	default HYPERV
 	help
 	  Select this option to enable the Hyper-V Utilities.
diff -druN linux-2.6.39-libre/drivers/staging/hv/logging.h linux-3.0-rc7-libre/drivers/staging/hv/logging.h
--- linux-2.6.39-libre/drivers/staging/hv/logging.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/hv/logging.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,98 +0,0 @@
-/*
- *
- * Copyright (c) 2009, Microsoft 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., 59 Temple
- * Place - Suite 330, Boston, MA 02111-1307 USA.
- *
- * Authors:
- *   Haiyang Zhang <haiyangz@microsoft.com>
- *   Hank Janssen  <hjanssen@microsoft.com>
- *
- */
-
-
-#ifndef _LOGGING_H_
-#define _LOGGING_H_
-
-#define LOWORD(dw) ((unsigned short)(dw))
-#define HIWORD(dw) ((unsigned short)(((unsigned int) (dw) >> 16) & 0xFFFF))
-
-/* #include <linux/init.h> */
-/* #include <linux/module.h> */
-
-
-#define VMBUS				0x0001
-#define STORVSC				0x0002
-#define NETVSC				0x0004
-#define INPUTVSC			0x0008
-#define BLKVSC				0x0010
-#define VMBUS_DRV			0x0100
-#define STORVSC_DRV			0x0200
-#define NETVSC_DRV			0x0400
-#define INPUTVSC_DRV		0x0800
-#define BLKVSC_DRV			0x1000
-
-#define ALL_MODULES			(VMBUS		|\
-							STORVSC		|\
-							NETVSC		|\
-							INPUTVSC	|\
-							BLKVSC		|\
-							VMBUS_DRV	|\
-							STORVSC_DRV	|\
-							NETVSC_DRV	|\
-							INPUTVSC_DRV|\
-							BLKVSC_DRV)
-
-/* Logging Level */
-#define ERROR_LVL				3
-#define WARNING_LVL				4
-#define INFO_LVL				6
-#define DEBUG_LVL				7
-#define DEBUG_LVL_ENTEREXIT			8
-#define DEBUG_RING_LVL				9
-
-extern unsigned int vmbus_loglevel;
-
-#define DPRINT(mod, lvl, fmt, args...) do {\
-	if ((mod & (HIWORD(vmbus_loglevel))) &&	\
-	    (lvl <= LOWORD(vmbus_loglevel)))	\
-		printk(KERN_DEBUG #mod": %s() " fmt "\n", __func__, ## args);\
-	} while (0)
-
-#define DPRINT_DBG(mod, fmt, args...) do {\
-	if ((mod & (HIWORD(vmbus_loglevel))) &&		\
-	    (DEBUG_LVL <= LOWORD(vmbus_loglevel)))	\
-		printk(KERN_DEBUG #mod": %s() " fmt "\n", __func__, ## args);\
-	} while (0)
-
-#define DPRINT_INFO(mod, fmt, args...) do {\
-	if ((mod & (HIWORD(vmbus_loglevel))) &&		\
-	    (INFO_LVL <= LOWORD(vmbus_loglevel)))	\
-		printk(KERN_INFO #mod": " fmt "\n", ## args);\
-	} while (0)
-
-#define DPRINT_WARN(mod, fmt, args...) do {\
-	if ((mod & (HIWORD(vmbus_loglevel))) &&		\
-	    (WARNING_LVL <= LOWORD(vmbus_loglevel)))	\
-		printk(KERN_WARNING #mod": WARNING! " fmt "\n", ## args);\
-	} while (0)
-
-#define DPRINT_ERR(mod, fmt, args...) do {\
-	if ((mod & (HIWORD(vmbus_loglevel))) &&		\
-	    (ERROR_LVL <= LOWORD(vmbus_loglevel)))	\
-		printk(KERN_ERR #mod": %s() ERROR!! " fmt "\n",	\
-		       __func__, ## args);\
-	} while (0)
-
-#endif /* _LOGGING_H_ */
diff -druN linux-2.6.39-libre/drivers/staging/hv/Makefile linux-3.0-rc7-libre/drivers/staging/hv/Makefile
--- linux-2.6.39-libre/drivers/staging/hv/Makefile	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/hv/Makefile	2011-07-11 19:51:52.000000000 -0400
@@ -9,6 +9,6 @@
 		 hv.o connection.o channel.o \
 		 channel_mgmt.o ring_buffer.o
 hv_storvsc-y := storvsc_drv.o storvsc.o
-hv_blkvsc-y := blkvsc_drv.o blkvsc.o
+hv_blkvsc-y := blkvsc_drv.o  storvsc.o
 hv_netvsc-y := netvsc_drv.o netvsc.o rndis_filter.o
 hv_utils-y := hv_util.o hv_kvp.o
diff -druN linux-2.6.39-libre/drivers/staging/hv/netvsc_api.h linux-3.0-rc7-libre/drivers/staging/hv/netvsc_api.h
--- linux-2.6.39-libre/drivers/staging/hv/netvsc_api.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/hv/netvsc_api.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,116 +0,0 @@
-/*
- *
- * Copyright (c) 2009, Microsoft 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., 59 Temple
- * Place - Suite 330, Boston, MA 02111-1307 USA.
- *
- * Authors:
- *   Haiyang Zhang <haiyangz@microsoft.com>
- *   Hank Janssen  <hjanssen@microsoft.com>
- *
- */
-
-
-#ifndef _NETVSC_API_H_
-#define _NETVSC_API_H_
-
-#include "vmbus_api.h"
-
-/* Fwd declaration */
-struct hv_netvsc_packet;
-
-/* Represent the xfer page packet which contains 1 or more netvsc packet */
-struct xferpage_packet {
-	struct list_head list_ent;
-
-	/* # of netvsc packets this xfer packet contains */
-	u32 count;
-};
-
-/* The number of pages which are enough to cover jumbo frame buffer. */
-#define NETVSC_PACKET_MAXPAGE		4
-
-/*
- * Represent netvsc packet which contains 1 RNDIS and 1 ethernet frame
- * within the RNDIS
- */
-struct hv_netvsc_packet {
-	/* Bookkeeping stuff */
-	struct list_head list_ent;
-
-	struct hv_device *device;
-	bool is_data_pkt;
-
-	/*
-	 * Valid only for receives when we break a xfer page packet
-	 * into multiple netvsc packets
-	 */
-	struct xferpage_packet *xfer_page_pkt;
-
-	union {
-		struct{
-			u64 recv_completion_tid;
-			void *recv_completion_ctx;
-			void (*recv_completion)(void *context);
-		} recv;
-		struct{
-			u64 send_completion_tid;
-			void *send_completion_ctx;
-			void (*send_completion)(void *context);
-		} send;
-	} completion;
-
-	/* This points to the memory after page_buf */
-	void *extension;
-
-	u32 total_data_buflen;
-	/* Points to the send/receive buffer where the ethernet frame is */
-	u32 page_buf_cnt;
-	struct hv_page_buffer page_buf[NETVSC_PACKET_MAXPAGE];
-};
-
-/* Represents the net vsc driver */
-struct netvsc_driver {
-	/* Must be the first field */
-	/* Which is a bug FIXME! */
-	struct hv_driver base;
-
-	u32 ring_buf_size;
-	u32 req_ext_size;
-
-	/*
-	 * This is set by the caller to allow us to callback when we
-	 * receive a packet from the "wire"
-	 */
-	int (*recv_cb)(struct hv_device *dev,
-				 struct hv_netvsc_packet *packet);
-	void (*link_status_change)(struct hv_device *dev, u32 status);
-
-	/* Specific to this driver */
-	int (*send)(struct hv_device *dev, struct hv_netvsc_packet *packet);
-
-	void *ctx;
-};
-
-struct netvsc_device_info {
-	unsigned char mac_adr[6];
-	bool link_state;	/* 0 - link up, 1 - link down */
-};
-
-/* Interface */
-int netvsc_initialize(struct hv_driver *drv);
-int rndis_filter_open(struct hv_device *dev);
-int rndis_filter_close(struct hv_device *dev);
-
-#endif /* _NETVSC_API_H_ */
diff -druN linux-2.6.39-libre/drivers/staging/hv/netvsc.c linux-3.0-rc7-libre/drivers/staging/hv/netvsc.c
--- linux-2.6.39-libre/drivers/staging/hv/netvsc.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/hv/netvsc.c	2011-07-11 19:51:52.000000000 -0400
@@ -18,6 +18,8 @@
  *   Haiyang Zhang <haiyangz@microsoft.com>
  *   Hank Janssen  <hjanssen@microsoft.com>
  */
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/kernel.h>
 #include <linux/sched.h>
 #include <linux/wait.h>
@@ -25,11 +27,9 @@
 #include <linux/delay.h>
 #include <linux/io.h>
 #include <linux/slab.h>
-#include "hv_api.h"
-#include "logging.h"
-#include "netvsc.h"
-#include "rndis_filter.h"
-#include "channel.h"
+
+#include "hyperv.h"
+#include "hyperv_net.h"
 
 
 /* Globals */
@@ -43,38 +43,6 @@
 	}
 };
 
-static int netvsc_device_add(struct hv_device *device, void *additional_info);
-
-static int netvsc_device_remove(struct hv_device *device);
-
-static void netvsc_cleanup(struct hv_driver *driver);
-
-static void netvsc_channel_cb(void *context);
-
-static int netvsc_init_send_buf(struct hv_device *device);
-
-static int netvsc_init_recv_buf(struct hv_device *device);
-
-static int netvsc_destroy_send_buf(struct netvsc_device *net_device);
-
-static int netvsc_destroy_recv_buf(struct netvsc_device *net_device);
-
-static int netvsc_connect_vsp(struct hv_device *device);
-
-static void netvsc_send_completion(struct hv_device *device,
-				   struct vmpacket_descriptor *packet);
-
-static int netvsc_send(struct hv_device *device,
-			struct hv_netvsc_packet *packet);
-
-static void netvsc_receive(struct hv_device *device,
-			    struct vmpacket_descriptor *packet);
-
-static void netvsc_receive_completion(void *context);
-
-static void netvsc_send_recv_completion(struct hv_device *device,
-					u64 transaction_id);
-
 
 static struct netvsc_device *alloc_net_device(struct hv_device *device)
 {
@@ -171,43 +139,85 @@
 	return net_device;
 }
 
-/*
- * netvsc_initialize - Main entry point
- */
-int netvsc_initialize(struct hv_driver *drv)
+static int netvsc_destroy_recv_buf(struct netvsc_device *net_device)
 {
-	struct netvsc_driver *driver = (struct netvsc_driver *)drv;
+	struct nvsp_message *revoke_packet;
+	int ret = 0;
 
-	DPRINT_DBG(NETVSC, "sizeof(struct hv_netvsc_packet)=%zd, "
-		   "sizeof(struct nvsp_message)=%zd, "
-		   "sizeof(struct vmtransfer_page_packet_header)=%zd",
-		   sizeof(struct hv_netvsc_packet),
-		   sizeof(struct nvsp_message),
-		   sizeof(struct vmtransfer_page_packet_header));
+	/*
+	 * If we got a section count, it means we received a
+	 * SendReceiveBufferComplete msg (ie sent
+	 * NvspMessage1TypeSendReceiveBuffer msg) therefore, we need
+	 * to send a revoke msg here
+	 */
+	if (net_device->recv_section_cnt) {
+		/* Send the revoke receive buffer */
+		revoke_packet = &net_device->revoke_packet;
+		memset(revoke_packet, 0, sizeof(struct nvsp_message));
 
-	drv->name = driver_name;
-	memcpy(&drv->dev_type, &netvsc_device_type, sizeof(struct hv_guid));
+		revoke_packet->hdr.msg_type =
+			NVSP_MSG1_TYPE_REVOKE_RECV_BUF;
+		revoke_packet->msg.v1_msg.
+		revoke_recv_buf.id = NETVSC_RECEIVE_BUFFER_ID;
 
-	/* Setup the dispatch table */
-	driver->base.dev_add	= netvsc_device_add;
-	driver->base.dev_rm	= netvsc_device_remove;
-	driver->base.cleanup		= netvsc_cleanup;
+		ret = vmbus_sendpacket(net_device->dev->channel,
+				       revoke_packet,
+				       sizeof(struct nvsp_message),
+				       (unsigned long)revoke_packet,
+				       VM_PKT_DATA_INBAND, 0);
+		/*
+		 * If we failed here, we might as well return and
+		 * have a leak rather than continue and a bugchk
+		 */
+		if (ret != 0) {
+			dev_err(&net_device->dev->device, "unable to send "
+				"revoke receive buffer to netvsp");
+			return -1;
+		}
+	}
 
-	driver->send			= netvsc_send;
+	/* Teardown the gpadl on the vsp end */
+	if (net_device->recv_buf_gpadl_handle) {
+		ret = vmbus_teardown_gpadl(net_device->dev->channel,
+			   net_device->recv_buf_gpadl_handle);
 
-	rndis_filter_init(driver);
-	return 0;
+		/* If we failed here, we might as well return and have a leak
+		 * rather than continue and a bugchk
+		 */
+		if (ret != 0) {
+			dev_err(&net_device->dev->device,
+				   "unable to teardown receive buffer's gpadl");
+			return -1;
+		}
+		net_device->recv_buf_gpadl_handle = 0;
+	}
+
+	if (net_device->recv_buf) {
+		/* Free up the receive buffer */
+		free_pages((unsigned long)net_device->recv_buf,
+			get_order(net_device->recv_buf_size));
+		net_device->recv_buf = NULL;
+	}
+
+	if (net_device->recv_section) {
+		net_device->recv_section_cnt = 0;
+		kfree(net_device->recv_section);
+		net_device->recv_section = NULL;
+	}
+
+	return ret;
 }
 
 static int netvsc_init_recv_buf(struct hv_device *device)
 {
 	int ret = 0;
+	int t;
 	struct netvsc_device *net_device;
 	struct nvsp_message *init_packet;
 
 	net_device = get_outbound_net_device(device);
 	if (!net_device) {
-		DPRINT_ERR(NETVSC, "unable to get net device..."
+		dev_err(&device->device, "unable to get net device..."
 			   "device being destroyed?");
 		return -1;
 	}
@@ -216,15 +226,12 @@
 		(void *)__get_free_pages(GFP_KERNEL|__GFP_ZERO,
 				get_order(net_device->recv_buf_size));
 	if (!net_device->recv_buf) {
-		DPRINT_ERR(NETVSC,
-			   "unable to allocate receive buffer of size %d",
-			   net_device->recv_buf_size);
+		dev_err(&device->device, "unable to allocate receive "
+			"buffer of size %d", net_device->recv_buf_size);
 		ret = -1;
 		goto cleanup;
 	}
 
-	DPRINT_INFO(NETVSC, "Establishing receive buffer's GPADL...");
-
 	/*
 	 * Establish the gpadl handle for this buffer on this
 	 * channel.  Note: This call uses the vmbus connection rather
@@ -234,15 +241,13 @@
 				    net_device->recv_buf_size,
 				    &net_device->recv_buf_gpadl_handle);
 	if (ret != 0) {
-		DPRINT_ERR(NETVSC,
-			   "unable to establish receive buffer's gpadl");
+		dev_err(&device->device,
+			"unable to establish receive buffer's gpadl");
 		goto cleanup;
 	}
 
 
 	/* Notify the NetVsp of the gpadl handle */
-	DPRINT_INFO(NETVSC, "Sending NvspMessage1TypeSendReceiveBuffer...");
-
 	init_packet = &net_device->channel_init_pkt;
 
 	memset(init_packet, 0, sizeof(struct nvsp_message));
@@ -254,28 +259,25 @@
 		send_recv_buf.id = NETVSC_RECEIVE_BUFFER_ID;
 
 	/* Send the gpadl notification request */
-	net_device->wait_condition = 0;
 	ret = vmbus_sendpacket(device->channel, init_packet,
 			       sizeof(struct nvsp_message),
 			       (unsigned long)init_packet,
 			       VM_PKT_DATA_INBAND,
 			       VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
 	if (ret != 0) {
-		DPRINT_ERR(NETVSC,
-			   "unable to send receive buffer's gpadl to netvsp");
+		dev_err(&device->device,
+			"unable to send receive buffer's gpadl to netvsp");
 		goto cleanup;
 	}
 
-	wait_event_timeout(net_device->channel_init_wait,
-			net_device->wait_condition,
-			msecs_to_jiffies(1000));
-	BUG_ON(net_device->wait_condition == 0);
+	t = wait_for_completion_timeout(&net_device->channel_init_wait, HZ);
+	BUG_ON(t == 0);
 
 
 	/* Check the response */
 	if (init_packet->msg.v1_msg.
 	    send_recv_buf_complete.status != NVSP_STAT_SUCCESS) {
-		DPRINT_ERR(NETVSC, "Unable to complete receive buffer "
+		dev_err(&device->device, "Unable to complete receive buffer "
 			   "initialzation with NetVsp - status %d",
 			   init_packet->msg.v1_msg.
 			   send_recv_buf_complete.status);
@@ -301,14 +303,6 @@
 		net_device->recv_section_cnt *
 	       sizeof(struct nvsp_1_receive_buffer_section));
 
-	DPRINT_INFO(NETVSC, "Receive sections info (count %d, offset %d, "
-		    "endoffset %d, suballoc size %d, num suballocs %d)",
-		    net_device->recv_section_cnt,
-		    net_device->recv_section[0].offset,
-		    net_device->recv_section[0].end_offset,
-		    net_device->recv_section[0].sub_alloc_size,
-		    net_device->recv_section[0].num_sub_allocs);
-
 	/*
 	 * For 1st release, there should only be 1 section that represents the
 	 * entire receive buffer
@@ -329,15 +323,80 @@
 	return ret;
 }
 
+static int netvsc_destroy_send_buf(struct netvsc_device *net_device)
+{
+	struct nvsp_message *revoke_packet;
+	int ret = 0;
+
+	/*
+	 * If we got a section count, it means we received a
+	 *  SendReceiveBufferComplete msg (ie sent
+	 *  NvspMessage1TypeSendReceiveBuffer msg) therefore, we need
+	 *  to send a revoke msg here
+	 */
+	if (net_device->send_section_size) {
+		/* Send the revoke send buffer */
+		revoke_packet = &net_device->revoke_packet;
+		memset(revoke_packet, 0, sizeof(struct nvsp_message));
+
+		revoke_packet->hdr.msg_type =
+			NVSP_MSG1_TYPE_REVOKE_SEND_BUF;
+		revoke_packet->msg.v1_msg.
+			revoke_send_buf.id = NETVSC_SEND_BUFFER_ID;
+
+		ret = vmbus_sendpacket(net_device->dev->channel,
+				       revoke_packet,
+				       sizeof(struct nvsp_message),
+				       (unsigned long)revoke_packet,
+				       VM_PKT_DATA_INBAND, 0);
+		/*
+		 * If we failed here, we might as well return and have a leak
+		 * rather than continue and a bugchk
+		 */
+		if (ret != 0) {
+			dev_err(&net_device->dev->device, "unable to send "
+				"revoke send buffer to netvsp");
+			return -1;
+		}
+	}
+
+	/* Teardown the gpadl on the vsp end */
+	if (net_device->send_buf_gpadl_handle) {
+		ret = vmbus_teardown_gpadl(net_device->dev->channel,
+					   net_device->send_buf_gpadl_handle);
+
+		/*
+		 * If we failed here, we might as well return and have a leak
+		 * rather than continue and a bugchk
+		 */
+		if (ret != 0) {
+			dev_err(&net_device->dev->device,
+				"unable to teardown send buffer's gpadl");
+			return -1;
+		}
+		net_device->send_buf_gpadl_handle = 0;
+	}
+
+	if (net_device->send_buf) {
+		/* Free up the receive buffer */
+		free_pages((unsigned long)net_device->send_buf,
+				get_order(net_device->send_buf_size));
+		net_device->send_buf = NULL;
+	}
+
+	return ret;
+}
+
 static int netvsc_init_send_buf(struct hv_device *device)
 {
 	int ret = 0;
+	int t;
 	struct netvsc_device *net_device;
 	struct nvsp_message *init_packet;
 
 	net_device = get_outbound_net_device(device);
 	if (!net_device) {
-		DPRINT_ERR(NETVSC, "unable to get net device..."
+		dev_err(&device->device, "unable to get net device..."
 			   "device being destroyed?");
 		return -1;
 	}
@@ -350,14 +409,12 @@
 		(void *)__get_free_pages(GFP_KERNEL|__GFP_ZERO,
 				get_order(net_device->send_buf_size));
 	if (!net_device->send_buf) {
-		DPRINT_ERR(NETVSC, "unable to allocate send buffer of size %d",
-			   net_device->send_buf_size);
+		dev_err(&device->device, "unable to allocate send "
+			"buffer of size %d", net_device->send_buf_size);
 		ret = -1;
 		goto cleanup;
 	}
 
-	DPRINT_INFO(NETVSC, "Establishing send buffer's GPADL...");
-
 	/*
 	 * Establish the gpadl handle for this buffer on this
 	 * channel.  Note: This call uses the vmbus connection rather
@@ -367,13 +424,11 @@
 				    net_device->send_buf_size,
 				    &net_device->send_buf_gpadl_handle);
 	if (ret != 0) {
-		DPRINT_ERR(NETVSC, "unable to establish send buffer's gpadl");
+		dev_err(&device->device, "unable to establish send buffer's gpadl");
 		goto cleanup;
 	}
 
 	/* Notify the NetVsp of the gpadl handle */
-	DPRINT_INFO(NETVSC, "Sending NvspMessage1TypeSendSendBuffer...");
-
 	init_packet = &net_device->channel_init_pkt;
 
 	memset(init_packet, 0, sizeof(struct nvsp_message));
@@ -385,27 +440,25 @@
 		NETVSC_SEND_BUFFER_ID;
 
 	/* Send the gpadl notification request */
-	net_device->wait_condition = 0;
 	ret = vmbus_sendpacket(device->channel, init_packet,
 			       sizeof(struct nvsp_message),
 			       (unsigned long)init_packet,
 			       VM_PKT_DATA_INBAND,
 			       VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
 	if (ret != 0) {
-		DPRINT_ERR(NETVSC,
+		dev_err(&device->device,
 			   "unable to send receive buffer's gpadl to netvsp");
 		goto cleanup;
 	}
 
-	wait_event_timeout(net_device->channel_init_wait,
-			net_device->wait_condition,
-			msecs_to_jiffies(1000));
-	BUG_ON(net_device->wait_condition == 0);
+	t = wait_for_completion_timeout(&net_device->channel_init_wait, HZ);
+
+	BUG_ON(t == 0);
 
 	/* Check the response */
 	if (init_packet->msg.v1_msg.
 	    send_send_buf_complete.status != NVSP_STAT_SUCCESS) {
-		DPRINT_ERR(NETVSC, "Unable to complete send buffer "
+		dev_err(&device->device, "Unable to complete send buffer "
 			   "initialzation with NetVsp - status %d",
 			   init_packet->msg.v1_msg.
 			   send_send_buf_complete.status);
@@ -426,161 +479,17 @@
 	return ret;
 }
 
-static int netvsc_destroy_recv_buf(struct netvsc_device *net_device)
-{
-	struct nvsp_message *revoke_packet;
-	int ret = 0;
-
-	/*
-	 * If we got a section count, it means we received a
-	 * SendReceiveBufferComplete msg (ie sent
-	 * NvspMessage1TypeSendReceiveBuffer msg) therefore, we need
-	 * to send a revoke msg here
-	 */
-	if (net_device->recv_section_cnt) {
-		DPRINT_INFO(NETVSC,
-			    "Sending NvspMessage1TypeRevokeReceiveBuffer...");
-
-		/* Send the revoke receive buffer */
-		revoke_packet = &net_device->revoke_packet;
-		memset(revoke_packet, 0, sizeof(struct nvsp_message));
-
-		revoke_packet->hdr.msg_type =
-			NVSP_MSG1_TYPE_REVOKE_RECV_BUF;
-		revoke_packet->msg.v1_msg.
-		revoke_recv_buf.id = NETVSC_RECEIVE_BUFFER_ID;
-
-		ret = vmbus_sendpacket(net_device->dev->channel,
-				       revoke_packet,
-				       sizeof(struct nvsp_message),
-				       (unsigned long)revoke_packet,
-				       VM_PKT_DATA_INBAND, 0);
-		/*
-		 * If we failed here, we might as well return and
-		 * have a leak rather than continue and a bugchk
-		 */
-		if (ret != 0) {
-			DPRINT_ERR(NETVSC, "unable to send revoke receive "
-				   "buffer to netvsp");
-			return -1;
-		}
-	}
-
-	/* Teardown the gpadl on the vsp end */
-	if (net_device->recv_buf_gpadl_handle) {
-		DPRINT_INFO(NETVSC, "Tearing down receive buffer's GPADL...");
-
-		ret = vmbus_teardown_gpadl(net_device->dev->channel,
-			   net_device->recv_buf_gpadl_handle);
-
-		/* If we failed here, we might as well return and have a leak rather than continue and a bugchk */
-		if (ret != 0) {
-			DPRINT_ERR(NETVSC,
-				   "unable to teardown receive buffer's gpadl");
-			return -1;
-		}
-		net_device->recv_buf_gpadl_handle = 0;
-	}
-
-	if (net_device->recv_buf) {
-		DPRINT_INFO(NETVSC, "Freeing up receive buffer...");
-
-		/* Free up the receive buffer */
-		free_pages((unsigned long)net_device->recv_buf,
-			get_order(net_device->recv_buf_size));
-		net_device->recv_buf = NULL;
-	}
-
-	if (net_device->recv_section) {
-		net_device->recv_section_cnt = 0;
-		kfree(net_device->recv_section);
-		net_device->recv_section = NULL;
-	}
-
-	return ret;
-}
-
-static int netvsc_destroy_send_buf(struct netvsc_device *net_device)
-{
-	struct nvsp_message *revoke_packet;
-	int ret = 0;
-
-	/*
-	 * If we got a section count, it means we received a
-	 *  SendReceiveBufferComplete msg (ie sent
-	 *  NvspMessage1TypeSendReceiveBuffer msg) therefore, we need
-	 *  to send a revoke msg here
-	 */
-	if (net_device->send_section_size) {
-		DPRINT_INFO(NETVSC,
-			    "Sending NvspMessage1TypeRevokeSendBuffer...");
-
-		/* Send the revoke send buffer */
-		revoke_packet = &net_device->revoke_packet;
-		memset(revoke_packet, 0, sizeof(struct nvsp_message));
-
-		revoke_packet->hdr.msg_type =
-			NVSP_MSG1_TYPE_REVOKE_SEND_BUF;
-		revoke_packet->msg.v1_msg.
-			revoke_send_buf.id = NETVSC_SEND_BUFFER_ID;
-
-		ret = vmbus_sendpacket(net_device->dev->channel,
-				       revoke_packet,
-				       sizeof(struct nvsp_message),
-				       (unsigned long)revoke_packet,
-				       VM_PKT_DATA_INBAND, 0);
-		/*
-		 * If we failed here, we might as well return and have a leak
-		 * rather than continue and a bugchk
-		 */
-		if (ret != 0) {
-			DPRINT_ERR(NETVSC, "unable to send revoke send buffer "
-				   "to netvsp");
-			return -1;
-		}
-	}
-
-	/* Teardown the gpadl on the vsp end */
-	if (net_device->send_buf_gpadl_handle) {
-		DPRINT_INFO(NETVSC, "Tearing down send buffer's GPADL...");
-		ret = vmbus_teardown_gpadl(net_device->dev->channel,
-					   net_device->send_buf_gpadl_handle);
-
-		/*
-		 * If we failed here, we might as well return and have a leak
-		 * rather than continue and a bugchk
-		 */
-		if (ret != 0) {
-			DPRINT_ERR(NETVSC, "unable to teardown send buffer's "
-				   "gpadl");
-			return -1;
-		}
-		net_device->send_buf_gpadl_handle = 0;
-	}
-
-	if (net_device->send_buf) {
-		DPRINT_INFO(NETVSC, "Freeing up send buffer...");
-
-		/* Free up the receive buffer */
-		free_pages((unsigned long)net_device->send_buf,
-				get_order(net_device->send_buf_size));
-		net_device->send_buf = NULL;
-	}
-
-	return ret;
-}
-
 
 static int netvsc_connect_vsp(struct hv_device *device)
 {
-	int ret;
+	int ret, t;
 	struct netvsc_device *net_device;
 	struct nvsp_message *init_packet;
 	int ndis_version;
 
 	net_device = get_outbound_net_device(device);
 	if (!net_device) {
-		DPRINT_ERR(NETVSC, "unable to get net device..."
+		dev_err(&device->device, "unable to get net device..."
 			   "device being destroyed?");
 		return -1;
 	}
@@ -594,54 +503,34 @@
 	init_packet->msg.init_msg.init.max_protocol_ver =
 		NVSP_MAX_PROTOCOL_VERSION;
 
-	DPRINT_INFO(NETVSC, "Sending NvspMessageTypeInit...");
-
 	/* Send the init request */
-	net_device->wait_condition = 0;
 	ret = vmbus_sendpacket(device->channel, init_packet,
 			       sizeof(struct nvsp_message),
 			       (unsigned long)init_packet,
 			       VM_PKT_DATA_INBAND,
 			       VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
 
-	if (ret != 0) {
-		DPRINT_ERR(NETVSC, "unable to send NvspMessageTypeInit");
+	if (ret != 0)
 		goto cleanup;
-	}
 
-	wait_event_timeout(net_device->channel_init_wait,
-			net_device->wait_condition,
-			msecs_to_jiffies(1000));
-	if (net_device->wait_condition == 0) {
+	t = wait_for_completion_timeout(&net_device->channel_init_wait, HZ);
+
+	if (t == 0) {
 		ret = -ETIMEDOUT;
 		goto cleanup;
 	}
 
-	DPRINT_INFO(NETVSC, "NvspMessageTypeInit status(%d) max mdl chain (%d)",
-		init_packet->msg.init_msg.init_complete.status,
-		init_packet->msg.init_msg.
-		    init_complete.max_mdl_chain_len);
-
 	if (init_packet->msg.init_msg.init_complete.status !=
 	    NVSP_STAT_SUCCESS) {
-		DPRINT_ERR(NETVSC,
-			"unable to initialize with netvsp (status 0x%x)",
-			init_packet->msg.init_msg.init_complete.status);
 		ret = -1;
 		goto cleanup;
 	}
 
 	if (init_packet->msg.init_msg.init_complete.
 	    negotiated_protocol_ver != NVSP_PROTOCOL_VERSION_1) {
-		DPRINT_ERR(NETVSC, "unable to initialize with netvsp "
-			   "(version expected 1 got %d)",
-			   init_packet->msg.init_msg.
-			   init_complete.negotiated_protocol_ver);
 		ret = -1;
 		goto cleanup;
 	}
-	DPRINT_INFO(NETVSC, "Sending NvspMessage1TypeSendNdisVersion...");
-
 	/* Send the ndis version */
 	memset(init_packet, 0, sizeof(struct nvsp_message));
 
@@ -661,8 +550,6 @@
 				(unsigned long)init_packet,
 				VM_PKT_DATA_INBAND, 0);
 	if (ret != 0) {
-		DPRINT_ERR(NETVSC,
-			   "unable to send NvspMessage1TypeSendNdisVersion");
 		ret = -1;
 		goto cleanup;
 	}
@@ -677,143 +564,42 @@
 	return ret;
 }
 
-static void NetVscDisconnectFromVsp(struct netvsc_device *net_device)
+static void netvsc_disconnect_vsp(struct netvsc_device *net_device)
 {
 	netvsc_destroy_recv_buf(net_device);
 	netvsc_destroy_send_buf(net_device);
 }
 
 /*
- * netvsc_device_add - Callback when the device belonging to this
- * driver is added
- */
-static int netvsc_device_add(struct hv_device *device, void *additional_info)
-{
-	int ret = 0;
-	int i;
-	struct netvsc_device *net_device;
-	struct hv_netvsc_packet *packet, *pos;
-	struct netvsc_driver *net_driver =
-				(struct netvsc_driver *)device->drv;
-
-	net_device = alloc_net_device(device);
-	if (!net_device) {
-		ret = -1;
-		goto cleanup;
-	}
-
-	DPRINT_DBG(NETVSC, "netvsc channel object allocated - %p", net_device);
-
-	/* Initialize the NetVSC channel extension */
-	net_device->recv_buf_size = NETVSC_RECEIVE_BUFFER_SIZE;
-	spin_lock_init(&net_device->recv_pkt_list_lock);
-
-	net_device->send_buf_size = NETVSC_SEND_BUFFER_SIZE;
-
-	INIT_LIST_HEAD(&net_device->recv_pkt_list);
-
-	for (i = 0; i < NETVSC_RECEIVE_PACKETLIST_COUNT; i++) {
-		packet = kzalloc(sizeof(struct hv_netvsc_packet) +
-				 (NETVSC_RECEIVE_SG_COUNT *
-				  sizeof(struct hv_page_buffer)), GFP_KERNEL);
-		if (!packet) {
-			DPRINT_DBG(NETVSC, "unable to allocate netvsc pkts "
-				   "for receive pool (wanted %d got %d)",
-				   NETVSC_RECEIVE_PACKETLIST_COUNT, i);
-			break;
-		}
-		list_add_tail(&packet->list_ent,
-			      &net_device->recv_pkt_list);
-	}
-	init_waitqueue_head(&net_device->channel_init_wait);
-
-	/* Open the channel */
-	ret = vmbus_open(device->channel, net_driver->ring_buf_size,
-			 net_driver->ring_buf_size, NULL, 0,
-			 netvsc_channel_cb, device);
-
-	if (ret != 0) {
-		DPRINT_ERR(NETVSC, "unable to open channel: %d", ret);
-		ret = -1;
-		goto cleanup;
-	}
-
-	/* Channel is opened */
-	DPRINT_INFO(NETVSC, "*** NetVSC channel opened successfully! ***");
-
-	/* Connect with the NetVsp */
-	ret = netvsc_connect_vsp(device);
-	if (ret != 0) {
-		DPRINT_ERR(NETVSC, "unable to connect to NetVSP - %d", ret);
-		ret = -1;
-		goto close;
-	}
-
-	DPRINT_INFO(NETVSC, "*** NetVSC channel handshake result - %d ***",
-		    ret);
-
-	return ret;
-
-close:
-	/* Now, we can close the channel safely */
-	vmbus_close(device->channel);
-
-cleanup:
-
-	if (net_device) {
-		list_for_each_entry_safe(packet, pos,
-					 &net_device->recv_pkt_list,
-					 list_ent) {
-			list_del(&packet->list_ent);
-			kfree(packet);
-		}
-
-		release_outbound_net_device(device);
-		release_inbound_net_device(device);
-
-		free_net_device(net_device);
-	}
-
-	return ret;
-}
-
-/*
  * netvsc_device_remove - Callback when the root bus device is removed
  */
-static int netvsc_device_remove(struct hv_device *device)
+int netvsc_device_remove(struct hv_device *device)
 {
 	struct netvsc_device *net_device;
 	struct hv_netvsc_packet *netvsc_packet, *pos;
 
-	DPRINT_INFO(NETVSC, "Disabling outbound traffic on net device (%p)...",
-		    device->ext);
-
 	/* Stop outbound traffic ie sends and receives completions */
 	net_device = release_outbound_net_device(device);
 	if (!net_device) {
-		DPRINT_ERR(NETVSC, "No net device present!!");
+		dev_err(&device->device, "No net device present!!");
 		return -1;
 	}
 
 	/* Wait for all send completions */
 	while (atomic_read(&net_device->num_outstanding_sends)) {
-		DPRINT_INFO(NETVSC, "waiting for %d requests to complete...",
-			    atomic_read(&net_device->num_outstanding_sends));
+		dev_err(&device->device,
+			"waiting for %d requests to complete...",
+			atomic_read(&net_device->num_outstanding_sends));
 		udelay(100);
 	}
 
-	DPRINT_INFO(NETVSC, "Disconnecting from netvsp...");
-
-	NetVscDisconnectFromVsp(net_device);
-
-	DPRINT_INFO(NETVSC, "Disabling inbound traffic on net device (%p)...",
-		    device->ext);
+	netvsc_disconnect_vsp(net_device);
 
 	/* Stop inbound traffic ie receives and sends completions */
 	net_device = release_inbound_net_device(device);
 
 	/* At this point, no one should be accessing netDevice except in here */
-	DPRINT_INFO(NETVSC, "net device (%p) safe to remove", net_device);
+	dev_notice(&device->device, "net device safe to remove");
 
 	/* Now, we can close the channel safely */
 	vmbus_close(device->channel);
@@ -829,13 +615,6 @@
 	return 0;
 }
 
-/*
- * netvsc_cleanup - Perform any cleanup when the driver is removed
- */
-static void netvsc_cleanup(struct hv_driver *drv)
-{
-}
-
 static void netvsc_send_completion(struct hv_device *device,
 				   struct vmpacket_descriptor *packet)
 {
@@ -845,7 +624,7 @@
 
 	net_device = get_inbound_net_device(device);
 	if (!net_device) {
-		DPRINT_ERR(NETVSC, "unable to get net device..."
+		dev_err(&device->device, "unable to get net device..."
 			   "device being destroyed?");
 		return;
 	}
@@ -853,9 +632,6 @@
 	nvsp_packet = (struct nvsp_message *)((unsigned long)packet +
 			(packet->offset8 << 3));
 
-	DPRINT_DBG(NETVSC, "send completion packet - type %d",
-		   nvsp_packet->hdr.msg_type);
-
 	if ((nvsp_packet->hdr.msg_type == NVSP_MSG_TYPE_INIT_COMPLETE) ||
 	    (nvsp_packet->hdr.msg_type ==
 	     NVSP_MSG1_TYPE_SEND_RECV_BUF_COMPLETE) ||
@@ -864,8 +640,7 @@
 		/* Copy the response back */
 		memcpy(&net_device->channel_init_pkt, nvsp_packet,
 		       sizeof(struct nvsp_message));
-		net_device->wait_condition = 1;
-		wake_up(&net_device->channel_init_wait);
+		complete(&net_device->channel_init_wait);
 	} else if (nvsp_packet->hdr.msg_type ==
 		   NVSP_MSG1_TYPE_SEND_RNDIS_PKT_COMPLETE) {
 		/* Get the send context */
@@ -878,14 +653,14 @@
 
 		atomic_dec(&net_device->num_outstanding_sends);
 	} else {
-		DPRINT_ERR(NETVSC, "Unknown send completion packet type - "
+		dev_err(&device->device, "Unknown send completion packet type- "
 			   "%d received!!", nvsp_packet->hdr.msg_type);
 	}
 
 	put_net_device(device);
 }
 
-static int netvsc_send(struct hv_device *device,
+int netvsc_send(struct hv_device *device,
 			struct hv_netvsc_packet *packet)
 {
 	struct netvsc_device *net_device;
@@ -895,7 +670,7 @@
 
 	net_device = get_outbound_net_device(device);
 	if (!net_device) {
-		DPRINT_ERR(NETVSC, "net device (%p) shutting down..."
+		dev_err(&device->device, "net device (%p) shutting down..."
 			   "ignoring outbound packets", net_device);
 		return -2;
 	}
@@ -931,7 +706,7 @@
 	}
 
 	if (ret != 0)
-		DPRINT_ERR(NETVSC, "Unable to send packet %p ret %d",
+		dev_err(&device->device, "Unable to send packet %p ret %d",
 			   packet, ret);
 
 	atomic_inc(&net_device->num_outstanding_sends);
@@ -939,6 +714,98 @@
 	return ret;
 }
 
+static void netvsc_send_recv_completion(struct hv_device *device,
+					u64 transaction_id)
+{
+	struct nvsp_message recvcompMessage;
+	int retries = 0;
+	int ret;
+
+	recvcompMessage.hdr.msg_type =
+				NVSP_MSG1_TYPE_SEND_RNDIS_PKT_COMPLETE;
+
+	/* FIXME: Pass in the status */
+	recvcompMessage.msg.v1_msg.send_rndis_pkt_complete.status =
+		NVSP_STAT_SUCCESS;
+
+retry_send_cmplt:
+	/* Send the completion */
+	ret = vmbus_sendpacket(device->channel, &recvcompMessage,
+			       sizeof(struct nvsp_message), transaction_id,
+			       VM_PKT_COMP, 0);
+	if (ret == 0) {
+		/* success */
+		/* no-op */
+	} else if (ret == -1) {
+		/* no more room...wait a bit and attempt to retry 3 times */
+		retries++;
+		dev_err(&device->device, "unable to send receive completion pkt"
+			" (tid %llx)...retrying %d", transaction_id, retries);
+
+		if (retries < 4) {
+			udelay(100);
+			goto retry_send_cmplt;
+		} else {
+			dev_err(&device->device, "unable to send receive "
+				"completion pkt (tid %llx)...give up retrying",
+				transaction_id);
+		}
+	} else {
+		dev_err(&device->device, "unable to send receive "
+			"completion pkt - %llx", transaction_id);
+	}
+}
+
+/* Send a receive completion packet to RNDIS device (ie NetVsp) */
+static void netvsc_receive_completion(void *context)
+{
+	struct hv_netvsc_packet *packet = context;
+	struct hv_device *device = (struct hv_device *)packet->device;
+	struct netvsc_device *net_device;
+	u64 transaction_id = 0;
+	bool fsend_receive_comp = false;
+	unsigned long flags;
+
+	/*
+	 * Even though it seems logical to do a GetOutboundNetDevice() here to
+	 * send out receive completion, we are using GetInboundNetDevice()
+	 * since we may have disable outbound traffic already.
+	 */
+	net_device = get_inbound_net_device(device);
+	if (!net_device) {
+		dev_err(&device->device, "unable to get net device..."
+			   "device being destroyed?");
+		return;
+	}
+
+	/* Overloading use of the lock. */
+	spin_lock_irqsave(&net_device->recv_pkt_list_lock, flags);
+
+	packet->xfer_page_pkt->count--;
+
+	/*
+	 * Last one in the line that represent 1 xfer page packet.
+	 * Return the xfer page packet itself to the freelist
+	 */
+	if (packet->xfer_page_pkt->count == 0) {
+		fsend_receive_comp = true;
+		transaction_id = packet->completion.recv.recv_completion_tid;
+		list_add_tail(&packet->xfer_page_pkt->list_ent,
+			      &net_device->recv_pkt_list);
+
+	}
+
+	/* Put the packet back */
+	list_add_tail(&packet->list_ent, &net_device->recv_pkt_list);
+	spin_unlock_irqrestore(&net_device->recv_pkt_list_lock, flags);
+
+	/* Send a receive completion for the xfer page packet */
+	if (fsend_receive_comp)
+		netvsc_send_recv_completion(device, transaction_id);
+
+	put_net_device(device);
+}
+
 static void netvsc_receive(struct hv_device *device,
 			    struct vmpacket_descriptor *packet)
 {
@@ -953,11 +820,12 @@
 	int i, j;
 	int count = 0, bytes_remain = 0;
 	unsigned long flags;
+
 	LIST_HEAD(listHead);
 
 	net_device = get_inbound_net_device(device);
 	if (!net_device) {
-		DPRINT_ERR(NETVSC, "unable to get net device..."
+		dev_err(&device->device, "unable to get net device..."
 			   "device being destroyed?");
 		return;
 	}
@@ -967,7 +835,7 @@
 	 * packet
 	 */
 	if (packet->type != VM_PKT_DATA_USING_XFER_PAGES) {
-		DPRINT_ERR(NETVSC, "Unknown packet type received - %d",
+		dev_err(&device->device, "Unknown packet type received - %d",
 			   packet->type);
 		put_net_device(device);
 		return;
@@ -979,28 +847,22 @@
 	/* Make sure this is a valid nvsp packet */
 	if (nvsp_packet->hdr.msg_type !=
 	    NVSP_MSG1_TYPE_SEND_RNDIS_PKT) {
-		DPRINT_ERR(NETVSC, "Unknown nvsp packet type received - %d",
-			   nvsp_packet->hdr.msg_type);
+		dev_err(&device->device, "Unknown nvsp packet type received-"
+			" %d", nvsp_packet->hdr.msg_type);
 		put_net_device(device);
 		return;
 	}
 
-	DPRINT_DBG(NETVSC, "NVSP packet received - type %d",
-		   nvsp_packet->hdr.msg_type);
-
 	vmxferpage_packet = (struct vmtransfer_page_packet_header *)packet;
 
 	if (vmxferpage_packet->xfer_pageset_id != NETVSC_RECEIVE_BUFFER_ID) {
-		DPRINT_ERR(NETVSC, "Invalid xfer page set id - "
+		dev_err(&device->device, "Invalid xfer page set id - "
 			   "expecting %x got %x", NETVSC_RECEIVE_BUFFER_ID,
 			   vmxferpage_packet->xfer_pageset_id);
 		put_net_device(device);
 		return;
 	}
 
-	DPRINT_DBG(NETVSC, "xfer page - range count %d",
-		   vmxferpage_packet->range_cnt);
-
 	/*
 	 * Grab free packets (range count + 1) to represent this xfer
 	 * page packet. +1 to represent the xfer page packet itself.
@@ -1021,9 +883,9 @@
 	 * some of the xfer page packet ranges...
 	 */
 	if (count < 2) {
-		DPRINT_ERR(NETVSC, "Got only %d netvsc pkt...needed %d pkts. "
-			   "Dropping this xfer page packet completely!",
-			   count, vmxferpage_packet->range_cnt + 1);
+		dev_err(&device->device, "Got only %d netvsc pkt...needed "
+			"%d pkts. Dropping this xfer page packet completely!",
+			count, vmxferpage_packet->range_cnt + 1);
 
 		/* Return it to the freelist */
 		spin_lock_irqsave(&net_device->recv_pkt_list_lock, flags);
@@ -1049,9 +911,9 @@
 	xferpage_packet->count = count - 1;
 
 	if (xferpage_packet->count != vmxferpage_packet->range_cnt) {
-		DPRINT_INFO(NETVSC, "Needed %d netvsc pkts to satisy this xfer "
-			    "page...got %d", vmxferpage_packet->range_cnt,
-			    xferpage_packet->count);
+		dev_err(&device->device, "Needed %d netvsc pkts to satisy "
+			"this xfer page...got %d",
+			vmxferpage_packet->range_cnt, xferpage_packet->count);
 	}
 
 	/* Each range represents 1 RNDIS pkt that contains 1 ethernet frame */
@@ -1117,17 +979,9 @@
 					break;
 			}
 		}
-		DPRINT_DBG(NETVSC, "[%d] - (abs offset %u len %u) => "
-			   "(pfn %llx, offset %u, len %u)", i,
-			   vmxferpage_packet->ranges[i].byte_offset,
-			   vmxferpage_packet->ranges[i].byte_count,
-			   netvsc_packet->page_buf[0].pfn,
-			   netvsc_packet->page_buf[0].offset,
-			   netvsc_packet->page_buf[0].len);
 
 		/* Pass it to the upper layer */
-		((struct netvsc_driver *)device->drv)->
-			recv_cb(device, netvsc_packet);
+		rndis_filter_receive(device, netvsc_packet);
 
 		netvsc_receive_completion(netvsc_packet->
 				completion.recv.recv_completion_ctx);
@@ -1136,101 +990,6 @@
 	put_net_device(device);
 }
 
-static void netvsc_send_recv_completion(struct hv_device *device,
-					u64 transaction_id)
-{
-	struct nvsp_message recvcompMessage;
-	int retries = 0;
-	int ret;
-
-	DPRINT_DBG(NETVSC, "Sending receive completion pkt - %llx",
-		   transaction_id);
-
-	recvcompMessage.hdr.msg_type =
-				NVSP_MSG1_TYPE_SEND_RNDIS_PKT_COMPLETE;
-
-	/* FIXME: Pass in the status */
-	recvcompMessage.msg.v1_msg.send_rndis_pkt_complete.status =
-		NVSP_STAT_SUCCESS;
-
-retry_send_cmplt:
-	/* Send the completion */
-	ret = vmbus_sendpacket(device->channel, &recvcompMessage,
-			       sizeof(struct nvsp_message), transaction_id,
-			       VM_PKT_COMP, 0);
-	if (ret == 0) {
-		/* success */
-		/* no-op */
-	} else if (ret == -1) {
-		/* no more room...wait a bit and attempt to retry 3 times */
-		retries++;
-		DPRINT_ERR(NETVSC, "unable to send receive completion pkt "
-			   "(tid %llx)...retrying %d", transaction_id, retries);
-
-		if (retries < 4) {
-			udelay(100);
-			goto retry_send_cmplt;
-		} else {
-			DPRINT_ERR(NETVSC, "unable to send receive completion "
-				  "pkt (tid %llx)...give up retrying",
-				  transaction_id);
-		}
-	} else {
-		DPRINT_ERR(NETVSC, "unable to send receive completion pkt - "
-			   "%llx", transaction_id);
-	}
-}
-
-/* Send a receive completion packet to RNDIS device (ie NetVsp) */
-static void netvsc_receive_completion(void *context)
-{
-	struct hv_netvsc_packet *packet = context;
-	struct hv_device *device = (struct hv_device *)packet->device;
-	struct netvsc_device *net_device;
-	u64 transaction_id = 0;
-	bool fsend_receive_comp = false;
-	unsigned long flags;
-
-	/*
-	 * Even though it seems logical to do a GetOutboundNetDevice() here to
-	 * send out receive completion, we are using GetInboundNetDevice()
-	 * since we may have disable outbound traffic already.
-	 */
-	net_device = get_inbound_net_device(device);
-	if (!net_device) {
-		DPRINT_ERR(NETVSC, "unable to get net device..."
-			   "device being destroyed?");
-		return;
-	}
-
-	/* Overloading use of the lock. */
-	spin_lock_irqsave(&net_device->recv_pkt_list_lock, flags);
-
-	packet->xfer_page_pkt->count--;
-
-	/*
-	 * Last one in the line that represent 1 xfer page packet.
-	 * Return the xfer page packet itself to the freelist
-	 */
-	if (packet->xfer_page_pkt->count == 0) {
-		fsend_receive_comp = true;
-		transaction_id = packet->completion.recv.recv_completion_tid;
-		list_add_tail(&packet->xfer_page_pkt->list_ent,
-			      &net_device->recv_pkt_list);
-
-	}
-
-	/* Put the packet back */
-	list_add_tail(&packet->list_ent, &net_device->recv_pkt_list);
-	spin_unlock_irqrestore(&net_device->recv_pkt_list_lock, flags);
-
-	/* Send a receive completion for the xfer page packet */
-	if (fsend_receive_comp)
-		netvsc_send_recv_completion(device, transaction_id);
-
-	put_net_device(device);
-}
-
 static void netvsc_channel_cb(void *context)
 {
 	int ret;
@@ -1251,7 +1010,7 @@
 
 	net_device = get_inbound_net_device(device);
 	if (!net_device) {
-		DPRINT_ERR(NETVSC, "net device (%p) shutting down..."
+		dev_err(&device->device, "net device (%p) shutting down..."
 			   "ignoring inbound packets", net_device);
 		goto out;
 	}
@@ -1261,9 +1020,6 @@
 					   &bytes_recvd, &request_id);
 		if (ret == 0) {
 			if (bytes_recvd > 0) {
-				DPRINT_DBG(NETVSC, "receive %d bytes, tid %llx",
-					   bytes_recvd, request_id);
-
 				desc = (struct vmpacket_descriptor *)buffer;
 				switch (desc->type) {
 				case VM_PKT_COMP:
@@ -1275,7 +1031,7 @@
 					break;
 
 				default:
-					DPRINT_ERR(NETVSC,
+					dev_err(&device->device,
 						   "unhandled packet type %d, "
 						   "tid %llx len %d\n",
 						   desc->type, request_id,
@@ -1304,7 +1060,7 @@
 			buffer = kmalloc(bytes_recvd, GFP_ATOMIC);
 			if (buffer == NULL) {
 				/* Try again next time around */
-				DPRINT_ERR(NETVSC,
+				dev_err(&device->device,
 					   "unable to allocate buffer of size "
 					   "(%d)!!", bytes_recvd);
 				break;
@@ -1319,3 +1075,102 @@
 	kfree(buffer);
 	return;
 }
+
+/*
+ * netvsc_device_add - Callback when the device belonging to this
+ * driver is added
+ */
+int netvsc_device_add(struct hv_device *device, void *additional_info)
+{
+	int ret = 0;
+	int i;
+	int ring_size =
+	((struct netvsc_device_info *)additional_info)->ring_size;
+	struct netvsc_device *net_device;
+	struct hv_netvsc_packet *packet, *pos;
+
+	net_device = alloc_net_device(device);
+	if (!net_device) {
+		ret = -1;
+		goto cleanup;
+	}
+
+	/* Initialize the NetVSC channel extension */
+	net_device->recv_buf_size = NETVSC_RECEIVE_BUFFER_SIZE;
+	spin_lock_init(&net_device->recv_pkt_list_lock);
+
+	net_device->send_buf_size = NETVSC_SEND_BUFFER_SIZE;
+
+	INIT_LIST_HEAD(&net_device->recv_pkt_list);
+
+	for (i = 0; i < NETVSC_RECEIVE_PACKETLIST_COUNT; i++) {
+		packet = kzalloc(sizeof(struct hv_netvsc_packet) +
+				 (NETVSC_RECEIVE_SG_COUNT *
+				  sizeof(struct hv_page_buffer)), GFP_KERNEL);
+		if (!packet)
+			break;
+
+		list_add_tail(&packet->list_ent,
+			      &net_device->recv_pkt_list);
+	}
+	init_completion(&net_device->channel_init_wait);
+
+	/* Open the channel */
+	ret = vmbus_open(device->channel, ring_size * PAGE_SIZE,
+			 ring_size * PAGE_SIZE, NULL, 0,
+			 netvsc_channel_cb, device);
+
+	if (ret != 0) {
+		dev_err(&device->device, "unable to open channel: %d", ret);
+		ret = -1;
+		goto cleanup;
+	}
+
+	/* Channel is opened */
+	pr_info("hv_netvsc channel opened successfully");
+
+	/* Connect with the NetVsp */
+	ret = netvsc_connect_vsp(device);
+	if (ret != 0) {
+		dev_err(&device->device,
+			"unable to connect to NetVSP - %d", ret);
+		ret = -1;
+		goto close;
+	}
+
+	return ret;
+
+close:
+	/* Now, we can close the channel safely */
+	vmbus_close(device->channel);
+
+cleanup:
+
+	if (net_device) {
+		list_for_each_entry_safe(packet, pos,
+					 &net_device->recv_pkt_list,
+					 list_ent) {
+			list_del(&packet->list_ent);
+			kfree(packet);
+		}
+
+		release_outbound_net_device(device);
+		release_inbound_net_device(device);
+
+		free_net_device(net_device);
+	}
+
+	return ret;
+}
+
+/*
+ * netvsc_initialize - Main entry point
+ */
+int netvsc_initialize(struct hv_driver *drv)
+{
+
+	drv->name = driver_name;
+	memcpy(&drv->dev_type, &netvsc_device_type, sizeof(struct hv_guid));
+
+	return 0;
+}
diff -druN linux-2.6.39-libre/drivers/staging/hv/netvsc_drv.c linux-3.0-rc7-libre/drivers/staging/hv/netvsc_drv.c
--- linux-2.6.39-libre/drivers/staging/hv/netvsc_drv.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/hv/netvsc_drv.c	2011-07-11 19:51:52.000000000 -0400
@@ -18,6 +18,8 @@
  *   Haiyang Zhang <haiyangz@microsoft.com>
  *   Hank Janssen  <hjanssen@microsoft.com>
  */
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/highmem.h>
@@ -36,11 +38,9 @@
 #include <net/route.h>
 #include <net/sock.h>
 #include <net/pkt_sched.h>
-#include "hv_api.h"
-#include "logging.h"
-#include "version_info.h"
-#include "vmbus.h"
-#include "netvsc_api.h"
+
+#include "hyperv.h"
+#include "hyperv_net.h"
 
 struct net_device_context {
 	/* point back to our device context */
@@ -58,9 +58,6 @@
 module_param(ring_size, int, S_IRUGO);
 MODULE_PARM_DESC(ring_size, "Ring buffer size (# of pages)");
 
-/* The one and only one */
-static struct  netvsc_driver g_netvsc_drv;
-
 /* no-op so the netdev core doesn't return -EINVAL when modifying the the
  * multicast address list in SIOCADDMULTI. hv is setup to get all multicast
  * when it calls RndisFilterOnOpen() */
@@ -78,14 +75,14 @@
 		/* Open up the device */
 		ret = rndis_filter_open(device_obj);
 		if (ret != 0) {
-			DPRINT_ERR(NETVSC_DRV,
-				   "unable to open device (ret %d).", ret);
+			netdev_err(net, "unable to open device (ret %d).\n",
+				   ret);
 			return ret;
 		}
 
 		netif_start_queue(net);
 	} else {
-		DPRINT_ERR(NETVSC_DRV, "unable to open device...link is down.");
+		netdev_err(net, "unable to open device...link is down.\n");
 	}
 
 	return ret;
@@ -101,7 +98,7 @@
 
 	ret = rndis_filter_close(device_obj);
 	if (ret != 0)
-		DPRINT_ERR(NETVSC_DRV, "unable to close device (ret %d).", ret);
+		netdev_err(net, "unable to close device (ret %d).\n", ret);
 
 	return ret;
 }
@@ -130,16 +127,10 @@
 static int netvsc_start_xmit(struct sk_buff *skb, struct net_device *net)
 {
 	struct net_device_context *net_device_ctx = netdev_priv(net);
-	struct hv_driver *drv =
-	    drv_to_hv_drv(net_device_ctx->device_ctx->device.driver);
-	struct netvsc_driver *net_drv_obj = drv->priv;
 	struct hv_netvsc_packet *packet;
 	int ret;
 	unsigned int i, num_pages;
 
-	DPRINT_DBG(NETVSC_DRV, "xmit packet - len %d data_len %d",
-		   skb->len, skb->data_len);
-
 	/* Add 1 for skb->data and additional one for RNDIS */
 	num_pages = skb_shinfo(skb)->nr_frags + 1 + 1;
 	if (num_pages > net_device_ctx->avail)
@@ -148,10 +139,10 @@
 	/* Allocate a netvsc packet based on # of frags. */
 	packet = kzalloc(sizeof(struct hv_netvsc_packet) +
 			 (num_pages * sizeof(struct hv_page_buffer)) +
-			 net_drv_obj->req_ext_size, GFP_ATOMIC);
+			 sizeof(struct rndis_filter_packet), GFP_ATOMIC);
 	if (!packet) {
 		/* out of memory, silently drop packet */
-		DPRINT_ERR(NETVSC_DRV, "unable to allocate hv_netvsc_packet");
+		netdev_err(net, "unable to allocate hv_netvsc_packet\n");
 
 		dev_kfree_skb(skb);
 		net->stats.tx_dropped++;
@@ -191,16 +182,12 @@
 	packet->completion.send.send_completion_ctx = packet;
 	packet->completion.send.send_completion_tid = (unsigned long)skb;
 
-	ret = net_drv_obj->send(net_device_ctx->device_ctx,
+	ret = rndis_filter_send(net_device_ctx->device_ctx,
 				  packet);
 	if (ret == 0) {
 		net->stats.tx_bytes += skb->len;
 		net->stats.tx_packets++;
 
-		DPRINT_DBG(NETVSC_DRV, "# of xmits %lu total size %lu",
-			   net->stats.tx_packets,
-			   net->stats.tx_bytes);
-
 		net_device_ctx->avail -= num_pages;
 		if (net_device_ctx->avail < PACKET_PAGES_LOWATER)
 			netif_stop_queue(net);
@@ -216,15 +203,15 @@
 /*
  * netvsc_linkstatus_callback - Link up/down notification
  */
-static void netvsc_linkstatus_callback(struct hv_device *device_obj,
+void netvsc_linkstatus_callback(struct hv_device *device_obj,
 				       unsigned int status)
 {
 	struct net_device *net = dev_get_drvdata(&device_obj->device);
 	struct net_device_context *ndev_ctx;
 
 	if (!net) {
-		DPRINT_ERR(NETVSC_DRV, "got link status but net device "
-				"not initialized yet");
+		netdev_err(net, "got link status but net device "
+				"not initialized yet\n");
 		return;
 	}
 
@@ -244,7 +231,7 @@
  * netvsc_recv_callback -  Callback when we receive a packet from the
  * "wire" on the specified device.
  */
-static int netvsc_recv_callback(struct hv_device *device_obj,
+int netvsc_recv_callback(struct hv_device *device_obj,
 				struct hv_netvsc_packet *packet)
 {
 	struct net_device *net = dev_get_drvdata(&device_obj->device);
@@ -254,8 +241,8 @@
 	unsigned long flags;
 
 	if (!net) {
-		DPRINT_ERR(NETVSC_DRV, "got receive callback but net device "
-				"not initialized yet");
+		netdev_err(net, "got receive callback but net device"
+			" not initialized yet\n");
 		return 0;
 	}
 
@@ -301,9 +288,6 @@
 	 */
 	netif_rx(skb);
 
-	DPRINT_DBG(NETVSC_DRV, "# of recvs %lu total size %lu",
-		   net->stats.rx_packets, net->stats.rx_bytes);
-
 	return 0;
 }
 
@@ -317,8 +301,6 @@
 
 static const struct ethtool_ops ethtool_ops = {
 	.get_drvinfo	= netvsc_get_drvinfo,
-	.get_sg		= ethtool_op_get_sg,
-	.set_sg		= ethtool_op_set_sg,
 	.get_link	= ethtool_op_get_link,
 };
 
@@ -351,20 +333,13 @@
 }
 
 
-static int netvsc_probe(struct device *device)
+static int netvsc_probe(struct hv_device *dev)
 {
-	struct hv_driver *drv =
-		drv_to_hv_drv(device->driver);
-	struct netvsc_driver *net_drv_obj = drv->priv;
-	struct hv_device *device_obj = device_to_hv_device(device);
 	struct net_device *net = NULL;
 	struct net_device_context *net_device_ctx;
 	struct netvsc_device_info device_info;
 	int ret;
 
-	if (!net_drv_obj->base.dev_add)
-		return -1;
-
 	net = alloc_etherdev(sizeof(struct net_device_context));
 	if (!net)
 		return -1;
@@ -373,19 +348,19 @@
 	netif_carrier_off(net);
 
 	net_device_ctx = netdev_priv(net);
-	net_device_ctx->device_ctx = device_obj;
+	net_device_ctx->device_ctx = dev;
 	net_device_ctx->avail = ring_size;
-	dev_set_drvdata(device, net);
+	dev_set_drvdata(&dev->device, net);
 	INIT_WORK(&net_device_ctx->work, netvsc_send_garp);
 
 	/* Notify the netvsc driver of the new device */
-	ret = net_drv_obj->base.dev_add(device_obj, &device_info);
+	device_info.ring_size = ring_size;
+	ret = rndis_filte_device_add(dev, &device_info);
 	if (ret != 0) {
 		free_netdev(net);
-		dev_set_drvdata(device, NULL);
+		dev_set_drvdata(&dev->device, NULL);
 
-		DPRINT_ERR(NETVSC_DRV, "unable to add netvsc device (ret %d)",
-			   ret);
+		netdev_err(net, "unable to add netvsc device (ret %d)\n", ret);
 		return ret;
 	}
 
@@ -406,38 +381,32 @@
 	net->netdev_ops = &device_ops;
 
 	/* TODO: Add GSO and Checksum offload */
+	net->hw_features = NETIF_F_SG;
 	net->features = NETIF_F_SG;
 
 	SET_ETHTOOL_OPS(net, &ethtool_ops);
-	SET_NETDEV_DEV(net, device);
+	SET_NETDEV_DEV(net, &dev->device);
 
 	ret = register_netdev(net);
 	if (ret != 0) {
 		/* Remove the device and release the resource */
-		net_drv_obj->base.dev_rm(device_obj);
+		rndis_filter_device_remove(dev);
 		free_netdev(net);
 	}
 
 	return ret;
 }
 
-static int netvsc_remove(struct device *device)
+static int netvsc_remove(struct hv_device *dev)
 {
-	struct hv_driver *drv =
-		drv_to_hv_drv(device->driver);
-	struct netvsc_driver *net_drv_obj = drv->priv;
-	struct hv_device *device_obj = device_to_hv_device(device);
-	struct net_device *net = dev_get_drvdata(&device_obj->device);
+	struct net_device *net = dev_get_drvdata(&dev->device);
 	int ret;
 
 	if (net == NULL) {
-		DPRINT_INFO(NETVSC, "no net device to remove");
+		dev_err(&dev->device, "No net device to remove\n");
 		return 0;
 	}
 
-	if (!net_drv_obj->base.dev_rm)
-		return -1;
-
 	/* Stop outbound asap */
 	netif_stop_queue(net);
 	/* netif_carrier_off(net); */
@@ -448,84 +417,27 @@
 	 * Call to the vsc driver to let it know that the device is being
 	 * removed
 	 */
-	ret = net_drv_obj->base.dev_rm(device_obj);
+	ret = rndis_filter_device_remove(dev);
 	if (ret != 0) {
 		/* TODO: */
-		DPRINT_ERR(NETVSC, "unable to remove vsc device (ret %d)", ret);
+		netdev_err(net, "unable to remove vsc device (ret %d)\n", ret);
 	}
 
 	free_netdev(net);
 	return ret;
 }
 
-static int netvsc_drv_exit_cb(struct device *dev, void *data)
-{
-	struct device **curr = (struct device **)data;
-
-	*curr = dev;
-	/* stop iterating */
-	return 1;
-}
+/* The one and only one */
+static struct  hv_driver netvsc_drv = {
+	.probe = netvsc_probe,
+	.remove = netvsc_remove,
+};
 
-static void netvsc_drv_exit(void)
+static void __exit netvsc_drv_exit(void)
 {
-	struct netvsc_driver *netvsc_drv_obj = &g_netvsc_drv;
-	struct hv_driver *drv = &g_netvsc_drv.base;
-	struct device *current_dev;
-	int ret;
-
-	while (1) {
-		current_dev = NULL;
-
-		/* Get the device */
-		ret = driver_for_each_device(&drv->driver, NULL,
-					     &current_dev, netvsc_drv_exit_cb);
-		if (ret)
-			DPRINT_WARN(NETVSC_DRV,
-				    "driver_for_each_device returned %d", ret);
-
-		if (current_dev == NULL)
-			break;
-
-		/* Initiate removal from the top-down */
-		DPRINT_INFO(NETVSC_DRV, "unregistering device (%p)...",
-			    current_dev);
-
-		device_unregister(current_dev);
-	}
-
-	if (netvsc_drv_obj->base.cleanup)
-		netvsc_drv_obj->base.cleanup(&netvsc_drv_obj->base);
-
-	vmbus_child_driver_unregister(&drv->driver);
-
-	return;
+	vmbus_child_driver_unregister(&netvsc_drv.driver);
 }
 
-static int netvsc_drv_init(int (*drv_init)(struct hv_driver *drv))
-{
-	struct netvsc_driver *net_drv_obj = &g_netvsc_drv;
-	struct hv_driver *drv = &g_netvsc_drv.base;
-	int ret;
-
-	net_drv_obj->ring_buf_size = ring_size * PAGE_SIZE;
-	net_drv_obj->recv_cb = netvsc_recv_callback;
-	net_drv_obj->link_status_change = netvsc_linkstatus_callback;
-	drv->priv = net_drv_obj;
-
-	/* Callback to client driver to complete the initialization */
-	drv_init(&net_drv_obj->base);
-
-	drv->driver.name = net_drv_obj->base.name;
-
-	drv->driver.probe = netvsc_probe;
-	drv->driver.remove = netvsc_remove;
-
-	/* The driver belongs to vmbus */
-	ret = vmbus_child_driver_register(&drv->driver);
-
-	return ret;
-}
 
 static const struct dmi_system_id __initconst
 hv_netvsc_dmi_table[] __maybe_unused  = {
@@ -541,19 +453,26 @@
 };
 MODULE_DEVICE_TABLE(dmi, hv_netvsc_dmi_table);
 
-static int __init netvsc_init(void)
+static int __init netvsc_drv_init(void)
 {
-	DPRINT_INFO(NETVSC_DRV, "Netvsc initializing....");
+	struct hv_driver *drv = &netvsc_drv;
+	int ret;
+
+	pr_info("initializing....");
 
 	if (!dmi_check_system(hv_netvsc_dmi_table))
 		return -ENODEV;
 
-	return netvsc_drv_init(netvsc_initialize);
-}
 
-static void __exit netvsc_exit(void)
-{
-	netvsc_drv_exit();
+	/* Callback to client driver to complete the initialization */
+	netvsc_initialize(drv);
+
+	drv->driver.name = drv->name;
+
+	/* The driver belongs to vmbus */
+	ret = vmbus_child_driver_register(&drv->driver);
+
+	return ret;
 }
 
 static const struct pci_device_id __initconst
@@ -567,5 +486,5 @@
 MODULE_VERSION(HV_DRV_VERSION);
 MODULE_DESCRIPTION("Microsoft Hyper-V network driver");
 
-module_init(netvsc_init);
-module_exit(netvsc_exit);
+module_init(netvsc_drv_init);
+module_exit(netvsc_drv_exit);
diff -druN linux-2.6.39-libre/drivers/staging/hv/netvsc.h linux-3.0-rc7-libre/drivers/staging/hv/netvsc.h
--- linux-2.6.39-libre/drivers/staging/hv/netvsc.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/hv/netvsc.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,332 +0,0 @@
-/*
- *
- * Copyright (c) 2009, Microsoft 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., 59 Temple
- * Place - Suite 330, Boston, MA 02111-1307 USA.
- *
- * Authors:
- *   Haiyang Zhang <haiyangz@microsoft.com>
- *   Hank Janssen  <hjanssen@microsoft.com>
- *
- */
-
-
-#ifndef _NETVSC_H_
-#define _NETVSC_H_
-
-#include <linux/list.h>
-#include "vmbus_packet_format.h"
-#include "vmbus_channel_interface.h"
-#include "netvsc_api.h"
-
-
-#define NVSP_INVALID_PROTOCOL_VERSION	((u32)0xFFFFFFFF)
-
-#define NVSP_PROTOCOL_VERSION_1		2
-#define NVSP_MIN_PROTOCOL_VERSION	NVSP_PROTOCOL_VERSION_1
-#define NVSP_MAX_PROTOCOL_VERSION	NVSP_PROTOCOL_VERSION_1
-
-enum {
-	NVSP_MSG_TYPE_NONE = 0,
-
-	/* Init Messages */
-	NVSP_MSG_TYPE_INIT			= 1,
-	NVSP_MSG_TYPE_INIT_COMPLETE		= 2,
-
-	NVSP_VERSION_MSG_START			= 100,
-
-	/* Version 1 Messages */
-	NVSP_MSG1_TYPE_SEND_NDIS_VER		= NVSP_VERSION_MSG_START,
-
-	NVSP_MSG1_TYPE_SEND_RECV_BUF,
-	NVSP_MSG1_TYPE_SEND_RECV_BUF_COMPLETE,
-	NVSP_MSG1_TYPE_REVOKE_RECV_BUF,
-
-	NVSP_MSG1_TYPE_SEND_SEND_BUF,
-	NVSP_MSG1_TYPE_SEND_SEND_BUF_COMPLETE,
-	NVSP_MSG1_TYPE_REVOKE_SEND_BUF,
-
-	NVSP_MSG1_TYPE_SEND_RNDIS_PKT,
-	NVSP_MSG1_TYPE_SEND_RNDIS_PKT_COMPLETE,
-
-	/*
-	 * This should be set to the number of messages for the version with
-	 * the maximum number of messages.
-	 */
-	NVSP_NUM_MSG_PER_VERSION		= 9,
-};
-
-enum {
-	NVSP_STAT_NONE = 0,
-	NVSP_STAT_SUCCESS,
-	NVSP_STAT_FAIL,
-	NVSP_STAT_PROTOCOL_TOO_NEW,
-	NVSP_STAT_PROTOCOL_TOO_OLD,
-	NVSP_STAT_INVALID_RNDIS_PKT,
-	NVSP_STAT_BUSY,
-	NVSP_STAT_MAX,
-};
-
-struct nvsp_message_header {
-	u32 msg_type;
-};
-
-/* Init Messages */
-
-/*
- * This message is used by the VSC to initialize the channel after the channels
- * has been opened. This message should never include anything other then
- * versioning (i.e. this message will be the same for ever).
- */
-struct nvsp_message_init {
-	u32 min_protocol_ver;
-	u32 max_protocol_ver;
-} __packed;
-
-/*
- * This message is used by the VSP to complete the initialization of the
- * channel. This message should never include anything other then versioning
- * (i.e. this message will be the same for ever).
- */
-struct nvsp_message_init_complete {
-	u32 negotiated_protocol_ver;
-	u32 max_mdl_chain_len;
-	u32 status;
-} __packed;
-
-union nvsp_message_init_uber {
-	struct nvsp_message_init init;
-	struct nvsp_message_init_complete init_complete;
-} __packed;
-
-/* Version 1 Messages */
-
-/*
- * This message is used by the VSC to send the NDIS version to the VSP. The VSP
- * can use this information when handling OIDs sent by the VSC.
- */
-struct nvsp_1_message_send_ndis_version {
-	u32 ndis_major_ver;
-	u32 ndis_minor_ver;
-} __packed;
-
-/*
- * This message is used by the VSC to send a receive buffer to the VSP. The VSP
- * can then use the receive buffer to send data to the VSC.
- */
-struct nvsp_1_message_send_receive_buffer {
-	u32 gpadl_handle;
-	u16 id;
-} __packed;
-
-struct nvsp_1_receive_buffer_section {
-	u32 offset;
-	u32 sub_alloc_size;
-	u32 num_sub_allocs;
-	u32 end_offset;
-} __packed;
-
-/*
- * This message is used by the VSP to acknowledge a receive buffer send by the
- * VSC. This message must be sent by the VSP before the VSP uses the receive
- * buffer.
- */
-struct nvsp_1_message_send_receive_buffer_complete {
-	u32 status;
-	u32 num_sections;
-
-	/*
-	 * The receive buffer is split into two parts, a large suballocation
-	 * section and a small suballocation section. These sections are then
-	 * suballocated by a certain size.
-	 */
-
-	/*
-	 * For example, the following break up of the receive buffer has 6
-	 * large suballocations and 10 small suballocations.
-	 */
-
-	/*
-	 * |            Large Section          |  |   Small Section   |
-	 * ------------------------------------------------------------
-	 * |     |     |     |     |     |     |  | | | | | | | | | | |
-	 * |                                      |
-	 *  LargeOffset                            SmallOffset
-	 */
-
-	struct nvsp_1_receive_buffer_section sections[1];
-} __packed;
-
-/*
- * This message is sent by the VSC to revoke the receive buffer.  After the VSP
- * completes this transaction, the vsp should never use the receive buffer
- * again.
- */
-struct nvsp_1_message_revoke_receive_buffer {
-	u16 id;
-};
-
-/*
- * This message is used by the VSC to send a send buffer to the VSP. The VSC
- * can then use the send buffer to send data to the VSP.
- */
-struct nvsp_1_message_send_send_buffer {
-	u32 gpadl_handle;
-	u16 id;
-} __packed;
-
-/*
- * This message is used by the VSP to acknowledge a send buffer sent by the
- * VSC. This message must be sent by the VSP before the VSP uses the sent
- * buffer.
- */
-struct nvsp_1_message_send_send_buffer_complete {
-	u32 status;
-
-	/*
-	 * The VSC gets to choose the size of the send buffer and the VSP gets
-	 * to choose the sections size of the buffer.  This was done to enable
-	 * dynamic reconfigurations when the cost of GPA-direct buffers
-	 * decreases.
-	 */
-	u32 section_size;
-} __packed;
-
-/*
- * This message is sent by the VSC to revoke the send buffer.  After the VSP
- * completes this transaction, the vsp should never use the send buffer again.
- */
-struct nvsp_1_message_revoke_send_buffer {
-	u16 id;
-};
-
-/*
- * This message is used by both the VSP and the VSC to send a RNDIS message to
- * the opposite channel endpoint.
- */
-struct nvsp_1_message_send_rndis_packet {
-	/*
-	 * This field is specified by RNIDS. They assume there's two different
-	 * channels of communication. However, the Network VSP only has one.
-	 * Therefore, the channel travels with the RNDIS packet.
-	 */
-	u32 channel_type;
-
-	/*
-	 * This field is used to send part or all of the data through a send
-	 * buffer. This values specifies an index into the send buffer. If the
-	 * index is 0xFFFFFFFF, then the send buffer is not being used and all
-	 * of the data was sent through other VMBus mechanisms.
-	 */
-	u32 send_buf_section_index;
-	u32 send_buf_section_size;
-} __packed;
-
-/*
- * This message is used by both the VSP and the VSC to complete a RNDIS message
- * to the opposite channel endpoint. At this point, the initiator of this
- * message cannot use any resources associated with the original RNDIS packet.
- */
-struct nvsp_1_message_send_rndis_packet_complete {
-	u32 status;
-};
-
-union nvsp_1_message_uber {
-	struct nvsp_1_message_send_ndis_version send_ndis_ver;
-
-	struct nvsp_1_message_send_receive_buffer send_recv_buf;
-	struct nvsp_1_message_send_receive_buffer_complete
-						send_recv_buf_complete;
-	struct nvsp_1_message_revoke_receive_buffer revoke_recv_buf;
-
-	struct nvsp_1_message_send_send_buffer send_send_buf;
-	struct nvsp_1_message_send_send_buffer_complete send_send_buf_complete;
-	struct nvsp_1_message_revoke_send_buffer revoke_send_buf;
-
-	struct nvsp_1_message_send_rndis_packet send_rndis_pkt;
-	struct nvsp_1_message_send_rndis_packet_complete
-						send_rndis_pkt_complete;
-} __packed;
-
-union nvsp_all_messages {
-	union nvsp_message_init_uber init_msg;
-	union nvsp_1_message_uber v1_msg;
-} __packed;
-
-/* ALL Messages */
-struct nvsp_message {
-	struct nvsp_message_header hdr;
-	union nvsp_all_messages msg;
-} __packed;
-
-
-
-
-/* #define NVSC_MIN_PROTOCOL_VERSION		1 */
-/* #define NVSC_MAX_PROTOCOL_VERSION		1 */
-
-#define NETVSC_SEND_BUFFER_SIZE			(64*1024)	/* 64K */
-#define NETVSC_SEND_BUFFER_ID			0xface
-
-
-#define NETVSC_RECEIVE_BUFFER_SIZE		(1024*1024)	/* 1MB */
-
-#define NETVSC_RECEIVE_BUFFER_ID		0xcafe
-
-#define NETVSC_RECEIVE_SG_COUNT			1
-
-/* Preallocated receive packets */
-#define NETVSC_RECEIVE_PACKETLIST_COUNT		256
-
-#define NETVSC_PACKET_SIZE                      2048
-
-/* Per netvsc channel-specific */
-struct netvsc_device {
-	struct hv_device *dev;
-
-	atomic_t refcnt;
-	atomic_t num_outstanding_sends;
-	/*
-	 * List of free preallocated hv_netvsc_packet to represent receive
-	 * packet
-	 */
-	struct list_head recv_pkt_list;
-	spinlock_t recv_pkt_list_lock;
-
-	/* Send buffer allocated by us but manages by NetVSP */
-	void *send_buf;
-	u32 send_buf_size;
-	u32 send_buf_gpadl_handle;
-	u32 send_section_size;
-
-	/* Receive buffer allocated by us but manages by NetVSP */
-	void *recv_buf;
-	u32 recv_buf_size;
-	u32 recv_buf_gpadl_handle;
-	u32 recv_section_cnt;
-	struct nvsp_1_receive_buffer_section *recv_section;
-
-	/* Used for NetVSP initialization protocol */
-	int wait_condition;
-	wait_queue_head_t channel_init_wait;
-	struct nvsp_message channel_init_pkt;
-
-	struct nvsp_message revoke_packet;
-	/* unsigned char HwMacAddr[HW_MACADDR_LEN]; */
-
-	/* Holds rndis device info */
-	void *extension;
-};
-
-#endif /* _NETVSC_H_ */
diff -druN linux-2.6.39-libre/drivers/staging/hv/ring_buffer.c linux-3.0-rc7-libre/drivers/staging/hv/ring_buffer.c
--- linux-2.6.39-libre/drivers/staging/hv/ring_buffer.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/hv/ring_buffer.c	2011-07-11 19:51:52.000000000 -0400
@@ -18,13 +18,16 @@
  * Authors:
  *   Haiyang Zhang <haiyangz@microsoft.com>
  *   Hank Janssen  <hjanssen@microsoft.com>
+ *   K. Y. Srinivasan <kys@microsoft.com>
  *
  */
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 
 #include <linux/kernel.h>
 #include <linux/mm.h>
-#include "logging.h"
-#include "ring_buffer.h"
+
+#include "hyperv.h"
+#include "hyperv_vmbus.h"
 
 
 /* #defines */
@@ -34,18 +37,15 @@
 #define BYTES_AVAIL_TO_WRITE(r, w, z) ((w) >= (r)) ? ((z) - ((w) - (r))) : ((r) - (w))
 
 
-/*++
-
-Name:
-	get_ringbuffer_availbytes()
-
-Description:
-	Get number of bytes available to read and to write to
-	for the specified ring buffer
-
---*/
+/*
+ *
+ * hv_get_ringbuffer_availbytes()
+ *
+ * Get number of bytes available to read and to write to
+ * for the specified ring buffer
+ */
 static inline void
-get_ringbuffer_availbytes(struct hv_ring_buffer_info *rbi,
+hv_get_ringbuffer_availbytes(struct hv_ring_buffer_info *rbi,
 			  u32 *read, u32 *write)
 {
 	u32 read_loc, write_loc;
@@ -58,162 +58,131 @@
 	*read = rbi->ring_datasize - *write;
 }
 
-/*++
-
-Name:
-	get_next_write_location()
-
-Description:
-	Get the next write location for the specified ring buffer
-
---*/
+/*
+ * hv_get_next_write_location()
+ *
+ * Get the next write location for the specified ring buffer
+ *
+ */
 static inline u32
-get_next_write_location(struct hv_ring_buffer_info *ring_info)
+hv_get_next_write_location(struct hv_ring_buffer_info *ring_info)
 {
 	u32 next = ring_info->ring_buffer->write_index;
 
-	/* ASSERT(next < ring_info->RingDataSize); */
-
 	return next;
 }
 
-/*++
-
-Name:
-	set_next_write_location()
-
-Description:
-	Set the next write location for the specified ring buffer
-
---*/
+/*
+ * hv_set_next_write_location()
+ *
+ * Set the next write location for the specified ring buffer
+ *
+ */
 static inline void
-set_next_write_location(struct hv_ring_buffer_info *ring_info,
+hv_set_next_write_location(struct hv_ring_buffer_info *ring_info,
 		     u32 next_write_location)
 {
 	ring_info->ring_buffer->write_index = next_write_location;
 }
 
-/*++
-
-Name:
-	get_next_read_location()
-
-Description:
-	Get the next read location for the specified ring buffer
-
---*/
+/*
+ * hv_get_next_read_location()
+ *
+ * Get the next read location for the specified ring buffer
+ */
 static inline u32
-get_next_read_location(struct hv_ring_buffer_info *ring_info)
+hv_get_next_read_location(struct hv_ring_buffer_info *ring_info)
 {
 	u32 next = ring_info->ring_buffer->read_index;
 
-	/* ASSERT(next < ring_info->RingDataSize); */
-
 	return next;
 }
 
-/*++
-
-Name:
-	get_next_readlocation_withoffset()
-
-Description:
-	Get the next read location + offset for the specified ring buffer.
-	This allows the caller to skip
-
---*/
+/*
+ * hv_get_next_readlocation_withoffset()
+ *
+ * Get the next read location + offset for the specified ring buffer.
+ * This allows the caller to skip
+ */
 static inline u32
-get_next_readlocation_withoffset(struct hv_ring_buffer_info *ring_info,
+hv_get_next_readlocation_withoffset(struct hv_ring_buffer_info *ring_info,
 				 u32 offset)
 {
 	u32 next = ring_info->ring_buffer->read_index;
 
-	/* ASSERT(next < ring_info->RingDataSize); */
 	next += offset;
 	next %= ring_info->ring_datasize;
 
 	return next;
 }
 
-/*++
-
-Name:
-	set_next_read_location()
-
-Description:
-	Set the next read location for the specified ring buffer
-
---*/
+/*
+ *
+ * hv_set_next_read_location()
+ *
+ * Set the next read location for the specified ring buffer
+ *
+ */
 static inline void
-set_next_read_location(struct hv_ring_buffer_info *ring_info,
+hv_set_next_read_location(struct hv_ring_buffer_info *ring_info,
 		    u32 next_read_location)
 {
 	ring_info->ring_buffer->read_index = next_read_location;
 }
 
 
-/*++
-
-Name:
-	get_ring_buffer()
-
-Description:
-	Get the start of the ring buffer
-
---*/
+/*
+ *
+ * hv_get_ring_buffer()
+ *
+ * Get the start of the ring buffer
+ */
 static inline void *
-get_ring_buffer(struct hv_ring_buffer_info *ring_info)
+hv_get_ring_buffer(struct hv_ring_buffer_info *ring_info)
 {
 	return (void *)ring_info->ring_buffer->buffer;
 }
 
 
-/*++
-
-Name:
-	get_ring_buffersize()
-
-Description:
-	Get the size of the ring buffer
-
---*/
+/*
+ *
+ * hv_get_ring_buffersize()
+ *
+ * Get the size of the ring buffer
+ */
 static inline u32
-get_ring_buffersize(struct hv_ring_buffer_info *ring_info)
+hv_get_ring_buffersize(struct hv_ring_buffer_info *ring_info)
 {
 	return ring_info->ring_datasize;
 }
 
-/*++
-
-Name:
-	get_ring_bufferindices()
-
-Description:
-	Get the read and write indices as u64 of the specified ring buffer
-
---*/
+/*
+ *
+ * hv_get_ring_bufferindices()
+ *
+ * Get the read and write indices as u64 of the specified ring buffer
+ *
+ */
 static inline u64
-get_ring_bufferindices(struct hv_ring_buffer_info *ring_info)
+hv_get_ring_bufferindices(struct hv_ring_buffer_info *ring_info)
 {
 	return (u64)ring_info->ring_buffer->write_index << 32;
 }
 
 
-/*++
-
-Name:
-	dump_ring_info()
-
-Description:
-	Dump out to console the ring buffer info
-
---*/
-void dump_ring_info(struct hv_ring_buffer_info *ring_info, char *prefix)
+/*
+ *
+ * hv_dump_ring_info()
+ *
+ * Dump out to console the ring buffer info
+ *
+ */
+void hv_dump_ring_info(struct hv_ring_buffer_info *ring_info, char *prefix)
 {
 	u32 bytes_avail_towrite;
 	u32 bytes_avail_toread;
 
-	get_ringbuffer_availbytes(ring_info,
+	hv_get_ringbuffer_availbytes(ring_info,
 	&bytes_avail_toread,
 	&bytes_avail_towrite);
 
@@ -231,41 +200,90 @@
 }
 
 
-/* Internal routines */
-
-static u32
-copyto_ringbuffer(
-	struct hv_ring_buffer_info	*ring_info,
-	u32				start_write_offset,
-	void				*src,
-	u32				srclen);
-
-static u32
-copyfrom_ringbuffer(
+/*
+ *
+ * hv_copyfrom_ringbuffer()
+ *
+ * Helper routine to copy to source from ring buffer.
+ * Assume there is enough room. Handles wrap-around in src case only!!
+ *
+ */
+static u32 hv_copyfrom_ringbuffer(
 	struct hv_ring_buffer_info	*ring_info,
 	void				*dest,
 	u32				destlen,
-	u32				start_read_offset);
+	u32				start_read_offset)
+{
+	void *ring_buffer = hv_get_ring_buffer(ring_info);
+	u32 ring_buffer_size = hv_get_ring_buffersize(ring_info);
 
+	u32 frag_len;
 
+	/* wrap-around detected at the src */
+	if (destlen > ring_buffer_size - start_read_offset) {
+		frag_len = ring_buffer_size - start_read_offset;
 
-/*++
+		memcpy(dest, ring_buffer + start_read_offset, frag_len);
+		memcpy(dest + frag_len, ring_buffer, destlen - frag_len);
+	} else
 
-Name:
-	ringbuffer_get_debuginfo()
+		memcpy(dest, ring_buffer + start_read_offset, destlen);
 
-Description:
-	Get various debug metrics for the specified ring buffer
 
---*/
-void ringbuffer_get_debuginfo(struct hv_ring_buffer_info *ring_info,
+	start_read_offset += destlen;
+	start_read_offset %= ring_buffer_size;
+
+	return start_read_offset;
+}
+
+
+/*
+ *
+ * hv_copyto_ringbuffer()
+ *
+ * Helper routine to copy from source to ring buffer.
+ * Assume there is enough room. Handles wrap-around in dest case only!!
+ *
+ */
+static u32 hv_copyto_ringbuffer(
+	struct hv_ring_buffer_info	*ring_info,
+	u32				start_write_offset,
+	void				*src,
+	u32				srclen)
+{
+	void *ring_buffer = hv_get_ring_buffer(ring_info);
+	u32 ring_buffer_size = hv_get_ring_buffersize(ring_info);
+	u32 frag_len;
+
+	/* wrap-around detected! */
+	if (srclen > ring_buffer_size - start_write_offset) {
+		frag_len = ring_buffer_size - start_write_offset;
+		memcpy(ring_buffer + start_write_offset, src, frag_len);
+		memcpy(ring_buffer, src + frag_len, srclen - frag_len);
+	} else
+		memcpy(ring_buffer + start_write_offset, src, srclen);
+
+	start_write_offset += srclen;
+	start_write_offset %= ring_buffer_size;
+
+	return start_write_offset;
+}
+
+/*
+ *
+ * hv_ringbuffer_get_debuginfo()
+ *
+ * Get various debug metrics for the specified ring buffer
+ *
+ */
+void hv_ringbuffer_get_debuginfo(struct hv_ring_buffer_info *ring_info,
 			    struct hv_ring_buffer_debug_info *debug_info)
 {
 	u32 bytes_avail_towrite;
 	u32 bytes_avail_toread;
 
 	if (ring_info->ring_buffer) {
-		get_ringbuffer_availbytes(ring_info,
+		hv_get_ringbuffer_availbytes(ring_info,
 					&bytes_avail_toread,
 					&bytes_avail_towrite);
 
@@ -281,30 +299,26 @@
 }
 
 
-/*++
-
-Name:
-	get_ringbuffer_interrupt_mask()
-
-Description:
-	Get the interrupt mask for the specified ring buffer
-
---*/
-u32 get_ringbuffer_interrupt_mask(struct hv_ring_buffer_info *rbi)
+/*
+ *
+ * hv_get_ringbuffer_interrupt_mask()
+ *
+ * Get the interrupt mask for the specified ring buffer
+ *
+ */
+u32 hv_get_ringbuffer_interrupt_mask(struct hv_ring_buffer_info *rbi)
 {
 	return rbi->ring_buffer->interrupt_mask;
 }
 
-/*++
-
-Name:
-	ringbuffer_init()
-
-Description:
-	Initialize the ring buffer
-
---*/
-int ringbuffer_init(struct hv_ring_buffer_info *ring_info,
+/*
+ *
+ * hv_ringbuffer_init()
+ *
+ *Initialize the ring buffer
+ *
+ */
+int hv_ringbuffer_init(struct hv_ring_buffer_info *ring_info,
 		   void *buffer, u32 buflen)
 {
 	if (sizeof(struct hv_ring_buffer) != PAGE_SIZE)
@@ -324,29 +338,25 @@
 	return 0;
 }
 
-/*++
-
-Name:
-	ringbuffer_cleanup()
-
-Description:
-	Cleanup the ring buffer
-
---*/
-void ringbuffer_cleanup(struct hv_ring_buffer_info *ring_info)
+/*
+ *
+ * hv_ringbuffer_cleanup()
+ *
+ * Cleanup the ring buffer
+ *
+ */
+void hv_ringbuffer_cleanup(struct hv_ring_buffer_info *ring_info)
 {
 }
 
-/*++
-
-Name:
-	ringbuffer_write()
-
-Description:
-	Write to the ring buffer
-
---*/
-int ringbuffer_write(struct hv_ring_buffer_info *outring_info,
+/*
+ *
+ * hv_ringbuffer_write()
+ *
+ * Write to the ring buffer
+ *
+ */
+int hv_ringbuffer_write(struct hv_ring_buffer_info *outring_info,
 		    struct scatterlist *sglist, u32 sgcount)
 {
 	int i = 0;
@@ -355,7 +365,7 @@
 	u32 totalbytes_towrite = 0;
 
 	struct scatterlist *sg;
-	volatile u32 next_write_location;
+	u32 next_write_location;
 	u64 prev_indices = 0;
 	unsigned long flags;
 
@@ -368,43 +378,34 @@
 
 	spin_lock_irqsave(&outring_info->ring_lock, flags);
 
-	get_ringbuffer_availbytes(outring_info,
+	hv_get_ringbuffer_availbytes(outring_info,
 				&bytes_avail_toread,
 				&bytes_avail_towrite);
 
-	DPRINT_DBG(VMBUS, "Writing %u bytes...", totalbytes_towrite);
-
-	/* Dumpring_info(Outring_info, "BEFORE "); */
 
 	/* 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 (bytes_avail_towrite <= totalbytes_towrite) {
-		DPRINT_DBG(VMBUS,
-			"No more space left on outbound ring buffer "
-			"(needed %u, avail %u)",
-			totalbytes_towrite,
-			bytes_avail_towrite);
-
 		spin_unlock_irqrestore(&outring_info->ring_lock, flags);
 		return -1;
 	}
 
 	/* Write to the ring buffer */
-	next_write_location = get_next_write_location(outring_info);
+	next_write_location = hv_get_next_write_location(outring_info);
 
 	for_each_sg(sglist, sg, sgcount, i)
 	{
-		next_write_location = copyto_ringbuffer(outring_info,
+		next_write_location = hv_copyto_ringbuffer(outring_info,
 						     next_write_location,
 						     sg_virt(sg),
 						     sg->length);
 	}
 
 	/* Set previous packet start */
-	prev_indices = get_ring_bufferindices(outring_info);
+	prev_indices = hv_get_ring_bufferindices(outring_info);
 
-	next_write_location = copyto_ringbuffer(outring_info,
+	next_write_location = hv_copyto_ringbuffer(outring_info,
 					     next_write_location,
 					     &prev_indices,
 					     sizeof(u64));
@@ -413,25 +414,22 @@
 	mb();
 
 	/* Now, update the write location */
-	set_next_write_location(outring_info, next_write_location);
+	hv_set_next_write_location(outring_info, next_write_location);
 
-	/* Dumpring_info(Outring_info, "AFTER "); */
 
 	spin_unlock_irqrestore(&outring_info->ring_lock, flags);
 	return 0;
 }
 
 
-/*++
-
-Name:
-	ringbuffer_peek()
-
-Description:
-	Read without advancing the read index
-
---*/
-int ringbuffer_peek(struct hv_ring_buffer_info *Inring_info,
+/*
+ *
+ * hv_ringbuffer_peek()
+ *
+ * Read without advancing the read index
+ *
+ */
+int hv_ringbuffer_peek(struct hv_ring_buffer_info *Inring_info,
 		   void *Buffer, u32 buflen)
 {
 	u32 bytes_avail_towrite;
@@ -441,17 +439,12 @@
 
 	spin_lock_irqsave(&Inring_info->ring_lock, flags);
 
-	get_ringbuffer_availbytes(Inring_info,
+	hv_get_ringbuffer_availbytes(Inring_info,
 				&bytes_avail_toread,
 				&bytes_avail_towrite);
 
 	/* Make sure there is something to read */
 	if (bytes_avail_toread < buflen) {
-		/* DPRINT_DBG(VMBUS,
-			"got callback but not enough to read "
-			"<avail to read %d read size %d>!!",
-			bytes_avail_toread,
-			BufferLen); */
 
 		spin_unlock_irqrestore(&Inring_info->ring_lock, flags);
 
@@ -459,9 +452,9 @@
 	}
 
 	/* Convert to byte offset */
-	next_read_location = get_next_read_location(Inring_info);
+	next_read_location = hv_get_next_read_location(Inring_info);
 
-	next_read_location = copyfrom_ringbuffer(Inring_info,
+	next_read_location = hv_copyfrom_ringbuffer(Inring_info,
 						Buffer,
 						buflen,
 						next_read_location);
@@ -472,16 +465,14 @@
 }
 
 
-/*++
-
-Name:
-	ringbuffer_read()
-
-Description:
-	Read and advance the read index
-
---*/
-int ringbuffer_read(struct hv_ring_buffer_info *inring_info, void *buffer,
+/*
+ *
+ * hv_ringbuffer_read()
+ *
+ * Read and advance the read index
+ *
+ */
+int hv_ringbuffer_read(struct hv_ring_buffer_info *inring_info, void *buffer,
 		   u32 buflen, u32 offset)
 {
 	u32 bytes_avail_towrite;
@@ -495,36 +486,26 @@
 
 	spin_lock_irqsave(&inring_info->ring_lock, flags);
 
-	get_ringbuffer_availbytes(inring_info,
+	hv_get_ringbuffer_availbytes(inring_info,
 				&bytes_avail_toread,
 				&bytes_avail_towrite);
 
-	DPRINT_DBG(VMBUS, "Reading %u bytes...", buflen);
-
-	/* Dumpring_info(Inring_info, "BEFORE "); */
-
 	/* Make sure there is something to read */
 	if (bytes_avail_toread < buflen) {
-		DPRINT_DBG(VMBUS,
-			"got callback but not enough to read "
-			"<avail to read %d read size %d>!!",
-			bytes_avail_toread,
-			buflen);
-
 		spin_unlock_irqrestore(&inring_info->ring_lock, flags);
 
 		return -1;
 	}
 
 	next_read_location =
-		get_next_readlocation_withoffset(inring_info, offset);
+		hv_get_next_readlocation_withoffset(inring_info, offset);
 
-	next_read_location = copyfrom_ringbuffer(inring_info,
+	next_read_location = hv_copyfrom_ringbuffer(inring_info,
 						buffer,
 						buflen,
 						next_read_location);
 
-	next_read_location = copyfrom_ringbuffer(inring_info,
+	next_read_location = hv_copyfrom_ringbuffer(inring_info,
 						&prev_indices,
 						sizeof(u64),
 						next_read_location);
@@ -535,94 +516,9 @@
 	mb();
 
 	/* Update the read index */
-	set_next_read_location(inring_info, next_read_location);
-
-	/* Dumpring_info(Inring_info, "AFTER "); */
+	hv_set_next_read_location(inring_info, next_read_location);
 
 	spin_unlock_irqrestore(&inring_info->ring_lock, flags);
 
 	return 0;
 }
-
-
-/*++
-
-Name:
-	copyto_ringbuffer()
-
-Description:
-	Helper routine to copy from source to ring buffer.
-	Assume there is enough room. Handles wrap-around in dest case only!!
-
---*/
-static u32
-copyto_ringbuffer(
-	struct hv_ring_buffer_info	*ring_info,
-	u32				start_write_offset,
-	void				*src,
-	u32				srclen)
-{
-	void *ring_buffer = get_ring_buffer(ring_info);
-	u32 ring_buffer_size = get_ring_buffersize(ring_info);
-	u32 frag_len;
-
-	/* wrap-around detected! */
-	if (srclen > ring_buffer_size - start_write_offset) {
-		DPRINT_DBG(VMBUS, "wrap-around detected!");
-
-		frag_len = ring_buffer_size - start_write_offset;
-		memcpy(ring_buffer + start_write_offset, src, frag_len);
-		memcpy(ring_buffer, src + frag_len, srclen - frag_len);
-	} else
-		memcpy(ring_buffer + start_write_offset, src, srclen);
-
-	start_write_offset += srclen;
-	start_write_offset %= ring_buffer_size;
-
-	return start_write_offset;
-}
-
-
-/*++
-
-Name:
-	copyfrom_ringbuffer()
-
-Description:
-	Helper routine to copy to source from ring buffer.
-	Assume there is enough room. Handles wrap-around in src case only!!
-
---*/
-static u32
-copyfrom_ringbuffer(
-	struct hv_ring_buffer_info	*ring_info,
-	void				*dest,
-	u32				destlen,
-	u32				start_read_offset)
-{
-	void *ring_buffer = get_ring_buffer(ring_info);
-	u32 ring_buffer_size = get_ring_buffersize(ring_info);
-
-	u32 frag_len;
-
-	/* wrap-around detected at the src */
-	if (destlen > ring_buffer_size - start_read_offset) {
-		DPRINT_DBG(VMBUS, "src wrap-around detected!");
-
-		frag_len = ring_buffer_size - start_read_offset;
-
-		memcpy(dest, ring_buffer + start_read_offset, frag_len);
-		memcpy(dest + frag_len, ring_buffer, destlen - frag_len);
-	} else
-
-		memcpy(dest, ring_buffer + start_read_offset, destlen);
-
-
-	start_read_offset += destlen;
-	start_read_offset %= ring_buffer_size;
-
-	return start_read_offset;
-}
-
-
-/* eof */
diff -druN linux-2.6.39-libre/drivers/staging/hv/ring_buffer.h linux-3.0-rc7-libre/drivers/staging/hv/ring_buffer.h
--- linux-2.6.39-libre/drivers/staging/hv/ring_buffer.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/hv/ring_buffer.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,102 +0,0 @@
-/*
- *
- * Copyright (c) 2009, Microsoft 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., 59 Temple
- * Place - Suite 330, Boston, MA 02111-1307 USA.
- *
- * Authors:
- *   Haiyang Zhang <haiyangz@microsoft.com>
- *   Hank Janssen  <hjanssen@microsoft.com>
- *
- */
-
-
-#ifndef _RING_BUFFER_H_
-#define _RING_BUFFER_H_
-
-#include <linux/scatterlist.h>
-
-struct hv_ring_buffer {
-	/* Offset in bytes from the start of ring data below */
-	volatile u32 write_index;
-
-	/* Offset in bytes from the start of ring data below */
-	volatile u32 read_index;
-
-	volatile u32 interrupt_mask;
-
-	/* Pad it to PAGE_SIZE so that data starts on page boundary */
-	u8	reserved[4084];
-
-	/* NOTE:
-	 * The interrupt_mask field is used only for channels but since our
-	 * vmbus connection also uses this data structure and its data starts
-	 * here, we commented out this field.
-	 */
-	/* volatile u32 InterruptMask; */
-
-	/*
-	 * Ring data starts here + RingDataStartOffset
-	 * !!! DO NOT place any fields below this !!!
-	 */
-	u8 buffer[0];
-} __packed;
-
-struct hv_ring_buffer_info {
-	struct hv_ring_buffer *ring_buffer;
-	u32 ring_size;			/* Include the shared header */
-	spinlock_t ring_lock;
-
-	u32 ring_datasize;		/* < ring_size */
-	u32 ring_data_startoffset;
-};
-
-struct hv_ring_buffer_debug_info {
-	u32 current_interrupt_mask;
-	u32 current_read_index;
-	u32 current_write_index;
-	u32 bytes_avail_toread;
-	u32 bytes_avail_towrite;
-};
-
-
-
-/* Interface */
-
-
-int ringbuffer_init(struct hv_ring_buffer_info *ring_info, void *buffer,
-		   u32 buflen);
-
-void ringbuffer_cleanup(struct hv_ring_buffer_info *ring_info);
-
-int ringbuffer_write(struct hv_ring_buffer_info *ring_info,
-		    struct scatterlist *sglist,
-		    u32 sgcount);
-
-int ringbuffer_peek(struct hv_ring_buffer_info *ring_info, void *buffer,
-		   u32 buflen);
-
-int ringbuffer_read(struct hv_ring_buffer_info *ring_info,
-		   void *buffer,
-		   u32 buflen,
-		   u32 offset);
-
-u32 get_ringbuffer_interrupt_mask(struct hv_ring_buffer_info *ring_info);
-
-void dump_ring_info(struct hv_ring_buffer_info *ring_info, char *prefix);
-
-void ringbuffer_get_debuginfo(struct hv_ring_buffer_info *ring_info,
-			    struct hv_ring_buffer_debug_info *debug_info);
-
-#endif /* _RING_BUFFER_H_ */
diff -druN linux-2.6.39-libre/drivers/staging/hv/rndis_filter.c linux-3.0-rc7-libre/drivers/staging/hv/rndis_filter.c
--- linux-2.6.39-libre/drivers/staging/hv/rndis_filter.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/hv/rndis_filter.c	2011-07-11 19:51:52.000000000 -0400
@@ -25,17 +25,11 @@
 #include <linux/slab.h>
 #include <linux/io.h>
 #include <linux/if_ether.h>
+#include <linux/netdevice.h>
 
-#include "logging.h"
-#include "hv_api.h"
-#include "netvsc_api.h"
-#include "rndis_filter.h"
+#include "hyperv.h"
+#include "hyperv_net.h"
 
-/* Data types */
-struct rndis_filter_driver_object {
-	/* The original driver */
-	struct netvsc_driver inner_drv;
-};
 
 enum rndis_device_state {
 	RNDIS_DEV_UNINITIALIZED = 0,
@@ -59,8 +53,7 @@
 
 struct rndis_request {
 	struct list_head list_ent;
-	int wait_condition;
-	wait_queue_head_t wait_event;
+	struct completion  wait_event;
 
 	/*
 	 * FIXME: We assumed a fixed size response here. If we do ever need to
@@ -76,31 +69,11 @@
 	struct rndis_message request_msg;
 };
 
-
-struct rndis_filter_packet {
-	void *completion_ctx;
-	void (*completion)(void *context);
-	struct rndis_message msg;
-};
-
-
-static int rndis_filte_device_add(struct hv_device *dev,
-				  void *additional_info);
-
-static int rndis_filter_device_remove(struct hv_device *dev);
-
-static void rndis_filter_cleanup(struct hv_driver *drv);
-
-static int rndis_filter_send(struct hv_device *dev,
-			     struct hv_netvsc_packet *pkt);
-
 static void rndis_filter_send_completion(void *ctx);
 
 static void rndis_filter_send_request_completion(void *ctx);
 
 
-/* The one and only */
-static struct rndis_filter_driver_object rndis_filter;
 
 static struct rndis_device *get_rndis_device(void)
 {
@@ -132,7 +105,7 @@
 	if (!request)
 		return NULL;
 
-	init_waitqueue_head(&request->wait_event);
+	init_completion(&request->wait_event);
 
 	rndis_msg = &request->request_msg;
 	rndis_msg->ndis_msg_type = msg_type;
@@ -264,7 +237,7 @@
 		rndis_filter_send_request_completion;
 	packet->completion.send.send_completion_tid = (unsigned long)dev;
 
-	ret = rndis_filter.inner_drv.send(dev->net_dev->dev, packet);
+	ret = netvsc_send(dev->net_dev->dev, packet);
 	return ret;
 }
 
@@ -283,14 +256,6 @@
 		 */
 		if (request->request_msg.msg.init_req.req_id
 		    == resp->msg.init_complete.req_id) {
-			DPRINT_DBG(NETVSC, "found rndis request for "
-				"this response (id 0x%x req type 0x%x res "
-				"type 0x%x)",
-				request->request_msg.msg.
-				   init_req.req_id,
-				request->request_msg.ndis_msg_type,
-				resp->ndis_msg_type);
-
 			found = true;
 			break;
 		}
@@ -302,10 +267,11 @@
 			memcpy(&request->response_msg, resp,
 			       resp->msg_len);
 		} else {
-			DPRINT_ERR(NETVSC, "rndis response buffer overflow "
-				  "detected (size %u max %zu)",
-				  resp->msg_len,
-				  sizeof(struct rndis_filter_packet));
+			dev_err(&dev->net_dev->dev->device,
+				"rndis response buffer overflow "
+				"detected (size %u max %zu)\n",
+				resp->msg_len,
+				sizeof(struct rndis_filter_packet));
 
 			if (resp->ndis_msg_type ==
 			    REMOTE_NDIS_RESET_CMPLT) {
@@ -319,13 +285,13 @@
 			}
 		}
 
-		request->wait_condition = 1;
-		wake_up(&request->wait_event);
+		complete(&request->wait_event);
 	} else {
-		DPRINT_ERR(NETVSC, "no rndis request found for this response "
-			   "(id 0x%x res type 0x%x)",
-			   resp->msg.init_complete.req_id,
-			   resp->ndis_msg_type);
+		dev_err(&dev->net_dev->dev->device,
+			"no rndis request found for this response "
+			"(id 0x%x res type 0x%x)\n",
+			resp->msg.init_complete.req_id,
+			resp->ndis_msg_type);
 	}
 }
 
@@ -336,10 +302,10 @@
 			&resp->msg.indicate_status;
 
 	if (indicate->status == RNDIS_STATUS_MEDIA_CONNECT) {
-		rndis_filter.inner_drv.link_status_change(
+		netvsc_linkstatus_callback(
 			dev->net_dev->dev, 1);
 	} else if (indicate->status == RNDIS_STATUS_MEDIA_DISCONNECT) {
-		rndis_filter.inner_drv.link_status_change(
+		netvsc_linkstatus_callback(
 			dev->net_dev->dev, 0);
 	} else {
 		/*
@@ -371,11 +337,10 @@
 
 	pkt->is_data_pkt = true;
 
-	rndis_filter.inner_drv.recv_cb(dev->net_dev->dev,
-						   pkt);
+	netvsc_recv_callback(dev->net_dev->dev, pkt);
 }
 
-static int rndis_filter_receive(struct hv_device *dev,
+int rndis_filter_receive(struct hv_device *dev,
 				struct hv_netvsc_packet	*pkt)
 {
 	struct netvsc_device *net_dev = dev->ext;
@@ -388,15 +353,15 @@
 
 	/* Make sure the rndis device state is initialized */
 	if (!net_dev->extension) {
-		DPRINT_ERR(NETVSC, "got rndis message but no rndis device..."
-			  "dropping this message!");
+		dev_err(&dev->device, "got rndis message but no rndis device - "
+			  "dropping this message!\n");
 		return -1;
 	}
 
 	rndis_dev = (struct rndis_device *)net_dev->extension;
 	if (rndis_dev->state == RNDIS_DEV_UNINITIALIZED) {
-		DPRINT_ERR(NETVSC, "got rndis message but rndis device "
-			   "uninitialized...dropping this message!");
+		dev_err(&dev->device, "got rndis message but rndis device "
+			   "uninitialized...dropping this message!\n");
 		return -1;
 	}
 
@@ -417,8 +382,8 @@
 		kunmap_atomic(rndis_hdr - pkt->page_buf[0].offset,
 			      KM_IRQ0);
 
-		DPRINT_ERR(NETVSC, "invalid rndis message? (expected %u "
-			   "bytes got %u)...dropping this message!",
+		dev_err(&dev->device, "invalid rndis message? (expected %u "
+			   "bytes got %u)...dropping this message!\n",
 			   rndis_hdr->msg_len,
 			   pkt->total_data_buflen);
 		return -1;
@@ -427,8 +392,8 @@
 
 	if ((rndis_hdr->ndis_msg_type != REMOTE_NDIS_PACKET_MSG) &&
 	    (rndis_hdr->msg_len > sizeof(struct rndis_message))) {
-		DPRINT_ERR(NETVSC, "incoming rndis message buffer overflow "
-			   "detected (got %u, max %zu)...marking it an error!",
+		dev_err(&dev->device, "incoming rndis message buffer overflow "
+			   "detected (got %u, max %zu)..marking it an error!\n",
 			   rndis_hdr->msg_len,
 			   sizeof(struct rndis_message));
 	}
@@ -460,7 +425,8 @@
 		rndis_filter_receive_indicate_status(rndis_dev, &rndis_msg);
 		break;
 	default:
-		DPRINT_ERR(NETVSC, "unhandled rndis message (type %u len %u)",
+		dev_err(&dev->device,
+			"unhandled rndis message (type %u len %u)\n",
 			   rndis_msg.ndis_msg_type,
 			   rndis_msg.msg_len);
 		break;
@@ -477,6 +443,7 @@
 	struct rndis_query_request *query;
 	struct rndis_query_complete *query_complete;
 	int ret = 0;
+	int t;
 
 	if (!result)
 		return -EINVAL;
@@ -496,14 +463,12 @@
 	query->info_buflen = 0;
 	query->dev_vc_handle = 0;
 
-	request->wait_condition = 0;
 	ret = rndis_filter_send_request(dev, request);
 	if (ret != 0)
 		goto Cleanup;
 
-	wait_event_timeout(request->wait_event, request->wait_condition,
-				msecs_to_jiffies(1000));
-	if (request->wait_condition == 0) {
+	t = wait_for_completion_timeout(&request->wait_event, HZ);
+	if (t == 0) {
 		ret = -ETIMEDOUT;
 		goto Cleanup;
 	}
@@ -555,7 +520,7 @@
 	struct rndis_set_request *set;
 	struct rndis_set_complete *set_complete;
 	u32 status;
-	int ret;
+	int ret, t;
 
 	request = get_rndis_request(dev, REMOTE_NDIS_SET_MSG,
 			RNDIS_MESSAGE_SIZE(struct rndis_set_request) +
@@ -574,16 +539,16 @@
 	memcpy((void *)(unsigned long)set + sizeof(struct rndis_set_request),
 	       &new_filter, sizeof(u32));
 
-	request->wait_condition = 0;
 	ret = rndis_filter_send_request(dev, request);
 	if (ret != 0)
 		goto Cleanup;
 
-	wait_event_timeout(request->wait_event, request->wait_condition,
-		msecs_to_jiffies(2000));
-	if (request->wait_condition == 0) {
+	t = wait_for_completion_timeout(&request->wait_event, HZ);
+
+	if (t == 0) {
 		ret = -1;
-		DPRINT_ERR(NETVSC, "timeout before we got a set response...");
+		dev_err(&dev->net_dev->dev->device,
+			"timeout before we got a set response...\n");
 		/*
 		 * We can't deallocate the request since we may still receive a
 		 * send completion for it.
@@ -603,42 +568,6 @@
 	return ret;
 }
 
-int rndis_filter_init(struct netvsc_driver *drv)
-{
-	DPRINT_DBG(NETVSC, "sizeof(struct rndis_filter_packet) == %zd",
-		   sizeof(struct rndis_filter_packet));
-
-	drv->req_ext_size = sizeof(struct rndis_filter_packet);
-
-	/* Driver->Context = rndisDriver; */
-
-	memset(&rndis_filter, 0, sizeof(struct rndis_filter_driver_object));
-
-	/*rndisDriver->Driver = Driver;
-
-	ASSERT(Driver->OnLinkStatusChanged);
-	rndisDriver->OnLinkStatusChanged = Driver->OnLinkStatusChanged;*/
-
-	/* Save the original dispatch handlers before we override it */
-	rndis_filter.inner_drv.base.dev_add = drv->base.dev_add;
-	rndis_filter.inner_drv.base.dev_rm =
-					drv->base.dev_rm;
-	rndis_filter.inner_drv.base.cleanup = drv->base.cleanup;
-
-	rndis_filter.inner_drv.send = drv->send;
-	rndis_filter.inner_drv.recv_cb = drv->recv_cb;
-	rndis_filter.inner_drv.link_status_change =
-					drv->link_status_change;
-
-	/* Override */
-	drv->base.dev_add = rndis_filte_device_add;
-	drv->base.dev_rm = rndis_filter_device_remove;
-	drv->base.cleanup = rndis_filter_cleanup;
-	drv->send = rndis_filter_send;
-	drv->recv_cb = rndis_filter_receive;
-
-	return 0;
-}
 
 static int rndis_filter_init_device(struct rndis_device *dev)
 {
@@ -646,7 +575,7 @@
 	struct rndis_initialize_request *init;
 	struct rndis_initialize_complete *init_complete;
 	u32 status;
-	int ret;
+	int ret, t;
 
 	request = get_rndis_request(dev, REMOTE_NDIS_INITIALIZE_MSG,
 			RNDIS_MESSAGE_SIZE(struct rndis_initialize_request));
@@ -664,7 +593,6 @@
 
 	dev->state = RNDIS_DEV_INITIALIZING;
 
-	request->wait_condition = 0;
 	ret = rndis_filter_send_request(dev, request);
 	if (ret != 0) {
 		dev->state = RNDIS_DEV_UNINITIALIZED;
@@ -672,9 +600,9 @@
 	}
 
 
-	wait_event_timeout(request->wait_event, request->wait_condition,
-		msecs_to_jiffies(1000));
-	if (request->wait_condition == 0) {
+	t = wait_for_completion_timeout(&request->wait_event, HZ);
+
+	if (t == 0) {
 		ret = -ETIMEDOUT;
 		goto Cleanup;
 	}
@@ -753,7 +681,7 @@
 	return ret;
 }
 
-static int rndis_filte_device_add(struct hv_device *dev,
+int rndis_filte_device_add(struct hv_device *dev,
 				  void *additional_info)
 {
 	int ret;
@@ -765,14 +693,12 @@
 	if (!rndisDevice)
 		return -1;
 
-	DPRINT_DBG(NETVSC, "rndis device object allocated - %p", rndisDevice);
-
 	/*
 	 * Let the inner driver handle this first to create the netvsc channel
 	 * NOTE! Once the channel is created, we may get a receive callback
 	 * (RndisFilterOnReceive()) before this call is completed
 	 */
-	ret = rndis_filter.inner_drv.base.dev_add(dev, additional_info);
+	ret = netvsc_device_add(dev, additional_info);
 	if (ret != 0) {
 		kfree(rndisDevice);
 		return ret;
@@ -802,21 +728,20 @@
 		 */
 	}
 
-	DPRINT_INFO(NETVSC, "Device 0x%p mac addr %pM",
-		    rndisDevice, rndisDevice->hw_mac_adr);
-
 	memcpy(deviceInfo->mac_adr, rndisDevice->hw_mac_adr, ETH_ALEN);
 
 	rndis_filter_query_device_link_status(rndisDevice);
 
 	deviceInfo->link_state = rndisDevice->link_stat;
-	DPRINT_INFO(NETVSC, "Device 0x%p link state %s", rndisDevice,
-		    ((deviceInfo->link_state) ? ("down") : ("up")));
+
+	dev_info(&dev->device, "Device MAC %pM link state %s",
+		 rndisDevice->hw_mac_adr,
+		 ((deviceInfo->link_state) ? ("down\n") : ("up\n")));
 
 	return ret;
 }
 
-static int rndis_filter_device_remove(struct hv_device *dev)
+int rndis_filter_device_remove(struct hv_device *dev)
 {
 	struct netvsc_device *net_dev = dev->ext;
 	struct rndis_device *rndis_dev = net_dev->extension;
@@ -827,15 +752,11 @@
 	kfree(rndis_dev);
 	net_dev->extension = NULL;
 
-	/* Pass control to inner driver to remove the device */
-	rndis_filter.inner_drv.base.dev_rm(dev);
+	netvsc_device_remove(dev);
 
 	return 0;
 }
 
-static void rndis_filter_cleanup(struct hv_driver *drv)
-{
-}
 
 int rndis_filter_open(struct hv_device *dev)
 {
@@ -857,7 +778,7 @@
 	return rndis_filter_close_device(netDevice->extension);
 }
 
-static int rndis_filter_send(struct hv_device *dev,
+int rndis_filter_send(struct hv_device *dev,
 			     struct hv_netvsc_packet *pkt)
 {
 	int ret;
@@ -897,7 +818,7 @@
 	pkt->completion.send.send_completion = rndis_filter_send_completion;
 	pkt->completion.send.send_completion_ctx = filterPacket;
 
-	ret = rndis_filter.inner_drv.send(dev, pkt);
+	ret = netvsc_send(dev, pkt);
 	if (ret != 0) {
 		/*
 		 * Reset the completion to originals to allow retries from
diff -druN linux-2.6.39-libre/drivers/staging/hv/rndis_filter.h linux-3.0-rc7-libre/drivers/staging/hv/rndis_filter.h
--- linux-2.6.39-libre/drivers/staging/hv/rndis_filter.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/hv/rndis_filter.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,55 +0,0 @@
-/*
- *
- * Copyright (c) 2009, Microsoft 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., 59 Temple
- * Place - Suite 330, Boston, MA 02111-1307 USA.
- *
- * Authors:
- *   Haiyang Zhang <haiyangz@microsoft.com>
- *   Hank Janssen  <hjanssen@microsoft.com>
- *
- */
-
-
-#ifndef _RNDISFILTER_H_
-#define _RNDISFILTER_H_
-
-#define __struct_bcount(x)
-
-#include "netvsc.h"
-
-#include "rndis.h"
-
-#define RNDIS_HEADER_SIZE	(sizeof(struct rndis_message) - \
-				 sizeof(union rndis_message_container))
-
-#define NDIS_PACKET_TYPE_DIRECTED	0x00000001
-#define NDIS_PACKET_TYPE_MULTICAST	0x00000002
-#define NDIS_PACKET_TYPE_ALL_MULTICAST	0x00000004
-#define NDIS_PACKET_TYPE_BROADCAST	0x00000008
-#define NDIS_PACKET_TYPE_SOURCE_ROUTING	0x00000010
-#define NDIS_PACKET_TYPE_PROMISCUOUS	0x00000020
-#define NDIS_PACKET_TYPE_SMT		0x00000040
-#define NDIS_PACKET_TYPE_ALL_LOCAL	0x00000080
-#define NDIS_PACKET_TYPE_GROUP		0x00000100
-#define NDIS_PACKET_TYPE_ALL_FUNCTIONAL	0x00000200
-#define NDIS_PACKET_TYPE_FUNCTIONAL	0x00000400
-#define NDIS_PACKET_TYPE_MAC_FRAME	0x00000800
-
-
-/* Interface */
-
-extern int rndis_filter_init(struct netvsc_driver *driver);
-
-#endif /* _RNDISFILTER_H_ */
diff -druN linux-2.6.39-libre/drivers/staging/hv/rndis.h linux-3.0-rc7-libre/drivers/staging/hv/rndis.h
--- linux-2.6.39-libre/drivers/staging/hv/rndis.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/hv/rndis.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,653 +0,0 @@
-/*
- *
- * Copyright (c) 2009, Microsoft 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., 59 Temple
- * Place - Suite 330, Boston, MA 02111-1307 USA.
- *
- * Authors:
- *   Haiyang Zhang <haiyangz@microsoft.com>
- *   Hank Janssen  <hjanssen@microsoft.com>
- *
- */
-
-#ifndef _RNDIS_H_
-#define _RNDIS_H_
-
-/*  Status codes */
-
-
-#ifndef STATUS_SUCCESS
-#define STATUS_SUCCESS				(0x00000000L)
-#endif
-
-#ifndef STATUS_UNSUCCESSFUL
-#define STATUS_UNSUCCESSFUL			(0xC0000001L)
-#endif
-
-#ifndef STATUS_PENDING
-#define STATUS_PENDING				(0x00000103L)
-#endif
-
-#ifndef STATUS_INSUFFICIENT_RESOURCES
-#define STATUS_INSUFFICIENT_RESOURCES		(0xC000009AL)
-#endif
-
-#ifndef STATUS_BUFFER_OVERFLOW
-#define STATUS_BUFFER_OVERFLOW			(0x80000005L)
-#endif
-
-#ifndef STATUS_NOT_SUPPORTED
-#define STATUS_NOT_SUPPORTED			(0xC00000BBL)
-#endif
-
-#define RNDIS_STATUS_SUCCESS			(STATUS_SUCCESS)
-#define RNDIS_STATUS_PENDING			(STATUS_PENDING)
-#define RNDIS_STATUS_NOT_RECOGNIZED		(0x00010001L)
-#define RNDIS_STATUS_NOT_COPIED			(0x00010002L)
-#define RNDIS_STATUS_NOT_ACCEPTED		(0x00010003L)
-#define RNDIS_STATUS_CALL_ACTIVE		(0x00010007L)
-
-#define RNDIS_STATUS_ONLINE			(0x40010003L)
-#define RNDIS_STATUS_RESET_START		(0x40010004L)
-#define RNDIS_STATUS_RESET_END			(0x40010005L)
-#define RNDIS_STATUS_RING_STATUS		(0x40010006L)
-#define RNDIS_STATUS_CLOSED			(0x40010007L)
-#define RNDIS_STATUS_WAN_LINE_UP		(0x40010008L)
-#define RNDIS_STATUS_WAN_LINE_DOWN		(0x40010009L)
-#define RNDIS_STATUS_WAN_FRAGMENT		(0x4001000AL)
-#define RNDIS_STATUS_MEDIA_CONNECT		(0x4001000BL)
-#define RNDIS_STATUS_MEDIA_DISCONNECT		(0x4001000CL)
-#define RNDIS_STATUS_HARDWARE_LINE_UP		(0x4001000DL)
-#define RNDIS_STATUS_HARDWARE_LINE_DOWN		(0x4001000EL)
-#define RNDIS_STATUS_INTERFACE_UP		(0x4001000FL)
-#define RNDIS_STATUS_INTERFACE_DOWN		(0x40010010L)
-#define RNDIS_STATUS_MEDIA_BUSY			(0x40010011L)
-#define RNDIS_STATUS_MEDIA_SPECIFIC_INDICATION	(0x40010012L)
-#define RNDIS_STATUS_WW_INDICATION		RDIA_SPECIFIC_INDICATION
-#define RNDIS_STATUS_LINK_SPEED_CHANGE		(0x40010013L)
-
-#define RNDIS_STATUS_NOT_RESETTABLE		(0x80010001L)
-#define RNDIS_STATUS_SOFT_ERRORS		(0x80010003L)
-#define RNDIS_STATUS_HARD_ERRORS		(0x80010004L)
-#define RNDIS_STATUS_BUFFER_OVERFLOW		(STATUS_BUFFER_OVERFLOW)
-
-#define RNDIS_STATUS_FAILURE			(STATUS_UNSUCCESSFUL)
-#define RNDIS_STATUS_RESOURCES			(STATUS_INSUFFICIENT_RESOURCES)
-#define RNDIS_STATUS_CLOSING			(0xC0010002L)
-#define RNDIS_STATUS_BAD_VERSION		(0xC0010004L)
-#define RNDIS_STATUS_BAD_CHARACTERISTICS	(0xC0010005L)
-#define RNDIS_STATUS_ADAPTER_NOT_FOUND		(0xC0010006L)
-#define RNDIS_STATUS_OPEN_FAILED		(0xC0010007L)
-#define RNDIS_STATUS_DEVICE_FAILED		(0xC0010008L)
-#define RNDIS_STATUS_MULTICAST_FULL		(0xC0010009L)
-#define RNDIS_STATUS_MULTICAST_EXISTS		(0xC001000AL)
-#define RNDIS_STATUS_MULTICAST_NOT_FOUND	(0xC001000BL)
-#define RNDIS_STATUS_REQUEST_ABORTED		(0xC001000CL)
-#define RNDIS_STATUS_RESET_IN_PROGRESS		(0xC001000DL)
-#define RNDIS_STATUS_CLOSING_INDICATING		(0xC001000EL)
-#define RNDIS_STATUS_NOT_SUPPORTED		(STATUS_NOT_SUPPORTED)
-#define RNDIS_STATUS_INVALID_PACKET		(0xC001000FL)
-#define RNDIS_STATUS_OPEN_LIST_FULL		(0xC0010010L)
-#define RNDIS_STATUS_ADAPTER_NOT_READY		(0xC0010011L)
-#define RNDIS_STATUS_ADAPTER_NOT_OPEN		(0xC0010012L)
-#define RNDIS_STATUS_NOT_INDICATING		(0xC0010013L)
-#define RNDIS_STATUS_INVALID_LENGTH		(0xC0010014L)
-#define RNDIS_STATUS_INVALID_DATA		(0xC0010015L)
-#define RNDIS_STATUS_BUFFER_TOO_SHORT		(0xC0010016L)
-#define RNDIS_STATUS_INVALID_OID		(0xC0010017L)
-#define RNDIS_STATUS_ADAPTER_REMOVED		(0xC0010018L)
-#define RNDIS_STATUS_UNSUPPORTED_MEDIA		(0xC0010019L)
-#define RNDIS_STATUS_GROUP_ADDRESS_IN_USE	(0xC001001AL)
-#define RNDIS_STATUS_FILE_NOT_FOUND		(0xC001001BL)
-#define RNDIS_STATUS_ERROR_READING_FILE		(0xC001001CL)
-#define RNDIS_STATUS_ALREADY_MAPPED		(0xC001001DL)
-#define RNDIS_STATUS_RESOURCE_CONFLICT		(0xC001001EL)
-#define RNDIS_STATUS_NO_CABLE			(0xC001001FL)
-
-#define RNDIS_STATUS_INVALID_SAP		(0xC0010020L)
-#define RNDIS_STATUS_SAP_IN_USE			(0xC0010021L)
-#define RNDIS_STATUS_INVALID_ADDRESS		(0xC0010022L)
-#define RNDIS_STATUS_VC_NOT_ACTIVATED		(0xC0010023L)
-#define RNDIS_STATUS_DEST_OUT_OF_ORDER		(0xC0010024L)
-#define RNDIS_STATUS_VC_NOT_AVAILABLE		(0xC0010025L)
-#define RNDIS_STATUS_CELLRATE_NOT_AVAILABLE	(0xC0010026L)
-#define RNDIS_STATUS_INCOMPATABLE_QOS		(0xC0010027L)
-#define RNDIS_STATUS_AAL_PARAMS_UNSUPPORTED	(0xC0010028L)
-#define RNDIS_STATUS_NO_ROUTE_TO_DESTINATION	(0xC0010029L)
-
-#define RNDIS_STATUS_TOKEN_RING_OPEN_ERROR	(0xC0011000L)
-
-/* Object Identifiers used by NdisRequest Query/Set Information */
-/* General Objects */
-#define RNDIS_OID_GEN_SUPPORTED_LIST		0x00010101
-#define RNDIS_OID_GEN_HARDWARE_STATUS		0x00010102
-#define RNDIS_OID_GEN_MEDIA_SUPPORTED		0x00010103
-#define RNDIS_OID_GEN_MEDIA_IN_USE		0x00010104
-#define RNDIS_OID_GEN_MAXIMUM_LOOKAHEAD		0x00010105
-#define RNDIS_OID_GEN_MAXIMUM_FRAME_SIZE	0x00010106
-#define RNDIS_OID_GEN_LINK_SPEED		0x00010107
-#define RNDIS_OID_GEN_TRANSMIT_BUFFER_SPACE	0x00010108
-#define RNDIS_OID_GEN_RECEIVE_BUFFER_SPACE	0x00010109
-#define RNDIS_OID_GEN_TRANSMIT_BLOCK_SIZE	0x0001010A
-#define RNDIS_OID_GEN_RECEIVE_BLOCK_SIZE	0x0001010B
-#define RNDIS_OID_GEN_VENDOR_ID			0x0001010C
-#define RNDIS_OID_GEN_VENDOR_DESCRIPTION	0x0001010D
-#define RNDIS_OID_GEN_CURRENT_PACKET_FILTER	0x0001010E
-#define RNDIS_OID_GEN_CURRENT_LOOKAHEAD		0x0001010F
-#define RNDIS_OID_GEN_DRIVER_VERSION		0x00010110
-#define RNDIS_OID_GEN_MAXIMUM_TOTAL_SIZE	0x00010111
-#define RNDIS_OID_GEN_PROTOCOL_OPTIONS		0x00010112
-#define RNDIS_OID_GEN_MAC_OPTIONS		0x00010113
-#define RNDIS_OID_GEN_MEDIA_CONNECT_STATUS	0x00010114
-#define RNDIS_OID_GEN_MAXIMUM_SEND_PACKETS	0x00010115
-#define RNDIS_OID_GEN_VENDOR_DRIVER_VERSION	0x00010116
-#define RNDIS_OID_GEN_NETWORK_LAYER_ADDRESSES	0x00010118
-#define RNDIS_OID_GEN_TRANSPORT_HEADER_OFFSET	0x00010119
-#define RNDIS_OID_GEN_MACHINE_NAME		0x0001021A
-#define RNDIS_OID_GEN_RNDIS_CONFIG_PARAMETER	0x0001021B
-
-#define RNDIS_OID_GEN_XMIT_OK			0x00020101
-#define RNDIS_OID_GEN_RCV_OK			0x00020102
-#define RNDIS_OID_GEN_XMIT_ERROR		0x00020103
-#define RNDIS_OID_GEN_RCV_ERROR			0x00020104
-#define RNDIS_OID_GEN_RCV_NO_BUFFER		0x00020105
-
-#define RNDIS_OID_GEN_DIRECTED_BYTES_XMIT	0x00020201
-#define RNDIS_OID_GEN_DIRECTED_FRAMES_XMIT	0x00020202
-#define RNDIS_OID_GEN_MULTICAST_BYTES_XMIT	0x00020203
-#define RNDIS_OID_GEN_MULTICAST_FRAMES_XMIT	0x00020204
-#define RNDIS_OID_GEN_BROADCAST_BYTES_XMIT	0x00020205
-#define RNDIS_OID_GEN_BROADCAST_FRAMES_XMIT	0x00020206
-#define RNDIS_OID_GEN_DIRECTED_BYTES_RCV	0x00020207
-#define RNDIS_OID_GEN_DIRECTED_FRAMES_RCV	0x00020208
-#define RNDIS_OID_GEN_MULTICAST_BYTES_RCV	0x00020209
-#define RNDIS_OID_GEN_MULTICAST_FRAMES_RCV	0x0002020A
-#define RNDIS_OID_GEN_BROADCAST_BYTES_RCV	0x0002020B
-#define RNDIS_OID_GEN_BROADCAST_FRAMES_RCV	0x0002020C
-
-#define RNDIS_OID_GEN_RCV_CRC_ERROR		0x0002020D
-#define RNDIS_OID_GEN_TRANSMIT_QUEUE_LENGTH	0x0002020E
-
-#define RNDIS_OID_GEN_GET_TIME_CAPS		0x0002020F
-#define RNDIS_OID_GEN_GET_NETCARD_TIME		0x00020210
-
-/* These are connection-oriented general OIDs. */
-/* These replace the above OIDs for connection-oriented media. */
-#define RNDIS_OID_GEN_CO_SUPPORTED_LIST		0x00010101
-#define RNDIS_OID_GEN_CO_HARDWARE_STATUS	0x00010102
-#define RNDIS_OID_GEN_CO_MEDIA_SUPPORTED	0x00010103
-#define RNDIS_OID_GEN_CO_MEDIA_IN_USE		0x00010104
-#define RNDIS_OID_GEN_CO_LINK_SPEED		0x00010105
-#define RNDIS_OID_GEN_CO_VENDOR_ID		0x00010106
-#define RNDIS_OID_GEN_CO_VENDOR_DESCRIPTION	0x00010107
-#define RNDIS_OID_GEN_CO_DRIVER_VERSION		0x00010108
-#define RNDIS_OID_GEN_CO_PROTOCOL_OPTIONS	0x00010109
-#define RNDIS_OID_GEN_CO_MAC_OPTIONS		0x0001010A
-#define RNDIS_OID_GEN_CO_MEDIA_CONNECT_STATUS	0x0001010B
-#define RNDIS_OID_GEN_CO_VENDOR_DRIVER_VERSION	0x0001010C
-#define RNDIS_OID_GEN_CO_MINIMUM_LINK_SPEED	0x0001010D
-
-#define RNDIS_OID_GEN_CO_GET_TIME_CAPS		0x00010201
-#define RNDIS_OID_GEN_CO_GET_NETCARD_TIME	0x00010202
-
-/* These are connection-oriented statistics OIDs. */
-#define RNDIS_OID_GEN_CO_XMIT_PDUS_OK		0x00020101
-#define RNDIS_OID_GEN_CO_RCV_PDUS_OK		0x00020102
-#define RNDIS_OID_GEN_CO_XMIT_PDUS_ERROR	0x00020103
-#define RNDIS_OID_GEN_CO_RCV_PDUS_ERROR		0x00020104
-#define RNDIS_OID_GEN_CO_RCV_PDUS_NO_BUFFER	0x00020105
-
-
-#define RNDIS_OID_GEN_CO_RCV_CRC_ERROR		0x00020201
-#define RNDIS_OID_GEN_CO_TRANSMIT_QUEUE_LENGTH	0x00020202
-#define RNDIS_OID_GEN_CO_BYTES_XMIT		0x00020203
-#define RNDIS_OID_GEN_CO_BYTES_RCV		0x00020204
-#define RNDIS_OID_GEN_CO_BYTES_XMIT_OUTSTANDING	0x00020205
-#define RNDIS_OID_GEN_CO_NETCARD_LOAD		0x00020206
-
-/* These are objects for Connection-oriented media call-managers. */
-#define RNDIS_OID_CO_ADD_PVC			0xFF000001
-#define RNDIS_OID_CO_DELETE_PVC			0xFF000002
-#define RNDIS_OID_CO_GET_CALL_INFORMATION	0xFF000003
-#define RNDIS_OID_CO_ADD_ADDRESS		0xFF000004
-#define RNDIS_OID_CO_DELETE_ADDRESS		0xFF000005
-#define RNDIS_OID_CO_GET_ADDRESSES		0xFF000006
-#define RNDIS_OID_CO_ADDRESS_CHANGE		0xFF000007
-#define RNDIS_OID_CO_SIGNALING_ENABLED		0xFF000008
-#define RNDIS_OID_CO_SIGNALING_DISABLED		0xFF000009
-
-/* 802.3 Objects (Ethernet) */
-#define RNDIS_OID_802_3_PERMANENT_ADDRESS	0x01010101
-#define RNDIS_OID_802_3_CURRENT_ADDRESS		0x01010102
-#define RNDIS_OID_802_3_MULTICAST_LIST		0x01010103
-#define RNDIS_OID_802_3_MAXIMUM_LIST_SIZE	0x01010104
-#define RNDIS_OID_802_3_MAC_OPTIONS		0x01010105
-
-#define NDIS_802_3_MAC_OPTION_PRIORITY		0x00000001
-
-#define RNDIS_OID_802_3_RCV_ERROR_ALIGNMENT	0x01020101
-#define RNDIS_OID_802_3_XMIT_ONE_COLLISION	0x01020102
-#define RNDIS_OID_802_3_XMIT_MORE_COLLISIONS	0x01020103
-
-#define RNDIS_OID_802_3_XMIT_DEFERRED		0x01020201
-#define RNDIS_OID_802_3_XMIT_MAX_COLLISIONS	0x01020202
-#define RNDIS_OID_802_3_RCV_OVERRUN		0x01020203
-#define RNDIS_OID_802_3_XMIT_UNDERRUN		0x01020204
-#define RNDIS_OID_802_3_XMIT_HEARTBEAT_FAILURE	0x01020205
-#define RNDIS_OID_802_3_XMIT_TIMES_CRS_LOST	0x01020206
-#define RNDIS_OID_802_3_XMIT_LATE_COLLISIONS	0x01020207
-
-/* Remote NDIS message types */
-#define REMOTE_NDIS_PACKET_MSG			0x00000001
-#define REMOTE_NDIS_INITIALIZE_MSG		0x00000002
-#define REMOTE_NDIS_HALT_MSG			0x00000003
-#define REMOTE_NDIS_QUERY_MSG			0x00000004
-#define REMOTE_NDIS_SET_MSG			0x00000005
-#define REMOTE_NDIS_RESET_MSG			0x00000006
-#define REMOTE_NDIS_INDICATE_STATUS_MSG		0x00000007
-#define REMOTE_NDIS_KEEPALIVE_MSG		0x00000008
-
-#define REMOTE_CONDIS_MP_CREATE_VC_MSG		0x00008001
-#define REMOTE_CONDIS_MP_DELETE_VC_MSG		0x00008002
-#define REMOTE_CONDIS_MP_ACTIVATE_VC_MSG	0x00008005
-#define REMOTE_CONDIS_MP_DEACTIVATE_VC_MSG	0x00008006
-#define REMOTE_CONDIS_INDICATE_STATUS_MSG	0x00008007
-
-/* Remote NDIS message completion types */
-#define REMOTE_NDIS_INITIALIZE_CMPLT		0x80000002
-#define REMOTE_NDIS_QUERY_CMPLT			0x80000004
-#define REMOTE_NDIS_SET_CMPLT			0x80000005
-#define REMOTE_NDIS_RESET_CMPLT			0x80000006
-#define REMOTE_NDIS_KEEPALIVE_CMPLT		0x80000008
-
-#define REMOTE_CONDIS_MP_CREATE_VC_CMPLT	0x80008001
-#define REMOTE_CONDIS_MP_DELETE_VC_CMPLT	0x80008002
-#define REMOTE_CONDIS_MP_ACTIVATE_VC_CMPLT	0x80008005
-#define REMOTE_CONDIS_MP_DEACTIVATE_VC_CMPLT	0x80008006
-
-/*
- * Reserved message type for private communication between lower-layer host
- * driver and remote device, if necessary.
- */
-#define REMOTE_NDIS_BUS_MSG			0xff000001
-
-/*  Defines for DeviceFlags in struct rndis_initialize_complete */
-#define RNDIS_DF_CONNECTIONLESS			0x00000001
-#define RNDIS_DF_CONNECTION_ORIENTED		0x00000002
-#define RNDIS_DF_RAW_DATA			0x00000004
-
-/*  Remote NDIS medium types. */
-#define RNDIS_MEDIUM_802_3			0x00000000
-#define RNDIS_MEDIUM_802_5			0x00000001
-#define RNDIS_MEDIUM_FDDI				0x00000002
-#define RNDIS_MEDIUM_WAN				0x00000003
-#define RNDIS_MEDIUM_LOCAL_TALK			0x00000004
-#define RNDIS_MEDIUM_ARCNET_RAW			0x00000006
-#define RNDIS_MEDIUM_ARCNET_878_2			0x00000007
-#define RNDIS_MEDIUM_ATM				0x00000008
-#define RNDIS_MEDIUM_WIRELESS_WAN			0x00000009
-#define RNDIS_MEDIUM_IRDA				0x0000000a
-#define RNDIS_MEDIUM_CO_WAN			0x0000000b
-/* Not a real medium, defined as an upper-bound */
-#define RNDIS_MEDIUM_MAX				0x0000000d
-
-
-/* Remote NDIS medium connection states. */
-#define RNDIS_MEDIA_STATE_CONNECTED		0x00000000
-#define RNDIS_MEDIA_STATE_DISCONNECTED		0x00000001
-
-/*  Remote NDIS version numbers */
-#define RNDIS_MAJOR_VERSION			0x00000001
-#define RNDIS_MINOR_VERSION			0x00000000
-
-
-/* NdisInitialize message */
-struct rndis_initialize_request {
-	u32 req_id;
-	u32 major_ver;
-	u32 minor_ver;
-	u32 max_xfer_size;
-};
-
-/* Response to NdisInitialize */
-struct rndis_initialize_complete {
-	u32 req_id;
-	u32 status;
-	u32 major_ver;
-	u32 minor_ver;
-	u32 dev_flags;
-	u32 medium;
-	u32 max_pkt_per_msg;
-	u32 max_xfer_size;
-	u32 pkt_alignment_factor;
-	u32 af_list_offset;
-	u32 af_list_size;
-};
-
-/* Call manager devices only: Information about an address family */
-/* supported by the device is appended to the response to NdisInitialize. */
-struct rndis_co_address_family {
-	u32 address_family;
-	u32 major_ver;
-	u32 minor_ver;
-};
-
-/* NdisHalt message */
-struct rndis_halt_request {
-	u32 req_id;
-};
-
-/* NdisQueryRequest message */
-struct rndis_query_request {
-	u32 req_id;
-	u32 oid;
-	u32 info_buflen;
-	u32 info_buf_offset;
-	u32 dev_vc_handle;
-};
-
-/* Response to NdisQueryRequest */
-struct rndis_query_complete {
-	u32 req_id;
-	u32 status;
-	u32 info_buflen;
-	u32 info_buf_offset;
-};
-
-/* NdisSetRequest message */
-struct rndis_set_request {
-	u32 req_id;
-	u32 oid;
-	u32 info_buflen;
-	u32 info_buf_offset;
-	u32 dev_vc_handle;
-};
-
-/* Response to NdisSetRequest */
-struct rndis_set_complete {
-	u32 req_id;
-	u32 status;
-};
-
-/* NdisReset message */
-struct rndis_reset_request {
-	u32 reserved;
-};
-
-/* Response to NdisReset */
-struct rndis_reset_complete {
-	u32 status;
-	u32 addressing_reset;
-};
-
-/* NdisMIndicateStatus message */
-struct rndis_indicate_status {
-	u32 status;
-	u32 status_buflen;
-	u32 status_buf_offset;
-};
-
-/* Diagnostic information passed as the status buffer in */
-/* struct rndis_indicate_status messages signifying error conditions. */
-struct rndis_diagnostic_info {
-	u32 diag_status;
-	u32 error_offset;
-};
-
-/* NdisKeepAlive message */
-struct rndis_keepalive_request {
-	u32 req_id;
-};
-
-/* Response to NdisKeepAlive */
-struct rndis_keepalive_complete {
-	u32 req_id;
-	u32 status;
-};
-
-/*
- * Data message. All Offset fields contain byte offsets from the beginning of
- * struct rndis_packet. All Length fields are in bytes.  VcHandle is set
- * to 0 for connectionless data, otherwise it contains the VC handle.
- */
-struct rndis_packet {
-	u32 data_offset;
-	u32 data_len;
-	u32 oob_data_offset;
-	u32 oob_data_len;
-	u32 num_oob_data_elements;
-	u32 per_pkt_info_offset;
-	u32 per_pkt_info_len;
-	u32 vc_handle;
-	u32 reserved;
-};
-
-/* Optional Out of Band data associated with a Data message. */
-struct rndis_oobd {
-	u32 size;
-	u32 type;
-	u32 class_info_offset;
-};
-
-/* Packet extension field contents associated with a Data message. */
-struct rndis_per_packet_info {
-	u32 size;
-	u32 type;
-	u32 per_pkt_info_offset;
-};
-
-/* Format of Information buffer passed in a SetRequest for the OID */
-/* OID_GEN_RNDIS_CONFIG_PARAMETER. */
-struct rndis_config_parameter_info {
-	u32 parameter_name_offset;
-	u32 parameter_name_length;
-	u32 parameter_type;
-	u32 parameter_value_offset;
-	u32 parameter_value_length;
-};
-
-/* Values for ParameterType in struct rndis_config_parameter_info */
-#define RNDIS_CONFIG_PARAM_TYPE_INTEGER     0
-#define RNDIS_CONFIG_PARAM_TYPE_STRING      2
-
-/* CONDIS Miniport messages for connection oriented devices */
-/* that do not implement a call manager. */
-
-/* CoNdisMiniportCreateVc message */
-struct rcondis_mp_create_vc {
-	u32 req_id;
-	u32 ndis_vc_handle;
-};
-
-/* Response to CoNdisMiniportCreateVc */
-struct rcondis_mp_create_vc_complete {
-	u32 req_id;
-	u32 dev_vc_handle;
-	u32 status;
-};
-
-/* CoNdisMiniportDeleteVc message */
-struct rcondis_mp_delete_vc {
-	u32 req_id;
-	u32 dev_vc_handle;
-};
-
-/* Response to CoNdisMiniportDeleteVc */
-struct rcondis_mp_delete_vc_complete {
-	u32 req_id;
-	u32 status;
-};
-
-/* CoNdisMiniportQueryRequest message */
-struct rcondis_mp_query_request {
-	u32 req_id;
-	u32 request_type;
-	u32 oid;
-	u32 dev_vc_handle;
-	u32 info_buflen;
-	u32 info_buf_offset;
-};
-
-/* CoNdisMiniportSetRequest message */
-struct rcondis_mp_set_request {
-	u32 req_id;
-	u32 request_type;
-	u32 oid;
-	u32 dev_vc_handle;
-	u32 info_buflen;
-	u32 info_buf_offset;
-};
-
-/* CoNdisIndicateStatus message */
-struct rcondis_indicate_status {
-	u32 ndis_vc_handle;
-	u32 status;
-	u32 status_buflen;
-	u32 status_buf_offset;
-};
-
-/* CONDIS Call/VC parameters */
-struct rcondis_specific_parameters {
-	u32 parameter_type;
-	u32 parameter_length;
-	u32 parameter_lffset;
-};
-
-struct rcondis_media_parameters {
-	u32 flags;
-	u32 reserved1;
-	u32 reserved2;
-	struct rcondis_specific_parameters media_specific;
-};
-
-struct rndis_flowspec {
-	u32 token_rate;
-	u32 token_bucket_size;
-	u32 peak_bandwidth;
-	u32 latency;
-	u32 delay_variation;
-	u32 service_type;
-	u32 max_sdu_size;
-	u32 minimum_policed_size;
-};
-
-struct rcondis_call_manager_parameters {
-	struct rndis_flowspec transmit;
-	struct rndis_flowspec receive;
-	struct rcondis_specific_parameters call_mgr_specific;
-};
-
-/* CoNdisMiniportActivateVc message */
-struct rcondis_mp_activate_vc_request {
-	u32 req_id;
-	u32 flags;
-	u32 dev_vc_handle;
-	u32 media_params_offset;
-	u32 media_params_length;
-	u32 call_mgr_params_offset;
-	u32 call_mgr_params_length;
-};
-
-/* Response to CoNdisMiniportActivateVc */
-struct rcondis_mp_activate_vc_complete {
-	u32 req_id;
-	u32 status;
-};
-
-/* CoNdisMiniportDeactivateVc message */
-struct rcondis_mp_deactivate_vc_request {
-	u32 req_id;
-	u32 flags;
-	u32 dev_vc_handle;
-};
-
-/* Response to CoNdisMiniportDeactivateVc */
-struct rcondis_mp_deactivate_vc_complete {
-	u32 req_id;
-	u32 status;
-};
-
-
-/* union with all of the RNDIS messages */
-union rndis_message_container {
-	struct rndis_packet pkt;
-	struct rndis_initialize_request init_req;
-	struct rndis_halt_request halt_req;
-	struct rndis_query_request query_req;
-	struct rndis_set_request set_req;
-	struct rndis_reset_request reset_req;
-	struct rndis_keepalive_request keep_alive_req;
-	struct rndis_indicate_status indicate_status;
-	struct rndis_initialize_complete init_complete;
-	struct rndis_query_complete query_complete;
-	struct rndis_set_complete set_complete;
-	struct rndis_reset_complete reset_complete;
-	struct rndis_keepalive_complete keep_alive_complete;
-	struct rcondis_mp_create_vc co_miniport_create_vc;
-	struct rcondis_mp_delete_vc co_miniport_delete_vc;
-	struct rcondis_indicate_status co_indicate_status;
-	struct rcondis_mp_activate_vc_request co_miniport_activate_vc;
-	struct rcondis_mp_deactivate_vc_request co_miniport_deactivate_vc;
-	struct rcondis_mp_create_vc_complete co_miniport_create_vc_complete;
-	struct rcondis_mp_delete_vc_complete co_miniport_delete_vc_complete;
-	struct rcondis_mp_activate_vc_complete co_miniport_activate_vc_complete;
-	struct rcondis_mp_deactivate_vc_complete
-		co_miniport_deactivate_vc_complete;
-};
-
-/* Remote NDIS message format */
-struct rndis_message {
-	u32 ndis_msg_type;
-
-	/* Total length of this message, from the beginning */
-	/* of the sruct rndis_message, in bytes. */
-	u32 msg_len;
-
-	/* Actual message */
-	union rndis_message_container msg;
-};
-
-/* Handy macros */
-
-/* get the size of an RNDIS message. Pass in the message type, */
-/* struct rndis_set_request, struct rndis_packet for example */
-#define RNDIS_MESSAGE_SIZE(msg)				\
-	(sizeof(msg) + (sizeof(struct rndis_message) -	\
-	 sizeof(union rndis_message_container)))
-
-/* get pointer to info buffer with message pointer */
-#define MESSAGE_TO_INFO_BUFFER(msg)				\
-	(((unsigned char *)(msg)) + msg->info_buf_offset)
-
-/* get pointer to status buffer with message pointer */
-#define MESSAGE_TO_STATUS_BUFFER(msg)			\
-	(((unsigned char *)(msg)) + msg->status_buf_offset)
-
-/* get pointer to OOBD buffer with message pointer */
-#define MESSAGE_TO_OOBD_BUFFER(msg)				\
-	(((unsigned char *)(msg)) + msg->oob_data_offset)
-
-/* get pointer to data buffer with message pointer */
-#define MESSAGE_TO_DATA_BUFFER(msg)				\
-	(((unsigned char *)(msg)) + msg->per_pkt_info_offset)
-
-/* get pointer to contained message from NDIS_MESSAGE pointer */
-#define RNDIS_MESSAGE_PTR_TO_MESSAGE_PTR(rndis_msg)		\
-	((void *) &rndis_msg->msg)
-
-/* get pointer to contained message from NDIS_MESSAGE pointer */
-#define RNDIS_MESSAGE_RAW_PTR_TO_MESSAGE_PTR(rndis_msg)	\
-	((void *) rndis_msg)
-
-#endif /* _RNDIS_H_ */
diff -druN linux-2.6.39-libre/drivers/staging/hv/storvsc_api.h linux-3.0-rc7-libre/drivers/staging/hv/storvsc_api.h
--- linux-2.6.39-libre/drivers/staging/hv/storvsc_api.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/hv/storvsc_api.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,110 +0,0 @@
-/*
- *
- * Copyright (c) 2009, Microsoft 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., 59 Temple
- * Place - Suite 330, Boston, MA 02111-1307 USA.
- *
- * Authors:
- *   Haiyang Zhang <haiyangz@microsoft.com>
- *   Hank Janssen  <hjanssen@microsoft.com>
- *
- */
-
-
-#ifndef _STORVSC_API_H_
-#define _STORVSC_API_H_
-
-#include "vmbus_api.h"
-
-/* Defines */
-#define STORVSC_RING_BUFFER_SIZE			(20*PAGE_SIZE)
-#define BLKVSC_RING_BUFFER_SIZE				(20*PAGE_SIZE)
-
-#define STORVSC_MAX_IO_REQUESTS				128
-
-/*
- * In Hyper-V, each port/path/target maps to 1 scsi host adapter.  In
- * reality, the path/target is not used (ie always set to 0) so our
- * scsi host adapter essentially has 1 bus with 1 target that contains
- * up to 256 luns.
- */
-#define STORVSC_MAX_LUNS_PER_TARGET			64
-#define STORVSC_MAX_TARGETS				1
-#define STORVSC_MAX_CHANNELS				1
-
-struct hv_storvsc_request;
-
-/* Matches Windows-end */
-enum storvsc_request_type{
-	WRITE_TYPE,
-	READ_TYPE,
-	UNKNOWN_TYPE,
-};
-
-struct hv_storvsc_request {
-	enum storvsc_request_type type;
-	u32 host;
-	u32 bus;
-	u32 target_id;
-	u32 lun_id;
-	u8 *cdb;
-	u32 cdb_len;
-	u32 status;
-	u32 bytes_xfer;
-
-	unsigned char *sense_buffer;
-	u32 sense_buffer_size;
-
-	void *context;
-
-	void (*on_io_completion)(struct hv_storvsc_request *request);
-
-	/* This points to the memory after DataBuffer */
-	void *extension;
-
-	struct hv_multipage_buffer data_buffer;
-};
-
-/* Represents the block vsc driver */
-struct storvsc_driver_object {
-	/* Must be the first field */
-	/* Which is a bug FIXME! */
-	struct hv_driver base;
-
-	/* Set by caller (in bytes) */
-	u32 ring_buffer_size;
-
-	/* Allocate this much private extension for each I/O request */
-	u32 request_ext_size;
-
-	/* Maximum # of requests in flight per channel/device */
-	u32 max_outstanding_req_per_channel;
-
-	/* Specific to this driver */
-	int (*on_io_request)(struct hv_device *device,
-			   struct hv_storvsc_request *request);
-};
-
-struct storvsc_device_info {
-	unsigned int port_number;
-	unsigned char path_id;
-	unsigned char target_id;
-};
-
-/* Interface */
-int stor_vsc_initialize(struct hv_driver *driver);
-int stor_vsc_on_host_reset(struct hv_device *device);
-int blk_vsc_initialize(struct hv_driver *driver);
-
-#endif /* _STORVSC_API_H_ */
diff -druN linux-2.6.39-libre/drivers/staging/hv/storvsc.c linux-3.0-rc7-libre/drivers/staging/hv/storvsc.c
--- linux-2.6.39-libre/drivers/staging/hv/storvsc.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/hv/storvsc.c	2011-07-11 19:51:52.000000000 -0400
@@ -17,71 +17,19 @@
  * Authors:
  *   Haiyang Zhang <haiyangz@microsoft.com>
  *   Hank Janssen  <hjanssen@microsoft.com>
+ *   K. Y. Srinivasan <kys@microsoft.com>
+ *
  */
 #include <linux/kernel.h>
 #include <linux/sched.h>
-#include <linux/wait.h>
+#include <linux/completion.h>
 #include <linux/string.h>
 #include <linux/slab.h>
 #include <linux/mm.h>
 #include <linux/delay.h>
-#include "hv_api.h"
-#include "logging.h"
-#include "storvsc_api.h"
-#include "vmbus_packet_format.h"
-#include "vstorage.h"
-#include "channel.h"
-
-
-struct storvsc_request_extension {
-	/* LIST_ENTRY ListEntry; */
-
-	struct hv_storvsc_request *request;
-	struct hv_device *device;
-
-	/* Synchronize the request/response if needed */
-	int wait_condition;
-	wait_queue_head_t wait_event;
-
-	struct vstor_packet vstor_packet;
-};
-
-/* A storvsc device is a device object that contains a vmbus channel */
-struct storvsc_device {
-	struct hv_device *device;
-
-	/* 0 indicates the device is being destroyed */
-	atomic_t ref_count;
-
-	atomic_t num_outstanding_req;
-
-	/*
-	 * Each unique Port/Path/Target represents 1 channel ie scsi
-	 * controller. In reality, the pathid, targetid is always 0
-	 * and the port is set by us
-	 */
-	unsigned int port_number;
-	unsigned char path_id;
-	unsigned char target_id;
-
-	/* LIST_ENTRY OutstandingRequestList; */
-	/* HANDLE OutstandingRequestLock; */
-
-	/* Used for vsc/vsp channel reset process */
-	struct storvsc_request_extension init_request;
-	struct storvsc_request_extension reset_request;
-};
-
 
-static const char *g_driver_name = "storvsc";
-
-/* {ba6163d9-04a1-4d29-b605-72e2ffb1dc7f} */
-static const struct hv_guid gStorVscDeviceType = {
-	.data = {
-		0xd9, 0x63, 0x61, 0xba, 0xa1, 0x04, 0x29, 0x4d,
-		0xb6, 0x05, 0x72, 0xe2, 0xff, 0xb1, 0xdc, 0x7f
-	}
-};
+#include "hyperv.h"
+#include "hyperv_storage.h"
 
 
 static inline struct storvsc_device *alloc_stor_device(struct hv_device *device)
@@ -96,6 +44,7 @@
 	/* (ie get_stor_device() and must_get_stor_device()) to proceed. */
 	atomic_cmpxchg(&stor_device->ref_count, 0, 2);
 
+	init_waitqueue_head(&stor_device->waiting_to_drain);
 	stor_device->device = device;
 	device->ext = stor_device;
 
@@ -104,24 +53,9 @@
 
 static inline void free_stor_device(struct storvsc_device *device)
 {
-	/* ASSERT(atomic_read(&device->ref_count) == 0); */
 	kfree(device);
 }
 
-/* Get the stordevice object iff exists and its refcount > 1 */
-static inline struct storvsc_device *get_stor_device(struct hv_device *device)
-{
-	struct storvsc_device *stor_device;
-
-	stor_device = (struct storvsc_device *)device->ext;
-	if (stor_device && atomic_read(&stor_device->ref_count) > 1)
-		atomic_inc(&stor_device->ref_count);
-	else
-		stor_device = NULL;
-
-	return stor_device;
-}
-
 /* Get the stordevice object iff exists and its refcount > 0 */
 static inline struct storvsc_device *must_get_stor_device(
 					struct hv_device *device)
@@ -137,17 +71,6 @@
 	return stor_device;
 }
 
-static inline void put_stor_device(struct hv_device *device)
-{
-	struct storvsc_device *stor_device;
-
-	stor_device = (struct storvsc_device *)device->ext;
-	/* ASSERT(stor_device); */
-
-	atomic_dec(&stor_device->ref_count);
-	/* ASSERT(atomic_read(&stor_device->ref_count)); */
-}
-
 /* Drop ref count to 1 to effectively disable get_stor_device() */
 static inline struct storvsc_device *release_stor_device(
 					struct hv_device *device)
@@ -155,7 +78,6 @@
 	struct storvsc_device *stor_device;
 
 	stor_device = (struct storvsc_device *)device->ext;
-	/* ASSERT(stor_device); */
 
 	/* Busy wait until the ref drop to 2, then set it to 1 */
 	while (atomic_cmpxchg(&stor_device->ref_count, 2, 1) != 2)
@@ -171,7 +93,6 @@
 	struct storvsc_device *stor_device;
 
 	stor_device = (struct storvsc_device *)device->ext;
-	/* ASSERT(stor_device); */
 
 	/* Busy wait until the ref drop to 1, then set it to 0 */
 	while (atomic_cmpxchg(&stor_device->ref_count, 1, 0) != 1)
@@ -181,19 +102,16 @@
 	return stor_device;
 }
 
-static int stor_vsc_channel_init(struct hv_device *device)
+static int storvsc_channel_init(struct hv_device *device)
 {
 	struct storvsc_device *stor_device;
-	struct storvsc_request_extension *request;
+	struct hv_storvsc_request *request;
 	struct vstor_packet *vstor_packet;
-	int ret;
+	int ret, t;
 
 	stor_device = get_stor_device(device);
-	if (!stor_device) {
-		DPRINT_ERR(STORVSC, "unable to get stor device..."
-			   "device being destroyed?");
+	if (!stor_device)
 		return -1;
-	}
 
 	request = &stor_device->init_request;
 	vstor_packet = &request->vstor_packet;
@@ -202,40 +120,30 @@
 	 * Now, initiate the vsc/vsp initialization protocol on the open
 	 * channel
 	 */
-	memset(request, 0, sizeof(struct storvsc_request_extension));
-	init_waitqueue_head(&request->wait_event);
+	memset(request, 0, sizeof(struct hv_storvsc_request));
+	init_completion(&request->wait_event);
 	vstor_packet->operation = VSTOR_OPERATION_BEGIN_INITIALIZATION;
 	vstor_packet->flags = REQUEST_COMPLETION_FLAG;
 
 	DPRINT_INFO(STORVSC, "BEGIN_INITIALIZATION_OPERATION...");
 
-	request->wait_condition = 0;
 	ret = vmbus_sendpacket(device->channel, vstor_packet,
 			       sizeof(struct vstor_packet),
 			       (unsigned long)request,
 			       VM_PKT_DATA_INBAND,
 			       VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
-	if (ret != 0) {
-		DPRINT_ERR(STORVSC,
-			   "unable to send BEGIN_INITIALIZATION_OPERATION");
+	if (ret != 0)
 		goto cleanup;
-	}
 
-	wait_event_timeout(request->wait_event, request->wait_condition,
-			msecs_to_jiffies(1000));
-	if (request->wait_condition == 0) {
+	t = wait_for_completion_timeout(&request->wait_event, HZ);
+	if (t == 0) {
 		ret = -ETIMEDOUT;
 		goto cleanup;
 	}
 
-
 	if (vstor_packet->operation != VSTOR_OPERATION_COMPLETE_IO ||
-	    vstor_packet->status != 0) {
-		DPRINT_ERR(STORVSC, "BEGIN_INITIALIZATION_OPERATION failed "
-			   "(op %d status 0x%x)",
-			   vstor_packet->operation, vstor_packet->status);
+	    vstor_packet->status != 0)
 		goto cleanup;
-	}
 
 	DPRINT_INFO(STORVSC, "QUERY_PROTOCOL_VERSION_OPERATION...");
 
@@ -247,33 +155,24 @@
 	vstor_packet->version.major_minor = VMSTOR_PROTOCOL_VERSION_CURRENT;
 	FILL_VMSTOR_REVISION(vstor_packet->version.revision);
 
-	request->wait_condition = 0;
 	ret = vmbus_sendpacket(device->channel, vstor_packet,
 			       sizeof(struct vstor_packet),
 			       (unsigned long)request,
 			       VM_PKT_DATA_INBAND,
 			       VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
-	if (ret != 0) {
-		DPRINT_ERR(STORVSC,
-			   "unable to send BEGIN_INITIALIZATION_OPERATION");
+	if (ret != 0)
 		goto cleanup;
-	}
 
-	wait_event_timeout(request->wait_event, request->wait_condition,
-			msecs_to_jiffies(1000));
-	if (request->wait_condition == 0) {
+	t = wait_for_completion_timeout(&request->wait_event, HZ);
+	if (t == 0) {
 		ret = -ETIMEDOUT;
 		goto cleanup;
 	}
 
 	/* TODO: Check returned version */
 	if (vstor_packet->operation != VSTOR_OPERATION_COMPLETE_IO ||
-	    vstor_packet->status != 0) {
-		DPRINT_ERR(STORVSC, "QUERY_PROTOCOL_VERSION_OPERATION failed "
-			   "(op %d status 0x%x)",
-			   vstor_packet->operation, vstor_packet->status);
+	    vstor_packet->status != 0)
 		goto cleanup;
-	}
 
 	/* Query channel properties */
 	DPRINT_INFO(STORVSC, "QUERY_PROPERTIES_OPERATION...");
@@ -284,76 +183,54 @@
 	vstor_packet->storage_channel_properties.port_number =
 					stor_device->port_number;
 
-	request->wait_condition = 0;
 	ret = vmbus_sendpacket(device->channel, vstor_packet,
 			       sizeof(struct vstor_packet),
 			       (unsigned long)request,
 			       VM_PKT_DATA_INBAND,
 			       VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
 
-	if (ret != 0) {
-		DPRINT_ERR(STORVSC,
-			   "unable to send QUERY_PROPERTIES_OPERATION");
+	if (ret != 0)
 		goto cleanup;
-	}
 
-	wait_event_timeout(request->wait_event, request->wait_condition,
-			msecs_to_jiffies(1000));
-	if (request->wait_condition == 0) {
+	t = wait_for_completion_timeout(&request->wait_event, HZ);
+	if (t == 0) {
 		ret = -ETIMEDOUT;
 		goto cleanup;
 	}
 
 	/* TODO: Check returned version */
 	if (vstor_packet->operation != VSTOR_OPERATION_COMPLETE_IO ||
-	    vstor_packet->status != 0) {
-		DPRINT_ERR(STORVSC, "QUERY_PROPERTIES_OPERATION failed "
-			   "(op %d status 0x%x)",
-			   vstor_packet->operation, vstor_packet->status);
+	    vstor_packet->status != 0)
 		goto cleanup;
-	}
 
 	stor_device->path_id = vstor_packet->storage_channel_properties.path_id;
 	stor_device->target_id
 		= vstor_packet->storage_channel_properties.target_id;
 
-	DPRINT_DBG(STORVSC, "channel flag 0x%x, max xfer len 0x%x",
-		   vstor_packet->storage_channel_properties.flags,
-		   vstor_packet->storage_channel_properties.max_transfer_bytes);
-
 	DPRINT_INFO(STORVSC, "END_INITIALIZATION_OPERATION...");
 
 	memset(vstor_packet, 0, sizeof(struct vstor_packet));
 	vstor_packet->operation = VSTOR_OPERATION_END_INITIALIZATION;
 	vstor_packet->flags = REQUEST_COMPLETION_FLAG;
 
-	request->wait_condition = 0;
 	ret = vmbus_sendpacket(device->channel, vstor_packet,
 			       sizeof(struct vstor_packet),
 			       (unsigned long)request,
 			       VM_PKT_DATA_INBAND,
 			       VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
 
-	if (ret != 0) {
-		DPRINT_ERR(STORVSC,
-			   "unable to send END_INITIALIZATION_OPERATION");
+	if (ret != 0)
 		goto cleanup;
-	}
 
-	wait_event_timeout(request->wait_event, request->wait_condition,
-			msecs_to_jiffies(1000));
-	if (request->wait_condition == 0) {
+	t = wait_for_completion_timeout(&request->wait_event, HZ);
+	if (t == 0) {
 		ret = -ETIMEDOUT;
 		goto cleanup;
 	}
 
 	if (vstor_packet->operation != VSTOR_OPERATION_COMPLETE_IO ||
-	    vstor_packet->status != 0) {
-		DPRINT_ERR(STORVSC, "END_INITIALIZATION_OPERATION failed "
-			   "(op %d status 0x%x)",
-			   vstor_packet->operation, vstor_packet->status);
+	    vstor_packet->status != 0)
 		goto cleanup;
-	}
 
 	DPRINT_INFO(STORVSC, "**** storage channel up and running!! ****");
 
@@ -362,78 +239,70 @@
 	return ret;
 }
 
-static void stor_vsc_on_io_completion(struct hv_device *device,
+static void storvsc_on_io_completion(struct hv_device *device,
 				  struct vstor_packet *vstor_packet,
-				  struct storvsc_request_extension *request_ext)
+				  struct hv_storvsc_request *request)
 {
-	struct hv_storvsc_request *request;
 	struct storvsc_device *stor_device;
+	struct vstor_packet *stor_pkt;
 
 	stor_device = must_get_stor_device(device);
-	if (!stor_device) {
-		DPRINT_ERR(STORVSC, "unable to get stor device..."
-			   "device being destroyed?");
+	if (!stor_device)
 		return;
-	}
 
-	DPRINT_DBG(STORVSC, "IO_COMPLETE_OPERATION - request extension %p "
-		   "completed bytes xfer %u", request_ext,
-		   vstor_packet->vm_srb.data_transfer_length);
-
-	/* ASSERT(request_ext != NULL); */
-	/* ASSERT(request_ext->request != NULL); */
-
-	request = request_ext->request;
+	stor_pkt = &request->vstor_packet;
 
-	/* ASSERT(request->OnIOCompletion != NULL); */
 
 	/* Copy over the status...etc */
-	request->status = vstor_packet->vm_srb.scsi_status;
+	stor_pkt->vm_srb.scsi_status = vstor_packet->vm_srb.scsi_status;
+	stor_pkt->vm_srb.srb_status = vstor_packet->vm_srb.srb_status;
+	stor_pkt->vm_srb.sense_info_length =
+	vstor_packet->vm_srb.sense_info_length;
 
-	if (request->status != 0 || vstor_packet->vm_srb.srb_status != 1) {
+	if (vstor_packet->vm_srb.scsi_status != 0 ||
+		vstor_packet->vm_srb.srb_status != 1){
 		DPRINT_WARN(STORVSC,
 			    "cmd 0x%x scsi status 0x%x srb status 0x%x\n",
-			    request->cdb[0], vstor_packet->vm_srb.scsi_status,
+			    stor_pkt->vm_srb.cdb[0],
+			    vstor_packet->vm_srb.scsi_status,
 			    vstor_packet->vm_srb.srb_status);
 	}
 
-	if ((request->status & 0xFF) == 0x02) {
+	if ((vstor_packet->vm_srb.scsi_status & 0xFF) == 0x02) {
 		/* CHECK_CONDITION */
 		if (vstor_packet->vm_srb.srb_status & 0x80) {
 			/* autosense data available */
 			DPRINT_WARN(STORVSC, "storvsc pkt %p autosense data "
-				    "valid - len %d\n", request_ext,
+				    "valid - len %d\n", request,
 				    vstor_packet->vm_srb.sense_info_length);
 
-			/* ASSERT(vstor_packet->vm_srb.sense_info_length <= */
-			/* 	request->SenseBufferSize); */
 			memcpy(request->sense_buffer,
 			       vstor_packet->vm_srb.sense_data,
 			       vstor_packet->vm_srb.sense_info_length);
 
-			request->sense_buffer_size =
-					vstor_packet->vm_srb.sense_info_length;
 		}
 	}
 
-	/* TODO: */
-	request->bytes_xfer = vstor_packet->vm_srb.data_transfer_length;
+	stor_pkt->vm_srb.data_transfer_length =
+	vstor_packet->vm_srb.data_transfer_length;
 
 	request->on_io_completion(request);
 
-	atomic_dec(&stor_device->num_outstanding_req);
+	if (atomic_dec_and_test(&stor_device->num_outstanding_req) &&
+		stor_device->drain_notify)
+		wake_up(&stor_device->waiting_to_drain);
+
 
 	put_stor_device(device);
 }
 
-static void stor_vsc_on_receive(struct hv_device *device,
+static void storvsc_on_receive(struct hv_device *device,
 			     struct vstor_packet *vstor_packet,
-			     struct storvsc_request_extension *request_ext)
+			     struct hv_storvsc_request *request)
 {
 	switch (vstor_packet->operation) {
 	case VSTOR_OPERATION_COMPLETE_IO:
-		DPRINT_DBG(STORVSC, "IO_COMPLETE_OPERATION");
-		stor_vsc_on_io_completion(device, vstor_packet, request_ext);
+		storvsc_on_io_completion(device, vstor_packet, request);
 		break;
 	case VSTOR_OPERATION_REMOVE_DEVICE:
 		DPRINT_INFO(STORVSC, "REMOVE_DEVICE_OPERATION");
@@ -447,60 +316,42 @@
 	}
 }
 
-static void stor_vsc_on_channel_callback(void *context)
+static void storvsc_on_channel_callback(void *context)
 {
 	struct hv_device *device = (struct hv_device *)context;
 	struct storvsc_device *stor_device;
 	u32 bytes_recvd;
 	u64 request_id;
 	unsigned char packet[ALIGN(sizeof(struct vstor_packet), 8)];
-	struct storvsc_request_extension *request;
+	struct hv_storvsc_request *request;
 	int ret;
 
-	/* ASSERT(device); */
 
 	stor_device = must_get_stor_device(device);
-	if (!stor_device) {
-		DPRINT_ERR(STORVSC, "unable to get stor device..."
-			   "device being destroyed?");
+	if (!stor_device)
 		return;
-	}
 
 	do {
 		ret = vmbus_recvpacket(device->channel, packet,
 				       ALIGN(sizeof(struct vstor_packet), 8),
 				       &bytes_recvd, &request_id);
 		if (ret == 0 && bytes_recvd > 0) {
-			DPRINT_DBG(STORVSC, "receive %d bytes - tid %llx",
-				   bytes_recvd, request_id);
 
-			/* ASSERT(bytes_recvd ==
-					sizeof(struct vstor_packet)); */
-
-			request = (struct storvsc_request_extension *)
+			request = (struct hv_storvsc_request *)
 					(unsigned long)request_id;
-			/* ASSERT(request);c */
 
-			/* if (vstor_packet.Flags & SYNTHETIC_FLAG) */
 			if ((request == &stor_device->init_request) ||
 			    (request == &stor_device->reset_request)) {
-				/* DPRINT_INFO(STORVSC,
-				 *             "reset completion - operation "
-				 *             "%u status %u",
-				 *             vstor_packet.Operation,
-				 *             vstor_packet.Status); */
 
 				memcpy(&request->vstor_packet, packet,
 				       sizeof(struct vstor_packet));
-				request->wait_condition = 1;
-				wake_up(&request->wait_event);
+				complete(&request->wait_event);
 			} else {
-				stor_vsc_on_receive(device,
+				storvsc_on_receive(device,
 						(struct vstor_packet *)packet,
 						request);
 			}
 		} else {
-			/* DPRINT_DBG(STORVSC, "nothing else to read..."); */
 			break;
 		}
 	} while (1);
@@ -509,45 +360,33 @@
 	return;
 }
 
-static int stor_vsc_connect_to_vsp(struct hv_device *device)
+static int storvsc_connect_to_vsp(struct hv_device *device, u32 ring_size)
 {
 	struct vmstorage_channel_properties props;
-	struct storvsc_driver_object *stor_driver;
 	int ret;
 
-	stor_driver = (struct storvsc_driver_object *)device->drv;
 	memset(&props, 0, sizeof(struct vmstorage_channel_properties));
 
 	/* Open the channel */
 	ret = vmbus_open(device->channel,
-			 stor_driver->ring_buffer_size,
-			 stor_driver->ring_buffer_size,
+			 ring_size,
+			 ring_size,
 			 (void *)&props,
 			 sizeof(struct vmstorage_channel_properties),
-			 stor_vsc_on_channel_callback, device);
-
-	DPRINT_DBG(STORVSC, "storage props: path id %d, tgt id %d, max xfer %d",
-		   props.path_id, props.target_id, props.max_transfer_bytes);
+			 storvsc_on_channel_callback, device);
 
-	if (ret != 0) {
-		DPRINT_ERR(STORVSC, "unable to open channel: %d", ret);
+	if (ret != 0)
 		return -1;
-	}
 
-	ret = stor_vsc_channel_init(device);
+	ret = storvsc_channel_init(device);
 
 	return ret;
 }
 
-/*
- * stor_vsc_on_device_add - Callback when the device belonging to this driver
- * is added
- */
-static int stor_vsc_on_device_add(struct hv_device *device,
+int storvsc_dev_add(struct hv_device *device,
 					void *additional_info)
 {
 	struct storvsc_device *stor_device;
-	/* struct vmstorage_channel_properties *props; */
 	struct storvsc_device_info *device_info;
 	int ret = 0;
 
@@ -559,8 +398,6 @@
 	}
 
 	/* Save the channel properties to our storvsc channel */
-	/* props = (struct vmstorage_channel_properties *)
-	 *		channel->offerMsg.Offer.u.Standard.UserDefined; */
 
 	/* FIXME: */
 	/*
@@ -569,30 +406,18 @@
 	 * scsi channel prior to the bus scan
 	 */
 
-	/* storChannel->PortNumber = 0;
-	storChannel->PathId = props->PathId;
-	storChannel->TargetId = props->TargetId; */
-
 	stor_device->port_number = device_info->port_number;
 	/* Send it back up */
-	ret = stor_vsc_connect_to_vsp(device);
+	ret = storvsc_connect_to_vsp(device, device_info->ring_buffer_size);
 
-	/* device_info->PortNumber = stor_device->PortNumber; */
 	device_info->path_id = stor_device->path_id;
 	device_info->target_id = stor_device->target_id;
 
-	DPRINT_DBG(STORVSC, "assigned port %u, path %u target %u\n",
-		   stor_device->port_number, stor_device->path_id,
-		   stor_device->target_id);
-
 cleanup:
 	return ret;
 }
 
-/*
- * stor_vsc_on_device_remove - Callback when the our device is being removed
- */
-static int stor_vsc_on_device_remove(struct hv_device *device)
+int storvsc_dev_remove(struct hv_device *device)
 {
 	struct storvsc_device *stor_device;
 
@@ -606,19 +431,11 @@
 	 * only allow inbound traffic (responses) to proceed so that
 	 * outstanding requests can be completed.
 	 */
-	while (atomic_read(&stor_device->num_outstanding_req)) {
-		DPRINT_INFO(STORVSC, "waiting for %d requests to complete...",
-			    atomic_read(&stor_device->num_outstanding_req));
-		udelay(100);
-	}
 
-	DPRINT_INFO(STORVSC, "removing storage device (%p)...",
-		    device->ext);
+	storvsc_wait_to_drain(stor_device);
 
 	stor_device = final_release_stor_device(device);
 
-	DPRINT_INFO(STORVSC, "storage device (%p) safe to remove", stor_device);
-
 	/* Close the channel */
 	vmbus_close(device->channel);
 
@@ -626,148 +443,52 @@
 	return 0;
 }
 
-int stor_vsc_on_host_reset(struct hv_device *device)
-{
-	struct storvsc_device *stor_device;
-	struct storvsc_request_extension *request;
-	struct vstor_packet *vstor_packet;
-	int ret;
-
-	DPRINT_INFO(STORVSC, "resetting host adapter...");
-
-	stor_device = get_stor_device(device);
-	if (!stor_device) {
-		DPRINT_ERR(STORVSC, "unable to get stor device..."
-			   "device being destroyed?");
-		return -1;
-	}
-
-	request = &stor_device->reset_request;
-	vstor_packet = &request->vstor_packet;
-
-	init_waitqueue_head(&request->wait_event);
-
-	vstor_packet->operation = VSTOR_OPERATION_RESET_BUS;
-	vstor_packet->flags = REQUEST_COMPLETION_FLAG;
-	vstor_packet->vm_srb.path_id = stor_device->path_id;
-
-	request->wait_condition = 0;
-	ret = vmbus_sendpacket(device->channel, vstor_packet,
-			       sizeof(struct vstor_packet),
-			       (unsigned long)&stor_device->reset_request,
-			       VM_PKT_DATA_INBAND,
-			       VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
-	if (ret != 0) {
-		DPRINT_ERR(STORVSC, "Unable to send reset packet %p ret %d",
-			   vstor_packet, ret);
-		goto cleanup;
-	}
-
-	wait_event_timeout(request->wait_event, request->wait_condition,
-			msecs_to_jiffies(1000));
-	if (request->wait_condition == 0) {
-		ret = -ETIMEDOUT;
-		goto cleanup;
-	}
-
-	DPRINT_INFO(STORVSC, "host adapter reset completed");
-
-	/*
-	 * At this point, all outstanding requests in the adapter
-	 * should have been flushed out and return to us
-	 */
-
-cleanup:
-	put_stor_device(device);
-	return ret;
-}
-
-/*
- * stor_vsc_on_io_request - Callback to initiate an I/O request
- */
-static int stor_vsc_on_io_request(struct hv_device *device,
+int storvsc_do_io(struct hv_device *device,
 			      struct hv_storvsc_request *request)
 {
 	struct storvsc_device *stor_device;
-	struct storvsc_request_extension *request_extension;
 	struct vstor_packet *vstor_packet;
 	int ret = 0;
 
-	request_extension =
-		(struct storvsc_request_extension *)request->extension;
-	vstor_packet = &request_extension->vstor_packet;
+	vstor_packet = &request->vstor_packet;
 	stor_device = get_stor_device(device);
 
-	DPRINT_DBG(STORVSC, "enter - Device %p, DeviceExt %p, Request %p, "
-		   "Extension %p", device, stor_device, request,
-		   request_extension);
-
-	DPRINT_DBG(STORVSC, "req %p len %d bus %d, target %d, lun %d cdblen %d",
-		   request, request->data_buffer.len, request->bus,
-		   request->target_id, request->lun_id, request->cdb_len);
-
-	if (!stor_device) {
-		DPRINT_ERR(STORVSC, "unable to get stor device..."
-			   "device being destroyed?");
+	if (!stor_device)
 		return -2;
-	}
 
-	/* print_hex_dump_bytes("", DUMP_PREFIX_NONE, request->Cdb,
-	 *			request->CdbLen); */
 
-	request_extension->request = request;
-	request_extension->device  = device;
+	request->device  = device;
 
-	memset(vstor_packet, 0 , sizeof(struct vstor_packet));
 
 	vstor_packet->flags |= REQUEST_COMPLETION_FLAG;
 
 	vstor_packet->vm_srb.length = sizeof(struct vmscsi_request);
 
-	vstor_packet->vm_srb.port_number = request->host;
-	vstor_packet->vm_srb.path_id = request->bus;
-	vstor_packet->vm_srb.target_id = request->target_id;
-	vstor_packet->vm_srb.lun = request->lun_id;
 
 	vstor_packet->vm_srb.sense_info_length = SENSE_BUFFER_SIZE;
 
-	/* Copy over the scsi command descriptor block */
-	vstor_packet->vm_srb.cdb_length = request->cdb_len;
-	memcpy(&vstor_packet->vm_srb.cdb, request->cdb, request->cdb_len);
 
-	vstor_packet->vm_srb.data_in = request->type;
-	vstor_packet->vm_srb.data_transfer_length = request->data_buffer.len;
+	vstor_packet->vm_srb.data_transfer_length =
+	request->data_buffer.len;
 
 	vstor_packet->operation = VSTOR_OPERATION_EXECUTE_SRB;
 
-	DPRINT_DBG(STORVSC, "srb - len %d port %d, path %d, target %d, "
-		   "lun %d senselen %d cdblen %d",
-		   vstor_packet->vm_srb.length,
-		   vstor_packet->vm_srb.port_number,
-		   vstor_packet->vm_srb.path_id,
-		   vstor_packet->vm_srb.target_id,
-		   vstor_packet->vm_srb.lun,
-		   vstor_packet->vm_srb.sense_info_length,
-		   vstor_packet->vm_srb.cdb_length);
-
-	if (request_extension->request->data_buffer.len) {
+	if (request->data_buffer.len) {
 		ret = vmbus_sendpacket_multipagebuffer(device->channel,
-				&request_extension->request->data_buffer,
+				&request->data_buffer,
 				vstor_packet,
 				sizeof(struct vstor_packet),
-				(unsigned long)request_extension);
+				(unsigned long)request);
 	} else {
 		ret = vmbus_sendpacket(device->channel, vstor_packet,
 				       sizeof(struct vstor_packet),
-				       (unsigned long)request_extension,
+				       (unsigned long)request,
 				       VM_PKT_DATA_INBAND,
 				       VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
 	}
 
-	if (ret != 0) {
-		DPRINT_DBG(STORVSC, "Unable to send packet %p ret %d",
-			   vstor_packet, ret);
-	}
+	if (ret != 0)
+		return ret;
 
 	atomic_inc(&stor_device->num_outstanding_req);
 
@@ -776,62 +497,68 @@
 }
 
 /*
- * stor_vsc_on_cleanup - Perform any cleanup when the driver is removed
+ * The channel properties uniquely specify how the device is to be
+ * presented to the guest. Map this information for use by the block
+ * driver. For Linux guests on Hyper-V, we emulate a scsi HBA in the guest
+ * (storvsc_drv) and so scsi devices in the guest  are handled by
+ * native upper level Linux drivers. Consequently, Hyper-V
+ * block driver, while being a generic block driver, presently does not
+ * deal with anything other than devices that would need to be presented
+ * to the guest as an IDE disk.
+ *
+ * This function maps the channel properties as embedded in the input
+ * parameter device_info onto information necessary to register the
+ * corresponding block device.
+ *
+ * Currently, there is no way to stop the emulation of the block device
+ * on the host side. And so, to prevent the native IDE drivers in Linux
+ * from taking over these devices (to be managedby Hyper-V block
+ * driver), we will take over if need be the major of the IDE controllers.
+ *
  */
-static void stor_vsc_on_cleanup(struct hv_driver *driver)
-{
-}
 
-/*
- * stor_vsc_initialize - Main entry point
- */
-int stor_vsc_initialize(struct hv_driver *driver)
+int storvsc_get_major_info(struct storvsc_device_info *device_info,
+			    struct storvsc_major_info *major_info)
 {
-	struct storvsc_driver_object *stor_driver;
-
-	stor_driver = (struct storvsc_driver_object *)driver;
-
-	DPRINT_DBG(STORVSC, "sizeof(STORVSC_REQUEST)=%zd "
-		   "sizeof(struct storvsc_request_extension)=%zd "
-		   "sizeof(struct vstor_packet)=%zd, "
-		   "sizeof(struct vmscsi_request)=%zd",
-		   sizeof(struct hv_storvsc_request),
-		   sizeof(struct storvsc_request_extension),
-		   sizeof(struct vstor_packet),
-		   sizeof(struct vmscsi_request));
-
-	/* Make sure we are at least 2 pages since 1 page is used for control */
-	/* ASSERT(stor_driver->RingBufferSize >= (PAGE_SIZE << 1)); */
-
-	driver->name = g_driver_name;
-	memcpy(&driver->dev_type, &gStorVscDeviceType,
-	       sizeof(struct hv_guid));
-
-	stor_driver->request_ext_size =
-			sizeof(struct storvsc_request_extension);
+	static bool ide0_registered;
+	static bool ide1_registered;
 
 	/*
-	 * Divide the ring buffer data size (which is 1 page less
-	 * than the ring buffer size since that page is reserved for
-	 * the ring buffer indices) by the max request size (which is
-	 * vmbus_channel_packet_multipage_buffer + struct vstor_packet + u64)
+	 * For now we only support IDE disks.
 	 */
-	stor_driver->max_outstanding_req_per_channel =
-		((stor_driver->ring_buffer_size - PAGE_SIZE) /
-		  ALIGN(MAX_MULTIPAGE_BUFFER_PACKET +
-			   sizeof(struct vstor_packet) + sizeof(u64),
-			   sizeof(u64)));
+	major_info->devname = "ide";
+	major_info->diskname = "hd";
 
-	DPRINT_INFO(STORVSC, "max io %u, currently %u\n",
-		    stor_driver->max_outstanding_req_per_channel,
-		    STORVSC_MAX_IO_REQUESTS);
+	if (device_info->path_id) {
+		major_info->major = 22;
+		if (!ide1_registered) {
+			major_info->do_register = true;
+			ide1_registered = true;
+		} else
+			major_info->do_register = false;
 
-	/* Setup the dispatch table */
-	stor_driver->base.dev_add	= stor_vsc_on_device_add;
-	stor_driver->base.dev_rm	= stor_vsc_on_device_remove;
-	stor_driver->base.cleanup	= stor_vsc_on_cleanup;
+		if (device_info->target_id)
+			major_info->index = 3;
+		else
+			major_info->index = 2;
 
-	stor_driver->on_io_request	= stor_vsc_on_io_request;
+		return 0;
+	} else {
+		major_info->major = 3;
+		if (!ide0_registered) {
+			major_info->do_register = true;
+			ide0_registered = true;
+		} else
+			major_info->do_register = false;
 
-	return 0;
+		if (device_info->target_id)
+			major_info->index = 1;
+		else
+			major_info->index = 0;
+
+		return 0;
+	}
+
+	return -ENODEV;
 }
+
diff -druN linux-2.6.39-libre/drivers/staging/hv/storvsc_drv.c linux-3.0-rc7-libre/drivers/staging/hv/storvsc_drv.c
--- linux-2.6.39-libre/drivers/staging/hv/storvsc_drv.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/hv/storvsc_drv.c	2011-07-11 19:51:52.000000000 -0400
@@ -17,6 +17,7 @@
  * Authors:
  *   Haiyang Zhang <haiyangz@microsoft.com>
  *   Hank Janssen  <hjanssen@microsoft.com>
+ *   K. Y. Srinivasan <kys@microsoft.com>
  */
 #include <linux/init.h>
 #include <linux/slab.h>
@@ -31,18 +32,27 @@
 #include <scsi/scsi_eh.h>
 #include <scsi/scsi_devinfo.h>
 #include <scsi/scsi_dbg.h>
-#include "hv_api.h"
-#include "logging.h"
-#include "version_info.h"
-#include "vmbus.h"
-#include "storvsc_api.h"
 
+#include "hyperv.h"
+#include "hyperv_storage.h"
+
+static int storvsc_ringbuffer_size = STORVSC_RING_BUFFER_SIZE;
 
-struct host_device_context {
-	/* must be 1st field
-	 * FIXME this is a bug */
-	/* point back to our device context */
-	struct hv_device *device_ctx;
+module_param(storvsc_ringbuffer_size, int, S_IRUGO);
+MODULE_PARM_DESC(storvsc_ringbuffer_size, "Ring buffer size (bytes)");
+
+static const char *driver_name = "storvsc";
+
+/* {ba6163d9-04a1-4d29-b605-72e2ffb1dc7f} */
+static const struct hv_guid gStorVscDeviceType = {
+	.data = {
+		0xd9, 0x63, 0x61, 0xba, 0xa1, 0x04, 0x29, 0x4d,
+		0xb6, 0x05, 0x72, 0xe2, 0xff, 0xb1, 0xdc, 0x7f
+	}
+};
+
+struct hv_host_device {
+	struct hv_device *dev;
 	struct kmem_cache *request_pool;
 	unsigned int port;
 	unsigned char path;
@@ -57,331 +67,57 @@
 	struct scatterlist *bounce_sgl;
 
 	struct hv_storvsc_request request;
-	/* !!!DO NOT ADD ANYTHING BELOW HERE!!! */
-	/* The extension buffer falls right here and is pointed to by
-	 * request.Extension;
-	 * Which sounds like a very bad design... */
 };
 
 
-/* Static decl */
-static int storvsc_probe(struct device *dev);
-static int storvsc_queuecommand(struct Scsi_Host *shost, struct scsi_cmnd *scmnd);
-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 int storvsc_remove(struct device *dev);
-
-static struct scatterlist *create_bounce_buffer(struct scatterlist *sgl,
-						unsigned int sg_count,
-						unsigned int len);
-static void destroy_bounce_buffer(struct scatterlist *sgl,
-				  unsigned int sg_count);
-static int do_bounce_buffer(struct scatterlist *sgl, unsigned int sg_count);
-static unsigned int copy_from_bounce_buffer(struct scatterlist *orig_sgl,
-					    struct scatterlist *bounce_sgl,
-					    unsigned int orig_sgl_count);
-static unsigned int copy_to_bounce_buffer(struct scatterlist *orig_sgl,
-					  struct scatterlist *bounce_sgl,
-					  unsigned int orig_sgl_count);
-
-static int storvsc_get_chs(struct scsi_device *sdev, struct block_device *bdev,
-			   sector_t capacity, int *info);
-
-
-static int storvsc_ringbuffer_size = STORVSC_RING_BUFFER_SIZE;
-module_param(storvsc_ringbuffer_size, int, S_IRUGO);
-MODULE_PARM_DESC(storvsc_ringbuffer_size, "Ring buffer size (bytes)");
-
-/* The one and only one */
-static struct storvsc_driver_object g_storvsc_drv;
-
-/* Scsi driver */
-static struct scsi_host_template scsi_driver = {
-	.module	=		THIS_MODULE,
-	.name =			"storvsc_host_t",
-	.bios_param =		storvsc_get_chs,
-	.queuecommand =		storvsc_queuecommand,
-	.eh_host_reset_handler =	storvsc_host_reset_handler,
-	.slave_alloc =		storvsc_device_alloc,
-	.slave_configure =	storvsc_device_configure,
-	.cmd_per_lun =		1,
-	/* 64 max_queue * 1 target */
-	.can_queue =		STORVSC_MAX_IO_REQUESTS*STORVSC_MAX_TARGETS,
-	.this_id =		-1,
-	/* no use setting to 0 since ll_blk_rw reset it to 1 */
-	/* currently 32 */
-	.sg_tablesize =		MAX_MULTIPAGE_BUFFER_COUNT,
+static int storvsc_device_alloc(struct scsi_device *sdevice)
+{
 	/*
-	 * ENABLE_CLUSTERING allows mutiple physically contig bio_vecs to merge
-	 * into 1 sg element. If set, we must limit the max_segment_size to
-	 * PAGE_SIZE, otherwise we may get 1 sg element that represents
-	 * multiple
+	 * This enables luns to be located sparsely. Otherwise, we may not
+	 * discovered them.
 	 */
-	/* physically contig pfns (ie sg[x].length > PAGE_SIZE). */
-	.use_clustering =	ENABLE_CLUSTERING,
-	/* Make sure we dont get a sg segment crosses a page boundary */
-	.dma_boundary =		PAGE_SIZE-1,
-};
-
-
-/*
- * storvsc_drv_init - StorVsc driver initialization.
- */
-static int storvsc_drv_init(int (*drv_init)(struct hv_driver *drv))
-{
-	int ret;
-	struct storvsc_driver_object *storvsc_drv_obj = &g_storvsc_drv;
-	struct hv_driver *drv = &g_storvsc_drv.base;
-
-	storvsc_drv_obj->ring_buffer_size = storvsc_ringbuffer_size;
-
-	/* Callback to client driver to complete the initialization */
-	drv_init(&storvsc_drv_obj->base);
-
-	drv->priv = storvsc_drv_obj;
-
-	DPRINT_INFO(STORVSC_DRV,
-		    "request extension size %u, max outstanding reqs %u",
-		    storvsc_drv_obj->request_ext_size,
-		    storvsc_drv_obj->max_outstanding_req_per_channel);
-
-	if (storvsc_drv_obj->max_outstanding_req_per_channel <
-	    STORVSC_MAX_IO_REQUESTS) {
-		DPRINT_ERR(STORVSC_DRV,
-			   "The number of outstanding io requests (%d) "
-			   "is larger than that supported (%d) internally.",
-			   STORVSC_MAX_IO_REQUESTS,
-			   storvsc_drv_obj->max_outstanding_req_per_channel);
-		return -1;
-	}
-
-	drv->driver.name = storvsc_drv_obj->base.name;
-
-	drv->driver.probe = storvsc_probe;
-	drv->driver.remove = storvsc_remove;
-
-	/* The driver belongs to vmbus */
-	ret = vmbus_child_driver_register(&drv->driver);
-
-	return ret;
-}
-
-static int storvsc_drv_exit_cb(struct device *dev, void *data)
-{
-	struct device **curr = (struct device **)data;
-	*curr = dev;
-	return 1; /* stop iterating */
-}
-
-static void storvsc_drv_exit(void)
-{
-	struct storvsc_driver_object *storvsc_drv_obj = &g_storvsc_drv;
-	struct hv_driver *drv = &g_storvsc_drv.base;
-	struct device *current_dev = NULL;
-	int ret;
-
-	while (1) {
-		current_dev = NULL;
-
-		/* Get the device */
-		ret = driver_for_each_device(&drv->driver, NULL,
-					     (void *) &current_dev,
-					     storvsc_drv_exit_cb);
-
-		if (ret)
-			DPRINT_WARN(STORVSC_DRV,
-				    "driver_for_each_device returned %d", ret);
-
-		if (current_dev == NULL)
-			break;
-
-		/* Initiate removal from the top-down */
-		device_unregister(current_dev);
-	}
-
-	if (storvsc_drv_obj->base.cleanup)
-		storvsc_drv_obj->base.cleanup(&storvsc_drv_obj->base);
-
-	vmbus_child_driver_unregister(&drv->driver);
-	return;
+	sdevice->sdev_bflags |= BLIST_SPARSELUN | BLIST_LARGELUN;
+	return 0;
 }
 
-/*
- * storvsc_probe - Add a new device for this driver
- */
-static int storvsc_probe(struct device *device)
+static int storvsc_merge_bvec(struct request_queue *q,
+			      struct bvec_merge_data *bmd, struct bio_vec *bvec)
 {
-	int ret;
-	struct hv_driver *drv =
-				drv_to_hv_drv(device->driver);
-	struct storvsc_driver_object *storvsc_drv_obj = drv->priv;
-	struct hv_device *device_obj = device_to_hv_device(device);
-	struct Scsi_Host *host;
-	struct host_device_context *host_device_ctx;
-	struct storvsc_device_info device_info;
-
-	if (!storvsc_drv_obj->base.dev_add)
-		return -1;
-
-	host = scsi_host_alloc(&scsi_driver,
-			       sizeof(struct host_device_context));
-	if (!host) {
-		DPRINT_ERR(STORVSC_DRV, "unable to allocate scsi host object");
-		return -ENOMEM;
-	}
-
-	dev_set_drvdata(device, host);
-
-	host_device_ctx = (struct host_device_context *)host->hostdata;
-	memset(host_device_ctx, 0, sizeof(struct host_device_context));
-
-	host_device_ctx->port = host->host_no;
-	host_device_ctx->device_ctx = device_obj;
-
-	host_device_ctx->request_pool =
-				kmem_cache_create(dev_name(&device_obj->device),
-					sizeof(struct storvsc_cmd_request) +
-					storvsc_drv_obj->request_ext_size, 0,
-					SLAB_HWCACHE_ALIGN, NULL);
-
-	if (!host_device_ctx->request_pool) {
-		scsi_host_put(host);
-		return -ENOMEM;
-	}
-
-	device_info.port_number = host->host_no;
-	/* Call to the vsc driver to add the device */
-	ret = storvsc_drv_obj->base.dev_add(device_obj,
-						(void *)&device_info);
-	if (ret != 0) {
-		DPRINT_ERR(STORVSC_DRV, "unable to add scsi vsc device");
-		kmem_cache_destroy(host_device_ctx->request_pool);
-		scsi_host_put(host);
-		return -1;
-	}
-
-	/* host_device_ctx->port = device_info.PortNumber; */
-	host_device_ctx->path = device_info.path_id;
-	host_device_ctx->target = device_info.target_id;
-
-	/* max # of devices per target */
-	host->max_lun = STORVSC_MAX_LUNS_PER_TARGET;
-	/* max # of targets per channel */
-	host->max_id = STORVSC_MAX_TARGETS;
-	/* max # of channels */
-	host->max_channel = STORVSC_MAX_CHANNELS - 1;
-
-	/* Register the HBA and start the scsi bus scan */
-	ret = scsi_add_host(host, device);
-	if (ret != 0) {
-		DPRINT_ERR(STORVSC_DRV, "unable to add scsi host device");
-
-		storvsc_drv_obj->base.dev_rm(device_obj);
-
-		kmem_cache_destroy(host_device_ctx->request_pool);
-		scsi_host_put(host);
-		return -1;
-	}
-
-	scsi_scan_host(host);
-	return ret;
+	/* checking done by caller. */
+	return bvec->bv_len;
 }
 
-/*
- * storvsc_remove - Callback when our device is removed
- */
-static int storvsc_remove(struct device *device)
+static int storvsc_device_configure(struct scsi_device *sdevice)
 {
-	int ret;
-	struct hv_driver *drv =
-			drv_to_hv_drv(device->driver);
-	struct storvsc_driver_object *storvsc_drv_obj = drv->priv;
-	struct hv_device *device_obj = device_to_hv_device(device);
-	struct Scsi_Host *host = dev_get_drvdata(device);
-	struct host_device_context *host_device_ctx =
-			(struct host_device_context *)host->hostdata;
-
-
-	if (!storvsc_drv_obj->base.dev_rm)
-		return -1;
+	scsi_adjust_queue_depth(sdevice, MSG_SIMPLE_TAG,
+				STORVSC_MAX_IO_REQUESTS);
 
-	/*
-	 * Call to the vsc driver to let it know that the device is being
-	 * removed
-	 */
-	ret = storvsc_drv_obj->base.dev_rm(device_obj);
-	if (ret != 0) {
-		/* TODO: */
-		DPRINT_ERR(STORVSC, "unable to remove vsc device (ret %d)",
-			   ret);
-	}
+	DPRINT_INFO(STORVSC_DRV, "sdev (%p) - setting max segment size to %ld",
+		    sdevice, PAGE_SIZE);
+	blk_queue_max_segment_size(sdevice->request_queue, PAGE_SIZE);
 
-	if (host_device_ctx->request_pool) {
-		kmem_cache_destroy(host_device_ctx->request_pool);
-		host_device_ctx->request_pool = NULL;
-	}
+	DPRINT_INFO(STORVSC_DRV, "sdev (%p) - adding merge bio vec routine",
+		    sdevice);
+	blk_queue_merge_bvec(sdevice->request_queue, storvsc_merge_bvec);
 
-	DPRINT_INFO(STORVSC, "removing host adapter (%p)...", host);
-	scsi_remove_host(host);
+	blk_queue_bounce_limit(sdevice->request_queue, BLK_BOUNCE_ANY);
 
-	DPRINT_INFO(STORVSC, "releasing host adapter (%p)...", host);
-	scsi_host_put(host);
-	return ret;
+	return 0;
 }
 
-/*
- * storvsc_commmand_completion - Command completion processing
- */
-static void storvsc_commmand_completion(struct hv_storvsc_request *request)
+static void destroy_bounce_buffer(struct scatterlist *sgl,
+				  unsigned int sg_count)
 {
-	struct storvsc_cmd_request *cmd_request =
-		(struct storvsc_cmd_request *)request->context;
-	struct scsi_cmnd *scmnd = cmd_request->cmd;
-	struct host_device_context *host_device_ctx =
-		(struct host_device_context *)scmnd->device->host->hostdata;
-	void (*scsi_done_fn)(struct scsi_cmnd *);
-	struct scsi_sense_hdr sense_hdr;
-
-	/* ASSERT(request == &cmd_request->request); */
-	/* ASSERT(scmnd); */
-	/* ASSERT((unsigned long)scmnd->host_scribble == */
-	/*        (unsigned long)cmd_request); */
-	/* ASSERT(scmnd->scsi_done); */
-
-	if (cmd_request->bounce_sgl_count) {
-		/* using bounce buffer */
-		/* printk("copy_from_bounce_buffer\n"); */
-
-		/* FIXME: We can optimize on writes by just skipping this */
-		copy_from_bounce_buffer(scsi_sglist(scmnd),
-					cmd_request->bounce_sgl,
-					scsi_sg_count(scmnd));
-		destroy_bounce_buffer(cmd_request->bounce_sgl,
-				      cmd_request->bounce_sgl_count);
-	}
-
-	scmnd->result = request->status;
+	int i;
+	struct page *page_buf;
 
-	if (scmnd->result) {
-		if (scsi_normalize_sense(scmnd->sense_buffer,
-				request->sense_buffer_size, &sense_hdr))
-			scsi_print_sense_hdr("storvsc", &sense_hdr);
+	for (i = 0; i < sg_count; i++) {
+		page_buf = sg_page((&sgl[i]));
+		if (page_buf != NULL)
+			__free_page(page_buf);
 	}
 
-	/* ASSERT(request->BytesXfer <= request->data_buffer.Length); */
-	scsi_set_resid(scmnd,
-		request->data_buffer.len - request->bytes_xfer);
-
-	scsi_done_fn = scmnd->scsi_done;
-
-	scmnd->host_scribble = NULL;
-	scmnd->scsi_done = NULL;
-
-	/* !!DO NOT MODIFY the scmnd after this call */
-	scsi_done_fn(scmnd);
-
-	kmem_cache_free(host_device_ctx->request_pool, cmd_request);
+	kfree(sgl);
 }
 
 static int do_bounce_buffer(struct scatterlist *sgl, unsigned int sg_count)
@@ -440,21 +176,72 @@
 	return NULL;
 }
 
-static void destroy_bounce_buffer(struct scatterlist *sgl,
-				  unsigned int sg_count)
+
+/* Assume the original sgl has enough room */
+static unsigned int copy_from_bounce_buffer(struct scatterlist *orig_sgl,
+					    struct scatterlist *bounce_sgl,
+					    unsigned int orig_sgl_count)
 {
 	int i;
-	struct page *page_buf;
+	int j = 0;
+	unsigned long src, dest;
+	unsigned int srclen, destlen, copylen;
+	unsigned int total_copied = 0;
+	unsigned long bounce_addr = 0;
+	unsigned long dest_addr = 0;
+	unsigned long flags;
 
-	for (i = 0; i < sg_count; i++) {
-		page_buf = sg_page((&sgl[i]));
-		if (page_buf != NULL)
-			__free_page(page_buf);
+	local_irq_save(flags);
+
+	for (i = 0; i < orig_sgl_count; i++) {
+		dest_addr = (unsigned long)kmap_atomic(sg_page((&orig_sgl[i])),
+					KM_IRQ0) + orig_sgl[i].offset;
+		dest = dest_addr;
+		destlen = orig_sgl[i].length;
+
+		if (bounce_addr == 0)
+			bounce_addr =
+			(unsigned long)kmap_atomic(sg_page((&bounce_sgl[j])),
+							KM_IRQ0);
+
+		while (destlen) {
+			src = bounce_addr + bounce_sgl[j].offset;
+			srclen = bounce_sgl[j].length - bounce_sgl[j].offset;
+
+			copylen = min(srclen, destlen);
+			memcpy((void *)dest, (void *)src, copylen);
+
+			total_copied += copylen;
+			bounce_sgl[j].offset += copylen;
+			destlen -= copylen;
+			dest += copylen;
+
+			if (bounce_sgl[j].offset == bounce_sgl[j].length) {
+				/* full */
+				kunmap_atomic((void *)bounce_addr, KM_IRQ0);
+				j++;
+
+				/* if we need to use another bounce buffer */
+				if (destlen || i != orig_sgl_count - 1)
+					bounce_addr =
+					(unsigned long)kmap_atomic(
+					sg_page((&bounce_sgl[j])), KM_IRQ0);
+			} else if (destlen == 0 && i == orig_sgl_count - 1) {
+				/* unmap the last bounce that is < PAGE_SIZE */
+				kunmap_atomic((void *)bounce_addr, KM_IRQ0);
+			}
+		}
+
+		kunmap_atomic((void *)(dest_addr - orig_sgl[i].offset),
+			      KM_IRQ0);
 	}
 
-	kfree(sgl);
+	local_irq_restore(flags);
+
+	return total_copied;
 }
 
+
 /* Assume the bounce_sgl has enough room ie using the create_bounce_buffer() */
 static unsigned int copy_to_bounce_buffer(struct scatterlist *orig_sgl,
 					  struct scatterlist *bounce_sgl,
@@ -477,10 +264,10 @@
 		src = src_addr;
 		srclen = orig_sgl[i].length;
 
-		/* ASSERT(orig_sgl[i].offset + orig_sgl[i].length <= PAGE_SIZE); */
-
 		if (bounce_addr == 0)
-			bounce_addr = (unsigned long)kmap_atomic(sg_page((&bounce_sgl[j])), KM_IRQ0);
+			bounce_addr =
+			(unsigned long)kmap_atomic(sg_page((&bounce_sgl[j])),
+						KM_IRQ0);
 
 		while (srclen) {
 			/* assume bounce offset always == 0 */
@@ -502,7 +289,10 @@
 
 				/* if we need to use another bounce buffer */
 				if (srclen || i != orig_sgl_count - 1)
-					bounce_addr = (unsigned long)kmap_atomic(sg_page((&bounce_sgl[j])), KM_IRQ0);
+					bounce_addr =
+					(unsigned long)kmap_atomic(
+					sg_page((&bounce_sgl[j])), KM_IRQ0);
+
 			} else if (srclen == 0 && i == orig_sgl_count - 1) {
 				/* unmap the last bounce that is < PAGE_SIZE */
 				kunmap_atomic((void *)bounce_addr, KM_IRQ0);
@@ -517,67 +307,185 @@
 	return total_copied;
 }
 
-/* Assume the original sgl has enough room */
-static unsigned int copy_from_bounce_buffer(struct scatterlist *orig_sgl,
-					    struct scatterlist *bounce_sgl,
-					    unsigned int orig_sgl_count)
+
+/*
+ * storvsc_remove - Callback when our device is removed
+ */
+static int storvsc_remove(struct hv_device *dev)
 {
-	int i;
-	int j = 0;
-	unsigned long src, dest;
-	unsigned int srclen, destlen, copylen;
-	unsigned int total_copied = 0;
-	unsigned long bounce_addr = 0;
-	unsigned long dest_addr = 0;
-	unsigned long flags;
+	struct Scsi_Host *host = dev_get_drvdata(&dev->device);
+	struct hv_host_device *host_dev =
+			(struct hv_host_device *)host->hostdata;
 
-	local_irq_save(flags);
+	/*
+	 * Call to the vsc driver to let it know that the device is being
+	 * removed
+	 */
+	storvsc_dev_remove(dev);
 
-	for (i = 0; i < orig_sgl_count; i++) {
-		dest_addr = (unsigned long)kmap_atomic(sg_page((&orig_sgl[i])),
-					KM_IRQ0) + orig_sgl[i].offset;
-		dest = dest_addr;
-		destlen = orig_sgl[i].length;
-		/* ASSERT(orig_sgl[i].offset + orig_sgl[i].length <= PAGE_SIZE); */
+	if (host_dev->request_pool) {
+		kmem_cache_destroy(host_dev->request_pool);
+		host_dev->request_pool = NULL;
+	}
 
-		if (bounce_addr == 0)
-			bounce_addr = (unsigned long)kmap_atomic(sg_page((&bounce_sgl[j])), KM_IRQ0);
+	DPRINT_INFO(STORVSC, "removing host adapter (%p)...", host);
+	scsi_remove_host(host);
 
-		while (destlen) {
-			src = bounce_addr + bounce_sgl[j].offset;
-			srclen = bounce_sgl[j].length - bounce_sgl[j].offset;
+	DPRINT_INFO(STORVSC, "releasing host adapter (%p)...", host);
+	scsi_host_put(host);
+	return 0;
+}
 
-			copylen = min(srclen, destlen);
-			memcpy((void *)dest, (void *)src, copylen);
 
-			total_copied += copylen;
-			bounce_sgl[j].offset += copylen;
-			destlen -= copylen;
-			dest += copylen;
+static int storvsc_get_chs(struct scsi_device *sdev, struct block_device * bdev,
+			   sector_t capacity, int *info)
+{
+	sector_t nsect = capacity;
+	sector_t cylinders = nsect;
+	int heads, sectors_pt;
 
-			if (bounce_sgl[j].offset == bounce_sgl[j].length) {
-				/* full */
-				kunmap_atomic((void *)bounce_addr, KM_IRQ0);
-				j++;
+	/*
+	 * We are making up these values; let us keep it simple.
+	 */
+	heads = 0xff;
+	sectors_pt = 0x3f;      /* Sectors per track */
+	sector_div(cylinders, heads * sectors_pt);
+	if ((sector_t)(cylinders + 1) * heads * sectors_pt < nsect)
+		cylinders = 0xffff;
 
-				/* if we need to use another bounce buffer */
-				if (destlen || i != orig_sgl_count - 1)
-					bounce_addr = (unsigned long)kmap_atomic(sg_page((&bounce_sgl[j])), KM_IRQ0);
-			} else if (destlen == 0 && i == orig_sgl_count - 1) {
-				/* unmap the last bounce that is < PAGE_SIZE */
-				kunmap_atomic((void *)bounce_addr, KM_IRQ0);
-			}
-		}
+	info[0] = heads;
+	info[1] = sectors_pt;
+	info[2] = (int)cylinders;
 
-		kunmap_atomic((void *)(dest_addr - orig_sgl[i].offset),
-			      KM_IRQ0);
+	DPRINT_INFO(STORVSC_DRV, "CHS (%d, %d, %d)", (int)cylinders, heads,
+			sectors_pt);
+
+	return 0;
+}
+
+static int storvsc_host_reset(struct hv_device *device)
+{
+	struct storvsc_device *stor_device;
+	struct hv_storvsc_request *request;
+	struct vstor_packet *vstor_packet;
+	int ret, t;
+
+	DPRINT_INFO(STORVSC, "resetting host adapter...");
+
+	stor_device = get_stor_device(device);
+	if (!stor_device)
+		return -1;
+
+	request = &stor_device->reset_request;
+	vstor_packet = &request->vstor_packet;
+
+	init_completion(&request->wait_event);
+
+	vstor_packet->operation = VSTOR_OPERATION_RESET_BUS;
+	vstor_packet->flags = REQUEST_COMPLETION_FLAG;
+	vstor_packet->vm_srb.path_id = stor_device->path_id;
+
+	ret = vmbus_sendpacket(device->channel, vstor_packet,
+			       sizeof(struct vstor_packet),
+			       (unsigned long)&stor_device->reset_request,
+			       VM_PKT_DATA_INBAND,
+			       VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
+	if (ret != 0)
+		goto cleanup;
+
+	t = wait_for_completion_timeout(&request->wait_event, HZ);
+	if (t == 0) {
+		ret = -ETIMEDOUT;
+		goto cleanup;
 	}
 
-	local_irq_restore(flags);
+	DPRINT_INFO(STORVSC, "host adapter reset completed");
 
-	return total_copied;
+	/*
+	 * At this point, all outstanding requests in the adapter
+	 * should have been flushed out and return to us
+	 */
+
+cleanup:
+	put_stor_device(device);
+	return ret;
+}
+
+
+/*
+ * storvsc_host_reset_handler - Reset the scsi HBA
+ */
+static int storvsc_host_reset_handler(struct scsi_cmnd *scmnd)
+{
+	int ret;
+	struct hv_host_device *host_dev =
+		(struct hv_host_device *)scmnd->device->host->hostdata;
+	struct hv_device *dev = host_dev->dev;
+
+	DPRINT_INFO(STORVSC_DRV, "sdev (%p) dev obj (%p) - host resetting...",
+		    scmnd->device, dev);
+
+	/* Invokes the vsc to reset the host/bus */
+	ret = storvsc_host_reset(dev);
+	if (ret != 0)
+		return ret;
+
+	DPRINT_INFO(STORVSC_DRV, "sdev (%p) dev obj (%p) - host reseted",
+		    scmnd->device, dev);
+
+	return ret;
 }
 
+
+/*
+ * storvsc_commmand_completion - Command completion processing
+ */
+static void storvsc_commmand_completion(struct hv_storvsc_request *request)
+{
+	struct storvsc_cmd_request *cmd_request =
+		(struct storvsc_cmd_request *)request->context;
+	struct scsi_cmnd *scmnd = cmd_request->cmd;
+	struct hv_host_device *host_dev =
+		(struct hv_host_device *)scmnd->device->host->hostdata;
+	void (*scsi_done_fn)(struct scsi_cmnd *);
+	struct scsi_sense_hdr sense_hdr;
+	struct vmscsi_request *vm_srb;
+
+	if (cmd_request->bounce_sgl_count) {
+
+		/* FIXME: We can optimize on writes by just skipping this */
+		copy_from_bounce_buffer(scsi_sglist(scmnd),
+					cmd_request->bounce_sgl,
+					scsi_sg_count(scmnd));
+		destroy_bounce_buffer(cmd_request->bounce_sgl,
+				      cmd_request->bounce_sgl_count);
+	}
+
+	vm_srb = &request->vstor_packet.vm_srb;
+	scmnd->result = vm_srb->scsi_status;
+
+	if (scmnd->result) {
+		if (scsi_normalize_sense(scmnd->sense_buffer,
+				SCSI_SENSE_BUFFERSIZE, &sense_hdr))
+			scsi_print_sense_hdr("storvsc", &sense_hdr);
+	}
+
+	scsi_set_resid(scmnd,
+		request->data_buffer.len -
+		vm_srb->data_transfer_length);
+
+	scsi_done_fn = scmnd->scsi_done;
+
+	scmnd->host_scribble = NULL;
+	scmnd->scsi_done = NULL;
+
+	/* !!DO NOT MODIFY the scmnd after this call */
+	scsi_done_fn(scmnd);
+
+	kmem_cache_free(host_dev->request_pool, cmd_request);
+}
+
+
 /*
  * storvsc_queuecommand - Initiate command processing
  */
@@ -585,28 +493,20 @@
 				void (*done)(struct scsi_cmnd *))
 {
 	int ret;
-	struct host_device_context *host_device_ctx =
-		(struct host_device_context *)scmnd->device->host->hostdata;
-	struct hv_device *device_ctx = host_device_ctx->device_ctx;
-	struct hv_driver *drv =
-		drv_to_hv_drv(device_ctx->device.driver);
-	struct storvsc_driver_object *storvsc_drv_obj = drv->priv;
+	struct hv_host_device *host_dev =
+		(struct hv_host_device *)scmnd->device->host->hostdata;
+	struct hv_device *dev = host_dev->dev;
 	struct hv_storvsc_request *request;
 	struct storvsc_cmd_request *cmd_request;
 	unsigned int request_size = 0;
 	int i;
 	struct scatterlist *sgl;
 	unsigned int sg_count = 0;
+	struct vmscsi_request *vm_srb;
 
-	DPRINT_DBG(STORVSC_DRV, "scmnd %p dir %d, use_sg %d buf %p len %d "
-		   "queue depth %d tagged %d", scmnd, scmnd->sc_data_direction,
-		   scsi_sg_count(scmnd), scsi_sglist(scmnd),
-		   scsi_bufflen(scmnd), scmnd->device->queue_depth,
-		   scmnd->device->tagged_supported);
 
 	/* If retrying, no need to prep the cmd */
 	if (scmnd->host_scribble) {
-		/* ASSERT(scmnd->scsi_done != NULL); */
 
 		cmd_request =
 			(struct storvsc_cmd_request *)scmnd->host_scribble;
@@ -616,18 +516,13 @@
 		goto retry_request;
 	}
 
-	/* ASSERT(scmnd->scsi_done == NULL); */
-	/* ASSERT(scmnd->host_scribble == NULL); */
-
 	scmnd->scsi_done = done;
 
 	request_size = sizeof(struct storvsc_cmd_request);
 
-	cmd_request = kmem_cache_alloc(host_device_ctx->request_pool,
+	cmd_request = kmem_cache_zalloc(host_dev->request_pool,
 				       GFP_ATOMIC);
 	if (!cmd_request) {
-		DPRINT_ERR(STORVSC_DRV, "scmnd (%p) - unable to allocate "
-			   "storvsc_cmd_request...marking queue busy", scmnd);
 		scmnd->scsi_done = NULL;
 		return SCSI_MLQUEUE_DEVICE_BUSY;
 	}
@@ -640,40 +535,35 @@
 	scmnd->host_scribble = (unsigned char *)cmd_request;
 
 	request = &cmd_request->request;
+	vm_srb = &request->vstor_packet.vm_srb;
 
-	request->extension =
-		(void *)((unsigned long)cmd_request + request_size);
-	DPRINT_DBG(STORVSC_DRV, "req %p size %d ext %d", request, request_size,
-		   storvsc_drv_obj->request_ext_size);
 
 	/* Build the SRB */
 	switch (scmnd->sc_data_direction) {
 	case DMA_TO_DEVICE:
-		request->type = WRITE_TYPE;
+		vm_srb->data_in = WRITE_TYPE;
 		break;
 	case DMA_FROM_DEVICE:
-		request->type = READ_TYPE;
+		vm_srb->data_in = READ_TYPE;
 		break;
 	default:
-		request->type = UNKNOWN_TYPE;
+		vm_srb->data_in = UNKNOWN_TYPE;
 		break;
 	}
 
 	request->on_io_completion = storvsc_commmand_completion;
 	request->context = cmd_request;/* scmnd; */
 
-	/* request->PortId = scmnd->device->channel; */
-	request->host = host_device_ctx->port;
-	request->bus = scmnd->device->channel;
-	request->target_id = scmnd->device->id;
-	request->lun_id = scmnd->device->lun;
+	vm_srb->port_number = host_dev->port;
+	vm_srb->path_id = scmnd->device->channel;
+	vm_srb->target_id = scmnd->device->id;
+	vm_srb->lun = scmnd->device->lun;
 
-	/* ASSERT(scmnd->cmd_len <= 16); */
-	request->cdb_len = scmnd->cmd_len;
-	request->cdb = scmnd->cmnd;
+	vm_srb->cdb_length = scmnd->cmd_len;
+
+	memcpy(vm_srb->cdb, scmnd->cmnd, vm_srb->cdb_length);
 
 	request->sense_buffer = scmnd->sense_buffer;
-	request->sense_buffer_size = SCSI_SENSE_BUFFERSIZE;
 
 
 	request->data_buffer.len = scsi_bufflen(scmnd);
@@ -683,20 +573,13 @@
 
 		/* check if we need to bounce the sgl */
 		if (do_bounce_buffer(sgl, scsi_sg_count(scmnd)) != -1) {
-			DPRINT_INFO(STORVSC_DRV,
-				    "need to bounce buffer for this scmnd %p",
-				    scmnd);
 			cmd_request->bounce_sgl =
 				create_bounce_buffer(sgl, scsi_sg_count(scmnd),
 						     scsi_bufflen(scmnd));
 			if (!cmd_request->bounce_sgl) {
-				DPRINT_ERR(STORVSC_DRV,
-					   "unable to create bounce buffer for "
-					   "this scmnd %p", scmnd);
-
 				scmnd->scsi_done = NULL;
 				scmnd->host_scribble = NULL;
-				kmem_cache_free(host_device_ctx->request_pool,
+				kmem_cache_free(host_dev->request_pool,
 						cmd_request);
 
 				return SCSI_MLQUEUE_HOST_BUSY;
@@ -719,14 +602,11 @@
 
 		request->data_buffer.offset = sgl[0].offset;
 
-		for (i = 0; i < sg_count; i++) {
-			DPRINT_DBG(STORVSC_DRV, "sgl[%d] len %d offset %d\n",
-				   i, sgl[i].length, sgl[i].offset);
+		for (i = 0; i < sg_count; i++)
 			request->data_buffer.pfn_array[i] =
 				page_to_pfn(sg_page((&sgl[i])));
-		}
+
 	} else if (scsi_sglist(scmnd)) {
-		/* ASSERT(scsi_bufflen(scmnd) <= PAGE_SIZE); */
 		request->data_buffer.offset =
 			virt_to_phys(scsi_sglist(scmnd)) & (PAGE_SIZE-1);
 		request->data_buffer.pfn_array[0] =
@@ -735,13 +615,10 @@
 
 retry_request:
 	/* Invokes the vsc to start an IO */
-	ret = storvsc_drv_obj->on_io_request(device_ctx,
-					   &cmd_request->request);
+	ret = storvsc_do_io(dev, &cmd_request->request);
+
 	if (ret == -1) {
 		/* no more space */
-		DPRINT_ERR(STORVSC_DRV,
-			   "scmnd (%p) - queue FULL...marking queue busy",
-			   scmnd);
 
 		if (cmd_request->bounce_sgl_count) {
 			/*
@@ -755,7 +632,7 @@
 					      cmd_request->bounce_sgl_count);
 		}
 
-		kmem_cache_free(host_device_ctx->request_pool, cmd_request);
+		kmem_cache_free(host_dev->request_pool, cmd_request);
 
 		scmnd->scsi_done = NULL;
 		scmnd->host_scribble = NULL;
@@ -768,154 +645,156 @@
 
 static DEF_SCSI_QCMD(storvsc_queuecommand)
 
-static int storvsc_merge_bvec(struct request_queue *q,
-			      struct bvec_merge_data *bmd, struct bio_vec *bvec)
-{
-	/* checking done by caller. */
-	return bvec->bv_len;
-}
 
-/*
- * storvsc_device_configure - Configure the specified scsi device
- */
-static int storvsc_device_alloc(struct scsi_device *sdevice)
-{
-	DPRINT_DBG(STORVSC_DRV, "sdev (%p) - setting device flag to %d",
-		   sdevice, BLIST_SPARSELUN);
+/* Scsi driver */
+static struct scsi_host_template scsi_driver = {
+	.module	=		THIS_MODULE,
+	.name =			"storvsc_host_t",
+	.bios_param =		storvsc_get_chs,
+	.queuecommand =		storvsc_queuecommand,
+	.eh_host_reset_handler =	storvsc_host_reset_handler,
+	.slave_alloc =		storvsc_device_alloc,
+	.slave_configure =	storvsc_device_configure,
+	.cmd_per_lun =		1,
+	/* 64 max_queue * 1 target */
+	.can_queue =		STORVSC_MAX_IO_REQUESTS*STORVSC_MAX_TARGETS,
+	.this_id =		-1,
+	/* no use setting to 0 since ll_blk_rw reset it to 1 */
+	/* currently 32 */
+	.sg_tablesize =		MAX_MULTIPAGE_BUFFER_COUNT,
 	/*
-	 * This enables luns to be located sparsely. Otherwise, we may not
-	 * discovered them.
+	 * ENABLE_CLUSTERING allows mutiple physically contig bio_vecs to merge
+	 * into 1 sg element. If set, we must limit the max_segment_size to
+	 * PAGE_SIZE, otherwise we may get 1 sg element that represents
+	 * multiple
 	 */
-	sdevice->sdev_bflags |= BLIST_SPARSELUN | BLIST_LARGELUN;
-	return 0;
-}
+	/* physically contig pfns (ie sg[x].length > PAGE_SIZE). */
+	.use_clustering =	ENABLE_CLUSTERING,
+	/* Make sure we dont get a sg segment crosses a page boundary */
+	.dma_boundary =		PAGE_SIZE-1,
+};
 
-static int storvsc_device_configure(struct scsi_device *sdevice)
+
+/*
+ * storvsc_probe - Add a new device for this driver
+ */
+
+static int storvsc_probe(struct hv_device *device)
 {
-	DPRINT_INFO(STORVSC_DRV, "sdev (%p) - curr queue depth %d", sdevice,
-		    sdevice->queue_depth);
+	int ret;
+	struct Scsi_Host *host;
+	struct hv_host_device *host_dev;
+	struct storvsc_device_info device_info;
 
-	DPRINT_INFO(STORVSC_DRV, "sdev (%p) - setting queue depth to %d",
-		    sdevice, STORVSC_MAX_IO_REQUESTS);
-	scsi_adjust_queue_depth(sdevice, MSG_SIMPLE_TAG,
-				STORVSC_MAX_IO_REQUESTS);
+	host = scsi_host_alloc(&scsi_driver,
+			       sizeof(struct hv_host_device));
+	if (!host)
+		return -ENOMEM;
 
-	DPRINT_INFO(STORVSC_DRV, "sdev (%p) - setting max segment size to %ld",
-		    sdevice, PAGE_SIZE);
-	blk_queue_max_segment_size(sdevice->request_queue, PAGE_SIZE);
+	dev_set_drvdata(&device->device, host);
 
-	DPRINT_INFO(STORVSC_DRV, "sdev (%p) - adding merge bio vec routine",
-		    sdevice);
-	blk_queue_merge_bvec(sdevice->request_queue, storvsc_merge_bvec);
+	host_dev = (struct hv_host_device *)host->hostdata;
+	memset(host_dev, 0, sizeof(struct hv_host_device));
 
-	blk_queue_bounce_limit(sdevice->request_queue, BLK_BOUNCE_ANY);
-	/* sdevice->timeout = (2000 * HZ);//(75 * HZ); */
+	host_dev->port = host->host_no;
+	host_dev->dev = device;
 
-	return 0;
-}
+	host_dev->request_pool =
+				kmem_cache_create(dev_name(&device->device),
+					sizeof(struct storvsc_cmd_request), 0,
+					SLAB_HWCACHE_ALIGN, NULL);
 
-/*
- * storvsc_host_reset_handler - Reset the scsi HBA
- */
-static int storvsc_host_reset_handler(struct scsi_cmnd *scmnd)
-{
-	int ret;
-	struct host_device_context *host_device_ctx =
-		(struct host_device_context *)scmnd->device->host->hostdata;
-	struct hv_device *device_ctx = host_device_ctx->device_ctx;
+	if (!host_dev->request_pool) {
+		scsi_host_put(host);
+		return -ENOMEM;
+	}
 
-	DPRINT_INFO(STORVSC_DRV, "sdev (%p) dev obj (%p) - host resetting...",
-		    scmnd->device, device_ctx);
+	device_info.port_number = host->host_no;
+	device_info.ring_buffer_size  = storvsc_ringbuffer_size;
+	/* Call to the vsc driver to add the device */
+	ret = storvsc_dev_add(device, (void *)&device_info);
 
-	/* Invokes the vsc to reset the host/bus */
-	ret = stor_vsc_on_host_reset(device_ctx);
-	if (ret != 0)
-		return ret;
+	if (ret != 0) {
+		kmem_cache_destroy(host_dev->request_pool);
+		scsi_host_put(host);
+		return -1;
+	}
 
-	DPRINT_INFO(STORVSC_DRV, "sdev (%p) dev obj (%p) - host reseted",
-		    scmnd->device, device_ctx);
+	host_dev->path = device_info.path_id;
+	host_dev->target = device_info.target_id;
 
-	return ret;
-}
+	/* max # of devices per target */
+	host->max_lun = STORVSC_MAX_LUNS_PER_TARGET;
+	/* max # of targets per channel */
+	host->max_id = STORVSC_MAX_TARGETS;
+	/* max # of channels */
+	host->max_channel = STORVSC_MAX_CHANNELS - 1;
 
-static int storvsc_get_chs(struct scsi_device *sdev, struct block_device * bdev,
-			   sector_t capacity, int *info)
-{
-	sector_t total_sectors = capacity;
-	sector_t cylinder_times_heads = 0;
-	sector_t temp = 0;
+	/* Register the HBA and start the scsi bus scan */
+	ret = scsi_add_host(host, &device->device);
+	if (ret != 0) {
 
-	int sectors_per_track = 0;
-	int heads = 0;
-	int cylinders = 0;
-	int rem = 0;
+		storvsc_dev_remove(device);
 
-	if (total_sectors > (65535 * 16 * 255))
-		total_sectors = (65535 * 16 * 255);
+		kmem_cache_destroy(host_dev->request_pool);
+		scsi_host_put(host);
+		return -1;
+	}
 
-	if (total_sectors >= (65535 * 16 * 63)) {
-		sectors_per_track = 255;
-		heads = 16;
+	scsi_scan_host(host);
+	return ret;
+}
 
-		cylinder_times_heads = total_sectors;
-		/* sector_div stores the quotient in cylinder_times_heads */
-		rem = sector_div(cylinder_times_heads, sectors_per_track);
-	} else {
-		sectors_per_track = 17;
+/* The one and only one */
 
-		cylinder_times_heads = total_sectors;
-		/* sector_div stores the quotient in cylinder_times_heads */
-		rem = sector_div(cylinder_times_heads, sectors_per_track);
+static struct hv_driver storvsc_drv = {
+	.probe = storvsc_probe,
+	.remove = storvsc_remove,
+};
 
-		temp = cylinder_times_heads + 1023;
-		/* sector_div stores the quotient in temp */
-		rem = sector_div(temp, 1024);
 
-		heads = temp;
+/*
+ * storvsc_drv_init - StorVsc driver initialization.
+ */
+static int storvsc_drv_init(void)
+{
+	int ret;
+	struct hv_driver *drv = &storvsc_drv;
+	u32 max_outstanding_req_per_channel;
 
-		if (heads < 4)
-			heads = 4;
+	/*
+	 * Divide the ring buffer data size (which is 1 page less
+	 * than the ring buffer size since that page is reserved for
+	 * the ring buffer indices) by the max request size (which is
+	 * vmbus_channel_packet_multipage_buffer + struct vstor_packet + u64)
+	 */
 
-		if (cylinder_times_heads >= (heads * 1024) || (heads > 16)) {
-			sectors_per_track = 31;
-			heads = 16;
+	max_outstanding_req_per_channel =
+	((storvsc_ringbuffer_size - PAGE_SIZE) /
+	ALIGN(MAX_MULTIPAGE_BUFFER_PACKET +
+	sizeof(struct vstor_packet) + sizeof(u64),
+	sizeof(u64)));
 
-			cylinder_times_heads = total_sectors;
-			/*
-			 * sector_div stores the quotient in
-			 * cylinder_times_heads
-			 */
-			rem = sector_div(cylinder_times_heads,
-					 sectors_per_track);
-		}
+	memcpy(&drv->dev_type, &gStorVscDeviceType,
+	       sizeof(struct hv_guid));
 
-		if (cylinder_times_heads >= (heads * 1024)) {
-			sectors_per_track = 63;
-			heads = 16;
+	if (max_outstanding_req_per_channel <
+	    STORVSC_MAX_IO_REQUESTS)
+		return -1;
 
-			cylinder_times_heads = total_sectors;
-			/*
-			 * sector_div stores the quotient in
-			 * cylinder_times_heads
-			 */
-			rem = sector_div(cylinder_times_heads,
-					 sectors_per_track);
-		}
-	}
+	drv->name = driver_name;
+	drv->driver.name = driver_name;
 
-	temp = cylinder_times_heads;
-	/* sector_div stores the quotient in temp */
-	rem = sector_div(temp, heads);
-	cylinders = temp;
 
-	info[0] = heads;
-	info[1] = sectors_per_track;
-	info[2] = cylinders;
+	/* The driver belongs to vmbus */
+	ret = vmbus_child_driver_register(&drv->driver);
 
-	DPRINT_INFO(STORVSC_DRV, "CHS (%d, %d, %d)", cylinders, heads,
-		    sectors_per_track);
+	return ret;
+}
 
-    return 0;
+static void storvsc_drv_exit(void)
+{
+	vmbus_child_driver_unregister(&storvsc_drv.driver);
 }
 
 static int __init storvsc_init(void)
@@ -923,7 +802,7 @@
 	int ret;
 
 	DPRINT_INFO(STORVSC_DRV, "Storvsc initializing....");
-	ret = storvsc_drv_init(stor_vsc_initialize);
+	ret = storvsc_drv_init();
 	return ret;
 }
 
diff -druN linux-2.6.39-libre/drivers/staging/hv/utils.h linux-3.0-rc7-libre/drivers/staging/hv/utils.h
--- linux-2.6.39-libre/drivers/staging/hv/utils.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/hv/utils.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,120 +0,0 @@
-/*
- * Copyright (c) 2009, Microsoft 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., 59 Temple
- * Place - Suite 330, Boston, MA 02111-1307 USA.
- *
- * Authors:
- *   Haiyang Zhang <haiyangz@microsoft.com>
- *   Hank Janssen  <hjanssen@microsoft.com>
- */
-#ifndef __HV_UTILS_H_
-#define __HV_UTILS_H_
-
-/*
- * Common header for Hyper-V ICs
- */
-#define ICMSGTYPE_NEGOTIATE		0
-#define ICMSGTYPE_HEARTBEAT		1
-#define ICMSGTYPE_KVPEXCHANGE		2
-#define ICMSGTYPE_SHUTDOWN		3
-#define ICMSGTYPE_TIMESYNC		4
-#define ICMSGTYPE_VSS			5
-
-#define ICMSGHDRFLAG_TRANSACTION	1
-#define ICMSGHDRFLAG_REQUEST		2
-#define ICMSGHDRFLAG_RESPONSE		4
-
-#define HV_S_OK				0x00000000
-#define HV_E_FAIL			0x80004005
-#define HV_ERROR_NOT_SUPPORTED		0x80070032
-#define HV_ERROR_MACHINE_LOCKED		0x800704F7
-
-struct vmbuspipe_hdr {
-	u32 flags;
-	u32 msgsize;
-} __packed;
-
-struct ic_version {
-	u16 major;
-	u16 minor;
-} __packed;
-
-struct icmsg_hdr {
-	struct ic_version icverframe;
-	u16 icmsgtype;
-	struct ic_version icvermsg;
-	u16 icmsgsize;
-	u32 status;
-	u8 ictransaction_id;
-	u8 icflags;
-	u8 reserved[2];
-} __packed;
-
-struct icmsg_negotiate {
-	u16 icframe_vercnt;
-	u16 icmsg_vercnt;
-	u32 reserved;
-	struct ic_version icversion_data[1]; /* any size array */
-} __packed;
-
-struct shutdown_msg_data {
-	u32 reason_code;
-	u32 timeout_seconds;
-	u32 flags;
-	u8  display_message[2048];
-} __packed;
-
-struct heartbeat_msg_data {
-	u64 seq_num;
-	u32 reserved[8];
-} __packed;
-
-/* Time Sync IC defs */
-#define ICTIMESYNCFLAG_PROBE	0
-#define ICTIMESYNCFLAG_SYNC	1
-#define ICTIMESYNCFLAG_SAMPLE	2
-
-#ifdef __x86_64__
-#define WLTIMEDELTA	116444736000000000L	/* in 100ns unit */
-#else
-#define WLTIMEDELTA	116444736000000000LL
-#endif
-
-struct ictimesync_data{
-	u64 parenttime;
-	u64 childtime;
-	u64 roundtriptime;
-	u8 flags;
-} __packed;
-
-/* Index for each IC struct in array hv_cb_utils[] */
-#define HV_SHUTDOWN_MSG		0
-#define HV_TIMESYNC_MSG		1
-#define HV_HEARTBEAT_MSG	2
-#define HV_KVP_MSG		3
-
-struct hyperv_service_callback {
-	u8 msg_type;
-	char *log_msg;
-	unsigned char data[16];
-	struct vmbus_channel *channel;
-	void (*callback) (void *context);
-};
-
-extern void prep_negotiate_resp(struct icmsg_hdr *,
-				struct icmsg_negotiate *, u8 *);
-extern void chn_cb_negotiate(void *);
-extern struct hyperv_service_callback hv_cb_utils[];
-
-#endif /* __HV_UTILS_H_ */
diff -druN linux-2.6.39-libre/drivers/staging/hv/version_info.h linux-3.0-rc7-libre/drivers/staging/hv/version_info.h
--- linux-2.6.39-libre/drivers/staging/hv/version_info.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/hv/version_info.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,48 +0,0 @@
-/*
- *
- * Copyright (c) 2009, Microsoft 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., 59 Temple
- * Place - Suite 330, Boston, MA 02111-1307 USA.
- *
- * Authors:
- *   Haiyang Zhang <haiyangz@microsoft.com>
- *   Hank Janssen  <hjanssen@microsoft.com>
- *
- */
-
-#ifndef __HV_VERSION_INFO
-#define __HV_VERSION_INFO
-
-/*
- * 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.
- *
- * 3.1 - Added completed hv_utils driver. Shutdown/Heartbeat/Timesync
- */
-#define HV_DRV_VERSION           "3.1"
-
-
-#endif
diff -druN linux-2.6.39-libre/drivers/staging/hv/vmbus_api.h linux-3.0-rc7-libre/drivers/staging/hv/vmbus_api.h
--- linux-2.6.39-libre/drivers/staging/hv/vmbus_api.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/hv/vmbus_api.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,139 +0,0 @@
-/*
- *
- * Copyright (c) 2009, Microsoft 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., 59 Temple
- * Place - Suite 330, Boston, MA 02111-1307 USA.
- *
- * Authors:
- *   Haiyang Zhang <haiyangz@microsoft.com>
- *   Hank Janssen  <hjanssen@microsoft.com>
- *
- */
-
-
-#ifndef _VMBUS_API_H_
-#define _VMBUS_API_H_
-
-#include <linux/device.h>
-#include <linux/workqueue.h>
-
-#define MAX_PAGE_BUFFER_COUNT				16
-#define MAX_MULTIPAGE_BUFFER_COUNT			32 /* 128K */
-
-#pragma pack(push, 1)
-
-/* Single-page buffer */
-struct hv_page_buffer {
-	u32 len;
-	u32 offset;
-	u64 pfn;
-};
-
-/* Multiple-page buffer */
-struct hv_multipage_buffer {
-	/* Length and Offset determines the # of pfns in the array */
-	u32 len;
-	u32 offset;
-	u64 pfn_array[MAX_MULTIPAGE_BUFFER_COUNT];
-};
-
-/* 0x18 includes the proprietary packet header */
-#define MAX_PAGE_BUFFER_PACKET		(0x18 +			\
-					(sizeof(struct hv_page_buffer) * \
-					 MAX_PAGE_BUFFER_COUNT))
-#define MAX_MULTIPAGE_BUFFER_PACKET	(0x18 +			\
-					 sizeof(struct hv_multipage_buffer))
-
-
-#pragma pack(pop)
-
-struct hv_driver;
-struct hv_device;
-
-struct hv_dev_port_info {
-	u32 int_mask;
-	u32 read_idx;
-	u32 write_idx;
-	u32 bytes_avail_toread;
-	u32 bytes_avail_towrite;
-};
-
-struct hv_device_info {
-	u32 chn_id;
-	u32 chn_state;
-	struct hv_guid chn_type;
-	struct hv_guid chn_instance;
-
-	u32 monitor_id;
-	u32 server_monitor_pending;
-	u32 server_monitor_latency;
-	u32 server_monitor_conn_id;
-	u32 client_monitor_pending;
-	u32 client_monitor_latency;
-	u32 client_monitor_conn_id;
-
-	struct hv_dev_port_info inbound;
-	struct hv_dev_port_info outbound;
-};
-
-/* Base driver object */
-struct hv_driver {
-	const char *name;
-
-	/* the device type supported by this driver */
-	struct hv_guid dev_type;
-
-	/*
-	 * Device type specific drivers (net, blk etc.)
-	 * need a mechanism to get a pointer to
-	 * device type specific driver structure given
-	 * a pointer to the base hyperv driver structure.
-	 * The current code solves this problem using
-	 * a hack. Support this need explicitly
-	 */
-	void *priv;
-
-	struct device_driver driver;
-
-	int (*dev_add)(struct hv_device *device, void *data);
-	int (*dev_rm)(struct hv_device *device);
-	void (*cleanup)(struct hv_driver *driver);
-};
-
-/* Base device object */
-struct hv_device {
-	/* the driver for this device */
-	struct hv_driver *drv;
-
-	char name[64];
-
-	struct work_struct probe_failed_work_item;
-
-	int probe_error;
-
-	/* the device type id of this device */
-	struct hv_guid dev_type;
-
-	/* the device instance id of this device */
-	struct hv_guid dev_instance;
-
-	struct device device;
-
-	struct vmbus_channel *channel;
-
-	/* Device extension; */
-	void *ext;
-};
-
-#endif /* _VMBUS_API_H_ */
diff -druN linux-2.6.39-libre/drivers/staging/hv/vmbus_channel_interface.h linux-3.0-rc7-libre/drivers/staging/hv/vmbus_channel_interface.h
--- linux-2.6.39-libre/drivers/staging/hv/vmbus_channel_interface.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/hv/vmbus_channel_interface.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,89 +0,0 @@
-/*
- *
- * Copyright (c) 2009, Microsoft 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., 59 Temple
- * Place - Suite 330, Boston, MA 02111-1307 USA.
- *
- * Authors:
- *   Haiyang Zhang <haiyangz@microsoft.com>
- *   Hank Janssen  <hjanssen@microsoft.com>
- *
- */
-
-#ifndef __VMBUSCHANNELINTERFACE_H
-#define __VMBUSCHANNELINTERFACE_H
-
-/*
- * A revision number of vmbus that is used for ensuring both ends on a
- * partition are using compatible versions.
- */
-#define VMBUS_REVISION_NUMBER		13
-
-/* Make maximum size of pipe payload of 16K */
-#define MAX_PIPE_DATA_PAYLOAD		(sizeof(u8) * 16384)
-
-/* Define PipeMode values. */
-#define VMBUS_PIPE_TYPE_BYTE		0x00000000
-#define VMBUS_PIPE_TYPE_MESSAGE		0x00000004
-
-/* The size of the user defined data buffer for non-pipe offers. */
-#define MAX_USER_DEFINED_BYTES		120
-
-/* The size of the user defined data buffer for pipe offers. */
-#define MAX_PIPE_USER_DEFINED_BYTES	116
-
-/*
- * At the center of the Channel Management library is the Channel Offer. This
- * struct contains the fundamental information about an offer.
- */
-struct vmbus_channel_offer {
-	struct hv_guid if_type;
-	struct hv_guid if_instance;
-	u64 int_latency; /* in 100ns units */
-	u32 if_revision;
-	u32 server_ctx_size;	/* in bytes */
-	u16 chn_flags;
-	u16 mmio_megabytes;		/* in bytes * 1024 * 1024 */
-
-	union {
-		/* Non-pipes: The user has MAX_USER_DEFINED_BYTES bytes. */
-		struct {
-			unsigned char user_def[MAX_USER_DEFINED_BYTES];
-		} std;
-
-		/*
-		 * Pipes:
-		 * The following sructure is an integrated pipe protocol, which
-		 * is implemented on top of standard user-defined data. Pipe
-		 * clients have MAX_PIPE_USER_DEFINED_BYTES left for their own
-		 * use.
-		 */
-		struct {
-			u32  pipe_mode;
-			unsigned char user_def[MAX_PIPE_USER_DEFINED_BYTES];
-		} pipe;
-	} u;
-	u32 padding;
-} __packed;
-
-/* Server Flags */
-#define VMBUS_CHANNEL_ENUMERATE_DEVICE_INTERFACE	1
-#define VMBUS_CHANNEL_SERVER_SUPPORTS_TRANSFER_PAGES	2
-#define VMBUS_CHANNEL_SERVER_SUPPORTS_GPADLS		4
-#define VMBUS_CHANNEL_NAMED_PIPE_MODE			0x10
-#define VMBUS_CHANNEL_LOOPBACK_OFFER			0x100
-#define VMBUS_CHANNEL_PARENT_OFFER			0x200
-#define VMBUS_CHANNEL_REQUEST_MONITORED_NOTIFICATION	0x400
-
-#endif
diff -druN linux-2.6.39-libre/drivers/staging/hv/vmbus_drv.c linux-3.0-rc7-libre/drivers/staging/hv/vmbus_drv.c
--- linux-2.6.39-libre/drivers/staging/hv/vmbus_drv.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/hv/vmbus_drv.c	2011-07-11 19:51:52.000000000 -0400
@@ -17,7 +17,11 @@
  * Authors:
  *   Haiyang Zhang <haiyangz@microsoft.com>
  *   Hank Janssen  <hjanssen@microsoft.com>
+ *   K. Y. Srinivasan <kys@microsoft.com>
+ *
  */
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/device.h>
@@ -27,52 +31,176 @@
 #include <linux/pci.h>
 #include <linux/dmi.h>
 #include <linux/slab.h>
+#include <linux/acpi.h>
+#include <acpi/acpi_bus.h>
 #include <linux/completion.h>
-#include "version_info.h"
-#include "hv_api.h"
-#include "logging.h"
-#include "vmbus.h"
-#include "channel.h"
-#include "vmbus_private.h"
 
+#include "hyperv.h"
+#include "hyperv_vmbus.h"
 
-/* FIXME! We need to do this dynamically for PIC and APIC system */
-#define VMBUS_IRQ		0x5
-#define VMBUS_IRQ_VECTOR	IRQ5_VECTOR
 
-/* Main vmbus driver data structure */
-struct vmbus_driver_context {
+static struct pci_dev *hv_pci_dev;
 
-	struct bus_type bus;
-	struct tasklet_struct msg_dpc;
-	struct tasklet_struct event_dpc;
+static struct tasklet_struct msg_dpc;
+static struct tasklet_struct event_dpc;
 
-	/* The bus root device */
-	struct hv_device device_ctx;
-};
+unsigned int vmbus_loglevel = (ALL_MODULES << 16 | INFO_LVL);
+EXPORT_SYMBOL(vmbus_loglevel);
+	/* (ALL_MODULES << 16 | DEBUG_LVL_ENTEREXIT); */
+	/* (((VMBUS | VMBUS_DRV)<<16) | DEBUG_LVL_ENTEREXIT); */
 
-static int vmbus_match(struct device *device, struct device_driver *driver);
-static int vmbus_probe(struct device *device);
-static int vmbus_remove(struct device *device);
-static void vmbus_shutdown(struct device *device);
-static int vmbus_uevent(struct device *device, struct kobj_uevent_env *env);
+static int pci_probe_error;
+static struct completion probe_event;
+static int irq;
 
-static irqreturn_t vmbus_isr(int irq, void *dev_id);
+static void get_channel_info(struct hv_device *device,
+			     struct hv_device_info *info)
+{
+	struct vmbus_channel_debug_info debug_info;
 
-static void vmbus_device_release(struct device *device);
-static void vmbus_bus_release(struct device *device);
+	if (!device->channel)
+		return;
+
+	vmbus_get_debug_info(device->channel, &debug_info);
+
+	info->chn_id = debug_info.relid;
+	info->chn_state = debug_info.state;
+	memcpy(&info->chn_type, &debug_info.interfacetype,
+	       sizeof(struct hv_guid));
+	memcpy(&info->chn_instance, &debug_info.interface_instance,
+	       sizeof(struct hv_guid));
+
+	info->monitor_id = debug_info.monitorid;
+
+	info->server_monitor_pending = debug_info.servermonitor_pending;
+	info->server_monitor_latency = debug_info.servermonitor_latency;
+	info->server_monitor_conn_id = debug_info.servermonitor_connectionid;
+
+	info->client_monitor_pending = debug_info.clientmonitor_pending;
+	info->client_monitor_latency = debug_info.clientmonitor_latency;
+	info->client_monitor_conn_id = debug_info.clientmonitor_connectionid;
 
+	info->inbound.int_mask = debug_info.inbound.current_interrupt_mask;
+	info->inbound.read_idx = debug_info.inbound.current_read_index;
+	info->inbound.write_idx = debug_info.inbound.current_write_index;
+	info->inbound.bytes_avail_toread =
+		debug_info.inbound.bytes_avail_toread;
+	info->inbound.bytes_avail_towrite =
+		debug_info.inbound.bytes_avail_towrite;
+
+	info->outbound.int_mask =
+		debug_info.outbound.current_interrupt_mask;
+	info->outbound.read_idx = debug_info.outbound.current_read_index;
+	info->outbound.write_idx = debug_info.outbound.current_write_index;
+	info->outbound.bytes_avail_toread =
+		debug_info.outbound.bytes_avail_toread;
+	info->outbound.bytes_avail_towrite =
+		debug_info.outbound.bytes_avail_towrite;
+}
+
+/*
+ * vmbus_show_device_attr - Show the device attribute in sysfs.
+ *
+ * This is invoked when user does a
+ * "cat /sys/bus/vmbus/devices/<busdevice>/<attr name>"
+ */
 static ssize_t vmbus_show_device_attr(struct device *dev,
 				      struct device_attribute *dev_attr,
-				      char *buf);
+				      char *buf)
+{
+	struct hv_device *device_ctx = device_to_hv_device(dev);
+	struct hv_device_info device_info;
 
+	memset(&device_info, 0, sizeof(struct hv_device_info));
 
-unsigned int vmbus_loglevel = (ALL_MODULES << 16 | INFO_LVL);
-EXPORT_SYMBOL(vmbus_loglevel);
-	/* (ALL_MODULES << 16 | DEBUG_LVL_ENTEREXIT); */
-	/* (((VMBUS | VMBUS_DRV)<<16) | DEBUG_LVL_ENTEREXIT); */
+	get_channel_info(device_ctx, &device_info);
 
-static int vmbus_irq = VMBUS_IRQ;
+	if (!strcmp(dev_attr->attr.name, "class_id")) {
+		return sprintf(buf, "{%02x%02x%02x%02x-%02x%02x-%02x%02x-"
+			       "%02x%02x%02x%02x%02x%02x%02x%02x}\n",
+			       device_info.chn_type.data[3],
+			       device_info.chn_type.data[2],
+			       device_info.chn_type.data[1],
+			       device_info.chn_type.data[0],
+			       device_info.chn_type.data[5],
+			       device_info.chn_type.data[4],
+			       device_info.chn_type.data[7],
+			       device_info.chn_type.data[6],
+			       device_info.chn_type.data[8],
+			       device_info.chn_type.data[9],
+			       device_info.chn_type.data[10],
+			       device_info.chn_type.data[11],
+			       device_info.chn_type.data[12],
+			       device_info.chn_type.data[13],
+			       device_info.chn_type.data[14],
+			       device_info.chn_type.data[15]);
+	} else if (!strcmp(dev_attr->attr.name, "device_id")) {
+		return sprintf(buf, "{%02x%02x%02x%02x-%02x%02x-%02x%02x-"
+			       "%02x%02x%02x%02x%02x%02x%02x%02x}\n",
+			       device_info.chn_instance.data[3],
+			       device_info.chn_instance.data[2],
+			       device_info.chn_instance.data[1],
+			       device_info.chn_instance.data[0],
+			       device_info.chn_instance.data[5],
+			       device_info.chn_instance.data[4],
+			       device_info.chn_instance.data[7],
+			       device_info.chn_instance.data[6],
+			       device_info.chn_instance.data[8],
+			       device_info.chn_instance.data[9],
+			       device_info.chn_instance.data[10],
+			       device_info.chn_instance.data[11],
+			       device_info.chn_instance.data[12],
+			       device_info.chn_instance.data[13],
+			       device_info.chn_instance.data[14],
+			       device_info.chn_instance.data[15]);
+	} else if (!strcmp(dev_attr->attr.name, "state")) {
+		return sprintf(buf, "%d\n", device_info.chn_state);
+	} else if (!strcmp(dev_attr->attr.name, "id")) {
+		return sprintf(buf, "%d\n", device_info.chn_id);
+	} else if (!strcmp(dev_attr->attr.name, "out_intr_mask")) {
+		return sprintf(buf, "%d\n", device_info.outbound.int_mask);
+	} else if (!strcmp(dev_attr->attr.name, "out_read_index")) {
+		return sprintf(buf, "%d\n", device_info.outbound.read_idx);
+	} else if (!strcmp(dev_attr->attr.name, "out_write_index")) {
+		return sprintf(buf, "%d\n", device_info.outbound.write_idx);
+	} else if (!strcmp(dev_attr->attr.name, "out_read_bytes_avail")) {
+		return sprintf(buf, "%d\n",
+			       device_info.outbound.bytes_avail_toread);
+	} else if (!strcmp(dev_attr->attr.name, "out_write_bytes_avail")) {
+		return sprintf(buf, "%d\n",
+			       device_info.outbound.bytes_avail_towrite);
+	} else if (!strcmp(dev_attr->attr.name, "in_intr_mask")) {
+		return sprintf(buf, "%d\n", device_info.inbound.int_mask);
+	} else if (!strcmp(dev_attr->attr.name, "in_read_index")) {
+		return sprintf(buf, "%d\n", device_info.inbound.read_idx);
+	} else if (!strcmp(dev_attr->attr.name, "in_write_index")) {
+		return sprintf(buf, "%d\n", device_info.inbound.write_idx);
+	} else if (!strcmp(dev_attr->attr.name, "in_read_bytes_avail")) {
+		return sprintf(buf, "%d\n",
+			       device_info.inbound.bytes_avail_toread);
+	} else if (!strcmp(dev_attr->attr.name, "in_write_bytes_avail")) {
+		return sprintf(buf, "%d\n",
+			       device_info.inbound.bytes_avail_towrite);
+	} else if (!strcmp(dev_attr->attr.name, "monitor_id")) {
+		return sprintf(buf, "%d\n", device_info.monitor_id);
+	} else if (!strcmp(dev_attr->attr.name, "server_monitor_pending")) {
+		return sprintf(buf, "%d\n", device_info.server_monitor_pending);
+	} else if (!strcmp(dev_attr->attr.name, "server_monitor_latency")) {
+		return sprintf(buf, "%d\n", device_info.server_monitor_latency);
+	} else if (!strcmp(dev_attr->attr.name, "server_monitor_conn_id")) {
+		return sprintf(buf, "%d\n",
+			       device_info.server_monitor_conn_id);
+	} else if (!strcmp(dev_attr->attr.name, "client_monitor_pending")) {
+		return sprintf(buf, "%d\n", device_info.client_monitor_pending);
+	} else if (!strcmp(dev_attr->attr.name, "client_monitor_latency")) {
+		return sprintf(buf, "%d\n", device_info.client_monitor_latency);
+	} else if (!strcmp(dev_attr->attr.name, "client_monitor_conn_id")) {
+		return sprintf(buf, "%d\n",
+			       device_info.client_monitor_conn_id);
+	} else {
+		return 0;
+	}
+}
 
 /* Set up per device attributes in /sys/bus/vmbus/devices/<bus device> */
 static struct device_attribute vmbus_device_attrs[] = {
@@ -104,68 +232,182 @@
 	__ATTR_NULL
 };
 
-/* The one and only one */
-static struct vmbus_driver_context vmbus_drv = {
-	.bus.name =		"vmbus",
-	.bus.match =		vmbus_match,
-	.bus.shutdown =		vmbus_shutdown,
-	.bus.remove =		vmbus_remove,
-	.bus.probe =		vmbus_probe,
-	.bus.uevent =		vmbus_uevent,
-	.bus.dev_attrs =	vmbus_device_attrs,
-};
 
-static const char *driver_name = "hyperv";
+/*
+ * vmbus_uevent - add uevent for our device
+ *
+ * This routine is invoked when a device is added or removed on the vmbus to
+ * generate a uevent to udev in the userspace. The udev will then look at its
+ * rule and the uevent generated here to load the appropriate driver
+ */
+static int vmbus_uevent(struct device *device, struct kobj_uevent_env *env)
+{
+	struct hv_device *dev = device_to_hv_device(device);
+	int ret;
+
+	ret = add_uevent_var(env, "VMBUS_DEVICE_CLASS_GUID={"
+			     "%02x%02x%02x%02x-%02x%02x-%02x%02x-"
+			     "%02x%02x%02x%02x%02x%02x%02x%02x}",
+			     dev->dev_type.data[3],
+			     dev->dev_type.data[2],
+			     dev->dev_type.data[1],
+			     dev->dev_type.data[0],
+			     dev->dev_type.data[5],
+			     dev->dev_type.data[4],
+			     dev->dev_type.data[7],
+			     dev->dev_type.data[6],
+			     dev->dev_type.data[8],
+			     dev->dev_type.data[9],
+			     dev->dev_type.data[10],
+			     dev->dev_type.data[11],
+			     dev->dev_type.data[12],
+			     dev->dev_type.data[13],
+			     dev->dev_type.data[14],
+			     dev->dev_type.data[15]);
+
+	if (ret)
+		return ret;
+
+	ret = add_uevent_var(env, "VMBUS_DEVICE_DEVICE_GUID={"
+			     "%02x%02x%02x%02x-%02x%02x-%02x%02x-"
+			     "%02x%02x%02x%02x%02x%02x%02x%02x}",
+			     dev->dev_instance.data[3],
+			     dev->dev_instance.data[2],
+			     dev->dev_instance.data[1],
+			     dev->dev_instance.data[0],
+			     dev->dev_instance.data[5],
+			     dev->dev_instance.data[4],
+			     dev->dev_instance.data[7],
+			     dev->dev_instance.data[6],
+			     dev->dev_instance.data[8],
+			     dev->dev_instance.data[9],
+			     dev->dev_instance.data[10],
+			     dev->dev_instance.data[11],
+			     dev->dev_instance.data[12],
+			     dev->dev_instance.data[13],
+			     dev->dev_instance.data[14],
+			     dev->dev_instance.data[15]);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
 
 /*
- * Windows vmbus does not defined this.
- * We defined this to be consistent with other devices
+ * vmbus_match - Attempt to match the specified device to the specified driver
  */
-/* {c5295816-f63a-4d5f-8d1a-4daf999ca185} */
-static const struct hv_guid device_type = {
-	.data = {
-		0x16, 0x58, 0x29, 0xc5, 0x3a, 0xf6, 0x5f, 0x4d,
-		0x8d, 0x1a, 0x4d, 0xaf, 0x99, 0x9c, 0xa1, 0x85
+static int vmbus_match(struct device *device, struct device_driver *driver)
+{
+	int match = 0;
+	struct hv_driver *drv = drv_to_hv_drv(driver);
+	struct hv_device *device_ctx = device_to_hv_device(device);
+
+	/* We found our driver ? */
+	if (memcmp(&device_ctx->dev_type, &drv->dev_type,
+		   sizeof(struct hv_guid)) == 0)
+		match = 1;
+
+	return match;
+}
+
+/*
+ * vmbus_probe - Add the new vmbus's child device
+ */
+static int vmbus_probe(struct device *child_device)
+{
+	int ret = 0;
+	struct hv_driver *drv =
+			drv_to_hv_drv(child_device->driver);
+	struct hv_device *dev = device_to_hv_device(child_device);
+
+	if (drv->probe) {
+		ret = drv->probe(dev);
+		if (ret != 0)
+			pr_err("probe failed for device %s (%d)\n",
+			       dev_name(child_device), ret);
+
+	} else {
+		pr_err("probe not set for driver %s\n",
+		       dev_name(child_device));
+		ret = -1;
 	}
-};
+	return ret;
+}
 
-/* {ac3760fc-9adf-40aa-9427-a70ed6de95c5} */
-static const struct hv_guid device_id = {
-	.data = {
-		0xfc, 0x60, 0x37, 0xac, 0xdf, 0x9a, 0xaa, 0x40,
-		0x94, 0x27, 0xa7, 0x0e, 0xd6, 0xde, 0x95, 0xc5
+/*
+ * vmbus_remove - Remove a vmbus device
+ */
+static int vmbus_remove(struct device *child_device)
+{
+	int ret;
+	struct hv_driver *drv;
+
+	struct hv_device *dev = device_to_hv_device(child_device);
+
+	if (child_device->driver) {
+		drv = drv_to_hv_drv(child_device->driver);
+
+		if (drv->remove) {
+			ret = drv->remove(dev);
+		} else {
+			pr_err("remove not set for driver %s\n",
+				dev_name(child_device));
+			ret = -1;
+		}
 	}
-};
 
-static struct hv_device *vmbus_device; /* vmbus root device */
+	return 0;
+}
 
 
 /*
- * vmbus_dev_add - Callback when the root bus device is added
+ * vmbus_shutdown - Shutdown a vmbus device
  */
-static int vmbus_dev_add(struct hv_device *dev, void *info)
+static void vmbus_shutdown(struct device *child_device)
 {
-	u32 *irqvector = info;
-	int ret;
+	struct hv_driver *drv;
+	struct hv_device *dev = device_to_hv_device(child_device);
 
-	vmbus_device = dev;
 
-	memcpy(&vmbus_device->dev_type, &device_type, sizeof(struct hv_guid));
-	memcpy(&vmbus_device->dev_instance, &device_id,
-	       sizeof(struct hv_guid));
+	/* The device may not be attached yet */
+	if (!child_device->driver)
+		return;
 
-	/* strcpy(dev->name, "vmbus"); */
-	/* SynIC setup... */
-	on_each_cpu(hv_synic_init, (void *)irqvector, 1);
+	drv = drv_to_hv_drv(child_device->driver);
 
-	/* Connect to VMBus in the root partition */
-	ret = vmbus_connect();
+	if (drv->shutdown)
+		drv->shutdown(dev);
 
-	/* VmbusSendEvent(device->localPortId+1); */
-	return ret;
+	return;
 }
 
 
+/*
+ * vmbus_device_release - Final callback release of the vmbus child device
+ */
+static void vmbus_device_release(struct device *device)
+{
+	struct hv_device *device_ctx = device_to_hv_device(device);
+
+	kfree(device_ctx);
+
+}
+
+/* The one and only one */
+static struct bus_type  hv_bus = {
+	.name =		"vmbus",
+	.match =		vmbus_match,
+	.shutdown =		vmbus_shutdown,
+	.remove =		vmbus_remove,
+	.probe =		vmbus_probe,
+	.uevent =		vmbus_uevent,
+	.dev_attrs =	vmbus_device_attrs,
+};
+
+static const char *driver_name = "hyperv";
+
+
 struct onmessage_work_context {
 	struct work_struct work;
 	struct hv_message msg;
@@ -242,172 +484,38 @@
 	msg = (struct hv_message *)page_addr + VMBUS_MESSAGE_SINT;
 
 	/* Check if there are actual msgs to be process */
-	if (msg->header.message_type != HVMSG_NONE) {
-		DPRINT_DBG(VMBUS, "received msg type %d size %d",
-				msg->header.message_type,
-				msg->header.payload_size);
+	if (msg->header.message_type != HVMSG_NONE)
 		ret |= 0x1;
-	}
 
 	/* TODO: Check if there are events to be process */
 	page_addr = hv_context.synic_event_page[cpu];
 	event = (union hv_synic_event_flags *)page_addr + VMBUS_MESSAGE_SINT;
 
 	/* Since we are a child, we only need to check bit 0 */
-	if (sync_test_and_clear_bit(0, (unsigned long *) &event->flags32[0])) {
-		DPRINT_DBG(VMBUS, "received event %d", event->flags32[0]);
+	if (sync_test_and_clear_bit(0, (unsigned long *) &event->flags32[0]))
 		ret |= 0x2;
-	}
 
 	return ret;
 }
 
-static void get_channel_info(struct hv_device *device,
-			     struct hv_device_info *info)
-{
-	struct vmbus_channel_debug_info debug_info;
-
-	if (!device->channel)
-		return;
-
-	vmbus_get_debug_info(device->channel, &debug_info);
-
-	info->chn_id = debug_info.relid;
-	info->chn_state = debug_info.state;
-	memcpy(&info->chn_type, &debug_info.interfacetype,
-	       sizeof(struct hv_guid));
-	memcpy(&info->chn_instance, &debug_info.interface_instance,
-	       sizeof(struct hv_guid));
-
-	info->monitor_id = debug_info.monitorid;
-
-	info->server_monitor_pending = debug_info.servermonitor_pending;
-	info->server_monitor_latency = debug_info.servermonitor_latency;
-	info->server_monitor_conn_id = debug_info.servermonitor_connectionid;
-
-	info->client_monitor_pending = debug_info.clientmonitor_pending;
-	info->client_monitor_latency = debug_info.clientmonitor_latency;
-	info->client_monitor_conn_id = debug_info.clientmonitor_connectionid;
-
-	info->inbound.int_mask = debug_info.inbound.current_interrupt_mask;
-	info->inbound.read_idx = debug_info.inbound.current_read_index;
-	info->inbound.write_idx = debug_info.inbound.current_write_index;
-	info->inbound.bytes_avail_toread =
-		debug_info.inbound.bytes_avail_toread;
-	info->inbound.bytes_avail_towrite =
-		debug_info.inbound.bytes_avail_towrite;
-
-	info->outbound.int_mask =
-		debug_info.outbound.current_interrupt_mask;
-	info->outbound.read_idx = debug_info.outbound.current_read_index;
-	info->outbound.write_idx = debug_info.outbound.current_write_index;
-	info->outbound.bytes_avail_toread =
-		debug_info.outbound.bytes_avail_toread;
-	info->outbound.bytes_avail_towrite =
-		debug_info.outbound.bytes_avail_towrite;
-}
 
-/*
- * vmbus_show_device_attr - Show the device attribute in sysfs.
- *
- * This is invoked when user does a
- * "cat /sys/bus/vmbus/devices/<busdevice>/<attr name>"
- */
-static ssize_t vmbus_show_device_attr(struct device *dev,
-				      struct device_attribute *dev_attr,
-				      char *buf)
+static irqreturn_t vmbus_isr(int irq, void *dev_id)
 {
-	struct hv_device *device_ctx = device_to_hv_device(dev);
-	struct hv_device_info device_info;
+	int ret;
 
-	memset(&device_info, 0, sizeof(struct hv_device_info));
+	ret = vmbus_on_isr();
 
-	get_channel_info(device_ctx, &device_info);
+	/* Schedules a dpc if necessary */
+	if (ret > 0) {
+		if (test_bit(0, (unsigned long *)&ret))
+			tasklet_schedule(&msg_dpc);
 
-	if (!strcmp(dev_attr->attr.name, "class_id")) {
-		return sprintf(buf, "{%02x%02x%02x%02x-%02x%02x-%02x%02x-"
-			       "%02x%02x%02x%02x%02x%02x%02x%02x}\n",
-			       device_info.chn_type.data[3],
-			       device_info.chn_type.data[2],
-			       device_info.chn_type.data[1],
-			       device_info.chn_type.data[0],
-			       device_info.chn_type.data[5],
-			       device_info.chn_type.data[4],
-			       device_info.chn_type.data[7],
-			       device_info.chn_type.data[6],
-			       device_info.chn_type.data[8],
-			       device_info.chn_type.data[9],
-			       device_info.chn_type.data[10],
-			       device_info.chn_type.data[11],
-			       device_info.chn_type.data[12],
-			       device_info.chn_type.data[13],
-			       device_info.chn_type.data[14],
-			       device_info.chn_type.data[15]);
-	} else if (!strcmp(dev_attr->attr.name, "device_id")) {
-		return sprintf(buf, "{%02x%02x%02x%02x-%02x%02x-%02x%02x-"
-			       "%02x%02x%02x%02x%02x%02x%02x%02x}\n",
-			       device_info.chn_instance.data[3],
-			       device_info.chn_instance.data[2],
-			       device_info.chn_instance.data[1],
-			       device_info.chn_instance.data[0],
-			       device_info.chn_instance.data[5],
-			       device_info.chn_instance.data[4],
-			       device_info.chn_instance.data[7],
-			       device_info.chn_instance.data[6],
-			       device_info.chn_instance.data[8],
-			       device_info.chn_instance.data[9],
-			       device_info.chn_instance.data[10],
-			       device_info.chn_instance.data[11],
-			       device_info.chn_instance.data[12],
-			       device_info.chn_instance.data[13],
-			       device_info.chn_instance.data[14],
-			       device_info.chn_instance.data[15]);
-	} else if (!strcmp(dev_attr->attr.name, "state")) {
-		return sprintf(buf, "%d\n", device_info.chn_state);
-	} else if (!strcmp(dev_attr->attr.name, "id")) {
-		return sprintf(buf, "%d\n", device_info.chn_id);
-	} else if (!strcmp(dev_attr->attr.name, "out_intr_mask")) {
-		return sprintf(buf, "%d\n", device_info.outbound.int_mask);
-	} else if (!strcmp(dev_attr->attr.name, "out_read_index")) {
-		return sprintf(buf, "%d\n", device_info.outbound.read_idx);
-	} else if (!strcmp(dev_attr->attr.name, "out_write_index")) {
-		return sprintf(buf, "%d\n", device_info.outbound.write_idx);
-	} else if (!strcmp(dev_attr->attr.name, "out_read_bytes_avail")) {
-		return sprintf(buf, "%d\n",
-			       device_info.outbound.bytes_avail_toread);
-	} else if (!strcmp(dev_attr->attr.name, "out_write_bytes_avail")) {
-		return sprintf(buf, "%d\n",
-			       device_info.outbound.bytes_avail_towrite);
-	} else if (!strcmp(dev_attr->attr.name, "in_intr_mask")) {
-		return sprintf(buf, "%d\n", device_info.inbound.int_mask);
-	} else if (!strcmp(dev_attr->attr.name, "in_read_index")) {
-		return sprintf(buf, "%d\n", device_info.inbound.read_idx);
-	} else if (!strcmp(dev_attr->attr.name, "in_write_index")) {
-		return sprintf(buf, "%d\n", device_info.inbound.write_idx);
-	} else if (!strcmp(dev_attr->attr.name, "in_read_bytes_avail")) {
-		return sprintf(buf, "%d\n",
-			       device_info.inbound.bytes_avail_toread);
-	} else if (!strcmp(dev_attr->attr.name, "in_write_bytes_avail")) {
-		return sprintf(buf, "%d\n",
-			       device_info.inbound.bytes_avail_towrite);
-	} else if (!strcmp(dev_attr->attr.name, "monitor_id")) {
-		return sprintf(buf, "%d\n", device_info.monitor_id);
-	} else if (!strcmp(dev_attr->attr.name, "server_monitor_pending")) {
-		return sprintf(buf, "%d\n", device_info.server_monitor_pending);
-	} else if (!strcmp(dev_attr->attr.name, "server_monitor_latency")) {
-		return sprintf(buf, "%d\n", device_info.server_monitor_latency);
-	} else if (!strcmp(dev_attr->attr.name, "server_monitor_conn_id")) {
-		return sprintf(buf, "%d\n",
-			       device_info.server_monitor_conn_id);
-	} else if (!strcmp(dev_attr->attr.name, "client_monitor_pending")) {
-		return sprintf(buf, "%d\n", device_info.client_monitor_pending);
-	} else if (!strcmp(dev_attr->attr.name, "client_monitor_latency")) {
-		return sprintf(buf, "%d\n", device_info.client_monitor_latency);
-	} else if (!strcmp(dev_attr->attr.name, "client_monitor_conn_id")) {
-		return sprintf(buf, "%d\n",
-			       device_info.client_monitor_conn_id);
+		if (test_bit(1, (unsigned long *)&ret))
+			tasklet_schedule(&event_dpc);
+
+		return IRQ_HANDLED;
 	} else {
-		return 0;
+		return IRQ_NONE;
 	}
 }
 
@@ -416,148 +524,69 @@
  *
  * Here, we
  *	- initialize the vmbus driver context
- *	- setup various driver entry points
  *	- invoke the vmbus hv main init routine
  *	- get the irq resource
- *	- invoke the vmbus to add the vmbus root device
- *	- setup the vmbus root device
  *	- retrieve the channel offers
  */
-static int vmbus_bus_init(void)
+static int vmbus_bus_init(struct pci_dev *pdev)
 {
-	struct vmbus_driver_context *vmbus_drv_ctx = &vmbus_drv;
-	struct hv_device *dev_ctx = &vmbus_drv.device_ctx;
 	int ret;
 	unsigned int vector;
 
-	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 +++++++",
-			VMBUS_MESSAGE_SINT);
-	DPRINT_DBG(VMBUS, "sizeof(vmbus_channel_packet_page_buffer)=%zd, "
-			"sizeof(VMBUS_CHANNEL_PACKET_MULITPAGE_BUFFER)=%zd",
-			sizeof(struct vmbus_channel_packet_page_buffer),
-			sizeof(struct vmbus_channel_packet_multipage_buffer));
-
-
 	/* Hypervisor initialization...setup hypercall page..etc */
 	ret = hv_init();
 	if (ret != 0) {
-		DPRINT_ERR(VMBUS, "Unable to initialize the hypervisor - 0x%x",
-				ret);
+		pr_err("Unable to initialize the hypervisor - 0x%x\n", ret);
 		goto cleanup;
 	}
 
-
-	vmbus_drv_ctx->bus.name = driver_name;
-
 	/* Initialize the bus context */
-	tasklet_init(&vmbus_drv_ctx->msg_dpc, vmbus_on_msg_dpc,
-		     (unsigned long)NULL);
-	tasklet_init(&vmbus_drv_ctx->event_dpc, vmbus_on_event,
-		     (unsigned long)NULL);
+	tasklet_init(&msg_dpc, vmbus_on_msg_dpc, 0);
+	tasklet_init(&event_dpc, vmbus_on_event, 0);
 
 	/* Now, register the bus  with LDM */
-	ret = bus_register(&vmbus_drv_ctx->bus);
+	ret = bus_register(&hv_bus);
 	if (ret) {
 		ret = -1;
 		goto cleanup;
 	}
 
 	/* Get the interrupt resource */
-	ret = request_irq(vmbus_irq, vmbus_isr, IRQF_SAMPLE_RANDOM,
-			  driver_name, NULL);
-
-	if (ret != 0) {
-		DPRINT_ERR(VMBUS_DRV, "ERROR - Unable to request IRQ %d",
-			   vmbus_irq);
-
-		bus_unregister(&vmbus_drv_ctx->bus);
-
-		ret = -1;
-		goto cleanup;
-	}
-	vector = VMBUS_IRQ_VECTOR;
-
-	DPRINT_INFO(VMBUS_DRV, "irq 0x%x vector 0x%x", vmbus_irq, vector);
-
-	/* Add the root device */
-	memset(dev_ctx, 0, sizeof(struct hv_device));
+	ret = request_irq(pdev->irq, vmbus_isr,
+			  IRQF_SHARED | IRQF_SAMPLE_RANDOM,
+			  driver_name, pdev);
 
-	ret = vmbus_dev_add(dev_ctx, &vector);
 	if (ret != 0) {
-		DPRINT_ERR(VMBUS_DRV,
-			   "ERROR - Unable to add vmbus root device");
-
-		free_irq(vmbus_irq, NULL);
+		pr_err("Unable to request IRQ %d\n",
+			   pdev->irq);
 
-		bus_unregister(&vmbus_drv_ctx->bus);
+		bus_unregister(&hv_bus);
 
 		ret = -1;
 		goto cleanup;
 	}
-	/* strcpy(dev_ctx->device.bus_id, dev_ctx->device_obj.name); */
-	dev_set_name(&dev_ctx->device, "vmbus_0_0");
 
-	/* No need to bind a driver to the root device. */
-	dev_ctx->device.parent = NULL;
-	/* NULL; vmbus_remove() does not get invoked */
-	dev_ctx->device.bus = &vmbus_drv_ctx->bus;
-
-	/* Setup the device dispatch table */
-	dev_ctx->device.release = vmbus_bus_release;
+	vector = IRQ0_VECTOR + pdev->irq;
 
-	/* register the  root device */
-	ret = device_register(&dev_ctx->device);
+	/*
+	 * Notify the hypervisor of our irq and
+	 * connect to the host.
+	 */
+	on_each_cpu(hv_synic_init, (void *)&vector, 1);
+	ret = vmbus_connect();
 	if (ret) {
-		DPRINT_ERR(VMBUS_DRV,
-			   "ERROR - Unable to register vmbus root device");
-
-		free_irq(vmbus_irq, NULL);
-		bus_unregister(&vmbus_drv_ctx->bus);
-
-		ret = -1;
+		free_irq(pdev->irq, pdev);
+		bus_unregister(&hv_bus);
 		goto cleanup;
 	}
 
+
 	vmbus_request_offers();
-	wait_for_completion(&hv_channel_ready);
 
 cleanup:
 	return ret;
 }
 
-/*
- * vmbus_bus_exit - Terminate the vmbus driver.
- *
- * This routine is opposite of vmbus_bus_init()
- */
-static void vmbus_bus_exit(void)
-{
-	struct vmbus_driver_context *vmbus_drv_ctx = &vmbus_drv;
-
-	struct hv_device *dev_ctx = &vmbus_drv.device_ctx;
-
-	vmbus_release_unattached_channels();
-	vmbus_disconnect();
-	on_each_cpu(hv_synic_cleanup, NULL, 1);
-
-	hv_cleanup();
-
-	/* Unregister the root bus device */
-	device_unregister(&dev_ctx->device);
-
-	bus_unregister(&vmbus_drv_ctx->bus);
-
-	free_irq(vmbus_irq, NULL);
-
-	tasklet_kill(&vmbus_drv_ctx->msg_dpc);
-	tasklet_kill(&vmbus_drv_ctx->event_dpc);
-}
-
-
 /**
  * vmbus_child_driver_register() - Register a vmbus's child driver
  * @drv:        Pointer to driver structure you want to register
@@ -573,11 +602,10 @@
 {
 	int ret;
 
-	DPRINT_INFO(VMBUS_DRV, "child driver (%p) registering - name %s",
-		    drv, drv->name);
+	pr_info("child driver registering - name %s\n", drv->name);
 
 	/* The child driver on this vmbus */
-	drv->bus = &vmbus_drv.bus;
+	drv->bus = &hv_bus;
 
 	ret = driver_register(drv);
 
@@ -599,8 +627,7 @@
  */
 void vmbus_child_driver_unregister(struct device_driver *drv)
 {
-	DPRINT_INFO(VMBUS_DRV, "child driver (%p) unregistering - name %s",
-		    drv, drv->name);
+	pr_info("child driver unregistering - name %s\n", drv->name);
 
 	driver_unregister(drv);
 
@@ -621,30 +648,10 @@
 	/* Allocate the new child device */
 	child_device_obj = kzalloc(sizeof(struct hv_device), GFP_KERNEL);
 	if (!child_device_obj) {
-		DPRINT_ERR(VMBUS_DRV,
-			"unable to allocate device_context for child device");
+		pr_err("Unable to allocate device object for child device\n");
 		return NULL;
 	}
 
-	DPRINT_DBG(VMBUS_DRV, "child device (%p) allocated - "
-		"type {%02x%02x%02x%02x-%02x%02x-%02x%02x-"
-		"%02x%02x%02x%02x%02x%02x%02x%02x},"
-		"id {%02x%02x%02x%02x-%02x%02x-%02x%02x-"
-		"%02x%02x%02x%02x%02x%02x%02x%02x}",
-		&child_device_obj->device,
-		type->data[3], type->data[2], type->data[1], type->data[0],
-		type->data[5], type->data[4], type->data[7], type->data[6],
-		type->data[8], type->data[9], type->data[10], type->data[11],
-		type->data[12], type->data[13], type->data[14], type->data[15],
-		instance->data[3], instance->data[2],
-		instance->data[1], instance->data[0],
-		instance->data[5], instance->data[4],
-		instance->data[7], instance->data[6],
-		instance->data[8], instance->data[9],
-		instance->data[10], instance->data[11],
-		instance->data[12], instance->data[13],
-		instance->data[14], instance->data[15]);
-
 	child_device_obj->channel = channel;
 	memcpy(&child_device_obj->dev_type, type, sizeof(struct hv_guid));
 	memcpy(&child_device_obj->dev_instance, instance,
@@ -663,16 +670,13 @@
 
 	static atomic_t device_num = ATOMIC_INIT(0);
 
-	DPRINT_DBG(VMBUS_DRV, "child device (%p) registering",
-		   child_device_obj);
-
 	/* Set the device name. Otherwise, device_register() will fail. */
 	dev_set_name(&child_device_obj->device, "vmbus_0_%d",
 		     atomic_inc_return(&device_num));
 
 	/* The new device belongs to this bus */
-	child_device_obj->device.bus = &vmbus_drv.bus; /* device->dev.bus; */
-	child_device_obj->device.parent = &vmbus_device->device;
+	child_device_obj->device.bus = &hv_bus; /* device->dev.bus; */
+	child_device_obj->device.parent = &hv_pci_dev->dev;
 	child_device_obj->device.release = vmbus_device_release;
 
 	/*
@@ -681,15 +685,11 @@
 	 */
 	ret = device_register(&child_device_obj->device);
 
-	/* vmbus_probe() error does not get propergate to device_register(). */
-	ret = child_device_obj->probe_error;
-
 	if (ret)
-		DPRINT_ERR(VMBUS_DRV, "unable to register child device (%p)",
-			   &child_device_obj->device);
+		pr_err("Unable to register child device\n");
 	else
-		DPRINT_INFO(VMBUS_DRV, "child device (%p) registered",
-			    &child_device_obj->device);
+		pr_info("child device %s registered\n",
+			dev_name(&child_device_obj->device));
 
 	return ret;
 }
@@ -700,331 +700,171 @@
  */
 void vmbus_child_device_unregister(struct hv_device *device_obj)
 {
-
-	DPRINT_INFO(VMBUS_DRV, "unregistering child device (%p)",
-		    &device_obj->device);
-
 	/*
 	 * Kick off the process of unregistering the device.
 	 * This will call vmbus_remove() and eventually vmbus_device_release()
 	 */
 	device_unregister(&device_obj->device);
 
-	DPRINT_INFO(VMBUS_DRV, "child device (%p) unregistered",
-		    &device_obj->device);
+	pr_info("child device %s unregistered\n",
+		dev_name(&device_obj->device));
 }
 
+
 /*
- * vmbus_uevent - add uevent for our device
- *
- * This routine is invoked when a device is added or removed on the vmbus to
- * generate a uevent to udev in the userspace. The udev will then look at its
- * rule and the uevent generated here to load the appropriate driver
+ * VMBUS is an acpi enumerated device. Get the the IRQ information
+ * from DSDT.
  */
-static int vmbus_uevent(struct device *device, struct kobj_uevent_env *env)
-{
-	struct hv_device *dev = device_to_hv_device(device);
-	int ret;
-
-	DPRINT_INFO(VMBUS_DRV, "generating uevent - VMBUS_DEVICE_CLASS_GUID={"
-		    "%02x%02x%02x%02x-%02x%02x-%02x%02x-"
-		    "%02x%02x%02x%02x%02x%02x%02x%02x}",
-		    dev->dev_type.data[3], dev->dev_type.data[2],
-		    dev->dev_type.data[1], dev->dev_type.data[0],
-		    dev->dev_type.data[5], dev->dev_type.data[4],
-		    dev->dev_type.data[7], dev->dev_type.data[6],
-		    dev->dev_type.data[8], dev->dev_type.data[9],
-		    dev->dev_type.data[10],
-		    dev->dev_type.data[11],
-		    dev->dev_type.data[12],
-		    dev->dev_type.data[13],
-		    dev->dev_type.data[14],
-		    dev->dev_type.data[15]);
 
-	ret = add_uevent_var(env, "VMBUS_DEVICE_CLASS_GUID={"
-			     "%02x%02x%02x%02x-%02x%02x-%02x%02x-"
-			     "%02x%02x%02x%02x%02x%02x%02x%02x}",
-			     dev->dev_type.data[3],
-			     dev->dev_type.data[2],
-			     dev->dev_type.data[1],
-			     dev->dev_type.data[0],
-			     dev->dev_type.data[5],
-			     dev->dev_type.data[4],
-			     dev->dev_type.data[7],
-			     dev->dev_type.data[6],
-			     dev->dev_type.data[8],
-			     dev->dev_type.data[9],
-			     dev->dev_type.data[10],
-			     dev->dev_type.data[11],
-			     dev->dev_type.data[12],
-			     dev->dev_type.data[13],
-			     dev->dev_type.data[14],
-			     dev->dev_type.data[15]);
+static acpi_status vmbus_walk_resources(struct acpi_resource *res, void *irq)
+{
 
-	if (ret)
-		return ret;
+	if (res->type == ACPI_RESOURCE_TYPE_IRQ) {
+		struct acpi_resource_irq *irqp;
+		irqp = &res->data.irq;
 
-	ret = add_uevent_var(env, "VMBUS_DEVICE_DEVICE_GUID={"
-			     "%02x%02x%02x%02x-%02x%02x-%02x%02x-"
-			     "%02x%02x%02x%02x%02x%02x%02x%02x}",
-			     dev->dev_instance.data[3],
-			     dev->dev_instance.data[2],
-			     dev->dev_instance.data[1],
-			     dev->dev_instance.data[0],
-			     dev->dev_instance.data[5],
-			     dev->dev_instance.data[4],
-			     dev->dev_instance.data[7],
-			     dev->dev_instance.data[6],
-			     dev->dev_instance.data[8],
-			     dev->dev_instance.data[9],
-			     dev->dev_instance.data[10],
-			     dev->dev_instance.data[11],
-			     dev->dev_instance.data[12],
-			     dev->dev_instance.data[13],
-			     dev->dev_instance.data[14],
-			     dev->dev_instance.data[15]);
-	if (ret)
-		return ret;
+		*((unsigned int *)irq) = irqp->interrupts[0];
+	}
 
-	return 0;
+	return AE_OK;
 }
 
-/*
- * vmbus_match - Attempt to match the specified device to the specified driver
- */
-static int vmbus_match(struct device *device, struct device_driver *driver)
+static int vmbus_acpi_add(struct acpi_device *device)
 {
-	int match = 0;
-	struct hv_driver *drv = drv_to_hv_drv(driver);
-	struct hv_device *device_ctx = device_to_hv_device(device);
-
-	/* We found our driver ? */
-	if (memcmp(&device_ctx->dev_type, &drv->dev_type,
-		   sizeof(struct hv_guid)) == 0) {
+	acpi_status result;
 
-		device_ctx->drv = drv->priv;
-		DPRINT_INFO(VMBUS_DRV,
-			    "device object (%p) set to driver object (%p)",
-			    &device_ctx,
-			    device_ctx->drv);
+	result =
+	acpi_walk_resources(device->handle, METHOD_NAME__CRS,
+			vmbus_walk_resources, &irq);
 
-		match = 1;
+	if (ACPI_FAILURE(result)) {
+		complete(&probe_event);
+		return -ENODEV;
 	}
-	return match;
+	complete(&probe_event);
+	return 0;
 }
 
-/*
- * vmbus_probe_failed_cb - Callback when a driver probe failed in vmbus_probe()
- *
- * We need a callback because we cannot invoked device_unregister() inside
- * vmbus_probe() since vmbus_probe() may be invoked inside device_register()
- * i.e. we cannot call device_unregister() inside device_register()
- */
-static void vmbus_probe_failed_cb(struct work_struct *context)
-{
-	struct hv_device *device_ctx = (struct hv_device *)context;
-
-	/*
-	 * Kick off the process of unregistering the device.
-	 * This will call vmbus_remove() and eventually vmbus_device_release()
-	 */
-	device_unregister(&device_ctx->device);
+static const struct acpi_device_id vmbus_acpi_device_ids[] = {
+	{"VMBUS", 0},
+	{"", 0},
+};
+MODULE_DEVICE_TABLE(acpi, vmbus_acpi_device_ids);
 
-	/* put_device(&device_ctx->device); */
-}
+static struct acpi_driver vmbus_acpi_driver = {
+	.name = "vmbus",
+	.ids = vmbus_acpi_device_ids,
+	.ops = {
+		.add = vmbus_acpi_add,
+	},
+};
 
-/*
- * vmbus_probe - Add the new vmbus's child device
- */
-static int vmbus_probe(struct device *child_device)
+static int vmbus_acpi_init(void)
 {
-	int ret = 0;
-	struct hv_driver *drv =
-			drv_to_hv_drv(child_device->driver);
-	struct hv_device *dev = device_to_hv_device(child_device);
+	int result;
 
-	/* Let the specific open-source driver handles the probe if it can */
-	if (drv->driver.probe) {
-		ret = dev->probe_error =
-		drv->driver.probe(child_device);
-		if (ret != 0) {
-			DPRINT_ERR(VMBUS_DRV, "probe() failed for device %s "
-				   "(%p) on driver %s (%d)...",
-				   dev_name(child_device), child_device,
-				   child_device->driver->name, ret);
 
-			INIT_WORK(&dev->probe_failed_work_item,
-				  vmbus_probe_failed_cb);
-			schedule_work(&dev->probe_failed_work_item);
-		}
-	} else {
-		DPRINT_ERR(VMBUS_DRV, "probe() method not set for driver - %s",
-			   child_device->driver->name);
-		ret = -1;
-	}
-	return ret;
+	result = acpi_bus_register_driver(&vmbus_acpi_driver);
+	if (result < 0)
+		return result;
+
+	return 0;
 }
 
-/*
- * vmbus_remove - Remove a vmbus device
- */
-static int vmbus_remove(struct device *child_device)
+static void vmbus_acpi_exit(void)
 {
-	int ret;
-	struct hv_driver *drv;
-
-	/* Special case root bus device */
-	if (child_device->parent == NULL) {
-		/*
-		 * No-op since it is statically defined and handle in
-		 * vmbus_bus_exit()
-		 */
-		return 0;
-	}
-
-	if (child_device->driver) {
-		drv = drv_to_hv_drv(child_device->driver);
-
-		/*
-		 * Let the specific open-source driver handles the removal if
-		 * it can
-		 */
-		if (drv->driver.remove) {
-			ret = drv->driver.remove(child_device);
-		} else {
-			DPRINT_ERR(VMBUS_DRV,
-				   "remove() method not set for driver - %s",
-				   child_device->driver->name);
-			ret = -1;
-		}
-	}
+	acpi_bus_unregister_driver(&vmbus_acpi_driver);
 
-	return 0;
+	return;
 }
 
-/*
- * vmbus_shutdown - Shutdown a vmbus device
- */
-static void vmbus_shutdown(struct device *child_device)
+
+static int __devinit hv_pci_probe(struct pci_dev *pdev,
+				const struct pci_device_id *ent)
 {
-	struct hv_driver *drv;
+	hv_pci_dev = pdev;
 
-	/* Special case root bus device */
-	if (child_device->parent == NULL) {
-		/*
-		 * No-op since it is statically defined and handle in
-		 * vmbus_bus_exit()
-		 */
-		return;
-	}
+	pci_probe_error = pci_enable_device(pdev);
+	if (pci_probe_error)
+		goto probe_cleanup;
 
-	/* The device may not be attached yet */
-	if (!child_device->driver)
-		return;
+	/*
+	 * If the PCI sub-sytem did not assign us an
+	 * irq, use the bios provided one.
+	 */
 
-	drv = drv_to_hv_drv(child_device->driver);
+	if (pdev->irq == 0)
+		pdev->irq = irq;
 
-	/* Let the specific open-source driver handles the removal if it can */
-	if (drv->driver.shutdown)
-		drv->driver.shutdown(child_device);
+	pci_probe_error = vmbus_bus_init(pdev);
 
-	return;
-}
+	if (pci_probe_error)
+		pci_disable_device(pdev);
 
-/*
- * vmbus_bus_release - Final callback release of the vmbus root device
- */
-static void vmbus_bus_release(struct device *device)
-{
-	/* FIXME */
-	/* Empty release functions are a bug, or a major sign
-	 * of a problem design, this MUST BE FIXED! */
-	dev_err(device, "%s needs to be fixed!\n", __func__);
-	WARN_ON(1);
+probe_cleanup:
+	complete(&probe_event);
+	return pci_probe_error;
 }
 
 /*
- * vmbus_device_release - Final callback release of the vmbus child device
+ * 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.
  */
-static void vmbus_device_release(struct device *device)
-{
-	struct hv_device *device_ctx = device_to_hv_device(device);
-
-	kfree(device_ctx);
-
-	/* !!DO NOT REFERENCE device_ctx anymore at this point!! */
-}
-
+static const struct pci_device_id microsoft_hv_pci_table[] = {
+	{ PCI_DEVICE(0x1414, 0x5353) },	/* VGA compatible controller */
+	{ 0 }
+};
+MODULE_DEVICE_TABLE(pci, microsoft_hv_pci_table);
 
+static struct pci_driver hv_bus_driver = {
+	.name =           "hv_bus",
+	.probe =          hv_pci_probe,
+	.id_table =       microsoft_hv_pci_table,
+};
 
-static irqreturn_t vmbus_isr(int irq, void *dev_id)
+static int __init hv_pci_init(void)
 {
 	int ret;
 
-	ret = vmbus_on_isr();
-
-	/* Schedules a dpc if necessary */
-	if (ret > 0) {
-		if (test_bit(0, (unsigned long *)&ret))
-			tasklet_schedule(&vmbus_drv.msg_dpc);
-
-		if (test_bit(1, (unsigned long *)&ret))
-			tasklet_schedule(&vmbus_drv.event_dpc);
+	init_completion(&probe_event);
 
-		return IRQ_HANDLED;
-	} else {
-		return IRQ_NONE;
-	}
-}
+	/*
+	 * Get irq resources first.
+	 */
 
-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);
+	ret = vmbus_acpi_init();
+	if (ret)
+		return ret;
 
-static int __init vmbus_init(void)
-{
-	DPRINT_INFO(VMBUS_DRV,
-		"Vmbus initializing.... current log level 0x%x (%x,%x)",
-		vmbus_loglevel, HIWORD(vmbus_loglevel), LOWORD(vmbus_loglevel));
-	/* Todo: it is used for loglevel, to be ported to new kernel. */
+	wait_for_completion(&probe_event);
 
-	if (!dmi_check_system(microsoft_hv_dmi_table))
+	if (irq <= 0) {
+		vmbus_acpi_exit();
 		return -ENODEV;
+	}
 
-	return vmbus_bus_init();
-}
+	vmbus_acpi_exit();
+	init_completion(&probe_event);
+	ret = pci_register_driver(&hv_bus_driver);
+	if (ret)
+		return ret;
+	/*
+	 * All the vmbus initialization occurs within the
+	 * hv_pci_probe() function. Wait for hv_pci_probe()
+	 * to complete.
+	 */
+	wait_for_completion(&probe_event);
 
-static void __exit vmbus_exit(void)
-{
-	vmbus_bus_exit();
-	/* Todo: it is used for loglevel, to be ported to new kernel. */
+	if (pci_probe_error)
+		pci_unregister_driver(&hv_bus_driver);
+	return pci_probe_error;
 }
 
-/*
- * 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.
- */
-static const 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);
+module_param(vmbus_loglevel, int, S_IRUGO|S_IWUSR);
 
-module_init(vmbus_init);
-module_exit(vmbus_exit);
+module_init(hv_pci_init);
diff -druN linux-2.6.39-libre/drivers/staging/hv/vmbus.h linux-3.0-rc7-libre/drivers/staging/hv/vmbus.h
--- linux-2.6.39-libre/drivers/staging/hv/vmbus.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/hv/vmbus.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,51 +0,0 @@
-/*
- *
- * Copyright (c) 2009, Microsoft 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., 59 Temple
- * Place - Suite 330, Boston, MA 02111-1307 USA.
- *
- * Authors:
- *   Haiyang Zhang <haiyangz@microsoft.com>
- *   Hank Janssen  <hjanssen@microsoft.com>
- *
- */
-
-
-#ifndef _VMBUS_H_
-#define _VMBUS_H_
-
-#include <linux/device.h>
-#include "vmbus_api.h"
-
-
-
-
-static inline struct hv_device *device_to_hv_device(struct device *d)
-{
-	return container_of(d, struct hv_device, device);
-}
-
-static inline struct hv_driver *drv_to_hv_drv(struct device_driver *d)
-{
-	return container_of(d, struct hv_driver, driver);
-}
-
-
-/* Vmbus interface */
-int vmbus_child_driver_register(struct device_driver *drv);
-void vmbus_child_driver_unregister(struct device_driver *drv);
-
-extern struct completion hv_channel_ready;
-
-#endif /* _VMBUS_H_ */
diff -druN linux-2.6.39-libre/drivers/staging/hv/vmbus_packet_format.h linux-3.0-rc7-libre/drivers/staging/hv/vmbus_packet_format.h
--- linux-2.6.39-libre/drivers/staging/hv/vmbus_packet_format.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/hv/vmbus_packet_format.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,161 +0,0 @@
-/*
- *
- * Copyright (c) 2009, Microsoft 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., 59 Temple
- * Place - Suite 330, Boston, MA 02111-1307 USA.
- *
- * Authors:
- *   Haiyang Zhang <haiyangz@microsoft.com>
- *   Hank Janssen  <hjanssen@microsoft.com>
- *
- */
-
-#ifndef _VMBUSPACKETFORMAT_H_
-#define _VMBUSPACKETFORMAT_H_
-
-struct vmpacket_descriptor {
-	u16 type;
-	u16 offset8;
-	u16 len8;
-	u16 flags;
-	u64 trans_id;
-} __packed;
-
-struct vmpacket_header {
-	u32 prev_pkt_start_offset;
-	struct vmpacket_descriptor descriptor;
-} __packed;
-
-struct vmtransfer_page_range {
-	u32 byte_count;
-	u32 byte_offset;
-} __packed;
-
-struct vmtransfer_page_packet_header {
-	struct vmpacket_descriptor d;
-	u16 xfer_pageset_id;
-	bool sender_owns_set;
-	u8 reserved;
-	u32 range_cnt;
-	struct vmtransfer_page_range ranges[1];
-} __packed;
-
-struct vmgpadl_packet_header {
-	struct vmpacket_descriptor d;
-	u32 gpadl;
-	u32 reserved;
-} __packed;
-
-struct vmadd_remove_transfer_page_set {
-	struct vmpacket_descriptor d;
-	u32 gpadl;
-	u16 xfer_pageset_id;
-	u16 reserved;
-} __packed;
-
-/*
- * This structure defines a range in guest physical space that can be made to
- * look virtually contiguous.
- */
-struct gpa_range {
-	u32 byte_count;
-	u32 byte_offset;
-	u64 pfn_array[0];
-};
-
-/*
- * This is the format for an Establish Gpadl packet, which contains a handle by
- * which this GPADL will be known and a set of GPA ranges associated with it.
- * This can be converted to a MDL by the guest OS.  If there are multiple GPA
- * ranges, then the resulting MDL will be "chained," representing multiple VA
- * ranges.
- */
-struct vmestablish_gpadl {
-	struct vmpacket_descriptor d;
-	u32 gpadl;
-	u32 range_cnt;
-	struct gpa_range range[1];
-} __packed;
-
-/*
- * This is the format for a Teardown Gpadl packet, which indicates that the
- * GPADL handle in the Establish Gpadl packet will never be referenced again.
- */
-struct vmteardown_gpadl {
-	struct vmpacket_descriptor d;
-	u32 gpadl;
-	u32 reserved;	/* for alignment to a 8-byte boundary */
-} __packed;
-
-/*
- * This is the format for a GPA-Direct packet, which contains a set of GPA
- * ranges, in addition to commands and/or data.
- */
-struct vmdata_gpa_direct {
-	struct vmpacket_descriptor d;
-	u32 reserved;
-	u32 range_cnt;
-	struct gpa_range range[1];
-} __packed;
-
-/* This is the format for a Additional Data Packet. */
-struct vmadditional_data {
-	struct vmpacket_descriptor d;
-	u64 total_bytes;
-	u32 offset;
-	u32 byte_cnt;
-	unsigned char data[1];
-} __packed;
-
-union vmpacket_largest_possible_header {
-	struct vmpacket_descriptor simple_hdr;
-	struct vmtransfer_page_packet_header xfer_page_hdr;
-	struct vmgpadl_packet_header gpadl_hdr;
-	struct vmadd_remove_transfer_page_set add_rm_xfer_page_hdr;
-	struct vmestablish_gpadl establish_gpadl_hdr;
-	struct vmteardown_gpadl teardown_gpadl_hdr;
-	struct vmdata_gpa_direct data_gpa_direct_hdr;
-};
-
-#define VMPACKET_DATA_START_ADDRESS(__packet)	\
-	(void *)(((unsigned char *)__packet) +	\
-	 ((struct vmpacket_descriptor)__packet)->offset8 * 8)
-
-#define VMPACKET_DATA_LENGTH(__packet)		\
-	((((struct vmpacket_descriptor)__packet)->len8 -	\
-	  ((struct vmpacket_descriptor)__packet)->offset8) * 8)
-
-#define VMPACKET_TRANSFER_MODE(__packet)	\
-	(((struct IMPACT)__packet)->type)
-
-enum vmbus_packet_type {
-	VM_PKT_INVALID				= 0x0,
-	VM_PKT_SYNCH				= 0x1,
-	VM_PKT_ADD_XFER_PAGESET			= 0x2,
-	VM_PKT_RM_XFER_PAGESET			= 0x3,
-	VM_PKT_ESTABLISH_GPADL			= 0x4,
-	VM_PKT_TEARDOWN_GPADL			= 0x5,
-	VM_PKT_DATA_INBAND			= 0x6,
-	VM_PKT_DATA_USING_XFER_PAGES		= 0x7,
-	VM_PKT_DATA_USING_GPADL			= 0x8,
-	VM_PKT_DATA_USING_GPA_DIRECT		= 0x9,
-	VM_PKT_CANCEL_REQUEST			= 0xa,
-	VM_PKT_COMP				= 0xb,
-	VM_PKT_DATA_USING_ADDITIONAL_PKT	= 0xc,
-	VM_PKT_ADDITIONAL_DATA			= 0xd
-};
-
-#define VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED	1
-
-#endif
diff -druN linux-2.6.39-libre/drivers/staging/hv/vmbus_private.h linux-3.0-rc7-libre/drivers/staging/hv/vmbus_private.h
--- linux-2.6.39-libre/drivers/staging/hv/vmbus_private.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/hv/vmbus_private.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,134 +0,0 @@
-/*
- *
- * Copyright (c) 2009, Microsoft 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., 59 Temple
- * Place - Suite 330, Boston, MA 02111-1307 USA.
- *
- * Authors:
- *   Haiyang Zhang <haiyangz@microsoft.com>
- *   Hank Janssen  <hjanssen@microsoft.com>
- *
- */
-
-
-#ifndef _VMBUS_PRIVATE_H_
-#define _VMBUS_PRIVATE_H_
-
-#include "hv.h"
-#include "vmbus_api.h"
-#include "channel.h"
-#include "channel_mgmt.h"
-#include "ring_buffer.h"
-#include <linux/list.h>
-#include <asm/sync_bitops.h>
-
-
-/*
- * Maximum channels is determined by the size of the interrupt page
- * which is PAGE_SIZE. 1/2 of PAGE_SIZE is for send endpoint interrupt
- * and the other is receive endpoint interrupt
- */
-#define MAX_NUM_CHANNELS	((PAGE_SIZE >> 1) << 3)	/* 16348 channels */
-
-/* The value here must be in multiple of 32 */
-/* TODO: Need to make this configurable */
-#define MAX_NUM_CHANNELS_SUPPORTED	256
-
-
-enum vmbus_connect_state {
-	DISCONNECTED,
-	CONNECTING,
-	CONNECTED,
-	DISCONNECTING
-};
-
-#define MAX_SIZE_CHANNEL_MESSAGE	HV_MESSAGE_PAYLOAD_BYTE_COUNT
-
-struct vmbus_connection {
-	enum vmbus_connect_state conn_state;
-
-	atomic_t next_gpadl_handle;
-
-	/*
-	 * Represents channel interrupts. Each bit position represents a
-	 * channel.  When a channel sends an interrupt via VMBUS, it finds its
-	 * bit in the sendInterruptPage, set it and calls Hv to generate a port
-	 * event. The other end receives the port event and parse the
-	 * recvInterruptPage to see which bit is set
-	 */
-	void *int_page;
-	void *send_int_page;
-	void *recv_int_page;
-
-	/*
-	 * 2 pages - 1st page for parent->child notification and 2nd
-	 * is child->parent notification
-	 */
-	void *monitor_pages;
-	struct list_head chn_msg_list;
-	spinlock_t channelmsg_lock;
-
-	/* List of channels */
-	struct list_head chn_list;
-	spinlock_t channel_lock;
-
-	struct workqueue_struct *work_queue;
-};
-
-
-struct vmbus_msginfo {
-	/* Bookkeeping stuff */
-	struct list_head msglist_entry;
-
-	/* Synchronize the request/response if needed */
-	int wait_condition;
-	wait_queue_head_t  wait_event;
-
-	/* The message itself */
-	unsigned char msg[0];
-};
-
-
-extern struct vmbus_connection vmbus_connection;
-
-/* General vmbus interface */
-
-struct hv_device *vmbus_child_device_create(struct hv_guid *type,
-					 struct hv_guid *instance,
-					 struct vmbus_channel *channel);
-
-int vmbus_child_device_register(struct hv_device *child_device_obj);
-void vmbus_child_device_unregister(struct hv_device *device_obj);
-
-/* static void */
-/* VmbusChildDeviceDestroy( */
-/* struct hv_device *); */
-
-struct vmbus_channel *relid2channel(u32 relid);
-
-
-/* Connection interface */
-
-int vmbus_connect(void);
-
-int vmbus_disconnect(void);
-
-int vmbus_post_msg(void *buffer, size_t buflen);
-
-int vmbus_set_event(u32 child_relid);
-
-void vmbus_on_event(unsigned long data);
-
-
-#endif /* _VMBUS_PRIVATE_H_ */
diff -druN linux-2.6.39-libre/drivers/staging/hv/vstorage.h linux-3.0-rc7-libre/drivers/staging/hv/vstorage.h
--- linux-2.6.39-libre/drivers/staging/hv/vstorage.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/hv/vstorage.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,192 +0,0 @@
-/*
- *
- * Copyright (c) 2009, Microsoft 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., 59 Temple
- * Place - Suite 330, Boston, MA 02111-1307 USA.
- *
- * Authors:
- *   Haiyang Zhang <haiyangz@microsoft.com>
- *   Hank Janssen  <hjanssen@microsoft.com>
- *
- */
-
-/* vstorage.w revision number.  This is used in the case of a version match, */
-/* to alert the user that structure sizes may be mismatched even though the */
-/* protocol versions match. */
-
-#define REVISION_STRING(REVISION_) #REVISION_
-#define FILL_VMSTOR_REVISION(RESULT_LVALUE_)				\
-	do {								\
-		char *revision_string					\
-			= REVISION_STRING($Rev : 6 $) + 6;		\
-		RESULT_LVALUE_ = 0;					\
-		while (*revision_string >= '0'				\
-			&& *revision_string <= '9') {			\
-			RESULT_LVALUE_ *= 10;				\
-			RESULT_LVALUE_ += *revision_string - '0';	\
-			revision_string++;				\
-		}							\
-	} while (0)
-
-/* Major/minor macros.  Minor version is in LSB, meaning that earlier flat */
-/* version numbers will be interpreted as "0.x" (i.e., 1 becomes 0.1). */
-#define VMSTOR_PROTOCOL_MAJOR(VERSION_)		(((VERSION_) >> 8) & 0xff)
-#define VMSTOR_PROTOCOL_MINOR(VERSION_)		(((VERSION_))      & 0xff)
-#define VMSTOR_PROTOCOL_VERSION(MAJOR_, MINOR_)	((((MAJOR_) & 0xff) << 8) | \
-						 (((MINOR_) & 0xff)))
-#define VMSTOR_INVALID_PROTOCOL_VERSION		(-1)
-
-/* Version history: */
-/* V1 Beta                    0.1 */
-/* V1 RC < 2008/1/31          1.0 */
-/* V1 RC > 2008/1/31          2.0 */
-#define VMSTOR_PROTOCOL_VERSION_CURRENT VMSTOR_PROTOCOL_VERSION(2, 0)
-
-
-
-
-/*  This will get replaced with the max transfer length that is possible on */
-/*  the host adapter. */
-/*  The max transfer length will be published when we offer a vmbus channel. */
-#define MAX_TRANSFER_LENGTH	0x40000
-#define DEFAULT_PACKET_SIZE (sizeof(struct vmdata_gpa_direct) +	\
-			sizeof(struct vstor_packet) +		\
-			sizesizeof(u64) * (MAX_TRANSFER_LENGTH / PAGE_SIZE)))
-
-
-/*  Packet structure describing virtual storage requests. */
-enum vstor_packet_operation {
-	VSTOR_OPERATION_COMPLETE_IO		= 1,
-	VSTOR_OPERATION_REMOVE_DEVICE		= 2,
-	VSTOR_OPERATION_EXECUTE_SRB		= 3,
-	VSTOR_OPERATION_RESET_LUN		= 4,
-	VSTOR_OPERATION_RESET_ADAPTER		= 5,
-	VSTOR_OPERATION_RESET_BUS		= 6,
-	VSTOR_OPERATION_BEGIN_INITIALIZATION	= 7,
-	VSTOR_OPERATION_END_INITIALIZATION	= 8,
-	VSTOR_OPERATION_QUERY_PROTOCOL_VERSION	= 9,
-	VSTOR_OPERATION_QUERY_PROPERTIES	= 10,
-	VSTOR_OPERATION_MAXIMUM			= 10
-};
-
-/*
- * Platform neutral description of a scsi request -
- * this remains the same across the write regardless of 32/64 bit
- * note: it's patterned off the SCSI_PASS_THROUGH structure
- */
-#define CDB16GENERIC_LENGTH			0x10
-
-#ifndef SENSE_BUFFER_SIZE
-#define SENSE_BUFFER_SIZE			0x12
-#endif
-
-#define MAX_DATA_BUF_LEN_WITH_PADDING		0x14
-
-struct vmscsi_request {
-	unsigned short length;
-	unsigned char srb_status;
-	unsigned char scsi_status;
-
-	unsigned char port_number;
-	unsigned char path_id;
-	unsigned char target_id;
-	unsigned char lun;
-
-	unsigned char cdb_length;
-	unsigned char sense_info_length;
-	unsigned char data_in;
-	unsigned char reserved;
-
-	unsigned int data_transfer_length;
-
-	union {
-		unsigned char cdb[CDB16GENERIC_LENGTH];
-		unsigned char sense_data[SENSE_BUFFER_SIZE];
-		unsigned char reserved_array[MAX_DATA_BUF_LEN_WITH_PADDING];
-	};
-} __attribute((packed));
-
-
-/*
- * This structure is sent during the intialization phase to get the different
- * properties of the channel.
- */
-struct vmstorage_channel_properties {
-	unsigned short protocol_version;
-	unsigned char path_id;
-	unsigned char target_id;
-
-	/* Note: port number is only really known on the client side */
-	unsigned int port_number;
-	unsigned int flags;
-	unsigned int max_transfer_bytes;
-
-	/*  This id is unique for each channel and will correspond with */
-	/*  vendor specific data in the inquirydata */
-	unsigned long long unique_id;
-} __packed;
-
-/*  This structure is sent during the storage protocol negotiations. */
-struct vmstorage_protocol_version {
-	/* Major (MSW) and minor (LSW) version numbers. */
-	unsigned short major_minor;
-
-	/*
-	 * Revision number is auto-incremented whenever this file is changed
-	 * (See FILL_VMSTOR_REVISION macro above).  Mismatch does not
-	 * definitely indicate incompatibility--but it does indicate mismatched
-	 * builds.
-	 */
-	unsigned short revision;
-} __packed;
-
-/* Channel Property Flags */
-#define STORAGE_CHANNEL_REMOVABLE_FLAG		0x1
-#define STORAGE_CHANNEL_EMULATED_IDE_FLAG	0x2
-
-struct vstor_packet {
-	/* Requested operation type */
-	enum vstor_packet_operation operation;
-
-	/*  Flags - see below for values */
-	unsigned int flags;
-
-	/* Status of the request returned from the server side. */
-	unsigned int status;
-
-	/* Data payload area */
-	union {
-		/*
-		 * Structure used to forward SCSI commands from the
-		 * client to the server.
-		 */
-		struct vmscsi_request vm_srb;
-
-		/* Structure used to query channel properties. */
-		struct vmstorage_channel_properties storage_channel_properties;
-
-		/* Used during version negotiations. */
-		struct vmstorage_protocol_version version;
-	};
-} __packed;
-
-/* Packet flags */
-/*
- * This flag indicates that the server should send back a completion for this
- * packet.
- */
-#define REQUEST_COMPLETION_FLAG	0x1
-
-/*  This is the set of flags that the vsc can set in any packets it sends */
-#define VSC_LEGAL_FLAGS		(REQUEST_COMPLETION_FLAG)
diff -druN linux-2.6.39-libre/drivers/staging/iio/accel/adis16201_core.c linux-3.0-rc7-libre/drivers/staging/iio/accel/adis16201_core.c
--- linux-2.6.39-libre/drivers/staging/iio/accel/adis16201_core.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/iio/accel/adis16201_core.c	2011-07-11 19:51:52.000000000 -0400
@@ -6,9 +6,6 @@
  * Licensed under the GPL-2 or later.
  */
 
-#include <linux/interrupt.h>
-#include <linux/irq.h>
-#include <linux/gpio.h>
 #include <linux/delay.h>
 #include <linux/mutex.h>
 #include <linux/device.h>
@@ -16,20 +13,28 @@
 #include <linux/spi/spi.h>
 #include <linux/slab.h>
 #include <linux/sysfs.h>
-#include <linux/list.h>
 
 #include "../iio.h"
 #include "../sysfs.h"
+#include "../ring_generic.h"
+
 #include "accel.h"
 #include "inclinometer.h"
-#include "../gyro/gyro.h"
 #include "../adc/adc.h"
 
 #include "adis16201.h"
 
 #define DRIVER_NAME		"adis16201"
 
-static int adis16201_check_status(struct device *dev);
+enum adis16201_chan {
+	in_supply,
+	temp,
+	accel_x,
+	accel_y,
+	incli_x,
+	incli_y,
+	in_aux,
+};
 
 /**
  * adis16201_spi_write_reg_8() - write single byte to a register
@@ -57,18 +62,17 @@
 
 /**
  * adis16201_spi_write_reg_16() - write 2 bytes to a pair of registers
- * @dev: device associated with child of actual device (iio_dev or iio_trig)
+ * @indio_dev: iio device associated with child of actual device
  * @reg_address: the address of the lower of the two registers. Second register
  *               is assumed to have address one greater.
  * @val: value to be written
  **/
-static int adis16201_spi_write_reg_16(struct device *dev,
-		u8 lower_reg_address,
-		u16 value)
+static int adis16201_spi_write_reg_16(struct iio_dev *indio_dev,
+				      u8 lower_reg_address,
+				      u16 value)
 {
 	int ret;
 	struct spi_message msg;
-	struct iio_dev *indio_dev = dev_get_drvdata(dev);
 	struct adis16201_state *st = iio_dev_get_devdata(indio_dev);
 	struct spi_transfer xfers[] = {
 		{
@@ -80,7 +84,6 @@
 			.tx_buf = st->tx + 2,
 			.bits_per_word = 8,
 			.len = 2,
-			.cs_change = 1,
 		},
 	};
 
@@ -101,17 +104,16 @@
 
 /**
  * adis16201_spi_read_reg_16() - read 2 bytes from a 16-bit register
- * @dev: device associated with child of actual device (iio_dev or iio_trig)
+ * @indio_dev: iio device associated with child of actual device
  * @reg_address: the address of the lower of the two registers. Second register
  *               is assumed to have address one greater.
  * @val: somewhere to pass back the value read
  **/
-static int adis16201_spi_read_reg_16(struct device *dev,
+static int adis16201_spi_read_reg_16(struct iio_dev *indio_dev,
 		u8 lower_reg_address,
 		u16 *val)
 {
 	struct spi_message msg;
-	struct iio_dev *indio_dev = dev_get_drvdata(dev);
 	struct adis16201_state *st = iio_dev_get_devdata(indio_dev);
 	int ret;
 	struct spi_transfer xfers[] = {
@@ -125,7 +127,6 @@
 			.rx_buf = st->rx,
 			.bits_per_word = 8,
 			.len = 2,
-			.cs_change = 1,
 			.delay_usecs = 20,
 		},
 	};
@@ -150,160 +151,6 @@
 	return ret;
 }
 
-static ssize_t adis16201_read_12bit_unsigned(struct device *dev,
-		struct device_attribute *attr,
-		char *buf)
-{
-	int ret;
-	u16 val = 0;
-	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
-
-	ret = adis16201_spi_read_reg_16(dev, this_attr->address, &val);
-	if (ret)
-		return ret;
-
-	if (val & ADIS16201_ERROR_ACTIVE) {
-		ret = adis16201_check_status(dev);
-		if (ret)
-			return ret;
-	}
-
-	return sprintf(buf, "%u\n", val & 0x0FFF);
-}
-
-static ssize_t adis16201_read_temp(struct device *dev,
-		struct device_attribute *attr,
-		char *buf)
-{
-	struct iio_dev *indio_dev = dev_get_drvdata(dev);
-	ssize_t ret;
-	u16 val;
-
-	/* Take the iio_dev status lock */
-	mutex_lock(&indio_dev->mlock);
-
-	ret = adis16201_spi_read_reg_16(dev, ADIS16201_TEMP_OUT, (u16 *)&val);
-	if (ret)
-		goto error_ret;
-
-	if (val & ADIS16201_ERROR_ACTIVE) {
-		ret = adis16201_check_status(dev);
-		if (ret)
-			goto error_ret;
-	}
-
-	val &= 0xFFF;
-	ret = sprintf(buf, "%d\n", val);
-
-error_ret:
-	mutex_unlock(&indio_dev->mlock);
-	return ret;
-}
-
-static ssize_t adis16201_read_9bit_signed(struct device *dev,
-		struct device_attribute *attr,
-		char *buf)
-{
-	struct iio_dev *indio_dev = dev_get_drvdata(dev);
-	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
-	s16 val = 0;
-	ssize_t ret;
-
-	mutex_lock(&indio_dev->mlock);
-
-	ret = adis16201_spi_read_reg_16(dev, this_attr->address, (u16 *)&val);
-	if (!ret) {
-		if (val & ADIS16201_ERROR_ACTIVE) {
-			ret = adis16201_check_status(dev);
-			if (ret)
-				goto error_ret;
-		}
-		val = ((s16)(val << 7) >> 7);
-		ret = sprintf(buf, "%d\n", val);
-	}
-
-error_ret:
-	mutex_unlock(&indio_dev->mlock);
-
-	return ret;
-}
-
-static ssize_t adis16201_read_12bit_signed(struct device *dev,
-		struct device_attribute *attr,
-		char *buf)
-{
-	struct iio_dev *indio_dev = dev_get_drvdata(dev);
-	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
-	s16 val = 0;
-	ssize_t ret;
-
-	mutex_lock(&indio_dev->mlock);
-
-	ret = adis16201_spi_read_reg_16(dev, this_attr->address, (u16 *)&val);
-	if (!ret) {
-		if (val & ADIS16201_ERROR_ACTIVE) {
-			ret = adis16201_check_status(dev);
-			if (ret)
-				goto error_ret;
-		}
-
-		val = ((s16)(val << 4) >> 4);
-		ret = sprintf(buf, "%d\n", val);
-	}
-
-error_ret:
-	mutex_unlock(&indio_dev->mlock);
-
-	return ret;
-}
-
-static ssize_t adis16201_read_14bit_signed(struct device *dev,
-		struct device_attribute *attr,
-		char *buf)
-{
-	struct iio_dev *indio_dev = dev_get_drvdata(dev);
-	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
-	s16 val = 0;
-	ssize_t ret;
-
-	mutex_lock(&indio_dev->mlock);
-
-	ret = adis16201_spi_read_reg_16(dev, this_attr->address, (u16 *)&val);
-	if (!ret) {
-		if (val & ADIS16201_ERROR_ACTIVE) {
-			ret = adis16201_check_status(dev);
-			if (ret)
-				goto error_ret;
-		}
-
-		val = ((s16)(val << 2) >> 2);
-		ret = sprintf(buf, "%d\n", val);
-	}
-
-error_ret:
-	mutex_unlock(&indio_dev->mlock);
-
-	return ret;
-}
-
-static ssize_t adis16201_write_16bit(struct device *dev,
-		struct device_attribute *attr,
-		const char *buf,
-		size_t len)
-{
-	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
-	int ret;
-	long val;
-
-	ret = strict_strtol(buf, 10, &val);
-	if (ret)
-		goto error_ret;
-	ret = adis16201_spi_write_reg_16(dev, this_attr->address, val);
-
-error_ret:
-	return ret ? ret : len;
-}
-
 static int adis16201_reset(struct device *dev)
 {
 	int ret;
@@ -331,12 +178,12 @@
 	return -EINVAL;
 }
 
-int adis16201_set_irq(struct device *dev, bool enable)
+int adis16201_set_irq(struct iio_dev *indio_dev, bool enable)
 {
 	int ret = 0;
 	u16 msc;
 
-	ret = adis16201_spi_read_reg_16(dev, ADIS16201_MSC_CTRL, &msc);
+	ret = adis16201_spi_read_reg_16(indio_dev, ADIS16201_MSC_CTRL, &msc);
 	if (ret)
 		goto error_ret;
 
@@ -347,20 +194,21 @@
 	else
 		msc &= ~ADIS16201_MSC_CTRL_DATA_RDY_EN;
 
-	ret = adis16201_spi_write_reg_16(dev, ADIS16201_MSC_CTRL, msc);
+	ret = adis16201_spi_write_reg_16(indio_dev, ADIS16201_MSC_CTRL, msc);
 
 error_ret:
 	return ret;
 }
 
-static int adis16201_check_status(struct device *dev)
+static int adis16201_check_status(struct iio_dev *indio_dev)
 {
 	u16 status;
 	int ret;
 
-	ret = adis16201_spi_read_reg_16(dev, ADIS16201_DIAG_STAT, &status);
+	ret = adis16201_spi_read_reg_16(indio_dev,
+					ADIS16201_DIAG_STAT, &status);
 	if (ret < 0) {
-		dev_err(dev, "Reading status failed\n");
+		dev_err(&indio_dev->dev, "Reading status failed\n");
 		goto error_ret;
 	}
 	ret = status & 0xF;
@@ -368,30 +216,30 @@
 		ret = -EFAULT;
 
 	if (status & ADIS16201_DIAG_STAT_SPI_FAIL)
-		dev_err(dev, "SPI failure\n");
+		dev_err(&indio_dev->dev, "SPI failure\n");
 	if (status & ADIS16201_DIAG_STAT_FLASH_UPT)
-		dev_err(dev, "Flash update failed\n");
+		dev_err(&indio_dev->dev, "Flash update failed\n");
 	if (status & ADIS16201_DIAG_STAT_POWER_HIGH)
-		dev_err(dev, "Power supply above 3.625V\n");
+		dev_err(&indio_dev->dev, "Power supply above 3.625V\n");
 	if (status & ADIS16201_DIAG_STAT_POWER_LOW)
-		dev_err(dev, "Power supply below 3.15V\n");
+		dev_err(&indio_dev->dev, "Power supply below 3.15V\n");
 
 error_ret:
 	return ret;
 }
 
-static int adis16201_self_test(struct device *dev)
+static int adis16201_self_test(struct iio_dev *indio_dev)
 {
 	int ret;
-	ret = adis16201_spi_write_reg_16(dev,
+	ret = adis16201_spi_write_reg_16(indio_dev,
 			ADIS16201_MSC_CTRL,
 			ADIS16201_MSC_CTRL_SELF_TEST_EN);
 	if (ret) {
-		dev_err(dev, "problem starting self test");
+		dev_err(&indio_dev->dev, "problem starting self test");
 		goto err_ret;
 	}
 
-	ret = adis16201_check_status(dev);
+	ret = adis16201_check_status(indio_dev);
 
 err_ret:
 	return ret;
@@ -403,26 +251,26 @@
 	struct device *dev = &st->indio_dev->dev;
 
 	/* Disable IRQ */
-	ret = adis16201_set_irq(dev, false);
+	ret = adis16201_set_irq(st->indio_dev, false);
 	if (ret) {
 		dev_err(dev, "disable irq failed");
 		goto err_ret;
 	}
 
 	/* Do self test */
-	ret = adis16201_self_test(dev);
+	ret = adis16201_self_test(st->indio_dev);
 	if (ret) {
 		dev_err(dev, "self test failure");
 		goto err_ret;
 	}
 
 	/* Read status register to check the result */
-	ret = adis16201_check_status(dev);
+	ret = adis16201_check_status(st->indio_dev);
 	if (ret) {
 		adis16201_reset(dev);
 		dev_err(dev, "device not playing ball -> reset");
 		msleep(ADIS16201_STARTUP_DELAY);
-		ret = adis16201_check_status(dev);
+		ret = adis16201_check_status(st->indio_dev);
 		if (ret) {
 			dev_err(dev, "giving up");
 			goto err_ret;
@@ -436,77 +284,172 @@
 	return ret;
 }
 
-static IIO_DEV_ATTR_IN_NAMED_RAW(0, supply, adis16201_read_12bit_unsigned,
-		ADIS16201_SUPPLY_OUT);
-static IIO_CONST_ATTR(in0_supply_scale, "0.00122");
-static IIO_DEV_ATTR_IN_RAW(1, adis16201_read_12bit_unsigned,
-		ADIS16201_AUX_ADC);
-static IIO_CONST_ATTR(in1_scale, "0.00061");
-
-static IIO_DEV_ATTR_ACCEL_X(adis16201_read_14bit_signed,
-		ADIS16201_XACCL_OUT);
-static IIO_DEV_ATTR_ACCEL_Y(adis16201_read_14bit_signed,
-		ADIS16201_YACCL_OUT);
-static IIO_DEV_ATTR_ACCEL_X_OFFSET(S_IWUSR | S_IRUGO,
-		adis16201_read_12bit_signed,
-		adis16201_write_16bit,
-		ADIS16201_XACCL_OFFS);
-static IIO_DEV_ATTR_ACCEL_Y_OFFSET(S_IWUSR | S_IRUGO,
-		adis16201_read_12bit_signed,
-		adis16201_write_16bit,
-		ADIS16201_YACCL_OFFS);
-static IIO_CONST_ATTR(accel_scale, "0.4625");
+static u8 adis16201_addresses[7][2] = {
+	[in_supply] = { ADIS16201_SUPPLY_OUT, },
+	[temp] = { ADIS16201_TEMP_OUT },
+	[accel_x] = { ADIS16201_XACCL_OUT, ADIS16201_XACCL_OFFS },
+	[accel_y] = { ADIS16201_YACCL_OUT, ADIS16201_YACCL_OFFS },
+	[in_aux] = { ADIS16201_AUX_ADC },
+	[incli_x] = { ADIS16201_XINCL_OUT },
+	[incli_y] = { ADIS16201_YINCL_OUT },
+};
 
-static IIO_DEV_ATTR_INCLI_X(adis16201_read_14bit_signed,
-		ADIS16201_XINCL_OUT);
-static IIO_DEV_ATTR_INCLI_Y(adis16201_read_14bit_signed,
-		ADIS16201_YINCL_OUT);
-static IIO_DEV_ATTR_INCLI_X_OFFSET(S_IWUSR | S_IRUGO,
-		adis16201_read_9bit_signed,
-		adis16201_write_16bit,
-		ADIS16201_XACCL_OFFS);
-static IIO_DEV_ATTR_INCLI_Y_OFFSET(S_IWUSR | S_IRUGO,
-		adis16201_read_9bit_signed,
-		adis16201_write_16bit,
-		ADIS16201_YACCL_OFFS);
-static IIO_CONST_ATTR(incli_scale, "0.1");
+static int adis16201_read_raw(struct iio_dev *indio_dev,
+			      struct iio_chan_spec const *chan,
+			      int *val, int *val2,
+			      long mask)
+{
+	int ret;
+	int bits;
+	u8 addr;
+	s16 val16;
 
-static IIO_DEV_ATTR_TEMP_RAW(adis16201_read_temp);
-static IIO_CONST_ATTR(temp_offset, "25");
-static IIO_CONST_ATTR(temp_scale, "-0.47");
+	switch (mask) {
+	case 0:
+		mutex_lock(&indio_dev->mlock);
+		addr = adis16201_addresses[chan->address][0];
+		ret = adis16201_spi_read_reg_16(indio_dev, addr, &val16);
+		if (ret)
+			return ret;
 
-static IIO_DEVICE_ATTR(reset, S_IWUSR, NULL, adis16201_write_reset, 0);
+		if (val16 & ADIS16201_ERROR_ACTIVE) {
+			ret = adis16201_check_status(indio_dev);
+			if (ret)
+				return ret;
+		}
+		val16 = val16 & ((1 << chan->scan_type.realbits) - 1);
+		if (chan->scan_type.sign == 's')
+			val16 = (s16)(val16 <<
+				      (16 - chan->scan_type.realbits)) >>
+				(16 - chan->scan_type.realbits);
+		*val = val16;
+		mutex_unlock(&indio_dev->mlock);
+		return IIO_VAL_INT;
+	case (1 << IIO_CHAN_INFO_SCALE_SEPARATE):
+	case (1 << IIO_CHAN_INFO_SCALE_SHARED):
+		switch (chan->type) {
+		case IIO_IN:
+			*val = 0;
+			if (chan->channel == 0)
+				*val2 = 1220;
+			else
+				*val2 = 610;
+			return IIO_VAL_INT_PLUS_MICRO;
+		case IIO_TEMP:
+			*val = 0;
+			*val2 = -470000;
+			return IIO_VAL_INT_PLUS_MICRO;
+		case IIO_ACCEL:
+			*val = 0;
+			*val2 = 462500;
+			return IIO_VAL_INT_PLUS_MICRO;
+		case IIO_INCLI:
+			*val = 0;
+			*val2 = 100000;
+			return IIO_VAL_INT_PLUS_MICRO;
+		default:
+			return -EINVAL;
+		}
+		break;
+	case (1 << IIO_CHAN_INFO_OFFSET_SEPARATE):
+		*val = 25;
+		return IIO_VAL_INT;
+	case (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE):
+		switch (chan->type) {
+		case IIO_ACCEL:
+			bits = 12;
+			break;
+		case IIO_INCLI:
+			bits = 9;
+			break;
+		default:
+			return -EINVAL;
+		};
+		mutex_lock(&indio_dev->mlock);
+		addr = adis16201_addresses[chan->address][1];
+		ret = adis16201_spi_read_reg_16(indio_dev, addr, &val16);
+		if (ret) {
+			mutex_unlock(&indio_dev->mlock);
+			return ret;
+		}
+		val16 &= (1 << bits) - 1;
+		val16 = (s16)(val16 << (16 - bits)) >> (16 - bits);
+		*val = val16;
+		mutex_unlock(&indio_dev->mlock);
+		return IIO_VAL_INT;
+	}
+	return -EINVAL;
+}
 
-static IIO_CONST_ATTR(name, "adis16201");
+static int adis16201_write_raw(struct iio_dev *indio_dev,
+			       struct iio_chan_spec const *chan,
+			       int val,
+			       int val2,
+			       long mask)
+{
+	int bits;
+	s16 val16;
+	u8 addr;
+	switch (mask) {
+	case (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE):
+		switch (chan->type) {
+		case IIO_ACCEL:
+			bits = 12;
+			break;
+		case IIO_INCLI:
+			bits = 9;
+			break;
+		default:
+			return -EINVAL;
+		};
+		val16 = val & ((1 << bits) - 1);
+		addr = adis16201_addresses[chan->address][1];
+		return adis16201_spi_write_reg_16(indio_dev, addr, val16);
+	}
+	return -EINVAL;
+}
 
-static struct attribute *adis16201_event_attributes[] = {
-	NULL
+static struct iio_chan_spec adis16201_channels[] = {
+	IIO_CHAN(IIO_IN, 0, 1, 0, "supply", 0, 0,
+		 (1 << IIO_CHAN_INFO_SCALE_SEPARATE),
+		 in_supply, ADIS16201_SCAN_SUPPLY,
+		 IIO_ST('u', 12, 16, 0), 0),
+	IIO_CHAN(IIO_TEMP, 0, 1, 0, NULL, 0, 0,
+		 (1 << IIO_CHAN_INFO_SCALE_SEPARATE) |
+		 (1 << IIO_CHAN_INFO_OFFSET_SEPARATE),
+		 temp, ADIS16201_SCAN_TEMP,
+		 IIO_ST('u', 12, 16, 0), 0),
+	IIO_CHAN(IIO_ACCEL, 1, 0, 0, NULL, 0, IIO_MOD_X,
+		 (1 << IIO_CHAN_INFO_SCALE_SHARED) |
+		 (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE),
+		 accel_x, ADIS16201_SCAN_ACC_X,
+		 IIO_ST('s', 14, 16, 0), 0),
+	IIO_CHAN(IIO_ACCEL, 1, 0, 0, NULL, 0, IIO_MOD_Y,
+		 (1 << IIO_CHAN_INFO_SCALE_SHARED) |
+		 (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE),
+		 accel_y, ADIS16201_SCAN_ACC_Y,
+		 IIO_ST('s', 14, 16, 0), 0),
+	IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 1, 0,
+		 (1 << IIO_CHAN_INFO_SCALE_SEPARATE),
+		 in_aux, ADIS16201_SCAN_AUX_ADC,
+		 IIO_ST('u', 12, 16, 0), 0),
+	IIO_CHAN(IIO_INCLI, 1, 0, 0, NULL, 0, IIO_MOD_X,
+		 (1 << IIO_CHAN_INFO_SCALE_SHARED) |
+		 (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE),
+		 incli_x, ADIS16201_SCAN_INCLI_X,
+		 IIO_ST('s', 14, 16, 0), 0),
+	IIO_CHAN(IIO_INCLI, 1, 0, 0, NULL, 0, IIO_MOD_Y,
+		 (1 << IIO_CHAN_INFO_SCALE_SHARED) |
+		 (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE),
+		 incli_y, ADIS16201_SCAN_INCLI_Y,
+		 IIO_ST('s', 14, 16, 0), 0),
+	IIO_CHAN_SOFT_TIMESTAMP(7)
 };
 
-static struct attribute_group adis16201_event_attribute_group = {
-	.attrs = adis16201_event_attributes,
-};
+static IIO_DEVICE_ATTR(reset, S_IWUSR, NULL, adis16201_write_reset, 0);
 
 static struct attribute *adis16201_attributes[] = {
-	&iio_dev_attr_in0_supply_raw.dev_attr.attr,
-	&iio_const_attr_in0_supply_scale.dev_attr.attr,
-	&iio_dev_attr_temp_raw.dev_attr.attr,
-	&iio_const_attr_temp_offset.dev_attr.attr,
-	&iio_const_attr_temp_scale.dev_attr.attr,
 	&iio_dev_attr_reset.dev_attr.attr,
-	&iio_const_attr_name.dev_attr.attr,
-	&iio_dev_attr_in1_raw.dev_attr.attr,
-	&iio_const_attr_in1_scale.dev_attr.attr,
-	&iio_dev_attr_accel_x_raw.dev_attr.attr,
-	&iio_dev_attr_accel_y_raw.dev_attr.attr,
-	&iio_dev_attr_accel_x_offset.dev_attr.attr,
-	&iio_dev_attr_accel_y_offset.dev_attr.attr,
-	&iio_const_attr_accel_scale.dev_attr.attr,
-	&iio_dev_attr_incli_x_raw.dev_attr.attr,
-	&iio_dev_attr_incli_y_raw.dev_attr.attr,
-	&iio_dev_attr_incli_x_offset.dev_attr.attr,
-	&iio_dev_attr_incli_y_offset.dev_attr.attr,
-	&iio_const_attr_incli_scale.dev_attr.attr,
 	NULL
 };
 
@@ -514,6 +457,13 @@
 	.attrs = adis16201_attributes,
 };
 
+static const struct iio_info adis16201_info = {
+	.attrs = &adis16201_attribute_group,
+	.read_raw = &adis16201_read_raw,
+	.write_raw = &adis16201_write_raw,
+	.driver_module = THIS_MODULE,
+};
+
 static int __devinit adis16201_probe(struct spi_device *spi)
 {
 	int ret, regdone = 0;
@@ -539,18 +489,19 @@
 	st->us = spi;
 	mutex_init(&st->buf_lock);
 	/* setup the industrialio driver allocated elements */
-	st->indio_dev = iio_allocate_device();
+	st->indio_dev = iio_allocate_device(0);
 	if (st->indio_dev == NULL) {
 		ret = -ENOMEM;
 		goto error_free_tx;
 	}
 
+	st->indio_dev->name = spi->dev.driver->name;
 	st->indio_dev->dev.parent = &spi->dev;
-	st->indio_dev->num_interrupt_lines = 1;
-	st->indio_dev->event_attrs = &adis16201_event_attribute_group;
-	st->indio_dev->attrs = &adis16201_attribute_group;
+	st->indio_dev->info = &adis16201_info;
+
+	st->indio_dev->channels = adis16201_channels;
+	st->indio_dev->num_channels = ARRAY_SIZE(adis16201_channels);
 	st->indio_dev->dev_data = (void *)(st);
-	st->indio_dev->driver_module = THIS_MODULE;
 	st->indio_dev->modes = INDIO_DIRECT_MODE;
 
 	ret = adis16201_configure_ring(st->indio_dev);
@@ -562,24 +513,18 @@
 		goto error_unreg_ring_funcs;
 	regdone = 1;
 
-	ret = adis16201_initialize_ring(st->indio_dev->ring);
+	ret = iio_ring_buffer_register_ex(st->indio_dev->ring, 0,
+					  adis16201_channels,
+					  ARRAY_SIZE(adis16201_channels));
 	if (ret) {
 		printk(KERN_ERR "failed to initialize the ring\n");
 		goto error_unreg_ring_funcs;
 	}
 
 	if (spi->irq) {
-		ret = iio_register_interrupt_line(spi->irq,
-				st->indio_dev,
-				0,
-				IRQF_TRIGGER_RISING,
-				"adis16201");
-		if (ret)
-			goto error_uninitialize_ring;
-
 		ret = adis16201_probe_trigger(st->indio_dev);
 		if (ret)
-			goto error_unregister_line;
+			goto error_uninitialize_ring;
 	}
 
 	/* Get the device into a sane initial state */
@@ -590,11 +535,8 @@
 
 error_remove_trigger:
 	adis16201_remove_trigger(st->indio_dev);
-error_unregister_line:
-	if (spi->irq)
-		iio_unregister_interrupt_line(st->indio_dev, 0);
 error_uninitialize_ring:
-	adis16201_uninitialize_ring(st->indio_dev->ring);
+	iio_ring_buffer_unregister(st->indio_dev->ring);
 error_unreg_ring_funcs:
 	adis16201_unconfigure_ring(st->indio_dev);
 error_free_dev:
@@ -617,13 +559,8 @@
 	struct adis16201_state *st = spi_get_drvdata(spi);
 	struct iio_dev *indio_dev = st->indio_dev;
 
-	flush_scheduled_work();
-
 	adis16201_remove_trigger(indio_dev);
-	if (spi->irq)
-		iio_unregister_interrupt_line(indio_dev, 0);
-
-	adis16201_uninitialize_ring(indio_dev->ring);
+	iio_ring_buffer_unregister(indio_dev->ring);
 	iio_device_unregister(indio_dev);
 	adis16201_unconfigure_ring(indio_dev);
 	kfree(st->tx);
diff -druN linux-2.6.39-libre/drivers/staging/iio/accel/adis16201.h linux-3.0-rc7-libre/drivers/staging/iio/accel/adis16201.h
--- linux-2.6.39-libre/drivers/staging/iio/accel/adis16201.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/iio/accel/adis16201.h	2011-07-11 19:51:52.000000000 -0400
@@ -64,9 +64,6 @@
 /**
  * struct adis16201_state - device instance specific data
  * @us:			actual spi_device
- * @work_trigger_to_ring: bh for triggered event handling
- * @inter:		used to check if new interrupt has been triggered
- * @last_timestamp:	passing timestamp from th to bh of interrupt handler
  * @indio_dev:		industrial I/O device structure
  * @trig:		data ready trigger registered with iio
  * @tx:			transmit buffer
@@ -75,8 +72,6 @@
  **/
 struct adis16201_state {
 	struct spi_device		*us;
-	struct work_struct		work_trigger_to_ring;
-	s64				last_timestamp;
 	struct iio_dev			*indio_dev;
 	struct iio_trigger		*trig;
 	u8				*tx;
@@ -84,9 +79,8 @@
 	struct mutex			buf_lock;
 };
 
-int adis16201_set_irq(struct device *dev, bool enable);
+int adis16201_set_irq(struct iio_dev *indio_dev, bool enable);
 
-#ifdef CONFIG_IIO_RING_BUFFER
 enum adis16201_scan {
 	ADIS16201_SCAN_SUPPLY,
 	ADIS16201_SCAN_ACC_X,
@@ -97,6 +91,7 @@
 	ADIS16201_SCAN_INCLI_Y,
 };
 
+#ifdef CONFIG_IIO_RING_BUFFER
 void adis16201_remove_trigger(struct iio_dev *indio_dev);
 int adis16201_probe_trigger(struct iio_dev *indio_dev);
 
@@ -107,8 +102,6 @@
 int adis16201_configure_ring(struct iio_dev *indio_dev);
 void adis16201_unconfigure_ring(struct iio_dev *indio_dev);
 
-int adis16201_initialize_ring(struct iio_ring_buffer *ring);
-void adis16201_uninitialize_ring(struct iio_ring_buffer *ring);
 #else /* CONFIG_IIO_RING_BUFFER */
 
 static inline void adis16201_remove_trigger(struct iio_dev *indio_dev)
diff -druN linux-2.6.39-libre/drivers/staging/iio/accel/adis16201_ring.c linux-3.0-rc7-libre/drivers/staging/iio/accel/adis16201_ring.c
--- linux-2.6.39-libre/drivers/staging/iio/accel/adis16201_ring.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/iio/accel/adis16201_ring.c	2011-07-11 19:51:52.000000000 -0400
@@ -1,14 +1,11 @@
 #include <linux/interrupt.h>
 #include <linux/irq.h>
-#include <linux/gpio.h>
-#include <linux/workqueue.h>
 #include <linux/mutex.h>
 #include <linux/device.h>
 #include <linux/kernel.h>
 #include <linux/spi/spi.h>
 #include <linux/slab.h>
 #include <linux/sysfs.h>
-#include <linux/list.h>
 
 #include "../iio.h"
 #include "../sysfs.h"
@@ -17,74 +14,15 @@
 #include "../trigger.h"
 #include "adis16201.h"
 
-static IIO_SCAN_EL_C(in_supply, ADIS16201_SCAN_SUPPLY, ADIS16201_SUPPLY_OUT, NULL);
-static IIO_CONST_ATTR_SCAN_EL_TYPE(in_supply, u, 12, 16);
-static IIO_SCAN_EL_C(accel_x, ADIS16201_SCAN_ACC_X, ADIS16201_XACCL_OUT, NULL);
-static IIO_SCAN_EL_C(accel_y, ADIS16201_SCAN_ACC_Y, ADIS16201_YACCL_OUT, NULL);
-static IIO_CONST_ATTR_SCAN_EL_TYPE(accel, s, 14, 16);
-static IIO_SCAN_EL_C(in0, ADIS16201_SCAN_AUX_ADC, ADIS16201_AUX_ADC, NULL);
-static IIO_CONST_ATTR_SCAN_EL_TYPE(in0, u, 12, 16);
-static IIO_SCAN_EL_C(temp, ADIS16201_SCAN_TEMP, ADIS16201_TEMP_OUT, NULL);
-static IIO_CONST_ATTR_SCAN_EL_TYPE(temp, u, 12, 16);
-static IIO_SCAN_EL_C(incli_x, ADIS16201_SCAN_INCLI_X,
-		     ADIS16201_XINCL_OUT, NULL);
-static IIO_SCAN_EL_C(incli_y, ADIS16201_SCAN_INCLI_Y,
-		     ADIS16201_YINCL_OUT, NULL);
-static IIO_CONST_ATTR_SCAN_EL_TYPE(incli, s, 14, 16);
-static IIO_SCAN_EL_TIMESTAMP(7);
-static IIO_CONST_ATTR_SCAN_EL_TYPE(timestamp, s, 64, 64);
-
-static struct attribute *adis16201_scan_el_attrs[] = {
-	&iio_scan_el_in_supply.dev_attr.attr,
-	&iio_const_attr_in_supply_index.dev_attr.attr,
-	&iio_const_attr_in_supply_type.dev_attr.attr,
-	&iio_scan_el_accel_x.dev_attr.attr,
-	&iio_const_attr_accel_x_index.dev_attr.attr,
-	&iio_scan_el_accel_y.dev_attr.attr,
-	&iio_const_attr_accel_y_index.dev_attr.attr,
-	&iio_const_attr_accel_type.dev_attr.attr,
-	&iio_scan_el_in0.dev_attr.attr,
-	&iio_const_attr_in0_index.dev_attr.attr,
-	&iio_const_attr_in0_type.dev_attr.attr,
-	&iio_scan_el_temp.dev_attr.attr,
-	&iio_const_attr_temp_index.dev_attr.attr,
-	&iio_const_attr_temp_type.dev_attr.attr,
-	&iio_scan_el_incli_x.dev_attr.attr,
-	&iio_const_attr_incli_x_index.dev_attr.attr,
-	&iio_scan_el_incli_y.dev_attr.attr,
-	&iio_const_attr_incli_y_index.dev_attr.attr,
-	&iio_const_attr_incli_type.dev_attr.attr,
-	&iio_scan_el_timestamp.dev_attr.attr,
-	&iio_const_attr_timestamp_index.dev_attr.attr,
-	&iio_const_attr_timestamp_type.dev_attr.attr,
-	NULL,
-};
-
-static struct attribute_group adis16201_scan_el_group = {
-	.attrs = adis16201_scan_el_attrs,
-	.name = "scan_elements",
-};
-
-/**
- * adis16201_poll_func_th() top half interrupt handler called by trigger
- * @private_data:	iio_dev
- **/
-static void adis16201_poll_func_th(struct iio_dev *indio_dev, s64 time)
-{
-	struct adis16201_state *st = iio_dev_get_devdata(indio_dev);
-	st->last_timestamp = time;
-	schedule_work(&st->work_trigger_to_ring);
-}
 
 /**
  * adis16201_read_ring_data() read data registers which will be placed into ring
  * @dev: device associated with child of actual device (iio_dev or iio_trig)
  * @rx: somewhere to pass back the value read
  **/
-static int adis16201_read_ring_data(struct device *dev, u8 *rx)
+static int adis16201_read_ring_data(struct iio_dev *indio_dev, u8 *rx)
 {
 	struct spi_message msg;
-	struct iio_dev *indio_dev = dev_get_drvdata(dev);
 	struct adis16201_state *st = iio_dev_get_devdata(indio_dev);
 	struct spi_transfer xfers[ADIS16201_OUTPUTS + 1];
 	int ret;
@@ -101,7 +39,8 @@
 		xfers[i].len = 2;
 		xfers[i].delay_usecs = 20;
 		xfers[i].tx_buf = st->tx + 2 * i;
-		st->tx[2 * i] = ADIS16201_READ_REG(ADIS16201_SUPPLY_OUT + 2 * i);
+		st->tx[2 * i] = ADIS16201_READ_REG(ADIS16201_SUPPLY_OUT +
+						   2 * i);
 		st->tx[2 * i + 1] = 0;
 		if (i >= 1)
 			xfers[i].rx_buf = rx + 2 * (i - 1);
@@ -120,55 +59,57 @@
 /* Whilst this makes a lot of calls to iio_sw_ring functions - it is to device
  * specific to be rolled into the core.
  */
-static void adis16201_trigger_bh_to_ring(struct work_struct *work_s)
+static irqreturn_t adis16201_trigger_handler(int irq, void *p)
 {
-	struct adis16201_state *st
-		= container_of(work_s, struct adis16201_state,
-			       work_trigger_to_ring);
-	struct iio_ring_buffer *ring = st->indio_dev->ring;
+	struct iio_poll_func *pf = p;
+	struct iio_dev *indio_dev = pf->private_data;
+	struct adis16201_state *st = iio_dev_get_devdata(indio_dev);
+	struct iio_ring_buffer *ring = indio_dev->ring;
 
 	int i = 0;
 	s16 *data;
-	size_t datasize = ring->access.get_bytes_per_datum(ring);
+	size_t datasize = ring->access->get_bytes_per_datum(ring);
 
 	data = kmalloc(datasize, GFP_KERNEL);
 	if (data == NULL) {
 		dev_err(&st->us->dev, "memory alloc failed in ring bh");
-		return;
+		return -ENOMEM;
 	}
 
 	if (ring->scan_count)
-		if (adis16201_read_ring_data(&st->indio_dev->dev, st->rx) >= 0)
+		if (adis16201_read_ring_data(st->indio_dev, st->rx) >= 0)
 			for (; i < ring->scan_count; i++)
 				data[i] = be16_to_cpup(
 					(__be16 *)&(st->rx[i*2]));
 
 	/* Guaranteed to be aligned with 8 byte boundary */
 	if (ring->scan_timestamp)
-		*((s64 *)(data + ((i + 3)/4)*4)) = st->last_timestamp;
+		*((s64 *)(data + ((i + 3)/4)*4)) = pf->timestamp;
 
-	ring->access.store_to(ring,
-			      (u8 *)data,
-			      st->last_timestamp);
+	ring->access->store_to(ring, (u8 *)data, pf->timestamp);
 
 	iio_trigger_notify_done(st->indio_dev->trig);
 	kfree(data);
 
-	return;
+	return IRQ_HANDLED;
 }
 
 void adis16201_unconfigure_ring(struct iio_dev *indio_dev)
 {
-	kfree(indio_dev->pollfunc);
+	iio_dealloc_pollfunc(indio_dev->pollfunc);
 	iio_sw_rb_free(indio_dev->ring);
 }
 
+static const struct iio_ring_setup_ops adis16201_ring_setup_ops = {
+	.preenable = &iio_sw_ring_preenable,
+	.postenable = &iio_triggered_ring_postenable,
+	.predisable = &iio_triggered_ring_predisable,
+};
+
 int adis16201_configure_ring(struct iio_dev *indio_dev)
 {
 	int ret = 0;
-	struct adis16201_state *st = indio_dev->dev_data;
 	struct iio_ring_buffer *ring;
-	INIT_WORK(&st->work_trigger_to_ring, adis16201_trigger_bh_to_ring);
 
 	ring = iio_sw_rb_allocate(indio_dev);
 	if (!ring) {
@@ -177,42 +118,35 @@
 	}
 	indio_dev->ring = ring;
 	/* Effectively select the ring buffer implementation */
-	iio_ring_sw_register_funcs(&ring->access);
 	ring->bpe = 2;
-	ring->scan_el_attrs = &adis16201_scan_el_group;
 	ring->scan_timestamp = true;
-	ring->preenable = &iio_sw_ring_preenable;
-	ring->postenable = &iio_triggered_ring_postenable;
-	ring->predisable = &iio_triggered_ring_predisable;
+	ring->access = &ring_sw_access_funcs;
+	ring->setup_ops = &adis16201_ring_setup_ops;
 	ring->owner = THIS_MODULE;
 
 	/* Set default scan mode */
-	iio_scan_mask_set(ring, iio_scan_el_in_supply.number);
-	iio_scan_mask_set(ring, iio_scan_el_accel_x.number);
-	iio_scan_mask_set(ring, iio_scan_el_accel_y.number);
-	iio_scan_mask_set(ring, iio_scan_el_temp.number);
-	iio_scan_mask_set(ring, iio_scan_el_in0.number);
-	iio_scan_mask_set(ring, iio_scan_el_incli_x.number);
-	iio_scan_mask_set(ring, iio_scan_el_incli_y.number);
+	iio_scan_mask_set(ring,	ADIS16201_SCAN_SUPPLY);
+	iio_scan_mask_set(ring, ADIS16201_SCAN_ACC_X);
+	iio_scan_mask_set(ring, ADIS16201_SCAN_ACC_Y);
+	iio_scan_mask_set(ring, ADIS16201_SCAN_AUX_ADC);
+	iio_scan_mask_set(ring, ADIS16201_SCAN_TEMP);
+	iio_scan_mask_set(ring, ADIS16201_SCAN_INCLI_X);
+	iio_scan_mask_set(ring, ADIS16201_SCAN_INCLI_Y);
 
-	ret = iio_alloc_pollfunc(indio_dev, NULL, &adis16201_poll_func_th);
-	if (ret)
+	indio_dev->pollfunc = iio_alloc_pollfunc(&iio_pollfunc_store_time,
+						 &adis16201_trigger_handler,
+						 IRQF_ONESHOT,
+						 indio_dev,
+						 "adis16201_consumer%d",
+						 indio_dev->id);
+	if (indio_dev->pollfunc == NULL) {
+		ret = -ENOMEM;
 		goto error_iio_sw_rb_free;
+	}
 
 	indio_dev->modes |= INDIO_RING_TRIGGERED;
 	return 0;
-
 error_iio_sw_rb_free:
 	iio_sw_rb_free(indio_dev->ring);
 	return ret;
 }
-
-int adis16201_initialize_ring(struct iio_ring_buffer *ring)
-{
-	return iio_ring_buffer_register(ring, 0);
-}
-
-void adis16201_uninitialize_ring(struct iio_ring_buffer *ring)
-{
-	iio_ring_buffer_unregister(ring);
-}
diff -druN linux-2.6.39-libre/drivers/staging/iio/accel/adis16201_trigger.c linux-3.0-rc7-libre/drivers/staging/iio/accel/adis16201_trigger.c
--- linux-2.6.39-libre/drivers/staging/iio/accel/adis16201_trigger.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/iio/accel/adis16201_trigger.c	2011-07-11 19:51:52.000000000 -0400
@@ -4,7 +4,6 @@
 #include <linux/device.h>
 #include <linux/kernel.h>
 #include <linux/sysfs.h>
-#include <linux/list.h>
 #include <linux/spi/spi.h>
 
 #include "../iio.h"
@@ -13,35 +12,6 @@
 #include "adis16201.h"
 
 /**
- * adis16201_data_rdy_trig_poll() the event handler for the data rdy trig
- **/
-static int adis16201_data_rdy_trig_poll(struct iio_dev *dev_info,
-				       int index,
-				       s64 timestamp,
-				       int no_test)
-{
-	struct adis16201_state *st = iio_dev_get_devdata(dev_info);
-	struct iio_trigger *trig = st->trig;
-
-	iio_trigger_poll(trig, timestamp);
-
-	return IRQ_HANDLED;
-}
-
-IIO_EVENT_SH(data_rdy_trig, &adis16201_data_rdy_trig_poll);
-
-static DEVICE_ATTR(name, S_IRUGO, iio_trigger_read_name, NULL);
-
-static struct attribute *adis16201_trigger_attrs[] = {
-	&dev_attr_name.attr,
-	NULL,
-};
-
-static const struct attribute_group adis16201_trigger_attr_group = {
-	.attrs = adis16201_trigger_attrs,
-};
-
-/**
  * adis16201_data_rdy_trigger_set_state() set datardy interrupt state
  **/
 static int adis16201_data_rdy_trigger_set_state(struct iio_trigger *trig,
@@ -49,31 +19,9 @@
 {
 	struct adis16201_state *st = trig->private_data;
 	struct iio_dev *indio_dev = st->indio_dev;
-	int ret = 0;
 
 	dev_dbg(&indio_dev->dev, "%s (%d)\n", __func__, state);
-	ret = adis16201_set_irq(&st->indio_dev->dev, state);
-	if (state == false) {
-		iio_remove_event_from_list(&iio_event_data_rdy_trig,
-					   &indio_dev->interrupts[0]
-					   ->ev_list);
-		flush_scheduled_work();
-	} else {
-		iio_add_event_to_list(&iio_event_data_rdy_trig,
-				      &indio_dev->interrupts[0]->ev_list);
-	}
-	return ret;
-}
-
-/**
- * adis16201_trig_try_reen() try renabling irq for data rdy trigger
- * @trig:	the datardy trigger
- **/
-static int adis16201_trig_try_reen(struct iio_trigger *trig)
-{
-	struct adis16201_state *st = trig->private_data;
-	enable_irq(st->us->irq);
-	return 0;
+	return adis16201_set_irq(st->indio_dev, state);
 }
 
 int adis16201_probe_trigger(struct iio_dev *indio_dev)
@@ -81,34 +29,36 @@
 	int ret;
 	struct adis16201_state *st = indio_dev->dev_data;
 
-	st->trig = iio_allocate_trigger();
-	st->trig->name = kasprintf(GFP_KERNEL,
-				"adis16201-dev%d",
-				indio_dev->id);
-	if (!st->trig->name) {
+	st->trig = iio_allocate_trigger("adis16201-dev%d", indio_dev->id);
+	if (st->trig == NULL) {
 		ret = -ENOMEM;
-		goto error_free_trig;
+		goto error_ret;
 	}
+	ret = request_irq(st->us->irq,
+			  &iio_trigger_generic_data_rdy_poll,
+			  IRQF_TRIGGER_RISING,
+			  "adis16201",
+			  st->trig);
+	if (ret)
+		goto error_free_trig;
 	st->trig->dev.parent = &st->us->dev;
 	st->trig->owner = THIS_MODULE;
 	st->trig->private_data = st;
 	st->trig->set_trigger_state = &adis16201_data_rdy_trigger_set_state;
-	st->trig->try_reenable = &adis16201_trig_try_reen;
-	st->trig->control_attrs = &adis16201_trigger_attr_group;
 	ret = iio_trigger_register(st->trig);
 
 	/* select default trigger */
 	indio_dev->trig = st->trig;
 	if (ret)
-		goto error_free_trig_name;
+		goto error_free_irq;
 
 	return 0;
 
-error_free_trig_name:
-	kfree(st->trig->name);
+error_free_irq:
+	free_irq(st->us->irq, st->trig);
 error_free_trig:
 	iio_free_trigger(st->trig);
-
+error_ret:
 	return ret;
 }
 
@@ -117,6 +67,6 @@
 	struct adis16201_state *state = indio_dev->dev_data;
 
 	iio_trigger_unregister(state->trig);
-	kfree(state->trig->name);
+	free_irq(state->us->irq, state->trig);
 	iio_free_trigger(state->trig);
 }
diff -druN linux-2.6.39-libre/drivers/staging/iio/accel/adis16203_core.c linux-3.0-rc7-libre/drivers/staging/iio/accel/adis16203_core.c
--- linux-2.6.39-libre/drivers/staging/iio/accel/adis16203_core.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/iio/accel/adis16203_core.c	2011-07-11 19:51:52.000000000 -0400
@@ -6,9 +6,6 @@
  * Licensed under the GPL-2 or later.
  */
 
-#include <linux/interrupt.h>
-#include <linux/irq.h>
-#include <linux/gpio.h>
 #include <linux/delay.h>
 #include <linux/mutex.h>
 #include <linux/device.h>
@@ -16,33 +13,29 @@
 #include <linux/spi/spi.h>
 #include <linux/slab.h>
 #include <linux/sysfs.h>
-#include <linux/list.h>
 
 #include "../iio.h"
 #include "../sysfs.h"
 #include "accel.h"
 #include "inclinometer.h"
-#include "../gyro/gyro.h"
+#include "../ring_generic.h"
 #include "../adc/adc.h"
 
 #include "adis16203.h"
 
 #define DRIVER_NAME		"adis16203"
 
-static int adis16203_check_status(struct device *dev);
-
 /**
  * adis16203_spi_write_reg_8() - write single byte to a register
- * @dev: device associated with child of actual device (iio_dev or iio_trig)
+ * @indio_dev: iio device associated with child of actual device
  * @reg_address: the address of the register to be written
  * @val: the value to write
  **/
-static int adis16203_spi_write_reg_8(struct device *dev,
-		u8 reg_address,
-		u8 val)
+static int adis16203_spi_write_reg_8(struct iio_dev *indio_dev,
+				     u8 reg_address,
+				     u8 val)
 {
 	int ret;
-	struct iio_dev *indio_dev = dev_get_drvdata(dev);
 	struct adis16203_state *st = iio_dev_get_devdata(indio_dev);
 
 	mutex_lock(&st->buf_lock);
@@ -57,18 +50,17 @@
 
 /**
  * adis16203_spi_write_reg_16() - write 2 bytes to a pair of registers
- * @dev: device associated with child of actual device (iio_dev or iio_trig)
+ * @indio_dev: iio device associated with child of actual device
  * @reg_address: the address of the lower of the two registers. Second register
  *               is assumed to have address one greater.
  * @val: value to be written
  **/
-static int adis16203_spi_write_reg_16(struct device *dev,
-		u8 lower_reg_address,
-		u16 value)
+static int adis16203_spi_write_reg_16(struct iio_dev *indio_dev,
+				      u8 lower_reg_address,
+				      u16 value)
 {
 	int ret;
 	struct spi_message msg;
-	struct iio_dev *indio_dev = dev_get_drvdata(dev);
 	struct adis16203_state *st = iio_dev_get_devdata(indio_dev);
 	struct spi_transfer xfers[] = {
 		{
@@ -80,7 +72,6 @@
 			.tx_buf = st->tx + 2,
 			.bits_per_word = 8,
 			.len = 2,
-			.cs_change = 1,
 		},
 	};
 
@@ -101,17 +92,16 @@
 
 /**
  * adis16203_spi_read_reg_16() - read 2 bytes from a 16-bit register
- * @dev: device associated with child of actual device (iio_dev or iio_trig)
+ * @indio_dev: iio device associated with child of actual device
  * @reg_address: the address of the lower of the two registers. Second register
  *               is assumed to have address one greater.
  * @val: somewhere to pass back the value read
  **/
-static int adis16203_spi_read_reg_16(struct device *dev,
+static int adis16203_spi_read_reg_16(struct iio_dev *indio_dev,
 		u8 lower_reg_address,
 		u16 *val)
 {
 	struct spi_message msg;
-	struct iio_dev *indio_dev = dev_get_drvdata(dev);
 	struct adis16203_state *st = iio_dev_get_devdata(indio_dev);
 	int ret;
 	struct spi_transfer xfers[] = {
@@ -125,7 +115,6 @@
 			.rx_buf = st->rx,
 			.bits_per_word = 8,
 			.len = 2,
-			.cs_change = 1,
 			.delay_usecs = 20,
 		},
 	};
@@ -150,101 +139,43 @@
 	return ret;
 }
 
-static ssize_t adis16203_read_12bit_unsigned(struct device *dev,
-		struct device_attribute *attr,
-		char *buf)
+static int adis16203_check_status(struct iio_dev *indio_dev)
 {
+	u16 status;
 	int ret;
-	u16 val = 0;
-	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
-
-	ret = adis16203_spi_read_reg_16(dev, this_attr->address, &val);
-	if (ret)
-		return ret;
-
-	if (val & ADIS16203_ERROR_ACTIVE)
-		adis16203_check_status(dev);
-
-	return sprintf(buf, "%u\n", val & 0x0FFF);
-}
-
-static ssize_t adis16203_read_temp(struct device *dev,
-		struct device_attribute *attr,
-		char *buf)
-{
-	struct iio_dev *indio_dev = dev_get_drvdata(dev);
-	ssize_t ret;
-	u16 val;
 
-	/* Take the iio_dev status lock */
-	mutex_lock(&indio_dev->mlock);
-
-	ret = adis16203_spi_read_reg_16(dev, ADIS16203_TEMP_OUT, (u16 *)&val);
-	if (ret)
+	ret = adis16203_spi_read_reg_16(indio_dev,
+					ADIS16203_DIAG_STAT,
+					&status);
+	if (ret < 0) {
+		dev_err(&indio_dev->dev, "Reading status failed\n");
 		goto error_ret;
-
-	if (val & ADIS16203_ERROR_ACTIVE)
-		adis16203_check_status(dev);
-
-	val &= 0xFFF;
-	ret = sprintf(buf, "%d\n", val);
-
-error_ret:
-	mutex_unlock(&indio_dev->mlock);
-	return ret;
-}
-
-static ssize_t adis16203_read_14bit_signed(struct device *dev,
-		struct device_attribute *attr,
-		char *buf)
-{
-	struct iio_dev *indio_dev = dev_get_drvdata(dev);
-	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
-	s16 val = 0;
-	ssize_t ret;
-
-	mutex_lock(&indio_dev->mlock);
-
-	ret = adis16203_spi_read_reg_16(dev, this_attr->address, (u16 *)&val);
-	if (!ret) {
-		if (val & ADIS16203_ERROR_ACTIVE)
-			adis16203_check_status(dev);
-
-		val = ((s16)(val << 2) >> 2);
-		ret = sprintf(buf, "%d\n", val);
 	}
+	ret = status & 0x1F;
 
-	mutex_unlock(&indio_dev->mlock);
-
-	return ret;
-}
-
-static ssize_t adis16203_write_16bit(struct device *dev,
-		struct device_attribute *attr,
-		const char *buf,
-		size_t len)
-{
-	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
-	int ret;
-	long val;
-
-	ret = strict_strtol(buf, 10, &val);
-	if (ret)
-		goto error_ret;
-	ret = adis16203_spi_write_reg_16(dev, this_attr->address, val);
+	if (status & ADIS16203_DIAG_STAT_SELFTEST_FAIL)
+		dev_err(&indio_dev->dev, "Self test failure\n");
+	if (status & ADIS16203_DIAG_STAT_SPI_FAIL)
+		dev_err(&indio_dev->dev, "SPI failure\n");
+	if (status & ADIS16203_DIAG_STAT_FLASH_UPT)
+		dev_err(&indio_dev->dev, "Flash update failed\n");
+	if (status & ADIS16203_DIAG_STAT_POWER_HIGH)
+		dev_err(&indio_dev->dev, "Power supply above 3.625V\n");
+	if (status & ADIS16203_DIAG_STAT_POWER_LOW)
+		dev_err(&indio_dev->dev, "Power supply below 3.15V\n");
 
 error_ret:
-	return ret ? ret : len;
+	return ret;
 }
 
-static int adis16203_reset(struct device *dev)
+static int adis16203_reset(struct iio_dev *indio_dev)
 {
 	int ret;
-	ret = adis16203_spi_write_reg_8(dev,
+	ret = adis16203_spi_write_reg_8(indio_dev,
 			ADIS16203_GLOB_CMD,
 			ADIS16203_GLOB_CMD_SW_RESET);
 	if (ret)
-		dev_err(dev, "problem resetting device");
+		dev_err(&indio_dev->dev, "problem resetting device");
 
 	return ret;
 }
@@ -253,23 +184,24 @@
 		struct device_attribute *attr,
 		const char *buf, size_t len)
 {
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
 	if (len < 1)
 		return -EINVAL;
 	switch (buf[0]) {
 	case '1':
 	case 'y':
 	case 'Y':
-		return adis16203_reset(dev);
+		return adis16203_reset(indio_dev);
 	}
 	return -EINVAL;
 }
 
-int adis16203_set_irq(struct device *dev, bool enable)
+int adis16203_set_irq(struct iio_dev *indio_dev, bool enable)
 {
 	int ret = 0;
 	u16 msc;
 
-	ret = adis16203_spi_read_reg_16(dev, ADIS16203_MSC_CTRL, &msc);
+	ret = adis16203_spi_read_reg_16(indio_dev, ADIS16203_MSC_CTRL, &msc);
 	if (ret)
 		goto error_ret;
 
@@ -280,142 +212,195 @@
 	else
 		msc &= ~ADIS16203_MSC_CTRL_DATA_RDY_EN;
 
-	ret = adis16203_spi_write_reg_16(dev, ADIS16203_MSC_CTRL, msc);
-
-error_ret:
-	return ret;
-}
-
-static int adis16203_check_status(struct device *dev)
-{
-	u16 status;
-	int ret;
-
-	ret = adis16203_spi_read_reg_16(dev, ADIS16203_DIAG_STAT, &status);
-	if (ret < 0) {
-		dev_err(dev, "Reading status failed\n");
-		goto error_ret;
-	}
-	ret = status & 0x1F;
-
-	if (status & ADIS16203_DIAG_STAT_SELFTEST_FAIL)
-		dev_err(dev, "Self test failure\n");
-	if (status & ADIS16203_DIAG_STAT_SPI_FAIL)
-		dev_err(dev, "SPI failure\n");
-	if (status & ADIS16203_DIAG_STAT_FLASH_UPT)
-		dev_err(dev, "Flash update failed\n");
-	if (status & ADIS16203_DIAG_STAT_POWER_HIGH)
-		dev_err(dev, "Power supply above 3.625V\n");
-	if (status & ADIS16203_DIAG_STAT_POWER_LOW)
-		dev_err(dev, "Power supply below 3.15V\n");
+	ret = adis16203_spi_write_reg_16(indio_dev, ADIS16203_MSC_CTRL, msc);
 
 error_ret:
 	return ret;
 }
 
-static int adis16203_self_test(struct device *dev)
+static int adis16203_self_test(struct iio_dev *indio_dev)
 {
 	int ret;
-	ret = adis16203_spi_write_reg_16(dev,
+	ret = adis16203_spi_write_reg_16(indio_dev,
 			ADIS16203_MSC_CTRL,
 			ADIS16203_MSC_CTRL_SELF_TEST_EN);
 	if (ret) {
-		dev_err(dev, "problem starting self test");
+		dev_err(&indio_dev->dev, "problem starting self test");
 		goto err_ret;
 	}
 
-	adis16203_check_status(dev);
+	adis16203_check_status(indio_dev);
 
 err_ret:
 	return ret;
 }
 
-static int adis16203_initial_setup(struct adis16203_state *st)
+static int adis16203_initial_setup(struct iio_dev *indio_dev)
 {
 	int ret;
-	struct device *dev = &st->indio_dev->dev;
 
 	/* Disable IRQ */
-	ret = adis16203_set_irq(dev, false);
+	ret = adis16203_set_irq(indio_dev, false);
 	if (ret) {
-		dev_err(dev, "disable irq failed");
+		dev_err(&indio_dev->dev, "disable irq failed");
 		goto err_ret;
 	}
 
 	/* Do self test */
-	ret = adis16203_self_test(dev);
+	ret = adis16203_self_test(indio_dev);
 	if (ret) {
-		dev_err(dev, "self test failure");
+		dev_err(&indio_dev->dev, "self test failure");
 		goto err_ret;
 	}
 
 	/* Read status register to check the result */
-	ret = adis16203_check_status(dev);
+	ret = adis16203_check_status(indio_dev);
 	if (ret) {
-		adis16203_reset(dev);
-		dev_err(dev, "device not playing ball -> reset");
+		adis16203_reset(indio_dev);
+		dev_err(&indio_dev->dev, "device not playing ball -> reset");
 		msleep(ADIS16203_STARTUP_DELAY);
-		ret = adis16203_check_status(dev);
+		ret = adis16203_check_status(indio_dev);
 		if (ret) {
-			dev_err(dev, "giving up");
+			dev_err(&indio_dev->dev, "giving up");
 			goto err_ret;
 		}
 	}
 
-	printk(KERN_INFO DRIVER_NAME ": at CS%d (irq %d)\n",
-			st->us->chip_select, st->us->irq);
-
 err_ret:
 	return ret;
 }
 
-static IIO_DEV_ATTR_IN_NAMED_RAW(0, supply, adis16203_read_12bit_unsigned,
-		ADIS16203_SUPPLY_OUT);
-static IIO_CONST_ATTR(in0_supply_scale, "0.00122");
-static IIO_DEV_ATTR_IN_RAW(1, adis16203_read_12bit_unsigned,
-		ADIS16203_AUX_ADC);
-static IIO_CONST_ATTR(in1_scale, "0.00061");
+enum adis16203_chan {
+	in_supply,
+	in_aux,
+	incli_x,
+	incli_y,
+	temp,
+};
 
-static IIO_DEV_ATTR_INCLI_X(adis16203_read_14bit_signed,
-		ADIS16203_XINCL_OUT);
-static IIO_DEV_ATTR_INCLI_Y(adis16203_read_14bit_signed,
-		ADIS16203_YINCL_OUT);
-static IIO_DEV_ATTR_INCLI_X_OFFSET(S_IWUSR | S_IRUGO,
-		adis16203_read_14bit_signed,
-		adis16203_write_16bit,
-		ADIS16203_INCL_NULL);
-static IIO_CONST_ATTR(incli_scale, "0.025");
+static u8 adis16203_addresses[5][2] = {
+	[in_supply] = { ADIS16203_SUPPLY_OUT },
+	[in_aux] = { ADIS16203_AUX_ADC },
+	[incli_x] = { ADIS16203_XINCL_OUT, ADIS16203_INCL_NULL},
+	[incli_y] = { ADIS16203_YINCL_OUT },
+	[temp] = { ADIS16203_TEMP_OUT }
+};
 
-static IIO_DEV_ATTR_TEMP_RAW(adis16203_read_temp);
-static IIO_CONST_ATTR(temp_offset, "25");
-static IIO_CONST_ATTR(temp_scale, "-0.47");
+static int adis16203_write_raw(struct iio_dev *indio_dev,
+			       struct iio_chan_spec const *chan,
+			       int val,
+			       int val2,
+			       long mask)
+{
+	/* currently only one writable parameter which keeps this simple */
+	u8 addr = adis16203_addresses[chan->address][1];
+	return adis16203_spi_write_reg_16(indio_dev, addr, val & 0x3FFF);
+}
 
-static IIO_DEVICE_ATTR(reset, S_IWUSR, NULL, adis16203_write_reset, 0);
+static int adis16203_read_raw(struct iio_dev *indio_dev,
+			      struct iio_chan_spec const *chan,
+			      int *val, int *val2,
+			      long mask)
+{
+	int ret;
+	int bits;
+	u8 addr;
+	s16 val16;
+	switch (mask) {
+	case 0:
+		mutex_lock(&indio_dev->mlock);
+		addr = adis16203_addresses[chan->address][0];
+		ret = adis16203_spi_read_reg_16(indio_dev, addr, &val16);
+		if (ret)
+			return ret;
 
-static IIO_CONST_ATTR(name, "adis16203");
+		if (val16 & ADIS16203_ERROR_ACTIVE) {
+			ret = adis16203_check_status(indio_dev);
+			if (ret)
+				return ret;
+		}
+		val16 = val16 & ((1 << chan->scan_type.realbits) - 1);
+		if (chan->scan_type.sign == 's')
+			val16 = (s16)(val16 <<
+				      (16 - chan->scan_type.realbits)) >>
+				(16 - chan->scan_type.realbits);
+		*val = val16;
+		mutex_unlock(&indio_dev->mlock);
+		return IIO_VAL_INT;
+	case (1 << IIO_CHAN_INFO_SCALE_SEPARATE):
+	case (1 << IIO_CHAN_INFO_SCALE_SHARED):
+		switch (chan->type) {
+		case IIO_IN:
+			*val = 0;
+			if (chan->channel == 0)
+				*val2 = 1220;
+			else
+				*val2 = 610;
+			return IIO_VAL_INT_PLUS_MICRO;
+		case IIO_TEMP:
+			*val = 0;
+			*val2 = -470000;
+			return IIO_VAL_INT_PLUS_MICRO;
+		case IIO_INCLI:
+			*val = 0;
+			*val2 = 25000;
+			return IIO_VAL_INT_PLUS_MICRO;
+		default:
+			return -EINVAL;
+		}
+	case (1 << IIO_CHAN_INFO_OFFSET_SEPARATE):
+		*val = 25;
+		return IIO_VAL_INT;
+	case (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE):
+		bits = 14;
+		mutex_lock(&indio_dev->mlock);
+		addr = adis16203_addresses[chan->address][1];
+		ret = adis16203_spi_read_reg_16(indio_dev, addr, &val16);
+		if (ret) {
+			mutex_unlock(&indio_dev->mlock);
+			return ret;
+		}
+		val16 &= (1 << bits) - 1;
+		val16 = (s16)(val16 << (16 - bits)) >> (16 - bits);
+		*val = val16;
+		mutex_unlock(&indio_dev->mlock);
+		return IIO_VAL_INT;
+	default:
+		return -EINVAL;
+	}
+}
 
-static struct attribute *adis16203_event_attributes[] = {
-	NULL
+static struct iio_chan_spec adis16203_channels[] = {
+	IIO_CHAN(IIO_IN, 0, 1, 0, "supply", 0, 0,
+		 (1 << IIO_CHAN_INFO_SCALE_SEPARATE),
+		 in_supply, ADIS16203_SCAN_SUPPLY,
+		 IIO_ST('u', 12, 16, 0), 0),
+	IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 1, 0,
+		 (1 << IIO_CHAN_INFO_SCALE_SEPARATE),
+		 in_aux, ADIS16203_SCAN_AUX_ADC,
+		 IIO_ST('u', 12, 16, 0), 0),
+	IIO_CHAN(IIO_INCLI, 1, 0, 0, NULL, 0, IIO_MOD_X,
+		 (1 << IIO_CHAN_INFO_SCALE_SHARED) |
+		 (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE),
+		 incli_x, ADIS16203_SCAN_INCLI_X,
+		 IIO_ST('s', 14, 16, 0), 0),
+	/* Fixme: Not what it appears to be - see data sheet */
+	IIO_CHAN(IIO_INCLI, 1, 0, 0, NULL, 0, IIO_MOD_Y,
+		 (1 << IIO_CHAN_INFO_SCALE_SHARED),
+		 incli_y, ADIS16203_SCAN_INCLI_Y,
+		 IIO_ST('s', 14, 16, 0), 0),
+	IIO_CHAN(IIO_TEMP, 0, 1, 0, NULL, 0, 0,
+		 (1 << IIO_CHAN_INFO_SCALE_SEPARATE) |
+		 (1 << IIO_CHAN_INFO_OFFSET_SEPARATE),
+		 temp, ADIS16203_SCAN_TEMP,
+		 IIO_ST('u', 12, 16, 0), 0),
+	IIO_CHAN_SOFT_TIMESTAMP(5),
 };
 
-static struct attribute_group adis16203_event_attribute_group = {
-	.attrs = adis16203_event_attributes,
-};
+static IIO_DEVICE_ATTR(reset, S_IWUSR, NULL, adis16203_write_reset, 0);
 
 static struct attribute *adis16203_attributes[] = {
-	&iio_dev_attr_in0_supply_raw.dev_attr.attr,
-	&iio_const_attr_in0_supply_scale.dev_attr.attr,
-	&iio_dev_attr_temp_raw.dev_attr.attr,
-	&iio_const_attr_temp_offset.dev_attr.attr,
-	&iio_const_attr_temp_scale.dev_attr.attr,
 	&iio_dev_attr_reset.dev_attr.attr,
-	&iio_const_attr_name.dev_attr.attr,
-	&iio_dev_attr_in1_raw.dev_attr.attr,
-	&iio_const_attr_in1_scale.dev_attr.attr,
-	&iio_dev_attr_incli_x_raw.dev_attr.attr,
-	&iio_dev_attr_incli_y_raw.dev_attr.attr,
-	&iio_dev_attr_incli_x_offset.dev_attr.attr,
-	&iio_const_attr_incli_scale.dev_attr.attr,
 	NULL
 };
 
@@ -423,6 +408,13 @@
 	.attrs = adis16203_attributes,
 };
 
+static const struct iio_info adis16203_info = {
+	.attrs = &adis16203_attribute_group,
+	.read_raw = &adis16203_read_raw,
+	.write_raw = &adis16203_write_raw,
+	.driver_module = THIS_MODULE,
+};
+
 static int __devinit adis16203_probe(struct spi_device *spi)
 {
 	int ret, regdone = 0;
@@ -448,18 +440,17 @@
 	st->us = spi;
 	mutex_init(&st->buf_lock);
 	/* setup the industrialio driver allocated elements */
-	st->indio_dev = iio_allocate_device();
+	st->indio_dev = iio_allocate_device(0);
 	if (st->indio_dev == NULL) {
 		ret = -ENOMEM;
 		goto error_free_tx;
 	}
-
+	st->indio_dev->name = spi->dev.driver->name;
 	st->indio_dev->dev.parent = &spi->dev;
-	st->indio_dev->num_interrupt_lines = 1;
-	st->indio_dev->event_attrs = &adis16203_event_attribute_group;
-	st->indio_dev->attrs = &adis16203_attribute_group;
+	st->indio_dev->channels = adis16203_channels;
+	st->indio_dev->num_channels = ARRAY_SIZE(adis16203_channels);
+	st->indio_dev->info = &adis16203_info;
 	st->indio_dev->dev_data = (void *)(st);
-	st->indio_dev->driver_module = THIS_MODULE;
 	st->indio_dev->modes = INDIO_DIRECT_MODE;
 
 	ret = adis16203_configure_ring(st->indio_dev);
@@ -471,39 +462,30 @@
 		goto error_unreg_ring_funcs;
 	regdone = 1;
 
-	ret = adis16203_initialize_ring(st->indio_dev->ring);
+	ret = iio_ring_buffer_register_ex(st->indio_dev->ring, 0,
+					  adis16203_channels,
+					  ARRAY_SIZE(adis16203_channels));
 	if (ret) {
 		printk(KERN_ERR "failed to initialize the ring\n");
 		goto error_unreg_ring_funcs;
 	}
 
 	if (spi->irq) {
-		ret = iio_register_interrupt_line(spi->irq,
-				st->indio_dev,
-				0,
-				IRQF_TRIGGER_RISING,
-				"adis16203");
-		if (ret)
-			goto error_uninitialize_ring;
-
 		ret = adis16203_probe_trigger(st->indio_dev);
 		if (ret)
-			goto error_unregister_line;
+			goto error_uninitialize_ring;
 	}
 
 	/* Get the device into a sane initial state */
-	ret = adis16203_initial_setup(st);
+	ret = adis16203_initial_setup(st->indio_dev);
 	if (ret)
 		goto error_remove_trigger;
 	return 0;
 
 error_remove_trigger:
 	adis16203_remove_trigger(st->indio_dev);
-error_unregister_line:
-	if (spi->irq)
-		iio_unregister_interrupt_line(st->indio_dev, 0);
 error_uninitialize_ring:
-	adis16203_uninitialize_ring(st->indio_dev->ring);
+	iio_ring_buffer_unregister(st->indio_dev->ring);
 error_unreg_ring_funcs:
 	adis16203_unconfigure_ring(st->indio_dev);
 error_free_dev:
@@ -526,13 +508,8 @@
 	struct adis16203_state *st = spi_get_drvdata(spi);
 	struct iio_dev *indio_dev = st->indio_dev;
 
-	flush_scheduled_work();
-
 	adis16203_remove_trigger(indio_dev);
-	if (spi->irq)
-		iio_unregister_interrupt_line(indio_dev, 0);
-
-	adis16203_uninitialize_ring(indio_dev->ring);
+	iio_ring_buffer_unregister(indio_dev->ring);
 	iio_device_unregister(indio_dev);
 	adis16203_unconfigure_ring(indio_dev);
 	kfree(st->tx);
diff -druN linux-2.6.39-libre/drivers/staging/iio/accel/adis16203.h linux-3.0-rc7-libre/drivers/staging/iio/accel/adis16203.h
--- linux-2.6.39-libre/drivers/staging/iio/accel/adis16203.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/iio/accel/adis16203.h	2011-07-11 19:51:52.000000000 -0400
@@ -59,9 +59,6 @@
 /**
  * struct adis16203_state - device instance specific data
  * @us:			actual spi_device
- * @work_trigger_to_ring: bh for triggered event handling
- * @inter:		used to check if new interrupt has been triggered
- * @last_timestamp:	passing timestamp from th to bh of interrupt handler
  * @indio_dev:		industrial I/O device structure
  * @trig:		data ready trigger registered with iio
  * @tx:			transmit buffer
@@ -70,8 +67,6 @@
  **/
 struct adis16203_state {
 	struct spi_device		*us;
-	struct work_struct		work_trigger_to_ring;
-	s64				last_timestamp;
 	struct iio_dev			*indio_dev;
 	struct iio_trigger		*trig;
 	u8				*tx;
@@ -79,9 +74,8 @@
 	struct mutex			buf_lock;
 };
 
-int adis16203_set_irq(struct device *dev, bool enable);
+int adis16203_set_irq(struct iio_dev *indio_dev, bool enable);
 
-#ifdef CONFIG_IIO_RING_BUFFER
 enum adis16203_scan {
 	ADIS16203_SCAN_SUPPLY,
 	ADIS16203_SCAN_AUX_ADC,
@@ -90,6 +84,7 @@
 	ADIS16203_SCAN_INCLI_Y,
 };
 
+#ifdef CONFIG_IIO_RING_BUFFER
 void adis16203_remove_trigger(struct iio_dev *indio_dev);
 int adis16203_probe_trigger(struct iio_dev *indio_dev);
 
@@ -100,8 +95,6 @@
 int adis16203_configure_ring(struct iio_dev *indio_dev);
 void adis16203_unconfigure_ring(struct iio_dev *indio_dev);
 
-int adis16203_initialize_ring(struct iio_ring_buffer *ring);
-void adis16203_uninitialize_ring(struct iio_ring_buffer *ring);
 #else /* CONFIG_IIO_RING_BUFFER */
 
 static inline void adis16203_remove_trigger(struct iio_dev *indio_dev)
@@ -130,14 +123,5 @@
 {
 }
 
-static inline int adis16203_initialize_ring(struct iio_ring_buffer *ring)
-{
-	return 0;
-}
-
-static inline void adis16203_uninitialize_ring(struct iio_ring_buffer *ring)
-{
-}
-
 #endif /* CONFIG_IIO_RING_BUFFER */
 #endif /* SPI_ADIS16203_H_ */
diff -druN linux-2.6.39-libre/drivers/staging/iio/accel/adis16203_ring.c linux-3.0-rc7-libre/drivers/staging/iio/accel/adis16203_ring.c
--- linux-2.6.39-libre/drivers/staging/iio/accel/adis16203_ring.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/iio/accel/adis16203_ring.c	2011-07-11 19:51:52.000000000 -0400
@@ -17,57 +17,6 @@
 #include "../trigger.h"
 #include "adis16203.h"
 
-static IIO_SCAN_EL_C(in_supply, ADIS16203_SCAN_SUPPLY, ADIS16203_SUPPLY_OUT, NULL);
-static IIO_CONST_ATTR_SCAN_EL_TYPE(in_supply, u, 12, 16);
-static IIO_SCAN_EL_C(in0, ADIS16203_SCAN_AUX_ADC, ADIS16203_AUX_ADC, NULL);
-static IIO_CONST_ATTR_SCAN_EL_TYPE(in0, u, 12, 16);
-static IIO_SCAN_EL_C(temp, ADIS16203_SCAN_TEMP, ADIS16203_TEMP_OUT, NULL);
-static IIO_CONST_ATTR_SCAN_EL_TYPE(temp, u, 12, 16);
-static IIO_SCAN_EL_C(incli_x, ADIS16203_SCAN_INCLI_X,
-		     ADIS16203_XINCL_OUT, NULL);
-static IIO_SCAN_EL_C(incli_y, ADIS16203_SCAN_INCLI_Y,
-		     ADIS16203_YINCL_OUT, NULL);
-static IIO_CONST_ATTR_SCAN_EL_TYPE(incli, s, 14, 16);
-static IIO_SCAN_EL_TIMESTAMP(5);
-static IIO_CONST_ATTR_SCAN_EL_TYPE(timestamp, s, 64, 64);
-
-static struct attribute *adis16203_scan_el_attrs[] = {
-	&iio_scan_el_in_supply.dev_attr.attr,
-	&iio_const_attr_in_supply_index.dev_attr.attr,
-	&iio_const_attr_in_supply_type.dev_attr.attr,
-	&iio_scan_el_in0.dev_attr.attr,
-	&iio_const_attr_in0_index.dev_attr.attr,
-	&iio_const_attr_in0_type.dev_attr.attr,
-	&iio_scan_el_temp.dev_attr.attr,
-	&iio_const_attr_temp_index.dev_attr.attr,
-	&iio_const_attr_temp_type.dev_attr.attr,
-	&iio_scan_el_incli_x.dev_attr.attr,
-	&iio_const_attr_incli_x_index.dev_attr.attr,
-	&iio_scan_el_incli_y.dev_attr.attr,
-	&iio_const_attr_incli_y_index.dev_attr.attr,
-	&iio_const_attr_incli_type.dev_attr.attr,
-	&iio_scan_el_timestamp.dev_attr.attr,
-	&iio_const_attr_timestamp_index.dev_attr.attr,
-	&iio_const_attr_timestamp_type.dev_attr.attr,
-	NULL,
-};
-
-static struct attribute_group adis16203_scan_el_group = {
-	.attrs = adis16203_scan_el_attrs,
-	.name = "scan_elements",
-};
-
-/**
- * adis16203_poll_func_th() top half interrupt handler called by trigger
- * @private_data:	iio_dev
- **/
-static void adis16203_poll_func_th(struct iio_dev *indio_dev, s64 timestamp)
-{
-	struct adis16203_state *st = iio_dev_get_devdata(indio_dev);
-	st->last_timestamp = timestamp;
-	schedule_work(&st->work_trigger_to_ring);
-}
-
 /**
  * adis16203_read_ring_data() read data registers which will be placed into ring
  * @dev: device associated with child of actual device (iio_dev or iio_trig)
@@ -115,21 +64,21 @@
 /* Whilst this makes a lot of calls to iio_sw_ring functions - it is to device
  * specific to be rolled into the core.
  */
-static void adis16203_trigger_bh_to_ring(struct work_struct *work_s)
+static irqreturn_t adis16203_trigger_handler(int irq, void *p)
 {
-	struct adis16203_state *st
-		= container_of(work_s, struct adis16203_state,
-			       work_trigger_to_ring);
-	struct iio_ring_buffer *ring = st->indio_dev->ring;
+	struct iio_poll_func *pf = p;
+	struct iio_dev *indio_dev = pf->private_data;
+	struct adis16203_state *st = iio_dev_get_devdata(indio_dev);
+	struct iio_ring_buffer *ring = indio_dev->ring;
 
 	int i = 0;
 	s16 *data;
-	size_t datasize = ring->access.get_bytes_per_datum(ring);
+	size_t datasize = ring->access->get_bytes_per_datum(ring);
 
 	data = kmalloc(datasize, GFP_KERNEL);
 	if (data == NULL) {
 		dev_err(&st->us->dev, "memory alloc failed in ring bh");
-		return;
+		return -ENOMEM;
 	}
 
 	if (ring->scan_count)
@@ -140,30 +89,34 @@
 
 	/* Guaranteed to be aligned with 8 byte boundary */
 	if (ring->scan_timestamp)
-		*((s64 *)(data + ((i + 3)/4)*4)) = st->last_timestamp;
+		*((s64 *)(data + ((i + 3)/4)*4)) = pf->timestamp;
 
-	ring->access.store_to(ring,
+	ring->access->store_to(ring,
 			      (u8 *)data,
-			      st->last_timestamp);
+			      pf->timestamp);
 
 	iio_trigger_notify_done(st->indio_dev->trig);
 	kfree(data);
 
-	return;
+	return IRQ_HANDLED;
 }
 
 void adis16203_unconfigure_ring(struct iio_dev *indio_dev)
 {
-	kfree(indio_dev->pollfunc);
+	iio_dealloc_pollfunc(indio_dev->pollfunc);
 	iio_sw_rb_free(indio_dev->ring);
 }
 
+static const struct iio_ring_setup_ops adis16203_ring_setup_ops = {
+	.preenable = &iio_sw_ring_preenable,
+	.postenable = &iio_triggered_ring_postenable,
+	.predisable = &iio_triggered_ring_predisable,
+};
+
 int adis16203_configure_ring(struct iio_dev *indio_dev)
 {
 	int ret = 0;
-	struct adis16203_state *st = indio_dev->dev_data;
 	struct iio_ring_buffer *ring;
-	INIT_WORK(&st->work_trigger_to_ring, adis16203_trigger_bh_to_ring);
 
 	ring = iio_sw_rb_allocate(indio_dev);
 	if (!ring) {
@@ -172,25 +125,29 @@
 	}
 	indio_dev->ring = ring;
 	/* Effectively select the ring buffer implementation */
-	iio_ring_sw_register_funcs(&ring->access);
 	ring->bpe = 2;
-	ring->scan_el_attrs = &adis16203_scan_el_group;
 	ring->scan_timestamp = true;
-	ring->preenable = &iio_sw_ring_preenable;
-	ring->postenable = &iio_triggered_ring_postenable;
-	ring->predisable = &iio_triggered_ring_predisable;
+	ring->access = &ring_sw_access_funcs;
+	ring->setup_ops = &adis16203_ring_setup_ops;
 	ring->owner = THIS_MODULE;
 
 	/* Set default scan mode */
-	iio_scan_mask_set(ring, iio_scan_el_in_supply.number);
-	iio_scan_mask_set(ring, iio_scan_el_temp.number);
-	iio_scan_mask_set(ring, iio_scan_el_in0.number);
-	iio_scan_mask_set(ring, iio_scan_el_incli_x.number);
-	iio_scan_mask_set(ring, iio_scan_el_incli_y.number);
+	iio_scan_mask_set(ring, ADIS16203_SCAN_SUPPLY);
+	iio_scan_mask_set(ring, ADIS16203_SCAN_TEMP);
+	iio_scan_mask_set(ring, ADIS16203_SCAN_AUX_ADC);
+	iio_scan_mask_set(ring, ADIS16203_SCAN_INCLI_X);
+	iio_scan_mask_set(ring, ADIS16203_SCAN_INCLI_Y);
 
-	ret = iio_alloc_pollfunc(indio_dev, NULL, &adis16203_poll_func_th);
-	if (ret)
+	indio_dev->pollfunc = iio_alloc_pollfunc(&iio_pollfunc_store_time,
+						 &adis16203_trigger_handler,
+						 IRQF_ONESHOT,
+						 indio_dev,
+						 "adis16203_consumer%d",
+						 indio_dev->id);
+	if (indio_dev->pollfunc == NULL) {
+		ret = -ENOMEM;
 		goto error_iio_sw_rb_free;
+	}
 
 	indio_dev->modes |= INDIO_RING_TRIGGERED;
 	return 0;
@@ -199,13 +156,3 @@
 	iio_sw_rb_free(indio_dev->ring);
 	return ret;
 }
-
-int adis16203_initialize_ring(struct iio_ring_buffer *ring)
-{
-	return iio_ring_buffer_register(ring, 0);
-}
-
-void adis16203_uninitialize_ring(struct iio_ring_buffer *ring)
-{
-	iio_ring_buffer_unregister(ring);
-}
diff -druN linux-2.6.39-libre/drivers/staging/iio/accel/adis16203_trigger.c linux-3.0-rc7-libre/drivers/staging/iio/accel/adis16203_trigger.c
--- linux-2.6.39-libre/drivers/staging/iio/accel/adis16203_trigger.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/iio/accel/adis16203_trigger.c	2011-07-11 19:51:52.000000000 -0400
@@ -13,35 +13,6 @@
 #include "adis16203.h"
 
 /**
- * adis16203_data_rdy_trig_poll() the event handler for the data rdy trig
- **/
-static int adis16203_data_rdy_trig_poll(struct iio_dev *dev_info,
-				       int index,
-				       s64 timestamp,
-				       int no_test)
-{
-	struct adis16203_state *st = iio_dev_get_devdata(dev_info);
-	struct iio_trigger *trig = st->trig;
-
-	iio_trigger_poll(trig, timestamp);
-
-	return IRQ_HANDLED;
-}
-
-IIO_EVENT_SH(data_rdy_trig, &adis16203_data_rdy_trig_poll);
-
-static DEVICE_ATTR(name, S_IRUGO, iio_trigger_read_name, NULL);
-
-static struct attribute *adis16203_trigger_attrs[] = {
-	&dev_attr_name.attr,
-	NULL,
-};
-
-static const struct attribute_group adis16203_trigger_attr_group = {
-	.attrs = adis16203_trigger_attrs,
-};
-
-/**
  * adis16203_data_rdy_trigger_set_state() set datardy interrupt state
  **/
 static int adis16203_data_rdy_trigger_set_state(struct iio_trigger *trig,
@@ -49,31 +20,9 @@
 {
 	struct adis16203_state *st = trig->private_data;
 	struct iio_dev *indio_dev = st->indio_dev;
-	int ret = 0;
 
 	dev_dbg(&indio_dev->dev, "%s (%d)\n", __func__, state);
-	ret = adis16203_set_irq(&st->indio_dev->dev, state);
-	if (state == false) {
-		iio_remove_event_from_list(&iio_event_data_rdy_trig,
-					   &indio_dev->interrupts[0]
-					   ->ev_list);
-		flush_scheduled_work();
-	} else {
-		iio_add_event_to_list(&iio_event_data_rdy_trig,
-				      &indio_dev->interrupts[0]->ev_list);
-	}
-	return ret;
-}
-
-/**
- * adis16203_trig_try_reen() try renabling irq for data rdy trigger
- * @trig:	the datardy trigger
- **/
-static int adis16203_trig_try_reen(struct iio_trigger *trig)
-{
-	struct adis16203_state *st = trig->private_data;
-	enable_irq(st->us->irq);
-	return 0;
+	return adis16203_set_irq(st->indio_dev, state);
 }
 
 int adis16203_probe_trigger(struct iio_dev *indio_dev)
@@ -81,34 +30,38 @@
 	int ret;
 	struct adis16203_state *st = indio_dev->dev_data;
 
-	st->trig = iio_allocate_trigger();
-	st->trig->name = kasprintf(GFP_KERNEL,
-				"adis16203-dev%d",
-				indio_dev->id);
-	if (!st->trig->name) {
+	st->trig = iio_allocate_trigger("adis16203-dev%d", indio_dev->id);
+	if (st->trig == NULL) {
 		ret = -ENOMEM;
-		goto error_free_trig;
+		goto error_ret;
 	}
+
+	ret = request_irq(st->us->irq,
+			  &iio_trigger_generic_data_rdy_poll,
+			  IRQF_TRIGGER_RISING,
+			  "adis16203",
+			  st->trig);
+	if (ret)
+		goto error_free_trig;
+
 	st->trig->dev.parent = &st->us->dev;
 	st->trig->owner = THIS_MODULE;
 	st->trig->private_data = st;
 	st->trig->set_trigger_state = &adis16203_data_rdy_trigger_set_state;
-	st->trig->try_reenable = &adis16203_trig_try_reen;
-	st->trig->control_attrs = &adis16203_trigger_attr_group;
 	ret = iio_trigger_register(st->trig);
 
 	/* select default trigger */
 	indio_dev->trig = st->trig;
 	if (ret)
-		goto error_free_trig_name;
+		goto error_free_irq;
 
 	return 0;
 
-error_free_trig_name:
-	kfree(st->trig->name);
+error_free_irq:
+	free_irq(st->us->irq, st->trig);
 error_free_trig:
 	iio_free_trigger(st->trig);
-
+error_ret:
 	return ret;
 }
 
@@ -117,6 +70,6 @@
 	struct adis16203_state *state = indio_dev->dev_data;
 
 	iio_trigger_unregister(state->trig);
-	kfree(state->trig->name);
+	free_irq(state->us->irq, state->trig);
 	iio_free_trigger(state->trig);
 }
diff -druN linux-2.6.39-libre/drivers/staging/iio/accel/adis16204_core.c linux-3.0-rc7-libre/drivers/staging/iio/accel/adis16204_core.c
--- linux-2.6.39-libre/drivers/staging/iio/accel/adis16204_core.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/iio/accel/adis16204_core.c	2011-07-11 19:51:52.000000000 -0400
@@ -20,28 +20,25 @@
 
 #include "../iio.h"
 #include "../sysfs.h"
+#include "../ring_generic.h"
 #include "accel.h"
-#include "../gyro/gyro.h"
 #include "../adc/adc.h"
 
 #include "adis16204.h"
 
 #define DRIVER_NAME		"adis16204"
 
-static int adis16204_check_status(struct device *dev);
-
 /**
  * adis16204_spi_write_reg_8() - write single byte to a register
  * @dev: device associated with child of actual device (iio_dev or iio_trig)
  * @reg_address: the address of the register to be written
  * @val: the value to write
  **/
-static int adis16204_spi_write_reg_8(struct device *dev,
+static int adis16204_spi_write_reg_8(struct iio_dev *indio_dev,
 		u8 reg_address,
 		u8 val)
 {
 	int ret;
-	struct iio_dev *indio_dev = dev_get_drvdata(dev);
 	struct adis16204_state *st = iio_dev_get_devdata(indio_dev);
 
 	mutex_lock(&st->buf_lock);
@@ -56,18 +53,17 @@
 
 /**
  * adis16204_spi_write_reg_16() - write 2 bytes to a pair of registers
- * @dev: device associated with child of actual device (iio_dev or iio_trig)
+ * @indio_dev: iio device associated with child of actual device
  * @reg_address: the address of the lower of the two registers. Second register
  *               is assumed to have address one greater.
  * @val: value to be written
  **/
-static int adis16204_spi_write_reg_16(struct device *dev,
+static int adis16204_spi_write_reg_16(struct iio_dev *indio_dev,
 		u8 lower_reg_address,
 		u16 value)
 {
 	int ret;
 	struct spi_message msg;
-	struct iio_dev *indio_dev = dev_get_drvdata(dev);
 	struct adis16204_state *st = iio_dev_get_devdata(indio_dev);
 	struct spi_transfer xfers[] = {
 		{
@@ -100,17 +96,16 @@
 
 /**
  * adis16204_spi_read_reg_16() - read 2 bytes from a 16-bit register
- * @dev: device associated with child of actual device (iio_dev or iio_trig)
+ * @indio_dev: iio device associated with child of actual device
  * @reg_address: the address of the lower of the two registers. Second register
  *               is assumed to have address one greater.
  * @val: somewhere to pass back the value read
  **/
-static int adis16204_spi_read_reg_16(struct device *dev,
-		u8 lower_reg_address,
-		u16 *val)
+static int adis16204_spi_read_reg_16(struct iio_dev *indio_dev,
+				     u8 lower_reg_address,
+				     u16 *val)
 {
 	struct spi_message msg;
-	struct iio_dev *indio_dev = dev_get_drvdata(dev);
 	struct adis16204_state *st = iio_dev_get_devdata(indio_dev);
 	int ret;
 	struct spi_transfer xfers[] = {
@@ -124,7 +119,6 @@
 			.rx_buf = st->rx,
 			.bits_per_word = 8,
 			.len = 2,
-			.cs_change = 1,
 			.delay_usecs = 20,
 		},
 	};
@@ -149,72 +143,31 @@
 	return ret;
 }
 
-static ssize_t adis16204_read_12bit_unsigned(struct device *dev,
-		struct device_attribute *attr,
-		char *buf)
+static int adis16204_check_status(struct iio_dev *indio_dev)
 {
+	u16 status;
 	int ret;
-	u16 val = 0;
-	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
-
-	ret = adis16204_spi_read_reg_16(dev, this_attr->address, &val);
-	if (ret)
-		return ret;
-
-	if (val & ADIS16204_ERROR_ACTIVE)
-		adis16204_check_status(dev);
-
-	return sprintf(buf, "%u\n", val & 0x0FFF);
-}
 
-static ssize_t adis16204_read_temp(struct device *dev,
-		struct device_attribute *attr,
-		char *buf)
-{
-	struct iio_dev *indio_dev = dev_get_drvdata(dev);
-	ssize_t ret;
-	u16 val;
-
-	/* Take the iio_dev status lock */
-	mutex_lock(&indio_dev->mlock);
-
-	ret = adis16204_spi_read_reg_16(dev, ADIS16204_TEMP_OUT, (u16 *)&val);
-	if (ret)
+	ret = adis16204_spi_read_reg_16(indio_dev,
+					ADIS16204_DIAG_STAT, &status);
+	if (ret < 0) {
+		dev_err(&indio_dev->dev, "Reading status failed\n");
 		goto error_ret;
-
-	if (val & ADIS16204_ERROR_ACTIVE)
-		adis16204_check_status(dev);
-
-	val &= 0xFFF;
-	ret = sprintf(buf, "%d\n", val);
-
-error_ret:
-	mutex_unlock(&indio_dev->mlock);
-	return ret;
-}
-
-static ssize_t adis16204_read_12bit_signed(struct device *dev,
-		struct device_attribute *attr,
-		char *buf)
-{
-	struct iio_dev *indio_dev = dev_get_drvdata(dev);
-	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
-	s16 val = 0;
-	ssize_t ret;
-
-	mutex_lock(&indio_dev->mlock);
-
-	ret = adis16204_spi_read_reg_16(dev, this_attr->address, (u16 *)&val);
-	if (!ret) {
-		if (val & ADIS16204_ERROR_ACTIVE)
-			adis16204_check_status(dev);
-
-		val = ((s16)(val << 4) >> 4);
-		ret = sprintf(buf, "%d\n", val);
 	}
+	ret = status & 0x1F;
 
-	mutex_unlock(&indio_dev->mlock);
+	if (status & ADIS16204_DIAG_STAT_SELFTEST_FAIL)
+		dev_err(&indio_dev->dev, "Self test failure\n");
+	if (status & ADIS16204_DIAG_STAT_SPI_FAIL)
+		dev_err(&indio_dev->dev, "SPI failure\n");
+	if (status & ADIS16204_DIAG_STAT_FLASH_UPT)
+		dev_err(&indio_dev->dev, "Flash update failed\n");
+	if (status & ADIS16204_DIAG_STAT_POWER_HIGH)
+		dev_err(&indio_dev->dev, "Power supply above 3.625V\n");
+	if (status & ADIS16204_DIAG_STAT_POWER_LOW)
+		dev_err(&indio_dev->dev, "Power supply below 2.975V\n");
 
+error_ret:
 	return ret;
 }
 
@@ -229,10 +182,11 @@
 
 	mutex_lock(&indio_dev->mlock);
 
-	ret = adis16204_spi_read_reg_16(dev, this_attr->address, (u16 *)&val);
+	ret = adis16204_spi_read_reg_16(indio_dev,
+					this_attr->address, (u16 *)&val);
 	if (!ret) {
 		if (val & ADIS16204_ERROR_ACTIVE)
-			adis16204_check_status(dev);
+			adis16204_check_status(indio_dev);
 
 		val = ((s16)(val << 2) >> 2);
 		ret = sprintf(buf, "%d\n", val);
@@ -243,32 +197,14 @@
 	return ret;
 }
 
-static ssize_t adis16204_write_16bit(struct device *dev,
-		struct device_attribute *attr,
-		const char *buf,
-		size_t len)
-{
-	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
-	int ret;
-	long val;
-
-	ret = strict_strtol(buf, 10, &val);
-	if (ret)
-		goto error_ret;
-	ret = adis16204_spi_write_reg_16(dev, this_attr->address, val);
-
-error_ret:
-	return ret ? ret : len;
-}
-
-static int adis16204_reset(struct device *dev)
+static int adis16204_reset(struct iio_dev *indio_dev)
 {
 	int ret;
-	ret = adis16204_spi_write_reg_8(dev,
+	ret = adis16204_spi_write_reg_8(indio_dev,
 			ADIS16204_GLOB_CMD,
 			ADIS16204_GLOB_CMD_SW_RESET);
 	if (ret)
-		dev_err(dev, "problem resetting device");
+		dev_err(&indio_dev->dev, "problem resetting device");
 
 	return ret;
 }
@@ -277,23 +213,25 @@
 		struct device_attribute *attr,
 		const char *buf, size_t len)
 {
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+
 	if (len < 1)
 		return -EINVAL;
 	switch (buf[0]) {
 	case '1':
 	case 'y':
 	case 'Y':
-		return adis16204_reset(dev);
+		return adis16204_reset(indio_dev);
 	}
 	return -EINVAL;
 }
 
-int adis16204_set_irq(struct device *dev, bool enable)
+int adis16204_set_irq(struct iio_dev *indio_dev, bool enable)
 {
 	int ret = 0;
 	u16 msc;
 
-	ret = adis16204_spi_read_reg_16(dev, ADIS16204_MSC_CTRL, &msc);
+	ret = adis16204_spi_read_reg_16(indio_dev, ADIS16204_MSC_CTRL, &msc);
 	if (ret)
 		goto error_ret;
 
@@ -304,106 +242,63 @@
 	else
 		msc &= ~ADIS16204_MSC_CTRL_DATA_RDY_EN;
 
-	ret = adis16204_spi_write_reg_16(dev, ADIS16204_MSC_CTRL, msc);
-
-error_ret:
-	return ret;
-}
-
-static int adis16204_check_status(struct device *dev)
-{
-	u16 status;
-	int ret;
-
-	ret = adis16204_spi_read_reg_16(dev, ADIS16204_DIAG_STAT, &status);
-	if (ret < 0) {
-		dev_err(dev, "Reading status failed\n");
-		goto error_ret;
-	}
-	ret = status & 0x1F;
-
-	if (status & ADIS16204_DIAG_STAT_SELFTEST_FAIL)
-		dev_err(dev, "Self test failure\n");
-	if (status & ADIS16204_DIAG_STAT_SPI_FAIL)
-		dev_err(dev, "SPI failure\n");
-	if (status & ADIS16204_DIAG_STAT_FLASH_UPT)
-		dev_err(dev, "Flash update failed\n");
-	if (status & ADIS16204_DIAG_STAT_POWER_HIGH)
-		dev_err(dev, "Power supply above 3.625V\n");
-	if (status & ADIS16204_DIAG_STAT_POWER_LOW)
-		dev_err(dev, "Power supply below 2.975V\n");
+	ret = adis16204_spi_write_reg_16(indio_dev, ADIS16204_MSC_CTRL, msc);
 
 error_ret:
 	return ret;
 }
 
-static int adis16204_self_test(struct device *dev)
+static int adis16204_self_test(struct iio_dev *indio_dev)
 {
 	int ret;
-	ret = adis16204_spi_write_reg_16(dev,
+	ret = adis16204_spi_write_reg_16(indio_dev,
 			ADIS16204_MSC_CTRL,
 			ADIS16204_MSC_CTRL_SELF_TEST_EN);
 	if (ret) {
-		dev_err(dev, "problem starting self test");
+		dev_err(&indio_dev->dev, "problem starting self test");
 		goto err_ret;
 	}
 
-	adis16204_check_status(dev);
+	adis16204_check_status(indio_dev);
 
 err_ret:
 	return ret;
 }
 
-static int adis16204_initial_setup(struct adis16204_state *st)
+static int adis16204_initial_setup(struct iio_dev *indio_dev)
 {
 	int ret;
-	struct device *dev = &st->indio_dev->dev;
 
 	/* Disable IRQ */
-	ret = adis16204_set_irq(dev, false);
+	ret = adis16204_set_irq(indio_dev, false);
 	if (ret) {
-		dev_err(dev, "disable irq failed");
+		dev_err(&indio_dev->dev, "disable irq failed");
 		goto err_ret;
 	}
 
 	/* Do self test */
-	ret = adis16204_self_test(dev);
+	ret = adis16204_self_test(indio_dev);
 	if (ret) {
-		dev_err(dev, "self test failure");
+		dev_err(&indio_dev->dev, "self test failure");
 		goto err_ret;
 	}
 
 	/* Read status register to check the result */
-	ret = adis16204_check_status(dev);
+	ret = adis16204_check_status(indio_dev);
 	if (ret) {
-		adis16204_reset(dev);
-		dev_err(dev, "device not playing ball -> reset");
+		adis16204_reset(indio_dev);
+		dev_err(&indio_dev->dev, "device not playing ball -> reset");
 		msleep(ADIS16204_STARTUP_DELAY);
-		ret = adis16204_check_status(dev);
+		ret = adis16204_check_status(indio_dev);
 		if (ret) {
-			dev_err(dev, "giving up");
+			dev_err(&indio_dev->dev, "giving up");
 			goto err_ret;
 		}
 	}
 
-	printk(KERN_INFO DRIVER_NAME ": at CS%d (irq %d)\n",
-			st->us->chip_select, st->us->irq);
-
 err_ret:
 	return ret;
 }
-
-static IIO_DEV_ATTR_IN_NAMED_RAW(0, supply, adis16204_read_12bit_unsigned,
-		ADIS16204_SUPPLY_OUT);
-static IIO_CONST_ATTR(in0_supply_scale, "0.00122");
-static IIO_DEV_ATTR_IN_RAW(1, adis16204_read_12bit_unsigned,
-		ADIS16204_AUX_ADC);
-static IIO_CONST_ATTR(in1_scale, "0.00061");
-
-static IIO_DEV_ATTR_ACCEL_X(adis16204_read_14bit_signed,
-		ADIS16204_XACCL_OUT);
-static IIO_DEV_ATTR_ACCEL_Y(adis16204_read_14bit_signed,
-		ADIS16204_YACCL_OUT);
 static IIO_DEV_ATTR_ACCEL_XY(adis16204_read_14bit_signed,
 		ADIS16204_XY_RSS_OUT);
 static IIO_DEV_ATTR_ACCEL_XPEAK(adis16204_read_14bit_signed,
@@ -412,54 +307,164 @@
 		ADIS16204_Y_PEAK_OUT);
 static IIO_DEV_ATTR_ACCEL_XYPEAK(adis16204_read_14bit_signed,
 		ADIS16204_XY_PEAK_OUT);
-static IIO_DEV_ATTR_ACCEL_X_OFFSET(S_IWUSR | S_IRUGO,
-		adis16204_read_12bit_signed,
-		adis16204_write_16bit,
-		ADIS16204_XACCL_NULL);
-static IIO_DEV_ATTR_ACCEL_Y_OFFSET(S_IWUSR | S_IRUGO,
-		adis16204_read_12bit_signed,
-		adis16204_write_16bit,
-		ADIS16204_YACCL_NULL);
-static IIO_CONST_ATTR(accel_x_scale, "0.017125");
-static IIO_CONST_ATTR(accel_y_scale, "0.008407");
 static IIO_CONST_ATTR(accel_xy_scale, "0.017125");
 
-static IIO_DEV_ATTR_TEMP_RAW(adis16204_read_temp);
-static IIO_CONST_ATTR(temp_offset, "25");
-static IIO_CONST_ATTR(temp_scale, "-0.47");
-
 static IIO_DEVICE_ATTR(reset, S_IWUSR, NULL, adis16204_write_reset, 0);
 
-static IIO_CONST_ATTR(name, "adis16204");
-
-static struct attribute *adis16204_event_attributes[] = {
-	NULL
+enum adis16204_channel {
+	in_supply,
+	in_aux,
+	temp,
+	accel_x,
+	accel_y,
 };
 
-static struct attribute_group adis16204_event_attribute_group = {
-	.attrs = adis16204_event_attributes,
+static u8 adis16204_addresses[5][2] = {
+	[in_supply] = { ADIS16204_SUPPLY_OUT },
+	[in_aux] = { ADIS16204_AUX_ADC },
+	[temp] = { ADIS16204_TEMP_OUT },
+	[accel_x] = { ADIS16204_XACCL_OUT, ADIS16204_XACCL_NULL },
+	[accel_y] = { ADIS16204_XACCL_OUT, ADIS16204_YACCL_NULL },
 };
+static int adis16204_read_raw(struct iio_dev *indio_dev,
+			      struct iio_chan_spec const *chan,
+			      int *val, int *val2,
+			      long mask)
+{
+	int ret;
+	int bits;
+	u8 addr;
+	s16 val16;
+
+	switch (mask) {
+	case 0:
+		mutex_lock(&indio_dev->mlock);
+		addr = adis16204_addresses[chan->address][0];
+		ret = adis16204_spi_read_reg_16(indio_dev, addr, &val16);
+		if (ret)
+			return ret;
 
+		if (val16 & ADIS16204_ERROR_ACTIVE) {
+			ret = adis16204_check_status(indio_dev);
+			if (ret)
+				return ret;
+		}
+		val16 = val16 & ((1 << chan->scan_type.realbits) - 1);
+		if (chan->scan_type.sign == 's')
+			val16 = (s16)(val16 <<
+				      (16 - chan->scan_type.realbits)) >>
+				(16 - chan->scan_type.realbits);
+		*val = val16;
+		mutex_unlock(&indio_dev->mlock);
+		return IIO_VAL_INT;
+	case (1 << IIO_CHAN_INFO_SCALE_SEPARATE):
+		switch (chan->type) {
+		case IIO_IN:
+			*val = 0;
+			if (chan->channel == 0)
+				*val2 = 1220;
+			else
+				*val2 = 610;
+			return IIO_VAL_INT_PLUS_MICRO;
+		case IIO_TEMP:
+			*val = 0;
+			*val2 = -470000;
+			return IIO_VAL_INT_PLUS_MICRO;
+		case IIO_ACCEL:
+			*val = 0;
+			if (chan->channel == 'x')
+				*val2 = 17125;
+			else
+				*val2 = 8407;
+			return IIO_VAL_INT_PLUS_MICRO;
+		default:
+			return -EINVAL;
+		}
+		break;
+	case (1 << IIO_CHAN_INFO_OFFSET_SEPARATE):
+		*val = 25;
+		return IIO_VAL_INT;
+	case (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE):
+		switch (chan->type) {
+		case IIO_ACCEL:
+			bits = 12;
+			break;
+		default:
+			return -EINVAL;
+		};
+		mutex_lock(&indio_dev->mlock);
+		addr = adis16204_addresses[chan->address][1];
+		ret = adis16204_spi_read_reg_16(indio_dev, addr, &val16);
+		if (ret) {
+			mutex_unlock(&indio_dev->mlock);
+			return ret;
+		}
+		val16 &= (1 << bits) - 1;
+		val16 = (s16)(val16 << (16 - bits)) >> (16 - bits);
+		*val = val16;
+		mutex_unlock(&indio_dev->mlock);
+		return IIO_VAL_INT;
+	}
+	return -EINVAL;
+}
+
+static int adis16204_write_raw(struct iio_dev *indio_dev,
+			       struct iio_chan_spec const *chan,
+			       int val,
+			       int val2,
+			       long mask)
+{
+	int bits;
+	s16 val16;
+	u8 addr;
+	switch (mask) {
+	case (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE):
+		switch (chan->type) {
+		case IIO_ACCEL:
+			bits = 12;
+			break;
+		default:
+			return -EINVAL;
+		};
+		val16 = val & ((1 << bits) - 1);
+		addr = adis16204_addresses[chan->address][1];
+		return adis16204_spi_write_reg_16(indio_dev, addr, val16);
+	}
+	return -EINVAL;
+}
+
+static struct iio_chan_spec adis16204_channels[] = {
+	IIO_CHAN(IIO_IN, 0, 0, 0, "supply", 0, 0,
+		 (1 << IIO_CHAN_INFO_SCALE_SEPARATE),
+		 in_supply, ADIS16204_SCAN_SUPPLY,
+		 IIO_ST('u', 12, 16, 0), 0),
+	IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 1, 0,
+		 (1 << IIO_CHAN_INFO_SCALE_SEPARATE),
+		 in_aux, ADIS16204_SCAN_AUX_ADC,
+		 IIO_ST('u', 12, 16, 0), 0),
+	IIO_CHAN(IIO_TEMP, 0, 1, 0, NULL, 0, 0,
+		 (1 << IIO_CHAN_INFO_SCALE_SEPARATE) |
+		 (1 << IIO_CHAN_INFO_OFFSET_SEPARATE),
+		 temp, ADIS16204_SCAN_TEMP,
+		 IIO_ST('u', 12, 16, 0), 0),
+	IIO_CHAN(IIO_ACCEL, 1, 0, 0, NULL, 0, IIO_MOD_X,
+		 (1 << IIO_CHAN_INFO_SCALE_SEPARATE) |
+		 (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE),
+		 accel_x, ADIS16204_SCAN_ACC_X,
+		 IIO_ST('s', 14, 16, 0), 0),
+	IIO_CHAN(IIO_ACCEL, 1, 0, 0, NULL, 0, IIO_MOD_Y,
+		 (1 << IIO_CHAN_INFO_SCALE_SEPARATE) |
+		 (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE),
+		 accel_y, ADIS16204_SCAN_ACC_Y,
+		 IIO_ST('s', 14, 16, 0), 0),
+	IIO_CHAN_SOFT_TIMESTAMP(5),
+};
 static struct attribute *adis16204_attributes[] = {
-	&iio_dev_attr_in0_supply_raw.dev_attr.attr,
-	&iio_const_attr_in0_supply_scale.dev_attr.attr,
-	&iio_dev_attr_temp_raw.dev_attr.attr,
-	&iio_const_attr_temp_offset.dev_attr.attr,
-	&iio_const_attr_temp_scale.dev_attr.attr,
 	&iio_dev_attr_reset.dev_attr.attr,
-	&iio_const_attr_name.dev_attr.attr,
-	&iio_dev_attr_in1_raw.dev_attr.attr,
-	&iio_const_attr_in1_scale.dev_attr.attr,
-	&iio_dev_attr_accel_x_raw.dev_attr.attr,
-	&iio_dev_attr_accel_y_raw.dev_attr.attr,
 	&iio_dev_attr_accel_xy.dev_attr.attr,
 	&iio_dev_attr_accel_xpeak.dev_attr.attr,
 	&iio_dev_attr_accel_ypeak.dev_attr.attr,
 	&iio_dev_attr_accel_xypeak.dev_attr.attr,
-	&iio_dev_attr_accel_x_offset.dev_attr.attr,
-	&iio_dev_attr_accel_y_offset.dev_attr.attr,
-	&iio_const_attr_accel_x_scale.dev_attr.attr,
-	&iio_const_attr_accel_y_scale.dev_attr.attr,
 	&iio_const_attr_accel_xy_scale.dev_attr.attr,
 	NULL
 };
@@ -468,6 +473,13 @@
 	.attrs = adis16204_attributes,
 };
 
+static const struct iio_info adis16204_info = {
+	.attrs = &adis16204_attribute_group,
+	.read_raw = &adis16204_read_raw,
+	.write_raw = &adis16204_write_raw,
+	.driver_module = THIS_MODULE,
+};
+
 static int __devinit adis16204_probe(struct spi_device *spi)
 {
 	int ret, regdone = 0;
@@ -493,18 +505,18 @@
 	st->us = spi;
 	mutex_init(&st->buf_lock);
 	/* setup the industrialio driver allocated elements */
-	st->indio_dev = iio_allocate_device();
+	st->indio_dev = iio_allocate_device(0);
 	if (st->indio_dev == NULL) {
 		ret = -ENOMEM;
 		goto error_free_tx;
 	}
 
+	st->indio_dev->name = spi->dev.driver->name;
 	st->indio_dev->dev.parent = &spi->dev;
-	st->indio_dev->num_interrupt_lines = 1;
-	st->indio_dev->event_attrs = &adis16204_event_attribute_group;
-	st->indio_dev->attrs = &adis16204_attribute_group;
+	st->indio_dev->info = &adis16204_info;
+	st->indio_dev->channels = adis16204_channels;
+	st->indio_dev->num_channels = ARRAY_SIZE(adis16204_channels);
 	st->indio_dev->dev_data = (void *)(st);
-	st->indio_dev->driver_module = THIS_MODULE;
 	st->indio_dev->modes = INDIO_DIRECT_MODE;
 
 	ret = adis16204_configure_ring(st->indio_dev);
@@ -516,39 +528,30 @@
 		goto error_unreg_ring_funcs;
 	regdone = 1;
 
-	ret = adis16204_initialize_ring(st->indio_dev->ring);
+	ret = iio_ring_buffer_register_ex(st->indio_dev->ring, 0,
+					  adis16204_channels,
+					  ARRAY_SIZE(adis16204_channels));
 	if (ret) {
 		printk(KERN_ERR "failed to initialize the ring\n");
 		goto error_unreg_ring_funcs;
 	}
 
 	if (spi->irq) {
-		ret = iio_register_interrupt_line(spi->irq,
-				st->indio_dev,
-				0,
-				IRQF_TRIGGER_RISING,
-				"adis16204");
-		if (ret)
-			goto error_uninitialize_ring;
-
 		ret = adis16204_probe_trigger(st->indio_dev);
 		if (ret)
-			goto error_unregister_line;
+			goto error_uninitialize_ring;
 	}
 
 	/* Get the device into a sane initial state */
-	ret = adis16204_initial_setup(st);
+	ret = adis16204_initial_setup(st->indio_dev);
 	if (ret)
 		goto error_remove_trigger;
 	return 0;
 
 error_remove_trigger:
 	adis16204_remove_trigger(st->indio_dev);
-error_unregister_line:
-	if (spi->irq)
-		iio_unregister_interrupt_line(st->indio_dev, 0);
 error_uninitialize_ring:
-	adis16204_uninitialize_ring(st->indio_dev->ring);
+	iio_ring_buffer_unregister(st->indio_dev->ring);
 error_unreg_ring_funcs:
 	adis16204_unconfigure_ring(st->indio_dev);
 error_free_dev:
@@ -571,13 +574,8 @@
 	struct adis16204_state *st = spi_get_drvdata(spi);
 	struct iio_dev *indio_dev = st->indio_dev;
 
-	flush_scheduled_work();
-
 	adis16204_remove_trigger(indio_dev);
-	if (spi->irq)
-		iio_unregister_interrupt_line(indio_dev, 0);
-
-	adis16204_uninitialize_ring(indio_dev->ring);
+	iio_ring_buffer_unregister(st->indio_dev->ring);
 	iio_device_unregister(indio_dev);
 	adis16204_unconfigure_ring(indio_dev);
 	kfree(st->tx);
@@ -609,5 +607,5 @@
 module_exit(adis16204_exit);
 
 MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>");
-MODULE_DESCRIPTION("Analog Devices ADIS16204 Programmable High-g Digital Impact Sensor and Recorder");
+MODULE_DESCRIPTION("ADIS16204 High-g Digital Impact Sensor and Recorder");
 MODULE_LICENSE("GPL v2");
diff -druN linux-2.6.39-libre/drivers/staging/iio/accel/adis16204.h linux-3.0-rc7-libre/drivers/staging/iio/accel/adis16204.h
--- linux-2.6.39-libre/drivers/staging/iio/accel/adis16204.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/iio/accel/adis16204.h	2011-07-11 19:51:52.000000000 -0400
@@ -67,9 +67,6 @@
 /**
  * struct adis16204_state - device instance specific data
  * @us:			actual spi_device
- * @work_trigger_to_ring: bh for triggered event handling
- * @inter:		used to check if new interrupt has been triggered
- * @last_timestamp:	passing timestamp from th to bh of interrupt handler
  * @indio_dev:		industrial I/O device structure
  * @trig:		data ready trigger registered with iio
  * @tx:			transmit buffer
@@ -78,8 +75,6 @@
  **/
 struct adis16204_state {
 	struct spi_device		*us;
-	struct work_struct		work_trigger_to_ring;
-	s64				last_timestamp;
 	struct iio_dev			*indio_dev;
 	struct iio_trigger		*trig;
 	u8				*tx;
@@ -87,9 +82,8 @@
 	struct mutex			buf_lock;
 };
 
-int adis16204_set_irq(struct device *dev, bool enable);
+int adis16204_set_irq(struct iio_dev *indio_dev, bool enable);
 
-#ifdef CONFIG_IIO_RING_BUFFER
 enum adis16204_scan {
 	ADIS16204_SCAN_SUPPLY,
 	ADIS16204_SCAN_ACC_X,
@@ -98,6 +92,7 @@
 	ADIS16204_SCAN_TEMP,
 };
 
+#ifdef CONFIG_IIO_RING_BUFFER
 void adis16204_remove_trigger(struct iio_dev *indio_dev);
 int adis16204_probe_trigger(struct iio_dev *indio_dev);
 
@@ -108,8 +103,6 @@
 int adis16204_configure_ring(struct iio_dev *indio_dev);
 void adis16204_unconfigure_ring(struct iio_dev *indio_dev);
 
-int adis16204_initialize_ring(struct iio_ring_buffer *ring);
-void adis16204_uninitialize_ring(struct iio_ring_buffer *ring);
 #else /* CONFIG_IIO_RING_BUFFER */
 
 static inline void adis16204_remove_trigger(struct iio_dev *indio_dev)
@@ -138,14 +131,5 @@
 {
 }
 
-static inline int adis16204_initialize_ring(struct iio_ring_buffer *ring)
-{
-	return 0;
-}
-
-static inline void adis16204_uninitialize_ring(struct iio_ring_buffer *ring)
-{
-}
-
 #endif /* CONFIG_IIO_RING_BUFFER */
 #endif /* SPI_ADIS16204_H_ */
diff -druN linux-2.6.39-libre/drivers/staging/iio/accel/adis16204_ring.c linux-3.0-rc7-libre/drivers/staging/iio/accel/adis16204_ring.c
--- linux-2.6.39-libre/drivers/staging/iio/accel/adis16204_ring.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/iio/accel/adis16204_ring.c	2011-07-11 19:51:52.000000000 -0400
@@ -17,55 +17,6 @@
 #include "../trigger.h"
 #include "adis16204.h"
 
-static IIO_SCAN_EL_C(in_supply, ADIS16204_SCAN_SUPPLY, ADIS16204_SUPPLY_OUT, NULL);
-static IIO_CONST_ATTR_SCAN_EL_TYPE(in_supply, u, 12, 16);
-static IIO_SCAN_EL_C(accel_x, ADIS16204_SCAN_ACC_X, ADIS16204_XACCL_OUT, NULL);
-static IIO_SCAN_EL_C(accel_y, ADIS16204_SCAN_ACC_Y, ADIS16204_YACCL_OUT, NULL);
-static IIO_CONST_ATTR_SCAN_EL_TYPE(accel, s, 14, 16);
-static IIO_SCAN_EL_C(in0, ADIS16204_SCAN_AUX_ADC, ADIS16204_AUX_ADC, NULL);
-static IIO_CONST_ATTR_SCAN_EL_TYPE(in0, u, 12, 16);
-static IIO_SCAN_EL_C(temp, ADIS16204_SCAN_TEMP, ADIS16204_TEMP_OUT, NULL);
-static IIO_CONST_ATTR_SCAN_EL_TYPE(temp, u, 12, 16);
-static IIO_SCAN_EL_TIMESTAMP(5);
-static IIO_CONST_ATTR_SCAN_EL_TYPE(timestamp, s, 64, 64);
-
-static struct attribute *adis16204_scan_el_attrs[] = {
-	&iio_scan_el_in_supply.dev_attr.attr,
-	&iio_const_attr_in_supply_index.dev_attr.attr,
-	&iio_const_attr_in_supply_type.dev_attr.attr,
-	&iio_scan_el_accel_x.dev_attr.attr,
-	&iio_const_attr_accel_x_index.dev_attr.attr,
-	&iio_scan_el_accel_y.dev_attr.attr,
-	&iio_const_attr_accel_y_index.dev_attr.attr,
-	&iio_const_attr_accel_type.dev_attr.attr,
-	&iio_scan_el_in0.dev_attr.attr,
-	&iio_const_attr_in0_index.dev_attr.attr,
-	&iio_const_attr_in0_type.dev_attr.attr,
-	&iio_scan_el_temp.dev_attr.attr,
-	&iio_const_attr_temp_index.dev_attr.attr,
-	&iio_const_attr_temp_type.dev_attr.attr,
-	&iio_scan_el_timestamp.dev_attr.attr,
-	&iio_const_attr_timestamp_index.dev_attr.attr,
-	&iio_const_attr_timestamp_type.dev_attr.attr,
-	NULL,
-};
-
-static struct attribute_group adis16204_scan_el_group = {
-	.attrs = adis16204_scan_el_attrs,
-	.name = "scan_elements",
-};
-
-/**
- * adis16204_poll_func_th() top half interrupt handler called by trigger
- * @private_data:	iio_dev
- **/
-static void adis16204_poll_func_th(struct iio_dev *indio_dev, s64 timestamp)
-{
-	struct adis16204_state *st = iio_dev_get_devdata(indio_dev);
-	st->last_timestamp = timestamp;
-	schedule_work(&st->work_trigger_to_ring);
-}
-
 /**
  * adis16204_read_ring_data() read data registers which will be placed into ring
  * @dev: device associated with child of actual device (iio_dev or iio_trig)
@@ -91,7 +42,8 @@
 		xfers[i].len = 2;
 		xfers[i].delay_usecs = 20;
 		xfers[i].tx_buf = st->tx + 2 * i;
-		st->tx[2 * i] = ADIS16204_READ_REG(ADIS16204_SUPPLY_OUT + 2 * i);
+		st->tx[2 * i]
+			= ADIS16204_READ_REG(ADIS16204_SUPPLY_OUT + 2 * i);
 		st->tx[2 * i + 1] = 0;
 		if (i >= 1)
 			xfers[i].rx_buf = rx + 2 * (i - 1);
@@ -110,21 +62,20 @@
 /* Whilst this makes a lot of calls to iio_sw_ring functions - it is to device
  * specific to be rolled into the core.
  */
-static void adis16204_trigger_bh_to_ring(struct work_struct *work_s)
+static irqreturn_t adis16204_trigger_handler(int irq, void *p)
 {
-	struct adis16204_state *st
-		= container_of(work_s, struct adis16204_state,
-			       work_trigger_to_ring);
-	struct iio_ring_buffer *ring = st->indio_dev->ring;
-
+	struct iio_poll_func *pf = p;
+	struct iio_dev *indio_dev = pf->private_data;
+	struct adis16204_state *st = iio_dev_get_devdata(indio_dev);
+	struct iio_ring_buffer *ring = indio_dev->ring;
 	int i = 0;
 	s16 *data;
-	size_t datasize = ring->access.get_bytes_per_datum(ring);
+	size_t datasize = ring->access->get_bytes_per_datum(ring);
 
 	data = kmalloc(datasize, GFP_KERNEL);
 	if (data == NULL) {
 		dev_err(&st->us->dev, "memory alloc failed in ring bh");
-		return;
+		return -ENOMEM;
 	}
 
 	if (ring->scan_count)
@@ -135,30 +86,32 @@
 
 	/* Guaranteed to be aligned with 8 byte boundary */
 	if (ring->scan_timestamp)
-		*((s64 *)(data + ((i + 3)/4)*4)) = st->last_timestamp;
+		*((s64 *)(data + ((i + 3)/4)*4)) = pf->timestamp;
 
-	ring->access.store_to(ring,
-			      (u8 *)data,
-			      st->last_timestamp);
+	ring->access->store_to(ring, (u8 *)data, pf->timestamp);
 
 	iio_trigger_notify_done(st->indio_dev->trig);
 	kfree(data);
 
-	return;
+	return IRQ_HANDLED;
 }
 
 void adis16204_unconfigure_ring(struct iio_dev *indio_dev)
 {
-	kfree(indio_dev->pollfunc);
+	iio_dealloc_pollfunc(indio_dev->pollfunc);
 	iio_sw_rb_free(indio_dev->ring);
 }
 
+static const struct iio_ring_setup_ops adis16204_ring_setup_ops = {
+	.preenable = &iio_sw_ring_preenable,
+	.postenable = &iio_triggered_ring_postenable,
+	.predisable = &iio_triggered_ring_predisable,
+};
+
 int adis16204_configure_ring(struct iio_dev *indio_dev)
 {
 	int ret = 0;
-	struct adis16204_state *st = indio_dev->dev_data;
 	struct iio_ring_buffer *ring;
-	INIT_WORK(&st->work_trigger_to_ring, adis16204_trigger_bh_to_ring);
 
 	ring = iio_sw_rb_allocate(indio_dev);
 	if (!ring) {
@@ -167,25 +120,30 @@
 	}
 	indio_dev->ring = ring;
 	/* Effectively select the ring buffer implementation */
-	iio_ring_sw_register_funcs(&ring->access);
+	ring->access = &ring_sw_access_funcs;
 	ring->bpe = 2;
-	ring->scan_el_attrs = &adis16204_scan_el_group;
 	ring->scan_timestamp = true;
-	ring->preenable = &iio_sw_ring_preenable;
-	ring->postenable = &iio_triggered_ring_postenable;
-	ring->predisable = &iio_triggered_ring_predisable;
+	ring->setup_ops = &adis16204_ring_setup_ops;
 	ring->owner = THIS_MODULE;
 
 	/* Set default scan mode */
-	iio_scan_mask_set(ring, iio_scan_el_in_supply.number);
-	iio_scan_mask_set(ring, iio_scan_el_accel_x.number);
-	iio_scan_mask_set(ring, iio_scan_el_accel_y.number);
-	iio_scan_mask_set(ring, iio_scan_el_temp.number);
-	iio_scan_mask_set(ring, iio_scan_el_in0.number);
+	iio_scan_mask_set(ring, ADIS16204_SCAN_SUPPLY);
+	iio_scan_mask_set(ring, ADIS16204_SCAN_ACC_X);
+	iio_scan_mask_set(ring, ADIS16204_SCAN_ACC_Y);
+	iio_scan_mask_set(ring, ADIS16204_SCAN_AUX_ADC);
+	iio_scan_mask_set(ring, ADIS16204_SCAN_TEMP);
 
-	ret = iio_alloc_pollfunc(indio_dev, NULL, &adis16204_poll_func_th);
-	if (ret)
+	indio_dev->pollfunc = iio_alloc_pollfunc(&iio_pollfunc_store_time,
+						 &adis16204_trigger_handler,
+						 IRQF_ONESHOT,
+						 indio_dev,
+						 "%s_consumer%d",
+						 indio_dev->name,
+						 indio_dev->id);
+	if (indio_dev->pollfunc == NULL) {
+		ret = -ENOMEM;
 		goto error_iio_sw_rb_free;
+	}
 
 	indio_dev->modes |= INDIO_RING_TRIGGERED;
 	return 0;
@@ -194,13 +152,3 @@
 	iio_sw_rb_free(indio_dev->ring);
 	return ret;
 }
-
-int adis16204_initialize_ring(struct iio_ring_buffer *ring)
-{
-	return iio_ring_buffer_register(ring, 0);
-}
-
-void adis16204_uninitialize_ring(struct iio_ring_buffer *ring)
-{
-	iio_ring_buffer_unregister(ring);
-}
diff -druN linux-2.6.39-libre/drivers/staging/iio/accel/adis16204_trigger.c linux-3.0-rc7-libre/drivers/staging/iio/accel/adis16204_trigger.c
--- linux-2.6.39-libre/drivers/staging/iio/accel/adis16204_trigger.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/iio/accel/adis16204_trigger.c	2011-07-11 19:51:52.000000000 -0400
@@ -13,35 +13,6 @@
 #include "adis16204.h"
 
 /**
- * adis16204_data_rdy_trig_poll() the event handler for the data rdy trig
- **/
-static int adis16204_data_rdy_trig_poll(struct iio_dev *dev_info,
-				       int index,
-				       s64 timestamp,
-				       int no_test)
-{
-	struct adis16204_state *st = iio_dev_get_devdata(dev_info);
-	struct iio_trigger *trig = st->trig;
-
-	iio_trigger_poll(trig, timestamp);
-
-	return IRQ_HANDLED;
-}
-
-IIO_EVENT_SH(data_rdy_trig, &adis16204_data_rdy_trig_poll);
-
-static DEVICE_ATTR(name, S_IRUGO, iio_trigger_read_name, NULL);
-
-static struct attribute *adis16204_trigger_attrs[] = {
-	&dev_attr_name.attr,
-	NULL,
-};
-
-static const struct attribute_group adis16204_trigger_attr_group = {
-	.attrs = adis16204_trigger_attrs,
-};
-
-/**
  * adis16204_data_rdy_trigger_set_state() set datardy interrupt state
  **/
 static int adis16204_data_rdy_trigger_set_state(struct iio_trigger *trig,
@@ -49,31 +20,9 @@
 {
 	struct adis16204_state *st = trig->private_data;
 	struct iio_dev *indio_dev = st->indio_dev;
-	int ret = 0;
 
 	dev_dbg(&indio_dev->dev, "%s (%d)\n", __func__, state);
-	ret = adis16204_set_irq(&st->indio_dev->dev, state);
-	if (state == false) {
-		iio_remove_event_from_list(&iio_event_data_rdy_trig,
-					   &indio_dev->interrupts[0]
-					   ->ev_list);
-		flush_scheduled_work();
-	} else {
-		iio_add_event_to_list(&iio_event_data_rdy_trig,
-				      &indio_dev->interrupts[0]->ev_list);
-	}
-	return ret;
-}
-
-/**
- * adis16204_trig_try_reen() try renabling irq for data rdy trigger
- * @trig:	the datardy trigger
- **/
-static int adis16204_trig_try_reen(struct iio_trigger *trig)
-{
-	struct adis16204_state *st = trig->private_data;
-	enable_irq(st->us->irq);
-	return 0;
+	return adis16204_set_irq(st->indio_dev, state);
 }
 
 int adis16204_probe_trigger(struct iio_dev *indio_dev)
@@ -81,34 +30,38 @@
 	int ret;
 	struct adis16204_state *st = indio_dev->dev_data;
 
-	st->trig = iio_allocate_trigger();
-	st->trig->name = kasprintf(GFP_KERNEL,
-				"adis16204-dev%d",
-				indio_dev->id);
-	if (!st->trig->name) {
+	st->trig = iio_allocate_trigger("adis16204-dev%d", indio_dev->id);
+	if (st->trig == NULL) {
 		ret = -ENOMEM;
-		goto error_free_trig;
+		goto error_ret;
 	}
+
+	ret = request_irq(st->us->irq,
+			  &iio_trigger_generic_data_rdy_poll,
+			  IRQF_TRIGGER_RISING,
+			  "adis16204",
+			  st->trig);
+	if (ret)
+		goto error_free_trig;
+
 	st->trig->dev.parent = &st->us->dev;
 	st->trig->owner = THIS_MODULE;
 	st->trig->private_data = st;
 	st->trig->set_trigger_state = &adis16204_data_rdy_trigger_set_state;
-	st->trig->try_reenable = &adis16204_trig_try_reen;
-	st->trig->control_attrs = &adis16204_trigger_attr_group;
 	ret = iio_trigger_register(st->trig);
 
 	/* select default trigger */
 	indio_dev->trig = st->trig;
 	if (ret)
-		goto error_free_trig_name;
+		goto error_free_irq;
 
 	return 0;
 
-error_free_trig_name:
-	kfree(st->trig->name);
+error_free_irq:
+	free_irq(st->us->irq, st->trig);
 error_free_trig:
 	iio_free_trigger(st->trig);
-
+error_ret:
 	return ret;
 }
 
@@ -117,6 +70,6 @@
 	struct adis16204_state *state = indio_dev->dev_data;
 
 	iio_trigger_unregister(state->trig);
-	kfree(state->trig->name);
+	free_irq(state->us->irq, state->trig);
 	iio_free_trigger(state->trig);
 }
diff -druN linux-2.6.39-libre/drivers/staging/iio/accel/adis16209_core.c linux-3.0-rc7-libre/drivers/staging/iio/accel/adis16209_core.c
--- linux-2.6.39-libre/drivers/staging/iio/accel/adis16209_core.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/iio/accel/adis16209_core.c	2011-07-11 19:51:52.000000000 -0400
@@ -6,9 +6,6 @@
  * Licensed under the GPL-2 or later.
  */
 
-#include <linux/interrupt.h>
-#include <linux/irq.h>
-#include <linux/gpio.h>
 #include <linux/delay.h>
 #include <linux/mutex.h>
 #include <linux/device.h>
@@ -23,27 +20,23 @@
 #include "../ring_generic.h"
 #include "accel.h"
 #include "inclinometer.h"
-#include "../gyro/gyro.h"
 #include "../adc/adc.h"
 
 #include "adis16209.h"
 
 #define DRIVER_NAME		"adis16209"
 
-static int adis16209_check_status(struct device *dev);
-
 /**
  * adis16209_spi_write_reg_8() - write single byte to a register
- * @dev: device associated with child of actual device (iio_dev or iio_trig)
+ * @indio_dev: iio device associated with actual device
  * @reg_address: the address of the register to be written
  * @val: the value to write
  **/
-static int adis16209_spi_write_reg_8(struct device *dev,
-		u8 reg_address,
-		u8 val)
+static int adis16209_spi_write_reg_8(struct iio_dev *indio_dev,
+				     u8 reg_address,
+				     u8 val)
 {
 	int ret;
-	struct iio_dev *indio_dev = dev_get_drvdata(dev);
 	struct adis16209_state *st = iio_dev_get_devdata(indio_dev);
 
 	mutex_lock(&st->buf_lock);
@@ -58,18 +51,17 @@
 
 /**
  * adis16209_spi_write_reg_16() - write 2 bytes to a pair of registers
- * @dev: device associated with child of actual device (iio_dev or iio_trig)
+ * @indio_dev: iio device associated actual device
  * @reg_address: the address of the lower of the two registers. Second register
  *               is assumed to have address one greater.
  * @val: value to be written
  **/
-static int adis16209_spi_write_reg_16(struct device *dev,
-		u8 lower_reg_address,
-		u16 value)
+static int adis16209_spi_write_reg_16(struct iio_dev *indio_dev,
+				      u8 lower_reg_address,
+				      u16 value)
 {
 	int ret;
 	struct spi_message msg;
-	struct iio_dev *indio_dev = dev_get_drvdata(dev);
 	struct adis16209_state *st = iio_dev_get_devdata(indio_dev);
 	struct spi_transfer xfers[] = {
 		{
@@ -82,7 +74,6 @@
 			.tx_buf = st->tx + 2,
 			.bits_per_word = 8,
 			.len = 2,
-			.cs_change = 1,
 			.delay_usecs = 30,
 		},
 	};
@@ -104,17 +95,16 @@
 
 /**
  * adis16209_spi_read_reg_16() - read 2 bytes from a 16-bit register
- * @dev: device associated with child of actual device (iio_dev or iio_trig)
+ * @indio_dev: iio device associated with device
  * @reg_address: the address of the lower of the two registers. Second register
  *               is assumed to have address one greater.
  * @val: somewhere to pass back the value read
  **/
-static int adis16209_spi_read_reg_16(struct device *dev,
-		u8 lower_reg_address,
-		u16 *val)
+static int adis16209_spi_read_reg_16(struct iio_dev *indio_dev,
+				     u8 lower_reg_address,
+				     u16 *val)
 {
 	struct spi_message msg;
-	struct iio_dev *indio_dev = dev_get_drvdata(dev);
 	struct adis16209_state *st = iio_dev_get_devdata(indio_dev);
 	int ret;
 	struct spi_transfer xfers[] = {
@@ -128,7 +118,6 @@
 			.rx_buf = st->rx,
 			.bits_per_word = 8,
 			.len = 2,
-			.cs_change = 1,
 			.delay_usecs = 30,
 		},
 	};
@@ -154,119 +143,14 @@
 	return ret;
 }
 
-static ssize_t adis16209_read_12bit_unsigned(struct device *dev,
-		struct device_attribute *attr,
-		char *buf)
-{
-	int ret;
-	u16 val = 0;
-	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
-
-	ret = adis16209_spi_read_reg_16(dev, this_attr->address, &val);
-	if (ret)
-		return ret;
-
-	if (val & ADIS16209_ERROR_ACTIVE)
-		adis16209_check_status(dev);
-
-	return sprintf(buf, "%u\n", val & 0x0FFF);
-}
-
-static ssize_t adis16209_read_14bit_unsigned(struct device *dev,
-		struct device_attribute *attr,
-		char *buf)
-{
-	int ret;
-	u16 val = 0;
-	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
-
-	ret = adis16209_spi_read_reg_16(dev, this_attr->address, &val);
-	if (ret)
-		return ret;
-
-	if (val & ADIS16209_ERROR_ACTIVE)
-		adis16209_check_status(dev);
-
-	return sprintf(buf, "%u\n", val & 0x3FFF);
-}
-
-static ssize_t adis16209_read_temp(struct device *dev,
-		struct device_attribute *attr,
-		char *buf)
-{
-	struct iio_dev *indio_dev = dev_get_drvdata(dev);
-	ssize_t ret;
-	u16 val;
-
-	/* Take the iio_dev status lock */
-	mutex_lock(&indio_dev->mlock);
-
-	ret = adis16209_spi_read_reg_16(dev, ADIS16209_TEMP_OUT, (u16 *)&val);
-	if (ret)
-		goto error_ret;
-
-	if (val & ADIS16209_ERROR_ACTIVE)
-		adis16209_check_status(dev);
-
-	val &= 0xFFF;
-	ret = sprintf(buf, "%d\n", val);
-
-error_ret:
-	mutex_unlock(&indio_dev->mlock);
-	return ret;
-}
-
-static ssize_t adis16209_read_14bit_signed(struct device *dev,
-		struct device_attribute *attr,
-		char *buf)
-{
-	struct iio_dev *indio_dev = dev_get_drvdata(dev);
-	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
-	s16 val = 0;
-	ssize_t ret;
-
-	mutex_lock(&indio_dev->mlock);
-
-	ret = adis16209_spi_read_reg_16(dev, this_attr->address, (u16 *)&val);
-	if (!ret) {
-		if (val & ADIS16209_ERROR_ACTIVE)
-			adis16209_check_status(dev);
-
-		val = ((s16)(val << 2) >> 2);
-		ret = sprintf(buf, "%d\n", val);
-	}
-
-	mutex_unlock(&indio_dev->mlock);
-
-	return ret;
-}
-
-static ssize_t adis16209_write_16bit(struct device *dev,
-		struct device_attribute *attr,
-		const char *buf,
-		size_t len)
-{
-	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
-	int ret;
-	long val;
-
-	ret = strict_strtol(buf, 10, &val);
-	if (ret)
-		goto error_ret;
-	ret = adis16209_spi_write_reg_16(dev, this_attr->address, val);
-
-error_ret:
-	return ret ? ret : len;
-}
-
-static int adis16209_reset(struct device *dev)
+static int adis16209_reset(struct iio_dev *indio_dev)
 {
 	int ret;
-	ret = adis16209_spi_write_reg_8(dev,
+	ret = adis16209_spi_write_reg_8(indio_dev,
 			ADIS16209_GLOB_CMD,
 			ADIS16209_GLOB_CMD_SW_RESET);
 	if (ret)
-		dev_err(dev, "problem resetting device");
+		dev_err(&indio_dev->dev, "problem resetting device");
 
 	return ret;
 }
@@ -275,23 +159,25 @@
 		struct device_attribute *attr,
 		const char *buf, size_t len)
 {
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+
 	if (len < 1)
 		return -EINVAL;
 	switch (buf[0]) {
 	case '1':
 	case 'y':
 	case 'Y':
-		return adis16209_reset(dev);
+		return adis16209_reset(indio_dev);
 	}
 	return -EINVAL;
 }
 
-int adis16209_set_irq(struct device *dev, bool enable)
+int adis16209_set_irq(struct iio_dev *indio_dev, bool enable)
 {
 	int ret = 0;
 	u16 msc;
 
-	ret = adis16209_spi_read_reg_16(dev, ADIS16209_MSC_CTRL, &msc);
+	ret = adis16209_spi_read_reg_16(indio_dev, ADIS16209_MSC_CTRL, &msc);
 	if (ret)
 		goto error_ret;
 
@@ -302,160 +188,267 @@
 	else
 		msc &= ~ADIS16209_MSC_CTRL_DATA_RDY_EN;
 
-	ret = adis16209_spi_write_reg_16(dev, ADIS16209_MSC_CTRL, msc);
+	ret = adis16209_spi_write_reg_16(indio_dev, ADIS16209_MSC_CTRL, msc);
 
 error_ret:
 	return ret;
 }
 
-static int adis16209_check_status(struct device *dev)
+static int adis16209_check_status(struct iio_dev *indio_dev)
 {
 	u16 status;
 	int ret;
 
-	ret = adis16209_spi_read_reg_16(dev, ADIS16209_DIAG_STAT, &status);
+	ret = adis16209_spi_read_reg_16(indio_dev,
+					ADIS16209_DIAG_STAT, &status);
 	if (ret < 0) {
-		dev_err(dev, "Reading status failed\n");
+		dev_err(&indio_dev->dev, "Reading status failed\n");
 		goto error_ret;
 	}
 	ret = status & 0x1F;
 
 	if (status & ADIS16209_DIAG_STAT_SELFTEST_FAIL)
-		dev_err(dev, "Self test failure\n");
+		dev_err(&indio_dev->dev, "Self test failure\n");
 	if (status & ADIS16209_DIAG_STAT_SPI_FAIL)
-		dev_err(dev, "SPI failure\n");
+		dev_err(&indio_dev->dev, "SPI failure\n");
 	if (status & ADIS16209_DIAG_STAT_FLASH_UPT)
-		dev_err(dev, "Flash update failed\n");
+		dev_err(&indio_dev->dev, "Flash update failed\n");
 	if (status & ADIS16209_DIAG_STAT_POWER_HIGH)
-		dev_err(dev, "Power supply above 3.625V\n");
+		dev_err(&indio_dev->dev, "Power supply above 3.625V\n");
 	if (status & ADIS16209_DIAG_STAT_POWER_LOW)
-		dev_err(dev, "Power supply below 3.15V\n");
+		dev_err(&indio_dev->dev, "Power supply below 3.15V\n");
 
 error_ret:
 	return ret;
 }
 
-static int adis16209_self_test(struct device *dev)
+static int adis16209_self_test(struct iio_dev *indio_dev)
 {
 	int ret;
-	ret = adis16209_spi_write_reg_16(dev,
+	ret = adis16209_spi_write_reg_16(indio_dev,
 			ADIS16209_MSC_CTRL,
 			ADIS16209_MSC_CTRL_SELF_TEST_EN);
 	if (ret) {
-		dev_err(dev, "problem starting self test");
+		dev_err(&indio_dev->dev, "problem starting self test");
 		goto err_ret;
 	}
 
-	adis16209_check_status(dev);
+	adis16209_check_status(indio_dev);
 
 err_ret:
 	return ret;
 }
 
-static int adis16209_initial_setup(struct adis16209_state *st)
+static int adis16209_initial_setup(struct iio_dev *indio_dev)
 {
 	int ret;
-	struct device *dev = &st->indio_dev->dev;
 
 	/* Disable IRQ */
-	ret = adis16209_set_irq(dev, false);
+	ret = adis16209_set_irq(indio_dev, false);
 	if (ret) {
-		dev_err(dev, "disable irq failed");
+		dev_err(&indio_dev->dev, "disable irq failed");
 		goto err_ret;
 	}
 
 	/* Do self test */
-	ret = adis16209_self_test(dev);
+	ret = adis16209_self_test(indio_dev);
 	if (ret) {
-		dev_err(dev, "self test failure");
+		dev_err(&indio_dev->dev, "self test failure");
 		goto err_ret;
 	}
 
 	/* Read status register to check the result */
-	ret = adis16209_check_status(dev);
+	ret = adis16209_check_status(indio_dev);
 	if (ret) {
-		adis16209_reset(dev);
-		dev_err(dev, "device not playing ball -> reset");
+		adis16209_reset(indio_dev);
+		dev_err(&indio_dev->dev, "device not playing ball -> reset");
 		msleep(ADIS16209_STARTUP_DELAY);
-		ret = adis16209_check_status(dev);
+		ret = adis16209_check_status(indio_dev);
 		if (ret) {
-			dev_err(dev, "giving up");
+			dev_err(&indio_dev->dev, "giving up");
 			goto err_ret;
 		}
 	}
 
-	printk(KERN_INFO DRIVER_NAME ": at CS%d (irq %d)\n",
-			st->us->chip_select, st->us->irq);
-
 err_ret:
 	return ret;
 }
 
-static IIO_DEV_ATTR_IN_NAMED_RAW(0, supply, adis16209_read_14bit_unsigned,
-		ADIS16209_SUPPLY_OUT);
-static IIO_CONST_ATTR_IN_NAMED_SCALE(0, supply, "0.30518");
-static IIO_DEV_ATTR_IN_RAW(1, adis16209_read_12bit_unsigned,
-		ADIS16209_AUX_ADC);
-static IIO_CONST_ATTR(in1_scale, "0.6105");
-
-static IIO_DEV_ATTR_ACCEL_X(adis16209_read_14bit_signed,
-		ADIS16209_XACCL_OUT);
-static IIO_DEV_ATTR_ACCEL_Y(adis16209_read_14bit_signed,
-		ADIS16209_YACCL_OUT);
-static IIO_DEV_ATTR_ACCEL_X_CALIBBIAS(S_IWUSR | S_IRUGO,
-		adis16209_read_14bit_signed,
-		adis16209_write_16bit,
-		ADIS16209_XACCL_NULL);
-static IIO_DEV_ATTR_ACCEL_Y_CALIBBIAS(S_IWUSR | S_IRUGO,
-		adis16209_read_14bit_signed,
-		adis16209_write_16bit,
-		ADIS16209_YACCL_NULL);
-static IIO_CONST_ATTR_ACCEL_SCALE("0.002394195531");
+enum adis16209_chan {
+	in_supply,
+	temp,
+	accel_x,
+	accel_y,
+	incli_x,
+	incli_y,
+	in_aux,
+	rot,
+};
 
-static IIO_DEV_ATTR_INCLI_X(adis16209_read_14bit_signed,
-		ADIS16209_XINCL_OUT);
-static IIO_DEV_ATTR_INCLI_Y(adis16209_read_14bit_signed,
-		ADIS16209_YINCL_OUT);
-static IIO_CONST_ATTR(incli_scale, "0.00043633231");
+static const u8 adis16209_addresses[8][2] = {
+	[in_supply] = { ADIS16209_SUPPLY_OUT },
+	[in_aux] = { ADIS16209_AUX_ADC },
+	[accel_x] = { ADIS16209_XACCL_OUT, ADIS16209_XACCL_NULL },
+	[accel_y] = { ADIS16209_YACCL_OUT, ADIS16209_YACCL_NULL },
+	[incli_x] = { ADIS16209_XINCL_OUT, ADIS16209_XINCL_NULL },
+	[incli_y] = { ADIS16209_YINCL_OUT, ADIS16209_YINCL_NULL },
+	[rot] = { ADIS16209_ROT_OUT },
+	[temp] = { ADIS16209_TEMP_OUT },
+};
 
-static IIO_DEVICE_ATTR(rot_raw, S_IRUGO, adis16209_read_14bit_signed,
-		       NULL, ADIS16209_ROT_OUT);
+static int adis16209_write_raw(struct iio_dev *indio_dev,
+			       struct iio_chan_spec const *chan,
+			       int val,
+			       int val2,
+			       long mask)
+{
+	int bits;
+	s16 val16;
+	u8 addr;
+	switch (mask) {
+	case (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE):
+		switch (chan->type) {
+		case IIO_ACCEL:
+		case IIO_INCLI:
+			bits = 14;
+			break;
+		default:
+			return -EINVAL;
+		};
+		val16 = val & ((1 << bits) - 1);
+		addr = adis16209_addresses[chan->address][1];
+		return adis16209_spi_write_reg_16(indio_dev, addr, val16);
+	}
+	return -EINVAL;
+}
 
-static IIO_DEV_ATTR_TEMP_RAW(adis16209_read_temp);
-static IIO_CONST_ATTR_TEMP_OFFSET("25");
-static IIO_CONST_ATTR_TEMP_SCALE("-0.47");
+static int adis16209_read_raw(struct iio_dev *indio_dev,
+			      struct iio_chan_spec const *chan,
+			      int *val, int *val2,
+			      long mask)
+{
+	int ret;
+	int bits;
+	u8 addr;
+	s16 val16;
 
-static IIO_DEVICE_ATTR(reset, S_IWUSR, NULL, adis16209_write_reset, 0);
+	switch (mask) {
+	case 0:
+		mutex_lock(&indio_dev->mlock);
+		addr = adis16209_addresses[chan->address][0];
+		ret = adis16209_spi_read_reg_16(indio_dev, addr, &val16);
+		if (ret)
+			return ret;
 
-static IIO_CONST_ATTR_NAME("adis16209");
+		if (val16 & ADIS16209_ERROR_ACTIVE) {
+			ret = adis16209_check_status(indio_dev);
+			if (ret)
+				return ret;
+		}
+		val16 = val16 & ((1 << chan->scan_type.realbits) - 1);
+		if (chan->scan_type.sign == 's')
+			val16 = (s16)(val16 <<
+				      (16 - chan->scan_type.realbits)) >>
+				(16 - chan->scan_type.realbits);
+		*val = val16;
+		mutex_unlock(&indio_dev->mlock);
+		return IIO_VAL_INT;
+	case (1 << IIO_CHAN_INFO_SCALE_SEPARATE):
+	case (1 << IIO_CHAN_INFO_SCALE_SHARED):
+		switch (chan->type) {
+		case IIO_IN:
+			*val = 0;
+			if (chan->channel == 0)
+				*val2 = 305180;
+			else
+				*val2 = 610500;
+			return IIO_VAL_INT_PLUS_MICRO;
+		case IIO_TEMP:
+			*val = 0;
+			*val2 = -470000;
+			return IIO_VAL_INT_PLUS_MICRO;
+		case IIO_ACCEL:
+			*val = 0;
+			*val2 = 2394;
+			return IIO_VAL_INT_PLUS_MICRO;
+		case IIO_INCLI:
+			*val = 0;
+			*val2 = 436;
+			return IIO_VAL_INT_PLUS_MICRO;
+		default:
+			return -EINVAL;
+		}
+		break;
+	case (1 << IIO_CHAN_INFO_OFFSET_SEPARATE):
+		*val = 25;
+		return IIO_VAL_INT;
+	case (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE):
+		switch (chan->type) {
+		case IIO_ACCEL:
+			bits = 14;
+			break;
+		default:
+			return -EINVAL;
+		};
+		mutex_lock(&indio_dev->mlock);
+		addr = adis16209_addresses[chan->address][1];
+		ret = adis16209_spi_read_reg_16(indio_dev, addr, &val16);
+		if (ret) {
+			mutex_unlock(&indio_dev->mlock);
+			return ret;
+		}
+		val16 &= (1 << bits) - 1;
+		val16 = (s16)(val16 << (16 - bits)) >> (16 - bits);
+		*val = val16;
+		mutex_unlock(&indio_dev->mlock);
+		return IIO_VAL_INT;
+	}
+	return -EINVAL;
+}
 
-static struct attribute *adis16209_event_attributes[] = {
-	NULL
+static struct iio_chan_spec adis16209_channels[] = {
+	IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 0, 0,
+		 (1 << IIO_CHAN_INFO_SCALE_SEPARATE),
+		 in_supply, ADIS16209_SCAN_SUPPLY,
+		 IIO_ST('u', 14, 16, 0), 0),
+	IIO_CHAN(IIO_TEMP, 0, 1, 0, NULL, 0, 0,
+		 (1 << IIO_CHAN_INFO_SCALE_SEPARATE) |
+		 (1 << IIO_CHAN_INFO_OFFSET_SEPARATE),
+		 temp, ADIS16209_SCAN_TEMP,
+		 IIO_ST('u', 12, 16, 0), 0),
+	IIO_CHAN(IIO_ACCEL, 1, 0, 0, NULL, 0, IIO_MOD_X,
+		 (1 << IIO_CHAN_INFO_SCALE_SHARED) |
+		 (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE),
+		 accel_x, ADIS16209_SCAN_ACC_X,
+		 IIO_ST('s', 14, 16, 0), 0),
+	IIO_CHAN(IIO_ACCEL, 1, 0, 0, NULL, 0, IIO_MOD_Y,
+		 (1 << IIO_CHAN_INFO_SCALE_SHARED) |
+		 (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE),
+		 accel_y, ADIS16209_SCAN_ACC_Y,
+		 IIO_ST('s', 14, 16, 0), 0),
+	IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 1, 0,
+		 (1 << IIO_CHAN_INFO_SCALE_SEPARATE),
+		 in_aux, ADIS16209_SCAN_AUX_ADC,
+		 IIO_ST('u', 12, 16, 0), 0),
+	IIO_CHAN(IIO_INCLI, 0, 1, 0, NULL, 0, IIO_MOD_X,
+		 (1 << IIO_CHAN_INFO_SCALE_SHARED),
+		 incli_x, ADIS16209_SCAN_INCLI_X,
+		 IIO_ST('s', 14, 16, 0), 0),
+	IIO_CHAN(IIO_INCLI, 0, 1, 0, NULL, 0, IIO_MOD_Y,
+		 (1 << IIO_CHAN_INFO_SCALE_SHARED),
+		 incli_y, ADIS16209_SCAN_INCLI_Y,
+		 IIO_ST('s', 14, 16, 0), 0),
+	IIO_CHAN(IIO_ROT, 0, 1, 0, NULL, 0, IIO_MOD_X,
+		    0,
+		    rot, ADIS16209_SCAN_ROT,
+		    IIO_ST('s', 14, 16, 0), 0),
+	IIO_CHAN_SOFT_TIMESTAMP(8)
 };
 
-static struct attribute_group adis16209_event_attribute_group = {
-	.attrs = adis16209_event_attributes,
-};
+static IIO_DEVICE_ATTR(reset, S_IWUSR, NULL, adis16209_write_reset, 0);
 
 static struct attribute *adis16209_attributes[] = {
-	&iio_dev_attr_in0_supply_raw.dev_attr.attr,
-	&iio_const_attr_in0_supply_scale.dev_attr.attr,
-	&iio_dev_attr_temp_raw.dev_attr.attr,
-	&iio_const_attr_temp_offset.dev_attr.attr,
-	&iio_const_attr_temp_scale.dev_attr.attr,
 	&iio_dev_attr_reset.dev_attr.attr,
-	&iio_const_attr_name.dev_attr.attr,
-	&iio_dev_attr_in1_raw.dev_attr.attr,
-	&iio_const_attr_in1_scale.dev_attr.attr,
-	&iio_dev_attr_accel_x_raw.dev_attr.attr,
-	&iio_dev_attr_accel_y_raw.dev_attr.attr,
-	&iio_dev_attr_accel_x_calibbias.dev_attr.attr,
-	&iio_dev_attr_accel_y_calibbias.dev_attr.attr,
-	&iio_const_attr_accel_scale.dev_attr.attr,
-	&iio_dev_attr_incli_x_raw.dev_attr.attr,
-	&iio_dev_attr_incli_y_raw.dev_attr.attr,
-	&iio_const_attr_incli_scale.dev_attr.attr,
-	&iio_dev_attr_rot_raw.dev_attr.attr,
 	NULL
 };
 
@@ -463,6 +456,13 @@
 	.attrs = adis16209_attributes,
 };
 
+static const struct iio_info adis16209_info = {
+	.attrs = &adis16209_attribute_group,
+	.read_raw = &adis16209_read_raw,
+	.write_raw = &adis16209_write_raw,
+	.driver_module = THIS_MODULE,
+};
+
 static int __devinit adis16209_probe(struct spi_device *spi)
 {
 	int ret, regdone = 0;
@@ -488,18 +488,18 @@
 	st->us = spi;
 	mutex_init(&st->buf_lock);
 	/* setup the industrialio driver allocated elements */
-	st->indio_dev = iio_allocate_device();
+	st->indio_dev = iio_allocate_device(0);
 	if (st->indio_dev == NULL) {
 		ret = -ENOMEM;
 		goto error_free_tx;
 	}
 
+	st->indio_dev->name = spi->dev.driver->name;
 	st->indio_dev->dev.parent = &spi->dev;
-	st->indio_dev->num_interrupt_lines = 1;
-	st->indio_dev->event_attrs = &adis16209_event_attribute_group;
-	st->indio_dev->attrs = &adis16209_attribute_group;
+	st->indio_dev->info = &adis16209_info;
+	st->indio_dev->channels = adis16209_channels;
+	st->indio_dev->num_channels = ARRAY_SIZE(adis16209_channels);
 	st->indio_dev->dev_data = (void *)(st);
-	st->indio_dev->driver_module = THIS_MODULE;
 	st->indio_dev->modes = INDIO_DIRECT_MODE;
 
 	ret = adis16209_configure_ring(st->indio_dev);
@@ -511,37 +511,28 @@
 		goto error_unreg_ring_funcs;
 	regdone = 1;
 
-	ret = iio_ring_buffer_register(st->indio_dev->ring, 0);
+	ret = iio_ring_buffer_register_ex(st->indio_dev->ring, 0,
+					  adis16209_channels,
+					  ARRAY_SIZE(adis16209_channels));
 	if (ret) {
 		printk(KERN_ERR "failed to initialize the ring\n");
 		goto error_unreg_ring_funcs;
 	}
 
 	if (spi->irq) {
-		ret = iio_register_interrupt_line(spi->irq,
-				st->indio_dev,
-				0,
-				IRQF_TRIGGER_RISING,
-				"adis16209");
-		if (ret)
-			goto error_uninitialize_ring;
-
 		ret = adis16209_probe_trigger(st->indio_dev);
 		if (ret)
-			goto error_unregister_line;
+			goto error_uninitialize_ring;
 	}
 
 	/* Get the device into a sane initial state */
-	ret = adis16209_initial_setup(st);
+	ret = adis16209_initial_setup(st->indio_dev);
 	if (ret)
 		goto error_remove_trigger;
 	return 0;
 
 error_remove_trigger:
 	adis16209_remove_trigger(st->indio_dev);
-error_unregister_line:
-	if (spi->irq)
-		iio_unregister_interrupt_line(st->indio_dev, 0);
 error_uninitialize_ring:
 	iio_ring_buffer_unregister(st->indio_dev->ring);
 error_unreg_ring_funcs:
@@ -569,9 +560,6 @@
 	flush_scheduled_work();
 
 	adis16209_remove_trigger(indio_dev);
-	if (spi->irq)
-		iio_unregister_interrupt_line(indio_dev, 0);
-
 	iio_ring_buffer_unregister(indio_dev->ring);
 	iio_device_unregister(indio_dev);
 	adis16209_unconfigure_ring(indio_dev);
diff -druN linux-2.6.39-libre/drivers/staging/iio/accel/adis16209.h linux-3.0-rc7-libre/drivers/staging/iio/accel/adis16209.h
--- linux-2.6.39-libre/drivers/staging/iio/accel/adis16209.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/iio/accel/adis16209.h	2011-07-11 19:51:52.000000000 -0400
@@ -104,8 +104,6 @@
 /**
  * struct adis16209_state - device instance specific data
  * @us:			actual spi_device
- * @work_trigger_to_ring: bh for triggered event handling
- * @last_timestamp:	passing timestamp from th to bh of interrupt handler
  * @indio_dev:		industrial I/O device structure
  * @trig:		data ready trigger registered with iio
  * @tx:			transmit buffer
@@ -114,8 +112,6 @@
  **/
 struct adis16209_state {
 	struct spi_device		*us;
-	struct work_struct		work_trigger_to_ring;
-	s64				last_timestamp;
 	struct iio_dev			*indio_dev;
 	struct iio_trigger		*trig;
 	u8				*tx;
@@ -123,9 +119,7 @@
 	struct mutex			buf_lock;
 };
 
-int adis16209_set_irq(struct device *dev, bool enable);
-
-#ifdef CONFIG_IIO_RING_BUFFER
+int adis16209_set_irq(struct iio_dev *indio_dev, bool enable);
 
 #define ADIS16209_SCAN_SUPPLY	0
 #define ADIS16209_SCAN_ACC_X	1
@@ -136,6 +130,8 @@
 #define ADIS16209_SCAN_INCLI_Y	6
 #define ADIS16209_SCAN_ROT	7
 
+#ifdef CONFIG_IIO_RING_BUFFER
+
 void adis16209_remove_trigger(struct iio_dev *indio_dev);
 int adis16209_probe_trigger(struct iio_dev *indio_dev);
 
diff -druN linux-2.6.39-libre/drivers/staging/iio/accel/adis16209_ring.c linux-3.0-rc7-libre/drivers/staging/iio/accel/adis16209_ring.c
--- linux-2.6.39-libre/drivers/staging/iio/accel/adis16209_ring.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/iio/accel/adis16209_ring.c	2011-07-11 19:51:52.000000000 -0400
@@ -17,71 +17,6 @@
 #include "../trigger.h"
 #include "adis16209.h"
 
-static IIO_SCAN_EL_C(in_supply, ADIS16209_SCAN_SUPPLY,
-		     ADIS16209_SUPPLY_OUT, NULL);
-static IIO_CONST_ATTR_SCAN_EL_TYPE(in_supply, u, 14, 16)
-static IIO_SCAN_EL_C(accel_x, ADIS16209_SCAN_ACC_X, ADIS16209_XACCL_OUT, NULL);
-static IIO_SCAN_EL_C(accel_y, ADIS16209_SCAN_ACC_Y, ADIS16209_YACCL_OUT, NULL);
-static IIO_CONST_ATTR_SCAN_EL_TYPE(accel, s, 14, 16);
-static IIO_SCAN_EL_C(in0, ADIS16209_SCAN_AUX_ADC, ADIS16209_AUX_ADC, NULL);
-static IIO_CONST_ATTR_SCAN_EL_TYPE(in0, u, 12, 16);
-static IIO_SCAN_EL_C(temp, ADIS16209_SCAN_TEMP, ADIS16209_TEMP_OUT, NULL);
-static IIO_CONST_ATTR_SCAN_EL_TYPE(temp, u, 12, 16);
-static IIO_SCAN_EL_C(incli_x, ADIS16209_SCAN_INCLI_X,
-		     ADIS16209_XINCL_OUT, NULL);
-static IIO_SCAN_EL_C(incli_y, ADIS16209_SCAN_INCLI_Y,
-		     ADIS16209_YINCL_OUT, NULL);
-static IIO_CONST_ATTR_SCAN_EL_TYPE(incli, s, 14, 16);
-static IIO_SCAN_EL_C(rot, ADIS16209_SCAN_ROT, ADIS16209_ROT_OUT, NULL);
-static IIO_CONST_ATTR_SCAN_EL_TYPE(rot, s, 14, 16);
-static IIO_SCAN_EL_TIMESTAMP(8);
-static IIO_CONST_ATTR_SCAN_EL_TYPE(timestamp, s, 64, 64);
-
-static struct attribute *adis16209_scan_el_attrs[] = {
-	&iio_scan_el_in_supply.dev_attr.attr,
-	&iio_const_attr_in_supply_index.dev_attr.attr,
-	&iio_const_attr_in_supply_type.dev_attr.attr,
-	&iio_scan_el_accel_x.dev_attr.attr,
-	&iio_const_attr_accel_x_index.dev_attr.attr,
-	&iio_scan_el_accel_y.dev_attr.attr,
-	&iio_const_attr_accel_y_index.dev_attr.attr,
-	&iio_const_attr_accel_type.dev_attr.attr,
-	&iio_scan_el_in0.dev_attr.attr,
-	&iio_const_attr_in0_index.dev_attr.attr,
-	&iio_const_attr_in0_type.dev_attr.attr,
-	&iio_scan_el_temp.dev_attr.attr,
-	&iio_const_attr_temp_index.dev_attr.attr,
-	&iio_const_attr_temp_type.dev_attr.attr,
-	&iio_scan_el_incli_x.dev_attr.attr,
-	&iio_const_attr_incli_x_index.dev_attr.attr,
-	&iio_scan_el_incli_y.dev_attr.attr,
-	&iio_const_attr_incli_y_index.dev_attr.attr,
-	&iio_const_attr_incli_type.dev_attr.attr,
-	&iio_scan_el_rot.dev_attr.attr,
-	&iio_const_attr_rot_index.dev_attr.attr,
-	&iio_const_attr_rot_type.dev_attr.attr,
-	&iio_scan_el_timestamp.dev_attr.attr,
-	&iio_const_attr_timestamp_index.dev_attr.attr,
-	&iio_const_attr_timestamp_type.dev_attr.attr,
-	NULL,
-};
-
-static struct attribute_group adis16209_scan_el_group = {
-	.attrs = adis16209_scan_el_attrs,
-	.name = "scan_elements",
-};
-
-/**
- * adis16209_poll_func_th() top half interrupt handler called by trigger
- * @private_data:	iio_dev
- **/
-static void adis16209_poll_func_th(struct iio_dev *indio_dev, s64 time)
-{
-	struct adis16209_state *st = iio_dev_get_devdata(indio_dev);
-	st->last_timestamp = time;
-	schedule_work(&st->work_trigger_to_ring);
-}
-
 /**
  * adis16209_read_ring_data() read data registers which will be placed into ring
  * @dev: device associated with child of actual device (iio_dev or iio_trig)
@@ -127,55 +62,56 @@
 /* Whilst this makes a lot of calls to iio_sw_ring functions - it is to device
  * specific to be rolled into the core.
  */
-static void adis16209_trigger_bh_to_ring(struct work_struct *work_s)
+static irqreturn_t adis16209_trigger_handler(int irq, void *p)
 {
-	struct adis16209_state *st
-		= container_of(work_s, struct adis16209_state,
-			       work_trigger_to_ring);
-	struct iio_ring_buffer *ring = st->indio_dev->ring;
+	struct iio_poll_func *pf = p;
+	struct iio_dev *indio_dev = pf->private_data;
+	struct adis16209_state *st = iio_dev_get_devdata(indio_dev);
+	struct iio_ring_buffer *ring = indio_dev->ring;
 
 	int i = 0;
 	s16 *data;
-	size_t datasize = ring->access.get_bytes_per_datum(ring);
+	size_t datasize = ring->access->get_bytes_per_datum(ring);
 
 	data = kmalloc(datasize , GFP_KERNEL);
 	if (data == NULL) {
 		dev_err(&st->us->dev, "memory alloc failed in ring bh");
-		return;
+		return -ENOMEM;
 	}
 
-	if (ring->scan_count)
-		if (adis16209_read_ring_data(&st->indio_dev->dev, st->rx) >= 0)
-			for (; i < ring->scan_count; i++)
-				data[i] = be16_to_cpup(
-					(__be16 *)&(st->rx[i*2]));
+	if (ring->scan_count &&
+	    adis16209_read_ring_data(&st->indio_dev->dev, st->rx) >= 0)
+		for (; i < ring->scan_count; i++)
+			data[i] = be16_to_cpup((__be16 *)&(st->rx[i*2]));
 
 	/* Guaranteed to be aligned with 8 byte boundary */
 	if (ring->scan_timestamp)
-		*((s64 *)(data + ((i + 3)/4)*4)) = st->last_timestamp;
+		*((s64 *)(data + ((i + 3)/4)*4)) = pf->timestamp;
 
-	ring->access.store_to(ring,
-			      (u8 *)data,
-			      st->last_timestamp);
+	ring->access->store_to(ring, (u8 *)data, pf->timestamp);
 
 	iio_trigger_notify_done(st->indio_dev->trig);
 	kfree(data);
 
-	return;
+	return IRQ_HANDLED;
 }
 
 void adis16209_unconfigure_ring(struct iio_dev *indio_dev)
 {
-	kfree(indio_dev->pollfunc);
+	iio_dealloc_pollfunc(indio_dev->pollfunc);
 	iio_sw_rb_free(indio_dev->ring);
 }
 
+static const struct iio_ring_setup_ops adis16209_ring_setup_ops = {
+	.preenable = &iio_sw_ring_preenable,
+	.postenable = &iio_triggered_ring_postenable,
+	.predisable = &iio_triggered_ring_predisable,
+};
+
 int adis16209_configure_ring(struct iio_dev *indio_dev)
 {
 	int ret = 0;
-	struct adis16209_state *st = indio_dev->dev_data;
 	struct iio_ring_buffer *ring;
-	INIT_WORK(&st->work_trigger_to_ring, adis16209_trigger_bh_to_ring);
 
 	ring = iio_sw_rb_allocate(indio_dev);
 	if (!ring) {
@@ -184,28 +120,33 @@
 	}
 	indio_dev->ring = ring;
 	/* Effectively select the ring buffer implementation */
-	iio_ring_sw_register_funcs(&ring->access);
+	ring->access = &ring_sw_access_funcs;
 	ring->bpe = 2;
-	ring->scan_el_attrs = &adis16209_scan_el_group;
 	ring->scan_timestamp = true;
-	ring->preenable = &iio_sw_ring_preenable;
-	ring->postenable = &iio_triggered_ring_postenable;
-	ring->predisable = &iio_triggered_ring_predisable;
+	ring->setup_ops = &adis16209_ring_setup_ops;
 	ring->owner = THIS_MODULE;
 
 	/* Set default scan mode */
-	iio_scan_mask_set(ring, iio_scan_el_in_supply.number);
-	iio_scan_mask_set(ring, iio_scan_el_rot.number);
-	iio_scan_mask_set(ring, iio_scan_el_accel_x.number);
-	iio_scan_mask_set(ring, iio_scan_el_accel_y.number);
-	iio_scan_mask_set(ring, iio_scan_el_temp.number);
-	iio_scan_mask_set(ring, iio_scan_el_in0.number);
-	iio_scan_mask_set(ring, iio_scan_el_incli_x.number);
-	iio_scan_mask_set(ring, iio_scan_el_incli_y.number);
+	iio_scan_mask_set(ring, ADIS16209_SCAN_SUPPLY);
+	iio_scan_mask_set(ring, ADIS16209_SCAN_ACC_X);
+	iio_scan_mask_set(ring, ADIS16209_SCAN_ACC_Y);
+	iio_scan_mask_set(ring, ADIS16209_SCAN_AUX_ADC);
+	iio_scan_mask_set(ring, ADIS16209_SCAN_TEMP);
+	iio_scan_mask_set(ring, ADIS16209_SCAN_INCLI_X);
+	iio_scan_mask_set(ring, ADIS16209_SCAN_INCLI_Y);
+	iio_scan_mask_set(ring, ADIS16209_SCAN_ROT);
 
-	ret = iio_alloc_pollfunc(indio_dev, NULL, &adis16209_poll_func_th);
-	if (ret)
+	indio_dev->pollfunc = iio_alloc_pollfunc(&iio_pollfunc_store_time,
+						 &adis16209_trigger_handler,
+						 IRQF_ONESHOT,
+						 indio_dev,
+						 "%s_consumer%d",
+						 indio_dev->name,
+						 indio_dev->id);
+	if (indio_dev->pollfunc == NULL) {
+		ret = -ENOMEM;
 		goto error_iio_sw_rb_free;
+	}
 
 	indio_dev->modes |= INDIO_RING_TRIGGERED;
 	return 0;
diff -druN linux-2.6.39-libre/drivers/staging/iio/accel/adis16209_trigger.c linux-3.0-rc7-libre/drivers/staging/iio/accel/adis16209_trigger.c
--- linux-2.6.39-libre/drivers/staging/iio/accel/adis16209_trigger.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/iio/accel/adis16209_trigger.c	2011-07-11 19:51:52.000000000 -0400
@@ -15,32 +15,12 @@
 /**
  * adis16209_data_rdy_trig_poll() the event handler for the data rdy trig
  **/
-static int adis16209_data_rdy_trig_poll(struct iio_dev *dev_info,
-				       int index,
-				       s64 timestamp,
-				       int no_test)
+static irqreturn_t adis16209_data_rdy_trig_poll(int irq, void *trig)
 {
-	struct adis16209_state *st = iio_dev_get_devdata(dev_info);
-	struct iio_trigger *trig = st->trig;
-
-	iio_trigger_poll(trig, timestamp);
-
+	iio_trigger_poll(trig, iio_get_time_ns());
 	return IRQ_HANDLED;
 }
 
-IIO_EVENT_SH(data_rdy_trig, &adis16209_data_rdy_trig_poll);
-
-static IIO_TRIGGER_NAME_ATTR;
-
-static struct attribute *adis16209_trigger_attrs[] = {
-	&dev_attr_name.attr,
-	NULL,
-};
-
-static const struct attribute_group adis16209_trigger_attr_group = {
-	.attrs = adis16209_trigger_attrs,
-};
-
 /**
  * adis16209_data_rdy_trigger_set_state() set datardy interrupt state
  **/
@@ -49,31 +29,9 @@
 {
 	struct adis16209_state *st = trig->private_data;
 	struct iio_dev *indio_dev = st->indio_dev;
-	int ret = 0;
 
 	dev_dbg(&indio_dev->dev, "%s (%d)\n", __func__, state);
-	ret = adis16209_set_irq(&st->indio_dev->dev, state);
-	if (state == false) {
-		iio_remove_event_from_list(&iio_event_data_rdy_trig,
-					   &indio_dev->interrupts[0]
-					   ->ev_list);
-		flush_scheduled_work();
-	} else {
-		iio_add_event_to_list(&iio_event_data_rdy_trig,
-				      &indio_dev->interrupts[0]->ev_list);
-	}
-	return ret;
-}
-
-/**
- * adis16209_trig_try_reen() try renabling irq for data rdy trigger
- * @trig:	the datardy trigger
- **/
-static int adis16209_trig_try_reen(struct iio_trigger *trig)
-{
-	struct adis16209_state *st = trig->private_data;
-	enable_irq(st->us->irq);
-	return 0;
+	return adis16209_set_irq(st->indio_dev, state);
 }
 
 int adis16209_probe_trigger(struct iio_dev *indio_dev)
@@ -81,34 +39,37 @@
 	int ret;
 	struct adis16209_state *st = indio_dev->dev_data;
 
-	st->trig = iio_allocate_trigger();
-	st->trig->name = kasprintf(GFP_KERNEL,
-				   "adis16209-dev%d",
-				   indio_dev->id);
-	if (!st->trig->name) {
+	st->trig = iio_allocate_trigger("adis16209-dev%d", indio_dev->id);
+	if (st->trig == NULL) {
 		ret = -ENOMEM;
-		goto error_free_trig;
+		goto error_ret;
 	}
+
+	ret = request_irq(st->us->irq,
+			  adis16209_data_rdy_trig_poll,
+			  IRQF_TRIGGER_RISING,
+			  "adis16209",
+			  st->trig);
+	if (ret)
+		goto error_free_trig;
 	st->trig->dev.parent = &st->us->dev;
 	st->trig->owner = THIS_MODULE;
 	st->trig->private_data = st;
 	st->trig->set_trigger_state = &adis16209_data_rdy_trigger_set_state;
-	st->trig->try_reenable = &adis16209_trig_try_reen;
-	st->trig->control_attrs = &adis16209_trigger_attr_group;
 	ret = iio_trigger_register(st->trig);
 
 	/* select default trigger */
 	indio_dev->trig = st->trig;
 	if (ret)
-		goto error_free_trig_name;
+		goto error_free_irq;
 
 	return 0;
 
-error_free_trig_name:
-	kfree(st->trig->name);
+error_free_irq:
+	free_irq(st->us->irq, st->trig);
 error_free_trig:
 	iio_free_trigger(st->trig);
-
+error_ret:
 	return ret;
 }
 
@@ -117,6 +78,6 @@
 	struct adis16209_state *state = indio_dev->dev_data;
 
 	iio_trigger_unregister(state->trig);
-	kfree(state->trig->name);
+	free_irq(state->us->irq, state->trig);
 	iio_free_trigger(state->trig);
 }
diff -druN linux-2.6.39-libre/drivers/staging/iio/accel/adis16220_core.c linux-3.0-rc7-libre/drivers/staging/iio/accel/adis16220_core.c
--- linux-2.6.39-libre/drivers/staging/iio/accel/adis16220_core.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/iio/accel/adis16220_core.c	2011-07-11 19:51:52.000000000 -0400
@@ -521,8 +521,6 @@
 
 static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("100200");
 
-static IIO_CONST_ATTR_NAME("adis16220");
-
 static struct attribute *adis16220_attributes[] = {
 	&iio_dev_attr_in0_supply_raw.dev_attr.attr,
 	&iio_const_attr_in0_supply_scale.dev_attr.attr,
@@ -539,7 +537,6 @@
 	&iio_dev_attr_reset.dev_attr.attr,
 	&iio_dev_attr_capture.dev_attr.attr,
 	&iio_dev_attr_capture_count.dev_attr.attr,
-	&iio_const_attr_name.dev_attr.attr,
 	NULL
 };
 
@@ -547,6 +544,10 @@
 	.attrs = adis16220_attributes,
 };
 
+static const struct iio_info adis16220_info = {
+	.attrs = &adis16220_attribute_group,
+	.driver_module = THIS_MODULE,
+};
 static int __devinit adis16220_probe(struct spi_device *spi)
 {
 	int ret, regdone = 0;
@@ -572,16 +573,16 @@
 	st->us = spi;
 	mutex_init(&st->buf_lock);
 	/* setup the industrialio driver allocated elements */
-	st->indio_dev = iio_allocate_device();
+	st->indio_dev = iio_allocate_device(0);
 	if (st->indio_dev == NULL) {
 		ret = -ENOMEM;
 		goto error_free_tx;
 	}
 
+	st->indio_dev->name = spi->dev.driver->name;
 	st->indio_dev->dev.parent = &spi->dev;
-	st->indio_dev->attrs = &adis16220_attribute_group;
+	st->indio_dev->info = &adis16220_info;
 	st->indio_dev->dev_data = (void *)(st);
-	st->indio_dev->driver_module = THIS_MODULE;
 	st->indio_dev->modes = INDIO_DIRECT_MODE;
 
 	ret = iio_device_register(st->indio_dev);
diff -druN linux-2.6.39-libre/drivers/staging/iio/accel/adis16240_core.c linux-3.0-rc7-libre/drivers/staging/iio/accel/adis16240_core.c
--- linux-2.6.39-libre/drivers/staging/iio/accel/adis16240_core.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/iio/accel/adis16240_core.c	2011-07-11 19:51:52.000000000 -0400
@@ -28,20 +28,19 @@
 
 #define DRIVER_NAME		"adis16240"
 
-static int adis16240_check_status(struct device *dev);
+static int adis16240_check_status(struct iio_dev *indio_dev);
 
 /**
  * adis16240_spi_write_reg_8() - write single byte to a register
- * @dev: device associated with child of actual device (iio_dev or iio_trig)
+ * @indio_dev: iio_dev associated with device
  * @reg_address: the address of the register to be written
  * @val: the value to write
  **/
-static int adis16240_spi_write_reg_8(struct device *dev,
-		u8 reg_address,
-		u8 val)
+static int adis16240_spi_write_reg_8(struct iio_dev *indio_dev,
+				     u8 reg_address,
+				     u8 val)
 {
 	int ret;
-	struct iio_dev *indio_dev = dev_get_drvdata(dev);
 	struct adis16240_state *st = iio_dev_get_devdata(indio_dev);
 
 	mutex_lock(&st->buf_lock);
@@ -56,18 +55,17 @@
 
 /**
  * adis16240_spi_write_reg_16() - write 2 bytes to a pair of registers
- * @dev: device associated with child of actual device (iio_dev or iio_trig)
+ * @indio_dev: iio_dev for this device
  * @reg_address: the address of the lower of the two registers. Second register
  *               is assumed to have address one greater.
  * @val: value to be written
  **/
-static int adis16240_spi_write_reg_16(struct device *dev,
-		u8 lower_reg_address,
-		u16 value)
+static int adis16240_spi_write_reg_16(struct iio_dev *indio_dev,
+				      u8 lower_reg_address,
+				      u16 value)
 {
 	int ret;
 	struct spi_message msg;
-	struct iio_dev *indio_dev = dev_get_drvdata(dev);
 	struct adis16240_state *st = iio_dev_get_devdata(indio_dev);
 	struct spi_transfer xfers[] = {
 		{
@@ -80,7 +78,6 @@
 			.tx_buf = st->tx + 2,
 			.bits_per_word = 8,
 			.len = 2,
-			.cs_change = 1,
 			.delay_usecs = 35,
 		},
 	};
@@ -102,17 +99,16 @@
 
 /**
  * adis16240_spi_read_reg_16() - read 2 bytes from a 16-bit register
- * @dev: device associated with child of actual device (iio_dev or iio_trig)
+ * @indio_dev: iio_dev for this device
  * @reg_address: the address of the lower of the two registers. Second register
  *               is assumed to have address one greater.
  * @val: somewhere to pass back the value read
  **/
-static int adis16240_spi_read_reg_16(struct device *dev,
+static int adis16240_spi_read_reg_16(struct iio_dev *indio_dev,
 		u8 lower_reg_address,
 		u16 *val)
 {
 	struct spi_message msg;
-	struct iio_dev *indio_dev = dev_get_drvdata(dev);
 	struct adis16240_state *st = iio_dev_get_devdata(indio_dev);
 	int ret;
 	struct spi_transfer xfers[] = {
@@ -159,61 +155,30 @@
 		char *buf,
 		unsigned bits)
 {
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
 	int ret;
 	s16 val = 0;
 	unsigned shift = 16 - bits;
 	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
 
-	ret = adis16240_spi_read_reg_16(dev, this_attr->address, (u16 *)&val);
+	ret = adis16240_spi_read_reg_16(indio_dev,
+					this_attr->address, (u16 *)&val);
 	if (ret)
 		return ret;
 
 	if (val & ADIS16240_ERROR_ACTIVE)
-		adis16240_check_status(dev);
+		adis16240_check_status(indio_dev);
 
 	val = ((s16)(val << shift) >> shift);
 	return sprintf(buf, "%d\n", val);
 }
 
-static ssize_t adis16240_read_10bit_unsigned(struct device *dev,
-		struct device_attribute *attr,
-		char *buf)
-{
-	int ret;
-	u16 val = 0;
-	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
-
-	ret = adis16240_spi_read_reg_16(dev, this_attr->address, &val);
-	if (ret)
-		return ret;
-
-	if (val & ADIS16240_ERROR_ACTIVE)
-		adis16240_check_status(dev);
-
-	return sprintf(buf, "%u\n", val & 0x03FF);
-}
-
-static ssize_t adis16240_read_10bit_signed(struct device *dev,
-		struct device_attribute *attr,
-		char *buf)
-{
-	struct iio_dev *indio_dev = dev_get_drvdata(dev);
-	ssize_t ret;
-
-	/* Take the iio_dev status lock */
-	mutex_lock(&indio_dev->mlock);
-	ret =  adis16240_spi_read_signed(dev, attr, buf, 10);
-	mutex_unlock(&indio_dev->mlock);
-
-	return ret;
-}
-
 static ssize_t adis16240_read_12bit_signed(struct device *dev,
 		struct device_attribute *attr,
 		char *buf)
 {
-	struct iio_dev *indio_dev = dev_get_drvdata(dev);
 	ssize_t ret;
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
 
 	/* Take the iio_dev status lock */
 	mutex_lock(&indio_dev->mlock);
@@ -223,32 +188,14 @@
 	return ret;
 }
 
-static ssize_t adis16240_write_16bit(struct device *dev,
-		struct device_attribute *attr,
-		const char *buf,
-		size_t len)
-{
-	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
-	int ret;
-	long val;
-
-	ret = strict_strtol(buf, 10, &val);
-	if (ret)
-		goto error_ret;
-	ret = adis16240_spi_write_reg_16(dev, this_attr->address, val);
-
-error_ret:
-	return ret ? ret : len;
-}
-
-static int adis16240_reset(struct device *dev)
+static int adis16240_reset(struct iio_dev *indio_dev)
 {
 	int ret;
-	ret = adis16240_spi_write_reg_8(dev,
+	ret = adis16240_spi_write_reg_8(indio_dev,
 			ADIS16240_GLOB_CMD,
 			ADIS16240_GLOB_CMD_SW_RESET);
 	if (ret)
-		dev_err(dev, "problem resetting device");
+		dev_err(&indio_dev->dev, "problem resetting device");
 
 	return ret;
 }
@@ -257,23 +204,26 @@
 		struct device_attribute *attr,
 		const char *buf, size_t len)
 {
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+
 	if (len < 1)
 		return -EINVAL;
 	switch (buf[0]) {
 	case '1':
 	case 'y':
 	case 'Y':
-		return adis16240_reset(dev);
+		return adis16240_reset(indio_dev);
 	}
 	return -EINVAL;
 }
 
-int adis16240_set_irq(struct device *dev, bool enable)
+int adis16240_set_irq(struct iio_dev *indio_dev, bool enable)
 {
 	int ret = 0;
 	u16 msc;
 
-	ret = adis16240_spi_read_reg_16(dev, ADIS16240_MSC_CTRL, &msc);
+	ret = adis16240_spi_read_reg_16(indio_dev,
+					ADIS16240_MSC_CTRL, &msc);
 	if (ret)
 		goto error_ret;
 
@@ -284,37 +234,40 @@
 	else
 		msc &= ~ADIS16240_MSC_CTRL_DATA_RDY_EN;
 
-	ret = adis16240_spi_write_reg_16(dev, ADIS16240_MSC_CTRL, msc);
+	ret = adis16240_spi_write_reg_16(indio_dev,
+					 ADIS16240_MSC_CTRL, msc);
 
 error_ret:
 	return ret;
 }
 
-static int adis16240_self_test(struct device *dev)
+static int adis16240_self_test(struct iio_dev *indio_dev)
 {
 	int ret;
-	ret = adis16240_spi_write_reg_16(dev,
+	ret = adis16240_spi_write_reg_16(indio_dev,
 			ADIS16240_MSC_CTRL,
 			ADIS16240_MSC_CTRL_SELF_TEST_EN);
 	if (ret) {
-		dev_err(dev, "problem starting self test");
+		dev_err(&indio_dev->dev, "problem starting self test");
 		goto err_ret;
 	}
 
 	msleep(ADIS16240_STARTUP_DELAY);
 
-	adis16240_check_status(dev);
+	adis16240_check_status(indio_dev);
 
 err_ret:
 	return ret;
 }
 
-static int adis16240_check_status(struct device *dev)
+static int adis16240_check_status(struct iio_dev *indio_dev)
 {
 	u16 status;
 	int ret;
+	struct device *dev = &indio_dev->dev;
 
-	ret = adis16240_spi_read_reg_16(dev, ADIS16240_DIAG_STAT, &status);
+	ret = adis16240_spi_read_reg_16(indio_dev,
+					ADIS16240_DIAG_STAT, &status);
 
 	if (ret < 0) {
 		dev_err(dev, "Reading status failed\n");
@@ -337,122 +290,216 @@
 	return ret;
 }
 
-static int adis16240_initial_setup(struct adis16240_state *st)
+static int adis16240_initial_setup(struct iio_dev *indio_dev)
 {
 	int ret;
-	struct device *dev = &st->indio_dev->dev;
+	struct device *dev = &indio_dev->dev;
 
 	/* Disable IRQ */
-	ret = adis16240_set_irq(dev, false);
+	ret = adis16240_set_irq(indio_dev, false);
 	if (ret) {
 		dev_err(dev, "disable irq failed");
 		goto err_ret;
 	}
 
 	/* Do self test */
-	ret = adis16240_self_test(dev);
+	ret = adis16240_self_test(indio_dev);
 	if (ret) {
 		dev_err(dev, "self test failure");
 		goto err_ret;
 	}
 
 	/* Read status register to check the result */
-	ret = adis16240_check_status(dev);
+	ret = adis16240_check_status(indio_dev);
 	if (ret) {
-		adis16240_reset(dev);
+		adis16240_reset(indio_dev);
 		dev_err(dev, "device not playing ball -> reset");
 		msleep(ADIS16240_STARTUP_DELAY);
-		ret = adis16240_check_status(dev);
+		ret = adis16240_check_status(indio_dev);
 		if (ret) {
 			dev_err(dev, "giving up");
 			goto err_ret;
 		}
 	}
 
-	printk(KERN_INFO DRIVER_NAME ": at CS%d (irq %d)\n",
-			st->us->chip_select, st->us->irq);
-
 err_ret:
 	return ret;
 }
 
-static IIO_DEV_ATTR_IN_NAMED_RAW(0, supply, adis16240_read_10bit_unsigned,
-		ADIS16240_SUPPLY_OUT);
-static IIO_DEV_ATTR_IN_RAW(1, adis16240_read_10bit_signed,
-		ADIS16240_AUX_ADC);
-static IIO_CONST_ATTR_IN_NAMED_SCALE(0, supply, "0.00488");
-
-static IIO_CONST_ATTR_ACCEL_SCALE("0.50406181");
-static IIO_CONST_ATTR(accel_peak_scale, "6.6292954");
-static IIO_DEV_ATTR_ACCEL_X(adis16240_read_10bit_signed,
-		ADIS16240_XACCL_OUT);
-static IIO_DEVICE_ATTR(accel_x_peak_raw, S_IRUGO,
-		       adis16240_read_10bit_signed, NULL,
-		       ADIS16240_XPEAK_OUT);
-static IIO_DEV_ATTR_ACCEL_Y(adis16240_read_10bit_signed,
-		ADIS16240_YACCL_OUT);
-static IIO_DEVICE_ATTR(accel_y_peak_raw, S_IRUGO,
-		       adis16240_read_10bit_signed, NULL,
-		       ADIS16240_YPEAK_OUT);
-static IIO_DEV_ATTR_ACCEL_Z(adis16240_read_10bit_signed,
-		ADIS16240_ZACCL_OUT);
-static IIO_DEVICE_ATTR(accel_z_peak_raw, S_IRUGO,
-		       adis16240_read_10bit_signed, NULL,
-		       ADIS16240_ZPEAK_OUT);
-
 static IIO_DEVICE_ATTR(accel_xyz_squared_peak_raw, S_IRUGO,
 		       adis16240_read_12bit_signed, NULL,
 		       ADIS16240_XYZPEAK_OUT);
-static IIO_DEV_ATTR_ACCEL_X_CALIBBIAS(S_IWUSR | S_IRUGO,
-		adis16240_read_10bit_signed,
-		adis16240_write_16bit,
-		ADIS16240_XACCL_OFF);
-static IIO_DEV_ATTR_ACCEL_Y_CALIBBIAS(S_IWUSR | S_IRUGO,
-		adis16240_read_10bit_signed,
-		adis16240_write_16bit,
-		ADIS16240_YACCL_OFF);
-static IIO_DEV_ATTR_ACCEL_Z_CALIBBIAS(S_IWUSR | S_IRUGO,
-		adis16240_read_10bit_signed,
-		adis16240_write_16bit,
-		ADIS16240_ZACCL_OFF);
-static IIO_DEV_ATTR_TEMP_RAW(adis16240_read_10bit_unsigned);
-static IIO_CONST_ATTR_TEMP_SCALE("0.244");
 
 static IIO_DEVICE_ATTR(reset, S_IWUSR, NULL, adis16240_write_reset, 0);
 
 static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("4096");
 
-static IIO_CONST_ATTR_NAME("adis16240");
+enum adis16240_chan {
+	in_supply,
+	in_aux,
+	accel_x,
+	accel_y,
+	accel_z,
+	temp,
+};
 
-static struct attribute *adis16240_event_attributes[] = {
-	NULL
+static const u8 adis16240_addresses[6][3] = {
+	[in_supply] = { ADIS16240_SUPPLY_OUT },
+	[in_aux] = { ADIS16240_AUX_ADC },
+	[accel_x] = { ADIS16240_XACCL_OUT, ADIS16240_XACCL_OFF,
+		      ADIS16240_XPEAK_OUT },
+	[accel_y] = { ADIS16240_YACCL_OUT, ADIS16240_YACCL_OFF,
+		      ADIS16240_YPEAK_OUT },
+	[accel_z] = { ADIS16240_ZACCL_OUT, ADIS16240_ZACCL_OFF,
+		      ADIS16240_ZPEAK_OUT },
+	[temp] = { ADIS16240_TEMP_OUT },
 };
 
-static struct attribute_group adis16240_event_attribute_group = {
-	.attrs = adis16240_event_attributes,
+static int adis16240_read_raw(struct iio_dev *indio_dev,
+			      struct iio_chan_spec const *chan,
+			      int *val, int *val2,
+			      long mask)
+{
+	int ret;
+	int bits;
+	u8 addr;
+	s16 val16;
+
+	switch (mask) {
+	case 0:
+		mutex_lock(&indio_dev->mlock);
+		addr = adis16240_addresses[chan->address][0];
+		ret = adis16240_spi_read_reg_16(indio_dev, addr, &val16);
+		if (ret)
+			return ret;
+
+		if (val16 & ADIS16240_ERROR_ACTIVE) {
+			ret = adis16240_check_status(indio_dev);
+			if (ret)
+				return ret;
+		}
+		val16 = val16 & ((1 << chan->scan_type.realbits) - 1);
+		if (chan->scan_type.sign == 's')
+			val16 = (s16)(val16 <<
+				      (16 - chan->scan_type.realbits)) >>
+				(16 - chan->scan_type.realbits);
+		*val = val16;
+		mutex_unlock(&indio_dev->mlock);
+		return IIO_VAL_INT;
+	case (1 << IIO_CHAN_INFO_SCALE_SEPARATE):
+	case (1 << IIO_CHAN_INFO_SCALE_SHARED):
+		switch (chan->type) {
+		case IIO_IN:
+			*val = 0;
+			if (chan->channel == 0)
+				*val2 = 4880;
+			else
+				return -EINVAL;
+			return IIO_VAL_INT_PLUS_MICRO;
+		case IIO_TEMP:
+			*val = 0;
+			*val2 = 244000;
+			return IIO_VAL_INT_PLUS_MICRO;
+		case IIO_ACCEL:
+			*val = 0;
+			*val2 = 504062;
+			return IIO_VAL_INT_PLUS_MICRO;
+		default:
+			return -EINVAL;
+		}
+		break;
+	case (1 << IIO_CHAN_INFO_PEAK_SCALE_SHARED):
+		*val = 6;
+		*val2 = 629295;
+		return IIO_VAL_INT_PLUS_MICRO;
+	case (1 << IIO_CHAN_INFO_OFFSET_SEPARATE):
+		*val = 25;
+		return IIO_VAL_INT;
+	case (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE):
+		bits = 10;
+		mutex_lock(&indio_dev->mlock);
+		addr = adis16240_addresses[chan->address][1];
+		ret = adis16240_spi_read_reg_16(indio_dev, addr, &val16);
+		if (ret) {
+			mutex_unlock(&indio_dev->mlock);
+			return ret;
+		}
+		val16 &= (1 << bits) - 1;
+		val16 = (s16)(val16 << (16 - bits)) >> (16 - bits);
+		*val = val16;
+		mutex_unlock(&indio_dev->mlock);
+		return IIO_VAL_INT;
+	case (1 << IIO_CHAN_INFO_PEAK_SEPARATE):
+		bits = 10;
+		mutex_lock(&indio_dev->mlock);
+		addr = adis16240_addresses[chan->address][2];
+		ret = adis16240_spi_read_reg_16(indio_dev, addr, &val16);
+		if (ret) {
+			mutex_unlock(&indio_dev->mlock);
+			return ret;
+		}
+		val16 &= (1 << bits) - 1;
+		val16 = (s16)(val16 << (16 - bits)) >> (16 - bits);
+		*val = val16;
+		mutex_unlock(&indio_dev->mlock);
+		return IIO_VAL_INT;
+	}
+	return -EINVAL;
+}
+
+static int adis16240_write_raw(struct iio_dev *indio_dev,
+			       struct iio_chan_spec const *chan,
+			       int val,
+			       int val2,
+			       long mask)
+{
+	int bits = 10;
+	s16 val16;
+	u8 addr;
+	switch (mask) {
+	case (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE):
+		val16 = val & ((1 << bits) - 1);
+		addr = adis16240_addresses[chan->address][1];
+		return adis16240_spi_write_reg_16(indio_dev, addr, val16);
+	}
+	return -EINVAL;
+}
+
+static struct iio_chan_spec adis16240_channels[] = {
+	IIO_CHAN(IIO_IN, 0, 1, 0, "supply", 0, 0,
+		 (1 << IIO_CHAN_INFO_SCALE_SEPARATE),
+		 in_supply, ADIS16240_SCAN_SUPPLY,
+		 IIO_ST('u', 10, 16, 0), 0),
+	IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 1, 0,
+		 0,
+		 in_aux, ADIS16240_SCAN_AUX_ADC,
+		 IIO_ST('u', 10, 16, 0), 0),
+	IIO_CHAN(IIO_ACCEL, 1, 0, 0, NULL, 0, IIO_MOD_X,
+		 (1 << IIO_CHAN_INFO_SCALE_SHARED) |
+		 (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE),
+		 accel_x, ADIS16240_SCAN_ACC_X,
+		 IIO_ST('s', 10, 16, 0), 0),
+	IIO_CHAN(IIO_ACCEL, 1, 0, 0, NULL, 0, IIO_MOD_Y,
+		 (1 << IIO_CHAN_INFO_SCALE_SHARED) |
+		 (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE),
+		 accel_y, ADIS16240_SCAN_ACC_Y,
+		 IIO_ST('s', 10, 16, 0), 0),
+	IIO_CHAN(IIO_ACCEL, 1, 0, 0, NULL, 0, IIO_MOD_Z,
+		 (1 << IIO_CHAN_INFO_SCALE_SHARED) |
+		 (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE),
+		 accel_z, ADIS16240_SCAN_ACC_Z,
+		 IIO_ST('s', 10, 16, 0), 0),
+	IIO_CHAN(IIO_TEMP, 0, 1, 0, NULL, 0, 0,
+		 (1 << IIO_CHAN_INFO_SCALE_SEPARATE),
+		 temp, ADIS16240_SCAN_TEMP,
+		 IIO_ST('u', 10, 16, 0), 0),
+	IIO_CHAN_SOFT_TIMESTAMP(6)
 };
 
 static struct attribute *adis16240_attributes[] = {
-	&iio_dev_attr_in0_supply_raw.dev_attr.attr,
-	&iio_const_attr_in0_supply_scale.dev_attr.attr,
-	&iio_dev_attr_in1_raw.dev_attr.attr,
-	&iio_const_attr_accel_scale.dev_attr.attr,
-	&iio_const_attr_accel_peak_scale.dev_attr.attr,
-	&iio_dev_attr_accel_x_raw.dev_attr.attr,
-	&iio_dev_attr_accel_x_calibbias.dev_attr.attr,
-	&iio_dev_attr_accel_x_peak_raw.dev_attr.attr,
-	&iio_dev_attr_accel_y_raw.dev_attr.attr,
-	&iio_dev_attr_accel_y_calibbias.dev_attr.attr,
-	&iio_dev_attr_accel_y_peak_raw.dev_attr.attr,
-	&iio_dev_attr_accel_z_raw.dev_attr.attr,
-	&iio_dev_attr_accel_z_calibbias.dev_attr.attr,
-	&iio_dev_attr_accel_z_peak_raw.dev_attr.attr,
 	&iio_dev_attr_accel_xyz_squared_peak_raw.dev_attr.attr,
-	&iio_dev_attr_temp_raw.dev_attr.attr,
-	&iio_const_attr_temp_scale.dev_attr.attr,
 	&iio_const_attr_sampling_frequency_available.dev_attr.attr,
 	&iio_dev_attr_reset.dev_attr.attr,
-	&iio_const_attr_name.dev_attr.attr,
 	NULL
 };
 
@@ -460,6 +507,13 @@
 	.attrs = adis16240_attributes,
 };
 
+static const struct iio_info adis16240_info = {
+	.attrs = &adis16240_attribute_group,
+	.read_raw = &adis16240_read_raw,
+	.write_raw = &adis16240_write_raw,
+	.driver_module = THIS_MODULE,
+};
+
 static int __devinit adis16240_probe(struct spi_device *spi)
 {
 	int ret, regdone = 0;
@@ -485,18 +539,18 @@
 	st->us = spi;
 	mutex_init(&st->buf_lock);
 	/* setup the industrialio driver allocated elements */
-	st->indio_dev = iio_allocate_device();
+	st->indio_dev = iio_allocate_device(0);
 	if (st->indio_dev == NULL) {
 		ret = -ENOMEM;
 		goto error_free_tx;
 	}
 
+	st->indio_dev->name = spi->dev.driver->name;
 	st->indio_dev->dev.parent = &spi->dev;
-	st->indio_dev->num_interrupt_lines = 1;
-	st->indio_dev->event_attrs = &adis16240_event_attribute_group;
-	st->indio_dev->attrs = &adis16240_attribute_group;
+	st->indio_dev->info = &adis16240_info;
+	st->indio_dev->channels = adis16240_channels;
+	st->indio_dev->num_channels = ARRAY_SIZE(adis16240_channels);
 	st->indio_dev->dev_data = (void *)(st);
-	st->indio_dev->driver_module = THIS_MODULE;
 	st->indio_dev->modes = INDIO_DIRECT_MODE;
 
 	ret = adis16240_configure_ring(st->indio_dev);
@@ -508,37 +562,28 @@
 		goto error_unreg_ring_funcs;
 	regdone = 1;
 
-	ret = iio_ring_buffer_register(st->indio_dev->ring, 0);
+	ret = iio_ring_buffer_register_ex(st->indio_dev->ring, 0,
+					  adis16240_channels,
+					  ARRAY_SIZE(adis16240_channels));
 	if (ret) {
 		printk(KERN_ERR "failed to initialize the ring\n");
 		goto error_unreg_ring_funcs;
 	}
 
 	if (spi->irq) {
-		ret = iio_register_interrupt_line(spi->irq,
-				st->indio_dev,
-				0,
-				IRQF_TRIGGER_RISING,
-				"adis16240");
-		if (ret)
-			goto error_uninitialize_ring;
-
 		ret = adis16240_probe_trigger(st->indio_dev);
 		if (ret)
-			goto error_unregister_line;
+			goto error_uninitialize_ring;
 	}
 
 	/* Get the device into a sane initial state */
-	ret = adis16240_initial_setup(st);
+	ret = adis16240_initial_setup(st->indio_dev);
 	if (ret)
 		goto error_remove_trigger;
 	return 0;
 
 error_remove_trigger:
 	adis16240_remove_trigger(st->indio_dev);
-error_unregister_line:
-	if (spi->irq)
-		iio_unregister_interrupt_line(st->indio_dev, 0);
 error_uninitialize_ring:
 	iio_ring_buffer_unregister(st->indio_dev->ring);
 error_unreg_ring_funcs:
@@ -566,9 +611,6 @@
 	flush_scheduled_work();
 
 	adis16240_remove_trigger(indio_dev);
-	if (spi->irq)
-		iio_unregister_interrupt_line(indio_dev, 0);
-
 	iio_ring_buffer_unregister(indio_dev->ring);
 	iio_device_unregister(indio_dev);
 	adis16240_unconfigure_ring(indio_dev);
diff -druN linux-2.6.39-libre/drivers/staging/iio/accel/adis16240.h linux-3.0-rc7-libre/drivers/staging/iio/accel/adis16240.h
--- linux-2.6.39-libre/drivers/staging/iio/accel/adis16240.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/iio/accel/adis16240.h	2011-07-11 19:51:52.000000000 -0400
@@ -126,9 +126,6 @@
 /**
  * struct adis16240_state - device instance specific data
  * @us:			actual spi_device
- * @work_trigger_to_ring: bh for triggered event handling
- * @inter:		used to check if new interrupt has been triggered
- * @last_timestamp:	passing timestamp from th to bh of interrupt handler
  * @indio_dev:		industrial I/O device structure
  * @trig:		data ready trigger registered with iio
  * @tx:			transmit buffer
@@ -137,8 +134,6 @@
  **/
 struct adis16240_state {
 	struct spi_device		*us;
-	struct work_struct		work_trigger_to_ring;
-	s64				last_timestamp;
 	struct iio_dev			*indio_dev;
 	struct iio_trigger		*trig;
 	u8				*tx;
@@ -146,7 +141,7 @@
 	struct mutex			buf_lock;
 };
 
-int adis16240_set_irq(struct device *dev, bool enable);
+int adis16240_set_irq(struct iio_dev *indio_dev, bool enable);
 
 #ifdef CONFIG_IIO_RING_BUFFER
 /* At the moment triggers are only used for ring buffer
diff -druN linux-2.6.39-libre/drivers/staging/iio/accel/adis16240_ring.c linux-3.0-rc7-libre/drivers/staging/iio/accel/adis16240_ring.c
--- linux-2.6.39-libre/drivers/staging/iio/accel/adis16240_ring.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/iio/accel/adis16240_ring.c	2011-07-11 19:51:52.000000000 -0400
@@ -17,59 +17,6 @@
 #include "../trigger.h"
 #include "adis16240.h"
 
-static IIO_SCAN_EL_C(in_supply, ADIS16240_SCAN_SUPPLY,
-		ADIS16240_SUPPLY_OUT, NULL);
-static IIO_CONST_ATTR_SCAN_EL_TYPE(in_supply, u, 10, 16);
-static IIO_SCAN_EL_C(accel_x, ADIS16240_SCAN_ACC_X, ADIS16240_XACCL_OUT, NULL);
-static IIO_SCAN_EL_C(accel_y, ADIS16240_SCAN_ACC_Y, ADIS16240_YACCL_OUT, NULL);
-static IIO_SCAN_EL_C(accel_z, ADIS16240_SCAN_ACC_Z, ADIS16240_ZACCL_OUT, NULL);
-static IIO_CONST_ATTR_SCAN_EL_TYPE(accel, s, 10, 16);
-static IIO_SCAN_EL_C(in0, ADIS16240_SCAN_AUX_ADC, ADIS16240_AUX_ADC, NULL);
-static IIO_CONST_ATTR_SCAN_EL_TYPE(in0, u, 10, 16);
-static IIO_SCAN_EL_C(temp, ADIS16240_SCAN_TEMP, ADIS16240_TEMP_OUT, NULL);
-static IIO_CONST_ATTR_SCAN_EL_TYPE(temp, u, 10, 16);
-static IIO_SCAN_EL_TIMESTAMP(6);
-static IIO_CONST_ATTR_SCAN_EL_TYPE(timestamp, s, 64, 64);
-
-static struct attribute *adis16240_scan_el_attrs[] = {
-	&iio_scan_el_in_supply.dev_attr.attr,
-	&iio_const_attr_in_supply_index.dev_attr.attr,
-	&iio_const_attr_in_supply_type.dev_attr.attr,
-	&iio_scan_el_accel_x.dev_attr.attr,
-	&iio_const_attr_accel_x_index.dev_attr.attr,
-	&iio_scan_el_accel_y.dev_attr.attr,
-	&iio_const_attr_accel_y_index.dev_attr.attr,
-	&iio_scan_el_accel_z.dev_attr.attr,
-	&iio_const_attr_accel_z_index.dev_attr.attr,
-	&iio_const_attr_accel_type.dev_attr.attr,
-	&iio_scan_el_in0.dev_attr.attr,
-	&iio_const_attr_in0_index.dev_attr.attr,
-	&iio_const_attr_in0_type.dev_attr.attr,
-	&iio_scan_el_temp.dev_attr.attr,
-	&iio_const_attr_temp_index.dev_attr.attr,
-	&iio_const_attr_temp_type.dev_attr.attr,
-	&iio_scan_el_timestamp.dev_attr.attr,
-	&iio_const_attr_timestamp_index.dev_attr.attr,
-	&iio_const_attr_timestamp_type.dev_attr.attr,
-	NULL,
-};
-
-static struct attribute_group adis16240_scan_el_group = {
-	.attrs = adis16240_scan_el_attrs,
-	.name = "scan_elements",
-};
-
-/**
- * adis16240_poll_func_th() top half interrupt handler called by trigger
- * @private_data:	iio_dev
- **/
-static void adis16240_poll_func_th(struct iio_dev *indio_dev, s64 time)
-{
-	struct adis16240_state *st = iio_dev_get_devdata(indio_dev);
-	st->last_timestamp = time;
-	schedule_work(&st->work_trigger_to_ring);
-}
-
 /**
  * adis16240_read_ring_data() read data registers which will be placed into ring
  * @dev: device associated with child of actual device (iio_dev or iio_trig)
@@ -112,56 +59,56 @@
 	return ret;
 }
 
-
-static void adis16240_trigger_bh_to_ring(struct work_struct *work_s)
+static irqreturn_t adis16240_trigger_handler(int irq, void *p)
 {
-	struct adis16240_state *st
-		= container_of(work_s, struct adis16240_state,
-				work_trigger_to_ring);
-	struct iio_ring_buffer *ring = st->indio_dev->ring;
+	struct iio_poll_func *pf = p;
+	struct iio_dev *indio_dev = pf->private_data;
+	struct adis16240_state *st = iio_dev_get_devdata(indio_dev);
+	struct iio_ring_buffer *ring = indio_dev->ring;
 
 	int i = 0;
 	s16 *data;
-	size_t datasize = ring->access.get_bytes_per_datum(ring);
+	size_t datasize = ring->access->get_bytes_per_datum(ring);
 
-	data = kmalloc(datasize , GFP_KERNEL);
+	data = kmalloc(datasize, GFP_KERNEL);
 	if (data == NULL) {
 		dev_err(&st->us->dev, "memory alloc failed in ring bh");
-		return;
+		return -ENOMEM;
 	}
 
-	if (ring->scan_count)
-		if (adis16240_read_ring_data(&st->indio_dev->dev, st->rx) >= 0)
-			for (; i < ring->scan_count; i++)
-				data[i] = be16_to_cpup(
-					(__be16 *)&(st->rx[i*2]));
+	if (ring->scan_count &&
+	    adis16240_read_ring_data(&st->indio_dev->dev, st->rx) >= 0)
+		for (; i < ring->scan_count; i++)
+			data[i] = be16_to_cpup((__be16 *)&(st->rx[i*2]));
 
 	/* Guaranteed to be aligned with 8 byte boundary */
 	if (ring->scan_timestamp)
-		*((s64 *)(data + ((i + 3)/4)*4)) = st->last_timestamp;
+		*((s64 *)(data + ((i + 3)/4)*4)) = pf->timestamp;
 
-	ring->access.store_to(ring,
-			(u8 *)data,
-			st->last_timestamp);
+	ring->access->store_to(ring, (u8 *)data, pf->timestamp);
 
 	iio_trigger_notify_done(st->indio_dev->trig);
 	kfree(data);
 
-	return;
+	return IRQ_HANDLED;
 }
 
 void adis16240_unconfigure_ring(struct iio_dev *indio_dev)
 {
-	kfree(indio_dev->pollfunc);
+	iio_dealloc_pollfunc(indio_dev->pollfunc);
 	iio_sw_rb_free(indio_dev->ring);
 }
 
+static const struct iio_ring_setup_ops adis16240_ring_setup_ops = {
+	.preenable = &iio_sw_ring_preenable,
+	.postenable = &iio_triggered_ring_postenable,
+	.predisable = &iio_triggered_ring_predisable,
+};
+
 int adis16240_configure_ring(struct iio_dev *indio_dev)
 {
 	int ret = 0;
-	struct adis16240_state *st = indio_dev->dev_data;
 	struct iio_ring_buffer *ring;
-	INIT_WORK(&st->work_trigger_to_ring, adis16240_trigger_bh_to_ring);
 
 	ring = iio_sw_rb_allocate(indio_dev);
 	if (!ring) {
@@ -170,26 +117,31 @@
 	}
 	indio_dev->ring = ring;
 	/* Effectively select the ring buffer implementation */
-	iio_ring_sw_register_funcs(&ring->access);
+	ring->access = &ring_sw_access_funcs;
 	ring->bpe = 2;
-	ring->scan_el_attrs = &adis16240_scan_el_group;
 	ring->scan_timestamp = true;
-	ring->preenable = &iio_sw_ring_preenable;
-	ring->postenable = &iio_triggered_ring_postenable;
-	ring->predisable = &iio_triggered_ring_predisable;
+	ring->setup_ops = &adis16240_ring_setup_ops;
 	ring->owner = THIS_MODULE;
 
 	/* Set default scan mode */
-	iio_scan_mask_set(ring, iio_scan_el_in_supply.number);
-	iio_scan_mask_set(ring, iio_scan_el_accel_x.number);
-	iio_scan_mask_set(ring, iio_scan_el_accel_y.number);
-	iio_scan_mask_set(ring, iio_scan_el_accel_z.number);
-	iio_scan_mask_set(ring, iio_scan_el_temp.number);
-	iio_scan_mask_set(ring, iio_scan_el_in0.number);
+	iio_scan_mask_set(ring, ADIS16240_SCAN_SUPPLY);
+	iio_scan_mask_set(ring, ADIS16240_SCAN_ACC_X);
+	iio_scan_mask_set(ring, ADIS16240_SCAN_ACC_Y);
+	iio_scan_mask_set(ring, ADIS16240_SCAN_ACC_Z);
+	iio_scan_mask_set(ring, ADIS16240_SCAN_AUX_ADC);
+	iio_scan_mask_set(ring, ADIS16240_SCAN_TEMP);
 
-	ret = iio_alloc_pollfunc(indio_dev, NULL, &adis16240_poll_func_th);
-	if (ret)
+	indio_dev->pollfunc = iio_alloc_pollfunc(&iio_pollfunc_store_time,
+						 &adis16240_trigger_handler,
+						 IRQF_ONESHOT,
+						 indio_dev,
+						 "%s_consumer%d",
+						 indio_dev->name,
+						 indio_dev->id);
+	if (indio_dev->pollfunc == NULL) {
+		ret = -ENOMEM;
 		goto error_iio_sw_rb_free;
+	}
 
 	indio_dev->modes |= INDIO_RING_TRIGGERED;
 	return 0;
@@ -198,4 +150,3 @@
 	iio_sw_rb_free(indio_dev->ring);
 	return ret;
 }
-
diff -druN linux-2.6.39-libre/drivers/staging/iio/accel/adis16240_trigger.c linux-3.0-rc7-libre/drivers/staging/iio/accel/adis16240_trigger.c
--- linux-2.6.39-libre/drivers/staging/iio/accel/adis16240_trigger.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/iio/accel/adis16240_trigger.c	2011-07-11 19:51:52.000000000 -0400
@@ -15,32 +15,12 @@
 /**
  * adis16240_data_rdy_trig_poll() the event handler for the data rdy trig
  **/
-static int adis16240_data_rdy_trig_poll(struct iio_dev *dev_info,
-				       int index,
-				       s64 timestamp,
-				       int no_test)
+static irqreturn_t adis16240_data_rdy_trig_poll(int irq, void *trig)
 {
-	struct adis16240_state *st = iio_dev_get_devdata(dev_info);
-	struct iio_trigger *trig = st->trig;
-
-	iio_trigger_poll(trig, timestamp);
-
+	iio_trigger_poll(trig, iio_get_time_ns());
 	return IRQ_HANDLED;
 }
 
-IIO_EVENT_SH(data_rdy_trig, &adis16240_data_rdy_trig_poll);
-
-static IIO_TRIGGER_NAME_ATTR;
-
-static struct attribute *adis16240_trigger_attrs[] = {
-	&dev_attr_name.attr,
-	NULL,
-};
-
-static const struct attribute_group adis16240_trigger_attr_group = {
-	.attrs = adis16240_trigger_attrs,
-};
-
 /**
  * adis16240_data_rdy_trigger_set_state() set datardy interrupt state
  **/
@@ -49,31 +29,9 @@
 {
 	struct adis16240_state *st = trig->private_data;
 	struct iio_dev *indio_dev = st->indio_dev;
-	int ret = 0;
 
 	dev_dbg(&indio_dev->dev, "%s (%d)\n", __func__, state);
-	ret = adis16240_set_irq(&st->indio_dev->dev, state);
-	if (state == false) {
-		iio_remove_event_from_list(&iio_event_data_rdy_trig,
-					   &indio_dev->interrupts[0]
-					   ->ev_list);
-		flush_scheduled_work();
-	} else {
-		iio_add_event_to_list(&iio_event_data_rdy_trig,
-				      &indio_dev->interrupts[0]->ev_list);
-	}
-	return ret;
-}
-
-/**
- * adis16240_trig_try_reen() try renabling irq for data rdy trigger
- * @trig:	the datardy trigger
- **/
-static int adis16240_trig_try_reen(struct iio_trigger *trig)
-{
-	struct adis16240_state *st = trig->private_data;
-	enable_irq(st->us->irq);
-	return 0;
+	return adis16240_set_irq(st->indio_dev, state);
 }
 
 int adis16240_probe_trigger(struct iio_dev *indio_dev)
@@ -81,34 +39,38 @@
 	int ret;
 	struct adis16240_state *st = indio_dev->dev_data;
 
-	st->trig = iio_allocate_trigger();
-	st->trig->name = kasprintf(GFP_KERNEL,
-				   "adis16240-dev%d",
-				   indio_dev->id);
-	if (!st->trig->name) {
+	st->trig = iio_allocate_trigger("adis16240-dev%d", indio_dev->id);
+	if (st->trig == NULL) {
 		ret = -ENOMEM;
-		goto error_free_trig;
+		goto error_ret;
 	}
+
+	ret = request_irq(st->us->irq,
+			  adis16240_data_rdy_trig_poll,
+			  IRQF_TRIGGER_RISING,
+			  "adis16240",
+			  st->trig);
+	if (ret)
+		goto error_free_trig;
+
 	st->trig->dev.parent = &st->us->dev;
 	st->trig->owner = THIS_MODULE;
 	st->trig->private_data = st;
 	st->trig->set_trigger_state = &adis16240_data_rdy_trigger_set_state;
-	st->trig->try_reenable = &adis16240_trig_try_reen;
-	st->trig->control_attrs = &adis16240_trigger_attr_group;
 	ret = iio_trigger_register(st->trig);
 
 	/* select default trigger */
 	indio_dev->trig = st->trig;
 	if (ret)
-		goto error_free_trig_name;
+		goto error_free_irq;
 
 	return 0;
 
-error_free_trig_name:
-	kfree(st->trig->name);
+error_free_irq:
+	free_irq(st->us->irq, st->trig);
 error_free_trig:
 	iio_free_trigger(st->trig);
-
+error_ret:
 	return ret;
 }
 
@@ -117,6 +79,6 @@
 	struct adis16240_state *state = indio_dev->dev_data;
 
 	iio_trigger_unregister(state->trig);
-	kfree(state->trig->name);
+	free_irq(state->us->irq, state->trig);
 	iio_free_trigger(state->trig);
 }
diff -druN linux-2.6.39-libre/drivers/staging/iio/accel/kxsd9.c linux-3.0-rc7-libre/drivers/staging/iio/accel/kxsd9.c
--- linux-2.6.39-libre/drivers/staging/iio/accel/kxsd9.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/iio/accel/kxsd9.c	2011-07-11 19:51:52.000000000 -0400
@@ -301,6 +301,11 @@
 
 };
 
+static const struct iio_info kxsd9_info = {
+	.attrs = &kxsd9_attribute_group,
+	.driver_module = THIS_MODULE,
+};
+
 static int __devinit kxsd9_probe(struct spi_device *spi)
 {
 
@@ -329,19 +334,14 @@
 
 	st->us = spi;
 	mutex_init(&st->buf_lock);
-	st->indio_dev = iio_allocate_device();
+	st->indio_dev = iio_allocate_device(0);
 	if (st->indio_dev == NULL) {
 		ret = -ENOMEM;
 		goto error_free_tx;
 	}
 	st->indio_dev->dev.parent = &spi->dev;
-	/* for now */
-	st->indio_dev->num_interrupt_lines = 0;
-	st->indio_dev->event_attrs = NULL;
-
-	st->indio_dev->attrs = &kxsd9_attribute_group;
+	st->indio_dev->info = &kxsd9_info;
 	st->indio_dev->dev_data = (void *)(st);
-	st->indio_dev->driver_module = THIS_MODULE;
 	st->indio_dev->modes = INDIO_DIRECT_MODE;
 
 	ret = iio_device_register(st->indio_dev);
diff -druN linux-2.6.39-libre/drivers/staging/iio/accel/lis3l02dq_core.c linux-3.0-rc7-libre/drivers/staging/iio/accel/lis3l02dq_core.c
--- linux-2.6.39-libre/drivers/staging/iio/accel/lis3l02dq_core.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/iio/accel/lis3l02dq_core.c	2011-07-11 19:51:52.000000000 -0400
@@ -15,20 +15,16 @@
 #include <linux/interrupt.h>
 #include <linux/irq.h>
 #include <linux/gpio.h>
-#include <linux/workqueue.h>
 #include <linux/mutex.h>
 #include <linux/device.h>
 #include <linux/kernel.h>
 #include <linux/spi/spi.h>
 #include <linux/slab.h>
-
 #include <linux/sysfs.h>
-#include <linux/list.h>
 
 #include "../iio.h"
 #include "../sysfs.h"
 #include "../ring_generic.h"
-#include "../ring_sw.h"
 
 #include "accel.h"
 
@@ -38,27 +34,31 @@
  * It's in the likely to be added comment at the top of spi.h.
  * This means that use cannot be made of spi_write etc.
  */
+/* direct copy of the irq_default_primary_handler */
+#ifndef CONFIG_IIO_RING_BUFFER
+static irqreturn_t lis3l02dq_noring(int irq, void *private)
+{
+	return IRQ_WAKE_THREAD;
+}
+#endif
 
 /**
  * lis3l02dq_spi_read_reg_8() - read single byte from a single register
- * @dev: device asosciated with child of actual device (iio_dev or iio_trig)
+ * @indio_dev: iio_dev for this actual device
  * @reg_address: the address of the register to be read
  * @val: pass back the resulting value
  **/
-int lis3l02dq_spi_read_reg_8(struct device *dev, u8 reg_address, u8 *val)
+int lis3l02dq_spi_read_reg_8(struct iio_dev *indio_dev,
+			     u8 reg_address, u8 *val)
 {
-	int ret;
+	struct lis3l02dq_state *st = iio_priv(indio_dev);
 	struct spi_message msg;
-	struct iio_dev *indio_dev = dev_get_drvdata(dev);
-	struct iio_sw_ring_helper_state *h = iio_dev_get_devdata(indio_dev);
-	struct lis3l02dq_state *st = lis3l02dq_h_to_s(h);
-
+	int ret;
 	struct spi_transfer xfer = {
 		.tx_buf = st->tx,
 		.rx_buf = st->rx,
 		.bits_per_word = 8,
 		.len = 2,
-		.cs_change = 1,
 	};
 
 	mutex_lock(&st->buf_lock);
@@ -76,34 +76,21 @@
 
 /**
  * lis3l02dq_spi_write_reg_8() - write single byte to a register
- * @dev: device associated with child of actual device (iio_dev or iio_trig)
+ * @indio_dev: iio_dev for this device
  * @reg_address: the address of the register to be written
  * @val: the value to write
  **/
-int lis3l02dq_spi_write_reg_8(struct device *dev,
+int lis3l02dq_spi_write_reg_8(struct iio_dev *indio_dev,
 			      u8 reg_address,
-			      u8 *val)
+			      u8 val)
 {
 	int ret;
-	struct spi_message msg;
-	struct iio_dev *indio_dev = dev_get_drvdata(dev);
-	struct iio_sw_ring_helper_state *h
-		= iio_dev_get_devdata(indio_dev);
-	struct lis3l02dq_state *st = lis3l02dq_h_to_s(h);
-	struct spi_transfer xfer = {
-		.tx_buf = st->tx,
-		.bits_per_word = 8,
-		.len = 2,
-		.cs_change = 1,
-	};
+	struct lis3l02dq_state *st = iio_priv(indio_dev);
 
 	mutex_lock(&st->buf_lock);
 	st->tx[0] = LIS3L02DQ_WRITE_REG(reg_address);
-	st->tx[1] = *val;
-
-	spi_message_init(&msg);
-	spi_message_add_tail(&xfer, &msg);
-	ret = spi_sync(st->us, &msg);
+	st->tx[1] = val;
+	ret = spi_write(st->us, st->tx, 2);
 	mutex_unlock(&st->buf_lock);
 
 	return ret;
@@ -111,21 +98,18 @@
 
 /**
  * lisl302dq_spi_write_reg_s16() - write 2 bytes to a pair of registers
- * @dev: device associated with child of actual device (iio_dev or iio_trig)
- * @reg_address: the address of the lower of the two registers. Second register
- *               is assumed to have address one greater.
- * @val: value to be written
+ * @indio_dev: iio_dev for this device
+ * @lower_reg_address: the address of the lower of the two registers.
+ *               Second register is assumed to have address one greater.
+ * @value: value to be written
  **/
-static int lis3l02dq_spi_write_reg_s16(struct device *dev,
+static int lis3l02dq_spi_write_reg_s16(struct iio_dev *indio_dev,
 				       u8 lower_reg_address,
 				       s16 value)
 {
 	int ret;
 	struct spi_message msg;
-	struct iio_dev *indio_dev = dev_get_drvdata(dev);
-	struct iio_sw_ring_helper_state *h
-		= iio_dev_get_devdata(indio_dev);
-	struct lis3l02dq_state *st = lis3l02dq_h_to_s(h);
+	struct lis3l02dq_state *st = iio_priv(indio_dev);
 	struct spi_transfer xfers[] = { {
 			.tx_buf = st->tx,
 			.bits_per_word = 8,
@@ -135,7 +119,6 @@
 			.tx_buf = st->tx + 2,
 			.bits_per_word = 8,
 			.len = 2,
-			.cs_change = 1,
 		},
 	};
 
@@ -154,23 +137,15 @@
 	return ret;
 }
 
-/**
- * lisl302dq_spi_read_reg_s16() - write 2 bytes to a pair of registers
- * @dev: device associated with child of actual device (iio_dev or iio_trig)
- * @reg_address: the address of the lower of the two registers. Second register
- *               is assumed to have address one greater.
- * @val: somewhere to pass back the value read
- **/
-static int lis3l02dq_spi_read_reg_s16(struct device *dev,
-				      u8 lower_reg_address,
-				      s16 *val)
+static int lis3l02dq_read_reg_s16(struct iio_dev *indio_dev,
+				  u8 lower_reg_address,
+				  int *val)
 {
+	struct lis3l02dq_state *st = iio_priv(indio_dev);
+
 	struct spi_message msg;
-	struct iio_dev *indio_dev = dev_get_drvdata(dev);
-	struct iio_sw_ring_helper_state *h
-		= iio_dev_get_devdata(indio_dev);
-	struct lis3l02dq_state *st = lis3l02dq_h_to_s(h);
 	int ret;
+	s16 tempval;
 	struct spi_transfer xfers[] = { {
 			.tx_buf = st->tx,
 			.rx_buf = st->rx,
@@ -182,15 +157,13 @@
 			.rx_buf = st->rx + 2,
 			.bits_per_word = 8,
 			.len = 2,
-			.cs_change = 1,
-
 		},
 	};
 
 	mutex_lock(&st->buf_lock);
 	st->tx[0] = LIS3L02DQ_READ_REG(lower_reg_address);
 	st->tx[1] = 0;
-	st->tx[2] = LIS3L02DQ_READ_REG(lower_reg_address+1);
+	st->tx[2] = LIS3L02DQ_READ_REG(lower_reg_address + 1);
 	st->tx[3] = 0;
 
 	spi_message_init(&msg);
@@ -201,144 +174,135 @@
 		dev_err(&st->us->dev, "problem when reading 16 bit register");
 		goto error_ret;
 	}
-	*val = (s16)(st->rx[1]) | ((s16)(st->rx[3]) << 8);
+	tempval = (s16)(st->rx[1]) | ((s16)(st->rx[3]) << 8);
 
+	*val = tempval;
 error_ret:
 	mutex_unlock(&st->buf_lock);
 	return ret;
 }
 
-/**
- * lis3l02dq_read_signed() - attribute function used for 8 bit signed values
- * @dev: the child device associated with the iio_dev or iio_trigger
- * @attr: the attribute being processed
- * @buf: buffer into which put the output string
- **/
-static ssize_t lis3l02dq_read_signed(struct device *dev,
-				     struct device_attribute *attr,
-				     char *buf)
-{
-	int ret;
-	s8 val;
-	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
-
-	ret = lis3l02dq_spi_read_reg_8(dev, this_attr->address, (u8 *)&val);
-
-	return ret ? ret : sprintf(buf, "%d\n", val);
-}
-
-static ssize_t lis3l02dq_read_unsigned(struct device *dev,
-				       struct device_attribute *attr,
-				       char *buf)
-{
-	int ret;
-	u8 val;
-	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
-
-	ret = lis3l02dq_spi_read_reg_8(dev, this_attr->address, &val);
-
-	return ret ? ret : sprintf(buf, "%d\n", val);
-}
-
-static ssize_t lis3l02dq_write_signed(struct device *dev,
-				      struct device_attribute *attr,
-				      const char *buf,
-				      size_t len)
-{
-	long valin;
-	s8 val;
-	int ret;
-	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
-
-	ret = strict_strtol(buf, 10, &valin);
-	if (ret)
-		goto error_ret;
-	val = valin;
-	ret = lis3l02dq_spi_write_reg_8(dev, this_attr->address, (u8 *)&val);
+enum lis3l02dq_rm_ind {
+	LIS3L02DQ_ACCEL,
+	LIS3L02DQ_GAIN,
+	LIS3L02DQ_BIAS,
+};
 
-error_ret:
-	return ret ? ret : len;
-}
+static u8 lis3l02dq_axis_map[3][3] = {
+	[LIS3L02DQ_ACCEL] = { LIS3L02DQ_REG_OUT_X_L_ADDR,
+			      LIS3L02DQ_REG_OUT_Y_L_ADDR,
+			      LIS3L02DQ_REG_OUT_Z_L_ADDR },
+	[LIS3L02DQ_GAIN] = { LIS3L02DQ_REG_GAIN_X_ADDR,
+			     LIS3L02DQ_REG_GAIN_Y_ADDR,
+			     LIS3L02DQ_REG_GAIN_Z_ADDR },
+	[LIS3L02DQ_BIAS] = { LIS3L02DQ_REG_OFFSET_X_ADDR,
+			     LIS3L02DQ_REG_OFFSET_Y_ADDR,
+			     LIS3L02DQ_REG_OFFSET_Z_ADDR }
+};
 
-static ssize_t lis3l02dq_write_unsigned(struct device *dev,
-					struct device_attribute *attr,
-					const char *buf,
-					size_t len)
+static int lis3l02dq_read_thresh(struct iio_dev *indio_dev,
+				 int e,
+				 int *val)
 {
-	int ret;
-	ulong valin;
-	u8 val;
-	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
-
-	ret = strict_strtoul(buf, 10, &valin);
-	if (ret)
-		goto err_ret;
-	val = valin;
-	ret = lis3l02dq_spi_write_reg_8(dev, this_attr->address, &val);
-
-err_ret:
-	return ret ? ret : len;
+	return lis3l02dq_read_reg_s16(indio_dev, LIS3L02DQ_REG_THS_L_ADDR, val);
 }
 
-static ssize_t lis3l02dq_read_16bit_signed(struct device *dev,
-					   struct device_attribute *attr,
-					   char *buf)
+static int lis3l02dq_write_thresh(struct iio_dev *indio_dev,
+				  int event_code,
+				  int val)
 {
-	int ret;
-	s16 val = 0;
-	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
-
-	ret = lis3l02dq_spi_read_reg_s16(dev, this_attr->address, &val);
-
-	if (ret)
-		return ret;
-
-	return sprintf(buf, "%d\n", val);
+	u16 value = val;
+	return lis3l02dq_spi_write_reg_s16(indio_dev,
+					   LIS3L02DQ_REG_THS_L_ADDR,
+					   value);
 }
 
-static ssize_t lis3l02dq_read_accel(struct device *dev,
-				    struct device_attribute *attr,
-				    char *buf)
+static int lis3l02dq_write_raw(struct iio_dev *indio_dev,
+			       struct iio_chan_spec const *chan,
+			       int val,
+			       int val2,
+			       long mask)
 {
-	struct iio_dev *indio_dev = dev_get_drvdata(dev);
-	ssize_t ret;
-
-	/* Take the iio_dev status lock */
-	mutex_lock(&indio_dev->mlock);
-	if (indio_dev->currentmode == INDIO_RING_TRIGGERED)
-		ret = lis3l02dq_read_accel_from_ring(dev, attr, buf);
-	else
-		ret =  lis3l02dq_read_16bit_signed(dev, attr, buf);
-	mutex_unlock(&indio_dev->mlock);
-
+	int ret = -EINVAL, reg;
+	u8 uval;
+	s8 sval;
+	switch (mask) {
+	case (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE):
+		if (val > 255 || val < -256)
+			return -EINVAL;
+		sval = val;
+		reg = lis3l02dq_axis_map[LIS3L02DQ_BIAS][chan->address];
+		ret = lis3l02dq_spi_write_reg_8(indio_dev, reg, sval);
+		break;
+	case (1 << IIO_CHAN_INFO_CALIBSCALE_SEPARATE):
+		if (val & ~0xFF)
+			return -EINVAL;
+		uval = val;
+		reg = lis3l02dq_axis_map[LIS3L02DQ_GAIN][chan->address];
+		ret = lis3l02dq_spi_write_reg_8(indio_dev, reg, uval);
+		break;
+	}
 	return ret;
 }
 
-static ssize_t lis3l02dq_write_16bit_signed(struct device *dev,
-					    struct device_attribute *attr,
-					    const char *buf,
-					    size_t len)
+static int lis3l02dq_read_raw(struct iio_dev *indio_dev,
+			      struct iio_chan_spec const *chan,
+			      int *val,
+			      int *val2,
+			      long mask)
 {
-	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
-	int ret;
-	long val;
+	u8 utemp;
+	s8 stemp;
+	ssize_t ret = 0;
+	u8 reg;
 
-	ret = strict_strtol(buf, 10, &val);
-	if (ret)
-		goto error_ret;
-	ret = lis3l02dq_spi_write_reg_s16(dev, this_attr->address, val);
+	switch (mask) {
+	case 0:
+		/* Take the iio_dev status lock */
+		mutex_lock(&indio_dev->mlock);
+		if (indio_dev->currentmode == INDIO_RING_TRIGGERED)
+			ret = lis3l02dq_read_accel_from_ring(indio_dev->ring,
+							     chan->scan_index,
+							     val);
+		else {
+			reg = lis3l02dq_axis_map
+				[LIS3L02DQ_ACCEL][chan->address];
+			ret = lis3l02dq_read_reg_s16(indio_dev, reg, val);
+		}
+		mutex_unlock(&indio_dev->mlock);
+		return IIO_VAL_INT;
+	case (1 << IIO_CHAN_INFO_SCALE_SHARED):
+		*val = 0;
+		*val2 = 9580;
+		return IIO_VAL_INT_PLUS_MICRO;
+	case (1 << IIO_CHAN_INFO_CALIBSCALE_SEPARATE):
+		reg = lis3l02dq_axis_map[LIS3L02DQ_GAIN][chan->address];
+		ret = lis3l02dq_spi_read_reg_8(indio_dev, reg, &utemp);
+		if (ret)
+			goto error_ret;
+		/* to match with what previous code does */
+		*val = utemp;
+		return IIO_VAL_INT;
 
+	case (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE):
+		reg = lis3l02dq_axis_map[LIS3L02DQ_BIAS][chan->address];
+		ret = lis3l02dq_spi_read_reg_8(indio_dev, reg, (u8 *)&stemp);
+		/* to match with what previous code does */
+		*val = stemp;
+		return IIO_VAL_INT;
+	}
 error_ret:
-	return ret ? ret : len;
+	return ret;
 }
 
 static ssize_t lis3l02dq_read_frequency(struct device *dev,
 					struct device_attribute *attr,
 					char *buf)
 {
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
 	int ret, len = 0;
 	s8 t;
-	ret = lis3l02dq_spi_read_reg_8(dev,
+	ret = lis3l02dq_spi_read_reg_8(indio_dev,
 				       LIS3L02DQ_REG_CTRL_1_ADDR,
 				       (u8 *)&t);
 	if (ret)
@@ -376,7 +340,7 @@
 		return ret;
 
 	mutex_lock(&indio_dev->mlock);
-	ret = lis3l02dq_spi_read_reg_8(dev,
+	ret = lis3l02dq_spi_read_reg_8(indio_dev,
 				       LIS3L02DQ_REG_CTRL_1_ADDR,
 				       &t);
 	if (ret)
@@ -399,11 +363,11 @@
 	default:
 		ret = -EINVAL;
 		goto error_ret_mutex;
-	};
+	}
 
-	ret = lis3l02dq_spi_write_reg_8(dev,
+	ret = lis3l02dq_spi_write_reg_8(indio_dev,
 					LIS3L02DQ_REG_CTRL_1_ADDR,
-					&t);
+					t);
 
 error_ret_mutex:
 	mutex_unlock(&indio_dev->mlock);
@@ -411,8 +375,9 @@
 	return ret ? ret : len;
 }
 
-static int lis3l02dq_initial_setup(struct lis3l02dq_state *st)
+static int lis3l02dq_initial_setup(struct iio_dev *indio_dev)
 {
+	struct lis3l02dq_state *st = iio_priv(indio_dev);
 	int ret;
 	u8 val, valtest;
 
@@ -422,17 +387,17 @@
 
 	val = LIS3L02DQ_DEFAULT_CTRL1;
 	/* Write suitable defaults to ctrl1 */
-	ret = lis3l02dq_spi_write_reg_8(&st->help.indio_dev->dev,
+	ret = lis3l02dq_spi_write_reg_8(indio_dev,
 					LIS3L02DQ_REG_CTRL_1_ADDR,
-					&val);
+					val);
 	if (ret) {
 		dev_err(&st->us->dev, "problem with setup control register 1");
 		goto err_ret;
 	}
 	/* Repeat as sometimes doesn't work first time?*/
-	ret = lis3l02dq_spi_write_reg_8(&st->help.indio_dev->dev,
+	ret = lis3l02dq_spi_write_reg_8(indio_dev,
 					LIS3L02DQ_REG_CTRL_1_ADDR,
-					&val);
+					val);
 	if (ret) {
 		dev_err(&st->us->dev, "problem with setup control register 1");
 		goto err_ret;
@@ -440,28 +405,29 @@
 
 	/* Read back to check this has worked acts as loose test of correct
 	 * chip */
-	ret = lis3l02dq_spi_read_reg_8(&st->help.indio_dev->dev,
+	ret = lis3l02dq_spi_read_reg_8(indio_dev,
 				       LIS3L02DQ_REG_CTRL_1_ADDR,
 				       &valtest);
 	if (ret || (valtest != val)) {
-		dev_err(&st->help.indio_dev->dev, "device not playing ball");
+		dev_err(&indio_dev->dev,
+			"device not playing ball %d %d\n", valtest, val);
 		ret = -EINVAL;
 		goto err_ret;
 	}
 
 	val = LIS3L02DQ_DEFAULT_CTRL2;
-	ret = lis3l02dq_spi_write_reg_8(&st->help.indio_dev->dev,
+	ret = lis3l02dq_spi_write_reg_8(indio_dev,
 					LIS3L02DQ_REG_CTRL_2_ADDR,
-					&val);
+					val);
 	if (ret) {
 		dev_err(&st->us->dev, "problem with setup control register 2");
 		goto err_ret;
 	}
 
 	val = LIS3L02DQ_REG_WAKE_UP_CFG_LATCH_SRC;
-	ret = lis3l02dq_spi_write_reg_8(&st->help.indio_dev->dev,
+	ret = lis3l02dq_spi_write_reg_8(indio_dev,
 					LIS3L02DQ_REG_WAKE_UP_CFG_ADDR,
-					&val);
+					val);
 	if (ret)
 		dev_err(&st->us->dev, "problem with interrupt cfg register");
 err_ret:
@@ -469,309 +435,215 @@
 	return ret;
 }
 
-#define LIS3L02DQ_SIGNED_ATTR(name, reg)	\
-	IIO_DEVICE_ATTR(name,			\
-			S_IWUSR | S_IRUGO,	\
-			lis3l02dq_read_signed,	\
-			lis3l02dq_write_signed, \
-			reg);
-
-#define LIS3L02DQ_UNSIGNED_ATTR(name, reg)		\
-	IIO_DEVICE_ATTR(name,				\
-			S_IWUSR | S_IRUGO,		\
-			lis3l02dq_read_unsigned,	\
-			lis3l02dq_write_unsigned,	\
-			reg);
-
-static LIS3L02DQ_SIGNED_ATTR(accel_x_calibbias,
-			     LIS3L02DQ_REG_OFFSET_X_ADDR);
-static LIS3L02DQ_SIGNED_ATTR(accel_y_calibbias,
-			     LIS3L02DQ_REG_OFFSET_Y_ADDR);
-static LIS3L02DQ_SIGNED_ATTR(accel_z_calibbias,
-			     LIS3L02DQ_REG_OFFSET_Z_ADDR);
-
-static LIS3L02DQ_UNSIGNED_ATTR(accel_x_calibscale,
-			       LIS3L02DQ_REG_GAIN_X_ADDR);
-static LIS3L02DQ_UNSIGNED_ATTR(accel_y_calibscale,
-			       LIS3L02DQ_REG_GAIN_Y_ADDR);
-static LIS3L02DQ_UNSIGNED_ATTR(accel_z_calibscale,
-			       LIS3L02DQ_REG_GAIN_Z_ADDR);
-
-static IIO_DEVICE_ATTR(accel_raw_mag_value,
-		       S_IWUSR | S_IRUGO,
-		       lis3l02dq_read_16bit_signed,
-		       lis3l02dq_write_16bit_signed,
-		       LIS3L02DQ_REG_THS_L_ADDR);
-/* RFC The reading method for these will change depending on whether
- * ring buffer capture is in use. Is it worth making these take two
- * functions and let the core handle which to call, or leave as in this
- * driver where it is the drivers problem to manage this?
- */
-
-static IIO_DEV_ATTR_ACCEL_X(lis3l02dq_read_accel,
-			    LIS3L02DQ_REG_OUT_X_L_ADDR);
-
-static IIO_DEV_ATTR_ACCEL_Y(lis3l02dq_read_accel,
-			    LIS3L02DQ_REG_OUT_Y_L_ADDR);
-
-static IIO_DEV_ATTR_ACCEL_Z(lis3l02dq_read_accel,
-			    LIS3L02DQ_REG_OUT_Z_L_ADDR);
-
 static IIO_DEV_ATTR_SAMP_FREQ(S_IWUSR | S_IRUGO,
 			      lis3l02dq_read_frequency,
 			      lis3l02dq_write_frequency);
 
 static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("280 560 1120 4480");
 
-static ssize_t lis3l02dq_read_interrupt_config(struct device *dev,
-					       struct device_attribute *attr,
-					       char *buf)
-{
-	int ret;
-	s8 val;
-	struct iio_event_attr *this_attr = to_iio_event_attr(attr);
-
-	ret = lis3l02dq_spi_read_reg_8(dev->parent,
-				       LIS3L02DQ_REG_WAKE_UP_CFG_ADDR,
-				       (u8 *)&val);
-
-	return ret ? ret : sprintf(buf, "%d\n", !!(val & this_attr->mask));
-}
-
-static ssize_t lis3l02dq_write_interrupt_config(struct device *dev,
-						struct device_attribute *attr,
-						const char *buf,
-						size_t len)
-{
-	struct iio_event_attr *this_attr = to_iio_event_attr(attr);
-	struct iio_dev *indio_dev = dev_get_drvdata(dev);
-	int ret, currentlyset, changed = 0;
-	u8 valold, controlold;
-	bool val;
-
-	val = !(buf[0] == '0');
-
-	mutex_lock(&indio_dev->mlock);
-	/* read current value */
-	ret = lis3l02dq_spi_read_reg_8(dev->parent,
-				       LIS3L02DQ_REG_WAKE_UP_CFG_ADDR,
-				       &valold);
-	if (ret)
-		goto error_mutex_unlock;
-
-	/* read current control */
-	ret = lis3l02dq_spi_read_reg_8(dev,
-				       LIS3L02DQ_REG_CTRL_2_ADDR,
-				       &controlold);
-	if (ret)
-		goto error_mutex_unlock;
-	currentlyset = !!(valold & this_attr->mask);
-	if (val == false && currentlyset) {
-		valold &= ~this_attr->mask;
-		changed = 1;
-		iio_remove_event_from_list(this_attr->listel,
-						 &indio_dev->interrupts[0]
-						 ->ev_list);
-	} else if (val == true && !currentlyset) {
-		changed = 1;
-		valold |= this_attr->mask;
-		iio_add_event_to_list(this_attr->listel,
-					    &indio_dev->interrupts[0]->ev_list);
-	}
-
-	if (changed) {
-		ret = lis3l02dq_spi_write_reg_8(dev,
-						LIS3L02DQ_REG_WAKE_UP_CFG_ADDR,
-						&valold);
-		if (ret)
-			goto error_mutex_unlock;
-		/* This always enables the interrupt, even if we've remove the
-		 * last thing using it. For this device we can use the reference
-		 * count on the handler to tell us if anyone wants the interrupt
-		 */
-		controlold = this_attr->listel->refcount ?
-			(controlold | LIS3L02DQ_REG_CTRL_2_ENABLE_INTERRUPT) :
-			(controlold & ~LIS3L02DQ_REG_CTRL_2_ENABLE_INTERRUPT);
-		ret = lis3l02dq_spi_write_reg_8(dev,
-						LIS3L02DQ_REG_CTRL_2_ADDR,
-						&controlold);
-		if (ret)
-			goto error_mutex_unlock;
-	}
-error_mutex_unlock:
-	mutex_unlock(&indio_dev->mlock);
-
-	return ret ? ret : len;
-}
-
-
-static int lis3l02dq_thresh_handler_th(struct iio_dev *indio_dev,
-				       int index,
-				       s64 timestamp,
-				       int no_test)
-{
-	struct iio_sw_ring_helper_state *h
-		= iio_dev_get_devdata(indio_dev);
-	struct lis3l02dq_state *st = lis3l02dq_h_to_s(h);
-
-	/* Stash the timestamp somewhere convenient for the bh */
-	st->thresh_timestamp = timestamp;
-	schedule_work(&st->work_thresh);
-
-	return 0;
-}
-
-
-/* Unforunately it appears the interrupt won't clear unless you read from the
- * src register.
- */
-static void lis3l02dq_thresh_handler_bh_no_check(struct work_struct *work_s)
+static irqreturn_t lis3l02dq_event_handler(int irq, void *private)
 {
-       struct lis3l02dq_state *st
-	       = container_of(work_s,
-		       struct lis3l02dq_state, work_thresh);
-
+	struct iio_dev *indio_dev = private;
 	u8 t;
 
-	lis3l02dq_spi_read_reg_8(&st->help.indio_dev->dev,
+	s64 timestamp = iio_get_time_ns();
+
+	lis3l02dq_spi_read_reg_8(indio_dev,
 				 LIS3L02DQ_REG_WAKE_UP_SRC_ADDR,
 				 &t);
 
 	if (t & LIS3L02DQ_REG_WAKE_UP_SRC_INTERRUPT_Z_HIGH)
-		iio_push_event(st->help.indio_dev, 0,
+		iio_push_event(indio_dev, 0,
 			       IIO_MOD_EVENT_CODE(IIO_EV_CLASS_ACCEL,
 						  0,
 						  IIO_EV_MOD_Z,
 						  IIO_EV_TYPE_THRESH,
 						  IIO_EV_DIR_RISING),
-			       st->thresh_timestamp);
+			       timestamp);
 
 	if (t & LIS3L02DQ_REG_WAKE_UP_SRC_INTERRUPT_Z_LOW)
-		iio_push_event(st->help.indio_dev, 0,
+		iio_push_event(indio_dev, 0,
 			       IIO_MOD_EVENT_CODE(IIO_EV_CLASS_ACCEL,
 						  0,
 						  IIO_EV_MOD_Z,
 						  IIO_EV_TYPE_THRESH,
 						  IIO_EV_DIR_FALLING),
-			       st->thresh_timestamp);
+			       timestamp);
 
 	if (t & LIS3L02DQ_REG_WAKE_UP_SRC_INTERRUPT_Y_HIGH)
-		iio_push_event(st->help.indio_dev, 0,
+		iio_push_event(indio_dev, 0,
 			       IIO_MOD_EVENT_CODE(IIO_EV_CLASS_ACCEL,
 						  0,
 						  IIO_EV_MOD_Y,
 						  IIO_EV_TYPE_THRESH,
 						  IIO_EV_DIR_RISING),
-			       st->thresh_timestamp);
+			       timestamp);
 
 	if (t & LIS3L02DQ_REG_WAKE_UP_SRC_INTERRUPT_Y_LOW)
-		iio_push_event(st->help.indio_dev, 0,
+		iio_push_event(indio_dev, 0,
 			       IIO_MOD_EVENT_CODE(IIO_EV_CLASS_ACCEL,
 						  0,
 						  IIO_EV_MOD_Y,
 						  IIO_EV_TYPE_THRESH,
 						  IIO_EV_DIR_FALLING),
-			       st->thresh_timestamp);
+			       timestamp);
 
 	if (t & LIS3L02DQ_REG_WAKE_UP_SRC_INTERRUPT_X_HIGH)
-		iio_push_event(st->help.indio_dev, 0,
+		iio_push_event(indio_dev, 0,
 			       IIO_MOD_EVENT_CODE(IIO_EV_CLASS_ACCEL,
 						  0,
 						  IIO_EV_MOD_X,
 						  IIO_EV_TYPE_THRESH,
 						  IIO_EV_DIR_RISING),
-			       st->thresh_timestamp);
+			       timestamp);
 
 	if (t & LIS3L02DQ_REG_WAKE_UP_SRC_INTERRUPT_X_LOW)
-		iio_push_event(st->help.indio_dev, 0,
+		iio_push_event(indio_dev, 0,
 			       IIO_MOD_EVENT_CODE(IIO_EV_CLASS_ACCEL,
 						  0,
 						  IIO_EV_MOD_X,
 						  IIO_EV_TYPE_THRESH,
 						  IIO_EV_DIR_FALLING),
-			       st->thresh_timestamp);
-	/* reenable the irq */
-	enable_irq(st->us->irq);
+			       timestamp);
+
 	/* Ack and allow for new interrupts */
-	lis3l02dq_spi_read_reg_8(&st->help.indio_dev->dev,
+	lis3l02dq_spi_read_reg_8(indio_dev,
 				 LIS3L02DQ_REG_WAKE_UP_ACK_ADDR,
 				 &t);
 
-	return;
+	return IRQ_HANDLED;
 }
 
-/* A shared handler for a number of threshold types */
-IIO_EVENT_SH(threshold, &lis3l02dq_thresh_handler_th);
+#define LIS3L02DQ_INFO_MASK				\
+	((1 << IIO_CHAN_INFO_SCALE_SHARED) |		\
+	 (1 << IIO_CHAN_INFO_CALIBSCALE_SEPARATE) |	\
+	 (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE))
 
-IIO_EVENT_ATTR_SH(accel_x_thresh_rising_en,
-		  iio_event_threshold,
-		  lis3l02dq_read_interrupt_config,
-		  lis3l02dq_write_interrupt_config,
-		  LIS3L02DQ_REG_WAKE_UP_CFG_INTERRUPT_X_HIGH);
+#define LIS3L02DQ_EVENT_MASK					\
+	(IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_RISING) |	\
+	 IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_FALLING))
 
-IIO_EVENT_ATTR_SH(accel_y_thresh_rising_en,
-		  iio_event_threshold,
-		  lis3l02dq_read_interrupt_config,
-		  lis3l02dq_write_interrupt_config,
-		  LIS3L02DQ_REG_WAKE_UP_CFG_INTERRUPT_Y_HIGH);
+static struct iio_chan_spec lis3l02dq_channels[] = {
+	IIO_CHAN(IIO_ACCEL, 1, 0, 0, NULL, 0, IIO_MOD_X, LIS3L02DQ_INFO_MASK,
+		 0, 0, IIO_ST('s', 12, 16, 0), LIS3L02DQ_EVENT_MASK),
+	IIO_CHAN(IIO_ACCEL, 1, 0, 0, NULL, 0, IIO_MOD_Y, LIS3L02DQ_INFO_MASK,
+		 1, 1, IIO_ST('s', 12, 16, 0), LIS3L02DQ_EVENT_MASK),
+	IIO_CHAN(IIO_ACCEL, 1, 0, 0, NULL, 0, IIO_MOD_Z, LIS3L02DQ_INFO_MASK,
+		 2, 2, IIO_ST('s', 12, 16, 0), LIS3L02DQ_EVENT_MASK),
+	IIO_CHAN_SOFT_TIMESTAMP(3)
+};
 
-IIO_EVENT_ATTR_SH(accel_z_thresh_rising_en,
-		  iio_event_threshold,
-		  lis3l02dq_read_interrupt_config,
-		  lis3l02dq_write_interrupt_config,
-		  LIS3L02DQ_REG_WAKE_UP_CFG_INTERRUPT_Z_HIGH);
 
-IIO_EVENT_ATTR_SH(accel_x_thresh_falling_en,
-		  iio_event_threshold,
-		  lis3l02dq_read_interrupt_config,
-		  lis3l02dq_write_interrupt_config,
-		  LIS3L02DQ_REG_WAKE_UP_CFG_INTERRUPT_X_LOW);
+static ssize_t lis3l02dq_read_event_config(struct iio_dev *indio_dev,
+					   int event_code)
+{
 
-IIO_EVENT_ATTR_SH(accel_y_thresh_falling_en,
-		  iio_event_threshold,
-		  lis3l02dq_read_interrupt_config,
-		  lis3l02dq_write_interrupt_config,
-		  LIS3L02DQ_REG_WAKE_UP_CFG_INTERRUPT_Y_LOW);
+	u8 val;
+	int ret;
+	u8 mask = (1 << (IIO_EVENT_CODE_EXTRACT_MODIFIER(event_code)*2 +
+			 (IIO_EVENT_CODE_EXTRACT_DIR(event_code) ==
+			  IIO_EV_DIR_RISING)));
+	ret = lis3l02dq_spi_read_reg_8(indio_dev,
+				       LIS3L02DQ_REG_WAKE_UP_CFG_ADDR,
+				       &val);
+	if (ret < 0)
+		return ret;
 
-IIO_EVENT_ATTR_SH(accel_z_thresh_falling_en,
-		  iio_event_threshold,
-		  lis3l02dq_read_interrupt_config,
-		  lis3l02dq_write_interrupt_config,
-		  LIS3L02DQ_REG_WAKE_UP_CFG_INTERRUPT_Z_LOW);
+	return !!(val & mask);
+}
 
+int lis3l02dq_disable_all_events(struct iio_dev *indio_dev)
+{
+	int ret;
+	u8 control, val;
 
-static struct attribute *lis3l02dq_event_attributes[] = {
-	&iio_event_attr_accel_x_thresh_rising_en.dev_attr.attr,
-	&iio_event_attr_accel_y_thresh_rising_en.dev_attr.attr,
-	&iio_event_attr_accel_z_thresh_rising_en.dev_attr.attr,
-	&iio_event_attr_accel_x_thresh_falling_en.dev_attr.attr,
-	&iio_event_attr_accel_y_thresh_falling_en.dev_attr.attr,
-	&iio_event_attr_accel_z_thresh_falling_en.dev_attr.attr,
-	&iio_dev_attr_accel_raw_mag_value.dev_attr.attr,
-	NULL
-};
+	ret = lis3l02dq_spi_read_reg_8(indio_dev,
+				       LIS3L02DQ_REG_CTRL_2_ADDR,
+				       &control);
 
-static struct attribute_group lis3l02dq_event_attribute_group = {
-	.attrs = lis3l02dq_event_attributes,
-};
+	control &= ~LIS3L02DQ_REG_CTRL_2_ENABLE_INTERRUPT;
+	ret = lis3l02dq_spi_write_reg_8(indio_dev,
+					LIS3L02DQ_REG_CTRL_2_ADDR,
+					control);
+	if (ret)
+		goto error_ret;
+	/* Also for consistency clear the mask */
+	ret = lis3l02dq_spi_read_reg_8(indio_dev,
+				       LIS3L02DQ_REG_WAKE_UP_CFG_ADDR,
+				       &val);
+	if (ret)
+		goto error_ret;
+	val &= ~0x3f;
 
-static IIO_CONST_ATTR_NAME("lis3l02dq");
-static IIO_CONST_ATTR(accel_scale, "0.00958");
+	ret = lis3l02dq_spi_write_reg_8(indio_dev,
+					LIS3L02DQ_REG_WAKE_UP_CFG_ADDR,
+					val);
+	if (ret)
+		goto error_ret;
+
+	ret = control;
+error_ret:
+	return ret;
+}
+
+static int lis3l02dq_write_event_config(struct iio_dev *indio_dev,
+					int event_code,
+					int state)
+{
+	int ret = 0;
+	u8 val, control;
+	u8 currentlyset;
+	bool changed = false;
+	u8 mask = (1 << (IIO_EVENT_CODE_EXTRACT_MODIFIER(event_code)*2 +
+			 (IIO_EVENT_CODE_EXTRACT_DIR(event_code) ==
+			  IIO_EV_DIR_RISING)));
+
+	mutex_lock(&indio_dev->mlock);
+	/* read current control */
+	ret = lis3l02dq_spi_read_reg_8(indio_dev,
+				       LIS3L02DQ_REG_CTRL_2_ADDR,
+				       &control);
+	if (ret)
+		goto error_ret;
+	ret = lis3l02dq_spi_read_reg_8(indio_dev,
+				       LIS3L02DQ_REG_WAKE_UP_CFG_ADDR,
+				       &val);
+	if (ret < 0)
+		goto error_ret;
+	currentlyset = val & mask;
+
+	if (!currentlyset && state) {
+		changed = true;
+		val |= mask;
+	} else if (currentlyset && !state) {
+		changed = true;
+		val &= ~mask;
+	}
+
+	if (changed) {
+		ret = lis3l02dq_spi_write_reg_8(indio_dev,
+						LIS3L02DQ_REG_WAKE_UP_CFG_ADDR,
+						val);
+		if (ret)
+			goto error_ret;
+		control = val & 0x3f ?
+			(control | LIS3L02DQ_REG_CTRL_2_ENABLE_INTERRUPT) :
+			(control & ~LIS3L02DQ_REG_CTRL_2_ENABLE_INTERRUPT);
+		ret = lis3l02dq_spi_write_reg_8(indio_dev,
+					       LIS3L02DQ_REG_CTRL_2_ADDR,
+					       control);
+		if (ret)
+			goto error_ret;
+	}
+
+error_ret:
+	mutex_unlock(&indio_dev->mlock);
+	return ret;
+}
 
 static struct attribute *lis3l02dq_attributes[] = {
-	&iio_dev_attr_accel_x_calibbias.dev_attr.attr,
-	&iio_dev_attr_accel_y_calibbias.dev_attr.attr,
-	&iio_dev_attr_accel_z_calibbias.dev_attr.attr,
-	&iio_dev_attr_accel_x_calibscale.dev_attr.attr,
-	&iio_dev_attr_accel_y_calibscale.dev_attr.attr,
-	&iio_dev_attr_accel_z_calibscale.dev_attr.attr,
-	&iio_const_attr_accel_scale.dev_attr.attr,
-	&iio_dev_attr_accel_x_raw.dev_attr.attr,
-	&iio_dev_attr_accel_y_raw.dev_attr.attr,
-	&iio_dev_attr_accel_z_raw.dev_attr.attr,
 	&iio_dev_attr_sampling_frequency.dev_attr.attr,
 	&iio_const_attr_sampling_frequency_available.dev_attr.attr,
-	&iio_const_attr_name.dev_attr.attr,
 	NULL
 };
 
@@ -779,103 +651,96 @@
 	.attrs = lis3l02dq_attributes,
 };
 
+static const struct iio_info lis3l02dq_info = {
+	.num_interrupt_lines = 1,
+	.read_raw = &lis3l02dq_read_raw,
+	.write_raw = &lis3l02dq_write_raw,
+	.read_event_value = &lis3l02dq_read_thresh,
+	.write_event_value = &lis3l02dq_write_thresh,
+	.write_event_config = &lis3l02dq_write_event_config,
+	.read_event_config = &lis3l02dq_read_event_config,
+	.driver_module = THIS_MODULE,
+	.attrs = &lis3l02dq_attribute_group,
+};
+
 static int __devinit lis3l02dq_probe(struct spi_device *spi)
 {
 	int ret, regdone = 0;
-	struct lis3l02dq_state *st = kzalloc(sizeof *st, GFP_KERNEL);
-	if (!st) {
-		ret =  -ENOMEM;
+	struct lis3l02dq_state *st;
+	struct iio_dev *indio_dev;
+
+	indio_dev = iio_allocate_device(sizeof *st);
+	if (indio_dev == NULL) {
+		ret = -ENOMEM;
 		goto error_ret;
 	}
-	INIT_WORK(&st->work_thresh, lis3l02dq_thresh_handler_bh_no_check);
+	st = iio_priv(indio_dev);
 	/* this is only used tor removal purposes */
 	spi_set_drvdata(spi, st);
 
-	/* Allocate the comms buffers */
-	st->rx = kzalloc(sizeof(*st->rx)*LIS3L02DQ_MAX_RX, GFP_KERNEL);
-	if (st->rx == NULL) {
-		ret = -ENOMEM;
-		goto error_free_st;
-	}
-	st->tx = kzalloc(sizeof(*st->tx)*LIS3L02DQ_MAX_TX, GFP_KERNEL);
-	if (st->tx == NULL) {
-		ret = -ENOMEM;
-		goto error_free_rx;
-	}
 	st->us = spi;
 	mutex_init(&st->buf_lock);
-	/* setup the industrialio driver allocated elements */
-	st->help.indio_dev = iio_allocate_device();
-	if (st->help.indio_dev == NULL) {
-		ret = -ENOMEM;
-		goto error_free_tx;
-	}
+	indio_dev->name = spi->dev.driver->name;
+	indio_dev->dev.parent = &spi->dev;
+	indio_dev->info = &lis3l02dq_info;
+	indio_dev->channels = lis3l02dq_channels;
+	indio_dev->num_channels = ARRAY_SIZE(lis3l02dq_channels);
 
-	st->help.indio_dev->dev.parent = &spi->dev;
-	st->help.indio_dev->num_interrupt_lines = 1;
-	st->help.indio_dev->event_attrs = &lis3l02dq_event_attribute_group;
-	st->help.indio_dev->attrs = &lis3l02dq_attribute_group;
-	st->help.indio_dev->dev_data = (void *)(&st->help);
-	st->help.indio_dev->driver_module = THIS_MODULE;
-	st->help.indio_dev->modes = INDIO_DIRECT_MODE;
+	indio_dev->modes = INDIO_DIRECT_MODE;
 
-	ret = lis3l02dq_configure_ring(st->help.indio_dev);
+	ret = lis3l02dq_configure_ring(indio_dev);
 	if (ret)
 		goto error_free_dev;
 
-	ret = iio_device_register(st->help.indio_dev);
+	ret = iio_device_register(indio_dev);
 	if (ret)
 		goto error_unreg_ring_funcs;
 	regdone = 1;
 
-	ret = iio_ring_buffer_register(st->help.indio_dev->ring, 0);
+	ret = iio_ring_buffer_register_ex(indio_dev->ring, 0,
+					  lis3l02dq_channels,
+					  ARRAY_SIZE(lis3l02dq_channels));
 	if (ret) {
 		printk(KERN_ERR "failed to initialize the ring\n");
 		goto error_unreg_ring_funcs;
 	}
 
 	if (spi->irq && gpio_is_valid(irq_to_gpio(spi->irq)) > 0) {
-		st->inter = 0;
-		ret = iio_register_interrupt_line(spi->irq,
-						  st->help.indio_dev,
-						  0,
-						  IRQF_TRIGGER_RISING,
-						  "lis3l02dq");
+		ret = request_threaded_irq(st->us->irq,
+					   &lis3l02dq_th,
+					   &lis3l02dq_event_handler,
+					   IRQF_TRIGGER_RISING,
+					   "lis3l02dq",
+					   indio_dev);
 		if (ret)
 			goto error_uninitialize_ring;
 
-		ret = lis3l02dq_probe_trigger(st->help.indio_dev);
+		ret = lis3l02dq_probe_trigger(indio_dev);
 		if (ret)
-			goto error_unregister_line;
+			goto error_free_interrupt;
 	}
 
 	/* Get the device into a sane initial state */
-	ret = lis3l02dq_initial_setup(st);
+	ret = lis3l02dq_initial_setup(indio_dev);
 	if (ret)
 		goto error_remove_trigger;
 	return 0;
 
 error_remove_trigger:
-	if (st->help.indio_dev->modes & INDIO_RING_TRIGGERED)
-		lis3l02dq_remove_trigger(st->help.indio_dev);
-error_unregister_line:
-	if (st->help.indio_dev->modes & INDIO_RING_TRIGGERED)
-		iio_unregister_interrupt_line(st->help.indio_dev, 0);
+	if (indio_dev->modes & INDIO_RING_TRIGGERED)
+		lis3l02dq_remove_trigger(indio_dev);
+error_free_interrupt:
+	if (spi->irq && gpio_is_valid(irq_to_gpio(spi->irq)) > 0)
+		free_irq(st->us->irq, indio_dev);
 error_uninitialize_ring:
-	iio_ring_buffer_unregister(st->help.indio_dev->ring);
+	iio_ring_buffer_unregister(indio_dev->ring);
 error_unreg_ring_funcs:
-	lis3l02dq_unconfigure_ring(st->help.indio_dev);
+	lis3l02dq_unconfigure_ring(indio_dev);
 error_free_dev:
 	if (regdone)
-		iio_device_unregister(st->help.indio_dev);
+		iio_device_unregister(indio_dev);
 	else
-		iio_free_device(st->help.indio_dev);
-error_free_tx:
-	kfree(st->tx);
-error_free_rx:
-	kfree(st->rx);
-error_free_st:
-	kfree(st);
+		iio_free_device(indio_dev);
 error_ret:
 	return ret;
 }
@@ -884,23 +749,21 @@
 static int lis3l02dq_stop_device(struct iio_dev *indio_dev)
 {
 	int ret;
-	struct iio_sw_ring_helper_state *h
-		= iio_dev_get_devdata(indio_dev);
-	struct lis3l02dq_state *st = lis3l02dq_h_to_s(h);
+	struct lis3l02dq_state *st = iio_priv(indio_dev);
 	u8 val = 0;
 
 	mutex_lock(&indio_dev->mlock);
-	ret = lis3l02dq_spi_write_reg_8(&indio_dev->dev,
+	ret = lis3l02dq_spi_write_reg_8(indio_dev,
 					LIS3L02DQ_REG_CTRL_1_ADDR,
-					&val);
+					val);
 	if (ret) {
 		dev_err(&st->us->dev, "problem with turning device off: ctrl1");
 		goto err_ret;
 	}
 
-	ret = lis3l02dq_spi_write_reg_8(&indio_dev->dev,
+	ret = lis3l02dq_spi_write_reg_8(indio_dev,
 					LIS3L02DQ_REG_CTRL_2_ADDR,
-					&val);
+					val);
 	if (ret)
 		dev_err(&st->us->dev, "problem with turning device off: ctrl2");
 err_ret:
@@ -912,25 +775,24 @@
 static int lis3l02dq_remove(struct spi_device *spi)
 {
 	int ret;
-	struct lis3l02dq_state *st = spi_get_drvdata(spi);
-	struct iio_dev *indio_dev = st->help.indio_dev;
+	struct iio_dev *indio_dev = spi_get_drvdata(spi);
+	struct lis3l02dq_state *st = iio_priv(indio_dev);
 
-	ret = lis3l02dq_stop_device(indio_dev);
+	ret = lis3l02dq_disable_all_events(indio_dev);
 	if (ret)
 		goto err_ret;
 
-	flush_scheduled_work();
+	ret = lis3l02dq_stop_device(indio_dev);
+	if (ret)
+		goto err_ret;
 
-	lis3l02dq_remove_trigger(indio_dev);
 	if (spi->irq && gpio_is_valid(irq_to_gpio(spi->irq)) > 0)
-		iio_unregister_interrupt_line(indio_dev, 0);
+		free_irq(st->us->irq, indio_dev);
 
+	lis3l02dq_remove_trigger(indio_dev);
 	iio_ring_buffer_unregister(indio_dev->ring);
 	lis3l02dq_unconfigure_ring(indio_dev);
 	iio_device_unregister(indio_dev);
-	kfree(st->tx);
-	kfree(st->rx);
-	kfree(st);
 
 	return 0;
 
diff -druN linux-2.6.39-libre/drivers/staging/iio/accel/lis3l02dq.h linux-3.0-rc7-libre/drivers/staging/iio/accel/lis3l02dq.h
--- linux-2.6.39-libre/drivers/staging/iio/accel/lis3l02dq.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/iio/accel/lis3l02dq.h	2011-07-11 19:51:52.000000000 -0400
@@ -148,38 +148,31 @@
 #define LIS3L02DQ_MAX_RX 12
 /**
  * struct lis3l02dq_state - device instance specific data
- * @helper:		data and func pointer allowing generic functions
  * @us:			actual spi_device
- * @work_thresh:	bh for threshold events
- * @thresh_timestamp:	timestamp for threshold interrupts.
- * @inter:		used to check if new interrupt has been triggered
  * @trig:		data ready trigger registered with iio
  * @tx:			transmit buffer
  * @rx:			receive buffer
  * @buf_lock:		mutex to protect tx and rx
  **/
 struct lis3l02dq_state {
-	struct iio_sw_ring_helper_state	help;
 	struct spi_device		*us;
-	struct work_struct		work_thresh;
-	s64				thresh_timestamp;
-	bool				inter;
 	struct iio_trigger		*trig;
-	u8				*tx;
-	u8				*rx;
 	struct mutex			buf_lock;
-};
+	bool				trigger_on;
 
-#define lis3l02dq_h_to_s(_h)				\
-	container_of(_h, struct lis3l02dq_state, help)
+	u8	tx[LIS3L02DQ_MAX_RX] ____cacheline_aligned;
+	u8	rx[LIS3L02DQ_MAX_RX] ____cacheline_aligned;
+};
 
-int lis3l02dq_spi_read_reg_8(struct device *dev,
+int lis3l02dq_spi_read_reg_8(struct iio_dev *indio_dev,
 			     u8 reg_address,
 			     u8 *val);
 
-int lis3l02dq_spi_write_reg_8(struct device *dev,
+int lis3l02dq_spi_write_reg_8(struct iio_dev *indio_dev,
 			      u8 reg_address,
-			      u8 *val);
+			      u8 val);
+
+int lis3l02dq_disable_all_events(struct iio_dev *indio_dev);
 
 #ifdef CONFIG_IIO_RING_BUFFER
 /* At the moment triggers are only used for ring buffer
@@ -188,9 +181,9 @@
 void lis3l02dq_remove_trigger(struct iio_dev *indio_dev);
 int lis3l02dq_probe_trigger(struct iio_dev *indio_dev);
 
-ssize_t lis3l02dq_read_accel_from_ring(struct device *dev,
-				       struct device_attribute *attr,
-				       char *buf);
+ssize_t lis3l02dq_read_accel_from_ring(struct iio_ring_buffer *ring,
+				       int index,
+				       int *val);
 
 
 int lis3l02dq_configure_ring(struct iio_dev *indio_dev);
@@ -199,14 +192,18 @@
 #ifdef CONFIG_LIS3L02DQ_BUF_RING_SW
 #define lis3l02dq_free_buf iio_sw_rb_free
 #define lis3l02dq_alloc_buf iio_sw_rb_allocate
-#define lis3l02dq_register_buf_funcs iio_ring_sw_register_funcs
+#define lis3l02dq_access_funcs ring_sw_access_funcs
 #endif
 #ifdef CONFIG_LIS3L02DQ_BUF_KFIFO
 #define lis3l02dq_free_buf iio_kfifo_free
 #define lis3l02dq_alloc_buf iio_kfifo_allocate
-#define lis3l02dq_register_buf_funcs iio_kfifo_register_funcs
+#define lis3l02dq_access_funcs kfifo_access_funcs
 #endif
+irqreturn_t lis3l02dq_data_rdy_trig_poll(int irq, void *private);
+#define lis3l02dq_th lis3l02dq_data_rdy_trig_poll
+
 #else /* CONFIG_IIO_RING_BUFFER */
+#define lis3l02dq_th lis3l02dq_noring
 
 static inline void lis3l02dq_remove_trigger(struct iio_dev *indio_dev)
 {
@@ -215,11 +212,10 @@
 {
 	return 0;
 }
-
 static inline ssize_t
-lis3l02dq_read_accel_from_ring(struct device *dev,
-			       struct device_attribute *attr,
-			       char *buf)
+lis3l02dq_read_accel_from_ring(struct iio_ring_buffer *ring,
+			       int index,
+			       int *val)
 {
 	return 0;
 }
diff -druN linux-2.6.39-libre/drivers/staging/iio/accel/lis3l02dq_ring.c linux-3.0-rc7-libre/drivers/staging/iio/accel/lis3l02dq_ring.c
--- linux-2.6.39-libre/drivers/staging/iio/accel/lis3l02dq_ring.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/iio/accel/lis3l02dq_ring.c	2011-07-11 19:51:52.000000000 -0400
@@ -1,13 +1,11 @@
 #include <linux/interrupt.h>
 #include <linux/irq.h>
 #include <linux/gpio.h>
-#include <linux/workqueue.h>
 #include <linux/mutex.h>
 #include <linux/device.h>
 #include <linux/kernel.h>
 #include <linux/spi/spi.h>
 #include <linux/sysfs.h>
-#include <linux/list.h>
 #include <linux/slab.h>
 
 #include "../iio.h"
@@ -29,180 +27,49 @@
 }
 
 /**
- * lis3l02dq_scan_el_set_state() set whether a scan contains a given channel
- * @scan_el:	associtate iio scan element attribute
- * @indio_dev:	the device structure
- * @bool:	desired state
- *
- * mlock already held when this is called.
- **/
-static int lis3l02dq_scan_el_set_state(struct iio_scan_el *scan_el,
-				       struct iio_dev *indio_dev,
-				       bool state)
-{
-	u8 t, mask;
-	int ret;
-
-	ret = lis3l02dq_spi_read_reg_8(&indio_dev->dev,
-				       LIS3L02DQ_REG_CTRL_1_ADDR,
-				       &t);
-	if (ret)
-		goto error_ret;
-	switch (scan_el->label) {
-	case LIS3L02DQ_REG_OUT_X_L_ADDR:
-		mask = LIS3L02DQ_REG_CTRL_1_AXES_X_ENABLE;
-		break;
-	case LIS3L02DQ_REG_OUT_Y_L_ADDR:
-		mask = LIS3L02DQ_REG_CTRL_1_AXES_Y_ENABLE;
-		break;
-	case LIS3L02DQ_REG_OUT_Z_L_ADDR:
-		mask = LIS3L02DQ_REG_CTRL_1_AXES_Z_ENABLE;
-		break;
-	default:
-		ret = -EINVAL;
-		goto error_ret;
-	}
-
-	if (!(mask & t) == state) {
-		if (state)
-			t |= mask;
-		else
-			t &= ~mask;
-		ret = lis3l02dq_spi_write_reg_8(&indio_dev->dev,
-						LIS3L02DQ_REG_CTRL_1_ADDR,
-						&t);
-	}
-error_ret:
-	return ret;
-
-}
-static IIO_SCAN_EL_C(accel_x, 0,
-		     LIS3L02DQ_REG_OUT_X_L_ADDR,
-		     &lis3l02dq_scan_el_set_state);
-static IIO_SCAN_EL_C(accel_y, 1,
-		     LIS3L02DQ_REG_OUT_Y_L_ADDR,
-		     &lis3l02dq_scan_el_set_state);
-static IIO_SCAN_EL_C(accel_z, 2,
-		     LIS3L02DQ_REG_OUT_Z_L_ADDR,
-		     &lis3l02dq_scan_el_set_state);
-static IIO_CONST_ATTR_SCAN_EL_TYPE(accel, s, 12, 16);
-static IIO_SCAN_EL_TIMESTAMP(3);
-static IIO_CONST_ATTR_SCAN_EL_TYPE(timestamp, s, 64, 64);
-
-static struct attribute *lis3l02dq_scan_el_attrs[] = {
-	&iio_scan_el_accel_x.dev_attr.attr,
-	&iio_const_attr_accel_x_index.dev_attr.attr,
-	&iio_scan_el_accel_y.dev_attr.attr,
-	&iio_const_attr_accel_y_index.dev_attr.attr,
-	&iio_scan_el_accel_z.dev_attr.attr,
-	&iio_const_attr_accel_z_index.dev_attr.attr,
-	&iio_const_attr_accel_type.dev_attr.attr,
-	&iio_scan_el_timestamp.dev_attr.attr,
-	&iio_const_attr_timestamp_index.dev_attr.attr,
-	&iio_const_attr_timestamp_type.dev_attr.attr,
-	NULL,
-};
-
-static struct attribute_group lis3l02dq_scan_el_group = {
-	.attrs = lis3l02dq_scan_el_attrs,
-	.name = "scan_elements",
-};
-
-/**
- * lis3l02dq_poll_func_th() top half interrupt handler called by trigger
- * @private_data:	iio_dev
+ * lis3l02dq_data_rdy_trig_poll() the event handler for the data rdy trig
  **/
-static void lis3l02dq_poll_func_th(struct iio_dev *indio_dev, s64 time)
+irqreturn_t lis3l02dq_data_rdy_trig_poll(int irq, void *private)
 {
-	struct iio_sw_ring_helper_state *h
-		= iio_dev_get_devdata(indio_dev);
-	struct lis3l02dq_state *st = lis3l02dq_h_to_s(h);
-	/* in this case we need to slightly extend the helper function */
-	iio_sw_poll_func_th(indio_dev, time);
+	struct iio_dev *indio_dev = private;
+	struct lis3l02dq_state *st = iio_priv(indio_dev);
 
-	/* Indicate that this interrupt is being handled */
-	/* Technically this is trigger related, but without this
-	 * handler running there is currently now way for the interrupt
-	 * to clear.
-	 */
-	st->inter = 1;
+	if (st->trigger_on) {
+		iio_trigger_poll(st->trig, iio_get_time_ns());
+		return IRQ_HANDLED;
+	} else
+		return IRQ_WAKE_THREAD;
 }
 
 /**
- * lis3l02dq_data_rdy_trig_poll() the event handler for the data rdy trig
+ * lis3l02dq_read_accel_from_ring() individual acceleration read from ring
  **/
-static int lis3l02dq_data_rdy_trig_poll(struct iio_dev *indio_dev,
+ssize_t lis3l02dq_read_accel_from_ring(struct iio_ring_buffer *ring,
 				       int index,
-				       s64 timestamp,
-				       int no_test)
+				       int *val)
 {
-	struct iio_sw_ring_helper_state *h
-		= iio_dev_get_devdata(indio_dev);
-	struct lis3l02dq_state *st = lis3l02dq_h_to_s(h);
-
-	iio_trigger_poll(st->trig, timestamp);
+	int ret;
+	s16 *data;
 
-	return IRQ_HANDLED;
-}
+	if (!iio_scan_mask_query(ring, index))
+		return -EINVAL;
 
-/* This is an event as it is a response to a physical interrupt */
-IIO_EVENT_SH(data_rdy_trig, &lis3l02dq_data_rdy_trig_poll);
+	if (!ring->access->read_last)
+		return -EBUSY;
 
-/**
- * lis3l02dq_read_accel_from_ring() individual acceleration read from ring
- **/
-ssize_t lis3l02dq_read_accel_from_ring(struct device *dev,
-				       struct device_attribute *attr,
-				       char *buf)
-{
-	struct iio_scan_el *el = NULL;
-	int ret, len = 0, i = 0;
-	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
-	struct iio_dev *dev_info = dev_get_drvdata(dev);
-	struct iio_ring_buffer *ring = dev_info->ring;
-	struct attribute_group *scan_el_attrs = ring->scan_el_attrs;
-	s16 *data;
+	data = kmalloc(ring->access->get_bytes_per_datum(ring),
+		       GFP_KERNEL);
+	if (data == NULL)
+		return -ENOMEM;
 
-	while (scan_el_attrs->attrs[i]) {
-		el = to_iio_scan_el((struct device_attribute *)
-				    (scan_el_attrs->attrs[i]));
-		/* label is in fact the address */
-		if (el->label == this_attr->address)
-			break;
-		i++;
-	}
-	if (!scan_el_attrs->attrs[i]) {
-		ret = -EINVAL;
-		goto error_ret;
-	}
-	/* If this element is in the scan mask */
-	ret = iio_scan_mask_query(ring, el->number);
-	if (ret < 0)
-		goto error_ret;
-	if (ret) {
-		data = kmalloc(ring->access.get_bytes_per_datum(ring),
-			       GFP_KERNEL);
-		if (data == NULL)
-			return -ENOMEM;
-		ret = ring->access.read_last(ring,
-					(u8 *)data);
-		if (ret)
-			goto error_free_data;
-	} else {
-		ret = -EINVAL;
-		goto error_ret;
-	}
-	len = iio_scan_mask_count_to_right(ring, el->number);
-	if (len < 0) {
-		ret = len;
+	ret = ring->access->read_last(ring, (u8 *)data);
+	if (ret)
 		goto error_free_data;
-	}
-	len = sprintf(buf, "ring %d\n", data[len]);
+	*val = data[bitmap_weight(&ring->scan_mask, index)];
 error_free_data:
 	kfree(data);
-error_ret:
-	return ret ? ret : len;
 
+	return ret;
 }
 
 static const u8 read_all_tx_array[] = {
@@ -220,9 +87,10 @@
  * @rx_array:	(dma capable) receive array, must be at least
  *		4*number of channels
  **/
-static int lis3l02dq_read_all(struct lis3l02dq_state *st, u8 *rx_array)
+static int lis3l02dq_read_all(struct iio_dev *indio_dev, u8 *rx_array)
 {
-	struct iio_ring_buffer *ring = st->help.indio_dev->ring;
+	struct iio_ring_buffer *ring = indio_dev->ring;
+	struct lis3l02dq_state *st = iio_priv(indio_dev);
 	struct spi_transfer *xfers;
 	struct spi_message msg;
 	int ret, i, j = 0;
@@ -234,7 +102,7 @@
 
 	mutex_lock(&st->buf_lock);
 
-	for (i = 0; i < ARRAY_SIZE(read_all_tx_array)/4; i++) {
+	for (i = 0; i < ARRAY_SIZE(read_all_tx_array)/4; i++)
 		if (ring->scan_mask & (1 << i)) {
 			/* lower byte */
 			xfers[j].tx_buf = st->tx + 2*j;
@@ -258,7 +126,7 @@
 			xfers[j].cs_change = 1;
 			j++;
 		}
-	}
+
 	/* After these are transmitted, the rx_buff should have
 	 * values in alternate bytes
 	 */
@@ -273,31 +141,20 @@
 	return ret;
 }
 
-static void lis3l02dq_trigger_bh_to_ring(struct work_struct *work_s)
-{
-	struct iio_sw_ring_helper_state *h
-		= container_of(work_s, struct iio_sw_ring_helper_state,
-			work_trigger_to_ring);
-	struct lis3l02dq_state *st = lis3l02dq_h_to_s(h);
-
-	st->inter = 0;
-	iio_sw_trigger_bh_to_ring(work_s);
-}
-
-static int lis3l02dq_get_ring_element(struct iio_sw_ring_helper_state *h,
+static int lis3l02dq_get_ring_element(struct iio_dev *indio_dev,
 				u8 *buf)
 {
 	int ret, i;
 	u8 *rx_array ;
 	s16 *data = (s16 *)buf;
 
-	rx_array = kzalloc(4 * (h->indio_dev->ring->scan_count), GFP_KERNEL);
+	rx_array = kzalloc(4 * (indio_dev->ring->scan_count), GFP_KERNEL);
 	if (rx_array == NULL)
 		return -ENOMEM;
-	ret = lis3l02dq_read_all(lis3l02dq_h_to_s(h), rx_array);
+	ret = lis3l02dq_read_all(indio_dev, rx_array);
 	if (ret < 0)
 		return ret;
-	for (i = 0; i < h->indio_dev->ring->scan_count; i++)
+	for (i = 0; i < indio_dev->ring->scan_count; i++)
 		data[i] = combine_8_to_16(rx_array[i*4+1],
 					rx_array[i*4+3]);
 	kfree(rx_array);
@@ -305,19 +162,48 @@
 	return i*sizeof(data[0]);
 }
 
+static irqreturn_t lis3l02dq_trigger_handler(int irq, void *p)
+{
+	struct iio_poll_func *pf = p;
+	struct iio_dev *indio_dev = pf->private_data;
+	struct iio_ring_buffer *ring = indio_dev->ring;
+	int len = 0;
+	size_t datasize = ring->access->get_bytes_per_datum(ring);
+	char *data = kmalloc(datasize, GFP_KERNEL);
+
+	if (data == NULL) {
+		dev_err(indio_dev->dev.parent,
+			"memory alloc failed in ring bh");
+		return -ENOMEM;
+	}
+
+	if (ring->scan_count)
+		len = lis3l02dq_get_ring_element(indio_dev, data);
+
+	  /* Guaranteed to be aligned with 8 byte boundary */
+	if (ring->scan_timestamp)
+		*(s64 *)(((phys_addr_t)data + len
+				+ sizeof(s64) - 1) & ~(sizeof(s64) - 1))
+			= pf->timestamp;
+	ring->access->store_to(ring, (u8 *)data, pf->timestamp);
+
+	iio_trigger_notify_done(indio_dev->trig);
+	kfree(data);
+	return IRQ_HANDLED;
+}
+
 /* Caller responsible for locking as necessary. */
 static int
-__lis3l02dq_write_data_ready_config(struct device *dev,
-				    struct iio_event_handler_list *list,
-				    bool state)
+__lis3l02dq_write_data_ready_config(struct device *dev, bool state)
 {
 	int ret;
 	u8 valold;
 	bool currentlyset;
 	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct lis3l02dq_state *st = iio_priv(indio_dev);
 
 /* Get the current event mask register */
-	ret = lis3l02dq_spi_read_reg_8(dev,
+	ret = lis3l02dq_spi_read_reg_8(indio_dev,
 				       LIS3L02DQ_REG_CTRL_2_ADDR,
 				       &valold);
 	if (ret)
@@ -328,32 +214,36 @@
 
 /* Disable requested */
 	if (!state && currentlyset) {
-
+		/* disable the data ready signal */
 		valold &= ~LIS3L02DQ_REG_CTRL_2_ENABLE_DATA_READY_GENERATION;
+
 		/* The double write is to overcome a hardware bug?*/
-		ret = lis3l02dq_spi_write_reg_8(dev,
+		ret = lis3l02dq_spi_write_reg_8(indio_dev,
 						LIS3L02DQ_REG_CTRL_2_ADDR,
-						&valold);
+						valold);
 		if (ret)
 			goto error_ret;
-		ret = lis3l02dq_spi_write_reg_8(dev,
+		ret = lis3l02dq_spi_write_reg_8(indio_dev,
 						LIS3L02DQ_REG_CTRL_2_ADDR,
-						&valold);
+						valold);
 		if (ret)
 			goto error_ret;
-
-		iio_remove_event_from_list(list,
-					   &indio_dev->interrupts[0]
-					   ->ev_list);
-
+		st->trigger_on = false;
 /* Enable requested */
 	} else if (state && !currentlyset) {
 		/* if not set, enable requested */
-		valold |= LIS3L02DQ_REG_CTRL_2_ENABLE_DATA_READY_GENERATION;
-		iio_add_event_to_list(list, &indio_dev->interrupts[0]->ev_list);
-		ret = lis3l02dq_spi_write_reg_8(dev,
+		/* first disable all events */
+		ret = lis3l02dq_disable_all_events(indio_dev);
+		if (ret < 0)
+			goto error_ret;
+
+		valold = ret |
+			LIS3L02DQ_REG_CTRL_2_ENABLE_DATA_READY_GENERATION;
+
+		st->trigger_on = true;
+		ret = lis3l02dq_spi_write_reg_8(indio_dev,
 						LIS3L02DQ_REG_CTRL_2_ADDR,
-						&valold);
+						valold);
 		if (ret)
 			goto error_ret;
 	}
@@ -373,65 +263,45 @@
 static int lis3l02dq_data_rdy_trigger_set_state(struct iio_trigger *trig,
 						bool state)
 {
-	struct lis3l02dq_state *st = trig->private_data;
+	struct iio_dev *indio_dev = trig->private_data;
 	int ret = 0;
 	u8 t;
-	__lis3l02dq_write_data_ready_config(&st->help.indio_dev->dev,
-					    &iio_event_data_rdy_trig,
-					    state);
+
+	__lis3l02dq_write_data_ready_config(&indio_dev->dev, state);
 	if (state == false) {
-		/* possible quirk with handler currently worked around
-		   by ensuring the work queue is empty */
-		flush_scheduled_work();
-		/* Clear any outstanding ready events */
-		ret = lis3l02dq_read_all(st, NULL);
+		/*
+		 * A possible quirk with teh handler is currently worked around
+		 *  by ensuring outstanding read events are cleared.
+		 */
+		ret = lis3l02dq_read_all(indio_dev, NULL);
 	}
-	lis3l02dq_spi_read_reg_8(&st->help.indio_dev->dev,
+	lis3l02dq_spi_read_reg_8(indio_dev,
 				 LIS3L02DQ_REG_WAKE_UP_SRC_ADDR,
 				 &t);
 	return ret;
 }
 
-static IIO_TRIGGER_NAME_ATTR;
-
-static struct attribute *lis3l02dq_trigger_attrs[] = {
-	&dev_attr_name.attr,
-	NULL,
-};
-
-static const struct attribute_group lis3l02dq_trigger_attr_group = {
-	.attrs = lis3l02dq_trigger_attrs,
-};
-
 /**
  * lis3l02dq_trig_try_reen() try renabling irq for data rdy trigger
  * @trig:	the datardy trigger
- *
- * As the trigger may occur on any data element being updated it is
- * really rather likely to occur during the read from the previous
- * trigger event.  The only way to discover if this has occurred on
- * boards not supporting level interrupts is to take a look at the line.
- * If it is indicating another interrupt and we don't seem to have a
- * handler looking at it, then we need to notify the core that we need
- * to tell the triggering core to try reading all these again.
- **/
+ */
 static int lis3l02dq_trig_try_reen(struct iio_trigger *trig)
 {
-	struct lis3l02dq_state *st = trig->private_data;
-	enable_irq(st->us->irq);
+	struct iio_dev *indio_dev = trig->private_data;
+	struct lis3l02dq_state *st = iio_priv(indio_dev);
+	int i;
+
 	/* If gpio still high (or high again) */
-	if (gpio_get_value(irq_to_gpio(st->us->irq)))
-		if (st->inter == 0) {
-			/* already interrupt handler dealing with it */
-			disable_irq_nosync(st->us->irq);
-			if (st->inter == 1) {
-				/* interrupt handler snuck in between test
-				 * and disable */
-				enable_irq(st->us->irq);
-				return 0;
-			}
-			return -EAGAIN;
-		}
+	/* In theory possible we will need to do this several times */
+	for (i = 0; i < 5; i++)
+		if (gpio_get_value(irq_to_gpio(st->us->irq)))
+			lis3l02dq_read_all(indio_dev, NULL);
+		else
+			break;
+	if (i == 5)
+		printk(KERN_INFO
+		       "Failed to clear the interrupt for lis3l02dq\n");
+
 	/* irq reenabled so success! */
 	return 0;
 }
@@ -439,62 +309,124 @@
 int lis3l02dq_probe_trigger(struct iio_dev *indio_dev)
 {
 	int ret;
-	struct lis3l02dq_state *state = indio_dev->dev_data;
-
-	state->trig = iio_allocate_trigger();
-	if (!state->trig)
-		return -ENOMEM;
+	struct lis3l02dq_state *st = iio_priv(indio_dev);
 
-	state->trig->name = kasprintf(GFP_KERNEL,
-				      "lis3l02dq-dev%d",
-				      indio_dev->id);
-	if (!state->trig->name) {
+	st->trig = iio_allocate_trigger("lis3l02dq-dev%d", indio_dev->id);
+	if (!st->trig) {
 		ret = -ENOMEM;
-		goto error_free_trig;
+		goto error_ret;
 	}
 
-	state->trig->dev.parent = &state->us->dev;
-	state->trig->owner = THIS_MODULE;
-	state->trig->private_data = state;
-	state->trig->set_trigger_state = &lis3l02dq_data_rdy_trigger_set_state;
-	state->trig->try_reenable = &lis3l02dq_trig_try_reen;
-	state->trig->control_attrs = &lis3l02dq_trigger_attr_group;
-	ret = iio_trigger_register(state->trig);
+	st->trig->dev.parent = &st->us->dev;
+	st->trig->owner = THIS_MODULE;
+	st->trig->private_data = indio_dev;
+	st->trig->set_trigger_state = &lis3l02dq_data_rdy_trigger_set_state;
+	st->trig->try_reenable = &lis3l02dq_trig_try_reen;
+	ret = iio_trigger_register(st->trig);
 	if (ret)
-		goto error_free_trig_name;
+		goto error_free_trig;
 
 	return 0;
 
-error_free_trig_name:
-	kfree(state->trig->name);
 error_free_trig:
-	iio_free_trigger(state->trig);
-
+	iio_free_trigger(st->trig);
+error_ret:
 	return ret;
 }
 
 void lis3l02dq_remove_trigger(struct iio_dev *indio_dev)
 {
-	struct lis3l02dq_state *state = indio_dev->dev_data;
+	struct lis3l02dq_state *st = iio_priv(indio_dev);
 
-	iio_trigger_unregister(state->trig);
-	kfree(state->trig->name);
-	iio_free_trigger(state->trig);
+	iio_trigger_unregister(st->trig);
+	iio_free_trigger(st->trig);
 }
 
 void lis3l02dq_unconfigure_ring(struct iio_dev *indio_dev)
 {
-	kfree(indio_dev->pollfunc);
+	iio_dealloc_pollfunc(indio_dev->pollfunc);
 	lis3l02dq_free_buf(indio_dev->ring);
 }
 
+static int lis3l02dq_ring_postenable(struct iio_dev *indio_dev)
+{
+	/* Disable unwanted channels otherwise the interrupt will not clear */
+	u8 t;
+	int ret;
+	bool oneenabled = false;
+
+	ret = lis3l02dq_spi_read_reg_8(indio_dev,
+				       LIS3L02DQ_REG_CTRL_1_ADDR,
+				       &t);
+	if (ret)
+		goto error_ret;
+
+	if (iio_scan_mask_query(indio_dev->ring, 0)) {
+		t |= LIS3L02DQ_REG_CTRL_1_AXES_X_ENABLE;
+		oneenabled = true;
+	} else
+		t &= ~LIS3L02DQ_REG_CTRL_1_AXES_X_ENABLE;
+	if (iio_scan_mask_query(indio_dev->ring, 1)) {
+		t |= LIS3L02DQ_REG_CTRL_1_AXES_Y_ENABLE;
+		oneenabled = true;
+	} else
+		t &= ~LIS3L02DQ_REG_CTRL_1_AXES_Y_ENABLE;
+	if (iio_scan_mask_query(indio_dev->ring, 2)) {
+		t |= LIS3L02DQ_REG_CTRL_1_AXES_Z_ENABLE;
+		oneenabled = true;
+	} else
+		t &= ~LIS3L02DQ_REG_CTRL_1_AXES_Z_ENABLE;
+
+	if (!oneenabled) /* what happens in this case is unknown */
+		return -EINVAL;
+	ret = lis3l02dq_spi_write_reg_8(indio_dev,
+					LIS3L02DQ_REG_CTRL_1_ADDR,
+					t);
+	if (ret)
+		goto error_ret;
+
+	return iio_triggered_ring_postenable(indio_dev);
+error_ret:
+	return ret;
+}
+
+/* Turn all channels on again */
+static int lis3l02dq_ring_predisable(struct iio_dev *indio_dev)
+{
+	u8 t;
+	int ret;
+
+	ret = iio_triggered_ring_predisable(indio_dev);
+	if (ret)
+		goto error_ret;
+
+	ret = lis3l02dq_spi_read_reg_8(indio_dev,
+				       LIS3L02DQ_REG_CTRL_1_ADDR,
+				       &t);
+	if (ret)
+		goto error_ret;
+	t |= LIS3L02DQ_REG_CTRL_1_AXES_X_ENABLE |
+		LIS3L02DQ_REG_CTRL_1_AXES_Y_ENABLE |
+		LIS3L02DQ_REG_CTRL_1_AXES_Z_ENABLE;
+
+	ret = lis3l02dq_spi_write_reg_8(indio_dev,
+					LIS3L02DQ_REG_CTRL_1_ADDR,
+					t);
+
+error_ret:
+	return ret;
+}
+
+static const struct iio_ring_setup_ops lis3l02dq_ring_setup_ops = {
+	.preenable = &iio_sw_ring_preenable,
+	.postenable = &lis3l02dq_ring_postenable,
+	.predisable = &lis3l02dq_ring_predisable,
+};
+
 int lis3l02dq_configure_ring(struct iio_dev *indio_dev)
 {
 	int ret;
-	struct iio_sw_ring_helper_state *h = iio_dev_get_devdata(indio_dev);
 	struct iio_ring_buffer *ring;
-	INIT_WORK(&h->work_trigger_to_ring, lis3l02dq_trigger_bh_to_ring);
-	h->get_ring_element = &lis3l02dq_get_ring_element;
 
 	ring = lis3l02dq_alloc_buf(indio_dev);
 	if (!ring)
@@ -502,23 +434,31 @@
 
 	indio_dev->ring = ring;
 	/* Effectively select the ring buffer implementation */
-	lis3l02dq_register_buf_funcs(&ring->access);
+	indio_dev->ring->access = &lis3l02dq_access_funcs;
 	ring->bpe = 2;
-	ring->scan_el_attrs = &lis3l02dq_scan_el_group;
+
 	ring->scan_timestamp = true;
-	ring->preenable = &iio_sw_ring_preenable;
-	ring->postenable = &iio_triggered_ring_postenable;
-	ring->predisable = &iio_triggered_ring_predisable;
+	ring->setup_ops = &lis3l02dq_ring_setup_ops;
 	ring->owner = THIS_MODULE;
 
 	/* Set default scan mode */
-	iio_scan_mask_set(ring, iio_scan_el_accel_x.number);
-	iio_scan_mask_set(ring, iio_scan_el_accel_y.number);
-	iio_scan_mask_set(ring, iio_scan_el_accel_z.number);
+	iio_scan_mask_set(ring, 0);
+	iio_scan_mask_set(ring, 1);
+	iio_scan_mask_set(ring, 2);
 
-	ret = iio_alloc_pollfunc(indio_dev, NULL, &lis3l02dq_poll_func_th);
-	if (ret)
+	/* Functions are NULL as we set handler below */
+	indio_dev->pollfunc = iio_alloc_pollfunc(&iio_pollfunc_store_time,
+						 &lis3l02dq_trigger_handler,
+						 0,
+						 indio_dev,
+						 "lis3l02dq_consumer%d",
+						 indio_dev->id);
+
+	if (indio_dev->pollfunc == NULL) {
+		ret = -ENOMEM;
 		goto error_iio_sw_rb_free;
+	}
+
 	indio_dev->modes |= INDIO_RING_TRIGGERED;
 	return 0;
 
diff -druN linux-2.6.39-libre/drivers/staging/iio/accel/sca3000_core.c linux-3.0-rc7-libre/drivers/staging/iio/accel/sca3000_core.c
--- linux-2.6.39-libre/drivers/staging/iio/accel/sca3000_core.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/iio/accel/sca3000_core.c	2011-07-11 19:51:52.000000000 -0400
@@ -40,95 +40,74 @@
  * do not actually appear to be available.
  */
 static const struct sca3000_chip_info sca3000_spi_chip_info_tbl[] = {
-	{
-		.name = "sca3000-d01",
-		.scale = " 0.0073575",
+	[d01] = {
+		.scale = 7357,
 		.temp_output = true,
 		.measurement_mode_freq = 250,
 		.option_mode_1 = SCA3000_OP_MODE_BYPASS,
 		.option_mode_1_freq = 250,
-	}, {
-		.name = "sca3000-e02",
-		.scale = "0.00981",
+		.mot_det_mult_xz = {50, 100, 200, 350, 650, 1300},
+		.mot_det_mult_y = {50, 100, 150, 250, 450, 850, 1750},
+	},
+	[e02] = {
+		.scale = 9810,
 		.measurement_mode_freq = 125,
 		.option_mode_1 = SCA3000_OP_MODE_NARROW,
 		.option_mode_1_freq = 63,
-	}, {
-		.name = "sca3000-e04",
-		.scale = "0.01962",
+		.mot_det_mult_xz = {100, 150, 300, 550, 1050, 2050},
+		.mot_det_mult_y = {50, 100, 200, 350, 700, 1350, 2700},
+	},
+	[e04] = {
+		.scale = 19620,
 		.measurement_mode_freq = 100,
 		.option_mode_1 = SCA3000_OP_MODE_NARROW,
 		.option_mode_1_freq = 50,
 		.option_mode_2 = SCA3000_OP_MODE_WIDE,
 		.option_mode_2_freq = 400,
-	}, {
-		.name = "sca3000-e05",
-		.scale = "0.0613125",
+		.mot_det_mult_xz = {200, 300, 600, 1100, 2100, 4100},
+		.mot_det_mult_y = {100, 200, 400, 7000, 1400, 2700, 54000},
+	},
+	[e05] = {
+		.scale = 61313,
 		.measurement_mode_freq = 200,
 		.option_mode_1 = SCA3000_OP_MODE_NARROW,
 		.option_mode_1_freq = 50,
 		.option_mode_2 = SCA3000_OP_MODE_WIDE,
 		.option_mode_2_freq = 400,
+		.mot_det_mult_xz = {600, 900, 1700, 3200, 6100, 11900},
+		.mot_det_mult_y = {300, 600, 1200, 2000, 4100, 7800, 15600},
 	},
 };
 
-
 int sca3000_write_reg(struct sca3000_state *st, u8 address, u8 val)
 {
-	struct spi_transfer xfer = {
-		.bits_per_word = 8,
-		.len = 2,
-		.cs_change = 1,
-		.tx_buf = st->tx,
-	};
-	struct spi_message msg;
-
 	st->tx[0] = SCA3000_WRITE_REG(address);
 	st->tx[1] = val;
-	spi_message_init(&msg);
-	spi_message_add_tail(&xfer, &msg);
-
-	return spi_sync(st->us, &msg);
+	return spi_write(st->us, st->tx, 2);
 }
 
-int sca3000_read_data(struct sca3000_state *st,
-		      uint8_t reg_address_high,
-		      u8 **rx_p,
-		      int len)
+int sca3000_read_data_short(struct sca3000_state *st,
+			    uint8_t reg_address_high,
+			    int len)
 {
-	int ret;
 	struct spi_message msg;
-	struct spi_transfer xfer = {
-		.bits_per_word = 8,
-		.len = len + 1,
-		.cs_change = 1,
-		.tx_buf = st->tx,
+	struct spi_transfer xfer[2] = {
+		{
+			.len = 1,
+			.tx_buf = st->tx,
+		}, {
+			.len = len,
+			.rx_buf = st->rx,
+		}
 	};
-
-	*rx_p = kmalloc(len + 1, GFP_KERNEL);
-	if (*rx_p == NULL) {
-		ret = -ENOMEM;
-		goto error_ret;
-	}
-	xfer.rx_buf = *rx_p;
 	st->tx[0] = SCA3000_READ_REG(reg_address_high);
 	spi_message_init(&msg);
-	spi_message_add_tail(&xfer, &msg);
-
-	ret = spi_sync(st->us, &msg);
-
-	if (ret) {
-		dev_err(get_device(&st->us->dev), "problem reading register");
-		goto error_free_rx;
-	}
-
-	return 0;
-error_free_rx:
-	kfree(*rx_p);
-error_ret:
-	return ret;
+	spi_message_add_tail(&xfer[0], &msg);
+	spi_message_add_tail(&xfer[1], &msg);
 
+	return spi_sync(st->us, &msg);
 }
+
 /**
  * sca3000_reg_lock_on() test if the ctrl register lock is on
  *
@@ -136,17 +115,13 @@
  **/
 static int sca3000_reg_lock_on(struct sca3000_state *st)
 {
-	u8 *rx;
 	int ret;
 
-	ret = sca3000_read_data(st, SCA3000_REG_ADDR_STATUS, &rx, 1);
-
+	ret = sca3000_read_data_short(st, SCA3000_REG_ADDR_STATUS, 1);
 	if (ret < 0)
 		return ret;
-	ret = !(rx[1] & SCA3000_LOCKED);
-	kfree(rx);
 
-	return ret;
+	return !(st->rx[0] & SCA3000_LOCKED);
 }
 
 /**
@@ -161,19 +136,15 @@
 	struct spi_message msg;
 	struct spi_transfer xfer[3] = {
 		{
-			.bits_per_word = 8,
 			.len = 2,
 			.cs_change = 1,
 			.tx_buf = st->tx,
 		}, {
-			.bits_per_word = 8,
 			.len = 2,
 			.cs_change = 1,
 			.tx_buf = st->tx + 2,
 		}, {
-			.bits_per_word = 8,
 			.len = 2,
-			.cs_change = 1,
 			.tx_buf = st->tx + 4,
 		},
 	};
@@ -236,8 +207,7 @@
  * Lock must be held.
  **/
 static int sca3000_read_ctrl_reg(struct sca3000_state *st,
-				 u8 ctrl_reg,
-				 u8 **rx_p)
+				 u8 ctrl_reg)
 {
 	int ret;
 
@@ -253,8 +223,11 @@
 	ret = sca3000_write_reg(st, SCA3000_REG_ADDR_CTRL_SEL, ctrl_reg);
 	if (ret)
 		goto error_ret;
-	ret = sca3000_read_data(st, SCA3000_REG_ADDR_CTRL_DATA, rx_p, 1);
-
+	ret = sca3000_read_data_short(st, SCA3000_REG_ADDR_CTRL_DATA, 1);
+	if (ret)
+		goto error_ret;
+	else
+		return st->rx[0];
 error_ret:
 	return ret;
 }
@@ -267,20 +240,18 @@
  **/
 static int sca3000_check_status(struct device *dev)
 {
-	u8 *rx;
 	int ret;
 	struct iio_dev *indio_dev = dev_get_drvdata(dev);
 	struct sca3000_state *st = indio_dev->dev_data;
 
 	mutex_lock(&st->lock);
-	ret = sca3000_read_data(st, SCA3000_REG_ADDR_STATUS, &rx, 1);
+	ret = sca3000_read_data_short(st, SCA3000_REG_ADDR_STATUS, 1);
 	if (ret < 0)
 		goto error_ret;
-	if (rx[1] & SCA3000_EEPROM_CS_ERROR)
+	if (st->rx[0] & SCA3000_EEPROM_CS_ERROR)
 		dev_err(dev, "eeprom error\n");
-	if (rx[1] & SCA3000_SPI_FRAME_ERROR)
+	if (st->rx[0] & SCA3000_SPI_FRAME_ERROR)
 		dev_err(dev, "Previous SPI Frame was corrupt\n");
-	kfree(rx);
 
 error_ret:
 	mutex_unlock(&st->lock);
@@ -288,53 +259,7 @@
 }
 #endif /* SCA3000_DEBUG */
 
-/**
- * sca3000_read_13bit_signed() sysfs interface to read 13 bit signed registers
- *
- * These are described as signed 12 bit on the data sheet, which appears
- * to be a conventional 2's complement 13 bit.
- **/
-static ssize_t sca3000_read_13bit_signed(struct device *dev,
-					 struct device_attribute *attr,
-					 char *buf)
-{
-	int len = 0, ret;
-	int val;
-	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
-	u8 *rx;
-	struct iio_dev *indio_dev = dev_get_drvdata(dev);
-	struct sca3000_state *st = indio_dev->dev_data;
-
-	mutex_lock(&st->lock);
-	ret = sca3000_read_data(st, this_attr->address, &rx, 2);
-	if (ret < 0)
-		goto error_ret;
-	val = sca3000_13bit_convert(rx[1], rx[2]);
-	len += sprintf(buf + len, "%d\n", val);
-	kfree(rx);
-error_ret:
-	mutex_unlock(&st->lock);
-
-	return ret ? ret : len;
-}
-
-static ssize_t sca3000_show_scale(struct device *dev,
-				  struct device_attribute *attr,
-				  char *buf)
-{
-	struct iio_dev *dev_info = dev_get_drvdata(dev);
-	struct sca3000_state *st = dev_info->dev_data;
-	return sprintf(buf, "%s\n", st->info->scale);
-}
 
-static ssize_t sca3000_show_name(struct device *dev,
-				 struct device_attribute *attr,
-				 char *buf)
-{
-	struct iio_dev *dev_info = dev_get_drvdata(dev);
-	struct sca3000_state *st = dev_info->dev_data;
-	return sprintf(buf, "%s\n", st->info->name);
-}
 /**
  * sca3000_show_reg() - sysfs interface to read the chip revision number
  **/
@@ -346,18 +271,14 @@
 	struct iio_dev *dev_info = dev_get_drvdata(dev);
 	struct sca3000_state *st = dev_info->dev_data;
 
-	u8 *rx;
-
 	mutex_lock(&st->lock);
-	ret = sca3000_read_data(st, SCA3000_REG_ADDR_REVID, &rx, 1);
+	ret = sca3000_read_data_short(st, SCA3000_REG_ADDR_REVID, 1);
 	if (ret < 0)
 		goto error_ret;
 	len += sprintf(buf + len,
 		       "major=%d, minor=%d\n",
-		       rx[1] & SCA3000_REVID_MAJOR_MASK,
-		       rx[1] & SCA3000_REVID_MINOR_MASK);
-	kfree(rx);
-
+		       st->rx[0] & SCA3000_REVID_MAJOR_MASK,
+		       st->rx[0] & SCA3000_REVID_MINOR_MASK);
 error_ret:
 	mutex_unlock(&st->lock);
 
@@ -410,15 +331,14 @@
 	struct iio_dev *dev_info = dev_get_drvdata(dev);
 	struct sca3000_state *st = dev_info->dev_data;
 	int len = 0, ret;
-	u8 *rx;
 
 	mutex_lock(&st->lock);
-	ret = sca3000_read_data(st, SCA3000_REG_ADDR_MODE, &rx, 1);
+	ret = sca3000_read_data_short(st, SCA3000_REG_ADDR_MODE, 1);
 	if (ret)
 		goto error_ret;
 	/* mask bottom 2 bits - only ones that are relevant */
-	rx[1] &= 0x03;
-	switch (rx[1]) {
+	st->rx[0] &= 0x03;
+	switch (st->rx[0]) {
 	case SCA3000_MEAS_MODE_NORMAL:
 		len += sprintf(buf + len, "0 - normal mode\n");
 		break;
@@ -462,7 +382,6 @@
 	struct iio_dev *dev_info = dev_get_drvdata(dev);
 	struct sca3000_state *st = dev_info->dev_data;
 	int ret;
-	u8 *rx;
 	int mask = 0x03;
 	long val;
 
@@ -470,20 +389,18 @@
 	ret = strict_strtol(buf, 10, &val);
 	if (ret)
 		goto error_ret;
-	ret = sca3000_read_data(st, SCA3000_REG_ADDR_MODE, &rx, 1);
+	ret = sca3000_read_data_short(st, SCA3000_REG_ADDR_MODE, 1);
 	if (ret)
 		goto error_ret;
-	rx[1] &= ~mask;
-	rx[1] |= (val & mask);
-	ret = sca3000_write_reg(st, SCA3000_REG_ADDR_MODE, rx[1]);
+	st->rx[0] &= ~mask;
+	st->rx[0] |= (val & mask);
+	ret = sca3000_write_reg(st, SCA3000_REG_ADDR_MODE, st->rx[0]);
 	if (ret)
-		goto error_free_rx;
+		goto error_ret;
 	mutex_unlock(&st->lock);
 
 	return len;
 
-error_free_rx:
-	kfree(rx);
 error_ret:
 	mutex_unlock(&st->lock);
 
@@ -505,18 +422,70 @@
 
 /* More standard attributes */
 
-static IIO_DEV_ATTR_NAME(sca3000_show_name);
 static IIO_DEV_ATTR_REV(sca3000_show_rev);
-static IIO_DEVICE_ATTR(accel_scale, S_IRUGO, sca3000_show_scale,
-		       NULL, 0);
 
-static IIO_DEV_ATTR_ACCEL_X(sca3000_read_13bit_signed,
-			    SCA3000_REG_ADDR_X_MSB);
-static IIO_DEV_ATTR_ACCEL_Y(sca3000_read_13bit_signed,
-			    SCA3000_REG_ADDR_Y_MSB);
-static IIO_DEV_ATTR_ACCEL_Z(sca3000_read_13bit_signed,
-			    SCA3000_REG_ADDR_Z_MSB);
+#define SCA3000_INFO_MASK			\
+	(1 << IIO_CHAN_INFO_SCALE_SHARED)
+#define SCA3000_EVENT_MASK					\
+	(IIO_EV_BIT(IIO_EV_TYPE_MAG, IIO_EV_DIR_RISING))
 
+static struct iio_chan_spec sca3000_channels[] = {
+	IIO_CHAN(IIO_ACCEL, 1, 0, 0, NULL, 0, IIO_MOD_X, SCA3000_INFO_MASK,
+		 0, 0, IIO_ST('s', 11, 16, 5), SCA3000_EVENT_MASK),
+	IIO_CHAN(IIO_ACCEL, 1, 0, 0, NULL, 0, IIO_MOD_Y, SCA3000_INFO_MASK,
+		 1, 1, IIO_ST('s', 11, 16, 5), SCA3000_EVENT_MASK),
+	IIO_CHAN(IIO_ACCEL, 1, 0, 0, NULL, 0, IIO_MOD_Z, SCA3000_INFO_MASK,
+		 2, 2, IIO_ST('s', 11, 16, 5), SCA3000_EVENT_MASK),
+};
+
+static u8 sca3000_addresses[3][3] = {
+	[0] = {SCA3000_REG_ADDR_X_MSB, SCA3000_REG_CTRL_SEL_MD_X_TH,
+	       SCA3000_MD_CTRL_OR_X},
+	[1] = {SCA3000_REG_ADDR_Y_MSB, SCA3000_REG_CTRL_SEL_MD_Y_TH,
+	       SCA3000_MD_CTRL_OR_Y},
+	[2] = {SCA3000_REG_ADDR_Z_MSB, SCA3000_REG_CTRL_SEL_MD_Z_TH,
+	       SCA3000_MD_CTRL_OR_Z},
+};
+
+static int sca3000_read_raw(struct iio_dev *indio_dev,
+			    struct iio_chan_spec const *chan,
+			    int *val,
+			    int *val2,
+			    long mask)
+{
+	struct sca3000_state *st = indio_dev->dev_data;
+	int ret;
+	u8 address;
+
+	switch (mask) {
+	case 0:
+		mutex_lock(&st->lock);
+		if (st->mo_det_use_count) {
+			mutex_unlock(&st->lock);
+			return -EBUSY;
+		}
+		address = sca3000_addresses[chan->address][0];
+		ret = sca3000_read_data_short(st, address, 2);
+		if (ret < 0) {
+			mutex_unlock(&st->lock);
+			return ret;
+		}
+		*val = (be16_to_cpup((__be16 *)st->rx) >> 3) & 0x1FFF;
+		*val = ((*val) << (sizeof(*val)*8 - 13)) >>
+			(sizeof(*val)*8 - 13);
+		mutex_unlock(&st->lock);
+		return IIO_VAL_INT;
+	case (1 << IIO_CHAN_INFO_SCALE_SHARED):
+		*val = 0;
+		if (chan->type == IIO_ACCEL)
+			*val2 = st->info->scale;
+		else /* temperature */
+			*val2 = 555556;
+		return IIO_VAL_INT_PLUS_MICRO;
+	default:
+		return -EINVAL;
+	}
+}
 
 /**
  * sca3000_read_av_freq() sysfs function to get available frequencies
@@ -532,15 +501,16 @@
 {
 	struct iio_dev *indio_dev = dev_get_drvdata(dev);
 	struct sca3000_state *st = indio_dev->dev_data;
-	int len = 0, ret;
-	u8 *rx;
+	int len = 0, ret, val;
+
 	mutex_lock(&st->lock);
-	ret = sca3000_read_data(st, SCA3000_REG_ADDR_MODE, &rx, 1);
+	ret = sca3000_read_data_short(st, SCA3000_REG_ADDR_MODE, 1);
+	val = st->rx[0];
 	mutex_unlock(&st->lock);
 	if (ret)
 		goto error_ret;
-	rx[1] &= 0x03;
-	switch (rx[1]) {
+
+	switch (val & 0x03) {
 	case SCA3000_MEAS_MODE_NORMAL:
 		len += sprintf(buf + len, "%d %d %d\n",
 			       st->info->measurement_mode_freq,
@@ -560,7 +530,6 @@
 			       st->info->option_mode_2_freq/4);
 		break;
 	}
-	kfree(rx);
 	return len;
 error_ret:
 	return ret;
@@ -575,12 +544,11 @@
 					  int *base_freq)
 {
 	int ret;
-	u8 *rx;
 
-	ret = sca3000_read_data(st, SCA3000_REG_ADDR_MODE, &rx, 1);
+	ret = sca3000_read_data_short(st, SCA3000_REG_ADDR_MODE, 1);
 	if (ret)
 		goto error_ret;
-	switch (0x03 & rx[1]) {
+	switch (0x03 & st->rx[0]) {
 	case SCA3000_MEAS_MODE_NORMAL:
 		*base_freq = info->measurement_mode_freq;
 		break;
@@ -591,7 +559,6 @@
 		*base_freq = info->option_mode_2_freq;
 		break;
 	}
-	kfree(rx);
 error_ret:
 	return ret;
 }
@@ -605,18 +572,19 @@
 {
 	struct iio_dev *indio_dev = dev_get_drvdata(dev);
 	struct sca3000_state *st = indio_dev->dev_data;
-	int ret, len = 0, base_freq = 0;
-	u8 *rx;
+	int ret, len = 0, base_freq = 0, val;
+
 	mutex_lock(&st->lock);
 	ret = __sca3000_get_base_freq(st, st->info, &base_freq);
 	if (ret)
 		goto error_ret_mut;
-	ret = sca3000_read_ctrl_reg(st, SCA3000_REG_CTRL_SEL_OUT_CTRL, &rx);
+	ret = sca3000_read_ctrl_reg(st, SCA3000_REG_CTRL_SEL_OUT_CTRL);
 	mutex_unlock(&st->lock);
 	if (ret)
 		goto error_ret;
+	val = ret;
 	if (base_freq > 0)
-		switch (rx[1]&0x03) {
+		switch (val & 0x03) {
 		case 0x00:
 		case 0x03:
 			len = sprintf(buf, "%d\n", base_freq);
@@ -628,7 +596,7 @@
 			len = sprintf(buf, "%d\n", base_freq/4);
 			break;
 	}
-	kfree(rx);
+
 	return len;
 error_ret_mut:
 	mutex_unlock(&st->lock);
@@ -647,7 +615,7 @@
 	struct iio_dev *indio_dev = dev_get_drvdata(dev);
 	struct sca3000_state *st = indio_dev->dev_data;
 	int ret, base_freq = 0;
-	u8 *rx;
+	int ctrlval;
 	long val;
 
 	ret = strict_strtol(buf, 10, &val);
@@ -660,21 +628,23 @@
 	if (ret)
 		goto error_free_lock;
 
-	ret = sca3000_read_ctrl_reg(st, SCA3000_REG_CTRL_SEL_OUT_CTRL, &rx);
-	if (ret)
+	ret = sca3000_read_ctrl_reg(st, SCA3000_REG_CTRL_SEL_OUT_CTRL);
+	if (ret < 0)
 		goto error_free_lock;
+	ctrlval = ret;
 	/* clear the bits */
-	rx[1] &= ~0x03;
+	ctrlval &= ~0x03;
 
 	if (val == base_freq/2) {
-		rx[1] |= SCA3000_OUT_CTRL_BUF_DIV_2;
+		ctrlval |= SCA3000_OUT_CTRL_BUF_DIV_2;
 	} else if (val == base_freq/4) {
-		rx[1] |= SCA3000_OUT_CTRL_BUF_DIV_4;
+		ctrlval |= SCA3000_OUT_CTRL_BUF_DIV_4;
 	} else if (val != base_freq) {
 		ret = -EINVAL;
 		goto error_free_lock;
 	}
-	ret = sca3000_write_ctrl_reg(st, SCA3000_REG_CTRL_SEL_OUT_CTRL, rx[1]);
+	ret = sca3000_write_ctrl_reg(st, SCA3000_REG_CTRL_SEL_OUT_CTRL,
+				     ctrlval);
 error_free_lock:
 	mutex_unlock(&st->lock);
 
@@ -704,17 +674,14 @@
 {
 	struct iio_dev *indio_dev = dev_get_drvdata(dev);
 	struct sca3000_state *st = indio_dev->dev_data;
-	int len = 0, ret;
+	int ret;
 	int val;
-	u8 *rx;
-	ret = sca3000_read_data(st, SCA3000_REG_ADDR_TEMP_MSB, &rx, 2);
+	ret = sca3000_read_data_short(st, SCA3000_REG_ADDR_TEMP_MSB, 2);
 	if (ret < 0)
 		goto error_ret;
-	val = ((rx[1]&0x3F) << 3) | ((rx[2] & 0xE0) >> 5);
-	len += sprintf(buf + len, "%d\n", val);
-	kfree(rx);
+	val = ((st->rx[0] & 0x3F) << 3) | ((st->rx[1] & 0xE0) >> 5);
 
-	return len;
+	return sprintf(buf, "%d\n", val);
 
 error_ret:
 	return ret;
@@ -725,80 +692,71 @@
 static IIO_CONST_ATTR_TEMP_OFFSET("-214.6");
 
 /**
- * sca3000_show_thresh() sysfs query of a threshold
+ * sca3000_read_thresh() - query of a threshold
  **/
-static ssize_t sca3000_show_thresh(struct device *dev,
-				   struct device_attribute *attr,
-				   char *buf)
+static int sca3000_read_thresh(struct iio_dev *indio_dev,
+			       int e,
+			       int *val)
 {
-	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	int ret, i;
 	struct sca3000_state *st = indio_dev->dev_data;
-	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
-	int len = 0, ret;
-	u8 *rx;
-
+	int num = IIO_EVENT_CODE_EXTRACT_MODIFIER(e);
 	mutex_lock(&st->lock);
-	ret = sca3000_read_ctrl_reg(st,
-				    this_attr->address,
-				    &rx);
+	ret = sca3000_read_ctrl_reg(st, sca3000_addresses[num][1]);
 	mutex_unlock(&st->lock);
-	if (ret)
+	if (ret < 0)
 		return ret;
-	len += sprintf(buf + len, "%d\n", rx[1]);
-	kfree(rx);
+	*val = 0;
+	if (num == 1)
+		for_each_set_bit(i, (unsigned long *)&ret,
+				 ARRAY_SIZE(st->info->mot_det_mult_y))
+			*val += st->info->mot_det_mult_y[i];
+	else
+		for_each_set_bit(i, (unsigned long *)&ret,
+				 ARRAY_SIZE(st->info->mot_det_mult_xz))
+			*val += st->info->mot_det_mult_xz[i];
 
-	return len;
+	return 0;
 }
 
 /**
- * sca3000_write_thresh() sysfs control of threshold
+ * sca3000_write_thresh() control of threshold
  **/
-static ssize_t sca3000_write_thresh(struct device *dev,
-				    struct device_attribute *attr,
-				    const char *buf,
-				    size_t len)
+static int sca3000_write_thresh(struct iio_dev *indio_dev,
+				    int e,
+				    int val)
 {
-	struct iio_dev *indio_dev = dev_get_drvdata(dev);
 	struct sca3000_state *st = indio_dev->dev_data;
-	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
+	int num = IIO_EVENT_CODE_EXTRACT_MODIFIER(e);
 	int ret;
-	long val;
+	int i;
+	u8 nonlinear = 0;
+
+	if (num == 1) {
+		i = ARRAY_SIZE(st->info->mot_det_mult_y);
+		while (i > 0)
+			if (val >= st->info->mot_det_mult_y[--i]) {
+				nonlinear |= (1 << i);
+				val -= st->info->mot_det_mult_y[i];
+			}
+	} else {
+		i = ARRAY_SIZE(st->info->mot_det_mult_xz);
+		while (i > 0)
+			if (val >= st->info->mot_det_mult_xz[--i]) {
+				nonlinear |= (1 << i);
+				val -= st->info->mot_det_mult_xz[i];
+			}
+	}
 
-	ret = strict_strtol(buf, 10, &val);
-	if (ret)
-		return ret;
 	mutex_lock(&st->lock);
-	ret = sca3000_write_ctrl_reg(st, this_attr->address, val);
+	ret = sca3000_write_ctrl_reg(st, sca3000_addresses[num][1], nonlinear);
 	mutex_unlock(&st->lock);
 
-	return ret ? ret : len;
+	return ret;
 }
 
-static IIO_DEVICE_ATTR(accel_x_raw_mag_rising_value,
-		S_IRUGO | S_IWUSR,
-		sca3000_show_thresh,
-		sca3000_write_thresh,
-		SCA3000_REG_CTRL_SEL_MD_X_TH);
-
-static IIO_DEVICE_ATTR(accel_y_raw_mag_rising_value,
-		S_IRUGO | S_IWUSR,
-		sca3000_show_thresh,
-		sca3000_write_thresh,
-		SCA3000_REG_CTRL_SEL_MD_Y_TH);
-
-static IIO_DEVICE_ATTR(accel_z_raw_mag_rising_value,
-		S_IRUGO | S_IWUSR,
-		sca3000_show_thresh,
-		sca3000_write_thresh,
-		SCA3000_REG_CTRL_SEL_MD_Z_TH);
-
 static struct attribute *sca3000_attributes[] = {
-	&iio_dev_attr_name.dev_attr.attr,
 	&iio_dev_attr_revision.dev_attr.attr,
-	&iio_dev_attr_accel_scale.dev_attr.attr,
-	&iio_dev_attr_accel_x_raw.dev_attr.attr,
-	&iio_dev_attr_accel_y_raw.dev_attr.attr,
-	&iio_dev_attr_accel_z_raw.dev_attr.attr,
 	&iio_dev_attr_measurement_mode_available.dev_attr.attr,
 	&iio_dev_attr_measurement_mode.dev_attr.attr,
 	&iio_dev_attr_sampling_frequency_available.dev_attr.attr,
@@ -807,12 +765,7 @@
 };
 
 static struct attribute *sca3000_attributes_with_temp[] = {
-	&iio_dev_attr_name.dev_attr.attr,
 	&iio_dev_attr_revision.dev_attr.attr,
-	&iio_dev_attr_accel_scale.dev_attr.attr,
-	&iio_dev_attr_accel_x_raw.dev_attr.attr,
-	&iio_dev_attr_accel_y_raw.dev_attr.attr,
-	&iio_dev_attr_accel_z_raw.dev_attr.attr,
 	&iio_dev_attr_measurement_mode_available.dev_attr.attr,
 	&iio_dev_attr_measurement_mode.dev_attr.attr,
 	&iio_dev_attr_sampling_frequency_available.dev_attr.attr,
@@ -836,134 +789,102 @@
 /* depending on event, push to the ring buffer event chrdev or the event one */
 
 /**
- * sca3000_interrupt_handler_bh() - handling ring and non ring events
+ * sca3000_event_handler() - handling ring and non ring events
  *
  * This function is complicated by the fact that the devices can signify ring
  * and non ring events via the same interrupt line and they can only
  * be distinguished via a read of the relevant status register.
  **/
-static void sca3000_interrupt_handler_bh(struct work_struct *work_s)
+static irqreturn_t sca3000_event_handler(int irq, void *private)
 {
-	struct sca3000_state *st
-		= container_of(work_s, struct sca3000_state,
-			       interrupt_handler_ws);
-	u8 *rx;
-	int ret;
+	struct iio_dev *indio_dev = private;
+	struct sca3000_state *st;
+	int ret, val;
+	s64 last_timestamp = iio_get_time_ns();
 
+	st = indio_dev->dev_data;
 	/* Could lead if badly timed to an extra read of status reg,
 	 * but ensures no interrupt is missed.
 	 */
-	enable_irq(st->us->irq);
 	mutex_lock(&st->lock);
-	ret = sca3000_read_data(st, SCA3000_REG_ADDR_INT_STATUS,
-				&rx, 1);
+	ret = sca3000_read_data_short(st, SCA3000_REG_ADDR_INT_STATUS, 1);
+	val = st->rx[0];
 	mutex_unlock(&st->lock);
 	if (ret)
 		goto done;
 
-	sca3000_ring_int_process(rx[1], st->indio_dev->ring);
+	sca3000_ring_int_process(val, st->indio_dev->ring);
 
-	if (rx[1] & SCA3000_INT_STATUS_FREE_FALL)
+	if (val & SCA3000_INT_STATUS_FREE_FALL)
 		iio_push_event(st->indio_dev, 0,
 			       IIO_MOD_EVENT_CODE(IIO_EV_CLASS_ACCEL,
 						  0,
 						  IIO_EV_MOD_X_AND_Y_AND_Z,
 						  IIO_EV_TYPE_MAG,
 						  IIO_EV_DIR_FALLING),
-			       st->last_timestamp);
+			       last_timestamp);
 
-	if (rx[1] & SCA3000_INT_STATUS_Y_TRIGGER)
+	if (val & SCA3000_INT_STATUS_Y_TRIGGER)
 		iio_push_event(st->indio_dev, 0,
 			       IIO_MOD_EVENT_CODE(IIO_EV_CLASS_ACCEL,
 						  0,
 						  IIO_EV_MOD_Y,
 						  IIO_EV_TYPE_MAG,
 						  IIO_EV_DIR_RISING),
-			       st->last_timestamp);
+			       last_timestamp);
 
-	if (rx[1] & SCA3000_INT_STATUS_X_TRIGGER)
+	if (val & SCA3000_INT_STATUS_X_TRIGGER)
 		iio_push_event(st->indio_dev, 0,
 			       IIO_MOD_EVENT_CODE(IIO_EV_CLASS_ACCEL,
 						  0,
 						  IIO_EV_MOD_X,
 						  IIO_EV_TYPE_MAG,
 						  IIO_EV_DIR_RISING),
-			       st->last_timestamp);
+			       last_timestamp);
 
-	if (rx[1] & SCA3000_INT_STATUS_Z_TRIGGER)
+	if (val & SCA3000_INT_STATUS_Z_TRIGGER)
 		iio_push_event(st->indio_dev, 0,
 			       IIO_MOD_EVENT_CODE(IIO_EV_CLASS_ACCEL,
 						  0,
 						  IIO_EV_MOD_Z,
 						  IIO_EV_TYPE_MAG,
 						  IIO_EV_DIR_RISING),
-			       st->last_timestamp);
+			       last_timestamp);
 
 done:
-	kfree(rx);
-	return;
-}
-
-/**
- * sca3000_handler_th() handles all interrupt events from device
- *
- * These devices deploy unified interrupt status registers meaning
- * all interrupts must be handled together
- **/
-static int sca3000_handler_th(struct iio_dev *dev_info,
-			      int index,
-			      s64 timestamp,
-			      int no_test)
-{
-	struct sca3000_state *st = dev_info->dev_data;
-
-	st->last_timestamp = timestamp;
-	schedule_work(&st->interrupt_handler_ws);
-
-	return 0;
+	return IRQ_HANDLED;
 }
 
 /**
- * sca3000_query_mo_det() is motion detection enabled for this axis
- *
- * First queries if motion detection is enabled and then if this axis is
- * on.
+ * sca3000_read_event_config() what events are enabled
  **/
-static ssize_t sca3000_query_mo_det(struct device *dev,
-				    struct device_attribute *attr,
-				    char *buf)
+static int sca3000_read_event_config(struct iio_dev *indio_dev,
+				     int e)
 {
-	struct iio_dev *indio_dev = dev_get_drvdata(dev->parent);
 	struct sca3000_state *st = indio_dev->dev_data;
-	struct iio_event_attr *this_attr = to_iio_event_attr(attr);
-	int ret, len = 0;
-	u8 *rx;
+	int ret;
 	u8 protect_mask = 0x03;
+	int num = IIO_EVENT_CODE_EXTRACT_MODIFIER(e);
 
 	/* read current value of mode register */
 	mutex_lock(&st->lock);
-	ret = sca3000_read_data(st, SCA3000_REG_ADDR_MODE, &rx, 1);
+	ret = sca3000_read_data_short(st, SCA3000_REG_ADDR_MODE, 1);
 	if (ret)
 		goto error_ret;
 
-	if ((rx[1]&protect_mask) != SCA3000_MEAS_MODE_MOT_DET)
-		len += sprintf(buf + len, "0\n");
+	if ((st->rx[0] & protect_mask) != SCA3000_MEAS_MODE_MOT_DET)
+		ret = 0;
 	else {
-		kfree(rx);
-		ret = sca3000_read_ctrl_reg(st,
-					    SCA3000_REG_CTRL_SEL_MD_CTRL,
-					    &rx);
-		if (ret)
+		ret = sca3000_read_ctrl_reg(st, SCA3000_REG_CTRL_SEL_MD_CTRL);
+		if (ret < 0)
 			goto error_ret;
 		/* only supporting logical or's for now */
-		len += sprintf(buf + len, "%d\n",
-			       (rx[1] & this_attr->mask) ? 1 : 0);
+		ret = !!(ret & sca3000_addresses[num][2]);
 	}
-	kfree(rx);
 error_ret:
 	mutex_unlock(&st->lock);
 
-	return ret ? ret : len;
+	return ret;
 }
 /**
  * sca3000_query_free_fall_mode() is free fall mode enabled
@@ -973,80 +894,20 @@
 					    char *buf)
 {
 	int ret, len;
-	u8 *rx;
 	struct iio_dev *indio_dev = dev_get_drvdata(dev);
 	struct sca3000_state *st = indio_dev->dev_data;
+	int val;
 
 	mutex_lock(&st->lock);
-	ret = sca3000_read_data(st, SCA3000_REG_ADDR_MODE, &rx, 1);
+	ret = sca3000_read_data_short(st, SCA3000_REG_ADDR_MODE, 1);
+	val = st->rx[0];
 	mutex_unlock(&st->lock);
-	if (ret)
+	if (ret < 0)
 		return ret;
 	len = sprintf(buf, "%d\n",
-		      !!(rx[1] & SCA3000_FREE_FALL_DETECT));
-	kfree(rx);
-
-	return len;
-}
-/**
- * sca3000_query_ring_int() is the hardware ring status interrupt enabled
- **/
-static ssize_t sca3000_query_ring_int(struct device *dev,
-				      struct device_attribute *attr,
-				      char *buf)
-{
-	struct iio_event_attr *this_attr = to_iio_event_attr(attr);
-	int ret, len;
-	u8 *rx;
-	struct iio_dev *indio_dev = dev_get_drvdata(dev->parent);
-	struct sca3000_state *st = indio_dev->dev_data;
-	mutex_lock(&st->lock);
-	ret = sca3000_read_data(st, SCA3000_REG_ADDR_INT_MASK, &rx, 1);
-	mutex_unlock(&st->lock);
-	if (ret)
-		return ret;
-	len = sprintf(buf, "%d\n", (rx[1] & this_attr->mask) ? 1 : 0);
-	kfree(rx);
-
+		      !!(val & SCA3000_FREE_FALL_DETECT));
 	return len;
 }
-/**
- * sca3000_set_ring_int() set state of ring status interrupt
- **/
-static ssize_t sca3000_set_ring_int(struct device *dev,
-				      struct device_attribute *attr,
-				      const char *buf,
-				      size_t len)
-{
-	struct iio_dev *indio_dev = dev_get_drvdata(dev->parent);
-	struct sca3000_state *st = indio_dev->dev_data;
-	struct iio_event_attr *this_attr = to_iio_event_attr(attr);
-
-	long val;
-	int ret;
-	u8 *rx;
-
-	mutex_lock(&st->lock);
-	ret = strict_strtol(buf, 10, &val);
-	if (ret)
-		goto error_ret;
-	ret = sca3000_read_data(st, SCA3000_REG_ADDR_INT_MASK, &rx, 1);
-	if (ret)
-		goto error_ret;
-	if (val)
-		ret = sca3000_write_reg(st,
-					SCA3000_REG_ADDR_INT_MASK,
-					rx[1] | this_attr->mask);
-	else
-		ret = sca3000_write_reg(st,
-					SCA3000_REG_ADDR_INT_MASK,
-					rx[1] & ~this_attr->mask);
-	kfree(rx);
-error_ret:
-	mutex_unlock(&st->lock);
-
-	return ret ? ret : len;
-}
 
 /**
  * sca3000_set_free_fall_mode() simple on off control for free fall int
@@ -1065,7 +926,6 @@
 	struct sca3000_state *st = indio_dev->dev_data;
 	long val;
 	int ret;
-	u8 *rx;
 	u8 protect_mask = SCA3000_FREE_FALL_DETECT;
 
 	mutex_lock(&st->lock);
@@ -1074,20 +934,18 @@
 		goto error_ret;
 
 	/* read current value of mode register */
-	ret = sca3000_read_data(st, SCA3000_REG_ADDR_MODE, &rx, 1);
+	ret = sca3000_read_data_short(st, SCA3000_REG_ADDR_MODE, 1);
 	if (ret)
 		goto error_ret;
 
 	/*if off and should be on*/
-	if (val && !(rx[1] & protect_mask))
+	if (val && !(st->rx[0] & protect_mask))
 		ret = sca3000_write_reg(st, SCA3000_REG_ADDR_MODE,
-					(rx[1] | SCA3000_FREE_FALL_DETECT));
+					(st->rx[0] | SCA3000_FREE_FALL_DETECT));
 	/* if on and should be off */
-	else if (!val && (rx[1]&protect_mask))
+	else if (!val && (st->rx[0] & protect_mask))
 		ret = sca3000_write_reg(st, SCA3000_REG_ADDR_MODE,
-					(rx[1] & ~protect_mask));
-
-	kfree(rx);
+					(st->rx[0] & ~protect_mask));
 error_ret:
 	mutex_unlock(&st->lock);
 
@@ -1103,127 +961,77 @@
  * There is a complexity in knowing which mode to return to when
  * this mode is disabled.  Currently normal mode is assumed.
  **/
-static ssize_t sca3000_set_mo_det(struct device *dev,
-				  struct device_attribute *attr,
-				  const char *buf,
-				  size_t len)
+static int sca3000_write_event_config(struct iio_dev *indio_dev,
+				      int e,
+				      int state)
 {
-	struct iio_dev *indio_dev = dev_get_drvdata(dev->parent);
 	struct sca3000_state *st = indio_dev->dev_data;
-	struct iio_event_attr *this_attr = to_iio_event_attr(attr);
-	long val;
-	int ret;
-	u8 *rx;
+	int ret, ctrlval;
 	u8 protect_mask = 0x03;
-	ret = strict_strtol(buf, 10, &val);
-	if (ret)
-		return ret;
+	int num = IIO_EVENT_CODE_EXTRACT_MODIFIER(e);
 
 	mutex_lock(&st->lock);
 	/* First read the motion detector config to find out if
 	 * this axis is on*/
-	ret = sca3000_read_ctrl_reg(st,
-				    SCA3000_REG_CTRL_SEL_MD_CTRL,
-				    &rx);
-	if (ret)
+	ret = sca3000_read_ctrl_reg(st, SCA3000_REG_CTRL_SEL_MD_CTRL);
+	if (ret < 0)
 		goto exit_point;
+	ctrlval = ret;
 	/* Off and should be on */
-	if (val && !(rx[1] & this_attr->mask)) {
+	if (state && !(ctrlval & sca3000_addresses[num][2])) {
 		ret = sca3000_write_ctrl_reg(st,
 					     SCA3000_REG_CTRL_SEL_MD_CTRL,
-					     rx[1] | this_attr->mask);
+					     ctrlval |
+					     sca3000_addresses[num][2]);
 		if (ret)
-			goto exit_point_free_rx;
+			goto exit_point;
 		st->mo_det_use_count++;
-	} else if (!val && (rx[1]&this_attr->mask)) {
+	} else if (!state && (ctrlval & sca3000_addresses[num][2])) {
 		ret = sca3000_write_ctrl_reg(st,
 					     SCA3000_REG_CTRL_SEL_MD_CTRL,
-					     rx[1] & ~(this_attr->mask));
+					     ctrlval &
+					     ~(sca3000_addresses[num][2]));
 		if (ret)
-			goto exit_point_free_rx;
+			goto exit_point;
 		st->mo_det_use_count--;
-	} else /* relies on clean state for device on boot */
-		goto exit_point_free_rx;
-	kfree(rx);
+	}
+
 	/* read current value of mode register */
-	ret = sca3000_read_data(st, SCA3000_REG_ADDR_MODE, &rx, 1);
+	ret = sca3000_read_data_short(st, SCA3000_REG_ADDR_MODE, 1);
 	if (ret)
 		goto exit_point;
 	/*if off and should be on*/
 	if ((st->mo_det_use_count)
-	    && ((rx[1]&protect_mask) != SCA3000_MEAS_MODE_MOT_DET))
+	    && ((st->rx[0] & protect_mask) != SCA3000_MEAS_MODE_MOT_DET))
 		ret = sca3000_write_reg(st, SCA3000_REG_ADDR_MODE,
-					(rx[1] & ~protect_mask)
+					(st->rx[0] & ~protect_mask)
 					| SCA3000_MEAS_MODE_MOT_DET);
 	/* if on and should be off */
 	else if (!(st->mo_det_use_count)
-		 && ((rx[1]&protect_mask) == SCA3000_MEAS_MODE_MOT_DET))
+		 && ((st->rx[0] & protect_mask) == SCA3000_MEAS_MODE_MOT_DET))
 		ret = sca3000_write_reg(st, SCA3000_REG_ADDR_MODE,
-					(rx[1] & ~protect_mask));
-exit_point_free_rx:
-	kfree(rx);
+					(st->rx[0] & ~protect_mask));
 exit_point:
 	mutex_unlock(&st->lock);
 
-	return ret ? ret : len;
+	return ret;
 }
 
-/* Shared event handler for all events as single event status register */
-IIO_EVENT_SH(all, &sca3000_handler_th);
-
 /* Free fall detector related event attribute */
-IIO_EVENT_ATTR_NAMED_SH(accel_xayaz_mag_falling_en,
-			accel_x&y&z_mag_falling_en,
-			iio_event_all,
-			sca3000_query_free_fall_mode,
-			sca3000_set_free_fall_mode,
-			0);
-
-IIO_CONST_ATTR_NAMED(accel_xayaz_mag_falling_period,
-		     accel_x&y&z_mag_falling_period,
-		     "0.226");
-
-/* Motion detector related event attributes */
-IIO_EVENT_ATTR_SH(accel_x_mag_rising_en,
-		  iio_event_all,
-		  sca3000_query_mo_det,
-		  sca3000_set_mo_det,
-		  SCA3000_MD_CTRL_OR_X);
-
-IIO_EVENT_ATTR_SH(accel_y_mag_rising_en,
-		  iio_event_all,
-		  sca3000_query_mo_det,
-		  sca3000_set_mo_det,
-		  SCA3000_MD_CTRL_OR_Y);
-
-IIO_EVENT_ATTR_SH(accel_z_mag_rising_en,
-		  iio_event_all,
-		  sca3000_query_mo_det,
-		  sca3000_set_mo_det,
-		  SCA3000_MD_CTRL_OR_Z);
-
-/* Hardware ring buffer related event attributes */
-IIO_EVENT_ATTR_RING_50_FULL_SH(iio_event_all,
-			       sca3000_query_ring_int,
-			       sca3000_set_ring_int,
-			       SCA3000_INT_MASK_RING_HALF);
+static IIO_DEVICE_ATTR_NAMED(accel_xayaz_mag_falling_en,
+			     accel_x&y&z_mag_falling_en,
+			     S_IRUGO | S_IWUSR,
+			     sca3000_query_free_fall_mode,
+			     sca3000_set_free_fall_mode,
+			     0);
 
-IIO_EVENT_ATTR_RING_75_FULL_SH(iio_event_all,
-			       sca3000_query_ring_int,
-			       sca3000_set_ring_int,
-			       SCA3000_INT_MASK_RING_THREE_QUARTER);
+static IIO_CONST_ATTR_NAMED(accel_xayaz_mag_falling_period,
+			    accel_x&y&z_mag_falling_period,
+			    "0.226");
 
 static struct attribute *sca3000_event_attributes[] = {
-	&iio_event_attr_accel_xayaz_mag_falling_en.dev_attr.attr,
+	&iio_dev_attr_accel_xayaz_mag_falling_en.dev_attr.attr,
 	&iio_const_attr_accel_xayaz_mag_falling_period.dev_attr.attr,
-	&iio_event_attr_accel_x_mag_rising_en.dev_attr.attr,
-	&iio_dev_attr_accel_x_raw_mag_rising_value.dev_attr.attr,
-	&iio_event_attr_accel_y_mag_rising_en.dev_attr.attr,
-	&iio_dev_attr_accel_y_raw_mag_rising_value.dev_attr.attr,
-	&iio_event_attr_accel_z_mag_rising_en.dev_attr.attr,
-	&iio_dev_attr_accel_z_raw_mag_rising_value.dev_attr.attr,
-	&iio_event_attr_ring_50_full.dev_attr.attr,
-	&iio_event_attr_ring_75_full.dev_attr.attr,
 	NULL,
 };
 
@@ -1241,70 +1049,50 @@
 static int sca3000_clean_setup(struct sca3000_state *st)
 {
 	int ret;
-	u8 *rx;
 
 	mutex_lock(&st->lock);
 	/* Ensure all interrupts have been acknowledged */
-	ret = sca3000_read_data(st, SCA3000_REG_ADDR_INT_STATUS, &rx, 1);
+	ret = sca3000_read_data_short(st, SCA3000_REG_ADDR_INT_STATUS, 1);
 	if (ret)
 		goto error_ret;
-	kfree(rx);
 
 	/* Turn off all motion detection channels */
-	ret = sca3000_read_ctrl_reg(st,
-				    SCA3000_REG_CTRL_SEL_MD_CTRL,
-				    &rx);
-	if (ret)
+	ret = sca3000_read_ctrl_reg(st, SCA3000_REG_CTRL_SEL_MD_CTRL);
+	if (ret < 0)
 		goto error_ret;
-	ret = sca3000_write_ctrl_reg(st,
-				     SCA3000_REG_CTRL_SEL_MD_CTRL,
-				     rx[1] & SCA3000_MD_CTRL_PROT_MASK);
-	kfree(rx);
+	ret = sca3000_write_ctrl_reg(st, SCA3000_REG_CTRL_SEL_MD_CTRL,
+				     ret & SCA3000_MD_CTRL_PROT_MASK);
 	if (ret)
 		goto error_ret;
 
 	/* Disable ring buffer */
-	sca3000_read_ctrl_reg(st,
-			      SCA3000_REG_CTRL_SEL_OUT_CTRL,
-			      &rx);
-	/* Frequency of ring buffer sampling deliberately restricted to make
-	 * debugging easier - add control of this later */
-	ret = sca3000_write_ctrl_reg(st,
-				     SCA3000_REG_CTRL_SEL_OUT_CTRL,
-				     (rx[1] & SCA3000_OUT_CTRL_PROT_MASK)
+	ret = sca3000_read_ctrl_reg(st, SCA3000_REG_CTRL_SEL_OUT_CTRL);
+	ret = sca3000_write_ctrl_reg(st, SCA3000_REG_CTRL_SEL_OUT_CTRL,
+				     (ret & SCA3000_OUT_CTRL_PROT_MASK)
 				     | SCA3000_OUT_CTRL_BUF_X_EN
 				     | SCA3000_OUT_CTRL_BUF_Y_EN
 				     | SCA3000_OUT_CTRL_BUF_Z_EN
 				     | SCA3000_OUT_CTRL_BUF_DIV_4);
-	kfree(rx);
-
 	if (ret)
 		goto error_ret;
 	/* Enable interrupts, relevant to mode and set up as active low */
-	ret = sca3000_read_data(st,
-			  SCA3000_REG_ADDR_INT_MASK,
-			  &rx, 1);
+	ret = sca3000_read_data_short(st, SCA3000_REG_ADDR_INT_MASK, 1);
 	if (ret)
 		goto error_ret;
 	ret = sca3000_write_reg(st,
 				SCA3000_REG_ADDR_INT_MASK,
-				(rx[1] & SCA3000_INT_MASK_PROT_MASK)
+				(ret & SCA3000_INT_MASK_PROT_MASK)
 				| SCA3000_INT_MASK_ACTIVE_LOW);
-	kfree(rx);
 	if (ret)
 		goto error_ret;
 	/* Select normal measurement mode, free fall off, ring off */
 	/* Ring in 12 bit mode - it is fine to overwrite reserved bits 3,5
 	 * as that occurs in one of the example on the datasheet */
-	ret = sca3000_read_data(st,
-			  SCA3000_REG_ADDR_MODE,
-			  &rx, 1);
+	ret = sca3000_read_data_short(st, SCA3000_REG_ADDR_MODE, 1);
 	if (ret)
 		goto error_ret;
-	ret = sca3000_write_reg(st,
-				SCA3000_REG_ADDR_MODE,
-				(rx[1] & SCA3000_MODE_PROT_MASK));
-	kfree(rx);
+	ret = sca3000_write_reg(st, SCA3000_REG_ADDR_MODE,
+				(st->rx[0] & SCA3000_MODE_PROT_MASK));
 	st->bpse = 11;
 
 error_ret:
@@ -1312,8 +1100,29 @@
 	return ret;
 }
 
-static int __devinit __sca3000_probe(struct spi_device *spi,
-				     enum sca3000_variant variant)
+static const struct iio_info sca3000_info = {
+	.attrs = &sca3000_attribute_group,
+	.read_raw = &sca3000_read_raw,
+	.num_interrupt_lines = 1,
+	.event_attrs = &sca3000_event_attribute_group,
+	.read_event_value = &sca3000_read_thresh,
+	.write_event_value = &sca3000_write_thresh,
+	.read_event_config = &sca3000_read_event_config,
+	.write_event_config = &sca3000_write_event_config,
+	.driver_module = THIS_MODULE,
+};
+
+static const struct iio_info sca3000_info_with_temp = {
+	.attrs = &sca3000_attribute_group_with_temp,
+	.read_raw = &sca3000_read_raw,
+	.read_event_value = &sca3000_read_thresh,
+	.write_event_value = &sca3000_write_thresh,
+	.read_event_config = &sca3000_read_event_config,
+	.write_event_config = &sca3000_write_event_config,
+	.driver_module = THIS_MODULE,
+};
+
+static int __devinit sca3000_probe(struct spi_device *spi)
 {
 	int ret, regdone = 0;
 	struct sca3000_state *st;
@@ -1325,75 +1134,57 @@
 	}
 	spi_set_drvdata(spi, st);
 
-	st->tx = kmalloc(sizeof(*st->tx)*6, GFP_KERNEL);
-	if (st->tx == NULL) {
-		ret = -ENOMEM;
-		goto error_clear_st;
-	}
-	st->rx = kmalloc(sizeof(*st->rx)*3, GFP_KERNEL);
-	if (st->rx == NULL) {
-		ret = -ENOMEM;
-		goto error_free_tx;
-	}
 	st->us = spi;
 	mutex_init(&st->lock);
-	st->info = &sca3000_spi_chip_info_tbl[variant];
+	st->info = &sca3000_spi_chip_info_tbl[spi_get_device_id(spi)
+					      ->driver_data];
 
-	st->indio_dev = iio_allocate_device();
+	st->indio_dev = iio_allocate_device(0);
 	if (st->indio_dev == NULL) {
 		ret = -ENOMEM;
-		goto error_free_rx;
+		goto error_clear_st;
 	}
-
 	st->indio_dev->dev.parent = &spi->dev;
-	st->indio_dev->num_interrupt_lines = 1;
-	st->indio_dev->event_attrs = &sca3000_event_attribute_group;
+	st->indio_dev->name = spi_get_device_id(spi)->name;
 	if (st->info->temp_output)
-		st->indio_dev->attrs = &sca3000_attribute_group_with_temp;
-	else
-		st->indio_dev->attrs = &sca3000_attribute_group;
+		st->indio_dev->info = &sca3000_info_with_temp;
+	else {
+		st->indio_dev->info = &sca3000_info;
+		st->indio_dev->channels = sca3000_channels;
+		st->indio_dev->num_channels = ARRAY_SIZE(sca3000_channels);
+	}
 	st->indio_dev->dev_data = (void *)(st);
 	st->indio_dev->modes = INDIO_DIRECT_MODE;
 
 	sca3000_configure_ring(st->indio_dev);
-
 	ret = iio_device_register(st->indio_dev);
 	if (ret < 0)
 		goto error_free_dev;
 	regdone = 1;
-	ret = iio_ring_buffer_register(st->indio_dev->ring, 0);
+	ret = iio_ring_buffer_register_ex(st->indio_dev->ring, 0,
+					  sca3000_channels,
+					  ARRAY_SIZE(sca3000_channels));
 	if (ret < 0)
 		goto error_unregister_dev;
 	if (spi->irq && gpio_is_valid(irq_to_gpio(spi->irq)) > 0) {
-		INIT_WORK(&st->interrupt_handler_ws,
-			  sca3000_interrupt_handler_bh);
-		ret = iio_register_interrupt_line(spi->irq,
-						  st->indio_dev,
-						  0,
-						  IRQF_TRIGGER_FALLING,
-						  "sca3000");
+		ret = request_threaded_irq(spi->irq,
+					   NULL,
+					   &sca3000_event_handler,
+					   IRQF_TRIGGER_FALLING,
+					   "sca3000",
+					   st->indio_dev);
 		if (ret)
 			goto error_unregister_ring;
-		/* RFC
-		 * Probably a common situation.  All interrupts need an ack
-		 * and there is only one handler so the complicated list system
-		 * is overkill.  At very least a simpler registration method
-		 * might be worthwhile.
-		 */
-		iio_add_event_to_list(
-			iio_event_attr_accel_z_mag_rising_en.listel,
-			&st->indio_dev
-			->interrupts[0]->ev_list);
 	}
 	sca3000_register_ring_funcs(st->indio_dev);
 	ret = sca3000_clean_setup(st);
 	if (ret)
-		goto error_unregister_interrupt_line;
+		goto error_free_irq;
 	return 0;
 
-error_unregister_interrupt_line:
+error_free_irq:
 	if (spi->irq && gpio_is_valid(irq_to_gpio(spi->irq)) > 0)
-		iio_unregister_interrupt_line(st->indio_dev, 0);
+		free_irq(spi->irq, st->indio_dev);
 error_unregister_ring:
 	iio_ring_buffer_unregister(st->indio_dev->ring);
 error_unregister_dev:
@@ -1402,10 +1193,6 @@
 		iio_device_unregister(st->indio_dev);
 	else
 		iio_free_device(st->indio_dev);
-error_free_rx:
-	kfree(st->rx);
-error_free_tx:
-	kfree(st->tx);
 error_clear_st:
 	kfree(st);
 error_ret:
@@ -1415,20 +1202,19 @@
 static int sca3000_stop_all_interrupts(struct sca3000_state *st)
 {
 	int ret;
-	u8 *rx;
 
 	mutex_lock(&st->lock);
-	ret = sca3000_read_data(st, SCA3000_REG_ADDR_INT_MASK, &rx, 1);
+	ret = sca3000_read_data_short(st, SCA3000_REG_ADDR_INT_MASK, 1);
 	if (ret)
 		goto error_ret;
 	ret = sca3000_write_reg(st, SCA3000_REG_ADDR_INT_MASK,
-				(rx[1] & ~(SCA3000_INT_MASK_RING_THREE_QUARTER
-					   | SCA3000_INT_MASK_RING_HALF
-					   | SCA3000_INT_MASK_ALL_INTS)));
+				(st->rx[0] &
+				 ~(SCA3000_INT_MASK_RING_THREE_QUARTER |
+				   SCA3000_INT_MASK_RING_HALF |
+				   SCA3000_INT_MASK_ALL_INTS)));
 error_ret:
-	kfree(rx);
+	mutex_unlock(&st->lock);
 	return ret;
-
 }
 
 static int sca3000_remove(struct spi_device *spi)
@@ -1441,87 +1227,44 @@
 	if (ret)
 		return ret;
 	if (spi->irq && gpio_is_valid(irq_to_gpio(spi->irq)) > 0)
-		iio_unregister_interrupt_line(indio_dev, 0);
+		free_irq(spi->irq, indio_dev);
 	iio_ring_buffer_unregister(indio_dev->ring);
 	sca3000_unconfigure_ring(indio_dev);
 	iio_device_unregister(indio_dev);
 
-	kfree(st->tx);
-	kfree(st->rx);
 	kfree(st);
 
 	return 0;
 }
 
-/* These macros save on an awful lot of repeated code */
-#define SCA3000_VARIANT_PROBE(_name)				\
-	static int __devinit					\
-	sca3000_##_name##_probe(struct spi_device *spi)		\
-	{							\
-		return __sca3000_probe(spi, _name);		\
-	}
-
-#define SCA3000_VARIANT_SPI_DRIVER(_name)			\
-	struct spi_driver sca3000_##_name##_driver = {		\
-		.driver = {					\
-			.name = "sca3000_" #_name,		\
-			.owner = THIS_MODULE,			\
-		},						\
-		.probe = sca3000_##_name##_probe,		\
-		.remove = __devexit_p(sca3000_remove),		\
-	}
-
-SCA3000_VARIANT_PROBE(d01);
-static SCA3000_VARIANT_SPI_DRIVER(d01);
-
-SCA3000_VARIANT_PROBE(e02);
-static SCA3000_VARIANT_SPI_DRIVER(e02);
-
-SCA3000_VARIANT_PROBE(e04);
-static SCA3000_VARIANT_SPI_DRIVER(e04);
+static const struct spi_device_id sca3000_id[] = {
+	{"sca3000_d01", d01},
+	{"sca3000_e02", e02},
+	{"sca3000_e04", e04},
+	{"sca3000_e05", e05},
+	{}
+};
 
-SCA3000_VARIANT_PROBE(e05);
-static SCA3000_VARIANT_SPI_DRIVER(e05);
+static struct spi_driver sca3000_driver = {
+	.driver = {
+		.name = "sca3000",
+		.owner = THIS_MODULE,
+	},
+	.probe = sca3000_probe,
+	.remove = __devexit_p(sca3000_remove),
+	.id_table = sca3000_id,
+};
 
 static __init int sca3000_init(void)
 {
-	int ret;
-
-	ret = spi_register_driver(&sca3000_d01_driver);
-	if (ret)
-		goto error_ret;
-	ret = spi_register_driver(&sca3000_e02_driver);
-	if (ret)
-		goto error_unreg_d01;
-	ret = spi_register_driver(&sca3000_e04_driver);
-	if (ret)
-		goto error_unreg_e02;
-	ret = spi_register_driver(&sca3000_e05_driver);
-	if (ret)
-		goto error_unreg_e04;
-
-	return 0;
-
-error_unreg_e04:
-	spi_unregister_driver(&sca3000_e04_driver);
-error_unreg_e02:
-	spi_unregister_driver(&sca3000_e02_driver);
-error_unreg_d01:
-	spi_unregister_driver(&sca3000_d01_driver);
-error_ret:
-
-	return ret;
+	return spi_register_driver(&sca3000_driver);
 }
+module_init(sca3000_init);
 
 static __exit void sca3000_exit(void)
 {
-	spi_unregister_driver(&sca3000_e05_driver);
-	spi_unregister_driver(&sca3000_e04_driver);
-	spi_unregister_driver(&sca3000_e02_driver);
-	spi_unregister_driver(&sca3000_d01_driver);
+	spi_unregister_driver(&sca3000_driver);
 }
-
-module_init(sca3000_init);
 module_exit(sca3000_exit);
 
 MODULE_AUTHOR("Jonathan Cameron <jic23@cam.ac.uk>");
diff -druN linux-2.6.39-libre/drivers/staging/iio/accel/sca3000.h linux-3.0-rc7-libre/drivers/staging/iio/accel/sca3000.h
--- linux-2.6.39-libre/drivers/staging/iio/accel/sca3000.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/iio/accel/sca3000.h	2011-07-11 19:51:52.000000000 -0400
@@ -158,17 +158,17 @@
 
 /**
  * struct sca3000_state - device instance state information
- * @us: 	 		the associated spi device
- * @info: 	  		chip variant information
- * @indio_dev: 	 		device information used by the IIO core
- * @interrupt_handler_ws: 	event interrupt handler for all events
- * @last_timestamp: 		the timestamp of the last event
- * @mo_det_use_count: 		reference counter for the motion detection unit
- * @lock: 		 	lock used to protect elements of sca3000_state
- * 	 			and the underlying device state.
- * @bpse: 		 	number of bits per scan element
- * @tx: 		 	dma-able transmit buffer
- * @rx: 		 	dma-able receive buffer
+ * @us:			the associated spi device
+ * @info:			chip variant information
+ * @indio_dev:			device information used by the IIO core
+ * @interrupt_handler_ws:	event interrupt handler for all events
+ * @last_timestamp:		the timestamp of the last event
+ * @mo_det_use_count:		reference counter for the motion detection unit
+ * @lock:			lock used to protect elements of sca3000_state
+ *				and the underlying device state.
+ * @bpse:			number of bits per scan element
+ * @tx:			dma-able transmit buffer
+ * @rx:			dma-able receive buffer
  **/
 struct sca3000_state {
 	struct spi_device		*us;
@@ -179,15 +179,14 @@
 	int				mo_det_use_count;
 	struct mutex			lock;
 	int				bpse;
-	u8				*tx;
-	/* not used during a ring buffer read */
-	u8				*rx;
+	/* Can these share a cacheline ? */
+	u8				rx[2] ____cacheline_aligned;
+	u8				tx[6] ____cacheline_aligned;
 };
 
 /**
  * struct sca3000_chip_info - model dependent parameters
- * @name: 			model identification
- * @scale:			string containing floating point scale factor
+ * @scale:			scale * 10^-6
  * @temp_output:		some devices have temperature sensors.
  * @measurement_mode_freq:	normal mode sampling frequency
  * @option_mode_1:		first optional mode. Not all models have one
@@ -199,30 +198,20 @@
  * sca3000 variant.
  **/
 struct sca3000_chip_info {
-	const char		*name;
-	const char		*scale;
+	unsigned int		scale;
 	bool			temp_output;
 	int			measurement_mode_freq;
 	int			option_mode_1;
 	int			option_mode_1_freq;
 	int			option_mode_2;
 	int			option_mode_2_freq;
+	int			mot_det_mult_xz[6];
+	int			mot_det_mult_y[7];
 };
 
-/**
- * sca3000_read_data() read a series of values from the device
- * @dev:		device
- * @reg_address_high:	start address (decremented read)
- * @rx:			pointer where received data is placed. Callee
- *			responsible for freeing this.
- * @len:		number of bytes to read
- *
- * The main lock must be held.
- **/
-int sca3000_read_data(struct sca3000_state *st,
-		      u8 reg_address_high,
-		      u8 **rx_p,
-		      int len);
+int sca3000_read_data_short(struct sca3000_state *st,
+			    u8 reg_address_high,
+			    int len);
 
 /**
  * sca3000_write_reg() write a single register
@@ -233,29 +222,6 @@
  **/
 int sca3000_write_reg(struct sca3000_state *st, u8 address, u8 val);
 
-/* Conversion function for use with the ring buffer when in 11bit mode */
-static inline int sca3000_11bit_convert(uint8_t msb, uint8_t lsb)
-{
-	int16_t val;
-
-	val = ((lsb >> 3) & 0x1C) | (msb << 5);
-	val |= (val & (1 << 12)) ? 0xE000 : 0;
-
-	return val;
-}
-
-static inline int sca3000_13bit_convert(uint8_t msb, uint8_t lsb)
-{
-	s16 val;
-
-	val = ((lsb >> 3) & 0x1F) | (msb << 5);
-	/* sign fill */
-	val |= (val & (1 << 12)) ? 0xE000 : 0;
-
-	return val;
-}
-
-
 #ifdef CONFIG_IIO_RING_BUFFER
 /**
  * sca3000_register_ring_funcs() setup the ring state change functions
diff -druN linux-2.6.39-libre/drivers/staging/iio/accel/sca3000_ring.c linux-3.0-rc7-libre/drivers/staging/iio/accel/sca3000_ring.c
--- linux-2.6.39-libre/drivers/staging/iio/accel/sca3000_ring.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/iio/accel/sca3000_ring.c	2011-07-11 19:51:52.000000000 -0400
@@ -17,6 +17,8 @@
 #include <linux/kernel.h>
 #include <linux/spi/spi.h>
 #include <linux/sysfs.h>
+#include <linux/sched.h>
+#include <linux/poll.h>
 
 #include "../iio.h"
 #include "../sysfs.h"
@@ -34,26 +36,61 @@
  * Currently scan elements aren't configured so it doesn't matter.
  */
 
+static int sca3000_read_data(struct sca3000_state *st,
+			    uint8_t reg_address_high,
+			    u8 **rx_p,
+			    int len)
+{
+	int ret;
+	struct spi_message msg;
+	struct spi_transfer xfer[2] = {
+		{
+			.len = 1,
+			.tx_buf = st->tx,
+		}, {
+			.len = len,
+		}
+	};
+	*rx_p = kmalloc(len, GFP_KERNEL);
+	if (*rx_p == NULL) {
+		ret = -ENOMEM;
+		goto error_ret;
+	}
+	xfer[1].rx_buf = *rx_p;
+	st->tx[0] = SCA3000_READ_REG(reg_address_high);
+	spi_message_init(&msg);
+	spi_message_add_tail(&xfer[0], &msg);
+	spi_message_add_tail(&xfer[1], &msg);
+	ret = spi_sync(st->us, &msg);
+	if (ret) {
+		dev_err(get_device(&st->us->dev), "problem reading register");
+		goto error_free_rx;
+	}
+
+	return 0;
+error_free_rx:
+	kfree(*rx_p);
+error_ret:
+	return ret;
+}
+
 /**
- * sca3000_rip_hw_rb() - main ring access function, pulls data from ring
+ * sca3000_read_first_n_hw_rb() - main ring access, pulls data from ring
  * @r:			the ring
  * @count:		number of samples to try and pull
  * @data:		output the actual samples pulled from the hw ring
- * @dead_offset:	cheating a bit here: Set to 1 so as to allow for the
- *			leading byte used in bus comms.
  *
  * Currently does not provide timestamps.  As the hardware doesn't add them they
  * can only be inferred approximately from ring buffer events such as 50% full
  * and knowledge of when buffer was last emptied.  This is left to userspace.
  **/
-static int sca3000_rip_hw_rb(struct iio_ring_buffer *r,
-			     size_t count, u8 **data, int *dead_offset)
+static int sca3000_read_first_n_hw_rb(struct iio_ring_buffer *r,
+				      size_t count, char __user *buf)
 {
 	struct iio_hw_ring_buffer *hw_ring = iio_to_hw_ring_buf(r);
 	struct iio_dev *indio_dev = hw_ring->private;
 	struct sca3000_state *st = indio_dev->dev_data;
 	u8 *rx;
-	s16 *samples;
 	int ret, i, num_available, num_read = 0;
 	int bytes_per_sample = 1;
 
@@ -61,44 +98,38 @@
 		bytes_per_sample = 2;
 
 	mutex_lock(&st->lock);
-	/* Check how much data is available:
-	 * RFC: Implement an ioctl to not bother checking whether there
-	 * is enough data in the ring?  Afterall, if we are responding
-	 * to an interrupt we have a minimum content guaranteed so it
-	 * seems slight silly to waste time checking it is there.
-	 */
-	ret = sca3000_read_data(st,
-				SCA3000_REG_ADDR_BUF_COUNT,
-				&rx, 1);
+	if (count % bytes_per_sample) {
+		ret = -EINVAL;
+		goto error_ret;
+	}
+
+	ret = sca3000_read_data_short(st, SCA3000_REG_ADDR_BUF_COUNT, 1);
 	if (ret)
 		goto error_ret;
 	else
-		num_available = rx[1];
-	/* num_available is the total number of samples available
+		num_available = st->rx[0];
+	/*
+	 * num_available is the total number of samples available
 	 * i.e. number of time points * number of channels.
 	 */
-	kfree(rx);
 	if (count > num_available * bytes_per_sample)
 		num_read = num_available*bytes_per_sample;
 	else
-		num_read = count - (count % (bytes_per_sample));
+		num_read = count;
 
-	/* Avoid the read request byte */
-	*dead_offset = 1;
 	ret = sca3000_read_data(st,
 				SCA3000_REG_ADDR_RING_OUT,
-				data, num_read);
+				&rx, num_read);
+	if (ret)
+		goto error_ret;
 
-	/* Convert byte order and shift to default resolution */
-	if (st->bpse == 11) {
-		samples = (s16*)(*data+1);
-		for (i = 0; i < (num_read/2); i++) {
-			samples[i] = be16_to_cpup(
-					(__be16 *)&(samples[i]));
-			samples[i] >>= 3;
-		}
-	}
+	for (i = 0; i < num_read; i++)
+		*(((u16 *)rx) + i) = be16_to_cpup((u16 *)rx + i);
 
+	if (copy_to_user(buf, rx, num_read))
+		ret = -EFAULT;
+	kfree(rx);
+	r->stufftoread = 0;
 error_ret:
 	mutex_unlock(&st->lock);
 
@@ -127,6 +158,76 @@
 static IIO_RING_LENGTH_ATTR;
 
 /**
+ * sca3000_query_ring_int() is the hardware ring status interrupt enabled
+ **/
+static ssize_t sca3000_query_ring_int(struct device *dev,
+				      struct device_attribute *attr,
+				      char *buf)
+{
+	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
+	int ret, val;
+	struct iio_ring_buffer *ring = dev_get_drvdata(dev);
+	struct iio_dev *indio_dev = ring->indio_dev;
+	struct sca3000_state *st = indio_dev->dev_data;
+
+	mutex_lock(&st->lock);
+	ret = sca3000_read_data_short(st, SCA3000_REG_ADDR_INT_MASK, 1);
+	val = st->rx[0];
+	mutex_unlock(&st->lock);
+	if (ret)
+		return ret;
+
+	return sprintf(buf, "%d\n", !!(val & this_attr->address));
+}
+
+/**
+ * sca3000_set_ring_int() set state of ring status interrupt
+ **/
+static ssize_t sca3000_set_ring_int(struct device *dev,
+				      struct device_attribute *attr,
+				      const char *buf,
+				      size_t len)
+{
+	struct iio_ring_buffer *ring = dev_get_drvdata(dev);
+	struct iio_dev *indio_dev = ring->indio_dev;
+	struct sca3000_state *st = indio_dev->dev_data;
+	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
+	long val;
+	int ret;
+
+	mutex_lock(&st->lock);
+	ret = strict_strtol(buf, 10, &val);
+	if (ret)
+		goto error_ret;
+	ret = sca3000_read_data_short(st, SCA3000_REG_ADDR_INT_MASK, 1);
+	if (ret)
+		goto error_ret;
+	if (val)
+		ret = sca3000_write_reg(st,
+					SCA3000_REG_ADDR_INT_MASK,
+					st->rx[0] | this_attr->address);
+	else
+		ret = sca3000_write_reg(st,
+					SCA3000_REG_ADDR_INT_MASK,
+					st->rx[0] & ~this_attr->address);
+error_ret:
+	mutex_unlock(&st->lock);
+
+	return ret ? ret : len;
+}
+
+static IIO_DEVICE_ATTR(50_percent, S_IRUGO | S_IWUSR,
+		       sca3000_query_ring_int,
+		       sca3000_set_ring_int,
+		       SCA3000_INT_MASK_RING_HALF);
+
+static IIO_DEVICE_ATTR(75_percent, S_IRUGO | S_IWUSR,
+		       sca3000_query_ring_int,
+		       sca3000_set_ring_int,
+		       SCA3000_INT_MASK_RING_THREE_QUARTER);
+
+
+/**
  * sca3000_show_ring_bpse() -sysfs function to query bits per sample from ring
  * @dev: ring buffer device
  * @attr: this device attribute
@@ -137,20 +238,18 @@
 				      char *buf)
 {
 	int len = 0, ret;
-	u8 *rx;
 	struct iio_ring_buffer *ring = dev_get_drvdata(dev);
 	struct iio_dev *indio_dev = ring->indio_dev;
 	struct sca3000_state *st = indio_dev->dev_data;
 
 	mutex_lock(&st->lock);
-	ret = sca3000_read_data(st, SCA3000_REG_ADDR_MODE, &rx, 1);
+	ret = sca3000_read_data_short(st, SCA3000_REG_ADDR_MODE, 1);
 	if (ret)
 		goto error_ret;
-	if (rx[1] & SCA3000_RING_BUF_8BIT)
+	if (st->rx[0] & SCA3000_RING_BUF_8BIT)
 		len = sprintf(buf, "s8/8\n");
 	else
 		len = sprintf(buf, "s11/16\n");
-	kfree(rx);
 error_ret:
 	mutex_unlock(&st->lock);
 
@@ -173,20 +272,19 @@
 	struct iio_dev *indio_dev = ring->indio_dev;
 	struct sca3000_state *st = indio_dev->dev_data;
 	int ret;
-	u8 *rx;
 
 	mutex_lock(&st->lock);
 
-	ret = sca3000_read_data(st, SCA3000_REG_ADDR_MODE, &rx, 1);
+	ret = sca3000_read_data_short(st, SCA3000_REG_ADDR_MODE, 1);
 	if (ret)
 		goto error_ret;
-	if (strncmp(buf, "s8/8", 4) == 0) {
+	if (sysfs_streq(buf, "s8/8")) {
 		ret = sca3000_write_reg(st, SCA3000_REG_ADDR_MODE,
-					rx[1] | SCA3000_RING_BUF_8BIT);
+					st->rx[0] | SCA3000_RING_BUF_8BIT);
 		st->bpse = 8;
-	} else if (strncmp(buf, "s11/16", 5) == 0) {
+	} else if (sysfs_streq(buf, "s11/16")) {
 		ret = sca3000_write_reg(st, SCA3000_REG_ADDR_MODE,
-					rx[1] & ~SCA3000_RING_BUF_8BIT);
+					st->rx[0] & ~SCA3000_RING_BUF_8BIT);
 		st->bpse = 11;
 	} else
 		ret = -EINVAL;
@@ -196,32 +294,22 @@
 	return ret ? ret : len;
 }
 
-static IIO_SCAN_EL_C(accel_x, 0, 0, NULL);
-static IIO_SCAN_EL_C(accel_y, 1, 0, NULL);
-static IIO_SCAN_EL_C(accel_z, 2, 0, NULL);
-static IIO_CONST_ATTR(accel_type_available, "s8/8 s11/16");
-static IIO_DEVICE_ATTR(accel_type,
-		       S_IRUGO | S_IWUSR,
-		       sca3000_show_ring_bpse,
-		       sca3000_store_ring_bpse,
-		       0);
+static ssize_t sca3000_show_buffer_scale(struct device *dev,
+					 struct device_attribute *attr,
+					 char *buf)
+{
+	struct iio_ring_buffer *ring = dev_get_drvdata(dev);
+	struct iio_dev *indio_dev = ring->indio_dev;
+	struct sca3000_state *st = indio_dev->dev_data;
 
-static struct attribute *sca3000_scan_el_attrs[] = {
-	&iio_scan_el_accel_x.dev_attr.attr,
-	&iio_const_attr_accel_x_index.dev_attr.attr,
-	&iio_scan_el_accel_y.dev_attr.attr,
-	&iio_const_attr_accel_y_index.dev_attr.attr,
-	&iio_scan_el_accel_z.dev_attr.attr,
-	&iio_const_attr_accel_z_index.dev_attr.attr,
-	&iio_const_attr_accel_type_available.dev_attr.attr,
-	&iio_dev_attr_accel_type.dev_attr.attr,
-	NULL
-};
+	return sprintf(buf, "0.%06d\n", 4*st->info->scale);
+}
 
-static struct attribute_group sca3000_scan_el_group = {
-	.attrs = sca3000_scan_el_attrs,
-	.name = "scan_elements",
-};
+static IIO_DEVICE_ATTR(accel_scale,
+		       S_IRUGO,
+		       sca3000_show_buffer_scale,
+		       NULL,
+		       0);
 
 /*
  * Ring buffer attributes
@@ -233,6 +321,9 @@
 	&dev_attr_length.attr,
 	&dev_attr_bytes_per_datum.attr,
 	&dev_attr_enable.attr,
+	&iio_dev_attr_50_percent.dev_attr.attr,
+	&iio_dev_attr_75_percent.dev_attr.attr,
+	&iio_dev_attr_accel_scale.dev_attr.attr,
 	NULL,
 };
 
@@ -258,11 +349,12 @@
 	ring = kzalloc(sizeof *ring, GFP_KERNEL);
 	if (!ring)
 		return NULL;
+
 	ring->private = indio_dev;
 	buf = &ring->buf;
+	buf->stufftoread = 0;
 	iio_ring_buffer_init(buf, indio_dev);
 	buf->dev.type = &sca3000_ring_type;
-	device_initialize(&buf->dev);
 	buf->dev.parent = &indio_dev->dev;
 	dev_set_drvdata(&buf->dev, (void *)buf);
 
@@ -275,6 +367,12 @@
 		iio_put_ring_buffer(r);
 }
 
+static const struct iio_ring_access_funcs sca3000_ring_access_funcs = {
+	.read_first_n = &sca3000_read_first_n_hw_rb,
+	.get_length = &sca3000_ring_get_length,
+	.get_bytes_per_datum = &sca3000_ring_get_bytes_per_datum,
+};
+
 int sca3000_configure_ring(struct iio_dev *indio_dev)
 {
 	indio_dev->ring = sca3000_rb_allocate(indio_dev);
@@ -282,10 +380,11 @@
 		return -ENOMEM;
 	indio_dev->modes |= INDIO_RING_HARDWARE_BUFFER;
 
-	indio_dev->ring->scan_el_attrs = &sca3000_scan_el_group;
-	indio_dev->ring->access.rip_lots = &sca3000_rip_hw_rb;
-	indio_dev->ring->access.get_length = &sca3000_ring_get_length;
-	indio_dev->ring->access.get_bytes_per_datum = &sca3000_ring_get_bytes_per_datum;
+	indio_dev->ring->access = &sca3000_ring_access_funcs;
+
+	iio_scan_mask_set(indio_dev->ring, 0);
+	iio_scan_mask_set(indio_dev->ring, 1);
+	iio_scan_mask_set(indio_dev->ring, 2);
 
 	return 0;
 }
@@ -300,22 +399,20 @@
 {
 	struct sca3000_state *st = indio_dev->dev_data;
 	int ret;
-	u8 *rx;
 
 	mutex_lock(&st->lock);
-	ret = sca3000_read_data(st, SCA3000_REG_ADDR_MODE, &rx, 1);
+	ret = sca3000_read_data_short(st, SCA3000_REG_ADDR_MODE, 1);
 	if (ret)
 		goto error_ret;
 	if (state) {
 		printk(KERN_INFO "supposedly enabling ring buffer\n");
 		ret = sca3000_write_reg(st,
 					SCA3000_REG_ADDR_MODE,
-					(rx[1] | SCA3000_RING_BUF_ENABLE));
+					(st->rx[0] | SCA3000_RING_BUF_ENABLE));
 	} else
 		ret = sca3000_write_reg(st,
 					SCA3000_REG_ADDR_MODE,
-					(rx[1] & ~SCA3000_RING_BUF_ENABLE));
-	kfree(rx);
+					(st->rx[0] & ~SCA3000_RING_BUF_ENABLE));
 error_ret:
 	mutex_unlock(&st->lock);
 
@@ -338,10 +435,14 @@
 	return __sca3000_hw_ring_state_set(indio_dev, 0);
 }
 
+static const struct iio_ring_setup_ops sca3000_ring_setup_ops = {
+	.preenable = &sca3000_hw_ring_preenable,
+	.postdisable = &sca3000_hw_ring_postdisable,
+};
+
 void sca3000_register_ring_funcs(struct iio_dev *indio_dev)
 {
-	indio_dev->ring->preenable = &sca3000_hw_ring_preenable;
-	indio_dev->ring->postdisable = &sca3000_hw_ring_postdisable;
+	indio_dev->ring->setup_ops = &sca3000_ring_setup_ops;
 }
 
 /**
@@ -352,11 +453,9 @@
  **/
 void sca3000_ring_int_process(u8 val, struct iio_ring_buffer *ring)
 {
-	if (val & SCA3000_INT_STATUS_THREE_QUARTERS)
-		iio_push_or_escallate_ring_event(ring,
-						 IIO_EVENT_CODE_RING_75_FULL,
-						 0);
-	else if (val & SCA3000_INT_STATUS_HALF)
-		iio_push_ring_event(ring,
-				    IIO_EVENT_CODE_RING_50_FULL, 0);
+	if (val & (SCA3000_INT_STATUS_THREE_QUARTERS |
+		   SCA3000_INT_STATUS_HALF)) {
+		ring->stufftoread = true;
+		wake_up_interruptible(&ring->pollq);
+	}
 }
diff -druN linux-2.6.39-libre/drivers/staging/iio/adc/ad7150.c linux-3.0-rc7-libre/drivers/staging/iio/adc/ad7150.c
--- linux-2.6.39-libre/drivers/staging/iio/adc/ad7150.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/iio/adc/ad7150.c	2011-07-11 19:51:52.000000000 -0400
@@ -7,15 +7,10 @@
  */
 
 #include <linux/interrupt.h>
-#include <linux/gpio.h>
-#include <linux/workqueue.h>
 #include <linux/device.h>
 #include <linux/kernel.h>
 #include <linux/slab.h>
-#include <linux/sysfs.h>
-#include <linux/list.h>
 #include <linux/i2c.h>
-#include <linux/rtc.h>
 
 #include "../iio.h"
 #include "../sysfs.h"
@@ -63,12 +58,9 @@
  */
 
 struct ad7150_chip_info {
-	const char *name;
 	struct i2c_client *client;
 	struct iio_dev *indio_dev;
-	struct work_struct thresh_work;
 	bool inter;
-	s64 last_timestamp;
 	u16 ch1_threshold;     /* Ch1 Threshold (in fixed threshold mode) */
 	u8  ch1_sensitivity;   /* Ch1 Sensitivity (in adaptive threshold mode) */
 	u8  ch1_timeout;       /* Ch1 Timeout (in adaptive threshold mode) */
@@ -88,7 +80,8 @@
 	u8 reg_cfg;
 };
 
-struct ad7150_conversion_mode ad7150_conv_mode_table[AD7150_MAX_CONV_MODE] = {
+static struct ad7150_conversion_mode
+ad7150_conv_mode_table[AD7150_MAX_CONV_MODE] = {
 	{ "idle", 0 },
 	{ "continuous-conversion", 1 },
 	{ "single-conversion", 2 },
@@ -590,17 +583,6 @@
 		ad7150_show_ch2_setup,
 		ad7150_store_ch2_setup);
 
-static ssize_t ad7150_show_name(struct device *dev,
-		struct device_attribute *attr,
-		char *buf)
-{
-	struct iio_dev *dev_info = dev_get_drvdata(dev);
-	struct ad7150_chip_info *chip = dev_info->dev_data;
-	return sprintf(buf, "%s\n", chip->name);
-}
-
-static IIO_DEVICE_ATTR(name, S_IRUGO, ad7150_show_name, NULL, 0);
-
 static ssize_t ad7150_show_powerdown_timer(struct device *dev,
 		struct device_attribute *attr,
 		char *buf)
@@ -649,7 +631,6 @@
 	&iio_dev_attr_powerdown_timer.dev_attr.attr,
 	&iio_dev_attr_ch1_value.dev_attr.attr,
 	&iio_dev_attr_ch2_value.dev_attr.attr,
-	&iio_dev_attr_name.dev_attr.attr,
 	NULL,
 };
 
@@ -661,96 +642,57 @@
  * threshold events
  */
 
-#define IIO_EVENT_CODE_CH1_HIGH    IIO_BUFFER_EVENT_CODE(0)
-#define IIO_EVENT_CODE_CH1_LOW     IIO_BUFFER_EVENT_CODE(1)
-#define IIO_EVENT_CODE_CH2_HIGH    IIO_BUFFER_EVENT_CODE(2)
-#define IIO_EVENT_CODE_CH2_LOW     IIO_BUFFER_EVENT_CODE(3)
-
-#define IIO_EVENT_ATTR_CH1_HIGH_SH(_evlist, _show, _store, _mask)	\
-	IIO_EVENT_ATTR_SH(ch1_high, _evlist, _show, _store, _mask)
-
-#define IIO_EVENT_ATTR_CH2_HIGH_SH(_evlist, _show, _store, _mask)	\
-	IIO_EVENT_ATTR_SH(ch2_high, _evlist, _show, _store, _mask)
-
-#define IIO_EVENT_ATTR_CH1_LOW_SH(_evlist, _show, _store, _mask)	\
-	IIO_EVENT_ATTR_SH(ch1_low, _evlist, _show, _store, _mask)
-
-#define IIO_EVENT_ATTR_CH2_LOW_SH(_evlist, _show, _store, _mask)	\
-	IIO_EVENT_ATTR_SH(ch2_low, _evlist, _show, _store, _mask)
-
-static void ad7150_interrupt_handler_bh(struct work_struct *work_s)
+static irqreturn_t ad7150_event_handler(int irq, void *private)
 {
-	struct ad7150_chip_info *chip =
-		container_of(work_s, struct ad7150_chip_info, thresh_work);
+	struct iio_dev *indio_dev = private;
+	struct ad7150_chip_info *chip = iio_dev_get_devdata(indio_dev);
 	u8 int_status;
-
-	enable_irq(chip->client->irq);
+	s64 timestamp = iio_get_time_ns();
 
 	ad7150_i2c_read(chip, AD7150_STATUS, &int_status, 1);
 
 	if ((int_status & AD7150_STATUS_OUT1) && !(chip->old_state & AD7150_STATUS_OUT1))
-		iio_push_event(chip->indio_dev, 0,
-				IIO_EVENT_CODE_CH1_HIGH,
-				chip->last_timestamp);
+		iio_push_event(indio_dev, 0,
+			       IIO_UNMOD_EVENT_CODE(IIO_EV_CLASS_IN,
+						    0,
+						    IIO_EV_TYPE_THRESH,
+						    IIO_EV_DIR_RISING),
+				timestamp);
 	else if ((!(int_status & AD7150_STATUS_OUT1)) && (chip->old_state & AD7150_STATUS_OUT1))
-		iio_push_event(chip->indio_dev, 0,
-				IIO_EVENT_CODE_CH1_LOW,
-				chip->last_timestamp);
+		iio_push_event(indio_dev, 0,
+			       IIO_UNMOD_EVENT_CODE(IIO_EV_CLASS_IN,
+						    0,
+						    IIO_EV_TYPE_THRESH,
+						    IIO_EV_DIR_FALLING),
+			       timestamp);
 
 	if ((int_status & AD7150_STATUS_OUT2) && !(chip->old_state & AD7150_STATUS_OUT2))
-		iio_push_event(chip->indio_dev, 0,
-				IIO_EVENT_CODE_CH2_HIGH,
-				chip->last_timestamp);
+		iio_push_event(indio_dev, 0,
+			       IIO_UNMOD_EVENT_CODE(IIO_EV_CLASS_IN,
+						    1,
+						    IIO_EV_TYPE_THRESH,
+						    IIO_EV_DIR_RISING),
+			       timestamp);
 	else if ((!(int_status & AD7150_STATUS_OUT2)) && (chip->old_state & AD7150_STATUS_OUT2))
-		iio_push_event(chip->indio_dev, 0,
-				IIO_EVENT_CODE_CH2_LOW,
-				chip->last_timestamp);
-}
-
-static int ad7150_interrupt_handler_th(struct iio_dev *dev_info,
-		int index,
-		s64 timestamp,
-		int no_test)
-{
-	struct ad7150_chip_info *chip = dev_info->dev_data;
-
-	chip->last_timestamp = timestamp;
-	schedule_work(&chip->thresh_work);
-
-	return 0;
-}
-
-IIO_EVENT_SH(threshold, &ad7150_interrupt_handler_th);
-
-static ssize_t ad7150_query_out_mode(struct device *dev,
-		struct device_attribute *attr,
-		char *buf)
-{
-	/*
-	 * AD7150 provides two logic output channels, which can be used as interrupt
-	 * but the pins are not configurable
-	 */
-	return sprintf(buf, "1\n");
-}
-
-static ssize_t ad7150_set_out_mode(struct device *dev,
-		struct device_attribute *attr,
-		const char *buf,
-		size_t len)
-{
-	return len;
+		iio_push_event(indio_dev, 0,
+			       IIO_UNMOD_EVENT_CODE(IIO_EV_CLASS_IN,
+						    1,
+						    IIO_EV_TYPE_THRESH,
+						    IIO_EV_DIR_FALLING),
+			       timestamp);
+	return IRQ_HANDLED;
 }
 
-IIO_EVENT_ATTR_CH1_HIGH_SH(iio_event_threshold, ad7150_query_out_mode, ad7150_set_out_mode, 0);
-IIO_EVENT_ATTR_CH2_HIGH_SH(iio_event_threshold, ad7150_query_out_mode, ad7150_set_out_mode, 0);
-IIO_EVENT_ATTR_CH1_LOW_SH(iio_event_threshold, ad7150_query_out_mode, ad7150_set_out_mode, 0);
-IIO_EVENT_ATTR_CH2_LOW_SH(iio_event_threshold, ad7150_query_out_mode, ad7150_set_out_mode, 0);
+static IIO_CONST_ATTR(ch1_high_en, "1");
+static IIO_CONST_ATTR(ch2_high_en, "1");
+static IIO_CONST_ATTR(ch1_low_en, "1");
+static IIO_CONST_ATTR(ch2_low_en, "1");
 
 static struct attribute *ad7150_event_attributes[] = {
-	&iio_event_attr_ch1_high.dev_attr.attr,
-	&iio_event_attr_ch2_high.dev_attr.attr,
-	&iio_event_attr_ch1_low.dev_attr.attr,
-	&iio_event_attr_ch2_low.dev_attr.attr,
+	&iio_const_attr_ch1_high_en.dev_attr.attr,
+	&iio_const_attr_ch2_high_en.dev_attr.attr,
+	&iio_const_attr_ch1_low_en.dev_attr.attr,
+	&iio_const_attr_ch2_low_en.dev_attr.attr,
 	NULL,
 };
 
@@ -758,6 +700,12 @@
 	.attrs = ad7150_event_attributes,
 };
 
+static const struct iio_info ad7150_info = {
+	.attrs = &ad7150_attribute_group,
+	.num_interrupt_lines = 1,
+	.event_attrs = &ad7150_event_attribute_group,
+	.driver_module = THIS_MODULE,
+};
 /*
  * device probe and remove
  */
@@ -776,21 +724,20 @@
 	i2c_set_clientdata(client, chip);
 
 	chip->client = client;
-	chip->name = id->name;
 
-	chip->indio_dev = iio_allocate_device();
+	chip->indio_dev = iio_allocate_device(0);
 	if (chip->indio_dev == NULL) {
 		ret = -ENOMEM;
 		goto error_free_chip;
 	}
 
-	/* Echipabilish that the iio_dev is a child of the i2c device */
+	/* Establish that the iio_dev is a child of the i2c device */
+	chip->indio_dev->name = id->name;
 	chip->indio_dev->dev.parent = &client->dev;
-	chip->indio_dev->attrs = &ad7150_attribute_group;
-	chip->indio_dev->event_attrs = &ad7150_event_attribute_group;
+
+	chip->indio_dev->info = &ad7150_info;
 	chip->indio_dev->dev_data = (void *)(chip);
-	chip->indio_dev->driver_module = THIS_MODULE;
-	chip->indio_dev->num_interrupt_lines = 1;
+
 	chip->indio_dev->modes = INDIO_DIRECT_MODE;
 
 	ret = iio_device_register(chip->indio_dev);
@@ -798,19 +745,16 @@
 		goto error_free_dev;
 	regdone = 1;
 
-	if (client->irq && gpio_is_valid(irq_to_gpio(client->irq)) > 0) {
-		ret = iio_register_interrupt_line(client->irq,
-				chip->indio_dev,
-				0,
-				IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
-				"ad7150");
+	if (client->irq) {
+		ret = request_threaded_irq(client->irq,
+					   NULL,
+					   &ad7150_event_handler,
+					   IRQF_TRIGGER_RISING |
+					   IRQF_TRIGGER_FALLING,
+					   "ad7150",
+					   chip->indio_dev);
 		if (ret)
 			goto error_free_dev;
-
-		iio_add_event_to_list(iio_event_attr_ch2_low.listel,
-				&chip->indio_dev->interrupts[0]->ev_list);
-
-		INIT_WORK(&chip->thresh_work, ad7150_interrupt_handler_bh);
 	}
 
 	dev_err(&client->dev, "%s capacitive sensor registered, irq: %d\n", id->name, client->irq);
@@ -833,8 +777,8 @@
 	struct ad7150_chip_info *chip = i2c_get_clientdata(client);
 	struct iio_dev *indio_dev = chip->indio_dev;
 
-	if (client->irq && gpio_is_valid(irq_to_gpio(client->irq)) > 0)
-		iio_unregister_interrupt_line(indio_dev, 0);
+	if (client->irq)
+		free_irq(client->irq, indio_dev);
 	iio_device_unregister(indio_dev);
 	kfree(chip);
 
diff -druN linux-2.6.39-libre/drivers/staging/iio/adc/ad7152.c linux-3.0-rc7-libre/drivers/staging/iio/adc/ad7152.c
--- linux-2.6.39-libre/drivers/staging/iio/adc/ad7152.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/iio/adc/ad7152.c	2011-07-11 19:51:52.000000000 -0400
@@ -7,15 +7,11 @@
  */
 
 #include <linux/interrupt.h>
-#include <linux/gpio.h>
-#include <linux/workqueue.h>
 #include <linux/device.h>
 #include <linux/kernel.h>
 #include <linux/slab.h>
 #include <linux/sysfs.h>
-#include <linux/list.h>
 #include <linux/i2c.h>
-#include <linux/rtc.h>
 
 #include "../iio.h"
 #include "../sysfs.h"
@@ -54,7 +50,6 @@
  */
 
 struct ad7152_chip_info {
-	const char *name;
 	struct i2c_client *client;
 	struct iio_dev *indio_dev;
 	u16 ch1_offset;     /* Channel 1 offset calibration coefficient */
@@ -72,7 +67,8 @@
 	u8 reg_cfg;
 };
 
-struct ad7152_conversion_mode ad7152_conv_mode_table[AD7152_MAX_CONV_MODE] = {
+static struct ad7152_conversion_mode
+ad7152_conv_mode_table[AD7152_MAX_CONV_MODE] = {
 	{ "idle", 0 },
 	{ "continuous-conversion", 1 },
 	{ "single-conversion", 2 },
@@ -482,17 +478,6 @@
 		ad7152_show_filter_rate_setup,
 		ad7152_store_filter_rate_setup);
 
-static ssize_t ad7152_show_name(struct device *dev,
-		struct device_attribute *attr,
-		char *buf)
-{
-	struct iio_dev *dev_info = dev_get_drvdata(dev);
-	struct ad7152_chip_info *chip = dev_info->dev_data;
-	return sprintf(buf, "%s\n", chip->name);
-}
-
-static IIO_DEVICE_ATTR(name, S_IRUGO, ad7152_show_name, NULL, 0);
-
 static struct attribute *ad7152_attributes[] = {
 	&iio_dev_attr_available_conversion_modes.dev_attr.attr,
 	&iio_dev_attr_conversion_mode.dev_attr.attr,
@@ -505,7 +490,6 @@
 	&iio_dev_attr_ch1_setup.dev_attr.attr,
 	&iio_dev_attr_ch2_setup.dev_attr.attr,
 	&iio_dev_attr_filter_rate_setup.dev_attr.attr,
-	&iio_dev_attr_name.dev_attr.attr,
 	NULL,
 };
 
@@ -513,6 +497,10 @@
 	.attrs = ad7152_attributes,
 };
 
+static const struct iio_info ad7152_info = {
+	.attrs = &ad7152_attribute_group,
+	.driver_module = THIS_MODULE,
+};
 /*
  * device probe and remove
  */
@@ -531,19 +519,18 @@
 	i2c_set_clientdata(client, chip);
 
 	chip->client = client;
-	chip->name = id->name;
 
-	chip->indio_dev = iio_allocate_device();
+	chip->indio_dev = iio_allocate_device(0);
 	if (chip->indio_dev == NULL) {
 		ret = -ENOMEM;
 		goto error_free_chip;
 	}
 
 	/* Echipabilish that the iio_dev is a child of the i2c device */
+	chip->indio_dev->name = id->name;
 	chip->indio_dev->dev.parent = &client->dev;
-	chip->indio_dev->attrs = &ad7152_attribute_group;
+	chip->indio_dev->info = &ad7152_info;
 	chip->indio_dev->dev_data = (void *)(chip);
-	chip->indio_dev->driver_module = THIS_MODULE;
 	chip->indio_dev->modes = INDIO_DIRECT_MODE;
 
 	ret = iio_device_register(chip->indio_dev);
@@ -567,8 +554,6 @@
 	struct ad7152_chip_info *chip = i2c_get_clientdata(client);
 	struct iio_dev *indio_dev = chip->indio_dev;
 
-	if (client->irq && gpio_is_valid(irq_to_gpio(client->irq)) > 0)
-		iio_unregister_interrupt_line(indio_dev, 0);
 	iio_device_unregister(indio_dev);
 	kfree(chip);
 
diff -druN linux-2.6.39-libre/drivers/staging/iio/adc/ad7291.c linux-3.0-rc7-libre/drivers/staging/iio/adc/ad7291.c
--- linux-2.6.39-libre/drivers/staging/iio/adc/ad7291.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/iio/adc/ad7291.c	2011-07-11 19:51:52.000000000 -0400
@@ -8,14 +8,12 @@
 
 #include <linux/interrupt.h>
 #include <linux/gpio.h>
-#include <linux/workqueue.h>
 #include <linux/device.h>
 #include <linux/kernel.h>
 #include <linux/slab.h>
 #include <linux/sysfs.h>
 #include <linux/list.h>
 #include <linux/i2c.h>
-#include <linux/rtc.h>
 
 #include "../iio.h"
 #include "../sysfs.h"
@@ -62,11 +60,8 @@
  */
 
 struct ad7291_chip_info {
-	const char *name;
 	struct i2c_client *client;
 	struct iio_dev *indio_dev;
-	struct work_struct thresh_work;
-	s64 last_timestamp;
 	u16 command;
 	u8  channels;	/* Active voltage channels */
 };
@@ -438,17 +433,6 @@
 		ad7291_store_channel_mask,
 		0);
 
-static ssize_t ad7291_show_name(struct device *dev,
-		struct device_attribute *attr,
-		char *buf)
-{
-	struct iio_dev *dev_info = dev_get_drvdata(dev);
-	struct ad7291_chip_info *chip = dev_info->dev_data;
-	return sprintf(buf, "%s\n", chip->name);
-}
-
-static IIO_DEVICE_ATTR(name, S_IRUGO, ad7291_show_name, NULL, 0);
-
 static struct attribute *ad7291_attributes[] = {
 	&iio_dev_attr_available_modes.dev_attr.attr,
 	&iio_dev_attr_mode.dev_attr.attr,
@@ -459,7 +443,6 @@
 	&iio_dev_attr_t_average.dev_attr.attr,
 	&iio_dev_attr_voltage.dev_attr.attr,
 	&iio_dev_attr_channel_mask.dev_attr.attr,
-	&iio_dev_attr_name.dev_attr.attr,
 	NULL,
 };
 
@@ -471,28 +454,23 @@
  * temperature bound events
  */
 
-#define IIO_EVENT_CODE_AD7291_T_SENSE_HIGH  IIO_BUFFER_EVENT_CODE(0)
-#define IIO_EVENT_CODE_AD7291_T_SENSE_LOW   IIO_BUFFER_EVENT_CODE(1)
-#define IIO_EVENT_CODE_AD7291_T_AVG_HIGH    IIO_BUFFER_EVENT_CODE(2)
-#define IIO_EVENT_CODE_AD7291_T_AVG_LOW     IIO_BUFFER_EVENT_CODE(3)
-#define IIO_EVENT_CODE_AD7291_VOLTAGE_BASE  IIO_BUFFER_EVENT_CODE(4)
-
-static void ad7291_interrupt_bh(struct work_struct *work_s)
+static irqreturn_t ad7291_event_handler(int irq, void *private)
 {
-	struct ad7291_chip_info *chip =
-		container_of(work_s, struct ad7291_chip_info, thresh_work);
+	struct iio_dev *indio_dev = private;
+	struct ad7291_chip_info *chip = iio_dev_get_devdata(private);
 	u16 t_status, v_status;
 	u16 command;
 	int i;
+	s64 timestamp = iio_get_time_ns();
 
 	if (ad7291_i2c_read(chip, AD7291_T_ALERT_STATUS, &t_status))
-		return;
+		return IRQ_HANDLED;
 
 	if (ad7291_i2c_read(chip, AD7291_VOLTAGE_ALERT_STATUS, &v_status))
-		return;
+		return IRQ_HANDLED;
 
 	if (!(t_status || v_status))
-		return;
+		return IRQ_HANDLED;
 
 	command = chip->command | AD7291_ALART_CLEAR;
 	ad7291_i2c_write(chip, AD7291_COMMAND, command);
@@ -500,50 +478,67 @@
 	command = chip->command & ~AD7291_ALART_CLEAR;
 	ad7291_i2c_write(chip, AD7291_COMMAND, command);
 
-	enable_irq(chip->client->irq);
-
-	for (i = 0; i < 4; i++) {
-		if (t_status & (1 << i))
-			iio_push_event(chip->indio_dev, 0,
-				IIO_EVENT_CODE_AD7291_T_SENSE_HIGH + i,
-				chip->last_timestamp);
-	}
+	if (t_status & (1 << 0))
+		iio_push_event(indio_dev, 0,
+			       IIO_UNMOD_EVENT_CODE(IIO_TEMP,
+						    0,
+						    IIO_EV_TYPE_THRESH,
+						    IIO_EV_DIR_FALLING),
+			       timestamp);
+	if (t_status & (1 << 1))
+		iio_push_event(indio_dev, 0,
+			       IIO_UNMOD_EVENT_CODE(IIO_TEMP,
+						    0,
+						    IIO_EV_TYPE_THRESH,
+						    IIO_EV_DIR_RISING),
+			       timestamp);
+	if (t_status & (1 << 2))
+		iio_push_event(indio_dev, 0,
+			       IIO_UNMOD_EVENT_CODE(IIO_TEMP,
+						    0,
+						    IIO_EV_TYPE_THRESH,
+						    IIO_EV_DIR_FALLING),
+			       timestamp);
+	if (t_status & (1 << 3))
+		iio_push_event(indio_dev, 0,
+			       IIO_UNMOD_EVENT_CODE(IIO_TEMP,
+						    0,
+						    IIO_EV_TYPE_THRESH,
+						    IIO_EV_DIR_RISING),
+			       timestamp);
 
-	for (i = 0; i < AD7291_VOLTAGE_LIMIT_COUNT*2; i++) {
+	for (i = 0; i < AD7291_VOLTAGE_LIMIT_COUNT*2; i += 2) {
 		if (v_status & (1 << i))
-			iio_push_event(chip->indio_dev, 0,
-				IIO_EVENT_CODE_AD7291_VOLTAGE_BASE + i,
-				chip->last_timestamp);
+			iio_push_event(indio_dev, 0,
+				       IIO_UNMOD_EVENT_CODE(IIO_IN,
+							    i/2,
+							    IIO_EV_TYPE_THRESH,
+							    IIO_EV_DIR_FALLING),
+				       timestamp);
+		if (v_status & (1 << (i + 1)))
+			iio_push_event(indio_dev, 0,
+				       IIO_UNMOD_EVENT_CODE(IIO_IN,
+							    i/2,
+							    IIO_EV_TYPE_THRESH,
+							    IIO_EV_DIR_RISING),
+				       timestamp);
 	}
-}
-
-static int ad7291_interrupt(struct iio_dev *dev_info,
-		int index,
-		s64 timestamp,
-		int no_test)
-{
-	struct ad7291_chip_info *chip = dev_info->dev_data;
 
-	chip->last_timestamp = timestamp;
-	schedule_work(&chip->thresh_work);
-
-	return 0;
+	return IRQ_HANDLED;
 }
 
-IIO_EVENT_SH(ad7291, &ad7291_interrupt);
-
 static inline ssize_t ad7291_show_t_bound(struct device *dev,
 		struct device_attribute *attr,
-		u8 bound_reg,
 		char *buf)
 {
 	struct iio_dev *dev_info = dev_get_drvdata(dev);
 	struct ad7291_chip_info *chip = dev_info->dev_data;
+	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
 	u16 data;
 	char sign = ' ';
 	int ret;
 
-	ret = ad7291_i2c_read(chip, bound_reg, &data);
+	ret = ad7291_i2c_read(chip, this_attr->address, &data);
 	if (ret)
 		return -EIO;
 
@@ -561,12 +556,12 @@
 
 static inline ssize_t ad7291_set_t_bound(struct device *dev,
 		struct device_attribute *attr,
-		u8 bound_reg,
 		const char *buf,
 		size_t len)
 {
 	struct iio_dev *dev_info = dev_get_drvdata(dev);
 	struct ad7291_chip_info *chip = dev_info->dev_data;
+	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
 	long tmp1, tmp2;
 	u16 data;
 	char *pos;
@@ -600,64 +595,13 @@
 		/* convert positive value to supplyment */
 		data = (AD7291_T_VALUE_SIGN << 1) - data;
 
-	ret = ad7291_i2c_write(chip, bound_reg, data);
+	ret = ad7291_i2c_write(chip, this_attr->address, data);
 	if (ret)
 		return -EIO;
 
 	return ret;
 }
 
-static ssize_t ad7291_show_t_sense_high(struct device *dev,
-		struct device_attribute *attr,
-		char *buf)
-{
-	return ad7291_show_t_bound(dev, attr,
-			AD7291_T_SENSE_HIGH, buf);
-}
-
-static inline ssize_t ad7291_set_t_sense_high(struct device *dev,
-		struct device_attribute *attr,
-		const char *buf,
-		size_t len)
-{
-	return ad7291_set_t_bound(dev, attr,
-			AD7291_T_SENSE_HIGH, buf, len);
-}
-
-static ssize_t ad7291_show_t_sense_low(struct device *dev,
-		struct device_attribute *attr,
-		char *buf)
-{
-	return ad7291_show_t_bound(dev, attr,
-			AD7291_T_SENSE_LOW, buf);
-}
-
-static inline ssize_t ad7291_set_t_sense_low(struct device *dev,
-		struct device_attribute *attr,
-		const char *buf,
-		size_t len)
-{
-	return ad7291_set_t_bound(dev, attr,
-			AD7291_T_SENSE_LOW, buf, len);
-}
-
-static ssize_t ad7291_show_t_sense_hyst(struct device *dev,
-		struct device_attribute *attr,
-		char *buf)
-{
-	return ad7291_show_t_bound(dev, attr,
-			AD7291_T_SENSE_HYST, buf);
-}
-
-static inline ssize_t ad7291_set_t_sense_hyst(struct device *dev,
-		struct device_attribute *attr,
-		const char *buf,
-		size_t len)
-{
-	return ad7291_set_t_bound(dev, attr,
-			AD7291_T_SENSE_HYST, buf, len);
-}
-
 static inline ssize_t ad7291_show_v_bound(struct device *dev,
 		struct device_attribute *attr,
 		u8 bound_reg,
@@ -712,191 +656,121 @@
 	return ret;
 }
 
-static int ad7291_get_voltage_limit_regs(const char *channel)
-{
-	int index;
-
-	if (strlen(channel) < 3 && channel[0] != 'v')
-		return -EINVAL;
-
-	index = channel[1] - '0';
-	if (index >= AD7291_VOLTAGE_LIMIT_COUNT)
-		return -EINVAL;
-
-	return index;
-}
-
-static ssize_t ad7291_show_voltage_high(struct device *dev,
-		struct device_attribute *attr,
-		char *buf)
-{
-	int regs;
-
-	regs = ad7291_get_voltage_limit_regs(attr->attr.name);
-
-	if (regs < 0)
-		return regs;
-
-	return ad7291_show_t_bound(dev, attr, regs, buf);
-}
-
-static inline ssize_t ad7291_set_voltage_high(struct device *dev,
-		struct device_attribute *attr,
-		const char *buf,
-		size_t len)
-{
-	int regs;
-
-	regs = ad7291_get_voltage_limit_regs(attr->attr.name);
-
-	if (regs < 0)
-		return regs;
-
-	return ad7291_set_t_bound(dev, attr, regs, buf, len);
-}
-
-static ssize_t ad7291_show_voltage_low(struct device *dev,
-		struct device_attribute *attr,
-		char *buf)
-{
-	int regs;
-
-	regs = ad7291_get_voltage_limit_regs(attr->attr.name);
-
-	if (regs < 0)
-		return regs;
-
-	return ad7291_show_t_bound(dev, attr, regs+1, buf);
-}
-
-static inline ssize_t ad7291_set_voltage_low(struct device *dev,
-		struct device_attribute *attr,
-		const char *buf,
-		size_t len)
-{
-	int regs;
-
-	regs = ad7291_get_voltage_limit_regs(attr->attr.name);
-
-	if (regs < 0)
-		return regs;
-
-	return ad7291_set_t_bound(dev, attr, regs+1, buf, len);
-}
-
-static ssize_t ad7291_show_voltage_hyst(struct device *dev,
-		struct device_attribute *attr,
-		char *buf)
-{
-	int regs;
-
-	regs = ad7291_get_voltage_limit_regs(attr->attr.name);
-
-	if (regs < 0)
-		return regs;
-
-	return ad7291_show_t_bound(dev, attr, regs+2, buf);
-}
-
-static inline ssize_t ad7291_set_voltage_hyst(struct device *dev,
-		struct device_attribute *attr,
-		const char *buf,
-		size_t len)
-{
-	int regs;
-
-	regs = ad7291_get_voltage_limit_regs(attr->attr.name);
-
-	if (regs < 0)
-		return regs;
-
-	return ad7291_set_t_bound(dev, attr, regs+2, buf, len);
-}
-
-IIO_EVENT_ATTR_SH(t_sense_high, iio_event_ad7291,
-		ad7291_show_t_sense_high, ad7291_set_t_sense_high, 0);
-IIO_EVENT_ATTR_SH(t_sense_low, iio_event_ad7291,
-		ad7291_show_t_sense_low, ad7291_set_t_sense_low, 0);
-IIO_EVENT_ATTR_SH(t_sense_hyst, iio_event_ad7291,
-		ad7291_show_t_sense_hyst, ad7291_set_t_sense_hyst, 0);
-
-IIO_EVENT_ATTR_SH(v0_high, iio_event_ad7291,
-		ad7291_show_voltage_high, ad7291_set_voltage_high, 0);
-IIO_EVENT_ATTR_SH(v0_low, iio_event_ad7291,
-		ad7291_show_voltage_low, ad7291_set_voltage_low, 0);
-IIO_EVENT_ATTR_SH(v0_hyst, iio_event_ad7291,
-		ad7291_show_voltage_hyst, ad7291_set_voltage_hyst, 0);
-IIO_EVENT_ATTR_SH(v1_high, iio_event_ad7291,
-		ad7291_show_voltage_high, ad7291_set_voltage_high, 0);
-IIO_EVENT_ATTR_SH(v1_low, iio_event_ad7291,
-		ad7291_show_voltage_low, ad7291_set_voltage_low, 0);
-IIO_EVENT_ATTR_SH(v1_hyst, iio_event_ad7291,
-		ad7291_show_voltage_hyst, ad7291_set_voltage_hyst, 0);
-IIO_EVENT_ATTR_SH(v2_high, iio_event_ad7291,
-		ad7291_show_voltage_high, ad7291_set_voltage_high, 0);
-IIO_EVENT_ATTR_SH(v2_low, iio_event_ad7291,
-		ad7291_show_voltage_low, ad7291_set_voltage_low, 0);
-IIO_EVENT_ATTR_SH(v2_hyst, iio_event_ad7291,
-		ad7291_show_voltage_hyst, ad7291_set_voltage_hyst, 0);
-IIO_EVENT_ATTR_SH(v3_high, iio_event_ad7291,
-		ad7291_show_voltage_high, ad7291_set_voltage_high, 0);
-IIO_EVENT_ATTR_SH(v3_low, iio_event_ad7291,
-		ad7291_show_voltage_low, ad7291_set_voltage_low, 0);
-IIO_EVENT_ATTR_SH(v3_hyst, iio_event_ad7291,
-		ad7291_show_voltage_hyst, ad7291_set_voltage_hyst, 0);
-IIO_EVENT_ATTR_SH(v4_high, iio_event_ad7291,
-		ad7291_show_voltage_high, ad7291_set_voltage_high, 0);
-IIO_EVENT_ATTR_SH(v4_low, iio_event_ad7291,
-		ad7291_show_voltage_low, ad7291_set_voltage_low, 0);
-IIO_EVENT_ATTR_SH(v4_hyst, iio_event_ad7291,
-		ad7291_show_voltage_hyst, ad7291_set_voltage_hyst, 0);
-IIO_EVENT_ATTR_SH(v5_high, iio_event_ad7291,
-		ad7291_show_voltage_high, ad7291_set_voltage_high, 0);
-IIO_EVENT_ATTR_SH(v5_low, iio_event_ad7291,
-		ad7291_show_voltage_low, ad7291_set_voltage_low, 0);
-IIO_EVENT_ATTR_SH(v5_hyst, iio_event_ad7291,
-		ad7291_show_voltage_hyst, ad7291_set_voltage_hyst, 0);
-IIO_EVENT_ATTR_SH(v6_high, iio_event_ad7291,
-		ad7291_show_voltage_high, ad7291_set_voltage_high, 0);
-IIO_EVENT_ATTR_SH(v6_low, iio_event_ad7291,
-		ad7291_show_voltage_low, ad7291_set_voltage_low, 0);
-IIO_EVENT_ATTR_SH(v6_hyst, iio_event_ad7291,
-		ad7291_show_voltage_hyst, ad7291_set_voltage_hyst, 0);
-IIO_EVENT_ATTR_SH(v7_high, iio_event_ad7291,
-		ad7291_show_voltage_high, ad7291_set_voltage_high, 0);
-IIO_EVENT_ATTR_SH(v7_low, iio_event_ad7291,
-		ad7291_show_voltage_low, ad7291_set_voltage_low, 0);
-IIO_EVENT_ATTR_SH(v7_hyst, iio_event_ad7291,
-		ad7291_show_voltage_hyst, ad7291_set_voltage_hyst, 0);
+static IIO_DEVICE_ATTR(t_sense_high_value,
+		       S_IRUGO | S_IWUSR,
+		       ad7291_show_t_bound, ad7291_set_t_bound,
+		       AD7291_T_SENSE_HIGH);
+static IIO_DEVICE_ATTR(t_sense_low_value,
+		       S_IRUGO | S_IWUSR,
+		       ad7291_show_t_bound, ad7291_set_t_bound,
+		       AD7291_T_SENSE_LOW);
+static IIO_DEVICE_ATTR(t_sense_hyst_value,
+		       S_IRUGO | S_IWUSR,
+		       ad7291_show_t_bound, ad7291_set_t_bound,
+		       AD7291_T_SENSE_HYST);
+static IIO_DEVICE_ATTR(v0_high,
+		       S_IRUGO | S_IWUSR,
+		       ad7291_show_t_bound, ad7291_set_t_bound, 0x04);
+static IIO_DEVICE_ATTR(v0_low,
+		       S_IRUGO | S_IWUSR,
+		       ad7291_show_t_bound, ad7291_set_t_bound, 0x05);
+static IIO_DEVICE_ATTR(v0_hyst,
+		       S_IRUGO | S_IWUSR,
+		       ad7291_show_t_bound, ad7291_set_t_bound, 0x06);
+static IIO_DEVICE_ATTR(v1_high,
+		       S_IRUGO | S_IWUSR,
+		       ad7291_show_t_bound, ad7291_set_t_bound, 0x07);
+static IIO_DEVICE_ATTR(v1_low,
+		       S_IRUGO | S_IWUSR,
+		       ad7291_show_t_bound, ad7291_set_t_bound, 0x08);
+static IIO_DEVICE_ATTR(v1_hyst,
+		       S_IRUGO | S_IWUSR,
+		       ad7291_show_t_bound, ad7291_set_t_bound, 0x09);
+static IIO_DEVICE_ATTR(v2_high,
+		       S_IRUGO | S_IWUSR,
+		       ad7291_show_t_bound, ad7291_set_t_bound, 0x0A);
+static IIO_DEVICE_ATTR(v2_low,
+		       S_IRUGO | S_IWUSR,
+		       ad7291_show_t_bound, ad7291_set_t_bound, 0x0B);
+static IIO_DEVICE_ATTR(v2_hyst,
+		       S_IRUGO | S_IWUSR,
+		       ad7291_show_t_bound, ad7291_set_t_bound, 0x0C);
+static IIO_DEVICE_ATTR(v3_high,
+		       S_IRUGO | S_IWUSR,
+		       /* Datasheet suggests this one and this one only
+			  has the registers in different order */
+		       ad7291_show_t_bound, ad7291_set_t_bound, 0x0E);
+static IIO_DEVICE_ATTR(v3_low,
+		       S_IRUGO | S_IWUSR,
+		       ad7291_show_t_bound, ad7291_set_t_bound, 0x0D);
+static IIO_DEVICE_ATTR(v3_hyst,
+		       S_IRUGO | S_IWUSR,
+		       ad7291_show_t_bound, ad7291_set_t_bound, 0x0F);
+static IIO_DEVICE_ATTR(v4_high,
+		       S_IRUGO | S_IWUSR,
+		       ad7291_show_t_bound, ad7291_set_t_bound, 0x10);
+static IIO_DEVICE_ATTR(v4_low,
+		       S_IRUGO | S_IWUSR,
+		       ad7291_show_t_bound, ad7291_set_t_bound, 0x11);
+static IIO_DEVICE_ATTR(v4_hyst,
+		       S_IRUGO | S_IWUSR,
+		       ad7291_show_t_bound, ad7291_set_t_bound, 0x12);
+static IIO_DEVICE_ATTR(v5_high,
+		       S_IRUGO | S_IWUSR,
+		       ad7291_show_t_bound, ad7291_set_t_bound, 0x13);
+static IIO_DEVICE_ATTR(v5_low,
+		       S_IRUGO | S_IWUSR,
+		       ad7291_show_t_bound, ad7291_set_t_bound, 0x14);
+static IIO_DEVICE_ATTR(v5_hyst,
+		       S_IRUGO | S_IWUSR,
+		       ad7291_show_t_bound, ad7291_set_t_bound, 0x15);
+static IIO_DEVICE_ATTR(v6_high,
+		       S_IRUGO | S_IWUSR,
+		       ad7291_show_t_bound, ad7291_set_t_bound, 0x16);
+static IIO_DEVICE_ATTR(v6_low,
+		       S_IRUGO | S_IWUSR,
+		       ad7291_show_t_bound, ad7291_set_t_bound, 0x17);
+static IIO_DEVICE_ATTR(v6_hyst,
+		       S_IRUGO | S_IWUSR,
+		       ad7291_show_t_bound, ad7291_set_t_bound, 0x18);
+static IIO_DEVICE_ATTR(v7_high,
+		       S_IRUGO | S_IWUSR,
+		       ad7291_show_t_bound, ad7291_set_t_bound, 0x19);
+static IIO_DEVICE_ATTR(v7_low,
+		       S_IRUGO | S_IWUSR,
+		       ad7291_show_t_bound, ad7291_set_t_bound, 0x1A);
+static IIO_DEVICE_ATTR(v7_hyst,
+		       S_IRUGO | S_IWUSR,
+		       ad7291_show_t_bound, ad7291_set_t_bound, 0x1B);
 
 static struct attribute *ad7291_event_attributes[] = {
-	&iio_event_attr_t_sense_high.dev_attr.attr,
-	&iio_event_attr_t_sense_low.dev_attr.attr,
-	&iio_event_attr_t_sense_hyst.dev_attr.attr,
-	&iio_event_attr_v0_high.dev_attr.attr,
-	&iio_event_attr_v0_low.dev_attr.attr,
-	&iio_event_attr_v0_hyst.dev_attr.attr,
-	&iio_event_attr_v1_high.dev_attr.attr,
-	&iio_event_attr_v1_low.dev_attr.attr,
-	&iio_event_attr_v1_hyst.dev_attr.attr,
-	&iio_event_attr_v2_high.dev_attr.attr,
-	&iio_event_attr_v2_low.dev_attr.attr,
-	&iio_event_attr_v2_hyst.dev_attr.attr,
-	&iio_event_attr_v3_high.dev_attr.attr,
-	&iio_event_attr_v3_low.dev_attr.attr,
-	&iio_event_attr_v3_hyst.dev_attr.attr,
-	&iio_event_attr_v4_high.dev_attr.attr,
-	&iio_event_attr_v4_low.dev_attr.attr,
-	&iio_event_attr_v4_hyst.dev_attr.attr,
-	&iio_event_attr_v5_high.dev_attr.attr,
-	&iio_event_attr_v5_low.dev_attr.attr,
-	&iio_event_attr_v5_hyst.dev_attr.attr,
-	&iio_event_attr_v6_high.dev_attr.attr,
-	&iio_event_attr_v6_low.dev_attr.attr,
-	&iio_event_attr_v6_hyst.dev_attr.attr,
-	&iio_event_attr_v7_high.dev_attr.attr,
-	&iio_event_attr_v7_low.dev_attr.attr,
-	&iio_event_attr_v7_hyst.dev_attr.attr,
+	&iio_dev_attr_t_sense_high_value.dev_attr.attr,
+	&iio_dev_attr_t_sense_low_value.dev_attr.attr,
+	&iio_dev_attr_t_sense_hyst_value.dev_attr.attr,
+	&iio_dev_attr_v0_high.dev_attr.attr,
+	&iio_dev_attr_v0_low.dev_attr.attr,
+	&iio_dev_attr_v0_hyst.dev_attr.attr,
+	&iio_dev_attr_v1_high.dev_attr.attr,
+	&iio_dev_attr_v1_low.dev_attr.attr,
+	&iio_dev_attr_v1_hyst.dev_attr.attr,
+	&iio_dev_attr_v2_high.dev_attr.attr,
+	&iio_dev_attr_v2_low.dev_attr.attr,
+	&iio_dev_attr_v2_hyst.dev_attr.attr,
+	&iio_dev_attr_v3_high.dev_attr.attr,
+	&iio_dev_attr_v3_low.dev_attr.attr,
+	&iio_dev_attr_v3_hyst.dev_attr.attr,
+	&iio_dev_attr_v4_high.dev_attr.attr,
+	&iio_dev_attr_v4_low.dev_attr.attr,
+	&iio_dev_attr_v4_hyst.dev_attr.attr,
+	&iio_dev_attr_v5_high.dev_attr.attr,
+	&iio_dev_attr_v5_low.dev_attr.attr,
+	&iio_dev_attr_v5_hyst.dev_attr.attr,
+	&iio_dev_attr_v6_high.dev_attr.attr,
+	&iio_dev_attr_v6_low.dev_attr.attr,
+	&iio_dev_attr_v6_hyst.dev_attr.attr,
+	&iio_dev_attr_v7_high.dev_attr.attr,
+	&iio_dev_attr_v7_low.dev_attr.attr,
+	&iio_dev_attr_v7_hyst.dev_attr.attr,
 	NULL,
 };
 
@@ -904,6 +778,12 @@
 	.attrs = ad7291_event_attributes,
 };
 
+static const struct iio_info ad7291_info = {
+	.attrs = &ad7291_attribute_group,
+	.num_interrupt_lines = 1,
+	.event_attrs = &ad7291_event_attribute_group,
+};
+
 /*
  * device probe and remove
  */
@@ -923,21 +803,18 @@
 	i2c_set_clientdata(client, chip);
 
 	chip->client = client;
-	chip->name = id->name;
 	chip->command = AD7291_NOISE_DELAY | AD7291_T_SENSE_MASK;
 
-	chip->indio_dev = iio_allocate_device();
+	chip->indio_dev = iio_allocate_device(0);
 	if (chip->indio_dev == NULL) {
 		ret = -ENOMEM;
 		goto error_free_chip;
 	}
 
+	chip->indio_dev->name = id->name;
 	chip->indio_dev->dev.parent = &client->dev;
-	chip->indio_dev->attrs = &ad7291_attribute_group;
-	chip->indio_dev->event_attrs = &ad7291_event_attribute_group;
+	chip->indio_dev->info = &ad7291_info;
 	chip->indio_dev->dev_data = (void *)chip;
-	chip->indio_dev->driver_module = THIS_MODULE;
-	chip->indio_dev->num_interrupt_lines = 1;
 	chip->indio_dev->modes = INDIO_DIRECT_MODE;
 
 	ret = iio_device_register(chip->indio_dev);
@@ -945,24 +822,15 @@
 		goto error_free_dev;
 
 	if (client->irq > 0) {
-		ret = iio_register_interrupt_line(client->irq,
-				chip->indio_dev,
-				0,
-				IRQF_TRIGGER_LOW,
-				chip->name);
+		ret = request_threaded_irq(client->irq,
+					   NULL,
+					   &ad7291_event_handler,
+					   IRQF_TRIGGER_LOW | IRQF_ONESHOT,
+					   id->name,
+					   chip->indio_dev);
 		if (ret)
 			goto error_unreg_dev;
 
-		/*
-		 * The event handler list element refer to iio_event_ad7291.
-		 * All event attributes bind to the same event handler.
-		 * So, only register event handler once.
-		 */
-		iio_add_event_to_list(&iio_event_ad7291,
-				&chip->indio_dev->interrupts[0]->ev_list);
-
-		INIT_WORK(&chip->thresh_work, ad7291_interrupt_bh);
-
 		/* set irq polarity low level */
 		chip->command |= AD7291_ALART_POLARITY;
 	}
@@ -979,7 +847,7 @@
 	return 0;
 
 error_unreg_irq:
-	iio_unregister_interrupt_line(chip->indio_dev, 0);
+	free_irq(client->irq, chip->indio_dev);
 error_unreg_dev:
 	iio_device_unregister(chip->indio_dev);
 error_free_dev:
@@ -996,7 +864,7 @@
 	struct iio_dev *indio_dev = chip->indio_dev;
 
 	if (client->irq)
-		iio_unregister_interrupt_line(indio_dev, 0);
+		free_irq(client->irq, chip->indio_dev);
 	iio_device_unregister(indio_dev);
 	iio_free_device(chip->indio_dev);
 	kfree(chip);
diff -druN linux-2.6.39-libre/drivers/staging/iio/adc/ad7298_core.c linux-3.0-rc7-libre/drivers/staging/iio/adc/ad7298_core.c
--- linux-2.6.39-libre/drivers/staging/iio/adc/ad7298_core.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/iio/adc/ad7298_core.c	2011-07-11 19:51:52.000000000 -0400
@@ -6,7 +6,6 @@
  * Licensed under the GPL-2.
  */
 
-#include <linux/workqueue.h>
 #include <linux/device.h>
 #include <linux/kernel.h>
 #include <linux/slab.h>
@@ -23,6 +22,37 @@
 
 #include "ad7298.h"
 
+static struct iio_chan_spec ad7298_channels[] = {
+	IIO_CHAN(IIO_TEMP, 0, 1, 0, NULL, 0, 0,
+		 (1 << IIO_CHAN_INFO_SCALE_SEPARATE),
+		 9, AD7298_CH_TEMP, IIO_ST('s', 32, 32, 0), 0),
+	IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 0, 0,
+		 (1 << IIO_CHAN_INFO_SCALE_SHARED),
+		 0, 0, IIO_ST('u', 12, 16, 0), 0),
+	IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 1, 0,
+		 (1 << IIO_CHAN_INFO_SCALE_SHARED),
+		 1, 1, IIO_ST('u', 12, 16, 0), 0),
+	IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 2, 0,
+		 (1 << IIO_CHAN_INFO_SCALE_SHARED),
+		 2, 2, IIO_ST('u', 12, 16, 0), 0),
+	IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 3, 0,
+		 (1 << IIO_CHAN_INFO_SCALE_SHARED),
+		 3, 3, IIO_ST('u', 12, 16, 0), 0),
+	IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 4, 0,
+		 (1 << IIO_CHAN_INFO_SCALE_SHARED),
+		 4, 4, IIO_ST('u', 12, 16, 0), 0),
+	IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 5, 0,
+		 (1 << IIO_CHAN_INFO_SCALE_SHARED),
+		 5, 5, IIO_ST('u', 12, 16, 0), 0),
+	IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 6, 0,
+		 (1 << IIO_CHAN_INFO_SCALE_SHARED),
+		 6, 6, IIO_ST('u', 12, 16, 0), 0),
+	IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 7, 0,
+		 (1 << IIO_CHAN_INFO_SCALE_SHARED),
+		 7, 7, IIO_ST('u', 12, 16, 0), 0),
+	IIO_CHAN_SOFT_TIMESTAMP(8),
+};
+
 static int ad7298_scan_direct(struct ad7298_state *st, unsigned ch)
 {
 	int ret;
@@ -36,55 +66,28 @@
 	return be16_to_cpu(st->rx_buf[0]);
 }
 
-static ssize_t ad7298_scan(struct device *dev,
-			    struct device_attribute *attr,
-			    char *buf)
+static int ad7298_scan_temp(struct ad7298_state *st, int *val)
 {
-	struct iio_dev *dev_info = dev_get_drvdata(dev);
-	struct ad7298_state *st = dev_info->dev_data;
-	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
-	int ret;
+	int tmp, ret;
 
-	mutex_lock(&dev_info->mlock);
-	if (iio_ring_enabled(dev_info))
-		ret = ad7298_scan_from_ring(st, this_attr->address);
-	else
-		ret = ad7298_scan_direct(st, this_attr->address);
-	mutex_unlock(&dev_info->mlock);
+	tmp = cpu_to_be16(AD7298_WRITE | AD7298_TSENSE |
+			  AD7298_TAVG | st->ext_ref);
 
-	if (ret < 0)
+	ret = spi_write(st->spi, (u8 *)&tmp, 2);
+	if (ret)
 		return ret;
 
-	return sprintf(buf, "%d\n", ret & RES_MASK(AD7298_BITS));
-}
-
-static IIO_DEV_ATTR_IN_RAW(0, ad7298_scan, 0);
-static IIO_DEV_ATTR_IN_RAW(1, ad7298_scan, 1);
-static IIO_DEV_ATTR_IN_RAW(2, ad7298_scan, 2);
-static IIO_DEV_ATTR_IN_RAW(3, ad7298_scan, 3);
-static IIO_DEV_ATTR_IN_RAW(4, ad7298_scan, 4);
-static IIO_DEV_ATTR_IN_RAW(5, ad7298_scan, 5);
-static IIO_DEV_ATTR_IN_RAW(6, ad7298_scan, 6);
-static IIO_DEV_ATTR_IN_RAW(7, ad7298_scan, 7);
-
-static ssize_t ad7298_show_temp(struct device *dev,
-				struct device_attribute *attr,
-				char *buf)
-{
-	struct iio_dev *dev_info = dev_get_drvdata(dev);
-	struct ad7298_state *st = iio_dev_get_devdata(dev_info);
-	int tmp;
+	tmp = 0;
 
-	tmp = cpu_to_be16(AD7298_WRITE | AD7298_TSENSE |
-			  AD7298_TAVG | st->ext_ref);
+	ret = spi_write(st->spi, (u8 *)&tmp, 2);
+	if (ret)
+		return ret;
 
-	mutex_lock(&dev_info->mlock);
-	spi_write(st->spi, (u8 *)&tmp, 2);
-	tmp = 0;
-	spi_write(st->spi, (u8 *)&tmp, 2);
 	usleep_range(101, 1000); /* sleep > 100us */
-	spi_read(st->spi, (u8 *)&tmp, 2);
-	mutex_unlock(&dev_info->mlock);
+
+	ret = spi_read(st->spi, (u8 *)&tmp, 2);
+	if (ret)
+		return ret;
 
 	tmp = be16_to_cpu(tmp) & RES_MASK(AD7298_BITS);
 
@@ -101,65 +104,74 @@
 		tmp *= 250; /* temperature in milli degrees Celsius */
 	}
 
-	return sprintf(buf, "%d\n", tmp);
-}
+	*val = tmp;
 
-static IIO_DEVICE_ATTR(temp0_input, S_IRUGO, ad7298_show_temp, NULL, 0);
+	return 0;
+}
 
-static ssize_t ad7298_show_scale(struct device *dev,
-				struct device_attribute *attr,
-				char *buf)
+static int ad7298_read_raw(struct iio_dev *dev_info,
+			   struct iio_chan_spec const *chan,
+			   int *val,
+			   int *val2,
+			   long m)
 {
-	struct iio_dev *dev_info = dev_get_drvdata(dev);
-	struct ad7298_state *st = iio_dev_get_devdata(dev_info);
-	/* Corresponds to Vref / 2^(bits) */
-	unsigned int scale_uv = (st->int_vref_mv * 1000) >> AD7298_BITS;
+	int ret;
+	struct ad7298_state *st = iio_priv(dev_info);
+	unsigned int scale_uv;
 
-	return sprintf(buf, "%d.%03d\n", scale_uv / 1000, scale_uv % 1000);
-}
-static IIO_DEVICE_ATTR(in_scale, S_IRUGO, ad7298_show_scale, NULL, 0);
+	switch (m) {
+	case 0:
+		mutex_lock(&dev_info->mlock);
+		if (iio_ring_enabled(dev_info)) {
+			if (chan->address == AD7298_CH_TEMP)
+				ret = -ENODEV;
+			else
+				ret = ad7298_scan_from_ring(dev_info,
+							    chan->address);
+		} else {
+			if (chan->address == AD7298_CH_TEMP)
+				ret = ad7298_scan_temp(st, val);
+			else
+				ret = ad7298_scan_direct(st, chan->address);
+		}
+		mutex_unlock(&dev_info->mlock);
 
-static ssize_t ad7298_show_name(struct device *dev,
-				 struct device_attribute *attr,
-				 char *buf)
-{
-	struct iio_dev *dev_info = dev_get_drvdata(dev);
-	struct ad7298_state *st = iio_dev_get_devdata(dev_info);
+		if (ret < 0)
+			return ret;
 
-	return sprintf(buf, "%s\n", spi_get_device_id(st->spi)->name);
-}
-static IIO_DEVICE_ATTR(name, S_IRUGO, ad7298_show_name, NULL, 0);
+		if (chan->address != AD7298_CH_TEMP)
+			*val = ret & RES_MASK(AD7298_BITS);
 
-static struct attribute *ad7298_attributes[] = {
-	&iio_dev_attr_in0_raw.dev_attr.attr,
-	&iio_dev_attr_in1_raw.dev_attr.attr,
-	&iio_dev_attr_in2_raw.dev_attr.attr,
-	&iio_dev_attr_in3_raw.dev_attr.attr,
-	&iio_dev_attr_in4_raw.dev_attr.attr,
-	&iio_dev_attr_in5_raw.dev_attr.attr,
-	&iio_dev_attr_in6_raw.dev_attr.attr,
-	&iio_dev_attr_in7_raw.dev_attr.attr,
-	&iio_dev_attr_in_scale.dev_attr.attr,
-	&iio_dev_attr_temp0_input.dev_attr.attr,
-	&iio_dev_attr_name.dev_attr.attr,
-	NULL,
-};
+		return IIO_VAL_INT;
+	case (1 << IIO_CHAN_INFO_SCALE_SHARED):
+		scale_uv = (st->int_vref_mv * 1000) >> AD7298_BITS;
+		*val =  scale_uv / 1000;
+		*val2 = (scale_uv % 1000) * 1000;
+		return IIO_VAL_INT_PLUS_MICRO;
+	case (1 << IIO_CHAN_INFO_SCALE_SEPARATE):
+		*val =  1;
+		*val2 = 0;
+		return IIO_VAL_INT_PLUS_MICRO;
+	}
+	return -EINVAL;
+}
 
-static const struct attribute_group ad7298_attribute_group = {
-	.attrs = ad7298_attributes,
+static const struct iio_info ad7298_info = {
+	.read_raw = &ad7298_read_raw,
+	.driver_module = THIS_MODULE,
 };
 
 static int __devinit ad7298_probe(struct spi_device *spi)
 {
 	struct ad7298_platform_data *pdata = spi->dev.platform_data;
 	struct ad7298_state *st;
-	int ret;
+	int ret, regdone = 0;
+	struct iio_dev *indio_dev = iio_allocate_device(sizeof(*st));
 
-	st = kzalloc(sizeof(*st), GFP_KERNEL);
-	if (st == NULL) {
-		ret = -ENOMEM;
-		goto error_ret;
-	}
+	if (indio_dev == NULL)
+		return -ENOMEM;
+
+	st = iio_priv(indio_dev);
 
 	st->reg = regulator_get(&spi->dev, "vcc");
 	if (!IS_ERR(st->reg)) {
@@ -168,22 +180,16 @@
 			goto error_put_reg;
 	}
 
-	spi_set_drvdata(spi, st);
+	spi_set_drvdata(spi, indio_dev);
 
-	atomic_set(&st->protect_ring, 0);
 	st->spi = spi;
 
-	st->indio_dev = iio_allocate_device();
-	if (st->indio_dev == NULL) {
-		ret = -ENOMEM;
-		goto error_disable_reg;
-	}
-
-	st->indio_dev->dev.parent = &spi->dev;
-	st->indio_dev->attrs = &ad7298_attribute_group;
-	st->indio_dev->dev_data = (void *)(st);
-	st->indio_dev->driver_module = THIS_MODULE;
-	st->indio_dev->modes = INDIO_DIRECT_MODE;
+	indio_dev->name = spi_get_device_id(spi)->name;
+	indio_dev->dev.parent = &spi->dev;
+	indio_dev->modes = INDIO_DIRECT_MODE;
+	indio_dev->channels = ad7298_channels;
+	indio_dev->num_channels = ARRAY_SIZE(ad7298_channels);
+	indio_dev->info = &ad7298_info;
 
 	/* Setup default message */
 
@@ -208,39 +214,44 @@
 		st->int_vref_mv = AD7298_INTREF_mV;
 	}
 
-	ret = ad7298_register_ring_funcs_and_init(st->indio_dev);
+	ret = ad7298_register_ring_funcs_and_init(indio_dev);
 	if (ret)
-		goto error_free_device;
+		goto error_disable_reg;
 
-	ret = iio_device_register(st->indio_dev);
+	ret = iio_device_register(indio_dev);
 	if (ret)
-		goto error_free_device;
+		goto error_disable_reg;
+	regdone = 1;
 
-	ret = iio_ring_buffer_register(st->indio_dev->ring, 0);
+	ret = iio_ring_buffer_register_ex(indio_dev->ring, 0,
+					  &ad7298_channels[1], /* skip temp0 */
+					  ARRAY_SIZE(ad7298_channels) - 1);
 	if (ret)
 		goto error_cleanup_ring;
+
 	return 0;
 
 error_cleanup_ring:
-	ad7298_ring_cleanup(st->indio_dev);
-	iio_device_unregister(st->indio_dev);
-error_free_device:
-	iio_free_device(st->indio_dev);
+	ad7298_ring_cleanup(indio_dev);
 error_disable_reg:
 	if (!IS_ERR(st->reg))
 		regulator_disable(st->reg);
 error_put_reg:
 	if (!IS_ERR(st->reg))
 		regulator_put(st->reg);
-	kfree(st);
-error_ret:
+
+	if (regdone)
+		iio_device_unregister(indio_dev);
+	else
+		iio_free_device(indio_dev);
+
 	return ret;
 }
 
 static int __devexit ad7298_remove(struct spi_device *spi)
 {
-	struct ad7298_state *st = spi_get_drvdata(spi);
-	struct iio_dev *indio_dev = st->indio_dev;
+	struct iio_dev *indio_dev = spi_get_drvdata(spi);
+	struct ad7298_state *st = iio_priv(indio_dev);
 
 	iio_ring_buffer_unregister(indio_dev->ring);
 	ad7298_ring_cleanup(indio_dev);
@@ -249,7 +260,8 @@
 		regulator_disable(st->reg);
 		regulator_put(st->reg);
 	}
-	kfree(st);
+	iio_device_unregister(indio_dev);
+
 	return 0;
 }
 
diff -druN linux-2.6.39-libre/drivers/staging/iio/adc/ad7298.h linux-3.0-rc7-libre/drivers/staging/iio/adc/ad7298.h
--- linux-2.6.39-libre/drivers/staging/iio/adc/ad7298.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/iio/adc/ad7298.h	2011-07-11 19:51:52.000000000 -0400
@@ -17,14 +17,13 @@
 #define AD7298_TAVG	(1 << 1) /* temperature sensor averaging enable */
 #define AD7298_PDD	(1 << 0) /* partial power down enable */
 
-#define AD7298_CH_MASK	(AD7298_CH0 | AD7298_CH1 | AD7298_CH2 | AD7298_CH3 | \
-			AD7298_CH4 | AD7298_CH5 | AD7298_CH6 | AD7298_CH7)
-
 #define AD7298_MAX_CHAN		8
 #define AD7298_BITS		12
 #define AD7298_STORAGE_BITS	16
 #define AD7298_INTREF_mV	2500
 
+#define AD7298_CH_TEMP		9
+
 #define RES_MASK(bits)	((1 << (bits)) - 1)
 
 /*
@@ -37,11 +36,8 @@
 };
 
 struct ad7298_state {
-	struct iio_dev			*indio_dev;
 	struct spi_device		*spi;
 	struct regulator		*reg;
-	struct work_struct		poll_work;
-	atomic_t			protect_ring;
 	size_t				d_size;
 	u16				int_vref_mv;
 	unsigned			ext_ref;
@@ -58,11 +54,11 @@
 };
 
 #ifdef CONFIG_IIO_RING_BUFFER
-int ad7298_scan_from_ring(struct ad7298_state *st, long ch);
+int ad7298_scan_from_ring(struct iio_dev *indio_dev, long ch);
 int ad7298_register_ring_funcs_and_init(struct iio_dev *indio_dev);
 void ad7298_ring_cleanup(struct iio_dev *indio_dev);
 #else /* CONFIG_IIO_RING_BUFFER */
-static inline int ad7298_scan_from_ring(struct ad7298_state *st, long ch)
+static inline int ad7298_scan_from_ring(struct iio_dev *indio_dev, long ch)
 {
 	return 0;
 }
diff -druN linux-2.6.39-libre/drivers/staging/iio/adc/ad7298_ring.c linux-3.0-rc7-libre/drivers/staging/iio/adc/ad7298_ring.c
--- linux-2.6.39-libre/drivers/staging/iio/adc/ad7298_ring.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/iio/adc/ad7298_ring.c	2011-07-11 19:51:52.000000000 -0400
@@ -7,7 +7,6 @@
  */
 
 #include <linux/interrupt.h>
-#include <linux/workqueue.h>
 #include <linux/device.h>
 #include <linux/kernel.h>
 #include <linux/slab.h>
@@ -22,52 +21,9 @@
 
 #include "ad7298.h"
 
-static IIO_SCAN_EL_C(in0, 0, 0, NULL);
-static IIO_SCAN_EL_C(in1, 1, 0, NULL);
-static IIO_SCAN_EL_C(in2, 2, 0, NULL);
-static IIO_SCAN_EL_C(in3, 3, 0, NULL);
-static IIO_SCAN_EL_C(in4, 4, 0, NULL);
-static IIO_SCAN_EL_C(in5, 5, 0, NULL);
-static IIO_SCAN_EL_C(in6, 6, 0, NULL);
-static IIO_SCAN_EL_C(in7, 7, 0, NULL);
-
-static IIO_SCAN_EL_TIMESTAMP(8);
-static IIO_CONST_ATTR_SCAN_EL_TYPE(timestamp, s, 64, 64);
-
-static IIO_CONST_ATTR(in_type, "u12/16") ;
-
-static struct attribute *ad7298_scan_el_attrs[] = {
-	&iio_scan_el_in0.dev_attr.attr,
-	&iio_const_attr_in0_index.dev_attr.attr,
-	&iio_scan_el_in1.dev_attr.attr,
-	&iio_const_attr_in1_index.dev_attr.attr,
-	&iio_scan_el_in2.dev_attr.attr,
-	&iio_const_attr_in2_index.dev_attr.attr,
-	&iio_scan_el_in3.dev_attr.attr,
-	&iio_const_attr_in3_index.dev_attr.attr,
-	&iio_scan_el_in4.dev_attr.attr,
-	&iio_const_attr_in4_index.dev_attr.attr,
-	&iio_scan_el_in5.dev_attr.attr,
-	&iio_const_attr_in5_index.dev_attr.attr,
-	&iio_scan_el_in6.dev_attr.attr,
-	&iio_const_attr_in6_index.dev_attr.attr,
-	&iio_scan_el_in7.dev_attr.attr,
-	&iio_const_attr_in7_index.dev_attr.attr,
-	&iio_const_attr_timestamp_index.dev_attr.attr,
-	&iio_scan_el_timestamp.dev_attr.attr,
-	&iio_const_attr_timestamp_type.dev_attr.attr,
-	&iio_const_attr_in_type.dev_attr.attr,
-	NULL,
-};
-
-static struct attribute_group ad7298_scan_el_group = {
-	.name = "scan_elements",
-	.attrs = ad7298_scan_el_attrs,
-};
-
-int ad7298_scan_from_ring(struct ad7298_state *st, long ch)
+int ad7298_scan_from_ring(struct iio_dev *dev_info, long ch)
 {
-	struct iio_ring_buffer *ring = st->indio_dev->ring;
+	struct iio_ring_buffer *ring = dev_info->ring;
 	int ret;
 	u16 *ring_data;
 
@@ -76,12 +32,13 @@
 		goto error_ret;
 	}
 
-	ring_data = kmalloc(ring->access.get_bytes_per_datum(ring), GFP_KERNEL);
+	ring_data = kmalloc(ring->access->get_bytes_per_datum(ring),
+			    GFP_KERNEL);
 	if (ring_data == NULL) {
 		ret = -ENOMEM;
 		goto error_ret;
 	}
-	ret = ring->access.read_last(ring, (u8 *) ring_data);
+	ret = ring->access->read_last(ring, (u8 *) ring_data);
 	if (ret)
 		goto error_free_ring_data;
 
@@ -102,7 +59,7 @@
  **/
 static int ad7298_ring_preenable(struct iio_dev *indio_dev)
 {
-	struct ad7298_state *st = indio_dev->dev_data;
+	struct ad7298_state *st = iio_priv(indio_dev);
 	struct iio_ring_buffer *ring = indio_dev->ring;
 	size_t d_size;
 	int i, m;
@@ -117,8 +74,8 @@
 			d_size += sizeof(s64) - (d_size % sizeof(s64));
 	}
 
-	if (ring->access.set_bytes_per_datum)
-		ring->access.set_bytes_per_datum(ring, d_size);
+	if (ring->access->set_bytes_per_datum)
+		ring->access->set_bytes_per_datum(ring, d_size);
 
 	st->d_size = d_size;
 
@@ -155,47 +112,24 @@
 }
 
 /**
- * ad7298_poll_func_th() th of trigger launched polling to ring buffer
- *
- * As sampling only occurs on spi comms occurring, leave timestamping until
- * then.  Some triggers will generate their own time stamp.  Currently
- * there is no way of notifying them when no one cares.
- **/
-static void ad7298_poll_func_th(struct iio_dev *indio_dev, s64 time)
-{
-	struct ad7298_state *st = indio_dev->dev_data;
-
-	schedule_work(&st->poll_work);
-	return;
-}
-
-/**
- * ad7298_poll_bh_to_ring() bh of trigger launched polling to ring buffer
- * @work_s:	the work struct through which this was scheduled
+ * ad7298_trigger_handler() bh of trigger launched polling to ring buffer
  *
  * Currently there is no option in this driver to disable the saving of
  * timestamps within the ring.
- * I think the one copy of this at a time was to avoid problems if the
- * trigger was set far too high and the reads then locked up the computer.
  **/
-static void ad7298_poll_bh_to_ring(struct work_struct *work_s)
+static irqreturn_t ad7298_trigger_handler(int irq, void *p)
 {
-	struct ad7298_state *st = container_of(work_s, struct ad7298_state,
-						  poll_work);
-	struct iio_dev *indio_dev = st->indio_dev;
-	struct iio_sw_ring_buffer *sw_ring = iio_to_sw_ring(indio_dev->ring);
+	struct iio_poll_func *pf = p;
+	struct iio_dev *indio_dev = pf->private_data;
+	struct ad7298_state *st = iio_priv(indio_dev);
 	struct iio_ring_buffer *ring = indio_dev->ring;
 	s64 time_ns;
 	__u16 buf[16];
 	int b_sent, i;
 
-	/* Ensure only one copy of this function running at a time */
-	if (atomic_inc_return(&st->protect_ring) > 1)
-		return;
-
 	b_sent = spi_sync(st->spi, &st->ring_msg);
 	if (b_sent)
-		goto done;
+		return b_sent;
 
 	if (ring->scan_timestamp) {
 		time_ns = iio_get_time_ns();
@@ -206,14 +140,20 @@
 	for (i = 0; i < ring->scan_count; i++)
 		buf[i] = be16_to_cpu(st->rx_buf[i]);
 
-	indio_dev->ring->access.store_to(&sw_ring->buf, (u8 *)buf, time_ns);
-done:
-	atomic_dec(&st->protect_ring);
+	indio_dev->ring->access->store_to(ring, (u8 *)buf, time_ns);
+	iio_trigger_notify_done(indio_dev->trig);
+
+	return IRQ_HANDLED;
 }
 
+static const struct iio_ring_setup_ops ad7298_ring_setup_ops = {
+	.preenable = &ad7298_ring_preenable,
+	.postenable = &iio_triggered_ring_postenable,
+	.predisable = &iio_triggered_ring_predisable,
+};
+
 int ad7298_register_ring_funcs_and_init(struct iio_dev *indio_dev)
 {
-	struct ad7298_state *st = indio_dev->dev_data;
 	int ret;
 
 	indio_dev->ring = iio_sw_rb_allocate(indio_dev);
@@ -222,24 +162,28 @@
 		goto error_ret;
 	}
 	/* Effectively select the ring buffer implementation */
-	iio_ring_sw_register_funcs(&indio_dev->ring->access);
-	ret = iio_alloc_pollfunc(indio_dev, NULL, &ad7298_poll_func_th);
-	if (ret)
+	indio_dev->ring->access = &ring_sw_access_funcs;
+
+	indio_dev->pollfunc = iio_alloc_pollfunc(NULL,
+						 &ad7298_trigger_handler,
+						 IRQF_ONESHOT,
+						 indio_dev,
+						 "ad7298_consumer%d",
+						 indio_dev->id);
+
+	if (indio_dev->pollfunc == NULL) {
+		ret = -ENOMEM;
 		goto error_deallocate_sw_rb;
+	}
 
 	/* Ring buffer functions - here trigger setup related */
-
-	indio_dev->ring->preenable = &ad7298_ring_preenable;
-	indio_dev->ring->postenable = &iio_triggered_ring_postenable;
-	indio_dev->ring->predisable = &iio_triggered_ring_predisable;
-	indio_dev->ring->scan_el_attrs = &ad7298_scan_el_group;
+	indio_dev->ring->setup_ops = &ad7298_ring_setup_ops;
 	indio_dev->ring->scan_timestamp = true;
 
-	INIT_WORK(&st->poll_work, &ad7298_poll_bh_to_ring);
-
 	/* Flag that polled ring buffering is possible */
 	indio_dev->modes |= INDIO_RING_TRIGGERED;
 	return 0;
+
 error_deallocate_sw_rb:
 	iio_sw_rb_free(indio_dev->ring);
 error_ret:
@@ -253,6 +197,6 @@
 		iio_trigger_dettach_poll_func(indio_dev->trig,
 					      indio_dev->pollfunc);
 	}
-	kfree(indio_dev->pollfunc);
+	iio_dealloc_pollfunc(indio_dev->pollfunc);
 	iio_sw_rb_free(indio_dev->ring);
 }
diff -druN linux-2.6.39-libre/drivers/staging/iio/adc/ad7314.c linux-3.0-rc7-libre/drivers/staging/iio/adc/ad7314.c
--- linux-2.6.39-libre/drivers/staging/iio/adc/ad7314.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/iio/adc/ad7314.c	2011-07-11 19:51:52.000000000 -0400
@@ -6,16 +6,11 @@
  * Licensed under the GPL-2 or later.
  */
 
-#include <linux/interrupt.h>
-#include <linux/gpio.h>
-#include <linux/workqueue.h>
 #include <linux/device.h>
 #include <linux/kernel.h>
 #include <linux/slab.h>
 #include <linux/sysfs.h>
-#include <linux/list.h>
 #include <linux/spi/spi.h>
-#include <linux/rtc.h>
 
 #include "../iio.h"
 #include "../sysfs.h"
@@ -47,7 +42,6 @@
  */
 
 struct ad7314_chip_info {
-	const char *name;
 	struct spi_device *spi_dev;
 	struct iio_dev *indio_dev;
 	s64 last_timestamp;
@@ -160,7 +154,7 @@
 	if (chip->mode)
 		ad7314_spi_write(chip, chip->mode);
 
-	if (strcmp(chip->name, "ad7314")) {
+	if (strcmp(dev_info->name, "ad7314")) {
 		data = (data & AD7314_TEMP_MASK) >>
 			AD7314_TEMP_OFFSET;
 		if (data & AD7314_TEMP_SIGN) {
@@ -186,22 +180,10 @@
 
 static IIO_DEVICE_ATTR(temperature, S_IRUGO, ad7314_show_temperature, NULL, 0);
 
-static ssize_t ad7314_show_name(struct device *dev,
-		struct device_attribute *attr,
-		char *buf)
-{
-	struct iio_dev *dev_info = dev_get_drvdata(dev);
-	struct ad7314_chip_info *chip = dev_info->dev_data;
-	return sprintf(buf, "%s\n", chip->name);
-}
-
-static IIO_DEVICE_ATTR(name, S_IRUGO, ad7314_show_name, NULL, 0);
-
 static struct attribute *ad7314_attributes[] = {
 	&iio_dev_attr_available_modes.dev_attr.attr,
 	&iio_dev_attr_mode.dev_attr.attr,
 	&iio_dev_attr_temperature.dev_attr.attr,
-	&iio_dev_attr_name.dev_attr.attr,
 	NULL,
 };
 
@@ -209,6 +191,10 @@
 	.attrs = ad7314_attributes,
 };
 
+static const struct iio_info ad7314_info = {
+	.attrs = &ad7314_attribute_group,
+	.driver_module = THIS_MODULE,
+};
 /*
  * device probe and remove
  */
@@ -227,25 +213,24 @@
 	dev_set_drvdata(&spi_dev->dev, chip);
 
 	chip->spi_dev = spi_dev;
-	chip->name = spi_dev->modalias;
 
-	chip->indio_dev = iio_allocate_device();
+	chip->indio_dev = iio_allocate_device(0);
 	if (chip->indio_dev == NULL) {
 		ret = -ENOMEM;
 		goto error_free_chip;
 	}
 
+	chip->indio_dev->name = spi_get_device_id(spi_dev)->name;
 	chip->indio_dev->dev.parent = &spi_dev->dev;
-	chip->indio_dev->attrs = &ad7314_attribute_group;
+	chip->indio_dev->info = &ad7314_info;
 	chip->indio_dev->dev_data = (void *)chip;
-	chip->indio_dev->driver_module = THIS_MODULE;
 
 	ret = iio_device_register(chip->indio_dev);
 	if (ret)
 		goto error_free_dev;
 
 	dev_info(&spi_dev->dev, "%s temperature sensor registered.\n",
-			 chip->name);
+			 chip->indio_dev->name);
 
 	return 0;
 error_free_dev:
@@ -262,8 +247,6 @@
 	struct iio_dev *indio_dev = chip->indio_dev;
 
 	dev_set_drvdata(&spi_dev->dev, NULL);
-	if (spi_dev->irq)
-		iio_unregister_interrupt_line(indio_dev, 0);
 	iio_device_unregister(indio_dev);
 	iio_free_device(chip->indio_dev);
 	kfree(chip);
diff -druN linux-2.6.39-libre/drivers/staging/iio/adc/ad7476_core.c linux-3.0-rc7-libre/drivers/staging/iio/adc/ad7476_core.c
--- linux-2.6.39-libre/drivers/staging/iio/adc/ad7476_core.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/iio/adc/ad7476_core.c	2011-07-11 19:51:52.000000000 -0400
@@ -6,13 +6,10 @@
  * Licensed under the GPL-2 or later.
  */
 
-#include <linux/interrupt.h>
-#include <linux/workqueue.h>
 #include <linux/device.h>
 #include <linux/kernel.h>
 #include <linux/slab.h>
 #include <linux/sysfs.h>
-#include <linux/list.h>
 #include <linux/spi/spi.h>
 #include <linux/regulator/consumer.h>
 #include <linux/err.h>
@@ -35,117 +32,97 @@
 	return (st->data[0] << 8) | st->data[1];
 }
 
-static ssize_t ad7476_scan(struct device *dev,
-			    struct device_attribute *attr,
-			    char *buf)
+static int ad7476_read_raw(struct iio_dev *dev_info,
+			   struct iio_chan_spec const *chan,
+			   int *val,
+			   int *val2,
+			   long m)
 {
-	struct iio_dev *dev_info = dev_get_drvdata(dev);
-	struct ad7476_state *st = dev_info->dev_data;
 	int ret;
+	struct ad7476_state *st = dev_info->dev_data;
+	unsigned int scale_uv;
 
-	mutex_lock(&dev_info->mlock);
-	if (iio_ring_enabled(dev_info))
-		ret = ad7476_scan_from_ring(st);
-	else
-		ret = ad7476_scan_direct(st);
-	mutex_unlock(&dev_info->mlock);
-
-	if (ret < 0)
-		return ret;
-
-	return sprintf(buf, "%d\n", (ret >> st->chip_info->res_shift) &
-		       RES_MASK(st->chip_info->bits));
-}
-static IIO_DEV_ATTR_IN_RAW(0, ad7476_scan, 0);
-
-static ssize_t ad7476_show_scale(struct device *dev,
-				struct device_attribute *attr,
-				char *buf)
-{
-	/* Driver currently only support internal vref */
-	struct iio_dev *dev_info = dev_get_drvdata(dev);
-	struct ad7476_state *st = iio_dev_get_devdata(dev_info);
-	/* Corresponds to Vref / 2^(bits) */
-	unsigned int scale_uv = (st->int_vref_mv * 1000) >> st->chip_info->bits;
-
-	return sprintf(buf, "%d.%03d\n", scale_uv / 1000, scale_uv % 1000);
-}
-static IIO_DEVICE_ATTR(in_scale, S_IRUGO, ad7476_show_scale, NULL, 0);
-
-static ssize_t ad7476_show_name(struct device *dev,
-				 struct device_attribute *attr,
-				 char *buf)
-{
-	struct iio_dev *dev_info = dev_get_drvdata(dev);
-	struct ad7476_state *st = iio_dev_get_devdata(dev_info);
+	switch (m) {
+	case 0:
+		mutex_lock(&dev_info->mlock);
+		if (iio_ring_enabled(dev_info))
+			ret = ad7476_scan_from_ring(st);
+		else
+			ret = ad7476_scan_direct(st);
+		mutex_unlock(&dev_info->mlock);
 
-	return sprintf(buf, "%s\n", spi_get_device_id(st->spi)->name);
+		if (ret < 0)
+			return ret;
+		*val = (ret >> st->chip_info->channel[0].scan_type.shift) &
+			RES_MASK(st->chip_info->channel[0].scan_type.realbits);
+		return IIO_VAL_INT;
+	case (1 << IIO_CHAN_INFO_SCALE_SHARED):
+		scale_uv = (st->int_vref_mv * 1000)
+			>> st->chip_info->channel[0].scan_type.realbits;
+		*val =  scale_uv/1000;
+		*val2 = (scale_uv%1000)*1000;
+		return IIO_VAL_INT_PLUS_MICRO;
+	}
+	return -EINVAL;
 }
-static IIO_DEVICE_ATTR(name, S_IRUGO, ad7476_show_name, NULL, 0);
-
-static struct attribute *ad7476_attributes[] = {
-	&iio_dev_attr_in0_raw.dev_attr.attr,
-	&iio_dev_attr_in_scale.dev_attr.attr,
-	&iio_dev_attr_name.dev_attr.attr,
-	NULL,
-};
-
-static const struct attribute_group ad7476_attribute_group = {
-	.attrs = ad7476_attributes,
-};
 
 static const struct ad7476_chip_info ad7476_chip_info_tbl[] = {
 	[ID_AD7466] = {
-		.bits = 12,
-		.storagebits = 16,
-		.res_shift = 0,
-		.sign = IIO_SCAN_EL_TYPE_UNSIGNED,
+		.channel[0] = IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 0, 0,
+				       (1 << IIO_CHAN_INFO_SCALE_SHARED),
+				       0, 0, IIO_ST('u', 12, 16, 0), 0),
+		.channel[1] = IIO_CHAN_SOFT_TIMESTAMP(1),
 	},
 	[ID_AD7467] = {
-		.bits = 10,
-		.storagebits = 16,
-		.res_shift = 2,
-		.sign = IIO_SCAN_EL_TYPE_UNSIGNED,
+		.channel[0] = IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 0, 0,
+				       (1 << IIO_CHAN_INFO_SCALE_SHARED),
+				       0, 0, IIO_ST('u', 10, 16, 2), 0),
+		.channel[1] = IIO_CHAN_SOFT_TIMESTAMP(1),
 	},
 	[ID_AD7468] = {
-		.bits = 8,
-		.storagebits = 16,
-		.res_shift = 4,
-		.sign = IIO_SCAN_EL_TYPE_UNSIGNED,
+		.channel[0] = IIO_CHAN(IIO_IN, 0, 1 , 0, NULL, 0, 0,
+				       (1 << IIO_CHAN_INFO_SCALE_SHARED),
+				       0, 0, IIO_ST('u', 8, 16, 4), 0),
+		.channel[1] = IIO_CHAN_SOFT_TIMESTAMP(1),
 	},
 	[ID_AD7475] = {
-		.bits = 12,
-		.storagebits = 16,
-		.res_shift = 0,
-		.sign = IIO_SCAN_EL_TYPE_UNSIGNED,
+		.channel[0] = IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 0, 0,
+				       (1 << IIO_CHAN_INFO_SCALE_SHARED),
+				       0, 0, IIO_ST('u', 12, 16, 0), 0),
+		.channel[1] = IIO_CHAN_SOFT_TIMESTAMP(1),
 	},
 	[ID_AD7476] = {
-		.bits = 12,
-		.storagebits = 16,
-		.res_shift = 0,
-		.sign = IIO_SCAN_EL_TYPE_UNSIGNED,
+		.channel[0] = IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 0, 0,
+				       (1 << IIO_CHAN_INFO_SCALE_SHARED),
+				       0, 0, IIO_ST('u', 12, 16, 0), 0),
+		.channel[1] = IIO_CHAN_SOFT_TIMESTAMP(1),
 	},
 	[ID_AD7477] = {
-		.bits = 10,
-		.storagebits = 16,
-		.res_shift = 2,
-		.sign = IIO_SCAN_EL_TYPE_UNSIGNED,
+		.channel[0] = IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 0, 0,
+				       (1 << IIO_CHAN_INFO_SCALE_SHARED),
+				       0, 0, IIO_ST('u', 10, 16, 2), 0),
+		.channel[1] = IIO_CHAN_SOFT_TIMESTAMP(1),
 	},
 	[ID_AD7478] = {
-		.bits = 8,
-		.storagebits = 16,
-		.res_shift = 4,
-		.sign = IIO_SCAN_EL_TYPE_UNSIGNED,
+		.channel[0] = IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 0, 0,
+				       (1 << IIO_CHAN_INFO_SCALE_SHARED),
+				       0, 0, IIO_ST('u', 8, 16, 4), 0),
+		.channel[1] = IIO_CHAN_SOFT_TIMESTAMP(1),
 	},
 	[ID_AD7495] = {
-		.bits = 12,
-		.storagebits = 16,
-		.res_shift = 0,
+		.channel[0] = IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 0, 0,
+				       (1 << IIO_CHAN_INFO_SCALE_SHARED),
+				       0, 0, IIO_ST('u', 12, 16, 0), 0),
+		.channel[1] = IIO_CHAN_SOFT_TIMESTAMP(1),
 		.int_vref_mv = 2500,
-		.sign = IIO_SCAN_EL_TYPE_UNSIGNED,
 	},
 };
 
+static const struct iio_info ad7476_info = {
+	.driver_module = THIS_MODULE,
+	.read_raw = &ad7476_read_raw,
+};
+
 static int __devinit ad7476_probe(struct spi_device *spi)
 {
 	struct ad7476_platform_data *pdata = spi->dev.platform_data;
@@ -181,10 +158,9 @@
 
 	spi_set_drvdata(spi, st);
 
-	atomic_set(&st->protect_ring, 0);
 	st->spi = spi;
 
-	st->indio_dev = iio_allocate_device();
+	st->indio_dev = iio_allocate_device(0);
 	if (st->indio_dev == NULL) {
 		ret = -ENOMEM;
 		goto error_disable_reg;
@@ -192,15 +168,16 @@
 
 	/* Establish that the iio_dev is a child of the spi device */
 	st->indio_dev->dev.parent = &spi->dev;
-	st->indio_dev->attrs = &ad7476_attribute_group;
+	st->indio_dev->name = spi_get_device_id(spi)->name;
 	st->indio_dev->dev_data = (void *)(st);
-	st->indio_dev->driver_module = THIS_MODULE;
 	st->indio_dev->modes = INDIO_DIRECT_MODE;
-
+	st->indio_dev->channels = st->chip_info->channel;
+	st->indio_dev->num_channels = 2;
+	st->indio_dev->info = &ad7476_info;
 	/* Setup default message */
 
 	st->xfer.rx_buf = &st->data;
-	st->xfer.len = st->chip_info->storagebits / 8;
+	st->xfer.len = st->chip_info->channel[0].scan_type.storagebits / 8;
 
 	spi_message_init(&st->msg);
 	spi_message_add_tail(&st->xfer, &st->msg);
@@ -213,7 +190,9 @@
 	if (ret)
 		goto error_free_device;
 
-	ret = iio_ring_buffer_register(st->indio_dev->ring, 0);
+	ret = iio_ring_buffer_register_ex(st->indio_dev->ring, 0,
+					  st->chip_info->channel,
+					  ARRAY_SIZE(st->chip_info->channel));
 	if (ret)
 		goto error_cleanup_ring;
 	return 0;
diff -druN linux-2.6.39-libre/drivers/staging/iio/adc/ad7476.h linux-3.0-rc7-libre/drivers/staging/iio/adc/ad7476.h
--- linux-2.6.39-libre/drivers/staging/iio/adc/ad7476.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/iio/adc/ad7476.h	2011-07-11 19:51:52.000000000 -0400
@@ -19,11 +19,8 @@
 };
 
 struct ad7476_chip_info {
-	u8				bits;
-	u8				storagebits;
-	u8				res_shift;
-	char				sign;
 	u16				int_vref_mv;
+	struct iio_chan_spec		channel[2];
 };
 
 struct ad7476_state {
@@ -31,8 +28,6 @@
 	struct spi_device		*spi;
 	const struct ad7476_chip_info	*chip_info;
 	struct regulator		*reg;
-	struct work_struct		poll_work;
-	atomic_t			protect_ring;
 	size_t				d_size;
 	u16				int_vref_mv;
 	struct spi_transfer		xfer;
diff -druN linux-2.6.39-libre/drivers/staging/iio/adc/ad7476_ring.c linux-3.0-rc7-libre/drivers/staging/iio/adc/ad7476_ring.c
--- linux-2.6.39-libre/drivers/staging/iio/adc/ad7476_ring.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/iio/adc/ad7476_ring.c	2011-07-11 19:51:52.000000000 -0400
@@ -8,13 +8,10 @@
  */
 
 #include <linux/interrupt.h>
-#include <linux/gpio.h>
-#include <linux/workqueue.h>
 #include <linux/device.h>
 #include <linux/kernel.h>
 #include <linux/slab.h>
 #include <linux/sysfs.h>
-#include <linux/list.h>
 #include <linux/spi/spi.h>
 
 #include "../iio.h"
@@ -25,51 +22,19 @@
 
 #include "ad7476.h"
 
-static IIO_SCAN_EL_C(in0, 0, 0, NULL);
-static IIO_SCAN_EL_TIMESTAMP(1);
-static IIO_CONST_ATTR_SCAN_EL_TYPE(timestamp, s, 64, 64);
-
-static ssize_t ad7476_show_type(struct device *dev,
-				struct device_attribute *attr,
-				char *buf)
-{
-	struct iio_ring_buffer *ring = dev_get_drvdata(dev);
-	struct iio_dev *indio_dev = ring->indio_dev;
-	struct ad7476_state *st = indio_dev->dev_data;
-
-	return sprintf(buf, "%c%d/%d>>%d\n", st->chip_info->sign,
-		       st->chip_info->bits, st->chip_info->storagebits,
-		       st->chip_info->res_shift);
-}
-static IIO_DEVICE_ATTR(in_type, S_IRUGO, ad7476_show_type, NULL, 0);
-
-static struct attribute *ad7476_scan_el_attrs[] = {
-	&iio_scan_el_in0.dev_attr.attr,
-	&iio_const_attr_in0_index.dev_attr.attr,
-	&iio_const_attr_timestamp_index.dev_attr.attr,
-	&iio_scan_el_timestamp.dev_attr.attr,
-	&iio_const_attr_timestamp_type.dev_attr.attr,
-	&iio_dev_attr_in_type.dev_attr.attr,
-	NULL,
-};
-
-static struct attribute_group ad7476_scan_el_group = {
-	.name = "scan_elements",
-	.attrs = ad7476_scan_el_attrs,
-};
-
 int ad7476_scan_from_ring(struct ad7476_state *st)
 {
 	struct iio_ring_buffer *ring = st->indio_dev->ring;
 	int ret;
 	u8 *ring_data;
 
-	ring_data = kmalloc(ring->access.get_bytes_per_datum(ring), GFP_KERNEL);
+	ring_data = kmalloc(ring->access->get_bytes_per_datum(ring),
+			    GFP_KERNEL);
 	if (ring_data == NULL) {
 		ret = -ENOMEM;
 		goto error_ret;
 	}
-	ret = ring->access.read_last(ring, ring_data);
+	ret = ring->access->read_last(ring, ring_data);
 	if (ret)
 		goto error_free_ring_data;
 
@@ -93,7 +58,8 @@
 	struct ad7476_state *st = indio_dev->dev_data;
 	struct iio_ring_buffer *ring = indio_dev->ring;
 
-	st->d_size = ring->scan_count * st->chip_info->storagebits / 8;
+	st->d_size = ring->scan_count *
+		st->chip_info->channel[0].scan_type.storagebits / 8;
 
 	if (ring->scan_timestamp) {
 		st->d_size += sizeof(s64);
@@ -102,55 +68,28 @@
 			st->d_size += sizeof(s64) - (st->d_size % sizeof(s64));
 	}
 
-	if (indio_dev->ring->access.set_bytes_per_datum)
-		indio_dev->ring->access.set_bytes_per_datum(indio_dev->ring,
+	if (indio_dev->ring->access->set_bytes_per_datum)
+		indio_dev->ring->access->set_bytes_per_datum(indio_dev->ring,
 							    st->d_size);
 
 	return 0;
 }
 
-/**
- * ad7476_poll_func_th() th of trigger launched polling to ring buffer
- *
- * As sampling only occurs on i2c comms occurring, leave timestamping until
- * then.  Some triggers will generate their own time stamp.  Currently
- * there is no way of notifying them when no one cares.
- **/
-static void ad7476_poll_func_th(struct iio_dev *indio_dev, s64 time)
-{
-	struct ad7476_state *st = indio_dev->dev_data;
-
-	schedule_work(&st->poll_work);
-	return;
-}
-/**
- * ad7476_poll_bh_to_ring() bh of trigger launched polling to ring buffer
- * @work_s:	the work struct through which this was scheduled
- *
- * Currently there is no option in this driver to disable the saving of
- * timestamps within the ring.
- * I think the one copy of this at a time was to avoid problems if the
- * trigger was set far too high and the reads then locked up the computer.
- **/
-static void ad7476_poll_bh_to_ring(struct work_struct *work_s)
+static irqreturn_t ad7476_trigger_handler(int irq, void  *p)
 {
-	struct ad7476_state *st = container_of(work_s, struct ad7476_state,
-						  poll_work);
-	struct iio_dev *indio_dev = st->indio_dev;
-	struct iio_sw_ring_buffer *sw_ring = iio_to_sw_ring(indio_dev->ring);
+	struct iio_poll_func *pf = p;
+	struct iio_dev *indio_dev = pf->private_data;
+	struct ad7476_state *st = iio_dev_get_devdata(indio_dev);
 	s64 time_ns;
 	__u8 *rxbuf;
 	int b_sent;
 
-	/* Ensure only one copy of this function running at a time */
-	if (atomic_inc_return(&st->protect_ring) > 1)
-		return;
-
 	rxbuf = kzalloc(st->d_size, GFP_KERNEL);
 	if (rxbuf == NULL)
-		return;
+		return -ENOMEM;
 
-	b_sent = spi_read(st->spi, rxbuf, st->chip_info->storagebits / 8);
+	b_sent = spi_read(st->spi, rxbuf,
+			  st->chip_info->channel[0].scan_type.storagebits / 8);
 	if (b_sent < 0)
 		goto done;
 
@@ -160,12 +99,20 @@
 		memcpy(rxbuf + st->d_size - sizeof(s64),
 			&time_ns, sizeof(time_ns));
 
-	indio_dev->ring->access.store_to(&sw_ring->buf, rxbuf, time_ns);
+	indio_dev->ring->access->store_to(indio_dev->ring, rxbuf, time_ns);
 done:
+	iio_trigger_notify_done(indio_dev->trig);
 	kfree(rxbuf);
-	atomic_dec(&st->protect_ring);
+
+	return IRQ_HANDLED;
 }
 
+static const struct iio_ring_setup_ops ad7476_ring_setup_ops = {
+	.preenable = &ad7476_ring_preenable,
+	.postenable = &iio_triggered_ring_postenable,
+	.predisable = &iio_triggered_ring_predisable,
+};
+
 int ad7476_register_ring_funcs_and_init(struct iio_dev *indio_dev)
 {
 	struct ad7476_state *st = indio_dev->dev_data;
@@ -177,24 +124,28 @@
 		goto error_ret;
 	}
 	/* Effectively select the ring buffer implementation */
-	iio_ring_sw_register_funcs(&indio_dev->ring->access);
-	ret = iio_alloc_pollfunc(indio_dev, NULL, &ad7476_poll_func_th);
-	if (ret)
+	indio_dev->ring->access = &ring_sw_access_funcs;
+	indio_dev->pollfunc
+		= iio_alloc_pollfunc(NULL,
+				     &ad7476_trigger_handler,
+				     IRQF_ONESHOT,
+				     indio_dev,
+				     "%s_consumer%d",
+				     spi_get_device_id(st->spi)->name,
+				     indio_dev->id);
+	if (indio_dev->pollfunc == NULL) {
+		ret = -ENOMEM;
 		goto error_deallocate_sw_rb;
+	}
 
 	/* Ring buffer functions - here trigger setup related */
-
-	indio_dev->ring->preenable = &ad7476_ring_preenable;
-	indio_dev->ring->postenable = &iio_triggered_ring_postenable;
-	indio_dev->ring->predisable = &iio_triggered_ring_predisable;
-	indio_dev->ring->scan_el_attrs = &ad7476_scan_el_group;
+	indio_dev->ring->setup_ops = &ad7476_ring_setup_ops;
 	indio_dev->ring->scan_timestamp = true;
 
-	INIT_WORK(&st->poll_work, &ad7476_poll_bh_to_ring);
-
 	/* Flag that polled ring buffering is possible */
 	indio_dev->modes |= INDIO_RING_TRIGGERED;
 	return 0;
+
 error_deallocate_sw_rb:
 	iio_sw_rb_free(indio_dev->ring);
 error_ret:
@@ -209,6 +160,6 @@
 		iio_trigger_dettach_poll_func(indio_dev->trig,
 					      indio_dev->pollfunc);
 	}
-	kfree(indio_dev->pollfunc);
+	iio_dealloc_pollfunc(indio_dev->pollfunc);
 	iio_sw_rb_free(indio_dev->ring);
 }
diff -druN linux-2.6.39-libre/drivers/staging/iio/adc/ad7606_core.c linux-3.0-rc7-libre/drivers/staging/iio/adc/ad7606_core.c
--- linux-2.6.39-libre/drivers/staging/iio/adc/ad7606_core.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/iio/adc/ad7606_core.c	2011-07-11 19:51:52.000000000 -0400
@@ -7,12 +7,10 @@
  */
 
 #include <linux/interrupt.h>
-#include <linux/workqueue.h>
 #include <linux/device.h>
 #include <linux/kernel.h>
 #include <linux/slab.h>
 #include <linux/sysfs.h>
-#include <linux/list.h>
 #include <linux/regulator/consumer.h>
 #include <linux/err.h>
 #include <linux/gpio.h>
@@ -38,8 +36,9 @@
 	return -ENODEV;
 }
 
-static int ad7606_scan_direct(struct ad7606_state *st, unsigned ch)
+static int ad7606_scan_direct(struct iio_dev *indio_dev, unsigned ch)
 {
+	struct ad7606_state *st = iio_priv(indio_dev);
 	int ret;
 
 	st->done = false;
@@ -78,67 +77,44 @@
 	return ret;
 }
 
-static ssize_t ad7606_scan(struct device *dev,
-			    struct device_attribute *attr,
-			    char *buf)
+static int ad7606_read_raw(struct iio_dev *indio_dev,
+			   struct iio_chan_spec const *chan,
+			   int *val,
+			   int *val2,
+			   long m)
 {
-	struct iio_dev *dev_info = dev_get_drvdata(dev);
-	struct ad7606_state *st = dev_info->dev_data;
-	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
 	int ret;
+	struct ad7606_state *st = iio_priv(indio_dev);
+	unsigned int scale_uv;
 
-	mutex_lock(&dev_info->mlock);
-	if (iio_ring_enabled(dev_info))
-		ret = ad7606_scan_from_ring(st, this_attr->address);
-	else
-		ret = ad7606_scan_direct(st, this_attr->address);
-	mutex_unlock(&dev_info->mlock);
-
-	if (ret < 0)
-		return ret;
-
-	return sprintf(buf, "%d\n", (short) ret);
-}
-
-static IIO_DEV_ATTR_IN_RAW(0, ad7606_scan, 0);
-static IIO_DEV_ATTR_IN_RAW(1, ad7606_scan, 1);
-static IIO_DEV_ATTR_IN_RAW(2, ad7606_scan, 2);
-static IIO_DEV_ATTR_IN_RAW(3, ad7606_scan, 3);
-static IIO_DEV_ATTR_IN_RAW(4, ad7606_scan, 4);
-static IIO_DEV_ATTR_IN_RAW(5, ad7606_scan, 5);
-static IIO_DEV_ATTR_IN_RAW(6, ad7606_scan, 6);
-static IIO_DEV_ATTR_IN_RAW(7, ad7606_scan, 7);
-
-static ssize_t ad7606_show_scale(struct device *dev,
-				struct device_attribute *attr,
-				char *buf)
-{
-	/* Driver currently only support internal vref */
-	struct iio_dev *dev_info = dev_get_drvdata(dev);
-	struct ad7606_state *st = iio_dev_get_devdata(dev_info);
-	unsigned int scale_uv = (st->range * 1000 * 2) >> st->chip_info->bits;
-
-	return sprintf(buf, "%d.%03d\n", scale_uv / 1000, scale_uv % 1000);
-}
-static IIO_DEVICE_ATTR(in_scale, S_IRUGO, ad7606_show_scale, NULL, 0);
-
-static ssize_t ad7606_show_name(struct device *dev,
-				 struct device_attribute *attr,
-				 char *buf)
-{
-	struct iio_dev *dev_info = dev_get_drvdata(dev);
-	struct ad7606_state *st = iio_dev_get_devdata(dev_info);
+	switch (m) {
+	case 0:
+		mutex_lock(&indio_dev->mlock);
+		if (iio_ring_enabled(indio_dev))
+			ret = ad7606_scan_from_ring(indio_dev, chan->address);
+		else
+			ret = ad7606_scan_direct(indio_dev, chan->address);
+		mutex_unlock(&indio_dev->mlock);
 
-	return sprintf(buf, "%s\n", st->chip_info->name);
+		if (ret < 0)
+			return ret;
+		*val = (short) ret;
+		return IIO_VAL_INT;
+	case (1 << IIO_CHAN_INFO_SCALE_SHARED):
+		scale_uv = (st->range * 1000 * 2)
+			>> st->chip_info->channels[0].scan_type.realbits;
+		*val =  scale_uv / 1000;
+		*val2 = (scale_uv % 1000) * 1000;
+		return IIO_VAL_INT_PLUS_MICRO;
+	}
+	return -EINVAL;
 }
 
-static IIO_DEVICE_ATTR(name, S_IRUGO, ad7606_show_name, NULL, 0);
-
 static ssize_t ad7606_show_range(struct device *dev,
 			struct device_attribute *attr, char *buf)
 {
-	struct iio_dev *dev_info = dev_get_drvdata(dev);
-	struct ad7606_state *st = iio_dev_get_devdata(dev_info);
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct ad7606_state *st = iio_priv(indio_dev);
 
 	return sprintf(buf, "%u\n", st->range);
 }
@@ -146,8 +122,8 @@
 static ssize_t ad7606_store_range(struct device *dev,
 		struct device_attribute *attr, const char *buf, size_t count)
 {
-	struct iio_dev *dev_info = dev_get_drvdata(dev);
-	struct ad7606_state *st = iio_dev_get_devdata(dev_info);
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct ad7606_state *st = iio_priv(indio_dev);
 	unsigned long lval;
 
 	if (strict_strtoul(buf, 10, &lval))
@@ -156,10 +132,10 @@
 		dev_err(dev, "range is not supported\n");
 		return -EINVAL;
 	}
-	mutex_lock(&dev_info->mlock);
+	mutex_lock(&indio_dev->mlock);
 	gpio_set_value(st->pdata->gpio_range, lval == 10000);
 	st->range = lval;
-	mutex_unlock(&dev_info->mlock);
+	mutex_unlock(&indio_dev->mlock);
 
 	return count;
 }
@@ -171,8 +147,8 @@
 static ssize_t ad7606_show_oversampling_ratio(struct device *dev,
 			struct device_attribute *attr, char *buf)
 {
-	struct iio_dev *dev_info = dev_get_drvdata(dev);
-	struct ad7606_state *st = iio_dev_get_devdata(dev_info);
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct ad7606_state *st = iio_priv(indio_dev);
 
 	return sprintf(buf, "%u\n", st->oversampling);
 }
@@ -192,8 +168,8 @@
 static ssize_t ad7606_store_oversampling_ratio(struct device *dev,
 		struct device_attribute *attr, const char *buf, size_t count)
 {
-	struct iio_dev *dev_info = dev_get_drvdata(dev);
-	struct ad7606_state *st = iio_dev_get_devdata(dev_info);
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct ad7606_state *st = iio_priv(indio_dev);
 	unsigned long lval;
 	int ret;
 
@@ -206,12 +182,12 @@
 		return ret;
 	}
 
-	mutex_lock(&dev_info->mlock);
+	mutex_lock(&indio_dev->mlock);
 	gpio_set_value(st->pdata->gpio_os0, (ret >> 0) & 1);
 	gpio_set_value(st->pdata->gpio_os1, (ret >> 1) & 1);
 	gpio_set_value(st->pdata->gpio_os1, (ret >> 2) & 1);
 	st->oversampling = lval;
-	mutex_unlock(&dev_info->mlock);
+	mutex_unlock(&indio_dev->mlock);
 
 	return count;
 }
@@ -222,16 +198,6 @@
 static IIO_CONST_ATTR(oversampling_ratio_available, "0 2 4 8 16 32 64");
 
 static struct attribute *ad7606_attributes[] = {
-	&iio_dev_attr_in0_raw.dev_attr.attr,
-	&iio_dev_attr_in1_raw.dev_attr.attr,
-	&iio_dev_attr_in2_raw.dev_attr.attr,
-	&iio_dev_attr_in3_raw.dev_attr.attr,
-	&iio_dev_attr_in4_raw.dev_attr.attr,
-	&iio_dev_attr_in5_raw.dev_attr.attr,
-	&iio_dev_attr_in6_raw.dev_attr.attr,
-	&iio_dev_attr_in7_raw.dev_attr.attr,
-	&iio_dev_attr_in_scale.dev_attr.attr,
-	&iio_dev_attr_name.dev_attr.attr,
 	&iio_dev_attr_range.dev_attr.attr,
 	&iio_const_attr_range_available.dev_attr.attr,
 	&iio_dev_attr_oversampling_ratio.dev_attr.attr,
@@ -243,20 +209,12 @@
 				     struct attribute *attr, int n)
 {
 	struct device *dev = container_of(kobj, struct device, kobj);
-	struct iio_dev *dev_info = dev_get_drvdata(dev);
-	struct ad7606_state *st = iio_dev_get_devdata(dev_info);
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct ad7606_state *st = iio_priv(indio_dev);
 
 	mode_t mode = attr->mode;
 
-	if (st->chip_info->num_channels <= 6 &&
-		(attr == &iio_dev_attr_in7_raw.dev_attr.attr ||
-		attr == &iio_dev_attr_in6_raw.dev_attr.attr))
-		mode = 0;
-	else if (st->chip_info->num_channels <= 4 &&
-		(attr == &iio_dev_attr_in5_raw.dev_attr.attr ||
-		attr == &iio_dev_attr_in4_raw.dev_attr.attr))
-		mode = 0;
-	else if (!st->have_os &&
+	if (!st->have_os &&
 		(attr == &iio_dev_attr_oversampling_ratio.dev_attr.attr ||
 		attr ==
 		&iio_const_attr_oversampling_ratio_available.dev_attr.attr))
@@ -274,29 +232,92 @@
 	.is_visible = ad7606_attr_is_visible,
 };
 
+static struct iio_chan_spec ad7606_8_channels[] = {
+	IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 0, 0,
+		 (1 << IIO_CHAN_INFO_SCALE_SHARED),
+		 0, 0, IIO_ST('s', 16, 16, 0), 0),
+	IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 1, 0,
+		 (1 << IIO_CHAN_INFO_SCALE_SHARED),
+		 1, 1, IIO_ST('s', 16, 16, 0), 0),
+	IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 2, 0,
+		 (1 << IIO_CHAN_INFO_SCALE_SHARED),
+		 2, 2, IIO_ST('s', 16, 16, 0), 0),
+	IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 3, 0,
+		 (1 << IIO_CHAN_INFO_SCALE_SHARED),
+		 3, 3, IIO_ST('s', 16, 16, 0), 0),
+	IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 4, 0,
+		 (1 << IIO_CHAN_INFO_SCALE_SHARED),
+		 4, 4, IIO_ST('s', 16, 16, 0), 0),
+	IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 5, 0,
+		 (1 << IIO_CHAN_INFO_SCALE_SHARED),
+		 5, 5, IIO_ST('s', 16, 16, 0), 0),
+	IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 6, 0,
+		 (1 << IIO_CHAN_INFO_SCALE_SHARED),
+		 6, 6, IIO_ST('s', 16, 16, 0), 0),
+	IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 7, 0,
+		 (1 << IIO_CHAN_INFO_SCALE_SHARED),
+		 7, 7, IIO_ST('s', 16, 16, 0), 0),
+	IIO_CHAN_SOFT_TIMESTAMP(8),
+};
+
+static struct iio_chan_spec ad7606_6_channels[] = {
+	IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 0, 0,
+		 (1 << IIO_CHAN_INFO_SCALE_SHARED),
+		 0, 0, IIO_ST('s', 16, 16, 0), 0),
+	IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 1, 0,
+		 (1 << IIO_CHAN_INFO_SCALE_SHARED),
+		 1, 1, IIO_ST('s', 16, 16, 0), 0),
+	IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 2, 0,
+		 (1 << IIO_CHAN_INFO_SCALE_SHARED),
+		 2, 2, IIO_ST('s', 16, 16, 0), 0),
+	IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 3, 0,
+		 (1 << IIO_CHAN_INFO_SCALE_SHARED),
+		 3, 3, IIO_ST('s', 16, 16, 0), 0),
+	IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 4, 0,
+		 (1 << IIO_CHAN_INFO_SCALE_SHARED),
+		 4, 4, IIO_ST('s', 16, 16, 0), 0),
+	IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 5, 0,
+		 (1 << IIO_CHAN_INFO_SCALE_SHARED),
+		 5, 5, IIO_ST('s', 16, 16, 0), 0),
+	IIO_CHAN_SOFT_TIMESTAMP(6),
+};
+
+static struct iio_chan_spec ad7606_4_channels[] = {
+	IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 0, 0,
+		 (1 << IIO_CHAN_INFO_SCALE_SHARED),
+		 0, 0, IIO_ST('s', 16, 16, 0), 0),
+	IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 1, 0,
+		 (1 << IIO_CHAN_INFO_SCALE_SHARED),
+		 1, 1, IIO_ST('s', 16, 16, 0), 0),
+	IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 2, 0,
+		 (1 << IIO_CHAN_INFO_SCALE_SHARED),
+		 2, 2, IIO_ST('s', 16, 16, 0), 0),
+	IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 3, 0,
+		 (1 << IIO_CHAN_INFO_SCALE_SHARED),
+		 3, 3, IIO_ST('s', 16, 16, 0), 0),
+	IIO_CHAN_SOFT_TIMESTAMP(4),
+};
+
 static const struct ad7606_chip_info ad7606_chip_info_tbl[] = {
 	/*
 	 * More devices added in future
 	 */
 	[ID_AD7606_8] = {
 		.name = "ad7606",
-		.bits = 16,
-		.sign = IIO_SCAN_EL_TYPE_SIGNED,
 		.int_vref_mv = 2500,
+		.channels = ad7606_8_channels,
 		.num_channels = 8,
 	},
 	[ID_AD7606_6] = {
 		.name = "ad7606-6",
-		.bits = 16,
-		.sign = IIO_SCAN_EL_TYPE_SIGNED,
 		.int_vref_mv = 2500,
+		.channels = ad7606_6_channels,
 		.num_channels = 6,
 	},
 	[ID_AD7606_4] = {
 		.name = "ad7606-4",
-		.bits = 16,
-		.sign = IIO_SCAN_EL_TYPE_SIGNED,
 		.int_vref_mv = 2500,
+		.channels = ad7606_4_channels,
 		.num_channels = 4,
 	},
 };
@@ -343,8 +364,8 @@
 		st->have_reset = true;
 
 	ret = gpio_request_one(st->pdata->gpio_range, GPIOF_DIR_OUT |
-			       ((st->range == 10000) ? GPIOF_INIT_HIGH :
-			       	GPIOF_INIT_LOW), "AD7606_RANGE");
+				((st->range == 10000) ? GPIOF_INIT_HIGH :
+				GPIOF_INIT_LOW), "AD7606_RANGE");
 	if (!ret)
 		st->have_range = true;
 
@@ -391,9 +412,10 @@
  */
 static irqreturn_t ad7606_interrupt(int irq, void *dev_id)
 {
-	struct ad7606_state *st = dev_id;
+	struct iio_dev *indio_dev = dev_id;
+	struct ad7606_state *st = iio_priv(indio_dev);
 
-	if (iio_ring_enabled(st->indio_dev)) {
+	if (iio_ring_enabled(indio_dev)) {
 		if (!work_pending(&st->poll_work))
 			schedule_work(&st->poll_work);
 	} else {
@@ -404,21 +426,29 @@
 	return IRQ_HANDLED;
 };
 
-struct ad7606_state *ad7606_probe(struct device *dev, int irq,
+static const struct iio_info ad7606_info = {
+	.driver_module = THIS_MODULE,
+	.read_raw = &ad7606_read_raw,
+	.attrs = &ad7606_attribute_group,
+};
+
+struct iio_dev *ad7606_probe(struct device *dev, int irq,
 			      void __iomem *base_address,
 			      unsigned id,
 			      const struct ad7606_bus_ops *bops)
 {
 	struct ad7606_platform_data *pdata = dev->platform_data;
 	struct ad7606_state *st;
-	int ret;
+	int ret, regdone = 0;
+	struct iio_dev *indio_dev = iio_allocate_device(sizeof(*st));
 
-	st = kzalloc(sizeof(*st), GFP_KERNEL);
-	if (st == NULL) {
+	if (indio_dev == NULL) {
 		ret = -ENOMEM;
 		goto error_ret;
 	}
 
+	st = iio_priv(indio_dev);
+
 	st->dev = dev;
 	st->id = id;
 	st->irq = irq;
@@ -445,93 +475,91 @@
 	st->pdata = pdata;
 	st->chip_info = &ad7606_chip_info_tbl[id];
 
-	atomic_set(&st->protect_ring, 0);
-
-	st->indio_dev = iio_allocate_device();
-	if (st->indio_dev == NULL) {
-		ret = -ENOMEM;
-		goto error_disable_reg;
-	}
-
-	st->indio_dev->dev.parent = dev;
-	st->indio_dev->attrs = &ad7606_attribute_group;
-	st->indio_dev->dev_data = (void *)(st);
-	st->indio_dev->driver_module = THIS_MODULE;
-	st->indio_dev->modes = INDIO_DIRECT_MODE;
+	indio_dev->dev.parent = dev;
+	indio_dev->info = &ad7606_info;
+	indio_dev->modes = INDIO_DIRECT_MODE;
+	indio_dev->name = st->chip_info->name;
+	indio_dev->channels = st->chip_info->channels;
+	indio_dev->num_channels = st->chip_info->num_channels;
 
 	init_waitqueue_head(&st->wq_data_avail);
 
 	ret = ad7606_request_gpios(st);
 	if (ret)
-		goto error_free_device;
+		goto error_disable_reg;
 
 	ret = ad7606_reset(st);
 	if (ret)
 		dev_warn(st->dev, "failed to RESET: no RESET GPIO specified\n");
 
 	ret = request_irq(st->irq, ad7606_interrupt,
-		IRQF_TRIGGER_FALLING, st->chip_info->name, st);
+		IRQF_TRIGGER_FALLING, st->chip_info->name, indio_dev);
 	if (ret)
 		goto error_free_gpios;
 
-	ret = ad7606_register_ring_funcs_and_init(st->indio_dev);
+	ret = ad7606_register_ring_funcs_and_init(indio_dev);
 	if (ret)
 		goto error_free_irq;
 
-	ret = iio_device_register(st->indio_dev);
+	ret = iio_device_register(indio_dev);
 	if (ret)
 		goto error_free_irq;
+	regdone = 1;
 
-	ret = iio_ring_buffer_register(st->indio_dev->ring, 0);
+	ret = iio_ring_buffer_register_ex(indio_dev->ring, 0,
+					  indio_dev->channels,
+					  indio_dev->num_channels);
 	if (ret)
 		goto error_cleanup_ring;
 
-	return st;
+	return indio_dev;
 
 error_cleanup_ring:
-	ad7606_ring_cleanup(st->indio_dev);
-	iio_device_unregister(st->indio_dev);
+	ad7606_ring_cleanup(indio_dev);
 
 error_free_irq:
-	free_irq(st->irq, st);
+	free_irq(st->irq, indio_dev);
 
 error_free_gpios:
 	ad7606_free_gpios(st);
 
-error_free_device:
-	iio_free_device(st->indio_dev);
-
 error_disable_reg:
 	if (!IS_ERR(st->reg))
 		regulator_disable(st->reg);
 error_put_reg:
 	if (!IS_ERR(st->reg))
 		regulator_put(st->reg);
-	kfree(st);
+	if (regdone)
+		iio_device_unregister(indio_dev);
+	else
+		iio_free_device(indio_dev);
 error_ret:
 	return ERR_PTR(ret);
 }
 
-int ad7606_remove(struct ad7606_state *st)
+int ad7606_remove(struct iio_dev *indio_dev)
 {
-	struct iio_dev *indio_dev = st->indio_dev;
+	struct ad7606_state *st = iio_priv(indio_dev);
+
 	iio_ring_buffer_unregister(indio_dev->ring);
 	ad7606_ring_cleanup(indio_dev);
-	iio_device_unregister(indio_dev);
-	free_irq(st->irq, st);
+
+	free_irq(st->irq, indio_dev);
 	if (!IS_ERR(st->reg)) {
 		regulator_disable(st->reg);
 		regulator_put(st->reg);
 	}
 
 	ad7606_free_gpios(st);
+	iio_device_unregister(indio_dev);
 
-	kfree(st);
 	return 0;
 }
 
-void ad7606_suspend(struct ad7606_state *st)
+void ad7606_suspend(struct iio_dev *indio_dev)
 {
+	struct ad7606_state *st = iio_priv(indio_dev);
+
 	if (st->have_stby) {
 		if (st->have_range)
 			gpio_set_value(st->pdata->gpio_range, 1);
@@ -539,8 +567,10 @@
 	}
 }
 
-void ad7606_resume(struct ad7606_state *st)
+void ad7606_resume(struct iio_dev *indio_dev)
 {
+	struct ad7606_state *st = iio_priv(indio_dev);
+
 	if (st->have_stby) {
 		if (st->have_range)
 			gpio_set_value(st->pdata->gpio_range,
diff -druN linux-2.6.39-libre/drivers/staging/iio/adc/ad7606.h linux-3.0-rc7-libre/drivers/staging/iio/adc/ad7606.h
--- linux-2.6.39-libre/drivers/staging/iio/adc/ad7606.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/iio/adc/ad7606.h	2011-07-11 19:51:52.000000000 -0400
@@ -43,17 +43,17 @@
 /**
  * struct ad7606_chip_info - chip specifc information
  * @name:		indentification string for chip
- * @bits:		accuracy of the adc in bits
- * @bits:		output coding [s]igned or [u]nsigned
  * @int_vref_mv:	the internal reference voltage
- * @num_channels:	number of physical inputs on chip
+ * @channels:		channel specification
+ * @num_channels:	number of channels
  */
 
 struct ad7606_chip_info {
-	char				name[10];
+	const char			*name;
 	u8				bits;
 	char				sign;
 	u16				int_vref_mv;
+	struct iio_chan_spec		*channels;
 	unsigned			num_channels;
 };
 
@@ -62,14 +62,12 @@
  */
 
 struct ad7606_state {
-	struct iio_dev			*indio_dev;
 	struct device			*dev;
 	const struct ad7606_chip_info	*chip_info;
 	struct ad7606_platform_data	*pdata;
 	struct regulator		*reg;
 	struct work_struct		poll_work;
 	wait_queue_head_t		wq_data_avail;
-	atomic_t			protect_ring;
 	size_t				d_size;
 	const struct ad7606_bus_ops	*bops;
 	int				irq;
@@ -97,12 +95,12 @@
 	int (*read_block)(struct device *, int, void *);
 };
 
-void ad7606_suspend(struct ad7606_state *st);
-void ad7606_resume(struct ad7606_state *st);
-struct ad7606_state *ad7606_probe(struct device *dev, int irq,
+void ad7606_suspend(struct iio_dev *indio_dev);
+void ad7606_resume(struct iio_dev *indio_dev);
+struct iio_dev *ad7606_probe(struct device *dev, int irq,
 			      void __iomem *base_address, unsigned id,
 			      const struct ad7606_bus_ops *bops);
-int ad7606_remove(struct ad7606_state *st);
+int ad7606_remove(struct iio_dev *indio_dev);
 int ad7606_reset(struct ad7606_state *st);
 
 enum ad7606_supported_device_ids {
@@ -111,7 +109,7 @@
 	ID_AD7606_4
 };
 
-int ad7606_scan_from_ring(struct ad7606_state *st, unsigned ch);
+int ad7606_scan_from_ring(struct iio_dev *indio_dev, unsigned ch);
 int ad7606_register_ring_funcs_and_init(struct iio_dev *indio_dev);
 void ad7606_ring_cleanup(struct iio_dev *indio_dev);
 #endif /* IIO_ADC_AD7606_H_ */
diff -druN linux-2.6.39-libre/drivers/staging/iio/adc/ad7606_par.c linux-3.0-rc7-libre/drivers/staging/iio/adc/ad7606_par.c
--- linux-2.6.39-libre/drivers/staging/iio/adc/ad7606_par.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/iio/adc/ad7606_par.c	2011-07-11 19:51:52.000000000 -0400
@@ -12,13 +12,15 @@
 #include <linux/err.h>
 #include <linux/io.h>
 
+#include "../iio.h"
 #include "ad7606.h"
 
 static int ad7606_par16_read_block(struct device *dev,
 				 int count, void *buf)
 {
 	struct platform_device *pdev = to_platform_device(dev);
-	struct ad7606_state *st = platform_get_drvdata(pdev);
+	struct iio_dev *indio_dev = platform_get_drvdata(pdev);
+	struct ad7606_state *st = iio_priv(indio_dev);
 
 	insw((unsigned long) st->base_address, buf, count);
 
@@ -33,7 +35,8 @@
 				 int count, void *buf)
 {
 	struct platform_device *pdev = to_platform_device(dev);
-	struct ad7606_state *st = platform_get_drvdata(pdev);
+	struct iio_dev *indio_dev = platform_get_drvdata(pdev);
+	struct ad7606_state *st = iio_priv(indio_dev);
 
 	insb((unsigned long) st->base_address, buf, count * 2);
 
@@ -47,7 +50,7 @@
 static int __devinit ad7606_par_probe(struct platform_device *pdev)
 {
 	struct resource *res;
-	struct ad7606_state *st;
+	struct iio_dev *indio_dev;
 	void __iomem *addr;
 	resource_size_t remap_size;
 	int ret, irq;
@@ -75,17 +78,17 @@
 		goto out1;
 	}
 
-	st = ad7606_probe(&pdev->dev, irq, addr,
+	indio_dev = ad7606_probe(&pdev->dev, irq, addr,
 			  platform_get_device_id(pdev)->driver_data,
 			  remap_size > 1 ? &ad7606_par16_bops :
 			  &ad7606_par8_bops);
 
-	if (IS_ERR(st))  {
-		ret = PTR_ERR(st);
+	if (IS_ERR(indio_dev))  {
+		ret = PTR_ERR(indio_dev);
 		goto out2;
 	}
 
-	platform_set_drvdata(pdev, st);
+	platform_set_drvdata(pdev, indio_dev);
 
 	return 0;
 
@@ -99,10 +102,11 @@
 
 static int __devexit ad7606_par_remove(struct platform_device *pdev)
 {
-	struct ad7606_state *st = platform_get_drvdata(pdev);
+	struct iio_dev *indio_dev = platform_get_drvdata(pdev);
 	struct resource *res;
+	struct ad7606_state *st = iio_priv(indio_dev);
 
-	ad7606_remove(st);
+	ad7606_remove(indio_dev);
 
 	iounmap(st->base_address);
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -116,18 +120,18 @@
 #ifdef CONFIG_PM
 static int ad7606_par_suspend(struct device *dev)
 {
-	struct ad7606_state *st = dev_get_drvdata(dev);
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
 
-	ad7606_suspend(st);
+	ad7606_suspend(indio_dev);
 
 	return 0;
 }
 
 static int ad7606_par_resume(struct device *dev)
 {
-	struct ad7606_state *st = dev_get_drvdata(dev);
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
 
-	ad7606_resume(st);
+	ad7606_resume(indio_dev);
 
 	return 0;
 }
diff -druN linux-2.6.39-libre/drivers/staging/iio/adc/ad7606_ring.c linux-3.0-rc7-libre/drivers/staging/iio/adc/ad7606_ring.c
--- linux-2.6.39-libre/drivers/staging/iio/adc/ad7606_ring.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/iio/adc/ad7606_ring.c	2011-07-11 19:51:52.000000000 -0400
@@ -7,7 +7,6 @@
 
 #include <linux/interrupt.h>
 #include <linux/gpio.h>
-#include <linux/workqueue.h>
 #include <linux/device.h>
 #include <linux/kernel.h>
 #include <linux/slab.h>
@@ -21,99 +20,19 @@
 
 #include "ad7606.h"
 
-static IIO_SCAN_EL_C(in0, 0, 0, NULL);
-static IIO_SCAN_EL_C(in1, 1, 0, NULL);
-static IIO_SCAN_EL_C(in2, 2, 0, NULL);
-static IIO_SCAN_EL_C(in3, 3, 0, NULL);
-static IIO_SCAN_EL_C(in4, 4, 0, NULL);
-static IIO_SCAN_EL_C(in5, 5, 0, NULL);
-static IIO_SCAN_EL_C(in6, 6, 0, NULL);
-static IIO_SCAN_EL_C(in7, 7, 0, NULL);
-
-static IIO_SCAN_EL_TIMESTAMP(8);
-static IIO_CONST_ATTR_SCAN_EL_TYPE(timestamp, s, 64, 64);
-
-static ssize_t ad7606_show_type(struct device *dev,
-				struct device_attribute *attr,
-				char *buf)
-{
-	struct iio_ring_buffer *ring = dev_get_drvdata(dev);
-	struct iio_dev *indio_dev = ring->indio_dev;
-	struct ad7606_state *st = indio_dev->dev_data;
-
-	return sprintf(buf, "%c%d/%d\n", st->chip_info->sign,
-		       st->chip_info->bits, st->chip_info->bits);
-}
-static IIO_DEVICE_ATTR(in_type, S_IRUGO, ad7606_show_type, NULL, 0);
-
-static struct attribute *ad7606_scan_el_attrs[] = {
-	&iio_scan_el_in0.dev_attr.attr,
-	&iio_const_attr_in0_index.dev_attr.attr,
-	&iio_scan_el_in1.dev_attr.attr,
-	&iio_const_attr_in1_index.dev_attr.attr,
-	&iio_scan_el_in2.dev_attr.attr,
-	&iio_const_attr_in2_index.dev_attr.attr,
-	&iio_scan_el_in3.dev_attr.attr,
-	&iio_const_attr_in3_index.dev_attr.attr,
-	&iio_scan_el_in4.dev_attr.attr,
-	&iio_const_attr_in4_index.dev_attr.attr,
-	&iio_scan_el_in5.dev_attr.attr,
-	&iio_const_attr_in5_index.dev_attr.attr,
-	&iio_scan_el_in6.dev_attr.attr,
-	&iio_const_attr_in6_index.dev_attr.attr,
-	&iio_scan_el_in7.dev_attr.attr,
-	&iio_const_attr_in7_index.dev_attr.attr,
-	&iio_const_attr_timestamp_index.dev_attr.attr,
-	&iio_scan_el_timestamp.dev_attr.attr,
-	&iio_const_attr_timestamp_type.dev_attr.attr,
-	&iio_dev_attr_in_type.dev_attr.attr,
-	NULL,
-};
-
-static mode_t ad7606_scan_el_attr_is_visible(struct kobject *kobj,
-				     struct attribute *attr, int n)
-{
-	struct device *dev = container_of(kobj, struct device, kobj);
-	struct iio_ring_buffer *ring = dev_get_drvdata(dev);
-	struct iio_dev *indio_dev = ring->indio_dev;
-	struct ad7606_state *st = indio_dev->dev_data;
-
-	mode_t mode = attr->mode;
-
-	if (st->chip_info->num_channels <= 6 &&
-		(attr == &iio_scan_el_in7.dev_attr.attr ||
-		attr == &iio_const_attr_in7_index.dev_attr.attr ||
-		attr == &iio_scan_el_in6.dev_attr.attr ||
-		attr == &iio_const_attr_in6_index.dev_attr.attr))
-		mode = 0;
-	else if (st->chip_info->num_channels <= 4 &&
-		(attr == &iio_scan_el_in5.dev_attr.attr ||
-		attr == &iio_const_attr_in5_index.dev_attr.attr ||
-		attr == &iio_scan_el_in4.dev_attr.attr ||
-		attr == &iio_const_attr_in4_index.dev_attr.attr))
-		mode = 0;
-
-	return mode;
-}
-
-static struct attribute_group ad7606_scan_el_group = {
-	.name = "scan_elements",
-	.attrs = ad7606_scan_el_attrs,
-	.is_visible = ad7606_scan_el_attr_is_visible,
-};
-
-int ad7606_scan_from_ring(struct ad7606_state *st, unsigned ch)
+int ad7606_scan_from_ring(struct iio_dev *indio_dev, unsigned ch)
 {
-	struct iio_ring_buffer *ring = st->indio_dev->ring;
+	struct iio_ring_buffer *ring = indio_dev->ring;
 	int ret;
 	u16 *ring_data;
 
-	ring_data = kmalloc(ring->access.get_bytes_per_datum(ring), GFP_KERNEL);
+	ring_data = kmalloc(ring->access->get_bytes_per_datum(ring),
+			    GFP_KERNEL);
 	if (ring_data == NULL) {
 		ret = -ENOMEM;
 		goto error_ret;
 	}
-	ret = ring->access.read_last(ring, (u8 *) ring_data);
+	ret = ring->access->read_last(ring, (u8 *) ring_data);
 	if (ret)
 		goto error_free_ring_data;
 
@@ -134,12 +53,12 @@
  **/
 static int ad7606_ring_preenable(struct iio_dev *indio_dev)
 {
-	struct ad7606_state *st = indio_dev->dev_data;
+	struct ad7606_state *st = iio_priv(indio_dev);
 	struct iio_ring_buffer *ring = indio_dev->ring;
 	size_t d_size;
 
 	d_size = st->chip_info->num_channels *
-		 st->chip_info->bits / 8;
+		 st->chip_info->channels[0].scan_type.storagebits / 8;
 
 	if (ring->scan_timestamp) {
 		d_size += sizeof(s64);
@@ -148,8 +67,8 @@
 			d_size += sizeof(s64) - (d_size % sizeof(s64));
 	}
 
-	if (ring->access.set_bytes_per_datum)
-		ring->access.set_bytes_per_datum(ring, d_size);
+	if (ring->access->set_bytes_per_datum)
+		ring->access->set_bytes_per_datum(ring, d_size);
 
 	st->d_size = d_size;
 
@@ -157,16 +76,20 @@
 }
 
 /**
- * ad7606_poll_func_th() th of trigger launched polling to ring buffer
+ * ad7606_trigger_handler_th() th/bh of trigger launched polling to ring buffer
  *
  **/
-static void ad7606_poll_func_th(struct iio_dev *indio_dev, s64 time)
+static irqreturn_t ad7606_trigger_handler_th_bh(int irq, void *p)
 {
-	struct ad7606_state *st = indio_dev->dev_data;
+	struct iio_poll_func *pf = p;
+	struct iio_dev *indio_dev = pf->private_data;
+	struct ad7606_state *st = iio_priv(indio_dev);
+
 	gpio_set_value(st->pdata->gpio_convst, 1);
 
-	return;
+	return IRQ_HANDLED;
 }
+
 /**
  * ad7606_poll_bh_to_ring() bh of trigger launched polling to ring buffer
  * @work_s:	the work struct through which this was scheduled
@@ -180,17 +103,12 @@
 {
 	struct ad7606_state *st = container_of(work_s, struct ad7606_state,
 						poll_work);
-	struct iio_dev *indio_dev = st->indio_dev;
-	struct iio_sw_ring_buffer *sw_ring = iio_to_sw_ring(indio_dev->ring);
+	struct iio_dev *indio_dev = iio_priv_to_dev(st);
 	struct iio_ring_buffer *ring = indio_dev->ring;
 	s64 time_ns;
 	__u8 *buf;
 	int ret;
 
-	/* Ensure only one copy of this function running at a time */
-	if (atomic_inc_return(&st->protect_ring) > 1)
-		return;
-
 	buf = kzalloc(st->d_size, GFP_KERNEL);
 	if (buf == NULL)
 		return;
@@ -225,16 +143,22 @@
 		memcpy(buf + st->d_size - sizeof(s64),
 			&time_ns, sizeof(time_ns));
 
-	ring->access.store_to(&sw_ring->buf, buf, time_ns);
+	ring->access->store_to(indio_dev->ring, buf, time_ns);
 done:
 	gpio_set_value(st->pdata->gpio_convst, 0);
+	iio_trigger_notify_done(indio_dev->trig);
 	kfree(buf);
-	atomic_dec(&st->protect_ring);
 }
 
+static const struct iio_ring_setup_ops ad7606_ring_setup_ops = {
+	.preenable = &ad7606_ring_preenable,
+	.postenable = &iio_triggered_ring_postenable,
+	.predisable = &iio_triggered_ring_predisable,
+};
+
 int ad7606_register_ring_funcs_and_init(struct iio_dev *indio_dev)
 {
-	struct ad7606_state *st = indio_dev->dev_data;
+	struct ad7606_state *st = iio_priv(indio_dev);
 	int ret;
 
 	indio_dev->ring = iio_sw_rb_allocate(indio_dev);
@@ -244,17 +168,22 @@
 	}
 
 	/* Effectively select the ring buffer implementation */
-	iio_ring_sw_register_funcs(&indio_dev->ring->access);
-	ret = iio_alloc_pollfunc(indio_dev, NULL, &ad7606_poll_func_th);
-	if (ret)
+	indio_dev->ring->access = &ring_sw_access_funcs;
+	indio_dev->pollfunc = iio_alloc_pollfunc(&ad7606_trigger_handler_th_bh,
+						 &ad7606_trigger_handler_th_bh,
+						 0,
+						 indio_dev,
+						 "%s_consumer%d",
+						 indio_dev->name,
+						 indio_dev->id);
+	if (indio_dev->pollfunc == NULL) {
+		ret = -ENOMEM;
 		goto error_deallocate_sw_rb;
+	}
 
 	/* Ring buffer functions - here trigger setup related */
 
-	indio_dev->ring->preenable = &ad7606_ring_preenable;
-	indio_dev->ring->postenable = &iio_triggered_ring_postenable;
-	indio_dev->ring->predisable = &iio_triggered_ring_predisable;
-	indio_dev->ring->scan_el_attrs = &ad7606_scan_el_group;
+	indio_dev->ring->setup_ops = &ad7606_ring_setup_ops;
 	indio_dev->ring->scan_timestamp = true ;
 
 	INIT_WORK(&st->poll_work, &ad7606_poll_bh_to_ring);
@@ -262,6 +191,7 @@
 	/* Flag that polled ring buffering is possible */
 	indio_dev->modes |= INDIO_RING_TRIGGERED;
 	return 0;
+
 error_deallocate_sw_rb:
 	iio_sw_rb_free(indio_dev->ring);
 error_ret:
@@ -275,6 +205,6 @@
 		iio_trigger_dettach_poll_func(indio_dev->trig,
 					      indio_dev->pollfunc);
 	}
-	kfree(indio_dev->pollfunc);
+	iio_dealloc_pollfunc(indio_dev->pollfunc);
 	iio_sw_rb_free(indio_dev->ring);
 }
diff -druN linux-2.6.39-libre/drivers/staging/iio/adc/ad7606_spi.c linux-3.0-rc7-libre/drivers/staging/iio/adc/ad7606_spi.c
--- linux-2.6.39-libre/drivers/staging/iio/adc/ad7606_spi.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/iio/adc/ad7606_spi.c	2011-07-11 19:51:52.000000000 -0400
@@ -10,6 +10,8 @@
 #include <linux/spi/spi.h>
 #include <linux/types.h>
 #include <linux/err.h>
+
+#include "../iio.h"
 #include "ad7606.h"
 
 #define MAX_SPI_FREQ_HZ		23500000	/* VDRIVE above 4.75 V */
@@ -39,42 +41,42 @@
 
 static int __devinit ad7606_spi_probe(struct spi_device *spi)
 {
-	struct ad7606_state *st;
+	struct iio_dev *indio_dev;
 
-	st = ad7606_probe(&spi->dev, spi->irq, NULL,
+	indio_dev = ad7606_probe(&spi->dev, spi->irq, NULL,
 			   spi_get_device_id(spi)->driver_data,
 			   &ad7606_spi_bops);
 
-	if (IS_ERR(st))
-		return PTR_ERR(st);
+	if (IS_ERR(indio_dev))
+		return PTR_ERR(indio_dev);
 
-	spi_set_drvdata(spi, st);
+	spi_set_drvdata(spi, indio_dev);
 
 	return 0;
 }
 
 static int __devexit ad7606_spi_remove(struct spi_device *spi)
 {
-	struct ad7606_state *st = dev_get_drvdata(&spi->dev);
+	struct iio_dev *indio_dev = dev_get_drvdata(&spi->dev);
 
-	return ad7606_remove(st);
+	return ad7606_remove(indio_dev);
 }
 
 #ifdef CONFIG_PM
 static int ad7606_spi_suspend(struct device *dev)
 {
-	struct ad7606_state *st = dev_get_drvdata(dev);
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
 
-	ad7606_suspend(st);
+	ad7606_suspend(indio_dev);
 
 	return 0;
 }
 
 static int ad7606_spi_resume(struct device *dev)
 {
-	struct ad7606_state *st = dev_get_drvdata(dev);
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
 
-	ad7606_resume(st);
+	ad7606_resume(indio_dev);
 
 	return 0;
 }
diff -druN linux-2.6.39-libre/drivers/staging/iio/adc/ad7745.c linux-3.0-rc7-libre/drivers/staging/iio/adc/ad7745.c
--- linux-2.6.39-libre/drivers/staging/iio/adc/ad7745.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/iio/adc/ad7745.c	2011-07-11 19:51:52.000000000 -0400
@@ -8,14 +8,12 @@
 
 #include <linux/interrupt.h>
 #include <linux/gpio.h>
-#include <linux/workqueue.h>
 #include <linux/device.h>
 #include <linux/kernel.h>
 #include <linux/slab.h>
 #include <linux/sysfs.h>
 #include <linux/list.h>
 #include <linux/i2c.h>
-#include <linux/rtc.h>
 
 #include "../iio.h"
 #include "../sysfs.h"
@@ -55,12 +53,9 @@
  */
 
 struct ad774x_chip_info {
-	const char *name;
 	struct i2c_client *client;
 	struct iio_dev *indio_dev;
-	struct work_struct thresh_work;
 	bool inter;
-	s64 last_timestamp;
 	u16 cap_offs;                   /* Capacitive offset */
 	u16 cap_gain;                   /* Capacitive gain calibration */
 	u16 volt_gain;                  /* Voltage gain calibration */
@@ -76,7 +71,8 @@
 	u8 reg_cfg;
 };
 
-struct ad774x_conversion_mode ad774x_conv_mode_table[AD774X_MAX_CONV_MODE] = {
+static struct ad774x_conversion_mode
+ad774x_conv_mode_table[AD774X_MAX_CONV_MODE] = {
 	{ "idle", 0 },
 	{ "continuous-conversion", 1 },
 	{ "single-conversion", 2 },
@@ -502,17 +498,6 @@
 		ad774x_show_cap_gain,
 		ad774x_store_cap_gain);
 
-static ssize_t ad774x_show_name(struct device *dev,
-		struct device_attribute *attr,
-		char *buf)
-{
-	struct iio_dev *dev_info = dev_get_drvdata(dev);
-	struct ad774x_chip_info *chip = dev_info->dev_data;
-	return sprintf(buf, "%s\n", chip->name);
-}
-
-static IIO_DEVICE_ATTR(name, S_IRUGO, ad774x_show_name, NULL, 0);
-
 static struct attribute *ad774x_attributes[] = {
 	&iio_dev_attr_available_conversion_modes.dev_attr.attr,
 	&iio_dev_attr_conversion_mode.dev_attr.attr,
@@ -526,7 +511,6 @@
 	&iio_dev_attr_cap0_raw.dev_attr.attr,
 	&iio_dev_attr_capdac0_raw.dev_attr.attr,
 	&iio_dev_attr_capdac1_raw.dev_attr.attr,
-	&iio_dev_attr_name.dev_attr.attr,
 	NULL,
 };
 
@@ -538,8 +522,8 @@
  * data ready events
  */
 
-#define IIO_EVENT_CODE_CAP_RDY     IIO_BUFFER_EVENT_CODE(0)
-#define IIO_EVENT_CODE_VT_RDY      IIO_BUFFER_EVENT_CODE(1)
+#define IIO_EVENT_CODE_CAP_RDY     0
+#define IIO_EVENT_CODE_VT_RDY      1
 
 #define IIO_EVENT_ATTR_CAP_RDY_SH(_evlist, _show, _store, _mask)	\
 	IIO_EVENT_ATTR_SH(cap_rdy, _evlist, _show, _store, _mask)
@@ -547,67 +531,33 @@
 #define IIO_EVENT_ATTR_VT_RDY_SH(_evlist, _show, _store, _mask)	\
 	IIO_EVENT_ATTR_SH(vt_rdy, _evlist, _show, _store, _mask)
 
-static void ad774x_interrupt_handler_bh(struct work_struct *work_s)
+static irqreturn_t ad774x_event_handler(int irq, void *private)
 {
-	struct ad774x_chip_info *chip =
-		container_of(work_s, struct ad774x_chip_info, thresh_work);
+	struct iio_dev *indio_dev = private;
+	struct ad774x_chip_info *chip = iio_dev_get_devdata(indio_dev);
 	u8 int_status;
 
-	enable_irq(chip->client->irq);
-
 	ad774x_i2c_read(chip, AD774X_STATUS, &int_status, 1);
 
 	if (int_status & AD774X_STATUS_RDYCAP)
-		iio_push_event(chip->indio_dev, 0,
-				IIO_EVENT_CODE_CAP_RDY,
-				chip->last_timestamp);
+		iio_push_event(indio_dev, 0,
+			       IIO_EVENT_CODE_CAP_RDY,
+			       iio_get_time_ns());
 
 	if (int_status & AD774X_STATUS_RDYVT)
-		iio_push_event(chip->indio_dev, 0,
-				IIO_EVENT_CODE_VT_RDY,
-				chip->last_timestamp);
-}
-
-static int ad774x_interrupt_handler_th(struct iio_dev *dev_info,
-		int index,
-		s64 timestamp,
-		int no_test)
-{
-	struct ad774x_chip_info *chip = dev_info->dev_data;
-
-	chip->last_timestamp = timestamp;
-	schedule_work(&chip->thresh_work);
-
-	return 0;
-}
-
-IIO_EVENT_SH(data_rdy, &ad774x_interrupt_handler_th);
-
-static ssize_t ad774x_query_out_mode(struct device *dev,
-		struct device_attribute *attr,
-		char *buf)
-{
-	/*
-	 * AD774X provides one /RDY pin, which can be used as interrupt
-	 * but the pin is not configurable
-	 */
-	return sprintf(buf, "1\n");
-}
+		iio_push_event(indio_dev, 0,
+			       IIO_EVENT_CODE_VT_RDY,
+			       iio_get_time_ns());
 
-static ssize_t ad774x_set_out_mode(struct device *dev,
-		struct device_attribute *attr,
-		const char *buf,
-		size_t len)
-{
-	return len;
+	return IRQ_HANDLED;
 }
 
-IIO_EVENT_ATTR_CAP_RDY_SH(iio_event_data_rdy, ad774x_query_out_mode, ad774x_set_out_mode, 0);
-IIO_EVENT_ATTR_VT_RDY_SH(iio_event_data_rdy, ad774x_query_out_mode, ad774x_set_out_mode, 0);
+static IIO_CONST_ATTR(cap_rdy_en, "1");
+static IIO_CONST_ATTR(vt_rdy_en, "1");
 
 static struct attribute *ad774x_event_attributes[] = {
-	&iio_event_attr_cap_rdy.dev_attr.attr,
-	&iio_event_attr_vt_rdy.dev_attr.attr,
+	&iio_const_attr_cap_rdy_en.dev_attr.attr,
+	&iio_const_attr_vt_rdy_en.dev_attr.attr,
 	NULL,
 };
 
@@ -615,6 +565,12 @@
 	.attrs = ad774x_event_attributes,
 };
 
+static const struct iio_info ad774x_info = {
+	.attrs = &ad774x_event_attribute_group,
+	.event_attrs = &ad774x_event_attribute_group,
+	.num_interrupt_lines = 1,
+	.driver_module = THIS_MODULE,
+};
 /*
  * device probe and remove
  */
@@ -633,21 +589,18 @@
 	i2c_set_clientdata(client, chip);
 
 	chip->client = client;
-	chip->name = id->name;
 
-	chip->indio_dev = iio_allocate_device();
+	chip->indio_dev = iio_allocate_device(0);
 	if (chip->indio_dev == NULL) {
 		ret = -ENOMEM;
 		goto error_free_chip;
 	}
 
 	/* Establish that the iio_dev is a child of the i2c device */
+	chip->indio_dev->name = id->name;
 	chip->indio_dev->dev.parent = &client->dev;
-	chip->indio_dev->attrs = &ad774x_attribute_group;
-	chip->indio_dev->event_attrs = &ad774x_event_attribute_group;
+	chip->indio_dev->info = &ad774x_info;
 	chip->indio_dev->dev_data = (void *)(chip);
-	chip->indio_dev->driver_module = THIS_MODULE;
-	chip->indio_dev->num_interrupt_lines = 1;
 	chip->indio_dev->modes = INDIO_DIRECT_MODE;
 
 	ret = iio_device_register(chip->indio_dev);
@@ -656,18 +609,14 @@
 	regdone = 1;
 
 	if (client->irq) {
-		ret = iio_register_interrupt_line(client->irq,
-				chip->indio_dev,
-				0,
-				IRQF_TRIGGER_FALLING,
-				"ad774x");
+		ret = request_threaded_irq(client->irq,
+					   NULL,
+					   &ad774x_event_handler,
+					   IRQF_TRIGGER_FALLING,
+					   "ad774x",
+					   chip->indio_dev);
 		if (ret)
 			goto error_free_dev;
-
-		iio_add_event_to_list(iio_event_attr_cap_rdy.listel,
-				&chip->indio_dev->interrupts[0]->ev_list);
-
-		INIT_WORK(&chip->thresh_work, ad774x_interrupt_handler_bh);
 	}
 
 	dev_err(&client->dev, "%s capacitive sensor registered, irq: %d\n", id->name, client->irq);
@@ -676,7 +625,7 @@
 
 error_free_dev:
 	if (regdone)
-		iio_device_unregister(chip->indio_dev);
+		free_irq(client->irq, chip->indio_dev);
 	else
 		iio_free_device(chip->indio_dev);
 error_free_chip:
@@ -691,7 +640,7 @@
 	struct iio_dev *indio_dev = chip->indio_dev;
 
 	if (client->irq)
-		iio_unregister_interrupt_line(indio_dev, 0);
+		free_irq(client->irq, indio_dev);
 	iio_device_unregister(indio_dev);
 	kfree(chip);
 
diff -druN linux-2.6.39-libre/drivers/staging/iio/adc/ad7780.c linux-3.0-rc7-libre/drivers/staging/iio/adc/ad7780.c
--- linux-2.6.39-libre/drivers/staging/iio/adc/ad7780.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/staging/iio/adc/ad7780.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,301 @@
+/*
+ * AD7780/AD7781 SPI ADC driver
+ *
+ * Copyright 2011 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2.
+ */
+
+#include <linux/interrupt.h>
+#include <linux/device.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/sysfs.h>
+#include <linux/spi/spi.h>
+#include <linux/regulator/consumer.h>
+#include <linux/err.h>
+#include <linux/sched.h>
+#include <linux/gpio.h>
+
+#include "../iio.h"
+#include "../sysfs.h"
+#include "../ring_generic.h"
+#include "adc.h"
+
+#include "ad7780.h"
+
+#define AD7780_RDY	(1 << 7)
+#define AD7780_FILTER	(1 << 6)
+#define AD7780_ERR	(1 << 5)
+#define AD7780_ID1	(1 << 4)
+#define AD7780_ID0	(1 << 3)
+#define AD7780_GAIN	(1 << 2)
+#define AD7780_PAT1	(1 << 1)
+#define AD7780_PAT0	(1 << 0)
+
+struct ad7780_chip_info {
+	struct iio_chan_spec		channel;
+};
+
+struct ad7780_state {
+	struct spi_device		*spi;
+	const struct ad7780_chip_info	*chip_info;
+	struct regulator		*reg;
+	struct ad7780_platform_data	*pdata;
+	wait_queue_head_t		wq_data_avail;
+	bool				done;
+	u16				int_vref_mv;
+	struct spi_transfer		xfer;
+	struct spi_message		msg;
+	/*
+	 * DMA (thus cache coherency maintenance) requires the
+	 * transfer buffers to live in their own cache lines.
+	 */
+	unsigned int			data ____cacheline_aligned;
+};
+
+enum ad7780_supported_device_ids {
+	ID_AD7780,
+	ID_AD7781,
+};
+
+static int ad7780_read(struct ad7780_state *st, int *val)
+{
+	int ret;
+
+	spi_bus_lock(st->spi->master);
+
+	enable_irq(st->spi->irq);
+	st->done = false;
+	gpio_set_value(st->pdata->gpio_pdrst, 1);
+
+	ret = wait_event_interruptible(st->wq_data_avail, st->done);
+	disable_irq_nosync(st->spi->irq);
+	if (ret)
+		goto out;
+
+	ret = spi_sync_locked(st->spi, &st->msg);
+	*val = be32_to_cpu(st->data);
+out:
+	gpio_set_value(st->pdata->gpio_pdrst, 0);
+	spi_bus_unlock(st->spi->master);
+
+	return ret;
+}
+
+static int ad7780_read_raw(struct iio_dev *indio_dev,
+			   struct iio_chan_spec const *chan,
+			   int *val,
+			   int *val2,
+			   long m)
+{
+	struct ad7780_state *st = iio_priv(indio_dev);
+	struct iio_chan_spec channel = st->chip_info->channel;
+	int ret, smpl = 0;
+	unsigned long scale_uv;
+
+	switch (m) {
+	case 0:
+		mutex_lock(&indio_dev->mlock);
+		ret = ad7780_read(st, &smpl);
+		mutex_unlock(&indio_dev->mlock);
+
+		if (ret < 0)
+			return ret;
+
+		if ((smpl & AD7780_ERR) ||
+			!((smpl & AD7780_PAT0) && !(smpl & AD7780_PAT1)))
+			return -EIO;
+
+		*val = (smpl >> channel.scan_type.shift) &
+			((1 << (channel.scan_type.realbits)) - 1);
+		*val -= (1 << (channel.scan_type.realbits - 1));
+
+		if (!(smpl & AD7780_GAIN))
+			*val *= 128;
+
+		return IIO_VAL_INT;
+	case (1 << IIO_CHAN_INFO_SCALE_SHARED):
+		scale_uv = (st->int_vref_mv * 100000)
+			>> (channel.scan_type.realbits - 1);
+		*val =  scale_uv / 100000;
+		*val2 = (scale_uv % 100000) * 10;
+		return IIO_VAL_INT_PLUS_MICRO;
+	}
+	return -EINVAL;
+}
+
+static const struct ad7780_chip_info ad7780_chip_info_tbl[] = {
+	[ID_AD7780] = {
+		.channel = IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 0, 0,
+				    (1 << IIO_CHAN_INFO_SCALE_SHARED),
+				    0, 0, IIO_ST('s', 24, 32, 8), 0),
+	},
+	[ID_AD7781] = {
+		.channel = IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 0, 0,
+				    (1 << IIO_CHAN_INFO_SCALE_SHARED),
+				    0, 0, IIO_ST('s', 20, 32, 12), 0),
+	},
+};
+
+/**
+ *  Interrupt handler
+ */
+static irqreturn_t ad7780_interrupt(int irq, void *dev_id)
+{
+	struct ad7780_state *st = dev_id;
+
+	st->done = true;
+	wake_up_interruptible(&st->wq_data_avail);
+
+	return IRQ_HANDLED;
+};
+
+static const struct iio_info ad7780_info = {
+	.read_raw = &ad7780_read_raw,
+	.driver_module = THIS_MODULE,
+};
+
+static int __devinit ad7780_probe(struct spi_device *spi)
+{
+	struct ad7780_platform_data *pdata = spi->dev.platform_data;
+	struct ad7780_state *st;
+	struct iio_dev *indio_dev;
+	int ret, voltage_uv = 0;
+
+	if (!pdata) {
+		dev_dbg(&spi->dev, "no platform data?\n");
+		return -ENODEV;
+	}
+
+	indio_dev = iio_allocate_device(sizeof(*st));
+	if (indio_dev == NULL)
+		return -ENOMEM;
+
+	st = iio_priv(indio_dev);
+
+	st->reg = regulator_get(&spi->dev, "vcc");
+	if (!IS_ERR(st->reg)) {
+		ret = regulator_enable(st->reg);
+		if (ret)
+			goto error_put_reg;
+
+		voltage_uv = regulator_get_voltage(st->reg);
+	}
+
+	st->chip_info =
+		&ad7780_chip_info_tbl[spi_get_device_id(spi)->driver_data];
+
+	st->pdata = pdata;
+
+	if (pdata && pdata->vref_mv)
+		st->int_vref_mv = pdata->vref_mv;
+	else if (voltage_uv)
+		st->int_vref_mv = voltage_uv / 1000;
+	else
+		dev_warn(&spi->dev, "reference voltage unspecified\n");
+
+	spi_set_drvdata(spi, indio_dev);
+	st->spi = spi;
+
+	indio_dev->dev.parent = &spi->dev;
+	indio_dev->name = spi_get_device_id(spi)->name;
+	indio_dev->modes = INDIO_DIRECT_MODE;
+	indio_dev->channels = &st->chip_info->channel;
+	indio_dev->num_channels = 1;
+	indio_dev->info = &ad7780_info;
+
+	init_waitqueue_head(&st->wq_data_avail);
+
+	/* Setup default message */
+
+	st->xfer.rx_buf = &st->data;
+	st->xfer.len = st->chip_info->channel.scan_type.storagebits / 8;
+
+	spi_message_init(&st->msg);
+	spi_message_add_tail(&st->xfer, &st->msg);
+
+	ret = gpio_request_one(st->pdata->gpio_pdrst, GPIOF_OUT_INIT_LOW,
+			       "AD7780 /PDRST");
+	if (ret) {
+		dev_err(&spi->dev, "failed to request GPIO PDRST\n");
+		goto error_disable_reg;
+	}
+
+	ret = request_irq(spi->irq, ad7780_interrupt,
+		IRQF_TRIGGER_FALLING, spi_get_device_id(spi)->name, st);
+	if (ret)
+		goto error_free_gpio;
+
+	disable_irq(spi->irq);
+
+	ret = iio_device_register(indio_dev);
+	if (ret)
+		goto error_free_irq;
+
+	return 0;
+
+error_free_irq:
+	free_irq(spi->irq, st);
+error_free_gpio:
+	gpio_free(st->pdata->gpio_pdrst);
+error_disable_reg:
+	if (!IS_ERR(st->reg))
+		regulator_disable(st->reg);
+error_put_reg:
+	if (!IS_ERR(st->reg))
+		regulator_put(st->reg);
+
+	iio_free_device(indio_dev);
+
+	return ret;
+}
+
+static int ad7780_remove(struct spi_device *spi)
+{
+	struct iio_dev *indio_dev = spi_get_drvdata(spi);
+	struct ad7780_state *st = iio_priv(indio_dev);
+
+	free_irq(spi->irq, st);
+	gpio_free(st->pdata->gpio_pdrst);
+	if (!IS_ERR(st->reg)) {
+		regulator_disable(st->reg);
+		regulator_put(st->reg);
+	}
+	iio_device_unregister(indio_dev);
+
+	return 0;
+}
+
+static const struct spi_device_id ad7780_id[] = {
+	{"ad7780", ID_AD7780},
+	{"ad7781", ID_AD7781},
+	{}
+};
+
+static struct spi_driver ad7780_driver = {
+	.driver = {
+		.name	= "ad7780",
+		.bus	= &spi_bus_type,
+		.owner	= THIS_MODULE,
+	},
+	.probe		= ad7780_probe,
+	.remove		= __devexit_p(ad7780_remove),
+	.id_table	= ad7780_id,
+};
+
+static int __init ad7780_init(void)
+{
+	return spi_register_driver(&ad7780_driver);
+}
+module_init(ad7780_init);
+
+static void __exit ad7780_exit(void)
+{
+	spi_unregister_driver(&ad7780_driver);
+}
+module_exit(ad7780_exit);
+
+MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>");
+MODULE_DESCRIPTION("Analog Devices AD7780/1 ADC");
+MODULE_LICENSE("GPL v2");
diff -druN linux-2.6.39-libre/drivers/staging/iio/adc/ad7780.h linux-3.0-rc7-libre/drivers/staging/iio/adc/ad7780.h
--- linux-2.6.39-libre/drivers/staging/iio/adc/ad7780.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/staging/iio/adc/ad7780.h	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,30 @@
+/*
+ * AD7780/AD7781 SPI ADC driver
+ *
+ * Copyright 2011 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2.
+ */
+#ifndef IIO_ADC_AD7780_H_
+#define IIO_ADC_AD7780_H_
+
+/*
+ * TODO: struct ad7780_platform_data needs to go into include/linux/iio
+ */
+
+/* NOTE:
+ * The AD7780 doesn't feature a dedicated SPI chip select, in addition it
+ * features a dual use data out ready DOUT/RDY output.
+ * In order to avoid contentions on the SPI bus, it's therefore necessary
+ * to use spi bus locking combined with a dedicated GPIO to control the
+ * power down reset signal of the AD7780.
+ *
+ * The DOUT/RDY output must also be wired to an interrupt capable GPIO.
+ */
+
+struct ad7780_platform_data {
+	u16				vref_mv;
+	int				gpio_pdrst;
+};
+
+#endif /* IIO_ADC_AD7780_H_ */
diff -druN linux-2.6.39-libre/drivers/staging/iio/adc/ad7816.c linux-3.0-rc7-libre/drivers/staging/iio/adc/ad7816.c
--- linux-2.6.39-libre/drivers/staging/iio/adc/ad7816.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/iio/adc/ad7816.c	2011-07-11 19:51:52.000000000 -0400
@@ -8,14 +8,12 @@
 
 #include <linux/interrupt.h>
 #include <linux/gpio.h>
-#include <linux/workqueue.h>
 #include <linux/device.h>
 #include <linux/kernel.h>
 #include <linux/slab.h>
 #include <linux/sysfs.h>
 #include <linux/list.h>
 #include <linux/spi/spi.h>
-#include <linux/rtc.h>
 
 #include "../iio.h"
 #include "../sysfs.h"
@@ -44,11 +42,8 @@
  */
 
 struct ad7816_chip_info {
-	const char *name;
 	struct spi_device *spi_dev;
 	struct iio_dev *indio_dev;
-	struct work_struct thresh_work;
-	s64 last_timestamp;
 	u16 rdwr_pin;
 	u16 convert_pin;
 	u16 busy_pin;
@@ -185,13 +180,13 @@
 
 	if (data > AD7816_CS_MAX && data != AD7816_CS_MASK) {
 		dev_err(&chip->spi_dev->dev, "Invalid channel id %lu for %s.\n",
-			data, chip->name);
+			data, dev_info->name);
 		return -EINVAL;
-	} else if (strcmp(chip->name, "ad7818") == 0 && data > 1) {
+	} else if (strcmp(dev_info->name, "ad7818") == 0 && data > 1) {
 		dev_err(&chip->spi_dev->dev,
 			"Invalid channel id %lu for ad7818.\n", data);
 		return -EINVAL;
-	} else if (strcmp(chip->name, "ad7816") == 0 && data > 0) {
+	} else if (strcmp(dev_info->name, "ad7816") == 0 && data > 0) {
 		dev_err(&chip->spi_dev->dev,
 			"Invalid channel id %lu for ad7816.\n", data);
 		return -EINVAL;
@@ -236,23 +231,11 @@
 
 static IIO_DEVICE_ATTR(value, S_IRUGO, ad7816_show_value, NULL, 0);
 
-static ssize_t ad7816_show_name(struct device *dev,
-		struct device_attribute *attr,
-		char *buf)
-{
-	struct iio_dev *dev_info = dev_get_drvdata(dev);
-	struct ad7816_chip_info *chip = dev_info->dev_data;
-	return sprintf(buf, "%s\n", chip->name);
-}
-
-static IIO_DEVICE_ATTR(name, S_IRUGO, ad7816_show_name, NULL, 0);
-
 static struct attribute *ad7816_attributes[] = {
 	&iio_dev_attr_available_modes.dev_attr.attr,
 	&iio_dev_attr_mode.dev_attr.attr,
 	&iio_dev_attr_channel.dev_attr.attr,
 	&iio_dev_attr_value.dev_attr.attr,
-	&iio_dev_attr_name.dev_attr.attr,
 	NULL,
 };
 
@@ -264,35 +247,19 @@
  * temperature bound events
  */
 
-#define IIO_EVENT_CODE_AD7816_OTI    IIO_BUFFER_EVENT_CODE(0)
-
-static void ad7816_interrupt_bh(struct work_struct *work_s)
-{
-	struct ad7816_chip_info *chip =
-		container_of(work_s, struct ad7816_chip_info, thresh_work);
-
-	enable_irq(chip->spi_dev->irq);
-
-	iio_push_event(chip->indio_dev, 0,
-			IIO_EVENT_CODE_AD7816_OTI,
-			chip->last_timestamp);
-}
+#define IIO_EVENT_CODE_AD7816_OTI IIO_UNMOD_EVENT_CODE(IIO_EV_CLASS_TEMP, \
+						       0,		\
+						       IIO_EV_TYPE_THRESH, \
+						       IIO_EV_DIR_FALLING)
 
-static int ad7816_interrupt(struct iio_dev *dev_info,
-		int index,
-		s64 timestamp,
-		int no_test)
+static irqreturn_t ad7816_event_handler(int irq, void *private)
 {
-	struct ad7816_chip_info *chip = dev_info->dev_data;
-
-	chip->last_timestamp = timestamp;
-	schedule_work(&chip->thresh_work);
-
-	return 0;
+	iio_push_event(private, 0,
+		       IIO_EVENT_CODE_AD7816_OTI,
+		       iio_get_time_ns());
+	return IRQ_HANDLED;
 }
 
-IIO_EVENT_SH(ad7816, &ad7816_interrupt);
-
 static ssize_t ad7816_show_oti(struct device *dev,
 		struct device_attribute *attr,
 		char *buf)
@@ -352,11 +319,11 @@
 	return len;
 }
 
-IIO_EVENT_ATTR_SH(oti, iio_event_ad7816,
-		ad7816_show_oti, ad7816_set_oti, 0);
+static IIO_DEVICE_ATTR(oti, S_IRUGO | S_IWUSR,
+		       ad7816_show_oti, ad7816_set_oti, 0);
 
 static struct attribute *ad7816_event_attributes[] = {
-	&iio_event_attr_oti.dev_attr.attr,
+	&iio_dev_attr_oti.dev_attr.attr,
 	NULL,
 };
 
@@ -364,6 +331,13 @@
 	.attrs = ad7816_event_attributes,
 };
 
+static const struct iio_info ad7816_info = {
+	.attrs = &ad7816_attribute_group,
+	.num_interrupt_lines = 1,
+	.event_attrs = &ad7816_event_attribute_group,
+	.driver_module = THIS_MODULE,
+};
+
 /*
  * device probe and remove
  */
@@ -389,28 +363,27 @@
 	dev_set_drvdata(&spi_dev->dev, chip);
 
 	chip->spi_dev = spi_dev;
-	chip->name = spi_dev->modalias;
 	for (i = 0; i <= AD7816_CS_MAX; i++)
 		chip->oti_data[i] = 203;
 	chip->rdwr_pin = pins[0];
 	chip->convert_pin = pins[1];
 	chip->busy_pin = pins[2];
 
-	ret = gpio_request(chip->rdwr_pin, chip->name);
+	ret = gpio_request(chip->rdwr_pin, spi_get_device_id(spi_dev)->name);
 	if (ret) {
 		dev_err(&spi_dev->dev, "Fail to request rdwr gpio PIN %d.\n",
 			chip->rdwr_pin);
 		goto error_free_chip;
 	}
 	gpio_direction_input(chip->rdwr_pin);
-	ret = gpio_request(chip->convert_pin, chip->name);
+	ret = gpio_request(chip->convert_pin, spi_get_device_id(spi_dev)->name);
 	if (ret) {
 		dev_err(&spi_dev->dev, "Fail to request convert gpio PIN %d.\n",
 			chip->convert_pin);
 		goto error_free_gpio_rdwr;
 	}
 	gpio_direction_input(chip->convert_pin);
-	ret = gpio_request(chip->busy_pin, chip->name);
+	ret = gpio_request(chip->busy_pin, spi_get_device_id(spi_dev)->name);
 	if (ret) {
 		dev_err(&spi_dev->dev, "Fail to request busy gpio PIN %d.\n",
 			chip->busy_pin);
@@ -418,18 +391,15 @@
 	}
 	gpio_direction_input(chip->busy_pin);
 
-	chip->indio_dev = iio_allocate_device();
+	chip->indio_dev = iio_allocate_device(0);
 	if (chip->indio_dev == NULL) {
 		ret = -ENOMEM;
 		goto error_free_gpio;
 	}
-
+	chip->indio_dev->name = spi_get_device_id(spi_dev)->name;
 	chip->indio_dev->dev.parent = &spi_dev->dev;
-	chip->indio_dev->attrs = &ad7816_attribute_group;
-	chip->indio_dev->event_attrs = &ad7816_event_attribute_group;
+	chip->indio_dev->info = &ad7816_info;
 	chip->indio_dev->dev_data = (void *)chip;
-	chip->indio_dev->driver_module = THIS_MODULE;
-	chip->indio_dev->num_interrupt_lines = 1;
 	chip->indio_dev->modes = INDIO_DIRECT_MODE;
 
 	ret = iio_device_register(chip->indio_dev);
@@ -438,27 +408,18 @@
 
 	if (spi_dev->irq) {
 		/* Only low trigger is supported in ad7816/7/8 */
-		ret = iio_register_interrupt_line(spi_dev->irq,
-				chip->indio_dev,
-				0,
-				IRQF_TRIGGER_LOW,
-				chip->name);
+		ret = request_threaded_irq(spi_dev->irq,
+					   NULL,
+					   &ad7816_event_handler,
+					   IRQF_TRIGGER_LOW,
+					   chip->indio_dev->name,
+					   chip->indio_dev);
 		if (ret)
 			goto error_unreg_dev;
-
-		/*
-		 * The event handler list element refer to iio_event_ad7816.
-		 * All event attributes bind to the same event handler.
-		 * So, only register event handler once.
-		 */
-		iio_add_event_to_list(&iio_event_ad7816,
-				&chip->indio_dev->interrupts[0]->ev_list);
-
-		INIT_WORK(&chip->thresh_work, ad7816_interrupt_bh);
 	}
 
 	dev_info(&spi_dev->dev, "%s temperature sensor and ADC registered.\n",
-			 chip->name);
+			 chip->indio_dev->name);
 
 	return 0;
 
@@ -485,7 +446,7 @@
 
 	dev_set_drvdata(&spi_dev->dev, NULL);
 	if (spi_dev->irq)
-		iio_unregister_interrupt_line(indio_dev, 0);
+		free_irq(spi_dev->irq, indio_dev);
 	iio_device_unregister(indio_dev);
 	iio_free_device(chip->indio_dev);
 	gpio_free(chip->busy_pin);
diff -druN linux-2.6.39-libre/drivers/staging/iio/adc/ad7887_core.c linux-3.0-rc7-libre/drivers/staging/iio/adc/ad7887_core.c
--- linux-2.6.39-libre/drivers/staging/iio/adc/ad7887_core.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/iio/adc/ad7887_core.c	2011-07-11 19:51:52.000000000 -0400
@@ -1,18 +1,15 @@
 /*
  * AD7887 SPI ADC driver
  *
- * Copyright 2010 Analog Devices Inc.
+ * Copyright 2010-2011 Analog Devices Inc.
  *
- * Licensed under the GPL-2 or later.
+ * Licensed under the GPL-2.
  */
 
-#include <linux/interrupt.h>
-#include <linux/workqueue.h>
 #include <linux/device.h>
 #include <linux/kernel.h>
 #include <linux/slab.h>
 #include <linux/sysfs.h>
-#include <linux/list.h>
 #include <linux/spi/spi.h>
 #include <linux/regulator/consumer.h>
 #include <linux/err.h>
@@ -33,108 +30,75 @@
 	return (st->data[(ch * 2)] << 8) | st->data[(ch * 2) + 1];
 }
 
-static ssize_t ad7887_scan(struct device *dev,
-			    struct device_attribute *attr,
-			    char *buf)
+static int ad7887_read_raw(struct iio_dev *dev_info,
+			   struct iio_chan_spec const *chan,
+			   int *val,
+			   int *val2,
+			   long m)
 {
-	struct iio_dev *dev_info = dev_get_drvdata(dev);
-	struct ad7887_state *st = dev_info->dev_data;
-	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
 	int ret;
+	struct ad7887_state *st = dev_info->dev_data;
+	unsigned int scale_uv;
 
-	mutex_lock(&dev_info->mlock);
-	if (iio_ring_enabled(dev_info))
-		ret = ad7887_scan_from_ring(st, 1 << this_attr->address);
-	else
-		ret = ad7887_scan_direct(st, this_attr->address);
-	mutex_unlock(&dev_info->mlock);
-
-	if (ret < 0)
-		return ret;
-
-	return sprintf(buf, "%d\n", (ret >> st->chip_info->left_shift) &
-		       RES_MASK(st->chip_info->bits));
-}
-static IIO_DEV_ATTR_IN_RAW(0, ad7887_scan, 0);
-static IIO_DEV_ATTR_IN_RAW(1, ad7887_scan, 1);
-
-static ssize_t ad7887_show_scale(struct device *dev,
-				struct device_attribute *attr,
-				char *buf)
-{
-	/* Driver currently only support internal vref */
-	struct iio_dev *dev_info = dev_get_drvdata(dev);
-	struct ad7887_state *st = iio_dev_get_devdata(dev_info);
-	/* Corresponds to Vref / 2^(bits) */
-	unsigned int scale_uv = (st->int_vref_mv * 1000) >> st->chip_info->bits;
-
-	return sprintf(buf, "%d.%03d\n", scale_uv / 1000, scale_uv % 1000);
-}
-static IIO_DEVICE_ATTR(in_scale, S_IRUGO, ad7887_show_scale, NULL, 0);
-
-static ssize_t ad7887_show_name(struct device *dev,
-				 struct device_attribute *attr,
-				 char *buf)
-{
-	struct iio_dev *dev_info = dev_get_drvdata(dev);
-	struct ad7887_state *st = iio_dev_get_devdata(dev_info);
-
-	return sprintf(buf, "%s\n", spi_get_device_id(st->spi)->name);
-}
-static IIO_DEVICE_ATTR(name, S_IRUGO, ad7887_show_name, NULL, 0);
-
-static struct attribute *ad7887_attributes[] = {
-	&iio_dev_attr_in0_raw.dev_attr.attr,
-	&iio_dev_attr_in1_raw.dev_attr.attr,
-	&iio_dev_attr_in_scale.dev_attr.attr,
-	&iio_dev_attr_name.dev_attr.attr,
-	NULL,
-};
-
-static mode_t ad7887_attr_is_visible(struct kobject *kobj,
-				     struct attribute *attr, int n)
-{
-	struct device *dev = container_of(kobj, struct device, kobj);
-	struct iio_dev *dev_info = dev_get_drvdata(dev);
-	struct ad7887_state *st = iio_dev_get_devdata(dev_info);
-
-	mode_t mode = attr->mode;
-
-	if ((attr == &iio_dev_attr_in1_raw.dev_attr.attr) && !st->en_dual)
-			mode = 0;
+	switch (m) {
+	case 0:
+		mutex_lock(&dev_info->mlock);
+		if (iio_ring_enabled(dev_info))
+			ret = ad7887_scan_from_ring(st, 1 << chan->address);
+		else
+			ret = ad7887_scan_direct(st, chan->address);
+		mutex_unlock(&dev_info->mlock);
 
-	return mode;
+		if (ret < 0)
+			return ret;
+		*val = (ret >> st->chip_info->channel[0].scan_type.shift) &
+			RES_MASK(st->chip_info->channel[0].scan_type.realbits);
+		return IIO_VAL_INT;
+	case (1 << IIO_CHAN_INFO_SCALE_SHARED):
+		scale_uv = (st->int_vref_mv * 1000)
+			>> st->chip_info->channel[0].scan_type.realbits;
+		*val =  scale_uv/1000;
+		*val2 = (scale_uv%1000)*1000;
+		return IIO_VAL_INT_PLUS_MICRO;
+	}
+	return -EINVAL;
 }
 
-static const struct attribute_group ad7887_attribute_group = {
-	.attrs = ad7887_attributes,
-	.is_visible = ad7887_attr_is_visible,
-};
 
 static const struct ad7887_chip_info ad7887_chip_info_tbl[] = {
 	/*
 	 * More devices added in future
 	 */
 	[ID_AD7887] = {
-		.bits = 12,
-		.storagebits = 16,
-		.left_shift = 0,
-		.sign = IIO_SCAN_EL_TYPE_UNSIGNED,
+		.channel[0] = IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 1, 0,
+				       (1 << IIO_CHAN_INFO_SCALE_SHARED),
+				       1, 1, IIO_ST('u', 12, 16, 0), 0),
+
+		.channel[1] = IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 0, 0,
+				       (1 << IIO_CHAN_INFO_SCALE_SHARED),
+				       0, 0, IIO_ST('u', 12, 16, 0), 0),
+
+		.channel[2] = IIO_CHAN_SOFT_TIMESTAMP(2),
 		.int_vref_mv = 2500,
 	},
 };
 
+static const struct iio_info ad7887_info = {
+	.read_raw = &ad7887_read_raw,
+	.driver_module = THIS_MODULE,
+};
+
 static int __devinit ad7887_probe(struct spi_device *spi)
 {
 	struct ad7887_platform_data *pdata = spi->dev.platform_data;
 	struct ad7887_state *st;
-	int ret, voltage_uv = 0;
+	int ret, voltage_uv = 0, regdone = 0;
+	struct iio_dev *indio_dev = iio_allocate_device(sizeof(*st));
 
-	st = kzalloc(sizeof(*st), GFP_KERNEL);
-	if (st == NULL) {
-		ret = -ENOMEM;
-		goto error_ret;
-	}
+	if (indio_dev == NULL)
+		return -ENOMEM;
+
+	st = iio_priv(indio_dev);
 
 	st->reg = regulator_get(&spi->dev, "vcc");
 	if (!IS_ERR(st->reg)) {
@@ -148,23 +112,15 @@
 	st->chip_info =
 		&ad7887_chip_info_tbl[spi_get_device_id(spi)->driver_data];
 
-	spi_set_drvdata(spi, st);
-
-	atomic_set(&st->protect_ring, 0);
+	spi_set_drvdata(spi, indio_dev);
 	st->spi = spi;
 
-	st->indio_dev = iio_allocate_device();
-	if (st->indio_dev == NULL) {
-		ret = -ENOMEM;
-		goto error_disable_reg;
-	}
-
 	/* Estabilish that the iio_dev is a child of the spi device */
-	st->indio_dev->dev.parent = &spi->dev;
-	st->indio_dev->attrs = &ad7887_attribute_group;
-	st->indio_dev->dev_data = (void *)(st);
-	st->indio_dev->driver_module = THIS_MODULE;
-	st->indio_dev->modes = INDIO_DIRECT_MODE;
+	indio_dev->dev.parent = &spi->dev;
+	indio_dev->name = spi_get_device_id(spi)->name;
+	indio_dev->dev_data = (void *)(st);
+	indio_dev->info = &ad7887_info;
+	indio_dev->modes = INDIO_DIRECT_MODE;
 
 	/* Setup default message */
 
@@ -208,8 +164,6 @@
 		spi_message_init(&st->msg[AD7887_CH1]);
 		spi_message_add_tail(&st->xfer[3], &st->msg[AD7887_CH1]);
 
-		st->en_dual = true;
-
 		if (pdata && pdata->vref_mv)
 			st->int_vref_mv = pdata->vref_mv;
 		else if (voltage_uv)
@@ -217,6 +171,8 @@
 		else
 			dev_warn(&spi->dev, "reference voltage unspecified\n");
 
+		indio_dev->channels = st->chip_info->channel;
+		indio_dev->num_channels = 3;
 	} else {
 		if (pdata && pdata->vref_mv)
 			st->int_vref_mv = pdata->vref_mv;
@@ -224,50 +180,56 @@
 			st->int_vref_mv = st->chip_info->int_vref_mv;
 		else
 			dev_warn(&spi->dev, "reference voltage unspecified\n");
-	}
 
+		indio_dev->channels = &st->chip_info->channel[1];
+		indio_dev->num_channels = 2;
+	}
 
-	ret = ad7887_register_ring_funcs_and_init(st->indio_dev);
+	ret = ad7887_register_ring_funcs_and_init(indio_dev);
 	if (ret)
-		goto error_free_device;
+		goto error_disable_reg;
 
-	ret = iio_device_register(st->indio_dev);
+	ret = iio_device_register(indio_dev);
 	if (ret)
-		goto error_free_device;
+		goto error_disable_reg;
+	regdone = 1;
 
-	ret = iio_ring_buffer_register(st->indio_dev->ring, 0);
+	ret = iio_ring_buffer_register_ex(indio_dev->ring, 0,
+					  indio_dev->channels,
+					  indio_dev->num_channels);
 	if (ret)
 		goto error_cleanup_ring;
 	return 0;
 
 error_cleanup_ring:
-	ad7887_ring_cleanup(st->indio_dev);
-	iio_device_unregister(st->indio_dev);
-error_free_device:
-	iio_free_device(st->indio_dev);
+	ad7887_ring_cleanup(indio_dev);
 error_disable_reg:
 	if (!IS_ERR(st->reg))
 		regulator_disable(st->reg);
 error_put_reg:
 	if (!IS_ERR(st->reg))
 		regulator_put(st->reg);
-	kfree(st);
-error_ret:
+	if (regdone)
+		iio_device_unregister(indio_dev);
+	else
+		iio_free_device(indio_dev);
+
 	return ret;
 }
 
 static int ad7887_remove(struct spi_device *spi)
 {
-	struct ad7887_state *st = spi_get_drvdata(spi);
-	struct iio_dev *indio_dev = st->indio_dev;
+	struct iio_dev *indio_dev = spi_get_drvdata(spi);
+	struct ad7887_state *st = iio_priv(indio_dev);
+
 	iio_ring_buffer_unregister(indio_dev->ring);
 	ad7887_ring_cleanup(indio_dev);
-	iio_device_unregister(indio_dev);
 	if (!IS_ERR(st->reg)) {
 		regulator_disable(st->reg);
 		regulator_put(st->reg);
 	}
-	kfree(st);
+	iio_device_unregister(indio_dev);
+
 	return 0;
 }
 
diff -druN linux-2.6.39-libre/drivers/staging/iio/adc/ad7887.h linux-3.0-rc7-libre/drivers/staging/iio/adc/ad7887.h
--- linux-2.6.39-libre/drivers/staging/iio/adc/ad7887.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/iio/adc/ad7887.h	2011-07-11 19:51:52.000000000 -0400
@@ -48,24 +48,23 @@
 	bool				use_onchip_ref;
 };
 
+/**
+ * struct ad7887_chip_info - chip specifc information
+ * @int_vref_mv:	the internal reference voltage
+ * @channel:		channel specification
+ */
+
 struct ad7887_chip_info {
-	u8				bits;		/* number of ADC bits */
-	u8				storagebits;	/* number of bits read from the ADC */
-	u8				left_shift;	/* number of bits the sample must be shifted */
-	char				sign;		/* [s]igned or [u]nsigned */
-	u16				int_vref_mv;	/* internal reference voltage */
+	u16				int_vref_mv;
+	struct iio_chan_spec		channel[3];
 };
 
 struct ad7887_state {
-	struct iio_dev			*indio_dev;
 	struct spi_device		*spi;
 	const struct ad7887_chip_info	*chip_info;
 	struct regulator		*reg;
-	struct work_struct		poll_work;
-	atomic_t			protect_ring;
 	size_t				d_size;
 	u16				int_vref_mv;
-	bool				en_dual;
 	struct spi_transfer		xfer[4];
 	struct spi_message		msg[3];
 	struct spi_message		*ring_msg;
diff -druN linux-2.6.39-libre/drivers/staging/iio/adc/ad7887_ring.c linux-3.0-rc7-libre/drivers/staging/iio/adc/ad7887_ring.c
--- linux-2.6.39-libre/drivers/staging/iio/adc/ad7887_ring.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/iio/adc/ad7887_ring.c	2011-07-11 19:51:52.000000000 -0400
@@ -1,20 +1,17 @@
 /*
- * Copyright 2010 Analog Devices Inc.
+ * Copyright 2010-2011 Analog Devices Inc.
  * Copyright (C) 2008 Jonathan Cameron
  *
- * Licensed under the GPL-2 or later.
+ * Licensed under the GPL-2.
  *
  * ad7887_ring.c
  */
 
 #include <linux/interrupt.h>
-#include <linux/gpio.h>
-#include <linux/workqueue.h>
 #include <linux/device.h>
 #include <linux/kernel.h>
 #include <linux/slab.h>
 #include <linux/sysfs.h>
-#include <linux/list.h>
 #include <linux/spi/spi.h>
 
 #include "../iio.h"
@@ -25,64 +22,9 @@
 
 #include "ad7887.h"
 
-static IIO_SCAN_EL_C(in0, 0, 0, NULL);
-static IIO_SCAN_EL_C(in1, 1, 0, NULL);
-static IIO_SCAN_EL_TIMESTAMP(2);
-static IIO_CONST_ATTR_SCAN_EL_TYPE(timestamp, s, 64, 64);
-
-static ssize_t ad7887_show_type(struct device *dev,
-				struct device_attribute *attr,
-				char *buf)
-{
-	struct iio_ring_buffer *ring = dev_get_drvdata(dev);
-	struct iio_dev *indio_dev = ring->indio_dev;
-	struct ad7887_state *st = indio_dev->dev_data;
-
-	return sprintf(buf, "%c%d/%d>>%d\n", st->chip_info->sign,
-		       st->chip_info->bits, st->chip_info->storagebits,
-		       st->chip_info->left_shift);
-}
-static IIO_DEVICE_ATTR(in_type, S_IRUGO, ad7887_show_type, NULL, 0);
-
-static struct attribute *ad7887_scan_el_attrs[] = {
-	&iio_scan_el_in0.dev_attr.attr,
-	&iio_const_attr_in0_index.dev_attr.attr,
-	&iio_scan_el_in1.dev_attr.attr,
-	&iio_const_attr_in1_index.dev_attr.attr,
-	&iio_const_attr_timestamp_index.dev_attr.attr,
-	&iio_scan_el_timestamp.dev_attr.attr,
-	&iio_const_attr_timestamp_type.dev_attr.attr,
-	&iio_dev_attr_in_type.dev_attr.attr,
-	NULL,
-};
-
-static mode_t ad7887_scan_el_attr_is_visible(struct kobject *kobj,
-				     struct attribute *attr, int n)
-{
-	struct device *dev = container_of(kobj, struct device, kobj);
-	struct iio_ring_buffer *ring = dev_get_drvdata(dev);
-	struct iio_dev *indio_dev = ring->indio_dev;
-	struct ad7887_state *st = indio_dev->dev_data;
-
-	mode_t mode = attr->mode;
-
-	if ((attr == &iio_scan_el_in1.dev_attr.attr) ||
-		(attr == &iio_const_attr_in1_index.dev_attr.attr))
-		if (!st->en_dual)
-			mode = 0;
-
-	return mode;
-}
-
-static struct attribute_group ad7887_scan_el_group = {
-	.name = "scan_elements",
-	.attrs = ad7887_scan_el_attrs,
-	.is_visible = ad7887_scan_el_attr_is_visible,
-};
-
 int ad7887_scan_from_ring(struct ad7887_state *st, long mask)
 {
-	struct iio_ring_buffer *ring = st->indio_dev->ring;
+	struct iio_ring_buffer *ring = iio_priv_to_dev(st)->ring;
 	int count = 0, ret;
 	u16 *ring_data;
 
@@ -91,12 +33,13 @@
 		goto error_ret;
 	}
 
-	ring_data = kmalloc(ring->access.get_bytes_per_datum(ring), GFP_KERNEL);
+	ring_data = kmalloc(ring->access->get_bytes_per_datum(ring),
+			    GFP_KERNEL);
 	if (ring_data == NULL) {
 		ret = -ENOMEM;
 		goto error_ret;
 	}
-	ret = ring->access.read_last(ring, (u8 *) ring_data);
+	ret = ring->access->read_last(ring, (u8 *) ring_data);
 	if (ret)
 		goto error_free_ring_data;
 
@@ -124,7 +67,8 @@
 	struct ad7887_state *st = indio_dev->dev_data;
 	struct iio_ring_buffer *ring = indio_dev->ring;
 
-	st->d_size = ring->scan_count * st->chip_info->storagebits / 8;
+	st->d_size = ring->scan_count *
+		st->chip_info->channel[0].scan_type.storagebits / 8;
 
 	if (ring->scan_timestamp) {
 		st->d_size += sizeof(s64);
@@ -133,8 +77,8 @@
 			st->d_size += sizeof(s64) - (st->d_size % sizeof(s64));
 	}
 
-	if (indio_dev->ring->access.set_bytes_per_datum)
-		indio_dev->ring->access.set_bytes_per_datum(indio_dev->ring,
+	if (indio_dev->ring->access->set_bytes_per_datum)
+		indio_dev->ring->access->set_bytes_per_datum(indio_dev->ring,
 							    st->d_size);
 
 	switch (ring->scan_mask) {
@@ -163,48 +107,27 @@
 }
 
 /**
- * ad7887_poll_func_th() th of trigger launched polling to ring buffer
- *
- * As sampling only occurs on spi comms occurring, leave timestamping until
- * then.  Some triggers will generate their own time stamp.  Currently
- * there is no way of notifying them when no one cares.
- **/
-static void ad7887_poll_func_th(struct iio_dev *indio_dev, s64 time)
-{
-	struct ad7887_state *st = indio_dev->dev_data;
-
-	schedule_work(&st->poll_work);
-	return;
-}
-/**
- * ad7887_poll_bh_to_ring() bh of trigger launched polling to ring buffer
- * @work_s:	the work struct through which this was scheduled
+ * ad7887_trigger_handler() bh of trigger launched polling to ring buffer
  *
  * Currently there is no option in this driver to disable the saving of
  * timestamps within the ring.
- * I think the one copy of this at a time was to avoid problems if the
- * trigger was set far too high and the reads then locked up the computer.
  **/
-static void ad7887_poll_bh_to_ring(struct work_struct *work_s)
+static irqreturn_t ad7887_trigger_handler(int irq, void *p)
 {
-	struct ad7887_state *st = container_of(work_s, struct ad7887_state,
-						  poll_work);
-	struct iio_dev *indio_dev = st->indio_dev;
-	struct iio_sw_ring_buffer *sw_ring = iio_to_sw_ring(indio_dev->ring);
+	struct iio_poll_func *pf = p;
+	struct iio_dev *indio_dev = pf->private_data;
+	struct ad7887_state *st = iio_dev_get_devdata(indio_dev);
 	struct iio_ring_buffer *ring = indio_dev->ring;
 	s64 time_ns;
 	__u8 *buf;
 	int b_sent;
 
-	unsigned int bytes = ring->scan_count * st->chip_info->storagebits / 8;
-
-	/* Ensure only one copy of this function running at a time */
-	if (atomic_inc_return(&st->protect_ring) > 1)
-		return;
+	unsigned int bytes = ring->scan_count *
+		st->chip_info->channel[0].scan_type.storagebits / 8;
 
 	buf = kzalloc(st->d_size, GFP_KERNEL);
 	if (buf == NULL)
-		return;
+		return -ENOMEM;
 
 	b_sent = spi_sync(st->spi, st->ring_msg);
 	if (b_sent)
@@ -215,17 +138,25 @@
 	memcpy(buf, st->data, bytes);
 	if (ring->scan_timestamp)
 		memcpy(buf + st->d_size - sizeof(s64),
-			&time_ns, sizeof(time_ns));
+		       &time_ns, sizeof(time_ns));
 
-	indio_dev->ring->access.store_to(&sw_ring->buf, buf, time_ns);
+	indio_dev->ring->access->store_to(indio_dev->ring, buf, time_ns);
 done:
 	kfree(buf);
-	atomic_dec(&st->protect_ring);
+	iio_trigger_notify_done(indio_dev->trig);
+
+	return IRQ_HANDLED;
 }
 
+static const struct iio_ring_setup_ops ad7887_ring_setup_ops = {
+	.preenable = &ad7887_ring_preenable,
+	.postenable = &iio_triggered_ring_postenable,
+	.predisable = &iio_triggered_ring_predisable,
+	.postdisable = &ad7887_ring_postdisable,
+};
+
 int ad7887_register_ring_funcs_and_init(struct iio_dev *indio_dev)
 {
-	struct ad7887_state *st = indio_dev->dev_data;
 	int ret;
 
 	indio_dev->ring = iio_sw_rb_allocate(indio_dev);
@@ -234,25 +165,24 @@
 		goto error_ret;
 	}
 	/* Effectively select the ring buffer implementation */
-	iio_ring_sw_register_funcs(&indio_dev->ring->access);
-	ret = iio_alloc_pollfunc(indio_dev, NULL, &ad7887_poll_func_th);
-	if (ret)
+	indio_dev->ring->access = &ring_sw_access_funcs;
+	indio_dev->pollfunc = iio_alloc_pollfunc(&iio_pollfunc_store_time,
+						 &ad7887_trigger_handler,
+						 IRQF_ONESHOT,
+						 indio_dev,
+						 "ad7887_consumer%d",
+						 indio_dev->id);
+	if (indio_dev->pollfunc == NULL) {
+		ret = -ENOMEM;
 		goto error_deallocate_sw_rb;
-
+	}
 	/* Ring buffer functions - here trigger setup related */
-
-	indio_dev->ring->preenable = &ad7887_ring_preenable;
-	indio_dev->ring->postenable = &iio_triggered_ring_postenable;
-	indio_dev->ring->predisable = &iio_triggered_ring_predisable;
-	indio_dev->ring->postdisable = &ad7887_ring_postdisable;
-	indio_dev->ring->scan_el_attrs = &ad7887_scan_el_group;
-	indio_dev->ring->scan_timestamp = true;
-
-	INIT_WORK(&st->poll_work, &ad7887_poll_bh_to_ring);
+	indio_dev->ring->setup_ops = &ad7887_ring_setup_ops;
 
 	/* Flag that polled ring buffering is possible */
 	indio_dev->modes |= INDIO_RING_TRIGGERED;
 	return 0;
+
 error_deallocate_sw_rb:
 	iio_sw_rb_free(indio_dev->ring);
 error_ret:
@@ -267,6 +197,6 @@
 		iio_trigger_dettach_poll_func(indio_dev->trig,
 					      indio_dev->pollfunc);
 	}
-	kfree(indio_dev->pollfunc);
+	iio_dealloc_pollfunc(indio_dev->pollfunc);
 	iio_sw_rb_free(indio_dev->ring);
 }
diff -druN linux-2.6.39-libre/drivers/staging/iio/adc/ad799x_core.c linux-3.0-rc7-libre/drivers/staging/iio/adc/ad799x_core.c
--- linux-2.6.39-libre/drivers/staging/iio/adc/ad799x_core.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/iio/adc/ad799x_core.c	2011-07-11 19:51:52.000000000 -0400
@@ -1,6 +1,6 @@
 /*
  * iio/adc/ad799x.c
- * Copyright (C) 2010 Michael Hennerich, Analog Devices Inc.
+ * Copyright (C) 2010-1011 Michael Hennerich, Analog Devices Inc.
  *
  * based on iio/adc/max1363
  * Copyright (C) 2008-2010 Jonathan Cameron
@@ -23,11 +23,9 @@
  */
 
 #include <linux/interrupt.h>
-#include <linux/workqueue.h>
 #include <linux/device.h>
 #include <linux/kernel.h>
 #include <linux/sysfs.h>
-#include <linux/list.h>
 #include <linux/i2c.h>
 #include <linux/regulator/consumer.h>
 #include <linux/slab.h>
@@ -100,130 +98,77 @@
 	return ret;
 }
 
-static int ad799x_scan_el_set_state(struct iio_scan_el *scan_el,
-				       struct iio_dev *indio_dev,
-				       bool state)
-{
-	struct ad799x_state *st = indio_dev->dev_data;
-	return ad799x_set_scan_mode(st, st->indio_dev->ring->scan_mask);
-}
-
-/* Here we claim all are 16 bits. This currently does no harm and saves
- * us a lot of scan element listings */
-
-#define AD799X_SCAN_EL(number)						\
-	IIO_SCAN_EL_C(in##number, number, 0, ad799x_scan_el_set_state);
-
-static AD799X_SCAN_EL(0);
-static AD799X_SCAN_EL(1);
-static AD799X_SCAN_EL(2);
-static AD799X_SCAN_EL(3);
-static AD799X_SCAN_EL(4);
-static AD799X_SCAN_EL(5);
-static AD799X_SCAN_EL(6);
-static AD799X_SCAN_EL(7);
-
-static IIO_SCAN_EL_TIMESTAMP(8);
-static IIO_CONST_ATTR_SCAN_EL_TYPE(timestamp, s, 64, 64)
-
-static ssize_t ad799x_show_type(struct device *dev,
-				struct device_attribute *attr,
-				char *buf)
-{
-	struct iio_ring_buffer *ring = dev_get_drvdata(dev);
-	struct iio_dev *indio_dev = ring->indio_dev;
-	struct ad799x_state *st = indio_dev->dev_data;
-
-	return sprintf(buf, "%c%d/%d\n", st->chip_info->sign,
-		       st->chip_info->bits, AD799X_STORAGEBITS);
-}
-static IIO_DEVICE_ATTR(in_type, S_IRUGO, ad799x_show_type, NULL, 0);
-
-static int ad7991_5_9_set_scan_mode(struct ad799x_state *st, unsigned mask)
-{
-	return i2c_smbus_write_byte(st->client,
-		st->config | (mask << AD799X_CHANNEL_SHIFT));
-}
-
-static int ad7992_3_4_set_scan_mode(struct ad799x_state *st, unsigned mask)
-{
-	return ad799x_i2c_write8(st, AD7998_CONF_REG,
-		st->config | (mask << AD799X_CHANNEL_SHIFT));
-}
-
-static int ad7997_8_set_scan_mode(struct ad799x_state *st, unsigned mask)
+int ad7997_8_set_scan_mode(struct ad799x_state *st, unsigned mask)
 {
 	return ad799x_i2c_write16(st, AD7998_CONF_REG,
 		st->config | (mask << AD799X_CHANNEL_SHIFT));
 }
 
-int ad799x_set_scan_mode(struct ad799x_state *st, unsigned mask)
+static int ad799x_scan_direct(struct ad799x_state *st, unsigned ch)
 {
+	u16 rxbuf;
+	u8 cmd;
 	int ret;
 
-	if (st->chip_info->ad799x_set_scan_mode != NULL) {
-		ret = st->chip_info->ad799x_set_scan_mode(st, mask);
-		return (ret > 0) ? 0 : ret;
+	switch (st->id) {
+	case ad7991:
+	case ad7995:
+	case ad7999:
+		cmd = st->config | ((1 << ch) << AD799X_CHANNEL_SHIFT);
+		break;
+	case ad7992:
+	case ad7993:
+	case ad7994:
+		cmd = (1 << ch) << AD799X_CHANNEL_SHIFT;
+		break;
+	case ad7997:
+	case ad7998:
+		cmd = (ch << AD799X_CHANNEL_SHIFT) | AD7997_8_READ_SINGLE;
+		break;
+	default:
+		return -EINVAL;
 	}
 
-	return 0;
+	ret = ad799x_i2c_read16(st, cmd, &rxbuf);
+	if (ret < 0)
+		return ret;
+
+	return rxbuf;
 }
 
-static ssize_t ad799x_read_single_channel(struct device *dev,
-				   struct device_attribute *attr,
-				   char *buf)
+static int ad799x_read_raw(struct iio_dev *dev_info,
+			   struct iio_chan_spec const *chan,
+			   int *val,
+			   int *val2,
+			   long m)
 {
-	struct iio_dev *dev_info = dev_get_drvdata(dev);
-	struct ad799x_state *st = iio_dev_get_devdata(dev_info);
-	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
-	int ret = 0, len = 0;
-	u32 data ;
-	u16 rxbuf[1];
-	u8 cmd;
-	long mask;
+	int ret;
+	struct ad799x_state *st = dev_info->dev_data;
+	unsigned int scale_uv;
 
-	mutex_lock(&dev_info->mlock);
-	mask = 1 << this_attr->address;
-	/* If ring buffer capture is occurring, query the buffer */
-	if (iio_ring_enabled(dev_info)) {
-		data = ret = ad799x_single_channel_from_ring(st, mask);
-		if (ret < 0)
-			goto error_ret;
-		ret = 0;
-	} else {
-		switch (st->id) {
-		case ad7991:
-		case ad7995:
-		case ad7999:
-			cmd = st->config | (mask << AD799X_CHANNEL_SHIFT);
-			break;
-		case ad7992:
-		case ad7993:
-		case ad7994:
-			cmd = mask << AD799X_CHANNEL_SHIFT;
-			break;
-		case ad7997:
-		case ad7998:
-			cmd = (this_attr->address <<
-				AD799X_CHANNEL_SHIFT) | AD7997_8_READ_SINGLE;
-			break;
-		default:
-			cmd = 0;
+	switch (m) {
+	case 0:
+		mutex_lock(&dev_info->mlock);
+		if (iio_ring_enabled(dev_info))
+			ret = ad799x_single_channel_from_ring(st,
+				1 << chan->address);
+		else
+			ret = ad799x_scan_direct(st, chan->address);
+		mutex_unlock(&dev_info->mlock);
 
-		}
-		ret = ad799x_i2c_read16(st, cmd, rxbuf);
 		if (ret < 0)
-			goto error_ret;
-
-		data = rxbuf[0];
+			return ret;
+		*val = (ret >> st->chip_info->channel[0].scan_type.shift) &
+			RES_MASK(st->chip_info->channel[0].scan_type.realbits);
+		return IIO_VAL_INT;
+	case (1 << IIO_CHAN_INFO_SCALE_SHARED):
+		scale_uv = (st->int_vref_mv * 1000)
+			>> st->chip_info->channel[0].scan_type.realbits;
+		*val =  scale_uv / 1000;
+		*val2 = (scale_uv % 1000) * 1000;
+		return IIO_VAL_INT_PLUS_MICRO;
 	}
-
-	/* Pretty print the result */
-	len = sprintf(buf, "%u\n", data & ((1 << (st->chip_info->bits)) - 1));
-
-error_ret:
-	mutex_unlock(&dev_info->mlock);
-	return ret ? ret : len;
+	return -EINVAL;
 }
 
 static ssize_t ad799x_read_frequency(struct device *dev,
@@ -331,18 +276,17 @@
 	return ret ? ret : len;
 }
 
-
 static ssize_t ad799x_read_channel_config(struct device *dev,
 					struct device_attribute *attr,
 					char *buf)
 {
 	struct iio_dev *dev_info = dev_get_drvdata(dev);
 	struct ad799x_state *st = iio_dev_get_devdata(dev_info);
-	struct iio_event_attr *this_attr = to_iio_event_attr(attr);
+	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
 
 	int ret;
 	u16 val;
-	ret = ad799x_i2c_read16(st, this_attr->mask, &val);
+	ret = ad799x_i2c_read16(st, this_attr->address, &val);
 	if (ret)
 		return ret;
 
@@ -356,7 +300,7 @@
 {
 	struct iio_dev *dev_info = dev_get_drvdata(dev);
 	struct ad799x_state *st = iio_dev_get_devdata(dev_info);
-	struct iio_event_attr *this_attr = to_iio_event_attr(attr);
+	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
 
 	long val;
 	int ret;
@@ -366,273 +310,111 @@
 		return ret;
 
 	mutex_lock(&dev_info->mlock);
-	ret = ad799x_i2c_write16(st, this_attr->mask, val);
+	ret = ad799x_i2c_write16(st, this_attr->address, val);
 	mutex_unlock(&dev_info->mlock);
 
 	return ret ? ret : len;
 }
 
-static void ad799x_interrupt_bh(struct work_struct *work_s)
+static irqreturn_t ad799x_event_handler(int irq, void *private)
 {
-	struct ad799x_state *st = container_of(work_s,
-		struct ad799x_state, work_thresh);
+	struct iio_dev *indio_dev = private;
+	struct ad799x_state *st = iio_dev_get_devdata(private);
 	u8 status;
-	int i;
+	int i, ret;
 
-	if (ad799x_i2c_read8(st, AD7998_ALERT_STAT_REG, &status))
-		goto err_out;
+	ret = ad799x_i2c_read8(st, AD7998_ALERT_STAT_REG, &status);
+	if (ret)
+		return ret;
 
 	if (!status)
-		goto err_out;
+		return -EIO;
 
 	ad799x_i2c_write8(st, AD7998_ALERT_STAT_REG, AD7998_ALERT_STAT_CLEAR);
 
 	for (i = 0; i < 8; i++) {
 		if (status & (1 << i))
-			iio_push_event(st->indio_dev, 0,
-				i & 0x1 ?
-				IIO_EVENT_CODE_IN_HIGH_THRESH(i >> 1) :
-				IIO_EVENT_CODE_IN_LOW_THRESH(i >> 1),
-				st->last_timestamp);
+			iio_push_event(indio_dev, 0,
+				       i & 0x1 ?
+				       IIO_EVENT_CODE_IN_HIGH_THRESH(i >> 1) :
+				       IIO_EVENT_CODE_IN_LOW_THRESH(i >> 1),
+				       iio_get_time_ns());
 	}
 
-err_out:
-	enable_irq(st->client->irq);
-}
-
-static int ad799x_interrupt(struct iio_dev *dev_info,
-		int index,
-		s64 timestamp,
-		int no_test)
-{
-	struct ad799x_state *st = dev_info->dev_data;
-
-	st->last_timestamp = timestamp;
-	schedule_work(&st->work_thresh);
-	return 0;
-}
-
-IIO_EVENT_SH(ad799x, &ad799x_interrupt);
-
-/* Direct read attribtues */
-static IIO_DEV_ATTR_IN_RAW(0, ad799x_read_single_channel, 0);
-static IIO_DEV_ATTR_IN_RAW(1, ad799x_read_single_channel, 1);
-static IIO_DEV_ATTR_IN_RAW(2, ad799x_read_single_channel, 2);
-static IIO_DEV_ATTR_IN_RAW(3, ad799x_read_single_channel, 3);
-static IIO_DEV_ATTR_IN_RAW(4, ad799x_read_single_channel, 4);
-static IIO_DEV_ATTR_IN_RAW(5, ad799x_read_single_channel, 5);
-static IIO_DEV_ATTR_IN_RAW(6, ad799x_read_single_channel, 6);
-static IIO_DEV_ATTR_IN_RAW(7, ad799x_read_single_channel, 7);
-
-static ssize_t ad799x_show_scale(struct device *dev,
-				struct device_attribute *attr,
-				char *buf)
-{
-	/* Driver currently only support internal vref */
-	struct iio_dev *dev_info = dev_get_drvdata(dev);
-	struct ad799x_state *st = iio_dev_get_devdata(dev_info);
-
-	/* Corresponds to Vref / 2^(bits) */
-	unsigned int scale_uv = (st->int_vref_mv * 1000) >> st->chip_info->bits;
-
-	return sprintf(buf, "%d.%03d\n", scale_uv / 1000, scale_uv % 1000);
-}
-
-static IIO_DEVICE_ATTR(in_scale, S_IRUGO, ad799x_show_scale, NULL, 0);
-
-static ssize_t ad799x_show_name(struct device *dev,
-				 struct device_attribute *attr,
-				 char *buf)
-{
-	struct iio_dev *dev_info = dev_get_drvdata(dev);
-	struct ad799x_state *st = iio_dev_get_devdata(dev_info);
-	return sprintf(buf, "%s\n", st->client->name);
+	return IRQ_HANDLED;
 }
 
-static IIO_DEVICE_ATTR(name, S_IRUGO, ad799x_show_name, NULL, 0);
-
-static struct attribute *ad7991_5_9_3_4_device_attrs[] = {
-	&iio_dev_attr_in0_raw.dev_attr.attr,
-	&iio_dev_attr_in1_raw.dev_attr.attr,
-	&iio_dev_attr_in2_raw.dev_attr.attr,
-	&iio_dev_attr_in3_raw.dev_attr.attr,
-	&iio_dev_attr_name.dev_attr.attr,
-	&iio_dev_attr_in_scale.dev_attr.attr,
-	NULL
-};
-
-static struct attribute_group ad7991_5_9_3_4_dev_attr_group = {
-	.attrs = ad7991_5_9_3_4_device_attrs,
-};
-
-static struct attribute *ad7991_5_9_3_4_scan_el_attrs[] = {
-	&iio_scan_el_in0.dev_attr.attr,
-	&iio_const_attr_in0_index.dev_attr.attr,
-	&iio_scan_el_in1.dev_attr.attr,
-	&iio_const_attr_in1_index.dev_attr.attr,
-	&iio_scan_el_in2.dev_attr.attr,
-	&iio_const_attr_in2_index.dev_attr.attr,
-	&iio_scan_el_in3.dev_attr.attr,
-	&iio_const_attr_in3_index.dev_attr.attr,
-	&iio_const_attr_timestamp_index.dev_attr.attr,
-	&iio_scan_el_timestamp.dev_attr.attr,
-	&iio_const_attr_timestamp_type.dev_attr.attr,
-	&iio_dev_attr_in_type.dev_attr.attr,
-	NULL,
-};
-
-static struct attribute_group ad7991_5_9_3_4_scan_el_group = {
-	.name = "scan_elements",
-	.attrs = ad7991_5_9_3_4_scan_el_attrs,
-};
-
-static struct attribute *ad7992_device_attrs[] = {
-	&iio_dev_attr_in0_raw.dev_attr.attr,
-	&iio_dev_attr_in1_raw.dev_attr.attr,
-	&iio_dev_attr_name.dev_attr.attr,
-	&iio_dev_attr_in_scale.dev_attr.attr,
-	NULL
-};
-
-static struct attribute_group ad7992_dev_attr_group = {
-	.attrs = ad7992_device_attrs,
-};
-
-static struct attribute *ad7992_scan_el_attrs[] = {
-	&iio_scan_el_in0.dev_attr.attr,
-	&iio_const_attr_in0_index.dev_attr.attr,
-	&iio_scan_el_in1.dev_attr.attr,
-	&iio_const_attr_in1_index.dev_attr.attr,
-	&iio_const_attr_timestamp_index.dev_attr.attr,
-	&iio_scan_el_timestamp.dev_attr.attr,
-	&iio_const_attr_timestamp_type.dev_attr.attr,
-	&iio_dev_attr_in_type.dev_attr.attr,
-	NULL,
-};
-
-static struct attribute_group ad7992_scan_el_group = {
-	.name = "scan_elements",
-	.attrs = ad7992_scan_el_attrs,
-};
-
-static struct attribute *ad7997_8_device_attrs[] = {
-	&iio_dev_attr_in0_raw.dev_attr.attr,
-	&iio_dev_attr_in1_raw.dev_attr.attr,
-	&iio_dev_attr_in2_raw.dev_attr.attr,
-	&iio_dev_attr_in3_raw.dev_attr.attr,
-	&iio_dev_attr_in4_raw.dev_attr.attr,
-	&iio_dev_attr_in5_raw.dev_attr.attr,
-	&iio_dev_attr_in6_raw.dev_attr.attr,
-	&iio_dev_attr_in7_raw.dev_attr.attr,
-	&iio_dev_attr_name.dev_attr.attr,
-	&iio_dev_attr_in_scale.dev_attr.attr,
-	NULL
-};
-
-static struct attribute_group ad7997_8_dev_attr_group = {
-	.attrs = ad7997_8_device_attrs,
-};
-
-static struct attribute *ad7997_8_scan_el_attrs[] = {
-	&iio_scan_el_in0.dev_attr.attr,
-	&iio_const_attr_in0_index.dev_attr.attr,
-	&iio_scan_el_in1.dev_attr.attr,
-	&iio_const_attr_in1_index.dev_attr.attr,
-	&iio_scan_el_in2.dev_attr.attr,
-	&iio_const_attr_in2_index.dev_attr.attr,
-	&iio_scan_el_in3.dev_attr.attr,
-	&iio_const_attr_in3_index.dev_attr.attr,
-	&iio_scan_el_in4.dev_attr.attr,
-	&iio_const_attr_in4_index.dev_attr.attr,
-	&iio_scan_el_in5.dev_attr.attr,
-	&iio_const_attr_in5_index.dev_attr.attr,
-	&iio_scan_el_in6.dev_attr.attr,
-	&iio_const_attr_in6_index.dev_attr.attr,
-	&iio_scan_el_in7.dev_attr.attr,
-	&iio_const_attr_in7_index.dev_attr.attr,
-	&iio_const_attr_timestamp_index.dev_attr.attr,
-	&iio_scan_el_timestamp.dev_attr.attr,
-	&iio_const_attr_timestamp_type.dev_attr.attr,
-	&iio_dev_attr_in_type.dev_attr.attr,
-	NULL,
-};
-
-static struct attribute_group ad7997_8_scan_el_group = {
-	.name = "scan_elements",
-	.attrs = ad7997_8_scan_el_attrs,
-};
-
-IIO_EVENT_ATTR_SH(in0_thresh_low_value,
-		  iio_event_ad799x,
-		  ad799x_read_channel_config,
-		  ad799x_write_channel_config,
-		  AD7998_DATALOW_CH1_REG);
+static IIO_DEVICE_ATTR(in0_thresh_low_value,
+		       S_IRUGO | S_IWUSR,
+		       ad799x_read_channel_config,
+		       ad799x_write_channel_config,
+		       AD7998_DATALOW_CH1_REG);
 
-IIO_EVENT_ATTR_SH(in0_thresh_high_value,
-		  iio_event_ad799x,
-		  ad799x_read_channel_config,
-		  ad799x_write_channel_config,
-		  AD7998_DATAHIGH_CH1_REG);
+static IIO_DEVICE_ATTR(in0_thresh_high_value,
+		       S_IRUGO | S_IWUSR,
+		       ad799x_read_channel_config,
+		       ad799x_write_channel_config,
+		       AD7998_DATAHIGH_CH1_REG);
 
-IIO_EVENT_ATTR_SH(in0_thresh_both_hyst_raw,
-		  iio_event_ad799x,
-		  ad799x_read_channel_config,
-		  ad799x_write_channel_config,
-		  AD7998_HYST_CH1_REG);
+static IIO_DEVICE_ATTR(in0_thresh_both_hyst_raw,
+		       S_IRUGO | S_IWUSR,
+		       ad799x_read_channel_config,
+		       ad799x_write_channel_config,
+		       AD7998_HYST_CH1_REG);
 
-IIO_EVENT_ATTR_SH(in1_thresh_low_value,
-		  iio_event_ad799x,
-		  ad799x_read_channel_config,
-		  ad799x_write_channel_config,
-		  AD7998_DATALOW_CH2_REG);
+static IIO_DEVICE_ATTR(in1_thresh_low_value,
+		       S_IRUGO | S_IWUSR,
+		       ad799x_read_channel_config,
+		       ad799x_write_channel_config,
+		       AD7998_DATALOW_CH2_REG);
 
-IIO_EVENT_ATTR_SH(in1_thresh_high_value,
-		  iio_event_ad799x,
-		  ad799x_read_channel_config,
-		  ad799x_write_channel_config,
-		  AD7998_DATAHIGH_CH2_REG);
+static IIO_DEVICE_ATTR(in1_thresh_high_value,
+		       S_IRUGO | S_IWUSR,
+		       ad799x_read_channel_config,
+		       ad799x_write_channel_config,
+		       AD7998_DATAHIGH_CH2_REG);
 
-IIO_EVENT_ATTR_SH(in1_thresh_both_hyst_raw,
-		  iio_event_ad799x,
-		  ad799x_read_channel_config,
-		  ad799x_write_channel_config,
-		  AD7998_HYST_CH2_REG);
+static IIO_DEVICE_ATTR(in1_thresh_both_hyst_raw,
+		       S_IRUGO | S_IWUSR,
+		       ad799x_read_channel_config,
+		       ad799x_write_channel_config,
+		       AD7998_HYST_CH2_REG);
 
-IIO_EVENT_ATTR_SH(in2_thresh_low_value,
-		  iio_event_ad799x,
-		  ad799x_read_channel_config,
-		  ad799x_write_channel_config,
-		  AD7998_DATALOW_CH3_REG);
+static IIO_DEVICE_ATTR(in2_thresh_low_value,
+		       S_IRUGO | S_IWUSR,
+		       ad799x_read_channel_config,
+		       ad799x_write_channel_config,
+		       AD7998_DATALOW_CH3_REG);
 
-IIO_EVENT_ATTR_SH(in2_thresh_high_value,
-		  iio_event_ad799x,
-		  ad799x_read_channel_config,
-		  ad799x_write_channel_config,
-		  AD7998_DATAHIGH_CH3_REG);
+static IIO_DEVICE_ATTR(in2_thresh_high_value,
+		       S_IRUGO | S_IWUSR,
+		       ad799x_read_channel_config,
+		       ad799x_write_channel_config,
+		       AD7998_DATAHIGH_CH3_REG);
 
-IIO_EVENT_ATTR_SH(in2_thresh_both_hyst_raw,
-		  iio_event_ad799x,
-		  ad799x_read_channel_config,
-		  ad799x_write_channel_config,
-		  AD7998_HYST_CH3_REG);
+static IIO_DEVICE_ATTR(in2_thresh_both_hyst_raw,
+		       S_IRUGO | S_IWUSR,
+		       ad799x_read_channel_config,
+		       ad799x_write_channel_config,
+		       AD7998_HYST_CH3_REG);
 
-IIO_EVENT_ATTR_SH(in3_thresh_low_value,
-		  iio_event_ad799x,
-		  ad799x_read_channel_config,
-		  ad799x_write_channel_config,
-		  AD7998_DATALOW_CH4_REG);
+static IIO_DEVICE_ATTR(in3_thresh_low_value,
+		       S_IRUGO | S_IWUSR,
+		       ad799x_read_channel_config,
+		       ad799x_write_channel_config,
+		       AD7998_DATALOW_CH4_REG);
 
-IIO_EVENT_ATTR_SH(in3_thresh_high_value,
-		  iio_event_ad799x,
-		  ad799x_read_channel_config,
-		  ad799x_write_channel_config,
-		  AD7998_DATAHIGH_CH4_REG);
+static IIO_DEVICE_ATTR(in3_thresh_high_value,
+		       S_IRUGO | S_IWUSR,
+		       ad799x_read_channel_config,
+		       ad799x_write_channel_config,
+		       AD7998_DATAHIGH_CH4_REG);
 
-IIO_EVENT_ATTR_SH(in3_thresh_both_hyst_raw,
-		  iio_event_ad799x,
-		  ad799x_read_channel_config,
-		  ad799x_write_channel_config,
-		  AD7998_HYST_CH4_REG);
+static IIO_DEVICE_ATTR(in3_thresh_both_hyst_raw,
+		       S_IRUGO | S_IWUSR,
+		       ad799x_read_channel_config,
+		       ad799x_write_channel_config,
+		       AD7998_HYST_CH4_REG);
 
 static IIO_DEV_ATTR_SAMP_FREQ(S_IWUSR | S_IRUGO,
 			      ad799x_read_frequency,
@@ -640,18 +422,18 @@
 static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("15625 7812 3906 1953 976 488 244 0");
 
 static struct attribute *ad7993_4_7_8_event_attributes[] = {
-	&iio_event_attr_in0_thresh_low_value.dev_attr.attr,
-	&iio_event_attr_in0_thresh_high_value.dev_attr.attr,
-	&iio_event_attr_in0_thresh_both_hyst_raw.dev_attr.attr,
-	&iio_event_attr_in1_thresh_low_value.dev_attr.attr,
-	&iio_event_attr_in1_thresh_high_value.dev_attr.attr,
-	&iio_event_attr_in1_thresh_both_hyst_raw.dev_attr.attr,
-	&iio_event_attr_in2_thresh_low_value.dev_attr.attr,
-	&iio_event_attr_in2_thresh_high_value.dev_attr.attr,
-	&iio_event_attr_in2_thresh_both_hyst_raw.dev_attr.attr,
-	&iio_event_attr_in3_thresh_low_value.dev_attr.attr,
-	&iio_event_attr_in3_thresh_high_value.dev_attr.attr,
-	&iio_event_attr_in3_thresh_both_hyst_raw.dev_attr.attr,
+	&iio_dev_attr_in0_thresh_low_value.dev_attr.attr,
+	&iio_dev_attr_in0_thresh_high_value.dev_attr.attr,
+	&iio_dev_attr_in0_thresh_both_hyst_raw.dev_attr.attr,
+	&iio_dev_attr_in1_thresh_low_value.dev_attr.attr,
+	&iio_dev_attr_in1_thresh_high_value.dev_attr.attr,
+	&iio_dev_attr_in1_thresh_both_hyst_raw.dev_attr.attr,
+	&iio_dev_attr_in2_thresh_low_value.dev_attr.attr,
+	&iio_dev_attr_in2_thresh_high_value.dev_attr.attr,
+	&iio_dev_attr_in2_thresh_both_hyst_raw.dev_attr.attr,
+	&iio_dev_attr_in3_thresh_low_value.dev_attr.attr,
+	&iio_dev_attr_in3_thresh_high_value.dev_attr.attr,
+	&iio_dev_attr_in3_thresh_both_hyst_raw.dev_attr.attr,
 	&iio_dev_attr_sampling_frequency.dev_attr.attr,
 	&iio_const_attr_sampling_frequency_available.dev_attr.attr,
 	NULL,
@@ -662,12 +444,12 @@
 };
 
 static struct attribute *ad7992_event_attributes[] = {
-	&iio_event_attr_in0_thresh_low_value.dev_attr.attr,
-	&iio_event_attr_in0_thresh_high_value.dev_attr.attr,
-	&iio_event_attr_in0_thresh_both_hyst_raw.dev_attr.attr,
-	&iio_event_attr_in1_thresh_low_value.dev_attr.attr,
-	&iio_event_attr_in1_thresh_high_value.dev_attr.attr,
-	&iio_event_attr_in1_thresh_both_hyst_raw.dev_attr.attr,
+	&iio_dev_attr_in0_thresh_low_value.dev_attr.attr,
+	&iio_dev_attr_in0_thresh_high_value.dev_attr.attr,
+	&iio_dev_attr_in0_thresh_both_hyst_raw.dev_attr.attr,
+	&iio_dev_attr_in1_thresh_low_value.dev_attr.attr,
+	&iio_dev_attr_in1_thresh_high_value.dev_attr.attr,
+	&iio_dev_attr_in1_thresh_both_hyst_raw.dev_attr.attr,
 	&iio_dev_attr_sampling_frequency.dev_attr.attr,
 	&iio_const_attr_sampling_frequency_available.dev_attr.attr,
 	NULL,
@@ -677,93 +459,192 @@
 	.attrs = ad7992_event_attributes,
 };
 
+static const struct iio_info ad7991_info = {
+	.read_raw = &ad799x_read_raw,
+	.driver_module = THIS_MODULE,
+};
+
+static const struct iio_info ad7992_info = {
+	.read_raw = &ad799x_read_raw,
+	.num_interrupt_lines = 1,
+	.event_attrs = &ad7992_event_attrs_group,
+	.driver_module = THIS_MODULE,
+};
+
+static const struct iio_info ad7993_4_7_8_info = {
+	.read_raw = &ad799x_read_raw,
+	.num_interrupt_lines = 1,
+	.event_attrs = &ad7993_4_7_8_event_attrs_group,
+	.driver_module = THIS_MODULE,
+};
+
 static const struct ad799x_chip_info ad799x_chip_info_tbl[] = {
 	[ad7991] = {
-		.num_inputs = 4,
-		.bits = 12,
-		.sign = IIO_SCAN_EL_TYPE_UNSIGNED,
+		.channel[0] = IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 0, 0,
+				       (1 << IIO_CHAN_INFO_SCALE_SHARED),
+				       0, 0, IIO_ST('u', 12, 16, 0), 0),
+		.channel[1] = IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 1, 0,
+				       (1 << IIO_CHAN_INFO_SCALE_SHARED),
+				       1, 1, IIO_ST('u', 12, 16, 0), 0),
+		.channel[2] = IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 2, 0,
+				       (1 << IIO_CHAN_INFO_SCALE_SHARED),
+				       2, 2, IIO_ST('u', 12, 16, 0), 0),
+		.channel[3] = IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 3, 0,
+				       (1 << IIO_CHAN_INFO_SCALE_SHARED),
+				       3, 3, IIO_ST('u', 12, 16, 0), 0),
+		.channel[4] = IIO_CHAN_SOFT_TIMESTAMP(4),
+		.num_channels = 5,
 		.int_vref_mv = 4096,
-		.dev_attrs = &ad7991_5_9_3_4_dev_attr_group,
-		.scan_attrs = &ad7991_5_9_3_4_scan_el_group,
-		.ad799x_set_scan_mode = ad7991_5_9_set_scan_mode,
+		.info = &ad7991_info,
 	},
 	[ad7995] = {
-		.num_inputs = 4,
-		.bits = 10,
-		.sign = IIO_SCAN_EL_TYPE_UNSIGNED,
+		.channel[0] = IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 0, 0,
+				       (1 << IIO_CHAN_INFO_SCALE_SHARED),
+				       0, 0, IIO_ST('u', 10, 16, 0), 0),
+		.channel[1] = IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 1, 0,
+				       (1 << IIO_CHAN_INFO_SCALE_SHARED),
+				       1, 1, IIO_ST('u', 10, 16, 0), 0),
+		.channel[2] = IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 2, 0,
+				       (1 << IIO_CHAN_INFO_SCALE_SHARED),
+				       2, 2, IIO_ST('u', 10, 16, 0), 0),
+		.channel[3] = IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 3, 0,
+				       (1 << IIO_CHAN_INFO_SCALE_SHARED),
+				       3, 3, IIO_ST('u', 10, 16, 0), 0),
+		.channel[4] = IIO_CHAN_SOFT_TIMESTAMP(4),
+		.num_channels = 5,
 		.int_vref_mv = 1024,
-		.dev_attrs = &ad7991_5_9_3_4_dev_attr_group,
-		.scan_attrs = &ad7991_5_9_3_4_scan_el_group,
-		.ad799x_set_scan_mode = ad7991_5_9_set_scan_mode,
+		.info = &ad7991_info,
 	},
 	[ad7999] = {
-		.num_inputs = 4,
-		.bits = 10,
-		.sign = IIO_SCAN_EL_TYPE_UNSIGNED,
+		.channel[0] = IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 0, 0,
+				       (1 << IIO_CHAN_INFO_SCALE_SHARED),
+				       0, 0, IIO_ST('u', 10, 16, 0), 0),
+		.channel[1] = IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 1, 0,
+				       (1 << IIO_CHAN_INFO_SCALE_SHARED),
+				       1, 1, IIO_ST('u', 10, 16, 0), 0),
+		.channel[2] = IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 2, 0,
+				       (1 << IIO_CHAN_INFO_SCALE_SHARED),
+				       2, 2, IIO_ST('u', 10, 16, 0), 0),
+		.channel[3] = IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 3, 0,
+				       (1 << IIO_CHAN_INFO_SCALE_SHARED),
+				       3, 3, IIO_ST('u', 10, 16, 0), 0),
+		.channel[4] = IIO_CHAN_SOFT_TIMESTAMP(4),
+		.num_channels = 5,
 		.int_vref_mv = 1024,
-		.dev_attrs = &ad7991_5_9_3_4_dev_attr_group,
-		.scan_attrs = &ad7991_5_9_3_4_scan_el_group,
-		.ad799x_set_scan_mode = ad7991_5_9_set_scan_mode,
+		.info = &ad7991_info,
 	},
 	[ad7992] = {
-		.num_inputs = 2,
-		.bits = 12,
-		.sign = IIO_SCAN_EL_TYPE_UNSIGNED,
+		.channel[0] = IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 0, 0,
+				       (1 << IIO_CHAN_INFO_SCALE_SHARED),
+				       0, 0, IIO_ST('u', 12, 16, 0), 0),
+		.channel[1] = IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 1, 0,
+				       (1 << IIO_CHAN_INFO_SCALE_SHARED),
+				       1, 1, IIO_ST('u', 12, 16, 0), 0),
+		.channel[2] = IIO_CHAN_SOFT_TIMESTAMP(2),
+		.num_channels = 3,
 		.int_vref_mv = 4096,
-		.monitor_mode = true,
 		.default_config = AD7998_ALERT_EN,
-		.dev_attrs = &ad7992_dev_attr_group,
-		.scan_attrs = &ad7992_scan_el_group,
-		.event_attrs = &ad7992_event_attrs_group,
-		.ad799x_set_scan_mode = ad7992_3_4_set_scan_mode,
+		.info = &ad7992_info,
 	},
 	[ad7993] = {
-		.num_inputs = 4,
-		.bits = 10,
-		.sign = IIO_SCAN_EL_TYPE_UNSIGNED,
+		.channel[0] = IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 0, 0,
+				       (1 << IIO_CHAN_INFO_SCALE_SHARED),
+				       0, 0, IIO_ST('u', 10, 16, 0), 0),
+		.channel[1] = IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 1, 0,
+				       (1 << IIO_CHAN_INFO_SCALE_SHARED),
+				       1, 1, IIO_ST('u', 10, 16, 0), 0),
+		.channel[2] = IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 2, 0,
+				       (1 << IIO_CHAN_INFO_SCALE_SHARED),
+				       2, 2, IIO_ST('u', 10, 16, 0), 0),
+		.channel[3] = IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 3, 0,
+				       (1 << IIO_CHAN_INFO_SCALE_SHARED),
+				       3, 3, IIO_ST('u', 10, 16, 0), 0),
+		.channel[4] = IIO_CHAN_SOFT_TIMESTAMP(4),
+		.num_channels = 5,
 		.int_vref_mv = 1024,
-		.monitor_mode = true,
 		.default_config = AD7998_ALERT_EN,
-		.dev_attrs = &ad7991_5_9_3_4_dev_attr_group,
-		.scan_attrs = &ad7991_5_9_3_4_scan_el_group,
-		.event_attrs = &ad7993_4_7_8_event_attrs_group,
-		.ad799x_set_scan_mode = ad7992_3_4_set_scan_mode,
+		.info = &ad7993_4_7_8_info,
 	},
 	[ad7994] = {
-		.num_inputs = 4,
-		.bits = 12,
-		.sign = IIO_SCAN_EL_TYPE_UNSIGNED,
+		.channel[0] = IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 0, 0,
+				       (1 << IIO_CHAN_INFO_SCALE_SHARED),
+				       0, 0, IIO_ST('u', 12, 16, 0), 0),
+		.channel[1] = IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 1, 0,
+				       (1 << IIO_CHAN_INFO_SCALE_SHARED),
+				       1, 1, IIO_ST('u', 12, 16, 0), 0),
+		.channel[2] = IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 2, 0,
+				       (1 << IIO_CHAN_INFO_SCALE_SHARED),
+				       2, 2, IIO_ST('u', 12, 16, 0), 0),
+		.channel[3] = IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 3, 0,
+				       (1 << IIO_CHAN_INFO_SCALE_SHARED),
+				       3, 3, IIO_ST('u', 12, 16, 0), 0),
+		.channel[4] = IIO_CHAN_SOFT_TIMESTAMP(4),
+		.num_channels = 5,
 		.int_vref_mv = 4096,
-		.monitor_mode = true,
 		.default_config = AD7998_ALERT_EN,
-		.dev_attrs = &ad7991_5_9_3_4_dev_attr_group,
-		.scan_attrs = &ad7991_5_9_3_4_scan_el_group,
-		.event_attrs = &ad7993_4_7_8_event_attrs_group,
-		.ad799x_set_scan_mode = ad7992_3_4_set_scan_mode,
+		.info = &ad7993_4_7_8_info,
 	},
 	[ad7997] = {
-		.num_inputs = 8,
-		.bits = 10,
-		.sign = IIO_SCAN_EL_TYPE_UNSIGNED,
+		.channel[0] = IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 0, 0,
+					  (1 << IIO_CHAN_INFO_SCALE_SHARED),
+					  0, 0, IIO_ST('u', 10, 16, 0), 0),
+		.channel[1] = IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 1, 0,
+					  (1 << IIO_CHAN_INFO_SCALE_SHARED),
+					  1, 1, IIO_ST('u', 10, 16, 0), 0),
+		.channel[2] = IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 2, 0,
+					  (1 << IIO_CHAN_INFO_SCALE_SHARED),
+					  2, 2, IIO_ST('u', 10, 16, 0), 0),
+		.channel[3] = IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 3, 0,
+					  (1 << IIO_CHAN_INFO_SCALE_SHARED),
+					  3, 3, IIO_ST('u', 10, 16, 0), 0),
+		.channel[4] = IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 4, 0,
+					  (1 << IIO_CHAN_INFO_SCALE_SHARED),
+					  4, 4, IIO_ST('u', 10, 16, 0), 0),
+		.channel[5] = IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 5, 0,
+					  (1 << IIO_CHAN_INFO_SCALE_SHARED),
+					  5, 5, IIO_ST('u', 10, 16, 0), 0),
+		.channel[6] = IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 6, 0,
+					  (1 << IIO_CHAN_INFO_SCALE_SHARED),
+					  6, 6, IIO_ST('u', 10, 16, 0), 0),
+		.channel[7] = IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 7, 0,
+					  (1 << IIO_CHAN_INFO_SCALE_SHARED),
+					  7, 7, IIO_ST('u', 10, 16, 0), 0),
+		.channel[8] = IIO_CHAN_SOFT_TIMESTAMP(8),
+		.num_channels = 9,
 		.int_vref_mv = 1024,
-		.monitor_mode = true,
 		.default_config = AD7998_ALERT_EN,
-		.dev_attrs = &ad7997_8_dev_attr_group,
-		.scan_attrs = &ad7997_8_scan_el_group,
-		.event_attrs = &ad7993_4_7_8_event_attrs_group,
-		.ad799x_set_scan_mode = ad7997_8_set_scan_mode,
+		.info = &ad7993_4_7_8_info,
 	},
 	[ad7998] = {
-		.num_inputs = 8,
-		.bits = 12,
-		.sign = IIO_SCAN_EL_TYPE_UNSIGNED,
+		.channel[0] = IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 0, 0,
+				       (1 << IIO_CHAN_INFO_SCALE_SHARED),
+				       0, 0, IIO_ST('u', 12, 16, 0), 0),
+		.channel[1] = IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 1, 0,
+				       (1 << IIO_CHAN_INFO_SCALE_SHARED),
+				       1, 1, IIO_ST('u', 12, 16, 0), 0),
+		.channel[2] = IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 2, 0,
+				       (1 << IIO_CHAN_INFO_SCALE_SHARED),
+				       2, 2, IIO_ST('u', 12, 16, 0), 0),
+		.channel[3] = IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 3, 0,
+				       (1 << IIO_CHAN_INFO_SCALE_SHARED),
+				       3, 3, IIO_ST('u', 12, 16, 0), 0),
+		.channel[4] = IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 4, 0,
+				       (1 << IIO_CHAN_INFO_SCALE_SHARED),
+				       4, 4, IIO_ST('u', 12, 16, 0), 0),
+		.channel[5] = IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 5, 0,
+				       (1 << IIO_CHAN_INFO_SCALE_SHARED),
+				       5, 5, IIO_ST('u', 12, 16, 0), 0),
+		.channel[6] = IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 6, 0,
+				       (1 << IIO_CHAN_INFO_SCALE_SHARED),
+				       6, 6, IIO_ST('u', 12, 16, 0), 0),
+		.channel[7] = IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 7, 0,
+					  (1 << IIO_CHAN_INFO_SCALE_SHARED),
+					  7, 7, IIO_ST('u', 12, 16, 0), 0),
+		.channel[8] = IIO_CHAN_SOFT_TIMESTAMP(8),
+		.num_channels = 9,
 		.int_vref_mv = 4096,
-		.monitor_mode = true,
 		.default_config = AD7998_ALERT_EN,
-		.dev_attrs = &ad7997_8_dev_attr_group,
-		.scan_attrs = &ad7997_8_scan_el_group,
-		.event_attrs = &ad7993_4_7_8_event_attrs_group,
-		.ad799x_set_scan_mode = ad7997_8_set_scan_mode,
+		.info = &ad7993_4_7_8_info,
 	},
 };
 
@@ -772,16 +653,16 @@
 {
 	int ret, regdone = 0;
 	struct ad799x_platform_data *pdata = client->dev.platform_data;
-	struct ad799x_state *st = kzalloc(sizeof(*st), GFP_KERNEL);
-	if (st == NULL) {
-		ret = -ENOMEM;
-		goto error_ret;
-	}
+	struct ad799x_state *st;
+	struct iio_dev *indio_dev = iio_allocate_device(sizeof(*st));
+
+	if (indio_dev == NULL)
+		return -ENOMEM;
 
+	st = iio_priv(indio_dev);
 	/* this is only used for device removal purposes */
-	i2c_set_clientdata(client, st);
+	i2c_set_clientdata(client, indio_dev);
 
-	atomic_set(&st->protect_ring, 0);
 	st->id = id->driver_data;
 	st->chip_info = &ad799x_chip_info_tbl[st->id];
 	st->config = st->chip_info->default_config;
@@ -801,94 +682,76 @@
 	}
 	st->client = client;
 
-	st->indio_dev = iio_allocate_device();
-	if (st->indio_dev == NULL) {
-		ret = -ENOMEM;
-		goto error_disable_reg;
-	}
-
-	/* Estabilish that the iio_dev is a child of the i2c device */
-	st->indio_dev->dev.parent = &client->dev;
-	st->indio_dev->attrs = st->chip_info->dev_attrs;
-	st->indio_dev->event_attrs = st->chip_info->event_attrs;
-
-	st->indio_dev->dev_data = (void *)(st);
-	st->indio_dev->driver_module = THIS_MODULE;
-	st->indio_dev->modes = INDIO_DIRECT_MODE;
-	st->indio_dev->num_interrupt_lines = 1;
+	indio_dev->dev.parent = &client->dev;
+	indio_dev->name = id->name;
+	indio_dev->info = st->chip_info->info;
+	indio_dev->name = id->name;
+	indio_dev->dev_data = (void *)(st);
 
-	ret = ad799x_set_scan_mode(st, 0);
-	if (ret)
-		goto error_free_device;
+	indio_dev->modes = INDIO_DIRECT_MODE;
+	indio_dev->channels = st->chip_info->channel;
+	indio_dev->num_channels = st->chip_info->num_channels;
 
-	ret = ad799x_register_ring_funcs_and_init(st->indio_dev);
+	ret = ad799x_register_ring_funcs_and_init(indio_dev);
 	if (ret)
-		goto error_free_device;
+		goto error_disable_reg;
 
-	ret = iio_device_register(st->indio_dev);
+	ret = iio_device_register(indio_dev);
 	if (ret)
 		goto error_cleanup_ring;
 	regdone = 1;
 
-	ret = iio_ring_buffer_register(st->indio_dev->ring, 0);
+	ret = iio_ring_buffer_register_ex(indio_dev->ring, 0,
+					  indio_dev->channels,
+					  indio_dev->num_channels);
 	if (ret)
 		goto error_cleanup_ring;
 
-	if (client->irq > 0 && st->chip_info->monitor_mode) {
-		INIT_WORK(&st->work_thresh, ad799x_interrupt_bh);
-
-		ret = iio_register_interrupt_line(client->irq,
-				st->indio_dev,
-				0,
-				IRQF_TRIGGER_FALLING,
-				client->name);
+	if (client->irq > 0) {
+		ret = request_threaded_irq(client->irq,
+					   NULL,
+					   ad799x_event_handler,
+					   IRQF_TRIGGER_FALLING |
+					   IRQF_ONESHOT,
+					   client->name,
+					   indio_dev);
 		if (ret)
 			goto error_cleanup_ring;
-
-		/*
-		 * The event handler list element refer to iio_event_ad799x.
-		 * All event attributes bind to the same event handler.
-		 * So, only register event handler once.
-		 */
-		iio_add_event_to_list(&iio_event_ad799x,
-				&st->indio_dev->interrupts[0]->ev_list);
 	}
 
 	return 0;
+
 error_cleanup_ring:
-	ad799x_ring_cleanup(st->indio_dev);
-error_free_device:
-	if (!regdone)
-		iio_free_device(st->indio_dev);
-	else
-		iio_device_unregister(st->indio_dev);
+	ad799x_ring_cleanup(indio_dev);
 error_disable_reg:
 	if (!IS_ERR(st->reg))
 		regulator_disable(st->reg);
 error_put_reg:
 	if (!IS_ERR(st->reg))
 		regulator_put(st->reg);
-	kfree(st);
-error_ret:
+	if (regdone)
+		iio_device_unregister(indio_dev);
+	else
+		iio_free_device(indio_dev);
+
 	return ret;
 }
 
 static __devexit int ad799x_remove(struct i2c_client *client)
 {
-	struct ad799x_state *st = i2c_get_clientdata(client);
-	struct iio_dev *indio_dev = st->indio_dev;
+	struct iio_dev *indio_dev = i2c_get_clientdata(client);
+	struct ad799x_state *st = iio_priv(indio_dev);
 
-	if (client->irq > 0 && st->chip_info->monitor_mode)
-		iio_unregister_interrupt_line(indio_dev, 0);
+	if (client->irq > 0)
+		free_irq(client->irq, indio_dev);
 
 	iio_ring_buffer_unregister(indio_dev->ring);
 	ad799x_ring_cleanup(indio_dev);
-	iio_device_unregister(indio_dev);
 	if (!IS_ERR(st->reg)) {
 		regulator_disable(st->reg);
 		regulator_put(st->reg);
 	}
-	kfree(st);
+	iio_device_unregister(indio_dev);
 
 	return 0;
 }
diff -druN linux-2.6.39-libre/drivers/staging/iio/adc/ad799x.h linux-3.0-rc7-libre/drivers/staging/iio/adc/ad799x.h
--- linux-2.6.39-libre/drivers/staging/iio/adc/ad799x.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/iio/adc/ad799x.h	2011-07-11 19:51:52.000000000 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2010 Michael Hennerich, Analog Devices Inc.
+ * Copyright (C) 2010-2011 Michael Hennerich, Analog Devices Inc.
  * Copyright (C) 2008-2010 Jonathan Cameron
  *
  * This program is free software; you can redistribute it and/or modify
@@ -67,6 +67,8 @@
 
 #define AD7997_8_READ_SINGLE			0x80
 #define AD7997_8_READ_SEQUENCE			0x70
+/* TODO: move this into a common header */
+#define RES_MASK(bits)	((1 << (bits)) - 1)
 
 enum {
 	ad7991,
@@ -83,43 +85,28 @@
 
 /**
  * struct ad799x_chip_info - chip specifc information
- * @num_inputs:		number of physical inputs on chip
- * @bits:		accuracy of the adc in bits
+ * @channel:		channel specification
+ * @num_channels:	number of channels
  * @int_vref_mv:	the internal reference voltage
  * @monitor_mode:	whether the chip supports monitor interrupts
  * @default_config:	device default configuration
- * @dev_attrs:		pointer to the device attribute group
- * @scan_attrs:		pointer to the scan element attribute group
  * @event_attrs:	pointer to the monitor event attribute group
- * @ad799x_set_scan_mode: function pointer to the device specific mode function
-
  */
+
 struct ad799x_chip_info {
-	u8				num_inputs;
-	u8				bits;
-	u8				storagebits;
-	char				sign;
+	struct iio_chan_spec		channel[9];
+	int				num_channels;
 	u16				int_vref_mv;
-	bool				monitor_mode;
 	u16				default_config;
-	struct attribute_group		*dev_attrs;
-	struct attribute_group		*scan_attrs;
-	struct attribute_group		*event_attrs;
-	int (*ad799x_set_scan_mode)	(struct ad799x_state *st,
-					unsigned mask);
+	const struct iio_info		*info;
 };
 
 struct ad799x_state {
-	struct iio_dev			*indio_dev;
 	struct i2c_client		*client;
 	const struct ad799x_chip_info	*chip_info;
-	struct work_struct		poll_work;
-	struct work_struct		work_thresh;
-	atomic_t			protect_ring;
 	size_t				d_size;
 	struct iio_trigger		*trig;
 	struct regulator		*reg;
-	s64				last_timestamp;
 	u16				int_vref_mv;
 	unsigned			id;
 	char				*name;
@@ -134,7 +121,7 @@
 	u16				vref_mv;
 };
 
-int ad799x_set_scan_mode(struct ad799x_state *st, unsigned mask);
+int ad7997_8_set_scan_mode(struct ad799x_state *st, unsigned mask);
 
 #ifdef CONFIG_AD799X_RING_BUFFER
 int ad799x_single_channel_from_ring(struct ad799x_state *st, long mask);
diff -druN linux-2.6.39-libre/drivers/staging/iio/adc/ad799x_ring.c linux-3.0-rc7-libre/drivers/staging/iio/adc/ad799x_ring.c
--- linux-2.6.39-libre/drivers/staging/iio/adc/ad799x_ring.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/iio/adc/ad799x_ring.c	2011-07-11 19:51:52.000000000 -0400
@@ -10,7 +10,6 @@
  */
 
 #include <linux/interrupt.h>
-#include <linux/workqueue.h>
 #include <linux/device.h>
 #include <linux/slab.h>
 #include <linux/kernel.h>
@@ -29,7 +28,7 @@
 
 int ad799x_single_channel_from_ring(struct ad799x_state *st, long mask)
 {
-	struct iio_ring_buffer *ring = st->indio_dev->ring;
+	struct iio_ring_buffer *ring = iio_priv_to_dev(st)->ring;
 	int count = 0, ret;
 	u16 *ring_data;
 
@@ -38,12 +37,13 @@
 		goto error_ret;
 	}
 
-	ring_data = kmalloc(ring->access.get_bytes_per_datum(ring), GFP_KERNEL);
+	ring_data = kmalloc(ring->access->get_bytes_per_datum(ring),
+			    GFP_KERNEL);
 	if (ring_data == NULL) {
 		ret = -ENOMEM;
 		goto error_ret;
 	}
-	ret = ring->access.read_last(ring, (u8 *) ring_data);
+	ret = ring->access->read_last(ring, (u8 *) ring_data);
 	if (ret)
 		goto error_free_ring_data;
 	/* Need a count of channels prior to this one */
@@ -72,7 +72,7 @@
 static int ad799x_ring_preenable(struct iio_dev *indio_dev)
 {
 	struct iio_ring_buffer *ring = indio_dev->ring;
-	struct ad799x_state *st = indio_dev->dev_data;
+	struct ad799x_state *st = iio_dev_get_devdata(indio_dev);
 
 	/*
 	 * Need to figure out the current mode based upon the requested
@@ -80,7 +80,7 @@
 	 */
 
 	if (st->id == ad7997 || st->id == ad7998)
-		ad799x_set_scan_mode(st, ring->scan_mask);
+		ad7997_8_set_scan_mode(st, ring->scan_mask);
 
 	st->d_size = ring->scan_count * 2;
 
@@ -91,56 +91,34 @@
 			st->d_size += sizeof(s64) - (st->d_size % sizeof(s64));
 	}
 
-	if (indio_dev->ring->access.set_bytes_per_datum)
-		indio_dev->ring->access.set_bytes_per_datum(indio_dev->ring,
+	if (indio_dev->ring->access->set_bytes_per_datum)
+		indio_dev->ring->access->set_bytes_per_datum(indio_dev->ring,
 							    st->d_size);
 
 	return 0;
 }
 
 /**
- * ad799x_poll_func_th() th of trigger launched polling to ring buffer
- *
- * As sampling only occurs on i2c comms occurring, leave timestamping until
- * then.  Some triggers will generate their own time stamp.  Currently
- * there is no way of notifying them when no one cares.
- **/
-static void ad799x_poll_func_th(struct iio_dev *indio_dev, s64 time)
-{
-	struct ad799x_state *st = indio_dev->dev_data;
-
-	schedule_work(&st->poll_work);
-
-	return;
-}
-/**
- * ad799x_poll_bh_to_ring() bh of trigger launched polling to ring buffer
- * @work_s:	the work struct through which this was scheduled
+ * ad799x_trigger_handler() bh of trigger launched polling to ring buffer
  *
  * Currently there is no option in this driver to disable the saving of
  * timestamps within the ring.
- * I think the one copy of this at a time was to avoid problems if the
- * trigger was set far too high and the reads then locked up the computer.
  **/
-static void ad799x_poll_bh_to_ring(struct work_struct *work_s)
+
+static irqreturn_t ad799x_trigger_handler(int irq, void *p)
 {
-	struct ad799x_state *st = container_of(work_s, struct ad799x_state,
-						  poll_work);
-	struct iio_dev *indio_dev = st->indio_dev;
+	struct iio_poll_func *pf = p;
+	struct iio_dev *indio_dev = pf->private_data;
+	struct ad799x_state *st = iio_dev_get_devdata(indio_dev);
 	struct iio_ring_buffer *ring = indio_dev->ring;
-	struct iio_sw_ring_buffer *ring_sw = iio_to_sw_ring(indio_dev->ring);
 	s64 time_ns;
 	__u8 *rxbuf;
 	int b_sent;
 	u8 cmd;
 
-	/* Ensure only one copy of this function running at a time */
-	if (atomic_inc_return(&st->protect_ring) > 1)
-		return;
-
 	rxbuf = kmalloc(st->d_size, GFP_KERNEL);
 	if (rxbuf == NULL)
-		return;
+		goto out;
 
 	switch (st->id) {
 	case ad7991:
@@ -173,16 +151,25 @@
 		memcpy(rxbuf + st->d_size - sizeof(s64),
 			&time_ns, sizeof(time_ns));
 
-	ring->access.store_to(&ring_sw->buf, rxbuf, time_ns);
+	ring->access->store_to(indio_dev->ring, rxbuf, time_ns);
 done:
 	kfree(rxbuf);
-	atomic_dec(&st->protect_ring);
+	if (b_sent < 0)
+		return b_sent;
+out:
+	iio_trigger_notify_done(indio_dev->trig);
+
+	return IRQ_HANDLED;
 }
 
+static const struct iio_ring_setup_ops ad799x_buf_setup_ops = {
+	.preenable = &ad799x_ring_preenable,
+	.postenable = &iio_triggered_ring_postenable,
+	.predisable = &iio_triggered_ring_predisable,
+};
 
 int ad799x_register_ring_funcs_and_init(struct iio_dev *indio_dev)
 {
-	struct ad799x_state *st = indio_dev->dev_data;
 	int ret = 0;
 
 	indio_dev->ring = iio_sw_rb_allocate(indio_dev);
@@ -191,25 +178,27 @@
 		goto error_ret;
 	}
 	/* Effectively select the ring buffer implementation */
-	iio_ring_sw_register_funcs(&st->indio_dev->ring->access);
-	ret = iio_alloc_pollfunc(indio_dev, NULL, &ad799x_poll_func_th);
-	if (ret)
+	indio_dev->ring->access = &ring_sw_access_funcs;
+	indio_dev->pollfunc = iio_alloc_pollfunc(NULL,
+						 &ad799x_trigger_handler,
+						 IRQF_ONESHOT,
+						 indio_dev,
+						 "%s_consumer%d",
+						 indio_dev->name,
+						 indio_dev->id);
+	if (indio_dev->pollfunc == NULL) {
+		ret = -ENOMEM;
 		goto error_deallocate_sw_rb;
+	}
 
 	/* Ring buffer functions - here trigger setup related */
-
-	indio_dev->ring->preenable = &ad799x_ring_preenable;
-	indio_dev->ring->postenable = &iio_triggered_ring_postenable;
-	indio_dev->ring->predisable = &iio_triggered_ring_predisable;
+	indio_dev->ring->setup_ops = &ad799x_buf_setup_ops;
 	indio_dev->ring->scan_timestamp = true;
 
-	INIT_WORK(&st->poll_work, &ad799x_poll_bh_to_ring);
-
-	indio_dev->ring->scan_el_attrs = st->chip_info->scan_attrs;
-
 	/* Flag that polled ring buffering is possible */
 	indio_dev->modes |= INDIO_RING_TRIGGERED;
 	return 0;
+
 error_deallocate_sw_rb:
 	iio_sw_rb_free(indio_dev->ring);
 error_ret:
@@ -224,6 +213,6 @@
 		iio_trigger_dettach_poll_func(indio_dev->trig,
 					      indio_dev->pollfunc);
 	}
-	kfree(indio_dev->pollfunc);
+	iio_dealloc_pollfunc(indio_dev->pollfunc);
 	iio_sw_rb_free(indio_dev->ring);
 }
diff -druN linux-2.6.39-libre/drivers/staging/iio/adc/adt7310.c linux-3.0-rc7-libre/drivers/staging/iio/adc/adt7310.c
--- linux-2.6.39-libre/drivers/staging/iio/adc/adt7310.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/iio/adc/adt7310.c	2011-07-11 19:51:52.000000000 -0400
@@ -7,15 +7,12 @@
  */
 
 #include <linux/interrupt.h>
-#include <linux/gpio.h>
-#include <linux/workqueue.h>
 #include <linux/device.h>
 #include <linux/kernel.h>
 #include <linux/slab.h>
 #include <linux/sysfs.h>
 #include <linux/list.h>
 #include <linux/spi/spi.h>
-#include <linux/rtc.h>
 
 #include "../iio.h"
 #include "../sysfs.h"
@@ -82,11 +79,8 @@
  */
 
 struct adt7310_chip_info {
-	const char *name;
 	struct spi_device *spi_dev;
 	struct iio_dev *indio_dev;
-	struct work_struct thresh_work;
-	s64 last_timestamp;
 	u8  config;
 };
 
@@ -380,24 +374,12 @@
 
 static IIO_DEVICE_ATTR(value, S_IRUGO, adt7310_show_value, NULL, 0);
 
-static ssize_t adt7310_show_name(struct device *dev,
-		struct device_attribute *attr,
-		char *buf)
-{
-	struct iio_dev *dev_info = dev_get_drvdata(dev);
-	struct adt7310_chip_info *chip = dev_info->dev_data;
-	return sprintf(buf, "%s\n", chip->name);
-}
-
-static IIO_DEVICE_ATTR(name, S_IRUGO, adt7310_show_name, NULL, 0);
-
 static struct attribute *adt7310_attributes[] = {
 	&iio_dev_attr_available_modes.dev_attr.attr,
 	&iio_dev_attr_mode.dev_attr.attr,
 	&iio_dev_attr_resolution.dev_attr.attr,
 	&iio_dev_attr_id.dev_attr.attr,
 	&iio_dev_attr_value.dev_attr.attr,
-	&iio_dev_attr_name.dev_attr.attr,
 	NULL,
 };
 
@@ -405,53 +387,39 @@
 	.attrs = adt7310_attributes,
 };
 
-/*
- * temperature bound events
- */
-
-#define IIO_EVENT_CODE_ADT7310_ABOVE_ALARM    IIO_BUFFER_EVENT_CODE(0)
-#define IIO_EVENT_CODE_ADT7310_BELLOW_ALARM   IIO_BUFFER_EVENT_CODE(1)
-#define IIO_EVENT_CODE_ADT7310_ABOVE_CRIT     IIO_BUFFER_EVENT_CODE(2)
-
-static void adt7310_interrupt_bh(struct work_struct *work_s)
+static irqreturn_t adt7310_event_handler(int irq, void *private)
 {
-	struct adt7310_chip_info *chip =
-		container_of(work_s, struct adt7310_chip_info, thresh_work);
+	struct iio_dev *indio_dev = private;
+	struct adt7310_chip_info *chip = iio_dev_get_devdata(indio_dev);
+	s64 timestamp = iio_get_time_ns();
 	u8 status;
+	int ret;
 
-	if (adt7310_spi_read_byte(chip, ADT7310_STATUS, &status))
-		return;
+	ret = adt7310_spi_read_byte(chip, ADT7310_STATUS, &status);
+	if (ret)
+		return ret;
 
 	if (status & ADT7310_STAT_T_HIGH)
-		iio_push_event(chip->indio_dev, 0,
-			IIO_EVENT_CODE_ADT7310_ABOVE_ALARM,
-			chip->last_timestamp);
+		iio_push_event(indio_dev, 0,
+			       IIO_UNMOD_EVENT_CODE(IIO_TEMP, 0,
+						    IIO_EV_TYPE_THRESH,
+						    IIO_EV_DIR_RISING),
+			       timestamp);
 	if (status & ADT7310_STAT_T_LOW)
-		iio_push_event(chip->indio_dev, 0,
-			IIO_EVENT_CODE_ADT7310_BELLOW_ALARM,
-			chip->last_timestamp);
+		iio_push_event(indio_dev, 0,
+			       IIO_UNMOD_EVENT_CODE(IIO_TEMP, 0,
+						    IIO_EV_TYPE_THRESH,
+						    IIO_EV_DIR_FALLING),
+			       timestamp);
 	if (status & ADT7310_STAT_T_CRIT)
-		iio_push_event(chip->indio_dev, 0,
-			IIO_EVENT_CODE_ADT7310_ABOVE_CRIT,
-			chip->last_timestamp);
-}
-
-static int adt7310_interrupt(struct iio_dev *dev_info,
-		int index,
-		s64 timestamp,
-		int no_test)
-{
-	struct adt7310_chip_info *chip = dev_info->dev_data;
-
-	chip->last_timestamp = timestamp;
-	schedule_work(&chip->thresh_work);
-
-	return 0;
+		iio_push_event(indio_dev, 0,
+			       IIO_UNMOD_EVENT_CODE(IIO_TEMP, 0,
+						    IIO_EV_TYPE_THRESH,
+						    IIO_EV_DIR_RISING),
+			timestamp);
+	return IRQ_HANDLED;
 }
 
-IIO_EVENT_SH(adt7310, &adt7310_interrupt);
-IIO_EVENT_SH(adt7310_ct, &adt7310_interrupt);
-
 static ssize_t adt7310_show_event_mode(struct device *dev,
 		struct device_attribute *attr,
 		char *buf)
@@ -729,49 +697,62 @@
 	return len;
 }
 
-IIO_EVENT_ATTR_SH(event_mode, iio_event_adt7310,
-		adt7310_show_event_mode, adt7310_set_event_mode, 0);
-IIO_EVENT_ATTR_SH(available_event_modes, iio_event_adt7310,
-		adt7310_show_available_event_modes, NULL, 0);
-IIO_EVENT_ATTR_SH(fault_queue, iio_event_adt7310,
-		adt7310_show_fault_queue, adt7310_set_fault_queue, 0);
-IIO_EVENT_ATTR_SH(t_alarm_high, iio_event_adt7310,
-		adt7310_show_t_alarm_high, adt7310_set_t_alarm_high, 0);
-IIO_EVENT_ATTR_SH(t_alarm_low, iio_event_adt7310,
-		adt7310_show_t_alarm_low, adt7310_set_t_alarm_low, 0);
-IIO_EVENT_ATTR_SH(t_crit, iio_event_adt7310_ct,
-		adt7310_show_t_crit, adt7310_set_t_crit, 0);
-IIO_EVENT_ATTR_SH(t_hyst, iio_event_adt7310,
-		adt7310_show_t_hyst, adt7310_set_t_hyst, 0);
+static IIO_DEVICE_ATTR(event_mode,
+		       S_IRUGO | S_IWUSR,
+		       adt7310_show_event_mode, adt7310_set_event_mode, 0);
+static IIO_DEVICE_ATTR(available_event_modes,
+		       S_IRUGO | S_IWUSR,
+		       adt7310_show_available_event_modes, NULL, 0);
+static IIO_DEVICE_ATTR(fault_queue,
+		       S_IRUGO | S_IWUSR,
+		       adt7310_show_fault_queue, adt7310_set_fault_queue, 0);
+static IIO_DEVICE_ATTR(t_alarm_high,
+		       S_IRUGO | S_IWUSR,
+		       adt7310_show_t_alarm_high, adt7310_set_t_alarm_high, 0);
+static IIO_DEVICE_ATTR(t_alarm_low,
+		       S_IRUGO | S_IWUSR,
+		       adt7310_show_t_alarm_low, adt7310_set_t_alarm_low, 0);
+static IIO_DEVICE_ATTR(t_crit,
+		       S_IRUGO | S_IWUSR,
+		       adt7310_show_t_crit, adt7310_set_t_crit, 0);
+static IIO_DEVICE_ATTR(t_hyst,
+		       S_IRUGO | S_IWUSR,
+		       adt7310_show_t_hyst, adt7310_set_t_hyst, 0);
 
 static struct attribute *adt7310_event_int_attributes[] = {
-	&iio_event_attr_event_mode.dev_attr.attr,
-	&iio_event_attr_available_event_modes.dev_attr.attr,
-	&iio_event_attr_fault_queue.dev_attr.attr,
-	&iio_event_attr_t_alarm_high.dev_attr.attr,
-	&iio_event_attr_t_alarm_low.dev_attr.attr,
-	&iio_event_attr_t_hyst.dev_attr.attr,
+	&iio_dev_attr_event_mode.dev_attr.attr,
+	&iio_dev_attr_available_event_modes.dev_attr.attr,
+	&iio_dev_attr_fault_queue.dev_attr.attr,
+	&iio_dev_attr_t_alarm_high.dev_attr.attr,
+	&iio_dev_attr_t_alarm_low.dev_attr.attr,
+	&iio_dev_attr_t_hyst.dev_attr.attr,
 	NULL,
 };
 
 static struct attribute *adt7310_event_ct_attributes[] = {
-	&iio_event_attr_event_mode.dev_attr.attr,
-	&iio_event_attr_available_event_modes.dev_attr.attr,
-	&iio_event_attr_fault_queue.dev_attr.attr,
-	&iio_event_attr_t_crit.dev_attr.attr,
-	&iio_event_attr_t_hyst.dev_attr.attr,
+	&iio_dev_attr_event_mode.dev_attr.attr,
+	&iio_dev_attr_available_event_modes.dev_attr.attr,
+	&iio_dev_attr_fault_queue.dev_attr.attr,
+	&iio_dev_attr_t_crit.dev_attr.attr,
+	&iio_dev_attr_t_hyst.dev_attr.attr,
 	NULL,
 };
 
 static struct attribute_group adt7310_event_attribute_group[ADT7310_IRQS] = {
 	{
 		.attrs = adt7310_event_int_attributes,
-	},
-	{
+	}, {
 		.attrs = adt7310_event_ct_attributes,
 	}
 };
 
+static const struct iio_info adt7310_info = {
+	.attrs = &adt7310_attribute_group,
+	.num_interrupt_lines = ADT7310_IRQS,
+	.event_attrs = adt7310_event_attribute_group,
+	.driver_module = THIS_MODULE,
+};
+
 /*
  * device probe and remove
  */
@@ -792,20 +773,17 @@
 	dev_set_drvdata(&spi_dev->dev, chip);
 
 	chip->spi_dev = spi_dev;
-	chip->name = spi_dev->modalias;
 
-	chip->indio_dev = iio_allocate_device();
+	chip->indio_dev = iio_allocate_device(0);
 	if (chip->indio_dev == NULL) {
 		ret = -ENOMEM;
 		goto error_free_chip;
 	}
 
 	chip->indio_dev->dev.parent = &spi_dev->dev;
-	chip->indio_dev->attrs = &adt7310_attribute_group;
-	chip->indio_dev->event_attrs = adt7310_event_attribute_group;
+	chip->indio_dev->name = spi_get_device_id(spi_dev)->name;
+	chip->indio_dev->info = &adt7310_info;
 	chip->indio_dev->dev_data = (void *)chip;
-	chip->indio_dev->driver_module = THIS_MODULE;
-	chip->indio_dev->num_interrupt_lines = ADT7310_IRQS;
 	chip->indio_dev->modes = INDIO_DIRECT_MODE;
 
 	ret = iio_device_register(chip->indio_dev);
@@ -818,45 +796,29 @@
 			irq_flags = adt7310_platform_data[2];
 		else
 			irq_flags = IRQF_TRIGGER_LOW;
-		ret = iio_register_interrupt_line(spi_dev->irq,
-				chip->indio_dev,
-				0,
-				irq_flags,
-				chip->name);
+		ret = request_threaded_irq(spi_dev->irq,
+					   NULL,
+					   &adt7310_event_handler,
+					   irq_flags,
+					   chip->indio_dev->name,
+					   chip->indio_dev);
 		if (ret)
 			goto error_unreg_dev;
-
-		/*
-		 * The event handler list element refer to iio_event_adt7310.
-		 * All event attributes bind to the same event handler.
-		 * One event handler can only be added to one event list.
-		 */
-		iio_add_event_to_list(&iio_event_adt7310,
-				&chip->indio_dev->interrupts[0]->ev_list);
 	}
 
 	/* INT bound temperature alarm event. line 1 */
 	if (adt7310_platform_data[0]) {
-		ret = iio_register_interrupt_line(adt7310_platform_data[0],
-				chip->indio_dev,
-				1,
-				adt7310_platform_data[1],
-				chip->name);
+		ret = request_threaded_irq(adt7310_platform_data[0],
+					   NULL,
+					   &adt7310_event_handler,
+					   adt7310_platform_data[1],
+					   chip->indio_dev->name,
+					   chip->indio_dev);
 		if (ret)
 			goto error_unreg_ct_irq;
-
-		/*
-		 * The event handler list element refer to iio_event_adt7310.
-		 * All event attributes bind to the same event handler.
-		 * One event handler can only be added to one event list.
-		 */
-		iio_add_event_to_list(&iio_event_adt7310_ct,
-				&chip->indio_dev->interrupts[1]->ev_list);
 	}
 
 	if (spi_dev->irq && adt7310_platform_data[0]) {
-		INIT_WORK(&chip->thresh_work, adt7310_interrupt_bh);
-
 		ret = adt7310_spi_read_byte(chip, ADT7310_CONFIG, &chip->config);
 		if (ret) {
 			ret = -EIO;
@@ -879,14 +841,14 @@
 	}
 
 	dev_info(&spi_dev->dev, "%s temperature sensor registered.\n",
-			chip->name);
+			chip->indio_dev->name);
 
 	return 0;
 
 error_unreg_int_irq:
-	iio_unregister_interrupt_line(chip->indio_dev, 1);
+	free_irq(adt7310_platform_data[0], chip->indio_dev);
 error_unreg_ct_irq:
-	iio_unregister_interrupt_line(chip->indio_dev, 0);
+	free_irq(spi_dev->irq, chip->indio_dev);
 error_unreg_dev:
 	iio_device_unregister(chip->indio_dev);
 error_free_dev:
@@ -905,9 +867,9 @@
 
 	dev_set_drvdata(&spi_dev->dev, NULL);
 	if (adt7310_platform_data[0])
-		iio_unregister_interrupt_line(indio_dev, 1);
+		free_irq(adt7310_platform_data[0], chip->indio_dev);
 	if (spi_dev->irq)
-		iio_unregister_interrupt_line(indio_dev, 0);
+		free_irq(spi_dev->irq, chip->indio_dev);
 	iio_device_unregister(indio_dev);
 	iio_free_device(chip->indio_dev);
 	kfree(chip);
diff -druN linux-2.6.39-libre/drivers/staging/iio/adc/adt7410.c linux-3.0-rc7-libre/drivers/staging/iio/adc/adt7410.c
--- linux-2.6.39-libre/drivers/staging/iio/adc/adt7410.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/iio/adc/adt7410.c	2011-07-11 19:51:52.000000000 -0400
@@ -7,15 +7,12 @@
  */
 
 #include <linux/interrupt.h>
-#include <linux/gpio.h>
-#include <linux/workqueue.h>
 #include <linux/device.h>
 #include <linux/kernel.h>
 #include <linux/slab.h>
 #include <linux/sysfs.h>
 #include <linux/list.h>
 #include <linux/i2c.h>
-#include <linux/rtc.h>
 
 #include "../iio.h"
 #include "../sysfs.h"
@@ -77,11 +74,8 @@
  */
 
 struct adt7410_chip_info {
-	const char *name;
 	struct i2c_client *client;
 	struct iio_dev *indio_dev;
-	struct work_struct thresh_work;
-	s64 last_timestamp;
 	u8  config;
 };
 
@@ -348,24 +342,12 @@
 
 static IIO_DEVICE_ATTR(value, S_IRUGO, adt7410_show_value, NULL, 0);
 
-static ssize_t adt7410_show_name(struct device *dev,
-		struct device_attribute *attr,
-		char *buf)
-{
-	struct iio_dev *dev_info = dev_get_drvdata(dev);
-	struct adt7410_chip_info *chip = dev_info->dev_data;
-	return sprintf(buf, "%s\n", chip->name);
-}
-
-static IIO_DEVICE_ATTR(name, S_IRUGO, adt7410_show_name, NULL, 0);
-
 static struct attribute *adt7410_attributes[] = {
 	&iio_dev_attr_available_modes.dev_attr.attr,
 	&iio_dev_attr_mode.dev_attr.attr,
 	&iio_dev_attr_resolution.dev_attr.attr,
 	&iio_dev_attr_id.dev_attr.attr,
 	&iio_dev_attr_value.dev_attr.attr,
-	&iio_dev_attr_name.dev_attr.attr,
 	NULL,
 };
 
@@ -373,55 +355,38 @@
 	.attrs = adt7410_attributes,
 };
 
-/*
- * temperature bound events
- */
-
-#define IIO_EVENT_CODE_ADT7410_ABOVE_ALARM    IIO_BUFFER_EVENT_CODE(0)
-#define IIO_EVENT_CODE_ADT7410_BELLOW_ALARM   IIO_BUFFER_EVENT_CODE(1)
-#define IIO_EVENT_CODE_ADT7410_ABOVE_CRIT     IIO_BUFFER_EVENT_CODE(2)
-
-static void adt7410_interrupt_bh(struct work_struct *work_s)
+static irqreturn_t adt7410_event_handler(int irq, void *private)
 {
-	struct adt7410_chip_info *chip =
-		container_of(work_s, struct adt7410_chip_info, thresh_work);
+	struct iio_dev *indio_dev = private;
+	struct adt7410_chip_info *chip = iio_dev_get_devdata(indio_dev);
+	s64 timestamp = iio_get_time_ns();
 	u8 status;
 
 	if (adt7410_i2c_read_byte(chip, ADT7410_STATUS, &status))
-		return;
-
-	enable_irq(chip->client->irq);
+		return IRQ_HANDLED;
 
 	if (status & ADT7410_STAT_T_HIGH)
-		iio_push_event(chip->indio_dev, 0,
-			IIO_EVENT_CODE_ADT7410_ABOVE_ALARM,
-			chip->last_timestamp);
+		iio_push_event(indio_dev, 0,
+			       IIO_UNMOD_EVENT_CODE(IIO_TEMP, 0,
+						    IIO_EV_TYPE_THRESH,
+						    IIO_EV_DIR_RISING),
+			       timestamp);
 	if (status & ADT7410_STAT_T_LOW)
-		iio_push_event(chip->indio_dev, 0,
-			IIO_EVENT_CODE_ADT7410_BELLOW_ALARM,
-			chip->last_timestamp);
+		iio_push_event(indio_dev, 0,
+			       IIO_UNMOD_EVENT_CODE(IIO_TEMP, 0,
+						    IIO_EV_TYPE_THRESH,
+						    IIO_EV_DIR_FALLING),
+			       timestamp);
 	if (status & ADT7410_STAT_T_CRIT)
-		iio_push_event(chip->indio_dev, 0,
-			IIO_EVENT_CODE_ADT7410_ABOVE_CRIT,
-			chip->last_timestamp);
-}
-
-static int adt7410_interrupt(struct iio_dev *dev_info,
-		int index,
-		s64 timestamp,
-		int no_test)
-{
-	struct adt7410_chip_info *chip = dev_info->dev_data;
-
-	chip->last_timestamp = timestamp;
-	schedule_work(&chip->thresh_work);
+		iio_push_event(indio_dev, 0,
+			       IIO_UNMOD_EVENT_CODE(IIO_TEMP, 0,
+						    IIO_EV_TYPE_THRESH,
+						    IIO_EV_DIR_RISING),
+			       timestamp);
 
-	return 0;
+	return IRQ_HANDLED;
 }
 
-IIO_EVENT_SH(adt7410, &adt7410_interrupt);
-IIO_EVENT_SH(adt7410_ct, &adt7410_interrupt);
-
 static ssize_t adt7410_show_event_mode(struct device *dev,
 		struct device_attribute *attr,
 		char *buf)
@@ -699,49 +664,62 @@
 	return ret;
 }
 
-IIO_EVENT_ATTR_SH(event_mode, iio_event_adt7410,
-		adt7410_show_event_mode, adt7410_set_event_mode, 0);
-IIO_EVENT_ATTR_SH(available_event_modes, iio_event_adt7410,
-		adt7410_show_available_event_modes, NULL, 0);
-IIO_EVENT_ATTR_SH(fault_queue, iio_event_adt7410,
-		adt7410_show_fault_queue, adt7410_set_fault_queue, 0);
-IIO_EVENT_ATTR_SH(t_alarm_high, iio_event_adt7410,
-		adt7410_show_t_alarm_high, adt7410_set_t_alarm_high, 0);
-IIO_EVENT_ATTR_SH(t_alarm_low, iio_event_adt7410,
-		adt7410_show_t_alarm_low, adt7410_set_t_alarm_low, 0);
-IIO_EVENT_ATTR_SH(t_crit, iio_event_adt7410_ct,
-		adt7410_show_t_crit, adt7410_set_t_crit, 0);
-IIO_EVENT_ATTR_SH(t_hyst, iio_event_adt7410,
-		adt7410_show_t_hyst, adt7410_set_t_hyst, 0);
+static IIO_DEVICE_ATTR(event_mode,
+		       S_IRUGO | S_IWUSR,
+		       adt7410_show_event_mode, adt7410_set_event_mode, 0);
+static IIO_DEVICE_ATTR(available_event_modes,
+		       S_IRUGO,
+		       adt7410_show_available_event_modes, NULL, 0);
+static IIO_DEVICE_ATTR(fault_queue,
+		       S_IRUGO | S_IWUSR,
+		       adt7410_show_fault_queue, adt7410_set_fault_queue, 0);
+static IIO_DEVICE_ATTR(t_alarm_high,
+		       S_IRUGO | S_IWUSR,
+		       adt7410_show_t_alarm_high, adt7410_set_t_alarm_high, 0);
+static IIO_DEVICE_ATTR(t_alarm_low,
+		       S_IRUGO | S_IWUSR,
+		       adt7410_show_t_alarm_low, adt7410_set_t_alarm_low, 0);
+static IIO_DEVICE_ATTR(t_crit,
+		       S_IRUGO | S_IWUSR,
+		       adt7410_show_t_crit, adt7410_set_t_crit, 0);
+static IIO_DEVICE_ATTR(t_hyst,
+		       S_IRUGO | S_IWUSR,
+		       adt7410_show_t_hyst, adt7410_set_t_hyst, 0);
 
 static struct attribute *adt7410_event_int_attributes[] = {
-	&iio_event_attr_event_mode.dev_attr.attr,
-	&iio_event_attr_available_event_modes.dev_attr.attr,
-	&iio_event_attr_fault_queue.dev_attr.attr,
-	&iio_event_attr_t_alarm_high.dev_attr.attr,
-	&iio_event_attr_t_alarm_low.dev_attr.attr,
-	&iio_event_attr_t_hyst.dev_attr.attr,
+	&iio_dev_attr_event_mode.dev_attr.attr,
+	&iio_dev_attr_available_event_modes.dev_attr.attr,
+	&iio_dev_attr_fault_queue.dev_attr.attr,
+	&iio_dev_attr_t_alarm_high.dev_attr.attr,
+	&iio_dev_attr_t_alarm_low.dev_attr.attr,
+	&iio_dev_attr_t_hyst.dev_attr.attr,
 	NULL,
 };
 
 static struct attribute *adt7410_event_ct_attributes[] = {
-	&iio_event_attr_event_mode.dev_attr.attr,
-	&iio_event_attr_available_event_modes.dev_attr.attr,
-	&iio_event_attr_fault_queue.dev_attr.attr,
-	&iio_event_attr_t_crit.dev_attr.attr,
-	&iio_event_attr_t_hyst.dev_attr.attr,
+	&iio_dev_attr_event_mode.dev_attr.attr,
+	&iio_dev_attr_available_event_modes.dev_attr.attr,
+	&iio_dev_attr_fault_queue.dev_attr.attr,
+	&iio_dev_attr_t_crit.dev_attr.attr,
+	&iio_dev_attr_t_hyst.dev_attr.attr,
 	NULL,
 };
 
 static struct attribute_group adt7410_event_attribute_group[ADT7410_IRQS] = {
 	{
 		.attrs = adt7410_event_int_attributes,
-	},
-	{
+	}, {
 		.attrs = adt7410_event_ct_attributes,
 	}
 };
 
+static const struct iio_info adt7410_info = {
+	.attrs = &adt7410_attribute_group,
+	.num_interrupt_lines = ADT7410_IRQS,
+	.event_attrs = adt7410_event_attribute_group,
+	.driver_module = THIS_MODULE,
+};
+
 /*
  * device probe and remove
  */
@@ -762,20 +740,16 @@
 	i2c_set_clientdata(client, chip);
 
 	chip->client = client;
-	chip->name = id->name;
 
-	chip->indio_dev = iio_allocate_device();
+	chip->indio_dev = iio_allocate_device(0);
 	if (chip->indio_dev == NULL) {
 		ret = -ENOMEM;
 		goto error_free_chip;
 	}
-
+	chip->indio_dev->name = id->name;
 	chip->indio_dev->dev.parent = &client->dev;
-	chip->indio_dev->attrs = &adt7410_attribute_group;
-	chip->indio_dev->event_attrs = adt7410_event_attribute_group;
+	chip->indio_dev->info = &adt7410_info;
 	chip->indio_dev->dev_data = (void *)chip;
-	chip->indio_dev->driver_module = THIS_MODULE;
-	chip->indio_dev->num_interrupt_lines = ADT7410_IRQS;
 	chip->indio_dev->modes = INDIO_DIRECT_MODE;
 
 	ret = iio_device_register(chip->indio_dev);
@@ -784,44 +758,29 @@
 
 	/* CT critcal temperature event. line 0 */
 	if (client->irq) {
-		ret = iio_register_interrupt_line(client->irq,
-				chip->indio_dev,
-				0,
-				IRQF_TRIGGER_LOW,
-				chip->name);
+		ret = request_threaded_irq(client->irq,
+					   NULL,
+					   &adt7410_event_handler,
+					   IRQF_TRIGGER_LOW,
+					   id->name,
+					   chip->indio_dev);
 		if (ret)
 			goto error_unreg_dev;
-
-		/*
-		 * The event handler list element refer to iio_event_adt7410.
-		 * All event attributes bind to the same event handler.
-		 * One event handler can only be added to one event list.
-		 */
-		iio_add_event_to_list(&iio_event_adt7410,
-				&chip->indio_dev->interrupts[0]->ev_list);
 	}
 
 	/* INT bound temperature alarm event. line 1 */
 	if (adt7410_platform_data[0]) {
-		ret = iio_register_interrupt_line(adt7410_platform_data[0],
-				chip->indio_dev,
-				1,
-				adt7410_platform_data[1],
-				chip->name);
+		ret = request_threaded_irq(adt7410_platform_data[0],
+					   NULL,
+					   &adt7410_event_handler,
+					   adt7410_platform_data[1],
+					   id->name,
+					   chip->indio_dev);
 		if (ret)
 			goto error_unreg_ct_irq;
-
-		/*
-		 * The event handler list element refer to iio_event_adt7410.
-		 * All event attributes bind to the same event handler.
-		 * One event handler can only be added to one event list.
-		 */
-		iio_add_event_to_list(&iio_event_adt7410_ct,
-				&chip->indio_dev->interrupts[1]->ev_list);
 	}
 
 	if (client->irq && adt7410_platform_data[0]) {
-		INIT_WORK(&chip->thresh_work, adt7410_interrupt_bh);
 
 		ret = adt7410_i2c_read_byte(chip, ADT7410_CONFIG, &chip->config);
 		if (ret) {
@@ -850,9 +809,9 @@
 	return 0;
 
 error_unreg_int_irq:
-	iio_unregister_interrupt_line(chip->indio_dev, 1);
+	free_irq(adt7410_platform_data[0], chip->indio_dev);
 error_unreg_ct_irq:
-	iio_unregister_interrupt_line(chip->indio_dev, 0);
+	free_irq(client->irq, chip->indio_dev);
 error_unreg_dev:
 	iio_device_unregister(chip->indio_dev);
 error_free_dev:
@@ -870,9 +829,9 @@
 	unsigned long *adt7410_platform_data = client->dev.platform_data;
 
 	if (adt7410_platform_data[0])
-		iio_unregister_interrupt_line(indio_dev, 1);
+		free_irq(adt7410_platform_data[0], chip->indio_dev);
 	if (client->irq)
-		iio_unregister_interrupt_line(indio_dev, 0);
+		free_irq(client->irq, chip->indio_dev);
 	iio_device_unregister(indio_dev);
 	iio_free_device(chip->indio_dev);
 	kfree(chip);
diff -druN linux-2.6.39-libre/drivers/staging/iio/adc/adt75.c linux-3.0-rc7-libre/drivers/staging/iio/adc/adt75.c
--- linux-2.6.39-libre/drivers/staging/iio/adc/adt75.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/iio/adc/adt75.c	2011-07-11 19:51:52.000000000 -0400
@@ -7,15 +7,11 @@
  */
 
 #include <linux/interrupt.h>
-#include <linux/gpio.h>
-#include <linux/workqueue.h>
 #include <linux/device.h>
 #include <linux/kernel.h>
 #include <linux/slab.h>
 #include <linux/sysfs.h>
-#include <linux/list.h>
 #include <linux/i2c.h>
-#include <linux/rtc.h>
 
 #include "../iio.h"
 #include "../sysfs.h"
@@ -54,11 +50,8 @@
  */
 
 struct adt75_chip_info {
-	const char *name;
 	struct i2c_client *client;
 	struct iio_dev *indio_dev;
-	struct work_struct thresh_work;
-	s64 last_timestamp;
 	u8  config;
 };
 
@@ -249,23 +242,11 @@
 
 static IIO_DEVICE_ATTR(value, S_IRUGO, adt75_show_value, NULL, 0);
 
-static ssize_t adt75_show_name(struct device *dev,
-		struct device_attribute *attr,
-		char *buf)
-{
-	struct iio_dev *dev_info = dev_get_drvdata(dev);
-	struct adt75_chip_info *chip = dev_info->dev_data;
-	return sprintf(buf, "%s\n", chip->name);
-}
-
-static IIO_DEVICE_ATTR(name, S_IRUGO, adt75_show_name, NULL, 0);
-
 static struct attribute *adt75_attributes[] = {
 	&iio_dev_attr_available_modes.dev_attr.attr,
 	&iio_dev_attr_mode.dev_attr.attr,
 	&iio_dev_attr_oneshot.dev_attr.attr,
 	&iio_dev_attr_value.dev_attr.attr,
-	&iio_dev_attr_name.dev_attr.attr,
 	NULL,
 };
 
@@ -277,35 +258,20 @@
  * temperature bound events
  */
 
-#define IIO_EVENT_CODE_ADT75_OTI    IIO_BUFFER_EVENT_CODE(0)
-
-static void adt75_interrupt_bh(struct work_struct *work_s)
-{
-	struct adt75_chip_info *chip =
-		container_of(work_s, struct adt75_chip_info, thresh_work);
-
-	enable_irq(chip->client->irq);
-
-	iio_push_event(chip->indio_dev, 0,
-			IIO_EVENT_CODE_ADT75_OTI,
-			chip->last_timestamp);
-}
+#define IIO_EVENT_CODE_ADT75_OTI IIO_UNMOD_EVENT_CODE(IIO_EV_CLASS_TEMP, \
+						      0,		\
+						      IIO_EV_TYPE_THRESH, \
+						      IIO_EV_DIR_FALLING)
 
-static int adt75_interrupt(struct iio_dev *dev_info,
-		int index,
-		s64 timestamp,
-		int no_test)
+static irqreturn_t adt75_event_handler(int irq, void *private)
 {
-	struct adt75_chip_info *chip = dev_info->dev_data;
-
-	chip->last_timestamp = timestamp;
-	schedule_work(&chip->thresh_work);
+	iio_push_event(private, 0,
+		       IIO_EVENT_CODE_ADT75_OTI,
+		       iio_get_time_ns());
 
-	return 0;
+	return IRQ_HANDLED;
 }
 
-IIO_EVENT_SH(adt75, &adt75_interrupt);
-
 static ssize_t adt75_show_oti_mode(struct device *dev,
 		struct device_attribute *attr,
 		char *buf)
@@ -458,16 +424,16 @@
 }
 static inline ssize_t adt75_show_t_bound(struct device *dev,
 		struct device_attribute *attr,
-		u8 bound_reg,
 		char *buf)
 {
+	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
 	struct iio_dev *dev_info = dev_get_drvdata(dev);
 	struct adt75_chip_info *chip = dev_info->dev_data;
 	u16 data;
 	char sign = ' ';
 	int ret;
 
-	ret = adt75_i2c_read(chip, bound_reg, (u8 *)&data);
+	ret = adt75_i2c_read(chip, this_attr->address, (u8 *)&data);
 	if (ret)
 		return -EIO;
 
@@ -485,10 +451,10 @@
 
 static inline ssize_t adt75_set_t_bound(struct device *dev,
 		struct device_attribute *attr,
-		u8 bound_reg,
 		const char *buf,
 		size_t len)
 {
+	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
 	struct iio_dev *dev_info = dev_get_drvdata(dev);
 	struct adt75_chip_info *chip = dev_info->dev_data;
 	long tmp1, tmp2;
@@ -525,67 +491,42 @@
 	data <<= ADT75_VALUE_OFFSET;
 	data = swab16(data);
 
-	ret = adt75_i2c_write(chip, bound_reg, (u8)data);
+	ret = adt75_i2c_write(chip, this_attr->address, (u8)data);
 	if (ret)
 		return -EIO;
 
 	return ret;
 }
 
-static ssize_t adt75_show_t_os(struct device *dev,
-		struct device_attribute *attr,
-		char *buf)
-{
-	return adt75_show_t_bound(dev, attr,
-			ADT75_T_OS, buf);
-}
-
-static inline ssize_t adt75_set_t_os(struct device *dev,
-		struct device_attribute *attr,
-		const char *buf,
-		size_t len)
-{
-	return adt75_set_t_bound(dev, attr,
-			ADT75_T_OS, buf, len);
-}
-
-static ssize_t adt75_show_t_hyst(struct device *dev,
-		struct device_attribute *attr,
-		char *buf)
-{
-	return adt75_show_t_bound(dev, attr,
-			ADT75_T_HYST, buf);
-}
-
-static inline ssize_t adt75_set_t_hyst(struct device *dev,
-		struct device_attribute *attr,
-		const char *buf,
-		size_t len)
-{
-	return adt75_set_t_bound(dev, attr,
-			ADT75_T_HYST, buf, len);
-}
 
-IIO_EVENT_ATTR_SH(oti_mode, iio_event_adt75,
-		adt75_show_oti_mode, adt75_set_oti_mode, 0);
-IIO_EVENT_ATTR_SH(available_oti_modes, iio_event_adt75,
-		adt75_show_available_oti_modes, NULL, 0);
-IIO_EVENT_ATTR_SH(smbus_alart, iio_event_adt75,
-		adt75_show_smbus_alart, adt75_set_smbus_alart, 0);
-IIO_EVENT_ATTR_SH(fault_queue, iio_event_adt75,
-		adt75_show_fault_queue, adt75_set_fault_queue, 0);
-IIO_EVENT_ATTR_SH(t_os, iio_event_adt75,
-		adt75_show_t_os, adt75_set_t_os, 0);
-IIO_EVENT_ATTR_SH(t_hyst, iio_event_adt75,
-		adt75_show_t_hyst, adt75_set_t_hyst, 0);
+static IIO_DEVICE_ATTR(oti_mode,
+		       S_IRUGO | S_IWUSR,
+		       adt75_show_oti_mode, adt75_set_oti_mode, 0);
+static IIO_DEVICE_ATTR(available_oti_modes,
+		       S_IRUGO,
+		       adt75_show_available_oti_modes, NULL, 0);
+static IIO_DEVICE_ATTR(smbus_alart,
+		       S_IRUGO | S_IWUSR,
+		       adt75_show_smbus_alart, adt75_set_smbus_alart, 0);
+static IIO_DEVICE_ATTR(fault_queue,
+		       S_IRUGO | S_IWUSR,
+		       adt75_show_fault_queue, adt75_set_fault_queue, 0);
+static IIO_DEVICE_ATTR(t_os_value,
+		       S_IRUGO | S_IWUSR,
+		       adt75_show_t_bound, adt75_set_t_bound,
+		       ADT75_T_OS);
+static IIO_DEVICE_ATTR(t_hyst_value,
+		       S_IRUGO | S_IWUSR,
+		       adt75_show_t_bound, adt75_set_t_bound,
+		       ADT75_T_HYST);
 
 static struct attribute *adt75_event_attributes[] = {
-	&iio_event_attr_oti_mode.dev_attr.attr,
-	&iio_event_attr_available_oti_modes.dev_attr.attr,
-	&iio_event_attr_smbus_alart.dev_attr.attr,
-	&iio_event_attr_fault_queue.dev_attr.attr,
-	&iio_event_attr_t_os.dev_attr.attr,
-	&iio_event_attr_t_hyst.dev_attr.attr,
+	&iio_dev_attr_oti_mode.dev_attr.attr,
+	&iio_dev_attr_available_oti_modes.dev_attr.attr,
+	&iio_dev_attr_smbus_alart.dev_attr.attr,
+	&iio_dev_attr_fault_queue.dev_attr.attr,
+	&iio_dev_attr_t_os_value.dev_attr.attr,
+	&iio_dev_attr_t_hyst_value.dev_attr.attr,
 	NULL,
 };
 
@@ -593,6 +534,13 @@
 	.attrs = adt75_event_attributes,
 };
 
+static const struct iio_info adt75_info = {
+	.attrs = &adt75_attribute_group,
+	.num_interrupt_lines = 1,
+	.event_attrs = &adt75_event_attribute_group,
+	.driver_module = THIS_MODULE,
+};
+
 /*
  * device probe and remove
  */
@@ -612,20 +560,17 @@
 	i2c_set_clientdata(client, chip);
 
 	chip->client = client;
-	chip->name = id->name;
 
-	chip->indio_dev = iio_allocate_device();
+	chip->indio_dev = iio_allocate_device(0);
 	if (chip->indio_dev == NULL) {
 		ret = -ENOMEM;
 		goto error_free_chip;
 	}
 
+	chip->indio_dev->name = id->name;
 	chip->indio_dev->dev.parent = &client->dev;
-	chip->indio_dev->attrs = &adt75_attribute_group;
-	chip->indio_dev->event_attrs = &adt75_event_attribute_group;
+	chip->indio_dev->info = &adt75_info;
 	chip->indio_dev->dev_data = (void *)chip;
-	chip->indio_dev->driver_module = THIS_MODULE;
-	chip->indio_dev->num_interrupt_lines = 1;
 	chip->indio_dev->modes = INDIO_DIRECT_MODE;
 
 	ret = iio_device_register(chip->indio_dev);
@@ -633,24 +578,15 @@
 		goto error_free_dev;
 
 	if (client->irq > 0) {
-		ret = iio_register_interrupt_line(client->irq,
-				chip->indio_dev,
-				0,
-				IRQF_TRIGGER_LOW,
-				chip->name);
+		ret = request_threaded_irq(client->irq,
+					   NULL,
+					   &adt75_event_handler,
+					   IRQF_TRIGGER_LOW,
+					   chip->indio_dev->name,
+					   chip->indio_dev);
 		if (ret)
 			goto error_unreg_dev;
 
-		/*
-		 * The event handler list element refer to iio_event_adt75.
-		 * All event attributes bind to the same event handler.
-		 * So, only register event handler once.
-		 */
-		iio_add_event_to_list(&iio_event_adt75,
-				&chip->indio_dev->interrupts[0]->ev_list);
-
-		INIT_WORK(&chip->thresh_work, adt75_interrupt_bh);
-
 		ret = adt75_i2c_read(chip, ADT75_CONFIG, &chip->config);
 		if (ret) {
 			ret = -EIO;
@@ -668,11 +604,11 @@
 	}
 
 	dev_info(&client->dev, "%s temperature sensor registered.\n",
-			 id->name);
+			 chip->indio_dev->name);
 
 	return 0;
 error_unreg_irq:
-	iio_unregister_interrupt_line(chip->indio_dev, 0);
+	free_irq(client->irq, chip->indio_dev);
 error_unreg_dev:
 	iio_device_unregister(chip->indio_dev);
 error_free_dev:
@@ -689,7 +625,7 @@
 	struct iio_dev *indio_dev = chip->indio_dev;
 
 	if (client->irq)
-		iio_unregister_interrupt_line(indio_dev, 0);
+		free_irq(client->irq, chip->indio_dev);
 	iio_device_unregister(indio_dev);
 	iio_free_device(chip->indio_dev);
 	kfree(chip);
diff -druN linux-2.6.39-libre/drivers/staging/iio/adc/Kconfig linux-3.0-rc7-libre/drivers/staging/iio/adc/Kconfig
--- linux-2.6.39-libre/drivers/staging/iio/adc/Kconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/iio/adc/Kconfig	2011-07-11 19:51:52.000000000 -0400
@@ -3,30 +3,6 @@
 #
 comment "Analog to digital convertors"
 
-config MAX1363
-	tristate "MAXIM max1363 ADC driver"
-	depends on I2C
-	select IIO_TRIGGER if IIO_RING_BUFFER
-	select MAX1363_RING_BUFFER
-	help
-	  Say yes here to build support for many MAXIM i2c analog to digital
-	  convertors (ADC). (max1361, max1362, max1363, max1364, max1036,
-	  max1037, max1038, max1039, max1136, max1136, max1137, max1138,
-	  max1139, max1236, max1237, max11238, max1239, max11600, max11601,
-	  max11602, max11603, max11604, max11605, max11606, max11607,
-	  max11608, max11609, max11610, max11611, max11612, max11613,
-	  max11614, max11615, max11616, max11617) Provides direct access
-	  via sysfs.
-
-config MAX1363_RING_BUFFER
-	bool "MAXIM max1363: use ring buffer"
-	depends on MAX1363
-	select IIO_RING_BUFFER
-	select IIO_SW_RING
-	help
-	  Say yes here to include ring buffer support in the MAX1363
-	  ADC driver.
-
 config AD7150
 	tristate "Analog Devices ad7150/1/6 capacitive sensor driver"
 	depends on I2C
@@ -142,6 +118,18 @@
 	  To compile this driver as a module, choose M here: the
 	  module will be called ad7887.
 
+config AD7780
+	tristate "Analog Devices AD7780 AD7781 ADC driver"
+	depends on SPI
+	depends on GPIOLIB
+	help
+	  Say yes here to build support for Analog Devices
+	  AD7780 and AD7781 SPI analog to digital convertors (ADC).
+	  If unsure, say N (but it's safe to say "Y").
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called ad7780.
+
 config AD7745
 	tristate "Analog Devices AD7745, AD7746 AD7747 capacitive sensor driver"
 	depends on I2C
@@ -179,3 +167,27 @@
 	help
 	  Say yes here to build support for Analog Devices ADT7410
 	  temperature sensors.
+
+config MAX1363
+	tristate "Maxim max1363 ADC driver"
+	depends on I2C
+	select IIO_TRIGGER if IIO_RING_BUFFER
+	select MAX1363_RING_BUFFER
+	help
+	  Say yes here to build support for many Maxim i2c analog to digital
+	  convertors (ADC). (max1361, max1362, max1363, max1364, max1036,
+	  max1037, max1038, max1039, max1136, max1136, max1137, max1138,
+	  max1139, max1236, max1237, max11238, max1239, max11600, max11601,
+	  max11602, max11603, max11604, max11605, max11606, max11607,
+	  max11608, max11609, max11610, max11611, max11612, max11613,
+	  max11614, max11615, max11616, max11617, max11644, max11645,
+	  max11646, max11647) Provides direct access via sysfs.
+
+config MAX1363_RING_BUFFER
+	bool "Maxim max1363: use ring buffer"
+	depends on MAX1363
+	select IIO_RING_BUFFER
+	select IIO_SW_RING
+	help
+	  Say yes here to include ring buffer support in the MAX1363
+	  ADC driver.
diff -druN linux-2.6.39-libre/drivers/staging/iio/adc/Makefile linux-3.0-rc7-libre/drivers/staging/iio/adc/Makefile
--- linux-2.6.39-libre/drivers/staging/iio/adc/Makefile	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/iio/adc/Makefile	2011-07-11 19:51:52.000000000 -0400
@@ -34,6 +34,7 @@
 obj-$(CONFIG_AD7291) += ad7291.o
 obj-$(CONFIG_AD7314) += ad7314.o
 obj-$(CONFIG_AD7745) += ad7745.o
+obj-$(CONFIG_AD7780) += ad7780.o
 obj-$(CONFIG_AD7816) += ad7816.o
 obj-$(CONFIG_ADT75) += adt75.o
 obj-$(CONFIG_ADT7310) += adt7310.o
diff -druN linux-2.6.39-libre/drivers/staging/iio/adc/max1363_core.c linux-3.0-rc7-libre/drivers/staging/iio/adc/max1363_core.c
--- linux-2.6.39-libre/drivers/staging/iio/adc/max1363_core.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/iio/adc/max1363_core.c	2011-07-11 19:51:52.000000000 -0400
@@ -22,7 +22,6 @@
   */
 
 #include <linux/interrupt.h>
-#include <linux/workqueue.h>
 #include <linux/device.h>
 #include <linux/kernel.h>
 #include <linux/sysfs.h>
@@ -39,38 +38,50 @@
 #include "adc.h"
 #include "max1363.h"
 
-/* Here we claim all are 16 bits. This currently does no harm and saves
- * us a lot of scan element listings */
+#define MAX1363_MODE_SINGLE(_num, _mask) {				\
+		.conf = MAX1363_CHANNEL_SEL(_num)			\
+			| MAX1363_CONFIG_SCAN_SINGLE_1			\
+			| MAX1363_CONFIG_SE,				\
+			.modemask = _mask,				\
+			}
 
-#define MAX1363_SCAN_EL(number)				\
-	IIO_SCAN_EL_C(in##number, number, 0, NULL);
-#define MAX1363_SCAN_EL_D(p, n, number)					\
-	IIO_SCAN_NAMED_EL_C(in##p##m##in##n, in##p-in##n, number, 0, NULL);
+#define MAX1363_MODE_SCAN_TO_CHANNEL(_num, _mask) {			\
+		.conf = MAX1363_CHANNEL_SEL(_num)			\
+			| MAX1363_CONFIG_SCAN_TO_CS			\
+			| MAX1363_CONFIG_SE,				\
+			.modemask = _mask,				\
+			}
 
-static MAX1363_SCAN_EL(0);
-static MAX1363_SCAN_EL(1);
-static MAX1363_SCAN_EL(2);
-static MAX1363_SCAN_EL(3);
-static MAX1363_SCAN_EL(4);
-static MAX1363_SCAN_EL(5);
-static MAX1363_SCAN_EL(6);
-static MAX1363_SCAN_EL(7);
-static MAX1363_SCAN_EL(8);
-static MAX1363_SCAN_EL(9);
-static MAX1363_SCAN_EL(10);
-static MAX1363_SCAN_EL(11);
-static MAX1363_SCAN_EL_D(0, 1, 12);
-static MAX1363_SCAN_EL_D(2, 3, 13);
-static MAX1363_SCAN_EL_D(4, 5, 14);
-static MAX1363_SCAN_EL_D(6, 7, 15);
-static MAX1363_SCAN_EL_D(8, 9, 16);
-static MAX1363_SCAN_EL_D(10, 11, 17);
-static MAX1363_SCAN_EL_D(1, 0, 18);
-static MAX1363_SCAN_EL_D(3, 2, 19);
-static MAX1363_SCAN_EL_D(5, 4, 20);
-static MAX1363_SCAN_EL_D(7, 6, 21);
-static MAX1363_SCAN_EL_D(9, 8, 22);
-static MAX1363_SCAN_EL_D(11, 10, 23);
+/* note not available for max1363 hence naming */
+#define MAX1236_MODE_SCAN_MID_TO_CHANNEL(_mid, _num, _mask) {		\
+		.conf = MAX1363_CHANNEL_SEL(_num)			\
+			| MAX1236_SCAN_MID_TO_CHANNEL			\
+			| MAX1363_CONFIG_SE,				\
+			.modemask = _mask				\
+}
+
+#define MAX1363_MODE_DIFF_SINGLE(_nump, _numm, _mask) {			\
+		.conf = MAX1363_CHANNEL_SEL(_nump)			\
+			| MAX1363_CONFIG_SCAN_SINGLE_1			\
+			| MAX1363_CONFIG_DE,				\
+			.modemask = _mask				\
+			}
+
+/* Can't think how to automate naming so specify for now */
+#define MAX1363_MODE_DIFF_SCAN_TO_CHANNEL(_num, _numvals, _mask) {	\
+		.conf = MAX1363_CHANNEL_SEL(_num)			\
+			| MAX1363_CONFIG_SCAN_TO_CS			\
+			| MAX1363_CONFIG_DE,				\
+			.modemask = _mask				\
+			}
+
+/* note only available for max1363 hence naming */
+#define MAX1236_MODE_DIFF_SCAN_MID_TO_CHANNEL(_num, _numvals, _mask) {	\
+		.conf = MAX1363_CHANNEL_SEL(_num)			\
+			| MAX1236_SCAN_MID_TO_CHANNEL			\
+			| MAX1363_CONFIG_SE,				\
+			.modemask = _mask				\
+}
 
 static const struct max1363_mode max1363_mode_table[] = {
 	/* All of the single channel options first */
@@ -147,76 +158,13 @@
 	return NULL;
 }
 
-static ssize_t max1363_show_precision_u(struct device *dev,
-				struct device_attribute *attr,
-				char *buf)
-{
-	struct iio_ring_buffer *ring = dev_get_drvdata(dev);
-	struct iio_dev *dev_info = ring->indio_dev;
-	struct max1363_state *st = iio_dev_get_devdata(dev_info);
-	return sprintf(buf, "u%d/16\n", st->chip_info->bits);
-}
-
-static ssize_t max1363_show_precision_s(struct device *dev,
-				struct device_attribute *attr,
-				char *buf)
-{
-	struct iio_ring_buffer *ring = dev_get_drvdata(dev);
-	struct iio_dev *dev_info = ring->indio_dev;
-	struct max1363_state *st = iio_dev_get_devdata(dev_info);
-	return sprintf(buf, "s%d/16\n", st->chip_info->bits);
-}
-
-#define MAX1363_SCAN_TYPE(n)						\
-	DEVICE_ATTR(in##n##_type, S_IRUGO,				\
-		    max1363_show_precision_u, NULL);
-#define MAX1363_SCAN_TYPE_D(p, n)					\
-	struct device_attribute dev_attr_in##p##m##in##n##_type =	\
-		__ATTR(in##p-in##n##_type, S_IRUGO,			\
-		       max1363_show_precision_s, NULL);
-
-static MAX1363_SCAN_TYPE(0);
-static MAX1363_SCAN_TYPE(1);
-static MAX1363_SCAN_TYPE(2);
-static MAX1363_SCAN_TYPE(3);
-static MAX1363_SCAN_TYPE(4);
-static MAX1363_SCAN_TYPE(5);
-static MAX1363_SCAN_TYPE(6);
-static MAX1363_SCAN_TYPE(7);
-static MAX1363_SCAN_TYPE(8);
-static MAX1363_SCAN_TYPE(9);
-static MAX1363_SCAN_TYPE(10);
-static MAX1363_SCAN_TYPE(11);
-
-static MAX1363_SCAN_TYPE_D(0, 1);
-static MAX1363_SCAN_TYPE_D(2, 3);
-static MAX1363_SCAN_TYPE_D(4, 5);
-static MAX1363_SCAN_TYPE_D(6, 7);
-static MAX1363_SCAN_TYPE_D(8, 9);
-static MAX1363_SCAN_TYPE_D(10, 11);
-static MAX1363_SCAN_TYPE_D(1, 0);
-static MAX1363_SCAN_TYPE_D(3, 2);
-static MAX1363_SCAN_TYPE_D(5, 4);
-static MAX1363_SCAN_TYPE_D(7, 6);
-static MAX1363_SCAN_TYPE_D(9, 8);
-static MAX1363_SCAN_TYPE_D(11, 10);
-
 static int max1363_write_basic_config(struct i2c_client *client,
 				      unsigned char d1,
 				      unsigned char d2)
 {
-	int ret;
-	u8 *tx_buf = kmalloc(2, GFP_KERNEL);
-
-	if (!tx_buf)
-		return -ENOMEM;
-	tx_buf[0] = d1;
-	tx_buf[1] = d2;
-
-	ret = i2c_master_send(client, tx_buf, 2);
-	kfree(tx_buf);
+	u8 tx_buf[2] = {d1, d2};
 
-	return (ret > 0) ? 0 : ret;
+	return i2c_master_send(client, tx_buf, 2);
 }
 
 int max1363_set_scan_mode(struct max1363_state *st)
@@ -231,20 +179,19 @@
 					  st->configbyte);
 }
 
-static ssize_t max1363_read_single_channel(struct device *dev,
-				   struct device_attribute *attr,
-				   char *buf)
+static int max1363_read_single_chan(struct iio_dev *indio_dev,
+				    struct iio_chan_spec const *chan,
+				    int *val,
+				    long m)
 {
-	struct iio_dev *dev_info = dev_get_drvdata(dev);
-	struct max1363_state *st = iio_dev_get_devdata(dev_info);
-	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
-	struct i2c_client *client = st->client;
-	int ret = 0, len = 0;
-	s32 data ;
+	int ret = 0;
+	s32 data;
 	char rxbuf[2];
 	long mask;
+	struct max1363_state *st = iio_priv(indio_dev);
+	struct i2c_client *client = st->client;
 
-	mutex_lock(&dev_info->mlock);
+	mutex_lock(&indio_dev->mlock);
 	/*
 	 * If monitor mode is enabled, the method for reading a single
 	 * channel will have to be rather different and has not yet
@@ -256,8 +203,8 @@
 	}
 
 	/* If ring buffer capture is occurring, query the buffer */
-	if (iio_ring_enabled(dev_info)) {
-		mask = max1363_mode_table[this_attr->address].modemask;
+	if (iio_ring_enabled(indio_dev)) {
+		mask = max1363_mode_table[chan->address].modemask;
 		data = max1363_single_channel_from_ring(mask, st);
 		if (data < 0) {
 			ret = data;
@@ -265,13 +212,11 @@
 		}
 	} else {
 		/* Check to see if current scan mode is correct */
-		if (st->current_mode !=
-		    &max1363_mode_table[this_attr->address]) {
+		if (st->current_mode != &max1363_mode_table[chan->address]) {
 			/* Update scan mode if needed */
-			st->current_mode
-				= &max1363_mode_table[this_attr->address];
+			st->current_mode = &max1363_mode_table[chan->address];
 			ret = max1363_set_scan_mode(st);
-			if (ret)
+			if (ret < 0)
 				goto error_ret;
 		}
 		if (st->chip_info->bits != 8) {
@@ -281,7 +226,6 @@
 				ret = data;
 				goto error_ret;
 			}
-
 			data = (s32)(rxbuf[1]) | ((s32)(rxbuf[0] & 0x0F)) << 8;
 		} else {
 			/* Get reading */
@@ -293,72 +237,44 @@
 			data = rxbuf[0];
 		}
 	}
-	/* Pretty print the result */
-	len = sprintf(buf, "%u\n", data);
-
+	*val = data;
 error_ret:
-	mutex_unlock(&dev_info->mlock);
-	return ret ? ret : len;
-}
-
-/* Direct read attribtues */
-static IIO_DEV_ATTR_IN_RAW(0, max1363_read_single_channel, _s0);
-static IIO_DEV_ATTR_IN_RAW(1, max1363_read_single_channel, _s1);
-static IIO_DEV_ATTR_IN_RAW(2, max1363_read_single_channel, _s2);
-static IIO_DEV_ATTR_IN_RAW(3, max1363_read_single_channel, _s3);
-static IIO_DEV_ATTR_IN_RAW(4, max1363_read_single_channel, _s4);
-static IIO_DEV_ATTR_IN_RAW(5, max1363_read_single_channel, _s5);
-static IIO_DEV_ATTR_IN_RAW(6, max1363_read_single_channel, _s6);
-static IIO_DEV_ATTR_IN_RAW(7, max1363_read_single_channel, _s7);
-static IIO_DEV_ATTR_IN_RAW(8, max1363_read_single_channel, _s8);
-static IIO_DEV_ATTR_IN_RAW(9, max1363_read_single_channel, _s9);
-static IIO_DEV_ATTR_IN_RAW(10, max1363_read_single_channel, _s10);
-static IIO_DEV_ATTR_IN_RAW(11, max1363_read_single_channel, _s11);
-
-static IIO_DEV_ATTR_IN_DIFF_RAW(0, 1, max1363_read_single_channel, d0m1);
-static IIO_DEV_ATTR_IN_DIFF_RAW(2, 3, max1363_read_single_channel, d2m3);
-static IIO_DEV_ATTR_IN_DIFF_RAW(4, 5, max1363_read_single_channel, d4m5);
-static IIO_DEV_ATTR_IN_DIFF_RAW(6, 7, max1363_read_single_channel, d6m7);
-static IIO_DEV_ATTR_IN_DIFF_RAW(8, 9, max1363_read_single_channel, d8m9);
-static IIO_DEV_ATTR_IN_DIFF_RAW(10, 11, max1363_read_single_channel, d10m11);
-static IIO_DEV_ATTR_IN_DIFF_RAW(1, 0, max1363_read_single_channel, d1m0);
-static IIO_DEV_ATTR_IN_DIFF_RAW(3, 2, max1363_read_single_channel, d3m2);
-static IIO_DEV_ATTR_IN_DIFF_RAW(5, 4, max1363_read_single_channel, d5m4);
-static IIO_DEV_ATTR_IN_DIFF_RAW(7, 6, max1363_read_single_channel, d7m6);
-static IIO_DEV_ATTR_IN_DIFF_RAW(9, 8, max1363_read_single_channel, d9m8);
-static IIO_DEV_ATTR_IN_DIFF_RAW(11, 10, max1363_read_single_channel, d11m10);
-
-
-static ssize_t max1363_show_scale(struct device *dev,
-				struct device_attribute *attr,
-				char *buf)
-{
-	/* Driver currently only support internal vref */
-	struct iio_dev *dev_info = dev_get_drvdata(dev);
-	struct max1363_state *st = iio_dev_get_devdata(dev_info);
-	/* Corresponds to Vref / 2^(bits) */
+	mutex_unlock(&indio_dev->mlock);
+	return ret;
 
-	if ((1 << (st->chip_info->bits + 1))
-	    > st->chip_info->int_vref_mv)
-		return sprintf(buf, "0.5\n");
-	else
-		return sprintf(buf, "%d\n",
-			st->chip_info->int_vref_mv >> st->chip_info->bits);
 }
 
-static IIO_DEVICE_ATTR(in_scale, S_IRUGO, max1363_show_scale, NULL, 0);
-
-static ssize_t max1363_show_name(struct device *dev,
-				 struct device_attribute *attr,
-				 char *buf)
+static int max1363_read_raw(struct iio_dev *indio_dev,
+			    struct iio_chan_spec const *chan,
+			    int *val,
+			    int *val2,
+			    long m)
 {
-	struct iio_dev *dev_info = dev_get_drvdata(dev);
-	struct max1363_state *st = iio_dev_get_devdata(dev_info);
-	return sprintf(buf, "%s\n", st->client->name);
+	struct max1363_state *st = iio_priv(indio_dev);
+	int ret;
+	switch (m) {
+	case 0:
+		ret = max1363_read_single_chan(indio_dev, chan, val, m);
+		if (ret)
+			return ret;
+		return IIO_VAL_INT;
+	case (1 << IIO_CHAN_INFO_SCALE_SHARED):
+		if ((1 << (st->chip_info->bits + 1)) >
+		    st->chip_info->int_vref_mv) {
+			*val = 0;
+			*val2 = 500000;
+			return IIO_VAL_INT_PLUS_MICRO;
+		} else {
+			*val = (st->chip_info->int_vref_mv)
+				>> st->chip_info->bits;
+			return IIO_VAL_INT;
+		}
+	default:
+		return -EINVAL;
+	}
+	return 0;
 }
 
-static IIO_DEVICE_ATTR(name, S_IRUGO, max1363_show_name, NULL, 0);
-
 /* Applies to max1363 */
 static const enum max1363_modes max1363_mode_list[] = {
 	_s0, _s1, _s2, _s3,
@@ -367,48 +283,76 @@
 	d0m1to2m3, d1m0to3m2,
 };
 
-static struct attribute *max1363_device_attrs[] = {
-	&iio_dev_attr_in0_raw.dev_attr.attr,
-	&iio_dev_attr_in1_raw.dev_attr.attr,
-	&iio_dev_attr_in2_raw.dev_attr.attr,
-	&iio_dev_attr_in3_raw.dev_attr.attr,
-	&iio_dev_attr_in0min1_raw.dev_attr.attr,
-	&iio_dev_attr_in2min3_raw.dev_attr.attr,
-	&iio_dev_attr_in1min0_raw.dev_attr.attr,
-	&iio_dev_attr_in3min2_raw.dev_attr.attr,
-	&iio_dev_attr_name.dev_attr.attr,
-	&iio_dev_attr_in_scale.dev_attr.attr,
-	NULL
-};
+#define MAX1363_EV_M						\
+	(IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_RISING)	\
+	 | IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_FALLING))
+#define MAX1363_INFO_MASK (1 << IIO_CHAN_INFO_SCALE_SHARED)
 
-static struct attribute_group max1363_dev_attr_group = {
-	.attrs = max1363_device_attrs,
+static struct iio_chan_spec max1363_channels[] = {
+	IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 0, 0, MAX1363_INFO_MASK,
+		 _s0, 0, IIO_ST('u', 12, 16, 0), MAX1363_EV_M),
+	IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 1, 0, MAX1363_INFO_MASK,
+		 _s1, 1, IIO_ST('u', 12, 16, 0), MAX1363_EV_M),
+	IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 2, 0, MAX1363_INFO_MASK,
+		 _s2, 2, IIO_ST('u', 12, 16, 0), MAX1363_EV_M),
+	IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 3, 0, MAX1363_INFO_MASK,
+		 _s3, 3, IIO_ST('u', 12, 16, 0), MAX1363_EV_M),
+	IIO_CHAN(IIO_IN_DIFF, 0, 1, 0, NULL, 0, 1, MAX1363_INFO_MASK,
+		 d0m1, 4, IIO_ST('s', 12, 16, 0), MAX1363_EV_M),
+	IIO_CHAN(IIO_IN_DIFF, 0, 1, 0, NULL, 2, 3, MAX1363_INFO_MASK,
+		 d2m3, 5, IIO_ST('s', 12, 16, 0), MAX1363_EV_M),
+	IIO_CHAN(IIO_IN_DIFF, 0, 1, 0, NULL, 1, 0, MAX1363_INFO_MASK,
+		 d1m0, 6, IIO_ST('s', 12, 16, 0), MAX1363_EV_M),
+	IIO_CHAN(IIO_IN_DIFF, 0, 1, 0, NULL, 3, 2, MAX1363_INFO_MASK,
+		 d3m2, 7, IIO_ST('s', 12, 16, 0), MAX1363_EV_M),
+	IIO_CHAN_SOFT_TIMESTAMP(8)
 };
 
-static struct attribute *max1363_scan_el_attrs[] = {
-	&iio_scan_el_in0.dev_attr.attr,	&dev_attr_in0_type.attr,
-	&iio_const_attr_in0_index.dev_attr.attr,
-	&iio_scan_el_in1.dev_attr.attr,	&dev_attr_in1_type.attr,
-	&iio_const_attr_in1_index.dev_attr.attr,
-	&iio_scan_el_in2.dev_attr.attr,	&dev_attr_in2_type.attr,
-	&iio_const_attr_in2_index.dev_attr.attr,
-	&iio_scan_el_in3.dev_attr.attr,	&dev_attr_in3_type.attr,
-	&iio_const_attr_in3_index.dev_attr.attr,
-	&iio_scan_el_in0min1.dev_attr.attr,	&dev_attr_in0min1_type.attr,
-	&iio_const_attr_in0min1_index.dev_attr.attr,
-	&iio_scan_el_in2min3.dev_attr.attr,	&dev_attr_in2min3_type.attr,
-	&iio_const_attr_in2min3_index.dev_attr.attr,
-	&iio_scan_el_in1min0.dev_attr.attr,	&dev_attr_in1min0_type.attr,
-	&iio_const_attr_in1min0_index.dev_attr.attr,
-	&iio_scan_el_in3min2.dev_attr.attr,	&dev_attr_in3min2_type.attr,
-	&iio_const_attr_in3min2_index.dev_attr.attr,
-	NULL,
+static struct iio_chan_spec max1361_channels[] = {
+	IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 0, 0, MAX1363_INFO_MASK,
+		 _s0, 0, IIO_ST('u', 10, 16, 0), MAX1363_EV_M),
+	IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 1, 0, MAX1363_INFO_MASK,
+		 _s1, 1, IIO_ST('u', 10, 16, 0), MAX1363_EV_M),
+	IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 2, 0, MAX1363_INFO_MASK,
+		 _s2, 2, IIO_ST('u', 10, 16, 0), MAX1363_EV_M),
+	IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 3, 0, MAX1363_INFO_MASK,
+		 _s3, 3, IIO_ST('u', 10, 16, 0), MAX1363_EV_M),
+	IIO_CHAN(IIO_IN_DIFF, 0, 1, 0, NULL, 0, 1, MAX1363_INFO_MASK,
+		 d0m1, 4, IIO_ST('s', 10, 16, 0), MAX1363_EV_M),
+	IIO_CHAN(IIO_IN_DIFF, 0, 1, 0, NULL, 2, 3, MAX1363_INFO_MASK,
+		 d2m3, 5, IIO_ST('s', 10, 16, 0), MAX1363_EV_M),
+	IIO_CHAN(IIO_IN_DIFF, 0, 1, 0, NULL, 1, 0, MAX1363_INFO_MASK,
+		 d1m0, 6, IIO_ST('s', 10, 16, 0), MAX1363_EV_M),
+	IIO_CHAN(IIO_IN_DIFF, 0, 1, 0, NULL, 3, 2, MAX1363_INFO_MASK,
+		 d3m2, 7, IIO_ST('s', 10, 16, 0), MAX1363_EV_M),
+	IIO_CHAN_SOFT_TIMESTAMP(8)
 };
 
-static struct attribute_group max1363_scan_el_group = {
-	.name = "scan_elements",
-	.attrs = max1363_scan_el_attrs,
-};
+#define MAX1363_CHAN_U(num, address, scan_index, bits)		\
+	IIO_CHAN(IIO_IN, 0, 1, 0, NULL, num, 0, MAX1363_INFO_MASK,	\
+		 address, scan_index, IIO_ST('u', bits,		\
+					     (bits == 8) ? 8 : 16, 0), 0)
+/* bipolar channel */
+#define MAX1363_CHAN_B(num, num2, address, scan_index, bits)		\
+	IIO_CHAN(IIO_IN_DIFF, 0, 1, 0, NULL, num, num2, MAX1363_INFO_MASK,\
+		 address, scan_index, IIO_ST('s', bits,		\
+					     (bits == 8) ? 8 : 16, 0), 0)
+
+#define MAX1363_4X_CHANS(bits) {		\
+	MAX1363_CHAN_U(0, _s0, 0, bits),	\
+	MAX1363_CHAN_U(1, _s1, 1, bits),	\
+	MAX1363_CHAN_U(2, _s2, 2, bits),	\
+	MAX1363_CHAN_U(3, _s3, 3, bits),	\
+	MAX1363_CHAN_B(0, 1, d0m1, 4, bits),	\
+	MAX1363_CHAN_B(2, 3, d2m3, 5, bits),	\
+	MAX1363_CHAN_B(1, 0, d1m0, 6, bits),	\
+	MAX1363_CHAN_B(3, 2, d3m2, 7, bits),	\
+	IIO_CHAN_SOFT_TIMESTAMP(8)		\
+	}
+
+static struct iio_chan_spec max1036_channels[] = MAX1363_4X_CHANS(8);
+static struct iio_chan_spec max1136_channels[] = MAX1363_4X_CHANS(10);
+static struct iio_chan_spec max1236_channels[] = MAX1363_4X_CHANS(12);
 
 /* Appies to max1236, max1237 */
 static const enum max1363_modes max1236_mode_list[] = {
@@ -432,97 +376,36 @@
 	d6m7to8m9, d6m7to10m11, d7m6to9m8, d7m6to11m10,
 };
 
-static struct attribute *max1238_device_attrs[] = {
-	&iio_dev_attr_in0_raw.dev_attr.attr,
-	&iio_dev_attr_in1_raw.dev_attr.attr,
-	&iio_dev_attr_in2_raw.dev_attr.attr,
-	&iio_dev_attr_in3_raw.dev_attr.attr,
-	&iio_dev_attr_in4_raw.dev_attr.attr,
-	&iio_dev_attr_in5_raw.dev_attr.attr,
-	&iio_dev_attr_in6_raw.dev_attr.attr,
-	&iio_dev_attr_in7_raw.dev_attr.attr,
-	&iio_dev_attr_in8_raw.dev_attr.attr,
-	&iio_dev_attr_in9_raw.dev_attr.attr,
-	&iio_dev_attr_in10_raw.dev_attr.attr,
-	&iio_dev_attr_in11_raw.dev_attr.attr,
-	&iio_dev_attr_in0min1_raw.dev_attr.attr,
-	&iio_dev_attr_in2min3_raw.dev_attr.attr,
-	&iio_dev_attr_in4min5_raw.dev_attr.attr,
-	&iio_dev_attr_in6min7_raw.dev_attr.attr,
-	&iio_dev_attr_in8min9_raw.dev_attr.attr,
-	&iio_dev_attr_in10min11_raw.dev_attr.attr,
-	&iio_dev_attr_in1min0_raw.dev_attr.attr,
-	&iio_dev_attr_in3min2_raw.dev_attr.attr,
-	&iio_dev_attr_in5min4_raw.dev_attr.attr,
-	&iio_dev_attr_in7min6_raw.dev_attr.attr,
-	&iio_dev_attr_in9min8_raw.dev_attr.attr,
-	&iio_dev_attr_in11min10_raw.dev_attr.attr,
-	&iio_dev_attr_name.dev_attr.attr,
-	&iio_dev_attr_in_scale.dev_attr.attr,
-	NULL
-};
-
-static struct attribute_group max1238_dev_attr_group = {
-	.attrs = max1238_device_attrs,
-};
-
-static struct attribute *max1238_scan_el_attrs[] = {
-	&iio_scan_el_in0.dev_attr.attr,	&dev_attr_in0_type.attr,
-	&iio_const_attr_in0_index.dev_attr.attr,
-	&iio_scan_el_in1.dev_attr.attr,	&dev_attr_in1_type.attr,
-	&iio_const_attr_in1_index.dev_attr.attr,
-	&iio_scan_el_in2.dev_attr.attr,	&dev_attr_in2_type.attr,
-	&iio_const_attr_in2_index.dev_attr.attr,
-	&iio_scan_el_in3.dev_attr.attr,	&dev_attr_in3_type.attr,
-	&iio_const_attr_in3_index.dev_attr.attr,
-	&iio_scan_el_in4.dev_attr.attr,	&dev_attr_in4_type.attr,
-	&iio_const_attr_in4_index.dev_attr.attr,
-	&iio_scan_el_in5.dev_attr.attr,	&dev_attr_in5_type.attr,
-	&iio_const_attr_in5_index.dev_attr.attr,
-	&iio_scan_el_in6.dev_attr.attr,	&dev_attr_in6_type.attr,
-	&iio_const_attr_in6_index.dev_attr.attr,
-	&iio_scan_el_in7.dev_attr.attr,	&dev_attr_in7_type.attr,
-	&iio_const_attr_in7_index.dev_attr.attr,
-	&iio_scan_el_in8.dev_attr.attr,	&dev_attr_in8_type.attr,
-	&iio_const_attr_in8_index.dev_attr.attr,
-	&iio_scan_el_in9.dev_attr.attr,	&dev_attr_in9_type.attr,
-	&iio_const_attr_in9_index.dev_attr.attr,
-	&iio_scan_el_in10.dev_attr.attr,	&dev_attr_in10_type.attr,
-	&iio_const_attr_in10_index.dev_attr.attr,
-	&iio_scan_el_in11.dev_attr.attr,	&dev_attr_in11_type.attr,
-	&iio_const_attr_in11_index.dev_attr.attr,
-	&iio_scan_el_in0min1.dev_attr.attr,	&dev_attr_in0min1_type.attr,
-	&iio_const_attr_in0min1_index.dev_attr.attr,
-	&iio_scan_el_in2min3.dev_attr.attr,	&dev_attr_in2min3_type.attr,
-	&iio_const_attr_in2min3_index.dev_attr.attr,
-	&iio_scan_el_in4min5.dev_attr.attr,	&dev_attr_in4min5_type.attr,
-	&iio_const_attr_in4min5_index.dev_attr.attr,
-	&iio_scan_el_in6min7.dev_attr.attr,	&dev_attr_in6min7_type.attr,
-	&iio_const_attr_in6min7_index.dev_attr.attr,
-	&iio_scan_el_in8min9.dev_attr.attr,	&dev_attr_in8min9_type.attr,
-	&iio_const_attr_in8min9_index.dev_attr.attr,
-	&iio_scan_el_in10min11.dev_attr.attr,	&dev_attr_in10min11_type.attr,
-	&iio_const_attr_in10min11_index.dev_attr.attr,
-	&iio_scan_el_in1min0.dev_attr.attr,	&dev_attr_in1min0_type.attr,
-	&iio_const_attr_in1min0_index.dev_attr.attr,
-	&iio_scan_el_in3min2.dev_attr.attr,	&dev_attr_in3min2_type.attr,
-	&iio_const_attr_in3min2_index.dev_attr.attr,
-	&iio_scan_el_in5min4.dev_attr.attr,	&dev_attr_in5min4_type.attr,
-	&iio_const_attr_in5min4_index.dev_attr.attr,
-	&iio_scan_el_in7min6.dev_attr.attr,	&dev_attr_in7min6_type.attr,
-	&iio_const_attr_in7min6_index.dev_attr.attr,
-	&iio_scan_el_in9min8.dev_attr.attr,	&dev_attr_in9min8_type.attr,
-	&iio_const_attr_in9min8_index.dev_attr.attr,
-	&iio_scan_el_in11min10.dev_attr.attr,	&dev_attr_in11min10_type.attr,
-	&iio_const_attr_in11min10_index.dev_attr.attr,
-	NULL,
-};
-
-static struct attribute_group max1238_scan_el_group = {
-	.name = "scan_elements",
-	.attrs = max1238_scan_el_attrs,
-};
-
+#define MAX1363_12X_CHANS(bits) {			\
+	MAX1363_CHAN_U(0, _s0, 0, bits),		\
+	MAX1363_CHAN_U(1, _s1, 1, bits),		\
+	MAX1363_CHAN_U(2, _s2, 2, bits),		\
+	MAX1363_CHAN_U(3, _s3, 3, bits),		\
+	MAX1363_CHAN_U(4, _s4, 4, bits),		\
+	MAX1363_CHAN_U(5, _s5, 5, bits),		\
+	MAX1363_CHAN_U(6, _s6, 6, bits),		\
+	MAX1363_CHAN_U(7, _s7, 7, bits),		\
+	MAX1363_CHAN_U(8, _s8, 8, bits),		\
+	MAX1363_CHAN_U(9, _s9, 9, bits),		\
+	MAX1363_CHAN_U(10, _s10, 10, bits),		\
+	MAX1363_CHAN_U(11, _s11, 11, bits),		\
+	MAX1363_CHAN_B(0, 1, d0m1, 12, bits),		\
+	MAX1363_CHAN_B(2, 3, d2m3, 13, bits),		\
+	MAX1363_CHAN_B(4, 5, d4m5, 14, bits),		\
+	MAX1363_CHAN_B(6, 7, d6m7, 15, bits),		\
+	MAX1363_CHAN_B(8, 9, d8m9, 16, bits),		\
+	MAX1363_CHAN_B(10, 11, d10m11, 17, bits),	\
+	MAX1363_CHAN_B(1, 0, d1m0, 18, bits),		\
+	MAX1363_CHAN_B(3, 2, d3m2, 19, bits),		\
+	MAX1363_CHAN_B(5, 4, d5m4, 20, bits),		\
+	MAX1363_CHAN_B(7, 6, d7m6, 21, bits),		\
+	MAX1363_CHAN_B(9, 8, d9m8, 22, bits),		\
+	MAX1363_CHAN_B(11, 10, d11m10, 23, bits),	\
+	IIO_CHAN_SOFT_TIMESTAMP(24)			\
+	}
+static struct iio_chan_spec max1038_channels[] = MAX1363_12X_CHANS(8);
+static struct iio_chan_spec max1138_channels[] = MAX1363_12X_CHANS(10);
+static struct iio_chan_spec max1238_channels[] = MAX1363_12X_CHANS(12);
 
 static const enum max1363_modes max11607_mode_list[] = {
 	_s0, _s1, _s2, _s3,
@@ -542,72 +425,43 @@
 	d1m0to3m2, d1m0to5m4, d1m0to7m6,
 };
 
-static struct attribute *max11608_device_attrs[] = {
-	&iio_dev_attr_in0_raw.dev_attr.attr,
-	&iio_dev_attr_in1_raw.dev_attr.attr,
-	&iio_dev_attr_in2_raw.dev_attr.attr,
-	&iio_dev_attr_in3_raw.dev_attr.attr,
-	&iio_dev_attr_in4_raw.dev_attr.attr,
-	&iio_dev_attr_in5_raw.dev_attr.attr,
-	&iio_dev_attr_in6_raw.dev_attr.attr,
-	&iio_dev_attr_in7_raw.dev_attr.attr,
-	&iio_dev_attr_in0min1_raw.dev_attr.attr,
-	&iio_dev_attr_in2min3_raw.dev_attr.attr,
-	&iio_dev_attr_in4min5_raw.dev_attr.attr,
-	&iio_dev_attr_in6min7_raw.dev_attr.attr,
-	&iio_dev_attr_in1min0_raw.dev_attr.attr,
-	&iio_dev_attr_in3min2_raw.dev_attr.attr,
-	&iio_dev_attr_in5min4_raw.dev_attr.attr,
-	&iio_dev_attr_in7min6_raw.dev_attr.attr,
-	&iio_dev_attr_name.dev_attr.attr,
-	&iio_dev_attr_in_scale.dev_attr.attr,
-	NULL
-};
+#define MAX1363_8X_CHANS(bits) {				\
+		MAX1363_CHAN_U(0, _s0, 0, bits),		\
+			MAX1363_CHAN_U(1, _s1, 1, bits),	\
+			MAX1363_CHAN_U(2, _s2, 2, bits),	\
+			MAX1363_CHAN_U(3, _s3, 3, bits),	\
+			MAX1363_CHAN_U(4, _s4, 4, bits),	\
+			MAX1363_CHAN_U(5, _s5, 5, bits),	\
+			MAX1363_CHAN_U(6, _s6, 6, bits),	\
+			MAX1363_CHAN_U(7, _s7, 7, bits),	\
+			MAX1363_CHAN_B(0, 1, d0m1, 8, bits),	\
+			MAX1363_CHAN_B(2, 3, d2m3, 9, bits),	\
+			MAX1363_CHAN_B(4, 5, d4m5, 10, bits),	\
+			MAX1363_CHAN_B(6, 7, d6m7, 11, bits),	\
+			MAX1363_CHAN_B(1, 0, d1m0, 12, bits),	\
+			MAX1363_CHAN_B(3, 2, d3m2, 13, bits),	\
+			MAX1363_CHAN_B(5, 4, d5m4, 14, bits),	\
+			MAX1363_CHAN_B(7, 6, d7m6, 15, bits),	\
+			IIO_CHAN_SOFT_TIMESTAMP(16)		\
+		}
+static struct iio_chan_spec max11602_channels[] = MAX1363_8X_CHANS(8);
+static struct iio_chan_spec max11608_channels[] = MAX1363_8X_CHANS(10);
+static struct iio_chan_spec max11614_channels[] = MAX1363_8X_CHANS(12);
 
-static struct attribute_group max11608_dev_attr_group = {
-	.attrs = max11608_device_attrs,
+static const enum max1363_modes max11644_mode_list[] = {
+	_s0, _s1, s0to1, d0m1, d1m0,
 };
 
-static struct attribute *max11608_scan_el_attrs[] = {
-	&iio_scan_el_in0.dev_attr.attr,	&dev_attr_in0_type.attr,
-	&iio_const_attr_in0_index.dev_attr.attr,
-	&iio_scan_el_in1.dev_attr.attr,	&dev_attr_in1_type.attr,
-	&iio_const_attr_in1_index.dev_attr.attr,
-	&iio_scan_el_in2.dev_attr.attr,	&dev_attr_in2_type.attr,
-	&iio_const_attr_in2_index.dev_attr.attr,
-	&iio_scan_el_in3.dev_attr.attr,	&dev_attr_in3_type.attr,
-	&iio_const_attr_in3_index.dev_attr.attr,
-	&iio_scan_el_in4.dev_attr.attr,	&dev_attr_in4_type.attr,
-	&iio_const_attr_in4_index.dev_attr.attr,
-	&iio_scan_el_in5.dev_attr.attr,	&dev_attr_in5_type.attr,
-	&iio_const_attr_in5_index.dev_attr.attr,
-	&iio_scan_el_in6.dev_attr.attr,	&dev_attr_in6_type.attr,
-	&iio_const_attr_in6_index.dev_attr.attr,
-	&iio_scan_el_in7.dev_attr.attr,	&dev_attr_in7_type.attr,
-	&iio_const_attr_in7_index.dev_attr.attr,
-	&iio_scan_el_in0min1.dev_attr.attr,	&dev_attr_in0min1_type.attr,
-	&iio_const_attr_in0min1_index.dev_attr.attr,
-	&iio_scan_el_in2min3.dev_attr.attr,	&dev_attr_in2min3_type.attr,
-	&iio_const_attr_in2min3_index.dev_attr.attr,
-	&iio_scan_el_in4min5.dev_attr.attr,	&dev_attr_in4min5_type.attr,
-	&iio_const_attr_in4min5_index.dev_attr.attr,
-	&iio_scan_el_in6min7.dev_attr.attr,	&dev_attr_in6min7_type.attr,
-	&iio_const_attr_in6min7_index.dev_attr.attr,
-	&iio_scan_el_in1min0.dev_attr.attr,	&dev_attr_in1min0_type.attr,
-	&iio_const_attr_in1min0_index.dev_attr.attr,
-	&iio_scan_el_in3min2.dev_attr.attr,	&dev_attr_in3min2_type.attr,
-	&iio_const_attr_in3min2_index.dev_attr.attr,
-	&iio_scan_el_in5min4.dev_attr.attr,	&dev_attr_in5min4_type.attr,
-	&iio_const_attr_in5min4_index.dev_attr.attr,
-	&iio_scan_el_in7min6.dev_attr.attr,	&dev_attr_in7min6_type.attr,
-	&iio_const_attr_in7min6_index.dev_attr.attr,
-	NULL
-};
+#define MAX1363_2X_CHANS(bits) {			\
+	MAX1363_CHAN_U(0, _s0, 0, bits),		\
+	MAX1363_CHAN_U(1, _s1, 1, bits),		\
+	MAX1363_CHAN_B(0, 1, d0m1, 2, bits),		\
+	MAX1363_CHAN_B(1, 0, d1m0, 3, bits),		\
+	IIO_CHAN_SOFT_TIMESTAMP(4)			\
+	}
 
-static struct attribute_group max11608_scan_el_group = {
-	.name = "scan_elements",
-	.attrs = max11608_scan_el_attrs,
-};
+static struct iio_chan_spec max11646_channels[] = MAX1363_2X_CHANS(10);
+static struct iio_chan_spec max11644_channels[] = MAX1363_2X_CHANS(12);
 
 enum { max1361,
        max1362,
@@ -643,354 +497,10 @@
        max11615,
        max11616,
        max11617,
-};
-
-/* max1363 and max1368 tested - rest from data sheet */
-static const struct max1363_chip_info max1363_chip_info_tbl[] = {
-	[max1361] = {
-		.num_inputs = 4,
-		.bits = 10,
-		.int_vref_mv = 2048,
-		.monitor_mode = 1,
-		.mode_list = max1363_mode_list,
-		.num_modes = ARRAY_SIZE(max1363_mode_list),
-		.default_mode = s0to3,
-		.dev_attrs = &max1363_dev_attr_group,
-		.scan_attrs = &max1363_scan_el_group,
-	},
-	[max1362] = {
-		.num_inputs = 4,
-		.bits = 10,
-		.int_vref_mv = 4096,
-		.monitor_mode = 1,
-		.mode_list = max1363_mode_list,
-		.num_modes = ARRAY_SIZE(max1363_mode_list),
-		.default_mode = s0to3,
-		.dev_attrs = &max1363_dev_attr_group,
-		.scan_attrs = &max1363_scan_el_group,
-	},
-	[max1363] = {
-		.num_inputs = 4,
-		.bits = 12,
-		.int_vref_mv = 2048,
-		.monitor_mode = 1,
-		.mode_list = max1363_mode_list,
-		.num_modes = ARRAY_SIZE(max1363_mode_list),
-		.default_mode = s0to3,
-		.dev_attrs = &max1363_dev_attr_group,
-		.scan_attrs = &max1363_scan_el_group,
-	},
-	[max1364] = {
-		.num_inputs = 4,
-		.bits = 12,
-		.int_vref_mv = 4096,
-		.monitor_mode = 1,
-		.mode_list = max1363_mode_list,
-		.num_modes = ARRAY_SIZE(max1363_mode_list),
-		.default_mode = s0to3,
-		.dev_attrs = &max1363_dev_attr_group,
-		.scan_attrs = &max1363_scan_el_group,
-	},
-	[max1036] = {
-		.num_inputs = 4,
-		.bits = 8,
-		.int_vref_mv = 4096,
-		.mode_list = max1236_mode_list,
-		.num_modes = ARRAY_SIZE(max1236_mode_list),
-		.default_mode = s0to3,
-		.dev_attrs = &max1363_dev_attr_group,
-		.scan_attrs = &max1363_scan_el_group,
-	},
-	[max1037] = {
-		.num_inputs = 4,
-		.bits = 8,
-		.int_vref_mv = 2048,
-		.mode_list = max1236_mode_list,
-		.num_modes = ARRAY_SIZE(max1236_mode_list),
-		.default_mode = s0to3,
-		.dev_attrs = &max1363_dev_attr_group,
-		.scan_attrs = &max1363_scan_el_group,
-	},
-	[max1038] = {
-		.num_inputs = 12,
-		.bits = 8,
-		.int_vref_mv = 4096,
-		.mode_list = max1238_mode_list,
-		.num_modes = ARRAY_SIZE(max1238_mode_list),
-		.default_mode = s0to11,
-		.dev_attrs = &max1238_dev_attr_group,
-		.scan_attrs = &max1238_scan_el_group,
-	},
-	[max1039] = {
-		.num_inputs = 12,
-		.bits = 8,
-		.int_vref_mv = 2048,
-		.mode_list = max1238_mode_list,
-		.num_modes = ARRAY_SIZE(max1238_mode_list),
-		.default_mode = s0to11,
-		.dev_attrs = &max1238_dev_attr_group,
-		.scan_attrs = &max1238_scan_el_group,
-	},
-	[max1136] = {
-		.num_inputs = 4,
-		.bits = 10,
-		.int_vref_mv = 4096,
-		.mode_list = max1236_mode_list,
-		.num_modes = ARRAY_SIZE(max1236_mode_list),
-		.default_mode = s0to3,
-		.dev_attrs = &max1363_dev_attr_group,
-		.scan_attrs = &max1363_scan_el_group,
-	},
-	[max1137] = {
-		.num_inputs = 4,
-		.bits = 10,
-		.int_vref_mv = 2048,
-		.mode_list = max1236_mode_list,
-		.num_modes = ARRAY_SIZE(max1236_mode_list),
-		.default_mode = s0to3,
-		.dev_attrs = &max1363_dev_attr_group,
-		.scan_attrs = &max1363_scan_el_group,
-	},
-	[max1138] = {
-		.num_inputs = 12,
-		.bits = 10,
-		.int_vref_mv = 4096,
-		.mode_list = max1238_mode_list,
-		.num_modes = ARRAY_SIZE(max1238_mode_list),
-		.default_mode = s0to11,
-		.dev_attrs = &max1238_dev_attr_group,
-		.scan_attrs = &max1238_scan_el_group,
-	},
-	[max1139] = {
-		.num_inputs = 12,
-		.bits = 10,
-		.int_vref_mv = 2048,
-		.mode_list = max1238_mode_list,
-		.num_modes = ARRAY_SIZE(max1238_mode_list),
-		.default_mode = s0to11,
-		.dev_attrs = &max1238_dev_attr_group,
-		.scan_attrs = &max1238_scan_el_group,
-	},
-	[max1236] = {
-		.num_inputs = 4,
-		.bits = 12,
-		.int_vref_mv = 4096,
-		.mode_list = max1236_mode_list,
-		.num_modes = ARRAY_SIZE(max1236_mode_list),
-		.default_mode = s0to3,
-		.dev_attrs = &max1363_dev_attr_group,
-		.scan_attrs = &max1363_scan_el_group,
-	},
-	[max1237] = {
-		.num_inputs = 4,
-		.bits = 12,
-		.int_vref_mv = 2048,
-		.mode_list = max1236_mode_list,
-		.num_modes = ARRAY_SIZE(max1236_mode_list),
-		.default_mode = s0to3,
-		.dev_attrs = &max1363_dev_attr_group,
-		.scan_attrs = &max1363_scan_el_group,
-	},
-	[max1238] = {
-		.num_inputs = 12,
-		.bits = 12,
-		.int_vref_mv = 4096,
-		.mode_list = max1238_mode_list,
-		.num_modes = ARRAY_SIZE(max1238_mode_list),
-		.default_mode = s0to11,
-		.dev_attrs = &max1238_dev_attr_group,
-		.scan_attrs = &max1238_scan_el_group,
-	},
-	[max1239] = {
-		.num_inputs = 12,
-		.bits = 12,
-		.int_vref_mv = 2048,
-		.mode_list = max1238_mode_list,
-		.num_modes = ARRAY_SIZE(max1238_mode_list),
-		.default_mode = s0to11,
-		.dev_attrs = &max1238_dev_attr_group,
-		.scan_attrs = &max1238_scan_el_group,
-	},
-	[max11600] = {
-		.num_inputs = 4,
-		.bits = 8,
-		.int_vref_mv = 4096,
-		.mode_list = max11607_mode_list,
-		.num_modes = ARRAY_SIZE(max11607_mode_list),
-		.default_mode = s0to3,
-		.dev_attrs = &max1363_dev_attr_group,
-		.scan_attrs = &max1363_scan_el_group,
-	},
-	[max11601] = {
-		.num_inputs = 4,
-		.bits = 8,
-		.int_vref_mv = 2048,
-		.mode_list = max11607_mode_list,
-		.num_modes = ARRAY_SIZE(max11607_mode_list),
-		.default_mode = s0to3,
-		.dev_attrs = &max1363_dev_attr_group,
-		.scan_attrs = &max1363_scan_el_group,
-	},
-	[max11602] = {
-		.num_inputs = 8,
-		.bits = 8,
-		.int_vref_mv = 4096,
-		.mode_list = max11608_mode_list,
-		.num_modes = ARRAY_SIZE(max11608_mode_list),
-		.default_mode = s0to7,
-		.dev_attrs = &max11608_dev_attr_group,
-		.scan_attrs = &max11608_scan_el_group,
-	},
-	[max11603] = {
-		.num_inputs = 8,
-		.bits = 8,
-		.int_vref_mv = 2048,
-		.mode_list = max11608_mode_list,
-		.num_modes = ARRAY_SIZE(max11608_mode_list),
-		.default_mode = s0to7,
-		.dev_attrs = &max11608_dev_attr_group,
-		.scan_attrs = &max11608_scan_el_group,
-	},
-	[max11604] = {
-		.num_inputs = 12,
-		.bits = 8,
-		.int_vref_mv = 4098,
-		.mode_list = max1238_mode_list,
-		.num_modes = ARRAY_SIZE(max1238_mode_list),
-		.default_mode = s0to11,
-		.dev_attrs = &max1238_dev_attr_group,
-		.scan_attrs = &max1238_scan_el_group,
-	},
-	[max11605] = {
-		.num_inputs = 12,
-		.bits = 8,
-		.int_vref_mv = 2048,
-		.mode_list = max1238_mode_list,
-		.num_modes = ARRAY_SIZE(max1238_mode_list),
-		.default_mode = s0to11,
-		.dev_attrs = &max1238_dev_attr_group,
-		.scan_attrs = &max1238_scan_el_group,
-	},
-	[max11606] = {
-		.num_inputs = 4,
-		.bits = 10,
-		.int_vref_mv = 4096,
-		.mode_list = max11607_mode_list,
-		.num_modes = ARRAY_SIZE(max11607_mode_list),
-		.default_mode = s0to3,
-		.dev_attrs = &max1363_dev_attr_group,
-		.scan_attrs = &max1363_scan_el_group,
-	},
-	[max11607] = {
-		.num_inputs = 4,
-		.bits = 10,
-		.int_vref_mv = 2048,
-		.mode_list = max11607_mode_list,
-		.num_modes = ARRAY_SIZE(max11607_mode_list),
-		.default_mode = s0to3,
-		.dev_attrs = &max1363_dev_attr_group,
-		.scan_attrs = &max1363_scan_el_group,
-	},
-	[max11608] = {
-		.num_inputs = 8,
-		.bits = 10,
-		.int_vref_mv = 4096,
-		.mode_list = max11608_mode_list,
-		.num_modes = ARRAY_SIZE(max11608_mode_list),
-		.default_mode = s0to7,
-		.dev_attrs = &max11608_dev_attr_group,
-		.scan_attrs = &max11608_scan_el_group,
-	},
-	[max11609] = {
-		.num_inputs = 8,
-		.bits = 10,
-		.int_vref_mv = 2048,
-		.mode_list = max11608_mode_list,
-		.num_modes = ARRAY_SIZE(max11608_mode_list),
-		.default_mode = s0to7,
-		.dev_attrs = &max11608_dev_attr_group,
-		.scan_attrs = &max11608_scan_el_group,
-	},
-	[max11610] = {
-		.num_inputs = 12,
-		.bits = 10,
-		.int_vref_mv = 4098,
-		.mode_list = max1238_mode_list,
-		.num_modes = ARRAY_SIZE(max1238_mode_list),
-		.default_mode = s0to11,
-		.dev_attrs = &max1238_dev_attr_group,
-		.scan_attrs = &max1238_scan_el_group,
-	},
-	[max11611] = {
-		.num_inputs = 12,
-		.bits = 10,
-		.int_vref_mv = 2048,
-		.mode_list = max1238_mode_list,
-		.num_modes = ARRAY_SIZE(max1238_mode_list),
-		.default_mode = s0to11,
-		.dev_attrs = &max1238_dev_attr_group,
-		.scan_attrs = &max1238_scan_el_group,
-	},
-	[max11612] = {
-		.num_inputs = 4,
-		.bits = 12,
-		.int_vref_mv = 4096,
-		.mode_list = max11607_mode_list,
-		.num_modes = ARRAY_SIZE(max11607_mode_list),
-		.default_mode = s0to3,
-		.dev_attrs = &max1363_dev_attr_group,
-		.scan_attrs = &max1363_scan_el_group,
-	},
-	[max11613] = {
-		.num_inputs = 4,
-		.bits = 12,
-		.int_vref_mv = 2048,
-		.mode_list = max11607_mode_list,
-		.num_modes = ARRAY_SIZE(max11607_mode_list),
-		.default_mode = s0to3,
-		.dev_attrs = &max1363_dev_attr_group,
-		.scan_attrs = &max1363_scan_el_group,
-	},
-	[max11614] = {
-		.num_inputs = 8,
-		.bits = 12,
-		.int_vref_mv = 4096,
-		.mode_list = max11608_mode_list,
-		.num_modes = ARRAY_SIZE(max11608_mode_list),
-		.default_mode = s0to7,
-		.dev_attrs = &max11608_dev_attr_group,
-		.scan_attrs = &max11608_scan_el_group,
-	},
-	[max11615] = {
-		.num_inputs = 8,
-		.bits = 12,
-		.int_vref_mv = 2048,
-		.mode_list = max11608_mode_list,
-		.num_modes = ARRAY_SIZE(max11608_mode_list),
-		.default_mode = s0to7,
-		.dev_attrs = &max11608_dev_attr_group,
-		.scan_attrs = &max11608_scan_el_group,
-	},
-	[max11616] = {
-		.num_inputs = 12,
-		.bits = 12,
-		.int_vref_mv = 4098,
-		.mode_list = max1238_mode_list,
-		.num_modes = ARRAY_SIZE(max1238_mode_list),
-		.default_mode = s0to11,
-		.dev_attrs = &max1238_dev_attr_group,
-		.scan_attrs = &max1238_scan_el_group,
-	},
-	[max11617] = {
-		.num_inputs = 12,
-		.bits = 12,
-		.int_vref_mv = 2048,
-		.mode_list = max1238_mode_list,
-		.num_modes = ARRAY_SIZE(max1238_mode_list),
-		.default_mode = s0to11,
-		.dev_attrs = &max1238_dev_attr_group,
-		.scan_attrs = &max1238_scan_el_group,
-	}
+       max11644,
+       max11645,
+       max11646,
+       max11647
 };
 
 static const int max1363_monitor_speeds[] = { 133000, 665000, 33300, 16600,
@@ -1000,8 +510,7 @@
 					struct device_attribute *attr,
 					char *buf)
 {
-	struct iio_dev *dev_info = dev_get_drvdata(dev);
-	struct max1363_state *st = iio_dev_get_devdata(dev_info);
+	struct max1363_state *st = iio_priv(dev_get_drvdata(dev));
 	return sprintf(buf, "%d\n", max1363_monitor_speeds[st->monitor_speed]);
 }
 
@@ -1010,8 +519,8 @@
 					const char *buf,
 					size_t len)
 {
-	struct iio_dev *dev_info = dev_get_drvdata(dev);
-	struct max1363_state *st = iio_dev_get_devdata(dev_info);
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct max1363_state *st = iio_priv(indio_dev);
 	int i, ret;
 	unsigned long val;
 	bool found = false;
@@ -1027,9 +536,9 @@
 	if (!found)
 		return -EINVAL;
 
-	mutex_lock(&dev_info->mlock);
+	mutex_lock(&indio_dev->mlock);
 	st->monitor_speed = i;
-	mutex_unlock(&dev_info->mlock);
+	mutex_unlock(&indio_dev->mlock);
 
 	return 0;
 }
@@ -1041,52 +550,24 @@
 static IIO_CONST_ATTR(sampling_frequency_available,
 		"133000 665000 33300 16600 8300 4200 2000 1000");
 
-static ssize_t max1363_show_thresh(struct device *dev,
-				struct device_attribute *attr,
-				char *buf,
-				bool high)
+static int max1363_read_thresh(struct iio_dev *indio_dev,
+			       int event_code,
+			       int *val)
 {
-	struct iio_dev *dev_info = dev_get_drvdata(dev);
-	struct max1363_state *st = iio_dev_get_devdata(dev_info);
-	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
-
-	if (high)
-		return sprintf(buf, "%d\n",
-			st->thresh_high[this_attr->address]);
+	struct max1363_state *st = iio_priv(indio_dev);
+	if (IIO_EVENT_CODE_EXTRACT_DIR(event_code) == IIO_EV_DIR_FALLING)
+		*val = st->thresh_low[IIO_EVENT_CODE_EXTRACT_NUM(event_code)];
 	else
-		return sprintf(buf, "%d\n",
-			st->thresh_low[this_attr->address & 0x7]);
-}
-
-static ssize_t max1363_show_thresh_low(struct device *dev,
-				struct device_attribute *attr,
-				char *buf)
-{
-	return max1363_show_thresh(dev, attr, buf, false);
-}
-
-static ssize_t max1363_show_thresh_high(struct device *dev,
-					struct device_attribute *attr,
-					char *buf)
-{
-	return max1363_show_thresh(dev, attr, buf, true);
+		*val = st->thresh_high[IIO_EVENT_CODE_EXTRACT_NUM(event_code)];
+	return 0;
 }
 
-static ssize_t max1363_store_thresh_unsigned(struct device *dev,
-					struct device_attribute *attr,
-					const char *buf,
-					size_t len,
-					bool high)
+static int max1363_write_thresh(struct iio_dev *indio_dev,
+				int event_code,
+				int val)
 {
-	struct iio_dev *dev_info = dev_get_drvdata(dev);
-	struct max1363_state *st = iio_dev_get_devdata(dev_info);
-	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
-	unsigned long val;
-	int ret;
-
-	ret = strict_strtoul(buf, 10, &val);
-	if (ret)
-		return -EINVAL;
+	struct max1363_state *st = iio_priv(indio_dev);
+	/* make it handle signed correctly as well */
 	switch (st->chip_info->bits) {
 	case 10:
 		if (val > 0x3FF)
@@ -1098,220 +579,60 @@
 		break;
 	}
 
-	switch (high) {
-	case 1:
-		st->thresh_high[this_attr->address] = val;
-		break;
-	case 0:
-		st->thresh_low[this_attr->address & 0x7] = val;
-		break;
-	}
-
-	return len;
-}
-
-static ssize_t max1363_store_thresh_high_unsigned(struct device *dev,
-						struct device_attribute *attr,
-						const char *buf,
-						size_t len)
-{
-	return max1363_store_thresh_unsigned(dev, attr, buf, len, true);
-}
-
-static ssize_t max1363_store_thresh_low_unsigned(struct device *dev,
-						struct device_attribute *attr,
-						const char *buf,
-						size_t len)
-{
-	return max1363_store_thresh_unsigned(dev, attr, buf, len, false);
-}
-
-static ssize_t max1363_store_thresh_signed(struct device *dev,
-					struct device_attribute *attr,
-					const char *buf,
-					size_t len,
-					bool high)
-{
-	struct iio_dev *dev_info = dev_get_drvdata(dev);
-	struct max1363_state *st = iio_dev_get_devdata(dev_info);
-	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
-	long val;
-	int ret;
-
-	ret = strict_strtol(buf, 10, &val);
-	if (ret)
-		return -EINVAL;
-	switch (st->chip_info->bits) {
-	case 10:
-		if (val < -512 || val > 511)
-			return -EINVAL;
-		break;
-	case 12:
-		if (val < -2048 || val > 2047)
-			return -EINVAL;
-		break;
-	}
-
-	switch (high) {
-	case 1:
-		st->thresh_high[this_attr->address] = val;
+	switch (IIO_EVENT_CODE_EXTRACT_DIR(event_code)) {
+	case IIO_EV_DIR_FALLING:
+		st->thresh_low[IIO_EVENT_CODE_EXTRACT_NUM(event_code)] = val;
 		break;
-	case 0:
-		st->thresh_low[this_attr->address & 0x7] = val;
+	case IIO_EV_DIR_RISING:
+		st->thresh_high[IIO_EVENT_CODE_EXTRACT_NUM(event_code)] = val;
 		break;
 	}
 
-	return len;
-}
-
-static ssize_t max1363_store_thresh_high_signed(struct device *dev,
-						struct device_attribute *attr,
-						const char *buf,
-						size_t len)
-{
-	return max1363_store_thresh_signed(dev, attr, buf, len, true);
-}
-
-static ssize_t max1363_store_thresh_low_signed(struct device *dev,
-						struct device_attribute *attr,
-						const char *buf,
-						size_t len)
-{
-	return max1363_store_thresh_signed(dev, attr, buf, len, false);
-}
-
-static IIO_DEVICE_ATTR(in0_thresh_high_value, S_IRUGO | S_IWUSR,
-		max1363_show_thresh_high,
-		max1363_store_thresh_high_unsigned, 0);
-static IIO_DEVICE_ATTR(in0_thresh_low_value, S_IRUGO | S_IWUSR,
-		max1363_show_thresh_low,
-		max1363_store_thresh_low_unsigned, 0);
-static IIO_DEVICE_ATTR(in1_thresh_high_value, S_IRUGO | S_IWUSR,
-		max1363_show_thresh_high,
-		max1363_store_thresh_high_unsigned, 1);
-static IIO_DEVICE_ATTR(in1_thresh_low_value, S_IRUGO | S_IWUSR,
-		max1363_show_thresh_low,
-		max1363_store_thresh_low_unsigned, 1);
-static IIO_DEVICE_ATTR(in2_thresh_high_value, S_IRUGO | S_IWUSR,
-		max1363_show_thresh_high,
-		max1363_store_thresh_high_unsigned, 2);
-static IIO_DEVICE_ATTR(in2_thresh_low_value, S_IRUGO | S_IWUSR,
-		max1363_show_thresh_low,
-		max1363_store_thresh_low_unsigned, 2);
-static IIO_DEVICE_ATTR(in3_thresh_high_value, S_IRUGO | S_IWUSR,
-		max1363_show_thresh_high,
-		max1363_store_thresh_high_unsigned, 3);
-static IIO_DEVICE_ATTR(in3_thresh_low_value, S_IRUGO | S_IWUSR,
-		max1363_show_thresh_low,
-		max1363_store_thresh_low_unsigned, 3);
-
-static IIO_DEVICE_ATTR_NAMED(in0min1_thresh_high_value,
-			in0-in1_thresh_high_value,
-			S_IRUGO | S_IWUSR, max1363_show_thresh_high,
-			max1363_store_thresh_high_signed, 4);
-static IIO_DEVICE_ATTR_NAMED(in0min1_thresh_low_value,
-			in0-in1_thresh_low_value,
-			S_IRUGO | S_IWUSR, max1363_show_thresh_low,
-			max1363_store_thresh_low_signed, 4);
-static IIO_DEVICE_ATTR_NAMED(in2min3_thresh_high_value,
-			in2-in3_thresh_high_value,
-			S_IRUGO | S_IWUSR, max1363_show_thresh_high,
-			max1363_store_thresh_high_signed, 5);
-static IIO_DEVICE_ATTR_NAMED(in2min3_thresh_low_value,
-			in2-in3_thresh_low_value,
-			S_IRUGO | S_IWUSR, max1363_show_thresh_low,
-			max1363_store_thresh_low_signed, 5);
-static IIO_DEVICE_ATTR_NAMED(in1min0_thresh_high_value,
-			in1-in0_thresh_high_value,
-			S_IRUGO | S_IWUSR, max1363_show_thresh_high,
-			max1363_store_thresh_high_signed, 6);
-static IIO_DEVICE_ATTR_NAMED(in1min0_thresh_low_value,
-			in1-in0_thresh_low_value,
-			S_IRUGO | S_IWUSR, max1363_show_thresh_low,
-			max1363_store_thresh_low_signed, 6);
-static IIO_DEVICE_ATTR_NAMED(in3min2_thresh_high_value,
-			in3-in2_thresh_high_value,
-			S_IRUGO | S_IWUSR, max1363_show_thresh_high,
-			max1363_store_thresh_high_signed, 7);
-static IIO_DEVICE_ATTR_NAMED(in3min2_thresh_low_value,
-			in3-in2_thresh_low_value,
-			S_IRUGO | S_IWUSR, max1363_show_thresh_low,
-			max1363_store_thresh_low_signed, 7);
-
-static int max1363_int_th(struct iio_dev *dev_info,
-			int index,
-			s64 timestamp,
-			int not_test)
-{
-	struct max1363_state *st = dev_info->dev_data;
-
-	st->last_timestamp = timestamp;
-	schedule_work(&st->thresh_work);
 	return 0;
 }
 
-static void max1363_thresh_handler_bh(struct work_struct *work_s)
+static const int max1363_event_codes[] = {
+	IIO_EVENT_CODE_IN_LOW_THRESH(3), IIO_EVENT_CODE_IN_HIGH_THRESH(3),
+	IIO_EVENT_CODE_IN_LOW_THRESH(2), IIO_EVENT_CODE_IN_HIGH_THRESH(2),
+	IIO_EVENT_CODE_IN_LOW_THRESH(1), IIO_EVENT_CODE_IN_HIGH_THRESH(1),
+	IIO_EVENT_CODE_IN_LOW_THRESH(0), IIO_EVENT_CODE_IN_HIGH_THRESH(0)
+};
+
+static irqreturn_t max1363_event_handler(int irq, void *private)
 {
-	struct max1363_state *st = container_of(work_s, struct max1363_state,
-						thresh_work);
+	struct iio_dev *indio_dev = private;
+	struct max1363_state *st = iio_priv(indio_dev);
+	s64 timestamp = iio_get_time_ns();
+	unsigned long mask, loc;
 	u8 rx;
 	u8 tx[2] = { st->setupbyte,
 		     MAX1363_MON_INT_ENABLE | (st->monitor_speed << 1) | 0xF0 };
 
 	i2c_master_recv(st->client, &rx, 1);
-	if (rx & (1 << 0))
-		iio_push_event(st->indio_dev, 0,
-			IIO_EVENT_CODE_IN_LOW_THRESH(3),
-			st->last_timestamp);
-	if (rx & (1 << 1))
-		iio_push_event(st->indio_dev, 0,
-			IIO_EVENT_CODE_IN_HIGH_THRESH(3),
-			st->last_timestamp);
-	if (rx & (1 << 2))
-		iio_push_event(st->indio_dev, 0,
-			IIO_EVENT_CODE_IN_LOW_THRESH(2),
-			st->last_timestamp);
-	if (rx & (1 << 3))
-		iio_push_event(st->indio_dev, 0,
-			IIO_EVENT_CODE_IN_HIGH_THRESH(2),
-			st->last_timestamp);
-	if (rx & (1 << 4))
-		iio_push_event(st->indio_dev, 0,
-			IIO_EVENT_CODE_IN_LOW_THRESH(1),
-			st->last_timestamp);
-	if (rx & (1 << 5))
-		iio_push_event(st->indio_dev, 0,
-			IIO_EVENT_CODE_IN_HIGH_THRESH(1),
-			st->last_timestamp);
-	if (rx & (1 << 6))
-		iio_push_event(st->indio_dev, 0,
-			IIO_EVENT_CODE_IN_LOW_THRESH(0),
-			st->last_timestamp);
-	if (rx & (1 << 7))
-		iio_push_event(st->indio_dev, 0,
-			IIO_EVENT_CODE_IN_HIGH_THRESH(0),
-			st->last_timestamp);
-	enable_irq(st->client->irq);
+	mask = rx;
+	for_each_set_bit(loc, &mask, 8)
+		iio_push_event(indio_dev, 0, max1363_event_codes[loc],
+			       timestamp);
 	i2c_master_send(st->client, tx, 2);
+
+	return IRQ_HANDLED;
 }
 
-static ssize_t max1363_read_interrupt_config(struct device *dev,
-					struct device_attribute *attr,
-					char *buf)
+static int max1363_read_event_config(struct iio_dev *indio_dev,
+				     int event_code)
 {
-	struct iio_dev *dev_info = dev_get_drvdata(dev);
-	struct max1363_state *st = iio_dev_get_devdata(dev_info);
-	struct iio_event_attr *this_attr = to_iio_event_attr(attr);
-	int val;
+	struct max1363_state *st = iio_priv(indio_dev);
 
-	mutex_lock(&dev_info->mlock);
-	if (this_attr->mask & 0x8)
-		val = (1 << (this_attr->mask & 0x7)) & st->mask_low;
+	int val;
+	int number = IIO_EVENT_CODE_EXTRACT_NUM(event_code);
+	mutex_lock(&indio_dev->mlock);
+	if (IIO_EVENT_CODE_EXTRACT_DIR(event_code) == IIO_EV_DIR_FALLING)
+		val = (1 << number) & st->mask_low;
 	else
-		val = (1 << this_attr->mask) & st->mask_high;
-	mutex_unlock(&dev_info->mlock);
+		val = (1 << number) & st->mask_high;
+	mutex_unlock(&indio_dev->mlock);
 
-	return sprintf(buf, "%d\n", !!val);
+	return val;
 }
 
 static int max1363_monitor_mode_update(struct max1363_state *st, int enabled)
@@ -1428,6 +749,7 @@
  * To keep this manageable we always use one of 3 scan modes.
  * Scan 0...3, 0-1,2-3 and 1-0,3-2
  */
+
 static inline int __max1363_check_event_mask(int thismask, int checkmask)
 {
 	int ret = 0;
@@ -1448,206 +770,54 @@
 	return ret;
 }
 
-static ssize_t max1363_write_interrupt_config(struct device *dev,
-					struct device_attribute *attr,
-					const char *buf,
-					size_t len)
+static int max1363_write_event_config(struct iio_dev *indio_dev,
+				      int event_code,
+				      int state)
 {
-	struct iio_dev *dev_info = dev_get_drvdata(dev);
-	struct max1363_state *st = iio_dev_get_devdata(dev_info);
-	struct iio_event_attr *this_attr = to_iio_event_attr(attr);
-	unsigned long val;
-	int ret;
+	int ret = 0;
+	struct max1363_state *st = iio_priv(indio_dev);
 	u16 unifiedmask;
-	ret = strict_strtoul(buf, 10, &val);
-	if (ret)
-		return -EINVAL;
-	mutex_lock(&st->indio_dev->mlock);
+	int number = IIO_EVENT_CODE_EXTRACT_NUM(event_code);
+
+	mutex_lock(&indio_dev->mlock);
 	unifiedmask = st->mask_low | st->mask_high;
-	if (this_attr->mask & 0x08) {
-		/* If we are disabling no need to test */
-		if (val == 0)
-			st->mask_low &= ~(1 << (this_attr->mask & 0x7));
+	if (IIO_EVENT_CODE_EXTRACT_DIR(event_code) == IIO_EV_DIR_FALLING) {
+
+		if (state == 0)
+			st->mask_low &= ~(1 << number);
 		else {
-			ret = __max1363_check_event_mask(this_attr->mask & 0x7,
-							unifiedmask);
+			ret = __max1363_check_event_mask((1 << number),
+							 unifiedmask);
 			if (ret)
 				goto error_ret;
-			st->mask_low |= (1 << (this_attr->mask & 0x7));
+			st->mask_low |= (1 << number);
 		}
 	} else {
-		if (val == 0)
-			st->mask_high &= ~(1 << (this_attr->mask));
+		if (state == 0)
+			st->mask_high &= ~(1 << number);
 		else {
-			ret = __max1363_check_event_mask(this_attr->mask,
-							unifiedmask);
+			ret = __max1363_check_event_mask((1 << number),
+							 unifiedmask);
 			if (ret)
 				goto error_ret;
-			st->mask_high |= (1 << this_attr->mask);
+			st->mask_high |= (1 << number);
 		}
 	}
-	if (st->monitor_on && !st->mask_high && !st->mask_low)
-		iio_remove_event_from_list(this_attr->listel,
-					&dev_info->interrupts[0]->ev_list);
-	if (!st->monitor_on && val)
-		iio_add_event_to_list(this_attr->listel,
-				&dev_info->interrupts[0]->ev_list);
 
 	max1363_monitor_mode_update(st, !!(st->mask_high | st->mask_low));
 error_ret:
-	mutex_unlock(&st->indio_dev->mlock);
+	mutex_unlock(&indio_dev->mlock);
 
-	return len;
+	return ret;
 }
 
-IIO_EVENT_SH(max1363_thresh, max1363_int_th);
-
-#define MAX1363_HIGH_THRESH(a) a
-#define MAX1363_LOW_THRESH(a) (a | 0x8)
-
-IIO_EVENT_ATTR_SH(in0_thresh_high_en,
-		iio_event_max1363_thresh,
-		max1363_read_interrupt_config,
-		max1363_write_interrupt_config,
-		MAX1363_HIGH_THRESH(0));
-
-IIO_EVENT_ATTR_SH(in0_thresh_low_en,
-		iio_event_max1363_thresh,
-		max1363_read_interrupt_config,
-		max1363_write_interrupt_config,
-		MAX1363_LOW_THRESH(0));
-
-IIO_EVENT_ATTR_SH(in1_thresh_high_en,
-		iio_event_max1363_thresh,
-		max1363_read_interrupt_config,
-		max1363_write_interrupt_config,
-		MAX1363_HIGH_THRESH(1));
-
-IIO_EVENT_ATTR_SH(in1_thresh_low_en,
-		iio_event_max1363_thresh,
-		max1363_read_interrupt_config,
-		max1363_write_interrupt_config,
-		MAX1363_LOW_THRESH(1));
-
-IIO_EVENT_ATTR_SH(in2_thresh_high_en,
-		iio_event_max1363_thresh,
-		max1363_read_interrupt_config,
-		max1363_write_interrupt_config,
-		MAX1363_HIGH_THRESH(2));
-
-IIO_EVENT_ATTR_SH(in2_thresh_low_en,
-		iio_event_max1363_thresh,
-		max1363_read_interrupt_config,
-		max1363_write_interrupt_config,
-		MAX1363_LOW_THRESH(2));
-
-IIO_EVENT_ATTR_SH(in3_thresh_high_en,
-		iio_event_max1363_thresh,
-		max1363_read_interrupt_config,
-		max1363_write_interrupt_config,
-		MAX1363_HIGH_THRESH(3));
-
-IIO_EVENT_ATTR_SH(in3_thresh_low_en,
-		iio_event_max1363_thresh,
-		max1363_read_interrupt_config,
-		max1363_write_interrupt_config,
-		MAX1363_LOW_THRESH(3));
-
-IIO_EVENT_ATTR_NAMED_SH(in0min1_thresh_high_en,
-			in0-in1_thresh_high_en,
-			iio_event_max1363_thresh,
-			max1363_read_interrupt_config,
-			max1363_write_interrupt_config,
-			MAX1363_HIGH_THRESH(4));
-
-IIO_EVENT_ATTR_NAMED_SH(in0min1_thresh_low_en,
-			in0-in1_thresh_low_en,
-			iio_event_max1363_thresh,
-			max1363_read_interrupt_config,
-			max1363_write_interrupt_config,
-			MAX1363_LOW_THRESH(4));
-
-IIO_EVENT_ATTR_NAMED_SH(in3min2_thresh_high_en,
-			in3-in2_thresh_high_en,
-			iio_event_max1363_thresh,
-			max1363_read_interrupt_config,
-			max1363_write_interrupt_config,
-			MAX1363_HIGH_THRESH(5));
-
-IIO_EVENT_ATTR_NAMED_SH(in3min2_thresh_low_en,
-			in3-in2_thresh_low_en,
-			iio_event_max1363_thresh,
-			max1363_read_interrupt_config,
-			max1363_write_interrupt_config,
-			MAX1363_LOW_THRESH(5));
-
-IIO_EVENT_ATTR_NAMED_SH(in1min0_thresh_high_en,
-			in1-in0_thresh_high_en,
-			iio_event_max1363_thresh,
-			max1363_read_interrupt_config,
-			max1363_write_interrupt_config,
-			MAX1363_HIGH_THRESH(6));
-
-IIO_EVENT_ATTR_NAMED_SH(in1min0_thresh_low_en,
-			in1-in0_thresh_low_en,
-			iio_event_max1363_thresh,
-			max1363_read_interrupt_config,
-			max1363_write_interrupt_config,
-			MAX1363_LOW_THRESH(6));
-
-IIO_EVENT_ATTR_NAMED_SH(in2min3_thresh_high_en,
-			in2-in3_thresh_high_en,
-			iio_event_max1363_thresh,
-			max1363_read_interrupt_config,
-			max1363_write_interrupt_config,
-			MAX1363_HIGH_THRESH(7));
-
-IIO_EVENT_ATTR_NAMED_SH(in2min3_thresh_low_en,
-			in2-in3_thresh_low_en,
-			iio_event_max1363_thresh,
-			max1363_read_interrupt_config,
-			max1363_write_interrupt_config,
-			MAX1363_LOW_THRESH(7));
-
 /*
  * As with scan_elements, only certain sets of these can
  * be combined.
  */
 static struct attribute *max1363_event_attributes[] = {
-	&iio_dev_attr_in0_thresh_high_value.dev_attr.attr,
-	&iio_dev_attr_in0_thresh_low_value.dev_attr.attr,
-	&iio_dev_attr_in1_thresh_high_value.dev_attr.attr,
-	&iio_dev_attr_in1_thresh_low_value.dev_attr.attr,
-	&iio_dev_attr_in2_thresh_high_value.dev_attr.attr,
-	&iio_dev_attr_in2_thresh_low_value.dev_attr.attr,
-	&iio_dev_attr_in3_thresh_high_value.dev_attr.attr,
-	&iio_dev_attr_in3_thresh_low_value.dev_attr.attr,
-	&iio_dev_attr_in0min1_thresh_high_value.dev_attr.attr,
-	&iio_dev_attr_in0min1_thresh_low_value.dev_attr.attr,
-	&iio_dev_attr_in2min3_thresh_high_value.dev_attr.attr,
-	&iio_dev_attr_in2min3_thresh_low_value.dev_attr.attr,
-	&iio_dev_attr_in1min0_thresh_high_value.dev_attr.attr,
-	&iio_dev_attr_in1min0_thresh_low_value.dev_attr.attr,
-	&iio_dev_attr_in3min2_thresh_high_value.dev_attr.attr,
-	&iio_dev_attr_in3min2_thresh_low_value.dev_attr.attr,
 	&iio_dev_attr_sampling_frequency.dev_attr.attr,
 	&iio_const_attr_sampling_frequency_available.dev_attr.attr,
-	&iio_event_attr_in0_thresh_high_en.dev_attr.attr,
-	&iio_event_attr_in0_thresh_low_en.dev_attr.attr,
-	&iio_event_attr_in1_thresh_high_en.dev_attr.attr,
-	&iio_event_attr_in1_thresh_low_en.dev_attr.attr,
-	&iio_event_attr_in2_thresh_high_en.dev_attr.attr,
-	&iio_event_attr_in2_thresh_low_en.dev_attr.attr,
-	&iio_event_attr_in3_thresh_high_en.dev_attr.attr,
-	&iio_event_attr_in3_thresh_low_en.dev_attr.attr,
-	&iio_event_attr_in0min1_thresh_high_en.dev_attr.attr,
-	&iio_event_attr_in0min1_thresh_low_en.dev_attr.attr,
-	&iio_event_attr_in3min2_thresh_high_en.dev_attr.attr,
-	&iio_event_attr_in3min2_thresh_low_en.dev_attr.attr,
-	&iio_event_attr_in1min0_thresh_high_en.dev_attr.attr,
-	&iio_event_attr_in1min0_thresh_low_en.dev_attr.attr,
-	&iio_event_attr_in2min3_thresh_high_en.dev_attr.attr,
-	&iio_event_attr_in2min3_thresh_low_en.dev_attr.attr,
 	NULL,
 };
 
@@ -1655,6 +825,411 @@
 	.attrs = max1363_event_attributes,
 };
 
+#define MAX1363_EVENT_FUNCS						\
+
+
+static const struct iio_info max1238_info = {
+	.read_raw = &max1363_read_raw,
+	.driver_module = THIS_MODULE,
+};
+
+static const struct iio_info max1363_info = {
+	.read_event_value = &max1363_read_thresh,
+	.write_event_value = &max1363_write_thresh,
+	.read_event_config = &max1363_read_event_config,
+	.write_event_config = &max1363_write_event_config,
+	.read_raw = &max1363_read_raw,
+	.driver_module = THIS_MODULE,
+	.num_interrupt_lines = 1,
+	.event_attrs = &max1363_event_attribute_group,
+};
+
+/* max1363 and max1368 tested - rest from data sheet */
+static const struct max1363_chip_info max1363_chip_info_tbl[] = {
+	[max1361] = {
+		.bits = 10,
+		.int_vref_mv = 2048,
+		.mode_list = max1363_mode_list,
+		.num_modes = ARRAY_SIZE(max1363_mode_list),
+		.default_mode = s0to3,
+		.channels = max1361_channels,
+		.num_channels = ARRAY_SIZE(max1361_channels),
+		.info = &max1363_info,
+	},
+	[max1362] = {
+		.bits = 10,
+		.int_vref_mv = 4096,
+		.mode_list = max1363_mode_list,
+		.num_modes = ARRAY_SIZE(max1363_mode_list),
+		.default_mode = s0to3,
+		.channels = max1361_channels,
+		.num_channels = ARRAY_SIZE(max1361_channels),
+		.info = &max1363_info,
+	},
+	[max1363] = {
+		.bits = 12,
+		.int_vref_mv = 2048,
+		.mode_list = max1363_mode_list,
+		.num_modes = ARRAY_SIZE(max1363_mode_list),
+		.default_mode = s0to3,
+		.channels = max1363_channels,
+		.num_channels = ARRAY_SIZE(max1363_channels),
+		.info = &max1363_info,
+	},
+	[max1364] = {
+		.bits = 12,
+		.int_vref_mv = 4096,
+		.mode_list = max1363_mode_list,
+		.num_modes = ARRAY_SIZE(max1363_mode_list),
+		.default_mode = s0to3,
+		.channels = max1363_channels,
+		.num_channels = ARRAY_SIZE(max1363_channels),
+		.info = &max1363_info,
+	},
+	[max1036] = {
+		.bits = 8,
+		.int_vref_mv = 4096,
+		.mode_list = max1236_mode_list,
+		.num_modes = ARRAY_SIZE(max1236_mode_list),
+		.default_mode = s0to3,
+		.info = &max1238_info,
+		.channels = max1036_channels,
+		.num_channels = ARRAY_SIZE(max1036_channels),
+	},
+	[max1037] = {
+		.bits = 8,
+		.int_vref_mv = 2048,
+		.mode_list = max1236_mode_list,
+		.num_modes = ARRAY_SIZE(max1236_mode_list),
+		.default_mode = s0to3,
+		.info = &max1238_info,
+		.channels = max1036_channels,
+		.num_channels = ARRAY_SIZE(max1036_channels),
+	},
+	[max1038] = {
+		.bits = 8,
+		.int_vref_mv = 4096,
+		.mode_list = max1238_mode_list,
+		.num_modes = ARRAY_SIZE(max1238_mode_list),
+		.default_mode = s0to11,
+		.info = &max1238_info,
+		.channels = max1038_channels,
+		.num_channels = ARRAY_SIZE(max1038_channels),
+	},
+	[max1039] = {
+		.bits = 8,
+		.int_vref_mv = 2048,
+		.mode_list = max1238_mode_list,
+		.num_modes = ARRAY_SIZE(max1238_mode_list),
+		.default_mode = s0to11,
+		.info = &max1238_info,
+		.channels = max1038_channels,
+		.num_channels = ARRAY_SIZE(max1038_channels),
+	},
+	[max1136] = {
+		.bits = 10,
+		.int_vref_mv = 4096,
+		.mode_list = max1236_mode_list,
+		.num_modes = ARRAY_SIZE(max1236_mode_list),
+		.default_mode = s0to3,
+		.info = &max1238_info,
+		.channels = max1136_channels,
+		.num_channels = ARRAY_SIZE(max1136_channels),
+	},
+	[max1137] = {
+		.bits = 10,
+		.int_vref_mv = 2048,
+		.mode_list = max1236_mode_list,
+		.num_modes = ARRAY_SIZE(max1236_mode_list),
+		.default_mode = s0to3,
+		.info = &max1238_info,
+		.channels = max1136_channels,
+		.num_channels = ARRAY_SIZE(max1136_channels),
+	},
+	[max1138] = {
+		.bits = 10,
+		.int_vref_mv = 4096,
+		.mode_list = max1238_mode_list,
+		.num_modes = ARRAY_SIZE(max1238_mode_list),
+		.default_mode = s0to11,
+		.info = &max1238_info,
+		.channels = max1138_channels,
+		.num_channels = ARRAY_SIZE(max1138_channels),
+	},
+	[max1139] = {
+		.bits = 10,
+		.int_vref_mv = 2048,
+		.mode_list = max1238_mode_list,
+		.num_modes = ARRAY_SIZE(max1238_mode_list),
+		.default_mode = s0to11,
+		.info = &max1238_info,
+		.channels = max1138_channels,
+		.num_channels = ARRAY_SIZE(max1138_channels),
+	},
+	[max1236] = {
+		.bits = 12,
+		.int_vref_mv = 4096,
+		.mode_list = max1236_mode_list,
+		.num_modes = ARRAY_SIZE(max1236_mode_list),
+		.default_mode = s0to3,
+		.info = &max1238_info,
+		.channels = max1236_channels,
+		.num_channels = ARRAY_SIZE(max1236_channels),
+	},
+	[max1237] = {
+		.bits = 12,
+		.int_vref_mv = 2048,
+		.mode_list = max1236_mode_list,
+		.num_modes = ARRAY_SIZE(max1236_mode_list),
+		.default_mode = s0to3,
+		.info = &max1238_info,
+		.channels = max1236_channels,
+		.num_channels = ARRAY_SIZE(max1236_channels),
+	},
+	[max1238] = {
+		.bits = 12,
+		.int_vref_mv = 4096,
+		.mode_list = max1238_mode_list,
+		.num_modes = ARRAY_SIZE(max1238_mode_list),
+		.default_mode = s0to11,
+		.info = &max1238_info,
+		.channels = max1238_channels,
+		.num_channels = ARRAY_SIZE(max1238_channels),
+	},
+	[max1239] = {
+		.bits = 12,
+		.int_vref_mv = 2048,
+		.mode_list = max1238_mode_list,
+		.num_modes = ARRAY_SIZE(max1238_mode_list),
+		.default_mode = s0to11,
+		.info = &max1238_info,
+		.channels = max1238_channels,
+		.num_channels = ARRAY_SIZE(max1238_channels),
+	},
+	[max11600] = {
+		.bits = 8,
+		.int_vref_mv = 4096,
+		.mode_list = max11607_mode_list,
+		.num_modes = ARRAY_SIZE(max11607_mode_list),
+		.default_mode = s0to3,
+		.info = &max1238_info,
+		.channels = max1036_channels,
+		.num_channels = ARRAY_SIZE(max1036_channels),
+	},
+	[max11601] = {
+		.bits = 8,
+		.int_vref_mv = 2048,
+		.mode_list = max11607_mode_list,
+		.num_modes = ARRAY_SIZE(max11607_mode_list),
+		.default_mode = s0to3,
+		.info = &max1238_info,
+		.channels = max1036_channels,
+		.num_channels = ARRAY_SIZE(max1036_channels),
+	},
+	[max11602] = {
+		.bits = 8,
+		.int_vref_mv = 4096,
+		.mode_list = max11608_mode_list,
+		.num_modes = ARRAY_SIZE(max11608_mode_list),
+		.default_mode = s0to7,
+		.info = &max1238_info,
+		.channels = max11602_channels,
+		.num_channels = ARRAY_SIZE(max11602_channels),
+	},
+	[max11603] = {
+		.bits = 8,
+		.int_vref_mv = 2048,
+		.mode_list = max11608_mode_list,
+		.num_modes = ARRAY_SIZE(max11608_mode_list),
+		.default_mode = s0to7,
+		.info = &max1238_info,
+		.channels = max11602_channels,
+		.num_channels = ARRAY_SIZE(max11602_channels),
+	},
+	[max11604] = {
+		.bits = 8,
+		.int_vref_mv = 4098,
+		.mode_list = max1238_mode_list,
+		.num_modes = ARRAY_SIZE(max1238_mode_list),
+		.default_mode = s0to11,
+		.info = &max1238_info,
+		.channels = max1238_channels,
+		.num_channels = ARRAY_SIZE(max1238_channels),
+	},
+	[max11605] = {
+		.bits = 8,
+		.int_vref_mv = 2048,
+		.mode_list = max1238_mode_list,
+		.num_modes = ARRAY_SIZE(max1238_mode_list),
+		.default_mode = s0to11,
+		.info = &max1238_info,
+		.channels = max1238_channels,
+		.num_channels = ARRAY_SIZE(max1238_channels),
+	},
+	[max11606] = {
+		.bits = 10,
+		.int_vref_mv = 4096,
+		.mode_list = max11607_mode_list,
+		.num_modes = ARRAY_SIZE(max11607_mode_list),
+		.default_mode = s0to3,
+		.info = &max1238_info,
+		.channels = max1136_channels,
+		.num_channels = ARRAY_SIZE(max1136_channels),
+	},
+	[max11607] = {
+		.bits = 10,
+		.int_vref_mv = 2048,
+		.mode_list = max11607_mode_list,
+		.num_modes = ARRAY_SIZE(max11607_mode_list),
+		.default_mode = s0to3,
+		.info = &max1238_info,
+		.channels = max1136_channels,
+		.num_channels = ARRAY_SIZE(max1136_channels),
+	},
+	[max11608] = {
+		.bits = 10,
+		.int_vref_mv = 4096,
+		.mode_list = max11608_mode_list,
+		.num_modes = ARRAY_SIZE(max11608_mode_list),
+		.default_mode = s0to7,
+		.info = &max1238_info,
+		.channels = max11608_channels,
+		.num_channels = ARRAY_SIZE(max11608_channels),
+	},
+	[max11609] = {
+		.bits = 10,
+		.int_vref_mv = 2048,
+		.mode_list = max11608_mode_list,
+		.num_modes = ARRAY_SIZE(max11608_mode_list),
+		.default_mode = s0to7,
+		.info = &max1238_info,
+		.channels = max11608_channels,
+		.num_channels = ARRAY_SIZE(max11608_channels),
+	},
+	[max11610] = {
+		.bits = 10,
+		.int_vref_mv = 4098,
+		.mode_list = max1238_mode_list,
+		.num_modes = ARRAY_SIZE(max1238_mode_list),
+		.default_mode = s0to11,
+		.info = &max1238_info,
+		.channels = max1238_channels,
+		.num_channels = ARRAY_SIZE(max1238_channels),
+	},
+	[max11611] = {
+		.bits = 10,
+		.int_vref_mv = 2048,
+		.mode_list = max1238_mode_list,
+		.num_modes = ARRAY_SIZE(max1238_mode_list),
+		.default_mode = s0to11,
+		.info = &max1238_info,
+		.channels = max1238_channels,
+		.num_channels = ARRAY_SIZE(max1238_channels),
+	},
+	[max11612] = {
+		.bits = 12,
+		.int_vref_mv = 4096,
+		.mode_list = max11607_mode_list,
+		.num_modes = ARRAY_SIZE(max11607_mode_list),
+		.default_mode = s0to3,
+		.info = &max1238_info,
+		.channels = max1363_channels,
+		.num_channels = ARRAY_SIZE(max1363_channels),
+	},
+	[max11613] = {
+		.bits = 12,
+		.int_vref_mv = 2048,
+		.mode_list = max11607_mode_list,
+		.num_modes = ARRAY_SIZE(max11607_mode_list),
+		.default_mode = s0to3,
+		.info = &max1238_info,
+		.channels = max1363_channels,
+		.num_channels = ARRAY_SIZE(max1363_channels),
+	},
+	[max11614] = {
+		.bits = 12,
+		.int_vref_mv = 4096,
+		.mode_list = max11608_mode_list,
+		.num_modes = ARRAY_SIZE(max11608_mode_list),
+		.default_mode = s0to7,
+		.info = &max1238_info,
+		.channels = max11614_channels,
+		.num_channels = ARRAY_SIZE(max11614_channels),
+	},
+	[max11615] = {
+		.bits = 12,
+		.int_vref_mv = 2048,
+		.mode_list = max11608_mode_list,
+		.num_modes = ARRAY_SIZE(max11608_mode_list),
+		.default_mode = s0to7,
+		.info = &max1238_info,
+		.channels = max11614_channels,
+		.num_channels = ARRAY_SIZE(max11614_channels),
+	},
+	[max11616] = {
+		.bits = 12,
+		.int_vref_mv = 4098,
+		.mode_list = max1238_mode_list,
+		.num_modes = ARRAY_SIZE(max1238_mode_list),
+		.default_mode = s0to11,
+		.info = &max1238_info,
+		.channels = max1238_channels,
+		.num_channels = ARRAY_SIZE(max1238_channels),
+	},
+	[max11617] = {
+		.bits = 12,
+		.int_vref_mv = 2048,
+		.mode_list = max1238_mode_list,
+		.num_modes = ARRAY_SIZE(max1238_mode_list),
+		.default_mode = s0to11,
+		.info = &max1238_info,
+		.channels = max1238_channels,
+		.num_channels = ARRAY_SIZE(max1238_channels),
+	},
+	[max11644] = {
+		.bits = 12,
+		.int_vref_mv = 2048,
+		.mode_list = max11644_mode_list,
+		.num_modes = ARRAY_SIZE(max11644_mode_list),
+		.default_mode = s0to1,
+		.info = &max1238_info,
+		.channels = max11644_channels,
+		.num_channels = ARRAY_SIZE(max11644_channels),
+	},
+	[max11645] = {
+		.bits = 12,
+		.int_vref_mv = 4096,
+		.mode_list = max11644_mode_list,
+		.num_modes = ARRAY_SIZE(max11644_mode_list),
+		.default_mode = s0to1,
+		.info = &max1238_info,
+		.channels = max11644_channels,
+		.num_channels = ARRAY_SIZE(max11644_channels),
+	},
+	[max11646] = {
+		.bits = 10,
+		.int_vref_mv = 2048,
+		.mode_list = max11644_mode_list,
+		.num_modes = ARRAY_SIZE(max11644_mode_list),
+		.default_mode = s0to1,
+		.info = &max1238_info,
+		.channels = max11646_channels,
+		.num_channels = ARRAY_SIZE(max11646_channels),
+	},
+	[max11647] = {
+		.bits = 10,
+		.int_vref_mv = 4096,
+		.mode_list = max11644_mode_list,
+		.num_modes = ARRAY_SIZE(max11644_mode_list),
+		.default_mode = s0to1,
+		.info = &max1238_info,
+		.channels = max11646_channels,
+		.num_channels = ARRAY_SIZE(max11646_channels),
+	},
+};
+
+
+
 static int max1363_initial_setup(struct max1363_state *st)
 {
 	st->setupbyte = MAX1363_SETUP_AIN3_IS_AIN3_REF_IS_VDD
@@ -1675,126 +1250,116 @@
 				   const struct i2c_device_id *id)
 {
 	int ret, i, regdone = 0;
-	struct max1363_state *st = kzalloc(sizeof(*st), GFP_KERNEL);
-	if (st == NULL) {
-		ret = -ENOMEM;
-		goto error_ret;
-	}
-
-	/* this is only used for device removal purposes */
-	i2c_set_clientdata(client, st);
-
-	atomic_set(&st->protect_ring, 0);
+	struct max1363_state *st;
+	struct iio_dev *indio_dev;
+	struct regulator *reg;
 
-	st->chip_info = &max1363_chip_info_tbl[id->driver_data];
-	st->reg = regulator_get(&client->dev, "vcc");
-	if (!IS_ERR(st->reg)) {
-		ret = regulator_enable(st->reg);
+	reg = regulator_get(&client->dev, "vcc");
+	if (!IS_ERR(reg)) {
+		ret = regulator_enable(reg);
 		if (ret)
 			goto error_put_reg;
 	}
-	st->client = client;
 
-	st->indio_dev = iio_allocate_device();
-	if (st->indio_dev == NULL) {
+	indio_dev = iio_allocate_device(sizeof(struct max1363_state));
+	if (indio_dev == NULL) {
 		ret = -ENOMEM;
 		goto error_disable_reg;
 	}
+	st = iio_priv(indio_dev);
+	st->reg = reg;
+	/* this is only used for device removal purposes */
+	i2c_set_clientdata(client, indio_dev);
 
-	st->indio_dev->available_scan_masks
-		= kzalloc(sizeof(*st->indio_dev->available_scan_masks)*
+	st->chip_info = &max1363_chip_info_tbl[id->driver_data];
+	st->client = client;
+
+	indio_dev->available_scan_masks
+		= kzalloc(sizeof(*indio_dev->available_scan_masks)*
 			  (st->chip_info->num_modes + 1), GFP_KERNEL);
-	if (!st->indio_dev->available_scan_masks) {
+	if (!indio_dev->available_scan_masks) {
 		ret = -ENOMEM;
 		goto error_free_device;
 	}
 
 	for (i = 0; i < st->chip_info->num_modes; i++)
-		st->indio_dev->available_scan_masks[i] =
+		indio_dev->available_scan_masks[i] =
 			max1363_mode_table[st->chip_info->mode_list[i]]
 			.modemask;
 	/* Estabilish that the iio_dev is a child of the i2c device */
-	st->indio_dev->dev.parent = &client->dev;
-	st->indio_dev->attrs = st->chip_info->dev_attrs;
-
-	/* Todo: this shouldn't be here. */
-	st->indio_dev->dev_data = (void *)(st);
-	st->indio_dev->driver_module = THIS_MODULE;
-	st->indio_dev->modes = INDIO_DIRECT_MODE;
-	if (st->chip_info->monitor_mode && client->irq) {
-		st->indio_dev->num_interrupt_lines = 1;
-		st->indio_dev->event_attrs
-			= &max1363_event_attribute_group;
-	}
+	indio_dev->dev.parent = &client->dev;
+	indio_dev->name = id->name;
 
+	indio_dev->info = st->chip_info->info;
+	indio_dev->modes = INDIO_DIRECT_MODE;
 	ret = max1363_initial_setup(st);
-	if (ret)
+	if (ret < 0)
 		goto error_free_available_scan_masks;
 
-	ret = max1363_register_ring_funcs_and_init(st->indio_dev);
+	ret = max1363_register_ring_funcs_and_init(indio_dev);
 	if (ret)
 		goto error_free_available_scan_masks;
 
-	ret = iio_device_register(st->indio_dev);
+	ret = iio_device_register(indio_dev);
 	if (ret)
 		goto error_cleanup_ring;
 	regdone = 1;
-	ret = iio_ring_buffer_register(st->indio_dev->ring, 0);
+	ret = iio_ring_buffer_register_ex(indio_dev->ring, 0,
+					  st->chip_info->channels,
+					  st->chip_info->num_channels);
 	if (ret)
 		goto error_cleanup_ring;
 
-	if (st->chip_info->monitor_mode && client->irq) {
-		ret = iio_register_interrupt_line(client->irq,
-						st->indio_dev,
-						0,
-						IRQF_TRIGGER_RISING,
-						client->name);
+	if (client->irq) {
+		ret = request_threaded_irq(st->client->irq,
+					   NULL,
+					   &max1363_event_handler,
+					   IRQF_TRIGGER_RISING | IRQF_ONESHOT,
+					   "max1363_event",
+					   indio_dev);
+
 		if (ret)
 			goto error_uninit_ring;
-
-		INIT_WORK(&st->thresh_work, max1363_thresh_handler_bh);
 	}
 
 	return 0;
 error_uninit_ring:
-	iio_ring_buffer_unregister(st->indio_dev->ring);
+	iio_ring_buffer_unregister(indio_dev->ring);
 error_cleanup_ring:
-	max1363_ring_cleanup(st->indio_dev);
+	max1363_ring_cleanup(indio_dev);
 error_free_available_scan_masks:
-	kfree(st->indio_dev->available_scan_masks);
+	kfree(indio_dev->available_scan_masks);
 error_free_device:
 	if (!regdone)
-		iio_free_device(st->indio_dev);
+		iio_free_device(indio_dev);
 	else
-		iio_device_unregister(st->indio_dev);
+		iio_device_unregister(indio_dev);
 error_disable_reg:
 	if (!IS_ERR(st->reg))
 		regulator_disable(st->reg);
 error_put_reg:
 	if (!IS_ERR(st->reg))
 		regulator_put(st->reg);
-	kfree(st);
 
-error_ret:
 	return ret;
 }
 
 static int max1363_remove(struct i2c_client *client)
 {
-	struct max1363_state *st = i2c_get_clientdata(client);
-	struct iio_dev *indio_dev = st->indio_dev;
+	struct iio_dev *indio_dev = i2c_get_clientdata(client);
+	struct max1363_state *st = iio_priv(indio_dev);
+	struct regulator *reg = st->reg;
 
-	if (st->chip_info->monitor_mode && client->irq)
-		iio_unregister_interrupt_line(st->indio_dev, 0);
+	if (client->irq)
+		free_irq(st->client->irq, indio_dev);
 	iio_ring_buffer_unregister(indio_dev->ring);
 	max1363_ring_cleanup(indio_dev);
-	kfree(st->indio_dev->available_scan_masks);
-	iio_device_unregister(indio_dev);
-	if (!IS_ERR(st->reg)) {
-		regulator_disable(st->reg);
-		regulator_put(st->reg);
+	kfree(indio_dev->available_scan_masks);
+	if (!IS_ERR(reg)) {
+		regulator_disable(reg);
+		regulator_put(reg);
 	}
-	kfree(st);
+	iio_device_unregister(indio_dev);
 
 	return 0;
 }
diff -druN linux-2.6.39-libre/drivers/staging/iio/adc/max1363.h linux-3.0-rc7-libre/drivers/staging/iio/adc/max1363.h
--- linux-2.6.39-libre/drivers/staging/iio/adc/max1363.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/iio/adc/max1363.h	2011-07-11 19:51:52.000000000 -0400
@@ -67,70 +67,6 @@
 	long		modemask;
 };
 
-#define MAX1363_MODE_SINGLE(_num, _mask) {				\
-		.conf = MAX1363_CHANNEL_SEL(_num)			\
-			| MAX1363_CONFIG_SCAN_SINGLE_1			\
-			| MAX1363_CONFIG_SE,				\
-			.modemask = _mask,				\
-			}
-
-#define MAX1363_MODE_SCAN_TO_CHANNEL(_num, _mask) {			\
-		.conf = MAX1363_CHANNEL_SEL(_num)			\
-			| MAX1363_CONFIG_SCAN_TO_CS			\
-			| MAX1363_CONFIG_SE,				\
-			.modemask = _mask,				\
-			}
-
-
-/* note not available for max1363 hence naming */
-#define MAX1236_MODE_SCAN_MID_TO_CHANNEL(_mid, _num, _mask) {		\
-		.conf = MAX1363_CHANNEL_SEL(_num)			\
-			| MAX1236_SCAN_MID_TO_CHANNEL			\
-			| MAX1363_CONFIG_SE,				\
-			.modemask = _mask				\
-}
-
-#define MAX1363_MODE_DIFF_SINGLE(_nump, _numm, _mask) {			\
-		.conf = MAX1363_CHANNEL_SEL(_nump)			\
-			| MAX1363_CONFIG_SCAN_SINGLE_1			\
-			| MAX1363_CONFIG_DE,				\
-			.modemask = _mask				\
-			}
-
-/* Can't think how to automate naming so specify for now */
-#define MAX1363_MODE_DIFF_SCAN_TO_CHANNEL(_num, _numvals, _mask) { \
-		.conf = MAX1363_CHANNEL_SEL(_num)			\
-			| MAX1363_CONFIG_SCAN_TO_CS			\
-			| MAX1363_CONFIG_DE,				\
-			.modemask = _mask				\
-			}
-
-/* note only available for max1363 hence naming */
-#define MAX1236_MODE_DIFF_SCAN_MID_TO_CHANNEL(_num, _numvals, _mask) { \
-		.conf = MAX1363_CHANNEL_SEL(_num)			\
-			| MAX1236_SCAN_MID_TO_CHANNEL			\
-			| MAX1363_CONFIG_SE,				\
-			.modemask = _mask				\
-}
-
-/* This may seem an overly long winded way to do this, but at least it makes
- * clear what all the various options actually do. Alternative suggestions
- * that don't require user to have intimate knowledge of the chip welcomed.
- */
-enum max1363_channels {
-	max1363_in0, max1363_in1, max1363_in2, max1363_in3,
-	max1363_in4, max1363_in5, max1363_in6, max1363_in7,
-	max1363_in8, max1363_in9, max1363_in10, max1363_in11,
-
-	max1363_in0min1, max1363_in2min3,
-	max1363_in4min5, max1363_in6min7,
-	max1363_in8min9, max1363_in10min11,
-
-	max1363_in1min0, max1363_in3min2,
-	max1363_in5min4, max1363_in7min6,
-	max1363_in9min8, max1363_in11min10,
-};
-
 /* This must be maintained along side the max1363_mode_table in max1363_core */
 enum max1363_modes {
 	/* Single read of a single channel */
@@ -152,37 +88,34 @@
 /**
  * struct max1363_chip_info - chip specifc information
  * @name:		indentification string for chip
- * @num_inputs:		number of physical inputs on chip
  * @bits:		accuracy of the adc in bits
  * @int_vref_mv:	the internal reference voltage
- * @monitor_mode:	whether the chip supports monitor interrupts
+ * @info:		iio core function callbacks structure
  * @mode_list:		array of available scan modes
  * @num_modes:		the number of scan modes available
  * @default_mode:	the scan mode in which the chip starts up
+ * @channel:		channel specification
+ * @num_channels:	number of channels
  */
 struct max1363_chip_info {
-	u8				num_inputs;
-	u8				bits;
-	u16				int_vref_mv;
-	bool				monitor_mode;
+	const struct iio_info		*info;
+	struct iio_chan_spec *channels;
+	int num_channels;
 	const enum max1363_modes	*mode_list;
-	int				num_modes;
 	enum max1363_modes		default_mode;
-	struct attribute_group		*dev_attrs;
-	struct attribute_group		*scan_attrs;
+	u16				int_vref_mv;
+	u8				num_modes;
+	u8				bits;
 };
 
 /**
  * struct max1363_state - driver instance specific data
- * @indio_dev:		the industrial I/O device
  * @client:		i2c_client
  * @setupbyte:		cache of current device setup byte
  * @configbyte:		cache of current device config byte
  * @chip_info:		chip model specific constants, available modes etc
  * @current_mode:	the scan mode of this chip
  * @requestedmask:	a valid requested set of channels
- * @poll_work:		bottom half of polling interrupt handler
- * @protect_ring:	used to ensure only one polling bh running at a time
  * @reg:		supply regulator
  * @monitor_on:		whether monitor mode is enabled
  * @monitor_speed:	parameter corresponding to device monitor speed setting
@@ -190,20 +123,14 @@
  * @mask_low:		bitmask for enabled low thresholds
  * @thresh_high:	high threshold values
  * @thresh_low:		low threshold values
- * @last_timestamp:	timestamp of last event interrupt
- * @thresh_work:	bh work structure for event handling
  */
 struct max1363_state {
-	struct iio_dev			*indio_dev;
 	struct i2c_client		*client;
 	u8				setupbyte;
 	u8				configbyte;
 	const struct max1363_chip_info	*chip_info;
 	const struct max1363_mode	*current_mode;
 	u32				requestedmask;
-	struct work_struct		poll_work;
-	atomic_t			protect_ring;
-	struct iio_trigger		*trig;
 	struct regulator		*reg;
 
 	/* Using monitor modes and buffer at the same time is
@@ -215,8 +142,6 @@
 	/* 4x unipolar first then the fours bipolar ones */
 	s16				thresh_high[8];
 	s16				thresh_low[8];
-	s64				last_timestamp;
-	struct work_struct		thresh_work;
 };
 
 const struct max1363_mode
diff -druN linux-2.6.39-libre/drivers/staging/iio/adc/max1363_ring.c linux-3.0-rc7-libre/drivers/staging/iio/adc/max1363_ring.c
--- linux-2.6.39-libre/drivers/staging/iio/adc/max1363_ring.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/iio/adc/max1363_ring.c	2011-07-11 19:51:52.000000000 -0400
@@ -9,8 +9,6 @@
  */
 
 #include <linux/interrupt.h>
-#include <linux/gpio.h>
-#include <linux/workqueue.h>
 #include <linux/device.h>
 #include <linux/slab.h>
 #include <linux/kernel.h>
@@ -27,10 +25,9 @@
 
 #include "max1363.h"
 
-/* Todo: test this */
 int max1363_single_channel_from_ring(long mask, struct max1363_state *st)
 {
-	struct iio_ring_buffer *ring = st->indio_dev->ring;
+	struct iio_ring_buffer *ring = iio_priv_to_dev(st)->ring;
 	int count = 0, ret;
 	u8 *ring_data;
 	if (!(st->current_mode->modemask & mask)) {
@@ -38,12 +35,13 @@
 		goto error_ret;
 	}
 
-	ring_data = kmalloc(ring->access.get_bytes_per_datum(ring), GFP_KERNEL);
+	ring_data = kmalloc(ring->access->get_bytes_per_datum(ring),
+			    GFP_KERNEL);
 	if (ring_data == NULL) {
 		ret = -ENOMEM;
 		goto error_ret;
 	}
-	ret = ring->access.read_last(ring, ring_data);
+	ret = ring->access->read_last(ring, ring_data);
 	if (ret)
 		goto error_free_ring_data;
 	/* Need a count of channels prior to this one */
@@ -65,6 +63,7 @@
 	return ret;
 }
 
+
 /**
  * max1363_ring_preenable() - setup the parameters of the ring before enabling
  *
@@ -74,9 +73,9 @@
  **/
 static int max1363_ring_preenable(struct iio_dev *indio_dev)
 {
-	struct max1363_state *st = indio_dev->dev_data;
+	struct max1363_state *st = iio_priv(indio_dev);
 	struct iio_ring_buffer *ring = indio_dev->ring;
-	size_t d_size;
+	size_t d_size = 0;
 	unsigned long numvals;
 
 	/*
@@ -91,50 +90,26 @@
 	max1363_set_scan_mode(st);
 
 	numvals = hweight_long(st->current_mode->modemask);
-	if (ring->access.set_bytes_per_datum) {
+	if (ring->access->set_bytes_per_datum) {
+		if (ring->scan_timestamp)
+			d_size += sizeof(s64);
 		if (st->chip_info->bits != 8)
-			d_size = numvals*2 + sizeof(s64);
+			d_size += numvals*2;
 		else
-			d_size = numvals + sizeof(s64);
-		if (d_size % 8)
+			d_size += numvals;
+		if (ring->scan_timestamp && (d_size % 8))
 			d_size += 8 - (d_size % 8);
-		ring->access.set_bytes_per_datum(ring, d_size);
+		ring->access->set_bytes_per_datum(ring, d_size);
 	}
 
 	return 0;
 }
 
-
-/**
- * max1363_poll_func_th() - th of trigger launched polling to ring buffer
- *
- * As sampling only occurs on i2c comms occurring, leave timestamping until
- * then.  Some triggers will generate their own time stamp.  Currently
- * there is no way of notifying them when no one cares.
- **/
-static void max1363_poll_func_th(struct iio_dev *indio_dev, s64 time)
-{
-	struct max1363_state *st = indio_dev->dev_data;
-
-	schedule_work(&st->poll_work);
-
-	return;
-}
-/**
- * max1363_poll_bh_to_ring() - bh of trigger launched polling to ring buffer
- * @work_s:	the work struct through which this was scheduled
- *
- * Currently there is no option in this driver to disable the saving of
- * timestamps within the ring.
- * I think the one copy of this at a time was to avoid problems if the
- * trigger was set far too high and the reads then locked up the computer.
- **/
-static void max1363_poll_bh_to_ring(struct work_struct *work_s)
+static irqreturn_t max1363_trigger_handler(int irq, void *p)
 {
-	struct max1363_state *st = container_of(work_s, struct max1363_state,
-						  poll_work);
-	struct iio_dev *indio_dev = st->indio_dev;
-	struct iio_sw_ring_buffer *sw_ring = iio_to_sw_ring(indio_dev->ring);
+	struct iio_poll_func *pf = p;
+	struct iio_dev *indio_dev = pf->private_data;
+	struct max1363_state *st = iio_priv(indio_dev);
 	s64 time_ns;
 	__u8 *rxbuf;
 	int b_sent;
@@ -149,20 +124,16 @@
 	if (d_size % sizeof(s64))
 		d_size += sizeof(s64) - (d_size % sizeof(s64));
 
-	/* Ensure only one copy of this function running at a time */
-	if (atomic_inc_return(&st->protect_ring) > 1)
-		return;
-
 	/* Monitor mode prevents reading. Whilst not currently implemented
 	 * might as well have this test in here in the meantime as it does
 	 * no harm.
 	 */
 	if (numvals == 0)
-		return;
+		return IRQ_HANDLED;
 
 	rxbuf = kmalloc(d_size,	GFP_KERNEL);
 	if (rxbuf == NULL)
-		return;
+		return -ENOMEM;
 	if (st->chip_info->bits != 8)
 		b_sent = i2c_master_recv(st->client, rxbuf, numvals*2);
 	else
@@ -174,16 +145,23 @@
 
 	memcpy(rxbuf + d_size - sizeof(s64), &time_ns, sizeof(time_ns));
 
-	indio_dev->ring->access.store_to(&sw_ring->buf, rxbuf, time_ns);
+	indio_dev->ring->access->store_to(indio_dev->ring, rxbuf, time_ns);
 done:
+	iio_trigger_notify_done(indio_dev->trig);
 	kfree(rxbuf);
-	atomic_dec(&st->protect_ring);
+
+	return IRQ_HANDLED;
 }
 
+static const struct iio_ring_setup_ops max1363_ring_setup_ops = {
+	.postenable = &iio_triggered_ring_postenable,
+	.preenable = &max1363_ring_preenable,
+	.predisable = &iio_triggered_ring_predisable,
+};
 
 int max1363_register_ring_funcs_and_init(struct iio_dev *indio_dev)
 {
-	struct max1363_state *st = indio_dev->dev_data;
+	struct max1363_state *st = iio_priv(indio_dev);
 	int ret = 0;
 
 	indio_dev->ring = iio_sw_rb_allocate(indio_dev);
@@ -191,22 +169,27 @@
 		ret = -ENOMEM;
 		goto error_ret;
 	}
-	/* Effectively select the ring buffer implementation */
-	iio_ring_sw_register_funcs(&indio_dev->ring->access);
-	ret = iio_alloc_pollfunc(indio_dev, NULL, &max1363_poll_func_th);
-	if (ret)
+	indio_dev->pollfunc = iio_alloc_pollfunc(NULL,
+						 &max1363_trigger_handler,
+						 IRQF_ONESHOT,
+						 indio_dev,
+						 "%s_consumer%d",
+						 st->client->name,
+						 indio_dev->id);
+	if (indio_dev->pollfunc == NULL) {
+		ret = -ENOMEM;
 		goto error_deallocate_sw_rb;
-
+	}
+	/* Effectively select the ring buffer implementation */
+	indio_dev->ring->access = &ring_sw_access_funcs;
 	/* Ring buffer functions - here trigger setup related */
-	indio_dev->ring->scan_el_attrs = st->chip_info->scan_attrs;
-	indio_dev->ring->postenable = &iio_triggered_ring_postenable;
-	indio_dev->ring->preenable = &max1363_ring_preenable;
-	indio_dev->ring->predisable = &iio_triggered_ring_predisable;
-	INIT_WORK(&st->poll_work, &max1363_poll_bh_to_ring);
+	indio_dev->ring->setup_ops = &max1363_ring_setup_ops;
 
 	/* Flag that polled ring buffering is possible */
 	indio_dev->modes |= INDIO_RING_TRIGGERED;
+
 	return 0;
+
 error_deallocate_sw_rb:
 	iio_sw_rb_free(indio_dev->ring);
 error_ret:
@@ -221,6 +204,6 @@
 		iio_trigger_dettach_poll_func(indio_dev->trig,
 					      indio_dev->pollfunc);
 	}
-	kfree(indio_dev->pollfunc);
+	iio_dealloc_pollfunc(indio_dev->pollfunc);
 	iio_sw_rb_free(indio_dev->ring);
 }
diff -druN linux-2.6.39-libre/drivers/staging/iio/addac/adt7316.c linux-3.0-rc7-libre/drivers/staging/iio/addac/adt7316.c
--- linux-2.6.39-libre/drivers/staging/iio/addac/adt7316.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/iio/addac/adt7316.c	2011-07-11 19:51:52.000000000 -0400
@@ -174,10 +174,7 @@
  */
 
 struct adt7316_chip_info {
-	const char		*name;
 	struct iio_dev		*indio_dev;
-	struct work_struct	thresh_work;
-	s64			last_timestamp;
 	struct adt7316_bus	bus;
 	u16			ldac_pin;
 	u16			int_mask;	/* 0x2f */
@@ -403,7 +400,7 @@
 		return sprintf(buf, "5 - AIN4\n");
 	default:
 		return sprintf(buf, "N/A\n");
-	};
+	}
 }
 
 static ssize_t adt7316_store_ad_channel(struct device *dev,
@@ -465,7 +462,7 @@
 
 	if ((chip->id & ID_FAMILY_MASK) == ID_ADT75XX)
 		return sprintf(buf, "0 - VDD\n1 - Internal Temperature\n"
-				"2 - External Temperature or AIN2\n"
+				"2 - External Temperature or AIN1\n"
 				"3 - AIN2\n4 - AIN3\n5 - AIN4\n");
 	else
 		return sprintf(buf, "0 - VDD\n1 - Internal Temperature\n"
@@ -893,7 +890,7 @@
 			return sprintf(buf, "2 - auto at MSB DAC ABCD writing\n");
 		default: /* ADT7316_DA_EN_MODE_LDAC */
 			return sprintf(buf, "3 - manual\n");
-		};
+		}
 	}
 }
 
@@ -1205,7 +1202,7 @@
 			return sprintf(buf, "%d\n", data);
 		else
 			break;
-	};
+	}
 
 	if (data & ADT7316_T_VALUE_SIGN) {
 		/* convert supplement to positive value */
@@ -1674,18 +1671,6 @@
 
 static IIO_DEVICE_ATTR(bus_type, S_IRUGO, adt7316_show_bus_type, NULL, 0);
 
-static ssize_t adt7316_show_name(struct device *dev,
-		struct device_attribute *attr,
-		char *buf)
-{
-	struct iio_dev *dev_info = dev_get_drvdata(dev);
-	struct adt7316_chip_info *chip = dev_info->dev_data;
-
-	return sprintf(buf, "%s\n", chip->name);
-}
-
-static IIO_DEVICE_ATTR(name, S_IRUGO, adt7316_show_name, NULL, 0);
-
 static struct attribute *adt7316_attributes[] = {
 	&iio_dev_attr_all_modes.dev_attr.attr,
 	&iio_dev_attr_mode.dev_attr.attr,
@@ -1722,7 +1707,6 @@
 	&iio_dev_attr_manufactorer_id.dev_attr.attr,
 	&iio_dev_attr_device_rev.dev_attr.attr,
 	&iio_dev_attr_bus_type.dev_attr.attr,
-	&iio_dev_attr_name.dev_attr.attr,
 	NULL,
 };
 
@@ -1771,7 +1755,6 @@
 	&iio_dev_attr_manufactorer_id.dev_attr.attr,
 	&iio_dev_attr_device_rev.dev_attr.attr,
 	&iio_dev_attr_bus_type.dev_attr.attr,
-	&iio_dev_attr_name.dev_attr.attr,
 	NULL,
 };
 
@@ -1779,70 +1762,77 @@
 	.attrs = adt7516_attributes,
 };
 
-
-/*
- * temperature bound events
- */
-
-#define IIO_EVENT_CODE_ADT7316_IN_TEMP_HIGH   IIO_BUFFER_EVENT_CODE(0)
-#define IIO_EVENT_CODE_ADT7316_IN_TEMP_LOW    IIO_BUFFER_EVENT_CODE(1)
-#define IIO_EVENT_CODE_ADT7316_EX_TEMP_HIGH   IIO_BUFFER_EVENT_CODE(2)
-#define IIO_EVENT_CODE_ADT7316_EX_TEMP_LOW    IIO_BUFFER_EVENT_CODE(3)
-#define IIO_EVENT_CODE_ADT7316_EX_TEMP_FAULT  IIO_BUFFER_EVENT_CODE(4)
-#define IIO_EVENT_CODE_ADT7516_AIN1           IIO_BUFFER_EVENT_CODE(5)
-#define IIO_EVENT_CODE_ADT7516_AIN2           IIO_BUFFER_EVENT_CODE(6)
-#define IIO_EVENT_CODE_ADT7516_AIN3           IIO_BUFFER_EVENT_CODE(7)
-#define IIO_EVENT_CODE_ADT7516_AIN4           IIO_BUFFER_EVENT_CODE(8)
-#define IIO_EVENT_CODE_ADT7316_VDD            IIO_BUFFER_EVENT_CODE(9)
-
-static void adt7316_interrupt_bh(struct work_struct *work_s)
+static irqreturn_t adt7316_event_handler(int irq, void *private)
 {
-	struct adt7316_chip_info *chip =
-		container_of(work_s, struct adt7316_chip_info, thresh_work);
+	struct iio_dev *indio_dev = private;
+	struct adt7316_chip_info *chip = iio_dev_get_devdata(indio_dev);
 	u8 stat1, stat2;
-	int i, ret, count;
+	int ret;
+	s64 time;
 
 	ret = chip->bus.read(chip->bus.client, ADT7316_INT_STAT1, &stat1);
 	if (!ret) {
-		if ((chip->id & ID_FAMILY_MASK) == ID_ADT75XX)
-			count = 8;
-		else
-			count = 5;
+		if ((chip->id & ID_FAMILY_MASK) != ID_ADT75XX)
+			stat1 &= 0x1F;
 
-		for (i = 0; i < count; i++) {
-			if (stat1 & (1 << i))
-				iio_push_event(chip->indio_dev, 0,
-					IIO_EVENT_CODE_ADT7316_IN_TEMP_HIGH + i,
-					chip->last_timestamp);
+		time = iio_get_time_ns();
+		if (stat1 & (1 << 0))
+			iio_push_event(chip->indio_dev, 0,
+				       IIO_UNMOD_EVENT_CODE(IIO_TEMP, 0,
+							    IIO_EV_TYPE_THRESH,
+							    IIO_EV_DIR_RISING),
+				       time);
+		if (stat1 & (1 << 1))
+			iio_push_event(chip->indio_dev, 0,
+				       IIO_UNMOD_EVENT_CODE(IIO_TEMP, 0,
+							    IIO_EV_TYPE_THRESH,
+							    IIO_EV_DIR_FALLING),
+				       time);
+		if (stat1 & (1 << 2))
+			iio_push_event(chip->indio_dev, 0,
+				       IIO_UNMOD_EVENT_CODE(IIO_TEMP, 1,
+							    IIO_EV_TYPE_THRESH,
+							    IIO_EV_DIR_RISING),
+				       time);
+		if (stat1 & (1 << 3))
+			iio_push_event(chip->indio_dev, 0,
+				       IIO_UNMOD_EVENT_CODE(IIO_TEMP, 1,
+							    IIO_EV_TYPE_THRESH,
+							    IIO_EV_DIR_FALLING),
+				       time);
+		if (stat1 & (1 << 5))
+			iio_push_event(chip->indio_dev, 0,
+				       IIO_UNMOD_EVENT_CODE(IIO_IN, 1,
+							    IIO_EV_TYPE_THRESH,
+							    IIO_EV_DIR_EITHER),
+				       time);
+		if (stat1 & (1 << 6))
+			iio_push_event(chip->indio_dev, 0,
+				       IIO_UNMOD_EVENT_CODE(IIO_IN, 2,
+							    IIO_EV_TYPE_THRESH,
+							    IIO_EV_DIR_EITHER),
+				       time);
+		if (stat1 & (1 << 7))
+			iio_push_event(chip->indio_dev, 0,
+				       IIO_UNMOD_EVENT_CODE(IIO_IN, 3,
+							    IIO_EV_TYPE_THRESH,
+							    IIO_EV_DIR_EITHER),
+				       time);
 		}
-	}
-
 	ret = chip->bus.read(chip->bus.client, ADT7316_INT_STAT2, &stat2);
 	if (!ret) {
 		if (stat2 & ADT7316_INT_MASK2_VDD)
 			iio_push_event(chip->indio_dev, 0,
-				IIO_EVENT_CODE_ADT7316_VDD,
-				chip->last_timestamp);
+				       IIO_UNMOD_EVENT_CODE(IIO_IN,
+							    0,
+							    IIO_EV_TYPE_THRESH,
+							    IIO_EV_DIR_RISING),
+				       iio_get_time_ns());
 	}
 
-	enable_irq(chip->bus.irq);
-}
-
-static int adt7316_interrupt(struct iio_dev *dev_info,
-		int index,
-		s64 timestamp,
-		int no_test)
-{
-	struct adt7316_chip_info *chip = dev_info->dev_data;
-
-	chip->last_timestamp = timestamp;
-	schedule_work(&chip->thresh_work);
-
-	return 0;
+	return IRQ_HANDLED;
 }
 
-IIO_EVENT_SH(adt7316, &adt7316_interrupt);
-
 /*
  * Show mask of enabled interrupts in Hex.
  */
@@ -1901,9 +1891,9 @@
 }
 static inline ssize_t adt7316_show_ad_bound(struct device *dev,
 		struct device_attribute *attr,
-		u8 bound_reg,
 		char *buf)
 {
+	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
 	struct iio_dev *dev_info = dev_get_drvdata(dev);
 	struct adt7316_chip_info *chip = dev_info->dev_data;
 	u8 val;
@@ -1911,10 +1901,10 @@
 	int ret;
 
 	if ((chip->id & ID_FAMILY_MASK) == ID_ADT73XX &&
-		bound_reg > ADT7316_EX_TEMP_LOW)
+		this_attr->address > ADT7316_EX_TEMP_LOW)
 		return -EPERM;
 
-	ret = chip->bus.read(chip->bus.client, bound_reg, &val);
+	ret = chip->bus.read(chip->bus.client, this_attr->address, &val);
 	if (ret)
 		return -EIO;
 
@@ -1931,10 +1921,10 @@
 
 static inline ssize_t adt7316_set_ad_bound(struct device *dev,
 		struct device_attribute *attr,
-		u8 bound_reg,
 		const char *buf,
 		size_t len)
 {
+	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
 	struct iio_dev *dev_info = dev_get_drvdata(dev);
 	struct adt7316_chip_info *chip = dev_info->dev_data;
 	long data;
@@ -1942,7 +1932,7 @@
 	int ret;
 
 	if ((chip->id & ID_FAMILY_MASK) == ID_ADT73XX &&
-		bound_reg > ADT7316_EX_TEMP_LOW)
+		this_attr->address > ADT7316_EX_TEMP_LOW)
 		return -EPERM;
 
 	ret = strict_strtol(buf, 10, &data);
@@ -1963,183 +1953,13 @@
 
 	val = (u8)data;
 
-	ret = chip->bus.write(chip->bus.client, bound_reg, val);
+	ret = chip->bus.write(chip->bus.client, this_attr->address, val);
 	if (ret)
 		return -EIO;
 
 	return len;
 }
 
-static ssize_t adt7316_show_in_temp_high(struct device *dev,
-		struct device_attribute *attr,
-		char *buf)
-{
-	return adt7316_show_ad_bound(dev, attr,
-			ADT7316_IN_TEMP_HIGH, buf);
-}
-
-static inline ssize_t adt7316_set_in_temp_high(struct device *dev,
-		struct device_attribute *attr,
-		const char *buf,
-		size_t len)
-{
-	return adt7316_set_ad_bound(dev, attr,
-			ADT7316_IN_TEMP_HIGH, buf, len);
-}
-
-static ssize_t adt7316_show_in_temp_low(struct device *dev,
-		struct device_attribute *attr,
-		char *buf)
-{
-	return adt7316_show_ad_bound(dev, attr,
-			ADT7316_IN_TEMP_LOW, buf);
-}
-
-static inline ssize_t adt7316_set_in_temp_low(struct device *dev,
-		struct device_attribute *attr,
-		const char *buf,
-		size_t len)
-{
-	return adt7316_set_ad_bound(dev, attr,
-			ADT7316_IN_TEMP_LOW, buf, len);
-}
-
-static ssize_t adt7316_show_ex_temp_ain1_high(struct device *dev,
-		struct device_attribute *attr,
-		char *buf)
-{
-	return adt7316_show_ad_bound(dev, attr,
-			ADT7316_EX_TEMP_HIGH, buf);
-}
-
-static inline ssize_t adt7316_set_ex_temp_ain1_high(struct device *dev,
-		struct device_attribute *attr,
-		const char *buf,
-		size_t len)
-{
-	return adt7316_set_ad_bound(dev, attr,
-			ADT7316_EX_TEMP_HIGH, buf, len);
-}
-
-static ssize_t adt7316_show_ex_temp_ain1_low(struct device *dev,
-		struct device_attribute *attr,
-		char *buf)
-{
-	return adt7316_show_ad_bound(dev, attr,
-			ADT7316_EX_TEMP_LOW, buf);
-}
-
-static inline ssize_t adt7316_set_ex_temp_ain1_low(struct device *dev,
-		struct device_attribute *attr,
-		const char *buf,
-		size_t len)
-{
-	return adt7316_set_ad_bound(dev, attr,
-			ADT7316_EX_TEMP_LOW, buf, len);
-}
-
-static ssize_t adt7316_show_ain2_high(struct device *dev,
-		struct device_attribute *attr,
-		char *buf)
-{
-	return adt7316_show_ad_bound(dev, attr,
-			ADT7516_AIN2_HIGH, buf);
-}
-
-static inline ssize_t adt7316_set_ain2_high(struct device *dev,
-		struct device_attribute *attr,
-		const char *buf,
-		size_t len)
-{
-	return adt7316_set_ad_bound(dev, attr,
-			ADT7516_AIN2_HIGH, buf, len);
-}
-
-static ssize_t adt7316_show_ain2_low(struct device *dev,
-		struct device_attribute *attr,
-		char *buf)
-{
-	return adt7316_show_ad_bound(dev, attr,
-			ADT7516_AIN2_LOW, buf);
-}
-
-static inline ssize_t adt7316_set_ain2_low(struct device *dev,
-		struct device_attribute *attr,
-		const char *buf,
-		size_t len)
-{
-	return adt7316_set_ad_bound(dev, attr,
-			ADT7516_AIN2_LOW, buf, len);
-}
-
-static ssize_t adt7316_show_ain3_high(struct device *dev,
-		struct device_attribute *attr,
-		char *buf)
-{
-	return adt7316_show_ad_bound(dev, attr,
-			ADT7516_AIN3_HIGH, buf);
-}
-
-static inline ssize_t adt7316_set_ain3_high(struct device *dev,
-		struct device_attribute *attr,
-		const char *buf,
-		size_t len)
-{
-	return adt7316_set_ad_bound(dev, attr,
-			ADT7516_AIN3_HIGH, buf, len);
-}
-
-static ssize_t adt7316_show_ain3_low(struct device *dev,
-		struct device_attribute *attr,
-		char *buf)
-{
-	return adt7316_show_ad_bound(dev, attr,
-			ADT7516_AIN3_LOW, buf);
-}
-
-static inline ssize_t adt7316_set_ain3_low(struct device *dev,
-		struct device_attribute *attr,
-		const char *buf,
-		size_t len)
-{
-	return adt7316_set_ad_bound(dev, attr,
-			ADT7516_AIN3_LOW, buf, len);
-}
-
-static ssize_t adt7316_show_ain4_high(struct device *dev,
-		struct device_attribute *attr,
-		char *buf)
-{
-	return adt7316_show_ad_bound(dev, attr,
-			ADT7516_AIN4_HIGH, buf);
-}
-
-static inline ssize_t adt7316_set_ain4_high(struct device *dev,
-		struct device_attribute *attr,
-		const char *buf,
-		size_t len)
-{
-	return adt7316_set_ad_bound(dev, attr,
-			ADT7516_AIN4_HIGH, buf, len);
-}
-
-static ssize_t adt7316_show_ain4_low(struct device *dev,
-		struct device_attribute *attr,
-		char *buf)
-{
-	return adt7316_show_ad_bound(dev, attr,
-			ADT7516_AIN4_LOW, buf);
-}
-
-static inline ssize_t adt7316_set_ain4_low(struct device *dev,
-		struct device_attribute *attr,
-		const char *buf,
-		size_t len)
-{
-	return adt7316_set_ad_bound(dev, attr,
-			ADT7516_AIN4_LOW, buf, len);
-}
-
 static ssize_t adt7316_show_int_enabled(struct device *dev,
 		struct device_attribute *attr,
 		char *buf)
@@ -2173,47 +1993,72 @@
 	return len;
 }
 
+static IIO_DEVICE_ATTR(int_mask,
+		       S_IRUGO | S_IWUSR,
+		       adt7316_show_int_mask, adt7316_set_int_mask,
+		       0);
+static IIO_DEVICE_ATTR(in_temp_high_value,
+		       S_IRUGO | S_IWUSR,
+		       adt7316_show_ad_bound, adt7316_set_ad_bound,
+		       ADT7316_IN_TEMP_HIGH);
+static IIO_DEVICE_ATTR(in_temp_low_value,
+		       S_IRUGO | S_IWUSR,
+		       adt7316_show_ad_bound, adt7316_set_ad_bound,
+		       ADT7316_IN_TEMP_LOW);
+static IIO_DEVICE_ATTR(ex_temp_high_value,
+		       S_IRUGO | S_IWUSR,
+		       adt7316_show_ad_bound, adt7316_set_ad_bound,
+		       ADT7316_EX_TEMP_HIGH);
+static IIO_DEVICE_ATTR(ex_temp_low_value,
+		       S_IRUGO | S_IWUSR,
+		       adt7316_show_ad_bound, adt7316_set_ad_bound,
+		       ADT7316_EX_TEMP_LOW);
 
-IIO_EVENT_ATTR_SH(int_mask, iio_event_adt7316,
-		adt7316_show_int_mask, adt7316_set_int_mask, 0);
-IIO_EVENT_ATTR_SH(in_temp_high, iio_event_adt7316,
-		adt7316_show_in_temp_high, adt7316_set_in_temp_high, 0);
-IIO_EVENT_ATTR_SH(in_temp_low, iio_event_adt7316,
-		adt7316_show_in_temp_low, adt7316_set_in_temp_low, 0);
-IIO_EVENT_ATTR_SH(ex_temp_high, iio_event_adt7316,
-		adt7316_show_ex_temp_ain1_high,
-		adt7316_set_ex_temp_ain1_high, 0);
-IIO_EVENT_ATTR_SH(ex_temp_low, iio_event_adt7316,
-		adt7316_show_ex_temp_ain1_low,
-		adt7316_set_ex_temp_ain1_low, 0);
-IIO_EVENT_ATTR_SH(ex_temp_ain1_high, iio_event_adt7316,
-		adt7316_show_ex_temp_ain1_high,
-		adt7316_set_ex_temp_ain1_high, 0);
-IIO_EVENT_ATTR_SH(ex_temp_ain1_low, iio_event_adt7316,
-		adt7316_show_ex_temp_ain1_low,
-		adt7316_set_ex_temp_ain1_low, 0);
-IIO_EVENT_ATTR_SH(ain2_high, iio_event_adt7316,
-		adt7316_show_ain2_high, adt7316_set_ain2_high, 0);
-IIO_EVENT_ATTR_SH(ain2_low, iio_event_adt7316,
-		adt7316_show_ain2_low, adt7316_set_ain2_low, 0);
-IIO_EVENT_ATTR_SH(ain3_high, iio_event_adt7316,
-		adt7316_show_ain3_high, adt7316_set_ain3_high, 0);
-IIO_EVENT_ATTR_SH(ain3_low, iio_event_adt7316,
-		adt7316_show_ain3_low, adt7316_set_ain3_low, 0);
-IIO_EVENT_ATTR_SH(ain4_high, iio_event_adt7316,
-		adt7316_show_ain4_high, adt7316_set_ain4_high, 0);
-IIO_EVENT_ATTR_SH(ain4_low, iio_event_adt7316,
-		adt7316_show_ain4_low, adt7316_set_ain4_low, 0);
-IIO_EVENT_ATTR_SH(int_enabled, iio_event_adt7316,
-		adt7316_show_int_enabled, adt7316_set_int_enabled, 0);
+/* NASTY duplication to be fixed */
+static IIO_DEVICE_ATTR(ex_temp_ain1_high_value,
+		       S_IRUGO | S_IWUSR,
+		       adt7316_show_ad_bound, adt7316_set_ad_bound,
+		       ADT7316_EX_TEMP_HIGH);
+static IIO_DEVICE_ATTR(ex_temp_ain1_low_value,
+		       S_IRUGO | S_IWUSR,
+		       adt7316_show_ad_bound, adt7316_set_ad_bound,
+		       ADT7316_EX_TEMP_LOW);
+static IIO_DEVICE_ATTR(ain2_high_value,
+		       S_IRUGO | S_IWUSR,
+		       adt7316_show_ad_bound, adt7316_set_ad_bound,
+		       ADT7516_AIN2_HIGH);
+static IIO_DEVICE_ATTR(ain2_low_value,
+		       S_IRUGO | S_IWUSR,
+		       adt7316_show_ad_bound, adt7316_set_ad_bound,
+		       ADT7516_AIN2_LOW);
+static IIO_DEVICE_ATTR(ain3_high_value,
+		       S_IRUGO | S_IWUSR,
+		       adt7316_show_ad_bound, adt7316_set_ad_bound,
+		       ADT7516_AIN3_HIGH);
+static IIO_DEVICE_ATTR(ain3_low_value,
+		       S_IRUGO | S_IWUSR,
+		       adt7316_show_ad_bound, adt7316_set_ad_bound,
+		       ADT7516_AIN3_LOW);
+static IIO_DEVICE_ATTR(ain4_high_value,
+		       S_IRUGO | S_IWUSR,
+		       adt7316_show_ad_bound, adt7316_set_ad_bound,
+		       ADT7516_AIN4_HIGH);
+static IIO_DEVICE_ATTR(ain4_low_value,
+		       S_IRUGO | S_IWUSR,
+		       adt7316_show_ad_bound, adt7316_set_ad_bound,
+		       ADT7516_AIN4_LOW);
+static IIO_DEVICE_ATTR(int_enabled,
+		       S_IRUGO | S_IWUSR,
+		       adt7316_show_int_enabled,
+		       adt7316_set_int_enabled, 0);
 
 static struct attribute *adt7316_event_attributes[] = {
-	&iio_event_attr_int_mask.dev_attr.attr,
-	&iio_event_attr_in_temp_high.dev_attr.attr,
-	&iio_event_attr_in_temp_low.dev_attr.attr,
-	&iio_event_attr_ex_temp_high.dev_attr.attr,
-	&iio_event_attr_ex_temp_low.dev_attr.attr,
-	&iio_event_attr_int_enabled.dev_attr.attr,
+	&iio_dev_attr_int_mask.dev_attr.attr,
+	&iio_dev_attr_in_temp_high_value.dev_attr.attr,
+	&iio_dev_attr_in_temp_low_value.dev_attr.attr,
+	&iio_dev_attr_ex_temp_high_value.dev_attr.attr,
+	&iio_dev_attr_ex_temp_low_value.dev_attr.attr,
+	&iio_dev_attr_int_enabled.dev_attr.attr,
 	NULL,
 };
 
@@ -2222,18 +2067,18 @@
 };
 
 static struct attribute *adt7516_event_attributes[] = {
-	&iio_event_attr_int_mask.dev_attr.attr,
-	&iio_event_attr_in_temp_high.dev_attr.attr,
-	&iio_event_attr_in_temp_low.dev_attr.attr,
-	&iio_event_attr_ex_temp_ain1_high.dev_attr.attr,
-	&iio_event_attr_ex_temp_ain1_low.dev_attr.attr,
-	&iio_event_attr_ain2_high.dev_attr.attr,
-	&iio_event_attr_ain2_low.dev_attr.attr,
-	&iio_event_attr_ain3_high.dev_attr.attr,
-	&iio_event_attr_ain3_low.dev_attr.attr,
-	&iio_event_attr_ain4_high.dev_attr.attr,
-	&iio_event_attr_ain4_low.dev_attr.attr,
-	&iio_event_attr_int_enabled.dev_attr.attr,
+	&iio_dev_attr_int_mask.dev_attr.attr,
+	&iio_dev_attr_in_temp_high_value.dev_attr.attr,
+	&iio_dev_attr_in_temp_low_value.dev_attr.attr,
+	&iio_dev_attr_ex_temp_ain1_high_value.dev_attr.attr,
+	&iio_dev_attr_ex_temp_ain1_low_value.dev_attr.attr,
+	&iio_dev_attr_ain2_high_value.dev_attr.attr,
+	&iio_dev_attr_ain2_low_value.dev_attr.attr,
+	&iio_dev_attr_ain3_high_value.dev_attr.attr,
+	&iio_dev_attr_ain3_low_value.dev_attr.attr,
+	&iio_dev_attr_ain4_high_value.dev_attr.attr,
+	&iio_dev_attr_ain4_low_value.dev_attr.attr,
+	&iio_dev_attr_int_enabled.dev_attr.attr,
 	NULL,
 };
 
@@ -2261,6 +2106,20 @@
 EXPORT_SYMBOL(adt7316_enable);
 #endif
 
+static const struct iio_info adt7316_info = {
+	.attrs = &adt7316_attribute_group,
+	.num_interrupt_lines = 1,
+	.event_attrs = &adt7316_event_attribute_group,
+	.driver_module = THIS_MODULE,
+};
+
+static const struct iio_info adt7516_info = {
+	.attrs = &adt7516_attribute_group,
+	.num_interrupt_lines = 1,
+	.event_attrs = &adt7516_event_attribute_group,
+	.driver_module = THIS_MODULE,
+};
+
 /*
  * device probe and remove
  */
@@ -2280,7 +2139,6 @@
 	dev_set_drvdata(dev, chip);
 
 	chip->bus = *bus;
-	chip->name = name;
 
 	if (name[4] == '3')
 		chip->id = ID_ADT7316 + (name[6] - '6');
@@ -2299,23 +2157,19 @@
 	if ((chip->id & ID_FAMILY_MASK) == ID_ADT75XX)
 		chip->int_mask |= ADT7516_AIN_INT_MASK;
 
-	chip->indio_dev = iio_allocate_device();
+	chip->indio_dev = iio_allocate_device(0);
 	if (chip->indio_dev == NULL) {
 		ret = -ENOMEM;
 		goto error_free_chip;
 	}
 
 	chip->indio_dev->dev.parent = dev;
-	if ((chip->id & ID_FAMILY_MASK) == ID_ADT75XX) {
-		chip->indio_dev->attrs = &adt7516_attribute_group;
-		chip->indio_dev->event_attrs = &adt7516_event_attribute_group;
-	} else {
-		chip->indio_dev->attrs = &adt7316_attribute_group;
-		chip->indio_dev->event_attrs = &adt7316_event_attribute_group;
-	}
+	if ((chip->id & ID_FAMILY_MASK) == ID_ADT75XX)
+		chip->indio_dev->info = &adt7516_info;
+	else
+		chip->indio_dev->info = &adt7316_info;
+	chip->indio_dev->name = name;
 	chip->indio_dev->dev_data = (void *)chip;
-	chip->indio_dev->driver_module = THIS_MODULE;
-	chip->indio_dev->num_interrupt_lines = 1;
 	chip->indio_dev->modes = INDIO_DIRECT_MODE;
 
 	ret = iio_device_register(chip->indio_dev);
@@ -2326,24 +2180,15 @@
 		if (adt7316_platform_data[0])
 			chip->bus.irq_flags = adt7316_platform_data[0];
 
-		ret = iio_register_interrupt_line(chip->bus.irq,
-				chip->indio_dev,
-				0,
-				chip->bus.irq_flags,
-				chip->name);
+		ret = request_threaded_irq(chip->bus.irq,
+					   NULL,
+					   &adt7316_event_handler,
+					   chip->bus.irq_flags | IRQF_ONESHOT,
+					   chip->indio_dev->name,
+					   chip->indio_dev);
 		if (ret)
 			goto error_unreg_dev;
 
-		/*
-		 * The event handler list element refer to iio_event_adt7316.
-		 * All event attributes bind to the same event handler.
-		 * So, only register event handler once.
-		 */
-		iio_add_event_to_list(&iio_event_adt7316,
-				&chip->indio_dev->interrupts[0]->ev_list);
-
-		INIT_WORK(&chip->thresh_work, adt7316_interrupt_bh);
-
 		if (chip->bus.irq_flags & IRQF_TRIGGER_HIGH)
 			chip->config1 |= ADT7316_INT_POLARITY;
 	}
@@ -2361,12 +2206,12 @@
 	}
 
 	dev_info(dev, "%s temperature sensor, ADC and DAC registered.\n",
-			chip->name);
+			chip->indio_dev->name);
 
 	return 0;
 
 error_unreg_irq:
-	iio_unregister_interrupt_line(chip->indio_dev, 0);
+	free_irq(chip->bus.irq, chip->indio_dev);
 error_unreg_dev:
 	iio_device_unregister(chip->indio_dev);
 error_free_dev:
@@ -2383,12 +2228,11 @@
 
 	struct iio_dev *dev_info = dev_get_drvdata(dev);
 	struct adt7316_chip_info *chip = dev_info->dev_data;
-	struct iio_dev *indio_dev = chip->indio_dev;
 
 	dev_set_drvdata(dev, NULL);
 	if (chip->bus.irq)
-		iio_unregister_interrupt_line(indio_dev, 0);
-	iio_device_unregister(indio_dev);
+		free_irq(chip->bus.irq, chip->indio_dev);
+	iio_device_unregister(chip->indio_dev);
 	iio_free_device(chip->indio_dev);
 	kfree(chip);
 
diff -druN linux-2.6.39-libre/drivers/staging/iio/chrdev.h linux-3.0-rc7-libre/drivers/staging/iio/chrdev.h
--- linux-2.6.39-libre/drivers/staging/iio/chrdev.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/iio/chrdev.h	2011-07-11 19:51:52.000000000 -0400
@@ -45,23 +45,10 @@
  * struct iio_detected_event_list - list element for events that have occurred
  * @list:		linked list header
  * @ev:			the event itself
- * @shared_pointer:	used when the event is shared - i.e. can be escallated
- *			on demand (eg ring buffer 50%->100% full)
  */
 struct iio_detected_event_list {
 	struct list_head		list;
 	struct iio_event_data		ev;
-	struct iio_shared_ev_pointer	*shared_pointer;
-};
-/**
- * struct iio_shared_ev_pointer - allows shared events to identify if currently
- *				in the detected event list
- * @ev_p:	pointer to detected event list element (null if not in list)
- * @lock:	protect this element to prevent simultaneous edit and remove
- */
-struct iio_shared_ev_pointer {
-	struct iio_detected_event_list	*ev_p;
-	spinlock_t			lock;
 };
 
 /**
@@ -73,43 +60,16 @@
  * @det_events:		list of detected events
  * @max_events:		maximum number of events before new ones are dropped
  * @current_events:	number of events in detected list
- * @owner:		ensure the driver module owns the file, not iio
- * @private:		driver specific data
- * @_name:		used internally to store the sysfs name for minor id
- *			attribute
- * @_attrname:		the event interface's attribute name
  */
 struct iio_event_interface {
 	struct device				dev;
 	struct iio_handler			handler;
 	wait_queue_head_t			wait;
 	struct mutex				event_list_lock;
-	struct iio_detected_event_list		det_events;
+	struct list_head			det_events;
 	int					max_events;
 	int					current_events;
-	struct module				*owner;
-	void					*private;
-	char					_name[35];
-	char					_attrname[20];
-};
-
-/**
- * struct iio_event_handler_list - element in list of handlers for events
- * @list:		list header
- * @refcount:		as the handler may be shared between multiple device
- *			side events, reference counting ensures clean removal
- * @exist_lock:		prevents race conditions related to refcount usage.
- * @handler:		event handler function - called on event if this
- *			event_handler is enabled.
- *
- * Each device has one list of these per interrupt line.
- **/
-struct iio_event_handler_list {
-	struct list_head	list;
-	int			refcount;
-	struct mutex		exist_lock;
-	int (*handler)(struct iio_dev *dev_info, int index, s64 timestamp,
-		       int no_test);
+	struct list_head dev_attr_list;
 };
 
 #endif
diff -druN linux-2.6.39-libre/drivers/staging/iio/dac/ad5446.c linux-3.0-rc7-libre/drivers/staging/iio/dac/ad5446.c
--- linux-2.6.39-libre/drivers/staging/iio/dac/ad5446.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/iio/dac/ad5446.c	2011-07-11 19:51:52.000000000 -0400
@@ -106,17 +106,6 @@
 }
 static IIO_DEVICE_ATTR(out_scale, S_IRUGO, ad5446_show_scale, NULL, 0);
 
-static ssize_t ad5446_show_name(struct device *dev,
-				 struct device_attribute *attr,
-				 char *buf)
-{
-	struct iio_dev *dev_info = dev_get_drvdata(dev);
-	struct ad5446_state *st = iio_dev_get_devdata(dev_info);
-
-	return sprintf(buf, "%s\n", spi_get_device_id(st->spi)->name);
-}
-static IIO_DEVICE_ATTR(name, S_IRUGO, ad5446_show_name, NULL, 0);
-
 static ssize_t ad5446_write_powerdown_mode(struct device *dev,
 				       struct device_attribute *attr,
 				       const char *buf, size_t len)
@@ -204,7 +193,6 @@
 	&iio_dev_attr_out0_powerdown.dev_attr.attr,
 	&iio_dev_attr_out_powerdown_mode.dev_attr.attr,
 	&iio_const_attr_out_powerdown_mode_available.dev_attr.attr,
-	&iio_dev_attr_name.dev_attr.attr,
 	NULL,
 };
 
@@ -245,6 +233,12 @@
 		.left_shift = 0,
 		.store_sample = ad5446_store_sample,
 	},
+	[ID_AD5541A] = {
+		.bits = 16,
+		.storagebits = 16,
+		.left_shift = 0,
+		.store_sample = ad5542_store_sample,
+	},
 	[ID_AD5542A] = {
 		.bits = 16,
 		.storagebits = 16,
@@ -340,6 +334,11 @@
 	},
 };
 
+static const struct iio_info ad5446_info = {
+	.attrs = &ad5446_attribute_group,
+	.driver_module = THIS_MODULE,
+};
+
 static int __devinit ad5446_probe(struct spi_device *spi)
 {
 	struct ad5446_state *st;
@@ -367,7 +366,7 @@
 
 	st->spi = spi;
 
-	st->indio_dev = iio_allocate_device();
+	st->indio_dev = iio_allocate_device(0);
 	if (st->indio_dev == NULL) {
 		ret = -ENOMEM;
 		goto error_disable_reg;
@@ -375,9 +374,9 @@
 
 	/* Estabilish that the iio_dev is a child of the spi device */
 	st->indio_dev->dev.parent = &spi->dev;
-	st->indio_dev->attrs = &ad5446_attribute_group;
+	st->indio_dev->name = spi_get_device_id(spi)->name;
+	st->indio_dev->info = &ad5446_info;
 	st->indio_dev->dev_data = (void *)(st);
-	st->indio_dev->driver_module = THIS_MODULE;
 	st->indio_dev->modes = INDIO_DIRECT_MODE;
 
 	/* Setup default message */
@@ -442,6 +441,7 @@
 	{"ad5444", ID_AD5444},
 	{"ad5446", ID_AD5446},
 	{"ad5512a", ID_AD5512A},
+	{"ad5541a", ID_AD5541A},
 	{"ad5542a", ID_AD5542A},
 	{"ad5543", ID_AD5543},
 	{"ad5553", ID_AD5553},
diff -druN linux-2.6.39-libre/drivers/staging/iio/dac/ad5446.h linux-3.0-rc7-libre/drivers/staging/iio/dac/ad5446.h
--- linux-2.6.39-libre/drivers/staging/iio/dac/ad5446.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/iio/dac/ad5446.h	2011-07-11 19:51:52.000000000 -0400
@@ -92,6 +92,7 @@
 enum ad5446_supported_device_ids {
 	ID_AD5444,
 	ID_AD5446,
+	ID_AD5541A,
 	ID_AD5542A,
 	ID_AD5543,
 	ID_AD5512A,
diff -druN linux-2.6.39-libre/drivers/staging/iio/dac/ad5504.c linux-3.0-rc7-libre/drivers/staging/iio/dac/ad5504.c
--- linux-2.6.39-libre/drivers/staging/iio/dac/ad5504.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/staging/iio/dac/ad5504.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,404 @@
+/*
+ * AD5504, AD5501 High Voltage Digital to Analog Converter
+ *
+ * Copyright 2011 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2.
+ */
+
+#include <linux/interrupt.h>
+#include <linux/gpio.h>
+#include <linux/fs.h>
+#include <linux/device.h>
+#include <linux/kernel.h>
+#include <linux/spi/spi.h>
+#include <linux/slab.h>
+#include <linux/sysfs.h>
+#include <linux/regulator/consumer.h>
+
+#include "../iio.h"
+#include "../sysfs.h"
+#include "dac.h"
+#include "ad5504.h"
+
+static int ad5504_spi_write(struct spi_device *spi, u8 addr, u16 val)
+{
+	u16 tmp = cpu_to_be16(AD5504_CMD_WRITE |
+			      AD5504_ADDR(addr) |
+			      (val & AD5504_RES_MASK));
+
+	return spi_write(spi, (u8 *)&tmp, 2);
+}
+
+static int ad5504_spi_read(struct spi_device *spi, u8 addr, u16 *val)
+{
+	u16 tmp = cpu_to_be16(AD5504_CMD_READ | AD5504_ADDR(addr));
+	int ret;
+	struct spi_transfer	t = {
+			.tx_buf		= &tmp,
+			.rx_buf		= val,
+			.len		= 2,
+		};
+	struct spi_message	m;
+
+	spi_message_init(&m);
+	spi_message_add_tail(&t, &m);
+	ret = spi_sync(spi, &m);
+
+	*val = be16_to_cpu(*val) & AD5504_RES_MASK;
+
+	return ret;
+}
+
+static ssize_t ad5504_write_dac(struct device *dev,
+				 struct device_attribute *attr,
+				 const char *buf, size_t len)
+{
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct ad5504_state *st = iio_dev_get_devdata(indio_dev);
+	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
+	long readin;
+	int ret;
+
+	ret = strict_strtol(buf, 10, &readin);
+	if (ret)
+		return ret;
+
+	ret = ad5504_spi_write(st->spi, this_attr->address, readin);
+	return ret ? ret : len;
+}
+
+static ssize_t ad5504_read_dac(struct device *dev,
+					   struct device_attribute *attr,
+					   char *buf)
+{
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct ad5504_state *st = iio_dev_get_devdata(indio_dev);
+	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
+	int ret;
+	u16 val;
+
+	ret = ad5504_spi_read(st->spi, this_attr->address, &val);
+	if (ret)
+		return ret;
+
+	return sprintf(buf, "%d\n", val);
+}
+
+static ssize_t ad5504_read_powerdown_mode(struct device *dev,
+				      struct device_attribute *attr, char *buf)
+{
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct ad5504_state *st = iio_dev_get_devdata(indio_dev);
+
+	const char mode[][14] = {"20kohm_to_gnd", "three_state"};
+
+	return sprintf(buf, "%s\n", mode[st->pwr_down_mode]);
+}
+
+static ssize_t ad5504_write_powerdown_mode(struct device *dev,
+				       struct device_attribute *attr,
+				       const char *buf, size_t len)
+{
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct ad5504_state *st = iio_dev_get_devdata(indio_dev);
+	int ret;
+
+	if (sysfs_streq(buf, "20kohm_to_gnd"))
+		st->pwr_down_mode = AD5504_DAC_PWRDN_20K;
+	else if (sysfs_streq(buf, "three_state"))
+		st->pwr_down_mode = AD5504_DAC_PWRDN_3STATE;
+	else
+		ret = -EINVAL;
+
+	return ret ? ret : len;
+}
+
+static ssize_t ad5504_read_dac_powerdown(struct device *dev,
+					   struct device_attribute *attr,
+					   char *buf)
+{
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct ad5504_state *st = iio_dev_get_devdata(indio_dev);
+	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
+
+	return sprintf(buf, "%d\n",
+			!(st->pwr_down_mask & (1 << this_attr->address)));
+}
+
+static ssize_t ad5504_write_dac_powerdown(struct device *dev,
+					    struct device_attribute *attr,
+					    const char *buf, size_t len)
+{
+	long readin;
+	int ret;
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct ad5504_state *st = iio_dev_get_devdata(indio_dev);
+	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
+
+	ret = strict_strtol(buf, 10, &readin);
+	if (ret)
+		return ret;
+
+	if (readin == 0)
+		st->pwr_down_mask |= (1 << this_attr->address);
+	else if (readin == 1)
+		st->pwr_down_mask &= ~(1 << this_attr->address);
+	else
+		ret = -EINVAL;
+
+	ret = ad5504_spi_write(st->spi, AD5504_ADDR_CTRL,
+				AD5504_DAC_PWRDWN_MODE(st->pwr_down_mode) |
+				AD5504_DAC_PWR(st->pwr_down_mask));
+
+	/* writes to the CTRL register must be followed by a NOOP */
+	ad5504_spi_write(st->spi, AD5504_ADDR_NOOP, 0);
+
+	return ret ? ret : len;
+}
+
+static ssize_t ad5504_show_scale(struct device *dev,
+				struct device_attribute *attr,
+				char *buf)
+{
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct ad5504_state *st = iio_dev_get_devdata(indio_dev);
+	/* Corresponds to Vref / 2^(bits) */
+	unsigned int scale_uv = (st->vref_mv * 1000) >> AD5505_BITS;
+
+	return sprintf(buf, "%d.%03d\n", scale_uv / 1000, scale_uv % 1000);
+}
+static IIO_DEVICE_ATTR(out_scale, S_IRUGO, ad5504_show_scale, NULL, 0);
+
+#define IIO_DEV_ATTR_OUT_RW_RAW(_num, _show, _store, _addr)		\
+	IIO_DEVICE_ATTR(out##_num##_raw,				\
+			S_IRUGO | S_IWUSR, _show, _store, _addr)
+
+static IIO_DEV_ATTR_OUT_RW_RAW(0, ad5504_read_dac,
+	ad5504_write_dac, AD5504_ADDR_DAC0);
+static IIO_DEV_ATTR_OUT_RW_RAW(1, ad5504_read_dac,
+	ad5504_write_dac, AD5504_ADDR_DAC1);
+static IIO_DEV_ATTR_OUT_RW_RAW(2, ad5504_read_dac,
+	ad5504_write_dac, AD5504_ADDR_DAC2);
+static IIO_DEV_ATTR_OUT_RW_RAW(3, ad5504_read_dac,
+	ad5504_write_dac, AD5504_ADDR_DAC3);
+
+static IIO_DEVICE_ATTR(out_powerdown_mode, S_IRUGO |
+			S_IWUSR, ad5504_read_powerdown_mode,
+			ad5504_write_powerdown_mode, 0);
+
+static IIO_CONST_ATTR(out_powerdown_mode_available,
+			"20kohm_to_gnd three_state");
+
+#define IIO_DEV_ATTR_DAC_POWERDOWN(_num, _show, _store, _addr)		\
+	IIO_DEVICE_ATTR(out##_num##_powerdown,				\
+			S_IRUGO | S_IWUSR, _show, _store, _addr)
+
+static IIO_DEV_ATTR_DAC_POWERDOWN(0, ad5504_read_dac_powerdown,
+				   ad5504_write_dac_powerdown, 0);
+static IIO_DEV_ATTR_DAC_POWERDOWN(1, ad5504_read_dac_powerdown,
+				   ad5504_write_dac_powerdown, 1);
+static IIO_DEV_ATTR_DAC_POWERDOWN(2, ad5504_read_dac_powerdown,
+				   ad5504_write_dac_powerdown, 2);
+static IIO_DEV_ATTR_DAC_POWERDOWN(3, ad5504_read_dac_powerdown,
+				   ad5504_write_dac_powerdown, 3);
+
+static struct attribute *ad5504_attributes[] = {
+	&iio_dev_attr_out0_raw.dev_attr.attr,
+	&iio_dev_attr_out1_raw.dev_attr.attr,
+	&iio_dev_attr_out2_raw.dev_attr.attr,
+	&iio_dev_attr_out3_raw.dev_attr.attr,
+	&iio_dev_attr_out0_powerdown.dev_attr.attr,
+	&iio_dev_attr_out1_powerdown.dev_attr.attr,
+	&iio_dev_attr_out2_powerdown.dev_attr.attr,
+	&iio_dev_attr_out3_powerdown.dev_attr.attr,
+	&iio_dev_attr_out_powerdown_mode.dev_attr.attr,
+	&iio_const_attr_out_powerdown_mode_available.dev_attr.attr,
+	&iio_dev_attr_out_scale.dev_attr.attr,
+	NULL,
+};
+
+static const struct attribute_group ad5504_attribute_group = {
+	.attrs = ad5504_attributes,
+};
+
+static struct attribute *ad5501_attributes[] = {
+	&iio_dev_attr_out0_raw.dev_attr.attr,
+	&iio_dev_attr_out0_powerdown.dev_attr.attr,
+	&iio_dev_attr_out_powerdown_mode.dev_attr.attr,
+	&iio_const_attr_out_powerdown_mode_available.dev_attr.attr,
+	&iio_dev_attr_out_scale.dev_attr.attr,
+	NULL,
+};
+
+static const struct attribute_group ad5501_attribute_group = {
+	.attrs = ad5501_attributes,
+};
+
+static IIO_CONST_ATTR(temp0_thresh_rising_value, "110000");
+static IIO_CONST_ATTR(temp0_thresh_rising_en, "1");
+
+static struct attribute *ad5504_ev_attributes[] = {
+	&iio_const_attr_temp0_thresh_rising_value.dev_attr.attr,
+	&iio_const_attr_temp0_thresh_rising_en.dev_attr.attr,
+	NULL,
+};
+
+static struct attribute_group ad5504_ev_attribute_group = {
+	.attrs = ad5504_ev_attributes,
+};
+
+static irqreturn_t ad5504_event_handler(int irq, void *private)
+{
+	iio_push_event(private, 0,
+		       IIO_UNMOD_EVENT_CODE(IIO_EV_CLASS_TEMP,
+					    0,
+					    IIO_EV_TYPE_THRESH,
+					    IIO_EV_DIR_RISING),
+		       iio_get_time_ns());
+
+	return IRQ_HANDLED;
+}
+
+static const struct iio_info ad5504_info = {
+	.attrs = &ad5504_attribute_group,
+	.num_interrupt_lines = 1,
+	.event_attrs = &ad5504_ev_attribute_group,
+	.driver_module = THIS_MODULE,
+};
+
+static const struct iio_info ad5501_info = {
+	.attrs = &ad5501_attribute_group,
+	.num_interrupt_lines = 1,
+	.event_attrs = &ad5504_ev_attribute_group,
+	.driver_module = THIS_MODULE,
+};
+
+static int __devinit ad5504_probe(struct spi_device *spi)
+{
+	struct ad5504_platform_data *pdata = spi->dev.platform_data;
+	struct ad5504_state *st;
+	int ret, voltage_uv = 0;
+
+	st = kzalloc(sizeof(*st), GFP_KERNEL);
+	if (st == NULL) {
+		ret = -ENOMEM;
+		goto error_ret;
+	}
+
+	spi_set_drvdata(spi, st);
+
+	st->reg = regulator_get(&spi->dev, "vcc");
+	if (!IS_ERR(st->reg)) {
+		ret = regulator_enable(st->reg);
+		if (ret)
+			goto error_put_reg;
+
+		voltage_uv = regulator_get_voltage(st->reg);
+	}
+
+	if (voltage_uv)
+		st->vref_mv = voltage_uv / 1000;
+	else if (pdata)
+		st->vref_mv = pdata->vref_mv;
+	else
+		dev_warn(&spi->dev, "reference voltage unspecified\n");
+
+	st->spi = spi;
+	st->indio_dev = iio_allocate_device(0);
+	if (st->indio_dev == NULL) {
+		ret = -ENOMEM;
+		goto error_disable_reg;
+	}
+	st->indio_dev->dev.parent = &spi->dev;
+	st->indio_dev->name = spi_get_device_id(st->spi)->name;
+	if (spi_get_device_id(st->spi)->driver_data == ID_AD5501)
+		st->indio_dev->info = &ad5501_info;
+	else
+		st->indio_dev->info = &ad5504_info;
+	st->indio_dev->dev_data = (void *)(st);
+	st->indio_dev->modes = INDIO_DIRECT_MODE;
+
+	ret = iio_device_register(st->indio_dev);
+	if (ret)
+		goto error_free_dev;
+
+	if (spi->irq) {
+		ret = request_threaded_irq(spi->irq,
+					   NULL,
+					   &ad5504_event_handler,
+					   IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
+					   spi_get_device_id(st->spi)->name,
+					   st->indio_dev);
+		if (ret)
+			goto error_unreg_iio_device;
+	}
+
+	return 0;
+
+error_unreg_iio_device:
+	iio_device_unregister(st->indio_dev);
+error_free_dev:
+	iio_free_device(st->indio_dev);
+error_disable_reg:
+	if (!IS_ERR(st->reg))
+		regulator_disable(st->reg);
+error_put_reg:
+	if (!IS_ERR(st->reg))
+		regulator_put(st->reg);
+
+	kfree(st);
+error_ret:
+	return ret;
+}
+
+static int __devexit ad5504_remove(struct spi_device *spi)
+{
+	struct ad5504_state *st = spi_get_drvdata(spi);
+
+	if (spi->irq)
+		free_irq(spi->irq, st->indio_dev);
+
+	iio_device_unregister(st->indio_dev);
+
+	if (!IS_ERR(st->reg)) {
+		regulator_disable(st->reg);
+		regulator_put(st->reg);
+	}
+
+	kfree(st);
+
+	return 0;
+}
+
+static const struct spi_device_id ad5504_id[] = {
+	{"ad5504", ID_AD5504},
+	{"ad5501", ID_AD5501},
+	{}
+};
+
+static struct spi_driver ad5504_driver = {
+	.driver = {
+		   .name = "ad5504",
+		   .owner = THIS_MODULE,
+		   },
+	.probe = ad5504_probe,
+	.remove = __devexit_p(ad5504_remove),
+	.id_table = ad5504_id,
+};
+
+static __init int ad5504_spi_init(void)
+{
+	return spi_register_driver(&ad5504_driver);
+}
+module_init(ad5504_spi_init);
+
+static __exit void ad5504_spi_exit(void)
+{
+	spi_unregister_driver(&ad5504_driver);
+}
+module_exit(ad5504_spi_exit);
+
+MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>");
+MODULE_DESCRIPTION("Analog Devices AD5501/AD5501 DAC");
+MODULE_LICENSE("GPL v2");
diff -druN linux-2.6.39-libre/drivers/staging/iio/dac/ad5504.h linux-3.0-rc7-libre/drivers/staging/iio/dac/ad5504.h
--- linux-2.6.39-libre/drivers/staging/iio/dac/ad5504.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/staging/iio/dac/ad5504.h	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,70 @@
+/*
+ * AD5504 SPI DAC driver
+ *
+ * Copyright 2011 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2.
+ */
+
+#ifndef SPI_AD5504_H_
+#define SPI_AD5504_H_
+
+#define AD5505_BITS			12
+#define AD5504_RES_MASK			((1 << (AD5505_BITS)) - 1)
+
+#define AD5504_CMD_READ			(1 << 15)
+#define AD5504_CMD_WRITE		(0 << 15)
+#define AD5504_ADDR(addr)		((addr) << 12)
+
+/* Registers */
+#define AD5504_ADDR_NOOP		0
+#define AD5504_ADDR_DAC0		1
+#define AD5504_ADDR_DAC1		2
+#define AD5504_ADDR_DAC2		3
+#define AD5504_ADDR_DAC3		4
+#define AD5504_ADDR_ALL_DAC		5
+#define AD5504_ADDR_CTRL		7
+
+/* Control Register */
+#define AD5504_DAC_PWR(ch)		((ch) << 2)
+#define AD5504_DAC_PWRDWN_MODE(mode)	((mode) << 6)
+#define AD5504_DAC_PWRDN_20K		0
+#define AD5504_DAC_PWRDN_3STATE		1
+
+/*
+ * TODO: struct ad5504_platform_data needs to go into include/linux/iio
+ */
+
+struct ad5504_platform_data {
+	u16				vref_mv;
+};
+
+/**
+ * struct ad5446_state - driver instance specific data
+ * @indio_dev:		the industrial I/O device
+ * @us:			spi_device
+ * @reg:		supply regulator
+ * @vref_mv:		actual reference voltage used
+ * @pwr_down_mask	power down mask
+ * @pwr_down_mode	current power down mode
+ */
+
+struct ad5504_state {
+	struct iio_dev			*indio_dev;
+	struct spi_device		*spi;
+	struct regulator		*reg;
+	unsigned short			vref_mv;
+	unsigned			pwr_down_mask;
+	unsigned			pwr_down_mode;
+};
+
+/**
+ * ad5504_supported_device_ids:
+ */
+
+enum ad5504_supported_device_ids {
+	ID_AD5504,
+	ID_AD5501,
+};
+
+#endif /* SPI_AD5504_H_ */
diff -druN linux-2.6.39-libre/drivers/staging/iio/dac/ad5624r_spi.c linux-3.0-rc7-libre/drivers/staging/iio/dac/ad5624r_spi.c
--- linux-2.6.39-libre/drivers/staging/iio/dac/ad5624r_spi.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/iio/dac/ad5624r_spi.c	2011-07-11 19:51:52.000000000 -0400
@@ -174,17 +174,6 @@
 }
 static IIO_DEVICE_ATTR(out_scale, S_IRUGO, ad5624r_show_scale, NULL, 0);
 
-static ssize_t ad5624r_show_name(struct device *dev,
-				 struct device_attribute *attr,
-				 char *buf)
-{
-	struct iio_dev *indio_dev = dev_get_drvdata(dev);
-	struct ad5624r_state *st = iio_dev_get_devdata(indio_dev);
-
-	return sprintf(buf, "%s\n", spi_get_device_id(st->us)->name);
-}
-static IIO_DEVICE_ATTR(name, S_IRUGO, ad5624r_show_name, NULL, 0);
-
 static IIO_DEV_ATTR_OUT_RAW(0, ad5624r_write_dac, AD5624R_ADDR_DAC0);
 static IIO_DEV_ATTR_OUT_RAW(1, ad5624r_write_dac, AD5624R_ADDR_DAC1);
 static IIO_DEV_ATTR_OUT_RAW(2, ad5624r_write_dac, AD5624R_ADDR_DAC2);
@@ -222,7 +211,6 @@
 	&iio_dev_attr_out_powerdown_mode.dev_attr.attr,
 	&iio_const_attr_out_powerdown_mode_available.dev_attr.attr,
 	&iio_dev_attr_out_scale.dev_attr.attr,
-	&iio_dev_attr_name.dev_attr.attr,
 	NULL,
 };
 
@@ -230,6 +218,11 @@
 	.attrs = ad5624r_attributes,
 };
 
+static const struct iio_info ad5624r_info = {
+	.attrs = &ad5624r_attribute_group,
+	.driver_module = THIS_MODULE,
+};
+
 static int __devinit ad5624r_probe(struct spi_device *spi)
 {
 	struct ad5624r_state *st;
@@ -260,15 +253,15 @@
 		st->vref_mv = st->chip_info->int_vref_mv;
 
 	st->us = spi;
-	st->indio_dev = iio_allocate_device();
+	st->indio_dev = iio_allocate_device(0);
 	if (st->indio_dev == NULL) {
 		ret = -ENOMEM;
 		goto error_disable_reg;
 	}
 	st->indio_dev->dev.parent = &spi->dev;
-	st->indio_dev->attrs = &ad5624r_attribute_group;
+	st->indio_dev->name = spi_get_device_id(spi)->name;
+	st->indio_dev->info = &ad5624r_info;
 	st->indio_dev->dev_data = (void *)(st);
-	st->indio_dev->driver_module = THIS_MODULE;
 	st->indio_dev->modes = INDIO_DIRECT_MODE;
 
 	ret = iio_device_register(st->indio_dev);
diff -druN linux-2.6.39-libre/drivers/staging/iio/dac/ad5791.c linux-3.0-rc7-libre/drivers/staging/iio/dac/ad5791.c
--- linux-2.6.39-libre/drivers/staging/iio/dac/ad5791.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/staging/iio/dac/ad5791.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,444 @@
+/*
+ * AD5760, AD5780, AD5781, AD5791 Voltage Output Digital to Analog Converter
+ *
+ * Copyright 2011 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2.
+ */
+
+#include <linux/interrupt.h>
+#include <linux/gpio.h>
+#include <linux/fs.h>
+#include <linux/device.h>
+#include <linux/kernel.h>
+#include <linux/spi/spi.h>
+#include <linux/slab.h>
+#include <linux/sysfs.h>
+#include <linux/regulator/consumer.h>
+
+#include "../iio.h"
+#include "../sysfs.h"
+#include "dac.h"
+#include "ad5791.h"
+
+static int ad5791_spi_write(struct spi_device *spi, u8 addr, u32 val)
+{
+	union {
+		u32 d32;
+		u8 d8[4];
+	} data;
+
+	data.d32 = cpu_to_be32(AD5791_CMD_WRITE |
+			      AD5791_ADDR(addr) |
+			      (val & AD5791_DAC_MASK));
+
+	return spi_write(spi, &data.d8[1], 3);
+}
+
+static int ad5791_spi_read(struct spi_device *spi, u8 addr, u32 *val)
+{
+	union {
+		u32 d32;
+		u8 d8[4];
+	} data[3];
+	int ret;
+	struct spi_message msg;
+	struct spi_transfer xfers[] = {
+		{
+			.tx_buf = &data[0].d8[1],
+			.bits_per_word = 8,
+			.len = 3,
+			.cs_change = 1,
+		}, {
+			.tx_buf = &data[1].d8[1],
+			.rx_buf = &data[2].d8[1],
+			.bits_per_word = 8,
+			.len = 3,
+		},
+	};
+
+	data[0].d32 = cpu_to_be32(AD5791_CMD_READ |
+			      AD5791_ADDR(addr));
+	data[1].d32 = cpu_to_be32(AD5791_ADDR(AD5791_ADDR_NOOP));
+
+	spi_message_init(&msg);
+	spi_message_add_tail(&xfers[0], &msg);
+	spi_message_add_tail(&xfers[1], &msg);
+	ret = spi_sync(spi, &msg);
+
+	*val = be32_to_cpu(data[2].d32);
+
+	return ret;
+}
+
+static ssize_t ad5791_write_dac(struct device *dev,
+				 struct device_attribute *attr,
+				 const char *buf, size_t len)
+{
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct ad5791_state *st = iio_dev_get_devdata(indio_dev);
+	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
+	long readin;
+	int ret;
+
+	ret = strict_strtol(buf, 10, &readin);
+	if (ret)
+		return ret;
+
+	readin += (1 << (st->chip_info->bits - 1));
+	readin &= AD5791_RES_MASK(st->chip_info->bits);
+	readin <<= st->chip_info->left_shift;
+
+	ret = ad5791_spi_write(st->spi, this_attr->address, readin);
+	return ret ? ret : len;
+}
+
+static ssize_t ad5791_read_dac(struct device *dev,
+					   struct device_attribute *attr,
+					   char *buf)
+{
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct ad5791_state *st = iio_dev_get_devdata(indio_dev);
+	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
+	int ret;
+	int val;
+
+	ret = ad5791_spi_read(st->spi, this_attr->address, &val);
+	if (ret)
+		return ret;
+
+	val &= AD5791_DAC_MASK;
+	val >>= st->chip_info->left_shift;
+	val -= (1 << (st->chip_info->bits - 1));
+
+	return sprintf(buf, "%d\n", val);
+}
+
+static ssize_t ad5791_read_powerdown_mode(struct device *dev,
+				      struct device_attribute *attr, char *buf)
+{
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct ad5791_state *st = iio_dev_get_devdata(indio_dev);
+
+	const char mode[][14] = {"6kohm_to_gnd", "three_state"};
+
+	return sprintf(buf, "%s\n", mode[st->pwr_down_mode]);
+}
+
+static ssize_t ad5791_write_powerdown_mode(struct device *dev,
+				       struct device_attribute *attr,
+				       const char *buf, size_t len)
+{
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct ad5791_state *st = iio_dev_get_devdata(indio_dev);
+	int ret;
+
+	if (sysfs_streq(buf, "6kohm_to_gnd"))
+		st->pwr_down_mode = AD5791_DAC_PWRDN_6K;
+	else if (sysfs_streq(buf, "three_state"))
+		st->pwr_down_mode = AD5791_DAC_PWRDN_3STATE;
+	else
+		ret = -EINVAL;
+
+	return ret ? ret : len;
+}
+
+static ssize_t ad5791_read_dac_powerdown(struct device *dev,
+					   struct device_attribute *attr,
+					   char *buf)
+{
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct ad5791_state *st = iio_dev_get_devdata(indio_dev);
+
+	return sprintf(buf, "%d\n", st->pwr_down);
+}
+
+static ssize_t ad5791_write_dac_powerdown(struct device *dev,
+					    struct device_attribute *attr,
+					    const char *buf, size_t len)
+{
+	long readin;
+	int ret;
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct ad5791_state *st = iio_dev_get_devdata(indio_dev);
+
+	ret = strict_strtol(buf, 10, &readin);
+	if (ret)
+		return ret;
+
+	if (readin == 0) {
+		st->pwr_down = false;
+		st->ctrl &= ~(AD5791_CTRL_OPGND | AD5791_CTRL_DACTRI);
+	} else if (readin == 1) {
+		st->pwr_down = true;
+		if (st->pwr_down_mode == AD5791_DAC_PWRDN_6K)
+			st->ctrl |= AD5791_CTRL_OPGND;
+		else if (st->pwr_down_mode == AD5791_DAC_PWRDN_3STATE)
+			st->ctrl |= AD5791_CTRL_DACTRI;
+	} else
+		ret = -EINVAL;
+
+	ret = ad5791_spi_write(st->spi, AD5791_ADDR_CTRL, st->ctrl);
+
+	return ret ? ret : len;
+}
+
+static ssize_t ad5791_show_scale(struct device *dev,
+				struct device_attribute *attr,
+				char *buf)
+{
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct ad5791_state *st = iio_dev_get_devdata(indio_dev);
+	/* Corresponds to Vref / 2^(bits) */
+	unsigned int scale_uv = (st->vref_mv * 1000) >> st->chip_info->bits;
+
+	return sprintf(buf, "%d.%03d\n", scale_uv / 1000, scale_uv % 1000);
+}
+static IIO_DEVICE_ATTR(out_scale, S_IRUGO, ad5791_show_scale, NULL, 0);
+
+static ssize_t ad5791_show_name(struct device *dev,
+				 struct device_attribute *attr,
+				 char *buf)
+{
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct ad5791_state *st = iio_dev_get_devdata(indio_dev);
+
+	return sprintf(buf, "%s\n", spi_get_device_id(st->spi)->name);
+}
+static IIO_DEVICE_ATTR(name, S_IRUGO, ad5791_show_name, NULL, 0);
+
+#define IIO_DEV_ATTR_OUT_RW_RAW(_num, _show, _store, _addr)		\
+	IIO_DEVICE_ATTR(out##_num##_raw,				\
+			S_IRUGO | S_IWUSR, _show, _store, _addr)
+
+static IIO_DEV_ATTR_OUT_RW_RAW(0, ad5791_read_dac,
+	ad5791_write_dac, AD5791_ADDR_DAC0);
+
+static IIO_DEVICE_ATTR(out_powerdown_mode, S_IRUGO |
+			S_IWUSR, ad5791_read_powerdown_mode,
+			ad5791_write_powerdown_mode, 0);
+
+static IIO_CONST_ATTR(out_powerdown_mode_available,
+			"6kohm_to_gnd three_state");
+
+#define IIO_DEV_ATTR_DAC_POWERDOWN(_num, _show, _store, _addr)		\
+	IIO_DEVICE_ATTR(out##_num##_powerdown,				\
+			S_IRUGO | S_IWUSR, _show, _store, _addr)
+
+static IIO_DEV_ATTR_DAC_POWERDOWN(0, ad5791_read_dac_powerdown,
+				   ad5791_write_dac_powerdown, 0);
+
+static struct attribute *ad5791_attributes[] = {
+	&iio_dev_attr_out0_raw.dev_attr.attr,
+	&iio_dev_attr_out0_powerdown.dev_attr.attr,
+	&iio_dev_attr_out_powerdown_mode.dev_attr.attr,
+	&iio_const_attr_out_powerdown_mode_available.dev_attr.attr,
+	&iio_dev_attr_out_scale.dev_attr.attr,
+	&iio_dev_attr_name.dev_attr.attr,
+	NULL,
+};
+
+static const struct attribute_group ad5791_attribute_group = {
+	.attrs = ad5791_attributes,
+};
+
+static int ad5791_get_lin_comp(unsigned int span)
+{
+	if (span <= 10000)
+		return AD5791_LINCOMP_0_10;
+	else if (span <= 12000)
+		return AD5791_LINCOMP_10_12;
+	else if (span <= 16000)
+		return AD5791_LINCOMP_12_16;
+	else if (span <= 19000)
+		return AD5791_LINCOMP_16_19;
+	else
+		return AD5791_LINCOMP_19_20;
+}
+
+static int ad5780_get_lin_comp(unsigned int span)
+{
+	if (span <= 10000)
+		return AD5780_LINCOMP_0_10;
+	else
+		return AD5780_LINCOMP_10_20;
+}
+
+static const struct ad5791_chip_info ad5791_chip_info_tbl[] = {
+	[ID_AD5760] = {
+		.bits = 16,
+		.left_shift = 4,
+		.get_lin_comp = ad5780_get_lin_comp,
+	},
+	[ID_AD5780] = {
+		.bits = 18,
+		.left_shift = 2,
+		.get_lin_comp = ad5780_get_lin_comp,
+	},
+	[ID_AD5781] = {
+		.bits = 18,
+		.left_shift = 2,
+		.get_lin_comp = ad5791_get_lin_comp,
+	},
+	[ID_AD5791] = {
+		.bits = 20,
+		.left_shift = 0,
+		.get_lin_comp = ad5791_get_lin_comp,
+	},
+};
+
+static const struct iio_info ad5791_info = {
+	.attrs = &ad5791_attribute_group,
+	.driver_module = THIS_MODULE,
+};
+
+static int __devinit ad5791_probe(struct spi_device *spi)
+{
+	struct ad5791_platform_data *pdata = spi->dev.platform_data;
+	struct ad5791_state *st;
+	int ret, pos_voltage_uv = 0, neg_voltage_uv = 0;
+
+	st = kzalloc(sizeof(*st), GFP_KERNEL);
+	if (st == NULL) {
+		ret = -ENOMEM;
+		goto error_ret;
+	}
+
+	spi_set_drvdata(spi, st);
+
+	st->reg_vdd = regulator_get(&spi->dev, "vdd");
+	if (!IS_ERR(st->reg_vdd)) {
+		ret = regulator_enable(st->reg_vdd);
+		if (ret)
+			goto error_put_reg_pos;
+
+		pos_voltage_uv = regulator_get_voltage(st->reg_vdd);
+	}
+
+	st->reg_vss = regulator_get(&spi->dev, "vss");
+	if (!IS_ERR(st->reg_vss)) {
+		ret = regulator_enable(st->reg_vss);
+		if (ret)
+			goto error_put_reg_neg;
+
+		neg_voltage_uv = regulator_get_voltage(st->reg_vss);
+	}
+
+	if (!IS_ERR(st->reg_vss) && !IS_ERR(st->reg_vdd))
+		st->vref_mv = (pos_voltage_uv - neg_voltage_uv) / 1000;
+	else if (pdata)
+		st->vref_mv = pdata->vref_pos_mv - pdata->vref_neg_mv;
+	else
+		dev_warn(&spi->dev, "reference voltage unspecified\n");
+
+	ret = ad5791_spi_write(spi, AD5791_ADDR_SW_CTRL, AD5791_SWCTRL_RESET);
+	if (ret)
+		goto error_disable_reg_neg;
+
+	st->chip_info =
+		&ad5791_chip_info_tbl[spi_get_device_id(spi)->driver_data];
+
+
+	st->ctrl = AD5761_CTRL_LINCOMP(st->chip_info->get_lin_comp(st->vref_mv))
+		  | ((pdata && pdata->use_rbuf_gain2) ? 0 : AD5791_CTRL_RBUF) |
+		  AD5791_CTRL_BIN2SC;
+
+	ret = ad5791_spi_write(spi, AD5791_ADDR_CTRL, st->ctrl |
+		AD5791_CTRL_OPGND | AD5791_CTRL_DACTRI);
+	if (ret)
+		goto error_disable_reg_neg;
+
+	st->pwr_down = true;
+
+	st->spi = spi;
+	st->indio_dev = iio_allocate_device(0);
+	if (st->indio_dev == NULL) {
+		ret = -ENOMEM;
+		goto error_disable_reg_neg;
+	}
+	st->indio_dev->dev.parent = &spi->dev;
+	st->indio_dev->dev_data = (void *)(st);
+	st->indio_dev->info = &ad5791_info;
+	st->indio_dev->modes = INDIO_DIRECT_MODE;
+
+	ret = iio_device_register(st->indio_dev);
+	if (ret)
+		goto error_free_dev;
+
+	return 0;
+
+error_free_dev:
+	iio_free_device(st->indio_dev);
+
+error_disable_reg_neg:
+	if (!IS_ERR(st->reg_vss))
+		regulator_disable(st->reg_vss);
+error_put_reg_neg:
+	if (!IS_ERR(st->reg_vss))
+		regulator_put(st->reg_vss);
+
+	if (!IS_ERR(st->reg_vdd))
+		regulator_disable(st->reg_vdd);
+error_put_reg_pos:
+	if (!IS_ERR(st->reg_vdd))
+		regulator_put(st->reg_vdd);
+
+	kfree(st);
+error_ret:
+	return ret;
+}
+
+static int __devexit ad5791_remove(struct spi_device *spi)
+{
+	struct ad5791_state *st = spi_get_drvdata(spi);
+
+	iio_device_unregister(st->indio_dev);
+
+	if (!IS_ERR(st->reg_vdd)) {
+		regulator_disable(st->reg_vdd);
+		regulator_put(st->reg_vdd);
+	}
+
+	if (!IS_ERR(st->reg_vss)) {
+		regulator_disable(st->reg_vss);
+		regulator_put(st->reg_vss);
+	}
+
+	kfree(st);
+
+	return 0;
+}
+
+static const struct spi_device_id ad5791_id[] = {
+	{"ad5760", ID_AD5760},
+	{"ad5780", ID_AD5780},
+	{"ad5781", ID_AD5781},
+	{"ad5791", ID_AD5791},
+	{}
+};
+
+static struct spi_driver ad5791_driver = {
+	.driver = {
+		   .name = "ad5791",
+		   .owner = THIS_MODULE,
+		   },
+	.probe = ad5791_probe,
+	.remove = __devexit_p(ad5791_remove),
+	.id_table = ad5791_id,
+};
+
+static __init int ad5791_spi_init(void)
+{
+	return spi_register_driver(&ad5791_driver);
+}
+module_init(ad5791_spi_init);
+
+static __exit void ad5791_spi_exit(void)
+{
+	spi_unregister_driver(&ad5791_driver);
+}
+module_exit(ad5791_spi_exit);
+
+MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>");
+MODULE_DESCRIPTION("Analog Devices AD5760/AD5780/AD5781/AD5791 DAC");
+MODULE_LICENSE("GPL v2");
diff -druN linux-2.6.39-libre/drivers/staging/iio/dac/ad5791.h linux-3.0-rc7-libre/drivers/staging/iio/dac/ad5791.h
--- linux-2.6.39-libre/drivers/staging/iio/dac/ad5791.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/staging/iio/dac/ad5791.h	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,116 @@
+/*
+ * AD5791 SPI DAC driver
+ *
+ * Copyright 2011 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2.
+ */
+
+#ifndef SPI_AD5791_H_
+#define SPI_AD5791_H_
+
+#define AD5791_RES_MASK(x)		((1 << (x)) - 1)
+#define AD5791_DAC_MASK			AD5791_RES_MASK(20)
+#define AD5791_DAC_MSB			(1 << 19)
+
+#define AD5791_CMD_READ			(1 << 23)
+#define AD5791_CMD_WRITE		(0 << 23)
+#define AD5791_ADDR(addr)		((addr) << 20)
+
+/* Registers */
+#define AD5791_ADDR_NOOP		0
+#define AD5791_ADDR_DAC0		1
+#define AD5791_ADDR_CTRL		2
+#define AD5791_ADDR_CLRCODE		3
+#define AD5791_ADDR_SW_CTRL		4
+
+/* Control Register */
+#define AD5791_CTRL_RBUF		(1 << 1)
+#define AD5791_CTRL_OPGND		(1 << 2)
+#define AD5791_CTRL_DACTRI		(1 << 3)
+#define AD5791_CTRL_BIN2SC		(1 << 4)
+#define AD5791_CTRL_SDODIS		(1 << 5)
+#define AD5761_CTRL_LINCOMP(x)		((x) << 6)
+
+#define AD5791_LINCOMP_0_10		0
+#define AD5791_LINCOMP_10_12		1
+#define AD5791_LINCOMP_12_16		2
+#define AD5791_LINCOMP_16_19		3
+#define AD5791_LINCOMP_19_20		12
+
+#define AD5780_LINCOMP_0_10		0
+#define AD5780_LINCOMP_10_20		12
+
+/* Software Control Register */
+#define AD5791_SWCTRL_LDAC		(1 << 0)
+#define AD5791_SWCTRL_CLR		(1 << 1)
+#define AD5791_SWCTRL_RESET		(1 << 2)
+
+#define AD5791_DAC_PWRDN_6K		0
+#define AD5791_DAC_PWRDN_3STATE		1
+
+/*
+ * TODO: struct ad5791_platform_data needs to go into include/linux/iio
+ */
+
+/**
+ * struct ad5791_platform_data - platform specific information
+ * @vref_pos_mv:	Vdd Positive Analog Supply Volatge (mV)
+ * @vref_neg_mv:	Vdd Negative Analog Supply Volatge (mV)
+ * @use_rbuf_gain2:	ext. amplifier connected in gain of two configuration
+ */
+
+struct ad5791_platform_data {
+	u16				vref_pos_mv;
+	u16				vref_neg_mv;
+	bool				use_rbuf_gain2;
+};
+
+/**
+ * struct ad5791_chip_info - chip specific information
+ * @bits:		accuracy of the DAC in bits
+ * @left_shift:		number of bits the datum must be shifted
+ * @get_lin_comp:	function pointer to the device specific function
+ */
+
+struct ad5791_chip_info {
+	u8			bits;
+	u8			left_shift;
+	int (*get_lin_comp)	(unsigned int span);
+};
+
+/**
+ * struct ad5791_state - driver instance specific data
+ * @indio_dev:		the industrial I/O device
+ * @us:			spi_device
+ * @reg_vdd:		positive supply regulator
+ * @reg_vss:		negative supply regulator
+ * @chip_info:		chip model specific constants
+ * @vref_mv:		actual reference voltage used
+ * @pwr_down_mode	current power down mode
+ */
+
+struct ad5791_state {
+	struct iio_dev			*indio_dev;
+	struct spi_device		*spi;
+	struct regulator		*reg_vdd;
+	struct regulator		*reg_vss;
+	const struct ad5791_chip_info	*chip_info;
+	unsigned short			vref_mv;
+	unsigned			ctrl;
+	unsigned			pwr_down_mode;
+	bool				pwr_down;
+};
+
+/**
+ * ad5791_supported_device_ids:
+ */
+
+enum ad5791_supported_device_ids {
+	ID_AD5760,
+	ID_AD5780,
+	ID_AD5781,
+	ID_AD5791,
+};
+
+#endif /* SPI_AD5791_H_ */
diff -druN linux-2.6.39-libre/drivers/staging/iio/dac/Kconfig linux-3.0-rc7-libre/drivers/staging/iio/dac/Kconfig
--- linux-2.6.39-libre/drivers/staging/iio/dac/Kconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/iio/dac/Kconfig	2011-07-11 19:51:52.000000000 -0400
@@ -21,6 +21,27 @@
 	  To compile this driver as a module, choose M here: the
 	  module will be called ad5446.
 
+config AD5504
+	tristate "Analog Devices AD5504/AD5501 DAC SPI driver"
+	depends on SPI
+	help
+	  Say yes here to build support for Analog Devices AD5504, AD5501,
+	  High Voltage Digital to Analog Converter.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called ad5504.
+
+config AD5791
+	tristate "Analog Devices AD5760/AD5780/AD5781/AD5791 DAC SPI driver"
+	depends on SPI
+	help
+	  Say yes here to build support for Analog Devices AD5760, AD5780,
+	  AD5781, AD5791 High Resolution Voltage Output Digital to
+	  Analog Converter.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called ad5791.
+
 config MAX517
 	tristate "Maxim MAX517/518/519 DAC driver"
 	depends on I2C && EXPERIMENTAL
diff -druN linux-2.6.39-libre/drivers/staging/iio/dac/Makefile linux-3.0-rc7-libre/drivers/staging/iio/dac/Makefile
--- linux-2.6.39-libre/drivers/staging/iio/dac/Makefile	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/iio/dac/Makefile	2011-07-11 19:51:52.000000000 -0400
@@ -3,5 +3,7 @@
 #
 
 obj-$(CONFIG_AD5624R_SPI) += ad5624r_spi.o
+obj-$(CONFIG_AD5504) += ad5504.o
 obj-$(CONFIG_AD5446) += ad5446.o
+obj-$(CONFIG_AD5791) += ad5791.o
 obj-$(CONFIG_MAX517) += max517.o
diff -druN linux-2.6.39-libre/drivers/staging/iio/dac/max517.c linux-3.0-rc7-libre/drivers/staging/iio/dac/max517.c
--- linux-2.6.39-libre/drivers/staging/iio/dac/max517.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/iio/dac/max517.c	2011-07-11 19:51:52.000000000 -0400
@@ -189,6 +189,16 @@
 	return i2c_master_send(client, &outbuf, 1);
 }
 
+static const struct iio_info max517_info = {
+	.attrs = &max517_attribute_group,
+	.driver_module = THIS_MODULE,
+};
+
+static const struct iio_info max518_info = {
+	.attrs = &max518_attribute_group,
+	.driver_module = THIS_MODULE,
+};
+
 static int max517_probe(struct i2c_client *client,
 			const struct i2c_device_id *id)
 {
@@ -206,7 +216,7 @@
 
 	data->client = client;
 
-	data->indio_dev = iio_allocate_device();
+	data->indio_dev = iio_allocate_device(0);
 	if (data->indio_dev == NULL) {
 		err = -ENOMEM;
 		goto exit_free_data;
@@ -217,11 +227,10 @@
 
 	/* reduced attribute set for MAX517 */
 	if (id->driver_data == ID_MAX517)
-		data->indio_dev->attrs = &max517_attribute_group;
+		data->indio_dev->info = &max517_info;
 	else
-		data->indio_dev->attrs = &max518_attribute_group;
+		data->indio_dev->info = &max518_info;
 	data->indio_dev->dev_data = (void *)(data);
-	data->indio_dev->driver_module = THIS_MODULE;
 	data->indio_dev->modes = INDIO_DIRECT_MODE;
 
 	/*
diff -druN linux-2.6.39-libre/drivers/staging/iio/dds/ad5930.c linux-3.0-rc7-libre/drivers/staging/iio/dds/ad5930.c
--- linux-2.6.39-libre/drivers/staging/iio/dds/ad5930.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/iio/dds/ad5930.c	2011-07-11 19:51:52.000000000 -0400
@@ -87,6 +87,12 @@
 	.attrs = ad5930_attributes,
 };
 
+static const struct iio_info ad5930_info = {
+	.attrs = &ad5930_attribute_group,
+
+	.driver_module = THIS_MODULE,
+};
+
 static int __devinit ad5930_probe(struct spi_device *spi)
 {
 	struct ad5930_state *st;
@@ -102,18 +108,14 @@
 	mutex_init(&st->lock);
 	st->sdev = spi;
 
-	st->idev = iio_allocate_device();
+	st->idev = iio_allocate_device(0);
 	if (st->idev == NULL) {
 		ret = -ENOMEM;
 		goto error_free_st;
 	}
 	st->idev->dev.parent = &spi->dev;
-	st->idev->num_interrupt_lines = 0;
-	st->idev->event_attrs = NULL;
-
-	st->idev->attrs = &ad5930_attribute_group;
 	st->idev->dev_data = (void *)(st);
-	st->idev->driver_module = THIS_MODULE;
+	st->idev->info = &ad5930_info;
 	st->idev->modes = INDIO_DIRECT_MODE;
 
 	ret = iio_device_register(st->idev);
diff -druN linux-2.6.39-libre/drivers/staging/iio/dds/ad9832.c linux-3.0-rc7-libre/drivers/staging/iio/dds/ad9832.c
--- linux-2.6.39-libre/drivers/staging/iio/dds/ad9832.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/iio/dds/ad9832.c	2011-07-11 19:51:52.000000000 -0400
@@ -153,17 +153,6 @@
 	return ret ? ret : len;
 }
 
-static ssize_t ad9832_show_name(struct device *dev,
-				 struct device_attribute *attr,
-				 char *buf)
-{
-	struct iio_dev *dev_info = dev_get_drvdata(dev);
-	struct ad9832_state *st = iio_dev_get_devdata(dev_info);
-
-	return sprintf(buf, "%s\n", spi_get_device_id(st->spi)->name);
-}
-static IIO_DEVICE_ATTR(name, S_IRUGO, ad9832_show_name, NULL, 0);
-
 /**
  * see dds.h for further information
  */
@@ -199,7 +188,6 @@
 	&iio_dev_attr_dds0_freqsymbol.dev_attr.attr,
 	&iio_dev_attr_dds0_phasesymbol.dev_attr.attr,
 	&iio_dev_attr_dds0_out_enable.dev_attr.attr,
-	&iio_dev_attr_name.dev_attr.attr,
 	NULL,
 };
 
@@ -207,6 +195,11 @@
 	.attrs = ad9832_attributes,
 };
 
+static const struct iio_info ad9832_info = {
+	.attrs = &ad9832_attribute_group,
+	.driver_module = THIS_MODULE,
+};
+
 static int __devinit ad9832_probe(struct spi_device *spi)
 {
 	struct ad9832_platform_data *pdata = spi->dev.platform_data;
@@ -236,16 +229,16 @@
 	spi_set_drvdata(spi, st);
 	st->spi = spi;
 
-	st->indio_dev = iio_allocate_device();
+	st->indio_dev = iio_allocate_device(0);
 	if (st->indio_dev == NULL) {
 		ret = -ENOMEM;
 		goto error_disable_reg;
 	}
 
 	st->indio_dev->dev.parent = &spi->dev;
-	st->indio_dev->attrs = &ad9832_attribute_group;
+	st->indio_dev->name = spi_get_device_id(spi)->name;
+	st->indio_dev->info = &ad9832_info;
 	st->indio_dev->dev_data = (void *) st;
-	st->indio_dev->driver_module = THIS_MODULE;
 	st->indio_dev->modes = INDIO_DIRECT_MODE;
 
 	/* Setup default messages */
diff -druN linux-2.6.39-libre/drivers/staging/iio/dds/ad9834.c linux-3.0-rc7-libre/drivers/staging/iio/dds/ad9834.c
--- linux-2.6.39-libre/drivers/staging/iio/dds/ad9834.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/iio/dds/ad9834.c	2011-07-11 19:51:52.000000000 -0400
@@ -1,9 +1,9 @@
 /*
- * AD9834 SPI DAC driver
+ * AD9833/AD9834/AD9837/AD9838 SPI DDS driver
  *
- * Copyright 2010 Analog Devices Inc.
+ * Copyright 2010-2011 Analog Devices Inc.
  *
- * Licensed under the GPL-2 or later.
+ * Licensed under the GPL-2.
  */
 
 #include <linux/interrupt.h>
@@ -47,7 +47,7 @@
 				       (AD9834_FREQ_BITS / 2)) &
 				       RES_MASK(AD9834_FREQ_BITS / 2)));
 
-	return spi_sync(st->spi, &st->freq_msg);;
+	return spi_sync(st->spi, &st->freq_msg);
 }
 
 static int ad9834_write_phase(struct ad9834_state *st,
@@ -148,7 +148,7 @@
 	struct ad9834_state *st = dev_info->dev_data;
 	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
 	int ret = 0;
-	bool is_ad9833 = st->devid == ID_AD9833;
+	bool is_ad9833_7 = (st->devid == ID_AD9833) || (st->devid == ID_AD9837);
 
 	mutex_lock(&dev_info->mlock);
 
@@ -156,10 +156,10 @@
 	case 0:
 		if (sysfs_streq(buf, "sine")) {
 			st->control &= ~AD9834_MODE;
-			if (is_ad9833)
+			if (is_ad9833_7)
 				st->control &= ~AD9834_OPBITEN;
 		} else if (sysfs_streq(buf, "triangle")) {
-			if (is_ad9833) {
+			if (is_ad9833_7) {
 				st->control &= ~AD9834_OPBITEN;
 				st->control |= AD9834_MODE;
 			} else if (st->control & AD9834_OPBITEN) {
@@ -167,7 +167,7 @@
 			} else {
 				st->control |= AD9834_MODE;
 			}
-		} else if (is_ad9833 && sysfs_streq(buf, "square")) {
+		} else if (is_ad9833_7 && sysfs_streq(buf, "square")) {
 			st->control &= ~AD9834_MODE;
 			st->control |= AD9834_OPBITEN;
 		} else {
@@ -198,17 +198,6 @@
 	return ret ? ret : len;
 }
 
-static ssize_t ad9834_show_name(struct device *dev,
-				 struct device_attribute *attr,
-				 char *buf)
-{
-	struct iio_dev *dev_info = dev_get_drvdata(dev);
-	struct ad9834_state *st = iio_dev_get_devdata(dev_info);
-
-	return sprintf(buf, "%s\n", spi_get_device_id(st->spi)->name);
-}
-static IIO_DEVICE_ATTR(name, S_IRUGO, ad9834_show_name, NULL, 0);
-
 static ssize_t ad9834_show_out0_wavetype_available(struct device *dev,
 						struct device_attribute *attr,
 						char *buf)
@@ -217,7 +206,7 @@
 	struct ad9834_state *st = iio_dev_get_devdata(dev_info);
 	char *str;
 
-	if (st->devid == ID_AD9833)
+	if ((st->devid == ID_AD9833) || (st->devid == ID_AD9837))
 		str = "sine triangle square";
 	else if (st->control & AD9834_OPBITEN)
 		str = "sine";
@@ -288,7 +277,6 @@
 	&iio_dev_attr_dds0_out1_wavetype.dev_attr.attr,
 	&iio_dev_attr_dds0_out0_wavetype_available.dev_attr.attr,
 	&iio_dev_attr_dds0_out1_wavetype_available.dev_attr.attr,
-	&iio_dev_attr_name.dev_attr.attr,
 	NULL,
 };
 
@@ -301,13 +289,12 @@
 
 	mode_t mode = attr->mode;
 
-	if (st->devid == ID_AD9834)
-		return mode;
-
-	if ((attr == &iio_dev_attr_dds0_out1_enable.dev_attr.attr) ||
+	if (((st->devid == ID_AD9833) || (st->devid == ID_AD9837)) &&
+		((attr == &iio_dev_attr_dds0_out1_enable.dev_attr.attr) ||
 		(attr == &iio_dev_attr_dds0_out1_wavetype.dev_attr.attr) ||
 		(attr ==
-		&iio_dev_attr_dds0_out1_wavetype_available.dev_attr.attr))
+		&iio_dev_attr_dds0_out1_wavetype_available.dev_attr.attr) ||
+		(attr == &iio_dev_attr_dds0_pincontrol_en.dev_attr.attr)))
 		mode = 0;
 
 	return mode;
@@ -318,6 +305,11 @@
 	.is_visible = ad9834_attr_is_visible,
 };
 
+static const struct iio_info ad9834_info = {
+	.attrs = &ad9834_attribute_group,
+	.driver_module = THIS_MODULE,
+};
+
 static int __devinit ad9834_probe(struct spi_device *spi)
 {
 	struct ad9834_platform_data *pdata = spi->dev.platform_data;
@@ -349,16 +341,16 @@
 	st->spi = spi;
 	st->devid = spi_get_device_id(spi)->driver_data;
 
-	st->indio_dev = iio_allocate_device();
+	st->indio_dev = iio_allocate_device(0);
 	if (st->indio_dev == NULL) {
 		ret = -ENOMEM;
 		goto error_disable_reg;
 	}
 
 	st->indio_dev->dev.parent = &spi->dev;
-	st->indio_dev->attrs = &ad9834_attribute_group;
+	st->indio_dev->name = spi_get_device_id(spi)->name;
+	st->indio_dev->info = &ad9834_info;
 	st->indio_dev->dev_data = (void *) st;
-	st->indio_dev->driver_module = THIS_MODULE;
 	st->indio_dev->modes = INDIO_DIRECT_MODE;
 
 	/* Setup default messages */
@@ -445,6 +437,8 @@
 static const struct spi_device_id ad9834_id[] = {
 	{"ad9833", ID_AD9833},
 	{"ad9834", ID_AD9834},
+	{"ad9837", ID_AD9837},
+	{"ad9838", ID_AD9838},
 	{}
 };
 
@@ -472,6 +466,6 @@
 module_exit(ad9834_exit);
 
 MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>");
-MODULE_DESCRIPTION("Analog Devices AD9833/AD9834 DDS");
+MODULE_DESCRIPTION("Analog Devices AD9833/AD9834/AD9837/AD9838 DDS");
 MODULE_LICENSE("GPL v2");
 MODULE_ALIAS("spi:ad9834");
diff -druN linux-2.6.39-libre/drivers/staging/iio/dds/ad9834.h linux-3.0-rc7-libre/drivers/staging/iio/dds/ad9834.h
--- linux-2.6.39-libre/drivers/staging/iio/dds/ad9834.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/iio/dds/ad9834.h	2011-07-11 19:51:52.000000000 -0400
@@ -1,9 +1,9 @@
 /*
- * AD9834 SPI DDS driver
+ * AD9833/AD9834/AD9837/AD9838 SPI DDS driver
  *
- * Copyright 2010 Analog Devices Inc.
+ * Copyright 2010-2011 Analog Devices Inc.
  *
- * Licensed under the GPL-2 or later.
+ * Licensed under the GPL-2.
  */
 #ifndef IIO_DDS_AD9834_H_
 #define IIO_DDS_AD9834_H_
@@ -107,6 +107,8 @@
 enum ad9834_supported_device_ids {
 	ID_AD9833,
 	ID_AD9834,
+	ID_AD9837,
+	ID_AD9838,
 };
 
 #endif /* IIO_DDS_AD9834_H_ */
diff -druN linux-2.6.39-libre/drivers/staging/iio/dds/ad9850.c linux-3.0-rc7-libre/drivers/staging/iio/dds/ad9850.c
--- linux-2.6.39-libre/drivers/staging/iio/dds/ad9850.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/iio/dds/ad9850.c	2011-07-11 19:51:52.000000000 -0400
@@ -73,6 +73,11 @@
 	.attrs = ad9850_attributes,
 };
 
+static const struct iio_info ad9850_info = {
+	.attrs = &ad9850_attribute_group,
+	.driver_module = THIS_MODULE,
+};
+
 static int __devinit ad9850_probe(struct spi_device *spi)
 {
 	struct ad9850_state *st;
@@ -88,18 +93,15 @@
 	mutex_init(&st->lock);
 	st->sdev = spi;
 
-	st->idev = iio_allocate_device();
+	st->idev = iio_allocate_device(0);
 	if (st->idev == NULL) {
 		ret = -ENOMEM;
 		goto error_free_st;
 	}
 	st->idev->dev.parent = &spi->dev;
-	st->idev->num_interrupt_lines = 0;
-	st->idev->event_attrs = NULL;
 
-	st->idev->attrs = &ad9850_attribute_group;
+	st->idev->info = &ad9850_info;
 	st->idev->dev_data = (void *)(st);
-	st->idev->driver_module = THIS_MODULE;
 	st->idev->modes = INDIO_DIRECT_MODE;
 
 	ret = iio_device_register(st->idev);
diff -druN linux-2.6.39-libre/drivers/staging/iio/dds/ad9852.c linux-3.0-rc7-libre/drivers/staging/iio/dds/ad9852.c
--- linux-2.6.39-libre/drivers/staging/iio/dds/ad9852.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/iio/dds/ad9852.c	2011-07-11 19:51:52.000000000 -0400
@@ -222,6 +222,11 @@
 	.attrs = ad9852_attributes,
 };
 
+static const struct iio_info ad9852_info = {
+	.attrs = &ad9852_attribute_group,
+	.driver_module = THIS_MODULE,
+};
+
 static int __devinit ad9852_probe(struct spi_device *spi)
 {
 	struct ad9852_state *st;
@@ -237,18 +242,15 @@
 	mutex_init(&st->lock);
 	st->sdev = spi;
 
-	st->idev = iio_allocate_device();
+	st->idev = iio_allocate_device(0);
 	if (st->idev == NULL) {
 		ret = -ENOMEM;
 		goto error_free_st;
 	}
 	st->idev->dev.parent = &spi->dev;
-	st->idev->num_interrupt_lines = 0;
-	st->idev->event_attrs = NULL;
 
-	st->idev->attrs = &ad9852_attribute_group;
+	st->idev->info = &ad9852_info;
 	st->idev->dev_data = (void *)(st);
-	st->idev->driver_module = THIS_MODULE;
 	st->idev->modes = INDIO_DIRECT_MODE;
 
 	ret = iio_device_register(st->idev);
diff -druN linux-2.6.39-libre/drivers/staging/iio/dds/ad9910.c linux-3.0-rc7-libre/drivers/staging/iio/dds/ad9910.c
--- linux-2.6.39-libre/drivers/staging/iio/dds/ad9910.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/iio/dds/ad9910.c	2011-07-11 19:51:52.000000000 -0400
@@ -357,6 +357,11 @@
 	.attrs = ad9910_attributes,
 };
 
+static const struct iio_info ad9910_info = {
+	.attrs = &ad9910_attribute_group,
+	.driver_module = THIS_MODULE,
+};
+
 static int __devinit ad9910_probe(struct spi_device *spi)
 {
 	struct ad9910_state *st;
@@ -372,18 +377,15 @@
 	mutex_init(&st->lock);
 	st->sdev = spi;
 
-	st->idev = iio_allocate_device();
+	st->idev = iio_allocate_device(0);
 	if (st->idev == NULL) {
 		ret = -ENOMEM;
 		goto error_free_st;
 	}
 	st->idev->dev.parent = &spi->dev;
-	st->idev->num_interrupt_lines = 0;
-	st->idev->event_attrs = NULL;
 
-	st->idev->attrs = &ad9910_attribute_group;
+	st->idev->info = &ad9910_info;
 	st->idev->dev_data = (void *)(st);
-	st->idev->driver_module = THIS_MODULE;
 	st->idev->modes = INDIO_DIRECT_MODE;
 
 	ret = iio_device_register(st->idev);
diff -druN linux-2.6.39-libre/drivers/staging/iio/dds/ad9951.c linux-3.0-rc7-libre/drivers/staging/iio/dds/ad9951.c
--- linux-2.6.39-libre/drivers/staging/iio/dds/ad9951.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/iio/dds/ad9951.c	2011-07-11 19:51:52.000000000 -0400
@@ -166,6 +166,11 @@
 	.attrs = ad9951_attributes,
 };
 
+static const struct iio_info ad9951_info = {
+	.attrs = &ad9951_attribute_group,
+	.driver_module = THIS_MODULE,
+};
+
 static int __devinit ad9951_probe(struct spi_device *spi)
 {
 	struct ad9951_state *st;
@@ -181,18 +186,15 @@
 	mutex_init(&st->lock);
 	st->sdev = spi;
 
-	st->idev = iio_allocate_device();
+	st->idev = iio_allocate_device(0);
 	if (st->idev == NULL) {
 		ret = -ENOMEM;
 		goto error_free_st;
 	}
 	st->idev->dev.parent = &spi->dev;
-	st->idev->num_interrupt_lines = 0;
-	st->idev->event_attrs = NULL;
 
-	st->idev->attrs = &ad9951_attribute_group;
+	st->idev->info = &ad9951_info;
 	st->idev->dev_data = (void *)(st);
-	st->idev->driver_module = THIS_MODULE;
 	st->idev->modes = INDIO_DIRECT_MODE;
 
 	ret = iio_device_register(st->idev);
diff -druN linux-2.6.39-libre/drivers/staging/iio/dds/Kconfig linux-3.0-rc7-libre/drivers/staging/iio/dds/Kconfig
--- linux-2.6.39-libre/drivers/staging/iio/dds/Kconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/iio/dds/Kconfig	2011-07-11 19:51:52.000000000 -0400
@@ -21,11 +21,11 @@
 	  module will be called ad9832.
 
 config AD9834
-	tristate "Analog Devices ad9833/4/ driver"
+	tristate "Analog Devices AD9833/4/7/8 driver"
 	depends on SPI
 	help
 	  Say yes here to build support for Analog Devices DDS chip
-	  AD9833 and AD9834, provides direct access via sysfs.
+	  AD9833, AD9834, AD9837 and AD9838, provides direct access via sysfs.
 
 	  To compile this driver as a module, choose M here: the
 	  module will be called ad9834.
diff -druN linux-2.6.39-libre/drivers/staging/iio/Documentation/device.txt linux-3.0-rc7-libre/drivers/staging/iio/Documentation/device.txt
--- linux-2.6.39-libre/drivers/staging/iio/Documentation/device.txt	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/iio/Documentation/device.txt	2011-07-11 19:51:52.000000000 -0400
@@ -8,34 +8,66 @@
 
 First allocate one using:
 
-struct iio_dev *indio_dev = iio_allocate_device();
-
-Then fill in the following:
-
-indio_dev->dev.parent
-  the struct device associated with the underlying hardware.
-
-indio_dev->num_interrupt_lines
-   number of event triggering hardware lines the device has.
+struct iio_dev *indio_dev = iio_allocate_device(sizeof(struct chip_state));
+where chip_state is a structure of local state data for this instance of
+the chip.
 
-indio_dev->event_attrs
-   attributes used to enable / disable hardware events - note the
-   attributes are embedded in iio_event_attr structures with an
-   associated iio_event_handler which may or may note be shared.
-   If num_interrupt_lines = 0, then no need to fill this in.
+That data can be accessed using iio_priv(struct iio_dev *)
 
-indio_dev->attrs
-   general attributes such as polled access to device channels.
+Then fill in the following:
 
-indio_dev->dev_data
-   private device specific data.
+- indio_dev->dev.parent
+	Struct device associated with the underlying hardware.
+- indio_dev->name
+	Name of the device being driven - made available as the name
+	attribute in sysfs.
 
-indio_dev->driver_module
-   typically set to THIS_MODULE. Used to specify ownership of some
-   iio created resources.
+- indio_dev->info
+	pointer to a structure with elements that tend to be fixed for
+	large sets of different parts supported by a given driver.
+	This contains:
+	* info->driver_module:
+		Set to THIS_MODULE. Used to ensure correct ownership
+		of various resources allocate by the core.
+	* info->num_interrupt_lines:
+		Number of event triggering hardware lines the device has.
+	* info->event_attrs:
+		Attributes used to enable / disable hardware events.
+	* info->attrs:
+		General device attributes. Typically used for the weird
+		and the wonderful bits not covered by the channel specification.
+	* info->read_raw:
+		Raw data reading function. Used for both raw channel access
+		and for associate parameters such as offsets and scales.
+	* info->write_raw:
+		Raw value writing function. Used for writable device values such
+		as DAC values and caliboffset.
+	* info->read_event_config:
+		Typically only set if there are some interrupt lines.  This
+		is used to read if an on sensor event detector is enabled.
+	* info->write_event_config:
+		Enable / disable an on sensor event detector.
+	* info->read_event_value:
+		Read value associated with on sensor event detectors. Note that
+		the meaning of the returned value is dependent on the event
+		type.
+	* info->write_event_value:
+		Write the value associated with on sensor event detectors. E.g.
+		a threshold above which an interrupt occurs.  Note that the
+		meaning of the value to be set is event type dependant.
 
-indio_dev->modes
-   whether direct access and / or ring buffer access is supported.
+- indio_dev->modes:
+	Specify whether direct access and / or ring buffer access is supported.
+- indio_dev->ring:
+	An optional associated buffer.
+- indio_dev->pollfunc:
+	Poll function related elements. This controls what occurs when a trigger
+	to which this device is attached sends and event.
+- indio_dev->channels:
+	Specification of device channels. Most attributes etc are built
+	form this spec.
+- indio_dev->num_channels:
+	How many channels are there?
 
 Once these are set up, a call to iio_device_register(indio_dev),
 will register the device with the iio core.
diff -druN linux-2.6.39-libre/drivers/staging/iio/Documentation/generic_buffer.c linux-3.0-rc7-libre/drivers/staging/iio/Documentation/generic_buffer.c
--- linux-2.6.39-libre/drivers/staging/iio/Documentation/generic_buffer.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/iio/Documentation/generic_buffer.c	2011-07-11 19:51:52.000000000 -0400
@@ -27,6 +27,7 @@
 #include <sys/dir.h>
 #include <linux/types.h>
 #include <string.h>
+#include <poll.h>
 #include "iio_utils.h"
 
 /**
@@ -53,6 +54,24 @@
 	return bytes;
 }
 
+void print2byte(int input, struct iio_channel_info *info)
+{
+	/* shift before conversion to avoid sign extension
+	   of left aligned data */
+	input = input >> info->shift;
+	if (info->is_signed) {
+		int16_t val = input;
+		val &= (1 << info->bits_used) - 1;
+		val = (int16_t)(val << (16 - info->bits_used)) >>
+			(16 - info->bits_used);
+		printf("%05f  ", val,
+		       (float)(val + info->offset)*info->scale);
+	} else {
+		uint16_t val = input;
+		val &= (1 << info->bits_used) - 1;
+		printf("%05f ", ((float)val + info->offset)*info->scale);
+	}
+}
 /**
  * process_scan() - print out the values in SI units
  * @data:		pointer to the start of the scan
@@ -70,25 +89,8 @@
 		switch (infoarray[k].bytes) {
 			/* only a few cases implemented so far */
 		case 2:
-			if (infoarray[k].is_signed) {
-				int16_t val = *(int16_t *)
-					(data
-					 + infoarray[k].location);
-				if ((val >> infoarray[k].bits_used) & 1)
-					val = (val & infoarray[k].mask) |
-						~infoarray[k].mask;
-				printf("%05f ", ((float)val +
-						 infoarray[k].offset)*
-				       infoarray[k].scale);
-			} else {
-				uint16_t val = *(uint16_t *)
-					(data +
-					 infoarray[k].location);
-				val = (val & infoarray[k].mask);
-				printf("%05f ", ((float)val +
-						 infoarray[k].offset)*
-				       infoarray[k].scale);
-			}
+			print2byte(*(uint16_t *)(data + infoarray[k].location),
+				   &infoarray[k]);
 			break;
 		case 8:
 			if (infoarray[k].is_signed) {
@@ -132,10 +134,9 @@
 
 	int datardytrigger = 1;
 	char *data;
-	size_t read_size;
-	struct iio_event_data dat;
+	ssize_t read_size;
 	int dev_num, trig_num;
-	char *buffer_access, *buffer_event;
+	char *buffer_access;
 	int scan_size;
 	int noevents = 0;
 	char *dummy;
@@ -210,7 +211,7 @@
 	 */
 	ret = build_channel_array(dev_dir_name, &infoarray, &num_channels);
 	if (ret) {
-		printf("Problem reading scan element information \n");
+		printf("Problem reading scan element information\n");
 		goto error_free_triggername;
 	}
 
@@ -251,54 +252,32 @@
 	}
 
 	ret = asprintf(&buffer_access,
-		       "/dev/device%d:buffer0:access0",
+		       "/dev/device%d:buffer0",
 		       dev_num);
 	if (ret < 0) {
 		ret = -ENOMEM;
 		goto error_free_data;
 	}
 
-	ret = asprintf(&buffer_event, "/dev/device%d:buffer0:event0", dev_num);
-	if (ret < 0) {
-		ret = -ENOMEM;
-		goto error_free_buffer_access;
-	}
 	/* Attempt to open non blocking the access dev */
 	fp = open(buffer_access, O_RDONLY | O_NONBLOCK);
 	if (fp == -1) { /*If it isn't there make the node */
 		printf("Failed to open %s\n", buffer_access);
 		ret = -errno;
-		goto error_free_buffer_event;
-	}
-	/* Attempt to open the event access dev (blocking this time) */
-	fp_ev = fopen(buffer_event, "rb");
-	if (fp_ev == NULL) {
-		printf("Failed to open %s\n", buffer_event);
-		ret = -errno;
-		goto error_close_buffer_access;
+		goto error_free_buffer_access;
 	}
 
 	/* Wait for events 10 times */
 	for (j = 0; j < num_loops; j++) {
 		if (!noevents) {
-			read_size = fread(&dat,
-					1,
-					sizeof(struct iio_event_data),
-					fp_ev);
-			switch (dat.id) {
-			case IIO_EVENT_CODE_RING_100_FULL:
-				toread = buf_len;
-				break;
-			case IIO_EVENT_CODE_RING_75_FULL:
-				toread = buf_len*3/4;
-				break;
-			case IIO_EVENT_CODE_RING_50_FULL:
-				toread = buf_len/2;
-				break;
-			default:
-				printf("Unexpecteded event code\n");
-				continue;
-			}
+			struct pollfd pfd = {
+				.fd = fp,
+				.events = POLLIN,
+			};
+
+			poll(&pfd, 1, -1);
+			toread = buf_len;
+
 		} else {
 			usleep(timedelay);
 			toread = 64;
@@ -320,22 +299,18 @@
 	/* Stop the ring buffer */
 	ret = write_sysfs_int("enable", buf_dir_name, 0);
 	if (ret < 0)
-		goto error_close_buffer_event;
+		goto error_close_buffer_access;
 
 	/* Disconnect from the trigger - just write a dummy name.*/
 	write_sysfs_string("trigger/current_trigger",
 			dev_dir_name, "NULL");
 
-error_close_buffer_event:
-	fclose(fp_ev);
 error_close_buffer_access:
 	close(fp);
 error_free_data:
 	free(data);
 error_free_buffer_access:
 	free(buffer_access);
-error_free_buffer_event:
-	free(buffer_event);
 error_free_buf_dir_name:
 	free(buf_dir_name);
 error_free_triggername:
diff -druN linux-2.6.39-libre/drivers/staging/iio/Documentation/iio_utils.h linux-3.0-rc7-libre/drivers/staging/iio/Documentation/iio_utils.h
--- linux-2.6.39-libre/drivers/staging/iio/Documentation/iio_utils.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/iio/Documentation/iio_utils.h	2011-07-11 19:51:52.000000000 -0400
@@ -16,25 +16,11 @@
 
 #define IIO_MAX_NAME_LENGTH 30
 
-#define IIO_EV_CLASS_BUFFER		0
-#define IIO_BUFFER_EVENT_CODE(code)		\
-	(IIO_EV_CLASS_BUFFER | (code << 8))
-
-#define IIO_EVENT_CODE_RING_50_FULL	IIO_BUFFER_EVENT_CODE(0)
-#define IIO_EVENT_CODE_RING_75_FULL	IIO_BUFFER_EVENT_CODE(1)
-#define IIO_EVENT_CODE_RING_100_FULL	IIO_BUFFER_EVENT_CODE(2)
-
-
 #define FORMAT_SCAN_ELEMENTS_DIR "%s:buffer0/scan_elements"
 #define FORMAT_TYPE_FILE "%s_type"
 
 const char *iio_dir = "/sys/bus/iio/devices/";
 
-struct iio_event_data {
-	int id;
-	__s64 timestamp;
-};
-
 /**
  * iioutils_break_up_name() - extract generic name from full channel name
  * @full_name: the full channel name
@@ -85,6 +71,7 @@
 	unsigned index;
 	unsigned bytes;
 	unsigned bits_used;
+	unsigned shift;
 	uint64_t mask;
 	unsigned is_signed;
 	unsigned enabled;
@@ -103,6 +90,7 @@
 inline int iioutils_get_type(unsigned *is_signed,
 			     unsigned *bytes,
 			     unsigned *bits_used,
+			     unsigned *shift,
 			     uint64_t *mask,
 			     const char *device_dir,
 			     const char *name,
@@ -157,7 +145,8 @@
 				goto error_free_filename;
 			}
 			fscanf(sysfsfp,
-			       "%c%u/%u", &signchar, bits_used, &padint);
+			       "%c%u/%u>>%u", &signchar, bits_used,
+			       &padint, shift);
 			*bytes = padint / 8;
 			if (*bits_used == 64)
 				*mask = ~0;
@@ -395,6 +384,7 @@
 			ret = iioutils_get_type(&current->is_signed,
 						&current->bytes,
 						&current->bits_used,
+						&current->shift,
 						&current->mask,
 						device_dir,
 						current->name,
diff -druN linux-2.6.39-libre/drivers/staging/iio/Documentation/overview.txt linux-3.0-rc7-libre/drivers/staging/iio/Documentation/overview.txt
--- linux-2.6.39-libre/drivers/staging/iio/Documentation/overview.txt	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/iio/Documentation/overview.txt	2011-07-11 19:51:52.000000000 -0400
@@ -3,8 +3,7 @@
 The Industrial I/O subsystem is intended to provide support for devices
 that in some sense are analog to digital converters (ADCs). As many
 actual devices combine some ADCs with digital to analog converters
-(DACs) the intention is to add that functionality at a future date
-(hence the name).
+(DACs) that functionality is also supported.
 
 The aim is to fill the gap between the somewhat similar hwmon and
 input subsystems.  Hwmon is very much directed at low sample rate
@@ -31,32 +30,28 @@
 Note: A given device may have one or more event channel.  These events are
 turned on or off (if possible) via sysfs interfaces.
 
-* Hardware ring buffer support.  Some recent sensors have included
+* Hardware buffer support.  Some recent sensors have included
 fifo / ring buffers on the sensor chip.  These greatly reduce the load
 on the host CPU by buffering relatively large numbers of data samples
 based on an internal sampling clock. Examples include VTI SCA3000
-series and Analog Device ADXL345 accelerometers.  Each ring buffer
-typically has an event chrdev (similar to the more general ones above)
-to pass on events such as buffer 50% full and an access chrdev via
-which the raw data it self may be read back.
+series and Analog Device ADXL345 accelerometers.  Each buffer supports
+polling to establish when data is available.
 
-* Trigger and software ring buffer support. In many data analysis
+* Trigger and software buffer support. In many data analysis
 applications it it useful to be able to capture data based on some
 external signal (trigger).  These triggers might be a data ready
 signal, a gpio line connected to some external system or an on
 processor periodic interrupt.  A single trigger may initialize data
 capture or reading from a number of sensors.  These triggers are
-used in IIO to fill software ring buffers acting in a very similar
+used in IIO to fill software buffers acting in a very similar
 fashion to the hardware buffers described above.
 
 Other documentation:
 
-userspace.txt - overview of ring buffer reading from userspace.
-
 device.txt - elements of a typical device driver.
 
 trigger.txt - elements of a typical trigger driver.
 
-ring.txt - additional elements required for ring buffer support.
+ring.txt - additional elements required for buffer support.
 
 sysfs-bus-iio - abi documentation file.
diff -druN linux-2.6.39-libre/drivers/staging/iio/Documentation/ring.txt linux-3.0-rc7-libre/drivers/staging/iio/Documentation/ring.txt
--- linux-2.6.39-libre/drivers/staging/iio/Documentation/ring.txt	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/iio/Documentation/ring.txt	2011-07-11 19:51:52.000000000 -0400
@@ -1,57 +1,55 @@
-Ring buffer support within IIO
+Buffer support within IIO
 
 This document is intended as a general overview of the functionality
-a ring buffer may supply and how it is specified within IIO.  For more
-specific information on a given ring buffer implementation, see the
-comments in the source code.  Note that the intention is to allow
-some drivers to specify ring buffers choice at probe or runtime, but
-for now the selection is hard coded within a given driver.
+a buffer may supply and how it is specified within IIO.  For more
+specific information on a given buffer implementation, see the
+comments in the source code.  Note that some drivers allow buffer
+implementation to be selected at compile time via Kconfig options.
 
-A given ring buffer implementation typically embedded a struct
+A given buffer implementation typically embeds a struct
 iio_ring_buffer and it is a pointer to this that is provided to the
 IIO core. Access to the embedding structure is typically done via
 container_of functions.
 
-struct iio_ring_buffer contains 4 function pointers
-(preenable, postenable, predisable, postdisable).
-These are used to perform implementation specific steps on either side
-of the core changing it's current mode to indicate that the ring buffer
+struct iio_ring_buffer contains a struct iio_ring_setup_ops *setup_ops
+which in turn contains the 4 function pointers
+(preenable, postenable, predisable and postdisable).
+These are used to perform device specific steps on either side
+of the core changing it's current mode to indicate that the buffer
 is enabled or disabled (along with enabling triggering etc as appropriate).
 
 Also in struct iio_ring_buffer is a struct iio_ring_access_funcs.
 The function pointers within here are used to allow the core to handle
-as much ring buffer functionality as possible. Note almost all of these
+as much buffer functionality as possible. Note almost all of these
 are optional.
 
 mark_in_use, unmark_in_use
-  Basically indicate that not changes should be made to the ring
-  buffer state that will effect the form of the data being captures
-  (e.g. scan elements or length)
+  Basically indicate that not changes should be made to the buffer state that
+  will effect the form of the data being captures (e.g. scan elements or length)
 
 store_to
-  If possible, push data to ring buffer.
+  If possible, push data to the buffer.
 
 read_last
-  If possible get the most recent entry from the buffer (without removal).
+  If possible, get the most recent scan from the buffer (without removal).
   This provides polling like functionality whilst the ring buffering is in
   use without a separate read from the device.
 
-rip_lots
-  The primary ring buffer reading function. Note that it may well not return
-  as much data as requested.  The deadoffset is used to indicate that some
-  initial data in the data array is not guaranteed to be valid.
+rip_first_n
+  The primary buffer reading function. Note that it may well not return
+  as much data as requested.
 
 mark_param_changed
   Used to indicate that something has changed. Used in conjunction with
 request_update
   If parameters have changed that require reinitialization or configuration of
-  the ring buffer this will trigger it.
+  the buffer this will trigger it.
 
 get_bytes_per_datum, set_bytes_per_datum
   Get/set the number of bytes for a complete scan. (All samples + timestamp)
 
 get_length / set_length
-  Get/set the number of sample sets that may be held by the buffer.
+  Get/set the number of complete scans that may be held by the buffer.
 
 is_enabled
   Query if ring buffer is in use
diff -druN linux-2.6.39-libre/drivers/staging/iio/Documentation/sysfs-bus-iio linux-3.0-rc7-libre/drivers/staging/iio/Documentation/sysfs-bus-iio
--- linux-2.6.39-libre/drivers/staging/iio/Documentation/sysfs-bus-iio	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/iio/Documentation/sysfs-bus-iio	2011-07-11 19:51:52.000000000 -0400
@@ -6,6 +6,12 @@
 		Corresponds to a grouping of sensor channels. X is the IIO
 		index of the device.
 
+What:		/sys/bus/iio/devices/device[n]/power_state
+KernelVersion:	2.6.37
+Contact:	linux-iio@vger.kernel.org
+Description:
+		This property gets/sets the device power state.
+
 What:		/sys/bus/iio/devices/triggerX
 KernelVersion:	2.6.35
 Contact:	linux-iio@vger.kernel.org
@@ -698,3 +704,10 @@
 		with all _en attributes to establish which channels are present,
 		and the relevant _type attributes to establish the data storage
 		format.
+
+What:		/sys/bus/iio/devices/deviceX/gyro_z_quadrature_correction_raw
+KernelVersion:	2.6.38
+Contact:	linux-iio@xxxxxxxxxxxxxxx
+Description:
+		This attribute is used to read the amount of quadrature error
+		present in the device at a given time.
diff -druN linux-2.6.39-libre/drivers/staging/iio/Documentation/sysfs-bus-iio-light linux-3.0-rc7-libre/drivers/staging/iio/Documentation/sysfs-bus-iio-light
--- linux-2.6.39-libre/drivers/staging/iio/Documentation/sysfs-bus-iio-light	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/iio/Documentation/sysfs-bus-iio-light	2011-07-11 19:51:52.000000000 -0400
@@ -62,3 +62,16 @@
 		sensing mode. This value should be the output from a reading
 		and if expressed in SI units, should include _input. If this
 		value is not in SI units, then it should include _raw.
+
+What:		/sys/bus/iio/devices/device[n]/illuminance0_target
+KernelVersion:	2.6.37
+Contact:	linux-iio@vger.kernel.org
+Description:
+		This property gets/sets the last known external
+		lux measurement used in/for calibration.
+
+What:		/sys/bus/iio/devices/device[n]/illuminance0_integration_time
+KernelVersion:	2.6.37
+Contact:	linux-iio@vger.kernel.org
+Description:
+		This property gets/sets the sensors ADC analog integration time.
diff -druN linux-2.6.39-libre/drivers/staging/iio/Documentation/sysfs-bus-iio-light-tsl2583 linux-3.0-rc7-libre/drivers/staging/iio/Documentation/sysfs-bus-iio-light-tsl2583
--- linux-2.6.39-libre/drivers/staging/iio/Documentation/sysfs-bus-iio-light-tsl2583	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/staging/iio/Documentation/sysfs-bus-iio-light-tsl2583	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,20 @@
+What:		/sys/bus/iio/devices/device[n]/lux_table
+KernelVersion:	2.6.37
+Contact:	linux-iio@vger.kernel.org
+Description:
+		This property gets/sets the table of coefficients
+		used in calculating illuminance in lux.
+
+What:		/sys/bus/iio/devices/device[n]/illuminance0_calibrate
+KernelVersion:	2.6.37
+Contact:	linux-iio@vger.kernel.org
+Description:
+		This property causes an internal calibration of the als gain trim
+		value which is later used in calculating illuminance in lux.
+
+What:		/sys/bus/iio/devices/device[n]/illuminance0_input_target
+KernelVersion:	2.6.37
+Contact:	linux-iio@vger.kernel.org
+Description:
+		This property is the known externally illuminance (in lux).
+		It is used in the process of calibrating the device accuracy.
diff -druN linux-2.6.39-libre/drivers/staging/iio/Documentation/trigger.txt linux-3.0-rc7-libre/drivers/staging/iio/Documentation/trigger.txt
--- linux-2.6.39-libre/drivers/staging/iio/Documentation/trigger.txt	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/iio/Documentation/trigger.txt	2011-07-11 19:51:52.000000000 -0400
@@ -5,14 +5,11 @@
 such triggers are registered with the core in the same way as
 stand-alone triggers.
 
-struct iio_trig *trig = iio_allocate_trigger();
+struct iio_trig *trig = iio_allocate_trigger("<trigger format string>", ...);
 
 allocates a trigger structure.  The key elements to then fill in within
 a driver are:
 
-trig->control_attrs
-	Any sysfs attributes needed to control parameters of the trigger
-
 trig->private_data
 	Device specific private data.
 
@@ -20,8 +17,12 @@
 	Typically set to THIS_MODULE. Used to ensure correct
 	ownership of core allocated resources.
 
-trig->name
-	A unique name for the trigger.
+trig->set_trigger_state:
+	Function that enables / disables the underlying source of the trigger.
+
+There is also a
+trig->alloc_list which is useful for drivers that allocate multiple
+triggers to keep track of what they have created.
 
 When these have been set call:
 
@@ -30,9 +31,8 @@
 to register the trigger with the core, making it available to trigger
 consumers.
 
-
 Trigger Consumers
 
-Currently triggers are only used for the filling of software ring
+Currently triggers are only used for the filling of software
 buffers and as such any device supporting INDIO_RING_TRIGGERED has the
 consumer interface automatically created.
diff -druN linux-2.6.39-libre/drivers/staging/iio/Documentation/userspace.txt linux-3.0-rc7-libre/drivers/staging/iio/Documentation/userspace.txt
--- linux-2.6.39-libre/drivers/staging/iio/Documentation/userspace.txt	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/iio/Documentation/userspace.txt	1969-12-31 19:00:00.000000000 -0500
@@ -1,12 +0,0 @@
-Userspace access to IIO
-
-The sysfs attributes are documented in sysfs-bus-iio.
-
-Udev will create the following entries under /dev by default:
-
-device0:buffer0:access0 - ring access chrdev
-device0:buffer0:event0 - ring event chrdev
-device0:event0 - general event chrdev.
-
-The files, lis3l02dqbuffersimple.c and iio_utils.h in this directory provide an example
-of how to use the ring buffer and event interfaces.
diff -druN linux-2.6.39-libre/drivers/staging/iio/gyro/adis16060_core.c linux-3.0-rc7-libre/drivers/staging/iio/gyro/adis16060_core.c
--- linux-2.6.39-libre/drivers/staging/iio/gyro/adis16060_core.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/iio/gyro/adis16060_core.c	2011-07-11 19:51:52.000000000 -0400
@@ -133,6 +133,11 @@
 	.attrs = adis16060_attributes,
 };
 
+static const struct iio_info adis16060_info = {
+	.attrs = &adis16060_attribute_group,
+	.driver_module = THIS_MODULE,
+};
+
 static int __devinit adis16060_r_probe(struct spi_device *spi)
 {
 	int ret, regdone = 0;
@@ -147,16 +152,15 @@
 	st->us_r = spi;
 	mutex_init(&st->buf_lock);
 	/* setup the industrialio driver allocated elements */
-	st->indio_dev = iio_allocate_device();
+	st->indio_dev = iio_allocate_device(0);
 	if (st->indio_dev == NULL) {
 		ret = -ENOMEM;
 		goto error_free_st;
 	}
 
 	st->indio_dev->dev.parent = &spi->dev;
-	st->indio_dev->attrs = &adis16060_attribute_group;
+	st->indio_dev->info = &adis16060_info;
 	st->indio_dev->dev_data = (void *)(st);
-	st->indio_dev->driver_module = THIS_MODULE;
 	st->indio_dev->modes = INDIO_DIRECT_MODE;
 
 	ret = iio_device_register(st->indio_dev);
diff -druN linux-2.6.39-libre/drivers/staging/iio/gyro/adis16080_core.c linux-3.0-rc7-libre/drivers/staging/iio/gyro/adis16080_core.c
--- linux-2.6.39-libre/drivers/staging/iio/gyro/adis16080_core.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/iio/gyro/adis16080_core.c	2011-07-11 19:51:52.000000000 -0400
@@ -110,14 +110,12 @@
 		       ADIS16080_DIN_TEMP);
 static IIO_DEV_ATTR_IN_RAW(0, adis16080_read, ADIS16080_DIN_AIN1);
 static IIO_DEV_ATTR_IN_RAW(1, adis16080_read, ADIS16080_DIN_AIN2);
-static IIO_CONST_ATTR(name, "adis16080");
 
 static struct attribute *adis16080_attributes[] = {
 	&iio_dev_attr_gyro_z_raw.dev_attr.attr,
 	&iio_dev_attr_temp_raw.dev_attr.attr,
 	&iio_dev_attr_in0_raw.dev_attr.attr,
 	&iio_dev_attr_in1_raw.dev_attr.attr,
-	&iio_const_attr_name.dev_attr.attr,
 	NULL
 };
 
@@ -125,6 +123,11 @@
 	.attrs = adis16080_attributes,
 };
 
+static const struct iio_info adis16080_info = {
+	.attrs = &adis16080_attribute_group,
+	.driver_module = THIS_MODULE,
+};
+
 static int __devinit adis16080_probe(struct spi_device *spi)
 {
 	int ret, regdone = 0;
@@ -140,16 +143,16 @@
 	st->us = spi;
 	mutex_init(&st->buf_lock);
 	/* setup the industrialio driver allocated elements */
-	st->indio_dev = iio_allocate_device();
+	st->indio_dev = iio_allocate_device(0);
 	if (st->indio_dev == NULL) {
 		ret = -ENOMEM;
 		goto error_free_st;
 	}
 
+	st->indio_dev->name = spi->dev.driver->name;
 	st->indio_dev->dev.parent = &spi->dev;
-	st->indio_dev->attrs = &adis16080_attribute_group;
+	st->indio_dev->info = &adis16080_info;
 	st->indio_dev->dev_data = (void *)(st);
-	st->indio_dev->driver_module = THIS_MODULE;
 	st->indio_dev->modes = INDIO_DIRECT_MODE;
 
 	ret = iio_device_register(st->indio_dev);
diff -druN linux-2.6.39-libre/drivers/staging/iio/gyro/adis16130_core.c linux-3.0-rc7-libre/drivers/staging/iio/gyro/adis16130_core.c
--- linux-2.6.39-libre/drivers/staging/iio/gyro/adis16130_core.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/iio/gyro/adis16130_core.c	2011-07-11 19:51:52.000000000 -0400
@@ -155,8 +155,6 @@
 static IIO_DEVICE_ATTR(temp_raw, S_IRUGO, adis16130_val_read, NULL,
 		      ADIS16130_TEMPDATA);
 
-static IIO_CONST_ATTR(name, "adis16130");
-
 static IIO_DEV_ATTR_GYRO_Z(adis16130_val_read, ADIS16130_RATEDATA);
 
 static IIO_DEVICE_ATTR(gyro_z_type, S_IWUSR | S_IRUGO, adis16130_bitsmode_read,
@@ -167,7 +165,6 @@
 
 static struct attribute *adis16130_attributes[] = {
 	&iio_dev_attr_temp_raw.dev_attr.attr,
-	&iio_const_attr_name.dev_attr.attr,
 	&iio_dev_attr_gyro_z_raw.dev_attr.attr,
 	&iio_dev_attr_gyro_z_type.dev_attr.attr,
 	&iio_const_attr_gyro_z_type_available.dev_attr.attr,
@@ -178,6 +175,11 @@
 	.attrs = adis16130_attributes,
 };
 
+static const struct iio_info adis16130_info = {
+	.attrs = &adis16130_attribute_group,
+	.driver_module = THIS_MODULE,
+};
+
 static int __devinit adis16130_probe(struct spi_device *spi)
 {
 	int ret;
@@ -191,16 +193,16 @@
 	st->us = spi;
 	mutex_init(&st->buf_lock);
 	/* setup the industrialio driver allocated elements */
-	st->indio_dev = iio_allocate_device();
+	st->indio_dev = iio_allocate_device(0);
 	if (st->indio_dev == NULL) {
 		ret = -ENOMEM;
 		goto error_free_st;
 	}
 
+	st->indio_dev->name = spi->dev.driver->name;
 	st->indio_dev->dev.parent = &spi->dev;
-	st->indio_dev->attrs = &adis16130_attribute_group;
+	st->indio_dev->info = &adis16130_info;
 	st->indio_dev->dev_data = (void *)(st);
-	st->indio_dev->driver_module = THIS_MODULE;
 	st->indio_dev->modes = INDIO_DIRECT_MODE;
 	st->mode = 1;
 
diff -druN linux-2.6.39-libre/drivers/staging/iio/gyro/adis16260_core.c linux-3.0-rc7-libre/drivers/staging/iio/gyro/adis16260_core.c
--- linux-2.6.39-libre/drivers/staging/iio/gyro/adis16260_core.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/iio/gyro/adis16260_core.c	2011-07-11 19:51:52.000000000 -0400
@@ -28,20 +28,19 @@
 
 #define DRIVER_NAME		"adis16260"
 
-static int adis16260_check_status(struct device *dev);
+static int adis16260_check_status(struct iio_dev *indio_dev);
 
 /**
  * adis16260_spi_write_reg_8() - write single byte to a register
- * @dev: device associated with child of actual device (iio_dev or iio_trig)
+ * @indio_dev: iio_dev for the device
  * @reg_address: the address of the register to be written
  * @val: the value to write
  **/
-static int adis16260_spi_write_reg_8(struct device *dev,
+static int adis16260_spi_write_reg_8(struct iio_dev *indio_dev,
 		u8 reg_address,
 		u8 val)
 {
 	int ret;
-	struct iio_dev *indio_dev = dev_get_drvdata(dev);
 	struct adis16260_state *st = iio_dev_get_devdata(indio_dev);
 
 	mutex_lock(&st->buf_lock);
@@ -56,18 +55,17 @@
 
 /**
  * adis16260_spi_write_reg_16() - write 2 bytes to a pair of registers
- * @dev: device associated with child of actual device (iio_dev or iio_trig)
+ * @indio_dev: iio_dev for the device
  * @reg_address: the address of the lower of the two registers. Second register
  *               is assumed to have address one greater.
  * @val: value to be written
  **/
-static int adis16260_spi_write_reg_16(struct device *dev,
+static int adis16260_spi_write_reg_16(struct iio_dev *indio_dev,
 		u8 lower_reg_address,
 		u16 value)
 {
 	int ret;
 	struct spi_message msg;
-	struct iio_dev *indio_dev = dev_get_drvdata(dev);
 	struct adis16260_state *st = iio_dev_get_devdata(indio_dev);
 	struct spi_transfer xfers[] = {
 		{
@@ -80,7 +78,6 @@
 			.tx_buf = st->tx + 2,
 			.bits_per_word = 8,
 			.len = 2,
-			.cs_change = 1,
 			.delay_usecs = 20,
 		},
 	};
@@ -102,17 +99,16 @@
 
 /**
  * adis16260_spi_read_reg_16() - read 2 bytes from a 16-bit register
- * @dev: device associated with child of actual device (iio_dev or iio_trig)
+ * @indio_dev: iio_dev for the device
  * @reg_address: the address of the lower of the two registers. Second register
  *               is assumed to have address one greater.
  * @val: somewhere to pass back the value read
  **/
-static int adis16260_spi_read_reg_16(struct device *dev,
+static int adis16260_spi_read_reg_16(struct iio_dev *indio_dev,
 		u8 lower_reg_address,
 		u16 *val)
 {
 	struct spi_message msg;
-	struct iio_dev *indio_dev = dev_get_drvdata(dev);
 	struct adis16260_state *st = iio_dev_get_devdata(indio_dev);
 	int ret;
 	struct spi_transfer xfers[] = {
@@ -126,7 +122,6 @@
 			.rx_buf = st->rx,
 			.bits_per_word = 8,
 			.len = 2,
-			.cs_change = 1,
 			.delay_usecs = 30,
 		},
 	};
@@ -152,92 +147,6 @@
 	return ret;
 }
 
-static ssize_t adis16260_spi_read_signed(struct device *dev,
-		struct device_attribute *attr,
-		char *buf,
-		unsigned bits)
-{
-	int ret;
-	s16 val = 0;
-	unsigned shift = 16 - bits;
-	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
-
-	ret = adis16260_spi_read_reg_16(dev, this_attr->address, (u16 *)&val);
-	if (ret)
-		return ret;
-
-	if (val & ADIS16260_ERROR_ACTIVE)
-		adis16260_check_status(dev);
-	val = ((s16)(val << shift) >> shift);
-	return sprintf(buf, "%d\n", val);
-}
-
-static ssize_t adis16260_read_12bit_unsigned(struct device *dev,
-		struct device_attribute *attr,
-		char *buf)
-{
-	int ret;
-	u16 val = 0;
-	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
-
-	ret = adis16260_spi_read_reg_16(dev, this_attr->address, &val);
-	if (ret)
-		return ret;
-
-	if (val & ADIS16260_ERROR_ACTIVE)
-		adis16260_check_status(dev);
-
-	return sprintf(buf, "%u\n", val & 0x0FFF);
-}
-
-static ssize_t adis16260_read_12bit_signed(struct device *dev,
-		struct device_attribute *attr,
-		char *buf)
-{
-	struct iio_dev *indio_dev = dev_get_drvdata(dev);
-	ssize_t ret;
-
-	/* Take the iio_dev status lock */
-	mutex_lock(&indio_dev->mlock);
-	ret =  adis16260_spi_read_signed(dev, attr, buf, 12);
-	mutex_unlock(&indio_dev->mlock);
-
-	return ret;
-}
-
-static ssize_t adis16260_read_14bit_signed(struct device *dev,
-		struct device_attribute *attr,
-		char *buf)
-{
-	struct iio_dev *indio_dev = dev_get_drvdata(dev);
-	ssize_t ret;
-
-	/* Take the iio_dev status lock */
-	mutex_lock(&indio_dev->mlock);
-	ret =  adis16260_spi_read_signed(dev, attr, buf, 14);
-	mutex_unlock(&indio_dev->mlock);
-
-	return ret;
-}
-
-static ssize_t adis16260_write_16bit(struct device *dev,
-		struct device_attribute *attr,
-		const char *buf,
-		size_t len)
-{
-	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
-	int ret;
-	long val;
-
-	ret = strict_strtol(buf, 10, &val);
-	if (ret)
-		goto error_ret;
-	ret = adis16260_spi_write_reg_16(dev, this_attr->address, val);
-
-error_ret:
-	return ret ? ret : len;
-}
-
 static ssize_t adis16260_read_frequency_available(struct device *dev,
 						  struct device_attribute *attr,
 						  char *buf)
@@ -259,7 +168,7 @@
 	int ret, len = 0;
 	u16 t;
 	int sps;
-	ret = adis16260_spi_read_reg_16(dev,
+	ret = adis16260_spi_read_reg_16(indio_dev,
 			ADIS16260_SMPL_PRD,
 			&t);
 	if (ret)
@@ -305,7 +214,7 @@
 		st->us->max_speed_hz = ADIS16260_SPI_SLOW;
 	else
 		st->us->max_speed_hz = ADIS16260_SPI_FAST;
-	ret = adis16260_spi_write_reg_8(dev,
+	ret = adis16260_spi_write_reg_8(indio_dev,
 			ADIS16260_SMPL_PRD,
 			t);
 
@@ -314,33 +223,14 @@
 	return ret ? ret : len;
 }
 
-static ssize_t adis16260_read_gyro_scale(struct device *dev,
-		struct device_attribute *attr,
-		char *buf)
-{
-	struct iio_dev *indio_dev = dev_get_drvdata(dev);
-	struct adis16260_state *st = iio_dev_get_devdata(indio_dev);
-	ssize_t ret = 0;
-
-	if (st->negate)
-		ret = sprintf(buf, "-");
-	/* Take the iio_dev status lock */
-	if (spi_get_device_id(st->us)->driver_data)
-		ret += sprintf(buf + ret, "%s\n", "0.00031974432");
-	else
-		ret += sprintf(buf + ret, "%s\n", "0.00127862821");
-
-	return ret;
-}
-
-static int adis16260_reset(struct device *dev)
+static int adis16260_reset(struct iio_dev *indio_dev)
 {
 	int ret;
-	ret = adis16260_spi_write_reg_8(dev,
+	ret = adis16260_spi_write_reg_8(indio_dev,
 			ADIS16260_GLOB_CMD,
 			ADIS16260_GLOB_CMD_SW_RESET);
 	if (ret)
-		dev_err(dev, "problem resetting device");
+		dev_err(&indio_dev->dev, "problem resetting device");
 
 	return ret;
 }
@@ -349,22 +239,23 @@
 		struct device_attribute *attr,
 		const char *buf, size_t len)
 {
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
 	if (len < 1)
 		return -EINVAL;
 	switch (buf[0]) {
 	case '1':
 	case 'y':
 	case 'Y':
-		return adis16260_reset(dev);
+		return adis16260_reset(indio_dev);
 	}
 	return -EINVAL;
 }
 
-int adis16260_set_irq(struct device *dev, bool enable)
+int adis16260_set_irq(struct iio_dev *indio_dev, bool enable)
 {
 	int ret;
 	u16 msc;
-	ret = adis16260_spi_read_reg_16(dev, ADIS16260_MSC_CTRL, &msc);
+	ret = adis16260_spi_read_reg_16(indio_dev, ADIS16260_MSC_CTRL, &msc);
 	if (ret)
 		goto error_ret;
 
@@ -374,7 +265,7 @@
 	else
 		msc &= ~ADIS16260_MSC_CTRL_DATA_RDY_EN;
 
-	ret = adis16260_spi_write_reg_16(dev, ADIS16260_MSC_CTRL, msc);
+	ret = adis16260_spi_write_reg_16(indio_dev, ADIS16260_MSC_CTRL, msc);
 	if (ret)
 		goto error_ret;
 
@@ -383,41 +274,44 @@
 }
 
 /* Power down the device */
-static int adis16260_stop_device(struct device *dev)
+static int adis16260_stop_device(struct iio_dev *indio_dev)
 {
 	int ret;
 	u16 val = ADIS16260_SLP_CNT_POWER_OFF;
 
-	ret = adis16260_spi_write_reg_16(dev, ADIS16260_SLP_CNT, val);
+	ret = adis16260_spi_write_reg_16(indio_dev, ADIS16260_SLP_CNT, val);
 	if (ret)
-		dev_err(dev, "problem with turning device off: SLP_CNT");
+		dev_err(&indio_dev->dev, "problem with turning device off: SLP_CNT");
 
 	return ret;
 }
 
-static int adis16260_self_test(struct device *dev)
+static int adis16260_self_test(struct iio_dev *indio_dev)
 {
 	int ret;
-	ret = adis16260_spi_write_reg_16(dev,
+	ret = adis16260_spi_write_reg_16(indio_dev,
 			ADIS16260_MSC_CTRL,
 			ADIS16260_MSC_CTRL_MEM_TEST);
 	if (ret) {
-		dev_err(dev, "problem starting self test");
+		dev_err(&indio_dev->dev, "problem starting self test");
 		goto err_ret;
 	}
 
-	adis16260_check_status(dev);
+	adis16260_check_status(indio_dev);
 
 err_ret:
 	return ret;
 }
 
-static int adis16260_check_status(struct device *dev)
+static int adis16260_check_status(struct iio_dev *indio_dev)
 {
 	u16 status;
 	int ret;
+	struct device *dev = &indio_dev->dev;
 
-	ret = adis16260_spi_read_reg_16(dev, ADIS16260_DIAG_STAT, &status);
+	ret = adis16260_spi_read_reg_16(indio_dev,
+					ADIS16260_DIAG_STAT,
+					&status);
 
 	if (ret < 0) {
 		dev_err(dev, "Reading status failed\n");
@@ -443,130 +337,240 @@
 	return ret;
 }
 
-static int adis16260_initial_setup(struct adis16260_state *st)
+static int adis16260_initial_setup(struct iio_dev *indio_dev)
 {
 	int ret;
-	struct device *dev = &st->indio_dev->dev;
+	struct device *dev = &indio_dev->dev;
 
 	/* Disable IRQ */
-	ret = adis16260_set_irq(dev, false);
+	ret = adis16260_set_irq(indio_dev, false);
 	if (ret) {
 		dev_err(dev, "disable irq failed");
 		goto err_ret;
 	}
 
 	/* Do self test */
-	ret = adis16260_self_test(dev);
+	ret = adis16260_self_test(indio_dev);
 	if (ret) {
 		dev_err(dev, "self test failure");
 		goto err_ret;
 	}
 
 	/* Read status register to check the result */
-	ret = adis16260_check_status(dev);
+	ret = adis16260_check_status(indio_dev);
 	if (ret) {
-		adis16260_reset(dev);
+		adis16260_reset(indio_dev);
 		dev_err(dev, "device not playing ball -> reset");
 		msleep(ADIS16260_STARTUP_DELAY);
-		ret = adis16260_check_status(dev);
+		ret = adis16260_check_status(indio_dev);
 		if (ret) {
 			dev_err(dev, "giving up");
 			goto err_ret;
 		}
 	}
 
-	printk(KERN_INFO DRIVER_NAME ": at CS%d (irq %d)\n",
-			st->us->chip_select, st->us->irq);
-
 err_ret:
 	return ret;
 }
 
-static IIO_DEV_ATTR_IN_NAMED_RAW(0, supply,
-				adis16260_read_12bit_unsigned,
-				ADIS16260_SUPPLY_OUT);
-static IIO_CONST_ATTR_IN_NAMED_SCALE(0, supply, "0.0018315");
-
-static IIO_DEV_ATTR_TEMP_RAW(adis16260_read_12bit_unsigned);
-static IIO_CONST_ATTR_TEMP_OFFSET("25");
-static IIO_CONST_ATTR_TEMP_SCALE("0.1453");
-
-static IIO_DEV_ATTR_IN_RAW(1, adis16260_read_12bit_unsigned,
-		ADIS16260_AUX_ADC);
-static IIO_CONST_ATTR(in1_scale, "0.0006105");
-
 static IIO_DEV_ATTR_SAMP_FREQ(S_IWUSR | S_IRUGO,
 		adis16260_read_frequency,
 		adis16260_write_frequency);
 
 static IIO_DEVICE_ATTR(reset, S_IWUSR, NULL, adis16260_write_reset, 0);
 
-
 static IIO_DEVICE_ATTR(sampling_frequency_available,
 		       S_IRUGO, adis16260_read_frequency_available, NULL, 0);
 
-static IIO_CONST_ATTR_NAME("adis16260");
-
-static struct attribute *adis16260_event_attributes[] = {
-	NULL
+enum adis16260_channel {
+	gyro,
+	temp,
+	in_supply,
+	in_aux,
+	angle,
 };
+#define ADIS16260_GYRO_CHANNEL_SET(axis, mod)				\
+	struct iio_chan_spec adis16260_channels_##axis[] = {		\
+		IIO_CHAN(IIO_GYRO, 1, 0, 0, NULL, 0, mod,		\
+			 (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE) |	\
+			 (1 << IIO_CHAN_INFO_CALIBSCALE_SEPARATE) |	\
+			 (1 << IIO_CHAN_INFO_SCALE_SEPARATE),		\
+			 gyro, ADIS16260_SCAN_GYRO,			\
+			 IIO_ST('s', 14, 16, 0), 0),			\
+		IIO_CHAN(IIO_ANGL, 1, 0, 0, NULL, 0, mod,		\
+			 0,						\
+			 angle, ADIS16260_SCAN_ANGL,			\
+			 IIO_ST('u', 14, 16, 0), 0),			\
+		IIO_CHAN(IIO_TEMP, 0, 1, 0, NULL, 0, 0,			\
+			 (1 << IIO_CHAN_INFO_OFFSET_SEPARATE) |		\
+			 (1 << IIO_CHAN_INFO_SCALE_SEPARATE),		\
+			 temp, ADIS16260_SCAN_TEMP,			\
+			 IIO_ST('u', 12, 16, 0), 0),			\
+		IIO_CHAN(IIO_IN, 0, 1, 0, "supply", 0, 0,		\
+			 (1 << IIO_CHAN_INFO_SCALE_SEPARATE),		\
+			 in_supply, ADIS16260_SCAN_SUPPLY,		\
+			 IIO_ST('u', 12, 16, 0), 0),			\
+		IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 1, 0,			\
+			 (1 << IIO_CHAN_INFO_SCALE_SEPARATE),		\
+			 in_aux, ADIS16260_SCAN_AUX_ADC,		\
+			 IIO_ST('u', 12, 16, 0), 0),			\
+		IIO_CHAN_SOFT_TIMESTAMP(5)				\
+	}
 
-static struct attribute_group adis16260_event_attribute_group = {
-	.attrs = adis16260_event_attributes,
+static const ADIS16260_GYRO_CHANNEL_SET(x, IIO_MOD_X);
+static const ADIS16260_GYRO_CHANNEL_SET(y, IIO_MOD_Y);
+static const ADIS16260_GYRO_CHANNEL_SET(z, IIO_MOD_Z);
+
+static const u8 adis16260_addresses[5][3] = {
+	[gyro] = { ADIS16260_GYRO_OUT,
+		   ADIS16260_GYRO_OFF,
+		   ADIS16260_GYRO_SCALE },
+	[angle] = { ADIS16260_ANGL_OUT },
+	[in_supply] = { ADIS16260_SUPPLY_OUT },
+	[in_aux] = { ADIS16260_AUX_ADC },
+	[temp] = { ADIS16260_TEMP_OUT },
 };
+static int adis16260_read_raw(struct iio_dev *indio_dev,
+			      struct iio_chan_spec const *chan,
+			      int *val, int *val2,
+			      long mask)
+{
+	struct adis16260_state *st = iio_dev_get_devdata(indio_dev);
+	int ret;
+	int bits;
+	u8 addr;
+	s16 val16;
 
-#define ADIS16260_GYRO_ATTR_SET(axis)					\
-	IIO_DEV_ATTR_GYRO##axis(adis16260_read_14bit_signed,		\
-				ADIS16260_GYRO_OUT);			\
-	static IIO_DEV_ATTR_GYRO##axis##_SCALE(S_IRUGO,			\
-					adis16260_read_gyro_scale,	\
-					NULL,				\
-					0);				\
-	static IIO_DEV_ATTR_GYRO##axis##_CALIBSCALE(S_IRUGO | S_IWUSR,	\
-					adis16260_read_12bit_unsigned,	\
-					adis16260_write_16bit,		\
-					ADIS16260_GYRO_SCALE);		\
-	static IIO_DEV_ATTR_GYRO##axis##_CALIBBIAS(S_IWUSR | S_IRUGO,	\
-					adis16260_read_12bit_signed,	\
-					adis16260_write_16bit,		\
-					ADIS16260_GYRO_OFF);		\
-	static IIO_DEV_ATTR_ANGL##axis(adis16260_read_14bit_signed,	\
-				       ADIS16260_ANGL_OUT);
+	switch (mask) {
+	case 0:
+		mutex_lock(&indio_dev->mlock);
+		addr = adis16260_addresses[chan->address][0];
+		ret = adis16260_spi_read_reg_16(indio_dev, addr, &val16);
+		if (ret)
+			return ret;
 
-static ADIS16260_GYRO_ATTR_SET();
-static ADIS16260_GYRO_ATTR_SET(_X);
-static ADIS16260_GYRO_ATTR_SET(_Y);
-static ADIS16260_GYRO_ATTR_SET(_Z);
+		if (val16 & ADIS16260_ERROR_ACTIVE) {
+			ret = adis16260_check_status(indio_dev);
+			if (ret)
+				return ret;
+		}
+		val16 = val16 & ((1 << chan->scan_type.realbits) - 1);
+		if (chan->scan_type.sign == 's')
+			val16 = (s16)(val16 <<
+				      (16 - chan->scan_type.realbits)) >>
+				(16 - chan->scan_type.realbits);
+		*val = val16;
+		mutex_unlock(&indio_dev->mlock);
+		return IIO_VAL_INT;
+	case (1 << IIO_CHAN_INFO_SCALE_SEPARATE):
+	case (1 << IIO_CHAN_INFO_SCALE_SHARED):
+		switch (chan->type) {
+		case IIO_GYRO:
+			*val = 0;
+			if (spi_get_device_id(st->us)->driver_data)
+				*val2 = 320;
+			else
+				*val2 = 1278;
+			return IIO_VAL_INT_PLUS_MICRO;
+		case IIO_IN:
+			*val = 0;
+			if (chan->channel == 0)
+				*val2 = 18315;
+			else
+				*val2 = 610500;
+			return IIO_VAL_INT_PLUS_MICRO;
+		case IIO_TEMP:
+			*val = 0;
+			*val2 = 145300;
+			return IIO_VAL_INT_PLUS_MICRO;
+		default:
+			return -EINVAL;
+		}
+		break;
+	case (1 << IIO_CHAN_INFO_OFFSET_SEPARATE):
+		*val = 25;
+		return IIO_VAL_INT;
+	case (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE):
+		switch (chan->type) {
+		case IIO_GYRO:
+			bits = 12;
+			break;
+		default:
+			return -EINVAL;
+		};
+		mutex_lock(&indio_dev->mlock);
+		addr = adis16260_addresses[chan->address][1];
+		ret = adis16260_spi_read_reg_16(indio_dev, addr, &val16);
+		if (ret) {
+			mutex_unlock(&indio_dev->mlock);
+			return ret;
+		}
+		val16 &= (1 << bits) - 1;
+		val16 = (s16)(val16 << (16 - bits)) >> (16 - bits);
+		*val = val16;
+		mutex_unlock(&indio_dev->mlock);
+		return IIO_VAL_INT;
+	case (1 << IIO_CHAN_INFO_CALIBSCALE_SEPARATE):
+		switch (chan->type) {
+		case IIO_GYRO:
+			bits = 12;
+			break;
+		default:
+			return -EINVAL;
+		};
+		mutex_lock(&indio_dev->mlock);
+		addr = adis16260_addresses[chan->address][2];
+		ret = adis16260_spi_read_reg_16(indio_dev, addr, &val16);
+		if (ret) {
+			mutex_unlock(&indio_dev->mlock);
+			return ret;
+		}
+		*val = (1 << bits) - 1;
+		mutex_unlock(&indio_dev->mlock);
+		return IIO_VAL_INT;
+	}
+	return -EINVAL;
+}
 
-#define ADIS16260_ATTR_GROUP(axis)					\
-	struct attribute *adis16260_attributes##axis[] = {		\
-		&iio_dev_attr_in0_supply_raw.dev_attr.attr,		\
-		&iio_const_attr_in0_supply_scale.dev_attr.attr,		\
-		&iio_dev_attr_gyro##axis##_raw.dev_attr.attr,		\
-		&iio_dev_attr_gyro##axis##_scale.dev_attr.attr,		\
-		&iio_dev_attr_gyro##axis##_calibscale.dev_attr.attr,	\
-		&iio_dev_attr_gyro##axis##_calibbias.dev_attr.attr,	\
-		&iio_dev_attr_angl##axis##_raw.dev_attr.attr,		\
-		&iio_dev_attr_temp_raw.dev_attr.attr,			\
-		&iio_const_attr_temp_offset.dev_attr.attr,		\
-		&iio_const_attr_temp_scale.dev_attr.attr,		\
-		&iio_dev_attr_in1_raw.dev_attr.attr,			\
-		&iio_const_attr_in1_scale.dev_attr.attr,		\
-		&iio_dev_attr_sampling_frequency.dev_attr.attr,		\
-		&iio_dev_attr_sampling_frequency_available.dev_attr.attr, \
-		&iio_dev_attr_reset.dev_attr.attr,			\
-		&iio_const_attr_name.dev_attr.attr,			\
-		NULL							\
-	};								\
-	static const struct attribute_group adis16260_attribute_group##axis \
-	= {								\
-		.attrs = adis16260_attributes##axis,			\
-	};
+static int adis16260_write_raw(struct iio_dev *indio_dev,
+			       struct iio_chan_spec const *chan,
+			       int val,
+			       int val2,
+			       long mask)
+{
+	int bits = 12;
+	s16 val16;
+	u8 addr;
+	switch (mask) {
+	case (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE):
+		val16 = val & ((1 << bits) - 1);
+		addr = adis16260_addresses[chan->address][1];
+		return adis16260_spi_write_reg_16(indio_dev, addr, val16);
+	case (1 << IIO_CHAN_INFO_CALIBSCALE_SEPARATE):
+		val16 = val & ((1 << bits) - 1);
+		addr = adis16260_addresses[chan->address][2];
+		return adis16260_spi_write_reg_16(indio_dev, addr, val16);
+	}
+	return -EINVAL;
+}
 
-static ADIS16260_ATTR_GROUP();
-static ADIS16260_ATTR_GROUP(_x);
-static ADIS16260_ATTR_GROUP(_y);
-static ADIS16260_ATTR_GROUP(_z);
+static struct attribute *adis16260_attributes[] = {
+	&iio_dev_attr_sampling_frequency.dev_attr.attr,
+	&iio_dev_attr_sampling_frequency_available.dev_attr.attr,
+	&iio_dev_attr_reset.dev_attr.attr,
+	NULL
+};
+
+static const struct attribute_group adis16260_attribute_group = {
+	.attrs = adis16260_attributes,
+};
+
+static const struct iio_info adis16260_info = {
+	.attrs = &adis16260_attribute_group,
+	.read_raw = &adis16260_read_raw,
+	.write_raw = &adis16260_write_raw,
+	.driver_module = THIS_MODULE,
+};
 
 static int __devinit adis16260_probe(struct spi_device *spi)
 {
@@ -596,35 +600,35 @@
 	st->us = spi;
 	mutex_init(&st->buf_lock);
 	/* setup the industrialio driver allocated elements */
-	st->indio_dev = iio_allocate_device();
+	st->indio_dev = iio_allocate_device(0);
 	if (st->indio_dev == NULL) {
 		ret = -ENOMEM;
 		goto error_free_tx;
 	}
 
+	st->indio_dev->name = spi_get_device_id(st->us)->name;
 	st->indio_dev->dev.parent = &spi->dev;
-	st->indio_dev->num_interrupt_lines = 1;
-	st->indio_dev->event_attrs = &adis16260_event_attribute_group;
+	st->indio_dev->info = &adis16260_info;
+	st->indio_dev->num_channels
+		= ARRAY_SIZE(adis16260_channels_x);
 	if (pd && pd->direction)
 		switch (pd->direction) {
 		case 'x':
-			st->indio_dev->attrs = &adis16260_attribute_group_x;
+			st->indio_dev->channels = adis16260_channels_x;
 			break;
 		case 'y':
-			st->indio_dev->attrs = &adis16260_attribute_group_y;
+			st->indio_dev->channels = adis16260_channels_y;
 			break;
 		case 'z':
-			st->indio_dev->attrs = &adis16260_attribute_group_z;
+			st->indio_dev->channels = adis16260_channels_z;
 			break;
 		default:
-			st->indio_dev->attrs = &adis16260_attribute_group;
-			break;
+			return -EINVAL;
 		}
 	else
-		st->indio_dev->attrs = &adis16260_attribute_group;
+		st->indio_dev->channels = adis16260_channels_x;
 
 	st->indio_dev->dev_data = (void *)(st);
-	st->indio_dev->driver_module = THIS_MODULE;
 	st->indio_dev->modes = INDIO_DIRECT_MODE;
 
 	ret = adis16260_configure_ring(st->indio_dev);
@@ -635,37 +639,28 @@
 	if (ret)
 		goto error_unreg_ring_funcs;
 	regdone = 1;
-	ret = iio_ring_buffer_register(st->indio_dev->ring, 0);
+	ret = iio_ring_buffer_register_ex(st->indio_dev->ring, 0,
+					  st->indio_dev->channels,
+					  ARRAY_SIZE(adis16260_channels_x));
 	if (ret) {
 		printk(KERN_ERR "failed to initialize the ring\n");
 		goto error_unreg_ring_funcs;
 	}
 
 	if (spi->irq) {
-		ret = iio_register_interrupt_line(spi->irq,
-				st->indio_dev,
-				0,
-				IRQF_TRIGGER_RISING,
-				"adis16260");
-		if (ret)
-			goto error_uninitialize_ring;
-
 		ret = adis16260_probe_trigger(st->indio_dev);
 		if (ret)
-			goto error_unregister_line;
+			goto error_uninitialize_ring;
 	}
 
 	/* Get the device into a sane initial state */
-	ret = adis16260_initial_setup(st);
+	ret = adis16260_initial_setup(st->indio_dev);
 	if (ret)
 		goto error_remove_trigger;
 	return 0;
 
 error_remove_trigger:
 	adis16260_remove_trigger(st->indio_dev);
-error_unregister_line:
-	if (spi->irq)
-		iio_unregister_interrupt_line(st->indio_dev, 0);
 error_uninitialize_ring:
 	iio_ring_buffer_unregister(st->indio_dev->ring);
 error_unreg_ring_funcs:
@@ -691,15 +686,13 @@
 	struct adis16260_state *st = spi_get_drvdata(spi);
 	struct iio_dev *indio_dev = st->indio_dev;
 
-	ret = adis16260_stop_device(&(indio_dev->dev));
+	ret = adis16260_stop_device(indio_dev);
 	if (ret)
 		goto err_ret;
 
 	flush_scheduled_work();
 
 	adis16260_remove_trigger(indio_dev);
-	if (spi->irq)
-		iio_unregister_interrupt_line(indio_dev, 0);
 
 	iio_ring_buffer_unregister(st->indio_dev->ring);
 	iio_device_unregister(indio_dev);
diff -druN linux-2.6.39-libre/drivers/staging/iio/gyro/adis16260.h linux-3.0-rc7-libre/drivers/staging/iio/gyro/adis16260.h
--- linux-2.6.39-libre/drivers/staging/iio/gyro/adis16260.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/iio/gyro/adis16260.h	2011-07-11 19:51:52.000000000 -0400
@@ -85,9 +85,6 @@
 /**
  * struct adis16260_state - device instance specific data
  * @us:			actual spi_device
- * @work_trigger_to_ring: bh for triggered event handling
- * @inter:		used to check if new interrupt has been triggered
- * @last_timestamp:	passing timestamp from th to bh of interrupt handler
  * @indio_dev:		industrial I/O device structure
  * @trig:		data ready trigger registered with iio
  * @tx:			transmit buffer
@@ -97,8 +94,6 @@
  **/
 struct adis16260_state {
 	struct spi_device		*us;
-	struct work_struct		work_trigger_to_ring;
-	s64				last_timestamp;
 	struct iio_dev			*indio_dev;
 	struct iio_trigger		*trig;
 	u8				*tx;
@@ -107,9 +102,8 @@
 	unsigned			negate:1;
 };
 
-int adis16260_set_irq(struct device *dev, bool enable);
+int adis16260_set_irq(struct iio_dev *indio_dev, bool enable);
 
-#ifdef CONFIG_IIO_RING_BUFFER
 /* At the moment triggers are only used for ring buffer
  * filling. This may change!
  */
@@ -120,6 +114,7 @@
 #define ADIS16260_SCAN_TEMP	3
 #define ADIS16260_SCAN_ANGL	4
 
+#ifdef CONFIG_IIO_RING_BUFFER
 void adis16260_remove_trigger(struct iio_dev *indio_dev);
 int adis16260_probe_trigger(struct iio_dev *indio_dev);
 
diff -druN linux-2.6.39-libre/drivers/staging/iio/gyro/adis16260_ring.c linux-3.0-rc7-libre/drivers/staging/iio/gyro/adis16260_ring.c
--- linux-2.6.39-libre/drivers/staging/iio/gyro/adis16260_ring.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/iio/gyro/adis16260_ring.c	2011-07-11 19:51:52.000000000 -0400
@@ -17,57 +17,6 @@
 #include "../trigger.h"
 #include "adis16260.h"
 
-static IIO_SCAN_EL_C(in_supply, ADIS16260_SCAN_SUPPLY,
-		ADIS16260_SUPPLY_OUT, NULL);
-static IIO_CONST_ATTR_SCAN_EL_TYPE(in_supply, u, 12, 16);
-static IIO_SCAN_EL_C(gyro, ADIS16260_SCAN_GYRO, ADIS16260_GYRO_OUT, NULL);
-static IIO_CONST_ATTR_SCAN_EL_TYPE(gyro, s, 14, 16);
-static IIO_SCAN_EL_C(in0, ADIS16260_SCAN_AUX_ADC, ADIS16260_AUX_ADC, NULL);
-static IIO_CONST_ATTR_SCAN_EL_TYPE(in0, u, 12, 16);
-static IIO_SCAN_EL_C(temp, ADIS16260_SCAN_TEMP, ADIS16260_TEMP_OUT, NULL);
-static IIO_CONST_ATTR_SCAN_EL_TYPE(temp, u, 12, 16);
-static IIO_SCAN_EL_C(angl, ADIS16260_SCAN_ANGL, ADIS16260_ANGL_OUT, NULL);
-static IIO_CONST_ATTR_SCAN_EL_TYPE(angl, u, 14, 16);
-static IIO_SCAN_EL_TIMESTAMP(5);
-static IIO_CONST_ATTR_SCAN_EL_TYPE(timestamp, s, 64, 64);
-
-static struct attribute *adis16260_scan_el_attrs[] = {
-	&iio_scan_el_in_supply.dev_attr.attr,
-	&iio_const_attr_in_supply_index.dev_attr.attr,
-	&iio_const_attr_in_supply_type.dev_attr.attr,
-	&iio_scan_el_gyro.dev_attr.attr,
-	&iio_const_attr_gyro_index.dev_attr.attr,
-	&iio_const_attr_gyro_type.dev_attr.attr,
-	&iio_scan_el_in0.dev_attr.attr,
-	&iio_const_attr_in0_index.dev_attr.attr,
-	&iio_const_attr_in0_type.dev_attr.attr,
-	&iio_scan_el_temp.dev_attr.attr,
-	&iio_const_attr_temp_index.dev_attr.attr,
-	&iio_const_attr_temp_type.dev_attr.attr,
-	&iio_scan_el_angl.dev_attr.attr,
-	&iio_const_attr_angl_index.dev_attr.attr,
-	&iio_const_attr_angl_type.dev_attr.attr,
-	&iio_scan_el_timestamp.dev_attr.attr,
-	&iio_const_attr_timestamp_index.dev_attr.attr,
-	&iio_const_attr_timestamp_type.dev_attr.attr,
-	NULL,
-};
-
-static struct attribute_group adis16260_scan_el_group = {
-	.attrs = adis16260_scan_el_attrs,
-	.name = "scan_elements",
-};
-
-/**
- * adis16260_poll_func_th() top half interrupt handler called by trigger
- * @private_data:	iio_dev
- **/
-static void adis16260_poll_func_th(struct iio_dev *indio_dev, s64 time)
-{
-	struct adis16260_state *st = iio_dev_get_devdata(indio_dev);
-	st->last_timestamp = time;
-	schedule_work(&st->work_trigger_to_ring);
-}
 
 /**
  * adis16260_read_ring_data() read data registers which will be placed into ring
@@ -117,56 +66,55 @@
 	return ret;
 }
 
-
-static void adis16260_trigger_bh_to_ring(struct work_struct *work_s)
+static irqreturn_t adis16260_trigger_handler(int irq, void *p)
 {
-	struct adis16260_state *st
-		= container_of(work_s, struct adis16260_state,
-				work_trigger_to_ring);
-	struct iio_ring_buffer *ring = st->indio_dev->ring;
-
+	struct iio_poll_func *pf = p;
+	struct iio_dev *indio_dev = pf->private_data;
+	struct adis16260_state *st = iio_dev_get_devdata(indio_dev);
+	struct iio_ring_buffer *ring = indio_dev->ring;
 	int i = 0;
 	s16 *data;
-	size_t datasize = ring->access.get_bytes_per_datum(ring);
+	size_t datasize = ring->access->get_bytes_per_datum(ring);
 
 	data = kmalloc(datasize , GFP_KERNEL);
 	if (data == NULL) {
 		dev_err(&st->us->dev, "memory alloc failed in ring bh");
-		return;
+		return -ENOMEM;
 	}
 
-	if (ring->scan_count)
-		if (adis16260_read_ring_data(&st->indio_dev->dev, st->rx) >= 0)
-			for (; i < ring->scan_count; i++)
-				data[i] = be16_to_cpup(
-					(__be16 *)&(st->rx[i*2]));
+	if (ring->scan_count &&
+	    adis16260_read_ring_data(&st->indio_dev->dev, st->rx) >= 0)
+		for (; i < ring->scan_count; i++)
+			data[i] = be16_to_cpup((__be16 *)&(st->rx[i*2]));
 
 	/* Guaranteed to be aligned with 8 byte boundary */
 	if (ring->scan_timestamp)
-		*((s64 *)(data + ((i + 3)/4)*4)) = st->last_timestamp;
+		*((s64 *)(data + ((i + 3)/4)*4)) = pf->timestamp;
 
-	ring->access.store_to(ring,
-			(u8 *)data,
-			st->last_timestamp);
+	ring->access->store_to(ring, (u8 *)data, pf->timestamp);
 
 	iio_trigger_notify_done(st->indio_dev->trig);
 	kfree(data);
 
-	return;
+	return IRQ_HANDLED;
 }
 
 void adis16260_unconfigure_ring(struct iio_dev *indio_dev)
 {
-	kfree(indio_dev->pollfunc);
+	iio_dealloc_pollfunc(indio_dev->pollfunc);
 	iio_sw_rb_free(indio_dev->ring);
 }
 
+static const struct iio_ring_setup_ops adis16260_ring_setup_ops = {
+	.preenable = &iio_sw_ring_preenable,
+	.postenable = &iio_triggered_ring_postenable,
+	.predisable = &iio_triggered_ring_predisable,
+};
+
 int adis16260_configure_ring(struct iio_dev *indio_dev)
 {
 	int ret = 0;
-	struct adis16260_state *st = indio_dev->dev_data;
 	struct iio_ring_buffer *ring;
-	INIT_WORK(&st->work_trigger_to_ring, adis16260_trigger_bh_to_ring);
 
 	ring = iio_sw_rb_allocate(indio_dev);
 	if (!ring) {
@@ -175,25 +123,29 @@
 	}
 	indio_dev->ring = ring;
 	/* Effectively select the ring buffer implementation */
-	iio_ring_sw_register_funcs(&ring->access);
+	ring->access = &ring_sw_access_funcs;
 	ring->bpe = 2;
-	ring->scan_el_attrs = &adis16260_scan_el_group;
 	ring->scan_timestamp = true;
-	ring->preenable = &iio_sw_ring_preenable;
-	ring->postenable = &iio_triggered_ring_postenable;
-	ring->predisable = &iio_triggered_ring_predisable;
+	ring->setup_ops = &adis16260_ring_setup_ops;
 	ring->owner = THIS_MODULE;
 
 	/* Set default scan mode */
-	iio_scan_mask_set(ring, iio_scan_el_in_supply.number);
-	iio_scan_mask_set(ring, iio_scan_el_gyro.number);
-	iio_scan_mask_set(ring, iio_scan_el_in0.number);
-	iio_scan_mask_set(ring, iio_scan_el_temp.number);
-	iio_scan_mask_set(ring, iio_scan_el_angl.number);
+	iio_scan_mask_set(ring, ADIS16260_SCAN_SUPPLY);
+	iio_scan_mask_set(ring, ADIS16260_SCAN_GYRO);
+	iio_scan_mask_set(ring, ADIS16260_SCAN_AUX_ADC);
+	iio_scan_mask_set(ring, ADIS16260_SCAN_TEMP);
+	iio_scan_mask_set(ring, ADIS16260_SCAN_ANGL);
 
-	ret = iio_alloc_pollfunc(indio_dev, NULL, &adis16260_poll_func_th);
-	if (ret)
+	indio_dev->pollfunc = iio_alloc_pollfunc(&iio_pollfunc_store_time,
+						 &adis16260_trigger_handler,
+						 IRQF_ONESHOT,
+						 indio_dev,
+						 "adis16260_consumer%d",
+						 indio_dev->id);
+	if (indio_dev->pollfunc == NULL) {
+		ret = -ENOMEM;
 		goto error_iio_sw_rb_free;
+	}
 
 	indio_dev->modes |= INDIO_RING_TRIGGERED;
 	return 0;
diff -druN linux-2.6.39-libre/drivers/staging/iio/gyro/adis16260_trigger.c linux-3.0-rc7-libre/drivers/staging/iio/gyro/adis16260_trigger.c
--- linux-2.6.39-libre/drivers/staging/iio/gyro/adis16260_trigger.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/iio/gyro/adis16260_trigger.c	2011-07-11 19:51:52.000000000 -0400
@@ -13,35 +13,6 @@
 #include "adis16260.h"
 
 /**
- * adis16260_data_rdy_trig_poll() the event handler for the data rdy trig
- **/
-static int adis16260_data_rdy_trig_poll(struct iio_dev *dev_info,
-				       int index,
-				       s64 timestamp,
-				       int no_test)
-{
-	struct adis16260_state *st = iio_dev_get_devdata(dev_info);
-	struct iio_trigger *trig = st->trig;
-
-	iio_trigger_poll(trig, timestamp);
-
-	return IRQ_HANDLED;
-}
-
-IIO_EVENT_SH(data_rdy_trig, &adis16260_data_rdy_trig_poll);
-
-static IIO_TRIGGER_NAME_ATTR;
-
-static struct attribute *adis16260_trigger_attrs[] = {
-	&dev_attr_name.attr,
-	NULL,
-};
-
-static const struct attribute_group adis16260_trigger_attr_group = {
-	.attrs = adis16260_trigger_attrs,
-};
-
-/**
  * adis16260_data_rdy_trigger_set_state() set datardy interrupt state
  **/
 static int adis16260_data_rdy_trigger_set_state(struct iio_trigger *trig,
@@ -49,31 +20,9 @@
 {
 	struct adis16260_state *st = trig->private_data;
 	struct iio_dev *indio_dev = st->indio_dev;
-	int ret = 0;
 
 	dev_dbg(&indio_dev->dev, "%s (%d)\n", __func__, state);
-	ret = adis16260_set_irq(&st->indio_dev->dev, state);
-	if (state == false) {
-		iio_remove_event_from_list(&iio_event_data_rdy_trig,
-					   &indio_dev->interrupts[0]
-					   ->ev_list);
-		flush_scheduled_work();
-	} else {
-		iio_add_event_to_list(&iio_event_data_rdy_trig,
-				      &indio_dev->interrupts[0]->ev_list);
-	}
-	return ret;
-}
-
-/**
- * adis16260_trig_try_reen() try renabling irq for data rdy trigger
- * @trig:	the datardy trigger
- **/
-static int adis16260_trig_try_reen(struct iio_trigger *trig)
-{
-	struct adis16260_state *st = trig->private_data;
-	enable_irq(st->us->irq);
-	return 0;
+	return adis16260_set_irq(indio_dev, state);
 }
 
 int adis16260_probe_trigger(struct iio_dev *indio_dev)
@@ -81,34 +30,40 @@
 	int ret;
 	struct adis16260_state *st = indio_dev->dev_data;
 
-	st->trig = iio_allocate_trigger();
-	st->trig->name = kasprintf(GFP_KERNEL,
-				   "adis16260-dev%d",
-				   indio_dev->id);
-	if (!st->trig->name) {
+	st->trig = iio_allocate_trigger("%s-dev%d",
+					spi_get_device_id(st->us)->name,
+					indio_dev->id);
+	if (st->trig == NULL) {
 		ret = -ENOMEM;
-		goto error_free_trig;
+		goto error_ret;
 	}
+
+	ret = request_irq(st->us->irq,
+			  &iio_trigger_generic_data_rdy_poll,
+			  IRQF_TRIGGER_RISING,
+			  "adis16260",
+			  st->trig);
+	if (ret)
+		goto error_free_trig;
+
 	st->trig->dev.parent = &st->us->dev;
 	st->trig->owner = THIS_MODULE;
 	st->trig->private_data = st;
 	st->trig->set_trigger_state = &adis16260_data_rdy_trigger_set_state;
-	st->trig->try_reenable = &adis16260_trig_try_reen;
-	st->trig->control_attrs = &adis16260_trigger_attr_group;
 	ret = iio_trigger_register(st->trig);
 
 	/* select default trigger */
 	indio_dev->trig = st->trig;
 	if (ret)
-		goto error_free_trig_name;
+		goto error_free_irq;
 
 	return 0;
 
-error_free_trig_name:
-	kfree(st->trig->name);
+error_free_irq:
+	free_irq(st->us->irq, st->trig);
 error_free_trig:
 	iio_free_trigger(st->trig);
-
+error_ret:
 	return ret;
 }
 
@@ -117,6 +72,6 @@
 	struct adis16260_state *state = indio_dev->dev_data;
 
 	iio_trigger_unregister(state->trig);
-	kfree(state->trig->name);
+	free_irq(state->us->irq, state->trig);
 	iio_free_trigger(state->trig);
 }
diff -druN linux-2.6.39-libre/drivers/staging/iio/gyro/adxrs450_core.c linux-3.0-rc7-libre/drivers/staging/iio/gyro/adxrs450_core.c
--- linux-2.6.39-libre/drivers/staging/iio/gyro/adxrs450_core.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/staging/iio/gyro/adxrs450_core.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,455 @@
+/*
+ * ADXRS450 Digital Output Gyroscope Driver
+ *
+ * Copyright 2011 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2.
+ */
+
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/gpio.h>
+#include <linux/delay.h>
+#include <linux/mutex.h>
+#include <linux/device.h>
+#include <linux/kernel.h>
+#include <linux/spi/spi.h>
+#include <linux/slab.h>
+#include <linux/sysfs.h>
+#include <linux/list.h>
+
+#include "../iio.h"
+#include "../sysfs.h"
+#include "gyro.h"
+#include "../adc/adc.h"
+
+#include "adxrs450.h"
+
+/**
+ * adxrs450_spi_read_reg_16() - read 2 bytes from a register pair
+ * @dev: device associated with child of actual iio_dev
+ * @reg_address: the address of the lower of the two registers,which should be an even address,
+ * Second register's address is reg_address + 1.
+ * @val: somewhere to pass back the value read
+ **/
+static int adxrs450_spi_read_reg_16(struct device *dev,
+		u8 reg_address,
+		u16 *val)
+{
+	struct spi_message msg;
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct adxrs450_state *st = iio_dev_get_devdata(indio_dev);
+	int ret;
+	struct spi_transfer xfers[] = {
+		{
+			.tx_buf = st->tx,
+			.bits_per_word = 8,
+			.len = 4,
+			.cs_change = 1,
+		}, {
+			.rx_buf = st->rx,
+			.bits_per_word = 8,
+			.len = 4,
+		},
+	};
+
+	mutex_lock(&st->buf_lock);
+	st->tx[0] = ADXRS450_READ_DATA | (reg_address >> 7);
+	st->tx[1] = reg_address << 1;
+	st->tx[2] = 0;
+	st->tx[3] = 0;
+
+	if (!(hweight32(be32_to_cpu(*(u32 *)st->tx)) & 1))
+		st->tx[3]  |= ADXRS450_P;
+
+	spi_message_init(&msg);
+	spi_message_add_tail(&xfers[0], &msg);
+	spi_message_add_tail(&xfers[1], &msg);
+	ret = spi_sync(st->us, &msg);
+	if (ret) {
+		dev_err(&st->us->dev, "problem while reading 16 bit register 0x%02x\n",
+				reg_address);
+		goto error_ret;
+	}
+
+	*val = (be32_to_cpu(*(u32 *)st->rx) >> 5) & 0xFFFF;
+
+error_ret:
+	mutex_unlock(&st->buf_lock);
+	return ret;
+}
+
+/**
+ * adxrs450_spi_write_reg_16() - write 2 bytes data to a register pair
+ * @dev: device associated with child of actual actual iio_dev
+ * @reg_address: the address of the lower of the two registers,which should be an even address,
+ * Second register's address is reg_address + 1.
+ * @val: value to be written.
+ **/
+static int adxrs450_spi_write_reg_16(struct device *dev,
+		u8 reg_address,
+		u16 val)
+{
+	struct spi_message msg;
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct adxrs450_state *st = iio_dev_get_devdata(indio_dev);
+	int ret;
+	struct spi_transfer xfers = {
+		.tx_buf = st->tx,
+		.rx_buf = st->rx,
+		.bits_per_word = 8,
+		.len = 4,
+	};
+
+	mutex_lock(&st->buf_lock);
+	st->tx[0] = ADXRS450_WRITE_DATA | reg_address >> 7;
+	st->tx[1] = reg_address << 1 | val >> 15;
+	st->tx[2] = val >> 7;
+	st->tx[3] = val << 1;
+
+	if (!(hweight32(be32_to_cpu(*(u32 *)st->tx)) & 1))
+		st->tx[3]  |= ADXRS450_P;
+
+	spi_message_init(&msg);
+	spi_message_add_tail(&xfers, &msg);
+	ret = spi_sync(st->us, &msg);
+	if (ret)
+		dev_err(&st->us->dev, "problem while writing 16 bit register 0x%02x\n",
+				reg_address);
+	msleep(1); /* enforce sequential transfer delay 0.1ms */
+	mutex_unlock(&st->buf_lock);
+	return ret;
+}
+
+/**
+ * adxrs450_spi_sensor_data() - read 2 bytes sensor data
+ * @dev: device associated with child of actual iio_dev
+ * @val: somewhere to pass back the value read
+ **/
+static int adxrs450_spi_sensor_data(struct device *dev, s16 *val)
+{
+	struct spi_message msg;
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct adxrs450_state *st = iio_dev_get_devdata(indio_dev);
+	int ret;
+	struct spi_transfer xfers[] = {
+		{
+			.tx_buf = st->tx,
+			.bits_per_word = 8,
+			.len = 4,
+			.cs_change = 1,
+		}, {
+			.rx_buf = st->rx,
+			.bits_per_word = 8,
+			.len = 4,
+		},
+	};
+
+	mutex_lock(&st->buf_lock);
+	st->tx[0] = ADXRS450_SENSOR_DATA;
+	st->tx[1] = 0;
+	st->tx[2] = 0;
+	st->tx[3] = 0;
+
+	spi_message_init(&msg);
+	spi_message_add_tail(&xfers[0], &msg);
+	spi_message_add_tail(&xfers[1], &msg);
+	ret = spi_sync(st->us, &msg);
+	if (ret) {
+		dev_err(&st->us->dev, "Problem while reading sensor data\n");
+		goto error_ret;
+	}
+
+	*val = (be32_to_cpu(*(u32 *)st->rx) >> 10) & 0xFFFF;
+
+error_ret:
+	mutex_unlock(&st->buf_lock);
+	return ret;
+}
+
+/**
+ * adxrs450_spi_initial() - use for initializing procedure.
+ * @st: device instance specific data
+ * @val: somewhere to pass back the value read
+ **/
+static int adxrs450_spi_initial(struct adxrs450_state *st,
+		u32 *val, char chk)
+{
+	struct spi_message msg;
+	int ret;
+	struct spi_transfer xfers = {
+		.tx_buf = st->tx,
+		.rx_buf = st->rx,
+		.bits_per_word = 8,
+		.len = 4,
+	};
+
+	mutex_lock(&st->buf_lock);
+	st->tx[0] = ADXRS450_SENSOR_DATA;
+	st->tx[1] = 0;
+	st->tx[2] = 0;
+	st->tx[3] = 0;
+	if (chk)
+		st->tx[3] |= (ADXRS450_CHK | ADXRS450_P);
+	spi_message_init(&msg);
+	spi_message_add_tail(&xfers, &msg);
+	ret = spi_sync(st->us, &msg);
+	if (ret) {
+		dev_err(&st->us->dev, "Problem while reading initializing data\n");
+		goto error_ret;
+	}
+
+	*val = be32_to_cpu(*(u32 *)st->rx);
+
+error_ret:
+	mutex_unlock(&st->buf_lock);
+	return ret;
+}
+
+static ssize_t adxrs450_read_temp(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	int ret;
+	u16 t;
+	ret = adxrs450_spi_read_reg_16(dev,
+			ADXRS450_TEMP1,
+			&t);
+	if (ret)
+		return ret;
+	return sprintf(buf, "%d\n", t >> 7);
+}
+
+static ssize_t adxrs450_read_quad(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	int ret;
+	s16 t;
+	ret = adxrs450_spi_read_reg_16(dev,
+			ADXRS450_QUAD1,
+			&t);
+	if (ret)
+		return ret;
+	return sprintf(buf, "%d\n", t);
+}
+
+static ssize_t adxrs450_write_dnc(struct device *dev,
+		struct device_attribute *attr,
+		const char *buf,
+		size_t len)
+{
+	int ret;
+	long val;
+
+	ret = strict_strtol(buf, 10, &val);
+	if (ret)
+		goto error_ret;
+	ret = adxrs450_spi_write_reg_16(dev,
+			ADXRS450_DNC1,
+			val & 0x3FF);
+error_ret:
+	return ret ? ret : len;
+}
+
+static ssize_t adxrs450_read_sensor_data(struct device *dev,
+		struct device_attribute *attr,
+		char *buf)
+{
+	int ret;
+	s16 t;
+
+	ret = adxrs450_spi_sensor_data(dev, &t);
+	if (ret)
+		return ret;
+
+	return sprintf(buf, "%d\n", t);
+}
+
+/* Recommended Startup Sequence by spec */
+static int adxrs450_initial_setup(struct adxrs450_state *st)
+{
+	u32 t;
+	u16 data;
+	int ret;
+	struct device *dev = &st->indio_dev->dev;
+
+	msleep(ADXRS450_STARTUP_DELAY*2);
+	ret = adxrs450_spi_initial(st, &t, 1);
+	if (ret)
+		return ret;
+	if (t != 0x01)
+		dev_warn(&st->us->dev, "The initial power on response "
+			 "is not correct! Restart without reset?\n");
+
+	msleep(ADXRS450_STARTUP_DELAY);
+	ret = adxrs450_spi_initial(st, &t, 0);
+	if (ret)
+		return ret;
+
+	msleep(ADXRS450_STARTUP_DELAY);
+	ret = adxrs450_spi_initial(st, &t, 0);
+	if (ret)
+		return ret;
+	if (((t & 0xff) | 0x01) != 0xff || ADXRS450_GET_ST(t) != 2) {
+		dev_err(&st->us->dev, "The second response is not correct!\n");
+		return -EIO;
+
+	}
+	ret = adxrs450_spi_initial(st, &t, 0);
+	if (ret)
+		return ret;
+	if (((t & 0xff) | 0x01) != 0xff || ADXRS450_GET_ST(t) != 2) {
+		dev_err(&st->us->dev, "The third response is not correct!\n");
+		return -EIO;
+
+	}
+	ret = adxrs450_spi_read_reg_16(dev, ADXRS450_FAULT1, &data);
+	if (ret)
+		return ret;
+	if (data & 0x0fff) {
+		dev_err(&st->us->dev, "The device is not in normal status!\n");
+		return -EINVAL;
+	}
+	ret = adxrs450_spi_read_reg_16(dev, ADXRS450_PID1, &data);
+	if (ret)
+		return ret;
+	dev_info(&st->us->dev, "The Part ID is 0x%x\n", data);
+
+	ret = adxrs450_spi_read_reg_16(dev, ADXRS450_SNL, &data);
+	if (ret)
+		return ret;
+	t = data;
+	ret = adxrs450_spi_read_reg_16(dev, ADXRS450_SNH, &data);
+	if (ret)
+		return ret;
+	t |= data << 16;
+	dev_info(&st->us->dev, "The Serial Number is 0x%x\n", t);
+
+	return 0;
+}
+
+static IIO_DEV_ATTR_GYRO_Z(adxrs450_read_sensor_data, 0);
+static IIO_DEV_ATTR_TEMP_RAW(adxrs450_read_temp);
+static IIO_DEV_ATTR_GYRO_Z_QUADRATURE_CORRECTION(adxrs450_read_quad, 0);
+static IIO_DEV_ATTR_GYRO_Z_CALIBBIAS(S_IWUSR,
+		NULL, adxrs450_write_dnc, 0);
+static IIO_CONST_ATTR(name, "adxrs450");
+
+static struct attribute *adxrs450_attributes[] = {
+	&iio_dev_attr_gyro_z_raw.dev_attr.attr,
+	&iio_dev_attr_temp_raw.dev_attr.attr,
+	&iio_dev_attr_gyro_z_quadrature_correction_raw.dev_attr.attr,
+	&iio_dev_attr_gyro_z_calibbias.dev_attr.attr,
+	&iio_const_attr_name.dev_attr.attr,
+	NULL
+};
+
+static const struct attribute_group adxrs450_attribute_group = {
+	.attrs = adxrs450_attributes,
+};
+
+static const struct iio_info adxrs450_info = {
+	.attrs = &adxrs450_attribute_group,
+	.driver_module = THIS_MODULE,
+};
+
+static int __devinit adxrs450_probe(struct spi_device *spi)
+{
+	int ret, regdone = 0;
+	struct adxrs450_state *st = kzalloc(sizeof *st, GFP_KERNEL);
+	if (!st) {
+		ret =  -ENOMEM;
+		goto error_ret;
+	}
+	/* This is only used for removal purposes */
+	spi_set_drvdata(spi, st);
+
+	/* Allocate the comms buffers */
+	st->rx = kzalloc(sizeof(*st->rx)*ADXRS450_MAX_RX, GFP_KERNEL);
+	if (st->rx == NULL) {
+		ret = -ENOMEM;
+		goto error_free_st;
+	}
+	st->tx = kzalloc(sizeof(*st->tx)*ADXRS450_MAX_TX, GFP_KERNEL);
+	if (st->tx == NULL) {
+		ret = -ENOMEM;
+		goto error_free_rx;
+	}
+	st->us = spi;
+	mutex_init(&st->buf_lock);
+	/* setup the industrialio driver allocated elements */
+	st->indio_dev = iio_allocate_device(0);
+	if (st->indio_dev == NULL) {
+		ret = -ENOMEM;
+		goto error_free_tx;
+	}
+
+	st->indio_dev->dev.parent = &spi->dev;
+	st->indio_dev->info = &adxrs450_info;
+	st->indio_dev->dev_data = (void *)(st);
+	st->indio_dev->modes = INDIO_DIRECT_MODE;
+
+	ret = iio_device_register(st->indio_dev);
+	if (ret)
+		goto error_free_dev;
+	regdone = 1;
+
+	/* Get the device into a sane initial state */
+	ret = adxrs450_initial_setup(st);
+	if (ret)
+		goto error_initial;
+	return 0;
+
+error_initial:
+error_free_dev:
+	if (regdone)
+		iio_device_unregister(st->indio_dev);
+	else
+		iio_free_device(st->indio_dev);
+error_free_tx:
+	kfree(st->tx);
+error_free_rx:
+	kfree(st->rx);
+error_free_st:
+	kfree(st);
+error_ret:
+	return ret;
+}
+
+static int adxrs450_remove(struct spi_device *spi)
+{
+	struct adxrs450_state *st = spi_get_drvdata(spi);
+
+	iio_device_unregister(st->indio_dev);
+	kfree(st->tx);
+	kfree(st->rx);
+	kfree(st);
+
+	return 0;
+}
+
+static struct spi_driver adxrs450_driver = {
+	.driver = {
+		.name = "adxrs450",
+		.owner = THIS_MODULE,
+	},
+	.probe = adxrs450_probe,
+	.remove = __devexit_p(adxrs450_remove),
+};
+
+static __init int adxrs450_init(void)
+{
+	return spi_register_driver(&adxrs450_driver);
+}
+module_init(adxrs450_init);
+
+static __exit void adxrs450_exit(void)
+{
+	spi_unregister_driver(&adxrs450_driver);
+}
+module_exit(adxrs450_exit);
+
+MODULE_AUTHOR("Cliff Cai <cliff.cai@xxxxxxxxxx>");
+MODULE_DESCRIPTION("Analog Devices ADXRS450 Gyroscope SPI driver");
+MODULE_LICENSE("GPL v2");
diff -druN linux-2.6.39-libre/drivers/staging/iio/gyro/adxrs450.h linux-3.0-rc7-libre/drivers/staging/iio/gyro/adxrs450.h
--- linux-2.6.39-libre/drivers/staging/iio/gyro/adxrs450.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/staging/iio/gyro/adxrs450.h	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,58 @@
+#ifndef SPI_ADXRS450_H_
+#define SPI_ADXRS450_H_
+
+#define ADXRS450_STARTUP_DELAY	50 /* ms */
+
+/* The MSB for the spi commands */
+#define ADXRS450_SENSOR_DATA    0x20
+#define ADXRS450_WRITE_DATA	0x40
+#define ADXRS450_READ_DATA	0x80
+
+#define ADXRS450_RATE1	0x00	/* Rate Registers */
+#define ADXRS450_TEMP1	0x02	/* Temperature Registers */
+#define ADXRS450_LOCST1	0x04	/* Low CST Memory Registers */
+#define ADXRS450_HICST1	0x06	/* High CST Memory Registers */
+#define ADXRS450_QUAD1	0x08	/* Quad Memory Registers */
+#define ADXRS450_FAULT1	0x0A	/* Fault Registers */
+#define ADXRS450_PID1	0x0C	/* Part ID Register 1 */
+#define ADXRS450_SNH	0x0E	/* Serial Number Registers, 4 bytes */
+#define ADXRS450_SNL	0x10
+#define ADXRS450_DNC1	0x12	/* Dynamic Null Correction Registers */
+/* Check bits */
+#define ADXRS450_P	0x01
+#define ADXRS450_CHK	0x02
+#define ADXRS450_CST	0x04
+#define ADXRS450_PWR	0x08
+#define ADXRS450_POR	0x10
+#define ADXRS450_NVM	0x20
+#define ADXRS450_Q	0x40
+#define ADXRS450_PLL	0x80
+#define ADXRS450_UV	0x100
+#define ADXRS450_OV	0x200
+#define ADXRS450_AMP	0x400
+#define ADXRS450_FAIL	0x800
+
+#define ADXRS450_WRERR_MASK	(0x7 << 29)
+
+#define ADXRS450_MAX_RX 4
+#define ADXRS450_MAX_TX 4
+
+#define ADXRS450_GET_ST(a)	((a >> 26) & 0x3)
+
+/**
+ * struct adxrs450_state - device instance specific data
+ * @us:			actual spi_device
+ * @indio_dev:		industrial I/O device structure
+ * @tx:			transmit buffer
+ * @rx:			recieve buffer
+ * @buf_lock:		mutex to protect tx and rx
+ **/
+struct adxrs450_state {
+	struct spi_device		*us;
+	struct iio_dev			*indio_dev;
+	u8				*tx;
+	u8				*rx;
+	struct mutex			buf_lock;
+};
+
+#endif /* SPI_ADXRS450_H_ */
diff -druN linux-2.6.39-libre/drivers/staging/iio/gyro/gyro.h linux-3.0-rc7-libre/drivers/staging/iio/gyro/gyro.h
--- linux-2.6.39-libre/drivers/staging/iio/gyro/gyro.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/iio/gyro/gyro.h	2011-07-11 19:51:52.000000000 -0400
@@ -57,6 +57,9 @@
 #define IIO_DEV_ATTR_GYRO_Z_CALIBSCALE(_mode, _show, _store, _addr)		\
 	IIO_DEVICE_ATTR(gyro_z_calibscale, _mode, _show, _store, _addr)
 
+#define IIO_DEV_ATTR_GYRO_Z_QUADRATURE_CORRECTION(_show, _addr)		\
+	IIO_DEVICE_ATTR(gyro_z_quadrature_correction_raw, S_IRUGO, _show, NULL, _addr)
+
 #define IIO_DEV_ATTR_GYRO(_show, _addr)			\
 	IIO_DEVICE_ATTR(gyro_raw, S_IRUGO, _show, NULL, _addr)
 
diff -druN linux-2.6.39-libre/drivers/staging/iio/gyro/Kconfig linux-3.0-rc7-libre/drivers/staging/iio/gyro/Kconfig
--- linux-2.6.39-libre/drivers/staging/iio/gyro/Kconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/iio/gyro/Kconfig	2011-07-11 19:51:52.000000000 -0400
@@ -35,3 +35,13 @@
 
 	  This driver can also be built as a module.  If so, the module
 	  will be called adis16260.
+
+config ADXRS450
+	tristate "Analog Devices ADXRS450 Digital Output Gyroscope SPI driver"
+	depends on SPI
+	help
+	  Say yes here to build support for Analog Devices ADXRS450 programmable
+	  digital output gyroscope.
+
+	  This driver can also be built as a module.  If so, the module
+	  will be called adxrs450.
diff -druN linux-2.6.39-libre/drivers/staging/iio/gyro/Makefile linux-3.0-rc7-libre/drivers/staging/iio/gyro/Makefile
--- linux-2.6.39-libre/drivers/staging/iio/gyro/Makefile	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/iio/gyro/Makefile	2011-07-11 19:51:52.000000000 -0400
@@ -17,3 +17,6 @@
 
 adis16251-y             := adis16251_core.o
 obj-$(CONFIG_ADIS16251) += adis16251.o
+
+adxrs450-y             := adxrs450_core.o
+obj-$(CONFIG_ADXRS450) += adxrs450.o
diff -druN linux-2.6.39-libre/drivers/staging/iio/iio.h linux-3.0-rc7-libre/drivers/staging/iio/iio.h
--- linux-2.6.39-libre/drivers/staging/iio/iio.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/iio/iio.h	2011-07-11 19:51:52.000000000 -0400
@@ -12,6 +12,7 @@
 
 #include <linux/device.h>
 #include <linux/cdev.h>
+#include <linux/irq.h>
 #include "sysfs.h"
 #include "chrdev.h"
 
@@ -24,8 +25,157 @@
 /* Event interface flags */
 #define IIO_BUSY_BIT_POS 1
 
-struct iio_dev;
+/* naughty temporary hack to match these against the event version
+   - need to flattern these together */
+enum iio_chan_type {
+	/* real channel types */
+	IIO_IN,
+	IIO_CURRENT,
+	IIO_POWER,
+	IIO_ACCEL,
+	IIO_IN_DIFF,
+	IIO_GYRO,
+	IIO_MAGN,
+	IIO_LIGHT,
+	IIO_INTENSITY,
+	IIO_PROXIMITY,
+	IIO_TEMP,
+	IIO_INCLI,
+	IIO_ROT,
+	IIO_ANGL,
+	IIO_TIMESTAMP,
+};
+
+#define IIO_MOD_X			0
+#define IIO_MOD_LIGHT_BOTH		0
+#define IIO_MOD_Y			1
+#define IIO_MOD_LIGHT_IR		1
+#define IIO_MOD_Z			2
+#define IIO_MOD_X_AND_Y			3
+#define IIO_MOD_X_ANX_Z			4
+#define IIO_MOD_Y_AND_Z			5
+#define IIO_MOD_X_AND_Y_AND_Z		6
+#define IIO_MOD_X_OR_Y			7
+#define IIO_MOD_X_OR_Z			8
+#define IIO_MOD_Y_OR_Z			9
+#define IIO_MOD_X_OR_Y_OR_Z		10
+
+/* Could add the raw attributes as well - allowing buffer only devices */
+enum iio_chan_info_enum {
+	IIO_CHAN_INFO_SCALE_SHARED,
+	IIO_CHAN_INFO_SCALE_SEPARATE,
+	IIO_CHAN_INFO_OFFSET_SHARED,
+	IIO_CHAN_INFO_OFFSET_SEPARATE,
+	IIO_CHAN_INFO_CALIBSCALE_SHARED,
+	IIO_CHAN_INFO_CALIBSCALE_SEPARATE,
+	IIO_CHAN_INFO_CALIBBIAS_SHARED,
+	IIO_CHAN_INFO_CALIBBIAS_SEPARATE,
+	IIO_CHAN_INFO_PEAK_SHARED,
+	IIO_CHAN_INFO_PEAK_SEPARATE,
+	IIO_CHAN_INFO_PEAK_SCALE_SHARED,
+	IIO_CHAN_INFO_PEAK_SCALE_SEPARATE,
+};
+
+/**
+ * struct iio_chan_spec - specification of a single channel
+ * @type:		What type of measurement is the channel making.
+ * @channel:		What number or name do we wish to asign the channel.
+ * @channel2:		If there is a second number for a differential
+ *			channel then this is it. If modified is set then the
+ *			value here specifies the modifier.
+ * @address:		Driver specific identifier.
+ * @scan_index:	Monotonic index to give ordering in scans when read
+ *			from a buffer.
+ * @scan_type:		Sign:		's' or 'u' to specify signed or unsigned
+ *			realbits:	Number of valid bits of data
+ *			storage_bits:	Realbits + padding
+ *			shift:		Shift right by this before masking out
+ *					realbits.
+ * @info_mask:		What information is to be exported about this channel.
+ *			This includes calibbias, scale etc.
+ * @event_mask:	What events can this channel produce.
+ * @extend_name:	Allows labeling of channel attributes with an
+ *			informative name. Note this has no effect codes etc,
+ *			unlike modifiers.
+ * @processed_val:	Flag to specify the data access attribute should be
+ *			*_input rather than *_raw.
+ * @modified:		Does a modifier apply to this channel. What these are
+ *			depends on the channel type.  Modifier is set in
+ *			channel2. Examples are IIO_MOD_X for axial sensors about
+ *			the 'x' axis.
+ * @indexed:		Specify the channel has a numerical index. If not,
+ *			the value in channel will be suppressed for attribute
+ *			but not for event codes. Typically set it to 0 when
+ *			the index is false.
+ */
+struct iio_chan_spec {
+	enum iio_chan_type	type;
+	int			channel;
+	int			channel2;
+	unsigned long		address;
+	int			scan_index;
+	struct {
+		char	sign;
+		u8	realbits;
+		u8	storagebits;
+		u8	shift;
+	} scan_type;
+	const long		info_mask;
+	const long		event_mask;
+	const char		*extend_name;
+	unsigned		processed_val:1;
+	unsigned		modified:1;
+	unsigned		indexed:1;
+};
+/* Meant for internal use only */
+void __iio_device_attr_deinit(struct device_attribute *dev_attr);
+int __iio_device_attr_init(struct device_attribute *dev_attr,
+			   const char *postfix,
+			   struct iio_chan_spec const *chan,
+			   ssize_t (*readfunc)(struct device *dev,
+					       struct device_attribute *attr,
+					       char *buf),
+			   ssize_t (*writefunc)(struct device *dev,
+						struct device_attribute *attr,
+						const char *buf,
+						size_t len),
+			   bool generic);
+#define IIO_ST(si, rb, sb, sh)						\
+	{ .sign = si, .realbits = rb, .storagebits = sb, .shift = sh }
+
+#define IIO_CHAN(_type, _mod, _indexed, _proc, _name, _chan, _chan2,	\
+		 _inf_mask, _address, _si, _stype, _event_mask)		\
+	{ .type = _type,						\
+	  .modified = _mod,						\
+	  .indexed = _indexed,						\
+	  .processed_val = _proc,					\
+	  .extend_name = _name,						\
+	  .channel = _chan,						\
+	  .channel2 = _chan2,						\
+	  .info_mask = _inf_mask,					\
+	  .address = _address,						\
+	  .scan_index = _si,						\
+	  .scan_type = _stype,						\
+	  .event_mask = _event_mask }
 
+#define IIO_CHAN_SOFT_TIMESTAMP(_si)					\
+	{ .type = IIO_TIMESTAMP, .channel = -1,				\
+			.scan_index = _si, .scan_type = IIO_ST('s', 64, 64, 0) }
+
+int __iio_add_chan_devattr(const char *postfix,
+			   const char *group,
+			   struct iio_chan_spec const *chan,
+			   ssize_t (*func)(struct device *dev,
+					   struct device_attribute *attr,
+					   char *buf),
+			   ssize_t (*writefunc)(struct device *dev,
+						struct device_attribute *attr,
+						const char *buf,
+						size_t len),
+			   int mask,
+			   bool generic,
+			   struct device *dev,
+			   struct list_head *attr_list);
 /**
  * iio_get_time_ns() - utility function to get a time stamp for events etc
  **/
@@ -41,26 +191,6 @@
 	return timespec_to_ns(&ts);
 }
 
-/**
- * iio_add_event_to_list() - Wraps adding to event lists
- * @el:		the list element of the event to be handled.
- * @head:	the list associated with the event handler being used.
- *
- * Does reference counting to allow shared handlers.
- **/
-void iio_add_event_to_list(struct iio_event_handler_list *el,
-			   struct list_head *head);
-
-/**
- * iio_remove_event_from_list() - Wraps removing from event list
- * @el:		element to be removed
- * @head:	associate list head for the interrupt handler.
- *
- * Does reference counting to allow shared handlers.
- **/
-void iio_remove_event_from_list(struct iio_event_handler_list *el,
-				struct list_head *head);
-
 /* Device operating modes */
 #define INDIO_DIRECT_MODE		0x01
 #define INDIO_RING_TRIGGERED		0x02
@@ -70,6 +200,62 @@
 
 /* Vast majority of this is set by the industrialio subsystem on a
  * call to iio_device_register. */
+#define IIO_VAL_INT 1
+#define IIO_VAL_INT_PLUS_MICRO 2
+
+/**
+ * struct iio_info - constant information about device
+ * @driver_module:	module structure used to ensure correct
+ *			ownership of chrdevs etc
+ * @num_interrupt_lines:number of physical interrupt lines from device
+ * @event_attrs:	event control attributes
+ * @attrs:		general purpose device attributes
+ * @read_raw:		function to request a value from the device.
+ *			mask specifies which value. Note 0 means a reading of
+ *			the channel in question.  Return value will specify the
+ *			type of value returned by the device. val and val2 will
+ *			contain the elements making up the returned value.
+ * @write_raw:		function to write a value to the device.
+ *			Parameters are the same as for read_raw.
+ * @read_event_config:	find out if the event is enabled.
+ * @write_event_config:	set if the event is enabled.
+ * @read_event_value:	read a value associated with the event. Meaning
+ *			is event dependant. event_code specifies which event.
+ * @write_event_value:	write the value associate with the event.
+ *			Meaning is event dependent.
+ **/
+struct iio_info {
+	struct module			*driver_module;
+	int				num_interrupt_lines;
+	struct attribute_group		*event_attrs;
+	const struct attribute_group	*attrs;
+
+	int (*read_raw)(struct iio_dev *indio_dev,
+			struct iio_chan_spec const *chan,
+			int *val,
+			int *val2,
+			long mask);
+
+	int (*write_raw)(struct iio_dev *indio_dev,
+			 struct iio_chan_spec const *chan,
+			 int val,
+			 int val2,
+			 long mask);
+
+	int (*read_event_config)(struct iio_dev *indio_dev,
+				 int event_code);
+
+	int (*write_event_config)(struct iio_dev *indio_dev,
+				  int event_code,
+				  int state);
+
+	int (*read_event_value)(struct iio_dev *indio_dev,
+				int event_code,
+				int *val);
+	int (*write_event_value)(struct iio_dev *indio_dev,
+				 int event_code,
+				 int val);
+};
 
 /**
  * struct iio_dev - industrial I/O device
@@ -79,13 +265,6 @@
  * @currentmode:	[DRIVER] current operating mode
  * @dev:		[DRIVER] device structure, should be assigned a parent
  *			and owner
- * @attrs:		[DRIVER] general purpose device attributes
- * @driver_module:	[DRIVER] module structure used to ensure correct
- *			ownership of chrdevs etc
- * @num_interrupt_lines:[DRIVER] number of physical interrupt lines from device
- * @interrupts:		[INTERN] interrupt line specific event lists etc
- * @event_attrs:	[DRIVER] event control attributes
- * @event_conf_attrs:	[DRIVER] event configuration attributes
  * @event_interfaces:	[INTERN] event chrdevs associated with interrupt lines
  * @ring:		[DRIVER] any ring buffer present
  * @mlock:		[INTERN] lock used to prevent simultaneous device state
@@ -93,6 +272,11 @@
  * @available_scan_masks: [DRIVER] optional array of allowed bitmasks
  * @trig:		[INTERN] current device trigger (ring buffer modes)
  * @pollfunc:		[DRIVER] function run on trigger being received
+ * @channels:		[DRIVER] channel specification structure table
+ * @num_channels:	[DRIVER] number of chanels specified in @channels.
+ * @channel_attr_list:	[INTERN] keep track of automatically created channel
+ *			attributes.
+ * @name:		[DRIVER] name of the device.
  **/
 struct iio_dev {
 	int				id;
@@ -100,13 +284,6 @@
 	int				modes;
 	int				currentmode;
 	struct device			dev;
-	const struct attribute_group	*attrs;
-	struct module			*driver_module;
-
-	int				num_interrupt_lines;
-	struct iio_interrupt		**interrupts;
-	struct attribute_group		*event_attrs;
-	struct attribute_group		*event_conf_attrs;
 
 	struct iio_event_interface	*event_interfaces;
 
@@ -116,6 +293,13 @@
 	u32				*available_scan_masks;
 	struct iio_trigger		*trig;
 	struct iio_poll_func		*pollfunc;
+
+	struct iio_chan_spec const *channels;
+	int num_channels;
+
+	struct list_head channel_attr_list;
+	const char *name;
+	const struct iio_info *info;
 };
 
 /**
@@ -131,47 +315,6 @@
 void iio_device_unregister(struct iio_dev *dev_info);
 
 /**
- * struct iio_interrupt - wrapper used to allow easy handling of multiple
- *			physical interrupt lines
- * @dev_info:		the iio device for which the is an interrupt line
- * @line_number:	associated line number
- * @id:			ida allocated unique id number
- * @irq:		associate interrupt number
- * @ev_list:		event handler list for associated events
- * @ev_list_lock:	ensure only one access to list at a time
- **/
-struct iio_interrupt {
-	struct iio_dev			*dev_info;
-	int				line_number;
-	int				id;
-	int				irq;
-	struct list_head		ev_list;
-	spinlock_t			ev_list_lock;
-};
-
-#define to_iio_interrupt(i) container_of(i, struct iio_interrupt, ev_list)
-
-/**
- * iio_register_interrupt_line() - Tell IIO about interrupt lines
- *
- * @irq:		Typically provided via platform data
- * @dev_info:		IIO device info structure for device
- * @line_number:	Which interrupt line of the device is this?
- * @type:		Interrupt type (e.g. edge triggered etc)
- * @name:		Identifying name.
- **/
-int iio_register_interrupt_line(unsigned int			irq,
-				struct iio_dev			*dev_info,
-				int				line_number,
-				unsigned long			type,
-				const char			*name);
-
-void iio_unregister_interrupt_line(struct iio_dev *dev_info,
-				   int line_number);
-
-
-
-/**
  * iio_push_event() - try to add event to the list for userspace reading
  * @dev_info:		IIO device structure
  * @ev_line:		Which event line (hardware interrupt)
@@ -183,50 +326,6 @@
 		  int ev_code,
 		  s64 timestamp);
 
-/**
- * __iio_push_event() - tries to add an event to the list associated with a chrdev
- * @ev_int:		the event interface to which we are pushing the event
- * @ev_code:		the outgoing event code
- * @timestamp:		timestamp of the event
- * @shared_pointer_p:	the shared event pointer
- **/
-int __iio_push_event(struct iio_event_interface *ev_int,
-		    int ev_code,
-		    s64 timestamp,
-		    struct iio_shared_ev_pointer*
-		    shared_pointer_p);
-/**
- * __iio_change_event() - change an event code in case of event escalation
- * @ev:			the event to be changed
- * @ev_code:		new event code
- * @timestamp:		new timestamp
- **/
-void __iio_change_event(struct iio_detected_event_list *ev,
-			int ev_code,
-			s64 timestamp);
-
-/**
- * iio_setup_ev_int() - configure an event interface (chrdev)
- * @name:		name used for resulting sysfs directory etc.
- * @ev_int:		interface we are configuring
- * @owner:		module that is responsible for registering this ev_int
- * @dev:		device whose ev_int this is
- **/
-int iio_setup_ev_int(struct iio_event_interface *ev_int,
-		     const char *name,
-		     struct module *owner,
-		     struct device *dev);
-
-void iio_free_ev_int(struct iio_event_interface *ev_int);
-
-/**
- * iio_allocate_chrdev() - Allocate a chrdev
- * @handler:	struct that contains relevant file handling for chrdev
- * @dev_info:	iio_dev for which chrdev is being created
- **/
-int iio_allocate_chrdev(struct iio_handler *handler, struct iio_dev *dev_info);
-void iio_deallocate_chrdev(struct iio_handler *handler);
-
 /* Used to distinguish between bipolar and unipolar scan elemenents.
  * Whilst this may seem obvious, we may well want to change the representation
  * in the future!*/
@@ -264,10 +363,25 @@
 	return d->dev_data;
 }
 
+
+/* Can we make this smaller? */
+#define IIO_ALIGN L1_CACHE_BYTES
 /**
  * iio_allocate_device() - allocate an iio_dev from a driver
+ * @sizeof_priv: Space to allocate for private structure.
  **/
-struct iio_dev *iio_allocate_device(void);
+struct iio_dev *iio_allocate_device(int sizeof_priv);
+
+static inline void *iio_priv(const struct iio_dev *dev)
+{
+	return (char *)dev + ALIGN(sizeof(struct iio_dev), IIO_ALIGN);
+}
+
+static inline struct iio_dev *iio_priv_to_dev(void *priv)
+{
+	return (struct iio_dev *)((char *)priv -
+				  ALIGN(sizeof(struct iio_dev), IIO_ALIGN));
+}
 
 /**
  * iio_free_device() - free an iio_dev from a driver
diff -druN linux-2.6.39-libre/drivers/staging/iio/imu/adis16300_core.c linux-3.0-rc7-libre/drivers/staging/iio/imu/adis16300_core.c
--- linux-2.6.39-libre/drivers/staging/iio/imu/adis16300_core.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/iio/imu/adis16300_core.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,756 +0,0 @@
-/*
- * ADIS16300 Four Degrees of Freedom Inertial Sensor Driver
- *
- * Copyright 2010 Analog Devices Inc.
- *
- * Licensed under the GPL-2 or later.
- */
-
-#include <linux/interrupt.h>
-#include <linux/irq.h>
-#include <linux/gpio.h>
-#include <linux/delay.h>
-#include <linux/mutex.h>
-#include <linux/device.h>
-#include <linux/kernel.h>
-#include <linux/spi/spi.h>
-#include <linux/slab.h>
-#include <linux/sysfs.h>
-#include <linux/list.h>
-
-#include "../iio.h"
-#include "../sysfs.h"
-#include "../ring_generic.h"
-#include "../accel/accel.h"
-#include "../accel/inclinometer.h"
-#include "../gyro/gyro.h"
-#include "../adc/adc.h"
-
-#include "adis16300.h"
-
-#define DRIVER_NAME		"adis16300"
-
-static int adis16300_check_status(struct device *dev);
-
-/**
- * adis16300_spi_write_reg_8() - write single byte to a register
- * @dev: device associated with child of actual device (iio_dev or iio_trig)
- * @reg_address: the address of the register to be written
- * @val: the value to write
- **/
-static int adis16300_spi_write_reg_8(struct device *dev,
-		u8 reg_address,
-		u8 val)
-{
-	int ret;
-	struct iio_dev *indio_dev = dev_get_drvdata(dev);
-	struct adis16300_state *st = iio_dev_get_devdata(indio_dev);
-
-	mutex_lock(&st->buf_lock);
-	st->tx[0] = ADIS16300_WRITE_REG(reg_address);
-	st->tx[1] = val;
-
-	ret = spi_write(st->us, st->tx, 2);
-	mutex_unlock(&st->buf_lock);
-
-	return ret;
-}
-
-/**
- * adis16300_spi_write_reg_16() - write 2 bytes to a pair of registers
- * @dev: device associated with child of actual device (iio_dev or iio_trig)
- * @reg_address: the address of the lower of the two registers. Second register
- *               is assumed to have address one greater.
- * @val: value to be written
- **/
-static int adis16300_spi_write_reg_16(struct device *dev,
-		u8 lower_reg_address,
-		u16 value)
-{
-	int ret;
-	struct spi_message msg;
-	struct iio_dev *indio_dev = dev_get_drvdata(dev);
-	struct adis16300_state *st = iio_dev_get_devdata(indio_dev);
-	struct spi_transfer xfers[] = {
-		{
-			.tx_buf = st->tx,
-			.bits_per_word = 8,
-			.len = 2,
-			.cs_change = 1,
-			.delay_usecs = 75,
-		}, {
-			.tx_buf = st->tx + 2,
-			.bits_per_word = 8,
-			.len = 2,
-			.cs_change = 1,
-			.delay_usecs = 75,
-		},
-	};
-
-	mutex_lock(&st->buf_lock);
-	st->tx[0] = ADIS16300_WRITE_REG(lower_reg_address);
-	st->tx[1] = value & 0xFF;
-	st->tx[2] = ADIS16300_WRITE_REG(lower_reg_address + 1);
-	st->tx[3] = (value >> 8) & 0xFF;
-
-	spi_message_init(&msg);
-	spi_message_add_tail(&xfers[0], &msg);
-	spi_message_add_tail(&xfers[1], &msg);
-	ret = spi_sync(st->us, &msg);
-	mutex_unlock(&st->buf_lock);
-
-	return ret;
-}
-
-/**
- * adis16300_spi_read_reg_16() - read 2 bytes from a 16-bit register
- * @dev: device associated with child of actual device (iio_dev or iio_trig)
- * @reg_address: the address of the lower of the two registers. Second register
- *               is assumed to have address one greater.
- * @val: somewhere to pass back the value read
- **/
-static int adis16300_spi_read_reg_16(struct device *dev,
-		u8 lower_reg_address,
-		u16 *val)
-{
-	struct spi_message msg;
-	struct iio_dev *indio_dev = dev_get_drvdata(dev);
-	struct adis16300_state *st = iio_dev_get_devdata(indio_dev);
-	int ret;
-	struct spi_transfer xfers[] = {
-		{
-			.tx_buf = st->tx,
-			.bits_per_word = 8,
-			.len = 2,
-			.cs_change = 1,
-			.delay_usecs = 75,
-		}, {
-			.rx_buf = st->rx,
-			.bits_per_word = 8,
-			.len = 2,
-			.cs_change = 1,
-			.delay_usecs = 75,
-		},
-	};
-
-	mutex_lock(&st->buf_lock);
-	st->tx[0] = ADIS16300_READ_REG(lower_reg_address);
-	st->tx[1] = 0;
-	st->tx[2] = 0;
-	st->tx[3] = 0;
-
-	spi_message_init(&msg);
-	spi_message_add_tail(&xfers[0], &msg);
-	spi_message_add_tail(&xfers[1], &msg);
-	ret = spi_sync(st->us, &msg);
-	if (ret) {
-		dev_err(&st->us->dev,
-			"problem when reading 16 bit register 0x%02X",
-			lower_reg_address);
-		goto error_ret;
-	}
-	*val = (st->rx[0] << 8) | st->rx[1];
-
-error_ret:
-	mutex_unlock(&st->buf_lock);
-	return ret;
-}
-
-static ssize_t adis16300_spi_read_signed(struct device *dev,
-		struct device_attribute *attr,
-		char *buf,
-		unsigned bits)
-{
-	int ret;
-	s16 val = 0;
-	unsigned shift = 16 - bits;
-	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
-
-	ret = adis16300_spi_read_reg_16(dev, this_attr->address, (u16 *)&val);
-	if (ret)
-		return ret;
-
-	if (val & ADIS16300_ERROR_ACTIVE)
-		adis16300_check_status(dev);
-	val = ((s16)(val << shift) >> shift);
-	return sprintf(buf, "%d\n", val);
-}
-
-static ssize_t adis16300_read_12bit_unsigned(struct device *dev,
-		struct device_attribute *attr,
-		char *buf)
-{
-	int ret;
-	u16 val = 0;
-	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
-
-	ret = adis16300_spi_read_reg_16(dev, this_attr->address, &val);
-	if (ret)
-		return ret;
-
-	if (val & ADIS16300_ERROR_ACTIVE)
-		adis16300_check_status(dev);
-
-	return sprintf(buf, "%u\n", val & 0x0FFF);
-}
-
-static ssize_t adis16300_read_14bit_unsigned(struct device *dev,
-		struct device_attribute *attr,
-		char *buf)
-{
-	int ret;
-	u16 val = 0;
-	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
-
-	ret = adis16300_spi_read_reg_16(dev, this_attr->address, &val);
-	if (ret)
-		return ret;
-
-	if (val & ADIS16300_ERROR_ACTIVE)
-		adis16300_check_status(dev);
-
-	return sprintf(buf, "%u\n", val & 0x3FFF);
-}
-
-static ssize_t adis16300_read_14bit_signed(struct device *dev,
-		struct device_attribute *attr,
-		char *buf)
-{
-	struct iio_dev *indio_dev = dev_get_drvdata(dev);
-	ssize_t ret;
-
-	/* Take the iio_dev status lock */
-	mutex_lock(&indio_dev->mlock);
-	ret =  adis16300_spi_read_signed(dev, attr, buf, 14);
-	mutex_unlock(&indio_dev->mlock);
-
-	return ret;
-}
-
-static ssize_t adis16300_read_12bit_signed(struct device *dev,
-		struct device_attribute *attr,
-		char *buf)
-{
-	struct iio_dev *indio_dev = dev_get_drvdata(dev);
-	ssize_t ret;
-
-	/* Take the iio_dev status lock */
-	mutex_lock(&indio_dev->mlock);
-	ret =  adis16300_spi_read_signed(dev, attr, buf, 12);
-	mutex_unlock(&indio_dev->mlock);
-
-	return ret;
-}
-
-static ssize_t adis16300_read_13bit_signed(struct device *dev,
-		struct device_attribute *attr,
-		char *buf)
-{
-	struct iio_dev *indio_dev = dev_get_drvdata(dev);
-	ssize_t ret;
-
-	/* Take the iio_dev status lock */
-	mutex_lock(&indio_dev->mlock);
-	ret =  adis16300_spi_read_signed(dev, attr, buf, 13);
-	mutex_unlock(&indio_dev->mlock);
-
-	return ret;
-}
-
-static ssize_t adis16300_write_16bit(struct device *dev,
-		struct device_attribute *attr,
-		const char *buf,
-		size_t len)
-{
-	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
-	int ret;
-	long val;
-
-	ret = strict_strtol(buf, 10, &val);
-	if (ret)
-		goto error_ret;
-	ret = adis16300_spi_write_reg_16(dev, this_attr->address, val);
-
-error_ret:
-	return ret ? ret : len;
-}
-
-static ssize_t adis16300_read_frequency(struct device *dev,
-		struct device_attribute *attr,
-		char *buf)
-{
-	int ret, len = 0;
-	u16 t;
-	int sps;
-	ret = adis16300_spi_read_reg_16(dev,
-			ADIS16300_SMPL_PRD,
-			&t);
-	if (ret)
-		return ret;
-	sps =  (t & ADIS16300_SMPL_PRD_TIME_BASE) ? 53 : 1638;
-	sps /= (t & ADIS16300_SMPL_PRD_DIV_MASK) + 1;
-	len = sprintf(buf, "%d SPS\n", sps);
-	return len;
-}
-
-static ssize_t adis16300_write_frequency(struct device *dev,
-		struct device_attribute *attr,
-		const char *buf,
-		size_t len)
-{
-	struct iio_dev *indio_dev = dev_get_drvdata(dev);
-	struct adis16300_state *st = iio_dev_get_devdata(indio_dev);
-	long val;
-	int ret;
-	u8 t;
-
-	ret = strict_strtol(buf, 10, &val);
-	if (ret)
-		return ret;
-
-	mutex_lock(&indio_dev->mlock);
-
-	t = (1638 / val);
-	if (t > 0)
-		t--;
-	t &= ADIS16300_SMPL_PRD_DIV_MASK;
-	if ((t & ADIS16300_SMPL_PRD_DIV_MASK) >= 0x0A)
-		st->us->max_speed_hz = ADIS16300_SPI_SLOW;
-	else
-		st->us->max_speed_hz = ADIS16300_SPI_FAST;
-
-	ret = adis16300_spi_write_reg_8(dev,
-			ADIS16300_SMPL_PRD,
-			t);
-
-	mutex_unlock(&indio_dev->mlock);
-
-	return ret ? ret : len;
-}
-
-static int adis16300_reset(struct device *dev)
-{
-	int ret;
-	ret = adis16300_spi_write_reg_8(dev,
-			ADIS16300_GLOB_CMD,
-			ADIS16300_GLOB_CMD_SW_RESET);
-	if (ret)
-		dev_err(dev, "problem resetting device");
-
-	return ret;
-}
-
-static ssize_t adis16300_write_reset(struct device *dev,
-		struct device_attribute *attr,
-		const char *buf, size_t len)
-{
-	if (len < 1)
-		return -1;
-	switch (buf[0]) {
-	case '1':
-	case 'y':
-	case 'Y':
-		return adis16300_reset(dev);
-	}
-	return -1;
-}
-
-int adis16300_set_irq(struct device *dev, bool enable)
-{
-	int ret;
-	u16 msc;
-	ret = adis16300_spi_read_reg_16(dev, ADIS16300_MSC_CTRL, &msc);
-	if (ret)
-		goto error_ret;
-
-	msc |= ADIS16300_MSC_CTRL_DATA_RDY_POL_HIGH;
-	msc &= ~ADIS16300_MSC_CTRL_DATA_RDY_DIO2;
-	if (enable)
-		msc |= ADIS16300_MSC_CTRL_DATA_RDY_EN;
-	else
-		msc &= ~ADIS16300_MSC_CTRL_DATA_RDY_EN;
-
-	ret = adis16300_spi_write_reg_16(dev, ADIS16300_MSC_CTRL, msc);
-	if (ret)
-		goto error_ret;
-
-error_ret:
-	return ret;
-}
-
-/* Power down the device */
-static int adis16300_stop_device(struct device *dev)
-{
-	int ret;
-	u16 val = ADIS16300_SLP_CNT_POWER_OFF;
-
-	ret = adis16300_spi_write_reg_16(dev, ADIS16300_SLP_CNT, val);
-	if (ret)
-		dev_err(dev, "problem with turning device off: SLP_CNT");
-
-	return ret;
-}
-
-static int adis16300_self_test(struct device *dev)
-{
-	int ret;
-	ret = adis16300_spi_write_reg_16(dev,
-			ADIS16300_MSC_CTRL,
-			ADIS16300_MSC_CTRL_MEM_TEST);
-	if (ret) {
-		dev_err(dev, "problem starting self test");
-		goto err_ret;
-	}
-
-	adis16300_check_status(dev);
-
-err_ret:
-	return ret;
-}
-
-static int adis16300_check_status(struct device *dev)
-{
-	u16 status;
-	int ret;
-
-	ret = adis16300_spi_read_reg_16(dev, ADIS16300_DIAG_STAT, &status);
-
-	if (ret < 0) {
-		dev_err(dev, "Reading status failed\n");
-		goto error_ret;
-	}
-	ret = status;
-	if (status & ADIS16300_DIAG_STAT_ZACCL_FAIL)
-		dev_err(dev, "Z-axis accelerometer self-test failure\n");
-	if (status & ADIS16300_DIAG_STAT_YACCL_FAIL)
-		dev_err(dev, "Y-axis accelerometer self-test failure\n");
-	if (status & ADIS16300_DIAG_STAT_XACCL_FAIL)
-		dev_err(dev, "X-axis accelerometer self-test failure\n");
-	if (status & ADIS16300_DIAG_STAT_XGYRO_FAIL)
-		dev_err(dev, "X-axis gyroscope self-test failure\n");
-	if (status & ADIS16300_DIAG_STAT_ALARM2)
-		dev_err(dev, "Alarm 2 active\n");
-	if (status & ADIS16300_DIAG_STAT_ALARM1)
-		dev_err(dev, "Alarm 1 active\n");
-	if (status & ADIS16300_DIAG_STAT_FLASH_CHK)
-		dev_err(dev, "Flash checksum error\n");
-	if (status & ADIS16300_DIAG_STAT_SELF_TEST)
-		dev_err(dev, "Self test error\n");
-	if (status & ADIS16300_DIAG_STAT_OVERFLOW)
-		dev_err(dev, "Sensor overrange\n");
-	if (status & ADIS16300_DIAG_STAT_SPI_FAIL)
-		dev_err(dev, "SPI failure\n");
-	if (status & ADIS16300_DIAG_STAT_FLASH_UPT)
-		dev_err(dev, "Flash update failed\n");
-	if (status & ADIS16300_DIAG_STAT_POWER_HIGH)
-		dev_err(dev, "Power supply above 5.25V\n");
-	if (status & ADIS16300_DIAG_STAT_POWER_LOW)
-		dev_err(dev, "Power supply below 4.75V\n");
-
-error_ret:
-	return ret;
-}
-
-static int adis16300_initial_setup(struct adis16300_state *st)
-{
-	int ret;
-	u16 smp_prd;
-	struct device *dev = &st->indio_dev->dev;
-
-	/* use low spi speed for init */
-	st->us->max_speed_hz = ADIS16300_SPI_SLOW;
-	st->us->mode = SPI_MODE_3;
-	spi_setup(st->us);
-
-	/* Disable IRQ */
-	ret = adis16300_set_irq(dev, false);
-	if (ret) {
-		dev_err(dev, "disable irq failed");
-		goto err_ret;
-	}
-
-	/* Do self test */
-	ret = adis16300_self_test(dev);
-	if (ret) {
-		dev_err(dev, "self test failure");
-		goto err_ret;
-	}
-
-	/* Read status register to check the result */
-	ret = adis16300_check_status(dev);
-	if (ret) {
-		adis16300_reset(dev);
-		dev_err(dev, "device not playing ball -> reset");
-		msleep(ADIS16300_STARTUP_DELAY);
-		ret = adis16300_check_status(dev);
-		if (ret) {
-			dev_err(dev, "giving up");
-			goto err_ret;
-		}
-	}
-
-	printk(KERN_INFO DRIVER_NAME ": at CS%d (irq %d)\n",
-			st->us->chip_select, st->us->irq);
-
-	/* use high spi speed if possible */
-	ret = adis16300_spi_read_reg_16(dev, ADIS16300_SMPL_PRD, &smp_prd);
-	if (!ret && (smp_prd & ADIS16300_SMPL_PRD_DIV_MASK) < 0x0A) {
-		st->us->max_speed_hz = ADIS16300_SPI_SLOW;
-		spi_setup(st->us);
-	}
-
-err_ret:
-	return ret;
-}
-
-static IIO_DEV_ATTR_GYRO_X_CALIBBIAS(S_IWUSR | S_IRUGO,
-		adis16300_read_12bit_signed,
-		adis16300_write_16bit,
-		ADIS16300_XGYRO_OFF);
-
-static IIO_DEV_ATTR_ACCEL_X_CALIBBIAS(S_IWUSR | S_IRUGO,
-		adis16300_read_12bit_signed,
-		adis16300_write_16bit,
-		ADIS16300_XACCL_OFF);
-
-static IIO_DEV_ATTR_ACCEL_Y_CALIBBIAS(S_IWUSR | S_IRUGO,
-		adis16300_read_12bit_signed,
-		adis16300_write_16bit,
-		ADIS16300_YACCL_OFF);
-
-static IIO_DEV_ATTR_ACCEL_Z_CALIBBIAS(S_IWUSR | S_IRUGO,
-		adis16300_read_12bit_signed,
-		adis16300_write_16bit,
-		ADIS16300_ZACCL_OFF);
-
-static IIO_DEV_ATTR_IN_NAMED_RAW(0, supply, adis16300_read_14bit_unsigned,
-			   ADIS16300_SUPPLY_OUT);
-static IIO_CONST_ATTR_IN_NAMED_SCALE(0, supply, "0.00242");
-
-static IIO_DEV_ATTR_GYRO_X(adis16300_read_14bit_signed,
-		ADIS16300_XGYRO_OUT);
-static IIO_CONST_ATTR_GYRO_SCALE("0.000872664");
-
-static IIO_DEV_ATTR_ACCEL_X(adis16300_read_14bit_signed,
-		ADIS16300_XACCL_OUT);
-static IIO_DEV_ATTR_ACCEL_Y(adis16300_read_14bit_signed,
-		ADIS16300_YACCL_OUT);
-static IIO_DEV_ATTR_ACCEL_Z(adis16300_read_14bit_signed,
-		ADIS16300_ZACCL_OUT);
-static IIO_CONST_ATTR_ACCEL_SCALE("0.00588399");
-
-static IIO_DEV_ATTR_INCLI_X(adis16300_read_13bit_signed,
-		ADIS16300_XINCLI_OUT);
-static IIO_DEV_ATTR_INCLI_Y(adis16300_read_13bit_signed,
-		ADIS16300_YINCLI_OUT);
-static IIO_CONST_ATTR_INCLI_SCALE("0.00076794487");
-
-static IIO_DEV_ATTR_TEMP_RAW(adis16300_read_12bit_unsigned);
-static IIO_CONST_ATTR_TEMP_OFFSET("198.16");
-static IIO_CONST_ATTR_TEMP_SCALE("0.14");
-
-static IIO_DEV_ATTR_IN_RAW(1, adis16300_read_12bit_unsigned,
-		ADIS16300_AUX_ADC);
-static IIO_CONST_ATTR(in1_scale, "0.000806");
-
-static IIO_DEV_ATTR_SAMP_FREQ(S_IWUSR | S_IRUGO,
-		adis16300_read_frequency,
-		adis16300_write_frequency);
-
-static IIO_DEVICE_ATTR(reset, S_IWUSR, NULL, adis16300_write_reset, 0);
-
-static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("409 546 819 1638");
-
-static IIO_CONST_ATTR_NAME("adis16300");
-
-static struct attribute *adis16300_event_attributes[] = {
-	NULL
-};
-
-static struct attribute_group adis16300_event_attribute_group = {
-	.attrs = adis16300_event_attributes,
-};
-
-static struct attribute *adis16300_attributes[] = {
-	&iio_dev_attr_gyro_x_calibbias.dev_attr.attr,
-	&iio_dev_attr_accel_x_calibbias.dev_attr.attr,
-	&iio_dev_attr_accel_y_calibbias.dev_attr.attr,
-	&iio_dev_attr_accel_z_calibbias.dev_attr.attr,
-	&iio_dev_attr_in0_supply_raw.dev_attr.attr,
-	&iio_const_attr_in0_supply_scale.dev_attr.attr,
-	&iio_dev_attr_gyro_x_raw.dev_attr.attr,
-	&iio_const_attr_gyro_scale.dev_attr.attr,
-	&iio_dev_attr_accel_x_raw.dev_attr.attr,
-	&iio_dev_attr_accel_y_raw.dev_attr.attr,
-	&iio_dev_attr_accel_z_raw.dev_attr.attr,
-	&iio_const_attr_accel_scale.dev_attr.attr,
-	&iio_dev_attr_incli_x_raw.dev_attr.attr,
-	&iio_dev_attr_incli_y_raw.dev_attr.attr,
-	&iio_const_attr_incli_scale.dev_attr.attr,
-	&iio_dev_attr_temp_raw.dev_attr.attr,
-	&iio_const_attr_temp_offset.dev_attr.attr,
-	&iio_const_attr_temp_scale.dev_attr.attr,
-	&iio_dev_attr_in1_raw.dev_attr.attr,
-	&iio_const_attr_in1_scale.dev_attr.attr,
-	&iio_dev_attr_sampling_frequency.dev_attr.attr,
-	&iio_const_attr_sampling_frequency_available.dev_attr.attr,
-	&iio_dev_attr_reset.dev_attr.attr,
-	&iio_const_attr_name.dev_attr.attr,
-	NULL
-};
-
-static const struct attribute_group adis16300_attribute_group = {
-	.attrs = adis16300_attributes,
-};
-
-static int __devinit adis16300_probe(struct spi_device *spi)
-{
-	int ret, regdone = 0;
-	struct adis16300_state *st = kzalloc(sizeof *st, GFP_KERNEL);
-	if (!st) {
-		ret =  -ENOMEM;
-		goto error_ret;
-	}
-	/* this is only used for removal purposes */
-	spi_set_drvdata(spi, st);
-
-	/* Allocate the comms buffers */
-	st->rx = kzalloc(sizeof(*st->rx)*ADIS16300_MAX_RX, GFP_KERNEL);
-	if (st->rx == NULL) {
-		ret = -ENOMEM;
-		goto error_free_st;
-	}
-	st->tx = kzalloc(sizeof(*st->tx)*ADIS16300_MAX_TX, GFP_KERNEL);
-	if (st->tx == NULL) {
-		ret = -ENOMEM;
-		goto error_free_rx;
-	}
-	st->us = spi;
-	mutex_init(&st->buf_lock);
-	/* setup the industrialio driver allocated elements */
-	st->indio_dev = iio_allocate_device();
-	if (st->indio_dev == NULL) {
-		ret = -ENOMEM;
-		goto error_free_tx;
-	}
-
-	st->indio_dev->dev.parent = &spi->dev;
-	st->indio_dev->num_interrupt_lines = 1;
-	st->indio_dev->event_attrs = &adis16300_event_attribute_group;
-	st->indio_dev->attrs = &adis16300_attribute_group;
-	st->indio_dev->dev_data = (void *)(st);
-	st->indio_dev->driver_module = THIS_MODULE;
-	st->indio_dev->modes = INDIO_DIRECT_MODE;
-
-	ret = adis16300_configure_ring(st->indio_dev);
-	if (ret)
-		goto error_free_dev;
-
-	ret = iio_device_register(st->indio_dev);
-	if (ret)
-		goto error_unreg_ring_funcs;
-	regdone = 1;
-
-	ret = iio_ring_buffer_register(st->indio_dev->ring, 0);
-	if (ret) {
-		printk(KERN_ERR "failed to initialize the ring\n");
-		goto error_unreg_ring_funcs;
-	}
-
-	if (spi->irq) {
-		ret = iio_register_interrupt_line(spi->irq,
-				st->indio_dev,
-				0,
-				IRQF_TRIGGER_RISING,
-				"adis16300");
-		if (ret)
-			goto error_uninitialize_ring;
-
-		ret = adis16300_probe_trigger(st->indio_dev);
-		if (ret)
-			goto error_unregister_line;
-	}
-
-	/* Get the device into a sane initial state */
-	ret = adis16300_initial_setup(st);
-	if (ret)
-		goto error_remove_trigger;
-	return 0;
-
-error_remove_trigger:
-	adis16300_remove_trigger(st->indio_dev);
-error_unregister_line:
-	if (spi->irq)
-		iio_unregister_interrupt_line(st->indio_dev, 0);
-error_uninitialize_ring:
-	iio_ring_buffer_unregister(st->indio_dev->ring);
-error_unreg_ring_funcs:
-	adis16300_unconfigure_ring(st->indio_dev);
-error_free_dev:
-	if (regdone)
-		iio_device_unregister(st->indio_dev);
-	else
-		iio_free_device(st->indio_dev);
-error_free_tx:
-	kfree(st->tx);
-error_free_rx:
-	kfree(st->rx);
-error_free_st:
-	kfree(st);
-error_ret:
-	return ret;
-}
-
-static int adis16300_remove(struct spi_device *spi)
-{
-	int ret;
-	struct adis16300_state *st = spi_get_drvdata(spi);
-	struct iio_dev *indio_dev = st->indio_dev;
-
-	ret = adis16300_stop_device(&(indio_dev->dev));
-	if (ret)
-		goto err_ret;
-
-	flush_scheduled_work();
-
-	adis16300_remove_trigger(indio_dev);
-	if (spi->irq)
-		iio_unregister_interrupt_line(indio_dev, 0);
-
-	iio_ring_buffer_unregister(indio_dev->ring);
-	iio_device_unregister(indio_dev);
-	adis16300_unconfigure_ring(indio_dev);
-	kfree(st->tx);
-	kfree(st->rx);
-	kfree(st);
-
-	return 0;
-
-err_ret:
-	return ret;
-}
-
-static struct spi_driver adis16300_driver = {
-	.driver = {
-		.name = "adis16300",
-		.owner = THIS_MODULE,
-	},
-	.probe = adis16300_probe,
-	.remove = __devexit_p(adis16300_remove),
-};
-
-static __init int adis16300_init(void)
-{
-	return spi_register_driver(&adis16300_driver);
-}
-module_init(adis16300_init);
-
-static __exit void adis16300_exit(void)
-{
-	spi_unregister_driver(&adis16300_driver);
-}
-module_exit(adis16300_exit);
-
-MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>");
-MODULE_DESCRIPTION("Analog Devices ADIS16300 IMU SPI driver");
-MODULE_LICENSE("GPL v2");
diff -druN linux-2.6.39-libre/drivers/staging/iio/imu/adis16300.h linux-3.0-rc7-libre/drivers/staging/iio/imu/adis16300.h
--- linux-2.6.39-libre/drivers/staging/iio/imu/adis16300.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/iio/imu/adis16300.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,184 +0,0 @@
-#ifndef SPI_ADIS16300_H_
-#define SPI_ADIS16300_H_
-
-#define ADIS16300_STARTUP_DELAY	220 /* ms */
-
-#define ADIS16300_READ_REG(a)    a
-#define ADIS16300_WRITE_REG(a) ((a) | 0x80)
-
-#define ADIS16300_FLASH_CNT  0x00 /* Flash memory write count */
-#define ADIS16300_SUPPLY_OUT 0x02 /* Power supply measurement */
-#define ADIS16300_XGYRO_OUT 0x04 /* X-axis gyroscope output */
-#define ADIS16300_XACCL_OUT 0x0A /* X-axis accelerometer output */
-#define ADIS16300_YACCL_OUT 0x0C /* Y-axis accelerometer output */
-#define ADIS16300_ZACCL_OUT 0x0E /* Z-axis accelerometer output */
-#define ADIS16300_TEMP_OUT  0x10 /* Temperature output */
-#define ADIS16300_XINCLI_OUT 0x12 /* X-axis inclinometer output measurement */
-#define ADIS16300_YINCLI_OUT 0x14 /* Y-axis inclinometer output measurement */
-#define ADIS16300_AUX_ADC   0x16 /* Auxiliary ADC measurement */
-
-/* Calibration parameters */
-#define ADIS16300_XGYRO_OFF 0x1A /* X-axis gyroscope bias offset factor */
-#define ADIS16300_XACCL_OFF 0x20 /* X-axis acceleration bias offset factor */
-#define ADIS16300_YACCL_OFF 0x22 /* Y-axis acceleration bias offset factor */
-#define ADIS16300_ZACCL_OFF 0x24 /* Z-axis acceleration bias offset factor */
-
-#define ADIS16300_GPIO_CTRL 0x32 /* Auxiliary digital input/output control */
-#define ADIS16300_MSC_CTRL  0x34 /* Miscellaneous control */
-#define ADIS16300_SMPL_PRD  0x36 /* Internal sample period (rate) control */
-#define ADIS16300_SENS_AVG  0x38 /* Dynamic range and digital filter control */
-#define ADIS16300_SLP_CNT   0x3A /* Sleep mode control */
-#define ADIS16300_DIAG_STAT 0x3C /* System status */
-
-/* Alarm functions */
-#define ADIS16300_GLOB_CMD  0x3E /* System command */
-#define ADIS16300_ALM_MAG1  0x26 /* Alarm 1 amplitude threshold */
-#define ADIS16300_ALM_MAG2  0x28 /* Alarm 2 amplitude threshold */
-#define ADIS16300_ALM_SMPL1 0x2A /* Alarm 1 sample size */
-#define ADIS16300_ALM_SMPL2 0x2C /* Alarm 2 sample size */
-#define ADIS16300_ALM_CTRL  0x2E /* Alarm control */
-#define ADIS16300_AUX_DAC   0x30 /* Auxiliary DAC data */
-
-#define ADIS16300_ERROR_ACTIVE			(1<<14)
-#define ADIS16300_NEW_DATA			(1<<15)
-
-/* MSC_CTRL */
-#define ADIS16300_MSC_CTRL_MEM_TEST		(1<<11)
-#define ADIS16300_MSC_CTRL_INT_SELF_TEST	(1<<10)
-#define ADIS16300_MSC_CTRL_NEG_SELF_TEST	(1<<9)
-#define ADIS16300_MSC_CTRL_POS_SELF_TEST	(1<<8)
-#define ADIS16300_MSC_CTRL_GYRO_BIAS		(1<<7)
-#define ADIS16300_MSC_CTRL_ACCL_ALIGN		(1<<6)
-#define ADIS16300_MSC_CTRL_DATA_RDY_EN		(1<<2)
-#define ADIS16300_MSC_CTRL_DATA_RDY_POL_HIGH	(1<<1)
-#define ADIS16300_MSC_CTRL_DATA_RDY_DIO2	(1<<0)
-
-/* SMPL_PRD */
-#define ADIS16300_SMPL_PRD_TIME_BASE	(1<<7)
-#define ADIS16300_SMPL_PRD_DIV_MASK	0x7F
-
-/* DIAG_STAT */
-#define ADIS16300_DIAG_STAT_ZACCL_FAIL	(1<<15)
-#define ADIS16300_DIAG_STAT_YACCL_FAIL	(1<<14)
-#define ADIS16300_DIAG_STAT_XACCL_FAIL	(1<<13)
-#define ADIS16300_DIAG_STAT_XGYRO_FAIL	(1<<10)
-#define ADIS16300_DIAG_STAT_ALARM2	(1<<9)
-#define ADIS16300_DIAG_STAT_ALARM1	(1<<8)
-#define ADIS16300_DIAG_STAT_FLASH_CHK	(1<<6)
-#define ADIS16300_DIAG_STAT_SELF_TEST	(1<<5)
-#define ADIS16300_DIAG_STAT_OVERFLOW	(1<<4)
-#define ADIS16300_DIAG_STAT_SPI_FAIL	(1<<3)
-#define ADIS16300_DIAG_STAT_FLASH_UPT	(1<<2)
-#define ADIS16300_DIAG_STAT_POWER_HIGH	(1<<1)
-#define ADIS16300_DIAG_STAT_POWER_LOW	(1<<0)
-
-/* GLOB_CMD */
-#define ADIS16300_GLOB_CMD_SW_RESET	(1<<7)
-#define ADIS16300_GLOB_CMD_P_AUTO_NULL	(1<<4)
-#define ADIS16300_GLOB_CMD_FLASH_UPD	(1<<3)
-#define ADIS16300_GLOB_CMD_DAC_LATCH	(1<<2)
-#define ADIS16300_GLOB_CMD_FAC_CALIB	(1<<1)
-#define ADIS16300_GLOB_CMD_AUTO_NULL	(1<<0)
-
-/* SLP_CNT */
-#define ADIS16300_SLP_CNT_POWER_OFF	(1<<8)
-
-#define ADIS16300_MAX_TX 18
-#define ADIS16300_MAX_RX 18
-
-#define ADIS16300_SPI_SLOW	(u32)(300 * 1000)
-#define ADIS16300_SPI_BURST	(u32)(1000 * 1000)
-#define ADIS16300_SPI_FAST	(u32)(2000 * 1000)
-
-/**
- * struct adis16300_state - device instance specific data
- * @us:			actual spi_device
- * @work_trigger_to_ring: bh for triggered event handling
- * @inter:		used to check if new interrupt has been triggered
- * @last_timestamp:	passing timestamp from th to bh of interrupt handler
- * @indio_dev:		industrial I/O device structure
- * @trig:		data ready trigger registered with iio
- * @tx:			transmit buffer
- * @rx:			receive buffer
- * @buf_lock:		mutex to protect tx and rx
- **/
-struct adis16300_state {
-	struct spi_device		*us;
-	struct work_struct		work_trigger_to_ring;
-	s64				last_timestamp;
-	struct iio_dev			*indio_dev;
-	struct iio_trigger		*trig;
-	u8				*tx;
-	u8				*rx;
-	struct mutex			buf_lock;
-};
-
-int adis16300_set_irq(struct device *dev, bool enable);
-
-#ifdef CONFIG_IIO_RING_BUFFER
-/* At the moment triggers are only used for ring buffer
- * filling. This may change!
- */
-
-#define ADIS16300_SCAN_SUPPLY	0
-#define ADIS16300_SCAN_GYRO_X	1
-#define ADIS16300_SCAN_ACC_X	2
-#define ADIS16300_SCAN_ACC_Y	3
-#define ADIS16300_SCAN_ACC_Z	4
-#define ADIS16300_SCAN_TEMP	5
-#define ADIS16300_SCAN_ADC_0	6
-#define ADIS16300_SCAN_INCLI_X	7
-#define ADIS16300_SCAN_INCLI_Y	8
-
-void adis16300_remove_trigger(struct iio_dev *indio_dev);
-int adis16300_probe_trigger(struct iio_dev *indio_dev);
-
-ssize_t adis16300_read_data_from_ring(struct device *dev,
-				      struct device_attribute *attr,
-				      char *buf);
-
-
-int adis16300_configure_ring(struct iio_dev *indio_dev);
-void adis16300_unconfigure_ring(struct iio_dev *indio_dev);
-
-int adis16300_initialize_ring(struct iio_ring_buffer *ring);
-void adis16300_uninitialize_ring(struct iio_ring_buffer *ring);
-#else /* CONFIG_IIO_RING_BUFFER */
-
-static inline void adis16300_remove_trigger(struct iio_dev *indio_dev)
-{
-}
-
-static inline int adis16300_probe_trigger(struct iio_dev *indio_dev)
-{
-	return 0;
-}
-
-static inline ssize_t
-adis16300_read_data_from_ring(struct device *dev,
-			      struct device_attribute *attr,
-			      char *buf)
-{
-	return 0;
-}
-
-static int adis16300_configure_ring(struct iio_dev *indio_dev)
-{
-	return 0;
-}
-
-static inline void adis16300_unconfigure_ring(struct iio_dev *indio_dev)
-{
-}
-
-static inline int adis16300_initialize_ring(struct iio_ring_buffer *ring)
-{
-	return 0;
-}
-
-static inline void adis16300_uninitialize_ring(struct iio_ring_buffer *ring)
-{
-}
-
-#endif /* CONFIG_IIO_RING_BUFFER */
-#endif /* SPI_ADIS16300_H_ */
diff -druN linux-2.6.39-libre/drivers/staging/iio/imu/adis16300_ring.c linux-3.0-rc7-libre/drivers/staging/iio/imu/adis16300_ring.c
--- linux-2.6.39-libre/drivers/staging/iio/imu/adis16300_ring.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/iio/imu/adis16300_ring.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,238 +0,0 @@
-#include <linux/interrupt.h>
-#include <linux/irq.h>
-#include <linux/gpio.h>
-#include <linux/workqueue.h>
-#include <linux/mutex.h>
-#include <linux/device.h>
-#include <linux/kernel.h>
-#include <linux/spi/spi.h>
-#include <linux/slab.h>
-#include <linux/sysfs.h>
-#include <linux/list.h>
-
-#include "../iio.h"
-#include "../sysfs.h"
-#include "../ring_sw.h"
-#include "../accel/accel.h"
-#include "../trigger.h"
-#include "adis16300.h"
-
-static IIO_SCAN_EL_C(in0_supply, ADIS16300_SCAN_SUPPLY,
-		     ADIS16300_SUPPLY_OUT, NULL);
-static IIO_CONST_ATTR_SCAN_EL_TYPE(in0_supply, u, 12, 16);
-static IIO_SCAN_EL_C(gyro_x, ADIS16300_SCAN_GYRO_X, ADIS16300_XGYRO_OUT, NULL);
-static IIO_CONST_ATTR_SCAN_EL_TYPE(gyro, s, 14, 16);
-
-static IIO_SCAN_EL_C(accel_x, ADIS16300_SCAN_ACC_X, ADIS16300_XACCL_OUT, NULL);
-static IIO_SCAN_EL_C(accel_y, ADIS16300_SCAN_ACC_Y, ADIS16300_YACCL_OUT, NULL);
-static IIO_SCAN_EL_C(accel_z, ADIS16300_SCAN_ACC_Z, ADIS16300_ZACCL_OUT, NULL);
-static IIO_CONST_ATTR_SCAN_EL_TYPE(accel, s, 14, 16);
-
-static IIO_SCAN_EL_C(temp, ADIS16300_SCAN_TEMP, ADIS16300_TEMP_OUT, NULL);
-static IIO_CONST_ATTR_SCAN_EL_TYPE(temp, s, 12, 16);
-
-static IIO_SCAN_EL_C(in1, ADIS16300_SCAN_ADC_0, ADIS16300_AUX_ADC, NULL);
-static IIO_CONST_ATTR_SCAN_EL_TYPE(in1, u, 12, 16);
-
-static IIO_SCAN_EL_C(incli_x, ADIS16300_SCAN_INCLI_X,
-		     ADIS16300_XINCLI_OUT, NULL);
-static IIO_SCAN_EL_C(incli_y, ADIS16300_SCAN_INCLI_Y,
-		     ADIS16300_YINCLI_OUT, NULL);
-static IIO_CONST_ATTR_SCAN_EL_TYPE(incli, s, 13, 16);
-
-static IIO_SCAN_EL_TIMESTAMP(9);
-static IIO_CONST_ATTR_SCAN_EL_TYPE(timestamp, s, 64, 64);
-
-static struct attribute *adis16300_scan_el_attrs[] = {
-	&iio_scan_el_in0_supply.dev_attr.attr,
-	&iio_const_attr_in0_supply_index.dev_attr.attr,
-	&iio_const_attr_in0_supply_type.dev_attr.attr,
-	&iio_scan_el_gyro_x.dev_attr.attr,
-	&iio_const_attr_gyro_x_index.dev_attr.attr,
-	&iio_const_attr_gyro_type.dev_attr.attr,
-	&iio_scan_el_temp.dev_attr.attr,
-	&iio_const_attr_temp_index.dev_attr.attr,
-	&iio_const_attr_temp_type.dev_attr.attr,
-	&iio_scan_el_accel_x.dev_attr.attr,
-	&iio_const_attr_accel_x_index.dev_attr.attr,
-	&iio_scan_el_accel_y.dev_attr.attr,
-	&iio_const_attr_accel_y_index.dev_attr.attr,
-	&iio_scan_el_accel_z.dev_attr.attr,
-	&iio_const_attr_accel_z_index.dev_attr.attr,
-	&iio_const_attr_accel_type.dev_attr.attr,
-	&iio_scan_el_incli_x.dev_attr.attr,
-	&iio_const_attr_incli_x_index.dev_attr.attr,
-	&iio_scan_el_incli_y.dev_attr.attr,
-	&iio_const_attr_incli_y_index.dev_attr.attr,
-	&iio_const_attr_incli_type.dev_attr.attr,
-	&iio_scan_el_in1.dev_attr.attr,
-	&iio_const_attr_in1_index.dev_attr.attr,
-	&iio_const_attr_in1_type.dev_attr.attr,
-	&iio_scan_el_timestamp.dev_attr.attr,
-	&iio_const_attr_timestamp_index.dev_attr.attr,
-	&iio_const_attr_timestamp_type.dev_attr.attr,
-	NULL,
-};
-
-static struct attribute_group adis16300_scan_el_group = {
-	.attrs = adis16300_scan_el_attrs,
-	.name = "scan_elements",
-};
-
-/**
- * adis16300_poll_func_th() top half interrupt handler called by trigger
- * @private_data:	iio_dev
- **/
-static void adis16300_poll_func_th(struct iio_dev *indio_dev, s64 time)
-{
-	struct adis16300_state *st = iio_dev_get_devdata(indio_dev);
-	st->last_timestamp = time;
-	schedule_work(&st->work_trigger_to_ring);
-	/* Indicate that this interrupt is being handled */
-
-	/* Technically this is trigger related, but without this
-	 * handler running there is currently no way for the interrupt
-	 * to clear.
-	 */
-}
-
-/**
- * adis16300_spi_read_burst() - read all data registers
- * @dev: device associated with child of actual device (iio_dev or iio_trig)
- * @rx: somewhere to pass back the value read (min size is 24 bytes)
- **/
-static int adis16300_spi_read_burst(struct device *dev, u8 *rx)
-{
-	struct spi_message msg;
-	struct iio_dev *indio_dev = dev_get_drvdata(dev);
-	struct adis16300_state *st = iio_dev_get_devdata(indio_dev);
-	u32 old_speed_hz = st->us->max_speed_hz;
-	int ret;
-
-	struct spi_transfer xfers[] = {
-		{
-			.tx_buf = st->tx,
-			.bits_per_word = 8,
-			.len = 2,
-			.cs_change = 0,
-		}, {
-			.rx_buf = rx,
-			.bits_per_word = 8,
-			.len = 18,
-			.cs_change = 0,
-		},
-	};
-
-	mutex_lock(&st->buf_lock);
-	st->tx[0] = ADIS16300_READ_REG(ADIS16300_GLOB_CMD);
-	st->tx[1] = 0;
-
-	spi_message_init(&msg);
-	spi_message_add_tail(&xfers[0], &msg);
-	spi_message_add_tail(&xfers[1], &msg);
-
-	st->us->max_speed_hz = ADIS16300_SPI_BURST;
-	spi_setup(st->us);
-
-	ret = spi_sync(st->us, &msg);
-	if (ret)
-		dev_err(&st->us->dev, "problem when burst reading");
-
-	st->us->max_speed_hz = old_speed_hz;
-	spi_setup(st->us);
-	mutex_unlock(&st->buf_lock);
-	return ret;
-}
-
-/* Whilst this makes a lot of calls to iio_sw_ring functions - it is to device
- * specific to be rolled into the core.
- */
-static void adis16300_trigger_bh_to_ring(struct work_struct *work_s)
-{
-	struct adis16300_state *st
-		= container_of(work_s, struct adis16300_state,
-			       work_trigger_to_ring);
-	struct iio_ring_buffer *ring = st->indio_dev->ring;
-
-	int i = 0;
-	s16 *data;
-	size_t datasize = ring->access.get_bytes_per_datum(ring);
-
-	data = kmalloc(datasize , GFP_KERNEL);
-	if (data == NULL) {
-		dev_err(&st->us->dev, "memory alloc failed in ring bh");
-		return;
-	}
-
-	if (ring->scan_count)
-		if (adis16300_spi_read_burst(&st->indio_dev->dev, st->rx) >= 0)
-			for (; i < ring->scan_count; i++)
-				data[i] = be16_to_cpup(
-					(__be16 *)&(st->rx[i*2]));
-
-	/* Guaranteed to be aligned with 8 byte boundary */
-	if (ring->scan_timestamp)
-		*((s64 *)(data + ((i + 3)/4)*4)) = st->last_timestamp;
-
-	ring->access.store_to(ring,
-			(u8 *)data,
-			st->last_timestamp);
-
-	iio_trigger_notify_done(st->indio_dev->trig);
-	kfree(data);
-
-	return;
-}
-
-void adis16300_unconfigure_ring(struct iio_dev *indio_dev)
-{
-	kfree(indio_dev->pollfunc);
-	iio_sw_rb_free(indio_dev->ring);
-}
-
-int adis16300_configure_ring(struct iio_dev *indio_dev)
-{
-	int ret = 0;
-	struct adis16300_state *st = indio_dev->dev_data;
-	struct iio_ring_buffer *ring;
-	INIT_WORK(&st->work_trigger_to_ring, adis16300_trigger_bh_to_ring);
-
-	ring = iio_sw_rb_allocate(indio_dev);
-	if (!ring) {
-		ret = -ENOMEM;
-		return ret;
-	}
-	indio_dev->ring = ring;
-	/* Effectively select the ring buffer implementation */
-	iio_ring_sw_register_funcs(&ring->access);
-	ring->bpe = 2;
-	ring->scan_el_attrs = &adis16300_scan_el_group;
-	ring->scan_timestamp = true;
-	ring->preenable = &iio_sw_ring_preenable;
-	ring->postenable = &iio_triggered_ring_postenable;
-	ring->predisable = &iio_triggered_ring_predisable;
-	ring->owner = THIS_MODULE;
-
-	/* Set default scan mode */
-	iio_scan_mask_set(ring, iio_scan_el_in0_supply.number);
-	iio_scan_mask_set(ring, iio_scan_el_gyro_x.number);
-	iio_scan_mask_set(ring, iio_scan_el_accel_x.number);
-	iio_scan_mask_set(ring, iio_scan_el_accel_y.number);
-	iio_scan_mask_set(ring, iio_scan_el_accel_z.number);
-	iio_scan_mask_set(ring, iio_scan_el_temp.number);
-	iio_scan_mask_set(ring, iio_scan_el_in1.number);
-	iio_scan_mask_set(ring, iio_scan_el_incli_x.number);
-	iio_scan_mask_set(ring, iio_scan_el_incli_y.number);
-
-	ret = iio_alloc_pollfunc(indio_dev, NULL, &adis16300_poll_func_th);
-	if (ret)
-		goto error_iio_sw_rb_free;
-
-	indio_dev->modes |= INDIO_RING_TRIGGERED;
-	return 0;
-
-error_iio_sw_rb_free:
-	iio_sw_rb_free(indio_dev->ring);
-	return ret;
-}
-
diff -druN linux-2.6.39-libre/drivers/staging/iio/imu/adis16300_trigger.c linux-3.0-rc7-libre/drivers/staging/iio/imu/adis16300_trigger.c
--- linux-2.6.39-libre/drivers/staging/iio/imu/adis16300_trigger.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/iio/imu/adis16300_trigger.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,125 +0,0 @@
-#include <linux/interrupt.h>
-#include <linux/irq.h>
-#include <linux/mutex.h>
-#include <linux/device.h>
-#include <linux/kernel.h>
-#include <linux/sysfs.h>
-#include <linux/list.h>
-#include <linux/spi/spi.h>
-
-#include "../iio.h"
-#include "../sysfs.h"
-#include "../trigger.h"
-#include "adis16300.h"
-
-/**
- * adis16300_data_rdy_trig_poll() the event handler for the data rdy trig
- **/
-static int adis16300_data_rdy_trig_poll(struct iio_dev *dev_info,
-				       int index,
-				       s64 timestamp,
-				       int no_test)
-{
-	struct adis16300_state *st = iio_dev_get_devdata(dev_info);
-	struct iio_trigger *trig = st->trig;
-
-	iio_trigger_poll(trig, timestamp);
-
-	return IRQ_HANDLED;
-}
-
-IIO_EVENT_SH(data_rdy_trig, &adis16300_data_rdy_trig_poll);
-
-static IIO_TRIGGER_NAME_ATTR;
-
-static struct attribute *adis16300_trigger_attrs[] = {
-	&dev_attr_name.attr,
-	NULL,
-};
-
-static const struct attribute_group adis16300_trigger_attr_group = {
-	.attrs = adis16300_trigger_attrs,
-};
-
-/**
- * adis16300_data_rdy_trigger_set_state() set datardy interrupt state
- **/
-static int adis16300_data_rdy_trigger_set_state(struct iio_trigger *trig,
-						bool state)
-{
-	struct adis16300_state *st = trig->private_data;
-	struct iio_dev *indio_dev = st->indio_dev;
-	int ret = 0;
-
-	dev_dbg(&indio_dev->dev, "%s (%d)\n", __func__, state);
-	ret = adis16300_set_irq(&st->indio_dev->dev, state);
-	if (state == false) {
-		iio_remove_event_from_list(&iio_event_data_rdy_trig,
-					   &indio_dev->interrupts[0]
-					   ->ev_list);
-		/* possible quirk with handler currently worked around
-		   by ensuring the work queue is empty */
-		flush_scheduled_work();
-	} else {
-		iio_add_event_to_list(&iio_event_data_rdy_trig,
-				      &indio_dev->interrupts[0]->ev_list);
-	}
-	return ret;
-}
-
-/**
- * adis16300_trig_try_reen() try renabling irq for data rdy trigger
- * @trig:	the datardy trigger
- **/
-static int adis16300_trig_try_reen(struct iio_trigger *trig)
-{
-	struct adis16300_state *st = trig->private_data;
-	enable_irq(st->us->irq);
-	/* irq reenabled so success! */
-	return 0;
-}
-
-int adis16300_probe_trigger(struct iio_dev *indio_dev)
-{
-	int ret;
-	struct adis16300_state *st = indio_dev->dev_data;
-
-	st->trig = iio_allocate_trigger();
-	st->trig->name = kasprintf(GFP_KERNEL,
-				   "adis16300-dev%d",
-				   indio_dev->id);
-	if (!st->trig->name) {
-		ret = -ENOMEM;
-		goto error_free_trig;
-	}
-	st->trig->dev.parent = &st->us->dev;
-	st->trig->owner = THIS_MODULE;
-	st->trig->private_data = st;
-	st->trig->set_trigger_state = &adis16300_data_rdy_trigger_set_state;
-	st->trig->try_reenable = &adis16300_trig_try_reen;
-	st->trig->control_attrs = &adis16300_trigger_attr_group;
-	ret = iio_trigger_register(st->trig);
-
-	/* select default trigger */
-	indio_dev->trig = st->trig;
-	if (ret)
-		goto error_free_trig_name;
-
-	return 0;
-
-error_free_trig_name:
-	kfree(st->trig->name);
-error_free_trig:
-	iio_free_trigger(st->trig);
-
-	return ret;
-}
-
-void adis16300_remove_trigger(struct iio_dev *indio_dev)
-{
-	struct adis16300_state *state = indio_dev->dev_data;
-
-	iio_trigger_unregister(state->trig);
-	kfree(state->trig->name);
-	iio_free_trigger(state->trig);
-}
diff -druN linux-2.6.39-libre/drivers/staging/iio/imu/adis16350_core.c linux-3.0-rc7-libre/drivers/staging/iio/imu/adis16350_core.c
--- linux-2.6.39-libre/drivers/staging/iio/imu/adis16350_core.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/iio/imu/adis16350_core.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,757 +0,0 @@
-/*
- * ADIS16350/54/55/60/62/64/65 high precision tri-axis inertial sensor
- *
- * Copyright 2010 Analog Devices Inc.
- *
- * Licensed under the GPL-2 or later.
- */
-
-#include <linux/interrupt.h>
-#include <linux/irq.h>
-#include <linux/gpio.h>
-#include <linux/delay.h>
-#include <linux/mutex.h>
-#include <linux/device.h>
-#include <linux/kernel.h>
-#include <linux/spi/spi.h>
-#include <linux/slab.h>
-#include <linux/sysfs.h>
-#include <linux/list.h>
-
-#include "../iio.h"
-#include "../sysfs.h"
-#include "../ring_generic.h"
-#include "../accel/accel.h"
-#include "../adc/adc.h"
-#include "../gyro/gyro.h"
-
-#include "adis16350.h"
-
-#define DRIVER_NAME		"adis16350"
-
-static int adis16350_check_status(struct device *dev);
-
-/**
- * adis16350_spi_write_reg_8() - write single byte to a register
- * @dev: device associated with child of actual device (iio_dev or iio_trig)
- * @reg_address: the address of the register to be written
- * @val: the value to write
- **/
-static int adis16350_spi_write_reg_8(struct device *dev,
-		u8 reg_address,
-		u8 val)
-{
-	int ret;
-	struct iio_dev *indio_dev = dev_get_drvdata(dev);
-	struct adis16350_state *st = iio_dev_get_devdata(indio_dev);
-
-	mutex_lock(&st->buf_lock);
-	st->tx[0] = ADIS16350_WRITE_REG(reg_address);
-	st->tx[1] = val;
-
-	ret = spi_write(st->us, st->tx, 2);
-	mutex_unlock(&st->buf_lock);
-
-	return ret;
-}
-
-/**
- * adis16350_spi_write_reg_16() - write 2 bytes to a pair of registers
- * @dev: device associated with child of actual device (iio_dev or iio_trig)
- * @reg_address: the address of the lower of the two registers. Second register
- *               is assumed to have address one greater.
- * @val: value to be written
- **/
-static int adis16350_spi_write_reg_16(struct device *dev,
-		u8 lower_reg_address,
-		u16 value)
-{
-	int ret;
-	struct spi_message msg;
-	struct iio_dev *indio_dev = dev_get_drvdata(dev);
-	struct adis16350_state *st = iio_dev_get_devdata(indio_dev);
-	struct spi_transfer xfers[] = {
-		{
-			.tx_buf = st->tx,
-			.bits_per_word = 8,
-			.len = 2,
-			.cs_change = 1,
-			.delay_usecs = 35,
-		}, {
-			.tx_buf = st->tx + 2,
-			.bits_per_word = 8,
-			.len = 2,
-			.cs_change = 1,
-			.delay_usecs = 35,
-		},
-	};
-
-	mutex_lock(&st->buf_lock);
-	st->tx[0] = ADIS16350_WRITE_REG(lower_reg_address);
-	st->tx[1] = value & 0xFF;
-	st->tx[2] = ADIS16350_WRITE_REG(lower_reg_address + 1);
-	st->tx[3] = (value >> 8) & 0xFF;
-
-	spi_message_init(&msg);
-	spi_message_add_tail(&xfers[0], &msg);
-	spi_message_add_tail(&xfers[1], &msg);
-	ret = spi_sync(st->us, &msg);
-	mutex_unlock(&st->buf_lock);
-
-	return ret;
-}
-
-/**
- * adis16350_spi_read_reg_16() - read 2 bytes from a 16-bit register
- * @dev: device associated with child of actual device (iio_dev or iio_trig)
- * @reg_address: the address of the lower of the two registers. Second register
- *               is assumed to have address one greater.
- * @val: somewhere to pass back the value read
- **/
-static int adis16350_spi_read_reg_16(struct device *dev,
-		u8 lower_reg_address,
-		u16 *val)
-{
-	struct spi_message msg;
-	struct iio_dev *indio_dev = dev_get_drvdata(dev);
-	struct adis16350_state *st = iio_dev_get_devdata(indio_dev);
-	int ret;
-	struct spi_transfer xfers[] = {
-		{
-			.tx_buf = st->tx,
-			.bits_per_word = 8,
-			.len = 2,
-			.cs_change = 1,
-			.delay_usecs = 35,
-		}, {
-			.rx_buf = st->rx,
-			.bits_per_word = 8,
-			.len = 2,
-			.cs_change = 1,
-			.delay_usecs = 35,
-		},
-	};
-
-	mutex_lock(&st->buf_lock);
-	st->tx[0] = ADIS16350_READ_REG(lower_reg_address);
-	st->tx[1] = 0;
-	st->tx[2] = 0;
-	st->tx[3] = 0;
-
-	spi_message_init(&msg);
-	spi_message_add_tail(&xfers[0], &msg);
-	spi_message_add_tail(&xfers[1], &msg);
-	ret = spi_sync(st->us, &msg);
-	if (ret) {
-		dev_err(&st->us->dev,
-			"problem when reading 16 bit register 0x%02X",
-			lower_reg_address);
-		goto error_ret;
-	}
-	*val = (st->rx[0] << 8) | st->rx[1];
-
-error_ret:
-	mutex_unlock(&st->buf_lock);
-	return ret;
-}
-
-
-static ssize_t adis16350_spi_read_signed(struct device *dev,
-		struct device_attribute *attr,
-		char *buf,
-		unsigned bits)
-{
-	int ret;
-	s16 val = 0;
-	unsigned shift = 16 - bits;
-	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
-
-	ret = adis16350_spi_read_reg_16(dev, this_attr->address, (u16 *)&val);
-	if (ret)
-		return ret;
-
-	if (val & ADIS16350_ERROR_ACTIVE)
-		adis16350_check_status(dev);
-	val = ((s16)(val << shift) >> shift);
-	return sprintf(buf, "%d\n", val);
-}
-
-static ssize_t adis16350_read_12bit_unsigned(struct device *dev,
-		struct device_attribute *attr,
-		char *buf)
-{
-	int ret;
-	u16 val = 0;
-	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
-
-	ret = adis16350_spi_read_reg_16(dev, this_attr->address, &val);
-	if (ret)
-		return ret;
-
-	if (val & ADIS16350_ERROR_ACTIVE)
-		adis16350_check_status(dev);
-
-	return sprintf(buf, "%u\n", val & 0x0FFF);
-}
-
-static ssize_t adis16350_read_14bit_signed(struct device *dev,
-		struct device_attribute *attr,
-		char *buf)
-{
-	struct iio_dev *indio_dev = dev_get_drvdata(dev);
-	ssize_t ret;
-
-	/* Take the iio_dev status lock */
-	mutex_lock(&indio_dev->mlock);
-	ret =  adis16350_spi_read_signed(dev, attr, buf, 14);
-	mutex_unlock(&indio_dev->mlock);
-
-	return ret;
-}
-
-static ssize_t adis16350_read_12bit_signed(struct device *dev,
-		struct device_attribute *attr,
-		char *buf)
-{
-	struct iio_dev *indio_dev = dev_get_drvdata(dev);
-	ssize_t ret;
-
-	/* Take the iio_dev status lock */
-	mutex_lock(&indio_dev->mlock);
-	ret =  adis16350_spi_read_signed(dev, attr, buf, 12);
-	mutex_unlock(&indio_dev->mlock);
-
-	return ret;
-}
-
-static ssize_t adis16350_write_16bit(struct device *dev,
-		struct device_attribute *attr,
-		const char *buf,
-		size_t len)
-{
-	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
-	int ret;
-	long val;
-
-	ret = strict_strtol(buf, 10, &val);
-	if (ret)
-		goto error_ret;
-	ret = adis16350_spi_write_reg_16(dev, this_attr->address, val);
-
-error_ret:
-	return ret ? ret : len;
-}
-
-static ssize_t adis16350_read_frequency(struct device *dev,
-		struct device_attribute *attr,
-		char *buf)
-{
-	int ret, len = 0;
-	u16 t;
-	int sps;
-	ret = adis16350_spi_read_reg_16(dev,
-			ADIS16350_SMPL_PRD,
-			&t);
-	if (ret)
-		return ret;
-	sps =  (t & ADIS16350_SMPL_PRD_TIME_BASE) ? 53 : 1638;
-	sps /= (t & ADIS16350_SMPL_PRD_DIV_MASK) + 1;
-	len = sprintf(buf, "%d SPS\n", sps);
-	return len;
-}
-
-static ssize_t adis16350_write_frequency(struct device *dev,
-		struct device_attribute *attr,
-		const char *buf,
-		size_t len)
-{
-	struct iio_dev *indio_dev = dev_get_drvdata(dev);
-	struct adis16350_state *st = iio_dev_get_devdata(indio_dev);
-	long val;
-	int ret;
-	u8 t;
-
-	ret = strict_strtol(buf, 10, &val);
-	if (ret)
-		return ret;
-
-	mutex_lock(&indio_dev->mlock);
-
-	t = (1638 / val);
-	if (t > 0)
-		t--;
-	t &= ADIS16350_SMPL_PRD_DIV_MASK;
-	if ((t & ADIS16350_SMPL_PRD_DIV_MASK) >= 0x0A)
-		st->us->max_speed_hz = ADIS16350_SPI_SLOW;
-	else
-		st->us->max_speed_hz = ADIS16350_SPI_FAST;
-
-	ret = adis16350_spi_write_reg_8(dev,
-			ADIS16350_SMPL_PRD,
-			t);
-
-	mutex_unlock(&indio_dev->mlock);
-
-	return ret ? ret : len;
-}
-
-static int adis16350_reset(struct device *dev)
-{
-	int ret;
-	ret = adis16350_spi_write_reg_8(dev,
-			ADIS16350_GLOB_CMD,
-			ADIS16350_GLOB_CMD_SW_RESET);
-	if (ret)
-		dev_err(dev, "problem resetting device");
-
-	return ret;
-}
-
-static ssize_t adis16350_write_reset(struct device *dev,
-		struct device_attribute *attr,
-		const char *buf, size_t len)
-{
-	if (len < 1)
-		return -1;
-	switch (buf[0]) {
-	case '1':
-	case 'y':
-	case 'Y':
-		return adis16350_reset(dev);
-	}
-	return -1;
-}
-
-int adis16350_set_irq(struct device *dev, bool enable)
-{
-	int ret;
-	u16 msc;
-	ret = adis16350_spi_read_reg_16(dev, ADIS16350_MSC_CTRL, &msc);
-	if (ret)
-		goto error_ret;
-
-	msc |= ADIS16350_MSC_CTRL_DATA_RDY_POL_HIGH;
-	msc &= ~ADIS16350_MSC_CTRL_DATA_RDY_DIO2;
-
-	if (enable)
-		msc |= ADIS16350_MSC_CTRL_DATA_RDY_EN;
-	else
-		msc &= ~ADIS16350_MSC_CTRL_DATA_RDY_EN;
-
-	ret = adis16350_spi_write_reg_16(dev, ADIS16350_MSC_CTRL, msc);
-	if (ret)
-		goto error_ret;
-
-error_ret:
-	return ret;
-}
-
-/* Power down the device */
-static int adis16350_stop_device(struct device *dev)
-{
-	int ret;
-	u16 val = ADIS16350_SLP_CNT_POWER_OFF;
-
-	ret = adis16350_spi_write_reg_16(dev, ADIS16350_SLP_CNT, val);
-	if (ret)
-		dev_err(dev, "problem with turning device off: SLP_CNT");
-
-	return ret;
-}
-
-static int adis16350_self_test(struct device *dev)
-{
-	int ret;
-	ret = adis16350_spi_write_reg_16(dev,
-			ADIS16350_MSC_CTRL,
-			ADIS16350_MSC_CTRL_MEM_TEST);
-	if (ret) {
-		dev_err(dev, "problem starting self test");
-		goto err_ret;
-	}
-
-	adis16350_check_status(dev);
-
-err_ret:
-	return ret;
-}
-
-static int adis16350_check_status(struct device *dev)
-{
-	u16 status;
-	int ret;
-
-	ret = adis16350_spi_read_reg_16(dev, ADIS16350_DIAG_STAT, &status);
-
-	if (ret < 0) {
-		dev_err(dev, "Reading status failed\n");
-		goto error_ret;
-	}
-	ret = status;
-	if (status & ADIS16350_DIAG_STAT_ZACCL_FAIL)
-		dev_err(dev, "Z-axis accelerometer self-test failure\n");
-	if (status & ADIS16350_DIAG_STAT_YACCL_FAIL)
-		dev_err(dev, "Y-axis accelerometer self-test failure\n");
-	if (status & ADIS16350_DIAG_STAT_XACCL_FAIL)
-		dev_err(dev, "X-axis accelerometer self-test failure\n");
-	if (status & ADIS16350_DIAG_STAT_XGYRO_FAIL)
-		dev_err(dev, "X-axis gyroscope self-test failure\n");
-	if (status & ADIS16350_DIAG_STAT_YGYRO_FAIL)
-		dev_err(dev, "Y-axis gyroscope self-test failure\n");
-	if (status & ADIS16350_DIAG_STAT_ZGYRO_FAIL)
-		dev_err(dev, "Z-axis gyroscope self-test failure\n");
-	if (status & ADIS16350_DIAG_STAT_ALARM2)
-		dev_err(dev, "Alarm 2 active\n");
-	if (status & ADIS16350_DIAG_STAT_ALARM1)
-		dev_err(dev, "Alarm 1 active\n");
-	if (status & ADIS16350_DIAG_STAT_FLASH_CHK)
-		dev_err(dev, "Flash checksum error\n");
-	if (status & ADIS16350_DIAG_STAT_SELF_TEST)
-		dev_err(dev, "Self test error\n");
-	if (status & ADIS16350_DIAG_STAT_OVERFLOW)
-		dev_err(dev, "Sensor overrange\n");
-	if (status & ADIS16350_DIAG_STAT_SPI_FAIL)
-		dev_err(dev, "SPI failure\n");
-	if (status & ADIS16350_DIAG_STAT_FLASH_UPT)
-		dev_err(dev, "Flash update failed\n");
-	if (status & ADIS16350_DIAG_STAT_POWER_HIGH)
-		dev_err(dev, "Power supply above 5.25V\n");
-	if (status & ADIS16350_DIAG_STAT_POWER_LOW)
-		dev_err(dev, "Power supply below 4.75V\n");
-
-error_ret:
-	return ret;
-}
-
-static int adis16350_initial_setup(struct adis16350_state *st)
-{
-	int ret;
-	u16 smp_prd;
-	struct device *dev = &st->indio_dev->dev;
-
-	/* use low spi speed for init */
-	st->us->max_speed_hz = ADIS16350_SPI_SLOW;
-	st->us->mode = SPI_MODE_3;
-	spi_setup(st->us);
-
-	/* Disable IRQ */
-	ret = adis16350_set_irq(dev, false);
-	if (ret) {
-		dev_err(dev, "disable irq failed");
-		goto err_ret;
-	}
-
-	/* Do self test */
-	ret = adis16350_self_test(dev);
-	if (ret) {
-		dev_err(dev, "self test failure");
-		goto err_ret;
-	}
-
-	/* Read status register to check the result */
-	ret = adis16350_check_status(dev);
-	if (ret) {
-		adis16350_reset(dev);
-		dev_err(dev, "device not playing ball -> reset");
-		msleep(ADIS16350_STARTUP_DELAY);
-		ret = adis16350_check_status(dev);
-		if (ret) {
-			dev_err(dev, "giving up");
-			goto err_ret;
-		}
-	}
-
-	printk(KERN_INFO DRIVER_NAME ": at CS%d (irq %d)\n",
-			st->us->chip_select, st->us->irq);
-
-	/* use high spi speed if possible */
-	ret = adis16350_spi_read_reg_16(dev, ADIS16350_SMPL_PRD, &smp_prd);
-	if (!ret && (smp_prd & ADIS16350_SMPL_PRD_DIV_MASK) < 0x0A) {
-		st->us->max_speed_hz = ADIS16350_SPI_SLOW;
-		spi_setup(st->us);
-	}
-
-err_ret:
-	return ret;
-}
-
-static IIO_DEV_ATTR_GYRO_X_CALIBBIAS(S_IWUSR | S_IRUGO,
-		adis16350_read_12bit_signed,
-		adis16350_write_16bit,
-		ADIS16350_XGYRO_OFF);
-
-static IIO_DEV_ATTR_GYRO_Y_CALIBBIAS(S_IWUSR | S_IRUGO,
-		adis16350_read_12bit_signed,
-		adis16350_write_16bit,
-		ADIS16350_YGYRO_OFF);
-
-static IIO_DEV_ATTR_GYRO_Z_CALIBBIAS(S_IWUSR | S_IRUGO,
-		adis16350_read_12bit_signed,
-		adis16350_write_16bit,
-		ADIS16350_ZGYRO_OFF);
-
-static IIO_DEV_ATTR_ACCEL_X_CALIBBIAS(S_IWUSR | S_IRUGO,
-		adis16350_read_12bit_signed,
-		adis16350_write_16bit,
-		ADIS16350_XACCL_OFF);
-
-static IIO_DEV_ATTR_ACCEL_Y_CALIBBIAS(S_IWUSR | S_IRUGO,
-		adis16350_read_12bit_signed,
-		adis16350_write_16bit,
-		ADIS16350_YACCL_OFF);
-
-static IIO_DEV_ATTR_ACCEL_Z_CALIBBIAS(S_IWUSR | S_IRUGO,
-		adis16350_read_12bit_signed,
-		adis16350_write_16bit,
-		ADIS16350_ZACCL_OFF);
-
-static IIO_DEV_ATTR_IN_NAMED_RAW(0, supply, adis16350_read_12bit_unsigned,
-		ADIS16350_SUPPLY_OUT);
-static IIO_CONST_ATTR_IN_NAMED_SCALE(0, supply, "0.002418");
-
-static IIO_DEV_ATTR_GYRO_X(adis16350_read_14bit_signed,
-		ADIS16350_XGYRO_OUT);
-static IIO_DEV_ATTR_GYRO_Y(adis16350_read_14bit_signed,
-		ADIS16350_YGYRO_OUT);
-static IIO_DEV_ATTR_GYRO_Z(adis16350_read_14bit_signed,
-		ADIS16350_ZGYRO_OUT);
-static IIO_CONST_ATTR_GYRO_SCALE("0.00127862821");
-
-static IIO_DEV_ATTR_ACCEL_X(adis16350_read_14bit_signed,
-		ADIS16350_XACCL_OUT);
-static IIO_DEV_ATTR_ACCEL_Y(adis16350_read_14bit_signed,
-		ADIS16350_YACCL_OUT);
-static IIO_DEV_ATTR_ACCEL_Z(adis16350_read_14bit_signed,
-		ADIS16350_ZACCL_OUT);
-static IIO_CONST_ATTR_ACCEL_SCALE("0.0247323713");
-
-static IIO_DEVICE_ATTR(temp_x_raw, S_IRUGO, adis16350_read_12bit_signed,
-		NULL, ADIS16350_XTEMP_OUT);
-static IIO_DEVICE_ATTR(temp_y_raw, S_IRUGO, adis16350_read_12bit_signed,
-		NULL, ADIS16350_YTEMP_OUT);
-static IIO_DEVICE_ATTR(temp_z_raw, S_IRUGO, adis16350_read_12bit_signed,
-		NULL, ADIS16350_ZTEMP_OUT);
-static IIO_CONST_ATTR_TEMP_SCALE("0.14534");
-static IIO_CONST_ATTR_TEMP_OFFSET("198.16");
-
-static IIO_DEV_ATTR_IN_RAW(1, adis16350_read_12bit_unsigned,
-		ADIS16350_AUX_ADC);
-static IIO_CONST_ATTR(in1_scale, "0.000806");
-
-static IIO_DEV_ATTR_SAMP_FREQ(S_IWUSR | S_IRUGO,
-		adis16350_read_frequency,
-		adis16350_write_frequency);
-
-static IIO_DEVICE_ATTR(reset, S_IWUSR, NULL,
-		adis16350_write_reset, 0);
-
-static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("409 546 819 1638");
-
-static IIO_CONST_ATTR_NAME("adis16350");
-
-static struct attribute *adis16350_attributes[] = {
-	&iio_dev_attr_gyro_x_calibbias.dev_attr.attr,
-	&iio_dev_attr_gyro_y_calibbias.dev_attr.attr,
-	&iio_dev_attr_gyro_z_calibbias.dev_attr.attr,
-	&iio_dev_attr_accel_x_calibbias.dev_attr.attr,
-	&iio_dev_attr_accel_y_calibbias.dev_attr.attr,
-	&iio_dev_attr_accel_z_calibbias.dev_attr.attr,
-	&iio_dev_attr_in0_supply_raw.dev_attr.attr,
-	&iio_const_attr_in0_supply_scale.dev_attr.attr,
-	&iio_dev_attr_gyro_x_raw.dev_attr.attr,
-	&iio_dev_attr_gyro_y_raw.dev_attr.attr,
-	&iio_dev_attr_gyro_z_raw.dev_attr.attr,
-	&iio_const_attr_gyro_scale.dev_attr.attr,
-	&iio_dev_attr_accel_x_raw.dev_attr.attr,
-	&iio_dev_attr_accel_y_raw.dev_attr.attr,
-	&iio_dev_attr_accel_z_raw.dev_attr.attr,
-	&iio_const_attr_accel_scale.dev_attr.attr,
-	&iio_dev_attr_temp_x_raw.dev_attr.attr,
-	&iio_dev_attr_temp_y_raw.dev_attr.attr,
-	&iio_dev_attr_temp_z_raw.dev_attr.attr,
-	&iio_const_attr_temp_scale.dev_attr.attr,
-	&iio_const_attr_temp_offset.dev_attr.attr,
-	&iio_dev_attr_in1_raw.dev_attr.attr,
-	&iio_const_attr_in1_scale.dev_attr.attr,
-	&iio_dev_attr_sampling_frequency.dev_attr.attr,
-	&iio_const_attr_sampling_frequency_available.dev_attr.attr,
-	&iio_dev_attr_reset.dev_attr.attr,
-	&iio_const_attr_name.dev_attr.attr,
-	NULL
-};
-
-static const struct attribute_group adis16350_attribute_group = {
-	.attrs = adis16350_attributes,
-};
-
-static struct attribute *adis16350_event_attributes[] = {
-	NULL,
-};
-
-static struct attribute_group adis16350_event_attribute_group = {
-	.attrs = adis16350_event_attributes,
-};
-
-static int __devinit adis16350_probe(struct spi_device *spi)
-{
-	int ret, regdone = 0;
-	struct adis16350_state *st = kzalloc(sizeof *st, GFP_KERNEL);
-	if (!st) {
-		ret =  -ENOMEM;
-		goto error_ret;
-	}
-	/* this is only used for removal purposes */
-	spi_set_drvdata(spi, st);
-
-	/* Allocate the comms buffers */
-	st->rx = kzalloc(sizeof(*st->rx)*ADIS16350_MAX_RX, GFP_KERNEL);
-	if (st->rx == NULL) {
-		ret = -ENOMEM;
-		goto error_free_st;
-	}
-	st->tx = kzalloc(sizeof(*st->tx)*ADIS16350_MAX_TX, GFP_KERNEL);
-	if (st->tx == NULL) {
-		ret = -ENOMEM;
-		goto error_free_rx;
-	}
-	st->us = spi;
-	mutex_init(&st->buf_lock);
-	/* setup the industrialio driver allocated elements */
-	st->indio_dev = iio_allocate_device();
-	if (st->indio_dev == NULL) {
-		ret = -ENOMEM;
-		goto error_free_tx;
-	}
-
-	st->indio_dev->dev.parent = &spi->dev;
-	st->indio_dev->num_interrupt_lines = 1;
-	st->indio_dev->event_attrs = &adis16350_event_attribute_group;
-	st->indio_dev->attrs = &adis16350_attribute_group;
-	st->indio_dev->dev_data = (void *)(st);
-	st->indio_dev->driver_module = THIS_MODULE;
-	st->indio_dev->modes = INDIO_DIRECT_MODE;
-
-	ret = adis16350_configure_ring(st->indio_dev);
-	if (ret)
-		goto error_free_dev;
-
-	ret = iio_device_register(st->indio_dev);
-	if (ret)
-		goto error_unreg_ring_funcs;
-	regdone = 1;
-
-	ret = iio_ring_buffer_register(st->indio_dev->ring, 0);
-	if (ret) {
-		printk(KERN_ERR "failed to initialize the ring\n");
-		goto error_unreg_ring_funcs;
-	}
-
-	if (spi->irq) {
-		ret = iio_register_interrupt_line(spi->irq,
-				st->indio_dev,
-				0,
-				IRQF_TRIGGER_RISING,
-				"adis16350");
-		if (ret)
-			goto error_uninitialize_ring;
-
-		ret = adis16350_probe_trigger(st->indio_dev);
-		if (ret)
-			goto error_unregister_line;
-	}
-
-	/* Get the device into a sane initial state */
-	ret = adis16350_initial_setup(st);
-	if (ret)
-		goto error_remove_trigger;
-	return 0;
-
-error_remove_trigger:
-	adis16350_remove_trigger(st->indio_dev);
-error_unregister_line:
-	if (spi->irq)
-		iio_unregister_interrupt_line(st->indio_dev, 0);
-error_uninitialize_ring:
-	iio_ring_buffer_unregister(st->indio_dev->ring);
-error_unreg_ring_funcs:
-	adis16350_unconfigure_ring(st->indio_dev);
-error_free_dev:
-	if (regdone)
-		iio_device_unregister(st->indio_dev);
-	else
-		iio_free_device(st->indio_dev);
-error_free_tx:
-	kfree(st->tx);
-error_free_rx:
-	kfree(st->rx);
-error_free_st:
-	kfree(st);
-error_ret:
-	return ret;
-}
-
-static int adis16350_remove(struct spi_device *spi)
-{
-	int ret;
-	struct adis16350_state *st = spi_get_drvdata(spi);
-	struct iio_dev *indio_dev = st->indio_dev;
-
-	ret = adis16350_stop_device(&(indio_dev->dev));
-	if (ret)
-		goto err_ret;
-
-	flush_scheduled_work();
-
-	adis16350_remove_trigger(indio_dev);
-	if (spi->irq)
-		iio_unregister_interrupt_line(indio_dev, 0);
-
-	iio_ring_buffer_unregister(indio_dev->ring);
-	iio_device_unregister(indio_dev);
-	adis16350_unconfigure_ring(indio_dev);
-	kfree(st->tx);
-	kfree(st->rx);
-	kfree(st);
-
-	return 0;
-
-err_ret:
-	return ret;
-}
-
-static const struct spi_device_id adis16350_id[] = {
-	{"adis16350", 0},
-	{"adis16354", 0},
-	{"adis16355", 0},
-	{"adis16360", 0},
-	{"adis16362", 0},
-	{"adis16364", 0},
-	{"adis16365", 0},
-	{}
-};
-
-static struct spi_driver adis16350_driver = {
-	.driver = {
-		.name = "adis16350",
-		.owner = THIS_MODULE,
-	},
-	.probe = adis16350_probe,
-	.remove = __devexit_p(adis16350_remove),
-	.id_table = adis16350_id,
-};
-
-static __init int adis16350_init(void)
-{
-	return spi_register_driver(&adis16350_driver);
-}
-module_init(adis16350_init);
-
-static __exit void adis16350_exit(void)
-{
-	spi_unregister_driver(&adis16350_driver);
-}
-module_exit(adis16350_exit);
-
-MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>");
-MODULE_DESCRIPTION("Analog Devices ADIS16350/54/55/60/62/64/65 IMU SPI driver");
-MODULE_LICENSE("GPL v2");
diff -druN linux-2.6.39-libre/drivers/staging/iio/imu/adis16350.h linux-3.0-rc7-libre/drivers/staging/iio/imu/adis16350.h
--- linux-2.6.39-libre/drivers/staging/iio/imu/adis16350.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/iio/imu/adis16350.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,177 +0,0 @@
-#ifndef SPI_ADIS16350_H_
-#define SPI_ADIS16350_H_
-
-#define ADIS16350_STARTUP_DELAY	220 /* ms */
-
-#define ADIS16350_READ_REG(a)    a
-#define ADIS16350_WRITE_REG(a) ((a) | 0x80)
-
-#define ADIS16350_FLASH_CNT  0x00 /* Flash memory write count */
-#define ADIS16350_SUPPLY_OUT 0x02 /* Power supply measurement */
-#define ADIS16350_XGYRO_OUT 0x04 /* X-axis gyroscope output */
-#define ADIS16350_YGYRO_OUT 0x06 /* Y-axis gyroscope output */
-#define ADIS16350_ZGYRO_OUT 0x08 /* Z-axis gyroscope output */
-#define ADIS16350_XACCL_OUT 0x0A /* X-axis accelerometer output */
-#define ADIS16350_YACCL_OUT 0x0C /* Y-axis accelerometer output */
-#define ADIS16350_ZACCL_OUT 0x0E /* Z-axis accelerometer output */
-#define ADIS16350_XTEMP_OUT 0x10 /* X-axis gyroscope temperature measurement */
-#define ADIS16350_YTEMP_OUT 0x12 /* Y-axis gyroscope temperature measurement */
-#define ADIS16350_ZTEMP_OUT 0x14 /* Z-axis gyroscope temperature measurement */
-#define ADIS16350_AUX_ADC   0x16 /* Auxiliary ADC measurement */
-
-/* Calibration parameters */
-#define ADIS16350_XGYRO_OFF 0x1A /* X-axis gyroscope bias offset factor */
-#define ADIS16350_YGYRO_OFF 0x1C /* Y-axis gyroscope bias offset factor */
-#define ADIS16350_ZGYRO_OFF 0x1E /* Z-axis gyroscope bias offset factor */
-#define ADIS16350_XACCL_OFF 0x20 /* X-axis acceleration bias offset factor */
-#define ADIS16350_YACCL_OFF 0x22 /* Y-axis acceleration bias offset factor */
-#define ADIS16350_ZACCL_OFF 0x24 /* Z-axis acceleration bias offset factor */
-
-#define ADIS16350_GPIO_CTRL 0x32 /* Auxiliary digital input/output control */
-#define ADIS16350_MSC_CTRL  0x34 /* Miscellaneous control */
-#define ADIS16350_SMPL_PRD  0x36 /* Internal sample period (rate) control */
-#define ADIS16350_SENS_AVG  0x38 /* Dynamic range and digital filter control */
-#define ADIS16350_SLP_CNT   0x3A /* Sleep mode control */
-#define ADIS16350_DIAG_STAT 0x3C /* System status */
-
-/* Alarm functions */
-#define ADIS16350_GLOB_CMD  0x3E /* System command */
-#define ADIS16350_ALM_MAG1  0x26 /* Alarm 1 amplitude threshold */
-#define ADIS16350_ALM_MAG2  0x28 /* Alarm 2 amplitude threshold */
-#define ADIS16350_ALM_SMPL1 0x2A /* Alarm 1 sample size */
-#define ADIS16350_ALM_SMPL2 0x2C /* Alarm 2 sample size */
-#define ADIS16350_ALM_CTRL  0x2E /* Alarm control */
-#define ADIS16350_AUX_DAC   0x30 /* Auxiliary DAC data */
-
-#define ADIS16350_ERROR_ACTIVE			(1<<14)
-#define ADIS16350_NEW_DATA			(1<<15)
-
-/* MSC_CTRL */
-#define ADIS16350_MSC_CTRL_MEM_TEST		(1<<11)
-#define ADIS16350_MSC_CTRL_INT_SELF_TEST	(1<<10)
-#define ADIS16350_MSC_CTRL_NEG_SELF_TEST	(1<<9)
-#define ADIS16350_MSC_CTRL_POS_SELF_TEST	(1<<8)
-#define ADIS16350_MSC_CTRL_GYRO_BIAS		(1<<7)
-#define ADIS16350_MSC_CTRL_ACCL_ALIGN		(1<<6)
-#define ADIS16350_MSC_CTRL_DATA_RDY_EN		(1<<2)
-#define ADIS16350_MSC_CTRL_DATA_RDY_POL_HIGH	(1<<1)
-#define ADIS16350_MSC_CTRL_DATA_RDY_DIO2	(1<<0)
-
-/* SMPL_PRD */
-#define ADIS16350_SMPL_PRD_TIME_BASE	(1<<7)
-#define ADIS16350_SMPL_PRD_DIV_MASK	0x7F
-
-/* DIAG_STAT */
-#define ADIS16350_DIAG_STAT_ZACCL_FAIL	(1<<15)
-#define ADIS16350_DIAG_STAT_YACCL_FAIL	(1<<14)
-#define ADIS16350_DIAG_STAT_XACCL_FAIL	(1<<13)
-#define ADIS16350_DIAG_STAT_XGYRO_FAIL	(1<<12)
-#define ADIS16350_DIAG_STAT_YGYRO_FAIL	(1<<11)
-#define ADIS16350_DIAG_STAT_ZGYRO_FAIL	(1<<10)
-#define ADIS16350_DIAG_STAT_ALARM2	(1<<9)
-#define ADIS16350_DIAG_STAT_ALARM1	(1<<8)
-#define ADIS16350_DIAG_STAT_FLASH_CHK	(1<<6)
-#define ADIS16350_DIAG_STAT_SELF_TEST	(1<<5)
-#define ADIS16350_DIAG_STAT_OVERFLOW	(1<<4)
-#define ADIS16350_DIAG_STAT_SPI_FAIL	(1<<3)
-#define ADIS16350_DIAG_STAT_FLASH_UPT	(1<<2)
-#define ADIS16350_DIAG_STAT_POWER_HIGH	(1<<1)
-#define ADIS16350_DIAG_STAT_POWER_LOW	(1<<0)
-
-/* GLOB_CMD */
-#define ADIS16350_GLOB_CMD_SW_RESET	(1<<7)
-#define ADIS16350_GLOB_CMD_P_AUTO_NULL	(1<<4)
-#define ADIS16350_GLOB_CMD_FLASH_UPD	(1<<3)
-#define ADIS16350_GLOB_CMD_DAC_LATCH	(1<<2)
-#define ADIS16350_GLOB_CMD_FAC_CALIB	(1<<1)
-#define ADIS16350_GLOB_CMD_AUTO_NULL	(1<<0)
-
-/* SLP_CNT */
-#define ADIS16350_SLP_CNT_POWER_OFF	(1<<8)
-
-#define ADIS16350_MAX_TX 24
-#define ADIS16350_MAX_RX 24
-
-#define ADIS16350_SPI_SLOW	(u32)(300 * 1000)
-#define ADIS16350_SPI_BURST	(u32)(1000 * 1000)
-#define ADIS16350_SPI_FAST	(u32)(2000 * 1000)
-
-/**
- * struct adis16350_state - device instance specific data
- * @us:			actual spi_device
- * @work_trigger_to_ring: bh for triggered event handling
- * @inter:		used to check if new interrupt has been triggered
- * @last_timestamp:	passing timestamp from th to bh of interrupt handler
- * @indio_dev:		industrial I/O device structure
- * @trig:		data ready trigger registered with iio
- * @tx:			transmit buffer
- * @rx:			receive buffer
- * @buf_lock:		mutex to protect tx and rx
- **/
-struct adis16350_state {
-	struct spi_device		*us;
-	struct work_struct		work_trigger_to_ring;
-	s64				last_timestamp;
-	struct iio_dev			*indio_dev;
-	struct iio_trigger		*trig;
-	u8				*tx;
-	u8				*rx;
-	struct mutex			buf_lock;
-};
-
-int adis16350_set_irq(struct device *dev, bool enable);
-
-#ifdef CONFIG_IIO_RING_BUFFER
-
-#define ADIS16350_SCAN_SUPPLY	0
-#define ADIS16350_SCAN_GYRO_X	1
-#define ADIS16350_SCAN_GYRO_Y	2
-#define ADIS16350_SCAN_GYRO_Z	3
-#define ADIS16350_SCAN_ACC_X	4
-#define ADIS16350_SCAN_ACC_Y	5
-#define ADIS16350_SCAN_ACC_Z	6
-#define ADIS16350_SCAN_TEMP_X	7
-#define ADIS16350_SCAN_TEMP_Y	8
-#define ADIS16350_SCAN_TEMP_Z	9
-#define ADIS16350_SCAN_ADC_0	10
-
-void adis16350_remove_trigger(struct iio_dev *indio_dev);
-int adis16350_probe_trigger(struct iio_dev *indio_dev);
-
-ssize_t adis16350_read_data_from_ring(struct device *dev,
-				      struct device_attribute *attr,
-				      char *buf);
-
-
-int adis16350_configure_ring(struct iio_dev *indio_dev);
-void adis16350_unconfigure_ring(struct iio_dev *indio_dev);
-
-#else /* CONFIG_IIO_RING_BUFFER */
-
-static inline void adis16350_remove_trigger(struct iio_dev *indio_dev)
-{
-}
-
-static inline int adis16350_probe_trigger(struct iio_dev *indio_dev)
-{
-	return 0;
-}
-
-static inline ssize_t
-adis16350_read_data_from_ring(struct device *dev,
-			      struct device_attribute *attr,
-			      char *buf)
-{
-	return 0;
-}
-
-static inline int adis16350_configure_ring(struct iio_dev *indio_dev)
-{
-	return 0;
-}
-
-static inline void adis16350_unconfigure_ring(struct iio_dev *indio_dev)
-{
-}
-#endif /* CONFIG_IIO_RING_BUFFER */
-#endif /* SPI_ADIS16350_H_ */
diff -druN linux-2.6.39-libre/drivers/staging/iio/imu/adis16350_ring.c linux-3.0-rc7-libre/drivers/staging/iio/imu/adis16350_ring.c
--- linux-2.6.39-libre/drivers/staging/iio/imu/adis16350_ring.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/iio/imu/adis16350_ring.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,236 +0,0 @@
-#include <linux/interrupt.h>
-#include <linux/irq.h>
-#include <linux/gpio.h>
-#include <linux/workqueue.h>
-#include <linux/mutex.h>
-#include <linux/device.h>
-#include <linux/kernel.h>
-#include <linux/spi/spi.h>
-#include <linux/slab.h>
-#include <linux/sysfs.h>
-#include <linux/list.h>
-
-#include "../iio.h"
-#include "../sysfs.h"
-#include "../ring_sw.h"
-#include "../accel/accel.h"
-#include "../trigger.h"
-#include "adis16350.h"
-
-static IIO_SCAN_EL_C(in0_supply, ADIS16350_SCAN_SUPPLY,
-		ADIS16350_SUPPLY_OUT, NULL);
-static IIO_CONST_ATTR_SCAN_EL_TYPE(in0_supply, u, 12, 16);
-
-static IIO_SCAN_EL_C(gyro_x, ADIS16350_SCAN_GYRO_X, ADIS16350_XGYRO_OUT, NULL);
-static IIO_SCAN_EL_C(gyro_y, ADIS16350_SCAN_GYRO_Y, ADIS16350_YGYRO_OUT, NULL);
-static IIO_SCAN_EL_C(gyro_z, ADIS16350_SCAN_GYRO_Z, ADIS16350_ZGYRO_OUT, NULL);
-static IIO_CONST_ATTR_SCAN_EL_TYPE(gyro, s, 14, 16);
-
-static IIO_SCAN_EL_C(accel_x, ADIS16350_SCAN_ACC_X, ADIS16350_XACCL_OUT, NULL);
-static IIO_SCAN_EL_C(accel_y, ADIS16350_SCAN_ACC_Y, ADIS16350_YACCL_OUT, NULL);
-static IIO_SCAN_EL_C(accel_z, ADIS16350_SCAN_ACC_Z, ADIS16350_ZACCL_OUT, NULL);
-static IIO_CONST_ATTR_SCAN_EL_TYPE(accel, s, 14, 16);
-
-static IIO_SCAN_EL_C(temp_x, ADIS16350_SCAN_TEMP_X, ADIS16350_XTEMP_OUT, NULL);
-static IIO_SCAN_EL_C(temp_y, ADIS16350_SCAN_TEMP_Y, ADIS16350_YTEMP_OUT, NULL);
-static IIO_SCAN_EL_C(temp_z, ADIS16350_SCAN_TEMP_Z, ADIS16350_ZTEMP_OUT, NULL);
-static IIO_CONST_ATTR_SCAN_EL_TYPE(temp, s, 12, 16);
-
-static IIO_SCAN_EL_C(in1, ADIS16350_SCAN_ADC_0, ADIS16350_AUX_ADC, NULL);
-static IIO_CONST_ATTR_SCAN_EL_TYPE(in1, u, 12, 16);
-
-static IIO_SCAN_EL_TIMESTAMP(11);
-static IIO_CONST_ATTR_SCAN_EL_TYPE(timestamp, s, 64, 64);
-
-static struct attribute *adis16350_scan_el_attrs[] = {
-	&iio_scan_el_in0_supply.dev_attr.attr,
-	&iio_const_attr_in0_supply_index.dev_attr.attr,
-	&iio_const_attr_in0_supply_type.dev_attr.attr,
-	&iio_scan_el_gyro_x.dev_attr.attr,
-	&iio_const_attr_gyro_x_index.dev_attr.attr,
-	&iio_scan_el_gyro_y.dev_attr.attr,
-	&iio_const_attr_gyro_y_index.dev_attr.attr,
-	&iio_scan_el_gyro_z.dev_attr.attr,
-	&iio_const_attr_gyro_z_index.dev_attr.attr,
-	&iio_const_attr_gyro_type.dev_attr.attr,
-	&iio_scan_el_accel_x.dev_attr.attr,
-	&iio_const_attr_accel_x_index.dev_attr.attr,
-	&iio_scan_el_accel_y.dev_attr.attr,
-	&iio_const_attr_accel_y_index.dev_attr.attr,
-	&iio_scan_el_accel_z.dev_attr.attr,
-	&iio_const_attr_accel_z_index.dev_attr.attr,
-	&iio_const_attr_accel_type.dev_attr.attr,
-	&iio_scan_el_temp_x.dev_attr.attr,
-	&iio_const_attr_temp_x_index.dev_attr.attr,
-	&iio_scan_el_temp_y.dev_attr.attr,
-	&iio_const_attr_temp_y_index.dev_attr.attr,
-	&iio_scan_el_temp_z.dev_attr.attr,
-	&iio_const_attr_temp_z_index.dev_attr.attr,
-	&iio_const_attr_temp_type.dev_attr.attr,
-	&iio_scan_el_in1.dev_attr.attr,
-	&iio_const_attr_in1_index.dev_attr.attr,
-	&iio_const_attr_in1_type.dev_attr.attr,
-	&iio_scan_el_timestamp.dev_attr.attr,
-	&iio_const_attr_timestamp_index.dev_attr.attr,
-	&iio_const_attr_timestamp_type.dev_attr.attr,
-	NULL,
-};
-
-static struct attribute_group adis16350_scan_el_group = {
-	.attrs = adis16350_scan_el_attrs,
-	.name = "scan_elements",
-};
-
-/**
- * adis16350_poll_func_th() top half interrupt handler called by trigger
- * @private_data:	iio_dev
- **/
-static void adis16350_poll_func_th(struct iio_dev *indio_dev, s64 time)
-{
-	struct adis16350_state *st = iio_dev_get_devdata(indio_dev);
-	st->last_timestamp = time;
-	schedule_work(&st->work_trigger_to_ring);
-}
-
-/**
- * adis16350_spi_read_burst() - read all data registers
- * @dev: device associated with child of actual device (iio_dev or iio_trig)
- * @rx: somewhere to pass back the value read (min size is 24 bytes)
- **/
-static int adis16350_spi_read_burst(struct device *dev, u8 *rx)
-{
-	struct spi_message msg;
-	struct iio_dev *indio_dev = dev_get_drvdata(dev);
-	struct adis16350_state *st = iio_dev_get_devdata(indio_dev);
-	u32 old_speed_hz = st->us->max_speed_hz;
-	int ret;
-
-	struct spi_transfer xfers[] = {
-		{
-			.tx_buf = st->tx,
-			.bits_per_word = 8,
-			.len = 2,
-			.cs_change = 0,
-		}, {
-			.rx_buf = rx,
-			.bits_per_word = 8,
-			.len = 22,
-			.cs_change = 0,
-		},
-	};
-
-	mutex_lock(&st->buf_lock);
-	st->tx[0] = ADIS16350_READ_REG(ADIS16350_GLOB_CMD);
-	st->tx[1] = 0;
-
-	spi_message_init(&msg);
-	spi_message_add_tail(&xfers[0], &msg);
-	spi_message_add_tail(&xfers[1], &msg);
-
-	st->us->max_speed_hz = ADIS16350_SPI_BURST;
-	spi_setup(st->us);
-
-	ret = spi_sync(st->us, &msg);
-	if (ret)
-		dev_err(&st->us->dev, "problem when burst reading");
-
-	st->us->max_speed_hz = old_speed_hz;
-	spi_setup(st->us);
-	mutex_unlock(&st->buf_lock);
-	return ret;
-}
-
-/* Whilst this makes a lot of calls to iio_sw_ring functions - it is to device
- * specific to be rolled into the core.
- */
-static void adis16350_trigger_bh_to_ring(struct work_struct *work_s)
-{
-	struct adis16350_state *st
-		= container_of(work_s, struct adis16350_state,
-			       work_trigger_to_ring);
-	struct iio_ring_buffer *ring = st->indio_dev->ring;
-
-	int i = 0;
-	s16 *data;
-	size_t datasize = ring->access.get_bytes_per_datum(ring);
-
-	data = kmalloc(datasize , GFP_KERNEL);
-	if (data == NULL) {
-		dev_err(&st->us->dev, "memory alloc failed in ring bh");
-		return;
-	}
-
-	if (ring->scan_count)
-		if (adis16350_spi_read_burst(&st->indio_dev->dev, st->rx) >= 0)
-			for (; i < ring->scan_count; i++)
-				data[i] = be16_to_cpup(
-					(__be16 *)&(st->rx[i*2]));
-
-	/* Guaranteed to be aligned with 8 byte boundary */
-	if (ring->scan_timestamp)
-		*((s64 *)(data + ((i + 3)/4)*4)) = st->last_timestamp;
-
-	ring->access.store_to(ring,
-			(u8 *)data,
-			st->last_timestamp);
-
-	iio_trigger_notify_done(st->indio_dev->trig);
-	kfree(data);
-
-	return;
-}
-
-void adis16350_unconfigure_ring(struct iio_dev *indio_dev)
-{
-	kfree(indio_dev->pollfunc);
-	iio_sw_rb_free(indio_dev->ring);
-}
-
-int adis16350_configure_ring(struct iio_dev *indio_dev)
-{
-	int ret = 0;
-	struct adis16350_state *st = indio_dev->dev_data;
-	struct iio_ring_buffer *ring;
-	INIT_WORK(&st->work_trigger_to_ring, adis16350_trigger_bh_to_ring);
-
-	ring = iio_sw_rb_allocate(indio_dev);
-	if (!ring) {
-		ret = -ENOMEM;
-		return ret;
-	}
-	indio_dev->ring = ring;
-	/* Effectively select the ring buffer implementation */
-	iio_ring_sw_register_funcs(&ring->access);
-	ring->bpe = 2;
-	ring->scan_el_attrs = &adis16350_scan_el_group;
-	ring->scan_timestamp = true;
-	ring->preenable = &iio_sw_ring_preenable;
-	ring->postenable = &iio_triggered_ring_postenable;
-	ring->predisable = &iio_triggered_ring_predisable;
-	ring->owner = THIS_MODULE;
-
-	/* Set default scan mode */
-	iio_scan_mask_set(ring, iio_scan_el_in0_supply.number);
-	iio_scan_mask_set(ring, iio_scan_el_gyro_x.number);
-	iio_scan_mask_set(ring, iio_scan_el_gyro_y.number);
-	iio_scan_mask_set(ring, iio_scan_el_gyro_z.number);
-	iio_scan_mask_set(ring, iio_scan_el_accel_x.number);
-	iio_scan_mask_set(ring, iio_scan_el_accel_y.number);
-	iio_scan_mask_set(ring, iio_scan_el_accel_z.number);
-	iio_scan_mask_set(ring, iio_scan_el_temp_x.number);
-	iio_scan_mask_set(ring, iio_scan_el_temp_y.number);
-	iio_scan_mask_set(ring, iio_scan_el_temp_z.number);
-	iio_scan_mask_set(ring, iio_scan_el_in1.number);
-
-	ret = iio_alloc_pollfunc(indio_dev, NULL, &adis16350_poll_func_th);
-	if (ret)
-		goto error_iio_sw_rb_free;
-
-	indio_dev->modes |= INDIO_RING_TRIGGERED;
-	return 0;
-
-error_iio_sw_rb_free:
-	iio_sw_rb_free(indio_dev->ring);
-	return ret;
-}
-
diff -druN linux-2.6.39-libre/drivers/staging/iio/imu/adis16350_trigger.c linux-3.0-rc7-libre/drivers/staging/iio/imu/adis16350_trigger.c
--- linux-2.6.39-libre/drivers/staging/iio/imu/adis16350_trigger.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/iio/imu/adis16350_trigger.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,125 +0,0 @@
-#include <linux/interrupt.h>
-#include <linux/irq.h>
-#include <linux/mutex.h>
-#include <linux/device.h>
-#include <linux/kernel.h>
-#include <linux/sysfs.h>
-#include <linux/list.h>
-#include <linux/spi/spi.h>
-
-#include "../iio.h"
-#include "../sysfs.h"
-#include "../trigger.h"
-#include "adis16350.h"
-
-/**
- * adis16350_data_rdy_trig_poll() the event handler for the data rdy trig
- **/
-static int adis16350_data_rdy_trig_poll(struct iio_dev *dev_info,
-				       int index,
-				       s64 timestamp,
-				       int no_test)
-{
-	struct adis16350_state *st = iio_dev_get_devdata(dev_info);
-	struct iio_trigger *trig = st->trig;
-
-	iio_trigger_poll(trig, timestamp);
-
-	return IRQ_HANDLED;
-}
-
-IIO_EVENT_SH(data_rdy_trig, &adis16350_data_rdy_trig_poll);
-
-static IIO_TRIGGER_NAME_ATTR;
-
-static struct attribute *adis16350_trigger_attrs[] = {
-	&dev_attr_name.attr,
-	NULL,
-};
-
-static const struct attribute_group adis16350_trigger_attr_group = {
-	.attrs = adis16350_trigger_attrs,
-};
-
-/**
- * adis16350_data_rdy_trigger_set_state() set datardy interrupt state
- **/
-static int adis16350_data_rdy_trigger_set_state(struct iio_trigger *trig,
-						bool state)
-{
-	struct adis16350_state *st = trig->private_data;
-	struct iio_dev *indio_dev = st->indio_dev;
-	int ret = 0;
-
-	dev_dbg(&indio_dev->dev, "%s (%d)\n", __func__, state);
-	ret = adis16350_set_irq(&st->indio_dev->dev, state);
-	if (state == false) {
-		iio_remove_event_from_list(&iio_event_data_rdy_trig,
-					   &indio_dev->interrupts[0]
-					   ->ev_list);
-		/* possible quirk with handler currently worked around
-		   by ensuring the work queue is empty */
-		flush_scheduled_work();
-	} else {
-		iio_add_event_to_list(&iio_event_data_rdy_trig,
-				      &indio_dev->interrupts[0]->ev_list);
-	}
-	return ret;
-}
-
-/**
- * adis16350_trig_try_reen() try renabling irq for data rdy trigger
- * @trig:	the datardy trigger
- **/
-static int adis16350_trig_try_reen(struct iio_trigger *trig)
-{
-	struct adis16350_state *st = trig->private_data;
-	enable_irq(st->us->irq);
-	/* irq reenabled so success! */
-	return 0;
-}
-
-int adis16350_probe_trigger(struct iio_dev *indio_dev)
-{
-	int ret;
-	struct adis16350_state *st = indio_dev->dev_data;
-
-	st->trig = iio_allocate_trigger();
-	st->trig->name = kasprintf(GFP_KERNEL,
-				   "adis16350-dev%d",
-				   indio_dev->id);
-	if (!st->trig->name) {
-		ret = -ENOMEM;
-		goto error_free_trig;
-	}
-	st->trig->dev.parent = &st->us->dev;
-	st->trig->owner = THIS_MODULE;
-	st->trig->private_data = st;
-	st->trig->set_trigger_state = &adis16350_data_rdy_trigger_set_state;
-	st->trig->try_reenable = &adis16350_trig_try_reen;
-	st->trig->control_attrs = &adis16350_trigger_attr_group;
-	ret = iio_trigger_register(st->trig);
-
-	/* select default trigger */
-	indio_dev->trig = st->trig;
-	if (ret)
-		goto error_free_trig_name;
-
-	return 0;
-
-error_free_trig_name:
-	kfree(st->trig->name);
-error_free_trig:
-	iio_free_trigger(st->trig);
-
-	return ret;
-}
-
-void adis16350_remove_trigger(struct iio_dev *indio_dev)
-{
-	struct adis16350_state *state = indio_dev->dev_data;
-
-	iio_trigger_unregister(state->trig);
-	kfree(state->trig->name);
-	iio_free_trigger(state->trig);
-}
diff -druN linux-2.6.39-libre/drivers/staging/iio/imu/adis16400_core.c linux-3.0-rc7-libre/drivers/staging/iio/imu/adis16400_core.c
--- linux-2.6.39-libre/drivers/staging/iio/imu/adis16400_core.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/iio/imu/adis16400_core.c	2011-07-11 19:51:52.000000000 -0400
@@ -38,7 +38,17 @@
 
 #define DRIVER_NAME		"adis16400"
 
-static int adis16400_check_status(struct device *dev);
+enum adis16400_chip_variant {
+	ADIS16300,
+	ADIS16350,
+	ADIS16360,
+	ADIS16362,
+	ADIS16364,
+	ADIS16365,
+	ADIS16400,
+};
+
+static int adis16400_check_status(struct iio_dev *indio_dev);
 
 /* At the moment the spi framework doesn't allow global setting of cs_change.
  * It's in the likely to be added comment at the top of spi.h.
@@ -51,13 +61,12 @@
  * @reg_address: the address of the register to be written
  * @val: the value to write
  **/
-static int adis16400_spi_write_reg_8(struct device *dev,
-		u8 reg_address,
-		u8 val)
+static int adis16400_spi_write_reg_8(struct iio_dev *indio_dev,
+				     u8 reg_address,
+				     u8 val)
 {
 	int ret;
-	struct iio_dev *indio_dev = dev_get_drvdata(dev);
-	struct adis16400_state *st = iio_dev_get_devdata(indio_dev);
+	struct adis16400_state *st = iio_priv(indio_dev);
 
 	mutex_lock(&st->buf_lock);
 	st->tx[0] = ADIS16400_WRITE_REG(reg_address);
@@ -76,14 +85,13 @@
  *               is assumed to have address one greater.
  * @val: value to be written
  **/
-static int adis16400_spi_write_reg_16(struct device *dev,
+static int adis16400_spi_write_reg_16(struct iio_dev *indio_dev,
 		u8 lower_reg_address,
 		u16 value)
 {
 	int ret;
 	struct spi_message msg;
-	struct iio_dev *indio_dev = dev_get_drvdata(dev);
-	struct adis16400_state *st = iio_dev_get_devdata(indio_dev);
+	struct adis16400_state *st = iio_priv(indio_dev);
 	struct spi_transfer xfers[] = {
 		{
 			.tx_buf = st->tx,
@@ -114,18 +122,17 @@
 
 /**
  * adis16400_spi_read_reg_16() - read 2 bytes from a 16-bit register
- * @dev: device associated with child of actual device (iio_dev or iio_trig)
+ * @indio_dev: iio device
  * @reg_address: the address of the lower of the two registers. Second register
  *               is assumed to have address one greater.
  * @val: somewhere to pass back the value read
  **/
-static int adis16400_spi_read_reg_16(struct device *dev,
+static int adis16400_spi_read_reg_16(struct iio_dev *indio_dev,
 		u8 lower_reg_address,
 		u16 *val)
 {
 	struct spi_message msg;
-	struct iio_dev *indio_dev = dev_get_drvdata(dev);
-	struct adis16400_state *st = iio_dev_get_devdata(indio_dev);
+	struct adis16400_state *st = iio_priv(indio_dev);
 	int ret;
 	struct spi_transfer xfers[] = {
 		{
@@ -163,100 +170,15 @@
 	return ret;
 }
 
-static ssize_t adis16400_spi_read_signed(struct device *dev,
-		struct device_attribute *attr,
-		char *buf,
-		unsigned bits)
-{
-	int ret;
-	s16 val = 0;
-	unsigned shift = 16 - bits;
-	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
-
-	ret = adis16400_spi_read_reg_16(dev, this_attr->address, (u16 *)&val);
-	if (ret)
-		return ret;
-
-	if (val & ADIS16400_ERROR_ACTIVE)
-		adis16400_check_status(dev);
-	val = ((s16)(val << shift) >> shift);
-	return sprintf(buf, "%d\n", val);
-}
-
-static ssize_t adis16400_read_12bit_unsigned(struct device *dev,
-		struct device_attribute *attr,
-		char *buf)
-{
-	int ret;
-	u16 val = 0;
-	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
-
-	ret = adis16400_spi_read_reg_16(dev, this_attr->address, &val);
-	if (ret)
-		return ret;
-
-	if (val & ADIS16400_ERROR_ACTIVE)
-		adis16400_check_status(dev);
-
-	return sprintf(buf, "%u\n", val & 0x0FFF);
-}
-
-static ssize_t adis16400_read_14bit_signed(struct device *dev,
-		struct device_attribute *attr,
-		char *buf)
-{
-	struct iio_dev *indio_dev = dev_get_drvdata(dev);
-	ssize_t ret;
-
-	/* Take the iio_dev status lock */
-	mutex_lock(&indio_dev->mlock);
-	ret =  adis16400_spi_read_signed(dev, attr, buf, 14);
-	mutex_unlock(&indio_dev->mlock);
-
-	return ret;
-}
-
-static ssize_t adis16400_read_12bit_signed(struct device *dev,
-		struct device_attribute *attr,
-		char *buf)
-{
-	struct iio_dev *indio_dev = dev_get_drvdata(dev);
-	ssize_t ret;
-
-	/* Take the iio_dev status lock */
-	mutex_lock(&indio_dev->mlock);
-	ret =  adis16400_spi_read_signed(dev, attr, buf, 12);
-	mutex_unlock(&indio_dev->mlock);
-
-	return ret;
-}
-
-static ssize_t adis16400_write_16bit(struct device *dev,
-		struct device_attribute *attr,
-		const char *buf,
-		size_t len)
-{
-	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
-	int ret;
-	long val;
-
-	ret = strict_strtol(buf, 10, &val);
-	if (ret)
-		goto error_ret;
-	ret = adis16400_spi_write_reg_16(dev, this_attr->address, val);
-
-error_ret:
-	return ret ? ret : len;
-}
-
 static ssize_t adis16400_read_frequency(struct device *dev,
 		struct device_attribute *attr,
 		char *buf)
 {
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
 	int ret, len = 0;
 	u16 t;
 	int sps;
-	ret = adis16400_spi_read_reg_16(dev,
+	ret = adis16400_spi_read_reg_16(indio_dev,
 			ADIS16400_SMPL_PRD,
 			&t);
 	if (ret)
@@ -273,7 +195,7 @@
 		size_t len)
 {
 	struct iio_dev *indio_dev = dev_get_drvdata(dev);
-	struct adis16400_state *st = iio_dev_get_devdata(indio_dev);
+	struct adis16400_state *st = iio_priv(indio_dev);
 	long val;
 	int ret;
 	u8 t;
@@ -293,7 +215,7 @@
 	else
 		st->us->max_speed_hz = ADIS16400_SPI_FAST;
 
-	ret = adis16400_spi_write_reg_8(dev,
+	ret = adis16400_spi_write_reg_8(indio_dev,
 			ADIS16400_SMPL_PRD,
 			t);
 
@@ -302,14 +224,14 @@
 	return ret ? ret : len;
 }
 
-static int adis16400_reset(struct device *dev)
+static int adis16400_reset(struct iio_dev *indio_dev)
 {
 	int ret;
-	ret = adis16400_spi_write_reg_8(dev,
+	ret = adis16400_spi_write_reg_8(indio_dev,
 			ADIS16400_GLOB_CMD,
 			ADIS16400_GLOB_CMD_SW_RESET);
 	if (ret)
-		dev_err(dev, "problem resetting device");
+		dev_err(&indio_dev->dev, "problem resetting device");
 
 	return ret;
 }
@@ -318,22 +240,24 @@
 		struct device_attribute *attr,
 		const char *buf, size_t len)
 {
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+
 	if (len < 1)
 		return -1;
 	switch (buf[0]) {
 	case '1':
 	case 'y':
 	case 'Y':
-		return adis16400_reset(dev);
+		return adis16400_reset(indio_dev);
 	}
 	return -1;
 }
 
-int adis16400_set_irq(struct device *dev, bool enable)
+int adis16400_set_irq(struct iio_dev *indio_dev, bool enable)
 {
 	int ret;
 	u16 msc;
-	ret = adis16400_spi_read_reg_16(dev, ADIS16400_MSC_CTRL, &msc);
+	ret = adis16400_spi_read_reg_16(indio_dev, ADIS16400_MSC_CTRL, &msc);
 	if (ret)
 		goto error_ret;
 
@@ -343,7 +267,7 @@
 	else
 		msc &= ~ADIS16400_MSC_CTRL_DATA_RDY_EN;
 
-	ret = adis16400_spi_write_reg_16(dev, ADIS16400_MSC_CTRL, msc);
+	ret = adis16400_spi_write_reg_16(indio_dev, ADIS16400_MSC_CTRL, msc);
 	if (ret)
 		goto error_ret;
 
@@ -352,41 +276,45 @@
 }
 
 /* Power down the device */
-static int adis16400_stop_device(struct device *dev)
+static int adis16400_stop_device(struct iio_dev *indio_dev)
 {
 	int ret;
 	u16 val = ADIS16400_SLP_CNT_POWER_OFF;
 
-	ret = adis16400_spi_write_reg_16(dev, ADIS16400_SLP_CNT, val);
+	ret = adis16400_spi_write_reg_16(indio_dev, ADIS16400_SLP_CNT, val);
 	if (ret)
-		dev_err(dev, "problem with turning device off: SLP_CNT");
+		dev_err(&indio_dev->dev,
+			"problem with turning device off: SLP_CNT");
 
 	return ret;
 }
 
-static int adis16400_self_test(struct device *dev)
+static int adis16400_self_test(struct iio_dev *indio_dev)
 {
 	int ret;
-	ret = adis16400_spi_write_reg_16(dev,
+	ret = adis16400_spi_write_reg_16(indio_dev,
 			ADIS16400_MSC_CTRL,
 			ADIS16400_MSC_CTRL_MEM_TEST);
 	if (ret) {
-		dev_err(dev, "problem starting self test");
+		dev_err(&indio_dev->dev, "problem starting self test");
 		goto err_ret;
 	}
+
 	msleep(ADIS16400_MTEST_DELAY);
-	adis16400_check_status(dev);
+	adis16400_check_status(indio_dev);
 
 err_ret:
 	return ret;
 }
 
-static int adis16400_check_status(struct device *dev)
+static int adis16400_check_status(struct iio_dev *indio_dev)
 {
 	u16 status;
 	int ret;
+	struct device *dev = &indio_dev->dev;
 
-	ret = adis16400_spi_read_reg_16(dev, ADIS16400_DIAG_STAT, &status);
+	ret = adis16400_spi_read_reg_16(indio_dev,
+					ADIS16400_DIAG_STAT, &status);
 
 	if (ret < 0) {
 		dev_err(dev, "Reading status failed\n");
@@ -428,11 +356,12 @@
 	return ret;
 }
 
-static int adis16400_initial_setup(struct adis16400_state *st)
+static int adis16400_initial_setup(struct iio_dev *indio_dev)
 {
 	int ret;
 	u16 prod_id, smp_prd;
-	struct device *dev = &st->indio_dev->dev;
+	struct device *dev = &indio_dev->dev;
+	struct adis16400_state *st = iio_priv(indio_dev);
 
 	/* use low spi speed for init */
 	st->us->max_speed_hz = ADIS16400_SPI_SLOW;
@@ -440,45 +369,46 @@
 	spi_setup(st->us);
 
 	/* Disable IRQ */
-	ret = adis16400_set_irq(dev, false);
+	ret = adis16400_set_irq(indio_dev, false);
 	if (ret) {
 		dev_err(dev, "disable irq failed");
 		goto err_ret;
 	}
 
 	/* Do self test */
-	ret = adis16400_self_test(dev);
+	ret = adis16400_self_test(indio_dev);
 	if (ret) {
 		dev_err(dev, "self test failure");
 		goto err_ret;
 	}
 
 	/* Read status register to check the result */
-	ret = adis16400_check_status(dev);
+	ret = adis16400_check_status(indio_dev);
 	if (ret) {
-		adis16400_reset(dev);
+		adis16400_reset(indio_dev);
 		dev_err(dev, "device not playing ball -> reset");
 		msleep(ADIS16400_STARTUP_DELAY);
-		ret = adis16400_check_status(dev);
+		ret = adis16400_check_status(indio_dev);
 		if (ret) {
 			dev_err(dev, "giving up");
 			goto err_ret;
 		}
 	}
+	if (st->variant->flags & ADIS16400_HAS_PROD_ID) {
+		ret = adis16400_spi_read_reg_16(indio_dev,
+						ADIS16400_PRODUCT_ID, &prod_id);
+		if (ret)
+			goto err_ret;
 
-	ret = adis16400_spi_read_reg_16(dev, ADIS16400_PRODUCT_ID, &prod_id);
-	if (ret)
-		goto err_ret;
-
-	if ((prod_id & 0xF000) != ADIS16400_PRODUCT_ID_DEFAULT)
-		dev_warn(dev, "unknown product id");
-
-
-	dev_info(dev, ": prod_id 0x%04x at CS%d (irq %d)\n",
-			prod_id, st->us->chip_select, st->us->irq);
+		if ((prod_id & 0xF000) != st->variant->product_id)
+			dev_warn(dev, "incorrect id");
 
+		printk(KERN_INFO DRIVER_NAME ": prod_id 0x%04x at CS%d (irq %d)\n",
+		       prod_id, st->us->chip_select, st->us->irq);
+	}
 	/* use high spi speed if possible */
-	ret = adis16400_spi_read_reg_16(dev, ADIS16400_SMPL_PRD, &smp_prd);
+	ret = adis16400_spi_read_reg_16(indio_dev,
+					ADIS16400_SMPL_PRD, &smp_prd);
 	if (!ret && (smp_prd & ADIS16400_SMPL_PRD_DIV_MASK) < 0x0A) {
 		st->us->max_speed_hz = ADIS16400_SPI_SLOW;
 		spi_setup(st->us);
@@ -490,58 +420,6 @@
 	return ret;
 }
 
-#define ADIS16400_DEV_ATTR_CALIBBIAS(_channel, _reg)		\
-	IIO_DEV_ATTR_##_channel##_CALIBBIAS(S_IWUSR | S_IRUGO,	\
-			adis16400_read_12bit_signed,		\
-			adis16400_write_16bit,			\
-			_reg)
-
-static ADIS16400_DEV_ATTR_CALIBBIAS(GYRO_X, ADIS16400_XGYRO_OFF);
-static ADIS16400_DEV_ATTR_CALIBBIAS(GYRO_Y, ADIS16400_YGYRO_OFF);
-static ADIS16400_DEV_ATTR_CALIBBIAS(GYRO_Z, ADIS16400_ZGYRO_OFF);
-
-static ADIS16400_DEV_ATTR_CALIBBIAS(ACCEL_X, ADIS16400_XACCL_OFF);
-static ADIS16400_DEV_ATTR_CALIBBIAS(ACCEL_Y, ADIS16400_YACCL_OFF);
-static ADIS16400_DEV_ATTR_CALIBBIAS(ACCEL_Z, ADIS16400_ZACCL_OFF);
-
-
-static IIO_DEV_ATTR_IN_NAMED_RAW(0, supply, adis16400_read_14bit_signed,
-		ADIS16400_SUPPLY_OUT);
-static IIO_CONST_ATTR_IN_NAMED_SCALE(0, supply, "0.002418 V");
-
-static IIO_DEV_ATTR_GYRO_X(adis16400_read_14bit_signed,
-		ADIS16400_XGYRO_OUT);
-static IIO_DEV_ATTR_GYRO_Y(adis16400_read_14bit_signed,
-		ADIS16400_YGYRO_OUT);
-static IIO_DEV_ATTR_GYRO_Z(adis16400_read_14bit_signed,
-		ADIS16400_ZGYRO_OUT);
-static IIO_CONST_ATTR(gyro_scale, "0.0008726646");
-
-static IIO_DEV_ATTR_ACCEL_X(adis16400_read_14bit_signed,
-		ADIS16400_XACCL_OUT);
-static IIO_DEV_ATTR_ACCEL_Y(adis16400_read_14bit_signed,
-		ADIS16400_YACCL_OUT);
-static IIO_DEV_ATTR_ACCEL_Z(adis16400_read_14bit_signed,
-		ADIS16400_ZACCL_OUT);
-static IIO_CONST_ATTR(accel_scale, "0.0326561445");
-
-static IIO_DEV_ATTR_MAGN_X(adis16400_read_14bit_signed,
-		ADIS16400_XMAGN_OUT);
-static IIO_DEV_ATTR_MAGN_Y(adis16400_read_14bit_signed,
-		ADIS16400_YMAGN_OUT);
-static IIO_DEV_ATTR_MAGN_Z(adis16400_read_14bit_signed,
-		ADIS16400_ZMAGN_OUT);
-static IIO_CONST_ATTR(magn_scale, "0.0005 Gs");
-
-
-static IIO_DEV_ATTR_TEMP_RAW(adis16400_read_12bit_signed);
-static IIO_CONST_ATTR_TEMP_OFFSET("198.16 K");
-static IIO_CONST_ATTR_TEMP_SCALE("0.14 K");
-
-static IIO_DEV_ATTR_IN_RAW(1, adis16400_read_12bit_unsigned,
-		ADIS16400_AUX_ADC);
-static IIO_CONST_ATTR(in1_scale, "0.000806 V");
-
 static IIO_DEV_ATTR_SAMP_FREQ(S_IWUSR | S_IRUGO,
 		adis16400_read_frequency,
 		adis16400_write_frequency);
@@ -550,46 +428,273 @@
 
 static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("409 546 819 1638");
 
-static IIO_CONST_ATTR_NAME("adis16400");
+enum adis16400_chan {
+	in_supply,
+	gyro_x,
+	gyro_y,
+	gyro_z,
+	accel_x,
+	accel_y,
+	accel_z,
+	magn_x,
+	magn_y,
+	magn_z,
+	temp,
+	temp0, temp1, temp2,
+	in1
+};
 
-static struct attribute *adis16400_event_attributes[] = {
-	NULL
+static u8 adis16400_addresses[16][2] = {
+	[in_supply] = { ADIS16400_SUPPLY_OUT, 0 },
+	[gyro_x] = { ADIS16400_XGYRO_OUT, ADIS16400_XGYRO_OFF },
+	[gyro_y] = { ADIS16400_YGYRO_OUT, ADIS16400_YGYRO_OFF },
+	[gyro_z] = { ADIS16400_ZGYRO_OUT, ADIS16400_ZGYRO_OFF },
+	[accel_x] = { ADIS16400_XACCL_OUT, ADIS16400_XACCL_OFF },
+	[accel_y] = { ADIS16400_YACCL_OUT, ADIS16400_YACCL_OFF },
+	[accel_z] = { ADIS16400_ZACCL_OUT, ADIS16400_ZACCL_OFF },
+	[magn_x] = { ADIS16400_XMAGN_OUT, 0 },
+	[magn_y] = { ADIS16400_YMAGN_OUT, 0 },
+	[magn_z] = { ADIS16400_ZMAGN_OUT, 0 },
+	[temp] = { ADIS16400_TEMP_OUT, 0 },
+	[temp0] = { ADIS16350_XTEMP_OUT },
+	[temp1] = { ADIS16350_YTEMP_OUT },
+	[temp2] = { ADIS16350_ZTEMP_OUT },
+	[in1] = { ADIS16400_AUX_ADC , 0 },
 };
 
-static struct attribute_group adis16400_event_attribute_group = {
-	.attrs = adis16400_event_attributes,
+static int adis16400_write_raw(struct iio_dev *indio_dev,
+			       struct iio_chan_spec const *chan,
+			       int val,
+			       int val2,
+			       long mask)
+{
+	int ret;
+	switch (mask) {
+	case (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE):
+		mutex_lock(&indio_dev->mlock);
+		ret = adis16400_spi_write_reg_16(indio_dev,
+				adis16400_addresses[chan->address][1],
+				val);
+		mutex_unlock(&indio_dev->mlock);
+		return ret;
+	default:
+		return -EINVAL;
+	}
+}
+
+static int adis16400_read_raw(struct iio_dev *indio_dev,
+			      struct iio_chan_spec const *chan,
+			      int *val,
+			      int *val2,
+			      long mask)
+{
+	struct adis16400_state *st = iio_priv(indio_dev);
+	int ret;
+	s16 val16;
+	int shift;
+
+	switch (mask) {
+	case 0:
+		mutex_lock(&indio_dev->mlock);
+		ret = adis16400_spi_read_reg_16(indio_dev,
+				adis16400_addresses[chan->address][0],
+				&val16);
+		if (ret) {
+			mutex_unlock(&indio_dev->mlock);
+			return ret;
+		}
+		val16 &= (1 << chan->scan_type.realbits) - 1;
+		if (chan->scan_type.sign == 's') {
+			shift = 16 - chan->scan_type.realbits;
+			val16 = (s16)(val16 << shift) >> shift;
+		}
+		*val = val16;
+		mutex_unlock(&indio_dev->mlock);
+		return IIO_VAL_INT;
+	case (1 << IIO_CHAN_INFO_SCALE_SHARED):
+	case (1 << IIO_CHAN_INFO_SCALE_SEPARATE):
+		switch (chan->type) {
+		case IIO_GYRO:
+			*val = 0;
+			*val2 = st->variant->gyro_scale_micro;
+			return IIO_VAL_INT_PLUS_MICRO;
+		case IIO_IN:
+			*val = 0;
+			if (chan->channel == 0)
+				*val2 = 2418;
+			else
+				*val2 = 806;
+			return IIO_VAL_INT_PLUS_MICRO;
+		case IIO_ACCEL:
+			*val = 0;
+			*val2 = st->variant->accel_scale_micro;
+			return IIO_VAL_INT_PLUS_MICRO;
+		case IIO_MAGN:
+			*val = 0;
+			*val2 = 500;
+			return IIO_VAL_INT_PLUS_MICRO;
+		case IIO_TEMP:
+			*val = 0;
+			*val2 = 140000;
+			return IIO_VAL_INT_PLUS_MICRO;
+		default:
+			return -EINVAL;
+		}
+	case (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE):
+		mutex_lock(&indio_dev->mlock);
+		ret = adis16400_spi_read_reg_16(indio_dev,
+				adis16400_addresses[chan->address][1],
+				&val16);
+		mutex_unlock(&indio_dev->mlock);
+		if (ret)
+			return ret;
+		val16 = ((val16 & 0xFFF) << 4) >> 4;
+		*val = val16;
+		return IIO_VAL_INT;
+	case (1 << IIO_CHAN_INFO_OFFSET_SEPARATE):
+		/* currently only temperature */
+		*val = 198;
+		*val2 = 160000;
+		return IIO_VAL_INT_PLUS_MICRO;
+	default:
+		return -EINVAL;
+	}
+}
+
+static struct iio_chan_spec adis16400_channels[] = {
+	IIO_CHAN(IIO_IN, 0, 1, 0, "supply", 0, 0,
+		 (1 << IIO_CHAN_INFO_SCALE_SEPARATE),
+		 in_supply, ADIS16400_SCAN_SUPPLY,
+		 IIO_ST('u', 14, 16, 0), 0),
+	IIO_CHAN(IIO_GYRO, 1, 0, 0, NULL, 0, IIO_MOD_X,
+		 (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE) |
+		 (1 << IIO_CHAN_INFO_SCALE_SHARED),
+		 gyro_x, ADIS16400_SCAN_GYRO_X, IIO_ST('s', 14, 16, 0), 0),
+	IIO_CHAN(IIO_GYRO, 1, 0, 0, NULL, 0, IIO_MOD_Y,
+		 (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE) |
+		 (1 << IIO_CHAN_INFO_SCALE_SHARED),
+		 gyro_y, ADIS16400_SCAN_GYRO_Y, IIO_ST('s', 14, 16, 0), 0),
+	IIO_CHAN(IIO_GYRO, 1, 0, 0, NULL, 0, IIO_MOD_Z,
+		 (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE) |
+		 (1 << IIO_CHAN_INFO_SCALE_SHARED),
+		 gyro_z, ADIS16400_SCAN_GYRO_Z, IIO_ST('s', 14, 16, 0), 0),
+	IIO_CHAN(IIO_ACCEL, 1, 0, 0, NULL, 0, IIO_MOD_X,
+		 (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE) |
+		 (1 << IIO_CHAN_INFO_SCALE_SHARED),
+		 accel_x, ADIS16400_SCAN_ACC_X, IIO_ST('s', 14, 16, 0), 0),
+	IIO_CHAN(IIO_ACCEL, 1, 0, 0, NULL, 0, IIO_MOD_Y,
+		 (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE) |
+		 (1 << IIO_CHAN_INFO_SCALE_SHARED),
+		 accel_y, ADIS16400_SCAN_ACC_Y, IIO_ST('s', 14, 16, 0), 0),
+	IIO_CHAN(IIO_ACCEL, 1, 0, 0, NULL, 0, IIO_MOD_Z,
+		 (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE) |
+		 (1 << IIO_CHAN_INFO_SCALE_SHARED),
+		 accel_z, ADIS16400_SCAN_ACC_Z, IIO_ST('s', 14, 16, 0), 0),
+	IIO_CHAN(IIO_MAGN, 1, 0, 0, NULL, 0, IIO_MOD_X,
+		 (1 << IIO_CHAN_INFO_SCALE_SHARED),
+		 magn_x, ADIS16400_SCAN_MAGN_X, IIO_ST('s', 14, 16, 0), 0),
+	IIO_CHAN(IIO_MAGN, 1, 0, 0, NULL, 0, IIO_MOD_Y,
+		 (1 << IIO_CHAN_INFO_SCALE_SHARED),
+		 magn_y, ADIS16400_SCAN_MAGN_Y, IIO_ST('s', 14, 16, 0), 0),
+	IIO_CHAN(IIO_MAGN, 1, 0, 0, NULL, 0, IIO_MOD_Z,
+		 (1 << IIO_CHAN_INFO_SCALE_SHARED),
+		 magn_z, ADIS16400_SCAN_MAGN_Z, IIO_ST('s', 14, 16, 0), 0),
+	IIO_CHAN(IIO_TEMP, 0, 1, 0, NULL, 0, 0,
+		 (1 << IIO_CHAN_INFO_OFFSET_SEPARATE) |
+		 (1 << IIO_CHAN_INFO_SCALE_SEPARATE),
+		 temp, ADIS16400_SCAN_TEMP, IIO_ST('s', 12, 16, 0), 0),
+	IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 1, 0,
+		 (1 << IIO_CHAN_INFO_SCALE_SEPARATE),
+		 in1, ADIS16400_SCAN_ADC_0, IIO_ST('s', 12, 16, 0), 0),
+	IIO_CHAN_SOFT_TIMESTAMP(12)
+};
+
+static struct iio_chan_spec adis16350_channels[] = {
+	IIO_CHAN(IIO_IN, 0, 1, 0, "supply", 0, 0,
+		 (1 << IIO_CHAN_INFO_SCALE_SEPARATE),
+		 0, ADIS16400_SCAN_SUPPLY, IIO_ST('u', 12, 16, 0), 0),
+	IIO_CHAN(IIO_GYRO, 1, 0, 0, NULL, 0, IIO_MOD_X,
+		 (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE) |
+		 (1 << IIO_CHAN_INFO_SCALE_SHARED),
+		 1, ADIS16400_SCAN_GYRO_X, IIO_ST('s', 14, 16, 0), 0),
+	IIO_CHAN(IIO_GYRO, 1, 0, 0, NULL, 0, IIO_MOD_Y,
+		 (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE) |
+		 (1 << IIO_CHAN_INFO_SCALE_SHARED),
+		 2, ADIS16400_SCAN_GYRO_Y, IIO_ST('s', 14, 16, 0), 0),
+	IIO_CHAN(IIO_GYRO, 1, 0, 0, NULL, 0, IIO_MOD_Z,
+		 (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE) |
+		 (1 << IIO_CHAN_INFO_SCALE_SHARED),
+		 3, ADIS16400_SCAN_GYRO_Z, IIO_ST('s', 14, 16, 0), 0),
+	IIO_CHAN(IIO_ACCEL, 1, 0, 0, NULL, 0, IIO_MOD_X,
+		 (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE) |
+		 (1 << IIO_CHAN_INFO_SCALE_SHARED),
+		 4, ADIS16400_SCAN_ACC_X, IIO_ST('s', 14, 16, 0), 0),
+	IIO_CHAN(IIO_ACCEL, 1, 0, 0, NULL, 0, IIO_MOD_Y,
+		 (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE) |
+		 (1 << IIO_CHAN_INFO_SCALE_SHARED),
+		 0, ADIS16400_SCAN_ACC_Y, IIO_ST('s', 14, 16, 0), 0),
+	IIO_CHAN(IIO_ACCEL, 1, 0, 0, NULL, 0, IIO_MOD_Z,
+		 (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE) |
+		 (1 << IIO_CHAN_INFO_SCALE_SHARED),
+		 0, ADIS16400_SCAN_ACC_Z, IIO_ST('s', 14, 16, 0), 0),
+	IIO_CHAN(IIO_TEMP, 0, 1, 0, "x", 0, 0,
+		 (1 << IIO_CHAN_INFO_OFFSET_SEPARATE) |
+		 (1 << IIO_CHAN_INFO_SCALE_SEPARATE),
+		 0, ADIS16350_SCAN_TEMP_X, IIO_ST('s', 12, 16, 0), 0),
+	IIO_CHAN(IIO_TEMP, 0, 1, 0, "y", 1, 0,
+		 (1 << IIO_CHAN_INFO_OFFSET_SEPARATE) |
+		 (1 << IIO_CHAN_INFO_SCALE_SEPARATE),
+		 0, ADIS16350_SCAN_TEMP_Y, IIO_ST('s', 12, 16, 0), 0),
+	IIO_CHAN(IIO_TEMP, 0, 1, 0, "z", 2, 0,
+		 (1 << IIO_CHAN_INFO_OFFSET_SEPARATE) |
+		 (1 << IIO_CHAN_INFO_SCALE_SEPARATE),
+		 0, ADIS16350_SCAN_TEMP_Z, IIO_ST('s', 12, 16, 0), 0),
+	IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 1, 0,
+		 (1 << IIO_CHAN_INFO_SCALE_SEPARATE),
+		 0, ADIS16350_SCAN_ADC_0, IIO_ST('s', 12, 16, 0), 0),
+	IIO_CHAN_SOFT_TIMESTAMP(11)
+};
+
+static struct iio_chan_spec adis16300_channels[] = {
+	IIO_CHAN(IIO_IN, 0, 1, 0, "supply", 0, 0,
+		 (1 << IIO_CHAN_INFO_SCALE_SEPARATE),
+		 0, ADIS16400_SCAN_SUPPLY, IIO_ST('u', 12, 16, 0), 0),
+	IIO_CHAN(IIO_GYRO, 1, 0, 0, NULL, 0, IIO_MOD_X,
+		 (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE) |
+		 (1 << IIO_CHAN_INFO_SCALE_SHARED),
+		 1, ADIS16400_SCAN_GYRO_X, IIO_ST('s', 14, 16, 0), 0),
+	IIO_CHAN(IIO_ACCEL, 1, 0, 0, NULL, 0, IIO_MOD_X,
+		 (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE) |
+		 (1 << IIO_CHAN_INFO_SCALE_SHARED),
+		 4, ADIS16400_SCAN_ACC_X, IIO_ST('s', 14, 16, 0), 0),
+	IIO_CHAN(IIO_ACCEL, 1, 0, 0, NULL, 0, IIO_MOD_Y,
+		 (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE) |
+		 (1 << IIO_CHAN_INFO_SCALE_SHARED),
+		 0, ADIS16400_SCAN_ACC_Y, IIO_ST('s', 14, 16, 0), 0),
+	IIO_CHAN(IIO_ACCEL, 1, 0, 0, NULL, 0, IIO_MOD_Z,
+		 (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE) |
+		 (1 << IIO_CHAN_INFO_SCALE_SHARED),
+		 0, ADIS16400_SCAN_ACC_Z, IIO_ST('s', 14, 16, 0), 0),
+	IIO_CHAN(IIO_TEMP, 0, 1, 0, NULL, 0, 0,
+		 (1 << IIO_CHAN_INFO_OFFSET_SEPARATE) |
+		 (1 << IIO_CHAN_INFO_SCALE_SEPARATE),
+		 0, ADIS16400_SCAN_TEMP, IIO_ST('s', 12, 16, 0), 0),
+	IIO_CHAN(IIO_IN, 0, 1, 0, NULL, 1, 0,
+		 (1 << IIO_CHAN_INFO_SCALE_SEPARATE),
+		 0, ADIS16350_SCAN_ADC_0, IIO_ST('s', 12, 16, 0), 0),
+	IIO_CHAN(IIO_INCLI, 1, 0, 0, NULL, 0, IIO_MOD_X,
+		 (1 << IIO_CHAN_INFO_SCALE_SHARED),
+		 0, ADIS16300_SCAN_INCLI_X, IIO_ST('s', 13, 16, 0), 0),
+	IIO_CHAN(IIO_INCLI, 1, 0, 0, NULL, 0, IIO_MOD_Y,
+		 (1 << IIO_CHAN_INFO_SCALE_SHARED),
+		 0, ADIS16300_SCAN_INCLI_Y, IIO_ST('s', 13, 16, 0), 0),
+	IIO_CHAN_SOFT_TIMESTAMP(14)
 };
 
 static struct attribute *adis16400_attributes[] = {
-	&iio_dev_attr_gyro_x_calibbias.dev_attr.attr,
-	&iio_dev_attr_gyro_y_calibbias.dev_attr.attr,
-	&iio_dev_attr_gyro_z_calibbias.dev_attr.attr,
-	&iio_dev_attr_accel_x_calibbias.dev_attr.attr,
-	&iio_dev_attr_accel_y_calibbias.dev_attr.attr,
-	&iio_dev_attr_accel_z_calibbias.dev_attr.attr,
-	&iio_dev_attr_in0_supply_raw.dev_attr.attr,
-	&iio_const_attr_in0_supply_scale.dev_attr.attr,
-	&iio_dev_attr_gyro_x_raw.dev_attr.attr,
-	&iio_dev_attr_gyro_y_raw.dev_attr.attr,
-	&iio_dev_attr_gyro_z_raw.dev_attr.attr,
-	&iio_const_attr_gyro_scale.dev_attr.attr,
-	&iio_dev_attr_accel_x_raw.dev_attr.attr,
-	&iio_dev_attr_accel_y_raw.dev_attr.attr,
-	&iio_dev_attr_accel_z_raw.dev_attr.attr,
-	&iio_const_attr_accel_scale.dev_attr.attr,
-	&iio_dev_attr_magn_x_raw.dev_attr.attr,
-	&iio_dev_attr_magn_y_raw.dev_attr.attr,
-	&iio_dev_attr_magn_z_raw.dev_attr.attr,
-	&iio_const_attr_magn_scale.dev_attr.attr,
-	&iio_dev_attr_temp_raw.dev_attr.attr,
-	&iio_const_attr_temp_offset.dev_attr.attr,
-	&iio_const_attr_temp_scale.dev_attr.attr,
-	&iio_dev_attr_in1_raw.dev_attr.attr,
-	&iio_const_attr_in1_scale.dev_attr.attr,
 	&iio_dev_attr_sampling_frequency.dev_attr.attr,
 	&iio_const_attr_sampling_frequency_available.dev_attr.attr,
 	&iio_dev_attr_reset.dev_attr.attr,
-	&iio_const_attr_name.dev_attr.attr,
 	NULL
 };
 
@@ -597,101 +702,147 @@
 	.attrs = adis16400_attributes,
 };
 
+static struct adis16400_chip_info adis16400_chips[] = {
+	[ADIS16300] = {
+		.channels = adis16300_channels,
+		.num_channels = ARRAY_SIZE(adis16300_channels),
+		.gyro_scale_micro = 873,
+		.accel_scale_micro = 5884,
+		.default_scan_mask = (1 << ADIS16400_SCAN_SUPPLY) |
+		(1 << ADIS16400_SCAN_GYRO_X) | (1 << ADIS16400_SCAN_ACC_X) |
+		(1 << ADIS16400_SCAN_ACC_Y) | (1 << ADIS16400_SCAN_ACC_Z) |
+		(1 << ADIS16400_SCAN_TEMP) | (1 << ADIS16400_SCAN_ADC_0) |
+		(1 << ADIS16300_SCAN_INCLI_X) | (1 << ADIS16300_SCAN_INCLI_Y) |
+		(1 << 14),
+	},
+	[ADIS16350] = {
+		.channels = adis16350_channels,
+		.num_channels = ARRAY_SIZE(adis16350_channels),
+		.gyro_scale_micro = 872664,
+		.accel_scale_micro = 24732,
+		.default_scan_mask = 0x7FF,
+		.flags = ADIS16400_NO_BURST,
+	},
+	[ADIS16360] = {
+		.channels = adis16350_channels,
+		.num_channels = ARRAY_SIZE(adis16350_channels),
+		.flags = ADIS16400_HAS_PROD_ID,
+		.product_id = 0x3FE8,
+		.gyro_scale_micro = 1279,
+		.accel_scale_micro = 24732,
+		.default_scan_mask = 0x7FF,
+	},
+	[ADIS16362] = {
+		.channels = adis16350_channels,
+		.num_channels = ARRAY_SIZE(adis16350_channels),
+		.flags = ADIS16400_HAS_PROD_ID,
+		.product_id = 0x3FEA,
+		.gyro_scale_micro = 1279,
+		.accel_scale_micro = 24732,
+		.default_scan_mask = 0x7FF,
+	},
+	[ADIS16364] = {
+		.channels = adis16350_channels,
+		.num_channels = ARRAY_SIZE(adis16350_channels),
+		.flags = ADIS16400_HAS_PROD_ID,
+		.product_id = 0x3FEC,
+		.gyro_scale_micro = 1279,
+		.accel_scale_micro = 24732,
+		.default_scan_mask = 0x7FF,
+	},
+	[ADIS16365] = {
+		.channels = adis16350_channels,
+		.num_channels = ARRAY_SIZE(adis16350_channels),
+		.flags = ADIS16400_HAS_PROD_ID,
+		.product_id = 0x3FED,
+		.gyro_scale_micro = 1279,
+		.accel_scale_micro = 24732,
+		.default_scan_mask = 0x7FF,
+	},
+	[ADIS16400] = {
+		.channels = adis16400_channels,
+		.num_channels = ARRAY_SIZE(adis16400_channels),
+		.flags = ADIS16400_HAS_PROD_ID,
+		.product_id = 0x4015,
+		.gyro_scale_micro = 873,
+		.accel_scale_micro = 32656,
+		.default_scan_mask = 0xFFF,
+	}
+};
+
+static const struct iio_info adis16400_info = {
+	.driver_module = THIS_MODULE,
+	.read_raw = &adis16400_read_raw,
+	.write_raw = &adis16400_write_raw,
+	.attrs = &adis16400_attribute_group,
+};
+
 static int __devinit adis16400_probe(struct spi_device *spi)
 {
 	int ret, regdone = 0;
-	struct adis16400_state *st = kzalloc(sizeof *st, GFP_KERNEL);
-	if (!st) {
+	struct adis16400_state *st;
+	struct iio_dev *indio_dev = iio_allocate_device(sizeof(*st));
+	if (indio_dev == NULL) {
 		ret =  -ENOMEM;
 		goto error_ret;
 	}
+	st = iio_priv(indio_dev);
 	/* this is only used for removal purposes */
-	spi_set_drvdata(spi, st);
+	spi_set_drvdata(spi, indio_dev);
 
-	/* Allocate the comms buffers */
-	st->rx = kzalloc(sizeof(*st->rx)*ADIS16400_MAX_RX, GFP_KERNEL);
-	if (st->rx == NULL) {
-		ret = -ENOMEM;
-		goto error_free_st;
-	}
-	st->tx = kzalloc(sizeof(*st->tx)*ADIS16400_MAX_TX, GFP_KERNEL);
-	if (st->tx == NULL) {
-		ret = -ENOMEM;
-		goto error_free_rx;
-	}
 	st->us = spi;
 	mutex_init(&st->buf_lock);
-	/* setup the industrialio driver allocated elements */
-	st->indio_dev = iio_allocate_device();
-	if (st->indio_dev == NULL) {
-		ret = -ENOMEM;
-		goto error_free_tx;
-	}
 
-	st->indio_dev->dev.parent = &spi->dev;
-	st->indio_dev->num_interrupt_lines = 1;
-	st->indio_dev->event_attrs = &adis16400_event_attribute_group;
-	st->indio_dev->attrs = &adis16400_attribute_group;
-	st->indio_dev->dev_data = (void *)(st);
-	st->indio_dev->driver_module = THIS_MODULE;
-	st->indio_dev->modes = INDIO_DIRECT_MODE;
+	/* setup the industrialio driver allocated elements */
+	st->variant = &adis16400_chips[spi_get_device_id(spi)->driver_data];
+	indio_dev->dev.parent = &spi->dev;
+	indio_dev->name = spi_get_device_id(spi)->name;
+	indio_dev->channels = st->variant->channels;
+	indio_dev->num_channels = st->variant->num_channels;
+	indio_dev->info = &adis16400_info;
+	indio_dev->modes = INDIO_DIRECT_MODE;
 
-	ret = adis16400_configure_ring(st->indio_dev);
+	ret = adis16400_configure_ring(indio_dev);
 	if (ret)
 		goto error_free_dev;
 
-	ret = iio_device_register(st->indio_dev);
+	ret = iio_device_register(indio_dev);
 	if (ret)
 		goto error_unreg_ring_funcs;
 	regdone = 1;
 
-	ret = iio_ring_buffer_register(st->indio_dev->ring, 0);
+	ret = iio_ring_buffer_register_ex(indio_dev->ring, 0,
+					  st->variant->channels,
+					  st->variant->num_channels);
 	if (ret) {
 		dev_err(&spi->dev, "failed to initialize the ring\n");
 		goto error_unreg_ring_funcs;
 	}
 
 	if (spi->irq && gpio_is_valid(irq_to_gpio(spi->irq)) > 0) {
-		ret = iio_register_interrupt_line(spi->irq,
-				st->indio_dev,
-				0,
-				IRQF_TRIGGER_RISING,
-				"adis16400");
+		ret = adis16400_probe_trigger(indio_dev);
 		if (ret)
 			goto error_uninitialize_ring;
-
-		ret = adis16400_probe_trigger(st->indio_dev);
-		if (ret)
-			goto error_unregister_line;
 	}
 
 	/* Get the device into a sane initial state */
-	ret = adis16400_initial_setup(st);
+	ret = adis16400_initial_setup(indio_dev);
 	if (ret)
 		goto error_remove_trigger;
 	return 0;
 
 error_remove_trigger:
-	if (st->indio_dev->modes & INDIO_RING_TRIGGERED)
-		adis16400_remove_trigger(st->indio_dev);
-error_unregister_line:
-	if (st->indio_dev->modes & INDIO_RING_TRIGGERED)
-		iio_unregister_interrupt_line(st->indio_dev, 0);
+	if (indio_dev->modes & INDIO_RING_TRIGGERED)
+		adis16400_remove_trigger(indio_dev);
 error_uninitialize_ring:
-	iio_ring_buffer_unregister(st->indio_dev->ring);
+	iio_ring_buffer_unregister(indio_dev->ring);
 error_unreg_ring_funcs:
-	adis16400_unconfigure_ring(st->indio_dev);
+	adis16400_unconfigure_ring(indio_dev);
 error_free_dev:
 	if (regdone)
-		iio_device_unregister(st->indio_dev);
+		iio_device_unregister(indio_dev);
 	else
-		iio_free_device(st->indio_dev);
-error_free_tx:
-	kfree(st->tx);
-error_free_rx:
-	kfree(st->rx);
-error_free_st:
-	kfree(st);
+		iio_free_device(indio_dev);
 error_ret:
 	return ret;
 }
@@ -700,25 +851,16 @@
 static int adis16400_remove(struct spi_device *spi)
 {
 	int ret;
-	struct adis16400_state *st = spi_get_drvdata(spi);
-	struct iio_dev *indio_dev = st->indio_dev;
+	struct iio_dev *indio_dev =  spi_get_drvdata(spi);
 
-	ret = adis16400_stop_device(&(indio_dev->dev));
+	ret = adis16400_stop_device(indio_dev);
 	if (ret)
 		goto err_ret;
 
-	flush_scheduled_work();
-
 	adis16400_remove_trigger(indio_dev);
-	if (spi->irq && gpio_is_valid(irq_to_gpio(spi->irq)) > 0)
-		iio_unregister_interrupt_line(indio_dev, 0);
-
-	iio_ring_buffer_unregister(st->indio_dev->ring);
+	iio_ring_buffer_unregister(indio_dev->ring);
 	adis16400_unconfigure_ring(indio_dev);
 	iio_device_unregister(indio_dev);
-	kfree(st->tx);
-	kfree(st->rx);
-	kfree(st);
 
 	return 0;
 
@@ -726,11 +868,26 @@
 	return ret;
 }
 
+static const struct spi_device_id adis16400_id[] = {
+	{"adis16300", ADIS16300},
+	{"adis16350", ADIS16350},
+	{"adis16354", ADIS16350},
+	{"adis16355", ADIS16350},
+	{"adis16360", ADIS16360},
+	{"adis16362", ADIS16362},
+	{"adis16364", ADIS16364},
+	{"adis16365", ADIS16365},
+	{"adis16400", ADIS16400},
+	{"adis16405", ADIS16400},
+	{}
+};
+
 static struct spi_driver adis16400_driver = {
 	.driver = {
 		.name = "adis16400",
 		.owner = THIS_MODULE,
 	},
+	.id_table = adis16400_id,
 	.probe = adis16400_probe,
 	.remove = __devexit_p(adis16400_remove),
 };
diff -druN linux-2.6.39-libre/drivers/staging/iio/imu/adis16400.h linux-3.0-rc7-libre/drivers/staging/iio/imu/adis16400.h
--- linux-2.6.39-libre/drivers/staging/iio/imu/adis16400.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/iio/imu/adis16400.h	2011-07-11 19:51:52.000000000 -0400
@@ -37,6 +37,10 @@
 #define ADIS16400_TEMP_OUT  0x16 /* Temperature output */
 #define ADIS16400_AUX_ADC   0x18 /* Auxiliary ADC measurement */
 
+#define ADIS16350_XTEMP_OUT 0x10 /* X-axis gyroscope temperature measurement */
+#define ADIS16350_YTEMP_OUT 0x12 /* Y-axis gyroscope temperature measurement */
+#define ADIS16350_ZTEMP_OUT 0x14 /* Z-axis gyroscope temperature measurement */
+
 /* Calibration parameters */
 #define ADIS16400_XGYRO_OFF 0x1A /* X-axis gyroscope bias offset factor */
 #define ADIS16400_YGYRO_OFF 0x1C /* Y-axis gyroscope bias offset factor */
@@ -68,7 +72,6 @@
 #define ADIS16400_AUX_DAC   0x4A /* Auxiliary DAC data */
 
 #define ADIS16400_PRODUCT_ID 0x56 /* Product identifier */
-#define ADIS16400_PRODUCT_ID_DEFAULT 0x4015	/* Datasheet says 0x4105, I get 0x4015 */
 
 #define ADIS16400_ERROR_ACTIVE			(1<<14)
 #define ADIS16400_NEW_DATA			(1<<14)
@@ -123,13 +126,21 @@
 #define ADIS16400_SPI_BURST	(u32)(1000 * 1000)
 #define ADIS16400_SPI_FAST	(u32)(2000 * 1000)
 
+#define ADIS16400_HAS_PROD_ID 1
+#define ADIS16400_NO_BURST 2
+struct adis16400_chip_info {
+	const struct iio_chan_spec *channels;
+	const int num_channels;
+	const int product_id;
+	const long flags;
+	unsigned int gyro_scale_micro;
+	unsigned int accel_scale_micro;
+	unsigned long default_scan_mask;
+};
+
 /**
  * struct adis16400_state - device instance specific data
  * @us:			actual spi_device
- * @work_trigger_to_ring: bh for triggered event handling
- * @inter:		used to check if new interrupt has been triggered
- * @last_timestamp:	passing timestamp from th to bh of interrupt handler
- * @indio_dev:		industrial I/O device structure
  * @trig:		data ready trigger registered with iio
  * @tx:			transmit buffer
  * @rx:			receive buffer
@@ -137,18 +148,16 @@
  **/
 struct adis16400_state {
 	struct spi_device		*us;
-	struct work_struct		work_trigger_to_ring;
-	s64				last_timestamp;
-	struct iio_dev			*indio_dev;
 	struct iio_trigger		*trig;
-	u8				*tx;
-	u8				*rx;
 	struct mutex			buf_lock;
+	struct adis16400_chip_info	*variant;
+
+	u8	tx[ADIS16400_MAX_TX] ____cacheline_aligned;
+	u8	rx[ADIS16400_MAX_RX] ____cacheline_aligned;
 };
 
-int adis16400_set_irq(struct device *dev, bool enable);
+int adis16400_set_irq(struct iio_dev *indio_dev, bool enable);
 
-#ifdef CONFIG_IIO_RING_BUFFER
 /* At the moment triggers are only used for ring buffer
  * filling. This may change!
  */
@@ -161,11 +170,18 @@
 #define ADIS16400_SCAN_ACC_Y	5
 #define ADIS16400_SCAN_ACC_Z	6
 #define ADIS16400_SCAN_MAGN_X	7
+#define ADIS16350_SCAN_TEMP_X	7
 #define ADIS16400_SCAN_MAGN_Y	8
+#define ADIS16350_SCAN_TEMP_Y	8
 #define ADIS16400_SCAN_MAGN_Z	9
+#define ADIS16350_SCAN_TEMP_Z	9
 #define ADIS16400_SCAN_TEMP	10
+#define ADIS16350_SCAN_ADC_0	10
 #define ADIS16400_SCAN_ADC_0	11
+#define ADIS16300_SCAN_INCLI_X	12
+#define ADIS16300_SCAN_INCLI_Y	13
 
+#ifdef CONFIG_IIO_RING_BUFFER
 void adis16400_remove_trigger(struct iio_dev *indio_dev);
 int adis16400_probe_trigger(struct iio_dev *indio_dev);
 
diff -druN linux-2.6.39-libre/drivers/staging/iio/imu/adis16400_ring.c linux-3.0-rc7-libre/drivers/staging/iio/imu/adis16400_ring.c
--- linux-2.6.39-libre/drivers/staging/iio/imu/adis16400_ring.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/iio/imu/adis16400_ring.c	2011-07-11 19:51:52.000000000 -0400
@@ -9,6 +9,7 @@
 #include <linux/slab.h>
 #include <linux/sysfs.h>
 #include <linux/list.h>
+#include <linux/bitops.h>
 
 #include "../iio.h"
 #include "../sysfs.h"
@@ -17,93 +18,6 @@
 #include "../trigger.h"
 #include "adis16400.h"
 
-static IIO_SCAN_EL_C(in0_supply, ADIS16400_SCAN_SUPPLY,
-		     ADIS16400_SUPPLY_OUT, NULL);
-static IIO_CONST_ATTR_SCAN_EL_TYPE(in0_supply, u, 14, 16);
-
-static IIO_SCAN_EL_C(gyro_x, ADIS16400_SCAN_GYRO_X, ADIS16400_XGYRO_OUT, NULL);
-static IIO_SCAN_EL_C(gyro_y, ADIS16400_SCAN_GYRO_Y, ADIS16400_YGYRO_OUT, NULL);
-static IIO_SCAN_EL_C(gyro_z, ADIS16400_SCAN_GYRO_Z, ADIS16400_ZGYRO_OUT, NULL);
-static IIO_CONST_ATTR_SCAN_EL_TYPE(gyro, s, 14, 16);
-
-static IIO_SCAN_EL_C(accel_x, ADIS16400_SCAN_ACC_X, ADIS16400_XACCL_OUT, NULL);
-static IIO_SCAN_EL_C(accel_y, ADIS16400_SCAN_ACC_Y, ADIS16400_YACCL_OUT, NULL);
-static IIO_SCAN_EL_C(accel_z, ADIS16400_SCAN_ACC_Z, ADIS16400_ZACCL_OUT, NULL);
-static IIO_CONST_ATTR_SCAN_EL_TYPE(accel, s, 14, 16);
-
-static IIO_SCAN_EL_C(magn_x, ADIS16400_SCAN_MAGN_X, ADIS16400_XMAGN_OUT, NULL);
-static IIO_SCAN_EL_C(magn_y, ADIS16400_SCAN_MAGN_Y, ADIS16400_YMAGN_OUT, NULL);
-static IIO_SCAN_EL_C(magn_z, ADIS16400_SCAN_MAGN_Z, ADIS16400_ZMAGN_OUT, NULL);
-static IIO_CONST_ATTR_SCAN_EL_TYPE(magn, s, 14, 16);
-
-static IIO_SCAN_EL_C(temp, ADIS16400_SCAN_TEMP, ADIS16400_TEMP_OUT, NULL);
-static IIO_CONST_ATTR_SCAN_EL_TYPE(temp, s, 12, 16);
-
-static IIO_SCAN_EL_C(in1, ADIS16400_SCAN_ADC_0, ADIS16400_AUX_ADC, NULL);
-static IIO_CONST_ATTR_SCAN_EL_TYPE(in1, u, 12, 16);
-
-static IIO_SCAN_EL_TIMESTAMP(12);
-static IIO_CONST_ATTR_SCAN_EL_TYPE(timestamp, s, 64, 64);
-
-static struct attribute *adis16400_scan_el_attrs[] = {
-	&iio_scan_el_in0_supply.dev_attr.attr,
-	&iio_const_attr_in0_supply_index.dev_attr.attr,
-	&iio_const_attr_in0_supply_type.dev_attr.attr,
-	&iio_scan_el_gyro_x.dev_attr.attr,
-	&iio_const_attr_gyro_x_index.dev_attr.attr,
-	&iio_scan_el_gyro_y.dev_attr.attr,
-	&iio_const_attr_gyro_y_index.dev_attr.attr,
-	&iio_scan_el_gyro_z.dev_attr.attr,
-	&iio_const_attr_gyro_z_index.dev_attr.attr,
-	&iio_const_attr_gyro_type.dev_attr.attr,
-	&iio_scan_el_accel_x.dev_attr.attr,
-	&iio_const_attr_accel_x_index.dev_attr.attr,
-	&iio_scan_el_accel_y.dev_attr.attr,
-	&iio_const_attr_accel_y_index.dev_attr.attr,
-	&iio_scan_el_accel_z.dev_attr.attr,
-	&iio_const_attr_accel_z_index.dev_attr.attr,
-	&iio_const_attr_accel_type.dev_attr.attr,
-	&iio_scan_el_magn_x.dev_attr.attr,
-	&iio_const_attr_magn_x_index.dev_attr.attr,
-	&iio_scan_el_magn_y.dev_attr.attr,
-	&iio_const_attr_magn_y_index.dev_attr.attr,
-	&iio_scan_el_magn_z.dev_attr.attr,
-	&iio_const_attr_magn_z_index.dev_attr.attr,
-	&iio_const_attr_magn_type.dev_attr.attr,
-	&iio_scan_el_temp.dev_attr.attr,
-	&iio_const_attr_temp_index.dev_attr.attr,
-	&iio_const_attr_temp_type.dev_attr.attr,
-	&iio_scan_el_in1.dev_attr.attr,
-	&iio_const_attr_in1_index.dev_attr.attr,
-	&iio_const_attr_in1_type.dev_attr.attr,
-	&iio_scan_el_timestamp.dev_attr.attr,
-	&iio_const_attr_timestamp_index.dev_attr.attr,
-	&iio_const_attr_timestamp_type.dev_attr.attr,
-	NULL,
-};
-
-static struct attribute_group adis16400_scan_el_group = {
-	.attrs = adis16400_scan_el_attrs,
-	.name = "scan_elements",
-};
-
-/**
- * adis16400_poll_func_th() top half interrupt handler called by trigger
- * @private_data:	iio_dev
- **/
-static void adis16400_poll_func_th(struct iio_dev *indio_dev, s64 time)
-{
-	struct adis16400_state *st = iio_dev_get_devdata(indio_dev);
-	st->last_timestamp = time;
-	schedule_work(&st->work_trigger_to_ring);
-	/* Indicate that this interrupt is being handled */
-
-	/* Technically this is trigger related, but without this
-	 * handler running there is currently no way for the interrupt
-	 * to clear.
-	 */
-}
-
 /**
  * adis16400_spi_read_burst() - read all data registers
  * @dev: device associated with child of actual device (iio_dev or iio_trig)
@@ -113,7 +27,7 @@
 {
 	struct spi_message msg;
 	struct iio_dev *indio_dev = dev_get_drvdata(dev);
-	struct adis16400_state *st = iio_dev_get_devdata(indio_dev);
+	struct adis16400_state *st = iio_priv(indio_dev);
 	u32 old_speed_hz = st->us->max_speed_hz;
 	int ret;
 
@@ -150,62 +64,126 @@
 	return ret;
 }
 
+static const u16 read_all_tx_array[] = {
+	cpu_to_be16(ADIS16400_READ_REG(ADIS16400_SUPPLY_OUT)),
+	cpu_to_be16(ADIS16400_READ_REG(ADIS16400_XGYRO_OUT)),
+	cpu_to_be16(ADIS16400_READ_REG(ADIS16400_YGYRO_OUT)),
+	cpu_to_be16(ADIS16400_READ_REG(ADIS16400_ZGYRO_OUT)),
+	cpu_to_be16(ADIS16400_READ_REG(ADIS16400_XACCL_OUT)),
+	cpu_to_be16(ADIS16400_READ_REG(ADIS16400_YACCL_OUT)),
+	cpu_to_be16(ADIS16400_READ_REG(ADIS16400_ZACCL_OUT)),
+	cpu_to_be16(ADIS16400_READ_REG(ADIS16350_XTEMP_OUT)),
+	cpu_to_be16(ADIS16400_READ_REG(ADIS16350_YTEMP_OUT)),
+	cpu_to_be16(ADIS16400_READ_REG(ADIS16350_ZTEMP_OUT)),
+	cpu_to_be16(ADIS16400_READ_REG(ADIS16400_AUX_ADC)),
+};
+
+static int adis16350_spi_read_all(struct device *dev, u8 *rx)
+{
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct adis16400_state *st = iio_priv(indio_dev);
+
+	struct spi_message msg;
+	int i, j = 0, ret;
+	struct spi_transfer *xfers;
+
+	xfers = kzalloc(sizeof(*xfers)*indio_dev->ring->scan_count + 1,
+			GFP_KERNEL);
+	if (xfers == NULL)
+		return -ENOMEM;
+
+	for (i = 0; i < ARRAY_SIZE(read_all_tx_array); i++)
+		if (indio_dev->ring->scan_mask & (1 << i)) {
+			xfers[j].tx_buf = &read_all_tx_array[i];
+			xfers[j].bits_per_word = 16;
+			xfers[j].len = 2;
+			xfers[j + 1].rx_buf = rx + j*2;
+			j++;
+		}
+	xfers[j].bits_per_word = 16;
+	xfers[j].len = 2;
+
+	spi_message_init(&msg);
+	for (j = 0; j < indio_dev->ring->scan_count + 1; j++)
+		spi_message_add_tail(&xfers[j], &msg);
+
+	ret = spi_sync(st->us, &msg);
+	kfree(xfers);
+
+	return ret;
+}
+
 /* Whilst this makes a lot of calls to iio_sw_ring functions - it is to device
  * specific to be rolled into the core.
  */
-static void adis16400_trigger_bh_to_ring(struct work_struct *work_s)
+static irqreturn_t adis16400_trigger_handler(int irq, void *p)
 {
-	struct adis16400_state *st
-		= container_of(work_s, struct adis16400_state,
-			       work_trigger_to_ring);
-	struct iio_ring_buffer *ring = st->indio_dev->ring;
-
-	int i = 0, j;
+	struct iio_poll_func *pf = p;
+	struct iio_dev *indio_dev = pf->private_data;
+	struct adis16400_state *st = iio_priv(indio_dev);
+	struct iio_ring_buffer *ring = indio_dev->ring;
+	int i = 0, j, ret = 0;
 	s16 *data;
-	size_t datasize = ring->access.get_bytes_per_datum(ring);
+	size_t datasize = ring->access->get_bytes_per_datum(ring);
 	unsigned long mask = ring->scan_mask;
 
 	data = kmalloc(datasize , GFP_KERNEL);
 	if (data == NULL) {
 		dev_err(&st->us->dev, "memory alloc failed in ring bh");
-		return;
+		return -ENOMEM;
 	}
 
-	if (ring->scan_count)
-		if (adis16400_spi_read_burst(&st->indio_dev->dev, st->rx) >= 0)
-			for (; i < ring->scan_count; i++) {
+	if (ring->scan_count) {
+		if (st->variant->flags & ADIS16400_NO_BURST) {
+			ret = adis16350_spi_read_all(&indio_dev->dev, st->rx);
+			if (ret < 0)
+				goto err;
+			for (; i < ring->scan_count; i++)
+				data[i]	= *(s16 *)(st->rx + i*2);
+		} else {
+			ret = adis16400_spi_read_burst(&indio_dev->dev, st->rx);
+			if (ret < 0)
+				goto err;
+			for (; i < indio_dev->ring->scan_count; i++) {
 				j = __ffs(mask);
 				mask &= ~(1 << j);
-				data[i]	= be16_to_cpup(
+				data[i] = be16_to_cpup(
 					(__be16 *)&(st->rx[j*2]));
 			}
-
+		}
+	}
 	/* Guaranteed to be aligned with 8 byte boundary */
 	if (ring->scan_timestamp)
-		*((s64 *)(data + ((i + 3)/4)*4)) = st->last_timestamp;
+		*((s64 *)(data + ((i + 3)/4)*4)) = pf->timestamp;
+	ring->access->store_to(indio_dev->ring, (u8 *) data, pf->timestamp);
 
-	ring->access.store_to(ring,
-			(u8 *) data,
-			st->last_timestamp);
+	iio_trigger_notify_done(indio_dev->trig);
 
-	iio_trigger_notify_done(st->indio_dev->trig);
 	kfree(data);
+	return IRQ_HANDLED;
 
-	return;
+err:
+	kfree(data);
+	return ret;
 }
 
 void adis16400_unconfigure_ring(struct iio_dev *indio_dev)
 {
-	kfree(indio_dev->pollfunc);
+	iio_dealloc_pollfunc(indio_dev->pollfunc);
 	iio_sw_rb_free(indio_dev->ring);
 }
 
+static const struct iio_ring_setup_ops adis16400_ring_setup_ops = {
+	.preenable = &iio_sw_ring_preenable,
+	.postenable = &iio_triggered_ring_postenable,
+	.predisable = &iio_triggered_ring_predisable,
+};
+
 int adis16400_configure_ring(struct iio_dev *indio_dev)
 {
 	int ret = 0;
-	struct adis16400_state *st = indio_dev->dev_data;
+	struct adis16400_state *st = iio_priv(indio_dev);
 	struct iio_ring_buffer *ring;
-	INIT_WORK(&st->work_trigger_to_ring, adis16400_trigger_bh_to_ring);
 
 	ring = iio_sw_rb_allocate(indio_dev);
 	if (!ring) {
@@ -214,36 +192,29 @@
 	}
 	indio_dev->ring = ring;
 	/* Effectively select the ring buffer implementation */
-	iio_ring_sw_register_funcs(&ring->access);
+	ring->access = &ring_sw_access_funcs;
 	ring->bpe = 2;
-	ring->scan_el_attrs = &adis16400_scan_el_group;
 	ring->scan_timestamp = true;
-	ring->preenable = &iio_sw_ring_preenable;
-	ring->postenable = &iio_triggered_ring_postenable;
-	ring->predisable = &iio_triggered_ring_predisable;
+	ring->setup_ops = &adis16400_ring_setup_ops;
 	ring->owner = THIS_MODULE;
-
 	/* Set default scan mode */
-	iio_scan_mask_set(ring, iio_scan_el_in0_supply.number);
-	iio_scan_mask_set(ring, iio_scan_el_gyro_x.number);
-	iio_scan_mask_set(ring, iio_scan_el_gyro_y.number);
-	iio_scan_mask_set(ring, iio_scan_el_gyro_z.number);
-	iio_scan_mask_set(ring, iio_scan_el_accel_x.number);
-	iio_scan_mask_set(ring, iio_scan_el_accel_y.number);
-	iio_scan_mask_set(ring, iio_scan_el_accel_z.number);
-	iio_scan_mask_set(ring, iio_scan_el_magn_x.number);
-	iio_scan_mask_set(ring, iio_scan_el_magn_y.number);
-	iio_scan_mask_set(ring, iio_scan_el_magn_z.number);
-	iio_scan_mask_set(ring, iio_scan_el_temp.number);
-	iio_scan_mask_set(ring, iio_scan_el_in1.number);
+	ring->scan_mask = st->variant->default_scan_mask;
+	ring->scan_count = hweight_long(st->variant->default_scan_mask);
 
-	ret = iio_alloc_pollfunc(indio_dev, NULL, &adis16400_poll_func_th);
-	if (ret)
+	indio_dev->pollfunc = iio_alloc_pollfunc(&iio_pollfunc_store_time,
+						 &adis16400_trigger_handler,
+						 IRQF_ONESHOT,
+						 indio_dev,
+						 "%s_consumer%d",
+						 indio_dev->name,
+						 indio_dev->id);
+	if (indio_dev->pollfunc == NULL) {
+		ret = -ENOMEM;
 		goto error_iio_sw_rb_free;
+	}
 
 	indio_dev->modes |= INDIO_RING_TRIGGERED;
 	return 0;
-
 error_iio_sw_rb_free:
 	iio_sw_rb_free(indio_dev->ring);
 	return ret;
diff -druN linux-2.6.39-libre/drivers/staging/iio/imu/adis16400_trigger.c linux-3.0-rc7-libre/drivers/staging/iio/imu/adis16400_trigger.c
--- linux-2.6.39-libre/drivers/staging/iio/imu/adis16400_trigger.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/iio/imu/adis16400_trigger.c	2011-07-11 19:51:52.000000000 -0400
@@ -13,113 +13,63 @@
 #include "adis16400.h"
 
 /**
- * adis16400_data_rdy_trig_poll() the event handler for the data rdy trig
- **/
-static int adis16400_data_rdy_trig_poll(struct iio_dev *dev_info,
-				       int index,
-				       s64 timestamp,
-				       int no_test)
-{
-	struct adis16400_state *st = iio_dev_get_devdata(dev_info);
-	struct iio_trigger *trig = st->trig;
-
-	iio_trigger_poll(trig, timestamp);
-
-	return IRQ_HANDLED;
-}
-
-IIO_EVENT_SH(data_rdy_trig, &adis16400_data_rdy_trig_poll);
-
-static IIO_TRIGGER_NAME_ATTR;
-
-static struct attribute *adis16400_trigger_attrs[] = {
-	&dev_attr_name.attr,
-	NULL,
-};
-
-static const struct attribute_group adis16400_trigger_attr_group = {
-	.attrs = adis16400_trigger_attrs,
-};
-
-/**
  * adis16400_data_rdy_trigger_set_state() set datardy interrupt state
  **/
 static int adis16400_data_rdy_trigger_set_state(struct iio_trigger *trig,
 						bool state)
 {
-	struct adis16400_state *st = trig->private_data;
-	struct iio_dev *indio_dev = st->indio_dev;
-	int ret = 0;
+	struct iio_dev *indio_dev = trig->private_data;
 
 	dev_dbg(&indio_dev->dev, "%s (%d)\n", __func__, state);
-	ret = adis16400_set_irq(&st->indio_dev->dev, state);
-	if (state == false) {
-		iio_remove_event_from_list(&iio_event_data_rdy_trig,
-					   &indio_dev->interrupts[0]
-					   ->ev_list);
-		/* possible quirk with handler currently worked around
-		   by ensuring the work queue is empty */
-		flush_scheduled_work();
-	} else {
-		iio_add_event_to_list(&iio_event_data_rdy_trig,
-				      &indio_dev->interrupts[0]->ev_list);
-	}
-	return ret;
-}
-
-/**
- * adis16400_trig_try_reen() try renabling irq for data rdy trigger
- * @trig:	the datardy trigger
- **/
-static int adis16400_trig_try_reen(struct iio_trigger *trig)
-{
-	struct adis16400_state *st = trig->private_data;
-	enable_irq(st->us->irq);
-	/* irq reenabled so success! */
-	return 0;
+	return adis16400_set_irq(indio_dev, state);
 }
 
 int adis16400_probe_trigger(struct iio_dev *indio_dev)
 {
 	int ret;
-	struct adis16400_state *st = indio_dev->dev_data;
+	struct adis16400_state *st = iio_priv(indio_dev);
 
-	st->trig = iio_allocate_trigger();
-	st->trig->name = kasprintf(GFP_KERNEL,
-				   "adis16400-dev%d",
-				   indio_dev->id);
-	if (!st->trig->name) {
+	st->trig = iio_allocate_trigger("%s-dev%d",
+					spi_get_device_id(st->us)->name,
+					indio_dev->id);
+	if (st->trig == NULL) {
 		ret = -ENOMEM;
-		goto error_free_trig;
+		goto error_ret;
 	}
+
+	ret = request_irq(st->us->irq,
+			  &iio_trigger_generic_data_rdy_poll,
+			  IRQF_TRIGGER_RISING,
+			  "adis16400",
+			  st->trig);
+	if (ret)
+		goto error_free_trig;
 	st->trig->dev.parent = &st->us->dev;
 	st->trig->owner = THIS_MODULE;
-	st->trig->private_data = st;
+	st->trig->private_data = indio_dev;
 	st->trig->set_trigger_state = &adis16400_data_rdy_trigger_set_state;
-	st->trig->try_reenable = &adis16400_trig_try_reen;
-	st->trig->control_attrs = &adis16400_trigger_attr_group;
 	ret = iio_trigger_register(st->trig);
 
 	/* select default trigger */
 	indio_dev->trig = st->trig;
 	if (ret)
-		goto error_free_trig_name;
+		goto error_free_irq;
 
 	return 0;
 
-error_free_trig_name:
-	kfree(st->trig->name);
+error_free_irq:
+	free_irq(st->us->irq, st->trig);
 error_free_trig:
 	iio_free_trigger(st->trig);
-
+error_ret:
 	return ret;
 }
 
 void adis16400_remove_trigger(struct iio_dev *indio_dev)
 {
-	struct adis16400_state *state = indio_dev->dev_data;
+	struct adis16400_state *st = iio_priv(indio_dev);
 
-	iio_trigger_unregister(state->trig);
-	kfree(state->trig->name);
-	iio_free_trigger(state->trig);
+	iio_trigger_unregister(st->trig);
+	free_irq(st->us->irq, st->trig);
+	iio_free_trigger(st->trig);
 }
diff -druN linux-2.6.39-libre/drivers/staging/iio/imu/Kconfig linux-3.0-rc7-libre/drivers/staging/iio/imu/Kconfig
--- linux-2.6.39-libre/drivers/staging/iio/imu/Kconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/iio/imu/Kconfig	2011-07-11 19:51:52.000000000 -0400
@@ -3,29 +3,13 @@
 #
 comment "Inertial measurement units"
 
-config ADIS16300
-	tristate "Analog Devices ADIS16300 IMU SPI driver"
-	depends on SPI
-	select IIO_SW_RING if IIO_RING_BUFFER
-	select IIO_TRIGGER if IIO_RING_BUFFER
-	help
-	  Say yes here to build support for Analog Devices adis16300 four degrees
-	  of freedom inertial sensor.
-
-config ADIS16350
-	tristate "Analog Devices ADIS16350/54/55/60/62/64/65 IMU SPI driver"
-	depends on SPI
-	select IIO_TRIGGER if IIO_RING_BUFFER
-	select IIO_SW_RING if IIO_RING_BUFFER
-	help
-	  Say yes here to build support for Analog Devices adis16350/54/55/60/62/64/65
-	  high precision tri-axis inertial sensor.
-
 config ADIS16400
-	tristate "Analog Devices ADIS16400/5 IMU SPI driver"
+	tristate "Analog Devices ADIS16400 and similar IMU SPI driver"
 	depends on SPI
 	select IIO_SW_RING if IIO_RING_BUFFER
 	select IIO_TRIGGER if IIO_RING_BUFFER
 	help
-	  Say yes here to build support for Analog Devices adis16400/5 triaxial
-	  inertial sensor with Magnetometer.
+	  Say yes here to build support for Analog Devices adis16300, adis16350,
+	  adis16354, adis16355, adis16360, adis16362, adis16364, adis16365,
+	  adis16400 and adis16405 triaxial inertial sensors (adis16400 series
+	  also have magnetometers).
diff -druN linux-2.6.39-libre/drivers/staging/iio/imu/Makefile linux-3.0-rc7-libre/drivers/staging/iio/imu/Makefile
--- linux-2.6.39-libre/drivers/staging/iio/imu/Makefile	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/iio/imu/Makefile	2011-07-11 19:51:52.000000000 -0400
@@ -2,14 +2,6 @@
 # Makefile for Inertial Measurement Units
 #
 
-adis16300-y             := adis16300_core.o
-adis16300-$(CONFIG_IIO_RING_BUFFER) += adis16300_ring.o adis16300_trigger.o
-obj-$(CONFIG_ADIS16300) += adis16300.o
-
-adis16350-y             := adis16350_core.o
-adis16350-$(CONFIG_IIO_RING_BUFFER) += adis16350_ring.o adis16350_trigger.o
-obj-$(CONFIG_ADIS16350) += adis16350.o
-
 adis16400-y             := adis16400_core.o
 adis16400-$(CONFIG_IIO_RING_BUFFER) += adis16400_ring.o adis16400_trigger.o
 obj-$(CONFIG_ADIS16400) += adis16400.o
diff -druN linux-2.6.39-libre/drivers/staging/iio/industrialio-core.c linux-3.0-rc7-libre/drivers/staging/iio/industrialio-core.c
--- linux-2.6.39-libre/drivers/staging/iio/industrialio-core.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/iio/industrialio-core.c	2011-07-11 19:51:52.000000000 -0400
@@ -16,7 +16,6 @@
 #include <linux/err.h>
 #include <linux/device.h>
 #include <linux/fs.h>
-#include <linux/interrupt.h>
 #include <linux/poll.h>
 #include <linux/sched.h>
 #include <linux/wait.h>
@@ -44,27 +43,55 @@
 };
 EXPORT_SYMBOL(iio_bus_type);
 
-void __iio_change_event(struct iio_detected_event_list *ev,
-			int ev_code,
-			s64 timestamp)
-{
-	ev->ev.id = ev_code;
-	ev->ev.timestamp = timestamp;
-}
-EXPORT_SYMBOL(__iio_change_event);
+static const char * const iio_chan_type_name_spec_shared[] = {
+	[IIO_TIMESTAMP] = "timestamp",
+	[IIO_ACCEL] = "accel",
+	[IIO_IN] = "in",
+	[IIO_CURRENT] = "current",
+	[IIO_POWER] = "power",
+	[IIO_IN_DIFF] = "in-in",
+	[IIO_GYRO] = "gyro",
+	[IIO_TEMP] = "temp",
+	[IIO_MAGN] = "magn",
+	[IIO_INCLI] = "incli",
+	[IIO_ROT] = "rot",
+	[IIO_INTENSITY] = "intensity",
+	[IIO_LIGHT] = "illuminance",
+	[IIO_ANGL] = "angl",
+};
 
-/* Used both in the interrupt line put events and the ring buffer ones */
+static const char * const iio_chan_type_name_spec_complex[] = {
+	[IIO_IN_DIFF] = "in%d-in%d",
+};
 
-/* Note that in it's current form someone has to be listening before events
- * are queued. Hence a client MUST open the chrdev before the ring buffer is
- * switched on.
- */
-int __iio_push_event(struct iio_event_interface *ev_int,
-		     int ev_code,
-		     s64 timestamp,
-		     struct iio_shared_ev_pointer *
-		     shared_pointer_p)
+static const char * const iio_modifier_names_light[] = {
+	[IIO_MOD_LIGHT_BOTH] = "both",
+	[IIO_MOD_LIGHT_IR] = "ir",
+};
+
+static const char * const iio_modifier_names_axial[] = {
+	[IIO_MOD_X] = "x",
+	[IIO_MOD_Y] = "y",
+	[IIO_MOD_Z] = "z",
+};
+
+/* relies on pairs of these shared then separate */
+static const char * const iio_chan_info_postfix[] = {
+	[IIO_CHAN_INFO_SCALE_SHARED/2] = "scale",
+	[IIO_CHAN_INFO_OFFSET_SHARED/2] = "offset",
+	[IIO_CHAN_INFO_CALIBSCALE_SHARED/2] = "calibscale",
+	[IIO_CHAN_INFO_CALIBBIAS_SHARED/2] = "calibbias",
+	[IIO_CHAN_INFO_PEAK_SHARED/2] = "peak_raw",
+	[IIO_CHAN_INFO_PEAK_SCALE_SHARED/2] = "peak_scale",
+};
+
+int iio_push_event(struct iio_dev *dev_info,
+		   int ev_line,
+		   int ev_code,
+		   s64 timestamp)
 {
+	struct iio_event_interface *ev_int
+		= &dev_info->event_interfaces[ev_line];
 	struct iio_detected_event_list *ev;
 	int ret = 0;
 
@@ -83,11 +110,8 @@
 		}
 		ev->ev.id = ev_code;
 		ev->ev.timestamp = timestamp;
-		ev->shared_pointer = shared_pointer_p;
-		if (ev->shared_pointer)
-			shared_pointer_p->ev_p = ev;
 
-		list_add_tail(&ev->list, &ev_int->det_events.list);
+		list_add_tail(&ev->list, &ev_int->det_events);
 		ev_int->current_events++;
 		mutex_unlock(&ev_int->event_list_lock);
 		wake_up_interruptible(&ev_int->wait);
@@ -97,85 +121,8 @@
 error_ret:
 	return ret;
 }
-EXPORT_SYMBOL(__iio_push_event);
-
-int iio_push_event(struct iio_dev *dev_info,
-		   int ev_line,
-		   int ev_code,
-		   s64 timestamp)
-{
-	return __iio_push_event(&dev_info->event_interfaces[ev_line],
-				ev_code, timestamp, NULL);
-}
 EXPORT_SYMBOL(iio_push_event);
 
-/* Generic interrupt line interrupt handler */
-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;
-	struct iio_event_handler_list *p;
-	s64 time_ns;
-	unsigned long flags;
-
-	spin_lock_irqsave(&int_info->ev_list_lock, flags);
-	if (list_empty(&int_info->ev_list)) {
-		spin_unlock_irqrestore(&int_info->ev_list_lock, flags);
-		return IRQ_NONE;
-	}
-
-	time_ns = iio_get_time_ns();
-	list_for_each_entry(p, &int_info->ev_list, list) {
-		disable_irq_nosync(irq);
-		p->handler(dev_info, 1, time_ns, !(p->refcount > 1));
-	}
-	spin_unlock_irqrestore(&int_info->ev_list_lock, flags);
-
-	return IRQ_HANDLED;
-}
-
-static struct iio_interrupt *iio_allocate_interrupt(void)
-{
-	struct iio_interrupt *i = kmalloc(sizeof *i, GFP_KERNEL);
-	if (i) {
-		spin_lock_init(&i->ev_list_lock);
-		INIT_LIST_HEAD(&i->ev_list);
-	}
-	return i;
-}
-
-/* Confirming the validity of supplied irq is left to drivers.*/
-int iio_register_interrupt_line(unsigned int irq,
-				struct iio_dev *dev_info,
-				int line_number,
-				unsigned long type,
-				const char *name)
-{
-	int ret;
-
-	dev_info->interrupts[line_number] = iio_allocate_interrupt();
-	if (dev_info->interrupts[line_number] == NULL) {
-		ret = -ENOMEM;
-		goto error_ret;
-	}
-	dev_info->interrupts[line_number]->line_number = line_number;
-	dev_info->interrupts[line_number]->irq = irq;
-	dev_info->interrupts[line_number]->dev_info = dev_info;
-
-	/* Possibly only request on demand?
-	 * Can see this may complicate the handling of interrupts.
-	 * However, with this approach we might end up handling lots of
-	 * events no-one cares about.*/
-	ret = request_irq(irq,
-			  &iio_interrupt_handler,
-			  type,
-			  name,
-			  dev_info->interrupts[line_number]);
-
-error_ret:
-	return ret;
-}
-EXPORT_SYMBOL(iio_register_interrupt_line);
 
 /* This turns up an awful lot */
 ssize_t iio_read_const_attr(struct device *dev,
@@ -186,54 +133,6 @@
 }
 EXPORT_SYMBOL(iio_read_const_attr);
 
-/* Before this runs the interrupt generator must have been disabled */
-void iio_unregister_interrupt_line(struct iio_dev *dev_info, int line_number)
-{
-	/* make sure the interrupt handlers are all done */
-	flush_scheduled_work();
-	free_irq(dev_info->interrupts[line_number]->irq,
-		 dev_info->interrupts[line_number]);
-	kfree(dev_info->interrupts[line_number]);
-}
-EXPORT_SYMBOL(iio_unregister_interrupt_line);
-
-/* Reference counted add and remove */
-void iio_add_event_to_list(struct iio_event_handler_list *el,
-			  struct list_head *head)
-{
-	unsigned long flags;
-	struct iio_interrupt *inter = to_iio_interrupt(head);
-
-	/* take mutex to protect this element */
-	mutex_lock(&el->exist_lock);
-	if (el->refcount == 0) {
-		/* Take the event list spin lock */
-		spin_lock_irqsave(&inter->ev_list_lock, flags);
-		list_add(&el->list, head);
-		spin_unlock_irqrestore(&inter->ev_list_lock, flags);
-	}
-	el->refcount++;
-	mutex_unlock(&el->exist_lock);
-}
-EXPORT_SYMBOL(iio_add_event_to_list);
-
-void iio_remove_event_from_list(struct iio_event_handler_list *el,
-			       struct list_head *head)
-{
-	unsigned long flags;
-	struct iio_interrupt *inter = to_iio_interrupt(head);
-
-	mutex_lock(&el->exist_lock);
-	el->refcount--;
-	if (el->refcount == 0) {
-		/* Take the event list spin lock */
-		spin_lock_irqsave(&inter->ev_list_lock, flags);
-		list_del_init(&el->list);
-		spin_unlock_irqrestore(&inter->ev_list_lock, flags);
-	}
-	mutex_unlock(&el->exist_lock);
-}
-EXPORT_SYMBOL(iio_remove_event_from_list);
 
 static ssize_t iio_event_chrdev_read(struct file *filep,
 				     char __user *buf,
@@ -246,7 +145,7 @@
 	size_t len;
 
 	mutex_lock(&ev_int->event_list_lock);
-	if (list_empty(&ev_int->det_events.list)) {
+	if (list_empty(&ev_int->det_events)) {
 		if (filep->f_flags & O_NONBLOCK) {
 			ret = -EAGAIN;
 			goto error_mutex_unlock;
@@ -255,14 +154,14 @@
 		/* Blocking on device; waiting for something to be there */
 		ret = wait_event_interruptible(ev_int->wait,
 					       !list_empty(&ev_int
-							   ->det_events.list));
+							   ->det_events));
 		if (ret)
 			goto error_ret;
 		/* Single access device so no one else can get the data */
 		mutex_lock(&ev_int->event_list_lock);
 	}
 
-	el = list_first_entry(&ev_int->det_events.list,
+	el = list_first_entry(&ev_int->det_events,
 			      struct iio_detected_event_list,
 			      list);
 	len = sizeof el->ev;
@@ -273,18 +172,6 @@
 	list_del(&el->list);
 	ev_int->current_events--;
 	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 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.
-	 */
-	if (el->shared_pointer) {
-		spin_lock(&el->shared_pointer->lock);
-		(el->shared_pointer->ev_p) = NULL;
-		spin_unlock(&el->shared_pointer->lock);
-	}
 	kfree(el);
 
 	return len;
@@ -309,7 +196,7 @@
 	 * clear out any awaiting events. The mask will prevent
 	 * any new __iio_push_event calls running.
 	 */
-	list_for_each_entry_safe(el, t, &ev_int->det_events.list, list) {
+	list_for_each_entry_safe(el, t, &ev_int->det_events, list) {
 		list_del(&el->list);
 		kfree(el);
 	}
@@ -381,10 +268,11 @@
 	spin_unlock(&iio_ida_lock);
 }
 
-int iio_setup_ev_int(struct iio_event_interface *ev_int,
-		     const char *name,
-		     struct module *owner,
-		     struct device *dev)
+static int iio_setup_ev_int(struct iio_event_interface *ev_int,
+			    const char *dev_name,
+			    int index,
+			    struct module *owner,
+			    struct device *dev)
 {
 	int ret, minor;
 
@@ -399,7 +287,7 @@
 		goto error_device_put;
 	}
 	ev_int->dev.devt = MKDEV(MAJOR(iio_devt), minor);
-	dev_set_name(&ev_int->dev, "%s", name);
+	dev_set_name(&ev_int->dev, "%s:event%d", dev_name, index);
 
 	ret = device_add(&ev_int->dev);
 	if (ret)
@@ -412,7 +300,7 @@
 	/* discussion point - make this variable? */
 	ev_int->max_events = 10;
 	ev_int->current_events = 0;
-	INIT_LIST_HEAD(&ev_int->det_events.list);
+	INIT_LIST_HEAD(&ev_int->det_events);
 	init_waitqueue_head(&ev_int->wait);
 	ev_int->handler.private = ev_int;
 	ev_int->handler.flags = 0;
@@ -433,7 +321,7 @@
 	return ret;
 }
 
-void iio_free_ev_int(struct iio_event_interface *ev_int)
+static void iio_free_ev_int(struct iio_event_interface *ev_int)
 {
 	device_unregister(&ev_int->dev);
 	put_device(&ev_int->dev);
@@ -488,24 +376,397 @@
 	bus_unregister(&iio_bus_type);
 }
 
-static int iio_device_register_sysfs(struct iio_dev *dev_info)
+static ssize_t iio_read_channel_info(struct device *dev,
+				     struct device_attribute *attr,
+				     char *buf)
 {
-	int ret = 0;
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
+	int val, val2;
+	int ret = indio_dev->info->read_raw(indio_dev, this_attr->c,
+					    &val, &val2, this_attr->address);
 
-	ret = sysfs_create_group(&dev_info->dev.kobj, dev_info->attrs);
-	if (ret) {
-		dev_err(dev_info->dev.parent,
-			"Failed to register sysfs hooks\n");
+	if (ret < 0)
+		return ret;
+
+	if (ret == IIO_VAL_INT)
+		return sprintf(buf, "%d\n", val);
+	else if (ret == IIO_VAL_INT_PLUS_MICRO) {
+		if (val2 < 0)
+			return sprintf(buf, "-%d.%06u\n", val, -val2);
+		else
+			return sprintf(buf, "%d.%06u\n", val, val2);
+	} else
+		return 0;
+}
+
+static ssize_t iio_write_channel_info(struct device *dev,
+				      struct device_attribute *attr,
+				      const char *buf,
+				      size_t len)
+{
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
+	int ret, integer = 0, micro = 0, micro_mult = 100000;
+	bool integer_part = true, negative = false;
+
+	/* Assumes decimal - precision based on number of digits */
+	if (!indio_dev->info->write_raw)
+		return -EINVAL;
+	if (buf[0] == '-') {
+		negative = true;
+		buf++;
+	}
+	while (*buf) {
+		if ('0' <= *buf && *buf <= '9') {
+			if (integer_part)
+				integer = integer*10 + *buf - '0';
+			else {
+				micro += micro_mult*(*buf - '0');
+				if (micro_mult == 1)
+					break;
+				micro_mult /= 10;
+			}
+		} else if (*buf == '\n') {
+			if (*(buf + 1) == '\0')
+				break;
+			else
+				return -EINVAL;
+		} else if (*buf == '.') {
+			integer_part = false;
+		} else {
+			return -EINVAL;
+		}
+		buf++;
+	}
+	if (negative) {
+		if (integer)
+			integer = -integer;
+		else
+			micro = -micro;
+	}
+
+	ret = indio_dev->info->write_raw(indio_dev, this_attr->c,
+					 integer, micro, this_attr->address);
+	if (ret)
+		return ret;
+
+	return len;
+}
+
+static int __iio_build_postfix(struct iio_chan_spec const *chan,
+			       bool generic,
+			       const char *postfix,
+			       char **result)
+{
+	char *all_post;
+	/* 3 options - generic, extend_name, modified - if generic, extend_name
+	* and modified cannot apply.*/
+
+	if (generic || (!chan->modified && !chan->extend_name)) {
+		all_post = kasprintf(GFP_KERNEL, "%s", postfix);
+	} else if (chan->modified) {
+		const char *intermediate;
+		switch (chan->type) {
+		case IIO_INTENSITY:
+			intermediate
+				= iio_modifier_names_light[chan->channel2];
+			break;
+		case IIO_ACCEL:
+		case IIO_GYRO:
+		case IIO_MAGN:
+		case IIO_INCLI:
+		case IIO_ROT:
+		case IIO_ANGL:
+			intermediate
+				= iio_modifier_names_axial[chan->channel2];
+			break;
+		default:
+			return -EINVAL;
+		}
+		if (chan->extend_name)
+			all_post = kasprintf(GFP_KERNEL, "%s_%s_%s",
+					     intermediate,
+					     chan->extend_name,
+					     postfix);
+		else
+			all_post = kasprintf(GFP_KERNEL, "%s_%s",
+					     intermediate,
+					     postfix);
+	} else
+		all_post = kasprintf(GFP_KERNEL, "%s_%s", chan->extend_name,
+				     postfix);
+	if (all_post == NULL)
+		return -ENOMEM;
+	*result = all_post;
+	return 0;
+}
+
+int __iio_device_attr_init(struct device_attribute *dev_attr,
+			   const char *postfix,
+			   struct iio_chan_spec const *chan,
+			   ssize_t (*readfunc)(struct device *dev,
+					       struct device_attribute *attr,
+					       char *buf),
+			   ssize_t (*writefunc)(struct device *dev,
+						struct device_attribute *attr,
+						const char *buf,
+						size_t len),
+			   bool generic)
+{
+	int ret;
+	char *name_format, *full_postfix;
+	sysfs_attr_init(&dev_attr->attr);
+	ret = __iio_build_postfix(chan, generic, postfix, &full_postfix);
+	if (ret)
 		goto error_ret;
+
+	/* Special case for types that uses both channel numbers in naming */
+	if (chan->type == IIO_IN_DIFF && !generic)
+		name_format
+			= kasprintf(GFP_KERNEL, "%s_%s",
+				    iio_chan_type_name_spec_complex[chan->type],
+				    full_postfix);
+	else if (generic || !chan->indexed)
+		name_format
+			= kasprintf(GFP_KERNEL, "%s_%s",
+				    iio_chan_type_name_spec_shared[chan->type],
+				    full_postfix);
+	else
+		name_format
+			= kasprintf(GFP_KERNEL, "%s%d_%s",
+				    iio_chan_type_name_spec_shared[chan->type],
+				    chan->channel,
+				    full_postfix);
+
+	if (name_format == NULL) {
+		ret = -ENOMEM;
+		goto error_free_full_postfix;
+	}
+	dev_attr->attr.name = kasprintf(GFP_KERNEL,
+					name_format,
+					chan->channel,
+					chan->channel2);
+	if (dev_attr->attr.name == NULL) {
+		ret = -ENOMEM;
+		goto error_free_name_format;
+	}
+
+	if (readfunc) {
+		dev_attr->attr.mode |= S_IRUGO;
+		dev_attr->show = readfunc;
+	}
+
+	if (writefunc) {
+		dev_attr->attr.mode |= S_IWUSR;
+		dev_attr->store = writefunc;
 	}
+	kfree(name_format);
+	kfree(full_postfix);
+
+	return 0;
 
+error_free_name_format:
+	kfree(name_format);
+error_free_full_postfix:
+	kfree(full_postfix);
 error_ret:
 	return ret;
 }
 
+void __iio_device_attr_deinit(struct device_attribute *dev_attr)
+{
+	kfree(dev_attr->attr.name);
+}
+
+int __iio_add_chan_devattr(const char *postfix,
+			   const char *group,
+			   struct iio_chan_spec const *chan,
+			   ssize_t (*readfunc)(struct device *dev,
+					       struct device_attribute *attr,
+					       char *buf),
+			   ssize_t (*writefunc)(struct device *dev,
+						struct device_attribute *attr,
+						const char *buf,
+						size_t len),
+			   int mask,
+			   bool generic,
+			   struct device *dev,
+			   struct list_head *attr_list)
+{
+	int ret;
+	struct iio_dev_attr *iio_attr, *t;
+
+	iio_attr = kzalloc(sizeof *iio_attr, GFP_KERNEL);
+	if (iio_attr == NULL) {
+		ret = -ENOMEM;
+		goto error_ret;
+	}
+	ret = __iio_device_attr_init(&iio_attr->dev_attr,
+				     postfix, chan,
+				     readfunc, writefunc, generic);
+	if (ret)
+		goto error_iio_dev_attr_free;
+	iio_attr->c = chan;
+	iio_attr->address = mask;
+	list_for_each_entry(t, attr_list, l)
+		if (strcmp(t->dev_attr.attr.name,
+			   iio_attr->dev_attr.attr.name) == 0) {
+			if (!generic)
+				dev_err(dev, "tried to double register : %s\n",
+					t->dev_attr.attr.name);
+			ret = -EBUSY;
+			goto error_device_attr_deinit;
+		}
+
+	ret = sysfs_add_file_to_group(&dev->kobj,
+				      &iio_attr->dev_attr.attr, group);
+	if (ret < 0)
+		goto error_device_attr_deinit;
+
+	list_add(&iio_attr->l, attr_list);
+
+	return 0;
+
+error_device_attr_deinit:
+	__iio_device_attr_deinit(&iio_attr->dev_attr);
+error_iio_dev_attr_free:
+	kfree(iio_attr);
+error_ret:
+	return ret;
+}
+
+static int iio_device_add_channel_sysfs(struct iio_dev *dev_info,
+					struct iio_chan_spec const *chan)
+{
+	int ret, i;
+
+
+	if (chan->channel < 0)
+		return 0;
+	if (chan->processed_val)
+		ret = __iio_add_chan_devattr("input", NULL, chan,
+					     &iio_read_channel_info,
+					     NULL,
+					     0,
+					     0,
+					     &dev_info->dev,
+					     &dev_info->channel_attr_list);
+	else
+		ret = __iio_add_chan_devattr("raw", NULL, chan,
+					     &iio_read_channel_info,
+					     NULL,
+					     0,
+					     0,
+					     &dev_info->dev,
+					     &dev_info->channel_attr_list);
+	if (ret)
+		goto error_ret;
+
+	for_each_set_bit(i, &chan->info_mask, sizeof(long)*8) {
+		ret = __iio_add_chan_devattr(iio_chan_info_postfix[i/2],
+					     NULL, chan,
+					     &iio_read_channel_info,
+					     &iio_write_channel_info,
+					     (1 << i),
+					     !(i%2),
+					     &dev_info->dev,
+					     &dev_info->channel_attr_list);
+		if (ret == -EBUSY && (i%2 == 0)) {
+			ret = 0;
+			continue;
+		}
+		if (ret < 0)
+			goto error_ret;
+	}
+error_ret:
+	return ret;
+}
+
+static void iio_device_remove_and_free_read_attr(struct iio_dev *dev_info,
+						 struct iio_dev_attr *p)
+{
+	sysfs_remove_file_from_group(&dev_info->dev.kobj,
+				     &p->dev_attr.attr, NULL);
+	kfree(p->dev_attr.attr.name);
+	kfree(p);
+}
+
+static ssize_t iio_show_dev_name(struct device *dev,
+				 struct device_attribute *attr,
+				 char *buf)
+{
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	return sprintf(buf, "%s\n", indio_dev->name);
+}
+
+static DEVICE_ATTR(name, S_IRUGO, iio_show_dev_name, NULL);
+
+static int iio_device_register_sysfs(struct iio_dev *dev_info)
+{
+	int i, ret = 0;
+	struct iio_dev_attr *p, *n;
+
+	if (dev_info->info->attrs) {
+		ret = sysfs_create_group(&dev_info->dev.kobj,
+					 dev_info->info->attrs);
+		if (ret) {
+			dev_err(dev_info->dev.parent,
+				"Failed to register sysfs hooks\n");
+			goto error_ret;
+		}
+	}
+
+	/*
+	 * New channel registration method - relies on the fact a group does
+	 *  not need to be initialized if it is name is NULL.
+	 */
+	INIT_LIST_HEAD(&dev_info->channel_attr_list);
+	if (dev_info->channels)
+		for (i = 0; i < dev_info->num_channels; i++) {
+			ret = iio_device_add_channel_sysfs(dev_info,
+							   &dev_info
+							   ->channels[i]);
+			if (ret < 0)
+				goto error_clear_attrs;
+		}
+	if (dev_info->name) {
+		ret = sysfs_add_file_to_group(&dev_info->dev.kobj,
+					      &dev_attr_name.attr,
+					      NULL);
+		if (ret)
+			goto error_clear_attrs;
+	}
+	return 0;
+
+error_clear_attrs:
+	list_for_each_entry_safe(p, n,
+				 &dev_info->channel_attr_list, l) {
+		list_del(&p->l);
+		iio_device_remove_and_free_read_attr(dev_info, p);
+	}
+	if (dev_info->info->attrs)
+		sysfs_remove_group(&dev_info->dev.kobj, dev_info->info->attrs);
+error_ret:
+	return ret;
+
+}
+
 static void iio_device_unregister_sysfs(struct iio_dev *dev_info)
 {
-	sysfs_remove_group(&dev_info->dev.kobj, dev_info->attrs);
+
+	struct iio_dev_attr *p, *n;
+	if (dev_info->name)
+		sysfs_remove_file_from_group(&dev_info->dev.kobj,
+					     &dev_attr_name.attr,
+					     NULL);
+	list_for_each_entry_safe(p, n, &dev_info->channel_attr_list, l) {
+		list_del(&p->l);
+		iio_device_remove_and_free_read_attr(dev_info, p);
+	}
+
+	if (dev_info->info->attrs)
+		sysfs_remove_group(&dev_info->dev.kobj, dev_info->info->attrs);
 }
 
 /* Return a negative errno on failure */
@@ -538,69 +799,217 @@
 }
 EXPORT_SYMBOL(iio_free_ida_val);
 
-static int iio_device_register_id(struct iio_dev *dev_info,
-				  struct ida *this_ida)
+static const char * const iio_ev_type_text[] = {
+	[IIO_EV_TYPE_THRESH] = "thresh",
+	[IIO_EV_TYPE_MAG] = "mag",
+	[IIO_EV_TYPE_ROC] = "roc"
+};
+
+static const char * const iio_ev_dir_text[] = {
+	[IIO_EV_DIR_EITHER] = "either",
+	[IIO_EV_DIR_RISING] = "rising",
+	[IIO_EV_DIR_FALLING] = "falling"
+};
+
+static ssize_t iio_ev_state_store(struct device *dev,
+				  struct device_attribute *attr,
+				  const char *buf,
+				  size_t len)
 {
-	dev_info->id = iio_get_new_ida_val(&iio_ida);
-	if (dev_info->id < 0)
-		return dev_info->id;
-	return 0;
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
+	int ret;
+	bool val;
+
+	ret = strtobool(buf, &val);
+	if (ret < 0)
+		return ret;
+
+	ret = indio_dev->info->write_event_config(indio_dev,
+						  this_attr->address,
+						  val);
+	return (ret < 0) ? ret : len;
 }
 
-static void iio_device_unregister_id(struct iio_dev *dev_info)
+static ssize_t iio_ev_state_show(struct device *dev,
+				 struct device_attribute *attr,
+				 char *buf)
 {
-	iio_free_ida_val(&iio_ida, dev_info->id);
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
+	int val = indio_dev->info->read_event_config(indio_dev,
+						     this_attr->address);
+
+	if (val < 0)
+		return val;
+	else
+		return sprintf(buf, "%d\n", val);
 }
 
-static inline int __iio_add_event_config_attrs(struct iio_dev *dev_info, int i)
+static ssize_t iio_ev_value_show(struct device *dev,
+				 struct device_attribute *attr,
+				 char *buf)
 {
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
+	int val, ret;
+
+	ret = indio_dev->info->read_event_value(indio_dev,
+						this_attr->address, &val);
+	if (ret < 0)
+		return ret;
+
+	return sprintf(buf, "%d\n", val);
+}
+
+static ssize_t iio_ev_value_store(struct device *dev,
+				  struct device_attribute *attr,
+				  const char *buf,
+				  size_t len)
+{
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
+	unsigned long val;
 	int ret;
-	/*p for adding, q for removing */
-	struct attribute **attrp, **attrq;
 
-	if (dev_info->event_conf_attrs && dev_info->event_conf_attrs[i].attrs) {
-		attrp = dev_info->event_conf_attrs[i].attrs;
-		while (*attrp) {
-			ret =  sysfs_add_file_to_group(&dev_info->dev.kobj,
-						       *attrp,
-						       dev_info
-						       ->event_attrs[i].name);
-			if (ret)
-				goto error_ret;
-			attrp++;
+	ret = strict_strtoul(buf, 10, &val);
+	if (ret)
+		return ret;
+
+	ret = indio_dev->info->write_event_value(indio_dev, this_attr->address,
+						 val);
+	if (ret < 0)
+		return ret;
+
+	return len;
+}
+
+static int iio_device_add_event_sysfs(struct iio_dev *dev_info,
+				      struct iio_chan_spec const *chan)
+{
+
+	int ret = 0, i, mask;
+	char *postfix;
+	if (!chan->event_mask)
+		return 0;
+
+	for_each_set_bit(i, &chan->event_mask, sizeof(chan->event_mask)*8) {
+		postfix = kasprintf(GFP_KERNEL, "%s_%s_en",
+				    iio_ev_type_text[i/IIO_EV_TYPE_MAX],
+				    iio_ev_dir_text[i%IIO_EV_TYPE_MAX]);
+		if (postfix == NULL) {
+			ret = -ENOMEM;
+			goto error_ret;
 		}
-	}
-	return 0;
+		switch (chan->type) {
+			/* Switch this to a table at some point */
+		case IIO_IN:
+			mask = IIO_UNMOD_EVENT_CODE(chan->type, chan->channel,
+						    i/IIO_EV_TYPE_MAX,
+						    i%IIO_EV_TYPE_MAX);
+			break;
+		case IIO_ACCEL:
+			mask = IIO_MOD_EVENT_CODE(chan->type, 0, chan->channel,
+						  i/IIO_EV_TYPE_MAX,
+						  i%IIO_EV_TYPE_MAX);
+			break;
+		case IIO_IN_DIFF:
+			mask = IIO_MOD_EVENT_CODE(chan->type, chan->channel,
+						  chan->channel2,
+						  i/IIO_EV_TYPE_MAX,
+						  i%IIO_EV_TYPE_MAX);
+			break;
+		default:
+			printk(KERN_INFO "currently unhandled type of event\n");
+		}
+		ret = __iio_add_chan_devattr(postfix,
+					     NULL,
+					     chan,
+					     &iio_ev_state_show,
+					     iio_ev_state_store,
+					     mask,
+					     /*HACK. - limits us to one
+					       event interface - fix by
+					       extending the bitmask - but
+					       how far*/
+					     0,
+					     &dev_info->event_interfaces[0].dev,
+					     &dev_info->event_interfaces[0].
+					     dev_attr_list);
+		kfree(postfix);
+		if (ret)
+			goto error_ret;
+
+		postfix = kasprintf(GFP_KERNEL, "%s_%s_value",
+				    iio_ev_type_text[i/IIO_EV_TYPE_MAX],
+				    iio_ev_dir_text[i%IIO_EV_TYPE_MAX]);
+		if (postfix == NULL) {
+			ret = -ENOMEM;
+			goto error_ret;
+		}
+		ret = __iio_add_chan_devattr(postfix, NULL, chan,
+					     iio_ev_value_show,
+					     iio_ev_value_store,
+					     mask,
+					     0,
+					     &dev_info->event_interfaces[0]
+					     .dev,
+					     &dev_info->event_interfaces[0]
+					     .dev_attr_list);
+		kfree(postfix);
+		if (ret)
+			goto error_ret;
 
-error_ret:
-	attrq = dev_info->event_conf_attrs[i].attrs;
-	while (attrq != attrp) {
-			sysfs_remove_file_from_group(&dev_info->dev.kobj,
-					     *attrq,
-					     dev_info->event_attrs[i].name);
-		attrq++;
 	}
 
+error_ret:
 	return ret;
 }
 
-static inline int __iio_remove_event_config_attrs(struct iio_dev *dev_info,
-						  int i)
+static inline void __iio_remove_all_event_sysfs(struct iio_dev *dev_info,
+						const char *groupname,
+						int num)
 {
-	struct attribute **attrq;
+	struct iio_dev_attr *p, *n;
+	list_for_each_entry_safe(p, n,
+				 &dev_info->event_interfaces[num].
+				 dev_attr_list, l) {
+		sysfs_remove_file_from_group(&dev_info
+					     ->event_interfaces[num].dev.kobj,
+					     &p->dev_attr.attr,
+					     groupname);
+		kfree(p->dev_attr.attr.name);
+		kfree(p);
+	}
+}
 
-	if (dev_info->event_conf_attrs
-		&& dev_info->event_conf_attrs[i].attrs) {
-		attrq = dev_info->event_conf_attrs[i].attrs;
-		while (*attrq) {
-			sysfs_remove_file_from_group(&dev_info->dev.kobj,
-						     *attrq,
-						     dev_info
-						     ->event_attrs[i].name);
-			attrq++;
+static inline int __iio_add_event_config_attrs(struct iio_dev *dev_info, int i)
+{
+	int j;
+	int ret;
+	INIT_LIST_HEAD(&dev_info->event_interfaces[0].dev_attr_list);
+	/* Dynically created from the channels array */
+	if (dev_info->channels) {
+		for (j = 0; j < dev_info->num_channels; j++) {
+			ret = iio_device_add_event_sysfs(dev_info,
+							 &dev_info
+							 ->channels[j]);
+			if (ret)
+				goto error_clear_attrs;
 		}
 	}
+	return 0;
+
+error_clear_attrs:
+	__iio_remove_all_event_sysfs(dev_info, NULL, i);
+
+	return ret;
+}
 
+static inline int __iio_remove_event_config_attrs(struct iio_dev *dev_info,
+						  int i)
+{
+	__iio_remove_all_event_sysfs(dev_info, NULL, i);
 	return 0;
 }
 
@@ -608,39 +1017,23 @@
 {
 	int ret = 0, i, j;
 
-	if (dev_info->num_interrupt_lines == 0)
+	if (dev_info->info->num_interrupt_lines == 0)
 		return 0;
 
 	dev_info->event_interfaces =
 		kzalloc(sizeof(struct iio_event_interface)
-			*dev_info->num_interrupt_lines,
+			*dev_info->info->num_interrupt_lines,
 			GFP_KERNEL);
 	if (dev_info->event_interfaces == NULL) {
 		ret = -ENOMEM;
 		goto error_ret;
 	}
 
-	dev_info->interrupts = kzalloc(sizeof(struct iio_interrupt *)
-				       *dev_info->num_interrupt_lines,
-				       GFP_KERNEL);
-	if (dev_info->interrupts == NULL) {
-		ret = -ENOMEM;
-		goto error_free_event_interfaces;
-	}
-
-	for (i = 0; i < dev_info->num_interrupt_lines; i++) {
-		dev_info->event_interfaces[i].owner = dev_info->driver_module;
-
-		snprintf(dev_info->event_interfaces[i]._name, 20,
-			 "%s:event%d",
-			 dev_name(&dev_info->dev),
-			 i);
-
+	for (i = 0; i < dev_info->info->num_interrupt_lines; i++) {
 		ret = iio_setup_ev_int(&dev_info->event_interfaces[i],
-				       (const char *)(dev_info
-						      ->event_interfaces[i]
-						      ._name),
-				       dev_info->driver_module,
+				       dev_name(&dev_info->dev),
+				       i,
+				       dev_info->info->driver_module,
 				       &dev_info->dev);
 		if (ret) {
 			dev_err(&dev_info->dev,
@@ -650,10 +1043,13 @@
 
 		dev_set_drvdata(&dev_info->event_interfaces[i].dev,
 				(void *)dev_info);
-		ret = sysfs_create_group(&dev_info
-					->event_interfaces[i]
-					.dev.kobj,
-					&dev_info->event_attrs[i]);
+
+		if (dev_info->info->event_attrs != NULL)
+			ret = sysfs_create_group(&dev_info
+						 ->event_interfaces[i]
+						 .dev.kobj,
+						 &dev_info->info
+						 ->event_attrs[i]);
 
 		if (ret) {
 			dev_err(&dev_info->dev,
@@ -662,7 +1058,7 @@
 		}
 	}
 
-	for (i = 0; i < dev_info->num_interrupt_lines; i++) {
+	for (i = 0; i < dev_info->info->num_interrupt_lines; i++) {
 		ret = __iio_add_event_config_attrs(dev_info, i);
 		if (ret)
 			goto error_unregister_config_attrs;
@@ -673,17 +1069,16 @@
 error_unregister_config_attrs:
 	for (j = 0; j < i; j++)
 		__iio_remove_event_config_attrs(dev_info, i);
-	i = dev_info->num_interrupt_lines - 1;
+	i = dev_info->info->num_interrupt_lines - 1;
 error_remove_sysfs_interfaces:
 	for (j = 0; j < i; j++)
-		sysfs_remove_group(&dev_info
+		if (dev_info->info->event_attrs != NULL)
+			sysfs_remove_group(&dev_info
 				   ->event_interfaces[j].dev.kobj,
-				   &dev_info->event_attrs[j]);
+				   &dev_info->info->event_attrs[j]);
 error_free_setup_ev_ints:
 	for (j = 0; j < i; j++)
 		iio_free_ev_int(&dev_info->event_interfaces[j]);
-	kfree(dev_info->interrupts);
-error_free_event_interfaces:
 	kfree(dev_info->event_interfaces);
 error_ret:
 
@@ -694,25 +1089,25 @@
 {
 	int i;
 
-	if (dev_info->num_interrupt_lines == 0)
+	if (dev_info->info->num_interrupt_lines == 0)
 		return;
-	for (i = 0; i < dev_info->num_interrupt_lines; i++)
-		sysfs_remove_group(&dev_info
-				   ->event_interfaces[i].dev.kobj,
-				   &dev_info->event_attrs[i]);
+	for (i = 0; i < dev_info->info->num_interrupt_lines; i++) {
+		__iio_remove_event_config_attrs(dev_info, i);
+		if (dev_info->info->event_attrs != NULL)
+			sysfs_remove_group(&dev_info
+					   ->event_interfaces[i].dev.kobj,
+					   &dev_info->info->event_attrs[i]);
+	}
 
-	for (i = 0; i < dev_info->num_interrupt_lines; i++)
+	for (i = 0; i < dev_info->info->num_interrupt_lines; i++)
 		iio_free_ev_int(&dev_info->event_interfaces[i]);
-	kfree(dev_info->interrupts);
 	kfree(dev_info->event_interfaces);
 }
 
 static void iio_dev_release(struct device *device)
 {
-	struct iio_dev *dev = to_iio_dev(device);
-
 	iio_put();
-	kfree(dev);
+	kfree(to_iio_dev(device));
 }
 
 static struct device_type iio_dev_type = {
@@ -720,9 +1115,20 @@
 	.release = iio_dev_release,
 };
 
-struct iio_dev *iio_allocate_device(void)
+struct iio_dev *iio_allocate_device(int sizeof_priv)
 {
-	struct iio_dev *dev = kzalloc(sizeof *dev, GFP_KERNEL);
+	struct iio_dev *dev;
+	size_t alloc_size;
+
+	alloc_size = sizeof(struct iio_dev);
+	if (sizeof_priv) {
+		alloc_size = ALIGN(alloc_size, IIO_ALIGN);
+		alloc_size += sizeof_priv;
+	}
+	/* ensure 32-byte alignment of whole construct ? */
+	alloc_size += IIO_ALIGN - 1;
+
+	dev = kzalloc(alloc_size, GFP_KERNEL);
 
 	if (dev) {
 		dev->dev.type = &iio_dev_type;
@@ -748,8 +1154,9 @@
 {
 	int ret;
 
-	ret = iio_device_register_id(dev_info, &iio_ida);
-	if (ret) {
+	dev_info->id = iio_get_new_ida_val(&iio_ida);
+	if (dev_info->id < 0) {
+		ret = dev_info->id;
 		dev_err(&dev_info->dev, "Failed to get id\n");
 		goto error_ret;
 	}
@@ -780,7 +1187,7 @@
 error_del_device:
 	device_del(&dev_info->dev);
 error_free_ida:
-	iio_device_unregister_id(dev_info);
+	iio_free_ida_val(&iio_ida, dev_info->id);
 error_ret:
 	return ret;
 }
@@ -792,7 +1199,7 @@
 		iio_device_unregister_trigger_consumer(dev_info);
 	iio_device_unregister_eventset(dev_info);
 	iio_device_unregister_sysfs(dev_info);
-	iio_device_unregister_id(dev_info);
+	iio_free_ida_val(&iio_ida, dev_info->id);
 	device_unregister(&dev_info->dev);
 }
 EXPORT_SYMBOL(iio_device_unregister);
diff -druN linux-2.6.39-libre/drivers/staging/iio/industrialio-ring.c linux-3.0-rc7-libre/drivers/staging/iio/industrialio-ring.c
--- linux-2.6.39-libre/drivers/staging/iio/industrialio-ring.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/iio/industrialio-ring.c	2011-07-11 19:51:52.000000000 -0400
@@ -18,37 +18,11 @@
 #include <linux/fs.h>
 #include <linux/cdev.h>
 #include <linux/slab.h>
+#include <linux/poll.h>
 
 #include "iio.h"
 #include "ring_generic.h"
 
-int iio_push_ring_event(struct iio_ring_buffer *ring_buf,
-		       int event_code,
-		       s64 timestamp)
-{
-	return __iio_push_event(&ring_buf->ev_int,
-			       event_code,
-			       timestamp,
-			       &ring_buf->shared_ev_pointer);
-}
-EXPORT_SYMBOL(iio_push_ring_event);
-
-int iio_push_or_escallate_ring_event(struct iio_ring_buffer *ring_buf,
-				    int event_code,
-				    s64 timestamp)
-{
-	if (ring_buf->shared_ev_pointer.ev_p)
-		__iio_change_event(ring_buf->shared_ev_pointer.ev_p,
-				   event_code,
-				   timestamp);
-	else
-		return iio_push_ring_event(ring_buf,
-					  event_code,
-					  timestamp);
-	return 0;
-}
-EXPORT_SYMBOL(iio_push_or_escallate_ring_event);
-
 /**
  * iio_ring_open() - chrdev file open for ring buffer access
  *
@@ -62,8 +36,8 @@
 	struct iio_ring_buffer *rb = hand->private;
 
 	filp->private_data = hand->private;
-	if (rb->access.mark_in_use)
-		rb->access.mark_in_use(rb);
+	if (rb->access->mark_in_use)
+		rb->access->mark_in_use(rb);
 
 	return 0;
 }
@@ -81,184 +55,316 @@
 	struct iio_ring_buffer *rb = hand->private;
 
 	clear_bit(IIO_BUSY_BIT_POS, &rb->access_handler.flags);
-	if (rb->access.unmark_in_use)
-		rb->access.unmark_in_use(rb);
+	if (rb->access->unmark_in_use)
+		rb->access->unmark_in_use(rb);
 
 	return 0;
 }
 
 /**
- * iio_ring_rip_outer() - chrdev read for ring buffer access
+ * iio_ring_read_first_n_outer() - chrdev read for ring buffer access
  *
  * This function relies on all ring buffer implementations having an
  * iio_ring _bufer as their first element.
  **/
-static ssize_t iio_ring_rip_outer(struct file *filp, char __user *buf,
-				  size_t count, loff_t *f_ps)
+static ssize_t iio_ring_read_first_n_outer(struct file *filp, char __user *buf,
+				  size_t n, loff_t *f_ps)
 {
 	struct iio_ring_buffer *rb = filp->private_data;
-	int ret, dead_offset;
 
-	/* rip lots must exist. */
-	if (!rb->access.rip_lots)
+	if (!rb->access->read_first_n)
 		return -EINVAL;
-	ret = rb->access.rip_lots(rb, count, buf, &dead_offset);
+	return rb->access->read_first_n(rb, n, buf);
+}
 
-	return ret;
+/**
+ * iio_ring_poll() - poll the ring to find out if it has data
+ */
+static unsigned int iio_ring_poll(struct file *filp,
+				  struct poll_table_struct *wait)
+{
+	struct iio_ring_buffer *rb = filp->private_data;
+
+	poll_wait(filp, &rb->pollq, wait);
+	if (rb->stufftoread)
+		return POLLIN | POLLRDNORM;
+	/* need a way of knowing if there may be enough data... */
+	return 0;
 }
 
 static const struct file_operations iio_ring_fileops = {
-	.read = iio_ring_rip_outer,
+	.read = iio_ring_read_first_n_outer,
 	.release = iio_ring_release,
 	.open = iio_ring_open,
+	.poll = iio_ring_poll,
 	.owner = THIS_MODULE,
 	.llseek = noop_llseek,
 };
 
-/**
- * __iio_request_ring_buffer_event_chrdev() - allocate ring event chrdev
- * @buf:	ring buffer whose event chrdev we are allocating
- * @id:		id of this ring buffer (typically 0)
- * @owner:	the module who owns the ring buffer (for ref counting)
- * @dev:	device with which the chrdev is associated
- **/
-static inline int
-__iio_request_ring_buffer_event_chrdev(struct iio_ring_buffer *buf,
-				       int id,
-				       struct module *owner,
-				       struct device *dev)
-{
-	int ret;
-
-	snprintf(buf->ev_int._name, sizeof(buf->ev_int._name),
-		 "%s:event%d",
-		 dev_name(&buf->dev),
-		 id);
-	ret = iio_setup_ev_int(&(buf->ev_int),
-			       buf->ev_int._name,
-			       owner,
-			       dev);
-	if (ret)
-		goto error_ret;
-	return 0;
-
-error_ret:
-	return ret;
-}
-
-static inline void
-__iio_free_ring_buffer_event_chrdev(struct iio_ring_buffer *buf)
-{
-	iio_free_ev_int(&(buf->ev_int));
-}
-
-static void iio_ring_access_release(struct device *dev)
+void iio_ring_access_release(struct device *dev)
 {
 	struct iio_ring_buffer *buf
-		= access_dev_to_iio_ring_buffer(dev);
+		= container_of(dev, struct iio_ring_buffer, dev);
 	cdev_del(&buf->access_handler.chrdev);
 	iio_device_free_chrdev_minor(MINOR(dev->devt));
 }
-
-static struct device_type iio_ring_access_type = {
-	.release = iio_ring_access_release,
-};
+EXPORT_SYMBOL(iio_ring_access_release);
 
 static inline int
-__iio_request_ring_buffer_access_chrdev(struct iio_ring_buffer *buf,
-					int id,
-					struct module *owner)
+__iio_request_ring_buffer_chrdev(struct iio_ring_buffer *buf,
+				 struct module *owner,
+				 int id)
 {
-	int ret, minor;
+	int ret;
 
 	buf->access_handler.flags = 0;
+	buf->dev.bus = &iio_bus_type;
+	device_initialize(&buf->dev);
 
-	buf->access_dev.parent = &buf->dev;
-	buf->access_dev.bus = &iio_bus_type;
-	buf->access_dev.type = &iio_ring_access_type;
-	device_initialize(&buf->access_dev);
-
-	minor = iio_device_get_chrdev_minor();
-	if (minor < 0) {
-		ret = minor;
+	ret = iio_device_get_chrdev_minor();
+	if (ret < 0)
 		goto error_device_put;
-	}
-	buf->access_dev.devt = MKDEV(MAJOR(iio_devt), minor);
 
-
-	buf->access_id = id;
-
-	dev_set_name(&buf->access_dev, "%s:access%d",
-		     dev_name(&buf->dev),
-		     buf->access_id);
-	ret = device_add(&buf->access_dev);
+	buf->dev.devt = MKDEV(MAJOR(iio_devt), ret);
+	dev_set_name(&buf->dev, "%s:buffer%d",
+		     dev_name(buf->dev.parent),
+		     id);
+	ret = device_add(&buf->dev);
 	if (ret < 0) {
-		printk(KERN_ERR "failed to add the ring access dev\n");
+		printk(KERN_ERR "failed to add the ring dev\n");
 		goto error_device_put;
 	}
-
 	cdev_init(&buf->access_handler.chrdev, &iio_ring_fileops);
 	buf->access_handler.chrdev.owner = owner;
-
-	ret = cdev_add(&buf->access_handler.chrdev, buf->access_dev.devt, 1);
+	ret = cdev_add(&buf->access_handler.chrdev, buf->dev.devt, 1);
 	if (ret) {
-		printk(KERN_ERR "failed to allocate ring access chrdev\n");
+		printk(KERN_ERR "failed to allocate ring chrdev\n");
 		goto error_device_unregister;
 	}
 	return 0;
 
 error_device_unregister:
-	device_unregister(&buf->access_dev);
+	device_unregister(&buf->dev);
 error_device_put:
-	put_device(&buf->access_dev);
+	put_device(&buf->dev);
 
 	return ret;
 }
 
-static void __iio_free_ring_buffer_access_chrdev(struct iio_ring_buffer *buf)
+static void __iio_free_ring_buffer_chrdev(struct iio_ring_buffer *buf)
 {
-	device_unregister(&buf->access_dev);
+	device_unregister(&buf->dev);
 }
 
 void iio_ring_buffer_init(struct iio_ring_buffer *ring,
 			  struct iio_dev *dev_info)
 {
-	if (ring->access.mark_param_change)
-		ring->access.mark_param_change(ring);
 	ring->indio_dev = dev_info;
-	ring->ev_int.private = ring;
 	ring->access_handler.private = ring;
-	ring->shared_ev_pointer.ev_p = NULL;
-	spin_lock_init(&ring->shared_ev_pointer.lock);
+	init_waitqueue_head(&ring->pollq);
 }
 EXPORT_SYMBOL(iio_ring_buffer_init);
 
-int iio_ring_buffer_register(struct iio_ring_buffer *ring, int id)
+static ssize_t iio_show_scan_index(struct device *dev,
+				   struct device_attribute *attr,
+				   char *buf)
+{
+	return sprintf(buf, "%u\n", to_iio_dev_attr(attr)->c->scan_index);
+}
+
+static ssize_t iio_show_fixed_type(struct device *dev,
+				   struct device_attribute *attr,
+				   char *buf)
+{
+	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
+	return sprintf(buf, "%c%d/%d>>%u\n",
+		       this_attr->c->scan_type.sign,
+		       this_attr->c->scan_type.realbits,
+		       this_attr->c->scan_type.storagebits,
+		       this_attr->c->scan_type.shift);
+}
+
+static ssize_t iio_scan_el_show(struct device *dev,
+				struct device_attribute *attr,
+				char *buf)
 {
 	int ret;
+	struct iio_ring_buffer *ring = dev_get_drvdata(dev);
 
-	ring->id = id;
+	ret = iio_scan_mask_query(ring, to_iio_dev_attr(attr)->address);
+	if (ret < 0)
+		return ret;
+	return sprintf(buf, "%d\n", ret);
+}
 
-	dev_set_name(&ring->dev, "%s:buffer%d",
-		     dev_name(ring->dev.parent),
-		     ring->id);
-	ret = device_add(&ring->dev);
+static int iio_scan_mask_clear(struct iio_ring_buffer *ring, int bit)
+{
+	if (bit > IIO_MAX_SCAN_LENGTH)
+		return -EINVAL;
+	ring->scan_mask &= ~(1 << bit);
+	ring->scan_count--;
+	return 0;
+}
+
+static ssize_t iio_scan_el_store(struct device *dev,
+				 struct device_attribute *attr,
+				 const char *buf,
+				 size_t len)
+{
+	int ret = 0;
+	bool state;
+	struct iio_ring_buffer *ring = dev_get_drvdata(dev);
+	struct iio_dev *indio_dev = ring->indio_dev;
+	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
+
+	state = !(buf[0] == '0');
+	mutex_lock(&indio_dev->mlock);
+	if (indio_dev->currentmode == INDIO_RING_TRIGGERED) {
+		ret = -EBUSY;
+		goto error_ret;
+	}
+	ret = iio_scan_mask_query(ring, this_attr->address);
+	if (ret < 0)
+		goto error_ret;
+	if (!state && ret) {
+		ret = iio_scan_mask_clear(ring, this_attr->address);
+		if (ret)
+			goto error_ret;
+	} else if (state && !ret) {
+		ret = iio_scan_mask_set(ring, this_attr->address);
+		if (ret)
+			goto error_ret;
+	}
+
+error_ret:
+	mutex_unlock(&indio_dev->mlock);
+
+	return ret ? ret : len;
+
+}
+
+static ssize_t iio_scan_el_ts_show(struct device *dev,
+				   struct device_attribute *attr,
+				   char *buf)
+{
+	struct iio_ring_buffer *ring = dev_get_drvdata(dev);
+	return sprintf(buf, "%d\n", ring->scan_timestamp);
+}
+
+static ssize_t iio_scan_el_ts_store(struct device *dev,
+				    struct device_attribute *attr,
+				    const char *buf,
+				    size_t len)
+{
+	int ret = 0;
+	struct iio_ring_buffer *ring = dev_get_drvdata(dev);
+	struct iio_dev *indio_dev = ring->indio_dev;
+	bool state;
+	state = !(buf[0] == '0');
+	mutex_lock(&indio_dev->mlock);
+	if (indio_dev->currentmode == INDIO_RING_TRIGGERED) {
+		ret = -EBUSY;
+		goto error_ret;
+	}
+	ring->scan_timestamp = state;
+error_ret:
+	mutex_unlock(&indio_dev->mlock);
+
+	return ret ? ret : len;
+}
+
+static int iio_ring_add_channel_sysfs(struct iio_ring_buffer *ring,
+				      const struct iio_chan_spec *chan)
+{
+	int ret;
+
+	ret = __iio_add_chan_devattr("index", "scan_elements",
+				     chan,
+				     &iio_show_scan_index,
+				     NULL,
+				     0,
+				     0,
+				     &ring->dev,
+				     &ring->scan_el_dev_attr_list);
 	if (ret)
 		goto error_ret;
 
-	ret = __iio_request_ring_buffer_event_chrdev(ring,
-						     0,
-						     ring->owner,
-						     &ring->dev);
+	ret = __iio_add_chan_devattr("type", "scan_elements",
+				     chan,
+				     &iio_show_fixed_type,
+				     NULL,
+				     0,
+				     0,
+				     &ring->dev,
+				     &ring->scan_el_dev_attr_list);
 	if (ret)
-		goto error_remove_device;
+		goto error_ret;
 
-	ret = __iio_request_ring_buffer_access_chrdev(ring,
-						      0,
-						      ring->owner);
+	if (chan->type != IIO_TIMESTAMP)
+		ret = __iio_add_chan_devattr("en", "scan_elements",
+					     chan,
+					     &iio_scan_el_show,
+					     &iio_scan_el_store,
+					     chan->scan_index,
+					     0,
+					     &ring->dev,
+					     &ring->scan_el_dev_attr_list);
+	else
+		ret = __iio_add_chan_devattr("en", "scan_elements",
+					     chan,
+					     &iio_scan_el_ts_show,
+					     &iio_scan_el_ts_store,
+					     chan->scan_index,
+					     0,
+					     &ring->dev,
+					     &ring->scan_el_dev_attr_list);
+error_ret:
+	return ret;
+}
+
+static void iio_ring_remove_and_free_scan_dev_attr(struct iio_ring_buffer *ring,
+						   struct iio_dev_attr *p)
+{
+	sysfs_remove_file_from_group(&ring->dev.kobj,
+				     &p->dev_attr.attr, "scan_elements");
+	kfree(p->dev_attr.attr.name);
+	kfree(p);
+}
 
+static struct attribute *iio_scan_el_dummy_attrs[] = {
+	NULL
+};
+
+static struct attribute_group iio_scan_el_dummy_group = {
+	.name = "scan_elements",
+	.attrs = iio_scan_el_dummy_attrs
+};
+
+static void __iio_ring_attr_cleanup(struct iio_ring_buffer *ring)
+{
+	struct iio_dev_attr *p, *n;
+	int anydynamic = !list_empty(&ring->scan_el_dev_attr_list);
+	list_for_each_entry_safe(p, n,
+				 &ring->scan_el_dev_attr_list, l)
+		iio_ring_remove_and_free_scan_dev_attr(ring, p);
+
+	if (ring->scan_el_attrs)
+		sysfs_remove_group(&ring->dev.kobj,
+				   ring->scan_el_attrs);
+	else if (anydynamic)
+		sysfs_remove_group(&ring->dev.kobj,
+				   &iio_scan_el_dummy_group);
+}
+
+int iio_ring_buffer_register_ex(struct iio_ring_buffer *ring, int id,
+				const struct iio_chan_spec *channels,
+				int num_channels)
+{
+	int ret, i;
+
+	ret = __iio_request_ring_buffer_chrdev(ring, ring->owner, id);
 	if (ret)
-		goto error_free_ring_buffer_event_chrdev;
+		goto error_ret;
 
 	if (ring->scan_el_attrs) {
 		ret = sysfs_create_group(&ring->dev.kobj,
@@ -266,29 +372,39 @@
 		if (ret) {
 			dev_err(&ring->dev,
 				"Failed to add sysfs scan elements\n");
-			goto error_free_ring_buffer_event_chrdev;
+			goto error_free_ring_buffer_chrdev;
 		}
+	} else if (channels) {
+		ret = sysfs_create_group(&ring->dev.kobj,
+					 &iio_scan_el_dummy_group);
+		if (ret)
+			goto error_free_ring_buffer_chrdev;
 	}
 
-	return ret;
-error_free_ring_buffer_event_chrdev:
-	__iio_free_ring_buffer_event_chrdev(ring);
-error_remove_device:
-	device_del(&ring->dev);
+	INIT_LIST_HEAD(&ring->scan_el_dev_attr_list);
+	if (channels) {
+		/* new magic */
+		for (i = 0; i < num_channels; i++) {
+			ret = iio_ring_add_channel_sysfs(ring, &channels[i]);
+			if (ret < 0)
+				goto error_cleanup_dynamic;
+		}
+	}
+
+	return 0;
+error_cleanup_dynamic:
+	__iio_ring_attr_cleanup(ring);
+error_free_ring_buffer_chrdev:
+	__iio_free_ring_buffer_chrdev(ring);
 error_ret:
 	return ret;
 }
-EXPORT_SYMBOL(iio_ring_buffer_register);
+EXPORT_SYMBOL(iio_ring_buffer_register_ex);
 
 void iio_ring_buffer_unregister(struct iio_ring_buffer *ring)
 {
-	if (ring->scan_el_attrs)
-		sysfs_remove_group(&ring->dev.kobj,
-				   ring->scan_el_attrs);
-
-	__iio_free_ring_buffer_access_chrdev(ring);
-	__iio_free_ring_buffer_event_chrdev(ring);
-	device_del(&ring->dev);
+	__iio_ring_attr_cleanup(ring);
+	__iio_free_ring_buffer_chrdev(ring);
 }
 EXPORT_SYMBOL(iio_ring_buffer_unregister);
 
@@ -296,14 +412,13 @@
 			     struct device_attribute *attr,
 			     char *buf)
 {
-	int len = 0;
 	struct iio_ring_buffer *ring = dev_get_drvdata(dev);
 
-	if (ring->access.get_length)
-		len = sprintf(buf, "%d\n",
-			      ring->access.get_length(ring));
+	if (ring->access->get_length)
+		return sprintf(buf, "%d\n",
+			       ring->access->get_length(ring));
 
-	return len;
+	return 0;
 }
 EXPORT_SYMBOL(iio_read_ring_length);
 
@@ -315,18 +430,19 @@
 	int ret;
 	ulong val;
 	struct iio_ring_buffer *ring = dev_get_drvdata(dev);
+
 	ret = strict_strtoul(buf, 10, &val);
 	if (ret)
 		return ret;
 
-	if (ring->access.get_length)
-		if (val == ring->access.get_length(ring))
+	if (ring->access->get_length)
+		if (val == ring->access->get_length(ring))
 			return len;
 
-	if (ring->access.set_length) {
-		ring->access.set_length(ring, val);
-		if (ring->access.mark_param_change)
-			ring->access.mark_param_change(ring);
+	if (ring->access->set_length) {
+		ring->access->set_length(ring, val);
+		if (ring->access->mark_param_change)
+			ring->access->mark_param_change(ring);
 	}
 
 	return len;
@@ -337,14 +453,13 @@
 			  struct device_attribute *attr,
 			  char *buf)
 {
-	int len = 0;
 	struct iio_ring_buffer *ring = dev_get_drvdata(dev);
 
-	if (ring->access.get_bytes_per_datum)
-		len = sprintf(buf, "%d\n",
-			      ring->access.get_bytes_per_datum(ring));
+	if (ring->access->get_bytes_per_datum)
+		return sprintf(buf, "%d\n",
+			       ring->access->get_bytes_per_datum(ring));
 
-	return len;
+	return 0;
 }
 EXPORT_SYMBOL(iio_read_ring_bytes_per_datum);
 
@@ -368,8 +483,8 @@
 		goto done;
 	}
 	if (requested_state) {
-		if (ring->preenable) {
-			ret = ring->preenable(dev_info);
+		if (ring->setup_ops->preenable) {
+			ret = ring->setup_ops->preenable(dev_info);
 			if (ret) {
 				printk(KERN_ERR
 				       "Buffer not started:"
@@ -377,8 +492,8 @@
 				goto error_ret;
 			}
 		}
-		if (ring->access.request_update) {
-			ret = ring->access.request_update(ring);
+		if (ring->access->request_update) {
+			ret = ring->access->request_update(ring);
 			if (ret) {
 				printk(KERN_INFO
 				       "Buffer not started:"
@@ -386,16 +501,16 @@
 				goto error_ret;
 			}
 		}
-		if (ring->access.mark_in_use)
-			ring->access.mark_in_use(ring);
+		if (ring->access->mark_in_use)
+			ring->access->mark_in_use(ring);
 		/* Definitely possible for devices to support both of these.*/
 		if (dev_info->modes & INDIO_RING_TRIGGERED) {
 			if (!dev_info->trig) {
 				printk(KERN_INFO
 				       "Buffer not started: no trigger\n");
 				ret = -EINVAL;
-				if (ring->access.unmark_in_use)
-					ring->access.unmark_in_use(ring);
+				if (ring->access->unmark_in_use)
+					ring->access->unmark_in_use(ring);
 				goto error_ret;
 			}
 			dev_info->currentmode = INDIO_RING_TRIGGERED;
@@ -406,32 +521,31 @@
 			goto error_ret;
 		}
 
-		if (ring->postenable) {
-
-			ret = ring->postenable(dev_info);
+		if (ring->setup_ops->postenable) {
+			ret = ring->setup_ops->postenable(dev_info);
 			if (ret) {
 				printk(KERN_INFO
 				       "Buffer not started:"
 				       "postenable failed\n");
-				if (ring->access.unmark_in_use)
-					ring->access.unmark_in_use(ring);
+				if (ring->access->unmark_in_use)
+					ring->access->unmark_in_use(ring);
 				dev_info->currentmode = previous_mode;
-				if (ring->postdisable)
-					ring->postdisable(dev_info);
+				if (ring->setup_ops->postdisable)
+					ring->setup_ops->postdisable(dev_info);
 				goto error_ret;
 			}
 		}
 	} else {
-		if (ring->predisable) {
-			ret = ring->predisable(dev_info);
+		if (ring->setup_ops->predisable) {
+			ret = ring->setup_ops->predisable(dev_info);
 			if (ret)
 				goto error_ret;
 		}
-		if (ring->access.unmark_in_use)
-			ring->access.unmark_in_use(ring);
+		if (ring->access->unmark_in_use)
+			ring->access->unmark_in_use(ring);
 		dev_info->currentmode = INDIO_DIRECT_MODE;
-		if (ring->postdisable) {
-			ret = ring->postdisable(dev_info);
+		if (ring->setup_ops->postdisable) {
+			ret = ring->setup_ops->postdisable(dev_info);
 			if (ret)
 				goto error_ret;
 		}
@@ -445,6 +559,7 @@
 	return ret;
 }
 EXPORT_SYMBOL(iio_store_ring_enable);
+
 ssize_t iio_show_ring_enable(struct device *dev,
 				    struct device_attribute *attr,
 				    char *buf)
@@ -455,89 +570,27 @@
 }
 EXPORT_SYMBOL(iio_show_ring_enable);
 
-ssize_t iio_scan_el_show(struct device *dev,
-			 struct device_attribute *attr,
-			 char *buf)
-{
-	int ret;
-	struct iio_ring_buffer *ring = dev_get_drvdata(dev);
-	struct iio_scan_el *this_el = to_iio_scan_el(attr);
-
-	ret = iio_scan_mask_query(ring, this_el->number);
-	if (ret < 0)
-		return ret;
-	return sprintf(buf, "%d\n", ret);
-}
-EXPORT_SYMBOL(iio_scan_el_show);
-
-ssize_t iio_scan_el_store(struct device *dev,
-			  struct device_attribute *attr,
-			  const char *buf,
-			  size_t len)
-{
-	int ret = 0;
-	bool state;
-	struct iio_ring_buffer *ring = dev_get_drvdata(dev);
-	struct iio_dev *indio_dev = ring->indio_dev;
-	struct iio_scan_el *this_el = to_iio_scan_el(attr);
-
-	state = !(buf[0] == '0');
-	mutex_lock(&indio_dev->mlock);
-	if (indio_dev->currentmode == INDIO_RING_TRIGGERED) {
-		ret = -EBUSY;
-		goto error_ret;
-	}
-	ret = iio_scan_mask_query(ring, this_el->number);
-	if (ret < 0)
-		goto error_ret;
-	if (!state && ret) {
-		ret = iio_scan_mask_clear(ring, this_el->number);
-		if (ret)
-			goto error_ret;
-	} else if (state && !ret) {
-		ret = iio_scan_mask_set(ring, this_el->number);
-		if (ret)
-			goto error_ret;
-	}
-	if (this_el->set_state)
-		ret = this_el->set_state(this_el, indio_dev, state);
-error_ret:
-	mutex_unlock(&indio_dev->mlock);
-
-	return ret ? ret : len;
-
-}
-EXPORT_SYMBOL(iio_scan_el_store);
-
-ssize_t iio_scan_el_ts_show(struct device *dev,
-			    struct device_attribute *attr,
-			    char *buf)
-{
-	struct iio_ring_buffer *ring = dev_get_drvdata(dev);
-	return sprintf(buf, "%d\n", ring->scan_timestamp);
-}
-EXPORT_SYMBOL(iio_scan_el_ts_show);
-
-ssize_t iio_scan_el_ts_store(struct device *dev,
-			     struct device_attribute *attr,
-			     const char *buf,
-			     size_t len)
+int iio_sw_ring_preenable(struct iio_dev *indio_dev)
 {
-	int ret = 0;
-	struct iio_ring_buffer *ring = dev_get_drvdata(dev);
-	struct iio_dev *indio_dev = ring->indio_dev;
-	bool state;
-	state = !(buf[0] == '0');
-	mutex_lock(&indio_dev->mlock);
-	if (indio_dev->currentmode == INDIO_RING_TRIGGERED) {
-		ret = -EBUSY;
-		goto error_ret;
-	}
-	ring->scan_timestamp = state;
-error_ret:
-	mutex_unlock(&indio_dev->mlock);
+	struct iio_ring_buffer *ring = indio_dev->ring;
+	size_t size;
+	dev_dbg(&indio_dev->dev, "%s\n", __func__);
+	/* Check if there are any scan elements enabled, if not fail*/
+	if (!(ring->scan_count || ring->scan_timestamp))
+		return -EINVAL;
+	if (ring->scan_timestamp)
+		if (ring->scan_count)
+			/* Timestamp (aligned to s64) and data */
+			size = (((ring->scan_count * ring->bpe)
+					+ sizeof(s64) - 1)
+				& ~(sizeof(s64) - 1))
+				+ sizeof(s64);
+		else /* Timestamp only  */
+			size = sizeof(s64);
+	else /* Data only */
+		size = ring->scan_count * ring->bpe;
+	ring->access->set_bytes_per_datum(ring, size);
 
-	return ret ? ret : len;
+	return 0;
 }
-EXPORT_SYMBOL(iio_scan_el_ts_store);
-
+EXPORT_SYMBOL(iio_sw_ring_preenable);
diff -druN linux-2.6.39-libre/drivers/staging/iio/industrialio-trigger.c linux-3.0-rc7-libre/drivers/staging/iio/industrialio-trigger.c
--- linux-2.6.39-libre/drivers/staging/iio/industrialio-trigger.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/iio/industrialio-trigger.c	2011-07-11 19:51:52.000000000 -0400
@@ -39,6 +39,19 @@
 static DEFINE_MUTEX(iio_trigger_list_lock);
 
 /**
+ * iio_trigger_read_name() - retrieve useful identifying name
+ **/
+static ssize_t iio_trigger_read_name(struct device *dev,
+				     struct device_attribute *attr,
+				     char *buf)
+{
+	struct iio_trigger *trig = dev_get_drvdata(dev);
+	return sprintf(buf, "%s\n", trig->name);
+}
+
+static DEVICE_ATTR(name, S_IRUGO, iio_trigger_read_name, NULL);
+
+/**
  * iio_trigger_register_sysfs() - create a device for this trigger
  * @trig_info:	the trigger
  *
@@ -46,20 +59,16 @@
  **/
 static int iio_trigger_register_sysfs(struct iio_trigger *trig_info)
 {
-	int ret = 0;
-
-	if (trig_info->control_attrs)
-		ret = sysfs_create_group(&trig_info->dev.kobj,
-					 trig_info->control_attrs);
-
-	return ret;
+	return sysfs_add_file_to_group(&trig_info->dev.kobj,
+				       &dev_attr_name.attr,
+				       NULL);
 }
 
 static void iio_trigger_unregister_sysfs(struct iio_trigger *trig_info)
 {
-	if (trig_info->control_attrs)
-		sysfs_remove_group(&trig_info->dev.kobj,
-				   trig_info->control_attrs);
+	sysfs_remove_file_from_group(&trig_info->dev.kobj,
+					   &dev_attr_name.attr,
+					   NULL);
 }
 
 
@@ -134,14 +143,8 @@
 
 void iio_trigger_unregister(struct iio_trigger *trig_info)
 {
-	struct iio_trigger *cursor;
-
 	mutex_lock(&iio_trigger_list_lock);
-	list_for_each_entry(cursor, &iio_trigger_list, list)
-		if (cursor == trig_info) {
-			list_del(&cursor->list);
-			break;
-		}
+	list_del(&trig_info->list);
 	mutex_unlock(&iio_trigger_list_lock);
 
 	iio_trigger_unregister_sysfs(trig_info);
@@ -151,47 +154,55 @@
 }
 EXPORT_SYMBOL(iio_trigger_unregister);
 
-struct iio_trigger *iio_trigger_find_by_name(const char *name, size_t len)
+static struct iio_trigger *iio_trigger_find_by_name(const char *name,
+						    size_t len)
 {
-	struct iio_trigger *trig;
-	bool found = false;
-
-	if (len && name[len - 1] == '\n')
-		len--;
+	struct iio_trigger *trig = NULL, *iter;
 
 	mutex_lock(&iio_trigger_list_lock);
-	list_for_each_entry(trig, &iio_trigger_list, list) {
-		if (strncmp(trig->name, name, len) == 0) {
-			found = true;
+	list_for_each_entry(iter, &iio_trigger_list, list)
+		if (sysfs_streq(iter->name, name)) {
+			trig = iter;
 			break;
 		}
-	}
 	mutex_unlock(&iio_trigger_list_lock);
 
-	return found ? trig : NULL;
+	return trig;
 }
-EXPORT_SYMBOL(iio_trigger_find_by_name);
 
 void iio_trigger_poll(struct iio_trigger *trig, s64 time)
 {
-	struct iio_poll_func *pf_cursor;
-
-	list_for_each_entry(pf_cursor, &trig->pollfunc_list, list) {
-		if (pf_cursor->poll_func_immediate) {
-			pf_cursor->poll_func_immediate(pf_cursor->private_data);
-			trig->use_count++;
-		}
-	}
-	list_for_each_entry(pf_cursor, &trig->pollfunc_list, list) {
-		if (pf_cursor->poll_func_main) {
-			pf_cursor->poll_func_main(pf_cursor->private_data,
-						  time);
-			trig->use_count++;
-		}
+	int i;
+	if (!trig->use_count) {
+		for (i = 0; i < CONFIG_IIO_CONSUMERS_PER_TRIGGER; i++)
+			if (trig->subirqs[i].enabled) {
+				trig->use_count++;
+				generic_handle_irq(trig->subirq_base + i);
+			}
 	}
 }
 EXPORT_SYMBOL(iio_trigger_poll);
 
+irqreturn_t iio_trigger_generic_data_rdy_poll(int irq, void *private)
+{
+	iio_trigger_poll(private, iio_get_time_ns());
+	return IRQ_HANDLED;
+}
+EXPORT_SYMBOL(iio_trigger_generic_data_rdy_poll);
+
+void iio_trigger_poll_chained(struct iio_trigger *trig, s64 time)
+{
+	int i;
+	if (!trig->use_count) {
+		for (i = 0; i < CONFIG_IIO_CONSUMERS_PER_TRIGGER; i++)
+			if (trig->subirqs[i].enabled) {
+				trig->use_count++;
+				handle_nested_irq(trig->subirq_base + i);
+			}
+	}
+}
+EXPORT_SYMBOL(iio_trigger_poll_chained);
+
 void iio_trigger_notify_done(struct iio_trigger *trig)
 {
 	trig->use_count--;
@@ -203,18 +214,6 @@
 }
 EXPORT_SYMBOL(iio_trigger_notify_done);
 
-/**
- * iio_trigger_read_name() - retrieve useful identifying name
- **/
-ssize_t iio_trigger_read_name(struct device *dev,
-			      struct device_attribute *attr,
-			      char *buf)
-{
-	struct iio_trigger *trig = dev_get_drvdata(dev);
-	return sprintf(buf, "%s\n", trig->name);
-}
-EXPORT_SYMBOL(iio_trigger_read_name);
-
 /* Trigger Consumer related functions */
 
 /* Complexity in here.  With certain triggers (datardy) an acknowledgement
@@ -228,18 +227,16 @@
 				 struct iio_poll_func *pf)
 {
 	int ret = 0;
-	unsigned long flags;
-
-	spin_lock_irqsave(&trig->pollfunc_list_lock, flags);
-	list_add_tail(&pf->list, &trig->pollfunc_list);
-	spin_unlock_irqrestore(&trig->pollfunc_list_lock, flags);
+	bool notinuse
+		= bitmap_empty(trig->pool, CONFIG_IIO_CONSUMERS_PER_TRIGGER);
 
-	if (trig->set_trigger_state)
+	pf->irq = iio_trigger_get_irq(trig);
+	ret = request_threaded_irq(pf->irq, pf->h, pf->thread,
+				   pf->type, pf->name,
+				   pf);
+	if (trig->set_trigger_state && notinuse)
 		ret = trig->set_trigger_state(trig, true);
-	if (ret) {
-		printk(KERN_ERR "set trigger state failed\n");
-		list_del(&pf->list);
-	}
+
 	return ret;
 }
 EXPORT_SYMBOL(iio_trigger_attach_poll_func);
@@ -247,41 +244,69 @@
 int iio_trigger_dettach_poll_func(struct iio_trigger *trig,
 				  struct iio_poll_func *pf)
 {
-	struct iio_poll_func *pf_cursor;
-	unsigned long flags;
-	int ret = -EINVAL;
-
-	spin_lock_irqsave(&trig->pollfunc_list_lock, flags);
-	list_for_each_entry(pf_cursor, &trig->pollfunc_list, list)
-		if (pf_cursor == pf) {
-			ret = 0;
-			break;
-		}
-	if (!ret) {
-		if (list_is_singular(&trig->pollfunc_list)
-		    && trig->set_trigger_state) {
-			spin_unlock_irqrestore(&trig->pollfunc_list_lock,
-					       flags);
-			/* May sleep hence cannot hold the spin lock */
-			ret = trig->set_trigger_state(trig, false);
-			if (ret)
-				goto error_ret;
-			spin_lock_irqsave(&trig->pollfunc_list_lock, flags);
-		}
-		/*
-		 * Now we can delete safe in the knowledge that, if this is
-		 * the last pollfunc then we have disabled the trigger anyway
-		 * and so nothing should be able to call the pollfunc.
-		 */
-		list_del(&pf_cursor->list);
+	int ret = 0;
+	bool no_other_users
+		= (bitmap_weight(trig->pool,
+				 CONFIG_IIO_CONSUMERS_PER_TRIGGER)
+		   == 1);
+	if (trig->set_trigger_state && no_other_users) {
+		ret = trig->set_trigger_state(trig, false);
+		if (ret)
+			goto error_ret;
 	}
-	spin_unlock_irqrestore(&trig->pollfunc_list_lock, flags);
+	iio_trigger_put_irq(trig, pf->irq);
+	free_irq(pf->irq, pf);
 
 error_ret:
 	return ret;
 }
 EXPORT_SYMBOL(iio_trigger_dettach_poll_func);
 
+irqreturn_t iio_pollfunc_store_time(int irq, void *p)
+{
+	struct iio_poll_func *pf = p;
+	pf->timestamp = iio_get_time_ns();
+	return IRQ_WAKE_THREAD;
+}
+EXPORT_SYMBOL(iio_pollfunc_store_time);
+
+struct iio_poll_func
+*iio_alloc_pollfunc(irqreturn_t (*h)(int irq, void *p),
+		    irqreturn_t (*thread)(int irq, void *p),
+		    int type,
+		    void *private,
+		    const char *fmt,
+		    ...)
+{
+	va_list vargs;
+	struct iio_poll_func *pf;
+
+	pf = kmalloc(sizeof *pf, GFP_KERNEL);
+	if (pf == NULL)
+		return NULL;
+	va_start(vargs, fmt);
+	pf->name = kvasprintf(GFP_KERNEL, fmt, vargs);
+	va_end(vargs);
+	if (pf->name == NULL) {
+		kfree(pf);
+		return NULL;
+	}
+	pf->h = h;
+	pf->thread = thread;
+	pf->type = type;
+	pf->private_data = private;
+
+	return pf;
+}
+EXPORT_SYMBOL_GPL(iio_alloc_pollfunc);
+
+void iio_dealloc_pollfunc(struct iio_poll_func *pf)
+{
+	kfree(pf->name);
+	kfree(pf);
+}
+EXPORT_SYMBOL_GPL(iio_dealloc_pollfunc);
+
 /**
  * iio_trigger_read_currrent() - trigger consumer sysfs query which trigger
  *
@@ -348,6 +373,23 @@
 static void iio_trig_release(struct device *device)
 {
 	struct iio_trigger *trig = to_iio_trigger(device);
+	int i;
+
+	if (trig->subirq_base) {
+		for (i = 0; i < CONFIG_IIO_CONSUMERS_PER_TRIGGER; i++) {
+			irq_modify_status(trig->subirq_base + i,
+					  IRQ_NOAUTOEN,
+					  IRQ_NOREQUEST | IRQ_NOPROBE);
+			irq_set_chip(trig->subirq_base + i,
+				     NULL);
+			irq_set_handler(trig->subirq_base + i,
+					NULL);
+		}
+
+		irq_free_descs(trig->subirq_base,
+			       CONFIG_IIO_CONSUMERS_PER_TRIGGER);
+	}
+	kfree(trig->name);
 	kfree(trig);
 	iio_put();
 }
@@ -356,18 +398,66 @@
 	.release = iio_trig_release,
 };
 
-struct iio_trigger *iio_allocate_trigger(void)
+static void iio_trig_subirqmask(struct irq_data *d)
 {
+	struct irq_chip *chip = irq_data_get_irq_chip(d);
+	struct iio_trigger *trig
+		= container_of(chip,
+			       struct iio_trigger, subirq_chip);
+	trig->subirqs[d->irq - trig->subirq_base].enabled = false;
+}
+
+static void iio_trig_subirqunmask(struct irq_data *d)
+{
+	struct irq_chip *chip = irq_data_get_irq_chip(d);
+	struct iio_trigger *trig
+		= container_of(chip,
+			       struct iio_trigger, subirq_chip);
+	trig->subirqs[d->irq - trig->subirq_base].enabled = true;
+}
+
+struct iio_trigger *iio_allocate_trigger(const char *fmt, ...)
+{
+	va_list vargs;
 	struct iio_trigger *trig;
 	trig = kzalloc(sizeof *trig, GFP_KERNEL);
 	if (trig) {
+		int i;
 		trig->dev.type = &iio_trig_type;
 		trig->dev.bus = &iio_bus_type;
 		device_initialize(&trig->dev);
 		dev_set_drvdata(&trig->dev, (void *)trig);
-		spin_lock_init(&trig->pollfunc_list_lock);
-		INIT_LIST_HEAD(&trig->list);
-		INIT_LIST_HEAD(&trig->pollfunc_list);
+
+		mutex_init(&trig->pool_lock);
+		trig->subirq_base
+			= irq_alloc_descs(-1, 0,
+					  CONFIG_IIO_CONSUMERS_PER_TRIGGER,
+					  0);
+		if (trig->subirq_base < 0) {
+			kfree(trig);
+			return NULL;
+		}
+		va_start(vargs, fmt);
+		trig->name = kvasprintf(GFP_KERNEL, fmt, vargs);
+		va_end(vargs);
+		if (trig->name == NULL) {
+			irq_free_descs(trig->subirq_base,
+				       CONFIG_IIO_CONSUMERS_PER_TRIGGER);
+			kfree(trig);
+			return NULL;
+		}
+		trig->subirq_chip.name = trig->name;
+		trig->subirq_chip.irq_mask = &iio_trig_subirqmask;
+		trig->subirq_chip.irq_unmask = &iio_trig_subirqunmask;
+		for (i = 0; i < CONFIG_IIO_CONSUMERS_PER_TRIGGER; i++) {
+			irq_set_chip(trig->subirq_base + i,
+				     &trig->subirq_chip);
+			irq_set_handler(trig->subirq_base + i,
+					&handle_simple_irq);
+			irq_modify_status(trig->subirq_base + i,
+					  IRQ_NOREQUEST | IRQ_NOAUTOEN,
+					  IRQ_NOPROBE);
+		}
 		iio_get();
 	}
 	return trig;
@@ -398,20 +488,6 @@
 }
 EXPORT_SYMBOL(iio_device_unregister_trigger_consumer);
 
-int iio_alloc_pollfunc(struct iio_dev *indio_dev,
-		       void (*immediate)(struct iio_dev *indio_dev),
-		       void (*main)(struct iio_dev *private_data, s64 time))
-{
-	indio_dev->pollfunc = kzalloc(sizeof(*indio_dev->pollfunc), GFP_KERNEL);
-	if (indio_dev->pollfunc == NULL)
-		return -ENOMEM;
-	indio_dev->pollfunc->poll_func_immediate = immediate;
-	indio_dev->pollfunc->poll_func_main = main;
-	indio_dev->pollfunc->private_data = indio_dev;
-	return 0;
-}
-EXPORT_SYMBOL(iio_alloc_pollfunc);
-
 int iio_triggered_ring_postenable(struct iio_dev *indio_dev)
 {
 	return indio_dev->trig
diff -druN linux-2.6.39-libre/drivers/staging/iio/Kconfig linux-3.0-rc7-libre/drivers/staging/iio/Kconfig
--- linux-2.6.39-libre/drivers/staging/iio/Kconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/iio/Kconfig	2011-07-11 19:51:52.000000000 -0400
@@ -4,18 +4,18 @@
 
 menuconfig IIO
 	tristate "Industrial I/O support"
-	depends on !S390
-	---help---
+	depends on GENERIC_HARDIRQS
+	help
 	  The industrial I/O subsystem provides a unified framework for
 	  drivers for many different types of embedded sensors using a
 	  number of different physical interfaces (i2c, spi, etc). See
-	  Documentation/industrialio for more information.
+	  drivers/staging/iio/Documentation for more information.
 if IIO
 
 config IIO_RING_BUFFER
-	bool "Enable ring buffer support within IIO"
+	bool "Enable buffer support within IIO"
 	help
-	  Provide core support for various ring buffer based data
+	  Provide core support for various buffer based data
 	  acquisition methods.
 
 if IIO_RING_BUFFER
@@ -48,6 +48,13 @@
 	  ring buffers.  The triggers are effectively a 'capture
 	  data now' interrupt.
 
+config IIO_CONSUMERS_PER_TRIGGER
+       int "Maximum number of consumers per trigger"
+       depends on IIO_TRIGGER
+       default "2"
+       help
+	This value controls the maximum number of consumers that a
+	given trigger may handle. Default is 2.
 
 source "drivers/staging/iio/accel/Kconfig"
 source "drivers/staging/iio/adc/Kconfig"
diff -druN linux-2.6.39-libre/drivers/staging/iio/kfifo_buf.c linux-3.0-rc7-libre/drivers/staging/iio/kfifo_buf.c
--- linux-2.6.39-libre/drivers/staging/iio/kfifo_buf.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/iio/kfifo_buf.c	2011-07-11 19:51:52.000000000 -0400
@@ -8,6 +8,8 @@
 
 #include "kfifo_buf.h"
 
+#define iio_to_kfifo(r) container_of(r, struct iio_kfifo, ring)
+
 static inline int __iio_allocate_kfifo(struct iio_kfifo *buf,
 				int bytes_per_datum, int length)
 {
@@ -18,7 +20,7 @@
 	return kfifo_alloc(&buf->kf, bytes_per_datum*length, GFP_KERNEL);
 }
 
-int iio_request_update_kfifo(struct iio_ring_buffer *r)
+static int iio_request_update_kfifo(struct iio_ring_buffer *r)
 {
 	int ret = 0;
 	struct iio_kfifo *buf = iio_to_kfifo(r);
@@ -37,31 +39,27 @@
 	mutex_unlock(&buf->use_lock);
 	return ret;
 }
-EXPORT_SYMBOL(iio_request_update_kfifo);
 
-void iio_mark_kfifo_in_use(struct iio_ring_buffer *r)
+static void iio_mark_kfifo_in_use(struct iio_ring_buffer *r)
 {
 	struct iio_kfifo *buf = iio_to_kfifo(r);
 	mutex_lock(&buf->use_lock);
 	buf->use_count++;
 	mutex_unlock(&buf->use_lock);
 }
-EXPORT_SYMBOL(iio_mark_kfifo_in_use);
 
-void iio_unmark_kfifo_in_use(struct iio_ring_buffer *r)
+static void iio_unmark_kfifo_in_use(struct iio_ring_buffer *r)
 {
 	struct iio_kfifo *buf = iio_to_kfifo(r);
 	mutex_lock(&buf->use_lock);
 	buf->use_count--;
 	mutex_unlock(&buf->use_lock);
 }
-EXPORT_SYMBOL(iio_unmark_kfifo_in_use);
 
-int iio_get_length_kfifo(struct iio_ring_buffer *r)
+static int iio_get_length_kfifo(struct iio_ring_buffer *r)
 {
 	return r->length;
 }
-EXPORT_SYMBOL(iio_get_length_kfifo);
 
 static inline void __iio_init_kfifo(struct iio_kfifo *kf)
 {
@@ -108,6 +106,7 @@
 	kf = kzalloc(sizeof *kf, GFP_KERNEL);
 	if (!kf)
 		return NULL;
+	kf->update_needed = true;
 	iio_ring_buffer_init(&kf->ring, indio_dev);
 	__iio_init_kfifo(kf);
 	kf->ring.dev.type = &iio_kfifo_type;
@@ -120,41 +119,37 @@
 }
 EXPORT_SYMBOL(iio_kfifo_allocate);
 
-int iio_get_bytes_per_datum_kfifo(struct iio_ring_buffer *r)
+static int iio_get_bytes_per_datum_kfifo(struct iio_ring_buffer *r)
 {
 	return r->bytes_per_datum;
 }
-EXPORT_SYMBOL(iio_get_bytes_per_datum_kfifo);
 
-int iio_set_bytes_per_datum_kfifo(struct iio_ring_buffer *r, size_t bpd)
+static int iio_set_bytes_per_datum_kfifo(struct iio_ring_buffer *r, size_t bpd)
 {
 	if (r->bytes_per_datum != bpd) {
 		r->bytes_per_datum = bpd;
-		if (r->access.mark_param_change)
-			r->access.mark_param_change(r);
+		if (r->access->mark_param_change)
+			r->access->mark_param_change(r);
 	}
 	return 0;
 }
-EXPORT_SYMBOL(iio_set_bytes_per_datum_kfifo);
 
-int iio_mark_update_needed_kfifo(struct iio_ring_buffer *r)
+static int iio_mark_update_needed_kfifo(struct iio_ring_buffer *r)
 {
 	struct iio_kfifo *kf = iio_to_kfifo(r);
 	kf->update_needed = true;
 	return 0;
 }
-EXPORT_SYMBOL(iio_mark_update_needed_kfifo);
 
-int iio_set_length_kfifo(struct iio_ring_buffer *r, int length)
+static int iio_set_length_kfifo(struct iio_ring_buffer *r, int length)
 {
 	if (r->length != length) {
 		r->length = length;
-		if (r->access.mark_param_change)
-			r->access.mark_param_change(r);
+		if (r->access->mark_param_change)
+			r->access->mark_param_change(r);
 	}
 	return 0;
 }
-EXPORT_SYMBOL(iio_set_length_kfifo);
 
 void iio_kfifo_free(struct iio_ring_buffer *r)
 {
@@ -163,7 +158,9 @@
 }
 EXPORT_SYMBOL(iio_kfifo_free);
 
-int iio_store_to_kfifo(struct iio_ring_buffer *r, u8 *data, s64 timestamp)
+static int iio_store_to_kfifo(struct iio_ring_buffer *r,
+			      u8 *data,
+			      s64 timestamp)
 {
 	int ret;
 	struct iio_kfifo *kf = iio_to_kfifo(r);
@@ -179,18 +176,30 @@
 	kfree(datal);
 	return 0;
 }
-EXPORT_SYMBOL(iio_store_to_kfifo);
 
-int iio_rip_kfifo(struct iio_ring_buffer *r,
-		size_t count, char __user *buf, int *deadoffset)
+static int iio_read_first_n_kfifo(struct iio_ring_buffer *r,
+			   size_t n, char __user *buf)
 {
 	int ret, copied;
 	struct iio_kfifo *kf = iio_to_kfifo(r);
 
-	*deadoffset = 0;
-	ret = kfifo_to_user(&kf->kf, buf, r->bytes_per_datum*count, &copied);
+	ret = kfifo_to_user(&kf->kf, buf, r->bytes_per_datum*n, &copied);
 
 	return copied;
 }
-EXPORT_SYMBOL(iio_rip_kfifo);
+
+const struct iio_ring_access_funcs kfifo_access_funcs = {
+	.mark_in_use = &iio_mark_kfifo_in_use,
+	.unmark_in_use = &iio_unmark_kfifo_in_use,
+	.store_to = &iio_store_to_kfifo,
+	.read_first_n = &iio_read_first_n_kfifo,
+	.mark_param_change = &iio_mark_update_needed_kfifo,
+	.request_update = &iio_request_update_kfifo,
+	.get_bytes_per_datum = &iio_get_bytes_per_datum_kfifo,
+	.set_bytes_per_datum = &iio_set_bytes_per_datum_kfifo,
+	.get_length = &iio_get_length_kfifo,
+	.set_length = &iio_set_length_kfifo,
+};
+EXPORT_SYMBOL(kfifo_access_funcs);
+
 MODULE_LICENSE("GPL");
diff -druN linux-2.6.39-libre/drivers/staging/iio/kfifo_buf.h linux-3.0-rc7-libre/drivers/staging/iio/kfifo_buf.h
--- linux-2.6.39-libre/drivers/staging/iio/kfifo_buf.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/iio/kfifo_buf.h	2011-07-11 19:51:52.000000000 -0400
@@ -11,45 +11,7 @@
 	struct mutex use_lock;
 };
 
-#define iio_to_kfifo(r) container_of(r, struct iio_kfifo, ring)
-
-int iio_create_kfifo(struct iio_ring_buffer **r);
-int iio_init_kfifo(struct iio_ring_buffer *r, struct iio_dev *indio_dev);
-void iio_exit_kfifo(struct iio_ring_buffer *r);
-void iio_free_kfifo(struct iio_ring_buffer *r);
-void iio_mark_kfifo_in_use(struct iio_ring_buffer *r);
-void iio_unmark_kfifo_in_use(struct iio_ring_buffer *r);
-
-int iio_store_to_kfifo(struct iio_ring_buffer *r, u8 *data, s64 timestamp);
-int iio_rip_kfifo(struct iio_ring_buffer *r,
-		size_t count,
-		char __user *buf,
-		int *dead_offset);
-
-int iio_request_update_kfifo(struct iio_ring_buffer *r);
-int iio_mark_update_needed_kfifo(struct iio_ring_buffer *r);
-
-int iio_get_bytes_per_datum_kfifo(struct iio_ring_buffer *r);
-int iio_set_bytes_per_datum_kfifo(struct iio_ring_buffer *r, size_t bpd);
-int iio_get_length_kfifo(struct iio_ring_buffer *r);
-int iio_set_length_kfifo(struct iio_ring_buffer *r, int length);
-
-static inline void iio_kfifo_register_funcs(struct iio_ring_access_funcs *ra)
-{
-	ra->mark_in_use = &iio_mark_kfifo_in_use;
-	ra->unmark_in_use = &iio_unmark_kfifo_in_use;
-
-	ra->store_to = &iio_store_to_kfifo;
-	ra->rip_lots = &iio_rip_kfifo;
-
-	ra->mark_param_change = &iio_mark_update_needed_kfifo;
-	ra->request_update = &iio_request_update_kfifo;
-
-	ra->get_bytes_per_datum = &iio_get_bytes_per_datum_kfifo;
-	ra->set_bytes_per_datum = &iio_set_bytes_per_datum_kfifo;
-	ra->get_length = &iio_get_length_kfifo;
-	ra->set_length = &iio_set_length_kfifo;
-};
+extern const struct iio_ring_access_funcs kfifo_access_funcs;
 
 struct iio_ring_buffer *iio_kfifo_allocate(struct iio_dev *indio_dev);
 void iio_kfifo_free(struct iio_ring_buffer *r);
diff -druN linux-2.6.39-libre/drivers/staging/iio/light/isl29018.c linux-3.0-rc7-libre/drivers/staging/iio/light/isl29018.c
--- linux-2.6.39-libre/drivers/staging/iio/light/isl29018.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/iio/light/isl29018.c	2011-07-11 19:51:52.000000000 -0400
@@ -402,16 +402,6 @@
 	return get_sensor_data(dev, buf, COMMMAND1_OPMODE_PROX_ONCE);
 }
 
-/* Read name */
-static ssize_t show_name(struct device *dev,
-		struct device_attribute *attr, char *buf)
-{
-	struct iio_dev *indio_dev = dev_get_drvdata(dev);
-	struct isl29018_chip *chip = indio_dev->dev_data;
-
-	return sprintf(buf, "%s\n", chip->client->name);
-}
-
 static IIO_DEVICE_ATTR(range, S_IRUGO | S_IWUSR, show_range, store_range, 0);
 static IIO_CONST_ATTR(range_available, "1000 4000 16000 64000");
 static IIO_CONST_ATTR(adc_resolution_available, "4 8 12 16");
@@ -424,12 +414,10 @@
 static IIO_DEVICE_ATTR(illuminance0_input, S_IRUGO, show_lux, NULL, 0);
 static IIO_DEVICE_ATTR(intensity_infrared_raw, S_IRUGO, show_ir, NULL, 0);
 static IIO_DEVICE_ATTR(proximity_raw, S_IRUGO, show_proxim_ir, NULL, 0);
-static IIO_DEVICE_ATTR(name, S_IRUGO, show_name, NULL, 0);
 
 #define ISL29018_DEV_ATTR(name) (&iio_dev_attr_##name.dev_attr.attr)
 #define ISL29018_CONST_ATTR(name) (&iio_const_attr_##name.dev_attr.attr)
 static struct attribute *isl29018_attributes[] = {
-	ISL29018_DEV_ATTR(name),
 	ISL29018_DEV_ATTR(range),
 	ISL29018_CONST_ATTR(range_available),
 	ISL29018_DEV_ATTR(adc_resolution),
@@ -467,6 +455,11 @@
 	return 0;
 }
 
+static const struct iio_info isl29108_info = {
+	.attrs = &isl29108_group,
+	.driver_module = THIS_MODULE,
+};
+
 static int __devinit isl29018_probe(struct i2c_client *client,
 			 const struct i2c_device_id *id)
 {
@@ -492,15 +485,15 @@
 	if (err)
 		goto exit_free;
 
-	chip->indio_dev = iio_allocate_device();
+	chip->indio_dev = iio_allocate_device(0);
 	if (!chip->indio_dev) {
 		dev_err(&client->dev, "iio allocation fails\n");
 		goto exit_free;
 	}
-	chip->indio_dev->attrs = &isl29108_group;
+	chip->indio_dev->info = &isl29108_info;
+	chip->indio_dev->name = id->name;
 	chip->indio_dev->dev.parent = &client->dev;
 	chip->indio_dev->dev_data = (void *)(chip);
-	chip->indio_dev->driver_module = THIS_MODULE;
 	chip->indio_dev->modes = INDIO_DIRECT_MODE;
 	err = iio_device_register(chip->indio_dev);
 	if (err) {
diff -druN linux-2.6.39-libre/drivers/staging/iio/light/Kconfig linux-3.0-rc7-libre/drivers/staging/iio/light/Kconfig
--- linux-2.6.39-libre/drivers/staging/iio/light/Kconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/iio/light/Kconfig	2011-07-11 19:51:52.000000000 -0400
@@ -1,18 +1,8 @@
-#
+\#
 # Light sensors
 #
 comment "Light sensors"
 
-config SENSORS_TSL2563
-	tristate "TAOS TSL256[0-3] ambient light sensor"
-	depends on I2C
-	help
-	 If you say yes here you get support for the Taos TSL2560,
-	 TSL2561, TSL2562 and TSL2563 ambient light sensors.
-
-	 This driver can also be built as a module.  If so, the module
-	 will be called tsl2563.
-
 config SENSORS_ISL29018
         tristate "ISL 29018 light and proximity sensor"
         depends on I2C
@@ -24,3 +14,19 @@
          in lux, proximity infrared sensing and normal infrared sensing.
          Data from sensor is accessible via sysfs.
 
+config SENSORS_TSL2563
+	tristate "TAOS TSL2560, TSL2561, TSL2562 and TSL2563 ambient light sensors"
+	depends on I2C
+	help
+	 If you say yes here you get support for the Taos TSL2560,
+	 TSL2561, TSL2562 and TSL2563 ambient light sensors.
+
+	 This driver can also be built as a module.  If so, the module
+	 will be called tsl2563.
+
+config TSL2583
+	tristate "TAOS TSL2580, TSL2581 and TSL2583 light-to-digital converters"
+	depends on I2C
+	help
+	 Provides support for the TAOS tsl2580, tsl2581 and tsl2583 devices.
+	 Access ALS data via iio, sysfs.
diff -druN linux-2.6.39-libre/drivers/staging/iio/light/Makefile linux-3.0-rc7-libre/drivers/staging/iio/light/Makefile
--- linux-2.6.39-libre/drivers/staging/iio/light/Makefile	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/iio/light/Makefile	2011-07-11 19:51:52.000000000 -0400
@@ -4,3 +4,4 @@
 
 obj-$(CONFIG_SENSORS_TSL2563)	+= tsl2563.o
 obj-$(CONFIG_SENSORS_ISL29018)	+= isl29018.o
+obj-$(CONFIG_TSL2583)	+= tsl2583.o
diff -druN linux-2.6.39-libre/drivers/staging/iio/light/tsl2563.c linux-3.0-rc7-libre/drivers/staging/iio/light/tsl2563.c
--- linux-2.6.39-libre/drivers/staging/iio/light/tsl2563.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/iio/light/tsl2563.c	2011-07-11 19:51:52.000000000 -0400
@@ -92,7 +92,7 @@
 	u16 max;
 };
 
-static struct tsl2563_gainlevel_coeff tsl2563_gainlevel_table[] = {
+static const struct tsl2563_gainlevel_coeff tsl2563_gainlevel_table[] = {
 	{
 		.gaintime	= TSL2563_TIMING_400MS | TSL2563_TIMING_GAIN16,
 		.min		= 0,
@@ -115,15 +115,12 @@
 struct tsl2563_chip {
 	struct mutex		lock;
 	struct i2c_client	*client;
-	struct iio_dev		*indio_dev;
 	struct delayed_work	poweroff_work;
 
-	struct work_struct	work_thresh;
-	s64			event_timestamp;
 	/* Remember state for suspend and resume functions */
 	pm_message_t		state;
 
-	struct tsl2563_gainlevel_coeff *gainlevel;
+	struct tsl2563_gainlevel_coeff const *gainlevel;
 
 	u16			low_thres;
 	u16			high_thres;
@@ -467,32 +464,6 @@
 /*                      Sysfs interface                         */
 /*--------------------------------------------------------------*/
 
-static ssize_t tsl2563_adc_show(struct device *dev,
-				struct device_attribute *attr, char *buf)
-{
-	struct iio_dev *indio_dev = dev_get_drvdata(dev);
-	struct tsl2563_chip *chip = indio_dev->dev_data;
-	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
-	int ret;
-
-	mutex_lock(&chip->lock);
-
-	ret = tsl2563_get_adc(chip);
-	if (ret)
-		goto out;
-
-	switch (this_attr->address) {
-	case 0:
-		ret = snprintf(buf, PAGE_SIZE, "%d\n", chip->data0);
-		break;
-	case 1:
-		ret = snprintf(buf, PAGE_SIZE, "%d\n", chip->data1);
-		break;
-	}
-out:
-	mutex_unlock(&chip->lock);
-	return ret;
-}
 
 /* Apply calibration coefficient to ADC count. */
 static u32 calib_adc(u32 adc, u32 calib)
@@ -505,237 +476,165 @@
 	return (u32) scaled;
 }
 
-static ssize_t tsl2563_lux_show(struct device *dev,
-				struct device_attribute *attr, char *buf)
+static int tsl2563_write_raw(struct iio_dev *indio_dev,
+			       struct iio_chan_spec const *chan,
+			       int val,
+			       int val2,
+			       long mask)
 {
-	struct iio_dev *indio_dev = dev_get_drvdata(dev);
-	struct tsl2563_chip *chip = indio_dev->dev_data;
-	u32 calib0, calib1;
-	int ret;
-
-	mutex_lock(&chip->lock);
-
-	ret = tsl2563_get_adc(chip);
-	if (ret)
-		goto out;
-
-	calib0 = calib_adc(chip->data0, chip->calib0) * chip->cover_comp_gain;
-	calib1 = calib_adc(chip->data1, chip->calib1) * chip->cover_comp_gain;
-
-	ret = snprintf(buf, PAGE_SIZE, "%d\n", adc_to_lux(calib0, calib1));
+	struct tsl2563_chip *chip = iio_priv(indio_dev);
 
-out:
-	mutex_unlock(&chip->lock);
-	return ret;
-}
+	if (chan->channel == 0)
+		chip->calib0 = calib_from_sysfs(val);
+	else
+		chip->calib1 = calib_from_sysfs(val);
 
-static ssize_t format_calib(char *buf, int len, u32 calib)
-{
-	return snprintf(buf, PAGE_SIZE, "%d\n", calib_to_sysfs(calib));
+	return 0;
 }
 
-static ssize_t tsl2563_calib_show(struct device *dev,
-				struct device_attribute *attr, char *buf)
+static int tsl2563_read_raw(struct iio_dev *indio_dev,
+			    struct iio_chan_spec const *chan,
+			    int *val,
+			    int *val2,
+			    long m)
 {
-	struct iio_dev *indio_dev = dev_get_drvdata(dev);
-	struct tsl2563_chip *chip = indio_dev->dev_data;
-	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
-	int ret;
+	int ret = -EINVAL;
+	u32 calib0, calib1;
+	struct tsl2563_chip *chip = iio_priv(indio_dev);
 
 	mutex_lock(&chip->lock);
-	switch (this_attr->address) {
+	switch (m) {
 	case 0:
-		ret = format_calib(buf, PAGE_SIZE, chip->calib0);
+		switch (chan->type) {
+		case IIO_LIGHT:
+			ret = tsl2563_get_adc(chip);
+			if (ret)
+				goto error_ret;
+			calib0 = calib_adc(chip->data0, chip->calib0) *
+				chip->cover_comp_gain;
+			calib1 = calib_adc(chip->data1, chip->calib1) *
+				chip->cover_comp_gain;
+			*val = adc_to_lux(calib0, calib1);
+			ret = IIO_VAL_INT;
+			break;
+		case IIO_INTENSITY:
+			ret = tsl2563_get_adc(chip);
+			if (ret)
+				goto error_ret;
+			if (chan->channel == 0)
+				*val = chip->data0;
+			else
+				*val = chip->data1;
+			ret = IIO_VAL_INT;
+			break;
+		default:
+			break;
+		}
 		break;
-	case 1:
-		ret = format_calib(buf, PAGE_SIZE, chip->calib1);
+
+	case (1 << IIO_CHAN_INFO_CALIBSCALE_SEPARATE):
+		if (chan->channel == 0)
+			*val = calib_to_sysfs(chip->calib0);
+		else
+			*val = calib_to_sysfs(chip->calib1);
+		ret = IIO_VAL_INT;
 		break;
 	default:
-		ret = -ENODEV;
-	}
-	mutex_unlock(&chip->lock);
-	return ret;
-}
-
-static ssize_t tsl2563_calib_store(struct device *dev,
-				struct device_attribute *attr,
-				const char *buf, size_t len)
-{
-	struct iio_dev *indio_dev = dev_get_drvdata(dev);
-	struct tsl2563_chip *chip = indio_dev->dev_data;
-	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
-	int value;
-	u32 calib;
-
-	if (1 != sscanf(buf, "%d", &value))
 		return -EINVAL;
-
-	calib = calib_from_sysfs(value);
-
-	switch (this_attr->address) {
-	case 0:
-		chip->calib0 = calib;
-		break;
-	case 1:
-		chip->calib1 = calib;
-		break;
 	}
 
-	return len;
-}
-
-static IIO_DEVICE_ATTR(intensity0_both_raw, S_IRUGO,
-		tsl2563_adc_show, NULL, 0);
-static IIO_DEVICE_ATTR(intensity1_ir_raw, S_IRUGO,
-		tsl2563_adc_show, NULL, 1);
-static DEVICE_ATTR(illuminance0_input, S_IRUGO, tsl2563_lux_show, NULL);
-static IIO_DEVICE_ATTR(intensity0_both_calibgain, S_IRUGO | S_IWUSR,
-		tsl2563_calib_show, tsl2563_calib_store, 0);
-static IIO_DEVICE_ATTR(intensity1_ir_calibgain, S_IRUGO | S_IWUSR,
-		tsl2563_calib_show, tsl2563_calib_store, 1);
-
-static ssize_t tsl2563_show_name(struct device *dev,
-				struct device_attribute *attr,
-				char *buf)
-{
-	struct iio_dev *indio_dev = dev_get_drvdata(dev);
-	struct tsl2563_chip *chip = indio_dev->dev_data;
-	return sprintf(buf, "%s\n", chip->client->name);
+error_ret:
+	mutex_unlock(&chip->lock);
+	return ret;
 }
 
-static DEVICE_ATTR(name, S_IRUGO, tsl2563_show_name, NULL);
-
-static struct attribute *tsl2563_attributes[] = {
-	&iio_dev_attr_intensity0_both_raw.dev_attr.attr,
-	&iio_dev_attr_intensity1_ir_raw.dev_attr.attr,
-	&dev_attr_illuminance0_input.attr,
-	&iio_dev_attr_intensity0_both_calibgain.dev_attr.attr,
-	&iio_dev_attr_intensity1_ir_calibgain.dev_attr.attr,
-	&dev_attr_name.attr,
-	NULL
-};
-
-static const struct attribute_group tsl2563_group = {
-	.attrs = tsl2563_attributes,
+static const struct iio_chan_spec tsl2563_channels[] = {
+	IIO_CHAN(IIO_LIGHT, 0, 1, 1, NULL, 0, 0, 0, 0, 0, {}, 0),
+	IIO_CHAN(IIO_INTENSITY, 1, 1, 0, "both", 0,
+		 (1 << IIO_CHAN_INFO_CALIBSCALE_SEPARATE), 0, 0, 0, {},
+		 IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_RISING) |
+		 IIO_EV_BIT(IIO_EV_TYPE_THRESH, IIO_EV_DIR_FALLING)),
+	IIO_CHAN(IIO_INTENSITY, 1, 1, 0, "ir", 1,
+		 (1 << IIO_CHAN_INFO_CALIBSCALE_SEPARATE), 0, 0, 0, {},
+		 0)
 };
 
-static ssize_t tsl2563_read_thresh(struct device *dev,
-			struct device_attribute *attr,
-			char *buf)
+static int tsl2563_read_thresh(struct iio_dev *indio_dev,
+				int event_code,
+				int *val)
 {
-	struct iio_dev *indio_dev = dev_get_drvdata(dev);
-	struct tsl2563_chip *chip = indio_dev->dev_data;
-	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
-	u16 val = 0;
-	switch (this_attr->address) {
-	case TSL2563_REG_HIGHLOW:
-		val = chip->high_thres;
+	struct tsl2563_chip *chip = iio_priv(indio_dev);
+
+	switch (IIO_EVENT_CODE_EXTRACT_DIR(event_code)) {
+	case IIO_EV_DIR_RISING:
+		*val = chip->high_thres;
 		break;
-	case TSL2563_REG_LOWLOW:
-		val = chip->low_thres;
+	case IIO_EV_DIR_FALLING:
+		*val = chip->low_thres;
 		break;
+	default:
+		return -EINVAL;
 	}
-	return snprintf(buf, PAGE_SIZE, "%d\n", val);
+
+	return 0;
 }
 
-static ssize_t tsl2563_write_thresh(struct device *dev,
-				struct device_attribute *attr,
-				const char *buf,
-				size_t len)
+static ssize_t tsl2563_write_thresh(struct iio_dev *indio_dev,
+				  int event_code,
+				  int val)
 {
-	struct iio_dev *indio_dev = dev_get_drvdata(dev);
-	struct tsl2563_chip *chip = indio_dev->dev_data;
-	struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
-	unsigned long val;
+	struct tsl2563_chip *chip = iio_priv(indio_dev);
 	int ret;
+	u8 address;
 
-	ret = strict_strtoul(buf, 10, &val);
-	if (ret)
-		return ret;
+	if (IIO_EVENT_CODE_EXTRACT_DIR(event_code) == IIO_EV_DIR_RISING)
+		address = TSL2563_REG_HIGHLOW;
+	else
+		address = TSL2563_REG_LOWLOW;
 	mutex_lock(&chip->lock);
-	ret = tsl2563_write(chip->client, this_attr->address, val & 0xFF);
+	ret = tsl2563_write(chip->client, address, val & 0xFF);
 	if (ret)
 		goto error_ret;
-	ret = tsl2563_write(chip->client, this_attr->address + 1,
+	ret = tsl2563_write(chip->client, address + 1,
 			(val >> 8) & 0xFF);
-	switch (this_attr->address) {
-	case TSL2563_REG_HIGHLOW:
+	if (IIO_EVENT_CODE_EXTRACT_DIR(event_code) == IIO_EV_DIR_RISING)
 		chip->high_thres = val;
-		break;
-	case TSL2563_REG_LOWLOW:
+	else
 		chip->low_thres = val;
-		break;
-	}
 
 error_ret:
 	mutex_unlock(&chip->lock);
 
-	return ret < 0 ? ret : len;
-}
-
-static IIO_DEVICE_ATTR(intensity0_both_raw_thresh_rising_value,
-		S_IRUGO | S_IWUSR,
-		tsl2563_read_thresh,
-		tsl2563_write_thresh,
-		TSL2563_REG_HIGHLOW);
-
-static IIO_DEVICE_ATTR(intensity0_both_raw_thresh_falling_value,
-		S_IRUGO | S_IWUSR,
-		tsl2563_read_thresh,
-		tsl2563_write_thresh,
-		TSL2563_REG_LOWLOW);
-
-static int tsl2563_int_th(struct iio_dev *dev_info,
-			int index,
-			s64 timestamp,
-			int not_test)
-{
-	struct tsl2563_chip *chip = dev_info->dev_data;
-
-	chip->event_timestamp = timestamp;
-	schedule_work(&chip->work_thresh);
-
-	return 0;
+	return ret;
 }
 
-static void tsl2563_int_bh(struct work_struct *work_s)
+static irqreturn_t tsl2563_event_handler(int irq, void *private)
 {
-	struct tsl2563_chip *chip
-		= container_of(work_s,
-			struct tsl2563_chip, work_thresh);
+	struct iio_dev *dev_info = private;
+	struct tsl2563_chip *chip = iio_priv(dev_info);
 	u8 cmd = TSL2563_CMD | TSL2563_CLEARINT;
 
-	iio_push_event(chip->indio_dev, 0,
+	iio_push_event(dev_info, 0,
 		       IIO_UNMOD_EVENT_CODE(IIO_EV_CLASS_LIGHT,
 					    0,
 					    IIO_EV_TYPE_THRESH,
 					    IIO_EV_DIR_EITHER),
-		       chip->event_timestamp);
+		       iio_get_time_ns());
 
-	/* reenable_irq */
-	enable_irq(chip->client->irq);
 	/* clear the interrupt and push the event */
 	i2c_master_send(chip->client, &cmd, sizeof(cmd));
-
+	return IRQ_HANDLED;
 }
 
-static ssize_t tsl2563_write_interrupt_config(struct device *dev,
-					struct device_attribute *attr,
-					const char *buf,
-					size_t len)
+static int tsl2563_write_interrupt_config(struct iio_dev *indio_dev,
+					int event_code,
+					int state)
 {
-	struct iio_dev *indio_dev = dev_get_drvdata(dev);
-	struct tsl2563_chip *chip = indio_dev->dev_data;
-	struct iio_event_attr *this_attr = to_iio_event_attr(attr);
-	int input, ret = 0;
+	struct tsl2563_chip *chip = iio_priv(indio_dev);
+	int ret = 0;
 
-	ret = sscanf(buf, "%d", &input);
-	if (ret != 1)
-		return -EINVAL;
 	mutex_lock(&chip->lock);
-	if (input && !(chip->intr & 0x30)) {
-		iio_add_event_to_list(this_attr->listel,
-				&indio_dev->interrupts[0]->ev_list);
+	if (state && !(chip->intr & 0x30)) {
 		chip->intr &= ~0x30;
 		chip->intr |= 0x10;
 		/* ensure the chip is actually on */
@@ -752,11 +651,9 @@
 		chip->int_enabled = true;
 	}
 
-	if (!input && (chip->intr & 0x30)) {
+	if (!state && (chip->intr & 0x30)) {
 		chip->intr |= ~0x30;
 		ret = tsl2563_write(chip->client, TSL2563_REG_INT, chip->intr);
-		iio_remove_event_from_list(this_attr->listel,
-					&indio_dev->interrupts[0]->ev_list);
 		chip->int_enabled = false;
 		/* now the interrupt is not enabled, we can go to sleep */
 		schedule_delayed_work(&chip->poweroff_work, 5 * HZ);
@@ -764,69 +661,64 @@
 out:
 	mutex_unlock(&chip->lock);
 
-	return (ret < 0) ? ret : len;
+	return ret;
 }
 
-static ssize_t tsl2563_read_interrupt_config(struct device *dev,
-					struct device_attribute *attr,
-					char *buf)
+static int tsl2563_read_interrupt_config(struct iio_dev *indio_dev,
+					   int event_code)
 {
-	struct iio_dev *indio_dev = dev_get_drvdata(dev);
-	struct tsl2563_chip *chip = indio_dev->dev_data;
-	int ret;
+	struct tsl2563_chip *chip = iio_priv(indio_dev);
 	u8 rxbuf;
-	ssize_t len;
+	int ret;
 
 	mutex_lock(&chip->lock);
-	ret = tsl2563_read(chip->client,
-			TSL2563_REG_INT,
-			&rxbuf,
-			sizeof(rxbuf));
+	ret = tsl2563_read(chip->client, TSL2563_REG_INT,
+			   &rxbuf, sizeof(rxbuf));
 	mutex_unlock(&chip->lock);
 	if (ret < 0)
 		goto error_ret;
-	len = snprintf(buf, PAGE_SIZE, "%d\n", !!(rxbuf & 0x30));
+	ret = !!(rxbuf & 0x30);
 error_ret:
 
-	return (ret < 0) ? ret : len;
+	return ret;
 }
 
-IIO_EVENT_ATTR(intensity0_both_thresh_en,
-	tsl2563_read_interrupt_config,
-	tsl2563_write_interrupt_config,
-	0,
-	tsl2563_int_th);
-
-static struct attribute *tsl2563_event_attributes[] = {
-	&iio_event_attr_intensity0_both_thresh_en.dev_attr.attr,
-	&iio_dev_attr_intensity0_both_raw_thresh_rising_value.dev_attr.attr,
-	&iio_dev_attr_intensity0_both_raw_thresh_falling_value.dev_attr.attr,
-	NULL,
-};
-
-static struct attribute_group tsl2563_event_attribute_group = {
-	.attrs = tsl2563_event_attributes,
-};
-
 /*--------------------------------------------------------------*/
 /*                      Probe, Attach, Remove                   */
 /*--------------------------------------------------------------*/
 static struct i2c_driver tsl2563_i2c_driver;
 
+static const struct iio_info tsl2563_info_no_irq = {
+	.driver_module = THIS_MODULE,
+};
+
+static const struct iio_info tsl2563_info = {
+	.driver_module = THIS_MODULE,
+	.num_interrupt_lines = 1,
+	.read_raw = &tsl2563_read_raw,
+	.write_raw = &tsl2563_write_raw,
+	.read_event_value = &tsl2563_read_thresh,
+	.write_event_value = &tsl2563_write_thresh,
+	.read_event_config = &tsl2563_read_interrupt_config,
+	.write_event_config = &tsl2563_write_interrupt_config,
+};
+
 static int __devinit tsl2563_probe(struct i2c_client *client,
 				const struct i2c_device_id *device_id)
 {
+	struct iio_dev *indio_dev;
 	struct tsl2563_chip *chip;
 	struct tsl2563_platform_data *pdata = client->dev.platform_data;
 	int err = 0;
 	int ret;
 	u8 id;
 
-	chip = kzalloc(sizeof(*chip), GFP_KERNEL);
-	if (!chip)
+	indio_dev = iio_allocate_device(sizeof(*chip));
+	if (!indio_dev)
 		return -ENOMEM;
 
-	INIT_WORK(&chip->work_thresh, tsl2563_int_bh);
+	chip = iio_priv(indio_dev);
+
 	i2c_set_clientdata(client, chip);
 	chip->client = client;
 
@@ -856,30 +748,25 @@
 		chip->cover_comp_gain = 1;
 
 	dev_info(&client->dev, "model %d, rev. %d\n", id >> 4, id & 0x0f);
-
-	chip->indio_dev = iio_allocate_device();
-	if (!chip->indio_dev)
-		goto fail1;
-	chip->indio_dev->attrs = &tsl2563_group;
-	chip->indio_dev->dev.parent = &client->dev;
-	chip->indio_dev->dev_data = (void *)(chip);
-	chip->indio_dev->driver_module = THIS_MODULE;
-	chip->indio_dev->modes = INDIO_DIRECT_MODE;
-	if (client->irq) {
-		chip->indio_dev->num_interrupt_lines = 1;
-		chip->indio_dev->event_attrs
-			= &tsl2563_event_attribute_group;
-	}
-	ret = iio_device_register(chip->indio_dev);
+	indio_dev->name = client->name;
+	indio_dev->channels = tsl2563_channels;
+	indio_dev->num_channels = ARRAY_SIZE(tsl2563_channels);
+	indio_dev->dev.parent = &client->dev;
+	indio_dev->modes = INDIO_DIRECT_MODE;
+	if (client->irq)
+		indio_dev->info = &tsl2563_info;
+	else
+		indio_dev->info = &tsl2563_info_no_irq;
+	ret = iio_device_register(indio_dev);
 	if (ret)
 		goto fail1;
-
 	if (client->irq) {
-		ret = iio_register_interrupt_line(client->irq,
-						chip->indio_dev,
-						0,
-						IRQF_TRIGGER_RISING,
-						client->name);
+		ret = request_threaded_irq(client->irq,
+					   NULL,
+					   &tsl2563_event_handler,
+					   IRQF_TRIGGER_RISING | IRQF_ONESHOT,
+					   "tsl2563_event",
+					   indio_dev);
 		if (ret)
 			goto fail2;
 	}
@@ -894,9 +781,9 @@
 	return 0;
 fail3:
 	if (client->irq)
-		iio_unregister_interrupt_line(chip->indio_dev, 0);
+		free_irq(client->irq, indio_dev);
 fail2:
-	iio_device_unregister(chip->indio_dev);
+	iio_device_unregister(indio_dev);
 fail1:
 	kfree(chip);
 	return err;
@@ -905,6 +792,7 @@
 static int tsl2563_remove(struct i2c_client *client)
 {
 	struct tsl2563_chip *chip = i2c_get_clientdata(client);
+	struct iio_dev *indio_dev = iio_priv_to_dev(chip);
 	if (!chip->int_enabled)
 		cancel_delayed_work(&chip->poweroff_work);
 	/* Ensure that interrupts are disabled - then flush any bottom halves */
@@ -913,10 +801,9 @@
 	flush_scheduled_work();
 	tsl2563_set_power(chip, 0);
 	if (client->irq)
-		iio_unregister_interrupt_line(chip->indio_dev, 0);
-	iio_device_unregister(chip->indio_dev);
+		free_irq(client->irq, indio_dev);
+	iio_device_unregister(indio_dev);
 
-	kfree(chip);
 	return 0;
 }
 
diff -druN linux-2.6.39-libre/drivers/staging/iio/light/tsl2583.c linux-3.0-rc7-libre/drivers/staging/iio/light/tsl2583.c
--- linux-2.6.39-libre/drivers/staging/iio/light/tsl2583.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/staging/iio/light/tsl2583.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,964 @@
+/*
+ * Device driver for monitoring ambient light intensity (lux)
+ * within the TAOS tsl258x family of devices (tsl2580, tsl2581).
+ *
+ * Copyright (c) 2011, TAOS 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA	02110-1301, USA.
+ */
+
+#include <linux/kernel.h>
+#include <linux/i2c.h>
+#include <linux/errno.h>
+#include <linux/delay.h>
+#include <linux/string.h>
+#include <linux/mutex.h>
+#include <linux/unistd.h>
+#include <linux/slab.h>
+#include "../iio.h"
+
+#define TSL258X_MAX_DEVICE_REGS		32
+
+/* Triton register offsets */
+#define	TSL258X_REG_MAX		8
+
+/* Device Registers and Masks */
+#define TSL258X_CNTRL			0x00
+#define TSL258X_ALS_TIME		0X01
+#define TSL258X_INTERRUPT		0x02
+#define TSL258X_GAIN			0x07
+#define TSL258X_REVID			0x11
+#define TSL258X_CHIPID			0x12
+#define TSL258X_ALS_CHAN0LO		0x14
+#define TSL258X_ALS_CHAN0HI		0x15
+#define TSL258X_ALS_CHAN1LO		0x16
+#define TSL258X_ALS_CHAN1HI		0x17
+#define TSL258X_TMR_LO			0x18
+#define TSL258X_TMR_HI			0x19
+
+/* tsl2583 cmd reg masks */
+#define TSL258X_CMD_REG			0x80
+#define TSL258X_CMD_SPL_FN		0x60
+#define TSL258X_CMD_ALS_INT_CLR	0X01
+
+/* tsl2583 cntrl reg masks */
+#define TSL258X_CNTL_ADC_ENBL	0x02
+#define TSL258X_CNTL_PWR_ON		0x01
+
+/* tsl2583 status reg masks */
+#define TSL258X_STA_ADC_VALID	0x01
+#define TSL258X_STA_ADC_INTR	0x10
+
+/* Lux calculation constants */
+#define	TSL258X_LUX_CALC_OVER_FLOW		65535
+
+enum {
+	TSL258X_CHIP_UNKNOWN = 0,
+	TSL258X_CHIP_WORKING = 1,
+	TSL258X_CHIP_SUSPENDED = 2
+} TSL258X_CHIP_WORKING_STATUS;
+
+/* Per-device data */
+struct taos_als_info {
+	u16 als_ch0;
+	u16 als_ch1;
+	u16 lux;
+};
+
+struct taos_settings {
+	int als_time;
+	int als_gain;
+	int als_gain_trim;
+	int als_cal_target;
+};
+
+struct tsl2583_chip {
+	struct mutex als_mutex;
+	struct i2c_client *client;
+	struct iio_dev *iio_dev;
+	struct taos_als_info als_cur_info;
+	struct taos_settings taos_settings;
+	int als_time_scale;
+	int als_saturation;
+	int taos_chip_status;
+	u8 taos_config[8];
+};
+
+/*
+ * Initial values for device - this values can/will be changed by driver.
+ * and applications as needed.
+ * These values are dynamic.
+ */
+static const u8 taos_config[8] = {
+		0x00, 0xee, 0x00, 0x03, 0x00, 0xFF, 0xFF, 0x00
+}; /*	cntrl atime intC  Athl0 Athl1 Athh0 Athh1 gain */
+
+struct taos_lux {
+	unsigned int ratio;
+	unsigned int ch0;
+	unsigned int ch1;
+};
+
+/* This structure is intentionally large to accommodate updates via sysfs. */
+/* Sized to 11 = max 10 segments + 1 termination segment */
+/* Assumption is is one and only one type of glass used  */
+struct taos_lux taos_device_lux[11] = {
+	{  9830,  8520, 15729 },
+	{ 12452, 10807, 23344 },
+	{ 14746,  6383, 11705 },
+	{ 17695,  4063,  6554 },
+};
+
+struct gainadj {
+	s16 ch0;
+	s16 ch1;
+};
+
+/* Index = (0 - 3) Used to validate the gain selection index */
+static const struct gainadj gainadj[] = {
+	{ 1, 1 },
+	{ 8, 8 },
+	{ 16, 16 },
+	{ 107, 115 }
+};
+
+/*
+ * Provides initial operational parameter defaults.
+ * These defaults may be changed through the device's sysfs files.
+ */
+static void taos_defaults(struct tsl2583_chip *chip)
+{
+	/* Operational parameters */
+	chip->taos_settings.als_time = 100;
+	/* must be a multiple of 50mS */
+	chip->taos_settings.als_gain = 0;
+	/* this is actually an index into the gain table */
+	/* assume clear glass as default */
+	chip->taos_settings.als_gain_trim = 1000;
+	/* default gain trim to account for aperture effects */
+	chip->taos_settings.als_cal_target = 130;
+	/* Known external ALS reading used for calibration */
+}
+
+/*
+ * Read a number of bytes starting at register (reg) location.
+ * Return 0, or i2c_smbus_write_byte ERROR code.
+ */
+static int
+taos_i2c_read(struct i2c_client *client, u8 reg, u8 *val, unsigned int len)
+{
+	int ret;
+	int i;
+
+	for (i = 0; i < len; i++) {
+		/* select register to write */
+		ret = i2c_smbus_write_byte(client, (TSL258X_CMD_REG | reg));
+		if (ret < 0) {
+			dev_err(&client->dev, "taos_i2c_read failed to write"
+				" register %x\n", reg);
+			return ret;
+		}
+		/* read the data */
+		*val = i2c_smbus_read_byte(client);
+		val++;
+		reg++;
+	}
+	return 0;
+}
+
+/*
+ * Reads and calculates current lux value.
+ * The raw ch0 and ch1 values of the ambient light sensed in the last
+ * integration cycle are read from the device.
+ * Time scale factor array values are adjusted based on the integration time.
+ * The raw values are multiplied by a scale factor, and device gain is obtained
+ * using gain index. Limit checks are done next, then the ratio of a multiple
+ * of ch1 value, to the ch0 value, is calculated. The array taos_device_lux[]
+ * declared above is then scanned to find the first ratio value that is just
+ * above the ratio we just calculated. The ch0 and ch1 multiplier constants in
+ * the array are then used along with the time scale factor array values, to
+ * calculate the lux.
+ */
+static int taos_get_lux(struct i2c_client *client)
+{
+	u16 ch0, ch1; /* separated ch0/ch1 data from device */
+	u32 lux; /* raw lux calculated from device data */
+	u32 ratio;
+	u8 buf[5];
+	struct taos_lux *p;
+	struct tsl2583_chip *chip = i2c_get_clientdata(client);
+	int i, ret;
+	u32 ch0lux = 0;
+	u32 ch1lux = 0;
+
+	if (mutex_trylock(&chip->als_mutex) == 0) {
+		dev_info(&client->dev, "taos_get_lux device is busy\n");
+		return chip->als_cur_info.lux; /* busy, so return LAST VALUE */
+	}
+
+	if (chip->taos_chip_status != TSL258X_CHIP_WORKING) {
+		/* device is not enabled */
+		dev_err(&client->dev, "taos_get_lux device is not enabled\n");
+		ret = -EBUSY ;
+		goto out_unlock;
+	}
+
+	ret = taos_i2c_read(client, (TSL258X_CMD_REG), &buf[0], 1);
+	if (ret < 0) {
+		dev_err(&client->dev, "taos_get_lux failed to read CMD_REG\n");
+		goto out_unlock;
+	}
+	/* is data new & valid */
+	if (!(buf[0] & TSL258X_STA_ADC_INTR)) {
+		dev_err(&client->dev, "taos_get_lux data not valid\n");
+		ret = chip->als_cur_info.lux; /* return LAST VALUE */
+		goto out_unlock;
+	}
+
+	for (i = 0; i < 4; i++) {
+		int reg = TSL258X_CMD_REG | (TSL258X_ALS_CHAN0LO + i);
+		ret = taos_i2c_read(client, reg, &buf[i], 1);
+		if (ret < 0) {
+			dev_err(&client->dev, "taos_get_lux failed to read"
+				" register %x\n", reg);
+			goto out_unlock;
+		}
+	}
+
+	/* clear status, really interrupt status (interrupts are off), but
+	 * we use the bit anyway - don't forget 0x80 - this is a command*/
+	ret = i2c_smbus_write_byte(client,
+	(TSL258X_CMD_REG | TSL258X_CMD_SPL_FN | TSL258X_CMD_ALS_INT_CLR));
+
+	if (ret < 0) {
+		dev_err(&client->dev,
+			"taos_i2c_write_command failed in taos_get_lux, err = %d\n",
+			ret);
+		goto out_unlock; /* have no data, so return failure */
+	}
+
+	/* extract ALS/lux data */
+	ch0 = le16_to_cpup((const __le16 *)&buf[0]);
+	ch1 = le16_to_cpup((const __le16 *)&buf[2]);
+
+	chip->als_cur_info.als_ch0 = ch0;
+	chip->als_cur_info.als_ch1 = ch1;
+
+	if ((ch0 >= chip->als_saturation) || (ch1 >= chip->als_saturation))
+		goto return_max;
+
+	if (ch0 == 0) {
+		/* have no data, so return LAST VALUE */
+		ret = chip->als_cur_info.lux = 0;
+		goto out_unlock;
+	}
+	/* calculate ratio */
+	ratio = (ch1 << 15) / ch0;
+	/* convert to unscaled lux using the pointer to the table */
+	for (p = (struct taos_lux *) taos_device_lux;
+	     p->ratio != 0 && p->ratio < ratio; p++)
+		;
+
+	if (p->ratio == 0) {
+		lux = 0;
+	} else {
+		ch0lux = ((ch0 * p->ch0) +
+			  (gainadj[chip->taos_settings.als_gain].ch0 >> 1))
+			 / gainadj[chip->taos_settings.als_gain].ch0;
+		ch1lux = ((ch1 * p->ch1) +
+			  (gainadj[chip->taos_settings.als_gain].ch1 >> 1))
+			 / gainadj[chip->taos_settings.als_gain].ch1;
+		lux = ch0lux - ch1lux;
+	}
+
+	/* note: lux is 31 bit max at this point */
+	if (ch1lux > ch0lux) {
+		dev_dbg(&client->dev, "No Data - Return last value\n");
+		ret = chip->als_cur_info.lux = 0;
+		goto out_unlock;
+	}
+
+	/* adjust for active time scale */
+	if (chip->als_time_scale == 0)
+		lux = 0;
+	else
+		lux = (lux + (chip->als_time_scale >> 1)) /
+			chip->als_time_scale;
+
+	/* adjust for active gain scale */
+	lux >>= 13; /* tables have factor of 8192 builtin for accuracy */
+	lux = (lux * chip->taos_settings.als_gain_trim + 500) / 1000;
+	if (lux > TSL258X_LUX_CALC_OVER_FLOW) { /* check for overflow */
+return_max:
+		lux = TSL258X_LUX_CALC_OVER_FLOW;
+	}
+
+	/* Update the structure with the latest VALID lux. */
+	chip->als_cur_info.lux = lux;
+	ret = lux;
+
+out_unlock:
+	mutex_unlock(&chip->als_mutex);
+	return ret;
+}
+
+/*
+ * Obtain single reading and calculate the als_gain_trim (later used
+ * to derive actual lux).
+ * Return updated gain_trim value.
+ */
+int taos_als_calibrate(struct i2c_client *client)
+{
+	struct tsl2583_chip *chip = i2c_get_clientdata(client);
+	u8 reg_val;
+	unsigned int gain_trim_val;
+	int ret;
+	int lux_val;
+
+	ret = i2c_smbus_write_byte(client, (TSL258X_CMD_REG | TSL258X_CNTRL));
+	if (ret < 0) {
+		dev_err(&client->dev,
+			"taos_als_calibrate failed to reach the CNTRL register, ret=%d\n",
+			ret);
+		return ret;
+	}
+
+	reg_val = i2c_smbus_read_byte(client);
+	if ((reg_val & (TSL258X_CNTL_ADC_ENBL | TSL258X_CNTL_PWR_ON))
+			!= (TSL258X_CNTL_ADC_ENBL | TSL258X_CNTL_PWR_ON)) {
+		dev_err(&client->dev,
+			"taos_als_calibrate failed: device not powered on with ADC enabled\n");
+		return -1;
+	}
+
+	ret = i2c_smbus_write_byte(client, (TSL258X_CMD_REG | TSL258X_CNTRL));
+	if (ret < 0) {
+		dev_err(&client->dev,
+			"taos_als_calibrate failed to reach the STATUS register, ret=%d\n",
+			ret);
+		return ret;
+	}
+	reg_val = i2c_smbus_read_byte(client);
+
+	if ((reg_val & TSL258X_STA_ADC_VALID) != TSL258X_STA_ADC_VALID) {
+		dev_err(&client->dev,
+			"taos_als_calibrate failed: STATUS - ADC not valid.\n");
+		return -ENODATA;
+	}
+	lux_val = taos_get_lux(client);
+	if (lux_val < 0) {
+		dev_err(&client->dev, "taos_als_calibrate failed to get lux\n");
+		return lux_val;
+	}
+	gain_trim_val = (unsigned int) (((chip->taos_settings.als_cal_target)
+			* chip->taos_settings.als_gain_trim) / lux_val);
+
+	if ((gain_trim_val < 250) || (gain_trim_val > 4000)) {
+		dev_err(&client->dev,
+			"taos_als_calibrate failed: trim_val of %d is out of range\n",
+			gain_trim_val);
+		return -ENODATA;
+	}
+	chip->taos_settings.als_gain_trim = (int) gain_trim_val;
+
+	return (int) gain_trim_val;
+}
+
+/*
+ * Turn the device on.
+ * Configuration must be set before calling this function.
+ */
+static int taos_chip_on(struct i2c_client *client)
+{
+	int i;
+	int ret = 0;
+	u8 *uP;
+	u8 utmp;
+	int als_count;
+	int als_time;
+	struct tsl2583_chip *chip = i2c_get_clientdata(client);
+
+	/* and make sure we're not already on */
+	if (chip->taos_chip_status == TSL258X_CHIP_WORKING) {
+		/* if forcing a register update - turn off, then on */
+		dev_info(&client->dev, "device is already enabled\n");
+		return   -EINVAL;
+	}
+
+	/* determine als integration regster */
+	als_count = (chip->taos_settings.als_time * 100 + 135) / 270;
+	if (als_count == 0)
+		als_count = 1; /* ensure at least one cycle */
+
+	/* convert back to time (encompasses overrides) */
+	als_time = (als_count * 27 + 5) / 10;
+	chip->taos_config[TSL258X_ALS_TIME] = 256 - als_count;
+
+	/* Set the gain based on taos_settings struct */
+	chip->taos_config[TSL258X_GAIN] = chip->taos_settings.als_gain;
+
+	/* set chip struct re scaling and saturation */
+	chip->als_saturation = als_count * 922; /* 90% of full scale */
+	chip->als_time_scale = (als_time + 25) / 50;
+
+	/* TSL258x Specific power-on / adc enable sequence
+	 * Power on the device 1st. */
+	utmp = TSL258X_CNTL_PWR_ON;
+	ret = i2c_smbus_write_byte_data(client,
+		TSL258X_CMD_REG | TSL258X_CNTRL, utmp);
+	if (ret < 0) {
+		dev_err(&client->dev, "taos_chip_on failed on CNTRL reg.\n");
+		return -1;
+	}
+
+	/* Use the following shadow copy for our delay before enabling ADC.
+	 * Write all the registers. */
+	for (i = 0, uP = chip->taos_config; i < TSL258X_REG_MAX; i++) {
+		ret = i2c_smbus_write_byte_data(client, TSL258X_CMD_REG + i,
+						*uP++);
+		if (ret < 0) {
+			dev_err(&client->dev,
+				"taos_chip_on failed on reg %d.\n", i);
+			return -1;
+		}
+	}
+
+	msleep(3);
+	/* NOW enable the ADC
+	 * initialize the desired mode of operation */
+	utmp = TSL258X_CNTL_PWR_ON | TSL258X_CNTL_ADC_ENBL;
+	ret = i2c_smbus_write_byte_data(client, TSL258X_CMD_REG | TSL258X_CNTRL,
+					utmp);
+	if (ret < 0) {
+		dev_err(&client->dev, "taos_chip_on failed on 2nd CTRL reg.\n");
+		return -1;
+	}
+	chip->taos_chip_status = TSL258X_CHIP_WORKING;
+
+	return ret;
+}
+
+static int taos_chip_off(struct i2c_client *client)
+{
+	struct tsl2583_chip *chip = i2c_get_clientdata(client);
+	int ret;
+
+	/* turn device off */
+	chip->taos_chip_status = TSL258X_CHIP_SUSPENDED;
+	ret = i2c_smbus_write_byte_data(client, TSL258X_CMD_REG | TSL258X_CNTRL,
+					0x00);
+	return ret;
+}
+
+/* Sysfs Interface Functions */
+static ssize_t taos_device_id(struct device *dev,
+struct device_attribute *attr, char *buf)
+{
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct tsl2583_chip *chip = indio_dev->dev_data;
+
+	return sprintf(buf, "%s\n", chip->client->name);
+}
+
+static ssize_t taos_power_state_show(struct device *dev,
+	struct device_attribute *attr, char *buf)
+{
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct tsl2583_chip *chip = indio_dev->dev_data;
+
+	return sprintf(buf, "%d\n", chip->taos_chip_status);
+}
+
+static ssize_t taos_power_state_store(struct device *dev,
+	struct device_attribute *attr, const char *buf, size_t len)
+{
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct tsl2583_chip *chip = indio_dev->dev_data;
+	unsigned long value;
+
+	if (strict_strtoul(buf, 0, &value))
+		return -EINVAL;
+
+	if (value == 0)
+		taos_chip_off(chip->client);
+	else
+		taos_chip_on(chip->client);
+
+	return len;
+}
+
+static ssize_t taos_gain_show(struct device *dev,
+	struct device_attribute *attr, char *buf)
+{
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct tsl2583_chip *chip = indio_dev->dev_data;
+	char gain[4] = {0};
+
+	switch (chip->taos_settings.als_gain) {
+	case 0:
+		strcpy(gain, "001");
+		break;
+	case 1:
+		strcpy(gain, "008");
+		break;
+	case 2:
+		strcpy(gain, "016");
+		break;
+	case 3:
+		strcpy(gain, "111");
+		break;
+	}
+
+	return sprintf(buf, "%s\n", gain);
+}
+
+static ssize_t taos_gain_store(struct device *dev,
+	struct device_attribute *attr, const char *buf, size_t len)
+{
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct tsl2583_chip *chip = indio_dev->dev_data;
+	unsigned long value;
+
+	if (strict_strtoul(buf, 0, &value))
+		return -EINVAL;
+
+	switch (value) {
+	case 1:
+		chip->taos_settings.als_gain = 0;
+		break;
+	case 8:
+		chip->taos_settings.als_gain = 1;
+		break;
+	case 16:
+		chip->taos_settings.als_gain = 2;
+		break;
+	case 111:
+		chip->taos_settings.als_gain = 3;
+		break;
+	default:
+		dev_err(dev, "Invalid Gain Index (must be 1,8,16,111)\n");
+		return -1;
+	}
+
+	return len;
+}
+
+static ssize_t taos_gain_available_show(struct device *dev,
+	struct device_attribute *attr, char *buf)
+{
+	return sprintf(buf, "%s\n", "1 8 16 111");
+}
+
+static ssize_t taos_als_time_show(struct device *dev,
+	struct device_attribute *attr, char *buf)
+{
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct tsl2583_chip *chip = indio_dev->dev_data;
+
+	return sprintf(buf, "%d\n", chip->taos_settings.als_time);
+}
+
+static ssize_t taos_als_time_store(struct device *dev,
+	struct device_attribute *attr, const char *buf, size_t len)
+{
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct tsl2583_chip *chip = indio_dev->dev_data;
+	unsigned long value;
+
+	if (strict_strtoul(buf, 0, &value))
+		return -EINVAL;
+
+	if ((value < 50) || (value > 650))
+		return -EINVAL;
+
+	if (value % 50)
+		return -EINVAL;
+
+	 chip->taos_settings.als_time = value;
+
+	return len;
+}
+
+static ssize_t taos_als_time_available_show(struct device *dev,
+	struct device_attribute *attr, char *buf)
+{
+	return sprintf(buf, "%s\n",
+		"50 100 150 200 250 300 350 400 450 500 550 600 650");
+}
+
+static ssize_t taos_als_trim_show(struct device *dev,
+	struct device_attribute *attr, char *buf)
+{
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct tsl2583_chip *chip = indio_dev->dev_data;
+
+	return sprintf(buf, "%d\n", chip->taos_settings.als_gain_trim);
+}
+
+static ssize_t taos_als_trim_store(struct device *dev,
+	struct device_attribute *attr, const char *buf, size_t len)
+{
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct tsl2583_chip *chip = indio_dev->dev_data;
+	unsigned long value;
+
+	if (strict_strtoul(buf, 0, &value))
+		return -EINVAL;
+
+	if (value)
+		chip->taos_settings.als_gain_trim = value;
+
+	return len;
+}
+
+static ssize_t taos_als_cal_target_show(struct device *dev,
+	struct device_attribute *attr, char *buf)
+{
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct tsl2583_chip *chip = indio_dev->dev_data;
+
+	return sprintf(buf, "%d\n", chip->taos_settings.als_cal_target);
+}
+
+static ssize_t taos_als_cal_target_store(struct device *dev,
+	struct device_attribute *attr, const char *buf, size_t len)
+{
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct tsl2583_chip *chip = indio_dev->dev_data;
+	unsigned long value;
+
+	if (strict_strtoul(buf, 0, &value))
+		return -EINVAL;
+
+	if (value)
+		chip->taos_settings.als_cal_target = value;
+
+	return len;
+}
+
+static ssize_t taos_lux_show(struct device *dev, struct device_attribute *attr,
+	char *buf)
+{
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct tsl2583_chip *chip = indio_dev->dev_data;
+	int lux;
+
+	lux = taos_get_lux(chip->client);
+
+	return sprintf(buf, "%d\n", lux);
+}
+
+static ssize_t taos_do_calibrate(struct device *dev,
+	struct device_attribute *attr, const char *buf, size_t len)
+{
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct tsl2583_chip *chip = indio_dev->dev_data;
+	unsigned long value;
+
+	if (strict_strtoul(buf, 0, &value))
+		return -EINVAL;
+
+	if (value == 1)
+		taos_als_calibrate(chip->client);
+
+	return len;
+}
+
+static ssize_t taos_luxtable_show(struct device *dev,
+	struct device_attribute *attr, char *buf)
+{
+	int i;
+	int offset = 0;
+
+	for (i = 0; i < ARRAY_SIZE(taos_device_lux); i++) {
+		offset += sprintf(buf + offset, "%d,%d,%d,",
+				  taos_device_lux[i].ratio,
+				  taos_device_lux[i].ch0,
+				  taos_device_lux[i].ch1);
+		if (taos_device_lux[i].ratio == 0) {
+			/* We just printed the first "0" entry.
+			 * Now get rid of the extra "," and break. */
+			offset--;
+			break;
+		}
+	}
+
+	offset += sprintf(buf + offset, "\n");
+	return offset;
+}
+
+static ssize_t taos_luxtable_store(struct device *dev,
+	struct device_attribute *attr, const char *buf, size_t len)
+{
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct tsl2583_chip *chip = indio_dev->dev_data;
+	int value[ARRAY_SIZE(taos_device_lux)];
+	int n;
+
+	get_options(buf, ARRAY_SIZE(value), value);
+
+	/* We now have an array of ints starting at value[1], and
+	 * enumerated by value[0].
+	 * We expect each group of three ints is one table entry,
+	 * and the last table entry is all 0.
+	 */
+	n = value[0];
+	if ((n % 3) || n < 6 || n > ((ARRAY_SIZE(taos_device_lux) - 1) * 3)) {
+		dev_info(dev, "LUX TABLE INPUT ERROR 1 Value[0]=%d\n", n);
+		return -EINVAL;
+	}
+	if ((value[(n - 2)] | value[(n - 1)] | value[n]) != 0) {
+		dev_info(dev, "LUX TABLE INPUT ERROR 2 Value[0]=%d\n", n);
+		return -EINVAL;
+	}
+
+	if (chip->taos_chip_status == TSL258X_CHIP_WORKING)
+		taos_chip_off(chip->client);
+
+	/* Zero out the table */
+	memset(taos_device_lux, 0, sizeof(taos_device_lux));
+	memcpy(taos_device_lux, &value[1], (value[0] * 4));
+
+	taos_chip_on(chip->client);
+
+	return len;
+}
+
+static DEVICE_ATTR(name, S_IRUGO, taos_device_id, NULL);
+static DEVICE_ATTR(power_state, S_IRUGO | S_IWUSR,
+		taos_power_state_show, taos_power_state_store);
+
+static DEVICE_ATTR(illuminance0_calibscale, S_IRUGO | S_IWUSR,
+		taos_gain_show, taos_gain_store);
+static DEVICE_ATTR(illuminance0_calibscale_available, S_IRUGO,
+		taos_gain_available_show, NULL);
+
+static DEVICE_ATTR(illuminance0_integration_time, S_IRUGO | S_IWUSR,
+		taos_als_time_show, taos_als_time_store);
+static DEVICE_ATTR(illuminance0_integration_time_available, S_IRUGO,
+		taos_als_time_available_show, NULL);
+
+static DEVICE_ATTR(illuminance0_calibbias, S_IRUGO | S_IWUSR,
+		taos_als_trim_show, taos_als_trim_store);
+
+static DEVICE_ATTR(illuminance0_input_target, S_IRUGO | S_IWUSR,
+		taos_als_cal_target_show, taos_als_cal_target_store);
+
+static DEVICE_ATTR(illuminance0_input, S_IRUGO, taos_lux_show, NULL);
+static DEVICE_ATTR(illuminance0_calibrate, S_IWUSR, NULL, taos_do_calibrate);
+static DEVICE_ATTR(illuminance0_lux_table, S_IRUGO | S_IWUSR,
+		taos_luxtable_show, taos_luxtable_store);
+
+static struct attribute *sysfs_attrs_ctrl[] = {
+	&dev_attr_name.attr,
+	&dev_attr_power_state.attr,
+	&dev_attr_illuminance0_calibscale.attr,			/* Gain  */
+	&dev_attr_illuminance0_calibscale_available.attr,
+	&dev_attr_illuminance0_integration_time.attr,	/* I time*/
+	&dev_attr_illuminance0_integration_time_available.attr,
+	&dev_attr_illuminance0_calibbias.attr,			/* trim  */
+	&dev_attr_illuminance0_input_target.attr,
+	&dev_attr_illuminance0_input.attr,
+	&dev_attr_illuminance0_calibrate.attr,
+	&dev_attr_illuminance0_lux_table.attr,
+	NULL
+};
+
+static struct attribute_group tsl2583_attribute_group = {
+	.attrs = sysfs_attrs_ctrl,
+};
+
+/* Use the default register values to identify the Taos device */
+static int taos_tsl258x_device(unsigned char *bufp)
+{
+	return ((bufp[TSL258X_CHIPID] & 0xf0) == 0x90);
+}
+
+static const struct iio_info tsl2583_info = {
+	.attrs = &tsl2583_attribute_group,
+	.driver_module = THIS_MODULE,
+};
+
+/*
+ * Client probe function - When a valid device is found, the driver's device
+ * data structure is updated, and initialization completes successfully.
+ */
+static int __devinit taos_probe(struct i2c_client *clientp,
+		      const struct i2c_device_id *idp)
+{
+	int i, ret = 0;
+	unsigned char buf[TSL258X_MAX_DEVICE_REGS];
+	static struct tsl2583_chip *chip;
+
+	if (!i2c_check_functionality(clientp->adapter,
+		I2C_FUNC_SMBUS_BYTE_DATA)) {
+		dev_err(&clientp->dev,
+			"taos_probe() - i2c smbus byte data "
+			"functions unsupported\n");
+		return -EOPNOTSUPP;
+	}
+
+	chip = kzalloc(sizeof(struct tsl2583_chip), GFP_KERNEL);
+	if (!chip)
+		return -ENOMEM;
+
+	chip->client = clientp;
+	i2c_set_clientdata(clientp, chip);
+
+	mutex_init(&chip->als_mutex);
+	chip->taos_chip_status = TSL258X_CHIP_UNKNOWN;
+	memcpy(chip->taos_config, taos_config, sizeof(chip->taos_config));
+
+	for (i = 0; i < TSL258X_MAX_DEVICE_REGS; i++) {
+		ret = i2c_smbus_write_byte(clientp,
+				(TSL258X_CMD_REG | (TSL258X_CNTRL + i)));
+		if (ret < 0) {
+			dev_err(&clientp->dev, "i2c_smbus_write_bytes() to cmd "
+				"reg failed in taos_probe(), err = %d\n", ret);
+			goto fail1;
+		}
+		ret = i2c_smbus_read_byte(clientp);
+		if (ret < 0) {
+			dev_err(&clientp->dev, "i2c_smbus_read_byte from "
+				"reg failed in taos_probe(), err = %d\n", ret);
+
+			goto fail1;
+		}
+		buf[i] = ret;
+	}
+
+	if (!taos_tsl258x_device(buf)) {
+		dev_info(&clientp->dev, "i2c device found but does not match "
+			"expected id in taos_probe()\n");
+		goto fail1;
+	}
+
+	ret = i2c_smbus_write_byte(clientp, (TSL258X_CMD_REG | TSL258X_CNTRL));
+	if (ret < 0) {
+		dev_err(&clientp->dev, "i2c_smbus_write_byte() to cmd reg "
+			"failed in taos_probe(), err = %d\n", ret);
+		goto fail1;
+	}
+
+	chip->iio_dev = iio_allocate_device(0);
+	if (!chip->iio_dev) {
+		ret = -ENOMEM;
+		dev_err(&clientp->dev, "iio allocation failed\n");
+		goto fail1;
+	}
+
+	chip->iio_dev->info = &tsl2583_info;
+	chip->iio_dev->dev.parent = &clientp->dev;
+	chip->iio_dev->dev_data = (void *)(chip);
+	chip->iio_dev->modes = INDIO_DIRECT_MODE;
+	ret = iio_device_register(chip->iio_dev);
+	if (ret) {
+		dev_err(&clientp->dev, "iio registration failed\n");
+		goto fail1;
+	}
+
+	/* Load up the V2 defaults (these are hard coded defaults for now) */
+	taos_defaults(chip);
+
+	/* Make sure the chip is on */
+	taos_chip_on(clientp);
+
+	dev_info(&clientp->dev, "Light sensor found.\n");
+
+	return 0;
+
+fail1:
+	kfree(chip);
+
+	return ret;
+}
+
+static int taos_suspend(struct i2c_client *client, pm_message_t state)
+{
+	struct tsl2583_chip *chip = i2c_get_clientdata(client);
+	int ret = 0;
+
+	mutex_lock(&chip->als_mutex);
+
+	if (chip->taos_chip_status == TSL258X_CHIP_WORKING) {
+		ret = taos_chip_off(client);
+		chip->taos_chip_status = TSL258X_CHIP_SUSPENDED;
+	}
+
+	mutex_unlock(&chip->als_mutex);
+	return ret;
+}
+
+static int taos_resume(struct i2c_client *client)
+{
+	struct tsl2583_chip *chip = i2c_get_clientdata(client);
+	int ret = 0;
+
+	mutex_lock(&chip->als_mutex);
+
+	if (chip->taos_chip_status == TSL258X_CHIP_SUSPENDED)
+		ret = taos_chip_on(client);
+
+	mutex_unlock(&chip->als_mutex);
+	return ret;
+}
+
+
+static int __devexit taos_remove(struct i2c_client *client)
+{
+	struct tsl2583_chip *chip = i2c_get_clientdata(client);
+
+	iio_device_unregister(chip->iio_dev);
+
+	kfree(chip);
+	return 0;
+}
+
+static struct i2c_device_id taos_idtable[] = {
+	{ "tsl2580", 0 },
+	{ "tsl2581", 1 },
+	{ "tsl2583", 2 },
+	{}
+};
+MODULE_DEVICE_TABLE(i2c, taos_idtable);
+
+/* Driver definition */
+static struct i2c_driver taos_driver = {
+	.driver = {
+		.name = "tsl2583",
+	},
+	.id_table = taos_idtable,
+	.suspend	= taos_suspend,
+	.resume		= taos_resume,
+	.probe = taos_probe,
+	.remove = __devexit_p(taos_remove),
+};
+
+static int __init taos_init(void)
+{
+	return i2c_add_driver(&taos_driver);
+}
+
+static void __exit taos_exit(void)
+{
+	i2c_del_driver(&taos_driver);
+}
+
+module_init(taos_init);
+module_exit(taos_exit);
+
+MODULE_AUTHOR("J. August Brenner<jbrenner@taosinc.com>");
+MODULE_DESCRIPTION("TAOS tsl2583 ambient light sensor driver");
+MODULE_LICENSE("GPL");
diff -druN linux-2.6.39-libre/drivers/staging/iio/magnetometer/ak8975.c linux-3.0-rc7-libre/drivers/staging/iio/magnetometer/ak8975.c
--- linux-2.6.39-libre/drivers/staging/iio/magnetometer/ak8975.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/iio/magnetometer/ak8975.c	2011-07-11 19:51:52.000000000 -0400
@@ -206,7 +206,7 @@
 	}
 
 	/* Precalculate scale factor for each axis and
-           store in the device data. */
+	   store in the device data. */
 	data->raw_to_gauss[0] = ((data->asa[0] + 128) * 30) >> 8;
 	data->raw_to_gauss[1] = ((data->asa[1] + 128) * 30) >> 8;
 	data->raw_to_gauss[2] = ((data->asa[2] + 128) * 30) >> 8;
@@ -316,6 +316,59 @@
 	return sprintf(buf, "%ld\n", data->raw_to_gauss[this_attr->address]);
 }
 
+static int wait_conversion_complete_gpio(struct ak8975_data *data)
+{
+	struct i2c_client *client = data->client;
+	u8 read_status;
+	u32 timeout_ms = AK8975_MAX_CONVERSION_TIMEOUT;
+	int ret;
+
+	/* Wait for the conversion to complete. */
+	while (timeout_ms) {
+		msleep(AK8975_CONVERSION_DONE_POLL_TIME);
+		if (gpio_get_value(data->eoc_gpio))
+			break;
+		timeout_ms -= AK8975_CONVERSION_DONE_POLL_TIME;
+	}
+	if (!timeout_ms) {
+		dev_err(&client->dev, "Conversion timeout happened\n");
+		return -EINVAL;
+	}
+
+	ret = ak8975_read_data(client, AK8975_REG_ST1, 1, &read_status);
+	if (ret < 0) {
+		dev_err(&client->dev, "Error in reading ST1\n");
+		return ret;
+	}
+	return read_status;
+}
+
+static int wait_conversion_complete_polled(struct ak8975_data *data)
+{
+	struct i2c_client *client = data->client;
+	u8 read_status;
+	u32 timeout_ms = AK8975_MAX_CONVERSION_TIMEOUT;
+	int ret;
+
+	/* Wait for the conversion to complete. */
+	while (timeout_ms) {
+		msleep(AK8975_CONVERSION_DONE_POLL_TIME);
+		ret = ak8975_read_data(client, AK8975_REG_ST1, 1, &read_status);
+		if (ret < 0) {
+			dev_err(&client->dev, "Error in reading ST1\n");
+			return ret;
+		}
+		if (read_status)
+			break;
+		timeout_ms -= AK8975_CONVERSION_DONE_POLL_TIME;
+	}
+	if (!timeout_ms) {
+		dev_err(&client->dev, "Conversion timeout happened\n");
+		return -EINVAL;
+	}
+	return read_status;
+}
+
 /*
  * Emits the raw flux value for the x, y, or z axis.
  */
@@ -326,7 +379,6 @@
 	struct ak8975_data *data = indio_dev->dev_data;
 	struct i2c_client *client = data->client;
 	struct iio_dev_attr *this_attr = to_iio_dev_attr(devattr);
-	u32 timeout_ms = AK8975_MAX_CONVERSION_TIMEOUT;
 	u16 meas_reg;
 	s16 raw;
 	u8 read_status;
@@ -352,23 +404,14 @@
 	}
 
 	/* Wait for the conversion to complete. */
-	while (timeout_ms) {
-		msleep(AK8975_CONVERSION_DONE_POLL_TIME);
-		if (gpio_get_value(data->eoc_gpio))
-			break;
-		timeout_ms -= AK8975_CONVERSION_DONE_POLL_TIME;
-	}
-	if (!timeout_ms) {
-		dev_err(&client->dev, "Conversion timeout happened\n");
-		ret = -EINVAL;
+	if (data->eoc_gpio)
+		ret = wait_conversion_complete_gpio(data);
+	else
+		ret = wait_conversion_complete_polled(data);
+	if (ret < 0)
 		goto exit;
-	}
 
-	ret = ak8975_read_data(client, AK8975_REG_ST1, 1, &read_status);
-	if (ret < 0) {
-		dev_err(&client->dev, "Error in reading ST1\n");
-		goto exit;
-	}
+	read_status = ret;
 
 	if (read_status & AK8975_REG_ST1_DRDY_MASK) {
 		ret = ak8975_read_data(client, AK8975_REG_ST2, 1, &read_status);
@@ -431,6 +474,11 @@
 	.attrs = ak8975_attr,
 };
 
+static const struct iio_info ak8975_info = {
+	.attrs = &ak8975_attr_group,
+	.driver_module = THIS_MODULE,
+};
+
 static int ak8975_probe(struct i2c_client *client,
 			const struct i2c_device_id *id)
 {
@@ -454,25 +502,26 @@
 	data->eoc_irq = client->irq;
 	data->eoc_gpio = irq_to_gpio(client->irq);
 
-	if (!data->eoc_gpio) {
-		dev_err(&client->dev, "failed, no valid GPIO\n");
-		err = -EINVAL;
-		goto exit_free;
-	}
-
-	err = gpio_request(data->eoc_gpio, "ak_8975");
-	if (err < 0) {
-		dev_err(&client->dev, "failed to request GPIO %d, error %d\n",
-			data->eoc_gpio, err);
-		goto exit_free;
-	}
+	/* We may not have a GPIO based IRQ to scan, that is fine, we will
+	   poll if so */
+	if (data->eoc_gpio > 0) {
+		err = gpio_request(data->eoc_gpio, "ak_8975");
+		if (err < 0) {
+			dev_err(&client->dev,
+				"failed to request GPIO %d, error %d\n",
+							data->eoc_gpio, err);
+			goto exit_free;
+		}
 
-	err = gpio_direction_input(data->eoc_gpio);
-	if (err < 0) {
-		dev_err(&client->dev, "Failed to configure input direction for"
-			" GPIO %d, error %d\n", data->eoc_gpio, err);
-		goto exit_gpio;
-	}
+		err = gpio_direction_input(data->eoc_gpio);
+		if (err < 0) {
+			dev_err(&client->dev,
+				"Failed to configure input direction for GPIO %d, error %d\n",
+						data->eoc_gpio, err);
+			goto exit_gpio;
+		}
+	} else
+		data->eoc_gpio = 0;	/* No GPIO available */
 
 	/* Perform some basic start-of-day setup of the device. */
 	err = ak8975_setup(client);
@@ -482,16 +531,15 @@
 	}
 
 	/* Register with IIO */
-	data->indio_dev = iio_allocate_device();
+	data->indio_dev = iio_allocate_device(0);
 	if (data->indio_dev == NULL) {
 		err = -ENOMEM;
 		goto exit_gpio;
 	}
 
 	data->indio_dev->dev.parent = &client->dev;
-	data->indio_dev->attrs = &ak8975_attr_group;
+	data->indio_dev->info = &ak8975_info;
 	data->indio_dev->dev_data = (void *)(data);
-	data->indio_dev->driver_module = THIS_MODULE;
 	data->indio_dev->modes = INDIO_DIRECT_MODE;
 
 	err = iio_device_register(data->indio_dev);
@@ -503,7 +551,8 @@
 exit_free_iio:
 	iio_free_device(data->indio_dev);
 exit_gpio:
-	gpio_free(data->eoc_gpio);
+	if (data->eoc_gpio)
+		gpio_free(data->eoc_gpio);
 exit_free:
 	kfree(data);
 exit:
@@ -517,7 +566,8 @@
 	iio_device_unregister(data->indio_dev);
 	iio_free_device(data->indio_dev);
 
-	gpio_free(data->eoc_gpio);
+	if (data->eoc_gpio)
+		gpio_free(data->eoc_gpio);
 
 	kfree(data);
 
diff -druN linux-2.6.39-libre/drivers/staging/iio/magnetometer/hmc5843.c linux-3.0-rc7-libre/drivers/staging/iio/magnetometer/hmc5843.c
--- linux-2.6.39-libre/drivers/staging/iio/magnetometer/hmc5843.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/iio/magnetometer/hmc5843.c	2011-07-11 19:51:52.000000000 -0400
@@ -529,6 +529,11 @@
 	pr_info("HMC5843 initialized\n");
 }
 
+static const struct iio_info hmc5843_info = {
+	.attrs = &hmc5843_group,
+	.driver_module = THIS_MODULE,
+};
+
 static int hmc5843_probe(struct i2c_client *client,
 			 const struct i2c_device_id *id)
 {
@@ -552,15 +557,14 @@
 	/* Initialize the HMC5843 chip */
 	hmc5843_init_client(client);
 
-	data->indio_dev = iio_allocate_device();
+	data->indio_dev = iio_allocate_device(0);
 	if (!data->indio_dev) {
 		err = -ENOMEM;
 		goto exit_free1;
 	}
-	data->indio_dev->attrs = &hmc5843_group;
+	data->indio_dev->info = &hmc5843_info;
 	data->indio_dev->dev.parent = &client->dev;
 	data->indio_dev->dev_data = (void *)(data);
-	data->indio_dev->driver_module = THIS_MODULE;
 	data->indio_dev->modes = INDIO_DIRECT_MODE;
 	err = iio_device_register(data->indio_dev);
 	if (err)
diff -druN linux-2.6.39-libre/drivers/staging/iio/meter/ade7753.c linux-3.0-rc7-libre/drivers/staging/iio/meter/ade7753.c
--- linux-2.6.39-libre/drivers/staging/iio/meter/ade7753.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/iio/meter/ade7753.c	2011-07-11 19:51:52.000000000 -0400
@@ -463,8 +463,6 @@
 
 static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("27900 14000 7000 3500");
 
-static IIO_CONST_ATTR(name, "ade7753");
-
 static struct attribute *ade7753_attributes[] = {
 	&iio_dev_attr_temp_raw.dev_attr.attr,
 	&iio_const_attr_temp_offset.dev_attr.attr,
@@ -472,7 +470,6 @@
 	&iio_dev_attr_sampling_frequency.dev_attr.attr,
 	&iio_const_attr_sampling_frequency_available.dev_attr.attr,
 	&iio_dev_attr_reset.dev_attr.attr,
-	&iio_const_attr_name.dev_attr.attr,
 	&iio_dev_attr_phcal.dev_attr.attr,
 	&iio_dev_attr_cfden.dev_attr.attr,
 	&iio_dev_attr_aenergy.dev_attr.attr,
@@ -507,6 +504,11 @@
 	.attrs = ade7753_attributes,
 };
 
+static const struct iio_info ade7753_info = {
+	.attrs = &ade7753_attribute_group,
+	.driver_module = THIS_MODULE,
+};
+
 static int __devinit ade7753_probe(struct spi_device *spi)
 {
 	int ret, regdone = 0;
@@ -532,16 +534,16 @@
 	st->us = spi;
 	mutex_init(&st->buf_lock);
 	/* setup the industrialio driver allocated elements */
-	st->indio_dev = iio_allocate_device();
+	st->indio_dev = iio_allocate_device(0);
 	if (st->indio_dev == NULL) {
 		ret = -ENOMEM;
 		goto error_free_tx;
 	}
 
+	st->indio_dev->name = spi->dev.driver->name;
 	st->indio_dev->dev.parent = &spi->dev;
-	st->indio_dev->attrs = &ade7753_attribute_group;
+	st->indio_dev->info = &ade7753_info;
 	st->indio_dev->dev_data = (void *)(st);
-	st->indio_dev->driver_module = THIS_MODULE;
 	st->indio_dev->modes = INDIO_DIRECT_MODE;
 
 	ret = iio_device_register(st->indio_dev);
diff -druN linux-2.6.39-libre/drivers/staging/iio/meter/ade7754.c linux-3.0-rc7-libre/drivers/staging/iio/meter/ade7754.c
--- linux-2.6.39-libre/drivers/staging/iio/meter/ade7754.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/iio/meter/ade7754.c	2011-07-11 19:51:52.000000000 -0400
@@ -482,8 +482,6 @@
 
 static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("26000 13000 65000 33000");
 
-static IIO_CONST_ATTR(name, "ade7754");
-
 static struct attribute *ade7754_attributes[] = {
 	&iio_dev_attr_temp_raw.dev_attr.attr,
 	&iio_const_attr_temp_offset.dev_attr.attr,
@@ -491,7 +489,6 @@
 	&iio_dev_attr_sampling_frequency.dev_attr.attr,
 	&iio_const_attr_sampling_frequency_available.dev_attr.attr,
 	&iio_dev_attr_reset.dev_attr.attr,
-	&iio_const_attr_name.dev_attr.attr,
 	&iio_dev_attr_aenergy.dev_attr.attr,
 	&iio_dev_attr_laenergy.dev_attr.attr,
 	&iio_dev_attr_vaenergy.dev_attr.attr,
@@ -530,7 +527,10 @@
 	.attrs = ade7754_attributes,
 };
 
-
+static const struct iio_info ade7754_info = {
+	.attrs = &ade7754_attribute_group,
+	.driver_module = THIS_MODULE,
+};
 
 static int __devinit ade7754_probe(struct spi_device *spi)
 {
@@ -557,16 +557,16 @@
 	st->us = spi;
 	mutex_init(&st->buf_lock);
 	/* setup the industrialio driver allocated elements */
-	st->indio_dev = iio_allocate_device();
+	st->indio_dev = iio_allocate_device(0);
 	if (st->indio_dev == NULL) {
 		ret = -ENOMEM;
 		goto error_free_tx;
 	}
 
+	st->indio_dev->name = spi->dev.driver->name;
 	st->indio_dev->dev.parent = &spi->dev;
-	st->indio_dev->attrs = &ade7754_attribute_group;
+	st->indio_dev->info = &ade7754_info;
 	st->indio_dev->dev_data = (void *)(st);
-	st->indio_dev->driver_module = THIS_MODULE;
 	st->indio_dev->modes = INDIO_DIRECT_MODE;
 
 	ret = iio_device_register(st->indio_dev);
diff -druN linux-2.6.39-libre/drivers/staging/iio/meter/ade7758_core.c linux-3.0-rc7-libre/drivers/staging/iio/meter/ade7758_core.c
--- linux-2.6.39-libre/drivers/staging/iio/meter/ade7758_core.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/iio/meter/ade7758_core.c	2011-07-11 19:51:52.000000000 -0400
@@ -1,9 +1,9 @@
 /*
- * ADE7758 Polyphase Multifunction Energy Metering IC Driver
+ * ADE7758 Poly Phase Multifunction Energy Metering IC driver
  *
- * Copyright 2010 Analog Devices Inc.
+ * Copyright 2010-2011 Analog Devices Inc.
  *
- * Licensed under the GPL-2 or later.
+ * Licensed under the GPL-2.
  */
 
 #include <linux/interrupt.h>
@@ -20,6 +20,7 @@
 
 #include "../iio.h"
 #include "../sysfs.h"
+#include "../ring_generic.h"
 #include "meter.h"
 #include "ade7758.h"
 
@@ -29,7 +30,7 @@
 {
 	int ret;
 	struct iio_dev *indio_dev = dev_get_drvdata(dev);
-	struct ade7758_state *st = iio_dev_get_devdata(indio_dev);
+	struct ade7758_state *st = iio_priv(indio_dev);
 
 	mutex_lock(&st->buf_lock);
 	st->tx[0] = ADE7758_WRITE_REG(reg_address);
@@ -48,7 +49,7 @@
 	int ret;
 	struct spi_message msg;
 	struct iio_dev *indio_dev = dev_get_drvdata(dev);
-	struct ade7758_state *st = iio_dev_get_devdata(indio_dev);
+	struct ade7758_state *st = iio_priv(indio_dev);
 	struct spi_transfer xfers[] = {
 		{
 			.tx_buf = st->tx,
@@ -77,7 +78,7 @@
 	int ret;
 	struct spi_message msg;
 	struct iio_dev *indio_dev = dev_get_drvdata(dev);
-	struct ade7758_state *st = iio_dev_get_devdata(indio_dev);
+	struct ade7758_state *st = iio_priv(indio_dev);
 	struct spi_transfer xfers[] = {
 		{
 			.tx_buf = st->tx,
@@ -100,20 +101,26 @@
 	return ret;
 }
 
-static int ade7758_spi_read_reg_8(struct device *dev,
+int ade7758_spi_read_reg_8(struct device *dev,
 		u8 reg_address,
 		u8 *val)
 {
 	struct spi_message msg;
 	struct iio_dev *indio_dev = dev_get_drvdata(dev);
-	struct ade7758_state *st = iio_dev_get_devdata(indio_dev);
+	struct ade7758_state *st = iio_priv(indio_dev);
 	int ret;
 	struct spi_transfer xfers[] = {
 		{
 			.tx_buf = st->tx,
+			.bits_per_word = 8,
+			.len = 1,
+			.delay_usecs = 4,
+		},
+		{
+			.tx_buf = &st->tx[1],
 			.rx_buf = st->rx,
 			.bits_per_word = 8,
-			.len = 2,
+			.len = 1,
 		},
 	};
 
@@ -122,14 +129,15 @@
 	st->tx[1] = 0;
 
 	spi_message_init(&msg);
-	spi_message_add_tail(xfers, &msg);
+	spi_message_add_tail(&xfers[0], &msg);
+	spi_message_add_tail(&xfers[1], &msg);
 	ret = spi_sync(st->us, &msg);
 	if (ret) {
 		dev_err(&st->us->dev, "problem when reading 8 bit register 0x%02X",
 				reg_address);
 		goto error_ret;
 	}
-	*val = st->rx[1];
+	*val = st->rx[0];
 
 error_ret:
 	mutex_unlock(&st->buf_lock);
@@ -142,31 +150,40 @@
 {
 	struct spi_message msg;
 	struct iio_dev *indio_dev = dev_get_drvdata(dev);
-	struct ade7758_state *st = iio_dev_get_devdata(indio_dev);
+	struct ade7758_state *st = iio_priv(indio_dev);
 	int ret;
 	struct spi_transfer xfers[] = {
 		{
 			.tx_buf = st->tx,
+			.bits_per_word = 8,
+			.len = 1,
+			.delay_usecs = 4,
+		},
+		{
+			.tx_buf = &st->tx[1],
 			.rx_buf = st->rx,
 			.bits_per_word = 8,
-			.len = 3,
+			.len = 2,
 		},
 	};
 
+
 	mutex_lock(&st->buf_lock);
 	st->tx[0] = ADE7758_READ_REG(reg_address);
 	st->tx[1] = 0;
 	st->tx[2] = 0;
 
 	spi_message_init(&msg);
-	spi_message_add_tail(xfers, &msg);
+	spi_message_add_tail(&xfers[0], &msg);
+	spi_message_add_tail(&xfers[1], &msg);
 	ret = spi_sync(st->us, &msg);
 	if (ret) {
 		dev_err(&st->us->dev, "problem when reading 16 bit register 0x%02X",
 				reg_address);
 		goto error_ret;
 	}
-	*val = (st->rx[1] << 8) | st->rx[2];
+
+	*val = (st->rx[0] << 8) | st->rx[1];
 
 error_ret:
 	mutex_unlock(&st->buf_lock);
@@ -179,14 +196,20 @@
 {
 	struct spi_message msg;
 	struct iio_dev *indio_dev = dev_get_drvdata(dev);
-	struct ade7758_state *st = iio_dev_get_devdata(indio_dev);
+	struct ade7758_state *st = iio_priv(indio_dev);
 	int ret;
 	struct spi_transfer xfers[] = {
 		{
 			.tx_buf = st->tx,
+			.bits_per_word = 8,
+			.len = 1,
+			.delay_usecs = 4,
+		},
+		{
+			.tx_buf = &st->tx[1],
 			.rx_buf = st->rx,
 			.bits_per_word = 8,
-			.len = 4,
+			.len = 3,
 		},
 	};
 
@@ -197,14 +220,15 @@
 	st->tx[3] = 0;
 
 	spi_message_init(&msg);
-	spi_message_add_tail(xfers, &msg);
+	spi_message_add_tail(&xfers[0], &msg);
+	spi_message_add_tail(&xfers[1], &msg);
 	ret = spi_sync(st->us, &msg);
 	if (ret) {
 		dev_err(&st->us->dev, "problem when reading 24 bit register 0x%02X",
 				reg_address);
 		goto error_ret;
 	}
-	*val = (st->rx[1] << 16) | (st->rx[2] << 8) | st->rx[3];
+	*val = (st->rx[0] << 16) | (st->rx[1] << 8) | st->rx[2];
 
 error_ret:
 	mutex_unlock(&st->buf_lock);
@@ -292,7 +316,7 @@
 	return ret ? ret : len;
 }
 
-int ade7758_reset(struct device *dev)
+static int ade7758_reset(struct device *dev)
 {
 	int ret;
 	u8 val;
@@ -319,7 +343,7 @@
 	case 'Y':
 		return ade7758_reset(dev);
 	}
-	return -1;
+	return len;
 }
 
 static IIO_DEV_ATTR_VPEAK(S_IWUSR | S_IRUGO,
@@ -461,13 +485,14 @@
 	return ret;
 }
 
-static int ade7758_initial_setup(struct ade7758_state *st)
+static int ade7758_initial_setup(struct iio_dev *indio_dev)
 {
+	struct ade7758_state *st = iio_priv(indio_dev);
+	struct device *dev = &indio_dev->dev;
 	int ret;
-	struct device *dev = &st->indio_dev->dev;
 
 	/* use low spi speed for init */
-	st->us->mode = SPI_MODE_3;
+	st->us->mode = SPI_MODE_1;
 	spi_setup(st->us);
 
 	/* Disable IRQ */
@@ -510,7 +535,6 @@
 		size_t len)
 {
 	struct iio_dev *indio_dev = dev_get_drvdata(dev);
-	struct ade7758_state *st = iio_dev_get_devdata(indio_dev);
 	unsigned long val;
 	int ret;
 	u8 reg, t;
@@ -521,14 +545,23 @@
 
 	mutex_lock(&indio_dev->mlock);
 
-	t = (26040 / val);
-	if (t > 0)
-		t >>= 1;
-
-	if (t > 1)
-		st->us->max_speed_hz = ADE7758_SPI_SLOW;
-	else
-		st->us->max_speed_hz = ADE7758_SPI_FAST;
+	switch (val) {
+	case 26040:
+		t = 0;
+		break;
+	case 13020:
+		t = 1;
+		break;
+	case 6510:
+		t = 2;
+		break;
+	case 3255:
+		t = 3;
+		break;
+	default:
+		ret = -EINVAL;
+		goto out;
+	}
 
 	ret = ade7758_spi_read_reg_8(dev,
 			ADE7758_WAVMODE,
@@ -549,63 +582,6 @@
 	return ret ? ret : len;
 }
 
-static ssize_t ade7758_read_waveform_type(struct device *dev,
-		struct device_attribute *attr,
-		char *buf)
-{
-	int ret, len = 0;
-	u8 t;
-	ret = ade7758_spi_read_reg_8(dev,
-			ADE7758_WAVMODE,
-			&t);
-	if (ret)
-		return ret;
-
-	t = (t >> 2) & 0x7;
-
-	len = sprintf(buf, "%d\n", t);
-
-	return len;
-}
-
-static ssize_t ade7758_write_waveform_type(struct device *dev,
-		struct device_attribute *attr,
-		const char *buf,
-		size_t len)
-{
-	struct iio_dev *indio_dev = dev_get_drvdata(dev);
-	unsigned long val;
-	int ret;
-	u8 reg;
-
-	ret = strict_strtol(buf, 10, &val);
-	if (ret)
-		return ret;
-
-	if (val > 4)
-		return -EINVAL;
-
-	mutex_lock(&indio_dev->mlock);
-
-	ret = ade7758_spi_read_reg_8(dev,
-			ADE7758_WAVMODE,
-			&reg);
-	if (ret)
-		goto out;
-
-	reg &= ~(7 << 2);
-	reg |= val << 2;
-
-	ret = ade7758_spi_write_reg_8(dev,
-			ADE7758_WAVMODE,
-			reg);
-
-out:
-	mutex_unlock(&indio_dev->mlock);
-
-	return ret ? ret : len;
-}
-
 static IIO_DEV_ATTR_TEMP_RAW(ade7758_read_8bit);
 static IIO_CONST_ATTR(temp_offset, "129 C");
 static IIO_CONST_ATTR(temp_scale, "4 C");
@@ -633,42 +609,17 @@
 		ade7758_read_frequency,
 		ade7758_write_frequency);
 
-/**
- * IIO_DEV_ATTR_WAVEFORM_TYPE - set the type of waveform.
- * @_mode: sysfs file mode/permissions
- * @_show: output method for the attribute
- * @_store: input method for the attribute
- **/
-#define IIO_DEV_ATTR_WAVEFORM_TYPE(_mode, _show, _store)			\
-	IIO_DEVICE_ATTR(waveform_type, _mode, _show, _store, 0)
-
-static IIO_DEV_ATTR_WAVEFORM_TYPE(S_IWUSR | S_IRUGO,
-		ade7758_read_waveform_type,
-		ade7758_write_waveform_type);
-
 static IIO_DEV_ATTR_RESET(ade7758_write_reset);
 
-static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("26000 13000 65000 33000");
-
-static IIO_CONST_ATTR(name, "ade7758");
-
-static struct attribute *ade7758_event_attributes[] = {
-	NULL
-};
-
-static struct attribute_group ade7758_event_attribute_group = {
-	.attrs = ade7758_event_attributes,
-};
+static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("26040 13020 6510 3255");
 
 static struct attribute *ade7758_attributes[] = {
 	&iio_dev_attr_temp_raw.dev_attr.attr,
 	&iio_const_attr_temp_offset.dev_attr.attr,
 	&iio_const_attr_temp_scale.dev_attr.attr,
 	&iio_dev_attr_sampling_frequency.dev_attr.attr,
-	&iio_dev_attr_waveform_type.dev_attr.attr,
 	&iio_const_attr_sampling_frequency_available.dev_attr.attr,
 	&iio_dev_attr_reset.dev_attr.attr,
-	&iio_const_attr_name.dev_attr.attr,
 	&iio_dev_attr_awatthr.dev_attr.attr,
 	&iio_dev_attr_bwatthr.dev_attr.attr,
 	&iio_dev_attr_cwatthr.dev_attr.attr,
@@ -710,24 +661,95 @@
 	.attrs = ade7758_attributes,
 };
 
+static struct iio_chan_spec ade7758_channels[] = {
+	IIO_CHAN(IIO_IN, 0, 1, 0, "raw", 0, 0,
+		(1 << IIO_CHAN_INFO_SCALE_SHARED),
+		AD7758_WT(AD7758_PHASE_A, AD7758_VOLTAGE),
+		0, IIO_ST('s', 24, 32, 0), 0),
+	IIO_CHAN(IIO_CURRENT, 0, 1, 0, "raw", 0, 0,
+		(1 << IIO_CHAN_INFO_SCALE_SHARED),
+		AD7758_WT(AD7758_PHASE_A, AD7758_CURRENT),
+		1, IIO_ST('s', 24, 32, 0), 0),
+	IIO_CHAN(IIO_POWER, 0, 1, 0, "apparent_raw", 0, 0,
+		(1 << IIO_CHAN_INFO_SCALE_SHARED),
+		AD7758_WT(AD7758_PHASE_A, AD7758_APP_PWR),
+		2, IIO_ST('s', 24, 32, 0), 0),
+	IIO_CHAN(IIO_POWER, 0, 1, 0, "active_raw", 0, 0,
+		(1 << IIO_CHAN_INFO_SCALE_SHARED),
+		AD7758_WT(AD7758_PHASE_A, AD7758_ACT_PWR),
+		3, IIO_ST('s', 24, 32, 0), 0),
+	IIO_CHAN(IIO_POWER, 0, 1, 0, "reactive_raw", 0, 0,
+		(1 << IIO_CHAN_INFO_SCALE_SHARED),
+		AD7758_WT(AD7758_PHASE_A, AD7758_REACT_PWR),
+		4, IIO_ST('s', 24, 32, 0), 0),
+	IIO_CHAN(IIO_IN, 0, 1, 0, "raw", 1, 0,
+		(1 << IIO_CHAN_INFO_SCALE_SHARED),
+		AD7758_WT(AD7758_PHASE_B, AD7758_VOLTAGE),
+		5, IIO_ST('s', 24, 32, 0), 0),
+	IIO_CHAN(IIO_CURRENT, 0, 1, 0, "raw", 1, 0,
+		(1 << IIO_CHAN_INFO_SCALE_SHARED),
+		AD7758_WT(AD7758_PHASE_B, AD7758_CURRENT),
+		6, IIO_ST('s', 24, 32, 0), 0),
+	IIO_CHAN(IIO_POWER, 0, 1, 0, "apparent_raw", 1, 0,
+		(1 << IIO_CHAN_INFO_SCALE_SHARED),
+		AD7758_WT(AD7758_PHASE_B, AD7758_APP_PWR),
+		7, IIO_ST('s', 24, 32, 0), 0),
+	IIO_CHAN(IIO_POWER, 0, 1, 0, "active_raw", 1, 0,
+		(1 << IIO_CHAN_INFO_SCALE_SHARED),
+		AD7758_WT(AD7758_PHASE_B, AD7758_ACT_PWR),
+		8, IIO_ST('s', 24, 32, 0), 0),
+	IIO_CHAN(IIO_POWER, 0, 1, 0, "reactive_raw", 1, 0,
+		(1 << IIO_CHAN_INFO_SCALE_SHARED),
+		AD7758_WT(AD7758_PHASE_B, AD7758_REACT_PWR),
+		9, IIO_ST('s', 24, 32, 0), 0),
+	IIO_CHAN(IIO_IN, 0, 1, 0, "raw", 2, 0,
+		(1 << IIO_CHAN_INFO_SCALE_SHARED),
+		AD7758_WT(AD7758_PHASE_C, AD7758_VOLTAGE),
+		10, IIO_ST('s', 24, 32, 0), 0),
+	IIO_CHAN(IIO_CURRENT, 0, 1, 0, "raw", 2, 0,
+		(1 << IIO_CHAN_INFO_SCALE_SHARED),
+		AD7758_WT(AD7758_PHASE_C, AD7758_CURRENT),
+		11, IIO_ST('s', 24, 32, 0), 0),
+	IIO_CHAN(IIO_POWER, 0, 1, 0, "apparent_raw", 2, 0,
+		(1 << IIO_CHAN_INFO_SCALE_SHARED),
+		AD7758_WT(AD7758_PHASE_C, AD7758_APP_PWR),
+		12, IIO_ST('s', 24, 32, 0), 0),
+	IIO_CHAN(IIO_POWER, 0, 1, 0, "active_raw", 2, 0,
+		(1 << IIO_CHAN_INFO_SCALE_SHARED),
+		AD7758_WT(AD7758_PHASE_C, AD7758_ACT_PWR),
+		13, IIO_ST('s', 24, 32, 0), 0),
+	IIO_CHAN(IIO_POWER, 0, 1, 0, "reactive_raw", 2, 0,
+		(1 << IIO_CHAN_INFO_SCALE_SHARED),
+		AD7758_WT(AD7758_PHASE_C, AD7758_REACT_PWR),
+		14, IIO_ST('s', 24, 32, 0), 0),
+	IIO_CHAN_SOFT_TIMESTAMP(15),
+};
 
+static const struct iio_info ade7758_info = {
+	.attrs = &ade7758_attribute_group,
+	.driver_module = THIS_MODULE,
+};
 
 static int __devinit ade7758_probe(struct spi_device *spi)
 {
-	int ret, regdone = 0;
-	struct ade7758_state *st = kzalloc(sizeof *st, GFP_KERNEL);
-	if (!st) {
-		ret =  -ENOMEM;
+	int i, ret, regdone = 0;
+	struct ade7758_state *st;
+	struct iio_dev *indio_dev = iio_allocate_device(sizeof(*st));
+
+	if (indio_dev == NULL) {
+		ret = -ENOMEM;
 		goto error_ret;
 	}
+
+	st = iio_priv(indio_dev);
 	/* this is only used for removal purposes */
-	spi_set_drvdata(spi, st);
+	spi_set_drvdata(spi, indio_dev);
 
 	/* Allocate the comms buffers */
 	st->rx = kzalloc(sizeof(*st->rx)*ADE7758_MAX_RX, GFP_KERNEL);
 	if (st->rx == NULL) {
 		ret = -ENOMEM;
-		goto error_free_st;
+		goto error_free_dev;
 	}
 	st->tx = kzalloc(sizeof(*st->tx)*ADE7758_MAX_TX, GFP_KERNEL);
 	if (st->tx == NULL) {
@@ -735,111 +757,96 @@
 		goto error_free_rx;
 	}
 	st->us = spi;
+	st->ade7758_ring_channels = &ade7758_channels[0];
 	mutex_init(&st->buf_lock);
-	/* setup the industrialio driver allocated elements */
-	st->indio_dev = iio_allocate_device();
-	if (st->indio_dev == NULL) {
-		ret = -ENOMEM;
-		goto error_free_tx;
-	}
 
-	st->indio_dev->dev.parent = &spi->dev;
-	st->indio_dev->num_interrupt_lines = 1;
-	st->indio_dev->event_attrs = &ade7758_event_attribute_group;
-	st->indio_dev->attrs = &ade7758_attribute_group;
-	st->indio_dev->dev_data = (void *)(st);
-	st->indio_dev->driver_module = THIS_MODULE;
-	st->indio_dev->modes = INDIO_DIRECT_MODE;
+	indio_dev->name = spi->dev.driver->name;
+	indio_dev->dev.parent = &spi->dev;
+	indio_dev->info = &ade7758_info;
+	indio_dev->modes = INDIO_DIRECT_MODE;
 
-	ret = ade7758_configure_ring(st->indio_dev);
+	for (i = 0; i < AD7758_NUM_WAVESRC; i++)
+		st->available_scan_masks[i] = 1 << i;
+
+	indio_dev->available_scan_masks = st->available_scan_masks;
+
+	ret = ade7758_configure_ring(indio_dev);
 	if (ret)
-		goto error_free_dev;
+		goto error_free_tx;
 
-	ret = iio_device_register(st->indio_dev);
+	ret = iio_device_register(indio_dev);
 	if (ret)
 		goto error_unreg_ring_funcs;
 	regdone = 1;
 
-	ret = ade7758_initialize_ring(st->indio_dev->ring);
+	ret = iio_ring_buffer_register_ex(indio_dev->ring, 0,
+					  &ade7758_channels[0],
+					  ARRAY_SIZE(ade7758_channels));
 	if (ret) {
-		printk(KERN_ERR "failed to initialize the ring\n");
+		dev_err(&spi->dev, "failed to initialize the ring\n");
 		goto error_unreg_ring_funcs;
 	}
 
-	if (spi->irq) {
-		ret = iio_register_interrupt_line(spi->irq,
-				st->indio_dev,
-				0,
-				IRQF_TRIGGER_FALLING,
-				"ade7758");
-		if (ret)
-			goto error_uninitialize_ring;
+	/* Get the device into a sane initial state */
+	ret = ade7758_initial_setup(indio_dev);
+	if (ret)
+		goto error_uninitialize_ring;
 
-		ret = ade7758_probe_trigger(st->indio_dev);
+	if (spi->irq) {
+		ret = ade7758_probe_trigger(indio_dev);
 		if (ret)
-			goto error_unregister_line;
+			goto error_remove_trigger;
 	}
 
-	/* Get the device into a sane initial state */
-	ret = ade7758_initial_setup(st);
-	if (ret)
-		goto error_remove_trigger;
 	return 0;
 
 error_remove_trigger:
-	if (st->indio_dev->modes & INDIO_RING_TRIGGERED)
-		ade7758_remove_trigger(st->indio_dev);
-error_unregister_line:
-	if (st->indio_dev->modes & INDIO_RING_TRIGGERED)
-		iio_unregister_interrupt_line(st->indio_dev, 0);
+	if (indio_dev->modes & INDIO_RING_TRIGGERED)
+		ade7758_remove_trigger(indio_dev);
 error_uninitialize_ring:
-	ade7758_uninitialize_ring(st->indio_dev->ring);
+	ade7758_uninitialize_ring(indio_dev->ring);
 error_unreg_ring_funcs:
-	ade7758_unconfigure_ring(st->indio_dev);
-error_free_dev:
-	if (regdone)
-		iio_device_unregister(st->indio_dev);
-	else
-		iio_free_device(st->indio_dev);
+	ade7758_unconfigure_ring(indio_dev);
 error_free_tx:
 	kfree(st->tx);
 error_free_rx:
 	kfree(st->rx);
-error_free_st:
-	kfree(st);
+error_free_dev:
+	if (regdone)
+		iio_device_unregister(indio_dev);
+	else
+		iio_free_device(indio_dev);
 error_ret:
 	return ret;
 }
 
 static int ade7758_remove(struct spi_device *spi)
 {
+	struct iio_dev *indio_dev = spi_get_drvdata(spi);
+	struct ade7758_state *st = iio_priv(indio_dev);
 	int ret;
-	struct ade7758_state *st = spi_get_drvdata(spi);
-	struct iio_dev *indio_dev = st->indio_dev;
 
-	ret = ade7758_stop_device(&(indio_dev->dev));
+	ret = ade7758_stop_device(&indio_dev->dev);
 	if (ret)
 		goto err_ret;
 
-	flush_scheduled_work();
-
 	ade7758_remove_trigger(indio_dev);
-	if (spi->irq && gpio_is_valid(irq_to_gpio(spi->irq)) > 0)
-		iio_unregister_interrupt_line(indio_dev, 0);
-
 	ade7758_uninitialize_ring(indio_dev->ring);
-	iio_device_unregister(indio_dev);
 	ade7758_unconfigure_ring(indio_dev);
 	kfree(st->tx);
 	kfree(st->rx);
-	kfree(st);
+	iio_device_unregister(indio_dev);
 
 	return 0;
-
 err_ret:
 	return ret;
 }
 
+static const struct spi_device_id ade7758_id[] = {
+	{"ade7758", 0},
+	{}
+};
+
 static struct spi_driver ade7758_driver = {
 	.driver = {
 		.name = "ade7758",
@@ -847,6 +854,7 @@
 	},
 	.probe = ade7758_probe,
 	.remove = __devexit_p(ade7758_remove),
+	.id_table = ade7758_id,
 };
 
 static __init int ade7758_init(void)
diff -druN linux-2.6.39-libre/drivers/staging/iio/meter/ade7758.h linux-3.0-rc7-libre/drivers/staging/iio/meter/ade7758.h
--- linux-2.6.39-libre/drivers/staging/iio/meter/ade7758.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/iio/meter/ade7758.h	2011-07-11 19:51:52.000000000 -0400
@@ -1,3 +1,11 @@
+/*
+ * ADE7758 Poly Phase Multifunction Energy Metering IC driver
+ *
+ * Copyright 2010-2011 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2.
+ */
+
 #ifndef _ADE7758_H
 #define _ADE7758_H
 
@@ -83,43 +91,54 @@
 #define ADE7758_MAX_RX    4
 #define ADE7758_STARTUP_DELAY 1
 
-#define ADE7758_SPI_SLOW	(u32)(300 * 1000)
-#define ADE7758_SPI_BURST	(u32)(1000 * 1000)
-#define ADE7758_SPI_FAST	(u32)(2000 * 1000)
+#define AD7758_NUM_WAVSEL	5
+#define AD7758_NUM_PHSEL	3
+#define AD7758_NUM_WAVESRC	(AD7758_NUM_WAVSEL * AD7758_NUM_PHSEL)
+
+#define AD7758_PHASE_A		0
+#define AD7758_PHASE_B		1
+#define AD7758_PHASE_C		2
+#define AD7758_CURRENT		0
+#define AD7758_VOLTAGE		1
+#define AD7758_ACT_PWR		2
+#define AD7758_REACT_PWR	3
+#define AD7758_APP_PWR		4
+#define AD7758_WT(p, w)		(((w) << 2) | (p))
 
 #define DRIVER_NAME		"ade7758"
 
+
 /**
  * struct ade7758_state - device instance specific data
  * @us:			actual spi_device
- * @work_trigger_to_ring: bh for triggered event handling
- * @inter:		used to check if new interrupt has been triggered
- * @last_timestamp:	passing timestamp from th to bh of interrupt handler
- * @indio_dev:		industrial I/O device structure
  * @trig:		data ready trigger registered with iio
  * @tx:			transmit buffer
  * @rx:			receive buffer
  * @buf_lock:		mutex to protect tx and rx
  **/
 struct ade7758_state {
-	struct spi_device		*us;
-	struct work_struct		work_trigger_to_ring;
-	s64				last_timestamp;
-	struct iio_dev			*indio_dev;
-	struct iio_trigger		*trig;
-	u8				*tx;
-	u8				*rx;
-	struct mutex			buf_lock;
+	struct spi_device	*us;
+	struct iio_trigger	*trig;
+	u8			*tx;
+	u8			*rx;
+	struct mutex		buf_lock;
+	u32			available_scan_masks[AD7758_NUM_WAVESRC];
+	struct iio_chan_spec	*ade7758_ring_channels;
+	struct spi_transfer	ring_xfer[4];
+	struct spi_message	ring_msg;
+	/*
+	 * DMA (thus cache coherency maintenance) requires the
+	 * transfer buffers to live in their own cache lines.
+	 */
+	unsigned char		rx_buf[8] ____cacheline_aligned;
+	unsigned char		tx_buf[8];
+
 };
 #ifdef CONFIG_IIO_RING_BUFFER
 /* At the moment triggers are only used for ring buffer
  * filling. This may change!
  */
 
-enum ade7758_scan {
-	ADE7758_SCAN_WFORM,
-};
-
 void ade7758_remove_trigger(struct iio_dev *indio_dev);
 int ade7758_probe_trigger(struct iio_dev *indio_dev);
 
@@ -134,6 +153,12 @@
 int ade7758_initialize_ring(struct iio_ring_buffer *ring);
 void ade7758_uninitialize_ring(struct iio_ring_buffer *ring);
 int ade7758_set_irq(struct device *dev, bool enable);
+
+int ade7758_spi_write_reg_8(struct device *dev,
+		u8 reg_address, u8 val);
+int ade7758_spi_read_reg_8(struct device *dev,
+		u8 reg_address, u8 *val);
+
 #else /* CONFIG_IIO_RING_BUFFER */
 
 static inline void ade7758_remove_trigger(struct iio_dev *indio_dev)
@@ -144,14 +169,6 @@
 	return 0;
 }
 
-static inline ssize_t
-ade7758_read_data_from_ring(struct device *dev,
-		struct device_attribute *attr,
-		char *buf)
-{
-	return 0;
-}
-
 static int ade7758_configure_ring(struct iio_dev *indio_dev)
 {
 	return 0;
diff -druN linux-2.6.39-libre/drivers/staging/iio/meter/ade7758_ring.c linux-3.0-rc7-libre/drivers/staging/iio/meter/ade7758_ring.c
--- linux-2.6.39-libre/drivers/staging/iio/meter/ade7758_ring.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/iio/meter/ade7758_ring.c	2011-07-11 19:51:52.000000000 -0400
@@ -1,3 +1,10 @@
+/*
+ * ADE7758 Poly Phase Multifunction Energy Metering IC driver
+ *
+ * Copyright 2010-2011 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2.
+ */
 #include <linux/interrupt.h>
 #include <linux/irq.h>
 #include <linux/gpio.h>
@@ -9,6 +16,7 @@
 #include <linux/slab.h>
 #include <linux/sysfs.h>
 #include <linux/list.h>
+#include <asm/unaligned.h>
 
 #include "../iio.h"
 #include "../sysfs.h"
@@ -18,182 +26,188 @@
 #include "ade7758.h"
 
 /**
- * combine_8_to_32() utility function to munge to u8s into u32
+ * ade7758_spi_read_burst() - read data registers
+ * @dev: device associated with child of actual device (iio_dev or iio_trig)
  **/
-static inline u32 combine_8_to_32(u8 lower, u8 mid, u8 upper)
+static int ade7758_spi_read_burst(struct device *dev)
 {
-	u32 _lower = lower;
-	u32 _mid = mid;
-	u32 _upper = upper;
-
-	return _lower | (_mid << 8) | (_upper << 16);
-}
-
-static IIO_SCAN_EL_C(wform, ADE7758_SCAN_WFORM, ADE7758_WFORM, NULL);
-static IIO_CONST_ATTR_SCAN_EL_TYPE(wform, s, 24, 32);
-static IIO_SCAN_EL_TIMESTAMP(1);
-static IIO_CONST_ATTR_SCAN_EL_TYPE(timestamp, s, 64, 64);
-
-static struct attribute *ade7758_scan_el_attrs[] = {
-	&iio_scan_el_wform.dev_attr.attr,
-	&iio_const_attr_wform_index.dev_attr.attr,
-	&iio_const_attr_wform_type.dev_attr.attr,
-	&iio_scan_el_timestamp.dev_attr.attr,
-	&iio_const_attr_timestamp_index.dev_attr.attr,
-	&iio_const_attr_timestamp_type.dev_attr.attr,
-	NULL,
-};
-
-static struct attribute_group ade7758_scan_el_group = {
-	.attrs = ade7758_scan_el_attrs,
-	.name = "scan_elements",
-};
+	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+	struct ade7758_state *st = iio_priv(indio_dev);
+	int ret;
 
-/**
- * ade7758_poll_func_th() top half interrupt handler called by trigger
- * @private_data:	iio_dev
- **/
-static void ade7758_poll_func_th(struct iio_dev *indio_dev, s64 time)
-{
-	struct ade7758_state *st = iio_dev_get_devdata(indio_dev);
-	st->last_timestamp = time;
-	schedule_work(&st->work_trigger_to_ring);
-	/* Indicate that this interrupt is being handled */
+	ret = spi_sync(st->us, &st->ring_msg);
+	if (ret)
+		dev_err(&st->us->dev, "problem when reading WFORM value\n");
 
-	/* Technically this is trigger related, but without this
-	 * handler running there is currently no way for the interrupt
-	 * to clear.
-	 */
+	return ret;
 }
 
-/**
- * ade7758_spi_read_burst() - read all data registers
- * @dev: device associated with child of actual device (iio_dev or iio_trig)
- * @rx: somewhere to pass back the value read (min size is 24 bytes)
- **/
-static int ade7758_spi_read_burst(struct device *dev, u8 *rx)
+static int ade7758_write_waveform_type(struct device *dev, unsigned type)
 {
-	struct spi_message msg;
-	struct iio_dev *indio_dev = dev_get_drvdata(dev);
-	struct ade7758_state *st = iio_dev_get_devdata(indio_dev);
 	int ret;
+	u8 reg;
 
-	struct spi_transfer xfers[] = {
-		{
-			.tx_buf = st->tx,
-			.rx_buf = rx,
-			.bits_per_word = 8,
-			.len = 4,
-		}, {
-			.tx_buf = st->tx + 4,
-			.rx_buf = rx,
-			.bits_per_word = 8,
-			.len = 4,
-		},
-	};
-
-	mutex_lock(&st->buf_lock);
-	st->tx[0] = ADE7758_READ_REG(ADE7758_RSTATUS);
-	st->tx[1] = 0;
-	st->tx[2] = 0;
-	st->tx[3] = 0;
-	st->tx[4] = ADE7758_READ_REG(ADE7758_WFORM);
-	st->tx[5] = 0;
-	st->tx[6] = 0;
-	st->tx[7] = 0;
-
-	spi_message_init(&msg);
-	spi_message_add_tail(&xfers[0], &msg);
-	spi_message_add_tail(&xfers[1], &msg);
-	ret = spi_sync(st->us, &msg);
+	ret = ade7758_spi_read_reg_8(dev,
+			ADE7758_WAVMODE,
+			&reg);
 	if (ret)
-		dev_err(&st->us->dev, "problem when reading WFORM value\n");
+		goto out;
 
-	mutex_unlock(&st->buf_lock);
+	reg &= ~0x1F;
+	reg |= type & 0x1F;
 
+	ret = ade7758_spi_write_reg_8(dev,
+			ADE7758_WAVMODE,
+			reg);
+out:
 	return ret;
 }
 
 /* Whilst this makes a lot of calls to iio_sw_ring functions - it is to device
  * specific to be rolled into the core.
  */
-static void ade7758_trigger_bh_to_ring(struct work_struct *work_s)
+static irqreturn_t ade7758_trigger_handler(int irq, void *p)
 {
-	struct ade7758_state *st
-		= container_of(work_s, struct ade7758_state,
-			       work_trigger_to_ring);
-	struct iio_ring_buffer *ring = st->indio_dev->ring;
-
-	int i = 0;
-	s32 *data;
-	size_t datasize = ring->access.get_bytes_per_datum(ring);
-
-	data = kmalloc(datasize, GFP_KERNEL);
-	if (data == NULL) {
-		dev_err(&st->us->dev, "memory alloc failed in ring bh");
-		return;
-	}
+	struct iio_poll_func *pf = p;
+	struct iio_dev *indio_dev = pf->private_data;
+	struct iio_ring_buffer *ring = indio_dev->ring;
+	struct ade7758_state *st = iio_priv(indio_dev);
+	s64 dat64[2];
+	u32 *dat32 = (u32 *)dat64;
 
 	if (ring->scan_count)
-		if (ade7758_spi_read_burst(&st->indio_dev->dev, st->rx) >= 0)
-			for (; i < ring->scan_count; i++)
-				data[i] = combine_8_to_32(st->rx[i*2+2],
-						st->rx[i*2+1],
-						st->rx[i*2]);
+		if (ade7758_spi_read_burst(&indio_dev->dev) >= 0)
+			*dat32 = get_unaligned_be32(&st->rx_buf[5]) & 0xFFFFFF;
 
 	/* Guaranteed to be aligned with 8 byte boundary */
 	if (ring->scan_timestamp)
-		*((s64 *)
-		(((u32)data + 4 * ring->scan_count + 4) & ~0x7)) =
-			st->last_timestamp;
+		dat64[1] = pf->timestamp;
 
-	ring->access.store_to(ring,
-			      (u8 *)data,
-			      st->last_timestamp);
+	ring->access->store_to(ring, (u8 *)dat64, pf->timestamp);
 
-	iio_trigger_notify_done(st->indio_dev->trig);
-	kfree(data);
+	iio_trigger_notify_done(indio_dev->trig);
 
-	return;
+	return IRQ_HANDLED;
+}
+
+/**
+ * ade7758_ring_preenable() setup the parameters of the ring before enabling
+ *
+ * The complex nature of the setting of the nuber of bytes per datum is due
+ * to this driver currently ensuring that the timestamp is stored at an 8
+ * byte boundary.
+ **/
+static int ade7758_ring_preenable(struct iio_dev *indio_dev)
+{
+	struct ade7758_state *st = iio_priv(indio_dev);
+	struct iio_ring_buffer *ring = indio_dev->ring;
+	size_t d_size;
+	unsigned channel;
+
+	if (!ring->scan_count)
+		return -EINVAL;
+
+	channel = __ffs(ring->scan_mask);
+
+	d_size = st->ade7758_ring_channels[channel].scan_type.storagebits / 8;
+
+	if (ring->scan_timestamp) {
+		d_size += sizeof(s64);
+
+		if (d_size % sizeof(s64))
+			d_size += sizeof(s64) - (d_size % sizeof(s64));
+	}
+
+	if (indio_dev->ring->access->set_bytes_per_datum)
+		indio_dev->ring->access->set_bytes_per_datum(indio_dev->ring,
+							    d_size);
+
+	ade7758_write_waveform_type(&indio_dev->dev,
+		st->ade7758_ring_channels[channel].address);
+
+	return 0;
 }
 
+static const struct iio_ring_setup_ops ade7758_ring_setup_ops = {
+	.preenable = &ade7758_ring_preenable,
+	.postenable = &iio_triggered_ring_postenable,
+	.predisable = &iio_triggered_ring_predisable,
+};
+
 void ade7758_unconfigure_ring(struct iio_dev *indio_dev)
 {
-	kfree(indio_dev->pollfunc);
+	/* ensure that the trigger has been detached */
+	if (indio_dev->trig) {
+		iio_put_trigger(indio_dev->trig);
+		iio_trigger_dettach_poll_func(indio_dev->trig,
+					      indio_dev->pollfunc);
+	}
+	iio_dealloc_pollfunc(indio_dev->pollfunc);
 	iio_sw_rb_free(indio_dev->ring);
 }
 
 int ade7758_configure_ring(struct iio_dev *indio_dev)
 {
+	struct ade7758_state *st = iio_priv(indio_dev);
 	int ret = 0;
-	struct ade7758_state *st = indio_dev->dev_data;
-	struct iio_ring_buffer *ring;
-	INIT_WORK(&st->work_trigger_to_ring, ade7758_trigger_bh_to_ring);
 
-	ring = iio_sw_rb_allocate(indio_dev);
-	if (!ring) {
+	indio_dev->ring = iio_sw_rb_allocate(indio_dev);
+	if (!indio_dev->ring) {
 		ret = -ENOMEM;
 		return ret;
 	}
-	indio_dev->ring = ring;
-	/* Effectively select the ring buffer implementation */
-	iio_ring_sw_register_funcs(&ring->access);
-	ring->bpe = 4;
-	ring->scan_el_attrs = &ade7758_scan_el_group;
-	ring->scan_timestamp = true;
-	ring->preenable = &iio_sw_ring_preenable;
-	ring->postenable = &iio_triggered_ring_postenable;
-	ring->predisable = &iio_triggered_ring_predisable;
-	ring->owner = THIS_MODULE;
 
-	/* Set default scan mode */
-	iio_scan_mask_set(ring, iio_scan_el_wform.number);
+	/* Effectively select the ring buffer implementation */
+	indio_dev->ring->access = &ring_sw_access_funcs;
+	indio_dev->ring->setup_ops = &ade7758_ring_setup_ops;
+	indio_dev->ring->owner = THIS_MODULE;
 
-	ret = iio_alloc_pollfunc(indio_dev, NULL, &ade7758_poll_func_th);
-	if (ret)
+	indio_dev->pollfunc = iio_alloc_pollfunc(&iio_pollfunc_store_time,
+						 &ade7758_trigger_handler,
+						 0,
+						 indio_dev,
+						 "ade7759_consumer%d",
+						 indio_dev->id);
+	if (indio_dev->pollfunc == NULL) {
+		ret = -ENOMEM;
 		goto error_iio_sw_rb_free;
+	}
 
 	indio_dev->modes |= INDIO_RING_TRIGGERED;
+
+	st->tx_buf[0] = ADE7758_READ_REG(ADE7758_RSTATUS);
+	st->tx_buf[1] = 0;
+	st->tx_buf[2] = 0;
+	st->tx_buf[3] = 0;
+	st->tx_buf[4] = ADE7758_READ_REG(ADE7758_WFORM);
+	st->tx_buf[5] = 0;
+	st->tx_buf[6] = 0;
+	st->tx_buf[7] = 0;
+
+	/* build spi ring message */
+	st->ring_xfer[0].tx_buf = &st->tx_buf[0];
+	st->ring_xfer[0].len = 1;
+	st->ring_xfer[0].bits_per_word = 8;
+	st->ring_xfer[0].delay_usecs = 4;
+	st->ring_xfer[1].rx_buf = &st->rx_buf[1];
+	st->ring_xfer[1].len = 3;
+	st->ring_xfer[1].bits_per_word = 8;
+	st->ring_xfer[1].cs_change = 1;
+
+	st->ring_xfer[2].tx_buf = &st->tx_buf[4];
+	st->ring_xfer[2].len = 1;
+	st->ring_xfer[2].bits_per_word = 8;
+	st->ring_xfer[2].delay_usecs = 1;
+	st->ring_xfer[3].rx_buf = &st->rx_buf[5];
+	st->ring_xfer[3].len = 3;
+	st->ring_xfer[3].bits_per_word = 8;
+
+	spi_message_init(&st->ring_msg);
+	spi_message_add_tail(&st->ring_xfer[0], &st->ring_msg);
+	spi_message_add_tail(&st->ring_xfer[1], &st->ring_msg);
+	spi_message_add_tail(&st->ring_xfer[2], &st->ring_msg);
+	spi_message_add_tail(&st->ring_xfer[3], &st->ring_msg);
+
 	return 0;
 
 error_iio_sw_rb_free:
@@ -201,11 +215,6 @@
 	return ret;
 }
 
-int ade7758_initialize_ring(struct iio_ring_buffer *ring)
-{
-	return iio_ring_buffer_register(ring, 0);
-}
-
 void ade7758_uninitialize_ring(struct iio_ring_buffer *ring)
 {
 	iio_ring_buffer_unregister(ring);
diff -druN linux-2.6.39-libre/drivers/staging/iio/meter/ade7758_trigger.c linux-3.0-rc7-libre/drivers/staging/iio/meter/ade7758_trigger.c
--- linux-2.6.39-libre/drivers/staging/iio/meter/ade7758_trigger.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/iio/meter/ade7758_trigger.c	2011-07-11 19:51:52.000000000 -0400
@@ -1,3 +1,11 @@
+/*
+ * ADE7758 Poly Phase Multifunction Energy Metering IC driver
+ *
+ * Copyright 2010-2011 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2.
+ */
+
 #include <linux/interrupt.h>
 #include <linux/irq.h>
 #include <linux/mutex.h>
@@ -15,56 +23,24 @@
 /**
  * ade7758_data_rdy_trig_poll() the event handler for the data rdy trig
  **/
-static int ade7758_data_rdy_trig_poll(struct iio_dev *dev_info,
-				       int index,
-				       s64 timestamp,
-				       int no_test)
+static irqreturn_t ade7758_data_rdy_trig_poll(int irq, void *private)
 {
-	struct ade7758_state *st = iio_dev_get_devdata(dev_info);
-	struct iio_trigger *trig = st->trig;
-
-	iio_trigger_poll(trig, timestamp);
+	disable_irq_nosync(irq);
+	iio_trigger_poll(private, iio_get_time_ns());
 
 	return IRQ_HANDLED;
 }
 
-IIO_EVENT_SH(data_rdy_trig, &ade7758_data_rdy_trig_poll);
-
-static DEVICE_ATTR(name, S_IRUGO, iio_trigger_read_name, NULL);
-
-static struct attribute *ade7758_trigger_attrs[] = {
-	&dev_attr_name.attr,
-	NULL,
-};
-
-static const struct attribute_group ade7758_trigger_attr_group = {
-	.attrs = ade7758_trigger_attrs,
-};
-
 /**
  * ade7758_data_rdy_trigger_set_state() set datardy interrupt state
  **/
 static int ade7758_data_rdy_trigger_set_state(struct iio_trigger *trig,
 						bool state)
 {
-	struct ade7758_state *st = trig->private_data;
-	struct iio_dev *indio_dev = st->indio_dev;
-	int ret = 0;
+	struct iio_dev *indio_dev = trig->private_data;
 
 	dev_dbg(&indio_dev->dev, "%s (%d)\n", __func__, state);
-	ret = ade7758_set_irq(&st->indio_dev->dev, state);
-	if (state == false) {
-		iio_remove_event_from_list(&iio_event_data_rdy_trig,
-					   &indio_dev->interrupts[0]
-					   ->ev_list);
-		/* possible quirk with handler currently worked around
-		   by ensuring the work queue is empty */
-		flush_scheduled_work();
-	} else {
-		iio_add_event_to_list(&iio_event_data_rdy_trig,
-				      &indio_dev->interrupts[0]->ev_list);
-	}
-	return ret;
+	return ade7758_set_irq(&indio_dev->dev, state);
 }
 
 /**
@@ -73,7 +49,9 @@
  **/
 static int ade7758_trig_try_reen(struct iio_trigger *trig)
 {
-	struct ade7758_state *st = trig->private_data;
+	struct iio_dev *indio_dev = trig->private_data;
+	struct ade7758_state *st = iio_priv(indio_dev);
+
 	enable_irq(st->us->irq);
 	/* irq reenabled so success! */
 	return 0;
@@ -81,45 +59,52 @@
 
 int ade7758_probe_trigger(struct iio_dev *indio_dev)
 {
+	struct ade7758_state *st = iio_priv(indio_dev);
 	int ret;
-	struct ade7758_state *st = indio_dev->dev_data;
 
-	st->trig = iio_allocate_trigger();
-	st->trig->name = kasprintf(GFP_KERNEL,
-				"ade7758-dev%d",
-				indio_dev->id);
-	if (!st->trig->name) {
+	st->trig = iio_allocate_trigger("%s-dev%d",
+					spi_get_device_id(st->us)->name,
+					indio_dev->id);
+	if (st->trig == NULL) {
 		ret = -ENOMEM;
-		goto error_free_trig;
+		goto error_ret;
 	}
+
+	ret = request_irq(st->us->irq,
+			  ade7758_data_rdy_trig_poll,
+			  IRQF_TRIGGER_LOW,
+			  spi_get_device_id(st->us)->name,
+			  st->trig);
+	if (ret)
+		goto error_free_trig;
+
 	st->trig->dev.parent = &st->us->dev;
 	st->trig->owner = THIS_MODULE;
-	st->trig->private_data = st;
+	st->trig->private_data = indio_dev;
 	st->trig->set_trigger_state = &ade7758_data_rdy_trigger_set_state;
 	st->trig->try_reenable = &ade7758_trig_try_reen;
-	st->trig->control_attrs = &ade7758_trigger_attr_group;
 	ret = iio_trigger_register(st->trig);
 
 	/* select default trigger */
 	indio_dev->trig = st->trig;
 	if (ret)
-		goto error_free_trig_name;
+		goto error_free_irq;
 
 	return 0;
 
-error_free_trig_name:
-	kfree(st->trig->name);
+error_free_irq:
+	free_irq(st->us->irq, st->trig);
 error_free_trig:
 	iio_free_trigger(st->trig);
-
+error_ret:
 	return ret;
 }
 
 void ade7758_remove_trigger(struct iio_dev *indio_dev)
 {
-	struct ade7758_state *state = indio_dev->dev_data;
+	struct ade7758_state *st = iio_priv(indio_dev);
 
-	iio_trigger_unregister(state->trig);
-	kfree(state->trig->name);
-	iio_free_trigger(state->trig);
+	iio_trigger_unregister(st->trig);
+	free_irq(st->us->irq, st->trig);
+	iio_free_trigger(st->trig);
 }
diff -druN linux-2.6.39-libre/drivers/staging/iio/meter/ade7759.c linux-3.0-rc7-libre/drivers/staging/iio/meter/ade7759.c
--- linux-2.6.39-libre/drivers/staging/iio/meter/ade7759.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/iio/meter/ade7759.c	2011-07-11 19:51:52.000000000 -0400
@@ -422,8 +422,6 @@
 
 static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("27900 14000 7000 3500");
 
-static IIO_CONST_ATTR(name, "ade7759");
-
 static struct attribute *ade7759_attributes[] = {
 	&iio_dev_attr_temp_raw.dev_attr.attr,
 	&iio_const_attr_temp_offset.dev_attr.attr,
@@ -431,7 +429,6 @@
 	&iio_dev_attr_sampling_frequency.dev_attr.attr,
 	&iio_const_attr_sampling_frequency_available.dev_attr.attr,
 	&iio_dev_attr_reset.dev_attr.attr,
-	&iio_const_attr_name.dev_attr.attr,
 	&iio_dev_attr_phcal.dev_attr.attr,
 	&iio_dev_attr_cfden.dev_attr.attr,
 	&iio_dev_attr_aenergy.dev_attr.attr,
@@ -453,6 +450,11 @@
 	.attrs = ade7759_attributes,
 };
 
+static const struct iio_info ade7759_info = {
+	.attrs = &ade7759_attribute_group,
+	.driver_module = THIS_MODULE,
+};
+
 static int __devinit ade7759_probe(struct spi_device *spi)
 {
 	int ret;
@@ -478,18 +480,17 @@
 	st->us = spi;
 	mutex_init(&st->buf_lock);
 	/* setup the industrialio driver allocated elements */
-	st->indio_dev = iio_allocate_device();
+	st->indio_dev = iio_allocate_device(0);
 	if (st->indio_dev == NULL) {
 		ret = -ENOMEM;
 		goto error_free_tx;
 	}
 
+	st->indio_dev->name = spi->dev.driver->name;
 	st->indio_dev->dev.parent = &spi->dev;
-	st->indio_dev->num_interrupt_lines = 1;
 
-	st->indio_dev->attrs = &ade7759_attribute_group;
+	st->indio_dev->info = &ade7759_info;
 	st->indio_dev->dev_data = (void *)(st);
-	st->indio_dev->driver_module = THIS_MODULE;
 	st->indio_dev->modes = INDIO_DIRECT_MODE;
 
 	ret = iio_device_register(st->indio_dev);
diff -druN linux-2.6.39-libre/drivers/staging/iio/meter/ade7854.c linux-3.0-rc7-libre/drivers/staging/iio/meter/ade7854.c
--- linux-2.6.39-libre/drivers/staging/iio/meter/ade7854.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/iio/meter/ade7854.c	2011-07-11 19:51:52.000000000 -0400
@@ -551,6 +551,11 @@
 	.attrs = ade7854_attributes,
 };
 
+static const struct iio_info ade7854_info = {
+	.attrs = &ade7854_attribute_group,
+	.driver_module = THIS_MODULE,
+};
+
 int ade7854_probe(struct ade7854_state *st, struct device *dev)
 {
 	int ret;
@@ -568,16 +573,15 @@
 	}
 	mutex_init(&st->buf_lock);
 	/* setup the industrialio driver allocated elements */
-	st->indio_dev = iio_allocate_device();
+	st->indio_dev = iio_allocate_device(0);
 	if (st->indio_dev == NULL) {
 		ret = -ENOMEM;
 		goto error_free_tx;
 	}
 
 	st->indio_dev->dev.parent = dev;
-	st->indio_dev->attrs = &ade7854_attribute_group;
+	st->indio_dev->info = &ade7854_info;
 	st->indio_dev->dev_data = (void *)(st);
-	st->indio_dev->driver_module = THIS_MODULE;
 	st->indio_dev->modes = INDIO_DIRECT_MODE;
 
 	ret = iio_device_register(st->indio_dev);
diff -druN linux-2.6.39-libre/drivers/staging/iio/resolver/ad2s120x.c linux-3.0-rc7-libre/drivers/staging/iio/resolver/ad2s120x.c
--- linux-2.6.39-libre/drivers/staging/iio/resolver/ad2s120x.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/iio/resolver/ad2s120x.c	2011-07-11 19:51:52.000000000 -0400
@@ -209,10 +209,14 @@
 };
 
 static const struct attribute_group ad2s120x_attribute_group = {
-	.name = DRV_NAME,
 	.attrs = ad2s120x_attributes,
 };
 
+static const struct iio_info ad2s120x_info = {
+	.attrs = &ad2s120x_attribute_group,
+	.driver_module = THIS_MODULE,
+};
+
 static int __devinit ad2s120x_probe(struct spi_device *spi)
 {
 	struct ad2s120x_state *st;
@@ -240,18 +244,15 @@
 	st->sample = pins[0];
 	st->rdvel = pins[1];
 
-	st->idev = iio_allocate_device();
+	st->idev = iio_allocate_device(0);
 	if (st->idev == NULL) {
 		ret = -ENOMEM;
 		goto error_free_st;
 	}
 	st->idev->dev.parent = &spi->dev;
-	st->idev->num_interrupt_lines = 0;
-	st->idev->event_attrs = NULL;
 
-	st->idev->attrs = &ad2s120x_attribute_group;
+	st->idev->info = &ad2s120x_info;
 	st->idev->dev_data = (void *)(st);
-	st->idev->driver_module = THIS_MODULE;
 	st->idev->modes = INDIO_DIRECT_MODE;
 
 	ret = iio_device_register(st->idev);
diff -druN linux-2.6.39-libre/drivers/staging/iio/resolver/ad2s1210.c linux-3.0-rc7-libre/drivers/staging/iio/resolver/ad2s1210.c
--- linux-2.6.39-libre/drivers/staging/iio/resolver/ad2s1210.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/iio/resolver/ad2s1210.c	2011-07-11 19:51:52.000000000 -0400
@@ -755,6 +755,11 @@
 	return ret;
 }
 
+static const struct iio_info ad2s1210_info = {
+	.attrs = &ad2s1210_attribute_group,
+	.driver_module = THIS_MODULE,
+};
+
 static int __devinit ad2s1210_probe(struct spi_device *spi)
 {
 	struct ad2s1210_state *st;
@@ -800,18 +805,15 @@
 	st->res0 = pins[3];
 	st->res1 = pins[4];
 
-	st->idev = iio_allocate_device();
+	st->idev = iio_allocate_device(0);
 	if (st->idev == NULL) {
 		ret = -ENOMEM;
 		goto error_free_st;
 	}
 	st->idev->dev.parent = &spi->dev;
-	st->idev->num_interrupt_lines = 0;
-	st->idev->event_attrs = NULL;
 
-	st->idev->attrs = &ad2s1210_attribute_group;
+	st->idev->info = &ad2s1210_info;
 	st->idev->dev_data = (void *)(st);
-	st->idev->driver_module = THIS_MODULE;
 	st->idev->modes = INDIO_DIRECT_MODE;
 
 	ret = iio_device_register(st->idev);
diff -druN linux-2.6.39-libre/drivers/staging/iio/resolver/ad2s90.c linux-3.0-rc7-libre/drivers/staging/iio/resolver/ad2s90.c
--- linux-2.6.39-libre/drivers/staging/iio/resolver/ad2s90.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/iio/resolver/ad2s90.c	2011-07-11 19:51:52.000000000 -0400
@@ -75,6 +75,11 @@
 	.attrs = ad2s90_attributes,
 };
 
+static const struct iio_info ad2s90_info = {
+	.attrs = &ad2s90_attribute_group,
+	.driver_module = THIS_MODULE,
+};
+
 static int __devinit ad2s90_probe(struct spi_device *spi)
 {
 	struct ad2s90_state *st;
@@ -90,18 +95,15 @@
 	mutex_init(&st->lock);
 	st->sdev = spi;
 
-	st->idev = iio_allocate_device();
+	st->idev = iio_allocate_device(0);
 	if (st->idev == NULL) {
 		ret = -ENOMEM;
 		goto error_free_st;
 	}
 	st->idev->dev.parent = &spi->dev;
-	st->idev->num_interrupt_lines = 0;
-	st->idev->event_attrs = NULL;
 
-	st->idev->attrs = &ad2s90_attribute_group;
+	st->idev->info = &ad2s90_info;
 	st->idev->dev_data = (void *)(st);
-	st->idev->driver_module = THIS_MODULE;
 	st->idev->modes = INDIO_DIRECT_MODE;
 
 	ret = iio_device_register(st->idev);
diff -druN linux-2.6.39-libre/drivers/staging/iio/ring_generic.h linux-3.0-rc7-libre/drivers/staging/iio/ring_generic.h
--- linux-2.6.39-libre/drivers/staging/iio/ring_generic.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/iio/ring_generic.h	2011-07-11 19:51:52.000000000 -0400
@@ -16,35 +16,12 @@
 struct iio_ring_buffer;
 
 /**
- * iio_push_ring_event() - ring buffer specific push to event chrdev
- * @ring_buf:		ring buffer that is the event source
- * @event_code:		event indentification code
- * @timestamp:		time of event
- **/
-int iio_push_ring_event(struct iio_ring_buffer *ring_buf,
-			int event_code,
-			s64 timestamp);
-/**
- * iio_push_or_escallate_ring_event() -	escalate or add as appropriate
- * @ring_buf:		ring buffer that is the event source
- * @event_code:		event indentification code
- * @timestamp:		time of event
- *
- * Typical usecase is to escalate a 50% ring full to 75% full if no one has yet
- * read the first event. Clearly the 50% full is no longer of interest in
- * typical use case.
- **/
-int iio_push_or_escallate_ring_event(struct iio_ring_buffer *ring_buf,
-				     int event_code,
-				     s64 timestamp);
-
-/**
  * struct iio_ring_access_funcs - access functions for ring buffers.
  * @mark_in_use:	reference counting, typically to prevent module removal
  * @unmark_in_use:	reduce reference count when no longer using ring buffer
  * @store_to:		actually store stuff to the ring buffer
  * @read_last:		get the last element stored
- * @rip_lots:		try to get a specified number of elements (must exist)
+ * @read_first_n:	try to get a specified number of elements (must exist)
  * @mark_param_change:	notify ring that some relevant parameter has changed
  *			Often this means the underlying storage may need to
  *			change.
@@ -71,10 +48,9 @@
 
 	int (*store_to)(struct iio_ring_buffer *ring, u8 *data, s64 timestamp);
 	int (*read_last)(struct iio_ring_buffer *ring, u8 *data);
-	int (*rip_lots)(struct iio_ring_buffer *ring,
-			size_t count,
-			char __user *buf,
-			int *dead_offset);
+	int (*read_first_n)(struct iio_ring_buffer *ring,
+			    size_t n,
+			    char __user *buf);
 
 	int (*mark_param_change)(struct iio_ring_buffer *ring);
 	int (*request_update)(struct iio_ring_buffer *ring);
@@ -88,58 +64,52 @@
 	int (*enable)(struct iio_ring_buffer *ring);
 };
 
+struct iio_ring_setup_ops {
+	int				(*preenable)(struct iio_dev *);
+	int				(*postenable)(struct iio_dev *);
+	int				(*predisable)(struct iio_dev *);
+	int				(*postdisable)(struct iio_dev *);
+};
+
 /**
  * struct iio_ring_buffer - general ring buffer structure
  * @dev:		ring buffer device struct
- * @access_dev:		system device struct for the chrdev
  * @indio_dev:		industrial I/O device structure
  * @owner:		module that owns the ring buffer (for ref counting)
- * @id:			unique id number
- * @access_id:		device id number
  * @length:		[DEVICE] number of datums in ring
  * @bytes_per_datum:	[DEVICE] size of individual datum including timestamp
  * @bpe:		[DEVICE] size of individual channel value
- * @loopcount:		[INTERN] number of times the ring has looped
  * @scan_el_attrs:	[DRIVER] control of scan elements if that scan mode
  *			control method is used
  * @scan_count:	[INTERN] the number of elements in the current scan mode
  * @scan_mask:		[INTERN] bitmask used in masking scan mode elements
  * @scan_timestamp:	[INTERN] does the scan mode include a timestamp
  * @access_handler:	[INTERN] chrdev access handling
- * @ev_int:		[INTERN] chrdev interface for the event chrdev
- * @shared_ev_pointer:	[INTERN] the shared event pointer to allow escalation of
- *			events
  * @access:		[DRIVER] ring access functions associated with the
  *			implementation.
  * @preenable:		[DRIVER] function to run prior to marking ring enabled
  * @postenable:		[DRIVER] function to run after marking ring enabled
  * @predisable:		[DRIVER] function to run prior to marking ring disabled
  * @postdisable:	[DRIVER] function to run after marking ring disabled
-  **/
+ **/
 struct iio_ring_buffer {
-	struct device dev;
-	struct device access_dev;
-	struct iio_dev *indio_dev;
-	struct module *owner;
-	int				id;
-	int				access_id;
-	int				length;
-	int				bytes_per_datum;
-	int				bpe;
-	int				loopcount;
-	struct attribute_group		*scan_el_attrs;
-	int				scan_count;
-	u32				scan_mask;
-	bool				scan_timestamp;
-	struct iio_handler		access_handler;
-	struct iio_event_interface	ev_int;
-	struct iio_shared_ev_pointer	shared_ev_pointer;
-	struct iio_ring_access_funcs	access;
-	int				(*preenable)(struct iio_dev *);
-	int				(*postenable)(struct iio_dev *);
-	int				(*predisable)(struct iio_dev *);
-	int				(*postdisable)(struct iio_dev *);
+	struct device				dev;
+	struct iio_dev				*indio_dev;
+	struct module				*owner;
+	int					length;
+	int					bytes_per_datum;
+	int					bpe;
+	struct attribute_group			*scan_el_attrs;
+	int					scan_count;
+	unsigned long				scan_mask;
+	bool					scan_timestamp;
+	struct iio_handler			access_handler;
+	const struct iio_ring_access_funcs	*access;
+	const struct iio_ring_setup_ops		*setup_ops;
+	struct list_head			scan_el_dev_attr_list;
 
+	wait_queue_head_t			pollq;
+	bool					stufftoread;
 };
 
 /**
@@ -161,154 +131,8 @@
 {
 	ring->bytes_per_datum = bytes_per_datum;
 	ring->length = length;
-	ring->loopcount = 0;
 }
 
-/**
- * struct iio_scan_el - an individual element of a scan
- * @dev_attr:		control attribute (if directly controllable)
- * @number:		unique identifier of element (used for bit mask)
- * @label:		useful data for the scan el (often reg address)
- * @set_state:		for some devices datardy signals are generated
- *			for any enabled lines.  This allows unwanted lines
- *			to be disabled and hence not get in the way.
- **/
-struct iio_scan_el {
-	struct device_attribute		dev_attr;
-	unsigned int			number;
-	unsigned int			label;
-
-	int (*set_state)(struct iio_scan_el *scanel,
-			 struct iio_dev *dev_info,
-			 bool state);
-};
-
-#define to_iio_scan_el(_dev_attr)				\
-	container_of(_dev_attr, struct iio_scan_el, dev_attr);
-
-/**
- * iio_scan_el_store() - sysfs scan element selection interface
- * @dev: the target device
- * @attr: the device attribute that is being processed
- * @buf: input from userspace
- * @len: length of input
- *
- * A generic function used to enable various scan elements.  In some
- * devices explicit read commands for each channel mean this is merely
- * a software switch.  In others this must actively disable the channel.
- * Complexities occur when this interacts with data ready type triggers
- * which may not reset unless every channel that is enabled is explicitly
- * read.
- **/
-ssize_t iio_scan_el_store(struct device *dev, struct device_attribute *attr,
-			  const char *buf, size_t len);
-/**
- * iio_scan_el_show() -	sysfs interface to query whether a scan element
- *			is enabled or not
- * @dev: the target device
- * @attr: the device attribute that is being processed
- * @buf: output buffer
- **/
-ssize_t iio_scan_el_show(struct device *dev, struct device_attribute *attr,
-			 char *buf);
-
-/**
- * iio_scan_el_ts_store() - sysfs interface to set whether a timestamp is included
- *			    in the scan.
- **/
-ssize_t iio_scan_el_ts_store(struct device *dev, struct device_attribute *attr,
-			     const char *buf, size_t len);
-/**
- * iio_scan_el_ts_show() - sysfs interface to query if a timestamp is included
- *			   in the scan.
- **/
-ssize_t iio_scan_el_ts_show(struct device *dev, struct device_attribute *attr,
-			    char *buf);
-/**
- * IIO_SCAN_EL_C - declare and initialize a scan element with a control func
- *
- * @_name:	identifying name. Resulting struct is iio_scan_el_##_name,
- *		sysfs element, _name##_en.
- * @_number:	unique id number for the scan element.
- *		length devices).
- * @_label:	indentification variable used by drivers.  Often a reg address.
- * @_controlfunc: function used to notify hardware of whether state changes
- **/
-#define __IIO_SCAN_EL_C(_name, _number, _label, _controlfunc)	\
-	struct iio_scan_el iio_scan_el_##_name = {			\
-		.dev_attr = __ATTR(_name##_en,				\
-				   S_IRUGO | S_IWUSR,			\
-				   iio_scan_el_show,			\
-				   iio_scan_el_store),			\
-		.number =  _number,					\
-		.label = _label,					\
-		.set_state = _controlfunc,				\
-	};								\
-	static IIO_CONST_ATTR(_name##_index, #_number)
-
-#define IIO_SCAN_EL_C(_name, _number, _label, _controlfunc)	\
-	__IIO_SCAN_EL_C(_name, _number, _label, _controlfunc)
-
-#define __IIO_SCAN_NAMED_EL_C(_name, _string, _number, _label, _cf)	\
-	struct iio_scan_el iio_scan_el_##_name = {			\
-		.dev_attr = __ATTR(_string##_en,			\
-				   S_IRUGO | S_IWUSR,			\
-				   iio_scan_el_show,			\
-				   iio_scan_el_store),			\
-		.number =  _number,					\
-		.label = _label,					\
-		.set_state = _cf,					\
-	};								\
-	static struct iio_const_attr iio_const_attr_##_name##_index = {	\
-		.string = #_number,					\
-		.dev_attr = __ATTR(_string##_index,			\
-				   S_IRUGO, iio_read_const_attr, NULL)	\
-	}
-
-
-#define IIO_SCAN_NAMED_EL_C(_name, _string, _number, _label, _cf) \
-	__IIO_SCAN_NAMED_EL_C(_name, _string, _number, _label, _cf)
-/**
- * IIO_SCAN_EL_TIMESTAMP - declare a special scan element for timestamps
- * @number: specify where in the scan order this is stored.
- *
- * Odd one out. Handled slightly differently from other scan elements.
- **/
-#define IIO_SCAN_EL_TIMESTAMP(number)				\
-	struct iio_scan_el iio_scan_el_timestamp = {		\
-		.dev_attr = __ATTR(timestamp_en,		\
-				   S_IRUGO | S_IWUSR,		\
-				   iio_scan_el_ts_show,		\
-				   iio_scan_el_ts_store),	\
-	};							\
-	static IIO_CONST_ATTR(timestamp_index, #number)
-
-/**
- * IIO_CONST_ATTR_SCAN_EL_TYPE - attr to specify the data format of a scan el
- * @name: the scan el name (may be more general and cover a set of scan elements
- * @_sign: either s or u for signed or unsigned
- * @_bits: number of actual bits occuplied by the value
- * @_storagebits: number of bits _bits is padded to when read out of buffer
- **/
-#define IIO_CONST_ATTR_SCAN_EL_TYPE(_name, _sign, _bits, _storagebits) \
-	IIO_CONST_ATTR(_name##_type, #_sign#_bits"/"#_storagebits);
-
-/**
- * IIO_CONST_ATTR_SCAN_EL_TYPE_WITH_SHIFT - attr to specify the data format of a scan el
- * @name: the scan el name (may be more general and cover a set of scan elements
- * @_sign: either s or u for signed or unsigned
- * @_bits: number of actual bits occuplied by the value
- * @_storagebits: number of bits _bits is padded to when read out of buffer
- * @_shiftbits: number of bits _shiftbits the result must be shifted
- **/
-#define IIO_CONST_ATTR_SCAN_EL_TYPE_WITH_SHIFT(_name, _sign, _bits, \
-					       _storagebits, _shiftbits) \
-	IIO_CONST_ATTR(_name##_type, #_sign#_bits"/"#_storagebits \
-		       ">>"#_shiftbits);
-
-#define IIO_SCAN_EL_TYPE_SIGNED         's'
-#define IIO_SCAN_EL_TYPE_UNSIGNED       'u'
-
 /*
  * These are mainly provided to allow for a change of implementation if a device
  * has a large number of scan elements
@@ -375,41 +199,6 @@
 };
 
 /**
- * iio_scan_mask_clear() - clear a particular element from the scan mask
- * @ring: the ring buffer whose scan mask we are interested in
- * @bit: the bit to clear
- **/
-static inline int iio_scan_mask_clear(struct iio_ring_buffer *ring, int bit)
-{
-	if (bit > IIO_MAX_SCAN_LENGTH)
-		return -EINVAL;
-	ring->scan_mask &= ~(1 << bit);
-	ring->scan_count--;
-	return 0;
-};
-
-/**
- * iio_scan_mask_count_to_right() - how many scan elements occur before here
- * @ring: the ring buffer whose scan mask we interested in
- * @bit: which number scan element is this
- **/
-static inline int iio_scan_mask_count_to_right(struct iio_ring_buffer *ring,
-						int bit)
-{
-	int count = 0;
-	int mask = (1 << bit);
-	if (bit > IIO_MAX_SCAN_LENGTH)
-		return -EINVAL;
-	while (mask) {
-		mask >>= 1;
-		if (mask & ring->scan_mask)
-			count++;
-	}
-
-	return count;
-}
-
-/**
  * iio_put_ring_buffer() - notify done with buffer
  * @ring: the buffer we are done with.
  **/
@@ -418,17 +207,19 @@
 	put_device(&ring->dev);
 };
 
-#define to_iio_ring_buffer(d)			\
+#define to_iio_ring_buffer(d)				\
 	container_of(d, struct iio_ring_buffer, dev)
-#define access_dev_to_iio_ring_buffer(d)			\
-	container_of(d, struct iio_ring_buffer, access_dev)
 
 /**
- * iio_ring_buffer_register() - register the buffer with IIO core
+ * iio_ring_buffer_register_ex() - register the buffer with IIO core
  * @ring: the buffer to be registered
  * @id: the id of the buffer (typically 0)
  **/
-int iio_ring_buffer_register(struct iio_ring_buffer *ring, int id);
+int iio_ring_buffer_register_ex(struct iio_ring_buffer *ring, int id,
+				const struct iio_chan_spec *channels,
+				int num_channels);
+
+void iio_ring_access_release(struct device *dev);
 
 /**
  * iio_ring_buffer_unregister() - unregister the buffer from IIO core
@@ -476,11 +267,19 @@
 #define IIO_RING_ENABLE_ATTR DEVICE_ATTR(enable, S_IRUGO | S_IWUSR, \
 					 iio_show_ring_enable,		\
 					 iio_store_ring_enable)
+
+int iio_sw_ring_preenable(struct iio_dev *indio_dev);
+
 #else /* CONFIG_IIO_RING_BUFFER */
-static inline int iio_ring_buffer_register(struct iio_ring_buffer *ring, int id)
+
+static inline int iio_ring_buffer_register_ex(struct iio_ring_buffer *ring,
+					      int id,
+					      struct iio_chan_spec *channels,
+					      int num_channels)
 {
 	return 0;
-};
+}
+
 static inline void iio_ring_buffer_unregister(struct iio_ring_buffer *ring)
 {};
 
diff -druN linux-2.6.39-libre/drivers/staging/iio/ring_sw.c linux-3.0-rc7-libre/drivers/staging/iio/ring_sw.c
--- linux-2.6.39-libre/drivers/staging/iio/ring_sw.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/iio/ring_sw.c	2011-07-11 19:51:52.000000000 -0400
@@ -12,10 +12,41 @@
 #include <linux/module.h>
 #include <linux/device.h>
 #include <linux/workqueue.h>
+#include <linux/sched.h>
 #include <linux/poll.h>
 #include "ring_sw.h"
 #include "trigger.h"
 
+/**
+ * struct iio_sw_ring_buffer - software ring buffer
+ * @buf:		generic ring buffer elements
+ * @data:		the ring buffer memory
+ * @read_p:		read pointer (oldest available)
+ * @write_p:		write pointer
+ * @last_written_p:	read pointer (newest available)
+ * @half_p:		half buffer length behind write_p (event generation)
+ * @use_count:		reference count to prevent resizing when in use
+ * @update_needed:	flag to indicated change in size requested
+ * @use_lock:		lock to prevent change in size when in use
+ *
+ * Note that the first element of all ring buffers must be a
+ * struct iio_ring_buffer.
+**/
+struct iio_sw_ring_buffer {
+	struct iio_ring_buffer  buf;
+	unsigned char		*data;
+	unsigned char		*read_p;
+	unsigned char		*write_p;
+	unsigned char		*last_written_p;
+	/* used to act as a point at which to signal an event */
+	unsigned char		*half_p;
+	int			use_count;
+	int			update_needed;
+	spinlock_t		use_lock;
+};
+
+#define iio_to_sw_ring(r) container_of(r, struct iio_sw_ring_buffer, buf)
+
 static inline int __iio_allocate_sw_ring_buffer(struct iio_sw_ring_buffer *ring,
 						int bytes_per_datum, int length)
 {
@@ -40,23 +71,21 @@
 	kfree(ring->data);
 }
 
-void iio_mark_sw_rb_in_use(struct iio_ring_buffer *r)
+static void iio_mark_sw_rb_in_use(struct iio_ring_buffer *r)
 {
 	struct iio_sw_ring_buffer *ring = iio_to_sw_ring(r);
 	spin_lock(&ring->use_lock);
 	ring->use_count++;
 	spin_unlock(&ring->use_lock);
 }
-EXPORT_SYMBOL(iio_mark_sw_rb_in_use);
 
-void iio_unmark_sw_rb_in_use(struct iio_ring_buffer *r)
+static void iio_unmark_sw_rb_in_use(struct iio_ring_buffer *r)
 {
 	struct iio_sw_ring_buffer *ring = iio_to_sw_ring(r);
 	spin_lock(&ring->use_lock);
 	ring->use_count--;
 	spin_unlock(&ring->use_lock);
 }
-EXPORT_SYMBOL(iio_unmark_sw_rb_in_use);
 
 
 /* Ring buffer related functionality */
@@ -68,7 +97,6 @@
 				unsigned char *data, s64 timestamp)
 {
 	int ret = 0;
-	int code;
 	unsigned char *temp_ptr, *change_test_ptr;
 
 	/* initial store */
@@ -123,14 +151,6 @@
 		 */
 		if (change_test_ptr == ring->read_p)
 			ring->read_p = temp_ptr;
-
-		spin_lock(&ring->buf.shared_ev_pointer.lock);
-
-		ret = iio_push_or_escallate_ring_event(&ring->buf,
-			       IIO_EVENT_CODE_RING_100_FULL, timestamp);
-		spin_unlock(&ring->buf.shared_ev_pointer.lock);
-		if (ret)
-			goto error_ret;
 	}
 	/* investigate if our event barrier has been passed */
 	/* There are definite 'issues' with this and chances of
@@ -140,41 +160,35 @@
 	if (ring->half_p == ring->data + ring->buf.length*ring->buf.bytes_per_datum)
 		ring->half_p = ring->data;
 	if (ring->half_p == ring->read_p) {
-		spin_lock(&ring->buf.shared_ev_pointer.lock);
-		code = IIO_EVENT_CODE_RING_50_FULL;
-		ret = __iio_push_event(&ring->buf.ev_int,
-				       code,
-				       timestamp,
-				       &ring->buf.shared_ev_pointer);
-		spin_unlock(&ring->buf.shared_ev_pointer.lock);
+		ring->buf.stufftoread = true;
+		wake_up_interruptible(&ring->buf.pollq);
 	}
-error_ret:
 	return ret;
 }
 
-int iio_rip_sw_rb(struct iio_ring_buffer *r,
-		  size_t count, char __user *buf, int *dead_offset)
+static int iio_read_first_n_sw_rb(struct iio_ring_buffer *r,
+				  size_t n, char __user *buf)
 {
 	struct iio_sw_ring_buffer *ring = iio_to_sw_ring(r);
 
 	u8 *initial_read_p, *initial_write_p, *current_read_p, *end_read_p;
 	u8 *data;
-	int ret, max_copied;
-	int bytes_to_rip;
+	int ret, max_copied, bytes_to_rip, dead_offset;
 
 	/* A userspace program has probably made an error if it tries to
 	 *  read something that is not a whole number of bpds.
 	 * Return an error.
 	 */
-	if (count % ring->buf.bytes_per_datum) {
+	if (n % ring->buf.bytes_per_datum) {
 		ret = -EINVAL;
 		printk(KERN_INFO "Ring buffer read request not whole number of"
 		       "samples: Request bytes %zd, Current bytes per datum %d\n",
-		       count, ring->buf.bytes_per_datum);
+		       n, ring->buf.bytes_per_datum);
 		goto error_ret;
 	}
 	/* Limit size to whole of ring buffer */
-	bytes_to_rip = min((size_t)(ring->buf.bytes_per_datum*ring->buf.length), count);
+	bytes_to_rip = min((size_t)(ring->buf.bytes_per_datum*ring->buf.length),
+			   n);
 
 	data = kmalloc(bytes_to_rip, GFP_KERNEL);
 	if (data == NULL) {
@@ -240,9 +254,9 @@
 	current_read_p = ring->read_p;
 
 	if (initial_read_p <= current_read_p)
-		*dead_offset = current_read_p - initial_read_p;
+		dead_offset = current_read_p - initial_read_p;
 	else
-		*dead_offset = ring->buf.length*ring->buf.bytes_per_datum
+		dead_offset = ring->buf.length*ring->buf.bytes_per_datum
 			- (initial_read_p - current_read_p);
 
 	/* possible issue if the initial write has been lapped or indeed
@@ -250,7 +264,7 @@
 	/* No valid data read.
 	 * In this case the read pointer is already correct having been
 	 * pushed further than we would look. */
-	if (max_copied - *dead_offset < 0) {
+	if (max_copied - dead_offset < 0) {
 		ret = 0;
 		goto error_free_data_cpy;
 	}
@@ -266,26 +280,30 @@
 	while (ring->read_p != end_read_p)
 		ring->read_p = end_read_p;
 
-	ret = max_copied - *dead_offset;
+	ret = max_copied - dead_offset;
 
-	if (copy_to_user(buf, data + *dead_offset, ret))  {
+	if (copy_to_user(buf, data + dead_offset, ret))  {
 		ret =  -EFAULT;
 		goto error_free_data_cpy;
 	}
+
+	if (bytes_to_rip >= ring->buf.length*ring->buf.bytes_per_datum/2)
+		ring->buf.stufftoread = 0;
+
 error_free_data_cpy:
 	kfree(data);
 error_ret:
 
 	return ret;
 }
-EXPORT_SYMBOL(iio_rip_sw_rb);
 
-int iio_store_to_sw_rb(struct iio_ring_buffer *r, u8 *data, s64 timestamp)
+static int iio_store_to_sw_rb(struct iio_ring_buffer *r,
+			      u8 *data,
+			      s64 timestamp)
 {
 	struct iio_sw_ring_buffer *ring = iio_to_sw_ring(r);
 	return iio_store_to_sw_ring(ring, data, timestamp);
 }
-EXPORT_SYMBOL(iio_store_to_sw_rb);
 
 static int iio_read_last_from_sw_ring(struct iio_sw_ring_buffer *ring,
 				      unsigned char *data)
@@ -309,18 +327,18 @@
 	return 0;
 }
 
-int iio_read_last_from_sw_rb(struct iio_ring_buffer *r,
+static int iio_read_last_from_sw_rb(struct iio_ring_buffer *r,
 			     unsigned char *data)
 {
 	return iio_read_last_from_sw_ring(iio_to_sw_ring(r), data);
 }
-EXPORT_SYMBOL(iio_read_last_from_sw_rb);
 
-int iio_request_update_sw_rb(struct iio_ring_buffer *r)
+static int iio_request_update_sw_rb(struct iio_ring_buffer *r)
 {
 	int ret = 0;
 	struct iio_sw_ring_buffer *ring = iio_to_sw_ring(r);
 
+	r->stufftoread = false;
 	spin_lock(&ring->use_lock);
 	if (!ring->update_needed)
 		goto error_ret;
@@ -335,54 +353,49 @@
 	spin_unlock(&ring->use_lock);
 	return ret;
 }
-EXPORT_SYMBOL(iio_request_update_sw_rb);
 
-int iio_get_bytes_per_datum_sw_rb(struct iio_ring_buffer *r)
+static int iio_get_bytes_per_datum_sw_rb(struct iio_ring_buffer *r)
 {
 	struct iio_sw_ring_buffer *ring = iio_to_sw_ring(r);
 	return ring->buf.bytes_per_datum;
 }
-EXPORT_SYMBOL(iio_get_bytes_per_datum_sw_rb);
 
-int iio_set_bytes_per_datum_sw_rb(struct iio_ring_buffer *r, size_t bpd)
+static int iio_set_bytes_per_datum_sw_rb(struct iio_ring_buffer *r, size_t bpd)
 {
 	if (r->bytes_per_datum != bpd) {
 		r->bytes_per_datum = bpd;
-		if (r->access.mark_param_change)
-			r->access.mark_param_change(r);
+		if (r->access->mark_param_change)
+			r->access->mark_param_change(r);
 	}
 	return 0;
 }
-EXPORT_SYMBOL(iio_set_bytes_per_datum_sw_rb);
 
-int iio_get_length_sw_rb(struct iio_ring_buffer *r)
+static int iio_get_length_sw_rb(struct iio_ring_buffer *r)
 {
 	return r->length;
 }
-EXPORT_SYMBOL(iio_get_length_sw_rb);
 
-int iio_set_length_sw_rb(struct iio_ring_buffer *r, int length)
+static int iio_set_length_sw_rb(struct iio_ring_buffer *r, int length)
 {
 	if (r->length != length) {
 		r->length = length;
-		if (r->access.mark_param_change)
-			r->access.mark_param_change(r);
+		if (r->access->mark_param_change)
+			r->access->mark_param_change(r);
 	}
 	return 0;
 }
-EXPORT_SYMBOL(iio_set_length_sw_rb);
 
-int iio_mark_update_needed_sw_rb(struct iio_ring_buffer *r)
+static int iio_mark_update_needed_sw_rb(struct iio_ring_buffer *r)
 {
 	struct iio_sw_ring_buffer *ring = iio_to_sw_ring(r);
 	ring->update_needed = true;
 	return 0;
 }
-EXPORT_SYMBOL(iio_mark_update_needed_sw_rb);
 
 static void iio_sw_rb_release(struct device *dev)
 {
 	struct iio_ring_buffer *r = to_iio_ring_buffer(dev);
+	iio_ring_access_release(&r->dev);
 	kfree(iio_to_sw_ring(r));
 }
 
@@ -420,13 +433,12 @@
 	ring = kzalloc(sizeof *ring, GFP_KERNEL);
 	if (!ring)
 		return NULL;
+	ring->update_needed = true;
 	buf = &ring->buf;
 	iio_ring_buffer_init(buf, indio_dev);
 	__iio_init_sw_ring_buffer(ring);
 	buf->dev.type = &iio_sw_ring_type;
-	device_initialize(&buf->dev);
 	buf->dev.parent = &indio_dev->dev;
-	buf->dev.bus = &iio_bus_type;
 	dev_set_drvdata(&buf->dev, (void *)buf);
 
 	return buf;
@@ -440,73 +452,20 @@
 }
 EXPORT_SYMBOL(iio_sw_rb_free);
 
-int iio_sw_ring_preenable(struct iio_dev *indio_dev)
-{
-	struct iio_ring_buffer *ring = indio_dev->ring;
-	size_t size;
-	dev_dbg(&indio_dev->dev, "%s\n", __func__);
-	/* Check if there are any scan elements enabled, if not fail*/
-	if (!(ring->scan_count || ring->scan_timestamp))
-		return -EINVAL;
-	if (ring->scan_timestamp)
-		if (ring->scan_count)
-			/* Timestamp (aligned to s64) and data */
-			size = (((ring->scan_count * ring->bpe)
-					+ sizeof(s64) - 1)
-				& ~(sizeof(s64) - 1))
-				+ sizeof(s64);
-		else /* Timestamp only  */
-			size = sizeof(s64);
-	else /* Data only */
-		size = ring->scan_count * ring->bpe;
-	ring->access.set_bytes_per_datum(ring, size);
-
-	return 0;
-}
-EXPORT_SYMBOL(iio_sw_ring_preenable);
-
-void iio_sw_trigger_bh_to_ring(struct work_struct *work_s)
-{
-	struct iio_sw_ring_helper_state *st
-		= container_of(work_s, struct iio_sw_ring_helper_state,
-			work_trigger_to_ring);
-	struct iio_ring_buffer *ring = st->indio_dev->ring;
-	int len = 0;
-	size_t datasize = ring->access.get_bytes_per_datum(ring);
-	char *data = kmalloc(datasize, GFP_KERNEL);
-
-	if (data == NULL) {
-		dev_err(st->indio_dev->dev.parent,
-			"memory alloc failed in ring bh");
-		return;
-	}
-
-	if (ring->scan_count)
-		len = st->get_ring_element(st, data);
-
-	  /* Guaranteed to be aligned with 8 byte boundary */
-	if (ring->scan_timestamp)
-		*(s64 *)(((phys_addr_t)data + len
-				+ sizeof(s64) - 1) & ~(sizeof(s64) - 1))
-			= st->last_timestamp;
-	ring->access.store_to(ring,
-			(u8 *)data,
-			st->last_timestamp);
-
-	iio_trigger_notify_done(st->indio_dev->trig);
-	kfree(data);
-
-	return;
-}
-EXPORT_SYMBOL(iio_sw_trigger_bh_to_ring);
-
-void iio_sw_poll_func_th(struct iio_dev *indio_dev, s64 time)
-{	struct iio_sw_ring_helper_state *h
-		= iio_dev_get_devdata(indio_dev);
-	h->last_timestamp = time;
-	schedule_work(&h->work_trigger_to_ring);
-}
-EXPORT_SYMBOL(iio_sw_poll_func_th);
+const struct iio_ring_access_funcs ring_sw_access_funcs = {
+	.mark_in_use = &iio_mark_sw_rb_in_use,
+	.unmark_in_use = &iio_unmark_sw_rb_in_use,
+	.store_to = &iio_store_to_sw_rb,
+	.read_last = &iio_read_last_from_sw_rb,
+	.read_first_n = &iio_read_first_n_sw_rb,
+	.mark_param_change = &iio_mark_update_needed_sw_rb,
+	.request_update = &iio_request_update_sw_rb,
+	.get_bytes_per_datum = &iio_get_bytes_per_datum_sw_rb,
+	.set_bytes_per_datum = &iio_set_bytes_per_datum_sw_rb,
+	.get_length = &iio_get_length_sw_rb,
+	.set_length = &iio_set_length_sw_rb,
+};
+EXPORT_SYMBOL(ring_sw_access_funcs);
 
 MODULE_DESCRIPTION("Industrialio I/O software ring buffer");
 MODULE_LICENSE("GPL");
diff -druN linux-2.6.39-libre/drivers/staging/iio/ring_sw.h linux-3.0-rc7-libre/drivers/staging/iio/ring_sw.h
--- linux-2.6.39-libre/drivers/staging/iio/ring_sw.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/iio/ring_sw.h	2011-07-11 19:51:52.000000000 -0400
@@ -23,205 +23,13 @@
 
 #ifndef _IIO_RING_SW_H_
 #define _IIO_RING_SW_H_
-/* NEEDS COMMENTS */
-/* The intention is that this should be a separate module from the iio core.
- * This is a bit like supporting algorithms dependent on what the device
- * driver requests - some may support multiple options */
-
-
-#include "iio.h"
 #include "ring_generic.h"
 
-#if defined CONFIG_IIO_SW_RING || defined CONFIG_IIO_SW_RING_MODULE
-
-/**
- * iio_create_sw_rb() - software ring buffer allocation
- * @r:		pointer to ring buffer pointer
- **/
-int iio_create_sw_rb(struct iio_ring_buffer **r);
-
-/**
- * iio_init_sw_rb() - initialize the software ring buffer
- * @r:		pointer to a software ring buffer created by an
- *		iio_create_sw_rb call
- * @indio_dev:		industrial I/O device structure
- **/
-int iio_init_sw_rb(struct iio_ring_buffer *r, struct iio_dev *indio_dev);
-
-/**
- * iio_exit_sw_rb() - reverse what was done in iio_init_sw_rb
- * @r:		pointer to a software ring buffer created by an
- *		iio_create_sw_rb call
- **/
-void iio_exit_sw_rb(struct iio_ring_buffer *r);
-
-/**
- * iio_free_sw_rb() - free memory occupied by the core ring buffer struct
- * @r:		pointer to a software ring buffer created by an
- *		iio_create_sw_rb call
- **/
-void iio_free_sw_rb(struct iio_ring_buffer *r);
-
-/**
- * iio_mark_sw_rb_in_use() - reference counting to prevent incorrect chances
- * @r:		pointer to a software ring buffer created by an
- *		iio_create_sw_rb call
- **/
-void iio_mark_sw_rb_in_use(struct iio_ring_buffer *r);
-
-/**
- *  iio_unmark_sw_rb_in_use() - notify the ring buffer that we don't care anymore
- * @r:		pointer to a software ring buffer created by an
- *		iio_create_sw_rb call
- **/
-void iio_unmark_sw_rb_in_use(struct iio_ring_buffer *r);
-
-/**
- * iio_read_last_from_sw_rb() - attempt to read the last stored datum from the rb
- * @r:		pointer to a software ring buffer created by an
- *		iio_create_sw_rb call
- * @data:	where to store the last datum
- **/
-int iio_read_last_from_sw_rb(struct iio_ring_buffer *r, u8 *data);
-
-/**
- * iio_store_to_sw_rb() - store a new datum to the ring buffer
- * @r:		pointer to ring buffer instance
- * @data:	the datum to be stored including timestamp if relevant
- * @timestamp:	timestamp which will be attached to buffer events if relevant
- **/
-int iio_store_to_sw_rb(struct iio_ring_buffer *r, u8 *data, s64 timestamp);
-
-/**
- * iio_rip_sw_rb() - attempt to read data from the ring buffer
- * @r:			ring buffer instance
- * @count:		number of datum's to try and read
- * @buf:		userspace buffer into which data is copied
- * @dead_offset:	how much of the stored data was possibly invalidated by
- *			the end of the copy.
- **/
-int iio_rip_sw_rb(struct iio_ring_buffer *r,
-		  size_t count,
-		  char __user *buf,
-		  int *dead_offset);
-
-/**
- * iio_request_update_sw_rb() - update params if update needed
- * @r:		pointer to a software ring buffer created by an
- *		iio_create_sw_rb call
- **/
-int iio_request_update_sw_rb(struct iio_ring_buffer *r);
-
-/**
- * iio_mark_update_needed_sw_rb() - tell the ring buffer it needs a param update
- * @r:		pointer to a software ring buffer created by an
- *		iio_create_sw_rb call
- **/
-int iio_mark_update_needed_sw_rb(struct iio_ring_buffer *r);
-
-
-/**
- * iio_get_bytes_per_datum_sw_rb() - get the datum size in bytes
- * @r:		pointer to a software ring buffer created by an
- *		iio_create_sw_rb call
- **/
-int iio_get_bytes_per_datum_sw_rb(struct iio_ring_buffer *r);
-
 /**
- * iio_set_bytes_per_datum_sw_rb() - set the datum size in bytes
- * @r:		pointer to a software ring buffer created by an
- *		iio_create_sw_rb call
- * @bpd:	bytes per datum value
- **/
-int iio_set_bytes_per_datum_sw_rb(struct iio_ring_buffer *r, size_t bpd);
-
-/**
- * iio_get_length_sw_rb() - get how many datums the rb may contain
- * @r:		pointer to a software ring buffer created by an
- *		iio_create_sw_rb call
- **/
-int iio_get_length_sw_rb(struct iio_ring_buffer *r);
-
-/**
- * iio_set_length_sw_rb() - set how many datums the rb may contain
- * @r:		pointer to a software ring buffer created by an
- *		iio_create_sw_rb call
- * @length:	max number of data items for the ring buffer
- **/
-int iio_set_length_sw_rb(struct iio_ring_buffer *r, int length);
-
-/**
- * iio_ring_sw_register_funcs() - helper function to set up rb access
- * @ra:		pointer to @iio_ring_access_funcs
+ * ring_sw_access_funcs - access functions for a software ring buffer
  **/
-static inline void iio_ring_sw_register_funcs(struct iio_ring_access_funcs *ra)
-{
-	ra->mark_in_use = &iio_mark_sw_rb_in_use;
-	ra->unmark_in_use = &iio_unmark_sw_rb_in_use;
-
-	ra->store_to = &iio_store_to_sw_rb;
-	ra->read_last = &iio_read_last_from_sw_rb;
-	ra->rip_lots = &iio_rip_sw_rb;
-
-	ra->mark_param_change = &iio_mark_update_needed_sw_rb;
-	ra->request_update = &iio_request_update_sw_rb;
-
-	ra->get_bytes_per_datum = &iio_get_bytes_per_datum_sw_rb;
-	ra->set_bytes_per_datum = &iio_set_bytes_per_datum_sw_rb;
-
-	ra->get_length = &iio_get_length_sw_rb;
-	ra->set_length = &iio_set_length_sw_rb;
-};
-
-/**
- * struct iio_sw_ring_buffer - software ring buffer
- * @buf:		generic ring buffer elements
- * @data:		the ring buffer memory
- * @read_p:		read pointer (oldest available)
- * @write_p:		write pointer
- * @last_written_p:	read pointer (newest available)
- * @half_p:		half buffer length behind write_p (event generation)
- * @use_count:		reference count to prevent resizing when in use
- * @update_needed:	flag to indicated change in size requested
- * @use_lock:		lock to prevent change in size when in use
- *
- * Note that the first element of all ring buffers must be a
- * struct iio_ring_buffer.
-**/
-
-struct iio_sw_ring_buffer {
-	struct iio_ring_buffer  buf;
-	unsigned char		*data;
-	unsigned char		*read_p;
-	unsigned char		*write_p;
-	unsigned char		*last_written_p;
-	/* used to act as a point at which to signal an event */
-	unsigned char		*half_p;
-	int			use_count;
-	int			update_needed;
-	spinlock_t		use_lock;
-};
-
-#define iio_to_sw_ring(r) container_of(r, struct iio_sw_ring_buffer, buf)
+extern const struct iio_ring_access_funcs ring_sw_access_funcs;
 
 struct iio_ring_buffer *iio_sw_rb_allocate(struct iio_dev *indio_dev);
 void iio_sw_rb_free(struct iio_ring_buffer *ring);
-
-int iio_sw_ring_preenable(struct iio_dev *indio_dev);
-
-struct iio_sw_ring_helper_state {
-	struct work_struct		work_trigger_to_ring;
-	struct iio_dev			*indio_dev;
-	int (*get_ring_element)(struct iio_sw_ring_helper_state *st, u8 *buf);
-	s64				last_timestamp;
-};
-
-void iio_sw_poll_func_th(struct iio_dev *indio_dev, s64 time);
-void iio_sw_trigger_bh_to_ring(struct work_struct *work_s);
-
-#else /* CONFIG_IIO_RING_BUFFER*/
-struct iio_sw_ring_helper_state {
-	struct iio_dev			*indio_dev;
-};
-#endif /* !CONFIG_IIO_RING_BUFFER */
 #endif /* _IIO_RING_SW_H_ */
diff -druN linux-2.6.39-libre/drivers/staging/iio/sysfs.h linux-3.0-rc7-libre/drivers/staging/iio/sysfs.h
--- linux-2.6.39-libre/drivers/staging/iio/sysfs.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/iio/sysfs.h	2011-07-11 19:51:52.000000000 -0400
@@ -15,30 +15,18 @@
 #include "iio.h"
 
 /**
- * struct iio_event_attr - event control attribute
- * @dev_attr:	underlying device attribute
- * @mask:	mask for the event when detecting
- * @listel:	list header to allow addition to list of event handlers
-*/
-struct iio_event_attr {
-	struct device_attribute dev_attr;
-	int mask;
-	struct iio_event_handler_list *listel;
-};
-
-#define to_iio_event_attr(_dev_attr) \
-	container_of(_dev_attr, struct iio_event_attr, dev_attr)
-
-/**
  * struct iio_dev_attr - iio specific device attribute
  * @dev_attr:	underlying device attribute
  * @address:	associated register address
  * @val2:	secondary attribute value
+ * @l:		list head for maintaining list of dynamically created attrs.
  */
 struct iio_dev_attr {
 	struct device_attribute dev_attr;
 	int address;
 	int val2;
+	struct list_head l;
+	struct iio_chan_spec const *c;
 };
 
 #define to_iio_dev_attr(_dev_attr)				\
@@ -101,13 +89,6 @@
 	IIO_DEVICE_ATTR(revision, S_IRUGO, _show, NULL, 0)
 
 /**
- * IIO_DEV_ATTR_NAME - chip type dependent identifier
- * @_show: output method for the attribute
- **/
-#define IIO_DEV_ATTR_NAME(_show)				\
-	IIO_DEVICE_ATTR(name, S_IRUGO, _show, NULL, 0)
-
-/**
  * IIO_DEV_ATTR_RESET: resets the device
  **/
 #define IIO_DEV_ATTR_RESET(_store)			\
@@ -180,104 +161,27 @@
 #define IIO_CONST_ATTR_TEMP_SCALE(_string)		\
 	IIO_CONST_ATTR(temp_scale, _string)
 
-/**
- * IIO_EVENT_SH - generic shared event handler
- * @_name: event name
- * @_handler: handler function to be called
- *
- * This is used in cases where more than one event may result from a single
- * handler.  Often the case that some alarm register must be read and multiple
- * alarms may have been triggered.
- **/
-#define IIO_EVENT_SH(_name, _handler)					\
-	static struct iio_event_handler_list				\
-	iio_event_##_name = {						\
-		.handler = _handler,					\
-		.refcount = 0,						\
-		.exist_lock = __MUTEX_INITIALIZER(iio_event_##_name	\
-						  .exist_lock),		\
-		.list = {						\
-			.next = &iio_event_##_name.list,		\
-			.prev = &iio_event_##_name.list,		\
-		},							\
-	};
-
-/**
- * IIO_EVENT_ATTR_SH - generic shared event attribute
- * @_name: event name
- * @_ev_list: event handler list
- * @_show: output method for the attribute
- * @_store: input method for the attribute
- * @_mask: mask used when detecting the event
- *
- * An attribute with an associated IIO_EVENT_SH
- **/
-#define IIO_EVENT_ATTR_SH(_name, _ev_list, _show, _store, _mask)	\
-	static struct iio_event_attr					\
-	iio_event_attr_##_name						\
-	= { .dev_attr = __ATTR(_name, S_IRUGO | S_IWUSR,		\
-			       _show, _store),				\
-	    .mask = _mask,						\
-	    .listel = &_ev_list };
-
-#define IIO_EVENT_ATTR_NAMED_SH(_vname, _name, _ev_list, _show, _store, _mask) \
-	static struct iio_event_attr					\
-	iio_event_attr_##_vname						\
-	= { .dev_attr = __ATTR(_name, S_IRUGO | S_IWUSR,		\
-			       _show, _store),				\
-	    .mask = _mask,						\
-	    .listel = &_ev_list };
-
-/**
- * IIO_EVENT_ATTR - non-shared event attribute
- * @_name: event name
- * @_show: output method for the attribute
- * @_store: input method for the attribute
- * @_mask: mask used when detecting the event
- * @_handler: handler function to be called
- **/
-#define IIO_EVENT_ATTR(_name, _show, _store, _mask, _handler)		\
-	IIO_EVENT_SH(_name, _handler);					\
-	static struct							\
-	iio_event_attr							\
-	iio_event_attr_##_name						\
-	= { .dev_attr = __ATTR(_name, S_IRUGO | S_IWUSR,		\
-			       _show, _store),				\
-	    .mask = _mask,						\
-	    .listel = &iio_event_##_name };				\
-
-/**
- * IIO_EVENT_ATTR_DATA_RDY - event driven by data ready signal
- * @_show: output method for the attribute
- * @_store: input method for the attribute
- * @_mask: mask used when detecting the event
- * @_handler: handler function to be called
- *
- * Not typically implemented in devices where full triggering support
- * has been implemented.
- **/
-#define IIO_EVENT_ATTR_DATA_RDY(_show, _store, _mask, _handler) \
-	IIO_EVENT_ATTR(data_rdy, _show, _store, _mask, _handler)
-
-#define IIO_EV_CLASS_BUFFER		0
-#define IIO_EV_CLASS_IN			1
-#define IIO_EV_CLASS_ACCEL		2
-#define IIO_EV_CLASS_GYRO		3
-#define IIO_EV_CLASS_MAGN		4
-#define IIO_EV_CLASS_LIGHT		5
-#define IIO_EV_CLASS_PROXIMITY		6
+/* must match our channel defs */
+#define IIO_EV_CLASS_IN			IIO_IN
+#define IIO_EV_CLASS_IN_DIFF		IIO_IN_DIFF
+#define IIO_EV_CLASS_ACCEL		IIO_ACCEL
+#define IIO_EV_CLASS_GYRO		IIO_GYRO
+#define IIO_EV_CLASS_MAGN		IIO_MAGN
+#define IIO_EV_CLASS_LIGHT		IIO_LIGHT
+#define IIO_EV_CLASS_PROXIMITY		IIO_PROXIMITY
+#define IIO_EV_CLASS_TEMP		IIO_TEMP
 
-#define IIO_EV_MOD_X			0
-#define IIO_EV_MOD_Y			1
-#define IIO_EV_MOD_Z			2
-#define IIO_EV_MOD_X_AND_Y		3
-#define IIO_EV_MOD_X_ANX_Z		4
-#define IIO_EV_MOD_Y_AND_Z		5
-#define IIO_EV_MOD_X_AND_Y_AND_Z	6
-#define IIO_EV_MOD_X_OR_Y		7
-#define IIO_EV_MOD_X_OR_Z		8
-#define IIO_EV_MOD_Y_OR_Z		9
-#define IIO_EV_MOD_X_OR_Y_OR_Z		10
+#define IIO_EV_MOD_X			IIO_MOD_X
+#define IIO_EV_MOD_Y			IIO_MOD_Y
+#define IIO_EV_MOD_Z			IIO_MOD_Z
+#define IIO_EV_MOD_X_AND_Y		IIO_MOD_X_AND_Y
+#define IIO_EV_MOD_X_ANX_Z		IIO_MOD_X_AND_Z
+#define IIO_EV_MOD_Y_AND_Z		IIO_MOD_Y_AND_Z
+#define IIO_EV_MOD_X_AND_Y_AND_Z	IIO_MOD_X_AND_Y_AND_Z
+#define IIO_EV_MOD_X_OR_Y		IIO_MOD_X_OR_Y
+#define IIO_EV_MOD_X_OR_Z		IIO_MOD_X_OR_Z
+#define IIO_EV_MOD_Y_OR_Z		IIO_MOD_Y_OR_Z
+#define IIO_EV_MOD_X_OR_Y_OR_Z		IIO_MOD_X_OR_Y_OR_Z
 
 #define IIO_EV_TYPE_THRESH		0
 #define IIO_EV_TYPE_MAG			1
@@ -287,6 +191,10 @@
 #define IIO_EV_DIR_RISING		1
 #define IIO_EV_DIR_FALLING		2
 
+#define IIO_EV_TYPE_MAX 8
+#define IIO_EV_BIT(type, direction)			\
+	(1 << (type*IIO_EV_TYPE_MAX + direction))
+
 #define IIO_EVENT_CODE(channelclass, orient_bit, number,		\
 		       modifier, type, direction)			\
 	(channelclass | (orient_bit << 8) | ((number) << 9) |		\
@@ -303,38 +211,12 @@
 #define IIO_BUFFER_EVENT_CODE(code)		\
 	(IIO_EV_CLASS_BUFFER | (code << 8))
 
-/**
- * IIO_EVENT_ATTR_RING_50_FULL - ring buffer event to indicate 50% full
- * @_show: output method for the attribute
- * @_store: input method for the attribute
- * @_mask: mask used when detecting the event
- * @_handler: handler function to be called
- **/
-#define IIO_EVENT_ATTR_RING_50_FULL(_show, _store, _mask, _handler)	\
-	IIO_EVENT_ATTR(ring_50_full, _show, _store, _mask, _handler)
-
-/**
- * IIO_EVENT_ATTR_RING_50_FULL_SH - shared ring event to indicate 50% full
- * @_evlist: event handler list
- * @_show: output method for the attribute
- * @_store: input method for the attribute
- * @_mask: mask used when detecting the event
- **/
-#define IIO_EVENT_ATTR_RING_50_FULL_SH(_evlist, _show, _store, _mask)	\
-	IIO_EVENT_ATTR_SH(ring_50_full, _evlist, _show, _store, _mask)
+#define IIO_EVENT_CODE_EXTRACT_DIR(mask) ((mask >> 24) & 0xf)
 
-/**
- * IIO_EVENT_ATTR_RING_75_FULL_SH - shared ring event to indicate 75% full
- * @_evlist: event handler list
- * @_show: output method for the attribute
- * @_store: input method for the attribute
- * @_mask: mask used when detecting the event
- **/
-#define IIO_EVENT_ATTR_RING_75_FULL_SH(_evlist, _show, _store, _mask)	\
-	IIO_EVENT_ATTR_SH(ring_75_full, _evlist, _show, _store, _mask)
+/* Event code number extraction depends on which type of event we have.
+ * Perhaps review this function in the future*/
+#define IIO_EVENT_CODE_EXTRACT_NUM(mask) ((mask >> 9) & 0x0f)
 
-#define IIO_EVENT_CODE_RING_50_FULL	IIO_BUFFER_EVENT_CODE(0)
-#define IIO_EVENT_CODE_RING_75_FULL	IIO_BUFFER_EVENT_CODE(1)
-#define IIO_EVENT_CODE_RING_100_FULL	IIO_BUFFER_EVENT_CODE(2)
+#define IIO_EVENT_CODE_EXTRACT_MODIFIER(mask) ((mask >> 13) & 0x7)
 
 #endif /* _INDUSTRIAL_IO_SYSFS_H_ */
diff -druN linux-2.6.39-libre/drivers/staging/iio/trigger/iio-trig-bfin-timer.c linux-3.0-rc7-libre/drivers/staging/iio/trigger/iio-trig-bfin-timer.c
--- linux-2.6.39-libre/drivers/staging/iio/trigger/iio-trig-bfin-timer.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/iio/trigger/iio-trig-bfin-timer.c	2011-07-11 19:51:52.000000000 -0400
@@ -106,11 +106,9 @@
 
 static DEVICE_ATTR(frequency, S_IRUGO | S_IWUSR, iio_bfin_tmr_frequency_show,
 		   iio_bfin_tmr_frequency_store);
-static IIO_TRIGGER_NAME_ATTR;
 
 static struct attribute *iio_bfin_tmr_trigger_attrs[] = {
 	&dev_attr_frequency.attr,
-	&dev_attr_name.attr,
 	NULL,
 };
 
@@ -118,6 +116,11 @@
 	.attrs = iio_bfin_tmr_trigger_attrs,
 };
 
+static const struct attribute_group *iio_bfin_tmr_trigger_attr_groups[] = {
+	&iio_bfin_tmr_trigger_attr_group,
+	NULL
+};
+
 
 static irqreturn_t iio_bfin_tmr_trigger_isr(int irq, void *devid)
 {
@@ -165,24 +168,18 @@
 	st->timer_num = ret;
 	st->t = &iio_bfin_timer_code[st->timer_num];
 
-	st->trig = iio_allocate_trigger();
+	st->trig = iio_allocate_trigger("bfintmr%d", st->timer_num);
 	if (!st->trig) {
 		ret = -ENOMEM;
 		goto out1;
 	}
 
 	st->trig->private_data = st;
-	st->trig->control_attrs = &iio_bfin_tmr_trigger_attr_group;
 	st->trig->owner = THIS_MODULE;
-	st->trig->name = kasprintf(GFP_KERNEL, "bfintmr%d", st->timer_num);
-	if (st->trig->name == NULL) {
-		ret = -ENOMEM;
-		goto out2;
-	}
-
+	st->trig->dev.groups = iio_bfin_tmr_trigger_attr_groups;
 	ret = iio_trigger_register(st->trig);
 	if (ret)
-		goto out3;
+		goto out2;
 
 	ret = request_irq(st->irq, iio_bfin_tmr_trigger_isr,
 			  0, st->trig->name, st);
@@ -201,8 +198,6 @@
 	return 0;
 out4:
 	iio_trigger_unregister(st->trig);
-out3:
-	kfree(st->trig->name);
 out2:
 	iio_put_trigger(st->trig);
 out1:
@@ -218,7 +213,6 @@
 	disable_gptimers(st->t->bit);
 	free_irq(st->irq, st);
 	iio_trigger_unregister(st->trig);
-	kfree(st->trig->name);
 	iio_put_trigger(st->trig);
 	kfree(st);
 
diff -druN linux-2.6.39-libre/drivers/staging/iio/trigger/iio-trig-gpio.c linux-3.0-rc7-libre/drivers/staging/iio/trigger/iio-trig-gpio.c
--- linux-2.6.39-libre/drivers/staging/iio/trigger/iio-trig-gpio.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/iio/trigger/iio-trig-gpio.c	2011-07-11 19:51:52.000000000 -0400
@@ -47,17 +47,6 @@
 	return IRQ_HANDLED;
 }
 
-static IIO_TRIGGER_NAME_ATTR;
-
-static struct attribute *iio_gpio_trigger_attrs[] = {
-	&dev_attr_name.attr,
-	NULL,
-};
-
-static const struct attribute_group iio_gpio_trigger_attr_group = {
-	.attrs = iio_gpio_trigger_attrs,
-};
-
 static int iio_gpio_trigger_probe(struct platform_device *pdev)
 {
 	struct iio_gpio_trigger_info *trig_info;
@@ -79,7 +68,7 @@
 
 		for (irq = irq_res->start; irq <= irq_res->end; irq++) {
 
-			trig = iio_allocate_trigger();
+			trig = iio_allocate_trigger("irqtrig%d", irq);
 			if (!trig) {
 				ret = -ENOMEM;
 				goto error_free_completed_registrations;
@@ -90,21 +79,15 @@
 				ret = -ENOMEM;
 				goto error_put_trigger;
 			}
-			trig->control_attrs = &iio_gpio_trigger_attr_group;
 			trig->private_data = trig_info;
 			trig_info->irq = irq;
 			trig->owner = THIS_MODULE;
-			trig->name = kasprintf(GFP_KERNEL, "irqtrig%d", irq);
-			if (trig->name == NULL) {
-				ret = -ENOMEM;
-				goto error_free_trig_info;
-			}
 			ret = request_irq(irq, iio_gpio_trigger_poll,
 					  irqflags, trig->name, trig);
 			if (ret) {
 				dev_err(&pdev->dev,
 					"request IRQ-%d failed", irq);
-				goto error_free_name;
+				goto error_free_trig_info;
 			}
 
 			ret = iio_trigger_register(trig);
@@ -124,8 +107,6 @@
 /* First clean up the partly allocated trigger */
 error_release_irq:
 	free_irq(irq, trig);
-error_free_name:
-	kfree(trig->name);
 error_free_trig_info:
 	kfree(trig_info);
 error_put_trigger:
@@ -138,7 +119,6 @@
 				 alloc_list) {
 		trig_info = trig->private_data;
 		free_irq(gpio_to_irq(trig_info->irq), trig);
-		kfree(trig->name);
 		kfree(trig_info);
 		iio_trigger_unregister(trig);
 	}
@@ -159,7 +139,6 @@
 		trig_info = trig->private_data;
 		iio_trigger_unregister(trig);
 		free_irq(trig_info->irq, trig);
-		kfree(trig->name);
 		kfree(trig_info);
 		iio_put_trigger(trig);
 	}
diff -druN linux-2.6.39-libre/drivers/staging/iio/trigger/iio-trig-periodic-rtc.c linux-3.0-rc7-libre/drivers/staging/iio/trigger/iio-trig-periodic-rtc.c
--- linux-2.6.39-libre/drivers/staging/iio/trigger/iio-trig-periodic-rtc.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/iio/trigger/iio-trig-periodic-rtc.c	2011-07-11 19:51:52.000000000 -0400
@@ -72,20 +72,24 @@
 	return ret;
 }
 
-static IIO_TRIGGER_NAME_ATTR;
 static DEVICE_ATTR(frequency, S_IRUGO | S_IWUSR,
 	    iio_trig_periodic_read_freq,
 	    iio_trig_periodic_write_freq);
 
 static struct attribute *iio_trig_prtc_attrs[] = {
 	&dev_attr_frequency.attr,
-	&dev_attr_name.attr,
 	NULL,
 };
+
 static const struct attribute_group iio_trig_prtc_attr_group = {
 	.attrs = iio_trig_prtc_attrs,
 };
 
+static const struct attribute_group *iio_trig_prtc_attr_groups[] = {
+	&iio_trig_prtc_attr_group,
+	NULL
+};
+
 static void iio_prtc_trigger_poll(void *private_data)
 {
 	/* Timestamp is not provided currently */
@@ -103,7 +107,7 @@
 	for (i = 0;; i++) {
 		if (pdata[i] == NULL)
 			break;
-		trig = iio_allocate_trigger();
+		trig = iio_allocate_trigger("periodic%s", pdata[i]);
 		if (!trig) {
 			ret = -ENOMEM;
 			goto error_free_completed_registrations;
@@ -118,25 +122,19 @@
 		trig->private_data = trig_info;
 		trig->owner = THIS_MODULE;
 		trig->set_trigger_state = &iio_trig_periodic_rtc_set_state;
-		trig->name = kasprintf(GFP_KERNEL, "periodic%s", pdata[i]);
-		if (trig->name == NULL) {
-			ret = -ENOMEM;
-			goto error_free_trig_info;
-		}
-
 		/* RTC access */
 		trig_info->rtc
 			= rtc_class_open(pdata[i]);
 		if (trig_info->rtc == NULL) {
 			ret = -EINVAL;
-			goto error_free_name;
+			goto error_free_trig_info;
 		}
 		trig_info->task.func = iio_prtc_trigger_poll;
 		trig_info->task.private_data = trig;
 		ret = rtc_irq_register(trig_info->rtc, &trig_info->task);
 		if (ret)
 			goto error_close_rtc;
-		trig->control_attrs = &iio_trig_prtc_attr_group;
+		trig->dev.groups = iio_trig_prtc_attr_groups;
 		ret = iio_trigger_register(trig);
 		if (ret)
 			goto error_unregister_rtc_irq;
@@ -146,8 +144,6 @@
 	rtc_irq_unregister(trig_info->rtc, &trig_info->task);
 error_close_rtc:
 	rtc_class_close(trig_info->rtc);
-error_free_name:
-	kfree(trig->name);
 error_free_trig_info:
 	kfree(trig_info);
 error_put_trigger_and_remove_from_list:
@@ -161,7 +157,6 @@
 		trig_info = trig->private_data;
 		rtc_irq_unregister(trig_info->rtc, &trig_info->task);
 		rtc_class_close(trig_info->rtc);
-		kfree(trig->name);
 		kfree(trig_info);
 		iio_trigger_unregister(trig);
 	}
@@ -180,7 +175,6 @@
 		trig_info = trig->private_data;
 		rtc_irq_unregister(trig_info->rtc, &trig_info->task);
 		rtc_class_close(trig_info->rtc);
-		kfree(trig->name);
 		kfree(trig_info);
 		iio_trigger_unregister(trig);
 	}
diff -druN linux-2.6.39-libre/drivers/staging/iio/trigger/iio-trig-sysfs.c linux-3.0-rc7-libre/drivers/staging/iio/trigger/iio-trig-sysfs.c
--- linux-2.6.39-libre/drivers/staging/iio/trigger/iio-trig-sysfs.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/iio/trigger/iio-trig-sysfs.c	2011-07-11 19:51:52.000000000 -0400
@@ -9,25 +9,92 @@
 #include <linux/module.h>
 #include <linux/platform_device.h>
 #include <linux/slab.h>
+#include <linux/list.h>
 
 #include "../iio.h"
 #include "../trigger.h"
 
+struct iio_sysfs_trig {
+	struct iio_trigger *trig;
+	int id;
+	struct list_head l;
+};
+
+static LIST_HEAD(iio_sysfs_trig_list);
+static DEFINE_MUTEX(iio_syfs_trig_list_mut);
+
+static int iio_sysfs_trigger_probe(int id);
+static ssize_t iio_sysfs_trig_add(struct device *dev,
+				  struct device_attribute *attr,
+				  const char *buf,
+				  size_t len)
+{
+	int ret;
+	unsigned long input;
+
+	ret = strict_strtoul(buf, 10, &input);
+	if (ret)
+		return ret;
+	ret = iio_sysfs_trigger_probe(input);
+	if (ret)
+		return ret;
+	return len;
+}
+static DEVICE_ATTR(add_trigger, S_IWUSR, NULL, &iio_sysfs_trig_add);
+
+static int iio_sysfs_trigger_remove(int id);
+static ssize_t iio_sysfs_trig_remove(struct device *dev,
+				     struct device_attribute *attr,
+				     const char *buf,
+				     size_t len)
+{
+	int ret;
+	unsigned long input;
+
+	ret = strict_strtoul(buf, 10, &input);
+	if (ret)
+		return ret;
+	ret = iio_sysfs_trigger_remove(input);
+	if (ret)
+		return ret;
+	return len;
+}
+
+static DEVICE_ATTR(remove_trigger, S_IWUSR, NULL, &iio_sysfs_trig_remove);
+
+static struct attribute *iio_sysfs_trig_attrs[] = {
+	&dev_attr_add_trigger.attr,
+	&dev_attr_remove_trigger.attr,
+	NULL,
+};
+
+static const struct attribute_group iio_sysfs_trig_group = {
+	.attrs = iio_sysfs_trig_attrs,
+};
+
+static const struct attribute_group *iio_sysfs_trig_groups[] = {
+	&iio_sysfs_trig_group,
+	NULL
+};
+
+static struct device iio_sysfs_trig_dev = {
+	.bus = &iio_bus_type,
+	.groups = iio_sysfs_trig_groups,
+};
+
 static ssize_t iio_sysfs_trigger_poll(struct device *dev,
 		struct device_attribute *attr, const char *buf, size_t count)
 {
 	struct iio_trigger *trig = dev_get_drvdata(dev);
-	iio_trigger_poll(trig, 0);
+	iio_trigger_poll_chained(trig, 0);
 
 	return count;
 }
 
 static DEVICE_ATTR(trigger_now, S_IWUSR, NULL, iio_sysfs_trigger_poll);
-static IIO_TRIGGER_NAME_ATTR;
 
 static struct attribute *iio_sysfs_trigger_attrs[] = {
 	&dev_attr_trigger_now.attr,
-	&dev_attr_name.attr,
 	NULL,
 };
 
@@ -35,70 +102,96 @@
 	.attrs = iio_sysfs_trigger_attrs,
 };
 
-static int __devinit iio_sysfs_trigger_probe(struct platform_device *pdev)
+static const struct attribute_group *iio_sysfs_trigger_attr_groups[] = {
+	&iio_sysfs_trigger_attr_group,
+	NULL
+};
+
+static int iio_sysfs_trigger_probe(int id)
 {
-	struct iio_trigger *trig;
+	struct iio_sysfs_trig *t;
 	int ret;
-
-	trig = iio_allocate_trigger();
-	if (!trig) {
+	bool foundit = false;
+	mutex_lock(&iio_syfs_trig_list_mut);
+	list_for_each_entry(t, &iio_sysfs_trig_list, l)
+		if (id == t->id) {
+			foundit = true;
+			break;
+		}
+	if (foundit) {
+		ret = -EINVAL;
+		goto out1;
+	}
+	t = kmalloc(sizeof(*t), GFP_KERNEL);
+	if (t == NULL) {
 		ret = -ENOMEM;
 		goto out1;
 	}
-
-	trig->control_attrs = &iio_sysfs_trigger_attr_group;
-	trig->owner = THIS_MODULE;
-	trig->name = kasprintf(GFP_KERNEL, "sysfstrig%d", pdev->id);
-	if (trig->name == NULL) {
+	t->id = id;
+	t->trig = iio_allocate_trigger("sysfstrig%d", id);
+	if (!t->trig) {
 		ret = -ENOMEM;
-		goto out2;
+		goto free_t;
 	}
 
-	ret = iio_trigger_register(trig);
-	if (ret)
-		goto out3;
-
-	platform_set_drvdata(pdev, trig);
+	t->trig->dev.groups = iio_sysfs_trigger_attr_groups;
+	t->trig->owner = THIS_MODULE;
+	t->trig->dev.parent = &iio_sysfs_trig_dev;
 
+	ret = iio_trigger_register(t->trig);
+	if (ret)
+		goto out2;
+	list_add(&t->l, &iio_sysfs_trig_list);
+	__module_get(THIS_MODULE);
+	mutex_unlock(&iio_syfs_trig_list_mut);
 	return 0;
-out3:
-	kfree(trig->name);
+
 out2:
-	iio_put_trigger(trig);
+	iio_put_trigger(t->trig);
+free_t:
+	kfree(t);
 out1:
-
+	mutex_unlock(&iio_syfs_trig_list_mut);
 	return ret;
 }
 
-static int __devexit iio_sysfs_trigger_remove(struct platform_device *pdev)
+static int iio_sysfs_trigger_remove(int id)
 {
-	struct iio_trigger *trig = platform_get_drvdata(pdev);
+	bool foundit = false;
+	struct iio_sysfs_trig *t;
+	mutex_lock(&iio_syfs_trig_list_mut);
+	list_for_each_entry(t, &iio_sysfs_trig_list, l)
+		if (id == t->id) {
+			foundit = true;
+			break;
+		}
+	if (!foundit) {
+		mutex_unlock(&iio_syfs_trig_list_mut);
+		return -EINVAL;
+	}
 
-	iio_trigger_unregister(trig);
-	kfree(trig->name);
-	iio_put_trigger(trig);
+	iio_trigger_unregister(t->trig);
+	iio_free_trigger(t->trig);
 
+	list_del(&t->l);
+	kfree(t);
+	module_put(THIS_MODULE);
+	mutex_unlock(&iio_syfs_trig_list_mut);
 	return 0;
 }
 
-static struct platform_driver iio_sysfs_trigger_driver = {
-	.driver = {
-		.name = "iio_sysfs_trigger",
-		.owner = THIS_MODULE,
-	},
-	.probe = iio_sysfs_trigger_probe,
-	.remove = __devexit_p(iio_sysfs_trigger_remove),
-};
 
 static int __init iio_sysfs_trig_init(void)
 {
-	return platform_driver_register(&iio_sysfs_trigger_driver);
+	device_initialize(&iio_sysfs_trig_dev);
+	dev_set_name(&iio_sysfs_trig_dev, "iio_sysfs_trigger");
+	return device_add(&iio_sysfs_trig_dev);
 }
 module_init(iio_sysfs_trig_init);
 
 static void __exit iio_sysfs_trig_exit(void)
 {
-	platform_driver_unregister(&iio_sysfs_trigger_driver);
+	device_unregister(&iio_sysfs_trig_dev);
 }
 module_exit(iio_sysfs_trig_exit);
 
diff -druN linux-2.6.39-libre/drivers/staging/iio/trigger/Kconfig linux-3.0-rc7-libre/drivers/staging/iio/trigger/Kconfig
--- linux-2.6.39-libre/drivers/staging/iio/trigger/Kconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/iio/trigger/Kconfig	2011-07-11 19:51:52.000000000 -0400
@@ -31,6 +31,7 @@
 config IIO_BFIN_TMR_TRIGGER
 	tristate "Blackfin TIMER trigger"
 	depends on BLACKFIN
+	select BFIN_GPTIMERS
 	help
 	  Provides support for using a Blackfin timer as IIO triggers.
 	  If unsure, say N (but it's safe to say "Y").
diff -druN linux-2.6.39-libre/drivers/staging/iio/trigger.h linux-3.0-rc7-libre/drivers/staging/iio/trigger.h
--- linux-2.6.39-libre/drivers/staging/iio/trigger.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/iio/trigger.h	2011-07-11 19:51:52.000000000 -0400
@@ -6,9 +6,15 @@
  * under the terms of the GNU General Public License version 2 as published by
  * the Free Software Foundation.
  */
+#include <linux/irq.h>
+
 #ifndef _IIO_TRIGGER_H_
 #define _IIO_TRIGGER_H_
 
+struct iio_subirq {
+	bool enabled;
+};
+
 /**
  * struct iio_trigger - industrial I/O trigger device
  *
@@ -18,14 +24,16 @@
  * @private_data:	[DRIVER] device specific data
  * @list:		[INTERN] used in maintenance of global trigger list
  * @alloc_list:		[DRIVER] used for driver specific trigger list
- * @pollfunc_list_lock:	[INTERN] protection of the polling function list
- * @pollfunc_list:	[INTERN] list of functions to run on trigger.
- * @control_attrs:	[DRIVER] sysfs attributes relevant to trigger type
  * @owner:		[DRIVER] used to monitor usage count of the trigger.
  * @use_count:		use count for the trigger
  * @set_trigger_state:	[DRIVER] switch on/off the trigger on demand
  * @try_reenable:	function to reenable the trigger when the
  *			use count is zero (may be NULL)
+ * @subirq_chip:	[INTERN] associate 'virtual' irq chip.
+ * @subirq_base:	[INTERN] base number for irqs provided by trigger.
+ * @subirqs:		[INTERN] information about the 'child' irqs.
+ * @pool:		[INTERN] bitmap of irqs currently in use.
+ * @pool_lock:		[INTERN] protection of the irq pool.
  **/
 struct iio_trigger {
 	int				id;
@@ -35,14 +43,18 @@
 	void				*private_data;
 	struct list_head		list;
 	struct list_head		alloc_list;
-	spinlock_t			pollfunc_list_lock;
-	struct list_head		pollfunc_list;
-	const struct attribute_group	*control_attrs;
 	struct module			*owner;
 	int use_count;
 
 	int (*set_trigger_state)(struct iio_trigger *trig, bool state);
 	int (*try_reenable)(struct iio_trigger *trig);
+
+	struct irq_chip			subirq_chip;
+	int				subirq_base;
+
+	struct iio_subirq subirqs[CONFIG_IIO_CONSUMERS_PER_TRIGGER];
+	unsigned long pool[BITS_TO_LONGS(CONFIG_IIO_CONSUMERS_PER_TRIGGER)];
+	struct mutex			pool_lock;
 };
 
 static inline struct iio_trigger *to_iio_trigger(struct device *d)
@@ -63,27 +75,6 @@
 };
 
 /**
- * iio_trigger_read_name() - sysfs access function to get the trigger name
- * @dev: the system device
- * @attr: device attributes for the device
- * @buf: output buffer to store the trigger name
- **/
-ssize_t iio_trigger_read_name(struct device *dev,
-			      struct device_attribute *attr,
-			      char *buf);
-
-#define IIO_TRIGGER_NAME_ATTR DEVICE_ATTR(name, S_IRUGO,		\
-					  iio_trigger_read_name,	\
-					  NULL);
-
-/**
- * iio_trigger_find_by_name() - search global trigger list
- * @name: trigger name to search for
- * @len: trigger name string length to compare
- **/
-struct iio_trigger *iio_trigger_find_by_name(const char *name, size_t len);
-
-/**
  * iio_trigger_register() - register a trigger with the IIO core
  * @trig_info:	trigger to be registered
  **/
@@ -119,36 +110,65 @@
  * Typically called in relevant hardware interrupt handler.
  **/
 void iio_trigger_poll(struct iio_trigger *trig, s64 time);
+void iio_trigger_poll_chained(struct iio_trigger *trig, s64 time);
 void iio_trigger_notify_done(struct iio_trigger *trig);
 
+irqreturn_t iio_trigger_generic_data_rdy_poll(int irq, void *private);
+
+static inline int iio_trigger_get_irq(struct iio_trigger *trig)
+{
+	int ret;
+	mutex_lock(&trig->pool_lock);
+	ret = bitmap_find_free_region(trig->pool,
+				      CONFIG_IIO_CONSUMERS_PER_TRIGGER,
+				      ilog2(1));
+	mutex_unlock(&trig->pool_lock);
+	if (ret >= 0)
+		ret += trig->subirq_base;
+
+	return ret;
+};
+
+static inline void iio_trigger_put_irq(struct iio_trigger *trig, int irq)
+{
+	mutex_lock(&trig->pool_lock);
+	clear_bit(irq - trig->subirq_base, trig->pool);
+	mutex_unlock(&trig->pool_lock);
+};
+
 /**
  * struct iio_poll_func - poll function pair
  *
- * @list:			associate this with a triggers pollfunc_list
  * @private_data:		data specific to device (passed into poll func)
- * @poll_func_immediate:	function in here is run first. They should be
- *				extremely lightweight.  Typically used for latch
- *				control on sensor supporting it.
- * @poll_func_main:		function in here is run after all immediates.
- *				Reading from sensor etc typically involves
- *				scheduling from here.
- *
- * The two stage approach used here is only important when multiple sensors are
- * being triggered by a single trigger. This really comes into its own with
- * simultaneous sampling devices where a simple latch command can be used to
- * make the device store the values on all inputs.
+ * @h:				the function that is actually run on trigger
+ * @thread:			threaded interrupt part
+ * @type:			the type of interrupt (basically if oneshot)
+ * @name:			name used to identify the trigger consumer.
+ * @irq:			the corresponding irq as allocated from the
+ *				trigger pool
+ * @timestamp:			some devices need a timestamp grabbed as soon
+ *				as possible after the trigger - hence handler
+ *				passes it via here.
  **/
 struct iio_poll_func {
-	struct				list_head list;
 	void				*private_data;
-	void (*poll_func_immediate)(struct iio_dev *indio_dev);
-	void (*poll_func_main)(struct iio_dev *private_data, s64 time);
-
+	irqreturn_t (*h)(int irq, void *p);
+	irqreturn_t (*thread)(int irq, void *p);
+	int type;
+	char *name;
+	int irq;
+	s64 timestamp;
 };
 
-int iio_alloc_pollfunc(struct iio_dev *indio_dev,
-		       void (*immediate)(struct iio_dev *indio_dev),
-		       void (*main)(struct iio_dev *private_data, s64 time));
+struct iio_poll_func
+*iio_alloc_pollfunc(irqreturn_t (*h)(int irq, void *p),
+		    irqreturn_t (*thread)(int irq, void *p),
+		    int type,
+		    void *private,
+		    const char *fmt,
+		    ...);
+void iio_dealloc_pollfunc(struct iio_poll_func *pf);
+irqreturn_t iio_pollfunc_store_time(int irq, void *p);
 
 /*
  * Two functions for common case where all that happens is a pollfunc
@@ -157,8 +177,8 @@
 int iio_triggered_ring_postenable(struct iio_dev *indio_dev);
 int iio_triggered_ring_predisable(struct iio_dev *indio_dev);
 
-struct iio_trigger *iio_allocate_trigger(void);
-
+struct iio_trigger *iio_allocate_trigger(const char *fmt, ...)
+	__attribute__((format(printf, 1, 2)));
 void iio_free_trigger(struct iio_trigger *trig);
 
 #endif /* _IIO_TRIGGER_H_ */
diff -druN linux-2.6.39-libre/drivers/staging/intel_sst/intelmid_adc_control.h linux-3.0-rc7-libre/drivers/staging/intel_sst/intelmid_adc_control.h
--- linux-2.6.39-libre/drivers/staging/intel_sst/intelmid_adc_control.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/staging/intel_sst/intelmid_adc_control.h	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,193 @@
+#ifndef __INTELMID_ADC_CONTROL_H__
+#define __INTELMID_ADC_CONTROL_H_
+/*
+ *  intelmid_adc_control.h - Intel SST Driver for audio engine
+ *
+ *  Copyright (C) 2008-10 Intel Corporation
+ *  Authors:	R Durgadadoss <r.durgadoss@intel.com>
+ *		Dharageswari R <dharageswari.r@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.
+ *
+ *  This program is distributed in the hope that it will be useful, but
+ *  WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ *  Common private ADC declarations for SST
+ */
+
+
+#define MSIC_ADC1CNTL1		0x1C0
+#define MSIC_ADC_ENBL		0x10
+#define MSIC_ADC_START		0x08
+
+#define MSIC_ADC1CNTL3		0x1C2
+#define MSIC_ADCTHERM_ENBL	0x04
+#define MSIC_ADCRRDATA_ENBL	0x05
+
+#define MSIC_STOPBIT_MASK	16
+#define MSIC_ADCTHERM_MASK	4
+
+#define ADC_CHANLS_MAX		15 /* Number of ADC channels */
+#define ADC_LOOP_MAX		(ADC_CHANLS_MAX - 1)
+
+/* ADC channel code values */
+#define AUDIO_DETECT_CODE	0x06
+
+/* ADC base addresses */
+#define ADC_CHNL_START_ADDR	0x1C5	/* increments by 1 */
+#define ADC_DATA_START_ADDR     0x1D4   /* increments by 2 */
+
+
+/**
+ * configure_adc - enables/disables the ADC for conversion
+ * @val: zero: disables the ADC non-zero:enables the ADC
+ *
+ * Enable/Disable the ADC depending on the argument
+ *
+ * Can sleep
+ */
+static inline int configure_adc(int val)
+{
+	int ret;
+	struct sc_reg_access sc_access = {0,};
+
+
+	sc_access.reg_addr = MSIC_ADC1CNTL1;
+	ret = sst_sc_reg_access(&sc_access, PMIC_READ, 1);
+	if (ret)
+		return ret;
+
+	if (val)
+		/* Enable and start the ADC */
+		sc_access.value |= (MSIC_ADC_ENBL | MSIC_ADC_START);
+	else
+		/* Just stop the ADC */
+		sc_access.value &= (~MSIC_ADC_START);
+	sc_access.reg_addr = MSIC_ADC1CNTL1;
+	return sst_sc_reg_access(&sc_access, PMIC_WRITE, 1);
+}
+
+/**
+ * reset_stopbit - sets the stop bit to 0 on the given channel
+ * @addr: address of the channel
+ *
+ * Can sleep
+ */
+static inline int reset_stopbit(uint16_t addr)
+{
+	int ret;
+	struct sc_reg_access sc_access = {0,};
+	sc_access.reg_addr = addr;
+	ret = sst_sc_reg_access(&sc_access, PMIC_READ, 1);
+	if (ret)
+		return ret;
+	/* Set the stop bit to zero */
+	sc_access.reg_addr = addr;
+	sc_access.value = (sc_access.value) & 0xEF;
+	return sst_sc_reg_access(&sc_access, PMIC_WRITE, 1);
+}
+
+/**
+ * find_free_channel - finds an empty channel for conversion
+ *
+ * If the ADC is not enabled then start using 0th channel
+ * itself. Otherwise find an empty channel by looking for a
+ * channel in which the stopbit is set to 1. returns the index
+ * of the first free channel if succeeds or an error code.
+ *
+ * Context: can sleep
+ *
+ */
+static inline int find_free_channel(void)
+{
+	int ret;
+	int i;
+
+	struct sc_reg_access sc_access = {0,};
+
+	/* check whether ADC is enabled */
+	sc_access.reg_addr = MSIC_ADC1CNTL1;
+	ret = sst_sc_reg_access(&sc_access, PMIC_READ, 1);
+	if (ret)
+		return ret;
+
+	if ((sc_access.value & MSIC_ADC_ENBL) == 0)
+		return 0;
+
+	/* ADC is already enabled; Looking for an empty channel */
+	for (i = 0; i < ADC_CHANLS_MAX; i++) {
+
+		sc_access.reg_addr = ADC_CHNL_START_ADDR + i;
+		ret = sst_sc_reg_access(&sc_access, PMIC_READ, 1);
+		if (ret)
+			return ret;
+
+		if (sc_access.value & MSIC_STOPBIT_MASK) {
+			ret = i;
+			break;
+		}
+	}
+	return (ret > ADC_LOOP_MAX) ? (-EINVAL) : ret;
+}
+
+/**
+ * mid_initialize_adc - initializing the ADC
+ * @dev: our device structure
+ *
+ * Initialize the ADC for reading thermistor values. Can sleep.
+ */
+static inline int mid_initialize_adc(void)
+{
+	int base_addr, chnl_addr;
+	int ret;
+	static int channel_index;
+	struct sc_reg_access sc_access = {0,};
+
+	/* Index of the first channel in which the stop bit is set */
+	channel_index = find_free_channel();
+	if (channel_index < 0) {
+		pr_err("No free ADC channels");
+		return channel_index;
+	}
+
+	base_addr = ADC_CHNL_START_ADDR + channel_index;
+
+	if (!(channel_index == 0 || channel_index == ADC_LOOP_MAX)) {
+		/* Reset stop bit for channels other than 0 and 12 */
+		ret = reset_stopbit(base_addr);
+		if (ret)
+			return ret;
+
+		/* Index of the first free channel */
+		base_addr++;
+		channel_index++;
+	}
+
+	/* Since this is the last channel, set the stop bit
+	   to 1 by ORing the DIE_SENSOR_CODE with 0x10 */
+	sc_access.reg_addr = base_addr;
+	sc_access.value = AUDIO_DETECT_CODE | 0x10;
+	ret = sst_sc_reg_access(&sc_access, PMIC_WRITE, 1);
+	if (ret) {
+		pr_err("unable to enable ADC");
+		return ret;
+	}
+
+	chnl_addr = ADC_DATA_START_ADDR + 2 * channel_index;
+	pr_debug("mid_initialize : %x", chnl_addr);
+	configure_adc(1);
+	return chnl_addr;
+}
+#endif
+
diff -druN linux-2.6.39-libre/drivers/staging/intel_sst/intelmid.c linux-3.0-rc7-libre/drivers/staging/intel_sst/intelmid.c
--- linux-2.6.39-libre/drivers/staging/intel_sst/intelmid.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/intel_sst/intelmid.c	2011-07-11 19:51:52.000000000 -0400
@@ -32,15 +32,21 @@
 #include <linux/platform_device.h>
 #include <linux/interrupt.h>
 #include <linux/sched.h>
+#include <linux/firmware.h>
+#include <linux/input.h>
 #include <sound/control.h>
 #include <asm/mrst.h>
 #include <sound/pcm.h>
-#include "jack.h"
+#include <sound/jack.h>
 #include <sound/pcm_params.h>
 #include <sound/initval.h>
+#include <linux/gpio.h>
 #include "intel_sst.h"
 #include "intel_sst_ioctl.h"
+#include "intel_sst_fw_ipc.h"
+#include "intel_sst_common.h"
 #include "intelmid_snd_control.h"
+#include "intelmid_adc_control.h"
 #include "intelmid.h"
 
 MODULE_AUTHOR("Vinod Koul <vinod.koul@intel.com>");
@@ -62,7 +68,14 @@
 
 int	sst_card_vendor_id;
 int intelmid_audio_interrupt_enable;/*checkpatch fix*/
+struct snd_intelmad *intelmad_drv;
 
+#define INFO(_cpu_id, _irq_cache, _size) \
+	((kernel_ulong_t)&(struct snd_intelmad_probe_info) {	\
+		.cpu_id = (_cpu_id),			\
+		.irq_cache = (_irq_cache),			\
+		.size = (_size),				\
+	})
 /* Data path functionalities */
 static struct snd_pcm_hardware snd_intelmad_stream = {
 	.info =	(SNDRV_PCM_INFO_INTERLEAVED |
@@ -184,7 +197,7 @@
 		return ret_val;
 	}
 
-	 ret_val = snd_intelmad_alloc_stream(substream);
+	ret_val = snd_intelmad_alloc_stream(substream);
 	if (ret_val < 0)
 		return ret_val;
 	stream->dbg_cum_bytes = 0;
@@ -323,6 +336,16 @@
 	runtime = substream->runtime;
 	/* set the runtime hw parameter with local snd_pcm_hardware struct */
 	runtime->hw = snd_intelmad_stream;
+	if (intelmaddata->cpu_id == CPU_CHIP_LINCROFT) {
+		/*
+		 * MRST firmware currently denies stereo recording requests.
+		 */
+		if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
+			runtime->hw.formats = (SNDRV_PCM_FMTBIT_S16 |
+					       SNDRV_PCM_FMTBIT_U16);
+			runtime->hw.channels_max = 1;
+		}
+	}
 	if (intelmaddata->cpu_id == CPU_CHIP_PENWELL) {
 		runtime->hw = snd_intelmad_stream;
 		runtime->hw.rates = SNDRV_PCM_RATE_48000;
@@ -423,7 +446,55 @@
 	.pointer = snd_intelmad_pcm_pointer,
 };
 
+int intelmad_get_mic_bias(void)
+{
+	struct snd_pmic_ops *pmic_ops;
+
+	if (!intelmad_drv || !intelmad_drv->sstdrv_ops)
+		return -ENODEV;
+	pmic_ops = intelmad_drv->sstdrv_ops->scard_ops;
+	if (pmic_ops && pmic_ops->pmic_get_mic_bias)
+		return pmic_ops->pmic_get_mic_bias(intelmad_drv);
+	else
+		return -ENODEV;
+}
+EXPORT_SYMBOL_GPL(intelmad_get_mic_bias);
+
+int intelmad_set_headset_state(int state)
+{
+	struct snd_pmic_ops *pmic_ops;
+
+	if (!intelmad_drv || !intelmad_drv->sstdrv_ops)
+		return -ENODEV;
+	pmic_ops = intelmad_drv->sstdrv_ops->scard_ops;
+	if (pmic_ops && pmic_ops->pmic_set_headset_state)
+		return pmic_ops->pmic_set_headset_state(state);
+	else
+		return -ENODEV;
+}
+EXPORT_SYMBOL_GPL(intelmad_set_headset_state);
+
+void sst_process_mad_jack_detection(struct work_struct *work)
+{
+	u8 interrupt_status;
+	struct mad_jack_msg_wq *mad_jack_detect =
+			container_of(work, struct mad_jack_msg_wq, wq);
 
+	struct snd_intelmad *intelmaddata =
+			mad_jack_detect->intelmaddata;
+
+	if (!intelmaddata)
+		return;
+
+	interrupt_status = mad_jack_detect->intsts;
+	if (intelmaddata->sstdrv_ops && intelmaddata->sstdrv_ops->scard_ops
+			&& intelmaddata->sstdrv_ops->scard_ops->pmic_irq_cb) {
+		intelmaddata->sstdrv_ops->scard_ops->pmic_irq_cb(
+			(void *)intelmaddata, interrupt_status);
+		intelmaddata->sstdrv_ops->scard_ops->pmic_jack_enable();
+	}
+	kfree(mad_jack_detect);
+}
 /**
  * snd_intelmad_intr_handler- interrupt handler
  *
@@ -436,15 +507,17 @@
 {
 	struct snd_intelmad *intelmaddata =
 			(struct snd_intelmad *)dev;
-	u8 intsts;
-
-	memcpy_fromio(&intsts,
+	u8 interrupt_status;
+	struct mad_jack_msg_wq  *mad_jack_msg;
+	memcpy_fromio(&interrupt_status,
 			((void *)(intelmaddata->int_base)),
 			sizeof(u8));
-	intelmaddata->mad_jack_msg.intsts = intsts;
-	intelmaddata->mad_jack_msg.intelmaddata = intelmaddata;
 
-	queue_work(intelmaddata->mad_jack_wq, &intelmaddata->mad_jack_msg.wq);
+	mad_jack_msg = kzalloc(sizeof(*mad_jack_msg), GFP_ATOMIC);
+	mad_jack_msg->intsts = interrupt_status;
+	mad_jack_msg->intelmaddata = intelmaddata;
+	INIT_WORK(&mad_jack_msg->wq, sst_process_mad_jack_detection);
+	queue_work(intelmaddata->mad_jack_wq, &mad_jack_msg->wq);
 
 	return IRQ_HANDLED;
 }
@@ -457,286 +530,22 @@
 		pr_debug("MAD error jack empty\n");
 
 	} else {
-		pr_debug("MAD send jack report for = %d!!!\n", status);
-		pr_debug("MAD send jack report %d\n", jack->type);
 		snd_jack_report(jack, status);
-
-		/*button pressed and released */
+		/* button pressed and released */
 		if (buttonpressevent)
 			snd_jack_report(jack, 0);
 		pr_debug("MAD sending jack report Done !!!\n");
 	}
-
-
-
 }
 
-void sst_mad_jackdetection_fs(u8 intsts , struct snd_intelmad *intelmaddata)
-{
-	struct snd_jack *jack = NULL;
-	unsigned int present = 0, jack_event_flag = 0, buttonpressflag = 0;
-	struct sc_reg_access sc_access[] = {
-				{0x187, 0x00, MASK7},
-				{0x188, 0x10, MASK4},
-				{0x18b, 0x10, MASK4},
-	};
-
-	struct sc_reg_access sc_access_write[] = {
-				{0x198, 0x00, 0x0},
-	};
-
-	if (intsts & 0x4) {
-
-		if (!(intelmid_audio_interrupt_enable)) {
-			pr_debug("Audio interrupt enable\n");
-			sst_sc_reg_access(sc_access, PMIC_READ_MODIFY, 3);
-
-			sst_sc_reg_access(sc_access_write, PMIC_WRITE, 1);
-			intelmid_audio_interrupt_enable = 1;
-			intelmaddata->jack[0].jack_status = 0;
-			intelmaddata->jack[1].jack_status = 0;
-
-		}
-		/* send headphone detect */
-		pr_debug("MAD headphone %d\n", intsts & 0x4);
-		jack = &intelmaddata->jack[0].jack;
-		present = !(intelmaddata->jack[0].jack_status);
-		intelmaddata->jack[0].jack_status = present;
-		jack_event_flag = 1;
-
-	}
-
-	if (intsts & 0x2) {
-		/* send short push */
-		pr_debug("MAD short push %d\n", intsts & 0x2);
-		jack = &intelmaddata->jack[2].jack;
-		present = 1;
-		jack_event_flag = 1;
-		buttonpressflag = 1;
-	}
-	if (intsts & 0x1) {
-		/* send long push */
-		pr_debug("MAD long push %d\n", intsts & 0x1);
-		jack = &intelmaddata->jack[3].jack;
-		present = 1;
-		jack_event_flag = 1;
-		buttonpressflag = 1;
-	}
-	if (intsts & 0x8) {
-		if (!(intelmid_audio_interrupt_enable)) {
-			pr_debug("Audio interrupt enable\n");
-			sst_sc_reg_access(sc_access, PMIC_READ_MODIFY, 3);
-
-			sst_sc_reg_access(sc_access_write, PMIC_WRITE, 1);
-			intelmid_audio_interrupt_enable = 1;
-			intelmaddata->jack[0].jack_status = 0;
-			intelmaddata->jack[1].jack_status = 0;
-		}
-		/* send headset detect */
-		pr_debug("MAD headset = %d\n", intsts & 0x8);
-		jack = &intelmaddata->jack[1].jack;
-		present = !(intelmaddata->jack[1].jack_status);
-		intelmaddata->jack[1].jack_status = present;
-		jack_event_flag = 1;
-	}
-
-	if (jack_event_flag)
-		sst_mad_send_jack_report(jack, buttonpressflag, present);
-}
-
-
-void sst_mad_jackdetection_mx(u8 intsts, struct snd_intelmad *intelmaddata)
-{
-	u8 value = 0, jack_prev_state = 0;
-	struct snd_jack *jack = NULL;
-	unsigned int present = 0, jack_event_flag = 0, buttonpressflag = 0;
-	time_t  timediff;
-	struct sc_reg_access sc_access_read = {0,};
-	struct snd_pmic_ops *scard_ops;
-
-	scard_ops = intelmaddata->sstdrv_ops->scard_ops;
-
-	pr_debug("previous value: %x\n", intelmaddata->jack_prev_state);
-
-	if (!(intelmid_audio_interrupt_enable)) {
-		pr_debug("Audio interrupt enable\n");
-		intelmaddata->jack_prev_state = 0xC0;
-		intelmid_audio_interrupt_enable = 1;
-	}
-
-	if (intsts & 0x2) {
-		jack_prev_state = intelmaddata->jack_prev_state;
-		if (intelmaddata->pmic_status == PMIC_INIT) {
-			sc_access_read.reg_addr = 0x201;
-			sst_sc_reg_access(&sc_access_read, PMIC_READ, 1);
-			value = (sc_access_read.value);
-			pr_debug("value returned = 0x%x\n", value);
-		}
-
-		if (jack_prev_state == 0xc0 && value == 0x40) {
-			/*headset detected. */
-			pr_debug("MAD headset inserted\n");
-			jack = &intelmaddata->jack[1].jack;
-			present = 1;
-			jack_event_flag = 1;
-			intelmaddata->jack[1].jack_status = 1;
-
-		}
-
-		if (jack_prev_state == 0xc0 && value == 0x00) {
-			/* headphone  detected. */
-			pr_debug("MAD headphone inserted\n");
-			jack = &intelmaddata->jack[0].jack;
-			present = 1;
-			jack_event_flag = 1;
-
-		}
-
-		if (jack_prev_state == 0x40 && value == 0xc0) {
-			/*headset  removed*/
-			pr_debug("Jack headset status %d\n",
-				intelmaddata->jack[1].jack_status);
-			pr_debug("MAD headset removed\n");
-			jack = &intelmaddata->jack[1].jack;
-			present = 0;
-			jack_event_flag = 1;
-			intelmaddata->jack[1].jack_status = 0;
-		}
-
-		if (jack_prev_state == 0x00 && value == 0xc0) {
-			/* headphone  detected. */
-			pr_debug("Jack headphone status %d\n",
-					intelmaddata->jack[0].jack_status);
-			pr_debug("headphone removed\n");
-			jack = &intelmaddata->jack[0].jack;
-			present = 0;
-			jack_event_flag = 1;
-		}
-
-		if (jack_prev_state == 0x40 && value == 0x00) {
-			/*button pressed*/
-			do_gettimeofday(&intelmaddata->jack[1].buttonpressed);
-			pr_debug("MAD button press detected\n");
-		}
-
-
-		if (jack_prev_state == 0x00 && value == 0x40) {
-			if (intelmaddata->jack[1].jack_status) {
-				/*button pressed*/
-				do_gettimeofday(
-					&intelmaddata->jack[1].buttonreleased);
-				/*button pressed */
-				pr_debug("Button Released detected\n");
-				timediff = intelmaddata->jack[1].
-					buttonreleased.tv_sec - intelmaddata->
-					jack[1].buttonpressed.tv_sec;
-				buttonpressflag = 1;
-				if (timediff > 1) {
-					pr_debug("long press detected\n");
-					/* send headphone detect/undetect */
-					jack = &intelmaddata->jack[3].jack;
-					present = 1;
-					jack_event_flag = 1;
-				} else {
-					pr_debug("short press detected\n");
-					/* send headphone detect/undetect */
-					jack = &intelmaddata->jack[2].jack;
-					present = 1;
-					jack_event_flag = 1;
-				}
-			}
-
-		}
-		intelmaddata->jack_prev_state = value;
-	}
-	if (jack_event_flag)
-		sst_mad_send_jack_report(jack, buttonpressflag, present);
-}
-
-
-void sst_mad_jackdetection_nec(u8 intsts, struct snd_intelmad *intelmaddata)
-{
-	u8 value = 0;
-	struct snd_jack *jack = NULL;
-	unsigned int present = 0, jack_event_flag = 0, buttonpressflag = 0;
-	struct sc_reg_access sc_access_read = {0,};
-
-	if (intelmaddata->pmic_status == PMIC_INIT) {
-		sc_access_read.reg_addr = 0x132;
-		sst_sc_reg_access(&sc_access_read, PMIC_READ, 1);
-		value = (sc_access_read.value);
-		pr_debug("value returned = 0x%x\n", value);
-	}
-	if (intsts & 0x1) {
-		pr_debug("headset detected\n");
-		/* send headset detect/undetect */
-		jack = &intelmaddata->jack[1].jack;
-		present = (value == 0x1) ? 1 : 0;
-		jack_event_flag = 1;
-	}
-	if (intsts & 0x2) {
-		pr_debug("headphone detected\n");
-		/* send headphone detect/undetect */
-		jack = &intelmaddata->jack[0].jack;
-		present = (value == 0x2) ? 1 : 0;
-		jack_event_flag = 1;
-	}
-	if (intsts & 0x4) {
-		pr_debug("short push detected\n");
-		/* send short push */
-		jack = &intelmaddata->jack[2].jack;
-		present = 1;
-		jack_event_flag = 1;
-		buttonpressflag = 1;
-	}
-	if (intsts & 0x8) {
-		pr_debug("long push detected\n");
-		/* send long push */
-		jack = &intelmaddata->jack[3].jack;
-		present = 1;
-		jack_event_flag = 1;
-		buttonpressflag = 1;
-	}
-
-	if (jack_event_flag)
-		sst_mad_send_jack_report(jack, buttonpressflag, present);
-
-
-}
-
-void sst_process_mad_jack_detection(struct work_struct *work)
-{
-	u8 intsts;
-	struct mad_jack_msg_wq *mad_jack_detect =
-			container_of(work, struct mad_jack_msg_wq, wq);
-
-	struct snd_intelmad *intelmaddata =
-			mad_jack_detect->intelmaddata;
-
-	intsts = mad_jack_detect->intsts;
-
-	switch (intelmaddata->sstdrv_ops->vendor_id) {
-	case SND_FS:
-		sst_mad_jackdetection_fs(intsts , intelmaddata);
-		break;
-	case SND_MX:
-		sst_mad_jackdetection_mx(intsts , intelmaddata);
-		break;
-	case SND_NC:
-		sst_mad_jackdetection_nec(intsts , intelmaddata);
-		break;
-	}
-}
-
-
 static int __devinit snd_intelmad_register_irq(
-					struct snd_intelmad *intelmaddata)
+		struct snd_intelmad *intelmaddata, unsigned int regbase,
+		unsigned int regsize)
 {
 	int ret_val;
-	u32 regbase = AUDINT_BASE, regsize = 8;
 	char *drv_name;
 
-	pr_debug("irq reg done, regbase 0x%x, regsize 0x%x\n",
+	pr_debug("irq reg regbase 0x%x, regsize 0x%x\n",
 					regbase, regsize);
 	intelmaddata->int_base = ioremap_nocache(regbase, regsize);
 	if (!intelmaddata->int_base)
@@ -794,6 +603,7 @@
 		intelmaddata->sstdrv_ops->scard_ops->input_dev_id = DMIC;
 		intelmaddata->sstdrv_ops->scard_ops->output_dev_id =
 							STEREO_HEADPHONE;
+		intelmaddata->sstdrv_ops->scard_ops->lineout_dev_id = NONE;
 	}
 
 	/* registering with SST driver to get access to SST APIs to use */
@@ -802,12 +612,15 @@
 		pr_err("sst card registration failed\n");
 		return ret_val;
 	}
-
 	sst_card_vendor_id = intelmaddata->sstdrv_ops->vendor_id;
 	intelmaddata->pmic_status = PMIC_UNINIT;
 	return ret_val;
 }
 
+static void snd_intelmad_page_free(struct snd_pcm *pcm)
+{
+	snd_pcm_lib_preallocate_free_for_all(pcm);
+}
 /* Driver Init/exit functionalities */
 /**
  * snd_intelmad_pcm_new - to setup pcm for the card
@@ -859,6 +672,7 @@
 		snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, cap_ops);
 	/* setup private data which can be retrieved when required */
 	pcm->private_data = intelmaddata;
+	pcm->private_free = snd_intelmad_page_free;
 	pcm->info_flags = 0;
 	strncpy(pcm->name, card->shortname, strlen(card->shortname));
 	/* allocate dma pages for ALSA stream operations */
@@ -903,8 +717,12 @@
 
 	pr_debug("snd_intelmad_jack called\n");
 	jack = &intelmaddata->jack[0].jack;
-	retval = snd_jack_new(intelmaddata->card, "Headphone",
-				SND_JACK_HEADPHONE, &jack);
+	snd_jack_set_key(jack, SND_JACK_BTN_0, KEY_PHONE);
+	retval = snd_jack_new(intelmaddata->card, "Intel(R) MID Audio Jack",
+		SND_JACK_HEADPHONE | SND_JACK_HEADSET |
+		SW_JACK_PHYSICAL_INSERT | SND_JACK_BTN_0
+		| SND_JACK_BTN_1, &jack);
+	pr_debug("snd_intelmad_jack called\n");
 	if (retval < 0)
 		return retval;
 	snd_jack_report(jack, 0);
@@ -912,40 +730,6 @@
 	jack->private_data = jack;
 	intelmaddata->jack[0].jack = *jack;
 
-
-	jack = &intelmaddata->jack[1].jack;
-	retval = snd_jack_new(intelmaddata->card, "Headset",
-				SND_JACK_HEADSET, &jack);
-	if (retval < 0)
-		return retval;
-
-
-
-	jack->private_data = jack;
-	intelmaddata->jack[1].jack = *jack;
-
-
-	jack = &intelmaddata->jack[2].jack;
-	retval = snd_jack_new(intelmaddata->card, "Short Press",
-				SND_JACK_HS_SHORT_PRESS, &jack);
-	if (retval < 0)
-		return retval;
-
-
-	jack->private_data = jack;
-	intelmaddata->jack[2].jack = *jack;
-
-
-	jack = &intelmaddata->jack[3].jack;
-	retval = snd_jack_new(intelmaddata->card, "Long Press",
-				SND_JACK_HS_LONG_PRESS, &jack);
-	if (retval < 0)
-		return retval;
-
-
-	jack->private_data = jack;
-	intelmaddata->jack[3].jack = *jack;
-
 	return retval;
 }
 
@@ -998,14 +782,14 @@
 	intelmaddata = device->device_data;
 
 	pr_debug("snd_intelmad_dev_free called\n");
-	snd_card_free(intelmaddata->card);
-	/*genl_unregister_family(&audio_event_genl_family);*/
 	unregister_sst_card(intelmaddata->sstdrv_ops);
 
 	/* free allocated memory for internal context */
 	destroy_workqueue(intelmaddata->mad_jack_wq);
+	device->device_data = NULL;
 	kfree(intelmaddata->sstdrv_ops);
 	kfree(intelmaddata);
+
 	return 0;
 }
 
@@ -1036,9 +820,10 @@
 	int ret_val;
 	struct snd_intelmad *intelmaddata;
 	const struct platform_device_id *id = platform_get_device_id(pdev);
-	unsigned int cpu_id = (unsigned int)id->driver_data;
+	struct snd_intelmad_probe_info *info = (void *)id->driver_data;
 
-	pr_debug("probe for %s cpu_id %d\n", pdev->name, cpu_id);
+	pr_debug("probe for %s cpu_id %d\n", pdev->name, info->cpu_id);
+	pr_debug("rq_chache %x of size %x\n", info->irq_cache, info->size);
 	if (!strcmp(pdev->name, DRIVER_NAME_MRST))
 		pr_debug("detected MRST\n");
 	else if (!strcmp(pdev->name, DRIVER_NAME_MFLD))
@@ -1047,7 +832,8 @@
 		pr_err("detected unknown device abort!!\n");
 		return -EIO;
 	}
-	if ((cpu_id < CPU_CHIP_LINCROFT) || (cpu_id > CPU_CHIP_PENWELL)) {
+	if ((info->cpu_id < CPU_CHIP_LINCROFT) ||
+				(info->cpu_id > CPU_CHIP_PENWELL)) {
 		pr_err("detected unknown cpu_id abort!!\n");
 		return -EIO;
 	}
@@ -1057,6 +843,7 @@
 		pr_debug("mem alloctn fail\n");
 		return -ENOMEM;
 	}
+	intelmad_drv = intelmaddata;
 
 	/* allocate memory for LPE API set */
 	intelmaddata->sstdrv_ops = kzalloc(sizeof(struct intel_sst_card_ops),
@@ -1067,7 +854,7 @@
 		return -ENOMEM;
 	}
 
-	intelmaddata->cpu_id = cpu_id;
+	intelmaddata->cpu_id = info->cpu_id;
 	/* create a card instance with ALSA framework */
 	ret_val = snd_card_create(card_index, card_id, THIS_MODULE, 0, &card);
 	if (ret_val) {
@@ -1091,7 +878,7 @@
 	ret_val = snd_intelmad_sst_register(intelmaddata);
 	if (ret_val) {
 		pr_err("snd_intelmad_sst_register failed\n");
-		goto free_allocs;
+		goto set_null_data;
 	}
 
 	intelmaddata->pmic_status = PMIC_INIT;
@@ -1099,20 +886,21 @@
 	ret_val = snd_intelmad_pcm(card, intelmaddata);
 	if (ret_val) {
 		pr_err("snd_intelmad_pcm failed\n");
-		goto free_allocs;
+		goto free_sst;
 	}
 
 	ret_val = snd_intelmad_mixer(intelmaddata);
 	if (ret_val) {
 		pr_err("snd_intelmad_mixer failed\n");
-		goto free_allocs;
+		goto free_card;
 	}
 
 	ret_val = snd_intelmad_jack(intelmaddata);
 	if (ret_val) {
 		pr_err("snd_intelmad_jack failed\n");
-		goto free_allocs;
+		goto free_card;
 	}
+	intelmaddata->adc_address = mid_initialize_adc();
 
 	/*create work queue for jack interrupt*/
 	INIT_WORK(&intelmaddata->mad_jack_msg.wq,
@@ -1120,33 +908,48 @@
 
 	intelmaddata->mad_jack_wq = create_workqueue("sst_mad_jack_wq");
 	if (!intelmaddata->mad_jack_wq)
-		goto free_mad_jack_wq;
+		goto free_card;
 
-	ret_val = snd_intelmad_register_irq(intelmaddata);
+	ret_val = snd_intelmad_register_irq(intelmaddata,
+					info->irq_cache, info->size);
 	if (ret_val) {
 		pr_err("snd_intelmad_register_irq fail\n");
-		goto free_allocs;
+		goto free_mad_jack_wq;
 	}
 
 	/* internal function call to register device with ALSA */
 	ret_val = snd_intelmad_create(intelmaddata, card);
 	if (ret_val) {
 		pr_err("snd_intelmad_create failed\n");
-		goto free_allocs;
+		goto set_pvt_data;
 	}
 	card->private_data = &intelmaddata;
 	snd_card_set_dev(card, &pdev->dev);
 	ret_val = snd_card_register(card);
 	if (ret_val) {
 		pr_err("snd_card_register failed\n");
-		goto free_allocs;
+		goto set_pvt_data;
+	}
+	if (pdev->dev.platform_data) {
+		int gpio_amp = *(int *)pdev->dev.platform_data;
+		if (gpio_request_one(gpio_amp, GPIOF_OUT_INIT_LOW, "amp power"))
+			gpio_amp = 0;
+		intelmaddata->sstdrv_ops->scard_ops->gpio_amp = gpio_amp;
 	}
 
 	pr_debug("snd_intelmad_probe complete\n");
 	return ret_val;
 
+set_pvt_data:
+	card->private_data = NULL;
 free_mad_jack_wq:
 	destroy_workqueue(intelmaddata->mad_jack_wq);
+free_card:
+	snd_card_free(intelmaddata->card);
+free_sst:
+	unregister_sst_card(intelmaddata->sstdrv_ops);
+set_null_data:
+	platform_set_drvdata(pdev, NULL);
 free_allocs:
 	pr_err("probe failed\n");
 	snd_card_free(card);
@@ -1161,13 +964,13 @@
 	struct snd_intelmad *intelmaddata = platform_get_drvdata(pdev);
 
 	if (intelmaddata) {
+		if (intelmaddata->sstdrv_ops->scard_ops->gpio_amp)
+			gpio_free(intelmaddata->sstdrv_ops->scard_ops->gpio_amp);
+		free_irq(intelmaddata->irq, intelmaddata);
 		snd_card_free(intelmaddata->card);
-		unregister_sst_card(intelmaddata->sstdrv_ops);
-		/* free allocated memory for internal context */
-		destroy_workqueue(intelmaddata->mad_jack_wq);
-		kfree(intelmaddata->sstdrv_ops);
-		kfree(intelmaddata);
 	}
+	intelmad_drv = NULL;
+	platform_set_drvdata(pdev, NULL);
 	return 0;
 }
 
@@ -1175,8 +978,8 @@
  *		Driver initialization and exit
  *********************************************************************/
 static const struct platform_device_id snd_intelmad_ids[] = {
-	{DRIVER_NAME_MRST, CPU_CHIP_LINCROFT},
-	{DRIVER_NAME_MFLD, CPU_CHIP_PENWELL},
+	{DRIVER_NAME_MRST, INFO(CPU_CHIP_LINCROFT, AUDINT_BASE, 1)},
+	{DRIVER_NAME_MFLD, INFO(CPU_CHIP_PENWELL, 0xFFFF7FCD, 1)},
 	{"", 0},
 
 };
diff -druN linux-2.6.39-libre/drivers/staging/intel_sst/intelmid_ctrl.c linux-3.0-rc7-libre/drivers/staging/intel_sst/intelmid_ctrl.c
--- linux-2.6.39-libre/drivers/staging/intel_sst/intelmid_ctrl.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/intel_sst/intelmid_ctrl.c	2011-07-11 19:51:52.000000000 -0400
@@ -29,17 +29,37 @@
 
 #include <sound/core.h>
 #include <sound/control.h>
-#include "jack.h"
 #include "intel_sst.h"
 #include "intel_sst_ioctl.h"
 #include "intelmid_snd_control.h"
 #include "intelmid.h"
 
+#define HW_CH_BASE 4
+
+
+#define HW_CH_0	"Hw1"
+#define HW_CH_1	"Hw2"
+#define HW_CH_2	"Hw3"
+#define HW_CH_3	"Hw4"
+
+static char *router_dmics[] = {	"DMIC1",
+				"DMIC2",
+				"DMIC3",
+				"DMIC4",
+				"DMIC5",
+				"DMIC6"
+				};
+
 static char *out_names_mrst[] = {"Headphones",
 				"Internal speakers"};
 static char *in_names_mrst[] = {"AMIC",
 				"DMIC",
 				"HS_MIC"};
+static char *line_out_names_mfld[] = {"Headset",
+				"IHF    ",
+				"Vibra1 ",
+				"Vibra2 ",
+				"NONE   "};
 static char *out_names_mfld[] = {"Headset ",
 				"EarPiece  "};
 static char *in_names_mfld[] = {"AMIC",
@@ -60,9 +80,11 @@
 	},
 	{
 		.playback_vol_max = 0,
-		.playback_vol_min = -126,
+		.playback_vol_min = -31,
 		.capture_vol_max = 0,
 		.capture_vol_min = -31,
+		.master_vol_max = 0,
+		.master_vol_min = -126,
 	},
 };
 
@@ -139,6 +161,15 @@
 	return 0;
 }
 
+static int snd_intelmad_master_volume_info(struct snd_kcontrol *kcontrol,
+					struct snd_ctl_elem_info *uinfo)
+{
+	snd_intelmad_volume_info(uinfo, STEREO_CNTL,
+		intelmad_ctrl_val[sst_card_vendor_id].master_vol_max,
+		intelmad_ctrl_val[sst_card_vendor_id].master_vol_min);
+	return 0;
+}
+
 /**
 * snd_intelmad_device_info_mrst - provides information about the devices available
 *
@@ -179,13 +210,27 @@
 static int snd_intelmad_device_info_mfld(struct snd_kcontrol *kcontrol,
 					struct snd_ctl_elem_info *uinfo)
 {
+	struct snd_pmic_ops *scard_ops;
+	struct snd_intelmad *intelmaddata;
+
 	WARN_ON(!kcontrol);
 	WARN_ON(!uinfo);
+
+	intelmaddata = kcontrol->private_data;
+
+	WARN_ON(!intelmaddata->sstdrv_ops);
+
+	scard_ops = intelmaddata->sstdrv_ops->scard_ops;
 	/* setup device select as drop down controls with different values */
 	if (kcontrol->id.numid == OUTPUT_SEL)
 		uinfo->value.enumerated.items = ARRAY_SIZE(out_names_mfld);
-	else
+	else if (kcontrol->id.numid == INPUT_SEL)
 		uinfo->value.enumerated.items = ARRAY_SIZE(in_names_mfld);
+	else if (kcontrol->id.numid == LINEOUT_SEL_MFLD) {
+		uinfo->value.enumerated.items = ARRAY_SIZE(line_out_names_mfld);
+		scard_ops->line_out_names_cnt = uinfo->value.enumerated.items;
+	} else
+		return -EINVAL;
 	uinfo->count = MONO_CNTL;
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
 
@@ -195,10 +240,16 @@
 		strncpy(uinfo->value.enumerated.name,
 			out_names_mfld[uinfo->value.enumerated.item],
 			sizeof(uinfo->value.enumerated.name)-1);
-	else
+	else if (kcontrol->id.numid == INPUT_SEL)
 		strncpy(uinfo->value.enumerated.name,
 			in_names_mfld[uinfo->value.enumerated.item],
 			sizeof(uinfo->value.enumerated.name)-1);
+	else if (kcontrol->id.numid == LINEOUT_SEL_MFLD)
+		strncpy(uinfo->value.enumerated.name,
+			line_out_names_mfld[uinfo->value.enumerated.item],
+			sizeof(uinfo->value.enumerated.name)-1);
+	else
+		return -EINVAL;
 	return 0;
 }
 
@@ -241,6 +292,11 @@
 	case CAPTURE_VOL:
 		cntl_list[0] = PMIC_SND_CAPTURE_VOL;
 		break;
+
+	case MASTER_VOL:
+		cntl_list[0] = PMIC_SND_RIGHT_MASTER_VOL;
+		cntl_list[1] = PMIC_SND_LEFT_MASTER_VOL;
+		break;
 	default:
 		return -EINVAL;
 	}
@@ -251,7 +307,8 @@
 	if (ret_val)
 		return ret_val;
 
-	if (kcontrol->id.numid == PLAYBACK_VOL) {
+	if (kcontrol->id.numid == PLAYBACK_VOL ||
+		kcontrol->id.numid == MASTER_VOL) {
 		ret_val = scard_ops->get_vol(cntl_list[1], &value);
 		uval->value.integer.value[1] = value;
 	}
@@ -359,6 +416,12 @@
 	case CAPTURE_VOL:
 		cntl_list[0] = PMIC_SND_CAPTURE_VOL;
 		break;
+
+	case MASTER_VOL:
+		cntl_list[0] = PMIC_SND_LEFT_MASTER_VOL;
+		cntl_list[1] = PMIC_SND_RIGHT_MASTER_VOL;
+		break;
+
 	default:
 		return -EINVAL;
 	}
@@ -368,7 +431,8 @@
 	if (ret_val)
 		return ret_val;
 
-	if (kcontrol->id.numid == PLAYBACK_VOL)
+	if (kcontrol->id.numid == PLAYBACK_VOL ||
+		kcontrol->id.numid == MASTER_VOL)
 		ret_val = scard_ops->set_vol(cntl_list[1],
 				uval->value.integer.value[1]);
 	return ret_val;
@@ -464,14 +528,36 @@
 	WARN_ON(!kcontrol);
 
 	intelmaddata = kcontrol->private_data;
+	scard_ops = intelmaddata->sstdrv_ops->scard_ops;
 	if (intelmaddata->cpu_id == CPU_CHIP_PENWELL) {
-		scard_ops = intelmaddata->sstdrv_ops->scard_ops;
 		if (kcontrol->id.numid == OUTPUT_SEL)
 			uval->value.enumerated.item[0] =
 					scard_ops->output_dev_id;
 		else if (kcontrol->id.numid == INPUT_SEL)
 			uval->value.enumerated.item[0] =
 					scard_ops->input_dev_id;
+		else if (kcontrol->id.numid == LINEOUT_SEL_MFLD)
+			uval->value.enumerated.item[0] =
+					scard_ops->lineout_dev_id;
+		else
+			return -EINVAL;
+	} else if (intelmaddata->cpu_id == CPU_CHIP_LINCROFT) {
+		if (kcontrol->id.numid == OUTPUT_SEL)
+			/* There is a mismatch here.
+			 * ALSA expects 1 for internal speaker.
+			 * But internally, we may give 2 for internal speaker.
+			 */
+			if (scard_ops->output_dev_id == MONO_EARPIECE ||
+			    scard_ops->output_dev_id == INTERNAL_SPKR)
+				uval->value.enumerated.item[0] = MONO_EARPIECE;
+			else if (scard_ops->output_dev_id == STEREO_HEADPHONE)
+				uval->value.enumerated.item[0] =
+					STEREO_HEADPHONE;
+			else
+				return -EINVAL;
+		else if (kcontrol->id.numid == INPUT_SEL)
+			uval->value.enumerated.item[0] =
+					scard_ops->input_dev_id;
 		else
 			return -EINVAL;
 	} else
@@ -534,6 +620,11 @@
 				uval->value.enumerated.item[0]);
 		intelmaddata->input_sel = uval->value.enumerated.item[0];
 		break;
+	case LINEOUT_SEL_MFLD:
+		ret_val = scard_ops->set_lineout_dev(
+					uval->value.enumerated.item[0]);
+		intelmaddata->lineout_sel = uval->value.enumerated.item[0];
+		break;
 	default:
 		return -EINVAL;
 	}
@@ -541,6 +632,151 @@
 	return ret_val;
 }
 
+static int snd_intelmad_device_dmic_get(struct snd_kcontrol *kcontrol,
+					struct snd_ctl_elem_value *uval)
+{
+	struct snd_intelmad *intelmaddata;
+	struct snd_pmic_ops *scard_ops;
+
+	WARN_ON(!uval);
+	WARN_ON(!kcontrol);
+
+	intelmaddata = kcontrol->private_data;
+	scard_ops = intelmaddata->sstdrv_ops->scard_ops;
+
+	if (scard_ops->input_dev_id != DMIC) {
+		pr_debug("input dev = 0x%x\n", scard_ops->input_dev_id);
+		return 0;
+	}
+
+	if (intelmaddata->cpu_id == CPU_CHIP_PENWELL)
+		uval->value.enumerated.item[0] = kcontrol->private_value;
+	else
+		pr_debug(" CPU id = 0x%xis invalid.\n",
+			intelmaddata->cpu_id);
+	return 0;
+}
+
+void msic_set_bit(u8 index, unsigned int *available_dmics)
+{
+	*available_dmics |= (1 << index);
+}
+
+void msic_clear_bit(u8 index, unsigned int *available_dmics)
+{
+	*available_dmics &= ~(1 << index);
+}
+
+int msic_is_set_bit(u8 index, unsigned int *available_dmics)
+{
+	int ret_val;
+
+	ret_val = (*available_dmics & (1 << index));
+	return ret_val;
+}
+
+static int snd_intelmad_device_dmic_set(struct snd_kcontrol *kcontrol,
+					struct snd_ctl_elem_value *uval)
+{
+	struct snd_intelmad *intelmaddata;
+	struct snd_pmic_ops *scard_ops;
+	int i, dmic_index;
+	unsigned int available_dmics;
+	int jump_count;
+	int max_dmics = ARRAY_SIZE(router_dmics);
+
+	WARN_ON(!uval);
+	WARN_ON(!kcontrol);
+
+	intelmaddata = kcontrol->private_data;
+	WARN_ON(!intelmaddata->sstdrv_ops);
+
+	scard_ops = intelmaddata->sstdrv_ops->scard_ops;
+	WARN_ON(!scard_ops);
+
+	if (scard_ops->input_dev_id != DMIC) {
+		pr_debug("input dev = 0x%x\n", scard_ops->input_dev_id);
+		return 0;
+	}
+
+	available_dmics = scard_ops->available_dmics;
+
+	if (kcontrol->private_value > uval->value.enumerated.item[0]) {
+		pr_debug("jump count -1.\n");
+		jump_count = -1;
+	} else {
+		pr_debug("jump count 1.\n");
+		jump_count = 1;
+	}
+
+	dmic_index =  uval->value.enumerated.item[0];
+	pr_debug("set function. dmic_index = %d, avl_dmic = 0x%x\n",
+			 dmic_index, available_dmics);
+	for (i = 0; i < max_dmics; i++) {
+		pr_debug("set function. loop index = 0x%x.  dmic_index = 0x%x\n",
+			 i, dmic_index);
+		if (!msic_is_set_bit(dmic_index, &available_dmics)) {
+			msic_clear_bit(kcontrol->private_value,
+						&available_dmics);
+			msic_set_bit(dmic_index, &available_dmics);
+			kcontrol->private_value = dmic_index;
+			scard_ops->available_dmics = available_dmics;
+			scard_ops->hw_dmic_map[kcontrol->id.numid-HW_CH_BASE] =
+				kcontrol->private_value;
+			scard_ops->set_hw_dmic_route
+				(kcontrol->id.numid-HW_CH_BASE);
+			return 0;
+		}
+
+		dmic_index += jump_count;
+
+		if (dmic_index > (max_dmics - 1) && jump_count == 1) {
+			pr_debug("Resettingthe dmic index to 0.\n");
+			dmic_index = 0;
+		} else if (dmic_index == -1 && jump_count == -1) {
+			pr_debug("Resetting the dmic index to 5.\n");
+			dmic_index = max_dmics - 1;
+		}
+	}
+
+	return -EINVAL;
+}
+
+static int snd_intelmad_device_dmic_info_mfld(struct snd_kcontrol *kcontrol,
+					struct snd_ctl_elem_info *uinfo)
+{
+	struct snd_intelmad *intelmaddata;
+	struct snd_pmic_ops *scard_ops;
+
+	uinfo->count                  = MONO_CNTL;
+	uinfo->type                   = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
+	uinfo->value.enumerated.items = ARRAY_SIZE(router_dmics);
+
+	intelmaddata = kcontrol->private_data;
+	WARN_ON(!intelmaddata->sstdrv_ops);
+
+	scard_ops = intelmaddata->sstdrv_ops->scard_ops;
+	WARN_ON(!scard_ops);
+
+	if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
+		uinfo->value.enumerated.item =
+			uinfo->value.enumerated.items - 1;
+
+	strncpy(uinfo->value.enumerated.name,
+	router_dmics[uinfo->value.enumerated.item],
+	sizeof(uinfo->value.enumerated.name)-1);
+
+
+	msic_set_bit(kcontrol->private_value, &scard_ops->available_dmics);
+	pr_debug("info function. avl_dmic = 0x%x",
+		scard_ops->available_dmics);
+
+	scard_ops->hw_dmic_map[kcontrol->id.numid-HW_CH_BASE] =
+		kcontrol->private_value;
+
+	return 0;
+}
+
 struct snd_kcontrol_new snd_intelmad_controls_mrst[MAX_CTRL] __devinitdata = {
 {
 	.iface		=	SNDRV_CTL_ELEM_IFACE_MIXER,
@@ -598,6 +834,15 @@
 },
 {
 	.iface		=	SNDRV_CTL_ELEM_IFACE_MIXER,
+	.name		=	"Master Playback Volume",
+	.access		=	SNDRV_CTL_ELEM_ACCESS_READWRITE,
+	.info		=	snd_intelmad_master_volume_info,
+	.get		=	snd_intelmad_volume_get,
+	.put		=	snd_intelmad_volume_set,
+	.private_value	=	0,
+},
+{
+	.iface		=	SNDRV_CTL_ELEM_IFACE_MIXER,
 	.name		=	"Master Playback Switch",
 	.access		=	SNDRV_CTL_ELEM_ACCESS_READWRITE,
 	.info		=	snd_intelmad_mute_info,
@@ -627,5 +872,50 @@
 	.put		=	snd_intelmad_device_set,
 	.private_value	=	0,
 },
+{
+	.iface		=	SNDRV_CTL_ELEM_IFACE_MIXER,
+	.name		=	"Line out",
+	.access		=	SNDRV_CTL_ELEM_ACCESS_READWRITE,
+	.info		=	snd_intelmad_device_info_mfld,
+	.get		=	snd_intelmad_device_get,
+	.put		=	snd_intelmad_device_set,
+	.private_value	=	0,
+},
+{
+	.iface		=	SNDRV_CTL_ELEM_IFACE_MIXER,
+	.name		=	HW_CH_0,
+	.access		=	SNDRV_CTL_ELEM_ACCESS_READWRITE,
+	.info		=	snd_intelmad_device_dmic_info_mfld,
+	.get		=	snd_intelmad_device_dmic_get,
+	.put		=	snd_intelmad_device_dmic_set,
+	.private_value	=	0
+},
+{
+	.iface		=	SNDRV_CTL_ELEM_IFACE_MIXER,
+	.name		=	HW_CH_1,
+	.access		=	SNDRV_CTL_ELEM_ACCESS_READWRITE,
+	.info		=	snd_intelmad_device_dmic_info_mfld,
+	.get		=	snd_intelmad_device_dmic_get,
+	.put		=	snd_intelmad_device_dmic_set,
+	.private_value	=	1
+},
+{
+	.iface		=	SNDRV_CTL_ELEM_IFACE_MIXER,
+	.name		=	HW_CH_2,
+	.access		=	SNDRV_CTL_ELEM_ACCESS_READWRITE,
+	.info		=	snd_intelmad_device_dmic_info_mfld,
+	.get		=	snd_intelmad_device_dmic_get,
+	.put		=	snd_intelmad_device_dmic_set,
+	.private_value	=	2
+},
+{
+	.iface		=	SNDRV_CTL_ELEM_IFACE_MIXER,
+	.name		=	HW_CH_3,
+	.access		=	SNDRV_CTL_ELEM_ACCESS_READWRITE,
+	.info		=	snd_intelmad_device_dmic_info_mfld,
+	.get		=	snd_intelmad_device_dmic_get,
+	.put		=	snd_intelmad_device_dmic_set,
+	.private_value	=	3
+}
 };
 
diff -druN linux-2.6.39-libre/drivers/staging/intel_sst/intelmid.h linux-3.0-rc7-libre/drivers/staging/intel_sst/intelmid.h
--- linux-2.6.39-libre/drivers/staging/intel_sst/intelmid.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/intel_sst/intelmid.h	2011-07-11 19:51:52.000000000 -0400
@@ -28,6 +28,7 @@
 #define __INTELMID_H
 
 #include <linux/time.h>
+#include <sound/jack.h>
 
 #define DRIVER_NAME_MFLD "msic_audio"
 #define DRIVER_NAME_MRST "pmic_audio"
@@ -43,7 +44,7 @@
 #define MAX_BUFFER		(800*1024) /* for PCM */
 #define MIN_BUFFER		(800*1024)
 #define MAX_PERIODS		(1024*2)
-#define MIN_PERIODS		1
+#define MIN_PERIODS		2
 #define MAX_PERIOD_BYTES MAX_BUFFER
 #define MIN_PERIOD_BYTES 32
 /*#define MIN_PERIOD_BYTES 160*/
@@ -53,12 +54,12 @@
 #define STEREO_CNTL		2
 #define MIN_CHANNEL		1
 #define MAX_CHANNEL_AMIC	2
-#define MAX_CHANNEL_DMIC	4
+#define MAX_CHANNEL_DMIC	5
 #define FIFO_SIZE		0 /* fifo not being used */
 #define INTEL_MAD		"Intel MAD"
-#define MAX_CTRL_MRST		7
-#define MAX_CTRL_MFLD		2
-#define MAX_CTRL		7
+#define MAX_CTRL_MRST		8
+#define MAX_CTRL_MFLD		7
+#define MAX_CTRL		8
 #define MAX_VENDORS		4
 /* TODO +6 db */
 #define MAX_VOL		64
@@ -66,12 +67,17 @@
 #define MIN_VOL		0
 #define PLAYBACK_COUNT  1
 #define CAPTURE_COUNT	1
+#define ADC_ONE_LSB_MULTIPLIER 2346
+
+#define MID_JACK_HS_LONG_PRESS SND_JACK_BTN_0
+#define MID_JACK_HS_SHORT_PRESS SND_JACK_BTN_1
 
 extern int	sst_card_vendor_id;
 
 struct mad_jack {
 	struct snd_jack jack;
 	int jack_status;
+	int jack_dev_state;
 	struct timeval buttonpressed;
 	struct timeval  buttonreleased;
 };
@@ -83,6 +89,12 @@
 
 };
 
+struct snd_intelmad_probe_info {
+	unsigned int cpu_id;
+	unsigned int irq_cache;
+	unsigned int size;
+};
+
 /**
  * struct snd_intelmad - intelmad driver structure
  *
@@ -116,10 +128,12 @@
 	void __iomem *int_base;
 	int output_sel;
 	int input_sel;
+	int lineout_sel;
 	int master_mute;
 	struct mad_jack jack[4];
 	int playback_cnt;
 	int capture_cnt;
+	u16 adc_address;
 	struct mad_jack_msg_wq  mad_jack_msg;
 	struct workqueue_struct *mad_jack_wq;
 	u8 jack_prev_state;
@@ -131,6 +145,8 @@
 	int	playback_vol_min;
 	int	capture_vol_max;
 	int	capture_vol_min;
+	int	master_vol_max;
+	int	master_vol_min;
 };
 
 struct mad_stream_pvt {
@@ -161,8 +177,18 @@
 	PLAYBACK_MUTE,
 	CAPTURE_VOL,
 	CAPTURE_MUTE,
+	MASTER_VOL,
 	MASTER_MUTE
 };
+enum _widget_ctrl_mfld {
+	LINEOUT_SEL_MFLD = 3,
+};
+enum hw_chs {
+	HW_CH0 = 0,
+	HW_CH1,
+	HW_CH2,
+	HW_CH3
+};
 
 void period_elapsed(void *mad_substream);
 int snd_intelmad_alloc_stream(struct snd_pcm_substream *substream);
@@ -177,5 +203,7 @@
 extern struct snd_kcontrol_new snd_intelmad_controls_mrst[];
 extern struct snd_kcontrol_new snd_intelmad_controls_mfld[];
 extern struct snd_pmic_ops *intelmad_vendor_ops[];
+void sst_mad_send_jack_report(struct snd_jack *jack,
+			int buttonpressevent , int status);
 
 #endif /* __INTELMID_H */
diff -druN linux-2.6.39-libre/drivers/staging/intel_sst/intelmid_msic_control.c linux-3.0-rc7-libre/drivers/staging/intel_sst/intelmid_msic_control.c
--- linux-2.6.39-libre/drivers/staging/intel_sst/intelmid_msic_control.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/intel_sst/intelmid_msic_control.c	2011-07-11 19:51:52.000000000 -0400
@@ -28,9 +28,15 @@
 
 #include <linux/pci.h>
 #include <linux/file.h>
+#include <linux/delay.h>
+#include <sound/control.h>
 #include "intel_sst.h"
-#include "intel_sst_ioctl.h"
+#include <linux/input.h>
 #include "intelmid_snd_control.h"
+#include "intelmid.h"
+
+#define AUDIOMUX12  0x24c
+#define AUDIOMUX34  0x24d
 
 static int msic_init_card(void)
 {
@@ -54,116 +60,359 @@
 		/*TI vibra w/a settings*/
 		{0x384, 0x80, 0},
 		{0x385, 0x80, 0},
-		/*vibra settings*/
 		{0x267, 0x00, 0},
-		{0x26A, 0x10, 0},
 		{0x261, 0x00, 0},
-		{0x264, 0x10, 0},
 		/* pcm port setting */
 		{0x278, 0x00, 0},
 		{0x27B, 0x01, 0},
 		{0x27C, 0x0a, 0},
 		/* Set vol HSLRVOLCTRL, IHFVOL */
-		{0x259, 0x04, 0},
-		{0x25A, 0x04, 0},
-		{0x25B, 0x04, 0},
-		{0x25C, 0x04, 0},
+		{0x259, 0x08, 0},
+		{0x25A, 0x08, 0},
+		{0x25B, 0x08, 0},
+		{0x25C, 0x08, 0},
 		/* HSEPRXCTRL  Enable the headset left and right FIR filters  */
 		{0x250, 0x30, 0},
 		/* HSMIXER */
 		{0x256, 0x11, 0},
 		/* amic configuration */
-		{0x249, 0x09, 0x0},
-		{0x24A, 0x09, 0x0},
+		{0x249, 0x01, 0x0},
+		{0x24A, 0x01, 0x0},
 		/* unmask ocaudio/accdet interrupts */
 		{0x1d, 0x00, 0x00},
 		{0x1e, 0x00, 0x00},
 	};
 	snd_msic_ops.card_status = SND_CARD_INIT_DONE;
-	sst_sc_reg_access(sc_access, PMIC_WRITE, 30);
+	sst_sc_reg_access(sc_access, PMIC_WRITE, 28);
 	snd_msic_ops.pb_on = 0;
+	snd_msic_ops.pbhs_on = 0;
 	snd_msic_ops.cap_on = 0;
 	snd_msic_ops.input_dev_id = DMIC; /*def dev*/
 	snd_msic_ops.output_dev_id = STEREO_HEADPHONE;
+	snd_msic_ops.jack_interrupt_status = false;
 	pr_debug("msic init complete!!\n");
 	return 0;
 }
+static int msic_line_out_restore(u8 value)
+{
+	struct sc_reg_access hs_drv_en[] = {
+		{0x25d, 0x03, 0x03},
+	};
+	struct sc_reg_access ep_drv_en[] = {
+		{0x25d, 0x40, 0x40},
+	};
+	struct sc_reg_access ihf_drv_en[] = {
+		{0x25d, 0x0c, 0x0c},
+	};
+	struct sc_reg_access vib1_drv_en[] = {
+		{0x25d, 0x10, 0x10},
+	};
+	struct sc_reg_access vib2_drv_en[] = {
+		{0x25d, 0x20, 0x20},
+	};
+	struct sc_reg_access pmode_enable[] = {
+		{0x381, 0x10, 0x10},
+	};
+	int retval = 0;
+
+	pr_debug("msic_lineout_restore_lineout_dev:%d\n", value);
+
+	switch (value) {
+	case HEADSET:
+		pr_debug("Selecting Lineout-HEADSET-restore\n");
+		if (snd_msic_ops.output_dev_id == STEREO_HEADPHONE)
+			retval = sst_sc_reg_access(hs_drv_en,
+							PMIC_READ_MODIFY, 1);
+		else
+			retval = sst_sc_reg_access(ep_drv_en,
+							PMIC_READ_MODIFY, 1);
+		break;
+	case IHF:
+		pr_debug("Selecting Lineout-IHF-restore\n");
+		retval = sst_sc_reg_access(ihf_drv_en, PMIC_READ_MODIFY, 1);
+		if (retval)
+			return retval;
+		retval = sst_sc_reg_access(pmode_enable, PMIC_READ_MODIFY, 1);
+		break;
+	case VIBRA1:
+		pr_debug("Selecting Lineout-Vibra1-restore\n");
+		retval = sst_sc_reg_access(vib1_drv_en, PMIC_READ_MODIFY, 1);
+		break;
+	case VIBRA2:
+		pr_debug("Selecting Lineout-VIBRA2-restore\n");
+		retval = sst_sc_reg_access(vib2_drv_en, PMIC_READ_MODIFY, 1);
+		break;
+	case NONE:
+		pr_debug("Selecting Lineout-NONE-restore\n");
+		break;
+	default:
+		return -EINVAL;
+	}
+	return retval;
+}
+static int msic_get_lineout_prvstate(void)
+{
+	struct sc_reg_access hs_ihf_drv[2] = {
+		{0x257, 0x0, 0x0},
+		{0x25d, 0x0, 0x0},
+	};
+	struct sc_reg_access vib1drv[2] = {
+		{0x264, 0x0, 0x0},
+		{0x25D, 0x0, 0x0},
+	};
+	struct sc_reg_access vib2drv[2] = {
+		{0x26A, 0x0, 0x0},
+		{0x25D, 0x0, 0x0},
+	};
+	int retval = 0, drv_en, dac_en, dev_id, mask;
+	for (dev_id = 0; dev_id < snd_msic_ops.line_out_names_cnt; dev_id++) {
+		switch (dev_id) {
+		case HEADSET:
+			pr_debug("msic_get_lineout_prvs_state: HEADSET\n");
+			sst_sc_reg_access(hs_ihf_drv, PMIC_READ, 2);
+
+			mask = (MASK0|MASK1);
+			dac_en = (hs_ihf_drv[0].value) & mask;
+
+			mask = ((MASK0|MASK1)|MASK6);
+			drv_en = (hs_ihf_drv[1].value) & mask;
+
+			if (dac_en && (!drv_en)) {
+				snd_msic_ops.prev_lineout_dev_id = HEADSET;
+				return retval;
+			}
+			break;
+		case IHF:
+			pr_debug("msic_get_lineout_prvstate: IHF\n");
+			sst_sc_reg_access(hs_ihf_drv, PMIC_READ, 2);
+
+			mask = (MASK2 | MASK3);
+			dac_en = (hs_ihf_drv[0].value) & mask;
+
+			mask = (MASK2 | MASK3);
+			drv_en = (hs_ihf_drv[1].value) & mask;
+
+			if (dac_en && (!drv_en)) {
+				snd_msic_ops.prev_lineout_dev_id = IHF;
+				return retval;
+			}
+			break;
+		case VIBRA1:
+			pr_debug("msic_get_lineout_prvstate: vibra1\n");
+			sst_sc_reg_access(vib1drv, PMIC_READ, 2);
+
+			mask = MASK1;
+			dac_en = (vib1drv[0].value) & mask;
+
+			mask = MASK4;
+			drv_en = (vib1drv[1].value) & mask;
+
+			if (dac_en && (!drv_en)) {
+				snd_msic_ops.prev_lineout_dev_id = VIBRA1;
+				return retval;
+			}
+			break;
+		case VIBRA2:
+			pr_debug("msic_get_lineout_prvstate: vibra2\n");
+			sst_sc_reg_access(vib2drv, PMIC_READ, 2);
+
+			mask = MASK1;
+			dac_en = (vib2drv[0].value) & mask;
+
+			mask = MASK5;
+			drv_en = ((vib2drv[1].value) & mask);
+
+			if (dac_en && (!drv_en)) {
+				snd_msic_ops.prev_lineout_dev_id = VIBRA2;
+				return retval;
+			}
+			break;
+		case NONE:
+			pr_debug("msic_get_lineout_prvstate: NONE\n");
+			snd_msic_ops.prev_lineout_dev_id = NONE;
+			return retval;
+		default:
+			pr_debug("Invalid device id\n");
+			snd_msic_ops.prev_lineout_dev_id = NONE;
+			return -EINVAL;
+		}
+	}
+	return retval;
+}
+static int msic_set_selected_lineout_dev(u8 value)
+{
+	struct sc_reg_access lout_hs[] = {
+		{0x25e, 0x33, 0xFF},
+		{0x25d, 0x0, 0x43},
+	};
+	struct sc_reg_access lout_ihf[] = {
+		{0x25e, 0x55, 0xff},
+		{0x25d, 0x0, 0x0c},
+	};
+	struct sc_reg_access lout_vibra1[] = {
+
+		{0x25e, 0x61, 0xff},
+		{0x25d, 0x0, 0x10},
+	};
+	struct sc_reg_access lout_vibra2[] = {
+
+		{0x25e, 0x16, 0xff},
+		{0x25d, 0x0, 0x20},
+	};
+	struct sc_reg_access lout_def[] = {
+		{0x25e, 0x66, 0x0},
+	};
+	struct sc_reg_access pmode_disable[] = {
+		{0x381, 0x00, 0x10},
+	};
+	struct sc_reg_access pmode_enable[] = {
+		{0x381, 0x10, 0x10},
+	};
+	int retval = 0;
+
+	pr_debug("msic_set_selected_lineout_dev:%d\n", value);
+	msic_get_lineout_prvstate();
+	msic_line_out_restore(snd_msic_ops.prev_lineout_dev_id);
+	snd_msic_ops.lineout_dev_id = value;
+
+	switch (value) {
+	case HEADSET:
+		pr_debug("Selecting Lineout-HEADSET\n");
+		if (snd_msic_ops.pb_on)
+			retval = sst_sc_reg_access(lout_hs,
+					PMIC_READ_MODIFY, 2);
+			if (retval)
+				return retval;
+			retval = sst_sc_reg_access(pmode_disable,
+					PMIC_READ_MODIFY, 1);
+		break;
+	case IHF:
+		pr_debug("Selecting Lineout-IHF\n");
+		if (snd_msic_ops.pb_on)
+			retval = sst_sc_reg_access(lout_ihf,
+							PMIC_READ_MODIFY, 2);
+			if (retval)
+				return retval;
+			retval = sst_sc_reg_access(pmode_enable,
+					PMIC_READ_MODIFY, 1);
+		break;
+	case VIBRA1:
+		pr_debug("Selecting Lineout-Vibra1\n");
+		if (snd_msic_ops.pb_on)
+			retval = sst_sc_reg_access(lout_vibra1,
+							PMIC_READ_MODIFY, 2);
+			if (retval)
+				return retval;
+			retval = sst_sc_reg_access(pmode_disable,
+					PMIC_READ_MODIFY, 1);
+		break;
+	case VIBRA2:
+		pr_debug("Selecting Lineout-VIBRA2\n");
+		if (snd_msic_ops.pb_on)
+			retval = sst_sc_reg_access(lout_vibra2,
+							PMIC_READ_MODIFY, 2);
+			if (retval)
+				return retval;
+			retval = sst_sc_reg_access(pmode_disable,
+					PMIC_READ_MODIFY, 1);
+		break;
+	case NONE:
+		pr_debug("Selecting Lineout-NONE\n");
+			retval = sst_sc_reg_access(lout_def,
+							PMIC_WRITE, 1);
+			if (retval)
+				return retval;
+			retval = sst_sc_reg_access(pmode_disable,
+					PMIC_READ_MODIFY, 1);
+		break;
+	default:
+		return -EINVAL;
+	}
+	return retval;
+}
+
 
 static int msic_power_up_pb(unsigned int device)
 {
-	struct sc_reg_access sc_access1[] = {
+	struct sc_reg_access vaud[] = {
 		/* turn on the audio power supplies */
-		{0x0DB, 0x05, 0},
+		{0x0DB, 0x07, 0},
+	};
+	struct sc_reg_access pll[] = {
+		/* turn on PLL */
+		{0x240, 0x20, 0},
+	};
+	struct sc_reg_access vhs[] = {
 		/*  VHSP */
-		{0x0DC, 0xFF, 0},
+		{0x0DC, 0x3D, 0},
 		/*  VHSN */
 		{0x0DD, 0x3F, 0},
-		/* turn on PLL */
-		{0x240, 0x21, 0},
 	};
-	struct sc_reg_access sc_access2[] = {
+	struct sc_reg_access hsdac[] = {
+		{0x382, 0x40, 0x40},
 		/*  disable driver */
 		{0x25D, 0x0, 0x43},
 		/* DAC CONFIG ; both HP, LP on */
 		{0x257, 0x03, 0x03},
 	};
-	struct sc_reg_access sc_access3[] = {
+	struct sc_reg_access hs_filter[] = {
 		/* HSEPRXCTRL  Enable the headset left and right FIR filters  */
 		{0x250, 0x30, 0},
 		/* HSMIXER */
 		{0x256, 0x11, 0},
 	};
-	struct sc_reg_access sc_access4[] = {
+	struct sc_reg_access hs_enable[] = {
 		/* enable driver */
 		{0x25D, 0x3, 0x3},
+		{0x26C, 0x0, 0x2},
 		/* unmute the headset */
 		{ 0x259, 0x80, 0x80},
 		{ 0x25A, 0x80, 0x80},
 	};
-	struct sc_reg_access sc_access_vihf[] = {
+	struct sc_reg_access vihf[] = {
 		/*  VIHF ON */
-		{0x0C9, 0x2D, 0x00},
+		{0x0C9, 0x27, 0x00},
 	};
-	struct sc_reg_access sc_access22[] = {
+	struct sc_reg_access ihf_filter[] = {
 		/*  disable driver */
 		{0x25D, 0x00, 0x0C},
 		/*Filer DAC enable*/
 		{0x251, 0x03, 0x03},
 		{0x257, 0x0C, 0x0C},
 	};
-	struct sc_reg_access sc_access32[] = {
+	struct sc_reg_access ihf_en[] = {
 		/*enable drv*/
 		{0x25D, 0x0C, 0x0c},
 	};
-	struct sc_reg_access sc_access42[] = {
+	struct sc_reg_access ihf_unmute[] = {
 		/*unmute headset*/
 		{0x25B, 0x80, 0x80},
 		{0x25C, 0x80, 0x80},
 	};
-	struct sc_reg_access sc_access23[] = {
+	struct sc_reg_access epdac[] = {
 		/*  disable driver */
 		{0x25D, 0x0, 0x43},
 		/* DAC CONFIG ; both HP, LP on */
 		{0x257, 0x03, 0x03},
 	};
-	struct sc_reg_access sc_access43[] = {
+	struct sc_reg_access ep_enable[] = {
 		/* enable driver */
 		{0x25D, 0x40, 0x40},
 		/* unmute the headset */
 		{ 0x259, 0x80, 0x80},
 		{ 0x25A, 0x80, 0x80},
 	};
-	struct sc_reg_access sc_access_vib[] = {
+	struct sc_reg_access vib1_en[] = {
 		/* enable driver, ADC */
 		{0x25D, 0x10, 0x10},
-		{0x264, 0x02, 0x02},
+		{0x264, 0x02, 0x82},
 	};
-	struct sc_reg_access sc_access_hap[] = {
+	struct sc_reg_access vib2_en[] = {
 		/* enable driver, ADC */
 		{0x25D, 0x20, 0x20},
-		{0x26A, 0x02, 0x02},
+		{0x26A, 0x02, 0x82},
 	};
-	struct sc_reg_access sc_access_pcm2[] = {
+	struct sc_reg_access pcm2_en[] = {
 		/* enable pcm 2 */
 		{0x27C, 0x1, 0x1},
 	};
@@ -176,89 +425,95 @@
 	}
 
 	pr_debug("powering up pb.... Device %d\n", device);
-	sst_sc_reg_access(sc_access1, PMIC_WRITE, 4);
+	sst_sc_reg_access(vaud, PMIC_WRITE, 1);
+	msleep(1);
+	sst_sc_reg_access(pll, PMIC_WRITE, 1);
+	msleep(1);
 	switch (device) {
 	case SND_SST_DEVICE_HEADSET:
+		snd_msic_ops.pb_on = 1;
+		snd_msic_ops.pbhs_on = 1;
 		if (snd_msic_ops.output_dev_id == STEREO_HEADPHONE) {
-			sst_sc_reg_access(sc_access2, PMIC_READ_MODIFY, 2);
-			sst_sc_reg_access(sc_access3, PMIC_WRITE, 2);
-			sst_sc_reg_access(sc_access4, PMIC_READ_MODIFY, 3);
+			sst_sc_reg_access(vhs, PMIC_WRITE, 2);
+			sst_sc_reg_access(hsdac, PMIC_READ_MODIFY, 3);
+			sst_sc_reg_access(hs_filter, PMIC_WRITE, 2);
+			sst_sc_reg_access(hs_enable, PMIC_READ_MODIFY, 4);
 		} else {
-			sst_sc_reg_access(sc_access23, PMIC_READ_MODIFY, 2);
-			sst_sc_reg_access(sc_access3, PMIC_WRITE, 2);
-			sst_sc_reg_access(sc_access43, PMIC_READ_MODIFY, 3);
+			sst_sc_reg_access(epdac, PMIC_READ_MODIFY, 2);
+			sst_sc_reg_access(hs_filter, PMIC_WRITE, 2);
+			sst_sc_reg_access(ep_enable, PMIC_READ_MODIFY, 3);
 		}
-		snd_msic_ops.pb_on = 1;
+		if (snd_msic_ops.lineout_dev_id == HEADSET)
+			msic_set_selected_lineout_dev(HEADSET);
 		break;
-
 	case SND_SST_DEVICE_IHF:
-		sst_sc_reg_access(sc_access_vihf, PMIC_WRITE, 1);
-		sst_sc_reg_access(sc_access22, PMIC_READ_MODIFY, 3);
-		sst_sc_reg_access(sc_access32, PMIC_READ_MODIFY, 1);
-		sst_sc_reg_access(sc_access42, PMIC_READ_MODIFY, 2);
+		snd_msic_ops.pb_on = 1;
+		sst_sc_reg_access(vihf, PMIC_WRITE, 1);
+		sst_sc_reg_access(ihf_filter, PMIC_READ_MODIFY, 3);
+		sst_sc_reg_access(ihf_en, PMIC_READ_MODIFY, 1);
+		sst_sc_reg_access(ihf_unmute, PMIC_READ_MODIFY, 2);
+		if (snd_msic_ops.lineout_dev_id == IHF)
+			msic_set_selected_lineout_dev(IHF);
 		break;
 
 	case SND_SST_DEVICE_VIBRA:
-		sst_sc_reg_access(sc_access_vib, PMIC_READ_MODIFY, 2);
+		snd_msic_ops.pb_on = 1;
+		sst_sc_reg_access(vib1_en, PMIC_READ_MODIFY, 2);
+		if (snd_msic_ops.lineout_dev_id == VIBRA1)
+			msic_set_selected_lineout_dev(VIBRA1);
 		break;
 
 	case SND_SST_DEVICE_HAPTIC:
-		sst_sc_reg_access(sc_access_hap, PMIC_READ_MODIFY, 2);
+		snd_msic_ops.pb_on = 1;
+		sst_sc_reg_access(vib2_en, PMIC_READ_MODIFY, 2);
+		if (snd_msic_ops.lineout_dev_id == VIBRA2)
+			msic_set_selected_lineout_dev(VIBRA2);
 		break;
 
 	default:
 		pr_warn("Wrong Device %d, selected %d\n",
 			       device, snd_msic_ops.output_dev_id);
 	}
-	return sst_sc_reg_access(sc_access_pcm2, PMIC_READ_MODIFY, 1);
+	return sst_sc_reg_access(pcm2_en, PMIC_READ_MODIFY, 1);
 }
 
 static int msic_power_up_cp(unsigned int device)
 {
-	struct sc_reg_access sc_access[] = {
+	struct sc_reg_access vaud[] = {
 		/* turn on the audio power supplies */
-		{0x0DB, 0x05, 0},
-		/*  VHSP */
-		{0x0DC, 0xFF, 0},
-		/*  VHSN */
-		{0x0DD, 0x3F, 0},
+		{0x0DB, 0x07, 0},
+	};
+	struct sc_reg_access pll[] = {
 		/* turn on PLL */
-		{0x240, 0x21, 0},
-
-		/*  Turn on DMIC supply  */
-		{0x247, 0xA0, 0x0},
-		{0x240, 0x21, 0x0},
-		{0x24C, 0x10, 0x0},
-
+		{0x240, 0x20, 0},
+	};
+	struct sc_reg_access dmic_bias[] = {
+		/*  Turn on AMIC supply  */
+		{0x247, 0xA0, 0xA0},
+	};
+	struct sc_reg_access dmic[] = {
 		/* mic demux enable */
-		{0x245, 0x3F, 0x0},
-		{0x246, 0x7, 0x0},
+		{0x245, 0x3F, 0x3F},
+		{0x246, 0x07, 0x07},
 
 	};
-	struct sc_reg_access sc_access_amic[] = {
-		/* turn on the audio power supplies */
-		{0x0DB, 0x05, 0},
-		/*  VHSP */
-		{0x0DC, 0xFF, 0},
-		/*  VHSN */
-		{0x0DD, 0x3F, 0},
-		/* turn on PLL */
-		{0x240, 0x21, 0},
-		/*ADC EN*/
-		{0x248, 0x05, 0x0},
-		{0x24C, 0x76, 0x0},
-		/*MIC EN*/
-		{0x249, 0x09, 0x0},
-		{0x24A, 0x09, 0x0},
+	struct sc_reg_access amic_bias[] = {
 		/*  Turn on AMIC supply  */
-		{0x247, 0xFC, 0x0},
+		{0x247, 0xFC, 0xFC},
+	};
+	struct sc_reg_access amic[] = {
+		/*MIC EN*/
+		{0x249, 0x01, 0x01},
+		{0x24A, 0x01, 0x01},
+		/*ADC EN*/
+		{0x248, 0x05, 0x0F},
 
 	};
-	struct sc_reg_access sc_access2[] = {
+	struct sc_reg_access pcm2[] = {
 		/* enable pcm 2 */
 		{0x27C, 0x1, 0x1},
 	};
-	struct sc_reg_access sc_access3[] = {
+	struct sc_reg_access tx_on[] = {
 		/*wait for mic to stabalize before turning on audio channels*/
 		{0x24F, 0x3C, 0x0},
 	};
@@ -271,42 +526,161 @@
 	}
 
 	pr_debug("powering up cp....%d\n", snd_msic_ops.input_dev_id);
-	sst_sc_reg_access(sc_access2, PMIC_READ_MODIFY, 1);
+	sst_sc_reg_access(vaud, PMIC_WRITE, 1);
+	msleep(500);/*FIXME need optimzed value here*/
+	sst_sc_reg_access(pll, PMIC_WRITE, 1);
+	msleep(1);
 	snd_msic_ops.cap_on = 1;
-	if (snd_msic_ops.input_dev_id == AMIC)
-		sst_sc_reg_access(sc_access_amic, PMIC_WRITE, 9);
-	else
-		sst_sc_reg_access(sc_access, PMIC_WRITE, 9);
-	return sst_sc_reg_access(sc_access3, PMIC_WRITE, 1);
-
+	if (snd_msic_ops.input_dev_id == AMIC) {
+		sst_sc_reg_access(amic_bias, PMIC_READ_MODIFY, 1);
+		msleep(1);
+		sst_sc_reg_access(amic, PMIC_READ_MODIFY, 3);
+	} else {
+		sst_sc_reg_access(dmic_bias, PMIC_READ_MODIFY, 1);
+		msleep(1);
+		sst_sc_reg_access(dmic, PMIC_READ_MODIFY, 2);
+	}
+	msleep(1);
+	sst_sc_reg_access(tx_on, PMIC_WRITE, 1);
+	return sst_sc_reg_access(pcm2, PMIC_READ_MODIFY, 1);
 }
 
 static int msic_power_down(void)
 {
-	int retval = 0;
+	struct sc_reg_access power_dn[] = {
+		/*  VHSP */
+		{0x0DC, 0xC4, 0},
+		/*  VHSN */
+		{0x0DD, 0x04, 0},
+		/*  VIHF */
+		{0x0C9, 0x24, 0},
+	};
+	struct sc_reg_access pll[] = {
+		/* turn off PLL*/
+		{0x240, 0x00, 0x0},
+	};
+	struct sc_reg_access vaud[] = {
+		/* turn off VAUD*/
+		{0x0DB, 0x04, 0},
+	};
 
 	pr_debug("powering dn msic\n");
+	snd_msic_ops.pbhs_on = 0;
 	snd_msic_ops.pb_on = 0;
 	snd_msic_ops.cap_on = 0;
-	return retval;
+	sst_sc_reg_access(power_dn, PMIC_WRITE, 3);
+	msleep(1);
+	sst_sc_reg_access(pll, PMIC_WRITE, 1);
+	msleep(1);
+	sst_sc_reg_access(vaud, PMIC_WRITE, 1);
+	return 0;
 }
 
-static int msic_power_down_pb(void)
+static int msic_power_down_pb(unsigned int device)
 {
-	int retval = 0;
+	struct sc_reg_access drv_enable[] = {
+		{0x25D, 0x00, 0x00},
+	};
+	struct sc_reg_access hs_mute[] = {
+		{0x259, 0x80, 0x80},
+		{0x25A, 0x80, 0x80},
+		{0x26C, 0x02, 0x02},
+	};
+	struct sc_reg_access hs_off[] = {
+		{0x257, 0x00, 0x03},
+		{0x250, 0x00, 0x30},
+		{0x382, 0x00, 0x40},
+	};
+	struct sc_reg_access ihf_mute[] = {
+		{0x25B, 0x80, 0x80},
+		{0x25C, 0x80, 0x80},
+	};
+	struct sc_reg_access ihf_off[] = {
+		{0x257, 0x00, 0x0C},
+		{0x251, 0x00, 0x03},
+	};
+	struct sc_reg_access vib1_off[] = {
+		{0x264, 0x00, 0x82},
+	};
+	struct sc_reg_access vib2_off[] = {
+		{0x26A, 0x00, 0x82},
+	};
+	struct sc_reg_access lout_off[] = {
+		{0x25e, 0x66, 0x00},
+	};
+	struct sc_reg_access pmode_disable[] = {
+		{0x381, 0x00, 0x10},
+	};
 
-	pr_debug("powering dn pb....\n");
-	snd_msic_ops.pb_on = 0;
-	return retval;
+
+
+	pr_debug("powering dn pb for device %d\n", device);
+	switch (device) {
+	case SND_SST_DEVICE_HEADSET:
+		snd_msic_ops.pbhs_on = 0;
+		sst_sc_reg_access(hs_mute, PMIC_READ_MODIFY, 3);
+		drv_enable[0].mask = 0x43;
+		sst_sc_reg_access(drv_enable, PMIC_READ_MODIFY, 1);
+		sst_sc_reg_access(hs_off, PMIC_READ_MODIFY, 3);
+		if (snd_msic_ops.lineout_dev_id == HEADSET)
+			sst_sc_reg_access(lout_off, PMIC_WRITE, 1);
+		break;
+
+	case SND_SST_DEVICE_IHF:
+		sst_sc_reg_access(ihf_mute, PMIC_READ_MODIFY, 2);
+		drv_enable[0].mask = 0x0C;
+		sst_sc_reg_access(drv_enable, PMIC_READ_MODIFY, 1);
+		sst_sc_reg_access(ihf_off, PMIC_READ_MODIFY, 2);
+		if (snd_msic_ops.lineout_dev_id == IHF) {
+			sst_sc_reg_access(lout_off, PMIC_WRITE, 1);
+			sst_sc_reg_access(pmode_disable, PMIC_READ_MODIFY, 1);
+		}
+		break;
+
+	case SND_SST_DEVICE_VIBRA:
+		sst_sc_reg_access(vib1_off, PMIC_READ_MODIFY, 1);
+		drv_enable[0].mask = 0x10;
+		sst_sc_reg_access(drv_enable, PMIC_READ_MODIFY, 1);
+		if (snd_msic_ops.lineout_dev_id == VIBRA1)
+			sst_sc_reg_access(lout_off, PMIC_WRITE, 1);
+		break;
+
+	case SND_SST_DEVICE_HAPTIC:
+		sst_sc_reg_access(vib2_off, PMIC_READ_MODIFY, 1);
+		drv_enable[0].mask = 0x20;
+		sst_sc_reg_access(drv_enable, PMIC_READ_MODIFY, 1);
+		if (snd_msic_ops.lineout_dev_id == VIBRA2)
+			sst_sc_reg_access(lout_off, PMIC_WRITE, 1);
+		break;
+	}
+	return 0;
 }
 
-static int msic_power_down_cp(void)
+static int msic_power_down_cp(unsigned int device)
 {
-	int retval = 0;
+	struct sc_reg_access dmic[] = {
+		{0x247, 0x00, 0xA0},
+		{0x245, 0x00, 0x38},
+		{0x246, 0x00, 0x07},
+	};
+	struct sc_reg_access amic[] = {
+		{0x248, 0x00, 0x05},
+		{0x249, 0x00, 0x01},
+		{0x24A, 0x00, 0x01},
+		{0x247, 0x00, 0xA3},
+	};
+	struct sc_reg_access tx_off[] = {
+		{0x24F, 0x00, 0x3C},
+	};
 
 	pr_debug("powering dn cp....\n");
 	snd_msic_ops.cap_on = 0;
-	return retval;
+	sst_sc_reg_access(tx_off, PMIC_READ_MODIFY, 1);
+	if (snd_msic_ops.input_dev_id == DMIC)
+		sst_sc_reg_access(dmic, PMIC_READ_MODIFY, 3);
+	else
+		sst_sc_reg_access(amic, PMIC_READ_MODIFY, 4);
+	return 0;
 }
 
 static int msic_set_selected_output_dev(u8 value)
@@ -315,7 +689,7 @@
 
 	pr_debug("msic set selected output:%d\n", value);
 	snd_msic_ops.output_dev_id = value;
-	if (snd_msic_ops.pb_on)
+	if (snd_msic_ops.pbhs_on)
 		msic_power_up_pb(SND_SST_DEVICE_HEADSET);
 	return retval;
 }
@@ -352,6 +726,57 @@
 	return retval;
 }
 
+static int msic_set_hw_dmic_route(u8 hw_ch_index)
+{
+	struct sc_reg_access sc_access_router;
+	int    retval = -EINVAL;
+
+	switch (hw_ch_index) {
+	case HW_CH0:
+		sc_access_router.reg_addr = AUDIOMUX12;
+		sc_access_router.value    = snd_msic_ops.hw_dmic_map[0];
+		sc_access_router.mask     = (MASK2 | MASK1 | MASK0);
+		pr_debug("hw_ch0.  value = 0x%x\n",
+				sc_access_router.value);
+		retval = sst_sc_reg_access(&sc_access_router,
+				PMIC_READ_MODIFY, 1);
+		break;
+
+	case HW_CH1:
+		sc_access_router.reg_addr = AUDIOMUX12;
+		sc_access_router.value    = (snd_msic_ops.hw_dmic_map[1]) << 4;
+		sc_access_router.mask     = (MASK6 | MASK5 | MASK4);
+		pr_debug("### hw_ch1.  value = 0x%x\n",
+				sc_access_router.value);
+		retval = sst_sc_reg_access(&sc_access_router,
+				PMIC_READ_MODIFY, 1);
+		break;
+
+	case HW_CH2:
+		sc_access_router.reg_addr = AUDIOMUX34;
+		sc_access_router.value    = snd_msic_ops.hw_dmic_map[2];
+		sc_access_router.mask     = (MASK2 | MASK1 | MASK0);
+		pr_debug("hw_ch2.  value = 0x%x\n",
+				sc_access_router.value);
+		retval = sst_sc_reg_access(&sc_access_router,
+				PMIC_READ_MODIFY, 1);
+		break;
+
+	case HW_CH3:
+		sc_access_router.reg_addr = AUDIOMUX34;
+		sc_access_router.value    = (snd_msic_ops.hw_dmic_map[3]) << 4;
+		sc_access_router.mask     = (MASK6 | MASK5 | MASK4);
+		pr_debug("hw_ch3.  value = 0x%x\n",
+				sc_access_router.value);
+		retval = sst_sc_reg_access(&sc_access_router,
+				PMIC_READ_MODIFY, 1);
+		break;
+	}
+
+	return retval;
+}
+
+
 static int msic_set_pcm_voice_params(void)
 {
 	return 0;
@@ -392,9 +817,215 @@
 	return 0;
 }
 
+static int msic_set_headset_state(int state)
+{
+	struct sc_reg_access hs_enable[] = {
+		{0x25D, 0x03, 0x03},
+	};
+
+	if (state)
+		/*enable*/
+		sst_sc_reg_access(hs_enable, PMIC_READ_MODIFY, 1);
+	else {
+		hs_enable[0].value = 0;
+		sst_sc_reg_access(hs_enable, PMIC_READ_MODIFY, 1);
+	}
+	return 0;
+}
+
+static int msic_enable_mic_bias(void)
+{
+	struct sc_reg_access jack_interrupt_reg[] = {
+		{0x0DB, 0x07, 0x00},
+
+	};
+	struct sc_reg_access jack_bias_reg[] = {
+		{0x247, 0x0C, 0x0C},
+	};
+
+	sst_sc_reg_access(jack_interrupt_reg, PMIC_WRITE, 1);
+	sst_sc_reg_access(jack_bias_reg, PMIC_READ_MODIFY, 1);
+	return 0;
+}
+
+static int msic_disable_mic_bias(void)
+{
+	if (snd_msic_ops.jack_interrupt_status == true)
+		return 0;
+	if (!(snd_msic_ops.pb_on || snd_msic_ops.cap_on))
+		msic_power_down();
+	return 0;
+}
+
+static int msic_disable_jack_btn(void)
+{
+	struct sc_reg_access btn_disable[] = {
+		{0x26C, 0x00, 0x01}
+	};
+
+	if (!(snd_msic_ops.pb_on || snd_msic_ops.cap_on))
+		msic_power_down();
+	snd_msic_ops.jack_interrupt_status = false;
+	return sst_sc_reg_access(btn_disable, PMIC_READ_MODIFY, 1);
+}
+
+static int msic_enable_jack_btn(void)
+{
+	struct sc_reg_access btn_enable[] = {
+			{0x26b, 0x77, 0x00},
+			{0x26C, 0x01, 0x00},
+	};
+	return sst_sc_reg_access(btn_enable, PMIC_WRITE, 2);
+}
+static int msic_convert_adc_to_mvolt(unsigned int mic_bias)
+{
+	return (ADC_ONE_LSB_MULTIPLIER * mic_bias) / 1000;
+}
+int msic_get_headset_state(int mic_bias)
+{
+	struct sc_reg_access msic_hs_toggle[] = {
+		{0x070, 0x00, 0x01},
+	};
+	if (mic_bias >= 0 && mic_bias < 400) {
+
+		pr_debug("Detected Headphone!!!\n");
+		sst_sc_reg_access(msic_hs_toggle, PMIC_READ_MODIFY, 1);
+
+	} else if (mic_bias > 400 && mic_bias < 650) {
+
+		pr_debug("Detected American headset\n");
+		msic_hs_toggle[0].value = 0x01;
+		sst_sc_reg_access(msic_hs_toggle, PMIC_READ_MODIFY, 1);
+
+	} else if (mic_bias >= 650 && mic_bias < 2000) {
+
+		pr_debug("Detected Headset!!!\n");
+		sst_sc_reg_access(msic_hs_toggle, PMIC_READ_MODIFY, 1);
+		/*power on jack and btn*/
+		snd_msic_ops.jack_interrupt_status = true;
+		msic_enable_jack_btn();
+		msic_enable_mic_bias();
+		return SND_JACK_HEADSET;
+
+	} else
+		pr_debug("Detected Open Cable!!!\n");
+
+	return SND_JACK_HEADPHONE;
+}
+
+static int msic_get_mic_bias(void *arg)
+{
+	struct snd_intelmad *intelmad_drv = (struct snd_intelmad *)arg;
+	u16 adc_adr = intelmad_drv->adc_address;
+	u16 adc_val;
+	int ret;
+	struct sc_reg_access adc_ctrl3[2] = {
+			{0x1C2, 0x05, 0x0},
+	};
+
+	struct sc_reg_access audio_adc_reg1 = {0,};
+	struct sc_reg_access audio_adc_reg2 = {0,};
+
+	msic_enable_mic_bias();
+	/* Enable the msic for conversion before reading */
+	ret = sst_sc_reg_access(adc_ctrl3, PMIC_WRITE, 1);
+	if (ret)
+		return ret;
+	adc_ctrl3[0].value = 0x04;
+	/* Re-toggle the RRDATARD bit */
+	ret = sst_sc_reg_access(adc_ctrl3, PMIC_WRITE, 1);
+	if (ret)
+		return ret;
+
+	audio_adc_reg1.reg_addr = adc_adr;
+	/* Read the higher bits of data */
+	msleep(1000);
+	ret = sst_sc_reg_access(&audio_adc_reg1, PMIC_READ, 1);
+	if (ret)
+		return ret;
+	pr_debug("adc read value %x", audio_adc_reg1.value);
+
+	/* Shift bits to accomodate the lower two data bits */
+	adc_val = (audio_adc_reg1.value << 2);
+	adc_adr++;
+	audio_adc_reg2. reg_addr = adc_adr;
+	ret = sst_sc_reg_access(&audio_adc_reg2, PMIC_READ, 1);
+	if (ret)
+		return ret;
+	pr_debug("adc read value %x", audio_adc_reg2.value);
+
+	/* Adding lower two bits to the higher bits */
+	audio_adc_reg2.value &= 03;
+	adc_val += audio_adc_reg2.value;
+
+	pr_debug("ADC value 0x%x", adc_val);
+	msic_disable_mic_bias();
+	return adc_val;
+}
+
+static void msic_pmic_irq_cb(void *cb_data, u8 intsts)
+{
+	struct mad_jack *mjack = NULL;
+	unsigned int present = 0, jack_event_flag = 0, buttonpressflag = 0;
+	struct snd_intelmad *intelmaddata = cb_data;
+	int retval = 0;
+
+	pr_debug("value returned = 0x%x\n", intsts);
+
+	if (snd_msic_ops.card_status == SND_CARD_UN_INIT) {
+		retval = msic_init_card();
+		if (retval)
+			return;
+	  }
+
+	mjack = &intelmaddata->jack[0];
+	if (intsts & 0x1) {
+		pr_debug("MAD short_push detected\n");
+		present = SND_JACK_BTN_0;
+		jack_event_flag = buttonpressflag = 1;
+		mjack->jack.type = SND_JACK_BTN_0;
+		mjack->jack.key[0] = BTN_0 ;
+	}
+
+	if (intsts & 0x2) {
+		pr_debug(":MAD long_push detected\n");
+		jack_event_flag = buttonpressflag = 1;
+		mjack->jack.type = present = SND_JACK_BTN_1;
+		mjack->jack.key[1] = BTN_1;
+	}
+
+	if (intsts & 0x4) {
+		unsigned int mic_bias;
+		jack_event_flag = 1;
+		buttonpressflag = 0;
+		mic_bias = msic_get_mic_bias(intelmaddata);
+		pr_debug("mic_bias = %d\n", mic_bias);
+		mic_bias = msic_convert_adc_to_mvolt(mic_bias);
+		pr_debug("mic_bias after conversion = %d mV\n", mic_bias);
+		mjack->jack_dev_state = msic_get_headset_state(mic_bias);
+		mjack->jack.type = present = mjack->jack_dev_state;
+	}
+
+	if (intsts & 0x8) {
+		mjack->jack.type = mjack->jack_dev_state;
+		present = 0;
+		jack_event_flag = 1;
+		buttonpressflag = 0;
+		msic_disable_jack_btn();
+		msic_disable_mic_bias();
+	}
+	if (jack_event_flag)
+		sst_mad_send_jack_report(&mjack->jack,
+					buttonpressflag, present);
+}
+
+
+
 struct snd_pmic_ops snd_msic_ops = {
 	.set_input_dev	=	msic_set_selected_input_dev,
 	.set_output_dev =	msic_set_selected_output_dev,
+	.set_lineout_dev =	msic_set_selected_lineout_dev,
+	.set_hw_dmic_route =    msic_set_hw_dmic_route,
 	.set_mute	=	msic_set_mute,
 	.get_mute	=	msic_get_mute,
 	.set_vol	=	msic_set_vol,
@@ -408,5 +1039,9 @@
 	.power_up_pmic_cp =	msic_power_up_cp,
 	.power_down_pmic_pb =	msic_power_down_pb,
 	.power_down_pmic_cp =	msic_power_down_cp,
-	.power_down_pmic =	msic_power_down,
+	.power_down_pmic	=	msic_power_down,
+	.pmic_irq_cb	=	msic_pmic_irq_cb,
+	.pmic_jack_enable = msic_enable_mic_bias,
+	.pmic_get_mic_bias	= msic_get_mic_bias,
+	.pmic_set_headset_state = msic_set_headset_state,
 };
diff -druN linux-2.6.39-libre/drivers/staging/intel_sst/intelmid_pvt.c linux-3.0-rc7-libre/drivers/staging/intel_sst/intelmid_pvt.c
--- linux-2.6.39-libre/drivers/staging/intel_sst/intelmid_pvt.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/intel_sst/intelmid_pvt.c	2011-07-11 19:51:52.000000000 -0400
@@ -31,7 +31,6 @@
 #include <sound/core.h>
 #include <sound/control.h>
 #include <sound/pcm.h>
-#include "jack.h"
 #include "intel_sst.h"
 #include "intel_sst_ioctl.h"
 #include "intelmid_snd_control.h"
diff -druN linux-2.6.39-libre/drivers/staging/intel_sst/intelmid_snd_control.h linux-3.0-rc7-libre/drivers/staging/intel_sst/intelmid_snd_control.h
--- linux-2.6.39-libre/drivers/staging/intel_sst/intelmid_snd_control.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/intel_sst/intelmid_snd_control.h	2011-07-11 19:51:52.000000000 -0400
@@ -80,6 +80,13 @@
 	HS_MIC,
 	IN_UNDEFINED
 };
+enum SND_LINE_OUT_DEVICE {
+	HEADSET,
+	IHF,
+	VIBRA1,
+	VIBRA2,
+	NONE,
+};
 
 enum SND_OUTPUT_DEVICE {
 	STEREO_HEADPHONE,
@@ -104,6 +111,8 @@
 	PMIC_SND_RIGHT_SPEAKER_MUTE =		0x0015,
 	PMIC_SND_RECEIVER_VOL =			0x0016,
 	PMIC_SND_RECEIVER_MUTE =		0x0017,
+	PMIC_SND_LEFT_MASTER_VOL =		0x0018,
+	PMIC_SND_RIGHT_MASTER_VOL =		0x0019,
 /* Other controls */
 	PMIC_SND_MUTE_ALL =			0x0020,
 	PMIC_MAX_CONTROLS =			0x0020,
diff -druN linux-2.6.39-libre/drivers/staging/intel_sst/intelmid_v0_control.c linux-3.0-rc7-libre/drivers/staging/intel_sst/intelmid_v0_control.c
--- linux-2.6.39-libre/drivers/staging/intel_sst/intelmid_v0_control.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/intel_sst/intelmid_v0_control.c	2011-07-11 19:51:52.000000000 -0400
@@ -30,9 +30,10 @@
 
 #include <linux/pci.h>
 #include <linux/file.h>
+#include <sound/control.h>
 #include "intel_sst.h"
 #include "intelmid_snd_control.h"
-
+#include "intelmid.h"
 
 enum _reg_v1 {
 	VOICEPORT1 = 0x180,
@@ -64,6 +65,7 @@
 };
 
 int rev_id = 0x20;
+static bool jack_det_enabled;
 
 /****
  * fs_init_card - initialize the sound card
@@ -157,7 +159,7 @@
 	return fs_enable_audiodac(UNMUTE);
 }
 
-static int fs_power_down_pb(void)
+static int fs_power_down_pb(unsigned int device)
 {
 	struct sc_reg_access sc_access[] = {
 		{POWERCTRL1, 0x00, 0xC6},
@@ -195,7 +197,7 @@
 	return sst_sc_reg_access(sc_access, PMIC_READ_MODIFY, 2);
 }
 
-static int fs_power_down_cp(void)
+static int fs_power_down_cp(unsigned int device)
 {
 	struct sc_reg_access sc_access[] = {
 		{POWERCTRL2, 0x00, 0x03},
@@ -753,6 +755,90 @@
 	return retval;
 }
 
+static void fs_pmic_irq_enable(void *data)
+{
+	struct snd_intelmad *intelmaddata = data;
+	struct sc_reg_access sc_access[] = {
+				{0x187, 0x00, MASK7},
+				{0x188, 0x10, MASK4},
+				{0x18b, 0x10, MASK4},
+	};
+
+	struct sc_reg_access sc_access_write[] = {
+				{0x198, 0x00, 0x0},
+	};
+	pr_debug("Audio interrupt enable\n");
+	sst_sc_reg_access(sc_access, PMIC_READ_MODIFY, 3);
+	sst_sc_reg_access(sc_access_write, PMIC_WRITE, 1);
+
+	intelmaddata->jack[0].jack_status = 0;
+	/*intelmaddata->jack[1].jack_status = 0;*/
+
+	jack_det_enabled = true;
+	return;
+}
+
+static void fs_pmic_irq_cb(void *cb_data, u8 value)
+{
+	struct mad_jack *mjack = NULL;
+	struct snd_intelmad *intelmaddata = cb_data;
+	unsigned int present = 0, jack_event_flag = 0, buttonpressflag = 0;
+
+	mjack = &intelmaddata->jack[0];
+
+	if (value & 0x4) {
+		if (!jack_det_enabled)
+			fs_pmic_irq_enable(intelmaddata);
+
+		/* send headphone detect */
+		pr_debug(":MAD headphone %d\n", value & 0x4);
+		present = !(mjack->jack_status);
+		mjack->jack_status = present;
+		jack_event_flag = 1;
+		mjack->jack.type = SND_JACK_HEADPHONE;
+	}
+
+	if (value & 0x2) {
+		/* send short push */
+		pr_debug(":MAD short push %d\n", value & 0x2);
+		present = 1;
+		jack_event_flag = 1;
+		buttonpressflag = 1;
+		mjack->jack.type = MID_JACK_HS_SHORT_PRESS;
+	}
+
+	if (value & 0x1) {
+		/* send long push */
+		pr_debug(":MAD long push %d\n", value & 0x1);
+		present = 1;
+		jack_event_flag = 1;
+		buttonpressflag = 1;
+		mjack->jack.type = MID_JACK_HS_LONG_PRESS;
+	}
+
+	if (value & 0x8) {
+		if (!jack_det_enabled)
+			fs_pmic_irq_enable(intelmaddata);
+		/* send headset detect */
+		pr_debug(":MAD headset = %d\n", value & 0x8);
+		present = !(mjack->jack_status);
+		mjack->jack_status = present;
+		jack_event_flag = 1;
+		mjack->jack.type = SND_JACK_HEADSET;
+	}
+
+
+	if (jack_event_flag)
+		sst_mad_send_jack_report(&mjack->jack,
+						buttonpressflag, present);
+
+	return;
+}
+static int fs_jack_enable(void)
+{
+	return 0;
+}
+
 struct snd_pmic_ops snd_pmic_ops_fs = {
 	.set_input_dev = fs_set_selected_input_dev,
 	.set_output_dev = fs_set_selected_output_dev,
@@ -765,9 +851,16 @@
 	.set_pcm_voice_params = fs_set_pcm_voice_params,
 	.set_voice_port = fs_set_voice_port,
 	.set_audio_port = fs_set_audio_port,
-	.power_up_pmic_pb = fs_power_up_pb,
-	.power_up_pmic_cp = fs_power_up_cp,
-	.power_down_pmic_pb = fs_power_down_pb,
-	.power_down_pmic_cp = fs_power_down_cp,
-	.power_down_pmic = fs_power_down,
+	.power_up_pmic_pb =	fs_power_up_pb,
+	.power_up_pmic_cp =	fs_power_up_cp,
+	.power_down_pmic_pb =	fs_power_down_pb,
+	.power_down_pmic_cp =	fs_power_down_cp,
+	.power_down_pmic	=	fs_power_down,
+	.pmic_irq_cb	=	fs_pmic_irq_cb,
+	/*
+	 * Jack detection enabling
+	 * need be delayed till first IRQ happen.
+	 */
+	.pmic_irq_enable =	NULL,
+	.pmic_jack_enable = fs_jack_enable,
 };
diff -druN linux-2.6.39-libre/drivers/staging/intel_sst/intelmid_v1_control.c linux-3.0-rc7-libre/drivers/staging/intel_sst/intelmid_v1_control.c
--- linux-2.6.39-libre/drivers/staging/intel_sst/intelmid_v1_control.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/intel_sst/intelmid_v1_control.c	2011-07-11 19:51:52.000000000 -0400
@@ -32,7 +32,6 @@
 #include <linux/file.h>
 #include <asm/mrst.h>
 #include <sound/pcm.h>
-#include "jack.h"
 #include <sound/pcm_params.h>
 #include <sound/control.h>
 #include <sound/initval.h>
@@ -212,7 +211,7 @@
 	return mx_enable_audiodac(UNMUTE);
 }
 
-static int mx_power_down_pb(void)
+static int mx_power_down_pb(unsigned int device)
 {
 	struct sc_reg_access sc_access[3];
 	int retval = 0;
@@ -255,7 +254,7 @@
 	return sst_sc_reg_access(sc_access, PMIC_READ_MODIFY, 2);
 }
 
-static int mx_power_down_cp(void)
+static int mx_power_down_cp(unsigned int device)
 {
 	struct sc_reg_access sc_access[] = {
 		{ENABLE_OPDEV_CTRL, 0x00, MASK1|MASK0},
@@ -832,6 +831,129 @@
 	return retval;
 }
 
+static u8 mx_get_jack_status(void)
+{
+	struct sc_reg_access sc_access_read = {0,};
+
+	sc_access_read.reg_addr = 0x201;
+	sst_sc_reg_access(&sc_access_read, PMIC_READ, 1);
+	pr_debug("value returned = 0x%x\n", sc_access_read.value);
+	return sc_access_read.value;
+}
+
+static void mx_pmic_irq_enable(void *data)
+{
+	struct snd_intelmad *intelmaddata = data;
+
+	intelmaddata->jack_prev_state = 0xc0;
+	return;
+}
+
+static void mx_pmic_irq_cb(void *cb_data, u8 intsts)
+{
+	u8 jack_cur_status, jack_prev_state = 0;
+	struct mad_jack *mjack = NULL;
+	unsigned int present = 0, jack_event_flag = 0, buttonpressflag = 0;
+	time_t  timediff;
+	struct snd_intelmad *intelmaddata = cb_data;
+
+	mjack = &intelmaddata->jack[0];
+	if (intsts & 0x2) {
+		jack_cur_status = mx_get_jack_status();
+		jack_prev_state = intelmaddata->jack_prev_state;
+		if ((jack_prev_state == 0xc0) && (jack_cur_status == 0x40)) {
+			/*headset insert detected. */
+			pr_debug("MAD headset inserted\n");
+			present = 1;
+			jack_event_flag = 1;
+			mjack->jack_status = 1;
+			mjack->jack.type = SND_JACK_HEADSET;
+		}
+
+		if ((jack_prev_state == 0xc0) && (jack_cur_status == 0x00)) {
+			/* headphone insert detected. */
+			pr_debug("MAD headphone inserted\n");
+			present = 1;
+			jack_event_flag = 1;
+			mjack->jack.type = SND_JACK_HEADPHONE;
+		}
+
+		if ((jack_prev_state == 0x40) && (jack_cur_status == 0xc0)) {
+			/* headset remove detected. */
+			pr_debug("MAD headset removed\n");
+
+			present = 0;
+			jack_event_flag = 1;
+			mjack->jack_status = 0;
+			mjack->jack.type = SND_JACK_HEADSET;
+		}
+
+		if ((jack_prev_state == 0x00) && (jack_cur_status == 0xc0)) {
+			/* headphone remove detected. */
+			pr_debug("MAD headphone removed\n");
+			present = 0;
+			jack_event_flag = 1;
+			mjack->jack.type = SND_JACK_HEADPHONE;
+		}
+
+		if ((jack_prev_state == 0x40) && (jack_cur_status == 0x00)) {
+			/* button pressed */
+			do_gettimeofday(&mjack->buttonpressed);
+			pr_debug("MAD button press detected\n");
+		}
+
+		if ((jack_prev_state == 0x00) && (jack_cur_status == 0x40)) {
+			if (mjack->jack_status) {
+				/*button pressed */
+				do_gettimeofday(
+					&mjack->buttonreleased);
+				/*button pressed */
+				pr_debug("MAD Button Released detected\n");
+				timediff = mjack->buttonreleased.tv_sec -
+					mjack->buttonpressed.tv_sec;
+				buttonpressflag = 1;
+
+				if (timediff > 1) {
+					pr_debug("MAD long press dtd\n");
+					/* send headphone detect/undetect */
+					present = 1;
+					jack_event_flag = 1;
+					mjack->jack.type =
+							MID_JACK_HS_LONG_PRESS;
+				} else {
+					pr_debug("MAD short press dtd\n");
+					/* send headphone detect/undetect */
+					present = 1;
+					jack_event_flag = 1;
+					mjack->jack.type =
+						MID_JACK_HS_SHORT_PRESS;
+				}
+			} else {
+				/***workaround for maxim
+				hw issue,0x00 t 0x40 is not
+				a valid transiton for Headset insertion */
+				/*headset insert detected. */
+				pr_debug("MAD headset inserted\n");
+				present = 1;
+				jack_event_flag = 1;
+				mjack->jack_status = 1;
+				mjack->jack.type = SND_JACK_HEADSET;
+			}
+		}
+		intelmaddata->jack_prev_state  = jack_cur_status;
+		pr_debug("mx_pmic_irq_cb prv_state= 0x%x\n",
+					intelmaddata->jack_prev_state);
+	}
+
+	if (jack_event_flag)
+		sst_mad_send_jack_report(&mjack->jack,
+						buttonpressflag, present);
+}
+static int mx_jack_enable(void)
+{
+	return 0;
+}
+
 struct snd_pmic_ops snd_pmic_ops_mx = {
 	.set_input_dev = mx_set_selected_input_dev,
 	.set_output_dev = mx_set_selected_output_dev,
@@ -844,10 +966,13 @@
 	.set_pcm_voice_params = mx_set_pcm_voice_params,
 	.set_voice_port = mx_set_voice_port,
 	.set_audio_port = mx_set_audio_port,
-	.power_up_pmic_pb = mx_power_up_pb,
-	.power_up_pmic_cp = mx_power_up_cp,
-	.power_down_pmic_pb = mx_power_down_pb,
-	.power_down_pmic_cp = mx_power_down_cp,
-	.power_down_pmic =  mx_power_down,
+	.power_up_pmic_pb =	mx_power_up_pb,
+	.power_up_pmic_cp =	mx_power_up_cp,
+	.power_down_pmic_pb =	mx_power_down_pb,
+	.power_down_pmic_cp =	mx_power_down_cp,
+	.power_down_pmic =	mx_power_down,
+	.pmic_irq_cb	 =	mx_pmic_irq_cb,
+	.pmic_irq_enable =	mx_pmic_irq_enable,
+	.pmic_jack_enable =	mx_jack_enable,
 };
 
diff -druN linux-2.6.39-libre/drivers/staging/intel_sst/intelmid_v2_control.c linux-3.0-rc7-libre/drivers/staging/intel_sst/intelmid_v2_control.c
--- linux-2.6.39-libre/drivers/staging/intel_sst/intelmid_v2_control.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/intel_sst/intelmid_v2_control.c	2011-07-11 19:51:52.000000000 -0400
@@ -28,11 +28,14 @@
 
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 
+#include <linux/gpio.h>
 #include <linux/pci.h>
 #include <linux/delay.h>
 #include <linux/file.h>
+#include <sound/control.h>
 #include "intel_sst.h"
 #include "intelmid_snd_control.h"
+#include "intelmid.h"
 
 enum reg_v3 {
 	VAUDIOCNT = 0x51,
@@ -82,8 +85,15 @@
 	HPLMIXSEL = 0x12b,
 	HPRMIXSEL = 0x12c,
 	LOANTIPOP = 0x12d,
+	AUXDBNC = 0x12f,
 };
 
+static void nc_set_amp_power(int power)
+{
+	if (snd_pmic_ops_nc.gpio_amp)
+		gpio_set_value(snd_pmic_ops_nc.gpio_amp, power);
+}
+
 /****
  * nc_init_card - initialize the sound card
  *
@@ -111,18 +121,20 @@
 		{VOICEVOL, 0x0e, 0},
 		{HPLVOL, 0x06, 0},
 		{HPRVOL, 0x06, 0},
-		{MICCTRL, 0x41, 0x00},
+		{MICCTRL, 0x51, 0x00},
 		{ADCSAMPLERATE, 0x8B, 0x00},
 		{MICSELVOL, 0x5B, 0x00},
 		{LILSEL, 0x06, 0},
 		{LIRSEL, 0x46, 0},
 		{LOANTIPOP, 0x00, 0},
 		{DMICCTRL1, 0x40, 0},
+		{AUXDBNC, 0xff, 0},
 	};
 	snd_pmic_ops_nc.card_status = SND_CARD_INIT_DONE;
 	snd_pmic_ops_nc.master_mute = UNMUTE;
 	snd_pmic_ops_nc.mute_status = UNMUTE;
-	sst_sc_reg_access(sc_access, PMIC_WRITE, 26);
+	sst_sc_reg_access(sc_access, PMIC_WRITE, 27);
+	mutex_init(&snd_pmic_ops_nc.lock);
 	pr_debug("init complete!!\n");
 	return 0;
 }
@@ -169,6 +181,7 @@
 		return retval;
 	if (port == 0xFF)
 		return 0;
+	mutex_lock(&snd_pmic_ops_nc.lock);
 	nc_enable_audiodac(MUTE);
 	msleep(30);
 
@@ -209,8 +222,21 @@
 
 	msleep(30);
 
-	return nc_enable_audiodac(UNMUTE);
+	snd_pmic_ops_nc.pb_on = 1;
 
+	/*
+	 * There is a mismatch between Playback Sources and the enumerated
+	 * values of output sources.  This mismatch causes ALSA upper to send
+	 * Item 1 for Internal Speaker, but the expected enumeration is 2!  For
+	 * now, treat MONO_EARPIECE and INTERNAL_SPKR identically and power up
+	 * the needed resources
+	 */
+	if (snd_pmic_ops_nc.output_dev_id == MONO_EARPIECE ||
+	    snd_pmic_ops_nc.output_dev_id == INTERNAL_SPKR)
+		nc_set_amp_power(1);
+	nc_enable_audiodac(UNMUTE);
+	mutex_unlock(&snd_pmic_ops_nc.lock);
+	return 0;
 }
 
 static int nc_power_up_cp(unsigned int port)
@@ -270,7 +296,6 @@
 	int retval = 0;
 	struct sc_reg_access sc_access[5];
 
-
 	if (snd_pmic_ops_nc.card_status == SND_CARD_UN_INIT)
 		retval = nc_init_card();
 	if (retval)
@@ -280,6 +305,10 @@
 
 	pr_debug("powering dn nc_power_down ....\n");
 
+	if (snd_pmic_ops_nc.output_dev_id == MONO_EARPIECE ||
+	    snd_pmic_ops_nc.output_dev_id == INTERNAL_SPKR)
+		nc_set_amp_power(0);
+
 	msleep(30);
 
 	sc_access[0].reg_addr = DRVPOWERCTRL;
@@ -316,7 +345,7 @@
 	return nc_enable_audiodac(UNMUTE);
 }
 
-static int nc_power_down_pb(void)
+static int nc_power_down_pb(unsigned int device)
 {
 
 	int retval = 0;
@@ -328,7 +357,7 @@
 		return retval;
 
 	pr_debug("powering dn pb....\n");
-
+	mutex_lock(&snd_pmic_ops_nc.lock);
 	nc_enable_audiodac(MUTE);
 
 
@@ -355,12 +384,14 @@
 
 	msleep(30);
 
-	return nc_enable_audiodac(UNMUTE);
-
+	snd_pmic_ops_nc.pb_on = 0;
 
+	nc_enable_audiodac(UNMUTE);
+	mutex_unlock(&snd_pmic_ops_nc.lock);
+	return 0;
 }
 
-static int nc_power_down_cp(void)
+static int nc_power_down_cp(unsigned int device)
 {
 	struct sc_reg_access sc_access[] = {
 		{POWERCTRL1, 0x00, 0xBE},
@@ -498,11 +529,13 @@
 {
 	struct sc_reg_access sc_access_HP[] = {
 		{LMUTE, 0x02, 0x06},
-		{RMUTE, 0x02, 0x06}
+		{RMUTE, 0x02, 0x06},
+		{DRVPOWERCTRL, 0x06, 0x06},
 	};
 	struct sc_reg_access sc_access_IS[] = {
 		{LMUTE, 0x04, 0x06},
-		{RMUTE, 0x04, 0x06}
+		{RMUTE, 0x04, 0x06},
+		{DRVPOWERCTRL, 0x00, 0x06},
 	};
 	int retval = 0;
 
@@ -512,17 +545,26 @@
 	if (retval)
 		return retval;
 	pr_debug("nc set selected output:%d\n", value);
+	mutex_lock(&snd_pmic_ops_nc.lock);
 	switch (value) {
 	case STEREO_HEADPHONE:
+		if (snd_pmic_ops_nc.pb_on)
+			sst_sc_reg_access(sc_access_HP+2, PMIC_WRITE, 1);
 		retval = sst_sc_reg_access(sc_access_HP, PMIC_WRITE, 2);
+		nc_set_amp_power(0);
 		break;
+	case MONO_EARPIECE:
 	case INTERNAL_SPKR:
-		retval = sst_sc_reg_access(sc_access_IS, PMIC_WRITE, 2);
+		retval = sst_sc_reg_access(sc_access_IS, PMIC_WRITE, 3);
+		if (snd_pmic_ops_nc.pb_on)
+			nc_set_amp_power(1);
 		break;
 	default:
 		pr_err("rcvd illegal request: %d\n", value);
+		mutex_unlock(&snd_pmic_ops_nc.lock);
 		return -EINVAL;
 	}
+	mutex_unlock(&snd_pmic_ops_nc.lock);
 	return retval;
 }
 
@@ -784,9 +826,8 @@
 	case PMIC_SND_LEFT_PB_VOL:
 		pr_debug("PMIC_SND_LEFT_HP_VOL %d\n", value);
 		sc_access[0].value = -value;
-		sc_access[0].reg_addr  = AUDIOLVOL;
-		sc_access[0].mask =
-			(MASK0|MASK1|MASK2|MASK3|MASK4|MASK5|MASK6);
+		sc_access[0].reg_addr  = HPLVOL;
+		sc_access[0].mask = (MASK0|MASK1|MASK2|MASK3|MASK4);
 		entries = 1;
 		break;
 
@@ -794,15 +835,32 @@
 		pr_debug("PMIC_SND_RIGHT_HP_VOL value %d\n", value);
 		if (snd_pmic_ops_nc.num_channel == 1) {
 			sc_access[0].value = 0x04;
-		    sc_access[0].reg_addr = RMUTE;
+			sc_access[0].reg_addr = RMUTE;
 			sc_access[0].mask = MASK2;
 		} else {
+			sc_access[0].value = -value;
+			sc_access[0].reg_addr  = HPRVOL;
+			sc_access[0].mask = (MASK0|MASK1|MASK2|MASK3|MASK4);
+		}
+		entries = 1;
+		break;
+
+	case PMIC_SND_LEFT_MASTER_VOL:
+		pr_debug("PMIC_SND_LEFT_MASTER_VOL value %d\n", value);
 		sc_access[0].value = -value;
-		sc_access[0].reg_addr  = AUDIORVOL;
+		sc_access[0].reg_addr = AUDIOLVOL;
+		sc_access[0].mask =
+			(MASK0|MASK1|MASK2|MASK3|MASK4|MASK5|MASK6);
+		entries = 1;
+		break;
+
+	case PMIC_SND_RIGHT_MASTER_VOL:
+		pr_debug("PMIC_SND_RIGHT_MASTER_VOL value %d\n", value);
+		sc_access[0].value = -value;
+		sc_access[0].reg_addr = AUDIORVOL;
 		sc_access[0].mask =
 				(MASK0|MASK1|MASK2|MASK3|MASK4|MASK5|MASK6);
 		entries = 1;
-		}
 		break;
 
 	default:
@@ -831,7 +889,7 @@
 		pr_debug("Selecting AMIC\n");
 		sc_access[0].reg_addr = 0x107;
 		sc_access[0].value = 0x40;
-		sc_access[0].mask =  MASK6|MASK4|MASK3|MASK1|MASK0;
+		sc_access[0].mask =  MASK6|MASK3|MASK1|MASK0;
 		sc_access[1].reg_addr = 0x10a;
 		sc_access[1].value = 0x40;
 		sc_access[1].mask = MASK6;
@@ -846,9 +904,9 @@
 
 	case HS_MIC:
 		pr_debug("Selecting HS_MIC\n");
-		sc_access[0].reg_addr = 0x107;
-		sc_access[0].mask =  MASK6|MASK4|MASK3|MASK1|MASK0;
-		sc_access[0].value = 0x10;
+		sc_access[0].reg_addr = MICCTRL;
+		sc_access[0].mask =  MASK6|MASK3|MASK1|MASK0;
+		sc_access[0].value = 0x00;
 		sc_access[1].reg_addr = 0x109;
 		sc_access[1].mask = MASK6;
 		sc_access[1].value = 0x40;
@@ -858,13 +916,16 @@
 		sc_access[3].reg_addr = 0x105;
 		sc_access[3].value = 0x40;
 		sc_access[3].mask = MASK6;
-		num_val = 4;
+		sc_access[4].reg_addr = ADCSAMPLERATE;
+		sc_access[4].mask = MASK7|MASK6|MASK5|MASK4|MASK3;
+		sc_access[4].value = 0xc8;
+		num_val = 5;
 		break;
 
 	case DMIC:
 		pr_debug("DMIC\n");
-		sc_access[0].reg_addr = 0x107;
-		sc_access[0].mask = MASK6|MASK4|MASK3|MASK1|MASK0;
+		sc_access[0].reg_addr = MICCTRL;
+		sc_access[0].mask = MASK6|MASK3|MASK1|MASK0;
 		sc_access[0].value = 0x0B;
 		sc_access[1].reg_addr = 0x105;
 		sc_access[1].value = 0x80;
@@ -872,12 +933,12 @@
 		sc_access[2].reg_addr = 0x10a;
 		sc_access[2].value = 0x40;
 		sc_access[2].mask = MASK6;
-		sc_access[3].reg_addr = 0x109;
+		sc_access[3].reg_addr = LILSEL;
 		sc_access[3].mask = MASK6;
 		sc_access[3].value = 0x00;
-		sc_access[4].reg_addr = 0x104;
-		sc_access[4].value = 0x3C;
-		sc_access[4].mask = 0xff;
+		sc_access[4].reg_addr = ADCSAMPLERATE;
+		sc_access[4].mask =  MASK7|MASK6|MASK5|MASK4|MASK3;
+		sc_access[4].value = 0x33;
 		num_val = 5;
 		break;
 	default:
@@ -964,18 +1025,30 @@
 		mask = (MASK0|MASK1|MASK2|MASK3|MASK4|MASK5);
 		break;
 
-	case PMIC_SND_RIGHT_PB_VOL:
-		pr_debug("GET_VOLUME_PMIC_LEFT_HP_VOL\n");
+	case PMIC_SND_LEFT_MASTER_VOL:
+		pr_debug("GET_VOLUME_PMIC_LEFT_MASTER_VOL\n");
 		sc_access.reg_addr = AUDIOLVOL;
 		mask = (MASK0|MASK1|MASK2|MASK3|MASK4|MASK5|MASK6);
 		break;
 
-	case PMIC_SND_LEFT_PB_VOL:
-		pr_debug("GET_VOLUME_PMIC_RIGHT_HP_VOL\n");
+	case PMIC_SND_RIGHT_MASTER_VOL:
+		pr_debug("GET_VOLUME_PMIC_RIGHT_MASTER_VOL\n");
 		sc_access.reg_addr = AUDIORVOL;
 		mask = (MASK0|MASK1|MASK2|MASK3|MASK4|MASK5|MASK6);
 		break;
 
+	case PMIC_SND_RIGHT_PB_VOL:
+		pr_debug("GET_VOLUME_PMIC_RIGHT_HP_VOL\n");
+		sc_access.reg_addr = HPRVOL;
+		mask = (MASK0|MASK1|MASK2|MASK3|MASK4);
+		break;
+
+	case PMIC_SND_LEFT_PB_VOL:
+		pr_debug("GET_VOLUME_PMIC_LEFT_HP_VOL\n");
+		sc_access.reg_addr = HPLVOL;
+		mask = (MASK0|MASK1|MASK2|MASK3|MASK4);
+		break;
+
 	default:
 		return -EINVAL;
 
@@ -987,7 +1060,81 @@
 	return retval;
 }
 
+static void hp_automute(enum snd_jack_types type, int present)
+{
+	u8 in = DMIC;
+	u8 out = INTERNAL_SPKR;
+	if (present) {
+		if (type == SND_JACK_HEADSET)
+			in = HS_MIC;
+		out = STEREO_HEADPHONE;
+	}
+	nc_set_selected_input_dev(in);
+	nc_set_selected_output_dev(out);
+}
+
+static void nc_pmic_irq_cb(void *cb_data, u8 intsts)
+{
+	u8 value = 0;
+	struct mad_jack *mjack = NULL;
+	unsigned int present = 0, jack_event_flag = 0, buttonpressflag = 0;
+	struct snd_intelmad *intelmaddata = cb_data;
+	struct sc_reg_access sc_access_read = {0,};
+
+	sc_access_read.reg_addr = 0x132;
+	sst_sc_reg_access(&sc_access_read, PMIC_READ, 1);
+	value = (sc_access_read.value);
+	pr_debug("value returned = 0x%x\n", value);
+
+	mjack = &intelmaddata->jack[0];
+	if (intsts & 0x1) {
+		pr_debug("SST DBG:MAD headset detected\n");
+		/* send headset detect/undetect */
+		present = (value == 0x1) ? 1 : 0;
+		jack_event_flag = 1;
+		mjack->jack.type = SND_JACK_HEADSET;
+		hp_automute(SND_JACK_HEADSET, present);
+	}
+
+	if (intsts & 0x2) {
+		pr_debug(":MAD headphone detected\n");
+		/* send headphone detect/undetect */
+		present = (value == 0x2) ? 1 : 0;
+		jack_event_flag = 1;
+		mjack->jack.type = SND_JACK_HEADPHONE;
+		hp_automute(SND_JACK_HEADPHONE, present);
+	}
+
+	if (intsts & 0x4) {
+		pr_debug("MAD short push detected\n");
+		/* send short push */
+		present = 1;
+		jack_event_flag = 1;
+		buttonpressflag = 1;
+		mjack->jack.type = MID_JACK_HS_SHORT_PRESS;
+	}
+
+	if (intsts & 0x8) {
+		pr_debug(":MAD long push detected\n");
+		/* send long push */
+		present = 1;
+		jack_event_flag = 1;
+		buttonpressflag = 1;
+		mjack->jack.type = MID_JACK_HS_LONG_PRESS;
+	}
+
+	if (jack_event_flag)
+		sst_mad_send_jack_report(&mjack->jack,
+					buttonpressflag, present);
+}
+static int nc_jack_enable(void)
+{
+	return 0;
+}
+
 struct snd_pmic_ops snd_pmic_ops_nc = {
+	.input_dev_id   =       DMIC,
+	.output_dev_id  =       INTERNAL_SPKR,
 	.set_input_dev	=	nc_set_selected_input_dev,
 	.set_output_dev =	nc_set_selected_output_dev,
 	.set_mute	=	nc_set_mute,
@@ -1003,5 +1150,7 @@
 	.power_up_pmic_cp =	nc_power_up_cp,
 	.power_down_pmic_pb =	nc_power_down_pb,
 	.power_down_pmic_cp =	nc_power_down_cp,
-	.power_down_pmic =	nc_power_down,
+	.power_down_pmic	=	nc_power_down,
+	.pmic_irq_cb	=	nc_pmic_irq_cb,
+	.pmic_jack_enable =	nc_jack_enable,
 };
diff -druN linux-2.6.39-libre/drivers/staging/intel_sst/intel_sst_app_interface.c linux-3.0-rc7-libre/drivers/staging/intel_sst/intel_sst_app_interface.c
--- linux-2.6.39-libre/drivers/staging/intel_sst/intel_sst_app_interface.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/intel_sst/intel_sst_app_interface.c	2011-07-11 19:51:52.000000000 -0400
@@ -418,10 +418,6 @@
 	static int sent_offset;
 	static unsigned long sent_index;
 
-	stream_bufs = kzalloc(sizeof(*stream_bufs), GFP_KERNEL);
-	if (!stream_bufs)
-		return -ENOMEM;
-	stream_bufs->addr = sst_drv_ctx->mmap_mem;
 #ifdef CONFIG_MRST_RAR_HANDLER
 	if (stream->ops == STREAM_OPS_PLAYBACK_DRM) {
 		for (index = stream->sg_index; index < nr_segs; index++) {
@@ -448,6 +444,10 @@
 		return retval;
 	}
 #endif
+	stream_bufs = kzalloc(sizeof(*stream_bufs), GFP_KERNEL);
+	if (!stream_bufs)
+		return -ENOMEM;
+	stream_bufs->addr = sst_drv_ctx->mmap_mem;
 	mmap_len = sst_drv_ctx->mmap_len;
 	stream_bufs->addr = sst_drv_ctx->mmap_mem;
 	bufp = stream->cur_ptr;
@@ -961,6 +961,34 @@
 	return retval;
 }
 
+
+int sst_ioctl_tuning_params(unsigned long arg)
+{
+	struct snd_sst_tuning_params params;
+	struct ipc_post *msg;
+
+	if (copy_from_user(&params, (void __user *)arg, sizeof(params)))
+		return -EFAULT;
+	if (params.size > SST_MAILBOX_SIZE)
+		return -ENOMEM;
+	pr_debug("Parameter %d, Stream %d, Size %d\n", params.type,
+			params.str_id, params.size);
+	if (sst_create_large_msg(&msg))
+		return -ENOMEM;
+
+	sst_fill_header(&msg->header, IPC_IA_TUNING_PARAMS, 1, params.str_id);
+	msg->header.part.data = sizeof(u32) + sizeof(params) + params.size;
+	memcpy(msg->mailbox_data, &msg->header.full, sizeof(u32));
+	memcpy(msg->mailbox_data + sizeof(u32), &params, sizeof(params));
+	if (copy_from_user(msg->mailbox_data + sizeof(params),
+			(void __user *)(unsigned long)params.addr,
+			params.size)) {
+		kfree(msg->mailbox_data);
+		kfree(msg);
+		return -EFAULT;
+	}
+	return sst_send_algo_ipc(&msg);
+}
 /**
  * intel_sst_ioctl - receives the device ioctl's
  * @file_ptr:pointer to file
@@ -1412,6 +1440,15 @@
 		}
 		retval = intel_sst_ioctl_dsp(cmd, arg);
 		break;
+
+	case _IOC_NR(SNDRV_SST_TUNING_PARAMS):
+		if (minor != AM_MODULE) {
+			retval = -EBADRQC;
+			break;
+		}
+		retval = sst_ioctl_tuning_params(arg);
+		break;
+
 	default:
 		retval = -EINVAL;
 	}
diff -druN linux-2.6.39-libre/drivers/staging/intel_sst/intel_sst.c linux-3.0-rc7-libre/drivers/staging/intel_sst/intel_sst.c
--- linux-2.6.39-libre/drivers/staging/intel_sst/intel_sst.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/intel_sst/intel_sst.c	2011-07-11 19:51:52.000000000 -0400
@@ -107,6 +107,9 @@
 	unsigned int size = 0, str_id;
 	struct stream_info *stream ;
 
+	/* Do not handle interrupt in suspended state */
+	if (drv->sst_state == SST_SUSPENDED)
+		return IRQ_NONE;
 	/* Interrupt arrived, check src */
 	isr.full = sst_shim_read(drv->shim, SST_ISRX);
 
@@ -316,14 +319,30 @@
 	if (sst_drv_ctx->pci_id == SST_MRST_PCI_ID) {
 		ret = misc_register(&lpe_dev);
 		if (ret) {
- 			pr_err("couldn't register misc driver\n");
+			pr_err("couldn't register LPE device\n");
 			goto do_free_misc;
  		}
+	} else if (sst_drv_ctx->pci_id == SST_MFLD_PCI_ID) {
+		u32 csr;
+
+		/*allocate mem for fw context save during suspend*/
+		sst_drv_ctx->fw_cntx = kzalloc(FW_CONTEXT_MEM, GFP_KERNEL);
+		if (!sst_drv_ctx->fw_cntx) {
+			ret = -ENOMEM;
+			goto do_free_misc;
+		}
+		/*setting zero as that is valid mem to restore*/
+		sst_drv_ctx->fw_cntx_size = 0;
+
+		/*set lpe start clock and ram size*/
+		csr = sst_shim_read(sst_drv_ctx->shim, SST_CSR);
+		csr |= 0x30060; /*remove the clock ratio after fw fix*/
+		sst_shim_write(sst_drv_ctx->shim, SST_CSR, csr);
 	}
 	sst_drv_ctx->lpe_stalled = 0;
-	pm_runtime_set_active(&pci->dev);
-	pm_runtime_enable(&pci->dev);
+	pci_set_drvdata(pci, sst_drv_ctx);
 	pm_runtime_allow(&pci->dev);
+	pm_runtime_put_noidle(&pci->dev);
 	pr_debug("...successfully done!!!\n");
 	return ret;
 
@@ -355,7 +374,8 @@
 	destroy_workqueue(sst_drv_ctx->mad_wq);
 do_free_drv_ctx:
 	kfree(sst_drv_ctx);
-	pr_err("Probe failed with 0x%x\n", ret);
+	sst_drv_ctx = NULL;
+	pr_err("Probe failed with %d\n", ret);
 	return ret;
 }
 
@@ -369,35 +389,76 @@
 */
 static void __devexit intel_sst_remove(struct pci_dev *pci)
 {
+	pm_runtime_get_noresume(&pci->dev);
+	pm_runtime_forbid(&pci->dev);
 	pci_dev_put(sst_drv_ctx->pci);
 	mutex_lock(&sst_drv_ctx->sst_lock);
 	sst_drv_ctx->sst_state = SST_UN_INIT;
 	mutex_unlock(&sst_drv_ctx->sst_lock);
 	misc_deregister(&lpe_ctrl);
-	if (sst_drv_ctx->pci_id == SST_MRST_PCI_ID)
-		misc_deregister(&lpe_dev);
 	free_irq(pci->irq, sst_drv_ctx);
 	iounmap(sst_drv_ctx->dram);
 	iounmap(sst_drv_ctx->iram);
 	iounmap(sst_drv_ctx->mailbox);
 	iounmap(sst_drv_ctx->shim);
 	sst_drv_ctx->pmic_state = SND_MAD_UN_INIT;
-	if (sst_drv_ctx->pci_id == SST_MRST_PCI_ID)
+	if (sst_drv_ctx->pci_id == SST_MRST_PCI_ID) {
+		misc_deregister(&lpe_dev);
 		kfree(sst_drv_ctx->mmap_mem);
+	} else
+		kfree(sst_drv_ctx->fw_cntx);
 	flush_scheduled_work();
 	destroy_workqueue(sst_drv_ctx->process_reply_wq);
 	destroy_workqueue(sst_drv_ctx->process_msg_wq);
 	destroy_workqueue(sst_drv_ctx->post_msg_wq);
 	destroy_workqueue(sst_drv_ctx->mad_wq);
-	kfree(sst_drv_ctx);
-	pci_release_region(pci, 1);
-	pci_release_region(pci, 2);
-	pci_release_region(pci, 3);
-	pci_release_region(pci, 4);
-	pci_release_region(pci, 5);
+	kfree(pci_get_drvdata(pci));
+	sst_drv_ctx = NULL;
+	pci_release_regions(pci);
+	pci_disable_device(pci);
 	pci_set_drvdata(pci, NULL);
 }
 
+void sst_save_dsp_context(void)
+{
+	struct snd_sst_ctxt_params fw_context;
+	unsigned int pvt_id, i;
+	struct ipc_post *msg = NULL;
+
+	/*check cpu type*/
+	if (sst_drv_ctx->pci_id != SST_MFLD_PCI_ID)
+		return;
+		/*not supported for rest*/
+	if (sst_drv_ctx->sst_state != SST_FW_RUNNING) {
+		pr_debug("fw not running no context save ...\n");
+		return;
+	}
+
+	/*send msg to fw*/
+	if (sst_create_large_msg(&msg))
+		return;
+	pvt_id = sst_assign_pvt_id(sst_drv_ctx);
+	i = sst_get_block_stream(sst_drv_ctx);
+	sst_drv_ctx->alloc_block[i].sst_id = pvt_id;
+	sst_fill_header(&msg->header, IPC_IA_GET_FW_CTXT, 1, pvt_id);
+	msg->header.part.data = sizeof(fw_context) + sizeof(u32);
+	fw_context.address = virt_to_phys((void *)sst_drv_ctx->fw_cntx);
+	fw_context.size = FW_CONTEXT_MEM;
+	memcpy(msg->mailbox_data, &msg->header, sizeof(u32));
+	memcpy(msg->mailbox_data + sizeof(u32),
+				&fw_context, sizeof(fw_context));
+	spin_lock(&sst_drv_ctx->list_spin_lock);
+	list_add_tail(&msg->node, &sst_drv_ctx->ipc_dispatch_list);
+	spin_unlock(&sst_drv_ctx->list_spin_lock);
+	sst_post_message(&sst_drv_ctx->ipc_post_msg_wq);
+	/*wait for reply*/
+	if (sst_wait_timeout(sst_drv_ctx, &sst_drv_ctx->alloc_block[i]))
+		pr_debug("err fw context save timeout  ...\n");
+	sst_drv_ctx->alloc_block[i].sst_id = BLOCK_UNINIT;
+	pr_debug("fw context saved  ...\n");
+	return;
+}
+
 /* Power Management */
 /*
 * intel_sst_suspend - PCI suspend function
@@ -417,6 +478,8 @@
 		pr_err("active streams,not able to suspend\n");
 		return -EBUSY;
 	}
+	/*save fw context*/
+	sst_save_dsp_context();
 	/*Assert RESET on LPE Processor*/
 	csr.full = sst_shim_read(sst_drv_ctx->shim, SST_CSR);
 	csr.full = csr.full | 0x2;
@@ -461,18 +524,45 @@
 	return 0;
 }
 
+/* The runtime_suspend/resume is pretty much similar to the legacy suspend/resume with the noted exception below:
+ * The PCI core takes care of taking the system through D3hot and restoring it back to D0 and so there is
+ * no need to duplicate that here.
+ */
 static int intel_sst_runtime_suspend(struct device *dev)
 {
-	struct pci_dev *pci_dev = to_pci_dev(dev);
-	pr_debug("runtime_suspend called\n");
-	return intel_sst_suspend(pci_dev, PMSG_SUSPEND);
+	union config_status_reg csr;
+
+	pr_debug("intel_sst_runtime_suspend called\n");
+	if (sst_drv_ctx->stream_cnt) {
+		pr_err("active streams,not able to suspend\n");
+		return -EBUSY;
+	}
+	/*save fw context*/
+	sst_save_dsp_context();
+	/*Assert RESET on LPE Processor*/
+	csr.full = sst_shim_read(sst_drv_ctx->shim, SST_CSR);
+	csr.full = csr.full | 0x2;
+	/* Move the SST state to Suspended */
+	mutex_lock(&sst_drv_ctx->sst_lock);
+	sst_drv_ctx->sst_state = SST_SUSPENDED;
+	sst_shim_write(sst_drv_ctx->shim, SST_CSR, csr.full);
+	mutex_unlock(&sst_drv_ctx->sst_lock);
+	return 0;
 }
 
 static int intel_sst_runtime_resume(struct device *dev)
 {
-	struct pci_dev *pci_dev = to_pci_dev(dev);
-	pr_debug("runtime_resume called\n");
-	return intel_sst_resume(pci_dev);
+
+	pr_debug("intel_sst_runtime_resume called\n");
+	if (sst_drv_ctx->sst_state != SST_SUSPENDED) {
+		pr_err("SST is not in suspended state\n");
+		return 0;
+	}
+
+	mutex_lock(&sst_drv_ctx->sst_lock);
+	sst_drv_ctx->sst_state = SST_UN_INIT;
+	mutex_unlock(&sst_drv_ctx->sst_lock);
+	return 0;
 }
 
 static int intel_sst_runtime_idle(struct device *dev)
@@ -545,6 +635,7 @@
 	pci_unregister_driver(&driver);
 
 	pr_debug("driver unloaded\n");
+	sst_drv_ctx = NULL;
 	return;
 }
 
diff -druN linux-2.6.39-libre/drivers/staging/intel_sst/intel_sst_common.h linux-3.0-rc7-libre/drivers/staging/intel_sst/intel_sst_common.h
--- linux-2.6.39-libre/drivers/staging/intel_sst/intel_sst_common.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/intel_sst/intel_sst_common.h	2011-07-11 19:51:52.000000000 -0400
@@ -28,8 +28,8 @@
  *  Common private declarations for SST
  */
 
-#define SST_DRIVER_VERSION "1.2.09"
-#define SST_VERSION_NUM 0x1209
+#define SST_DRIVER_VERSION "1.2.17"
+#define SST_VERSION_NUM 0x1217
 
 /* driver names */
 #define SST_DRV_NAME "intel_sst_driver"
@@ -37,6 +37,7 @@
 #define SST_MFLD_PCI_ID 0x082F
 #define PCI_ID_LENGTH 4
 #define SST_SUSPEND_DELAY 2000
+#define FW_CONTEXT_MEM (64*1024)
 
 enum sst_states {
 	SST_FW_LOADED = 1,
@@ -94,7 +95,7 @@
 /* SST shim registers to structure mapping  */
 union config_status_reg {
 	struct {
-		u32 rsvd0:1;
+		u32 mfld_strb:1;
 		u32 sst_reset:1;
 		u32 hw_rsvd:3;
 		u32 sst_clk:2;
@@ -417,6 +418,8 @@
 	unsigned int		audio_start;
 	dev_t			devt_d, devt_c;
 	unsigned int		max_streams;
+	unsigned int		*fw_cntx;
+	unsigned int		fw_cntx_size;
 };
 
 extern struct intel_sst_drv *sst_drv_ctx;
diff -druN linux-2.6.39-libre/drivers/staging/intel_sst/intel_sst_drv_interface.c linux-3.0-rc7-libre/drivers/staging/intel_sst/intel_sst_drv_interface.c
--- linux-2.6.39-libre/drivers/staging/intel_sst/intel_sst_drv_interface.c	2011-05-19 02:19:03.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/intel_sst/intel_sst_drv_interface.c	2011-07-21 07:01:11.000000000 -0400
@@ -104,21 +104,28 @@
 	if (!sst_validate_strid(str_id)) {
 		/* str_id is valid, so stream is alloacted */
 		stream = &sst_drv_ctx->streams[str_id];
+		if (sst_free_stream(str_id))
+			sst_clean_stream(&sst_drv_ctx->streams[str_id]);
 		if (stream->ops == STREAM_OPS_PLAYBACK ||
 				stream->ops == STREAM_OPS_PLAYBACK_DRM) {
 			sst_drv_ctx->pb_streams--;
-			if (sst_drv_ctx->pb_streams == 0)
-				sst_drv_ctx->scard_ops->power_down_pmic_pb();
+			if (sst_drv_ctx->pci_id == SST_MFLD_PCI_ID)
+				sst_drv_ctx->scard_ops->power_down_pmic_pb(
+						stream->device);
+			else {
+				if (sst_drv_ctx->pb_streams == 0)
+					sst_drv_ctx->scard_ops->
+					power_down_pmic_pb(stream->device);
+			}
 		} else if (stream->ops == STREAM_OPS_CAPTURE) {
 			sst_drv_ctx->cp_streams--;
 			if (sst_drv_ctx->cp_streams == 0)
-				sst_drv_ctx->scard_ops->power_down_pmic_cp();
+				sst_drv_ctx->scard_ops->power_down_pmic_cp(
+						stream->device);
 		}
 		if (sst_drv_ctx->pb_streams == 0
 				&& sst_drv_ctx->cp_streams == 0)
 			sst_drv_ctx->scard_ops->power_down_pmic();
-		if (sst_free_stream(str_id))
-			sst_clean_stream(&sst_drv_ctx->streams[str_id]);
 	}
 }
 
@@ -275,8 +282,8 @@
 		retval = sst_resume_stream(mad_ops->stream_id);
 		break;
 	case SST_SND_DROP:
-/*		retval = sst_drop_stream(mad_ops->stream_id);
-*/		break;
+		retval = sst_drop_stream(mad_ops->stream_id);
+		break;
 	case SST_SND_START:
 			pr_debug("SST Debug: start stream\n");
 		retval = sst_start_stream(mad_ops->stream_id);
@@ -507,7 +514,6 @@
 			sst_drv_ctx->pmic_state = SND_MAD_INIT_DONE;
 			sst_drv_ctx->rx_time_slot_status = 0; /*default AMIC*/
 			card->pcm_control = sst_pmic_ops.pcm_control;
-			sst_drv_ctx->scard_ops->card_status = SND_CARD_UN_INIT;
 			return 0;
 		} else {
 			pr_err("strcmp fail %s\n", card->module_name);
@@ -519,6 +525,9 @@
 		pr_err("Repeat for registration..denied\n");
 		return -EBADRQC;
 	}
+	/* The ASoC code doesn't set scard_ops */
+	if (sst_drv_ctx->scard_ops)
+		sst_drv_ctx->scard_ops->card_status = SND_CARD_UN_INIT;
 	return 0;
 }
 EXPORT_SYMBOL_GPL(register_sst_card);
diff -druN linux-2.6.39-libre/drivers/staging/intel_sst/intel_sst_dsp.c linux-3.0-rc7-libre/drivers/staging/intel_sst/intel_sst_dsp.c
--- linux-2.6.39-libre/drivers/staging/intel_sst/intel_sst_dsp.c	2011-05-19 02:19:03.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/intel_sst/intel_sst_dsp.c	2011-07-21 07:01:11.000000000 -0400
@@ -73,7 +73,8 @@
 	union config_status_reg csr;
 
 	pr_debug("Resetting the DSP in medfield\n");
-	csr.full = 0x048303E2;
+	csr.full = sst_shim_read(sst_drv_ctx->shim, SST_CSR);
+	csr.full |= 0x382;
 	sst_shim_write(sst_drv_ctx->shim, SST_CSR, csr.full);
 
 	return 0;
@@ -109,11 +110,16 @@
 {
 	union config_status_reg csr;
 
-	csr.full = 0x04830062;
+	csr.full = sst_shim_read(sst_drv_ctx->shim, SST_CSR);
+	csr.part.bypass = 0;
 	sst_shim_write(sst_drv_ctx->shim, SST_CSR, csr.full);
-	csr.full = 0x04830063;
+	csr.full = sst_shim_read(sst_drv_ctx->shim, SST_CSR);
+	csr.part.mfld_strb = 1;
 	sst_shim_write(sst_drv_ctx->shim, SST_CSR, csr.full);
-	csr.full = 0x04830061;
+	csr.full = sst_shim_read(sst_drv_ctx->shim, SST_CSR);
+	csr.part.run_stall = 0;
+	csr.part.sst_reset = 0;
+	pr_debug("Starting the DSP_medfld %x\n", csr.full);
 	sst_shim_write(sst_drv_ctx->shim, SST_CSR, csr.full);
 	pr_debug("Starting the DSP_medfld\n");
 
diff -druN linux-2.6.39-libre/drivers/staging/intel_sst/intel_sst_fw_ipc.h linux-3.0-rc7-libre/drivers/staging/intel_sst/intel_sst_fw_ipc.h
--- linux-2.6.39-libre/drivers/staging/intel_sst/intel_sst_fw_ipc.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/intel_sst/intel_sst_fw_ipc.h	2011-07-11 19:51:52.000000000 -0400
@@ -56,6 +56,8 @@
 #define IPC_IA_GET_FW_VERSION 0x04
 #define IPC_IA_GET_FW_BUILD_INF 0x05
 #define IPC_IA_GET_FW_INFO 0x06
+#define IPC_IA_GET_FW_CTXT 0x07
+#define IPC_IA_SET_FW_CTXT 0x08
 
 /* I2L Codec Config/control msgs */
 #define IPC_IA_SET_CODEC_PARAMS 0x10
@@ -69,6 +71,7 @@
 #define IPC_IA_DECODE_FRAMES 0x18
 
 #define IPC_IA_ALG_PARAMS 0x1A
+#define IPC_IA_TUNING_PARAMS 0x1B
 
 /* I2L Stream config/control msgs */
 #define IPC_IA_ALLOC_STREAM 0x20 /* Allocate a stream ID */
@@ -406,4 +409,8 @@
 	char *mailbox_data;
 };
 
+struct snd_sst_ctxt_params {
+	u32 address; /* Physical Address in DDR where the context is stored */
+	u32 size; /* size of the context */
+};
 #endif /* __INTEL_SST_FW_IPC_H__ */
diff -druN linux-2.6.39-libre/drivers/staging/intel_sst/intel_sst.h linux-3.0-rc7-libre/drivers/staging/intel_sst/intel_sst.h
--- linux-2.6.39-libre/drivers/staging/intel_sst/intel_sst.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/intel_sst/intel_sst.h	2011-07-11 19:51:52.000000000 -0400
@@ -30,9 +30,11 @@
  *  This file is shared between the SST and MAD drivers
  */
 #include "intel_sst_ioctl.h"
+#include <sound/jack.h>
 
 #define SST_CARD_NAMES "intel_mid_card"
 
+#define MFLD_MAX_HW_CH 4
 /* control list Pmic & Lpe */
 /* Input controls */
 enum port_status {
@@ -82,12 +84,16 @@
 	int num_channel;
 	int input_dev_id;
 	int mute_status;
-	int pb_on;
+	struct mutex lock;
+	int pb_on, pbhs_on;
 	int cap_on;
 	int output_dev_id;
+	int lineout_dev_id, line_out_names_cnt;
+	int prev_lineout_dev_id;
+	bool jack_interrupt_status;
 	int (*set_input_dev) (u8 value);
 	int (*set_output_dev) (u8 value);
-
+	int (*set_lineout_dev) (u8 value);
 	int (*set_mute) (int dev_id, u8 value);
 	int (*get_mute) (int dev_id, u8 *value);
 
@@ -103,11 +109,30 @@
 
 	int (*power_up_pmic_pb) (unsigned int port);
 	int (*power_up_pmic_cp) (unsigned int port);
-	int (*power_down_pmic_pb) (void);
-	int (*power_down_pmic_cp) (void);
+	int (*power_down_pmic_pb) (unsigned int device);
+	int (*power_down_pmic_cp) (unsigned int device);
 	int (*power_down_pmic) (void);
+	void (*pmic_irq_cb) (void *cb_data, u8 value);
+	void (*pmic_irq_enable)(void *data);
+	int (*pmic_jack_enable) (void);
+	int (*pmic_get_mic_bias)(void *intelmaddata);
+	int (*pmic_set_headset_state)(int state);
+
+	unsigned int hw_dmic_map[MFLD_MAX_HW_CH];
+	unsigned int available_dmics;
+	int (*set_hw_dmic_route) (u8 index);
+
+	int gpio_amp;
 };
 
+extern void sst_mad_send_jack_report(struct snd_jack *jack,
+				     int buttonpressevent,
+				     int status);
+
+
+int intemad_set_headset_state(int state);
+int intelmad_get_mic_bias(void);
+
 struct intel_sst_pcm_control {
 	int (*open) (struct snd_sst_params *str_param);
 	int (*device_control) (int cmd, void *arg);
diff -druN linux-2.6.39-libre/drivers/staging/intel_sst/intel_sst_ioctl.h linux-3.0-rc7-libre/drivers/staging/intel_sst/intel_sst_ioctl.h
--- linux-2.6.39-libre/drivers/staging/intel_sst/intel_sst_ioctl.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/intel_sst/intel_sst_ioctl.h	2011-07-11 19:51:52.000000000 -0400
@@ -400,6 +400,13 @@
 	struct snd_sst_buffs *obufs;
 };
 
+struct snd_sst_tuning_params {
+	__u8 type;
+	__u8 str_id;
+	__u8 size;
+	__u8 rsvd;
+	__aligned_u64 addr;
+} __attribute__ ((packed));
 /*IOCTL defined here */
 /*SST MMF IOCTLS only */
 #define SNDRV_SST_STREAM_SET_PARAMS _IOR('L', 0x00, \
@@ -428,5 +435,6 @@
 /*DSP Ioctls on /dev/intel_sst_ctrl only*/
 #define SNDRV_SST_SET_ALGO	_IOW('L', 0x30,  struct snd_ppp_params *)
 #define SNDRV_SST_GET_ALGO	_IOWR('L', 0x31,  struct snd_ppp_params *)
+#define SNDRV_SST_TUNING_PARAMS	_IOW('L', 0x32,  struct snd_sst_tuning_params *)
 
 #endif /* __INTEL_SST_IOCTL_H__ */
diff -druN linux-2.6.39-libre/drivers/staging/intel_sst/intel_sst_ipc.c linux-3.0-rc7-libre/drivers/staging/intel_sst/intel_sst_ipc.c
--- linux-2.6.39-libre/drivers/staging/intel_sst/intel_sst_ipc.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/intel_sst/intel_sst_ipc.c	2011-07-11 19:51:52.000000000 -0400
@@ -154,6 +154,37 @@
 	sst_shim_write(sst_drv_ctx->shim, SST_IMRX, imr.full);
 }
 
+void sst_restore_fw_context(void)
+{
+	struct snd_sst_ctxt_params fw_context;
+	struct ipc_post *msg = NULL;
+
+	pr_debug("restore_fw_context\n");
+	/*check cpu type*/
+	if (sst_drv_ctx->pci_id != SST_MFLD_PCI_ID)
+		return;
+		/*not supported for rest*/
+	if (!sst_drv_ctx->fw_cntx_size)
+		return;
+		/*nothing to restore*/
+	pr_debug("restoring context......\n");
+	/*send msg to fw*/
+	if (sst_create_large_msg(&msg))
+		return;
+
+	sst_fill_header(&msg->header, IPC_IA_SET_FW_CTXT, 1, 0);
+	msg->header.part.data = sizeof(fw_context) + sizeof(u32);
+	fw_context.address = virt_to_phys((void *)sst_drv_ctx->fw_cntx);
+	fw_context.size = sst_drv_ctx->fw_cntx_size;
+	memcpy(msg->mailbox_data, &msg->header, sizeof(u32));
+	memcpy(msg->mailbox_data + sizeof(u32),
+				&fw_context, sizeof(fw_context));
+	spin_lock(&sst_drv_ctx->list_spin_lock);
+	list_add_tail(&msg->node, &sst_drv_ctx->ipc_dispatch_list);
+	spin_unlock(&sst_drv_ctx->list_spin_lock);
+	sst_post_message(&sst_drv_ctx->ipc_post_msg_wq);
+	return;
+}
 /*
  * process_fw_init - process the FW init msg
  *
@@ -184,13 +215,13 @@
 	sst_drv_ctx->sst_state = SST_FW_RUNNING;
 	sst_drv_ctx->lpe_stalled = 0;
 	mutex_unlock(&sst_drv_ctx->sst_lock);
-	pr_debug("FW Version %x.%x\n",
-			init->fw_version.major, init->fw_version.minor);
-	pr_debug("Build No %x Type %x\n",
-			init->fw_version.build, init->fw_version.type);
+	pr_debug("FW Version %02x.%02x.%02x\n", init->fw_version.major,
+			init->fw_version.minor, init->fw_version.build);
+	pr_debug("Build Type %x\n", init->fw_version.type);
 	pr_debug(" Build date %s Time %s\n",
 			init->build_info.date, init->build_info.time);
 	sst_wake_up_alloc_block(sst_drv_ctx, FW_DWNL_ID, retval, NULL);
+	sst_restore_fw_context();
 	return retval;
 }
 /**
@@ -385,6 +416,24 @@
 		}
 		break;
 	}
+
+	case IPC_IA_TUNING_PARAMS: {
+		pr_debug("sst:IPC_TUNING_PARAMS resp: %x\n", msg->header.full);
+		pr_debug("data value %x\n", msg->header.part.data);
+		if (msg->header.part.large) {
+			pr_debug("alg set failed\n");
+			sst_drv_ctx->ppp_params_blk.ret_code =
+							-msg->header.part.data;
+		} else {
+			pr_debug("alg set success\n");
+			sst_drv_ctx->ppp_params_blk.ret_code = 0;
+		}
+		if (sst_drv_ctx->ppp_params_blk.on == true) {
+			sst_drv_ctx->ppp_params_blk.condition = true;
+			wake_up(&sst_drv_ctx->wait_queue);
+		}
+	}
+
 	case IPC_IA_GET_FW_INFO: {
 		struct snd_sst_fw_info *fw_info =
 			(struct snd_sst_fw_info *)msg->mailbox;
@@ -615,12 +664,18 @@
 		break;
 
 	case IPC_IA_FREE_STREAM:
+		str_info = &sst_drv_ctx->streams[str_id];
 		if (!msg->header.part.data) {
 			pr_debug("Stream %d freed\n", str_id);
 		} else {
 			pr_err("Free for %d ret error %x\n",
 				       str_id, msg->header.part.data);
 		}
+		if (str_info->ctrl_blk.on == true) {
+			str_info->ctrl_blk.on = false;
+			str_info->ctrl_blk.condition = true;
+			wake_up(&sst_drv_ctx->wait_queue);
+		}
 		break;
 	case IPC_IA_ALLOC_STREAM: {
 		/* map to stream, call play */
@@ -699,6 +754,17 @@
 	case IPC_IA_START_STREAM:
 		pr_debug("reply for START STREAM %x\n", msg->header.full);
 		break;
+
+	case IPC_IA_GET_FW_CTXT:
+		pr_debug("reply for get fw ctxt  %x\n", msg->header.full);
+		if (msg->header.part.data)
+			sst_drv_ctx->fw_cntx_size = 0;
+		else
+			sst_drv_ctx->fw_cntx_size = *sst_drv_ctx->fw_cntx;
+		pr_debug("fw copied data %x\n", sst_drv_ctx->fw_cntx_size);
+		sst_wake_up_alloc_block(
+			sst_drv_ctx, str_id, msg->header.part.data, NULL);
+		break;
 	default:
 		/* Illegal case */
 		pr_err("process reply:default = %x\n", msg->header.full);
diff -druN linux-2.6.39-libre/drivers/staging/intel_sst/intel_sst_pvt.c linux-3.0-rc7-libre/drivers/staging/intel_sst/intel_sst_pvt.c
--- linux-2.6.39-libre/drivers/staging/intel_sst/intel_sst_pvt.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/intel_sst/intel_sst_pvt.c	2011-07-11 19:51:52.000000000 -0400
@@ -203,7 +203,7 @@
 		kfree(msg);
 		pr_err("kzalloc mailbox_data failed");
 		return -ENOMEM;
-	};
+	}
 	*arg = msg;
 	return 0;
 }
diff -druN linux-2.6.39-libre/drivers/staging/intel_sst/intel_sst_stream.c linux-3.0-rc7-libre/drivers/staging/intel_sst/intel_sst_stream.c
--- linux-2.6.39-libre/drivers/staging/intel_sst/intel_sst_stream.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/intel_sst/intel_sst_stream.c	2011-07-11 19:51:52.000000000 -0400
@@ -31,6 +31,7 @@
 #include <linux/pci.h>
 #include <linux/firmware.h>
 #include <linux/sched.h>
+#include <linux/delay.h>
 #include "intel_sst_ioctl.h"
 #include "intel_sst.h"
 #include "intel_sst_fw_ipc.h"
@@ -47,7 +48,7 @@
  */
 int sst_check_device_type(u32 device, u32 num_chan, u32 *pcm_slot)
 {
-	if (device > MAX_NUM_STREAMS_MFLD) {
+	if (device >= MAX_NUM_STREAMS_MFLD) {
 		pr_debug("device type invalid %d\n", device);
 		return -EINVAL;
 	}
@@ -72,6 +73,8 @@
 			*pcm_slot = 0x07;
 		else if (device == SND_SST_DEVICE_CAPTURE && num_chan == 4)
 			*pcm_slot = 0x0F;
+		else if (device == SND_SST_DEVICE_CAPTURE && num_chan > 4)
+			*pcm_slot = 0x1F;
 		else {
 			pr_debug("No condition satisfied.. ret err\n");
 			return -EINVAL;
@@ -519,10 +522,6 @@
 	str_info->data_blk.on = true;
 	retval = sst_wait_interruptible(sst_drv_ctx, &str_info->data_blk);
 	str_info->need_draining = false;
-	if (retval == -SST_ERR_INVALID_STREAM_ID) {
-		retval = -EINVAL;
-		sst_clean_stream(str_info);
-	}
 	return retval;
 }
 
@@ -563,6 +562,12 @@
 			str_info->data_blk.ret_code = 0;
 			wake_up(&sst_drv_ctx->wait_queue);
 		}
+		str_info->data_blk.on = true;
+		str_info->data_blk.condition = false;
+		retval = sst_wait_interruptible_timeout(sst_drv_ctx,
+				&str_info->ctrl_blk, SST_BLOCK_TIMEOUT);
+		pr_debug("wait for free returned %d\n", retval);
+		msleep(100);
 		mutex_lock(&sst_drv_ctx->stream_lock);
 		sst_clean_stream(str_info);
 		mutex_unlock(&sst_drv_ctx->stream_lock);
diff -druN linux-2.6.39-libre/drivers/staging/intel_sst/intel_sst_stream_encoded.c linux-3.0-rc7-libre/drivers/staging/intel_sst/intel_sst_stream_encoded.c
--- linux-2.6.39-libre/drivers/staging/intel_sst/intel_sst_stream_encoded.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/intel_sst/intel_sst_stream_encoded.c	2011-07-11 19:51:52.000000000 -0400
@@ -363,7 +363,6 @@
 				pr_err("SST_Activate_target_fail\n");
 			else
 				pr_err("SST_Activate_target_pass\n");
-		return retval;
 	} else if (slot->action == SND_SST_PORT_PREPARE &&
 			slot->device_type == SND_SST_DEVICE_PCM) {
 				retval = sst_prepare_target(slot);
@@ -371,12 +370,11 @@
 				pr_err("SST_prepare_target_fail\n");
 			else
 				pr_err("SST_prepare_target_pass\n");
-			return retval;
 	} else {
 		pr_err("slot_action : %d, device_type: %d\n",
 				slot->action, slot->device_type);
-		return retval;
 	}
+	return retval;
 }
 
 int sst_send_target(struct snd_sst_target_device *target)
@@ -886,8 +884,7 @@
 			int *input_index, int *in_copied,
 			int *input_index_valid_size, int *new_entry_flag)
 {
-	int retval = 0;
-	int i;
+	int retval = 0, i;
 
 	if (str_info->ops == STREAM_OPS_PLAYBACK_DRM) {
 		struct RAR_buffer rar_buffers;
@@ -924,7 +921,6 @@
 	return retval;
 }
 #endif
-
 /*This function is used to prepare the kernel input buffers with contents
 before sending for decode*/
 static int sst_prepare_input_buffers(struct stream_info *str_info,
diff -druN linux-2.6.39-libre/drivers/staging/intel_sst/jack.h linux-3.0-rc7-libre/drivers/staging/intel_sst/jack.h
--- linux-2.6.39-libre/drivers/staging/intel_sst/jack.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/intel_sst/jack.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,10 +0,0 @@
-/* Temporary staging glue */
-
-#include <sound/jack.h>
-
-/* These want adding to jack.h as enum entries once approved */
-
-#define SND_JACK_HS_SHORT_PRESS 	(SND_JACK_HEADSET | 0x0020)
-#define	SND_JACK_HS_LONG_PRESS		(SND_JACK_HEADSET | 0x0040)
-
-
diff -druN linux-2.6.39-libre/drivers/staging/Kconfig linux-3.0-rc7-libre/drivers/staging/Kconfig
--- linux-2.6.39-libre/drivers/staging/Kconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/Kconfig	2011-07-11 19:51:52.000000000 -0400
@@ -24,23 +24,6 @@
 
 if STAGING
 
-config STAGING_EXCLUDE_BUILD
-	bool "Exclude Staging drivers from being built" if STAGING
-	default y
-	---help---
-	  Are you sure you really want to build the staging drivers?
-	  They taint your kernel, don't live up to the normal Linux
-	  kernel quality standards, are a bit crufty around the edges,
-	  and might go off and kick your dog when you aren't paying
-	  attention.
-
-	  Say N here to be able to select and build the Staging drivers.
-	  This option is primarily here to prevent them from being built
-	  when selecting 'make allyesconfg' and 'make allmodconfig' so
-	  don't be all that put off, your dog will be just fine.
-
-if !STAGING_EXCLUDE_BUILD
-
 source "drivers/staging/tty/Kconfig"
 
 source "drivers/staging/generic_serial/Kconfig"
@@ -67,10 +50,6 @@
 
 source "drivers/staging/brcm80211/Kconfig"
 
-source "drivers/staging/rt2860/Kconfig"
-
-source "drivers/staging/rt2870/Kconfig"
-
 source "drivers/staging/comedi/Kconfig"
 
 source "drivers/staging/olpc_dcon/Kconfig"
@@ -177,5 +156,8 @@
 
 source "drivers/staging/altera-stapl/Kconfig"
 
-endif # !STAGING_EXCLUDE_BUILD
+source "drivers/staging/mei/Kconfig"
+
+source "drivers/staging/nvec/Kconfig"
+
 endif # STAGING
diff -druN linux-2.6.39-libre/drivers/staging/keucr/common.h linux-3.0-rc7-libre/drivers/staging/keucr/common.h
--- linux-2.6.39-libre/drivers/staging/keucr/common.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/keucr/common.h	2011-07-11 19:51:52.000000000 -0400
@@ -9,5 +9,7 @@
 typedef u32 DWORD;
 typedef u32 *PDWORD;
 
+#define BYTE_MASK	0xff
+
 #endif
 
diff -druN linux-2.6.39-libre/drivers/staging/keucr/init.c linux-3.0-rc7-libre/drivers/staging/keucr/init.c
--- linux-2.6.39-libre/drivers/staging/keucr/init.c	2011-05-19 02:18:18.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/keucr/init.c	2011-07-21 07:00:20.000000000 -0400
@@ -11,9 +11,6 @@
 #include "transport.h"
 #include "init.h"
 
-BYTE IsSSFDCCompliance;
-BYTE IsXDCompliance;
-
 /*
  * ENE_InitMedia():
  */
diff -druN linux-2.6.39-libre/drivers/staging/keucr/init.h linux-3.0-rc7-libre/drivers/staging/keucr/init.h
--- linux-2.6.39-libre/drivers/staging/keucr/init.h	2011-05-19 02:18:18.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/keucr/init.h	2011-07-21 07:00:20.000000000 -0400
@@ -4,18 +4,18 @@
 extern int Check_D_MediaFmt(struct us_data *);
 
 
-BYTE MS_Init[] = {
+static BYTE MS_Init[] = {
 /*(DEBLOBBED)*/ };
 
-BYTE MSP_Rdwr[] = {
+static BYTE MSP_Rdwr[] = {
 /*(DEBLOBBED)*/ };
 
-BYTE MS_Rdwr[] = {
+static BYTE MS_Rdwr[] = {
 /*(DEBLOBBED)*/ };
 
-BYTE SM_Init[] = {
+static BYTE SM_Init[] = {
 /*(DEBLOBBED)*/ };
 
-BYTE SM_Rdwr[] = {
+static BYTE SM_Rdwr[] = {
 /*(DEBLOBBED)*/ };
 
diff -druN linux-2.6.39-libre/drivers/staging/keucr/ms.c linux-3.0-rc7-libre/drivers/staging/keucr/ms.c
--- linux-2.6.39-libre/drivers/staging/keucr/ms.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/keucr/ms.c	2011-07-11 19:51:52.000000000 -0400
@@ -6,13 +6,17 @@
 #include "transport.h"
 #include "ms.h"
 
-//----- MS_ReaderCopyBlock() ------------------------------------------
-int MS_ReaderCopyBlock(struct us_data *us, WORD oldphy, WORD newphy, WORD PhyBlockAddr, BYTE PageNum, PBYTE buf, WORD len)
+/*
+ * MS_ReaderCopyBlock()
+ */
+int MS_ReaderCopyBlock(struct us_data *us, WORD oldphy, WORD newphy,
+			WORD PhyBlockAddr, BYTE PageNum, PBYTE buf, WORD len)
 {
 	struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf;
 	int	result;
 
-	//printk("MS_ReaderCopyBlock --- PhyBlockAddr = %x, PageNum = %x\n", PhyBlockAddr, PageNum);
+	/* printk(KERN_INFO "MS_ReaderCopyBlock --- PhyBlockAddr = %x,
+				PageNum = %x\n", PhyBlockAddr, PageNum); */
 	result = ENE_LoadBinCode(us, MS_RW_PATTERN);
 	if (result != USB_STOR_XFER_GOOD)
 		return USB_STOR_TRANSPORT_ERROR;
@@ -25,10 +29,10 @@
 	bcb->CDB[1]			= 0x08;
 	bcb->CDB[4]			= (BYTE)(oldphy);
 	bcb->CDB[3]			= (BYTE)(oldphy>>8);
-	bcb->CDB[2]			= (BYTE)(oldphy>>16);
+	bcb->CDB[2]			= 0; /* (BYTE)(oldphy>>16) */
 	bcb->CDB[7]			= (BYTE)(newphy);
 	bcb->CDB[6]			= (BYTE)(newphy>>8);
-	bcb->CDB[5]			= (BYTE)(newphy>>16);
+	bcb->CDB[5]			= 0; /* (BYTE)(newphy>>16) */
 	bcb->CDB[9]			= (BYTE)(PhyBlockAddr);
 	bcb->CDB[8]			= (BYTE)(PhyBlockAddr>>8);
 	bcb->CDB[10]		= PageNum;
@@ -40,21 +44,25 @@
 	return USB_STOR_TRANSPORT_GOOD;
 }
 
-//----- MS_ReaderReadPage() ------------------------------------------
-int MS_ReaderReadPage(struct us_data *us, DWORD PhyBlockAddr, BYTE PageNum, PDWORD PageBuf, MS_LibTypeExtdat *ExtraDat)
+/*
+ * MS_ReaderReadPage()
+ */
+int MS_ReaderReadPage(struct us_data *us, DWORD PhyBlockAddr,
+		BYTE PageNum, PDWORD PageBuf, MS_LibTypeExtdat *ExtraDat)
 {
 	struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf;
 	int	result;
 	BYTE	ExtBuf[4];
 	DWORD	bn = PhyBlockAddr * 0x20 + PageNum;
 
-	//printk("MS --- MS_ReaderReadPage,  PhyBlockAddr = %x, PageNum = %x\n", PhyBlockAddr, PageNum);
+	/* printk(KERN_INFO "MS --- MS_ReaderReadPage,
+		PhyBlockAddr = %x, PageNum = %x\n", PhyBlockAddr, PageNum); */
 
 	result = ENE_LoadBinCode(us, MS_RW_PATTERN);
 	if (result != USB_STOR_XFER_GOOD)
 		return USB_STOR_TRANSPORT_ERROR;
 
-	// Read Page Data
+	/* Read Page Data */
 	memset(bcb, 0, sizeof(struct bulk_cb_wrap));
 	bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN);
 	bcb->DataTransferLength = 0x200;
@@ -65,12 +73,12 @@
 	bcb->CDB[4]			= (BYTE)(bn>>8);
 	bcb->CDB[3]			= (BYTE)(bn>>16);
 	bcb->CDB[2]			= (BYTE)(bn>>24);
-	
+
 	result = ENE_SendScsiCmd(us, FDIR_READ, PageBuf, 0);
 	if (result != USB_STOR_XFER_GOOD)
 		return USB_STOR_TRANSPORT_ERROR;
 
-	// Read Extra Data
+	/* Read Extra Data */
 	memset(bcb, 0, sizeof(struct bulk_cb_wrap));
 	bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN);
 	bcb->DataTransferLength = 0x4;
@@ -88,9 +96,9 @@
 		return USB_STOR_TRANSPORT_ERROR;
 
 	ExtraDat->reserved = 0;
-	ExtraDat->intr     = 0x80;  // Not yet, �����], �� fireware support
-	ExtraDat->status0  = 0x10;  // Not yet, �����], �� fireware support
-	ExtraDat->status1  = 0x00;  // Not yet, �����], �� fireware support
+	ExtraDat->intr     = 0x80;  /* Not yet,fireware support */
+	ExtraDat->status0  = 0x10;  /* Not yet,fireware support */
+	ExtraDat->status1  = 0x00;  /* Not yet,fireware support */
 	ExtraDat->ovrflg   = ExtBuf[0];
 	ExtraDat->mngflg   = ExtBuf[1];
 	ExtraDat->logadr   = MemStickLogAddr(ExtBuf[2], ExtBuf[3]);
@@ -98,14 +106,17 @@
 	return USB_STOR_TRANSPORT_GOOD;
 }
 
-//----- MS_ReaderEraseBlock() ----------------------------------------
+/*
+ * MS_ReaderEraseBlock()
+ */
 int MS_ReaderEraseBlock(struct us_data *us, DWORD PhyBlockAddr)
 {
 	struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf;
 	int	result;
 	DWORD	bn = PhyBlockAddr;
 
-	//printk("MS --- MS_ReaderEraseBlock,  PhyBlockAddr = %x\n", PhyBlockAddr);
+	/* printk(KERN_INFO "MS --- MS_ReaderEraseBlock,
+		PhyBlockAddr = %x\n", PhyBlockAddr); */
 	result = ENE_LoadBinCode(us, MS_RW_PATTERN);
 	if (result != USB_STOR_XFER_GOOD)
 		return USB_STOR_TRANSPORT_ERROR;
@@ -119,7 +130,7 @@
 	bcb->CDB[4]			= (BYTE)(bn);
 	bcb->CDB[3]			= (BYTE)(bn>>8);
 	bcb->CDB[2]			= (BYTE)(bn>>16);
-	
+
 	result = ENE_SendScsiCmd(us, FDIR_READ, NULL, 0);
 	if (result != USB_STOR_XFER_GOOD)
 		return USB_STOR_TRANSPORT_ERROR;
@@ -127,23 +138,25 @@
 	return USB_STOR_TRANSPORT_GOOD;
 }
 
-//----- MS_CardInit() ------------------------------------------------
+/*
+ * MS_CardInit()
+ */
 int MS_CardInit(struct us_data *us)
 {
-	DWORD			result=0;
+	DWORD			result = 0;
 	WORD			TmpBlock;
 	PBYTE			PageBuffer0 = NULL, PageBuffer1 = NULL;
 	MS_LibTypeExtdat	extdat;
 	WORD			btBlk1st, btBlk2nd;
 	DWORD			btBlk1stErred;
 
-	printk("MS_CardInit start\n");
+	printk(KERN_INFO "MS_CardInit start\n");
 
 	MS_LibFreeAllocatedArea(us);
 
-	if (((PageBuffer0 = kmalloc(MS_BYTES_PER_PAGE, GFP_KERNEL)) == NULL) ||
-	    ((PageBuffer1 = kmalloc(MS_BYTES_PER_PAGE, GFP_KERNEL)) == NULL))
-	{
+	PageBuffer0 = kmalloc(MS_BYTES_PER_PAGE, GFP_KERNEL);
+	PageBuffer1 = kmalloc(MS_BYTES_PER_PAGE, GFP_KERNEL);
+	if ((PageBuffer0 == NULL) || (PageBuffer1 == NULL)) {
 		result = MS_NO_MEMORY_ERROR;
 		goto exit;
 	}
@@ -151,16 +164,16 @@
 	btBlk1st = btBlk2nd = MS_LB_NOT_USED;
 	btBlk1stErred = 0;
 
-	for (TmpBlock=0; TmpBlock < MS_MAX_INITIAL_ERROR_BLOCKS+2; TmpBlock++)
-	{
-		switch (MS_ReaderReadPage(us, TmpBlock, 0, (DWORD *)PageBuffer0, &extdat))
-		{
-			case MS_STATUS_SUCCESS:
+	for (TmpBlock = 0; TmpBlock < MS_MAX_INITIAL_ERROR_BLOCKS+2;
+		TmpBlock++) {
+		switch (MS_ReaderReadPage(us, TmpBlock, 0,
+			(DWORD *)PageBuffer0, &extdat)) {
+		case MS_STATUS_SUCCESS:
 			break;
-			case MS_STATUS_INT_ERROR:
+		case MS_STATUS_INT_ERROR:
 			break;
-			case MS_STATUS_ERROR:
-			default:
+		case MS_STATUS_ERROR:
+		default:
 			continue;
 		}
 
@@ -173,38 +186,37 @@
 			(((MemStickBootBlockPage0 *)PageBuffer0)->header.bNumberOfDataEntry != MS_BOOT_BLOCK_DATA_ENTRIES))
 				continue;
 
-		if (btBlk1st != MS_LB_NOT_USED)
-		{
+		if (btBlk1st != MS_LB_NOT_USED) {
 			btBlk2nd = TmpBlock;
 			break;
 		}
 
 		btBlk1st = TmpBlock;
 		memcpy(PageBuffer1, PageBuffer0, MS_BYTES_PER_PAGE);
-		if (extdat.status1 & (MS_REG_ST1_DTER | MS_REG_ST1_EXER | MS_REG_ST1_FGER))
+		if (extdat.status1 &
+			(MS_REG_ST1_DTER | MS_REG_ST1_EXER | MS_REG_ST1_FGER))
 			btBlk1stErred = 1;
 	}
 
-	if (btBlk1st == MS_LB_NOT_USED)
-	{
+	if (btBlk1st == MS_LB_NOT_USED) {
 		result = MS_STATUS_ERROR;
 		goto exit;
 	}
 
-	// write protect
+	/* write protect */
 	if ((extdat.status0 & MS_REG_ST0_WP) == MS_REG_ST0_WP_ON)
 		MS_LibCtrlSet(us, MS_LIB_CTRL_WRPROTECT);
 
 	result = MS_STATUS_ERROR;
-	// 1st Boot Block
+	/* 1st Boot Block */
 	if (btBlk1stErred == 0)
-		result = MS_LibProcessBootBlock(us, btBlk1st, PageBuffer1);   // 1st
-	// 2nd Boot Block
+		result = MS_LibProcessBootBlock(us, btBlk1st, PageBuffer1);
+		/* 1st */
+	/* 2nd Boot Block */
 	if (result && (btBlk2nd != MS_LB_NOT_USED))
 		result = MS_LibProcessBootBlock(us, btBlk2nd, PageBuffer0);
 
-	if (result)
-	{
+	if (result) {
 		result = MS_STATUS_ERROR;
 		goto exit;
 	}
@@ -214,8 +226,7 @@
 
 	us->MS_Lib.Phy2LogMap[btBlk1st] = MS_LB_BOOT_BLOCK;
 
-	if (btBlk2nd != MS_LB_NOT_USED)
-	{
+	if (btBlk2nd != MS_LB_NOT_USED) {
 		for (TmpBlock = btBlk1st + 1; TmpBlock < btBlk2nd; TmpBlock++)
 			us->MS_Lib.Phy2LogMap[TmpBlock] = MS_LB_INITIAL_ERROR;
 		us->MS_Lib.Phy2LogMap[btBlk2nd] = MS_LB_BOOT_BLOCK;
@@ -225,18 +236,17 @@
 	if (result)
 		goto exit;
 
-	for (TmpBlock=MS_PHYSICAL_BLOCKS_PER_SEGMENT; TmpBlock<us->MS_Lib.NumberOfPhyBlock; TmpBlock+=MS_PHYSICAL_BLOCKS_PER_SEGMENT)
-	{
-		if (MS_CountFreeBlock(us, TmpBlock) == 0)
-		{
+	for (TmpBlock = MS_PHYSICAL_BLOCKS_PER_SEGMENT;
+		TmpBlock < us->MS_Lib.NumberOfPhyBlock;
+		TmpBlock += MS_PHYSICAL_BLOCKS_PER_SEGMENT) {
+		if (MS_CountFreeBlock(us, TmpBlock) == 0) {
 			MS_LibCtrlSet(us, MS_LIB_CTRL_WRPROTECT);
 			break;
 		}
 	}
 
-	// write
-	if (MS_LibAllocWriteBuf(us))
-	{
+	/* write */
+	if (MS_LibAllocWriteBuf(us)) {
 		result = MS_NO_MEMORY_ERROR;
 		goto exit;
 	}
@@ -245,46 +255,48 @@
 
 exit:
 	kfree(PageBuffer1);
-    	kfree(PageBuffer0);
+	kfree(PageBuffer0);
 
-	printk("MS_CardInit end\n");
+	printk(KERN_INFO "MS_CardInit end\n");
 	return result;
 }
 
-//----- MS_LibCheckDisableBlock() ------------------------------------
+/*
+ * MS_LibCheckDisableBlock()
+ */
 int MS_LibCheckDisableBlock(struct us_data *us, WORD PhyBlock)
 {
-	PWORD			PageBuf=NULL;
-	DWORD			result=MS_STATUS_SUCCESS;
-	DWORD			blk, index=0;
+	PWORD			PageBuf = NULL;
+	DWORD			result = MS_STATUS_SUCCESS;
+	DWORD			blk, index = 0;
 	MS_LibTypeExtdat	extdat;
 
-	if (((PageBuf = kmalloc(MS_BYTES_PER_PAGE, GFP_KERNEL)) == NULL))
-	{
+	PageBuf = kmalloc(MS_BYTES_PER_PAGE, GFP_KERNEL);
+	if (PageBuf == NULL) {
 		result = MS_NO_MEMORY_ERROR;
 		goto exit;
 	}
 
 	MS_ReaderReadPage(us, PhyBlock, 1, (DWORD *)PageBuf, &extdat);
-	do
-	{
+	do {
 		blk = be16_to_cpu(PageBuf[index]);
 		if (blk == MS_LB_NOT_USED)
 			break;
-		if (blk == us->MS_Lib.Log2PhyMap[0])
-		{
+		if (blk == us->MS_Lib.Log2PhyMap[0]) {
 			result = MS_ERROR_FLASH_READ;
 			break;
 		}
 		index++;
-	} while(1);
+	} while (1);
 
 exit:
 	kfree(PageBuf);
 	return result;
 }
 
-//----- MS_LibFreeAllocatedArea() ------------------------------------
+/*
+ * MS_LibFreeAllocatedArea()
+ */
 void MS_LibFreeAllocatedArea(struct us_data *us)
 {
 	MS_LibFreeWriteBuf(us);
@@ -302,26 +314,31 @@
 	us->MS_Lib.NumberOfLogBlock	= 0;
 }
 
-//----- MS_LibFreeWriteBuf() -----------------------------------------
+/*
+ * MS_LibFreeWriteBuf()
+ */
 void MS_LibFreeWriteBuf(struct us_data *us)
 {
-	us->MS_Lib.wrtblk = (WORD)-1; //set to -1
-	MS_LibClearPageMap(us); // memset((fdoExt)->MS_Lib.pagemap, 0, sizeof((fdoExt)->MS_Lib.pagemap))
+	us->MS_Lib.wrtblk = (WORD)-1; /* set to -1 */
 
-	if (us->MS_Lib.blkpag)
-	{
-		kfree((BYTE *)(us->MS_Lib.blkpag));  // Arnold test ...
+	/* memset((fdoExt)->MS_Lib.pagemap, 0,
+			sizeof((fdoExt)->MS_Lib.pagemap)) */
+	MS_LibClearPageMap(us);
+
+	if (us->MS_Lib.blkpag) {
+		kfree((BYTE *)(us->MS_Lib.blkpag));  /* Arnold test ... */
 		us->MS_Lib.blkpag = NULL;
 	}
 
-	if (us->MS_Lib.blkext)
-	{
-		kfree((BYTE *)(us->MS_Lib.blkext));  // Arnold test ...
+	if (us->MS_Lib.blkext) {
+		kfree((BYTE *)(us->MS_Lib.blkext));  /* Arnold test ... */
 		us->MS_Lib.blkext = NULL;
 	}
 }
 
-//----- MS_LibFreeLogicalMap() ---------------------------------------
+/*
+ * MS_LibFreeLogicalMap()
+ */
 int MS_LibFreeLogicalMap(struct us_data *us)
 {
 	kfree(us->MS_Lib.Phy2LogMap);
@@ -330,10 +347,12 @@
 	kfree(us->MS_Lib.Log2PhyMap);
 	us->MS_Lib.Log2PhyMap = NULL;
 
-    return 0;
+	return 0;
 }
 
-//----- MS_LibProcessBootBlock() -------------------------------------
+/*
+ * MS_LibProcessBootBlock()
+ */
 int MS_LibProcessBootBlock(struct us_data *us, WORD PhyBlock, BYTE *PageData)
 {
 	MemStickBootBlockSysEnt  *SysEntry;
@@ -343,144 +362,165 @@
 	BYTE                     *PageBuffer;
 	MS_LibTypeExtdat         ExtraData;
 
-	if ((PageBuffer = kmalloc(MS_BYTES_PER_PAGE, GFP_KERNEL))==NULL)
+
+	PageBuffer = kmalloc(MS_BYTES_PER_PAGE, GFP_KERNEL);
+	if (PageBuffer == NULL)
 		return (DWORD)-1;
 
 	result = (DWORD)-1;
 
-	SysInfo= &(((MemStickBootBlockPage0 *)PageData)->sysinf);
+	SysInfo = &(((MemStickBootBlockPage0 *)PageData)->sysinf);
 
-	if ((SysInfo->bMsClass != MS_SYSINF_MSCLASS_TYPE_1)                                   ||
-		(be16_to_cpu(SysInfo->wPageSize) != MS_SYSINF_PAGE_SIZE)                       ||
+	if ((SysInfo->bMsClass != MS_SYSINF_MSCLASS_TYPE_1) ||
+		(be16_to_cpu(SysInfo->wPageSize) != MS_SYSINF_PAGE_SIZE) ||
 		((SysInfo->bSecuritySupport & MS_SYSINF_SECURITY) == MS_SYSINF_SECURITY_SUPPORT) ||
-		(SysInfo->bReserved1 != MS_SYSINF_RESERVED1)                                     ||
-		(SysInfo->bReserved2 != MS_SYSINF_RESERVED2)                                     ||
-		(SysInfo->bFormatType!= MS_SYSINF_FORMAT_FAT)                                    ||
+		(SysInfo->bReserved1 != MS_SYSINF_RESERVED1) ||
+		(SysInfo->bReserved2 != MS_SYSINF_RESERVED2) ||
+		(SysInfo->bFormatType != MS_SYSINF_FORMAT_FAT) ||
 		(SysInfo->bUsage != MS_SYSINF_USAGE_GENERAL))
 		goto exit;
 
-	switch (us->MS_Lib.cardType = SysInfo->bCardType)
-	{
-		case MS_SYSINF_CARDTYPE_RDONLY:
-			MS_LibCtrlSet(us, MS_LIB_CTRL_RDONLY);
-			break;
-		case MS_SYSINF_CARDTYPE_RDWR:
-			MS_LibCtrlReset(us, MS_LIB_CTRL_RDONLY);
-			break;
-		case MS_SYSINF_CARDTYPE_HYBRID:
-		default:
-			goto exit;
+	switch (us->MS_Lib.cardType = SysInfo->bCardType) {
+	case MS_SYSINF_CARDTYPE_RDONLY:
+		MS_LibCtrlSet(us, MS_LIB_CTRL_RDONLY);
+		break;
+	case MS_SYSINF_CARDTYPE_RDWR:
+		MS_LibCtrlReset(us, MS_LIB_CTRL_RDONLY);
+		break;
+	case MS_SYSINF_CARDTYPE_HYBRID:
+	default:
+		goto exit;
 	}
 
 	us->MS_Lib.blockSize        = be16_to_cpu(SysInfo->wBlockSize);
 	us->MS_Lib.NumberOfPhyBlock = be16_to_cpu(SysInfo->wBlockNumber);
-	us->MS_Lib.NumberOfLogBlock = be16_to_cpu(SysInfo->wTotalBlockNumber) - 2;
-	us->MS_Lib.PagesPerBlock    = us->MS_Lib.blockSize * SIZE_OF_KIRO / MS_BYTES_PER_PAGE;
-	us->MS_Lib.NumberOfSegment  = us->MS_Lib.NumberOfPhyBlock / MS_PHYSICAL_BLOCKS_PER_SEGMENT;
+	us->MS_Lib.NumberOfLogBlock = be16_to_cpu(SysInfo->wTotalBlockNumber)
+									-2;
+	us->MS_Lib.PagesPerBlock    = us->MS_Lib.blockSize * SIZE_OF_KIRO /
+							MS_BYTES_PER_PAGE;
+	us->MS_Lib.NumberOfSegment  = us->MS_Lib.NumberOfPhyBlock /
+					MS_PHYSICAL_BLOCKS_PER_SEGMENT;
 	us->MS_Model                = be16_to_cpu(SysInfo->wMemorySize);
 
-	if (MS_LibAllocLogicalMap(us))			//Allocate to all number of logicalblock and physicalblock
+	/*Allocate to all number of logicalblock and physicalblock */
+	if (MS_LibAllocLogicalMap(us))
 		goto exit;
 
-	MS_LibSetBootBlockMark(us, PhyBlock);		//Mark the book block
+	/* Mark the book block */
+	MS_LibSetBootBlockMark(us, PhyBlock);
 
 	SysEntry = &(((MemStickBootBlockPage0 *)PageData)->sysent);
 
-	for (i=0; i<MS_NUMBER_OF_SYSTEM_ENTRY; i++)
-	{
+	for (i = 0; i < MS_NUMBER_OF_SYSTEM_ENTRY; i++) {
 		DWORD  EntryOffset, EntrySize;
 
-		if ((EntryOffset = be32_to_cpu(SysEntry->entry[i].dwStart)) == 0xffffff)
+		EntryOffset = be32_to_cpu(SysEntry->entry[i].dwStart);
+
+		if (EntryOffset == 0xffffff)
 			continue;
+		EntrySize = be32_to_cpu(SysEntry->entry[i].dwSize);
 
-		if ((EntrySize = be32_to_cpu(SysEntry->entry[i].dwSize)) == 0)
+		if (EntrySize == 0)
 			continue;
 
-		if (EntryOffset + MS_BYTES_PER_PAGE + EntrySize > us->MS_Lib.blockSize * (DWORD)SIZE_OF_KIRO)
+		if (EntryOffset + MS_BYTES_PER_PAGE + EntrySize >
+			us->MS_Lib.blockSize * (DWORD)SIZE_OF_KIRO)
 			continue;
 
-		if (i == 0)
-		{
+		if (i == 0) {
 			BYTE  PrevPageNumber = 0;
 			WORD  phyblk;
 
-			if (SysEntry->entry[i].bType != MS_SYSENT_TYPE_INVALID_BLOCK)
+			if (SysEntry->entry[i].bType !=
+				MS_SYSENT_TYPE_INVALID_BLOCK)
 				goto exit;
 
-			while (EntrySize > 0)
-			{
-				if ((PageNumber = (BYTE)(EntryOffset / MS_BYTES_PER_PAGE + 1)) != PrevPageNumber)
-				{
-					switch (MS_ReaderReadPage(us, PhyBlock, PageNumber, (DWORD *)PageBuffer, &ExtraData))
-					{
-						case MS_STATUS_SUCCESS:
-							break;
-						case MS_STATUS_WRITE_PROTECT:
-						case MS_ERROR_FLASH_READ:
-						case MS_STATUS_ERROR:
-						default:
-							goto exit;
+			while (EntrySize > 0) {
+
+				PageNumber = (BYTE)(EntryOffset /
+							MS_BYTES_PER_PAGE + 1);
+				if (PageNumber != PrevPageNumber) {
+					switch (MS_ReaderReadPage(us, PhyBlock,
+						PageNumber, (DWORD *)PageBuffer,
+						&ExtraData)) {
+					case MS_STATUS_SUCCESS:
+						break;
+					case MS_STATUS_WRITE_PROTECT:
+					case MS_ERROR_FLASH_READ:
+					case MS_STATUS_ERROR:
+					default:
+						goto exit;
 					}
 
 					PrevPageNumber = PageNumber;
 				}
 
-				if ((phyblk = be16_to_cpu(*(WORD *)(PageBuffer + (EntryOffset % MS_BYTES_PER_PAGE)))) < 0x0fff)
+				phyblk = be16_to_cpu(*(WORD *)(PageBuffer +
+					(EntryOffset % MS_BYTES_PER_PAGE)));
+				if (phyblk < 0x0fff)
 					MS_LibSetInitialErrorBlock(us, phyblk);
 
 				EntryOffset += 2;
 				EntrySize -= 2;
 			}
-		}
-		else if (i == 1)
-		{  // CIS/IDI
+		} else if (i == 1) {  /* CIS/IDI */
 			MemStickBootBlockIDI  *idi;
 
 			if (SysEntry->entry[i].bType != MS_SYSENT_TYPE_CIS_IDI)
 				goto exit;
 
-			switch (MS_ReaderReadPage(us, PhyBlock, (BYTE)(EntryOffset / MS_BYTES_PER_PAGE + 1), (DWORD *)PageBuffer, &ExtraData))
-			{
-				case MS_STATUS_SUCCESS:
-					break;
-				case MS_STATUS_WRITE_PROTECT:
-				case MS_ERROR_FLASH_READ:
-				case MS_STATUS_ERROR:
-				default:
-					goto exit;
+			switch (MS_ReaderReadPage(us, PhyBlock,
+				(BYTE)(EntryOffset / MS_BYTES_PER_PAGE + 1),
+				(DWORD *)PageBuffer, &ExtraData)) {
+			case MS_STATUS_SUCCESS:
+				break;
+			case MS_STATUS_WRITE_PROTECT:
+			case MS_ERROR_FLASH_READ:
+			case MS_STATUS_ERROR:
+			default:
+				goto exit;
 			}
 
-			idi = &((MemStickBootBlockCIS_IDI *)(PageBuffer + (EntryOffset % MS_BYTES_PER_PAGE)))->idi.idi;
-			if (le16_to_cpu(idi->wIDIgeneralConfiguration) != MS_IDI_GENERAL_CONF)
+			idi = &((MemStickBootBlockCIS_IDI *)(PageBuffer +
+				(EntryOffset % MS_BYTES_PER_PAGE)))->idi.idi;
+			if (le16_to_cpu(idi->wIDIgeneralConfiguration) !=
+							MS_IDI_GENERAL_CONF)
 				goto exit;
 
-			us->MS_Lib.BytesPerSector = le16_to_cpu(idi->wIDIbytesPerSector);
+			us->MS_Lib.BytesPerSector =
+				le16_to_cpu(idi->wIDIbytesPerSector);
 			if (us->MS_Lib.BytesPerSector != MS_BYTES_PER_PAGE)
 				goto exit;
 		}
-	} // End for ..
+	} /* End for .. */
 
 	result = 0;
 
 exit:
-	if (result)		MS_LibFreeLogicalMap(us);
+	if (result)
+		MS_LibFreeLogicalMap(us);
+
 	kfree(PageBuffer);
 
 	result = 0;
 	return result;
 }
 
-//----- MS_LibAllocLogicalMap() --------------------------------------
+/*
+ * MS_LibAllocLogicalMap()
+ */
 int MS_LibAllocLogicalMap(struct us_data *us)
 {
 	DWORD  i;
 
 
-	us->MS_Lib.Phy2LogMap = kmalloc(us->MS_Lib.NumberOfPhyBlock * sizeof(WORD), GFP_KERNEL);
-	us->MS_Lib.Log2PhyMap = kmalloc(us->MS_Lib.NumberOfLogBlock * sizeof(WORD), GFP_KERNEL);
+	us->MS_Lib.Phy2LogMap = kmalloc(us->MS_Lib.NumberOfPhyBlock *
+						sizeof(WORD), GFP_KERNEL);
+	us->MS_Lib.Log2PhyMap = kmalloc(us->MS_Lib.NumberOfLogBlock *
+						sizeof(WORD), GFP_KERNEL);
 
-	if ((us->MS_Lib.Phy2LogMap == NULL) || (us->MS_Lib.Log2PhyMap == NULL))
-	{
+	if ((us->MS_Lib.Phy2LogMap == NULL) ||
+		(us->MS_Lib.Log2PhyMap == NULL)) {
 		MS_LibFreeLogicalMap(us);
 		return (DWORD)-1;
 	}
@@ -489,128 +529,142 @@
 		us->MS_Lib.Phy2LogMap[i] = MS_LB_NOT_USED;
 
 	for (i = 0; i < us->MS_Lib.NumberOfLogBlock; i++)
-	us->MS_Lib.Log2PhyMap[i] = MS_LB_NOT_USED;
+		us->MS_Lib.Log2PhyMap[i] = MS_LB_NOT_USED;
 
 	return 0;
 }
 
-//----- MS_LibSetBootBlockMark() -------------------------------------
+/*
+ * MS_LibSetBootBlockMark()
+ */
 int MS_LibSetBootBlockMark(struct us_data *us, WORD phyblk)
 {
-    return MS_LibSetLogicalBlockMark(us, phyblk, MS_LB_BOOT_BLOCK);
+	return MS_LibSetLogicalBlockMark(us, phyblk, MS_LB_BOOT_BLOCK);
 }
 
-//----- MS_LibSetLogicalBlockMark() ----------------------------------
+/*
+ * MS_LibSetLogicalBlockMark()
+ */
 int MS_LibSetLogicalBlockMark(struct us_data *us, WORD phyblk, WORD mark)
 {
-    if (phyblk >= us->MS_Lib.NumberOfPhyBlock)
-        return (DWORD)-1;
+	if (phyblk >= us->MS_Lib.NumberOfPhyBlock)
+		return (DWORD)-1;
 
-    us->MS_Lib.Phy2LogMap[phyblk] = mark;
+	us->MS_Lib.Phy2LogMap[phyblk] = mark;
 
-    return 0;
+	return 0;
 }
 
-//----- MS_LibSetInitialErrorBlock() ---------------------------------
+/*
+ * MS_LibSetInitialErrorBlock()
+ */
 int MS_LibSetInitialErrorBlock(struct us_data *us, WORD phyblk)
 {
-    return MS_LibSetLogicalBlockMark(us, phyblk, MS_LB_INITIAL_ERROR);
+	return MS_LibSetLogicalBlockMark(us, phyblk, MS_LB_INITIAL_ERROR);
 }
 
-//----- MS_LibScanLogicalBlockNumber() -------------------------------
+/*
+ * MS_LibScanLogicalBlockNumber()
+ */
 int MS_LibScanLogicalBlockNumber(struct us_data *us, WORD btBlk1st)
 {
 	WORD			PhyBlock, newblk, i;
 	WORD			LogStart, LogEnde;
 	MS_LibTypeExtdat	extdat;
 	BYTE			buf[0x200];
-	DWORD			count=0, index=0;
+	DWORD			count = 0, index = 0;
 
-	for (PhyBlock = 0; PhyBlock < us->MS_Lib.NumberOfPhyBlock;)
-	{
+	for (PhyBlock = 0; PhyBlock < us->MS_Lib.NumberOfPhyBlock;) {
 		MS_LibPhy2LogRange(PhyBlock, &LogStart, &LogEnde);
 
-		for (i=0; i<MS_PHYSICAL_BLOCKS_PER_SEGMENT; i++, PhyBlock++)
-		{
-			switch (MS_LibConv2Logical(us, PhyBlock))
-			{
-				case MS_STATUS_ERROR:
-					continue;
-				default:
-					break;
+		for (i = 0; i < MS_PHYSICAL_BLOCKS_PER_SEGMENT;
+			i++, PhyBlock++) {
+			switch (MS_LibConv2Logical(us, PhyBlock)) {
+			case MS_STATUS_ERROR:
+				continue;
+			default:
+				break;
 			}
 
-			if (count == PhyBlock)
-			{
-				MS_LibReadExtraBlock(us, PhyBlock, 0, 0x80, &buf);
+			if (count == PhyBlock) {
+				MS_LibReadExtraBlock(us, PhyBlock,
+							0, 0x80, &buf);
 				count += 0x80;
 			}
 			index = (PhyBlock % 0x80) * 4;
 
 			extdat.ovrflg = buf[index];
 			extdat.mngflg = buf[index+1];
-			extdat.logadr = MemStickLogAddr(buf[index+2], buf[index+3]);
+			extdat.logadr = MemStickLogAddr(buf[index+2],
+							buf[index+3]);
 
-			if ((extdat.ovrflg & MS_REG_OVR_BKST) != MS_REG_OVR_BKST_OK)
-			{
+			if ((extdat.ovrflg & MS_REG_OVR_BKST) !=
+				MS_REG_OVR_BKST_OK) {
 				MS_LibSetAcquiredErrorBlock(us, PhyBlock);
 				continue;
 			}
 
-			if ((extdat.mngflg & MS_REG_MNG_ATFLG) == MS_REG_MNG_ATFLG_ATTBL)
-			{
+			if ((extdat.mngflg & MS_REG_MNG_ATFLG) ==
+				MS_REG_MNG_ATFLG_ATTBL) {
 				MS_LibErasePhyBlock(us, PhyBlock);
 				continue;
 			}
 
-			if (extdat.logadr != MS_LB_NOT_USED)
-			{
-				if ((extdat.logadr < LogStart) || (LogEnde <= extdat.logadr))
-				{
+			if (extdat.logadr != MS_LB_NOT_USED) {
+				if ((extdat.logadr < LogStart) ||
+					(LogEnde <= extdat.logadr)) {
 					MS_LibErasePhyBlock(us, PhyBlock);
 					continue;
 				}
 
-				if ((newblk = MS_LibConv2Physical(us, extdat.logadr)) != MS_LB_NOT_USED)
-				{
-					if (extdat.logadr==0)
-					{
-						MS_LibSetLogicalPair(us, extdat.logadr, PhyBlock);
-						if ( MS_LibCheckDisableBlock(us, btBlk1st) )
-						{
-							MS_LibSetLogicalPair(us, extdat.logadr, newblk);
+				newblk = MS_LibConv2Physical(us, extdat.logadr);
+
+				if (newblk != MS_LB_NOT_USED) {
+					if (extdat.logadr == 0) {
+						MS_LibSetLogicalPair(us,
+								extdat.logadr,
+								PhyBlock);
+						if (MS_LibCheckDisableBlock(us,
+							btBlk1st)) {
+							MS_LibSetLogicalPair(us,
+							extdat.logadr, newblk);
 							continue;
 						}
 					}
 
 					MS_LibReadExtra(us, newblk, 0, &extdat);
-					if ((extdat.ovrflg & MS_REG_OVR_UDST) == MS_REG_OVR_UDST_UPDATING)
-					{
-						MS_LibErasePhyBlock(us, PhyBlock);
+					if ((extdat.ovrflg & MS_REG_OVR_UDST) ==
+						MS_REG_OVR_UDST_UPDATING) {
+						MS_LibErasePhyBlock(us,
+								PhyBlock);
 						continue;
-					}
-					else
+					} else {
 						MS_LibErasePhyBlock(us, newblk);
+					}
 				}
 
-				MS_LibSetLogicalPair(us, extdat.logadr, PhyBlock);
+				MS_LibSetLogicalPair(us, extdat.logadr,
+								PhyBlock);
 			}
 		}
-	} //End for ...
+	} /* End for ... */
 
 	return MS_STATUS_SUCCESS;
 }
 
-//----- MS_LibAllocWriteBuf() ----------------------------------------
+/*
+ * MS_LibAllocWriteBuf()
+ */
 int MS_LibAllocWriteBuf(struct us_data *us)
 {
 	us->MS_Lib.wrtblk = (WORD)-1;
 
-	us->MS_Lib.blkpag = kmalloc(us->MS_Lib.PagesPerBlock * us->MS_Lib.BytesPerSector, GFP_KERNEL);
-	us->MS_Lib.blkext = kmalloc(us->MS_Lib.PagesPerBlock * sizeof(MS_LibTypeExtdat), GFP_KERNEL);
+	us->MS_Lib.blkpag = kmalloc(us->MS_Lib.PagesPerBlock *
+					us->MS_Lib.BytesPerSector, GFP_KERNEL);
+	us->MS_Lib.blkext = kmalloc(us->MS_Lib.PagesPerBlock *
+					sizeof(MS_LibTypeExtdat), GFP_KERNEL);
 
-	if ((us->MS_Lib.blkpag == NULL) || (us->MS_Lib.blkext == NULL))
-	{
+	if ((us->MS_Lib.blkpag == NULL) || (us->MS_Lib.blkext == NULL)) {
 		MS_LibFreeWriteBuf(us);
 		return (DWORD)-1;
 	}
@@ -620,7 +674,9 @@
 	return 0;
 }
 
-//----- MS_LibClearWriteBuf() ----------------------------------------
+/*
+ * MS_LibClearWriteBuf()
+ */
 void MS_LibClearWriteBuf(struct us_data *us)
 {
 	int i;
@@ -629,12 +685,11 @@
 	MS_LibClearPageMap(us);
 
 	if (us->MS_Lib.blkpag)
-		memset(us->MS_Lib.blkpag, 0xff, us->MS_Lib.PagesPerBlock * us->MS_Lib.BytesPerSector);
+		memset(us->MS_Lib.blkpag, 0xff,
+			us->MS_Lib.PagesPerBlock * us->MS_Lib.BytesPerSector);
 
-	if (us->MS_Lib.blkext)
-	{
-		for (i = 0; i < us->MS_Lib.PagesPerBlock; i++)
-		{
+	if (us->MS_Lib.blkext) {
+		for (i = 0; i < us->MS_Lib.PagesPerBlock; i++) {
 			us->MS_Lib.blkext[i].status1 = MS_REG_ST1_DEFAULT;
 			us->MS_Lib.blkext[i].ovrflg = MS_REG_OVR_DEFAULT;
 			us->MS_Lib.blkext[i].mngflg = MS_REG_MNG_DEFAULT;
@@ -643,32 +698,36 @@
 	}
 }
 
-//----- MS_LibPhy2LogRange() -----------------------------------------
+/*
+ * MS_LibPhy2LogRange()
+ */
 void MS_LibPhy2LogRange(WORD PhyBlock, WORD *LogStart, WORD *LogEnde)
 {
 	PhyBlock /= MS_PHYSICAL_BLOCKS_PER_SEGMENT;
 
-	if (PhyBlock)
-	{
-		*LogStart = MS_LOGICAL_BLOCKS_IN_1ST_SEGMENT + (PhyBlock - 1) * MS_LOGICAL_BLOCKS_PER_SEGMENT;//496
-		*LogEnde = *LogStart + MS_LOGICAL_BLOCKS_PER_SEGMENT;//496
-	}
-	else
-	{
+	if (PhyBlock) {
+		*LogStart = MS_LOGICAL_BLOCKS_IN_1ST_SEGMENT +
+			(PhyBlock - 1) * MS_LOGICAL_BLOCKS_PER_SEGMENT;/*496*/
+		*LogEnde = *LogStart + MS_LOGICAL_BLOCKS_PER_SEGMENT;/*496*/
+	} else {
 		*LogStart = 0;
-		*LogEnde = MS_LOGICAL_BLOCKS_IN_1ST_SEGMENT;//494
+		*LogEnde = MS_LOGICAL_BLOCKS_IN_1ST_SEGMENT;/*494*/
 	}
 }
 
-//----- MS_LibReadExtraBlock() --------------------------------------------
-int MS_LibReadExtraBlock(struct us_data *us, DWORD PhyBlock, BYTE PageNum, BYTE blen, void *buf)
+/*
+ * MS_LibReadExtraBlock()
+ */
+int MS_LibReadExtraBlock(struct us_data *us, DWORD PhyBlock,
+				BYTE PageNum, BYTE blen, void *buf)
 {
 	struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf;
 	int	result;
 
-	//printk("MS_LibReadExtraBlock --- PhyBlock = %x, PageNum = %x, blen = %x\n", PhyBlock, PageNum, blen);
+	/* printk("MS_LibReadExtraBlock --- PhyBlock = %x,
+		PageNum = %x, blen = %x\n", PhyBlock, PageNum, blen); */
 
-	// Read Extra Data
+	/* Read Extra Data */
 	memset(bcb, 0, sizeof(struct bulk_cb_wrap));
 	bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN);
 	bcb->DataTransferLength = 0x4 * blen;
@@ -688,14 +747,18 @@
 	return USB_STOR_TRANSPORT_GOOD;
 }
 
-//----- MS_LibReadExtra() --------------------------------------------
-int MS_LibReadExtra(struct us_data *us, DWORD PhyBlock, BYTE PageNum, MS_LibTypeExtdat *ExtraDat)
+/*
+ * MS_LibReadExtra()
+ */
+int MS_LibReadExtra(struct us_data *us, DWORD PhyBlock,
+		BYTE PageNum, MS_LibTypeExtdat *ExtraDat)
 {
 	struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf;
 	int	result;
 	BYTE	ExtBuf[4];
 
-	//printk("MS_LibReadExtra --- PhyBlock = %x, PageNum = %x\n", PhyBlock, PageNum);
+	/* printk("MS_LibReadExtra --- PhyBlock = %x, PageNum = %x\n"
+						, PhyBlock, PageNum); */
 	memset(bcb, 0, sizeof(struct bulk_cb_wrap));
 	bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN);
 	bcb->DataTransferLength = 0x4;
@@ -707,23 +770,25 @@
 	bcb->CDB[3]			= (BYTE)(PhyBlock>>8);
 	bcb->CDB[2]			= (BYTE)(PhyBlock>>16);
 	bcb->CDB[6]			= 0x01;
-	
+
 	result = ENE_SendScsiCmd(us, FDIR_READ, &ExtBuf, 0);
 	if (result != USB_STOR_XFER_GOOD)
 		return USB_STOR_TRANSPORT_ERROR;
 
 	ExtraDat->reserved = 0;
-	ExtraDat->intr     = 0x80;  // Not yet, waiting for fireware support
-	ExtraDat->status0  = 0x10;  // Not yet, waiting for fireware support
-	ExtraDat->status1  = 0x00;  // Not yet, waiting for fireware support
+	ExtraDat->intr     = 0x80;  /* Not yet, waiting for fireware support */
+	ExtraDat->status0  = 0x10;  /* Not yet, waiting for fireware support */
+	ExtraDat->status1  = 0x00;  /* Not yet, waiting for fireware support */
 	ExtraDat->ovrflg   = ExtBuf[0];
 	ExtraDat->mngflg   = ExtBuf[1];
 	ExtraDat->logadr   = MemStickLogAddr(ExtBuf[2], ExtBuf[3]);
-	
+
 	return USB_STOR_TRANSPORT_GOOD;
 }
 
-//----- MS_LibSetAcquiredErrorBlock() --------------------------------
+/*
+ * MS_LibSetAcquiredErrorBlock()
+ */
 int MS_LibSetAcquiredErrorBlock(struct us_data *us, WORD phyblk)
 {
 	WORD log;
@@ -731,7 +796,9 @@
 	if (phyblk >= us->MS_Lib.NumberOfPhyBlock)
 		return (DWORD)-1;
 
-	if ((log = us->MS_Lib.Phy2LogMap[phyblk]) < us->MS_Lib.NumberOfLogBlock)
+	log = us->MS_Lib.Phy2LogMap[phyblk];
+
+	if (log  < us->MS_Lib.NumberOfLogBlock)
 		us->MS_Lib.Log2PhyMap[log] = MS_LB_NOT_USED;
 
 	if (us->MS_Lib.Phy2LogMap[phyblk] != MS_LB_INITIAL_ERROR)
@@ -740,7 +807,9 @@
 	return 0;
 }
 
-//----- MS_LibErasePhyBlock() ----------------------------------------
+/*
+ * MS_LibErasePhyBlock()
+ */
 int MS_LibErasePhyBlock(struct us_data *us, WORD phyblk)
 {
 	WORD  log;
@@ -748,27 +817,27 @@
 	if (phyblk >= us->MS_Lib.NumberOfPhyBlock)
 		return MS_STATUS_ERROR;
 
-	if ((log = us->MS_Lib.Phy2LogMap[phyblk]) < us->MS_Lib.NumberOfLogBlock)
+	log = us->MS_Lib.Phy2LogMap[phyblk];
+
+	if (log < us->MS_Lib.NumberOfLogBlock)
 		us->MS_Lib.Log2PhyMap[log] = MS_LB_NOT_USED;
 
 	us->MS_Lib.Phy2LogMap[phyblk] = MS_LB_NOT_USED;
 
-	if (MS_LibIsWritable(us))
-	{
-		switch (MS_ReaderEraseBlock(us, phyblk))
-		{
-			case MS_STATUS_SUCCESS:
-				us->MS_Lib.Phy2LogMap[phyblk] = MS_LB_NOT_USED_ERASED;
-				return MS_STATUS_SUCCESS;
-			case MS_ERROR_FLASH_ERASE:
-			case MS_STATUS_INT_ERROR :
-				MS_LibErrorPhyBlock(us, phyblk);
-				return MS_ERROR_FLASH_ERASE;
-			case MS_STATUS_ERROR:
-			default:
-				MS_LibCtrlSet(us, MS_LIB_CTRL_RDONLY);
-				MS_LibSetAcquiredErrorBlock(us, phyblk);
-				return MS_STATUS_ERROR;
+	if (MS_LibIsWritable(us)) {
+		switch (MS_ReaderEraseBlock(us, phyblk)) {
+		case MS_STATUS_SUCCESS:
+			us->MS_Lib.Phy2LogMap[phyblk] = MS_LB_NOT_USED_ERASED;
+			return MS_STATUS_SUCCESS;
+		case MS_ERROR_FLASH_ERASE:
+		case MS_STATUS_INT_ERROR:
+			MS_LibErrorPhyBlock(us, phyblk);
+			return MS_ERROR_FLASH_ERASE;
+		case MS_STATUS_ERROR:
+		default:
+			MS_LibCtrlSet(us, MS_LIB_CTRL_RDONLY);
+			MS_LibSetAcquiredErrorBlock(us, phyblk);
+			return MS_STATUS_ERROR;
 		}
 	}
 
@@ -777,28 +846,35 @@
 	return MS_STATUS_SUCCESS;
 }
 
-//----- MS_LibErrorPhyBlock() ----------------------------------------
+/*
+ * MS_LibErrorPhyBlock()
+ */
 int MS_LibErrorPhyBlock(struct us_data *us, WORD phyblk)
 {
-    if (phyblk >= us->MS_Lib.NumberOfPhyBlock)
-        return MS_STATUS_ERROR;
+	if (phyblk >= us->MS_Lib.NumberOfPhyBlock)
+		return MS_STATUS_ERROR;
 
-    MS_LibSetAcquiredErrorBlock(us, phyblk);
+	MS_LibSetAcquiredErrorBlock(us, phyblk);
 
-    if (MS_LibIsWritable(us))
-        return MS_LibOverwriteExtra(us, phyblk, 0, (BYTE)(~MS_REG_OVR_BKST));
+	if (MS_LibIsWritable(us))
+		return MS_LibOverwriteExtra(us, phyblk, 0,
+				(BYTE)(~MS_REG_OVR_BKST & BYTE_MASK));
 
 
-    return MS_STATUS_SUCCESS;
+	return MS_STATUS_SUCCESS;
 }
 
-//----- MS_LibOverwriteExtra() ---------------------------------------
-int MS_LibOverwriteExtra(struct us_data *us, DWORD PhyBlockAddr, BYTE PageNum, BYTE OverwriteFlag)
+/*
+ * MS_LibOverwriteExtra()
+ */
+int MS_LibOverwriteExtra(struct us_data *us, DWORD PhyBlockAddr,
+				BYTE PageNum, BYTE OverwriteFlag)
 {
 	struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf;
 	int	result;
 
-	//printk("MS --- MS_LibOverwriteExtra,  PhyBlockAddr = %x, PageNum = %x\n", PhyBlockAddr, PageNum);
+	/* printk("MS --- MS_LibOverwriteExtra,  \
+		PhyBlockAddr = %x, PageNum = %x\n", PhyBlockAddr, PageNum); */
 	result = ENE_LoadBinCode(us, MS_RW_PATTERN);
 	if (result != USB_STOR_XFER_GOOD)
 		return USB_STOR_TRANSPORT_ERROR;
@@ -817,7 +893,7 @@
 	bcb->CDB[7]			= 0xFF;
 	bcb->CDB[8]			= 0xFF;
 	bcb->CDB[9]			= 0xFF;
-	
+
 	result = ENE_SendScsiCmd(us, FDIR_READ, NULL, 0);
 	if (result != USB_STOR_XFER_GOOD)
 		return USB_STOR_TRANSPORT_ERROR;
@@ -825,13 +901,16 @@
 	return USB_STOR_TRANSPORT_GOOD;
 }
 
-//----- MS_LibForceSetLogicalPair() ----------------------------------
+/*
+ * MS_LibForceSetLogicalPair()
+ */
 int MS_LibForceSetLogicalPair(struct us_data *us, WORD logblk, WORD phyblk)
 {
 	if (logblk == MS_LB_NOT_USED)
 		return 0;
 
-	if ((logblk >= us->MS_Lib.NumberOfLogBlock) || (phyblk >= us->MS_Lib.NumberOfPhyBlock))
+	if ((logblk >= us->MS_Lib.NumberOfLogBlock) ||
+		(phyblk >= us->MS_Lib.NumberOfPhyBlock))
 		return (DWORD)-1;
 
 	us->MS_Lib.Phy2LogMap[phyblk] = logblk;
@@ -840,10 +919,13 @@
 	return 0;
 }
 
-//----- MS_LibSetLogicalPair() ---------------------------------------
+/*
+ * MS_LibSetLogicalPair()
+ */
 int MS_LibSetLogicalPair(struct us_data *us, WORD logblk, WORD phyblk)
 {
-	if ((logblk >= us->MS_Lib.NumberOfLogBlock) || (phyblk >= us->MS_Lib.NumberOfPhyBlock))
+	if ((logblk >= us->MS_Lib.NumberOfLogBlock) ||
+		(phyblk >= us->MS_Lib.NumberOfPhyBlock))
 		return (DWORD)-1;
 
 	us->MS_Lib.Phy2LogMap[phyblk] = logblk;
@@ -852,28 +934,30 @@
 	return 0;
 }
 
-//----- MS_CountFreeBlock() ------------------------------------------
+/*
+ * MS_CountFreeBlock()
+ */
 int MS_CountFreeBlock(struct us_data *us, WORD PhyBlock)
 {
 	DWORD Ende, Count;
 
 	Ende = PhyBlock + MS_PHYSICAL_BLOCKS_PER_SEGMENT;
-	for (Count = 0; PhyBlock < Ende; PhyBlock++)
-	{
-		switch (us->MS_Lib.Phy2LogMap[PhyBlock])
-		{
-			case MS_LB_NOT_USED:
-			case MS_LB_NOT_USED_ERASED:
-				Count++;
-			default:
-				break;
+	for (Count = 0; PhyBlock < Ende; PhyBlock++) {
+		switch (us->MS_Lib.Phy2LogMap[PhyBlock]) {
+		case MS_LB_NOT_USED:
+		case MS_LB_NOT_USED_ERASED:
+			Count++;
+		default:
+			break;
 		}
 	}
 
 	return Count;
 }
 
-//----- MS_LibSearchBlockFromPhysical() ------------------------------
+/*
+ * MS_LibSearchBlockFromPhysical()
+ */
 int MS_LibSearchBlockFromPhysical(struct us_data *us, WORD phyblk)
 {
 	WORD			Newblk;
@@ -883,70 +967,68 @@
 	if (phyblk >= us->MS_Lib.NumberOfPhyBlock)
 		return MS_LB_ERROR;
 
-	for (blk = phyblk + 1; blk != phyblk; blk++)
-	{
+	for (blk = phyblk + 1; blk != phyblk; blk++) {
 		if ((blk & MS_PHYSICAL_BLOCKS_PER_SEGMENT_MASK) == 0)
 			blk -= MS_PHYSICAL_BLOCKS_PER_SEGMENT;
 
 		Newblk = us->MS_Lib.Phy2LogMap[blk];
 		if (us->MS_Lib.Phy2LogMap[blk] == MS_LB_NOT_USED_ERASED)
 			return blk;
-		else if (us->MS_Lib.Phy2LogMap[blk] == MS_LB_NOT_USED)
-		{
-			switch (MS_LibReadExtra(us, blk, 0, &extdat))
-			{
-				case MS_STATUS_SUCCESS :
-				case MS_STATUS_SUCCESS_WITH_ECC:
-					break;
-				case MS_NOCARD_ERROR:
-					return MS_NOCARD_ERROR;
-				case MS_STATUS_INT_ERROR:
-					return MS_LB_ERROR;
-				case MS_ERROR_FLASH_READ:
-				default:
-					MS_LibSetAcquiredErrorBlock(us, blk);     // MS_LibErrorPhyBlock(fdoExt, blk);
-					continue;
-			} // End switch
+		else if (us->MS_Lib.Phy2LogMap[blk] == MS_LB_NOT_USED) {
+			switch (MS_LibReadExtra(us, blk, 0, &extdat)) {
+			case MS_STATUS_SUCCESS:
+			case MS_STATUS_SUCCESS_WITH_ECC:
+				break;
+			case MS_NOCARD_ERROR:
+				return MS_NOCARD_ERROR;
+			case MS_STATUS_INT_ERROR:
+				return MS_LB_ERROR;
+			case MS_ERROR_FLASH_READ:
+			default:
+				MS_LibSetAcquiredErrorBlock(us, blk);
+				/* MS_LibErrorPhyBlock(fdoExt, blk); */
+				continue;
+			} /* End switch */
 
-			if ((extdat.ovrflg & MS_REG_OVR_BKST) != MS_REG_OVR_BKST_OK)
-			{
+			if ((extdat.ovrflg & MS_REG_OVR_BKST) !=
+						MS_REG_OVR_BKST_OK) {
 				MS_LibSetAcquiredErrorBlock(us, blk);
 				continue;
 			}
 
-			switch (MS_LibErasePhyBlock(us, blk))
-			{
-				case MS_STATUS_SUCCESS:
-					return blk;
-				case MS_STATUS_ERROR:
-					return MS_LB_ERROR;
-				case MS_ERROR_FLASH_ERASE:
-				default:
-					MS_LibErrorPhyBlock(us, blk);
-					break;
+			switch (MS_LibErasePhyBlock(us, blk)) {
+			case MS_STATUS_SUCCESS:
+				return blk;
+			case MS_STATUS_ERROR:
+				return MS_LB_ERROR;
+			case MS_ERROR_FLASH_ERASE:
+			default:
+				MS_LibErrorPhyBlock(us, blk);
+				break;
 			}
 		}
-	} // End for
+	} /* End for */
 
 	return MS_LB_ERROR;
 }
 
-//----- MS_LibSearchBlockFromLogical() -------------------------------
+/*
+ * MS_LibSearchBlockFromLogical()
+ */
 int MS_LibSearchBlockFromLogical(struct us_data *us, WORD logblk)
 {
 	WORD phyblk;
 
-	if ((phyblk=MS_LibConv2Physical(us, logblk)) >= MS_LB_ERROR)
-	{
+	phyblk = MS_LibConv2Physical(us, logblk);
+	if (phyblk >= MS_LB_ERROR) {
 		if (logblk >= us->MS_Lib.NumberOfLogBlock)
 			return MS_LB_ERROR;
 
-		phyblk = (logblk + MS_NUMBER_OF_BOOT_BLOCK) / MS_LOGICAL_BLOCKS_PER_SEGMENT;
+		phyblk = (logblk + MS_NUMBER_OF_BOOT_BLOCK) /
+					MS_LOGICAL_BLOCKS_PER_SEGMENT;
 		phyblk *= MS_PHYSICAL_BLOCKS_PER_SEGMENT;
 		phyblk += MS_PHYSICAL_BLOCKS_PER_SEGMENT - 1;
 	}
 
 	return MS_LibSearchBlockFromPhysical(us, phyblk);
 }
-
-
diff -druN linux-2.6.39-libre/drivers/staging/keucr/ms.h linux-3.0-rc7-libre/drivers/staging/keucr/ms.h
--- linux-2.6.39-libre/drivers/staging/keucr/ms.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/keucr/ms.h	2011-07-11 19:51:52.000000000 -0400
@@ -4,41 +4,41 @@
 #include <linux/blkdev.h>
 #include "common.h"
 
-// MemoryStick Register
-// Status Register 0
-#define MS_REG_ST0_MB                           0x80    // media busy
-#define MS_REG_ST0_FB0                          0x40    // flush busy 0
-#define MS_REG_ST0_BE                           0x20    // buffer empty
-#define MS_REG_ST0_BF                           0x10    // buffer full
-#define MS_REG_ST0_SL                           0x02    // sleep
-#define MS_REG_ST0_WP                           0x01    // write protected
+/* MemoryStick Register */
+/* Status Register 0 */
+#define MS_REG_ST0_MB                           0x80    /* media busy */
+#define MS_REG_ST0_FB0                          0x40    /* flush busy 0 */
+#define MS_REG_ST0_BE                           0x20    /* buffer empty */
+#define MS_REG_ST0_BF                           0x10    /* buffer full */
+#define MS_REG_ST0_SL                           0x02    /* sleep */
+#define MS_REG_ST0_WP                           0x01    /* write protected */
 #define MS_REG_ST0_WP_ON                        MS_REG_ST0_WP
 #define MS_REG_ST0_WP_OFF                       0x00
 
-// Status Register 1
-#define MS_REG_ST1_MB                           0x80    // media busy
-#define MS_REG_ST1_FB1                          0x40    // flush busy 1
-#define MS_REG_ST1_DTER                         0x20    // error on data(corrected)
-#define MS_REG_ST1_UCDT                         0x10    // unable to correct data
-#define MS_REG_ST1_EXER                         0x08    // error on extra(corrected)
-#define MS_REG_ST1_UCEX                         0x04    // unable to correct extra
-#define MS_REG_ST1_FGER                         0x02    // error on overwrite flag(corrected)
-#define MS_REG_ST1_UCFG                         0x01    // unable to correct overwrite flag
-#define MS_REG_ST1_DEFAULT                      (MS_REG_ST1_MB   | MS_REG_ST1_FB1  | \
-                                                 MS_REG_ST1_DTER | MS_REG_ST1_UCDT | \
-                                                 MS_REG_ST1_EXER | MS_REG_ST1_UCEX | \
-                                                 MS_REG_ST1_FGER | MS_REG_ST1_UCFG)
+/* Status Register 1 */
+#define MS_REG_ST1_MB		0x80    /* media busy */
+#define MS_REG_ST1_FB1		0x40    /* flush busy 1 */
+#define MS_REG_ST1_DTER		0x20    /* error on data(corrected) */
+#define MS_REG_ST1_UCDT		0x10    /* unable to correct data */
+#define MS_REG_ST1_EXER		0x08    /* error on extra(corrected) */
+#define MS_REG_ST1_UCEX		0x04    /* unable to correct extra */
+#define MS_REG_ST1_FGER		0x02    /* error on overwrite flag(corrected) */
+#define MS_REG_ST1_UCFG		0x01    /* unable to correct overwrite flag */
+#define MS_REG_ST1_DEFAULT	(MS_REG_ST1_MB   | MS_REG_ST1_FB1  | \
+				MS_REG_ST1_DTER | MS_REG_ST1_UCDT | \
+				MS_REG_ST1_EXER | MS_REG_ST1_UCEX | \
+				MS_REG_ST1_FGER | MS_REG_ST1_UCFG)
 
-// System Parameter
-#define MS_REG_SYSPAR_BAMD                      0x80                // block address mode
-#define MS_REG_SYSPAR_BAND_LINEAR               MS_REG_SYSPAR_BAMD  //   linear mode
-#define MS_REG_SYSPAR_BAND_CHIP                 0x00                //  chip mode
-#define MS_REG_SYSPAR_ATEN                      0x40                // attribute ROM enable
-#define MS_REG_SYSPAR_ATEN_ENABLE               MS_REG_SYSPAR_ATEN  //  enable
-#define MS_REG_SYSPAR_ATEN_DISABLE              0x00                //  disable
+/* System Parameter */
+#define MS_REG_SYSPAR_BAMD		0x80	/* block address mode */
+#define MS_REG_SYSPAR_BAND_LINEAR	MS_REG_SYSPAR_BAMD  /*   linear mode */
+#define MS_REG_SYSPAR_BAND_CHIP		0x00	/*  chip mode */
+#define MS_REG_SYSPAR_ATEN		0x40	/* attribute ROM enable */
+#define MS_REG_SYSPAR_ATEN_ENABLE	MS_REG_SYSPAR_ATEN	/*  enable */
+#define MS_REG_SYSPAR_ATEN_DISABLE	0x00	/*  disable */
 #define MS_REG_SYSPAR_RESERVED                  0x2f
 
-// Command Parameter
+/* Command Parameter */
 #define MS_REG_CMDPAR_CP2                       0x80
 #define MS_REG_CMDPAR_CP1                       0x40
 #define MS_REG_CMDPAR_CP0                       0x20
@@ -48,44 +48,44 @@
 #define MS_REG_CMDPAR_OVERWRITE                 MS_REG_CMDPAR_CP2
 #define MS_REG_CMDPAR_RESERVED                  0x1f
 
-// Overwrite Area
-#define MS_REG_OVR_BKST                         0x80            // block status
-#define MS_REG_OVR_BKST_OK                      MS_REG_OVR_BKST     // OK
-#define MS_REG_OVR_BKST_NG                      0x00            // NG
-#define MS_REG_OVR_PGST0                        0x40            // page status
+/* Overwrite Area */
+#define MS_REG_OVR_BKST		0x80            /* block status */
+#define MS_REG_OVR_BKST_OK                      MS_REG_OVR_BKST     /* OK */
+#define MS_REG_OVR_BKST_NG                      0x00            /* NG */
+#define MS_REG_OVR_PGST0	0x40            /* page status */
 #define MS_REG_OVR_PGST1                        0x20
-#define MS_REG_OVR_PGST_MASK                    (MS_REG_OVR_PGST0 | MS_REG_OVR_PGST1)
-#define MS_REG_OVR_PGST_OK                      (MS_REG_OVR_PGST0 | MS_REG_OVR_PGST1) // OK
-#define MS_REG_OVR_PGST_NG                      MS_REG_OVR_PGST1                      // NG
-#define MS_REG_OVR_PGST_DATA_ERROR              0x00        // data error
-#define MS_REG_OVR_UDST                         0x10        // update status
-#define MS_REG_OVR_UDST_UPDATING                0x00        // updating
+#define MS_REG_OVR_PGST_MASK	(MS_REG_OVR_PGST0 | MS_REG_OVR_PGST1)
+#define MS_REG_OVR_PGST_OK	(MS_REG_OVR_PGST0 | MS_REG_OVR_PGST1) /* OK */
+#define MS_REG_OVR_PGST_NG	MS_REG_OVR_PGST1                      /* NG */
+#define MS_REG_OVR_PGST_DATA_ERROR              0x00        /* data error */
+#define MS_REG_OVR_UDST                         0x10        /* update status */
+#define MS_REG_OVR_UDST_UPDATING                0x00        /* updating */
 #define MS_REG_OVR_UDST_NO_UPDATE               MS_REG_OVR_UDST
 #define MS_REG_OVR_RESERVED                     0x08
 #define MS_REG_OVR_DEFAULT                      (MS_REG_OVR_BKST_OK |      \
-                                                 MS_REG_OVR_PGST_OK |      \
-                                                 MS_REG_OVR_UDST_NO_UPDATE |   \
-                                                 MS_REG_OVR_RESERVED)
-// Management Flag
-#define MS_REG_MNG_SCMS0                        0x20    // serial copy management system
+						MS_REG_OVR_PGST_OK |      \
+						MS_REG_OVR_UDST_NO_UPDATE |   \
+						MS_REG_OVR_RESERVED)
+/* Management Flag */
+#define MS_REG_MNG_SCMS0	0x20    /* serial copy management system */
 #define MS_REG_MNG_SCMS1                        0x10
-#define MS_REG_MNG_SCMS_MASK                    (MS_REG_MNG_SCMS0 | MS_REG_MNG_SCMS1)
-#define MS_REG_MNG_SCMS_COPY_OK                 (MS_REG_MNG_SCMS0 | MS_REG_MNG_SCMS1)
+#define MS_REG_MNG_SCMS_MASK		(MS_REG_MNG_SCMS0 | MS_REG_MNG_SCMS1)
+#define MS_REG_MNG_SCMS_COPY_OK		(MS_REG_MNG_SCMS0 | MS_REG_MNG_SCMS1)
 #define MS_REG_MNG_SCMS_ONE_COPY                MS_REG_MNG_SCMS1
 #define MS_REG_MNG_SCMS_NO_COPY                 0x00
-#define MS_REG_MNG_ATFLG                        0x08    // address transfer table flag
-#define MS_REG_MNG_ATFLG_OTHER                  MS_REG_MNG_ATFLG    // other
-#define MS_REG_MNG_ATFLG_ATTBL                  0x00    // address transfer table
-#define MS_REG_MNG_SYSFLG                       0x04    // system flag
-#define MS_REG_MNG_SYSFLG_USER                  MS_REG_MNG_SYSFLG   // user block
-#define MS_REG_MNG_SYSFLG_BOOT                  0x00            // system block
+#define MS_REG_MNG_ATFLG	0x08	/* address transfer table flag */
+#define MS_REG_MNG_ATFLG_OTHER                  MS_REG_MNG_ATFLG    /* other */
+#define MS_REG_MNG_ATFLG_ATTBL		0x00	/* address transfer table */
+#define MS_REG_MNG_SYSFLG                       0x04    /* system flag */
+#define MS_REG_MNG_SYSFLG_USER		MS_REG_MNG_SYSFLG   /* user block */
+#define MS_REG_MNG_SYSFLG_BOOT                  0x00    /* system block */
 #define MS_REG_MNG_RESERVED                     0xc3
 #define MS_REG_MNG_DEFAULT		(MS_REG_MNG_SCMS_COPY_OK |	\
 					 MS_REG_MNG_ATFLG_OTHER |	\
 					 MS_REG_MNG_SYSFLG_USER |	\
 					 MS_REG_MNG_RESERVED)
 
-// Error codes
+/* Error codes */
 #define MS_STATUS_SUCCESS                       0x0000
 #define MS_ERROR_OUT_OF_SPACE                   0x0103
 #define MS_STATUS_WRITE_PROTECT                 0x0106
@@ -110,29 +110,41 @@
 #define MS_LB_ACQUIRED_ERROR                    0xfff4
 #define MS_LB_NOT_USED_ERASED                   0xfff5
 
-#define MS_LibConv2Physical(pdx, LogBlock)      (((LogBlock) >= (pdx)->MS_Lib.NumberOfLogBlock) ? MS_STATUS_ERROR : (pdx)->MS_Lib.Log2PhyMap[LogBlock])
-#define MS_LibConv2Logical(pdx, PhyBlock)       (((PhyBlock) >= (pdx)->MS_Lib.NumberOfPhyBlock) ? MS_STATUS_ERROR : (pdx)->MS_Lib.Phy2LogMap[PhyBlock]) //�dphy->log table
+#define MS_LibConv2Physical(pdx, LogBlock) \
+	(((LogBlock) >= (pdx)->MS_Lib.NumberOfLogBlock) ? \
+	MS_STATUS_ERROR : (pdx)->MS_Lib.Log2PhyMap[LogBlock])
+#define MS_LibConv2Logical(pdx, PhyBlock) \
+	(((PhyBlock) >= (pdx)->MS_Lib.NumberOfPhyBlock) ? \
+	MS_STATUS_ERROR : (pdx)->MS_Lib.Phy2LogMap[PhyBlock])
+	/*dphy->log table */
 
 #define MS_LIB_CTRL_RDONLY                      0
 #define MS_LIB_CTRL_WRPROTECT                   1
-#define MS_LibCtrlCheck(pdx, Flag)              ((pdx)->MS_Lib.flags & (1 << (Flag)))
+#define MS_LibCtrlCheck(pdx, Flag)	((pdx)->MS_Lib.flags & (1 << (Flag)))
 
-#define MS_LibCtrlSet(pdx, Flag)                (pdx)->MS_Lib.flags |= (1 << (Flag))
-#define MS_LibCtrlReset(pdx, Flag)              (pdx)->MS_Lib.flags &= ~(1 << (Flag))
-#define MS_LibIsWritable(pdx)                   ((MS_LibCtrlCheck((pdx), MS_LIB_CTRL_RDONLY) == 0) && (MS_LibCtrlCheck(pdx, MS_LIB_CTRL_WRPROTECT) == 0))
+#define MS_LibCtrlSet(pdx, Flag)	((pdx)->MS_Lib.flags |= (1 << (Flag)))
+#define MS_LibCtrlReset(pdx, Flag)	((pdx)->MS_Lib.flags &= ~(1 << (Flag)))
+#define MS_LibIsWritable(pdx) \
+	((MS_LibCtrlCheck((pdx), MS_LIB_CTRL_RDONLY) == 0) && \
+	(MS_LibCtrlCheck(pdx, MS_LIB_CTRL_WRPROTECT) == 0))
 
 #define MS_MAX_PAGES_PER_BLOCK                  32
 #define MS_LIB_BITS_PER_BYTE                    8
 
-#define MS_LibPageMapIdx(n)                     ((n) / MS_LIB_BITS_PER_BYTE)
-#define MS_LibPageMapBit(n)                     (1 << ((n) % MS_LIB_BITS_PER_BYTE))
-#define MS_LibCheckPageMapBit(pdx, n)           ((pdx)->MS_Lib.pagemap[MS_LibPageMapIdx(n)] & MS_LibPageMapBit(n))
-#define MS_LibSetPageMapBit(pdx, n)             ((pdx)->MS_Lib.pagemap[MS_LibPageMapIdx(n)] |= MS_LibPageMapBit(n))
-#define MS_LibResetPageMapBit(pdx, n)           ((pdx)->MS_Lib.pagemap[MS_LibPageMapIdx(n)] &= ~MS_LibPageMapBit(n))
-#define MS_LibClearPageMap(pdx)                 memset((pdx)->MS_Lib.pagemap, 0, sizeof((pdx)->MS_Lib.pagemap))
+#define MS_LibPageMapIdx(n) ((n) / MS_LIB_BITS_PER_BYTE)
+#define MS_LibPageMapBit(n) (1 << ((n) % MS_LIB_BITS_PER_BYTE))
+#define MS_LibCheckPageMapBit(pdx, n) \
+	((pdx)->MS_Lib.pagemap[MS_LibPageMapIdx(n)] & MS_LibPageMapBit(n))
+#define MS_LibSetPageMapBit(pdx, n) \
+	((pdx)->MS_Lib.pagemap[MS_LibPageMapIdx(n)] |= MS_LibPageMapBit(n))
+#define MS_LibResetPageMapBit(pdx, n) \
+	((pdx)->MS_Lib.pagemap[MS_LibPageMapIdx(n)] &= ~MS_LibPageMapBit(n))
+#define MS_LibClearPageMap(pdx) \
+	memset((pdx)->MS_Lib.pagemap, 0, sizeof((pdx)->MS_Lib.pagemap))
 
 
-#define MemStickLogAddr(logadr1, logadr0)       ((((WORD)(logadr1)) << 8) | (logadr0))
+#define MemStickLogAddr(logadr1, logadr0) \
+	((((WORD)(logadr1)) << 8) | (logadr0))
 
 #define MS_BYTES_PER_PAGE                       512
 
@@ -144,7 +156,7 @@
 #define MS_NUMBER_OF_SYSTEM_BLOCK               4
 #define MS_LOGICAL_BLOCKS_PER_SEGMENT           496
 #define MS_LOGICAL_BLOCKS_IN_1ST_SEGMENT        494
-#define MS_PHYSICAL_BLOCKS_PER_SEGMENT          0x200   // 512
+#define MS_PHYSICAL_BLOCKS_PER_SEGMENT          0x200   /* 512 */
 #define MS_PHYSICAL_BLOCKS_PER_SEGMENT_MASK     0x1ff
 
 #define MS_SECTOR_SIZE                          512
@@ -165,51 +177,53 @@
 #define MS_SYSINF_SECURITY                      0x01
 #define MS_SYSINF_SECURITY_NO_SUPPORT           MS_SYSINF_SECURITY
 #define MS_SYSINF_SECURITY_SUPPORT              0
-#define MS_SYSINF_FORMAT_MAT                    0   // ?
+#define MS_SYSINF_FORMAT_MAT                    0   /* ? */
 #define MS_SYSINF_FORMAT_FAT                    1
 #define MS_SYSINF_USAGE_GENERAL                 0
-#define MS_SYSINF_PAGE_SIZE                     MS_BYTES_PER_PAGE // fixed
+#define MS_SYSINF_PAGE_SIZE                     MS_BYTES_PER_PAGE /* fixed */
 #define MS_SYSINF_RESERVED1                     1
 #define MS_SYSINF_RESERVED2                     1
 
 #define MS_SYSENT_TYPE_INVALID_BLOCK            0x01
-#define MS_SYSENT_TYPE_CIS_IDI                  0x0a    // CIS/IDI
+#define MS_SYSENT_TYPE_CIS_IDI                  0x0a    /* CIS/IDI */
 
 #define SIZE_OF_KIRO                            1024
 
-// BOOT BLOCK
+/* BOOT BLOCK */
 #define MS_NUMBER_OF_SYSTEM_ENTRY               4
 
-//----- MemStickRegisters --------------------------------------------
-// Status registers (16 bytes)
+/*
+ * MemStickRegisters
+ */
+/* Status registers (16 bytes) */
 typedef struct {
-	BYTE Reserved0;		// 00
-	BYTE INTRegister;	// 01
-	BYTE StatusRegister0;	// 02
-	BYTE StatusRegister1;	// 03
-	BYTE Reserved1[12];	// 04-0F
+	BYTE Reserved0;		/* 00 */
+	BYTE INTRegister;	/* 01 */
+	BYTE StatusRegister0;	/* 02 */
+	BYTE StatusRegister1;	/* 03 */
+	BYTE Reserved1[12];	/* 04-0F */
 } MemStickStatusRegisters;
 
-// Parameter registers (6 bytes)
+/* Parameter registers (6 bytes) */
 typedef struct {
-	BYTE SystemParameter;	// 10
-	BYTE BlockAddress2;	// 11
-	BYTE BlockAddress1;	// 12
-	BYTE BlockAddress0;	// 13
-	BYTE CMDParameter;	// 14
-	BYTE PageAddress;	// 15
+	BYTE SystemParameter;	/* 10 */
+	BYTE BlockAddress2;	/* 11 */
+	BYTE BlockAddress1;	/* 12 */
+	BYTE BlockAddress0;	/* 13 */
+	BYTE CMDParameter;	/* 14 */
+	BYTE PageAddress;	/* 15 */
 } MemStickParameterRegisters;
 
-// Extra registers (9 bytes)
+/* Extra registers (9 bytes) */
 typedef struct {
-	BYTE OverwriteFlag;	// 16
-	BYTE ManagementFlag;	// 17
-	BYTE LogicalAddress1;	// 18
-	BYTE LogicalAddress0;	// 19
-	BYTE ReservedArea[5];	// 1A-1E
+	BYTE OverwriteFlag;	/* 16 */
+	BYTE ManagementFlag;	/* 17 */
+	BYTE LogicalAddress1;	/* 18 */
+	BYTE LogicalAddress0;	/* 19 */
+	BYTE ReservedArea[5];	/* 1A-1E */
 } MemStickExtraDataRegisters;
 
-// All registers in Memory Stick (32 bytes, includes 1 byte padding)
+/* All registers in Memory Stick (32 bytes, includes 1 byte padding) */
 typedef struct {
 	MemStickStatusRegisters status;
 	MemStickParameterRegisters param;
@@ -217,7 +231,9 @@
 	BYTE padding;
 } MemStickRegisters, *PMemStickRegisters;
 
-//----- MemStickBootBlockPage0 ---------------------------------------
+/*
+ * MemStickBootBlockPage0
+ */
 typedef struct {
 	WORD wBlockID;
 	WORD wFormatVersion;
@@ -238,13 +254,13 @@
 } MemStickBootBlockSysEnt;
 
 typedef struct {
-	BYTE bMsClass;		// must be 1
-	BYTE bCardType;		// see below
-	WORD wBlockSize;	// n KB
-	WORD wBlockNumber;	// number of physical block
-	WORD wTotalBlockNumber;	// number of logical block
-	WORD wPageSize;		// must be 0x200
-	BYTE bExtraSize;	// 0x10
+	BYTE bMsClass;		/* must be 1 */
+	BYTE bCardType;		/* see below */
+	WORD wBlockSize;	/* n KB */
+	WORD wBlockNumber;	/* number of physical block */
+	WORD wTotalBlockNumber;	/* number of logical block */
+	WORD wPageSize;		/* must be 0x200 */
+	BYTE bExtraSize;	/* 0x10 */
 	BYTE bSecuritySupport;
 	BYTE bAssemblyDate[8];
 	BYTE bFactoryArea[4];
@@ -258,10 +274,10 @@
 	BYTE bVCC;
 	BYTE bVPP;
 	WORD wControllerChipNumber;
-	WORD wControllerFunction;	// New MS
-	BYTE bReserved3[9];		// New MS
-	BYTE bParallelSupport;		// New MS
-	WORD wFormatValue;		// New MS
+	WORD wControllerFunction;	/* New MS */
+	BYTE bReserved3[9];		/* New MS */
+	BYTE bParallelSupport;		/* New MS */
+	WORD wFormatValue;		/* New MS */
 	BYTE bFormatType;
 	BYTE bUsage;
 	BYTE bDeviceType;
@@ -277,60 +293,62 @@
 	MemStickBootBlockSysInf sysinf;
 } MemStickBootBlockPage0;
 
-//----- MemStickBootBlockCIS_IDI -------------------------------------
+/*
+ * MemStickBootBlockCIS_IDI
+ */
 typedef struct {
-	BYTE bCistplDEVICE[6];            // 0
-	BYTE bCistplDEVICE0C[6];          // 6
-	BYTE bCistplJEDECC[4];            // 12
-	BYTE bCistplMANFID[6];            // 16
-	BYTE bCistplVER1[32];             // 22
-	BYTE bCistplFUNCID[4];            // 54
-	BYTE bCistplFUNCE0[4];            // 58
-	BYTE bCistplFUNCE1[5];            // 62
-	BYTE bCistplCONF[7];              // 67
-	BYTE bCistplCFTBLENT0[10];        // 74
-	BYTE bCistplCFTBLENT1[8];         // 84
-	BYTE bCistplCFTBLENT2[12];        // 92
-	BYTE bCistplCFTBLENT3[8];         // 104
-	BYTE bCistplCFTBLENT4[17];        // 112
-	BYTE bCistplCFTBLENT5[8];         // 129
-	BYTE bCistplCFTBLENT6[17];        // 137
-	BYTE bCistplCFTBLENT7[8];         // 154
-	BYTE bCistplNOLINK[3];            // 162
+	BYTE bCistplDEVICE[6];            /* 0 */
+	BYTE bCistplDEVICE0C[6];          /* 6 */
+	BYTE bCistplJEDECC[4];            /* 12 */
+	BYTE bCistplMANFID[6];            /* 16 */
+	BYTE bCistplVER1[32];             /* 22 */
+	BYTE bCistplFUNCID[4];            /* 54 */
+	BYTE bCistplFUNCE0[4];            /* 58 */
+	BYTE bCistplFUNCE1[5];            /* 62 */
+	BYTE bCistplCONF[7];              /* 67 */
+	BYTE bCistplCFTBLENT0[10];        /* 74 */
+	BYTE bCistplCFTBLENT1[8];         /* 84 */
+	BYTE bCistplCFTBLENT2[12];        /* 92 */
+	BYTE bCistplCFTBLENT3[8];         /* 104 */
+	BYTE bCistplCFTBLENT4[17];        /* 112 */
+	BYTE bCistplCFTBLENT5[8];         /* 129 */
+	BYTE bCistplCFTBLENT6[17];        /* 137 */
+	BYTE bCistplCFTBLENT7[8];         /* 154 */
+	BYTE bCistplNOLINK[3];            /* 162 */
 } MemStickBootBlockCIS;
 
 typedef struct {
 #define MS_IDI_GENERAL_CONF         0x848A
-	WORD wIDIgeneralConfiguration;     // 0
-	WORD wIDInumberOfCylinder;         // 1
-	WORD wIDIreserved0;                // 2
-	WORD wIDInumberOfHead;             // 3
-	WORD wIDIbytesPerTrack;            // 4
-	WORD wIDIbytesPerSector;           // 5
-	WORD wIDIsectorsPerTrack;          // 6
-	WORD wIDItotalSectors[2];          // 7-8  high,low
-	WORD wIDIreserved1[11];            // 9-19
-	WORD wIDIbufferType;               // 20
-	WORD wIDIbufferSize;               // 21
-	WORD wIDIlongCmdECC;               // 22
-	WORD wIDIfirmVersion[4];           // 23-26
-	WORD wIDImodelName[20];            // 27-46
-	WORD wIDIreserved2;                // 47
-	WORD wIDIlongWordSupported;        // 48
-	WORD wIDIdmaSupported;             // 49
-	WORD wIDIreserved3;                // 50
-	WORD wIDIpioTiming;                // 51
-	WORD wIDIdmaTiming;                // 52
-	WORD wIDItransferParameter;        // 53
-	WORD wIDIformattedCylinder;        // 54
-	WORD wIDIformattedHead;            // 55
-	WORD wIDIformattedSectorsPerTrack; // 56
-	WORD wIDIformattedTotalSectors[2]; // 57-58
-	WORD wIDImultiSector;              // 59
-	WORD wIDIlbaSectors[2];            // 60-61
-	WORD wIDIsingleWordDMA;            // 62
-	WORD wIDImultiWordDMA;             // 63
-	WORD wIDIreserved4[192];           // 64-255
+	WORD wIDIgeneralConfiguration;     /* 0 */
+	WORD wIDInumberOfCylinder;         /* 1 */
+	WORD wIDIreserved0;                /* 2 */
+	WORD wIDInumberOfHead;             /* 3 */
+	WORD wIDIbytesPerTrack;            /* 4 */
+	WORD wIDIbytesPerSector;           /* 5 */
+	WORD wIDIsectorsPerTrack;          /* 6 */
+	WORD wIDItotalSectors[2];          /* 7-8  high,low */
+	WORD wIDIreserved1[11];            /* 9-19 */
+	WORD wIDIbufferType;               /* 20 */
+	WORD wIDIbufferSize;               /* 21 */
+	WORD wIDIlongCmdECC;               /* 22 */
+	WORD wIDIfirmVersion[4];           /* 23-26 */
+	WORD wIDImodelName[20];            /* 27-46 */
+	WORD wIDIreserved2;                /* 47 */
+	WORD wIDIlongWordSupported;        /* 48 */
+	WORD wIDIdmaSupported;             /* 49 */
+	WORD wIDIreserved3;                /* 50 */
+	WORD wIDIpioTiming;                /* 51 */
+	WORD wIDIdmaTiming;                /* 52 */
+	WORD wIDItransferParameter;        /* 53 */
+	WORD wIDIformattedCylinder;        /* 54 */
+	WORD wIDIformattedHead;            /* 55 */
+	WORD wIDIformattedSectorsPerTrack; /* 56 */
+	WORD wIDIformattedTotalSectors[2]; /* 57-58 */
+	WORD wIDImultiSector;              /* 59 */
+	WORD wIDIlbaSectors[2];            /* 60-61 */
+	WORD wIDIsingleWordDMA;            /* 62 */
+	WORD wIDImultiWordDMA;             /* 63 */
+	WORD wIDIreserved4[192];           /* 64-255 */
 } MemStickBootBlockIDI;
 
 typedef struct {
@@ -346,7 +364,9 @@
 
 } MemStickBootBlockCIS_IDI;
 
-//----- MS_LibControl ------------------------------------------------
+/*
+ * MS_LibControl
+ */
 typedef struct {
 	BYTE reserved;
 	BYTE intr;
@@ -362,14 +382,14 @@
 	DWORD BytesPerSector;
 	DWORD NumberOfCylinder;
 	DWORD SectorsPerCylinder;
-	WORD cardType;			// R/W, RO, Hybrid
+	WORD cardType;			/* R/W, RO, Hybrid */
 	WORD blockSize;
 	WORD PagesPerBlock;
 	WORD NumberOfPhyBlock;
 	WORD NumberOfLogBlock;
 	WORD NumberOfSegment;
-	WORD *Phy2LogMap;		// phy2log table
-	WORD *Log2PhyMap;		// log2phy table
+	WORD *Phy2LogMap;		/* phy2log table */
+	WORD *Log2PhyMap;		/* log2phy table */
 	WORD wrtblk;
 	BYTE pagemap[(MS_MAX_PAGES_PER_BLOCK + (MS_LIB_BITS_PER_BYTE-1)) /
 		     MS_LIB_BITS_PER_BYTE];
diff -druN linux-2.6.39-libre/drivers/staging/keucr/msscsi.c linux-3.0-rc7-libre/drivers/staging/keucr/msscsi.c
--- linux-2.6.39-libre/drivers/staging/keucr/msscsi.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/keucr/msscsi.c	2011-07-11 19:51:52.000000000 -0400
@@ -1,3 +1,5 @@
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/sched.h>
 #include <linux/errno.h>
 #include <linux/slab.h>
@@ -10,68 +12,48 @@
 #include "scsiglue.h"
 #include "transport.h"
 
-int MS_SCSI_Test_Unit_Ready (struct us_data *us, struct scsi_cmnd *srb);
-int MS_SCSI_Inquiry         (struct us_data *us, struct scsi_cmnd *srb);
-int MS_SCSI_Mode_Sense      (struct us_data *us, struct scsi_cmnd *srb);
-int MS_SCSI_Start_Stop      (struct us_data *us, struct scsi_cmnd *srb);
-int MS_SCSI_Read_Capacity   (struct us_data *us, struct scsi_cmnd *srb);
-int MS_SCSI_Read            (struct us_data *us, struct scsi_cmnd *srb);
-int MS_SCSI_Write           (struct us_data *us, struct scsi_cmnd *srb);
-
-//----- MS_SCSIIrp() --------------------------------------------------
-int MS_SCSIIrp(struct us_data *us, struct scsi_cmnd *srb)
-{
-	int    result;
-
-	us->SrbStatus = SS_SUCCESS;
-	switch (srb->cmnd[0])
-	{
-		case TEST_UNIT_READY :  result = MS_SCSI_Test_Unit_Ready (us, srb);  break; //0x00
-		case INQUIRY         :  result = MS_SCSI_Inquiry         (us, srb);  break; //0x12
-		case MODE_SENSE      :  result = MS_SCSI_Mode_Sense      (us, srb);  break; //0x1A
-		case READ_CAPACITY   :  result = MS_SCSI_Read_Capacity   (us, srb);  break; //0x25
-		case READ_10         :  result = MS_SCSI_Read            (us, srb);  break; //0x28
-		case WRITE_10        :  result = MS_SCSI_Write           (us, srb);  break; //0x2A
-
-		default:
-			us->SrbStatus = SS_ILLEGAL_REQUEST;
-			result = USB_STOR_TRANSPORT_FAILED;
-			break;
-	}
-	return result;
-}
-
-//----- MS_SCSI_Test_Unit_Ready() --------------------------------------------------
+/*
+ * MS_SCSI_Test_Unit_Ready()
+ */
 int MS_SCSI_Test_Unit_Ready(struct us_data *us, struct scsi_cmnd *srb)
 {
-	//printk("MS_SCSI_Test_Unit_Ready\n");
+	/* pr_info("MS_SCSI_Test_Unit_Ready\n"); */
 	if (us->MS_Status.Insert && us->MS_Status.Ready)
 		return USB_STOR_TRANSPORT_GOOD;
-	else
-	{
+	else {
 		ENE_MSInit(us);
 		return USB_STOR_TRANSPORT_GOOD;
 	}
-		
+
 	return USB_STOR_TRANSPORT_GOOD;
 }
 
-//----- MS_SCSI_Inquiry() --------------------------------------------------
+/*
+ * MS_SCSI_Inquiry()
+ */
 int MS_SCSI_Inquiry(struct us_data *us, struct scsi_cmnd *srb)
 {
-	//printk("MS_SCSI_Inquiry\n");
-	BYTE data_ptr[36] = {0x00, 0x80, 0x02, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x55, 0x53, 0x42, 0x32, 0x2E, 0x30, 0x20, 0x20, 0x43, 0x61, 0x72, 0x64, 0x52, 0x65, 0x61, 0x64, 0x65, 0x72, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x30, 0x31, 0x30, 0x30};
+	/* pr_info("MS_SCSI_Inquiry\n"); */
+	BYTE data_ptr[36] = {0x00, 0x80, 0x02, 0x00, 0x1F, 0x00,
+				0x00, 0x00, 0x55, 0x53, 0x42, 0x32,
+				0x2E, 0x30, 0x20, 0x20, 0x43, 0x61,
+				0x72, 0x64, 0x52, 0x65, 0x61, 0x64,
+				0x65, 0x72, 0x20, 0x20, 0x20, 0x20,
+				0x20, 0x20, 0x30, 0x31, 0x30, 0x30};
 
 	usb_stor_set_xfer_buf(us, data_ptr, 36, srb, TO_XFER_BUF);
 	return USB_STOR_TRANSPORT_GOOD;
 }
 
-
-//----- MS_SCSI_Mode_Sense() --------------------------------------------------
+/*
+ * MS_SCSI_Mode_Sense()
+ */
 int MS_SCSI_Mode_Sense(struct us_data *us, struct scsi_cmnd *srb)
 {
-	BYTE	mediaNoWP[12] = {0x0b,0x00,0x00,0x08,0x00,0x00,0x71,0xc0,0x00,0x00,0x02,0x00};
-	BYTE	mediaWP[12]   = {0x0b,0x00,0x80,0x08,0x00,0x00,0x71,0xc0,0x00,0x00,0x02,0x00};
+	BYTE	mediaNoWP[12] = {0x0b, 0x00, 0x00, 0x08, 0x00, 0x00,
+					0x71, 0xc0, 0x00, 0x00, 0x02, 0x00};
+	BYTE	mediaWP[12]   = {0x0b, 0x00, 0x80, 0x08, 0x00, 0x00,
+					0x71, 0xc0, 0x00, 0x00, 0x02, 0x00};
 
 	if (us->MS_Status.WtP)
 		usb_stor_set_xfer_buf(us, mediaWP, 12, srb, TO_XFER_BUF);
@@ -82,7 +64,9 @@
 	return USB_STOR_TRANSPORT_GOOD;
 }
 
-//----- MS_SCSI_Read_Capacity() --------------------------------------------------
+/*
+ * MS_SCSI_Read_Capacity()
+ */
 int MS_SCSI_Read_Capacity(struct us_data *us, struct scsi_cmnd *srb)
 {
 	unsigned int offset = 0;
@@ -91,60 +75,65 @@
 	WORD    bl_len;
 	BYTE    buf[8];
 
-	printk("MS_SCSI_Read_Capacity\n");
+	pr_info("MS_SCSI_Read_Capacity\n");
 
 	bl_len = 0x200;
-	if ( us->MS_Status.IsMSPro )
+	if (us->MS_Status.IsMSPro)
 		bl_num = us->MSP_TotalBlock - 1;
 	else
-		bl_num = us->MS_Lib.NumberOfLogBlock * us->MS_Lib.blockSize * 2 - 1;
+		bl_num = us->MS_Lib.NumberOfLogBlock *
+				us->MS_Lib.blockSize * 2 - 1;
 
 	us->bl_num = bl_num;
-	printk("bl_len = %x\n", bl_len);
-	printk("bl_num = %x\n", bl_num);
+	pr_info("bl_len = %x\n", bl_len);
+	pr_info("bl_num = %x\n", bl_num);
+
+	/* srb->request_bufflen = 8; */
+	buf[0] = (bl_num >> 24) & 0xff;
+	buf[1] = (bl_num >> 16) & 0xff;
+	buf[2] = (bl_num >> 8) & 0xff;
+	buf[3] = (bl_num >> 0) & 0xff;
+	buf[4] = (bl_len >> 24) & 0xff;
+	buf[5] = (bl_len >> 16) & 0xff;
+	buf[6] = (bl_len >> 8) & 0xff;
+	buf[7] = (bl_len >> 0) & 0xff;
 
-	//srb->request_bufflen = 8;
-	buf[0] = (bl_num>>24) & 0xff;
-	buf[1] = (bl_num>>16) & 0xff;
-	buf[2] = (bl_num>> 8) & 0xff;
-	buf[3] = (bl_num>> 0) & 0xff;
-	buf[4] = (bl_len>>24) & 0xff;
-	buf[5] = (bl_len>>16) & 0xff;
-	buf[6] = (bl_len>> 8) & 0xff;
-	buf[7] = (bl_len>> 0) & 0xff;
-	
 	usb_stor_access_xfer_buf(us, buf, 8, srb, &sg, &offset, TO_XFER_BUF);
-	//usb_stor_set_xfer_buf(us, buf, srb->request_bufflen, srb, TO_XFER_BUF);
+	/* usb_stor_set_xfer_buf(us, buf, srb->request_bufflen,
+						srb, TO_XFER_BUF); */
 
 	return USB_STOR_TRANSPORT_GOOD;
 }
 
-//----- MS_SCSI_Read() --------------------------------------------------
+/*
+ * MS_SCSI_Read()
+ */
 int MS_SCSI_Read(struct us_data *us, struct scsi_cmnd *srb)
 {
 	struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf;
-	int result=0;
+	int result = 0;
 	PBYTE	Cdb = srb->cmnd;
-	DWORD bn  =  ((Cdb[2]<<24) & 0xff000000) | ((Cdb[3]<<16) & 0x00ff0000) |
-                   ((Cdb[4]<< 8) & 0x0000ff00) | ((Cdb[5]<< 0) & 0x000000ff);
-	WORD  blen = ((Cdb[7]<< 8) & 0xff00)     | ((Cdb[8]<< 0) & 0x00ff);
+	DWORD bn  =  ((Cdb[2] << 24) & 0xff000000) |
+			((Cdb[3] << 16) & 0x00ff0000) |
+			((Cdb[4] << 8) & 0x0000ff00) |
+			((Cdb[5] << 0) & 0x000000ff);
+	WORD  blen = ((Cdb[7] << 8) & 0xff00) | ((Cdb[8] << 0) & 0x00ff);
 	DWORD	blenByte = blen * 0x200;
 
-	//printk("SCSIOP_READ --- bn = %X, blen = %X, srb->use_sg = %X\n", bn, blen, srb->use_sg);
-	
+	/* pr_info("SCSIOP_READ --- bn = %X, blen = %X, srb->use_sg = %X\n",
+						bn, blen, srb->use_sg); */
+
 	if (bn > us->bl_num)
 		return USB_STOR_TRANSPORT_ERROR;
 
-	if (us->MS_Status.IsMSPro)
-	{
+	if (us->MS_Status.IsMSPro) {
 		result = ENE_LoadBinCode(us, MSP_RW_PATTERN);
-		if (result != USB_STOR_XFER_GOOD)
-		{
-			printk("Load MSP RW pattern Fail !!\n");
+		if (result != USB_STOR_XFER_GOOD) {
+			pr_info("Load MSP RW pattern Fail !!\n");
 			return USB_STOR_TRANSPORT_ERROR;
 		}
 
-		// set up the command wrapper
+		/*  set up the command wrapper */
 		memset(bcb, 0, sizeof(struct bulk_cb_wrap));
 		bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN);
 		bcb->DataTransferLength = blenByte;
@@ -157,11 +146,9 @@
 		bcb->CDB[2] = (BYTE)(bn>>24);
 
 		result = ENE_SendScsiCmd(us, FDIR_READ, scsi_sglist(srb), 1);
-	}
-	else
-	{
+	} else {
 		void	*buf;
-		int	offset=0;
+		int	offset = 0;
 		WORD	phyblk, logblk;
 		BYTE	PageNum;
 		WORD	len;
@@ -172,9 +159,8 @@
 			return USB_STOR_TRANSPORT_ERROR;
 
 		result = ENE_LoadBinCode(us, MS_RW_PATTERN);
-		if (result != USB_STOR_XFER_GOOD)
-		{
-			printk("Load MS RW pattern Fail !!\n");
+		if (result != USB_STOR_XFER_GOOD) {
+			pr_info("Load MS RW pattern Fail !!\n");
 			result = USB_STOR_TRANSPORT_ERROR;
 			goto exit;
 		}
@@ -182,9 +168,8 @@
 		logblk  = (WORD)(bn / us->MS_Lib.PagesPerBlock);
 		PageNum = (BYTE)(bn % us->MS_Lib.PagesPerBlock);
 
-		while(1)
-		{
-			if (blen > (us->MS_Lib.PagesPerBlock-PageNum) )
+		while (1) {
+			if (blen > (us->MS_Lib.PagesPerBlock-PageNum))
 				len = us->MS_Lib.PagesPerBlock-PageNum;
 			else
 				len = blen;
@@ -192,7 +177,7 @@
 			phyblk = MS_LibConv2Physical(us, logblk);
 			blkno  = phyblk * 0x20 + PageNum;
 
-			// set up the command wrapper
+			/* set up the command wrapper */
 			memset(bcb, 0, sizeof(struct bulk_cb_wrap));
 			bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN);
 			bcb->DataTransferLength = 0x200 * len;
@@ -205,15 +190,15 @@
 			bcb->CDB[2] = (BYTE)(blkno>>24);
 
 			result = ENE_SendScsiCmd(us, FDIR_READ, buf+offset, 0);
-			if (result != USB_STOR_XFER_GOOD)
-			{
-				printk("MS_SCSI_Read --- result = %x\n", result);
+			if (result != USB_STOR_XFER_GOOD) {
+				pr_info("MS_SCSI_Read --- result = %x\n",
+								result);
 				result =  USB_STOR_TRANSPORT_ERROR;
 				goto exit;
 			}
 
 			blen -= len;
-			if (blen<=0)
+			if (blen <= 0)
 				break;
 			logblk++;
 			PageNum = 0;
@@ -226,30 +211,32 @@
 	return result;
 }
 
-//----- MS_SCSI_Write() --------------------------------------------------
+/*
+ * MS_SCSI_Write()
+ */
 int MS_SCSI_Write(struct us_data *us, struct scsi_cmnd *srb)
 {
 	struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf;
-	int result=0;
+	int result = 0;
 	PBYTE	Cdb = srb->cmnd;
-	DWORD bn  =  ((Cdb[2]<<24) & 0xff000000) | ((Cdb[3]<<16) & 0x00ff0000) |
-                   ((Cdb[4]<< 8) & 0x0000ff00) | ((Cdb[5]<< 0) & 0x000000ff);
-	WORD  blen = ((Cdb[7]<< 8) & 0xff00)     | ((Cdb[8]<< 0) & 0x00ff);
+	DWORD bn  = ((Cdb[2] << 24) & 0xff000000) |
+			((Cdb[3] << 16) & 0x00ff0000) |
+			((Cdb[4] << 8) & 0x0000ff00) |
+			((Cdb[5] << 0) & 0x000000ff);
+	WORD  blen = ((Cdb[7] << 8) & 0xff00)     | ((Cdb[8] << 0) & 0x00ff);
 	DWORD	blenByte = blen * 0x200;
 
 	if (bn > us->bl_num)
 		return USB_STOR_TRANSPORT_ERROR;
 
-	if (us->MS_Status.IsMSPro)
-	{
+	if (us->MS_Status.IsMSPro) {
 		result = ENE_LoadBinCode(us, MSP_RW_PATTERN);
-		if (result != USB_STOR_XFER_GOOD)
-		{
-			printk("Load MSP RW pattern Fail !!\n");
+		if (result != USB_STOR_XFER_GOOD) {
+			pr_info("Load MSP RW pattern Fail !!\n");
 			return USB_STOR_TRANSPORT_ERROR;
 		}
 
-		// set up the command wrapper
+		/* set up the command wrapper */
 		memset(bcb, 0, sizeof(struct bulk_cb_wrap));
 		bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN);
 		bcb->DataTransferLength = blenByte;
@@ -262,11 +249,9 @@
 		bcb->CDB[2] = (BYTE)(bn>>24);
 
 		result = ENE_SendScsiCmd(us, FDIR_WRITE, scsi_sglist(srb), 1);
-	}
-	else
-	{
+	} else {
 		void	*buf;
-		int	offset=0;
+		int	offset = 0;
 		WORD	PhyBlockAddr;
 		BYTE	PageNum;
 		DWORD	result;
@@ -278,9 +263,8 @@
 		usb_stor_set_xfer_buf(us, buf, blenByte, srb, FROM_XFER_BUF);
 
 		result = ENE_LoadBinCode(us, MS_RW_PATTERN);
-		if (result != USB_STOR_XFER_GOOD)
-		{
-			printk("Load MS RW pattern Fail !!\n");
+		if (result != USB_STOR_XFER_GOOD) {
+			pr_info("Load MS RW pattern Fail !!\n");
 			result = USB_STOR_TRANSPORT_ERROR;
 			goto exit;
 		}
@@ -288,9 +272,8 @@
 		PhyBlockAddr = (WORD)(bn / us->MS_Lib.PagesPerBlock);
 		PageNum      = (BYTE)(bn % us->MS_Lib.PagesPerBlock);
 
-		while(1)
-		{
-			if (blen > (us->MS_Lib.PagesPerBlock-PageNum) )
+		while (1) {
+			if (blen > (us->MS_Lib.PagesPerBlock-PageNum))
 				len = us->MS_Lib.PagesPerBlock-PageNum;
 			else
 				len = blen;
@@ -298,10 +281,12 @@
 			oldphy = MS_LibConv2Physical(us, PhyBlockAddr);
 			newphy = MS_LibSearchBlockFromLogical(us, PhyBlockAddr);
 
-			result = MS_ReaderCopyBlock(us, oldphy, newphy, PhyBlockAddr, PageNum, buf+offset, len);
-			if (result != USB_STOR_XFER_GOOD)
-			{
-				printk("MS_SCSI_Write --- result = %x\n", result);
+			result = MS_ReaderCopyBlock(us, oldphy, newphy,
+							PhyBlockAddr, PageNum,
+							buf+offset, len);
+			if (result != USB_STOR_XFER_GOOD) {
+				pr_info("MS_SCSI_Write --- result = %x\n",
+								result);
 				result =  USB_STOR_TRANSPORT_ERROR;
 				goto exit;
 			}
@@ -310,7 +295,7 @@
 			MS_LibForceSetLogicalPair(us, PhyBlockAddr, newphy);
 
 			blen -= len;
-			if (blen<=0)
+			if (blen <= 0)
 				break;
 			PhyBlockAddr++;
 			PageNum = 0;
@@ -322,3 +307,38 @@
 	return result;
 }
 
+/*
+ * MS_SCSIIrp()
+ */
+int MS_SCSIIrp(struct us_data *us, struct scsi_cmnd *srb)
+{
+	int    result;
+
+	us->SrbStatus = SS_SUCCESS;
+	switch (srb->cmnd[0]) {
+	case TEST_UNIT_READY:
+		result = MS_SCSI_Test_Unit_Ready(us, srb);
+		break; /* 0x00 */
+	case INQUIRY:
+		result = MS_SCSI_Inquiry(us, srb);
+		break; /* 0x12 */
+	case MODE_SENSE:
+		result = MS_SCSI_Mode_Sense(us, srb);
+		break; /* 0x1A */
+	case READ_CAPACITY:
+		result = MS_SCSI_Read_Capacity(us, srb);
+		break; /* 0x25 */
+	case READ_10:
+		result = MS_SCSI_Read(us, srb);
+		break; /* 0x28 */
+	case WRITE_10:
+		result = MS_SCSI_Write(us, srb);
+		break;	/* 0x2A */
+	default:
+		us->SrbStatus = SS_ILLEGAL_REQUEST;
+		result = USB_STOR_TRANSPORT_FAILED;
+		break;
+	}
+	return result;
+}
+
diff -druN linux-2.6.39-libre/drivers/staging/keucr/scsiglue.c linux-3.0-rc7-libre/drivers/staging/keucr/scsiglue.c
--- linux-2.6.39-libre/drivers/staging/keucr/scsiglue.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/keucr/scsiglue.c	2011-07-11 19:51:52.000000000 -0400
@@ -1,3 +1,5 @@
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/mutex.h>
@@ -13,19 +15,23 @@
 #include "transport.h"
 
 /* Host functions */
-//----- host_info() ---------------------
-static const char* host_info(struct Scsi_Host *host)
+/*
+ * host_info()
+ */
+static const char *host_info(struct Scsi_Host *host)
 {
-	//printk("scsiglue --- host_info\n");
+	/* pr_info("scsiglue --- host_info\n"); */
 	return "SCSI emulation for USB Mass Storage devices";
 }
 
-//----- slave_alloc() ---------------------
+/*
+ * slave_alloc()
+ */
 static int slave_alloc(struct scsi_device *sdev)
 {
 	struct us_data *us = host_to_us(sdev->host);
 
-	//printk("scsiglue --- slave_alloc\n");
+	/* pr_info("scsiglue --- slave_alloc\n"); */
 	sdev->inquiry_len = 36;
 
 	blk_queue_update_dma_alignment(sdev->request_queue, (512 - 1));
@@ -36,14 +42,15 @@
 	return 0;
 }
 
-//----- slave_configure() ---------------------
+/*
+ * slave_configure()
+ */
 static int slave_configure(struct scsi_device *sdev)
 {
 	struct us_data *us = host_to_us(sdev->host);
 
-	//printk("scsiglue --- slave_configure\n");
-	if (us->fflags & (US_FL_MAX_SECTORS_64 | US_FL_MAX_SECTORS_MIN))
-	{
+	/* pr_info("scsiglue --- slave_configure\n"); */
+	if (us->fflags & (US_FL_MAX_SECTORS_64 | US_FL_MAX_SECTORS_MIN)) {
 		unsigned int max_sectors = 64;
 
 		if (us->fflags & US_FL_MAX_SECTORS_MIN)
@@ -53,9 +60,9 @@
 					      max_sectors);
 	}
 
-	if (sdev->type == TYPE_DISK)
-	{
-		if (us->subclass != USB_SC_SCSI && us->subclass != USB_SC_CYP_ATACB)
+	if (sdev->type == TYPE_DISK) {
+		if (us->subclass != USB_SC_SCSI &&
+			us->subclass != USB_SC_CYP_ATACB)
 			sdev->use_10_for_ms = 1;
 		sdev->use_192_bytes_for_3f = 1;
 		if (us->fflags & US_FL_NO_WP_DETECT)
@@ -70,13 +77,12 @@
 		sdev->retry_hwerror = 1;
 		sdev->allow_restart = 1;
 		sdev->last_sector_bug = 1;
-	}
-	else
-	{
+	} else {
 		sdev->use_10_for_ms = 1;
 	}
 
-	if ((us->protocol == USB_PR_CB || us->protocol == USB_PR_CBI) && sdev->scsi_level == SCSI_UNKNOWN)
+	if ((us->protocol == USB_PR_CB || us->protocol == USB_PR_CBI) &&
+					sdev->scsi_level == SCSI_UNKNOWN)
 		us->max_lun = 0;
 
 	if (us->fflags & US_FL_NOT_LOCKABLE)
@@ -86,24 +92,26 @@
 }
 
 /* This is always called with scsi_lock(host) held */
-//----- queuecommand() ---------------------
-static int queuecommand_lck(struct scsi_cmnd *srb, void (*done)(struct scsi_cmnd *))
+/*
+ * queuecommand()
+ */
+static int queuecommand_lck(struct scsi_cmnd *srb,
+				void (*done)(struct scsi_cmnd *))
 {
 	struct us_data *us = host_to_us(srb->device->host);
 
-	//printk("scsiglue --- queuecommand\n");
+	/* pr_info("scsiglue --- queuecommand\n"); */
 
 	/* check for state-transition errors */
-	if (us->srb != NULL)
-	{
-		printk("Error in %s: us->srb = %p\n", __FUNCTION__, us->srb);
+	if (us->srb != NULL) {
+		/* pr_info("Error in %s: us->srb = %p\n"
+				 __FUNCTION__, us->srb); */
 		return SCSI_MLQUEUE_HOST_BUSY;
 	}
 
 	/* fail the command if we are disconnecting */
-	if (test_bit(US_FLIDX_DISCONNECTING, &us->dflags))
-	{
-		printk("Fail command during disconnect\n");
+	if (test_bit(US_FLIDX_DISCONNECTING, &us->dflags)) {
+		pr_info("Fail command during disconnect\n");
 		srb->result = DID_NO_CONNECT << 16;
 		done(srb);
 		return 0;
@@ -124,24 +132,24 @@
  ***********************************************************************/
 
 /* Command timeout and abort */
-//----- command_abort() ---------------------
+/*
+ * command_abort()
+ */
 static int command_abort(struct scsi_cmnd *srb)
 {
 	struct us_data *us = host_to_us(srb->device->host);
 
-	//printk("scsiglue --- command_abort\n");
+	/* pr_info("scsiglue --- command_abort\n"); */
 
 	scsi_lock(us_to_host(us));
-	if (us->srb != srb)
-	{
+	if (us->srb != srb) {
 		scsi_unlock(us_to_host(us));
 		printk ("-- nothing to abort\n");
 		return FAILED;
 	}
 
 	set_bit(US_FLIDX_TIMED_OUT, &us->dflags);
-	if (!test_bit(US_FLIDX_RESETTING, &us->dflags))
-	{
+	if (!test_bit(US_FLIDX_RESETTING, &us->dflags)) {
 		set_bit(US_FLIDX_ABORTING, &us->dflags);
 		usb_stor_stop_transport(us);
 	}
@@ -152,14 +160,18 @@
 	return SUCCESS;
 }
 
-/* This invokes the transport reset mechanism to reset the state of the device */
-//----- device_reset() ---------------------
+/* This invokes the transport reset mechanism to reset the state of the
+ * device.
+ */
+/*
+ * device_reset()
+ */
 static int device_reset(struct scsi_cmnd *srb)
 {
 	struct us_data *us = host_to_us(srb->device->host);
 	int result;
 
-	//printk("scsiglue --- device_reset\n");
+	/* pr_info("scsiglue --- device_reset\n"); */
 
 	/* lock the device pointers and do the reset */
 	mutex_lock(&(us->dev_mutex));
@@ -169,38 +181,43 @@
 	return result < 0 ? FAILED : SUCCESS;
 }
 
-//----- bus_reset() ---------------------
+/*
+ * bus_reset()
+ */
 static int bus_reset(struct scsi_cmnd *srb)
 {
 	struct us_data *us = host_to_us(srb->device->host);
 	int result;
 
-	//printk("scsiglue --- bus_reset\n");
+	/* pr_info("scsiglue --- bus_reset\n"); */
 	result = usb_stor_port_reset(us);
 	return result < 0 ? FAILED : SUCCESS;
 }
 
-//----- usb_stor_report_device_reset() ---------------------
+/*
+ * usb_stor_report_device_reset()
+ */
 void usb_stor_report_device_reset(struct us_data *us)
 {
 	int i;
 	struct Scsi_Host *host = us_to_host(us);
 
-	//printk("scsiglue --- usb_stor_report_device_reset\n");
+	/* pr_info("scsiglue --- usb_stor_report_device_reset\n"); */
 	scsi_report_device_reset(host, 0, 0);
-	if (us->fflags & US_FL_SCM_MULT_TARG)
-	{
+	if (us->fflags & US_FL_SCM_MULT_TARG) {
 		for (i = 1; i < host->max_id; ++i)
 			scsi_report_device_reset(host, 0, i);
 	}
 }
 
-//----- usb_stor_report_bus_reset() ---------------------
+/*
+ * usb_stor_report_bus_reset()
+ */
 void usb_stor_report_bus_reset(struct us_data *us)
 {
 	struct Scsi_Host *host = us_to_host(us);
 
-	//printk("scsiglue --- usb_stor_report_bus_reset\n");
+	/* pr_info("scsiglue --- usb_stor_report_bus_reset\n"); */
 	scsi_lock(host);
 	scsi_report_bus_reset(host, 0);
 	scsi_unlock(host);
@@ -215,14 +232,17 @@
 #define SPRINTF(args...) \
 	do { if (pos < buffer+length) pos += sprintf(pos, ## args); } while (0)
 
-//----- proc_info() ---------------------
-static int proc_info (struct Scsi_Host *host, char *buffer, char **start, off_t offset, int length, int inout)
+/*
+ * proc_info()
+ */
+static int proc_info(struct Scsi_Host *host, char *buffer, char **start,
+					off_t offset, int length, int inout)
 {
 	struct us_data *us = host_to_us(host);
 	char *pos = buffer;
 	const char *string;
 
-	//printk("scsiglue --- proc_info\n");
+	/* pr_info("scsiglue --- proc_info\n"); */
 	if (inout)
 		return length;
 
@@ -255,8 +275,7 @@
 	SPRINTF("    Transport: %s\n", us->transport_name);
 
 	/* show the device flags */
-	if (pos < buffer + length)
-	{
+	if (pos < buffer + length) {
 		pos += sprintf(pos, "       Quirks:");
 
 #define US_FLAG(name, value) \
@@ -271,11 +290,11 @@
 	*start = buffer + offset;
 
 	if ((pos - buffer) < offset)
-		return (0);
+		return 0;
 	else if ((pos - buffer - offset) < length)
-		return (pos - buffer - offset);
+		return pos - buffer - offset;
 	else
-		return (length);
+		return length;
 }
 
 /***********************************************************************
@@ -283,29 +302,35 @@
  ***********************************************************************/
 
 /* Output routine for the sysfs max_sectors file */
-//----- show_max_sectors() ---------------------
-static ssize_t show_max_sectors(struct device *dev, struct device_attribute *attr, char *buf)
+/*
+ * show_max_sectors()
+ */
+static ssize_t show_max_sectors(struct device *dev,
+				struct device_attribute *attr, char *buf)
 {
 	struct scsi_device *sdev = to_scsi_device(dev);
 
-	//printk("scsiglue --- ssize_t show_max_sectors\n");
+	/* pr_info("scsiglue --- ssize_t show_max_sectors\n"); */
 	return sprintf(buf, "%u\n", queue_max_sectors(sdev->request_queue));
 }
 
 /* Input routine for the sysfs max_sectors file */
-//----- store_max_sectors() ---------------------
-static ssize_t store_max_sectors(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
+/*
+ * store_max_sectors()
+ */
+static ssize_t store_max_sectors(struct device *dev,
+				struct device_attribute *attr,
+				const char *buf, size_t count)
 {
 	struct scsi_device *sdev = to_scsi_device(dev);
 	unsigned short ms;
 
-	//printk("scsiglue --- ssize_t store_max_sectors\n");
-	if (sscanf(buf, "%hu", &ms) > 0 && ms <= SCSI_DEFAULT_MAX_SECTORS)
-	{
+	/* pr_info("scsiglue --- ssize_t store_max_sectors\n"); */
+	if (sscanf(buf, "%hu", &ms) > 0 && ms <= SCSI_DEFAULT_MAX_SECTORS) {
 		blk_queue_max_hw_sectors(sdev->request_queue, ms);
 		return strlen(buf);
 	}
-	return -EINVAL;	
+	return -EINVAL;
 }
 
 static DEVICE_ATTR(max_sectors, S_IRUGO | S_IWUSR, show_max_sectors, store_max_sectors);
@@ -313,7 +338,9 @@
 
 /* this defines our host template, with which we'll allocate hosts */
 
-//----- usb_stor_host_template() ---------------------
+/*
+ * usb_stor_host_template()
+ */
 struct scsi_host_template usb_stor_host_template = {
 	/* basic userland interface stuff */
 	.name =				"eucr-storage",
@@ -376,42 +403,41 @@
  * Scatter-gather transfer buffer access routines
  ***********************************************************************/
 
-//----- usb_stor_access_xfer_buf() ---------------------
+/*
+ * usb_stor_access_xfer_buf()
+ */
 unsigned int usb_stor_access_xfer_buf(struct us_data *us, unsigned char *buffer,
 	unsigned int buflen, struct scsi_cmnd *srb, struct scatterlist **sgptr,
 	unsigned int *offset, enum xfer_buf_dir dir)
 {
 	unsigned int cnt;
 
-	//printk("transport --- usb_stor_access_xfer_buf\n");
+	/* pr_info("transport --- usb_stor_access_xfer_buf\n"); */
 	struct scatterlist *sg = *sgptr;
 
 	if (!sg)
 		sg = scsi_sglist(srb);
 
 	cnt = 0;
-	while (cnt < buflen && sg)
-	{
-		struct page *page = sg_page(sg) + ((sg->offset + *offset) >> PAGE_SHIFT);
+	while (cnt < buflen && sg) {
+		struct page *page = sg_page(sg) +
+					((sg->offset + *offset) >> PAGE_SHIFT);
 		unsigned int poff = (sg->offset + *offset) & (PAGE_SIZE-1);
 		unsigned int sglen = sg->length - *offset;
 
-		if (sglen > buflen - cnt)
-		{
+		if (sglen > buflen - cnt) {
 			/* Transfer ends within this s-g entry */
 			sglen = buflen - cnt;
 			*offset += sglen;
-		}
-		else
-		{
+		} else {
 			/* Transfer continues to next s-g entry */
 			*offset = 0;
 			sg = sg_next(sg);
 		}
 
-		while (sglen > 0)
-		{
-			unsigned int plen = min(sglen, (unsigned int)PAGE_SIZE - poff);
+		while (sglen > 0) {
+			unsigned int plen = min(sglen,
+						(unsigned int)PAGE_SIZE - poff);
 			unsigned char *ptr = kmap(page);
 
 			if (dir == TO_XFER_BUF)
@@ -433,18 +459,24 @@
 	return cnt;
 }
 
-/* Store the contents of buffer into srb's transfer buffer and set the SCSI residue. */
-//----- usb_stor_set_xfer_buf() ---------------------
-void usb_stor_set_xfer_buf(struct us_data *us, unsigned char *buffer, unsigned int buflen, struct scsi_cmnd *srb,
-	unsigned int dir)
+/*
+ * Store the contents of buffer into srb's transfer
+ * buffer and set the SCSI residue.
+ */
+/*
+ * usb_stor_set_xfer_buf()
+ */
+void usb_stor_set_xfer_buf(struct us_data *us, unsigned char *buffer,
+		unsigned int buflen, struct scsi_cmnd *srb, unsigned int dir)
 {
 	unsigned int offset = 0;
 	struct scatterlist *sg = NULL;
 
-	//printk("transport --- usb_stor_set_xfer_buf\n");
-	// TO_XFER_BUF = 0, FROM_XFER_BUF = 1
+	/* pr_info("transport --- usb_stor_set_xfer_buf\n"); */
+	/* TO_XFER_BUF = 0, FROM_XFER_BUF = 1 */
 	buflen = min(buflen, scsi_bufflen(srb));
-	buflen = usb_stor_access_xfer_buf(us, buffer, buflen, srb, &sg, &offset, dir);
+	buflen = usb_stor_access_xfer_buf(us, buffer, buflen, srb,
+						&sg, &offset, dir);
 	if (buflen < scsi_bufflen(srb))
 		scsi_set_resid(srb, scsi_bufflen(srb) - buflen);
 }
diff -druN linux-2.6.39-libre/drivers/staging/keucr/smcommon.h linux-3.0-rc7-libre/drivers/staging/keucr/smcommon.h
--- linux-2.6.39-libre/drivers/staging/keucr/smcommon.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/keucr/smcommon.h	2011-07-11 19:51:52.000000000 -0400
@@ -6,7 +6,7 @@
 /***************************************************************************
 Define Difinetion
 ***************************************************************************/
-#define SUCCESS             0x0000 /* SUCCESS */
+#define SMSUCCESS           0x0000 /* SUCCESS */
 #define ERROR               0xFFFF /* ERROR */
 #define CORRECT             0x0001 /* CORRECTABLE */
 
diff -druN linux-2.6.39-libre/drivers/staging/keucr/smilecc.c linux-3.0-rc7-libre/drivers/staging/keucr/smilecc.c
--- linux-2.6.39-libre/drivers/staging/keucr/smilecc.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/keucr/smilecc.c	2011-07-11 19:51:52.000000000 -0400
@@ -1,39 +1,42 @@
 #include "usb.h"
 #include "scsiglue.h"
 #include "transport.h"
-//#include "stdlib.h"
-//#include "EUCR6SK.h"
+/* #include "stdlib.h" */
+/* #include "EUCR6SK.h" */
 #include "smcommon.h"
 #include "smil.h"
 
-//#include <stdio.h>
-//#include <stdlib.h>
-//#include <string.h>
-//#include <dos.h>
-//
-//#include "EMCRIOS.h"
+/* #include <stdio.h> */
+/* #include <stdlib.h> */
+/* #include <string.h> */
+/* #include <dos.h> */
+/* #include "EMCRIOS.h" */
 
-// CP0-CP5 code table
+/* CP0-CP5 code table */
 static BYTE ecctable[256] = {
-0x00,0x55,0x56,0x03,0x59,0x0C,0x0F,0x5A,0x5A,0x0F,0x0C,0x59,0x03,0x56,0x55,0x00,
-0x65,0x30,0x33,0x66,0x3C,0x69,0x6A,0x3F,0x3F,0x6A,0x69,0x3C,0x66,0x33,0x30,0x65,
-0x66,0x33,0x30,0x65,0x3F,0x6A,0x69,0x3C,0x3C,0x69,0x6A,0x3F,0x65,0x30,0x33,0x66,
-0x03,0x56,0x55,0x00,0x5A,0x0F,0x0C,0x59,0x59,0x0C,0x0F,0x5A,0x00,0x55,0x56,0x03,
-0x69,0x3C,0x3F,0x6A,0x30,0x65,0x66,0x33,0x33,0x66,0x65,0x30,0x6A,0x3F,0x3C,0x69,
-0x0C,0x59,0x5A,0x0F,0x55,0x00,0x03,0x56,0x56,0x03,0x00,0x55,0x0F,0x5A,0x59,0x0C,
-0x0F,0x5A,0x59,0x0C,0x56,0x03,0x00,0x55,0x55,0x00,0x03,0x56,0x0C,0x59,0x5A,0x0F,
-0x6A,0x3F,0x3C,0x69,0x33,0x66,0x65,0x30,0x30,0x65,0x66,0x33,0x69,0x3C,0x3F,0x6A,
-0x6A,0x3F,0x3C,0x69,0x33,0x66,0x65,0x30,0x30,0x65,0x66,0x33,0x69,0x3C,0x3F,0x6A,
-0x0F,0x5A,0x59,0x0C,0x56,0x03,0x00,0x55,0x55,0x00,0x03,0x56,0x0C,0x59,0x5A,0x0F,
-0x0C,0x59,0x5A,0x0F,0x55,0x00,0x03,0x56,0x56,0x03,0x00,0x55,0x0F,0x5A,0x59,0x0C,
-0x69,0x3C,0x3F,0x6A,0x30,0x65,0x66,0x33,0x33,0x66,0x65,0x30,0x6A,0x3F,0x3C,0x69,
-0x03,0x56,0x55,0x00,0x5A,0x0F,0x0C,0x59,0x59,0x0C,0x0F,0x5A,0x00,0x55,0x56,0x03,
-0x66,0x33,0x30,0x65,0x3F,0x6A,0x69,0x3C,0x3C,0x69,0x6A,0x3F,0x65,0x30,0x33,0x66,
-0x65,0x30,0x33,0x66,0x3C,0x69,0x6A,0x3F,0x3F,0x6A,0x69,0x3C,0x66,0x33,0x30,0x65,
-0x00,0x55,0x56,0x03,0x59,0x0C,0x0F,0x5A,0x5A,0x0F,0x0C,0x59,0x03,0x56,0x55,0x00
+0x00, 0x55, 0x56, 0x03, 0x59, 0x0C, 0x0F, 0x5A, 0x5A, 0x0F, 0x0C, 0x59, 0x03,
+0x56, 0x55, 0x00, 0x65, 0x30, 0x33, 0x66, 0x3C, 0x69, 0x6A, 0x3F, 0x3F, 0x6A,
+0x69, 0x3C, 0x66, 0x33, 0x30, 0x65, 0x66, 0x33, 0x30, 0x65, 0x3F, 0x6A, 0x69,
+0x3C, 0x3C, 0x69, 0x6A, 0x3F, 0x65, 0x30, 0x33, 0x66, 0x03, 0x56, 0x55, 0x00,
+0x5A, 0x0F, 0x0C, 0x59, 0x59, 0x0C, 0x0F, 0x5A, 0x00, 0x55, 0x56, 0x03, 0x69,
+0x3C, 0x3F, 0x6A, 0x30, 0x65, 0x66, 0x33, 0x33, 0x66, 0x65, 0x30, 0x6A, 0x3F,
+0x3C, 0x69, 0x0C, 0x59, 0x5A, 0x0F, 0x55, 0x00, 0x03, 0x56, 0x56, 0x03, 0x00,
+0x55, 0x0F, 0x5A, 0x59, 0x0C, 0x0F, 0x5A, 0x59, 0x0C, 0x56, 0x03, 0x00, 0x55,
+0x55, 0x00, 0x03, 0x56, 0x0C, 0x59, 0x5A, 0x0F, 0x6A, 0x3F, 0x3C, 0x69, 0x33,
+0x66, 0x65, 0x30, 0x30, 0x65, 0x66, 0x33, 0x69, 0x3C, 0x3F, 0x6A, 0x6A, 0x3F,
+0x3C, 0x69, 0x33, 0x66, 0x65, 0x30, 0x30, 0x65, 0x66, 0x33, 0x69, 0x3C, 0x3F,
+0x6A, 0x0F, 0x5A, 0x59, 0x0C, 0x56, 0x03, 0x00, 0x55, 0x55, 0x00, 0x03, 0x56,
+0x0C, 0x59, 0x5A, 0x0F, 0x0C, 0x59, 0x5A, 0x0F, 0x55, 0x00, 0x03, 0x56, 0x56,
+0x03, 0x00, 0x55, 0x0F, 0x5A, 0x59, 0x0C, 0x69, 0x3C, 0x3F, 0x6A, 0x30, 0x65,
+0x66, 0x33, 0x33, 0x66, 0x65, 0x30, 0x6A, 0x3F, 0x3C, 0x69, 0x03, 0x56, 0x55,
+0x00, 0x5A, 0x0F, 0x0C, 0x59, 0x59, 0x0C, 0x0F, 0x5A, 0x00, 0x55, 0x56, 0x03,
+0x66, 0x33, 0x30, 0x65, 0x3F, 0x6A, 0x69, 0x3C, 0x3C, 0x69, 0x6A, 0x3F, 0x65,
+0x30, 0x33, 0x66, 0x65, 0x30, 0x33, 0x66, 0x3C, 0x69, 0x6A, 0x3F, 0x3F, 0x6A,
+0x69, 0x3C, 0x66, 0x33, 0x30, 0x65, 0x00, 0x55, 0x56, 0x03, 0x59, 0x0C, 0x0F,
+0x5A, 0x5A, 0x0F, 0x0C, 0x59, 0x03, 0x56, 0x55, 0x00
 };
 
-static void   trans_result  (BYTE,   BYTE,   BYTE *, BYTE *);
+static void   trans_result(BYTE,   BYTE,   BYTE *, BYTE *);
 
 #define BIT7        0x80
 #define BIT6        0x40
@@ -48,139 +51,144 @@
 #define MASK_CPS    0x3f
 #define CORRECTABLE 0x00555554L
 
-static void trans_result(reg2,reg3,ecc1,ecc2)
-BYTE reg2; // LP14,LP12,LP10,...
-BYTE reg3; // LP15,LP13,LP11,...
-BYTE *ecc1; // LP15,LP14,LP13,...
-BYTE *ecc2; // LP07,LP06,LP05,...
+/*
+ * reg2; * LP14,LP12,LP10,...
+ * reg3; * LP15,LP13,LP11,...
+ * *ecc1; * LP15,LP14,LP13,...
+ * *ecc2; * LP07,LP06,LP05,...
+ */
+static void trans_result(BYTE reg2, BYTE reg3, BYTE *ecc1, BYTE *ecc2)
 {
-    BYTE a; // Working for reg2,reg3
-    BYTE b; // Working for ecc1,ecc2
-    BYTE i; // For counting
+	BYTE a; /* Working for reg2,reg3 */
+	BYTE b; /* Working for ecc1,ecc2 */
+	BYTE i; /* For counting */
 
-    a=BIT7; b=BIT7; // 80h=10000000b
-    *ecc1=*ecc2=0; // Clear ecc1,ecc2
-    for(i=0; i<4; ++i) {
-        if ((reg3&a)!=0)
-            *ecc1|=b; // LP15,13,11,9 -> ecc1
-        b=b>>1; // Right shift
-        if ((reg2&a)!=0)
-            *ecc1|=b; // LP14,12,10,8 -> ecc1
-        b=b>>1; // Right shift
-        a=a>>1; // Right shift
-    }
+	a = BIT7; b = BIT7; /* 80h=10000000b */
+	*ecc1 = *ecc2 = 0; /* Clear ecc1,ecc2 */
+	for (i = 0; i < 4; ++i) {
+		if ((reg3&a) != 0)
+			*ecc1 |= b; /* LP15,13,11,9 -> ecc1 */
+		b = b>>1; /* Right shift */
+		if ((reg2&a) != 0)
+			*ecc1 |= b; /* LP14,12,10,8 -> ecc1 */
+		b = b>>1; /* Right shift */
+		a = a>>1; /* Right shift */
+	}
 
-    b=BIT7; // 80h=10000000b
-    for(i=0; i<4; ++i) {
-        if ((reg3&a)!=0)
-            *ecc2|=b; // LP7,5,3,1 -> ecc2
-        b=b>>1; // Right shift
-        if ((reg2&a)!=0)
-            *ecc2|=b; // LP6,4,2,0 -> ecc2
-        b=b>>1; // Right shift
-        a=a>>1; // Right shift
-    }
+	b = BIT7; /* 80h=10000000b */
+	for (i = 0; i < 4; ++i) {
+		if ((reg3&a) != 0)
+			*ecc2 |= b; /* LP7,5,3,1 -> ecc2 */
+		b = b>>1; /* Right shift */
+		if ((reg2&a) != 0)
+			*ecc2 |= b; /* LP6,4,2,0 -> ecc2 */
+		b = b>>1; /* Right shift */
+		a = a>>1; /* Right shift */
+	}
 }
 
-//static void calculate_ecc(table,data,ecc1,ecc2,ecc3)
-void calculate_ecc(table,data,ecc1,ecc2,ecc3)
-BYTE *table; // CP0-CP5 code table
-BYTE *data; // DATA
-BYTE *ecc1; // LP15,LP14,LP13,...
-BYTE *ecc2; // LP07,LP06,LP05,...
-BYTE *ecc3; // CP5,CP4,CP3,...,"1","1"
+/*static void calculate_ecc(table,data,ecc1,ecc2,ecc3) */
+/*
+ * *table; * CP0-CP5 code table
+ * *data; * DATA
+ * *ecc1; * LP15,LP14,LP13,...
+ * *ecc2; * LP07,LP06,LP05,...
+ * *ecc3; * CP5,CP4,CP3,...,"1","1"
+ */
+void calculate_ecc(BYTE *table, BYTE *data, BYTE *ecc1, BYTE *ecc2, BYTE *ecc3)
 {
-    DWORD  i;    // For counting
-    BYTE a;    // Working for table
-    BYTE reg1; // D-all,CP5,CP4,CP3,...
-    BYTE reg2; // LP14,LP12,L10,...
-    BYTE reg3; // LP15,LP13,L11,...
+	DWORD  i;    /* For counting */
+	BYTE a;    /* Working for table */
+	BYTE reg1; /* D-all,CP5,CP4,CP3,... */
+	BYTE reg2; /* LP14,LP12,L10,... */
+	BYTE reg3; /* LP15,LP13,L11,... */
 
-    reg1=reg2=reg3=0;   // Clear parameter
-    for(i=0; i<256; ++i) {
-        a=table[data[i]]; // Get CP0-CP5 code from table
-        reg1^=(a&MASK_CPS); // XOR with a
-        if ((a&BIT6)!=0)
-        { // If D_all(all bit XOR) = 1
-            reg3^=(BYTE)i; // XOR with counter
-            reg2^=~((BYTE)i); // XOR with inv. of counter
-        }
-    }
+	reg1 = reg2 = reg3 = 0;   /* Clear parameter */
+	for (i = 0; i < 256; ++i) {
+		a = table[data[i]]; /* Get CP0-CP5 code from table */
+		reg1 ^= (a&MASK_CPS); /* XOR with a */
+		if ((a&BIT6) != 0) { /* If D_all(all bit XOR) = 1 */
+			reg3 ^= (BYTE)i; /* XOR with counter */
+			reg2 ^= ~((BYTE)i); /* XOR with inv. of counter */
+		}
+	}
 
-    // Trans LP14,12,10,... & LP15,13,11,... -> LP15,14,13,... & LP7,6,5,..
-    trans_result(reg2,reg3,ecc1,ecc2);
-    *ecc1=~(*ecc1); *ecc2=~(*ecc2); // Inv. ecc2 & ecc3
-    *ecc3=((~reg1)<<2)|BIT1BIT0; // Make TEL format
+	/* Trans LP14,12,10,... & LP15,13,11,... ->
+						LP15,14,13,... & LP7,6,5,.. */
+	trans_result(reg2, reg3, ecc1, ecc2);
+	*ecc1 = ~(*ecc1); *ecc2 = ~(*ecc2); /* Inv. ecc2 & ecc3 */
+	*ecc3 = ((~reg1)<<2)|BIT1BIT0; /* Make TEL format */
 }
 
-BYTE correct_data(data,eccdata,ecc1,ecc2,ecc3)
-BYTE *data; // DATA
-BYTE *eccdata; // ECC DATA
-BYTE ecc1; // LP15,LP14,LP13,...
-BYTE ecc2; // LP07,LP06,LP05,...
-BYTE ecc3; // CP5,CP4,CP3,...,"1","1"
+/*
+ * *data; * DATA
+ * *eccdata; * ECC DATA
+ * ecc1; * LP15,LP14,LP13,...
+ * ecc2; * LP07,LP06,LP05,...
+ * ecc3; * CP5,CP4,CP3,...,"1","1"
+ */
+BYTE correct_data(BYTE *data, BYTE *eccdata, BYTE ecc1, BYTE ecc2, BYTE ecc3)
 {
-    DWORD l; // Working to check d
-    DWORD d; // Result of comparison
-    DWORD i; // For counting
-    BYTE d1,d2,d3; // Result of comparison
-    BYTE a; // Working for add
-    BYTE add; // Byte address of cor. DATA
-    BYTE b; // Working for bit
-    BYTE bit; // Bit address of cor. DATA
+	DWORD l; /* Working to check d */
+	DWORD d; /* Result of comparison */
+	DWORD i; /* For counting */
+	BYTE d1, d2, d3; /* Result of comparison */
+	BYTE a; /* Working for add */
+	BYTE add; /* Byte address of cor. DATA */
+	BYTE b; /* Working for bit */
+	BYTE bit; /* Bit address of cor. DATA */
 
-    d1=ecc1^eccdata[1]; d2=ecc2^eccdata[0]; // Compare LP's
-    d3=ecc3^eccdata[2]; // Comapre CP's
-    d=((DWORD)d1<<16) // Result of comparison
-    +((DWORD)d2<<8)
-    +(DWORD)d3;
+	d1 = ecc1^eccdata[1]; d2 = ecc2^eccdata[0]; /* Compare LP's */
+	d3 = ecc3^eccdata[2]; /* Comapre CP's */
+	d = ((DWORD)d1<<16) /* Result of comparison */
+	+((DWORD)d2<<8)
+	+(DWORD)d3;
 
-    if (d==0) return(0); // If No error, return
+	if (d == 0)
+		return 0; /* If No error, return */
 
-    if (((d^(d>>1))&CORRECTABLE)==CORRECTABLE)
-    { // If correctable
-        l=BIT23;
-        add=0; // Clear parameter
-        a=BIT7;
+	if (((d^(d>>1))&CORRECTABLE) == CORRECTABLE) { /* If correctable */
+		l = BIT23;
+		add = 0; /* Clear parameter */
+		a = BIT7;
 
-        for(i=0; i<8; ++i) { // Checking 8 bit
-            if ((d&l)!=0) add|=a; // Make byte address from LP's
-            l>>=2; a>>=1; // Right Shift
-        }
+		for (i = 0; i < 8; ++i) { /* Checking 8 bit */
+			if ((d&l) != 0)
+				add |= a; /* Make byte address from LP's */
+			l >>= 2; a >>= 1; /* Right Shift */
+		}
 
-        bit=0; // Clear parameter
-        b=BIT2;
-        for(i=0; i<3; ++i) { // Checking 3 bit
-            if ((d&l)!=0) bit|=b; // Make bit address from CP's
-            l>>=2; b>>=1; // Right shift
-        }
+		bit = 0; /* Clear parameter */
+		b = BIT2;
+		for (i = 0; i < 3; ++i) { /* Checking 3 bit */
+			if ((d&l) != 0)
+				bit |= b; /* Make bit address from CP's */
+			l >>= 2; b >>= 1; /* Right shift */
+		}
 
-        b=BIT0;
-        data[add]^=(b<<bit); // Put corrected data
-        return(1);
-    }
+		b = BIT0;
+		data[add] ^= (b<<bit); /* Put corrected data */
+		return 1;
+	}
 
-    i=0; // Clear count
-    d&=0x00ffffffL; // Masking
+	i = 0; /* Clear count */
+	d &= 0x00ffffffL; /* Masking */
 
-    while(d) { // If d=0 finish counting
-        if (d&BIT0) ++i; // Count number of 1 bit
-        d>>=1; // Right shift
-    }
+	while (d) { /* If d=0 finish counting */
+		if (d&BIT0)
+			++i; /* Count number of 1 bit */
+		d >>= 1; /* Right shift */
+	}
 
-    if (i==1)
-    { // If ECC error
-        eccdata[1]=ecc1; eccdata[0]=ecc2; // Put right ECC code
-        eccdata[2]=ecc3;
-        return(2);
-    }
-    return(3); // Uncorrectable error
+	if (i == 1) { /* If ECC error */
+		eccdata[1] = ecc1; eccdata[0] = ecc2; /* Put right ECC code */
+		eccdata[2] = ecc3;
+		return 2;
+	}
+	return 3; /* Uncorrectable error */
 }
 
-int _Correct_D_SwECC(buf,redundant_ecc,calculate_ecc)
-BYTE *buf;
-BYTE *redundant_ecc;
-BYTE *calculate_ecc;
+int _Correct_D_SwECC(BYTE *buf, BYTE *redundant_ecc, BYTE *calculate_ecc)
 {
 	DWORD err;
 
@@ -195,11 +203,9 @@
 	return -1;
 }
 
-void _Calculate_D_SwECC(buf,ecc)
-BYTE *buf;
-BYTE *ecc;
+void _Calculate_D_SwECC(BYTE *buf, BYTE *ecc)
 {
-    calculate_ecc(ecctable,buf,ecc+1,ecc+0,ecc+2);
+	calculate_ecc(ecctable, buf, ecc+1, ecc+0, ecc+2);
 }
 
 
diff -druN linux-2.6.39-libre/drivers/staging/keucr/smil.h linux-3.0-rc7-libre/drivers/staging/keucr/smil.h
--- linux-2.6.39-libre/drivers/staging/keucr/smil.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/keucr/smil.h	2011-07-11 19:51:52.000000000 -0400
@@ -44,21 +44,22 @@
 /***************************************************************************
 Hardware ECC Definition
 ***************************************************************************/
-#define HW_ECC_SUPPORTED    1      /* Hardware ECC Supported */  /* No difinition for Software ECC */
+#define HW_ECC_SUPPORTED    1	   /* Hardware ECC Supported */
+/* No difinition for Software ECC */
 
 /***************************************************************************
 SmartMedia Command & Status Definition
 ***************************************************************************/
 /* SmartMedia Command */
 #define WRDATA        0x80
-//#define READ          0x00
+/* #define READ          0x00 */
 #define READ_REDT     0x50
-//#define WRITE         0x10
+/* #define WRITE         0x10 */
 #define RDSTATUS      0x70
 
-#define READ1         0x00 //NO
-#define READ2         0x01 //NO
-#define READ3         0x50 //NO
+#define READ1         0x00 /* NO */
+#define READ2         0x01 /* NO */
+#define READ3         0x50 /* NO */
 #define RST_CHIP      0xFF
 #define ERASE1        0x60
 #define ERASE2        0xD0
@@ -67,19 +68,19 @@
 #define READ_ID_3     0x9A
 
 /* 712 SmartMedia Command */
-#define SM_CMD_RESET                0x00    // 0xFF
-#define SM_CMD_READ_ID_1            0x10    // 0x90
-#define SM_CMD_READ_ID_2            0x20    // 0x91
-#define SM_CMD_READ_STAT            0x30    // 0x70
-#define SM_CMD_RDMULTPL_STAT        0x40    // 0x71
-#define SM_CMD_READ_1               0x50    // 0x00
-#define SM_CMD_READ_2               0x60    // 0x01
-#define SM_CMD_READ_3               0x70    // 0x50
-#define SM_CMD_PAGPRGM_TRUE         0x80    // {0x80, 0x10}
-#define SM_CMD_PAGPRGM_DUMY         0x90    // {0x80, 0x11}
-#define SM_CMD_PAGPRGM_MBLK         0xA0    // {0x80, 0x15}
-#define SM_CMD_BLKERASE             0xB0    // {0x60, 0xD0}
-#define SM_CMD_BLKERASE_MULTPL      0xC0    // {0x60-0x60, 0xD0}
+#define SM_CMD_RESET                0x00    /* 0xFF */
+#define SM_CMD_READ_ID_1            0x10    /* 0x90 */
+#define SM_CMD_READ_ID_2            0x20    /* 0x91 */
+#define SM_CMD_READ_STAT            0x30    /* 0x70 */
+#define SM_CMD_RDMULTPL_STAT        0x40    /* 0x71 */
+#define SM_CMD_READ_1               0x50    /* 0x00 */
+#define SM_CMD_READ_2               0x60    /* 0x01 */
+#define SM_CMD_READ_3               0x70    /* 0x50 */
+#define SM_CMD_PAGPRGM_TRUE         0x80    /* {0x80, 0x10} */
+#define SM_CMD_PAGPRGM_DUMY         0x90    /* {0x80, 0x11} */
+#define SM_CMD_PAGPRGM_MBLK         0xA0    /* {0x80, 0x15} */
+#define SM_CMD_BLKERASE             0xB0    /* {0x60, 0xD0} */
+#define SM_CMD_BLKERASE_MULTPL      0xC0    /* {0x60-0x60, 0xD0} */
 
 #define SM_CRADDTCT_DEBNCETIMER_EN  0x02
 #define SM_CMD_START_BIT            0x01
@@ -87,27 +88,31 @@
 #define SM_WaitCmdDone { while (!SM_CmdDone); }
 #define SM_WaitDmaDone { while (!SM_DmaDone); }
 
-// SmartMedia Status
-#define WR_FAIL       0x01      // 0:Pass, 1:Fail
-#define SUSPENDED     0x20      // 0:Not Suspended, 1:Suspended
-#define READY         0x40      // 0:Busy, 1:Ready
-#define WR_PRTCT      0x80      // 0:Protect, 1:Not Protect
+/* SmartMedia Status */
+#define WR_FAIL       0x01      /* 0:Pass, 1:Fail */
+#define SUSPENDED     0x20      /* 0:Not Suspended, 1:Suspended */
+#define READY         0x40      /* 0:Busy, 1:Ready */
+#define WR_PRTCT      0x80      /* 0:Protect, 1:Not Protect */
 
-// SmartMedia Busy Time (1bit:0.1ms)
-#define BUSY_PROG     200       // tPROG   : 20ms  ----- Program Time          old : 200
-#define BUSY_ERASE    4000      // tBERASE : 400ms ----- Block Erase Time      old : 4000
-//for 712 Test
-//#define BUSY_READ     1         // tR      : 100us ----- Data transfer Time   old : 1
-//#define BUSY_READ     10         // tR      : 100us ----- Data transfer Time   old : 1
-#define BUSY_READ     200       // tR      : 20ms   ----- Data transfer Time   old : 1
-//#define BUSY_RESET    60        // tRST    : 6ms   ----- Device Resetting Time old : 60
-#define BUSY_RESET    600        // tRST    : 60ms   ----- Device Resetting Time old : 60
+/* SmartMedia Busy Time (1bit:0.1ms) */
+#define BUSY_PROG 200 /* tPROG   : 20ms  ----- Program Time old : 200 */
+#define BUSY_ERASE 4000 /* tBERASE : 400ms ----- Block Erase Time old : 4000 */
 
-// Hardware Timer (1bit:0.1ms)
-#define TIME_PON      3000      // 300ms ------ Power On Wait Time
-#define TIME_CDCHK    200       // 20ms  ------ Card Check Interval Timer
-#define TIME_WPCHK    50        // 5ms   ------ WP Check Interval Timer
-#define TIME_5VCHK    10        // 1ms   ------ 5V Check Interval Timer
+/*for 712 Test */
+/* #define BUSY_READ 1 *//* tR : 100us ----- Data transfer Time   old : 1 */
+/* #define BUSY_READ 10 *//* tR : 100us ----- Data transfer Time   old : 1 */
+
+#define BUSY_READ 200 /* tR : 20ms   ----- Data transfer Time   old : 1 */
+
+/* #define BUSY_RESET 60 *//* tRST : 6ms ----- Device Resetting Time old : 60 */
+
+#define BUSY_RESET 600 /* tRST : 60ms   ----- Device Resetting Time old : 60 */
+
+/* Hardware Timer (1bit:0.1ms) */
+#define TIME_PON      3000      /* 300ms ------ Power On Wait Time */
+#define TIME_CDCHK    200       /* 20ms  ------ Card Check Interval Timer */
+#define TIME_WPCHK    50        /* 5ms   ------ WP Check Interval Timer */
+#define TIME_5VCHK    10        /* 1ms   ------ 5V Check Interval Timer */
 
 /***************************************************************************
 Redundant Data
@@ -129,32 +134,32 @@
 SmartMedia Model & Attribute
 ***************************************************************************/
 /* SmartMedia Attribute */
-#define NOWP          0x00 // 0... .... No Write Protect
-#define WP            0x80 // 1... .... Write Protected
-#define MASK          0x00 // .00. .... NAND MASK ROM Model
-#define FLASH         0x20 // .01. .... NAND Flash ROM Model
-#define AD3CYC        0x00 // ...0 .... Address 3-cycle
-#define AD4CYC        0x10 // ...1 .... Address 4-cycle
-#define BS16          0x00 // .... 00.. 16page/block
-#define BS32          0x04 // .... 01.. 32page/block
-#define PS256         0x00 // .... ..00 256byte/page
-#define PS512         0x01 // .... ..01 512byte/page
-#define MWP           0x80 // WriteProtect mask
-#define MFLASH        0x60 // Flash Rom mask
-#define MADC          0x10 // Address Cycle
-#define MBS           0x0C // BlockSize mask
-#define MPS           0x03 // PageSize mask
+#define NOWP          0x00 /* 0... .... No Write Protect */
+#define WP            0x80 /* 1... .... Write Protected */
+#define MASK          0x00 /* .00. .... NAND MASK ROM Model */
+#define FLASH         0x20 /* .01. .... NAND Flash ROM Model */
+#define AD3CYC        0x00 /* ...0 .... Address 3-cycle */
+#define AD4CYC        0x10 /* ...1 .... Address 4-cycle */
+#define BS16          0x00 /* .... 00.. 16page/block */
+#define BS32          0x04 /* .... 01.. 32page/block */
+#define PS256         0x00 /* .... ..00 256byte/page */
+#define PS512         0x01 /* .... ..01 512byte/page */
+#define MWP           0x80 /* WriteProtect mask */
+#define MFLASH        0x60 /* Flash Rom mask */
+#define MADC          0x10 /* Address Cycle */
+#define MBS           0x0C /* BlockSize mask */
+#define MPS           0x03 /* PageSize mask */
 
 /* SmartMedia Model */
-#define NOSSFDC       0x00 // NO   SmartMedia
-#define SSFDC1MB      0x01 // 1MB  SmartMedia
-#define SSFDC2MB      0x02 // 2MB  SmartMedia
-#define SSFDC4MB      0x03 // 4MB  SmartMedia
-#define SSFDC8MB      0x04 // 8MB  SmartMedia
-#define SSFDC16MB     0x05 // 16MB SmartMedia
-#define SSFDC32MB     0x06 // 32MB SmartMedia
-#define SSFDC64MB     0x07 // 64MB SmartMedia
-#define SSFDC128MB    0x08 //128MB SmartMedia
+#define NOSSFDC       0x00 /* NO   SmartMedia */
+#define SSFDC1MB      0x01 /* 1MB  SmartMedia */
+#define SSFDC2MB      0x02 /* 2MB  SmartMedia */
+#define SSFDC4MB      0x03 /* 4MB  SmartMedia */
+#define SSFDC8MB      0x04 /* 8MB  SmartMedia */
+#define SSFDC16MB     0x05 /* 16MB SmartMedia */
+#define SSFDC32MB     0x06 /* 32MB SmartMedia */
+#define SSFDC64MB     0x07 /* 64MB SmartMedia */
+#define SSFDC128MB    0x08 /*128MB SmartMedia */
 #define SSFDC256MB    0x09
 #define SSFDC512MB    0x0A
 #define SSFDC1GB      0x0B
@@ -163,8 +168,7 @@
 /***************************************************************************
 Struct Definition
 ***************************************************************************/
-struct SSFDCTYPE
-{
+struct SSFDCTYPE {
 	BYTE Model;
 	BYTE Attribute;
 	BYTE MaxZones;
@@ -183,8 +187,7 @@
 	WORD MaxLogBlocks;
 } *SSFDCTYPE_T;
 
-struct ADDRESS
-{
+struct ADDRESS {
 	BYTE Zone;	/* Zone Number */
 	BYTE Sector;	/* Sector(512byte) Number on Block */
 	WORD PhyBlock;	/* Physical Block Number on Zone */
@@ -199,92 +202,112 @@
 	WORD LogBlock;	/* Logical Block Number of Zone */
 } *ADDRESS_T;
 
-struct CIS_AREA
-{
+struct CIS_AREA {
 	BYTE Sector;	/* Sector(512byte) Number on Block */
 	WORD PhyBlock;	/* Physical Block Number on Zone 0 */
 };
 
 
-//----- SMILMain.c ---------------------------------------------------
+extern BYTE IsSSFDCCompliance;
+extern BYTE IsXDCompliance;
+
+extern DWORD	ErrXDCode;
+extern DWORD	ErrCode;
+extern WORD	ReadBlock;
+extern WORD	WriteBlock;
+extern DWORD	MediaChange;
+
+extern struct SSFDCTYPE  Ssfdc;
+extern struct ADDRESS    Media;
+extern struct CIS_AREA   CisArea;
+
+/*
+ * SMILMain.c
+ */
 /******************************************/
-int         Init_D_SmartMedia           (void);
-int         Pwoff_D_SmartMedia          (void);
-int         Check_D_SmartMedia          (void);
-int         Check_D_Parameter           (struct us_data *,WORD *,BYTE *,BYTE *);
-int         Media_D_ReadSector          (struct us_data *,DWORD,WORD,BYTE *);
-int         Media_D_WriteSector         (struct us_data *,DWORD,WORD,BYTE *);
-int         Media_D_CopySector          (struct us_data *,DWORD,WORD,BYTE *);
-int         Media_D_EraseBlock          (struct us_data *,DWORD,WORD);
-int         Media_D_EraseAll            (struct us_data *);
+int         Init_D_SmartMedia(void);
+int         Pwoff_D_SmartMedia(void);
+int         Check_D_SmartMedia(void);
+int         Check_D_Parameter(struct us_data *, WORD *, BYTE *, BYTE *);
+int         Media_D_ReadSector(struct us_data *, DWORD, WORD, BYTE *);
+int         Media_D_WriteSector(struct us_data *, DWORD, WORD, BYTE *);
+int         Media_D_CopySector(struct us_data *, DWORD, WORD, BYTE *);
+int         Media_D_EraseBlock(struct us_data *, DWORD, WORD);
+int         Media_D_EraseAll(struct us_data *);
 /******************************************/
-int         Media_D_OneSectWriteStart   (struct us_data *,DWORD,BYTE *);
-int         Media_D_OneSectWriteNext    (struct us_data *,BYTE *);
-int         Media_D_OneSectWriteFlush   (struct us_data *);
+int         Media_D_OneSectWriteStart(struct us_data *, DWORD, BYTE *);
+int         Media_D_OneSectWriteNext(struct us_data *, BYTE *);
+int         Media_D_OneSectWriteFlush(struct us_data *);
 
 /******************************************/
-void        SM_EnableLED                (struct us_data *,BOOLEAN);
-void        Led_D_TernOn                (void);
-void        Led_D_TernOff               (void);
+extern int	SM_FreeMem(void);	/* ENE SM function */
+void        SM_EnableLED(struct us_data *, BOOLEAN);
+void        Led_D_TernOn(void);
+void        Led_D_TernOff(void);
 
-int         Media_D_EraseAllRedtData    (DWORD Index, BOOLEAN CheckBlock);
-//DWORD       Media_D_GetMediaInfo        (struct us_data * fdoExt, PIOCTL_MEDIA_INFO_IN pParamIn, PIOCTL_MEDIA_INFO_OUT pParamOut);
+int         Media_D_EraseAllRedtData(DWORD Index, BOOLEAN CheckBlock);
+/*DWORD Media_D_GetMediaInfo(struct us_data * fdoExt,
+	PIOCTL_MEDIA_INFO_IN pParamIn, PIOCTL_MEDIA_INFO_OUT pParamOut); */
 
-//----- SMILSub.c ----------------------------------------------------
+/*
+ * SMILSub.c
+ */
 /******************************************/
-int  Check_D_DataBlank            (BYTE *);
-int  Check_D_FailBlock            (BYTE *);
-int  Check_D_DataStatus           (BYTE *);
-int  Load_D_LogBlockAddr          (BYTE *);
-void Clr_D_RedundantData          (BYTE *);
-void Set_D_LogBlockAddr           (BYTE *);
-void Set_D_FailBlock              (BYTE *);
-void Set_D_DataStaus              (BYTE *);
+int  Check_D_DataBlank(BYTE *);
+int  Check_D_FailBlock(BYTE *);
+int  Check_D_DataStatus(BYTE *);
+int  Load_D_LogBlockAddr(BYTE *);
+void Clr_D_RedundantData(BYTE *);
+void Set_D_LogBlockAddr(BYTE *);
+void Set_D_FailBlock(BYTE *);
+void Set_D_DataStaus(BYTE *);
 
 /******************************************/
-void Ssfdc_D_Reset                (struct us_data *);
-int  Ssfdc_D_ReadCisSect          (struct us_data *, BYTE *,BYTE *);
-void Ssfdc_D_WriteRedtMode        (void);
-void Ssfdc_D_ReadID               (BYTE *, BYTE);
-int  Ssfdc_D_ReadSect             (struct us_data *, BYTE *,BYTE *);
-int  Ssfdc_D_ReadBlock            (struct us_data *, WORD, BYTE *,BYTE *);
-int  Ssfdc_D_WriteSect            (struct us_data *, BYTE *,BYTE *);
-int  Ssfdc_D_WriteBlock           (struct us_data *, WORD, BYTE *,BYTE *);
-int  Ssfdc_D_CopyBlock            (struct us_data *, WORD, BYTE *,BYTE *);
-int  Ssfdc_D_WriteSectForCopy     (struct us_data *, BYTE *,BYTE *);
-int  Ssfdc_D_EraseBlock           (struct us_data *);
-int  Ssfdc_D_ReadRedtData         (struct us_data *, BYTE *);
-int  Ssfdc_D_WriteRedtData        (struct us_data *, BYTE *);
-int  Ssfdc_D_CheckStatus          (void);
-int  Set_D_SsfdcModel             (BYTE);
-void Cnt_D_Reset                  (void);
-int  Cnt_D_PowerOn                (void);
-void Cnt_D_PowerOff               (void);
-void Cnt_D_LedOn                  (void);
-void Cnt_D_LedOff                 (void);
-int  Check_D_CntPower             (void);
-int  Check_D_CardExist            (void);
-int  Check_D_CardStsChg           (void);
-int  Check_D_SsfdcWP              (void);
-int  SM_ReadBlock                 (struct us_data *, BYTE *,BYTE *);
+void Ssfdc_D_Reset(struct us_data *);
+int  Ssfdc_D_ReadCisSect(struct us_data *, BYTE *, BYTE *);
+void Ssfdc_D_WriteRedtMode(void);
+void Ssfdc_D_ReadID(BYTE *, BYTE);
+int  Ssfdc_D_ReadSect(struct us_data *, BYTE *, BYTE *);
+int  Ssfdc_D_ReadBlock(struct us_data *, WORD, BYTE *, BYTE *);
+int  Ssfdc_D_WriteSect(struct us_data *, BYTE *, BYTE *);
+int  Ssfdc_D_WriteBlock(struct us_data *, WORD, BYTE *, BYTE *);
+int  Ssfdc_D_CopyBlock(struct us_data *, WORD, BYTE *, BYTE *);
+int  Ssfdc_D_WriteSectForCopy(struct us_data *, BYTE *, BYTE *);
+int  Ssfdc_D_EraseBlock(struct us_data *);
+int  Ssfdc_D_ReadRedtData(struct us_data *, BYTE *);
+int  Ssfdc_D_WriteRedtData(struct us_data *, BYTE *);
+int  Ssfdc_D_CheckStatus(void);
+int  Set_D_SsfdcModel(BYTE);
+void Cnt_D_Reset(void);
+int  Cnt_D_PowerOn(void);
+void Cnt_D_PowerOff(void);
+void Cnt_D_LedOn(void);
+void Cnt_D_LedOff(void);
+int  Check_D_CntPower(void);
+int  Check_D_CardExist(void);
+int  Check_D_CardStsChg(void);
+int  Check_D_SsfdcWP(void);
+int  SM_ReadBlock(struct us_data *, BYTE *, BYTE *);
 
-int  Ssfdc_D_ReadSect_DMA         (struct us_data *, BYTE *,BYTE *);
-int  Ssfdc_D_ReadSect_PIO         (struct us_data *, BYTE *,BYTE *);
-int  Ssfdc_D_WriteSect_DMA        (struct us_data *, BYTE *,BYTE *);
-int  Ssfdc_D_WriteSect_PIO        (struct us_data *, BYTE *,BYTE *);
+int  Ssfdc_D_ReadSect_DMA(struct us_data *, BYTE *, BYTE *);
+int  Ssfdc_D_ReadSect_PIO(struct us_data *, BYTE *, BYTE *);
+int  Ssfdc_D_WriteSect_DMA(struct us_data *, BYTE *, BYTE *);
+int  Ssfdc_D_WriteSect_PIO(struct us_data *, BYTE *, BYTE *);
 
 /******************************************/
-int  Check_D_ReadError            (BYTE *);
-int  Check_D_Correct              (BYTE *,BYTE *);
-int  Check_D_CISdata              (BYTE *,BYTE *);
-void Set_D_RightECC               (BYTE *);
+int  Check_D_ReadError(BYTE *);
+int  Check_D_Correct(BYTE *, BYTE *);
+int  Check_D_CISdata(BYTE *, BYTE *);
+void Set_D_RightECC(BYTE *);
 
-//----- SMILECC.c ----------------------------------------------------
-void calculate_ecc                (BYTE *, BYTE *, BYTE *, BYTE *, BYTE *);
-BYTE correct_data                 (BYTE *, BYTE *, BYTE,   BYTE,   BYTE);
-int  _Correct_D_SwECC             (BYTE *,BYTE *,BYTE *);
-void _Calculate_D_SwECC           (BYTE *,BYTE *);
+/*
+ * SMILECC.c
+ */
+void calculate_ecc(BYTE *, BYTE *, BYTE *, BYTE *, BYTE *);
+BYTE correct_data(BYTE *, BYTE *, BYTE,   BYTE,   BYTE);
+int  _Correct_D_SwECC(BYTE *, BYTE *, BYTE *);
+void _Calculate_D_SwECC(BYTE *, BYTE *);
 
-void SM_Init        (void);
+void SM_Init(void);
 
-#endif // already included
+#endif /* already included */
diff -druN linux-2.6.39-libre/drivers/staging/keucr/smilmain.c linux-3.0-rc7-libre/drivers/staging/keucr/smilmain.c
--- linux-2.6.39-libre/drivers/staging/keucr/smilmain.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/keucr/smilmain.c	2011-07-11 19:51:52.000000000 -0400
@@ -48,31 +48,27 @@
 DWORD ErrXDCode;
 DWORD ErrCode;
 //BYTE  SectBuf[SECTSIZE];
-BYTE  WorkBuf[SECTSIZE];
-BYTE  Redundant[REDTSIZE];
-BYTE  WorkRedund[REDTSIZE];
+static BYTE  WorkBuf[SECTSIZE];
+static BYTE  Redundant[REDTSIZE];
+static BYTE  WorkRedund[REDTSIZE];
 //WORD  Log2Phy[MAX_ZONENUM][MAX_LOGBLOCK];
-WORD  *Log2Phy[MAX_ZONENUM];                 // 128 x 1000,   Log2Phy[MAX_ZONENUM][MAX_LOGBLOCK];
-BYTE  Assign[MAX_ZONENUM][MAX_BLOCKNUM/8];
-WORD  AssignStart[MAX_ZONENUM];
+static WORD  *Log2Phy[MAX_ZONENUM];                 // 128 x 1000,   Log2Phy[MAX_ZONENUM][MAX_LOGBLOCK];
+static BYTE  Assign[MAX_ZONENUM][MAX_BLOCKNUM/8];
+static WORD  AssignStart[MAX_ZONENUM];
 WORD  ReadBlock;
 WORD  WriteBlock;
 DWORD MediaChange;
-DWORD SectCopyMode;
-
-extern struct SSFDCTYPE  Ssfdc;
-extern struct ADDRESS    Media;
-extern struct CIS_AREA   CisArea;
+static DWORD SectCopyMode;
 
 //BIT Control Macro
-BYTE BitData[] = { 0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80 } ;
+static BYTE BitData[] = { 0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80 } ;
 #define Set_D_Bit(a,b)    (a[(BYTE)((b)/8)]|= BitData[(b)%8])
 #define Clr_D_Bit(a,b)    (a[(BYTE)((b)/8)]&=~BitData[(b)%8])
 #define Chk_D_Bit(a,b)    (a[(BYTE)((b)/8)] & BitData[(b)%8])
 
 //extern PBYTE    SMHostAddr;
-extern BYTE     IsSSFDCCompliance;
-extern BYTE     IsXDCompliance;
+BYTE     IsSSFDCCompliance;
+BYTE     IsXDCompliance;
 
 
 //
@@ -102,12 +98,12 @@
 {
 	int	i;
 
-	printk("SM_FreeMem start\n");
+	pr_info("SM_FreeMem start\n");
 	for (i=0; i<MAX_ZONENUM; i++)
 	{
 		if (Log2Phy[i]!=NULL)
 		{
-			printk("Free Zone = %x, Addr = %p\n", i, Log2Phy[i]);
+			pr_info("Free Zone = %x, Addr = %p\n", i, Log2Phy[i]);
 			kfree(Log2Phy[i]);
 			Log2Phy[i] = NULL;
 		}
@@ -198,7 +194,7 @@
 	//SSFDCTYPE_T aa = (SSFDCTYPE_T ) &Ssfdc;
 	//ADDRESS_T   bb = (ADDRESS_T) &Media;
 
-	//printk("Media_D_CopySector !!!\n");
+	/* pr_info("Media_D_CopySector !!!\n"); */
 	if (Conv_D_MediaAddr(us, start))
 		return(ErrCode);
 
@@ -256,13 +252,13 @@
 	if (Media.PhyBlock==NO_ASSIGN)
 	{
 		Media.PhyBlock=WriteBlock;
-		return(SUCCESS);
+		return(SMSUCCESS);
 	}
 
 	Clr_D_Bit(Assign[Media.Zone],Media.PhyBlock);
 	Media.PhyBlock=WriteBlock;
 
-	return(SUCCESS);
+	return(SMSUCCESS);
 }
 /*
 //----- Media_D_WriteSector() ------------------------------------------
@@ -572,7 +568,7 @@
 //        default:         *c= 0;  *h= 0; *s= 0; ErrCode = ERR_NoSmartMedia;    return(ERROR);
 //    }
 //
-//    return(SUCCESS);
+//    return(SMSUCCESS);
 //}
 //
 ////Power Control & Media Exist Check Subroutine
@@ -599,7 +595,7 @@
 //        MediaChange = ERROR;
 //    //usleep(56*1024);
 //    if ((!Check_D_CntPower())&&(!MediaChange))  // �� power & Media �S�Q change, �h return success
-//        return(SUCCESS);
+//        return(SMSUCCESS);
 //    //usleep(56*1024);
 //
 //    if (Check_D_CardExist())                    // Check if card is not exist, return err
@@ -618,7 +614,7 @@
 //    //usleep(56*1024);
 //    Ssfdc_D_Reset(fdoExt);
 //    //usleep(56*1024);
-//    return(SUCCESS);
+//    return(SMSUCCESS);
 //}
 //
 ////-----Check_D_MediaExist() --------------------------------------------
@@ -630,7 +626,7 @@
 //    if (!Check_D_CardExist())
 //    {
 //        if (!MediaChange)
-//            return(SUCCESS);
+//            return(SMSUCCESS);
 //
 //        ErrCode = ERR_ChangedMedia;
 //        return(ERROR);
@@ -650,19 +646,19 @@
 //        return(ERROR);
 //    }
 //
-//    return(SUCCESS);
+//    return(SMSUCCESS);
 //}
 */
 //SmartMedia Physical Format Test Subroutine
 //----- Check_D_MediaFmt() ---------------------------------------------
 int Check_D_MediaFmt(struct us_data *us)
 {
-	printk("Check_D_MediaFmt\n");
+	pr_info("Check_D_MediaFmt\n");
 	//ULONG i,j, result=FALSE, zone,block;
 
 	//usleep(56*1024);
 	if (!MediaChange)
-		return(SUCCESS);
+		return(SMSUCCESS);
 
 	MediaChange  = ERROR;
 	SectCopyMode = COMPLETED;
@@ -682,8 +678,8 @@
 	}
 
 
-    MediaChange = SUCCESS;
-    return(SUCCESS);
+    MediaChange = SMSUCCESS;
+    return(SMSUCCESS);
 }
 /*
 ////----- Check_D_BlockIsFull() ----------------------------------
@@ -735,7 +731,7 @@
 //        return(ERROR);
 //    }
 //
-//    return(SUCCESS);
+//    return(SMSUCCESS);
 //}
 */
 //SmartMedia Physical Address Control Subroutine
@@ -767,7 +763,7 @@
 		Clr_D_RedundantData(Redundant);
 		Set_D_LogBlockAddr(Redundant);
 		Media.PhyBlock = Log2Phy[Media.Zone][Media.LogBlock];
-		return(SUCCESS);
+		return(SMSUCCESS);
 	}
 
 	ErrCode = ERR_OutOfLBA;
@@ -782,7 +778,7 @@
 	//ADDRESS_T   bb = (ADDRESS_T) &Media;
 
 	if (++Media.Sector<Ssfdc.MaxSectors)
-		return(SUCCESS);
+		return(SMSUCCESS);
 
 	if (Log2Phy[Media.Zone]==NULL)
 	{
@@ -801,7 +797,7 @@
 		Clr_D_RedundantData(Redundant);
 		Set_D_LogBlockAddr(Redundant);
 		Media.PhyBlock=Log2Phy[Media.Zone][Media.LogBlock];
-		return(SUCCESS);
+		return(SMSUCCESS);
 	}
 
 	Media.LogBlock=0;
@@ -822,7 +818,7 @@
 		Clr_D_RedundantData(Redundant);
 		Set_D_LogBlockAddr(Redundant);
 		Media.PhyBlock=Log2Phy[Media.Zone][Media.LogBlock];
-		return(SUCCESS);
+		return(SMSUCCESS);
 	}
 
 	Media.Zone=0;
@@ -838,7 +834,7 @@
     ADDRESS_T   bb = (ADDRESS_T) &Media;
 
     if (!Media.Sector)
-        return(SUCCESS);
+        return(SMSUCCESS);
 
     return(ERROR);
 }
@@ -852,7 +848,7 @@
     if (Media.Sector<(Ssfdc.MaxSectors-1))
         return(ERROR);
 
-    return(SUCCESS);
+    return(SMSUCCESS);
 }
 */
 //SmartMedia Read/Write Subroutine with Retry
@@ -862,7 +858,7 @@
 	DWORD err, retry;
 
 	if (!Read_D_PhyOneSect(us, count, buf))
-		return(SUCCESS);
+		return(SMSUCCESS);
 	if (ErrCode==ERR_HwError)
 		return(ERROR);
 	if (ErrCode==ERR_DataStatus)
@@ -872,7 +868,7 @@
 	if (Ssfdc.Attribute &MWP)
 	{
 		if (ErrCode==ERR_CorReadErr)
-			return(SUCCESS);
+			return(SMSUCCESS);
 		return(ERROR);
 	}
 
@@ -888,13 +884,13 @@
 
 		ErrCode = err;
 		if (ErrCode==ERR_CorReadErr)
-			return(SUCCESS);
+			return(SMSUCCESS);
 		return(ERROR);
 	}
 
 	MediaChange = ERROR;
 #else
-	if (ErrCode==ERR_CorReadErr) return(SUCCESS);
+	if (ErrCode==ERR_CorReadErr) return(SMSUCCESS);
 #endif
 
 	return(ERROR);
@@ -908,7 +904,7 @@
     ADDRESS_T   bb = (ADDRESS_T) &Media;
 
     if (!Write_D_PhyOneSect(fdoExt, count, buf))
-        return(SUCCESS);
+        return(SMSUCCESS);
     if (ErrCode==ERR_HwError)
         return(ERROR);
 
@@ -922,7 +918,7 @@
         }
 
         if (!Write_D_PhyOneSect(fdoExt, count, buf))
-            return(SUCCESS);
+            return(SMSUCCESS);
         if (ErrCode==ERR_HwError)
             return(ERROR);
     }
@@ -944,7 +940,7 @@
     for(retry=0; retry<2; retry++)
     {
         if (!Copy_D_BlockHead(fdoExt))
-            return(SUCCESS);
+            return(SMSUCCESS);
         if (ErrCode==ERR_HwError)
             return(ERROR);
     }
@@ -959,7 +955,7 @@
     DWORD retry;
 
     if (!Copy_D_BlockTail(fdoExt))
-        return(SUCCESS);
+        return(SMSUCCESS);
     if (ErrCode==ERR_HwError)
         return(ERROR);
 
@@ -973,7 +969,7 @@
         }
 
         if (!Copy_D_BlockTail(fdoExt))
-            return(SUCCESS);
+            return(SMSUCCESS);
         if (ErrCode==ERR_HwError)
             return(ERROR);
     }
@@ -995,7 +991,7 @@
 //    ADDRESS_T   bb = (ADDRESS_T) &Media;
 //
 //    if (Media.PhyBlock==NO_ASSIGN)
-//        return(SUCCESS);
+//        return(SMSUCCESS);
 //
 //    if (Log2Phy[Media.Zone]==NULL)
 //    {
@@ -1023,7 +1019,7 @@
 //
 //    Clr_D_Bit(Assign[Media.Zone],Media.PhyBlock);
 //    Media.PhyBlock=NO_ASSIGN;
-//    return(SUCCESS);
+//    return(SMSUCCESS);
 //}
 //
 ////SmartMedia Erase Subroutine
@@ -1076,7 +1072,7 @@
 //            }
 //
 //        }
-//    return(SUCCESS);
+//    return(SMSUCCESS);
 //}
 */
 //SmartMedia Physical Sector Data Copy Subroutine
@@ -1116,7 +1112,7 @@
 
 	Media.PhyBlock=WriteBlock;
 	Media.Sector=sect;
-	return(SUCCESS);
+	return(SMSUCCESS);
 }
 /*
 //----- Copy_D_BlockHead() ---------------------------------------------
@@ -1149,7 +1145,7 @@
 
     Media.PhyBlock=WriteBlock;
     Media.Sector=sect;
-    return(SUCCESS);
+    return(SMSUCCESS);
 }
 
 //----- Copy_D_BlockTail() ---------------------------------------------
@@ -1178,7 +1174,7 @@
 
     Media.PhyBlock=WriteBlock;
     Media.Sector=sect;
-    return(SUCCESS);
+    return(SMSUCCESS);
 }
 
 //----- Reassign_D_BlockHead() -----------------------------------------
@@ -1226,7 +1222,7 @@
     ReadBlock=block;
     Media.Sector=sect;
     Media.PhyBlock=WriteBlock;
-    return(SUCCESS);
+    return(SMSUCCESS);
 }
 */
 //SmartMedia Physical Block Assign/Release Subroutine
@@ -1246,7 +1242,7 @@
 			Media.PhyBlock=WriteBlock;
 			SectCopyMode=REQ_ERASE;
 			//ErrXDCode = NO_ERROR;
-			return(SUCCESS);
+			return(SMSUCCESS);
 		}
 	}
 
@@ -1259,7 +1255,7 @@
 			Media.PhyBlock=WriteBlock;
 			SectCopyMode=REQ_ERASE;
 			//ErrXDCode = NO_ERROR;
-			return(SUCCESS);
+			return(SMSUCCESS);
 		}
 	}
 
@@ -1282,7 +1278,7 @@
 	SectCopyMode=COMPLETED;
 
 	if (mode==COMPLETED)
-		return(SUCCESS);
+		return(SMSUCCESS);
 
 	Log2Phy[Media.Zone][Media.LogBlock]=WriteBlock;
 	Media.PhyBlock=ReadBlock;
@@ -1290,7 +1286,7 @@
 	if (Media.PhyBlock==NO_ASSIGN)
 	{
 		Media.PhyBlock=WriteBlock;
-		return(SUCCESS);
+		return(SMSUCCESS);
 	}
 
 	if (mode==REQ_ERASE)
@@ -1307,7 +1303,7 @@
 		return(ERROR);
 
 	Media.PhyBlock=WriteBlock;
-	return(SUCCESS);
+	return(SMSUCCESS);
 }
 
 //----- Release_D_WriteBlock() -----------------------------------------
@@ -1322,7 +1318,7 @@
 		return(ERROR);
 
 	Media.PhyBlock=ReadBlock;
-	return(SUCCESS);
+	return(SMSUCCESS);
 }
 
 //SmartMedia Physical Sector Data Copy Subroutine
@@ -1334,7 +1330,7 @@
 	//SSFDCTYPE_T aa = (SSFDCTYPE_T ) &Ssfdc;
 	//ADDRESS_T   bb = (ADDRESS_T) &Media;
 
-	//printk("Copy_D_PhyOneSect --- Secotr = %x\n", Media.Sector);
+	/* pr_info("Copy_D_PhyOneSect --- Secotr = %x\n", Media.Sector); */
 	if (ReadBlock!=NO_ASSIGN)
 	{
 		Media.PhyBlock=ReadBlock;
@@ -1355,9 +1351,9 @@
 			if (Check_D_DataStatus(WorkRedund))
 			{ err=ERROR; break; }
 			if (!Check_D_ReadError(WorkRedund))
-			{ err=SUCCESS; break; }
+			{ err=SMSUCCESS; break; }
 			if (!Check_D_Correct(WorkBuf,WorkRedund))
-			{ err=SUCCESS; break; }
+			{ err=SMSUCCESS; break; }
 
 			err=ERROR;
 			SectCopyMode=REQ_FAIL;
@@ -1365,7 +1361,7 @@
 	}
 	else
 	{
-		err=SUCCESS;
+		err=SMSUCCESS;
 		for(i=0; i<SECTSIZE; i++)
 			WorkBuf[i]=DUMMY_DATA;
 		Clr_D_RedundantData(WorkRedund);
@@ -1386,7 +1382,7 @@
 	{ ErrCode = ERR_WriteFault; return(ERROR); }
 
 	Media.PhyBlock=ReadBlock;
-	return(SUCCESS);
+	return(SMSUCCESS);
 }
 
 //SmartMedia Physical Sector Read/Write/Erase Subroutine
@@ -1402,7 +1398,7 @@
 	{
 		for(i=0; i<SECTSIZE; i++)
 			*buf++=DUMMY_DATA;
-		return(SUCCESS);
+		return(SMSUCCESS);
 	}
 
 	for(retry=0; retry<2; retry++)
@@ -1424,7 +1420,7 @@
 		{ ErrCode = ERR_DataStatus; return(ERROR); }
 
 		if (!Check_D_ReadError(Redundant))
-			return(SUCCESS);
+			return(SMSUCCESS);
 
 		if (!Check_D_Correct(buf,Redundant))
 		{ ErrCode = ERR_CorReadErr; return(ERROR); }
@@ -1446,7 +1442,7 @@
     if (Ssfdc_D_CheckStatus())
     { ErrCode = ERR_WriteFault; return(ERROR); }
 
-    return(SUCCESS);
+    return(SMSUCCESS);
 }
 */
 //----- Erase_D_PhyOneBlock() ------------------------------------------
@@ -1460,7 +1456,7 @@
 	if (Ssfdc_D_CheckStatus())
 	{ ErrCode = ERR_WriteFault; return(ERROR); }
 
-	return(SUCCESS);
+	return(SMSUCCESS);
 }
 
 //SmartMedia Physical Format Check Local Subroutine
@@ -1544,7 +1540,7 @@
 //       }
 //    }
 
-    return(SUCCESS);
+    return(SMSUCCESS);
 }
 
 //----- Search_D_CIS() -------------------------------------------------
@@ -1600,7 +1596,7 @@
 			CisArea.PhyBlock=Media.PhyBlock;
 			CisArea.Sector=Media.Sector;
 			Ssfdc_D_Reset(us);
-			return(SUCCESS);
+			return(SMSUCCESS);
 		}
 
 		Media.Sector++;
@@ -1620,7 +1616,8 @@
 	if (Log2Phy[Media.Zone]==NULL)
 	{
 		Log2Phy[Media.Zone] = kmalloc(MAX_LOGBLOCK*sizeof(WORD), GFP_KERNEL);
-		//printk("ExAllocatePool Zone = %x, Addr = %x\n", Media.Zone, Log2Phy[Media.Zone]);
+		/* pr_info("ExAllocatePool Zone = %x, Addr = %x\n",
+				Media.Zone, Log2Phy[Media.Zone]); */
 		if (Log2Phy[Media.Zone]==NULL)
 			return(ERROR);
 	}
@@ -1630,7 +1627,8 @@
 	//for(Media.Zone=0; Media.Zone<MAX_ZONENUM; Media.Zone++)
 	//for(Media.Zone=0; Media.Zone<Ssfdc.MaxZones; Media.Zone++)
 	{
-		//printk("Make_D_LogTable --- MediaZone = 0x%x\n", Media.Zone);
+		/* pr_info("Make_D_LogTable --- MediaZone = 0x%x\n",
+							Media.Zone); */
 		for(Media.LogBlock=0; Media.LogBlock<Ssfdc.MaxLogBlocks; Media.LogBlock++)
 			Log2Phy[Media.Zone][Media.LogBlock]=NO_ASSIGN;
 
@@ -1735,7 +1733,7 @@
 	} // End for (Media.Zone<MAX_ZONENUM)
 
 	Ssfdc_D_Reset(us);
-	return(SUCCESS);
+	return(SMSUCCESS);
 }
 
 //----- MarkFail_D_PhyOneBlock() ---------------------------------------
@@ -1763,7 +1761,7 @@
 
 	Ssfdc_D_Reset(us);
 	Media.Sector=sect;
-	return(SUCCESS);
+	return(SMSUCCESS);
 }
 /*
 //
@@ -1821,7 +1819,7 @@
 //
 //    Ssfdc_D_Reset(fdoExt);
 //
-//    return(SUCCESS);
+//    return(SMSUCCESS);
 //}
 //
 ////----- Media_D_GetMediaInfo() ---------------------------------------
diff -druN linux-2.6.39-libre/drivers/staging/keucr/smilsub.c linux-3.0-rc7-libre/drivers/staging/keucr/smilsub.c
--- linux-2.6.39-libre/drivers/staging/keucr/smilsub.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/keucr/smilsub.c	2011-07-11 19:51:52.000000000 -0400
@@ -42,10 +42,8 @@
 struct ADDRESS                  Media;
 struct CIS_AREA                 CisArea;
 
-BYTE                            EccBuf[6];
+static BYTE                            EccBuf[6];
 extern PBYTE                    SMHostAddr;
-extern BYTE                     IsSSFDCCompliance;
-extern BYTE                     IsXDCompliance;
 extern DWORD                    ErrXDCode;
 
 extern WORD  ReadBlock;
@@ -67,7 +65,7 @@
 		if (*redundant++!=0xFF)
 			return(ERROR);
 
-	return(SUCCESS);
+	return(SMSUCCESS);
 }
 
 //----- Check_D_FailBlock() --------------------------------------------
@@ -76,13 +74,13 @@
 	redundant+=REDT_BLOCK;
 
 	if (*redundant==0xFF)
-		return(SUCCESS);
+		return(SMSUCCESS);
 	if (!*redundant)
 		return(ERROR);
 	if (hweight8(*redundant)<7)
 		return(ERROR);
 
-	return(SUCCESS);
+	return(SMSUCCESS);
 }
 
 //----- Check_D_DataStatus() -------------------------------------------
@@ -91,7 +89,7 @@
 	redundant+=REDT_DATA;
 
 	if (*redundant==0xFF)
-		return(SUCCESS);
+		return(SMSUCCESS);
 	if (!*redundant)
 	{
 		ErrXDCode = ERR_DataStatus;
@@ -103,7 +101,7 @@
 	if (hweight8(*redundant)<5)
 		return(ERROR);
 
-	return(SUCCESS);
+	return(SMSUCCESS);
 }
 
 //----- Load_D_LogBlockAddr() ------------------------------------------
@@ -118,17 +116,17 @@
 
 	if (addr1==addr2)
 		if ((addr1 &0xF000)==0x1000)
-		{ Media.LogBlock=(addr1 &0x0FFF)/2; return(SUCCESS); }
+		{ Media.LogBlock=(addr1 &0x0FFF)/2; return(SMSUCCESS); }
 
 	if (hweight16((WORD)(addr1^addr2))!=0x01) return(ERROR);
 
 	if ((addr1 &0xF000)==0x1000)
 		if (!(hweight16(addr1) &0x01))
-		{ Media.LogBlock=(addr1 &0x0FFF)/2; return(SUCCESS); }
+		{ Media.LogBlock=(addr1 &0x0FFF)/2; return(SMSUCCESS); }
 
 	if ((addr2 &0xF000)==0x1000)
 		if (!(hweight16(addr2) &0x01))
-		{ Media.LogBlock=(addr2 &0x0FFF)/2; return(SUCCESS); }
+		{ Media.LogBlock=(addr2 &0x0FFF)/2; return(SMSUCCESS); }
 
 	return(ERROR);
 }
@@ -222,7 +220,7 @@
 	}
 
 	Media.Zone=zone; Media.PhyBlock=block; Media.Sector=sector;
-	return(SUCCESS);
+	return(SMSUCCESS);
 }
 /*
 ////----- Ssfdc_D_WriteRedtMode() ----------------------------------------
@@ -428,7 +426,7 @@
 //
 //    if (!_Hw_D_ChkCardIn())
 //       return(ERROR);
-//    return(SUCCESS);
+//    return(SMSUCCESS);
 //}
 //
 ////----- Ssfdc_D_ReadSect_PIO() ---------------------------------------------
@@ -451,7 +449,7 @@
 //
 //    _Calc_D_ECCdata(buf);
 //    _Set_D_SsfdcRdStandby();
-//    return(SUCCESS);
+//    return(SMSUCCESS);
 //}
 
 // 6250 CMD 3
@@ -509,7 +507,7 @@
 //        ENE_Print("Error\n");
 //  }
 
-    return(SUCCESS);
+    return(SMSUCCESS);
 }
 */
 //----- Ssfdc_D_CopyBlock() --------------------------------------------
@@ -614,7 +612,7 @@
 //        ENE_Print("Error\n");
 //  }
 
-    return(SUCCESS);
+    return(SMSUCCESS);
 }
 //
 ////----- Ssfdc_D_WriteSect_DMA() --------------------------------------------
@@ -704,7 +702,7 @@
 //    if (!_Hw_D_ChkCardIn())
 //       return(ERROR);
 //
-//    return(SUCCESS);
+//    return(SMSUCCESS);
 //}
 //
 ////----- Ssfdc_D_WriteSect_PIO() --------------------------------------------
@@ -729,7 +727,7 @@
 //
 //    _Set_D_SsfdcWrStandby();
 //    _Set_D_SsfdcRdStandby();
-//    return(SUCCESS);
+//    return(SMSUCCESS);
 //}
 */
 //----- Ssfdc_D_WriteSectForCopy() -------------------------------------
@@ -893,14 +891,14 @@
 int Ssfdc_D_CheckStatus(void)
 {
     // Driver ����
-    return(SUCCESS);
+    return(SMSUCCESS);
     //_Set_D_SsfdcRdCmd(RDSTATUS);
     //
     //if (_Check_D_SsfdcStatus())
     //{ _Set_D_SsfdcRdStandby(); return(ERROR); }
     //
     //_Set_D_SsfdcRdStandby();
-    //return(SUCCESS);
+    //return(SMSUCCESS);
 }
 /*
 ////NAND Memory (SmartMedia) Control Subroutine for Read Data
@@ -1095,7 +1093,7 @@
 //
 //    do {
 //        if (!_Hw_D_ChkBusy())
-//            return(SUCCESS);
+//            return(SMSUCCESS);
 //        EDelay(100);
 //        count++;
 //    } while (count<=time);
@@ -1109,7 +1107,7 @@
 //    if (_Hw_D_InData() & WR_FAIL)
 //        return(ERROR);
 //
-//    return(SUCCESS);
+//    return(SMSUCCESS);
 //}
 //
 //// For 712
@@ -1339,7 +1337,7 @@
             return(ERROR);
     }
 
-    return(SUCCESS);
+    return(SMSUCCESS);
 }
 
 //----- _Check_D_DevCode() ---------------------------------------------
@@ -1388,7 +1386,7 @@
 //    if (_Hw_D_ChkPower())
 //    {
 //        _Hw_D_EnableOB();                       // Set SM_REG_CTRL_5 Reg. to 0x83
-//        return(SUCCESS);
+//        return(SMSUCCESS);
 //    }
 //
 //    _Hw_D_SetVccOff();
@@ -1419,7 +1417,7 @@
 //int Check_D_CntPower(void)
 //{
 //    if (_Hw_D_ChkPower())
-//        return(SUCCESS); // Power On
+//        return(SMSUCCESS); // Power On
 //
 //    return(ERROR);       // Power Off
 //}
@@ -1431,7 +1429,7 @@
 //
 //    if (!_Hw_D_ChkStatus()) // Not Status Change
 //        if (_Hw_D_ChkCardIn())
-//            return(SUCCESS); // Card exist in Slot
+//            return(SMSUCCESS); // Card exist in Slot
 //
 //    for(i=0,j=0,k=0; i<16; i++) {
 //        if (_Hw_D_ChkCardIn()) // Status Change
@@ -1444,7 +1442,7 @@
 //        }
 //
 //        if (j>3)
-//            return(SUCCESS); // Card exist in Slot
+//            return(SMSUCCESS); // Card exist in Slot
 //        if (k>3)
 //            return(ERROR); // NO Card exist in Slot
 //
@@ -1460,12 +1458,12 @@
 //    if (_Hw_D_ChkStatus())
 //        return(ERROR); // Status Change
 //
-//    return(SUCCESS);   // Not Status Change
+//    return(SMSUCCESS);   // Not Status Change
 //}
 //
 ////----- Check_D_SsfdcWP() ----------------------------------------------
 //int Check_D_SsfdcWP(void)
-//{ // ERROR: WP, SUCCESS: Not WP
+//{ // ERROR: WP, SMSUCCESS: Not WP
 //    char i;
 //
 //    for(i=0; i<8; i++) {
@@ -1474,7 +1472,7 @@
 //        _Wait_D_Timer(TIME_WPCHK);
 //    }
 //
-//    return(SUCCESS);
+//    return(SMSUCCESS);
 //}
 //
 */
@@ -1482,13 +1480,13 @@
 //----- Check_D_ReadError() ----------------------------------------------
 int Check_D_ReadError(BYTE *redundant)
 {
-	return SUCCESS;
+	return SMSUCCESS;
 }
 
 //----- Check_D_Correct() ----------------------------------------------
 int Check_D_Correct(BYTE *buf,BYTE *redundant)
 {
-	return SUCCESS;
+	return SMSUCCESS;
 }
 
 //----- Check_D_CISdata() ----------------------------------------------
@@ -1500,7 +1498,7 @@
 	int cis_len = sizeof(cis);
 
 	if (!IsSSFDCCompliance && !IsXDCompliance)
-		return SUCCESS;
+		return SMSUCCESS;
 
 	if (!memcmp(redundant + 0x0D, EccBuf, 3))
 		return memcmp(buf, cis, cis_len);
@@ -1599,5 +1597,5 @@
     if (!NT_SUCCESS(ntStatus))
        return(ERROR);
 
-    return(SUCCESS);
+    return(SMSUCCESS);
 }*/
diff -druN linux-2.6.39-libre/drivers/staging/keucr/smscsi.c linux-3.0-rc7-libre/drivers/staging/keucr/smscsi.c
--- linux-2.6.39-libre/drivers/staging/keucr/smscsi.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/keucr/smscsi.c	2011-07-11 19:51:52.000000000 -0400
@@ -20,8 +20,6 @@
 int SM_SCSI_Read            (struct us_data *us, struct scsi_cmnd *srb);
 int SM_SCSI_Write           (struct us_data *us, struct scsi_cmnd *srb);
 
-extern struct SSFDCTYPE     Ssfdc;
-extern struct ADDRESS       Media;
 extern PBYTE                SMHostAddr;
 extern DWORD                ErrXDCode;
 
diff -druN linux-2.6.39-libre/drivers/staging/keucr/transport.c linux-3.0-rc7-libre/drivers/staging/keucr/transport.c
--- linux-2.6.39-libre/drivers/staging/keucr/transport.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/keucr/transport.c	2011-07-11 19:51:52.000000000 -0400
@@ -1,3 +1,5 @@
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/sched.h>
 #include <linux/errno.h>
 #include <linux/slab.h>
@@ -13,23 +15,27 @@
 /***********************************************************************
  * Data transfer routines
  ***********************************************************************/
-//----- usb_stor_blocking_completion() ---------------------
+/*
+ * usb_stor_blocking_completion()
+ */
 static void usb_stor_blocking_completion(struct urb *urb)
 {
 	struct completion *urb_done_ptr = urb->context;
 
-	//printk("transport --- usb_stor_blocking_completion\n");
+	/* pr_info("transport --- usb_stor_blocking_completion\n"); */
 	complete(urb_done_ptr);
 }
 
-//----- usb_stor_msg_common() ---------------------
+/*
+ * usb_stor_msg_common()
+ */
 static int usb_stor_msg_common(struct us_data *us, int timeout)
 {
 	struct completion urb_done;
 	long timeleft;
 	int status;
 
-	//printk("transport --- usb_stor_msg_common\n");
+	/* pr_info("transport --- usb_stor_msg_common\n"); */
 	if (test_bit(US_FLIDX_ABORTING, &us->dflags))
 		return -EIO;
 
@@ -52,35 +58,36 @@
 
 	set_bit(US_FLIDX_URB_ACTIVE, &us->dflags);
 
-	if (test_bit(US_FLIDX_ABORTING, &us->dflags))
-	{
-		if (test_and_clear_bit(US_FLIDX_URB_ACTIVE, &us->dflags))
-		{
-			//printk("-- cancelling URB\n");
+	if (test_bit(US_FLIDX_ABORTING, &us->dflags)) {
+		if (test_and_clear_bit(US_FLIDX_URB_ACTIVE, &us->dflags)) {
+			/* pr_info("-- cancelling URB\n"); */
 			usb_unlink_urb(us->current_urb);
 		}
 	}
 
-	timeleft = wait_for_completion_interruptible_timeout(&urb_done, timeout ? : MAX_SCHEDULE_TIMEOUT);
+	timeleft = wait_for_completion_interruptible_timeout(&urb_done,
+					timeout ? : MAX_SCHEDULE_TIMEOUT);
 	clear_bit(US_FLIDX_URB_ACTIVE, &us->dflags);
 
-	if (timeleft <= 0)
-	{
-		//printk("%s -- cancelling URB\n", timeleft == 0 ? "Timeout" : "Signal");
+	if (timeleft <= 0) {
+		/* pr_info("%s -- cancelling URB\n",
+			timeleft == 0 ? "Timeout" : "Signal"); */
 		usb_kill_urb(us->current_urb);
 	}
 
 	return us->current_urb->status;
 }
 
-//----- usb_stor_control_msg() ---------------------
+/*
+ * usb_stor_control_msg()
+ */
 int usb_stor_control_msg(struct us_data *us, unsigned int pipe,
 		 u8 request, u8 requesttype, u16 value, u16 index,
 		 void *data, u16 size, int timeout)
 {
 	int status;
 
-	//printk("transport --- usb_stor_control_msg\n");
+	/* pr_info("transport --- usb_stor_control_msg\n"); */
 
 	/* fill in the devrequest structure */
 	us->cr->bRequestType = requesttype;
@@ -91,7 +98,7 @@
 
 	/* fill and submit the URB */
 	usb_fill_control_urb(us->current_urb, us->pusb_dev, pipe,
-			 (unsigned char*) us->cr, data, size,
+			 (unsigned char *) us->cr, data, size,
 			 usb_stor_blocking_completion, NULL);
 	status = usb_stor_msg_common(us, timeout);
 
@@ -101,14 +108,16 @@
 	return status;
 }
 
-//----- usb_stor_clear_halt() ---------------------
+/*
+ * usb_stor_clear_halt()
+ */
 int usb_stor_clear_halt(struct us_data *us, unsigned int pipe)
 {
 	int result;
 	int endp = usb_pipeendpoint(pipe);
 
-	//printk("transport --- usb_stor_clear_halt\n");
-	if (usb_pipein (pipe))
+	/* pr_info("transport --- usb_stor_clear_halt\n"); */
+	if (usb_pipein(pipe))
 		endp |= USB_DIR_IN;
 
 	result = usb_stor_control_msg(us, us->send_ctrl_pipe,
@@ -118,103 +127,109 @@
 
 	/* reset the endpoint toggle */
 	if (result >= 0)
-		//usb_settoggle(us->pusb_dev, usb_pipeendpoint(pipe), usb_pipeout(pipe), 0);
-                usb_reset_endpoint(us->pusb_dev, endp);
+		/* usb_settoggle(us->pusb_dev, usb_pipeendpoint(pipe),
+						usb_pipeout(pipe), 0); */
+		usb_reset_endpoint(us->pusb_dev, endp);
 
 	return result;
 }
 
-//----- interpret_urb_result() ---------------------
+/*
+ * interpret_urb_result()
+ */
 static int interpret_urb_result(struct us_data *us, unsigned int pipe,
 		unsigned int length, int result, unsigned int partial)
 {
-	//printk("transport --- interpret_urb_result\n");
+	/* pr_info("transport --- interpret_urb_result\n"); */
 	switch (result) {
 	/* no error code; did we send all the data? */
 	case 0:
-		if (partial != length)
-		{
-			//printk("-- short transfer\n");
+		if (partial != length) {
+			/* pr_info("-- short transfer\n"); */
 			return USB_STOR_XFER_SHORT;
 		}
-		//printk("-- transfer complete\n");
+		/* pr_info("-- transfer complete\n"); */
 		return USB_STOR_XFER_GOOD;
 	case -EPIPE:
-		if (usb_pipecontrol(pipe))
-		{
-			//printk("-- stall on control pipe\n");
+		if (usb_pipecontrol(pipe)) {
+			/* pr_info("-- stall on control pipe\n"); */
 			return USB_STOR_XFER_STALLED;
 		}
-		//printk("clearing endpoint halt for pipe 0x%x\n", pipe);
+		/* pr_info("clearing endpoint halt for pipe 0x%x\n", pipe); */
 		if (usb_stor_clear_halt(us, pipe) < 0)
 			return USB_STOR_XFER_ERROR;
 		return USB_STOR_XFER_STALLED;
 	case -EOVERFLOW:
-		//printk("-- babble\n");
+		/* pr_info("-- babble\n"); */
 		return USB_STOR_XFER_LONG;
 	case -ECONNRESET:
-		//printk("-- transfer cancelled\n");
+		/* pr_info("-- transfer cancelled\n"); */
 		return USB_STOR_XFER_ERROR;
 	case -EREMOTEIO:
-		//printk("-- short read transfer\n");
+		/* pr_info("-- short read transfer\n"); */
 		return USB_STOR_XFER_SHORT;
 	case -EIO:
-		//printk("-- abort or disconnect in progress\n");
+		/* pr_info("-- abort or disconnect in progress\n"); */
 		return USB_STOR_XFER_ERROR;
 	default:
-		//printk("-- unknown error\n");
+		/* pr_info("-- unknown error\n"); */
 		return USB_STOR_XFER_ERROR;
 	}
 }
 
-//----- usb_stor_bulk_transfer_buf() ---------------------
+/*
+ * usb_stor_bulk_transfer_buf()
+ */
 int usb_stor_bulk_transfer_buf(struct us_data *us, unsigned int pipe,
 	void *buf, unsigned int length, unsigned int *act_len)
 {
 	int result;
 
-	//printk("transport --- usb_stor_bulk_transfer_buf\n");
+	/* pr_info("transport --- usb_stor_bulk_transfer_buf\n"); */
 
 	/* fill and submit the URB */
-	usb_fill_bulk_urb(us->current_urb, us->pusb_dev, pipe, buf, length, usb_stor_blocking_completion, NULL);
+	usb_fill_bulk_urb(us->current_urb, us->pusb_dev, pipe, buf,
+				length, usb_stor_blocking_completion, NULL);
 	result = usb_stor_msg_common(us, 0);
 
 	/* store the actual length of the data transferred */
 	if (act_len)
 		*act_len = us->current_urb->actual_length;
 
-	return interpret_urb_result(us, pipe, length, result, us->current_urb->actual_length);
+	return interpret_urb_result(us, pipe, length, result,
+					us->current_urb->actual_length);
 }
 
-//----- usb_stor_bulk_transfer_sglist() ---------------------
+/*
+ * usb_stor_bulk_transfer_sglist()
+ */
 static int usb_stor_bulk_transfer_sglist(struct us_data *us, unsigned int pipe,
 		struct scatterlist *sg, int num_sg, unsigned int length,
 		unsigned int *act_len)
 {
 	int result;
 
-	//printk("transport --- usb_stor_bulk_transfer_sglist\n");
+	/* pr_info("transport --- usb_stor_bulk_transfer_sglist\n"); */
 	if (test_bit(US_FLIDX_ABORTING, &us->dflags))
 		return USB_STOR_XFER_ERROR;
 
 	/* initialize the scatter-gather request block */
-	result = usb_sg_init(&us->current_sg, us->pusb_dev, pipe, 0, sg, num_sg, length, GFP_NOIO);
-	if (result)
-	{
-		//printk("usb_sg_init returned %d\n", result);
+	result = usb_sg_init(&us->current_sg, us->pusb_dev, pipe, 0,
+					sg, num_sg, length, GFP_NOIO);
+	if (result) {
+		/* pr_info("usb_sg_init returned %d\n", result); */
 		return USB_STOR_XFER_ERROR;
 	}
 
-	/* since the block has been initialized successfully, it's now okay to cancel it */
+	/* since the block has been initialized successfully,
+					it's now okay to cancel it */
 	set_bit(US_FLIDX_SG_ACTIVE, &us->dflags);
 
 	/* did an abort/disconnect occur during the submission? */
-	if (test_bit(US_FLIDX_ABORTING, &us->dflags))
-	{
+	if (test_bit(US_FLIDX_ABORTING, &us->dflags)) {
 		/* cancel the request, if it hasn't been cancelled already */
-		if (test_and_clear_bit(US_FLIDX_SG_ACTIVE, &us->dflags))
-		{
-			//printk("-- cancelling sg request\n");
+		if (test_and_clear_bit(US_FLIDX_SG_ACTIVE, &us->dflags)) {
+			/* pr_info("-- cancelling sg request\n"); */
 			usb_sg_cancel(&us->current_sg);
 		}
 	}
@@ -227,11 +242,15 @@
 	if (act_len)
 		*act_len = us->current_sg.bytes;
 
-	return interpret_urb_result(us, pipe, length, result, us->current_sg.bytes);
+	return interpret_urb_result(us, pipe, length,
+					result, us->current_sg.bytes);
 }
 
-//----- usb_stor_bulk_srb() ---------------------
-int usb_stor_bulk_srb(struct us_data* us, unsigned int pipe, struct scsi_cmnd* srb)
+/*
+ * usb_stor_bulk_srb()
+ */
+int usb_stor_bulk_srb(struct us_data *us, unsigned int pipe,
+					struct scsi_cmnd *srb)
 {
 	unsigned int partial;
 	int result = usb_stor_bulk_transfer_sglist(us, pipe, scsi_sglist(srb),
@@ -242,27 +261,27 @@
 	return result;
 }
 
-//----- usb_stor_bulk_transfer_sg() ---------------------
-int usb_stor_bulk_transfer_sg(struct us_data* us, unsigned int pipe,
+/*
+ * usb_stor_bulk_transfer_sg()
+ */
+int usb_stor_bulk_transfer_sg(struct us_data *us, unsigned int pipe,
 		void *buf, unsigned int length_left, int use_sg, int *residual)
 {
 	int result;
 	unsigned int partial;
 
-	//printk("transport --- usb_stor_bulk_transfer_sg\n");
+	/* pr_info("transport --- usb_stor_bulk_transfer_sg\n"); */
 	/* are we scatter-gathering? */
-	if (use_sg)
-	{
+	if (use_sg) {
 		/* use the usb core scatter-gather primitives */
 		result = usb_stor_bulk_transfer_sglist(us, pipe,
 				(struct scatterlist *) buf, use_sg,
 				length_left, &partial);
 		length_left -= partial;
-	}
-	else
-	{
+	} else {
 		/* no scatter-gather, just make the request */
-		result = usb_stor_bulk_transfer_buf(us, pipe, buf, length_left, &partial);
+		result = usb_stor_bulk_transfer_buf(us, pipe, buf,
+							length_left, &partial);
 		length_left -= partial;
 	}
 
@@ -275,37 +294,37 @@
 /***********************************************************************
  * Transport routines
  ***********************************************************************/
-//----- usb_stor_invoke_transport() ---------------------
+/*
+ * usb_stor_invoke_transport()
+ */
 void usb_stor_invoke_transport(struct scsi_cmnd *srb, struct us_data *us)
 {
 	int need_auto_sense;
 	int result;
 
-	//printk("transport --- usb_stor_invoke_transport\n");
+	/* pr_info("transport --- usb_stor_invoke_transport\n"); */
 	usb_stor_print_cmd(srb);
 	/* send the command to the transport layer */
 	scsi_set_resid(srb, 0);
-	result = us->transport(srb, us); //usb_stor_Bulk_transport;
-	
-	/* if the command gets aborted by the higher layers, we need to short-circuit all other processing */
-	if (test_bit(US_FLIDX_TIMED_OUT, &us->dflags))
-	{
-		//printk("-- command was aborted\n");
+	result = us->transport(srb, us); /* usb_stor_Bulk_transport; */
+
+	/* if the command gets aborted by the higher layers,
+		we need to short-circuit all other processing */
+	if (test_bit(US_FLIDX_TIMED_OUT, &us->dflags)) {
+		/* pr_info("-- command was aborted\n"); */
 		srb->result = DID_ABORT << 16;
 		goto Handle_Errors;
 	}
 
 	/* if there is a transport error, reset and don't auto-sense */
-	if (result == USB_STOR_TRANSPORT_ERROR)
-	{
-		//printk("-- transport indicates error, resetting\n");
+	if (result == USB_STOR_TRANSPORT_ERROR) {
+		/* pr_info("-- transport indicates error, resetting\n"); */
 		srb->result = DID_ERROR << 16;
 		goto Handle_Errors;
 	}
 
 	/* if the transport provided its own sense data, don't auto-sense */
-	if (result == USB_STOR_TRANSPORT_NO_SENSE)
-	{
+	if (result == USB_STOR_TRANSPORT_NO_SENSE) {
 		srb->result = SAM_STAT_CHECK_CONDITION;
 		return;
 	}
@@ -315,34 +334,34 @@
 	/* Determine if we need to auto-sense */
 	need_auto_sense = 0;
 
-	if ((us->protocol == USB_PR_CB || us->protocol == USB_PR_DPCM_USB) && srb->sc_data_direction != DMA_FROM_DEVICE)
-	{
-		//printk("-- CB transport device requiring auto-sense\n");
+	if ((us->protocol == USB_PR_CB || us->protocol == USB_PR_DPCM_USB) &&
+				srb->sc_data_direction != DMA_FROM_DEVICE) {
+		/* pr_info("-- CB transport device requiring auto-sense\n"); */
 		need_auto_sense = 1;
 	}
 
-	if (result == USB_STOR_TRANSPORT_FAILED)
-	{
-		//printk("-- transport indicates command failure\n");
+	if (result == USB_STOR_TRANSPORT_FAILED) {
+		/* pr_info("-- transport indicates command failure\n"); */
 		need_auto_sense = 1;
 	}
 
 	/* Now, if we need to do the auto-sense, let's do it */
-	if (need_auto_sense)
-	{
+	if (need_auto_sense) {
 		int temp_result;
 		struct scsi_eh_save ses;
 
-		printk("Issuing auto-REQUEST_SENSE\n");
+		pr_info("Issuing auto-REQUEST_SENSE\n");
 
 		scsi_eh_prep_cmnd(srb, &ses, NULL, 0, US_SENSE_SIZE);
 
 		/* we must do the protocol translation here */
-		if (us->subclass == USB_SC_RBC || us->subclass == USB_SC_SCSI || us->subclass == USB_SC_CYP_ATACB)
+		if (us->subclass == USB_SC_RBC ||
+			us->subclass == USB_SC_SCSI ||
+			us->subclass == USB_SC_CYP_ATACB) {
 			srb->cmd_len = 6;
-		else
+		} else {
 			srb->cmd_len = 12;
-
+		}
 		/* issue the auto-sense command */
 		scsi_set_resid(srb, 0);
 		temp_result = us->transport(us->srb, us);
@@ -350,15 +369,13 @@
 		/* let's clean up right away */
 		scsi_eh_restore_cmnd(srb, &ses);
 
-		if (test_bit(US_FLIDX_TIMED_OUT, &us->dflags))
-		{
-			//printk("-- auto-sense aborted\n");
+		if (test_bit(US_FLIDX_TIMED_OUT, &us->dflags)) {
+			/* pr_info("-- auto-sense aborted\n"); */
 			srb->result = DID_ABORT << 16;
 			goto Handle_Errors;
 		}
-		if (temp_result != USB_STOR_TRANSPORT_GOOD)
-		{
-			//printk("-- auto-sense failure\n");
+		if (temp_result != USB_STOR_TRANSPORT_GOOD) {
+			/* pr_info("-- auto-sense failure\n"); */
 			srb->result = DID_ERROR << 16;
 			if (!(us->fflags & US_FL_SCM_MULT_TARG))
 				goto Handle_Errors;
@@ -371,16 +388,17 @@
 		if (result == USB_STOR_TRANSPORT_GOOD &&
 			(srb->sense_buffer[2] & 0xaf) == 0 &&
 			srb->sense_buffer[12] == 0 &&
-			srb->sense_buffer[13] == 0)
-		{
+			srb->sense_buffer[13] == 0) {
 			srb->result = SAM_STAT_GOOD;
 			srb->sense_buffer[0] = 0x0;
 		}
 	}
 
 	/* Did we transfer less than the minimum amount required? */
-	if (srb->result == SAM_STAT_GOOD &&	scsi_bufflen(srb) - scsi_get_resid(srb) < srb->underflow)
-		srb->result = (DID_ERROR << 16);//v02 | (SUGGEST_RETRY << 24);
+	if (srb->result == SAM_STAT_GOOD && scsi_bufflen(srb) -
+				scsi_get_resid(srb) < srb->underflow)
+		srb->result = (DID_ERROR << 16);
+		/* v02 | (SUGGEST_RETRY << 24); */
 
 	return;
 
@@ -394,8 +412,7 @@
 	result = usb_stor_port_reset(us);
 	mutex_lock(&us->dev_mutex);
 
-	if (result < 0)
-	{
+	if (result < 0) {
 		scsi_lock(us_to_host(us));
 		usb_stor_report_device_reset(us);
 		scsi_unlock(us_to_host(us));
@@ -404,61 +421,64 @@
 	clear_bit(US_FLIDX_RESETTING, &us->dflags);
 }
 
-//----- ENE_stor_invoke_transport() ---------------------
+/*
+ * ENE_stor_invoke_transport()
+ */
 void ENE_stor_invoke_transport(struct scsi_cmnd *srb, struct us_data *us)
 {
-	int result=0;
+	int result = 0;
 
-	//printk("transport --- ENE_stor_invoke_transport\n");
+	/* pr_info("transport --- ENE_stor_invoke_transport\n"); */
 	usb_stor_print_cmd(srb);
 	/* send the command to the transport layer */
 	scsi_set_resid(srb, 0);
 	if (!(us->MS_Status.Ready || us->SM_Status.Ready))
 		result = ENE_InitMedia(us);
-	
+
 	if (us->Power_IsResum == true) {
 		result = ENE_InitMedia(us);
-		us->Power_IsResum = false;		
-	}	
-	
-	if (us->MS_Status.Ready)	result = MS_SCSIIrp(us, srb);
-	if (us->SM_Status.Ready)	result = SM_SCSIIrp(us, srb);
+		us->Power_IsResum = false;
+	}
 
-	/* if the command gets aborted by the higher layers, we need to short-circuit all other processing */
-	if (test_bit(US_FLIDX_TIMED_OUT, &us->dflags))
-	{
-		//printk("-- command was aborted\n");
+	if (us->MS_Status.Ready)
+		result = MS_SCSIIrp(us, srb);
+	if (us->SM_Status.Ready)
+		result = SM_SCSIIrp(us, srb);
+
+	/* if the command gets aborted by the higher layers,
+		we need to short-circuit all other processing */
+	if (test_bit(US_FLIDX_TIMED_OUT, &us->dflags)) {
+		/* pr_info("-- command was aborted\n"); */
 		srb->result = DID_ABORT << 16;
 		goto Handle_Errors;
 	}
 
 	/* if there is a transport error, reset and don't auto-sense */
-	if (result == USB_STOR_TRANSPORT_ERROR)
-	{
-		//printk("-- transport indicates error, resetting\n");
+	if (result == USB_STOR_TRANSPORT_ERROR) {
+		/* pr_info("-- transport indicates error, resetting\n"); */
 		srb->result = DID_ERROR << 16;
 		goto Handle_Errors;
 	}
 
 	/* if the transport provided its own sense data, don't auto-sense */
-	if (result == USB_STOR_TRANSPORT_NO_SENSE)
-	{
+	if (result == USB_STOR_TRANSPORT_NO_SENSE) {
 		srb->result = SAM_STAT_CHECK_CONDITION;
 		return;
 	}
 
 	srb->result = SAM_STAT_GOOD;
-	if (result == USB_STOR_TRANSPORT_FAILED)
-	{
-		//printk("-- transport indicates command failure\n");
-		//need_auto_sense = 1;
+	if (result == USB_STOR_TRANSPORT_FAILED) {
+		/* pr_info("-- transport indicates command failure\n"); */
+		/* need_auto_sense = 1; */
 		BuildSenseBuffer(srb, us->SrbStatus);
 		srb->result = SAM_STAT_CHECK_CONDITION;
 	}
 
 	/* Did we transfer less than the minimum amount required? */
-	if (srb->result == SAM_STAT_GOOD && scsi_bufflen(srb) - scsi_get_resid(srb) < srb->underflow)
-		srb->result = (DID_ERROR << 16);//v02 | (SUGGEST_RETRY << 24);
+	if (srb->result == SAM_STAT_GOOD && scsi_bufflen(srb) -
+					scsi_get_resid(srb) < srb->underflow)
+		srb->result = (DID_ERROR << 16);
+		/* v02 | (SUGGEST_RETRY << 24); */
 
 	return;
 
@@ -472,8 +492,7 @@
 	result = usb_stor_port_reset(us);
 	mutex_lock(&us->dev_mutex);
 
-	if (result < 0)
-	{
+	if (result < 0) {
 		scsi_lock(us_to_host(us));
 		usb_stor_report_device_reset(us);
 		scsi_unlock(us_to_host(us));
@@ -482,52 +501,63 @@
 	clear_bit(US_FLIDX_RESETTING, &us->dflags);
 }
 
-//----- BuildSenseBuffer() -------------------------------------------
+/*
+ * BuildSenseBuffer()
+ */
 void BuildSenseBuffer(struct scsi_cmnd *srb, int SrbStatus)
 {
-    BYTE    *buf = srb->sense_buffer;
-    BYTE    asc;
+	BYTE    *buf = srb->sense_buffer;
+	BYTE    asc;
 
-    printk("transport --- BuildSenseBuffer\n");
-    switch (SrbStatus)
-    {
-        case SS_NOT_READY:        asc = 0x3a;    break;  // sense key = 0x02
-        case SS_MEDIUM_ERR:       asc = 0x0c;    break;  // sense key = 0x03
-        case SS_ILLEGAL_REQUEST:  asc = 0x20;    break;  // sense key = 0x05
-        default:                  asc = 0x00;    break;  // ??
-    }
+	pr_info("transport --- BuildSenseBuffer\n");
+	switch (SrbStatus) {
+	case SS_NOT_READY:
+		asc = 0x3a;
+		break;  /*  sense key = 0x02 */
+	case SS_MEDIUM_ERR:
+		asc = 0x0c;
+		break;  /*  sense key = 0x03 */
+	case SS_ILLEGAL_REQUEST:
+		asc = 0x20;
+		break;  /*  sense key = 0x05 */
+	default:
+		asc = 0x00;
+		break;  /*  ?? */
+	}
 
-    memset(buf, 0, 18);
-    buf[0x00] = 0xf0;
-    buf[0x02] = SrbStatus;
-    buf[0x07] = 0x0b;
-    buf[0x0c] = asc;
+	memset(buf, 0, 18);
+	buf[0x00] = 0xf0;
+	buf[0x02] = SrbStatus;
+	buf[0x07] = 0x0b;
+	buf[0x0c] = asc;
 }
 
-//----- usb_stor_stop_transport() ---------------------
+/*
+ * usb_stor_stop_transport()
+ */
 void usb_stor_stop_transport(struct us_data *us)
 {
-	//printk("transport --- usb_stor_stop_transport\n");
+	/* pr_info("transport --- usb_stor_stop_transport\n"); */
 
-	if (test_and_clear_bit(US_FLIDX_URB_ACTIVE, &us->dflags))
-	{
-		//printk("-- cancelling URB\n");
+	if (test_and_clear_bit(US_FLIDX_URB_ACTIVE, &us->dflags)) {
+		/* pr_info("-- cancelling URB\n"); */
 		usb_unlink_urb(us->current_urb);
 	}
 
-	if (test_and_clear_bit(US_FLIDX_SG_ACTIVE, &us->dflags))
-	{
-		//printk("-- cancelling sg request\n");
+	if (test_and_clear_bit(US_FLIDX_SG_ACTIVE, &us->dflags)) {
+		/* pr_info("-- cancelling sg request\n"); */
 		usb_sg_cancel(&us->current_sg);
 	}
 }
 
-//----- usb_stor_Bulk_max_lun() ---------------------
+/*
+ * usb_stor_Bulk_max_lun()
+ */
 int usb_stor_Bulk_max_lun(struct us_data *us)
 {
 	int result;
 
-	//printk("transport --- usb_stor_Bulk_max_lun\n");
+	/* pr_info("transport --- usb_stor_Bulk_max_lun\n"); */
 	/* issue the command */
 	us->iobuf[0] = 0;
 	result = usb_stor_control_msg(us, us->recv_ctrl_pipe,
@@ -536,7 +566,8 @@
 				 USB_RECIP_INTERFACE,
 				 0, us->ifnum, us->iobuf, 1, HZ);
 
-	//printk("GetMaxLUN command result is %d, data is %d\n", result, us->iobuf[0]);
+	/* pr_info("GetMaxLUN command result is %d, data is %d\n",
+						result, us->iobuf[0]); */
 
 	/* if we have a successful request, return the result */
 	if (result > 0)
@@ -545,7 +576,9 @@
 	return 0;
 }
 
-//----- usb_stor_Bulk_transport() ---------------------
+/*
+ * usb_stor_Bulk_transport()
+ */
 int usb_stor_Bulk_transport(struct scsi_cmnd *srb, struct us_data *us)
 {
 	struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf;
@@ -557,10 +590,9 @@
 	unsigned int cswlen;
 	unsigned int cbwlen = US_BULK_CB_WRAP_LEN;
 
-	//printk("transport --- usb_stor_Bulk_transport\n");
+	/* pr_info("transport --- usb_stor_Bulk_transport\n"); */
 	/* Take care of BULK32 devices; set extra byte to 0 */
-	if (unlikely(us->fflags & US_FL_BULK32))
-	{
+	if (unlikely(us->fflags & US_FL_BULK32)) {
 		cbwlen = 32;
 		us->iobuf[31] = 0;
 	}
@@ -579,27 +611,32 @@
 	memset(bcb->CDB, 0, sizeof(bcb->CDB));
 	memcpy(bcb->CDB, srb->cmnd, bcb->Length);
 
-	// send command
+	/*  send command */
 	/* send it to out endpoint */
-	/*printk("Bulk Command S 0x%x T 0x%x L %d F %d Trg %d LUN %d CL %d\n",
+	/* pr_info("Bulk Command S 0x%x T 0x%x L %d F %d Trg %d LUN %d CL %d\n",
 			le32_to_cpu(bcb->Signature), bcb->Tag,
 			le32_to_cpu(bcb->DataTransferLength), bcb->Flags,
 			(bcb->Lun >> 4), (bcb->Lun & 0x0F),
-			bcb->Length);*/
-	result = usb_stor_bulk_transfer_buf(us, us->send_bulk_pipe, bcb, cbwlen, NULL);
-	//printk("Bulk command transfer result=%d\n", result);
+			bcb->Length); */
+	result = usb_stor_bulk_transfer_buf(us, us->send_bulk_pipe,
+						bcb, cbwlen, NULL);
+	/* pr_info("Bulk command transfer result=%d\n", result); */
 	if (result != USB_STOR_XFER_GOOD)
 		return USB_STOR_TRANSPORT_ERROR;
 
 	if (unlikely(us->fflags & US_FL_GO_SLOW))
 		udelay(125);
 
-	// R/W data
-	if (transfer_length)
-	{
-		unsigned int pipe = srb->sc_data_direction == DMA_FROM_DEVICE ? us->recv_bulk_pipe : us->send_bulk_pipe;
+	/*  R/W data */
+	if (transfer_length) {
+		unsigned int pipe;
+		if (srb->sc_data_direction == DMA_FROM_DEVICE)
+			pipe = us->recv_bulk_pipe;
+		else
+			pipe = us->send_bulk_pipe;
+
 		result = usb_stor_bulk_srb(us, pipe, srb);
-		//printk("Bulk data transfer result 0x%x\n", result);
+		/* pr_info("Bulk data transfer result 0x%x\n", result); */
 		if (result == USB_STOR_XFER_ERROR)
 			return USB_STOR_TRANSPORT_ERROR;
 
@@ -608,55 +645,56 @@
 	}
 
 	/* get CSW for device status */
-	//printk("Attempting to get CSW...\n");
-	result = usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe, bcs, US_BULK_CS_WRAP_LEN, &cswlen);
+	/* pr_info("Attempting to get CSW...\n"); */
+	result = usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe, bcs,
+						US_BULK_CS_WRAP_LEN, &cswlen);
 
-	if (result == USB_STOR_XFER_SHORT && cswlen == 0)
-	{
-		//printk("Received 0-length CSW; retrying...\n");
-		result = usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe, bcs, US_BULK_CS_WRAP_LEN, &cswlen);
+	if (result == USB_STOR_XFER_SHORT && cswlen == 0) {
+		/* pr_info("Received 0-length CSW; retrying...\n"); */
+		result = usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe, bcs,
+						US_BULK_CS_WRAP_LEN, &cswlen);
 	}
 
 	/* did the attempt to read the CSW fail? */
-	if (result == USB_STOR_XFER_STALLED)
-	{
+	if (result == USB_STOR_XFER_STALLED) {
 		/* get the status again */
-		//printk("Attempting to get CSW (2nd try)...\n");
-		result = usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe, bcs, US_BULK_CS_WRAP_LEN, NULL);
+		/* pr_info("Attempting to get CSW (2nd try)...\n"); */
+		result = usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe, bcs,
+						US_BULK_CS_WRAP_LEN, NULL);
 	}
 
 	/* if we still have a failure at this point, we're in trouble */
-	//printk("Bulk status result = %d\n", result);
+	/* pr_info("Bulk status result = %d\n", result); */
 	if (result != USB_STOR_XFER_GOOD)
 		return USB_STOR_TRANSPORT_ERROR;
 
 	/* check bulk status */
 	residue = le32_to_cpu(bcs->Residue);
-	//printk("Bulk Status S 0x%x T 0x%x R %u Stat 0x%x\n", le32_to_cpu(bcs->Signature), bcs->Tag, residue, bcs->Status);
-	if (!(bcs->Tag == us->tag || (us->fflags & US_FL_BULK_IGNORE_TAG)) || bcs->Status > US_BULK_STAT_PHASE)
-	{
-		//printk("Bulk logical error\n");
+	/* pr_info("Bulk Status S 0x%x T 0x%x R %u Stat 0x%x\n",
+				le32_to_cpu(bcs->Signature),
+				bcs->Tag, residue, bcs->Status); */
+	if (!(bcs->Tag == us->tag ||
+		(us->fflags & US_FL_BULK_IGNORE_TAG)) ||
+		bcs->Status > US_BULK_STAT_PHASE) {
+		/* pr_info("Bulk logical error\n"); */
 		return USB_STOR_TRANSPORT_ERROR;
 	}
 
-	if (!us->bcs_signature)
-	{
+	if (!us->bcs_signature) {
 		us->bcs_signature = bcs->Signature;
-		//if (us->bcs_signature != cpu_to_le32(US_BULK_CS_SIGN))
-		//	printk("Learnt BCS signature 0x%08X\n", le32_to_cpu(us->bcs_signature));
-	}
-	else if (bcs->Signature != us->bcs_signature)
-	{
-		/*printk("Signature mismatch: got %08X, expecting %08X\n",
+		/* if (us->bcs_signature != cpu_to_le32(US_BULK_CS_SIGN)) */
+		/* pr_info("Learnt BCS signature 0x%08X\n",
+				le32_to_cpu(us->bcs_signature)); */
+	} else if (bcs->Signature != us->bcs_signature) {
+		/* pr_info("Signature mismatch: got %08X, expecting %08X\n",
 			  le32_to_cpu(bcs->Signature),
-			  le32_to_cpu(us->bcs_signature));*/
+			  le32_to_cpu(us->bcs_signature)); */
 		return USB_STOR_TRANSPORT_ERROR;
 	}
 
 	/* try to compute the actual residue, based on how much data
 	 * was really transferred and what the device tells us */
-	if (residue && !(us->fflags & US_FL_IGNORE_RESIDUE))
-	{
+	if (residue && !(us->fflags & US_FL_IGNORE_RESIDUE)) {
 
 		/* Heuristically detect devices that generate bogus residues
 		 * by seeing what happens with INQUIRY and READ CAPACITY
@@ -667,34 +705,31 @@
 					((srb->cmnd[0] == INQUIRY &&
 						transfer_length == 36) ||
 					(srb->cmnd[0] == READ_CAPACITY &&
-						transfer_length == 8)))
-		{
+						transfer_length == 8))) {
 			us->fflags |= US_FL_IGNORE_RESIDUE;
 
-		}
-		else
-		{
+		} else {
 			residue = min(residue, transfer_length);
-			scsi_set_resid(srb, max(scsi_get_resid(srb), (int) residue));
+			scsi_set_resid(srb, max(scsi_get_resid(srb),
+							(int) residue));
 		}
 	}
 
 	/* based on the status code, we report good or bad */
-	switch (bcs->Status)
-	{
-		case US_BULK_STAT_OK:
-			if (fake_sense)
-			{
-				memcpy(srb->sense_buffer, usb_stor_sense_invalidCDB, sizeof(usb_stor_sense_invalidCDB));
-				return USB_STOR_TRANSPORT_NO_SENSE;
-			}
-			return USB_STOR_TRANSPORT_GOOD;
+	switch (bcs->Status) {
+	case US_BULK_STAT_OK:
+		if (fake_sense) {
+			memcpy(srb->sense_buffer, usb_stor_sense_invalidCDB,
+					sizeof(usb_stor_sense_invalidCDB));
+			return USB_STOR_TRANSPORT_NO_SENSE;
+		}
+		return USB_STOR_TRANSPORT_GOOD;
 
-		case US_BULK_STAT_FAIL:
-			return USB_STOR_TRANSPORT_FAILED;
+	case US_BULK_STAT_FAIL:
+		return USB_STOR_TRANSPORT_FAILED;
 
-		case US_BULK_STAT_PHASE:
-			return USB_STOR_TRANSPORT_ERROR;
+	case US_BULK_STAT_PHASE:
+		return USB_STOR_TRANSPORT_ERROR;
 	}
 	return USB_STOR_TRANSPORT_ERROR;
 }
@@ -702,7 +737,9 @@
 /***********************************************************************
  * Reset routines
  ***********************************************************************/
-//----- usb_stor_reset_common() ---------------------
+/*
+ * usb_stor_reset_common()
+ */
 static int usb_stor_reset_common(struct us_data *us,
 		u8 request, u8 requesttype,
 		u16 value, u16 index, void *data, u16 size)
@@ -710,69 +747,75 @@
 	int result;
 	int result2;
 
-	//printk("transport --- usb_stor_reset_common\n");
-	if (test_bit(US_FLIDX_DISCONNECTING, &us->dflags))
-	{
-		//printk("No reset during disconnect\n");
+	/* pr_info("transport --- usb_stor_reset_common\n"); */
+	if (test_bit(US_FLIDX_DISCONNECTING, &us->dflags)) {
+		/* pr_info("No reset during disconnect\n"); */
 		return -EIO;
 	}
 
-	result = usb_stor_control_msg(us, us->send_ctrl_pipe, request, requesttype, value, index, data, size,	5*HZ);
-	if (result < 0)
-	{
-		//printk("Soft reset failed: %d\n", result);
+	result = usb_stor_control_msg(us, us->send_ctrl_pipe,
+			request, requesttype, value, index, data, size,	5*HZ);
+
+	if (result < 0) {
+		/* pr_info("Soft reset failed: %d\n", result); */
 		return result;
 	}
 
-	wait_event_interruptible_timeout(us->delay_wait, test_bit(US_FLIDX_DISCONNECTING, &us->dflags),	HZ*6);
-	if (test_bit(US_FLIDX_DISCONNECTING, &us->dflags))
-	{
-		//printk("Reset interrupted by disconnect\n");
+	wait_event_interruptible_timeout(us->delay_wait,
+			test_bit(US_FLIDX_DISCONNECTING, &us->dflags),	HZ*6);
+
+	if (test_bit(US_FLIDX_DISCONNECTING, &us->dflags)) {
+		/* pr_info("Reset interrupted by disconnect\n"); */
 		return -EIO;
 	}
 
-	//printk("Soft reset: clearing bulk-in endpoint halt\n");
+	/* pr_info("Soft reset: clearing bulk-in endpoint halt\n"); */
 	result = usb_stor_clear_halt(us, us->recv_bulk_pipe);
 
-	//printk("Soft reset: clearing bulk-out endpoint halt\n");
+	/* pr_info("Soft reset: clearing bulk-out endpoint halt\n"); */
 	result2 = usb_stor_clear_halt(us, us->send_bulk_pipe);
 
 	/* return a result code based on the result of the clear-halts */
 	if (result >= 0)
 		result = result2;
-	//if (result < 0)
-	//	printk("Soft reset failed\n");
-	//else
-	//	printk("Soft reset done\n");
+	/* if (result < 0) */
+		/* pr_info("Soft reset failed\n"); */
+	/* else */
+		/* pr_info("Soft reset done\n"); */
 	return result;
 }
 
-//----- usb_stor_Bulk_reset() ---------------------
+/*
+ * usb_stor_Bulk_reset()
+ */
 int usb_stor_Bulk_reset(struct us_data *us)
 {
-	//printk("transport --- usb_stor_Bulk_reset\n");
+	/* pr_info("transport --- usb_stor_Bulk_reset\n"); */
 	return usb_stor_reset_common(us, US_BULK_RESET_REQUEST,
 				 USB_TYPE_CLASS | USB_RECIP_INTERFACE,
 				 0, us->ifnum, NULL, 0);
 }
 
-//----- usb_stor_port_reset() ---------------------
+/*
+ * usb_stor_port_reset()
+ */
 int usb_stor_port_reset(struct us_data *us)
 {
 	int result;
 
-	//printk("transport --- usb_stor_port_reset\n");
+	/* pr_info("transport --- usb_stor_port_reset\n"); */
 	result = usb_lock_device_for_reset(us->pusb_dev, us->pusb_intf);
 	if (result < 0)
-		printk("unable to lock device for reset: %d\n", result);
+		pr_info("unable to lock device for reset: %d\n", result);
 	else {
 		/* Were we disconnected while waiting for the lock? */
 		if (test_bit(US_FLIDX_DISCONNECTING, &us->dflags)) {
 			result = -EIO;
-			//printk("No reset during disconnect\n");
+			/* pr_info("No reset during disconnect\n"); */
 		} else {
 			result = usb_reset_device(us->pusb_dev);
-			//printk("usb_reset_composite_device returns %d\n", result);
+			/* pr_info("usb_reset_composite_device returns %d\n",
+								result); */
 		}
 		usb_unlock_device(us->pusb_dev);
 	}
diff -druN linux-2.6.39-libre/drivers/staging/keucr/transport.h linux-3.0-rc7-libre/drivers/staging/keucr/transport.h
--- linux-2.6.39-libre/drivers/staging/keucr/transport.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/keucr/transport.h	2011-07-11 19:51:52.000000000 -0400
@@ -8,7 +8,7 @@
 /* command block wrapper */
 struct bulk_cb_wrap {
 	__le32	Signature;			/* contains 'USBC' */
-	__u32	Tag;					/* unique per command id */
+	__u32	Tag;				/* unique per command id */
 	__le32	DataTransferLength;	/* size of data */
 	__u8	Flags;				/* direction in bit 0 */
 	__u8	Lun;					/* LUN normally 0 */
@@ -49,9 +49,9 @@
 
 /* Transport return codes */
 #define USB_STOR_TRANSPORT_GOOD	0	/* Transport good, command good	*/
-#define USB_STOR_TRANSPORT_FAILED	1	/* Transport good, command failed   */
-#define USB_STOR_TRANSPORT_NO_SENSE	2	/* Command failed, no auto-sense    */
-#define USB_STOR_TRANSPORT_ERROR	3	/* Transport bad (i.e. device dead) */
+#define USB_STOR_TRANSPORT_FAILED 1	/* Transport good, command failed */
+#define USB_STOR_TRANSPORT_NO_SENSE 2	/* Command failed, no auto-sense */
+#define USB_STOR_TRANSPORT_ERROR 3	/* Transport bad (i.e. device dead) */
 
 /*
  * We used to have USB_STOR_XFER_ABORTED and USB_STOR_TRANSPORT_ABORTED
@@ -64,11 +64,11 @@
 /* CBI accept device specific command */
 #define US_CBI_ADSC		0
 extern int usb_stor_Bulk_transport(struct scsi_cmnd *, struct us_data*);
-extern int usb_stor_Bulk_max_lun(struct us_data*);
-extern int usb_stor_Bulk_reset(struct us_data*);
+extern int usb_stor_Bulk_max_lun(struct us_data *);
+extern int usb_stor_Bulk_reset(struct us_data *);
 extern void usb_stor_print_cmd(struct scsi_cmnd *);
 extern void usb_stor_invoke_transport(struct scsi_cmnd *, struct us_data*);
-extern void usb_stor_stop_transport(struct us_data*);
+extern void usb_stor_stop_transport(struct us_data *);
 extern int usb_stor_control_msg(struct us_data *us, unsigned int pipe,
 		u8 request, u8 requesttype, u16 value, u16 index,
 		void *data, u16 size, int timeout);
@@ -77,23 +77,26 @@
 		void *buf, unsigned int length, unsigned int *act_len);
 extern int usb_stor_bulk_transfer_sg(struct us_data *us, unsigned int pipe,
 		void *buf, unsigned int length, int use_sg, int *residual);
-extern int usb_stor_bulk_srb(struct us_data* us, unsigned int pipe,
-		struct scsi_cmnd* srb);
+extern int usb_stor_bulk_srb(struct us_data *us, unsigned int pipe,
+		struct scsi_cmnd *srb);
 extern int usb_stor_port_reset(struct us_data *us);
 
 /* Protocol handling routines */
 enum xfer_buf_dir	{TO_XFER_BUF, FROM_XFER_BUF};
-extern unsigned int usb_stor_access_xfer_buf(struct us_data*, unsigned char *buffer,
-	unsigned int buflen, struct scsi_cmnd *srb, struct scatterlist **,
-	unsigned int *offset, enum xfer_buf_dir dir);
-extern void usb_stor_set_xfer_buf(struct us_data*, unsigned char *buffer, unsigned int buflen, struct scsi_cmnd *srb,
+extern unsigned int usb_stor_access_xfer_buf(struct us_data*,
+	unsigned char *buffer, unsigned int buflen, struct scsi_cmnd *srb,
+	struct scatterlist **, unsigned int *offset, enum xfer_buf_dir dir);
+extern void usb_stor_set_xfer_buf(struct us_data*, unsigned char *buffer,
+	unsigned int buflen, struct scsi_cmnd *srb,
 	unsigned int dir);
 
-// ENE scsi function
-extern void ENE_stor_invoke_transport(struct scsi_cmnd *, struct us_data*);
-extern int ENE_InitMedia(struct us_data*);
-extern int ENE_MSInit(struct us_data*);
-extern int ENE_SMInit(struct us_data*);
+/*
+ * ENE scsi function
+ */
+extern void ENE_stor_invoke_transport(struct scsi_cmnd *, struct us_data *);
+extern int ENE_InitMedia(struct us_data *);
+extern int ENE_MSInit(struct us_data *);
+extern int ENE_SMInit(struct us_data *);
 extern int ENE_SendScsiCmd(struct us_data*, BYTE, void*, int);
 extern int ENE_LoadBinCode(struct us_data*, BYTE);
 extern int ENE_Read_BYTE(struct us_data*, WORD index, void *buf);
@@ -101,41 +104,54 @@
 extern int ENE_Write_Data(struct us_data*, void *buf, unsigned int length);
 extern void BuildSenseBuffer(struct scsi_cmnd *, int);
 
-// ENE scsi function
+/*
+ * ENE scsi function
+ */
 extern int MS_SCSIIrp(struct us_data *us, struct scsi_cmnd *srb);
 extern int SM_SCSIIrp(struct us_data *us, struct scsi_cmnd *srb);
 
-// ENE MS function
-extern int 	MS_CardInit(struct us_data *us);
+/*
+ * ENE MS function
+ */
+extern int	MS_CardInit(struct us_data *us);
 extern void	MS_LibFreeAllocatedArea(struct us_data *us);
 extern void	MS_LibFreeWriteBuf(struct us_data *us);
 extern int	MS_LibFreeLogicalMap(struct us_data *us);
-extern int	MS_LibForceSetLogicalPair(struct us_data *us, WORD logblk, WORD phyblk);
-extern int	MS_ReaderReadPage(struct us_data *us, DWORD PhyBlockAddr, BYTE PageNum, DWORD *PageBuf, MS_LibTypeExtdat *ExtraDat);
-extern int	MS_ReaderCopyBlock(struct us_data *us, WORD oldphy, WORD newphy, WORD PhyBlockAddr, BYTE PageNum, PBYTE buf, WORD len);
+extern int	MS_LibForceSetLogicalPair(struct us_data *us, WORD logblk,
+								WORD phyblk);
+extern int	MS_ReaderReadPage(struct us_data *us, DWORD PhyBlockAddr,
+					BYTE PageNum, DWORD *PageBuf,
+					MS_LibTypeExtdat *ExtraDat);
+extern int	MS_ReaderCopyBlock(struct us_data *us, WORD oldphy,
+					WORD newphy, WORD PhyBlockAddr,
+					BYTE PageNum, PBYTE buf, WORD len);
 extern int	MS_ReaderEraseBlock(struct us_data *us, DWORD PhyBlockAddr);
-extern int	MS_LibProcessBootBlock(struct us_data *us, WORD PhyBlock, BYTE *PageData);
+extern int	MS_LibProcessBootBlock(struct us_data *us, WORD PhyBlock,
+							BYTE *PageData);
 extern int	MS_LibAllocLogicalMap(struct us_data *us);
 extern int	MS_LibSetBootBlockMark(struct us_data *us, WORD phyblk);
-extern int	MS_LibSetLogicalBlockMark(struct us_data *us, WORD phyblk, WORD mark);
+extern int	MS_LibSetLogicalBlockMark(struct us_data *us, WORD phyblk,
+								WORD mark);
 extern int	MS_LibSetInitialErrorBlock(struct us_data *us, WORD phyblk);
 extern int	MS_LibScanLogicalBlockNumber(struct us_data *us, WORD phyblk);
 extern int	MS_LibAllocWriteBuf(struct us_data *us);
 void		MS_LibClearWriteBuf(struct us_data *us);
-void		MS_LibPhy2LogRange(WORD PhyBlock, WORD *LogStart, WORD *LogEnde);
-extern int	MS_LibReadExtra(struct us_data *us, DWORD PhyBlock, BYTE PageNum, MS_LibTypeExtdat *ExtraDat);
-extern int	MS_LibReadExtraBlock(struct us_data *us, DWORD PhyBlock, BYTE PageNum, BYTE blen, void *buf);
+void		MS_LibPhy2LogRange(WORD PhyBlock, WORD *LogStart,
+							WORD *LogEnde);
+extern int	MS_LibReadExtra(struct us_data *us, DWORD PhyBlock,
+				BYTE PageNum, MS_LibTypeExtdat *ExtraDat);
+extern int	MS_LibReadExtraBlock(struct us_data *us, DWORD PhyBlock,
+					BYTE PageNum, BYTE blen, void *buf);
 extern int	MS_LibSetAcquiredErrorBlock(struct us_data *us, WORD phyblk);
 extern int	MS_LibErasePhyBlock(struct us_data *us, WORD phyblk);
 extern int	MS_LibErrorPhyBlock(struct us_data *us, WORD phyblk);
-extern int	MS_LibOverwriteExtra(struct us_data *us, DWORD PhyBlockAddr, BYTE PageNum, BYTE OverwriteFlag);
-extern int	MS_LibSetLogicalPair(struct us_data *us, WORD logblk, WORD phyblk);
+extern int	MS_LibOverwriteExtra(struct us_data *us, DWORD PhyBlockAddr,
+					BYTE PageNum, BYTE OverwriteFlag);
+extern int	MS_LibSetLogicalPair(struct us_data *us,
+					WORD logblk, WORD phyblk);
 extern int	MS_LibCheckDisableBlock(struct us_data *us, WORD PhyBlock);
 extern int	MS_CountFreeBlock(struct us_data *us, WORD PhyBlock);
 extern int	MS_LibSearchBlockFromLogical(struct us_data *us, WORD logblk);
 extern int	MS_LibSearchBlockFromPhysical(struct us_data *us, WORD phyblk);
 
-// ENE SM function
-extern int	SM_FreeMem(void);
-
 #endif
diff -druN linux-2.6.39-libre/drivers/staging/keucr/usb.c linux-3.0-rc7-libre/drivers/staging/keucr/usb.c
--- linux-2.6.39-libre/drivers/staging/keucr/usb.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/keucr/usb.c	2011-07-11 19:51:52.000000000 -0400
@@ -14,6 +14,7 @@
 
 #include "usb.h"
 #include "scsiglue.h"
+#include "smil.h"
 #include "transport.h"
 
 /* Some informational data */
@@ -34,10 +35,10 @@
 
 #ifdef CONFIG_PM
 
-int eucr_suspend(struct usb_interface *iface, pm_message_t message)
+static int eucr_suspend(struct usb_interface *iface, pm_message_t message)
 {
 	struct us_data *us = usb_get_intfdata(iface);
-	printk("--- eucr_suspend ---\n");
+	pr_info("--- eucr_suspend ---\n");
 	/* Wait until no command is running */
 	mutex_lock(&us->dev_mutex);
 
@@ -55,12 +56,12 @@
 }
 //EXPORT_SYMBOL_GPL(eucr_suspend);
 
-int eucr_resume(struct usb_interface *iface)
+static int eucr_resume(struct usb_interface *iface)
 {
 	BYTE    tmp = 0;
 
 	struct us_data *us = usb_get_intfdata(iface);
-	printk("--- eucr_resume---\n");
+	pr_info("--- eucr_resume---\n");
 	mutex_lock(&us->dev_mutex);
 
 	//US_DEBUGP("%s\n", __func__);
@@ -80,12 +81,12 @@
 	return 0;
 }
 //EXPORT_SYMBOL_GPL(eucr_resume);
-int eucr_reset_resume(struct usb_interface *iface)
+static int eucr_reset_resume(struct usb_interface *iface)
 {
 	BYTE    tmp = 0;
 	struct us_data *us = usb_get_intfdata(iface);
 
-	printk("--- eucr_reset_resume---\n");
+	pr_info("--- eucr_reset_resume---\n");
 	//US_DEBUGP("%s\n", __func__);
 
 	/* Report the reset to the SCSI core */
@@ -116,7 +117,7 @@
 {
 	struct us_data *us = usb_get_intfdata(iface);
 
-      printk("usb --- eucr_pre_reset\n");
+	pr_info("usb --- eucr_pre_reset\n");
 
 	/* Make sure no command runs during the reset */
 	mutex_lock(&us->dev_mutex);
@@ -128,7 +129,7 @@
 {
 	struct us_data *us = usb_get_intfdata(iface);
 
-      printk("usb --- eucr_post_reset\n");
+	pr_info("usb --- eucr_post_reset\n");
 
 	/* Report the reset to the SCSI core */
 	usb_stor_report_bus_reset(us);
@@ -140,7 +141,7 @@
 //----- fill_inquiry_response() ---------------------
 void fill_inquiry_response(struct us_data *us, unsigned char *data, unsigned int data_len)
 {
-      printk("usb --- fill_inquiry_response\n");
+	pr_info("usb --- fill_inquiry_response\n");
 	if (data_len<36) // You lose.
 		return;
 
@@ -171,7 +172,7 @@
 	struct us_data *us = (struct us_data *)__us;
 	struct Scsi_Host *host = us_to_host(us);
 
-      printk("usb --- usb_stor_control_thread\n");
+	pr_info("usb --- usb_stor_control_thread\n");
 	for(;;)
 	{
 		if (wait_for_completion_interruptible(&us->cmnd_ready))
@@ -242,7 +243,7 @@
 		else
 		{
 SkipForAbort:
-			printk("scsi command aborted\n");
+			pr_info("scsi command aborted\n");
 		}
 
 		if (test_bit(US_FLIDX_TIMED_OUT, &us->dflags))
@@ -277,7 +278,7 @@
 //----- associate_dev() ---------------------
 static int associate_dev(struct us_data *us, struct usb_interface *intf)
 {
-      printk("usb --- associate_dev\n");
+	pr_info("usb --- associate_dev\n");
 
 	/* Fill in the device-related fields */
 	us->pusb_dev = interface_to_usbdev(intf);
@@ -291,21 +292,21 @@
 	us->cr = usb_alloc_coherent(us->pusb_dev, sizeof(*us->cr), GFP_KERNEL, &us->cr_dma);
 	if (!us->cr)
 	{
-		printk("usb_ctrlrequest allocation failed\n");
+		pr_info("usb_ctrlrequest allocation failed\n");
 		return -ENOMEM;
 	}
 
 	us->iobuf = usb_alloc_coherent(us->pusb_dev, US_IOBUF_SIZE, GFP_KERNEL, &us->iobuf_dma);
 	if (!us->iobuf)
 	{
-		printk("I/O buffer allocation failed\n");
+		pr_info("I/O buffer allocation failed\n");
 		return -ENOMEM;
 	}
 
 	us->sensebuf = kmalloc(US_SENSE_SIZE, GFP_KERNEL);
 	if (!us->sensebuf)
 	{
-		printk("Sense buffer allocation failed\n");
+		pr_info("Sense buffer allocation failed\n");
 		return -ENOMEM;
 	}
 	return 0;
@@ -317,7 +318,7 @@
 	struct usb_device *dev = us->pusb_dev;
 	struct usb_interface_descriptor *idesc = &us->pusb_intf->cur_altsetting->desc;
 
-      printk("usb --- get_device_info\n");
+	pr_info("usb --- get_device_info\n");
 
 	us->subclass = idesc->bInterfaceSubClass;
 	us->protocol = idesc->bInterfaceProtocol;
@@ -326,7 +327,7 @@
 
 	if (us->fflags & US_FL_IGNORE_DEVICE)
 	{
-		printk("device ignored\n");
+		pr_info("device ignored\n");
 		return -ENODEV;
 	}
 
@@ -339,7 +340,7 @@
 //----- get_transport() ---------------------
 static int get_transport(struct us_data *us)
 {
-      printk("usb --- get_transport\n");
+	pr_info("usb --- get_transport\n");
 	switch (us->protocol) {
 	case USB_PR_BULK:
 		us->transport_name = "Bulk";
@@ -350,7 +351,7 @@
 	default:
 		return -EIO;
 	}
-	//printk("Transport: %s\n", us->transport_name);
+	/* pr_info("Transport: %s\n", us->transport_name); */
 
 	/* fix for single-lun devices */
 	if (us->fflags & US_FL_SINGLE_LUN)
@@ -361,9 +362,11 @@
 //----- get_protocol() ---------------------
 static int get_protocol(struct us_data *us)
 {
-      printk("usb --- get_protocol\n");
-	printk("us->pusb_dev->descriptor.idVendor = %x\n", us->pusb_dev->descriptor.idVendor);
-	printk("us->pusb_dev->descriptor.idProduct = %x\n", us->pusb_dev->descriptor.idProduct);
+	pr_info("usb --- get_protocol\n");
+	pr_info("us->pusb_dev->descriptor.idVendor = %x\n",
+			us->pusb_dev->descriptor.idVendor);
+	pr_info("us->pusb_dev->descriptor.idProduct = %x\n",
+			us->pusb_dev->descriptor.idProduct);
 	switch (us->subclass) {
 	case USB_SC_SCSI:
 		us->protocol_name = "Transparent SCSI";
@@ -376,7 +379,7 @@
 	default:
 		return -EIO;
 	}
-	//printk("Protocol: %s\n", us->protocol_name);
+	/* pr_info("Protocol: %s\n", us->protocol_name); */
 	return 0;
 }
 
@@ -390,7 +393,7 @@
 	struct usb_endpoint_descriptor *ep_out = NULL;
 	struct usb_endpoint_descriptor *ep_int = NULL;
 
-      printk("usb --- get_pipes\n");
+	pr_info("usb --- get_pipes\n");
 
 	for (i = 0; i < altsetting->desc.bNumEndpoints; i++)
 	{
@@ -418,7 +421,7 @@
 
 	if (!ep_in || !ep_out || (us->protocol == USB_PR_CBI && !ep_int))
 	{
-		printk("Endpoint sanity check failed! Rejecting dev.\n");
+		pr_info("Endpoint sanity check failed! Rejecting dev.\n");
 		return -EIO;
 	}
 
@@ -440,11 +443,11 @@
 {
 	struct task_struct *th;
 
-      printk("usb --- usb_stor_acquire_resources\n");
+	pr_info("usb --- usb_stor_acquire_resources\n");
 	us->current_urb = usb_alloc_urb(0, GFP_KERNEL);
 	if (!us->current_urb)
 	{
-		printk("URB allocation failed\n");
+		pr_info("URB allocation failed\n");
 		return -ENOMEM;
 	}
 
@@ -452,7 +455,7 @@
 	th = kthread_run(usb_stor_control_thread, us, "eucr-storage");
 	if (IS_ERR(th))
 	{
-		printk("Unable to start control thread\n");
+		pr_info("Unable to start control thread\n");
 		return PTR_ERR(th);
 	}
 	us->ctl_thread = th;
@@ -463,7 +466,7 @@
 //----- usb_stor_release_resources() ---------------------
 static void usb_stor_release_resources(struct us_data *us)
 {
-	printk("usb --- usb_stor_release_resources\n");
+	pr_info("usb --- usb_stor_release_resources\n");
 
 	SM_FreeMem();
 
@@ -474,7 +477,7 @@
 	/* Call the destructor routine, if it exists */
 	if (us->extra_destructor)
 	{
-		printk("-- calling extra_destructor()\n");
+		pr_info("-- calling extra_destructor()\n");
 		us->extra_destructor(us->extra);
 	}
 
@@ -486,7 +489,7 @@
 //----- dissociate_dev() ---------------------
 static void dissociate_dev(struct us_data *us)
 {
-      printk("usb --- dissociate_dev\n");
+	pr_info("usb --- dissociate_dev\n");
 
 	kfree(us->sensebuf);
 
@@ -505,7 +508,7 @@
 {
 	struct Scsi_Host *host = us_to_host(us);
 
-      printk("usb --- quiesce_and_remove_host\n");
+	pr_info("usb --- quiesce_and_remove_host\n");
 
 	/* If the device is really gone, cut short reset delays */
 	if (us->pusb_dev->state == USB_STATE_NOTATTACHED)
@@ -535,7 +538,7 @@
 //----- release_everything() ---------------------
 static void release_everything(struct us_data *us)
 {
-      printk("usb --- release_everything\n");
+	pr_info("usb --- release_everything\n");
 
 	usb_stor_release_resources(us);
 	dissociate_dev(us);
@@ -547,8 +550,8 @@
 {
 	struct us_data *us = (struct us_data *)__us;
 
-      printk("usb --- usb_stor_scan_thread\n");
-	printk("EUCR : device found at %d\n", us->pusb_dev->devnum);
+	pr_info("usb --- usb_stor_scan_thread\n");
+	pr_info("EUCR : device found at %d\n", us->pusb_dev->devnum);
 
 	set_freezable();
 	/* Wait for the timeout to expire or for a disconnect */
@@ -569,7 +572,7 @@
 			mutex_unlock(&us->dev_mutex);
 		}
 		scsi_scan_host(us_to_host(us));
-		printk("EUCR : device scan complete\n");
+		pr_info("EUCR : device scan complete\n");
 	}
 	complete_and_exit(&us->scanning_done, 0);
 }
@@ -583,12 +586,12 @@
 	BYTE	MiscReg03 = 0;
 	struct task_struct *th;
 
-      printk("usb --- eucr_probe\n");
+	pr_info("usb --- eucr_probe\n");
 
       host = scsi_host_alloc(&usb_stor_host_template, sizeof(*us));
 	if (!host)
 	{
-		printk("Unable to allocate the scsi host\n");
+		pr_info("Unable to allocate the scsi host\n");
 		return -ENOMEM;
 	}
 
@@ -631,7 +634,7 @@
 	result = scsi_add_host(host, &intf->dev);
 	if (result)
 	{
-		printk("Unable to add the scsi host\n");
+		pr_info("Unable to add the scsi host\n");
 		goto BadDevice;
 	}
 
@@ -639,7 +642,7 @@
 	th = kthread_create(usb_stor_scan_thread, us, "eucr-stor-scan");
 	if (IS_ERR(th))
 	{
-		printk("Unable to start the device-scanning thread\n");
+		pr_info("Unable to start the device-scanning thread\n");
 		complete(&us->scanning_done);
 		quiesce_and_remove_host(us);
 		result = PTR_ERR(th);
@@ -658,7 +661,7 @@
 	if (!(MiscReg03 & 0x02)) {
 		result = -ENODEV;
 		quiesce_and_remove_host(us);
-		printk(KERN_NOTICE "keucr: The driver only supports SM/MS card.\
+		pr_info("keucr: The driver only supports SM/MS card.\
 			To use SD card, \
 			please build driver/usb/storage/ums-eneub6250.ko\n");
 		goto BadDevice;
@@ -668,7 +671,7 @@
 
 	/* We come here if there are any problems */
 BadDevice:
-      printk("usb --- eucr_probe failed\n");
+	pr_info("usb --- eucr_probe failed\n");
 	release_everything(us);
 	return result;
 }
@@ -678,7 +681,7 @@
 {
 	struct us_data *us = usb_get_intfdata(intf);
 
-      printk("usb --- eucr_disconnect\n");
+	pr_info("usb --- eucr_disconnect\n");
 	quiesce_and_remove_host(us);
 	release_everything(us);
 }
@@ -705,11 +708,11 @@
 static int __init usb_stor_init(void)
 {
 	int retval;
-      printk("usb --- usb_stor_init start\n");
+	pr_info("usb --- usb_stor_init start\n");
 
 	retval = usb_register(&usb_storage_driver);
 	if (retval == 0)
-            printk("ENE USB Mass Storage support registered.\n");
+		pr_info("ENE USB Mass Storage support registered.\n");
 
 	return retval;
 }
@@ -717,7 +720,7 @@
 //----- usb_stor_exit() ---------------------
 static void __exit usb_stor_exit(void)
 {
-      printk("usb --- usb_stor_exit\n");
+	pr_info("usb --- usb_stor_exit\n");
 
 	usb_deregister(&usb_storage_driver) ;
 }
diff -druN linux-2.6.39-libre/drivers/staging/line6/driver.c linux-3.0-rc7-libre/drivers/staging/line6/driver.c
--- linux-2.6.39-libre/drivers/staging/line6/driver.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/line6/driver.c	2011-07-11 19:51:52.000000000 -0400
@@ -1094,8 +1094,6 @@
 err_destruct:
 	line6_destruct(interface);
 err_put:
-	usb_put_intf(interface);
-	usb_put_dev(usbdev);
 	return ret;
 }
 
diff -druN linux-2.6.39-libre/drivers/staging/lirc/lirc_imon.c linux-3.0-rc7-libre/drivers/staging/lirc/lirc_imon.c
--- linux-2.6.39-libre/drivers/staging/lirc/lirc_imon.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/lirc/lirc_imon.c	2011-07-11 19:51:52.000000000 -0400
@@ -672,8 +672,6 @@
 static void usb_rx_callback(struct urb *urb)
 {
 	struct imon_context *context;
-	unsigned char *buf;
-	int len;
 	int intfnum = 0;
 
 	if (!urb)
@@ -683,9 +681,6 @@
 	if (!context)
 		return;
 
-	buf = urb->transfer_buffer;
-	len = urb->actual_length;
-
 	switch (urb->status) {
 	case -ENOENT:		/* usbcore unlink successful! */
 		return;
@@ -728,7 +723,6 @@
 	int ir_ep_found = 0;
 	int alloc_status = 0;
 	int vfd_proto_6p = 0;
-	int code_length;
 	struct imon_context *context = NULL;
 	int i;
 	u16 vendor, product;
@@ -749,8 +743,6 @@
 	else
 		context->display = 1;
 
-	code_length = BUF_CHUNK_SIZE * 8;
-
 	usbdev     = usb_get_dev(interface_to_usbdev(interface));
 	iface_desc = interface->cur_altsetting;
 	num_endpts = iface_desc->desc.bNumEndpoints;
@@ -856,7 +848,7 @@
 
 	strcpy(driver->name, MOD_NAME);
 	driver->minor = -1;
-	driver->code_length = sizeof(int) * 8;
+	driver->code_length = BUF_CHUNK_SIZE * 8;
 	driver->sample_rate = 0;
 	driver->features = LIRC_CAN_REC_MODE2;
 	driver->data = context;
diff -druN linux-2.6.39-libre/drivers/staging/lirc/lirc_parallel.c linux-3.0-rc7-libre/drivers/staging/lirc/lirc_parallel.c
--- linux-2.6.39-libre/drivers/staging/lirc/lirc_parallel.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/lirc/lirc_parallel.c	2011-07-11 19:51:52.000000000 -0400
@@ -568,17 +568,17 @@
 }
 
 static struct lirc_driver driver = {
-       .name		= LIRC_DRIVER_NAME,
-       .minor		= -1,
-       .code_length	= 1,
-       .sample_rate	= 0,
-       .data		= NULL,
-       .add_to_buf	= NULL,
-       .set_use_inc	= set_use_inc,
-       .set_use_dec	= set_use_dec,
-       .fops		= &lirc_fops,
-       .dev		= NULL,
-       .owner		= THIS_MODULE,
+	.name		= LIRC_DRIVER_NAME,
+	.minor		= -1,
+	.code_length	= 1,
+	.sample_rate	= 0,
+	.data		= NULL,
+	.add_to_buf	= NULL,
+	.set_use_inc	= set_use_inc,
+	.set_use_dec	= set_use_dec,
+	.fops		= &lirc_fops,
+	.dev		= NULL,
+	.owner		= THIS_MODULE,
 };
 
 static struct platform_device *lirc_parallel_dev;
@@ -594,7 +594,7 @@
 }
 
 static int lirc_parallel_suspend(struct platform_device *dev,
-                                 pm_message_t state)
+					pm_message_t state)
 {
 	return 0;
 }
@@ -647,7 +647,8 @@
 
 	result = platform_driver_register(&lirc_parallel_driver);
 	if (result) {
-		printk("platform_driver_register returned %d\n", result);
+		printk(KERN_NOTICE "platform_driver_register"
+					" returned %d\n", result);
 		return result;
 	}
 
diff -druN linux-2.6.39-libre/drivers/staging/lirc/lirc_sasem.c linux-3.0-rc7-libre/drivers/staging/lirc/lirc_sasem.c
--- linux-2.6.39-libre/drivers/staging/lirc/lirc_sasem.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/lirc/lirc_sasem.c	2011-07-11 19:51:52.000000000 -0400
@@ -570,6 +570,7 @@
 	unsigned char *buf = urb->transfer_buffer;
 	long ms;
 	struct timeval tv;
+	int i;
 
 	if (len != 8) {
 		printk(KERN_WARNING "%s: invalid incoming packet size (%d)\n",
@@ -577,12 +578,12 @@
 		return;
 	}
 
-#ifdef DEBUG
-	int i;
-	for (i = 0; i < 8; ++i)
-		printk(KERN_INFO "%02x ", buf[i]);
-	printk(KERN_INFO "\n");
-#endif
+	if (debug) {
+		printk(KERN_INFO "Incoming data: ");
+		for (i = 0; i < 8; ++i)
+			printk(KERN_CONT "%02x ", buf[i]);
+		printk(KERN_CONT "\n");
+	}
 
 	/*
 	 * Lirc could deal with the repeat code, but we really need to block it
diff -druN linux-2.6.39-libre/drivers/staging/lirc/lirc_serial.c linux-3.0-rc7-libre/drivers/staging/lirc/lirc_serial.c
--- linux-2.6.39-libre/drivers/staging/lirc/lirc_serial.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/lirc/lirc_serial.c	2011-07-11 19:51:52.000000000 -0400
@@ -838,7 +838,23 @@
 
 static int init_port(void)
 {
-	int i, nlow, nhigh;
+	int i, nlow, nhigh, result;
+
+	result = request_irq(irq, irq_handler,
+			     IRQF_DISABLED | (share_irq ? IRQF_SHARED : 0),
+			     LIRC_DRIVER_NAME, (void *)&hardware);
+
+	switch (result) {
+	case -EBUSY:
+		printk(KERN_ERR LIRC_DRIVER_NAME ": IRQ %d busy\n", irq);
+		return -EBUSY;
+	case -EINVAL:
+		printk(KERN_ERR LIRC_DRIVER_NAME
+		       ": Bad irq number or handler\n");
+		return -EINVAL;
+	default:
+		break;
+	};
 
 	/* Reserve io region. */
 	/*
@@ -893,34 +909,17 @@
 		printk(KERN_INFO LIRC_DRIVER_NAME  ": Manually using active "
 		       "%s receiver\n", sense ? "low" : "high");
 
+	dprintk("Interrupt %d, port %04x obtained\n", irq, io);
 	return 0;
 }
 
 static int set_use_inc(void *data)
 {
-	int result;
 	unsigned long flags;
 
 	/* initialize timestamp */
 	do_gettimeofday(&lasttv);
 
-	result = request_irq(irq, irq_handler,
-			     IRQF_DISABLED | (share_irq ? IRQF_SHARED : 0),
-			     LIRC_DRIVER_NAME, (void *)&hardware);
-
-	switch (result) {
-	case -EBUSY:
-		printk(KERN_ERR LIRC_DRIVER_NAME ": IRQ %d busy\n", irq);
-		return -EBUSY;
-	case -EINVAL:
-		printk(KERN_ERR LIRC_DRIVER_NAME
-		       ": Bad irq number or handler\n");
-		return -EINVAL;
-	default:
-		dprintk("Interrupt %d, port %04x obtained\n", irq, io);
-		break;
-	};
-
 	spin_lock_irqsave(&hardware[type].lock, flags);
 
 	/* Set DLAB 0. */
@@ -945,10 +944,6 @@
 	soutp(UART_IER, sinp(UART_IER) &
 	      (~(UART_IER_MSI|UART_IER_RLSI|UART_IER_THRI|UART_IER_RDI)));
 	spin_unlock_irqrestore(&hardware[type].lock, flags);
-
-	free_irq(irq, (void *)&hardware);
-
-	dprintk("freed IRQ %d\n", irq);
 }
 
 static ssize_t lirc_write(struct file *file, const char *buf,
@@ -1256,6 +1251,9 @@
 static void __exit lirc_serial_exit_module(void)
 {
 	lirc_serial_exit();
+
+	free_irq(irq, (void *)&hardware);
+
 	if (iommap != 0)
 		release_mem_region(iommap, 8 << ioshift);
 	else
diff -druN linux-2.6.39-libre/drivers/staging/lirc/lirc_sir.c linux-3.0-rc7-libre/drivers/staging/lirc/lirc_sir.c
--- linux-2.6.39-libre/drivers/staging/lirc/lirc_sir.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/lirc/lirc_sir.c	2011-07-11 19:51:52.000000000 -0400
@@ -143,9 +143,9 @@
 #endif
 #ifndef LIRC_PORT
 /* for external dongles, default to com1 */
-#if defined(LIRC_SIR_ACTISYS_ACT200L) || \
-    defined(LIRC_SIR_ACTISYS_ACT220L) || \
-    defined(LIRC_SIR_TEKRAM)
+#if defined(LIRC_SIR_ACTISYS_ACT200L)         || \
+	    defined(LIRC_SIR_ACTISYS_ACT220L) || \
+	    defined(LIRC_SIR_TEKRAM)
 #define LIRC_PORT 0x3f8
 #else
 /* onboard sir ports are typically com3 */
@@ -467,7 +467,7 @@
 
 static int set_use_inc(void *data)
 {
-       return 0;
+	return 0;
 }
 
 static void set_use_dec(void *data)
@@ -475,17 +475,17 @@
 }
 
 static struct lirc_driver driver = {
-       .name		= LIRC_DRIVER_NAME,
-       .minor		= -1,
-       .code_length	= 1,
-       .sample_rate	= 0,
-       .data		= NULL,
-       .add_to_buf	= NULL,
-       .set_use_inc	= set_use_inc,
-       .set_use_dec	= set_use_dec,
-       .fops		= &lirc_fops,
-       .dev		= NULL,
-       .owner		= THIS_MODULE,
+	.name		= LIRC_DRIVER_NAME,
+	.minor		= -1,
+	.code_length	= 1,
+	.sample_rate	= 0,
+	.data		= NULL,
+	.add_to_buf	= NULL,
+	.set_use_inc	= set_use_inc,
+	.set_use_dec	= set_use_dec,
+	.fops		= &lirc_fops,
+	.dev		= NULL,
+	.owner		= THIS_MODULE,
 };
 
 
@@ -739,23 +739,16 @@
 static void send_pulse(unsigned long len)
 {
 	long bytes_out = len / TIME_CONST;
-	long time_left;
 
-	time_left = (long)len - (long)bytes_out * (long)TIME_CONST;
-	if (bytes_out == 0) {
+	if (bytes_out == 0)
 		bytes_out++;
-		time_left = 0;
-	}
+
 	while (bytes_out--) {
 		outb(PULSE, io + UART_TX);
 		/* FIXME treba seriozne cakanie z char/serial.c */
 		while (!(inb(io + UART_LSR) & UART_LSR_THRE))
 			;
 	}
-#if 0
-	if (time_left > 0)
-		safe_udelay(time_left);
-#endif
 }
 #endif
 
diff -druN linux-2.6.39-libre/drivers/staging/lirc/lirc_zilog.c linux-3.0-rc7-libre/drivers/staging/lirc/lirc_zilog.c
--- linux-2.6.39-libre/drivers/staging/lirc/lirc_zilog.c	2011-05-19 02:17:19.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/lirc/lirc_zilog.c	2011-07-21 06:59:17.000000000 -0400
@@ -475,14 +475,14 @@
 	dprintk("poll thread started\n");
 
 	while (!kthread_should_stop()) {
+		set_current_state(TASK_INTERRUPTIBLE);
+
 		/* if device not opened, we can sleep half a second */
 		if (atomic_read(&ir->open_count) == 0) {
 			schedule_timeout(HZ/2);
 			continue;
 		}
 
-		set_current_state(TASK_INTERRUPTIBLE);
-
 		/*
 		 * This is ~113*2 + 24 + jitter (2*repeat gap + code length).
 		 * We use this interval as the chip resets every time you poll
diff -druN linux-2.6.39-libre/drivers/staging/Makefile linux-3.0-rc7-libre/drivers/staging/Makefile
--- linux-2.6.39-libre/drivers/staging/Makefile	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/Makefile	2011-07-11 19:51:52.000000000 -0400
@@ -12,13 +12,12 @@
 obj-$(CONFIG_VIDEO_TM6000)	+= tm6000/
 obj-$(CONFIG_DVB_CXD2099)	+= cxd2099/
 obj-$(CONFIG_LIRC_STAGING)	+= lirc/
-obj-$(CONFIG_USB_IP_COMMON)	+= usbip/
+obj-$(CONFIG_USBIP_CORE)	+= usbip/
 obj-$(CONFIG_W35UND)		+= winbond/
 obj-$(CONFIG_PRISM2_USB)	+= wlan-ng/
 obj-$(CONFIG_ECHO)		+= echo/
-obj-$(CONFIG_BRCM80211)		+= brcm80211/
-obj-$(CONFIG_RT2860)		+= rt2860/
-obj-$(CONFIG_RT2870)		+= rt2870/
+obj-$(CONFIG_BRCMSMAC)		+= brcm80211/
+obj-$(CONFIG_BRCMFMAC)		+= brcm80211/
 obj-$(CONFIG_COMEDI)		+= comedi/
 obj-$(CONFIG_FB_OLPC_DCON)	+= olpc_dcon/
 obj-$(CONFIG_ASUS_OLED)		+= asus_oled/
@@ -70,3 +69,5 @@
 obj-$(CONFIG_TOUCHSCREEN_CLEARPAD_TM1217)	+= cptm1217/
 obj-$(CONFIG_TOUCHSCREEN_SYNAPTICS_I2C_RMI4)	+= ste_rmi4/
 obj-$(CONFIG_DRM_PSB)		+= gma500/
+obj-$(CONFIG_INTEL_MEI)		+= mei/
+obj-$(CONFIG_MFD_NVEC)		+= nvec/
diff -druN linux-2.6.39-libre/drivers/staging/mei/hw.h linux-3.0-rc7-libre/drivers/staging/mei/hw.h
--- linux-2.6.39-libre/drivers/staging/mei/hw.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/staging/mei/hw.h	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,333 @@
+/*
+ *
+ * Intel Management Engine Interface (Intel MEI) Linux driver
+ * Copyright (c) 2003-2011, 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.
+ *
+ */
+
+#ifndef _MEI_HW_TYPES_H_
+#define _MEI_HW_TYPES_H_
+
+#include <linux/uuid.h>
+
+/*
+ * Timeouts
+ */
+#define MEI_INTEROP_TIMEOUT    (HZ * 7)
+#define MEI_CONNECT_TIMEOUT		3	/* at least 2 seconds */
+
+#define CONNECT_TIMEOUT        15	/* HPS definition */
+#define INIT_CLIENTS_TIMEOUT   15	/* HPS definition */
+
+#define IAMTHIF_STALL_TIMER		12	/* seconds */
+#define IAMTHIF_READ_TIMER		10000	/* ms */
+
+/*
+ * Internal Clients Number
+ */
+#define MEI_WD_HOST_CLIENT_ID          1
+#define MEI_IAMTHIF_HOST_CLIENT_ID     2
+
+/*
+ * MEI device IDs
+ */
+#define    MEI_DEV_ID_82946GZ	0x2974  /* 82946GZ/GL */
+#define    MEI_DEV_ID_82G35	0x2984  /* 82G35 Express */
+#define    MEI_DEV_ID_82Q965	0x2994  /* 82Q963/Q965 */
+#define    MEI_DEV_ID_82G965	0x29A4  /* 82P965/G965 */
+
+#define    MEI_DEV_ID_82GM965	0x2A04  /* Mobile PM965/GM965 */
+#define    MEI_DEV_ID_82GME965	0x2A14  /* Mobile GME965/GLE960 */
+
+#define    MEI_DEV_ID_ICH9_82Q35 0x29B4  /* 82Q35 Express */
+#define    MEI_DEV_ID_ICH9_82G33 0x29C4  /* 82G33/G31/P35/P31 Express */
+#define    MEI_DEV_ID_ICH9_82Q33 0x29D4  /* 82Q33 Express */
+#define    MEI_DEV_ID_ICH9_82X38 0x29E4  /* 82X38/X48 Express */
+#define    MEI_DEV_ID_ICH9_3200  0x29F4  /* 3200/3210 Server */
+
+#define    MEI_DEV_ID_ICH9_6	0x28B4  /* Bearlake */
+#define    MEI_DEV_ID_ICH9_7	0x28C4  /* Bearlake */
+#define    MEI_DEV_ID_ICH9_8	0x28D4  /* Bearlake */
+#define    MEI_DEV_ID_ICH9_9    0x28E4  /* Bearlake */
+#define    MEI_DEV_ID_ICH9_10	0x28F4  /* Bearlake */
+
+#define    MEI_DEV_ID_ICH9M_1	0x2A44  /* Cantiga */
+#define    MEI_DEV_ID_ICH9M_2	0x2A54  /* Cantiga */
+#define    MEI_DEV_ID_ICH9M_3	0x2A64  /* Cantiga */
+#define    MEI_DEV_ID_ICH9M_4	0x2A74  /* Cantiga */
+
+#define    MEI_DEV_ID_ICH10_1	0x2E04  /* Eaglelake */
+#define    MEI_DEV_ID_ICH10_2	0x2E14  /* Eaglelake */
+#define    MEI_DEV_ID_ICH10_3	0x2E24  /* Eaglelake */
+#define    MEI_DEV_ID_ICH10_4	0x2E34  /* Eaglelake */
+
+#define    MEI_DEV_ID_IBXPK_1	0x3B64  /* Calpella */
+#define    MEI_DEV_ID_IBXPK_2	0x3B65  /* Calpella */
+
+#define    MEI_DEV_ID_CPT_1	0x1C3A    /* Cougerpoint */
+#define    MEI_DEV_ID_PBG_1	0x1D3A    /* PBG */
+
+#define    MEI_DEV_ID_PPT_1	0x1E3A    /* Pantherpoint PPT */
+#define    MEI_DEV_ID_PPT_2	0x1CBA    /* Pantherpoint PPT */
+#define    MEI_DEV_ID_PPT_3	0x1DBA    /* Pantherpoint PPT */
+
+
+/*
+ * MEI HW Section
+ */
+
+/* MEI registers */
+/* H_CB_WW - Host Circular Buffer (CB) Write Window register */
+#define H_CB_WW    0
+/* H_CSR - Host Control Status register */
+#define H_CSR      4
+/* ME_CB_RW - ME Circular Buffer Read Window register (read only) */
+#define ME_CB_RW   8
+/* ME_CSR_HA - ME Control Status Host Access register (read only) */
+#define ME_CSR_HA  0xC
+
+
+/* register bits of H_CSR (Host Control Status register) */
+/* Host Circular Buffer Depth - maximum number of 32-bit entries in CB */
+#define H_CBD             0xFF000000
+/* Host Circular Buffer Write Pointer */
+#define H_CBWP            0x00FF0000
+/* Host Circular Buffer Read Pointer */
+#define H_CBRP            0x0000FF00
+/* Host Reset */
+#define H_RST             0x00000010
+/* Host Ready */
+#define H_RDY             0x00000008
+/* Host Interrupt Generate */
+#define H_IG              0x00000004
+/* Host Interrupt Status */
+#define H_IS              0x00000002
+/* Host Interrupt Enable */
+#define H_IE              0x00000001
+
+
+/* register bits of ME_CSR_HA (ME Control Status Host Access register) */
+/* ME CB (Circular Buffer) Depth HRA (Host Read Access) - host read only
+access to ME_CBD */
+#define ME_CBD_HRA        0xFF000000
+/* ME CB Write Pointer HRA - host read only access to ME_CBWP */
+#define ME_CBWP_HRA       0x00FF0000
+/* ME CB Read Pointer HRA - host read only access to ME_CBRP */
+#define ME_CBRP_HRA       0x0000FF00
+/* ME Reset HRA - host read only access to ME_RST */
+#define ME_RST_HRA        0x00000010
+/* ME Ready HRA - host read only access to ME_RDY */
+#define ME_RDY_HRA        0x00000008
+/* ME Interrupt Generate HRA - host read only access to ME_IG */
+#define ME_IG_HRA         0x00000004
+/* ME Interrupt Status HRA - host read only access to ME_IS */
+#define ME_IS_HRA         0x00000002
+/* ME Interrupt Enable HRA - host read only access to ME_IE */
+#define ME_IE_HRA         0x00000001
+
+/*
+ * MEI Version
+ */
+#define HBM_MINOR_VERSION                   0
+#define HBM_MAJOR_VERSION                   1
+#define HBM_TIMEOUT                         1	/* 1 second */
+
+/*
+ * MEI Bus Message Command IDs
+ */
+#define HOST_START_REQ_CMD                  0x01
+#define HOST_START_RES_CMD                  0x81
+
+#define HOST_STOP_REQ_CMD                   0x02
+#define HOST_STOP_RES_CMD                   0x82
+
+#define ME_STOP_REQ_CMD                     0x03
+
+#define HOST_ENUM_REQ_CMD                   0x04
+#define HOST_ENUM_RES_CMD                   0x84
+
+#define HOST_CLIENT_PROPERTIES_REQ_CMD      0x05
+#define HOST_CLIENT_PROPERTIES_RES_CMD      0x85
+
+#define CLIENT_CONNECT_REQ_CMD              0x06
+#define CLIENT_CONNECT_RES_CMD              0x86
+
+#define CLIENT_DISCONNECT_REQ_CMD           0x07
+#define CLIENT_DISCONNECT_RES_CMD           0x87
+
+#define MEI_FLOW_CONTROL_CMD               0x08
+
+/*
+ * MEI Stop Reason
+ * used by hbm_host_stop_request.reason
+ */
+enum mei_stop_reason_types {
+	DRIVER_STOP_REQUEST = 0x00,
+	DEVICE_D1_ENTRY = 0x01,
+	DEVICE_D2_ENTRY = 0x02,
+	DEVICE_D3_ENTRY = 0x03,
+	SYSTEM_S1_ENTRY = 0x04,
+	SYSTEM_S2_ENTRY = 0x05,
+	SYSTEM_S3_ENTRY = 0x06,
+	SYSTEM_S4_ENTRY = 0x07,
+	SYSTEM_S5_ENTRY = 0x08
+};
+
+/*
+ * Client Connect Status
+ * used by hbm_client_connect_response.status
+ */
+enum client_connect_status_types {
+	CCS_SUCCESS = 0x00,
+	CCS_NOT_FOUND = 0x01,
+	CCS_ALREADY_STARTED = 0x02,
+	CCS_OUT_OF_RESOURCES = 0x03,
+	CCS_MESSAGE_SMALL = 0x04
+};
+
+/*
+ * Client Disconnect Status
+ */
+enum client_disconnect_status_types {
+	CDS_SUCCESS = 0x00
+};
+
+/*
+ *  MEI BUS Interface Section
+ */
+struct mei_msg_hdr {
+	u32 me_addr:8;
+	u32 host_addr:8;
+	u32 length:9;
+	u32 reserved:6;
+	u32 msg_complete:1;
+} __packed;
+
+
+struct hbm_cmd {
+	u8 cmd:7;
+	u8 is_response:1;
+} __packed;
+
+
+struct mei_bus_message {
+	struct hbm_cmd cmd;
+	u8 command_specific_data[];
+} __packed;
+
+struct hbm_version {
+	u8 minor_version;
+	u8 major_version;
+} __packed;
+
+struct hbm_host_version_request {
+	struct hbm_cmd cmd;
+	u8 reserved;
+	struct hbm_version host_version;
+} __packed;
+
+struct hbm_host_version_response {
+	struct hbm_cmd cmd;
+	int host_version_supported;
+	struct hbm_version me_max_version;
+} __packed;
+
+struct hbm_host_stop_request {
+	struct hbm_cmd cmd;
+	u8 reason;
+	u8 reserved[2];
+} __packed;
+
+struct hbm_host_stop_response {
+	struct hbm_cmd cmd;
+	u8 reserved[3];
+} __packed;
+
+struct hbm_me_stop_request {
+	struct hbm_cmd cmd;
+	u8 reason;
+	u8 reserved[2];
+} __packed;
+
+struct hbm_host_enum_request {
+	struct hbm_cmd cmd;
+	u8 reserved[3];
+} __packed;
+
+struct hbm_host_enum_response {
+	struct hbm_cmd cmd;
+	u8 reserved[3];
+	u8 valid_addresses[32];
+} __packed;
+
+struct mei_client_properties {
+	uuid_le protocol_name;
+	u8 protocol_version;
+	u8 max_number_of_connections;
+	u8 fixed_address;
+	u8 single_recv_buf;
+	u32 max_msg_length;
+} __packed;
+
+struct hbm_props_request {
+	struct hbm_cmd cmd;
+	u8 address;
+	u8 reserved[2];
+} __packed;
+
+
+struct hbm_props_response {
+	struct hbm_cmd cmd;
+	u8 address;
+	u8 status;
+	u8 reserved[1];
+	struct mei_client_properties client_properties;
+} __packed;
+
+struct hbm_client_connect_request {
+	struct hbm_cmd cmd;
+	u8 me_addr;
+	u8 host_addr;
+	u8 reserved;
+} __packed;
+
+struct hbm_client_connect_response {
+	struct hbm_cmd cmd;
+	u8 me_addr;
+	u8 host_addr;
+	u8 status;
+} __packed;
+
+struct hbm_client_disconnect_request {
+	struct hbm_cmd cmd;
+	u8 me_addr;
+	u8 host_addr;
+	u8 reserved[1];
+} __packed;
+
+#define MEI_FC_MESSAGE_RESERVED_LENGTH           5
+
+struct hbm_flow_control {
+	struct hbm_cmd cmd;
+	u8 me_addr;
+	u8 host_addr;
+	u8 reserved[MEI_FC_MESSAGE_RESERVED_LENGTH];
+} __packed;
+
+struct mei_me_client {
+	struct mei_client_properties props;
+	u8 client_id;
+	u8 mei_flow_ctrl_creds;
+} __packed;
+
+
+#endif
diff -druN linux-2.6.39-libre/drivers/staging/mei/init.c linux-3.0-rc7-libre/drivers/staging/mei/init.c
--- linux-2.6.39-libre/drivers/staging/mei/init.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/staging/mei/init.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,770 @@
+/*
+ *
+ * Intel Management Engine Interface (Intel MEI) Linux driver
+ * Copyright (c) 2003-2011, Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ */
+
+#include <linux/pci.h>
+#include <linux/sched.h>
+#include <linux/wait.h>
+#include <linux/delay.h>
+
+#include "mei_dev.h"
+#include "hw.h"
+#include "interface.h"
+#include "mei.h"
+
+const uuid_le mei_amthi_guid  = UUID_LE(0x12f80028, 0xb4b7, 0x4b2d, 0xac,
+						0xa8, 0x46, 0xe0, 0xff, 0x65,
+						0x81, 0x4c);
+
+/**
+ * mei_initialize_list - Sets up a queue list.
+ *
+ * @list: An instance of our list structure
+ * @dev: the device structure
+ */
+void mei_initialize_list(struct mei_io_list *list, struct mei_device *dev)
+{
+	/* initialize our queue list */
+	INIT_LIST_HEAD(&list->mei_cb.cb_list);
+	list->status = 0;
+	list->device_extension = dev;
+}
+
+/**
+ * mei_flush_queues - flushes queue lists belonging to cl.
+ *
+ * @dev: the device structure
+ * @cl: private data of the file object
+ */
+void mei_flush_queues(struct mei_device *dev, struct mei_cl *cl)
+{
+	int i;
+
+	if (!dev || !cl)
+		return;
+
+	for (i = 0; i < MEI_IO_LISTS_NUMBER; i++) {
+		dev_dbg(&dev->pdev->dev, "remove list entry belonging to cl\n");
+		mei_flush_list(dev->io_list_array[i], cl);
+	}
+}
+
+
+/**
+ * mei_flush_list - removes list entry belonging to cl.
+ *
+ * @list:  An instance of our list structure
+ * @cl: private data of the file object
+ */
+void mei_flush_list(struct mei_io_list *list, struct mei_cl *cl)
+{
+	struct mei_cl *cl_tmp;
+	struct mei_cl_cb *cb_pos = NULL;
+	struct mei_cl_cb *cb_next = NULL;
+
+	if (!list || !cl)
+		return;
+
+	if (list->status != 0)
+		return;
+
+	if (list_empty(&list->mei_cb.cb_list))
+		return;
+
+	list_for_each_entry_safe(cb_pos, cb_next,
+				 &list->mei_cb.cb_list, cb_list) {
+		if (cb_pos) {
+			cl_tmp = (struct mei_cl *)
+				cb_pos->file_private;
+			if (cl_tmp &&
+			    mei_fe_same_id(cl, cl_tmp))
+				list_del(&cb_pos->cb_list);
+		}
+	}
+}
+
+/**
+ * mei_reset_iamthif_params - initializes mei device iamthif
+ *
+ * @dev: the device structure
+ */
+static void mei_reset_iamthif_params(struct mei_device *dev)
+{
+	/* reset iamthif parameters. */
+	dev->iamthif_current_cb = NULL;
+	dev->iamthif_msg_buf_size = 0;
+	dev->iamthif_msg_buf_index = 0;
+	dev->iamthif_canceled = 0;
+	dev->iamthif_ioctl = 0;
+	dev->iamthif_state = MEI_IAMTHIF_IDLE;
+	dev->iamthif_timer = 0;
+}
+
+/**
+ * init_mei_device - allocates and initializes the mei device structure
+ *
+ * @pdev: The pci device structure
+ *
+ * returns The mei_device_device pointer on success, NULL on failure.
+ */
+struct mei_device *init_mei_device(struct pci_dev *pdev)
+{
+	int i;
+	struct mei_device *dev;
+
+	dev = kzalloc(sizeof(struct mei_device), GFP_KERNEL);
+	if (!dev)
+		return NULL;
+
+	/* setup our list array */
+	dev->io_list_array[0] = &dev->read_list;
+	dev->io_list_array[1] = &dev->write_list;
+	dev->io_list_array[2] = &dev->write_waiting_list;
+	dev->io_list_array[3] = &dev->ctrl_wr_list;
+	dev->io_list_array[4] = &dev->ctrl_rd_list;
+	dev->io_list_array[5] = &dev->amthi_cmd_list;
+	dev->io_list_array[6] = &dev->amthi_read_complete_list;
+	INIT_LIST_HEAD(&dev->file_list);
+	INIT_LIST_HEAD(&dev->wd_cl.link);
+	INIT_LIST_HEAD(&dev->iamthif_cl.link);
+	mutex_init(&dev->device_lock);
+	init_waitqueue_head(&dev->wait_recvd_msg);
+	init_waitqueue_head(&dev->wait_stop_wd);
+	dev->mei_state = MEI_INITIALIZING;
+	dev->iamthif_state = MEI_IAMTHIF_IDLE;
+	for (i = 0; i < MEI_IO_LISTS_NUMBER; i++)
+		mei_initialize_list(dev->io_list_array[i], dev);
+	dev->pdev = pdev;
+	return dev;
+}
+
+/**
+ * mei_hw_init - initializes host and fw to start work.
+ *
+ * @dev: the device structure
+ *
+ * returns 0 on success, <0 on failure.
+ */
+int mei_hw_init(struct mei_device *dev)
+{
+	int err = 0;
+	int ret;
+
+	mutex_lock(&dev->device_lock);
+
+	dev->host_hw_state = mei_hcsr_read(dev);
+	dev->me_hw_state = mei_mecsr_read(dev);
+	dev_dbg(&dev->pdev->dev, "host_hw_state = 0x%08x, mestate = 0x%08x.\n",
+	    dev->host_hw_state, dev->me_hw_state);
+
+	/* acknowledge interrupt and stop interupts */
+	if ((dev->host_hw_state & H_IS) == H_IS)
+		mei_reg_write(dev, H_CSR, dev->host_hw_state);
+
+	dev->recvd_msg = 0;
+	dev_dbg(&dev->pdev->dev, "reset in start the mei device.\n");
+
+	mei_reset(dev, 1);
+
+	dev_dbg(&dev->pdev->dev, "host_hw_state = 0x%08x, me_hw_state = 0x%08x.\n",
+	    dev->host_hw_state, dev->me_hw_state);
+
+	/* wait for ME to turn on ME_RDY */
+	if (!dev->recvd_msg) {
+		mutex_unlock(&dev->device_lock);
+		err = wait_event_interruptible_timeout(dev->wait_recvd_msg,
+			dev->recvd_msg, MEI_INTEROP_TIMEOUT);
+		mutex_lock(&dev->device_lock);
+	}
+
+	if (err <= 0 && !dev->recvd_msg) {
+		dev->mei_state = MEI_DISABLED;
+		dev_dbg(&dev->pdev->dev,
+			"wait_event_interruptible_timeout failed"
+			"on wait for ME to turn on ME_RDY.\n");
+		ret = -ENODEV;
+		goto out;
+	}
+
+	if (!(((dev->host_hw_state & H_RDY) == H_RDY) &&
+	      ((dev->me_hw_state & ME_RDY_HRA) == ME_RDY_HRA))) {
+		dev->mei_state = MEI_DISABLED;
+		dev_dbg(&dev->pdev->dev,
+			"host_hw_state = 0x%08x, me_hw_state = 0x%08x.\n",
+			dev->host_hw_state, dev->me_hw_state);
+
+		if (!(dev->host_hw_state & H_RDY))
+			dev_dbg(&dev->pdev->dev, "host turn off H_RDY.\n");
+
+		if (!(dev->me_hw_state & ME_RDY_HRA))
+			dev_dbg(&dev->pdev->dev, "ME turn off ME_RDY.\n");
+
+		printk(KERN_ERR "mei: link layer initialization failed.\n");
+		ret = -ENODEV;
+		goto out;
+	}
+
+	if (dev->version.major_version != HBM_MAJOR_VERSION ||
+	    dev->version.minor_version != HBM_MINOR_VERSION) {
+		dev_dbg(&dev->pdev->dev, "MEI start failed.\n");
+		ret = -ENODEV;
+		goto out;
+	}
+
+	dev->recvd_msg = 0;
+	dev_dbg(&dev->pdev->dev, "host_hw_state = 0x%08x, me_hw_state = 0x%08x.\n",
+	    dev->host_hw_state, dev->me_hw_state);
+	dev_dbg(&dev->pdev->dev, "ME turn on ME_RDY and host turn on H_RDY.\n");
+	dev_dbg(&dev->pdev->dev, "link layer has been established.\n");
+	dev_dbg(&dev->pdev->dev, "MEI  start success.\n");
+	ret = 0;
+
+out:
+	mutex_unlock(&dev->device_lock);
+	return ret;
+}
+
+/**
+ * mei_hw_reset - resets fw via mei csr register.
+ *
+ * @dev: the device structure
+ * @interrupts_enabled: if interrupt should be enabled after reset.
+ */
+static void mei_hw_reset(struct mei_device *dev, int interrupts_enabled)
+{
+	dev->host_hw_state |= (H_RST | H_IG);
+
+	if (interrupts_enabled)
+		mei_enable_interrupts(dev);
+	else
+		mei_disable_interrupts(dev);
+}
+
+/**
+ * mei_reset - resets host and fw.
+ *
+ * @dev: the device structure
+ * @interrupts_enabled: if interrupt should be enabled after reset.
+ */
+void mei_reset(struct mei_device *dev, int interrupts_enabled)
+{
+	struct mei_cl *cl_pos = NULL;
+	struct mei_cl *cl_next = NULL;
+	struct mei_cl_cb *cb_pos = NULL;
+	struct mei_cl_cb *cb_next = NULL;
+	bool unexpected;
+
+	if (dev->mei_state == MEI_RECOVERING_FROM_RESET) {
+		dev->need_reset = 1;
+		return;
+	}
+
+	unexpected = (dev->mei_state != MEI_INITIALIZING &&
+			dev->mei_state != MEI_DISABLED &&
+			dev->mei_state != MEI_POWER_DOWN &&
+			dev->mei_state != MEI_POWER_UP);
+
+	dev->host_hw_state = mei_hcsr_read(dev);
+
+	dev_dbg(&dev->pdev->dev, "before reset host_hw_state = 0x%08x.\n",
+	    dev->host_hw_state);
+
+	mei_hw_reset(dev, interrupts_enabled);
+
+	dev->host_hw_state &= ~H_RST;
+	dev->host_hw_state |= H_IG;
+
+	mei_hcsr_set(dev);
+
+	dev_dbg(&dev->pdev->dev, "currently saved host_hw_state = 0x%08x.\n",
+	    dev->host_hw_state);
+
+	dev->need_reset = 0;
+
+	if (dev->mei_state != MEI_INITIALIZING) {
+		if (dev->mei_state != MEI_DISABLED &&
+		    dev->mei_state != MEI_POWER_DOWN)
+			dev->mei_state = MEI_RESETING;
+
+		list_for_each_entry_safe(cl_pos,
+				cl_next, &dev->file_list, link) {
+			cl_pos->state = MEI_FILE_DISCONNECTED;
+			cl_pos->mei_flow_ctrl_creds = 0;
+			cl_pos->read_cb = NULL;
+			cl_pos->timer_count = 0;
+		}
+		/* remove entry if already in list */
+		dev_dbg(&dev->pdev->dev, "list del iamthif and wd file list.\n");
+		mei_remove_client_from_file_list(dev,
+				dev->wd_cl.host_client_id);
+
+		mei_remove_client_from_file_list(dev,
+				dev->iamthif_cl.host_client_id);
+
+		mei_reset_iamthif_params(dev);
+		dev->wd_due_counter = 0;
+		dev->extra_write_index = 0;
+	}
+
+	dev->num_mei_me_clients = 0;
+	dev->rd_msg_hdr = 0;
+	dev->stop = 0;
+	dev->wd_pending = 0;
+
+	/* update the state of the registers after reset */
+	dev->host_hw_state = mei_hcsr_read(dev);
+	dev->me_hw_state = mei_mecsr_read(dev);
+
+	dev_dbg(&dev->pdev->dev, "after reset host_hw_state = 0x%08x, me_hw_state = 0x%08x.\n",
+	    dev->host_hw_state, dev->me_hw_state);
+
+	if (unexpected)
+		dev_warn(&dev->pdev->dev, "unexpected reset.\n");
+
+	/* Wake up all readings so they can be interrupted */
+	list_for_each_entry_safe(cl_pos, cl_next, &dev->file_list, link) {
+		if (waitqueue_active(&cl_pos->rx_wait)) {
+			dev_dbg(&dev->pdev->dev, "Waking up client!\n");
+			wake_up_interruptible(&cl_pos->rx_wait);
+		}
+	}
+	/* remove all waiting requests */
+	if (dev->write_list.status == 0 &&
+		!list_empty(&dev->write_list.mei_cb.cb_list)) {
+		list_for_each_entry_safe(cb_pos, cb_next,
+				&dev->write_list.mei_cb.cb_list, cb_list) {
+			if (cb_pos) {
+				list_del(&cb_pos->cb_list);
+				mei_free_cb_private(cb_pos);
+				cb_pos = NULL;
+			}
+		}
+	}
+}
+
+
+
+/**
+ * host_start_message - mei host sends start message.
+ *
+ * @dev: the device structure
+ *
+ * returns none.
+ */
+void host_start_message(struct mei_device *dev)
+{
+	struct mei_msg_hdr *mei_hdr;
+	struct hbm_host_version_request *host_start_req;
+
+	/* host start message */
+	mei_hdr = (struct mei_msg_hdr *) &dev->wr_msg_buf[0];
+	mei_hdr->host_addr = 0;
+	mei_hdr->me_addr = 0;
+	mei_hdr->length = sizeof(struct hbm_host_version_request);
+	mei_hdr->msg_complete = 1;
+	mei_hdr->reserved = 0;
+
+	host_start_req =
+	    (struct hbm_host_version_request *) &dev->wr_msg_buf[1];
+	memset(host_start_req, 0, sizeof(struct hbm_host_version_request));
+	host_start_req->cmd.cmd = HOST_START_REQ_CMD;
+	host_start_req->host_version.major_version = HBM_MAJOR_VERSION;
+	host_start_req->host_version.minor_version = HBM_MINOR_VERSION;
+	dev->recvd_msg = 0;
+	if (!mei_write_message(dev, mei_hdr,
+				       (unsigned char *) (host_start_req),
+				       mei_hdr->length)) {
+		dev_dbg(&dev->pdev->dev, "write send version message to FW fail.\n");
+		dev->mei_state = MEI_RESETING;
+		mei_reset(dev, 1);
+	}
+	dev->init_clients_state = MEI_START_MESSAGE;
+	dev->init_clients_timer = INIT_CLIENTS_TIMEOUT;
+	return ;
+}
+
+/**
+ * host_enum_clients_message - host sends enumeration client request message.
+ *
+ * @dev: the device structure
+ *
+ * returns none.
+ */
+void host_enum_clients_message(struct mei_device *dev)
+{
+	struct mei_msg_hdr *mei_hdr;
+	struct hbm_host_enum_request *host_enum_req;
+	mei_hdr = (struct mei_msg_hdr *) &dev->wr_msg_buf[0];
+	/* enumerate clients */
+	mei_hdr->host_addr = 0;
+	mei_hdr->me_addr = 0;
+	mei_hdr->length = sizeof(struct hbm_host_enum_request);
+	mei_hdr->msg_complete = 1;
+	mei_hdr->reserved = 0;
+
+	host_enum_req = (struct hbm_host_enum_request *) &dev->wr_msg_buf[1];
+	memset(host_enum_req, 0, sizeof(struct hbm_host_enum_request));
+	host_enum_req->cmd.cmd = HOST_ENUM_REQ_CMD;
+	if (!mei_write_message(dev, mei_hdr,
+			       (unsigned char *) (host_enum_req),
+				mei_hdr->length)) {
+		dev->mei_state = MEI_RESETING;
+		dev_dbg(&dev->pdev->dev, "write send enumeration request message to FW fail.\n");
+		mei_reset(dev, 1);
+	}
+	dev->init_clients_state = MEI_ENUM_CLIENTS_MESSAGE;
+	dev->init_clients_timer = INIT_CLIENTS_TIMEOUT;
+	return ;
+}
+
+
+/**
+ * allocate_me_clients_storage - allocates storage for me clients
+ *
+ * @dev: the device structure
+ *
+ * returns none.
+ */
+void allocate_me_clients_storage(struct mei_device *dev)
+{
+	struct mei_me_client *clients;
+	int b;
+
+	/* count how many ME clients we have */
+	for_each_set_bit(b, dev->me_clients_map, MEI_CLIENTS_MAX)
+		dev->num_mei_me_clients++;
+
+	if (dev->num_mei_me_clients <= 0)
+		return ;
+
+
+	if (dev->me_clients != NULL) {
+		kfree(dev->me_clients);
+		dev->me_clients = NULL;
+	}
+	dev_dbg(&dev->pdev->dev, "memory allocation for ME clients size=%zd.\n",
+		dev->num_mei_me_clients * sizeof(struct mei_me_client));
+	/* allocate storage for ME clients representation */
+	clients = kcalloc(dev->num_mei_me_clients,
+			sizeof(struct mei_me_client), GFP_KERNEL);
+	if (!clients) {
+		dev_dbg(&dev->pdev->dev, "memory allocation for ME clients failed.\n");
+		dev->mei_state = MEI_RESETING;
+		mei_reset(dev, 1);
+		return ;
+	}
+	dev->me_clients = clients;
+	return ;
+}
+/**
+ * host_client_properties - reads properties for client
+ *
+ * @dev: the device structure
+ *
+ * returns none.
+ */
+void host_client_properties(struct mei_device *dev)
+{
+	struct mei_msg_hdr *mei_header;
+	struct hbm_props_request *host_cli_req;
+	int b;
+	u8 client_num = dev->me_client_presentation_num;
+
+	b = dev->me_client_index;
+	b = find_next_bit(dev->me_clients_map, MEI_CLIENTS_MAX, b);
+	if (b < MEI_CLIENTS_MAX) {
+		dev->me_clients[client_num].client_id = b;
+		dev->me_clients[client_num].mei_flow_ctrl_creds = 0;
+		mei_header = (struct mei_msg_hdr *)&dev->wr_msg_buf[0];
+		mei_header->host_addr = 0;
+		mei_header->me_addr = 0;
+		mei_header->length = sizeof(struct hbm_props_request);
+		mei_header->msg_complete = 1;
+		mei_header->reserved = 0;
+
+		host_cli_req = (struct hbm_props_request *)&dev->wr_msg_buf[1];
+
+		memset(host_cli_req, 0, sizeof(struct hbm_props_request));
+
+		host_cli_req->cmd.cmd = HOST_CLIENT_PROPERTIES_REQ_CMD;
+		host_cli_req->address = b;
+
+		if (!mei_write_message(dev, mei_header,
+				(unsigned char *)host_cli_req,
+				mei_header->length)) {
+			dev->mei_state = MEI_RESETING;
+			dev_dbg(&dev->pdev->dev, "write send enumeration request message to FW fail.\n");
+			mei_reset(dev, 1);
+			return;
+		}
+
+		dev->init_clients_timer = INIT_CLIENTS_TIMEOUT;
+		dev->me_client_index = b;
+		return;
+	}
+
+
+	/*
+	 * Clear Map for indicating now ME clients
+	 * with associated host client
+	 */
+	bitmap_zero(dev->host_clients_map, MEI_CLIENTS_MAX);
+	dev->write_hang = -1;
+	dev->open_handle_count = 0;
+	bitmap_set(dev->host_clients_map, 0, 3);
+	dev->mei_state = MEI_ENABLED;
+
+	mei_wd_host_init(dev);
+	return;
+}
+
+/**
+ * mei_init_file_private - initializes private file structure.
+ *
+ * @priv: private file structure to be initialized
+ * @file: the file structure
+ */
+void mei_init_file_private(struct mei_cl *priv, struct mei_device *dev)
+{
+	memset(priv, 0, sizeof(struct mei_cl));
+	init_waitqueue_head(&priv->wait);
+	init_waitqueue_head(&priv->rx_wait);
+	init_waitqueue_head(&priv->tx_wait);
+	INIT_LIST_HEAD(&priv->link);
+	priv->reading_state = MEI_IDLE;
+	priv->writing_state = MEI_IDLE;
+	priv->dev = dev;
+}
+
+int mei_find_me_client_index(const struct mei_device *dev, uuid_le cuuid)
+{
+	int i, res = -1;
+
+	for (i = 0; i < dev->num_mei_me_clients; ++i)
+		if (uuid_le_cmp(cuuid,
+				dev->me_clients[i].props.protocol_name) == 0) {
+			res = i;
+			break;
+		}
+
+	return res;
+}
+
+
+/**
+ * mei_find_me_client_update_filext - searches for ME client guid
+ *                       sets client_id in mei_file_private if found
+ * @dev: the device structure
+ * @priv: private file structure to set client_id in
+ * @cguid: searched guid of ME client
+ * @client_id: id of host client to be set in file private structure
+ *
+ * returns ME client index
+ */
+u8 mei_find_me_client_update_filext(struct mei_device *dev, struct mei_cl *priv,
+				const uuid_le *cguid, u8 client_id)
+{
+	int i;
+
+	if (!dev || !priv || !cguid)
+		return 0;
+
+	/* check for valid client id */
+	i = mei_find_me_client_index(dev, *cguid);
+	if (i >= 0) {
+		priv->me_client_id = dev->me_clients[i].client_id;
+		priv->state = MEI_FILE_CONNECTING;
+		priv->host_client_id = client_id;
+
+		list_add_tail(&priv->link, &dev->file_list);
+		return (u8)i;
+	}
+
+	return 0;
+}
+
+/**
+ * host_init_iamthif - mei initialization iamthif client.
+ *
+ * @dev: the device structure
+ *
+ */
+void host_init_iamthif(struct mei_device *dev)
+{
+	u8 i;
+	unsigned char *msg_buf;
+
+	mei_init_file_private(&dev->iamthif_cl, dev);
+	dev->iamthif_cl.state = MEI_FILE_DISCONNECTED;
+
+	/* find ME amthi client */
+	i = mei_find_me_client_update_filext(dev, &dev->iamthif_cl,
+			    &mei_amthi_guid, MEI_IAMTHIF_HOST_CLIENT_ID);
+	if (dev->iamthif_cl.state != MEI_FILE_CONNECTING) {
+		dev_dbg(&dev->pdev->dev, "failed to find iamthif client.\n");
+		return;
+	}
+
+	/* Do not render the system unusable when iamthif_mtu is not equal to
+	the value received from ME.
+	Assign iamthif_mtu to the value received from ME in order to solve the
+	hardware macro incompatibility. */
+
+	dev_dbg(&dev->pdev->dev, "[DEFAULT] IAMTHIF = %d\n", dev->iamthif_mtu);
+	dev->iamthif_mtu = dev->me_clients[i].props.max_msg_length;
+	dev_dbg(&dev->pdev->dev,
+			"IAMTHIF = %d\n",
+			dev->me_clients[i].props.max_msg_length);
+
+	kfree(dev->iamthif_msg_buf);
+	dev->iamthif_msg_buf = NULL;
+
+	/* allocate storage for ME message buffer */
+	msg_buf = kcalloc(dev->iamthif_mtu,
+			sizeof(unsigned char), GFP_KERNEL);
+	if (!msg_buf) {
+		dev_dbg(&dev->pdev->dev, "memory allocation for ME message buffer failed.\n");
+		return;
+	}
+
+	dev->iamthif_msg_buf = msg_buf;
+
+	if (!mei_connect(dev, &dev->iamthif_cl)) {
+		dev_dbg(&dev->pdev->dev, "Failed to connect to AMTHI client\n");
+		dev->iamthif_cl.state = MEI_FILE_DISCONNECTED;
+		dev->iamthif_cl.host_client_id = 0;
+	} else {
+		dev->iamthif_cl.timer_count = CONNECT_TIMEOUT;
+	}
+}
+
+/**
+ * mei_alloc_file_private - allocates a private file structure and sets it up.
+ * @file: the file structure
+ *
+ * returns  The allocated file or NULL on failure
+ */
+struct mei_cl *mei_alloc_file_private(struct mei_device *dev)
+{
+	struct mei_cl *priv;
+
+	priv = kmalloc(sizeof(struct mei_cl), GFP_KERNEL);
+	if (!priv)
+		return NULL;
+
+	mei_init_file_private(priv, dev);
+
+	return priv;
+}
+
+
+
+/**
+ * mei_disconnect_host_client - sends disconnect message to fw from host client.
+ *
+ * @dev: the device structure
+ * @cl: private data of the file object
+ *
+ * Locking: called under "dev->device_lock" lock
+ *
+ * returns 0 on success, <0 on failure.
+ */
+int mei_disconnect_host_client(struct mei_device *dev, struct mei_cl *cl)
+{
+	int rets, err;
+	long timeout = 15;	/* 15 seconds */
+	struct mei_cl_cb *cb;
+
+	if (!dev || !cl)
+		return -ENODEV;
+
+	if (cl->state != MEI_FILE_DISCONNECTING)
+		return 0;
+
+	cb = kzalloc(sizeof(struct mei_cl_cb), GFP_KERNEL);
+	if (!cb)
+		return -ENOMEM;
+
+	INIT_LIST_HEAD(&cb->cb_list);
+	cb->file_private = cl;
+	cb->major_file_operations = MEI_CLOSE;
+	if (dev->mei_host_buffer_is_empty) {
+		dev->mei_host_buffer_is_empty = 0;
+		if (mei_disconnect(dev, cl)) {
+			mdelay(10); /* Wait for hardware disconnection ready */
+			list_add_tail(&cb->cb_list,
+				&dev->ctrl_rd_list.mei_cb.cb_list);
+		} else {
+			rets = -ENODEV;
+			dev_dbg(&dev->pdev->dev, "failed to call mei_disconnect.\n");
+			goto free;
+		}
+	} else {
+		dev_dbg(&dev->pdev->dev, "add disconnect cb to control write list\n");
+		list_add_tail(&cb->cb_list,
+				&dev->ctrl_wr_list.mei_cb.cb_list);
+	}
+	mutex_unlock(&dev->device_lock);
+
+	err = wait_event_timeout(dev->wait_recvd_msg,
+		 (MEI_FILE_DISCONNECTED == cl->state),
+		 timeout * HZ);
+
+	mutex_lock(&dev->device_lock);
+	if (MEI_FILE_DISCONNECTED == cl->state) {
+		rets = 0;
+		dev_dbg(&dev->pdev->dev, "successfully disconnected from FW client.\n");
+	} else {
+		rets = -ENODEV;
+		if (MEI_FILE_DISCONNECTED != cl->state)
+			dev_dbg(&dev->pdev->dev, "wrong status client disconnect.\n");
+
+		if (err)
+			dev_dbg(&dev->pdev->dev,
+					"wait failed disconnect err=%08x\n",
+					err);
+
+		dev_dbg(&dev->pdev->dev, "failed to disconnect from FW client.\n");
+	}
+
+	mei_flush_list(&dev->ctrl_rd_list, cl);
+	mei_flush_list(&dev->ctrl_wr_list, cl);
+free:
+	mei_free_cb_private(cb);
+	return rets;
+}
+
+/**
+ * mei_remove_client_from_file_list -
+ *	removes file private data from device file list
+ *
+ * @dev: the device structure
+ * @host_client_id: host client id to be removed
+ */
+void mei_remove_client_from_file_list(struct mei_device *dev,
+				       u8 host_client_id)
+{
+	struct mei_cl *cl_pos = NULL;
+	struct mei_cl *cl_next = NULL;
+	list_for_each_entry_safe(cl_pos, cl_next, &dev->file_list, link) {
+		if (host_client_id == cl_pos->host_client_id) {
+			dev_dbg(&dev->pdev->dev, "remove host client = %d, ME client = %d\n",
+					cl_pos->host_client_id,
+					cl_pos->me_client_id);
+			list_del_init(&cl_pos->link);
+			break;
+		}
+	}
+}
diff -druN linux-2.6.39-libre/drivers/staging/mei/interface.c linux-3.0-rc7-libre/drivers/staging/mei/interface.c
--- linux-2.6.39-libre/drivers/staging/mei/interface.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/staging/mei/interface.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,447 @@
+/*
+ *
+ * Intel Management Engine Interface (Intel MEI) Linux driver
+ * Copyright (c) 2003-2011, Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ */
+
+#include <linux/pci.h>
+#include "mei_dev.h"
+#include "mei.h"
+#include "interface.h"
+
+
+
+/**
+ * mei_set_csr_register - writes H_CSR register to the mei device,
+ * and ignores the H_IS bit for it is write-one-to-zero.
+ *
+ * @dev: the device structure
+ */
+void mei_hcsr_set(struct mei_device *dev)
+{
+	if ((dev->host_hw_state & H_IS) == H_IS)
+		dev->host_hw_state &= ~H_IS;
+	mei_reg_write(dev, H_CSR, dev->host_hw_state);
+	dev->host_hw_state = mei_hcsr_read(dev);
+}
+
+/**
+ * mei_csr_enable_interrupts - enables mei device interrupts
+ *
+ * @dev: the device structure
+ */
+void mei_enable_interrupts(struct mei_device *dev)
+{
+	dev->host_hw_state |= H_IE;
+	mei_hcsr_set(dev);
+}
+
+/**
+ * mei_csr_disable_interrupts - disables mei device interrupts
+ *
+ * @dev: the device structure
+ */
+void mei_disable_interrupts(struct mei_device *dev)
+{
+	dev->host_hw_state &= ~H_IE;
+	mei_hcsr_set(dev);
+}
+
+/**
+ * _host_get_filled_slots - gets number of device filled buffer slots
+ *
+ * @device: the device structure
+ *
+ * returns number of filled slots
+ */
+static unsigned char _host_get_filled_slots(const struct mei_device *dev)
+{
+	char read_ptr, write_ptr;
+
+	read_ptr = (char) ((dev->host_hw_state & H_CBRP) >> 8);
+	write_ptr = (char) ((dev->host_hw_state & H_CBWP) >> 16);
+
+	return (unsigned char) (write_ptr - read_ptr);
+}
+
+/**
+ * mei_host_buffer_is_empty - checks if host buffer is empty.
+ *
+ * @dev: the device structure
+ *
+ * returns 1 if empty, 0 - otherwise.
+ */
+int mei_host_buffer_is_empty(struct mei_device *dev)
+{
+	unsigned char filled_slots;
+
+	dev->host_hw_state = mei_hcsr_read(dev);
+	filled_slots = _host_get_filled_slots(dev);
+
+	if (filled_slots == 0)
+		return 1;
+
+	return 0;
+}
+
+/**
+ * mei_count_empty_write_slots - counts write empty slots.
+ *
+ * @dev: the device structure
+ *
+ * returns -1(ESLOTS_OVERFLOW) if overflow, otherwise empty slots count
+ */
+int mei_count_empty_write_slots(struct mei_device *dev)
+{
+	unsigned char buffer_depth, filled_slots, empty_slots;
+
+	dev->host_hw_state = mei_hcsr_read(dev);
+	buffer_depth = (unsigned char) ((dev->host_hw_state & H_CBD) >> 24);
+	filled_slots = _host_get_filled_slots(dev);
+	empty_slots = buffer_depth - filled_slots;
+
+	/* check for overflow */
+	if (filled_slots > buffer_depth)
+		return -EOVERFLOW;
+
+	return empty_slots;
+}
+
+/**
+ * mei_write_message - writes a message to mei device.
+ *
+ * @dev: the device structure
+ * @header: header of message
+ * @write_buffer: message buffer will be written
+ * @write_length: message size will be written
+ *
+ * returns 1 if success, 0 - otherwise.
+ */
+int mei_write_message(struct mei_device *dev,
+			     struct mei_msg_hdr *header,
+			     unsigned char *write_buffer,
+			     unsigned long write_length)
+{
+	u32 temp_msg = 0;
+	unsigned long bytes_written = 0;
+	unsigned char buffer_depth, filled_slots, empty_slots;
+	unsigned long dw_to_write;
+
+	dev->host_hw_state = mei_hcsr_read(dev);
+
+	dev_dbg(&dev->pdev->dev,
+			"host_hw_state = 0x%08x.\n",
+			dev->host_hw_state);
+
+	dev_dbg(&dev->pdev->dev,
+			"mei_write_message header=%08x.\n",
+			*((u32 *) header));
+
+	buffer_depth = (unsigned char) ((dev->host_hw_state & H_CBD) >> 24);
+	filled_slots = _host_get_filled_slots(dev);
+	empty_slots = buffer_depth - filled_slots;
+	dev_dbg(&dev->pdev->dev,
+			"filled = %hu, empty = %hu.\n",
+			filled_slots, empty_slots);
+
+	dw_to_write = ((write_length + 3) / 4);
+
+	if (dw_to_write > empty_slots)
+		return 0;
+
+	mei_reg_write(dev, H_CB_WW, *((u32 *) header));
+
+	while (write_length >= 4) {
+		mei_reg_write(dev, H_CB_WW,
+				*(u32 *) (write_buffer + bytes_written));
+		bytes_written += 4;
+		write_length -= 4;
+	}
+
+	if (write_length > 0) {
+		memcpy(&temp_msg, &write_buffer[bytes_written], write_length);
+		mei_reg_write(dev, H_CB_WW, temp_msg);
+	}
+
+	dev->host_hw_state |= H_IG;
+	mei_hcsr_set(dev);
+	dev->me_hw_state = mei_mecsr_read(dev);
+	if ((dev->me_hw_state & ME_RDY_HRA) != ME_RDY_HRA)
+		return 0;
+
+	dev->write_hang = 0;
+	return 1;
+}
+
+/**
+ * mei_count_full_read_slots - counts read full slots.
+ *
+ * @dev: the device structure
+ *
+ * returns -1(ESLOTS_OVERFLOW) if overflow, otherwise filled slots count
+ */
+int mei_count_full_read_slots(struct mei_device *dev)
+{
+	char read_ptr, write_ptr;
+	unsigned char buffer_depth, filled_slots;
+
+	dev->me_hw_state = mei_mecsr_read(dev);
+	buffer_depth = (unsigned char)((dev->me_hw_state & ME_CBD_HRA) >> 24);
+	read_ptr = (char) ((dev->me_hw_state & ME_CBRP_HRA) >> 8);
+	write_ptr = (char) ((dev->me_hw_state & ME_CBWP_HRA) >> 16);
+	filled_slots = (unsigned char) (write_ptr - read_ptr);
+
+	/* check for overflow */
+	if (filled_slots > buffer_depth)
+		return -EOVERFLOW;
+
+	dev_dbg(&dev->pdev->dev, "filled_slots =%08x\n", filled_slots);
+	return (int)filled_slots;
+}
+
+/**
+ * mei_read_slots - reads a message from mei device.
+ *
+ * @dev: the device structure
+ * @buffer: message buffer will be written
+ * @buffer_length: message size will be read
+ */
+void mei_read_slots(struct mei_device *dev,
+		     unsigned char *buffer, unsigned long buffer_length)
+{
+	u32 i = 0;
+	unsigned char temp_buf[sizeof(u32)];
+
+	while (buffer_length >= sizeof(u32)) {
+		((u32 *) buffer)[i] = mei_mecbrw_read(dev);
+
+		dev_dbg(&dev->pdev->dev,
+				"buffer[%d]= %d\n",
+				i, ((u32 *) buffer)[i]);
+
+		i++;
+		buffer_length -= sizeof(u32);
+	}
+
+	if (buffer_length > 0) {
+		*((u32 *) &temp_buf) = mei_mecbrw_read(dev);
+		memcpy(&buffer[i * 4], temp_buf, buffer_length);
+	}
+
+	dev->host_hw_state |= H_IG;
+	mei_hcsr_set(dev);
+}
+
+/**
+ * mei_flow_ctrl_creds - checks flow_control credentials.
+ *
+ * @dev: the device structure
+ * @cl: private data of the file object
+ *
+ * returns 1 if mei_flow_ctrl_creds >0, 0 - otherwise.
+ *	-ENOENT if mei_cl is not present
+ *	-EINVAL if single_recv_buf == 0
+ */
+int mei_flow_ctrl_creds(struct mei_device *dev, struct mei_cl *cl)
+{
+	int i;
+
+	if (!dev->num_mei_me_clients)
+		return 0;
+
+	if (cl->mei_flow_ctrl_creds > 0)
+		return 1;
+
+	for (i = 0; i < dev->num_mei_me_clients; i++) {
+		struct mei_me_client  *me_cl = &dev->me_clients[i];
+		if (me_cl->client_id == cl->me_client_id) {
+			if (me_cl->mei_flow_ctrl_creds) {
+				if (WARN_ON(me_cl->props.single_recv_buf == 0))
+					return -EINVAL;
+				return 1;
+			} else {
+				return 0;
+			}
+		}
+	}
+	return -ENOENT;
+}
+
+/**
+ * mei_flow_ctrl_reduce - reduces flow_control.
+ *
+ * @dev: the device structure
+ * @cl: private data of the file object
+ * @returns
+ *	0 on success
+ *	-ENOENT when me client is not found
+ *	-EINVAL wehn ctrl credits are <= 0
+ */
+int mei_flow_ctrl_reduce(struct mei_device *dev, struct mei_cl *cl)
+{
+	int i;
+
+	if (!dev->num_mei_me_clients)
+		return -ENOENT;
+
+	for (i = 0; i < dev->num_mei_me_clients; i++) {
+		struct mei_me_client  *me_cl = &dev->me_clients[i];
+		if (me_cl->client_id == cl->me_client_id) {
+			if (me_cl->props.single_recv_buf != 0) {
+				if (WARN_ON(me_cl->mei_flow_ctrl_creds <= 0))
+					return -EINVAL;
+				dev->me_clients[i].mei_flow_ctrl_creds--;
+			} else {
+				if (WARN_ON(cl->mei_flow_ctrl_creds <= 0))
+					return -EINVAL;
+				cl->mei_flow_ctrl_creds--;
+			}
+			return 0;
+		}
+	}
+	return -ENOENT;
+}
+
+/**
+ * mei_send_flow_control - sends flow control to fw.
+ *
+ * @dev: the device structure
+ * @cl: private data of the file object
+ *
+ * returns 1 if success, 0 - otherwise.
+ */
+int mei_send_flow_control(struct mei_device *dev, struct mei_cl *cl)
+{
+	struct mei_msg_hdr *mei_hdr;
+	struct hbm_flow_control *mei_flow_control;
+
+	mei_hdr = (struct mei_msg_hdr *) &dev->wr_msg_buf[0];
+	mei_hdr->host_addr = 0;
+	mei_hdr->me_addr = 0;
+	mei_hdr->length = sizeof(struct hbm_flow_control);
+	mei_hdr->msg_complete = 1;
+	mei_hdr->reserved = 0;
+
+	mei_flow_control = (struct hbm_flow_control *) &dev->wr_msg_buf[1];
+	memset(mei_flow_control, 0, sizeof(mei_flow_control));
+	mei_flow_control->host_addr = cl->host_client_id;
+	mei_flow_control->me_addr = cl->me_client_id;
+	mei_flow_control->cmd.cmd = MEI_FLOW_CONTROL_CMD;
+	memset(mei_flow_control->reserved, 0,
+			sizeof(mei_flow_control->reserved));
+	dev_dbg(&dev->pdev->dev, "sending flow control host client = %d, ME client = %d\n",
+	    cl->host_client_id, cl->me_client_id);
+	if (!mei_write_message(dev, mei_hdr,
+				(unsigned char *) mei_flow_control,
+				sizeof(struct hbm_flow_control)))
+		return 0;
+
+	return 1;
+
+}
+
+/**
+ * mei_other_client_is_connecting - checks if other
+ *    client with the same client id is connected.
+ *
+ * @dev: the device structure
+ * @cl: private data of the file object
+ *
+ * returns 1 if other client is connected, 0 - otherwise.
+ */
+int mei_other_client_is_connecting(struct mei_device *dev,
+				struct mei_cl *cl)
+{
+	struct mei_cl *cl_pos = NULL;
+	struct mei_cl *cl_next = NULL;
+
+	list_for_each_entry_safe(cl_pos, cl_next, &dev->file_list, link) {
+		if ((cl_pos->state == MEI_FILE_CONNECTING) &&
+			(cl_pos != cl) &&
+			cl->me_client_id == cl_pos->me_client_id)
+			return 1;
+
+	}
+	return 0;
+}
+
+/**
+ * mei_disconnect - sends disconnect message to fw.
+ *
+ * @dev: the device structure
+ * @cl: private data of the file object
+ *
+ * returns 1 if success, 0 - otherwise.
+ */
+int mei_disconnect(struct mei_device *dev, struct mei_cl *cl)
+{
+	struct mei_msg_hdr *mei_hdr;
+	struct hbm_client_disconnect_request *mei_cli_disconnect;
+
+	mei_hdr = (struct mei_msg_hdr *) &dev->wr_msg_buf[0];
+	mei_hdr->host_addr = 0;
+	mei_hdr->me_addr = 0;
+	mei_hdr->length = sizeof(struct hbm_client_disconnect_request);
+	mei_hdr->msg_complete = 1;
+	mei_hdr->reserved = 0;
+
+	mei_cli_disconnect =
+	    (struct hbm_client_disconnect_request *) &dev->wr_msg_buf[1];
+	memset(mei_cli_disconnect, 0, sizeof(mei_cli_disconnect));
+	mei_cli_disconnect->host_addr = cl->host_client_id;
+	mei_cli_disconnect->me_addr = cl->me_client_id;
+	mei_cli_disconnect->cmd.cmd = CLIENT_DISCONNECT_REQ_CMD;
+	mei_cli_disconnect->reserved[0] = 0;
+
+	if (!mei_write_message(dev, mei_hdr,
+				(unsigned char *) mei_cli_disconnect,
+				sizeof(struct hbm_client_disconnect_request)))
+		return 0;
+
+	return 1;
+}
+
+/**
+ * mei_connect - sends connect message to fw.
+ *
+ * @dev: the device structure
+ * @cl: private data of the file object
+ *
+ * returns 1 if success, 0 - otherwise.
+ */
+int mei_connect(struct mei_device *dev, struct mei_cl *cl)
+{
+	struct mei_msg_hdr *mei_hdr;
+	struct hbm_client_connect_request *mei_cli_connect;
+
+	mei_hdr = (struct mei_msg_hdr *) &dev->wr_msg_buf[0];
+	mei_hdr->host_addr = 0;
+	mei_hdr->me_addr = 0;
+	mei_hdr->length = sizeof(struct hbm_client_connect_request);
+	mei_hdr->msg_complete = 1;
+	mei_hdr->reserved = 0;
+
+	mei_cli_connect =
+	    (struct hbm_client_connect_request *) &dev->wr_msg_buf[1];
+	mei_cli_connect->host_addr = cl->host_client_id;
+	mei_cli_connect->me_addr = cl->me_client_id;
+	mei_cli_connect->cmd.cmd = CLIENT_CONNECT_REQ_CMD;
+	mei_cli_connect->reserved = 0;
+
+	if (!mei_write_message(dev, mei_hdr,
+				(unsigned char *) mei_cli_connect,
+				sizeof(struct hbm_client_connect_request)))
+		return 0;
+
+	return 1;
+}
diff -druN linux-2.6.39-libre/drivers/staging/mei/interface.h linux-3.0-rc7-libre/drivers/staging/mei/interface.h
--- linux-2.6.39-libre/drivers/staging/mei/interface.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/staging/mei/interface.h	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,62 @@
+/*
+ *
+ * Intel Management Engine Interface (Intel MEI) Linux driver
+ * Copyright (c) 2003-2011, 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.
+ *
+ */
+
+
+
+#ifndef _MEI_INTERFACE_H_
+#define _MEI_INTERFACE_H_
+
+#include "mei.h"
+#include "mei_dev.h"
+
+
+#define AMT_WD_VALUE 120	/* seconds */
+
+#define MEI_WATCHDOG_DATA_SIZE         16
+#define MEI_START_WD_DATA_SIZE         20
+#define MEI_WD_PARAMS_SIZE             4
+
+
+void mei_read_slots(struct mei_device *dev,
+		     unsigned char *buffer, unsigned long buffer_length);
+
+int mei_write_message(struct mei_device *dev,
+			     struct mei_msg_hdr *header,
+			     unsigned char *write_buffer,
+			     unsigned long write_length);
+
+int mei_host_buffer_is_empty(struct mei_device *dev);
+
+int mei_count_full_read_slots(struct mei_device *dev);
+
+int mei_count_empty_write_slots(struct mei_device *dev);
+
+int mei_flow_ctrl_creds(struct mei_device *dev, struct mei_cl *cl);
+
+int mei_wd_send(struct mei_device *dev);
+int mei_wd_stop(struct mei_device *dev, bool preserve);
+void mei_wd_host_init(struct mei_device *dev);
+void mei_wd_start_setup(struct mei_device *dev);
+
+int mei_flow_ctrl_reduce(struct mei_device *dev, struct mei_cl *cl);
+
+int mei_send_flow_control(struct mei_device *dev, struct mei_cl *cl);
+
+int mei_disconnect(struct mei_device *dev, struct mei_cl *cl);
+int mei_other_client_is_connecting(struct mei_device *dev, struct mei_cl *cl);
+int mei_connect(struct mei_device *dev, struct mei_cl *cl);
+
+#endif /* _MEI_INTERFACE_H_ */
diff -druN linux-2.6.39-libre/drivers/staging/mei/interrupt.c linux-3.0-rc7-libre/drivers/staging/mei/interrupt.c
--- linux-2.6.39-libre/drivers/staging/mei/interrupt.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/staging/mei/interrupt.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,1624 @@
+/*
+ *
+ * Intel Management Engine Interface (Intel MEI) Linux driver
+ * Copyright (c) 2003-2011, Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ */
+
+
+#include <linux/pci.h>
+#include <linux/kthread.h>
+#include <linux/interrupt.h>
+#include <linux/fs.h>
+#include <linux/jiffies.h>
+
+#include "mei_dev.h"
+#include "mei.h"
+#include "hw.h"
+#include "interface.h"
+
+
+/**
+ * mei_interrupt_quick_handler - The ISR of the MEI device
+ *
+ * @irq: The irq number
+ * @dev_id: pointer to the device structure
+ *
+ * returns irqreturn_t
+ */
+irqreturn_t mei_interrupt_quick_handler(int irq, void *dev_id)
+{
+	struct mei_device *dev = (struct mei_device *) dev_id;
+	u32 csr_reg = mei_hcsr_read(dev);
+
+	if ((csr_reg & H_IS) != H_IS)
+		return IRQ_NONE;
+
+	/* clear H_IS bit in H_CSR */
+	mei_reg_write(dev, H_CSR, csr_reg);
+
+	return IRQ_WAKE_THREAD;
+}
+
+/**
+ * _mei_cmpl - processes completed operation.
+ *
+ * @cl: private data of the file object.
+ * @cb_pos: callback block.
+ */
+static void _mei_cmpl(struct mei_cl *cl, struct mei_cl_cb *cb_pos)
+{
+	if (cb_pos->major_file_operations == MEI_WRITE) {
+		mei_free_cb_private(cb_pos);
+		cb_pos = NULL;
+		cl->writing_state = MEI_WRITE_COMPLETE;
+		if (waitqueue_active(&cl->tx_wait))
+			wake_up_interruptible(&cl->tx_wait);
+
+	} else if (cb_pos->major_file_operations == MEI_READ &&
+			MEI_READING == cl->reading_state) {
+		cl->reading_state = MEI_READ_COMPLETE;
+		if (waitqueue_active(&cl->rx_wait))
+			wake_up_interruptible(&cl->rx_wait);
+
+	}
+}
+
+/**
+ * _mei_cmpl_iamthif - processes completed iamthif operation.
+ *
+ * @dev: the device structure.
+ * @cb_pos: callback block.
+ */
+static void _mei_cmpl_iamthif(struct mei_device *dev, struct mei_cl_cb *cb_pos)
+{
+	if (dev->iamthif_canceled != 1) {
+		dev->iamthif_state = MEI_IAMTHIF_READ_COMPLETE;
+		dev->iamthif_stall_timer = 0;
+		memcpy(cb_pos->response_buffer.data,
+				dev->iamthif_msg_buf,
+				dev->iamthif_msg_buf_index);
+		list_add_tail(&cb_pos->cb_list,
+				&dev->amthi_read_complete_list.mei_cb.cb_list);
+		dev_dbg(&dev->pdev->dev, "amthi read completed.\n");
+		dev->iamthif_timer = jiffies;
+		dev_dbg(&dev->pdev->dev, "dev->iamthif_timer = %ld\n",
+				dev->iamthif_timer);
+	} else {
+		run_next_iamthif_cmd(dev);
+	}
+
+	dev_dbg(&dev->pdev->dev, "completing amthi call back.\n");
+	wake_up_interruptible(&dev->iamthif_cl.wait);
+}
+
+
+/**
+ * mei_irq_thread_read_amthi_message - bottom half read routine after ISR to
+ * handle the read amthi message data processing.
+ *
+ * @complete_list: An instance of our list structure
+ * @dev: the device structure
+ * @mei_hdr: header of amthi message
+ *
+ * returns 0 on success, <0 on failure.
+ */
+static int mei_irq_thread_read_amthi_message(struct mei_io_list *complete_list,
+		struct mei_device *dev,
+		struct mei_msg_hdr *mei_hdr)
+{
+	struct mei_cl *cl;
+	struct mei_cl_cb *cb;
+	unsigned char *buffer;
+
+	BUG_ON(mei_hdr->me_addr != dev->iamthif_cl.me_client_id);
+	BUG_ON(dev->iamthif_state != MEI_IAMTHIF_READING);
+
+	buffer = (unsigned char *) (dev->iamthif_msg_buf +
+			dev->iamthif_msg_buf_index);
+	BUG_ON(dev->iamthif_mtu < dev->iamthif_msg_buf_index + mei_hdr->length);
+
+	mei_read_slots(dev, buffer, mei_hdr->length);
+
+	dev->iamthif_msg_buf_index += mei_hdr->length;
+
+	if (!mei_hdr->msg_complete)
+		return 0;
+
+	dev_dbg(&dev->pdev->dev,
+			"amthi_message_buffer_index =%d\n",
+			mei_hdr->length);
+
+	dev_dbg(&dev->pdev->dev, "completed amthi read.\n ");
+	if (!dev->iamthif_current_cb)
+		return -ENODEV;
+
+	cb = dev->iamthif_current_cb;
+	dev->iamthif_current_cb = NULL;
+
+	cl = (struct mei_cl *)cb->file_private;
+	if (!cl)
+		return -ENODEV;
+
+	dev->iamthif_stall_timer = 0;
+	cb->information =	dev->iamthif_msg_buf_index;
+	cb->read_time = jiffies;
+	if (dev->iamthif_ioctl && cl == &dev->iamthif_cl) {
+		/* found the iamthif cb */
+		dev_dbg(&dev->pdev->dev, "complete the amthi read cb.\n ");
+		dev_dbg(&dev->pdev->dev, "add the amthi read cb to complete.\n ");
+		list_add_tail(&cb->cb_list,
+						&complete_list->mei_cb.cb_list);
+	}
+	return 0;
+}
+
+/**
+ * _mei_irq_thread_state_ok - checks if mei header matches file private data
+ *
+ * @cl: private data of the file object
+ * @mei_hdr: header of mei client message
+ *
+ * returns !=0 if matches, 0 if no match.
+ */
+static int _mei_irq_thread_state_ok(struct mei_cl *cl,
+				struct mei_msg_hdr *mei_hdr)
+{
+	return (cl->host_client_id == mei_hdr->host_addr &&
+		cl->me_client_id == mei_hdr->me_addr &&
+		cl->state == MEI_FILE_CONNECTED &&
+		MEI_READ_COMPLETE != cl->reading_state);
+}
+
+/**
+ * mei_irq_thread_read_client_message - bottom half read routine after ISR to
+ * handle the read mei client message data processing.
+ *
+ * @complete_list: An instance of our list structure
+ * @dev: the device structure
+ * @mei_hdr: header of mei client message
+ *
+ * returns 0 on success, <0 on failure.
+ */
+static int mei_irq_thread_read_client_message(struct mei_io_list *complete_list,
+		struct mei_device *dev,
+		struct mei_msg_hdr *mei_hdr)
+{
+	struct mei_cl *cl;
+	struct mei_cl_cb *cb_pos = NULL, *cb_next = NULL;
+	unsigned char *buffer;
+
+	dev_dbg(&dev->pdev->dev, "start client msg\n");
+	if (!(dev->read_list.status == 0 &&
+	      !list_empty(&dev->read_list.mei_cb.cb_list)))
+		goto quit;
+
+	list_for_each_entry_safe(cb_pos, cb_next,
+			&dev->read_list.mei_cb.cb_list, cb_list) {
+		cl = (struct mei_cl *)cb_pos->file_private;
+		if (cl && _mei_irq_thread_state_ok(cl, mei_hdr)) {
+			cl->reading_state = MEI_READING;
+			buffer = (unsigned char *)
+				(cb_pos->response_buffer.data +
+				cb_pos->information);
+			BUG_ON(cb_pos->response_buffer.size <
+					mei_hdr->length +
+					cb_pos->information);
+
+			if (cb_pos->response_buffer.size <
+					mei_hdr->length + cb_pos->information) {
+				dev_dbg(&dev->pdev->dev, "message overflow.\n");
+				list_del(&cb_pos->cb_list);
+				return -ENOMEM;
+			}
+			if (buffer)
+				mei_read_slots(dev, buffer, mei_hdr->length);
+
+			cb_pos->information += mei_hdr->length;
+			if (mei_hdr->msg_complete) {
+				cl->status = 0;
+				list_del(&cb_pos->cb_list);
+				dev_dbg(&dev->pdev->dev,
+					"completed read host client = %d,"
+					"ME client = %d, "
+					"data length = %lu\n",
+					cl->host_client_id,
+					cl->me_client_id,
+					cb_pos->information);
+
+				*(cb_pos->response_buffer.data +
+					cb_pos->information) = '\0';
+				dev_dbg(&dev->pdev->dev, "cb_pos->res_buffer - %s\n",
+					cb_pos->response_buffer.data);
+				list_add_tail(&cb_pos->cb_list,
+					&complete_list->mei_cb.cb_list);
+			}
+
+			break;
+		}
+
+	}
+
+quit:
+	dev_dbg(&dev->pdev->dev, "message read\n");
+	if (!buffer) {
+		mei_read_slots(dev, (unsigned char *) dev->rd_msg_buf,
+						mei_hdr->length);
+		dev_dbg(&dev->pdev->dev, "discarding message, header =%08x.\n",
+				*(u32 *) dev->rd_msg_buf);
+	}
+
+	return 0;
+}
+
+/**
+ * _mei_irq_thread_iamthif_read - prepares to read iamthif data.
+ *
+ * @dev: the device structure.
+ * @slots: free slots.
+ *
+ * returns 0, OK; otherwise, error.
+ */
+static int _mei_irq_thread_iamthif_read(struct mei_device *dev, s32 *slots)
+{
+
+	if (((*slots) * sizeof(u32)) >= (sizeof(struct mei_msg_hdr)
+			+ sizeof(struct hbm_flow_control))) {
+		*slots -= (sizeof(struct mei_msg_hdr) +
+				sizeof(struct hbm_flow_control) + 3) / 4;
+		if (!mei_send_flow_control(dev, &dev->iamthif_cl)) {
+			dev_dbg(&dev->pdev->dev, "iamthif flow control failed\n");
+		} else {
+			dev_dbg(&dev->pdev->dev, "iamthif flow control success\n");
+			dev->iamthif_state = MEI_IAMTHIF_READING;
+			dev->iamthif_flow_control_pending = 0;
+			dev->iamthif_msg_buf_index = 0;
+			dev->iamthif_msg_buf_size = 0;
+			dev->iamthif_stall_timer = IAMTHIF_STALL_TIMER;
+			dev->mei_host_buffer_is_empty =
+					mei_host_buffer_is_empty(dev);
+		}
+		return 0;
+	} else {
+		return -EMSGSIZE;
+	}
+}
+
+/**
+ * _mei_irq_thread_close - processes close related operation.
+ *
+ * @dev: the device structure.
+ * @slots: free slots.
+ * @cb_pos: callback block.
+ * @cl: private data of the file object.
+ * @cmpl_list: complete list.
+ *
+ * returns 0, OK; otherwise, error.
+ */
+static int _mei_irq_thread_close(struct mei_device *dev, s32 *slots,
+				struct mei_cl_cb *cb_pos,
+				struct mei_cl *cl,
+				struct mei_io_list *cmpl_list)
+{
+	if ((*slots * sizeof(u32)) >= (sizeof(struct mei_msg_hdr) +
+			sizeof(struct hbm_client_disconnect_request))) {
+		*slots -= (sizeof(struct mei_msg_hdr) +
+			sizeof(struct hbm_client_disconnect_request) + 3) / 4;
+
+		if (!mei_disconnect(dev, cl)) {
+			cl->status = 0;
+			cb_pos->information = 0;
+			list_move_tail(&cb_pos->cb_list,
+					&cmpl_list->mei_cb.cb_list);
+			return -EMSGSIZE;
+		} else {
+			cl->state = MEI_FILE_DISCONNECTING;
+			cl->status = 0;
+			cb_pos->information = 0;
+			list_move_tail(&cb_pos->cb_list,
+					&dev->ctrl_rd_list.mei_cb.cb_list);
+			cl->timer_count = MEI_CONNECT_TIMEOUT;
+		}
+	} else {
+		/* return the cancel routine */
+		return -EBADMSG;
+	}
+
+	return 0;
+}
+
+/**
+ * is_treat_specially_client - checks if the message belongs
+ * to the file private data.
+ *
+ * @cl: private data of the file object
+ * @rs: connect response bus message
+ *
+ */
+static bool is_treat_specially_client(struct mei_cl *cl,
+		struct hbm_client_connect_response *rs)
+{
+
+	if (cl->host_client_id == rs->host_addr &&
+	    cl->me_client_id == rs->me_addr) {
+		if (!rs->status) {
+			cl->state = MEI_FILE_CONNECTED;
+			cl->status = 0;
+
+		} else {
+			cl->state = MEI_FILE_DISCONNECTED;
+			cl->status = -ENODEV;
+		}
+		cl->timer_count = 0;
+
+		return true;
+	}
+	return false;
+}
+
+/**
+ * mei_client_connect_response - connects to response irq routine
+ *
+ * @dev: the device structure
+ * @rs: connect response bus message
+ */
+static void mei_client_connect_response(struct mei_device *dev,
+		struct hbm_client_connect_response *rs)
+{
+
+	struct mei_cl *cl;
+	struct mei_cl_cb *cb_pos = NULL, *cb_next = NULL;
+
+	dev_dbg(&dev->pdev->dev,
+			"connect_response:\n"
+			"ME Client = %d\n"
+			"Host Client = %d\n"
+			"Status = %d\n",
+			rs->me_addr,
+			rs->host_addr,
+			rs->status);
+
+	/* if WD or iamthif client treat specially */
+
+	if (is_treat_specially_client(&(dev->wd_cl), rs)) {
+		dev_dbg(&dev->pdev->dev, "dev->wd_timeout =%d.\n",
+				dev->wd_timeout);
+
+		dev->wd_due_counter = (dev->wd_timeout) ? 1 : 0;
+
+		dev_dbg(&dev->pdev->dev, "successfully connected to WD client.\n");
+		host_init_iamthif(dev);
+		return;
+	}
+
+	if (is_treat_specially_client(&(dev->iamthif_cl), rs)) {
+		dev->iamthif_state = MEI_IAMTHIF_IDLE;
+		return;
+	}
+	if (!dev->ctrl_rd_list.status &&
+	    !list_empty(&dev->ctrl_rd_list.mei_cb.cb_list)) {
+		list_for_each_entry_safe(cb_pos, cb_next,
+			&dev->ctrl_rd_list.mei_cb.cb_list, cb_list) {
+			cl = (struct mei_cl *)cb_pos->file_private;
+			if (!cl) {
+				list_del(&cb_pos->cb_list);
+				return;
+			}
+			if (MEI_IOCTL == cb_pos->major_file_operations) {
+				if (is_treat_specially_client(cl, rs)) {
+					list_del(&cb_pos->cb_list);
+					cl->status = 0;
+					cl->timer_count = 0;
+					break;
+				}
+			}
+		}
+	}
+}
+
+/**
+ * mei_client_disconnect_response - disconnects from response irq routine
+ *
+ * @dev: the device structure
+ * @rs: disconnect response bus message
+ */
+static void mei_client_disconnect_response(struct mei_device *dev,
+					struct hbm_client_connect_response *rs)
+{
+	struct mei_cl *cl;
+	struct mei_cl_cb *cb_pos = NULL, *cb_next = NULL;
+
+	dev_dbg(&dev->pdev->dev,
+			"disconnect_response:\n"
+			"ME Client = %d\n"
+			"Host Client = %d\n"
+			"Status = %d\n",
+			rs->me_addr,
+			rs->host_addr,
+			rs->status);
+
+	if (!dev->ctrl_rd_list.status &&
+	    !list_empty(&dev->ctrl_rd_list.mei_cb.cb_list)) {
+		list_for_each_entry_safe(cb_pos, cb_next,
+				&dev->ctrl_rd_list.mei_cb.cb_list, cb_list) {
+			cl = (struct mei_cl *)cb_pos->file_private;
+
+			if (!cl) {
+				list_del(&cb_pos->cb_list);
+				return;
+			}
+
+			dev_dbg(&dev->pdev->dev, "list_for_each_entry_safe in ctrl_rd_list.\n");
+			if (cl->host_client_id == rs->host_addr &&
+			    cl->me_client_id == rs->me_addr) {
+
+				list_del(&cb_pos->cb_list);
+				if (!rs->status)
+					cl->state = MEI_FILE_DISCONNECTED;
+
+				cl->status = 0;
+				cl->timer_count = 0;
+				break;
+			}
+		}
+	}
+}
+
+/**
+ * same_flow_addr - tells if they have the same address.
+ *
+ * @file: private data of the file object.
+ * @flow: flow control.
+ *
+ * returns  !=0, same; 0,not.
+ */
+static int same_flow_addr(struct mei_cl *cl, struct hbm_flow_control *flow)
+{
+	return (cl->host_client_id == flow->host_addr &&
+		cl->me_client_id == flow->me_addr);
+}
+
+/**
+ * add_single_flow_creds - adds single buffer credentials.
+ *
+ * @file: private data ot the file object.
+ * @flow: flow control.
+ */
+static void add_single_flow_creds(struct mei_device *dev,
+				  struct hbm_flow_control *flow)
+{
+	struct mei_me_client *client;
+	int i;
+
+	for (i = 0; i < dev->num_mei_me_clients; i++) {
+		client = &dev->me_clients[i];
+		if (client && flow->me_addr == client->client_id) {
+			if (client->props.single_recv_buf) {
+				client->mei_flow_ctrl_creds++;
+				dev_dbg(&dev->pdev->dev, "recv flow ctrl msg ME %d (single).\n",
+				    flow->me_addr);
+				dev_dbg(&dev->pdev->dev, "flow control credentials =%d.\n",
+				    client->mei_flow_ctrl_creds);
+			} else {
+				BUG();	/* error in flow control */
+			}
+		}
+	}
+}
+
+/**
+ * mei_client_flow_control_response - flow control response irq routine
+ *
+ * @dev: the device structure
+ * @flow_control: flow control response bus message
+ */
+static void mei_client_flow_control_response(struct mei_device *dev,
+		struct hbm_flow_control *flow_control)
+{
+	struct mei_cl *cl_pos = NULL;
+	struct mei_cl *cl_next = NULL;
+
+	if (!flow_control->host_addr) {
+		/* single receive buffer */
+		add_single_flow_creds(dev, flow_control);
+	} else {
+		/* normal connection */
+		list_for_each_entry_safe(cl_pos, cl_next,
+				&dev->file_list, link) {
+			dev_dbg(&dev->pdev->dev, "list_for_each_entry_safe in file_list\n");
+
+			dev_dbg(&dev->pdev->dev, "cl of host client %d ME client %d.\n",
+			    cl_pos->host_client_id,
+			    cl_pos->me_client_id);
+			dev_dbg(&dev->pdev->dev, "flow ctrl msg for host %d ME %d.\n",
+			    flow_control->host_addr,
+			    flow_control->me_addr);
+			if (same_flow_addr(cl_pos, flow_control)) {
+				dev_dbg(&dev->pdev->dev, "recv ctrl msg for host  %d ME %d.\n",
+				    flow_control->host_addr,
+				    flow_control->me_addr);
+				cl_pos->mei_flow_ctrl_creds++;
+				dev_dbg(&dev->pdev->dev, "flow control credentials = %d.\n",
+				    cl_pos->mei_flow_ctrl_creds);
+				break;
+			}
+		}
+	}
+}
+
+/**
+ * same_disconn_addr - tells if they have the same address
+ *
+ * @file: private data of the file object.
+ * @disconn: disconnection request.
+ *
+ * returns !=0, same; 0,not.
+ */
+static int same_disconn_addr(struct mei_cl *cl,
+			     struct hbm_client_disconnect_request *disconn)
+{
+	return (cl->host_client_id == disconn->host_addr &&
+		cl->me_client_id == disconn->me_addr);
+}
+
+/**
+ * mei_client_disconnect_request - disconnects from request irq routine
+ *
+ * @dev: the device structure.
+ * @disconnect_req: disconnect request bus message.
+ */
+static void mei_client_disconnect_request(struct mei_device *dev,
+		struct hbm_client_disconnect_request *disconnect_req)
+{
+	struct mei_msg_hdr *mei_hdr;
+	struct hbm_client_connect_response *disconnect_res;
+	struct mei_cl *cl_pos = NULL;
+	struct mei_cl *cl_next = NULL;
+
+	list_for_each_entry_safe(cl_pos, cl_next, &dev->file_list, link) {
+		if (same_disconn_addr(cl_pos, disconnect_req)) {
+			dev_dbg(&dev->pdev->dev, "disconnect request host client %d ME client %d.\n",
+					disconnect_req->host_addr,
+					disconnect_req->me_addr);
+			cl_pos->state = MEI_FILE_DISCONNECTED;
+			cl_pos->timer_count = 0;
+			if (cl_pos == &dev->wd_cl) {
+				dev->wd_due_counter = 0;
+				dev->wd_pending = 0;
+			} else if (cl_pos == &dev->iamthif_cl)
+				dev->iamthif_timer = 0;
+
+			/* prepare disconnect response */
+			mei_hdr =
+				(struct mei_msg_hdr *) &dev->ext_msg_buf[0];
+			mei_hdr->host_addr = 0;
+			mei_hdr->me_addr = 0;
+			mei_hdr->length =
+				sizeof(struct hbm_client_connect_response);
+			mei_hdr->msg_complete = 1;
+			mei_hdr->reserved = 0;
+
+			disconnect_res =
+				(struct hbm_client_connect_response *)
+				&dev->ext_msg_buf[1];
+			disconnect_res->host_addr = cl_pos->host_client_id;
+			disconnect_res->me_addr = cl_pos->me_client_id;
+			*(u8 *) (&disconnect_res->cmd) =
+				CLIENT_DISCONNECT_RES_CMD;
+			disconnect_res->status = 0;
+			dev->extra_write_index = 2;
+			break;
+		}
+	}
+}
+
+
+/**
+ * mei_irq_thread_read_bus_message - bottom half read routine after ISR to
+ * handle the read bus message cmd processing.
+ *
+ * @dev: the device structure
+ * @mei_hdr: header of bus message
+ */
+static void mei_irq_thread_read_bus_message(struct mei_device *dev,
+		struct mei_msg_hdr *mei_hdr)
+{
+	struct mei_bus_message *mei_msg;
+	struct hbm_host_version_response *version_res;
+	struct hbm_client_connect_response *connect_res;
+	struct hbm_client_connect_response *disconnect_res;
+	struct hbm_flow_control *flow_control;
+	struct hbm_props_response *props_res;
+	struct hbm_host_enum_response *enum_res;
+	struct hbm_client_disconnect_request *disconnect_req;
+	struct hbm_host_stop_request *host_stop_req;
+
+	unsigned char *buffer;
+
+	/* read the message to our buffer */
+	buffer = (unsigned char *) dev->rd_msg_buf;
+	BUG_ON(mei_hdr->length >= sizeof(dev->rd_msg_buf));
+	mei_read_slots(dev, buffer, mei_hdr->length);
+	mei_msg = (struct mei_bus_message *) buffer;
+
+	switch (*(u8 *) mei_msg) {
+	case HOST_START_RES_CMD:
+		version_res = (struct hbm_host_version_response *) mei_msg;
+		if (version_res->host_version_supported) {
+			dev->version.major_version = HBM_MAJOR_VERSION;
+			dev->version.minor_version = HBM_MINOR_VERSION;
+			if (dev->mei_state == MEI_INIT_CLIENTS &&
+			    dev->init_clients_state == MEI_START_MESSAGE) {
+				dev->init_clients_timer = 0;
+				host_enum_clients_message(dev);
+			} else {
+				dev->recvd_msg = 0;
+				dev_dbg(&dev->pdev->dev, "IMEI reset due to received host start response bus message.\n");
+				mei_reset(dev, 1);
+				return;
+			}
+		} else {
+			dev->version = version_res->me_max_version;
+			/* send stop message */
+			mei_hdr->host_addr = 0;
+			mei_hdr->me_addr = 0;
+			mei_hdr->length = sizeof(struct hbm_host_stop_request);
+			mei_hdr->msg_complete = 1;
+			mei_hdr->reserved = 0;
+
+			host_stop_req = (struct hbm_host_stop_request *)
+							&dev->wr_msg_buf[1];
+
+			memset(host_stop_req,
+					0,
+					sizeof(struct hbm_host_stop_request));
+			host_stop_req->cmd.cmd = HOST_STOP_REQ_CMD;
+			host_stop_req->reason = DRIVER_STOP_REQUEST;
+			mei_write_message(dev, mei_hdr,
+					   (unsigned char *) (host_stop_req),
+					   mei_hdr->length);
+			dev_dbg(&dev->pdev->dev, "version mismatch.\n");
+			return;
+		}
+
+		dev->recvd_msg = 1;
+		dev_dbg(&dev->pdev->dev, "host start response message received.\n");
+		break;
+
+	case CLIENT_CONNECT_RES_CMD:
+		connect_res =
+			(struct hbm_client_connect_response *) mei_msg;
+		mei_client_connect_response(dev, connect_res);
+		dev_dbg(&dev->pdev->dev, "client connect response message received.\n");
+		wake_up(&dev->wait_recvd_msg);
+		break;
+
+	case CLIENT_DISCONNECT_RES_CMD:
+		disconnect_res =
+			(struct hbm_client_connect_response *) mei_msg;
+		mei_client_disconnect_response(dev,	 disconnect_res);
+		dev_dbg(&dev->pdev->dev, "client disconnect response message received.\n");
+		wake_up(&dev->wait_recvd_msg);
+		break;
+
+	case MEI_FLOW_CONTROL_CMD:
+		flow_control = (struct hbm_flow_control *) mei_msg;
+		mei_client_flow_control_response(dev, flow_control);
+		dev_dbg(&dev->pdev->dev, "client flow control response message received.\n");
+		break;
+
+	case HOST_CLIENT_PROPERTIES_RES_CMD:
+		props_res = (struct hbm_props_response *)mei_msg;
+		if (props_res->status || !dev->me_clients) {
+			dev_dbg(&dev->pdev->dev, "reset due to received host client properties response bus message wrong status.\n");
+			mei_reset(dev, 1);
+			return;
+		}
+	       if (dev->me_clients[dev->me_client_presentation_num]
+					.client_id == props_res->address) {
+
+			dev->me_clients[dev->me_client_presentation_num].props
+						= props_res->client_properties;
+
+			if (dev->mei_state == MEI_INIT_CLIENTS &&
+			    dev->init_clients_state ==
+					MEI_CLIENT_PROPERTIES_MESSAGE) {
+				dev->me_client_index++;
+				dev->me_client_presentation_num++;
+				host_client_properties(dev);
+			} else {
+				dev_dbg(&dev->pdev->dev, "reset due to received host client properties response bus message");
+				mei_reset(dev, 1);
+				return;
+			}
+		} else {
+			dev_dbg(&dev->pdev->dev, "reset due to received host client properties response bus message for wrong client ID\n");
+			mei_reset(dev, 1);
+			return;
+		}
+		break;
+
+	case HOST_ENUM_RES_CMD:
+		enum_res = (struct hbm_host_enum_response *) mei_msg;
+		memcpy(dev->me_clients_map, enum_res->valid_addresses, 32);
+		if (dev->mei_state == MEI_INIT_CLIENTS &&
+		    dev->init_clients_state == MEI_ENUM_CLIENTS_MESSAGE) {
+				dev->init_clients_timer = 0;
+				dev->me_client_presentation_num = 0;
+				dev->me_client_index = 0;
+				allocate_me_clients_storage(dev);
+				dev->init_clients_state =
+					MEI_CLIENT_PROPERTIES_MESSAGE;
+				host_client_properties(dev);
+		} else {
+			dev_dbg(&dev->pdev->dev, "reset due to received host enumeration clients response bus message.\n");
+			mei_reset(dev, 1);
+			return;
+		}
+		break;
+
+	case HOST_STOP_RES_CMD:
+		dev->mei_state = MEI_DISABLED;
+		dev_dbg(&dev->pdev->dev, "resetting because of FW stop response.\n");
+		mei_reset(dev, 1);
+		break;
+
+	case CLIENT_DISCONNECT_REQ_CMD:
+		/* search for client */
+		disconnect_req =
+			(struct hbm_client_disconnect_request *) mei_msg;
+		mei_client_disconnect_request(dev, disconnect_req);
+		break;
+
+	case ME_STOP_REQ_CMD:
+		/* prepare stop request */
+		mei_hdr = (struct mei_msg_hdr *) &dev->ext_msg_buf[0];
+		mei_hdr->host_addr = 0;
+		mei_hdr->me_addr = 0;
+		mei_hdr->length = sizeof(struct hbm_host_stop_request);
+		mei_hdr->msg_complete = 1;
+		mei_hdr->reserved = 0;
+		host_stop_req =
+			(struct hbm_host_stop_request *) &dev->ext_msg_buf[1];
+		memset(host_stop_req, 0, sizeof(struct hbm_host_stop_request));
+		host_stop_req->cmd.cmd = HOST_STOP_REQ_CMD;
+		host_stop_req->reason = DRIVER_STOP_REQUEST;
+		host_stop_req->reserved[0] = 0;
+		host_stop_req->reserved[1] = 0;
+		dev->extra_write_index = 2;
+		break;
+
+	default:
+		BUG();
+		break;
+
+	}
+}
+
+
+/**
+ * _mei_hb_read - processes read related operation.
+ *
+ * @dev: the device structure.
+ * @slots: free slots.
+ * @cb_pos: callback block.
+ * @cl: private data of the file object.
+ * @cmpl_list: complete list.
+ *
+ * returns 0, OK; otherwise, error.
+ */
+static int _mei_irq_thread_read(struct mei_device *dev,	s32 *slots,
+			struct mei_cl_cb *cb_pos,
+			struct mei_cl *cl,
+			struct mei_io_list *cmpl_list)
+{
+	if ((*slots * sizeof(u32)) >= (sizeof(struct mei_msg_hdr) +
+			sizeof(struct hbm_flow_control))) {
+		*slots -= (sizeof(struct mei_msg_hdr) +
+			sizeof(struct hbm_flow_control) + 3) / 4;
+		if (!mei_send_flow_control(dev, cl)) {
+			cl->status = -ENODEV;
+			cb_pos->information = 0;
+			list_move_tail(&cb_pos->cb_list,
+					&cmpl_list->mei_cb.cb_list);
+			return -ENODEV;
+		} else {
+			list_move_tail(&cb_pos->cb_list,
+					&dev->read_list.mei_cb.cb_list);
+		}
+	} else {
+		/* return the cancel routine */
+		list_del(&cb_pos->cb_list);
+		return -EBADMSG;
+	}
+
+	return 0;
+}
+
+
+/**
+ * _mei_irq_thread_ioctl - processes ioctl related operation.
+ *
+ * @dev: the device structure.
+ * @slots: free slots.
+ * @cb_pos: callback block.
+ * @cl: private data of the file object.
+ * @cmpl_list: complete list.
+ *
+ * returns 0, OK; otherwise, error.
+ */
+static int _mei_irq_thread_ioctl(struct mei_device *dev, s32 *slots,
+			struct mei_cl_cb *cb_pos,
+			struct mei_cl *cl,
+			struct mei_io_list *cmpl_list)
+{
+	if ((*slots * sizeof(u32)) >= (sizeof(struct mei_msg_hdr) +
+			sizeof(struct hbm_client_connect_request))) {
+		cl->state = MEI_FILE_CONNECTING;
+		*slots -= (sizeof(struct mei_msg_hdr) +
+			sizeof(struct hbm_client_connect_request) + 3) / 4;
+		if (!mei_connect(dev, cl)) {
+			cl->status = -ENODEV;
+			cb_pos->information = 0;
+			list_del(&cb_pos->cb_list);
+			return -ENODEV;
+		} else {
+			list_move_tail(&cb_pos->cb_list,
+				&dev->ctrl_rd_list.mei_cb.cb_list);
+			cl->timer_count = MEI_CONNECT_TIMEOUT;
+		}
+	} else {
+		/* return the cancel routine */
+		list_del(&cb_pos->cb_list);
+		return -EBADMSG;
+	}
+
+	return 0;
+}
+
+/**
+ * _mei_irq_thread_cmpl - processes completed and no-iamthif operation.
+ *
+ * @dev: the device structure.
+ * @slots: free slots.
+ * @cb_pos: callback block.
+ * @cl: private data of the file object.
+ * @cmpl_list: complete list.
+ *
+ * returns 0, OK; otherwise, error.
+ */
+static int _mei_irq_thread_cmpl(struct mei_device *dev,	s32 *slots,
+			struct mei_cl_cb *cb_pos,
+			struct mei_cl *cl,
+			struct mei_io_list *cmpl_list)
+{
+	struct mei_msg_hdr *mei_hdr;
+
+	if ((*slots * sizeof(u32)) >= (sizeof(struct mei_msg_hdr) +
+			(cb_pos->request_buffer.size -
+			cb_pos->information))) {
+		mei_hdr = (struct mei_msg_hdr *) &dev->wr_msg_buf[0];
+		mei_hdr->host_addr = cl->host_client_id;
+		mei_hdr->me_addr = cl->me_client_id;
+		mei_hdr->length = cb_pos->request_buffer.size -
+					cb_pos->information;
+		mei_hdr->msg_complete = 1;
+		mei_hdr->reserved = 0;
+		dev_dbg(&dev->pdev->dev, "cb_pos->request_buffer.size =%d"
+			"mei_hdr->msg_complete = %d\n",
+				cb_pos->request_buffer.size,
+				mei_hdr->msg_complete);
+		dev_dbg(&dev->pdev->dev, "cb_pos->information  =%lu\n",
+				cb_pos->information);
+		dev_dbg(&dev->pdev->dev, "mei_hdr->length  =%d\n",
+				mei_hdr->length);
+		*slots -= (sizeof(struct mei_msg_hdr) +
+				mei_hdr->length + 3) / 4;
+		if (!mei_write_message(dev, mei_hdr,
+				(unsigned char *)
+				(cb_pos->request_buffer.data +
+				cb_pos->information),
+				mei_hdr->length)) {
+			cl->status = -ENODEV;
+			list_move_tail(&cb_pos->cb_list,
+				&cmpl_list->mei_cb.cb_list);
+			return -ENODEV;
+		} else {
+			if (mei_flow_ctrl_reduce(dev, cl))
+				return -ENODEV;
+			cl->status = 0;
+			cb_pos->information += mei_hdr->length;
+			list_move_tail(&cb_pos->cb_list,
+				&dev->write_waiting_list.mei_cb.cb_list);
+		}
+	} else if (*slots == ((dev->host_hw_state & H_CBD) >> 24)) {
+		/* buffer is still empty */
+		mei_hdr = (struct mei_msg_hdr *) &dev->wr_msg_buf[0];
+		mei_hdr->host_addr = cl->host_client_id;
+		mei_hdr->me_addr = cl->me_client_id;
+		mei_hdr->length =
+			(*slots * sizeof(u32)) - sizeof(struct mei_msg_hdr);
+		mei_hdr->msg_complete = 0;
+		mei_hdr->reserved = 0;
+
+		(*slots) -= (sizeof(struct mei_msg_hdr) +
+				mei_hdr->length + 3) / 4;
+		if (!mei_write_message(dev, mei_hdr,
+					(unsigned char *)
+					(cb_pos->request_buffer.data +
+					cb_pos->information),
+					mei_hdr->length)) {
+			cl->status = -ENODEV;
+			list_move_tail(&cb_pos->cb_list,
+				&cmpl_list->mei_cb.cb_list);
+			return -ENODEV;
+		} else {
+			cb_pos->information += mei_hdr->length;
+			dev_dbg(&dev->pdev->dev,
+					"cb_pos->request_buffer.size =%d"
+					" mei_hdr->msg_complete = %d\n",
+					cb_pos->request_buffer.size,
+					mei_hdr->msg_complete);
+			dev_dbg(&dev->pdev->dev, "cb_pos->information  =%lu\n",
+					cb_pos->information);
+			dev_dbg(&dev->pdev->dev, "mei_hdr->length  =%d\n",
+					mei_hdr->length);
+		}
+		return -EMSGSIZE;
+	} else {
+		return -EBADMSG;
+	}
+
+	return 0;
+}
+
+/**
+ * _mei_irq_thread_cmpl_iamthif - processes completed iamthif operation.
+ *
+ * @dev: the device structure.
+ * @slots: free slots.
+ * @cb_pos: callback block.
+ * @cl: private data of the file object.
+ * @cmpl_list: complete list.
+ *
+ * returns 0, OK; otherwise, error.
+ */
+static int _mei_irq_thread_cmpl_iamthif(struct mei_device *dev, s32 *slots,
+			struct mei_cl_cb *cb_pos,
+			struct mei_cl *cl,
+			struct mei_io_list *cmpl_list)
+{
+	struct mei_msg_hdr *mei_hdr;
+
+	if ((*slots * sizeof(u32)) >= (sizeof(struct mei_msg_hdr) +
+			dev->iamthif_msg_buf_size -
+			dev->iamthif_msg_buf_index)) {
+		mei_hdr = (struct mei_msg_hdr *) &dev->wr_msg_buf[0];
+		mei_hdr->host_addr = cl->host_client_id;
+		mei_hdr->me_addr = cl->me_client_id;
+		mei_hdr->length = dev->iamthif_msg_buf_size -
+			dev->iamthif_msg_buf_index;
+		mei_hdr->msg_complete = 1;
+		mei_hdr->reserved = 0;
+
+		*slots -= (sizeof(struct mei_msg_hdr) +
+				mei_hdr->length + 3) / 4;
+
+		if (!mei_write_message(dev, mei_hdr,
+					(dev->iamthif_msg_buf +
+					dev->iamthif_msg_buf_index),
+					mei_hdr->length)) {
+			dev->iamthif_state = MEI_IAMTHIF_IDLE;
+			cl->status = -ENODEV;
+			list_del(&cb_pos->cb_list);
+			return -ENODEV;
+		} else {
+			if (mei_flow_ctrl_reduce(dev, cl))
+				return -ENODEV;
+			dev->iamthif_msg_buf_index += mei_hdr->length;
+			cb_pos->information = dev->iamthif_msg_buf_index;
+			cl->status = 0;
+			dev->iamthif_state = MEI_IAMTHIF_FLOW_CONTROL;
+			dev->iamthif_flow_control_pending = 1;
+			/* save iamthif cb sent to amthi client */
+			dev->iamthif_current_cb = cb_pos;
+			list_move_tail(&cb_pos->cb_list,
+				&dev->write_waiting_list.mei_cb.cb_list);
+
+		}
+	} else if (*slots == ((dev->host_hw_state & H_CBD) >> 24)) {
+			/* buffer is still empty */
+		mei_hdr = (struct mei_msg_hdr *) &dev->wr_msg_buf[0];
+		mei_hdr->host_addr = cl->host_client_id;
+		mei_hdr->me_addr = cl->me_client_id;
+		mei_hdr->length =
+			(*slots * sizeof(u32)) - sizeof(struct mei_msg_hdr);
+		mei_hdr->msg_complete = 0;
+		mei_hdr->reserved = 0;
+
+		*slots -= (sizeof(struct mei_msg_hdr) +
+				mei_hdr->length + 3) / 4;
+
+		if (!mei_write_message(dev, mei_hdr,
+					(dev->iamthif_msg_buf +
+					dev->iamthif_msg_buf_index),
+					mei_hdr->length)) {
+			cl->status = -ENODEV;
+			list_del(&cb_pos->cb_list);
+		} else {
+			dev->iamthif_msg_buf_index += mei_hdr->length;
+		}
+		return -EMSGSIZE;
+	} else {
+		return -EBADMSG;
+	}
+
+	return 0;
+}
+
+/**
+ * mei_irq_thread_read_handler - bottom half read routine after ISR to
+ * handle the read processing.
+ *
+ * @cmpl_list: An instance of our list structure
+ * @dev: the device structure
+ * @slots: slots to read.
+ *
+ * returns 0 on success, <0 on failure.
+ */
+static int mei_irq_thread_read_handler(struct mei_io_list *cmpl_list,
+		struct mei_device *dev,
+		s32 *slots)
+{
+	struct mei_msg_hdr *mei_hdr;
+	struct mei_cl *cl_pos = NULL;
+	struct mei_cl *cl_next = NULL;
+	int ret = 0;
+
+	if (!dev->rd_msg_hdr) {
+		dev->rd_msg_hdr = mei_mecbrw_read(dev);
+		dev_dbg(&dev->pdev->dev, "slots =%08x.\n", *slots);
+		(*slots)--;
+		dev_dbg(&dev->pdev->dev, "slots =%08x.\n", *slots);
+	}
+	mei_hdr = (struct mei_msg_hdr *) &dev->rd_msg_hdr;
+	dev_dbg(&dev->pdev->dev, "mei_hdr->length =%d\n", mei_hdr->length);
+
+	if (mei_hdr->reserved || !dev->rd_msg_hdr) {
+		dev_dbg(&dev->pdev->dev, "corrupted message header.\n");
+		ret = -EBADMSG;
+		goto end;
+	}
+
+	if (mei_hdr->host_addr || mei_hdr->me_addr) {
+		list_for_each_entry_safe(cl_pos, cl_next,
+					&dev->file_list, link) {
+			dev_dbg(&dev->pdev->dev,
+					"list_for_each_entry_safe read host"
+					" client = %d, ME client = %d\n",
+					cl_pos->host_client_id,
+					cl_pos->me_client_id);
+			if (cl_pos->host_client_id == mei_hdr->host_addr &&
+			    cl_pos->me_client_id == mei_hdr->me_addr)
+				break;
+		}
+
+		if (&cl_pos->link == &dev->file_list) {
+			dev_dbg(&dev->pdev->dev, "corrupted message header\n");
+			ret = -EBADMSG;
+			goto end;
+		}
+	}
+	if (((*slots) * sizeof(u32)) < mei_hdr->length) {
+		dev_dbg(&dev->pdev->dev,
+				"we can't read the message slots =%08x.\n",
+				*slots);
+		/* we can't read the message */
+		ret = -ERANGE;
+		goto end;
+	}
+
+	/* decide where to read the message too */
+	if (!mei_hdr->host_addr) {
+		dev_dbg(&dev->pdev->dev, "call mei_irq_thread_read_bus_message.\n");
+		mei_irq_thread_read_bus_message(dev, mei_hdr);
+		dev_dbg(&dev->pdev->dev, "end mei_irq_thread_read_bus_message.\n");
+	} else if (mei_hdr->host_addr == dev->iamthif_cl.host_client_id &&
+		   (MEI_FILE_CONNECTED == dev->iamthif_cl.state) &&
+		   (dev->iamthif_state == MEI_IAMTHIF_READING)) {
+		dev_dbg(&dev->pdev->dev, "call mei_irq_thread_read_iamthif_message.\n");
+		dev_dbg(&dev->pdev->dev, "mei_hdr->length =%d\n",
+				mei_hdr->length);
+		ret = mei_irq_thread_read_amthi_message(cmpl_list,
+							dev, mei_hdr);
+		if (ret)
+			goto end;
+
+	} else {
+		dev_dbg(&dev->pdev->dev, "call mei_irq_thread_read_client_message.\n");
+		ret = mei_irq_thread_read_client_message(cmpl_list,
+							 dev, mei_hdr);
+		if (ret)
+			goto end;
+
+	}
+
+	/* reset the number of slots and header */
+	*slots = mei_count_full_read_slots(dev);
+	dev->rd_msg_hdr = 0;
+
+	if (*slots == -EOVERFLOW) {
+		/* overflow - reset */
+		dev_dbg(&dev->pdev->dev, "resetting due to slots overflow.\n");
+		/* set the event since message has been read */
+		ret = -ERANGE;
+		goto end;
+	}
+end:
+	return ret;
+}
+
+
+/**
+ * mei_irq_thread_write_handler - bottom half write routine after
+ * ISR to handle the write processing.
+ *
+ * @cmpl_list: An instance of our list structure
+ * @dev: the device structure
+ * @slots: slots to write.
+ *
+ * returns 0 on success, <0 on failure.
+ */
+static int mei_irq_thread_write_handler(struct mei_io_list *cmpl_list,
+		struct mei_device *dev,
+		s32 *slots)
+{
+
+	struct mei_cl *cl;
+	struct mei_cl_cb *cb_pos = NULL, *cb_next = NULL;
+	struct mei_io_list *list;
+	int ret;
+
+	if (!mei_host_buffer_is_empty(dev)) {
+		dev_dbg(&dev->pdev->dev, "host buffer is not empty.\n");
+		return 0;
+	}
+	dev->write_hang = -1;
+	*slots = mei_count_empty_write_slots(dev);
+	/* complete all waiting for write CB */
+	dev_dbg(&dev->pdev->dev, "complete all waiting for write cb.\n");
+
+	list = &dev->write_waiting_list;
+	if (!list->status && !list_empty(&list->mei_cb.cb_list)) {
+		list_for_each_entry_safe(cb_pos, cb_next,
+				&list->mei_cb.cb_list, cb_list) {
+			cl = (struct mei_cl *)cb_pos->file_private;
+			if (cl) {
+				cl->status = 0;
+				list_del(&cb_pos->cb_list);
+				if (MEI_WRITING == cl->writing_state &&
+				   (cb_pos->major_file_operations ==
+						MEI_WRITE) &&
+				   (cl != &dev->iamthif_cl)) {
+					dev_dbg(&dev->pdev->dev,
+						"MEI WRITE COMPLETE\n");
+					cl->writing_state =
+							MEI_WRITE_COMPLETE;
+					list_add_tail(&cb_pos->cb_list,
+						&cmpl_list->mei_cb.cb_list);
+				}
+				if (cl == &dev->iamthif_cl) {
+					dev_dbg(&dev->pdev->dev, "check iamthif flow control.\n");
+					if (dev->iamthif_flow_control_pending) {
+						ret =
+						_mei_irq_thread_iamthif_read(
+								dev, slots);
+						if (ret)
+							return ret;
+					}
+				}
+			}
+
+		}
+	}
+
+	if (dev->stop && !dev->wd_pending) {
+		dev->wd_stopped = 1;
+		wake_up_interruptible(&dev->wait_stop_wd);
+		return 0;
+	}
+
+	if (dev->extra_write_index) {
+		dev_dbg(&dev->pdev->dev, "extra_write_index =%d.\n",
+				dev->extra_write_index);
+		mei_write_message(dev,
+				(struct mei_msg_hdr *) &dev->ext_msg_buf[0],
+				(unsigned char *) &dev->ext_msg_buf[1],
+				(dev->extra_write_index - 1) * sizeof(u32));
+		*slots -= dev->extra_write_index;
+		dev->extra_write_index = 0;
+	}
+	if (dev->mei_state == MEI_ENABLED) {
+		if (dev->wd_pending &&
+			mei_flow_ctrl_creds(dev, &dev->wd_cl) > 0) {
+			if (mei_wd_send(dev))
+				dev_dbg(&dev->pdev->dev, "wd send failed.\n");
+			else
+				if (mei_flow_ctrl_reduce(dev, &dev->wd_cl))
+					return -ENODEV;
+
+			dev->wd_pending = 0;
+
+			if (dev->wd_timeout) {
+				*slots -= (sizeof(struct mei_msg_hdr) +
+					 MEI_START_WD_DATA_SIZE + 3) / 4;
+				dev->wd_due_counter = 2;
+			} else {
+				*slots -= (sizeof(struct mei_msg_hdr) +
+					 MEI_WD_PARAMS_SIZE + 3) / 4;
+				dev->wd_due_counter = 0;
+			}
+
+		}
+	}
+	if (dev->stop)
+		return ~ENODEV;
+
+	/* complete control write list CB */
+	if (!dev->ctrl_wr_list.status) {
+		/* complete control write list CB */
+		dev_dbg(&dev->pdev->dev, "complete control write list cb.\n");
+		list_for_each_entry_safe(cb_pos, cb_next,
+				&dev->ctrl_wr_list.mei_cb.cb_list, cb_list) {
+			cl = (struct mei_cl *)
+				cb_pos->file_private;
+			if (!cl) {
+				list_del(&cb_pos->cb_list);
+				return -ENODEV;
+			}
+			switch (cb_pos->major_file_operations) {
+			case MEI_CLOSE:
+				/* send disconnect message */
+				ret = _mei_irq_thread_close(dev, slots,
+						     cb_pos, cl, cmpl_list);
+				if (ret)
+					return ret;
+
+				break;
+			case MEI_READ:
+				/* send flow control message */
+				ret = _mei_irq_thread_read(dev, slots,
+						    cb_pos, cl, cmpl_list);
+				if (ret)
+					return ret;
+
+				break;
+			case MEI_IOCTL:
+				/* connect message */
+				if (!mei_other_client_is_connecting(dev,
+						cl))
+					continue;
+				ret = _mei_irq_thread_ioctl(dev, slots,
+						     cb_pos, cl, cmpl_list);
+				if (ret)
+					return ret;
+
+				break;
+
+			default:
+				BUG();
+			}
+
+		}
+	}
+	/* complete  write list CB */
+	if (!dev->write_list.status &&
+	    !list_empty(&dev->write_list.mei_cb.cb_list)) {
+		dev_dbg(&dev->pdev->dev, "complete write list cb.\n");
+		list_for_each_entry_safe(cb_pos, cb_next,
+				&dev->write_list.mei_cb.cb_list, cb_list) {
+			cl = (struct mei_cl *)cb_pos->file_private;
+
+			if (cl) {
+				if (cl != &dev->iamthif_cl) {
+					if (!mei_flow_ctrl_creds(dev,
+						cl)) {
+						dev_dbg(&dev->pdev->dev,
+							"No flow control"
+						    " credentials for client"
+						    " %d, not sending.\n",
+						    cl->host_client_id);
+						continue;
+					}
+					ret = _mei_irq_thread_cmpl(dev, slots,
+							    cb_pos,
+							    cl, cmpl_list);
+					if (ret)
+						return ret;
+
+				} else if (cl == &dev->iamthif_cl) {
+					/* IAMTHIF IOCTL */
+					dev_dbg(&dev->pdev->dev, "complete amthi write cb.\n");
+					if (!mei_flow_ctrl_creds(dev,
+							cl)) {
+						dev_dbg(&dev->pdev->dev,
+							"No flow control"
+						    " credentials for amthi"
+						    " client %d.\n",
+						    cl->host_client_id);
+						continue;
+					}
+					ret = _mei_irq_thread_cmpl_iamthif(dev,
+								slots,
+								cb_pos,
+								cl,
+								cmpl_list);
+					if (ret)
+						return ret;
+
+				}
+			}
+
+		}
+	}
+	return 0;
+}
+
+
+
+/**
+ * mei_timer - timer function.
+ *
+ * @work: pointer to the work_struct structure
+ *
+ * NOTE: This function is called by timer interrupt work
+ */
+void mei_wd_timer(struct work_struct *work)
+{
+	unsigned long timeout;
+	struct mei_cl *cl_pos = NULL;
+	struct mei_cl *cl_next = NULL;
+	struct list_head *amthi_complete_list = NULL;
+	struct mei_cl_cb  *cb_pos = NULL;
+	struct mei_cl_cb  *cb_next = NULL;
+
+	struct mei_device *dev = container_of(work,
+					struct mei_device, wd_work.work);
+
+
+	mutex_lock(&dev->device_lock);
+	if (dev->mei_state != MEI_ENABLED) {
+		if (dev->mei_state == MEI_INIT_CLIENTS) {
+			if (dev->init_clients_timer) {
+				if (--dev->init_clients_timer == 0) {
+					dev_dbg(&dev->pdev->dev, "IMEI reset due to init clients timeout ,init clients state = %d.\n",
+						dev->init_clients_state);
+					mei_reset(dev, 1);
+				}
+			}
+		}
+		goto out;
+	}
+	/*** connect/disconnect timeouts ***/
+	list_for_each_entry_safe(cl_pos, cl_next, &dev->file_list, link) {
+		if (cl_pos->timer_count) {
+			if (--cl_pos->timer_count == 0) {
+				dev_dbg(&dev->pdev->dev, "HECI reset due to connect/disconnect timeout.\n");
+				mei_reset(dev, 1);
+				goto out;
+			}
+		}
+	}
+
+	if (dev->wd_cl.state != MEI_FILE_CONNECTED)
+		goto out;
+
+	/* Watchdog */
+	if (dev->wd_due_counter && !dev->wd_bypass) {
+		if (--dev->wd_due_counter == 0) {
+			if (dev->mei_host_buffer_is_empty &&
+			    mei_flow_ctrl_creds(dev, &dev->wd_cl) > 0) {
+				dev->mei_host_buffer_is_empty = 0;
+				dev_dbg(&dev->pdev->dev, "send watchdog.\n");
+
+				if (mei_wd_send(dev))
+					dev_dbg(&dev->pdev->dev, "wd send failed.\n");
+				else
+					if (mei_flow_ctrl_reduce(dev, &dev->wd_cl))
+						goto out;
+
+				if (dev->wd_timeout)
+					dev->wd_due_counter = 2;
+				else
+					dev->wd_due_counter = 0;
+
+			} else
+				dev->wd_pending = 1;
+
+		}
+	}
+	if (dev->iamthif_stall_timer) {
+		if (--dev->iamthif_stall_timer == 0) {
+			dev_dbg(&dev->pdev->dev, "reseting because of hang to amthi.\n");
+			mei_reset(dev, 1);
+			dev->iamthif_msg_buf_size = 0;
+			dev->iamthif_msg_buf_index = 0;
+			dev->iamthif_canceled = 0;
+			dev->iamthif_ioctl = 1;
+			dev->iamthif_state = MEI_IAMTHIF_IDLE;
+			dev->iamthif_timer = 0;
+
+			if (dev->iamthif_current_cb)
+				mei_free_cb_private(dev->iamthif_current_cb);
+
+			dev->iamthif_file_object = NULL;
+			dev->iamthif_current_cb = NULL;
+			run_next_iamthif_cmd(dev);
+		}
+	}
+
+	if (dev->iamthif_timer) {
+
+		timeout = dev->iamthif_timer +
+				msecs_to_jiffies(IAMTHIF_READ_TIMER);
+
+		dev_dbg(&dev->pdev->dev, "dev->iamthif_timer = %ld\n",
+				dev->iamthif_timer);
+		dev_dbg(&dev->pdev->dev, "timeout = %ld\n", timeout);
+		dev_dbg(&dev->pdev->dev, "jiffies = %ld\n", jiffies);
+		if (time_after(jiffies, timeout)) {
+			/*
+			 * User didn't read the AMTHI data on time (15sec)
+			 * freeing AMTHI for other requests
+			 */
+
+			dev_dbg(&dev->pdev->dev, "freeing AMTHI for other requests\n");
+
+			amthi_complete_list = &dev->amthi_read_complete_list.
+					mei_cb.cb_list;
+
+			if (!list_empty(amthi_complete_list)) {
+
+				list_for_each_entry_safe(cb_pos, cb_next,
+							amthi_complete_list,
+							cb_list) {
+
+					cl_pos = cb_pos->file_object->private_data;
+
+					/* Finding the AMTHI entry. */
+					if (cl_pos ==	&dev->iamthif_cl)
+						list_del(&cb_pos->cb_list);
+				}
+			}
+			if (dev->iamthif_current_cb)
+				mei_free_cb_private(dev->iamthif_current_cb);
+
+			dev->iamthif_file_object->private_data = NULL;
+			dev->iamthif_file_object = NULL;
+			dev->iamthif_current_cb = NULL;
+			dev->iamthif_timer = 0;
+			run_next_iamthif_cmd(dev);
+
+		}
+	}
+out:
+	 schedule_delayed_work(&dev->wd_work, 2 * HZ);
+	 mutex_unlock(&dev->device_lock);
+}
+
+/**
+ *  mei_interrupt_thread_handler - function called after ISR to handle the interrupt
+ * processing.
+ *
+ * @irq: The irq number
+ * @dev_id: pointer to the device structure
+ *
+ * returns irqreturn_t
+ *
+ */
+irqreturn_t mei_interrupt_thread_handler(int irq, void *dev_id)
+{
+	struct mei_device *dev = (struct mei_device *) dev_id;
+	struct mei_io_list complete_list;
+	struct mei_cl_cb *cb_pos = NULL, *cb_next = NULL;
+	struct mei_cl *cl;
+	s32 slots;
+	int rets;
+	bool  bus_message_received;
+
+
+	dev_dbg(&dev->pdev->dev, "function called after ISR to handle the interrupt processing.\n");
+	/* initialize our complete list */
+	mutex_lock(&dev->device_lock);
+	mei_initialize_list(&complete_list, dev);
+	dev->host_hw_state = mei_hcsr_read(dev);
+	dev->me_hw_state = mei_mecsr_read(dev);
+
+	/* check if ME wants a reset */
+	if ((dev->me_hw_state & ME_RDY_HRA) == 0 &&
+	    dev->mei_state != MEI_RESETING &&
+	    dev->mei_state != MEI_INITIALIZING) {
+		dev_dbg(&dev->pdev->dev, "FW not ready.\n");
+		mei_reset(dev, 1);
+		mutex_unlock(&dev->device_lock);
+		return IRQ_HANDLED;
+	}
+
+	/*  check if we need to start the dev */
+	if ((dev->host_hw_state & H_RDY) == 0) {
+		if ((dev->me_hw_state & ME_RDY_HRA) == ME_RDY_HRA) {
+			dev_dbg(&dev->pdev->dev, "we need to start the dev.\n");
+			dev->host_hw_state |= (H_IE | H_IG | H_RDY);
+			mei_hcsr_set(dev);
+			dev->mei_state = MEI_INIT_CLIENTS;
+			dev_dbg(&dev->pdev->dev, "link is established start sending messages.\n");
+			/* link is established
+			 * start sending messages.
+			 */
+			host_start_message(dev);
+			mutex_unlock(&dev->device_lock);
+			return IRQ_HANDLED;
+		} else {
+			dev_dbg(&dev->pdev->dev, "FW not ready.\n");
+			mutex_unlock(&dev->device_lock);
+			return IRQ_HANDLED;
+		}
+	}
+	/* check slots avalable for reading */
+	slots = mei_count_full_read_slots(dev);
+	dev_dbg(&dev->pdev->dev, "slots =%08x  extra_write_index =%08x.\n",
+		slots, dev->extra_write_index);
+	while (slots > 0 && !dev->extra_write_index) {
+		dev_dbg(&dev->pdev->dev, "slots =%08x  extra_write_index =%08x.\n",
+				slots, dev->extra_write_index);
+		dev_dbg(&dev->pdev->dev, "call mei_irq_thread_read_handler.\n");
+		rets = mei_irq_thread_read_handler(&complete_list, dev, &slots);
+		if (rets)
+			goto end;
+	}
+	rets = mei_irq_thread_write_handler(&complete_list, dev, &slots);
+end:
+	dev_dbg(&dev->pdev->dev, "end of bottom half function.\n");
+	dev->host_hw_state = mei_hcsr_read(dev);
+	dev->mei_host_buffer_is_empty = mei_host_buffer_is_empty(dev);
+
+	bus_message_received = false;
+	if (dev->recvd_msg && waitqueue_active(&dev->wait_recvd_msg)) {
+		dev_dbg(&dev->pdev->dev, "received waiting bus message\n");
+		bus_message_received = true;
+	}
+	mutex_unlock(&dev->device_lock);
+	if (bus_message_received) {
+		dev_dbg(&dev->pdev->dev, "wake up dev->wait_recvd_msg\n");
+		wake_up_interruptible(&dev->wait_recvd_msg);
+		bus_message_received = false;
+	}
+	if (complete_list.status || list_empty(&complete_list.mei_cb.cb_list))
+		return IRQ_HANDLED;
+
+
+	list_for_each_entry_safe(cb_pos, cb_next,
+			&complete_list.mei_cb.cb_list, cb_list) {
+		cl = (struct mei_cl *)cb_pos->file_private;
+		list_del(&cb_pos->cb_list);
+		if (cl) {
+			if (cl != &dev->iamthif_cl) {
+				dev_dbg(&dev->pdev->dev, "completing call back.\n");
+				_mei_cmpl(cl, cb_pos);
+				cb_pos = NULL;
+			} else if (cl == &dev->iamthif_cl) {
+				_mei_cmpl_iamthif(dev, cb_pos);
+			}
+		}
+	}
+	return IRQ_HANDLED;
+}
diff -druN linux-2.6.39-libre/drivers/staging/mei/iorw.c linux-3.0-rc7-libre/drivers/staging/mei/iorw.c
--- linux-2.6.39-libre/drivers/staging/mei/iorw.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/staging/mei/iorw.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,604 @@
+/*
+ *
+ * Intel Management Engine Interface (Intel MEI) Linux driver
+ * Copyright (c) 2003-2011, Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ */
+
+
+#include <linux/kernel.h>
+#include <linux/fs.h>
+#include <linux/errno.h>
+#include <linux/types.h>
+#include <linux/fcntl.h>
+#include <linux/aio.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+#include <linux/ioctl.h>
+#include <linux/cdev.h>
+#include <linux/list.h>
+#include <linux/delay.h>
+#include <linux/sched.h>
+#include <linux/uuid.h>
+#include <linux/jiffies.h>
+#include <linux/uaccess.h>
+
+
+#include "mei_dev.h"
+#include "hw.h"
+#include "mei.h"
+#include "interface.h"
+#include "mei_version.h"
+
+
+
+/**
+ * mei_ioctl_connect_client - the connect to fw client IOCTL function
+ *
+ * @dev: the device structure
+ * @data: IOCTL connect data, input and output parameters
+ * @file: private data of the file object
+ *
+ * Locking: called under "dev->device_lock" lock
+ *
+ * returns 0 on success, <0 on failure.
+ */
+int mei_ioctl_connect_client(struct file *file,
+			struct mei_connect_client_data *data)
+{
+	struct mei_device *dev;
+	struct mei_cl_cb *cb;
+	struct mei_client *client;
+	struct mei_cl *cl;
+	struct mei_cl *cl_pos = NULL;
+	struct mei_cl *cl_next = NULL;
+	long timeout = CONNECT_TIMEOUT;
+	int i;
+	int err;
+	int rets;
+
+	cl = file->private_data;
+	if (WARN_ON(!cl || !cl->dev))
+		return -ENODEV;
+
+	dev = cl->dev;
+
+	dev_dbg(&dev->pdev->dev, "mei_ioctl_connect_client() Entry\n");
+
+
+	/* buffered ioctl cb */
+	cb = kzalloc(sizeof(struct mei_cl_cb), GFP_KERNEL);
+	if (!cb) {
+		rets = -ENOMEM;
+		goto end;
+	}
+	INIT_LIST_HEAD(&cb->cb_list);
+
+	cb->major_file_operations = MEI_IOCTL;
+
+	if (dev->mei_state != MEI_ENABLED) {
+		rets = -ENODEV;
+		goto end;
+	}
+	if (cl->state != MEI_FILE_INITIALIZING &&
+	    cl->state != MEI_FILE_DISCONNECTED) {
+		rets = -EBUSY;
+		goto end;
+	}
+
+	/* find ME client we're trying to connect to */
+	i = mei_find_me_client_index(dev, data->in_client_uuid);
+	if (i >= 0 && !dev->me_clients[i].props.fixed_address) {
+		cl->me_client_id = dev->me_clients[i].client_id;
+		cl->state = MEI_FILE_CONNECTING;
+	}
+
+	dev_dbg(&dev->pdev->dev, "Connect to FW Client ID = %d\n",
+			cl->me_client_id);
+	dev_dbg(&dev->pdev->dev, "FW Client - Protocol Version = %d\n",
+			dev->me_clients[i].props.protocol_version);
+	dev_dbg(&dev->pdev->dev, "FW Client - Max Msg Len = %d\n",
+			dev->me_clients[i].props.max_msg_length);
+
+	/* if we're connecting to amthi client so we will use the exist
+	 * connection
+	 */
+	if (uuid_le_cmp(data->in_client_uuid, mei_amthi_guid) == 0) {
+		dev_dbg(&dev->pdev->dev, "FW Client is amthi\n");
+		if (dev->iamthif_cl.state != MEI_FILE_CONNECTED) {
+			rets = -ENODEV;
+			goto end;
+		}
+		clear_bit(cl->host_client_id, dev->host_clients_map);
+		list_for_each_entry_safe(cl_pos, cl_next,
+					 &dev->file_list, link) {
+			if (mei_fe_same_id(cl, cl_pos)) {
+				dev_dbg(&dev->pdev->dev,
+					"remove file private data node host"
+				    " client = %d, ME client = %d.\n",
+				    cl_pos->host_client_id,
+				    cl_pos->me_client_id);
+				list_del(&cl_pos->link);
+			}
+
+		}
+		dev_dbg(&dev->pdev->dev, "free file private data memory.\n");
+		kfree(cl);
+
+		cl = NULL;
+		file->private_data = &dev->iamthif_cl;
+
+		client = &data->out_client_properties;
+		client->max_msg_length =
+			dev->me_clients[i].props.max_msg_length;
+		client->protocol_version =
+			dev->me_clients[i].props.protocol_version;
+		rets = dev->iamthif_cl.status;
+
+		goto end;
+	}
+
+	if (cl->state != MEI_FILE_CONNECTING) {
+		rets = -ENODEV;
+		goto end;
+	}
+
+
+	/* prepare the output buffer */
+	client = &data->out_client_properties;
+	client->max_msg_length = dev->me_clients[i].props.max_msg_length;
+	client->protocol_version = dev->me_clients[i].props.protocol_version;
+	dev_dbg(&dev->pdev->dev, "Can connect?\n");
+	if (dev->mei_host_buffer_is_empty
+	    && !mei_other_client_is_connecting(dev, cl)) {
+		dev_dbg(&dev->pdev->dev, "Sending Connect Message\n");
+		dev->mei_host_buffer_is_empty = 0;
+		if (!mei_connect(dev, cl)) {
+			dev_dbg(&dev->pdev->dev, "Sending connect message - failed\n");
+			rets = -ENODEV;
+			goto end;
+		} else {
+			dev_dbg(&dev->pdev->dev, "Sending connect message - succeeded\n");
+			cl->timer_count = MEI_CONNECT_TIMEOUT;
+			cb->file_private = cl;
+			list_add_tail(&cb->cb_list,
+				      &dev->ctrl_rd_list.mei_cb.
+				      cb_list);
+		}
+
+
+	} else {
+		dev_dbg(&dev->pdev->dev, "Queuing the connect request due to device busy\n");
+		cb->file_private = cl;
+		dev_dbg(&dev->pdev->dev, "add connect cb to control write list.\n");
+		list_add_tail(&cb->cb_list,
+			      &dev->ctrl_wr_list.mei_cb.cb_list);
+	}
+	mutex_unlock(&dev->device_lock);
+	err = wait_event_timeout(dev->wait_recvd_msg,
+			(MEI_FILE_CONNECTED == cl->state ||
+			 MEI_FILE_DISCONNECTED == cl->state),
+			timeout * HZ);
+
+	mutex_lock(&dev->device_lock);
+	if (MEI_FILE_CONNECTED == cl->state) {
+		dev_dbg(&dev->pdev->dev, "successfully connected to FW client.\n");
+		rets = cl->status;
+		goto end;
+	} else {
+		dev_dbg(&dev->pdev->dev, "failed to connect to FW client.cl->state = %d.\n",
+		    cl->state);
+		if (!err) {
+			dev_dbg(&dev->pdev->dev,
+				"wait_event_interruptible_timeout failed on client"
+				" connect message fw response message.\n");
+		}
+		rets = -EFAULT;
+
+		mei_flush_list(&dev->ctrl_rd_list, cl);
+		mei_flush_list(&dev->ctrl_wr_list, cl);
+		goto end;
+	}
+	rets = 0;
+end:
+	dev_dbg(&dev->pdev->dev, "free connect cb memory.");
+	kfree(cb);
+	return rets;
+}
+
+/**
+ * find_amthi_read_list_entry - finds a amthilist entry for current file
+ *
+ * @dev: the device structure
+ * @file: pointer to file object
+ *
+ * returns   returned a list entry on success, NULL on failure.
+ */
+struct mei_cl_cb *find_amthi_read_list_entry(
+		struct mei_device *dev,
+		struct file *file)
+{
+	struct mei_cl *cl_temp;
+	struct mei_cl_cb *cb_pos = NULL;
+	struct mei_cl_cb *cb_next = NULL;
+
+	if (!dev->amthi_read_complete_list.status &&
+	    !list_empty(&dev->amthi_read_complete_list.mei_cb.cb_list)) {
+		list_for_each_entry_safe(cb_pos, cb_next,
+		    &dev->amthi_read_complete_list.mei_cb.cb_list, cb_list) {
+			cl_temp = (struct mei_cl *)cb_pos->file_private;
+			if (cl_temp && cl_temp == &dev->iamthif_cl &&
+				cb_pos->file_object == file)
+				return cb_pos;
+		}
+	}
+	return NULL;
+}
+
+/**
+ * amthi_read - read data from AMTHI client
+ *
+ * @dev: the device structure
+ * @if_num:  minor number
+ * @file: pointer to file object
+ * @*ubuf: pointer to user data in user space
+ * @length: data length to read
+ * @offset: data read offset
+ *
+ * Locking: called under "dev->device_lock" lock
+ *
+ * returns
+ *  returned data length on success,
+ *  zero if no data to read,
+ *  negative on failure.
+ */
+int amthi_read(struct mei_device *dev, struct file *file,
+	      char __user *ubuf, size_t length, loff_t *offset)
+{
+	int rets;
+	int wait_ret;
+	struct mei_cl_cb *cb = NULL;
+	struct mei_cl *cl = file->private_data;
+	unsigned long timeout;
+	int i;
+
+	/* Only Posible if we are in timeout */
+	if (!cl || cl != &dev->iamthif_cl) {
+		dev_dbg(&dev->pdev->dev, "bad file ext.\n");
+		return -ETIMEDOUT;
+	}
+
+	for (i = 0; i < dev->num_mei_me_clients; i++) {
+		if (dev->me_clients[i].client_id ==
+		    dev->iamthif_cl.me_client_id)
+			break;
+	}
+
+	if (i == dev->num_mei_me_clients) {
+		dev_dbg(&dev->pdev->dev, "amthi client not found.\n");
+		return -ENODEV;
+	}
+	if (WARN_ON(dev->me_clients[i].client_id != cl->me_client_id))
+		return -ENODEV;
+
+	dev_dbg(&dev->pdev->dev, "checking amthi data\n");
+	cb = find_amthi_read_list_entry(dev, file);
+
+	/* Check for if we can block or not*/
+	if (cb == NULL && file->f_flags & O_NONBLOCK)
+		return -EAGAIN;
+
+
+	dev_dbg(&dev->pdev->dev, "waiting for amthi data\n");
+	while (cb == NULL) {
+		/* unlock the Mutex */
+		mutex_unlock(&dev->device_lock);
+
+		wait_ret = wait_event_interruptible(dev->iamthif_cl.wait,
+			(cb = find_amthi_read_list_entry(dev, file)));
+
+		if (wait_ret)
+			return -ERESTARTSYS;
+
+		dev_dbg(&dev->pdev->dev, "woke up from sleep\n");
+
+		/* Locking again the Mutex */
+		mutex_lock(&dev->device_lock);
+	}
+
+
+	dev_dbg(&dev->pdev->dev, "Got amthi data\n");
+	dev->iamthif_timer = 0;
+
+	if (cb) {
+		timeout = cb->read_time +
+					msecs_to_jiffies(IAMTHIF_READ_TIMER);
+		dev_dbg(&dev->pdev->dev, "amthi timeout = %lud\n",
+				timeout);
+
+		if  (time_after(jiffies, timeout)) {
+			dev_dbg(&dev->pdev->dev, "amthi Time out\n");
+			/* 15 sec for the message has expired */
+			list_del(&cb->cb_list);
+			rets = -ETIMEDOUT;
+			goto free;
+		}
+	}
+	/* if the whole message will fit remove it from the list */
+	if (cb->information >= *offset &&
+	    length >= (cb->information - *offset))
+		list_del(&cb->cb_list);
+	else if (cb->information > 0 && cb->information <= *offset) {
+		/* end of the message has been reached */
+		list_del(&cb->cb_list);
+		rets = 0;
+		goto free;
+	}
+		/* else means that not full buffer will be read and do not
+		 * remove message from deletion list
+		 */
+
+	dev_dbg(&dev->pdev->dev, "amthi cb->response_buffer size - %d\n",
+	    cb->response_buffer.size);
+	dev_dbg(&dev->pdev->dev, "amthi cb->information - %lu\n",
+	    cb->information);
+
+	/* length is being turncated to PAGE_SIZE, however,
+	 * the information may be longer */
+	length = min_t(size_t, length, (cb->information - *offset));
+
+	if (copy_to_user(ubuf,
+			 cb->response_buffer.data + *offset,
+			 length))
+		rets = -EFAULT;
+	else {
+		rets = length;
+		if ((*offset + length) < cb->information) {
+			*offset += length;
+			goto out;
+		}
+	}
+free:
+	dev_dbg(&dev->pdev->dev, "free amthi cb memory.\n");
+	*offset = 0;
+	mei_free_cb_private(cb);
+out:
+	return rets;
+}
+
+/**
+ * mei_start_read - the start read client message function.
+ *
+ * @dev: the device structure
+ * @if_num:  minor number
+ * @cl: private data of the file object
+ *
+ * returns 0 on success, <0 on failure.
+ */
+int mei_start_read(struct mei_device *dev, struct mei_cl *cl)
+{
+	struct mei_cl_cb *cb;
+	int rets = 0;
+	int i;
+
+	if (cl->state != MEI_FILE_CONNECTED)
+		return -ENODEV;
+
+	if (dev->mei_state != MEI_ENABLED)
+		return -ENODEV;
+
+	dev_dbg(&dev->pdev->dev, "check if read is pending.\n");
+	if (cl->read_pending || cl->read_cb) {
+		dev_dbg(&dev->pdev->dev, "read is pending.\n");
+		return -EBUSY;
+	}
+
+	cb = kzalloc(sizeof(struct mei_cl_cb), GFP_KERNEL);
+	if (!cb)
+		return -ENOMEM;
+
+	dev_dbg(&dev->pdev->dev, "allocation call back successful. host client = %d, ME client = %d\n",
+		cl->host_client_id, cl->me_client_id);
+
+	for (i = 0; i < dev->num_mei_me_clients; i++) {
+		if (dev->me_clients[i].client_id == cl->me_client_id)
+			break;
+
+	}
+
+	if (WARN_ON(dev->me_clients[i].client_id != cl->me_client_id)) {
+		rets = -ENODEV;
+		goto unlock;
+	}
+
+	if (i == dev->num_mei_me_clients) {
+		rets = -ENODEV;
+		goto unlock;
+	}
+
+	cb->response_buffer.size = dev->me_clients[i].props.max_msg_length;
+	cb->response_buffer.data =
+	    kmalloc(cb->response_buffer.size, GFP_KERNEL);
+	if (!cb->response_buffer.data) {
+		rets = -ENOMEM;
+		goto unlock;
+	}
+	dev_dbg(&dev->pdev->dev, "allocation call back data success.\n");
+	cb->major_file_operations = MEI_READ;
+	/* make sure information is zero before we start */
+	cb->information = 0;
+	cb->file_private = (void *) cl;
+	cl->read_cb = cb;
+	if (dev->mei_host_buffer_is_empty) {
+		dev->mei_host_buffer_is_empty = 0;
+		if (!mei_send_flow_control(dev, cl)) {
+			rets = -ENODEV;
+			goto unlock;
+		} else {
+			list_add_tail(&cb->cb_list,
+				      &dev->read_list.mei_cb.cb_list);
+		}
+	} else {
+		list_add_tail(&cb->cb_list,
+			      &dev->ctrl_wr_list.mei_cb.cb_list);
+	}
+	return rets;
+unlock:
+	mei_free_cb_private(cb);
+	return rets;
+}
+
+/**
+ * amthi_write - write iamthif data to amthi client
+ *
+ * @dev: the device structure
+ * @cb: mei call back struct
+ *
+ * returns 0 on success, <0 on failure.
+ */
+int amthi_write(struct mei_device *dev, struct mei_cl_cb *cb)
+{
+	struct mei_msg_hdr mei_hdr;
+	int ret;
+
+	if (!dev || !cb)
+		return -ENODEV;
+
+	dev_dbg(&dev->pdev->dev, "write data to amthi client.\n");
+
+	dev->iamthif_state = MEI_IAMTHIF_WRITING;
+	dev->iamthif_current_cb = cb;
+	dev->iamthif_file_object = cb->file_object;
+	dev->iamthif_canceled = 0;
+	dev->iamthif_ioctl = 1;
+	dev->iamthif_msg_buf_size = cb->request_buffer.size;
+	memcpy(dev->iamthif_msg_buf, cb->request_buffer.data,
+	    cb->request_buffer.size);
+
+	ret = mei_flow_ctrl_creds(dev, &dev->iamthif_cl);
+	if (ret < 0)
+		return ret;
+
+	if (ret && dev->mei_host_buffer_is_empty) {
+		ret = 0;
+		dev->mei_host_buffer_is_empty = 0;
+		if (cb->request_buffer.size >
+			(((dev->host_hw_state & H_CBD) >> 24) * sizeof(u32))
+				-sizeof(struct mei_msg_hdr)) {
+			mei_hdr.length =
+			    (((dev->host_hw_state & H_CBD) >> 24) *
+			    sizeof(u32)) - sizeof(struct mei_msg_hdr);
+			mei_hdr.msg_complete = 0;
+		} else {
+			mei_hdr.length = cb->request_buffer.size;
+			mei_hdr.msg_complete = 1;
+		}
+
+		mei_hdr.host_addr = dev->iamthif_cl.host_client_id;
+		mei_hdr.me_addr = dev->iamthif_cl.me_client_id;
+		mei_hdr.reserved = 0;
+		dev->iamthif_msg_buf_index += mei_hdr.length;
+		if (!mei_write_message(dev, &mei_hdr,
+					(unsigned char *)(dev->iamthif_msg_buf),
+					mei_hdr.length))
+			return -ENODEV;
+
+		if (mei_hdr.msg_complete) {
+			if (mei_flow_ctrl_reduce(dev, &dev->iamthif_cl))
+				return -ENODEV;
+			dev->iamthif_flow_control_pending = 1;
+			dev->iamthif_state = MEI_IAMTHIF_FLOW_CONTROL;
+			dev_dbg(&dev->pdev->dev, "add amthi cb to write waiting list\n");
+			dev->iamthif_current_cb = cb;
+			dev->iamthif_file_object = cb->file_object;
+			list_add_tail(&cb->cb_list,
+				      &dev->write_waiting_list.mei_cb.cb_list);
+		} else {
+			dev_dbg(&dev->pdev->dev, "message does not complete, "
+					"so add amthi cb to write list.\n");
+			list_add_tail(&cb->cb_list,
+				      &dev->write_list.mei_cb.cb_list);
+		}
+	} else {
+		if (!(dev->mei_host_buffer_is_empty))
+			dev_dbg(&dev->pdev->dev, "host buffer is not empty");
+
+		dev_dbg(&dev->pdev->dev, "No flow control credentials, "
+				"so add iamthif cb to write list.\n");
+		list_add_tail(&cb->cb_list,
+			      &dev->write_list.mei_cb.cb_list);
+	}
+	return 0;
+}
+
+/**
+ * iamthif_ioctl_send_msg - send cmd data to amthi client
+ *
+ * @dev: the device structure
+ *
+ * returns 0 on success, <0 on failure.
+ */
+void run_next_iamthif_cmd(struct mei_device *dev)
+{
+	struct mei_cl *cl_tmp;
+	struct mei_cl_cb *cb_pos = NULL;
+	struct mei_cl_cb *cb_next = NULL;
+	int status;
+
+	if (!dev)
+		return;
+
+	dev->iamthif_msg_buf_size = 0;
+	dev->iamthif_msg_buf_index = 0;
+	dev->iamthif_canceled = 0;
+	dev->iamthif_ioctl = 1;
+	dev->iamthif_state = MEI_IAMTHIF_IDLE;
+	dev->iamthif_timer = 0;
+	dev->iamthif_file_object = NULL;
+
+	if (dev->amthi_cmd_list.status == 0 &&
+	    !list_empty(&dev->amthi_cmd_list.mei_cb.cb_list)) {
+		dev_dbg(&dev->pdev->dev, "complete amthi cmd_list cb.\n");
+
+		list_for_each_entry_safe(cb_pos, cb_next,
+		    &dev->amthi_cmd_list.mei_cb.cb_list, cb_list) {
+			list_del(&cb_pos->cb_list);
+			cl_tmp = (struct mei_cl *)cb_pos->file_private;
+
+			if (cl_tmp && cl_tmp == &dev->iamthif_cl) {
+				status = amthi_write(dev, cb_pos);
+				if (status) {
+					dev_dbg(&dev->pdev->dev,
+						"amthi write failed status = %d\n",
+							status);
+					return;
+				}
+				break;
+			}
+		}
+	}
+}
+
+/**
+ * mei_free_cb_private - free mei_cb_private related memory
+ *
+ * @cb: mei callback struct
+ */
+void mei_free_cb_private(struct mei_cl_cb *cb)
+{
+	if (cb == NULL)
+		return;
+
+	kfree(cb->request_buffer.data);
+	kfree(cb->response_buffer.data);
+	kfree(cb);
+}
diff -druN linux-2.6.39-libre/drivers/staging/mei/Kconfig linux-3.0-rc7-libre/drivers/staging/mei/Kconfig
--- linux-2.6.39-libre/drivers/staging/mei/Kconfig	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/staging/mei/Kconfig	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,28 @@
+config INTEL_MEI
+	tristate "Intel Management Engine Interface (Intel MEI)"
+	depends on X86 && PCI && EXPERIMENTAL
+	help
+	  The Intel Management Engine (Intel ME) provides Manageability,
+	  Security and Media services for system containing Intel chipsets.
+	  if selected /dev/mei misc device will be created.
+
+	  Supported Chipsets are:
+	  7 Series Chipset Family
+	  6 Series Chipset Family
+	  5 Series Chipset Family
+	  4 Series Chipset Family
+	  Mobile 4 Series Chipset Family
+	  ICH9
+	  82946GZ/GL
+	  82G35 Express
+	  82Q963/Q965
+	  82P965/G965
+	  Mobile PM965/GM965
+	  Mobile GME965/GLE960
+	  82Q35 Express
+	  82G33/G31/P35/P31 Express
+	  82Q33 Express
+	  82X38/X48 Express
+
+	  For more information see
+	  <http://software.intel.com/en-us/manageability/>
diff -druN linux-2.6.39-libre/drivers/staging/mei/main.c linux-3.0-rc7-libre/drivers/staging/mei/main.c
--- linux-2.6.39-libre/drivers/staging/mei/main.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/staging/mei/main.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,1349 @@
+/*
+ *
+ * Intel Management Engine Interface (Intel MEI) Linux driver
+ * Copyright (c) 2003-2011, Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ */
+
+
+
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/kernel.h>
+#include <linux/device.h>
+#include <linux/fs.h>
+#include <linux/errno.h>
+#include <linux/types.h>
+#include <linux/fcntl.h>
+#include <linux/aio.h>
+#include <linux/pci.h>
+#include <linux/poll.h>
+#include <linux/init.h>
+#include <linux/ioctl.h>
+#include <linux/cdev.h>
+#include <linux/version.h>
+#include <linux/sched.h>
+#include <linux/uuid.h>
+#include <linux/compat.h>
+#include <linux/jiffies.h>
+#include <linux/interrupt.h>
+
+#include "mei_dev.h"
+#include "mei.h"
+#include "interface.h"
+#include "mei_version.h"
+
+
+#define MEI_READ_TIMEOUT 45
+#define MEI_DRIVER_NAME	"mei"
+#define MEI_DEV_NAME "mei"
+
+/*
+ *  mei driver strings
+ */
+static char mei_driver_name[] = MEI_DRIVER_NAME;
+static const char mei_driver_string[] = "Intel(R) Management Engine Interface";
+static const char mei_driver_version[] = MEI_DRIVER_VERSION;
+
+/* mei char device for registration */
+static struct cdev mei_cdev;
+
+/* major number for device */
+static int mei_major;
+/* The device pointer */
+/* Currently this driver works as long as there is only a single AMT device. */
+static struct pci_dev *mei_device;
+
+static struct class *mei_class;
+
+
+/* mei_pci_tbl - PCI Device ID Table */
+static DEFINE_PCI_DEVICE_TABLE(mei_pci_tbl) = {
+	{PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_82946GZ)},
+	{PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_82G35)},
+	{PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_82Q965)},
+	{PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_82G965)},
+	{PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_82GM965)},
+	{PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_82GME965)},
+	{PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_ICH9_82Q35)},
+	{PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_ICH9_82G33)},
+	{PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_ICH9_82Q33)},
+	{PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_ICH9_82X38)},
+	{PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_ICH9_3200)},
+	{PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_ICH9_6)},
+	{PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_ICH9_7)},
+	{PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_ICH9_8)},
+	{PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_ICH9_9)},
+	{PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_ICH9_10)},
+	{PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_ICH9M_1)},
+	{PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_ICH9M_2)},
+	{PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_ICH9M_3)},
+	{PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_ICH9M_4)},
+	{PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_ICH10_1)},
+	{PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_ICH10_2)},
+	{PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_ICH10_3)},
+	{PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_ICH10_4)},
+	{PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_IBXPK_1)},
+	{PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_IBXPK_2)},
+	{PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_CPT_1)},
+	{PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_PBG_1)},
+	{PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_PPT_1)},
+	{PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_PPT_2)},
+	{PCI_DEVICE(PCI_VENDOR_ID_INTEL, MEI_DEV_ID_PPT_3)},
+
+	/* required last entry */
+	{0, }
+};
+
+MODULE_DEVICE_TABLE(pci, mei_pci_tbl);
+
+static DEFINE_MUTEX(mei_mutex);
+
+/**
+ * mei_probe - Device Initialization Routine
+ *
+ * @pdev: PCI device structure
+ * @ent: entry in kcs_pci_tbl
+ *
+ * returns 0 on success, <0 on failure.
+ */
+static int __devinit mei_probe(struct pci_dev *pdev,
+				const struct pci_device_id *ent)
+{
+	struct mei_device *dev;
+	int err;
+
+	mutex_lock(&mei_mutex);
+	if (mei_device) {
+		err = -EEXIST;
+		goto end;
+	}
+	/* enable pci dev */
+	err = pci_enable_device(pdev);
+	if (err) {
+		printk(KERN_ERR "mei: Failed to enable pci device.\n");
+		goto end;
+	}
+	/* set PCI host mastering  */
+	pci_set_master(pdev);
+	/* pci request regions for mei driver */
+	err = pci_request_regions(pdev, mei_driver_name);
+	if (err) {
+		printk(KERN_ERR "mei: Failed to get pci regions.\n");
+		goto disable_device;
+	}
+	/* allocates and initializes the mei dev structure */
+	dev = init_mei_device(pdev);
+	if (!dev) {
+		err = -ENOMEM;
+		goto release_regions;
+	}
+	/* mapping  IO device memory */
+	dev->mem_addr = pci_iomap(pdev, 0, 0);
+	if (!dev->mem_addr) {
+		printk(KERN_ERR "mei: mapping I/O device memory failure.\n");
+		err = -ENOMEM;
+		goto free_device;
+	}
+	/* request and enable interrupt   */
+	err = request_threaded_irq(pdev->irq,
+			mei_interrupt_quick_handler,
+			mei_interrupt_thread_handler,
+			IRQF_SHARED, mei_driver_name, dev);
+	if (err) {
+		printk(KERN_ERR "mei: request_threaded_irq failure. irq = %d\n",
+		       pdev->irq);
+		goto unmap_memory;
+	}
+	INIT_DELAYED_WORK(&dev->wd_work, mei_wd_timer);
+	if (mei_hw_init(dev)) {
+		printk(KERN_ERR "mei: Init hw failure.\n");
+		err = -ENODEV;
+		goto release_irq;
+	}
+	mei_device = pdev;
+	pci_set_drvdata(pdev, dev);
+	schedule_delayed_work(&dev->wd_work, HZ);
+
+	mutex_unlock(&mei_mutex);
+
+	pr_debug("mei: Driver initialization successful.\n");
+
+	return 0;
+
+release_irq:
+	/* disable interrupts */
+	dev->host_hw_state = mei_hcsr_read(dev);
+	mei_disable_interrupts(dev);
+	flush_scheduled_work();
+	free_irq(pdev->irq, dev);
+unmap_memory:
+	pci_iounmap(pdev, dev->mem_addr);
+free_device:
+	kfree(dev);
+release_regions:
+	pci_release_regions(pdev);
+disable_device:
+	pci_disable_device(pdev);
+end:
+	mutex_unlock(&mei_mutex);
+	printk(KERN_ERR "mei: Driver initialization failed.\n");
+	return err;
+}
+
+/**
+ * mei_remove - Device Removal Routine
+ *
+ * @pdev: PCI device structure
+ *
+ * mei_remove is called by the PCI subsystem to alert the driver
+ * that it should release a PCI device.
+ */
+static void __devexit mei_remove(struct pci_dev *pdev)
+{
+	struct mei_device *dev;
+
+	if (mei_device != pdev)
+		return;
+
+	dev = pci_get_drvdata(pdev);
+	if (!dev)
+		return;
+
+	mutex_lock(&dev->device_lock);
+
+	mei_wd_stop(dev, false);
+
+	mei_device = NULL;
+
+	if (dev->iamthif_cl.state == MEI_FILE_CONNECTED) {
+		dev->iamthif_cl.state = MEI_FILE_DISCONNECTING;
+		mei_disconnect_host_client(dev, &dev->iamthif_cl);
+	}
+	if (dev->wd_cl.state == MEI_FILE_CONNECTED) {
+		dev->wd_cl.state = MEI_FILE_DISCONNECTING;
+		mei_disconnect_host_client(dev, &dev->wd_cl);
+	}
+
+	/* remove entry if already in list */
+	dev_dbg(&pdev->dev, "list del iamthif and wd file list.\n");
+	mei_remove_client_from_file_list(dev, dev->wd_cl.host_client_id);
+	mei_remove_client_from_file_list(dev, dev->iamthif_cl.host_client_id);
+
+	dev->iamthif_current_cb = NULL;
+	dev->num_mei_me_clients = 0;
+
+	mutex_unlock(&dev->device_lock);
+
+	flush_scheduled_work();
+
+	/* disable interrupts */
+	mei_disable_interrupts(dev);
+
+	free_irq(pdev->irq, dev);
+	pci_set_drvdata(pdev, NULL);
+
+	if (dev->mem_addr)
+		pci_iounmap(pdev, dev->mem_addr);
+
+	kfree(dev);
+
+	pci_release_regions(pdev);
+	pci_disable_device(pdev);
+}
+
+/**
+ * mei_clear_list - removes all callbacks associated with file
+ *		from mei_cb_list
+ *
+ * @dev: device structure.
+ * @file: file structure
+ * @mei_cb_list: callbacks list
+ *
+ * mei_clear_list is called to clear resources associated with file
+ * when application calls close function or Ctrl-C was pressed
+ *
+ * returns true if callback removed from the list, false otherwise
+ */
+static bool mei_clear_list(struct mei_device *dev,
+		struct file *file, struct list_head *mei_cb_list)
+{
+	struct mei_cl_cb *cb_pos = NULL;
+	struct mei_cl_cb *cb_next = NULL;
+	struct file *file_temp;
+	bool removed = false;
+
+	/* list all list member */
+	list_for_each_entry_safe(cb_pos, cb_next, mei_cb_list, cb_list) {
+		file_temp = (struct file *)cb_pos->file_object;
+		/* check if list member associated with a file */
+		if (file_temp == file) {
+			/* remove member from the list */
+			list_del(&cb_pos->cb_list);
+			/* check if cb equal to current iamthif cb */
+			if (dev->iamthif_current_cb == cb_pos) {
+				dev->iamthif_current_cb = NULL;
+				/* send flow control to iamthif client */
+				mei_send_flow_control(dev, &dev->iamthif_cl);
+			}
+			/* free all allocated buffers */
+			mei_free_cb_private(cb_pos);
+			cb_pos = NULL;
+			removed = true;
+		}
+	}
+	return removed;
+}
+
+/**
+ * mei_clear_lists - removes all callbacks associated with file
+ *
+ * @dev: device structure
+ * @file: file structure
+ *
+ * mei_clear_lists is called to clear resources associated with file
+ * when application calls close function or Ctrl-C was pressed
+ *
+ * returns true if callback removed from the list, false otherwise
+ */
+static bool mei_clear_lists(struct mei_device *dev, struct file *file)
+{
+	bool removed = false;
+
+	/* remove callbacks associated with a file */
+	mei_clear_list(dev, file, &dev->amthi_cmd_list.mei_cb.cb_list);
+	if (mei_clear_list(dev, file,
+			    &dev->amthi_read_complete_list.mei_cb.cb_list))
+		removed = true;
+
+	mei_clear_list(dev, file, &dev->ctrl_rd_list.mei_cb.cb_list);
+
+	if (mei_clear_list(dev, file, &dev->ctrl_wr_list.mei_cb.cb_list))
+		removed = true;
+
+	if (mei_clear_list(dev, file, &dev->write_waiting_list.mei_cb.cb_list))
+		removed = true;
+
+	if (mei_clear_list(dev, file, &dev->write_list.mei_cb.cb_list))
+		removed = true;
+
+	/* check if iamthif_current_cb not NULL */
+	if (dev->iamthif_current_cb && !removed) {
+		/* check file and iamthif current cb association */
+		if (dev->iamthif_current_cb->file_object == file) {
+			/* remove cb */
+			mei_free_cb_private(dev->iamthif_current_cb);
+			dev->iamthif_current_cb = NULL;
+			removed = true;
+		}
+	}
+	return removed;
+}
+/**
+ * find_read_list_entry - find read list entry
+ *
+ * @dev: device structure
+ * @file: pointer to file structure
+ *
+ * returns cb on success, NULL on error
+ */
+static struct mei_cl_cb *find_read_list_entry(
+		struct mei_device *dev,
+		struct mei_cl *cl)
+{
+	struct mei_cl_cb *cb_pos = NULL;
+	struct mei_cl_cb *cb_next = NULL;
+	struct mei_cl *cl_list_temp;
+
+	if (!dev->read_list.status &&
+	    !list_empty(&dev->read_list.mei_cb.cb_list)) {
+
+		dev_dbg(&dev->pdev->dev, "remove read_list CB\n");
+		list_for_each_entry_safe(cb_pos, cb_next,
+				&dev->read_list.mei_cb.cb_list, cb_list) {
+
+			cl_list_temp = (struct mei_cl *)
+				cb_pos->file_private;
+
+			if (cl_list_temp &&
+			    mei_fe_same_id(cl, cl_list_temp))
+				return cb_pos;
+
+		}
+	}
+	return NULL;
+}
+
+/**
+ * mei_open - the open function
+ *
+ * @inode: pointer to inode structure
+ * @file: pointer to file structure
+ *
+ * returns 0 on success, <0 on error
+ */
+static int mei_open(struct inode *inode, struct file *file)
+{
+	struct mei_cl *cl;
+	int if_num = iminor(inode), err;
+	struct mei_device *dev;
+
+	err = -ENODEV;
+	if (!mei_device)
+		goto out;
+
+	dev = pci_get_drvdata(mei_device);
+	if (if_num != MEI_MINOR_NUMBER || !dev)
+		goto out;
+
+	mutex_lock(&dev->device_lock);
+	err = -ENOMEM;
+	cl = mei_alloc_file_private(dev);
+	if (!cl)
+		goto out;
+
+	err = -ENODEV;
+	if (dev->mei_state != MEI_ENABLED) {
+		dev_dbg(&dev->pdev->dev, "mei_state != MEI_ENABLED  mei_state= %d\n",
+		    dev->mei_state);
+		goto out_unlock;
+	}
+	err = -EMFILE;
+	if (dev->open_handle_count >= MEI_MAX_OPEN_HANDLE_COUNT)
+		goto out_unlock;
+
+	cl->host_client_id = find_first_zero_bit(dev->host_clients_map,
+							MEI_CLIENTS_MAX);
+	if (cl->host_client_id > MEI_CLIENTS_MAX)
+		goto out_unlock;
+
+	dev_dbg(&dev->pdev->dev, "client_id = %d\n", cl->host_client_id);
+
+	dev->open_handle_count++;
+	list_add_tail(&cl->link, &dev->file_list);
+
+	set_bit(cl->host_client_id, dev->host_clients_map);
+	cl->state = MEI_FILE_INITIALIZING;
+	cl->sm_state = 0;
+
+	file->private_data = cl;
+	mutex_unlock(&dev->device_lock);
+
+	return 0;
+
+out_unlock:
+	mutex_unlock(&dev->device_lock);
+	kfree(cl);
+out:
+	return err;
+}
+
+/**
+ * mei_release - the release function
+ *
+ * @inode: pointer to inode structure
+ * @file: pointer to file structure
+ *
+ * returns 0 on success, <0 on error
+ */
+static int mei_release(struct inode *inode, struct file *file)
+{
+	struct mei_cl *cl = file->private_data;
+	struct mei_cl_cb *cb;
+	struct mei_device *dev;
+	int rets = 0;
+
+	if (WARN_ON(!cl || !cl->dev))
+		return -ENODEV;
+
+	dev = cl->dev;
+
+	mutex_lock(&dev->device_lock);
+	if (cl != &dev->iamthif_cl) {
+		if (cl->state == MEI_FILE_CONNECTED) {
+			cl->state = MEI_FILE_DISCONNECTING;
+			dev_dbg(&dev->pdev->dev,
+				"disconnecting client host client = %d, "
+			    "ME client = %d\n",
+			    cl->host_client_id,
+			    cl->me_client_id);
+			rets = mei_disconnect_host_client(dev, cl);
+		}
+		mei_flush_queues(dev, cl);
+		dev_dbg(&dev->pdev->dev, "remove client host client = %d, ME client = %d\n",
+		    cl->host_client_id,
+		    cl->me_client_id);
+
+		if (dev->open_handle_count > 0) {
+			clear_bit(cl->host_client_id,
+				  dev->host_clients_map);
+			dev->open_handle_count--;
+		}
+		mei_remove_client_from_file_list(dev, cl->host_client_id);
+
+		/* free read cb */
+		cb = NULL;
+		if (cl->read_cb) {
+			cb = find_read_list_entry(dev, cl);
+			/* Remove entry from read list */
+			if (cb)
+				list_del(&cb->cb_list);
+
+			cb = cl->read_cb;
+			cl->read_cb = NULL;
+		}
+
+		file->private_data = NULL;
+
+		if (cb) {
+			mei_free_cb_private(cb);
+			cb = NULL;
+		}
+
+		kfree(cl);
+	} else {
+		if (dev->open_handle_count > 0)
+			dev->open_handle_count--;
+
+		if (dev->iamthif_file_object == file &&
+		    dev->iamthif_state != MEI_IAMTHIF_IDLE) {
+
+			dev_dbg(&dev->pdev->dev, "amthi canceled iamthif state %d\n",
+			    dev->iamthif_state);
+			dev->iamthif_canceled = 1;
+			if (dev->iamthif_state == MEI_IAMTHIF_READ_COMPLETE) {
+				dev_dbg(&dev->pdev->dev, "run next amthi iamthif cb\n");
+				run_next_iamthif_cmd(dev);
+			}
+		}
+
+		if (mei_clear_lists(dev, file))
+			dev->iamthif_state = MEI_IAMTHIF_IDLE;
+
+	}
+	mutex_unlock(&dev->device_lock);
+	return rets;
+}
+
+
+/**
+ * mei_read - the read function.
+ *
+ * @file: pointer to file structure
+ * @ubuf: pointer to user buffer
+ * @length: buffer length
+ * @offset: data offset in buffer
+ *
+ * returns >=0 data length on success , <0 on error
+ */
+static ssize_t mei_read(struct file *file, char __user *ubuf,
+			 size_t length, loff_t *offset)
+{
+	struct mei_cl *cl = file->private_data;
+	struct mei_cl_cb *cb_pos = NULL;
+	struct mei_cl_cb *cb = NULL;
+	struct mei_device *dev;
+	int i;
+	int rets;
+	int err;
+
+
+	if (WARN_ON(!cl || !cl->dev))
+		return -ENODEV;
+
+	dev = cl->dev;
+
+	mutex_lock(&dev->device_lock);
+	if (dev->mei_state != MEI_ENABLED) {
+		rets = -ENODEV;
+		goto out;
+	}
+
+	if ((cl->sm_state & MEI_WD_STATE_INDEPENDENCE_MSG_SENT) == 0) {
+		/* Do not allow to read watchdog client */
+		i = mei_find_me_client_index(dev, mei_wd_guid);
+		if (i >= 0) {
+			struct mei_me_client *me_client = &dev->me_clients[i];
+
+			if (cl->me_client_id == me_client->client_id) {
+				rets = -EBADF;
+				goto out;
+			}
+		}
+	} else {
+		cl->sm_state &= ~MEI_WD_STATE_INDEPENDENCE_MSG_SENT;
+	}
+
+	if (cl == &dev->iamthif_cl) {
+		rets = amthi_read(dev, file, ubuf, length, offset);
+		goto out;
+	}
+
+	if (cl->read_cb && cl->read_cb->information > *offset) {
+		cb = cl->read_cb;
+		goto copy_buffer;
+	} else if (cl->read_cb && cl->read_cb->information > 0 &&
+		   cl->read_cb->information <= *offset) {
+		cb = cl->read_cb;
+		rets = 0;
+		goto free;
+	} else if ((!cl->read_cb || !cl->read_cb->information) &&
+		    *offset > 0) {
+		/*Offset needs to be cleaned for contingous reads*/
+		*offset = 0;
+		rets = 0;
+		goto out;
+	}
+
+	err = mei_start_read(dev, cl);
+	if (err && err != -EBUSY) {
+		dev_dbg(&dev->pdev->dev,
+			"mei start read failure with status = %d\n", err);
+		rets = err;
+		goto out;
+	}
+
+	if (MEI_READ_COMPLETE != cl->reading_state &&
+			!waitqueue_active(&cl->rx_wait)) {
+		if (file->f_flags & O_NONBLOCK) {
+			rets = -EAGAIN;
+			goto out;
+		}
+
+		mutex_unlock(&dev->device_lock);
+
+		if (wait_event_interruptible(cl->rx_wait,
+			(MEI_READ_COMPLETE == cl->reading_state ||
+			 MEI_FILE_INITIALIZING == cl->state ||
+			 MEI_FILE_DISCONNECTED == cl->state ||
+			 MEI_FILE_DISCONNECTING == cl->state))) {
+			if (signal_pending(current))
+				return -EINTR;
+			return -ERESTARTSYS;
+		}
+
+		mutex_lock(&dev->device_lock);
+		if (MEI_FILE_INITIALIZING == cl->state ||
+		    MEI_FILE_DISCONNECTED == cl->state ||
+		    MEI_FILE_DISCONNECTING == cl->state) {
+			rets = -EBUSY;
+			goto out;
+		}
+	}
+
+	cb = cl->read_cb;
+
+	if (!cb) {
+		rets = -ENODEV;
+		goto out;
+	}
+	if (cl->reading_state != MEI_READ_COMPLETE) {
+		rets = 0;
+		goto out;
+	}
+	/* now copy the data to user space */
+copy_buffer:
+	dev_dbg(&dev->pdev->dev, "cb->response_buffer size - %d\n",
+	    cb->response_buffer.size);
+	dev_dbg(&dev->pdev->dev, "cb->information - %lu\n",
+	    cb->information);
+	if (length == 0 || ubuf == NULL || *offset > cb->information) {
+		rets = -EMSGSIZE;
+		goto free;
+	}
+
+	/* length is being turncated to PAGE_SIZE, however, */
+	/* information size may be longer */
+	length = min_t(size_t, length, (cb->information - *offset));
+
+	if (copy_to_user(ubuf,
+			 cb->response_buffer.data + *offset,
+			 length)) {
+		rets = -EFAULT;
+		goto free;
+	}
+
+	rets = length;
+	*offset += length;
+	if ((unsigned long)*offset < cb->information)
+		goto out;
+
+free:
+	cb_pos = find_read_list_entry(dev, cl);
+	/* Remove entry from read list */
+	if (cb_pos)
+		list_del(&cb_pos->cb_list);
+	mei_free_cb_private(cb);
+	cl->reading_state = MEI_IDLE;
+	cl->read_cb = NULL;
+	cl->read_pending = 0;
+out:
+	dev_dbg(&dev->pdev->dev, "end mei read rets= %d\n", rets);
+	mutex_unlock(&dev->device_lock);
+	return rets;
+}
+
+/**
+ * mei_write - the write function.
+ *
+ * @file: pointer to file structure
+ * @ubuf: pointer to user buffer
+ * @length: buffer length
+ * @offset: data offset in buffer
+ *
+ * returns >=0 data length on success , <0 on error
+ */
+static ssize_t mei_write(struct file *file, const char __user *ubuf,
+			  size_t length, loff_t *offset)
+{
+	struct mei_cl *cl = file->private_data;
+	struct mei_cl_cb *write_cb = NULL;
+	struct mei_msg_hdr mei_hdr;
+	struct mei_device *dev;
+	unsigned long timeout = 0;
+	int rets;
+	int i;
+
+	if (WARN_ON(!cl || !cl->dev))
+		return -ENODEV;
+
+	dev = cl->dev;
+
+	mutex_lock(&dev->device_lock);
+
+	if (dev->mei_state != MEI_ENABLED) {
+		mutex_unlock(&dev->device_lock);
+		return -ENODEV;
+	}
+
+	if (cl == &dev->iamthif_cl) {
+		write_cb = find_amthi_read_list_entry(dev, file);
+
+		if (write_cb) {
+			timeout = write_cb->read_time +
+					msecs_to_jiffies(IAMTHIF_READ_TIMER);
+
+			if (time_after(jiffies, timeout) ||
+				 cl->reading_state == MEI_READ_COMPLETE) {
+					*offset = 0;
+					list_del(&write_cb->cb_list);
+					mei_free_cb_private(write_cb);
+					write_cb = NULL;
+			}
+		}
+	}
+
+	/* free entry used in read */
+	if (cl->reading_state == MEI_READ_COMPLETE) {
+		*offset = 0;
+		write_cb = find_read_list_entry(dev, cl);
+		if (write_cb) {
+			list_del(&write_cb->cb_list);
+			mei_free_cb_private(write_cb);
+			write_cb = NULL;
+			cl->reading_state = MEI_IDLE;
+			cl->read_cb = NULL;
+			cl->read_pending = 0;
+		}
+	} else if (cl->reading_state == MEI_IDLE &&
+		   !cl->read_pending)
+		*offset = 0;
+
+
+	write_cb = kzalloc(sizeof(struct mei_cl_cb), GFP_KERNEL);
+	if (!write_cb) {
+		mutex_unlock(&dev->device_lock);
+		return -ENOMEM;
+	}
+
+	write_cb->file_object = file;
+	write_cb->file_private = cl;
+	write_cb->request_buffer.data = kmalloc(length, GFP_KERNEL);
+	rets = -ENOMEM;
+	if (!write_cb->request_buffer.data)
+		goto unlock_dev;
+
+	dev_dbg(&dev->pdev->dev, "length =%d\n", (int) length);
+
+	rets = -EFAULT;
+	if (copy_from_user(write_cb->request_buffer.data, ubuf, length))
+		goto unlock_dev;
+
+	cl->sm_state = 0;
+	if (length == 4 &&
+	    ((memcmp(mei_wd_state_independence_msg[0],
+				 write_cb->request_buffer.data, 4) == 0) ||
+	     (memcmp(mei_wd_state_independence_msg[1],
+				 write_cb->request_buffer.data, 4) == 0) ||
+	     (memcmp(mei_wd_state_independence_msg[2],
+				 write_cb->request_buffer.data, 4) == 0)))
+		cl->sm_state |= MEI_WD_STATE_INDEPENDENCE_MSG_SENT;
+
+	INIT_LIST_HEAD(&write_cb->cb_list);
+	if (cl == &dev->iamthif_cl) {
+		write_cb->response_buffer.data =
+		    kmalloc(dev->iamthif_mtu, GFP_KERNEL);
+		if (!write_cb->response_buffer.data) {
+			rets = -ENOMEM;
+			goto unlock_dev;
+		}
+		if (dev->mei_state != MEI_ENABLED) {
+			rets = -ENODEV;
+			goto unlock_dev;
+		}
+		for (i = 0; i < dev->num_mei_me_clients; i++) {
+			if (dev->me_clients[i].client_id ==
+				dev->iamthif_cl.me_client_id)
+				break;
+		}
+
+		if (WARN_ON(dev->me_clients[i].client_id != cl->me_client_id)) {
+			rets = -ENODEV;
+			goto unlock_dev;
+		}
+		if (i == dev->num_mei_me_clients ||
+		    (dev->me_clients[i].client_id !=
+		      dev->iamthif_cl.me_client_id)) {
+			rets = -ENODEV;
+			goto unlock_dev;
+		} else if (length > dev->me_clients[i].props.max_msg_length ||
+			   length <= 0) {
+			rets = -EMSGSIZE;
+			goto unlock_dev;
+		}
+
+		write_cb->response_buffer.size = dev->iamthif_mtu;
+		write_cb->major_file_operations = MEI_IOCTL;
+		write_cb->information = 0;
+		write_cb->request_buffer.size = length;
+		if (dev->iamthif_cl.state != MEI_FILE_CONNECTED) {
+			rets = -ENODEV;
+			goto unlock_dev;
+		}
+
+		if (!list_empty(&dev->amthi_cmd_list.mei_cb.cb_list) ||
+				dev->iamthif_state != MEI_IAMTHIF_IDLE) {
+			dev_dbg(&dev->pdev->dev, "amthi_state = %d\n",
+					(int) dev->iamthif_state);
+			dev_dbg(&dev->pdev->dev, "add amthi cb to amthi cmd waiting list\n");
+			list_add_tail(&write_cb->cb_list,
+					&dev->amthi_cmd_list.mei_cb.cb_list);
+			rets = length;
+		} else {
+			dev_dbg(&dev->pdev->dev, "call amthi write\n");
+			rets = amthi_write(dev, write_cb);
+
+			if (rets) {
+				dev_dbg(&dev->pdev->dev, "amthi write failed with status = %d\n",
+				    rets);
+				goto unlock_dev;
+			}
+			rets = length;
+		}
+		mutex_unlock(&dev->device_lock);
+		return rets;
+	}
+
+	write_cb->major_file_operations = MEI_WRITE;
+	/* make sure information is zero before we start */
+
+	write_cb->information = 0;
+	write_cb->request_buffer.size = length;
+
+	dev_dbg(&dev->pdev->dev, "host client = %d, ME client = %d\n",
+	    cl->host_client_id, cl->me_client_id);
+	if (cl->state != MEI_FILE_CONNECTED) {
+		rets = -ENODEV;
+		dev_dbg(&dev->pdev->dev, "host client = %d,  is not connected to ME client = %d",
+		    cl->host_client_id,
+		    cl->me_client_id);
+		goto unlock_dev;
+	}
+	for (i = 0; i < dev->num_mei_me_clients; i++) {
+		if (dev->me_clients[i].client_id ==
+		    cl->me_client_id)
+			break;
+	}
+	if (WARN_ON(dev->me_clients[i].client_id != cl->me_client_id)) {
+		rets = -ENODEV;
+		goto unlock_dev;
+	}
+	if (i == dev->num_mei_me_clients) {
+		rets = -ENODEV;
+		goto unlock_dev;
+	}
+	if (length > dev->me_clients[i].props.max_msg_length || length <= 0) {
+		rets = -EINVAL;
+		goto unlock_dev;
+	}
+	write_cb->file_private = cl;
+
+	rets = mei_flow_ctrl_creds(dev, cl);
+	if (rets < 0)
+		goto unlock_dev;
+
+	if (rets && dev->mei_host_buffer_is_empty) {
+		rets = 0;
+		dev->mei_host_buffer_is_empty = 0;
+		if (length > ((((dev->host_hw_state & H_CBD) >> 24) *
+			sizeof(u32)) - sizeof(struct mei_msg_hdr))) {
+
+			mei_hdr.length =
+				(((dev->host_hw_state & H_CBD) >> 24) *
+				sizeof(u32)) -
+				sizeof(struct mei_msg_hdr);
+			mei_hdr.msg_complete = 0;
+		} else {
+			mei_hdr.length = length;
+			mei_hdr.msg_complete = 1;
+		}
+		mei_hdr.host_addr = cl->host_client_id;
+		mei_hdr.me_addr = cl->me_client_id;
+		mei_hdr.reserved = 0;
+		dev_dbg(&dev->pdev->dev, "call mei_write_message header=%08x.\n",
+		    *((u32 *) &mei_hdr));
+		if (!mei_write_message(dev, &mei_hdr,
+			(unsigned char *) (write_cb->request_buffer.data),
+			mei_hdr.length)) {
+			rets = -ENODEV;
+			goto unlock_dev;
+		}
+		cl->writing_state = MEI_WRITING;
+		write_cb->information = mei_hdr.length;
+		if (mei_hdr.msg_complete) {
+			if (mei_flow_ctrl_reduce(dev, cl)) {
+				rets = -ENODEV;
+				goto unlock_dev;
+			}
+			list_add_tail(&write_cb->cb_list,
+				      &dev->write_waiting_list.mei_cb.cb_list);
+		} else {
+			list_add_tail(&write_cb->cb_list,
+				      &dev->write_list.mei_cb.cb_list);
+		}
+
+	} else {
+
+		write_cb->information = 0;
+		cl->writing_state = MEI_WRITING;
+		list_add_tail(&write_cb->cb_list,
+			      &dev->write_list.mei_cb.cb_list);
+	}
+	mutex_unlock(&dev->device_lock);
+	return length;
+
+unlock_dev:
+	mutex_unlock(&dev->device_lock);
+	mei_free_cb_private(write_cb);
+	return rets;
+}
+
+
+/**
+ * mei_ioctl - the IOCTL function
+ *
+ * @file: pointer to file structure
+ * @cmd: ioctl command
+ * @data: pointer to mei message structure
+ *
+ * returns 0 on success , <0 on error
+ */
+static long mei_ioctl(struct file *file, unsigned int cmd, unsigned long data)
+{
+	struct mei_device *dev;
+	struct mei_cl *cl = file->private_data;
+	struct mei_connect_client_data *connect_data = NULL;
+	int rets;
+
+	if (cmd != IOCTL_MEI_CONNECT_CLIENT)
+		return -EINVAL;
+
+	if (WARN_ON(!cl || !cl->dev))
+		return -ENODEV;
+
+	dev = cl->dev;
+
+	dev_dbg(&dev->pdev->dev, "IOCTL cmd = 0x%x", cmd);
+
+	mutex_lock(&dev->device_lock);
+	if (dev->mei_state != MEI_ENABLED) {
+		rets = -ENODEV;
+		goto out;
+	}
+
+	dev_dbg(&dev->pdev->dev, ": IOCTL_MEI_CONNECT_CLIENT.\n");
+
+	connect_data = kzalloc(sizeof(struct mei_connect_client_data),
+							GFP_KERNEL);
+	if (!connect_data) {
+		rets = -ENOMEM;
+		goto out;
+	}
+	dev_dbg(&dev->pdev->dev, "copy connect data from user\n");
+	if (copy_from_user(connect_data, (char __user *)data,
+				sizeof(struct mei_connect_client_data))) {
+		dev_dbg(&dev->pdev->dev, "failed to copy data from userland\n");
+		rets = -EFAULT;
+		goto out;
+	}
+	rets = mei_ioctl_connect_client(file, connect_data);
+
+	/* if all is ok, copying the data back to user. */
+	if (rets)
+		goto out;
+
+	dev_dbg(&dev->pdev->dev, "copy connect data to user\n");
+	if (copy_to_user((char __user *)data, connect_data,
+				sizeof(struct mei_connect_client_data))) {
+		dev_dbg(&dev->pdev->dev, "failed to copy data to userland\n");
+		rets = -EFAULT;
+		goto out;
+	}
+
+out:
+	kfree(connect_data);
+	mutex_unlock(&dev->device_lock);
+	return rets;
+}
+
+/**
+ * mei_compat_ioctl - the compat IOCTL function
+ *
+ * @file: pointer to file structure
+ * @cmd: ioctl command
+ * @data: pointer to mei message structure
+ *
+ * returns 0 on success , <0 on error
+ */
+#ifdef CONFIG_COMPAT
+static long mei_compat_ioctl(struct file *file,
+		      unsigned int cmd, unsigned long data)
+{
+	return mei_ioctl(file, cmd, (unsigned long)compat_ptr(data));
+}
+#endif
+
+
+/**
+ * mei_poll - the poll function
+ *
+ * @file: pointer to file structure
+ * @wait: pointer to poll_table structure
+ *
+ * returns poll mask
+ */
+static unsigned int mei_poll(struct file *file, poll_table *wait)
+{
+	struct mei_cl *cl = file->private_data;
+	struct mei_device *dev;
+	unsigned int mask = 0;
+
+	if (WARN_ON(!cl || !cl->dev))
+		return mask;
+
+	dev = cl->dev;
+
+	mutex_lock(&dev->device_lock);
+
+	if (dev->mei_state != MEI_ENABLED)
+		goto out;
+
+
+	if (cl == &dev->iamthif_cl) {
+		mutex_unlock(&dev->device_lock);
+		poll_wait(file, &dev->iamthif_cl.wait, wait);
+		mutex_lock(&dev->device_lock);
+		if (dev->iamthif_state == MEI_IAMTHIF_READ_COMPLETE &&
+			dev->iamthif_file_object == file) {
+			mask |= (POLLIN | POLLRDNORM);
+			dev_dbg(&dev->pdev->dev, "run next amthi cb\n");
+			run_next_iamthif_cmd(dev);
+		}
+		goto out;
+	}
+
+	mutex_unlock(&dev->device_lock);
+	poll_wait(file, &cl->tx_wait, wait);
+	mutex_lock(&dev->device_lock);
+	if (MEI_WRITE_COMPLETE == cl->writing_state)
+		mask |= (POLLIN | POLLRDNORM);
+
+out:
+	mutex_unlock(&dev->device_lock);
+	return mask;
+}
+
+#ifdef CONFIG_PM
+static int mei_pci_suspend(struct device *device)
+{
+	struct pci_dev *pdev = to_pci_dev(device);
+	struct mei_device *dev = pci_get_drvdata(pdev);
+	int err;
+
+	if (!dev)
+		return -ENODEV;
+	mutex_lock(&dev->device_lock);
+	/* Stop watchdog if exists */
+	err = mei_wd_stop(dev, true);
+	/* Set new mei state */
+	if (dev->mei_state == MEI_ENABLED ||
+	    dev->mei_state == MEI_RECOVERING_FROM_RESET) {
+		dev->mei_state = MEI_POWER_DOWN;
+		mei_reset(dev, 0);
+	}
+	mutex_unlock(&dev->device_lock);
+
+	free_irq(pdev->irq, dev);
+
+
+	return err;
+}
+
+static int mei_pci_resume(struct device *device)
+{
+	struct pci_dev *pdev = to_pci_dev(device);
+	struct mei_device *dev;
+	int err;
+
+	dev = pci_get_drvdata(pdev);
+	if (!dev)
+		return -ENODEV;
+
+	/* request and enable interrupt   */
+	err = request_threaded_irq(pdev->irq,
+			mei_interrupt_quick_handler,
+			mei_interrupt_thread_handler,
+			IRQF_SHARED, mei_driver_name, dev);
+	if (err) {
+		printk(KERN_ERR "mei: Request_irq failure. irq = %d\n",
+		       pdev->irq);
+		return err;
+	}
+
+	mutex_lock(&dev->device_lock);
+	dev->mei_state = MEI_POWER_UP;
+	mei_reset(dev, 1);
+	mutex_unlock(&dev->device_lock);
+
+	/* Start watchdog if stopped in suspend */
+	if (dev->wd_timeout) {
+		mei_wd_start_setup(dev);
+		dev->wd_due_counter = 1;
+		schedule_delayed_work(&dev->wd_work, HZ);
+	}
+	return err;
+}
+static SIMPLE_DEV_PM_OPS(mei_pm_ops, mei_pci_suspend, mei_pci_resume);
+#define MEI_PM_OPS	(&mei_pm_ops)
+#else
+#define MEI_PM_OPS	NULL
+#endif /* CONFIG_PM */
+/*
+ *  PCI driver structure
+ */
+static struct pci_driver mei_driver = {
+	.name = mei_driver_name,
+	.id_table = mei_pci_tbl,
+	.probe = mei_probe,
+	.remove = __devexit_p(mei_remove),
+	.shutdown = __devexit_p(mei_remove),
+	.driver.pm = MEI_PM_OPS,
+};
+
+/*
+ * file operations structure will be used for mei char device.
+ */
+static const struct file_operations mei_fops = {
+	.owner = THIS_MODULE,
+	.read = mei_read,
+	.unlocked_ioctl = mei_ioctl,
+#ifdef CONFIG_COMPAT
+	.compat_ioctl = mei_compat_ioctl,
+#endif
+	.open = mei_open,
+	.release = mei_release,
+	.write = mei_write,
+	.poll = mei_poll,
+};
+
+/**
+ * mei_registration_cdev - sets up the cdev structure for mei device.
+ *
+ * @dev: char device struct
+ * @hminor: minor number for registration char device
+ * @fops: file operations structure
+ *
+ * returns 0 on success, <0 on failure.
+ */
+static int mei_registration_cdev(struct cdev *dev, int hminor,
+				  const struct file_operations *fops)
+{
+	int ret, devno = MKDEV(mei_major, hminor);
+
+	cdev_init(dev, fops);
+	dev->owner = THIS_MODULE;
+	ret = cdev_add(dev, devno, 1);
+	/* Fail gracefully if need be */
+	if (ret)
+		printk(KERN_ERR "mei: Error %d registering mei device %d\n",
+		       ret, hminor);
+	return ret;
+}
+
+/**
+ * mei_register_cdev - registers mei char device
+ *
+ * returns 0 on success, <0 on failure.
+ */
+static int mei_register_cdev(void)
+{
+	int ret;
+	dev_t dev;
+
+	/* registration of char devices */
+	ret = alloc_chrdev_region(&dev, MEI_MINORS_BASE, MEI_MINORS_COUNT,
+				  MEI_DRIVER_NAME);
+	if (ret) {
+		printk(KERN_ERR "mei: Error allocating char device region.\n");
+		return ret;
+	}
+
+	mei_major = MAJOR(dev);
+
+	ret = mei_registration_cdev(&mei_cdev, MEI_MINOR_NUMBER,
+				     &mei_fops);
+	if (ret)
+		unregister_chrdev_region(MKDEV(mei_major, MEI_MINORS_BASE),
+					 MEI_MINORS_COUNT);
+
+	return ret;
+}
+
+/**
+ * mei_unregister_cdev - unregisters mei char device
+ */
+static void mei_unregister_cdev(void)
+{
+	cdev_del(&mei_cdev);
+	unregister_chrdev_region(MKDEV(mei_major, MEI_MINORS_BASE),
+				 MEI_MINORS_COUNT);
+}
+
+/**
+ * mei_sysfs_device_create - adds device entry to sysfs
+ *
+ * returns 0 on success, <0 on failure.
+ */
+static int mei_sysfs_device_create(void)
+{
+	struct class *class;
+	void *tmphdev;
+	int err;
+
+	class = class_create(THIS_MODULE, MEI_DRIVER_NAME);
+	if (IS_ERR(class)) {
+		err = PTR_ERR(class);
+		printk(KERN_ERR "mei: Error creating mei class.\n");
+		goto err_out;
+	}
+
+	tmphdev = device_create(class, NULL, mei_cdev.dev, NULL,
+					MEI_DEV_NAME);
+	if (IS_ERR(tmphdev)) {
+		err = PTR_ERR(tmphdev);
+		goto err_destroy;
+	}
+
+	mei_class = class;
+	return 0;
+
+err_destroy:
+	class_destroy(class);
+err_out:
+	return err;
+}
+
+/**
+ * mei_sysfs_device_remove - unregisters the device entry on sysfs
+ */
+static void mei_sysfs_device_remove(void)
+{
+	if (IS_ERR_OR_NULL(mei_class))
+		return;
+
+	device_destroy(mei_class, mei_cdev.dev);
+	class_destroy(mei_class);
+}
+
+/**
+ * mei_init_module - Driver Registration Routine
+ *
+ * mei_init_module is the first routine called when the driver is
+ * loaded. All it does is to register with the PCI subsystem.
+ *
+ * returns 0 on success, <0 on failure.
+ */
+static int __init mei_init_module(void)
+{
+	int ret;
+
+	pr_debug("mei: %s - version %s\n",
+		mei_driver_string, mei_driver_version);
+	/* init pci module */
+	ret = pci_register_driver(&mei_driver);
+	if (ret < 0) {
+		printk(KERN_ERR "mei: Error registering driver.\n");
+		goto end;
+	}
+
+	ret = mei_register_cdev();
+	if (ret)
+		goto unregister_pci;
+
+	ret = mei_sysfs_device_create();
+	if (ret)
+		goto unregister_cdev;
+
+	return ret;
+
+unregister_cdev:
+	mei_unregister_cdev();
+unregister_pci:
+	pci_unregister_driver(&mei_driver);
+end:
+	return ret;
+}
+
+module_init(mei_init_module);
+
+/**
+ * mei_exit_module - Driver Exit Cleanup Routine
+ *
+ * mei_exit_module is called just before the driver is removed
+ * from memory.
+ */
+static void __exit mei_exit_module(void)
+{
+	pci_unregister_driver(&mei_driver);
+	mei_sysfs_device_remove();
+	mei_unregister_cdev();
+
+	pr_debug("mei: Driver unloaded successfully.\n");
+}
+
+module_exit(mei_exit_module);
+
+
+MODULE_AUTHOR("Intel Corporation");
+MODULE_DESCRIPTION("Intel(R) Management Engine Interface");
+MODULE_LICENSE("GPL v2");
+MODULE_VERSION(MEI_DRIVER_VERSION);
diff -druN linux-2.6.39-libre/drivers/staging/mei/Makefile linux-3.0-rc7-libre/drivers/staging/mei/Makefile
--- linux-2.6.39-libre/drivers/staging/mei/Makefile	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/staging/mei/Makefile	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,11 @@
+#
+# Makefile - Intel Management Engine Interface (Intel MEI) Linux driver
+# Copyright (c) 2010-2011, Intel Corporation.
+#
+obj-$(CONFIG_INTEL_MEI) += mei.o
+mei-objs := init.o
+mei-objs += interrupt.o
+mei-objs += interface.o
+mei-objs += iorw.o
+mei-objs += main.o
+mei-objs += wd.o
diff -druN linux-2.6.39-libre/drivers/staging/mei/mei_dev.h linux-3.0-rc7-libre/drivers/staging/mei/mei_dev.h
--- linux-2.6.39-libre/drivers/staging/mei/mei_dev.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/staging/mei/mei_dev.h	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,422 @@
+/*
+ *
+ * Intel Management Engine Interface (Intel MEI) Linux driver
+ * Copyright (c) 2003-2011, 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.
+ *
+ */
+
+#ifndef _MEI_DEV_H_
+#define _MEI_DEV_H_
+
+#include <linux/types.h>
+#include "mei.h"
+#include "hw.h"
+
+/*
+ * MEI Char Driver Minors
+ */
+#define MEI_MINORS_BASE	1
+#define MEI_MINORS_COUNT	1
+#define MEI_MINOR_NUMBER	1
+
+/*
+ * watch dog definition
+ */
+#define MEI_WATCHDOG_DATA_SIZE         16
+#define MEI_START_WD_DATA_SIZE         20
+#define MEI_WD_PARAMS_SIZE             4
+#define MEI_WD_STATE_INDEPENDENCE_MSG_SENT       (1 << 0)
+
+/*
+ * AMTHI Client UUID
+ */
+extern const uuid_le mei_amthi_guid;
+
+/*
+ * Watchdog Client UUID
+ */
+extern const uuid_le mei_wd_guid;
+
+/*
+ * Watchdog independence state message
+ */
+extern const u8 mei_wd_state_independence_msg[3][4];
+
+/*
+ * Number of File descriptors/handles
+ * that can be opened to the driver.
+ *
+ * Limit to 253: 255 Total Clients
+ * minus internal client for AMTHI
+ * minus internal client for Watchdog
+ */
+#define  MEI_MAX_OPEN_HANDLE_COUNT	253
+
+/*
+ * Number of queue lists used by this driver
+ */
+#define MEI_IO_LISTS_NUMBER        7
+
+/*
+ * Number of Maximum MEI Clients
+ */
+#define MEI_CLIENTS_MAX 255
+
+/* File state */
+enum file_state {
+	MEI_FILE_INITIALIZING = 0,
+	MEI_FILE_CONNECTING,
+	MEI_FILE_CONNECTED,
+	MEI_FILE_DISCONNECTING,
+	MEI_FILE_DISCONNECTED
+};
+
+/* MEI device states */
+enum mei_states {
+	MEI_INITIALIZING = 0,
+	MEI_INIT_CLIENTS,
+	MEI_ENABLED,
+	MEI_RESETING,
+	MEI_DISABLED,
+	MEI_RECOVERING_FROM_RESET,
+	MEI_POWER_DOWN,
+	MEI_POWER_UP
+};
+
+/* init clients  states*/
+enum mei_init_clients_states {
+	MEI_START_MESSAGE = 0,
+	MEI_ENUM_CLIENTS_MESSAGE,
+	MEI_CLIENT_PROPERTIES_MESSAGE
+};
+
+enum iamthif_states {
+	MEI_IAMTHIF_IDLE,
+	MEI_IAMTHIF_WRITING,
+	MEI_IAMTHIF_FLOW_CONTROL,
+	MEI_IAMTHIF_READING,
+	MEI_IAMTHIF_READ_COMPLETE
+};
+
+enum mei_file_transaction_states {
+	MEI_IDLE,
+	MEI_WRITING,
+	MEI_WRITE_COMPLETE,
+	MEI_FLOW_CONTROL,
+	MEI_READING,
+	MEI_READ_COMPLETE
+};
+
+/* MEI CB */
+enum mei_cb_major_types {
+	MEI_READ = 0,
+	MEI_WRITE,
+	MEI_IOCTL,
+	MEI_OPEN,
+	MEI_CLOSE
+};
+
+/*
+ * Intel MEI message data struct
+ */
+struct mei_message_data {
+	u32 size;
+	char *data;
+} __packed;
+
+
+struct mei_cl_cb {
+	struct list_head cb_list;
+	enum mei_cb_major_types major_file_operations;
+	void *file_private;
+	struct mei_message_data request_buffer;
+	struct mei_message_data response_buffer;
+	unsigned long information;
+	unsigned long read_time;
+	struct file *file_object;
+};
+
+/* MEI client instance carried as file->pirvate_data*/
+struct mei_cl {
+	struct list_head link;
+	struct mei_device *dev;
+	enum file_state state;
+	wait_queue_head_t tx_wait;
+	wait_queue_head_t rx_wait;
+	wait_queue_head_t wait;
+	int read_pending;
+	int status;
+	/* ID of client connected */
+	u8 host_client_id;
+	u8 me_client_id;
+	u8 mei_flow_ctrl_creds;
+	u8 timer_count;
+	enum mei_file_transaction_states reading_state;
+	enum mei_file_transaction_states writing_state;
+	int sm_state;
+	struct mei_cl_cb *read_cb;
+};
+
+struct mei_io_list {
+	struct mei_cl_cb mei_cb;
+	int status;
+	struct mei_device *device_extension;
+};
+
+/* MEI private device struct */
+struct mei_device {
+	struct pci_dev *pdev;	/* pointer to pci device struct */
+	/*
+	 * lists of queues
+	 */
+	 /* array of pointers to aio lists */
+	struct mei_io_list *io_list_array[MEI_IO_LISTS_NUMBER];
+	struct mei_io_list read_list;		/* driver read queue */
+	struct mei_io_list write_list;		/* driver write queue */
+	struct mei_io_list write_waiting_list;	/* write waiting queue */
+	struct mei_io_list ctrl_wr_list;	/* managed write IOCTL list */
+	struct mei_io_list ctrl_rd_list;	/* managed read IOCTL list */
+	struct mei_io_list amthi_cmd_list;	/* amthi list for cmd waiting */
+
+	/* driver managed amthi list for reading completed amthi cmd data */
+	struct mei_io_list amthi_read_complete_list;
+	/*
+	 * list of files
+	 */
+	struct list_head file_list;
+	/*
+	 * memory of device
+	 */
+	unsigned int mem_base;
+	unsigned int mem_length;
+	void __iomem *mem_addr;
+	/*
+	 * lock for the device
+	 */
+	struct mutex device_lock; /* device lock */
+	int recvd_msg;
+	struct delayed_work wd_work;	/* watch dog deleye work */
+	/*
+	 * hw states of host and fw(ME)
+	 */
+	u32 host_hw_state;
+	u32 me_hw_state;
+	/*
+	 * waiting queue for receive message from FW
+	 */
+	wait_queue_head_t wait_recvd_msg;
+	wait_queue_head_t wait_stop_wd;
+
+	/*
+	 * mei device  states
+	 */
+	enum mei_states mei_state;
+	enum mei_init_clients_states init_clients_state;
+	u16 init_clients_timer;
+	int stop;
+
+	u32 extra_write_index;
+	u32 rd_msg_buf[128];	/* used for control messages */
+	u32 wr_msg_buf[128];	/* used for control messages */
+	u32 ext_msg_buf[8];	/* for control responses */
+	u32 rd_msg_hdr;
+
+	struct hbm_version version;
+
+	int mei_host_buffer_is_empty;
+	struct mei_cl wd_cl;
+	struct mei_me_client *me_clients; /* Note: memory has to be allocated */
+	DECLARE_BITMAP(me_clients_map, MEI_CLIENTS_MAX);
+	DECLARE_BITMAP(host_clients_map, MEI_CLIENTS_MAX);
+	u8 num_mei_me_clients;
+	u8 me_client_presentation_num;
+	u8 me_client_index;
+
+	int wd_pending;
+	int wd_stopped;
+	u16 wd_timeout;	/* seconds ((wd_data[1] << 8) + wd_data[0]) */
+	unsigned char wd_data[MEI_START_WD_DATA_SIZE];
+
+
+	u16 wd_due_counter;
+	bool wd_bypass;	/* if false, don't refresh watchdog ME client */
+
+	struct file *iamthif_file_object;
+	struct mei_cl iamthif_cl;
+	int iamthif_ioctl;
+	int iamthif_canceled;
+	int iamthif_mtu;
+	unsigned long iamthif_timer;
+	u32 iamthif_stall_timer;
+	unsigned char *iamthif_msg_buf; /* Note: memory has to be allocated */
+	u32 iamthif_msg_buf_size;
+	u32 iamthif_msg_buf_index;
+	int iamthif_flow_control_pending;
+	enum iamthif_states iamthif_state;
+	struct mei_cl_cb *iamthif_current_cb;
+	u8 write_hang;
+	int need_reset;
+	long open_handle_count;
+
+};
+
+
+/*
+ * mei init function prototypes
+ */
+struct mei_device *init_mei_device(struct pci_dev *pdev);
+void mei_reset(struct mei_device *dev, int interrupts);
+int mei_hw_init(struct mei_device *dev);
+int mei_task_initialize_clients(void *data);
+int mei_initialize_clients(struct mei_device *dev);
+struct mei_cl *mei_alloc_file_private(struct mei_device *dev);
+int mei_disconnect_host_client(struct mei_device *dev, struct mei_cl *cl);
+void mei_initialize_list(struct mei_io_list *list,
+			  struct mei_device *dev);
+void mei_flush_list(struct mei_io_list *list, struct mei_cl *cl);
+void mei_flush_queues(struct mei_device *dev, struct mei_cl *cl);
+void mei_remove_client_from_file_list(struct mei_device *dev,
+				       u8 host_client_id);
+void host_init_iamthif(struct mei_device *dev);
+void mei_init_file_private(struct mei_cl *priv, struct mei_device *dev);
+void allocate_me_clients_storage(struct mei_device *dev);
+
+void host_start_message(struct mei_device *dev);
+void host_enum_clients_message(struct mei_device *dev);
+void host_client_properties(struct mei_device *dev);
+
+u8 mei_find_me_client_update_filext(struct mei_device *dev,
+				struct mei_cl *priv,
+				const uuid_le *cguid, u8 client_id);
+
+/*
+ *  interrupt functions prototype
+ */
+irqreturn_t mei_interrupt_quick_handler(int irq, void *dev_id);
+irqreturn_t  mei_interrupt_thread_handler(int irq, void *dev_id);
+void mei_wd_timer(struct work_struct *work);
+
+/*
+ *  input output function prototype
+ */
+int mei_ioctl_connect_client(struct file *file,
+			struct mei_connect_client_data *data);
+
+int mei_start_read(struct mei_device *dev, struct mei_cl *cl);
+
+int amthi_write(struct mei_device *dev, struct mei_cl_cb *priv_cb);
+
+int amthi_read(struct mei_device *dev, struct file *file,
+	      char __user *ubuf, size_t length, loff_t *offset);
+
+struct mei_cl_cb *find_amthi_read_list_entry(struct mei_device *dev,
+						struct file *file);
+
+void run_next_iamthif_cmd(struct mei_device *dev);
+
+void mei_free_cb_private(struct mei_cl_cb *priv_cb);
+
+int mei_find_me_client_index(const struct mei_device *dev, uuid_le cuuid);
+
+/*
+ * Register Access Function
+ */
+
+/**
+ * mei_reg_read - Reads 32bit data from the mei device
+ *
+ * @dev: the device structure
+ * @offset: offset from which to read the data
+ *
+ * returns the byte read.
+ */
+static inline u32 mei_reg_read(struct mei_device *dev,
+				unsigned long offset)
+{
+	return ioread32(dev->mem_addr + offset);
+}
+
+/**
+ * mei_reg_write - Writes 32bit data to the mei device
+ *
+ * @dev: the device structure
+ * @offset: offset from which to write the data
+ * @value: the byte to write
+ */
+static inline void mei_reg_write(struct mei_device *dev,
+				unsigned long offset, u32 value)
+{
+	iowrite32(value, dev->mem_addr + offset);
+}
+
+/**
+ * mei_hcsr_read - Reads 32bit data from the host CSR
+ *
+ * @dev: the device structure
+ *
+ * returns the byte read.
+ */
+static inline u32 mei_hcsr_read(struct mei_device *dev)
+{
+	return mei_reg_read(dev, H_CSR);
+}
+
+/**
+ * mei_mecsr_read - Reads 32bit data from the ME CSR
+ *
+ * @dev: the device structure
+ *
+ * returns ME_CSR_HA register value (u32)
+ */
+static inline u32 mei_mecsr_read(struct mei_device *dev)
+{
+	return mei_reg_read(dev, ME_CSR_HA);
+}
+
+/**
+ * get_me_cb_rw - Reads 32bit data from the mei ME_CB_RW register
+ *
+ * @dev: the device structure
+ *
+ * returns ME_CB_RW register value (u32)
+ */
+static inline u32 mei_mecbrw_read(struct mei_device *dev)
+{
+	return mei_reg_read(dev, ME_CB_RW);
+}
+
+
+/*
+ * mei interface function prototypes
+ */
+void mei_hcsr_set(struct mei_device *dev);
+void mei_csr_clear_his(struct mei_device *dev);
+
+void mei_enable_interrupts(struct mei_device *dev);
+void mei_disable_interrupts(struct mei_device *dev);
+
+/**
+ * mei_fe_same_id - tells if file private data have same id
+ *
+ * @fe1: private data of 1. file object
+ * @fe2: private data of 2. file object
+ *
+ * returns !=0 - if ids are the same, 0 - if differ.
+ */
+static inline int mei_fe_same_id(const struct mei_cl *fe1,
+				  const struct mei_cl *fe2)
+{
+	return ((fe1->host_client_id == fe2->host_client_id) &&
+		(fe1->me_client_id == fe2->me_client_id));
+}
+
+#endif
diff -druN linux-2.6.39-libre/drivers/staging/mei/mei.h linux-3.0-rc7-libre/drivers/staging/mei/mei.h
--- linux-2.6.39-libre/drivers/staging/mei/mei.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/staging/mei/mei.h	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,105 @@
+/*
+
+  Intel Management Engine Interface (Intel MEI) Linux driver
+  Intel MEI Interface Header
+
+  This file is provided under a dual BSD/GPLv2 license.  When using or
+  redistributing this file, you may do so under either license.
+
+  GPL LICENSE SUMMARY
+
+  Copyright(c) 2003-2011 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.
+
+  Contact Information:
+	  Intel Corporation.
+	  linux-mei@linux.intel.com
+	  http://www.intel.com
+
+
+  BSD LICENSE
+
+  Copyright(c) 2003-2011 Intel Corporation. All rights reserved.
+  All rights reserved.
+
+  Redistribution and use in source and binary forms, with or without
+  modification, are permitted provided that the following conditions
+  are met:
+
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above copyright
+      notice, this list of conditions and the following disclaimer in
+      the documentation and/or other materials provided with the
+      distribution.
+    * Neither the name of Intel Corporation nor the names of its
+      contributors may be used to endorse or promote products derived
+      from this software without specific prior written permission.
+
+  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*/
+
+
+#ifndef _LINUX_MEI_H
+#define _LINUX_MEI_H
+
+#include <linux/uuid.h>
+
+/*
+ * This IOCTL is used to associate the current file descriptor with a
+ * FW Client (given by UUID). This opens a communication channel
+ * between a host client and a FW client. From this point every read and write
+ * will communicate with the associated FW client.
+ * Only in close() (file_operation release()) the communication between
+ * the clients is disconnected
+ *
+ * The IOCTL argument is a struct with a union the contains
+ * the input parameter and the output parameter for this IOCTL.
+ *
+ * The input parameter is UUID of the FW Client.
+ * The output parameter is the properties of the FW client
+ * (FW protocol version and max message size).
+ *
+ */
+#define IOCTL_MEI_CONNECT_CLIENT \
+	_IOWR('H' , 0x01, struct mei_connect_client_data)
+
+/*
+ * Intel MEI client information struct
+ */
+struct mei_client {
+	__u32 max_msg_length;
+	__u8 protocol_version;
+	__u8 reserved[3];
+};
+
+/*
+ * IOCTL Connect Client Data structure
+ */
+struct mei_connect_client_data {
+	union {
+		uuid_le in_client_uuid;
+		struct mei_client out_client_properties;
+	};
+};
+
+#endif /* _LINUX_MEI_H  */
diff -druN linux-2.6.39-libre/drivers/staging/mei/mei.txt linux-3.0-rc7-libre/drivers/staging/mei/mei.txt
--- linux-2.6.39-libre/drivers/staging/mei/mei.txt	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/staging/mei/mei.txt	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,189 @@
+Intel MEI
+=======================
+
+Introduction
+=======================
+
+The Intel Management Engine (Intel ME) is an isolated and
+protected computing resource (Coprocessor) residing inside
+Intel chipsets. The Intel ME provides support for computer/IT
+management features.
+The Feature set depends on the Intel chipset SKU.
+
+The Intel Management Engine Interface (Intel MEI, previously known
+as HECI) is the interface between the Host and Intel ME.
+This interface is exposed to the host as a PCI device.
+The Intel MEI Driver is in charge of the communication channel
+between a host application and the ME feature.
+
+Each Intel ME feature (Intel ME Client) is addressed by
+GUID/UUID and each feature defines its own protocol.
+The protocol is message-based with a header and payload up to
+512 bytes.
+
+[place holder to URL to protocol definitions]
+
+Prominent usage of the Interface is to communicate with
+Intel Active Management Technology (Intel AMT)
+implemented in firmware running on the Intel ME.
+
+Intel AMT provides the ability to manage a host remotely out-of-band (OOB)
+even when the host processor has crashed or is in a sleep state.
+
+Some examples of Intel AMT usage are:
+   - Monitoring hardware state and platform components
+   - Remote power off/on (useful for green computing or overnight IT maintenance)
+   - OS updates
+   - Storage of useful platform information such as software assets
+   - built-in hardware KVM
+   - selective network isolation of Ethernet and IP protocol flows based on
+     policies set by a remote management console
+   - IDE device redirection from remote management console
+
+Intel AMT (OOB) communication is based on SOAP (deprecated
+starting with Release 6.0) over HTTP/HTTPS or WS-Management protocol
+over HTTP and HTTPS that are received from a remote
+management console application.
+
+For more information about Intel AMT:
+http://software.intel.com/sites/manageability/AMT_Implementation_and_Reference_Guide/WordDocuments/aboutintelamt.htm
+
+
+MEI Driver
+=======================
+
+The driver exposes a character device called /dev/mei.
+
+An application maintains communication with an ME feature while
+/dev/mei is open. The binding to a specific features is performed
+by calling MEI_CONNECT_CLIENT_IOCTL, which passes the desired UUID.
+The number of instances of an ME feature that can be opened
+at the same time depends on the ME feature, but most of the
+features allow only a single instance.
+
+
+The Intel AMT Host Interface (AMTHI) feature requires multiple
+simultaneous user applications, therefore the MEI driver handles
+this internally by maintaining request queues for the applications.
+
+The driver is oblivious to data that are passed between
+
+Because some of the ME features can change the system
+configuration, the driver by default allows only privileged
+user to access it.
+
+A Code snippet for application communicating with AMTHI client:
+	struct mei_connect_client_data data;
+	fd = open(MEI_DEVICE);
+
+	data.d.in_client_uuid = AMTHI_UUID;
+
+	ioctl(fd, IOCTL_MEI_CONNECT_CLIENT, &data);
+
+	printf(“Ver=%d, MaxLen=%ld\n”,
+			data.d.in_client_uuid.protocol_version,
+			data.d.in_client_uuid.max_msg_length);
+
+	[...]
+
+	write(fd, amthi_req_data, amthi_req_data_len);
+
+	[...]
+
+	read(fd, &amthi_res_data, amthi_res_data_len);
+
+	[...]
+	close(fd);
+
+ME Applications:
+==============
+
+1) Intel Local Management Service (Intel LMS)
+	Applications running locally on the platform communicate with
+	Intel AMT Release 2.0 and later releases in the same way
+	that network applications do via SOAP over HTTP (deprecated
+	starting with Release 6.0) or with WS-Management over SOAP over
+	HTTP. which means that some Intel AMT feature can be access
+	from a local application using same Network interface as for
+	remote application.
+
+	When a local application sends a message addressed to the local
+	Intel AMT host name, the Local Manageability Service (LMS),
+	which listens for traffic directed to the host name, intercepts
+	the message and routes it to the Intel Management Engine Interface.
+	For more information:
+	http://software.intel.com/sites/manageability/AMT_Implementation_and_
+	Reference_Guide/WordDocuments/localaccess1.htm
+
+	The LMS opens a connection using the MEI driver to the LMS
+	FW feature using a defined UUID and then communicates with the
+	feature using a protocol
+	called Intel(R) AMT Port Forwarding Protocol (APF protocol).
+	The protocol is used to maintain multiple sessions with
+	Intel AMT from a single application.
+	See the protocol specification in
+	the Intel(R) AMT Implementation and Reference Guide
+	http://software.intel.com/sites/manageability/AMT_Implementation_and_Reference_Guide/HTMLDocuments/MPSDocuments/Intel%20AMT%20Port%20Forwarding%20Protocol%20Reference%20Manual.pdf
+
+  2) Intel AMT Remote configuration using a Local Agent:
+	A Local Agent enables IT personnel to configure Intel AMT out-of-the-box
+	without requiring installing additional data to enable setup.
+	The remote configuration process may involve an ISV-developed remote
+	configuration agent that runs on the host.
+	For more information:
+	http://software.intel.com/sites/manageability/AMT_Implementation_and_Reference_Guide/WordDocuments/remoteconfigurationwithalocalagent.htm
+
+	How the Local Agent Works (including Command structs):
+	http://software.intel.com/sites/manageability/AMT_Implementation_and_Reference_Guide/WordDocuments/howthelocalagentsampleworks.htm
+
+Intel AMT OS Health Watchdog:
+=============================
+The Intel AMT Watchdog is an OS Health (Hang/Crash) watchdog.
+Whenever the OS hangs or crashes, Intel AMT will send an event
+to whoever subscribed to this event. This mechanism means that
+IT knows when a platform crashes even when there is a hard failure
+on the host.
+The AMT Watchdog is composed of two parts:
+	1) FW Feature - that receives the heartbeats
+	   and sends an event when the heartbeats stop.
+	2) MEI driver – connects to the watchdog (WD) feature,
+	   configures the watchdog and sends the heartbeats.
+
+The MEI driver configures the Watchdog to expire by default
+every 120sec unless set by the user using module parameters.
+The Driver then sends heartbeats every 2sec.
+
+If WD feature does not exist (i.e. the connection failed),
+the MEI driver will disable the sending of heartbeats.
+
+Module Parameters
+=================
+watchdog_timeout - the user can use this module parameter
+to change the watchdog timeout setting.
+
+This value sets the Intel AMT watchdog timeout interval in seconds;
+the default value is 120sec.
+in order to disable the watchdog activites set the value to 0.
+Normal values should be between 120 and 65535
+
+Supported Chipsets:
+==================
+7 Series Chipset Family
+6 Series Chipset Family
+5 Series Chipset Family
+4 Series Chipset Family
+Mobile 4 Series Chipset Family
+ICH9
+82946GZ/GL
+82G35 Express
+82Q963/Q965
+82P965/G965
+Mobile PM965/GM965
+Mobile GME965/GLE960
+82Q35 Express
+82G33/G31/P35/P31 Express
+82Q33 Express
+82X38/X48 Express
+
+---
+linux-mei@linux.intel.com
diff -druN linux-2.6.39-libre/drivers/staging/mei/mei_version.h linux-3.0-rc7-libre/drivers/staging/mei/mei_version.h
--- linux-2.6.39-libre/drivers/staging/mei/mei_version.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/staging/mei/mei_version.h	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,31 @@
+/*
+ *
+ * Intel Management Engine Interface (Intel MEI) Linux driver
+ * Copyright (c) 2003-2011, 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.
+ *
+ */
+
+
+#ifndef MEI_VERSION_H
+#define MEI_VERSION_H
+
+#define MAJOR_VERSION		7
+#define MINOR_VERSION		1
+#define QUICK_FIX_NUMBER	20
+#define VER_BUILD		1
+
+#define MEI_DRV_VER1 __stringify(MAJOR_VERSION) "." __stringify(MINOR_VERSION)
+#define MEI_DRV_VER2 __stringify(QUICK_FIX_NUMBER) "." __stringify(VER_BUILD)
+
+#define MEI_DRIVER_VERSION	MEI_DRV_VER1 "." MEI_DRV_VER2
+
+#endif
diff -druN linux-2.6.39-libre/drivers/staging/mei/TODO linux-3.0-rc7-libre/drivers/staging/mei/TODO
--- linux-2.6.39-libre/drivers/staging/mei/TODO	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/staging/mei/TODO	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,17 @@
+TODO:
+	- Create in-kernel Client API. Examples of in-kernel clients are watchdog and AMTHI.
+	- ME Watchdog Driver to expose standard Linux watchdog interface
+	- Rewrite AMTHI to use in-kernel client interface
+	- Cleanup init and probe functions
+	- Review BUG/BUG_ON usage
+	- Cleanup and reorganize header files
+	- Rewrite client data structure
+	- Make state machine more readable
+	- Add mei.txt with driver explanation and it's driver
+	- Fix Kconfig
+	- Cleanup and split the timer function
+Upon Unstaging:
+	- move mei.h to include/linux/mei.h
+	- Documentation/ioctl/ioctl-number.txt
+	- drop mei_version.h
+	- Updated MAINTAINERS
diff -druN linux-2.6.39-libre/drivers/staging/mei/wd.c linux-3.0-rc7-libre/drivers/staging/mei/wd.c
--- linux-2.6.39-libre/drivers/staging/mei/wd.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/staging/mei/wd.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,188 @@
+/*
+ *
+ * Intel Management Engine Interface (Intel MEI) Linux driver
+ * Copyright (c) 2003-2011, Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ */
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/device.h>
+#include <linux/pci.h>
+#include <linux/sched.h>
+
+#include "mei_dev.h"
+#include "hw.h"
+#include "interface.h"
+#include "mei.h"
+
+/*
+ * MEI Watchdog Module Parameters
+ */
+static u16 watchdog_timeout = AMT_WD_VALUE;
+module_param(watchdog_timeout, ushort, 0);
+MODULE_PARM_DESC(watchdog_timeout,
+		"Intel(R) AMT Watchdog timeout value in seconds. (default="
+					__MODULE_STRING(AMT_WD_VALUE)
+					", disable=0)");
+
+static const u8 mei_start_wd_params[] = { 0x02, 0x12, 0x13, 0x10 };
+static const u8 mei_stop_wd_params[] = { 0x02, 0x02, 0x14, 0x10 };
+
+const u8 mei_wd_state_independence_msg[3][4] = {
+	{0x05, 0x02, 0x51, 0x10},
+	{0x05, 0x02, 0x52, 0x10},
+	{0x07, 0x02, 0x01, 0x10}
+};
+
+/* UUIDs for AMT F/W clients */
+const uuid_le mei_wd_guid = UUID_LE(0x05B79A6F, 0x4628, 0x4D7F, 0x89,
+						0x9D, 0xA9, 0x15, 0x14, 0xCB,
+						0x32, 0xAB);
+
+
+void mei_wd_start_setup(struct mei_device *dev)
+{
+	dev_dbg(&dev->pdev->dev, "dev->wd_timeout=%d.\n", dev->wd_timeout);
+	memcpy(dev->wd_data, mei_start_wd_params, MEI_WD_PARAMS_SIZE);
+	memcpy(dev->wd_data + MEI_WD_PARAMS_SIZE,
+		&dev->wd_timeout, sizeof(u16));
+}
+
+/**
+ * host_init_wd - mei initialization wd.
+ *
+ * @dev: the device structure
+ */
+void mei_wd_host_init(struct mei_device *dev)
+{
+	mei_init_file_private(&dev->wd_cl, dev);
+
+	/* look for WD client and connect to it */
+	dev->wd_cl.state = MEI_FILE_DISCONNECTED;
+	dev->wd_timeout = watchdog_timeout;
+
+	if (dev->wd_timeout > 0) {
+		mei_wd_start_setup(dev);
+		/* find ME WD client */
+		mei_find_me_client_update_filext(dev, &dev->wd_cl,
+					&mei_wd_guid, MEI_WD_HOST_CLIENT_ID);
+
+		dev_dbg(&dev->pdev->dev, "check wd_cl\n");
+		if (MEI_FILE_CONNECTING == dev->wd_cl.state) {
+			if (!mei_connect(dev, &dev->wd_cl)) {
+				dev_dbg(&dev->pdev->dev, "Failed to connect to WD client\n");
+				dev->wd_cl.state = MEI_FILE_DISCONNECTED;
+				dev->wd_cl.host_client_id = 0;
+				host_init_iamthif(dev) ;
+			} else {
+				dev->wd_cl.timer_count = CONNECT_TIMEOUT;
+			}
+		} else {
+			dev_dbg(&dev->pdev->dev, "Failed to find WD client\n");
+			host_init_iamthif(dev) ;
+		}
+	} else {
+		dev->wd_bypass = true;
+		dev_dbg(&dev->pdev->dev, "WD requested to be disabled\n");
+		host_init_iamthif(dev) ;
+	}
+}
+
+/**
+ * mei_wd_send - sends watch dog message to fw.
+ *
+ * @dev: the device structure
+ *
+ * returns 0 if success,
+ *	-EIO when message send fails
+ *	-EINVAL when invalid message is to be sent
+ */
+int mei_wd_send(struct mei_device *dev)
+{
+	struct mei_msg_hdr *mei_hdr;
+
+	mei_hdr = (struct mei_msg_hdr *) &dev->wr_msg_buf[0];
+	mei_hdr->host_addr = dev->wd_cl.host_client_id;
+	mei_hdr->me_addr = dev->wd_cl.me_client_id;
+	mei_hdr->msg_complete = 1;
+	mei_hdr->reserved = 0;
+
+	if (!memcmp(dev->wd_data, mei_start_wd_params, MEI_WD_PARAMS_SIZE))
+		mei_hdr->length = MEI_START_WD_DATA_SIZE;
+	else if (!memcmp(dev->wd_data, mei_stop_wd_params, MEI_WD_PARAMS_SIZE))
+		mei_hdr->length = MEI_WD_PARAMS_SIZE;
+	else
+		return -EINVAL;
+
+	if (mei_write_message(dev, mei_hdr, dev->wd_data, mei_hdr->length))
+		return 0;
+	return -EIO;
+}
+
+int mei_wd_stop(struct mei_device *dev, bool preserve)
+{
+	int ret;
+	u16 wd_timeout = dev->wd_timeout;
+
+	cancel_delayed_work(&dev->wd_work);
+	if (dev->wd_cl.state != MEI_FILE_CONNECTED || !dev->wd_timeout)
+		return 0;
+
+	dev->wd_timeout = 0;
+	dev->wd_due_counter = 0;
+	memcpy(dev->wd_data, mei_stop_wd_params, MEI_WD_PARAMS_SIZE);
+	dev->stop = 1;
+
+	ret = mei_flow_ctrl_creds(dev, &dev->wd_cl);
+	if (ret < 0)
+		goto out;
+
+	if (ret && dev->mei_host_buffer_is_empty) {
+		ret = 0;
+		dev->mei_host_buffer_is_empty = 0;
+
+		if (!mei_wd_send(dev)) {
+			ret = mei_flow_ctrl_reduce(dev, &dev->wd_cl);
+			if (ret)
+				goto out;
+		} else {
+			dev_dbg(&dev->pdev->dev, "send stop WD failed\n");
+		}
+
+		dev->wd_pending = 0;
+	} else {
+		dev->wd_pending = 1;
+	}
+	dev->wd_stopped = 0;
+	mutex_unlock(&dev->device_lock);
+
+	ret = wait_event_interruptible_timeout(dev->wait_stop_wd,
+					dev->wd_stopped, 10 * HZ);
+	mutex_lock(&dev->device_lock);
+	if (dev->wd_stopped) {
+		dev_dbg(&dev->pdev->dev, "stop wd complete ret=%d.\n", ret);
+		ret = 0;
+	} else {
+		if (!ret)
+			ret = -ETIMEDOUT;
+		dev_warn(&dev->pdev->dev,
+			"stop wd failed to complete ret=%d.\n", ret);
+	}
+
+	if (preserve)
+		dev->wd_timeout = wd_timeout;
+
+out:
+	return ret;
+}
+
diff -druN linux-2.6.39-libre/drivers/staging/nvec/Kconfig linux-3.0-rc7-libre/drivers/staging/nvec/Kconfig
--- linux-2.6.39-libre/drivers/staging/nvec/Kconfig	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/staging/nvec/Kconfig	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,27 @@
+config MFD_NVEC
+	bool "NV Tegra Embedded Controller SMBus Interface"
+	depends on I2C && GPIOLIB && ARCH_TEGRA
+	help
+	    Say Y here to enable support for a nVidia compliant embedded
+	    controller.
+
+config KEYBOARD_NVEC
+	bool "Keyboard on nVidia compliant EC"
+	depends on MFD_NVEC
+	help
+	  Say Y here to enable support for a keyboard connected to 
+	  a nVidia compliant embedded controller.
+
+config SERIO_NVEC_PS2
+	bool "PS2 on nVidia EC"
+	depends on MFD_NVEC
+	help
+	  Say Y here to enable support for a Touchpad / Mouse connected
+	  to a nVidia compliant embedded controller.
+
+config NVEC_POWER
+	bool "NVEC charger and battery"
+	depends on MFD_NVEC
+	help
+	  Say Y to enable support for battery and charger interface for
+	  nVidia compliant embedded controllers.
diff -druN linux-2.6.39-libre/drivers/staging/nvec/Makefile linux-3.0-rc7-libre/drivers/staging/nvec/Makefile
--- linux-2.6.39-libre/drivers/staging/nvec/Makefile	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/staging/nvec/Makefile	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,4 @@
+obj-$(CONFIG_SERIO_NVEC_PS2)	+= nvec_ps2.o
+obj-$(CONFIG_MFD_NVEC)		+= nvec.o
+obj-$(CONFIG_NVEC_POWER) 	+= nvec_power.o
+obj-$(CONFIG_KEYBOARD_NVEC) 	+= nvec_kbd.o
diff -druN linux-2.6.39-libre/drivers/staging/nvec/nvec.c linux-3.0-rc7-libre/drivers/staging/nvec/nvec.c
--- linux-2.6.39-libre/drivers/staging/nvec/nvec.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/staging/nvec/nvec.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,468 @@
+// #define DEBUG
+
+/* ToDo list (incomplete, unorderd)
+	- convert mouse, keyboard, and power to platform devices
+*/
+
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <linux/completion.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/slab.h>
+#include <linux/gpio.h>
+#include <linux/serio.h>
+#include <linux/delay.h>
+#include <linux/input.h>
+#include <linux/workqueue.h>
+#include <linux/clk.h>
+#include <mach/iomap.h>
+#include <mach/clk.h>
+#include <linux/semaphore.h>
+#include <linux/list.h>
+#include <linux/notifier.h>
+#include <linux/workqueue.h>
+#include <linux/platform_device.h>
+#include "nvec.h"
+
+static unsigned char EC_DISABLE_EVENT_REPORTING[] =	{'\x04','\x00','\x00'};
+static unsigned char EC_ENABLE_EVENT_REPORTING[] =	{'\x04','\x00','\x01'};
+static unsigned char EC_GET_FIRMWARE_VERSION[] =	{'\x07','\x15'};
+
+static struct nvec_chip *nvec_power_handle;
+
+int nvec_register_notifier(struct nvec_chip *nvec, struct notifier_block *nb,
+				unsigned int events)
+{
+	return atomic_notifier_chain_register(&nvec->notifier_list, nb);
+}
+EXPORT_SYMBOL_GPL(nvec_register_notifier);
+
+static int nvec_status_notifier(struct notifier_block *nb, unsigned long event_type,
+				void *data)
+{
+	unsigned char *msg = (unsigned char *)data;
+	int i;
+
+	if(event_type != NVEC_CNTL)
+		return NOTIFY_DONE;
+
+	printk("unhandled msg type %ld, payload: ", event_type);
+	for (i = 0; i < msg[1]; i++)
+		printk("%0x ", msg[i+2]);
+	printk("\n");
+
+	return NOTIFY_OK;
+}
+
+void nvec_write_async(struct nvec_chip *nvec, unsigned char *data, short size)
+{
+	struct nvec_msg *msg = kzalloc(sizeof(struct nvec_msg), GFP_NOWAIT);
+
+	msg->data = kzalloc(size, GFP_NOWAIT);
+	msg->data[0] = size;
+	memcpy(msg->data + 1, data, size);
+	msg->size = size + 1;
+	msg->pos = 0;
+	INIT_LIST_HEAD(&msg->node);
+
+	list_add_tail(&msg->node, &nvec->tx_data);
+
+	gpio_set_value(nvec->gpio, 0);
+}
+EXPORT_SYMBOL(nvec_write_async);
+
+static void nvec_request_master(struct work_struct *work)
+{
+	struct nvec_chip *nvec = container_of(work, struct nvec_chip, tx_work);
+
+	if(!list_empty(&nvec->tx_data)) {
+		gpio_set_value(nvec->gpio, 0);
+	}
+}
+
+static int parse_msg(struct nvec_chip *nvec, struct nvec_msg *msg)
+{
+	int i;
+
+	if((msg->data[0] & 1<<7) == 0 && msg->data[3]) {
+		dev_err(nvec->dev, "ec responded %02x %02x %02x %02x\n", msg->data[0],
+			msg->data[1], msg->data[2], msg->data[3]);
+		return -EINVAL;
+	}
+
+	if ((msg->data[0] >> 7 ) == 1 && (msg->data[0] & 0x0f) == 5)
+	{
+		dev_warn(nvec->dev, "ec system event ");
+		for (i=0; i < msg->data[1]; i++)
+			dev_warn(nvec->dev, "%02x ", msg->data[2+i]);
+		dev_warn(nvec->dev, "\n");
+	}
+
+	atomic_notifier_call_chain(&nvec->notifier_list, msg->data[0] & 0x8f, msg->data);
+
+	return 0;
+}
+
+static struct nvec_msg *nvec_write_sync(struct nvec_chip *nvec, unsigned char *data, short size)
+{
+	down(&nvec->sync_write_mutex);
+
+	nvec->sync_write_pending = (data[1] << 8) + data[0];
+	nvec_write_async(nvec, data, size);
+
+	dev_dbg(nvec->dev, "nvec_sync_write: 0x%04x\n", nvec->sync_write_pending);
+	wait_for_completion(&nvec->sync_write);
+	dev_dbg(nvec->dev, "nvec_sync_write: pong!\n");
+
+	up(&nvec->sync_write_mutex);
+
+	return nvec->last_sync_msg;
+}
+
+/* RX worker */
+static void nvec_dispatch(struct work_struct *work)
+{
+	struct nvec_chip *nvec = container_of(work, struct nvec_chip, rx_work);
+	struct nvec_msg *msg;
+
+	while(!list_empty(&nvec->rx_data))
+	{
+		msg = list_first_entry(&nvec->rx_data, struct nvec_msg, node);
+		list_del_init(&msg->node);
+
+		if(nvec->sync_write_pending == (msg->data[2] << 8) + msg->data[0])
+		{
+			dev_dbg(nvec->dev, "sync write completed!\n");
+			nvec->sync_write_pending = 0;
+			nvec->last_sync_msg = msg;
+			complete(&nvec->sync_write);
+		} else {
+			parse_msg(nvec, msg);
+			if((!msg) || (!msg->data))
+				dev_warn(nvec->dev, "attempt access zero pointer");
+			else {
+				kfree(msg->data);
+				kfree(msg);
+			}
+		}
+	}
+}
+
+static irqreturn_t i2c_interrupt(int irq, void *dev)
+{
+	unsigned long status;
+	unsigned long received;
+	unsigned char to_send;
+	struct nvec_msg *msg;
+	struct nvec_chip *nvec = (struct nvec_chip *)dev;
+	unsigned char *i2c_regs = nvec->i2c_regs;
+
+	status = readl(i2c_regs + I2C_SL_STATUS);
+
+	if(!(status & I2C_SL_IRQ))
+	{
+		dev_warn(nvec->dev, "nvec Spurious IRQ\n");
+		//Yup, handled. ahum.
+		goto handled;
+	}
+	if(status & END_TRANS && !(status & RCVD))
+	{
+		//Reenable IRQ only when even has been sent
+		//printk("Write sequence ended !\n");
+                //parse_msg(nvec);
+		nvec->state = NVEC_WAIT;
+		if(nvec->rx->size > 1)
+		{
+			list_add_tail(&nvec->rx->node, &nvec->rx_data);
+			schedule_work(&nvec->rx_work);
+		} else {
+			kfree(nvec->rx->data);
+			kfree(nvec->rx);
+		}
+		return IRQ_HANDLED;
+	} else if(status & RNW)
+	{
+		// Work around for AP20 New Slave Hw Bug. Give 1us extra.
+		// nvec/smbus/nvec_i2c_transport.c in NV`s crap for reference
+		if(status & RCVD)
+			udelay(3);
+
+		if(status & RCVD)
+		{
+			nvec->state = NVEC_WRITE;
+			//Master wants something from us. New communication
+//			dev_dbg(nvec->dev, "New read comm!\n");
+		} else {
+			//Master wants something from us from a communication we've already started
+//			dev_dbg(nvec->dev, "Read comm cont !\n");
+		}
+		//if(msg_pos<msg_size) {
+		if(list_empty(&nvec->tx_data))
+		{
+			dev_err(nvec->dev, "nvec empty tx - sending no-op\n");
+			to_send = 0x8a;
+			nvec_write_async(nvec, "\x07\x02", 2);
+//			to_send = 0x01;
+		} else {
+			msg = list_first_entry(&nvec->tx_data, struct nvec_msg, node);
+			if(msg->pos < msg->size) {
+				to_send = msg->data[msg->pos];
+				msg->pos++;
+			} else {
+				dev_err(nvec->dev, "nvec crap! %d\n", msg->size);
+				to_send = 0x01;
+			}
+
+			if(msg->pos >= msg->size)
+			{
+				list_del_init(&msg->node);
+				kfree(msg->data);
+				kfree(msg);
+				schedule_work(&nvec->tx_work);
+				nvec->state = NVEC_WAIT;
+			}
+		}
+		writel(to_send, i2c_regs + I2C_SL_RCVD);
+
+		gpio_set_value(nvec->gpio, 1);
+
+		dev_dbg(nvec->dev, "nvec sent %x\n", to_send);
+
+		goto handled;
+	} else {
+		received = readl(i2c_regs + I2C_SL_RCVD);
+		//Workaround?
+		if(status & RCVD) {
+			writel(0, i2c_regs + I2C_SL_RCVD);
+			goto handled;
+		}
+
+		if (nvec->state == NVEC_WAIT)
+		{
+			nvec->state = NVEC_READ;
+			msg = kzalloc(sizeof(struct nvec_msg), GFP_NOWAIT);
+			msg->data = kzalloc(32, GFP_NOWAIT);
+			INIT_LIST_HEAD(&msg->node);
+			nvec->rx = msg;
+		} else
+			msg = nvec->rx;
+
+		BUG_ON(msg->pos > 32);
+
+		msg->data[msg->pos] = received;
+		msg->pos++;
+		msg->size = msg->pos;
+		dev_dbg(nvec->dev, "Got %02lx from Master (pos: %d)!\n", received, msg->pos);
+	}
+handled:
+	return IRQ_HANDLED;
+}
+
+static int __devinit nvec_add_subdev(struct nvec_chip *nvec, struct nvec_subdev *subdev)
+{
+	struct platform_device *pdev;
+
+	pdev = platform_device_alloc(subdev->name, subdev->id);
+	pdev->dev.parent = nvec->dev;
+	pdev->dev.platform_data = subdev->platform_data;
+
+	return platform_device_add(pdev);
+}
+
+static void tegra_init_i2c_slave(struct nvec_platform_data *pdata, unsigned char *i2c_regs,
+					struct clk *i2c_clk)
+{
+	u32 val;
+
+	clk_enable(i2c_clk);
+	tegra_periph_reset_assert(i2c_clk);
+	udelay(2);
+	tegra_periph_reset_deassert(i2c_clk);
+
+	writel(pdata->i2c_addr>>1, i2c_regs + I2C_SL_ADDR1);
+	writel(0, i2c_regs + I2C_SL_ADDR2);
+
+	writel(0x1E, i2c_regs + I2C_SL_DELAY_COUNT);
+	val = I2C_CNFG_NEW_MASTER_SFM | I2C_CNFG_PACKET_MODE_EN |
+		(0x2 << I2C_CNFG_DEBOUNCE_CNT_SHIFT);
+	writel(val, i2c_regs + I2C_CNFG);
+	writel(I2C_SL_NEWL, i2c_regs + I2C_SL_CNFG);
+
+	clk_disable(i2c_clk);
+}
+
+static void nvec_power_off(void)
+{
+	nvec_write_async(nvec_power_handle, EC_DISABLE_EVENT_REPORTING, 3);
+	nvec_write_async(nvec_power_handle, "\x04\x01", 2);
+}
+
+static int __devinit tegra_nvec_probe(struct platform_device *pdev)
+{
+	int err, i, ret;
+	struct clk *i2c_clk;
+	struct nvec_platform_data *pdata = pdev->dev.platform_data;
+	struct nvec_chip *nvec;
+	struct nvec_msg *msg;
+	unsigned char *i2c_regs;
+
+	nvec = kzalloc(sizeof(struct nvec_chip), GFP_KERNEL);
+	if(nvec == NULL) {
+		dev_err(&pdev->dev, "failed to reserve memory\n");
+		return -ENOMEM;
+	}
+	platform_set_drvdata(pdev, nvec);
+	nvec->dev = &pdev->dev;
+	nvec->gpio = pdata->gpio;
+	nvec->irq = pdata->irq;
+
+/*
+	i2c_clk=clk_get_sys(NULL, "i2c");
+	if(IS_ERR_OR_NULL(i2c_clk))
+		printk(KERN_ERR"No such clock tegra-i2c.2\n");
+	else
+		clk_enable(i2c_clk);
+*/
+	i2c_regs = ioremap(pdata->base, pdata->size);
+	if(!i2c_regs) {
+		dev_err(nvec->dev, "failed to ioremap registers\n");
+		goto failed;
+	}
+
+	nvec->i2c_regs = i2c_regs;
+
+	i2c_clk = clk_get_sys(pdata->clock, NULL);
+	if(IS_ERR_OR_NULL(i2c_clk)) {
+		dev_err(nvec->dev, "failed to get clock tegra-i2c.2\n");
+		goto failed;
+	}
+
+	tegra_init_i2c_slave(pdata, i2c_regs, i2c_clk);
+
+	err = request_irq(nvec->irq, i2c_interrupt, IRQF_DISABLED, "nvec", nvec);
+	if(err) {
+		dev_err(nvec->dev, "couldn't request irq");
+		goto failed;
+	}
+
+	clk_enable(i2c_clk);
+	clk_set_rate(i2c_clk, 8*80000);
+
+	/* Set the gpio to low when we've got something to say */
+	err = gpio_request(nvec->gpio, "nvec gpio");
+	if(err < 0)
+		dev_err(nvec->dev, "couldn't request gpio\n");
+
+	tegra_gpio_enable(nvec->gpio);
+	gpio_direction_output(nvec->gpio, 1);
+	gpio_set_value(nvec->gpio, 1);
+
+	ATOMIC_INIT_NOTIFIER_HEAD(&nvec->notifier_list);
+
+	init_completion(&nvec->sync_write);
+	sema_init(&nvec->sync_write_mutex, 1);
+	INIT_LIST_HEAD(&nvec->tx_data);
+	INIT_LIST_HEAD(&nvec->rx_data);
+	INIT_WORK(&nvec->rx_work, nvec_dispatch);
+	INIT_WORK(&nvec->tx_work, nvec_request_master);
+
+	/* enable event reporting */
+	nvec_write_async(nvec, EC_ENABLE_EVENT_REPORTING,
+				sizeof(EC_ENABLE_EVENT_REPORTING));
+
+	nvec_kbd_init(nvec);
+#ifdef CONFIG_SERIO_NVEC_PS2
+	nvec_ps2(nvec);
+#endif
+
+        /* setup subdevs */
+	for (i = 0; i < pdata->num_subdevs; i++) {
+		ret = nvec_add_subdev(nvec, &pdata->subdevs[i]);
+	}
+
+	nvec->nvec_status_notifier.notifier_call = nvec_status_notifier;
+	nvec_register_notifier(nvec, &nvec->nvec_status_notifier, 0);
+
+	nvec_power_handle = nvec;
+	pm_power_off = nvec_power_off;
+
+	/* Get Firmware Version */
+	msg = nvec_write_sync(nvec, EC_GET_FIRMWARE_VERSION,
+		sizeof(EC_GET_FIRMWARE_VERSION));
+
+	dev_warn(nvec->dev, "ec firmware version %02x.%02x.%02x / %02x\n",
+			msg->data[4], msg->data[5], msg->data[6], msg->data[7]);
+
+	kfree(msg->data);
+	kfree(msg);
+
+	/* unmute speakers? */
+	nvec_write_async(nvec, "\x0d\x10\x59\x94", 4);
+
+	/* enable lid switch event */
+	nvec_write_async(nvec, "\x01\x01\x01\x00\x00\x02\x00", 7);
+
+	/* enable power button event */
+	nvec_write_async(nvec, "\x01\x01\x01\x00\x00\x80\x00", 7);
+
+	return 0;
+
+failed:
+	kfree(nvec);
+	return -ENOMEM;
+}
+
+static int __devexit tegra_nvec_remove(struct platform_device *pdev)
+{
+	// TODO: unregister
+	return 0;
+}
+
+#ifdef CONFIG_PM
+
+static int tegra_nvec_suspend(struct platform_device *pdev, pm_message_t state)
+{
+	struct nvec_chip *nvec = platform_get_drvdata(pdev);
+
+	dev_dbg(nvec->dev, "suspending\n");
+	nvec_write_async(nvec, EC_DISABLE_EVENT_REPORTING, 3);
+	nvec_write_async(nvec, "\x04\x02", 2);
+
+	return 0;
+}
+
+static int tegra_nvec_resume(struct platform_device *pdev) {
+
+	struct nvec_chip *nvec = platform_get_drvdata(pdev);
+
+	dev_dbg(nvec->dev, "resuming\n");
+	nvec_write_async(nvec, EC_ENABLE_EVENT_REPORTING, 3);
+
+	return 0;
+}
+
+#else
+#define tegra_nvec_suspend NULL
+#define tegra_nvec_resume NULL
+#endif
+
+static struct platform_driver nvec_device_driver =
+{
+	.probe = tegra_nvec_probe,
+	.remove = __devexit_p(tegra_nvec_remove),
+	.suspend = tegra_nvec_suspend,
+	.resume = tegra_nvec_resume,
+	.driver = {
+		.name = "nvec",
+		.owner = THIS_MODULE,
+	}
+};
+
+static int __init tegra_nvec_init(void)
+{
+	return platform_driver_register(&nvec_device_driver);
+}
+
+module_init(tegra_nvec_init);
+MODULE_ALIAS("platform:nvec");
diff -druN linux-2.6.39-libre/drivers/staging/nvec/nvec.h linux-3.0-rc7-libre/drivers/staging/nvec/nvec.h
--- linux-2.6.39-libre/drivers/staging/nvec/nvec.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/staging/nvec/nvec.h	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,110 @@
+#ifndef __LINUX_MFD_NVEC
+#define __LINUX_MFD_NVEC
+
+#include <linux/semaphore.h>
+
+typedef enum {
+	NVEC_2BYTES,
+	NVEC_3BYTES,
+	NVEC_VAR_SIZE
+} nvec_size;
+
+typedef enum {
+	NOT_REALLY,
+	YES,
+	NOT_AT_ALL,
+} how_care;
+
+typedef enum {
+	NVEC_SYS=1,
+	NVEC_BAT,
+	NVEC_KBD = 5,
+	NVEC_PS2,
+	NVEC_CNTL,
+	NVEC_KB_EVT = 0x80,
+	NVEC_PS2_EVT
+} nvec_event;
+
+typedef enum {
+       NVEC_WAIT,
+       NVEC_READ,
+       NVEC_WRITE
+} nvec_state;
+
+struct nvec_msg {
+	unsigned char *data;
+	unsigned short size;
+	unsigned short pos;
+	struct list_head node;
+};
+
+struct nvec_subdev {
+	const char *name;
+	void *platform_data;
+	int id;
+};
+
+struct nvec_platform_data {
+	int num_subdevs;
+	int i2c_addr;
+	int gpio;
+	int irq;
+	int base;
+	int size;
+	char clock[16];
+	struct nvec_subdev *subdevs;
+};
+
+struct nvec_chip {
+	struct device *dev;
+	int gpio;
+	int irq;
+	unsigned char *i2c_regs;
+	nvec_state state;
+	struct atomic_notifier_head notifier_list;
+	struct list_head rx_data, tx_data;
+	struct notifier_block nvec_status_notifier;
+	struct work_struct rx_work, tx_work;
+	struct nvec_msg *rx, *tx;
+
+/* sync write stuff */
+	struct semaphore sync_write_mutex;
+	struct completion sync_write;
+	u16 sync_write_pending;
+	struct nvec_msg *last_sync_msg;
+};
+
+extern void nvec_write_async(struct nvec_chip *nvec, unsigned char *data, short size);
+
+extern int nvec_register_notifier(struct nvec_chip *nvec,
+		 struct notifier_block *nb, unsigned int events);
+
+extern int nvec_unregister_notifier(struct device *dev,
+		struct notifier_block *nb, unsigned int events);
+
+const char *nvec_send_msg(unsigned char *src, unsigned char *dst_size, how_care care_resp, void (*rt_handler)(unsigned char *data));
+
+extern int nvec_ps2(struct nvec_chip *nvec);
+extern int nvec_kbd_init(struct nvec_chip *nvec);
+
+#define I2C_CNFG			0x00
+#define I2C_CNFG_PACKET_MODE_EN		(1<<10)
+#define I2C_CNFG_NEW_MASTER_SFM		(1<<11)
+#define I2C_CNFG_DEBOUNCE_CNT_SHIFT	12
+
+#define I2C_SL_CNFG		0x20
+#define I2C_SL_NEWL		(1<<2)
+#define I2C_SL_NACK		(1<<1)
+#define I2C_SL_RESP		(1<<0)
+#define I2C_SL_IRQ		(1<<3)
+#define END_TRANS		(1<<4)
+#define RCVD			(1<<2)
+#define RNW			(1<<1)
+
+#define I2C_SL_RCVD		0x24
+#define I2C_SL_STATUS		0x28
+#define I2C_SL_ADDR1		0x2c
+#define I2C_SL_ADDR2		0x30
+#define I2C_SL_DELAY_COUNT	0x3c
+
+#endif
diff -druN linux-2.6.39-libre/drivers/staging/nvec/nvec_kbd.c linux-3.0-rc7-libre/drivers/staging/nvec/nvec_kbd.c
--- linux-2.6.39-libre/drivers/staging/nvec/nvec_kbd.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/staging/nvec/nvec_kbd.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,122 @@
+#include <linux/slab.h>
+#include <linux/input.h>
+#include <linux/delay.h>
+#include "nvec-keytable.h"
+#include "nvec.h"
+
+#define ACK_KBD_EVENT {'\x05','\xed','\x01'}
+
+static unsigned char keycodes[ARRAY_SIZE(code_tab_102us)
+			+ ARRAY_SIZE(extcode_tab_us102)];
+
+struct nvec_keys {
+	struct input_dev *input;
+	struct notifier_block notifier;
+	struct nvec_chip *nvec;
+};
+
+static struct nvec_keys keys_dev;
+
+static int nvec_keys_notifier(struct notifier_block *nb,
+				unsigned long event_type, void *data)
+{
+	int code, state;
+	unsigned char *msg = (unsigned char *)data;
+
+	if (event_type == NVEC_KB_EVT) {
+		nvec_size _size = (msg[0] & (3 << 5)) >> 5;
+
+/* power on/off button */
+		if(_size == NVEC_VAR_SIZE)
+			return NOTIFY_STOP;
+
+		if(_size == NVEC_3BYTES)
+			msg++;
+
+		code = msg[1] & 0x7f;
+		state = msg[1] & 0x80;
+
+		input_report_key(keys_dev.input, code_tabs[_size][code], !state);
+		input_sync(keys_dev.input);
+
+		return NOTIFY_STOP;
+	}
+
+	return NOTIFY_DONE;
+}
+
+static int nvec_kbd_event(struct input_dev *dev, unsigned int type,
+				unsigned int code, int value)
+{
+	unsigned char buf[] = ACK_KBD_EVENT;
+	struct nvec_chip *nvec = keys_dev.nvec;
+
+	if(type==EV_REP)
+		return 0;
+
+	if(type!=EV_LED)
+		return -1;
+
+	if(code!=LED_CAPSL)
+		return -1;
+
+	buf[2] = !!value;
+	nvec_write_async(nvec, buf, sizeof(buf));
+
+	return 0;
+}
+
+int __init nvec_kbd_init(struct nvec_chip *nvec)
+{
+	int i, j, err;
+	struct input_dev *idev;
+
+	j = 0;
+
+	for(i = 0; i < ARRAY_SIZE(code_tab_102us); ++i)
+		keycodes[j++] = code_tab_102us[i];
+
+	for(i = 0; i < ARRAY_SIZE(extcode_tab_us102); ++i)
+		keycodes[j++]=extcode_tab_us102[i];
+
+	idev = input_allocate_device();
+	idev->name = "Tegra nvec keyboard";
+	idev->phys = "i2c3_slave/nvec";
+	idev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP) | BIT_MASK(EV_LED);
+	idev->ledbit[0] = BIT_MASK(LED_CAPSL);
+	idev->event = nvec_kbd_event;
+	idev->keycode = keycodes;
+	idev->keycodesize = sizeof(unsigned char);
+	idev->keycodemax = ARRAY_SIZE(keycodes);
+
+	for( i = 0; i < ARRAY_SIZE(keycodes); ++i)
+		set_bit(keycodes[i], idev->keybit);
+
+	clear_bit(0, idev->keybit);
+	err = input_register_device(idev);
+	if(err)
+		goto fail;
+
+	keys_dev.input = idev;
+	keys_dev.notifier.notifier_call = nvec_keys_notifier;
+	keys_dev.nvec = nvec;
+	nvec_register_notifier(nvec, &keys_dev.notifier, 0);
+
+	/* Enable keyboard */
+	nvec_write_async(nvec, "\x05\xf4", 2);
+
+	/* keyboard reset? */
+	nvec_write_async(nvec, "\x05\x03\x01\x01", 4);
+	nvec_write_async(nvec, "\x05\x04\x01", 3);
+	nvec_write_async(nvec, "\x06\x01\xff\x03", 4);
+/*	FIXME
+	wait until keyboard reset is finished
+	or until we have a sync write */
+	mdelay(1000);
+
+	return 0;
+
+fail:
+	input_free_device(idev);
+	return err;
+}
diff -druN linux-2.6.39-libre/drivers/staging/nvec/nvec-keytable.h linux-3.0-rc7-libre/drivers/staging/nvec/nvec-keytable.h
--- linux-2.6.39-libre/drivers/staging/nvec/nvec-keytable.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/staging/nvec/nvec-keytable.h	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,266 @@
+/*
+ * drivers/input/keyboard/tegra-nvec.c
+ *
+ * Keyboard class input driver for keyboards connected to an NvEc compliant
+ * embedded controller
+ *
+ * Copyright (c) 2009, NVIDIA 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+static unsigned short code_tab_102us[] = {
+	KEY_GRAVE,	// 0x00
+	KEY_ESC,
+	KEY_1,
+	KEY_2,
+	KEY_3,
+	KEY_4,
+	KEY_5,
+	KEY_6,
+	KEY_7,
+	KEY_8,
+	KEY_9,
+	KEY_0,
+	KEY_MINUS,
+	KEY_EQUAL,
+	KEY_BACKSPACE,
+	KEY_TAB,
+	KEY_Q,		// 0x10
+	KEY_W,
+	KEY_E,
+	KEY_R,
+	KEY_T,
+	KEY_Y,
+	KEY_U,
+	KEY_I,
+	KEY_O,
+	KEY_P,
+	KEY_LEFTBRACE,
+	KEY_RIGHTBRACE,
+	KEY_ENTER,
+	KEY_LEFTCTRL,
+	KEY_A,
+	KEY_S,
+	KEY_D,		// 0x20
+	KEY_F,
+	KEY_G,
+	KEY_H,
+	KEY_J,
+	KEY_K,
+	KEY_L,
+	KEY_SEMICOLON,
+	KEY_APOSTROPHE,
+	KEY_GRAVE,
+	KEY_LEFTSHIFT,
+	KEY_BACKSLASH,
+	KEY_Z,
+	KEY_X,
+	KEY_C,
+	KEY_V,
+	KEY_B,		// 0x30
+	KEY_N,
+	KEY_M,
+	KEY_COMMA,
+	KEY_DOT,
+	KEY_SLASH,
+	KEY_RIGHTSHIFT,
+	KEY_KPASTERISK,
+	KEY_LEFTALT,
+	KEY_SPACE,
+	KEY_CAPSLOCK,
+	KEY_F1,
+	KEY_F2,
+	KEY_F3,
+	KEY_F4,
+	KEY_F5,
+	KEY_F6,		// 0x40
+	KEY_F7,
+	KEY_F8,
+	KEY_F9,
+	KEY_F10,
+	KEY_FN,
+	0,		//VK_SCROLL
+	KEY_KP7,
+	KEY_KP8,
+	KEY_KP9,
+	KEY_KPMINUS,
+	KEY_KP4,
+	KEY_KP5,
+	KEY_KP6,
+	KEY_KPPLUS,
+	KEY_KP1,
+	KEY_KP2,	// 0x50
+	KEY_KP3,
+	KEY_KP0,
+	KEY_KPDOT,
+	KEY_MENU,		//VK_SNAPSHOT
+	KEY_POWER,
+	KEY_102ND,		//VK_OEM_102   henry+ 0x2B (43) BACKSLASH have been used,change to use 0X56 (86)
+	KEY_F11,		//VK_F11
+	KEY_F12,		//VK_F12
+	0, 
+	0, 
+	0, 
+	0, 
+	0, 
+	0, 
+	0, 
+	0, // 60 
+	0,
+	0,
+	KEY_SEARCH, // add search key map 
+	0,		
+	0,
+	0,
+	0,	
+	0,		
+	0, 
+	0, 
+	0, 
+	0, 
+	0, 
+	0, 
+	0, 
+	0, // 70 
+	0,
+	0,
+	KEY_KP5,  //73 for JP keyboard '\' key, report 0x4c
+	0,		
+	0,
+	0,
+	0,	
+	0,		
+	0, 
+	0, 
+    0, 
+	0, 
+	KEY_KP9, //7d  for JP keyboard '|' key, report 0x49
+};
+
+static unsigned short extcode_tab_us102[] = {
+	0,
+	0,
+	0,
+	0,
+	0,
+	0,
+	0,
+	0,
+	0,
+	0,
+	0,
+	0,
+	0,
+	0,
+	0,
+	0,
+	0,		// 0xE0 0x10
+	0,
+	0,
+	0,
+	0,
+	0,
+	0,
+	0,
+	0,
+	0,		//VK_MEDIA_NEXT_TRACK,
+	0,
+	0,
+	0,		//VK_RETURN,
+	KEY_RIGHTCTRL,		//VK_RCONTROL,
+	0,
+	0,
+	KEY_MUTE,	// 0xE0 0x20
+	0,		//VK_LAUNCH_APP1
+	0,		//VK_MEDIA_PLAY_PAUSE
+	0,
+	0,		//VK_MEDIA_STOP
+	0,
+	0,
+	0,
+	0,
+	0,
+	0,
+	0,
+	0,
+	0,
+	0,
+	0,
+	KEY_VOLUMEUP,	// 0xE0 0x30
+	0,
+	0,		//VK_BROWSER_HOME
+	0,
+	0,
+	KEY_KPSLASH,	//VK_DIVIDE
+	0,
+	KEY_SYSRQ,		//VK_SNAPSHOT
+	KEY_RIGHTALT,		//VK_RMENU
+	0,		//VK_OEM_NV_BACKLIGHT_UP
+	0,		//VK_OEM_NV_BACKLIGHT_DN
+	0,		//VK_OEM_NV_BACKLIGHT_AUTOTOGGLE
+	0,		//VK_OEM_NV_POWER_INFO
+	0,		//VK_OEM_NV_WIFI_TOGGLE
+	0,		//VK_OEM_NV_DISPLAY_SELECT
+	0,		//VK_OEM_NV_AIRPLANE_TOGGLE
+	0,		//0xE0 0x40
+	KEY_LEFT,		//VK_OEM_NV_RESERVED    henry+ for JP keyboard
+	0,		//VK_OEM_NV_RESERVED
+	0,		//VK_OEM_NV_RESERVED
+	0,		//VK_OEM_NV_RESERVED
+	0,		//VK_OEM_NV_RESERVED
+	KEY_CANCEL,
+	KEY_HOME,
+	KEY_UP,
+	KEY_PAGEUP,		//VK_PRIOR
+	0,
+	KEY_LEFT,
+	0,
+	KEY_RIGHT,
+	0,
+	KEY_END,
+	KEY_DOWN,	// 0xE0 0x50
+	KEY_PAGEDOWN,		//VK_NEXT
+	KEY_INSERT,
+	KEY_DELETE,
+	0,
+	0,
+	0,
+	0,
+	0,
+	0,
+	0,
+	KEY_LEFTMETA,	//VK_LWIN
+	0,		//VK_RWIN
+	KEY_ESC,	//VK_APPS
+	KEY_KPMINUS, //for power button workaround
+	0, 
+	0,
+	0,
+	0,
+	0,
+	0,
+	0,		//VK_BROWSER_SEARCH
+	0,		//VK_BROWSER_FAVORITES
+	0,		//VK_BROWSER_REFRESH
+	0,		//VK_BROWSER_STOP
+	0,		//VK_BROWSER_FORWARD
+	0,		//VK_BROWSER_BACK
+	0,		//VK_LAUNCH_APP2
+	0,		//VK_LAUNCH_MAIL
+	0,		//VK_LAUNCH_MEDIA_SELECT
+};
+
+static unsigned short* code_tabs[] = {code_tab_102us, extcode_tab_us102 };
diff -druN linux-2.6.39-libre/drivers/staging/nvec/nvec_power.c linux-3.0-rc7-libre/drivers/staging/nvec/nvec_power.c
--- linux-2.6.39-libre/drivers/staging/nvec/nvec_power.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/staging/nvec/nvec_power.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,418 @@
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/err.h>
+#include <linux/power_supply.h>
+#include <linux/slab.h>
+#include <linux/workqueue.h>
+#include <linux/delay.h>
+#include "nvec.h"
+
+struct nvec_power
+{
+	struct notifier_block notifier;
+	struct delayed_work poller;
+	struct nvec_chip *nvec;
+	int on;
+	int bat_present;
+	int bat_status;
+	int bat_voltage_now;
+	int bat_current_now;
+	int bat_current_avg;
+	int time_remain;
+	int charge_full_design;
+	int charge_last_full;
+	int critical_capacity;
+	int capacity_remain;
+	int bat_temperature;
+	int bat_cap;
+	int bat_type_enum;
+	char bat_manu[30];
+	char bat_model[30];
+	char bat_type[30];
+};
+
+enum {
+	SLOT_STATUS,
+	VOLTAGE,
+	TIME_REMAINING,
+	CURRENT,
+	AVERAGE_CURRENT,
+	AVERAGING_TIME_INTERVAL,
+	CAPACITY_REMAINING,
+	LAST_FULL_CHARGE_CAPACITY,
+	DESIGN_CAPACITY,
+	CRITICAL_CAPACITY,
+	TEMPERATURE,
+	MANUFACTURER,
+	MODEL,
+	TYPE,
+};
+
+enum {
+	AC,
+	BAT,
+};
+
+struct bat_response {
+	u8 event_type;
+	u8 length;
+	u8 sub_type;
+	u8 status;
+	union { /* payload */
+		char plc[30];
+		u16 plu;
+		s16 pls;
+	};
+};
+
+static struct power_supply nvec_bat_psy;
+static struct power_supply nvec_psy;
+
+static int nvec_power_notifier(struct notifier_block *nb,
+				 unsigned long event_type, void *data)
+{
+	struct nvec_power *power = container_of(nb, struct nvec_power, notifier);
+	struct bat_response *res = (struct bat_response *)data;
+
+	if (event_type != NVEC_SYS)
+		return NOTIFY_DONE;
+
+	if(res->sub_type == 0)
+	{
+		if (power->on != res->plu)
+		{
+			power->on = res->plu;
+			power_supply_changed(&nvec_psy);
+		}
+		return NOTIFY_STOP;
+	}
+	return NOTIFY_OK;
+}
+
+static const int bat_init[] =
+{
+	LAST_FULL_CHARGE_CAPACITY, DESIGN_CAPACITY, CRITICAL_CAPACITY,
+	MANUFACTURER, MODEL, TYPE,
+};
+
+static void get_bat_mfg_data(struct nvec_power *power)
+{
+	int i;
+	char buf[] = { '\x02', '\x00' };
+
+	for (i = 0; i < ARRAY_SIZE(bat_init); i++)
+	{
+		buf[1] = bat_init[i];
+		nvec_write_async(power->nvec, buf, 2);
+	}
+}
+
+static int nvec_power_bat_notifier(struct notifier_block *nb,
+				 unsigned long event_type, void *data)
+{
+	struct nvec_power *power = container_of(nb, struct nvec_power, notifier);
+	struct bat_response *res = (struct bat_response *)data;
+	int status_changed = 0;
+
+	if (event_type != NVEC_BAT)
+		return NOTIFY_DONE;
+
+	switch(res->sub_type)
+	{
+		case SLOT_STATUS:
+			if (res->plc[0] & 1)
+			{
+				if (power->bat_present == 0)
+				{
+					status_changed = 1;
+					get_bat_mfg_data(power);
+				}
+
+				power->bat_present = 1;
+
+				switch ((res->plc[0] >> 1) & 3)
+				{
+					case 0:
+						power->bat_status = POWER_SUPPLY_STATUS_NOT_CHARGING;
+						break;
+					case 1:
+						power->bat_status = POWER_SUPPLY_STATUS_CHARGING;
+						break;
+					case 2:
+						power->bat_status = POWER_SUPPLY_STATUS_DISCHARGING;
+						break;
+					default:
+						power->bat_status = POWER_SUPPLY_STATUS_UNKNOWN;
+				}
+			} else {
+				if (power->bat_present == 1)
+					status_changed = 1;
+
+				power->bat_present = 0;
+				power->bat_status = POWER_SUPPLY_STATUS_UNKNOWN;
+			}
+			power->bat_cap = res->plc[1];
+			if (status_changed)
+				power_supply_changed(&nvec_bat_psy);
+			break;
+		case VOLTAGE:
+			power->bat_voltage_now = res->plu * 1000;
+			break;
+		case TIME_REMAINING:
+			power->time_remain = res->plu * 3600;
+			break;
+		case CURRENT:
+			power->bat_current_now = res->pls * 1000;
+			break;
+		case AVERAGE_CURRENT:
+			power->bat_current_avg = res->pls * 1000;
+			break;
+		case CAPACITY_REMAINING:
+			power->capacity_remain = res->plu * 1000;
+			break;
+		case LAST_FULL_CHARGE_CAPACITY:
+			power->charge_last_full = res->plu * 1000;
+			break;
+		case DESIGN_CAPACITY:
+			power->charge_full_design = res->plu * 1000;
+			break;
+		case CRITICAL_CAPACITY:
+			power->critical_capacity = res->plu * 1000;
+			break;
+		case TEMPERATURE:
+			power->bat_temperature = res->plu - 2732;
+			break;
+		case MANUFACTURER:
+			memcpy(power->bat_manu, &res->plc, res->length-2);
+			power->bat_model[res->length-2] = '\0';
+			break;
+		case MODEL:
+			memcpy(power->bat_model, &res->plc, res->length-2);
+			power->bat_model[res->length-2] = '\0';
+			break;
+		case TYPE:
+			memcpy(power->bat_type, &res->plc, res->length-2);
+			power->bat_type[res->length-2] = '\0';
+			/* this differs a little from the spec
+			   fill in more if you find some */
+			if (!strncmp(power->bat_type, "Li", 30))
+				power->bat_type_enum = POWER_SUPPLY_TECHNOLOGY_LION;
+			else
+				power->bat_type_enum = POWER_SUPPLY_TECHNOLOGY_UNKNOWN;
+			break;
+		default:
+			return NOTIFY_STOP;
+	}
+
+	return NOTIFY_STOP;
+}
+
+static int nvec_power_get_property(struct power_supply *psy,
+				enum power_supply_property psp,
+				union power_supply_propval *val)
+{
+	struct nvec_power *power = dev_get_drvdata(psy->dev->parent);
+	switch (psp) {
+	case POWER_SUPPLY_PROP_ONLINE:
+		val->intval = power->on;
+		break;
+	default:
+		return -EINVAL;
+	}
+	return 0;
+}
+
+static int nvec_battery_get_property(struct power_supply *psy,
+				enum power_supply_property psp,
+				union power_supply_propval *val)
+{
+	struct nvec_power *power = dev_get_drvdata(psy->dev->parent);
+
+	switch(psp)
+	{
+		case POWER_SUPPLY_PROP_STATUS:
+			val->intval = power->bat_status;
+			break;
+		case POWER_SUPPLY_PROP_CAPACITY:
+			val->intval = power->bat_cap;
+			break;
+		case POWER_SUPPLY_PROP_PRESENT:
+			val->intval = power->bat_present;
+			break;
+		case POWER_SUPPLY_PROP_VOLTAGE_NOW:
+			val->intval = power->bat_voltage_now;
+			break;
+		case POWER_SUPPLY_PROP_CURRENT_NOW:
+			val->intval = power->bat_current_now;
+			break;
+		case POWER_SUPPLY_PROP_CURRENT_AVG:
+			val->intval = power->bat_current_avg;
+			break;
+		case POWER_SUPPLY_PROP_TIME_TO_EMPTY_NOW:
+			val->intval = power->time_remain;
+			break;
+		case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN:
+			val->intval = power->charge_full_design;
+			break;
+		case POWER_SUPPLY_PROP_CHARGE_FULL:
+			val->intval = power->charge_last_full;
+			break;
+		case POWER_SUPPLY_PROP_CHARGE_EMPTY:
+			val->intval = power->critical_capacity;
+			break;
+		case POWER_SUPPLY_PROP_CHARGE_NOW:
+			val->intval = power->capacity_remain;
+			break;
+		case POWER_SUPPLY_PROP_TEMP:
+			val->intval = power->bat_temperature;
+			break;
+		case POWER_SUPPLY_PROP_MANUFACTURER:
+			val->strval = power->bat_manu;
+			break;
+		case POWER_SUPPLY_PROP_MODEL_NAME:
+			val->strval = power->bat_model;
+			break;
+		case POWER_SUPPLY_PROP_TECHNOLOGY:
+			val->intval = power->bat_type_enum;
+			break;
+		default:
+			return -EINVAL;
+		}
+	return 0;
+}
+
+static enum power_supply_property nvec_power_props[] = {
+	POWER_SUPPLY_PROP_ONLINE,
+};
+
+static enum power_supply_property nvec_battery_props[] = {
+	POWER_SUPPLY_PROP_STATUS,
+	POWER_SUPPLY_PROP_PRESENT,
+	POWER_SUPPLY_PROP_CAPACITY,
+	POWER_SUPPLY_PROP_VOLTAGE_NOW,
+	POWER_SUPPLY_PROP_CURRENT_NOW,
+#ifdef EC_FULL_DIAG
+	POWER_SUPPLY_PROP_CURRENT_AVG,
+	POWER_SUPPLY_PROP_TEMP,
+	POWER_SUPPLY_PROP_TIME_TO_EMPTY_NOW,
+#endif
+	POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN,
+	POWER_SUPPLY_PROP_CHARGE_FULL,
+	POWER_SUPPLY_PROP_CHARGE_EMPTY,
+	POWER_SUPPLY_PROP_CHARGE_NOW,
+	POWER_SUPPLY_PROP_MANUFACTURER,
+	POWER_SUPPLY_PROP_MODEL_NAME,
+	POWER_SUPPLY_PROP_TECHNOLOGY,
+};
+
+static char *nvec_power_supplied_to[] = {
+	"battery",
+};
+
+static struct power_supply nvec_bat_psy = {
+	.name		= "battery",
+	.type		= POWER_SUPPLY_TYPE_BATTERY,
+	.properties	= nvec_battery_props,
+	.num_properties	= ARRAY_SIZE(nvec_battery_props),
+	.get_property	= nvec_battery_get_property,
+};
+
+static struct power_supply nvec_psy = {
+	.name = "ac",
+	.type = POWER_SUPPLY_TYPE_MAINS,
+	.supplied_to = nvec_power_supplied_to,
+	.num_supplicants = ARRAY_SIZE(nvec_power_supplied_to),
+	.properties = nvec_power_props,
+	.num_properties = ARRAY_SIZE(nvec_power_props),
+	.get_property = nvec_power_get_property,
+};
+
+static int counter = 0;
+static int const bat_iter[] =
+{
+	SLOT_STATUS, VOLTAGE, CURRENT, CAPACITY_REMAINING,
+#ifdef EC_FULL_DIAG
+	AVERAGE_CURRENT, TEMPERATURE, TIME_REMAINING,
+#endif
+};
+
+static void nvec_power_poll(struct work_struct *work)
+{
+	char buf[] = { '\x01', '\x00' };
+	struct nvec_power *power = container_of(work, struct nvec_power,
+		 poller.work);
+
+	if (counter >= ARRAY_SIZE(bat_iter))
+		counter = 0;
+
+/* AC status via sys req */
+	nvec_write_async(power->nvec, buf, 2);
+	msleep(100);
+
+/* select a battery request function via round robin
+   doing it all at once seems to overload the power supply */
+	buf[0] = '\x02'; /* battery */
+        buf[1] = bat_iter[counter++];
+	nvec_write_async(power->nvec, buf, 2);
+
+//	printk("%02x %02x\n", buf[0], buf[1]);
+
+	schedule_delayed_work(to_delayed_work(work), msecs_to_jiffies(5000));
+};
+
+static int __devinit nvec_power_probe(struct platform_device *pdev)
+{
+	struct power_supply *psy;
+	struct nvec_power *power = kzalloc(sizeof(struct nvec_power), GFP_NOWAIT);
+	struct nvec_chip *nvec = dev_get_drvdata(pdev->dev.parent);
+
+	dev_set_drvdata(&pdev->dev, power);
+	power->nvec = nvec;
+
+	switch (pdev->id) {
+	case AC:
+		psy = &nvec_psy;
+
+		power->notifier.notifier_call = nvec_power_notifier;
+
+		INIT_DELAYED_WORK(&power->poller, nvec_power_poll);
+		schedule_delayed_work(&power->poller, msecs_to_jiffies(5000));
+		break;
+	case BAT:
+		psy = &nvec_bat_psy;
+
+                power->notifier.notifier_call = nvec_power_bat_notifier;
+		break;
+	default:
+		kfree(power);
+		return -ENODEV;
+	}
+
+	nvec_register_notifier(nvec, &power->notifier, NVEC_SYS);
+
+	if (pdev->id == BAT)
+		get_bat_mfg_data(power);
+
+	return power_supply_register(&pdev->dev, psy);
+}
+
+static struct platform_driver nvec_power_driver = {
+	.probe = nvec_power_probe,
+//	.remove = __devexit_p(nvec_power_remove),
+	.driver = {
+		.name = "nvec-power",
+		.owner = THIS_MODULE,
+	}
+};
+
+static int __init nvec_power_init(void) 
+{
+	return platform_driver_register(&nvec_power_driver);
+}
+
+module_init(nvec_power_init);
+
+MODULE_AUTHOR("Ilya Petrov <ilya.muromec@gmail.com>");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("NVEC battery and AC driver");
+MODULE_ALIAS("platform:nvec-power");
diff -druN linux-2.6.39-libre/drivers/staging/nvec/nvec_ps2.c linux-3.0-rc7-libre/drivers/staging/nvec/nvec_ps2.c
--- linux-2.6.39-libre/drivers/staging/nvec/nvec_ps2.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/staging/nvec/nvec_ps2.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,103 @@
+#include <linux/slab.h>
+#include <linux/serio.h>
+#include <linux/delay.h>
+#include "nvec.h"
+
+#define START_STREAMING	{'\x06','\x03','\x01'}
+#define STOP_STREAMING	{'\x06','\x04'}
+#define SEND_COMMAND	{'\x06','\x01','\xf4','\x01'}
+
+struct nvec_ps2
+{
+	struct serio *ser_dev;
+	struct notifier_block notifier;
+	struct nvec_chip *nvec;
+};
+
+static struct nvec_ps2 ps2_dev;
+
+static int ps2_startstreaming(struct serio *ser_dev)
+{
+	unsigned char buf[] = START_STREAMING;
+	nvec_write_async(ps2_dev.nvec, buf, sizeof(buf));
+	return 0;
+}
+
+static void ps2_stopstreaming(struct serio *ser_dev)
+{
+	unsigned char buf[] = STOP_STREAMING;
+	nvec_write_async(ps2_dev.nvec, buf, sizeof(buf));
+}
+
+/* is this really needed?
+static void nvec_resp_handler(unsigned char *data) {
+	serio_interrupt(ser_dev, data[4], 0);
+}
+*/
+
+static int ps2_sendcommand(struct serio *ser_dev, unsigned char cmd)
+{
+	unsigned char buf[] = SEND_COMMAND;
+
+	buf[2] = cmd & 0xff;
+
+	dev_dbg(&ser_dev->dev, "Sending ps2 cmd %02x\n", cmd);
+	nvec_write_async(ps2_dev.nvec, buf, sizeof(buf));
+
+	return 0;
+}
+
+static int nvec_ps2_notifier(struct notifier_block *nb,
+				unsigned long event_type, void *data)
+{
+	int i;
+	unsigned char *msg = (unsigned char *)data;
+
+	switch (event_type) {
+		case NVEC_PS2_EVT:
+			serio_interrupt(ps2_dev.ser_dev, msg[2], 0);
+			return NOTIFY_STOP;
+
+		case NVEC_PS2:
+			if (msg[2] == 1)
+				for(i = 0; i < (msg[1] - 2); i++)
+					serio_interrupt(ps2_dev.ser_dev, msg[i+4], 0);
+			else if (msg[1] != 2) /* !ack */
+			{
+				printk("nvec_ps2: unhandled mouse event ");
+				for(i = 0; i <= (msg[1]+1); i++)
+					printk("%02x ", msg[i]);
+				printk(".\n");
+			}
+
+			return NOTIFY_STOP;
+	}
+
+	return NOTIFY_DONE;
+}
+
+
+int __init nvec_ps2(struct nvec_chip *nvec)
+{
+	struct serio *ser_dev = kzalloc(sizeof(struct serio), GFP_KERNEL);
+
+	ser_dev->id.type=SERIO_8042;
+	ser_dev->write=ps2_sendcommand;
+	ser_dev->open=ps2_startstreaming;
+	ser_dev->close=ps2_stopstreaming;
+
+	strlcpy(ser_dev->name, "NVEC PS2", sizeof(ser_dev->name));
+	strlcpy(ser_dev->phys, "NVEC I2C slave", sizeof(ser_dev->phys));
+
+	ps2_dev.ser_dev = ser_dev;
+	ps2_dev.notifier.notifier_call = nvec_ps2_notifier;
+	ps2_dev.nvec = nvec;
+	nvec_register_notifier(nvec, &ps2_dev.notifier, 0);
+
+	serio_register_port(ser_dev);
+
+	/* mouse reset */
+	nvec_write_async(nvec, "\x06\x01\xff\x03", 4);
+
+	return 0;
+}
diff -druN linux-2.6.39-libre/drivers/staging/nvec/README linux-3.0-rc7-libre/drivers/staging/nvec/README
--- linux-2.6.39-libre/drivers/staging/nvec/README	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/staging/nvec/README	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,14 @@
+NVEC: An NVidia compliant Embedded Controller Protocol Implemenation
+
+This is an implementation of the NVEC protocol used to communicate with an
+embedded controller (EC) via I2C bus. The EC is an I2C master while the host
+processor is the I2C slave. Requests from the host processor to the EC are
+started by triggering a gpio line.
+
+There is no written documentation of the protocol available to the public,
+but the source code[1] of the published nvec reference drivers can be a guide.
+This driver is currently only used by the AC100 project[2], but it is likely,
+that other Tegra boards (not yet mainlined, if ever) also use it.
+
+[1] e.g. http://nv-tegra.nvidia.com/gitweb/?p=linux-2.6.git;a=tree;f=arch/arm/mach-tegra/nvec;hb=android-tegra-2.6.32
+[2] http://gitorious.org/ac100, http://launchpad.net/ac100
diff -druN linux-2.6.39-libre/drivers/staging/nvec/TODO linux-3.0-rc7-libre/drivers/staging/nvec/TODO
--- linux-2.6.39-libre/drivers/staging/nvec/TODO	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/staging/nvec/TODO	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,8 @@
+ToDo list (incomplete, unordered)
+	- convert mouse, keyboard, and power to platform devices
+	- add copyright / driver author / license
+	- add compile as module support
+	- move nvec devices to mfd cells?
+	- adjust to kernel style
+
+
diff -druN linux-2.6.39-libre/drivers/staging/octeon/ethernet-mdio.c linux-3.0-rc7-libre/drivers/staging/octeon/ethernet-mdio.c
--- linux-2.6.39-libre/drivers/staging/octeon/ethernet-mdio.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/octeon/ethernet-mdio.c	2011-07-11 19:51:52.000000000 -0400
@@ -91,8 +91,6 @@
 	.set_settings = cvm_oct_set_settings,
 	.nway_reset = cvm_oct_nway_reset,
 	.get_link = ethtool_op_get_link,
-	.get_sg = ethtool_op_get_sg,
-	.get_tx_csum = ethtool_op_get_tx_csum,
 };
 
 /**
diff -druN linux-2.6.39-libre/drivers/staging/olpc_dcon/Kconfig linux-3.0-rc7-libre/drivers/staging/olpc_dcon/Kconfig
--- linux-2.6.39-libre/drivers/staging/olpc_dcon/Kconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/olpc_dcon/Kconfig	2011-07-11 19:51:52.000000000 -0400
@@ -2,6 +2,7 @@
 	tristate "One Laptop Per Child Display CONtroller support"
 	depends on OLPC && FB
 	select I2C
+	select BACKLIGHT_CLASS_DEVICE
 	---help---
 	  Add support for the OLPC XO DCON controller.  This controller is
 	  only available on OLPC platforms.   Unless you have one of these
diff -druN linux-2.6.39-libre/drivers/staging/olpc_dcon/olpc_dcon_xo_1_5.c linux-3.0-rc7-libre/drivers/staging/olpc_dcon/olpc_dcon_xo_1_5.c
--- linux-2.6.39-libre/drivers/staging/olpc_dcon/olpc_dcon_xo_1_5.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/olpc_dcon/olpc_dcon_xo_1_5.c	2011-07-11 19:51:52.000000000 -0400
@@ -24,9 +24,8 @@
 #include "olpc_dcon.h"
 
 /* Hardware setup on the XO 1.5:
- * 	DCONLOAD connects to
- *		VX855_GPIO1 (not SMBCK2)
- * 	DCONBLANK connects to VX855_GPIO8 (not SSPICLK)  unused in driver
+ *	DCONLOAD connects to VX855_GPIO1 (not SMBCK2)
+ *	DCONBLANK connects to VX855_GPIO8 (not SSPICLK)  unused in driver
  *	DCONSTAT0 connects to VX855_GPI10 (not SSPISDI)
  *	DCONSTAT1 connects to VX855_GPI11 (not nSSPISS)
  *	DCONIRQ connects to VX855_GPIO12
@@ -34,9 +33,9 @@
  *	DCONSMBCLK connects to VX855 graphics CRTSPCLK
  */
 
-#define VX855_GENL_PURPOSE_OUTPUT 0x44c // PMIO_Rx4c-4f
-#define VX855_GPI_STATUS_CHG 0x450  // PMIO_Rx50
-#define VX855_GPI_SCI_SMI 0x452  // PMIO_Rx52
+#define VX855_GENL_PURPOSE_OUTPUT 0x44c /* PMIO_Rx4c-4f */
+#define VX855_GPI_STATUS_CHG 0x450  /* PMIO_Rx50 */
+#define VX855_GPI_SCI_SMI 0x452  /* PMIO_Rx52 */
 #define BIT_GPIO12 0x40
 
 #define PREFIX "OLPC DCON:"
@@ -63,8 +62,7 @@
 	unsigned int irq;
 	u_int8_t tmp;
 	struct pci_dev *pdev;
-	
-	
+
 	pdev = pci_get_device(PCI_VENDOR_ID_VIA,
 			      PCI_DEVICE_ID_VIA_VX855, NULL);
 	if (!pdev) {
@@ -149,7 +147,7 @@
 	 * state machine to reset to a (sane) initial state.  Mitch Bradley
 	 * did some testing and discovered that holding for 16 SMB_CLK cycles
 	 * worked a lot more reliably, so that's what we do here.
- 	 */
+	 */
 	set_i2c_line(1, 1);
 
 	for (x = 0; x < 16; x++) {
@@ -172,13 +170,13 @@
 static u8 dcon_read_status_xo_1_5(void)
 {
 	u8 status;
-	
+
 	if (!dcon_was_irq())
 		return -1;
 
-	// i believe this is the same as "inb(0x44b) & 3"
+	/* i believe this is the same as "inb(0x44b) & 3" */
 	status = gpio_get_value(VX855_GPI(10));
-	status |= gpio_get_value(VX855_GPI(11)) << 1; 
+	status |= gpio_get_value(VX855_GPI(11)) << 1;
 
 	dcon_clear_irq();
 
diff -druN linux-2.6.39-libre/drivers/staging/olpc_dcon/olpc_dcon_xo_1.c linux-3.0-rc7-libre/drivers/staging/olpc_dcon/olpc_dcon_xo_1.c
--- linux-2.6.39-libre/drivers/staging/olpc_dcon/olpc_dcon_xo_1.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/olpc_dcon/olpc_dcon_xo_1.c	2011-07-11 19:51:52.000000000 -0400
@@ -153,7 +153,7 @@
 	 * According to the cs5536 spec, to set GPIO14 to SMB_CLK we must
 	 * simultaneously set AUX1 IN/OUT to GPIO14; ditto for SMB_DATA and
 	 * GPIO15.
- 	 */
+	 */
 	cs5535_gpio_set(OLPC_GPIO_SMB_CLK, GPIO_OUTPUT_VAL);
 	cs5535_gpio_set(OLPC_GPIO_SMB_DATA, GPIO_OUTPUT_VAL);
 	cs5535_gpio_set(OLPC_GPIO_SMB_CLK, GPIO_OUTPUT_ENABLE);
diff -druN linux-2.6.39-libre/drivers/staging/pohmelfs/inode.c linux-3.0-rc7-libre/drivers/staging/pohmelfs/inode.c
--- linux-2.6.39-libre/drivers/staging/pohmelfs/inode.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/pohmelfs/inode.c	2011-07-11 19:51:52.000000000 -0400
@@ -29,6 +29,7 @@
 #include <linux/slab.h>
 #include <linux/statfs.h>
 #include <linux/writeback.h>
+#include <linux/prefetch.h>
 
 #include "netfs.h"
 
diff -druN linux-2.6.39-libre/drivers/staging/rt2860/ap.h linux-3.0-rc7-libre/drivers/staging/rt2860/ap.h
--- linux-2.6.39-libre/drivers/staging/rt2860/ap.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rt2860/ap.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,68 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, 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.             *
- *                                                                       *
- *************************************************************************
-
-Module Name:
-ap.h
-
-Abstract:
-Miniport generic portion header file
-
-Revision History:
-Who         When          What
---------    ----------    ----------------------------------------------
-Paul Lin    08-01-2002    created
-James Tan   09-06-2002    modified (Revise NTCRegTable)
-John Chang  12-22-2004    modified for RT2561/2661. merge with STA driver
-*/
-#ifndef __AP_H__
-#define __AP_H__
-
-/* ap_wpa.c */
-void WpaStateMachineInit(struct rt_rtmp_adapter *pAd,
-			 struct rt_state_machine *Sm,
-			 OUT STATE_MACHINE_FUNC Trans[]);
-
-#ifdef RTMP_MAC_USB
-void BeaconUpdateExec(void *SystemSpecific1,
-		      void *FunctionContext,
-		      void *SystemSpecific2, void *SystemSpecific3);
-#endif /* RTMP_MAC_USB // */
-
-void RTMPSetPiggyBack(struct rt_rtmp_adapter *pAd, IN BOOLEAN bPiggyBack);
-
-void MacTableReset(struct rt_rtmp_adapter *pAd);
-
-struct rt_mac_table_entry *MacTableInsertEntry(struct rt_rtmp_adapter *pAd,
-				     u8 *pAddr,
-				     u8 apidx, IN BOOLEAN CleanAll);
-
-BOOLEAN MacTableDeleteEntry(struct rt_rtmp_adapter *pAd,
-			    u16 wcid, u8 *pAddr);
-
-struct rt_mac_table_entry *MacTableLookup(struct rt_rtmp_adapter *pAd,
-								u8 *pAddr);
-
-#endif /* __AP_H__ */
diff -druN linux-2.6.39-libre/drivers/staging/rt2860/chip/mac_pci.h linux-3.0-rc7-libre/drivers/staging/rt2860/chip/mac_pci.h
--- linux-2.6.39-libre/drivers/staging/rt2860/chip/mac_pci.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rt2860/chip/mac_pci.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,355 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, 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.             *
- *                                                                       *
- *************************************************************************
-
-    Module Name:
-	mac_pci.h
-
-    Abstract:
-
-    Revision History:
-    Who          	When            What
-    Justin P. Mattock	11/07/2010	Fix some typos
-    ---------    ----------    ----------------------------------------------
- */
-
-#ifndef __MAC_PCI_H__
-#define __MAC_PCI_H__
-
-#include "../rtmp_type.h"
-#include "rtmp_mac.h"
-#include "rtmp_phy.h"
-#include "../rtmp_iface.h"
-#include "../rtmp_dot11.h"
-
-/* */
-/* Device ID & Vendor ID related definitions, */
-/* NOTE: you should not add the new VendorID/DeviceID here unless you know for sure what chip it belongs too. */
-/* */
-#define NIC_PCI_VENDOR_ID		0x1814
-#define PCIBUS_INTEL_VENDOR	0x8086
-
-#if !defined(PCI_CAP_ID_EXP)
-#define PCI_CAP_ID_EXP			    0x10
-#endif
-#if !defined(PCI_EXP_LNKCTL)
-#define PCI_EXP_LNKCTL			    0x10
-#endif
-#if !defined(PCI_CLASS_BRIDGE_PCI)
-#define PCI_CLASS_BRIDGE_PCI		0x0604
-#endif
-
-#define TXINFO_SIZE						0
-#define RTMP_PKT_TAIL_PADDING			0
-#define fRTMP_ADAPTER_NEED_STOP_TX	0
-
-#define AUX_CTRL           0x10c
-
-/* */
-/* TX descriptor format, Tx     ring, Mgmt Ring */
-/* */
-struct PACKED rt_txd {
-	/* Word 0 */
-	u32 SDPtr0;
-	/* Word 1 */
-	u32 SDLen1:14;
-	u32 LastSec1:1;
-	u32 Burst:1;
-	u32 SDLen0:14;
-	u32 LastSec0:1;
-	u32 DMADONE:1;
-	/*Word2 */
-	u32 SDPtr1;
-	/*Word3 */
-	u32 rsv2:24;
-	u32 WIV:1;		/* Wireless Info Valid. 1 if Driver already fill WI,  o if DMA needs to copy WI to correct position */
-	u32 QSEL:2;		/* select on-chip FIFO ID for 2nd-stage output scheduler.0:MGMT, 1:HCCA 2:EDCA */
-	u32 rsv:2;
-	u32 TCO:1;		/* */
-	u32 UCO:1;		/* */
-	u32 ICO:1;		/* */
-};
-
-/* */
-/* Rx descriptor format, Rx Ring */
-/* */
-typedef struct PACKED rt_rxd {
-	/* Word 0 */
-	u32 SDP0;
-	/* Word 1 */
-	u32 SDL1:14;
-	u32 Rsv:2;
-	u32 SDL0:14;
-	u32 LS0:1;
-	u32 DDONE:1;
-	/* Word 2 */
-	u32 SDP1;
-	/* Word 3 */
-	u32 BA:1;
-	u32 DATA:1;
-	u32 NULLDATA:1;
-	u32 FRAG:1;
-	u32 U2M:1;		/* 1: this RX frame is unicast to me */
-	u32 Mcast:1;		/* 1: this is a multicast frame */
-	u32 Bcast:1;		/* 1: this is a broadcast frame */
-	u32 MyBss:1;		/* 1: this frame belongs to the same BSSID */
-	u32 Crc:1;		/* 1: CRC error */
-	u32 CipherErr:2;	/* 0: decryption okay, 1:ICV error, 2:MIC error, 3:KEY not valid */
-	u32 AMSDU:1;		/* rx with 802.3 header, not 802.11 header. */
-	u32 HTC:1;
-	u32 RSSI:1;
-	u32 L2PAD:1;
-	u32 AMPDU:1;
-	u32 Decrypted:1;	/* this frame is being decrypted. */
-	u32 PlcpSignal:1;	/* To be moved */
-	u32 PlcpRssil:1;	/* To be moved */
-	u32 Rsv1:13;
-} RT28XX_RXD_STRUC, *PRT28XX_RXD_STRUC;
-
-typedef union _TX_ATTENUATION_CTRL_STRUC {
-	struct {
-		unsigned long RF_ISOLATION_ENABLE:1;
-		unsigned long Reserve2:7;
-		unsigned long PCIE_PHY_TX_ATTEN_VALUE:3;
-		unsigned long PCIE_PHY_TX_ATTEN_EN:1;
-		unsigned long Reserve1:20;
-	} field;
-
-	unsigned long word;
-} TX_ATTENUATION_CTRL_STRUC, *PTX_ATTENUATION_CTRL_STRUC;
-
-/* ----------------- EEPROM Related MACRO ----------------- */
-
-/* 8051 firmware image for RT2860 - base address = 0x4000 */
-#define FIRMWARE_IMAGE_BASE     0x2000
-#define MAX_FIRMWARE_IMAGE_SIZE 0x2000	/* 8kbyte */
-
-/* ----------------- Frimware Related MACRO ----------------- */
-#define RTMP_WRITE_FIRMWARE(_pAd, _pFwImage, _FwLen)			\
-	do {								\
-		unsigned long	_i, _firm;					\
-		RTMP_IO_WRITE32(_pAd, PBF_SYS_CTRL, 0x10000);		\
-									\
-		for (_i = 0; _i < _FwLen; _i += 4) {				\
-				_firm = _pFwImage[_i] +				\
-			   (_pFwImage[_i+3] << 24) +			\
-			   (_pFwImage[_i+2] << 16) +			\
-			   (_pFwImage[_i+1] << 8);			\
-			RTMP_IO_WRITE32(_pAd, FIRMWARE_IMAGE_BASE + _i, _firm);	\
-		}							\
-		RTMP_IO_WRITE32(_pAd, PBF_SYS_CTRL, 0x00000);		\
-		RTMP_IO_WRITE32(_pAd, PBF_SYS_CTRL, 0x00001);		\
-									\
-		/* initialize BBP R/W access agent */			\
-		RTMP_IO_WRITE32(_pAd, H2M_BBP_AGENT, 0);		\
-		RTMP_IO_WRITE32(_pAd, H2M_MAILBOX_CSR, 0);		\
-	} while (0)
-
-/* ----------------- TX Related MACRO ----------------- */
-#define RTMP_START_DEQUEUE(pAd, QueIdx, irqFlags)		do {} while (0)
-#define RTMP_STOP_DEQUEUE(pAd, QueIdx, irqFlags)		do {} while (0)
-
-#define RTMP_HAS_ENOUGH_FREE_DESC(pAd, pTxBlk, freeNum, pPacket) \
-		((freeNum) >= (unsigned long)(pTxBlk->TotalFragNum + RTMP_GET_PACKET_FRAGMENTS(pPacket) + 3))	/* rough estimate we will use 3 more descriptor. */
-#define RTMP_RELEASE_DESC_RESOURCE(pAd, QueIdx)			do {} while (0)
-
-#define NEED_QUEUE_BACK_FOR_AGG(pAd, QueIdx, freeNum, _TxFrameType) \
-		(((freeNum != (TX_RING_SIZE-1)) && \
-		(pAd->TxSwQueue[QueIdx].Number == 0)) || (freeNum < 3))
-
-#define HAL_KickOutMgmtTx(_pAd, _QueIdx, _pPacket, _pSrcBufVA, _SrcBufLen)	\
-			RtmpPCIMgmtKickOut(_pAd, _QueIdx, _pPacket, _pSrcBufVA, _SrcBufLen)
-
-#define HAL_WriteSubTxResource(pAd, pTxBlk, bIsLast, pFreeNumber)	\
-				/* RtmpPCI_WriteSubTxResource(pAd, pTxBlk, bIsLast, pFreeNumber) */
-
-#define HAL_WriteTxResource(pAd, pTxBlk, bIsLast, pFreeNumber)	\
-			RtmpPCI_WriteSingleTxResource(pAd, pTxBlk, bIsLast, pFreeNumber)
-
-#define HAL_WriteFragTxResource(pAd, pTxBlk, fragNum, pFreeNumber) \
-			RtmpPCI_WriteFragTxResource(pAd, pTxBlk, fragNum, pFreeNumber)
-
-#define HAL_WriteMultiTxResource(pAd, pTxBlk, frameNum, pFreeNumber) \
-			RtmpPCI_WriteMultiTxResource(pAd, pTxBlk, frameNum, pFreeNumber)
-
-#define HAL_FinalWriteTxResource(_pAd, _pTxBlk, _TotalMPDUSize, _FirstTxIdx)	\
-			RtmpPCI_FinalWriteTxResource(_pAd, _pTxBlk, _TotalMPDUSize, _FirstTxIdx)
-
-#define HAL_LastTxIdx(_pAd, _QueIdx, _LastTxIdx) \
-				/*RtmpPCIDataLastTxIdx(_pAd, _QueIdx,_LastTxIdx) */
-
-#define HAL_KickOutTx(_pAd, _pTxBlk, _QueIdx)	\
-			RTMP_IO_WRITE32((_pAd), TX_CTX_IDX0+((_QueIdx)*0x10), (_pAd)->TxRing[(_QueIdx)].TxCpuIdx)
-/*			RtmpPCIDataKickOut(_pAd, _pTxBlk, _QueIdx)*/
-
-#define HAL_KickOutNullFrameTx(_pAd, _QueIdx, _pNullFrame, _frameLen)	\
-			MiniportMMRequest(_pAd, _QueIdx, _pNullFrame, _frameLen)
-
-#define GET_TXRING_FREENO(_pAd, _QueIdx) \
-	(_pAd->TxRing[_QueIdx].TxSwFreeIdx > _pAd->TxRing[_QueIdx].TxCpuIdx)	? \
-			(_pAd->TxRing[_QueIdx].TxSwFreeIdx - _pAd->TxRing[_QueIdx].TxCpuIdx - 1) \
-			 :	\
-			(_pAd->TxRing[_QueIdx].TxSwFreeIdx + TX_RING_SIZE - _pAd->TxRing[_QueIdx].TxCpuIdx - 1);
-
-#define GET_MGMTRING_FREENO(_pAd) \
-	(_pAd->MgmtRing.TxSwFreeIdx > _pAd->MgmtRing.TxCpuIdx)	? \
-			(_pAd->MgmtRing.TxSwFreeIdx - _pAd->MgmtRing.TxCpuIdx - 1) \
-			 :	\
-			(_pAd->MgmtRing.TxSwFreeIdx + MGMT_RING_SIZE - _pAd->MgmtRing.TxCpuIdx - 1);
-
-/* ----------------- RX Related MACRO ----------------- */
-
-/* ----------------- ASIC Related MACRO ----------------- */
-/* reset MAC of a station entry to 0x000000000000 */
-#define RTMP_STA_ENTRY_MAC_RESET(pAd, Wcid)	\
-	AsicDelWcidTab(pAd, Wcid);
-
-/* add this entry into ASIC RX WCID search table */
-#define RTMP_STA_ENTRY_ADD(pAd, pEntry)		\
-	AsicUpdateRxWCIDTable(pAd, pEntry->Aid, pEntry->Addr);
-
-/* add by johnli, fix "in_interrupt" error when call "MacTableDeleteEntry" in Rx tasklet */
-/* Set MAC register value according operation mode */
-#define RTMP_UPDATE_PROTECT(pAd)	\
-	AsicUpdateProtect(pAd, 0, (ALLN_SETPROTECT), TRUE, 0);
-/* end johnli */
-
-/* remove Pair-wise key material from ASIC */
-#define RTMP_STA_ENTRY_KEY_DEL(pAd, BssIdx, Wcid)	\
-	AsicRemovePairwiseKeyEntry(pAd, BssIdx, (u8)Wcid);
-
-/* add Client security information into ASIC WCID table and IVEIV table */
-#define RTMP_STA_SECURITY_INFO_ADD(pAd, apidx, KeyID, pEntry)		\
-	RTMPAddWcidAttributeEntry(pAd, apidx, KeyID,			\
-							pAd->SharedKey[apidx][KeyID].CipherAlg, pEntry);
-
-#define RTMP_SECURITY_KEY_ADD(pAd, apidx, KeyID, pEntry)		\
-	{	/* update pairwise key information to ASIC Shared Key Table */	\
-		AsicAddSharedKeyEntry(pAd, apidx, KeyID,					\
-						  pAd->SharedKey[apidx][KeyID].CipherAlg,		\
-						  pAd->SharedKey[apidx][KeyID].Key,				\
-						  pAd->SharedKey[apidx][KeyID].TxMic,			\
-						  pAd->SharedKey[apidx][KeyID].RxMic);			\
-		/* update ASIC WCID attribute table and IVEIV table */			\
-		RTMPAddWcidAttributeEntry(pAd, apidx, KeyID,					\
-						  pAd->SharedKey[apidx][KeyID].CipherAlg,		\
-						  pEntry); }
-
-/* Insert the BA bitmap to ASIC for the Wcid entry */
-#define RTMP_ADD_BA_SESSION_TO_ASIC(_pAd, _Aid, _TID)	\
-		do {					\
-			u32 _Value = 0, _Offset;					\
-			_Offset = MAC_WCID_BASE + (_Aid) * HW_WCID_ENTRY_SIZE + 4;	\
-			RTMP_IO_READ32((_pAd), _Offset, &_Value);\
-			_Value |= (0x10000<<(_TID));	\
-			RTMP_IO_WRITE32((_pAd), _Offset, _Value);\
-		} while (0)
-
-/* Remove the BA bitmap from ASIC for the Wcid entry */
-/*              bitmap field starts at 0x10000 in ASIC WCID table */
-#define RTMP_DEL_BA_SESSION_FROM_ASIC(_pAd, _Wcid, _TID)				\
-		do {								\
-			u32 _Value = 0, _Offset;				\
-			_Offset = MAC_WCID_BASE + (_Wcid) * HW_WCID_ENTRY_SIZE + 4;	\
-			RTMP_IO_READ32((_pAd), _Offset, &_Value);			\
-			_Value &= (~(0x10000 << (_TID)));				\
-			RTMP_IO_WRITE32((_pAd), _Offset, _Value);			\
-		} while (0)
-
-/* ----------------- Interface Related MACRO ----------------- */
-
-/* */
-/* Enable & Disable NIC interrupt via writing interrupt mask register */
-/* Since it use ADAPTER structure, it have to be put after structure definition. */
-/* */
-#define RTMP_ASIC_INTERRUPT_DISABLE(_pAd)		\
-	do {			\
-		RTMP_IO_WRITE32((_pAd), INT_MASK_CSR, 0x0);     /* 0: disable */	\
-		RTMP_CLEAR_FLAG((_pAd), fRTMP_ADAPTER_INTERRUPT_ACTIVE);		\
-	} while (0)
-
-#define RTMP_ASIC_INTERRUPT_ENABLE(_pAd)\
-	do {				\
-		RTMP_IO_WRITE32((_pAd), INT_MASK_CSR, (_pAd)->int_enable_reg /*DELAYINTMASK*/);     /* 1:enable */	\
-		RTMP_SET_FLAG((_pAd), fRTMP_ADAPTER_INTERRUPT_ACTIVE);	\
-	} while (0)
-
-#define RTMP_IRQ_INIT(pAd)	\
-	{	pAd->int_enable_reg = ((DELAYINTMASK) |		\
-					(RxINT|TxDataInt|TxMgmtInt)) & ~(0x03);	\
-		pAd->int_disable_mask = 0;						\
-		pAd->int_pending = 0; }
-
-#define RTMP_IRQ_ENABLE(pAd)					\
-	{	/* clear garbage ints */			\
-		RTMP_IO_WRITE32(pAd, INT_SOURCE_CSR, 0xffffffff);\
-		RTMP_ASIC_INTERRUPT_ENABLE(pAd); }
-
-/* ----------------- MLME Related MACRO ----------------- */
-#define RTMP_MLME_HANDLER(pAd)			MlmeHandler(pAd)
-
-#define RTMP_MLME_PRE_SANITY_CHECK(pAd)
-
-#define RTMP_MLME_STA_QUICK_RSP_WAKE_UP(pAd)	\
-		RTMPSetTimer(&pAd->StaCfg.StaQuickResponeForRateUpTimer, 100);
-
-#define RTMP_MLME_RESET_STATE_MACHINE(pAd)	\
-		MlmeRestartStateMachine(pAd)
-
-#define RTMP_HANDLE_COUNTER_MEASURE(_pAd, _pEntry)\
-		HandleCounterMeasure(_pAd, _pEntry)
-
-/* ----------------- Power Save Related MACRO ----------------- */
-#define RTMP_PS_POLL_ENQUEUE(pAd)				EnqueuePsPoll(pAd)
-
-/* For RTMPPCIePowerLinkCtrlRestore () function */
-#define RESTORE_HALT		1
-#define RESTORE_WAKEUP		2
-#define RESTORE_CLOSE           3
-
-#define PowerSafeCID		1
-#define PowerRadioOffCID	2
-#define PowerWakeCID		3
-#define CID0MASK		0x000000ff
-#define CID1MASK		0x0000ff00
-#define CID2MASK		0x00ff0000
-#define CID3MASK		0xff000000
-
-#define RTMP_STA_FORCE_WAKEUP(pAd, bFromTx) \
-    RT28xxPciStaAsicForceWakeup(pAd, bFromTx);
-
-#define RTMP_STA_SLEEP_THEN_AUTO_WAKEUP(pAd, TbttNumToNextWakeUp) \
-    RT28xxPciStaAsicSleepThenAutoWakeup(pAd, TbttNumToNextWakeUp);
-
-#define RTMP_SET_PSM_BIT(_pAd, _val) \
-	MlmeSetPsmBit(_pAd, _val);
-
-#define RTMP_MLME_RADIO_ON(pAd) \
-    RT28xxPciMlmeRadioOn(pAd);
-
-#define RTMP_MLME_RADIO_OFF(pAd) \
-    RT28xxPciMlmeRadioOFF(pAd);
-
-#endif /*__MAC_PCI_H__ // */
diff -druN linux-2.6.39-libre/drivers/staging/rt2860/chip/mac_usb.h linux-3.0-rc7-libre/drivers/staging/rt2860/chip/mac_usb.h
--- linux-2.6.39-libre/drivers/staging/rt2860/chip/mac_usb.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rt2860/chip/mac_usb.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,345 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, 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.             *
- *                                                                       *
- *************************************************************************
-
-    Module Name:
-		mac_usb.h
-
-    Abstract:
-
-    Revision History:
-    Who          	When            What
-    Justin P. Mattock	11/07/2010	Fix a typo
-    ---------    ----------    ----------------------------------------------
- */
-
-#ifndef __MAC_USB_H__
-#define __MAC_USB_H__
-
-#include "../rtmp_type.h"
-#include "rtmp_mac.h"
-#include "rtmp_phy.h"
-#include "../rtmp_iface.h"
-#include "../rtmp_dot11.h"
-
-#define USB_CYC_CFG				0x02a4
-
-#define BEACON_RING_SIZE		2
-#define MGMTPIPEIDX			0	/* EP6 is highest priority */
-
-#define RTMP_PKT_TAIL_PADDING	11	/* 3(max 4 byte padding) + 4 (last packet padding) + 4 (MaxBulkOutsize align padding) */
-
-#define fRTMP_ADAPTER_NEED_STOP_TX		\
-		(fRTMP_ADAPTER_NIC_NOT_EXIST | fRTMP_ADAPTER_HALT_IN_PROGRESS |	\
-		 fRTMP_ADAPTER_RESET_IN_PROGRESS | fRTMP_ADAPTER_BULKOUT_RESET | \
-		 fRTMP_ADAPTER_RADIO_OFF | fRTMP_ADAPTER_REMOVE_IN_PROGRESS)
-
-/* */
-/* RXINFO appends at the end of each rx packet. */
-/* */
-#define RXINFO_SIZE				4
-#define RT2870_RXDMALEN_FIELD_SIZE	4
-
-typedef struct PACKED rt_rxinfo {
-	u32 BA:1;
-	u32 DATA:1;
-	u32 NULLDATA:1;
-	u32 FRAG:1;
-	u32 U2M:1;		/* 1: this RX frame is unicast to me */
-	u32 Mcast:1;		/* 1: this is a multicast frame */
-	u32 Bcast:1;		/* 1: this is a broadcast frame */
-	u32 MyBss:1;		/* 1: this frame belongs to the same BSSID */
-	u32 Crc:1;		/* 1: CRC error */
-	u32 CipherErr:2;	/* 0: decryption okay, 1:ICV error, 2:MIC error, 3:KEY not valid */
-	u32 AMSDU:1;		/* rx with 802.3 header, not 802.11 header. */
-	u32 HTC:1;
-	u32 RSSI:1;
-	u32 L2PAD:1;
-	u32 AMPDU:1;		/* To be moved */
-	u32 Decrypted:1;
-	u32 PlcpRssil:1;
-	u32 CipherAlg:1;
-	u32 LastAMSDU:1;
-	u32 PlcpSignal:12;
-} RT28XX_RXD_STRUC, *PRT28XX_RXD_STRUC;
-
-/* */
-/* TXINFO */
-/* */
-#define TXINFO_SIZE				4
-
-struct rt_txinfo {
-	/* Word 0 */
-	u32 USBDMATxPktLen:16;	/*used ONLY in USB bulk Aggregation,  Total byte counts of all sub-frame. */
-	u32 rsv:8;
-	u32 WIV:1;		/* Wireless Info Valid. 1 if Driver already fill WI,  o if DMA needs to copy WI to correct position */
-	u32 QSEL:2;		/* select on-chip FIFO ID for 2nd-stage output scheduler.0:MGMT, 1:HCCA 2:EDCA */
-	u32 SwUseLastRound:1;	/* Software use. */
-	u32 rsv2:2;		/* Software use. */
-	u32 USBDMANextVLD:1;	/*used ONLY in USB bulk Aggregation, NextValid */
-	u32 USBDMATxburst:1;	/*used ONLY in USB bulk Aggre. Force USB DMA transmit frame from current selected endpoint */
-};
-
-/* */
-/* Management ring buffer format */
-/* */
-struct rt_mgmt {
-	BOOLEAN Valid;
-	u8 *pBuffer;
-	unsigned long Length;
-};
-
-/*////////////////////////////////////////////////////////////////////////// */
-/* The struct rt_tx_buffer structure forms the transmitted USB packet to the device */
-/*////////////////////////////////////////////////////////////////////////// */
-struct rt_tx_buffer {
-	union {
-		u8 WirelessPacket[TX_BUFFER_NORMSIZE];
-		struct rt_header_802_11 NullFrame;
-		struct rt_pspoll_frame PsPollPacket;
-		struct rt_rts_frame RTSFrame;
-	} field;
-	u8 Aggregation[4];	/*Buffer for save Aggregation size. */
-};
-
-struct rt_httx_buffer {
-	union {
-		u8 WirelessPacket[MAX_TXBULK_SIZE];
-		struct rt_header_802_11 NullFrame;
-		struct rt_pspoll_frame PsPollPacket;
-		struct rt_rts_frame RTSFrame;
-	} field;
-	u8 Aggregation[4];	/*Buffer for save Aggregation size. */
-};
-
-/* used to track driver-generated write irps */
-struct rt_tx_context {
-	void *pAd;		/*Initialized in MiniportInitialize */
-	PURB pUrb;		/*Initialized in MiniportInitialize */
-	PIRP pIrp;		/*used to cancel pending bulk out. */
-	/*Initialized in MiniportInitialize */
-	struct rt_tx_buffer *TransferBuffer;	/*Initialized in MiniportInitialize */
-	unsigned long BulkOutSize;
-	u8 BulkOutPipeId;
-	u8 SelfIdx;
-	BOOLEAN InUse;
-	BOOLEAN bWaitingBulkOut;	/* at least one packet is in this TxContext, ready for making IRP anytime. */
-	BOOLEAN bFullForBulkOut;	/* all tx buffer are full , so waiting for tx bulkout. */
-	BOOLEAN IRPPending;
-	BOOLEAN LastOne;
-	BOOLEAN bAggregatible;
-	u8 Header_802_3[LENGTH_802_3];
-	u8 Rsv[2];
-	unsigned long DataOffset;
-	u32 TxRate;
-	dma_addr_t data_dma;	/* urb dma on linux */
-
-};
-
-/* used to track driver-generated write irps */
-struct rt_ht_tx_context {
-	void *pAd;		/*Initialized in MiniportInitialize */
-	PURB pUrb;		/*Initialized in MiniportInitialize */
-	PIRP pIrp;		/*used to cancel pending bulk out. */
-	/*Initialized in MiniportInitialize */
-	struct rt_httx_buffer *TransferBuffer;	/*Initialized in MiniportInitialize */
-	unsigned long BulkOutSize;	/* Indicate the total bulk-out size in bytes in one bulk-transmission */
-	u8 BulkOutPipeId;
-	BOOLEAN IRPPending;
-	BOOLEAN LastOne;
-	BOOLEAN bCurWriting;
-	BOOLEAN bRingEmpty;
-	BOOLEAN bCopySavePad;
-	u8 SavedPad[8];
-	u8 Header_802_3[LENGTH_802_3];
-	unsigned long CurWritePosition;	/* Indicate the buffer offset which packet will be inserted start from. */
-	unsigned long CurWriteRealPos;	/* Indicate the buffer offset which packet now are writing to. */
-	unsigned long NextBulkOutPosition;	/* Indicate the buffer start offset of a bulk-transmission */
-	unsigned long ENextBulkOutPosition;	/* Indicate the buffer end offset of a bulk-transmission */
-	u32 TxRate;
-	dma_addr_t data_dma;	/* urb dma on linux */
-};
-
-/* */
-/* Structure to keep track of receive packets and buffers to indicate */
-/* receive data to the protocol. */
-/* */
-struct rt_rx_context {
-	u8 *TransferBuffer;
-	void *pAd;
-	PIRP pIrp;		/*used to cancel pending bulk in. */
-	PURB pUrb;
-	/*These 2 Boolean shouldn't both be 1 at the same time. */
-	unsigned long BulkInOffset;	/* number of packets waiting for reordering . */
-/*      BOOLEAN                         ReorderInUse;   // At least one packet in this buffer are in reordering buffer and wait for receive indication */
-	BOOLEAN bRxHandling;	/* Notify this packet is being process now. */
-	BOOLEAN InUse;		/* USB Hardware Occupied. Wait for USB HW to put packet. */
-	BOOLEAN Readable;	/* Receive Complete back. OK for driver to indicate receiving packet. */
-	BOOLEAN IRPPending;	/* TODO: To be removed */
-	atomic_t IrpLock;
-	spinlock_t RxContextLock;
-	dma_addr_t data_dma;	/* urb dma on linux */
-};
-
-/******************************************************************************
-
-	USB Frimware Related MACRO
-
-******************************************************************************/
-/* 8051 firmware image for usb - use last-half base address = 0x3000 */
-#define FIRMWARE_IMAGE_BASE			0x3000
-#define MAX_FIRMWARE_IMAGE_SIZE		0x1000	/* 4kbyte */
-
-#define RTMP_WRITE_FIRMWARE(_pAd, _pFwImage, _FwLen)		\
-	RTUSBFirmwareWrite(_pAd, _pFwImage, _FwLen)
-
-/******************************************************************************
-
-	USB TX Related MACRO
-
-******************************************************************************/
-#define RTMP_START_DEQUEUE(pAd, QueIdx, irqFlags)				\
-			do {													\
-				RTMP_IRQ_LOCK(&pAd->DeQueueLock[QueIdx], irqFlags);		\
-				if (pAd->DeQueueRunning[QueIdx]) {						\
-					RTMP_IRQ_UNLOCK(&pAd->DeQueueLock[QueIdx], irqFlags); \
-					DBGPRINT(RT_DEBUG_OFF, ("DeQueueRunning[%d]= TRUE!\n", QueIdx));		\
-					continue;											\
-				} else {												\
-					pAd->DeQueueRunning[QueIdx] = TRUE;					\
-					RTMP_IRQ_UNLOCK(&pAd->DeQueueLock[QueIdx], irqFlags);\
-				}														\
-			} while (0)
-
-#define RTMP_STOP_DEQUEUE(pAd, QueIdx, irqFlags)						\
-			do {													\
-				RTMP_IRQ_LOCK(&pAd->DeQueueLock[QueIdx], irqFlags);		\
-				pAd->DeQueueRunning[QueIdx] = FALSE;					\
-				RTMP_IRQ_UNLOCK(&pAd->DeQueueLock[QueIdx], irqFlags);	\
-			} while (0)
-
-#define	RTMP_HAS_ENOUGH_FREE_DESC(pAd, pTxBlk, freeNum, pPacket) \
-		(RTUSBFreeDescriptorRequest(pAd, pTxBlk->QueIdx, (pTxBlk->TotalFrameLen + GET_OS_PKT_LEN(pPacket))) == NDIS_STATUS_SUCCESS)
-
-#define RTMP_RELEASE_DESC_RESOURCE(pAd, QueIdx)			\
-		do {} while (0)
-
-#define NEED_QUEUE_BACK_FOR_AGG(_pAd, _QueIdx, _freeNum, _TxFrameType)		\
-		((_TxFrameType == TX_RALINK_FRAME) && \
-		(RTUSBNeedQueueBackForAgg(_pAd, _QueIdx)))
-
-#define HAL_WriteSubTxResource(pAd, pTxBlk, bIsLast, pFreeNumber)	\
-		RtmpUSB_WriteSubTxResource(pAd, pTxBlk, bIsLast, pFreeNumber)
-
-#define HAL_WriteTxResource(pAd, pTxBlk, bIsLast, pFreeNumber)	\
-		RtmpUSB_WriteSingleTxResource(pAd, pTxBlk, bIsLast, pFreeNumber)
-
-#define HAL_WriteFragTxResource(pAd, pTxBlk, fragNum, pFreeNumber) \
-		RtmpUSB_WriteFragTxResource(pAd, pTxBlk, fragNum, pFreeNumber)
-
-#define HAL_WriteMultiTxResource(pAd, pTxBlk, frameNum, pFreeNumber)	\
-		RtmpUSB_WriteMultiTxResource(pAd, pTxBlk, frameNum, pFreeNumber)
-
-#define HAL_FinalWriteTxResource(pAd, pTxBlk, totalMPDUSize, TxIdx)	\
-		RtmpUSB_FinalWriteTxResource(pAd, pTxBlk, totalMPDUSize, TxIdx)
-
-#define HAL_LastTxIdx(pAd, QueIdx, TxIdx) \
-				/*RtmpUSBDataLastTxIdx(pAd, QueIdx,TxIdx) */
-
-#define HAL_KickOutTx(pAd, pTxBlk, QueIdx)	\
-			RtmpUSBDataKickOut(pAd, pTxBlk, QueIdx)
-
-#define HAL_KickOutMgmtTx(pAd, QueIdx, pPacket, pSrcBufVA, SrcBufLen)	\
-			RtmpUSBMgmtKickOut(pAd, QueIdx, pPacket, pSrcBufVA, SrcBufLen)
-
-#define HAL_KickOutNullFrameTx(_pAd, _QueIdx, _pNullFrame, _frameLen)	\
-			RtmpUSBNullFrameKickOut(_pAd, _QueIdx, _pNullFrame, _frameLen)
-
-#define GET_TXRING_FREENO(_pAd, _QueIdx)	(_QueIdx)	/*(_pAd->TxRing[_QueIdx].TxSwFreeIdx) */
-#define GET_MGMTRING_FREENO(_pAd)			(_pAd->MgmtRing.TxSwFreeIdx)
-
-/* ----------------- RX Related MACRO ----------------- */
-
-/*
-  *	Device Hardware Interface Related MACRO
-  */
-#define RTMP_IRQ_INIT(pAd)				do {} while (0)
-#define RTMP_IRQ_ENABLE(pAd)			do {} while (0)
-
-/*
-  *	MLME Related MACRO
-  */
-#define RTMP_MLME_HANDLER(pAd)			RTUSBMlmeUp(pAd)
-
-#define RTMP_MLME_PRE_SANITY_CHECK(pAd)								\
-	{	if ((pAd->CommonCfg.bHardwareRadio == TRUE) &&					\
-			(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) &&		\
-			(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS))) {	\
-			RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_CHECK_GPIO, NULL, 0); } }
-
-#define RTMP_MLME_STA_QUICK_RSP_WAKE_UP(pAd)	\
-	{	RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_QKERIODIC_EXECUT, NULL, 0);	\
-		RTUSBMlmeUp(pAd); }
-
-#define RTMP_MLME_RESET_STATE_MACHINE(pAd)	\
-	{	MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_RESET_CONF, 0, NULL);	\
-		RTUSBMlmeUp(pAd); }
-
-#define RTMP_HANDLE_COUNTER_MEASURE(_pAd, _pEntry)		\
-	{	RTUSBEnqueueInternalCmd(_pAd, CMDTHREAD_802_11_COUNTER_MEASURE, _pEntry, sizeof(struct rt_mac_table_entry));	\
-		RTUSBMlmeUp(_pAd);									\
-	}
-
-/*
-  *	Power Save Related MACRO
-  */
-#define RTMP_PS_POLL_ENQUEUE(pAd)						\
-	{	RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_PSPOLL);	\
-		RTUSBKickBulkOut(pAd); }
-
-#define RTMP_STA_FORCE_WAKEUP(_pAd, bFromTx) \
-	RT28xxUsbStaAsicForceWakeup(_pAd, bFromTx);
-
-#define RTMP_STA_SLEEP_THEN_AUTO_WAKEUP(pAd, TbttNumToNextWakeUp) \
-    RT28xxUsbStaAsicSleepThenAutoWakeup(pAd, TbttNumToNextWakeUp);
-
-#define RTMP_SET_PSM_BIT(_pAd, _val) \
-	{\
-		if ((_pAd)->StaCfg.WindowsPowerMode == Ndis802_11PowerModeFast_PSP) \
-			MlmeSetPsmBit(_pAd, _val);\
-		else { \
-			u16 _psm_val; \
-			_psm_val = _val; \
-			RTUSBEnqueueInternalCmd(_pAd, CMDTHREAD_SET_PSM_BIT, &(_psm_val), sizeof(u16)); \
-		} \
-	}
-
-#define RTMP_MLME_RADIO_ON(pAd) \
-    RT28xxUsbMlmeRadioOn(pAd);
-
-#define RTMP_MLME_RADIO_OFF(pAd) \
-    RT28xxUsbMlmeRadioOFF(pAd);
-
-#endif /*__MAC_USB_H__ // */
diff -druN linux-2.6.39-libre/drivers/staging/rt2860/chip/rt2860.h linux-3.0-rc7-libre/drivers/staging/rt2860/chip/rt2860.h
--- linux-2.6.39-libre/drivers/staging/rt2860/chip/rt2860.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rt2860/chip/rt2860.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,54 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, 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 __RT2860_H__
-#define __RT2860_H__
-
-#include "mac_pci.h"
-
-#ifndef RTMP_PCI_SUPPORT
-#error "For RT2860, you should define the compile flag -DRTMP_PCI_SUPPORT"
-#endif
-
-#ifndef RTMP_MAC_PCI
-#error "For RT2880, you should define the compile flag -DRTMP_MAC_PCI"
-#endif
-
-/* */
-/* Device ID & Vendor ID, these values should match EEPROM value */
-/* */
-#define NIC2860_PCI_DEVICE_ID	0x0601
-#define NIC2860_PCIe_DEVICE_ID	0x0681
-#define NIC2760_PCI_DEVICE_ID	0x0701	/* 1T/2R Cardbus ??? */
-#define NIC2790_PCIe_DEVICE_ID  0x0781	/* 1T/2R miniCard */
-
-#define VEN_AWT_PCIe_DEVICE_ID	0x1059
-#define VEN_AWT_PCI_VENDOR_ID		0x1A3B
-
-#define EDIMAX_PCI_VENDOR_ID		0x1432
-
-#endif /*__RT2860_H__ // */
diff -druN linux-2.6.39-libre/drivers/staging/rt2860/chip/rt2870.h linux-3.0-rc7-libre/drivers/staging/rt2860/chip/rt2870.h
--- linux-2.6.39-libre/drivers/staging/rt2860/chip/rt2870.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rt2860/chip/rt2870.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,46 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, 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 __RT2870_H__
-#define __RT2870_H__
-
-#ifdef RT2870
-
-#ifndef RTMP_USB_SUPPORT
-#error "For RT2870, you should define the compile flag -DRTMP_USB_SUPPORT"
-#endif
-
-#ifndef RTMP_MAC_USB
-#error "For RT2870, you should define the compile flag -DRTMP_MAC_USB"
-#endif
-
-#include "../rtmp_type.h"
-#include "mac_usb.h"
-
-/*#define RTMP_CHIP_NAME                "RT2870" */
-
-#endif /* RT2870 // */
-#endif /*__RT2870_H__ // */
diff -druN linux-2.6.39-libre/drivers/staging/rt2860/chip/rt3070.h linux-3.0-rc7-libre/drivers/staging/rt2860/chip/rt3070.h
--- linux-2.6.39-libre/drivers/staging/rt2860/chip/rt3070.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rt2860/chip/rt3070.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,67 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, 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.             *
- *                                                                       *
- *************************************************************************
-
-    Module Name:
-	rt3070.h
-
-    Abstract:
-
-    Revision History:
-    Who          When          What
-    ---------    ----------    ----------------------------------------------
- */
-
-#ifndef __RT3070_H__
-#define __RT3070_H__
-
-#ifdef RT3070
-
-#ifndef RTMP_USB_SUPPORT
-#error "For RT3070, you should define the compile flag -DRTMP_USB_SUPPORT"
-#endif
-
-#ifndef RTMP_MAC_USB
-#error "For RT3070, you should define the compile flag -DRTMP_MAC_USB"
-#endif
-
-#ifndef RTMP_RF_RW_SUPPORT
-#error "For RT3070, you should define the compile flag -DRTMP_RF_RW_SUPPORT"
-#endif
-
-#ifndef RT30xx
-#error "For RT3070, you should define the compile flag -DRT30xx"
-#endif
-
-#include "mac_usb.h"
-#include "rt30xx.h"
-
-/* */
-/* Device ID & Vendor ID, these values should match EEPROM value */
-/* */
-
-#endif /* RT3070 // */
-
-#endif /*__RT3070_H__ // */
diff -druN linux-2.6.39-libre/drivers/staging/rt2860/chip/rt3090.h linux-3.0-rc7-libre/drivers/staging/rt2860/chip/rt3090.h
--- linux-2.6.39-libre/drivers/staging/rt2860/chip/rt3090.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rt2860/chip/rt3090.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,72 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, 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.             *
- *                                                                       *
- *************************************************************************
-
-    Module Name:
-	rt3090.h
-
-    Abstract:
-
-    Revision History:
-    Who          When          What
-    ---------    ----------    ----------------------------------------------
- */
-
-#ifndef __RT3090_H__
-#define __RT3090_H__
-
-#ifdef RT3090
-
-#ifndef RTMP_PCI_SUPPORT
-#error "For RT3090, you should define the compile flag -DRTMP_PCI_SUPPORT"
-#endif
-
-#ifndef RTMP_MAC_PCI
-#error "For RT3090, you should define the compile flag -DRTMP_MAC_PCI"
-#endif
-
-#ifndef RTMP_RF_RW_SUPPORT
-#error "For RT3090, you should define the compile flag -DRTMP_RF_RW_SUPPORT"
-#endif
-
-#ifndef RT30xx
-#error "For RT3090, you should define the compile flag -DRT30xx"
-#endif
-
-#define PCIE_PS_SUPPORT
-
-#include "mac_pci.h"
-#include "rt30xx.h"
-
-/* */
-/* Device ID & Vendor ID, these values should match EEPROM value */
-/* */
-#define NIC3090_PCIe_DEVICE_ID  0x3090	/* 1T/1R miniCard */
-#define NIC3091_PCIe_DEVICE_ID  0x3091	/* 1T/2R miniCard */
-#define NIC3092_PCIe_DEVICE_ID  0x3092	/* 2T/2R miniCard */
-
-#endif /* RT3090 // */
-
-#endif /*__RT3090_H__ // */
diff -druN linux-2.6.39-libre/drivers/staging/rt2860/chip/rt30xx.h linux-3.0-rc7-libre/drivers/staging/rt2860/chip/rt30xx.h
--- linux-2.6.39-libre/drivers/staging/rt2860/chip/rt30xx.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rt2860/chip/rt30xx.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,47 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, 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.             *
- *                                                                       *
- *************************************************************************
-
-    Module Name:
-	rt30xx.h
-
-    Abstract:
-
-    Revision History:
-    Who          When          What
-    ---------    ----------    ----------------------------------------------
- */
-
-#ifndef __RT30XX_H__
-#define __RT30XX_H__
-
-#ifdef RT30xx
-
-extern struct rt_reg_pair RT30xx_RFRegTable[];
-extern u8 NUM_RF_REG_PARMS;
-
-#endif /* RT30xx // */
-
-#endif /*__RT30XX_H__ // */
diff -druN linux-2.6.39-libre/drivers/staging/rt2860/chip/rtmp_mac.h linux-3.0-rc7-libre/drivers/staging/rt2860/chip/rtmp_mac.h
--- linux-2.6.39-libre/drivers/staging/rt2860/chip/rtmp_mac.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rt2860/chip/rtmp_mac.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,1308 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, 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.             *
- *                                                                       *
- *************************************************************************
-
-	Module Name:
-	rtmp_mac.h
-
-	Abstract:
-	Ralink Wireless Chip MAC related definition & structures
-
-	Revision History:
-	Who			When		  What
-	Justin P. Mattock	11/07/2010	  Fix a comments, and typos
-	--------	----------	  ----------------------------------------------
-*/
-
-#ifndef __RTMP_MAC_H__
-#define __RTMP_MAC_H__
-
-/* ================================================================================= */
-/* TX / RX ring descriptor format */
-/* ================================================================================= */
-
-/* the first 24-byte in TXD is called TXINFO and will be DMAed to MAC block through TXFIFO. */
-/* MAC block uses this TXINFO to control the transmission behavior of this frame. */
-#define FIFO_MGMT                 0
-#define FIFO_HCCA                 1
-#define FIFO_EDCA                 2
-
-/* */
-/* TXD Wireless Information format for Tx ring and Mgmt Ring */
-/* */
-/*txop : for txop mode */
-/* 0:txop for the MPDU frame will be handles by ASIC by register */
-/* 1/2/3:the MPDU frame is send after PIFS/backoff/SIFS */
-struct PACKED rt_txwi {
-	/* Word 0 */
-	/* ex: 00 03 00 40 means txop = 3, PHYMODE = 1 */
-	u32 FRAG:1;		/* 1 to inform TKIP engine this is a fragment. */
-	u32 MIMOps:1;	/* the remote peer is in dynamic MIMO-PS mode */
-	u32 CFACK:1;
-	u32 TS:1;
-
-	u32 AMPDU:1;
-	u32 MpduDensity:3;
-	u32 txop:2;		/*FOR "THIS" frame. 0:HT TXOP rule , 1:PIFS TX ,2:Backoff, 3:sifs only when previous frame exchange is successful. */
-	u32 rsv:6;
-
-	u32 MCS:7;
-	u32 BW:1;		/*channel bandwidth 20MHz or 40 MHz */
-	u32 ShortGI:1;
-	u32 STBC:2;		/* 1: STBC support MCS =0-7,   2,3 : RESERVE */
-	u32 Ifs:1;		/* */
-/*      u32          rsv2:2; //channel bandwidth 20MHz or 40 MHz */
-	u32 rsv2:1;
-	u32 TxBF:1;		/* 3*3 */
-	u32 PHYMODE:2;
-	/* Word1 */
-	/* ex:  1c ff 38 00 means ACK=0, BAWinSize=7, MPDUtotalByteCount = 0x38 */
-	u32 ACK:1;
-	u32 NSEQ:1;
-	u32 BAWinSize:6;
-	u32 WirelessCliID:8;
-	u32 MPDUtotalByteCount:12;
-	u32 PacketId:4;
-	/*Word2 */
-	u32 IV;
-	/*Word3 */
-	u32 EIV;
-};
-
-/* */
-/* RXWI wireless information format, in PBF. invisible in driver. */
-/* */
-struct PACKED rt_rxwi {
-	/* Word 0 */
-	u32 WirelessCliID:8;
-	u32 KeyIndex:2;
-	u32 BSSID:3;
-	u32 UDF:3;
-	u32 MPDUtotalByteCount:12;
-	u32 TID:4;
-	/* Word 1 */
-	u32 FRAG:4;
-	u32 SEQUENCE:12;
-	u32 MCS:7;
-	u32 BW:1;
-	u32 ShortGI:1;
-	u32 STBC:2;
-	u32 rsv:3;
-	u32 PHYMODE:2;	/* 1: this RX frame is unicast to me */
-	/*Word2 */
-	u32 RSSI0:8;
-	u32 RSSI1:8;
-	u32 RSSI2:8;
-	u32 rsv1:8;
-	/*Word3 */
-	u32 SNR0:8;
-	u32 SNR1:8;
-	u32 FOFFSET:8;	/* RT35xx */
-	u32 rsv2:8;
-	/*u32                rsv2:16; */
-};
-
-/* ================================================================================= */
-/* Register format */
-/* ================================================================================= */
-
-/* */
-/* SCH/DMA registers - base address 0x0200 */
-/* */
-/* INT_SOURCE_CSR: Interrupt source register. Write one to clear corresponding bit */
-/* */
-#define DMA_CSR0		0x200
-#define INT_SOURCE_CSR		0x200
-typedef union _INT_SOURCE_CSR_STRUC {
-	struct {
-		u32 RxDelayINT:1;
-		u32 TxDelayINT:1;
-		u32 RxDone:1;
-		u32 Ac0DmaDone:1;	/*4 */
-		u32 Ac1DmaDone:1;
-		u32 Ac2DmaDone:1;
-		u32 Ac3DmaDone:1;
-		u32 HccaDmaDone:1;	/* bit7 */
-		u32 MgmtDmaDone:1;
-		u32 MCUCommandINT:1;	/*bit 9 */
-		u32 RxTxCoherent:1;
-		u32 TBTTInt:1;
-		u32 PreTBTT:1;
-		u32 TXFifoStatusInt:1;	/*FIFO Statistics is full, sw should read 0x171c */
-		u32 AutoWakeup:1;	/*bit14 */
-		u32 GPTimer:1;
-		u32 RxCoherent:1;	/*bit16 */
-		u32 TxCoherent:1;
-		u32: 14;
-	} field;
-	u32 word;
-} INT_SOURCE_CSR_STRUC, *PINT_SOURCE_CSR_STRUC;
-
-/* */
-/* INT_MASK_CSR:   Interrupt MASK register.   1: the interrupt is mask OFF */
-/* */
-#define INT_MASK_CSR        0x204
-typedef union _INT_MASK_CSR_STRUC {
-	struct {
-		u32 RXDelay_INT_MSK:1;
-		u32 TxDelay:1;
-		u32 RxDone:1;
-		u32 Ac0DmaDone:1;
-		u32 Ac1DmaDone:1;
-		u32 Ac2DmaDone:1;
-		u32 Ac3DmaDone:1;
-		u32 HccaDmaDone:1;
-		u32 MgmtDmaDone:1;
-		u32 MCUCommandINT:1;
-		u32: 20;
-		u32 RxCoherent:1;
-		u32 TxCoherent:1;
-	} field;
-	u32 word;
-} INT_MASK_CSR_STRUC, *PINT_MASK_CSR_STRUC;
-
-#define WPDMA_GLO_CFG	0x208
-typedef union _WPDMA_GLO_CFG_STRUC {
-	struct {
-		u32 EnableTxDMA:1;
-		u32 TxDMABusy:1;
-		u32 EnableRxDMA:1;
-		u32 RxDMABusy:1;
-		u32 WPDMABurstSIZE:2;
-		u32 EnTXWriteBackDDONE:1;
-		u32 BigEndian:1;
-		u32 RXHdrScater:8;
-		u32 HDR_SEG_LEN:16;
-	} field;
-	u32 word;
-} WPDMA_GLO_CFG_STRUC, *PWPDMA_GLO_CFG_STRUC;
-
-#define WPDMA_RST_IDX	0x20c
-typedef union _WPDMA_RST_IDX_STRUC {
-	struct {
-		u32 RST_DTX_IDX0:1;
-		u32 RST_DTX_IDX1:1;
-		u32 RST_DTX_IDX2:1;
-		u32 RST_DTX_IDX3:1;
-		u32 RST_DTX_IDX4:1;
-		u32 RST_DTX_IDX5:1;
-		u32 rsv:10;
-		u32 RST_DRX_IDX0:1;
-		u32: 15;
-	} field;
-	u32 word;
-} WPDMA_RST_IDX_STRUC, *PWPDMA_RST_IDX_STRUC;
-#define DELAY_INT_CFG  0x0210
-typedef union _DELAY_INT_CFG_STRUC {
-	struct {
-		u32 RXMAX_PTIME:8;
-		u32 RXMAX_PINT:7;
-		u32 RXDLY_INT_EN:1;
-		u32 TXMAX_PTIME:8;
-		u32 TXMAX_PINT:7;
-		u32 TXDLY_INT_EN:1;
-	} field;
-	u32 word;
-} DELAY_INT_CFG_STRUC, *PDELAY_INT_CFG_STRUC;
-#define WMM_AIFSN_CFG   0x0214
-typedef union _AIFSN_CSR_STRUC {
-	struct {
-		u32 Aifsn0:4;	/* for AC_BE */
-		u32 Aifsn1:4;	/* for AC_BK */
-		u32 Aifsn2:4;	/* for AC_VI */
-		u32 Aifsn3:4;	/* for AC_VO */
-		u32 Rsv:16;
-	} field;
-	u32 word;
-} AIFSN_CSR_STRUC, *PAIFSN_CSR_STRUC;
-/* */
-/* CWMIN_CSR: CWmin for each EDCA AC */
-/* */
-#define WMM_CWMIN_CFG   0x0218
-typedef union _CWMIN_CSR_STRUC {
-	struct {
-		u32 Cwmin0:4;	/* for AC_BE */
-		u32 Cwmin1:4;	/* for AC_BK */
-		u32 Cwmin2:4;	/* for AC_VI */
-		u32 Cwmin3:4;	/* for AC_VO */
-		u32 Rsv:16;
-	} field;
-	u32 word;
-} CWMIN_CSR_STRUC, *PCWMIN_CSR_STRUC;
-
-/* */
-/* CWMAX_CSR: CWmin for each EDCA AC */
-/* */
-#define WMM_CWMAX_CFG   0x021c
-typedef union _CWMAX_CSR_STRUC {
-	struct {
-		u32 Cwmax0:4;	/* for AC_BE */
-		u32 Cwmax1:4;	/* for AC_BK */
-		u32 Cwmax2:4;	/* for AC_VI */
-		u32 Cwmax3:4;	/* for AC_VO */
-		u32 Rsv:16;
-	} field;
-	u32 word;
-} CWMAX_CSR_STRUC, *PCWMAX_CSR_STRUC;
-
-/* */
-/* AC_TXOP_CSR0: AC_BK/AC_BE TXOP register */
-/* */
-#define WMM_TXOP0_CFG    0x0220
-typedef union _AC_TXOP_CSR0_STRUC {
-	struct {
-		u16 Ac0Txop;	/* for AC_BK, in unit of 32us */
-		u16 Ac1Txop;	/* for AC_BE, in unit of 32us */
-	} field;
-	u32 word;
-} AC_TXOP_CSR0_STRUC, *PAC_TXOP_CSR0_STRUC;
-
-/* */
-/* AC_TXOP_CSR1: AC_VO/AC_VI TXOP register */
-/* */
-#define WMM_TXOP1_CFG    0x0224
-typedef union _AC_TXOP_CSR1_STRUC {
-	struct {
-		u16 Ac2Txop;	/* for AC_VI, in unit of 32us */
-		u16 Ac3Txop;	/* for AC_VO, in unit of 32us */
-	} field;
-	u32 word;
-} AC_TXOP_CSR1_STRUC, *PAC_TXOP_CSR1_STRUC;
-
-#define RINGREG_DIFF			0x10
-#define GPIO_CTRL_CFG    0x0228	/*MAC_CSR13 */
-#define MCU_CMD_CFG    0x022c
-#define TX_BASE_PTR0     0x0230	/*AC_BK base address */
-#define TX_MAX_CNT0      0x0234
-#define TX_CTX_IDX0       0x0238
-#define TX_DTX_IDX0      0x023c
-#define TX_BASE_PTR1     0x0240	/*AC_BE base address */
-#define TX_MAX_CNT1      0x0244
-#define TX_CTX_IDX1       0x0248
-#define TX_DTX_IDX1      0x024c
-#define TX_BASE_PTR2     0x0250	/*AC_VI base address */
-#define TX_MAX_CNT2      0x0254
-#define TX_CTX_IDX2       0x0258
-#define TX_DTX_IDX2      0x025c
-#define TX_BASE_PTR3     0x0260	/*AC_VO base address */
-#define TX_MAX_CNT3      0x0264
-#define TX_CTX_IDX3       0x0268
-#define TX_DTX_IDX3      0x026c
-#define TX_BASE_PTR4     0x0270	/*HCCA base address */
-#define TX_MAX_CNT4      0x0274
-#define TX_CTX_IDX4       0x0278
-#define TX_DTX_IDX4      0x027c
-#define TX_BASE_PTR5     0x0280	/*MGMT base address */
-#define  TX_MAX_CNT5     0x0284
-#define TX_CTX_IDX5       0x0288
-#define TX_DTX_IDX5      0x028c
-#define TX_MGMTMAX_CNT      TX_MAX_CNT5
-#define TX_MGMTCTX_IDX       TX_CTX_IDX5
-#define TX_MGMTDTX_IDX      TX_DTX_IDX5
-#define RX_BASE_PTR     0x0290	/*RX base address */
-#define RX_MAX_CNT      0x0294
-#define RX_CRX_IDX       0x0298
-#define RX_DRX_IDX      0x029c
-
-#define USB_DMA_CFG      0x02a0
-typedef union _USB_DMA_CFG_STRUC {
-	struct {
-		u32 RxBulkAggTOut:8;	/*Rx Bulk Aggregation TimeOut  in unit of 33ns */
-		u32 RxBulkAggLmt:8;	/*Rx Bulk Aggregation Limit  in unit of 256 bytes */
-		u32 phyclear:1;	/*phy watch dog enable. write 1 */
-		u32 rsv:2;
-		u32 TxClear:1;	/*Clear USB DMA TX path */
-		u32 TxopHalt:1;	/*Halt TXOP count down when TX buffer is full. */
-		u32 RxBulkAggEn:1;	/*Enable Rx Bulk Aggregation */
-		u32 RxBulkEn:1;	/*Enable USB DMA Rx */
-		u32 TxBulkEn:1;	/*Enable USB DMA Tx */
-		u32 EpoutValid:6;	/*OUT endpoint data valid */
-		u32 RxBusy:1;	/*USB DMA RX FSM busy */
-		u32 TxBusy:1;	/*USB DMA TX FSM busy */
-	} field;
-	u32 word;
-} USB_DMA_CFG_STRUC, *PUSB_DMA_CFG_STRUC;
-
-/* */
-/*  3  PBF  registers */
-/* */
-/* */
-/* Most are for debug. Driver doesn't touch PBF register. */
-#define PBF_SYS_CTRL	 0x0400
-#define PBF_CFG                 0x0408
-#define PBF_MAX_PCNT	 0x040C
-#define PBF_CTRL		0x0410
-#define PBF_INT_STA	 0x0414
-#define PBF_INT_ENA	 0x0418
-#define TXRXQ_PCNT	 0x0438
-#define PBF_DBG			 0x043c
-#define PBF_CAP_CTRL     0x0440
-
-#ifdef RT30xx
-#ifdef RTMP_EFUSE_SUPPORT
-/* eFuse registers */
-#define EFUSE_CTRL				0x0580
-#define EFUSE_DATA0				0x0590
-#define EFUSE_DATA1				0x0594
-#define EFUSE_DATA2				0x0598
-#define EFUSE_DATA3				0x059c
-#endif /* RTMP_EFUSE_SUPPORT // */
-#endif /* RT30xx // */
-
-#define OSC_CTRL		0x5a4
-#define PCIE_PHY_TX_ATTENUATION_CTRL	0x05C8
-#define LDO_CFG0				0x05d4
-#define GPIO_SWITCH				0x05dc
-
-/* */
-/*  4  MAC  registers */
-/* */
-/* */
-/*  4.1 MAC SYSTEM  configuration registers (offset:0x1000) */
-/* */
-#define MAC_CSR0            0x1000
-typedef union _ASIC_VER_ID_STRUC {
-	struct {
-		u16 ASICRev;	/* reversion  : 0 */
-		u16 ASICVer;	/* version : 2860 */
-	} field;
-	u32 word;
-} ASIC_VER_ID_STRUC, *PASIC_VER_ID_STRUC;
-#define MAC_SYS_CTRL            0x1004	/*MAC_CSR1 */
-#define MAC_ADDR_DW0				0x1008	/* MAC ADDR DW0 */
-#define MAC_ADDR_DW1			 0x100c	/* MAC ADDR DW1 */
-/* */
-/* MAC_CSR2: STA MAC register 0 */
-/* */
-typedef union _MAC_DW0_STRUC {
-	struct {
-		u8 Byte0;	/* MAC address byte 0 */
-		u8 Byte1;	/* MAC address byte 1 */
-		u8 Byte2;	/* MAC address byte 2 */
-		u8 Byte3;	/* MAC address byte 3 */
-	} field;
-	u32 word;
-} MAC_DW0_STRUC, *PMAC_DW0_STRUC;
-
-/* */
-/* MAC_CSR3: STA MAC register 1 */
-/* */
-typedef union _MAC_DW1_STRUC {
-	struct {
-		u8 Byte4;	/* MAC address byte 4 */
-		u8 Byte5;	/* MAC address byte 5 */
-		u8 U2MeMask;
-		u8 Rsvd1;
-	} field;
-	u32 word;
-} MAC_DW1_STRUC, *PMAC_DW1_STRUC;
-
-#define MAC_BSSID_DW0				0x1010	/* MAC BSSID DW0 */
-#define MAC_BSSID_DW1				0x1014	/* MAC BSSID DW1 */
-
-/* */
-/* MAC_CSR5: BSSID register 1 */
-/* */
-typedef union _MAC_CSR5_STRUC {
-	struct {
-		u8 Byte4;	/* BSSID byte 4 */
-		u8 Byte5;	/* BSSID byte 5 */
-		u16 BssIdMask:2;	/* 0: one BSSID, 10: 4 BSSID,  01: 2 BSSID , 11: 8BSSID */
-		u16 MBssBcnNum:3;
-		u16 Rsvd:11;
-	} field;
-	u32 word;
-} MAC_CSR5_STRUC, *PMAC_CSR5_STRUC;
-
-#define MAX_LEN_CFG              0x1018	/* rt2860b max 16k bytes. bit12:13 Maximum PSDU length (power factor) 0:2^13, 1:2^14, 2:2^15, 3:2^16 */
-#define BBP_CSR_CFG			0x101c	/* */
-/* */
-/* BBP_CSR_CFG: BBP serial control register */
-/* */
-typedef union _BBP_CSR_CFG_STRUC {
-	struct {
-		u32 Value:8;	/* Register     value to program into BBP */
-		u32 RegNum:8;	/* Selected     BBP     register */
-		u32 fRead:1;	/* 0: Write BBP, 1: Read BBP */
-		u32 Busy:1;	/* 1: ASIC is busy execute BBP programming. */
-		u32 BBP_PAR_DUR:1;	/* 0: 4 MAC clock cycles  1: 8 MAC clock cycles */
-		u32 BBP_RW_MODE:1;	/* 0: use serial mode  1:parallel */
-		u32: 12;
-	} field;
-	u32 word;
-} BBP_CSR_CFG_STRUC, *PBBP_CSR_CFG_STRUC;
-#define RF_CSR_CFG0			0x1020
-/* */
-/* RF_CSR_CFG: RF control register */
-/* */
-typedef union _RF_CSR_CFG0_STRUC {
-	struct {
-		u32 RegIdAndContent:24;	/* Register value to program into BBP */
-		u32 bitwidth:5;	/* Selected BBP register */
-		u32 StandbyMode:1;	/* 0: high when stand by 1: low when standby */
-		u32 Sel:1;	/* 0:RF_LE0 activate  1:RF_LE1 activate */
-		u32 Busy:1;	/* 0: idle 1: 8busy */
-	} field;
-	u32 word;
-} RF_CSR_CFG0_STRUC, *PRF_CSR_CFG0_STRUC;
-#define RF_CSR_CFG1			0x1024
-typedef union _RF_CSR_CFG1_STRUC {
-	struct {
-		u32 RegIdAndContent:24;	/* Register value to program into BBP */
-		u32 RFGap:5;	/* Gap between BB_CONTROL_RF and RF_LE. 0: 3 system clock cycle (37.5usec) 1: 5 system clock cycle (62.5usec) */
-		u32 rsv:7;	/* 0: idle 1: 8busy */
-	} field;
-	u32 word;
-} RF_CSR_CFG1_STRUC, *PRF_CSR_CFG1_STRUC;
-#define RF_CSR_CFG2			0x1028	/* */
-typedef union _RF_CSR_CFG2_STRUC {
-	struct {
-		u32 RegIdAndContent:24;	/* Register value to program into BBP */
-		u32 rsv:8;	/* 0: idle 1: 8busy */
-	} field;
-	u32 word;
-} RF_CSR_CFG2_STRUC, *PRF_CSR_CFG2_STRUC;
-#define LED_CFG				0x102c	/*  MAC_CSR14 */
-typedef union _LED_CFG_STRUC {
-	struct {
-		u32 OnPeriod:8;	/* blinking on period unit 1ms */
-		u32 OffPeriod:8;	/* blinking off period unit 1ms */
-		u32 SlowBlinkPeriod:6;	/* slow blinking period. unit:1ms */
-		u32 rsv:2;
-		u32 RLedMode:2;	/* red Led Mode 0: off1: blinking upon TX2: periodic slow blinking3: always on */
-		u32 GLedMode:2;	/* green Led Mode */
-		u32 YLedMode:2;	/* yellow Led Mode */
-		u32 LedPolar:1;	/* Led Polarity.  0: active low1: active high */
-		u32: 1;
-	} field;
-	u32 word;
-} LED_CFG_STRUC, *PLED_CFG_STRUC;
-/* */
-/*  4.2 MAC TIMING  configuration registers (offset:0x1100) */
-/* */
-#define XIFS_TIME_CFG             0x1100	/* MAC_CSR8  MAC_CSR9 */
-typedef union _IFS_SLOT_CFG_STRUC {
-	struct {
-		u32 CckmSifsTime:8;	/*  unit 1us. Applied after CCK RX/TX */
-		u32 OfdmSifsTime:8;	/*  unit 1us. Applied after OFDM RX/TX */
-		u32 OfdmXifsTime:4;	/*OFDM SIFS. unit 1us. Applied after OFDM RX when MAC doesn't reference BBP signal BBRXEND */
-		u32 EIFS:9;	/*  unit 1us */
-		u32 BBRxendEnable:1;	/*  reference RXEND signal to begin XIFS defer */
-		u32 rsv:2;
-	} field;
-	u32 word;
-} IFS_SLOT_CFG_STRUC, *PIFS_SLOT_CFG_STRUC;
-
-#define BKOFF_SLOT_CFG             0x1104	/*  mac_csr9 last 8 bits */
-#define NAV_TIME_CFG             0x1108	/* NAV  (MAC_CSR15) */
-#define CH_TIME_CFG             0x110C	/* Count as channel busy */
-#define PBF_LIFE_TIMER             0x1110	/*TX/RX MPDU timestamp timer (free run)Unit: 1us */
-#define BCN_TIME_CFG             0x1114	/* TXRX_CSR9 */
-
-#define BCN_OFFSET0				0x042C
-#define BCN_OFFSET1				0x0430
-
-/* */
-/* BCN_TIME_CFG : Synchronization control register */
-/* */
-typedef union _BCN_TIME_CFG_STRUC {
-	struct {
-		u32 BeaconInterval:16;	/* in unit of 1/16 TU */
-		u32 bTsfTicking:1;	/* Enable TSF auto counting */
-		u32 TsfSyncMode:2;	/* Enable TSF sync, 00: disable, 01: infra mode, 10: ad-hoc mode */
-		u32 bTBTTEnable:1;
-		u32 bBeaconGen:1;	/* Enable beacon generator */
-		u32: 3;
-		u32 TxTimestampCompensate:8;
-	} field;
-	u32 word;
-} BCN_TIME_CFG_STRUC, *PBCN_TIME_CFG_STRUC;
-#define TBTT_SYNC_CFG            0x1118	/* txrx_csr10 */
-#define TSF_TIMER_DW0             0x111C	/* Local TSF timer lsb 32 bits. Read-only */
-#define TSF_TIMER_DW1             0x1120	/* msb 32 bits. Read-only. */
-#define TBTT_TIMER		0x1124	/* TImer remains till next TBTT. Read-only.  TXRX_CSR14 */
-#define INT_TIMER_CFG			0x1128	/* */
-#define INT_TIMER_EN			0x112c	/*  GP-timer and pre-tbtt Int enable */
-#define CH_IDLE_STA			0x1130	/*  channel idle time */
-#define CH_BUSY_STA			0x1134	/*  channle busy time */
-/* */
-/*  4.2 MAC POWER  configuration registers (offset:0x1200) */
-/* */
-#define MAC_STATUS_CFG             0x1200	/* old MAC_CSR12 */
-#define PWR_PIN_CFG             0x1204	/* old MAC_CSR12 */
-#define AUTO_WAKEUP_CFG             0x1208	/* old MAC_CSR10 */
-/* */
-/* AUTO_WAKEUP_CFG: Manual power control / status register */
-/* */
-typedef union _AUTO_WAKEUP_STRUC {
-	struct {
-		u32 AutoLeadTime:8;
-		u32 NumofSleepingTbtt:7;	/* ForceWake has high privilege than PutToSleep when both set */
-		u32 EnableAutoWakeup:1;	/* 0:sleep, 1:awake */
-		u32: 16;
-	} field;
-	u32 word;
-} AUTO_WAKEUP_STRUC, *PAUTO_WAKEUP_STRUC;
-/* */
-/*  4.3 MAC TX  configuration registers (offset:0x1300) */
-/* */
-
-#define EDCA_AC0_CFG	0x1300	/*AC_TXOP_CSR0 0x3474 */
-#define EDCA_AC1_CFG	0x1304
-#define EDCA_AC2_CFG	0x1308
-#define EDCA_AC3_CFG	0x130c
-typedef union _EDCA_AC_CFG_STRUC {
-	struct {
-		u32 AcTxop:8;	/*  in unit of 32us */
-		u32 Aifsn:4;	/* # of slot time */
-		u32 Cwmin:4;	/* */
-		u32 Cwmax:4;	/*unit power of 2 */
-		u32: 12;	/* */
-	} field;
-	u32 word;
-} EDCA_AC_CFG_STRUC, *PEDCA_AC_CFG_STRUC;
-
-#define EDCA_TID_AC_MAP	0x1310
-#define TX_PWR_CFG_0	0x1314
-#define TX_PWR_CFG_1	0x1318
-#define TX_PWR_CFG_2	0x131C
-#define TX_PWR_CFG_3	0x1320
-#define TX_PWR_CFG_4	0x1324
-#define TX_PIN_CFG		0x1328
-#define TX_BAND_CFG	0x132c	/* 0x1 use upper 20MHz. 0 juse lower 20MHz */
-#define TX_SW_CFG0		0x1330
-#define TX_SW_CFG1		0x1334
-#define TX_SW_CFG2		0x1338
-#define TXOP_THRES_CFG		0x133c
-#define TXOP_CTRL_CFG		0x1340
-#define TX_RTS_CFG		0x1344
-
-typedef union _TX_RTS_CFG_STRUC {
-	struct {
-		u32 AutoRtsRetryLimit:8;
-		u32 RtsThres:16;	/* unit:byte */
-		u32 RtsFbkEn:1;	/* enable rts rate fallback */
-		u32 rsv:7;	/* 1: HT non-STBC control frame enable */
-	} field;
-	u32 word;
-} TX_RTS_CFG_STRUC, *PTX_RTS_CFG_STRUC;
-#define TX_TIMEOUT_CFG	0x1348
-typedef union _TX_TIMEOUT_CFG_STRUC {
-	struct {
-		u32 rsv:4;
-		u32 MpduLifeTime:4;	/*  expiration time = 2^(9+MPDU LIFE TIME)  us */
-		u32 RxAckTimeout:8;	/* unit:slot. Used for TX precedure */
-		u32 TxopTimeout:8;	/*TXOP timeout value for TXOP truncation.  It is recommended that (SLOT_TIME) > (TX_OP_TIMEOUT) > (RX_ACK_TIMEOUT) */
-		u32 rsv2:8;	/* 1: HT non-STBC control frame enable */
-	} field;
-	u32 word;
-} TX_TIMEOUT_CFG_STRUC, *PTX_TIMEOUT_CFG_STRUC;
-#define TX_RTY_CFG	0x134c
-typedef union PACKED _TX_RTY_CFG_STRUC {
-	struct {
-		u32 ShortRtyLimit:8;	/* short retry limit */
-		u32 LongRtyLimit:8;	/* long retry limit */
-		u32 LongRtyThre:12;	/* Long retry threshold */
-		u32 NonAggRtyMode:1;	/* Non-Aggregate MPDU retry mode.  0:expired by retry limit, 1: expired by mpdu life timer */
-		u32 AggRtyMode:1;	/* Aggregate MPDU retry mode.  0:expired by retry limit, 1: expired by mpdu life timer */
-		u32 TxautoFBEnable:1;	/* Tx retry PHY rate auto fallback enable */
-		u32 rsv:1;	/* 1: HT non-STBC control frame enable */
-	} field;
-	u32 word;
-} TX_RTY_CFG_STRUC, *PTX_RTY_CFG_STRUC;
-#define TX_LINK_CFG	0x1350
-typedef union PACKED _TX_LINK_CFG_STRUC {
-	struct PACKED {
-		u32 RemoteMFBLifeTime:8;	/*remote MFB life time. unit : 32us */
-		u32 MFBEnable:1;	/*  TX apply remote MFB 1:enable */
-		u32 RemoteUMFSEnable:1;	/*  remote unsolicit  MFB enable.  0: not apply remote remote unsolicit (MFS=7) */
-		u32 TxMRQEn:1;	/*  MCS request TX enable */
-		u32 TxRDGEn:1;	/* RDG TX enable */
-		u32 TxCFAckEn:1;	/*   Piggyback CF-ACK enable */
-		u32 rsv:3;	/* */
-		u32 RemotMFB:8;	/*  remote MCS feedback */
-		u32 RemotMFS:8;	/*remote MCS feedback sequence number */
-	} field;
-	u32 word;
-} TX_LINK_CFG_STRUC, *PTX_LINK_CFG_STRUC;
-#define HT_FBK_CFG0	0x1354
-typedef union PACKED _HT_FBK_CFG0_STRUC {
-	struct {
-		u32 HTMCS0FBK:4;
-		u32 HTMCS1FBK:4;
-		u32 HTMCS2FBK:4;
-		u32 HTMCS3FBK:4;
-		u32 HTMCS4FBK:4;
-		u32 HTMCS5FBK:4;
-		u32 HTMCS6FBK:4;
-		u32 HTMCS7FBK:4;
-	} field;
-	u32 word;
-} HT_FBK_CFG0_STRUC, *PHT_FBK_CFG0_STRUC;
-#define HT_FBK_CFG1	0x1358
-typedef union _HT_FBK_CFG1_STRUC {
-	struct {
-		u32 HTMCS8FBK:4;
-		u32 HTMCS9FBK:4;
-		u32 HTMCS10FBK:4;
-		u32 HTMCS11FBK:4;
-		u32 HTMCS12FBK:4;
-		u32 HTMCS13FBK:4;
-		u32 HTMCS14FBK:4;
-		u32 HTMCS15FBK:4;
-	} field;
-	u32 word;
-} HT_FBK_CFG1_STRUC, *PHT_FBK_CFG1_STRUC;
-#define LG_FBK_CFG0	0x135c
-typedef union _LG_FBK_CFG0_STRUC {
-	struct {
-		u32 OFDMMCS0FBK:4;	/*initial value is 0 */
-		u32 OFDMMCS1FBK:4;	/*initial value is 0 */
-		u32 OFDMMCS2FBK:4;	/*initial value is 1 */
-		u32 OFDMMCS3FBK:4;	/*initial value is 2 */
-		u32 OFDMMCS4FBK:4;	/*initial value is 3 */
-		u32 OFDMMCS5FBK:4;	/*initial value is 4 */
-		u32 OFDMMCS6FBK:4;	/*initial value is 5 */
-		u32 OFDMMCS7FBK:4;	/*initial value is 6 */
-	} field;
-	u32 word;
-} LG_FBK_CFG0_STRUC, *PLG_FBK_CFG0_STRUC;
-#define LG_FBK_CFG1		0x1360
-typedef union _LG_FBK_CFG1_STRUC {
-	struct {
-		u32 CCKMCS0FBK:4;	/*initial value is 0 */
-		u32 CCKMCS1FBK:4;	/*initial value is 0 */
-		u32 CCKMCS2FBK:4;	/*initial value is 1 */
-		u32 CCKMCS3FBK:4;	/*initial value is 2 */
-		u32 rsv:16;
-	} field;
-	u32 word;
-} LG_FBK_CFG1_STRUC, *PLG_FBK_CFG1_STRUC;
-
-/*======================================================= */
-/*================ Protection Paramater================================ */
-/*======================================================= */
-#define CCK_PROT_CFG	0x1364	/*CCK Protection */
-#define ASIC_SHORTNAV		1
-#define ASIC_longNAV		2
-#define ASIC_RTS		1
-#define ASIC_CTS		2
-typedef union _PROT_CFG_STRUC {
-	struct {
-		u32 ProtectRate:16;	/*Protection control frame rate for CCK TX(RTS/CTS/CFEnd). */
-		u32 ProtectCtrl:2;	/*Protection control frame type for CCK TX. 1:RTS/CTS, 2:CTS-to-self, 0:None, 3:rsv */
-		u32 ProtectNav:2;	/*TXOP protection type for CCK TX. 0:None, 1:ShortNAVprotect,  2:LongNAVProtect, 3:rsv */
-		u32 TxopAllowCck:1;	/*CCK TXOP allowance.0:disallow. */
-		u32 TxopAllowOfdm:1;	/*CCK TXOP allowance.0:disallow. */
-		u32 TxopAllowMM20:1;	/*CCK TXOP allowance. 0:disallow. */
-		u32 TxopAllowMM40:1;	/*CCK TXOP allowance.0:disallow. */
-		u32 TxopAllowGF20:1;	/*CCK TXOP allowance.0:disallow. */
-		u32 TxopAllowGF40:1;	/*CCK TXOP allowance.0:disallow. */
-		u32 RTSThEn:1;	/*RTS threshold enable on CCK TX */
-		u32 rsv:5;
-	} field;
-	u32 word;
-} PROT_CFG_STRUC, *PPROT_CFG_STRUC;
-
-#define OFDM_PROT_CFG	0x1368	/*OFDM Protection */
-#define MM20_PROT_CFG	0x136C	/*MM20 Protection */
-#define MM40_PROT_CFG	0x1370	/*MM40 Protection */
-#define GF20_PROT_CFG	0x1374	/*GF20 Protection */
-#define GF40_PROT_CFG	0x1378	/*GR40 Protection */
-#define EXP_CTS_TIME	0x137C	/* */
-#define EXP_ACK_TIME	0x1380	/* */
-
-/* */
-/*  4.4 MAC RX configuration registers (offset:0x1400) */
-/* */
-#define RX_FILTR_CFG	0x1400	/*TXRX_CSR0 */
-#define AUTO_RSP_CFG	0x1404	/*TXRX_CSR4 */
-/* */
-/* TXRX_CSR4: Auto-Responder/ */
-/* */
-typedef union _AUTO_RSP_CFG_STRUC {
-	struct {
-		u32 AutoResponderEnable:1;
-		u32 BACAckPolicyEnable:1;	/* 0:long, 1:short preamble */
-		u32 CTS40MMode:1;	/* Response CTS 40MHz duplicate mode */
-		u32 CTS40MRef:1;	/* Response CTS 40MHz duplicate mode */
-		u32 AutoResponderPreamble:1;	/* 0:long, 1:short preamble */
-		u32 rsv:1;	/* Power bit value in conrtrol frame */
-		u32 DualCTSEn:1;	/* Power bit value in conrtrol frame */
-		u32 AckCtsPsmBit:1;	/* Power bit value in conrtrol frame */
-		u32: 24;
-	} field;
-	u32 word;
-} AUTO_RSP_CFG_STRUC, *PAUTO_RSP_CFG_STRUC;
-
-#define LEGACY_BASIC_RATE	0x1408	/*  TXRX_CSR5           0x3054 */
-#define HT_BASIC_RATE		0x140c
-#define HT_CTRL_CFG		0x1410
-#define SIFS_COST_CFG		0x1414
-#define RX_PARSER_CFG		0x1418	/*Set NAV for all received frames */
-
-/* */
-/*  4.5 MAC Security configuration (offset:0x1500) */
-/* */
-#define TX_SEC_CNT0		0x1500	/* */
-#define RX_SEC_CNT0		0x1504	/* */
-#define CCMP_FC_MUTE		0x1508	/* */
-/* */
-/*  4.6 HCCA/PSMP (offset:0x1600) */
-/* */
-#define TXOP_HLDR_ADDR0		0x1600
-#define TXOP_HLDR_ADDR1		0x1604
-#define TXOP_HLDR_ET		0x1608
-#define QOS_CFPOLL_RA_DW0		0x160c
-#define QOS_CFPOLL_A1_DW1		0x1610
-#define QOS_CFPOLL_QC		0x1614
-/* */
-/*  4.7 MAC Statistis registers (offset:0x1700) */
-/* */
-#define RX_STA_CNT0		0x1700	/* */
-#define RX_STA_CNT1		0x1704	/* */
-#define RX_STA_CNT2		0x1708	/* */
-
-/* */
-/* RX_STA_CNT0_STRUC: RX PLCP error count & RX CRC error count */
-/* */
-typedef union _RX_STA_CNT0_STRUC {
-	struct {
-		u16 CrcErr;
-		u16 PhyErr;
-	} field;
-	u32 word;
-} RX_STA_CNT0_STRUC, *PRX_STA_CNT0_STRUC;
-
-/* */
-/* RX_STA_CNT1_STRUC: RX False CCA count & RX long frame count */
-/* */
-typedef union _RX_STA_CNT1_STRUC {
-	struct {
-		u16 FalseCca;
-		u16 PlcpErr;
-	} field;
-	u32 word;
-} RX_STA_CNT1_STRUC, *PRX_STA_CNT1_STRUC;
-
-/* */
-/* RX_STA_CNT2_STRUC: */
-/* */
-typedef union _RX_STA_CNT2_STRUC {
-	struct {
-		u16 RxDupliCount;
-		u16 RxFifoOverflowCount;
-	} field;
-	u32 word;
-} RX_STA_CNT2_STRUC, *PRX_STA_CNT2_STRUC;
-#define TX_STA_CNT0		0x170C	/* */
-/* */
-/* STA_CSR3: TX Beacon count */
-/* */
-typedef union _TX_STA_CNT0_STRUC {
-	struct {
-		u16 TxFailCount;
-		u16 TxBeaconCount;
-	} field;
-	u32 word;
-} TX_STA_CNT0_STRUC, *PTX_STA_CNT0_STRUC;
-#define TX_STA_CNT1		0x1710	/* */
-/* */
-/* TX_STA_CNT1: TX tx count */
-/* */
-typedef union _TX_STA_CNT1_STRUC {
-	struct {
-		u16 TxSuccess;
-		u16 TxRetransmit;
-	} field;
-	u32 word;
-} TX_STA_CNT1_STRUC, *PTX_STA_CNT1_STRUC;
-#define TX_STA_CNT2		0x1714	/* */
-/* */
-/* TX_STA_CNT2: TX tx count */
-/* */
-typedef union _TX_STA_CNT2_STRUC {
-	struct {
-		u16 TxZeroLenCount;
-		u16 TxUnderFlowCount;
-	} field;
-	u32 word;
-} TX_STA_CNT2_STRUC, *PTX_STA_CNT2_STRUC;
-#define TX_STA_FIFO		0x1718	/* */
-/* */
-/* TX_STA_FIFO_STRUC: TX Result for specific PID status fifo register */
-/* */
-typedef union PACKED _TX_STA_FIFO_STRUC {
-	struct {
-		u32 bValid:1;	/* 1:This register contains a valid TX result */
-		u32 PidType:4;
-		u32 TxSuccess:1;	/* Tx No retry success */
-		u32 TxAggre:1;	/* Tx Retry Success */
-		u32 TxAckRequired:1;	/* Tx fail */
-		u32 wcid:8;	/*wireless client index */
-/*              u32          SuccessRate:16; //include MCS, mode ,shortGI, BW settingSame format as TXWI Word 0 Bit 31-16. */
-		u32 SuccessRate:13;	/*include MCS, mode ,shortGI, BW settingSame format as TXWI Word 0 Bit 31-16. */
-		u32 TxBF:1;
-		u32 Reserve:2;
-	} field;
-	u32 word;
-} TX_STA_FIFO_STRUC, *PTX_STA_FIFO_STRUC;
-/* Debug counter */
-#define TX_AGG_CNT	0x171c
-typedef union _TX_AGG_CNT_STRUC {
-	struct {
-		u16 NonAggTxCount;
-		u16 AggTxCount;
-	} field;
-	u32 word;
-} TX_AGG_CNT_STRUC, *PTX_AGG_CNT_STRUC;
-/* Debug counter */
-#define TX_AGG_CNT0	0x1720
-typedef union _TX_AGG_CNT0_STRUC {
-	struct {
-		u16 AggSize1Count;
-		u16 AggSize2Count;
-	} field;
-	u32 word;
-} TX_AGG_CNT0_STRUC, *PTX_AGG_CNT0_STRUC;
-/* Debug counter */
-#define TX_AGG_CNT1	0x1724
-typedef union _TX_AGG_CNT1_STRUC {
-	struct {
-		u16 AggSize3Count;
-		u16 AggSize4Count;
-	} field;
-	u32 word;
-} TX_AGG_CNT1_STRUC, *PTX_AGG_CNT1_STRUC;
-#define TX_AGG_CNT2	0x1728
-typedef union _TX_AGG_CNT2_STRUC {
-	struct {
-		u16 AggSize5Count;
-		u16 AggSize6Count;
-	} field;
-	u32 word;
-} TX_AGG_CNT2_STRUC, *PTX_AGG_CNT2_STRUC;
-/* Debug counter */
-#define TX_AGG_CNT3	0x172c
-typedef union _TX_AGG_CNT3_STRUC {
-	struct {
-		u16 AggSize7Count;
-		u16 AggSize8Count;
-	} field;
-	u32 word;
-} TX_AGG_CNT3_STRUC, *PTX_AGG_CNT3_STRUC;
-/* Debug counter */
-#define TX_AGG_CNT4	0x1730
-typedef union _TX_AGG_CNT4_STRUC {
-	struct {
-		u16 AggSize9Count;
-		u16 AggSize10Count;
-	} field;
-	u32 word;
-} TX_AGG_CNT4_STRUC, *PTX_AGG_CNT4_STRUC;
-#define TX_AGG_CNT5	0x1734
-typedef union _TX_AGG_CNT5_STRUC {
-	struct {
-		u16 AggSize11Count;
-		u16 AggSize12Count;
-	} field;
-	u32 word;
-} TX_AGG_CNT5_STRUC, *PTX_AGG_CNT5_STRUC;
-#define TX_AGG_CNT6		0x1738
-typedef union _TX_AGG_CNT6_STRUC {
-	struct {
-		u16 AggSize13Count;
-		u16 AggSize14Count;
-	} field;
-	u32 word;
-} TX_AGG_CNT6_STRUC, *PTX_AGG_CNT6_STRUC;
-#define TX_AGG_CNT7		0x173c
-typedef union _TX_AGG_CNT7_STRUC {
-	struct {
-		u16 AggSize15Count;
-		u16 AggSize16Count;
-	} field;
-	u32 word;
-} TX_AGG_CNT7_STRUC, *PTX_AGG_CNT7_STRUC;
-#define MPDU_DENSITY_CNT		0x1740
-typedef union _MPDU_DEN_CNT_STRUC {
-	struct {
-		u16 TXZeroDelCount;	/*TX zero length delimiter count */
-		u16 RXZeroDelCount;	/*RX zero length delimiter count */
-	} field;
-	u32 word;
-} MPDU_DEN_CNT_STRUC, *PMPDU_DEN_CNT_STRUC;
-/* */
-/* TXRX control registers - base address 0x3000 */
-/* */
-/* rt2860b  UNKNOWN reg use R/O Reg Addr 0x77d0 first.. */
-#define TXRX_CSR1           0x77d0
-
-/* */
-/* Security key table memory, base address = 0x1000 */
-/* */
-#define MAC_WCID_BASE		0x1800	/*8-bytes(use only 6-bytes) * 256 entry = */
-#define HW_WCID_ENTRY_SIZE   8
-#define PAIRWISE_KEY_TABLE_BASE     0x4000	/* 32-byte * 256-entry =  -byte */
-#define HW_KEY_ENTRY_SIZE           0x20
-#define PAIRWISE_IVEIV_TABLE_BASE     0x6000	/* 8-byte * 256-entry =  -byte */
-#define MAC_IVEIV_TABLE_BASE     0x6000	/* 8-byte * 256-entry =  -byte */
-#define HW_IVEIV_ENTRY_SIZE   8
-#define MAC_WCID_ATTRIBUTE_BASE     0x6800	/* 4-byte * 256-entry =  -byte */
-#define HW_WCID_ATTRI_SIZE   4
-#define WCID_RESERVED			0x6bfc
-#define SHARED_KEY_TABLE_BASE       0x6c00	/* 32-byte * 16-entry = 512-byte */
-#define SHARED_KEY_MODE_BASE       0x7000	/* 32-byte * 16-entry = 512-byte */
-#define HW_SHARED_KEY_MODE_SIZE   4
-#define SHAREDKEYTABLE			0
-#define PAIRWISEKEYTABLE			1
-
-typedef union _SHAREDKEY_MODE_STRUC {
-	struct {
-		u32 Bss0Key0CipherAlg:3;
-		u32: 1;
-		u32 Bss0Key1CipherAlg:3;
-		u32: 1;
-		u32 Bss0Key2CipherAlg:3;
-		u32: 1;
-		u32 Bss0Key3CipherAlg:3;
-		u32: 1;
-		u32 Bss1Key0CipherAlg:3;
-		u32: 1;
-		u32 Bss1Key1CipherAlg:3;
-		u32: 1;
-		u32 Bss1Key2CipherAlg:3;
-		u32: 1;
-		u32 Bss1Key3CipherAlg:3;
-		u32: 1;
-	} field;
-	u32 word;
-} SHAREDKEY_MODE_STRUC, *PSHAREDKEY_MODE_STRUC;
-
-/* 8-byte per entry, 64-entry for pairwise key table */
-struct rt_hw_wcid_entry {
-	u8 Address[6];
-	u8 Rsv[2];
-};
-
-/* ================================================================================= */
-/* WCID  format */
-/* ================================================================================= */
-/*7.1   WCID  ENTRY  format  : 8bytes */
-struct rt_wcid_entry {
-	u8 RXBABitmap7;	/* bit0 for TID8, bit7 for TID 15 */
-	u8 RXBABitmap0;	/* bit0 for TID0, bit7 for TID 7 */
-	u8 MAC[6];		/* 0 for shared key table.  1 for pairwise key table */
-};
-
-/*8.1.1 SECURITY  KEY  format  : 8DW */
-/* 32-byte per entry, total 16-entry for shared key table, 64-entry for pairwise key table */
-struct rt_hw_key_entry {
-	u8 Key[16];
-	u8 TxMic[8];
-	u8 RxMic[8];
-};
-
-/*8.1.2 IV/EIV  format  : 2DW */
-
-/*8.1.3 RX attribute entry format  : 1DW */
-struct rt_mac_attribute {
-	u32 KeyTab:1;	/* 0 for shared key table.  1 for pairwise key table */
-	u32 PairKeyMode:3;
-	u32 BSSIDIdx:3;	/*multipleBSS index for the WCID */
-	u32 RXWIUDF:3;
-	u32 rsv:22;
-};
-
-/* ================================================================================= */
-/* HOST-MCU communication data structure */
-/* ================================================================================= */
-
-/* */
-/* H2M_MAILBOX_CSR: Host-to-MCU Mailbox */
-/* */
-typedef union _H2M_MAILBOX_STRUC {
-	struct {
-		u32 LowByte:8;
-		u32 HighByte:8;
-		u32 CmdToken:8;
-		u32 Owner:8;
-	} field;
-	u32 word;
-} H2M_MAILBOX_STRUC, *PH2M_MAILBOX_STRUC;
-
-/* */
-/* M2H_CMD_DONE_CSR: MCU-to-Host command complete indication */
-/* */
-typedef union _M2H_CMD_DONE_STRUC {
-	struct {
-		u32 CmdToken0;
-		u32 CmdToken1;
-		u32 CmdToken2;
-		u32 CmdToken3;
-	} field;
-	u32 word;
-} M2H_CMD_DONE_STRUC, *PM2H_CMD_DONE_STRUC;
-
-/*NAV_TIME_CFG :NAV */
-typedef union _NAV_TIME_CFG_STRUC {
-	struct {
-		u8 Sifs;	/* in unit of 1-us */
-		u8 SlotTime;	/* in unit of 1-us */
-		u16 Eifs:9;	/* in unit of 1-us */
-		u16 ZeroSifs:1;	/* Applied zero SIFS timer after OFDM RX 0: disable */
-		u16 rsv:6;
-	} field;
-	u32 word;
-} NAV_TIME_CFG_STRUC, *PNAV_TIME_CFG_STRUC;
-
-/* */
-/* RX_FILTR_CFG:  /RX configuration register */
-/* */
-typedef union _RX_FILTR_CFG_STRUC {
-	struct {
-		u32 DropCRCErr:1;	/* Drop CRC error */
-		u32 DropPhyErr:1;	/* Drop physical error */
-		u32 DropNotToMe:1;	/* Drop not to me unicast frame */
-		u32 DropNotMyBSSID:1;	/* Drop fram ToDs bit is true */
-
-		u32 DropVerErr:1;	/* Drop version error frame */
-		u32 DropMcast:1;	/* Drop multicast frames */
-		u32 DropBcast:1;	/* Drop broadcast frames */
-		u32 DropDuplicate:1;	/* Drop duplicate frame */
-
-		u32 DropCFEndAck:1;	/* Drop Ps-Poll */
-		u32 DropCFEnd:1;	/* Drop Ps-Poll */
-		u32 DropAck:1;	/* Drop Ps-Poll */
-		u32 DropCts:1;	/* Drop Ps-Poll */
-
-		u32 DropRts:1;	/* Drop Ps-Poll */
-		u32 DropPsPoll:1;	/* Drop Ps-Poll */
-		u32 DropBA:1;	/* */
-		u32 DropBAR:1;	/* */
-
-		u32 DropRsvCntlType:1;
-		u32: 15;
-	} field;
-	u32 word;
-} RX_FILTR_CFG_STRUC, *PRX_FILTR_CFG_STRUC;
-
-/* */
-/* PHY_CSR4: RF serial control register */
-/* */
-typedef union _PHY_CSR4_STRUC {
-	struct {
-		u32 RFRegValue:24;	/* Register     value (include register id)     serial out to RF/IF     chip. */
-		u32 NumberOfBits:5;	/* Number of bits used in RFRegValue (I:20,     RFMD:22) */
-		u32 IFSelect:1;	/* 1: select IF to program,     0: select RF to program */
-		u32 PLL_LD:1;	/* RF PLL_LD status */
-		u32 Busy:1;	/* 1: ASIC is busy execute RF programming. */
-	} field;
-	u32 word;
-} PHY_CSR4_STRUC, *PPHY_CSR4_STRUC;
-
-/* */
-/* SEC_CSR5: shared key table security mode register */
-/* */
-typedef union _SEC_CSR5_STRUC {
-	struct {
-		u32 Bss2Key0CipherAlg:3;
-		u32: 1;
-		u32 Bss2Key1CipherAlg:3;
-		u32: 1;
-		u32 Bss2Key2CipherAlg:3;
-		u32: 1;
-		u32 Bss2Key3CipherAlg:3;
-		u32: 1;
-		u32 Bss3Key0CipherAlg:3;
-		u32: 1;
-		u32 Bss3Key1CipherAlg:3;
-		u32: 1;
-		u32 Bss3Key2CipherAlg:3;
-		u32: 1;
-		u32 Bss3Key3CipherAlg:3;
-		u32: 1;
-	} field;
-	u32 word;
-} SEC_CSR5_STRUC, *PSEC_CSR5_STRUC;
-
-/* */
-/* HOST_CMD_CSR: For HOST to interrupt embedded processor */
-/* */
-typedef union _HOST_CMD_CSR_STRUC {
-	struct {
-		u32 HostCommand:8;
-		u32 Rsv:24;
-	} field;
-	u32 word;
-} HOST_CMD_CSR_STRUC, *PHOST_CMD_CSR_STRUC;
-
-/* */
-/* AIFSN_CSR: AIFSN for each EDCA AC */
-/* */
-
-/* */
-/* E2PROM_CSR: EEPROM control register */
-/* */
-typedef union _E2PROM_CSR_STRUC {
-	struct {
-		u32 Reload:1;	/* Reload EEPROM content, write one to reload, self-cleared. */
-		u32 EepromSK:1;
-		u32 EepromCS:1;
-		u32 EepromDI:1;
-		u32 EepromDO:1;
-		u32 Type:1;	/* 1: 93C46, 0:93C66 */
-		u32 LoadStatus:1;	/* 1:loading, 0:done */
-		u32 Rsvd:25;
-	} field;
-	u32 word;
-} E2PROM_CSR_STRUC, *PE2PROM_CSR_STRUC;
-
-/* */
-/* QOS_CSR0: TXOP holder address0 register */
-/* */
-typedef union _QOS_CSR0_STRUC {
-	struct {
-		u8 Byte0;	/* MAC address byte 0 */
-		u8 Byte1;	/* MAC address byte 1 */
-		u8 Byte2;	/* MAC address byte 2 */
-		u8 Byte3;	/* MAC address byte 3 */
-	} field;
-	u32 word;
-} QOS_CSR0_STRUC, *PQOS_CSR0_STRUC;
-
-/* */
-/* QOS_CSR1: TXOP holder address1 register */
-/* */
-typedef union _QOS_CSR1_STRUC {
-	struct {
-		u8 Byte4;	/* MAC address byte 4 */
-		u8 Byte5;	/* MAC address byte 5 */
-		u8 Rsvd0;
-		u8 Rsvd1;
-	} field;
-	u32 word;
-} QOS_CSR1_STRUC, *PQOS_CSR1_STRUC;
-
-#define	RF_CSR_CFG	0x500
-typedef union _RF_CSR_CFG_STRUC {
-	struct {
-		u32 RF_CSR_DATA:8;	/* DATA */
-		u32 TESTCSR_RFACC_REGNUM:5;	/* RF register ID */
-		u32 Rsvd2:3;	/* Reserved */
-		u32 RF_CSR_WR:1;	/* 0: read  1: write */
-		u32 RF_CSR_KICK:1;	/* kick RF register read/write */
-		u32 Rsvd1:14;	/* Reserved */
-	} field;
-	u32 word;
-} RF_CSR_CFG_STRUC, *PRF_CSR_CFG_STRUC;
-
-/* */
-/* Other on-chip shared memory space, base = 0x2000 */
-/* */
-
-/* CIS space - base address = 0x2000 */
-#define HW_CIS_BASE             0x2000
-
-/* Carrier-sense CTS frame base address. It's where mac stores carrier-sense frame for carrier-sense function. */
-#define HW_CS_CTS_BASE			0x7700
-/* DFS CTS frame base address. It's where mac stores CTS frame for DFS. */
-#define HW_DFS_CTS_BASE			0x7780
-#define HW_CTS_FRAME_SIZE		0x80
-
-/* 2004-11-08 john - since NULL frame won't be that long (256 byte). We steal 16 tail bytes */
-/* to save debugging settings */
-#define HW_DEBUG_SETTING_BASE   0x77f0	/* 0x77f0~0x77ff total 16 bytes */
-#define HW_DEBUG_SETTING_BASE2   0x7770	/* 0x77f0~0x77ff total 16 bytes */
-
-/* In order to support maximum 8 MBSS and its maximum length is 512 for each beacon */
-/* Three section discontinue memory segments will be used. */
-/* 1. The original region for BCN 0~3 */
-/* 2. Extract memory from FCE table for BCN 4~5 */
-/* 3. Extract memory from Pair-wise key table for BCN 6~7 */
-/*        It occupied those memory of wcid 238~253 for BCN 6 */
-/*                                                    and wcid 222~237 for BCN 7 */
-#define HW_BEACON_MAX_SIZE      0x1000	/* unit: byte */
-#define HW_BEACON_BASE0         0x7800
-#define HW_BEACON_BASE1         0x7A00
-#define HW_BEACON_BASE2         0x7C00
-#define HW_BEACON_BASE3         0x7E00
-#define HW_BEACON_BASE4         0x7200
-#define HW_BEACON_BASE5         0x7400
-#define HW_BEACON_BASE6         0x5DC0
-#define HW_BEACON_BASE7         0x5BC0
-
-#define HW_BEACON_MAX_COUNT     8
-#define HW_BEACON_OFFSET		0x0200
-#define HW_BEACON_CONTENT_LEN	(HW_BEACON_OFFSET - TXWI_SIZE)
-
-/* HOST-MCU shared memory - base address = 0x2100 */
-#define HOST_CMD_CSR		0x404
-#define H2M_MAILBOX_CSR         0x7010
-#define H2M_MAILBOX_CID         0x7014
-#define H2M_MAILBOX_STATUS      0x701c
-#define H2M_INT_SRC             0x7024
-#define H2M_BBP_AGENT           0x7028
-#define M2H_CMD_DONE_CSR        0x000c
-#define MCU_TXOP_ARRAY_BASE     0x000c	/* TODO: to be provided by Albert */
-#define MCU_TXOP_ENTRY_SIZE     32	/* TODO: to be provided by Albert */
-#define MAX_NUM_OF_TXOP_ENTRY   16	/* TODO: must be same with 8051 firmware */
-#define MCU_MBOX_VERSION        0x01	/* TODO: to be confirmed by Albert */
-#define MCU_MBOX_VERSION_OFFSET 5	/* TODO: to be provided by Albert */
-
-/* */
-/* Host DMA registers - base address 0x200 .  TX0-3=EDCAQid0-3, TX4=HCCA, TX5=MGMT, */
-/* */
-/* */
-/*  DMA RING DESCRIPTOR */
-/* */
-#define E2PROM_CSR          0x0004
-#define IO_CNTL_CSR         0x77d0
-
-/* ================================================================ */
-/* Tx / Rx / Mgmt ring descriptor definition */
-/* ================================================================ */
-
-/* the following PID values are used to mark outgoing frame type in TXD->PID so that */
-/* proper TX statistics can be collected based on these categories */
-/* b3-2 of PID field - */
-#define PID_MGMT			0x05
-#define PID_BEACON			0x0c
-#define PID_DATA_NORMALUCAST		0x02
-#define PID_DATA_AMPDU		0x04
-#define PID_DATA_NO_ACK		0x08
-#define PID_DATA_NOT_NORM_ACK		0x03
-/* value domain of pTxD->HostQId (4-bit: 0~15) */
-#define QID_AC_BK               1	/* meet ACI definition in 802.11e */
-#define QID_AC_BE               0	/* meet ACI definition in 802.11e */
-#define QID_AC_VI               2
-#define QID_AC_VO               3
-#define QID_HCCA                4
-#define NUM_OF_TX_RING          4
-#define QID_MGMT                13
-#define QID_RX                  14
-#define QID_OTHER               15
-
-#endif /* __RTMP_MAC_H__ // */
diff -druN linux-2.6.39-libre/drivers/staging/rt2860/chip/rtmp_phy.h linux-3.0-rc7-libre/drivers/staging/rt2860/chip/rtmp_phy.h
--- linux-2.6.39-libre/drivers/staging/rt2860/chip/rtmp_phy.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rt2860/chip/rtmp_phy.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,516 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, 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.             *
- *                                                                       *
- *************************************************************************
-
-	Module Name:
-	rtmp_phy.h
-
-	Abstract:
-	Ralink Wireless Chip PHY(BBP/RF) related definition & structures
-
-	Revision History:
-	Who			When		  What
-	--------	----------	  ----------------------------------------------
-*/
-
-#ifndef __RTMP_PHY_H__
-#define __RTMP_PHY_H__
-
-/*
-	RF sections
-*/
-#define RF_R00			0
-#define RF_R01			1
-#define RF_R02			2
-#define RF_R03			3
-#define RF_R04			4
-#define RF_R05			5
-#define RF_R06			6
-#define RF_R07			7
-#define RF_R08			8
-#define RF_R09			9
-#define RF_R10			10
-#define RF_R11			11
-#define RF_R12			12
-#define RF_R13			13
-#define RF_R14			14
-#define RF_R15			15
-#define RF_R16			16
-#define RF_R17			17
-#define RF_R18			18
-#define RF_R19			19
-#define RF_R20			20
-#define RF_R21			21
-#define RF_R22			22
-#define RF_R23			23
-#define RF_R24			24
-#define RF_R25			25
-#define RF_R26			26
-#define RF_R27			27
-#define RF_R28			28
-#define RF_R29			29
-#define RF_R30			30
-#define RF_R31			31
-
-/* value domain of pAd->RfIcType */
-#define RFIC_2820                   1	/* 2.4G 2T3R */
-#define RFIC_2850                   2	/* 2.4G/5G 2T3R */
-#define RFIC_2720                   3	/* 2.4G 1T2R */
-#define RFIC_2750                   4	/* 2.4G/5G 1T2R */
-#define RFIC_3020                   5	/* 2.4G 1T1R */
-#define RFIC_2020                   6	/* 2.4G B/G */
-#define RFIC_3021                   7	/* 2.4G 1T2R */
-#define RFIC_3022                   8	/* 2.4G 2T2R */
-#define RFIC_3052                   9	/* 2.4G/5G 2T2R */
-
-/*
-	BBP sections
-*/
-#define BBP_R0			0	/* version */
-#define BBP_R1			1	/* TSSI */
-#define BBP_R2			2	/* TX configure */
-#define BBP_R3			3
-#define BBP_R4			4
-#define BBP_R5			5
-#define BBP_R6			6
-#define BBP_R14			14	/* RX configure */
-#define BBP_R16			16
-#define BBP_R17			17	/* RX sensibility */
-#define BBP_R18			18
-#define BBP_R21			21
-#define BBP_R22			22
-#define BBP_R24			24
-#define BBP_R25			25
-#define BBP_R26			26
-#define BBP_R27			27
-#define BBP_R31			31
-#define BBP_R49			49	/*TSSI */
-#define BBP_R50			50
-#define BBP_R51			51
-#define BBP_R52			52
-#define BBP_R55			55
-#define BBP_R62			62	/* Rx SQ0 Threshold HIGH */
-#define BBP_R63			63
-#define BBP_R64			64
-#define BBP_R65			65
-#define BBP_R66			66
-#define BBP_R67			67
-#define BBP_R68			68
-#define BBP_R69			69
-#define BBP_R70			70	/* Rx AGC SQ CCK Xcorr threshold */
-#define BBP_R73			73
-#define BBP_R75			75
-#define BBP_R77			77
-#define BBP_R78			78
-#define BBP_R79			79
-#define BBP_R80			80
-#define BBP_R81			81
-#define BBP_R82			82
-#define BBP_R83			83
-#define BBP_R84			84
-#define BBP_R86			86
-#define BBP_R91			91
-#define BBP_R92			92
-#define BBP_R94			94	/* Tx Gain Control */
-#define BBP_R103		103
-#define BBP_R105		105
-#define BBP_R106		106
-#define BBP_R113		113
-#define BBP_R114		114
-#define BBP_R115		115
-#define BBP_R116		116
-#define BBP_R117		117
-#define BBP_R118		118
-#define BBP_R119		119
-#define BBP_R120		120
-#define BBP_R121		121
-#define BBP_R122		122
-#define BBP_R123		123
-#ifdef RT30xx
-#define BBP_R138		138	/* add by johnli, RF power sequence setup, ADC dynamic on/off control */
-#endif /* RT30xx // */
-
-#define BBPR94_DEFAULT	0x06	/* Add 1 value will gain 1db */
-
-/* */
-/* BBP & RF are using indirect access. Before write any value into it. */
-/* We have to make sure there is no outstanding command pending via checking busy bit. */
-/* */
-#define MAX_BUSY_COUNT  100	/* Number of retry before failing access BBP & RF indirect register */
-
-/*#define PHY_TR_SWITCH_TIME          5  // usec */
-
-/*#define BBP_R17_LOW_SENSIBILITY     0x50 */
-/*#define BBP_R17_MID_SENSIBILITY     0x41 */
-/*#define BBP_R17_DYNAMIC_UP_BOUND    0x40 */
-
-#define RSSI_FOR_VERY_LOW_SENSIBILITY   -35
-#define RSSI_FOR_LOW_SENSIBILITY		-58
-#define RSSI_FOR_MID_LOW_SENSIBILITY	-80
-#define RSSI_FOR_MID_SENSIBILITY		-90
-
-/*****************************************************************************
-	RF register Read/Write marco definition
- *****************************************************************************/
-#ifdef RTMP_MAC_PCI
-#define RTMP_RF_IO_WRITE32(_A, _V)                  \
-{											\
-	if ((_A)->bPCIclkOff == FALSE) {				\
-		PHY_CSR4_STRUC  _value;                          \
-		unsigned long           _busyCnt = 0;                    \
-											\
-		do {                                            \
-			RTMP_IO_READ32((_A), RF_CSR_CFG0, &_value.word);  \
-			if (_value.field.Busy == IDLE)               \
-				break;                                  \
-			_busyCnt++;                                  \
-		} while (_busyCnt < MAX_BUSY_COUNT);			\
-		if (_busyCnt < MAX_BUSY_COUNT) {			\
-			RTMP_IO_WRITE32((_A), RF_CSR_CFG0, (_V));          \
-		}                                               \
-	}								\
-}
-#endif /* RTMP_MAC_PCI // */
-#ifdef RTMP_MAC_USB
-#define RTMP_RF_IO_WRITE32(_A, _V)                 RTUSBWriteRFRegister(_A, _V)
-#endif /* RTMP_MAC_USB // */
-
-#ifdef RT30xx
-#define RTMP_RF_IO_READ8_BY_REG_ID(_A, _I, _pV)    RT30xxReadRFRegister(_A, _I, _pV)
-#define RTMP_RF_IO_WRITE8_BY_REG_ID(_A, _I, _V)    RT30xxWriteRFRegister(_A, _I, _V)
-#endif /* RT30xx // */
-
-/*****************************************************************************
-	BBP register Read/Write marco definitions.
-	we read/write the bbp value by register's ID.
-	Generate PER to test BA
- *****************************************************************************/
-#ifdef RTMP_MAC_PCI
-/*
-	basic marco for BBP read operation.
-	_pAd: the data structure pointer of struct rt_rtmp_adapter
-	_bbpID : the bbp register ID
-	_pV: data pointer used to save the value of queried bbp register.
-	_bViaMCU: if we need access the bbp via the MCU.
-*/
-#define RTMP_BBP_IO_READ8(_pAd, _bbpID, _pV, _bViaMCU)			\
-	do {								\
-		BBP_CSR_CFG_STRUC  BbpCsr;				\
-		int   _busyCnt, _secCnt, _regID;			\
-									\
-		_regID = ((_bViaMCU) == TRUE ? H2M_BBP_AGENT : BBP_CSR_CFG); \
-		for (_busyCnt = 0; _busyCnt < MAX_BUSY_COUNT; _busyCnt++) { \
-			RTMP_IO_READ32(_pAd, _regID, &BbpCsr.word);	\
-			if (BbpCsr.field.Busy == BUSY)                  \
-				continue;                               \
-			BbpCsr.word = 0;                                \
-			BbpCsr.field.fRead = 1;                         \
-			BbpCsr.field.BBP_RW_MODE = 1;                   \
-			BbpCsr.field.Busy = 1;                          \
-			BbpCsr.field.RegNum = _bbpID;                   \
-			RTMP_IO_WRITE32(_pAd, _regID, BbpCsr.word);     \
-			if ((_bViaMCU) == TRUE) {			\
-			    AsicSendCommandToMcu(_pAd, 0x80, 0xff, 0x0, 0x0); \
-			    RTMPusecDelay(1000);	\
-			}						\
-			for (_secCnt = 0; _secCnt < MAX_BUSY_COUNT; _secCnt++) { \
-				RTMP_IO_READ32(_pAd, _regID, &BbpCsr.word); \
-				if (BbpCsr.field.Busy == IDLE)		\
-					break;				\
-			}						\
-			if ((BbpCsr.field.Busy == IDLE) &&		\
-				(BbpCsr.field.RegNum == _bbpID)) {	\
-				*(_pV) = (u8)BbpCsr.field.Value;	\
-				break;					\
-			}						\
-		}							\
-		if (BbpCsr.field.Busy == BUSY) {			\
-			DBGPRINT_ERR("BBP(viaMCU=%d) read R%d fail\n", (_bViaMCU), _bbpID);	\
-			*(_pV) = (_pAd)->BbpWriteLatch[_bbpID];               \
-			if ((_bViaMCU) == TRUE) {			\
-				RTMP_IO_READ32(_pAd, _regID, &BbpCsr.word);				\
-				BbpCsr.field.Busy = 0;                          \
-				RTMP_IO_WRITE32(_pAd, _regID, BbpCsr.word);				\
-			}				\
-		}													\
-	} while (0)
-
-/*
-	This marco used for the BBP read operation which didn't need via MCU.
-*/
-#define BBP_IO_READ8_BY_REG_ID(_A, _I, _pV)			\
-	RTMP_BBP_IO_READ8((_A), (_I), (_pV), FALSE)
-
-/*
-	This marco used for the BBP read operation which need via MCU.
-	But for some chipset which didn't have mcu (e.g., RBUS based chipset), we
-	will use this function too and didn't access the bbp register via the MCU.
-*/
-/* Read BBP register by register's ID. Generate PER to test BA */
-#define RTMP_BBP_IO_READ8_BY_REG_ID(_A, _I, _pV)						\
-{																		\
-	BBP_CSR_CFG_STRUC	BbpCsr;											\
-	int					i, k;			\
-	BOOLEAN					brc;			\
-	BbpCsr.field.Busy = IDLE;			\
-	if ((IS_RT3090((_A)) || IS_RT3572((_A)) || IS_RT3390((_A)))  \
-		&& ((_A)->StaCfg.PSControl.field.rt30xxPowerMode == 3)	\
-		&& ((_A)->StaCfg.PSControl.field.EnableNewPS == TRUE)	\
-		&& ((_A)->bPCIclkOff == FALSE)	\
-		&& ((_A)->brt30xxBanMcuCmd == FALSE)) {			\
-		for (i = 0; i < MAX_BUSY_COUNT; i++) {			\
-			RTMP_IO_READ32(_A, H2M_BBP_AGENT, &BbpCsr.word); \
-			if (BbpCsr.field.Busy == BUSY) {		\
-				continue;				\
-			}						\
-			BbpCsr.word = 0;				\
-			BbpCsr.field.fRead = 1;				\
-			BbpCsr.field.BBP_RW_MODE = 1;			\
-			BbpCsr.field.Busy = 1;				\
-			BbpCsr.field.RegNum = _I;			\
-			RTMP_IO_WRITE32(_A, H2M_BBP_AGENT, BbpCsr.word); \
-			brc = AsicSendCommandToMcu(_A, 0x80, 0xff, 0x0, 0x0); \
-			if (brc == TRUE) {				\
-				for (k = 0; k < MAX_BUSY_COUNT; k++) {	\
-					RTMP_IO_READ32(_A, H2M_BBP_AGENT, &BbpCsr.word); \
-					if (BbpCsr.field.Busy == IDLE)	\
-						break;			\
-				}					\
-				if ((BbpCsr.field.Busy == IDLE) &&	\
-					(BbpCsr.field.RegNum == _I)) {	\
-					*(_pV) = (u8)BbpCsr.field.Value; \
-					break;				\
-				}					\
-			} else {					\
-				BbpCsr.field.Busy = 0;											\
-				RTMP_IO_WRITE32(_A, H2M_BBP_AGENT, BbpCsr.word);				\
-			}																\
-		}																	\
-	}	\
-	else if (!((IS_RT3090((_A)) || IS_RT3572((_A)) || IS_RT3390((_A))) && ((_A)->StaCfg.PSControl.field.rt30xxPowerMode == 3)	\
-		&& ((_A)->StaCfg.PSControl.field.EnableNewPS == TRUE))	\
-		&& ((_A)->bPCIclkOff == FALSE)) {			\
-		for (i = 0; i < MAX_BUSY_COUNT; i++) {			\
-			RTMP_IO_READ32(_A, H2M_BBP_AGENT, &BbpCsr.word); \
-			if (BbpCsr.field.Busy == BUSY) {		\
-				continue;				\
-			}						\
-			BbpCsr.word = 0;				\
-			BbpCsr.field.fRead = 1;				\
-			BbpCsr.field.BBP_RW_MODE = 1;			\
-			BbpCsr.field.Busy = 1;				\
-			BbpCsr.field.RegNum = _I;			\
-			RTMP_IO_WRITE32(_A, H2M_BBP_AGENT, BbpCsr.word); \
-			AsicSendCommandToMcu(_A, 0x80, 0xff, 0x0, 0x0);	\
-			for (k = 0; k < MAX_BUSY_COUNT; k++) {		\
-				RTMP_IO_READ32(_A, H2M_BBP_AGENT, &BbpCsr.word); \
-				if (BbpCsr.field.Busy == IDLE)		\
-					break;				\
-			}						\
-			if ((BbpCsr.field.Busy == IDLE) &&		\
-				(BbpCsr.field.RegNum == _I)) {		\
-				*(_pV) = (u8)BbpCsr.field.Value;	\
-				break;					\
-			}						\
-		}							\
-	} else {							\
-		DBGPRINT_ERR(" , brt30xxBanMcuCmd = %d, Read BBP %d \n", (_A)->brt30xxBanMcuCmd, (_I));	\
-		*(_pV) = (_A)->BbpWriteLatch[_I];			\
-	}								\
-	if ((BbpCsr.field.Busy == BUSY) || ((_A)->bPCIclkOff == TRUE)) { \
-		DBGPRINT_ERR("BBP read R%d=0x%x fail\n", _I, BbpCsr.word); \
-		*(_pV) = (_A)->BbpWriteLatch[_I];			\
-	}								\
-}
-
-/*
-	basic marco for BBP write operation.
-	_pAd: the data structure pointer of struct rt_rtmp_adapter
-	_bbpID : the bbp register ID
-	_pV: data used to save the value of queried bbp register.
-	_bViaMCU: if we need access the bbp via the MCU.
-*/
-#define RTMP_BBP_IO_WRITE8(_pAd, _bbpID, _pV, _bViaMCU)			\
-	do {								\
-		BBP_CSR_CFG_STRUC  BbpCsr;                             \
-		int             _busyCnt, _regID;			\
-									\
-		_regID = ((_bViaMCU) == TRUE ? H2M_BBP_AGENT : BBP_CSR_CFG);	\
-		for (_busyCnt = 0; _busyCnt < MAX_BUSY_COUNT; _busyCnt++) { \
-			RTMP_IO_READ32((_pAd), BBP_CSR_CFG, &BbpCsr.word);     \
-			if (BbpCsr.field.Busy == BUSY)			\
-				continue;				\
-			BbpCsr.word = 0;				\
-			BbpCsr.field.fRead = 0;				\
-			BbpCsr.field.BBP_RW_MODE = 1;			\
-			BbpCsr.field.Busy = 1;				\
-			BbpCsr.field.Value = _pV;			\
-			BbpCsr.field.RegNum = _bbpID;			\
-			RTMP_IO_WRITE32((_pAd), BBP_CSR_CFG, BbpCsr.word); \
-			if ((_bViaMCU) == TRUE) {			\
-				AsicSendCommandToMcu(_pAd, 0x80, 0xff, 0x0, 0x0); \
-				if ((_pAd)->OpMode == OPMODE_AP)	\
-					RTMPusecDelay(1000);		\
-			}						\
-			(_pAd)->BbpWriteLatch[_bbpID] = _pV;		\
-			break;						\
-		}							\
-		if (_busyCnt == MAX_BUSY_COUNT) {			\
-			DBGPRINT_ERR("BBP write R%d fail\n", _bbpID);	\
-			if ((_bViaMCU) == TRUE) {			\
-				RTMP_IO_READ32(_pAd, H2M_BBP_AGENT, &BbpCsr.word);	\
-				BbpCsr.field.Busy = 0;			\
-				RTMP_IO_WRITE32(_pAd, H2M_BBP_AGENT, BbpCsr.word);	\
-			}						\
-		}							\
-	} while (0)
-
-/*
-	This marco used for the BBP write operation which didn't need via MCU.
-*/
-#define BBP_IO_WRITE8_BY_REG_ID(_A, _I, _pV)			\
-	RTMP_BBP_IO_WRITE8((_A), (_I), (_pV), FALSE)
-
-/*
-	This marco used for the BBP write operation which need via MCU.
-	But for some chipset which didn't have mcu (e.g., RBUS based chipset), we
-	will use this function too and didn't access the bbp register via the MCU.
-*/
-/* Write BBP register by register's ID & value */
-#define RTMP_BBP_IO_WRITE8_BY_REG_ID(_A, _I, _V)			\
-{									\
-	BBP_CSR_CFG_STRUC	BbpCsr;					\
-	int					BusyCnt = 0;		\
-	BOOLEAN					brc;			\
-	if (_I < MAX_NUM_OF_BBP_LATCH) {				\
-		if ((IS_RT3090((_A)) || IS_RT3572((_A)) || IS_RT3390((_A))) \
-			&& ((_A)->StaCfg.PSControl.field.rt30xxPowerMode == 3)	\
-			&& ((_A)->StaCfg.PSControl.field.EnableNewPS == TRUE)	\
-			&& ((_A)->bPCIclkOff == FALSE)	\
-			&& ((_A)->brt30xxBanMcuCmd == FALSE)) {		\
-			if (_A->AccessBBPFailCount > 20) {		\
-				AsicResetBBPAgent(_A);			\
-				_A->AccessBBPFailCount = 0;		\
-			}						\
-			for (BusyCnt = 0; BusyCnt < MAX_BUSY_COUNT; BusyCnt++) { \
-				RTMP_IO_READ32(_A, H2M_BBP_AGENT, &BbpCsr.word);				\
-				if (BbpCsr.field.Busy == BUSY)									\
-					continue;													\
-				BbpCsr.word = 0;												\
-				BbpCsr.field.fRead = 0;											\
-				BbpCsr.field.BBP_RW_MODE = 1;									\
-				BbpCsr.field.Busy = 1;											\
-				BbpCsr.field.Value = _V;										\
-				BbpCsr.field.RegNum = _I;										\
-				RTMP_IO_WRITE32(_A, H2M_BBP_AGENT, BbpCsr.word);				\
-				brc = AsicSendCommandToMcu(_A, 0x80, 0xff, 0x0, 0x0);					\
-				if (brc == TRUE) {			\
-					(_A)->BbpWriteLatch[_I] = _V;									\
-				} else {				\
-					BbpCsr.field.Busy = 0;											\
-					RTMP_IO_WRITE32(_A, H2M_BBP_AGENT, BbpCsr.word);				\
-				}																\
-				break;															\
-			}																	\
-		}																	\
-		else if (!((IS_RT3090((_A)) || IS_RT3572((_A)) || IS_RT3390((_A))) \
-			&& ((_A)->StaCfg.PSControl.field.rt30xxPowerMode == 3)	\
-			&& ((_A)->StaCfg.PSControl.field.EnableNewPS == TRUE))	\
-			&& ((_A)->bPCIclkOff == FALSE)) { 		\
-			if (_A->AccessBBPFailCount > 20) {		\
-				AsicResetBBPAgent(_A);			\
-				_A->AccessBBPFailCount = 0;		\
-			}						\
-			for (BusyCnt = 0; BusyCnt < MAX_BUSY_COUNT; BusyCnt++) { \
-				RTMP_IO_READ32(_A, H2M_BBP_AGENT, &BbpCsr.word);				\
-				if (BbpCsr.field.Busy == BUSY)									\
-					continue;													\
-				BbpCsr.word = 0;												\
-				BbpCsr.field.fRead = 0;											\
-				BbpCsr.field.BBP_RW_MODE = 1;									\
-				BbpCsr.field.Busy = 1;											\
-				BbpCsr.field.Value = _V;										\
-				BbpCsr.field.RegNum = _I;										\
-				RTMP_IO_WRITE32(_A, H2M_BBP_AGENT, BbpCsr.word);				\
-				AsicSendCommandToMcu(_A, 0x80, 0xff, 0x0, 0x0);					\
-				(_A)->BbpWriteLatch[_I] = _V;									\
-				break;															\
-			}																	\
-		} else {						\
-			DBGPRINT_ERR("  brt30xxBanMcuCmd = %d. Write BBP %d \n",  (_A)->brt30xxBanMcuCmd, (_I));	\
-		}																	\
-		if ((BusyCnt == MAX_BUSY_COUNT) || ((_A)->bPCIclkOff == TRUE)) { \
-			if (BusyCnt == MAX_BUSY_COUNT)				\
-				(_A)->AccessBBPFailCount++;					\
-			DBGPRINT_ERR("BBP write R%d=0x%x fail. BusyCnt= %d.bPCIclkOff = %d. \n", _I, BbpCsr.word, BusyCnt, (_A)->bPCIclkOff);	\
-		}																	\
-	} else {							\
-		DBGPRINT_ERR("****** BBP_Write_Latch Buffer exceeds max boundary ****** \n");	\
-	}																		\
-}
-#endif /* RTMP_MAC_PCI // */
-
-#ifdef RTMP_MAC_USB
-#define RTMP_BBP_IO_READ8_BY_REG_ID(_A, _I, _pV)   RTUSBReadBBPRegister(_A, _I, _pV)
-#define RTMP_BBP_IO_WRITE8_BY_REG_ID(_A, _I, _V)   RTUSBWriteBBPRegister(_A, _I, _V)
-
-#define BBP_IO_WRITE8_BY_REG_ID(_A, _I, _V)			RTUSBWriteBBPRegister(_A, _I, _V)
-#define BBP_IO_READ8_BY_REG_ID(_A, _I, _pV)		RTUSBReadBBPRegister(_A, _I, _pV)
-#endif /* RTMP_MAC_USB // */
-
-#ifdef RT30xx
-#define RTMP_ASIC_MMPS_DISABLE(_pAd)							\
-	do {															\
-		u32 _macData; \
-		u8 _bbpData = 0; \
-		/* disable MMPS BBP control register */						\
-		RTMP_BBP_IO_READ8_BY_REG_ID(_pAd, BBP_R3, &_bbpData);	\
-		_bbpData &= ~(0x04);	/*bit 2*/								\
-		RTMP_BBP_IO_WRITE8_BY_REG_ID(_pAd, BBP_R3, _bbpData);	\
-																\
-		/* disable MMPS MAC control register */						\
-		RTMP_IO_READ32(_pAd, 0x1210, &_macData);				\
-		_macData &= ~(0x09);	/*bit 0, 3*/							\
-		RTMP_IO_WRITE32(_pAd, 0x1210, _macData);				\
-	} while (0)
-
-#define RTMP_ASIC_MMPS_ENABLE(_pAd)							\
-	do {															\
-		u32 _macData; \
-		u8 _bbpData = 0; \
-		/* enable MMPS BBP control register */						\
-		RTMP_BBP_IO_READ8_BY_REG_ID(_pAd, BBP_R3, &_bbpData);	\
-		_bbpData |= (0x04);	/*bit 2*/								\
-		RTMP_BBP_IO_WRITE8_BY_REG_ID(_pAd, BBP_R3, _bbpData);	\
-																\
-		/* enable MMPS MAC control register */						\
-		RTMP_IO_READ32(_pAd, 0x1210, &_macData);				\
-		_macData |= (0x09);	/*bit 0, 3*/							\
-		RTMP_IO_WRITE32(_pAd, 0x1210, _macData);				\
-	} while (0)
-
-#endif /* RT30xx // */
-
-#endif /* __RTMP_PHY_H__ // */
diff -druN linux-2.6.39-libre/drivers/staging/rt2860/chips/rt3070.c linux-3.0-rc7-libre/drivers/staging/rt2860/chips/rt3070.c
--- linux-2.6.39-libre/drivers/staging/rt2860/chips/rt3070.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rt2860/chips/rt3070.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,169 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, 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.             *
- *                                                                       *
- *************************************************************************
-
-	Module Name:
-	rt3070.c
-
-	Abstract:
-	Specific funcitons and variables for RT3070
-
-	Revision History:
-	Who         When          What
-	--------    ----------    ----------------------------------------------
-*/
-
-#ifdef RT3070
-
-#include "../rt_config.h"
-
-#ifndef RTMP_RF_RW_SUPPORT
-#error "You Should Enable compile flag RTMP_RF_RW_SUPPORT for this chip"
-#endif /* RTMP_RF_RW_SUPPORT // */
-
-void NICInitRT3070RFRegisters(struct rt_rtmp_adapter *pAd)
-{
-	int i;
-	u8 RFValue;
-
-	/* Driver must read EEPROM to get RfIcType before initial RF registers */
-	/* Initialize RF register to default value */
-	if (IS_RT3070(pAd) || IS_RT3071(pAd)) {
-		/* Init RF calibration */
-		/* Driver should toggle RF R30 bit7 before init RF registers */
-		u32 RfReg = 0;
-		u32 data;
-
-		RT30xxReadRFRegister(pAd, RF_R30, (u8 *)&RfReg);
-		RfReg |= 0x80;
-		RT30xxWriteRFRegister(pAd, RF_R30, (u8)RfReg);
-		RTMPusecDelay(1000);
-		RfReg &= 0x7F;
-		RT30xxWriteRFRegister(pAd, RF_R30, (u8)RfReg);
-
-		/* Initialize RF register to default value */
-		for (i = 0; i < NUM_RF_REG_PARMS; i++) {
-			RT30xxWriteRFRegister(pAd,
-					      RT30xx_RFRegTable[i].Register,
-					      RT30xx_RFRegTable[i].Value);
-		}
-
-		/* add by johnli */
-		if (IS_RT3070(pAd)) {
-			/* */
-			/* The DAC issue(LDO_CFG0) has been fixed in RT3070(F). */
-			/* The voltage raising patch is no longer needed for RT3070(F) */
-			/* */
-			if ((pAd->MACVersion & 0xffff) < 0x0201) {
-				/*  Update MAC 0x05D4 from 01xxxxxx to 0Dxxxxxx (voltage 1.2V to 1.35V) for RT3070 to improve yield rate */
-				RTUSBReadMACRegister(pAd, LDO_CFG0, &data);
-				data = ((data & 0xF0FFFFFF) | 0x0D000000);
-				RTUSBWriteMACRegister(pAd, LDO_CFG0, data);
-			}
-		} else if (IS_RT3071(pAd)) {
-			/* Driver should set RF R6 bit6 on before init RF registers */
-			RT30xxReadRFRegister(pAd, RF_R06, (u8 *)&RfReg);
-			RfReg |= 0x40;
-			RT30xxWriteRFRegister(pAd, RF_R06, (u8)RfReg);
-
-			/* init R31 */
-			RT30xxWriteRFRegister(pAd, RF_R31, 0x14);
-
-			/* RT3071 version E has fixed this issue */
-			if ((pAd->NicConfig2.field.DACTestBit == 1)
-			    && ((pAd->MACVersion & 0xffff) < 0x0211)) {
-				/* patch tx EVM issue temporarily */
-				RTUSBReadMACRegister(pAd, LDO_CFG0, &data);
-				data = ((data & 0xE0FFFFFF) | 0x0D000000);
-				RTUSBWriteMACRegister(pAd, LDO_CFG0, data);
-			} else {
-				RTMP_IO_READ32(pAd, LDO_CFG0, &data);
-				data = ((data & 0xE0FFFFFF) | 0x01000000);
-				RTMP_IO_WRITE32(pAd, LDO_CFG0, data);
-			}
-
-			/* patch LNA_PE_G1 failed issue */
-			RTUSBReadMACRegister(pAd, GPIO_SWITCH, &data);
-			data &= ~(0x20);
-			RTUSBWriteMACRegister(pAd, GPIO_SWITCH, data);
-		}
-		/*For RF filter Calibration */
-		RTMPFilterCalibration(pAd);
-
-		/* Initialize RF R27 register, set RF R27 must be behind RTMPFilterCalibration() */
-		/* */
-		/* TX to RX IQ glitch(RF_R27) has been fixed in RT3070(F). */
-		/* Raising RF voltage is no longer needed for RT3070(F) */
-		/* */
-		if ((IS_RT3070(pAd)) && ((pAd->MACVersion & 0xffff) < 0x0201)) {
-			RT30xxWriteRFRegister(pAd, RF_R27, 0x3);
-		} else if ((IS_RT3071(pAd))
-			   && ((pAd->MACVersion & 0xffff) < 0x0211)) {
-			RT30xxWriteRFRegister(pAd, RF_R27, 0x3);
-		}
-		/* set led open drain enable */
-		RTUSBReadMACRegister(pAd, OPT_14, &data);
-		data |= 0x01;
-		RTUSBWriteMACRegister(pAd, OPT_14, data);
-
-		/* move from RT30xxLoadRFNormalModeSetup because it's needed for both RT3070 and RT3071 */
-		/* TX_LO1_en, RF R17 register Bit 3 to 0 */
-		RT30xxReadRFRegister(pAd, RF_R17, &RFValue);
-		RFValue &= (~0x08);
-		/* to fix rx long range issue */
-		if (pAd->NicConfig2.field.ExternalLNAForG == 0) {
-			if ((IS_RT3071(pAd)
-			     && ((pAd->MACVersion & 0xffff) >= 0x0211))
-			    || IS_RT3070(pAd)) {
-				RFValue |= 0x20;
-			}
-		}
-		/* set RF_R17_bit[2:0] equal to EEPROM setting at 0x48h */
-		if (pAd->TxMixerGain24G >= 1) {
-			RFValue &= (~0x7);	/* clean bit [2:0] */
-			RFValue |= pAd->TxMixerGain24G;
-		}
-		RT30xxWriteRFRegister(pAd, RF_R17, RFValue);
-
-		if (IS_RT3071(pAd)) {
-			/* add by johnli, RF power sequence setup, load RF normal operation-mode setup */
-			RT30xxLoadRFNormalModeSetup(pAd);
-		} else if (IS_RT3070(pAd)) {
-			/* add by johnli, reset RF_R27 when interface down & up to fix throughput problem */
-			/* LDORF_VC, RF R27 register Bit 2 to 0 */
-			RT30xxReadRFRegister(pAd, RF_R27, &RFValue);
-			/* TX to RX IQ glitch(RF_R27) has been fixed in RT3070(F). */
-			/* Raising RF voltage is no longer needed for RT3070(F) */
-			if ((pAd->MACVersion & 0xffff) < 0x0201)
-				RFValue = (RFValue & (~0x77)) | 0x3;
-			else
-				RFValue = (RFValue & (~0x77));
-			RT30xxWriteRFRegister(pAd, RF_R27, RFValue);
-			/* end johnli */
-		}
-	}
-
-}
-#endif /* RT3070 // */
diff -druN linux-2.6.39-libre/drivers/staging/rt2860/chips/rt3090.c linux-3.0-rc7-libre/drivers/staging/rt2860/chips/rt3090.c
--- linux-2.6.39-libre/drivers/staging/rt2860/chips/rt3090.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rt2860/chips/rt3090.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,121 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, 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.             *
- *                                                                       *
- *************************************************************************
-
-	Module Name:
-	rt3090.c
-
-	Abstract:
-	Specific functions and variables for RT3070
-
-	Revision History:
-	Who         		When            What
-	Justin P. Mattock	11/07/2010	Fix a typo
-	--------    ----------    ----------------------------------------------
-*/
-
-#ifdef RT3090
-
-#include "../rt_config.h"
-
-#ifndef RTMP_RF_RW_SUPPORT
-#error "You Should Enable compile flag RTMP_RF_RW_SUPPORT for this chip"
-#endif /* RTMP_RF_RW_SUPPORT // */
-
-void NICInitRT3090RFRegisters(struct rt_rtmp_adapter *pAd)
-{
-	int i;
-	/* Driver must read EEPROM to get RfIcType before initial RF registers */
-	/* Initialize RF register to default value */
-	if (IS_RT3090(pAd)) {
-		/* Init RF calibration */
-		/* Driver should toggle RF R30 bit7 before init RF registers */
-		u8 RfReg;
-		u32 data;
-
-		RT30xxReadRFRegister(pAd, RF_R30, (u8 *)&RfReg);
-		RfReg |= 0x80;
-		RT30xxWriteRFRegister(pAd, RF_R30, (u8)RfReg);
-		RTMPusecDelay(1000);
-		RfReg &= 0x7F;
-		RT30xxWriteRFRegister(pAd, RF_R30, (u8)RfReg);
-
-		/* init R24, R31 */
-		RT30xxWriteRFRegister(pAd, RF_R24, 0x0F);
-		RT30xxWriteRFRegister(pAd, RF_R31, 0x0F);
-
-		/* RT309x version E has fixed this issue */
-		if ((pAd->NicConfig2.field.DACTestBit == 1)
-		    && ((pAd->MACVersion & 0xffff) < 0x0211)) {
-			/* patch tx EVM issue temporarily */
-			RTMP_IO_READ32(pAd, LDO_CFG0, &data);
-			data = ((data & 0xE0FFFFFF) | 0x0D000000);
-			RTMP_IO_WRITE32(pAd, LDO_CFG0, data);
-		} else {
-			RTMP_IO_READ32(pAd, LDO_CFG0, &data);
-			data = ((data & 0xE0FFFFFF) | 0x01000000);
-			RTMP_IO_WRITE32(pAd, LDO_CFG0, data);
-		}
-
-		/* patch LNA_PE_G1 failed issue */
-		RTMP_IO_READ32(pAd, GPIO_SWITCH, &data);
-		data &= ~(0x20);
-		RTMP_IO_WRITE32(pAd, GPIO_SWITCH, data);
-
-		/* Initialize RF register to default value */
-		for (i = 0; i < NUM_RF_REG_PARMS; i++) {
-			RT30xxWriteRFRegister(pAd,
-					      RT30xx_RFRegTable[i].Register,
-					      RT30xx_RFRegTable[i].Value);
-		}
-
-		/* Driver should set RF R6 bit6 on before calibration */
-		RT30xxReadRFRegister(pAd, RF_R06, (u8 *)&RfReg);
-		RfReg |= 0x40;
-		RT30xxWriteRFRegister(pAd, RF_R06, (u8)RfReg);
-
-		/*For RF filter Calibration */
-		RTMPFilterCalibration(pAd);
-
-		/* Initialize RF R27 register, set RF R27 must be behind RTMPFilterCalibration() */
-		if ((pAd->MACVersion & 0xffff) < 0x0211)
-			RT30xxWriteRFRegister(pAd, RF_R27, 0x3);
-
-		/* set led open drain enable */
-		RTMP_IO_READ32(pAd, OPT_14, &data);
-		data |= 0x01;
-		RTMP_IO_WRITE32(pAd, OPT_14, data);
-
-		/* set default antenna as main */
-		if (pAd->RfIcType == RFIC_3020)
-			AsicSetRxAnt(pAd, pAd->RxAnt.Pair1PrimaryRxAnt);
-
-		/* add by johnli, RF power sequence setup, load RF normal operation-mode setup */
-		RT30xxLoadRFNormalModeSetup(pAd);
-	}
-
-}
-
-#endif /* RT3090 // */
diff -druN linux-2.6.39-libre/drivers/staging/rt2860/chips/rt30xx.c linux-3.0-rc7-libre/drivers/staging/rt2860/chips/rt30xx.c
--- linux-2.6.39-libre/drivers/staging/rt2860/chips/rt30xx.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rt2860/chips/rt30xx.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,516 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, 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.             *
- *                                                                       *
- *************************************************************************
-
-	Module Name:
-	rt30xx.c
-
-	Abstract:
-	Specific functions and variables for RT30xx.
-
-	Revision History:
-	Who         		When            What
-	Justin P. Mattock	11/07/2010	Fix some typos
-	--------    ----------    ----------------------------------------------
-*/
-
-#ifdef RT30xx
-
-#ifndef RTMP_RF_RW_SUPPORT
-#error "You Should Enable compile flag RTMP_RF_RW_SUPPORT for this chip"
-#endif /* RTMP_RF_RW_SUPPORT // */
-
-#include "../rt_config.h"
-
-/* */
-/* RF register initialization set */
-/* */
-struct rt_reg_pair RT30xx_RFRegTable[] = {
-	{RF_R04, 0x40}
-	,
-	{RF_R05, 0x03}
-	,
-	{RF_R06, 0x02}
-	,
-	{RF_R07, 0x60}
-	,
-	{RF_R09, 0x0F}
-	,
-	{RF_R10, 0x41}
-	,
-	{RF_R11, 0x21}
-	,
-	{RF_R12, 0x7B}
-	,
-	{RF_R14, 0x90}
-	,
-	{RF_R15, 0x58}
-	,
-	{RF_R16, 0xB3}
-	,
-	{RF_R17, 0x92}
-	,
-	{RF_R18, 0x2C}
-	,
-	{RF_R19, 0x02}
-	,
-	{RF_R20, 0xBA}
-	,
-	{RF_R21, 0xDB}
-	,
-	{RF_R24, 0x16}
-	,
-	{RF_R25, 0x01}
-	,
-	{RF_R29, 0x1F}
-	,
-};
-
-u8 NUM_RF_REG_PARMS = (sizeof(RT30xx_RFRegTable) / sizeof(struct rt_reg_pair));
-
-/* Antenna diversity use GPIO3 and EESK pin for control */
-/* Antenna and EEPROM access are both using EESK pin, */
-/* Therefor we should avoid accessing EESK at the same time */
-/* Then restore antenna after EEPROM access */
-/* The original name of this function is AsicSetRxAnt(), now change to */
-/*void AsicSetRxAnt( */
-void RT30xxSetRxAnt(struct rt_rtmp_adapter *pAd, u8 Ant)
-{
-	u32 Value;
-#ifdef RTMP_MAC_PCI
-	u32 x;
-#endif
-
-	if ((pAd->EepromAccess) ||
-	    (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)) ||
-	    (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) ||
-	    (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF)) ||
-	    (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))) {
-		return;
-	}
-	/* the antenna selection is through firmware and MAC register(GPIO3) */
-	if (Ant == 0) {
-		/* Main antenna */
-#ifdef RTMP_MAC_PCI
-		RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
-		x |= (EESK);
-		RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);
-#else
-		AsicSendCommandToMcu(pAd, 0x73, 0xFF, 0x1, 0x0);
-#endif /* RTMP_MAC_PCI // */
-
-		RTMP_IO_READ32(pAd, GPIO_CTRL_CFG, &Value);
-		Value &= ~(0x0808);
-		RTMP_IO_WRITE32(pAd, GPIO_CTRL_CFG, Value);
-		DBGPRINT_RAW(RT_DEBUG_TRACE,
-			     ("AsicSetRxAnt, switch to main antenna\n"));
-	} else {
-		/* Aux antenna */
-#ifdef RTMP_MAC_PCI
-		RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
-		x &= ~(EESK);
-		RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);
-#else
-		AsicSendCommandToMcu(pAd, 0x73, 0xFF, 0x0, 0x0);
-#endif /* RTMP_MAC_PCI // */
-		RTMP_IO_READ32(pAd, GPIO_CTRL_CFG, &Value);
-		Value &= ~(0x0808);
-		Value |= 0x08;
-		RTMP_IO_WRITE32(pAd, GPIO_CTRL_CFG, Value);
-		DBGPRINT_RAW(RT_DEBUG_TRACE,
-			     ("AsicSetRxAnt, switch to aux antenna\n"));
-	}
-}
-
-/*
-	========================================================================
-
-	Routine Description:
-		For RF filter calibration purpose
-
-	Arguments:
-		pAd                          Pointer to our adapter
-
-	Return Value:
-		None
-
-	IRQL = PASSIVE_LEVEL
-
-	========================================================================
-*/
-void RTMPFilterCalibration(struct rt_rtmp_adapter *pAd)
-{
-	u8 R55x = 0, value, FilterTarget = 0x1E, BBPValue = 0;
-	u32 loop = 0, count = 0, loopcnt = 0, ReTry = 0;
-	u8 RF_R24_Value = 0;
-
-	/* Give bbp filter initial value */
-	pAd->Mlme.CaliBW20RfR24 = 0x1F;
-	pAd->Mlme.CaliBW40RfR24 = 0x2F;	/*Bit[5] must be 1 for BW 40 */
-
-	do {
-		if (loop == 1) {	/*BandWidth = 40 MHz */
-			/* Write 0x27 to RF_R24 to program filter */
-			RF_R24_Value = 0x27;
-			RT30xxWriteRFRegister(pAd, RF_R24, RF_R24_Value);
-			if (IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd))
-				FilterTarget = 0x15;
-			else
-				FilterTarget = 0x19;
-
-			/* when calibrate BW40, BBP mask must set to BW40. */
-			RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue);
-			BBPValue &= (~0x18);
-			BBPValue |= (0x10);
-			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue);
-
-			/* set to BW40 */
-			RT30xxReadRFRegister(pAd, RF_R31, &value);
-			value |= 0x20;
-			RT30xxWriteRFRegister(pAd, RF_R31, value);
-		} else {	/*BandWidth = 20 MHz */
-			/* Write 0x07 to RF_R24 to program filter */
-			RF_R24_Value = 0x07;
-			RT30xxWriteRFRegister(pAd, RF_R24, RF_R24_Value);
-			if (IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd))
-				FilterTarget = 0x13;
-			else
-				FilterTarget = 0x16;
-
-			/* set to BW20 */
-			RT30xxReadRFRegister(pAd, RF_R31, &value);
-			value &= (~0x20);
-			RT30xxWriteRFRegister(pAd, RF_R31, value);
-		}
-
-		/* Write 0x01 to RF_R22 to enable baseband loopback mode */
-		RT30xxReadRFRegister(pAd, RF_R22, &value);
-		value |= 0x01;
-		RT30xxWriteRFRegister(pAd, RF_R22, value);
-
-		/* Write 0x00 to BBP_R24 to set power & frequency of passband test tone */
-		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R24, 0);
-
-		do {
-			/* Write 0x90 to BBP_R25 to transmit test tone */
-			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R25, 0x90);
-
-			RTMPusecDelay(1000);
-			/* Read BBP_R55[6:0] for received power, set R55x = BBP_R55[6:0] */
-			RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R55, &value);
-			R55x = value & 0xFF;
-
-		} while ((ReTry++ < 100) && (R55x == 0));
-
-		/* Write 0x06 to BBP_R24 to set power & frequency of stopband test tone */
-		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R24, 0x06);
-
-		while (TRUE) {
-			/* Write 0x90 to BBP_R25 to transmit test tone */
-			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R25, 0x90);
-
-			/*We need to wait for calibration */
-			RTMPusecDelay(1000);
-			RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R55, &value);
-			value &= 0xFF;
-			if ((R55x - value) < FilterTarget) {
-				RF_R24_Value++;
-			} else if ((R55x - value) == FilterTarget) {
-				RF_R24_Value++;
-				count++;
-			} else {
-				break;
-			}
-
-			/* prevent infinite loop; causes driver hang. */
-			if (loopcnt++ > 100) {
-				DBGPRINT(RT_DEBUG_ERROR,
-					 ("RTMPFilterCalibration - can't find a valid value, loopcnt=%d stop calibrating",
-					  loopcnt));
-				break;
-			}
-			/* Write RF_R24 to program filter */
-			RT30xxWriteRFRegister(pAd, RF_R24, RF_R24_Value);
-		}
-
-		if (count > 0) {
-			RF_R24_Value = RF_R24_Value - ((count) ? (1) : (0));
-		}
-		/* Store for future usage */
-		if (loopcnt < 100) {
-			if (loop++ == 0) {
-				/*BandWidth = 20 MHz */
-				pAd->Mlme.CaliBW20RfR24 = (u8)RF_R24_Value;
-			} else {
-				/*BandWidth = 40 MHz */
-				pAd->Mlme.CaliBW40RfR24 = (u8)RF_R24_Value;
-				break;
-			}
-		} else
-			break;
-
-		RT30xxWriteRFRegister(pAd, RF_R24, RF_R24_Value);
-
-		/* reset count */
-		count = 0;
-	} while (TRUE);
-
-	/* */
-	/* Set back to initial state */
-	/* */
-	RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R24, 0);
-
-	RT30xxReadRFRegister(pAd, RF_R22, &value);
-	value &= ~(0x01);
-	RT30xxWriteRFRegister(pAd, RF_R22, value);
-
-	/* set BBP back to BW20 */
-	RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue);
-	BBPValue &= (~0x18);
-	RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue);
-
-	DBGPRINT(RT_DEBUG_TRACE,
-		 ("RTMPFilterCalibration - CaliBW20RfR24=0x%x, CaliBW40RfR24=0x%x\n",
-		  pAd->Mlme.CaliBW20RfR24, pAd->Mlme.CaliBW40RfR24));
-}
-
-/* add by johnli, RF power sequence setup */
-/*
-	==========================================================================
-	Description:
-
-	Load RF normal operation-mode setup
-
-	==========================================================================
- */
-void RT30xxLoadRFNormalModeSetup(struct rt_rtmp_adapter *pAd)
-{
-	u8 RFValue;
-
-	/* RX0_PD & TX0_PD, RF R1 register Bit 2 & Bit 3 to 0 and RF_BLOCK_en,RX1_PD & TX1_PD, Bit0, Bit 4 & Bit5 to 1 */
-	RT30xxReadRFRegister(pAd, RF_R01, &RFValue);
-	RFValue = (RFValue & (~0x0C)) | 0x31;
-	RT30xxWriteRFRegister(pAd, RF_R01, RFValue);
-
-	/* TX_LO2_en, RF R15 register Bit 3 to 0 */
-	RT30xxReadRFRegister(pAd, RF_R15, &RFValue);
-	RFValue &= (~0x08);
-	RT30xxWriteRFRegister(pAd, RF_R15, RFValue);
-
-	/* move to NICInitRT30xxRFRegisters
-	   // TX_LO1_en, RF R17 register Bit 3 to 0
-	   RT30xxReadRFRegister(pAd, RF_R17, &RFValue);
-	   RFValue &= (~0x08);
-	   // to fix rx long range issue
-	   if (((pAd->MACVersion & 0xffff) >= 0x0211) && (pAd->NicConfig2.field.ExternalLNAForG == 0))
-	   {
-	   RFValue |= 0x20;
-	   }
-	   // set RF_R17_bit[2:0] equal to EEPROM setting at 0x48h
-	   if (pAd->TxMixerGain24G >= 2)
-	   {
-	   RFValue &= (~0x7);  // clean bit [2:0]
-	   RFValue |= pAd->TxMixerGain24G;
-	   }
-	   RT30xxWriteRFRegister(pAd, RF_R17, RFValue);
-	 */
-
-	/* RX_LO1_en, RF R20 register Bit 3 to 0 */
-	RT30xxReadRFRegister(pAd, RF_R20, &RFValue);
-	RFValue &= (~0x08);
-	RT30xxWriteRFRegister(pAd, RF_R20, RFValue);
-
-	/* RX_LO2_en, RF R21 register Bit 3 to 0 */
-	RT30xxReadRFRegister(pAd, RF_R21, &RFValue);
-	RFValue &= (~0x08);
-	RT30xxWriteRFRegister(pAd, RF_R21, RFValue);
-
-	/* add by johnli, reset RF_R27 when interface down & up to fix throughput problem */
-	/* LDORF_VC, RF R27 register Bit 2 to 0 */
-	RT30xxReadRFRegister(pAd, RF_R27, &RFValue);
-	/* TX to RX IQ glitch(RF_R27) has been fixed in RT3070(F). */
-	/* Raising RF voltage is no longer needed for RT3070(F) */
-	if (IS_RT3090(pAd)) {	/* RT309x and RT3071/72 */
-		if ((pAd->MACVersion & 0xffff) < 0x0211)
-			RFValue = (RFValue & (~0x77)) | 0x3;
-		else
-			RFValue = (RFValue & (~0x77));
-		RT30xxWriteRFRegister(pAd, RF_R27, RFValue);
-	}
-	/* end johnli */
-}
-
-/*
-	==========================================================================
-	Description:
-
-	Load RF sleep-mode setup
-
-	==========================================================================
- */
-void RT30xxLoadRFSleepModeSetup(struct rt_rtmp_adapter *pAd)
-{
-	u8 RFValue;
-	u32 MACValue;
-
-#ifdef RTMP_MAC_USB
-	if (!IS_RT3572(pAd))
-#endif /* RTMP_MAC_USB // */
-	{
-		/* RF_BLOCK_en. RF R1 register Bit 0 to 0 */
-		RT30xxReadRFRegister(pAd, RF_R01, &RFValue);
-		RFValue &= (~0x01);
-		RT30xxWriteRFRegister(pAd, RF_R01, RFValue);
-
-		/* VCO_IC, RF R7 register Bit 4 & Bit 5 to 0 */
-		RT30xxReadRFRegister(pAd, RF_R07, &RFValue);
-		RFValue &= (~0x30);
-		RT30xxWriteRFRegister(pAd, RF_R07, RFValue);
-
-		/* Idoh, RF R9 register Bit 1, Bit 2 & Bit 3 to 0 */
-		RT30xxReadRFRegister(pAd, RF_R09, &RFValue);
-		RFValue &= (~0x0E);
-		RT30xxWriteRFRegister(pAd, RF_R09, RFValue);
-
-		/* RX_CTB_en, RF R21 register Bit 7 to 0 */
-		RT30xxReadRFRegister(pAd, RF_R21, &RFValue);
-		RFValue &= (~0x80);
-		RT30xxWriteRFRegister(pAd, RF_R21, RFValue);
-	}
-
-	if (IS_RT3090(pAd) ||	/* IS_RT3090 including RT309x and RT3071/72 */
-	    IS_RT3572(pAd) ||
-	    (IS_RT3070(pAd) && ((pAd->MACVersion & 0xffff) < 0x0201))) {
-#ifdef RTMP_MAC_USB
-		if (!IS_RT3572(pAd))
-#endif /* RTMP_MAC_USB // */
-		{
-			RT30xxReadRFRegister(pAd, RF_R27, &RFValue);
-			RFValue |= 0x77;
-			RT30xxWriteRFRegister(pAd, RF_R27, RFValue);
-		}
-
-		RTMP_IO_READ32(pAd, LDO_CFG0, &MACValue);
-		MACValue |= 0x1D000000;
-		RTMP_IO_WRITE32(pAd, LDO_CFG0, MACValue);
-	}
-}
-
-/*
-	==========================================================================
-	Description:
-
-	Reverse RF sleep-mode setup
-
-	==========================================================================
- */
-void RT30xxReverseRFSleepModeSetup(struct rt_rtmp_adapter *pAd)
-{
-	u8 RFValue;
-	u32 MACValue;
-
-#ifdef RTMP_MAC_USB
-	if (!IS_RT3572(pAd))
-#endif /* RTMP_MAC_USB // */
-	{
-		/* RF_BLOCK_en, RF R1 register Bit 0 to 1 */
-		RT30xxReadRFRegister(pAd, RF_R01, &RFValue);
-		RFValue |= 0x01;
-		RT30xxWriteRFRegister(pAd, RF_R01, RFValue);
-
-		/* VCO_IC, RF R7 register Bit 4 & Bit 5 to 1 */
-		RT30xxReadRFRegister(pAd, RF_R07, &RFValue);
-		RFValue |= 0x20;
-		RT30xxWriteRFRegister(pAd, RF_R07, RFValue);
-
-		/* Idoh, RF R9 register Bit 1, Bit 2 & Bit 3 to 1 */
-		RT30xxReadRFRegister(pAd, RF_R09, &RFValue);
-		RFValue |= 0x0E;
-		RT30xxWriteRFRegister(pAd, RF_R09, RFValue);
-
-		/* RX_CTB_en, RF R21 register Bit 7 to 1 */
-		RT30xxReadRFRegister(pAd, RF_R21, &RFValue);
-		RFValue |= 0x80;
-		RT30xxWriteRFRegister(pAd, RF_R21, RFValue);
-	}
-
-	if (IS_RT3090(pAd) ||	/* IS_RT3090 including RT309x and RT3071/72 */
-	    IS_RT3572(pAd) ||
-	    IS_RT3390(pAd) ||
-	    (IS_RT3070(pAd) && ((pAd->MACVersion & 0xffff) < 0x0201))) {
-#ifdef RTMP_MAC_USB
-		if (!IS_RT3572(pAd))
-#endif /* RTMP_MAC_USB // */
-		{
-			RT30xxReadRFRegister(pAd, RF_R27, &RFValue);
-			if ((pAd->MACVersion & 0xffff) < 0x0211)
-				RFValue = (RFValue & (~0x77)) | 0x3;
-			else
-				RFValue = (RFValue & (~0x77));
-			RT30xxWriteRFRegister(pAd, RF_R27, RFValue);
-		}
-		/* RT3071 version E has fixed this issue */
-		if ((pAd->NicConfig2.field.DACTestBit == 1)
-		    && ((pAd->MACVersion & 0xffff) < 0x0211)) {
-			/* patch tx EVM issue temporarily */
-			RTMP_IO_READ32(pAd, LDO_CFG0, &MACValue);
-			MACValue = ((MACValue & 0xE0FFFFFF) | 0x0D000000);
-			RTMP_IO_WRITE32(pAd, LDO_CFG0, MACValue);
-		} else {
-			RTMP_IO_READ32(pAd, LDO_CFG0, &MACValue);
-			MACValue = ((MACValue & 0xE0FFFFFF) | 0x01000000);
-			RTMP_IO_WRITE32(pAd, LDO_CFG0, MACValue);
-		}
-	}
-
-	if (IS_RT3572(pAd))
-		RT30xxWriteRFRegister(pAd, RF_R08, 0x80);
-}
-
-/* end johnli */
-
-void RT30xxHaltAction(struct rt_rtmp_adapter *pAd)
-{
-	u32 TxPinCfg = 0x00050F0F;
-
-	/* */
-	/* Turn off LNA_PE or TRSW_POL */
-	/* */
-	if (IS_RT3070(pAd) || IS_RT3071(pAd) || IS_RT3572(pAd)) {
-		if ((IS_RT3071(pAd) || IS_RT3572(pAd))
-#ifdef RTMP_EFUSE_SUPPORT
-		    && (pAd->bUseEfuse)
-#endif /* RTMP_EFUSE_SUPPORT // */
-		    ) {
-			TxPinCfg &= 0xFFFBF0F0;	/* bit18 off */
-		} else {
-			TxPinCfg &= 0xFFFFF0F0;
-		}
-
-		RTMP_IO_WRITE32(pAd, TX_PIN_CFG, TxPinCfg);
-	}
-}
-
-#endif /* RT30xx // */
diff -druN linux-2.6.39-libre/drivers/staging/rt2860/chlist.h linux-3.0-rc7-libre/drivers/staging/rt2860/chlist.h
--- linux-2.6.39-libre/drivers/staging/rt2860/chlist.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rt2860/chlist.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,113 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, 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.             *
- *                                                                       *
- *************************************************************************
-
-	Module Name:
-	chlist.c
-
-	Abstract:
-
-	Revision History:
-	Who         When          What
-	--------    ----------    ----------------------------------------------
-	Fonchi Wu   2007-12-19    created
-*/
-
-#ifndef __CHLIST_H__
-#define __CHLIST_H__
-
-#include "rtmp_type.h"
-#include "rtmp_def.h"
-
-#define ODOR			0
-#define IDOR			1
-#define BOTH			2
-
-#define BAND_5G         0
-#define BAND_24G        1
-#define BAND_BOTH       2
-
-struct rt_ch_desp {
-	u8 FirstChannel;
-	u8 NumOfCh;
-	char MaxTxPwr;		/* dBm */
-	u8 Geography;	/* 0:out door, 1:in door, 2:both */
-	BOOLEAN DfsReq;		/* Dfs require, 0: No, 1: yes. */
-};
-
-struct rt_ch_region {
-	u8 CountReg[3];
-	u8 DfsType;		/* 0: CE, 1: FCC, 2: JAP, 3:JAP_W53, JAP_W56 */
-	struct rt_ch_desp ChDesp[10];
-};
-
-extern struct rt_ch_region ChRegion[];
-
-struct rt_ch_freq_map {
-	u16 channel;
-	u16 freqKHz;
-};
-
-extern struct rt_ch_freq_map CH_HZ_ID_MAP[];
-extern int CH_HZ_ID_MAP_NUM;
-
-#define     MAP_CHANNEL_ID_TO_KHZ(_ch, _khz)		\
-		do {							\
-			int _chIdx;					\
-			for (_chIdx = 0; _chIdx < CH_HZ_ID_MAP_NUM; _chIdx++) {\
-				if ((_ch) == CH_HZ_ID_MAP[_chIdx].channel) { \
-					(_khz) = CH_HZ_ID_MAP[_chIdx].freqKHz * 1000;\
-					break;				\
-				}					\
-			}						\
-			if (_chIdx == CH_HZ_ID_MAP_NUM)	\
-				(_khz) = 2412000;		\
-		} while (0)
-
-#define     MAP_KHZ_TO_CHANNEL_ID(_khz, _ch)                 \
-		do {							\
-			int _chIdx;				\
-			for (_chIdx = 0; _chIdx < CH_HZ_ID_MAP_NUM; _chIdx++) {\
-				if ((_khz) == CH_HZ_ID_MAP[_chIdx].freqKHz) {\
-					(_ch) = CH_HZ_ID_MAP[_chIdx].channel; \
-					break;			\
-				}					\
-			}						\
-			if (_chIdx == CH_HZ_ID_MAP_NUM)			\
-				(_ch) = 1;				\
-		} while (0)
-
-void BuildChannelListEx(struct rt_rtmp_adapter *pAd);
-
-void BuildBeaconChList(struct rt_rtmp_adapter *pAd,
-		       u8 *pBuf, unsigned long *pBufLen);
-
-void N_ChannelCheck(struct rt_rtmp_adapter *pAd);
-
-void N_SetCenCh(struct rt_rtmp_adapter *pAd);
-
-u8 GetCuntryMaxTxPwr(struct rt_rtmp_adapter *pAd, u8 channel);
-
-#endif /* __CHLIST_H__ */
diff -druN linux-2.6.39-libre/drivers/staging/rt2860/common/action.c linux-3.0-rc7-libre/drivers/staging/rt2860/common/action.c
--- linux-2.6.39-libre/drivers/staging/rt2860/common/action.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rt2860/common/action.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,606 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, 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.             *
- *                                                                       *
- *************************************************************************
-
-    Module Name:
-	action.c
-
-    Abstract:
-    Handle association related requests either from WSTA or from local MLME
-
-    Revision History:
-    Who         When          What
-    --------    ----------    ----------------------------------------------
-	Jan Lee		2006	  	created for rt2860
- */
-
-#include "../rt_config.h"
-#include "action.h"
-
-static void ReservedAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem);
-
-/*
-    ==========================================================================
-    Description:
-        association state machine init, including state transition and timer init
-    Parameters:
-        S - pointer to the association state machine
-    Note:
-        The state machine looks like the following
-
-                                    ASSOC_IDLE
-        MT2_MLME_DISASSOC_REQ    mlme_disassoc_req_action
-        MT2_PEER_DISASSOC_REQ    peer_disassoc_action
-        MT2_PEER_ASSOC_REQ       drop
-        MT2_PEER_REASSOC_REQ     drop
-        MT2_CLS3ERR              cls3err_action
-    ==========================================================================
- */
-void ActionStateMachineInit(struct rt_rtmp_adapter *pAd,
-			    struct rt_state_machine *S,
-			    OUT STATE_MACHINE_FUNC Trans[])
-{
-	StateMachineInit(S, (STATE_MACHINE_FUNC *) Trans, MAX_ACT_STATE,
-			 MAX_ACT_MSG, (STATE_MACHINE_FUNC) Drop, ACT_IDLE,
-			 ACT_MACHINE_BASE);
-
-	StateMachineSetAction(S, ACT_IDLE, MT2_PEER_SPECTRUM_CATE,
-			      (STATE_MACHINE_FUNC) PeerSpectrumAction);
-	StateMachineSetAction(S, ACT_IDLE, MT2_PEER_QOS_CATE,
-			      (STATE_MACHINE_FUNC) PeerQOSAction);
-
-	StateMachineSetAction(S, ACT_IDLE, MT2_PEER_DLS_CATE,
-			      (STATE_MACHINE_FUNC) ReservedAction);
-
-	StateMachineSetAction(S, ACT_IDLE, MT2_PEER_BA_CATE,
-			      (STATE_MACHINE_FUNC) PeerBAAction);
-	StateMachineSetAction(S, ACT_IDLE, MT2_PEER_HT_CATE,
-			      (STATE_MACHINE_FUNC) PeerHTAction);
-	StateMachineSetAction(S, ACT_IDLE, MT2_MLME_ADD_BA_CATE,
-			      (STATE_MACHINE_FUNC) MlmeADDBAAction);
-	StateMachineSetAction(S, ACT_IDLE, MT2_MLME_ORI_DELBA_CATE,
-			      (STATE_MACHINE_FUNC) MlmeDELBAAction);
-	StateMachineSetAction(S, ACT_IDLE, MT2_MLME_REC_DELBA_CATE,
-			      (STATE_MACHINE_FUNC) MlmeDELBAAction);
-
-	StateMachineSetAction(S, ACT_IDLE, MT2_PEER_PUBLIC_CATE,
-			      (STATE_MACHINE_FUNC) PeerPublicAction);
-	StateMachineSetAction(S, ACT_IDLE, MT2_PEER_RM_CATE,
-			      (STATE_MACHINE_FUNC) PeerRMAction);
-
-	StateMachineSetAction(S, ACT_IDLE, MT2_MLME_QOS_CATE,
-			      (STATE_MACHINE_FUNC) MlmeQOSAction);
-	StateMachineSetAction(S, ACT_IDLE, MT2_MLME_DLS_CATE,
-			      (STATE_MACHINE_FUNC) MlmeDLSAction);
-	StateMachineSetAction(S, ACT_IDLE, MT2_ACT_INVALID,
-			      (STATE_MACHINE_FUNC) MlmeInvalidAction);
-}
-
-void MlmeADDBAAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
-{
-	struct rt_mlme_addba_req *pInfo;
-	u8 Addr[6];
-	u8 *pOutBuffer = NULL;
-	int NStatus;
-	unsigned long Idx;
-	struct rt_frame_addba_req Frame;
-	unsigned long FrameLen;
-	struct rt_ba_ori_entry *pBAEntry = NULL;
-
-	pInfo = (struct rt_mlme_addba_req *)Elem->Msg;
-	NdisZeroMemory(&Frame, sizeof(struct rt_frame_addba_req));
-
-	if (MlmeAddBAReqSanity(pAd, Elem->Msg, Elem->MsgLen, Addr)) {
-		NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);	/*Get an unused nonpaged memory */
-		if (NStatus != NDIS_STATUS_SUCCESS) {
-			DBGPRINT(RT_DEBUG_TRACE,
-				 ("BA - MlmeADDBAAction() allocate memory failed \n"));
-			return;
-		}
-		/* 1. find entry */
-		Idx =
-		    pAd->MacTab.Content[pInfo->Wcid].BAOriWcidArray[pInfo->TID];
-		if (Idx == 0) {
-			MlmeFreeMemory(pAd, pOutBuffer);
-			DBGPRINT(RT_DEBUG_ERROR,
-				 ("BA - MlmeADDBAAction() can't find BAOriEntry \n"));
-			return;
-		} else {
-			pBAEntry = &pAd->BATable.BAOriEntry[Idx];
-		}
-
-		{
-			if (ADHOC_ON(pAd))
-				ActHeaderInit(pAd, &Frame.Hdr, pInfo->pAddr,
-					      pAd->CurrentAddress,
-					      pAd->CommonCfg.Bssid);
-			else
-				ActHeaderInit(pAd, &Frame.Hdr,
-					      pAd->CommonCfg.Bssid,
-					      pAd->CurrentAddress,
-					      pInfo->pAddr);
-		}
-
-		Frame.Category = CATEGORY_BA;
-		Frame.Action = ADDBA_REQ;
-		Frame.BaParm.AMSDUSupported = 0;
-		Frame.BaParm.BAPolicy = IMMED_BA;
-		Frame.BaParm.TID = pInfo->TID;
-		Frame.BaParm.BufSize = pInfo->BaBufSize;
-		Frame.Token = pInfo->Token;
-		Frame.TimeOutValue = pInfo->TimeOutValue;
-		Frame.BaStartSeq.field.FragNum = 0;
-		Frame.BaStartSeq.field.StartSeq =
-		    pAd->MacTab.Content[pInfo->Wcid].TxSeq[pInfo->TID];
-
-		*(u16 *) (&Frame.BaParm) =
-		    cpu2le16(*(u16 *) (&Frame.BaParm));
-		Frame.TimeOutValue = cpu2le16(Frame.TimeOutValue);
-		Frame.BaStartSeq.word = cpu2le16(Frame.BaStartSeq.word);
-
-		MakeOutgoingFrame(pOutBuffer, &FrameLen,
-				  sizeof(struct rt_frame_addba_req), &Frame, END_OF_ARGS);
-
-		MiniportMMRequest(pAd,
-				  (MGMT_USE_QUEUE_FLAG |
-				   MapUserPriorityToAccessCategory[pInfo->TID]),
-				  pOutBuffer, FrameLen);
-
-		MlmeFreeMemory(pAd, pOutBuffer);
-
-		DBGPRINT(RT_DEBUG_TRACE,
-			 ("BA - Send ADDBA request. StartSeq = %x,  FrameLen = %ld. BufSize = %d\n",
-			  Frame.BaStartSeq.field.StartSeq, FrameLen,
-			  Frame.BaParm.BufSize));
-	}
-}
-
-/*
-    ==========================================================================
-    Description:
-        send DELBA and delete BaEntry if any
-    Parametrs:
-        Elem - MLME message struct rt_mlme_delba_req
-
-	IRQL = DISPATCH_LEVEL
-
-    ==========================================================================
- */
-void MlmeDELBAAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
-{
-	struct rt_mlme_delba_req *pInfo;
-	u8 *pOutBuffer = NULL;
-	u8 *pOutBuffer2 = NULL;
-	int NStatus;
-	unsigned long Idx;
-	struct rt_frame_delba_req Frame;
-	unsigned long FrameLen;
-	struct rt_frame_bar FrameBar;
-
-	pInfo = (struct rt_mlme_delba_req *)Elem->Msg;
-	/* must send back DELBA */
-	NdisZeroMemory(&Frame, sizeof(struct rt_frame_delba_req));
-	DBGPRINT(RT_DEBUG_TRACE,
-		 ("==> MlmeDELBAAction(), Initiator(%d) \n", pInfo->Initiator));
-
-	if (MlmeDelBAReqSanity(pAd, Elem->Msg, Elem->MsgLen)) {
-		NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);	/*Get an unused nonpaged memory */
-		if (NStatus != NDIS_STATUS_SUCCESS) {
-			DBGPRINT(RT_DEBUG_ERROR,
-				 ("BA - MlmeDELBAAction() allocate memory failed 1. \n"));
-			return;
-		}
-
-		NStatus = MlmeAllocateMemory(pAd, &pOutBuffer2);	/*Get an unused nonpaged memory */
-		if (NStatus != NDIS_STATUS_SUCCESS) {
-			MlmeFreeMemory(pAd, pOutBuffer);
-			DBGPRINT(RT_DEBUG_ERROR,
-				 ("BA - MlmeDELBAAction() allocate memory failed 2. \n"));
-			return;
-		}
-		/* SEND BAR (Send BAR to refresh peer reordering buffer.) */
-		Idx =
-		    pAd->MacTab.Content[pInfo->Wcid].BAOriWcidArray[pInfo->TID];
-
-		BarHeaderInit(pAd, &FrameBar,
-			      pAd->MacTab.Content[pInfo->Wcid].Addr,
-			      pAd->CurrentAddress);
-
-		FrameBar.StartingSeq.field.FragNum = 0;	/* make sure sequence not clear in DEL funciton. */
-		FrameBar.StartingSeq.field.StartSeq = pAd->MacTab.Content[pInfo->Wcid].TxSeq[pInfo->TID];	/* make sure sequence not clear in DEL funciton. */
-		FrameBar.BarControl.TID = pInfo->TID;	/* make sure sequence not clear in DEL funciton. */
-		FrameBar.BarControl.ACKPolicy = IMMED_BA;	/* make sure sequence not clear in DEL funciton. */
-		FrameBar.BarControl.Compressed = 1;	/* make sure sequence not clear in DEL funciton. */
-		FrameBar.BarControl.MTID = 0;	/* make sure sequence not clear in DEL funciton. */
-
-		MakeOutgoingFrame(pOutBuffer2, &FrameLen,
-				  sizeof(struct rt_frame_bar), &FrameBar, END_OF_ARGS);
-		MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer2, FrameLen);
-		MlmeFreeMemory(pAd, pOutBuffer2);
-		DBGPRINT(RT_DEBUG_TRACE,
-			 ("BA - MlmeDELBAAction() . Send BAR to refresh peer reordering buffer \n"));
-
-		/* SEND DELBA FRAME */
-		FrameLen = 0;
-
-		{
-			if (ADHOC_ON(pAd))
-				ActHeaderInit(pAd, &Frame.Hdr,
-					      pAd->MacTab.Content[pInfo->Wcid].
-					      Addr, pAd->CurrentAddress,
-					      pAd->CommonCfg.Bssid);
-			else
-				ActHeaderInit(pAd, &Frame.Hdr,
-					      pAd->CommonCfg.Bssid,
-					      pAd->CurrentAddress,
-					      pAd->MacTab.Content[pInfo->Wcid].
-					      Addr);
-		}
-
-		Frame.Category = CATEGORY_BA;
-		Frame.Action = DELBA;
-		Frame.DelbaParm.Initiator = pInfo->Initiator;
-		Frame.DelbaParm.TID = pInfo->TID;
-		Frame.ReasonCode = 39;	/* Time Out */
-		*(u16 *) (&Frame.DelbaParm) =
-		    cpu2le16(*(u16 *) (&Frame.DelbaParm));
-		Frame.ReasonCode = cpu2le16(Frame.ReasonCode);
-
-		MakeOutgoingFrame(pOutBuffer, &FrameLen,
-				  sizeof(struct rt_frame_delba_req), &Frame, END_OF_ARGS);
-		MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
-		MlmeFreeMemory(pAd, pOutBuffer);
-		DBGPRINT(RT_DEBUG_TRACE,
-			 ("BA - MlmeDELBAAction() . 3 DELBA sent. Initiator(%d)\n",
-			  pInfo->Initiator));
-	}
-}
-
-void MlmeQOSAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
-{
-}
-
-void MlmeDLSAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
-{
-}
-
-void MlmeInvalidAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
-{
-	/*u8 *                  pOutBuffer = NULL; */
-	/*Return the receiving frame except the MSB of category filed set to 1.  7.3.1.11 */
-}
-
-void PeerQOSAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
-{
-}
-
-void PeerBAAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
-{
-	u8 Action = Elem->Msg[LENGTH_802_11 + 1];
-
-	switch (Action) {
-	case ADDBA_REQ:
-		PeerAddBAReqAction(pAd, Elem);
-		break;
-	case ADDBA_RESP:
-		PeerAddBARspAction(pAd, Elem);
-		break;
-	case DELBA:
-		PeerDelBAAction(pAd, Elem);
-		break;
-	}
-}
-
-void PeerPublicAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
-{
-	if (Elem->Wcid >= MAX_LEN_OF_MAC_TABLE)
-		return;
-}
-
-static void ReservedAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
-{
-	u8 Category;
-
-	if (Elem->MsgLen <= LENGTH_802_11) {
-		return;
-	}
-
-	Category = Elem->Msg[LENGTH_802_11];
-	DBGPRINT(RT_DEBUG_TRACE,
-		 ("Rcv reserved category(%d) Action Frame\n", Category));
-	hex_dump("Reserved Action Frame", &Elem->Msg[0], Elem->MsgLen);
-}
-
-void PeerRMAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
-{
-	return;
-}
-
-static void respond_ht_information_exchange_action(struct rt_rtmp_adapter *pAd,
-						   struct rt_mlme_queue_elem *Elem)
-{
-	u8 *pOutBuffer = NULL;
-	int NStatus;
-	unsigned long FrameLen;
-	struct rt_frame_ht_info HTINFOframe, *pFrame;
-	u8 *pAddr;
-
-	/* 2. Always send back ADDBA Response */
-	NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);	/*Get an unused nonpaged memory */
-
-	if (NStatus != NDIS_STATUS_SUCCESS) {
-		DBGPRINT(RT_DEBUG_TRACE,
-			 ("ACTION - respond_ht_information_exchange_action() allocate memory failed \n"));
-		return;
-	}
-	/* get RA */
-	pFrame = (struct rt_frame_ht_info *) & Elem->Msg[0];
-	pAddr = pFrame->Hdr.Addr2;
-
-	NdisZeroMemory(&HTINFOframe, sizeof(struct rt_frame_ht_info));
-	/* 2-1. Prepare ADDBA Response frame. */
-	{
-		if (ADHOC_ON(pAd))
-			ActHeaderInit(pAd, &HTINFOframe.Hdr, pAddr,
-				      pAd->CurrentAddress,
-				      pAd->CommonCfg.Bssid);
-		else
-			ActHeaderInit(pAd, &HTINFOframe.Hdr,
-				      pAd->CommonCfg.Bssid, pAd->CurrentAddress,
-				      pAddr);
-	}
-
-	HTINFOframe.Category = CATEGORY_HT;
-	HTINFOframe.Action = HT_INFO_EXCHANGE;
-	HTINFOframe.HT_Info.Request = 0;
-	HTINFOframe.HT_Info.Forty_MHz_Intolerant =
-	    pAd->CommonCfg.HtCapability.HtCapInfo.Forty_Mhz_Intolerant;
-	HTINFOframe.HT_Info.STA_Channel_Width =
-	    pAd->CommonCfg.AddHTInfo.AddHtInfo.RecomWidth;
-
-	MakeOutgoingFrame(pOutBuffer, &FrameLen,
-			  sizeof(struct rt_frame_ht_info), &HTINFOframe, END_OF_ARGS);
-
-	MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
-	MlmeFreeMemory(pAd, pOutBuffer);
-}
-
-void PeerHTAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
-{
-	u8 Action = Elem->Msg[LENGTH_802_11 + 1];
-
-	if (Elem->Wcid >= MAX_LEN_OF_MAC_TABLE)
-		return;
-
-	switch (Action) {
-	case NOTIFY_BW_ACTION:
-		DBGPRINT(RT_DEBUG_TRACE,
-			 ("ACTION - HT Notify Channel bandwidth action----> \n"));
-
-		if (pAd->StaActive.SupportedPhyInfo.bHtEnable == FALSE) {
-			/* Note, this is to patch DIR-1353 AP. When the AP set to Wep, it will use legacy mode. But AP still keeps */
-			/* sending BW_Notify Action frame, and cause us to linkup and linkdown. */
-			/* In legacy mode, don't need to parse HT action frame. */
-			DBGPRINT(RT_DEBUG_TRACE,
-				 ("ACTION -Ignore HT Notify Channel BW when link as legacy mode. BW = %d---> \n",
-				  Elem->Msg[LENGTH_802_11 + 2]));
-			break;
-		}
-
-		if (Elem->Msg[LENGTH_802_11 + 2] == 0)	/* 7.4.8.2. if value is 1, keep the same as supported channel bandwidth. */
-			pAd->MacTab.Content[Elem->Wcid].HTPhyMode.field.BW = 0;
-
-		break;
-	case SMPS_ACTION:
-		/* 7.3.1.25 */
-		DBGPRINT(RT_DEBUG_TRACE, ("ACTION - SMPS action----> \n"));
-		if (((Elem->Msg[LENGTH_802_11 + 2] & 0x1) == 0)) {
-			pAd->MacTab.Content[Elem->Wcid].MmpsMode = MMPS_ENABLE;
-		} else if (((Elem->Msg[LENGTH_802_11 + 2] & 0x2) == 0)) {
-			pAd->MacTab.Content[Elem->Wcid].MmpsMode = MMPS_STATIC;
-		} else {
-			pAd->MacTab.Content[Elem->Wcid].MmpsMode = MMPS_DYNAMIC;
-		}
-
-		DBGPRINT(RT_DEBUG_TRACE,
-			 ("Aid(%d) MIMO PS = %d\n", Elem->Wcid,
-			  pAd->MacTab.Content[Elem->Wcid].MmpsMode));
-		/* rt2860c : add something for smps change. */
-		break;
-
-	case SETPCO_ACTION:
-		break;
-	case MIMO_CHA_MEASURE_ACTION:
-		break;
-	case HT_INFO_EXCHANGE:
-		{
-			struct rt_ht_information_octet *pHT_info;
-
-			pHT_info =
-			    (struct rt_ht_information_octet *) & Elem->Msg[LENGTH_802_11 +
-								 2];
-			/* 7.4.8.10 */
-			DBGPRINT(RT_DEBUG_TRACE,
-				 ("ACTION - HT Information Exchange action----> \n"));
-			if (pHT_info->Request) {
-				respond_ht_information_exchange_action(pAd,
-								       Elem);
-			}
-		}
-		break;
-	}
-}
-
-/*
-	==========================================================================
-	Description:
-		Retry sending ADDBA Reqest.
-
-	IRQL = DISPATCH_LEVEL
-
-	Parametrs:
-	p8023Header: if this is already 802.3 format, p8023Header is NULL
-
-	Return	: TRUE if put into rx reordering buffer, shouldn't indicaterxhere.
-				FALSE , then continue indicaterx at this moment.
-	==========================================================================
- */
-void ORIBATimerTimeout(struct rt_rtmp_adapter *pAd)
-{
-	struct rt_mac_table_entry *pEntry;
-	int i, total;
-	u8 TID;
-
-	total = pAd->MacTab.Size * NUM_OF_TID;
-
-	for (i = 1; ((i < MAX_LEN_OF_BA_ORI_TABLE) && (total > 0)); i++) {
-		if (pAd->BATable.BAOriEntry[i].ORI_BA_Status == Originator_Done) {
-			pEntry =
-			    &pAd->MacTab.Content[pAd->BATable.BAOriEntry[i].
-						 Wcid];
-			TID = pAd->BATable.BAOriEntry[i].TID;
-
-			ASSERT(pAd->BATable.BAOriEntry[i].Wcid <
-			       MAX_LEN_OF_MAC_TABLE);
-		}
-		total--;
-	}
-}
-
-void SendRefreshBAR(struct rt_rtmp_adapter *pAd, struct rt_mac_table_entry *pEntry)
-{
-	struct rt_frame_bar FrameBar;
-	unsigned long FrameLen;
-	int NStatus;
-	u8 *pOutBuffer = NULL;
-	u16 Sequence;
-	u8 i, TID;
-	u16 idx;
-	struct rt_ba_ori_entry *pBAEntry;
-
-	for (i = 0; i < NUM_OF_TID; i++) {
-		idx = pEntry->BAOriWcidArray[i];
-		if (idx == 0) {
-			continue;
-		}
-		pBAEntry = &pAd->BATable.BAOriEntry[idx];
-
-		if (pBAEntry->ORI_BA_Status == Originator_Done) {
-			TID = pBAEntry->TID;
-
-			ASSERT(pBAEntry->Wcid < MAX_LEN_OF_MAC_TABLE);
-
-			NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);	/*Get an unused nonpaged memory */
-			if (NStatus != NDIS_STATUS_SUCCESS) {
-				DBGPRINT(RT_DEBUG_ERROR,
-					 ("BA - MlmeADDBAAction() allocate memory failed \n"));
-				return;
-			}
-
-			Sequence = pEntry->TxSeq[TID];
-
-			BarHeaderInit(pAd, &FrameBar, pEntry->Addr,
-				      pAd->CurrentAddress);
-
-			FrameBar.StartingSeq.field.FragNum = 0;	/* make sure sequence not clear in DEL function. */
-			FrameBar.StartingSeq.field.StartSeq = Sequence;	/* make sure sequence not clear in DEL funciton. */
-			FrameBar.BarControl.TID = TID;	/* make sure sequence not clear in DEL funciton. */
-
-			MakeOutgoingFrame(pOutBuffer, &FrameLen,
-					  sizeof(struct rt_frame_bar), &FrameBar,
-					  END_OF_ARGS);
-			/*if (!(CLIENT_STATUS_TEST_FLAG(pEntry, fCLIENT_STATUS_RALINK_CHIPSET))) */
-			if (1)	/* Now we always send BAR. */
-			{
-				/*MiniportMMRequestUnlock(pAd, 0, pOutBuffer, FrameLen); */
-				MiniportMMRequest(pAd,
-						  (MGMT_USE_QUEUE_FLAG |
-						   MapUserPriorityToAccessCategory
-						   [TID]), pOutBuffer,
-						  FrameLen);
-
-			}
-			MlmeFreeMemory(pAd, pOutBuffer);
-		}
-	}
-}
-
-void ActHeaderInit(struct rt_rtmp_adapter *pAd,
-		   struct rt_header_802_11 * pHdr80211,
-		   u8 *Addr1, u8 *Addr2, u8 *Addr3)
-{
-	NdisZeroMemory(pHdr80211, sizeof(struct rt_header_802_11));
-	pHdr80211->FC.Type = BTYPE_MGMT;
-	pHdr80211->FC.SubType = SUBTYPE_ACTION;
-
-	COPY_MAC_ADDR(pHdr80211->Addr1, Addr1);
-	COPY_MAC_ADDR(pHdr80211->Addr2, Addr2);
-	COPY_MAC_ADDR(pHdr80211->Addr3, Addr3);
-}
-
-void BarHeaderInit(struct rt_rtmp_adapter *pAd,
-		   struct rt_frame_bar * pCntlBar, u8 *pDA, u8 *pSA)
-{
-	NdisZeroMemory(pCntlBar, sizeof(struct rt_frame_bar));
-	pCntlBar->FC.Type = BTYPE_CNTL;
-	pCntlBar->FC.SubType = SUBTYPE_BLOCK_ACK_REQ;
-	pCntlBar->BarControl.MTID = 0;
-	pCntlBar->BarControl.Compressed = 1;
-	pCntlBar->BarControl.ACKPolicy = 0;
-
-	pCntlBar->Duration =
-	    16 + RTMPCalcDuration(pAd, RATE_1, sizeof(struct rt_frame_ba));
-
-	COPY_MAC_ADDR(pCntlBar->Addr1, pDA);
-	COPY_MAC_ADDR(pCntlBar->Addr2, pSA);
-}
-
-/*
-	==========================================================================
-	Description:
-		Insert Category and action code into the action frame.
-
-	Parametrs:
-		1. frame buffer pointer.
-		2. frame length.
-		3. category code of the frame.
-		4. action code of the frame.
-
-	Return	: None.
-	==========================================================================
- */
-void InsertActField(struct rt_rtmp_adapter *pAd,
-		    u8 *pFrameBuf,
-		    unsigned long *pFrameLen, u8 Category, u8 ActCode)
-{
-	unsigned long TempLen;
-
-	MakeOutgoingFrame(pFrameBuf, &TempLen,
-			  1, &Category, 1, &ActCode, END_OF_ARGS);
-
-	*pFrameLen = *pFrameLen + TempLen;
-
-	return;
-}
diff -druN linux-2.6.39-libre/drivers/staging/rt2860/common/action.h linux-3.0-rc7-libre/drivers/staging/rt2860/common/action.h
--- linux-2.6.39-libre/drivers/staging/rt2860/common/action.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rt2860/common/action.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,56 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, 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.             *
- *                                                                       *
- *************************************************************************
-
-	Module Name:
-	aironet.h
-
-	Abstract:
-
-	Revision History:
-	Who			When			What
-	--------	----------		----------------------------------------------
-	Name		Date			Modification logs
-	Paul Lin	04-06-15		Initial
-*/
-
-#ifndef	__ACTION_H__
-#define	__ACTION_H__
-
-struct PACKED rt_ht_information_octet {
-	u8 Request:1;
-	u8 Forty_MHz_Intolerant:1;
-	u8 STA_Channel_Width:1;
-	u8 Reserved:5;
-};
-
-struct PACKED rt_frame_ht_info {
-	struct rt_header_802_11 Hdr;
-	u8 Category;
-	u8 Action;
-	struct rt_ht_information_octet HT_Info;
-};
-
-#endif /* __ACTION_H__ */
diff -druN linux-2.6.39-libre/drivers/staging/rt2860/common/ba_action.c linux-3.0-rc7-libre/drivers/staging/rt2860/common/ba_action.c
--- linux-2.6.39-libre/drivers/staging/rt2860/common/ba_action.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rt2860/common/ba_action.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,1650 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, Inc.
- *
- * This program is free software; you can redistribute it and/or modify  *
- * it under the terms of the GNU General Public License as published by  *
- * the Free Software Foundation; either version 2 of the License, or     *
- * (at your option) any later version.                                   *
- *                                                                       *
- * This program is distributed in the hope that it will be useful,       *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of        *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
- * GNU General Public License for more details.                          *
- *                                                                       *
- * You should have received a copy of the GNU General Public License     *
- * along with this program; if not, write to the                         *
- * Free Software Foundation, Inc.,                                       *
- * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
- *                                                                       *
- *************************************************************************
- */
-
-#include "../rt_config.h"
-#include <linux/kernel.h>
-
-#define BA_ORI_INIT_SEQ		(pEntry->TxSeq[TID])	/*1                        // initial sequence number of BA session */
-
-#define ORI_SESSION_MAX_RETRY	8
-#define ORI_BA_SESSION_TIMEOUT	(2000)	/* ms */
-#define REC_BA_SESSION_IDLE_TIMEOUT	(1000)	/* ms */
-
-#define REORDERING_PACKET_TIMEOUT		((100 * OS_HZ)/1000)	/* system ticks -- 100 ms */
-#define MAX_REORDERING_PACKET_TIMEOUT	((3000 * OS_HZ)/1000)	/* system ticks -- 100 ms */
-
-#define RESET_RCV_SEQ		(0xFFFF)
-
-static void ba_mpdu_blk_free(struct rt_rtmp_adapter *pAd,
-			     struct reordering_mpdu *mpdu_blk);
-
-struct rt_ba_ori_entry *BATableAllocOriEntry(struct rt_rtmp_adapter *pAd, u16 * Idx);
-
-struct rt_ba_rec_entry *BATableAllocRecEntry(struct rt_rtmp_adapter *pAd, u16 * Idx);
-
-void BAOriSessionSetupTimeout(void *SystemSpecific1,
-			      void *FunctionContext,
-			      void *SystemSpecific2,
-			      void *SystemSpecific3);
-
-void BARecSessionIdleTimeout(void *SystemSpecific1,
-			     void *FunctionContext,
-			     void *SystemSpecific2,
-			     void *SystemSpecific3);
-
-BUILD_TIMER_FUNCTION(BAOriSessionSetupTimeout);
-BUILD_TIMER_FUNCTION(BARecSessionIdleTimeout);
-
-#define ANNOUNCE_REORDERING_PACKET(_pAd, _mpdu_blk)	\
-			Announce_Reordering_Packet(_pAd, _mpdu_blk);
-
-void BA_MaxWinSizeReasign(struct rt_rtmp_adapter *pAd,
-			  struct rt_mac_table_entry *pEntryPeer, u8 * pWinSize)
-{
-	u8 MaxSize;
-
-	if (pAd->MACVersion >= RALINK_2883_VERSION)	/* 3*3 */
-	{
-		if (pAd->MACVersion >= RALINK_3070_VERSION) {
-			if (pEntryPeer->WepStatus !=
-			    Ndis802_11EncryptionDisabled)
-				MaxSize = 7;	/* for non-open mode */
-			else
-				MaxSize = 13;
-		} else
-			MaxSize = 31;
-	} else if (pAd->MACVersion >= RALINK_2880E_VERSION)	/* 2880 e */
-	{
-		if (pEntryPeer->WepStatus != Ndis802_11EncryptionDisabled)
-			MaxSize = 7;	/* for non-open mode */
-		else
-			MaxSize = 13;
-	} else
-		MaxSize = 7;
-
-	DBGPRINT(RT_DEBUG_TRACE, ("ba> Win Size = %d, Max Size = %d\n",
-				  *pWinSize, MaxSize));
-
-	if ((*pWinSize) > MaxSize) {
-		DBGPRINT(RT_DEBUG_TRACE,
-			 ("ba> reassign max win size from %d to %d\n",
-			  *pWinSize, MaxSize));
-
-		*pWinSize = MaxSize;
-	}
-}
-
-void Announce_Reordering_Packet(struct rt_rtmp_adapter *pAd,
-				IN struct reordering_mpdu *mpdu)
-{
-	void *pPacket;
-
-	pPacket = mpdu->pPacket;
-
-	if (mpdu->bAMSDU) {
-		ASSERT(0);
-		BA_Reorder_AMSDU_Announce(pAd, pPacket);
-	} else {
-		/* */
-		/* pass this 802.3 packet to upper layer or forward this packet to WM directly */
-		/* */
-
-		ANNOUNCE_OR_FORWARD_802_3_PACKET(pAd, pPacket,
-						 RTMP_GET_PACKET_IF(pPacket));
-	}
-}
-
-/*
- * Insert a reordering mpdu into sorted linked list by sequence no.
- */
-BOOLEAN ba_reordering_mpdu_insertsorted(struct reordering_list *list,
-					struct reordering_mpdu *mpdu)
-{
-
-	struct reordering_mpdu **ppScan = &list->next;
-
-	while (*ppScan != NULL) {
-		if (SEQ_SMALLER((*ppScan)->Sequence, mpdu->Sequence, MAXSEQ)) {
-			ppScan = &(*ppScan)->next;
-		} else if ((*ppScan)->Sequence == mpdu->Sequence) {
-			/* give up this duplicated frame */
-			return (FALSE);
-		} else {
-			/* find position */
-			break;
-		}
-	}
-
-	mpdu->next = *ppScan;
-	*ppScan = mpdu;
-	list->qlen++;
-	return TRUE;
-}
-
-/*
- * caller lock critical section if necessary
- */
-static inline void ba_enqueue(struct reordering_list *list,
-			      struct reordering_mpdu *mpdu_blk)
-{
-	list->qlen++;
-	mpdu_blk->next = list->next;
-	list->next = mpdu_blk;
-}
-
-/*
- * caller lock critical section if necessary
- */
-static inline struct reordering_mpdu *ba_dequeue(struct reordering_list *list)
-{
-	struct reordering_mpdu *mpdu_blk = NULL;
-
-	ASSERT(list);
-
-	if (list->qlen) {
-		list->qlen--;
-		mpdu_blk = list->next;
-		if (mpdu_blk) {
-			list->next = mpdu_blk->next;
-			mpdu_blk->next = NULL;
-		}
-	}
-	return mpdu_blk;
-}
-
-static inline struct reordering_mpdu *ba_reordering_mpdu_dequeue(struct
-								 reordering_list
-								 *list)
-{
-	return (ba_dequeue(list));
-}
-
-static inline struct reordering_mpdu *ba_reordering_mpdu_probe(struct
-							       reordering_list
-							       *list)
-{
-	ASSERT(list);
-
-	return (list->next);
-}
-
-/*
- * free all resource for reordering mechanism
- */
-void ba_reordering_resource_release(struct rt_rtmp_adapter *pAd)
-{
-	struct rt_ba_table *Tab;
-	struct rt_ba_rec_entry *pBAEntry;
-	struct reordering_mpdu *mpdu_blk;
-	int i;
-
-	Tab = &pAd->BATable;
-
-	/* I.  release all pending reordering packet */
-	NdisAcquireSpinLock(&pAd->BATabLock);
-	for (i = 0; i < MAX_LEN_OF_BA_REC_TABLE; i++) {
-		pBAEntry = &Tab->BARecEntry[i];
-		if (pBAEntry->REC_BA_Status != Recipient_NONE) {
-			while ((mpdu_blk =
-				ba_reordering_mpdu_dequeue(&pBAEntry->list))) {
-				ASSERT(mpdu_blk->pPacket);
-				RELEASE_NDIS_PACKET(pAd, mpdu_blk->pPacket,
-						    NDIS_STATUS_FAILURE);
-				ba_mpdu_blk_free(pAd, mpdu_blk);
-			}
-		}
-	}
-	NdisReleaseSpinLock(&pAd->BATabLock);
-
-	ASSERT(pBAEntry->list.qlen == 0);
-	/* II. free memory of reordering mpdu table */
-	NdisAcquireSpinLock(&pAd->mpdu_blk_pool.lock);
-	os_free_mem(pAd, pAd->mpdu_blk_pool.mem);
-	NdisReleaseSpinLock(&pAd->mpdu_blk_pool.lock);
-}
-
-/*
- * Allocate all resource for reordering mechanism
- */
-BOOLEAN ba_reordering_resource_init(struct rt_rtmp_adapter *pAd, int num)
-{
-	int i;
-	u8 *mem;
-	struct reordering_mpdu *mpdu_blk;
-	struct reordering_list *freelist;
-
-	/* allocate spinlock */
-	NdisAllocateSpinLock(&pAd->mpdu_blk_pool.lock);
-
-	/* initialize freelist */
-	freelist = &pAd->mpdu_blk_pool.freelist;
-	freelist->next = NULL;
-	freelist->qlen = 0;
-
-	DBGPRINT(RT_DEBUG_TRACE,
-		 ("Allocate %d memory for BA reordering\n",
-		  (u32)(num * sizeof(struct reordering_mpdu))));
-
-	/* allocate number of mpdu_blk memory */
-	os_alloc_mem(pAd, (u8 **) & mem,
-		     (num * sizeof(struct reordering_mpdu)));
-
-	pAd->mpdu_blk_pool.mem = mem;
-
-	if (mem == NULL) {
-		DBGPRINT(RT_DEBUG_ERROR,
-			 ("Can't Allocate Memory for BA Reordering\n"));
-		return (FALSE);
-	}
-
-	/* build mpdu_blk free list */
-	for (i = 0; i < num; i++) {
-		/* get mpdu_blk */
-		mpdu_blk = (struct reordering_mpdu *)mem;
-		/* initial mpdu_blk */
-		NdisZeroMemory(mpdu_blk, sizeof(struct reordering_mpdu));
-		/* next mpdu_blk */
-		mem += sizeof(struct reordering_mpdu);
-		/* insert mpdu_blk into freelist */
-		ba_enqueue(freelist, mpdu_blk);
-	}
-
-	return (TRUE);
-}
-
-/*static int blk_count=0; // sample take off, no use */
-
-static struct reordering_mpdu *ba_mpdu_blk_alloc(struct rt_rtmp_adapter *pAd)
-{
-	struct reordering_mpdu *mpdu_blk;
-
-	NdisAcquireSpinLock(&pAd->mpdu_blk_pool.lock);
-	mpdu_blk = ba_dequeue(&pAd->mpdu_blk_pool.freelist);
-	if (mpdu_blk) {
-/*              blk_count++; */
-		/* reset mpdu_blk */
-		NdisZeroMemory(mpdu_blk, sizeof(struct reordering_mpdu));
-	}
-	NdisReleaseSpinLock(&pAd->mpdu_blk_pool.lock);
-	return mpdu_blk;
-}
-
-static void ba_mpdu_blk_free(struct rt_rtmp_adapter *pAd,
-			     struct reordering_mpdu *mpdu_blk)
-{
-	ASSERT(mpdu_blk);
-
-	NdisAcquireSpinLock(&pAd->mpdu_blk_pool.lock);
-/*      blk_count--; */
-	ba_enqueue(&pAd->mpdu_blk_pool.freelist, mpdu_blk);
-	NdisReleaseSpinLock(&pAd->mpdu_blk_pool.lock);
-}
-
-static u16 ba_indicate_reordering_mpdus_in_order(struct rt_rtmp_adapter *pAd,
-						    struct rt_ba_rec_entry *pBAEntry,
-						    u16 StartSeq)
-{
-	struct reordering_mpdu *mpdu_blk;
-	u16 LastIndSeq = RESET_RCV_SEQ;
-
-	NdisAcquireSpinLock(&pBAEntry->RxReRingLock);
-
-	while ((mpdu_blk = ba_reordering_mpdu_probe(&pBAEntry->list))) {
-		/* find in-order frame */
-		if (!SEQ_STEPONE(mpdu_blk->Sequence, StartSeq, MAXSEQ)) {
-			break;
-		}
-		/* dequeue in-order frame from reodering list */
-		mpdu_blk = ba_reordering_mpdu_dequeue(&pBAEntry->list);
-		/* pass this frame up */
-		ANNOUNCE_REORDERING_PACKET(pAd, mpdu_blk);
-		/* move to next sequence */
-		StartSeq = mpdu_blk->Sequence;
-		LastIndSeq = StartSeq;
-		/* free mpdu_blk */
-		ba_mpdu_blk_free(pAd, mpdu_blk);
-	}
-
-	NdisReleaseSpinLock(&pBAEntry->RxReRingLock);
-
-	/* update last indicated sequence */
-	return LastIndSeq;
-}
-
-static void ba_indicate_reordering_mpdus_le_seq(struct rt_rtmp_adapter *pAd,
-						struct rt_ba_rec_entry *pBAEntry,
-						u16 Sequence)
-{
-	struct reordering_mpdu *mpdu_blk;
-
-	NdisAcquireSpinLock(&pBAEntry->RxReRingLock);
-	while ((mpdu_blk = ba_reordering_mpdu_probe(&pBAEntry->list))) {
-		/* find in-order frame */
-		if ((mpdu_blk->Sequence == Sequence)
-		    || SEQ_SMALLER(mpdu_blk->Sequence, Sequence, MAXSEQ)) {
-			/* dequeue in-order frame from reodering list */
-			mpdu_blk = ba_reordering_mpdu_dequeue(&pBAEntry->list);
-			/* pass this frame up */
-			ANNOUNCE_REORDERING_PACKET(pAd, mpdu_blk);
-			/* free mpdu_blk */
-			ba_mpdu_blk_free(pAd, mpdu_blk);
-		} else {
-			break;
-		}
-	}
-	NdisReleaseSpinLock(&pBAEntry->RxReRingLock);
-}
-
-static void ba_refresh_reordering_mpdus(struct rt_rtmp_adapter *pAd,
-					struct rt_ba_rec_entry *pBAEntry)
-{
-	struct reordering_mpdu *mpdu_blk;
-
-	NdisAcquireSpinLock(&pBAEntry->RxReRingLock);
-
-	/* dequeue in-order frame from reodering list */
-	while ((mpdu_blk = ba_reordering_mpdu_dequeue(&pBAEntry->list))) {
-		/* pass this frame up */
-		ANNOUNCE_REORDERING_PACKET(pAd, mpdu_blk);
-
-		pBAEntry->LastIndSeq = mpdu_blk->Sequence;
-		ba_mpdu_blk_free(pAd, mpdu_blk);
-
-		/* update last indicated sequence */
-	}
-	ASSERT(pBAEntry->list.qlen == 0);
-	pBAEntry->LastIndSeq = RESET_RCV_SEQ;
-	NdisReleaseSpinLock(&pBAEntry->RxReRingLock);
-}
-
-/*static */
-void ba_flush_reordering_timeout_mpdus(struct rt_rtmp_adapter *pAd,
-				       struct rt_ba_rec_entry *pBAEntry,
-				       unsigned long Now32)
-{
-	u16 Sequence;
-
-/*      if ((RTMP_TIME_AFTER((unsigned long)Now32, (unsigned long)(pBAEntry->LastIndSeqAtTimer+REORDERING_PACKET_TIMEOUT)) && */
-/*               (pBAEntry->list.qlen > ((pBAEntry->BAWinSize*7)/8))) //|| */
-/*              (RTMP_TIME_AFTER((unsigned long)Now32, (unsigned long)(pBAEntry->LastIndSeqAtTimer+(10*REORDERING_PACKET_TIMEOUT))) && */
-/*               (pBAEntry->list.qlen > (pBAEntry->BAWinSize/8))) */
-	if (RTMP_TIME_AFTER
-	    ((unsigned long)Now32,
-	     (unsigned long)(pBAEntry->LastIndSeqAtTimer +
-			     (MAX_REORDERING_PACKET_TIMEOUT / 6)))
-	    && (pBAEntry->list.qlen > 1)
-	    ) {
-		DBGPRINT(RT_DEBUG_TRACE,
-			 ("timeout[%d] (%08lx-%08lx = %d > %d): %x, flush all!\n ",
-			  pBAEntry->list.qlen, Now32,
-			  (pBAEntry->LastIndSeqAtTimer),
-			  (int)((long)Now32 -
-				(long)(pBAEntry->LastIndSeqAtTimer)),
-			  MAX_REORDERING_PACKET_TIMEOUT, pBAEntry->LastIndSeq));
-		ba_refresh_reordering_mpdus(pAd, pBAEntry);
-		pBAEntry->LastIndSeqAtTimer = Now32;
-	} else
-	    if (RTMP_TIME_AFTER
-		((unsigned long)Now32,
-		 (unsigned long)(pBAEntry->LastIndSeqAtTimer +
-				 (REORDERING_PACKET_TIMEOUT)))
-		&& (pBAEntry->list.qlen > 0)
-	    ) {
-		/* */
-		/* force LastIndSeq to shift to LastIndSeq+1 */
-		/* */
-		Sequence = (pBAEntry->LastIndSeq + 1) & MAXSEQ;
-		ba_indicate_reordering_mpdus_le_seq(pAd, pBAEntry, Sequence);
-		pBAEntry->LastIndSeqAtTimer = Now32;
-		pBAEntry->LastIndSeq = Sequence;
-		/* */
-		/* indicate in-order mpdus */
-		/* */
-		Sequence =
-		    ba_indicate_reordering_mpdus_in_order(pAd, pBAEntry,
-							  Sequence);
-		if (Sequence != RESET_RCV_SEQ) {
-			pBAEntry->LastIndSeq = Sequence;
-		}
-
-		DBGPRINT(RT_DEBUG_OFF,
-			 ("%x, flush one!\n", pBAEntry->LastIndSeq));
-
-	}
-}
-
-/*
- * generate ADDBA request to
- * set up BA agreement
- */
-void BAOriSessionSetUp(struct rt_rtmp_adapter *pAd,
-		       struct rt_mac_table_entry *pEntry,
-		       u8 TID,
-		       u16 TimeOut,
-		       unsigned long DelayTime, IN BOOLEAN isForced)
-{
-	/*struct rt_mlme_addba_req AddbaReq; */
-	struct rt_ba_ori_entry *pBAEntry = NULL;
-	u16 Idx;
-	BOOLEAN Cancelled;
-
-	if ((pAd->CommonCfg.BACapability.field.AutoBA != TRUE)
-	    && (isForced == FALSE))
-		return;
-
-	/* if this entry is limited to use legacy tx mode, it doesn't generate BA. */
-	if (RTMPStaFixedTxMode(pAd, pEntry) != FIXED_TXMODE_HT)
-		return;
-
-	if ((pEntry->BADeclineBitmap & (1 << TID)) && (isForced == FALSE)) {
-		/* try again after 3 secs */
-		DelayTime = 3000;
-/*              DBGPRINT(RT_DEBUG_TRACE, ("DeCline BA from Peer\n")); */
-/*              return; */
-	}
-
-	Idx = pEntry->BAOriWcidArray[TID];
-	if (Idx == 0) {
-		/* allocate a BA session */
-		pBAEntry = BATableAllocOriEntry(pAd, &Idx);
-		if (pBAEntry == NULL) {
-			DBGPRINT(RT_DEBUG_TRACE,
-				 ("ADDBA - MlmeADDBAAction() allocate BA session failed \n"));
-			return;
-		}
-	} else {
-		pBAEntry = &pAd->BATable.BAOriEntry[Idx];
-	}
-
-	if (pBAEntry->ORI_BA_Status >= Originator_WaitRes) {
-		return;
-	}
-
-	pEntry->BAOriWcidArray[TID] = Idx;
-
-	/* Initialize BA session */
-	pBAEntry->ORI_BA_Status = Originator_WaitRes;
-	pBAEntry->Wcid = pEntry->Aid;
-	pBAEntry->BAWinSize = pAd->CommonCfg.BACapability.field.RxBAWinLimit;
-	pBAEntry->Sequence = BA_ORI_INIT_SEQ;
-	pBAEntry->Token = 1;	/* (2008-01-21) Jan Lee recommends it - this token can't be 0 */
-	pBAEntry->TID = TID;
-	pBAEntry->TimeOutValue = TimeOut;
-	pBAEntry->pAdapter = pAd;
-
-	if (!(pEntry->TXBAbitmap & (1 << TID))) {
-		RTMPInitTimer(pAd, &pBAEntry->ORIBATimer,
-			      GET_TIMER_FUNCTION(BAOriSessionSetupTimeout),
-			      pBAEntry, FALSE);
-	} else
-		RTMPCancelTimer(&pBAEntry->ORIBATimer, &Cancelled);
-
-	/* set timer to send ADDBA request */
-	RTMPSetTimer(&pBAEntry->ORIBATimer, DelayTime);
-}
-
-void BAOriSessionAdd(struct rt_rtmp_adapter *pAd,
-		     struct rt_mac_table_entry *pEntry, struct rt_frame_addba_rsp * pFrame)
-{
-	struct rt_ba_ori_entry *pBAEntry = NULL;
-	BOOLEAN Cancelled;
-	u8 TID;
-	u16 Idx;
-	u8 *pOutBuffer2 = NULL;
-	int NStatus;
-	unsigned long FrameLen;
-	struct rt_frame_bar FrameBar;
-
-	TID = pFrame->BaParm.TID;
-	Idx = pEntry->BAOriWcidArray[TID];
-	pBAEntry = &pAd->BATable.BAOriEntry[Idx];
-
-	/* Start fill in parameters. */
-	if ((Idx != 0) && (pBAEntry->TID == TID)
-	    && (pBAEntry->ORI_BA_Status == Originator_WaitRes)) {
-		pBAEntry->BAWinSize =
-		    min(pBAEntry->BAWinSize, ((u8)pFrame->BaParm.BufSize));
-		BA_MaxWinSizeReasign(pAd, pEntry, &pBAEntry->BAWinSize);
-
-		pBAEntry->TimeOutValue = pFrame->TimeOutValue;
-		pBAEntry->ORI_BA_Status = Originator_Done;
-		pAd->BATable.numDoneOriginator++;
-
-		/* reset sequence number */
-		pBAEntry->Sequence = BA_ORI_INIT_SEQ;
-		/* Set Bitmap flag. */
-		pEntry->TXBAbitmap |= (1 << TID);
-		RTMPCancelTimer(&pBAEntry->ORIBATimer, &Cancelled);
-
-		pBAEntry->ORIBATimer.TimerValue = 0;	/*pFrame->TimeOutValue; */
-
-		DBGPRINT(RT_DEBUG_TRACE,
-			 ("%s : TXBAbitmap = %x, BAWinSize = %d, TimeOut = %ld\n",
-			  __func__, pEntry->TXBAbitmap, pBAEntry->BAWinSize,
-			  pBAEntry->ORIBATimer.TimerValue));
-
-		/* SEND BAR ; */
-		NStatus = MlmeAllocateMemory(pAd, &pOutBuffer2);	/*Get an unused nonpaged memory */
-		if (NStatus != NDIS_STATUS_SUCCESS) {
-			DBGPRINT(RT_DEBUG_TRACE,
-				 ("BA - BAOriSessionAdd() allocate memory failed \n"));
-			return;
-		}
-
-		BarHeaderInit(pAd, &FrameBar,
-			      pAd->MacTab.Content[pBAEntry->Wcid].Addr,
-			      pAd->CurrentAddress);
-
-		FrameBar.StartingSeq.field.FragNum = 0;	/* make sure sequence not clear in DEL function. */
-		FrameBar.StartingSeq.field.StartSeq = pBAEntry->Sequence;	/* make sure sequence not clear in DEL funciton. */
-		FrameBar.BarControl.TID = pBAEntry->TID;	/* make sure sequence not clear in DEL funciton. */
-		MakeOutgoingFrame(pOutBuffer2, &FrameLen,
-				  sizeof(struct rt_frame_bar), &FrameBar, END_OF_ARGS);
-		MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer2, FrameLen);
-		MlmeFreeMemory(pAd, pOutBuffer2);
-
-		if (pBAEntry->ORIBATimer.TimerValue)
-			RTMPSetTimer(&pBAEntry->ORIBATimer, pBAEntry->ORIBATimer.TimerValue);	/* in mSec */
-	}
-}
-
-BOOLEAN BARecSessionAdd(struct rt_rtmp_adapter *pAd,
-			struct rt_mac_table_entry *pEntry, struct rt_frame_addba_req * pFrame)
-{
-	struct rt_ba_rec_entry *pBAEntry = NULL;
-	BOOLEAN Status = TRUE;
-	BOOLEAN Cancelled;
-	u16 Idx;
-	u8 TID;
-	u8 BAWinSize;
-	/*u32                  Value; */
-	/*u32                    offset; */
-
-	ASSERT(pEntry);
-
-	/* find TID */
-	TID = pFrame->BaParm.TID;
-
-	BAWinSize =
-	    min(((u8)pFrame->BaParm.BufSize),
-		(u8)pAd->CommonCfg.BACapability.field.RxBAWinLimit);
-
-	/* Intel patch */
-	if (BAWinSize == 0) {
-		BAWinSize = 64;
-	}
-
-	Idx = pEntry->BARecWcidArray[TID];
-
-	if (Idx == 0) {
-		pBAEntry = BATableAllocRecEntry(pAd, &Idx);
-	} else {
-		pBAEntry = &pAd->BATable.BARecEntry[Idx];
-		/* flush all pending reordering mpdus */
-		ba_refresh_reordering_mpdus(pAd, pBAEntry);
-	}
-
-	DBGPRINT(RT_DEBUG_TRACE,
-		 ("%s(%ld): Idx = %d, BAWinSize(req %d) = %d\n", __func__,
-		  pAd->BATable.numAsRecipient, Idx, pFrame->BaParm.BufSize,
-		  BAWinSize));
-
-	/* Start fill in parameters. */
-	if (pBAEntry != NULL) {
-		ASSERT(pBAEntry->list.qlen == 0);
-
-		pBAEntry->REC_BA_Status = Recipient_HandleRes;
-		pBAEntry->BAWinSize = BAWinSize;
-		pBAEntry->Wcid = pEntry->Aid;
-		pBAEntry->TID = TID;
-		pBAEntry->TimeOutValue = pFrame->TimeOutValue;
-		pBAEntry->REC_BA_Status = Recipient_Accept;
-		/* initial sequence number */
-		pBAEntry->LastIndSeq = RESET_RCV_SEQ;	/*pFrame->BaStartSeq.field.StartSeq; */
-
-		DBGPRINT(RT_DEBUG_OFF,
-			 ("Start Seq = %08x\n",
-			  pFrame->BaStartSeq.field.StartSeq));
-
-		if (pEntry->RXBAbitmap & (1 << TID)) {
-			RTMPCancelTimer(&pBAEntry->RECBATimer, &Cancelled);
-		} else {
-			RTMPInitTimer(pAd, &pBAEntry->RECBATimer,
-				      GET_TIMER_FUNCTION
-				      (BARecSessionIdleTimeout), pBAEntry,
-				      TRUE);
-		}
-
-		/* Set Bitmap flag. */
-		pEntry->RXBAbitmap |= (1 << TID);
-		pEntry->BARecWcidArray[TID] = Idx;
-
-		pEntry->BADeclineBitmap &= ~(1 << TID);
-
-		/* Set BA session mask in WCID table. */
-		RTMP_ADD_BA_SESSION_TO_ASIC(pAd, pEntry->Aid, TID);
-
-		DBGPRINT(RT_DEBUG_TRACE,
-			 ("MACEntry[%d]RXBAbitmap = 0x%x. BARecWcidArray=%d\n",
-			  pEntry->Aid, pEntry->RXBAbitmap,
-			  pEntry->BARecWcidArray[TID]));
-	} else {
-		Status = FALSE;
-		DBGPRINT(RT_DEBUG_TRACE,
-			("Can't Accept ADDBA for %pM TID = %d\n",
-				pEntry->Addr, TID));
-	}
-	return (Status);
-}
-
-struct rt_ba_rec_entry *BATableAllocRecEntry(struct rt_rtmp_adapter *pAd, u16 * Idx)
-{
-	int i;
-	struct rt_ba_rec_entry *pBAEntry = NULL;
-
-	NdisAcquireSpinLock(&pAd->BATabLock);
-
-	if (pAd->BATable.numAsRecipient >= MAX_BARECI_SESSION) {
-		DBGPRINT(RT_DEBUG_OFF, ("BA Recipeint Session (%ld) > %d\n",
-					pAd->BATable.numAsRecipient,
-					MAX_BARECI_SESSION));
-		goto done;
-	}
-	/* reserve idx 0 to identify BAWcidArray[TID] as empty */
-	for (i = 1; i < MAX_LEN_OF_BA_REC_TABLE; i++) {
-		pBAEntry = &pAd->BATable.BARecEntry[i];
-		if ((pBAEntry->REC_BA_Status == Recipient_NONE)) {
-			/* get one */
-			pAd->BATable.numAsRecipient++;
-			pBAEntry->REC_BA_Status = Recipient_USED;
-			*Idx = i;
-			break;
-		}
-	}
-
-done:
-	NdisReleaseSpinLock(&pAd->BATabLock);
-	return pBAEntry;
-}
-
-struct rt_ba_ori_entry *BATableAllocOriEntry(struct rt_rtmp_adapter *pAd, u16 * Idx)
-{
-	int i;
-	struct rt_ba_ori_entry *pBAEntry = NULL;
-
-	NdisAcquireSpinLock(&pAd->BATabLock);
-
-	if (pAd->BATable.numAsOriginator >= (MAX_LEN_OF_BA_ORI_TABLE)) {
-		goto done;
-	}
-	/* reserve idx 0 to identify BAWcidArray[TID] as empty */
-	for (i = 1; i < MAX_LEN_OF_BA_ORI_TABLE; i++) {
-		pBAEntry = &pAd->BATable.BAOriEntry[i];
-		if ((pBAEntry->ORI_BA_Status == Originator_NONE)) {
-			/* get one */
-			pAd->BATable.numAsOriginator++;
-			pBAEntry->ORI_BA_Status = Originator_USED;
-			pBAEntry->pAdapter = pAd;
-			*Idx = i;
-			break;
-		}
-	}
-
-done:
-	NdisReleaseSpinLock(&pAd->BATabLock);
-	return pBAEntry;
-}
-
-void BATableFreeOriEntry(struct rt_rtmp_adapter *pAd, unsigned long Idx)
-{
-	struct rt_ba_ori_entry *pBAEntry = NULL;
-	struct rt_mac_table_entry *pEntry;
-
-	if ((Idx == 0) || (Idx >= MAX_LEN_OF_BA_ORI_TABLE))
-		return;
-
-	pBAEntry = &pAd->BATable.BAOriEntry[Idx];
-
-	if (pBAEntry->ORI_BA_Status != Originator_NONE) {
-		pEntry = &pAd->MacTab.Content[pBAEntry->Wcid];
-		pEntry->BAOriWcidArray[pBAEntry->TID] = 0;
-
-		NdisAcquireSpinLock(&pAd->BATabLock);
-		if (pBAEntry->ORI_BA_Status == Originator_Done) {
-			pAd->BATable.numDoneOriginator -= 1;
-			pEntry->TXBAbitmap &= (~(1 << (pBAEntry->TID)));
-			DBGPRINT(RT_DEBUG_TRACE,
-				 ("BATableFreeOriEntry numAsOriginator= %ld\n",
-				  pAd->BATable.numAsRecipient));
-			/* Erase Bitmap flag. */
-		}
-
-		ASSERT(pAd->BATable.numAsOriginator != 0);
-
-		pAd->BATable.numAsOriginator -= 1;
-
-		pBAEntry->ORI_BA_Status = Originator_NONE;
-		pBAEntry->Token = 0;
-		NdisReleaseSpinLock(&pAd->BATabLock);
-	}
-}
-
-void BATableFreeRecEntry(struct rt_rtmp_adapter *pAd, unsigned long Idx)
-{
-	struct rt_ba_rec_entry *pBAEntry = NULL;
-	struct rt_mac_table_entry *pEntry;
-
-	if ((Idx == 0) || (Idx >= MAX_LEN_OF_BA_REC_TABLE))
-		return;
-
-	pBAEntry = &pAd->BATable.BARecEntry[Idx];
-
-	if (pBAEntry->REC_BA_Status != Recipient_NONE) {
-		pEntry = &pAd->MacTab.Content[pBAEntry->Wcid];
-		pEntry->BARecWcidArray[pBAEntry->TID] = 0;
-
-		NdisAcquireSpinLock(&pAd->BATabLock);
-
-		ASSERT(pAd->BATable.numAsRecipient != 0);
-
-		pAd->BATable.numAsRecipient -= 1;
-
-		pBAEntry->REC_BA_Status = Recipient_NONE;
-		NdisReleaseSpinLock(&pAd->BATabLock);
-	}
-}
-
-void BAOriSessionTearDown(struct rt_rtmp_adapter *pAd,
-			  u8 Wcid,
-			  u8 TID,
-			  IN BOOLEAN bPassive, IN BOOLEAN bForceSend)
-{
-	unsigned long Idx = 0;
-	struct rt_ba_ori_entry *pBAEntry;
-	BOOLEAN Cancelled;
-
-	if (Wcid >= MAX_LEN_OF_MAC_TABLE) {
-		return;
-	}
-	/* */
-	/* Locate corresponding BA Originator Entry in BA Table with the (pAddr,TID). */
-	/* */
-	Idx = pAd->MacTab.Content[Wcid].BAOriWcidArray[TID];
-	if ((Idx == 0) || (Idx >= MAX_LEN_OF_BA_ORI_TABLE)) {
-		if (bForceSend == TRUE) {
-			/* force send specified TID DelBA */
-			struct rt_mlme_delba_req DelbaReq;
-			struct rt_mlme_queue_elem *Elem =
-				kmalloc(sizeof(struct rt_mlme_queue_elem),
-					MEM_ALLOC_FLAG);
-			if (Elem != NULL) {
-				NdisZeroMemory(&DelbaReq, sizeof(DelbaReq));
-				NdisZeroMemory(Elem, sizeof(struct rt_mlme_queue_elem));
-
-				COPY_MAC_ADDR(DelbaReq.Addr,
-					      pAd->MacTab.Content[Wcid].Addr);
-				DelbaReq.Wcid = Wcid;
-				DelbaReq.TID = TID;
-				DelbaReq.Initiator = ORIGINATOR;
-				Elem->MsgLen = sizeof(DelbaReq);
-				NdisMoveMemory(Elem->Msg, &DelbaReq,
-					       sizeof(DelbaReq));
-				MlmeDELBAAction(pAd, Elem);
-				kfree(Elem);
-			} else {
-				DBGPRINT(RT_DEBUG_ERROR,
-					 ("%s(bForceSend):alloc memory failed!\n",
-					  __func__));
-			}
-		}
-
-		return;
-	}
-
-	DBGPRINT(RT_DEBUG_TRACE,
-		 ("%s===>Wcid=%d.TID=%d \n", __func__, Wcid, TID));
-
-	pBAEntry = &pAd->BATable.BAOriEntry[Idx];
-	DBGPRINT(RT_DEBUG_TRACE,
-		 ("\t===>Idx = %ld, Wcid=%d.TID=%d, ORI_BA_Status = %d \n", Idx,
-		  Wcid, TID, pBAEntry->ORI_BA_Status));
-	/* */
-	/* Prepare DelBA action frame and send to the peer. */
-	/* */
-	if ((bPassive == FALSE) && (TID == pBAEntry->TID)
-	    && (pBAEntry->ORI_BA_Status == Originator_Done)) {
-		struct rt_mlme_delba_req DelbaReq;
-		struct rt_mlme_queue_elem *Elem =
-			kmalloc(sizeof(struct rt_mlme_queue_elem),
-				MEM_ALLOC_FLAG);
-		if (Elem != NULL) {
-			NdisZeroMemory(&DelbaReq, sizeof(DelbaReq));
-			NdisZeroMemory(Elem, sizeof(struct rt_mlme_queue_elem));
-
-			COPY_MAC_ADDR(DelbaReq.Addr,
-				      pAd->MacTab.Content[Wcid].Addr);
-			DelbaReq.Wcid = Wcid;
-			DelbaReq.TID = pBAEntry->TID;
-			DelbaReq.Initiator = ORIGINATOR;
-			Elem->MsgLen = sizeof(DelbaReq);
-			NdisMoveMemory(Elem->Msg, &DelbaReq, sizeof(DelbaReq));
-			MlmeDELBAAction(pAd, Elem);
-			kfree(Elem);
-		} else {
-			DBGPRINT(RT_DEBUG_ERROR,
-				 ("%s():alloc memory failed!\n", __func__));
-			return;
-		}
-	}
-	RTMPCancelTimer(&pBAEntry->ORIBATimer, &Cancelled);
-	BATableFreeOriEntry(pAd, Idx);
-
-	if (bPassive) {
-		/*BAOriSessionSetUp(pAd, &pAd->MacTab.Content[Wcid], TID, 0, 10000, TRUE); */
-	}
-}
-
-void BARecSessionTearDown(struct rt_rtmp_adapter *pAd,
-			  u8 Wcid, u8 TID, IN BOOLEAN bPassive)
-{
-	unsigned long Idx = 0;
-	struct rt_ba_rec_entry *pBAEntry;
-
-	if (Wcid >= MAX_LEN_OF_MAC_TABLE) {
-		return;
-	}
-	/* */
-	/*  Locate corresponding BA Originator Entry in BA Table with the (pAddr,TID). */
-	/* */
-	Idx = pAd->MacTab.Content[Wcid].BARecWcidArray[TID];
-	if (Idx == 0)
-		return;
-
-	DBGPRINT(RT_DEBUG_TRACE,
-		 ("%s===>Wcid=%d.TID=%d \n", __func__, Wcid, TID));
-
-	pBAEntry = &pAd->BATable.BARecEntry[Idx];
-	DBGPRINT(RT_DEBUG_TRACE,
-		 ("\t===>Idx = %ld, Wcid=%d.TID=%d, REC_BA_Status = %d \n", Idx,
-		  Wcid, TID, pBAEntry->REC_BA_Status));
-	/* */
-	/* Prepare DelBA action frame and send to the peer. */
-	/* */
-	if ((TID == pBAEntry->TID)
-	    && (pBAEntry->REC_BA_Status == Recipient_Accept)) {
-		struct rt_mlme_delba_req DelbaReq;
-		BOOLEAN Cancelled;
-		/*unsigned long   offset; */
-		/*u32  VALUE; */
-
-		RTMPCancelTimer(&pBAEntry->RECBATimer, &Cancelled);
-
-		/* */
-		/* 1. Send DELBA Action Frame */
-		/* */
-		if (bPassive == FALSE) {
-			struct rt_mlme_queue_elem *Elem =
-				kmalloc(sizeof(struct rt_mlme_queue_elem),
-					MEM_ALLOC_FLAG);
-			if (Elem != NULL) {
-				NdisZeroMemory(&DelbaReq, sizeof(DelbaReq));
-				NdisZeroMemory(Elem, sizeof(struct rt_mlme_queue_elem));
-
-				COPY_MAC_ADDR(DelbaReq.Addr,
-					      pAd->MacTab.Content[Wcid].Addr);
-				DelbaReq.Wcid = Wcid;
-				DelbaReq.TID = TID;
-				DelbaReq.Initiator = RECIPIENT;
-				Elem->MsgLen = sizeof(DelbaReq);
-				NdisMoveMemory(Elem->Msg, &DelbaReq,
-					       sizeof(DelbaReq));
-				MlmeDELBAAction(pAd, Elem);
-				kfree(Elem);
-			} else {
-				DBGPRINT(RT_DEBUG_ERROR,
-					 ("%s():alloc memory failed!\n",
-					  __func__));
-				return;
-			}
-		}
-
-		/* */
-		/* 2. Free resource of BA session */
-		/* */
-		/* flush all pending reordering mpdus */
-		ba_refresh_reordering_mpdus(pAd, pBAEntry);
-
-		NdisAcquireSpinLock(&pAd->BATabLock);
-
-		/* Erase Bitmap flag. */
-		pBAEntry->LastIndSeq = RESET_RCV_SEQ;
-		pBAEntry->BAWinSize = 0;
-		/* Erase Bitmap flag at software mactable */
-		pAd->MacTab.Content[Wcid].RXBAbitmap &=
-		    (~(1 << (pBAEntry->TID)));
-		pAd->MacTab.Content[Wcid].BARecWcidArray[TID] = 0;
-
-		RTMP_DEL_BA_SESSION_FROM_ASIC(pAd, Wcid, TID);
-
-		NdisReleaseSpinLock(&pAd->BATabLock);
-
-	}
-
-	BATableFreeRecEntry(pAd, Idx);
-}
-
-void BASessionTearDownALL(struct rt_rtmp_adapter *pAd, u8 Wcid)
-{
-	int i;
-
-	for (i = 0; i < NUM_OF_TID; i++) {
-		BAOriSessionTearDown(pAd, Wcid, i, FALSE, FALSE);
-		BARecSessionTearDown(pAd, Wcid, i, FALSE);
-	}
-}
-
-/*
-	==========================================================================
-	Description:
-		Retry sending ADDBA Reqest.
-
-	IRQL = DISPATCH_LEVEL
-
-	Parametrs:
-	p8023Header: if this is already 802.3 format, p8023Header is NULL
-
-	Return	: TRUE if put into rx reordering buffer, shouldn't indicaterxhere.
-				FALSE , then continue indicaterx at this moment.
-	==========================================================================
- */
-void BAOriSessionSetupTimeout(void *SystemSpecific1,
-			      void *FunctionContext,
-			      void *SystemSpecific2,
-			      void *SystemSpecific3)
-{
-	struct rt_ba_ori_entry *pBAEntry = (struct rt_ba_ori_entry *)FunctionContext;
-	struct rt_mac_table_entry *pEntry;
-	struct rt_rtmp_adapter *pAd;
-
-	if (pBAEntry == NULL)
-		return;
-
-	pAd = pBAEntry->pAdapter;
-
-	{
-		/* Do nothing if monitor mode is on */
-		if (MONITOR_ON(pAd))
-			return;
-	}
-
-	pEntry = &pAd->MacTab.Content[pBAEntry->Wcid];
-
-	if ((pBAEntry->ORI_BA_Status == Originator_WaitRes)
-	    && (pBAEntry->Token < ORI_SESSION_MAX_RETRY)) {
-		struct rt_mlme_addba_req AddbaReq;
-
-		NdisZeroMemory(&AddbaReq, sizeof(AddbaReq));
-		COPY_MAC_ADDR(AddbaReq.pAddr, pEntry->Addr);
-		AddbaReq.Wcid = (u8)(pEntry->Aid);
-		AddbaReq.TID = pBAEntry->TID;
-		AddbaReq.BaBufSize =
-		    pAd->CommonCfg.BACapability.field.RxBAWinLimit;
-		AddbaReq.TimeOutValue = 0;
-		AddbaReq.Token = pBAEntry->Token;
-		MlmeEnqueue(pAd, ACTION_STATE_MACHINE, MT2_MLME_ADD_BA_CATE,
-			    sizeof(struct rt_mlme_addba_req), (void *)& AddbaReq);
-		RTMP_MLME_HANDLER(pAd);
-		DBGPRINT(RT_DEBUG_TRACE,
-			 ("BA Ori Session Timeout(%d) : Send ADD BA again\n",
-			  pBAEntry->Token));
-
-		pBAEntry->Token++;
-		RTMPSetTimer(&pBAEntry->ORIBATimer, ORI_BA_SESSION_TIMEOUT);
-	} else {
-		BATableFreeOriEntry(pAd, pEntry->BAOriWcidArray[pBAEntry->TID]);
-	}
-}
-
-/*
-	==========================================================================
-	Description:
-		Retry sending ADDBA Reqest.
-
-	IRQL = DISPATCH_LEVEL
-
-	Parametrs:
-	p8023Header: if this is already 802.3 format, p8023Header is NULL
-
-	Return	: TRUE if put into rx reordering buffer, shouldn't indicaterxhere.
-				FALSE , then continue indicaterx at this moment.
-	==========================================================================
- */
-void BARecSessionIdleTimeout(void *SystemSpecific1,
-			     void *FunctionContext,
-			     void *SystemSpecific2, void *SystemSpecific3)
-{
-
-	struct rt_ba_rec_entry *pBAEntry = (struct rt_ba_rec_entry *)FunctionContext;
-	struct rt_rtmp_adapter *pAd;
-	unsigned long Now32;
-
-	if (pBAEntry == NULL)
-		return;
-
-	if ((pBAEntry->REC_BA_Status == Recipient_Accept)) {
-		NdisGetSystemUpTime(&Now32);
-
-		if (RTMP_TIME_AFTER
-		    ((unsigned long)Now32,
-		     (unsigned long)(pBAEntry->LastIndSeqAtTimer +
-				     REC_BA_SESSION_IDLE_TIMEOUT))) {
-			pAd = pBAEntry->pAdapter;
-			/* flush all pending reordering mpdus */
-			ba_refresh_reordering_mpdus(pAd, pBAEntry);
-			DBGPRINT(RT_DEBUG_OFF,
-				 ("%ld: REC BA session Timeout\n", Now32));
-		}
-	}
-}
-
-void PeerAddBAReqAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
-{
-	/*      7.4.4.1 */
-	/*unsigned long Idx; */
-	u8 Status = 1;
-	u8 pAddr[6];
-	struct rt_frame_addba_rsp ADDframe;
-	u8 *pOutBuffer = NULL;
-	int NStatus;
-	struct rt_frame_addba_req * pAddreqFrame = NULL;
-	/*u8         BufSize; */
-	unsigned long FrameLen;
-	unsigned long *ptemp;
-	struct rt_mac_table_entry *pMacEntry;
-
-	DBGPRINT(RT_DEBUG_TRACE,
-		 ("%s ==> (Wcid = %d)\n", __func__, Elem->Wcid));
-
-	/*hex_dump("AddBAReq", Elem->Msg, Elem->MsgLen); */
-
-	/*ADDBA Request from unknown peer, ignore this. */
-	if (Elem->Wcid >= MAX_LEN_OF_MAC_TABLE)
-		return;
-
-	pMacEntry = &pAd->MacTab.Content[Elem->Wcid];
-	DBGPRINT(RT_DEBUG_TRACE, ("BA - PeerAddBAReqAction----> \n"));
-	ptemp = (unsigned long *)Elem->Msg;
-	/*DBGPRINT_RAW(RT_DEBUG_EMU, ("%08x:: %08x:: %08x:: %08x:: %08x:: %08x:: %08x:: %08x:: %08x\n", *(ptemp), *(ptemp+1), *(ptemp+2), *(ptemp+3), *(ptemp+4), *(ptemp+5), *(ptemp+6), *(ptemp+7), *(ptemp+8))); */
-
-	if (PeerAddBAReqActionSanity(pAd, Elem->Msg, Elem->MsgLen, pAddr)) {
-
-		if ((pAd->CommonCfg.bBADecline == FALSE)
-		    && IS_HT_STA(pMacEntry)) {
-			pAddreqFrame = (struct rt_frame_addba_req *) (&Elem->Msg[0]);
-			DBGPRINT(RT_DEBUG_OFF,
-				 ("Rcv Wcid(%d) AddBAReq\n", Elem->Wcid));
-			if (BARecSessionAdd
-			    (pAd, &pAd->MacTab.Content[Elem->Wcid],
-			     pAddreqFrame))
-				Status = 0;
-			else
-				Status = 38;	/* more parameters have invalid values */
-		} else {
-			Status = 37;	/* the request has been declined. */
-		}
-	}
-
-	if (pAd->MacTab.Content[Elem->Wcid].ValidAsCLI)
-		ASSERT(pAd->MacTab.Content[Elem->Wcid].Sst == SST_ASSOC);
-
-	pAddreqFrame = (struct rt_frame_addba_req *) (&Elem->Msg[0]);
-	/* 2. Always send back ADDBA Response */
-	NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);	/*Get an unused nonpaged memory */
-	if (NStatus != NDIS_STATUS_SUCCESS) {
-		DBGPRINT(RT_DEBUG_TRACE,
-			 ("ACTION - PeerBAAction() allocate memory failed \n"));
-		return;
-	}
-
-	NdisZeroMemory(&ADDframe, sizeof(struct rt_frame_addba_rsp));
-
-	/* 2-1. Prepare ADDBA Response frame. */
-	{
-		if (ADHOC_ON(pAd))
-			ActHeaderInit(pAd, &ADDframe.Hdr, pAddr,
-				      pAd->CurrentAddress,
-				      pAd->CommonCfg.Bssid);
-		else
-			ActHeaderInit(pAd, &ADDframe.Hdr, pAd->CommonCfg.Bssid,
-				      pAd->CurrentAddress, pAddr);
-	}
-
-	ADDframe.Category = CATEGORY_BA;
-	ADDframe.Action = ADDBA_RESP;
-	ADDframe.Token = pAddreqFrame->Token;
-	/* What is the Status code??  need to check. */
-	ADDframe.StatusCode = Status;
-	ADDframe.BaParm.BAPolicy = IMMED_BA;
-	ADDframe.BaParm.AMSDUSupported = 0;
-	ADDframe.BaParm.TID = pAddreqFrame->BaParm.TID;
-	ADDframe.BaParm.BufSize =
-	    min(((u8)pAddreqFrame->BaParm.BufSize),
-		(u8)pAd->CommonCfg.BACapability.field.RxBAWinLimit);
-	if (ADDframe.BaParm.BufSize == 0) {
-		ADDframe.BaParm.BufSize = 64;
-	}
-	ADDframe.TimeOutValue = 0;	/*pAddreqFrame->TimeOutValue; */
-
-	*(u16 *) (&ADDframe.BaParm) =
-	    cpu2le16(*(u16 *) (&ADDframe.BaParm));
-	ADDframe.StatusCode = cpu2le16(ADDframe.StatusCode);
-	ADDframe.TimeOutValue = cpu2le16(ADDframe.TimeOutValue);
-
-	MakeOutgoingFrame(pOutBuffer, &FrameLen,
-			  sizeof(struct rt_frame_addba_rsp), &ADDframe, END_OF_ARGS);
-	MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
-	MlmeFreeMemory(pAd, pOutBuffer);
-
-	DBGPRINT(RT_DEBUG_TRACE,
-		 ("%s(%d): TID(%d), BufSize(%d) <== \n", __func__, Elem->Wcid,
-		  ADDframe.BaParm.TID, ADDframe.BaParm.BufSize));
-}
-
-void PeerAddBARspAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
-{
-	/*u8         Idx, i; */
-	/*u8 *                  pOutBuffer = NULL; */
-	struct rt_frame_addba_rsp * pFrame = NULL;
-	/*struct rt_ba_ori_entry *pBAEntry; */
-
-	/*ADDBA Response from unknown peer, ignore this. */
-	if (Elem->Wcid >= MAX_LEN_OF_MAC_TABLE)
-		return;
-
-	DBGPRINT(RT_DEBUG_TRACE, ("%s ==> Wcid(%d)\n", __func__, Elem->Wcid));
-
-	/*hex_dump("PeerAddBARspAction()", Elem->Msg, Elem->MsgLen); */
-
-	if (PeerAddBARspActionSanity(pAd, Elem->Msg, Elem->MsgLen)) {
-		pFrame = (struct rt_frame_addba_rsp *) (&Elem->Msg[0]);
-
-		DBGPRINT(RT_DEBUG_TRACE,
-			 ("\t\t StatusCode = %d\n", pFrame->StatusCode));
-		switch (pFrame->StatusCode) {
-		case 0:
-			/* I want a BAsession with this peer as an originator. */
-			BAOriSessionAdd(pAd, &pAd->MacTab.Content[Elem->Wcid],
-					pFrame);
-			break;
-		default:
-			/* check status == USED ??? */
-			BAOriSessionTearDown(pAd, Elem->Wcid,
-					     pFrame->BaParm.TID, TRUE, FALSE);
-			break;
-		}
-		/* Rcv Decline StatusCode */
-		if ((pFrame->StatusCode == 37)
-		    || ((pAd->OpMode == OPMODE_STA) && STA_TGN_WIFI_ON(pAd)
-			&& (pFrame->StatusCode != 0))
-		    ) {
-			pAd->MacTab.Content[Elem->Wcid].BADeclineBitmap |=
-			    1 << pFrame->BaParm.TID;
-		}
-	}
-}
-
-void PeerDelBAAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
-{
-	/*u8                         Idx; */
-	/*u8 *                               pOutBuffer = NULL; */
-	struct rt_frame_delba_req * pDelFrame = NULL;
-
-	DBGPRINT(RT_DEBUG_TRACE, ("%s ==>\n", __func__));
-	/*DELBA Request from unknown peer, ignore this. */
-	if (PeerDelBAActionSanity(pAd, Elem->Wcid, Elem->Msg, Elem->MsgLen)) {
-		pDelFrame = (struct rt_frame_delba_req *) (&Elem->Msg[0]);
-		if (pDelFrame->DelbaParm.Initiator == ORIGINATOR) {
-			DBGPRINT(RT_DEBUG_TRACE,
-				 ("BA - PeerDelBAAction----> ORIGINATOR\n"));
-			BARecSessionTearDown(pAd, Elem->Wcid,
-					     pDelFrame->DelbaParm.TID, TRUE);
-		} else {
-			DBGPRINT(RT_DEBUG_TRACE,
-				 ("BA - PeerDelBAAction----> RECIPIENT, Reason = %d\n",
-				  pDelFrame->ReasonCode));
-			/*hex_dump("DelBA Frame", pDelFrame, Elem->MsgLen); */
-			BAOriSessionTearDown(pAd, Elem->Wcid,
-					     pDelFrame->DelbaParm.TID, TRUE,
-					     FALSE);
-		}
-	}
-}
-
-BOOLEAN CntlEnqueueForRecv(struct rt_rtmp_adapter *pAd,
-			   unsigned long Wcid,
-			   unsigned long MsgLen, struct rt_frame_ba_req * pMsg)
-{
-	struct rt_frame_ba_req * pFrame = pMsg;
-	/*PRTMP_REORDERBUF      pBuffer; */
-	/*PRTMP_REORDERBUF      pDmaBuf; */
-	struct rt_ba_rec_entry *pBAEntry;
-	/*BOOLEAN       Result; */
-	unsigned long Idx;
-	/*u8 NumRxPkt; */
-	u8 TID;		/*, i; */
-
-	TID = (u8)pFrame->BARControl.TID;
-
-	DBGPRINT(RT_DEBUG_TRACE,
-		 ("%s(): BAR-Wcid(%ld), Tid (%d)\n", __func__, Wcid, TID));
-	/*hex_dump("BAR", (char *)pFrame, MsgLen); */
-	/* Do nothing if the driver is starting halt state. */
-	/* This might happen when timer already been fired before cancel timer with mlmehalt */
-	if (RTMP_TEST_FLAG
-	    (pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST))
-		return FALSE;
-
-	/* First check the size, it MUST not exceed the mlme queue size */
-	if (MsgLen > MGMT_DMA_BUFFER_SIZE) {
-		DBGPRINT_ERR("CntlEnqueueForRecv: frame too large, size = %ld \n", MsgLen);
-		return FALSE;
-	} else if (MsgLen != sizeof(struct rt_frame_ba_req)) {
-		DBGPRINT_ERR("CntlEnqueueForRecv: BlockAck Request frame length size = %ld incorrect\n", MsgLen);
-		return FALSE;
-	} else if (MsgLen != sizeof(struct rt_frame_ba_req)) {
-		DBGPRINT_ERR("CntlEnqueueForRecv: BlockAck Request frame length size = %ld incorrect\n", MsgLen);
-		return FALSE;
-	}
-
-	if ((Wcid < MAX_LEN_OF_MAC_TABLE) && (TID < 8)) {
-		/* if this receiving packet is from SA that is in our OriEntry. Since WCID <9 has direct mapping. no need search. */
-		Idx = pAd->MacTab.Content[Wcid].BARecWcidArray[TID];
-		pBAEntry = &pAd->BATable.BARecEntry[Idx];
-	} else {
-		return FALSE;
-	}
-
-	DBGPRINT(RT_DEBUG_TRACE,
-		 ("BAR(%ld) : Tid (%d) - %04x:%04x\n", Wcid, TID,
-		  pFrame->BAStartingSeq.field.StartSeq, pBAEntry->LastIndSeq));
-
-	if (SEQ_SMALLER
-	    (pBAEntry->LastIndSeq, pFrame->BAStartingSeq.field.StartSeq,
-	     MAXSEQ)) {
-		/*DBGPRINT(RT_DEBUG_TRACE, ("BAR Seq = %x, LastIndSeq = %x\n", pFrame->BAStartingSeq.field.StartSeq, pBAEntry->LastIndSeq)); */
-		ba_indicate_reordering_mpdus_le_seq(pAd, pBAEntry,
-						    pFrame->BAStartingSeq.field.
-						    StartSeq);
-		pBAEntry->LastIndSeq =
-		    (pFrame->BAStartingSeq.field.StartSeq ==
-		     0) ? MAXSEQ : (pFrame->BAStartingSeq.field.StartSeq - 1);
-	}
-	/*ba_refresh_reordering_mpdus(pAd, pBAEntry); */
-	return TRUE;
-}
-
-/*
-Description : Send PSMP Action frame If PSMP mode switches.
-*/
-void SendPSMPAction(struct rt_rtmp_adapter *pAd, u8 Wcid, u8 Psmp)
-{
-	u8 *pOutBuffer = NULL;
-	int NStatus;
-	/*unsigned long           Idx; */
-	struct rt_frame_psmp_action Frame;
-	unsigned long FrameLen;
-
-	NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);	/*Get an unused nonpaged memory */
-	if (NStatus != NDIS_STATUS_SUCCESS) {
-		DBGPRINT(RT_DEBUG_ERROR,
-			 ("BA - MlmeADDBAAction() allocate memory failed \n"));
-		return;
-	}
-
-	ActHeaderInit(pAd, &Frame.Hdr, pAd->CommonCfg.Bssid,
-		      pAd->CurrentAddress, pAd->MacTab.Content[Wcid].Addr);
-
-	Frame.Category = CATEGORY_HT;
-	Frame.Action = SMPS_ACTION;
-	switch (Psmp) {
-	case MMPS_ENABLE:
-#ifdef RT30xx
-		if (IS_RT30xx(pAd)
-		    && (pAd->Antenna.field.RxPath > 1
-			|| pAd->Antenna.field.TxPath > 1)) {
-			RTMP_ASIC_MMPS_DISABLE(pAd);
-		}
-#endif /* RT30xx // */
-		Frame.Psmp = 0;
-		break;
-	case MMPS_DYNAMIC:
-		Frame.Psmp = 3;
-		break;
-	case MMPS_STATIC:
-#ifdef RT30xx
-		if (IS_RT30xx(pAd)
-		    && (pAd->Antenna.field.RxPath > 1
-			|| pAd->Antenna.field.TxPath > 1)) {
-			RTMP_ASIC_MMPS_ENABLE(pAd);
-		}
-#endif /* RT30xx // */
-		Frame.Psmp = 1;
-		break;
-	}
-	MakeOutgoingFrame(pOutBuffer, &FrameLen,
-			  sizeof(struct rt_frame_psmp_action), &Frame, END_OF_ARGS);
-	MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
-	MlmeFreeMemory(pAd, pOutBuffer);
-	DBGPRINT(RT_DEBUG_ERROR, ("HT - SendPSMPAction( %d )  \n", Frame.Psmp));
-}
-
-#define RADIO_MEASUREMENT_REQUEST_ACTION	0
-
-struct PACKED rt_beacon_request {
-	u8 RegulatoryClass;
-	u8 ChannelNumber;
-	u16 RandomInterval;
-	u16 MeasurementDuration;
-	u8 MeasurementMode;
-	u8 BSSID[MAC_ADDR_LEN];
-	u8 ReportingCondition;
-	u8 Threshold;
-	u8 SSIDIE[2];	/* 2 byte */
-};
-
-struct PACKED rt_measurement_req {
-	u8 ID;
-	u8 Length;
-	u8 Token;
-	u8 RequestMode;
-	u8 Type;
-};
-
-void convert_reordering_packet_to_preAMSDU_or_802_3_packet(struct rt_rtmp_adapter *pAd,
-							   struct rt_rx_blk *pRxBlk,
-							   u8
-							   FromWhichBSSID)
-{
-	void *pRxPkt;
-	u8 Header802_3[LENGTH_802_3];
-
-	/* 1. get 802.3 Header */
-	/* 2. remove LLC */
-	/*              a. pointer pRxBlk->pData to payload */
-	/*      b. modify pRxBlk->DataSize */
-
-	RTMP_802_11_REMOVE_LLC_AND_CONVERT_TO_802_3(pRxBlk, Header802_3);
-
-	ASSERT(pRxBlk->pRxPacket);
-	pRxPkt = RTPKT_TO_OSPKT(pRxBlk->pRxPacket);
-
-	SET_OS_PKT_NETDEV(pRxPkt, get_netdev_from_bssid(pAd, FromWhichBSSID));
-	SET_OS_PKT_DATAPTR(pRxPkt, pRxBlk->pData);
-	SET_OS_PKT_LEN(pRxPkt, pRxBlk->DataSize);
-	SET_OS_PKT_DATATAIL(pRxPkt, pRxBlk->pData, pRxBlk->DataSize);
-
-	/* */
-	/* copy 802.3 header, if necessary */
-	/* */
-	if (!RX_BLK_TEST_FLAG(pRxBlk, fRX_AMSDU)) {
-		{
-#ifdef LINUX
-			NdisMoveMemory(skb_push(pRxPkt, LENGTH_802_3),
-				       Header802_3, LENGTH_802_3);
-#endif
-		}
-	}
-}
-
-#define INDICATE_LEGACY_OR_AMSDU(_pAd, _pRxBlk, _fromWhichBSSID)		\
-	do																	\
-	{																	\
-    	if (RX_BLK_TEST_FLAG(_pRxBlk, fRX_AMSDU))						\
-    	{																\
-    		Indicate_AMSDU_Packet(_pAd, _pRxBlk, _fromWhichBSSID);		\
-    	}																\
-		else if (RX_BLK_TEST_FLAG(_pRxBlk, fRX_EAP))					\
-		{																\
-			Indicate_EAPOL_Packet(_pAd, _pRxBlk, _fromWhichBSSID);		\
-		}																\
-    	else															\
-    	{																\
-    		Indicate_Legacy_Packet(_pAd, _pRxBlk, _fromWhichBSSID);		\
-    	}																\
-	} while (0);
-
-static void ba_enqueue_reordering_packet(struct rt_rtmp_adapter *pAd,
-					 struct rt_ba_rec_entry *pBAEntry,
-					 struct rt_rx_blk *pRxBlk,
-					 u8 FromWhichBSSID)
-{
-	struct reordering_mpdu *mpdu_blk;
-	u16 Sequence = (u16)pRxBlk->pHeader->Sequence;
-
-	mpdu_blk = ba_mpdu_blk_alloc(pAd);
-	if ((mpdu_blk != NULL) && (!RX_BLK_TEST_FLAG(pRxBlk, fRX_EAP))) {
-		/* Write RxD buffer address & allocated buffer length */
-		NdisAcquireSpinLock(&pBAEntry->RxReRingLock);
-
-		mpdu_blk->Sequence = Sequence;
-
-		mpdu_blk->bAMSDU = RX_BLK_TEST_FLAG(pRxBlk, fRX_AMSDU);
-
-		convert_reordering_packet_to_preAMSDU_or_802_3_packet(pAd,
-								      pRxBlk,
-								      FromWhichBSSID);
-
-		STATS_INC_RX_PACKETS(pAd, FromWhichBSSID);
-
-		/* */
-		/* it is necessary for reordering packet to record */
-		/* which BSS it come from */
-		/* */
-		RTMP_SET_PACKET_IF(pRxBlk->pRxPacket, FromWhichBSSID);
-
-		mpdu_blk->pPacket = pRxBlk->pRxPacket;
-
-		if (ba_reordering_mpdu_insertsorted(&pBAEntry->list, mpdu_blk)
-		    == FALSE) {
-			/* had been already within reordering list */
-			/* don't indicate */
-			RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket,
-					    NDIS_STATUS_SUCCESS);
-			ba_mpdu_blk_free(pAd, mpdu_blk);
-		}
-
-		ASSERT((0 <= pBAEntry->list.qlen)
-		       && (pBAEntry->list.qlen <= pBAEntry->BAWinSize));
-		NdisReleaseSpinLock(&pBAEntry->RxReRingLock);
-	} else {
-		DBGPRINT(RT_DEBUG_ERROR,
-			 (" (%d) Can't allocate reordering mpdu blk\n",
-			  pBAEntry->list.qlen));
-
-		/*
-		 * flush all pending reordering mpdus
-		 * and receiving mpdu to upper layer
-		 * make tcp/ip to take care reordering mechanism
-		 */
-		/*ba_refresh_reordering_mpdus(pAd, pBAEntry); */
-		ba_indicate_reordering_mpdus_le_seq(pAd, pBAEntry, Sequence);
-
-		pBAEntry->LastIndSeq = Sequence;
-		INDICATE_LEGACY_OR_AMSDU(pAd, pRxBlk, FromWhichBSSID);
-	}
-}
-
-/*
-	==========================================================================
-	Description:
-		Indicate this packet to upper layer or put it into reordering buffer
-
-	Parametrs:
-		pRxBlk         : carry necessary packet info 802.11 format
-		FromWhichBSSID : the packet received from which BSS
-
-	Return	:
-			  none
-
-	Note    :
-	          the packet queued into reordering buffer need to cover to 802.3 format
-			  or pre_AMSDU format
-	==========================================================================
- */
-
-void Indicate_AMPDU_Packet(struct rt_rtmp_adapter *pAd,
-			   struct rt_rx_blk *pRxBlk, u8 FromWhichBSSID)
-{
-	u16 Idx;
-	struct rt_ba_rec_entry *pBAEntry = NULL;
-	u16 Sequence = pRxBlk->pHeader->Sequence;
-	unsigned long Now32;
-	u8 Wcid = pRxBlk->pRxWI->WirelessCliID;
-	u8 TID = pRxBlk->pRxWI->TID;
-
-	if (!RX_BLK_TEST_FLAG(pRxBlk, fRX_AMSDU)
-	    && (pRxBlk->DataSize > MAX_RX_PKT_LEN)) {
-		/* release packet */
-		RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket,
-				    NDIS_STATUS_FAILURE);
-		return;
-	}
-
-	if (Wcid < MAX_LEN_OF_MAC_TABLE) {
-		Idx = pAd->MacTab.Content[Wcid].BARecWcidArray[TID];
-		if (Idx == 0) {
-			/* Rec BA Session had been torn down */
-			INDICATE_LEGACY_OR_AMSDU(pAd, pRxBlk, FromWhichBSSID);
-			return;
-		}
-		pBAEntry = &pAd->BATable.BARecEntry[Idx];
-	} else {
-		/* impossible ! */
-		ASSERT(0);
-		/* release packet */
-		RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket,
-				    NDIS_STATUS_FAILURE);
-		return;
-	}
-
-	ASSERT(pBAEntry);
-
-	/* update last rx time */
-	NdisGetSystemUpTime(&Now32);
-
-	pBAEntry->rcvSeq = Sequence;
-
-	ba_flush_reordering_timeout_mpdus(pAd, pBAEntry, Now32);
-	pBAEntry->LastIndSeqAtTimer = Now32;
-
-	/* */
-	/* Reset Last Indicate Sequence */
-	/* */
-	if (pBAEntry->LastIndSeq == RESET_RCV_SEQ) {
-		ASSERT((pBAEntry->list.qlen == 0)
-		       && (pBAEntry->list.next == NULL));
-
-		/* reset rcv sequence of BA session */
-		pBAEntry->LastIndSeq = Sequence;
-		pBAEntry->LastIndSeqAtTimer = Now32;
-		INDICATE_LEGACY_OR_AMSDU(pAd, pRxBlk, FromWhichBSSID);
-		return;
-	}
-
-	/* */
-	/* I. Check if in order. */
-	/* */
-	if (SEQ_STEPONE(Sequence, pBAEntry->LastIndSeq, MAXSEQ)) {
-		u16 LastIndSeq;
-
-		pBAEntry->LastIndSeq = Sequence;
-		INDICATE_LEGACY_OR_AMSDU(pAd, pRxBlk, FromWhichBSSID);
-		LastIndSeq =
-		    ba_indicate_reordering_mpdus_in_order(pAd, pBAEntry,
-							  pBAEntry->LastIndSeq);
-		if (LastIndSeq != RESET_RCV_SEQ) {
-			pBAEntry->LastIndSeq = LastIndSeq;
-		}
-		pBAEntry->LastIndSeqAtTimer = Now32;
-	}
-	/* */
-	/* II. Drop Duplicated Packet */
-	/* */
-	else if (Sequence == pBAEntry->LastIndSeq) {
-
-		/* drop and release packet */
-		pBAEntry->nDropPacket++;
-		RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket,
-				    NDIS_STATUS_FAILURE);
-	}
-	/* */
-	/* III. Drop Old Received Packet */
-	/* */
-	else if (SEQ_SMALLER(Sequence, pBAEntry->LastIndSeq, MAXSEQ)) {
-
-		/* drop and release packet */
-		pBAEntry->nDropPacket++;
-		RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket,
-				    NDIS_STATUS_FAILURE);
-	}
-	/* */
-	/* IV. Receive Sequence within Window Size */
-	/* */
-	else if (SEQ_SMALLER
-		 (Sequence,
-		  (((pBAEntry->LastIndSeq + pBAEntry->BAWinSize + 1)) & MAXSEQ),
-		  MAXSEQ)) {
-		ba_enqueue_reordering_packet(pAd, pBAEntry, pRxBlk,
-					     FromWhichBSSID);
-	}
-	/* */
-	/* V. Receive seq surpasses Win(lastseq + nMSDU). So refresh all reorder buffer */
-	/* */
-	else {
-		long WinStartSeq, TmpSeq;
-
-		TmpSeq = Sequence - (pBAEntry->BAWinSize) - 1;
-		if (TmpSeq < 0) {
-			TmpSeq = (MAXSEQ + 1) + TmpSeq;
-		}
-		WinStartSeq = (TmpSeq + 1) & MAXSEQ;
-		ba_indicate_reordering_mpdus_le_seq(pAd, pBAEntry, WinStartSeq);
-		pBAEntry->LastIndSeq = WinStartSeq;	/*TmpSeq; */
-
-		pBAEntry->LastIndSeqAtTimer = Now32;
-
-		ba_enqueue_reordering_packet(pAd, pBAEntry, pRxBlk,
-					     FromWhichBSSID);
-
-		TmpSeq =
-		    ba_indicate_reordering_mpdus_in_order(pAd, pBAEntry,
-							  pBAEntry->LastIndSeq);
-		if (TmpSeq != RESET_RCV_SEQ) {
-			pBAEntry->LastIndSeq = TmpSeq;
-		}
-	}
-}
diff -druN linux-2.6.39-libre/drivers/staging/rt2860/common/cmm_aes.c linux-3.0-rc7-libre/drivers/staging/rt2860/common/cmm_aes.c
--- linux-2.6.39-libre/drivers/staging/rt2860/common/cmm_aes.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rt2860/common/cmm_aes.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,1311 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, 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.             *
- *                                                                       *
- *************************************************************************
-
-	Module Name:
-	cmm_aes.c
-
-	Abstract:
-
-	Revision History:
-	Who			When			What
-	--------	----------		----------------------------------------------
-	Paul Wu		02-25-02		Initial
-*/
-
-#include	"../rt_config.h"
-
-struct aes_context {
-	u32 erk[64];		/* encryption round keys */
-	u32 drk[64];		/* decryption round keys */
-	int nr;			/* number of rounds */
-};
-
-/*****************************/
-/******** SBOX Table *********/
-/*****************************/
-
-u8 SboxTable[256] = {
-	0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5,
-	0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
-	0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0,
-	0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
-	0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc,
-	0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
-	0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a,
-	0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
-	0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0,
-	0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
-	0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b,
-	0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
-	0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85,
-	0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
-	0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5,
-	0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
-	0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17,
-	0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
-	0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88,
-	0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
-	0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c,
-	0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
-	0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9,
-	0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
-	0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6,
-	0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
-	0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e,
-	0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
-	0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94,
-	0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
-	0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68,
-	0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
-};
-
-void xor_32(u8 *a, u8 *b, u8 *out)
-{
-	int i;
-
-	for (i = 0; i < 4; i++) {
-		out[i] = a[i] ^ b[i];
-	}
-}
-
-void xor_128(u8 *a, u8 *b, u8 *out)
-{
-	int i;
-
-	for (i = 0; i < 16; i++) {
-		out[i] = a[i] ^ b[i];
-	}
-}
-
-u8 RTMPCkipSbox(u8 a)
-{
-	return SboxTable[(int)a];
-}
-
-void next_key(u8 *key, int round)
-{
-	u8 rcon;
-	u8 sbox_key[4];
-	u8 rcon_table[12] = {
-		0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80,
-		0x1b, 0x36, 0x36, 0x36
-	};
-
-	sbox_key[0] = RTMPCkipSbox(key[13]);
-	sbox_key[1] = RTMPCkipSbox(key[14]);
-	sbox_key[2] = RTMPCkipSbox(key[15]);
-	sbox_key[3] = RTMPCkipSbox(key[12]);
-
-	rcon = rcon_table[round];
-
-	xor_32(&key[0], sbox_key, &key[0]);
-	key[0] = key[0] ^ rcon;
-
-	xor_32(&key[4], &key[0], &key[4]);
-	xor_32(&key[8], &key[4], &key[8]);
-	xor_32(&key[12], &key[8], &key[12]);
-}
-
-void byte_sub(u8 *in, u8 *out)
-{
-	int i;
-
-	for (i = 0; i < 16; i++) {
-		out[i] = RTMPCkipSbox(in[i]);
-	}
-}
-
-/************************************/
-/* bitwise_xor()                    */
-/* A 128 bit, bitwise exclusive or  */
-/************************************/
-
-void bitwise_xor(unsigned char *ina, unsigned char *inb, unsigned char *out)
-{
-	int i;
-	for (i = 0; i < 16; i++) {
-		out[i] = ina[i] ^ inb[i];
-	}
-}
-
-void shift_row(u8 *in, u8 *out)
-{
-	out[0] = in[0];
-	out[1] = in[5];
-	out[2] = in[10];
-	out[3] = in[15];
-	out[4] = in[4];
-	out[5] = in[9];
-	out[6] = in[14];
-	out[7] = in[3];
-	out[8] = in[8];
-	out[9] = in[13];
-	out[10] = in[2];
-	out[11] = in[7];
-	out[12] = in[12];
-	out[13] = in[1];
-	out[14] = in[6];
-	out[15] = in[11];
-}
-
-void mix_column(u8 *in, u8 *out)
-{
-	int i;
-	u8 add1b[4];
-	u8 add1bf7[4];
-	u8 rotl[4];
-	u8 swap_halfs[4];
-	u8 andf7[4];
-	u8 rotr[4];
-	u8 temp[4];
-	u8 tempb[4];
-
-	for (i = 0; i < 4; i++) {
-		if ((in[i] & 0x80) == 0x80)
-			add1b[i] = 0x1b;
-		else
-			add1b[i] = 0x00;
-	}
-
-	swap_halfs[0] = in[2];	/* Swap halfs */
-	swap_halfs[1] = in[3];
-	swap_halfs[2] = in[0];
-	swap_halfs[3] = in[1];
-
-	rotl[0] = in[3];	/* Rotate left 8 bits */
-	rotl[1] = in[0];
-	rotl[2] = in[1];
-	rotl[3] = in[2];
-
-	andf7[0] = in[0] & 0x7f;
-	andf7[1] = in[1] & 0x7f;
-	andf7[2] = in[2] & 0x7f;
-	andf7[3] = in[3] & 0x7f;
-
-	for (i = 3; i > 0; i--) {	/* logical shift left 1 bit */
-		andf7[i] = andf7[i] << 1;
-		if ((andf7[i - 1] & 0x80) == 0x80) {
-			andf7[i] = (andf7[i] | 0x01);
-		}
-	}
-	andf7[0] = andf7[0] << 1;
-	andf7[0] = andf7[0] & 0xfe;
-
-	xor_32(add1b, andf7, add1bf7);
-
-	xor_32(in, add1bf7, rotr);
-
-	temp[0] = rotr[0];	/* Rotate right 8 bits */
-	rotr[0] = rotr[1];
-	rotr[1] = rotr[2];
-	rotr[2] = rotr[3];
-	rotr[3] = temp[0];
-
-	xor_32(add1bf7, rotr, temp);
-	xor_32(swap_halfs, rotl, tempb);
-	xor_32(temp, tempb, out);
-}
-
-/************************************************/
-/* construct_mic_header1()                      */
-/* Builds the first MIC header block from       */
-/* header fields.                               */
-/************************************************/
-
-void construct_mic_header1(unsigned char *mic_header1,
-			   int header_length, unsigned char *mpdu)
-{
-	mic_header1[0] = (unsigned char)((header_length - 2) / 256);
-	mic_header1[1] = (unsigned char)((header_length - 2) % 256);
-	mic_header1[2] = mpdu[0] & 0xcf;	/* Mute CF poll & CF ack bits */
-	mic_header1[3] = mpdu[1] & 0xc7;	/* Mute retry, more data and pwr mgt bits */
-	mic_header1[4] = mpdu[4];	/* A1 */
-	mic_header1[5] = mpdu[5];
-	mic_header1[6] = mpdu[6];
-	mic_header1[7] = mpdu[7];
-	mic_header1[8] = mpdu[8];
-	mic_header1[9] = mpdu[9];
-	mic_header1[10] = mpdu[10];	/* A2 */
-	mic_header1[11] = mpdu[11];
-	mic_header1[12] = mpdu[12];
-	mic_header1[13] = mpdu[13];
-	mic_header1[14] = mpdu[14];
-	mic_header1[15] = mpdu[15];
-}
-
-/************************************************/
-/* construct_mic_header2()                      */
-/* Builds the last MIC header block from        */
-/* header fields.                               */
-/************************************************/
-
-void construct_mic_header2(unsigned char *mic_header2,
-			   unsigned char *mpdu, int a4_exists, int qc_exists)
-{
-	int i;
-
-	for (i = 0; i < 16; i++)
-		mic_header2[i] = 0x00;
-
-	mic_header2[0] = mpdu[16];	/* A3 */
-	mic_header2[1] = mpdu[17];
-	mic_header2[2] = mpdu[18];
-	mic_header2[3] = mpdu[19];
-	mic_header2[4] = mpdu[20];
-	mic_header2[5] = mpdu[21];
-
-	/* In Sequence Control field, mute sequence numer bits (12-bit) */
-	mic_header2[6] = mpdu[22] & 0x0f;	/* SC */
-	mic_header2[7] = 0x00;	/* mpdu[23]; */
-
-	if ((!qc_exists) && a4_exists) {
-		for (i = 0; i < 6; i++)
-			mic_header2[8 + i] = mpdu[24 + i];	/* A4 */
-
-	}
-
-	if (qc_exists && (!a4_exists)) {
-		mic_header2[8] = mpdu[24] & 0x0f;	/* mute bits 15 - 4 */
-		mic_header2[9] = mpdu[25] & 0x00;
-	}
-
-	if (qc_exists && a4_exists) {
-		for (i = 0; i < 6; i++)
-			mic_header2[8 + i] = mpdu[24 + i];	/* A4 */
-
-		mic_header2[14] = mpdu[30] & 0x0f;
-		mic_header2[15] = mpdu[31] & 0x00;
-	}
-}
-
-/************************************************/
-/* construct_mic_iv()                           */
-/* Builds the MIC IV from header fields and PN  */
-/************************************************/
-
-void construct_mic_iv(unsigned char *mic_iv,
-		      int qc_exists,
-		      int a4_exists,
-		      unsigned char *mpdu,
-		      unsigned int payload_length, unsigned char *pn_vector)
-{
-	int i;
-
-	mic_iv[0] = 0x59;
-	if (qc_exists && a4_exists)
-		mic_iv[1] = mpdu[30] & 0x0f;	/* QoS_TC           */
-	if (qc_exists && !a4_exists)
-		mic_iv[1] = mpdu[24] & 0x0f;	/* mute bits 7-4    */
-	if (!qc_exists)
-		mic_iv[1] = 0x00;
-	for (i = 2; i < 8; i++)
-		mic_iv[i] = mpdu[i + 8];	/* mic_iv[2:7] = A2[0:5] = mpdu[10:15] */
-#ifdef CONSISTENT_PN_ORDER
-	for (i = 8; i < 14; i++)
-		mic_iv[i] = pn_vector[i - 8];	/* mic_iv[8:13] = PN[0:5] */
-#else
-	for (i = 8; i < 14; i++)
-		mic_iv[i] = pn_vector[13 - i];	/* mic_iv[8:13] = PN[5:0] */
-#endif
-	mic_iv[14] = (unsigned char)(payload_length / 256);
-	mic_iv[15] = (unsigned char)(payload_length % 256);
-
-}
-
-/****************************************/
-/* aes128k128d()                        */
-/* Performs a 128 bit AES encrypt with  */
-/* 128 bit data.                        */
-/****************************************/
-void aes128k128d(unsigned char *key, unsigned char *data,
-		 unsigned char *ciphertext)
-{
-	int round;
-	int i;
-	unsigned char intermediatea[16];
-	unsigned char intermediateb[16];
-	unsigned char round_key[16];
-
-	for (i = 0; i < 16; i++)
-		round_key[i] = key[i];
-
-	for (round = 0; round < 11; round++) {
-		if (round == 0) {
-			xor_128(round_key, data, ciphertext);
-			next_key(round_key, round);
-		} else if (round == 10) {
-			byte_sub(ciphertext, intermediatea);
-			shift_row(intermediatea, intermediateb);
-			xor_128(intermediateb, round_key, ciphertext);
-		} else {	/* 1 - 9 */
-
-			byte_sub(ciphertext, intermediatea);
-			shift_row(intermediatea, intermediateb);
-			mix_column(&intermediateb[0], &intermediatea[0]);
-			mix_column(&intermediateb[4], &intermediatea[4]);
-			mix_column(&intermediateb[8], &intermediatea[8]);
-			mix_column(&intermediateb[12], &intermediatea[12]);
-			xor_128(intermediatea, round_key, ciphertext);
-			next_key(round_key, round);
-		}
-	}
-
-}
-
-void construct_ctr_preload(unsigned char *ctr_preload,
-			   int a4_exists,
-			   int qc_exists,
-			   unsigned char *mpdu, unsigned char *pn_vector, int c)
-{
-
-	int i = 0;
-	for (i = 0; i < 16; i++)
-		ctr_preload[i] = 0x00;
-	i = 0;
-
-	ctr_preload[0] = 0x01;	/* flag */
-	if (qc_exists && a4_exists)
-		ctr_preload[1] = mpdu[30] & 0x0f;	/* QoC_Control  */
-	if (qc_exists && !a4_exists)
-		ctr_preload[1] = mpdu[24] & 0x0f;
-
-	for (i = 2; i < 8; i++)
-		ctr_preload[i] = mpdu[i + 8];	/* ctr_preload[2:7] = A2[0:5] = mpdu[10:15] */
-#ifdef CONSISTENT_PN_ORDER
-	for (i = 8; i < 14; i++)
-		ctr_preload[i] = pn_vector[i - 8];	/* ctr_preload[8:13] = PN[0:5] */
-#else
-	for (i = 8; i < 14; i++)
-		ctr_preload[i] = pn_vector[13 - i];	/* ctr_preload[8:13] = PN[5:0] */
-#endif
-	ctr_preload[14] = (unsigned char)(c / 256);	/* Ctr */
-	ctr_preload[15] = (unsigned char)(c % 256);
-
-}
-
-BOOLEAN RTMPSoftDecryptAES(struct rt_rtmp_adapter *pAd,
-			   u8 *pData,
-			   unsigned long DataByteCnt, struct rt_cipher_key *pWpaKey)
-{
-	u8 KeyID;
-	u32 HeaderLen;
-	u8 PN[6];
-	u32 payload_len;
-	u32 num_blocks;
-	u32 payload_remainder;
-	u16 fc;
-	u8 fc0;
-	u8 fc1;
-	u32 frame_type;
-	u32 frame_subtype;
-	u32 from_ds;
-	u32 to_ds;
-	int a4_exists;
-	int qc_exists;
-	u8 aes_out[16];
-	int payload_index;
-	u32 i;
-	u8 ctr_preload[16];
-	u8 chain_buffer[16];
-	u8 padded_buffer[16];
-	u8 mic_iv[16];
-	u8 mic_header1[16];
-	u8 mic_header2[16];
-	u8 MIC[8];
-	u8 TrailMIC[8];
-
-	fc0 = *pData;
-	fc1 = *(pData + 1);
-
-	fc = *((u16 *)pData);
-
-	frame_type = ((fc0 >> 2) & 0x03);
-	frame_subtype = ((fc0 >> 4) & 0x0f);
-
-	from_ds = (fc1 & 0x2) >> 1;
-	to_ds = (fc1 & 0x1);
-
-	a4_exists = (from_ds & to_ds);
-	qc_exists = ((frame_subtype == 0x08) ||	/* Assumed QoS subtypes */
-		     (frame_subtype == 0x09) ||	/* Likely to change.    */
-		     (frame_subtype == 0x0a) || (frame_subtype == 0x0b)
-	    );
-
-	HeaderLen = 24;
-	if (a4_exists)
-		HeaderLen += 6;
-
-	KeyID = *((u8 *)(pData + HeaderLen + 3));
-	KeyID = KeyID >> 6;
-
-	if (pWpaKey[KeyID].KeyLen == 0) {
-		DBGPRINT(RT_DEBUG_TRACE,
-			 ("RTMPSoftDecryptAES failed!(KeyID[%d] Length can not be 0)\n",
-			  KeyID));
-		return FALSE;
-	}
-
-	PN[0] = *(pData + HeaderLen);
-	PN[1] = *(pData + HeaderLen + 1);
-	PN[2] = *(pData + HeaderLen + 4);
-	PN[3] = *(pData + HeaderLen + 5);
-	PN[4] = *(pData + HeaderLen + 6);
-	PN[5] = *(pData + HeaderLen + 7);
-
-	payload_len = DataByteCnt - HeaderLen - 8 - 8;	/* 8 bytes for CCMP header , 8 bytes for MIC */
-	payload_remainder = (payload_len) % 16;
-	num_blocks = (payload_len) / 16;
-
-	/* Find start of payload */
-	payload_index = HeaderLen + 8;	/*IV+EIV */
-
-	for (i = 0; i < num_blocks; i++) {
-		construct_ctr_preload(ctr_preload,
-				      a4_exists, qc_exists, pData, PN, i + 1);
-
-		aes128k128d(pWpaKey[KeyID].Key, ctr_preload, aes_out);
-
-		bitwise_xor(aes_out, pData + payload_index, chain_buffer);
-		NdisMoveMemory(pData + payload_index - 8, chain_buffer, 16);
-		payload_index += 16;
-	}
-
-	/* */
-	/* If there is a short final block, then pad it */
-	/* encrypt it and copy the unpadded part back */
-	/* */
-	if (payload_remainder > 0) {
-		construct_ctr_preload(ctr_preload,
-				      a4_exists,
-				      qc_exists, pData, PN, num_blocks + 1);
-
-		NdisZeroMemory(padded_buffer, 16);
-		NdisMoveMemory(padded_buffer, pData + payload_index,
-			       payload_remainder);
-
-		aes128k128d(pWpaKey[KeyID].Key, ctr_preload, aes_out);
-
-		bitwise_xor(aes_out, padded_buffer, chain_buffer);
-		NdisMoveMemory(pData + payload_index - 8, chain_buffer,
-			       payload_remainder);
-		payload_index += payload_remainder;
-	}
-	/* */
-	/* Descrypt the MIC */
-	/* */
-	construct_ctr_preload(ctr_preload, a4_exists, qc_exists, pData, PN, 0);
-	NdisZeroMemory(padded_buffer, 16);
-	NdisMoveMemory(padded_buffer, pData + payload_index, 8);
-
-	aes128k128d(pWpaKey[KeyID].Key, ctr_preload, aes_out);
-
-	bitwise_xor(aes_out, padded_buffer, chain_buffer);
-
-	NdisMoveMemory(TrailMIC, chain_buffer, 8);
-
-	/* */
-	/* Calculate MIC */
-	/* */
-
-	/*Force the protected frame bit on */
-	*(pData + 1) = *(pData + 1) | 0x40;
-
-	/* Find start of payload */
-	/* Because the CCMP header has been removed */
-	payload_index = HeaderLen;
-
-	construct_mic_iv(mic_iv, qc_exists, a4_exists, pData, payload_len, PN);
-
-	construct_mic_header1(mic_header1, HeaderLen, pData);
-
-	construct_mic_header2(mic_header2, pData, a4_exists, qc_exists);
-
-	aes128k128d(pWpaKey[KeyID].Key, mic_iv, aes_out);
-	bitwise_xor(aes_out, mic_header1, chain_buffer);
-	aes128k128d(pWpaKey[KeyID].Key, chain_buffer, aes_out);
-	bitwise_xor(aes_out, mic_header2, chain_buffer);
-	aes128k128d(pWpaKey[KeyID].Key, chain_buffer, aes_out);
-
-	/* iterate through each 16 byte payload block */
-	for (i = 0; i < num_blocks; i++) {
-		bitwise_xor(aes_out, pData + payload_index, chain_buffer);
-		payload_index += 16;
-		aes128k128d(pWpaKey[KeyID].Key, chain_buffer, aes_out);
-	}
-
-	/* Add on the final payload block if it needs padding */
-	if (payload_remainder > 0) {
-		NdisZeroMemory(padded_buffer, 16);
-		NdisMoveMemory(padded_buffer, pData + payload_index,
-			       payload_remainder);
-
-		bitwise_xor(aes_out, padded_buffer, chain_buffer);
-		aes128k128d(pWpaKey[KeyID].Key, chain_buffer, aes_out);
-	}
-	/* aes_out contains padded mic, discard most significant */
-	/* 8 bytes to generate 64 bit MIC */
-	for (i = 0; i < 8; i++)
-		MIC[i] = aes_out[i];
-
-	if (!NdisEqualMemory(MIC, TrailMIC, 8)) {
-		DBGPRINT(RT_DEBUG_ERROR, ("RTMPSoftDecryptAES, MIC Error !\n"));	/*MIC error. */
-		return FALSE;
-	}
-
-	return TRUE;
-}
-
-/* =========================  AES En/Decryption ========================== */
-#ifndef	uint8
-#define	uint8  unsigned	char
-#endif
-
-#ifndef	uint32
-#define	uint32 unsigned	int
-#endif
-
-/* forward S-box */
-static uint32 FSb[256] = {
-	0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5,
-	0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76,
-	0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0,
-	0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0,
-	0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC,
-	0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15,
-	0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A,
-	0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75,
-	0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0,
-	0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84,
-	0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B,
-	0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF,
-	0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85,
-	0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8,
-	0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5,
-	0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2,
-	0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17,
-	0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73,
-	0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88,
-	0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB,
-	0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C,
-	0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79,
-	0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9,
-	0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08,
-	0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6,
-	0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A,
-	0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E,
-	0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E,
-	0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94,
-	0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF,
-	0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68,
-	0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16
-};
-
-/* forward table */
-#define	FT \
-\
-	V(C6,63,63,A5),	V(F8,7C,7C,84),	V(EE,77,77,99),	V(F6,7B,7B,8D),	\
-	V(FF,F2,F2,0D),	V(D6,6B,6B,BD),	V(DE,6F,6F,B1),	V(91,C5,C5,54),	\
-	V(60,30,30,50),	V(02,01,01,03),	V(CE,67,67,A9),	V(56,2B,2B,7D),	\
-	V(E7,FE,FE,19),	V(B5,D7,D7,62),	V(4D,AB,AB,E6),	V(EC,76,76,9A),	\
-	V(8F,CA,CA,45),	V(1F,82,82,9D),	V(89,C9,C9,40),	V(FA,7D,7D,87),	\
-	V(EF,FA,FA,15),	V(B2,59,59,EB),	V(8E,47,47,C9),	V(FB,F0,F0,0B),	\
-	V(41,AD,AD,EC),	V(B3,D4,D4,67),	V(5F,A2,A2,FD),	V(45,AF,AF,EA),	\
-	V(23,9C,9C,BF),	V(53,A4,A4,F7),	V(E4,72,72,96),	V(9B,C0,C0,5B),	\
-	V(75,B7,B7,C2),	V(E1,FD,FD,1C),	V(3D,93,93,AE),	V(4C,26,26,6A),	\
-	V(6C,36,36,5A),	V(7E,3F,3F,41),	V(F5,F7,F7,02),	V(83,CC,CC,4F),	\
-	V(68,34,34,5C),	V(51,A5,A5,F4),	V(D1,E5,E5,34),	V(F9,F1,F1,08),	\
-	V(E2,71,71,93),	V(AB,D8,D8,73),	V(62,31,31,53),	V(2A,15,15,3F),	\
-	V(08,04,04,0C),	V(95,C7,C7,52),	V(46,23,23,65),	V(9D,C3,C3,5E),	\
-	V(30,18,18,28),	V(37,96,96,A1),	V(0A,05,05,0F),	V(2F,9A,9A,B5),	\
-	V(0E,07,07,09),	V(24,12,12,36),	V(1B,80,80,9B),	V(DF,E2,E2,3D),	\
-	V(CD,EB,EB,26),	V(4E,27,27,69),	V(7F,B2,B2,CD),	V(EA,75,75,9F),	\
-	V(12,09,09,1B),	V(1D,83,83,9E),	V(58,2C,2C,74),	V(34,1A,1A,2E),	\
-	V(36,1B,1B,2D),	V(DC,6E,6E,B2),	V(B4,5A,5A,EE),	V(5B,A0,A0,FB),	\
-	V(A4,52,52,F6),	V(76,3B,3B,4D),	V(B7,D6,D6,61),	V(7D,B3,B3,CE),	\
-	V(52,29,29,7B),	V(DD,E3,E3,3E),	V(5E,2F,2F,71),	V(13,84,84,97),	\
-	V(A6,53,53,F5),	V(B9,D1,D1,68),	V(00,00,00,00),	V(C1,ED,ED,2C),	\
-	V(40,20,20,60),	V(E3,FC,FC,1F),	V(79,B1,B1,C8),	V(B6,5B,5B,ED),	\
-	V(D4,6A,6A,BE),	V(8D,CB,CB,46),	V(67,BE,BE,D9),	V(72,39,39,4B),	\
-	V(94,4A,4A,DE),	V(98,4C,4C,D4),	V(B0,58,58,E8),	V(85,CF,CF,4A),	\
-	V(BB,D0,D0,6B),	V(C5,EF,EF,2A),	V(4F,AA,AA,E5),	V(ED,FB,FB,16),	\
-	V(86,43,43,C5),	V(9A,4D,4D,D7),	V(66,33,33,55),	V(11,85,85,94),	\
-	V(8A,45,45,CF),	V(E9,F9,F9,10),	V(04,02,02,06),	V(FE,7F,7F,81),	\
-	V(A0,50,50,F0),	V(78,3C,3C,44),	V(25,9F,9F,BA),	V(4B,A8,A8,E3),	\
-	V(A2,51,51,F3),	V(5D,A3,A3,FE),	V(80,40,40,C0),	V(05,8F,8F,8A),	\
-	V(3F,92,92,AD),	V(21,9D,9D,BC),	V(70,38,38,48),	V(F1,F5,F5,04),	\
-	V(63,BC,BC,DF),	V(77,B6,B6,C1),	V(AF,DA,DA,75),	V(42,21,21,63),	\
-	V(20,10,10,30),	V(E5,FF,FF,1A),	V(FD,F3,F3,0E),	V(BF,D2,D2,6D),	\
-	V(81,CD,CD,4C),	V(18,0C,0C,14),	V(26,13,13,35),	V(C3,EC,EC,2F),	\
-	V(BE,5F,5F,E1),	V(35,97,97,A2),	V(88,44,44,CC),	V(2E,17,17,39),	\
-	V(93,C4,C4,57),	V(55,A7,A7,F2),	V(FC,7E,7E,82),	V(7A,3D,3D,47),	\
-	V(C8,64,64,AC),	V(BA,5D,5D,E7),	V(32,19,19,2B),	V(E6,73,73,95),	\
-	V(C0,60,60,A0),	V(19,81,81,98),	V(9E,4F,4F,D1),	V(A3,DC,DC,7F),	\
-	V(44,22,22,66),	V(54,2A,2A,7E),	V(3B,90,90,AB),	V(0B,88,88,83),	\
-	V(8C,46,46,CA),	V(C7,EE,EE,29),	V(6B,B8,B8,D3),	V(28,14,14,3C),	\
-	V(A7,DE,DE,79),	V(BC,5E,5E,E2),	V(16,0B,0B,1D),	V(AD,DB,DB,76),	\
-	V(DB,E0,E0,3B),	V(64,32,32,56),	V(74,3A,3A,4E),	V(14,0A,0A,1E),	\
-	V(92,49,49,DB),	V(0C,06,06,0A),	V(48,24,24,6C),	V(B8,5C,5C,E4),	\
-	V(9F,C2,C2,5D),	V(BD,D3,D3,6E),	V(43,AC,AC,EF),	V(C4,62,62,A6),	\
-	V(39,91,91,A8),	V(31,95,95,A4),	V(D3,E4,E4,37),	V(F2,79,79,8B),	\
-	V(D5,E7,E7,32),	V(8B,C8,C8,43),	V(6E,37,37,59),	V(DA,6D,6D,B7),	\
-	V(01,8D,8D,8C),	V(B1,D5,D5,64),	V(9C,4E,4E,D2),	V(49,A9,A9,E0),	\
-	V(D8,6C,6C,B4),	V(AC,56,56,FA),	V(F3,F4,F4,07),	V(CF,EA,EA,25),	\
-	V(CA,65,65,AF),	V(F4,7A,7A,8E),	V(47,AE,AE,E9),	V(10,08,08,18),	\
-	V(6F,BA,BA,D5),	V(F0,78,78,88),	V(4A,25,25,6F),	V(5C,2E,2E,72),	\
-	V(38,1C,1C,24),	V(57,A6,A6,F1),	V(73,B4,B4,C7),	V(97,C6,C6,51),	\
-	V(CB,E8,E8,23),	V(A1,DD,DD,7C),	V(E8,74,74,9C),	V(3E,1F,1F,21),	\
-	V(96,4B,4B,DD),	V(61,BD,BD,DC),	V(0D,8B,8B,86),	V(0F,8A,8A,85),	\
-	V(E0,70,70,90),	V(7C,3E,3E,42),	V(71,B5,B5,C4),	V(CC,66,66,AA),	\
-	V(90,48,48,D8),	V(06,03,03,05),	V(F7,F6,F6,01),	V(1C,0E,0E,12),	\
-	V(C2,61,61,A3),	V(6A,35,35,5F),	V(AE,57,57,F9),	V(69,B9,B9,D0),	\
-	V(17,86,86,91),	V(99,C1,C1,58),	V(3A,1D,1D,27),	V(27,9E,9E,B9),	\
-	V(D9,E1,E1,38),	V(EB,F8,F8,13),	V(2B,98,98,B3),	V(22,11,11,33),	\
-	V(D2,69,69,BB),	V(A9,D9,D9,70),	V(07,8E,8E,89),	V(33,94,94,A7),	\
-	V(2D,9B,9B,B6),	V(3C,1E,1E,22),	V(15,87,87,92),	V(C9,E9,E9,20),	\
-	V(87,CE,CE,49),	V(AA,55,55,FF),	V(50,28,28,78),	V(A5,DF,DF,7A),	\
-	V(03,8C,8C,8F),	V(59,A1,A1,F8),	V(09,89,89,80),	V(1A,0D,0D,17),	\
-	V(65,BF,BF,DA),	V(D7,E6,E6,31),	V(84,42,42,C6),	V(D0,68,68,B8),	\
-	V(82,41,41,C3),	V(29,99,99,B0),	V(5A,2D,2D,77),	V(1E,0F,0F,11),	\
-	V(7B,B0,B0,CB),	V(A8,54,54,FC),	V(6D,BB,BB,D6),	V(2C,16,16,3A)
-
-#define	V(a,b,c,d) 0x##a##b##c##d
-static uint32 FT0[256] = { FT };
-
-#undef V
-
-#define	V(a,b,c,d) 0x##d##a##b##c
-static uint32 FT1[256] = { FT };
-
-#undef V
-
-#define	V(a,b,c,d) 0x##c##d##a##b
-static uint32 FT2[256] = { FT };
-
-#undef V
-
-#define	V(a,b,c,d) 0x##b##c##d##a
-static uint32 FT3[256] = { FT };
-
-#undef V
-
-#undef FT
-
-/* reverse S-box */
-
-static uint32 RSb[256] = {
-	0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38,
-	0xBF, 0x40, 0xA3, 0x9E, 0x81, 0xF3, 0xD7, 0xFB,
-	0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87,
-	0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB,
-	0x54, 0x7B, 0x94, 0x32, 0xA6, 0xC2, 0x23, 0x3D,
-	0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E,
-	0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2,
-	0x76, 0x5B, 0xA2, 0x49, 0x6D, 0x8B, 0xD1, 0x25,
-	0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16,
-	0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92,
-	0x6C, 0x70, 0x48, 0x50, 0xFD, 0xED, 0xB9, 0xDA,
-	0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84,
-	0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A,
-	0xF7, 0xE4, 0x58, 0x05, 0xB8, 0xB3, 0x45, 0x06,
-	0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02,
-	0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B,
-	0x3A, 0x91, 0x11, 0x41, 0x4F, 0x67, 0xDC, 0xEA,
-	0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73,
-	0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85,
-	0xE2, 0xF9, 0x37, 0xE8, 0x1C, 0x75, 0xDF, 0x6E,
-	0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89,
-	0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B,
-	0xFC, 0x56, 0x3E, 0x4B, 0xC6, 0xD2, 0x79, 0x20,
-	0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4,
-	0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31,
-	0xB1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xEC, 0x5F,
-	0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D,
-	0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF,
-	0xA0, 0xE0, 0x3B, 0x4D, 0xAE, 0x2A, 0xF5, 0xB0,
-	0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61,
-	0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26,
-	0xE1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0C, 0x7D
-};
-
-/* reverse table */
-
-#define	RT \
-\
-	V(51,F4,A7,50),	V(7E,41,65,53),	V(1A,17,A4,C3),	V(3A,27,5E,96),	\
-	V(3B,AB,6B,CB),	V(1F,9D,45,F1),	V(AC,FA,58,AB),	V(4B,E3,03,93),	\
-	V(20,30,FA,55),	V(AD,76,6D,F6),	V(88,CC,76,91),	V(F5,02,4C,25),	\
-	V(4F,E5,D7,FC),	V(C5,2A,CB,D7),	V(26,35,44,80),	V(B5,62,A3,8F),	\
-	V(DE,B1,5A,49),	V(25,BA,1B,67),	V(45,EA,0E,98),	V(5D,FE,C0,E1),	\
-	V(C3,2F,75,02),	V(81,4C,F0,12),	V(8D,46,97,A3),	V(6B,D3,F9,C6),	\
-	V(03,8F,5F,E7),	V(15,92,9C,95),	V(BF,6D,7A,EB),	V(95,52,59,DA),	\
-	V(D4,BE,83,2D),	V(58,74,21,D3),	V(49,E0,69,29),	V(8E,C9,C8,44),	\
-	V(75,C2,89,6A),	V(F4,8E,79,78),	V(99,58,3E,6B),	V(27,B9,71,DD),	\
-	V(BE,E1,4F,B6),	V(F0,88,AD,17),	V(C9,20,AC,66),	V(7D,CE,3A,B4),	\
-	V(63,DF,4A,18),	V(E5,1A,31,82),	V(97,51,33,60),	V(62,53,7F,45),	\
-	V(B1,64,77,E0),	V(BB,6B,AE,84),	V(FE,81,A0,1C),	V(F9,08,2B,94),	\
-	V(70,48,68,58),	V(8F,45,FD,19),	V(94,DE,6C,87),	V(52,7B,F8,B7),	\
-	V(AB,73,D3,23),	V(72,4B,02,E2),	V(E3,1F,8F,57),	V(66,55,AB,2A),	\
-	V(B2,EB,28,07),	V(2F,B5,C2,03),	V(86,C5,7B,9A),	V(D3,37,08,A5),	\
-	V(30,28,87,F2),	V(23,BF,A5,B2),	V(02,03,6A,BA),	V(ED,16,82,5C),	\
-	V(8A,CF,1C,2B),	V(A7,79,B4,92),	V(F3,07,F2,F0),	V(4E,69,E2,A1),	\
-	V(65,DA,F4,CD),	V(06,05,BE,D5),	V(D1,34,62,1F),	V(C4,A6,FE,8A),	\
-	V(34,2E,53,9D),	V(A2,F3,55,A0),	V(05,8A,E1,32),	V(A4,F6,EB,75),	\
-	V(0B,83,EC,39),	V(40,60,EF,AA),	V(5E,71,9F,06),	V(BD,6E,10,51),	\
-	V(3E,21,8A,F9),	V(96,DD,06,3D),	V(DD,3E,05,AE),	V(4D,E6,BD,46),	\
-	V(91,54,8D,B5),	V(71,C4,5D,05),	V(04,06,D4,6F),	V(60,50,15,FF),	\
-	V(19,98,FB,24),	V(D6,BD,E9,97),	V(89,40,43,CC),	V(67,D9,9E,77),	\
-	V(B0,E8,42,BD),	V(07,89,8B,88),	V(E7,19,5B,38),	V(79,C8,EE,DB),	\
-	V(A1,7C,0A,47),	V(7C,42,0F,E9),	V(F8,84,1E,C9),	V(00,00,00,00),	\
-	V(09,80,86,83),	V(32,2B,ED,48),	V(1E,11,70,AC),	V(6C,5A,72,4E),	\
-	V(FD,0E,FF,FB),	V(0F,85,38,56),	V(3D,AE,D5,1E),	V(36,2D,39,27),	\
-	V(0A,0F,D9,64),	V(68,5C,A6,21),	V(9B,5B,54,D1),	V(24,36,2E,3A),	\
-	V(0C,0A,67,B1),	V(93,57,E7,0F),	V(B4,EE,96,D2),	V(1B,9B,91,9E),	\
-	V(80,C0,C5,4F),	V(61,DC,20,A2),	V(5A,77,4B,69),	V(1C,12,1A,16),	\
-	V(E2,93,BA,0A),	V(C0,A0,2A,E5),	V(3C,22,E0,43),	V(12,1B,17,1D),	\
-	V(0E,09,0D,0B),	V(F2,8B,C7,AD),	V(2D,B6,A8,B9),	V(14,1E,A9,C8),	\
-	V(57,F1,19,85),	V(AF,75,07,4C),	V(EE,99,DD,BB),	V(A3,7F,60,FD),	\
-	V(F7,01,26,9F),	V(5C,72,F5,BC),	V(44,66,3B,C5),	V(5B,FB,7E,34),	\
-	V(8B,43,29,76),	V(CB,23,C6,DC),	V(B6,ED,FC,68),	V(B8,E4,F1,63),	\
-	V(D7,31,DC,CA),	V(42,63,85,10),	V(13,97,22,40),	V(84,C6,11,20),	\
-	V(85,4A,24,7D),	V(D2,BB,3D,F8),	V(AE,F9,32,11),	V(C7,29,A1,6D),	\
-	V(1D,9E,2F,4B),	V(DC,B2,30,F3),	V(0D,86,52,EC),	V(77,C1,E3,D0),	\
-	V(2B,B3,16,6C),	V(A9,70,B9,99),	V(11,94,48,FA),	V(47,E9,64,22),	\
-	V(A8,FC,8C,C4),	V(A0,F0,3F,1A),	V(56,7D,2C,D8),	V(22,33,90,EF),	\
-	V(87,49,4E,C7),	V(D9,38,D1,C1),	V(8C,CA,A2,FE),	V(98,D4,0B,36),	\
-	V(A6,F5,81,CF),	V(A5,7A,DE,28),	V(DA,B7,8E,26),	V(3F,AD,BF,A4),	\
-	V(2C,3A,9D,E4),	V(50,78,92,0D),	V(6A,5F,CC,9B),	V(54,7E,46,62),	\
-	V(F6,8D,13,C2),	V(90,D8,B8,E8),	V(2E,39,F7,5E),	V(82,C3,AF,F5),	\
-	V(9F,5D,80,BE),	V(69,D0,93,7C),	V(6F,D5,2D,A9),	V(CF,25,12,B3),	\
-	V(C8,AC,99,3B),	V(10,18,7D,A7),	V(E8,9C,63,6E),	V(DB,3B,BB,7B),	\
-	V(CD,26,78,09),	V(6E,59,18,F4),	V(EC,9A,B7,01),	V(83,4F,9A,A8),	\
-	V(E6,95,6E,65),	V(AA,FF,E6,7E),	V(21,BC,CF,08),	V(EF,15,E8,E6),	\
-	V(BA,E7,9B,D9),	V(4A,6F,36,CE),	V(EA,9F,09,D4),	V(29,B0,7C,D6),	\
-	V(31,A4,B2,AF),	V(2A,3F,23,31),	V(C6,A5,94,30),	V(35,A2,66,C0),	\
-	V(74,4E,BC,37),	V(FC,82,CA,A6),	V(E0,90,D0,B0),	V(33,A7,D8,15),	\
-	V(F1,04,98,4A),	V(41,EC,DA,F7),	V(7F,CD,50,0E),	V(17,91,F6,2F),	\
-	V(76,4D,D6,8D),	V(43,EF,B0,4D),	V(CC,AA,4D,54),	V(E4,96,04,DF),	\
-	V(9E,D1,B5,E3),	V(4C,6A,88,1B),	V(C1,2C,1F,B8),	V(46,65,51,7F),	\
-	V(9D,5E,EA,04),	V(01,8C,35,5D),	V(FA,87,74,73),	V(FB,0B,41,2E),	\
-	V(B3,67,1D,5A),	V(92,DB,D2,52),	V(E9,10,56,33),	V(6D,D6,47,13),	\
-	V(9A,D7,61,8C),	V(37,A1,0C,7A),	V(59,F8,14,8E),	V(EB,13,3C,89),	\
-	V(CE,A9,27,EE),	V(B7,61,C9,35),	V(E1,1C,E5,ED),	V(7A,47,B1,3C),	\
-	V(9C,D2,DF,59),	V(55,F2,73,3F),	V(18,14,CE,79),	V(73,C7,37,BF),	\
-	V(53,F7,CD,EA),	V(5F,FD,AA,5B),	V(DF,3D,6F,14),	V(78,44,DB,86),	\
-	V(CA,AF,F3,81),	V(B9,68,C4,3E),	V(38,24,34,2C),	V(C2,A3,40,5F),	\
-	V(16,1D,C3,72),	V(BC,E2,25,0C),	V(28,3C,49,8B),	V(FF,0D,95,41),	\
-	V(39,A8,01,71),	V(08,0C,B3,DE),	V(D8,B4,E4,9C),	V(64,56,C1,90),	\
-	V(7B,CB,84,61),	V(D5,32,B6,70),	V(48,6C,5C,74),	V(D0,B8,57,42)
-
-#define	V(a,b,c,d) 0x##a##b##c##d
-static uint32 RT0[256] = { RT };
-
-#undef V
-
-#define	V(a,b,c,d) 0x##d##a##b##c
-static uint32 RT1[256] = { RT };
-
-#undef V
-
-#define	V(a,b,c,d) 0x##c##d##a##b
-static uint32 RT2[256] = { RT };
-
-#undef V
-
-#define	V(a,b,c,d) 0x##b##c##d##a
-static uint32 RT3[256] = { RT };
-
-#undef V
-
-#undef RT
-
-/* round constants */
-
-static uint32 RCON[10] = {
-	0x01000000, 0x02000000, 0x04000000, 0x08000000,
-	0x10000000, 0x20000000, 0x40000000, 0x80000000,
-	0x1B000000, 0x36000000
-};
-
-/* key schedule	tables */
-
-static int KT_init = 1;
-
-static uint32 KT0[256];
-static uint32 KT1[256];
-static uint32 KT2[256];
-static uint32 KT3[256];
-
-/* platform-independent	32-bit integer manipulation	macros */
-
-#define	GET_UINT32(n,b,i)						\
-{												\
-	(n)	= (	(uint32) (b)[(i)	] << 24	)		\
-		| (	(uint32) (b)[(i) + 1] << 16	)		\
-		| (	(uint32) (b)[(i) + 2] <<  8	)		\
-		| (	(uint32) (b)[(i) + 3]		);		\
-}
-
-#define	PUT_UINT32(n,b,i)						\
-{												\
-	(b)[(i)	   ] = (uint8) ( (n) >>	24 );		\
-	(b)[(i)	+ 1] = (uint8) ( (n) >>	16 );		\
-	(b)[(i)	+ 2] = (uint8) ( (n) >>	 8 );		\
-	(b)[(i)	+ 3] = (uint8) ( (n)	   );		\
-}
-
-int rt_aes_set_key(struct aes_context * ctx, uint8 * key, int nbits)
-{
-	int i;
-	uint32 *RK, *SK;
-
-	switch (nbits) {
-	case 128:
-		ctx->nr = 10;
-		break;
-	case 192:
-		ctx->nr = 12;
-		break;
-	case 256:
-		ctx->nr = 14;
-		break;
-	default:
-		return (1);
-	}
-
-	RK = (uint32 *) ctx->erk;
-
-	for (i = 0; i < (nbits >> 5); i++) {
-		GET_UINT32(RK[i], key, i * 4);
-	}
-
-	/* setup encryption     round keys */
-
-	switch (nbits) {
-	case 128:
-
-		for (i = 0; i < 10; i++, RK += 4) {
-			RK[4] = RK[0] ^ RCON[i] ^
-			    (FSb[(uint8) (RK[3] >> 16)] << 24) ^
-			    (FSb[(uint8) (RK[3] >> 8)] << 16) ^
-			    (FSb[(uint8) (RK[3])] << 8) ^
-			    (FSb[(uint8) (RK[3] >> 24)]);
-
-			RK[5] = RK[1] ^ RK[4];
-			RK[6] = RK[2] ^ RK[5];
-			RK[7] = RK[3] ^ RK[6];
-		}
-		break;
-
-	case 192:
-
-		for (i = 0; i < 8; i++, RK += 6) {
-			RK[6] = RK[0] ^ RCON[i] ^
-			    (FSb[(uint8) (RK[5] >> 16)] << 24) ^
-			    (FSb[(uint8) (RK[5] >> 8)] << 16) ^
-			    (FSb[(uint8) (RK[5])] << 8) ^
-			    (FSb[(uint8) (RK[5] >> 24)]);
-
-			RK[7] = RK[1] ^ RK[6];
-			RK[8] = RK[2] ^ RK[7];
-			RK[9] = RK[3] ^ RK[8];
-			RK[10] = RK[4] ^ RK[9];
-			RK[11] = RK[5] ^ RK[10];
-		}
-		break;
-
-	case 256:
-
-		for (i = 0; i < 7; i++, RK += 8) {
-			RK[8] = RK[0] ^ RCON[i] ^
-			    (FSb[(uint8) (RK[7] >> 16)] << 24) ^
-			    (FSb[(uint8) (RK[7] >> 8)] << 16) ^
-			    (FSb[(uint8) (RK[7])] << 8) ^
-			    (FSb[(uint8) (RK[7] >> 24)]);
-
-			RK[9] = RK[1] ^ RK[8];
-			RK[10] = RK[2] ^ RK[9];
-			RK[11] = RK[3] ^ RK[10];
-
-			RK[12] = RK[4] ^
-			    (FSb[(uint8) (RK[11] >> 24)] << 24) ^
-			    (FSb[(uint8) (RK[11] >> 16)] << 16) ^
-			    (FSb[(uint8) (RK[11] >> 8)] << 8) ^
-			    (FSb[(uint8) (RK[11])]);
-
-			RK[13] = RK[5] ^ RK[12];
-			RK[14] = RK[6] ^ RK[13];
-			RK[15] = RK[7] ^ RK[14];
-		}
-		break;
-	}
-
-	/* setup decryption     round keys */
-
-	if (KT_init) {
-		for (i = 0; i < 256; i++) {
-			KT0[i] = RT0[FSb[i]];
-			KT1[i] = RT1[FSb[i]];
-			KT2[i] = RT2[FSb[i]];
-			KT3[i] = RT3[FSb[i]];
-		}
-
-		KT_init = 0;
-	}
-
-	SK = (uint32 *) ctx->drk;
-
-	*SK++ = *RK++;
-	*SK++ = *RK++;
-	*SK++ = *RK++;
-	*SK++ = *RK++;
-
-	for (i = 1; i < ctx->nr; i++) {
-		RK -= 8;
-
-		*SK++ = KT0[(uint8) (*RK >> 24)] ^
-		    KT1[(uint8) (*RK >> 16)] ^
-		    KT2[(uint8) (*RK >> 8)] ^ KT3[(uint8) (*RK)];
-		RK++;
-
-		*SK++ = KT0[(uint8) (*RK >> 24)] ^
-		    KT1[(uint8) (*RK >> 16)] ^
-		    KT2[(uint8) (*RK >> 8)] ^ KT3[(uint8) (*RK)];
-		RK++;
-
-		*SK++ = KT0[(uint8) (*RK >> 24)] ^
-		    KT1[(uint8) (*RK >> 16)] ^
-		    KT2[(uint8) (*RK >> 8)] ^ KT3[(uint8) (*RK)];
-		RK++;
-
-		*SK++ = KT0[(uint8) (*RK >> 24)] ^
-		    KT1[(uint8) (*RK >> 16)] ^
-		    KT2[(uint8) (*RK >> 8)] ^ KT3[(uint8) (*RK)];
-		RK++;
-	}
-
-	RK -= 8;
-
-	*SK++ = *RK++;
-	*SK++ = *RK++;
-	*SK++ = *RK++;
-	*SK++ = *RK++;
-
-	return (0);
-}
-
-/* AES 128-bit block encryption	routine	*/
-
-void rt_aes_encrypt(struct aes_context * ctx, uint8 input[16], uint8 output[16])
-{
-	uint32 *RK, X0, X1, X2, X3, Y0, Y1, Y2, Y3;
-
-	RK = (uint32 *) ctx->erk;
-	GET_UINT32(X0, input, 0);
-	X0 ^= RK[0];
-	GET_UINT32(X1, input, 4);
-	X1 ^= RK[1];
-	GET_UINT32(X2, input, 8);
-	X2 ^= RK[2];
-	GET_UINT32(X3, input, 12);
-	X3 ^= RK[3];
-
-#define	AES_FROUND(X0,X1,X2,X3,Y0,Y1,Y2,Y3)		\
-{												\
-	RK += 4;									\
-												\
-	X0 = RK[0] ^ FT0[ (uint8) (	Y0 >> 24 ) ] ^	\
-				 FT1[ (uint8) (	Y1 >> 16 ) ] ^	\
-				 FT2[ (uint8) (	Y2 >>  8 ) ] ^	\
-				 FT3[ (uint8) (	Y3		 ) ];	\
-												\
-	X1 = RK[1] ^ FT0[ (uint8) (	Y1 >> 24 ) ] ^	\
-				 FT1[ (uint8) (	Y2 >> 16 ) ] ^	\
-				 FT2[ (uint8) (	Y3 >>  8 ) ] ^	\
-				 FT3[ (uint8) (	Y0		 ) ];	\
-												\
-	X2 = RK[2] ^ FT0[ (uint8) (	Y2 >> 24 ) ] ^	\
-				 FT1[ (uint8) (	Y3 >> 16 ) ] ^	\
-				 FT2[ (uint8) (	Y0 >>  8 ) ] ^	\
-				 FT3[ (uint8) (	Y1		 ) ];	\
-												\
-	X3 = RK[3] ^ FT0[ (uint8) (	Y3 >> 24 ) ] ^	\
-				 FT1[ (uint8) (	Y0 >> 16 ) ] ^	\
-				 FT2[ (uint8) (	Y1 >>  8 ) ] ^	\
-				 FT3[ (uint8) (	Y2		 ) ];	\
-}
-
-	AES_FROUND(Y0, Y1, Y2, Y3, X0, X1, X2, X3);	/* round 1 */
-	AES_FROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3);	/* round 2 */
-	AES_FROUND(Y0, Y1, Y2, Y3, X0, X1, X2, X3);	/* round 3 */
-	AES_FROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3);	/* round 4 */
-	AES_FROUND(Y0, Y1, Y2, Y3, X0, X1, X2, X3);	/* round 5 */
-	AES_FROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3);	/* round 6 */
-	AES_FROUND(Y0, Y1, Y2, Y3, X0, X1, X2, X3);	/* round 7 */
-	AES_FROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3);	/* round 8 */
-	AES_FROUND(Y0, Y1, Y2, Y3, X0, X1, X2, X3);	/* round 9 */
-
-	if (ctx->nr > 10) {
-		AES_FROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3);	/* round 10     */
-		AES_FROUND(Y0, Y1, Y2, Y3, X0, X1, X2, X3);	/* round 11     */
-	}
-
-	if (ctx->nr > 12) {
-		AES_FROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3);	/* round 12     */
-		AES_FROUND(Y0, Y1, Y2, Y3, X0, X1, X2, X3);	/* round 13     */
-	}
-
-	/* last round */
-
-	RK += 4;
-
-	X0 = RK[0] ^ (FSb[(uint8) (Y0 >> 24)] << 24) ^
-	    (FSb[(uint8) (Y1 >> 16)] << 16) ^
-	    (FSb[(uint8) (Y2 >> 8)] << 8) ^ (FSb[(uint8) (Y3)]);
-
-	X1 = RK[1] ^ (FSb[(uint8) (Y1 >> 24)] << 24) ^
-	    (FSb[(uint8) (Y2 >> 16)] << 16) ^
-	    (FSb[(uint8) (Y3 >> 8)] << 8) ^ (FSb[(uint8) (Y0)]);
-
-	X2 = RK[2] ^ (FSb[(uint8) (Y2 >> 24)] << 24) ^
-	    (FSb[(uint8) (Y3 >> 16)] << 16) ^
-	    (FSb[(uint8) (Y0 >> 8)] << 8) ^ (FSb[(uint8) (Y1)]);
-
-	X3 = RK[3] ^ (FSb[(uint8) (Y3 >> 24)] << 24) ^
-	    (FSb[(uint8) (Y0 >> 16)] << 16) ^
-	    (FSb[(uint8) (Y1 >> 8)] << 8) ^ (FSb[(uint8) (Y2)]);
-
-	PUT_UINT32(X0, output, 0);
-	PUT_UINT32(X1, output, 4);
-	PUT_UINT32(X2, output, 8);
-	PUT_UINT32(X3, output, 12);
-}
-
-/* AES 128-bit block decryption	routine	*/
-
-void rt_aes_decrypt(struct aes_context * ctx, uint8 input[16], uint8 output[16])
-{
-	uint32 *RK, X0, X1, X2, X3, Y0, Y1, Y2, Y3;
-
-	RK = (uint32 *) ctx->drk;
-
-	GET_UINT32(X0, input, 0);
-	X0 ^= RK[0];
-	GET_UINT32(X1, input, 4);
-	X1 ^= RK[1];
-	GET_UINT32(X2, input, 8);
-	X2 ^= RK[2];
-	GET_UINT32(X3, input, 12);
-	X3 ^= RK[3];
-
-#define	AES_RROUND(X0,X1,X2,X3,Y0,Y1,Y2,Y3)		\
-{												\
-	RK += 4;									\
-												\
-	X0 = RK[0] ^ RT0[ (uint8) (	Y0 >> 24 ) ] ^	\
-				 RT1[ (uint8) (	Y3 >> 16 ) ] ^	\
-				 RT2[ (uint8) (	Y2 >>  8 ) ] ^	\
-				 RT3[ (uint8) (	Y1		 ) ];	\
-												\
-	X1 = RK[1] ^ RT0[ (uint8) (	Y1 >> 24 ) ] ^	\
-				 RT1[ (uint8) (	Y0 >> 16 ) ] ^	\
-				 RT2[ (uint8) (	Y3 >>  8 ) ] ^	\
-				 RT3[ (uint8) (	Y2		 ) ];	\
-												\
-	X2 = RK[2] ^ RT0[ (uint8) (	Y2 >> 24 ) ] ^	\
-				 RT1[ (uint8) (	Y1 >> 16 ) ] ^	\
-				 RT2[ (uint8) (	Y0 >>  8 ) ] ^	\
-				 RT3[ (uint8) (	Y3		 ) ];	\
-												\
-	X3 = RK[3] ^ RT0[ (uint8) (	Y3 >> 24 ) ] ^	\
-				 RT1[ (uint8) (	Y2 >> 16 ) ] ^	\
-				 RT2[ (uint8) (	Y1 >>  8 ) ] ^	\
-				 RT3[ (uint8) (	Y0		 ) ];	\
-}
-
-	AES_RROUND(Y0, Y1, Y2, Y3, X0, X1, X2, X3);	/* round 1 */
-	AES_RROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3);	/* round 2 */
-	AES_RROUND(Y0, Y1, Y2, Y3, X0, X1, X2, X3);	/* round 3 */
-	AES_RROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3);	/* round 4 */
-	AES_RROUND(Y0, Y1, Y2, Y3, X0, X1, X2, X3);	/* round 5 */
-	AES_RROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3);	/* round 6 */
-	AES_RROUND(Y0, Y1, Y2, Y3, X0, X1, X2, X3);	/* round 7 */
-	AES_RROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3);	/* round 8 */
-	AES_RROUND(Y0, Y1, Y2, Y3, X0, X1, X2, X3);	/* round 9 */
-
-	if (ctx->nr > 10) {
-		AES_RROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3);	/* round 10     */
-		AES_RROUND(Y0, Y1, Y2, Y3, X0, X1, X2, X3);	/* round 11     */
-	}
-
-	if (ctx->nr > 12) {
-		AES_RROUND(X0, X1, X2, X3, Y0, Y1, Y2, Y3);	/* round 12     */
-		AES_RROUND(Y0, Y1, Y2, Y3, X0, X1, X2, X3);	/* round 13     */
-	}
-
-	/* last round */
-
-	RK += 4;
-
-	X0 = RK[0] ^ (RSb[(uint8) (Y0 >> 24)] << 24) ^
-	    (RSb[(uint8) (Y3 >> 16)] << 16) ^
-	    (RSb[(uint8) (Y2 >> 8)] << 8) ^ (RSb[(uint8) (Y1)]);
-
-	X1 = RK[1] ^ (RSb[(uint8) (Y1 >> 24)] << 24) ^
-	    (RSb[(uint8) (Y0 >> 16)] << 16) ^
-	    (RSb[(uint8) (Y3 >> 8)] << 8) ^ (RSb[(uint8) (Y2)]);
-
-	X2 = RK[2] ^ (RSb[(uint8) (Y2 >> 24)] << 24) ^
-	    (RSb[(uint8) (Y1 >> 16)] << 16) ^
-	    (RSb[(uint8) (Y0 >> 8)] << 8) ^ (RSb[(uint8) (Y3)]);
-
-	X3 = RK[3] ^ (RSb[(uint8) (Y3 >> 24)] << 24) ^
-	    (RSb[(uint8) (Y2 >> 16)] << 16) ^
-	    (RSb[(uint8) (Y1 >> 8)] << 8) ^ (RSb[(uint8) (Y0)]);
-
-	PUT_UINT32(X0, output, 0);
-	PUT_UINT32(X1, output, 4);
-	PUT_UINT32(X2, output, 8);
-	PUT_UINT32(X3, output, 12);
-}
-
-/*
-    ==========================================================================
-    Description:
-        ENCRYPT AES GTK before sending in EAPOL frame.
-        AES GTK length = 128 bit,  so fix blocks for aes-key-wrap as 2 in this function.
-        This function references to RFC 3394 for aes key wrap algorithm.
-    Return:
-    ==========================================================================
-*/
-void AES_GTK_KEY_WRAP(u8 * key,
-		      u8 * plaintext,
-		      u32 p_len, u8 * ciphertext)
-{
-	u8 A[8], BIN[16], BOUT[16];
-	u8 R[512];
-	int num_blocks = p_len / 8;	/* unit:64bits */
-	int i, j;
-	struct aes_context aesctx;
-	u8 xor;
-
-	rt_aes_set_key(&aesctx, key, 128);
-
-	/* Init IA */
-	for (i = 0; i < 8; i++)
-		A[i] = 0xa6;
-
-	/*Input plaintext */
-	for (i = 0; i < num_blocks; i++) {
-		for (j = 0; j < 8; j++)
-			R[8 * (i + 1) + j] = plaintext[8 * i + j];
-	}
-
-	/* Key Mix */
-	for (j = 0; j < 6; j++) {
-		for (i = 1; i <= num_blocks; i++) {
-			/*phase 1 */
-			NdisMoveMemory(BIN, A, 8);
-			NdisMoveMemory(&BIN[8], &R[8 * i], 8);
-			rt_aes_encrypt(&aesctx, BIN, BOUT);
-
-			NdisMoveMemory(A, &BOUT[0], 8);
-			xor = num_blocks * j + i;
-			A[7] = BOUT[7] ^ xor;
-			NdisMoveMemory(&R[8 * i], &BOUT[8], 8);
-		}
-	}
-
-	/* Output ciphertext */
-	NdisMoveMemory(ciphertext, A, 8);
-
-	for (i = 1; i <= num_blocks; i++) {
-		for (j = 0; j < 8; j++)
-			ciphertext[8 * i + j] = R[8 * i + j];
-	}
-}
-
-/*
-	========================================================================
-
-	Routine Description:
-		Misc function to decrypt AES body
-
-	Arguments:
-
-	Return Value:
-
-	Note:
-		This function references to	RFC	3394 for aes key unwrap algorithm.
-
-	========================================================================
-*/
-void AES_GTK_KEY_UNWRAP(u8 * key,
-			u8 * plaintext,
-			u32 c_len, u8 * ciphertext)
-{
-	u8 A[8], BIN[16], BOUT[16];
-	u8 xor;
-	int i, j;
-	struct aes_context aesctx;
-	u8 *R;
-	int num_blocks = c_len / 8;	/* unit:64bits */
-
-	os_alloc_mem(NULL, (u8 **) & R, 512);
-
-	if (R == NULL) {
-		DBGPRINT(RT_DEBUG_ERROR,
-			 ("AES_GTK_KEY_UNWRAP: no memory!\n"));
-		return;
-	}
-	/* End of if */
-	/* Initialize */
-	NdisMoveMemory(A, ciphertext, 8);
-	/*Input plaintext */
-	for (i = 0; i < (c_len - 8); i++) {
-		R[i] = ciphertext[i + 8];
-	}
-
-	rt_aes_set_key(&aesctx, key, 128);
-
-	for (j = 5; j >= 0; j--) {
-		for (i = (num_blocks - 1); i > 0; i--) {
-			xor = (num_blocks - 1) * j + i;
-			NdisMoveMemory(BIN, A, 8);
-			BIN[7] = A[7] ^ xor;
-			NdisMoveMemory(&BIN[8], &R[(i - 1) * 8], 8);
-			rt_aes_decrypt(&aesctx, BIN, BOUT);
-			NdisMoveMemory(A, &BOUT[0], 8);
-			NdisMoveMemory(&R[(i - 1) * 8], &BOUT[8], 8);
-		}
-	}
-
-	/* OUTPUT */
-	for (i = 0; i < c_len; i++) {
-		plaintext[i] = R[i];
-	}
-
-	os_free_mem(NULL, R);
-}
diff -druN linux-2.6.39-libre/drivers/staging/rt2860/common/cmm_asic.c linux-3.0-rc7-libre/drivers/staging/rt2860/common/cmm_asic.c
--- linux-2.6.39-libre/drivers/staging/rt2860/common/cmm_asic.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rt2860/common/cmm_asic.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,2565 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, 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.             *
- *                                                                       *
- *************************************************************************
-
-	Module Name:
-	cmm_asic.c
-
-	Abstract:
-	Functions used to communicate with ASIC
-
-	Revision History:
-	Who			When			What
-	--------	----------		----------------------------------------------
-*/
-
-#include "../rt_config.h"
-
-/* Reset the RFIC setting to new series */
-struct rt_rtmp_rf_regs RF2850RegTable[] = {
-/*              ch       R1              R2              R3(TX0~4=0) R4 */
-	{1, 0x98402ecc, 0x984c0786, 0x9816b455, 0x9800510b}
-	,
-	{2, 0x98402ecc, 0x984c0786, 0x98168a55, 0x9800519f}
-	,
-	{3, 0x98402ecc, 0x984c078a, 0x98168a55, 0x9800518b}
-	,
-	{4, 0x98402ecc, 0x984c078a, 0x98168a55, 0x9800519f}
-	,
-	{5, 0x98402ecc, 0x984c078e, 0x98168a55, 0x9800518b}
-	,
-	{6, 0x98402ecc, 0x984c078e, 0x98168a55, 0x9800519f}
-	,
-	{7, 0x98402ecc, 0x984c0792, 0x98168a55, 0x9800518b}
-	,
-	{8, 0x98402ecc, 0x984c0792, 0x98168a55, 0x9800519f}
-	,
-	{9, 0x98402ecc, 0x984c0796, 0x98168a55, 0x9800518b}
-	,
-	{10, 0x98402ecc, 0x984c0796, 0x98168a55, 0x9800519f}
-	,
-	{11, 0x98402ecc, 0x984c079a, 0x98168a55, 0x9800518b}
-	,
-	{12, 0x98402ecc, 0x984c079a, 0x98168a55, 0x9800519f}
-	,
-	{13, 0x98402ecc, 0x984c079e, 0x98168a55, 0x9800518b}
-	,
-	{14, 0x98402ecc, 0x984c07a2, 0x98168a55, 0x98005193}
-	,
-
-	/* 802.11 UNI / HyperLan 2 */
-	{36, 0x98402ecc, 0x984c099a, 0x98158a55, 0x980ed1a3}
-	,
-	{38, 0x98402ecc, 0x984c099e, 0x98158a55, 0x980ed193}
-	,
-	{40, 0x98402ec8, 0x984c0682, 0x98158a55, 0x980ed183}
-	,
-	{44, 0x98402ec8, 0x984c0682, 0x98158a55, 0x980ed1a3}
-	,
-	{46, 0x98402ec8, 0x984c0686, 0x98158a55, 0x980ed18b}
-	,
-	{48, 0x98402ec8, 0x984c0686, 0x98158a55, 0x980ed19b}
-	,
-	{52, 0x98402ec8, 0x984c068a, 0x98158a55, 0x980ed193}
-	,
-	{54, 0x98402ec8, 0x984c068a, 0x98158a55, 0x980ed1a3}
-	,
-	{56, 0x98402ec8, 0x984c068e, 0x98158a55, 0x980ed18b}
-	,
-	{60, 0x98402ec8, 0x984c0692, 0x98158a55, 0x980ed183}
-	,
-	{62, 0x98402ec8, 0x984c0692, 0x98158a55, 0x980ed193}
-	,
-	{64, 0x98402ec8, 0x984c0692, 0x98158a55, 0x980ed1a3}
-	,			/* Plugfest#4, Day4, change RFR3 left4th 9->5. */
-
-	/* 802.11 HyperLan 2 */
-	{100, 0x98402ec8, 0x984c06b2, 0x98178a55, 0x980ed783}
-	,
-
-	/* 2008.04.30 modified */
-	/* The system team has AN to improve the EVM value */
-	/* for channel 102 to 108 for the RT2850/RT2750 dual band solution. */
-	{102, 0x98402ec8, 0x985c06b2, 0x98578a55, 0x980ed793}
-	,
-	{104, 0x98402ec8, 0x985c06b2, 0x98578a55, 0x980ed1a3}
-	,
-	{108, 0x98402ecc, 0x985c0a32, 0x98578a55, 0x980ed193}
-	,
-
-	{110, 0x98402ecc, 0x984c0a36, 0x98178a55, 0x980ed183}
-	,
-	{112, 0x98402ecc, 0x984c0a36, 0x98178a55, 0x980ed19b}
-	,
-	{116, 0x98402ecc, 0x984c0a3a, 0x98178a55, 0x980ed1a3}
-	,
-	{118, 0x98402ecc, 0x984c0a3e, 0x98178a55, 0x980ed193}
-	,
-	{120, 0x98402ec4, 0x984c0382, 0x98178a55, 0x980ed183}
-	,
-	{124, 0x98402ec4, 0x984c0382, 0x98178a55, 0x980ed193}
-	,
-	{126, 0x98402ec4, 0x984c0382, 0x98178a55, 0x980ed15b}
-	,			/* 0x980ed1bb->0x980ed15b required by Rory 20070927 */
-	{128, 0x98402ec4, 0x984c0382, 0x98178a55, 0x980ed1a3}
-	,
-	{132, 0x98402ec4, 0x984c0386, 0x98178a55, 0x980ed18b}
-	,
-	{134, 0x98402ec4, 0x984c0386, 0x98178a55, 0x980ed193}
-	,
-	{136, 0x98402ec4, 0x984c0386, 0x98178a55, 0x980ed19b}
-	,
-	{140, 0x98402ec4, 0x984c038a, 0x98178a55, 0x980ed183}
-	,
-
-	/* 802.11 UNII */
-	{149, 0x98402ec4, 0x984c038a, 0x98178a55, 0x980ed1a7}
-	,
-	{151, 0x98402ec4, 0x984c038e, 0x98178a55, 0x980ed187}
-	,
-	{153, 0x98402ec4, 0x984c038e, 0x98178a55, 0x980ed18f}
-	,
-	{157, 0x98402ec4, 0x984c038e, 0x98178a55, 0x980ed19f}
-	,
-	{159, 0x98402ec4, 0x984c038e, 0x98178a55, 0x980ed1a7}
-	,
-	{161, 0x98402ec4, 0x984c0392, 0x98178a55, 0x980ed187}
-	,
-	{165, 0x98402ec4, 0x984c0392, 0x98178a55, 0x980ed197}
-	,
-	{167, 0x98402ec4, 0x984c03d2, 0x98179855, 0x9815531f}
-	,
-	{169, 0x98402ec4, 0x984c03d2, 0x98179855, 0x98155327}
-	,
-	{171, 0x98402ec4, 0x984c03d6, 0x98179855, 0x98155307}
-	,
-	{173, 0x98402ec4, 0x984c03d6, 0x98179855, 0x9815530f}
-	,
-
-	/* Japan */
-	{184, 0x95002ccc, 0x9500491e, 0x9509be55, 0x950c0a0b}
-	,
-	{188, 0x95002ccc, 0x95004922, 0x9509be55, 0x950c0a13}
-	,
-	{192, 0x95002ccc, 0x95004926, 0x9509be55, 0x950c0a1b}
-	,
-	{196, 0x95002ccc, 0x9500492a, 0x9509be55, 0x950c0a23}
-	,
-	{208, 0x95002ccc, 0x9500493a, 0x9509be55, 0x950c0a13}
-	,
-	{212, 0x95002ccc, 0x9500493e, 0x9509be55, 0x950c0a1b}
-	,
-	{216, 0x95002ccc, 0x95004982, 0x9509be55, 0x950c0a23}
-	,
-
-	/* still lack of MMAC(Japan) ch 34,38,42,46 */
-};
-
-u8 NUM_OF_2850_CHNL = (sizeof(RF2850RegTable) / sizeof(struct rt_rtmp_rf_regs));
-
-struct rt_frequency_item FreqItems3020[] = {
-	/**************************************************/
-	/* ISM : 2.4 to 2.483 GHz                         // */
-	/**************************************************/
-	/* 11g */
-	/**************************************************/
-	/*-CH---N-------R---K----------- */
-	{1, 241, 2, 2}
-	,
-	{2, 241, 2, 7}
-	,
-	{3, 242, 2, 2}
-	,
-	{4, 242, 2, 7}
-	,
-	{5, 243, 2, 2}
-	,
-	{6, 243, 2, 7}
-	,
-	{7, 244, 2, 2}
-	,
-	{8, 244, 2, 7}
-	,
-	{9, 245, 2, 2}
-	,
-	{10, 245, 2, 7}
-	,
-	{11, 246, 2, 2}
-	,
-	{12, 246, 2, 7}
-	,
-	{13, 247, 2, 2}
-	,
-	{14, 248, 2, 4}
-	,
-};
-
-u8 NUM_OF_3020_CHNL = (sizeof(FreqItems3020) / sizeof(struct rt_frequency_item));
-
-void AsicUpdateAutoFallBackTable(struct rt_rtmp_adapter *pAd, u8 *pRateTable)
-{
-	u8 i;
-	HT_FBK_CFG0_STRUC HtCfg0;
-	HT_FBK_CFG1_STRUC HtCfg1;
-	LG_FBK_CFG0_STRUC LgCfg0;
-	LG_FBK_CFG1_STRUC LgCfg1;
-	struct rt_rtmp_tx_rate_switch *pCurrTxRate, *pNextTxRate;
-
-	/* set to initial value */
-	HtCfg0.word = 0x65432100;
-	HtCfg1.word = 0xedcba988;
-	LgCfg0.word = 0xedcba988;
-	LgCfg1.word = 0x00002100;
-
-	pNextTxRate = (struct rt_rtmp_tx_rate_switch *) pRateTable + 1;
-	for (i = 1; i < *((u8 *)pRateTable); i++) {
-		pCurrTxRate = (struct rt_rtmp_tx_rate_switch *) pRateTable + 1 + i;
-		switch (pCurrTxRate->Mode) {
-		case 0:	/*CCK */
-			break;
-		case 1:	/*OFDM */
-			{
-				switch (pCurrTxRate->CurrMCS) {
-				case 0:
-					LgCfg0.field.OFDMMCS0FBK =
-					    (pNextTxRate->Mode ==
-					     MODE_OFDM) ? (pNextTxRate->
-							   CurrMCS +
-							   8) : pNextTxRate->
-					    CurrMCS;
-					break;
-				case 1:
-					LgCfg0.field.OFDMMCS1FBK =
-					    (pNextTxRate->Mode ==
-					     MODE_OFDM) ? (pNextTxRate->
-							   CurrMCS +
-							   8) : pNextTxRate->
-					    CurrMCS;
-					break;
-				case 2:
-					LgCfg0.field.OFDMMCS2FBK =
-					    (pNextTxRate->Mode ==
-					     MODE_OFDM) ? (pNextTxRate->
-							   CurrMCS +
-							   8) : pNextTxRate->
-					    CurrMCS;
-					break;
-				case 3:
-					LgCfg0.field.OFDMMCS3FBK =
-					    (pNextTxRate->Mode ==
-					     MODE_OFDM) ? (pNextTxRate->
-							   CurrMCS +
-							   8) : pNextTxRate->
-					    CurrMCS;
-					break;
-				case 4:
-					LgCfg0.field.OFDMMCS4FBK =
-					    (pNextTxRate->Mode ==
-					     MODE_OFDM) ? (pNextTxRate->
-							   CurrMCS +
-							   8) : pNextTxRate->
-					    CurrMCS;
-					break;
-				case 5:
-					LgCfg0.field.OFDMMCS5FBK =
-					    (pNextTxRate->Mode ==
-					     MODE_OFDM) ? (pNextTxRate->
-							   CurrMCS +
-							   8) : pNextTxRate->
-					    CurrMCS;
-					break;
-				case 6:
-					LgCfg0.field.OFDMMCS6FBK =
-					    (pNextTxRate->Mode ==
-					     MODE_OFDM) ? (pNextTxRate->
-							   CurrMCS +
-							   8) : pNextTxRate->
-					    CurrMCS;
-					break;
-				case 7:
-					LgCfg0.field.OFDMMCS7FBK =
-					    (pNextTxRate->Mode ==
-					     MODE_OFDM) ? (pNextTxRate->
-							   CurrMCS +
-							   8) : pNextTxRate->
-					    CurrMCS;
-					break;
-				}
-			}
-			break;
-		case 2:	/*HT-MIX */
-		case 3:	/*HT-GF */
-			{
-				if ((pNextTxRate->Mode >= MODE_HTMIX)
-				    && (pCurrTxRate->CurrMCS !=
-					pNextTxRate->CurrMCS)) {
-					switch (pCurrTxRate->CurrMCS) {
-					case 0:
-						HtCfg0.field.HTMCS0FBK =
-						    pNextTxRate->CurrMCS;
-						break;
-					case 1:
-						HtCfg0.field.HTMCS1FBK =
-						    pNextTxRate->CurrMCS;
-						break;
-					case 2:
-						HtCfg0.field.HTMCS2FBK =
-						    pNextTxRate->CurrMCS;
-						break;
-					case 3:
-						HtCfg0.field.HTMCS3FBK =
-						    pNextTxRate->CurrMCS;
-						break;
-					case 4:
-						HtCfg0.field.HTMCS4FBK =
-						    pNextTxRate->CurrMCS;
-						break;
-					case 5:
-						HtCfg0.field.HTMCS5FBK =
-						    pNextTxRate->CurrMCS;
-						break;
-					case 6:
-						HtCfg0.field.HTMCS6FBK =
-						    pNextTxRate->CurrMCS;
-						break;
-					case 7:
-						HtCfg0.field.HTMCS7FBK =
-						    pNextTxRate->CurrMCS;
-						break;
-					case 8:
-						HtCfg1.field.HTMCS8FBK =
-						    pNextTxRate->CurrMCS;
-						break;
-					case 9:
-						HtCfg1.field.HTMCS9FBK =
-						    pNextTxRate->CurrMCS;
-						break;
-					case 10:
-						HtCfg1.field.HTMCS10FBK =
-						    pNextTxRate->CurrMCS;
-						break;
-					case 11:
-						HtCfg1.field.HTMCS11FBK =
-						    pNextTxRate->CurrMCS;
-						break;
-					case 12:
-						HtCfg1.field.HTMCS12FBK =
-						    pNextTxRate->CurrMCS;
-						break;
-					case 13:
-						HtCfg1.field.HTMCS13FBK =
-						    pNextTxRate->CurrMCS;
-						break;
-					case 14:
-						HtCfg1.field.HTMCS14FBK =
-						    pNextTxRate->CurrMCS;
-						break;
-					case 15:
-						HtCfg1.field.HTMCS15FBK =
-						    pNextTxRate->CurrMCS;
-						break;
-					default:
-						DBGPRINT(RT_DEBUG_ERROR,
-							 ("AsicUpdateAutoFallBackTable: not support CurrMCS=%d\n",
-							  pCurrTxRate->
-							  CurrMCS));
-					}
-				}
-			}
-			break;
-		}
-
-		pNextTxRate = pCurrTxRate;
-	}
-
-	RTMP_IO_WRITE32(pAd, HT_FBK_CFG0, HtCfg0.word);
-	RTMP_IO_WRITE32(pAd, HT_FBK_CFG1, HtCfg1.word);
-	RTMP_IO_WRITE32(pAd, LG_FBK_CFG0, LgCfg0.word);
-	RTMP_IO_WRITE32(pAd, LG_FBK_CFG1, LgCfg1.word);
-}
-
-/*
-	========================================================================
-
-	Routine Description:
-		Set MAC register value according operation mode.
-		OperationMode AND bNonGFExist are for MM and GF Proteciton.
-		If MM or GF mask is not set, those passing argument doesn't not take effect.
-
-		Operation mode meaning:
-		= 0 : Pure HT, no preotection.
-		= 0x01; there may be non-HT devices in both the control and extension channel, protection is optional in BSS.
-		= 0x10: No Transmission in 40M is protected.
-		= 0x11: Transmission in both 40M and 20M shall be protected
-		if (bNonGFExist)
-			we should choose not to use GF. But still set correct ASIC registers.
-	========================================================================
-*/
-void AsicUpdateProtect(struct rt_rtmp_adapter *pAd,
-		       u16 OperationMode,
-		       u8 SetMask,
-		       IN BOOLEAN bDisableBGProtect, IN BOOLEAN bNonGFExist)
-{
-	PROT_CFG_STRUC ProtCfg, ProtCfg4;
-	u32 Protect[6];
-	u16 offset;
-	u8 i;
-	u32 MacReg = 0;
-
-	if (!(pAd->CommonCfg.bHTProtect) && (OperationMode != 8)) {
-		return;
-	}
-
-	if (pAd->BATable.numDoneOriginator) {
-		/* */
-		/* enable the RTS/CTS to avoid channel collision */
-		/* */
-		SetMask = ALLN_SETPROTECT;
-		OperationMode = 8;
-	}
-	/* Config ASIC RTS threshold register */
-	RTMP_IO_READ32(pAd, TX_RTS_CFG, &MacReg);
-	MacReg &= 0xFF0000FF;
-	/* If the user want disable RtsThreshold and enable Amsdu/Ralink-Aggregation, set the RtsThreshold as 4096 */
-	if (((pAd->CommonCfg.BACapability.field.AmsduEnable) ||
-	     (pAd->CommonCfg.bAggregationCapable == TRUE))
-	    && pAd->CommonCfg.RtsThreshold == MAX_RTS_THRESHOLD) {
-		MacReg |= (0x1000 << 8);
-	} else {
-		MacReg |= (pAd->CommonCfg.RtsThreshold << 8);
-	}
-
-	RTMP_IO_WRITE32(pAd, TX_RTS_CFG, MacReg);
-
-	/* Initial common protection settings */
-	RTMPZeroMemory(Protect, sizeof(Protect));
-	ProtCfg4.word = 0;
-	ProtCfg.word = 0;
-	ProtCfg.field.TxopAllowGF40 = 1;
-	ProtCfg.field.TxopAllowGF20 = 1;
-	ProtCfg.field.TxopAllowMM40 = 1;
-	ProtCfg.field.TxopAllowMM20 = 1;
-	ProtCfg.field.TxopAllowOfdm = 1;
-	ProtCfg.field.TxopAllowCck = 1;
-	ProtCfg.field.RTSThEn = 1;
-	ProtCfg.field.ProtectNav = ASIC_SHORTNAV;
-
-	/* update PHY mode and rate */
-	if (pAd->CommonCfg.Channel > 14)
-		ProtCfg.field.ProtectRate = 0x4000;
-	ProtCfg.field.ProtectRate |= pAd->CommonCfg.RtsRate;
-
-	/* Handle legacy(B/G) protection */
-	if (bDisableBGProtect) {
-		/*ProtCfg.field.ProtectRate = pAd->CommonCfg.RtsRate; */
-		ProtCfg.field.ProtectCtrl = 0;
-		Protect[0] = ProtCfg.word;
-		Protect[1] = ProtCfg.word;
-		pAd->FlgCtsEnabled = 0;	/* CTS-self is not used */
-	} else {
-		/*ProtCfg.field.ProtectRate = pAd->CommonCfg.RtsRate; */
-		ProtCfg.field.ProtectCtrl = 0;	/* CCK do not need to be protected */
-		Protect[0] = ProtCfg.word;
-		ProtCfg.field.ProtectCtrl = ASIC_CTS;	/* OFDM needs using CCK to protect */
-		Protect[1] = ProtCfg.word;
-		pAd->FlgCtsEnabled = 1;	/* CTS-self is used */
-	}
-
-	/* Decide HT frame protection. */
-	if ((SetMask & ALLN_SETPROTECT) != 0) {
-		switch (OperationMode) {
-		case 0x0:
-			/* NO PROTECT */
-			/* 1.All STAs in the BSS are 20/40 MHz HT */
-			/* 2. in ai 20/40MHz BSS */
-			/* 3. all STAs are 20MHz in a 20MHz BSS */
-			/* Pure HT. no protection. */
-
-			/* MM20_PROT_CFG */
-			/*      Reserved (31:27) */
-			/*      PROT_TXOP(25:20) -- 010111 */
-			/*      PROT_NAV(19:18)  -- 01 (Short NAV protection) */
-			/*  PROT_CTRL(17:16) -- 00 (None) */
-			/*      PROT_RATE(15:0)  -- 0x4004 (OFDM 24M) */
-			Protect[2] = 0x01744004;
-
-			/* MM40_PROT_CFG */
-			/*      Reserved (31:27) */
-			/*      PROT_TXOP(25:20) -- 111111 */
-			/*      PROT_NAV(19:18)  -- 01 (Short NAV protection) */
-			/*  PROT_CTRL(17:16) -- 00 (None) */
-			/*      PROT_RATE(15:0)  -- 0x4084 (duplicate OFDM 24M) */
-			Protect[3] = 0x03f44084;
-
-			/* CF20_PROT_CFG */
-			/*      Reserved (31:27) */
-			/*      PROT_TXOP(25:20) -- 010111 */
-			/*      PROT_NAV(19:18)  -- 01 (Short NAV protection) */
-			/*  PROT_CTRL(17:16) -- 00 (None) */
-			/*      PROT_RATE(15:0)  -- 0x4004 (OFDM 24M) */
-			Protect[4] = 0x01744004;
-
-			/* CF40_PROT_CFG */
-			/*      Reserved (31:27) */
-			/*      PROT_TXOP(25:20) -- 111111 */
-			/*      PROT_NAV(19:18)  -- 01 (Short NAV protection) */
-			/*  PROT_CTRL(17:16) -- 00 (None) */
-			/*      PROT_RATE(15:0)  -- 0x4084 (duplicate OFDM 24M) */
-			Protect[5] = 0x03f44084;
-
-			if (bNonGFExist) {
-				/* PROT_NAV(19:18)  -- 01 (Short NAV protectiion) */
-				/* PROT_CTRL(17:16) -- 01 (RTS/CTS) */
-				Protect[4] = 0x01754004;
-				Protect[5] = 0x03f54084;
-			}
-			pAd->CommonCfg.IOTestParm.bRTSLongProtOn = FALSE;
-			break;
-
-		case 1:
-			/* This is "HT non-member protection mode." */
-			/* If there may be non-HT STAs my BSS */
-			ProtCfg.word = 0x01744004;	/* PROT_CTRL(17:16) : 0 (None) */
-			ProtCfg4.word = 0x03f44084;	/* duplicaet legacy 24M. BW set 1. */
-			if (OPSTATUS_TEST_FLAG
-			    (pAd, fOP_STATUS_BG_PROTECTION_INUSED)) {
-				ProtCfg.word = 0x01740003;	/*ERP use Protection bit is set, use protection rate at Clause 18.. */
-				ProtCfg4.word = 0x03f40003;	/* Don't duplicate RTS/CTS in CCK mode. 0x03f40083; */
-			}
-			/*Assign Protection method for 20&40 MHz packets */
-			ProtCfg.field.ProtectCtrl = ASIC_RTS;
-			ProtCfg.field.ProtectNav = ASIC_SHORTNAV;
-			ProtCfg4.field.ProtectCtrl = ASIC_RTS;
-			ProtCfg4.field.ProtectNav = ASIC_SHORTNAV;
-			Protect[2] = ProtCfg.word;
-			Protect[3] = ProtCfg4.word;
-			Protect[4] = ProtCfg.word;
-			Protect[5] = ProtCfg4.word;
-			pAd->CommonCfg.IOTestParm.bRTSLongProtOn = TRUE;
-			break;
-
-		case 2:
-			/* If only HT STAs are in BSS. at least one is 20MHz. Only protect 40MHz packets */
-			ProtCfg.word = 0x01744004;	/* PROT_CTRL(17:16) : 0 (None) */
-			ProtCfg4.word = 0x03f44084;	/* duplicaet legacy 24M. BW set 1. */
-
-			/*Assign Protection method for 40MHz packets */
-			ProtCfg4.field.ProtectCtrl = ASIC_RTS;
-			ProtCfg4.field.ProtectNav = ASIC_SHORTNAV;
-			Protect[2] = ProtCfg.word;
-			Protect[3] = ProtCfg4.word;
-			if (bNonGFExist) {
-				ProtCfg.field.ProtectCtrl = ASIC_RTS;
-				ProtCfg.field.ProtectNav = ASIC_SHORTNAV;
-			}
-			Protect[4] = ProtCfg.word;
-			Protect[5] = ProtCfg4.word;
-
-			pAd->CommonCfg.IOTestParm.bRTSLongProtOn = FALSE;
-			break;
-
-		case 3:
-			/* HT mixed mode.        PROTECT ALL! */
-			/* Assign Rate */
-			ProtCfg.word = 0x01744004;	/*duplicaet legacy 24M. BW set 1. */
-			ProtCfg4.word = 0x03f44084;
-			/* both 20MHz and 40MHz are protected. Whether use RTS or CTS-to-self depends on the */
-			if (OPSTATUS_TEST_FLAG
-			    (pAd, fOP_STATUS_BG_PROTECTION_INUSED)) {
-				ProtCfg.word = 0x01740003;	/*ERP use Protection bit is set, use protection rate at Clause 18.. */
-				ProtCfg4.word = 0x03f40003;	/* Don't duplicate RTS/CTS in CCK mode. 0x03f40083 */
-			}
-			/*Assign Protection method for 20&40 MHz packets */
-			ProtCfg.field.ProtectCtrl = ASIC_RTS;
-			ProtCfg.field.ProtectNav = ASIC_SHORTNAV;
-			ProtCfg4.field.ProtectCtrl = ASIC_RTS;
-			ProtCfg4.field.ProtectNav = ASIC_SHORTNAV;
-			Protect[2] = ProtCfg.word;
-			Protect[3] = ProtCfg4.word;
-			Protect[4] = ProtCfg.word;
-			Protect[5] = ProtCfg4.word;
-			pAd->CommonCfg.IOTestParm.bRTSLongProtOn = TRUE;
-			break;
-
-		case 8:
-			/* Special on for Atheros problem n chip. */
-			Protect[2] = 0x01754004;
-			Protect[3] = 0x03f54084;
-			Protect[4] = 0x01754004;
-			Protect[5] = 0x03f54084;
-			pAd->CommonCfg.IOTestParm.bRTSLongProtOn = TRUE;
-			break;
-		}
-	}
-
-	offset = CCK_PROT_CFG;
-	for (i = 0; i < 6; i++) {
-		if ((SetMask & (1 << i))) {
-			RTMP_IO_WRITE32(pAd, offset + i * 4, Protect[i]);
-		}
-	}
-}
-
-/*
-	==========================================================================
-	Description:
-
-	IRQL = PASSIVE_LEVEL
-	IRQL = DISPATCH_LEVEL
-
-	==========================================================================
- */
-void AsicSwitchChannel(struct rt_rtmp_adapter *pAd, u8 Channel, IN BOOLEAN bScan)
-{
-	unsigned long R2 = 0, R3 = DEFAULT_RF_TX_POWER, R4 = 0;
-	char TxPwer = 0, TxPwer2 = DEFAULT_RF_TX_POWER;	/*Bbp94 = BBPR94_DEFAULT, TxPwer2 = DEFAULT_RF_TX_POWER; */
-	u8 index;
-	u32 Value = 0;	/*BbpReg, Value; */
-	struct rt_rtmp_rf_regs *RFRegTable;
-	u8 RFValue;
-
-	RFValue = 0;
-	/* Search Tx power value */
-	/* We can't use ChannelList to search channel, since some central channl's txpowr doesn't list */
-	/* in ChannelList, so use TxPower array instead. */
-	/* */
-	for (index = 0; index < MAX_NUM_OF_CHANNELS; index++) {
-		if (Channel == pAd->TxPower[index].Channel) {
-			TxPwer = pAd->TxPower[index].Power;
-			TxPwer2 = pAd->TxPower[index].Power2;
-			break;
-		}
-	}
-
-	if (index == MAX_NUM_OF_CHANNELS) {
-		DBGPRINT(RT_DEBUG_ERROR,
-			 ("AsicSwitchChannel: Can't find the Channel#%d \n",
-			  Channel));
-	}
-#ifdef RT30xx
-	/* The RF programming sequence is difference between 3xxx and 2xxx */
-	if ((IS_RT3070(pAd) || IS_RT3090(pAd) || IS_RT3390(pAd))
-	    && ((pAd->RfIcType == RFIC_3020) || (pAd->RfIcType == RFIC_2020)
-		|| (pAd->RfIcType == RFIC_3021)
-		|| (pAd->RfIcType == RFIC_3022))) {
-		/* modify by WY for Read RF Reg. error */
-
-		for (index = 0; index < NUM_OF_3020_CHNL; index++) {
-			if (Channel == FreqItems3020[index].Channel) {
-				/* Programming channel parameters */
-				RT30xxWriteRFRegister(pAd, RF_R02,
-						      FreqItems3020[index].N);
-				RT30xxWriteRFRegister(pAd, RF_R03,
-						      FreqItems3020[index].K);
-				RT30xxReadRFRegister(pAd, RF_R06, &RFValue);
-				RFValue =
-				    (RFValue & 0xFC) | FreqItems3020[index].R;
-				RT30xxWriteRFRegister(pAd, RF_R06, RFValue);
-
-				/* Set Tx0 Power */
-				RT30xxReadRFRegister(pAd, RF_R12, &RFValue);
-				RFValue = (RFValue & 0xE0) | TxPwer;
-				RT30xxWriteRFRegister(pAd, RF_R12, RFValue);
-
-				/* Set Tx1 Power */
-				RT30xxReadRFRegister(pAd, RF_R13, &RFValue);
-				RFValue = (RFValue & 0xE0) | TxPwer2;
-				RT30xxWriteRFRegister(pAd, RF_R13, RFValue);
-
-				/* Tx/Rx Stream setting */
-				RT30xxReadRFRegister(pAd, RF_R01, &RFValue);
-				/*if (IS_RT3090(pAd)) */
-				/*      RFValue |= 0x01; // Enable RF block. */
-				RFValue &= 0x03;	/*clear bit[7~2] */
-				if (pAd->Antenna.field.TxPath == 1)
-					RFValue |= 0xA0;
-				else if (pAd->Antenna.field.TxPath == 2)
-					RFValue |= 0x80;
-				if (pAd->Antenna.field.RxPath == 1)
-					RFValue |= 0x50;
-				else if (pAd->Antenna.field.RxPath == 2)
-					RFValue |= 0x40;
-				RT30xxWriteRFRegister(pAd, RF_R01, RFValue);
-
-				/* Set RF offset */
-				RT30xxReadRFRegister(pAd, RF_R23, &RFValue);
-				RFValue = (RFValue & 0x80) | pAd->RfFreqOffset;
-				RT30xxWriteRFRegister(pAd, RF_R23, RFValue);
-
-				/* Set BW */
-				if (!bScan
-				    && (pAd->CommonCfg.BBPCurrentBW == BW_40)) {
-					RFValue = pAd->Mlme.CaliBW40RfR24;
-					/*DISABLE_11N_CHECK(pAd); */
-				} else {
-					RFValue = pAd->Mlme.CaliBW20RfR24;
-				}
-				RT30xxWriteRFRegister(pAd, RF_R24, RFValue);
-				RT30xxWriteRFRegister(pAd, RF_R31, RFValue);
-
-				/* Enable RF tuning */
-				RT30xxReadRFRegister(pAd, RF_R07, &RFValue);
-				RFValue = RFValue | 0x1;
-				RT30xxWriteRFRegister(pAd, RF_R07, RFValue);
-
-				/* latch channel for future usage. */
-				pAd->LatchRfRegs.Channel = Channel;
-
-				DBGPRINT(RT_DEBUG_TRACE,
-					 ("SwitchChannel#%d(RF=%d, Pwr0=%d, Pwr1=%d, %dT), N=0x%02X, K=0x%02X, R=0x%02X\n",
-					  Channel, pAd->RfIcType, TxPwer,
-					  TxPwer2, pAd->Antenna.field.TxPath,
-					  FreqItems3020[index].N,
-					  FreqItems3020[index].K,
-					  FreqItems3020[index].R));
-
-				break;
-			}
-		}
-	} else
-#endif /* RT30xx // */
-	{
-		RFRegTable = RF2850RegTable;
-		switch (pAd->RfIcType) {
-		case RFIC_2820:
-		case RFIC_2850:
-		case RFIC_2720:
-		case RFIC_2750:
-
-			for (index = 0; index < NUM_OF_2850_CHNL; index++) {
-				if (Channel == RFRegTable[index].Channel) {
-					R2 = RFRegTable[index].R2;
-					if (pAd->Antenna.field.TxPath == 1) {
-						R2 |= 0x4000;	/* If TXpath is 1, bit 14 = 1; */
-					}
-
-					if (pAd->Antenna.field.RxPath == 2) {
-						R2 |= 0x40;	/* write 1 to off Rxpath. */
-					} else if (pAd->Antenna.field.RxPath ==
-						   1) {
-						R2 |= 0x20040;	/* write 1 to off RxPath */
-					}
-
-					if (Channel > 14) {
-						/* initialize R3, R4 */
-						R3 = (RFRegTable[index].
-						      R3 & 0xffffc1ff);
-						R4 = (RFRegTable[index].
-						      R4 & (~0x001f87c0)) |
-						    (pAd->RfFreqOffset << 15);
-
-						/* 5G band power range: 0xF9~0X0F, TX0 Reg3 bit9/TX1 Reg4 bit6="0" means the TX power reduce 7dB */
-						/* R3 */
-						if ((TxPwer >= -7)
-						    && (TxPwer < 0)) {
-							TxPwer = (7 + TxPwer);
-							TxPwer =
-							    (TxPwer >
-							     0xF) ? (0xF)
-							    : (TxPwer);
-							R3 |= (TxPwer << 10);
-							DBGPRINT(RT_DEBUG_ERROR,
-								 ("AsicSwitchChannel: TxPwer=%d \n",
-								  TxPwer));
-						} else {
-							TxPwer =
-							    (TxPwer >
-							     0xF) ? (0xF)
-							    : (TxPwer);
-							R3 |=
-							    (TxPwer << 10) | (1
-									      <<
-									      9);
-						}
-
-						/* R4 */
-						if ((TxPwer2 >= -7)
-						    && (TxPwer2 < 0)) {
-							TxPwer2 = (7 + TxPwer2);
-							TxPwer2 =
-							    (TxPwer2 >
-							     0xF) ? (0xF)
-							    : (TxPwer2);
-							R4 |= (TxPwer2 << 7);
-							DBGPRINT(RT_DEBUG_ERROR,
-								 ("AsicSwitchChannel: TxPwer2=%d \n",
-								  TxPwer2));
-						} else {
-							TxPwer2 =
-							    (TxPwer2 >
-							     0xF) ? (0xF)
-							    : (TxPwer2);
-							R4 |=
-							    (TxPwer2 << 7) | (1
-									      <<
-									      6);
-						}
-					} else {
-						R3 = (RFRegTable[index].R3 & 0xffffc1ff) | (TxPwer << 9);	/* set TX power0 */
-						R4 = (RFRegTable[index].R4 & (~0x001f87c0)) | (pAd->RfFreqOffset << 15) | (TxPwer2 << 6);	/* Set freq Offset & TxPwr1 */
-					}
-
-					/* Based on BBP current mode before changing RF channel. */
-					if (!bScan
-					    && (pAd->CommonCfg.BBPCurrentBW ==
-						BW_40)) {
-						R4 |= 0x200000;
-					}
-					/* Update variables */
-					pAd->LatchRfRegs.Channel = Channel;
-					pAd->LatchRfRegs.R1 =
-					    RFRegTable[index].R1;
-					pAd->LatchRfRegs.R2 = R2;
-					pAd->LatchRfRegs.R3 = R3;
-					pAd->LatchRfRegs.R4 = R4;
-
-					/* Set RF value 1's set R3[bit2] = [0] */
-					RTMP_RF_IO_WRITE32(pAd,
-							   pAd->LatchRfRegs.R1);
-					RTMP_RF_IO_WRITE32(pAd,
-							   pAd->LatchRfRegs.R2);
-					RTMP_RF_IO_WRITE32(pAd,
-							   (pAd->LatchRfRegs.
-							    R3 & (~0x04)));
-					RTMP_RF_IO_WRITE32(pAd,
-							   pAd->LatchRfRegs.R4);
-
-					RTMPusecDelay(200);
-
-					/* Set RF value 2's set R3[bit2] = [1] */
-					RTMP_RF_IO_WRITE32(pAd,
-							   pAd->LatchRfRegs.R1);
-					RTMP_RF_IO_WRITE32(pAd,
-							   pAd->LatchRfRegs.R2);
-					RTMP_RF_IO_WRITE32(pAd,
-							   (pAd->LatchRfRegs.
-							    R3 | 0x04));
-					RTMP_RF_IO_WRITE32(pAd,
-							   pAd->LatchRfRegs.R4);
-
-					RTMPusecDelay(200);
-
-					/* Set RF value 3's set R3[bit2] = [0] */
-					RTMP_RF_IO_WRITE32(pAd,
-							   pAd->LatchRfRegs.R1);
-					RTMP_RF_IO_WRITE32(pAd,
-							   pAd->LatchRfRegs.R2);
-					RTMP_RF_IO_WRITE32(pAd,
-							   (pAd->LatchRfRegs.
-							    R3 & (~0x04)));
-					RTMP_RF_IO_WRITE32(pAd,
-							   pAd->LatchRfRegs.R4);
-
-					break;
-				}
-			}
-			break;
-
-		default:
-			break;
-		}
-
-		DBGPRINT(RT_DEBUG_TRACE,
-			 ("SwitchChannel#%d(RF=%d, Pwr0=%lu, Pwr1=%lu, %dT) to , R1=0x%08lx, R2=0x%08lx, R3=0x%08lx, R4=0x%08lx\n",
-			  Channel, pAd->RfIcType, (R3 & 0x00003e00) >> 9,
-			  (R4 & 0x000007c0) >> 6, pAd->Antenna.field.TxPath,
-			  pAd->LatchRfRegs.R1, pAd->LatchRfRegs.R2,
-			  pAd->LatchRfRegs.R3, pAd->LatchRfRegs.R4));
-	}
-
-	/* Change BBP setting during siwtch from a->g, g->a */
-	if (Channel <= 14) {
-		unsigned long TxPinCfg = 0x00050F0A;	/*Gary 2007/08/09 0x050A0A */
-
-		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R62,
-					     (0x37 - GET_LNA_GAIN(pAd)));
-		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R63,
-					     (0x37 - GET_LNA_GAIN(pAd)));
-		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R64,
-					     (0x37 - GET_LNA_GAIN(pAd)));
-		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R86, 0);	/*(0x44 - GET_LNA_GAIN(pAd)));    // According the Rory's suggestion to solve the middle range issue. */
-		/*RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R82, 0x62); */
-
-		/* Rx High power VGA offset for LNA select */
-		if (pAd->NicConfig2.field.ExternalLNAForG) {
-			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R82, 0x62);
-			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R75, 0x46);
-		} else {
-			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R82, 0x84);
-			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R75, 0x50);
-		}
-
-		/* 5G band selection PIN, bit1 and bit2 are complement */
-		RTMP_IO_READ32(pAd, TX_BAND_CFG, &Value);
-		Value &= (~0x6);
-		Value |= (0x04);
-		RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Value);
-
-		/* Turn off unused PA or LNA when only 1T or 1R */
-		if (pAd->Antenna.field.TxPath == 1) {
-			TxPinCfg &= 0xFFFFFFF3;
-		}
-		if (pAd->Antenna.field.RxPath == 1) {
-			TxPinCfg &= 0xFFFFF3FF;
-		}
-
-		RTMP_IO_WRITE32(pAd, TX_PIN_CFG, TxPinCfg);
-
-#if defined(RT3090) || defined(RT3390)
-		/* PCIe PHY Transmit attenuation adjustment */
-		if (IS_RT3090A(pAd) || IS_RT3390(pAd)) {
-			TX_ATTENUATION_CTRL_STRUC TxAttenuationCtrl = {
-			.word = 0};
-
-			RTMP_IO_READ32(pAd, PCIE_PHY_TX_ATTENUATION_CTRL,
-				       &TxAttenuationCtrl.word);
-
-			if (Channel == 14)	/* Channel #14 */
-			{
-				TxAttenuationCtrl.field.PCIE_PHY_TX_ATTEN_EN = 1;	/* Enable PCIe PHY Tx attenuation */
-				TxAttenuationCtrl.field.PCIE_PHY_TX_ATTEN_VALUE = 4;	/* 9/16 full drive level */
-			} else	/* Channel #1~#13 */
-			{
-				TxAttenuationCtrl.field.PCIE_PHY_TX_ATTEN_EN = 0;	/* Disable PCIe PHY Tx attenuation */
-				TxAttenuationCtrl.field.PCIE_PHY_TX_ATTEN_VALUE = 0;	/* n/a */
-			}
-
-			RTMP_IO_WRITE32(pAd, PCIE_PHY_TX_ATTENUATION_CTRL,
-					TxAttenuationCtrl.word);
-		}
-#endif
-	} else {
-		unsigned long TxPinCfg = 0x00050F05;	/*Gary 2007/8/9 0x050505 */
-
-		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R62,
-					     (0x37 - GET_LNA_GAIN(pAd)));
-		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R63,
-					     (0x37 - GET_LNA_GAIN(pAd)));
-		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R64,
-					     (0x37 - GET_LNA_GAIN(pAd)));
-		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R86, 0);	/*(0x44 - GET_LNA_GAIN(pAd)));   // According the Rory's suggestion to solve the middle range issue. */
-		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R82, 0xF2);
-
-		/* Rx High power VGA offset for LNA select */
-		if (pAd->NicConfig2.field.ExternalLNAForA) {
-			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R75, 0x46);
-		} else {
-			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R75, 0x50);
-		}
-
-		/* 5G band selection PIN, bit1 and bit2 are complement */
-		RTMP_IO_READ32(pAd, TX_BAND_CFG, &Value);
-		Value &= (~0x6);
-		Value |= (0x02);
-		RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Value);
-
-		/* Turn off unused PA or LNA when only 1T or 1R */
-		if (pAd->Antenna.field.TxPath == 1) {
-			TxPinCfg &= 0xFFFFFFF3;
-		}
-		if (pAd->Antenna.field.RxPath == 1) {
-			TxPinCfg &= 0xFFFFF3FF;
-		}
-
-		RTMP_IO_WRITE32(pAd, TX_PIN_CFG, TxPinCfg);
-
-	}
-
-	/* R66 should be set according to Channel and use 20MHz when scanning */
-	/*RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, (0x2E + GET_LNA_GAIN(pAd))); */
-	if (bScan)
-		RTMPSetAGCInitValue(pAd, BW_20);
-	else
-		RTMPSetAGCInitValue(pAd, pAd->CommonCfg.BBPCurrentBW);
-
-	/* */
-	/* On 11A, We should delay and wait RF/BBP to be stable */
-	/* and the appropriate time should be 1000 micro seconds */
-	/* 2005/06/05 - On 11G, We also need this delay time. Otherwise it's difficult to pass the WHQL. */
-	/* */
-	RTMPusecDelay(1000);
-}
-
-void AsicResetBBPAgent(struct rt_rtmp_adapter *pAd)
-{
-	BBP_CSR_CFG_STRUC BbpCsr;
-	DBGPRINT(RT_DEBUG_ERROR, ("Reset BBP Agent busy bit!\n"));
-	/* Still need to find why BBP agent keeps busy, but in fact, hardware still function ok. Now clear busy first. */
-	RTMP_IO_READ32(pAd, H2M_BBP_AGENT, &BbpCsr.word);
-	BbpCsr.field.Busy = 0;
-	RTMP_IO_WRITE32(pAd, H2M_BBP_AGENT, BbpCsr.word);
-}
-
-/*
-	==========================================================================
-	Description:
-		This function is required for 2421 only, and should not be used during
-		site survey. It's only required after NIC decided to stay at a channel
-		for a longer period.
-		When this function is called, it's always after AsicSwitchChannel().
-
-	IRQL = PASSIVE_LEVEL
-	IRQL = DISPATCH_LEVEL
-
-	==========================================================================
- */
-void AsicLockChannel(struct rt_rtmp_adapter *pAd, u8 Channel)
-{
-}
-
-void AsicRfTuningExec(void *SystemSpecific1,
-		      void *FunctionContext,
-		      void *SystemSpecific2, void *SystemSpecific3)
-{
-}
-
-/*
-	==========================================================================
-	Description:
-		Gives CCK TX rate 2 more dB TX power.
-		This routine works only in LINK UP in INFRASTRUCTURE mode.
-
-		calculate desired Tx power in RF R3.Tx0~5,	should consider -
-		0. if current radio is a noisy environment (pAd->DrsCounters.fNoisyEnvironment)
-		1. TxPowerPercentage
-		2. auto calibration based on TSSI feedback
-		3. extra 2 db for CCK
-		4. -10 db upon very-short distance (AvgRSSI >= -40db) to AP
-
-	NOTE: Since this routine requires the value of (pAd->DrsCounters.fNoisyEnvironment),
-		it should be called AFTER MlmeDynamicTxRatSwitching()
-	==========================================================================
- */
-void AsicAdjustTxPower(struct rt_rtmp_adapter *pAd)
-{
-	int i, j;
-	char DeltaPwr = 0;
-	BOOLEAN bAutoTxAgc = FALSE;
-	u8 TssiRef, *pTssiMinusBoundary, *pTssiPlusBoundary, TxAgcStep;
-	u8 BbpR1 = 0, BbpR49 = 0, idx;
-	char *pTxAgcCompensate;
-	unsigned long TxPwr[5];
-	char Value;
-	char Rssi = -127;
-
-	if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE) ||
-#ifdef RTMP_MAC_PCI
-	    (pAd->bPCIclkOff == TRUE) ||
-#endif /* RTMP_MAC_PCI // */
-	    RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF) ||
-	    RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
-		return;
-
-	Rssi = RTMPMaxRssi(pAd,
-			   pAd->StaCfg.RssiSample.AvgRssi0,
-			   pAd->StaCfg.RssiSample.AvgRssi1,
-			   pAd->StaCfg.RssiSample.AvgRssi2);
-
-	if (pAd->CommonCfg.BBPCurrentBW == BW_40) {
-		if (pAd->CommonCfg.CentralChannel > 14) {
-			TxPwr[0] = pAd->Tx40MPwrCfgABand[0];
-			TxPwr[1] = pAd->Tx40MPwrCfgABand[1];
-			TxPwr[2] = pAd->Tx40MPwrCfgABand[2];
-			TxPwr[3] = pAd->Tx40MPwrCfgABand[3];
-			TxPwr[4] = pAd->Tx40MPwrCfgABand[4];
-		} else {
-			TxPwr[0] = pAd->Tx40MPwrCfgGBand[0];
-			TxPwr[1] = pAd->Tx40MPwrCfgGBand[1];
-			TxPwr[2] = pAd->Tx40MPwrCfgGBand[2];
-			TxPwr[3] = pAd->Tx40MPwrCfgGBand[3];
-			TxPwr[4] = pAd->Tx40MPwrCfgGBand[4];
-		}
-	} else {
-		if (pAd->CommonCfg.Channel > 14) {
-			TxPwr[0] = pAd->Tx20MPwrCfgABand[0];
-			TxPwr[1] = pAd->Tx20MPwrCfgABand[1];
-			TxPwr[2] = pAd->Tx20MPwrCfgABand[2];
-			TxPwr[3] = pAd->Tx20MPwrCfgABand[3];
-			TxPwr[4] = pAd->Tx20MPwrCfgABand[4];
-		} else {
-			TxPwr[0] = pAd->Tx20MPwrCfgGBand[0];
-			TxPwr[1] = pAd->Tx20MPwrCfgGBand[1];
-			TxPwr[2] = pAd->Tx20MPwrCfgGBand[2];
-			TxPwr[3] = pAd->Tx20MPwrCfgGBand[3];
-			TxPwr[4] = pAd->Tx20MPwrCfgGBand[4];
-		}
-	}
-
-	/* TX power compensation for temperature variation based on TSSI. try every 4 second */
-	if (pAd->Mlme.OneSecPeriodicRound % 4 == 0) {
-		if (pAd->CommonCfg.Channel <= 14) {
-			/* bg channel */
-			bAutoTxAgc = pAd->bAutoTxAgcG;
-			TssiRef = pAd->TssiRefG;
-			pTssiMinusBoundary = &pAd->TssiMinusBoundaryG[0];
-			pTssiPlusBoundary = &pAd->TssiPlusBoundaryG[0];
-			TxAgcStep = pAd->TxAgcStepG;
-			pTxAgcCompensate = &pAd->TxAgcCompensateG;
-		} else {
-			/* a channel */
-			bAutoTxAgc = pAd->bAutoTxAgcA;
-			TssiRef = pAd->TssiRefA;
-			pTssiMinusBoundary = &pAd->TssiMinusBoundaryA[0];
-			pTssiPlusBoundary = &pAd->TssiPlusBoundaryA[0];
-			TxAgcStep = pAd->TxAgcStepA;
-			pTxAgcCompensate = &pAd->TxAgcCompensateA;
-		}
-
-		if (bAutoTxAgc) {
-			/* BbpR1 is unsigned char */
-			RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R49, &BbpR49);
-
-			/* (p) TssiPlusBoundaryG[0] = 0 = (m) TssiMinusBoundaryG[0] */
-			/* compensate: +4     +3   +2   +1    0   -1   -2   -3   -4 * steps */
-			/* step value is defined in pAd->TxAgcStepG for tx power value */
-
-			/* [4]+1+[4]   p4     p3   p2   p1   o1   m1   m2   m3   m4 */
-			/* ex:         0x00 0x15 0x25 0x45 0x88 0xA0 0xB5 0xD0 0xF0
-			   above value are examined in mass factory production */
-			/*             [4]    [3]  [2]  [1]  [0]  [1]  [2]  [3]  [4] */
-
-			/* plus (+) is 0x00 ~ 0x45, minus (-) is 0xa0 ~ 0xf0 */
-			/* if value is between p1 ~ o1 or o1 ~ s1, no need to adjust tx power */
-			/* if value is 0xa5, tx power will be -= TxAgcStep*(2-1) */
-
-			if (BbpR49 > pTssiMinusBoundary[1]) {
-				/* Reading is larger than the reference value */
-				/* check for how large we need to decrease the Tx power */
-				for (idx = 1; idx < 5; idx++) {
-					if (BbpR49 <= pTssiMinusBoundary[idx])	/* Found the range */
-						break;
-				}
-				/* The index is the step we should decrease, idx = 0 means there is nothing to compensate */
-/*                              if (R3 > (unsigned long)(TxAgcStep * (idx-1))) */
-				*pTxAgcCompensate = -(TxAgcStep * (idx - 1));
-/*                              else */
-/*                                      *pTxAgcCompensate = -((u8)R3); */
-
-				DeltaPwr += (*pTxAgcCompensate);
-				DBGPRINT(RT_DEBUG_TRACE,
-					 ("-- Tx Power, BBP R1=%x, TssiRef=%x, TxAgcStep=%x, step = -%d\n",
-					  BbpR49, TssiRef, TxAgcStep, idx - 1));
-			} else if (BbpR49 < pTssiPlusBoundary[1]) {
-				/* Reading is smaller than the reference value */
-				/* check for how large we need to increase the Tx power */
-				for (idx = 1; idx < 5; idx++) {
-					if (BbpR49 >= pTssiPlusBoundary[idx])	/* Found the range */
-						break;
-				}
-				/* The index is the step we should increase, idx = 0 means there is nothing to compensate */
-				*pTxAgcCompensate = TxAgcStep * (idx - 1);
-				DeltaPwr += (*pTxAgcCompensate);
-				DBGPRINT(RT_DEBUG_TRACE,
-					 ("++ Tx Power, BBP R1=%x, TssiRef=%x, TxAgcStep=%x, step = +%d\n",
-					  BbpR49, TssiRef, TxAgcStep, idx - 1));
-			} else {
-				*pTxAgcCompensate = 0;
-				DBGPRINT(RT_DEBUG_TRACE,
-					 ("   Tx Power, BBP R49=%x, TssiRef=%x, TxAgcStep=%x, step = +%d\n",
-					  BbpR49, TssiRef, TxAgcStep, 0));
-			}
-		}
-	} else {
-		if (pAd->CommonCfg.Channel <= 14) {
-			bAutoTxAgc = pAd->bAutoTxAgcG;
-			pTxAgcCompensate = &pAd->TxAgcCompensateG;
-		} else {
-			bAutoTxAgc = pAd->bAutoTxAgcA;
-			pTxAgcCompensate = &pAd->TxAgcCompensateA;
-		}
-
-		if (bAutoTxAgc)
-			DeltaPwr += (*pTxAgcCompensate);
-	}
-
-	RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R1, &BbpR1);
-	BbpR1 &= 0xFC;
-
-	/* calculate delta power based on the percentage specified from UI */
-	/* E2PROM setting is calibrated for maximum TX power (i.e. 100%) */
-	/* We lower TX power here according to the percentage specified from UI */
-	if (pAd->CommonCfg.TxPowerPercentage == 0xffffffff)	/* AUTO TX POWER control */
-	{
-		{
-			/* to patch high power issue with some APs, like Belkin N1. */
-			if (Rssi > -35) {
-				BbpR1 |= 0x02;	/* DeltaPwr -= 12; */
-			} else if (Rssi > -40) {
-				BbpR1 |= 0x01;	/* DeltaPwr -= 6; */
-			} else;
-		}
-	} else if (pAd->CommonCfg.TxPowerPercentage > 90)	/* 91 ~ 100% & AUTO, treat as 100% in terms of mW */
-		;
-	else if (pAd->CommonCfg.TxPowerPercentage > 60)	/* 61 ~ 90%, treat as 75% in terms of mW               // DeltaPwr -= 1; */
-	{
-		DeltaPwr -= 1;
-	} else if (pAd->CommonCfg.TxPowerPercentage > 30)	/* 31 ~ 60%, treat as 50% in terms of mW               // DeltaPwr -= 3; */
-	{
-		DeltaPwr -= 3;
-	} else if (pAd->CommonCfg.TxPowerPercentage > 15)	/* 16 ~ 30%, treat as 25% in terms of mW               // DeltaPwr -= 6; */
-	{
-		BbpR1 |= 0x01;
-	} else if (pAd->CommonCfg.TxPowerPercentage > 9)	/* 10 ~ 15%, treat as 12.5% in terms of mW             // DeltaPwr -= 9; */
-	{
-		BbpR1 |= 0x01;
-		DeltaPwr -= 3;
-	} else			/* 0 ~ 9 %, treat as MIN(~3%) in terms of mW             // DeltaPwr -= 12; */
-	{
-		BbpR1 |= 0x02;
-	}
-
-	RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R1, BbpR1);
-
-	/* reset different new tx power for different TX rate */
-	for (i = 0; i < 5; i++) {
-		if (TxPwr[i] != 0xffffffff) {
-			for (j = 0; j < 8; j++) {
-				Value = (char)((TxPwr[i] >> j * 4) & 0x0F);	/* 0 ~ 15 */
-
-				if ((Value + DeltaPwr) < 0) {
-					Value = 0;	/* min */
-				} else if ((Value + DeltaPwr) > 0xF) {
-					Value = 0xF;	/* max */
-				} else {
-					Value += DeltaPwr;	/* temperature compensation */
-				}
-
-				/* fill new value to CSR offset */
-				TxPwr[i] =
-				    (TxPwr[i] & ~(0x0000000F << j * 4)) | (Value
-									   << j
-									   * 4);
-			}
-
-			/* write tx power value to CSR */
-			/* TX_PWR_CFG_0 (8 tx rate) for TX power for OFDM 12M/18M
-			   TX power for OFDM 6M/9M
-			   TX power for CCK5.5M/11M
-			   TX power for CCK1M/2M */
-			/* TX_PWR_CFG_1 ~ TX_PWR_CFG_4 */
-			RTMP_IO_WRITE32(pAd, TX_PWR_CFG_0 + i * 4, TxPwr[i]);
-		}
-	}
-
-}
-
-/*
-	==========================================================================
-	Description:
-		put PHY to sleep here, and set next wakeup timer. PHY doesn't not wakeup
-		automatically. Instead, MCU will issue a TwakeUpInterrupt to host after
-		the wakeup timer timeout. Driver has to issue a separate command to wake
-		PHY up.
-
-	IRQL = DISPATCH_LEVEL
-
-	==========================================================================
- */
-void AsicSleepThenAutoWakeup(struct rt_rtmp_adapter *pAd,
-			     u16 TbttNumToNextWakeUp)
-{
-	RTMP_STA_SLEEP_THEN_AUTO_WAKEUP(pAd, TbttNumToNextWakeUp);
-}
-
-/*
-	==========================================================================
-	Description:
-		AsicForceWakeup() is used whenever manual wakeup is required
-		AsicForceSleep() should only be used when not in INFRA BSS. When
-		in INFRA BSS, we should use AsicSleepThenAutoWakeup() instead.
-	==========================================================================
- */
-void AsicForceSleep(struct rt_rtmp_adapter *pAd)
-{
-
-}
-
-/*
-	==========================================================================
-	Description:
-		AsicForceWakeup() is used whenever Twakeup timer (set via AsicSleepThenAutoWakeup)
-		expired.
-
-	IRQL = PASSIVE_LEVEL
-	IRQL = DISPATCH_LEVEL
-	==========================================================================
- */
-void AsicForceWakeup(struct rt_rtmp_adapter *pAd, IN BOOLEAN bFromTx)
-{
-	DBGPRINT(RT_DEBUG_INFO, ("--> AsicForceWakeup \n"));
-	RTMP_STA_FORCE_WAKEUP(pAd, bFromTx);
-}
-
-/*
-	==========================================================================
-	Description:
-		Set My BSSID
-
-	IRQL = DISPATCH_LEVEL
-
-	==========================================================================
- */
-void AsicSetBssid(struct rt_rtmp_adapter *pAd, u8 *pBssid)
-{
-	unsigned long Addr4;
-	DBGPRINT(RT_DEBUG_TRACE,
-		 ("==============> AsicSetBssid %x:%x:%x:%x:%x:%x\n", pBssid[0],
-		  pBssid[1], pBssid[2], pBssid[3], pBssid[4], pBssid[5]));
-
-	Addr4 = (unsigned long)(pBssid[0]) |
-	    (unsigned long)(pBssid[1] << 8) |
-	    (unsigned long)(pBssid[2] << 16) | (unsigned long)(pBssid[3] << 24);
-	RTMP_IO_WRITE32(pAd, MAC_BSSID_DW0, Addr4);
-
-	Addr4 = 0;
-	/* always one BSSID in STA mode */
-	Addr4 = (unsigned long)(pBssid[4]) | (unsigned long)(pBssid[5] << 8);
-
-	RTMP_IO_WRITE32(pAd, MAC_BSSID_DW1, Addr4);
-}
-
-void AsicSetMcastWC(struct rt_rtmp_adapter *pAd)
-{
-	struct rt_mac_table_entry *pEntry = &pAd->MacTab.Content[MCAST_WCID];
-	u16 offset;
-
-	pEntry->Sst = SST_ASSOC;
-	pEntry->Aid = MCAST_WCID;	/* Softap supports 1 BSSID and use WCID=0 as multicast Wcid index */
-	pEntry->PsMode = PWR_ACTIVE;
-	pEntry->CurrTxRate = pAd->CommonCfg.MlmeRate;
-	offset = MAC_WCID_BASE + BSS0Mcast_WCID * HW_WCID_ENTRY_SIZE;
-}
-
-/*
-	==========================================================================
-	Description:
-
-	IRQL = DISPATCH_LEVEL
-
-	==========================================================================
- */
-void AsicDelWcidTab(struct rt_rtmp_adapter *pAd, u8 Wcid)
-{
-	unsigned long Addr0 = 0x0, Addr1 = 0x0;
-	unsigned long offset;
-
-	DBGPRINT(RT_DEBUG_TRACE, ("AsicDelWcidTab==>Wcid = 0x%x\n", Wcid));
-	offset = MAC_WCID_BASE + Wcid * HW_WCID_ENTRY_SIZE;
-	RTMP_IO_WRITE32(pAd, offset, Addr0);
-	offset += 4;
-	RTMP_IO_WRITE32(pAd, offset, Addr1);
-}
-
-/*
-	==========================================================================
-	Description:
-
-	IRQL = DISPATCH_LEVEL
-
-	==========================================================================
- */
-void AsicEnableRDG(struct rt_rtmp_adapter *pAd)
-{
-	TX_LINK_CFG_STRUC TxLinkCfg;
-	u32 Data = 0;
-
-	RTMP_IO_READ32(pAd, TX_LINK_CFG, &TxLinkCfg.word);
-	TxLinkCfg.field.TxRDGEn = 1;
-	RTMP_IO_WRITE32(pAd, TX_LINK_CFG, TxLinkCfg.word);
-
-	RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &Data);
-	Data &= 0xFFFFFF00;
-	Data |= 0x80;
-	RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Data);
-
-	/*OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED); */
-}
-
-/*
-	==========================================================================
-	Description:
-
-	IRQL = DISPATCH_LEVEL
-
-	==========================================================================
- */
-void AsicDisableRDG(struct rt_rtmp_adapter *pAd)
-{
-	TX_LINK_CFG_STRUC TxLinkCfg;
-	u32 Data = 0;
-
-	RTMP_IO_READ32(pAd, TX_LINK_CFG, &TxLinkCfg.word);
-	TxLinkCfg.field.TxRDGEn = 0;
-	RTMP_IO_WRITE32(pAd, TX_LINK_CFG, TxLinkCfg.word);
-
-	RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &Data);
-
-	Data &= 0xFFFFFF00;
-	/*Data  |= 0x20; */
-#ifndef WIFI_TEST
-	/*if ( pAd->CommonCfg.bEnableTxBurst ) */
-	/*      Data |= 0x60; // for performance issue not set the TXOP to 0 */
-#endif
-	if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_DYNAMIC_BE_TXOP_ACTIVE)
-	    && (pAd->MacTab.fAnyStationMIMOPSDynamic == FALSE)
-	    ) {
-		/* For CWC test, change txop from 0x30 to 0x20 in TxBurst mode */
-		if (pAd->CommonCfg.bEnableTxBurst)
-			Data |= 0x20;
-	}
-	RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Data);
-}
-
-/*
-	==========================================================================
-	Description:
-
-	IRQL = PASSIVE_LEVEL
-	IRQL = DISPATCH_LEVEL
-
-	==========================================================================
- */
-void AsicDisableSync(struct rt_rtmp_adapter *pAd)
-{
-	BCN_TIME_CFG_STRUC csr;
-
-	DBGPRINT(RT_DEBUG_TRACE, ("--->Disable TSF synchronization\n"));
-
-	/* 2003-12-20 disable TSF and TBTT while NIC in power-saving have side effect */
-	/*                        that NIC will never wakes up because TSF stops and no more */
-	/*                        TBTT interrupts */
-	pAd->TbttTickCount = 0;
-	RTMP_IO_READ32(pAd, BCN_TIME_CFG, &csr.word);
-	csr.field.bBeaconGen = 0;
-	csr.field.bTBTTEnable = 0;
-	csr.field.TsfSyncMode = 0;
-	csr.field.bTsfTicking = 0;
-	RTMP_IO_WRITE32(pAd, BCN_TIME_CFG, csr.word);
-
-}
-
-/*
-	==========================================================================
-	Description:
-
-	IRQL = DISPATCH_LEVEL
-
-	==========================================================================
- */
-void AsicEnableBssSync(struct rt_rtmp_adapter *pAd)
-{
-	BCN_TIME_CFG_STRUC csr;
-
-	DBGPRINT(RT_DEBUG_TRACE, ("--->AsicEnableBssSync(INFRA mode)\n"));
-
-	RTMP_IO_READ32(pAd, BCN_TIME_CFG, &csr.word);
-/*      RTMP_IO_WRITE32(pAd, BCN_TIME_CFG, 0x00000000); */
-	{
-		csr.field.BeaconInterval = pAd->CommonCfg.BeaconPeriod << 4;	/* ASIC register in units of 1/16 TU */
-		csr.field.bTsfTicking = 1;
-		csr.field.TsfSyncMode = 1;	/* sync TSF in INFRASTRUCTURE mode */
-		csr.field.bBeaconGen = 0;	/* do NOT generate BEACON */
-		csr.field.bTBTTEnable = 1;
-	}
-	RTMP_IO_WRITE32(pAd, BCN_TIME_CFG, csr.word);
-}
-
-/*
-	==========================================================================
-	Description:
-	Note:
-		BEACON frame in shared memory should be built ok before this routine
-		can be called. Otherwise, a garbage frame maybe transmitted out every
-		Beacon period.
-
-	IRQL = DISPATCH_LEVEL
-
-	==========================================================================
- */
-void AsicEnableIbssSync(struct rt_rtmp_adapter *pAd)
-{
-	BCN_TIME_CFG_STRUC csr9;
-	u8 *ptr;
-	u32 i;
-
-	DBGPRINT(RT_DEBUG_TRACE,
-		 ("--->AsicEnableIbssSync(ADHOC mode. MPDUtotalByteCount = %d)\n",
-		  pAd->BeaconTxWI.MPDUtotalByteCount));
-
-	RTMP_IO_READ32(pAd, BCN_TIME_CFG, &csr9.word);
-	csr9.field.bBeaconGen = 0;
-	csr9.field.bTBTTEnable = 0;
-	csr9.field.bTsfTicking = 0;
-	RTMP_IO_WRITE32(pAd, BCN_TIME_CFG, csr9.word);
-
-#ifdef RTMP_MAC_PCI
-	/* move BEACON TXD and frame content to on-chip memory */
-	ptr = (u8 *)& pAd->BeaconTxWI;
-	for (i = 0; i < TXWI_SIZE; i += 4)	/* 16-byte TXWI field */
-	{
-		u32 longptr =
-		    *ptr + (*(ptr + 1) << 8) + (*(ptr + 2) << 16) +
-		    (*(ptr + 3) << 24);
-		RTMP_IO_WRITE32(pAd, HW_BEACON_BASE0 + i, longptr);
-		ptr += 4;
-	}
-
-	/* start right after the 16-byte TXWI field */
-	ptr = pAd->BeaconBuf;
-	for (i = 0; i < pAd->BeaconTxWI.MPDUtotalByteCount; i += 4) {
-		u32 longptr =
-		    *ptr + (*(ptr + 1) << 8) + (*(ptr + 2) << 16) +
-		    (*(ptr + 3) << 24);
-		RTMP_IO_WRITE32(pAd, HW_BEACON_BASE0 + TXWI_SIZE + i, longptr);
-		ptr += 4;
-	}
-#endif /* RTMP_MAC_PCI // */
-#ifdef RTMP_MAC_USB
-	/* move BEACON TXD and frame content to on-chip memory */
-	ptr = (u8 *)& pAd->BeaconTxWI;
-	for (i = 0; i < TXWI_SIZE; i += 2)	/* 16-byte TXWI field */
-	{
-		/*u32 longptr =  *ptr + (*(ptr+1)<<8) + (*(ptr+2)<<16) + (*(ptr+3)<<24); */
-		/*RTMP_IO_WRITE32(pAd, HW_BEACON_BASE0 + i, longptr); */
-		RTUSBMultiWrite(pAd, HW_BEACON_BASE0 + i, ptr, 2);
-		ptr += 2;
-	}
-
-	/* start right after the 16-byte TXWI field */
-	ptr = pAd->BeaconBuf;
-	for (i = 0; i < pAd->BeaconTxWI.MPDUtotalByteCount; i += 2) {
-		/*u32 longptr =  *ptr + (*(ptr+1)<<8) + (*(ptr+2)<<16) + (*(ptr+3)<<24); */
-		/*RTMP_IO_WRITE32(pAd, HW_BEACON_BASE0 + TXWI_SIZE + i, longptr); */
-		RTUSBMultiWrite(pAd, HW_BEACON_BASE0 + TXWI_SIZE + i, ptr, 2);
-		ptr += 2;
-	}
-#endif /* RTMP_MAC_USB // */
-
-	/* */
-	/* For Wi-Fi faily generated beacons between participating stations. */
-	/* Set TBTT phase adaptive adjustment step to 8us (default 16us) */
-	/* don't change settings 2006-5- by Jerry */
-	/*RTMP_IO_WRITE32(pAd, TBTT_SYNC_CFG, 0x00001010); */
-
-	/* start sending BEACON */
-	csr9.field.BeaconInterval = pAd->CommonCfg.BeaconPeriod << 4;	/* ASIC register in units of 1/16 TU */
-	csr9.field.bTsfTicking = 1;
-	csr9.field.TsfSyncMode = 2;	/* sync TSF in IBSS mode */
-	csr9.field.bTBTTEnable = 1;
-	csr9.field.bBeaconGen = 1;
-	RTMP_IO_WRITE32(pAd, BCN_TIME_CFG, csr9.word);
-}
-
-/*
-	==========================================================================
-	Description:
-
-	IRQL = PASSIVE_LEVEL
-	IRQL = DISPATCH_LEVEL
-
-	==========================================================================
- */
-void AsicSetEdcaParm(struct rt_rtmp_adapter *pAd, struct rt_edca_parm *pEdcaParm)
-{
-	EDCA_AC_CFG_STRUC Ac0Cfg, Ac1Cfg, Ac2Cfg, Ac3Cfg;
-	AC_TXOP_CSR0_STRUC csr0;
-	AC_TXOP_CSR1_STRUC csr1;
-	AIFSN_CSR_STRUC AifsnCsr;
-	CWMIN_CSR_STRUC CwminCsr;
-	CWMAX_CSR_STRUC CwmaxCsr;
-	int i;
-
-	Ac0Cfg.word = 0;
-	Ac1Cfg.word = 0;
-	Ac2Cfg.word = 0;
-	Ac3Cfg.word = 0;
-	if ((pEdcaParm == NULL) || (pEdcaParm->bValid == FALSE)) {
-		DBGPRINT(RT_DEBUG_TRACE, ("AsicSetEdcaParm\n"));
-		OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_WMM_INUSED);
-		for (i = 0; i < MAX_LEN_OF_MAC_TABLE; i++) {
-			if (pAd->MacTab.Content[i].ValidAsCLI
-			    || pAd->MacTab.Content[i].ValidAsApCli)
-				CLIENT_STATUS_CLEAR_FLAG(&pAd->MacTab.
-							 Content[i],
-							 fCLIENT_STATUS_WMM_CAPABLE);
-		}
-
-		/*======================================================== */
-		/*      MAC Register has a copy . */
-		/*======================================================== */
-/*#ifndef WIFI_TEST */
-		if (pAd->CommonCfg.bEnableTxBurst) {
-			/* For CWC test, change txop from 0x30 to 0x20 in TxBurst mode */
-			Ac0Cfg.field.AcTxop = 0x20;	/* Suggest by John for TxBurst in HT Mode */
-		} else
-			Ac0Cfg.field.AcTxop = 0;	/* QID_AC_BE */
-/*#else */
-/*              Ac0Cfg.field.AcTxop = 0;        // QID_AC_BE */
-/*#endif */
-		Ac0Cfg.field.Cwmin = CW_MIN_IN_BITS;
-		Ac0Cfg.field.Cwmax = CW_MAX_IN_BITS;
-		Ac0Cfg.field.Aifsn = 2;
-		RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Ac0Cfg.word);
-
-		Ac1Cfg.field.AcTxop = 0;	/* QID_AC_BK */
-		Ac1Cfg.field.Cwmin = CW_MIN_IN_BITS;
-		Ac1Cfg.field.Cwmax = CW_MAX_IN_BITS;
-		Ac1Cfg.field.Aifsn = 2;
-		RTMP_IO_WRITE32(pAd, EDCA_AC1_CFG, Ac1Cfg.word);
-
-		if (pAd->CommonCfg.PhyMode == PHY_11B) {
-			Ac2Cfg.field.AcTxop = 192;	/* AC_VI: 192*32us ~= 6ms */
-			Ac3Cfg.field.AcTxop = 96;	/* AC_VO: 96*32us  ~= 3ms */
-		} else {
-			Ac2Cfg.field.AcTxop = 96;	/* AC_VI: 96*32us ~= 3ms */
-			Ac3Cfg.field.AcTxop = 48;	/* AC_VO: 48*32us ~= 1.5ms */
-		}
-		Ac2Cfg.field.Cwmin = CW_MIN_IN_BITS;
-		Ac2Cfg.field.Cwmax = CW_MAX_IN_BITS;
-		Ac2Cfg.field.Aifsn = 2;
-		RTMP_IO_WRITE32(pAd, EDCA_AC2_CFG, Ac2Cfg.word);
-		Ac3Cfg.field.Cwmin = CW_MIN_IN_BITS;
-		Ac3Cfg.field.Cwmax = CW_MAX_IN_BITS;
-		Ac3Cfg.field.Aifsn = 2;
-		RTMP_IO_WRITE32(pAd, EDCA_AC3_CFG, Ac3Cfg.word);
-
-		/*======================================================== */
-		/*      DMA Register has a copy too. */
-		/*======================================================== */
-		csr0.field.Ac0Txop = 0;	/* QID_AC_BE */
-		csr0.field.Ac1Txop = 0;	/* QID_AC_BK */
-		RTMP_IO_WRITE32(pAd, WMM_TXOP0_CFG, csr0.word);
-		if (pAd->CommonCfg.PhyMode == PHY_11B) {
-			csr1.field.Ac2Txop = 192;	/* AC_VI: 192*32us ~= 6ms */
-			csr1.field.Ac3Txop = 96;	/* AC_VO: 96*32us  ~= 3ms */
-		} else {
-			csr1.field.Ac2Txop = 96;	/* AC_VI: 96*32us ~= 3ms */
-			csr1.field.Ac3Txop = 48;	/* AC_VO: 48*32us ~= 1.5ms */
-		}
-		RTMP_IO_WRITE32(pAd, WMM_TXOP1_CFG, csr1.word);
-
-		CwminCsr.word = 0;
-		CwminCsr.field.Cwmin0 = CW_MIN_IN_BITS;
-		CwminCsr.field.Cwmin1 = CW_MIN_IN_BITS;
-		CwminCsr.field.Cwmin2 = CW_MIN_IN_BITS;
-		CwminCsr.field.Cwmin3 = CW_MIN_IN_BITS;
-		RTMP_IO_WRITE32(pAd, WMM_CWMIN_CFG, CwminCsr.word);
-
-		CwmaxCsr.word = 0;
-		CwmaxCsr.field.Cwmax0 = CW_MAX_IN_BITS;
-		CwmaxCsr.field.Cwmax1 = CW_MAX_IN_BITS;
-		CwmaxCsr.field.Cwmax2 = CW_MAX_IN_BITS;
-		CwmaxCsr.field.Cwmax3 = CW_MAX_IN_BITS;
-		RTMP_IO_WRITE32(pAd, WMM_CWMAX_CFG, CwmaxCsr.word);
-
-		RTMP_IO_WRITE32(pAd, WMM_AIFSN_CFG, 0x00002222);
-
-		NdisZeroMemory(&pAd->CommonCfg.APEdcaParm, sizeof(struct rt_edca_parm));
-	} else {
-		OPSTATUS_SET_FLAG(pAd, fOP_STATUS_WMM_INUSED);
-		/*======================================================== */
-		/*      MAC Register has a copy. */
-		/*======================================================== */
-		/* */
-		/* Modify Cwmin/Cwmax/Txop on queue[QID_AC_VI], Recommend by Jerry 2005/07/27 */
-		/* To degrade our VIDO Queue's throughput for WiFi WMM S3T07 Issue. */
-		/* */
-		/*pEdcaParm->Txop[QID_AC_VI] = pEdcaParm->Txop[QID_AC_VI] * 7 / 10; // rt2860c need this */
-
-		Ac0Cfg.field.AcTxop = pEdcaParm->Txop[QID_AC_BE];
-		Ac0Cfg.field.Cwmin = pEdcaParm->Cwmin[QID_AC_BE];
-		Ac0Cfg.field.Cwmax = pEdcaParm->Cwmax[QID_AC_BE];
-		Ac0Cfg.field.Aifsn = pEdcaParm->Aifsn[QID_AC_BE];	/*+1; */
-
-		Ac1Cfg.field.AcTxop = pEdcaParm->Txop[QID_AC_BK];
-		Ac1Cfg.field.Cwmin = pEdcaParm->Cwmin[QID_AC_BK];	/*+2; */
-		Ac1Cfg.field.Cwmax = pEdcaParm->Cwmax[QID_AC_BK];
-		Ac1Cfg.field.Aifsn = pEdcaParm->Aifsn[QID_AC_BK];	/*+1; */
-
-		Ac2Cfg.field.AcTxop = (pEdcaParm->Txop[QID_AC_VI] * 6) / 10;
-		if (pAd->Antenna.field.TxPath == 1) {
-			Ac2Cfg.field.Cwmin = pEdcaParm->Cwmin[QID_AC_VI] + 1;
-			Ac2Cfg.field.Cwmax = pEdcaParm->Cwmax[QID_AC_VI] + 1;
-		} else {
-			Ac2Cfg.field.Cwmin = pEdcaParm->Cwmin[QID_AC_VI];
-			Ac2Cfg.field.Cwmax = pEdcaParm->Cwmax[QID_AC_VI];
-		}
-		Ac2Cfg.field.Aifsn = pEdcaParm->Aifsn[QID_AC_VI] + 1;
-#ifdef RTMP_MAC_USB
-		Ac2Cfg.field.Aifsn = pEdcaParm->Aifsn[QID_AC_VI] + 3;
-#endif /* RTMP_MAC_USB // */
-
-		{
-			/* Tuning for Wi-Fi WMM S06 */
-			if (pAd->CommonCfg.bWiFiTest &&
-			    pEdcaParm->Aifsn[QID_AC_VI] == 10)
-				Ac2Cfg.field.Aifsn -= 1;
-
-			/* Tuning for TGn Wi-Fi 5.2.32 */
-			/* STA TestBed changes in this item: conexant legacy sta ==> broadcom 11n sta */
-			if (STA_TGN_WIFI_ON(pAd) &&
-			    pEdcaParm->Aifsn[QID_AC_VI] == 10) {
-				Ac0Cfg.field.Aifsn = 3;
-				Ac2Cfg.field.AcTxop = 5;
-			}
-#ifdef RT30xx
-			if (pAd->RfIcType == RFIC_3020
-			    || pAd->RfIcType == RFIC_2020) {
-				/* Tuning for WiFi WMM S3-T07: connexant legacy sta ==> broadcom 11n sta. */
-				Ac2Cfg.field.Aifsn = 5;
-			}
-#endif /* RT30xx // */
-		}
-
-		Ac3Cfg.field.AcTxop = pEdcaParm->Txop[QID_AC_VO];
-		Ac3Cfg.field.Cwmin = pEdcaParm->Cwmin[QID_AC_VO];
-		Ac3Cfg.field.Cwmax = pEdcaParm->Cwmax[QID_AC_VO];
-		Ac3Cfg.field.Aifsn = pEdcaParm->Aifsn[QID_AC_VO];
-
-/*#ifdef WIFI_TEST */
-		if (pAd->CommonCfg.bWiFiTest) {
-			if (Ac3Cfg.field.AcTxop == 102) {
-				Ac0Cfg.field.AcTxop =
-				    pEdcaParm->Txop[QID_AC_BE] ? pEdcaParm->
-				    Txop[QID_AC_BE] : 10;
-				Ac0Cfg.field.Aifsn = pEdcaParm->Aifsn[QID_AC_BE] - 1;	/* AIFSN must >= 1 */
-				Ac1Cfg.field.AcTxop =
-				    pEdcaParm->Txop[QID_AC_BK];
-				Ac1Cfg.field.Aifsn =
-				    pEdcaParm->Aifsn[QID_AC_BK];
-				Ac2Cfg.field.AcTxop =
-				    pEdcaParm->Txop[QID_AC_VI];
-			}	/* End of if */
-		}
-/*#endif // WIFI_TEST // */
-
-		RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Ac0Cfg.word);
-		RTMP_IO_WRITE32(pAd, EDCA_AC1_CFG, Ac1Cfg.word);
-		RTMP_IO_WRITE32(pAd, EDCA_AC2_CFG, Ac2Cfg.word);
-		RTMP_IO_WRITE32(pAd, EDCA_AC3_CFG, Ac3Cfg.word);
-
-		/*======================================================== */
-		/*      DMA Register has a copy too. */
-		/*======================================================== */
-		csr0.field.Ac0Txop = Ac0Cfg.field.AcTxop;
-		csr0.field.Ac1Txop = Ac1Cfg.field.AcTxop;
-		RTMP_IO_WRITE32(pAd, WMM_TXOP0_CFG, csr0.word);
-
-		csr1.field.Ac2Txop = Ac2Cfg.field.AcTxop;
-		csr1.field.Ac3Txop = Ac3Cfg.field.AcTxop;
-		RTMP_IO_WRITE32(pAd, WMM_TXOP1_CFG, csr1.word);
-
-		CwminCsr.word = 0;
-		CwminCsr.field.Cwmin0 = pEdcaParm->Cwmin[QID_AC_BE];
-		CwminCsr.field.Cwmin1 = pEdcaParm->Cwmin[QID_AC_BK];
-		CwminCsr.field.Cwmin2 = pEdcaParm->Cwmin[QID_AC_VI];
-		CwminCsr.field.Cwmin3 = pEdcaParm->Cwmin[QID_AC_VO] - 1;	/*for TGn wifi test */
-		RTMP_IO_WRITE32(pAd, WMM_CWMIN_CFG, CwminCsr.word);
-
-		CwmaxCsr.word = 0;
-		CwmaxCsr.field.Cwmax0 = pEdcaParm->Cwmax[QID_AC_BE];
-		CwmaxCsr.field.Cwmax1 = pEdcaParm->Cwmax[QID_AC_BK];
-		CwmaxCsr.field.Cwmax2 = pEdcaParm->Cwmax[QID_AC_VI];
-		CwmaxCsr.field.Cwmax3 = pEdcaParm->Cwmax[QID_AC_VO];
-		RTMP_IO_WRITE32(pAd, WMM_CWMAX_CFG, CwmaxCsr.word);
-
-		AifsnCsr.word = 0;
-		AifsnCsr.field.Aifsn0 = Ac0Cfg.field.Aifsn;	/*pEdcaParm->Aifsn[QID_AC_BE]; */
-		AifsnCsr.field.Aifsn1 = Ac1Cfg.field.Aifsn;	/*pEdcaParm->Aifsn[QID_AC_BK]; */
-		AifsnCsr.field.Aifsn2 = Ac2Cfg.field.Aifsn;	/*pEdcaParm->Aifsn[QID_AC_VI]; */
-
-		{
-			/* Tuning for Wi-Fi WMM S06 */
-			if (pAd->CommonCfg.bWiFiTest &&
-			    pEdcaParm->Aifsn[QID_AC_VI] == 10)
-				AifsnCsr.field.Aifsn2 = Ac2Cfg.field.Aifsn - 4;
-
-			/* Tuning for TGn Wi-Fi 5.2.32 */
-			/* STA TestBed changes in this item: connexant legacy sta ==> broadcom 11n sta */
-			if (STA_TGN_WIFI_ON(pAd) &&
-			    pEdcaParm->Aifsn[QID_AC_VI] == 10) {
-				AifsnCsr.field.Aifsn0 = 3;
-				AifsnCsr.field.Aifsn2 = 7;
-			}
-
-			if (INFRA_ON(pAd))
-				CLIENT_STATUS_SET_FLAG(&pAd->MacTab.
-						       Content[BSSID_WCID],
-						       fCLIENT_STATUS_WMM_CAPABLE);
-		}
-
-		{
-			AifsnCsr.field.Aifsn3 = Ac3Cfg.field.Aifsn - 1;	/*pEdcaParm->Aifsn[QID_AC_VO]; //for TGn wifi test */
-#ifdef RT30xx
-			/* TODO: Shiang, this modification also suitable for RT3052/RT3050 ??? */
-			if (pAd->RfIcType == RFIC_3020
-			    || pAd->RfIcType == RFIC_2020) {
-				AifsnCsr.field.Aifsn2 = 0x2;	/*pEdcaParm->Aifsn[QID_AC_VI]; //for WiFi WMM S4-T04. */
-			}
-#endif /* RT30xx // */
-		}
-		RTMP_IO_WRITE32(pAd, WMM_AIFSN_CFG, AifsnCsr.word);
-
-		NdisMoveMemory(&pAd->CommonCfg.APEdcaParm, pEdcaParm,
-			       sizeof(struct rt_edca_parm));
-		if (!ADHOC_ON(pAd)) {
-			DBGPRINT(RT_DEBUG_TRACE,
-				 ("EDCA [#%d]: AIFSN CWmin CWmax  TXOP(us)  ACM\n",
-				  pEdcaParm->EdcaUpdateCount));
-			DBGPRINT(RT_DEBUG_TRACE,
-				 ("     AC_BE      %2d     %2d     %2d      %4d     %d\n",
-				  pEdcaParm->Aifsn[0], pEdcaParm->Cwmin[0],
-				  pEdcaParm->Cwmax[0], pEdcaParm->Txop[0] << 5,
-				  pEdcaParm->bACM[0]));
-			DBGPRINT(RT_DEBUG_TRACE,
-				 ("     AC_BK      %2d     %2d     %2d      %4d     %d\n",
-				  pEdcaParm->Aifsn[1], pEdcaParm->Cwmin[1],
-				  pEdcaParm->Cwmax[1], pEdcaParm->Txop[1] << 5,
-				  pEdcaParm->bACM[1]));
-			DBGPRINT(RT_DEBUG_TRACE,
-				 ("     AC_VI      %2d     %2d     %2d      %4d     %d\n",
-				  pEdcaParm->Aifsn[2], pEdcaParm->Cwmin[2],
-				  pEdcaParm->Cwmax[2], pEdcaParm->Txop[2] << 5,
-				  pEdcaParm->bACM[2]));
-			DBGPRINT(RT_DEBUG_TRACE,
-				 ("     AC_VO      %2d     %2d     %2d      %4d     %d\n",
-				  pEdcaParm->Aifsn[3], pEdcaParm->Cwmin[3],
-				  pEdcaParm->Cwmax[3], pEdcaParm->Txop[3] << 5,
-				  pEdcaParm->bACM[3]));
-		}
-	}
-
-}
-
-/*
-	==========================================================================
-	Description:
-
-	IRQL = PASSIVE_LEVEL
-	IRQL = DISPATCH_LEVEL
-
-	==========================================================================
- */
-void AsicSetSlotTime(struct rt_rtmp_adapter *pAd, IN BOOLEAN bUseShortSlotTime)
-{
-	unsigned long SlotTime;
-	u32 RegValue = 0;
-
-	if (pAd->CommonCfg.Channel > 14)
-		bUseShortSlotTime = TRUE;
-
-	if (bUseShortSlotTime
-	    && OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_SHORT_SLOT_INUSED))
-		return;
-	else if ((!bUseShortSlotTime)
-		 && (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_SHORT_SLOT_INUSED)))
-		return;
-
-	if (bUseShortSlotTime)
-		OPSTATUS_SET_FLAG(pAd, fOP_STATUS_SHORT_SLOT_INUSED);
-	else
-		OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_SHORT_SLOT_INUSED);
-
-	SlotTime = (bUseShortSlotTime) ? 9 : 20;
-
-	{
-		/* force using short SLOT time for FAE to demo performance when TxBurst is ON */
-		if (((pAd->StaActive.SupportedPhyInfo.bHtEnable == FALSE)
-		     && (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED)))
-		    || ((pAd->StaActive.SupportedPhyInfo.bHtEnable == TRUE)
-			&& (pAd->CommonCfg.BACapability.field.Policy ==
-			    BA_NOTUSE))
-		    ) {
-			/* In this case, we will think it is doing Wi-Fi test */
-			/* And we will not set to short slot when bEnableTxBurst is TRUE. */
-		} else if (pAd->CommonCfg.bEnableTxBurst) {
-			OPSTATUS_SET_FLAG(pAd, fOP_STATUS_SHORT_SLOT_INUSED);
-			SlotTime = 9;
-		}
-	}
-
-	/* */
-	/* For some reasons, always set it to short slot time. */
-	/* */
-	/* ToDo: Should consider capability with 11B */
-	/* */
-	{
-		if (pAd->StaCfg.BssType == BSS_ADHOC) {
-			OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_SHORT_SLOT_INUSED);
-			SlotTime = 20;
-		}
-	}
-
-	RTMP_IO_READ32(pAd, BKOFF_SLOT_CFG, &RegValue);
-	RegValue = RegValue & 0xFFFFFF00;
-
-	RegValue |= SlotTime;
-
-	RTMP_IO_WRITE32(pAd, BKOFF_SLOT_CFG, RegValue);
-}
-
-/*
-	========================================================================
-	Description:
-		Add Shared key information into ASIC.
-		Update shared key, TxMic and RxMic to Asic Shared key table
-		Update its cipherAlg to Asic Shared key Mode.
-
-    Return:
-	========================================================================
-*/
-void AsicAddSharedKeyEntry(struct rt_rtmp_adapter *pAd,
-			   u8 BssIndex,
-			   u8 KeyIdx,
-			   u8 CipherAlg,
-			   u8 *pKey, u8 *pTxMic, u8 *pRxMic)
-{
-	unsigned long offset;		/*, csr0; */
-	SHAREDKEY_MODE_STRUC csr1;
-#ifdef RTMP_MAC_PCI
-	int i;
-#endif /* RTMP_MAC_PCI // */
-
-	DBGPRINT(RT_DEBUG_TRACE,
-		 ("AsicAddSharedKeyEntry BssIndex=%d, KeyIdx=%d\n", BssIndex,
-		  KeyIdx));
-/*============================================================================================ */
-
-	DBGPRINT(RT_DEBUG_TRACE,
-		 ("AsicAddSharedKeyEntry: %s key #%d\n", CipherName[CipherAlg],
-		  BssIndex * 4 + KeyIdx));
-	DBGPRINT_RAW(RT_DEBUG_TRACE,
-		     ("		Key = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
-		      pKey[0], pKey[1], pKey[2], pKey[3], pKey[4],
-		      pKey[5], pKey[6], pKey[7], pKey[8], pKey[9],
-		      pKey[10], pKey[11], pKey[12], pKey[13], pKey[14],
-		      pKey[15]));
-	if (pRxMic) {
-		DBGPRINT_RAW(RT_DEBUG_TRACE,
-			     ("		Rx MIC Key = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
-			      pRxMic[0], pRxMic[1], pRxMic[2], pRxMic[3],
-			      pRxMic[4], pRxMic[5], pRxMic[6], pRxMic[7]));
-	}
-	if (pTxMic) {
-		DBGPRINT_RAW(RT_DEBUG_TRACE,
-			     ("		Tx MIC Key = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
-			      pTxMic[0], pTxMic[1], pTxMic[2], pTxMic[3],
-			      pTxMic[4], pTxMic[5], pTxMic[6], pTxMic[7]));
-	}
-/*============================================================================================ */
-	/* */
-	/* fill key material - key + TX MIC + RX MIC */
-	/* */
-#ifdef RTMP_MAC_PCI
-	offset =
-	    SHARED_KEY_TABLE_BASE + (4 * BssIndex + KeyIdx) * HW_KEY_ENTRY_SIZE;
-	for (i = 0; i < MAX_LEN_OF_SHARE_KEY; i++) {
-		RTMP_IO_WRITE8(pAd, offset + i, pKey[i]);
-	}
-
-	offset += MAX_LEN_OF_SHARE_KEY;
-	if (pTxMic) {
-		for (i = 0; i < 8; i++) {
-			RTMP_IO_WRITE8(pAd, offset + i, pTxMic[i]);
-		}
-	}
-
-	offset += 8;
-	if (pRxMic) {
-		for (i = 0; i < 8; i++) {
-			RTMP_IO_WRITE8(pAd, offset + i, pRxMic[i]);
-		}
-	}
-#endif /* RTMP_MAC_PCI // */
-#ifdef RTMP_MAC_USB
-	{
-		offset =
-		    SHARED_KEY_TABLE_BASE + (4 * BssIndex +
-					     KeyIdx) * HW_KEY_ENTRY_SIZE;
-		RTUSBMultiWrite(pAd, offset, pKey, MAX_LEN_OF_SHARE_KEY);
-
-		offset += MAX_LEN_OF_SHARE_KEY;
-		if (pTxMic) {
-			RTUSBMultiWrite(pAd, offset, pTxMic, 8);
-		}
-
-		offset += 8;
-		if (pRxMic) {
-			RTUSBMultiWrite(pAd, offset, pRxMic, 8);
-		}
-	}
-#endif /* RTMP_MAC_USB // */
-
-	/* */
-	/* Update cipher algorithm. WSTA always use BSS0 */
-	/* */
-	RTMP_IO_READ32(pAd, SHARED_KEY_MODE_BASE + 4 * (BssIndex / 2),
-		       &csr1.word);
-	DBGPRINT(RT_DEBUG_TRACE,
-		 ("Read: SHARED_KEY_MODE_BASE at this Bss[%d] KeyIdx[%d]= 0x%x \n",
-		  BssIndex, KeyIdx, csr1.word));
-	if ((BssIndex % 2) == 0) {
-		if (KeyIdx == 0)
-			csr1.field.Bss0Key0CipherAlg = CipherAlg;
-		else if (KeyIdx == 1)
-			csr1.field.Bss0Key1CipherAlg = CipherAlg;
-		else if (KeyIdx == 2)
-			csr1.field.Bss0Key2CipherAlg = CipherAlg;
-		else
-			csr1.field.Bss0Key3CipherAlg = CipherAlg;
-	} else {
-		if (KeyIdx == 0)
-			csr1.field.Bss1Key0CipherAlg = CipherAlg;
-		else if (KeyIdx == 1)
-			csr1.field.Bss1Key1CipherAlg = CipherAlg;
-		else if (KeyIdx == 2)
-			csr1.field.Bss1Key2CipherAlg = CipherAlg;
-		else
-			csr1.field.Bss1Key3CipherAlg = CipherAlg;
-	}
-	DBGPRINT(RT_DEBUG_TRACE,
-		 ("Write: SHARED_KEY_MODE_BASE at this Bss[%d] = 0x%x \n",
-		  BssIndex, csr1.word));
-	RTMP_IO_WRITE32(pAd, SHARED_KEY_MODE_BASE + 4 * (BssIndex / 2),
-			csr1.word);
-
-}
-
-/*      IRQL = DISPATCH_LEVEL */
-void AsicRemoveSharedKeyEntry(struct rt_rtmp_adapter *pAd,
-			      u8 BssIndex, u8 KeyIdx)
-{
-	/*unsigned long SecCsr0; */
-	SHAREDKEY_MODE_STRUC csr1;
-
-	DBGPRINT(RT_DEBUG_TRACE,
-		 ("AsicRemoveSharedKeyEntry: #%d \n", BssIndex * 4 + KeyIdx));
-
-	RTMP_IO_READ32(pAd, SHARED_KEY_MODE_BASE + 4 * (BssIndex / 2),
-		       &csr1.word);
-	if ((BssIndex % 2) == 0) {
-		if (KeyIdx == 0)
-			csr1.field.Bss0Key0CipherAlg = 0;
-		else if (KeyIdx == 1)
-			csr1.field.Bss0Key1CipherAlg = 0;
-		else if (KeyIdx == 2)
-			csr1.field.Bss0Key2CipherAlg = 0;
-		else
-			csr1.field.Bss0Key3CipherAlg = 0;
-	} else {
-		if (KeyIdx == 0)
-			csr1.field.Bss1Key0CipherAlg = 0;
-		else if (KeyIdx == 1)
-			csr1.field.Bss1Key1CipherAlg = 0;
-		else if (KeyIdx == 2)
-			csr1.field.Bss1Key2CipherAlg = 0;
-		else
-			csr1.field.Bss1Key3CipherAlg = 0;
-	}
-	DBGPRINT(RT_DEBUG_TRACE,
-		 ("Write: SHARED_KEY_MODE_BASE at this Bss[%d] = 0x%x \n",
-		  BssIndex, csr1.word));
-	RTMP_IO_WRITE32(pAd, SHARED_KEY_MODE_BASE + 4 * (BssIndex / 2),
-			csr1.word);
-	ASSERT(BssIndex < 4);
-	ASSERT(KeyIdx < 4);
-
-}
-
-void AsicUpdateWCIDAttribute(struct rt_rtmp_adapter *pAd,
-			     u16 WCID,
-			     u8 BssIndex,
-			     u8 CipherAlg,
-			     IN BOOLEAN bUsePairewiseKeyTable)
-{
-	unsigned long WCIDAttri = 0, offset;
-
-	/* */
-	/* Update WCID attribute. */
-	/* Only TxKey could update WCID attribute. */
-	/* */
-	offset = MAC_WCID_ATTRIBUTE_BASE + (WCID * HW_WCID_ATTRI_SIZE);
-	WCIDAttri =
-	    (BssIndex << 4) | (CipherAlg << 1) | (bUsePairewiseKeyTable);
-	RTMP_IO_WRITE32(pAd, offset, WCIDAttri);
-}
-
-void AsicUpdateWCIDIVEIV(struct rt_rtmp_adapter *pAd,
-			 u16 WCID, unsigned long uIV, unsigned long uEIV)
-{
-	unsigned long offset;
-
-	offset = MAC_IVEIV_TABLE_BASE + (WCID * HW_IVEIV_ENTRY_SIZE);
-
-	RTMP_IO_WRITE32(pAd, offset, uIV);
-	RTMP_IO_WRITE32(pAd, offset + 4, uEIV);
-}
-
-void AsicUpdateRxWCIDTable(struct rt_rtmp_adapter *pAd,
-			   u16 WCID, u8 *pAddr)
-{
-	unsigned long offset;
-	unsigned long Addr;
-
-	offset = MAC_WCID_BASE + (WCID * HW_WCID_ENTRY_SIZE);
-	Addr = pAddr[0] + (pAddr[1] << 8) + (pAddr[2] << 16) + (pAddr[3] << 24);
-	RTMP_IO_WRITE32(pAd, offset, Addr);
-	Addr = pAddr[4] + (pAddr[5] << 8);
-	RTMP_IO_WRITE32(pAd, offset + 4, Addr);
-}
-
-/*
-    ========================================================================
-
-    Routine Description:
-        Set Cipher Key, Cipher algorithm, IV/EIV to Asic
-
-    Arguments:
-        pAd                     Pointer to our adapter
-        WCID                    WCID Entry number.
-        BssIndex                BSSID index, station or none multiple BSSID support
-                                this value should be 0.
-        KeyIdx                  This KeyIdx will set to IV's KeyID if bTxKey enabled
-        pCipherKey              Pointer to Cipher Key.
-        bUsePairewiseKeyTable   TRUE means saved the key in SharedKey table,
-                                otherwise PairewiseKey table
-        bTxKey                  This is the transmit key if enabled.
-
-    Return Value:
-        None
-
-    Note:
-        This routine will set the relative key stuff to Asic including WCID attribute,
-        Cipher Key, Cipher algorithm and IV/EIV.
-
-        IV/EIV will be update if this CipherKey is the transmission key because
-        ASIC will base on IV's KeyID value to select Cipher Key.
-
-        If bTxKey sets to FALSE, this is not the TX key, but it could be
-        RX key
-
-	For AP mode bTxKey must be always set to TRUE.
-    ========================================================================
-*/
-void AsicAddKeyEntry(struct rt_rtmp_adapter *pAd,
-		     u16 WCID,
-		     u8 BssIndex,
-		     u8 KeyIdx,
-		     struct rt_cipher_key *pCipherKey,
-		     IN BOOLEAN bUsePairewiseKeyTable, IN BOOLEAN bTxKey)
-{
-	unsigned long offset;
-/*      unsigned long   WCIDAttri = 0; */
-	u8 IV4 = 0;
-	u8 *pKey = pCipherKey->Key;
-/*      unsigned long           KeyLen = pCipherKey->KeyLen; */
-	u8 *pTxMic = pCipherKey->TxMic;
-	u8 *pRxMic = pCipherKey->RxMic;
-	u8 *pTxtsc = pCipherKey->TxTsc;
-	u8 CipherAlg = pCipherKey->CipherAlg;
-	SHAREDKEY_MODE_STRUC csr1;
-#ifdef RTMP_MAC_PCI
-	u8 i;
-#endif /* RTMP_MAC_PCI // */
-
-/*      ASSERT(KeyLen <= MAX_LEN_OF_PEER_KEY); */
-
-	DBGPRINT(RT_DEBUG_TRACE, ("==> AsicAddKeyEntry\n"));
-	/* */
-	/* 1.) decide key table offset */
-	/* */
-	if (bUsePairewiseKeyTable)
-		offset = PAIRWISE_KEY_TABLE_BASE + (WCID * HW_KEY_ENTRY_SIZE);
-	else
-		offset =
-		    SHARED_KEY_TABLE_BASE + (4 * BssIndex +
-					     KeyIdx) * HW_KEY_ENTRY_SIZE;
-
-	/* */
-	/* 2.) Set Key to Asic */
-	/* */
-	/*for (i = 0; i < KeyLen; i++) */
-#ifdef RTMP_MAC_PCI
-	for (i = 0; i < MAX_LEN_OF_PEER_KEY; i++) {
-		RTMP_IO_WRITE8(pAd, offset + i, pKey[i]);
-	}
-	offset += MAX_LEN_OF_PEER_KEY;
-
-	/* */
-	/* 3.) Set MIC key if available */
-	/* */
-	if (pTxMic) {
-		for (i = 0; i < 8; i++) {
-			RTMP_IO_WRITE8(pAd, offset + i, pTxMic[i]);
-		}
-	}
-	offset += LEN_TKIP_TXMICK;
-
-	if (pRxMic) {
-		for (i = 0; i < 8; i++) {
-			RTMP_IO_WRITE8(pAd, offset + i, pRxMic[i]);
-		}
-	}
-#endif /* RTMP_MAC_PCI // */
-#ifdef RTMP_MAC_USB
-	RTUSBMultiWrite(pAd, offset, pKey, MAX_LEN_OF_PEER_KEY);
-	offset += MAX_LEN_OF_PEER_KEY;
-
-	/* */
-	/* 3.) Set MIC key if available */
-	/* */
-	if (pTxMic) {
-		RTUSBMultiWrite(pAd, offset, pTxMic, 8);
-	}
-	offset += LEN_TKIP_TXMICK;
-
-	if (pRxMic) {
-		RTUSBMultiWrite(pAd, offset, pRxMic, 8);
-	}
-#endif /* RTMP_MAC_USB // */
-
-	/* */
-	/* 4.) Modify IV/EIV if needs */
-	/*     This will force Asic to use this key ID by setting IV. */
-	/* */
-	if (bTxKey) {
-#ifdef RTMP_MAC_PCI
-		offset = MAC_IVEIV_TABLE_BASE + (WCID * HW_IVEIV_ENTRY_SIZE);
-		/* */
-		/* Write IV */
-		/* */
-		RTMP_IO_WRITE8(pAd, offset, pTxtsc[1]);
-		RTMP_IO_WRITE8(pAd, offset + 1, ((pTxtsc[1] | 0x20) & 0x7f));
-		RTMP_IO_WRITE8(pAd, offset + 2, pTxtsc[0]);
-
-		IV4 = (KeyIdx << 6);
-		if ((CipherAlg == CIPHER_TKIP)
-		    || (CipherAlg == CIPHER_TKIP_NO_MIC)
-		    || (CipherAlg == CIPHER_AES))
-			IV4 |= 0x20;	/* turn on extension bit means EIV existence */
-
-		RTMP_IO_WRITE8(pAd, offset + 3, IV4);
-
-		/* */
-		/* Write EIV */
-		/* */
-		offset += 4;
-		for (i = 0; i < 4; i++) {
-			RTMP_IO_WRITE8(pAd, offset + i, pTxtsc[i + 2]);
-		}
-#endif /* RTMP_MAC_PCI // */
-#ifdef RTMP_MAC_USB
-		u32 tmpVal;
-
-		/* */
-		/* Write IV */
-		/* */
-		IV4 = (KeyIdx << 6);
-		if ((CipherAlg == CIPHER_TKIP)
-		    || (CipherAlg == CIPHER_TKIP_NO_MIC)
-		    || (CipherAlg == CIPHER_AES))
-			IV4 |= 0x20;	/* turn on extension bit means EIV existence */
-
-		tmpVal =
-		    pTxtsc[1] + (((pTxtsc[1] | 0x20) & 0x7f) << 8) +
-		    (pTxtsc[0] << 16) + (IV4 << 24);
-		RTMP_IO_WRITE32(pAd, offset, tmpVal);
-
-		/* */
-		/* Write EIV */
-		/* */
-		offset += 4;
-		RTMP_IO_WRITE32(pAd, offset, *(u32 *)& pCipherKey->TxTsc[2]);
-#endif /* RTMP_MAC_USB // */
-
-		AsicUpdateWCIDAttribute(pAd, WCID, BssIndex, CipherAlg,
-					bUsePairewiseKeyTable);
-	}
-
-	if (!bUsePairewiseKeyTable) {
-		/* */
-		/* Only update the shared key security mode */
-		/* */
-		RTMP_IO_READ32(pAd, SHARED_KEY_MODE_BASE + 4 * (BssIndex / 2),
-			       &csr1.word);
-		if ((BssIndex % 2) == 0) {
-			if (KeyIdx == 0)
-				csr1.field.Bss0Key0CipherAlg = CipherAlg;
-			else if (KeyIdx == 1)
-				csr1.field.Bss0Key1CipherAlg = CipherAlg;
-			else if (KeyIdx == 2)
-				csr1.field.Bss0Key2CipherAlg = CipherAlg;
-			else
-				csr1.field.Bss0Key3CipherAlg = CipherAlg;
-		} else {
-			if (KeyIdx == 0)
-				csr1.field.Bss1Key0CipherAlg = CipherAlg;
-			else if (KeyIdx == 1)
-				csr1.field.Bss1Key1CipherAlg = CipherAlg;
-			else if (KeyIdx == 2)
-				csr1.field.Bss1Key2CipherAlg = CipherAlg;
-			else
-				csr1.field.Bss1Key3CipherAlg = CipherAlg;
-		}
-		RTMP_IO_WRITE32(pAd, SHARED_KEY_MODE_BASE + 4 * (BssIndex / 2),
-				csr1.word);
-	}
-
-	DBGPRINT(RT_DEBUG_TRACE, ("<== AsicAddKeyEntry\n"));
-}
-
-/*
-	========================================================================
-	Description:
-		Add Pair-wise key material into ASIC.
-		Update pairwise key, TxMic and RxMic to Asic Pair-wise key table
-
-    Return:
-	========================================================================
-*/
-void AsicAddPairwiseKeyEntry(struct rt_rtmp_adapter *pAd,
-			     u8 *pAddr,
-			     u8 WCID, struct rt_cipher_key *pCipherKey)
-{
-	int i;
-	unsigned long offset;
-	u8 *pKey = pCipherKey->Key;
-	u8 *pTxMic = pCipherKey->TxMic;
-	u8 *pRxMic = pCipherKey->RxMic;
-#ifdef DBG
-	u8 CipherAlg = pCipherKey->CipherAlg;
-#endif /* DBG // */
-
-	/* EKEY */
-	offset = PAIRWISE_KEY_TABLE_BASE + (WCID * HW_KEY_ENTRY_SIZE);
-#ifdef RTMP_MAC_PCI
-	for (i = 0; i < MAX_LEN_OF_PEER_KEY; i++) {
-		RTMP_IO_WRITE8(pAd, offset + i, pKey[i]);
-	}
-#endif /* RTMP_MAC_PCI // */
-#ifdef RTMP_MAC_USB
-	RTUSBMultiWrite(pAd, offset, &pCipherKey->Key[0], MAX_LEN_OF_PEER_KEY);
-#endif /* RTMP_MAC_USB // */
-	for (i = 0; i < MAX_LEN_OF_PEER_KEY; i += 4) {
-		u32 Value;
-		RTMP_IO_READ32(pAd, offset + i, &Value);
-	}
-
-	offset += MAX_LEN_OF_PEER_KEY;
-
-	/*  MIC KEY */
-	if (pTxMic) {
-#ifdef RTMP_MAC_PCI
-		for (i = 0; i < 8; i++) {
-			RTMP_IO_WRITE8(pAd, offset + i, pTxMic[i]);
-		}
-#endif /* RTMP_MAC_PCI // */
-#ifdef RTMP_MAC_USB
-		RTUSBMultiWrite(pAd, offset, &pCipherKey->TxMic[0], 8);
-#endif /* RTMP_MAC_USB // */
-	}
-	offset += 8;
-	if (pRxMic) {
-#ifdef RTMP_MAC_PCI
-		for (i = 0; i < 8; i++) {
-			RTMP_IO_WRITE8(pAd, offset + i, pRxMic[i]);
-		}
-#endif /* RTMP_MAC_PCI // */
-#ifdef RTMP_MAC_USB
-		RTUSBMultiWrite(pAd, offset, &pCipherKey->RxMic[0], 8);
-#endif /* RTMP_MAC_USB // */
-	}
-
-	DBGPRINT(RT_DEBUG_TRACE,
-		 ("AsicAddPairwiseKeyEntry: WCID #%d Alg=%s\n", WCID,
-		  CipherName[CipherAlg]));
-	DBGPRINT(RT_DEBUG_TRACE,
-		 ("	Key = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
-		  pKey[0], pKey[1], pKey[2], pKey[3], pKey[4], pKey[5],
-		  pKey[6], pKey[7], pKey[8], pKey[9], pKey[10], pKey[11],
-		  pKey[12], pKey[13], pKey[14], pKey[15]));
-	if (pRxMic) {
-		DBGPRINT(RT_DEBUG_TRACE,
-			 ("	Rx MIC Key = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
-			  pRxMic[0], pRxMic[1], pRxMic[2], pRxMic[3],
-			  pRxMic[4], pRxMic[5], pRxMic[6], pRxMic[7]));
-	}
-	if (pTxMic) {
-		DBGPRINT(RT_DEBUG_TRACE,
-			 ("	Tx MIC Key = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
-			  pTxMic[0], pTxMic[1], pTxMic[2], pTxMic[3],
-			  pTxMic[4], pTxMic[5], pTxMic[6], pTxMic[7]));
-	}
-}
-
-/*
-	========================================================================
-	Description:
-		Remove Pair-wise key material from ASIC.
-
-    Return:
-	========================================================================
-*/
-void AsicRemovePairwiseKeyEntry(struct rt_rtmp_adapter *pAd,
-				u8 BssIdx, u8 Wcid)
-{
-	unsigned long WCIDAttri;
-	u16 offset;
-
-	/* re-set the entry's WCID attribute as OPEN-NONE. */
-	offset = MAC_WCID_ATTRIBUTE_BASE + (Wcid * HW_WCID_ATTRI_SIZE);
-	WCIDAttri = (BssIdx << 4) | PAIRWISEKEYTABLE;
-	RTMP_IO_WRITE32(pAd, offset, WCIDAttri);
-}
-
-BOOLEAN AsicSendCommandToMcu(struct rt_rtmp_adapter *pAd,
-			     u8 Command,
-			     u8 Token, u8 Arg0, u8 Arg1)
-{
-
-	if (pAd->chipOps.sendCommandToMcu)
-		pAd->chipOps.sendCommandToMcu(pAd, Command, Token, Arg0, Arg1);
-
-	return TRUE;
-}
-
-void AsicSetRxAnt(struct rt_rtmp_adapter *pAd, u8 Ant)
-{
-#ifdef RT30xx
-	/* RT3572 ATE need not to do this. */
-	RT30xxSetRxAnt(pAd, Ant);
-#endif /* RT30xx // */
-}
-
-void AsicTurnOffRFClk(struct rt_rtmp_adapter *pAd, u8 Channel)
-{
-	if (pAd->chipOps.AsicRfTurnOff) {
-		pAd->chipOps.AsicRfTurnOff(pAd);
-	} else {
-		/* RF R2 bit 18 = 0 */
-		u32 R1 = 0, R2 = 0, R3 = 0;
-		u8 index;
-		struct rt_rtmp_rf_regs *RFRegTable;
-
-		RFRegTable = RF2850RegTable;
-
-		switch (pAd->RfIcType) {
-		case RFIC_2820:
-		case RFIC_2850:
-		case RFIC_2720:
-		case RFIC_2750:
-
-			for (index = 0; index < NUM_OF_2850_CHNL; index++) {
-				if (Channel == RFRegTable[index].Channel) {
-					R1 = RFRegTable[index].R1 & 0xffffdfff;
-					R2 = RFRegTable[index].R2 & 0xfffbffff;
-					R3 = RFRegTable[index].R3 & 0xfff3ffff;
-
-					RTMP_RF_IO_WRITE32(pAd, R1);
-					RTMP_RF_IO_WRITE32(pAd, R2);
-
-					/* Program R1b13 to 1, R3/b18,19 to 0, R2b18 to 0. */
-					/* Set RF R2 bit18=0, R3 bit[18:19]=0 */
-					/*if (pAd->StaCfg.bRadio == FALSE) */
-					if (1) {
-						RTMP_RF_IO_WRITE32(pAd, R3);
-
-						DBGPRINT(RT_DEBUG_TRACE,
-							 ("AsicTurnOffRFClk#%d(RF=%d, ) , R2=0x%08x,  R3 = 0x%08x \n",
-							  Channel,
-							  pAd->RfIcType, R2,
-							  R3));
-					} else
-						DBGPRINT(RT_DEBUG_TRACE,
-							 ("AsicTurnOffRFClk#%d(RF=%d, ) , R2=0x%08x \n",
-							  Channel,
-							  pAd->RfIcType, R2));
-					break;
-				}
-			}
-			break;
-
-		default:
-			break;
-		}
-	}
-}
-
-void AsicTurnOnRFClk(struct rt_rtmp_adapter *pAd, u8 Channel)
-{
-	/* RF R2 bit 18 = 0 */
-	u32 R1 = 0, R2 = 0, R3 = 0;
-	u8 index;
-	struct rt_rtmp_rf_regs *RFRegTable;
-
-#ifdef PCIE_PS_SUPPORT
-	/* The RF programming sequence is difference between 3xxx and 2xxx */
-	if ((IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd))) {
-		return;
-	}
-#endif /* PCIE_PS_SUPPORT // */
-
-	RFRegTable = RF2850RegTable;
-
-	switch (pAd->RfIcType) {
-	case RFIC_2820:
-	case RFIC_2850:
-	case RFIC_2720:
-	case RFIC_2750:
-
-		for (index = 0; index < NUM_OF_2850_CHNL; index++) {
-			if (Channel == RFRegTable[index].Channel) {
-				R3 = pAd->LatchRfRegs.R3;
-				R3 &= 0xfff3ffff;
-				R3 |= 0x00080000;
-				RTMP_RF_IO_WRITE32(pAd, R3);
-
-				R1 = RFRegTable[index].R1;
-				RTMP_RF_IO_WRITE32(pAd, R1);
-
-				R2 = RFRegTable[index].R2;
-				if (pAd->Antenna.field.TxPath == 1) {
-					R2 |= 0x4000;	/* If TXpath is 1, bit 14 = 1; */
-				}
-
-				if (pAd->Antenna.field.RxPath == 2) {
-					R2 |= 0x40;	/* write 1 to off Rxpath. */
-				} else if (pAd->Antenna.field.RxPath == 1) {
-					R2 |= 0x20040;	/* write 1 to off RxPath */
-				}
-				RTMP_RF_IO_WRITE32(pAd, R2);
-
-				break;
-			}
-		}
-		break;
-
-	default:
-		break;
-	}
-
-	DBGPRINT(RT_DEBUG_TRACE, ("AsicTurnOnRFClk#%d(RF=%d, ) , R2=0x%08x\n",
-				  Channel, pAd->RfIcType, R2));
-}
diff -druN linux-2.6.39-libre/drivers/staging/rt2860/common/cmm_cfg.c linux-3.0-rc7-libre/drivers/staging/rt2860/common/cmm_cfg.c
--- linux-2.6.39-libre/drivers/staging/rt2860/common/cmm_cfg.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rt2860/common/cmm_cfg.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,258 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, 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.             *
- *                                                                       *
- *************************************************************************
-
-    Module Name:
-	cmm_cfg.c
-
-    Abstract:
-    Ralink WiFi Driver configuration related subroutines
-
-    Revision History:
-    Who          When          What
-    ---------    ----------    ----------------------------------------------
-*/
-
-#include "../rt_config.h"
-
-char *GetPhyMode(int Mode)
-{
-	switch (Mode) {
-	case MODE_CCK:
-		return "CCK";
-
-	case MODE_OFDM:
-		return "OFDM";
-	case MODE_HTMIX:
-		return "HTMIX";
-
-	case MODE_HTGREENFIELD:
-		return "GREEN";
-	default:
-		return "N/A";
-	}
-}
-
-char *GetBW(int BW)
-{
-	switch (BW) {
-	case BW_10:
-		return "10M";
-
-	case BW_20:
-		return "20M";
-	case BW_40:
-		return "40M";
-	default:
-		return "N/A";
-	}
-}
-
-/*
-    ==========================================================================
-    Description:
-        Set Country Region to pAd->CommonCfg.CountryRegion.
-        This command will not work, if the field of CountryRegion in eeprom is programmed.
-
-    Return:
-        TRUE if all parameters are OK, FALSE otherwise
-    ==========================================================================
-*/
-int RT_CfgSetCountryRegion(struct rt_rtmp_adapter *pAd, char *arg, int band)
-{
-	long region, regionMax;
-	u8 *pCountryRegion;
-
-	region = simple_strtol(arg, 0, 10);
-
-	if (band == BAND_24G) {
-		pCountryRegion = &pAd->CommonCfg.CountryRegion;
-		regionMax = REGION_MAXIMUM_BG_BAND;
-	} else {
-		pCountryRegion = &pAd->CommonCfg.CountryRegionForABand;
-		regionMax = REGION_MAXIMUM_A_BAND;
-	}
-
-	/* TODO: Is it neccesay for following check??? */
-	/* Country can be set only when EEPROM not programmed */
-	if (*pCountryRegion & 0x80) {
-		DBGPRINT(RT_DEBUG_ERROR,
-			 ("CfgSetCountryRegion():CountryRegion in eeprom was programmed\n"));
-		return FALSE;
-	}
-
-	if ((region >= 0) && (region <= REGION_MAXIMUM_BG_BAND)) {
-		*pCountryRegion = (u8)region;
-	} else if ((region == REGION_31_BG_BAND) && (band == BAND_24G)) {
-		*pCountryRegion = (u8)region;
-	} else {
-		DBGPRINT(RT_DEBUG_ERROR,
-			 ("CfgSetCountryRegion():region(%ld) out of range!\n",
-			  region));
-		return FALSE;
-	}
-
-	return TRUE;
-
-}
-
-/*
-    ==========================================================================
-    Description:
-        Set Wireless Mode
-    Return:
-        TRUE if all parameters are OK, FALSE otherwise
-    ==========================================================================
-*/
-int RT_CfgSetWirelessMode(struct rt_rtmp_adapter *pAd, char *arg)
-{
-	int MaxPhyMode = PHY_11G;
-	long WirelessMode;
-
-	MaxPhyMode = PHY_11N_5G;
-
-	WirelessMode = simple_strtol(arg, 0, 10);
-	if (WirelessMode <= MaxPhyMode) {
-		pAd->CommonCfg.PhyMode = WirelessMode;
-		return TRUE;
-	}
-
-	return FALSE;
-
-}
-
-int RT_CfgSetShortSlot(struct rt_rtmp_adapter *pAd, char *arg)
-{
-	long ShortSlot;
-
-	ShortSlot = simple_strtol(arg, 0, 10);
-
-	if (ShortSlot == 1)
-		pAd->CommonCfg.bUseShortSlotTime = TRUE;
-	else if (ShortSlot == 0)
-		pAd->CommonCfg.bUseShortSlotTime = FALSE;
-	else
-		return FALSE;	/*Invalid argument */
-
-	return TRUE;
-}
-
-/*
-    ==========================================================================
-    Description:
-        Set WEP KEY base on KeyIdx
-    Return:
-        TRUE if all parameters are OK, FALSE otherwise
-    ==========================================================================
-*/
-int RT_CfgSetWepKey(struct rt_rtmp_adapter *pAd,
-		    char *keyString,
-		    struct rt_cipher_key *pSharedKey, int keyIdx)
-{
-	int KeyLen;
-	int i;
-	u8 CipherAlg = CIPHER_NONE;
-	BOOLEAN bKeyIsHex = FALSE;
-
-	/* TODO: Shall we do memset for the original key info?? */
-	memset(pSharedKey, 0, sizeof(struct rt_cipher_key));
-	KeyLen = strlen(keyString);
-	switch (KeyLen) {
-	case 5:		/*wep 40 Ascii type */
-	case 13:		/*wep 104 Ascii type */
-		bKeyIsHex = FALSE;
-		pSharedKey->KeyLen = KeyLen;
-		NdisMoveMemory(pSharedKey->Key, keyString, KeyLen);
-		break;
-
-	case 10:		/*wep 40 Hex type */
-	case 26:		/*wep 104 Hex type */
-		for (i = 0; i < KeyLen; i++) {
-			if (!isxdigit(*(keyString + i)))
-				return FALSE;	/*Not Hex value; */
-		}
-		bKeyIsHex = TRUE;
-		pSharedKey->KeyLen = KeyLen / 2;
-		AtoH(keyString, pSharedKey->Key, pSharedKey->KeyLen);
-		break;
-
-	default:		/*Invalid argument */
-		DBGPRINT(RT_DEBUG_TRACE,
-			 ("RT_CfgSetWepKey(keyIdx=%d):Invalid argument (arg=%s)\n",
-			  keyIdx, keyString));
-		return FALSE;
-	}
-
-	pSharedKey->CipherAlg = ((KeyLen % 5) ? CIPHER_WEP128 : CIPHER_WEP64);
-	DBGPRINT(RT_DEBUG_TRACE,
-		 ("RT_CfgSetWepKey:(KeyIdx=%d,type=%s, Alg=%s)\n", keyIdx,
-		  (bKeyIsHex == FALSE ? "Ascii" : "Hex"),
-		  CipherName[CipherAlg]));
-
-	return TRUE;
-}
-
-/*
-    ==========================================================================
-    Description:
-        Set WPA PSK key
-
-    Arguments:
-        pAdapter	Pointer to our adapter
-        keyString	WPA pre-shared key string
-        pHashStr	String used for password hash function
-        hashStrLen	Length of the hash string
-        pPMKBuf		Output buffer of WPAPSK key
-
-    Return:
-        TRUE if all parameters are OK, FALSE otherwise
-    ==========================================================================
-*/
-int RT_CfgSetWPAPSKKey(struct rt_rtmp_adapter *pAd,
-		       char *keyString,
-		       u8 * pHashStr,
-		       int hashStrLen, u8 *pPMKBuf)
-{
-	int keyLen;
-	u8 keyMaterial[40];
-
-	keyLen = strlen(keyString);
-	if ((keyLen < 8) || (keyLen > 64)) {
-		DBGPRINT(RT_DEBUG_TRACE,
-			 ("WPAPSK Key length(%d) error, required 8 ~ 64 characters!(keyStr=%s)\n",
-			  keyLen, keyString));
-		return FALSE;
-	}
-
-	memset(pPMKBuf, 0, 32);
-	if (keyLen == 64) {
-		AtoH(keyString, pPMKBuf, 32);
-	} else {
-		PasswordHash(keyString, pHashStr, hashStrLen, keyMaterial);
-		NdisMoveMemory(pPMKBuf, keyMaterial, 32);
-	}
-
-	return TRUE;
-}
diff -druN linux-2.6.39-libre/drivers/staging/rt2860/common/cmm_data.c linux-3.0-rc7-libre/drivers/staging/rt2860/common/cmm_data.c
--- linux-2.6.39-libre/drivers/staging/rt2860/common/cmm_data.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rt2860/common/cmm_data.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,2361 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, Inc.
- *
- * This program is free software; you can redistribute it and/or modify  *
- * it under the terms of the GNU General Public License as published by  *
- * the Free Software Foundation; either version 2 of the License, or     *
- * (at your option) any later version.                                   *
- *                                                                       *
- * This program is distributed in the hope that it will be useful,       *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of        *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
- * GNU General Public License for more details.                          *
- *                                                                       *
- * You should have received a copy of the GNU General Public License     *
- * along with this program; if not, write to the                         *
- * Free Software Foundation, Inc.,                                       *
- * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
- *                                                                       *
- *************************************************************************
-*/
-
-#include "../rt_config.h"
-
-u8 SNAP_802_1H[] = { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00 };
-u8 SNAP_BRIDGE_TUNNEL[] = { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0xf8 };
-
-/* Add Cisco Aironet SNAP heade for CCX2 support */
-u8 SNAP_AIRONET[] = { 0xaa, 0xaa, 0x03, 0x00, 0x40, 0x96, 0x00, 0x00 };
-u8 CKIP_LLC_SNAP[] = { 0xaa, 0xaa, 0x03, 0x00, 0x40, 0x96, 0x00, 0x02 };
-u8 EAPOL_LLC_SNAP[] = { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00, 0x88, 0x8e };
-u8 EAPOL[] = { 0x88, 0x8e };
-u8 TPID[] = { 0x81, 0x00 };	/* VLAN related */
-
-u8 IPX[] = { 0x81, 0x37 };
-u8 APPLE_TALK[] = { 0x80, 0xf3 };
-
-u8 RateIdToPlcpSignal[12] = {
-	0, /* RATE_1 */ 1, /* RATE_2 */ 2, /* RATE_5_5 */ 3,	/* RATE_11 *//* see BBP spec */
-	11, /* RATE_6 */ 15, /* RATE_9 */ 10, /* RATE_12 */ 14,	/* RATE_18 *//* see IEEE802.11a-1999 p.14 */
-	9, /* RATE_24 */ 13, /* RATE_36 */ 8, /* RATE_48 */ 12 /* RATE_54 */
-};				/* see IEEE802.11a-1999 p.14 */
-
-u8 OfdmSignalToRateId[16] = {
-	RATE_54, RATE_54, RATE_54, RATE_54,	/* OFDM PLCP Signal = 0,  1,  2,  3 respectively */
-	RATE_54, RATE_54, RATE_54, RATE_54,	/* OFDM PLCP Signal = 4,  5,  6,  7 respectively */
-	RATE_48, RATE_24, RATE_12, RATE_6,	/* OFDM PLCP Signal = 8,  9,  10, 11 respectively */
-	RATE_54, RATE_36, RATE_18, RATE_9,	/* OFDM PLCP Signal = 12, 13, 14, 15 respectively */
-};
-
-u8 OfdmRateToRxwiMCS[12] = {
-	0, 0, 0, 0,
-	0, 1, 2, 3,		/* OFDM rate 6,9,12,18 = rxwi mcs 0,1,2,3 */
-	4, 5, 6, 7,		/* OFDM rate 24,36,48,54 = rxwi mcs 4,5,6,7 */
-};
-
-u8 RxwiMCSToOfdmRate[12] = {
-	RATE_6, RATE_9, RATE_12, RATE_18,
-	RATE_24, RATE_36, RATE_48, RATE_54,	/* OFDM rate 6,9,12,18 = rxwi mcs 0,1,2,3 */
-	4, 5, 6, 7,		/* OFDM rate 24,36,48,54 = rxwi mcs 4,5,6,7 */
-};
-
-char *MCSToMbps[] =
-    { "1Mbps", "2Mbps", "5.5Mbps", "11Mbps", "06Mbps", "09Mbps", "12Mbps",
-"18Mbps", "24Mbps", "36Mbps", "48Mbps", "54Mbps", "MM-0", "MM-1", "MM-2", "MM-3",
-"MM-4", "MM-5", "MM-6", "MM-7", "MM-8", "MM-9", "MM-10", "MM-11", "MM-12", "MM-13",
-"MM-14", "MM-15", "MM-32", "ee1", "ee2", "ee3" };
-
-u8 default_cwmin[] =
-    { CW_MIN_IN_BITS, CW_MIN_IN_BITS, CW_MIN_IN_BITS - 1, CW_MIN_IN_BITS - 2 };
-/*u8 default_cwmax[]={CW_MAX_IN_BITS, CW_MAX_IN_BITS, CW_MIN_IN_BITS, CW_MIN_IN_BITS-1}; */
-u8 default_sta_aifsn[] = { 3, 7, 2, 2 };
-
-u8 MapUserPriorityToAccessCategory[8] =
-    { QID_AC_BE, QID_AC_BK, QID_AC_BK, QID_AC_BE, QID_AC_VI, QID_AC_VI,
-QID_AC_VO, QID_AC_VO };
-
-/*
-	========================================================================
-
-	Routine Description:
-		API for MLME to transmit management frame to AP (BSS Mode)
-	or station (IBSS Mode)
-
-	Arguments:
-		pAd Pointer to our adapter
-		pData		Pointer to the outgoing 802.11 frame
-		Length		Size of outgoing management frame
-
-	Return Value:
-		NDIS_STATUS_FAILURE
-		NDIS_STATUS_PENDING
-		NDIS_STATUS_SUCCESS
-
-	IRQL = PASSIVE_LEVEL
-	IRQL = DISPATCH_LEVEL
-
-	Note:
-
-	========================================================================
-*/
-int MiniportMMRequest(struct rt_rtmp_adapter *pAd,
-			      u8 QueIdx, u8 *pData, u32 Length)
-{
-	void *pPacket;
-	int Status = NDIS_STATUS_SUCCESS;
-	unsigned long FreeNum;
-	u8 rtmpHwHdr[TXINFO_SIZE + TXWI_SIZE];	/*RTMP_HW_HDR_LEN]; */
-#ifdef RTMP_MAC_PCI
-	unsigned long IrqFlags = 0;
-	u8 IrqState;
-#endif /* RTMP_MAC_PCI // */
-	BOOLEAN bUseDataQ = FALSE;
-	int retryCnt = 0;
-
-	ASSERT(Length <= MGMT_DMA_BUFFER_SIZE);
-
-	if ((QueIdx & MGMT_USE_QUEUE_FLAG) == MGMT_USE_QUEUE_FLAG) {
-		bUseDataQ = TRUE;
-		QueIdx &= (~MGMT_USE_QUEUE_FLAG);
-	}
-#ifdef RTMP_MAC_PCI
-	/* 2860C use Tx Ring */
-	IrqState = pAd->irq_disabled;
-	if (pAd->MACVersion == 0x28600100) {
-		QueIdx = (bUseDataQ == TRUE ? QueIdx : 3);
-		bUseDataQ = TRUE;
-	}
-	if (bUseDataQ && (!IrqState))
-		RTMP_IRQ_LOCK(&pAd->irq_lock, IrqFlags);
-#endif /* RTMP_MAC_PCI // */
-
-	do {
-		/* Reset is in progress, stop immediately */
-		if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS) ||
-		    RTMP_TEST_FLAG(pAd,
-				   fRTMP_ADAPTER_HALT_IN_PROGRESS |
-				   fRTMP_ADAPTER_NIC_NOT_EXIST)
-		    || !RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_START_UP)) {
-			Status = NDIS_STATUS_FAILURE;
-			break;
-		}
-		/* Check Free priority queue */
-		/* Since we use PBF Queue2 for management frame.  Its corresponding DMA ring should be using TxRing. */
-#ifdef RTMP_MAC_PCI
-		if (bUseDataQ) {
-			retryCnt = MAX_DATAMM_RETRY;
-			/* free Tx(QueIdx) resources */
-			RTMPFreeTXDUponTxDmaDone(pAd, QueIdx);
-			FreeNum = GET_TXRING_FREENO(pAd, QueIdx);
-		} else
-#endif /* RTMP_MAC_PCI // */
-		{
-			FreeNum = GET_MGMTRING_FREENO(pAd);
-		}
-
-		if ((FreeNum > 0)) {
-			/* We need to reserve space for rtmp hardware header. i.e., TxWI for RT2860 and TxInfo+TxWI for RT2870 */
-			NdisZeroMemory(&rtmpHwHdr, (TXINFO_SIZE + TXWI_SIZE));
-			Status =
-			    RTMPAllocateNdisPacket(pAd, &pPacket,
-						   (u8 *)& rtmpHwHdr,
-						   (TXINFO_SIZE + TXWI_SIZE),
-						   pData, Length);
-			if (Status != NDIS_STATUS_SUCCESS) {
-				DBGPRINT(RT_DEBUG_WARN,
-					 ("MiniportMMRequest (error:: can't allocate NDIS PACKET)\n"));
-				break;
-			}
-			/*pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_CCK; */
-			/*pAd->CommonCfg.MlmeRate = RATE_2; */
-
-#ifdef RTMP_MAC_PCI
-			if (bUseDataQ) {
-				Status =
-				    MlmeDataHardTransmit(pAd, QueIdx, pPacket);
-				retryCnt--;
-			} else
-#endif /* RTMP_MAC_PCI // */
-				Status = MlmeHardTransmit(pAd, QueIdx, pPacket);
-			if (Status == NDIS_STATUS_SUCCESS)
-				retryCnt = 0;
-			else
-				RTMPFreeNdisPacket(pAd, pPacket);
-		} else {
-			pAd->RalinkCounters.MgmtRingFullCount++;
-#ifdef RTMP_MAC_PCI
-			if (bUseDataQ) {
-				retryCnt--;
-				DBGPRINT(RT_DEBUG_TRACE,
-					 ("retryCnt %d\n", retryCnt));
-				if (retryCnt == 0) {
-					DBGPRINT(RT_DEBUG_ERROR,
-						 ("Qidx(%d), not enough space in DataRing, MgmtRingFullCount=%ld!\n",
-						  QueIdx,
-						  pAd->RalinkCounters.
-						  MgmtRingFullCount));
-				}
-			}
-#endif /* RTMP_MAC_PCI // */
-			DBGPRINT(RT_DEBUG_ERROR,
-				 ("Qidx(%d), not enough space in MgmtRing, MgmtRingFullCount=%ld!\n",
-				  QueIdx,
-				  pAd->RalinkCounters.MgmtRingFullCount));
-		}
-	} while (retryCnt > 0);
-
-#ifdef RTMP_MAC_PCI
-	if (bUseDataQ && (!IrqState))
-		RTMP_IRQ_UNLOCK(&pAd->irq_lock, IrqFlags);
-#endif /* RTMP_MAC_PCI // */
-
-	return Status;
-}
-
-/*
-	========================================================================
-
-	Routine Description:
-		Copy frame from waiting queue into relative ring buffer and set
-	appropriate ASIC register to kick hardware transmit function
-
-	Arguments:
-		pAd Pointer to our adapter
-		pBuffer 	Pointer to	memory of outgoing frame
-		Length		Size of outgoing management frame
-
-	Return Value:
-		NDIS_STATUS_FAILURE
-		NDIS_STATUS_PENDING
-		NDIS_STATUS_SUCCESS
-
-	IRQL = PASSIVE_LEVEL
-	IRQL = DISPATCH_LEVEL
-
-	Note:
-
-	========================================================================
-*/
-int MlmeHardTransmit(struct rt_rtmp_adapter *pAd,
-			     u8 QueIdx, void *pPacket)
-{
-	struct rt_packet_info PacketInfo;
-	u8 *pSrcBufVA;
-	u32 SrcBufLen;
-	struct rt_header_802_11 * pHeader_802_11;
-
-	if ((pAd->CommonCfg.RadarDetect.RDMode != RD_NORMAL_MODE)
-	    ) {
-		return NDIS_STATUS_FAILURE;
-	}
-
-	RTMP_QueryPacketInfo(pPacket, &PacketInfo, &pSrcBufVA, &SrcBufLen);
-	if (pSrcBufVA == NULL)
-		return NDIS_STATUS_FAILURE;
-
-	pHeader_802_11 = (struct rt_header_802_11 *) (pSrcBufVA + TXINFO_SIZE + TXWI_SIZE);
-
-#ifdef RTMP_MAC_PCI
-	if (pAd->MACVersion == 0x28600100)
-		return MlmeHardTransmitTxRing(pAd, QueIdx, pPacket);
-	else
-#endif /* RTMP_MAC_PCI // */
-		return MlmeHardTransmitMgmtRing(pAd, QueIdx, pPacket);
-
-}
-
-int MlmeHardTransmitMgmtRing(struct rt_rtmp_adapter *pAd,
-				     u8 QueIdx, void *pPacket)
-{
-	struct rt_packet_info PacketInfo;
-	u8 *pSrcBufVA;
-	u32 SrcBufLen;
-	struct rt_header_802_11 * pHeader_802_11;
-	BOOLEAN bAckRequired, bInsertTimestamp;
-	u8 MlmeRate;
-	struct rt_txwi * pFirstTxWI;
-	struct rt_mac_table_entry *pMacEntry = NULL;
-	u8 PID;
-
-	RTMP_QueryPacketInfo(pPacket, &PacketInfo, &pSrcBufVA, &SrcBufLen);
-
-	/* Make sure MGMT ring resource won't be used by other threads */
-	RTMP_SEM_LOCK(&pAd->MgmtRingLock);
-	if (pSrcBufVA == NULL) {
-		/* The buffer shouldn't be NULL */
-		RTMP_SEM_UNLOCK(&pAd->MgmtRingLock);
-		return NDIS_STATUS_FAILURE;
-	}
-
-	{
-		/* outgoing frame always wakeup PHY to prevent frame lost */
-		if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
-			AsicForceWakeup(pAd, TRUE);
-	}
-
-	pFirstTxWI = (struct rt_txwi *) (pSrcBufVA + TXINFO_SIZE);
-	pHeader_802_11 = (struct rt_header_802_11 *) (pSrcBufVA + TXINFO_SIZE + TXWI_SIZE);	/*TXWI_SIZE); */
-
-	if (pHeader_802_11->Addr1[0] & 0x01) {
-		MlmeRate = pAd->CommonCfg.BasicMlmeRate;
-	} else {
-		MlmeRate = pAd->CommonCfg.MlmeRate;
-	}
-
-	/* Verify Mlme rate for a / g bands. */
-	if ((pAd->LatchRfRegs.Channel > 14) && (MlmeRate < RATE_6))	/* 11A band */
-		MlmeRate = RATE_6;
-
-	if ((pHeader_802_11->FC.Type == BTYPE_DATA) &&
-	    (pHeader_802_11->FC.SubType == SUBTYPE_QOS_NULL)) {
-		pMacEntry = MacTableLookup(pAd, pHeader_802_11->Addr1);
-	}
-
-	{
-		/* Fixed W52 with Activity scan issue in ABG_MIXED and ABGN_MIXED mode. */
-		if (pAd->CommonCfg.PhyMode == PHY_11ABG_MIXED
-		    || pAd->CommonCfg.PhyMode == PHY_11ABGN_MIXED) {
-			if (pAd->LatchRfRegs.Channel > 14)
-				pAd->CommonCfg.MlmeTransmit.field.MODE = 1;
-			else
-				pAd->CommonCfg.MlmeTransmit.field.MODE = 0;
-		}
-	}
-
-	/* */
-	/* Should not be hard code to set PwrMgmt to 0 (PWR_ACTIVE) */
-	/* Snice it's been set to 0 while on MgtMacHeaderInit */
-	/* By the way this will cause frame to be send on PWR_SAVE failed. */
-	/* */
-	pHeader_802_11->FC.PwrMgmt = PWR_ACTIVE;	/* (pAd->StaCfg.Psm == PWR_SAVE); */
-
-	/* */
-	/* In WMM-UAPSD, mlme frame should be set psm as power saving but probe request frame */
-	/* Data-Null packets also pass through MMRequest in RT2860, however, we hope control the psm bit to pass APSD */
-/*      if ((pHeader_802_11->FC.Type != BTYPE_DATA) && (pHeader_802_11->FC.Type != BTYPE_CNTL)) */
-	{
-		if ((pHeader_802_11->FC.SubType == SUBTYPE_ACTION) ||
-		    ((pHeader_802_11->FC.Type == BTYPE_DATA) &&
-		     ((pHeader_802_11->FC.SubType == SUBTYPE_QOS_NULL) ||
-		      (pHeader_802_11->FC.SubType == SUBTYPE_NULL_FUNC)))) {
-			if (pAd->StaCfg.Psm == PWR_SAVE)
-				pHeader_802_11->FC.PwrMgmt = PWR_SAVE;
-			else
-				pHeader_802_11->FC.PwrMgmt =
-				    pAd->CommonCfg.bAPSDForcePowerSave;
-		}
-	}
-
-	bInsertTimestamp = FALSE;
-	if (pHeader_802_11->FC.Type == BTYPE_CNTL)	/* must be PS-POLL */
-	{
-		/*Set PM bit in ps-poll, to fix WLK 1.2  PowerSaveMode_ext failure issue. */
-		if ((pAd->OpMode == OPMODE_STA)
-		    && (pHeader_802_11->FC.SubType == SUBTYPE_PS_POLL)) {
-			pHeader_802_11->FC.PwrMgmt = PWR_SAVE;
-		}
-		bAckRequired = FALSE;
-	} else			/* BTYPE_MGMT or BTYPE_DATA(must be NULL frame) */
-	{
-		/*pAd->Sequence++; */
-		/*pHeader_802_11->Sequence = pAd->Sequence; */
-
-		if (pHeader_802_11->Addr1[0] & 0x01)	/* MULTICAST, BROADCAST */
-		{
-			bAckRequired = FALSE;
-			pHeader_802_11->Duration = 0;
-		} else {
-			bAckRequired = TRUE;
-			pHeader_802_11->Duration =
-			    RTMPCalcDuration(pAd, MlmeRate, 14);
-			if ((pHeader_802_11->FC.SubType == SUBTYPE_PROBE_RSP)
-			    && (pHeader_802_11->FC.Type == BTYPE_MGMT)) {
-				bInsertTimestamp = TRUE;
-				bAckRequired = FALSE;	/* Disable ACK to prevent retry 0x1f for Probe Response */
-			} else
-			    if ((pHeader_802_11->FC.SubType ==
-				 SUBTYPE_PROBE_REQ)
-				&& (pHeader_802_11->FC.Type == BTYPE_MGMT)) {
-				bAckRequired = FALSE;	/* Disable ACK to prevent retry 0x1f for Probe Request */
-			}
-		}
-	}
-
-	pHeader_802_11->Sequence = pAd->Sequence++;
-	if (pAd->Sequence > 0xfff)
-		pAd->Sequence = 0;
-
-	/* Before radar detection done, mgmt frame can not be sent but probe req */
-	/* Because we need to use probe req to trigger driver to send probe req in passive scan */
-	if ((pHeader_802_11->FC.SubType != SUBTYPE_PROBE_REQ)
-	    && (pAd->CommonCfg.bIEEE80211H == 1)
-	    && (pAd->CommonCfg.RadarDetect.RDMode != RD_NORMAL_MODE)) {
-		DBGPRINT(RT_DEBUG_ERROR,
-			 ("MlmeHardTransmit --> radar detect not in normal mode!\n"));
-/*              if (!IrqState) */
-		RTMP_SEM_UNLOCK(&pAd->MgmtRingLock);
-		return (NDIS_STATUS_FAILURE);
-	}
-
-	/* */
-	/* fill scatter-and-gather buffer list into TXD. Internally created NDIS PACKET */
-	/* should always has only one physical buffer, and the whole frame size equals */
-	/* to the first scatter buffer size */
-	/* */
-
-	/* Initialize TX Descriptor */
-	/* For inter-frame gap, the number is for this frame and next frame */
-	/* For MLME rate, we will fix as 2Mb to match other vendor's implement */
-/*      pAd->CommonCfg.MlmeTransmit.field.MODE = 1; */
-
-/* management frame doesn't need encryption. so use RESERVED_WCID no matter u are sending to specific wcid or not. */
-	PID = PID_MGMT;
-
-	if (pMacEntry == NULL) {
-		RTMPWriteTxWI(pAd, pFirstTxWI, FALSE, FALSE, bInsertTimestamp,
-			      FALSE, bAckRequired, FALSE, 0, RESERVED_WCID,
-			      (SrcBufLen - TXINFO_SIZE - TXWI_SIZE), PID, 0,
-			      (u8)pAd->CommonCfg.MlmeTransmit.field.MCS,
-			      IFS_BACKOFF, FALSE, &pAd->CommonCfg.MlmeTransmit);
-	} else {
-		/* dont use low rate to send QoS Null data frame */
-		RTMPWriteTxWI(pAd, pFirstTxWI, FALSE, FALSE,
-			      bInsertTimestamp, FALSE, bAckRequired, FALSE,
-			      0, pMacEntry->Aid,
-			      (SrcBufLen - TXINFO_SIZE - TXWI_SIZE),
-			      pMacEntry->MaxHTPhyMode.field.MCS, 0,
-			      (u8)pMacEntry->MaxHTPhyMode.field.MCS,
-			      IFS_BACKOFF, FALSE, &pMacEntry->MaxHTPhyMode);
-	}
-
-	/* Now do hardware-depened kick out. */
-	HAL_KickOutMgmtTx(pAd, QueIdx, pPacket, pSrcBufVA, SrcBufLen);
-
-	/* Make sure to release MGMT ring resource */
-/*      if (!IrqState) */
-	RTMP_SEM_UNLOCK(&pAd->MgmtRingLock);
-	return NDIS_STATUS_SUCCESS;
-}
-
-/********************************************************************************
-
-	New DeQueue Procedures.
-
- ********************************************************************************/
-
-#define DEQUEUE_LOCK(lock, bIntContext, IrqFlags) 				\
-			do{													\
-				if (bIntContext == FALSE)						\
-				RTMP_IRQ_LOCK((lock), IrqFlags);		\
-			}while(0)
-
-#define DEQUEUE_UNLOCK(lock, bIntContext, IrqFlags)				\
-			do{													\
-				if (bIntContext == FALSE)						\
-					RTMP_IRQ_UNLOCK((lock), IrqFlags);	\
-			}while(0)
-
-/*
-	========================================================================
-	Tx Path design algorithm:
-		Basically, we divide the packets into four types, Broadcast/Multicast, 11N Rate(AMPDU, AMSDU, Normal), B/G Rate(ARALINK, Normal),
-		Specific Packet Type. Following show the classification rule and policy for each kinds of packets.
-				Classification Rule=>
-					Multicast: (*addr1 & 0x01) == 0x01
-					Specific : bDHCPFrame, bARPFrame, bEAPOLFrame, etc.
-					11N Rate : If peer support HT
-								(1).AMPDU  -- If TXBA is negotiated.
-								(2).AMSDU  -- If AMSDU is capable for both peer and ourself.
-											*). AMSDU can embedded in a AMPDU, but now we didn't support it.
-								(3).Normal -- Other packets which send as 11n rate.
-
-					B/G Rate : If peer is b/g only.
-								(1).ARALINK-- If both of peer/us supprot Ralink proprietary Aggregation and the TxRate is large than RATE_6
-								(2).Normal -- Other packets which send as b/g rate.
-					Fragment:
-								The packet must be unicast, NOT A-RALINK, NOT A-MSDU, NOT 11n, then can consider about fragment.
-
-				Classified Packet Handle Rule=>
-					Multicast:
-								No ACK, 		//pTxBlk->bAckRequired = FALSE;
-								No WMM, 		//pTxBlk->bWMM = FALSE;
-								No piggyback,   //pTxBlk->bPiggyBack = FALSE;
-								Force LowRate,  //pTxBlk->bForceLowRate = TRUE;
-					Specific :	Basically, for specific packet, we should handle it specifically, but now all specific packets are use
-									the same policy to handle it.
-								Force LowRate,  //pTxBlk->bForceLowRate = TRUE;
-
-					11N Rate :
-								No piggyback,	//pTxBlk->bPiggyBack = FALSE;
-
-								(1).AMSDU
-									pTxBlk->bWMM = TRUE;
-								(2).AMPDU
-									pTxBlk->bWMM = TRUE;
-								(3).Normal
-
-					B/G Rate :
-								(1).ARALINK
-
-								(2).Normal
-	========================================================================
-*/
-static u8 TxPktClassification(struct rt_rtmp_adapter *pAd, void *pPacket)
-{
-	u8 TxFrameType = TX_UNKOWN_FRAME;
-	u8 Wcid;
-	struct rt_mac_table_entry *pMacEntry = NULL;
-	BOOLEAN bHTRate = FALSE;
-
-	Wcid = RTMP_GET_PACKET_WCID(pPacket);
-	if (Wcid == MCAST_WCID) {	/* Handle for RA is Broadcast/Multicast Address. */
-		return TX_MCAST_FRAME;
-	}
-	/* Handle for unicast packets */
-	pMacEntry = &pAd->MacTab.Content[Wcid];
-	if (RTMP_GET_PACKET_LOWRATE(pPacket)) {	/* It's a specific packet need to force low rate, i.e., bDHCPFrame, bEAPOLFrame, bWAIFrame */
-		TxFrameType = TX_LEGACY_FRAME;
-	} else if (IS_HT_RATE(pMacEntry)) {	/* it's a 11n capable packet */
-
-		/* Depends on HTPhyMode to check if the peer support the HTRate transmission. */
-		/*      Currently didn't support A-MSDU embedded in A-MPDU */
-		bHTRate = TRUE;
-		if (RTMP_GET_PACKET_MOREDATA(pPacket)
-		    || (pMacEntry->PsMode == PWR_SAVE))
-			TxFrameType = TX_LEGACY_FRAME;
-		else if ((pMacEntry->
-			  TXBAbitmap & (1 << (RTMP_GET_PACKET_UP(pPacket)))) !=
-			 0)
-			return TX_AMPDU_FRAME;
-		else if (CLIENT_STATUS_TEST_FLAG
-			 (pMacEntry, fCLIENT_STATUS_AMSDU_INUSED))
-			return TX_AMSDU_FRAME;
-		else
-			TxFrameType = TX_LEGACY_FRAME;
-	} else {		/* it's a legacy b/g packet. */
-		if ((CLIENT_STATUS_TEST_FLAG(pMacEntry, fCLIENT_STATUS_AGGREGATION_CAPABLE) && pAd->CommonCfg.bAggregationCapable) && (RTMP_GET_PACKET_TXRATE(pPacket) >= RATE_6) && (!(OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED) && CLIENT_STATUS_TEST_FLAG(pMacEntry, fCLIENT_STATUS_WMM_CAPABLE)))) {	/* if peer support Ralink Aggregation, we use it. */
-			TxFrameType = TX_RALINK_FRAME;
-		} else {
-			TxFrameType = TX_LEGACY_FRAME;
-		}
-	}
-
-	/* Currently, our fragment only support when a unicast packet send as NOT-ARALINK, NOT-AMSDU and NOT-AMPDU. */
-	if ((RTMP_GET_PACKET_FRAGMENTS(pPacket) > 1)
-	    && (TxFrameType == TX_LEGACY_FRAME))
-		TxFrameType = TX_FRAG_FRAME;
-
-	return TxFrameType;
-}
-
-BOOLEAN RTMP_FillTxBlkInfo(struct rt_rtmp_adapter *pAd, struct rt_tx_blk *pTxBlk)
-{
-	struct rt_packet_info PacketInfo;
-	void *pPacket;
-	struct rt_mac_table_entry *pMacEntry = NULL;
-
-	pPacket = pTxBlk->pPacket;
-	RTMP_QueryPacketInfo(pPacket, &PacketInfo, &pTxBlk->pSrcBufHeader,
-			     &pTxBlk->SrcBufLen);
-
-	pTxBlk->Wcid = RTMP_GET_PACKET_WCID(pPacket);
-	pTxBlk->apidx = RTMP_GET_PACKET_IF(pPacket);
-	pTxBlk->UserPriority = RTMP_GET_PACKET_UP(pPacket);
-	pTxBlk->FrameGap = IFS_HTTXOP;	/* ASIC determine Frame Gap */
-
-	if (RTMP_GET_PACKET_CLEAR_EAP_FRAME(pTxBlk->pPacket))
-		TX_BLK_SET_FLAG(pTxBlk, fTX_bClearEAPFrame);
-	else
-		TX_BLK_CLEAR_FLAG(pTxBlk, fTX_bClearEAPFrame);
-
-	/* Default to clear this flag */
-	TX_BLK_CLEAR_FLAG(pTxBlk, fTX_bForceNonQoS);
-
-	if (pTxBlk->Wcid == MCAST_WCID) {
-		pTxBlk->pMacEntry = NULL;
-		{
-			pTxBlk->pTransmit =
-			    &pAd->MacTab.Content[MCAST_WCID].HTPhyMode;
-		}
-
-		TX_BLK_CLEAR_FLAG(pTxBlk, fTX_bAckRequired);	/* AckRequired = FALSE, when broadcast packet in Adhoc mode. */
-		/*TX_BLK_SET_FLAG(pTxBlk, fTX_bForceLowRate); */
-		TX_BLK_CLEAR_FLAG(pTxBlk, fTX_bAllowFrag);
-		TX_BLK_CLEAR_FLAG(pTxBlk, fTX_bWMM);
-		if (RTMP_GET_PACKET_MOREDATA(pPacket)) {
-			TX_BLK_SET_FLAG(pTxBlk, fTX_bMoreData);
-		}
-
-	} else {
-		pTxBlk->pMacEntry = &pAd->MacTab.Content[pTxBlk->Wcid];
-		pTxBlk->pTransmit = &pTxBlk->pMacEntry->HTPhyMode;
-
-		pMacEntry = pTxBlk->pMacEntry;
-
-		/* For all unicast packets, need Ack unless the Ack Policy is not set as NORMAL_ACK. */
-		if (pAd->CommonCfg.AckPolicy[pTxBlk->QueIdx] != NORMAL_ACK)
-			TX_BLK_CLEAR_FLAG(pTxBlk, fTX_bAckRequired);
-		else
-			TX_BLK_SET_FLAG(pTxBlk, fTX_bAckRequired);
-
-		if ((pAd->OpMode == OPMODE_STA) &&
-		    (ADHOC_ON(pAd)) &&
-		    (RX_FILTER_TEST_FLAG(pAd, fRX_FILTER_ACCEPT_PROMISCUOUS))) {
-			if (pAd->CommonCfg.PSPXlink)
-				TX_BLK_CLEAR_FLAG(pTxBlk, fTX_bAckRequired);
-		}
-
-		{
-			{
-
-				/* If support WMM, enable it. */
-				if (OPSTATUS_TEST_FLAG
-				    (pAd, fOP_STATUS_WMM_INUSED)
-				    && CLIENT_STATUS_TEST_FLAG(pMacEntry,
-							       fCLIENT_STATUS_WMM_CAPABLE))
-					TX_BLK_SET_FLAG(pTxBlk, fTX_bWMM);
-
-/*                              if (pAd->StaCfg.bAutoTxRateSwitch) */
-/*                                      TX_BLK_SET_FLAG(pTxBlk, fTX_AutoRateSwitch); */
-			}
-		}
-
-		if (pTxBlk->TxFrameType == TX_LEGACY_FRAME) {
-			if ((RTMP_GET_PACKET_LOWRATE(pPacket)) || ((pAd->OpMode == OPMODE_AP) && (pMacEntry->MaxHTPhyMode.field.MODE == MODE_CCK) && (pMacEntry->MaxHTPhyMode.field.MCS == RATE_1))) {	/* Specific packet, i.e., bDHCPFrame, bEAPOLFrame, bWAIFrame, need force low rate. */
-				pTxBlk->pTransmit =
-				    &pAd->MacTab.Content[MCAST_WCID].HTPhyMode;
-
-				/* Modify the WMM bit for ICV issue. If we have a packet with EOSP field need to set as 1, how to handle it??? */
-				if (IS_HT_STA(pTxBlk->pMacEntry) &&
-				    (CLIENT_STATUS_TEST_FLAG
-				     (pMacEntry, fCLIENT_STATUS_RALINK_CHIPSET))
-				    && ((pAd->CommonCfg.bRdg == TRUE)
-					&& CLIENT_STATUS_TEST_FLAG(pMacEntry,
-								   fCLIENT_STATUS_RDG_CAPABLE)))
-				{
-					TX_BLK_CLEAR_FLAG(pTxBlk, fTX_bWMM);
-					TX_BLK_SET_FLAG(pTxBlk,
-							fTX_bForceNonQoS);
-				}
-			}
-
-			if ((IS_HT_RATE(pMacEntry) == FALSE) && (CLIENT_STATUS_TEST_FLAG(pMacEntry, fCLIENT_STATUS_PIGGYBACK_CAPABLE))) {	/* Currently piggy-back only support when peer is operate in b/g mode. */
-				TX_BLK_SET_FLAG(pTxBlk, fTX_bPiggyBack);
-			}
-
-			if (RTMP_GET_PACKET_MOREDATA(pPacket)) {
-				TX_BLK_SET_FLAG(pTxBlk, fTX_bMoreData);
-			}
-		} else if (pTxBlk->TxFrameType == TX_FRAG_FRAME) {
-			TX_BLK_SET_FLAG(pTxBlk, fTX_bAllowFrag);
-		}
-
-		pMacEntry->DebugTxCount++;
-	}
-
-	return TRUE;
-}
-
-BOOLEAN CanDoAggregateTransmit(struct rt_rtmp_adapter *pAd,
-			       char * pPacket, struct rt_tx_blk *pTxBlk)
-{
-
-	/*DBGPRINT(RT_DEBUG_TRACE, ("Check if can do aggregation! TxFrameType=%d!\n", pTxBlk->TxFrameType)); */
-
-	if (RTMP_GET_PACKET_WCID(pPacket) == MCAST_WCID)
-		return FALSE;
-
-	if (RTMP_GET_PACKET_DHCP(pPacket) ||
-	    RTMP_GET_PACKET_EAPOL(pPacket) || RTMP_GET_PACKET_WAI(pPacket))
-		return FALSE;
-
-	if ((pTxBlk->TxFrameType == TX_AMSDU_FRAME) && ((pTxBlk->TotalFrameLen + GET_OS_PKT_LEN(pPacket)) > (RX_BUFFER_AGGRESIZE - 100))) {	/* For AMSDU, allow the packets with total length < max-amsdu size */
-		return FALSE;
-	}
-
-	if ((pTxBlk->TxFrameType == TX_RALINK_FRAME) && (pTxBlk->TxPacketList.Number == 2)) {	/* For RALINK-Aggregation, allow two frames in one batch. */
-		return FALSE;
-	}
-
-	if ((INFRA_ON(pAd)) && (pAd->OpMode == OPMODE_STA))	/* must be unicast to AP */
-		return TRUE;
-	else
-		return FALSE;
-
-}
-
-/*
-	========================================================================
-
-	Routine Description:
-		To do the enqueue operation and extract the first item of waiting
-		list. If a number of available shared memory segments could meet
-		the request of extracted item, the extracted item will be fragmented
-		into shared memory segments.
-
-	Arguments:
-		pAd Pointer to our adapter
-		pQueue		Pointer to Waiting Queue
-
-	Return Value:
-		None
-
-	IRQL = DISPATCH_LEVEL
-
-	Note:
-
-	========================================================================
-*/
-void RTMPDeQueuePacket(struct rt_rtmp_adapter *pAd, IN BOOLEAN bIntContext, u8 QIdx,	/* BulkOutPipeId */
-		       u8 Max_Tx_Packets)
-{
-	struct rt_queue_entry *pEntry = NULL;
-	void *pPacket;
-	int Status = NDIS_STATUS_SUCCESS;
-	u8 Count = 0;
-	struct rt_queue_header *pQueue;
-	unsigned long FreeNumber[NUM_OF_TX_RING];
-	u8 QueIdx, sQIdx, eQIdx;
-	unsigned long IrqFlags = 0;
-	BOOLEAN hasTxDesc = FALSE;
-	struct rt_tx_blk TxBlk;
-	struct rt_tx_blk *pTxBlk;
-
-	if (QIdx == NUM_OF_TX_RING) {
-		sQIdx = 0;
-		eQIdx = 3;	/* 4 ACs, start from 0. */
-	} else {
-		sQIdx = eQIdx = QIdx;
-	}
-
-	for (QueIdx = sQIdx; QueIdx <= eQIdx; QueIdx++) {
-		Count = 0;
-
-		RTMP_START_DEQUEUE(pAd, QueIdx, IrqFlags);
-
-		while (1) {
-			if ((RTMP_TEST_FLAG
-			     (pAd,
-			      (fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS |
-			       fRTMP_ADAPTER_RADIO_OFF |
-			       fRTMP_ADAPTER_RESET_IN_PROGRESS |
-			       fRTMP_ADAPTER_HALT_IN_PROGRESS |
-			       fRTMP_ADAPTER_NIC_NOT_EXIST)))) {
-				RTMP_STOP_DEQUEUE(pAd, QueIdx, IrqFlags);
-				return;
-			}
-
-			if (Count >= Max_Tx_Packets)
-				break;
-
-			DEQUEUE_LOCK(&pAd->irq_lock, bIntContext, IrqFlags);
-			if (&pAd->TxSwQueue[QueIdx] == NULL) {
-				DEQUEUE_UNLOCK(&pAd->irq_lock, bIntContext,
-					       IrqFlags);
-				break;
-			}
-#ifdef RTMP_MAC_PCI
-			FreeNumber[QueIdx] = GET_TXRING_FREENO(pAd, QueIdx);
-
-			if (FreeNumber[QueIdx] <= 5) {
-				/* free Tx(QueIdx) resources */
-				RTMPFreeTXDUponTxDmaDone(pAd, QueIdx);
-				FreeNumber[QueIdx] =
-				    GET_TXRING_FREENO(pAd, QueIdx);
-			}
-#endif /* RTMP_MAC_PCI // */
-
-			/* probe the Queue Head */
-			pQueue = &pAd->TxSwQueue[QueIdx];
-			pEntry = pQueue->Head;
-			if (pEntry == NULL) {
-				DEQUEUE_UNLOCK(&pAd->irq_lock, bIntContext,
-					       IrqFlags);
-				break;
-			}
-
-			pTxBlk = &TxBlk;
-			NdisZeroMemory((u8 *)pTxBlk, sizeof(struct rt_tx_blk));
-			/*InitializeQueueHeader(&pTxBlk->TxPacketList);         // Didn't need it because we already memzero it. */
-			pTxBlk->QueIdx = QueIdx;
-
-			pPacket = QUEUE_ENTRY_TO_PACKET(pEntry);
-
-			/* Early check to make sure we have enoguh Tx Resource. */
-			hasTxDesc =
-			    RTMP_HAS_ENOUGH_FREE_DESC(pAd, pTxBlk,
-						      FreeNumber[QueIdx],
-						      pPacket);
-			if (!hasTxDesc) {
-				pAd->PrivateInfo.TxRingFullCnt++;
-
-				DEQUEUE_UNLOCK(&pAd->irq_lock, bIntContext,
-					       IrqFlags);
-
-				break;
-			}
-
-			pTxBlk->TxFrameType = TxPktClassification(pAd, pPacket);
-			pEntry = RemoveHeadQueue(pQueue);
-			pTxBlk->TotalFrameNum++;
-			pTxBlk->TotalFragNum += RTMP_GET_PACKET_FRAGMENTS(pPacket);	/* The real fragment number maybe vary */
-			pTxBlk->TotalFrameLen += GET_OS_PKT_LEN(pPacket);
-			pTxBlk->pPacket = pPacket;
-			InsertTailQueue(&pTxBlk->TxPacketList,
-					PACKET_TO_QUEUE_ENTRY(pPacket));
-
-			if (pTxBlk->TxFrameType == TX_RALINK_FRAME
-			    || pTxBlk->TxFrameType == TX_AMSDU_FRAME) {
-				/* Enhance SW Aggregation Mechanism */
-				if (NEED_QUEUE_BACK_FOR_AGG
-				    (pAd, QueIdx, FreeNumber[QueIdx],
-				     pTxBlk->TxFrameType)) {
-					InsertHeadQueue(pQueue,
-							PACKET_TO_QUEUE_ENTRY
-							(pPacket));
-					DEQUEUE_UNLOCK(&pAd->irq_lock,
-						       bIntContext, IrqFlags);
-					break;
-				}
-
-				do {
-					pEntry = pQueue->Head;
-					if (pEntry == NULL)
-						break;
-
-					/* For TX_AMSDU_FRAME/TX_RALINK_FRAME, Need to check if next pakcet can do aggregation. */
-					pPacket = QUEUE_ENTRY_TO_PACKET(pEntry);
-					FreeNumber[QueIdx] =
-					    GET_TXRING_FREENO(pAd, QueIdx);
-					hasTxDesc =
-					    RTMP_HAS_ENOUGH_FREE_DESC(pAd,
-								      pTxBlk,
-								      FreeNumber
-								      [QueIdx],
-								      pPacket);
-					if ((hasTxDesc == FALSE)
-					    ||
-					    (CanDoAggregateTransmit
-					     (pAd, pPacket, pTxBlk) == FALSE))
-						break;
-
-					/*Remove the packet from the TxSwQueue and insert into pTxBlk */
-					pEntry = RemoveHeadQueue(pQueue);
-					ASSERT(pEntry);
-					pPacket = QUEUE_ENTRY_TO_PACKET(pEntry);
-					pTxBlk->TotalFrameNum++;
-					pTxBlk->TotalFragNum += RTMP_GET_PACKET_FRAGMENTS(pPacket);	/* The real fragment number maybe vary */
-					pTxBlk->TotalFrameLen +=
-					    GET_OS_PKT_LEN(pPacket);
-					InsertTailQueue(&pTxBlk->TxPacketList,
-							PACKET_TO_QUEUE_ENTRY
-							(pPacket));
-				} while (1);
-
-				if (pTxBlk->TxPacketList.Number == 1)
-					pTxBlk->TxFrameType = TX_LEGACY_FRAME;
-			}
-#ifdef RTMP_MAC_USB
-			DEQUEUE_UNLOCK(&pAd->irq_lock, bIntContext, IrqFlags);
-#endif /* RTMP_MAC_USB // */
-			Count += pTxBlk->TxPacketList.Number;
-
-			/* Do HardTransmit now. */
-			Status = STAHardTransmit(pAd, pTxBlk, QueIdx);
-
-#ifdef RTMP_MAC_PCI
-			DEQUEUE_UNLOCK(&pAd->irq_lock, bIntContext, IrqFlags);
-			/* static rate also need NICUpdateFifoStaCounters() function. */
-			/*if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED)) */
-			NICUpdateFifoStaCounters(pAd);
-#endif /* RTMP_MAC_PCI // */
-
-		}
-
-		RTMP_STOP_DEQUEUE(pAd, QueIdx, IrqFlags);
-
-#ifdef RTMP_MAC_USB
-		if (!hasTxDesc)
-			RTUSBKickBulkOut(pAd);
-#endif /* RTMP_MAC_USB // */
-	}
-
-}
-
-/*
-	========================================================================
-
-	Routine Description:
-		Calculates the duration which is required to transmit out frames
-	with given size and specified rate.
-
-	Arguments:
-		pAd 	Pointer to our adapter
-		Rate			Transmit rate
-		Size			Frame size in units of byte
-
-	Return Value:
-		Duration number in units of usec
-
-	IRQL = PASSIVE_LEVEL
-	IRQL = DISPATCH_LEVEL
-
-	Note:
-
-	========================================================================
-*/
-u16 RTMPCalcDuration(struct rt_rtmp_adapter *pAd, u8 Rate, unsigned long Size)
-{
-	unsigned long Duration = 0;
-
-	if (Rate < RATE_FIRST_OFDM_RATE)	/* CCK */
-	{
-		if ((Rate > RATE_1)
-		    && OPSTATUS_TEST_FLAG(pAd,
-					  fOP_STATUS_SHORT_PREAMBLE_INUSED))
-			Duration = 96;	/* 72+24 preamble+plcp */
-		else
-			Duration = 192;	/* 144+48 preamble+plcp */
-
-		Duration += (u16)((Size << 4) / RateIdTo500Kbps[Rate]);
-		if ((Size << 4) % RateIdTo500Kbps[Rate])
-			Duration++;
-	} else if (Rate <= RATE_LAST_OFDM_RATE)	/* OFDM rates */
-	{
-		Duration = 20 + 6;	/* 16+4 preamble+plcp + Signal Extension */
-		Duration +=
-		    4 * (u16)((11 + Size * 4) / RateIdTo500Kbps[Rate]);
-		if ((11 + Size * 4) % RateIdTo500Kbps[Rate])
-			Duration += 4;
-	} else			/*mimo rate */
-	{
-		Duration = 20 + 6;	/* 16+4 preamble+plcp + Signal Extension */
-	}
-
-	return (u16)Duration;
-}
-
-/*
-	========================================================================
-
-	Routine Description:
-		Calculates the duration which is required to transmit out frames
-	with given size and specified rate.
-
-	Arguments:
-		pTxWI		Pointer to head of each MPDU to HW.
-		Ack 		Setting for Ack requirement bit
-		Fragment	Setting for Fragment bit
-		RetryMode	Setting for retry mode
-		Ifs 		Setting for IFS gap
-		Rate		Setting for transmit rate
-		Service 	Setting for service
-		Length		Frame length
-		TxPreamble	Short or Long preamble when using CCK rates
-		QueIdx - 0-3, according to 802.11e/d4.4 June/2003
-
-	Return Value:
-		None
-
-	IRQL = PASSIVE_LEVEL
-	IRQL = DISPATCH_LEVEL
-
-    See also : BASmartHardTransmit()    !
-
-	========================================================================
-*/
-void RTMPWriteTxWI(struct rt_rtmp_adapter *pAd, struct rt_txwi * pOutTxWI, IN BOOLEAN FRAG, IN BOOLEAN CFACK, IN BOOLEAN InsTimestamp, IN BOOLEAN AMPDU, IN BOOLEAN Ack, IN BOOLEAN NSeq,	/* HW new a sequence. */
-		   u8 BASize,
-		   u8 WCID,
-		   unsigned long Length,
-		   u8 PID,
-		   u8 TID,
-		   u8 TxRate,
-		   u8 Txopmode,
-		   IN BOOLEAN CfAck, IN HTTRANSMIT_SETTING * pTransmit)
-{
-	struct rt_mac_table_entry *pMac = NULL;
-	struct rt_txwi TxWI;
-	struct rt_txwi * pTxWI;
-
-	if (WCID < MAX_LEN_OF_MAC_TABLE)
-		pMac = &pAd->MacTab.Content[WCID];
-
-	/* */
-	/* Always use Long preamble before verifiation short preamble functionality works well. */
-	/* Todo: remove the following line if short preamble functionality works */
-	/* */
-	OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_SHORT_PREAMBLE_INUSED);
-	NdisZeroMemory(&TxWI, TXWI_SIZE);
-	pTxWI = &TxWI;
-
-	pTxWI->FRAG = FRAG;
-
-	pTxWI->CFACK = CFACK;
-	pTxWI->TS = InsTimestamp;
-	pTxWI->AMPDU = AMPDU;
-	pTxWI->ACK = Ack;
-	pTxWI->txop = Txopmode;
-
-	pTxWI->NSEQ = NSeq;
-	/* John tune the performace with Intel Client in 20 MHz performance */
-	BASize = pAd->CommonCfg.TxBASize;
-	if (pAd->MACVersion == 0x28720200) {
-		if (BASize > 13)
-			BASize = 13;
-	} else {
-		if (BASize > 7)
-			BASize = 7;
-	}
-	pTxWI->BAWinSize = BASize;
-	pTxWI->ShortGI = pTransmit->field.ShortGI;
-	pTxWI->STBC = pTransmit->field.STBC;
-
-	pTxWI->WirelessCliID = WCID;
-	pTxWI->MPDUtotalByteCount = Length;
-	pTxWI->PacketId = PID;
-
-	/* If CCK or OFDM, BW must be 20 */
-	pTxWI->BW =
-	    (pTransmit->field.MODE <=
-	     MODE_OFDM) ? (BW_20) : (pTransmit->field.BW);
-
-	pTxWI->MCS = pTransmit->field.MCS;
-	pTxWI->PHYMODE = pTransmit->field.MODE;
-	pTxWI->CFACK = CfAck;
-
-	if (pMac) {
-		if (pAd->CommonCfg.bMIMOPSEnable) {
-			if ((pMac->MmpsMode == MMPS_DYNAMIC)
-			    && (pTransmit->field.MCS > 7)) {
-				/* Dynamic MIMO Power Save Mode */
-				pTxWI->MIMOps = 1;
-			} else if (pMac->MmpsMode == MMPS_STATIC) {
-				/* Static MIMO Power Save Mode */
-				if (pTransmit->field.MODE >= MODE_HTMIX
-				    && pTransmit->field.MCS > 7) {
-					pTxWI->MCS = 7;
-					pTxWI->MIMOps = 0;
-				}
-			}
-		}
-		/*pTxWI->MIMOps = (pMac->PsMode == PWR_MMPS)? 1:0; */
-		if (pMac->bIAmBadAtheros
-		    && (pMac->WepStatus != Ndis802_11WEPDisabled)) {
-			pTxWI->MpduDensity = 7;
-		} else {
-			pTxWI->MpduDensity = pMac->MpduDensity;
-		}
-	}
-
-	pTxWI->PacketId = pTxWI->MCS;
-	NdisMoveMemory(pOutTxWI, &TxWI, sizeof(struct rt_txwi));
-}
-
-void RTMPWriteTxWI_Data(struct rt_rtmp_adapter *pAd,
-			struct rt_txwi * pTxWI, struct rt_tx_blk *pTxBlk)
-{
-	HTTRANSMIT_SETTING *pTransmit;
-	struct rt_mac_table_entry *pMacEntry;
-	u8 BASize;
-
-	ASSERT(pTxWI);
-
-	pTransmit = pTxBlk->pTransmit;
-	pMacEntry = pTxBlk->pMacEntry;
-
-	/* */
-	/* Always use Long preamble before verifiation short preamble functionality works well. */
-	/* Todo: remove the following line if short preamble functionality works */
-	/* */
-	OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_SHORT_PREAMBLE_INUSED);
-	NdisZeroMemory(pTxWI, TXWI_SIZE);
-
-	pTxWI->FRAG = TX_BLK_TEST_FLAG(pTxBlk, fTX_bAllowFrag);
-	pTxWI->ACK = TX_BLK_TEST_FLAG(pTxBlk, fTX_bAckRequired);
-	pTxWI->txop = pTxBlk->FrameGap;
-
-	pTxWI->WirelessCliID = pTxBlk->Wcid;
-
-	pTxWI->MPDUtotalByteCount = pTxBlk->MpduHeaderLen + pTxBlk->SrcBufLen;
-	pTxWI->CFACK = TX_BLK_TEST_FLAG(pTxBlk, fTX_bPiggyBack);
-
-	/* If CCK or OFDM, BW must be 20 */
-	pTxWI->BW =
-	    (pTransmit->field.MODE <=
-	     MODE_OFDM) ? (BW_20) : (pTransmit->field.BW);
-	pTxWI->AMPDU = ((pTxBlk->TxFrameType == TX_AMPDU_FRAME) ? TRUE : FALSE);
-
-	/* John tune the performace with Intel Client in 20 MHz performance */
-	BASize = pAd->CommonCfg.TxBASize;
-	if ((pTxBlk->TxFrameType == TX_AMPDU_FRAME) && (pMacEntry)) {
-		u8 RABAOriIdx = 0;	/*The RA's BA Originator table index. */
-
-		RABAOriIdx =
-		    pTxBlk->pMacEntry->BAOriWcidArray[pTxBlk->UserPriority];
-		BASize = pAd->BATable.BAOriEntry[RABAOriIdx].BAWinSize;
-	}
-
-	pTxWI->TxBF = pTransmit->field.TxBF;
-	pTxWI->BAWinSize = BASize;
-	pTxWI->ShortGI = pTransmit->field.ShortGI;
-	pTxWI->STBC = pTransmit->field.STBC;
-
-	pTxWI->MCS = pTransmit->field.MCS;
-	pTxWI->PHYMODE = pTransmit->field.MODE;
-
-	if (pMacEntry) {
-		if ((pMacEntry->MmpsMode == MMPS_DYNAMIC)
-		    && (pTransmit->field.MCS > 7)) {
-			/* Dynamic MIMO Power Save Mode */
-			pTxWI->MIMOps = 1;
-		} else if (pMacEntry->MmpsMode == MMPS_STATIC) {
-			/* Static MIMO Power Save Mode */
-			if (pTransmit->field.MODE >= MODE_HTMIX
-			    && pTransmit->field.MCS > 7) {
-				pTxWI->MCS = 7;
-				pTxWI->MIMOps = 0;
-			}
-		}
-
-		if (pMacEntry->bIAmBadAtheros
-		    && (pMacEntry->WepStatus != Ndis802_11WEPDisabled)) {
-			pTxWI->MpduDensity = 7;
-		} else {
-			pTxWI->MpduDensity = pMacEntry->MpduDensity;
-		}
-	}
-
-	/* for rate adapation */
-	pTxWI->PacketId = pTxWI->MCS;
-}
-
-void RTMPWriteTxWI_Cache(struct rt_rtmp_adapter *pAd,
-			 struct rt_txwi * pTxWI, struct rt_tx_blk *pTxBlk)
-{
-	PHTTRANSMIT_SETTING /*pTxHTPhyMode, */ pTransmit;
-	struct rt_mac_table_entry *pMacEntry;
-
-	/* */
-	/* update TXWI */
-	/* */
-	pMacEntry = pTxBlk->pMacEntry;
-	pTransmit = pTxBlk->pTransmit;
-
-	/*if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED)) */
-	/*if (RTMPCheckEntryEnableAutoRateSwitch(pAd, pMacEntry)) */
-	/*if (TX_BLK_TEST_FLAG(pTxBlk, fTX_AutoRateSwitch)) */
-	if (pMacEntry->bAutoTxRateSwitch) {
-		pTxWI->txop = IFS_HTTXOP;
-
-		/* If CCK or OFDM, BW must be 20 */
-		pTxWI->BW =
-		    (pTransmit->field.MODE <=
-		     MODE_OFDM) ? (BW_20) : (pTransmit->field.BW);
-		pTxWI->ShortGI = pTransmit->field.ShortGI;
-		pTxWI->STBC = pTransmit->field.STBC;
-
-		pTxWI->MCS = pTransmit->field.MCS;
-		pTxWI->PHYMODE = pTransmit->field.MODE;
-
-		/* set PID for TxRateSwitching */
-		pTxWI->PacketId = pTransmit->field.MCS;
-	}
-
-	pTxWI->AMPDU = ((pMacEntry->NoBADataCountDown == 0) ? TRUE : FALSE);
-	pTxWI->MIMOps = 0;
-
-	if (pAd->CommonCfg.bMIMOPSEnable) {
-		/* MIMO Power Save Mode */
-		if ((pMacEntry->MmpsMode == MMPS_DYNAMIC)
-		    && (pTransmit->field.MCS > 7)) {
-			/* Dynamic MIMO Power Save Mode */
-			pTxWI->MIMOps = 1;
-		} else if (pMacEntry->MmpsMode == MMPS_STATIC) {
-			/* Static MIMO Power Save Mode */
-			if ((pTransmit->field.MODE >= MODE_HTMIX)
-			    && (pTransmit->field.MCS > 7)) {
-				pTxWI->MCS = 7;
-				pTxWI->MIMOps = 0;
-			}
-		}
-	}
-
-	pTxWI->MPDUtotalByteCount = pTxBlk->MpduHeaderLen + pTxBlk->SrcBufLen;
-
-}
-
-/* should be called only when - */
-/* 1. MEADIA_CONNECTED */
-/* 2. AGGREGATION_IN_USED */
-/* 3. Fragmentation not in used */
-/* 4. either no previous frame (pPrevAddr1=NULL) .OR. previoud frame is aggregatible */
-BOOLEAN TxFrameIsAggregatible(struct rt_rtmp_adapter *pAd,
-			      u8 *pPrevAddr1, u8 *p8023hdr)
-{
-
-	/* can't aggregate EAPOL (802.1x) frame */
-	if ((p8023hdr[12] == 0x88) && (p8023hdr[13] == 0x8e))
-		return FALSE;
-
-	/* can't aggregate multicast/broadcast frame */
-	if (p8023hdr[0] & 0x01)
-		return FALSE;
-
-	if (INFRA_ON(pAd))	/* must be unicast to AP */
-		return TRUE;
-	else if ((pPrevAddr1 == NULL) || MAC_ADDR_EQUAL(pPrevAddr1, p8023hdr))	/* unicast to same STA */
-		return TRUE;
-	else
-		return FALSE;
-}
-
-/*
-	========================================================================
-
-	Routine Description:
-	   Check the MSDU Aggregation policy
-	1.HT aggregation is A-MSDU
-	2.legaacy rate aggregation is software aggregation by Ralink.
-
-	Arguments:
-
-	Return Value:
-
-	Note:
-
-	========================================================================
-*/
-BOOLEAN PeerIsAggreOn(struct rt_rtmp_adapter *pAd,
-		      unsigned long TxRate, struct rt_mac_table_entry *pMacEntry)
-{
-	unsigned long AFlags =
-	    (fCLIENT_STATUS_AMSDU_INUSED | fCLIENT_STATUS_AGGREGATION_CAPABLE);
-
-	if (pMacEntry != NULL && CLIENT_STATUS_TEST_FLAG(pMacEntry, AFlags)) {
-		if (pMacEntry->HTPhyMode.field.MODE >= MODE_HTMIX) {
-			return TRUE;
-		}
-#ifdef AGGREGATION_SUPPORT
-		if (TxRate >= RATE_6 && pAd->CommonCfg.bAggregationCapable && (!(OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED) && CLIENT_STATUS_TEST_FLAG(pMacEntry, fCLIENT_STATUS_WMM_CAPABLE)))) {	/* legacy  Ralink Aggregation support */
-			return TRUE;
-		}
-#endif /* AGGREGATION_SUPPORT // */
-	}
-
-	return FALSE;
-
-}
-
-/*
-	========================================================================
-
-	Routine Description:
-		Check and fine the packet waiting in SW queue with highest priority
-
-	Arguments:
-		pAd Pointer to our adapter
-
-	Return Value:
-		pQueue		Pointer to Waiting Queue
-
-	IRQL = DISPATCH_LEVEL
-
-	Note:
-
-	========================================================================
-*/
-struct rt_queue_header *RTMPCheckTxSwQueue(struct rt_rtmp_adapter *pAd, u8 *pQueIdx)
-{
-
-	unsigned long Number;
-	/* 2004-11-15 to be removed. test aggregation only */
-/*      if ((OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED)) && (*pNumber < 2)) */
-/*               return NULL; */
-
-	Number = pAd->TxSwQueue[QID_AC_BK].Number
-	    + pAd->TxSwQueue[QID_AC_BE].Number
-	    + pAd->TxSwQueue[QID_AC_VI].Number
-	    + pAd->TxSwQueue[QID_AC_VO].Number;
-
-	if (pAd->TxSwQueue[QID_AC_VO].Head != NULL) {
-		*pQueIdx = QID_AC_VO;
-		return (&pAd->TxSwQueue[QID_AC_VO]);
-	} else if (pAd->TxSwQueue[QID_AC_VI].Head != NULL) {
-		*pQueIdx = QID_AC_VI;
-		return (&pAd->TxSwQueue[QID_AC_VI]);
-	} else if (pAd->TxSwQueue[QID_AC_BE].Head != NULL) {
-		*pQueIdx = QID_AC_BE;
-		return (&pAd->TxSwQueue[QID_AC_BE]);
-	} else if (pAd->TxSwQueue[QID_AC_BK].Head != NULL) {
-		*pQueIdx = QID_AC_BK;
-		return (&pAd->TxSwQueue[QID_AC_BK]);
-	}
-	/* No packet pending in Tx Sw queue */
-	*pQueIdx = QID_AC_BK;
-
-	return (NULL);
-}
-
-/*
-	========================================================================
-
-	Routine Description:
-		Suspend MSDU transmission
-
-	Arguments:
-		pAd 	Pointer to our adapter
-
-	Return Value:
-		None
-
-	Note:
-
-	========================================================================
-*/
-void RTMPSuspendMsduTransmission(struct rt_rtmp_adapter *pAd)
-{
-	DBGPRINT(RT_DEBUG_TRACE, ("SCANNING, suspend MSDU transmission ...\n"));
-
-	/* */
-	/* Before BSS_SCAN_IN_PROGRESS, we need to keep Current R66 value and */
-	/* use Lowbound as R66 value on ScanNextChannel(...) */
-	/* */
-	RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R66,
-				    &pAd->BbpTuning.R66CurrentValue);
-
-	/* set BBP_R66 to 0x30/0x40 when scanning (AsicSwitchChannel will set R66 according to channel when scanning) */
-	/*RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, (0x26 + GET_LNA_GAIN(pAd))); */
-	RTMPSetAGCInitValue(pAd, BW_20);
-
-	RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS);
-	/*RTMP_IO_WRITE32(pAd, TX_CNTL_CSR, 0x000f0000);                // abort all TX rings */
-}
-
-/*
-	========================================================================
-
-	Routine Description:
-		Resume MSDU transmission
-
-	Arguments:
-		pAd 	Pointer to our adapter
-
-	Return Value:
-		None
-
-	IRQL = DISPATCH_LEVEL
-
-	Note:
-
-	========================================================================
-*/
-void RTMPResumeMsduTransmission(struct rt_rtmp_adapter *pAd)
-{
-/*    u8                     IrqState; */
-
-	DBGPRINT(RT_DEBUG_TRACE, ("SCAN done, resume MSDU transmission ...\n"));
-
-	/* After finish BSS_SCAN_IN_PROGRESS, we need to restore Current R66 value */
-	/* R66 should not be 0 */
-	if (pAd->BbpTuning.R66CurrentValue == 0) {
-		pAd->BbpTuning.R66CurrentValue = 0x38;
-		DBGPRINT_ERR("RTMPResumeMsduTransmission, R66CurrentValue=0...\n");
-	}
-
-	RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66,
-				     pAd->BbpTuning.R66CurrentValue);
-
-	RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS);
-/* sample, for IRQ LOCK to SEM LOCK */
-/*    IrqState = pAd->irq_disabled; */
-/*      if (IrqState) */
-/*              RTMPDeQueuePacket(pAd, TRUE, NUM_OF_TX_RING, MAX_TX_PROCESS); */
-/*    else */
-	RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, MAX_TX_PROCESS);
-}
-
-u32 deaggregate_AMSDU_announce(struct rt_rtmp_adapter *pAd,
-				void *pPacket,
-				u8 *pData, unsigned long DataSize)
-{
-	u16 PayloadSize;
-	u16 SubFrameSize;
-	struct rt_header_802_3 * pAMSDUsubheader;
-	u32 nMSDU;
-	u8 Header802_3[14];
-
-	u8 *pPayload, *pDA, *pSA, *pRemovedLLCSNAP;
-	void *pClonePacket;
-
-	nMSDU = 0;
-
-	while (DataSize > LENGTH_802_3) {
-
-		nMSDU++;
-
-		/*hex_dump("subheader", pData, 64); */
-		pAMSDUsubheader = (struct rt_header_802_3 *) pData;
-		/*pData += LENGTH_802_3; */
-		PayloadSize =
-		    pAMSDUsubheader->Octet[1] +
-		    (pAMSDUsubheader->Octet[0] << 8);
-		SubFrameSize = PayloadSize + LENGTH_802_3;
-
-		if ((DataSize < SubFrameSize) || (PayloadSize > 1518)) {
-			break;
-		}
-		/*DBGPRINT(RT_DEBUG_TRACE,("%d subframe: Size = %d\n",  nMSDU, PayloadSize)); */
-
-		pPayload = pData + LENGTH_802_3;
-		pDA = pData;
-		pSA = pData + MAC_ADDR_LEN;
-
-		/* convert to 802.3 header */
-		CONVERT_TO_802_3(Header802_3, pDA, pSA, pPayload, PayloadSize,
-				 pRemovedLLCSNAP);
-
-		if ((Header802_3[12] == 0x88) && (Header802_3[13] == 0x8E)) {
-			/* avoid local heap overflow, use dyanamic allocation */
-			struct rt_mlme_queue_elem *Elem =
-			    kmalloc(sizeof(struct rt_mlme_queue_elem),
-							MEM_ALLOC_FLAG);
-			if (Elem != NULL) {
-				memmove(Elem->Msg +
-					(LENGTH_802_11 + LENGTH_802_1_H),
-					pPayload, PayloadSize);
-				Elem->MsgLen =
-				    LENGTH_802_11 + LENGTH_802_1_H +
-				    PayloadSize;
-				/*WpaEAPOLKeyAction(pAd, Elem); */
-				REPORT_MGMT_FRAME_TO_MLME(pAd, BSSID_WCID,
-							  Elem->Msg,
-							  Elem->MsgLen, 0, 0, 0,
-							  0);
-				kfree(Elem);
-			}
-		}
-
-		{
-			if (pRemovedLLCSNAP) {
-				pPayload -= LENGTH_802_3;
-				PayloadSize += LENGTH_802_3;
-				NdisMoveMemory(pPayload, &Header802_3[0],
-					       LENGTH_802_3);
-			}
-		}
-
-		pClonePacket = ClonePacket(pAd, pPacket, pPayload, PayloadSize);
-		if (pClonePacket) {
-			ANNOUNCE_OR_FORWARD_802_3_PACKET(pAd, pClonePacket,
-							 RTMP_GET_PACKET_IF
-							 (pPacket));
-		}
-
-		/* A-MSDU has padding to multiple of 4 including subframe header. */
-		/* align SubFrameSize up to multiple of 4 */
-		SubFrameSize = (SubFrameSize + 3) & (~0x3);
-
-		if (SubFrameSize > 1528 || SubFrameSize < 32) {
-			break;
-		}
-
-		if (DataSize > SubFrameSize) {
-			pData += SubFrameSize;
-			DataSize -= SubFrameSize;
-		} else {
-			/* end of A-MSDU */
-			DataSize = 0;
-		}
-	}
-
-	/* finally release original rx packet */
-	RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_SUCCESS);
-
-	return nMSDU;
-}
-
-u32 BA_Reorder_AMSDU_Announce(struct rt_rtmp_adapter *pAd, void *pPacket)
-{
-	u8 *pData;
-	u16 DataSize;
-	u32 nMSDU = 0;
-
-	pData = (u8 *)GET_OS_PKT_DATAPTR(pPacket);
-	DataSize = (u16)GET_OS_PKT_LEN(pPacket);
-
-	nMSDU = deaggregate_AMSDU_announce(pAd, pPacket, pData, DataSize);
-
-	return nMSDU;
-}
-
-/*
-	==========================================================================
-	Description:
-		Look up the MAC address in the MAC table. Return NULL if not found.
-	Return:
-		pEntry - pointer to the MAC entry; NULL is not found
-	==========================================================================
-*/
-struct rt_mac_table_entry *MacTableLookup(struct rt_rtmp_adapter *pAd, u8 *pAddr)
-{
-	unsigned long HashIdx;
-	struct rt_mac_table_entry *pEntry = NULL;
-
-	HashIdx = MAC_ADDR_HASH_INDEX(pAddr);
-	pEntry = pAd->MacTab.Hash[HashIdx];
-
-	while (pEntry
-	       && (pEntry->ValidAsCLI || pEntry->ValidAsWDS
-		   || pEntry->ValidAsApCli || pEntry->ValidAsMesh)) {
-		if (MAC_ADDR_EQUAL(pEntry->Addr, pAddr)) {
-			break;
-		} else
-			pEntry = pEntry->pNext;
-	}
-
-	return pEntry;
-}
-
-struct rt_mac_table_entry *MacTableInsertEntry(struct rt_rtmp_adapter *pAd,
-				     u8 *pAddr,
-				     u8 apidx, IN BOOLEAN CleanAll)
-{
-	u8 HashIdx;
-	int i, FirstWcid;
-	struct rt_mac_table_entry *pEntry = NULL, *pCurrEntry;
-/*      u16  offset; */
-/*      unsigned long   addr; */
-
-	/* if FULL, return */
-	if (pAd->MacTab.Size >= MAX_LEN_OF_MAC_TABLE)
-		return NULL;
-
-	FirstWcid = 1;
-
-	if (pAd->StaCfg.BssType == BSS_INFRA)
-		FirstWcid = 2;
-
-	/* allocate one MAC entry */
-	NdisAcquireSpinLock(&pAd->MacTabLock);
-	for (i = FirstWcid; i < MAX_LEN_OF_MAC_TABLE; i++)	/* skip entry#0 so that "entry index == AID" for fast lookup */
-	{
-		/* pick up the first available vacancy */
-		if ((pAd->MacTab.Content[i].ValidAsCLI == FALSE) &&
-		    (pAd->MacTab.Content[i].ValidAsWDS == FALSE) &&
-		    (pAd->MacTab.Content[i].ValidAsApCli == FALSE) &&
-		    (pAd->MacTab.Content[i].ValidAsMesh == FALSE)
-		    ) {
-			pEntry = &pAd->MacTab.Content[i];
-			if (CleanAll == TRUE) {
-				pEntry->MaxSupportedRate = RATE_11;
-				pEntry->CurrTxRate = RATE_11;
-				NdisZeroMemory(pEntry, sizeof(struct rt_mac_table_entry));
-				pEntry->PairwiseKey.KeyLen = 0;
-				pEntry->PairwiseKey.CipherAlg = CIPHER_NONE;
-			}
-			{
-				{
-					pEntry->ValidAsCLI = TRUE;
-					pEntry->ValidAsWDS = FALSE;
-					pEntry->ValidAsApCli = FALSE;
-					pEntry->ValidAsMesh = FALSE;
-					pEntry->ValidAsDls = FALSE;
-				}
-			}
-
-			pEntry->bIAmBadAtheros = FALSE;
-			pEntry->pAd = pAd;
-			pEntry->CMTimerRunning = FALSE;
-			pEntry->EnqueueEapolStartTimerRunning =
-			    EAPOL_START_DISABLE;
-			pEntry->RSNIE_Len = 0;
-			NdisZeroMemory(pEntry->R_Counter,
-				       sizeof(pEntry->R_Counter));
-			pEntry->ReTryCounter = PEER_MSG1_RETRY_TIMER_CTR;
-
-			if (pEntry->ValidAsMesh)
-				pEntry->apidx =
-				    (apidx - MIN_NET_DEVICE_FOR_MESH);
-			else if (pEntry->ValidAsApCli)
-				pEntry->apidx =
-				    (apidx - MIN_NET_DEVICE_FOR_APCLI);
-			else if (pEntry->ValidAsWDS)
-				pEntry->apidx =
-				    (apidx - MIN_NET_DEVICE_FOR_WDS);
-			else
-				pEntry->apidx = apidx;
-
-			{
-				{
-					pEntry->AuthMode = pAd->StaCfg.AuthMode;
-					pEntry->WepStatus =
-					    pAd->StaCfg.WepStatus;
-					pEntry->PrivacyFilter =
-					    Ndis802_11PrivFilterAcceptAll;
-#ifdef RTMP_MAC_PCI
-					AsicRemovePairwiseKeyEntry(pAd,
-								   pEntry->
-								   apidx,
-								   (u8)i);
-#endif /* RTMP_MAC_PCI // */
-				}
-			}
-
-			pEntry->GTKState = REKEY_NEGOTIATING;
-			pEntry->PairwiseKey.KeyLen = 0;
-			pEntry->PairwiseKey.CipherAlg = CIPHER_NONE;
-			pEntry->PortSecured = WPA_802_1X_PORT_NOT_SECURED;
-
-			pEntry->PMKID_CacheIdx = ENTRY_NOT_FOUND;
-			COPY_MAC_ADDR(pEntry->Addr, pAddr);
-			pEntry->Sst = SST_NOT_AUTH;
-			pEntry->AuthState = AS_NOT_AUTH;
-			pEntry->Aid = (u16)i;	/*0; */
-			pEntry->CapabilityInfo = 0;
-			pEntry->PsMode = PWR_ACTIVE;
-			pEntry->PsQIdleCount = 0;
-			pEntry->NoDataIdleCount = 0;
-			pEntry->AssocDeadLine = MAC_TABLE_ASSOC_TIMEOUT;
-			pEntry->ContinueTxFailCnt = 0;
-			InitializeQueueHeader(&pEntry->PsQueue);
-
-			pAd->MacTab.Size++;
-			/* Add this entry into ASIC RX WCID search table */
-			RTMP_STA_ENTRY_ADD(pAd, pEntry);
-
-			DBGPRINT(RT_DEBUG_TRACE,
-				 ("MacTableInsertEntry - allocate entry #%d, Total= %d\n",
-				  i, pAd->MacTab.Size));
-			break;
-		}
-	}
-
-	/* add this MAC entry into HASH table */
-	if (pEntry) {
-		HashIdx = MAC_ADDR_HASH_INDEX(pAddr);
-		if (pAd->MacTab.Hash[HashIdx] == NULL) {
-			pAd->MacTab.Hash[HashIdx] = pEntry;
-		} else {
-			pCurrEntry = pAd->MacTab.Hash[HashIdx];
-			while (pCurrEntry->pNext != NULL)
-				pCurrEntry = pCurrEntry->pNext;
-			pCurrEntry->pNext = pEntry;
-		}
-	}
-
-	NdisReleaseSpinLock(&pAd->MacTabLock);
-	return pEntry;
-}
-
-/*
-	==========================================================================
-	Description:
-		Delete a specified client from MAC table
-	==========================================================================
- */
-BOOLEAN MacTableDeleteEntry(struct rt_rtmp_adapter *pAd,
-			    u16 wcid, u8 *pAddr)
-{
-	u16 HashIdx;
-	struct rt_mac_table_entry *pEntry, *pPrevEntry, *pProbeEntry;
-	BOOLEAN Cancelled;
-	/*u16        offset; // unused variable */
-	/*u8 j;                      // unused variable */
-
-	if (wcid >= MAX_LEN_OF_MAC_TABLE)
-		return FALSE;
-
-	NdisAcquireSpinLock(&pAd->MacTabLock);
-
-	HashIdx = MAC_ADDR_HASH_INDEX(pAddr);
-	/*pEntry = pAd->MacTab.Hash[HashIdx]; */
-	pEntry = &pAd->MacTab.Content[wcid];
-
-	if (pEntry
-	    && (pEntry->ValidAsCLI || pEntry->ValidAsApCli || pEntry->ValidAsWDS
-		|| pEntry->ValidAsMesh)) {
-		if (MAC_ADDR_EQUAL(pEntry->Addr, pAddr)) {
-
-			/* Delete this entry from ASIC on-chip WCID Table */
-			RTMP_STA_ENTRY_MAC_RESET(pAd, wcid);
-
-			/* free resources of BA */
-			BASessionTearDownALL(pAd, pEntry->Aid);
-
-			pPrevEntry = NULL;
-			pProbeEntry = pAd->MacTab.Hash[HashIdx];
-			ASSERT(pProbeEntry);
-
-			/* update Hash list */
-			do {
-				if (pProbeEntry == pEntry) {
-					if (pPrevEntry == NULL) {
-						pAd->MacTab.Hash[HashIdx] =
-						    pEntry->pNext;
-					} else {
-						pPrevEntry->pNext =
-						    pEntry->pNext;
-					}
-					break;
-				}
-
-				pPrevEntry = pProbeEntry;
-				pProbeEntry = pProbeEntry->pNext;
-			} while (pProbeEntry);
-
-			/* not found ! */
-			ASSERT(pProbeEntry != NULL);
-
-			RTMP_STA_ENTRY_KEY_DEL(pAd, BSS0, wcid);
-
-			if (pEntry->EnqueueEapolStartTimerRunning !=
-			    EAPOL_START_DISABLE) {
-				RTMPCancelTimer(&pEntry->
-						EnqueueStartForPSKTimer,
-						&Cancelled);
-				pEntry->EnqueueEapolStartTimerRunning =
-				    EAPOL_START_DISABLE;
-			}
-
-			NdisZeroMemory(pEntry, sizeof(struct rt_mac_table_entry));
-			pAd->MacTab.Size--;
-			DBGPRINT(RT_DEBUG_TRACE,
-				 ("MacTableDeleteEntry1 - Total= %d\n",
-				  pAd->MacTab.Size));
-		} else {
-			DBGPRINT(RT_DEBUG_OFF,
-				 ("\n%s: Impossible Wcid = %d !\n",
-				  __func__, wcid));
-		}
-	}
-
-	NdisReleaseSpinLock(&pAd->MacTabLock);
-
-	/*Reset operating mode when no Sta. */
-	if (pAd->MacTab.Size == 0) {
-		pAd->CommonCfg.AddHTInfo.AddHtInfo2.OperaionMode = 0;
-		RTMP_UPDATE_PROTECT(pAd);	/* edit by johnli, fix "in_interrupt" error when call "MacTableDeleteEntry" in Rx tasklet */
-	}
-
-	return TRUE;
-}
-
-/*
-	==========================================================================
-	Description:
-		This routine reset the entire MAC table. All packets pending in
-		the power-saving queues are freed here.
-	==========================================================================
- */
-void MacTableReset(struct rt_rtmp_adapter *pAd)
-{
-	int i;
-
-	DBGPRINT(RT_DEBUG_TRACE, ("MacTableReset\n"));
-	/*NdisAcquireSpinLock(&pAd->MacTabLock); */
-
-	for (i = 1; i < MAX_LEN_OF_MAC_TABLE; i++) {
-#ifdef RTMP_MAC_PCI
-		RTMP_STA_ENTRY_MAC_RESET(pAd, i);
-#endif /* RTMP_MAC_PCI // */
-		if (pAd->MacTab.Content[i].ValidAsCLI == TRUE) {
-
-			/* free resources of BA */
-			BASessionTearDownALL(pAd, i);
-
-			pAd->MacTab.Content[i].ValidAsCLI = FALSE;
-
-#ifdef RTMP_MAC_USB
-			NdisZeroMemory(pAd->MacTab.Content[i].Addr, 6);
-			RTMP_STA_ENTRY_MAC_RESET(pAd, i);
-#endif /* RTMP_MAC_USB // */
-
-			/*AsicDelWcidTab(pAd, i); */
-		}
-	}
-
-	return;
-}
-
-/*
-	==========================================================================
-	Description:
-
-	IRQL = DISPATCH_LEVEL
-
-	==========================================================================
-*/
-void AssocParmFill(struct rt_rtmp_adapter *pAd,
-		   struct rt_mlme_assoc_req *AssocReq,
-		   u8 *pAddr,
-		   u16 CapabilityInfo,
-		   unsigned long Timeout, u16 ListenIntv)
-{
-	COPY_MAC_ADDR(AssocReq->Addr, pAddr);
-	/* Add mask to support 802.11b mode only */
-	AssocReq->CapabilityInfo = CapabilityInfo & SUPPORTED_CAPABILITY_INFO;	/* not cf-pollable, not cf-poll-request */
-	AssocReq->Timeout = Timeout;
-	AssocReq->ListenIntv = ListenIntv;
-}
-
-/*
-	==========================================================================
-	Description:
-
-	IRQL = DISPATCH_LEVEL
-
-	==========================================================================
-*/
-void DisassocParmFill(struct rt_rtmp_adapter *pAd,
-		      struct rt_mlme_disassoc_req *DisassocReq,
-		      u8 *pAddr, u16 Reason)
-{
-	COPY_MAC_ADDR(DisassocReq->Addr, pAddr);
-	DisassocReq->Reason = Reason;
-}
-
-/*
-	========================================================================
-
-	Routine Description:
-		Check the out going frame, if this is an DHCP or ARP datagram
-	will be duplicate another frame at low data rate transmit.
-
-	Arguments:
-		pAd 		Pointer to our adapter
-		pPacket 	Pointer to outgoing Ndis frame
-
-	Return Value:
-		TRUE		To be duplicate at Low data rate transmit. (1mb)
-		FALSE		Do nothing.
-
-	IRQL = DISPATCH_LEVEL
-
-	Note:
-
-		MAC header + IP Header + UDP Header
-		  14 Bytes	  20 Bytes
-
-		UDP Header
-		00|01|02|03|04|05|06|07|08|09|10|11|12|13|14|15|
-						Source Port
-		16|17|18|19|20|21|22|23|24|25|26|27|28|29|30|31|
-					Destination Port
-
-		port 0x43 means Bootstrap Protocol, server.
-		Port 0x44 means Bootstrap Protocol, client.
-
-	========================================================================
-*/
-
-BOOLEAN RTMPCheckDHCPFrame(struct rt_rtmp_adapter *pAd, void *pPacket)
-{
-	struct rt_packet_info PacketInfo;
-	unsigned long NumberOfBytesRead = 0;
-	unsigned long CurrentOffset = 0;
-	void *pVirtualAddress = NULL;
-	u32 NdisBufferLength;
-	u8 *pSrc;
-	u16 Protocol;
-	u8 ByteOffset36 = 0;
-	u8 ByteOffset38 = 0;
-	BOOLEAN ReadFirstParm = TRUE;
-
-	RTMP_QueryPacketInfo(pPacket, &PacketInfo, (u8 **) & pVirtualAddress,
-			     &NdisBufferLength);
-
-	NumberOfBytesRead += NdisBufferLength;
-	pSrc = (u8 *)pVirtualAddress;
-	Protocol = *(pSrc + 12) * 256 + *(pSrc + 13);
-
-	/* */
-	/* Check DHCP & BOOTP protocol */
-	/* */
-	while (NumberOfBytesRead <= PacketInfo.TotalPacketLength) {
-		if ((NumberOfBytesRead >= 35) && (ReadFirstParm == TRUE)) {
-			CurrentOffset =
-			    35 - (NumberOfBytesRead - NdisBufferLength);
-			ByteOffset36 = *(pSrc + CurrentOffset);
-			ReadFirstParm = FALSE;
-		}
-
-		if (NumberOfBytesRead >= 37) {
-			CurrentOffset =
-			    37 - (NumberOfBytesRead - NdisBufferLength);
-			ByteOffset38 = *(pSrc + CurrentOffset);
-			/*End of Read */
-			break;
-		}
-		return FALSE;
-	}
-
-	/* Check for DHCP & BOOTP protocol */
-	if ((ByteOffset36 != 0x44) || (ByteOffset38 != 0x43)) {
-		/* */
-		/* 2054 (hex 0806) for ARP datagrams */
-		/* if this packet is not ARP datagrams, then do nothing */
-		/* ARP datagrams will also be duplicate at 1mb broadcast frames */
-		/* */
-		if (Protocol != 0x0806)
-			return FALSE;
-	}
-
-	return TRUE;
-}
-
-BOOLEAN RTMPCheckEtherType(struct rt_rtmp_adapter *pAd, void *pPacket)
-{
-	u16 TypeLen;
-	u8 Byte0, Byte1;
-	u8 *pSrcBuf;
-	u32 pktLen;
-	u16 srcPort, dstPort;
-	BOOLEAN status = TRUE;
-
-	pSrcBuf = GET_OS_PKT_DATAPTR(pPacket);
-	pktLen = GET_OS_PKT_LEN(pPacket);
-
-	ASSERT(pSrcBuf);
-
-	RTMP_SET_PACKET_SPECIFIC(pPacket, 0);
-
-	/* get Ethernet protocol field */
-	TypeLen = (pSrcBuf[12] << 8) | pSrcBuf[13];
-
-	pSrcBuf += LENGTH_802_3;	/* Skip the Ethernet Header. */
-
-	if (TypeLen <= 1500) {	/* 802.3, 802.3 LLC */
-		/*
-		   DestMAC(6) + SrcMAC(6) + Length(2) +
-		   DSAP(1) + SSAP(1) + Control(1) +
-		   if the DSAP = 0xAA, SSAP=0xAA, Contorl = 0x03, it has a 5-bytes SNAP header.
-		   => + SNAP (5, OriginationID(3) + etherType(2))
-		 */
-		if (pSrcBuf[0] == 0xAA && pSrcBuf[1] == 0xAA
-		    && pSrcBuf[2] == 0x03) {
-			Sniff2BytesFromNdisBuffer((char *)pSrcBuf, 6,
-						  &Byte0, &Byte1);
-			RTMP_SET_PACKET_LLCSNAP(pPacket, 1);
-			TypeLen = (u16)((Byte0 << 8) + Byte1);
-			pSrcBuf += 8;	/* Skip this LLC/SNAP header */
-		} else {
-			/*It just has 3-byte LLC header, maybe a legacy ether type frame. we didn't handle it. */
-		}
-	}
-	/* If it's a VLAN packet, get the real Type/Length field. */
-	if (TypeLen == 0x8100) {
-		/* 0x8100 means VLAN packets */
-
-		/* Dest. MAC Address (6-bytes) +
-		   Source MAC Address (6-bytes) +
-		   Length/Type = 802.1Q Tag Type (2-byte) +
-		   Tag Control Information (2-bytes) +
-		   Length / Type (2-bytes) +
-		   data payload (0-n bytes) +
-		   Pad (0-p bytes) +
-		   Frame Check Sequence (4-bytes) */
-
-		RTMP_SET_PACKET_VLAN(pPacket, 1);
-		Sniff2BytesFromNdisBuffer((char *)pSrcBuf, 2, &Byte0,
-					  &Byte1);
-		TypeLen = (u16)((Byte0 << 8) + Byte1);
-
-		pSrcBuf += 4;	/* Skip the VLAN Header. */
-	}
-
-	switch (TypeLen) {
-	case 0x0800:
-		{
-			ASSERT((pktLen > 34));
-			if (*(pSrcBuf + 9) == 0x11) {	/* udp packet */
-				ASSERT((pktLen > 34));	/* 14 for ethernet header, 20 for IP header */
-
-				pSrcBuf += 20;	/* Skip the IP header */
-				srcPort =
-				    OS_NTOHS(get_unaligned
-					     ((u16 *)(pSrcBuf)));
-				dstPort =
-				    OS_NTOHS(get_unaligned
-					     ((u16 *)(pSrcBuf + 2)));
-
-				if ((srcPort == 0x44 && dstPort == 0x43) || (srcPort == 0x43 && dstPort == 0x44)) {	/*It's a BOOTP/DHCP packet */
-					RTMP_SET_PACKET_DHCP(pPacket, 1);
-				}
-			}
-		}
-		break;
-	case 0x0806:
-		{
-			/*ARP Packet. */
-			RTMP_SET_PACKET_DHCP(pPacket, 1);
-		}
-		break;
-	case 0x888e:
-		{
-			/* EAPOL Packet. */
-			RTMP_SET_PACKET_EAPOL(pPacket, 1);
-		}
-		break;
-	default:
-		status = FALSE;
-		break;
-	}
-
-	return status;
-
-}
-
-void Update_Rssi_Sample(struct rt_rtmp_adapter *pAd,
-			struct rt_rssi_sample *pRssi, struct rt_rxwi * pRxWI)
-{
-	char rssi0 = pRxWI->RSSI0;
-	char rssi1 = pRxWI->RSSI1;
-	char rssi2 = pRxWI->RSSI2;
-
-	if (rssi0 != 0) {
-		pRssi->LastRssi0 = ConvertToRssi(pAd, (char)rssi0, RSSI_0);
-		pRssi->AvgRssi0X8 =
-		    (pRssi->AvgRssi0X8 - pRssi->AvgRssi0) + pRssi->LastRssi0;
-		pRssi->AvgRssi0 = pRssi->AvgRssi0X8 >> 3;
-	}
-
-	if (rssi1 != 0) {
-		pRssi->LastRssi1 = ConvertToRssi(pAd, (char)rssi1, RSSI_1);
-		pRssi->AvgRssi1X8 =
-		    (pRssi->AvgRssi1X8 - pRssi->AvgRssi1) + pRssi->LastRssi1;
-		pRssi->AvgRssi1 = pRssi->AvgRssi1X8 >> 3;
-	}
-
-	if (rssi2 != 0) {
-		pRssi->LastRssi2 = ConvertToRssi(pAd, (char)rssi2, RSSI_2);
-		pRssi->AvgRssi2X8 =
-		    (pRssi->AvgRssi2X8 - pRssi->AvgRssi2) + pRssi->LastRssi2;
-		pRssi->AvgRssi2 = pRssi->AvgRssi2X8 >> 3;
-	}
-}
-
-/* Normal legacy Rx packet indication */
-void Indicate_Legacy_Packet(struct rt_rtmp_adapter *pAd,
-			    struct rt_rx_blk *pRxBlk, u8 FromWhichBSSID)
-{
-	void *pRxPacket = pRxBlk->pRxPacket;
-	u8 Header802_3[LENGTH_802_3];
-
-	/* 1. get 802.3 Header */
-	/* 2. remove LLC */
-	/*              a. pointer pRxBlk->pData to payload */
-	/*      b. modify pRxBlk->DataSize */
-	RTMP_802_11_REMOVE_LLC_AND_CONVERT_TO_802_3(pRxBlk, Header802_3);
-
-	if (pRxBlk->DataSize > MAX_RX_PKT_LEN) {
-
-		/* release packet */
-		RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_FAILURE);
-		return;
-	}
-
-	STATS_INC_RX_PACKETS(pAd, FromWhichBSSID);
-
-#ifdef RTMP_MAC_USB
-	if (pAd->CommonCfg.bDisableReordering == 0) {
-		struct rt_ba_rec_entry *pBAEntry;
-		unsigned long Now32;
-		u8 Wcid = pRxBlk->pRxWI->WirelessCliID;
-		u8 TID = pRxBlk->pRxWI->TID;
-		u16 Idx;
-
-#define REORDERING_PACKET_TIMEOUT		((100 * OS_HZ)/1000)	/* system ticks -- 100 ms */
-
-		if (Wcid < MAX_LEN_OF_MAC_TABLE) {
-			Idx = pAd->MacTab.Content[Wcid].BARecWcidArray[TID];
-			if (Idx != 0) {
-				pBAEntry = &pAd->BATable.BARecEntry[Idx];
-				/* update last rx time */
-				NdisGetSystemUpTime(&Now32);
-				if ((pBAEntry->list.qlen > 0) &&
-				    RTMP_TIME_AFTER((unsigned long)Now32,
-						    (unsigned long)(pBAEntry->
-								    LastIndSeqAtTimer
-								    +
-								    (REORDERING_PACKET_TIMEOUT)))
-				    ) {
-					DBGPRINT(RT_DEBUG_OFF,
-						 ("Indicate_Legacy_Packet():flush reordering_timeout_mpdus! RxWI->Flags=%d, pRxWI.TID=%d, RxD->AMPDU=%d!\n",
-						  pRxBlk->Flags,
-						  pRxBlk->pRxWI->TID,
-						  pRxBlk->RxD.AMPDU));
-					hex_dump("Dump the legacy Packet:",
-						 GET_OS_PKT_DATAPTR(pRxBlk->
-								    pRxPacket),
-						 64);
-					ba_flush_reordering_timeout_mpdus(pAd,
-									  pBAEntry,
-									  Now32);
-				}
-			}
-		}
-	}
-#endif /* RTMP_MAC_USB // */
-
-	wlan_802_11_to_802_3_packet(pAd, pRxBlk, Header802_3, FromWhichBSSID);
-
-	/* */
-	/* pass this 802.3 packet to upper layer or forward this packet to WM directly */
-	/* */
-	ANNOUNCE_OR_FORWARD_802_3_PACKET(pAd, pRxPacket, FromWhichBSSID);
-}
-
-/* Normal, AMPDU or AMSDU */
-void CmmRxnonRalinkFrameIndicate(struct rt_rtmp_adapter *pAd,
-				 struct rt_rx_blk *pRxBlk, u8 FromWhichBSSID)
-{
-	if (RX_BLK_TEST_FLAG(pRxBlk, fRX_AMPDU)
-	    && (pAd->CommonCfg.bDisableReordering == 0)) {
-		Indicate_AMPDU_Packet(pAd, pRxBlk, FromWhichBSSID);
-	} else {
-		if (RX_BLK_TEST_FLAG(pRxBlk, fRX_AMSDU)) {
-			/* handle A-MSDU */
-			Indicate_AMSDU_Packet(pAd, pRxBlk, FromWhichBSSID);
-		} else {
-			Indicate_Legacy_Packet(pAd, pRxBlk, FromWhichBSSID);
-		}
-	}
-}
-
-void CmmRxRalinkFrameIndicate(struct rt_rtmp_adapter *pAd,
-			      struct rt_mac_table_entry *pEntry,
-			      struct rt_rx_blk *pRxBlk, u8 FromWhichBSSID)
-{
-	u8 Header802_3[LENGTH_802_3];
-	u16 Msdu2Size;
-	u16 Payload1Size, Payload2Size;
-	u8 *pData2;
-	void *pPacket2 = NULL;
-
-	Msdu2Size = *(pRxBlk->pData) + (*(pRxBlk->pData + 1) << 8);
-
-	if ((Msdu2Size <= 1536) && (Msdu2Size < pRxBlk->DataSize)) {
-		/* skip two byte MSDU2 len */
-		pRxBlk->pData += 2;
-		pRxBlk->DataSize -= 2;
-	} else {
-		/* release packet */
-		RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket,
-				    NDIS_STATUS_FAILURE);
-		return;
-	}
-
-	/* get 802.3 Header and  remove LLC */
-	RTMP_802_11_REMOVE_LLC_AND_CONVERT_TO_802_3(pRxBlk, Header802_3);
-
-	ASSERT(pRxBlk->pRxPacket);
-
-	/* Ralink Aggregation frame */
-	pAd->RalinkCounters.OneSecRxAggregationCount++;
-	Payload1Size = pRxBlk->DataSize - Msdu2Size;
-	Payload2Size = Msdu2Size - LENGTH_802_3;
-
-	pData2 = pRxBlk->pData + Payload1Size + LENGTH_802_3;
-
-	pPacket2 =
-	    duplicate_pkt(pAd, (pData2 - LENGTH_802_3), LENGTH_802_3, pData2,
-			  Payload2Size, FromWhichBSSID);
-
-	if (!pPacket2) {
-		/* release packet */
-		RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket,
-				    NDIS_STATUS_FAILURE);
-		return;
-	}
-	/* update payload size of 1st packet */
-	pRxBlk->DataSize = Payload1Size;
-	wlan_802_11_to_802_3_packet(pAd, pRxBlk, Header802_3, FromWhichBSSID);
-
-	ANNOUNCE_OR_FORWARD_802_3_PACKET(pAd, pRxBlk->pRxPacket,
-					 FromWhichBSSID);
-
-	if (pPacket2) {
-		ANNOUNCE_OR_FORWARD_802_3_PACKET(pAd, pPacket2, FromWhichBSSID);
-	}
-}
-
-#define RESET_FRAGFRAME(_fragFrame) \
-	{								\
-		_fragFrame.RxSize = 0;		\
-		_fragFrame.Sequence = 0;	\
-		_fragFrame.LastFrag = 0;	\
-		_fragFrame.Flags = 0;		\
-	}
-
-void *RTMPDeFragmentDataFrame(struct rt_rtmp_adapter *pAd, struct rt_rx_blk *pRxBlk)
-{
-	struct rt_header_802_11 * pHeader = pRxBlk->pHeader;
-	void *pRxPacket = pRxBlk->pRxPacket;
-	u8 *pData = pRxBlk->pData;
-	u16 DataSize = pRxBlk->DataSize;
-	void *pRetPacket = NULL;
-	u8 *pFragBuffer = NULL;
-	BOOLEAN bReassDone = FALSE;
-	u8 HeaderRoom = 0;
-
-	ASSERT(pHeader);
-
-	HeaderRoom = pData - (u8 *) pHeader;
-
-	/* Re-assemble the fragmented packets */
-	if (pHeader->Frag == 0)	/* Frag. Number is 0 : First frag or only one pkt */
-	{
-		/* the first pkt of fragment, record it. */
-		if (pHeader->FC.MoreFrag) {
-			ASSERT(pAd->FragFrame.pFragPacket);
-			pFragBuffer =
-			    GET_OS_PKT_DATAPTR(pAd->FragFrame.pFragPacket);
-			pAd->FragFrame.RxSize = DataSize + HeaderRoom;
-			NdisMoveMemory(pFragBuffer, pHeader,
-				       pAd->FragFrame.RxSize);
-			pAd->FragFrame.Sequence = pHeader->Sequence;
-			pAd->FragFrame.LastFrag = pHeader->Frag;	/* Should be 0 */
-			ASSERT(pAd->FragFrame.LastFrag == 0);
-			goto done;	/* end of processing this frame */
-		}
-	} else			/*Middle & End of fragment */
-	{
-		if ((pHeader->Sequence != pAd->FragFrame.Sequence) ||
-		    (pHeader->Frag != (pAd->FragFrame.LastFrag + 1))) {
-			/* Fragment is not the same sequence or out of fragment number order */
-			/* Reset Fragment control blk */
-			RESET_FRAGFRAME(pAd->FragFrame);
-			DBGPRINT(RT_DEBUG_ERROR,
-				 ("Fragment is not the same sequence or out of fragment number order.\n"));
-			goto done;	/* give up this frame */
-		} else if ((pAd->FragFrame.RxSize + DataSize) > MAX_FRAME_SIZE) {
-			/* Fragment frame is too large, it exeeds the maximum frame size. */
-			/* Reset Fragment control blk */
-			RESET_FRAGFRAME(pAd->FragFrame);
-			DBGPRINT(RT_DEBUG_ERROR,
-				 ("Fragment frame is too large, it exeeds the maximum frame size.\n"));
-			goto done;	/* give up this frame */
-		}
-		/* */
-		/* Broadcom AP(BCM94704AGR) will send out LLC in fragment's packet, LLC only can accpet at first fragment. */
-		/* In this case, we will dropt it. */
-		/* */
-		if (NdisEqualMemory(pData, SNAP_802_1H, sizeof(SNAP_802_1H))) {
-			DBGPRINT(RT_DEBUG_ERROR,
-				 ("Find another LLC at Middle or End fragment(SN=%d, Frag=%d)\n",
-				  pHeader->Sequence, pHeader->Frag));
-			goto done;	/* give up this frame */
-		}
-
-		pFragBuffer = GET_OS_PKT_DATAPTR(pAd->FragFrame.pFragPacket);
-
-		/* concatenate this fragment into the re-assembly buffer */
-		NdisMoveMemory((pFragBuffer + pAd->FragFrame.RxSize), pData,
-			       DataSize);
-		pAd->FragFrame.RxSize += DataSize;
-		pAd->FragFrame.LastFrag = pHeader->Frag;	/* Update fragment number */
-
-		/* Last fragment */
-		if (pHeader->FC.MoreFrag == FALSE) {
-			bReassDone = TRUE;
-		}
-	}
-
-done:
-	/* always release rx fragmented packet */
-	RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_FAILURE);
-
-	/* return defragmented packet if packet is reassembled completely */
-	/* otherwise return NULL */
-	if (bReassDone) {
-		void *pNewFragPacket;
-
-		/* allocate a new packet buffer for fragment */
-		pNewFragPacket =
-		    RTMP_AllocateFragPacketBuffer(pAd, RX_BUFFER_NORMSIZE);
-		if (pNewFragPacket) {
-			/* update RxBlk */
-			pRetPacket = pAd->FragFrame.pFragPacket;
-			pAd->FragFrame.pFragPacket = pNewFragPacket;
-			pRxBlk->pHeader =
-			    (struct rt_header_802_11 *) GET_OS_PKT_DATAPTR(pRetPacket);
-			pRxBlk->pData = (u8 *) pRxBlk->pHeader + HeaderRoom;
-			pRxBlk->DataSize = pAd->FragFrame.RxSize - HeaderRoom;
-			pRxBlk->pRxPacket = pRetPacket;
-		} else {
-			RESET_FRAGFRAME(pAd->FragFrame);
-		}
-	}
-
-	return pRetPacket;
-}
-
-void Indicate_AMSDU_Packet(struct rt_rtmp_adapter *pAd,
-			   struct rt_rx_blk *pRxBlk, u8 FromWhichBSSID)
-{
-	u32 nMSDU;
-
-	update_os_packet_info(pAd, pRxBlk, FromWhichBSSID);
-	RTMP_SET_PACKET_IF(pRxBlk->pRxPacket, FromWhichBSSID);
-	nMSDU =
-	    deaggregate_AMSDU_announce(pAd, pRxBlk->pRxPacket, pRxBlk->pData,
-				       pRxBlk->DataSize);
-}
-
-void Indicate_EAPOL_Packet(struct rt_rtmp_adapter *pAd,
-			   struct rt_rx_blk *pRxBlk, u8 FromWhichBSSID)
-{
-	struct rt_mac_table_entry *pEntry = NULL;
-
-	{
-		pEntry = &pAd->MacTab.Content[BSSID_WCID];
-		STARxEAPOLFrameIndicate(pAd, pEntry, pRxBlk, FromWhichBSSID);
-		return;
-	}
-
-	if (pEntry == NULL) {
-		DBGPRINT(RT_DEBUG_WARN,
-			 ("Indicate_EAPOL_Packet: drop and release the invalid packet.\n"));
-		/* release packet */
-		RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket,
-				    NDIS_STATUS_FAILURE);
-		return;
-	}
-}
-
-#define BCN_TBTT_OFFSET		64	/*defer 64 us */
-void ReSyncBeaconTime(struct rt_rtmp_adapter *pAd)
-{
-
-	u32 Offset;
-
-	Offset = (pAd->TbttTickCount) % (BCN_TBTT_OFFSET);
-
-	pAd->TbttTickCount++;
-
-	/* */
-	/* The updated BeaconInterval Value will affect Beacon Interval after two TBTT */
-	/* beacasue the original BeaconInterval had been loaded into next TBTT_TIMER */
-	/* */
-	if (Offset == (BCN_TBTT_OFFSET - 2)) {
-		BCN_TIME_CFG_STRUC csr;
-		RTMP_IO_READ32(pAd, BCN_TIME_CFG, &csr.word);
-		csr.field.BeaconInterval = (pAd->CommonCfg.BeaconPeriod << 4) - 1;	/* ASIC register in units of 1/16 TU = 64us */
-		RTMP_IO_WRITE32(pAd, BCN_TIME_CFG, csr.word);
-	} else {
-		if (Offset == (BCN_TBTT_OFFSET - 1)) {
-			BCN_TIME_CFG_STRUC csr;
-
-			RTMP_IO_READ32(pAd, BCN_TIME_CFG, &csr.word);
-			csr.field.BeaconInterval = (pAd->CommonCfg.BeaconPeriod) << 4;	/* ASIC register in units of 1/16 TU */
-			RTMP_IO_WRITE32(pAd, BCN_TIME_CFG, csr.word);
-		}
-	}
-}
diff -druN linux-2.6.39-libre/drivers/staging/rt2860/common/cmm_data_pci.c linux-3.0-rc7-libre/drivers/staging/rt2860/common/cmm_data_pci.c
--- linux-2.6.39-libre/drivers/staging/rt2860/common/cmm_data_pci.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rt2860/common/cmm_data_pci.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,1096 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, 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.             *
- *                                                                       *
- *************************************************************************
- */
-
-/*
-   All functions in this file must be PCI-depended, or you should out your function
-	in other files.
-
-*/
-#include	"../rt_config.h"
-
-u16 RtmpPCI_WriteTxResource(struct rt_rtmp_adapter *pAd,
-			       struct rt_tx_blk *pTxBlk,
-			       IN BOOLEAN bIsLast, u16 * FreeNumber)
-{
-
-	u8 *pDMAHeaderBufVA;
-	u16 TxIdx, RetTxIdx;
-	struct rt_txd * pTxD;
-	u32 BufBasePaLow;
-	struct rt_rtmp_tx_ring *pTxRing;
-	u16 hwHeaderLen;
-
-	/* */
-	/* get Tx Ring Resource */
-	/* */
-	pTxRing = &pAd->TxRing[pTxBlk->QueIdx];
-	TxIdx = pAd->TxRing[pTxBlk->QueIdx].TxCpuIdx;
-	pDMAHeaderBufVA = (u8 *)pTxRing->Cell[TxIdx].DmaBuf.AllocVa;
-	BufBasePaLow =
-	    RTMP_GetPhysicalAddressLow(pTxRing->Cell[TxIdx].DmaBuf.AllocPa);
-
-	/* copy TXINFO + TXWI + WLAN Header + LLC into DMA Header Buffer */
-	if (pTxBlk->TxFrameType == TX_AMSDU_FRAME) {
-		/*hwHeaderLen = ROUND_UP(pTxBlk->MpduHeaderLen-LENGTH_AMSDU_SUBFRAMEHEAD, 4)+LENGTH_AMSDU_SUBFRAMEHEAD; */
-		hwHeaderLen =
-		    pTxBlk->MpduHeaderLen - LENGTH_AMSDU_SUBFRAMEHEAD +
-		    pTxBlk->HdrPadLen + LENGTH_AMSDU_SUBFRAMEHEAD;
-	} else {
-		/*hwHeaderLen = ROUND_UP(pTxBlk->MpduHeaderLen, 4); */
-		hwHeaderLen = pTxBlk->MpduHeaderLen + pTxBlk->HdrPadLen;
-	}
-	NdisMoveMemory(pDMAHeaderBufVA, pTxBlk->HeaderBuf,
-		       TXINFO_SIZE + TXWI_SIZE + hwHeaderLen);
-
-	pTxRing->Cell[TxIdx].pNdisPacket = pTxBlk->pPacket;
-	pTxRing->Cell[TxIdx].pNextNdisPacket = NULL;
-
-	/* */
-	/* build Tx Descriptor */
-	/* */
-
-	pTxD = (struct rt_txd *) pTxRing->Cell[TxIdx].AllocVa;
-	NdisZeroMemory(pTxD, TXD_SIZE);
-
-	pTxD->SDPtr0 = BufBasePaLow;
-	pTxD->SDLen0 = TXINFO_SIZE + TXWI_SIZE + hwHeaderLen;	/* include padding */
-	pTxD->SDPtr1 = PCI_MAP_SINGLE(pAd, pTxBlk, 0, 1, PCI_DMA_TODEVICE);
-	pTxD->SDLen1 = pTxBlk->SrcBufLen;
-	pTxD->LastSec0 = 0;
-	pTxD->LastSec1 = (bIsLast) ? 1 : 0;
-
-	RTMPWriteTxDescriptor(pAd, pTxD, FALSE, FIFO_EDCA);
-
-	RetTxIdx = TxIdx;
-	/* */
-	/* Update Tx index */
-	/* */
-	INC_RING_INDEX(TxIdx, TX_RING_SIZE);
-	pTxRing->TxCpuIdx = TxIdx;
-
-	*FreeNumber -= 1;
-
-	return RetTxIdx;
-}
-
-u16 RtmpPCI_WriteSingleTxResource(struct rt_rtmp_adapter *pAd,
-				     struct rt_tx_blk *pTxBlk,
-				     IN BOOLEAN bIsLast,
-				     u16 * FreeNumber)
-{
-
-	u8 *pDMAHeaderBufVA;
-	u16 TxIdx, RetTxIdx;
-	struct rt_txd * pTxD;
-	u32 BufBasePaLow;
-	struct rt_rtmp_tx_ring *pTxRing;
-	u16 hwHeaderLen;
-
-	/* */
-	/* get Tx Ring Resource */
-	/* */
-	pTxRing = &pAd->TxRing[pTxBlk->QueIdx];
-	TxIdx = pAd->TxRing[pTxBlk->QueIdx].TxCpuIdx;
-	pDMAHeaderBufVA = (u8 *)pTxRing->Cell[TxIdx].DmaBuf.AllocVa;
-	BufBasePaLow =
-	    RTMP_GetPhysicalAddressLow(pTxRing->Cell[TxIdx].DmaBuf.AllocPa);
-
-	/* copy TXINFO + TXWI + WLAN Header + LLC into DMA Header Buffer */
-	/*hwHeaderLen = ROUND_UP(pTxBlk->MpduHeaderLen, 4); */
-	hwHeaderLen = pTxBlk->MpduHeaderLen + pTxBlk->HdrPadLen;
-
-	NdisMoveMemory(pDMAHeaderBufVA, pTxBlk->HeaderBuf,
-		       TXINFO_SIZE + TXWI_SIZE + hwHeaderLen);
-
-	pTxRing->Cell[TxIdx].pNdisPacket = pTxBlk->pPacket;
-	pTxRing->Cell[TxIdx].pNextNdisPacket = NULL;
-
-	/* */
-	/* build Tx Descriptor */
-	/* */
-	pTxD = (struct rt_txd *) pTxRing->Cell[TxIdx].AllocVa;
-	NdisZeroMemory(pTxD, TXD_SIZE);
-
-	pTxD->SDPtr0 = BufBasePaLow;
-	pTxD->SDLen0 = TXINFO_SIZE + TXWI_SIZE + hwHeaderLen;	/* include padding */
-	pTxD->SDPtr1 = PCI_MAP_SINGLE(pAd, pTxBlk, 0, 1, PCI_DMA_TODEVICE);
-	pTxD->SDLen1 = pTxBlk->SrcBufLen;
-	pTxD->LastSec0 = 0;
-	pTxD->LastSec1 = (bIsLast) ? 1 : 0;
-
-	RTMPWriteTxDescriptor(pAd, pTxD, FALSE, FIFO_EDCA);
-
-	RetTxIdx = TxIdx;
-	/* */
-	/* Update Tx index */
-	/* */
-	INC_RING_INDEX(TxIdx, TX_RING_SIZE);
-	pTxRing->TxCpuIdx = TxIdx;
-
-	*FreeNumber -= 1;
-
-	return RetTxIdx;
-}
-
-u16 RtmpPCI_WriteMultiTxResource(struct rt_rtmp_adapter *pAd,
-				    struct rt_tx_blk *pTxBlk,
-				    u8 frameNum, u16 * FreeNumber)
-{
-	BOOLEAN bIsLast;
-	u8 *pDMAHeaderBufVA;
-	u16 TxIdx, RetTxIdx;
-	struct rt_txd * pTxD;
-	u32 BufBasePaLow;
-	struct rt_rtmp_tx_ring *pTxRing;
-	u16 hwHdrLen;
-	u32 firstDMALen;
-
-	bIsLast = ((frameNum == (pTxBlk->TotalFrameNum - 1)) ? 1 : 0);
-
-	/* */
-	/* get Tx Ring Resource */
-	/* */
-	pTxRing = &pAd->TxRing[pTxBlk->QueIdx];
-	TxIdx = pAd->TxRing[pTxBlk->QueIdx].TxCpuIdx;
-	pDMAHeaderBufVA = (u8 *)pTxRing->Cell[TxIdx].DmaBuf.AllocVa;
-	BufBasePaLow =
-	    RTMP_GetPhysicalAddressLow(pTxRing->Cell[TxIdx].DmaBuf.AllocPa);
-
-	if (frameNum == 0) {
-		/* copy TXINFO + TXWI + WLAN Header + LLC into DMA Header Buffer */
-		if (pTxBlk->TxFrameType == TX_AMSDU_FRAME)
-			/*hwHdrLen = ROUND_UP(pTxBlk->MpduHeaderLen-LENGTH_AMSDU_SUBFRAMEHEAD, 4)+LENGTH_AMSDU_SUBFRAMEHEAD; */
-			hwHdrLen =
-			    pTxBlk->MpduHeaderLen - LENGTH_AMSDU_SUBFRAMEHEAD +
-			    pTxBlk->HdrPadLen + LENGTH_AMSDU_SUBFRAMEHEAD;
-		else if (pTxBlk->TxFrameType == TX_RALINK_FRAME)
-			/*hwHdrLen = ROUND_UP(pTxBlk->MpduHeaderLen-LENGTH_ARALINK_HEADER_FIELD, 4)+LENGTH_ARALINK_HEADER_FIELD; */
-			hwHdrLen =
-			    pTxBlk->MpduHeaderLen -
-			    LENGTH_ARALINK_HEADER_FIELD + pTxBlk->HdrPadLen +
-			    LENGTH_ARALINK_HEADER_FIELD;
-		else
-			/*hwHdrLen = ROUND_UP(pTxBlk->MpduHeaderLen, 4); */
-			hwHdrLen = pTxBlk->MpduHeaderLen + pTxBlk->HdrPadLen;
-
-		firstDMALen = TXINFO_SIZE + TXWI_SIZE + hwHdrLen;
-	} else {
-		firstDMALen = pTxBlk->MpduHeaderLen;
-	}
-
-	NdisMoveMemory(pDMAHeaderBufVA, pTxBlk->HeaderBuf, firstDMALen);
-
-	pTxRing->Cell[TxIdx].pNdisPacket = pTxBlk->pPacket;
-	pTxRing->Cell[TxIdx].pNextNdisPacket = NULL;
-
-	/* */
-	/* build Tx Descriptor */
-	/* */
-	pTxD = (struct rt_txd *) pTxRing->Cell[TxIdx].AllocVa;
-	NdisZeroMemory(pTxD, TXD_SIZE);
-
-	pTxD->SDPtr0 = BufBasePaLow;
-	pTxD->SDLen0 = firstDMALen;	/* include padding */
-	pTxD->SDPtr1 = PCI_MAP_SINGLE(pAd, pTxBlk, 0, 1, PCI_DMA_TODEVICE);
-	pTxD->SDLen1 = pTxBlk->SrcBufLen;
-	pTxD->LastSec0 = 0;
-	pTxD->LastSec1 = (bIsLast) ? 1 : 0;
-
-	RTMPWriteTxDescriptor(pAd, pTxD, FALSE, FIFO_EDCA);
-
-	RetTxIdx = TxIdx;
-	/* */
-	/* Update Tx index */
-	/* */
-	INC_RING_INDEX(TxIdx, TX_RING_SIZE);
-	pTxRing->TxCpuIdx = TxIdx;
-
-	*FreeNumber -= 1;
-
-	return RetTxIdx;
-
-}
-
-void RtmpPCI_FinalWriteTxResource(struct rt_rtmp_adapter *pAd,
-				  struct rt_tx_blk *pTxBlk,
-				  u16 totalMPDUSize, u16 FirstTxIdx)
-{
-
-	struct rt_txwi * pTxWI;
-	struct rt_rtmp_tx_ring *pTxRing;
-
-	/* */
-	/* get Tx Ring Resource */
-	/* */
-	pTxRing = &pAd->TxRing[pTxBlk->QueIdx];
-	pTxWI = (struct rt_txwi *) pTxRing->Cell[FirstTxIdx].DmaBuf.AllocVa;
-	pTxWI->MPDUtotalByteCount = totalMPDUSize;
-
-}
-
-void RtmpPCIDataLastTxIdx(struct rt_rtmp_adapter *pAd,
-			  u8 QueIdx, u16 LastTxIdx)
-{
-	struct rt_txd * pTxD;
-	struct rt_rtmp_tx_ring *pTxRing;
-
-	/* */
-	/* get Tx Ring Resource */
-	/* */
-	pTxRing = &pAd->TxRing[QueIdx];
-
-	/* */
-	/* build Tx Descriptor */
-	/* */
-	pTxD = (struct rt_txd *) pTxRing->Cell[LastTxIdx].AllocVa;
-
-	pTxD->LastSec1 = 1;
-
-}
-
-u16 RtmpPCI_WriteFragTxResource(struct rt_rtmp_adapter *pAd,
-				   struct rt_tx_blk *pTxBlk,
-				   u8 fragNum, u16 * FreeNumber)
-{
-	u8 *pDMAHeaderBufVA;
-	u16 TxIdx, RetTxIdx;
-	struct rt_txd * pTxD;
-	u32 BufBasePaLow;
-	struct rt_rtmp_tx_ring *pTxRing;
-	u16 hwHeaderLen;
-	u32 firstDMALen;
-
-	/* */
-	/* Get Tx Ring Resource */
-	/* */
-	pTxRing = &pAd->TxRing[pTxBlk->QueIdx];
-	TxIdx = pAd->TxRing[pTxBlk->QueIdx].TxCpuIdx;
-	pDMAHeaderBufVA = (u8 *)pTxRing->Cell[TxIdx].DmaBuf.AllocVa;
-	BufBasePaLow =
-	    RTMP_GetPhysicalAddressLow(pTxRing->Cell[TxIdx].DmaBuf.AllocPa);
-
-	/* */
-	/* Copy TXINFO + TXWI + WLAN Header + LLC into DMA Header Buffer */
-	/* */
-	/*hwHeaderLen = ROUND_UP(pTxBlk->MpduHeaderLen, 4); */
-	hwHeaderLen = pTxBlk->MpduHeaderLen + pTxBlk->HdrPadLen;
-
-	firstDMALen = TXINFO_SIZE + TXWI_SIZE + hwHeaderLen;
-	NdisMoveMemory(pDMAHeaderBufVA, pTxBlk->HeaderBuf, firstDMALen);
-
-	/* */
-	/* Build Tx Descriptor */
-	/* */
-	pTxD = (struct rt_txd *) pTxRing->Cell[TxIdx].AllocVa;
-	NdisZeroMemory(pTxD, TXD_SIZE);
-
-	if (fragNum == pTxBlk->TotalFragNum) {
-		pTxRing->Cell[TxIdx].pNdisPacket = pTxBlk->pPacket;
-		pTxRing->Cell[TxIdx].pNextNdisPacket = NULL;
-	}
-
-	pTxD->SDPtr0 = BufBasePaLow;
-	pTxD->SDLen0 = firstDMALen;	/* include padding */
-	pTxD->SDPtr1 = PCI_MAP_SINGLE(pAd, pTxBlk, 0, 1, PCI_DMA_TODEVICE);
-	pTxD->SDLen1 = pTxBlk->SrcBufLen;
-	pTxD->LastSec0 = 0;
-	pTxD->LastSec1 = 1;
-
-	RTMPWriteTxDescriptor(pAd, pTxD, FALSE, FIFO_EDCA);
-
-	RetTxIdx = TxIdx;
-	pTxBlk->Priv += pTxBlk->SrcBufLen;
-
-	/* */
-	/* Update Tx index */
-	/* */
-	INC_RING_INDEX(TxIdx, TX_RING_SIZE);
-	pTxRing->TxCpuIdx = TxIdx;
-
-	*FreeNumber -= 1;
-
-	return RetTxIdx;
-
-}
-
-/*
-	Must be run in Interrupt context
-	This function handle PCI specific TxDesc and cpu index update and kick the packet out.
- */
-int RtmpPCIMgmtKickOut(struct rt_rtmp_adapter *pAd,
-		       u8 QueIdx,
-		       void *pPacket,
-		       u8 *pSrcBufVA, u32 SrcBufLen)
-{
-	struct rt_txd * pTxD;
-	unsigned long SwIdx = pAd->MgmtRing.TxCpuIdx;
-
-	pTxD = (struct rt_txd *) pAd->MgmtRing.Cell[SwIdx].AllocVa;
-
-	pAd->MgmtRing.Cell[SwIdx].pNdisPacket = pPacket;
-	pAd->MgmtRing.Cell[SwIdx].pNextNdisPacket = NULL;
-
-	RTMPWriteTxDescriptor(pAd, pTxD, TRUE, FIFO_MGMT);
-	pTxD->LastSec0 = 1;
-	pTxD->LastSec1 = 1;
-	pTxD->DMADONE = 0;
-	pTxD->SDLen1 = 0;
-	pTxD->SDPtr0 =
-	    PCI_MAP_SINGLE(pAd, pSrcBufVA, SrcBufLen, 0, PCI_DMA_TODEVICE);
-	pTxD->SDLen0 = SrcBufLen;
-
-/*================================================================== */
-/*	DBGPRINT_RAW(RT_DEBUG_TRACE, ("MLMEHardTransmit\n"));
-	for (i = 0; i < (TXWI_SIZE+24); i++)
-	{
-
-		DBGPRINT_RAW(RT_DEBUG_TRACE, ("%x:", *(pSrcBufVA+i)));
-		if ( i%4 == 3)
-			DBGPRINT_RAW(RT_DEBUG_TRACE, (" :: "));
-		if ( i%16 == 15)
-			DBGPRINT_RAW(RT_DEBUG_TRACE, ("\n      "));
-	}
-	DBGPRINT_RAW(RT_DEBUG_TRACE, ("\n      "));*/
-/*======================================================================= */
-
-	pAd->RalinkCounters.KickTxCount++;
-	pAd->RalinkCounters.OneSecTxDoneCount++;
-
-	/* Increase TX_CTX_IDX, but write to register later. */
-	INC_RING_INDEX(pAd->MgmtRing.TxCpuIdx, MGMT_RING_SIZE);
-
-	RTMP_IO_WRITE32(pAd, TX_MGMTCTX_IDX, pAd->MgmtRing.TxCpuIdx);
-
-	return 0;
-}
-
-/*
-	========================================================================
-
-	Routine Description:
-		Check Rx descriptor, return NDIS_STATUS_FAILURE if any error dound
-
-	Arguments:
-		pRxD		Pointer to the Rx descriptor
-
-	Return Value:
-		NDIS_STATUS_SUCCESS	No err
-		NDIS_STATUS_FAILURE	Error
-
-	Note:
-
-	========================================================================
-*/
-int RTMPCheckRxError(struct rt_rtmp_adapter *pAd,
-			     struct rt_header_802_11 * pHeader,
-			     struct rt_rxwi * pRxWI, IN PRT28XX_RXD_STRUC pRxD)
-{
-	struct rt_cipher_key *pWpaKey;
-	int dBm;
-
-	/* Phy errors & CRC errors */
-	if ( /*(pRxD->PhyErr) || */ (pRxD->Crc)) {
-		/* Check RSSI for Noise Hist statistic collection. */
-		dBm = (int)(pRxWI->RSSI0) - pAd->BbpRssiToDbmDelta;
-		if (dBm <= -87)
-			pAd->StaCfg.RPIDensity[0] += 1;
-		else if (dBm <= -82)
-			pAd->StaCfg.RPIDensity[1] += 1;
-		else if (dBm <= -77)
-			pAd->StaCfg.RPIDensity[2] += 1;
-		else if (dBm <= -72)
-			pAd->StaCfg.RPIDensity[3] += 1;
-		else if (dBm <= -67)
-			pAd->StaCfg.RPIDensity[4] += 1;
-		else if (dBm <= -62)
-			pAd->StaCfg.RPIDensity[5] += 1;
-		else if (dBm <= -57)
-			pAd->StaCfg.RPIDensity[6] += 1;
-		else if (dBm > -57)
-			pAd->StaCfg.RPIDensity[7] += 1;
-
-		return (NDIS_STATUS_FAILURE);
-	}
-	/* Add Rx size to channel load counter, we should ignore error counts */
-	pAd->StaCfg.CLBusyBytes += (pRxD->SDL0 + 14);
-
-	/* Drop ToDs promiscuous frame, it is opened due to CCX 2 channel load statistics */
-	if (pHeader != NULL) {
-		if (pHeader->FC.ToDs) {
-			return (NDIS_STATUS_FAILURE);
-		}
-	}
-	/* Drop not U2M frames, can't drop here because we will drop beacon in this case */
-	/* I am kind of doubting the U2M bit operation */
-	/* if (pRxD->U2M == 0) */
-	/*      return(NDIS_STATUS_FAILURE); */
-
-	/* drop decyption fail frame */
-	if (pRxD->CipherErr) {
-		if (pRxD->CipherErr == 2) {
-			DBGPRINT_RAW(RT_DEBUG_TRACE,
-				     ("pRxD ERROR: ICV ok but MICErr "));
-		} else if (pRxD->CipherErr == 1) {
-			DBGPRINT_RAW(RT_DEBUG_TRACE, ("pRxD ERROR: ICV Err "));
-		} else if (pRxD->CipherErr == 3)
-			DBGPRINT_RAW(RT_DEBUG_TRACE,
-				     ("pRxD ERROR: Key not valid "));
-
-		if (((pRxD->CipherErr & 1) == 1)
-		    && pAd->CommonCfg.bWirelessEvent && INFRA_ON(pAd))
-			RTMPSendWirelessEvent(pAd, IW_ICV_ERROR_EVENT_FLAG,
-					      pAd->MacTab.Content[BSSID_WCID].
-					      Addr, BSS0, 0);
-
-		DBGPRINT_RAW(RT_DEBUG_TRACE,
-			     (" %d (len=%d, Mcast=%d, MyBss=%d, Wcid=%d, KeyId=%d)\n",
-			      pRxD->CipherErr, pRxD->SDL0,
-			      pRxD->Mcast | pRxD->Bcast, pRxD->MyBss,
-			      pRxWI->WirelessCliID,
-/*                      CipherName[pRxD->CipherAlg], */
-			      pRxWI->KeyIndex));
-
-		/* */
-		/* MIC Error */
-		/* */
-		if (pRxD->CipherErr == 2) {
-			pWpaKey = &pAd->SharedKey[BSS0][pRxWI->KeyIndex];
-			if (pAd->StaCfg.WpaSupplicantUP)
-				WpaSendMicFailureToWpaSupplicant(pAd,
-								 (pWpaKey->
-								  Type ==
-								  PAIRWISEKEY) ?
-								 TRUE : FALSE);
-			else
-				RTMPReportMicError(pAd, pWpaKey);
-
-			if (((pRxD->CipherErr & 2) == 2)
-			    && pAd->CommonCfg.bWirelessEvent && INFRA_ON(pAd))
-				RTMPSendWirelessEvent(pAd,
-						      IW_MIC_ERROR_EVENT_FLAG,
-						      pAd->MacTab.
-						      Content[BSSID_WCID].Addr,
-						      BSS0, 0);
-
-			DBGPRINT_RAW(RT_DEBUG_ERROR, ("Rx MIC Value error\n"));
-		}
-
-		if (pHeader == NULL)
-			return (NDIS_STATUS_SUCCESS);
-		/*if ((pRxD->CipherAlg == CIPHER_AES) &&
-		   (pHeader->Sequence == pAd->FragFrame.Sequence))
-		   {
-		   //
-		   // Acceptable since the First FragFrame no CipherErr problem.
-		   //
-		   return(NDIS_STATUS_SUCCESS);
-		   } */
-
-		return (NDIS_STATUS_FAILURE);
-	}
-
-	return (NDIS_STATUS_SUCCESS);
-}
-
-BOOLEAN RTMPFreeTXDUponTxDmaDone(struct rt_rtmp_adapter *pAd, u8 QueIdx)
-{
-	struct rt_rtmp_tx_ring *pTxRing;
-	struct rt_txd * pTxD;
-	void *pPacket;
-	u8 FREE = 0;
-	struct rt_txd TxD, *pOriTxD;
-	/*unsigned long         IrqFlags; */
-	BOOLEAN bReschedule = FALSE;
-
-	ASSERT(QueIdx < NUM_OF_TX_RING);
-	pTxRing = &pAd->TxRing[QueIdx];
-
-	RTMP_IO_READ32(pAd, TX_DTX_IDX0 + QueIdx * RINGREG_DIFF,
-		       &pTxRing->TxDmaIdx);
-	while (pTxRing->TxSwFreeIdx != pTxRing->TxDmaIdx) {
-/*              RTMP_IRQ_LOCK(&pAd->irq_lock, IrqFlags); */
-
-		/* static rate also need NICUpdateFifoStaCounters() function. */
-		/*if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED)) */
-		NICUpdateFifoStaCounters(pAd);
-
-		/* Note : If (pAd->ate.bQATxStart == TRUE), we will never reach here. */
-		FREE++;
-		pTxD =
-		    (struct rt_txd *) (pTxRing->Cell[pTxRing->TxSwFreeIdx].AllocVa);
-		pOriTxD = pTxD;
-		NdisMoveMemory(&TxD, pTxD, sizeof(struct rt_txd));
-		pTxD = &TxD;
-
-		pTxD->DMADONE = 0;
-
-		{
-			pPacket =
-			    pTxRing->Cell[pTxRing->TxSwFreeIdx].pNdisPacket;
-			if (pPacket) {
-				PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr1,
-						 pTxD->SDLen1,
-						 PCI_DMA_TODEVICE);
-				RELEASE_NDIS_PACKET(pAd, pPacket,
-						    NDIS_STATUS_SUCCESS);
-			}
-			/*Always assign pNdisPacket as NULL after clear */
-			pTxRing->Cell[pTxRing->TxSwFreeIdx].pNdisPacket = NULL;
-
-			pPacket =
-			    pTxRing->Cell[pTxRing->TxSwFreeIdx].pNextNdisPacket;
-
-			ASSERT(pPacket == NULL);
-			if (pPacket) {
-				PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr1,
-						 pTxD->SDLen1,
-						 PCI_DMA_TODEVICE);
-				RELEASE_NDIS_PACKET(pAd, pPacket,
-						    NDIS_STATUS_SUCCESS);
-			}
-			/*Always assign pNextNdisPacket as NULL after clear */
-			pTxRing->Cell[pTxRing->TxSwFreeIdx].pNextNdisPacket =
-			    NULL;
-		}
-
-		pAd->RalinkCounters.TransmittedByteCount +=
-		    (pTxD->SDLen1 + pTxD->SDLen0);
-		pAd->RalinkCounters.OneSecDmaDoneCount[QueIdx]++;
-		INC_RING_INDEX(pTxRing->TxSwFreeIdx, TX_RING_SIZE);
-		/* get tx_tdx_idx again */
-		RTMP_IO_READ32(pAd, TX_DTX_IDX0 + QueIdx * RINGREG_DIFF,
-			       &pTxRing->TxDmaIdx);
-		NdisMoveMemory(pOriTxD, pTxD, sizeof(struct rt_txd));
-
-/*         RTMP_IRQ_UNLOCK(&pAd->irq_lock, IrqFlags); */
-	}
-
-	return bReschedule;
-
-}
-
-/*
-	========================================================================
-
-	Routine Description:
-		Process TX Rings DMA Done interrupt, running in DPC level
-
-	Arguments:
-		Adapter		Pointer to our adapter
-
-	Return Value:
-		None
-
-	IRQL = DISPATCH_LEVEL
-
-	========================================================================
-*/
-BOOLEAN RTMPHandleTxRingDmaDoneInterrupt(struct rt_rtmp_adapter *pAd,
-					 INT_SOURCE_CSR_STRUC TxRingBitmap)
-{
-/*      u8                   Count = 0; */
-	unsigned long IrqFlags;
-	BOOLEAN bReschedule = FALSE;
-
-	/* Make sure Tx ring resource won't be used by other threads */
-	/*NdisAcquireSpinLock(&pAd->TxRingLock); */
-
-	RTMP_IRQ_LOCK(&pAd->irq_lock, IrqFlags);
-
-	if (TxRingBitmap.field.Ac0DmaDone)
-		bReschedule = RTMPFreeTXDUponTxDmaDone(pAd, QID_AC_BE);
-
-	if (TxRingBitmap.field.Ac3DmaDone)
-		bReschedule |= RTMPFreeTXDUponTxDmaDone(pAd, QID_AC_VO);
-
-	if (TxRingBitmap.field.Ac2DmaDone)
-		bReschedule |= RTMPFreeTXDUponTxDmaDone(pAd, QID_AC_VI);
-
-	if (TxRingBitmap.field.Ac1DmaDone)
-		bReschedule |= RTMPFreeTXDUponTxDmaDone(pAd, QID_AC_BK);
-
-	/* Make sure to release Tx ring resource */
-	/*NdisReleaseSpinLock(&pAd->TxRingLock); */
-	RTMP_IRQ_UNLOCK(&pAd->irq_lock, IrqFlags);
-
-	/* Dequeue outgoing frames from TxSwQueue[] and process it */
-	RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, MAX_TX_PROCESS);
-
-	return bReschedule;
-}
-
-/*
-	========================================================================
-
-	Routine Description:
-		Process MGMT ring DMA done interrupt, running in DPC level
-
-	Arguments:
-		pAd	Pointer to our adapter
-
-	Return Value:
-		None
-
-	IRQL = DISPATCH_LEVEL
-
-	Note:
-
-	========================================================================
-*/
-void RTMPHandleMgmtRingDmaDoneInterrupt(struct rt_rtmp_adapter *pAd)
-{
-	struct rt_txd * pTxD;
-	void *pPacket;
-/*      int              i; */
-	u8 FREE = 0;
-	struct rt_rtmp_mgmt_ring *pMgmtRing = &pAd->MgmtRing;
-
-	NdisAcquireSpinLock(&pAd->MgmtRingLock);
-
-	RTMP_IO_READ32(pAd, TX_MGMTDTX_IDX, &pMgmtRing->TxDmaIdx);
-	while (pMgmtRing->TxSwFreeIdx != pMgmtRing->TxDmaIdx) {
-		FREE++;
-		pTxD =
-		    (struct rt_txd *) (pMgmtRing->Cell[pAd->MgmtRing.TxSwFreeIdx].
-				  AllocVa);
-		pTxD->DMADONE = 0;
-		pPacket = pMgmtRing->Cell[pMgmtRing->TxSwFreeIdx].pNdisPacket;
-
-		if (pPacket) {
-			PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr0, pTxD->SDLen0,
-					 PCI_DMA_TODEVICE);
-			RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_SUCCESS);
-		}
-		pMgmtRing->Cell[pMgmtRing->TxSwFreeIdx].pNdisPacket = NULL;
-
-		pPacket =
-		    pMgmtRing->Cell[pMgmtRing->TxSwFreeIdx].pNextNdisPacket;
-		if (pPacket) {
-			PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr1, pTxD->SDLen1,
-					 PCI_DMA_TODEVICE);
-			RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_SUCCESS);
-		}
-		pMgmtRing->Cell[pMgmtRing->TxSwFreeIdx].pNextNdisPacket = NULL;
-		INC_RING_INDEX(pMgmtRing->TxSwFreeIdx, MGMT_RING_SIZE);
-
-	}
-	NdisReleaseSpinLock(&pAd->MgmtRingLock);
-
-}
-
-/*
-	========================================================================
-
-	Routine Description:
-	Arguments:
-		Adapter		Pointer to our adapter. Dequeue all power safe delayed braodcast frames after beacon.
-
-	IRQL = DISPATCH_LEVEL
-
-	========================================================================
-*/
-void RTMPHandleTBTTInterrupt(struct rt_rtmp_adapter *pAd)
-{
-	{
-		if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE)) {
-		}
-	}
-}
-
-/*
-	========================================================================
-
-	Routine Description:
-	Arguments:
-		pAd		Pointer to our adapter. Rewrite beacon content before next send-out.
-
-	IRQL = DISPATCH_LEVEL
-
-	========================================================================
-*/
-void RTMPHandlePreTBTTInterrupt(struct rt_rtmp_adapter *pAd)
-{
-	{
-		if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE)) {
-			DBGPRINT(RT_DEBUG_TRACE,
-				 ("RTMPHandlePreTBTTInterrupt...\n"));
-		}
-	}
-
-}
-
-void RTMPHandleRxCoherentInterrupt(struct rt_rtmp_adapter *pAd)
-{
-	WPDMA_GLO_CFG_STRUC GloCfg;
-
-	if (pAd == NULL) {
-		DBGPRINT(RT_DEBUG_TRACE, ("====> pAd is NULL, return.\n"));
-		return;
-	}
-
-	DBGPRINT(RT_DEBUG_TRACE, ("==> RTMPHandleRxCoherentInterrupt \n"));
-
-	RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &GloCfg.word);
-
-	GloCfg.field.EnTXWriteBackDDONE = 0;
-	GloCfg.field.EnableRxDMA = 0;
-	GloCfg.field.EnableTxDMA = 0;
-	RTMP_IO_WRITE32(pAd, WPDMA_GLO_CFG, GloCfg.word);
-
-	RTMPRingCleanUp(pAd, QID_AC_BE);
-	RTMPRingCleanUp(pAd, QID_AC_BK);
-	RTMPRingCleanUp(pAd, QID_AC_VI);
-	RTMPRingCleanUp(pAd, QID_AC_VO);
-	RTMPRingCleanUp(pAd, QID_MGMT);
-	RTMPRingCleanUp(pAd, QID_RX);
-
-	RTMPEnableRxTx(pAd);
-
-	DBGPRINT(RT_DEBUG_TRACE, ("<== RTMPHandleRxCoherentInterrupt \n"));
-}
-
-void *GetPacketFromRxRing(struct rt_rtmp_adapter *pAd,
-				 OUT PRT28XX_RXD_STRUC pSaveRxD,
-				 OUT BOOLEAN * pbReschedule,
-				 IN u32 * pRxPending)
-{
-	struct rt_rxd * pRxD;
-	void *pRxPacket = NULL;
-	void *pNewPacket;
-	void *AllocVa;
-	dma_addr_t AllocPa;
-	BOOLEAN bReschedule = FALSE;
-	struct rt_rtmp_dmacb *pRxCell;
-
-	RTMP_SEM_LOCK(&pAd->RxRingLock);
-
-	if (*pRxPending == 0) {
-		/* Get how may packets had been received */
-		RTMP_IO_READ32(pAd, RX_DRX_IDX, &pAd->RxRing.RxDmaIdx);
-
-		if (pAd->RxRing.RxSwReadIdx == pAd->RxRing.RxDmaIdx) {
-			/* no more rx packets */
-			bReschedule = FALSE;
-			goto done;
-		}
-		/* get rx pending count */
-		if (pAd->RxRing.RxDmaIdx > pAd->RxRing.RxSwReadIdx)
-			*pRxPending =
-			    pAd->RxRing.RxDmaIdx - pAd->RxRing.RxSwReadIdx;
-		else
-			*pRxPending =
-			    pAd->RxRing.RxDmaIdx + RX_RING_SIZE -
-			    pAd->RxRing.RxSwReadIdx;
-
-	}
-
-	pRxCell = &pAd->RxRing.Cell[pAd->RxRing.RxSwReadIdx];
-
-	/* Point to Rx indexed rx ring descriptor */
-	pRxD = (struct rt_rxd *) pRxCell->AllocVa;
-
-	if (pRxD->DDONE == 0) {
-		*pRxPending = 0;
-		/* DMAIndx had done but DDONE bit not ready */
-		bReschedule = TRUE;
-		goto done;
-	}
-
-	/* return rx descriptor */
-	NdisMoveMemory(pSaveRxD, pRxD, RXD_SIZE);
-
-	pNewPacket =
-	    RTMP_AllocateRxPacketBuffer(pAd, RX_BUFFER_AGGRESIZE, FALSE,
-					&AllocVa, &AllocPa);
-
-	if (pNewPacket) {
-		/* unmap the rx buffer */
-		PCI_UNMAP_SINGLE(pAd, pRxCell->DmaBuf.AllocPa,
-				 pRxCell->DmaBuf.AllocSize, PCI_DMA_FROMDEVICE);
-		pRxPacket = pRxCell->pNdisPacket;
-
-		pRxCell->DmaBuf.AllocSize = RX_BUFFER_AGGRESIZE;
-		pRxCell->pNdisPacket = (void *)pNewPacket;
-		pRxCell->DmaBuf.AllocVa = AllocVa;
-		pRxCell->DmaBuf.AllocPa = AllocPa;
-		/* update SDP0 to new buffer of rx packet */
-		pRxD->SDP0 = AllocPa;
-	} else {
-		/*DBGPRINT(RT_DEBUG_TRACE,("No Rx Buffer\n")); */
-		pRxPacket = NULL;
-		bReschedule = TRUE;
-	}
-
-	pRxD->DDONE = 0;
-
-	/* had handled one rx packet */
-	*pRxPending = *pRxPending - 1;
-
-	/* update rx descriptor and kick rx */
-	INC_RING_INDEX(pAd->RxRing.RxSwReadIdx, RX_RING_SIZE);
-
-	pAd->RxRing.RxCpuIdx =
-	    (pAd->RxRing.RxSwReadIdx ==
-	     0) ? (RX_RING_SIZE - 1) : (pAd->RxRing.RxSwReadIdx - 1);
-	RTMP_IO_WRITE32(pAd, RX_CRX_IDX, pAd->RxRing.RxCpuIdx);
-
-done:
-	RTMP_SEM_UNLOCK(&pAd->RxRingLock);
-	*pbReschedule = bReschedule;
-	return pRxPacket;
-}
-
-int MlmeHardTransmitTxRing(struct rt_rtmp_adapter *pAd,
-				   u8 QueIdx, void *pPacket)
-{
-	struct rt_packet_info PacketInfo;
-	u8 *pSrcBufVA;
-	u32 SrcBufLen;
-	struct rt_txd * pTxD;
-	struct rt_header_802_11 * pHeader_802_11;
-	BOOLEAN bAckRequired, bInsertTimestamp;
-	unsigned long SrcBufPA;
-	/*u8                 TxBufIdx; */
-	u8 MlmeRate;
-	unsigned long SwIdx = pAd->TxRing[QueIdx].TxCpuIdx;
-	struct rt_txwi * pFirstTxWI;
-	/*unsigned long i; */
-	/*HTTRANSMIT_SETTING    MlmeTransmit;   //Rate for this MGMT frame. */
-	unsigned long FreeNum;
-	struct rt_mac_table_entry *pMacEntry = NULL;
-
-	RTMP_QueryPacketInfo(pPacket, &PacketInfo, &pSrcBufVA, &SrcBufLen);
-
-	if (pSrcBufVA == NULL) {
-		/* The buffer shouldn't be NULL */
-		return NDIS_STATUS_FAILURE;
-	}
-	/* Make sure MGMT ring resource won't be used by other threads */
-	/*NdisAcquireSpinLock(&pAd->TxRingLock); */
-
-	FreeNum = GET_TXRING_FREENO(pAd, QueIdx);
-
-	if (FreeNum == 0) {
-		/*NdisReleaseSpinLock(&pAd->TxRingLock); */
-		return NDIS_STATUS_FAILURE;
-	}
-
-	SwIdx = pAd->TxRing[QueIdx].TxCpuIdx;
-
-	pTxD = (struct rt_txd *) pAd->TxRing[QueIdx].Cell[SwIdx].AllocVa;
-
-	if (pAd->TxRing[QueIdx].Cell[SwIdx].pNdisPacket) {
-		DBGPRINT(RT_DEBUG_OFF, ("MlmeHardTransmit Error\n"));
-		/*NdisReleaseSpinLock(&pAd->TxRingLock); */
-		return NDIS_STATUS_FAILURE;
-	}
-
-	{
-		/* outgoing frame always wakeup PHY to prevent frame lost */
-		/* if (pAd->StaCfg.Psm == PWR_SAVE) */
-		if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
-			AsicForceWakeup(pAd, TRUE);
-	}
-	pFirstTxWI = (struct rt_txwi *) pSrcBufVA;
-
-	pHeader_802_11 = (struct rt_header_802_11 *) (pSrcBufVA + TXWI_SIZE);
-	if (pHeader_802_11->Addr1[0] & 0x01) {
-		MlmeRate = pAd->CommonCfg.BasicMlmeRate;
-	} else {
-		MlmeRate = pAd->CommonCfg.MlmeRate;
-	}
-
-	if ((pHeader_802_11->FC.Type == BTYPE_DATA) &&
-	    (pHeader_802_11->FC.SubType == SUBTYPE_QOS_NULL)) {
-		pMacEntry = MacTableLookup(pAd, pHeader_802_11->Addr1);
-	}
-	/* Verify Mlme rate for a / g bands. */
-	if ((pAd->LatchRfRegs.Channel > 14) && (MlmeRate < RATE_6))	/* 11A band */
-		MlmeRate = RATE_6;
-
-	/* */
-	/* Should not be hard code to set PwrMgmt to 0 (PWR_ACTIVE) */
-	/* Snice it's been set to 0 while on MgtMacHeaderInit */
-	/* By the way this will cause frame to be send on PWR_SAVE failed. */
-	/* */
-	/* */
-	/* In WMM-UAPSD, mlme frame should be set psm as power saving but probe request frame */
-	/* Data-Null packets also pass through MMRequest in RT2860, however, we hope control the psm bit to pass APSD */
-	if (pHeader_802_11->FC.Type != BTYPE_DATA) {
-		if ((pHeader_802_11->FC.SubType == SUBTYPE_PROBE_REQ)
-		    || !(pAd->CommonCfg.bAPSDCapable
-			 && pAd->CommonCfg.APEdcaParm.bAPSDCapable)) {
-			pHeader_802_11->FC.PwrMgmt = PWR_ACTIVE;
-		} else {
-			pHeader_802_11->FC.PwrMgmt =
-			    pAd->CommonCfg.bAPSDForcePowerSave;
-		}
-	}
-
-	bInsertTimestamp = FALSE;
-	if (pHeader_802_11->FC.Type == BTYPE_CNTL)	/* must be PS-POLL */
-	{
-		bAckRequired = FALSE;
-	} else			/* BTYPE_MGMT or BTYPE_DATA(must be NULL frame) */
-	{
-		if (pHeader_802_11->Addr1[0] & 0x01)	/* MULTICAST, BROADCAST */
-		{
-			bAckRequired = FALSE;
-			pHeader_802_11->Duration = 0;
-		} else {
-			bAckRequired = TRUE;
-			pHeader_802_11->Duration =
-			    RTMPCalcDuration(pAd, MlmeRate, 14);
-			if (pHeader_802_11->FC.SubType == SUBTYPE_PROBE_RSP) {
-				bInsertTimestamp = TRUE;
-			}
-		}
-	}
-	pHeader_802_11->Sequence = pAd->Sequence++;
-	if (pAd->Sequence > 0xfff)
-		pAd->Sequence = 0;
-	/* Before radar detection done, mgmt frame can not be sent but probe req */
-	/* Because we need to use probe req to trigger driver to send probe req in passive scan */
-	if ((pHeader_802_11->FC.SubType != SUBTYPE_PROBE_REQ)
-	    && (pAd->CommonCfg.bIEEE80211H == 1)
-	    && (pAd->CommonCfg.RadarDetect.RDMode != RD_NORMAL_MODE)) {
-		DBGPRINT(RT_DEBUG_ERROR,
-			 ("MlmeHardTransmit --> radar detect not in normal mode!\n"));
-		/*NdisReleaseSpinLock(&pAd->TxRingLock); */
-		return (NDIS_STATUS_FAILURE);
-	}
-	/* */
-	/* fill scatter-and-gather buffer list into TXD. Internally created NDIS PACKET */
-	/* should always has only one ohysical buffer, and the whole frame size equals */
-	/* to the first scatter buffer size */
-	/* */
-
-	/* Initialize TX Descriptor */
-	/* For inter-frame gap, the number is for this frame and next frame */
-	/* For MLME rate, we will fix as 2Mb to match other vendor's implement */
-/*      pAd->CommonCfg.MlmeTransmit.field.MODE = 1; */
-
-/* management frame doesn't need encryption. so use RESERVED_WCID no matter u are sending to specific wcid or not. */
-	/* Only beacon use Nseq=TRUE. So here we use Nseq=FALSE. */
-	if (pMacEntry == NULL) {
-		RTMPWriteTxWI(pAd, pFirstTxWI, FALSE, FALSE, bInsertTimestamp,
-			      FALSE, bAckRequired, FALSE, 0, RESERVED_WCID,
-			      (SrcBufLen - TXWI_SIZE), PID_MGMT, 0,
-			      (u8)pAd->CommonCfg.MlmeTransmit.field.MCS,
-			      IFS_BACKOFF, FALSE, &pAd->CommonCfg.MlmeTransmit);
-	} else {
-		RTMPWriteTxWI(pAd, pFirstTxWI, FALSE, FALSE,
-			      bInsertTimestamp, FALSE, bAckRequired, FALSE,
-			      0, pMacEntry->Aid, (SrcBufLen - TXWI_SIZE),
-			      pMacEntry->MaxHTPhyMode.field.MCS, 0,
-			      (u8)pMacEntry->MaxHTPhyMode.field.MCS,
-			      IFS_BACKOFF, FALSE, &pMacEntry->MaxHTPhyMode);
-	}
-
-	pAd->TxRing[QueIdx].Cell[SwIdx].pNdisPacket = pPacket;
-	pAd->TxRing[QueIdx].Cell[SwIdx].pNextNdisPacket = NULL;
-/*      pFirstTxWI->MPDUtotalByteCount = SrcBufLen - TXWI_SIZE; */
-	SrcBufPA =
-	    PCI_MAP_SINGLE(pAd, pSrcBufVA, SrcBufLen, 0, PCI_DMA_TODEVICE);
-
-	RTMPWriteTxDescriptor(pAd, pTxD, TRUE, FIFO_EDCA);
-	pTxD->LastSec0 = 1;
-	pTxD->LastSec1 = 1;
-	pTxD->SDLen0 = SrcBufLen;
-	pTxD->SDLen1 = 0;
-	pTxD->SDPtr0 = SrcBufPA;
-	pTxD->DMADONE = 0;
-
-	pAd->RalinkCounters.KickTxCount++;
-	pAd->RalinkCounters.OneSecTxDoneCount++;
-
-	/* Increase TX_CTX_IDX, but write to register later. */
-	INC_RING_INDEX(pAd->TxRing[QueIdx].TxCpuIdx, TX_RING_SIZE);
-
-	RTMP_IO_WRITE32(pAd, TX_CTX_IDX0 + QueIdx * 0x10,
-			pAd->TxRing[QueIdx].TxCpuIdx);
-
-	/* Make sure to release MGMT ring resource */
-/*      NdisReleaseSpinLock(&pAd->TxRingLock); */
-
-	return NDIS_STATUS_SUCCESS;
-}
-
-int MlmeDataHardTransmit(struct rt_rtmp_adapter *pAd,
-				 u8 QueIdx, void *pPacket)
-{
-	if ((pAd->CommonCfg.RadarDetect.RDMode != RD_NORMAL_MODE)
-	    ) {
-		return NDIS_STATUS_FAILURE;
-	}
-
-	return MlmeHardTransmitTxRing(pAd, QueIdx, pPacket);
-}
-
-/*
-	========================================================================
-
-	Routine Description:
-		Calculates the duration which is required to transmit out frames
-	with given size and specified rate.
-
-	Arguments:
-		pTxD		Pointer to transmit descriptor
-		Ack		Setting for Ack requirement bit
-		Fragment	Setting for Fragment bit
-		RetryMode	Setting for retry mode
-		Ifs		Setting for IFS gap
-		Rate		Setting for transmit rate
-		Service		Setting for service
-		Length		Frame length
-		TxPreamble	Short or Long preamble when using CCK rates
-		QueIdx - 0-3, according to 802.11e/d4.4 June/2003
-
-	Return Value:
-		None
-
-	IRQL = PASSIVE_LEVEL
-	IRQL = DISPATCH_LEVEL
-
-	========================================================================
-*/
-void RTMPWriteTxDescriptor(struct rt_rtmp_adapter *pAd,
-			   struct rt_txd * pTxD,
-			   IN BOOLEAN bWIV, u8 QueueSEL)
-{
-	/* */
-	/* Always use Long preamble before verifiation short preamble functionality works well. */
-	/* Todo: remove the following line if short preamble functionality works */
-	/* */
-	OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_SHORT_PREAMBLE_INUSED);
-
-	pTxD->WIV = (bWIV) ? 1 : 0;
-	pTxD->QSEL = (QueueSEL);
-	/*RT2860c??  fixed using EDCA queue for test...  We doubt Queue1 has problem.  2006-09-26 Jan */
-	/*pTxD->QSEL= FIFO_EDCA; */
-	pTxD->DMADONE = 0;
-}
diff -druN linux-2.6.39-libre/drivers/staging/rt2860/common/cmm_data_usb.c linux-3.0-rc7-libre/drivers/staging/rt2860/common/cmm_data_usb.c
--- linux-2.6.39-libre/drivers/staging/rt2860/common/cmm_data_usb.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rt2860/common/cmm_data_usb.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,951 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, 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.             *
- *                                                                       *
- *************************************************************************
-*/
-
-/*
-   All functions in this file must be USB-depended, or you should out your function
-	in other files.
-
-*/
-
-#ifdef RTMP_MAC_USB
-
-#include	"../rt_config.h"
-
-/*
-	We can do copy the frame into pTxContext when match following conditions.
-		=>
-		=>
-		=>
-*/
-static inline int RtmpUSBCanDoWrite(struct rt_rtmp_adapter *pAd,
-					    u8 QueIdx,
-					    struct rt_ht_tx_context *pHTTXContext)
-{
-	int canWrite = NDIS_STATUS_RESOURCES;
-
-	if (((pHTTXContext->CurWritePosition) <
-	     pHTTXContext->NextBulkOutPosition)
-	    && (pHTTXContext->CurWritePosition + LOCAL_TXBUF_SIZE) >
-	    pHTTXContext->NextBulkOutPosition) {
-		DBGPRINT(RT_DEBUG_ERROR, ("RtmpUSBCanDoWrite c1!\n"));
-		RTUSB_SET_BULK_FLAG(pAd,
-				    (fRTUSB_BULK_OUT_DATA_NORMAL << QueIdx));
-	} else if ((pHTTXContext->CurWritePosition == 8)
-		   && (pHTTXContext->NextBulkOutPosition < LOCAL_TXBUF_SIZE)) {
-		DBGPRINT(RT_DEBUG_ERROR, ("RtmpUSBCanDoWrite c2!\n"));
-		RTUSB_SET_BULK_FLAG(pAd,
-				    (fRTUSB_BULK_OUT_DATA_NORMAL << QueIdx));
-	} else if (pHTTXContext->bCurWriting == TRUE) {
-		DBGPRINT(RT_DEBUG_ERROR, ("RtmpUSBCanDoWrite c3!\n"));
-	} else {
-		canWrite = NDIS_STATUS_SUCCESS;
-	}
-
-	return canWrite;
-}
-
-u16 RtmpUSB_WriteSubTxResource(struct rt_rtmp_adapter *pAd,
-				  struct rt_tx_blk *pTxBlk,
-				  IN BOOLEAN bIsLast, u16 * FreeNumber)
-{
-
-	/* Dummy function. Should be removed in the future. */
-	return 0;
-
-}
-
-u16 RtmpUSB_WriteFragTxResource(struct rt_rtmp_adapter *pAd,
-				   struct rt_tx_blk *pTxBlk,
-				   u8 fragNum, u16 * FreeNumber)
-{
-	struct rt_ht_tx_context *pHTTXContext;
-	u16 hwHdrLen;	/* The hwHdrLen consist of 802.11 header length plus the header padding length. */
-	u32 fillOffset;
-	struct rt_txinfo *pTxInfo;
-	struct rt_txwi *pTxWI;
-	u8 *pWirelessPacket = NULL;
-	u8 QueIdx;
-	int Status;
-	unsigned long IrqFlags;
-	u32 USBDMApktLen = 0, DMAHdrLen, padding;
-	BOOLEAN TxQLastRound = FALSE;
-
-	/* */
-	/* get Tx Ring Resource & Dma Buffer address */
-	/* */
-	QueIdx = pTxBlk->QueIdx;
-	pHTTXContext = &pAd->TxContext[QueIdx];
-
-	RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
-
-	pHTTXContext = &pAd->TxContext[QueIdx];
-	fillOffset = pHTTXContext->CurWritePosition;
-
-	if (fragNum == 0) {
-		/* Check if we have enough space for this bulk-out batch. */
-		Status = RtmpUSBCanDoWrite(pAd, QueIdx, pHTTXContext);
-		if (Status == NDIS_STATUS_SUCCESS) {
-			pHTTXContext->bCurWriting = TRUE;
-
-			/* Reserve space for 8 bytes padding. */
-			if ((pHTTXContext->ENextBulkOutPosition ==
-			     pHTTXContext->CurWritePosition)) {
-				pHTTXContext->ENextBulkOutPosition += 8;
-				pHTTXContext->CurWritePosition += 8;
-				fillOffset += 8;
-			}
-			pTxBlk->Priv = 0;
-			pHTTXContext->CurWriteRealPos =
-			    pHTTXContext->CurWritePosition;
-		} else {
-			RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[QueIdx],
-					IrqFlags);
-
-			RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket,
-					    NDIS_STATUS_FAILURE);
-			return (Status);
-		}
-	} else {
-		/* For sub-sequent frames of this bulk-out batch. Just copy it to our bulk-out buffer. */
-		Status =
-		    ((pHTTXContext->bCurWriting ==
-		      TRUE) ? NDIS_STATUS_SUCCESS : NDIS_STATUS_FAILURE);
-		if (Status == NDIS_STATUS_SUCCESS) {
-			fillOffset += pTxBlk->Priv;
-		} else {
-			RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[QueIdx],
-					IrqFlags);
-
-			RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket,
-					    NDIS_STATUS_FAILURE);
-			return (Status);
-		}
-	}
-
-	NdisZeroMemory((u8 *)(&pTxBlk->HeaderBuf[0]), TXINFO_SIZE);
-	pTxInfo = (struct rt_txinfo *)(&pTxBlk->HeaderBuf[0]);
-	pTxWI = (struct rt_txwi *) (&pTxBlk->HeaderBuf[TXINFO_SIZE]);
-
-	pWirelessPacket =
-	    &pHTTXContext->TransferBuffer->field.WirelessPacket[fillOffset];
-
-	/* copy TXWI + WLAN Header + LLC into DMA Header Buffer */
-	/*hwHdrLen = ROUND_UP(pTxBlk->MpduHeaderLen, 4); */
-	hwHdrLen = pTxBlk->MpduHeaderLen + pTxBlk->HdrPadLen;
-
-	/* Build our URB for USBD */
-	DMAHdrLen = TXWI_SIZE + hwHdrLen;
-	USBDMApktLen = DMAHdrLen + pTxBlk->SrcBufLen;
-	padding = (4 - (USBDMApktLen % 4)) & 0x03;	/* round up to 4 byte alignment */
-	USBDMApktLen += padding;
-
-	pTxBlk->Priv += (TXINFO_SIZE + USBDMApktLen);
-
-	/* For TxInfo, the length of USBDMApktLen = TXWI_SIZE + 802.11 header + payload */
-	RTMPWriteTxInfo(pAd, pTxInfo, (u16)(USBDMApktLen), FALSE, FIFO_EDCA,
-			FALSE /*NextValid */ , FALSE);
-
-	if (fragNum == pTxBlk->TotalFragNum) {
-		pTxInfo->USBDMATxburst = 0;
-		if ((pHTTXContext->CurWritePosition + pTxBlk->Priv + 3906) >
-		    MAX_TXBULK_LIMIT) {
-			pTxInfo->SwUseLastRound = 1;
-			TxQLastRound = TRUE;
-		}
-	} else {
-		pTxInfo->USBDMATxburst = 1;
-	}
-
-	NdisMoveMemory(pWirelessPacket, pTxBlk->HeaderBuf,
-		       TXINFO_SIZE + TXWI_SIZE + hwHdrLen);
-	pWirelessPacket += (TXINFO_SIZE + TXWI_SIZE + hwHdrLen);
-	pHTTXContext->CurWriteRealPos += (TXINFO_SIZE + TXWI_SIZE + hwHdrLen);
-
-	RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
-
-	NdisMoveMemory(pWirelessPacket, pTxBlk->pSrcBufData, pTxBlk->SrcBufLen);
-
-	/*      Zero the last padding. */
-	pWirelessPacket += pTxBlk->SrcBufLen;
-	NdisZeroMemory(pWirelessPacket, padding + 8);
-
-	if (fragNum == pTxBlk->TotalFragNum) {
-		RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
-
-		/* Update the pHTTXContext->CurWritePosition. 3906 used to prevent the NextBulkOut is a A-RALINK/A-MSDU Frame. */
-		pHTTXContext->CurWritePosition += pTxBlk->Priv;
-		if (TxQLastRound == TRUE)
-			pHTTXContext->CurWritePosition = 8;
-		pHTTXContext->CurWriteRealPos = pHTTXContext->CurWritePosition;
-
-		/* Finally, set bCurWriting as FALSE */
-		pHTTXContext->bCurWriting = FALSE;
-
-		RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
-
-		/* succeed and release the skb buffer */
-		RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket, NDIS_STATUS_SUCCESS);
-	}
-
-	return (Status);
-
-}
-
-u16 RtmpUSB_WriteSingleTxResource(struct rt_rtmp_adapter *pAd,
-				     struct rt_tx_blk *pTxBlk,
-				     IN BOOLEAN bIsLast,
-				     u16 * FreeNumber)
-{
-	struct rt_ht_tx_context *pHTTXContext;
-	u16 hwHdrLen;
-	u32 fillOffset;
-	struct rt_txinfo *pTxInfo;
-	struct rt_txwi *pTxWI;
-	u8 *pWirelessPacket;
-	u8 QueIdx;
-	unsigned long IrqFlags;
-	int Status;
-	u32 USBDMApktLen = 0, DMAHdrLen, padding;
-	BOOLEAN bTxQLastRound = FALSE;
-
-	/* For USB, didn't need PCI_MAP_SINGLE() */
-	/*SrcBufPA = PCI_MAP_SINGLE(pAd, (char *) pTxBlk->pSrcBufData, pTxBlk->SrcBufLen, PCI_DMA_TODEVICE); */
-
-	/* */
-	/* get Tx Ring Resource & Dma Buffer address */
-	/* */
-	QueIdx = pTxBlk->QueIdx;
-
-	RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
-	pHTTXContext = &pAd->TxContext[QueIdx];
-	fillOffset = pHTTXContext->CurWritePosition;
-
-	/* Check ring full. */
-	Status = RtmpUSBCanDoWrite(pAd, QueIdx, pHTTXContext);
-	if (Status == NDIS_STATUS_SUCCESS) {
-		pHTTXContext->bCurWriting = TRUE;
-
-		pTxInfo = (struct rt_txinfo *)(&pTxBlk->HeaderBuf[0]);
-		pTxWI = (struct rt_txwi *) (&pTxBlk->HeaderBuf[TXINFO_SIZE]);
-
-		/* Reserve space for 8 bytes padding. */
-		if ((pHTTXContext->ENextBulkOutPosition ==
-		     pHTTXContext->CurWritePosition)) {
-			pHTTXContext->ENextBulkOutPosition += 8;
-			pHTTXContext->CurWritePosition += 8;
-			fillOffset += 8;
-		}
-		pHTTXContext->CurWriteRealPos = pHTTXContext->CurWritePosition;
-
-		pWirelessPacket =
-		    &pHTTXContext->TransferBuffer->field.
-		    WirelessPacket[fillOffset];
-
-		/* copy TXWI + WLAN Header + LLC into DMA Header Buffer */
-		/*hwHdrLen = ROUND_UP(pTxBlk->MpduHeaderLen, 4); */
-		hwHdrLen = pTxBlk->MpduHeaderLen + pTxBlk->HdrPadLen;
-
-		/* Build our URB for USBD */
-		DMAHdrLen = TXWI_SIZE + hwHdrLen;
-		USBDMApktLen = DMAHdrLen + pTxBlk->SrcBufLen;
-		padding = (4 - (USBDMApktLen % 4)) & 0x03;	/* round up to 4 byte alignment */
-		USBDMApktLen += padding;
-
-		pTxBlk->Priv = (TXINFO_SIZE + USBDMApktLen);
-
-		/* For TxInfo, the length of USBDMApktLen = TXWI_SIZE + 802.11 header + payload */
-		RTMPWriteTxInfo(pAd, pTxInfo, (u16)(USBDMApktLen), FALSE,
-				FIFO_EDCA, FALSE /*NextValid */ , FALSE);
-
-		if ((pHTTXContext->CurWritePosition + 3906 + pTxBlk->Priv) >
-		    MAX_TXBULK_LIMIT) {
-			pTxInfo->SwUseLastRound = 1;
-			bTxQLastRound = TRUE;
-		}
-		NdisMoveMemory(pWirelessPacket, pTxBlk->HeaderBuf,
-			       TXINFO_SIZE + TXWI_SIZE + hwHdrLen);
-		pWirelessPacket += (TXINFO_SIZE + TXWI_SIZE + hwHdrLen);
-
-		/* We unlock it here to prevent the first 8 bytes maybe over-writed issue. */
-		/*      1. First we got CurWritePosition but the first 8 bytes still not write to the pTxcontext. */
-		/*      2. An interrupt break our routine and handle bulk-out complete. */
-		/*      3. In the bulk-out compllete, it need to do another bulk-out, */
-		/*                      if the ENextBulkOutPosition is just the same as CurWritePosition, it will save the first 8 bytes from CurWritePosition, */
-		/*                      but the payload still not copyed. the pTxContext->SavedPad[] will save as allzero. and set the bCopyPad = TRUE. */
-		/*      4. Interrupt complete. */
-		/*  5. Our interrupted routine go back and fill the first 8 bytes to pTxContext. */
-		/*      6. Next time when do bulk-out, it found the bCopyPad==TRUE and will copy the SavedPad[] to pTxContext->NextBulkOutPosition. */
-		/*              and the packet will wrong. */
-		pHTTXContext->CurWriteRealPos +=
-		    (TXINFO_SIZE + TXWI_SIZE + hwHdrLen);
-		RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
-
-		NdisMoveMemory(pWirelessPacket, pTxBlk->pSrcBufData,
-			       pTxBlk->SrcBufLen);
-		pWirelessPacket += pTxBlk->SrcBufLen;
-		NdisZeroMemory(pWirelessPacket, padding + 8);
-
-		RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
-
-		pHTTXContext->CurWritePosition += pTxBlk->Priv;
-		if (bTxQLastRound)
-			pHTTXContext->CurWritePosition = 8;
-		pHTTXContext->CurWriteRealPos = pHTTXContext->CurWritePosition;
-
-		pHTTXContext->bCurWriting = FALSE;
-	}
-
-	RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
-
-	/* succeed and release the skb buffer */
-	RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket, NDIS_STATUS_SUCCESS);
-
-	return (Status);
-
-}
-
-u16 RtmpUSB_WriteMultiTxResource(struct rt_rtmp_adapter *pAd,
-				    struct rt_tx_blk *pTxBlk,
-				    u8 frameNum, u16 * FreeNumber)
-{
-	struct rt_ht_tx_context *pHTTXContext;
-	u16 hwHdrLen;	/* The hwHdrLen consist of 802.11 header length plus the header padding length. */
-	u32 fillOffset;
-	struct rt_txinfo *pTxInfo;
-	struct rt_txwi *pTxWI;
-	u8 *pWirelessPacket = NULL;
-	u8 QueIdx;
-	int Status;
-	unsigned long IrqFlags;
-	/*u32                        USBDMApktLen = 0, DMAHdrLen, padding; */
-
-	/* */
-	/* get Tx Ring Resource & Dma Buffer address */
-	/* */
-	QueIdx = pTxBlk->QueIdx;
-	pHTTXContext = &pAd->TxContext[QueIdx];
-
-	RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
-
-	if (frameNum == 0) {
-		/* Check if we have enough space for this bulk-out batch. */
-		Status = RtmpUSBCanDoWrite(pAd, QueIdx, pHTTXContext);
-		if (Status == NDIS_STATUS_SUCCESS) {
-			pHTTXContext->bCurWriting = TRUE;
-
-			pTxInfo = (struct rt_txinfo *)(&pTxBlk->HeaderBuf[0]);
-			pTxWI = (struct rt_txwi *) (&pTxBlk->HeaderBuf[TXINFO_SIZE]);
-
-			/* Reserve space for 8 bytes padding. */
-			if ((pHTTXContext->ENextBulkOutPosition ==
-			     pHTTXContext->CurWritePosition)) {
-
-				pHTTXContext->CurWritePosition += 8;
-				pHTTXContext->ENextBulkOutPosition += 8;
-			}
-			fillOffset = pHTTXContext->CurWritePosition;
-			pHTTXContext->CurWriteRealPos =
-			    pHTTXContext->CurWritePosition;
-
-			pWirelessPacket =
-			    &pHTTXContext->TransferBuffer->field.
-			    WirelessPacket[fillOffset];
-
-			/* */
-			/* Copy TXINFO + TXWI + WLAN Header + LLC into DMA Header Buffer */
-			/* */
-			if (pTxBlk->TxFrameType == TX_AMSDU_FRAME)
-				/*hwHdrLen = ROUND_UP(pTxBlk->MpduHeaderLen-LENGTH_AMSDU_SUBFRAMEHEAD, 4)+LENGTH_AMSDU_SUBFRAMEHEAD; */
-				hwHdrLen =
-				    pTxBlk->MpduHeaderLen -
-				    LENGTH_AMSDU_SUBFRAMEHEAD +
-				    pTxBlk->HdrPadLen +
-				    LENGTH_AMSDU_SUBFRAMEHEAD;
-			else if (pTxBlk->TxFrameType == TX_RALINK_FRAME)
-				/*hwHdrLen = ROUND_UP(pTxBlk->MpduHeaderLen-LENGTH_ARALINK_HEADER_FIELD, 4)+LENGTH_ARALINK_HEADER_FIELD; */
-				hwHdrLen =
-				    pTxBlk->MpduHeaderLen -
-				    LENGTH_ARALINK_HEADER_FIELD +
-				    pTxBlk->HdrPadLen +
-				    LENGTH_ARALINK_HEADER_FIELD;
-			else
-				/*hwHdrLen = ROUND_UP(pTxBlk->MpduHeaderLen, 4); */
-				hwHdrLen =
-				    pTxBlk->MpduHeaderLen + pTxBlk->HdrPadLen;
-
-			/* Update the pTxBlk->Priv. */
-			pTxBlk->Priv = TXINFO_SIZE + TXWI_SIZE + hwHdrLen;
-
-			/*      pTxInfo->USBDMApktLen now just a temp value and will to correct latter. */
-			RTMPWriteTxInfo(pAd, pTxInfo, (u16)(pTxBlk->Priv),
-					FALSE, FIFO_EDCA, FALSE /*NextValid */ ,
-					FALSE);
-
-			/* Copy it. */
-			NdisMoveMemory(pWirelessPacket, pTxBlk->HeaderBuf,
-				       pTxBlk->Priv);
-			pHTTXContext->CurWriteRealPos += pTxBlk->Priv;
-			pWirelessPacket += pTxBlk->Priv;
-		}
-	} else {		/* For sub-sequent frames of this bulk-out batch. Just copy it to our bulk-out buffer. */
-
-		Status =
-		    ((pHTTXContext->bCurWriting ==
-		      TRUE) ? NDIS_STATUS_SUCCESS : NDIS_STATUS_FAILURE);
-		if (Status == NDIS_STATUS_SUCCESS) {
-			fillOffset =
-			    (pHTTXContext->CurWritePosition + pTxBlk->Priv);
-			pWirelessPacket =
-			    &pHTTXContext->TransferBuffer->field.
-			    WirelessPacket[fillOffset];
-
-			/*hwHdrLen = pTxBlk->MpduHeaderLen; */
-			NdisMoveMemory(pWirelessPacket, pTxBlk->HeaderBuf,
-				       pTxBlk->MpduHeaderLen);
-			pWirelessPacket += (pTxBlk->MpduHeaderLen);
-			pTxBlk->Priv += pTxBlk->MpduHeaderLen;
-		} else {	/* It should not happened now unless we are going to shutdown. */
-			DBGPRINT(RT_DEBUG_ERROR,
-				 ("WriteMultiTxResource():bCurWriting is FALSE when handle sub-sequent frames.\n"));
-			Status = NDIS_STATUS_FAILURE;
-		}
-	}
-
-	/* We unlock it here to prevent the first 8 bytes maybe over-write issue. */
-	/*      1. First we got CurWritePosition but the first 8 bytes still not write to the pTxContext. */
-	/*      2. An interrupt break our routine and handle bulk-out complete. */
-	/*      3. In the bulk-out compllete, it need to do another bulk-out, */
-	/*                      if the ENextBulkOutPosition is just the same as CurWritePosition, it will save the first 8 bytes from CurWritePosition, */
-	/*                      but the payload still not copyed. the pTxContext->SavedPad[] will save as allzero. and set the bCopyPad = TRUE. */
-	/*      4. Interrupt complete. */
-	/*  5. Our interrupted routine go back and fill the first 8 bytes to pTxContext. */
-	/*      6. Next time when do bulk-out, it found the bCopyPad==TRUE and will copy the SavedPad[] to pTxContext->NextBulkOutPosition. */
-	/*              and the packet will wrong. */
-	RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
-
-	if (Status != NDIS_STATUS_SUCCESS) {
-		DBGPRINT(RT_DEBUG_ERROR,
-			 ("WriteMultiTxResource: CWPos = %ld, NBOutPos = %ld.\n",
-			  pHTTXContext->CurWritePosition,
-			  pHTTXContext->NextBulkOutPosition));
-		goto done;
-	}
-	/* Copy the frame content into DMA buffer and update the pTxBlk->Priv */
-	NdisMoveMemory(pWirelessPacket, pTxBlk->pSrcBufData, pTxBlk->SrcBufLen);
-	pWirelessPacket += pTxBlk->SrcBufLen;
-	pTxBlk->Priv += pTxBlk->SrcBufLen;
-
-done:
-	/* Release the skb buffer here */
-	RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket, NDIS_STATUS_SUCCESS);
-
-	return (Status);
-
-}
-
-void RtmpUSB_FinalWriteTxResource(struct rt_rtmp_adapter *pAd,
-				  struct rt_tx_blk *pTxBlk,
-				  u16 totalMPDUSize, u16 TxIdx)
-{
-	u8 QueIdx;
-	struct rt_ht_tx_context *pHTTXContext;
-	u32 fillOffset;
-	struct rt_txinfo *pTxInfo;
-	struct rt_txwi *pTxWI;
-	u32 USBDMApktLen, padding;
-	unsigned long IrqFlags;
-	u8 *pWirelessPacket;
-
-	QueIdx = pTxBlk->QueIdx;
-	pHTTXContext = &pAd->TxContext[QueIdx];
-
-	RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
-
-	if (pHTTXContext->bCurWriting == TRUE) {
-		fillOffset = pHTTXContext->CurWritePosition;
-		if (((pHTTXContext->ENextBulkOutPosition ==
-		      pHTTXContext->CurWritePosition)
-		     || ((pHTTXContext->ENextBulkOutPosition - 8) ==
-			 pHTTXContext->CurWritePosition))
-		    && (pHTTXContext->bCopySavePad == TRUE))
-			pWirelessPacket = (u8 *)(&pHTTXContext->SavedPad[0]);
-		else
-			pWirelessPacket =
-			    (u8 *)(&pHTTXContext->TransferBuffer->field.
-				      WirelessPacket[fillOffset]);
-
-		/* */
-		/* Update TxInfo->USBDMApktLen , */
-		/*              the length = TXWI_SIZE + 802.11_hdr + 802.11_hdr_pad + payload_of_all_batch_frames + Bulk-Out-padding */
-		/* */
-		pTxInfo = (struct rt_txinfo *)(pWirelessPacket);
-
-		/* Calculate the bulk-out padding */
-		USBDMApktLen = pTxBlk->Priv - TXINFO_SIZE;
-		padding = (4 - (USBDMApktLen % 4)) & 0x03;	/* round up to 4 byte alignment */
-		USBDMApktLen += padding;
-
-		pTxInfo->USBDMATxPktLen = USBDMApktLen;
-
-		/* */
-		/* Update TXWI->MPDUtotalByteCount , */
-		/*              the length = 802.11 header + payload_of_all_batch_frames */
-		pTxWI = (struct rt_txwi *) (pWirelessPacket + TXINFO_SIZE);
-		pTxWI->MPDUtotalByteCount = totalMPDUSize;
-
-		/* */
-		/* Update the pHTTXContext->CurWritePosition */
-		/* */
-		pHTTXContext->CurWritePosition += (TXINFO_SIZE + USBDMApktLen);
-		if ((pHTTXContext->CurWritePosition + 3906) > MAX_TXBULK_LIMIT) {	/* Add 3906 for prevent the NextBulkOut packet size is a A-RALINK/A-MSDU Frame. */
-			pHTTXContext->CurWritePosition = 8;
-			pTxInfo->SwUseLastRound = 1;
-		}
-		pHTTXContext->CurWriteRealPos = pHTTXContext->CurWritePosition;
-
-		/* */
-		/*      Zero the last padding. */
-		/* */
-		pWirelessPacket =
-		    (&pHTTXContext->TransferBuffer->field.
-		     WirelessPacket[fillOffset + pTxBlk->Priv]);
-		NdisZeroMemory(pWirelessPacket, padding + 8);
-
-		/* Finally, set bCurWriting as FALSE */
-		pHTTXContext->bCurWriting = FALSE;
-
-	} else {		/* It should not happened now unless we are going to shutdown. */
-		DBGPRINT(RT_DEBUG_ERROR,
-			 ("FinalWriteTxResource():bCurWriting is FALSE when handle last frames.\n"));
-	}
-
-	RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
-
-}
-
-void RtmpUSBDataLastTxIdx(struct rt_rtmp_adapter *pAd,
-			  u8 QueIdx, u16 TxIdx)
-{
-	/* DO nothing for USB. */
-}
-
-/*
-	When can do bulk-out:
-		1. TxSwFreeIdx < TX_RING_SIZE;
-			It means has at least one Ring entity is ready for bulk-out, kick it out.
-		2. If TxSwFreeIdx == TX_RING_SIZE
-			Check if the CurWriting flag is FALSE, if it's FALSE, we can do kick out.
-
-*/
-void RtmpUSBDataKickOut(struct rt_rtmp_adapter *pAd,
-			struct rt_tx_blk *pTxBlk, u8 QueIdx)
-{
-	RTUSB_SET_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_NORMAL << QueIdx));
-	RTUSBKickBulkOut(pAd);
-
-}
-
-/*
-	Must be run in Interrupt context
-	This function handle RT2870 specific TxDesc and cpu index update and kick the packet out.
- */
-int RtmpUSBMgmtKickOut(struct rt_rtmp_adapter *pAd,
-		       u8 QueIdx,
-		       void *pPacket,
-		       u8 *pSrcBufVA, u32 SrcBufLen)
-{
-	struct rt_txinfo *pTxInfo;
-	unsigned long BulkOutSize;
-	u8 padLen;
-	u8 *pDest;
-	unsigned long SwIdx = pAd->MgmtRing.TxCpuIdx;
-	struct rt_tx_context *pMLMEContext =
-	    (struct rt_tx_context *)pAd->MgmtRing.Cell[SwIdx].AllocVa;
-	unsigned long IrqFlags;
-
-	pTxInfo = (struct rt_txinfo *)(pSrcBufVA);
-
-	/* Build our URB for USBD */
-	BulkOutSize = SrcBufLen;
-	BulkOutSize = (BulkOutSize + 3) & (~3);
-	RTMPWriteTxInfo(pAd, pTxInfo, (u16)(BulkOutSize - TXINFO_SIZE),
-			TRUE, EpToQueue[MGMTPIPEIDX], FALSE, FALSE);
-
-	BulkOutSize += 4;	/* Always add 4 extra bytes at every packet. */
-
-	/* If BulkOutSize is multiple of BulkOutMaxPacketSize, add extra 4 bytes again. */
-	if ((BulkOutSize % pAd->BulkOutMaxPacketSize) == 0)
-		BulkOutSize += 4;
-
-	padLen = BulkOutSize - SrcBufLen;
-	ASSERT((padLen <= RTMP_PKT_TAIL_PADDING));
-
-	/* Now memzero all extra padding bytes. */
-	pDest = (u8 *)(pSrcBufVA + SrcBufLen);
-	skb_put(GET_OS_PKT_TYPE(pPacket), padLen);
-	NdisZeroMemory(pDest, padLen);
-
-	RTMP_IRQ_LOCK(&pAd->MLMEBulkOutLock, IrqFlags);
-
-	pAd->MgmtRing.Cell[pAd->MgmtRing.TxCpuIdx].pNdisPacket = pPacket;
-	pMLMEContext->TransferBuffer =
-	    (struct rt_tx_buffer *)(GET_OS_PKT_DATAPTR(pPacket));
-
-	/* Length in TxInfo should be 8 less than bulkout size. */
-	pMLMEContext->BulkOutSize = BulkOutSize;
-	pMLMEContext->InUse = TRUE;
-	pMLMEContext->bWaitingBulkOut = TRUE;
-
-	/*for debug */
-	/*hex_dump("RtmpUSBMgmtKickOut", &pMLMEContext->TransferBuffer->field.WirelessPacket[0], (pMLMEContext->BulkOutSize > 16 ? 16 : pMLMEContext->BulkOutSize)); */
-
-	/*pAd->RalinkCounters.KickTxCount++; */
-	/*pAd->RalinkCounters.OneSecTxDoneCount++; */
-
-	/*if (pAd->MgmtRing.TxSwFreeIdx == MGMT_RING_SIZE) */
-	/*      needKickOut = TRUE; */
-
-	/* Decrease the TxSwFreeIdx and Increase the TX_CTX_IDX */
-	pAd->MgmtRing.TxSwFreeIdx--;
-	INC_RING_INDEX(pAd->MgmtRing.TxCpuIdx, MGMT_RING_SIZE);
-
-	RTMP_IRQ_UNLOCK(&pAd->MLMEBulkOutLock, IrqFlags);
-
-	RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_MLME);
-	/*if (needKickOut) */
-	RTUSBKickBulkOut(pAd);
-
-	return 0;
-}
-
-void RtmpUSBNullFrameKickOut(struct rt_rtmp_adapter *pAd,
-			     u8 QueIdx,
-			     u8 * pNullFrame, u32 frameLen)
-{
-	if (pAd->NullContext.InUse == FALSE) {
-		struct rt_tx_context *pNullContext;
-		struct rt_txinfo *pTxInfo;
-		struct rt_txwi * pTxWI;
-		u8 *pWirelessPkt;
-
-		pNullContext = &(pAd->NullContext);
-
-		/* Set the in use bit */
-		pNullContext->InUse = TRUE;
-		pWirelessPkt =
-		    (u8 *)& pNullContext->TransferBuffer->field.
-		    WirelessPacket[0];
-
-		RTMPZeroMemory(&pWirelessPkt[0], 100);
-		pTxInfo = (struct rt_txinfo *)& pWirelessPkt[0];
-		RTMPWriteTxInfo(pAd, pTxInfo,
-				(u16)(sizeof(struct rt_header_802_11) + TXWI_SIZE),
-				TRUE, EpToQueue[MGMTPIPEIDX], FALSE, FALSE);
-		pTxInfo->QSEL = FIFO_EDCA;
-		pTxWI = (struct rt_txwi *) & pWirelessPkt[TXINFO_SIZE];
-		RTMPWriteTxWI(pAd, pTxWI, FALSE, FALSE, FALSE, FALSE, TRUE,
-			      FALSE, 0, BSSID_WCID, (sizeof(struct rt_header_802_11)), 0,
-			      0, (u8)pAd->CommonCfg.MlmeTransmit.field.MCS,
-			      IFS_HTTXOP, FALSE, &pAd->CommonCfg.MlmeTransmit);
-
-		RTMPMoveMemory(&pWirelessPkt[TXWI_SIZE + TXINFO_SIZE],
-			       &pAd->NullFrame, sizeof(struct rt_header_802_11));
-		pAd->NullContext.BulkOutSize =
-		    TXINFO_SIZE + TXWI_SIZE + sizeof(pAd->NullFrame) + 4;
-
-		/* Fill out frame length information for global Bulk out arbitor */
-		/*pNullContext->BulkOutSize = TransferBufferLength; */
-		DBGPRINT(RT_DEBUG_TRACE,
-			 ("SYNC - send NULL Frame @%d Mbps...\n",
-			  RateIdToMbps[pAd->CommonCfg.TxRate]));
-		RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NULL);
-
-		/* Kick bulk out */
-		RTUSBKickBulkOut(pAd);
-	}
-
-}
-
-/*
-========================================================================
-Routine Description:
-    Get a received packet.
-
-Arguments:
-	pAd					device control block
-	pSaveRxD			receive descriptor information
-	*pbReschedule		need reschedule flag
-	*pRxPending			pending received packet flag
-
-Return Value:
-    the received packet
-
-Note:
-========================================================================
-*/
-void *GetPacketFromRxRing(struct rt_rtmp_adapter *pAd,
-				 OUT PRT28XX_RXD_STRUC pSaveRxD,
-				 OUT BOOLEAN * pbReschedule,
-				 IN u32 * pRxPending)
-{
-	struct rt_rx_context *pRxContext;
-	void *pSkb;
-	u8 *pData;
-	unsigned long ThisFrameLen;
-	unsigned long RxBufferLength;
-	struct rt_rxwi * pRxWI;
-
-	pRxContext = &pAd->RxContext[pAd->NextRxBulkInReadIndex];
-	if ((pRxContext->Readable == FALSE) || (pRxContext->InUse == TRUE))
-		return NULL;
-
-	RxBufferLength = pRxContext->BulkInOffset - pAd->ReadPosition;
-	if (RxBufferLength <
-	    (RT2870_RXDMALEN_FIELD_SIZE + sizeof(struct rt_rxwi) +
-	     sizeof(struct rt_rxinfo))) {
-		goto label_null;
-	}
-
-	pData = &pRxContext->TransferBuffer[pAd->ReadPosition];	/* 4KB */
-	/* The RXDMA field is 4 bytes, now just use the first 2 bytes. The Length including the (RXWI + MSDU + Padding) */
-	ThisFrameLen = *pData + (*(pData + 1) << 8);
-	if (ThisFrameLen == 0) {
-		DBGPRINT(RT_DEBUG_TRACE,
-			 ("BIRIdx(%d): RXDMALen is zero.[%ld], BulkInBufLen = %ld)\n",
-			  pAd->NextRxBulkInReadIndex, ThisFrameLen,
-			  pRxContext->BulkInOffset));
-		goto label_null;
-	}
-	if ((ThisFrameLen & 0x3) != 0) {
-		DBGPRINT(RT_DEBUG_ERROR,
-			 ("BIRIdx(%d): RXDMALen not multiple of 4.[%ld], BulkInBufLen = %ld)\n",
-			  pAd->NextRxBulkInReadIndex, ThisFrameLen,
-			  pRxContext->BulkInOffset));
-		goto label_null;
-	}
-
-	if ((ThisFrameLen + 8) > RxBufferLength)	/* 8 for (RT2870_RXDMALEN_FIELD_SIZE + sizeof(struct rt_rxinfo)) */
-	{
-		DBGPRINT(RT_DEBUG_TRACE,
-			 ("BIRIdx(%d):FrameLen(0x%lx) outranges. BulkInLen=0x%lx, remaining RxBufLen=0x%lx, ReadPos=0x%lx\n",
-			  pAd->NextRxBulkInReadIndex, ThisFrameLen,
-			  pRxContext->BulkInOffset, RxBufferLength,
-			  pAd->ReadPosition));
-
-		/* error frame. finish this loop */
-		goto label_null;
-	}
-	/* skip USB frame length field */
-	pData += RT2870_RXDMALEN_FIELD_SIZE;
-	pRxWI = (struct rt_rxwi *) pData;
-	if (pRxWI->MPDUtotalByteCount > ThisFrameLen) {
-		DBGPRINT(RT_DEBUG_ERROR,
-			 ("%s():pRxWIMPDUtotalByteCount(%d) large than RxDMALen(%ld)\n",
-			  __FUNCTION__, pRxWI->MPDUtotalByteCount,
-			  ThisFrameLen));
-		goto label_null;
-	}
-	/* allocate a rx packet */
-	pSkb = dev_alloc_skb(ThisFrameLen);
-	if (pSkb == NULL) {
-		DBGPRINT(RT_DEBUG_ERROR,
-			 ("%s():Cannot Allocate sk buffer for this Bulk-In buffer!\n",
-			  __FUNCTION__));
-		goto label_null;
-	}
-	/* copy the rx packet */
-	memcpy(skb_put(pSkb, ThisFrameLen), pData, ThisFrameLen);
-	RTPKT_TO_OSPKT(pSkb)->dev = get_netdev_from_bssid(pAd, BSS0);
-	RTMP_SET_PACKET_SOURCE(OSPKT_TO_RTPKT(pSkb), PKTSRC_NDIS);
-
-	/* copy RxD */
-	*pSaveRxD = *(struct rt_rxinfo *) (pData + ThisFrameLen);
-
-	/* update next packet read position. */
-	pAd->ReadPosition += (ThisFrameLen + RT2870_RXDMALEN_FIELD_SIZE + RXINFO_SIZE);	/* 8 for (RT2870_RXDMALEN_FIELD_SIZE + sizeof(struct rt_rxinfo)) */
-
-	return pSkb;
-
-label_null:
-
-	return NULL;
-}
-
-/*
-	========================================================================
-
-	Routine	Description:
-		Check Rx descriptor, return NDIS_STATUS_FAILURE if any error dound
-
-	Arguments:
-		pRxD		Pointer	to the Rx descriptor
-
-	Return Value:
-		NDIS_STATUS_SUCCESS		No err
-		NDIS_STATUS_FAILURE		Error
-
-	Note:
-
-	========================================================================
-*/
-int RTMPCheckRxError(struct rt_rtmp_adapter *pAd,
-			     struct rt_header_802_11 * pHeader,
-			     struct rt_rxwi * pRxWI, IN PRT28XX_RXD_STRUC pRxINFO)
-{
-	struct rt_cipher_key *pWpaKey;
-	int dBm;
-
-	if (pAd->bPromiscuous == TRUE)
-		return (NDIS_STATUS_SUCCESS);
-	if (pRxINFO == NULL)
-		return (NDIS_STATUS_FAILURE);
-
-	/* Phy errors & CRC errors */
-	if (pRxINFO->Crc) {
-		/* Check RSSI for Noise Hist statistic collection. */
-		dBm = (int)(pRxWI->RSSI0) - pAd->BbpRssiToDbmDelta;
-		if (dBm <= -87)
-			pAd->StaCfg.RPIDensity[0] += 1;
-		else if (dBm <= -82)
-			pAd->StaCfg.RPIDensity[1] += 1;
-		else if (dBm <= -77)
-			pAd->StaCfg.RPIDensity[2] += 1;
-		else if (dBm <= -72)
-			pAd->StaCfg.RPIDensity[3] += 1;
-		else if (dBm <= -67)
-			pAd->StaCfg.RPIDensity[4] += 1;
-		else if (dBm <= -62)
-			pAd->StaCfg.RPIDensity[5] += 1;
-		else if (dBm <= -57)
-			pAd->StaCfg.RPIDensity[6] += 1;
-		else if (dBm > -57)
-			pAd->StaCfg.RPIDensity[7] += 1;
-
-		return (NDIS_STATUS_FAILURE);
-	}
-	/* Add Rx size to channel load counter, we should ignore error counts */
-	pAd->StaCfg.CLBusyBytes += (pRxWI->MPDUtotalByteCount + 14);
-
-	/* Drop ToDs promiscuous frame, it is opened due to CCX 2 channel load statistics */
-	if (pHeader->FC.ToDs) {
-		DBGPRINT_RAW(RT_DEBUG_ERROR, ("Err;FC.ToDs\n"));
-		return NDIS_STATUS_FAILURE;
-	}
-	/* Paul 04-03 for OFDM Rx length issue */
-	if (pRxWI->MPDUtotalByteCount > MAX_AGGREGATION_SIZE) {
-		DBGPRINT_RAW(RT_DEBUG_ERROR, ("received packet too long\n"));
-		return NDIS_STATUS_FAILURE;
-	}
-	/* Drop not U2M frames, can't drop here because we will drop beacon in this case */
-	/* I am kind of doubting the U2M bit operation */
-	/* if (pRxD->U2M == 0) */
-	/*      return(NDIS_STATUS_FAILURE); */
-
-	/* drop decyption fail frame */
-	if (pRxINFO->Decrypted && pRxINFO->CipherErr) {
-
-		if (((pRxINFO->CipherErr & 1) == 1)
-		    && pAd->CommonCfg.bWirelessEvent && INFRA_ON(pAd))
-			RTMPSendWirelessEvent(pAd, IW_ICV_ERROR_EVENT_FLAG,
-					      pAd->MacTab.Content[BSSID_WCID].
-					      Addr, BSS0, 0);
-
-		if (((pRxINFO->CipherErr & 2) == 2)
-		    && pAd->CommonCfg.bWirelessEvent && INFRA_ON(pAd))
-			RTMPSendWirelessEvent(pAd, IW_MIC_ERROR_EVENT_FLAG,
-					      pAd->MacTab.Content[BSSID_WCID].
-					      Addr, BSS0, 0);
-		/* */
-		/* MIC Error */
-		/* */
-		if ((pRxINFO->CipherErr == 2) && pRxINFO->MyBss) {
-			pWpaKey = &pAd->SharedKey[BSS0][pRxWI->KeyIndex];
-			RTMPReportMicError(pAd, pWpaKey);
-			DBGPRINT_RAW(RT_DEBUG_ERROR, ("Rx MIC Value error\n"));
-		}
-
-		if (pRxINFO->Decrypted &&
-		    (pAd->SharedKey[BSS0][pRxWI->KeyIndex].CipherAlg ==
-		     CIPHER_AES)
-		    && (pHeader->Sequence == pAd->FragFrame.Sequence)) {
-			/* */
-			/* Acceptable since the First FragFrame no CipherErr problem. */
-			/* */
-			return (NDIS_STATUS_SUCCESS);
-		}
-
-		return (NDIS_STATUS_FAILURE);
-	}
-
-	return (NDIS_STATUS_SUCCESS);
-}
-
-void RtmpUsbStaAsicForceWakeupTimeout(void *SystemSpecific1,
-				      void *FunctionContext,
-				      void *SystemSpecific2,
-				      void *SystemSpecific3)
-{
-	struct rt_rtmp_adapter *pAd = (struct rt_rtmp_adapter *)FunctionContext;
-
-	if (pAd && pAd->Mlme.AutoWakeupTimerRunning) {
-		AsicSendCommandToMcu(pAd, 0x31, 0xff, 0x00, 0x02);
-
-		OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_DOZE);
-		pAd->Mlme.AutoWakeupTimerRunning = FALSE;
-	}
-}
-
-void RT28xxUsbStaAsicForceWakeup(struct rt_rtmp_adapter *pAd, IN BOOLEAN bFromTx)
-{
-	BOOLEAN Canceled;
-
-	if (pAd->Mlme.AutoWakeupTimerRunning)
-		RTMPCancelTimer(&pAd->Mlme.AutoWakeupTimer, &Canceled);
-
-	AsicSendCommandToMcu(pAd, 0x31, 0xff, 0x00, 0x02);
-
-	OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_DOZE);
-}
-
-void RT28xxUsbStaAsicSleepThenAutoWakeup(struct rt_rtmp_adapter *pAd,
-					 u16 TbttNumToNextWakeUp)
-{
-
-	/* we have decided to SLEEP, so at least do it for a BEACON period. */
-	if (TbttNumToNextWakeUp == 0)
-		TbttNumToNextWakeUp = 1;
-
-	RTMPSetTimer(&pAd->Mlme.AutoWakeupTimer, AUTO_WAKEUP_TIMEOUT);
-	pAd->Mlme.AutoWakeupTimerRunning = TRUE;
-
-	AsicSendCommandToMcu(pAd, 0x30, 0xff, 0xff, 0x02);	/* send POWER-SAVE command to MCU. Timeout 40us. */
-
-	OPSTATUS_SET_FLAG(pAd, fOP_STATUS_DOZE);
-
-}
-
-#endif /* RTMP_MAC_USB // */
diff -druN linux-2.6.39-libre/drivers/staging/rt2860/common/cmm_info.c linux-3.0-rc7-libre/drivers/staging/rt2860/common/cmm_info.c
--- linux-2.6.39-libre/drivers/staging/rt2860/common/cmm_info.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rt2860/common/cmm_info.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,955 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, Inc.
- *
- * This program is free software; you can redistribute it and/or modify  *
- * it under the terms of the GNU General Public License as published by  *
- * the Free Software Foundation; either version 2 of the License, or     *
- * (at your option) any later version.                                   *
- *                                                                       *
- * This program is distributed in the hope that it will be useful,       *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of        *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
- * GNU General Public License for more details.                          *
- *                                                                       *
- * You should have received a copy of the GNU General Public License     *
- * along with this program; if not, write to the                         *
- * Free Software Foundation, Inc.,                                       *
- * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
- *                                                                       *
- *************************************************************************
- */
-
-#include <linux/sched.h>
-#include "../rt_config.h"
-
-/*
-	========================================================================
-
-	Routine Description:
-		Remove WPA Key process
-
-	Arguments:
-		pAd 					Pointer to our adapter
-		pBuf							Pointer to the where the key stored
-
-	Return Value:
-		NDIS_SUCCESS					Add key successfully
-
-	IRQL = DISPATCH_LEVEL
-
-	Note:
-
-	========================================================================
-*/
-void RTMPSetDesiredRates(struct rt_rtmp_adapter *pAdapter, long Rates)
-{
-	NDIS_802_11_RATES aryRates;
-
-	memset(&aryRates, 0x00, sizeof(NDIS_802_11_RATES));
-	switch (pAdapter->CommonCfg.PhyMode) {
-	case PHY_11A:		/* A only */
-		switch (Rates) {
-		case 6000000:	/*6M */
-			aryRates[0] = 0x0c;	/* 6M */
-			pAdapter->StaCfg.DesiredTransmitSetting.field.MCS =
-			    MCS_0;
-			break;
-		case 9000000:	/*9M */
-			aryRates[0] = 0x12;	/* 9M */
-			pAdapter->StaCfg.DesiredTransmitSetting.field.MCS =
-			    MCS_1;
-			break;
-		case 12000000:	/*12M */
-			aryRates[0] = 0x18;	/* 12M */
-			pAdapter->StaCfg.DesiredTransmitSetting.field.MCS =
-			    MCS_2;
-			break;
-		case 18000000:	/*18M */
-			aryRates[0] = 0x24;	/* 18M */
-			pAdapter->StaCfg.DesiredTransmitSetting.field.MCS =
-			    MCS_3;
-			break;
-		case 24000000:	/*24M */
-			aryRates[0] = 0x30;	/* 24M */
-			pAdapter->StaCfg.DesiredTransmitSetting.field.MCS =
-			    MCS_4;
-			break;
-		case 36000000:	/*36M */
-			aryRates[0] = 0x48;	/* 36M */
-			pAdapter->StaCfg.DesiredTransmitSetting.field.MCS =
-			    MCS_5;
-			break;
-		case 48000000:	/*48M */
-			aryRates[0] = 0x60;	/* 48M */
-			pAdapter->StaCfg.DesiredTransmitSetting.field.MCS =
-			    MCS_6;
-			break;
-		case 54000000:	/*54M */
-			aryRates[0] = 0x6c;	/* 54M */
-			pAdapter->StaCfg.DesiredTransmitSetting.field.MCS =
-			    MCS_7;
-			break;
-		case -1:	/*Auto */
-		default:
-			aryRates[0] = 0x6c;	/* 54Mbps */
-			aryRates[1] = 0x60;	/* 48Mbps */
-			aryRates[2] = 0x48;	/* 36Mbps */
-			aryRates[3] = 0x30;	/* 24Mbps */
-			aryRates[4] = 0x24;	/* 18M */
-			aryRates[5] = 0x18;	/* 12M */
-			aryRates[6] = 0x12;	/* 9M */
-			aryRates[7] = 0x0c;	/* 6M */
-			pAdapter->StaCfg.DesiredTransmitSetting.field.MCS =
-			    MCS_AUTO;
-			break;
-		}
-		break;
-	case PHY_11BG_MIXED:	/* B/G Mixed */
-	case PHY_11B:		/* B only */
-	case PHY_11ABG_MIXED:	/* A/B/G Mixed */
-	default:
-		switch (Rates) {
-		case 1000000:	/*1M */
-			aryRates[0] = 0x02;
-			pAdapter->StaCfg.DesiredTransmitSetting.field.MCS =
-			    MCS_0;
-			break;
-		case 2000000:	/*2M */
-			aryRates[0] = 0x04;
-			pAdapter->StaCfg.DesiredTransmitSetting.field.MCS =
-			    MCS_1;
-			break;
-		case 5000000:	/*5.5M */
-			aryRates[0] = 0x0b;	/* 5.5M */
-			pAdapter->StaCfg.DesiredTransmitSetting.field.MCS =
-			    MCS_2;
-			break;
-		case 11000000:	/*11M */
-			aryRates[0] = 0x16;	/* 11M */
-			pAdapter->StaCfg.DesiredTransmitSetting.field.MCS =
-			    MCS_3;
-			break;
-		case 6000000:	/*6M */
-			aryRates[0] = 0x0c;	/* 6M */
-			pAdapter->StaCfg.DesiredTransmitSetting.field.MCS =
-			    MCS_0;
-			break;
-		case 9000000:	/*9M */
-			aryRates[0] = 0x12;	/* 9M */
-			pAdapter->StaCfg.DesiredTransmitSetting.field.MCS =
-			    MCS_1;
-			break;
-		case 12000000:	/*12M */
-			aryRates[0] = 0x18;	/* 12M */
-			pAdapter->StaCfg.DesiredTransmitSetting.field.MCS =
-			    MCS_2;
-			break;
-		case 18000000:	/*18M */
-			aryRates[0] = 0x24;	/* 18M */
-			pAdapter->StaCfg.DesiredTransmitSetting.field.MCS =
-			    MCS_3;
-			break;
-		case 24000000:	/*24M */
-			aryRates[0] = 0x30;	/* 24M */
-			pAdapter->StaCfg.DesiredTransmitSetting.field.MCS =
-			    MCS_4;
-			break;
-		case 36000000:	/*36M */
-			aryRates[0] = 0x48;	/* 36M */
-			pAdapter->StaCfg.DesiredTransmitSetting.field.MCS =
-			    MCS_5;
-			break;
-		case 48000000:	/*48M */
-			aryRates[0] = 0x60;	/* 48M */
-			pAdapter->StaCfg.DesiredTransmitSetting.field.MCS =
-			    MCS_6;
-			break;
-		case 54000000:	/*54M */
-			aryRates[0] = 0x6c;	/* 54M */
-			pAdapter->StaCfg.DesiredTransmitSetting.field.MCS =
-			    MCS_7;
-			break;
-		case -1:	/*Auto */
-		default:
-			if (pAdapter->CommonCfg.PhyMode == PHY_11B) {	/*B Only */
-				aryRates[0] = 0x16;	/* 11Mbps */
-				aryRates[1] = 0x0b;	/* 5.5Mbps */
-				aryRates[2] = 0x04;	/* 2Mbps */
-				aryRates[3] = 0x02;	/* 1Mbps */
-			} else {	/*(B/G) Mixed or (A/B/G) Mixed */
-				aryRates[0] = 0x6c;	/* 54Mbps */
-				aryRates[1] = 0x60;	/* 48Mbps */
-				aryRates[2] = 0x48;	/* 36Mbps */
-				aryRates[3] = 0x30;	/* 24Mbps */
-				aryRates[4] = 0x16;	/* 11Mbps */
-				aryRates[5] = 0x0b;	/* 5.5Mbps */
-				aryRates[6] = 0x04;	/* 2Mbps */
-				aryRates[7] = 0x02;	/* 1Mbps */
-			}
-			pAdapter->StaCfg.DesiredTransmitSetting.field.MCS =
-			    MCS_AUTO;
-			break;
-		}
-		break;
-	}
-
-	NdisZeroMemory(pAdapter->CommonCfg.DesireRate,
-		       MAX_LEN_OF_SUPPORTED_RATES);
-	NdisMoveMemory(pAdapter->CommonCfg.DesireRate, &aryRates,
-		       sizeof(NDIS_802_11_RATES));
-	DBGPRINT(RT_DEBUG_TRACE,
-		 (" RTMPSetDesiredRates (%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x)\n",
-		  pAdapter->CommonCfg.DesireRate[0],
-		  pAdapter->CommonCfg.DesireRate[1],
-		  pAdapter->CommonCfg.DesireRate[2],
-		  pAdapter->CommonCfg.DesireRate[3],
-		  pAdapter->CommonCfg.DesireRate[4],
-		  pAdapter->CommonCfg.DesireRate[5],
-		  pAdapter->CommonCfg.DesireRate[6],
-		  pAdapter->CommonCfg.DesireRate[7]));
-	/* Changing DesiredRate may affect the MAX TX rate we used to TX frames out */
-	MlmeUpdateTxRates(pAdapter, FALSE, 0);
-}
-
-/*
-	========================================================================
-
-	Routine Description:
-		Remove All WPA Keys
-
-	Arguments:
-		pAd 					Pointer to our adapter
-
-	Return Value:
-		None
-
-	IRQL = DISPATCH_LEVEL
-
-	Note:
-
-	========================================================================
-*/
-void RTMPWPARemoveAllKeys(struct rt_rtmp_adapter *pAd)
-{
-
-	u8 i;
-
-	DBGPRINT(RT_DEBUG_TRACE,
-		 ("RTMPWPARemoveAllKeys(AuthMode=%d, WepStatus=%d)\n",
-		  pAd->StaCfg.AuthMode, pAd->StaCfg.WepStatus));
-	RTMP_CLEAR_PSFLAG(pAd, fRTMP_PS_CAN_GO_SLEEP);
-	/* For WEP/CKIP, there is no need to remove it, since WinXP won't set it again after */
-	/* Link up. And it will be replaced if user changed it. */
-	if (pAd->StaCfg.AuthMode < Ndis802_11AuthModeWPA)
-		return;
-
-	/* For WPA-None, there is no need to remove it, since WinXP won't set it again after */
-	/* Link up. And it will be replaced if user changed it. */
-	if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPANone)
-		return;
-
-	/* set BSSID wcid entry of the Pair-wise Key table as no-security mode */
-	AsicRemovePairwiseKeyEntry(pAd, BSS0, BSSID_WCID);
-
-	/* set all shared key mode as no-security. */
-	for (i = 0; i < SHARE_KEY_NUM; i++) {
-		DBGPRINT(RT_DEBUG_TRACE,
-			 ("remove %s key #%d\n",
-			  CipherName[pAd->SharedKey[BSS0][i].CipherAlg], i));
-		NdisZeroMemory(&pAd->SharedKey[BSS0][i], sizeof(struct rt_cipher_key));
-
-		AsicRemoveSharedKeyEntry(pAd, BSS0, i);
-	}
-	RTMP_SET_PSFLAG(pAd, fRTMP_PS_CAN_GO_SLEEP);
-}
-
-/*
-	========================================================================
-
-	Routine Description:
-		As STA's BSSID is a WC too, it uses shared key table.
-		This function write correct unicast TX key to ASIC WCID.
-		And we still make a copy in our MacTab.Content[BSSID_WCID].PairwiseKey.
-		Caller guarantee TKIP/AES always has keyidx = 0. (pairwise key)
-		Caller guarantee WEP calls this function when set Txkey,  default key index=0~3.
-
-	Arguments:
-		pAd					Pointer to our adapter
-		pKey							Pointer to the where the key stored
-
-	Return Value:
-		NDIS_SUCCESS					Add key successfully
-
-	IRQL = DISPATCH_LEVEL
-
-	Note:
-
-	========================================================================
-*/
-/*
-	========================================================================
-	Routine Description:
-		Change NIC PHY mode. Re-association may be necessary. possible settings
-		include - PHY_11B, PHY_11BG_MIXED, PHY_11A, and PHY_11ABG_MIXED
-
-	Arguments:
-		pAd - Pointer to our adapter
-		phymode  -
-
-	IRQL = PASSIVE_LEVEL
-	IRQL = DISPATCH_LEVEL
-
-	========================================================================
-*/
-void RTMPSetPhyMode(struct rt_rtmp_adapter *pAd, unsigned long phymode)
-{
-	int i;
-	/* the selected phymode must be supported by the RF IC encoded in E2PROM */
-
-	/* if no change, do nothing */
-	/* bug fix
-	   if (pAd->CommonCfg.PhyMode == phymode)
-	   return;
-	 */
-	pAd->CommonCfg.PhyMode = (u8)phymode;
-
-	DBGPRINT(RT_DEBUG_TRACE,
-		 ("RTMPSetPhyMode : PhyMode=%d, channel=%d \n",
-		  pAd->CommonCfg.PhyMode, pAd->CommonCfg.Channel));
-
-	BuildChannelList(pAd);
-
-	/* sanity check user setting */
-	for (i = 0; i < pAd->ChannelListNum; i++) {
-		if (pAd->CommonCfg.Channel == pAd->ChannelList[i].Channel)
-			break;
-	}
-
-	if (i == pAd->ChannelListNum) {
-		pAd->CommonCfg.Channel = FirstChannel(pAd);
-		DBGPRINT(RT_DEBUG_ERROR,
-			 ("RTMPSetPhyMode: channel is out of range, use first channel=%d \n",
-			  pAd->CommonCfg.Channel));
-	}
-
-	NdisZeroMemory(pAd->CommonCfg.SupRate, MAX_LEN_OF_SUPPORTED_RATES);
-	NdisZeroMemory(pAd->CommonCfg.ExtRate, MAX_LEN_OF_SUPPORTED_RATES);
-	NdisZeroMemory(pAd->CommonCfg.DesireRate, MAX_LEN_OF_SUPPORTED_RATES);
-	switch (phymode) {
-	case PHY_11B:
-		pAd->CommonCfg.SupRate[0] = 0x82;	/* 1 mbps, in units of 0.5 Mbps, basic rate */
-		pAd->CommonCfg.SupRate[1] = 0x84;	/* 2 mbps, in units of 0.5 Mbps, basic rate */
-		pAd->CommonCfg.SupRate[2] = 0x8B;	/* 5.5 mbps, in units of 0.5 Mbps, basic rate */
-		pAd->CommonCfg.SupRate[3] = 0x96;	/* 11 mbps, in units of 0.5 Mbps, basic rate */
-		pAd->CommonCfg.SupRateLen = 4;
-		pAd->CommonCfg.ExtRateLen = 0;
-		pAd->CommonCfg.DesireRate[0] = 2;	/* 1 mbps, in units of 0.5 Mbps */
-		pAd->CommonCfg.DesireRate[1] = 4;	/* 2 mbps, in units of 0.5 Mbps */
-		pAd->CommonCfg.DesireRate[2] = 11;	/* 5.5 mbps, in units of 0.5 Mbps */
-		pAd->CommonCfg.DesireRate[3] = 22;	/* 11 mbps, in units of 0.5 Mbps */
-		/*pAd->CommonCfg.HTPhyMode.field.MODE = MODE_CCK; // This MODE is only FYI. not use */
-		break;
-
-	case PHY_11G:
-	case PHY_11BG_MIXED:
-	case PHY_11ABG_MIXED:
-	case PHY_11N_2_4G:
-	case PHY_11ABGN_MIXED:
-	case PHY_11BGN_MIXED:
-	case PHY_11GN_MIXED:
-		pAd->CommonCfg.SupRate[0] = 0x82;	/* 1 mbps, in units of 0.5 Mbps, basic rate */
-		pAd->CommonCfg.SupRate[1] = 0x84;	/* 2 mbps, in units of 0.5 Mbps, basic rate */
-		pAd->CommonCfg.SupRate[2] = 0x8B;	/* 5.5 mbps, in units of 0.5 Mbps, basic rate */
-		pAd->CommonCfg.SupRate[3] = 0x96;	/* 11 mbps, in units of 0.5 Mbps, basic rate */
-		pAd->CommonCfg.SupRate[4] = 0x12;	/* 9 mbps, in units of 0.5 Mbps */
-		pAd->CommonCfg.SupRate[5] = 0x24;	/* 18 mbps, in units of 0.5 Mbps */
-		pAd->CommonCfg.SupRate[6] = 0x48;	/* 36 mbps, in units of 0.5 Mbps */
-		pAd->CommonCfg.SupRate[7] = 0x6c;	/* 54 mbps, in units of 0.5 Mbps */
-		pAd->CommonCfg.SupRateLen = 8;
-		pAd->CommonCfg.ExtRate[0] = 0x0C;	/* 6 mbps, in units of 0.5 Mbps */
-		pAd->CommonCfg.ExtRate[1] = 0x18;	/* 12 mbps, in units of 0.5 Mbps */
-		pAd->CommonCfg.ExtRate[2] = 0x30;	/* 24 mbps, in units of 0.5 Mbps */
-		pAd->CommonCfg.ExtRate[3] = 0x60;	/* 48 mbps, in units of 0.5 Mbps */
-		pAd->CommonCfg.ExtRateLen = 4;
-		pAd->CommonCfg.DesireRate[0] = 2;	/* 1 mbps, in units of 0.5 Mbps */
-		pAd->CommonCfg.DesireRate[1] = 4;	/* 2 mbps, in units of 0.5 Mbps */
-		pAd->CommonCfg.DesireRate[2] = 11;	/* 5.5 mbps, in units of 0.5 Mbps */
-		pAd->CommonCfg.DesireRate[3] = 22;	/* 11 mbps, in units of 0.5 Mbps */
-		pAd->CommonCfg.DesireRate[4] = 12;	/* 6 mbps, in units of 0.5 Mbps */
-		pAd->CommonCfg.DesireRate[5] = 18;	/* 9 mbps, in units of 0.5 Mbps */
-		pAd->CommonCfg.DesireRate[6] = 24;	/* 12 mbps, in units of 0.5 Mbps */
-		pAd->CommonCfg.DesireRate[7] = 36;	/* 18 mbps, in units of 0.5 Mbps */
-		pAd->CommonCfg.DesireRate[8] = 48;	/* 24 mbps, in units of 0.5 Mbps */
-		pAd->CommonCfg.DesireRate[9] = 72;	/* 36 mbps, in units of 0.5 Mbps */
-		pAd->CommonCfg.DesireRate[10] = 96;	/* 48 mbps, in units of 0.5 Mbps */
-		pAd->CommonCfg.DesireRate[11] = 108;	/* 54 mbps, in units of 0.5 Mbps */
-		break;
-
-	case PHY_11A:
-	case PHY_11AN_MIXED:
-	case PHY_11AGN_MIXED:
-	case PHY_11N_5G:
-		pAd->CommonCfg.SupRate[0] = 0x8C;	/* 6 mbps, in units of 0.5 Mbps, basic rate */
-		pAd->CommonCfg.SupRate[1] = 0x12;	/* 9 mbps, in units of 0.5 Mbps */
-		pAd->CommonCfg.SupRate[2] = 0x98;	/* 12 mbps, in units of 0.5 Mbps, basic rate */
-		pAd->CommonCfg.SupRate[3] = 0x24;	/* 18 mbps, in units of 0.5 Mbps */
-		pAd->CommonCfg.SupRate[4] = 0xb0;	/* 24 mbps, in units of 0.5 Mbps, basic rate */
-		pAd->CommonCfg.SupRate[5] = 0x48;	/* 36 mbps, in units of 0.5 Mbps */
-		pAd->CommonCfg.SupRate[6] = 0x60;	/* 48 mbps, in units of 0.5 Mbps */
-		pAd->CommonCfg.SupRate[7] = 0x6c;	/* 54 mbps, in units of 0.5 Mbps */
-		pAd->CommonCfg.SupRateLen = 8;
-		pAd->CommonCfg.ExtRateLen = 0;
-		pAd->CommonCfg.DesireRate[0] = 12;	/* 6 mbps, in units of 0.5 Mbps */
-		pAd->CommonCfg.DesireRate[1] = 18;	/* 9 mbps, in units of 0.5 Mbps */
-		pAd->CommonCfg.DesireRate[2] = 24;	/* 12 mbps, in units of 0.5 Mbps */
-		pAd->CommonCfg.DesireRate[3] = 36;	/* 18 mbps, in units of 0.5 Mbps */
-		pAd->CommonCfg.DesireRate[4] = 48;	/* 24 mbps, in units of 0.5 Mbps */
-		pAd->CommonCfg.DesireRate[5] = 72;	/* 36 mbps, in units of 0.5 Mbps */
-		pAd->CommonCfg.DesireRate[6] = 96;	/* 48 mbps, in units of 0.5 Mbps */
-		pAd->CommonCfg.DesireRate[7] = 108;	/* 54 mbps, in units of 0.5 Mbps */
-		/*pAd->CommonCfg.HTPhyMode.field.MODE = MODE_OFDM; // This MODE is only FYI. not use */
-		break;
-
-	default:
-		break;
-	}
-
-	pAd->CommonCfg.BandState = UNKNOWN_BAND;
-}
-
-/*
-	========================================================================
-	Routine Description:
-		Caller ensures we has 802.11n support.
-		Calls at setting HT from AP/STASetinformation
-
-	Arguments:
-		pAd - Pointer to our adapter
-		phymode  -
-
-	========================================================================
-*/
-void RTMPSetHT(struct rt_rtmp_adapter *pAd, struct rt_oid_set_ht_phymode *pHTPhyMode)
-{
-	/*unsigned long *pmcs; */
-	u32 Value = 0;
-	u8 BBPValue = 0;
-	u8 BBP3Value = 0;
-	u8 RxStream = pAd->CommonCfg.RxStream;
-
-	DBGPRINT(RT_DEBUG_TRACE,
-		 ("RTMPSetHT : HT_mode(%d), ExtOffset(%d), MCS(%d), BW(%d), STBC(%d), SHORTGI(%d)\n",
-		  pHTPhyMode->HtMode, pHTPhyMode->ExtOffset, pHTPhyMode->MCS,
-		  pHTPhyMode->BW, pHTPhyMode->STBC, pHTPhyMode->SHORTGI));
-
-	/* Don't zero supportedHyPhy structure. */
-	RTMPZeroMemory(&pAd->CommonCfg.HtCapability,
-		       sizeof(pAd->CommonCfg.HtCapability));
-	RTMPZeroMemory(&pAd->CommonCfg.AddHTInfo,
-		       sizeof(pAd->CommonCfg.AddHTInfo));
-	RTMPZeroMemory(&pAd->CommonCfg.NewExtChanOffset,
-		       sizeof(pAd->CommonCfg.NewExtChanOffset));
-	RTMPZeroMemory(&pAd->CommonCfg.DesiredHtPhy,
-		       sizeof(pAd->CommonCfg.DesiredHtPhy));
-
-	if (pAd->CommonCfg.bRdg) {
-		pAd->CommonCfg.HtCapability.ExtHtCapInfo.PlusHTC = 1;
-		pAd->CommonCfg.HtCapability.ExtHtCapInfo.RDGSupport = 1;
-	} else {
-		pAd->CommonCfg.HtCapability.ExtHtCapInfo.PlusHTC = 0;
-		pAd->CommonCfg.HtCapability.ExtHtCapInfo.RDGSupport = 0;
-	}
-
-	pAd->CommonCfg.HtCapability.HtCapParm.MaxRAmpduFactor = 3;
-	pAd->CommonCfg.DesiredHtPhy.MaxRAmpduFactor = 3;
-
-	DBGPRINT(RT_DEBUG_TRACE,
-		 ("RTMPSetHT : RxBAWinLimit = %d\n",
-		  pAd->CommonCfg.BACapability.field.RxBAWinLimit));
-
-	/* Mimo power save, A-MSDU size, */
-	pAd->CommonCfg.DesiredHtPhy.AmsduEnable =
-	    (u16)pAd->CommonCfg.BACapability.field.AmsduEnable;
-	pAd->CommonCfg.DesiredHtPhy.AmsduSize =
-	    (u8)pAd->CommonCfg.BACapability.field.AmsduSize;
-	pAd->CommonCfg.DesiredHtPhy.MimoPs =
-	    (u8)pAd->CommonCfg.BACapability.field.MMPSmode;
-	pAd->CommonCfg.DesiredHtPhy.MpduDensity =
-	    (u8)pAd->CommonCfg.BACapability.field.MpduDensity;
-
-	pAd->CommonCfg.HtCapability.HtCapInfo.AMsduSize =
-	    (u16)pAd->CommonCfg.BACapability.field.AmsduSize;
-	pAd->CommonCfg.HtCapability.HtCapInfo.MimoPs =
-	    (u16)pAd->CommonCfg.BACapability.field.MMPSmode;
-	pAd->CommonCfg.HtCapability.HtCapParm.MpduDensity =
-	    (u8)pAd->CommonCfg.BACapability.field.MpduDensity;
-
-	DBGPRINT(RT_DEBUG_TRACE,
-		 ("RTMPSetHT : AMsduSize = %d, MimoPs = %d, MpduDensity = %d, MaxRAmpduFactor = %d\n",
-		  pAd->CommonCfg.DesiredHtPhy.AmsduSize,
-		  pAd->CommonCfg.DesiredHtPhy.MimoPs,
-		  pAd->CommonCfg.DesiredHtPhy.MpduDensity,
-		  pAd->CommonCfg.DesiredHtPhy.MaxRAmpduFactor));
-
-	if (pHTPhyMode->HtMode == HTMODE_GF) {
-		pAd->CommonCfg.HtCapability.HtCapInfo.GF = 1;
-		pAd->CommonCfg.DesiredHtPhy.GF = 1;
-	} else
-		pAd->CommonCfg.DesiredHtPhy.GF = 0;
-
-	/* Decide Rx MCSSet */
-	switch (RxStream) {
-	case 1:
-		pAd->CommonCfg.HtCapability.MCSSet[0] = 0xff;
-		pAd->CommonCfg.HtCapability.MCSSet[1] = 0x00;
-		break;
-
-	case 2:
-		pAd->CommonCfg.HtCapability.MCSSet[0] = 0xff;
-		pAd->CommonCfg.HtCapability.MCSSet[1] = 0xff;
-		break;
-
-	case 3:		/* 3*3 */
-		pAd->CommonCfg.HtCapability.MCSSet[0] = 0xff;
-		pAd->CommonCfg.HtCapability.MCSSet[1] = 0xff;
-		pAd->CommonCfg.HtCapability.MCSSet[2] = 0xff;
-		break;
-	}
-
-	if (pAd->CommonCfg.bForty_Mhz_Intolerant
-	    && (pAd->CommonCfg.Channel <= 14) && (pHTPhyMode->BW == BW_40)) {
-		pHTPhyMode->BW = BW_20;
-		pAd->CommonCfg.HtCapability.HtCapInfo.Forty_Mhz_Intolerant = 1;
-	}
-
-	if (pHTPhyMode->BW == BW_40) {
-		pAd->CommonCfg.HtCapability.MCSSet[4] = 0x1;	/* MCS 32 */
-		pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth = 1;
-		if (pAd->CommonCfg.Channel <= 14)
-			pAd->CommonCfg.HtCapability.HtCapInfo.CCKmodein40 = 1;
-
-		pAd->CommonCfg.DesiredHtPhy.ChannelWidth = 1;
-		pAd->CommonCfg.AddHTInfo.AddHtInfo.RecomWidth = 1;
-		pAd->CommonCfg.AddHTInfo.AddHtInfo.ExtChanOffset =
-		    (pHTPhyMode->ExtOffset ==
-		     EXTCHA_BELOW) ? (EXTCHA_BELOW) : EXTCHA_ABOVE;
-		/* Set Regsiter for extension channel position. */
-		RTMP_IO_READ32(pAd, TX_BAND_CFG, &Value);
-		RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &BBP3Value);
-		if ((pHTPhyMode->ExtOffset == EXTCHA_BELOW)) {
-			Value |= 0x1;
-			BBP3Value |= (0x20);
-			RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Value);
-		} else if ((pHTPhyMode->ExtOffset == EXTCHA_ABOVE)) {
-			Value &= 0xfe;
-			BBP3Value &= (~0x20);
-			RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Value);
-		}
-		/* Turn on BBP 40MHz mode now only as AP . */
-		/* Sta can turn on BBP 40MHz after connection with 40MHz AP. Sta only broadcast 40MHz capability before connection. */
-		if ((pAd->OpMode == OPMODE_AP) || INFRA_ON(pAd) || ADHOC_ON(pAd)
-		    ) {
-			RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue);
-			BBPValue &= (~0x18);
-			BBPValue |= 0x10;
-			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue);
-
-			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, BBP3Value);
-			pAd->CommonCfg.BBPCurrentBW = BW_40;
-		}
-	} else {
-		pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth = 0;
-		pAd->CommonCfg.DesiredHtPhy.ChannelWidth = 0;
-		pAd->CommonCfg.AddHTInfo.AddHtInfo.RecomWidth = 0;
-		pAd->CommonCfg.AddHTInfo.AddHtInfo.ExtChanOffset = EXTCHA_NONE;
-		pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel;
-		/* Turn on BBP 20MHz mode by request here. */
-		{
-			RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue);
-			BBPValue &= (~0x18);
-			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue);
-			pAd->CommonCfg.BBPCurrentBW = BW_20;
-		}
-	}
-
-	if (pHTPhyMode->STBC == STBC_USE) {
-		pAd->CommonCfg.HtCapability.HtCapInfo.TxSTBC = 1;
-		pAd->CommonCfg.DesiredHtPhy.TxSTBC = 1;
-		pAd->CommonCfg.HtCapability.HtCapInfo.RxSTBC = 1;
-		pAd->CommonCfg.DesiredHtPhy.RxSTBC = 1;
-	} else {
-		pAd->CommonCfg.DesiredHtPhy.TxSTBC = 0;
-		pAd->CommonCfg.DesiredHtPhy.RxSTBC = 0;
-	}
-
-	if (pHTPhyMode->SHORTGI == GI_400) {
-		pAd->CommonCfg.HtCapability.HtCapInfo.ShortGIfor20 = 1;
-		pAd->CommonCfg.HtCapability.HtCapInfo.ShortGIfor40 = 1;
-		pAd->CommonCfg.DesiredHtPhy.ShortGIfor20 = 1;
-		pAd->CommonCfg.DesiredHtPhy.ShortGIfor40 = 1;
-	} else {
-		pAd->CommonCfg.HtCapability.HtCapInfo.ShortGIfor20 = 0;
-		pAd->CommonCfg.HtCapability.HtCapInfo.ShortGIfor40 = 0;
-		pAd->CommonCfg.DesiredHtPhy.ShortGIfor20 = 0;
-		pAd->CommonCfg.DesiredHtPhy.ShortGIfor40 = 0;
-	}
-
-	/* We support link adaptation for unsolicit MCS feedback, set to 2. */
-	pAd->CommonCfg.HtCapability.ExtHtCapInfo.MCSFeedback = MCSFBK_NONE;	/*MCSFBK_UNSOLICIT; */
-	pAd->CommonCfg.AddHTInfo.ControlChan = pAd->CommonCfg.Channel;
-	/* 1, the extension channel above the control channel. */
-
-	/* EDCA parameters used for AP's own transmission */
-	if (pAd->CommonCfg.APEdcaParm.bValid == FALSE) {
-		pAd->CommonCfg.APEdcaParm.bValid = TRUE;
-		pAd->CommonCfg.APEdcaParm.Aifsn[0] = 3;
-		pAd->CommonCfg.APEdcaParm.Aifsn[1] = 7;
-		pAd->CommonCfg.APEdcaParm.Aifsn[2] = 1;
-		pAd->CommonCfg.APEdcaParm.Aifsn[3] = 1;
-
-		pAd->CommonCfg.APEdcaParm.Cwmin[0] = 4;
-		pAd->CommonCfg.APEdcaParm.Cwmin[1] = 4;
-		pAd->CommonCfg.APEdcaParm.Cwmin[2] = 3;
-		pAd->CommonCfg.APEdcaParm.Cwmin[3] = 2;
-
-		pAd->CommonCfg.APEdcaParm.Cwmax[0] = 6;
-		pAd->CommonCfg.APEdcaParm.Cwmax[1] = 10;
-		pAd->CommonCfg.APEdcaParm.Cwmax[2] = 4;
-		pAd->CommonCfg.APEdcaParm.Cwmax[3] = 3;
-
-		pAd->CommonCfg.APEdcaParm.Txop[0] = 0;
-		pAd->CommonCfg.APEdcaParm.Txop[1] = 0;
-		pAd->CommonCfg.APEdcaParm.Txop[2] = 94;
-		pAd->CommonCfg.APEdcaParm.Txop[3] = 47;
-	}
-	AsicSetEdcaParm(pAd, &pAd->CommonCfg.APEdcaParm);
-
-	{
-		RTMPSetIndividualHT(pAd, 0);
-	}
-
-}
-
-/*
-	========================================================================
-	Routine Description:
-		Caller ensures we has 802.11n support.
-		Calls at setting HT from AP/STASetinformation
-
-	Arguments:
-		pAd - Pointer to our adapter
-		phymode  -
-
-	========================================================================
-*/
-void RTMPSetIndividualHT(struct rt_rtmp_adapter *pAd, u8 apidx)
-{
-	struct rt_ht_phy_info *pDesired_ht_phy = NULL;
-	u8 TxStream = pAd->CommonCfg.TxStream;
-	u8 DesiredMcs = MCS_AUTO;
-
-	do {
-		{
-			pDesired_ht_phy = &pAd->StaCfg.DesiredHtPhyInfo;
-			DesiredMcs =
-			    pAd->StaCfg.DesiredTransmitSetting.field.MCS;
-			/*pAd->StaCfg.bAutoTxRateSwitch = (DesiredMcs == MCS_AUTO) ? TRUE : FALSE; */
-			break;
-		}
-	} while (FALSE);
-
-	if (pDesired_ht_phy == NULL) {
-		DBGPRINT(RT_DEBUG_ERROR,
-			 ("RTMPSetIndividualHT: invalid apidx(%d)\n", apidx));
-		return;
-	}
-	RTMPZeroMemory(pDesired_ht_phy, sizeof(struct rt_ht_phy_info));
-
-	DBGPRINT(RT_DEBUG_TRACE,
-		 ("RTMPSetIndividualHT : Desired MCS = %d\n", DesiredMcs));
-	/* Check the validity of MCS */
-	if ((TxStream == 1)
-	    && ((DesiredMcs >= MCS_8) && (DesiredMcs <= MCS_15))) {
-		DBGPRINT(RT_DEBUG_WARN,
-			 ("RTMPSetIndividualHT: MCS(%d) is invalid in 1S, reset it as MCS_7\n",
-			  DesiredMcs));
-		DesiredMcs = MCS_7;
-	}
-
-	if ((pAd->CommonCfg.DesiredHtPhy.ChannelWidth == BW_20)
-	    && (DesiredMcs == MCS_32)) {
-		DBGPRINT(RT_DEBUG_WARN,
-			 ("RTMPSetIndividualHT: MCS_32 is only supported in 40-MHz, reset it as MCS_0\n"));
-		DesiredMcs = MCS_0;
-	}
-
-	pDesired_ht_phy->bHtEnable = TRUE;
-
-	/* Decide desired Tx MCS */
-	switch (TxStream) {
-	case 1:
-		if (DesiredMcs == MCS_AUTO) {
-			pDesired_ht_phy->MCSSet[0] = 0xff;
-			pDesired_ht_phy->MCSSet[1] = 0x00;
-		} else if (DesiredMcs <= MCS_7) {
-			pDesired_ht_phy->MCSSet[0] = 1 << DesiredMcs;
-			pDesired_ht_phy->MCSSet[1] = 0x00;
-		}
-		break;
-
-	case 2:
-		if (DesiredMcs == MCS_AUTO) {
-			pDesired_ht_phy->MCSSet[0] = 0xff;
-			pDesired_ht_phy->MCSSet[1] = 0xff;
-		} else if (DesiredMcs <= MCS_15) {
-			unsigned long mode;
-
-			mode = DesiredMcs / 8;
-			if (mode < 2)
-				pDesired_ht_phy->MCSSet[mode] =
-				    (1 << (DesiredMcs - mode * 8));
-		}
-		break;
-
-	case 3:		/* 3*3 */
-		if (DesiredMcs == MCS_AUTO) {
-			/* MCS0 ~ MCS23, 3 bytes */
-			pDesired_ht_phy->MCSSet[0] = 0xff;
-			pDesired_ht_phy->MCSSet[1] = 0xff;
-			pDesired_ht_phy->MCSSet[2] = 0xff;
-		} else if (DesiredMcs <= MCS_23) {
-			unsigned long mode;
-
-			mode = DesiredMcs / 8;
-			if (mode < 3)
-				pDesired_ht_phy->MCSSet[mode] =
-				    (1 << (DesiredMcs - mode * 8));
-		}
-		break;
-	}
-
-	if (pAd->CommonCfg.DesiredHtPhy.ChannelWidth == BW_40) {
-		if (DesiredMcs == MCS_AUTO || DesiredMcs == MCS_32)
-			pDesired_ht_phy->MCSSet[4] = 0x1;
-	}
-	/* update HT Rate setting */
-	if (pAd->OpMode == OPMODE_STA)
-		MlmeUpdateHtTxRates(pAd, BSS0);
-	else
-		MlmeUpdateHtTxRates(pAd, apidx);
-}
-
-/*
-	========================================================================
-	Routine Description:
-		Update HT IE from our capability.
-
-	Arguments:
-		Send all HT IE in beacon/probe rsp/assoc rsp/action frame.
-
-	========================================================================
-*/
-void RTMPUpdateHTIE(struct rt_ht_capability *pRtHt,
-		    u8 * pMcsSet,
-		    struct rt_ht_capability_ie * pHtCapability,
-		    struct rt_add_ht_info_ie * pAddHtInfo)
-{
-	RTMPZeroMemory(pHtCapability, sizeof(struct rt_ht_capability_ie));
-	RTMPZeroMemory(pAddHtInfo, sizeof(struct rt_add_ht_info_ie));
-
-	pHtCapability->HtCapInfo.ChannelWidth = pRtHt->ChannelWidth;
-	pHtCapability->HtCapInfo.MimoPs = pRtHt->MimoPs;
-	pHtCapability->HtCapInfo.GF = pRtHt->GF;
-	pHtCapability->HtCapInfo.ShortGIfor20 = pRtHt->ShortGIfor20;
-	pHtCapability->HtCapInfo.ShortGIfor40 = pRtHt->ShortGIfor40;
-	pHtCapability->HtCapInfo.TxSTBC = pRtHt->TxSTBC;
-	pHtCapability->HtCapInfo.RxSTBC = pRtHt->RxSTBC;
-	pHtCapability->HtCapInfo.AMsduSize = pRtHt->AmsduSize;
-	pHtCapability->HtCapParm.MaxRAmpduFactor = pRtHt->MaxRAmpduFactor;
-	pHtCapability->HtCapParm.MpduDensity = pRtHt->MpduDensity;
-
-	pAddHtInfo->AddHtInfo.ExtChanOffset = pRtHt->ExtChanOffset;
-	pAddHtInfo->AddHtInfo.RecomWidth = pRtHt->RecomWidth;
-	pAddHtInfo->AddHtInfo2.OperaionMode = pRtHt->OperaionMode;
-	pAddHtInfo->AddHtInfo2.NonGfPresent = pRtHt->NonGfPresent;
-	RTMPMoveMemory(pAddHtInfo->MCSSet, /*pRtHt->MCSSet */ pMcsSet, 4);	/* rt2860 only support MCS max=32, no need to copy all 16 uchar. */
-
-	DBGPRINT(RT_DEBUG_TRACE, ("RTMPUpdateHTIE <== \n"));
-}
-
-/*
-	========================================================================
-	Description:
-		Add Client security information into ASIC WCID table and IVEIV table.
-    Return:
-	========================================================================
-*/
-void RTMPAddWcidAttributeEntry(struct rt_rtmp_adapter *pAd,
-			       u8 BssIdx,
-			       u8 KeyIdx,
-			       u8 CipherAlg, struct rt_mac_table_entry *pEntry)
-{
-	u32 WCIDAttri = 0;
-	u16 offset;
-	u8 IVEIV = 0;
-	u16 Wcid = 0;
-
-	{
-		{
-			if (BssIdx > BSS0) {
-				DBGPRINT(RT_DEBUG_ERROR,
-					 ("RTMPAddWcidAttributeEntry: The BSS-index(%d) is out of range for Infra link. \n",
-					  BssIdx));
-				return;
-			}
-			/* 1.   In ADHOC mode, the AID is wcid number. And NO mesh link exists. */
-			/* 2.   In Infra mode, the AID:1 MUST be wcid of infra STA. */
-			/*                                         the AID:2~ assign to mesh link entry. */
-			if (pEntry)
-				Wcid = pEntry->Aid;
-			else
-				Wcid = MCAST_WCID;
-		}
-	}
-
-	/* Update WCID attribute table */
-	offset = MAC_WCID_ATTRIBUTE_BASE + (Wcid * HW_WCID_ATTRI_SIZE);
-
-	{
-		if (pEntry && pEntry->ValidAsMesh)
-			WCIDAttri = (CipherAlg << 1) | PAIRWISEKEYTABLE;
-		else
-			WCIDAttri = (CipherAlg << 1) | SHAREDKEYTABLE;
-	}
-
-	RTMP_IO_WRITE32(pAd, offset, WCIDAttri);
-
-	/* Update IV/EIV table */
-	offset = MAC_IVEIV_TABLE_BASE + (Wcid * HW_IVEIV_ENTRY_SIZE);
-
-	/* WPA mode */
-	if ((CipherAlg == CIPHER_TKIP) || (CipherAlg == CIPHER_TKIP_NO_MIC)
-	    || (CipherAlg == CIPHER_AES)) {
-		/* Eiv bit on. keyid always is 0 for pairwise key */
-		IVEIV = (KeyIdx << 6) | 0x20;
-	} else {
-		/* WEP KeyIdx is default tx key. */
-		IVEIV = (KeyIdx << 6);
-	}
-
-	/* For key index and ext IV bit, so only need to update the position(offset+3). */
-#ifdef RTMP_MAC_PCI
-	RTMP_IO_WRITE8(pAd, offset + 3, IVEIV);
-#endif /* RTMP_MAC_PCI // */
-#ifdef RTMP_MAC_USB
-	RTUSBMultiWrite_OneByte(pAd, offset + 3, &IVEIV);
-#endif /* RTMP_MAC_USB // */
-
-	DBGPRINT(RT_DEBUG_TRACE,
-		 ("RTMPAddWcidAttributeEntry: WCID #%d, KeyIndex #%d, Alg=%s\n",
-		  Wcid, KeyIdx, CipherName[CipherAlg]));
-	DBGPRINT(RT_DEBUG_TRACE, ("	WCIDAttri = 0x%x \n", WCIDAttri));
-
-}
-
-/*
-    ==========================================================================
-    Description:
-        Parse encryption type
-Arguments:
-    pAdapter                    Pointer to our adapter
-    wrq                         Pointer to the ioctl argument
-
-    Return Value:
-        None
-
-    Note:
-    ==========================================================================
-*/
-char *GetEncryptType(char enc)
-{
-	if (enc == Ndis802_11WEPDisabled)
-		return "NONE";
-	if (enc == Ndis802_11WEPEnabled)
-		return "WEP";
-	if (enc == Ndis802_11Encryption2Enabled)
-		return "TKIP";
-	if (enc == Ndis802_11Encryption3Enabled)
-		return "AES";
-	if (enc == Ndis802_11Encryption4Enabled)
-		return "TKIPAES";
-	else
-		return "UNKNOW";
-}
-
-char *GetAuthMode(char auth)
-{
-	if (auth == Ndis802_11AuthModeOpen)
-		return "OPEN";
-	if (auth == Ndis802_11AuthModeShared)
-		return "SHARED";
-	if (auth == Ndis802_11AuthModeAutoSwitch)
-		return "AUTOWEP";
-	if (auth == Ndis802_11AuthModeWPA)
-		return "WPA";
-	if (auth == Ndis802_11AuthModeWPAPSK)
-		return "WPAPSK";
-	if (auth == Ndis802_11AuthModeWPANone)
-		return "WPANONE";
-	if (auth == Ndis802_11AuthModeWPA2)
-		return "WPA2";
-	if (auth == Ndis802_11AuthModeWPA2PSK)
-		return "WPA2PSK";
-	if (auth == Ndis802_11AuthModeWPA1WPA2)
-		return "WPA1WPA2";
-	if (auth == Ndis802_11AuthModeWPA1PSKWPA2PSK)
-		return "WPA1PSKWPA2PSK";
-
-	return "UNKNOW";
-}
-
-int SetCommonHT(struct rt_rtmp_adapter *pAd)
-{
-	struct rt_oid_set_ht_phymode SetHT;
-
-	if (pAd->CommonCfg.PhyMode < PHY_11ABGN_MIXED)
-		return FALSE;
-
-	SetHT.PhyMode = pAd->CommonCfg.PhyMode;
-	SetHT.TransmitNo = ((u8)pAd->Antenna.field.TxPath);
-	SetHT.HtMode = (u8)pAd->CommonCfg.RegTransmitSetting.field.HTMODE;
-	SetHT.ExtOffset =
-	    (u8)pAd->CommonCfg.RegTransmitSetting.field.EXTCHA;
-	SetHT.MCS = MCS_AUTO;
-	SetHT.BW = (u8)pAd->CommonCfg.RegTransmitSetting.field.BW;
-	SetHT.STBC = (u8)pAd->CommonCfg.RegTransmitSetting.field.STBC;
-	SetHT.SHORTGI = (u8)pAd->CommonCfg.RegTransmitSetting.field.ShortGI;
-
-	RTMPSetHT(pAd, &SetHT);
-
-	return TRUE;
-}
-
-char *RTMPGetRalinkEncryModeStr(u16 encryMode)
-{
-	switch (encryMode) {
-	case Ndis802_11WEPDisabled:
-		return "NONE";
-	case Ndis802_11WEPEnabled:
-		return "WEP";
-	case Ndis802_11Encryption2Enabled:
-		return "TKIP";
-	case Ndis802_11Encryption3Enabled:
-		return "AES";
-	case Ndis802_11Encryption4Enabled:
-		return "TKIPAES";
-	default:
-		return "UNKNOW";
-	}
-}
diff -druN linux-2.6.39-libre/drivers/staging/rt2860/common/cmm_mac_pci.c linux-3.0-rc7-libre/drivers/staging/rt2860/common/cmm_mac_pci.c
--- linux-2.6.39-libre/drivers/staging/rt2860/common/cmm_mac_pci.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rt2860/common/cmm_mac_pci.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,1661 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, 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.             *
- *                                                                       *
- *************************************************************************
-*/
-
-#ifdef RTMP_MAC_PCI
-#include	"../rt_config.h"
-
-/*
-	========================================================================
-
-	Routine Description:
-		Allocate DMA memory blocks for send, receive
-
-	Arguments:
-		Adapter		Pointer to our adapter
-
-	Return Value:
-		NDIS_STATUS_SUCCESS
-		NDIS_STATUS_FAILURE
-		NDIS_STATUS_RESOURCES
-
-	IRQL = PASSIVE_LEVEL
-
-	Note:
-
-	========================================================================
-*/
-int RTMPAllocTxRxRingMemory(struct rt_rtmp_adapter *pAd)
-{
-	int Status = NDIS_STATUS_SUCCESS;
-	unsigned long RingBasePaHigh;
-	unsigned long RingBasePaLow;
-	void *RingBaseVa;
-	int index, num;
-	struct rt_txd * pTxD;
-	struct rt_rxd * pRxD;
-	unsigned long ErrorValue = 0;
-	struct rt_rtmp_tx_ring *pTxRing;
-	struct rt_rtmp_dmabuf *pDmaBuf;
-	void *pPacket;
-/*      PRTMP_REORDERBUF        pReorderBuf; */
-
-	DBGPRINT(RT_DEBUG_TRACE, ("--> RTMPAllocTxRxRingMemory\n"));
-	do {
-		/* */
-		/* Allocate all ring descriptors, include TxD, RxD, MgmtD. */
-		/* Although each size is different, to prevent cacheline and alignment */
-		/* issue, I intentional set them all to 64 bytes. */
-		/* */
-		for (num = 0; num < NUM_OF_TX_RING; num++) {
-			unsigned long BufBasePaHigh;
-			unsigned long BufBasePaLow;
-			void *BufBaseVa;
-
-			/* */
-			/* Allocate Tx ring descriptor's memory (5 TX rings = 4 ACs + 1 HCCA) */
-			/* */
-			pAd->TxDescRing[num].AllocSize =
-			    TX_RING_SIZE * TXD_SIZE;
-			RTMP_AllocateTxDescMemory(pAd, num,
-						  pAd->TxDescRing[num].
-						  AllocSize, FALSE,
-						  &pAd->TxDescRing[num].AllocVa,
-						  &pAd->TxDescRing[num].
-						  AllocPa);
-
-			if (pAd->TxDescRing[num].AllocVa == NULL) {
-				ErrorValue = ERRLOG_OUT_OF_SHARED_MEMORY;
-				DBGPRINT_ERR("Failed to allocate a big buffer\n");
-				Status = NDIS_STATUS_RESOURCES;
-				break;
-			}
-			/* Zero init this memory block */
-			NdisZeroMemory(pAd->TxDescRing[num].AllocVa,
-				       pAd->TxDescRing[num].AllocSize);
-
-			/* Save PA & VA for further operation */
-			RingBasePaHigh =
-			    RTMP_GetPhysicalAddressHigh(pAd->TxDescRing[num].
-							AllocPa);
-			RingBasePaLow =
-			    RTMP_GetPhysicalAddressLow(pAd->TxDescRing[num].
-						       AllocPa);
-			RingBaseVa = pAd->TxDescRing[num].AllocVa;
-
-			/* */
-			/* Allocate all 1st TXBuf's memory for this TxRing */
-			/* */
-			pAd->TxBufSpace[num].AllocSize =
-			    TX_RING_SIZE * TX_DMA_1ST_BUFFER_SIZE;
-			RTMP_AllocateFirstTxBuffer(pAd, num,
-						   pAd->TxBufSpace[num].
-						   AllocSize, FALSE,
-						   &pAd->TxBufSpace[num].
-						   AllocVa,
-						   &pAd->TxBufSpace[num].
-						   AllocPa);
-
-			if (pAd->TxBufSpace[num].AllocVa == NULL) {
-				ErrorValue = ERRLOG_OUT_OF_SHARED_MEMORY;
-				DBGPRINT_ERR("Failed to allocate a big buffer\n");
-				Status = NDIS_STATUS_RESOURCES;
-				break;
-			}
-			/* Zero init this memory block */
-			NdisZeroMemory(pAd->TxBufSpace[num].AllocVa,
-				       pAd->TxBufSpace[num].AllocSize);
-
-			/* Save PA & VA for further operation */
-			BufBasePaHigh =
-			    RTMP_GetPhysicalAddressHigh(pAd->TxBufSpace[num].
-							AllocPa);
-			BufBasePaLow =
-			    RTMP_GetPhysicalAddressLow(pAd->TxBufSpace[num].
-						       AllocPa);
-			BufBaseVa = pAd->TxBufSpace[num].AllocVa;
-
-			/* */
-			/* Initialize Tx Ring Descriptor and associated buffer memory */
-			/* */
-			pTxRing = &pAd->TxRing[num];
-			for (index = 0; index < TX_RING_SIZE; index++) {
-				pTxRing->Cell[index].pNdisPacket = NULL;
-				pTxRing->Cell[index].pNextNdisPacket = NULL;
-				/* Init Tx Ring Size, Va, Pa variables */
-				pTxRing->Cell[index].AllocSize = TXD_SIZE;
-				pTxRing->Cell[index].AllocVa = RingBaseVa;
-				RTMP_SetPhysicalAddressHigh(pTxRing->
-							    Cell[index].AllocPa,
-							    RingBasePaHigh);
-				RTMP_SetPhysicalAddressLow(pTxRing->Cell[index].
-							   AllocPa,
-							   RingBasePaLow);
-
-				/* Setup Tx Buffer size & address. only 802.11 header will store in this space */
-				pDmaBuf = &pTxRing->Cell[index].DmaBuf;
-				pDmaBuf->AllocSize = TX_DMA_1ST_BUFFER_SIZE;
-				pDmaBuf->AllocVa = BufBaseVa;
-				RTMP_SetPhysicalAddressHigh(pDmaBuf->AllocPa,
-							    BufBasePaHigh);
-				RTMP_SetPhysicalAddressLow(pDmaBuf->AllocPa,
-							   BufBasePaLow);
-
-				/* link the pre-allocated TxBuf to TXD */
-				pTxD =
-				    (struct rt_txd *) pTxRing->Cell[index].AllocVa;
-				pTxD->SDPtr0 = BufBasePaLow;
-				/* advance to next ring descriptor address */
-				pTxD->DMADONE = 1;
-				RingBasePaLow += TXD_SIZE;
-				RingBaseVa = (u8 *)RingBaseVa + TXD_SIZE;
-
-				/* advance to next TxBuf address */
-				BufBasePaLow += TX_DMA_1ST_BUFFER_SIZE;
-				BufBaseVa =
-				    (u8 *)BufBaseVa + TX_DMA_1ST_BUFFER_SIZE;
-			}
-			DBGPRINT(RT_DEBUG_TRACE,
-				 ("TxRing[%d]: total %d entry allocated\n", num,
-				  index));
-		}
-		if (Status == NDIS_STATUS_RESOURCES)
-			break;
-
-		/* */
-		/* Allocate MGMT ring descriptor's memory except Tx ring which allocated eariler */
-		/* */
-		pAd->MgmtDescRing.AllocSize = MGMT_RING_SIZE * TXD_SIZE;
-		RTMP_AllocateMgmtDescMemory(pAd,
-					    pAd->MgmtDescRing.AllocSize,
-					    FALSE,
-					    &pAd->MgmtDescRing.AllocVa,
-					    &pAd->MgmtDescRing.AllocPa);
-
-		if (pAd->MgmtDescRing.AllocVa == NULL) {
-			ErrorValue = ERRLOG_OUT_OF_SHARED_MEMORY;
-			DBGPRINT_ERR("Failed to allocate a big buffer\n");
-			Status = NDIS_STATUS_RESOURCES;
-			break;
-		}
-		/* Zero init this memory block */
-		NdisZeroMemory(pAd->MgmtDescRing.AllocVa,
-			       pAd->MgmtDescRing.AllocSize);
-
-		/* Save PA & VA for further operation */
-		RingBasePaHigh =
-		    RTMP_GetPhysicalAddressHigh(pAd->MgmtDescRing.AllocPa);
-		RingBasePaLow =
-		    RTMP_GetPhysicalAddressLow(pAd->MgmtDescRing.AllocPa);
-		RingBaseVa = pAd->MgmtDescRing.AllocVa;
-
-		/* */
-		/* Initialize MGMT Ring and associated buffer memory */
-		/* */
-		for (index = 0; index < MGMT_RING_SIZE; index++) {
-			pAd->MgmtRing.Cell[index].pNdisPacket = NULL;
-			pAd->MgmtRing.Cell[index].pNextNdisPacket = NULL;
-			/* Init MGMT Ring Size, Va, Pa variables */
-			pAd->MgmtRing.Cell[index].AllocSize = TXD_SIZE;
-			pAd->MgmtRing.Cell[index].AllocVa = RingBaseVa;
-			RTMP_SetPhysicalAddressHigh(pAd->MgmtRing.Cell[index].
-						    AllocPa, RingBasePaHigh);
-			RTMP_SetPhysicalAddressLow(pAd->MgmtRing.Cell[index].
-						   AllocPa, RingBasePaLow);
-
-			/* Offset to next ring descriptor address */
-			RingBasePaLow += TXD_SIZE;
-			RingBaseVa = (u8 *)RingBaseVa + TXD_SIZE;
-
-			/* link the pre-allocated TxBuf to TXD */
-			pTxD = (struct rt_txd *) pAd->MgmtRing.Cell[index].AllocVa;
-			pTxD->DMADONE = 1;
-
-			/* no pre-allocated buffer required in MgmtRing for scatter-gather case */
-		}
-		DBGPRINT(RT_DEBUG_TRACE,
-			 ("MGMT Ring: total %d entry allocated\n", index));
-
-		/* */
-		/* Allocate RX ring descriptor's memory except Tx ring which allocated eariler */
-		/* */
-		pAd->RxDescRing.AllocSize = RX_RING_SIZE * RXD_SIZE;
-		RTMP_AllocateRxDescMemory(pAd,
-					  pAd->RxDescRing.AllocSize,
-					  FALSE,
-					  &pAd->RxDescRing.AllocVa,
-					  &pAd->RxDescRing.AllocPa);
-
-		if (pAd->RxDescRing.AllocVa == NULL) {
-			ErrorValue = ERRLOG_OUT_OF_SHARED_MEMORY;
-			DBGPRINT_ERR("Failed to allocate a big buffer\n");
-			Status = NDIS_STATUS_RESOURCES;
-			break;
-		}
-		/* Zero init this memory block */
-		NdisZeroMemory(pAd->RxDescRing.AllocVa,
-			       pAd->RxDescRing.AllocSize);
-
-		DBGPRINT(RT_DEBUG_OFF,
-			 ("RX DESC %p  size = %ld\n", pAd->RxDescRing.AllocVa,
-			  pAd->RxDescRing.AllocSize));
-
-		/* Save PA & VA for further operation */
-		RingBasePaHigh =
-		    RTMP_GetPhysicalAddressHigh(pAd->RxDescRing.AllocPa);
-		RingBasePaLow =
-		    RTMP_GetPhysicalAddressLow(pAd->RxDescRing.AllocPa);
-		RingBaseVa = pAd->RxDescRing.AllocVa;
-
-		/* */
-		/* Initialize Rx Ring and associated buffer memory */
-		/* */
-		for (index = 0; index < RX_RING_SIZE; index++) {
-			/* Init RX Ring Size, Va, Pa variables */
-			pAd->RxRing.Cell[index].AllocSize = RXD_SIZE;
-			pAd->RxRing.Cell[index].AllocVa = RingBaseVa;
-			RTMP_SetPhysicalAddressHigh(pAd->RxRing.Cell[index].
-						    AllocPa, RingBasePaHigh);
-			RTMP_SetPhysicalAddressLow(pAd->RxRing.Cell[index].
-						   AllocPa, RingBasePaLow);
-
-			/*NdisZeroMemory(RingBaseVa, RXD_SIZE); */
-
-			/* Offset to next ring descriptor address */
-			RingBasePaLow += RXD_SIZE;
-			RingBaseVa = (u8 *)RingBaseVa + RXD_SIZE;
-
-			/* Setup Rx associated Buffer size & allocate share memory */
-			pDmaBuf = &pAd->RxRing.Cell[index].DmaBuf;
-			pDmaBuf->AllocSize = RX_BUFFER_AGGRESIZE;
-			pPacket = RTMP_AllocateRxPacketBuffer(pAd,
-							      pDmaBuf->
-							      AllocSize, FALSE,
-							      &pDmaBuf->AllocVa,
-							      &pDmaBuf->
-							      AllocPa);
-
-			/* keep allocated rx packet */
-			pAd->RxRing.Cell[index].pNdisPacket = pPacket;
-
-			/* Error handling */
-			if (pDmaBuf->AllocVa == NULL) {
-				ErrorValue = ERRLOG_OUT_OF_SHARED_MEMORY;
-				DBGPRINT_ERR("Failed to allocate RxRing's 1st buffer\n");
-				Status = NDIS_STATUS_RESOURCES;
-				break;
-			}
-			/* Zero init this memory block */
-			NdisZeroMemory(pDmaBuf->AllocVa, pDmaBuf->AllocSize);
-
-			/* Write RxD buffer address & allocated buffer length */
-			pRxD = (struct rt_rxd *) pAd->RxRing.Cell[index].AllocVa;
-			pRxD->SDP0 =
-			    RTMP_GetPhysicalAddressLow(pDmaBuf->AllocPa);
-			pRxD->DDONE = 0;
-
-		}
-
-		DBGPRINT(RT_DEBUG_TRACE,
-			 ("Rx Ring: total %d entry allocated\n", index));
-
-	} while (FALSE);
-
-	NdisZeroMemory(&pAd->FragFrame, sizeof(struct rt_fragment_frame));
-	pAd->FragFrame.pFragPacket =
-	    RTMP_AllocateFragPacketBuffer(pAd, RX_BUFFER_NORMSIZE);
-
-	if (pAd->FragFrame.pFragPacket == NULL) {
-		Status = NDIS_STATUS_RESOURCES;
-	}
-
-	if (Status != NDIS_STATUS_SUCCESS) {
-		/* Log error inforamtion */
-		NdisWriteErrorLogEntry(pAd->AdapterHandle,
-				       NDIS_ERROR_CODE_OUT_OF_RESOURCES,
-				       1, ErrorValue);
-	}
-	/* Following code segment get from original func:NICInitTxRxRingAndBacklogQueue(), now should integrate it to here. */
-	{
-		DBGPRINT(RT_DEBUG_TRACE,
-			 ("--> NICInitTxRxRingAndBacklogQueue\n"));
-
-/*
-		// Disable DMA.
-		RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &GloCfg.word);
-		GloCfg.word &= 0xff0;
-		GloCfg.field.EnTXWriteBackDDONE =1;
-		RTMP_IO_WRITE32(pAd, WPDMA_GLO_CFG, GloCfg.word);
-*/
-
-		/* Initialize all transmit related software queues */
-		for (index = 0; index < NUM_OF_TX_RING; index++) {
-			InitializeQueueHeader(&pAd->TxSwQueue[index]);
-			/* Init TX rings index pointer */
-			pAd->TxRing[index].TxSwFreeIdx = 0;
-			pAd->TxRing[index].TxCpuIdx = 0;
-			/*RTMP_IO_WRITE32(pAd, (TX_CTX_IDX0 + i * 0x10) ,  pAd->TxRing[i].TX_CTX_IDX); */
-		}
-
-		/* Init RX Ring index pointer */
-		pAd->RxRing.RxSwReadIdx = 0;
-		pAd->RxRing.RxCpuIdx = RX_RING_SIZE - 1;
-		/*RTMP_IO_WRITE32(pAd, RX_CRX_IDX, pAd->RxRing.RX_CRX_IDX0); */
-
-		/* init MGMT ring index pointer */
-		pAd->MgmtRing.TxSwFreeIdx = 0;
-		pAd->MgmtRing.TxCpuIdx = 0;
-
-		pAd->PrivateInfo.TxRingFullCnt = 0;
-
-		DBGPRINT(RT_DEBUG_TRACE,
-			 ("<-- NICInitTxRxRingAndBacklogQueue\n"));
-	}
-
-	DBGPRINT_S(Status,
-		   ("<-- RTMPAllocTxRxRingMemory, Status=%x\n", Status));
-	return Status;
-}
-
-/*
-	========================================================================
-
-	Routine Description:
-		Reset NIC Asics. Call after rest DMA. So reset TX_CTX_IDX to zero.
-
-	Arguments:
-		Adapter						Pointer to our adapter
-
-	Return Value:
-		None
-
-	IRQL = PASSIVE_LEVEL
-	IRQL = DISPATCH_LEVEL
-
-	Note:
-		Reset NIC to initial state AS IS system boot up time.
-
-	========================================================================
-*/
-void RTMPRingCleanUp(struct rt_rtmp_adapter *pAd, u8 RingType)
-{
-	struct rt_txd * pTxD;
-	struct rt_rxd * pRxD;
-	struct rt_queue_entry *pEntry;
-	void *pPacket;
-	int i;
-	struct rt_rtmp_tx_ring *pTxRing;
-	unsigned long IrqFlags;
-	/*u32                        RxSwReadIdx; */
-
-	DBGPRINT(RT_DEBUG_TRACE,
-		 ("RTMPRingCleanUp(RingIdx=%d, Pending-NDIS=%ld)\n", RingType,
-		  pAd->RalinkCounters.PendingNdisPacketCount));
-	switch (RingType) {
-	case QID_AC_BK:
-	case QID_AC_BE:
-	case QID_AC_VI:
-	case QID_AC_VO:
-
-		pTxRing = &pAd->TxRing[RingType];
-
-		RTMP_IRQ_LOCK(&pAd->irq_lock, IrqFlags);
-		/* We have to clean all descriptors in case some error happened with reset */
-		for (i = 0; i < TX_RING_SIZE; i++)	/* We have to scan all TX ring */
-		{
-			pTxD = (struct rt_txd *) pTxRing->Cell[i].AllocVa;
-
-			pPacket = (void *)pTxRing->Cell[i].pNdisPacket;
-			/* release scatter-and-gather char */
-			if (pPacket) {
-				RELEASE_NDIS_PACKET(pAd, pPacket,
-						    NDIS_STATUS_FAILURE);
-				pTxRing->Cell[i].pNdisPacket = NULL;
-			}
-
-			pPacket =
-			    (void *)pTxRing->Cell[i].pNextNdisPacket;
-			/* release scatter-and-gather char */
-			if (pPacket) {
-				RELEASE_NDIS_PACKET(pAd, pPacket,
-						    NDIS_STATUS_FAILURE);
-				pTxRing->Cell[i].pNextNdisPacket = NULL;
-			}
-		}
-
-		RTMP_IO_READ32(pAd, TX_DTX_IDX0 + RingType * 0x10,
-			       &pTxRing->TxDmaIdx);
-		pTxRing->TxSwFreeIdx = pTxRing->TxDmaIdx;
-		pTxRing->TxCpuIdx = pTxRing->TxDmaIdx;
-		RTMP_IO_WRITE32(pAd, TX_CTX_IDX0 + RingType * 0x10,
-				pTxRing->TxCpuIdx);
-
-		RTMP_IRQ_UNLOCK(&pAd->irq_lock, IrqFlags);
-
-		RTMP_IRQ_LOCK(&pAd->irq_lock, IrqFlags);
-		while (pAd->TxSwQueue[RingType].Head != NULL) {
-			pEntry = RemoveHeadQueue(&pAd->TxSwQueue[RingType]);
-			pPacket = QUEUE_ENTRY_TO_PACKET(pEntry);
-			RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
-			DBGPRINT(RT_DEBUG_TRACE,
-				 ("Release 1 NDIS packet from s/w backlog queue\n"));
-		}
-		RTMP_IRQ_UNLOCK(&pAd->irq_lock, IrqFlags);
-		break;
-
-	case QID_MGMT:
-		/* We have to clean all descriptors in case some error happened with reset */
-		NdisAcquireSpinLock(&pAd->MgmtRingLock);
-
-		for (i = 0; i < MGMT_RING_SIZE; i++) {
-			pTxD = (struct rt_txd *) pAd->MgmtRing.Cell[i].AllocVa;
-
-			pPacket =
-			    (void *)pAd->MgmtRing.Cell[i].pNdisPacket;
-			/* rlease scatter-and-gather char */
-			if (pPacket) {
-				PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr0,
-						 pTxD->SDLen0,
-						 PCI_DMA_TODEVICE);
-				RELEASE_NDIS_PACKET(pAd, pPacket,
-						    NDIS_STATUS_FAILURE);
-			}
-			pAd->MgmtRing.Cell[i].pNdisPacket = NULL;
-
-			pPacket =
-			    (void *)pAd->MgmtRing.Cell[i].
-			    pNextNdisPacket;
-			/* release scatter-and-gather char */
-			if (pPacket) {
-				PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr1,
-						 pTxD->SDLen1,
-						 PCI_DMA_TODEVICE);
-				RELEASE_NDIS_PACKET(pAd, pPacket,
-						    NDIS_STATUS_FAILURE);
-			}
-			pAd->MgmtRing.Cell[i].pNextNdisPacket = NULL;
-
-		}
-
-		RTMP_IO_READ32(pAd, TX_MGMTDTX_IDX, &pAd->MgmtRing.TxDmaIdx);
-		pAd->MgmtRing.TxSwFreeIdx = pAd->MgmtRing.TxDmaIdx;
-		pAd->MgmtRing.TxCpuIdx = pAd->MgmtRing.TxDmaIdx;
-		RTMP_IO_WRITE32(pAd, TX_MGMTCTX_IDX, pAd->MgmtRing.TxCpuIdx);
-
-		NdisReleaseSpinLock(&pAd->MgmtRingLock);
-		pAd->RalinkCounters.MgmtRingFullCount = 0;
-		break;
-
-	case QID_RX:
-		/* We have to clean all descriptors in case some error happened with reset */
-		NdisAcquireSpinLock(&pAd->RxRingLock);
-
-		for (i = 0; i < RX_RING_SIZE; i++) {
-			pRxD = (struct rt_rxd *) pAd->RxRing.Cell[i].AllocVa;
-			pRxD->DDONE = 0;
-		}
-
-		RTMP_IO_READ32(pAd, RX_DRX_IDX, &pAd->RxRing.RxDmaIdx);
-		pAd->RxRing.RxSwReadIdx = pAd->RxRing.RxDmaIdx;
-		pAd->RxRing.RxCpuIdx =
-		    ((pAd->RxRing.RxDmaIdx ==
-		      0) ? (RX_RING_SIZE - 1) : (pAd->RxRing.RxDmaIdx - 1));
-		RTMP_IO_WRITE32(pAd, RX_CRX_IDX, pAd->RxRing.RxCpuIdx);
-
-		NdisReleaseSpinLock(&pAd->RxRingLock);
-		break;
-
-	default:
-		break;
-	}
-}
-
-void RTMPFreeTxRxRingMemory(struct rt_rtmp_adapter *pAd)
-{
-	int index, num, j;
-	struct rt_rtmp_tx_ring *pTxRing;
-	struct rt_txd * pTxD;
-	void *pPacket;
-	unsigned int IrqFlags;
-
-	/*struct os_cookie *pObj =(struct os_cookie *)pAd->OS_Cookie; */
-
-	DBGPRINT(RT_DEBUG_TRACE, ("--> RTMPFreeTxRxRingMemory\n"));
-
-	/* Free TxSwQueue Packet */
-	for (index = 0; index < NUM_OF_TX_RING; index++) {
-		struct rt_queue_entry *pEntry;
-		void *pPacket;
-		struct rt_queue_header *pQueue;
-
-		RTMP_IRQ_LOCK(&pAd->irq_lock, IrqFlags);
-		pQueue = &pAd->TxSwQueue[index];
-		while (pQueue->Head) {
-			pEntry = RemoveHeadQueue(pQueue);
-			pPacket = QUEUE_ENTRY_TO_PACKET(pEntry);
-			RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
-		}
-		RTMP_IRQ_UNLOCK(&pAd->irq_lock, IrqFlags);
-	}
-
-	/* Free Tx Ring Packet */
-	for (index = 0; index < NUM_OF_TX_RING; index++) {
-		pTxRing = &pAd->TxRing[index];
-
-		for (j = 0; j < TX_RING_SIZE; j++) {
-			pTxD = (struct rt_txd *) (pTxRing->Cell[j].AllocVa);
-			pPacket = pTxRing->Cell[j].pNdisPacket;
-
-			if (pPacket) {
-				PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr0,
-						 pTxD->SDLen0,
-						 PCI_DMA_TODEVICE);
-				RELEASE_NDIS_PACKET(pAd, pPacket,
-						    NDIS_STATUS_SUCCESS);
-			}
-			/*Always assign pNdisPacket as NULL after clear */
-			pTxRing->Cell[j].pNdisPacket = NULL;
-
-			pPacket = pTxRing->Cell[j].pNextNdisPacket;
-
-			if (pPacket) {
-				PCI_UNMAP_SINGLE(pAd, pTxD->SDPtr1,
-						 pTxD->SDLen1,
-						 PCI_DMA_TODEVICE);
-				RELEASE_NDIS_PACKET(pAd, pPacket,
-						    NDIS_STATUS_SUCCESS);
-			}
-			/*Always assign pNextNdisPacket as NULL after clear */
-			pTxRing->Cell[pTxRing->TxSwFreeIdx].pNextNdisPacket =
-			    NULL;
-
-		}
-	}
-
-	for (index = RX_RING_SIZE - 1; index >= 0; index--) {
-		if ((pAd->RxRing.Cell[index].DmaBuf.AllocVa)
-		    && (pAd->RxRing.Cell[index].pNdisPacket)) {
-			PCI_UNMAP_SINGLE(pAd,
-					 pAd->RxRing.Cell[index].DmaBuf.AllocPa,
-					 pAd->RxRing.Cell[index].DmaBuf.
-					 AllocSize, PCI_DMA_FROMDEVICE);
-			RELEASE_NDIS_PACKET(pAd,
-					    pAd->RxRing.Cell[index].pNdisPacket,
-					    NDIS_STATUS_SUCCESS);
-		}
-	}
-	NdisZeroMemory(pAd->RxRing.Cell, RX_RING_SIZE * sizeof(struct rt_rtmp_dmacb));
-
-	if (pAd->RxDescRing.AllocVa) {
-		RTMP_FreeDescMemory(pAd, pAd->RxDescRing.AllocSize,
-				    pAd->RxDescRing.AllocVa,
-				    pAd->RxDescRing.AllocPa);
-	}
-	NdisZeroMemory(&pAd->RxDescRing, sizeof(struct rt_rtmp_dmabuf));
-
-	if (pAd->MgmtDescRing.AllocVa) {
-		RTMP_FreeDescMemory(pAd, pAd->MgmtDescRing.AllocSize,
-				    pAd->MgmtDescRing.AllocVa,
-				    pAd->MgmtDescRing.AllocPa);
-	}
-	NdisZeroMemory(&pAd->MgmtDescRing, sizeof(struct rt_rtmp_dmabuf));
-
-	for (num = 0; num < NUM_OF_TX_RING; num++) {
-		if (pAd->TxBufSpace[num].AllocVa) {
-			RTMP_FreeFirstTxBuffer(pAd,
-					       pAd->TxBufSpace[num].AllocSize,
-					       FALSE,
-					       pAd->TxBufSpace[num].AllocVa,
-					       pAd->TxBufSpace[num].AllocPa);
-		}
-		NdisZeroMemory(&pAd->TxBufSpace[num], sizeof(struct rt_rtmp_dmabuf));
-
-		if (pAd->TxDescRing[num].AllocVa) {
-			RTMP_FreeDescMemory(pAd, pAd->TxDescRing[num].AllocSize,
-					    pAd->TxDescRing[num].AllocVa,
-					    pAd->TxDescRing[num].AllocPa);
-		}
-		NdisZeroMemory(&pAd->TxDescRing[num], sizeof(struct rt_rtmp_dmabuf));
-	}
-
-	if (pAd->FragFrame.pFragPacket)
-		RELEASE_NDIS_PACKET(pAd, pAd->FragFrame.pFragPacket,
-				    NDIS_STATUS_SUCCESS);
-
-	DBGPRINT(RT_DEBUG_TRACE, ("<-- RTMPFreeTxRxRingMemory\n"));
-}
-
-/***************************************************************************
-  *
-  *	register related procedures.
-  *
-  **************************************************************************/
-/*
-========================================================================
-Routine Description:
-    Disable DMA.
-
-Arguments:
-	*pAd				the raxx interface data pointer
-
-Return Value:
-	None
-
-Note:
-========================================================================
-*/
-void RT28XXDMADisable(struct rt_rtmp_adapter *pAd)
-{
-	WPDMA_GLO_CFG_STRUC GloCfg;
-
-	RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &GloCfg.word);
-	GloCfg.word &= 0xff0;
-	GloCfg.field.EnTXWriteBackDDONE = 1;
-	RTMP_IO_WRITE32(pAd, WPDMA_GLO_CFG, GloCfg.word);
-}
-
-/*
-========================================================================
-Routine Description:
-    Enable DMA.
-
-Arguments:
-	*pAd				the raxx interface data pointer
-
-Return Value:
-	None
-
-Note:
-========================================================================
-*/
-void RT28XXDMAEnable(struct rt_rtmp_adapter *pAd)
-{
-	WPDMA_GLO_CFG_STRUC GloCfg;
-	int i = 0;
-
-	RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x4);
-	do {
-		RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &GloCfg.word);
-		if ((GloCfg.field.TxDMABusy == 0)
-		    && (GloCfg.field.RxDMABusy == 0))
-			break;
-
-		DBGPRINT(RT_DEBUG_TRACE, ("==>  DMABusy\n"));
-		RTMPusecDelay(1000);
-		i++;
-	} while (i < 200);
-
-	RTMPusecDelay(50);
-
-	GloCfg.field.EnTXWriteBackDDONE = 1;
-	GloCfg.field.WPDMABurstSIZE = 2;
-	GloCfg.field.EnableRxDMA = 1;
-	GloCfg.field.EnableTxDMA = 1;
-
-	DBGPRINT(RT_DEBUG_TRACE,
-		 ("<== WRITE DMA offset 0x208 = 0x%x\n", GloCfg.word));
-	RTMP_IO_WRITE32(pAd, WPDMA_GLO_CFG, GloCfg.word);
-
-}
-
-BOOLEAN AsicCheckCommanOk(struct rt_rtmp_adapter *pAd, u8 Command)
-{
-	u32 CmdStatus = 0, CID = 0, i;
-	u32 ThisCIDMask = 0;
-
-	i = 0;
-	do {
-		RTMP_IO_READ32(pAd, H2M_MAILBOX_CID, &CID);
-		/* Find where the command is. Because this is randomly specified by firmware. */
-		if ((CID & CID0MASK) == Command) {
-			ThisCIDMask = CID0MASK;
-			break;
-		} else if ((((CID & CID1MASK) >> 8) & 0xff) == Command) {
-			ThisCIDMask = CID1MASK;
-			break;
-		} else if ((((CID & CID2MASK) >> 16) & 0xff) == Command) {
-			ThisCIDMask = CID2MASK;
-			break;
-		} else if ((((CID & CID3MASK) >> 24) & 0xff) == Command) {
-			ThisCIDMask = CID3MASK;
-			break;
-		}
-
-		RTMPusecDelay(100);
-		i++;
-	} while (i < 200);
-
-	/* Get CommandStatus Value */
-	RTMP_IO_READ32(pAd, H2M_MAILBOX_STATUS, &CmdStatus);
-
-	/* This command's status is at the same position as command. So AND command position's bitmask to read status. */
-	if (i < 200) {
-		/* If Status is 1, the command is success. */
-		if (((CmdStatus & ThisCIDMask) == 0x1)
-		    || ((CmdStatus & ThisCIDMask) == 0x100)
-		    || ((CmdStatus & ThisCIDMask) == 0x10000)
-		    || ((CmdStatus & ThisCIDMask) == 0x1000000)) {
-			DBGPRINT(RT_DEBUG_TRACE,
-				 ("--> AsicCheckCommanOk CID = 0x%x, CmdStatus= 0x%x \n",
-				  CID, CmdStatus));
-			RTMP_IO_WRITE32(pAd, H2M_MAILBOX_STATUS, 0xffffffff);
-			RTMP_IO_WRITE32(pAd, H2M_MAILBOX_CID, 0xffffffff);
-			return TRUE;
-		}
-		DBGPRINT(RT_DEBUG_TRACE,
-			 ("--> AsicCheckCommanFail1 CID = 0x%x, CmdStatus= 0x%x \n",
-			  CID, CmdStatus));
-	} else {
-		DBGPRINT(RT_DEBUG_TRACE,
-			 ("--> AsicCheckCommanFail2 Timeout Command = %d, CmdStatus= 0x%x \n",
-			  Command, CmdStatus));
-	}
-	/* Clear Command and Status. */
-	RTMP_IO_WRITE32(pAd, H2M_MAILBOX_STATUS, 0xffffffff);
-	RTMP_IO_WRITE32(pAd, H2M_MAILBOX_CID, 0xffffffff);
-
-	return FALSE;
-}
-
-/*
-========================================================================
-Routine Description:
-    Write Beacon buffer to Asic.
-
-Arguments:
-	*pAd				the raxx interface data pointer
-
-Return Value:
-	None
-
-Note:
-========================================================================
-*/
-void RT28xx_UpdateBeaconToAsic(struct rt_rtmp_adapter *pAd,
-			       int apidx,
-			       unsigned long FrameLen, unsigned long UpdatePos)
-{
-	unsigned long CapInfoPos = 0;
-	u8 *ptr, *ptr_update, *ptr_capinfo;
-	u32 i;
-	BOOLEAN bBcnReq = FALSE;
-	u8 bcn_idx = 0;
-
-	{
-		DBGPRINT(RT_DEBUG_ERROR,
-			 ("%s() : No valid Interface be found.\n", __func__));
-		return;
-	}
-
-	/*if ((pAd->WdsTab.Mode == WDS_BRIDGE_MODE) */
-	/*      || ((pAd->ApCfg.MBSSID[apidx].MSSIDDev == NULL) */
-	/*              || !(pAd->ApCfg.MBSSID[apidx].MSSIDDev->flags & IFF_UP)) */
-	/*      ) */
-	if (bBcnReq == FALSE) {
-		/* when the ra interface is down, do not send its beacon frame */
-		/* clear all zero */
-		for (i = 0; i < TXWI_SIZE; i += 4)
-			RTMP_IO_WRITE32(pAd, pAd->BeaconOffset[bcn_idx] + i,
-					0x00);
-	} else {
-		ptr = (u8 *)& pAd->BeaconTxWI;
-		for (i = 0; i < TXWI_SIZE; i += 4)	/* 16-byte TXWI field */
-		{
-			u32 longptr =
-			    *ptr + (*(ptr + 1) << 8) + (*(ptr + 2) << 16) +
-			    (*(ptr + 3) << 24);
-			RTMP_IO_WRITE32(pAd, pAd->BeaconOffset[bcn_idx] + i,
-					longptr);
-			ptr += 4;
-		}
-
-		/* Update CapabilityInfo in Beacon */
-		for (i = CapInfoPos; i < (CapInfoPos + 2); i++) {
-			RTMP_IO_WRITE8(pAd,
-				       pAd->BeaconOffset[bcn_idx] + TXWI_SIZE +
-				       i, *ptr_capinfo);
-			ptr_capinfo++;
-		}
-
-		if (FrameLen > UpdatePos) {
-			for (i = UpdatePos; i < (FrameLen); i++) {
-				RTMP_IO_WRITE8(pAd,
-					       pAd->BeaconOffset[bcn_idx] +
-					       TXWI_SIZE + i, *ptr_update);
-				ptr_update++;
-			}
-		}
-
-	}
-
-}
-
-void RT28xxPciStaAsicForceWakeup(struct rt_rtmp_adapter *pAd, IN BOOLEAN bFromTx)
-{
-	AUTO_WAKEUP_STRUC AutoWakeupCfg;
-
-	if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
-		return;
-
-	if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WAKEUP_NOW)) {
-		DBGPRINT(RT_DEBUG_TRACE, ("waking up now!\n"));
-		return;
-	}
-
-	OPSTATUS_SET_FLAG(pAd, fOP_STATUS_WAKEUP_NOW);
-
-	RTMP_CLEAR_PSFLAG(pAd, fRTMP_PS_GO_TO_SLEEP_NOW);
-
-	if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE)
-	    && pAd->StaCfg.PSControl.field.EnableNewPS == TRUE) {
-		/* Support PCIe Advance Power Save */
-		if (bFromTx == TRUE && (pAd->Mlme.bPsPollTimerRunning == TRUE)) {
-			pAd->Mlme.bPsPollTimerRunning = FALSE;
-			RTMPPCIeLinkCtrlValueRestore(pAd, RESTORE_WAKEUP);
-			RTMPusecDelay(3000);
-			DBGPRINT(RT_DEBUG_TRACE,
-				 ("=======AsicForceWakeup===bFromTx\n"));
-		}
-
-		AutoWakeupCfg.word = 0;
-		RTMP_IO_WRITE32(pAd, AUTO_WAKEUP_CFG, AutoWakeupCfg.word);
-
-		if (RT28xxPciAsicRadioOn(pAd, DOT11POWERSAVE)) {
-#ifdef PCIE_PS_SUPPORT
-			/* add by johnli, RF power sequence setup, load RF normal operation-mode setup */
-			if ((IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd))
-			    && IS_VERSION_AFTER_F(pAd)) {
-				struct rt_rtmp_chip_op *pChipOps = &pAd->chipOps;
-
-				if (pChipOps->AsicReverseRfFromSleepMode)
-					pChipOps->
-					    AsicReverseRfFromSleepMode(pAd);
-			} else
-#endif /* PCIE_PS_SUPPORT // */
-			{
-				/* end johnli */
-				/* In Radio Off, we turn off RF clk, So now need to call ASICSwitchChannel again. */
-				if (INFRA_ON(pAd)
-				    && (pAd->CommonCfg.CentralChannel !=
-					pAd->CommonCfg.Channel)
-				    && (pAd->MlmeAux.HtCapability.HtCapInfo.
-					ChannelWidth == BW_40)) {
-					/* Must using 40MHz. */
-					AsicSwitchChannel(pAd,
-							  pAd->CommonCfg.
-							  CentralChannel,
-							  FALSE);
-					AsicLockChannel(pAd,
-							pAd->CommonCfg.
-							CentralChannel);
-				} else {
-					/* Must using 20MHz. */
-					AsicSwitchChannel(pAd,
-							  pAd->CommonCfg.
-							  Channel, FALSE);
-					AsicLockChannel(pAd,
-							pAd->CommonCfg.Channel);
-				}
-			}
-		}
-#ifdef PCIE_PS_SUPPORT
-		/* 3090 MCU Wakeup command needs more time to be stable. */
-		/* Before stable, don't issue other MCU command to prevent from firmware error. */
-		if (((IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd))
-		     && IS_VERSION_AFTER_F(pAd)) && IS_VERSION_AFTER_F(pAd)
-		    && (pAd->StaCfg.PSControl.field.rt30xxPowerMode == 3)
-		    && (pAd->StaCfg.PSControl.field.EnableNewPS == TRUE)) {
-			DBGPRINT(RT_DEBUG_TRACE,
-				 ("<==RT28xxPciStaAsicForceWakeup::Release the MCU Lock(3090)\n"));
-			RTMP_SEM_LOCK(&pAd->McuCmdLock);
-			pAd->brt30xxBanMcuCmd = FALSE;
-			RTMP_SEM_UNLOCK(&pAd->McuCmdLock);
-		}
-#endif /* PCIE_PS_SUPPORT // */
-	} else {
-		/* PCI, 2860-PCIe */
-		DBGPRINT(RT_DEBUG_TRACE,
-			 ("<==RT28xxPciStaAsicForceWakeup::Original PCI Power Saving\n"));
-		AsicSendCommandToMcu(pAd, 0x31, 0xff, 0x00, 0x02);
-		AutoWakeupCfg.word = 0;
-		RTMP_IO_WRITE32(pAd, AUTO_WAKEUP_CFG, AutoWakeupCfg.word);
-	}
-
-	OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_DOZE);
-	OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_WAKEUP_NOW);
-	DBGPRINT(RT_DEBUG_TRACE, ("<=======RT28xxPciStaAsicForceWakeup\n"));
-}
-
-void RT28xxPciStaAsicSleepThenAutoWakeup(struct rt_rtmp_adapter *pAd,
-					 u16 TbttNumToNextWakeUp)
-{
-	BOOLEAN brc;
-
-	if (pAd->StaCfg.bRadio == FALSE) {
-		OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_DOZE);
-		return;
-	}
-	if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE)
-	    && pAd->StaCfg.PSControl.field.EnableNewPS == TRUE) {
-		unsigned long Now = 0;
-		if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WAKEUP_NOW)) {
-			DBGPRINT(RT_DEBUG_TRACE, ("waking up now!\n"));
-			OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_DOZE);
-			return;
-		}
-
-		NdisGetSystemUpTime(&Now);
-		/* If last send NULL fram time is too close to this receiving beacon (within 8ms), don't go to sleep for this DTM. */
-		/* Because Some AP can't queuing outgoing frames immediately. */
-		if (((pAd->Mlme.LastSendNULLpsmTime + 8) >= Now)
-		    && (pAd->Mlme.LastSendNULLpsmTime <= Now)) {
-			DBGPRINT(RT_DEBUG_TRACE,
-				 ("Now = %lu, LastSendNULLpsmTime=%lu :  RxCountSinceLastNULL = %lu. \n",
-				  Now, pAd->Mlme.LastSendNULLpsmTime,
-				  pAd->RalinkCounters.RxCountSinceLastNULL));
-			return;
-		} else if ((pAd->RalinkCounters.RxCountSinceLastNULL > 0)
-			   &&
-			   ((pAd->Mlme.LastSendNULLpsmTime +
-			     pAd->CommonCfg.BeaconPeriod) >= Now)) {
-			DBGPRINT(RT_DEBUG_TRACE,
-				 ("Now = %lu, LastSendNULLpsmTime=%lu: RxCountSinceLastNULL = %lu > 0 \n",
-				  Now, pAd->Mlme.LastSendNULLpsmTime,
-				  pAd->RalinkCounters.RxCountSinceLastNULL));
-			return;
-		}
-
-		brc =
-		    RT28xxPciAsicRadioOff(pAd, DOT11POWERSAVE,
-					  TbttNumToNextWakeUp);
-		if (brc == TRUE)
-			OPSTATUS_SET_FLAG(pAd, fOP_STATUS_DOZE);
-	} else {
-		AUTO_WAKEUP_STRUC AutoWakeupCfg;
-		/* we have decided to SLEEP, so at least do it for a BEACON period. */
-		if (TbttNumToNextWakeUp == 0)
-			TbttNumToNextWakeUp = 1;
-
-		/*RTMP_IO_WRITE32(pAd, INT_MASK_CSR, AutoWakeupInt); */
-
-		AutoWakeupCfg.word = 0;
-		RTMP_IO_WRITE32(pAd, AUTO_WAKEUP_CFG, AutoWakeupCfg.word);
-		AutoWakeupCfg.field.NumofSleepingTbtt = TbttNumToNextWakeUp - 1;
-		AutoWakeupCfg.field.EnableAutoWakeup = 1;
-		AutoWakeupCfg.field.AutoLeadTime = 5;
-		RTMP_IO_WRITE32(pAd, AUTO_WAKEUP_CFG, AutoWakeupCfg.word);
-		AsicSendCommandToMcu(pAd, 0x30, 0xff, 0xff, 0x00);	/* send POWER-SAVE command to MCU. Timeout 40us. */
-		OPSTATUS_SET_FLAG(pAd, fOP_STATUS_DOZE);
-		DBGPRINT(RT_DEBUG_TRACE,
-			 ("<-- %s, TbttNumToNextWakeUp=%d \n", __func__,
-			  TbttNumToNextWakeUp));
-	}
-
-}
-
-void PsPollWakeExec(void *SystemSpecific1,
-		    void *FunctionContext,
-		    void *SystemSpecific2, void *SystemSpecific3)
-{
-	struct rt_rtmp_adapter *pAd = (struct rt_rtmp_adapter *)FunctionContext;
-	unsigned long flags;
-
-	DBGPRINT(RT_DEBUG_TRACE, ("-->PsPollWakeExec \n"));
-	RTMP_INT_LOCK(&pAd->irq_lock, flags);
-	if (pAd->Mlme.bPsPollTimerRunning) {
-		RTMPPCIeLinkCtrlValueRestore(pAd, RESTORE_WAKEUP);
-	}
-	pAd->Mlme.bPsPollTimerRunning = FALSE;
-	RTMP_INT_UNLOCK(&pAd->irq_lock, flags);
-#ifdef PCIE_PS_SUPPORT
-	/* For rt30xx power solution 3, Use software timer to wake up in psm. So call */
-	/* AsicForceWakeup here instead of handling twakeup interrupt. */
-	if (((IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd))
-	     && IS_VERSION_AFTER_F(pAd))
-	    && (pAd->StaCfg.PSControl.field.rt30xxPowerMode == 3)
-	    && (pAd->StaCfg.PSControl.field.EnableNewPS == TRUE)) {
-		DBGPRINT(RT_DEBUG_TRACE,
-			 ("<--PsPollWakeExec::3090 calls AsicForceWakeup(pAd, DOT11POWERSAVE) in advance \n"));
-		AsicForceWakeup(pAd, DOT11POWERSAVE);
-	}
-#endif /* PCIE_PS_SUPPORT // */
-}
-
-void RadioOnExec(void *SystemSpecific1,
-		 void *FunctionContext,
-		 void *SystemSpecific2, void *SystemSpecific3)
-{
-	struct rt_rtmp_adapter *pAd = (struct rt_rtmp_adapter *)FunctionContext;
-	struct rt_rtmp_chip_op *pChipOps = &pAd->chipOps;
-	WPDMA_GLO_CFG_STRUC DmaCfg;
-	BOOLEAN Cancelled;
-
-	if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE)) {
-		DBGPRINT(RT_DEBUG_TRACE,
-			 ("-->RadioOnExec() return on fOP_STATUS_DOZE == TRUE; \n"));
-/*KH Debug: Add the compile flag "RT2860 and condition */
-#ifdef RTMP_PCI_SUPPORT
-		if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE)
-		    && pAd->StaCfg.PSControl.field.EnableNewPS == TRUE)
-			RTMPSetTimer(&pAd->Mlme.RadioOnOffTimer, 10);
-#endif /* RTMP_PCI_SUPPORT // */
-		return;
-	}
-
-	if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) {
-		DBGPRINT(RT_DEBUG_TRACE,
-			 ("-->RadioOnExec() return on SCAN_IN_PROGRESS; \n"));
-#ifdef RTMP_PCI_SUPPORT
-		if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE)
-		    && pAd->StaCfg.PSControl.field.EnableNewPS == TRUE)
-			RTMPSetTimer(&pAd->Mlme.RadioOnOffTimer, 10);
-#endif /* RTMP_PCI_SUPPORT // */
-		return;
-	}
-/*KH Debug: need to check. I add the compile flag "CONFIG_STA_SUPPORT" to enclose the following codes. */
-#ifdef RTMP_PCI_SUPPORT
-	if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE)
-	    && pAd->StaCfg.PSControl.field.EnableNewPS == TRUE) {
-		pAd->Mlme.bPsPollTimerRunning = FALSE;
-		RTMPCancelTimer(&pAd->Mlme.PsPollTimer, &Cancelled);
-	}
-#endif /* RTMP_PCI_SUPPORT // */
-	if (pAd->StaCfg.bRadio == TRUE) {
-		pAd->bPCIclkOff = FALSE;
-		RTMPRingCleanUp(pAd, QID_AC_BK);
-		RTMPRingCleanUp(pAd, QID_AC_BE);
-		RTMPRingCleanUp(pAd, QID_AC_VI);
-		RTMPRingCleanUp(pAd, QID_AC_VO);
-		RTMPRingCleanUp(pAd, QID_MGMT);
-		RTMPRingCleanUp(pAd, QID_RX);
-
-		/* 2. Send wake up command. */
-		AsicSendCommandToMcu(pAd, 0x31, PowerWakeCID, 0x00, 0x02);
-		/* 2-1. wait command ok. */
-		AsicCheckCommanOk(pAd, PowerWakeCID);
-
-		/* When PCI clock is off, don't want to service interrupt. So when back to clock on, enable interrupt. */
-		/*RTMP_IO_WRITE32(pAd, INT_MASK_CSR, (DELAYINTMASK|RxINT)); */
-		RTMP_ASIC_INTERRUPT_ENABLE(pAd);
-
-		/* 3. Enable Tx DMA. */
-		RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &DmaCfg.word);
-		DmaCfg.field.EnableTxDMA = 1;
-		RTMP_IO_WRITE32(pAd, WPDMA_GLO_CFG, DmaCfg.word);
-
-		/* In Radio Off, we turn off RF clk, So now need to call ASICSwitchChannel again. */
-		if (INFRA_ON(pAd)
-		    && (pAd->CommonCfg.CentralChannel != pAd->CommonCfg.Channel)
-		    && (pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth ==
-			BW_40)) {
-			/* Must using 40MHz. */
-			AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel,
-					  FALSE);
-			AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel);
-		} else {
-			/* Must using 20MHz. */
-			AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
-			AsicLockChannel(pAd, pAd->CommonCfg.Channel);
-		}
-
-/*KH Debug:The following codes should be enclosed by RT3090 compile flag */
-		if (pChipOps->AsicReverseRfFromSleepMode)
-			pChipOps->AsicReverseRfFromSleepMode(pAd);
-
-#ifdef PCIE_PS_SUPPORT
-/* 3090 MCU Wakeup command needs more time to be stable. */
-/* Before stable, don't issue other MCU command to prevent from firmware error. */
-		if ((IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd))
-		    && IS_VERSION_AFTER_F(pAd)
-		    && (pAd->StaCfg.PSControl.field.rt30xxPowerMode == 3)
-		    && (pAd->StaCfg.PSControl.field.EnableNewPS == TRUE)) {
-			RTMP_SEM_LOCK(&pAd->McuCmdLock);
-			pAd->brt30xxBanMcuCmd = FALSE;
-			RTMP_SEM_UNLOCK(&pAd->McuCmdLock);
-		}
-#endif /* PCIE_PS_SUPPORT // */
-
-		/* Clear Radio off flag */
-		RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF);
-
-		/* Set LED */
-		RTMPSetLED(pAd, LED_RADIO_ON);
-
-		if (pAd->StaCfg.Psm == PWR_ACTIVE) {
-			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3,
-						     pAd->StaCfg.BBPR3);
-		}
-	} else {
-		RT28xxPciAsicRadioOff(pAd, GUIRADIO_OFF, 0);
-	}
-}
-
-/*
-	==========================================================================
-	Description:
-		This routine sends command to firmware and turn our chip to wake up mode from power save mode.
-		Both RadioOn and .11 power save function needs to call this routine.
-	Input:
-		Level = GUIRADIO_OFF : call this function is from Radio Off to Radio On.  Need to restore PCI host value.
-		Level = other value : normal wake up function.
-
-	==========================================================================
- */
-BOOLEAN RT28xxPciAsicRadioOn(struct rt_rtmp_adapter *pAd, u8 Level)
-{
-	/*WPDMA_GLO_CFG_STRUC       DmaCfg; */
-	BOOLEAN Cancelled;
-	/*u32                        MACValue; */
-
-	if (pAd->OpMode == OPMODE_AP && Level == DOT11POWERSAVE)
-		return FALSE;
-
-	if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE)) {
-		if (pAd->StaCfg.PSControl.field.EnableNewPS == TRUE) {
-			pAd->Mlme.bPsPollTimerRunning = FALSE;
-			RTMPCancelTimer(&pAd->Mlme.PsPollTimer, &Cancelled);
-		}
-		if ((pAd->StaCfg.PSControl.field.EnableNewPS == TRUE &&
-		     (Level == GUIRADIO_OFF || Level == GUI_IDLE_POWER_SAVE)) ||
-		    RTMP_TEST_PSFLAG(pAd, fRTMP_PS_SET_PCI_CLK_OFF_COMMAND)) {
-			/* Some chips don't need to delay 6ms, so copy RTMPPCIePowerLinkCtrlRestore */
-			/* return condition here. */
-			/*
-			   if (((pAd->MACVersion&0xffff0000) != 0x28600000)
-			   && ((pAd->DeviceID == NIC2860_PCIe_DEVICE_ID)
-			   ||(pAd->DeviceID == NIC2790_PCIe_DEVICE_ID)))
-			 */
-			{
-				DBGPRINT(RT_DEBUG_TRACE,
-					 ("RT28xxPciAsicRadioOn ()\n"));
-				/* 1. Set PCI Link Control in Configuration Space. */
-				RTMPPCIeLinkCtrlValueRestore(pAd,
-							     RESTORE_WAKEUP);
-				RTMPusecDelay(6000);
-			}
-		}
-	}
-#ifdef PCIE_PS_SUPPORT
-	if (!
-	    (((IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd))
-	      && IS_VERSION_AFTER_F(pAd)
-	      && (pAd->StaCfg.PSControl.field.rt30xxPowerMode == 3)
-	      && (pAd->StaCfg.PSControl.field.EnableNewPS == TRUE))))
-#endif /* PCIE_PS_SUPPORT // */
-	{
-		pAd->bPCIclkOff = FALSE;
-		DBGPRINT(RT_DEBUG_TRACE,
-			 ("PSM :309xbPCIclkOff == %d\n", pAd->bPCIclkOff));
-	}
-	/* 2. Send wake up command. */
-	AsicSendCommandToMcu(pAd, 0x31, PowerWakeCID, 0x00, 0x02);
-	pAd->bPCIclkOff = FALSE;
-	/* 2-1. wait command ok. */
-	AsicCheckCommanOk(pAd, PowerWakeCID);
-	RTMP_ASIC_INTERRUPT_ENABLE(pAd);
-
-	RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF);
-	if (Level == GUI_IDLE_POWER_SAVE) {
-#ifdef  PCIE_PS_SUPPORT
-
-		/* add by johnli, RF power sequence setup, load RF normal operation-mode setup */
-		if ((IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd))) {
-			struct rt_rtmp_chip_op *pChipOps = &pAd->chipOps;
-
-			if (pChipOps->AsicReverseRfFromSleepMode)
-				pChipOps->AsicReverseRfFromSleepMode(pAd);
-			/* 3090 MCU Wakeup command needs more time to be stable. */
-			/* Before stable, don't issue other MCU command to prevent from firmware error. */
-			if ((IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd))
-			    && IS_VERSION_AFTER_F(pAd)
-			    && (pAd->StaCfg.PSControl.field.rt30xxPowerMode ==
-				3)
-			    && (pAd->StaCfg.PSControl.field.EnableNewPS ==
-				TRUE)) {
-				RTMP_SEM_LOCK(&pAd->McuCmdLock);
-				pAd->brt30xxBanMcuCmd = FALSE;
-				RTMP_SEM_UNLOCK(&pAd->McuCmdLock);
-			}
-		} else
-			/* end johnli */
-#endif /* PCIE_PS_SUPPORT // */
-		{
-			/* In Radio Off, we turn off RF clk, So now need to call ASICSwitchChannel again. */
-			{
-				if (INFRA_ON(pAd)
-				    && (pAd->CommonCfg.CentralChannel !=
-					pAd->CommonCfg.Channel)
-				    && (pAd->MlmeAux.HtCapability.HtCapInfo.
-					ChannelWidth == BW_40)) {
-					/* Must using 40MHz. */
-					AsicSwitchChannel(pAd,
-							  pAd->CommonCfg.
-							  CentralChannel,
-							  FALSE);
-					AsicLockChannel(pAd,
-							pAd->CommonCfg.
-							CentralChannel);
-				} else {
-					/* Must using 20MHz. */
-					AsicSwitchChannel(pAd,
-							  pAd->CommonCfg.
-							  Channel, FALSE);
-					AsicLockChannel(pAd,
-							pAd->CommonCfg.Channel);
-				}
-			}
-
-		}
-	}
-	return TRUE;
-
-}
-
-/*
-	==========================================================================
-	Description:
-		This routine sends command to firmware and turn our chip to power save mode.
-		Both RadioOff and .11 power save function needs to call this routine.
-	Input:
-		Level = GUIRADIO_OFF  : GUI Radio Off mode
-		Level = DOT11POWERSAVE  : 802.11 power save mode
-		Level = RTMP_HALT  : When Disable device.
-
-	==========================================================================
- */
-BOOLEAN RT28xxPciAsicRadioOff(struct rt_rtmp_adapter *pAd,
-			      u8 Level, u16 TbttNumToNextWakeUp)
-{
-	WPDMA_GLO_CFG_STRUC DmaCfg;
-	u8 i, tempBBP_R3 = 0;
-	BOOLEAN brc = FALSE, Cancelled;
-	u32 TbTTTime = 0;
-	u32 PsPollTime = 0 /*, MACValue */ ;
-	unsigned long BeaconPeriodTime;
-	u32 RxDmaIdx, RxCpuIdx;
-	DBGPRINT(RT_DEBUG_TRACE,
-		 ("AsicRadioOff ===> Lv= %d, TxCpuIdx = %d, TxDmaIdx = %d. RxCpuIdx = %d, RxDmaIdx = %d.\n",
-		  Level, pAd->TxRing[0].TxCpuIdx, pAd->TxRing[0].TxDmaIdx,
-		  pAd->RxRing.RxCpuIdx, pAd->RxRing.RxDmaIdx));
-
-	if (pAd->OpMode == OPMODE_AP && Level == DOT11POWERSAVE)
-		return FALSE;
-
-	/* Check Rx DMA busy status, if more than half is occupied, give up this radio off. */
-	RTMP_IO_READ32(pAd, RX_DRX_IDX, &RxDmaIdx);
-	RTMP_IO_READ32(pAd, RX_CRX_IDX, &RxCpuIdx);
-	if ((RxDmaIdx > RxCpuIdx) && ((RxDmaIdx - RxCpuIdx) > RX_RING_SIZE / 3)) {
-		DBGPRINT(RT_DEBUG_TRACE,
-			 ("AsicRadioOff ===> return1. RxDmaIdx = %d ,  RxCpuIdx = %d. \n",
-			  RxDmaIdx, RxCpuIdx));
-		return FALSE;
-	} else if ((RxCpuIdx >= RxDmaIdx)
-		   && ((RxCpuIdx - RxDmaIdx) < RX_RING_SIZE / 3)) {
-		DBGPRINT(RT_DEBUG_TRACE,
-			 ("AsicRadioOff ===> return2.  RxCpuIdx = %d. RxDmaIdx = %d ,  \n",
-			  RxCpuIdx, RxDmaIdx));
-		return FALSE;
-	}
-	/* Once go into this function, disable tx because don't want too many packets in queue to prevent HW stops. */
-	/*pAd->bPCIclkOffDisableTx = TRUE; */
-	RTMP_SET_PSFLAG(pAd, fRTMP_PS_DISABLE_TX);
-	if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE)
-	    && pAd->OpMode == OPMODE_STA
-	    && pAd->StaCfg.PSControl.field.EnableNewPS == TRUE) {
-		RTMPCancelTimer(&pAd->Mlme.RadioOnOffTimer, &Cancelled);
-		RTMPCancelTimer(&pAd->Mlme.PsPollTimer, &Cancelled);
-
-		if (Level == DOT11POWERSAVE) {
-			RTMP_IO_READ32(pAd, TBTT_TIMER, &TbTTTime);
-			TbTTTime &= 0x1ffff;
-			/* 00. check if need to do sleep in this DTIM period.   If next beacon will arrive within 30ms , ...doesn't necessarily sleep. */
-			/* TbTTTime uint = 64us, LEAD_TIME unit = 1024us, PsPollTime unit = 1ms */
-			if (((64 * TbTTTime) < ((LEAD_TIME * 1024) + 40000))
-			    && (TbttNumToNextWakeUp == 0)) {
-				DBGPRINT(RT_DEBUG_TRACE,
-					 ("TbTTTime = 0x%x , give up this sleep. \n",
-					  TbTTTime));
-				OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_DOZE);
-				/*pAd->bPCIclkOffDisableTx = FALSE; */
-				RTMP_CLEAR_PSFLAG(pAd, fRTMP_PS_DISABLE_TX);
-				return FALSE;
-			} else {
-				PsPollTime =
-				    (64 * TbTTTime - LEAD_TIME * 1024) / 1000;
-#ifdef PCIE_PS_SUPPORT
-				if ((IS_RT3090(pAd) || IS_RT3572(pAd)
-				     || IS_RT3390(pAd))
-				    && IS_VERSION_AFTER_F(pAd)
-				    && (pAd->StaCfg.PSControl.field.
-					rt30xxPowerMode == 3)
-				    && (pAd->StaCfg.PSControl.field.
-					EnableNewPS == TRUE)) {
-					PsPollTime -= 5;
-				} else
-#endif /* PCIE_PS_SUPPORT // */
-					PsPollTime -= 3;
-
-				BeaconPeriodTime =
-				    pAd->CommonCfg.BeaconPeriod * 102 / 100;
-				if (TbttNumToNextWakeUp > 0)
-					PsPollTime +=
-					    ((TbttNumToNextWakeUp -
-					      1) * BeaconPeriodTime);
-
-				pAd->Mlme.bPsPollTimerRunning = TRUE;
-				RTMPSetTimer(&pAd->Mlme.PsPollTimer,
-					     PsPollTime);
-			}
-		}
-	} else {
-		DBGPRINT(RT_DEBUG_TRACE,
-			 ("RT28xxPciAsicRadioOff::Level!=DOT11POWERSAVE \n"));
-	}
-
-	pAd->bPCIclkOffDisableTx = FALSE;
-
-	RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF);
-
-	/* Set to 1R. */
-	if (pAd->Antenna.field.RxPath > 1 && pAd->OpMode == OPMODE_STA) {
-		tempBBP_R3 = (pAd->StaCfg.BBPR3 & 0xE7);
-		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, tempBBP_R3);
-	}
-	/* In Radio Off, we turn off RF clk, So now need to call ASICSwitchChannel again. */
-	if ((INFRA_ON(pAd) || pAd->OpMode == OPMODE_AP)
-	    && (pAd->CommonCfg.CentralChannel != pAd->CommonCfg.Channel)
-	    && (pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth == BW_40)) {
-		/* Must using 40MHz. */
-		AsicTurnOffRFClk(pAd, pAd->CommonCfg.CentralChannel);
-	} else {
-		/* Must using 20MHz. */
-		AsicTurnOffRFClk(pAd, pAd->CommonCfg.Channel);
-	}
-
-	if (Level != RTMP_HALT) {
-		/* Change Interrupt bitmask. */
-		/* When PCI clock is off, don't want to service interrupt. */
-		RTMP_IO_WRITE32(pAd, INT_MASK_CSR, AutoWakeupInt);
-	} else {
-		RTMP_ASIC_INTERRUPT_DISABLE(pAd);
-	}
-
-	RTMP_IO_WRITE32(pAd, RX_CRX_IDX, pAd->RxRing.RxCpuIdx);
-	/*  2. Send Sleep command */
-	RTMP_IO_WRITE32(pAd, H2M_MAILBOX_STATUS, 0xffffffff);
-	RTMP_IO_WRITE32(pAd, H2M_MAILBOX_CID, 0xffffffff);
-	/* send POWER-SAVE command to MCU. high-byte = 1 save power as much as possible. high byte = 0 save less power */
-	AsicSendCommandToMcu(pAd, 0x30, PowerSafeCID, 0xff, 0x1);
-	/*  2-1. Wait command success */
-	/* Status = 1 : success, Status = 2, already sleep, Status = 3, Maybe MAC is busy so can't finish this task. */
-	brc = AsicCheckCommanOk(pAd, PowerSafeCID);
-
-	/*  3. After 0x30 command is ok, send radio off command. lowbyte = 0 for power safe. */
-	/* If 0x30 command is not ok this time, we can ignore 0x35 command. It will make sure not cause firmware'r problem. */
-	if ((Level == DOT11POWERSAVE) && (brc == TRUE)) {
-		AsicSendCommandToMcu(pAd, 0x35, PowerRadioOffCID, 0, 0x00);	/* lowbyte = 0 means to do power safe, NOT turn off radio. */
-		/*  3-1. Wait command success */
-		AsicCheckCommanOk(pAd, PowerRadioOffCID);
-	} else if (brc == TRUE) {
-		AsicSendCommandToMcu(pAd, 0x35, PowerRadioOffCID, 1, 0x00);	/* lowbyte = 0 means to do power safe, NOT turn off radio. */
-		/*  3-1. Wait command success */
-		AsicCheckCommanOk(pAd, PowerRadioOffCID);
-	}
-	/* 1. Wait DMA not busy */
-	i = 0;
-	do {
-		RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &DmaCfg.word);
-		if ((DmaCfg.field.RxDMABusy == 0)
-		    && (DmaCfg.field.TxDMABusy == 0))
-			break;
-		RTMPusecDelay(20);
-		i++;
-	} while (i < 50);
-
-	/*
-	   if (i >= 50)
-	   {
-	   pAd->CheckDmaBusyCount++;
-	   DBGPRINT(RT_DEBUG_TRACE, ("DMA Rx keeps busy.  return on AsicRadioOff () CheckDmaBusyCount = %d \n", pAd->CheckDmaBusyCount));
-	   }
-	   else
-	   {
-	   pAd->CheckDmaBusyCount = 0;
-	   }
-	 */
-/*KH Debug:My original codes have the following codes, but currecnt codes do not have it. */
-/* Disable for stability. If PCIE Link Control is modified for advance power save, re-covery this code segment. */
-	RTMP_IO_WRITE32(pAd, PBF_SYS_CTRL, 0x1280);
-/*OPSTATUS_SET_FLAG(pAd, fOP_STATUS_CLKSELECT_40MHZ); */
-
-#ifdef PCIE_PS_SUPPORT
-	if ((IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd))
-	    && IS_VERSION_AFTER_F(pAd)
-	    && (pAd->StaCfg.PSControl.field.rt30xxPowerMode == 3)
-	    && (pAd->StaCfg.PSControl.field.EnableNewPS == TRUE)) {
-		DBGPRINT(RT_DEBUG_TRACE,
-			 ("RT28xxPciAsicRadioOff::3090 return to skip the following TbttNumToNextWakeUp setting for 279x\n"));
-		pAd->bPCIclkOff = TRUE;
-		RTMP_CLEAR_PSFLAG(pAd, fRTMP_PS_DISABLE_TX);
-		/* For this case, doesn't need to below actions, so return here. */
-		return brc;
-	}
-#endif /* PCIE_PS_SUPPORT // */
-
-	if (Level == DOT11POWERSAVE) {
-		AUTO_WAKEUP_STRUC AutoWakeupCfg;
-		/*RTMPSetTimer(&pAd->Mlme.PsPollTimer, 90); */
-
-		/* we have decided to SLEEP, so at least do it for a BEACON period. */
-		if (TbttNumToNextWakeUp == 0)
-			TbttNumToNextWakeUp = 1;
-
-		AutoWakeupCfg.word = 0;
-		RTMP_IO_WRITE32(pAd, AUTO_WAKEUP_CFG, AutoWakeupCfg.word);
-
-		/* 1. Set auto wake up timer. */
-		AutoWakeupCfg.field.NumofSleepingTbtt = TbttNumToNextWakeUp - 1;
-		AutoWakeupCfg.field.EnableAutoWakeup = 1;
-		AutoWakeupCfg.field.AutoLeadTime = LEAD_TIME;
-		RTMP_IO_WRITE32(pAd, AUTO_WAKEUP_CFG, AutoWakeupCfg.word);
-	}
-	/*  4-1. If it's to disable our device. Need to restore PCI Configuration Space to its original value. */
-	if (Level == RTMP_HALT && pAd->OpMode == OPMODE_STA) {
-		if ((brc == TRUE) && (i < 50))
-			RTMPPCIeLinkCtrlSetting(pAd, 1);
-	}
-	/*  4. Set PCI configuration Space Link Comtrol fields.  Only Radio Off needs to call this function */
-	else if (pAd->OpMode == OPMODE_STA) {
-		if ((brc == TRUE) && (i < 50))
-			RTMPPCIeLinkCtrlSetting(pAd, 3);
-	}
-	/*pAd->bPCIclkOffDisableTx = FALSE; */
-	RTMP_CLEAR_PSFLAG(pAd, fRTMP_PS_DISABLE_TX);
-	return TRUE;
-}
-
-void RT28xxPciMlmeRadioOn(struct rt_rtmp_adapter *pAd)
-{
-	if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF))
-		return;
-
-	DBGPRINT(RT_DEBUG_TRACE, ("%s===>\n", __func__));
-
-	if ((pAd->OpMode == OPMODE_AP) || ((pAd->OpMode == OPMODE_STA)
-					   &&
-					   (!OPSTATUS_TEST_FLAG
-					    (pAd, fOP_STATUS_PCIE_DEVICE)
-					    || pAd->StaCfg.PSControl.field.
-					    EnableNewPS == FALSE))) {
-		RT28xxPciAsicRadioOn(pAd, GUI_IDLE_POWER_SAVE);
-		/*NICResetFromError(pAd); */
-
-		RTMPRingCleanUp(pAd, QID_AC_BK);
-		RTMPRingCleanUp(pAd, QID_AC_BE);
-		RTMPRingCleanUp(pAd, QID_AC_VI);
-		RTMPRingCleanUp(pAd, QID_AC_VO);
-		RTMPRingCleanUp(pAd, QID_MGMT);
-		RTMPRingCleanUp(pAd, QID_RX);
-
-		/* Enable Tx/Rx */
-		RTMPEnableRxTx(pAd);
-
-		/* Clear Radio off flag */
-		RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF);
-
-		RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF);
-
-		/* Set LED */
-		RTMPSetLED(pAd, LED_RADIO_ON);
-	}
-
-	if ((pAd->OpMode == OPMODE_STA) &&
-	    (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE))
-	    && (pAd->StaCfg.PSControl.field.EnableNewPS == TRUE)) {
-		BOOLEAN Cancelled;
-
-		RTMPPCIeLinkCtrlValueRestore(pAd, RESTORE_WAKEUP);
-
-		pAd->Mlme.bPsPollTimerRunning = FALSE;
-		RTMPCancelTimer(&pAd->Mlme.PsPollTimer, &Cancelled);
-		RTMPCancelTimer(&pAd->Mlme.RadioOnOffTimer, &Cancelled);
-		RTMPSetTimer(&pAd->Mlme.RadioOnOffTimer, 40);
-	}
-}
-
-void RT28xxPciMlmeRadioOFF(struct rt_rtmp_adapter *pAd)
-{
-	BOOLEAN brc = TRUE;
-
-	if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF))
-		return;
-
-	/* Link down first if any association exists */
-	if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) {
-		if (INFRA_ON(pAd) || ADHOC_ON(pAd)) {
-			struct rt_mlme_disassoc_req DisReq;
-			struct rt_mlme_queue_elem *pMsgElem =
-			    kmalloc(sizeof(struct rt_mlme_queue_elem),
-							MEM_ALLOC_FLAG);
-
-			if (pMsgElem) {
-				COPY_MAC_ADDR(&DisReq.Addr,
-					      pAd->CommonCfg.Bssid);
-				DisReq.Reason = REASON_DISASSOC_STA_LEAVING;
-
-				pMsgElem->Machine = ASSOC_STATE_MACHINE;
-				pMsgElem->MsgType = MT2_MLME_DISASSOC_REQ;
-				pMsgElem->MsgLen =
-				    sizeof(struct rt_mlme_disassoc_req);
-				NdisMoveMemory(pMsgElem->Msg, &DisReq,
-					       sizeof
-					       (struct rt_mlme_disassoc_req));
-
-				MlmeDisassocReqAction(pAd, pMsgElem);
-				kfree(pMsgElem);
-
-				RTMPusecDelay(1000);
-			}
-		}
-	}
-
-	DBGPRINT(RT_DEBUG_TRACE, ("%s===>\n", __func__));
-
-	/* Set Radio off flag */
-	RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF);
-
-	{
-		BOOLEAN Cancelled;
-		if (pAd->StaCfg.PSControl.field.EnableNewPS == TRUE) {
-			if (RTMP_TEST_FLAG
-			    (pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) {
-				RTMPCancelTimer(&pAd->MlmeAux.ScanTimer,
-						&Cancelled);
-				RTMP_CLEAR_FLAG(pAd,
-						fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS);
-			}
-			/* If during power safe mode. */
-			if (pAd->StaCfg.bRadio == TRUE) {
-				DBGPRINT(RT_DEBUG_TRACE,
-					 ("-->MlmeRadioOff() return on bRadio == TRUE; \n"));
-				return;
-			}
-			/* Always radio on since the NIC needs to set the MCU command (LED_RADIO_OFF). */
-			if (IDLE_ON(pAd) &&
-			    (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF)))
-			{
-				RT28xxPciAsicRadioOn(pAd, GUI_IDLE_POWER_SAVE);
-			}
-			if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE)) {
-				BOOLEAN Cancelled;
-				pAd->Mlme.bPsPollTimerRunning = FALSE;
-				RTMPCancelTimer(&pAd->Mlme.PsPollTimer,
-						&Cancelled);
-				RTMPCancelTimer(&pAd->Mlme.RadioOnOffTimer,
-						&Cancelled);
-			}
-		}
-		/* Link down first if any association exists */
-		if (INFRA_ON(pAd) || ADHOC_ON(pAd))
-			LinkDown(pAd, FALSE);
-		RTMPusecDelay(10000);
-		/*========================================== */
-		/* Clean up old bss table */
-		BssTableInit(&pAd->ScanTab);
-
-		/*
-		   if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE))
-		   {
-		   RTMPSetTimer(&pAd->Mlme.RadioOnOffTimer, 10);
-		   return;
-		   }
-		 */
-	}
-
-	/* Set LED.Move to here for fixing LED bug. This flag must be called after LinkDown */
-	RTMPSetLED(pAd, LED_RADIO_OFF);
-
-/*KH Debug:All PCIe devices need to use timer to execute radio off function, or the PCIe&&EnableNewPS needs. */
-/*KH Ans:It is right, because only when the PCIe and EnableNewPs is true, we need to delay the RadioOffTimer */
-/*to avoid the deadlock with PCIe Power saving function. */
-	if (pAd->OpMode == OPMODE_STA &&
-	    OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE) &&
-	    pAd->StaCfg.PSControl.field.EnableNewPS == TRUE) {
-		RTMPSetTimer(&pAd->Mlme.RadioOnOffTimer, 10);
-	} else {
-		brc = RT28xxPciAsicRadioOff(pAd, GUIRADIO_OFF, 0);
-
-		if (brc == FALSE) {
-			DBGPRINT(RT_DEBUG_ERROR,
-				 ("%s call RT28xxPciAsicRadioOff fail!\n",
-				  __func__));
-		}
-	}
-/*
-*/
-}
-
-#endif /* RTMP_MAC_PCI // */
diff -druN linux-2.6.39-libre/drivers/staging/rt2860/common/cmm_mac_usb.c linux-3.0-rc7-libre/drivers/staging/rt2860/common/cmm_mac_usb.c
--- linux-2.6.39-libre/drivers/staging/rt2860/common/cmm_mac_usb.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rt2860/common/cmm_mac_usb.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,1162 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, 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.             *
- *                                                                       *
- *************************************************************************
-*/
-
-#ifdef RTMP_MAC_USB
-
-#include	"../rt_config.h"
-
-/*
-========================================================================
-Routine Description:
-    Initialize receive data structures.
-
-Arguments:
-    pAd					Pointer to our adapter
-
-Return Value:
-	NDIS_STATUS_SUCCESS
-	NDIS_STATUS_RESOURCES
-
-Note:
-	Initialize all receive releated private buffer, include those define
-	in struct rt_rtmp_adapter structure and all private data structures. The mahor
-	work is to allocate buffer for each packet and chain buffer to
-	NDIS packet descriptor.
-========================================================================
-*/
-int NICInitRecv(struct rt_rtmp_adapter *pAd)
-{
-	u8 i;
-	int Status = NDIS_STATUS_SUCCESS;
-	struct os_cookie *pObj = (struct os_cookie *)pAd->OS_Cookie;
-
-	DBGPRINT(RT_DEBUG_TRACE, ("--> NICInitRecv\n"));
-	pObj = pObj;
-
-	/*InterlockedExchange(&pAd->PendingRx, 0); */
-	pAd->PendingRx = 0;
-	pAd->NextRxBulkInReadIndex = 0;	/* Next Rx Read index */
-	pAd->NextRxBulkInIndex = 0;	/*RX_RING_SIZE -1; // Rx Bulk pointer */
-	pAd->NextRxBulkInPosition = 0;
-
-	for (i = 0; i < (RX_RING_SIZE); i++) {
-		struct rt_rx_context *pRxContext = &(pAd->RxContext[i]);
-
-		/*Allocate URB */
-		pRxContext->pUrb = RTUSB_ALLOC_URB(0);
-		if (pRxContext->pUrb == NULL) {
-			Status = NDIS_STATUS_RESOURCES;
-			goto out1;
-		}
-		/* Allocate transfer buffer */
-		pRxContext->TransferBuffer =
-		    RTUSB_URB_ALLOC_BUFFER(pObj->pUsb_Dev, MAX_RXBULK_SIZE,
-					   &pRxContext->data_dma);
-		if (pRxContext->TransferBuffer == NULL) {
-			Status = NDIS_STATUS_RESOURCES;
-			goto out1;
-		}
-
-		NdisZeroMemory(pRxContext->TransferBuffer, MAX_RXBULK_SIZE);
-
-		pRxContext->pAd = pAd;
-		pRxContext->pIrp = NULL;
-		pRxContext->InUse = FALSE;
-		pRxContext->IRPPending = FALSE;
-		pRxContext->Readable = FALSE;
-		/*pRxContext->ReorderInUse = FALSE; */
-		pRxContext->bRxHandling = FALSE;
-		pRxContext->BulkInOffset = 0;
-	}
-
-	DBGPRINT(RT_DEBUG_TRACE, ("<-- NICInitRecv(Status=%d)\n", Status));
-	return Status;
-
-out1:
-	for (i = 0; i < (RX_RING_SIZE); i++) {
-		struct rt_rx_context *pRxContext = &(pAd->RxContext[i]);
-
-		if (NULL != pRxContext->TransferBuffer) {
-			RTUSB_URB_FREE_BUFFER(pObj->pUsb_Dev, MAX_RXBULK_SIZE,
-					      pRxContext->TransferBuffer,
-					      pRxContext->data_dma);
-			pRxContext->TransferBuffer = NULL;
-		}
-
-		if (NULL != pRxContext->pUrb) {
-			RTUSB_UNLINK_URB(pRxContext->pUrb);
-			RTUSB_FREE_URB(pRxContext->pUrb);
-			pRxContext->pUrb = NULL;
-		}
-	}
-
-	return Status;
-}
-
-/*
-========================================================================
-Routine Description:
-    Initialize transmit data structures.
-
-Arguments:
-    pAd					Pointer to our adapter
-
-Return Value:
-	NDIS_STATUS_SUCCESS
-	NDIS_STATUS_RESOURCES
-
-Note:
-========================================================================
-*/
-int NICInitTransmit(struct rt_rtmp_adapter *pAd)
-{
-#define LM_USB_ALLOC(pObj, Context, TB_Type, BufferSize, Status, msg1, err1, msg2, err2)	\
-	Context->pUrb = RTUSB_ALLOC_URB(0);		\
-	if (Context->pUrb == NULL) {			\
-		DBGPRINT(RT_DEBUG_ERROR, msg1);		\
-		Status = NDIS_STATUS_RESOURCES;		\
-		goto err1; }						\
-											\
-	Context->TransferBuffer =				\
-		(TB_Type)RTUSB_URB_ALLOC_BUFFER(pObj->pUsb_Dev, BufferSize, &Context->data_dma);	\
-	if (Context->TransferBuffer == NULL) {	\
-		DBGPRINT(RT_DEBUG_ERROR, msg2);		\
-		Status = NDIS_STATUS_RESOURCES;		\
-		goto err2; }
-
-#define LM_URB_FREE(pObj, Context, BufferSize)				\
-	if (NULL != Context->pUrb) {							\
-		RTUSB_UNLINK_URB(Context->pUrb);					\
-		RTUSB_FREE_URB(Context->pUrb);						\
-		Context->pUrb = NULL; }								\
-	if (NULL != Context->TransferBuffer) {				\
-		RTUSB_URB_FREE_BUFFER(pObj->pUsb_Dev, BufferSize,	\
-								Context->TransferBuffer,	\
-								Context->data_dma);			\
-		Context->TransferBuffer = NULL; }
-
-	u8 i, acidx;
-	int Status = NDIS_STATUS_SUCCESS;
-	struct rt_tx_context *pNullContext = &(pAd->NullContext);
-	struct rt_tx_context *pPsPollContext = &(pAd->PsPollContext);
-	struct rt_tx_context *pRTSContext = &(pAd->RTSContext);
-	struct rt_tx_context *pMLMEContext = NULL;
-/*      struct rt_ht_tx_context *pHTTXContext = NULL; */
-	struct os_cookie *pObj = (struct os_cookie *)pAd->OS_Cookie;
-	void *RingBaseVa;
-/*      struct rt_rtmp_tx_ring *pTxRing; */
-	struct rt_rtmp_mgmt_ring *pMgmtRing;
-
-	DBGPRINT(RT_DEBUG_TRACE, ("--> NICInitTransmit\n"));
-	pObj = pObj;
-
-	/* Init 4 set of Tx parameters */
-	for (acidx = 0; acidx < NUM_OF_TX_RING; acidx++) {
-		/* Initialize all Transmit releated queues */
-		InitializeQueueHeader(&pAd->TxSwQueue[acidx]);
-
-		/* Next Local tx ring pointer waiting for buck out */
-		pAd->NextBulkOutIndex[acidx] = acidx;
-		pAd->BulkOutPending[acidx] = FALSE;	/* Buck Out control flag */
-		/*pAd->DataBulkDoneIdx[acidx] = 0; */
-	}
-
-	/*pAd->NextMLMEIndex    = 0; */
-	/*pAd->PushMgmtIndex    = 0; */
-	/*pAd->PopMgmtIndex     = 0; */
-	/*InterlockedExchange(&pAd->MgmtQueueSize, 0); */
-	/*InterlockedExchange(&pAd->TxCount, 0); */
-
-	/*pAd->PrioRingFirstIndex       = 0; */
-	/*pAd->PrioRingTxCnt            = 0; */
-
-	do {
-		/* */
-		/* TX_RING_SIZE, 4 ACs */
-		/* */
-		for (acidx = 0; acidx < 4; acidx++) {
-			struct rt_ht_tx_context *pHTTXContext = &(pAd->TxContext[acidx]);
-
-			NdisZeroMemory(pHTTXContext, sizeof(struct rt_ht_tx_context));
-			/*Allocate URB */
-			LM_USB_ALLOC(pObj, pHTTXContext, struct rt_httx_buffer *,
-				     sizeof(struct rt_httx_buffer), Status,
-				     ("<-- ERROR in Alloc TX TxContext[%d] urb!\n",
-				      acidx), done,
-				     ("<-- ERROR in Alloc TX TxContext[%d] struct rt_httx_buffer!\n",
-				      acidx), out1);
-
-			NdisZeroMemory(pHTTXContext->TransferBuffer->
-				       Aggregation, 4);
-			pHTTXContext->pAd = pAd;
-			pHTTXContext->pIrp = NULL;
-			pHTTXContext->IRPPending = FALSE;
-			pHTTXContext->NextBulkOutPosition = 0;
-			pHTTXContext->ENextBulkOutPosition = 0;
-			pHTTXContext->CurWritePosition = 0;
-			pHTTXContext->CurWriteRealPos = 0;
-			pHTTXContext->BulkOutSize = 0;
-			pHTTXContext->BulkOutPipeId = acidx;
-			pHTTXContext->bRingEmpty = TRUE;
-			pHTTXContext->bCopySavePad = FALSE;
-			pAd->BulkOutPending[acidx] = FALSE;
-		}
-
-		/* */
-		/* MGMT_RING_SIZE */
-		/* */
-
-		/* Allocate MGMT ring descriptor's memory */
-		pAd->MgmtDescRing.AllocSize =
-		    MGMT_RING_SIZE * sizeof(struct rt_tx_context);
-		os_alloc_mem(pAd, (u8 **) (&pAd->MgmtDescRing.AllocVa),
-			     pAd->MgmtDescRing.AllocSize);
-		if (pAd->MgmtDescRing.AllocVa == NULL) {
-			DBGPRINT_ERR("Failed to allocate a big buffer for MgmtDescRing!\n");
-			Status = NDIS_STATUS_RESOURCES;
-			goto out1;
-		}
-		NdisZeroMemory(pAd->MgmtDescRing.AllocVa,
-			       pAd->MgmtDescRing.AllocSize);
-		RingBaseVa = pAd->MgmtDescRing.AllocVa;
-
-		/* Initialize MGMT Ring and associated buffer memory */
-		pMgmtRing = &pAd->MgmtRing;
-		for (i = 0; i < MGMT_RING_SIZE; i++) {
-			/* link the pre-allocated Mgmt buffer to MgmtRing.Cell */
-			pMgmtRing->Cell[i].AllocSize = sizeof(struct rt_tx_context);
-			pMgmtRing->Cell[i].AllocVa = RingBaseVa;
-			pMgmtRing->Cell[i].pNdisPacket = NULL;
-			pMgmtRing->Cell[i].pNextNdisPacket = NULL;
-
-			/*Allocate URB for MLMEContext */
-			pMLMEContext =
-			    (struct rt_tx_context *)pAd->MgmtRing.Cell[i].AllocVa;
-			pMLMEContext->pUrb = RTUSB_ALLOC_URB(0);
-			if (pMLMEContext->pUrb == NULL) {
-				DBGPRINT(RT_DEBUG_ERROR,
-					 ("<-- ERROR in Alloc TX MLMEContext[%d] urb!\n",
-					  i));
-				Status = NDIS_STATUS_RESOURCES;
-				goto out2;
-			}
-			pMLMEContext->pAd = pAd;
-			pMLMEContext->pIrp = NULL;
-			pMLMEContext->TransferBuffer = NULL;
-			pMLMEContext->InUse = FALSE;
-			pMLMEContext->IRPPending = FALSE;
-			pMLMEContext->bWaitingBulkOut = FALSE;
-			pMLMEContext->BulkOutSize = 0;
-			pMLMEContext->SelfIdx = i;
-
-			/* Offset to next ring descriptor address */
-			RingBaseVa = (u8 *)RingBaseVa + sizeof(struct rt_tx_context);
-		}
-		DBGPRINT(RT_DEBUG_TRACE,
-			 ("MGMT Ring: total %d entry allocated\n", i));
-
-		/*pAd->MgmtRing.TxSwFreeIdx = (MGMT_RING_SIZE - 1); */
-		pAd->MgmtRing.TxSwFreeIdx = MGMT_RING_SIZE;
-		pAd->MgmtRing.TxCpuIdx = 0;
-		pAd->MgmtRing.TxDmaIdx = 0;
-
-		/* */
-		/* BEACON_RING_SIZE */
-		/* */
-		for (i = 0; i < BEACON_RING_SIZE; i++)	/* 2 */
-		{
-			struct rt_tx_context *pBeaconContext = &(pAd->BeaconContext[i]);
-
-			NdisZeroMemory(pBeaconContext, sizeof(struct rt_tx_context));
-
-			/*Allocate URB */
-			LM_USB_ALLOC(pObj, pBeaconContext, struct rt_tx_buffer *,
-				     sizeof(struct rt_tx_buffer), Status,
-				     ("<-- ERROR in Alloc TX BeaconContext[%d] urb!\n",
-				      i), out2,
-				     ("<-- ERROR in Alloc TX BeaconContext[%d] struct rt_tx_buffer!\n",
-				      i), out3);
-
-			pBeaconContext->pAd = pAd;
-			pBeaconContext->pIrp = NULL;
-			pBeaconContext->InUse = FALSE;
-			pBeaconContext->IRPPending = FALSE;
-		}
-
-		/* */
-		/* NullContext */
-		/* */
-		NdisZeroMemory(pNullContext, sizeof(struct rt_tx_context));
-
-		/*Allocate URB */
-		LM_USB_ALLOC(pObj, pNullContext, struct rt_tx_buffer *, sizeof(struct rt_tx_buffer),
-			     Status,
-			     ("<-- ERROR in Alloc TX NullContext urb!\n"),
-			     out3,
-			     ("<-- ERROR in Alloc TX NullContext struct rt_tx_buffer!\n"),
-			     out4);
-
-		pNullContext->pAd = pAd;
-		pNullContext->pIrp = NULL;
-		pNullContext->InUse = FALSE;
-		pNullContext->IRPPending = FALSE;
-
-		/* */
-		/* RTSContext */
-		/* */
-		NdisZeroMemory(pRTSContext, sizeof(struct rt_tx_context));
-
-		/*Allocate URB */
-		LM_USB_ALLOC(pObj, pRTSContext, struct rt_tx_buffer *, sizeof(struct rt_tx_buffer),
-			     Status,
-			     ("<-- ERROR in Alloc TX RTSContext urb!\n"),
-			     out4,
-			     ("<-- ERROR in Alloc TX RTSContext struct rt_tx_buffer!\n"),
-			     out5);
-
-		pRTSContext->pAd = pAd;
-		pRTSContext->pIrp = NULL;
-		pRTSContext->InUse = FALSE;
-		pRTSContext->IRPPending = FALSE;
-
-		/* */
-		/* PsPollContext */
-		/* */
-		/*NdisZeroMemory(pPsPollContext, sizeof(struct rt_tx_context)); */
-		/*Allocate URB */
-		LM_USB_ALLOC(pObj, pPsPollContext, struct rt_tx_buffer *,
-			     sizeof(struct rt_tx_buffer), Status,
-			     ("<-- ERROR in Alloc TX PsPollContext urb!\n"),
-			     out5,
-			     ("<-- ERROR in Alloc TX PsPollContext struct rt_tx_buffer!\n"),
-			     out6);
-
-		pPsPollContext->pAd = pAd;
-		pPsPollContext->pIrp = NULL;
-		pPsPollContext->InUse = FALSE;
-		pPsPollContext->IRPPending = FALSE;
-		pPsPollContext->bAggregatible = FALSE;
-		pPsPollContext->LastOne = TRUE;
-
-	} while (FALSE);
-
-done:
-	DBGPRINT(RT_DEBUG_TRACE, ("<-- NICInitTransmit(Status=%d)\n", Status));
-
-	return Status;
-
-	/* --------------------------- ERROR HANDLE --------------------------- */
-out6:
-	LM_URB_FREE(pObj, pPsPollContext, sizeof(struct rt_tx_buffer));
-
-out5:
-	LM_URB_FREE(pObj, pRTSContext, sizeof(struct rt_tx_buffer));
-
-out4:
-	LM_URB_FREE(pObj, pNullContext, sizeof(struct rt_tx_buffer));
-
-out3:
-	for (i = 0; i < BEACON_RING_SIZE; i++) {
-		struct rt_tx_context *pBeaconContext = &(pAd->BeaconContext[i]);
-		if (pBeaconContext)
-			LM_URB_FREE(pObj, pBeaconContext, sizeof(struct rt_tx_buffer));
-	}
-
-out2:
-	if (pAd->MgmtDescRing.AllocVa) {
-		pMgmtRing = &pAd->MgmtRing;
-		for (i = 0; i < MGMT_RING_SIZE; i++) {
-			pMLMEContext =
-			    (struct rt_tx_context *)pAd->MgmtRing.Cell[i].AllocVa;
-			if (pMLMEContext)
-				LM_URB_FREE(pObj, pMLMEContext,
-					    sizeof(struct rt_tx_buffer));
-		}
-		os_free_mem(pAd, pAd->MgmtDescRing.AllocVa);
-		pAd->MgmtDescRing.AllocVa = NULL;
-	}
-
-out1:
-	for (acidx = 0; acidx < 4; acidx++) {
-		struct rt_ht_tx_context *pTxContext = &(pAd->TxContext[acidx]);
-		if (pTxContext)
-			LM_URB_FREE(pObj, pTxContext, sizeof(struct rt_httx_buffer));
-	}
-
-	/* Here we didn't have any pre-allocated memory need to free. */
-
-	return Status;
-}
-
-/*
-========================================================================
-Routine Description:
-    Allocate DMA memory blocks for send, receive.
-
-Arguments:
-    pAd					Pointer to our adapter
-
-Return Value:
-	NDIS_STATUS_SUCCESS
-	NDIS_STATUS_FAILURE
-	NDIS_STATUS_RESOURCES
-
-Note:
-========================================================================
-*/
-int RTMPAllocTxRxRingMemory(struct rt_rtmp_adapter *pAd)
-{
-/*      struct rt_counter_802_11  pCounter = &pAd->WlanCounters; */
-	int Status;
-	int num;
-
-	DBGPRINT(RT_DEBUG_TRACE, ("--> RTMPAllocTxRxRingMemory\n"));
-
-	do {
-		/* Init the struct rt_cmdq and CmdQLock */
-		NdisAllocateSpinLock(&pAd->CmdQLock);
-		NdisAcquireSpinLock(&pAd->CmdQLock);
-		RTUSBInitializeCmdQ(&pAd->CmdQ);
-		NdisReleaseSpinLock(&pAd->CmdQLock);
-
-		NdisAllocateSpinLock(&pAd->MLMEBulkOutLock);
-		/*NdisAllocateSpinLock(&pAd->MLMEWaitQueueLock); */
-		NdisAllocateSpinLock(&pAd->BulkOutLock[0]);
-		NdisAllocateSpinLock(&pAd->BulkOutLock[1]);
-		NdisAllocateSpinLock(&pAd->BulkOutLock[2]);
-		NdisAllocateSpinLock(&pAd->BulkOutLock[3]);
-		NdisAllocateSpinLock(&pAd->BulkOutLock[4]);
-		NdisAllocateSpinLock(&pAd->BulkOutLock[5]);
-		NdisAllocateSpinLock(&pAd->BulkInLock);
-
-		for (num = 0; num < NUM_OF_TX_RING; num++) {
-			NdisAllocateSpinLock(&pAd->TxContextQueueLock[num]);
-		}
-
-/*              NdisAllocateSpinLock(&pAd->MemLock);    // Not used in RT28XX */
-
-/*              NdisAllocateSpinLock(&pAd->MacTabLock); // init it in UserCfgInit() */
-/*              NdisAllocateSpinLock(&pAd->BATabLock); // init it in BATableInit() */
-
-/*              for(num=0; num<MAX_LEN_OF_BA_REC_TABLE; num++) */
-/*              { */
-/*                      NdisAllocateSpinLock(&pAd->BATable.BARecEntry[num].RxReRingLock); */
-/*              } */
-
-		/* */
-		/* Init Mac Table */
-		/* */
-/*              MacTableInitialize(pAd); */
-
-		/* */
-		/* Init send data structures and related parameters */
-		/* */
-		Status = NICInitTransmit(pAd);
-		if (Status != NDIS_STATUS_SUCCESS)
-			break;
-
-		/* */
-		/* Init receive data structures and related parameters */
-		/* */
-		Status = NICInitRecv(pAd);
-		if (Status != NDIS_STATUS_SUCCESS)
-			break;
-
-		pAd->PendingIoCount = 1;
-
-	} while (FALSE);
-
-	NdisZeroMemory(&pAd->FragFrame, sizeof(struct rt_fragment_frame));
-	pAd->FragFrame.pFragPacket =
-	    RTMP_AllocateFragPacketBuffer(pAd, RX_BUFFER_NORMSIZE);
-
-	if (pAd->FragFrame.pFragPacket == NULL) {
-		Status = NDIS_STATUS_RESOURCES;
-	}
-
-	DBGPRINT_S(Status,
-		   ("<-- RTMPAllocTxRxRingMemory, Status=%x\n", Status));
-	return Status;
-}
-
-/*
-========================================================================
-Routine Description:
-	Calls USB_InterfaceStop and frees memory allocated for the URBs
-    calls NdisMDeregisterDevice and frees the memory
-    allocated in VNetInitialize for the Adapter Object
-
-Arguments:
-	*pAd				the raxx interface data pointer
-
-Return Value:
-	None
-
-Note:
-========================================================================
-*/
-void RTMPFreeTxRxRingMemory(struct rt_rtmp_adapter *pAd)
-{
-#define LM_URB_FREE(pObj, Context, BufferSize)				\
-	if (NULL != Context->pUrb) {							\
-		RTUSB_UNLINK_URB(Context->pUrb);					\
-		RTUSB_FREE_URB(Context->pUrb);						\
-		Context->pUrb = NULL; }								\
-	if (NULL != Context->TransferBuffer) {					\
-		RTUSB_URB_FREE_BUFFER(pObj->pUsb_Dev, BufferSize,	\
-								Context->TransferBuffer,	\
-								Context->data_dma);			\
-		Context->TransferBuffer = NULL; }
-
-	u32 i, acidx;
-	struct rt_tx_context *pNullContext = &pAd->NullContext;
-	struct rt_tx_context *pPsPollContext = &pAd->PsPollContext;
-	struct rt_tx_context *pRTSContext = &pAd->RTSContext;
-/*      struct rt_ht_tx_context *pHTTXContext; */
-	/*PRTMP_REORDERBUF      pReorderBuf; */
-	struct os_cookie *pObj = (struct os_cookie *)pAd->OS_Cookie;
-/*      struct rt_rtmp_tx_ring *pTxRing; */
-
-	DBGPRINT(RT_DEBUG_ERROR, ("---> RTMPFreeTxRxRingMemory\n"));
-	pObj = pObj;
-
-	/* Free all resources for the RECEIVE buffer queue. */
-	for (i = 0; i < (RX_RING_SIZE); i++) {
-		struct rt_rx_context *pRxContext = &(pAd->RxContext[i]);
-		if (pRxContext)
-			LM_URB_FREE(pObj, pRxContext, MAX_RXBULK_SIZE);
-	}
-
-	/* Free PsPoll frame resource */
-	LM_URB_FREE(pObj, pPsPollContext, sizeof(struct rt_tx_buffer));
-
-	/* Free NULL frame resource */
-	LM_URB_FREE(pObj, pNullContext, sizeof(struct rt_tx_buffer));
-
-	/* Free RTS frame resource */
-	LM_URB_FREE(pObj, pRTSContext, sizeof(struct rt_tx_buffer));
-
-	/* Free beacon frame resource */
-	for (i = 0; i < BEACON_RING_SIZE; i++) {
-		struct rt_tx_context *pBeaconContext = &(pAd->BeaconContext[i]);
-		if (pBeaconContext)
-			LM_URB_FREE(pObj, pBeaconContext, sizeof(struct rt_tx_buffer));
-	}
-
-	/* Free mgmt frame resource */
-	for (i = 0; i < MGMT_RING_SIZE; i++) {
-		struct rt_tx_context *pMLMEContext =
-		    (struct rt_tx_context *)pAd->MgmtRing.Cell[i].AllocVa;
-		/*LM_URB_FREE(pObj, pMLMEContext, sizeof(struct rt_tx_buffer)); */
-		if (NULL != pAd->MgmtRing.Cell[i].pNdisPacket) {
-			RTMPFreeNdisPacket(pAd,
-					   pAd->MgmtRing.Cell[i].pNdisPacket);
-			pAd->MgmtRing.Cell[i].pNdisPacket = NULL;
-			pMLMEContext->TransferBuffer = NULL;
-		}
-
-		if (pMLMEContext) {
-			if (NULL != pMLMEContext->pUrb) {
-				RTUSB_UNLINK_URB(pMLMEContext->pUrb);
-				RTUSB_FREE_URB(pMLMEContext->pUrb);
-				pMLMEContext->pUrb = NULL;
-			}
-		}
-	}
-	if (pAd->MgmtDescRing.AllocVa)
-		os_free_mem(pAd, pAd->MgmtDescRing.AllocVa);
-
-	/* Free Tx frame resource */
-	for (acidx = 0; acidx < 4; acidx++) {
-		struct rt_ht_tx_context *pHTTXContext = &(pAd->TxContext[acidx]);
-		if (pHTTXContext)
-			LM_URB_FREE(pObj, pHTTXContext, sizeof(struct rt_httx_buffer));
-	}
-
-	if (pAd->FragFrame.pFragPacket)
-		RELEASE_NDIS_PACKET(pAd, pAd->FragFrame.pFragPacket,
-				    NDIS_STATUS_SUCCESS);
-
-	for (i = 0; i < 6; i++) {
-		NdisFreeSpinLock(&pAd->BulkOutLock[i]);
-	}
-
-	NdisFreeSpinLock(&pAd->BulkInLock);
-	NdisFreeSpinLock(&pAd->MLMEBulkOutLock);
-
-	NdisFreeSpinLock(&pAd->CmdQLock);
-	/* Clear all pending bulk-out request flags. */
-	RTUSB_CLEAR_BULK_FLAG(pAd, 0xffffffff);
-
-/*      NdisFreeSpinLock(&pAd->MacTabLock); */
-
-/*      for(i=0; i<MAX_LEN_OF_BA_REC_TABLE; i++) */
-/*      { */
-/*              NdisFreeSpinLock(&pAd->BATable.BARecEntry[i].RxReRingLock); */
-/*      } */
-
-	DBGPRINT(RT_DEBUG_ERROR, ("<--- RTMPFreeTxRxRingMemory\n"));
-}
-
-/*
-========================================================================
-Routine Description:
-    Write WLAN MAC address to USB 2870.
-
-Arguments:
-    pAd					Pointer to our adapter
-
-Return Value:
-	NDIS_STATUS_SUCCESS
-
-Note:
-========================================================================
-*/
-int RTUSBWriteHWMACAddress(struct rt_rtmp_adapter *pAd)
-{
-	MAC_DW0_STRUC StaMacReg0;
-	MAC_DW1_STRUC StaMacReg1;
-	int Status = NDIS_STATUS_SUCCESS;
-	LARGE_INTEGER NOW;
-
-	/* initialize the random number generator */
-	RTMP_GetCurrentSystemTime(&NOW);
-
-	if (pAd->bLocalAdminMAC != TRUE) {
-		pAd->CurrentAddress[0] = pAd->PermanentAddress[0];
-		pAd->CurrentAddress[1] = pAd->PermanentAddress[1];
-		pAd->CurrentAddress[2] = pAd->PermanentAddress[2];
-		pAd->CurrentAddress[3] = pAd->PermanentAddress[3];
-		pAd->CurrentAddress[4] = pAd->PermanentAddress[4];
-		pAd->CurrentAddress[5] = pAd->PermanentAddress[5];
-	}
-	/* Write New MAC address to MAC_CSR2 & MAC_CSR3 & let ASIC know our new MAC */
-	StaMacReg0.field.Byte0 = pAd->CurrentAddress[0];
-	StaMacReg0.field.Byte1 = pAd->CurrentAddress[1];
-	StaMacReg0.field.Byte2 = pAd->CurrentAddress[2];
-	StaMacReg0.field.Byte3 = pAd->CurrentAddress[3];
-	StaMacReg1.field.Byte4 = pAd->CurrentAddress[4];
-	StaMacReg1.field.Byte5 = pAd->CurrentAddress[5];
-	StaMacReg1.field.U2MeMask = 0xff;
-	DBGPRINT_RAW(RT_DEBUG_TRACE,
-		("Local MAC = %pM\n", pAd->CurrentAddress));
-
-	RTUSBWriteMACRegister(pAd, MAC_ADDR_DW0, StaMacReg0.word);
-	RTUSBWriteMACRegister(pAd, MAC_ADDR_DW1, StaMacReg1.word);
-	return Status;
-}
-
-/*
-========================================================================
-Routine Description:
-    Disable DMA.
-
-Arguments:
-	*pAd				the raxx interface data pointer
-
-Return Value:
-	None
-
-Note:
-========================================================================
-*/
-void RT28XXDMADisable(struct rt_rtmp_adapter *pAd)
-{
-	/* no use */
-}
-
-/*
-========================================================================
-Routine Description:
-    Enable DMA.
-
-Arguments:
-	*pAd				the raxx interface data pointer
-
-Return Value:
-	None
-
-Note:
-========================================================================
-*/
-void RT28XXDMAEnable(struct rt_rtmp_adapter *pAd)
-{
-	WPDMA_GLO_CFG_STRUC GloCfg;
-	USB_DMA_CFG_STRUC UsbCfg;
-	int i = 0;
-
-	RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x4);
-	do {
-		RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &GloCfg.word);
-		if ((GloCfg.field.TxDMABusy == 0)
-		    && (GloCfg.field.RxDMABusy == 0))
-			break;
-
-		DBGPRINT(RT_DEBUG_TRACE, ("==>  DMABusy\n"));
-		RTMPusecDelay(1000);
-		i++;
-	} while (i < 200);
-
-	RTMPusecDelay(50);
-	GloCfg.field.EnTXWriteBackDDONE = 1;
-	GloCfg.field.EnableRxDMA = 1;
-	GloCfg.field.EnableTxDMA = 1;
-	DBGPRINT(RT_DEBUG_TRACE,
-		 ("<== WRITE DMA offset 0x208 = 0x%x\n", GloCfg.word));
-	RTMP_IO_WRITE32(pAd, WPDMA_GLO_CFG, GloCfg.word);
-
-	UsbCfg.word = 0;
-	UsbCfg.field.phyclear = 0;
-	/* usb version is 1.1,do not use bulk in aggregation */
-	if (pAd->BulkInMaxPacketSize == 512)
-		UsbCfg.field.RxBulkAggEn = 1;
-	/* for last packet, PBF might use more than limited, so minus 2 to prevent from error */
-	UsbCfg.field.RxBulkAggLmt = (MAX_RXBULK_SIZE / 1024) - 3;
-	UsbCfg.field.RxBulkAggTOut = 0x80;	/* 2006-10-18 */
-	UsbCfg.field.RxBulkEn = 1;
-	UsbCfg.field.TxBulkEn = 1;
-
-	RTUSBWriteMACRegister(pAd, USB_DMA_CFG, UsbCfg.word);
-
-}
-
-/********************************************************************
-  *
-  *	2870 Beacon Update Related functions.
-  *
-  ********************************************************************/
-
-/*
-========================================================================
-Routine Description:
-    Write Beacon buffer to Asic.
-
-Arguments:
-	*pAd				the raxx interface data pointer
-
-Return Value:
-	None
-
-Note:
-========================================================================
-*/
-void RT28xx_UpdateBeaconToAsic(struct rt_rtmp_adapter *pAd,
-			       int apidx,
-			       unsigned long FrameLen, unsigned long UpdatePos)
-{
-	u8 *pBeaconFrame = NULL;
-	u8 *ptr;
-	u32 i, padding;
-	struct rt_beacon_sync *pBeaconSync = pAd->CommonCfg.pBeaconSync;
-	u32 longValue;
-/*      u16                  shortValue; */
-	BOOLEAN bBcnReq = FALSE;
-	u8 bcn_idx = 0;
-
-	if (pBeaconFrame == NULL) {
-		DBGPRINT(RT_DEBUG_ERROR, ("pBeaconFrame is NULL!\n"));
-		return;
-	}
-
-	if (pBeaconSync == NULL) {
-		DBGPRINT(RT_DEBUG_ERROR, ("pBeaconSync is NULL!\n"));
-		return;
-	}
-	/*if ((pAd->WdsTab.Mode == WDS_BRIDGE_MODE) || */
-	/*      ((pAd->ApCfg.MBSSID[apidx].MSSIDDev == NULL) || !(pAd->ApCfg.MBSSID[apidx].MSSIDDev->flags & IFF_UP)) */
-	/*      ) */
-	if (bBcnReq == FALSE) {
-		/* when the ra interface is down, do not send its beacon frame */
-		/* clear all zero */
-		for (i = 0; i < TXWI_SIZE; i += 4) {
-			RTMP_IO_WRITE32(pAd, pAd->BeaconOffset[bcn_idx] + i,
-					0x00);
-		}
-		pBeaconSync->BeaconBitMap &=
-		    (~(BEACON_BITMAP_MASK & (1 << bcn_idx)));
-		NdisZeroMemory(pBeaconSync->BeaconTxWI[bcn_idx], TXWI_SIZE);
-	} else {
-		ptr = (u8 *)& pAd->BeaconTxWI;
-		if (NdisEqualMemory(pBeaconSync->BeaconTxWI[bcn_idx], &pAd->BeaconTxWI, TXWI_SIZE) == FALSE) {	/* If BeaconTxWI changed, we need to rewrite the TxWI for the Beacon frames. */
-			pBeaconSync->BeaconBitMap &=
-			    (~(BEACON_BITMAP_MASK & (1 << bcn_idx)));
-			NdisMoveMemory(pBeaconSync->BeaconTxWI[bcn_idx],
-				       &pAd->BeaconTxWI, TXWI_SIZE);
-		}
-
-		if ((pBeaconSync->BeaconBitMap & (1 << bcn_idx)) !=
-		    (1 << bcn_idx)) {
-			for (i = 0; i < TXWI_SIZE; i += 4)	/* 16-byte TXWI field */
-			{
-				longValue =
-				    *ptr + (*(ptr + 1) << 8) +
-				    (*(ptr + 2) << 16) + (*(ptr + 3) << 24);
-				RTMP_IO_WRITE32(pAd,
-						pAd->BeaconOffset[bcn_idx] + i,
-						longValue);
-				ptr += 4;
-			}
-		}
-
-		ptr = pBeaconSync->BeaconBuf[bcn_idx];
-		padding = (FrameLen & 0x01);
-		NdisZeroMemory((u8 *)(pBeaconFrame + FrameLen), padding);
-		FrameLen += padding;
-		for (i = 0; i < FrameLen /*HW_BEACON_OFFSET */ ; i += 2) {
-			if (NdisEqualMemory(ptr, pBeaconFrame, 2) == FALSE) {
-				NdisMoveMemory(ptr, pBeaconFrame, 2);
-				/*shortValue = *ptr + (*(ptr+1)<<8); */
-				/*RTMP_IO_WRITE8(pAd, pAd->BeaconOffset[bcn_idx] + TXWI_SIZE + i, shortValue); */
-				RTUSBMultiWrite(pAd,
-						pAd->BeaconOffset[bcn_idx] +
-						TXWI_SIZE + i, ptr, 2);
-			}
-			ptr += 2;
-			pBeaconFrame += 2;
-		}
-
-		pBeaconSync->BeaconBitMap |= (1 << bcn_idx);
-
-		/* For AP interface, set the DtimBitOn so that we can send Bcast/Mcast frame out after this beacon frame. */
-	}
-
-}
-
-void RTUSBBssBeaconStop(struct rt_rtmp_adapter *pAd)
-{
-	struct rt_beacon_sync *pBeaconSync;
-	int i, offset;
-	BOOLEAN Cancelled = TRUE;
-
-	pBeaconSync = pAd->CommonCfg.pBeaconSync;
-	if (pBeaconSync && pBeaconSync->EnableBeacon) {
-		int NumOfBcn;
-
-		{
-			NumOfBcn = MAX_MESH_NUM;
-		}
-
-		RTMPCancelTimer(&pAd->CommonCfg.BeaconUpdateTimer, &Cancelled);
-
-		for (i = 0; i < NumOfBcn; i++) {
-			NdisZeroMemory(pBeaconSync->BeaconBuf[i],
-				       HW_BEACON_OFFSET);
-			NdisZeroMemory(pBeaconSync->BeaconTxWI[i], TXWI_SIZE);
-
-			for (offset = 0; offset < HW_BEACON_OFFSET; offset += 4)
-				RTMP_IO_WRITE32(pAd,
-						pAd->BeaconOffset[i] + offset,
-						0x00);
-
-			pBeaconSync->CapabilityInfoLocationInBeacon[i] = 0;
-			pBeaconSync->TimIELocationInBeacon[i] = 0;
-		}
-		pBeaconSync->BeaconBitMap = 0;
-		pBeaconSync->DtimBitOn = 0;
-	}
-}
-
-void RTUSBBssBeaconStart(struct rt_rtmp_adapter *pAd)
-{
-	int apidx;
-	struct rt_beacon_sync *pBeaconSync;
-/*      LARGE_INTEGER   tsfTime, deltaTime; */
-
-	pBeaconSync = pAd->CommonCfg.pBeaconSync;
-	if (pBeaconSync && pBeaconSync->EnableBeacon) {
-		int NumOfBcn;
-
-		{
-			NumOfBcn = MAX_MESH_NUM;
-		}
-
-		for (apidx = 0; apidx < NumOfBcn; apidx++) {
-			u8 CapabilityInfoLocationInBeacon = 0;
-			u8 TimIELocationInBeacon = 0;
-
-			NdisZeroMemory(pBeaconSync->BeaconBuf[apidx],
-				       HW_BEACON_OFFSET);
-			pBeaconSync->CapabilityInfoLocationInBeacon[apidx] =
-			    CapabilityInfoLocationInBeacon;
-			pBeaconSync->TimIELocationInBeacon[apidx] =
-			    TimIELocationInBeacon;
-			NdisZeroMemory(pBeaconSync->BeaconTxWI[apidx],
-				       TXWI_SIZE);
-		}
-		pBeaconSync->BeaconBitMap = 0;
-		pBeaconSync->DtimBitOn = 0;
-		pAd->CommonCfg.BeaconUpdateTimer.Repeat = TRUE;
-
-		pAd->CommonCfg.BeaconAdjust = 0;
-		pAd->CommonCfg.BeaconFactor =
-		    0xffffffff / (pAd->CommonCfg.BeaconPeriod << 10);
-		pAd->CommonCfg.BeaconRemain =
-		    (0xffffffff % (pAd->CommonCfg.BeaconPeriod << 10)) + 1;
-		DBGPRINT(RT_DEBUG_TRACE,
-			 ("RTUSBBssBeaconStart:BeaconFactor=%d, BeaconRemain=%d!\n",
-			  pAd->CommonCfg.BeaconFactor,
-			  pAd->CommonCfg.BeaconRemain));
-		RTMPSetTimer(&pAd->CommonCfg.BeaconUpdateTimer,
-			     10 /*pAd->CommonCfg.BeaconPeriod */ );
-
-	}
-}
-
-void RTUSBBssBeaconInit(struct rt_rtmp_adapter *pAd)
-{
-	struct rt_beacon_sync *pBeaconSync;
-	int i;
-
-	os_alloc_mem(pAd, (u8 **) (&pAd->CommonCfg.pBeaconSync),
-		     sizeof(struct rt_beacon_sync));
-	/*NdisAllocMemory(pAd->CommonCfg.pBeaconSync, sizeof(struct rt_beacon_sync), MEM_ALLOC_FLAG); */
-	if (pAd->CommonCfg.pBeaconSync) {
-		pBeaconSync = pAd->CommonCfg.pBeaconSync;
-		NdisZeroMemory(pBeaconSync, sizeof(struct rt_beacon_sync));
-		for (i = 0; i < HW_BEACON_MAX_COUNT; i++) {
-			NdisZeroMemory(pBeaconSync->BeaconBuf[i],
-				       HW_BEACON_OFFSET);
-			pBeaconSync->CapabilityInfoLocationInBeacon[i] = 0;
-			pBeaconSync->TimIELocationInBeacon[i] = 0;
-			NdisZeroMemory(pBeaconSync->BeaconTxWI[i], TXWI_SIZE);
-		}
-		pBeaconSync->BeaconBitMap = 0;
-
-		/*RTMPInitTimer(pAd, &pAd->CommonCfg.BeaconUpdateTimer, GET_TIMER_FUNCTION(BeaconUpdateExec), pAd, TRUE); */
-		pBeaconSync->EnableBeacon = TRUE;
-	}
-}
-
-void RTUSBBssBeaconExit(struct rt_rtmp_adapter *pAd)
-{
-	struct rt_beacon_sync *pBeaconSync;
-	BOOLEAN Cancelled = TRUE;
-	int i;
-
-	if (pAd->CommonCfg.pBeaconSync) {
-		pBeaconSync = pAd->CommonCfg.pBeaconSync;
-		pBeaconSync->EnableBeacon = FALSE;
-		RTMPCancelTimer(&pAd->CommonCfg.BeaconUpdateTimer, &Cancelled);
-		pBeaconSync->BeaconBitMap = 0;
-
-		for (i = 0; i < HW_BEACON_MAX_COUNT; i++) {
-			NdisZeroMemory(pBeaconSync->BeaconBuf[i],
-				       HW_BEACON_OFFSET);
-			pBeaconSync->CapabilityInfoLocationInBeacon[i] = 0;
-			pBeaconSync->TimIELocationInBeacon[i] = 0;
-			NdisZeroMemory(pBeaconSync->BeaconTxWI[i], TXWI_SIZE);
-		}
-
-		os_free_mem(pAd, pAd->CommonCfg.pBeaconSync);
-		pAd->CommonCfg.pBeaconSync = NULL;
-	}
-}
-
-/*
-    ========================================================================
-    Routine Description:
-        For device work as AP mode but didn't have TBTT interrupt event, we need a mechanism
-        to update the beacon context in each Beacon interval. Here we use a periodical timer
-        to simulate the TBTT interrupt to handle the beacon context update.
-
-    Arguments:
-        SystemSpecific1         - Not used.
-        FunctionContext         - Pointer to our Adapter context.
-        SystemSpecific2         - Not used.
-        SystemSpecific3         - Not used.
-
-    Return Value:
-        None
-
-    ========================================================================
-*/
-void BeaconUpdateExec(void *SystemSpecific1,
-		      void *FunctionContext,
-		      void *SystemSpecific2, void *SystemSpecific3)
-{
-	struct rt_rtmp_adapter *pAd = (struct rt_rtmp_adapter *)FunctionContext;
-	LARGE_INTEGER tsfTime_a;	/*, tsfTime_b, deltaTime_exp, deltaTime_ab; */
-	u32 delta, delta2MS, period2US, remain, remain_low, remain_high;
-/*      BOOLEAN                 positive; */
-
-	if (pAd->CommonCfg.IsUpdateBeacon == TRUE) {
-		ReSyncBeaconTime(pAd);
-
-	}
-
-	RTMP_IO_READ32(pAd, TSF_TIMER_DW0, &tsfTime_a.u.LowPart);
-	RTMP_IO_READ32(pAd, TSF_TIMER_DW1, &tsfTime_a.u.HighPart);
-
-	/*positive=getDeltaTime(tsfTime_a, expectedTime, &deltaTime_exp); */
-	period2US = (pAd->CommonCfg.BeaconPeriod << 10);
-	remain_high = pAd->CommonCfg.BeaconRemain * tsfTime_a.u.HighPart;
-	remain_low = tsfTime_a.u.LowPart % (pAd->CommonCfg.BeaconPeriod << 10);
-	remain =
-	    (remain_high + remain_low) % (pAd->CommonCfg.BeaconPeriod << 10);
-	delta = (pAd->CommonCfg.BeaconPeriod << 10) - remain;
-
-	delta2MS = (delta >> 10);
-	if (delta2MS > 150) {
-		pAd->CommonCfg.BeaconUpdateTimer.TimerValue = 100;
-		pAd->CommonCfg.IsUpdateBeacon = FALSE;
-	} else {
-		pAd->CommonCfg.BeaconUpdateTimer.TimerValue = delta2MS + 10;
-		pAd->CommonCfg.IsUpdateBeacon = TRUE;
-	}
-
-}
-
-/********************************************************************
-  *
-  *	2870 Radio on/off Related functions.
-  *
-  ********************************************************************/
-void RT28xxUsbMlmeRadioOn(struct rt_rtmp_adapter *pAd)
-{
-	struct rt_rtmp_chip_op *pChipOps = &pAd->chipOps;
-
-	DBGPRINT(RT_DEBUG_TRACE, ("RT28xxUsbMlmeRadioOn()\n"));
-
-	if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF))
-		return;
-
-	{
-		AsicSendCommandToMcu(pAd, 0x31, 0xff, 0x00, 0x02);
-		RTMPusecDelay(10000);
-	}
-	/*NICResetFromError(pAd); */
-
-	/* Enable Tx/Rx */
-	RTMPEnableRxTx(pAd);
-
-	if (pChipOps->AsicReverseRfFromSleepMode)
-		pChipOps->AsicReverseRfFromSleepMode(pAd);
-
-	/* Clear Radio off flag */
-	RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF);
-
-	RTUSBBulkReceive(pAd);
-
-	/* Set LED */
-	RTMPSetLED(pAd, LED_RADIO_ON);
-}
-
-void RT28xxUsbMlmeRadioOFF(struct rt_rtmp_adapter *pAd)
-{
-	WPDMA_GLO_CFG_STRUC GloCfg;
-	u32 Value, i;
-
-	DBGPRINT(RT_DEBUG_TRACE, ("RT28xxUsbMlmeRadioOFF()\n"));
-
-	if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF))
-		return;
-
-	/* Clear PMKID cache. */
-	pAd->StaCfg.SavedPMKNum = 0;
-	RTMPZeroMemory(pAd->StaCfg.SavedPMK, (PMKID_NO * sizeof(struct rt_bssid_info)));
-
-	/* Link down first if any association exists */
-	if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) {
-		if (INFRA_ON(pAd) || ADHOC_ON(pAd)) {
-			struct rt_mlme_disassoc_req DisReq;
-			struct rt_mlme_queue_elem *pMsgElem =
-			    kmalloc(sizeof(struct rt_mlme_queue_elem),
-							MEM_ALLOC_FLAG);
-
-			if (pMsgElem) {
-				COPY_MAC_ADDR(&DisReq.Addr,
-					      pAd->CommonCfg.Bssid);
-				DisReq.Reason = REASON_DISASSOC_STA_LEAVING;
-
-				pMsgElem->Machine = ASSOC_STATE_MACHINE;
-				pMsgElem->MsgType = MT2_MLME_DISASSOC_REQ;
-				pMsgElem->MsgLen =
-				    sizeof(struct rt_mlme_disassoc_req);
-				NdisMoveMemory(pMsgElem->Msg, &DisReq,
-					       sizeof
-					       (struct rt_mlme_disassoc_req));
-
-				MlmeDisassocReqAction(pAd, pMsgElem);
-				kfree(pMsgElem);
-
-				RTMPusecDelay(1000);
-			}
-		}
-	}
-	/* Set Radio off flag */
-	RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF);
-
-	{
-		/* Link down first if any association exists */
-		if (INFRA_ON(pAd) || ADHOC_ON(pAd))
-			LinkDown(pAd, FALSE);
-		RTMPusecDelay(10000);
-
-		/*========================================== */
-		/* Clean up old bss table */
-		BssTableInit(&pAd->ScanTab);
-	}
-
-	/* Set LED */
-	RTMPSetLED(pAd, LED_RADIO_OFF);
-
-	if (pAd->CommonCfg.BBPCurrentBW == BW_40) {
-		/* Must using 40MHz. */
-		AsicTurnOffRFClk(pAd, pAd->CommonCfg.CentralChannel);
-	} else {
-		/* Must using 20MHz. */
-		AsicTurnOffRFClk(pAd, pAd->CommonCfg.Channel);
-	}
-
-	/* Disable Tx/Rx DMA */
-	RTUSBReadMACRegister(pAd, WPDMA_GLO_CFG, &GloCfg.word);	/* disable DMA */
-	GloCfg.field.EnableTxDMA = 0;
-	GloCfg.field.EnableRxDMA = 0;
-	RTUSBWriteMACRegister(pAd, WPDMA_GLO_CFG, GloCfg.word);	/* abort all TX rings */
-
-	/* Waiting for DMA idle */
-	i = 0;
-	do {
-		RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &GloCfg.word);
-		if ((GloCfg.field.TxDMABusy == 0)
-		    && (GloCfg.field.RxDMABusy == 0))
-			break;
-
-		RTMPusecDelay(1000);
-	} while (i++ < 100);
-
-	/* Disable MAC Tx/Rx */
-	RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
-	Value &= (0xfffffff3);
-	RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
-
-	{
-		AsicSendCommandToMcu(pAd, 0x30, 0xff, 0xff, 0x02);
-	}
-}
-
-#endif /* RTMP_MAC_USB // */
diff -druN linux-2.6.39-libre/drivers/staging/rt2860/common/cmm_sanity.c linux-3.0-rc7-libre/drivers/staging/rt2860/common/cmm_sanity.c
--- linux-2.6.39-libre/drivers/staging/rt2860/common/cmm_sanity.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rt2860/common/cmm_sanity.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,1205 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, 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.             *
- *                                                                       *
- *************************************************************************
-
-	Module Name:
-	sanity.c
-
-	Abstract:
-
-	Revision History:
-	Who			When			What
-	--------	----------		----------------------------------------------
-	John Chang  2004-09-01      add WMM support
-*/
-#include "../rt_config.h"
-
-extern u8 CISCO_OUI[];
-
-extern u8 WPA_OUI[];
-extern u8 RSN_OUI[];
-extern u8 WME_INFO_ELEM[];
-extern u8 WME_PARM_ELEM[];
-extern u8 Ccx2QosInfo[];
-extern u8 RALINK_OUI[];
-extern u8 BROADCOM_OUI[];
-extern u8 WPS_OUI[];
-
-/*
-    ==========================================================================
-    Description:
-        MLME message sanity check
-    Return:
-        TRUE if all parameters are OK, FALSE otherwise
-
-	IRQL = DISPATCH_LEVEL
-
-    ==========================================================================
- */
-BOOLEAN MlmeAddBAReqSanity(struct rt_rtmp_adapter *pAd,
-			   void * Msg, unsigned long MsgLen, u8 *pAddr2)
-{
-	struct rt_mlme_addba_req *pInfo;
-
-	pInfo = (struct rt_mlme_addba_req *)Msg;
-
-	if ((MsgLen != sizeof(struct rt_mlme_addba_req))) {
-		DBGPRINT(RT_DEBUG_TRACE,
-			 ("MlmeAddBAReqSanity fail - message length not correct.\n"));
-		return FALSE;
-	}
-
-	if ((pInfo->Wcid >= MAX_LEN_OF_MAC_TABLE)) {
-		DBGPRINT(RT_DEBUG_TRACE,
-			 ("MlmeAddBAReqSanity fail - The peer Mac is not associated yet.\n"));
-		return FALSE;
-	}
-
-	if ((pInfo->pAddr[0] & 0x01) == 0x01) {
-		DBGPRINT(RT_DEBUG_TRACE,
-			 ("MlmeAddBAReqSanity fail - broadcast address not support BA\n"));
-		return FALSE;
-	}
-
-	return TRUE;
-}
-
-/*
-    ==========================================================================
-    Description:
-        MLME message sanity check
-    Return:
-        TRUE if all parameters are OK, FALSE otherwise
-
-	IRQL = DISPATCH_LEVEL
-
-    ==========================================================================
- */
-BOOLEAN MlmeDelBAReqSanity(struct rt_rtmp_adapter *pAd, void * Msg, unsigned long MsgLen)
-{
-	struct rt_mlme_delba_req *pInfo;
-	pInfo = (struct rt_mlme_delba_req *)Msg;
-
-	if ((MsgLen != sizeof(struct rt_mlme_delba_req))) {
-		DBGPRINT(RT_DEBUG_ERROR,
-			 ("MlmeDelBAReqSanity fail - message length not correct.\n"));
-		return FALSE;
-	}
-
-	if ((pInfo->Wcid >= MAX_LEN_OF_MAC_TABLE)) {
-		DBGPRINT(RT_DEBUG_ERROR,
-			 ("MlmeDelBAReqSanity fail - The peer Mac is not associated yet.\n"));
-		return FALSE;
-	}
-
-	if ((pInfo->TID & 0xf0)) {
-		DBGPRINT(RT_DEBUG_ERROR,
-			 ("MlmeDelBAReqSanity fail - The peer TID is incorrect.\n"));
-		return FALSE;
-	}
-
-	if (NdisEqualMemory
-	    (pAd->MacTab.Content[pInfo->Wcid].Addr, pInfo->Addr,
-	     MAC_ADDR_LEN) == 0) {
-		DBGPRINT(RT_DEBUG_ERROR,
-			 ("MlmeDelBAReqSanity fail - the peer addr dosen't exist.\n"));
-		return FALSE;
-	}
-
-	return TRUE;
-}
-
-BOOLEAN PeerAddBAReqActionSanity(struct rt_rtmp_adapter *pAd,
-				 void * pMsg,
-				 unsigned long MsgLen, u8 *pAddr2)
-{
-	struct rt_frame_802_11 * pFrame = (struct rt_frame_802_11 *) pMsg;
-	struct rt_frame_addba_req * pAddFrame;
-	pAddFrame = (struct rt_frame_addba_req *) (pMsg);
-	if (MsgLen < (sizeof(struct rt_frame_addba_req))) {
-		DBGPRINT(RT_DEBUG_ERROR,
-			 ("PeerAddBAReqActionSanity: ADDBA Request frame length size = %ld incorrect\n",
-			  MsgLen));
-		return FALSE;
-	}
-	/* we support immediate BA. */
-	*(u16 *) (&pAddFrame->BaParm) =
-	    cpu2le16(*(u16 *) (&pAddFrame->BaParm));
-	pAddFrame->TimeOutValue = cpu2le16(pAddFrame->TimeOutValue);
-	pAddFrame->BaStartSeq.word = cpu2le16(pAddFrame->BaStartSeq.word);
-
-	if (pAddFrame->BaParm.BAPolicy != IMMED_BA) {
-		DBGPRINT(RT_DEBUG_ERROR,
-			 ("PeerAddBAReqActionSanity: ADDBA Request Ba Policy[%d] not support\n",
-			  pAddFrame->BaParm.BAPolicy));
-		DBGPRINT(RT_DEBUG_ERROR,
-			 ("ADDBA Request. tid=%x, Bufsize=%x, AMSDUSupported=%x \n",
-			  pAddFrame->BaParm.TID, pAddFrame->BaParm.BufSize,
-			  pAddFrame->BaParm.AMSDUSupported));
-		return FALSE;
-	}
-	/* we support immediate BA. */
-	if (pAddFrame->BaParm.TID & 0xfff0) {
-		DBGPRINT(RT_DEBUG_ERROR,
-			 ("PeerAddBAReqActionSanity: ADDBA Request incorrect TID = %d\n",
-			  pAddFrame->BaParm.TID));
-		return FALSE;
-	}
-	COPY_MAC_ADDR(pAddr2, pFrame->Hdr.Addr2);
-	return TRUE;
-}
-
-BOOLEAN PeerAddBARspActionSanity(struct rt_rtmp_adapter *pAd,
-				 void * pMsg, unsigned long MsgLen)
-{
-	struct rt_frame_addba_rsp * pAddFrame;
-
-	pAddFrame = (struct rt_frame_addba_rsp *) (pMsg);
-	if (MsgLen < (sizeof(struct rt_frame_addba_rsp))) {
-		DBGPRINT(RT_DEBUG_ERROR,
-			 ("PeerAddBARspActionSanity: ADDBA Response frame length size = %ld incorrect\n",
-			  MsgLen));
-		return FALSE;
-	}
-	/* we support immediate BA. */
-	*(u16 *) (&pAddFrame->BaParm) =
-	    cpu2le16(*(u16 *) (&pAddFrame->BaParm));
-	pAddFrame->StatusCode = cpu2le16(pAddFrame->StatusCode);
-	pAddFrame->TimeOutValue = cpu2le16(pAddFrame->TimeOutValue);
-
-	if (pAddFrame->BaParm.BAPolicy != IMMED_BA) {
-		DBGPRINT(RT_DEBUG_ERROR,
-			 ("PeerAddBAReqActionSanity: ADDBA Response Ba Policy[%d] not support\n",
-			  pAddFrame->BaParm.BAPolicy));
-		return FALSE;
-	}
-	/* we support immediate BA. */
-	if (pAddFrame->BaParm.TID & 0xfff0) {
-		DBGPRINT(RT_DEBUG_ERROR,
-			 ("PeerAddBARspActionSanity: ADDBA Response incorrect TID = %d\n",
-			  pAddFrame->BaParm.TID));
-		return FALSE;
-	}
-	return TRUE;
-
-}
-
-BOOLEAN PeerDelBAActionSanity(struct rt_rtmp_adapter *pAd,
-			      u8 Wcid, void * pMsg, unsigned long MsgLen)
-{
-	/*struct rt_frame_802_11 * pFrame = (struct rt_frame_802_11 *)pMsg; */
-	struct rt_frame_delba_req * pDelFrame;
-	if (MsgLen != (sizeof(struct rt_frame_delba_req)))
-		return FALSE;
-
-	if (Wcid >= MAX_LEN_OF_MAC_TABLE)
-		return FALSE;
-
-	pDelFrame = (struct rt_frame_delba_req *) (pMsg);
-
-	*(u16 *) (&pDelFrame->DelbaParm) =
-	    cpu2le16(*(u16 *) (&pDelFrame->DelbaParm));
-	pDelFrame->ReasonCode = cpu2le16(pDelFrame->ReasonCode);
-
-	if (pDelFrame->DelbaParm.TID & 0xfff0)
-		return FALSE;
-
-	return TRUE;
-}
-
-/*
-    ==========================================================================
-    Description:
-        MLME message sanity check
-    Return:
-        TRUE if all parameters are OK, FALSE otherwise
-
-	IRQL = DISPATCH_LEVEL
-
-    ==========================================================================
- */
-BOOLEAN PeerBeaconAndProbeRspSanity(struct rt_rtmp_adapter *pAd, void * Msg, unsigned long MsgLen, u8 MsgChannel, u8 *pAddr2, u8 *pBssid, char Ssid[], u8 * pSsidLen, u8 * pBssType, u16 * pBeaconPeriod, u8 * pChannel, u8 * pNewChannel, OUT LARGE_INTEGER * pTimestamp, struct rt_cf_parm * pCfParm, u16 * pAtimWin, u16 * pCapabilityInfo, u8 * pErp, u8 * pDtimCount, u8 * pDtimPeriod, u8 * pBcastFlag, u8 * pMessageToMe, u8 SupRate[], u8 * pSupRateLen, u8 ExtRate[], u8 * pExtRateLen, u8 * pCkipFlag, u8 * pAironetCellPowerLimit, struct rt_edca_parm *pEdcaParm, struct rt_qbss_load_parm *pQbssLoad, struct rt_qos_capability_parm *pQosCapability, unsigned long * pRalinkIe, u8 * pHtCapabilityLen, u8 * pPreNHtCapabilityLen, struct rt_ht_capability_ie * pHtCapability, u8 * AddHtInfoLen, struct rt_add_ht_info_ie * AddHtInfo, u8 * NewExtChannelOffset,	/* Ht extension channel offset(above or below) */
-				    u16 * LengthVIE,
-				    struct rt_ndis_802_11_variable_ies *pVIE)
-{
-	u8 *Ptr;
-	u8 TimLen;
-	struct rt_frame_802_11 * pFrame;
-	struct rt_eid * pEid;
-	u8 SubType;
-	u8 Sanity;
-	/*u8                             ECWMin, ECWMax; */
-	/*MAC_CSR9_STRUC            Csr9; */
-	unsigned long Length = 0;
-
-	/* For some 11a AP which didn't have DS_IE, we use two conditions to decide the channel */
-	/*      1. If the AP is 11n enabled, then check the control channel. */
-	/*      2. If the AP didn't have any info about channel, use the channel we received this frame as the channel. (May inaccuracy!) */
-	u8 CtrlChannel = 0;
-
-	/* Add for 3 necessary EID field check */
-	Sanity = 0;
-
-	*pAtimWin = 0;
-	*pErp = 0;
-	*pDtimCount = 0;
-	*pDtimPeriod = 0;
-	*pBcastFlag = 0;
-	*pMessageToMe = 0;
-	*pExtRateLen = 0;
-	*pCkipFlag = 0;		/* Default of CkipFlag is 0 */
-	*pAironetCellPowerLimit = 0xFF;	/* Default of AironetCellPowerLimit is 0xFF */
-	*LengthVIE = 0;		/* Set the length of VIE to init value 0 */
-	*pHtCapabilityLen = 0;	/* Set the length of VIE to init value 0 */
-	if (pAd->OpMode == OPMODE_STA)
-		*pPreNHtCapabilityLen = 0;	/* Set the length of VIE to init value 0 */
-	*AddHtInfoLen = 0;	/* Set the length of VIE to init value 0 */
-	*pRalinkIe = 0;
-	*pNewChannel = 0;
-	*NewExtChannelOffset = 0xff;	/*Default 0xff means no such IE */
-	pCfParm->bValid = FALSE;	/* default: no IE_CF found */
-	pQbssLoad->bValid = FALSE;	/* default: no IE_QBSS_LOAD found */
-	pEdcaParm->bValid = FALSE;	/* default: no IE_EDCA_PARAMETER found */
-	pQosCapability->bValid = FALSE;	/* default: no IE_QOS_CAPABILITY found */
-
-	pFrame = (struct rt_frame_802_11 *) Msg;
-
-	/* get subtype from header */
-	SubType = (u8)pFrame->Hdr.FC.SubType;
-
-	/* get Addr2 and BSSID from header */
-	COPY_MAC_ADDR(pAddr2, pFrame->Hdr.Addr2);
-	COPY_MAC_ADDR(pBssid, pFrame->Hdr.Addr3);
-
-	Ptr = pFrame->Octet;
-	Length += LENGTH_802_11;
-
-	/* get timestamp from payload and advance the pointer */
-	NdisMoveMemory(pTimestamp, Ptr, TIMESTAMP_LEN);
-
-	pTimestamp->u.LowPart = cpu2le32(pTimestamp->u.LowPart);
-	pTimestamp->u.HighPart = cpu2le32(pTimestamp->u.HighPart);
-
-	Ptr += TIMESTAMP_LEN;
-	Length += TIMESTAMP_LEN;
-
-	/* get beacon interval from payload and advance the pointer */
-	NdisMoveMemory(pBeaconPeriod, Ptr, 2);
-	Ptr += 2;
-	Length += 2;
-
-	/* get capability info from payload and advance the pointer */
-	NdisMoveMemory(pCapabilityInfo, Ptr, 2);
-	Ptr += 2;
-	Length += 2;
-
-	if (CAP_IS_ESS_ON(*pCapabilityInfo))
-		*pBssType = BSS_INFRA;
-	else
-		*pBssType = BSS_ADHOC;
-
-	pEid = (struct rt_eid *) Ptr;
-
-	/* get variable fields from payload and advance the pointer */
-	while ((Length + 2 + pEid->Len) <= MsgLen) {
-		/* */
-		/* Secure copy VIE to VarIE[MAX_VIE_LEN] didn't overflow. */
-		/* */
-		if ((*LengthVIE + pEid->Len + 2) >= MAX_VIE_LEN) {
-			DBGPRINT(RT_DEBUG_WARN,
-				 ("PeerBeaconAndProbeRspSanity - Variable IEs out of resource [len(=%d) > MAX_VIE_LEN(=%d)]\n",
-				  (*LengthVIE + pEid->Len + 2), MAX_VIE_LEN));
-			break;
-		}
-
-		switch (pEid->Eid) {
-		case IE_SSID:
-			/* Already has one SSID EID in this beacon, ignore the second one */
-			if (Sanity & 0x1)
-				break;
-			if (pEid->Len <= MAX_LEN_OF_SSID) {
-				NdisMoveMemory(Ssid, pEid->Octet, pEid->Len);
-				*pSsidLen = pEid->Len;
-				Sanity |= 0x1;
-			} else {
-				DBGPRINT(RT_DEBUG_TRACE,
-					 ("PeerBeaconAndProbeRspSanity - wrong IE_SSID (len=%d)\n",
-					  pEid->Len));
-				return FALSE;
-			}
-			break;
-
-		case IE_SUPP_RATES:
-			if (pEid->Len <= MAX_LEN_OF_SUPPORTED_RATES) {
-				Sanity |= 0x2;
-				NdisMoveMemory(SupRate, pEid->Octet, pEid->Len);
-				*pSupRateLen = pEid->Len;
-
-				/* TODO: 2004-09-14 not a good design here, cause it exclude extra rates */
-				/* from ScanTab. We should report as is. And filter out unsupported */
-				/* rates in MlmeAux. */
-				/* Check against the supported rates */
-				/* RTMPCheckRates(pAd, SupRate, pSupRateLen); */
-			} else {
-				DBGPRINT(RT_DEBUG_TRACE,
-					 ("PeerBeaconAndProbeRspSanity - wrong IE_SUPP_RATES (len=%d)\n",
-					  pEid->Len));
-				return FALSE;
-			}
-			break;
-
-		case IE_HT_CAP:
-			if (pEid->Len >= SIZE_HT_CAP_IE)	/*Note: allow extension! */
-			{
-				NdisMoveMemory(pHtCapability, pEid->Octet,
-					       sizeof(struct rt_ht_capability_ie));
-				*pHtCapabilityLen = SIZE_HT_CAP_IE;	/* Nnow we only support 26 bytes. */
-
-				*(u16 *) (&pHtCapability->HtCapInfo) =
-				    cpu2le16(*(u16 *)
-					     (&pHtCapability->HtCapInfo));
-				*(u16 *) (&pHtCapability->ExtHtCapInfo) =
-				    cpu2le16(*(u16 *)
-					     (&pHtCapability->ExtHtCapInfo));
-
-				{
-					*pPreNHtCapabilityLen = 0;	/* Nnow we only support 26 bytes. */
-
-					Ptr = (u8 *)pVIE;
-					NdisMoveMemory(Ptr + *LengthVIE,
-						       &pEid->Eid,
-						       pEid->Len + 2);
-					*LengthVIE += (pEid->Len + 2);
-				}
-			} else {
-				DBGPRINT(RT_DEBUG_WARN,
-					 ("PeerBeaconAndProbeRspSanity - wrong IE_HT_CAP. pEid->Len = %d\n",
-					  pEid->Len));
-			}
-
-			break;
-		case IE_ADD_HT:
-			if (pEid->Len >= sizeof(struct rt_add_ht_info_ie)) {
-				/* This IE allows extension, but we can ignore extra bytes beyond our knowledge , so only */
-				/* copy first sizeof(struct rt_add_ht_info_ie) */
-				NdisMoveMemory(AddHtInfo, pEid->Octet,
-					       sizeof(struct rt_add_ht_info_ie));
-				*AddHtInfoLen = SIZE_ADD_HT_INFO_IE;
-
-				CtrlChannel = AddHtInfo->ControlChan;
-
-				*(u16 *) (&AddHtInfo->AddHtInfo2) =
-				    cpu2le16(*(u16 *)
-					     (&AddHtInfo->AddHtInfo2));
-				*(u16 *) (&AddHtInfo->AddHtInfo3) =
-				    cpu2le16(*(u16 *)
-					     (&AddHtInfo->AddHtInfo3));
-
-				{
-					Ptr = (u8 *)pVIE;
-					NdisMoveMemory(Ptr + *LengthVIE,
-						       &pEid->Eid,
-						       pEid->Len + 2);
-					*LengthVIE += (pEid->Len + 2);
-				}
-			} else {
-				DBGPRINT(RT_DEBUG_WARN,
-					 ("PeerBeaconAndProbeRspSanity - wrong IE_ADD_HT. \n"));
-			}
-
-			break;
-		case IE_SECONDARY_CH_OFFSET:
-			if (pEid->Len == 1) {
-				*NewExtChannelOffset = pEid->Octet[0];
-			} else {
-				DBGPRINT(RT_DEBUG_WARN,
-					 ("PeerBeaconAndProbeRspSanity - wrong IE_SECONDARY_CH_OFFSET. \n"));
-			}
-
-			break;
-		case IE_FH_PARM:
-			DBGPRINT(RT_DEBUG_TRACE,
-				 ("PeerBeaconAndProbeRspSanity(IE_FH_PARM) \n"));
-			break;
-
-		case IE_DS_PARM:
-			if (pEid->Len == 1) {
-				*pChannel = *pEid->Octet;
-
-				{
-					if (ChannelSanity(pAd, *pChannel) == 0) {
-
-						return FALSE;
-					}
-				}
-
-				Sanity |= 0x4;
-			} else {
-				DBGPRINT(RT_DEBUG_TRACE,
-					 ("PeerBeaconAndProbeRspSanity - wrong IE_DS_PARM (len=%d)\n",
-					  pEid->Len));
-				return FALSE;
-			}
-			break;
-
-		case IE_CF_PARM:
-			if (pEid->Len == 6) {
-				pCfParm->bValid = TRUE;
-				pCfParm->CfpCount = pEid->Octet[0];
-				pCfParm->CfpPeriod = pEid->Octet[1];
-				pCfParm->CfpMaxDuration =
-				    pEid->Octet[2] + 256 * pEid->Octet[3];
-				pCfParm->CfpDurRemaining =
-				    pEid->Octet[4] + 256 * pEid->Octet[5];
-			} else {
-				DBGPRINT(RT_DEBUG_TRACE,
-					 ("PeerBeaconAndProbeRspSanity - wrong IE_CF_PARM\n"));
-				return FALSE;
-			}
-			break;
-
-		case IE_IBSS_PARM:
-			if (pEid->Len == 2) {
-				NdisMoveMemory(pAtimWin, pEid->Octet,
-					       pEid->Len);
-			} else {
-				DBGPRINT(RT_DEBUG_TRACE,
-					 ("PeerBeaconAndProbeRspSanity - wrong IE_IBSS_PARM\n"));
-				return FALSE;
-			}
-			break;
-
-		case IE_TIM:
-			if (INFRA_ON(pAd) && SubType == SUBTYPE_BEACON) {
-				GetTimBit((char *)pEid, pAd->StaActive.Aid,
-					  &TimLen, pBcastFlag, pDtimCount,
-					  pDtimPeriod, pMessageToMe);
-			}
-			break;
-		case IE_CHANNEL_SWITCH_ANNOUNCEMENT:
-			if (pEid->Len == 3) {
-				*pNewChannel = pEid->Octet[1];	/*extract new channel number */
-			}
-			break;
-
-			/* New for WPA */
-			/* CCX v2 has the same IE, we need to parse that too */
-			/* Wifi WMM use the same IE vale, need to parse that too */
-			/* case IE_WPA: */
-		case IE_VENDOR_SPECIFIC:
-			/* Check Broadcom/Atheros 802.11n OUI version, for HT Capability IE. */
-			/* This HT IE is before IEEE draft set HT IE value.2006-09-28 by Jan. */
-			/*if (NdisEqualMemory(pEid->Octet, BROADCOM_OUI, 3) && (pEid->Len >= 4))
-			   {
-			   if ((pEid->Octet[3] == OUI_BROADCOM_HT) && (pEid->Len >= 30))
-			   {
-			   {
-			   NdisMoveMemory(pHtCapability, &pEid->Octet[4], sizeof(struct rt_ht_capability_ie));
-			   *pHtCapabilityLen = SIZE_HT_CAP_IE;  // Nnow we only support 26 bytes.
-			   }
-			   }
-			   if ((pEid->Octet[3] == OUI_BROADCOM_HT) && (pEid->Len >= 26))
-			   {
-			   {
-			   NdisMoveMemory(AddHtInfo, &pEid->Octet[4], sizeof(struct rt_add_ht_info_ie));
-			   *AddHtInfoLen = SIZE_ADD_HT_INFO_IE; // Nnow we only support 26 bytes.
-			   }
-			   }
-			   }
-			 */
-			/* Check the OUI version, filter out non-standard usage */
-			if (NdisEqualMemory(pEid->Octet, RALINK_OUI, 3)
-			    && (pEid->Len == 7)) {
-				/**pRalinkIe = pEid->Octet[3]; */
-				if (pEid->Octet[3] != 0)
-					*pRalinkIe = pEid->Octet[3];
-				else
-					*pRalinkIe = 0xf0000000;	/* Set to non-zero value (can't set bit0-2) to represent this is Ralink Chip. So at linkup, we will set ralinkchip flag. */
-			}
-			/* This HT IE is before IEEE draft set HT IE value.2006-09-28 by Jan. */
-
-			/* Other vendors had production before IE_HT_CAP value is assigned. To backward support those old-firmware AP, */
-			/* Check broadcom-defiend pre-802.11nD1.0 OUI for HT related IE, including HT Capatilities IE and HT Information IE */
-			else if ((*pHtCapabilityLen == 0)
-				 && NdisEqualMemory(pEid->Octet, PRE_N_HT_OUI,
-						    3) && (pEid->Len >= 4)
-				 && (pAd->OpMode == OPMODE_STA)) {
-				if ((pEid->Octet[3] == OUI_PREN_HT_CAP)
-				    && (pEid->Len >= 30)
-				    && (*pHtCapabilityLen == 0)) {
-					NdisMoveMemory(pHtCapability,
-						       &pEid->Octet[4],
-						       sizeof
-						       (struct rt_ht_capability_ie));
-					*pPreNHtCapabilityLen = SIZE_HT_CAP_IE;
-				}
-
-				if ((pEid->Octet[3] == OUI_PREN_ADD_HT)
-				    && (pEid->Len >= 26)) {
-					NdisMoveMemory(AddHtInfo,
-						       &pEid->Octet[4],
-						       sizeof(struct rt_add_ht_info_ie));
-					*AddHtInfoLen = SIZE_ADD_HT_INFO_IE;
-				}
-			} else if (NdisEqualMemory(pEid->Octet, WPA_OUI, 4)) {
-				/* Copy to pVIE which will report to microsoft bssid list. */
-				Ptr = (u8 *)pVIE;
-				NdisMoveMemory(Ptr + *LengthVIE, &pEid->Eid,
-					       pEid->Len + 2);
-				*LengthVIE += (pEid->Len + 2);
-			} else
-			    if (NdisEqualMemory(pEid->Octet, WME_PARM_ELEM, 6)
-				&& (pEid->Len == 24)) {
-				u8 *ptr;
-				int i;
-
-				/* parsing EDCA parameters */
-				pEdcaParm->bValid = TRUE;
-				pEdcaParm->bQAck = FALSE;	/* pEid->Octet[0] & 0x10; */
-				pEdcaParm->bQueueRequest = FALSE;	/* pEid->Octet[0] & 0x20; */
-				pEdcaParm->bTxopRequest = FALSE;	/* pEid->Octet[0] & 0x40; */
-				pEdcaParm->EdcaUpdateCount =
-				    pEid->Octet[6] & 0x0f;
-				pEdcaParm->bAPSDCapable =
-				    (pEid->Octet[6] & 0x80) ? 1 : 0;
-				ptr = &pEid->Octet[8];
-				for (i = 0; i < 4; i++) {
-					u8 aci = (*ptr & 0x60) >> 5;	/* b5~6 is AC INDEX */
-					pEdcaParm->bACM[aci] = (((*ptr) & 0x10) == 0x10);	/* b5 is ACM */
-					pEdcaParm->Aifsn[aci] = (*ptr) & 0x0f;	/* b0~3 is AIFSN */
-					pEdcaParm->Cwmin[aci] = *(ptr + 1) & 0x0f;	/* b0~4 is Cwmin */
-					pEdcaParm->Cwmax[aci] = *(ptr + 1) >> 4;	/* b5~8 is Cwmax */
-					pEdcaParm->Txop[aci] = *(ptr + 2) + 256 * (*(ptr + 3));	/* in unit of 32-us */
-					ptr += 4;	/* point to next AC */
-				}
-			} else
-			    if (NdisEqualMemory(pEid->Octet, WME_INFO_ELEM, 6)
-				&& (pEid->Len == 7)) {
-				/* parsing EDCA parameters */
-				pEdcaParm->bValid = TRUE;
-				pEdcaParm->bQAck = FALSE;	/* pEid->Octet[0] & 0x10; */
-				pEdcaParm->bQueueRequest = FALSE;	/* pEid->Octet[0] & 0x20; */
-				pEdcaParm->bTxopRequest = FALSE;	/* pEid->Octet[0] & 0x40; */
-				pEdcaParm->EdcaUpdateCount =
-				    pEid->Octet[6] & 0x0f;
-				pEdcaParm->bAPSDCapable =
-				    (pEid->Octet[6] & 0x80) ? 1 : 0;
-
-				/* use default EDCA parameter */
-				pEdcaParm->bACM[QID_AC_BE] = 0;
-				pEdcaParm->Aifsn[QID_AC_BE] = 3;
-				pEdcaParm->Cwmin[QID_AC_BE] = CW_MIN_IN_BITS;
-				pEdcaParm->Cwmax[QID_AC_BE] = CW_MAX_IN_BITS;
-				pEdcaParm->Txop[QID_AC_BE] = 0;
-
-				pEdcaParm->bACM[QID_AC_BK] = 0;
-				pEdcaParm->Aifsn[QID_AC_BK] = 7;
-				pEdcaParm->Cwmin[QID_AC_BK] = CW_MIN_IN_BITS;
-				pEdcaParm->Cwmax[QID_AC_BK] = CW_MAX_IN_BITS;
-				pEdcaParm->Txop[QID_AC_BK] = 0;
-
-				pEdcaParm->bACM[QID_AC_VI] = 0;
-				pEdcaParm->Aifsn[QID_AC_VI] = 2;
-				pEdcaParm->Cwmin[QID_AC_VI] =
-				    CW_MIN_IN_BITS - 1;
-				pEdcaParm->Cwmax[QID_AC_VI] = CW_MAX_IN_BITS;
-				pEdcaParm->Txop[QID_AC_VI] = 96;	/* AC_VI: 96*32us ~= 3ms */
-
-				pEdcaParm->bACM[QID_AC_VO] = 0;
-				pEdcaParm->Aifsn[QID_AC_VO] = 2;
-				pEdcaParm->Cwmin[QID_AC_VO] =
-				    CW_MIN_IN_BITS - 2;
-				pEdcaParm->Cwmax[QID_AC_VO] =
-				    CW_MAX_IN_BITS - 1;
-				pEdcaParm->Txop[QID_AC_VO] = 48;	/* AC_VO: 48*32us ~= 1.5ms */
-			}
-
-			break;
-
-		case IE_EXT_SUPP_RATES:
-			if (pEid->Len <= MAX_LEN_OF_SUPPORTED_RATES) {
-				NdisMoveMemory(ExtRate, pEid->Octet, pEid->Len);
-				*pExtRateLen = pEid->Len;
-
-				/* TODO: 2004-09-14 not a good design here, cause it exclude extra rates */
-				/* from ScanTab. We should report as is. And filter out unsupported */
-				/* rates in MlmeAux. */
-				/* Check against the supported rates */
-				/* RTMPCheckRates(pAd, ExtRate, pExtRateLen); */
-			}
-			break;
-
-		case IE_ERP:
-			if (pEid->Len == 1) {
-				*pErp = (u8)pEid->Octet[0];
-			}
-			break;
-
-		case IE_AIRONET_CKIP:
-			/* 0. Check Aironet IE length, it must be larger or equal to 28 */
-			/* Cisco AP350 used length as 28 */
-			/* Cisco AP12XX used length as 30 */
-			if (pEid->Len < (CKIP_NEGOTIATION_LENGTH - 2))
-				break;
-
-			/* 1. Copy CKIP flag byte to buffer for process */
-			*pCkipFlag = *(pEid->Octet + 8);
-			break;
-
-		case IE_AP_TX_POWER:
-			/* AP Control of Client Transmit Power */
-			/*0. Check Aironet IE length, it must be 6 */
-			if (pEid->Len != 0x06)
-				break;
-
-			/* Get cell power limit in dBm */
-			if (NdisEqualMemory(pEid->Octet, CISCO_OUI, 3) == 1)
-				*pAironetCellPowerLimit = *(pEid->Octet + 4);
-			break;
-
-			/* WPA2 & 802.11i RSN */
-		case IE_RSN:
-			/* There is no OUI for version anymore, check the group cipher OUI before copying */
-			if (RTMPEqualMemory(pEid->Octet + 2, RSN_OUI, 3)) {
-				/* Copy to pVIE which will report to microsoft bssid list. */
-				Ptr = (u8 *)pVIE;
-				NdisMoveMemory(Ptr + *LengthVIE, &pEid->Eid,
-					       pEid->Len + 2);
-				*LengthVIE += (pEid->Len + 2);
-			}
-			break;
-
-		default:
-			break;
-		}
-
-		Length = Length + 2 + pEid->Len;	/* Eid[1] + Len[1]+ content[Len] */
-		pEid = (struct rt_eid *) ((u8 *) pEid + 2 + pEid->Len);
-	}
-
-	/* For some 11a AP. it did not have the channel EID, patch here */
-	{
-		u8 LatchRfChannel = MsgChannel;
-		if ((pAd->LatchRfRegs.Channel > 14) && ((Sanity & 0x4) == 0)) {
-			if (CtrlChannel != 0)
-				*pChannel = CtrlChannel;
-			else
-				*pChannel = LatchRfChannel;
-			Sanity |= 0x4;
-		}
-	}
-
-	if (Sanity != 0x7) {
-		DBGPRINT(RT_DEBUG_LOUD,
-			 ("PeerBeaconAndProbeRspSanity - missing field, Sanity=0x%02x\n",
-			  Sanity));
-		return FALSE;
-	} else {
-		return TRUE;
-	}
-
-}
-
-/*
-    ==========================================================================
-    Description:
-        MLME message sanity check
-    Return:
-        TRUE if all parameters are OK, FALSE otherwise
-    ==========================================================================
- */
-BOOLEAN MlmeScanReqSanity(struct rt_rtmp_adapter *pAd,
-			  void * Msg,
-			  unsigned long MsgLen,
-			  u8 * pBssType,
-			  char Ssid[],
-			  u8 * pSsidLen, u8 * pScanType)
-{
-	struct rt_mlme_scan_req *Info;
-
-	Info = (struct rt_mlme_scan_req *)(Msg);
-	*pBssType = Info->BssType;
-	*pSsidLen = Info->SsidLen;
-	NdisMoveMemory(Ssid, Info->Ssid, *pSsidLen);
-	*pScanType = Info->ScanType;
-
-	if ((*pBssType == BSS_INFRA || *pBssType == BSS_ADHOC
-	     || *pBssType == BSS_ANY)
-	    && (*pScanType == SCAN_ACTIVE || *pScanType == SCAN_PASSIVE)) {
-		return TRUE;
-	} else {
-		DBGPRINT(RT_DEBUG_TRACE,
-			 ("MlmeScanReqSanity fail - wrong BssType or ScanType\n"));
-		return FALSE;
-	}
-}
-
-/* IRQL = DISPATCH_LEVEL */
-u8 ChannelSanity(struct rt_rtmp_adapter *pAd, u8 channel)
-{
-	int i;
-
-	for (i = 0; i < pAd->ChannelListNum; i++) {
-		if (channel == pAd->ChannelList[i].Channel)
-			return 1;
-	}
-	return 0;
-}
-
-/*
-    ==========================================================================
-    Description:
-        MLME message sanity check
-    Return:
-        TRUE if all parameters are OK, FALSE otherwise
-
-	IRQL = DISPATCH_LEVEL
-
-    ==========================================================================
- */
-BOOLEAN PeerDeauthSanity(struct rt_rtmp_adapter *pAd,
-			 void * Msg,
-			 unsigned long MsgLen,
-			 u8 *pAddr2, u16 * pReason)
-{
-	struct rt_frame_802_11 * pFrame = (struct rt_frame_802_11 *) Msg;
-
-	COPY_MAC_ADDR(pAddr2, pFrame->Hdr.Addr2);
-	NdisMoveMemory(pReason, &pFrame->Octet[0], 2);
-
-	return TRUE;
-}
-
-/*
-    ==========================================================================
-    Description:
-        MLME message sanity check
-    Return:
-        TRUE if all parameters are OK, FALSE otherwise
-
-	IRQL = DISPATCH_LEVEL
-
-    ==========================================================================
- */
-BOOLEAN PeerAuthSanity(struct rt_rtmp_adapter *pAd,
-		       void * Msg,
-		       unsigned long MsgLen,
-		       u8 *pAddr,
-		       u16 * pAlg,
-		       u16 * pSeq,
-		       u16 * pStatus, char * pChlgText)
-{
-	struct rt_frame_802_11 * pFrame = (struct rt_frame_802_11 *) Msg;
-
-	COPY_MAC_ADDR(pAddr, pFrame->Hdr.Addr2);
-	NdisMoveMemory(pAlg, &pFrame->Octet[0], 2);
-	NdisMoveMemory(pSeq, &pFrame->Octet[2], 2);
-	NdisMoveMemory(pStatus, &pFrame->Octet[4], 2);
-
-	if (*pAlg == AUTH_MODE_OPEN) {
-		if (*pSeq == 1 || *pSeq == 2) {
-			return TRUE;
-		} else {
-			DBGPRINT(RT_DEBUG_TRACE,
-				 ("PeerAuthSanity fail - wrong Seg#\n"));
-			return FALSE;
-		}
-	} else if (*pAlg == AUTH_MODE_KEY) {
-		if (*pSeq == 1 || *pSeq == 4) {
-			return TRUE;
-		} else if (*pSeq == 2 || *pSeq == 3) {
-			NdisMoveMemory(pChlgText, &pFrame->Octet[8],
-				       CIPHER_TEXT_LEN);
-			return TRUE;
-		} else {
-			DBGPRINT(RT_DEBUG_TRACE,
-				 ("PeerAuthSanity fail - wrong Seg#\n"));
-			return FALSE;
-		}
-	} else {
-		DBGPRINT(RT_DEBUG_TRACE,
-			 ("PeerAuthSanity fail - wrong algorithm\n"));
-		return FALSE;
-	}
-}
-
-/*
-    ==========================================================================
-    Description:
-        MLME message sanity check
-    Return:
-        TRUE if all parameters are OK, FALSE otherwise
-    ==========================================================================
- */
-BOOLEAN MlmeAuthReqSanity(struct rt_rtmp_adapter *pAd,
-			  void * Msg,
-			  unsigned long MsgLen,
-			  u8 *pAddr,
-			  unsigned long * pTimeout, u16 * pAlg)
-{
-	struct rt_mlme_auth_req *pInfo;
-
-	pInfo = (struct rt_mlme_auth_req *)Msg;
-	COPY_MAC_ADDR(pAddr, pInfo->Addr);
-	*pTimeout = pInfo->Timeout;
-	*pAlg = pInfo->Alg;
-
-	if (((*pAlg == AUTH_MODE_KEY) || (*pAlg == AUTH_MODE_OPEN)
-	    ) && ((*pAddr & 0x01) == 0)) {
-		return TRUE;
-	} else {
-		DBGPRINT(RT_DEBUG_TRACE,
-			 ("MlmeAuthReqSanity fail - wrong algorithm\n"));
-		return FALSE;
-	}
-}
-
-/*
-    ==========================================================================
-    Description:
-        MLME message sanity check
-    Return:
-        TRUE if all parameters are OK, FALSE otherwise
-
-	IRQL = DISPATCH_LEVEL
-
-    ==========================================================================
- */
-BOOLEAN MlmeAssocReqSanity(struct rt_rtmp_adapter *pAd,
-			   void * Msg,
-			   unsigned long MsgLen,
-			   u8 *pApAddr,
-			   u16 * pCapabilityInfo,
-			   unsigned long * pTimeout, u16 * pListenIntv)
-{
-	struct rt_mlme_assoc_req *pInfo;
-
-	pInfo = (struct rt_mlme_assoc_req *)Msg;
-	*pTimeout = pInfo->Timeout;	/* timeout */
-	COPY_MAC_ADDR(pApAddr, pInfo->Addr);	/* AP address */
-	*pCapabilityInfo = pInfo->CapabilityInfo;	/* capability info */
-	*pListenIntv = pInfo->ListenIntv;
-
-	return TRUE;
-}
-
-/*
-    ==========================================================================
-    Description:
-        MLME message sanity check
-    Return:
-        TRUE if all parameters are OK, FALSE otherwise
-
-	IRQL = DISPATCH_LEVEL
-
-    ==========================================================================
- */
-BOOLEAN PeerDisassocSanity(struct rt_rtmp_adapter *pAd,
-			   void * Msg,
-			   unsigned long MsgLen,
-			   u8 *pAddr2, u16 * pReason)
-{
-	struct rt_frame_802_11 * pFrame = (struct rt_frame_802_11 *) Msg;
-
-	COPY_MAC_ADDR(pAddr2, pFrame->Hdr.Addr2);
-	NdisMoveMemory(pReason, &pFrame->Octet[0], 2);
-
-	return TRUE;
-}
-
-/*
-	========================================================================
-	Routine Description:
-		Sanity check NetworkType (11b, 11g or 11a)
-
-	Arguments:
-		pBss - Pointer to BSS table.
-
-	Return Value:
-        Ndis802_11DS .......(11b)
-        Ndis802_11OFDM24....(11g)
-        Ndis802_11OFDM5.....(11a)
-
-	IRQL = DISPATCH_LEVEL
-
-	========================================================================
-*/
-NDIS_802_11_NETWORK_TYPE NetworkTypeInUseSanity(struct rt_bss_entry *pBss)
-{
-	NDIS_802_11_NETWORK_TYPE NetWorkType;
-	u8 rate, i;
-
-	NetWorkType = Ndis802_11DS;
-
-	if (pBss->Channel <= 14) {
-		/* */
-		/* First check support Rate. */
-		/* */
-		for (i = 0; i < pBss->SupRateLen; i++) {
-			rate = pBss->SupRate[i] & 0x7f;	/* Mask out basic rate set bit */
-			if ((rate == 2) || (rate == 4) || (rate == 11)
-			    || (rate == 22)) {
-				continue;
-			} else {
-				/* */
-				/* Otherwise (even rate > 108) means Ndis802_11OFDM24 */
-				/* */
-				NetWorkType = Ndis802_11OFDM24;
-				break;
-			}
-		}
-
-		/* */
-		/* Second check Extend Rate. */
-		/* */
-		if (NetWorkType != Ndis802_11OFDM24) {
-			for (i = 0; i < pBss->ExtRateLen; i++) {
-				rate = pBss->SupRate[i] & 0x7f;	/* Mask out basic rate set bit */
-				if ((rate == 2) || (rate == 4) || (rate == 11)
-				    || (rate == 22)) {
-					continue;
-				} else {
-					/* */
-					/* Otherwise (even rate > 108) means Ndis802_11OFDM24 */
-					/* */
-					NetWorkType = Ndis802_11OFDM24;
-					break;
-				}
-			}
-		}
-	} else {
-		NetWorkType = Ndis802_11OFDM5;
-	}
-
-	if (pBss->HtCapabilityLen != 0) {
-		if (NetWorkType == Ndis802_11OFDM5)
-			NetWorkType = Ndis802_11OFDM5_N;
-		else
-			NetWorkType = Ndis802_11OFDM24_N;
-	}
-
-	return NetWorkType;
-}
-
-/*
-    ==========================================================================
-    Description:
-        Check the validity of the received EAPoL frame
-    Return:
-        TRUE if all parameters are OK,
-        FALSE otherwise
-    ==========================================================================
- */
-BOOLEAN PeerWpaMessageSanity(struct rt_rtmp_adapter *pAd,
-			     struct rt_eapol_packet * pMsg,
-			     unsigned long MsgLen,
-			     u8 MsgType, struct rt_mac_table_entry *pEntry)
-{
-	u8 mic[LEN_KEY_DESC_MIC], digest[80], KEYDATA[MAX_LEN_OF_RSNIE];
-	BOOLEAN bReplayDiff = FALSE;
-	BOOLEAN bWPA2 = FALSE;
-	struct rt_key_info EapolKeyInfo;
-	u8 GroupKeyIndex = 0;
-
-	NdisZeroMemory(mic, sizeof(mic));
-	NdisZeroMemory(digest, sizeof(digest));
-	NdisZeroMemory(KEYDATA, sizeof(KEYDATA));
-	NdisZeroMemory((u8 *)& EapolKeyInfo, sizeof(EapolKeyInfo));
-
-	NdisMoveMemory((u8 *)& EapolKeyInfo,
-		       (u8 *)& pMsg->KeyDesc.KeyInfo, sizeof(struct rt_key_info));
-
-	*((u16 *) & EapolKeyInfo) = cpu2le16(*((u16 *) & EapolKeyInfo));
-
-	/* Choose WPA2 or not */
-	if ((pEntry->AuthMode == Ndis802_11AuthModeWPA2)
-	    || (pEntry->AuthMode == Ndis802_11AuthModeWPA2PSK))
-		bWPA2 = TRUE;
-
-	/* 0. Check MsgType */
-	if ((MsgType > EAPOL_GROUP_MSG_2) || (MsgType < EAPOL_PAIR_MSG_1)) {
-		DBGPRINT(RT_DEBUG_ERROR,
-			 ("The message type is invalid(%d)! \n", MsgType));
-		return FALSE;
-	}
-	/* 1. Replay counter check */
-	if (MsgType == EAPOL_PAIR_MSG_1 || MsgType == EAPOL_PAIR_MSG_3 || MsgType == EAPOL_GROUP_MSG_1)	/* For supplicant */
-	{
-		/* First validate replay counter, only accept message with larger replay counter. */
-		/* Let equal pass, some AP start with all zero replay counter */
-		u8 ZeroReplay[LEN_KEY_DESC_REPLAY];
-
-		NdisZeroMemory(ZeroReplay, LEN_KEY_DESC_REPLAY);
-		if ((RTMPCompareMemory
-		     (pMsg->KeyDesc.ReplayCounter, pEntry->R_Counter,
-		      LEN_KEY_DESC_REPLAY) != 1)
-		    &&
-		    (RTMPCompareMemory
-		     (pMsg->KeyDesc.ReplayCounter, ZeroReplay,
-		      LEN_KEY_DESC_REPLAY) != 0)) {
-			bReplayDiff = TRUE;
-		}
-	} else if (MsgType == EAPOL_PAIR_MSG_2 || MsgType == EAPOL_PAIR_MSG_4 || MsgType == EAPOL_GROUP_MSG_2)	/* For authenticator */
-	{
-		/* check Replay Counter coresponds to MSG from authenticator, otherwise discard */
-		if (!NdisEqualMemory
-		    (pMsg->KeyDesc.ReplayCounter, pEntry->R_Counter,
-		     LEN_KEY_DESC_REPLAY)) {
-			bReplayDiff = TRUE;
-		}
-	}
-	/* Replay Counter different condition */
-	if (bReplayDiff) {
-		/* send wireless event - for replay counter different */
-		if (pAd->CommonCfg.bWirelessEvent)
-			RTMPSendWirelessEvent(pAd,
-					      IW_REPLAY_COUNTER_DIFF_EVENT_FLAG,
-					      pEntry->Addr, pEntry->apidx, 0);
-
-		if (MsgType < EAPOL_GROUP_MSG_1) {
-			DBGPRINT(RT_DEBUG_ERROR,
-				 ("Replay Counter Different in pairwise msg %d of 4-way handshake!\n",
-				  MsgType));
-		} else {
-			DBGPRINT(RT_DEBUG_ERROR,
-				 ("Replay Counter Different in group msg %d of 2-way handshake!\n",
-				  (MsgType - EAPOL_PAIR_MSG_4)));
-		}
-
-		hex_dump("Receive replay counter ", pMsg->KeyDesc.ReplayCounter,
-			 LEN_KEY_DESC_REPLAY);
-		hex_dump("Current replay counter ", pEntry->R_Counter,
-			 LEN_KEY_DESC_REPLAY);
-		return FALSE;
-	}
-	/* 2. Verify MIC except Pairwise Msg1 */
-	if (MsgType != EAPOL_PAIR_MSG_1) {
-		u8 rcvd_mic[LEN_KEY_DESC_MIC];
-
-		/* Record the received MIC for check later */
-		NdisMoveMemory(rcvd_mic, pMsg->KeyDesc.KeyMic,
-			       LEN_KEY_DESC_MIC);
-		NdisZeroMemory(pMsg->KeyDesc.KeyMic, LEN_KEY_DESC_MIC);
-
-		if (EapolKeyInfo.KeyDescVer == DESC_TYPE_TKIP)	/* TKIP */
-		{
-			HMAC_MD5(pEntry->PTK, LEN_EAP_MICK, (u8 *)pMsg,
-				 MsgLen, mic, MD5_DIGEST_SIZE);
-		} else if (EapolKeyInfo.KeyDescVer == DESC_TYPE_AES)	/* AES */
-		{
-			HMAC_SHA1(pEntry->PTK, LEN_EAP_MICK, (u8 *)pMsg,
-				  MsgLen, digest, SHA1_DIGEST_SIZE);
-			NdisMoveMemory(mic, digest, LEN_KEY_DESC_MIC);
-		}
-
-		if (!NdisEqualMemory(rcvd_mic, mic, LEN_KEY_DESC_MIC)) {
-			/* send wireless event - for MIC different */
-			if (pAd->CommonCfg.bWirelessEvent)
-				RTMPSendWirelessEvent(pAd,
-						      IW_MIC_DIFF_EVENT_FLAG,
-						      pEntry->Addr,
-						      pEntry->apidx, 0);
-
-			if (MsgType < EAPOL_GROUP_MSG_1) {
-				DBGPRINT(RT_DEBUG_ERROR,
-					 ("MIC Different in pairwise msg %d of 4-way handshake!\n",
-					  MsgType));
-			} else {
-				DBGPRINT(RT_DEBUG_ERROR,
-					 ("MIC Different in group msg %d of 2-way handshake!\n",
-					  (MsgType - EAPOL_PAIR_MSG_4)));
-			}
-
-			hex_dump("Received MIC", rcvd_mic, LEN_KEY_DESC_MIC);
-			hex_dump("Desired  MIC", mic, LEN_KEY_DESC_MIC);
-
-			return FALSE;
-		}
-	}
-	/* 1. Decrypt the Key Data field if GTK is included. */
-	/* 2. Extract the context of the Key Data field if it exist. */
-	/* The field in pairwise_msg_2_WPA1(WPA2) & pairwise_msg_3_WPA1 is clear. */
-	/* The field in group_msg_1_WPA1(WPA2) & pairwise_msg_3_WPA2 is encrypted. */
-	if (CONV_ARRARY_TO_u16(pMsg->KeyDesc.KeyDataLen) > 0) {
-		/* Decrypt this field */
-		if ((MsgType == EAPOL_PAIR_MSG_3 && bWPA2)
-		    || (MsgType == EAPOL_GROUP_MSG_1)) {
-			if ((EapolKeyInfo.KeyDescVer == DESC_TYPE_AES)) {
-				/* AES */
-				AES_GTK_KEY_UNWRAP(&pEntry->PTK[16], KEYDATA,
-						   CONV_ARRARY_TO_u16(pMsg->
-									 KeyDesc.
-									 KeyDataLen),
-						   pMsg->KeyDesc.KeyData);
-			} else {
-				int i;
-				u8 Key[32];
-				/* Decrypt TKIP GTK */
-				/* Construct 32 bytes RC4 Key */
-				NdisMoveMemory(Key, pMsg->KeyDesc.KeyIv, 16);
-				NdisMoveMemory(&Key[16], &pEntry->PTK[16], 16);
-				ARCFOUR_INIT(&pAd->PrivateInfo.WEPCONTEXT, Key,
-					     32);
-				/*discard first 256 bytes */
-				for (i = 0; i < 256; i++)
-					ARCFOUR_BYTE(&pAd->PrivateInfo.
-						     WEPCONTEXT);
-				/* Decrypt GTK. Becareful, there is no ICV to check the result is correct or not */
-				ARCFOUR_DECRYPT(&pAd->PrivateInfo.WEPCONTEXT,
-						KEYDATA, pMsg->KeyDesc.KeyData,
-						CONV_ARRARY_TO_u16(pMsg->
-								      KeyDesc.
-								      KeyDataLen));
-			}
-
-			if (!bWPA2 && (MsgType == EAPOL_GROUP_MSG_1))
-				GroupKeyIndex = EapolKeyInfo.KeyIndex;
-
-		} else if ((MsgType == EAPOL_PAIR_MSG_2)
-			   || (MsgType == EAPOL_PAIR_MSG_3 && !bWPA2)) {
-			NdisMoveMemory(KEYDATA, pMsg->KeyDesc.KeyData,
-				       CONV_ARRARY_TO_u16(pMsg->KeyDesc.
-							     KeyDataLen));
-		} else {
-
-			return TRUE;
-		}
-
-		/* Parse Key Data field to */
-		/* 1. verify RSN IE for pairwise_msg_2_WPA1(WPA2) ,pairwise_msg_3_WPA1(WPA2) */
-		/* 2. verify KDE format for pairwise_msg_3_WPA2, group_msg_1_WPA2 */
-		/* 3. update shared key for pairwise_msg_3_WPA2, group_msg_1_WPA1(WPA2) */
-		if (!RTMPParseEapolKeyData(pAd, KEYDATA,
-					   CONV_ARRARY_TO_u16(pMsg->KeyDesc.
-								 KeyDataLen),
-					   GroupKeyIndex, MsgType, bWPA2,
-					   pEntry)) {
-			return FALSE;
-		}
-	}
-
-	return TRUE;
-
-}
diff -druN linux-2.6.39-libre/drivers/staging/rt2860/common/cmm_sync.c linux-3.0-rc7-libre/drivers/staging/rt2860/common/cmm_sync.c
--- linux-2.6.39-libre/drivers/staging/rt2860/common/cmm_sync.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rt2860/common/cmm_sync.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,718 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, 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.             *
- *                                                                       *
- *************************************************************************
-
-	Module Name:
-	cmm_sync.c
-
-	Abstract:
-
-	Revision History:
-	Who			When			What
-	--------	----------		----------------------------------------------
-	John Chang	2004-09-01      modified for rt2561/2661
-*/
-#include "../rt_config.h"
-
-/* 2.4 Ghz channel plan index in the TxPower arrays. */
-#define	BG_BAND_REGION_0_START	0	/* 1,2,3,4,5,6,7,8,9,10,11 */
-#define	BG_BAND_REGION_0_SIZE	11
-#define	BG_BAND_REGION_1_START	0	/* 1,2,3,4,5,6,7,8,9,10,11,12,13 */
-#define	BG_BAND_REGION_1_SIZE	13
-#define	BG_BAND_REGION_2_START	9	/* 10,11 */
-#define	BG_BAND_REGION_2_SIZE	2
-#define	BG_BAND_REGION_3_START	9	/* 10,11,12,13 */
-#define	BG_BAND_REGION_3_SIZE	4
-#define	BG_BAND_REGION_4_START	13	/* 14 */
-#define	BG_BAND_REGION_4_SIZE	1
-#define	BG_BAND_REGION_5_START	0	/* 1,2,3,4,5,6,7,8,9,10,11,12,13,14 */
-#define	BG_BAND_REGION_5_SIZE	14
-#define	BG_BAND_REGION_6_START	2	/* 3,4,5,6,7,8,9 */
-#define	BG_BAND_REGION_6_SIZE	7
-#define	BG_BAND_REGION_7_START	4	/* 5,6,7,8,9,10,11,12,13 */
-#define	BG_BAND_REGION_7_SIZE	9
-#define	BG_BAND_REGION_31_START	0	/* 1,2,3,4,5,6,7,8,9,10,11,12,13,14 */
-#define	BG_BAND_REGION_31_SIZE	14
-
-/* 5 Ghz channel plan index in the TxPower arrays. */
-u8 A_BAND_REGION_0_CHANNEL_LIST[] =
-    { 36, 40, 44, 48, 52, 56, 60, 64, 149, 153, 157, 161, 165 };
-u8 A_BAND_REGION_1_CHANNEL_LIST[] =
-    { 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128,
-132, 136, 140 };
-u8 A_BAND_REGION_2_CHANNEL_LIST[] = { 36, 40, 44, 48, 52, 56, 60, 64 };
-u8 A_BAND_REGION_3_CHANNEL_LIST[] = { 52, 56, 60, 64, 149, 153, 157, 161 };
-u8 A_BAND_REGION_4_CHANNEL_LIST[] = { 149, 153, 157, 161, 165 };
-u8 A_BAND_REGION_5_CHANNEL_LIST[] = { 149, 153, 157, 161 };
-u8 A_BAND_REGION_6_CHANNEL_LIST[] = { 36, 40, 44, 48 };
-u8 A_BAND_REGION_7_CHANNEL_LIST[] =
-    { 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128,
-132, 136, 140, 149, 153, 157, 161, 165, 169, 173 };
-u8 A_BAND_REGION_8_CHANNEL_LIST[] = { 52, 56, 60, 64 };
-u8 A_BAND_REGION_9_CHANNEL_LIST[] =
-    { 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 132, 136, 140,
-149, 153, 157, 161, 165 };
-u8 A_BAND_REGION_10_CHANNEL_LIST[] =
-    { 36, 40, 44, 48, 149, 153, 157, 161, 165 };
-u8 A_BAND_REGION_11_CHANNEL_LIST[] =
-    { 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 149, 153,
-157, 161 };
-u8 A_BAND_REGION_12_CHANNEL_LIST[] =
-    { 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128,
-132, 136, 140 };
-u8 A_BAND_REGION_13_CHANNEL_LIST[] =
-    { 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140,
-149, 153, 157, 161 };
-u8 A_BAND_REGION_14_CHANNEL_LIST[] =
-    { 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 136, 140, 149,
-153, 157, 161, 165 };
-u8 A_BAND_REGION_15_CHANNEL_LIST[] = { 149, 153, 157, 161, 165, 169, 173 };
-
-/*BaSizeArray follows the 802.11n definition as MaxRxFactor.  2^(13+factor) bytes. When factor =0, it's about Ba buffer size =8. */
-u8 BaSizeArray[4] = { 8, 16, 32, 64 };
-
-/*
-	==========================================================================
-	Description:
-		Update StaCfg->ChannelList[] according to 1) Country Region 2) RF IC type,
-		and 3) PHY-mode user selected.
-		The outcome is used by driver when doing site survey.
-
-	IRQL = PASSIVE_LEVEL
-	IRQL = DISPATCH_LEVEL
-
-	==========================================================================
- */
-void BuildChannelList(struct rt_rtmp_adapter *pAd)
-{
-	u8 i, j, index = 0, num = 0;
-	u8 *pChannelList = NULL;
-
-	NdisZeroMemory(pAd->ChannelList,
-		       MAX_NUM_OF_CHANNELS * sizeof(struct rt_channel_tx_power));
-
-	/* if not 11a-only mode, channel list starts from 2.4Ghz band */
-	if ((pAd->CommonCfg.PhyMode != PHY_11A)
-	    && (pAd->CommonCfg.PhyMode != PHY_11AN_MIXED)
-	    && (pAd->CommonCfg.PhyMode != PHY_11N_5G)
-	    ) {
-		switch (pAd->CommonCfg.CountryRegion & 0x7f) {
-		case REGION_0_BG_BAND:	/* 1 -11 */
-			NdisMoveMemory(&pAd->ChannelList[index],
-				       &pAd->TxPower[BG_BAND_REGION_0_START],
-				       sizeof(struct rt_channel_tx_power) *
-				       BG_BAND_REGION_0_SIZE);
-			index += BG_BAND_REGION_0_SIZE;
-			break;
-		case REGION_1_BG_BAND:	/* 1 - 13 */
-			NdisMoveMemory(&pAd->ChannelList[index],
-				       &pAd->TxPower[BG_BAND_REGION_1_START],
-				       sizeof(struct rt_channel_tx_power) *
-				       BG_BAND_REGION_1_SIZE);
-			index += BG_BAND_REGION_1_SIZE;
-			break;
-		case REGION_2_BG_BAND:	/* 10 - 11 */
-			NdisMoveMemory(&pAd->ChannelList[index],
-				       &pAd->TxPower[BG_BAND_REGION_2_START],
-				       sizeof(struct rt_channel_tx_power) *
-				       BG_BAND_REGION_2_SIZE);
-			index += BG_BAND_REGION_2_SIZE;
-			break;
-		case REGION_3_BG_BAND:	/* 10 - 13 */
-			NdisMoveMemory(&pAd->ChannelList[index],
-				       &pAd->TxPower[BG_BAND_REGION_3_START],
-				       sizeof(struct rt_channel_tx_power) *
-				       BG_BAND_REGION_3_SIZE);
-			index += BG_BAND_REGION_3_SIZE;
-			break;
-		case REGION_4_BG_BAND:	/* 14 */
-			NdisMoveMemory(&pAd->ChannelList[index],
-				       &pAd->TxPower[BG_BAND_REGION_4_START],
-				       sizeof(struct rt_channel_tx_power) *
-				       BG_BAND_REGION_4_SIZE);
-			index += BG_BAND_REGION_4_SIZE;
-			break;
-		case REGION_5_BG_BAND:	/* 1 - 14 */
-			NdisMoveMemory(&pAd->ChannelList[index],
-				       &pAd->TxPower[BG_BAND_REGION_5_START],
-				       sizeof(struct rt_channel_tx_power) *
-				       BG_BAND_REGION_5_SIZE);
-			index += BG_BAND_REGION_5_SIZE;
-			break;
-		case REGION_6_BG_BAND:	/* 3 - 9 */
-			NdisMoveMemory(&pAd->ChannelList[index],
-				       &pAd->TxPower[BG_BAND_REGION_6_START],
-				       sizeof(struct rt_channel_tx_power) *
-				       BG_BAND_REGION_6_SIZE);
-			index += BG_BAND_REGION_6_SIZE;
-			break;
-		case REGION_7_BG_BAND:	/* 5 - 13 */
-			NdisMoveMemory(&pAd->ChannelList[index],
-				       &pAd->TxPower[BG_BAND_REGION_7_START],
-				       sizeof(struct rt_channel_tx_power) *
-				       BG_BAND_REGION_7_SIZE);
-			index += BG_BAND_REGION_7_SIZE;
-			break;
-		case REGION_31_BG_BAND:	/* 1 - 14 */
-			NdisMoveMemory(&pAd->ChannelList[index],
-				       &pAd->TxPower[BG_BAND_REGION_31_START],
-				       sizeof(struct rt_channel_tx_power) *
-				       BG_BAND_REGION_31_SIZE);
-			index += BG_BAND_REGION_31_SIZE;
-			break;
-		default:	/* Error. should never happen */
-			break;
-		}
-		for (i = 0; i < index; i++)
-			pAd->ChannelList[i].MaxTxPwr = 20;
-	}
-
-	if ((pAd->CommonCfg.PhyMode == PHY_11A)
-	    || (pAd->CommonCfg.PhyMode == PHY_11ABG_MIXED)
-	    || (pAd->CommonCfg.PhyMode == PHY_11ABGN_MIXED)
-	    || (pAd->CommonCfg.PhyMode == PHY_11AN_MIXED)
-	    || (pAd->CommonCfg.PhyMode == PHY_11AGN_MIXED)
-	    || (pAd->CommonCfg.PhyMode == PHY_11N_5G)
-	    ) {
-		switch (pAd->CommonCfg.CountryRegionForABand & 0x7f) {
-		case REGION_0_A_BAND:
-			num =
-			    sizeof(A_BAND_REGION_0_CHANNEL_LIST) /
-			    sizeof(u8);
-			pChannelList = A_BAND_REGION_0_CHANNEL_LIST;
-			break;
-		case REGION_1_A_BAND:
-			num =
-			    sizeof(A_BAND_REGION_1_CHANNEL_LIST) /
-			    sizeof(u8);
-			pChannelList = A_BAND_REGION_1_CHANNEL_LIST;
-			break;
-		case REGION_2_A_BAND:
-			num =
-			    sizeof(A_BAND_REGION_2_CHANNEL_LIST) /
-			    sizeof(u8);
-			pChannelList = A_BAND_REGION_2_CHANNEL_LIST;
-			break;
-		case REGION_3_A_BAND:
-			num =
-			    sizeof(A_BAND_REGION_3_CHANNEL_LIST) /
-			    sizeof(u8);
-			pChannelList = A_BAND_REGION_3_CHANNEL_LIST;
-			break;
-		case REGION_4_A_BAND:
-			num =
-			    sizeof(A_BAND_REGION_4_CHANNEL_LIST) /
-			    sizeof(u8);
-			pChannelList = A_BAND_REGION_4_CHANNEL_LIST;
-			break;
-		case REGION_5_A_BAND:
-			num =
-			    sizeof(A_BAND_REGION_5_CHANNEL_LIST) /
-			    sizeof(u8);
-			pChannelList = A_BAND_REGION_5_CHANNEL_LIST;
-			break;
-		case REGION_6_A_BAND:
-			num =
-			    sizeof(A_BAND_REGION_6_CHANNEL_LIST) /
-			    sizeof(u8);
-			pChannelList = A_BAND_REGION_6_CHANNEL_LIST;
-			break;
-		case REGION_7_A_BAND:
-			num =
-			    sizeof(A_BAND_REGION_7_CHANNEL_LIST) /
-			    sizeof(u8);
-			pChannelList = A_BAND_REGION_7_CHANNEL_LIST;
-			break;
-		case REGION_8_A_BAND:
-			num =
-			    sizeof(A_BAND_REGION_8_CHANNEL_LIST) /
-			    sizeof(u8);
-			pChannelList = A_BAND_REGION_8_CHANNEL_LIST;
-			break;
-		case REGION_9_A_BAND:
-			num =
-			    sizeof(A_BAND_REGION_9_CHANNEL_LIST) /
-			    sizeof(u8);
-			pChannelList = A_BAND_REGION_9_CHANNEL_LIST;
-			break;
-
-		case REGION_10_A_BAND:
-			num =
-			    sizeof(A_BAND_REGION_10_CHANNEL_LIST) /
-			    sizeof(u8);
-			pChannelList = A_BAND_REGION_10_CHANNEL_LIST;
-			break;
-
-		case REGION_11_A_BAND:
-			num =
-			    sizeof(A_BAND_REGION_11_CHANNEL_LIST) /
-			    sizeof(u8);
-			pChannelList = A_BAND_REGION_11_CHANNEL_LIST;
-			break;
-		case REGION_12_A_BAND:
-			num =
-			    sizeof(A_BAND_REGION_12_CHANNEL_LIST) /
-			    sizeof(u8);
-			pChannelList = A_BAND_REGION_12_CHANNEL_LIST;
-			break;
-		case REGION_13_A_BAND:
-			num =
-			    sizeof(A_BAND_REGION_13_CHANNEL_LIST) /
-			    sizeof(u8);
-			pChannelList = A_BAND_REGION_13_CHANNEL_LIST;
-			break;
-		case REGION_14_A_BAND:
-			num =
-			    sizeof(A_BAND_REGION_14_CHANNEL_LIST) /
-			    sizeof(u8);
-			pChannelList = A_BAND_REGION_14_CHANNEL_LIST;
-			break;
-		case REGION_15_A_BAND:
-			num =
-			    sizeof(A_BAND_REGION_15_CHANNEL_LIST) /
-			    sizeof(u8);
-			pChannelList = A_BAND_REGION_15_CHANNEL_LIST;
-			break;
-		default:	/* Error. should never happen */
-			DBGPRINT(RT_DEBUG_WARN,
-				 ("countryregion=%d not support",
-				  pAd->CommonCfg.CountryRegionForABand));
-			break;
-		}
-
-		if (num != 0) {
-			u8 RadarCh[15] =
-			    { 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124,
-		    128, 132, 136, 140 };
-			for (i = 0; i < num; i++) {
-				for (j = 0; j < MAX_NUM_OF_CHANNELS; j++) {
-					if (pChannelList[i] ==
-					    pAd->TxPower[j].Channel)
-						NdisMoveMemory(&pAd->
-							       ChannelList[index
-									   + i],
-							       &pAd->TxPower[j],
-							       sizeof
-							       (struct rt_channel_tx_power));
-				}
-				for (j = 0; j < 15; j++) {
-					if (pChannelList[i] == RadarCh[j])
-						pAd->ChannelList[index +
-								 i].DfsReq =
-						    TRUE;
-				}
-				pAd->ChannelList[index + i].MaxTxPwr = 20;
-			}
-			index += num;
-		}
-	}
-
-	pAd->ChannelListNum = index;
-	DBGPRINT(RT_DEBUG_TRACE,
-		 ("country code=%d/%d, RFIC=%d, PHY mode=%d, support %d channels\n",
-		  pAd->CommonCfg.CountryRegion,
-		  pAd->CommonCfg.CountryRegionForABand, pAd->RfIcType,
-		  pAd->CommonCfg.PhyMode, pAd->ChannelListNum));
-#ifdef DBG
-	for (i = 0; i < pAd->ChannelListNum; i++) {
-		DBGPRINT_RAW(RT_DEBUG_TRACE,
-			     ("BuildChannel # %d :: Pwr0 = %d, Pwr1 =%d, \n ",
-			      pAd->ChannelList[i].Channel,
-			      pAd->ChannelList[i].Power,
-			      pAd->ChannelList[i].Power2));
-	}
-#endif
-}
-
-/*
-	==========================================================================
-	Description:
-		This routine return the first channel number according to the country
-		code selection and RF IC selection (signal band or dual band). It is called
-		whenever driver need to start a site survey of all supported channels.
-	Return:
-		ch - the first channel number of current country code setting
-
-	IRQL = PASSIVE_LEVEL
-
-	==========================================================================
- */
-u8 FirstChannel(struct rt_rtmp_adapter *pAd)
-{
-	return pAd->ChannelList[0].Channel;
-}
-
-/*
-	==========================================================================
-	Description:
-		This routine returns the next channel number. This routine is called
-		during driver need to start a site survey of all supported channels.
-	Return:
-		next_channel - the next channel number valid in current country code setting.
-	Note:
-		return 0 if no more next channel
-	==========================================================================
- */
-u8 NextChannel(struct rt_rtmp_adapter *pAd, u8 channel)
-{
-	int i;
-	u8 next_channel = 0;
-
-	for (i = 0; i < (pAd->ChannelListNum - 1); i++)
-		if (channel == pAd->ChannelList[i].Channel) {
-			next_channel = pAd->ChannelList[i + 1].Channel;
-			break;
-		}
-	return next_channel;
-}
-
-/*
-	==========================================================================
-	Description:
-		This routine is for Cisco Compatible Extensions 2.X
-		Spec31. AP Control of Client Transmit Power
-	Return:
-		None
-	Note:
-	   Required by Aironet dBm(mW)
-		   0dBm(1mW),   1dBm(5mW), 13dBm(20mW), 15dBm(30mW),
-		  17dBm(50mw), 20dBm(100mW)
-
-	   We supported
-		   3dBm(Lowest), 6dBm(10%), 9dBm(25%), 12dBm(50%),
-		  14dBm(75%),   15dBm(100%)
-
-		The client station's actual transmit power shall be within +/- 5dB of
-		the minimum value or next lower value.
-	==========================================================================
- */
-void ChangeToCellPowerLimit(struct rt_rtmp_adapter *pAd,
-			    u8 AironetCellPowerLimit)
-{
-	/*valud 0xFF means that hasn't found power limit information */
-	/*from the AP's Beacon/Probe response. */
-	if (AironetCellPowerLimit == 0xFF)
-		return;
-
-	if (AironetCellPowerLimit < 6)	/*Used Lowest Power Percentage. */
-		pAd->CommonCfg.TxPowerPercentage = 6;
-	else if (AironetCellPowerLimit < 9)
-		pAd->CommonCfg.TxPowerPercentage = 10;
-	else if (AironetCellPowerLimit < 12)
-		pAd->CommonCfg.TxPowerPercentage = 25;
-	else if (AironetCellPowerLimit < 14)
-		pAd->CommonCfg.TxPowerPercentage = 50;
-	else if (AironetCellPowerLimit < 15)
-		pAd->CommonCfg.TxPowerPercentage = 75;
-	else
-		pAd->CommonCfg.TxPowerPercentage = 100;	/*else used maximum */
-
-	if (pAd->CommonCfg.TxPowerPercentage > pAd->CommonCfg.TxPowerDefault)
-		pAd->CommonCfg.TxPowerPercentage =
-		    pAd->CommonCfg.TxPowerDefault;
-
-}
-
-char ConvertToRssi(struct rt_rtmp_adapter *pAd, char Rssi, u8 RssiNumber)
-{
-	u8 RssiOffset, LNAGain;
-
-	/* Rssi equals to zero should be an invalid value */
-	if (Rssi == 0)
-		return -99;
-
-	LNAGain = GET_LNA_GAIN(pAd);
-	if (pAd->LatchRfRegs.Channel > 14) {
-		if (RssiNumber == 0)
-			RssiOffset = pAd->ARssiOffset0;
-		else if (RssiNumber == 1)
-			RssiOffset = pAd->ARssiOffset1;
-		else
-			RssiOffset = pAd->ARssiOffset2;
-	} else {
-		if (RssiNumber == 0)
-			RssiOffset = pAd->BGRssiOffset0;
-		else if (RssiNumber == 1)
-			RssiOffset = pAd->BGRssiOffset1;
-		else
-			RssiOffset = pAd->BGRssiOffset2;
-	}
-
-	return (-12 - RssiOffset - LNAGain - Rssi);
-}
-
-/*
-	==========================================================================
-	Description:
-		Scan next channel
-	==========================================================================
- */
-void ScanNextChannel(struct rt_rtmp_adapter *pAd)
-{
-	struct rt_header_802_11 Hdr80211;
-	u8 *pOutBuffer = NULL;
-	int NStatus;
-	unsigned long FrameLen = 0;
-	u8 SsidLen = 0, ScanType = pAd->MlmeAux.ScanType, BBPValue = 0;
-	u16 Status;
-	struct rt_header_802_11 * pHdr80211;
-	u32 ScanTimeIn5gChannel = SHORT_CHANNEL_TIME;
-
-	{
-		if (MONITOR_ON(pAd))
-			return;
-	}
-
-	if (pAd->MlmeAux.Channel == 0) {
-		if ((pAd->CommonCfg.BBPCurrentBW == BW_40)
-		    && (INFRA_ON(pAd)
-			|| (pAd->OpMode == OPMODE_AP))
-		    ) {
-			AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel,
-					  FALSE);
-			AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel);
-			RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue);
-			BBPValue &= (~0x18);
-			BBPValue |= 0x10;
-			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue);
-			DBGPRINT(RT_DEBUG_TRACE,
-				 ("SYNC - End of SCAN, restore to 40MHz channel %d, Total BSS[%02d]\n",
-				  pAd->CommonCfg.CentralChannel,
-				  pAd->ScanTab.BssNr));
-		} else {
-			AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
-			AsicLockChannel(pAd, pAd->CommonCfg.Channel);
-			DBGPRINT(RT_DEBUG_TRACE,
-				 ("SYNC - End of SCAN, restore to channel %d, Total BSS[%02d]\n",
-				  pAd->CommonCfg.Channel, pAd->ScanTab.BssNr));
-		}
-
-		{
-			/* */
-			/* To prevent data lost. */
-			/* Send an NULL data with turned PSM bit on to current associated AP before SCAN progress. */
-			/* Now, we need to send an NULL data with turned PSM bit off to AP, when scan progress done */
-			/* */
-			if (OPSTATUS_TEST_FLAG
-			    (pAd, fOP_STATUS_MEDIA_STATE_CONNECTED)
-			    && (INFRA_ON(pAd))) {
-				NStatus =
-				    MlmeAllocateMemory(pAd,
-						       (void *)& pOutBuffer);
-				if (NStatus == NDIS_STATUS_SUCCESS) {
-					pHdr80211 = (struct rt_header_802_11 *) pOutBuffer;
-					MgtMacHeaderInit(pAd, pHdr80211,
-							 SUBTYPE_NULL_FUNC, 1,
-							 pAd->CommonCfg.Bssid,
-							 pAd->CommonCfg.Bssid);
-					pHdr80211->Duration = 0;
-					pHdr80211->FC.Type = BTYPE_DATA;
-					pHdr80211->FC.PwrMgmt =
-					    (pAd->StaCfg.Psm == PWR_SAVE);
-
-					/* Send using priority queue */
-					MiniportMMRequest(pAd, 0, pOutBuffer,
-							  sizeof
-							  (struct rt_header_802_11));
-					DBGPRINT(RT_DEBUG_TRACE,
-						 ("MlmeScanReqAction -- Send PSM Data frame\n"));
-					MlmeFreeMemory(pAd, pOutBuffer);
-					RTMPusecDelay(5000);
-				}
-			}
-
-			pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
-			Status = MLME_SUCCESS;
-			MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_SCAN_CONF,
-				    2, &Status);
-		}
-
-		RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS);
-	}
-#ifdef RTMP_MAC_USB
-	else if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)
-		 && (pAd->OpMode == OPMODE_STA)) {
-		pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
-		MlmeCntlConfirm(pAd, MT2_SCAN_CONF, MLME_FAIL_NO_RESOURCE);
-	}
-#endif /* RTMP_MAC_USB // */
-	else {
-		{
-			/* BBP and RF are not accessible in PS mode, we has to wake them up first */
-			if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
-				AsicForceWakeup(pAd, TRUE);
-
-			/* leave PSM during scanning. otherwise we may lost ProbeRsp & BEACON */
-			if (pAd->StaCfg.Psm == PWR_SAVE)
-				RTMP_SET_PSM_BIT(pAd, PWR_ACTIVE);
-		}
-
-		AsicSwitchChannel(pAd, pAd->MlmeAux.Channel, TRUE);
-		AsicLockChannel(pAd, pAd->MlmeAux.Channel);
-
-		{
-			if (pAd->MlmeAux.Channel > 14) {
-				if ((pAd->CommonCfg.bIEEE80211H == 1)
-				    && RadarChannelCheck(pAd,
-							 pAd->MlmeAux.
-							 Channel)) {
-					ScanType = SCAN_PASSIVE;
-					ScanTimeIn5gChannel = MIN_CHANNEL_TIME;
-				}
-			}
-		}
-
-		/*Global country domain(ch1-11:active scan, ch12-14 passive scan) */
-		if ((pAd->MlmeAux.Channel <= 14) && (pAd->MlmeAux.Channel >= 12)
-		    && ((pAd->CommonCfg.CountryRegion & 0x7f) ==
-			REGION_31_BG_BAND)) {
-			ScanType = SCAN_PASSIVE;
-		}
-		/* We need to shorten active scan time in order for WZC connect issue */
-		/* Chnage the channel scan time for CISCO stuff based on its IAPP announcement */
-		if (ScanType == FAST_SCAN_ACTIVE)
-			RTMPSetTimer(&pAd->MlmeAux.ScanTimer,
-				     FAST_ACTIVE_SCAN_TIME);
-		else		/* must be SCAN_PASSIVE or SCAN_ACTIVE */
-		{
-			if ((pAd->CommonCfg.PhyMode == PHY_11ABG_MIXED)
-			    || (pAd->CommonCfg.PhyMode == PHY_11ABGN_MIXED)
-			    || (pAd->CommonCfg.PhyMode == PHY_11AGN_MIXED)
-			    ) {
-				if (pAd->MlmeAux.Channel > 14)
-					RTMPSetTimer(&pAd->MlmeAux.ScanTimer,
-						     ScanTimeIn5gChannel);
-				else
-					RTMPSetTimer(&pAd->MlmeAux.ScanTimer,
-						     MIN_CHANNEL_TIME);
-			} else
-				RTMPSetTimer(&pAd->MlmeAux.ScanTimer,
-					     MAX_CHANNEL_TIME);
-		}
-
-		if ((ScanType == SCAN_ACTIVE)
-		    || (ScanType == FAST_SCAN_ACTIVE)
-		    ) {
-			NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);	/*Get an unused nonpaged memory */
-			if (NStatus != NDIS_STATUS_SUCCESS) {
-				DBGPRINT(RT_DEBUG_TRACE,
-					 ("SYNC - ScanNextChannel() allocate memory fail\n"));
-
-				{
-					pAd->Mlme.SyncMachine.CurrState =
-					    SYNC_IDLE;
-					Status = MLME_FAIL_NO_RESOURCE;
-					MlmeEnqueue(pAd,
-						    MLME_CNTL_STATE_MACHINE,
-						    MT2_SCAN_CONF, 2, &Status);
-				}
-
-				return;
-			}
-			/* There is no need to send broadcast probe request if active scan is in effect. */
-			if ((ScanType == SCAN_ACTIVE)
-			    || (ScanType == FAST_SCAN_ACTIVE)
-			    )
-				SsidLen = pAd->MlmeAux.SsidLen;
-			else
-				SsidLen = 0;
-
-			MgtMacHeaderInit(pAd, &Hdr80211, SUBTYPE_PROBE_REQ, 0,
-					 BROADCAST_ADDR, BROADCAST_ADDR);
-			MakeOutgoingFrame(pOutBuffer, &FrameLen,
-					  sizeof(struct rt_header_802_11), &Hdr80211, 1,
-					  &SsidIe, 1, &SsidLen, SsidLen,
-					  pAd->MlmeAux.Ssid, 1, &SupRateIe, 1,
-					  &pAd->CommonCfg.SupRateLen,
-					  pAd->CommonCfg.SupRateLen,
-					  pAd->CommonCfg.SupRate, END_OF_ARGS);
-
-			if (pAd->CommonCfg.ExtRateLen) {
-				unsigned long Tmp;
-				MakeOutgoingFrame(pOutBuffer + FrameLen, &Tmp,
-						  1, &ExtRateIe,
-						  1, &pAd->CommonCfg.ExtRateLen,
-						  pAd->CommonCfg.ExtRateLen,
-						  pAd->CommonCfg.ExtRate,
-						  END_OF_ARGS);
-				FrameLen += Tmp;
-			}
-
-			if (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED) {
-				unsigned long Tmp;
-				u8 HtLen;
-				u8 BROADCOM[4] = { 0x0, 0x90, 0x4c, 0x33 };
-
-				if (pAd->bBroadComHT == TRUE) {
-					HtLen =
-					    pAd->MlmeAux.HtCapabilityLen + 4;
-
-					MakeOutgoingFrame(pOutBuffer + FrameLen,
-							  &Tmp, 1, &WpaIe, 1,
-							  &HtLen, 4,
-							  &BROADCOM[0],
-							  pAd->MlmeAux.
-							  HtCapabilityLen,
-							  &pAd->MlmeAux.
-							  HtCapability,
-							  END_OF_ARGS);
-				} else {
-					HtLen = pAd->MlmeAux.HtCapabilityLen;
-
-					MakeOutgoingFrame(pOutBuffer + FrameLen,
-							  &Tmp, 1, &HtCapIe, 1,
-							  &HtLen, HtLen,
-							  &pAd->CommonCfg.
-							  HtCapability,
-							  END_OF_ARGS);
-				}
-				FrameLen += Tmp;
-			}
-
-			MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
-			MlmeFreeMemory(pAd, pOutBuffer);
-		}
-		/* For SCAN_CISCO_PASSIVE, do nothing and silently wait for beacon or other probe response */
-
-		pAd->Mlme.SyncMachine.CurrState = SCAN_LISTEN;
-	}
-}
-
-void MgtProbReqMacHeaderInit(struct rt_rtmp_adapter *pAd,
-			     struct rt_header_802_11 * pHdr80211,
-			     u8 SubType,
-			     u8 ToDs, u8 *pDA, u8 *pBssid)
-{
-	NdisZeroMemory(pHdr80211, sizeof(struct rt_header_802_11));
-
-	pHdr80211->FC.Type = BTYPE_MGMT;
-	pHdr80211->FC.SubType = SubType;
-	if (SubType == SUBTYPE_ACK)
-		pHdr80211->FC.Type = BTYPE_CNTL;
-	pHdr80211->FC.ToDs = ToDs;
-	COPY_MAC_ADDR(pHdr80211->Addr1, pDA);
-	COPY_MAC_ADDR(pHdr80211->Addr2, pAd->CurrentAddress);
-	COPY_MAC_ADDR(pHdr80211->Addr3, pBssid);
-}
diff -druN linux-2.6.39-libre/drivers/staging/rt2860/common/cmm_tkip.c linux-3.0-rc7-libre/drivers/staging/rt2860/common/cmm_tkip.c
--- linux-2.6.39-libre/drivers/staging/rt2860/common/cmm_tkip.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rt2860/common/cmm_tkip.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,833 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, 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.             *
- *                                                                       *
- *************************************************************************
-
-	Module Name:
-	cmm_tkip.c
-
-	Abstract:
-
-	Revision History:
-	Who			When			What
-	--------	----------		----------------------------------------------
-	Paul Wu		02-25-02		Initial
-*/
-
-#include	"../rt_config.h"
-
-/* Rotation functions on 32 bit values */
-#define ROL32( A, n ) \
-	( ((A) << (n)) | ( ((A)>>(32-(n))) & ( (1UL << (n)) - 1 ) ) )
-#define ROR32( A, n ) ROL32( (A), 32-(n) )
-
-u32 Tkip_Sbox_Lower[256] = {
-	0xA5, 0x84, 0x99, 0x8D, 0x0D, 0xBD, 0xB1, 0x54,
-	0x50, 0x03, 0xA9, 0x7D, 0x19, 0x62, 0xE6, 0x9A,
-	0x45, 0x9D, 0x40, 0x87, 0x15, 0xEB, 0xC9, 0x0B,
-	0xEC, 0x67, 0xFD, 0xEA, 0xBF, 0xF7, 0x96, 0x5B,
-	0xC2, 0x1C, 0xAE, 0x6A, 0x5A, 0x41, 0x02, 0x4F,
-	0x5C, 0xF4, 0x34, 0x08, 0x93, 0x73, 0x53, 0x3F,
-	0x0C, 0x52, 0x65, 0x5E, 0x28, 0xA1, 0x0F, 0xB5,
-	0x09, 0x36, 0x9B, 0x3D, 0x26, 0x69, 0xCD, 0x9F,
-	0x1B, 0x9E, 0x74, 0x2E, 0x2D, 0xB2, 0xEE, 0xFB,
-	0xF6, 0x4D, 0x61, 0xCE, 0x7B, 0x3E, 0x71, 0x97,
-	0xF5, 0x68, 0x00, 0x2C, 0x60, 0x1F, 0xC8, 0xED,
-	0xBE, 0x46, 0xD9, 0x4B, 0xDE, 0xD4, 0xE8, 0x4A,
-	0x6B, 0x2A, 0xE5, 0x16, 0xC5, 0xD7, 0x55, 0x94,
-	0xCF, 0x10, 0x06, 0x81, 0xF0, 0x44, 0xBA, 0xE3,
-	0xF3, 0xFE, 0xC0, 0x8A, 0xAD, 0xBC, 0x48, 0x04,
-	0xDF, 0xC1, 0x75, 0x63, 0x30, 0x1A, 0x0E, 0x6D,
-	0x4C, 0x14, 0x35, 0x2F, 0xE1, 0xA2, 0xCC, 0x39,
-	0x57, 0xF2, 0x82, 0x47, 0xAC, 0xE7, 0x2B, 0x95,
-	0xA0, 0x98, 0xD1, 0x7F, 0x66, 0x7E, 0xAB, 0x83,
-	0xCA, 0x29, 0xD3, 0x3C, 0x79, 0xE2, 0x1D, 0x76,
-	0x3B, 0x56, 0x4E, 0x1E, 0xDB, 0x0A, 0x6C, 0xE4,
-	0x5D, 0x6E, 0xEF, 0xA6, 0xA8, 0xA4, 0x37, 0x8B,
-	0x32, 0x43, 0x59, 0xB7, 0x8C, 0x64, 0xD2, 0xE0,
-	0xB4, 0xFA, 0x07, 0x25, 0xAF, 0x8E, 0xE9, 0x18,
-	0xD5, 0x88, 0x6F, 0x72, 0x24, 0xF1, 0xC7, 0x51,
-	0x23, 0x7C, 0x9C, 0x21, 0xDD, 0xDC, 0x86, 0x85,
-	0x90, 0x42, 0xC4, 0xAA, 0xD8, 0x05, 0x01, 0x12,
-	0xA3, 0x5F, 0xF9, 0xD0, 0x91, 0x58, 0x27, 0xB9,
-	0x38, 0x13, 0xB3, 0x33, 0xBB, 0x70, 0x89, 0xA7,
-	0xB6, 0x22, 0x92, 0x20, 0x49, 0xFF, 0x78, 0x7A,
-	0x8F, 0xF8, 0x80, 0x17, 0xDA, 0x31, 0xC6, 0xB8,
-	0xC3, 0xB0, 0x77, 0x11, 0xCB, 0xFC, 0xD6, 0x3A
-};
-
-u32 Tkip_Sbox_Upper[256] = {
-	0xC6, 0xF8, 0xEE, 0xF6, 0xFF, 0xD6, 0xDE, 0x91,
-	0x60, 0x02, 0xCE, 0x56, 0xE7, 0xB5, 0x4D, 0xEC,
-	0x8F, 0x1F, 0x89, 0xFA, 0xEF, 0xB2, 0x8E, 0xFB,
-	0x41, 0xB3, 0x5F, 0x45, 0x23, 0x53, 0xE4, 0x9B,
-	0x75, 0xE1, 0x3D, 0x4C, 0x6C, 0x7E, 0xF5, 0x83,
-	0x68, 0x51, 0xD1, 0xF9, 0xE2, 0xAB, 0x62, 0x2A,
-	0x08, 0x95, 0x46, 0x9D, 0x30, 0x37, 0x0A, 0x2F,
-	0x0E, 0x24, 0x1B, 0xDF, 0xCD, 0x4E, 0x7F, 0xEA,
-	0x12, 0x1D, 0x58, 0x34, 0x36, 0xDC, 0xB4, 0x5B,
-	0xA4, 0x76, 0xB7, 0x7D, 0x52, 0xDD, 0x5E, 0x13,
-	0xA6, 0xB9, 0x00, 0xC1, 0x40, 0xE3, 0x79, 0xB6,
-	0xD4, 0x8D, 0x67, 0x72, 0x94, 0x98, 0xB0, 0x85,
-	0xBB, 0xC5, 0x4F, 0xED, 0x86, 0x9A, 0x66, 0x11,
-	0x8A, 0xE9, 0x04, 0xFE, 0xA0, 0x78, 0x25, 0x4B,
-	0xA2, 0x5D, 0x80, 0x05, 0x3F, 0x21, 0x70, 0xF1,
-	0x63, 0x77, 0xAF, 0x42, 0x20, 0xE5, 0xFD, 0xBF,
-	0x81, 0x18, 0x26, 0xC3, 0xBE, 0x35, 0x88, 0x2E,
-	0x93, 0x55, 0xFC, 0x7A, 0xC8, 0xBA, 0x32, 0xE6,
-	0xC0, 0x19, 0x9E, 0xA3, 0x44, 0x54, 0x3B, 0x0B,
-	0x8C, 0xC7, 0x6B, 0x28, 0xA7, 0xBC, 0x16, 0xAD,
-	0xDB, 0x64, 0x74, 0x14, 0x92, 0x0C, 0x48, 0xB8,
-	0x9F, 0xBD, 0x43, 0xC4, 0x39, 0x31, 0xD3, 0xF2,
-	0xD5, 0x8B, 0x6E, 0xDA, 0x01, 0xB1, 0x9C, 0x49,
-	0xD8, 0xAC, 0xF3, 0xCF, 0xCA, 0xF4, 0x47, 0x10,
-	0x6F, 0xF0, 0x4A, 0x5C, 0x38, 0x57, 0x73, 0x97,
-	0xCB, 0xA1, 0xE8, 0x3E, 0x96, 0x61, 0x0D, 0x0F,
-	0xE0, 0x7C, 0x71, 0xCC, 0x90, 0x06, 0xF7, 0x1C,
-	0xC2, 0x6A, 0xAE, 0x69, 0x17, 0x99, 0x3A, 0x27,
-	0xD9, 0xEB, 0x2B, 0x22, 0xD2, 0xA9, 0x07, 0x33,
-	0x2D, 0x3C, 0x15, 0xC9, 0x87, 0xAA, 0x50, 0xA5,
-	0x03, 0x59, 0x09, 0x1A, 0x65, 0xD7, 0x84, 0xD0,
-	0x82, 0x29, 0x5A, 0x1E, 0x7B, 0xA8, 0x6D, 0x2C
-};
-
-/* */
-/* Expanded IV for TKIP function. */
-/* */
-struct PACKED rt_tkip_iv {
-	union PACKED {
-		struct PACKED {
-			u8 rc0;
-			u8 rc1;
-			u8 rc2;
-
-			union PACKED {
-				struct PACKED {
-					u8 Rsvd:5;
-					u8 ExtIV:1;
-					u8 KeyID:2;
-				} field;
-				u8 Byte;
-			} CONTROL;
-		} field;
-
-		unsigned long word;
-	} IV16;
-
-	unsigned long IV32;
-};
-
-/*
-	========================================================================
-
-	Routine	Description:
-		Convert from u8[] to unsigned long in a portable way
-
-	Arguments:
-      pMICKey		pointer to MIC Key
-
-	Return Value:
-		None
-
-	Note:
-
-	========================================================================
-*/
-unsigned long RTMPTkipGetUInt32(u8 *pMICKey)
-{
-	unsigned long res = 0;
-	int i;
-
-	for (i = 0; i < 4; i++) {
-		res |= (*pMICKey++) << (8 * i);
-	}
-
-	return res;
-}
-
-/*
-	========================================================================
-
-	Routine	Description:
-		Convert from unsigned long to u8[] in a portable way
-
-	Arguments:
-      pDst			pointer to destination for convert unsigned long to u8[]
-      val			the value for convert
-
-	Return Value:
-		None
-
-	IRQL = DISPATCH_LEVEL
-
-	Note:
-
-	========================================================================
-*/
-void RTMPTkipPutUInt32(IN u8 *pDst, unsigned long val)
-{
-	int i;
-
-	for (i = 0; i < 4; i++) {
-		*pDst++ = (u8)(val & 0xff);
-		val >>= 8;
-	}
-}
-
-/*
-	========================================================================
-
-	Routine	Description:
-		Set the MIC Key.
-
-	Arguments:
-      pAd		Pointer to our adapter
-      pMICKey		pointer to MIC Key
-
-	Return Value:
-		None
-
-	IRQL = DISPATCH_LEVEL
-
-	Note:
-
-	========================================================================
-*/
-void RTMPTkipSetMICKey(struct rt_tkip_key_info *pTkip, u8 *pMICKey)
-{
-	/* Set the key */
-	pTkip->K0 = RTMPTkipGetUInt32(pMICKey);
-	pTkip->K1 = RTMPTkipGetUInt32(pMICKey + 4);
-	/* and reset the message */
-	pTkip->L = pTkip->K0;
-	pTkip->R = pTkip->K1;
-	pTkip->nBytesInM = 0;
-	pTkip->M = 0;
-}
-
-/*
-	========================================================================
-
-	Routine	Description:
-		Calculate the MIC Value.
-
-	Arguments:
-      pAd		Pointer to our adapter
-      uChar			Append this uChar
-
-	Return Value:
-		None
-
-	IRQL = DISPATCH_LEVEL
-
-	Note:
-
-	========================================================================
-*/
-void RTMPTkipAppendByte(struct rt_tkip_key_info *pTkip, u8 uChar)
-{
-	/* Append the byte to our word-sized buffer */
-	pTkip->M |= (uChar << (8 * pTkip->nBytesInM));
-	pTkip->nBytesInM++;
-	/* Process the word if it is full. */
-	if (pTkip->nBytesInM >= 4) {
-		pTkip->L ^= pTkip->M;
-		pTkip->R ^= ROL32(pTkip->L, 17);
-		pTkip->L += pTkip->R;
-		pTkip->R ^=
-		    ((pTkip->L & 0xff00ff00) >> 8) | ((pTkip->
-						       L & 0x00ff00ff) << 8);
-		pTkip->L += pTkip->R;
-		pTkip->R ^= ROL32(pTkip->L, 3);
-		pTkip->L += pTkip->R;
-		pTkip->R ^= ROR32(pTkip->L, 2);
-		pTkip->L += pTkip->R;
-		/* Clear the buffer */
-		pTkip->M = 0;
-		pTkip->nBytesInM = 0;
-	}
-}
-
-/*
-	========================================================================
-
-	Routine	Description:
-		Calculate the MIC Value.
-
-	Arguments:
-      pAd		Pointer to our adapter
-      pSrc			Pointer to source data for Calculate MIC Value
-      Len			Indicate the length of the source data
-
-	Return Value:
-		None
-
-	IRQL = DISPATCH_LEVEL
-
-	Note:
-
-	========================================================================
-*/
-void RTMPTkipAppend(struct rt_tkip_key_info *pTkip, u8 *pSrc, u32 nBytes)
-{
-	/* This is simple */
-	while (nBytes > 0) {
-		RTMPTkipAppendByte(pTkip, *pSrc++);
-		nBytes--;
-	}
-}
-
-/*
-	========================================================================
-
-	Routine	Description:
-		Get the MIC Value.
-
-	Arguments:
-      pAd		Pointer to our adapter
-
-	Return Value:
-		None
-
-	IRQL = DISPATCH_LEVEL
-
-	Note:
-		the MIC Value is store in pAd->PrivateInfo.MIC
-	========================================================================
-*/
-void RTMPTkipGetMIC(struct rt_tkip_key_info *pTkip)
-{
-	/* Append the minimum padding */
-	RTMPTkipAppendByte(pTkip, 0x5a);
-	RTMPTkipAppendByte(pTkip, 0);
-	RTMPTkipAppendByte(pTkip, 0);
-	RTMPTkipAppendByte(pTkip, 0);
-	RTMPTkipAppendByte(pTkip, 0);
-	/* and then zeroes until the length is a multiple of 4 */
-	while (pTkip->nBytesInM != 0) {
-		RTMPTkipAppendByte(pTkip, 0);
-	}
-	/* The appendByte function has already computed the result. */
-	RTMPTkipPutUInt32(pTkip->MIC, pTkip->L);
-	RTMPTkipPutUInt32(pTkip->MIC + 4, pTkip->R);
-}
-
-/*
-	========================================================================
-
-	Routine	Description:
-		Init Tkip function.
-
-	Arguments:
-      pAd		Pointer to our adapter
-		pTKey       Pointer to the Temporal Key (TK), TK shall be 128bits.
-		KeyId		TK Key ID
-		pTA			Pointer to transmitter address
-		pMICKey		pointer to MIC Key
-
-	Return Value:
-		None
-
-	IRQL = DISPATCH_LEVEL
-
-	Note:
-
-	========================================================================
-*/
-void RTMPInitTkipEngine(struct rt_rtmp_adapter *pAd,
-			u8 *pKey,
-			u8 KeyId,
-			u8 *pTA,
-			u8 *pMICKey,
-			u8 *pTSC, unsigned long *pIV16, unsigned long *pIV32)
-{
-	struct rt_tkip_iv tkipIv;
-
-	/* Prepare 8 bytes TKIP encapsulation for MPDU */
-	NdisZeroMemory(&tkipIv, sizeof(struct rt_tkip_iv));
-	tkipIv.IV16.field.rc0 = *(pTSC + 1);
-	tkipIv.IV16.field.rc1 = (tkipIv.IV16.field.rc0 | 0x20) & 0x7f;
-	tkipIv.IV16.field.rc2 = *pTSC;
-	tkipIv.IV16.field.CONTROL.field.ExtIV = 1;	/* 0: non-extended IV, 1: an extended IV */
-	tkipIv.IV16.field.CONTROL.field.KeyID = KeyId;
-/*      tkipIv.IV32 = *(unsigned long *)(pTSC + 2); */
-	NdisMoveMemory(&tkipIv.IV32, (pTSC + 2), 4);	/* Copy IV */
-
-	*pIV16 = tkipIv.IV16.word;
-	*pIV32 = tkipIv.IV32;
-}
-
-/*
-	========================================================================
-
-	Routine	Description:
-		Init MIC Value calculation function which include set MIC key &
-		calculate first 16 bytes (DA + SA + priority +  0)
-
-	Arguments:
-      pAd		Pointer to our adapter
-		pTKey       Pointer to the Temporal Key (TK), TK shall be 128bits.
-		pDA			Pointer to DA address
-		pSA			Pointer to SA address
-		pMICKey		pointer to MIC Key
-
-	Return Value:
-		None
-
-	Note:
-
-	========================================================================
-*/
-void RTMPInitMICEngine(struct rt_rtmp_adapter *pAd,
-		       u8 *pKey,
-		       u8 *pDA,
-		       u8 *pSA, u8 UserPriority, u8 *pMICKey)
-{
-	unsigned long Priority = UserPriority;
-
-	/* Init MIC value calculation */
-	RTMPTkipSetMICKey(&pAd->PrivateInfo.Tx, pMICKey);
-	/* DA */
-	RTMPTkipAppend(&pAd->PrivateInfo.Tx, pDA, MAC_ADDR_LEN);
-	/* SA */
-	RTMPTkipAppend(&pAd->PrivateInfo.Tx, pSA, MAC_ADDR_LEN);
-	/* Priority + 3 bytes of 0 */
-	RTMPTkipAppend(&pAd->PrivateInfo.Tx, (u8 *)& Priority, 4);
-}
-
-/*
-	========================================================================
-
-	Routine	Description:
-		Compare MIC value of received MSDU
-
-	Arguments:
-		pAd	Pointer to our adapter
-		pSrc        Pointer to the received Plain text data
-		pDA			Pointer to DA address
-		pSA			Pointer to SA address
-		pMICKey		pointer to MIC Key
-		Len         the length of the received plain text data exclude MIC value
-
-	Return Value:
-		TRUE        MIC value matched
-		FALSE       MIC value mismatched
-
-	IRQL = DISPATCH_LEVEL
-
-	Note:
-
-	========================================================================
-*/
-BOOLEAN RTMPTkipCompareMICValue(struct rt_rtmp_adapter *pAd,
-				u8 *pSrc,
-				u8 *pDA,
-				u8 *pSA,
-				u8 *pMICKey,
-				u8 UserPriority, u32 Len)
-{
-	u8 OldMic[8];
-	unsigned long Priority = UserPriority;
-
-	/* Init MIC value calculation */
-	RTMPTkipSetMICKey(&pAd->PrivateInfo.Rx, pMICKey);
-	/* DA */
-	RTMPTkipAppend(&pAd->PrivateInfo.Rx, pDA, MAC_ADDR_LEN);
-	/* SA */
-	RTMPTkipAppend(&pAd->PrivateInfo.Rx, pSA, MAC_ADDR_LEN);
-	/* Priority + 3 bytes of 0 */
-	RTMPTkipAppend(&pAd->PrivateInfo.Rx, (u8 *)& Priority, 4);
-
-	/* Calculate MIC value from plain text data */
-	RTMPTkipAppend(&pAd->PrivateInfo.Rx, pSrc, Len);
-
-	/* Get MIC valude from received frame */
-	NdisMoveMemory(OldMic, pSrc + Len, 8);
-
-	/* Get MIC value from decrypted plain data */
-	RTMPTkipGetMIC(&pAd->PrivateInfo.Rx);
-
-	/* Move MIC value from MSDU, this steps should move to data path. */
-	/* Since the MIC value might cross MPDUs. */
-	if (!NdisEqualMemory(pAd->PrivateInfo.Rx.MIC, OldMic, 8)) {
-		DBGPRINT_RAW(RT_DEBUG_ERROR, ("RTMPTkipCompareMICValue(): TKIP MIC Error !\n"));	/*MIC error. */
-
-		return (FALSE);
-	}
-	return (TRUE);
-}
-
-/*
-	========================================================================
-
-	Routine	Description:
-		Copy frame from waiting queue into relative ring buffer and set
-	appropriate ASIC register to kick hardware transmit function
-
-	Arguments:
-		pAd		Pointer	to our adapter
-		void *	Pointer to Ndis Packet for MIC calculation
-		pEncap			Pointer to LLC encap data
-		LenEncap		Total encap length, might be 0 which indicates no encap
-
-	Return Value:
-		None
-
-	IRQL = DISPATCH_LEVEL
-
-	Note:
-
-	========================================================================
-*/
-void RTMPCalculateMICValue(struct rt_rtmp_adapter *pAd,
-			   void *pPacket,
-			   u8 *pEncap,
-			   struct rt_cipher_key *pKey, u8 apidx)
-{
-	struct rt_packet_info PacketInfo;
-	u8 *pSrcBufVA;
-	u32 SrcBufLen;
-	u8 *pSrc;
-	u8 UserPriority;
-	u8 vlan_offset = 0;
-
-	RTMP_QueryPacketInfo(pPacket, &PacketInfo, &pSrcBufVA, &SrcBufLen);
-
-	UserPriority = RTMP_GET_PACKET_UP(pPacket);
-	pSrc = pSrcBufVA;
-
-	/* determine if this is a vlan packet */
-	if (((*(pSrc + 12) << 8) + *(pSrc + 13)) == 0x8100)
-		vlan_offset = 4;
-
-	{
-		RTMPInitMICEngine(pAd,
-				  pKey->Key,
-				  pSrc, pSrc + 6, UserPriority, pKey->TxMic);
-	}
-
-	if (pEncap != NULL) {
-		/* LLC encapsulation */
-		RTMPTkipAppend(&pAd->PrivateInfo.Tx, pEncap, 6);
-		/* Protocol Type */
-		RTMPTkipAppend(&pAd->PrivateInfo.Tx, pSrc + 12 + vlan_offset,
-			       2);
-	}
-	SrcBufLen -= (14 + vlan_offset);
-	pSrc += (14 + vlan_offset);
-	do {
-		if (SrcBufLen > 0) {
-			RTMPTkipAppend(&pAd->PrivateInfo.Tx, pSrc, SrcBufLen);
-		}
-
-		break;		/* No need handle next packet */
-
-	} while (TRUE);		/* End of copying payload */
-
-	/* Compute the final MIC Value */
-	RTMPTkipGetMIC(&pAd->PrivateInfo.Tx);
-}
-
-/************************************************************/
-/* tkip_sbox()																*/
-/* Returns a 16 bit value from a 64K entry table. The Table */
-/* is synthesized from two 256 entry byte wide tables.		*/
-/************************************************************/
-
-u32 tkip_sbox(u32 index)
-{
-	u32 index_low;
-	u32 index_high;
-	u32 left, right;
-
-	index_low = (index % 256);
-	index_high = ((index >> 8) % 256);
-
-	left = Tkip_Sbox_Lower[index_low] + (Tkip_Sbox_Upper[index_low] * 256);
-	right =
-	    Tkip_Sbox_Upper[index_high] + (Tkip_Sbox_Lower[index_high] * 256);
-
-	return (left ^ right);
-}
-
-u32 rotr1(u32 a)
-{
-	unsigned int b;
-
-	if ((a & 0x01) == 0x01) {
-		b = (a >> 1) | 0x8000;
-	} else {
-		b = (a >> 1) & 0x7fff;
-	}
-	b = b % 65536;
-	return b;
-}
-
-void RTMPTkipMixKey(u8 * key, u8 * ta, unsigned long pnl,	/* Least significant 16 bits of PN */
-		    unsigned long pnh,	/* Most significant 32 bits of PN */
-		    u8 * rc4key, u32 * p1k)
-{
-
-	u32 tsc0;
-	u32 tsc1;
-	u32 tsc2;
-
-	u32 ppk0;
-	u32 ppk1;
-	u32 ppk2;
-	u32 ppk3;
-	u32 ppk4;
-	u32 ppk5;
-
-	int i;
-	int j;
-
-	tsc0 = (unsigned int)((pnh >> 16) % 65536);	/* msb */
-	tsc1 = (unsigned int)(pnh % 65536);
-	tsc2 = (unsigned int)(pnl % 65536);	/* lsb */
-
-	/* Phase 1, step 1 */
-	p1k[0] = tsc1;
-	p1k[1] = tsc0;
-	p1k[2] = (u32)(ta[0] + (ta[1] * 256));
-	p1k[3] = (u32)(ta[2] + (ta[3] * 256));
-	p1k[4] = (u32)(ta[4] + (ta[5] * 256));
-
-	/* Phase 1, step 2 */
-	for (i = 0; i < 8; i++) {
-		j = 2 * (i & 1);
-		p1k[0] =
-		    (p1k[0] +
-		     tkip_sbox((p1k[4] ^ ((256 * key[1 + j]) + key[j])) %
-			       65536)) % 65536;
-		p1k[1] =
-		    (p1k[1] +
-		     tkip_sbox((p1k[0] ^ ((256 * key[5 + j]) + key[4 + j])) %
-			       65536)) % 65536;
-		p1k[2] =
-		    (p1k[2] +
-		     tkip_sbox((p1k[1] ^ ((256 * key[9 + j]) + key[8 + j])) %
-			       65536)) % 65536;
-		p1k[3] =
-		    (p1k[3] +
-		     tkip_sbox((p1k[2] ^ ((256 * key[13 + j]) + key[12 + j])) %
-			       65536)) % 65536;
-		p1k[4] =
-		    (p1k[4] +
-		     tkip_sbox((p1k[3] ^ (((256 * key[1 + j]) + key[j]))) %
-			       65536)) % 65536;
-		p1k[4] = (p1k[4] + i) % 65536;
-	}
-
-	/* Phase 2, Step 1 */
-	ppk0 = p1k[0];
-	ppk1 = p1k[1];
-	ppk2 = p1k[2];
-	ppk3 = p1k[3];
-	ppk4 = p1k[4];
-	ppk5 = (p1k[4] + tsc2) % 65536;
-
-	/* Phase2, Step 2 */
-	ppk0 = ppk0 + tkip_sbox((ppk5 ^ ((256 * key[1]) + key[0])) % 65536);
-	ppk1 = ppk1 + tkip_sbox((ppk0 ^ ((256 * key[3]) + key[2])) % 65536);
-	ppk2 = ppk2 + tkip_sbox((ppk1 ^ ((256 * key[5]) + key[4])) % 65536);
-	ppk3 = ppk3 + tkip_sbox((ppk2 ^ ((256 * key[7]) + key[6])) % 65536);
-	ppk4 = ppk4 + tkip_sbox((ppk3 ^ ((256 * key[9]) + key[8])) % 65536);
-	ppk5 = ppk5 + tkip_sbox((ppk4 ^ ((256 * key[11]) + key[10])) % 65536);
-
-	ppk0 = ppk0 + rotr1(ppk5 ^ ((256 * key[13]) + key[12]));
-	ppk1 = ppk1 + rotr1(ppk0 ^ ((256 * key[15]) + key[14]));
-	ppk2 = ppk2 + rotr1(ppk1);
-	ppk3 = ppk3 + rotr1(ppk2);
-	ppk4 = ppk4 + rotr1(ppk3);
-	ppk5 = ppk5 + rotr1(ppk4);
-
-	/* Phase 2, Step 3 */
-	/* Phase 2, Step 3 */
-
-	tsc0 = (unsigned int)((pnh >> 16) % 65536);	/* msb */
-	tsc1 = (unsigned int)(pnh % 65536);
-	tsc2 = (unsigned int)(pnl % 65536);	/* lsb */
-
-	rc4key[0] = (tsc2 >> 8) % 256;
-	rc4key[1] = (((tsc2 >> 8) % 256) | 0x20) & 0x7f;
-	rc4key[2] = tsc2 % 256;
-	rc4key[3] = ((ppk5 ^ ((256 * key[1]) + key[0])) >> 1) % 256;
-
-	rc4key[4] = ppk0 % 256;
-	rc4key[5] = (ppk0 >> 8) % 256;
-
-	rc4key[6] = ppk1 % 256;
-	rc4key[7] = (ppk1 >> 8) % 256;
-
-	rc4key[8] = ppk2 % 256;
-	rc4key[9] = (ppk2 >> 8) % 256;
-
-	rc4key[10] = ppk3 % 256;
-	rc4key[11] = (ppk3 >> 8) % 256;
-
-	rc4key[12] = ppk4 % 256;
-	rc4key[13] = (ppk4 >> 8) % 256;
-
-	rc4key[14] = ppk5 % 256;
-	rc4key[15] = (ppk5 >> 8) % 256;
-}
-
-/* */
-/* TRUE: Success! */
-/* FALSE: Decrypt Error! */
-/* */
-BOOLEAN RTMPSoftDecryptTKIP(struct rt_rtmp_adapter *pAd,
-			    u8 *pData,
-			    unsigned long DataByteCnt,
-			    u8 UserPriority, struct rt_cipher_key *pWpaKey)
-{
-	u8 KeyID;
-	u32 HeaderLen;
-	u8 fc0;
-	u8 fc1;
-	u16 fc;
-	u32 frame_type;
-	u32 frame_subtype;
-	u32 from_ds;
-	u32 to_ds;
-	int a4_exists;
-	int qc_exists;
-	u16 duration;
-	u16 seq_control;
-	u16 qos_control;
-	u8 TA[MAC_ADDR_LEN];
-	u8 DA[MAC_ADDR_LEN];
-	u8 SA[MAC_ADDR_LEN];
-	u8 RC4Key[16];
-	u32 p1k[5];		/*for mix_key; */
-	unsigned long pnl;		/* Least significant 16 bits of PN */
-	unsigned long pnh;		/* Most significant 32 bits of PN */
-	u32 num_blocks;
-	u32 payload_remainder;
-	struct rt_arcfourcontext ArcFourContext;
-	u32 crc32 = 0;
-	u32 trailfcs = 0;
-	u8 MIC[8];
-	u8 TrailMIC[8];
-
-	fc0 = *pData;
-	fc1 = *(pData + 1);
-
-	fc = *((u16 *)pData);
-
-	frame_type = ((fc0 >> 2) & 0x03);
-	frame_subtype = ((fc0 >> 4) & 0x0f);
-
-	from_ds = (fc1 & 0x2) >> 1;
-	to_ds = (fc1 & 0x1);
-
-	a4_exists = (from_ds & to_ds);
-	qc_exists = ((frame_subtype == 0x08) ||	/* Assumed QoS subtypes */
-		     (frame_subtype == 0x09) ||	/* Likely to change.    */
-		     (frame_subtype == 0x0a) || (frame_subtype == 0x0b)
-	    );
-
-	HeaderLen = 24;
-	if (a4_exists)
-		HeaderLen += 6;
-
-	KeyID = *((u8 *)(pData + HeaderLen + 3));
-	KeyID = KeyID >> 6;
-
-	if (pWpaKey[KeyID].KeyLen == 0) {
-		DBGPRINT(RT_DEBUG_TRACE,
-			 ("RTMPSoftDecryptTKIP failed!(KeyID[%d] Length can not be 0)\n",
-			  KeyID));
-		return FALSE;
-	}
-
-	duration = *((u16 *)(pData + 2));
-
-	seq_control = *((u16 *)(pData + 22));
-
-	if (qc_exists) {
-		if (a4_exists) {
-			qos_control = *((u16 *)(pData + 30));
-		} else {
-			qos_control = *((u16 *)(pData + 24));
-		}
-	}
-
-	if (to_ds == 0 && from_ds == 1) {
-		NdisMoveMemory(DA, pData + 4, MAC_ADDR_LEN);
-		NdisMoveMemory(SA, pData + 16, MAC_ADDR_LEN);
-		NdisMoveMemory(TA, pData + 10, MAC_ADDR_LEN);	/*BSSID */
-	} else if (to_ds == 0 && from_ds == 0) {
-		NdisMoveMemory(TA, pData + 10, MAC_ADDR_LEN);
-		NdisMoveMemory(DA, pData + 4, MAC_ADDR_LEN);
-		NdisMoveMemory(SA, pData + 10, MAC_ADDR_LEN);
-	} else if (to_ds == 1 && from_ds == 0) {
-		NdisMoveMemory(SA, pData + 10, MAC_ADDR_LEN);
-		NdisMoveMemory(TA, pData + 10, MAC_ADDR_LEN);
-		NdisMoveMemory(DA, pData + 16, MAC_ADDR_LEN);
-	} else if (to_ds == 1 && from_ds == 1) {
-		NdisMoveMemory(TA, pData + 10, MAC_ADDR_LEN);
-		NdisMoveMemory(DA, pData + 16, MAC_ADDR_LEN);
-		NdisMoveMemory(SA, pData + 22, MAC_ADDR_LEN);
-	}
-
-	num_blocks = (DataByteCnt - 16) / 16;
-	payload_remainder = (DataByteCnt - 16) % 16;
-
-	pnl = (*(pData + HeaderLen)) * 256 + *(pData + HeaderLen + 2);
-	pnh = *((unsigned long *)(pData + HeaderLen + 4));
-	pnh = cpu2le32(pnh);
-	RTMPTkipMixKey(pWpaKey[KeyID].Key, TA, pnl, pnh, RC4Key, p1k);
-
-	ARCFOUR_INIT(&ArcFourContext, RC4Key, 16);
-
-	ARCFOUR_DECRYPT(&ArcFourContext, pData + HeaderLen,
-			pData + HeaderLen + 8, DataByteCnt - HeaderLen - 8);
-	NdisMoveMemory(&trailfcs, pData + DataByteCnt - 8 - 4, 4);
-	crc32 = RTMP_CALC_FCS32(PPPINITFCS32, pData + HeaderLen, DataByteCnt - HeaderLen - 8 - 4);	/*Skip IV+EIV 8 bytes & Skip last 4 bytes(FCS). */
-	crc32 ^= 0xffffffff;	/* complement */
-
-	if (crc32 != cpu2le32(trailfcs)) {
-		DBGPRINT(RT_DEBUG_TRACE, ("RTMPSoftDecryptTKIP, WEP Data ICV Error !\n"));	/*ICV error. */
-
-		return (FALSE);
-	}
-
-	NdisMoveMemory(TrailMIC, pData + DataByteCnt - 8 - 8 - 4, 8);
-	RTMPInitMICEngine(pAd, pWpaKey[KeyID].Key, DA, SA, UserPriority,
-			  pWpaKey[KeyID].RxMic);
-	RTMPTkipAppend(&pAd->PrivateInfo.Tx, pData + HeaderLen,
-		       DataByteCnt - HeaderLen - 8 - 12);
-	RTMPTkipGetMIC(&pAd->PrivateInfo.Tx);
-	NdisMoveMemory(MIC, pAd->PrivateInfo.Tx.MIC, 8);
-
-	if (!NdisEqualMemory(MIC, TrailMIC, 8)) {
-		DBGPRINT(RT_DEBUG_ERROR, ("RTMPSoftDecryptTKIP, WEP Data MIC Error !\n"));	/*MIC error. */
-		/*RTMPReportMicError(pAd, &pWpaKey[KeyID]);     // marked by AlbertY @ 20060630 */
-		return (FALSE);
-	}
-	/*DBGPRINT(RT_DEBUG_TRACE, "RTMPSoftDecryptTKIP Decript done!\n"); */
-	return TRUE;
-}
diff -druN linux-2.6.39-libre/drivers/staging/rt2860/common/cmm_wep.c linux-3.0-rc7-libre/drivers/staging/rt2860/common/cmm_wep.c
--- linux-2.6.39-libre/drivers/staging/rt2860/common/cmm_wep.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rt2860/common/cmm_wep.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,473 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, 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.             *
- *                                                                       *
- *************************************************************************
-
-	Module Name:
-	rtmp_wep.c
-
-	Abstract:
-
-	Revision History:
-	Who			When			What
-	--------	----------		----------------------------------------------
-	Paul Wu		10-28-02		Initial
-*/
-
-#include	"../rt_config.h"
-
-u32 FCSTAB_32[256] = {
-	0x00000000, 0x77073096, 0xee0e612c, 0x990951ba,
-	0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3,
-	0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
-	0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91,
-	0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de,
-	0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
-	0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec,
-	0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5,
-	0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
-	0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
-	0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940,
-	0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
-	0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116,
-	0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f,
-	0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
-	0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d,
-	0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a,
-	0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
-	0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818,
-	0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
-	0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
-	0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457,
-	0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c,
-	0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
-	0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2,
-	0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb,
-	0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
-	0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9,
-	0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086,
-	0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
-	0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4,
-	0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad,
-	0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
-	0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683,
-	0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,
-	0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
-	0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe,
-	0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7,
-	0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
-	0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
-	0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252,
-	0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
-	0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60,
-	0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79,
-	0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
-	0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f,
-	0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04,
-	0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
-	0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a,
-	0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
-	0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
-	0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21,
-	0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e,
-	0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
-	0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c,
-	0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45,
-	0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
-	0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db,
-	0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0,
-	0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
-	0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6,
-	0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf,
-	0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
-	0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
-};
-
-/*
-u8   WEPKEY[] = {
-		//IV
-		0x00, 0x11, 0x22,
-		//WEP KEY
-		0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC
-	};
- */
-
-/*
-	========================================================================
-
-	Routine	Description:
-		Init WEP function.
-
-	Arguments:
-      pAd		Pointer to our adapter
-		pKey        Pointer to the WEP KEY
-		KeyId		   WEP Key ID
-		KeyLen      the length of WEP KEY
-		pDest       Pointer to the destination which Encryption data will store in.
-
-	Return Value:
-		None
-
-	IRQL = DISPATCH_LEVEL
-
-	Note:
-
-	========================================================================
-*/
-void RTMPInitWepEngine(struct rt_rtmp_adapter *pAd,
-		       u8 *pKey,
-		       u8 KeyId, u8 KeyLen, IN u8 *pDest)
-{
-	u32 i;
-	u8 WEPKEY[] = {
-		/*IV */
-		0x00, 0x11, 0x22,
-		/*WEP KEY */
-		0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99,
-		    0xAA, 0xBB, 0xCC
-	};
-
-	pAd->PrivateInfo.FCSCRC32 = PPPINITFCS32;	/*Init crc32. */
-
-	{
-		NdisMoveMemory(WEPKEY + 3, pKey, KeyLen);
-
-		for (i = 0; i < 3; i++)
-			WEPKEY[i] = RandomByte(pAd);	/*Call mlme RandomByte() function. */
-		ARCFOUR_INIT(&pAd->PrivateInfo.WEPCONTEXT, WEPKEY, KeyLen + 3);	/*INIT SBOX, KEYLEN+3(IV) */
-
-		NdisMoveMemory(pDest, WEPKEY, 3);	/*Append Init Vector */
-	}
-	*(pDest + 3) = (KeyId << 6);	/*Append KEYID */
-
-}
-
-/*
-	========================================================================
-
-	Routine	Description:
-		Encrypt transimitted data
-
-	Arguments:
-      pAd		Pointer to our adapter
-      pSrc        Pointer to the transimitted source data that will be encrypt
-      pDest       Pointer to the destination where entryption data will be store in.
-      Len			Indicate the length of the source data
-
-	Return Value:
-      None
-
-	IRQL = DISPATCH_LEVEL
-
-	Note:
-
-	========================================================================
-*/
-void RTMPEncryptData(struct rt_rtmp_adapter *pAd,
-		     u8 *pSrc, u8 *pDest, u32 Len)
-{
-	pAd->PrivateInfo.FCSCRC32 =
-	    RTMP_CALC_FCS32(pAd->PrivateInfo.FCSCRC32, pSrc, Len);
-	ARCFOUR_ENCRYPT(&pAd->PrivateInfo.WEPCONTEXT, pDest, pSrc, Len);
-}
-
-/*
-	========================================================================
-
-	Routine	Description:
-		Decrypt received WEP data
-
-	Arguments:
-		pAdapter		Pointer to our adapter
-		pSrc        Pointer to the received data
-		Len         the length of the received data
-
-	Return Value:
-		TRUE        Decrypt WEP data success
-		FALSE       Decrypt WEP data failed
-
-	Note:
-
-	========================================================================
-*/
-BOOLEAN RTMPSoftDecryptWEP(struct rt_rtmp_adapter *pAd,
-			   u8 *pData,
-			   unsigned long DataByteCnt, struct rt_cipher_key *pGroupKey)
-{
-	u32 trailfcs;
-	u32 crc32;
-	u8 KeyIdx;
-	u8 WEPKEY[] = {
-		/*IV */
-		0x00, 0x11, 0x22,
-		/*WEP KEY */
-		0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99,
-		    0xAA, 0xBB, 0xCC
-	};
-	u8 *pPayload = (u8 *) pData + LENGTH_802_11;
-	unsigned long payload_len = DataByteCnt - LENGTH_802_11;
-
-	NdisMoveMemory(WEPKEY, pPayload, 3);	/*Get WEP IV */
-
-	KeyIdx = (*(pPayload + 3) & 0xc0) >> 6;
-	if (pGroupKey[KeyIdx].KeyLen == 0)
-		return (FALSE);
-
-	NdisMoveMemory(WEPKEY + 3, pGroupKey[KeyIdx].Key,
-		       pGroupKey[KeyIdx].KeyLen);
-	ARCFOUR_INIT(&pAd->PrivateInfo.WEPCONTEXT, WEPKEY,
-		     pGroupKey[KeyIdx].KeyLen + 3);
-	ARCFOUR_DECRYPT(&pAd->PrivateInfo.WEPCONTEXT, pPayload, pPayload + 4,
-			payload_len - 4);
-	NdisMoveMemory(&trailfcs, pPayload + payload_len - 8, 4);
-	crc32 = RTMP_CALC_FCS32(PPPINITFCS32, pPayload, payload_len - 8);	/*Skip last 4 bytes(FCS). */
-	crc32 ^= 0xffffffff;	/* complement */
-
-	if (crc32 != cpu2le32(trailfcs)) {
-		DBGPRINT(RT_DEBUG_TRACE, ("WEP Data CRC Error!\n"));	/*CRC error. */
-		return (FALSE);
-	}
-	return (TRUE);
-}
-
-/*
-	========================================================================
-
-	Routine	Description:
-		The Stream Cipher Encryption Algorithm "struct rt_arcfour" initialize
-
-	Arguments:
-	   Ctx         Pointer to struct rt_arcfour CONTEXT (SBOX)
-		pKey        Pointer to the WEP KEY
-		KeyLen      Indicate the length fo the WEP KEY
-
-	Return Value:
-	   None
-
-	IRQL = DISPATCH_LEVEL
-
-	Note:
-
-	========================================================================
-*/
-void ARCFOUR_INIT(struct rt_arcfourcontext *Ctx, u8 *pKey, u32 KeyLen)
-{
-	u8 t, u;
-	u32 keyindex;
-	u32 stateindex;
-	u8 *state;
-	u32 counter;
-
-	state = Ctx->STATE;
-	Ctx->X = 0;
-	Ctx->Y = 0;
-	for (counter = 0; counter < 256; counter++)
-		state[counter] = (u8)counter;
-	keyindex = 0;
-	stateindex = 0;
-	for (counter = 0; counter < 256; counter++) {
-		t = state[counter];
-		stateindex = (stateindex + pKey[keyindex] + t) & 0xff;
-		u = state[stateindex];
-		state[stateindex] = t;
-		state[counter] = u;
-		if (++keyindex >= KeyLen)
-			keyindex = 0;
-	}
-}
-
-/*
-	========================================================================
-
-	Routine	Description:
-		Get bytes from struct rt_arcfour CONTEXT (S-BOX)
-
-	Arguments:
-	   Ctx         Pointer to struct rt_arcfour CONTEXT (SBOX)
-
-	Return Value:
-	   u8  - the value of the struct rt_arcfour CONTEXT (S-BOX)
-
-	Note:
-
-	========================================================================
-*/
-u8 ARCFOUR_BYTE(struct rt_arcfourcontext *Ctx)
-{
-	u32 x;
-	u32 y;
-	u8 sx, sy;
-	u8 *state;
-
-	state = Ctx->STATE;
-	x = (Ctx->X + 1) & 0xff;
-	sx = state[x];
-	y = (sx + Ctx->Y) & 0xff;
-	sy = state[y];
-	Ctx->X = x;
-	Ctx->Y = y;
-	state[y] = sx;
-	state[x] = sy;
-
-	return (state[(sx + sy) & 0xff]);
-
-}
-
-/*
-	========================================================================
-
-	Routine	Description:
-		The Stream Cipher Decryption Algorithm
-
-	Arguments:
-		Ctx         Pointer to struct rt_arcfour CONTEXT (SBOX)
-		pDest			Pointer to the Destination
-		pSrc        Pointer to the Source data
-		Len         Indicate the length of the Source data
-
-	Return Value:
-		None
-
-	Note:
-
-	========================================================================
-*/
-void ARCFOUR_DECRYPT(struct rt_arcfourcontext *Ctx,
-		     u8 *pDest, u8 *pSrc, u32 Len)
-{
-	u32 i;
-
-	for (i = 0; i < Len; i++)
-		pDest[i] = pSrc[i] ^ ARCFOUR_BYTE(Ctx);
-}
-
-/*
-	========================================================================
-
-	Routine	Description:
-		The Stream Cipher Encryption Algorithm
-
-	Arguments:
-		Ctx         Pointer to struct rt_arcfour CONTEXT (SBOX)
-		pDest			Pointer to the Destination
-		pSrc        Pointer to the Source data
-		Len         Indicate the length of the Source dta
-
-	Return Value:
-		None
-
-	IRQL = DISPATCH_LEVEL
-
-	Note:
-
-	========================================================================
-*/
-void ARCFOUR_ENCRYPT(struct rt_arcfourcontext *Ctx,
-		     u8 *pDest, u8 *pSrc, u32 Len)
-{
-	u32 i;
-
-	for (i = 0; i < Len; i++)
-		pDest[i] = pSrc[i] ^ ARCFOUR_BYTE(Ctx);
-}
-
-/*
-	========================================================================
-
-	Routine	Description:
-		The Stream Cipher Encryption Algorithm which conform to the special requirement to encrypt  GTK.
-
-	Arguments:
-		Ctx         Pointer to struct rt_arcfour CONTEXT (SBOX)
-		pDest			Pointer to the Destination
-		pSrc        Pointer to the Source data
-		Len         Indicate the length of the Source dta
-
-	========================================================================
-*/
-
-void WPAARCFOUR_ENCRYPT(struct rt_arcfourcontext *Ctx,
-			u8 *pDest, u8 *pSrc, u32 Len)
-{
-	u32 i;
-	/*discard first 256 bytes */
-	for (i = 0; i < 256; i++)
-		ARCFOUR_BYTE(Ctx);
-
-	for (i = 0; i < Len; i++)
-		pDest[i] = pSrc[i] ^ ARCFOUR_BYTE(Ctx);
-}
-
-/*
-	========================================================================
-
-	Routine	Description:
-		Calculate a new FCS given the current FCS and the new data.
-
-	Arguments:
-		Fcs	      the original FCS value
-		Cp          pointer to the data which will be calculate the FCS
-		Len         the length of the data
-
-	Return Value:
-		u32 - FCS 32 bits
-
-	IRQL = DISPATCH_LEVEL
-
-	Note:
-
-	========================================================================
-*/
-u32 RTMP_CALC_FCS32(u32 Fcs, u8 *Cp, int Len)
-{
-	while (Len--)
-		Fcs = (((Fcs) >> 8) ^ FCSTAB_32[((Fcs) ^ (*Cp++)) & 0xff]);
-
-	return (Fcs);
-}
-
-/*
-	========================================================================
-
-	Routine	Description:
-		Get last FCS and encrypt it to the destination
-
-	Arguments:
-		pDest			Pointer to the Destination
-
-	Return Value:
-		None
-
-	Note:
-
-	========================================================================
-*/
-void RTMPSetICV(struct rt_rtmp_adapter *pAd, u8 *pDest)
-{
-	pAd->PrivateInfo.FCSCRC32 ^= 0xffffffff;	/* complement */
-	pAd->PrivateInfo.FCSCRC32 = cpu2le32(pAd->PrivateInfo.FCSCRC32);
-
-	ARCFOUR_ENCRYPT(&pAd->PrivateInfo.WEPCONTEXT, pDest,
-			(u8 *)& pAd->PrivateInfo.FCSCRC32, 4);
-}
diff -druN linux-2.6.39-libre/drivers/staging/rt2860/common/cmm_wpa.c linux-3.0-rc7-libre/drivers/staging/rt2860/common/cmm_wpa.c
--- linux-2.6.39-libre/drivers/staging/rt2860/common/cmm_wpa.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rt2860/common/cmm_wpa.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,3010 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, 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.             *
- *                                                                       *
- *************************************************************************
-
-	Module Name:
-	wpa.c
-
-	Abstract:
-
-	Revision History:
-	Who			When			What
-	--------	----------		----------------------------------------------
-	Jan	Lee		03-07-22		Initial
-	Paul Lin	03-11-28		Modify for supplicant
-*/
-#include "../rt_config.h"
-/* WPA OUI */
-u8 OUI_WPA_NONE_AKM[4] = { 0x00, 0x50, 0xF2, 0x00 };
-u8 OUI_WPA_VERSION[4] = { 0x00, 0x50, 0xF2, 0x01 };
-u8 OUI_WPA_WEP40[4] = { 0x00, 0x50, 0xF2, 0x01 };
-u8 OUI_WPA_TKIP[4] = { 0x00, 0x50, 0xF2, 0x02 };
-u8 OUI_WPA_CCMP[4] = { 0x00, 0x50, 0xF2, 0x04 };
-u8 OUI_WPA_WEP104[4] = { 0x00, 0x50, 0xF2, 0x05 };
-u8 OUI_WPA_8021X_AKM[4] = { 0x00, 0x50, 0xF2, 0x01 };
-u8 OUI_WPA_PSK_AKM[4] = { 0x00, 0x50, 0xF2, 0x02 };
-
-/* WPA2 OUI */
-u8 OUI_WPA2_WEP40[4] = { 0x00, 0x0F, 0xAC, 0x01 };
-u8 OUI_WPA2_TKIP[4] = { 0x00, 0x0F, 0xAC, 0x02 };
-u8 OUI_WPA2_CCMP[4] = { 0x00, 0x0F, 0xAC, 0x04 };
-u8 OUI_WPA2_8021X_AKM[4] = { 0x00, 0x0F, 0xAC, 0x01 };
-u8 OUI_WPA2_PSK_AKM[4] = { 0x00, 0x0F, 0xAC, 0x02 };
-u8 OUI_WPA2_WEP104[4] = { 0x00, 0x0F, 0xAC, 0x05 };
-
-static void ConstructEapolKeyData(struct rt_mac_table_entry *pEntry,
-				  u8 GroupKeyWepStatus,
-				  u8 keyDescVer,
-				  u8 MsgType,
-				  u8 DefaultKeyIdx,
-				  u8 * GTK,
-				  u8 * RSNIE,
-				  u8 RSNIE_LEN, struct rt_eapol_packet * pMsg);
-
-static void CalculateMIC(u8 KeyDescVer,
-			 u8 * PTK, struct rt_eapol_packet * pMsg);
-
-static void WpaEAPPacketAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem);
-
-static void WpaEAPOLASFAlertAction(struct rt_rtmp_adapter *pAd,
-				   struct rt_mlme_queue_elem *Elem);
-
-static void WpaEAPOLLogoffAction(struct rt_rtmp_adapter *pAd,
-				 struct rt_mlme_queue_elem *Elem);
-
-static void WpaEAPOLStartAction(struct rt_rtmp_adapter *pAd,
-				struct rt_mlme_queue_elem *Elem);
-
-static void WpaEAPOLKeyAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem);
-
-/*
-    ==========================================================================
-    Description:
-        association state machine init, including state transition and timer init
-    Parameters:
-        S - pointer to the association state machine
-    ==========================================================================
- */
-void WpaStateMachineInit(struct rt_rtmp_adapter *pAd,
-			 struct rt_state_machine *S, OUT STATE_MACHINE_FUNC Trans[])
-{
-	StateMachineInit(S, (STATE_MACHINE_FUNC *) Trans, MAX_WPA_PTK_STATE,
-			 MAX_WPA_MSG, (STATE_MACHINE_FUNC) Drop, WPA_PTK,
-			 WPA_MACHINE_BASE);
-
-	StateMachineSetAction(S, WPA_PTK, MT2_EAPPacket,
-			      (STATE_MACHINE_FUNC) WpaEAPPacketAction);
-	StateMachineSetAction(S, WPA_PTK, MT2_EAPOLStart,
-			      (STATE_MACHINE_FUNC) WpaEAPOLStartAction);
-	StateMachineSetAction(S, WPA_PTK, MT2_EAPOLLogoff,
-			      (STATE_MACHINE_FUNC) WpaEAPOLLogoffAction);
-	StateMachineSetAction(S, WPA_PTK, MT2_EAPOLKey,
-			      (STATE_MACHINE_FUNC) WpaEAPOLKeyAction);
-	StateMachineSetAction(S, WPA_PTK, MT2_EAPOLASFAlert,
-			      (STATE_MACHINE_FUNC) WpaEAPOLASFAlertAction);
-}
-
-/*
-    ==========================================================================
-    Description:
-        this is state machine function.
-        When receiving EAP packets which is  for 802.1x authentication use.
-        Not use in PSK case
-    Return:
-    ==========================================================================
-*/
-void WpaEAPPacketAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
-{
-}
-
-void WpaEAPOLASFAlertAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
-{
-}
-
-void WpaEAPOLLogoffAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
-{
-}
-
-/*
-    ==========================================================================
-    Description:
-       Start 4-way HS when rcv EAPOL_START which may create by our driver in assoc.c
-    Return:
-    ==========================================================================
-*/
-void WpaEAPOLStartAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
-{
-	struct rt_mac_table_entry *pEntry;
-	struct rt_header_802_11 * pHeader;
-
-	DBGPRINT(RT_DEBUG_TRACE, ("WpaEAPOLStartAction ===> \n"));
-
-	pHeader = (struct rt_header_802_11 *) Elem->Msg;
-
-	/*For normaol PSK, we enqueue an EAPOL-Start command to trigger the process. */
-	if (Elem->MsgLen == 6)
-		pEntry = MacTableLookup(pAd, Elem->Msg);
-	else {
-		pEntry = MacTableLookup(pAd, pHeader->Addr2);
-	}
-
-	if (pEntry) {
-		DBGPRINT(RT_DEBUG_TRACE,
-			 (" PortSecured(%d), WpaState(%d), AuthMode(%d), PMKID_CacheIdx(%d) \n",
-			  pEntry->PortSecured, pEntry->WpaState,
-			  pEntry->AuthMode, pEntry->PMKID_CacheIdx));
-
-		if ((pEntry->PortSecured == WPA_802_1X_PORT_NOT_SECURED)
-		    && (pEntry->WpaState < AS_PTKSTART)
-		    && ((pEntry->AuthMode == Ndis802_11AuthModeWPAPSK)
-			|| (pEntry->AuthMode == Ndis802_11AuthModeWPA2PSK)
-			|| ((pEntry->AuthMode == Ndis802_11AuthModeWPA2)
-			    && (pEntry->PMKID_CacheIdx != ENTRY_NOT_FOUND)))) {
-			pEntry->PrivacyFilter = Ndis802_11PrivFilter8021xWEP;
-			pEntry->WpaState = AS_INITPSK;
-			pEntry->PortSecured = WPA_802_1X_PORT_NOT_SECURED;
-			NdisZeroMemory(pEntry->R_Counter,
-				       sizeof(pEntry->R_Counter));
-			pEntry->ReTryCounter = PEER_MSG1_RETRY_TIMER_CTR;
-
-			WPAStart4WayHS(pAd, pEntry, PEER_MSG1_RETRY_EXEC_INTV);
-		}
-	}
-}
-
-/*
-    ==========================================================================
-    Description:
-        This is state machine function.
-        When receiving EAPOL packets which is  for 802.1x key management.
-        Use both in WPA, and WPAPSK case.
-        In this function, further dispatch to different functions according to the received packet.  3 categories are :
-          1.  normal 4-way pairwisekey and 2-way groupkey handshake
-          2.  MIC error (Countermeasures attack)  report packet from STA.
-          3.  Request for pairwise/group key update from STA
-    Return:
-    ==========================================================================
-*/
-void WpaEAPOLKeyAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
-{
-	struct rt_mac_table_entry *pEntry;
-	struct rt_header_802_11 * pHeader;
-	struct rt_eapol_packet * pEapol_packet;
-	struct rt_key_info peerKeyInfo;
-
-	DBGPRINT(RT_DEBUG_TRACE, ("WpaEAPOLKeyAction ===>\n"));
-
-	pHeader = (struct rt_header_802_11 *) Elem->Msg;
-	pEapol_packet =
-	    (struct rt_eapol_packet *) & Elem->Msg[LENGTH_802_11 + LENGTH_802_1_H];
-
-	NdisZeroMemory((u8 *)& peerKeyInfo, sizeof(peerKeyInfo));
-	NdisMoveMemory((u8 *)& peerKeyInfo,
-		       (u8 *)& pEapol_packet->KeyDesc.KeyInfo,
-		       sizeof(struct rt_key_info));
-
-	hex_dump("Received Eapol frame", (unsigned char *)pEapol_packet,
-		 (Elem->MsgLen - LENGTH_802_11 - LENGTH_802_1_H));
-
-	*((u16 *) & peerKeyInfo) = cpu2le16(*((u16 *) & peerKeyInfo));
-
-	do {
-		pEntry = MacTableLookup(pAd, pHeader->Addr2);
-
-		if (!pEntry
-		    || ((!pEntry->ValidAsCLI) && (!pEntry->ValidAsApCli)))
-			break;
-
-		if (pEntry->AuthMode < Ndis802_11AuthModeWPA)
-			break;
-
-		DBGPRINT(RT_DEBUG_TRACE,
-			("Receive EAPoL-Key frame from STA %pMF\n",
-				pEntry->Addr));
-
-		if (((pEapol_packet->ProVer != EAPOL_VER)
-		     && (pEapol_packet->ProVer != EAPOL_VER2))
-		    || ((pEapol_packet->KeyDesc.Type != WPA1_KEY_DESC)
-			&& (pEapol_packet->KeyDesc.Type != WPA2_KEY_DESC))) {
-			DBGPRINT(RT_DEBUG_ERROR,
-				 ("Key descripter does not match with WPA rule\n"));
-			break;
-		}
-		/* The value 1 shall be used for all EAPOL-Key frames to and from a STA when */
-		/* neither the group nor pairwise ciphers are CCMP for Key Descriptor 1. */
-		if ((pEntry->WepStatus == Ndis802_11Encryption2Enabled)
-		    && (peerKeyInfo.KeyDescVer != DESC_TYPE_TKIP)) {
-			DBGPRINT(RT_DEBUG_ERROR,
-				 ("Key descripter version not match(TKIP) \n"));
-			break;
-		}
-		/* The value 2 shall be used for all EAPOL-Key frames to and from a STA when */
-		/* either the pairwise or the group cipher is AES-CCMP for Key Descriptor 2. */
-		else if ((pEntry->WepStatus == Ndis802_11Encryption3Enabled)
-			 && (peerKeyInfo.KeyDescVer != DESC_TYPE_AES)) {
-			DBGPRINT(RT_DEBUG_ERROR,
-				 ("Key descripter version not match(AES) \n"));
-			break;
-		}
-		/* Check if this STA is in class 3 state and the WPA state is started */
-		if ((pEntry->Sst == SST_ASSOC)
-		    && (pEntry->WpaState >= AS_INITPSK)) {
-			/* Check the Key Ack (bit 7) of the Key Information to determine the Authenticator */
-			/* or not. */
-			/* An EAPOL-Key frame that is sent by the Supplicant in response to an EAPOL- */
-			/* Key frame from the Authenticator must not have the Ack bit set. */
-			if (peerKeyInfo.KeyAck == 1) {
-				/* The frame is snet by Authenticator. */
-				/* So the Supplicant side shall handle this. */
-
-				if ((peerKeyInfo.Secure == 0)
-				    && (peerKeyInfo.Request == 0)
-				    && (peerKeyInfo.Error == 0)
-				    && (peerKeyInfo.KeyType == PAIRWISEKEY)) {
-					/* Process 1. the message 1 of 4-way HS in WPA or WPA2 */
-					/*                        EAPOL-Key(0,0,1,0,P,0,0,ANonce,0,DataKD_M1) */
-					/*                 2. the message 3 of 4-way HS in WPA */
-					/*                        EAPOL-Key(0,1,1,1,P,0,KeyRSC,ANonce,MIC,DataKD_M3) */
-					if (peerKeyInfo.KeyMic == 0)
-						PeerPairMsg1Action(pAd, pEntry,
-								   Elem);
-					else
-						PeerPairMsg3Action(pAd, pEntry,
-								   Elem);
-				} else if ((peerKeyInfo.Secure == 1)
-					   && (peerKeyInfo.KeyMic == 1)
-					   && (peerKeyInfo.Request == 0)
-					   && (peerKeyInfo.Error == 0)) {
-					/* Process 1. the message 3 of 4-way HS in WPA2 */
-					/*                        EAPOL-Key(1,1,1,1,P,0,KeyRSC,ANonce,MIC,DataKD_M3) */
-					/*                 2. the message 1 of group KS in WPA or WPA2 */
-					/*                        EAPOL-Key(1,1,1,0,G,0,Key RSC,0, MIC,GTK[N]) */
-					if (peerKeyInfo.KeyType == PAIRWISEKEY)
-						PeerPairMsg3Action(pAd, pEntry,
-								   Elem);
-					else
-						PeerGroupMsg1Action(pAd, pEntry,
-								    Elem);
-				}
-			} else {
-				/* The frame is snet by Supplicant. */
-				/* So the Authenticator side shall handle this. */
-				if ((peerKeyInfo.Request == 0) &&
-				    (peerKeyInfo.Error == 0) &&
-				    (peerKeyInfo.KeyMic == 1)) {
-					if (peerKeyInfo.Secure == 0
-					    && peerKeyInfo.KeyType ==
-					    PAIRWISEKEY) {
-						/* EAPOL-Key(0,1,0,0,P,0,0,SNonce,MIC,Data) */
-						/* Process 1. message 2 of 4-way HS in WPA or WPA2 */
-						/*                 2. message 4 of 4-way HS in WPA */
-						if (CONV_ARRARY_TO_u16
-						    (pEapol_packet->KeyDesc.
-						     KeyDataLen) == 0) {
-							PeerPairMsg4Action(pAd,
-									   pEntry,
-									   Elem);
-						} else {
-							PeerPairMsg2Action(pAd,
-									   pEntry,
-									   Elem);
-						}
-					} else if (peerKeyInfo.Secure == 1
-						   && peerKeyInfo.KeyType ==
-						   PAIRWISEKEY) {
-						/* EAPOL-Key(1,1,0,0,P,0,0,0,MIC,0) */
-						/* Process message 4 of 4-way HS in WPA2 */
-						PeerPairMsg4Action(pAd, pEntry,
-								   Elem);
-					} else if (peerKeyInfo.Secure == 1
-						   && peerKeyInfo.KeyType ==
-						   GROUPKEY) {
-						/* EAPOL-Key(1,1,0,0,G,0,0,0,MIC,0) */
-						/* Process message 2 of Group key HS in WPA or WPA2 */
-						PeerGroupMsg2Action(pAd, pEntry,
-								    &Elem->
-								    Msg
-								    [LENGTH_802_11],
-								    (Elem->
-								     MsgLen -
-								     LENGTH_802_11));
-					}
-				}
-			}
-		}
-	} while (FALSE);
-}
-
-/*
-	========================================================================
-
-	Routine	Description:
-		Copy frame from waiting queue into relative ring buffer and set
-	appropriate ASIC register to kick hardware encryption before really
-	sent out to air.
-
-	Arguments:
-		pAd		Pointer	to our adapter
-		void *	Pointer to outgoing Ndis frame
-		NumberOfFrag	Number of fragment required
-
-	Return Value:
-		None
-
-	Note:
-
-	========================================================================
-*/
-void RTMPToWirelessSta(struct rt_rtmp_adapter *pAd,
-		       struct rt_mac_table_entry *pEntry,
-		       u8 *pHeader802_3,
-		       u32 HdrLen,
-		       u8 *pData, u32 DataLen, IN BOOLEAN bClearFrame)
-{
-	void *pPacket;
-	int Status;
-
-	if ((!pEntry) || ((!pEntry->ValidAsCLI) && (!pEntry->ValidAsApCli)))
-		return;
-
-	do {
-		/* build a NDIS packet */
-		Status =
-		    RTMPAllocateNdisPacket(pAd, &pPacket, pHeader802_3, HdrLen,
-					   pData, DataLen);
-		if (Status != NDIS_STATUS_SUCCESS)
-			break;
-
-		if (bClearFrame)
-			RTMP_SET_PACKET_CLEAR_EAP_FRAME(pPacket, 1);
-		else
-			RTMP_SET_PACKET_CLEAR_EAP_FRAME(pPacket, 0);
-		{
-			RTMP_SET_PACKET_SOURCE(pPacket, PKTSRC_NDIS);
-
-			RTMP_SET_PACKET_NET_DEVICE_MBSSID(pPacket, MAIN_MBSSID);	/* set a default value */
-			if (pEntry->apidx != 0)
-				RTMP_SET_PACKET_NET_DEVICE_MBSSID(pPacket,
-								  pEntry->
-								  apidx);
-
-			RTMP_SET_PACKET_WCID(pPacket, (u8)pEntry->Aid);
-			RTMP_SET_PACKET_MOREDATA(pPacket, FALSE);
-		}
-
-		{
-			/* send out the packet */
-			Status = STASendPacket(pAd, pPacket);
-			if (Status == NDIS_STATUS_SUCCESS) {
-				u8 Index;
-
-				/* Dequeue one frame from TxSwQueue0..3 queue and process it */
-				/* There are three place calling dequeue for TX ring. */
-				/* 1. Here, right after queueing the frame. */
-				/* 2. At the end of TxRingTxDone service routine. */
-				/* 3. Upon NDIS call RTMPSendPackets */
-				if ((!RTMP_TEST_FLAG
-				     (pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
-				    &&
-				    (!RTMP_TEST_FLAG
-				     (pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS))) {
-					for (Index = 0; Index < 5; Index++)
-						if (pAd->TxSwQueue[Index].
-						    Number > 0)
-							RTMPDeQueuePacket(pAd,
-									  FALSE,
-									  Index,
-									  MAX_TX_PROCESS);
-				}
-			}
-		}
-
-	} while (FALSE);
-}
-
-/*
-    ==========================================================================
-    Description:
-        This is a function to initialize 4-way handshake
-
-    Return:
-
-    ==========================================================================
-*/
-void WPAStart4WayHS(struct rt_rtmp_adapter *pAd,
-		    struct rt_mac_table_entry *pEntry, unsigned long TimeInterval)
-{
-	u8 Header802_3[14];
-	struct rt_eapol_packet EAPOLPKT;
-	u8 *pBssid = NULL;
-	u8 group_cipher = Ndis802_11WEPDisabled;
-
-	DBGPRINT(RT_DEBUG_TRACE, ("===> WPAStart4WayHS\n"));
-
-	if (RTMP_TEST_FLAG
-	    (pAd,
-	     fRTMP_ADAPTER_RESET_IN_PROGRESS | fRTMP_ADAPTER_HALT_IN_PROGRESS))
-	{
-		DBGPRINT(RT_DEBUG_ERROR,
-			 ("[ERROR]WPAStart4WayHS : The interface is closed...\n"));
-		return;
-	}
-
-	if (pBssid == NULL) {
-		DBGPRINT(RT_DEBUG_ERROR,
-			 ("[ERROR]WPAStart4WayHS : No corresponding Authenticator.\n"));
-		return;
-	}
-	/* Check the status */
-	if ((pEntry->WpaState > AS_PTKSTART) || (pEntry->WpaState < AS_INITPMK)) {
-		DBGPRINT(RT_DEBUG_ERROR,
-			 ("[ERROR]WPAStart4WayHS : Not expect calling\n"));
-		return;
-	}
-
-	/* Increment replay counter by 1 */
-	ADD_ONE_To_64BIT_VAR(pEntry->R_Counter);
-
-	/* Randomly generate ANonce */
-	GenRandom(pAd, (u8 *) pBssid, pEntry->ANonce);
-
-	/* Construct EAPoL message - Pairwise Msg 1 */
-	/* EAPOL-Key(0,0,1,0,P,0,0,ANonce,0,DataKD_M1) */
-	NdisZeroMemory(&EAPOLPKT, sizeof(struct rt_eapol_packet));
-	ConstructEapolMsg(pEntry, group_cipher, EAPOL_PAIR_MSG_1, 0,	/* Default key index */
-			  pEntry->ANonce, NULL,	/* TxRSC */
-			  NULL,	/* GTK */
-			  NULL,	/* RSNIE */
-			  0,	/* RSNIE length */
-			  &EAPOLPKT);
-
-	/* Make outgoing frame */
-	MAKE_802_3_HEADER(Header802_3, pEntry->Addr, pBssid, EAPOL);
-	RTMPToWirelessSta(pAd, pEntry, Header802_3,
-			  LENGTH_802_3, (u8 *)& EAPOLPKT,
-			  CONV_ARRARY_TO_u16(EAPOLPKT.Body_Len) + 4,
-			  (pEntry->PortSecured ==
-			   WPA_802_1X_PORT_SECURED) ? FALSE : TRUE);
-
-	/* Trigger Retry Timer */
-	RTMPModTimer(&pEntry->RetryTimer, TimeInterval);
-
-	/* Update State */
-	pEntry->WpaState = AS_PTKSTART;
-
-	DBGPRINT(RT_DEBUG_TRACE,
-		 ("<=== WPAStart4WayHS: send Msg1 of 4-way \n"));
-
-}
-
-/*
-	========================================================================
-
-	Routine Description:
-		Process Pairwise key Msg-1 of 4-way handshaking and send Msg-2
-
-	Arguments:
-		pAd			Pointer	to our adapter
-		Elem		Message body
-
-	Return Value:
-		None
-
-	Note:
-
-	========================================================================
-*/
-void PeerPairMsg1Action(struct rt_rtmp_adapter *pAd,
-			struct rt_mac_table_entry *pEntry, struct rt_mlme_queue_elem *Elem)
-{
-	u8 PTK[80];
-	u8 Header802_3[14];
-	struct rt_eapol_packet * pMsg1;
-	u32 MsgLen;
-	struct rt_eapol_packet EAPOLPKT;
-	u8 *pCurrentAddr = NULL;
-	u8 *pmk_ptr = NULL;
-	u8 group_cipher = Ndis802_11WEPDisabled;
-	u8 *rsnie_ptr = NULL;
-	u8 rsnie_len = 0;
-
-	DBGPRINT(RT_DEBUG_TRACE, ("===> PeerPairMsg1Action \n"));
-
-	if ((!pEntry) || ((!pEntry->ValidAsCLI) && (!pEntry->ValidAsApCli)))
-		return;
-
-	if (Elem->MsgLen <
-	    (LENGTH_802_11 + LENGTH_802_1_H + LENGTH_EAPOL_H +
-	     sizeof(struct rt_key_descripter) - MAX_LEN_OF_RSNIE - 2))
-		return;
-
-	{
-		pCurrentAddr = pAd->CurrentAddress;
-		pmk_ptr = pAd->StaCfg.PMK;
-		group_cipher = pAd->StaCfg.GroupCipher;
-		rsnie_ptr = pAd->StaCfg.RSN_IE;
-		rsnie_len = pAd->StaCfg.RSNIE_Len;
-	}
-
-	/* Store the received frame */
-	pMsg1 = (struct rt_eapol_packet *) & Elem->Msg[LENGTH_802_11 + LENGTH_802_1_H];
-	MsgLen = Elem->MsgLen - LENGTH_802_11 - LENGTH_802_1_H;
-
-	/* Sanity Check peer Pairwise message 1 - Replay Counter */
-	if (PeerWpaMessageSanity(pAd, pMsg1, MsgLen, EAPOL_PAIR_MSG_1, pEntry)
-	    == FALSE)
-		return;
-
-	/* Store Replay counter, it will use to verify message 3 and construct message 2 */
-	NdisMoveMemory(pEntry->R_Counter, pMsg1->KeyDesc.ReplayCounter,
-		       LEN_KEY_DESC_REPLAY);
-
-	/* Store ANonce */
-	NdisMoveMemory(pEntry->ANonce, pMsg1->KeyDesc.KeyNonce,
-		       LEN_KEY_DESC_NONCE);
-
-	/* Generate random SNonce */
-	GenRandom(pAd, (u8 *) pCurrentAddr, pEntry->SNonce);
-
-	{
-		/* Calculate PTK(ANonce, SNonce) */
-		WpaDerivePTK(pAd,
-			     pmk_ptr,
-			     pEntry->ANonce,
-			     pEntry->Addr,
-			     pEntry->SNonce, pCurrentAddr, PTK, LEN_PTK);
-
-		/* Save key to PTK entry */
-		NdisMoveMemory(pEntry->PTK, PTK, LEN_PTK);
-	}
-
-	/* Update WpaState */
-	pEntry->WpaState = AS_PTKINIT_NEGOTIATING;
-
-	/* Construct EAPoL message - Pairwise Msg 2 */
-	/*  EAPOL-Key(0,1,0,0,P,0,0,SNonce,MIC,DataKD_M2) */
-	NdisZeroMemory(&EAPOLPKT, sizeof(struct rt_eapol_packet));
-	ConstructEapolMsg(pEntry, group_cipher, EAPOL_PAIR_MSG_2, 0,	/* DefaultKeyIdx */
-			  pEntry->SNonce, NULL,	/* TxRsc */
-			  NULL,	/* GTK */
-			  (u8 *) rsnie_ptr, rsnie_len, &EAPOLPKT);
-
-	/* Make outgoing frame */
-	MAKE_802_3_HEADER(Header802_3, pEntry->Addr, pCurrentAddr, EAPOL);
-
-	RTMPToWirelessSta(pAd, pEntry,
-			  Header802_3, sizeof(Header802_3), (u8 *)& EAPOLPKT,
-			  CONV_ARRARY_TO_u16(EAPOLPKT.Body_Len) + 4, TRUE);
-
-	DBGPRINT(RT_DEBUG_TRACE,
-		 ("<=== PeerPairMsg1Action: send Msg2 of 4-way \n"));
-}
-
-/*
-    ==========================================================================
-    Description:
-        When receiving the second packet of 4-way pairwisekey handshake.
-    Return:
-    ==========================================================================
-*/
-void PeerPairMsg2Action(struct rt_rtmp_adapter *pAd,
-			struct rt_mac_table_entry *pEntry, struct rt_mlme_queue_elem *Elem)
-{
-	u8 PTK[80];
-	BOOLEAN Cancelled;
-	struct rt_header_802_11 * pHeader;
-	struct rt_eapol_packet EAPOLPKT;
-	struct rt_eapol_packet * pMsg2;
-	u32 MsgLen;
-	u8 Header802_3[LENGTH_802_3];
-	u8 TxTsc[6];
-	u8 *pBssid = NULL;
-	u8 *pmk_ptr = NULL;
-	u8 *gtk_ptr = NULL;
-	u8 default_key = 0;
-	u8 group_cipher = Ndis802_11WEPDisabled;
-	u8 *rsnie_ptr = NULL;
-	u8 rsnie_len = 0;
-
-	DBGPRINT(RT_DEBUG_TRACE, ("===> PeerPairMsg2Action \n"));
-
-	if ((!pEntry) || (!pEntry->ValidAsCLI))
-		return;
-
-	if (Elem->MsgLen <
-	    (LENGTH_802_11 + LENGTH_802_1_H + LENGTH_EAPOL_H +
-	     sizeof(struct rt_key_descripter) - MAX_LEN_OF_RSNIE - 2))
-		return;
-
-	/* check Entry in valid State */
-	if (pEntry->WpaState < AS_PTKSTART)
-		return;
-
-	/* pointer to 802.11 header */
-	pHeader = (struct rt_header_802_11 *) Elem->Msg;
-
-	/* skip 802.11_header(24-byte) and LLC_header(8) */
-	pMsg2 = (struct rt_eapol_packet *) & Elem->Msg[LENGTH_802_11 + LENGTH_802_1_H];
-	MsgLen = Elem->MsgLen - LENGTH_802_11 - LENGTH_802_1_H;
-
-	/* Store SNonce */
-	NdisMoveMemory(pEntry->SNonce, pMsg2->KeyDesc.KeyNonce,
-		       LEN_KEY_DESC_NONCE);
-
-	{
-		/* Derive PTK */
-		WpaDerivePTK(pAd, (u8 *) pmk_ptr, pEntry->ANonce,	/* ANONCE */
-			     (u8 *) pBssid, pEntry->SNonce,	/* SNONCE */
-			     pEntry->Addr, PTK, LEN_PTK);
-
-		NdisMoveMemory(pEntry->PTK, PTK, LEN_PTK);
-	}
-
-	/* Sanity Check peer Pairwise message 2 - Replay Counter, MIC, RSNIE */
-	if (PeerWpaMessageSanity(pAd, pMsg2, MsgLen, EAPOL_PAIR_MSG_2, pEntry)
-	    == FALSE)
-		return;
-
-	do {
-		/* delete retry timer */
-		RTMPCancelTimer(&pEntry->RetryTimer, &Cancelled);
-
-		/* Change state */
-		pEntry->WpaState = AS_PTKINIT_NEGOTIATING;
-
-		/* Increment replay counter by 1 */
-		ADD_ONE_To_64BIT_VAR(pEntry->R_Counter);
-
-		/* Construct EAPoL message - Pairwise Msg 3 */
-		NdisZeroMemory(&EAPOLPKT, sizeof(struct rt_eapol_packet));
-		ConstructEapolMsg(pEntry,
-				  group_cipher,
-				  EAPOL_PAIR_MSG_3,
-				  default_key,
-				  pEntry->ANonce,
-				  TxTsc,
-				  (u8 *) gtk_ptr,
-				  (u8 *) rsnie_ptr, rsnie_len, &EAPOLPKT);
-
-		/* Make outgoing frame */
-		MAKE_802_3_HEADER(Header802_3, pEntry->Addr, pBssid, EAPOL);
-		RTMPToWirelessSta(pAd, pEntry, Header802_3, LENGTH_802_3,
-				  (u8 *)& EAPOLPKT,
-				  CONV_ARRARY_TO_u16(EAPOLPKT.Body_Len) + 4,
-				  (pEntry->PortSecured ==
-				   WPA_802_1X_PORT_SECURED) ? FALSE : TRUE);
-
-		pEntry->ReTryCounter = PEER_MSG3_RETRY_TIMER_CTR;
-		RTMPSetTimer(&pEntry->RetryTimer, PEER_MSG3_RETRY_EXEC_INTV);
-
-		/* Update State */
-		pEntry->WpaState = AS_PTKINIT_NEGOTIATING;
-	} while (FALSE);
-
-	DBGPRINT(RT_DEBUG_TRACE,
-		 ("<=== PeerPairMsg2Action: send Msg3 of 4-way \n"));
-}
-
-/*
-	========================================================================
-
-	Routine Description:
-		Process Pairwise key Msg 3 of 4-way handshaking and send Msg 4
-
-	Arguments:
-		pAd	Pointer	to our adapter
-		Elem		Message body
-
-	Return Value:
-		None
-
-	Note:
-
-	========================================================================
-*/
-void PeerPairMsg3Action(struct rt_rtmp_adapter *pAd,
-			struct rt_mac_table_entry *pEntry, struct rt_mlme_queue_elem *Elem)
-{
-	struct rt_header_802_11 * pHeader;
-	u8 Header802_3[14];
-	struct rt_eapol_packet EAPOLPKT;
-	struct rt_eapol_packet * pMsg3;
-	u32 MsgLen;
-	u8 *pCurrentAddr = NULL;
-	u8 group_cipher = Ndis802_11WEPDisabled;
-
-	DBGPRINT(RT_DEBUG_TRACE, ("===> PeerPairMsg3Action \n"));
-
-	if ((!pEntry) || ((!pEntry->ValidAsCLI) && (!pEntry->ValidAsApCli)))
-		return;
-
-	if (Elem->MsgLen <
-	    (LENGTH_802_11 + LENGTH_802_1_H + LENGTH_EAPOL_H +
-	     sizeof(struct rt_key_descripter) - MAX_LEN_OF_RSNIE - 2))
-		return;
-
-	{
-		pCurrentAddr = pAd->CurrentAddress;
-		group_cipher = pAd->StaCfg.GroupCipher;
-
-	}
-
-	/* Record 802.11 header & the received EAPOL packet Msg3 */
-	pHeader = (struct rt_header_802_11 *) Elem->Msg;
-	pMsg3 = (struct rt_eapol_packet *) & Elem->Msg[LENGTH_802_11 + LENGTH_802_1_H];
-	MsgLen = Elem->MsgLen - LENGTH_802_11 - LENGTH_802_1_H;
-
-	/* Sanity Check peer Pairwise message 3 - Replay Counter, MIC, RSNIE */
-	if (PeerWpaMessageSanity(pAd, pMsg3, MsgLen, EAPOL_PAIR_MSG_3, pEntry)
-	    == FALSE)
-		return;
-
-	/* Save Replay counter, it will use construct message 4 */
-	NdisMoveMemory(pEntry->R_Counter, pMsg3->KeyDesc.ReplayCounter,
-		       LEN_KEY_DESC_REPLAY);
-
-	/* Double check ANonce */
-	if (!NdisEqualMemory
-	    (pEntry->ANonce, pMsg3->KeyDesc.KeyNonce, LEN_KEY_DESC_NONCE)) {
-		return;
-	}
-	/* Construct EAPoL message - Pairwise Msg 4 */
-	NdisZeroMemory(&EAPOLPKT, sizeof(struct rt_eapol_packet));
-	ConstructEapolMsg(pEntry, group_cipher, EAPOL_PAIR_MSG_4, 0,	/* group key index not used in message 4 */
-			  NULL,	/* Nonce not used in message 4 */
-			  NULL,	/* TxRSC not used in message 4 */
-			  NULL,	/* GTK not used in message 4 */
-			  NULL,	/* RSN IE not used in message 4 */
-			  0, &EAPOLPKT);
-
-	/* Update WpaState */
-	pEntry->WpaState = AS_PTKINITDONE;
-
-	/* Update pairwise key */
-	{
-		struct rt_cipher_key *pSharedKey;
-
-		pSharedKey = &pAd->SharedKey[BSS0][0];
-
-		NdisMoveMemory(pAd->StaCfg.PTK, pEntry->PTK, LEN_PTK);
-
-		/* Prepare pair-wise key information into shared key table */
-		NdisZeroMemory(pSharedKey, sizeof(struct rt_cipher_key));
-		pSharedKey->KeyLen = LEN_TKIP_EK;
-		NdisMoveMemory(pSharedKey->Key, &pAd->StaCfg.PTK[32],
-			       LEN_TKIP_EK);
-		NdisMoveMemory(pSharedKey->RxMic, &pAd->StaCfg.PTK[48],
-			       LEN_TKIP_RXMICK);
-		NdisMoveMemory(pSharedKey->TxMic,
-			       &pAd->StaCfg.PTK[48 + LEN_TKIP_RXMICK],
-			       LEN_TKIP_TXMICK);
-
-		/* Decide its ChiperAlg */
-		if (pAd->StaCfg.PairCipher == Ndis802_11Encryption2Enabled)
-			pSharedKey->CipherAlg = CIPHER_TKIP;
-		else if (pAd->StaCfg.PairCipher == Ndis802_11Encryption3Enabled)
-			pSharedKey->CipherAlg = CIPHER_AES;
-		else
-			pSharedKey->CipherAlg = CIPHER_NONE;
-
-		/* Update these related information to struct rt_mac_table_entry */
-		pEntry = &pAd->MacTab.Content[BSSID_WCID];
-		NdisMoveMemory(pEntry->PairwiseKey.Key, &pAd->StaCfg.PTK[32],
-			       LEN_TKIP_EK);
-		NdisMoveMemory(pEntry->PairwiseKey.RxMic, &pAd->StaCfg.PTK[48],
-			       LEN_TKIP_RXMICK);
-		NdisMoveMemory(pEntry->PairwiseKey.TxMic,
-			       &pAd->StaCfg.PTK[48 + LEN_TKIP_RXMICK],
-			       LEN_TKIP_TXMICK);
-		pEntry->PairwiseKey.CipherAlg = pSharedKey->CipherAlg;
-
-		/* Update pairwise key information to ASIC Shared Key Table */
-		AsicAddSharedKeyEntry(pAd,
-				      BSS0,
-				      0,
-				      pSharedKey->CipherAlg,
-				      pSharedKey->Key,
-				      pSharedKey->TxMic, pSharedKey->RxMic);
-
-		/* Update ASIC WCID attribute table and IVEIV table */
-		RTMPAddWcidAttributeEntry(pAd,
-					  BSS0,
-					  0, pSharedKey->CipherAlg, pEntry);
-
-	}
-
-	/* open 802.1x port control and privacy filter */
-	if (pEntry->AuthMode == Ndis802_11AuthModeWPA2PSK ||
-	    pEntry->AuthMode == Ndis802_11AuthModeWPA2) {
-		pEntry->PortSecured = WPA_802_1X_PORT_SECURED;
-		pEntry->PrivacyFilter = Ndis802_11PrivFilterAcceptAll;
-
-		STA_PORT_SECURED(pAd);
-		/* Indicate Connected for GUI */
-		pAd->IndicateMediaState = NdisMediaStateConnected;
-		DBGPRINT(RT_DEBUG_TRACE,
-			 ("PeerPairMsg3Action: AuthMode(%s) PairwiseCipher(%s) GroupCipher(%s) \n",
-			  GetAuthMode(pEntry->AuthMode),
-			  GetEncryptType(pEntry->WepStatus),
-			  GetEncryptType(group_cipher)));
-	} else {
-	}
-
-	/* Init 802.3 header and send out */
-	MAKE_802_3_HEADER(Header802_3, pEntry->Addr, pCurrentAddr, EAPOL);
-	RTMPToWirelessSta(pAd, pEntry,
-			  Header802_3, sizeof(Header802_3),
-			  (u8 *)& EAPOLPKT,
-			  CONV_ARRARY_TO_u16(EAPOLPKT.Body_Len) + 4, TRUE);
-
-	DBGPRINT(RT_DEBUG_TRACE,
-		 ("<=== PeerPairMsg3Action: send Msg4 of 4-way \n"));
-}
-
-/*
-    ==========================================================================
-    Description:
-        When receiving the last packet of 4-way pairwisekey handshake.
-        Initialize 2-way groupkey handshake following.
-    Return:
-    ==========================================================================
-*/
-void PeerPairMsg4Action(struct rt_rtmp_adapter *pAd,
-			struct rt_mac_table_entry *pEntry, struct rt_mlme_queue_elem *Elem)
-{
-	struct rt_eapol_packet * pMsg4;
-	struct rt_header_802_11 * pHeader;
-	u32 MsgLen;
-	BOOLEAN Cancelled;
-	u8 group_cipher = Ndis802_11WEPDisabled;
-
-	DBGPRINT(RT_DEBUG_TRACE, ("===> PeerPairMsg4Action\n"));
-
-	do {
-		if ((!pEntry) || (!pEntry->ValidAsCLI))
-			break;
-
-		if (Elem->MsgLen <
-		    (LENGTH_802_11 + LENGTH_802_1_H + LENGTH_EAPOL_H +
-		     sizeof(struct rt_key_descripter) - MAX_LEN_OF_RSNIE - 2))
-			break;
-
-		if (pEntry->WpaState < AS_PTKINIT_NEGOTIATING)
-			break;
-
-		/* pointer to 802.11 header */
-		pHeader = (struct rt_header_802_11 *) Elem->Msg;
-
-		/* skip 802.11_header(24-byte) and LLC_header(8) */
-		pMsg4 =
-		    (struct rt_eapol_packet *) & Elem->Msg[LENGTH_802_11 + LENGTH_802_1_H];
-		MsgLen = Elem->MsgLen - LENGTH_802_11 - LENGTH_802_1_H;
-
-		/* Sanity Check peer Pairwise message 4 - Replay Counter, MIC */
-		if (PeerWpaMessageSanity
-		    (pAd, pMsg4, MsgLen, EAPOL_PAIR_MSG_4, pEntry) == FALSE)
-			break;
-
-		/* 3. uses the MLME.SETKEYS.request to configure PTK into MAC */
-		NdisZeroMemory(&pEntry->PairwiseKey, sizeof(struct rt_cipher_key));
-
-		/* reset IVEIV in Asic */
-		AsicUpdateWCIDIVEIV(pAd, pEntry->Aid, 1, 0);
-
-		pEntry->PairwiseKey.KeyLen = LEN_TKIP_EK;
-		NdisMoveMemory(pEntry->PairwiseKey.Key, &pEntry->PTK[32],
-			       LEN_TKIP_EK);
-		NdisMoveMemory(pEntry->PairwiseKey.RxMic,
-			       &pEntry->PTK[TKIP_AP_RXMICK_OFFSET],
-			       LEN_TKIP_RXMICK);
-		NdisMoveMemory(pEntry->PairwiseKey.TxMic,
-			       &pEntry->PTK[TKIP_AP_TXMICK_OFFSET],
-			       LEN_TKIP_TXMICK);
-
-		/* Set pairwise key to Asic */
-		{
-			pEntry->PairwiseKey.CipherAlg = CIPHER_NONE;
-			if (pEntry->WepStatus == Ndis802_11Encryption2Enabled)
-				pEntry->PairwiseKey.CipherAlg = CIPHER_TKIP;
-			else if (pEntry->WepStatus ==
-				 Ndis802_11Encryption3Enabled)
-				pEntry->PairwiseKey.CipherAlg = CIPHER_AES;
-
-			/* Add Pair-wise key to Asic */
-			AsicAddPairwiseKeyEntry(pAd,
-						pEntry->Addr,
-						(u8)pEntry->Aid,
-						&pEntry->PairwiseKey);
-
-			/* update WCID attribute table and IVEIV table for this entry */
-			RTMPAddWcidAttributeEntry(pAd,
-						  pEntry->apidx,
-						  0,
-						  pEntry->PairwiseKey.CipherAlg,
-						  pEntry);
-		}
-
-		/* 4. upgrade state */
-		pEntry->PrivacyFilter = Ndis802_11PrivFilterAcceptAll;
-		pEntry->WpaState = AS_PTKINITDONE;
-		pEntry->PortSecured = WPA_802_1X_PORT_SECURED;
-
-		if (pEntry->AuthMode == Ndis802_11AuthModeWPA2 ||
-		    pEntry->AuthMode == Ndis802_11AuthModeWPA2PSK) {
-			pEntry->GTKState = REKEY_ESTABLISHED;
-			RTMPCancelTimer(&pEntry->RetryTimer, &Cancelled);
-
-			/* send wireless event - for set key done WPA2 */
-			if (pAd->CommonCfg.bWirelessEvent)
-				RTMPSendWirelessEvent(pAd,
-						      IW_SET_KEY_DONE_WPA2_EVENT_FLAG,
-						      pEntry->Addr,
-						      pEntry->apidx, 0);
-
-			DBGPRINT(RT_DEBUG_OFF,
-				 ("AP SETKEYS DONE - WPA2, AuthMode(%d)=%s, WepStatus(%d)=%s, GroupWepStatus(%d)=%s\n\n",
-				  pEntry->AuthMode,
-				  GetAuthMode(pEntry->AuthMode),
-				  pEntry->WepStatus,
-				  GetEncryptType(pEntry->WepStatus),
-				  group_cipher, GetEncryptType(group_cipher)));
-		} else {
-			/* 5. init Group 2-way handshake if necessary. */
-			WPAStart2WayGroupHS(pAd, pEntry);
-
-			pEntry->ReTryCounter = GROUP_MSG1_RETRY_TIMER_CTR;
-			RTMPModTimer(&pEntry->RetryTimer,
-				     PEER_MSG3_RETRY_EXEC_INTV);
-		}
-	} while (FALSE);
-
-}
-
-/*
-    ==========================================================================
-    Description:
-        This is a function to send the first packet of 2-way groupkey handshake
-    Return:
-
-    ==========================================================================
-*/
-void WPAStart2WayGroupHS(struct rt_rtmp_adapter *pAd, struct rt_mac_table_entry *pEntry)
-{
-	u8 Header802_3[14];
-	u8 TxTsc[6];
-	struct rt_eapol_packet EAPOLPKT;
-	u8 group_cipher = Ndis802_11WEPDisabled;
-	u8 default_key = 0;
-	u8 *gnonce_ptr = NULL;
-	u8 *gtk_ptr = NULL;
-	u8 *pBssid = NULL;
-
-	DBGPRINT(RT_DEBUG_TRACE, ("===> WPAStart2WayGroupHS\n"));
-
-	if ((!pEntry) || (!pEntry->ValidAsCLI))
-		return;
-
-	do {
-		/* Increment replay counter by 1 */
-		ADD_ONE_To_64BIT_VAR(pEntry->R_Counter);
-
-		/* Construct EAPoL message - Group Msg 1 */
-		NdisZeroMemory(&EAPOLPKT, sizeof(struct rt_eapol_packet));
-		ConstructEapolMsg(pEntry,
-				  group_cipher,
-				  EAPOL_GROUP_MSG_1,
-				  default_key,
-				  (u8 *) gnonce_ptr,
-				  TxTsc, (u8 *) gtk_ptr, NULL, 0, &EAPOLPKT);
-
-		/* Make outgoing frame */
-		MAKE_802_3_HEADER(Header802_3, pEntry->Addr, pBssid, EAPOL);
-		RTMPToWirelessSta(pAd, pEntry,
-				  Header802_3, LENGTH_802_3,
-				  (u8 *)& EAPOLPKT,
-				  CONV_ARRARY_TO_u16(EAPOLPKT.Body_Len) + 4,
-				  FALSE);
-
-	} while (FALSE);
-
-	DBGPRINT(RT_DEBUG_TRACE,
-		 ("<=== WPAStart2WayGroupHS : send out Group Message 1 \n"));
-
-	return;
-}
-
-/*
-	========================================================================
-
-	Routine Description:
-		Process Group key 2-way handshaking
-
-	Arguments:
-		pAd	Pointer	to our adapter
-		Elem		Message body
-
-	Return Value:
-		None
-
-	Note:
-
-	========================================================================
-*/
-void PeerGroupMsg1Action(struct rt_rtmp_adapter *pAd,
-			 struct rt_mac_table_entry *pEntry, struct rt_mlme_queue_elem *Elem)
-{
-	u8 Header802_3[14];
-	struct rt_eapol_packet EAPOLPKT;
-	struct rt_eapol_packet * pGroup;
-	u32 MsgLen;
-	BOOLEAN Cancelled;
-	u8 default_key = 0;
-	u8 group_cipher = Ndis802_11WEPDisabled;
-	u8 *pCurrentAddr = NULL;
-
-	DBGPRINT(RT_DEBUG_TRACE, ("===> PeerGroupMsg1Action \n"));
-
-	if ((!pEntry) || ((!pEntry->ValidAsCLI) && (!pEntry->ValidAsApCli)))
-		return;
-
-	{
-		pCurrentAddr = pAd->CurrentAddress;
-		group_cipher = pAd->StaCfg.GroupCipher;
-		default_key = pAd->StaCfg.DefaultKeyId;
-	}
-
-	/* Process Group Message 1 frame. skip 802.11 header(24) & LLC_SNAP header(8) */
-	pGroup = (struct rt_eapol_packet *) & Elem->Msg[LENGTH_802_11 + LENGTH_802_1_H];
-	MsgLen = Elem->MsgLen - LENGTH_802_11 - LENGTH_802_1_H;
-
-	/* Sanity Check peer group message 1 - Replay Counter, MIC, RSNIE */
-	if (PeerWpaMessageSanity(pAd, pGroup, MsgLen, EAPOL_GROUP_MSG_1, pEntry)
-	    == FALSE)
-		return;
-
-	/* delete retry timer */
-	RTMPCancelTimer(&pEntry->RetryTimer, &Cancelled);
-
-	/* Save Replay counter, it will use to construct message 2 */
-	NdisMoveMemory(pEntry->R_Counter, pGroup->KeyDesc.ReplayCounter,
-		       LEN_KEY_DESC_REPLAY);
-
-	/* Construct EAPoL message - Group Msg 2 */
-	NdisZeroMemory(&EAPOLPKT, sizeof(struct rt_eapol_packet));
-	ConstructEapolMsg(pEntry, group_cipher, EAPOL_GROUP_MSG_2, default_key, NULL,	/* Nonce not used */
-			  NULL,	/* TxRSC not used */
-			  NULL,	/* GTK not used */
-			  NULL,	/* RSN IE not used */
-			  0, &EAPOLPKT);
-
-	/* open 802.1x port control and privacy filter */
-	pEntry->PortSecured = WPA_802_1X_PORT_SECURED;
-	pEntry->PrivacyFilter = Ndis802_11PrivFilterAcceptAll;
-
-	STA_PORT_SECURED(pAd);
-	/* Indicate Connected for GUI */
-	pAd->IndicateMediaState = NdisMediaStateConnected;
-
-	DBGPRINT(RT_DEBUG_TRACE,
-		 ("PeerGroupMsg1Action: AuthMode(%s) PairwiseCipher(%s) GroupCipher(%s) \n",
-		  GetAuthMode(pEntry->AuthMode),
-		  GetEncryptType(pEntry->WepStatus),
-		  GetEncryptType(group_cipher)));
-
-	/* init header and Fill Packet and send Msg 2 to authenticator */
-	MAKE_802_3_HEADER(Header802_3, pEntry->Addr, pCurrentAddr, EAPOL);
-	RTMPToWirelessSta(pAd, pEntry,
-			  Header802_3, sizeof(Header802_3),
-			  (u8 *)& EAPOLPKT,
-			  CONV_ARRARY_TO_u16(EAPOLPKT.Body_Len) + 4, FALSE);
-
-	DBGPRINT(RT_DEBUG_TRACE,
-		 ("<=== PeerGroupMsg1Action: sned group message 2\n"));
-}
-
-/*
-    ==========================================================================
-    Description:
-        When receiving the last packet of 2-way groupkey handshake.
-    Return:
-    ==========================================================================
-*/
-void PeerGroupMsg2Action(struct rt_rtmp_adapter *pAd,
-			 struct rt_mac_table_entry *pEntry,
-			 void * Msg, u32 MsgLen)
-{
-	u32 Len;
-	u8 *pData;
-	BOOLEAN Cancelled;
-	struct rt_eapol_packet * pMsg2;
-	u8 group_cipher = Ndis802_11WEPDisabled;
-
-	DBGPRINT(RT_DEBUG_TRACE, ("===> PeerGroupMsg2Action \n"));
-
-	do {
-		if ((!pEntry) || (!pEntry->ValidAsCLI))
-			break;
-
-		if (MsgLen <
-		    (LENGTH_802_1_H + LENGTH_EAPOL_H + sizeof(struct rt_key_descripter) -
-		     MAX_LEN_OF_RSNIE - 2))
-			break;
-
-		if (pEntry->WpaState != AS_PTKINITDONE)
-			break;
-
-		pData = (u8 *)Msg;
-		pMsg2 = (struct rt_eapol_packet *) (pData + LENGTH_802_1_H);
-		Len = MsgLen - LENGTH_802_1_H;
-
-		/* Sanity Check peer group message 2 - Replay Counter, MIC */
-		if (PeerWpaMessageSanity
-		    (pAd, pMsg2, Len, EAPOL_GROUP_MSG_2, pEntry) == FALSE)
-			break;
-
-		/* 3.  upgrade state */
-
-		RTMPCancelTimer(&pEntry->RetryTimer, &Cancelled);
-		pEntry->GTKState = REKEY_ESTABLISHED;
-
-		if ((pEntry->AuthMode == Ndis802_11AuthModeWPA2)
-		    || (pEntry->AuthMode == Ndis802_11AuthModeWPA2PSK)) {
-			/* send wireless event - for set key done WPA2 */
-			if (pAd->CommonCfg.bWirelessEvent)
-				RTMPSendWirelessEvent(pAd,
-						      IW_SET_KEY_DONE_WPA2_EVENT_FLAG,
-						      pEntry->Addr,
-						      pEntry->apidx, 0);
-
-			DBGPRINT(RT_DEBUG_OFF,
-				 ("AP SETKEYS DONE - WPA2, AuthMode(%d)=%s, WepStatus(%d)=%s, GroupWepStatus(%d)=%s\n\n",
-				  pEntry->AuthMode,
-				  GetAuthMode(pEntry->AuthMode),
-				  pEntry->WepStatus,
-				  GetEncryptType(pEntry->WepStatus),
-				  group_cipher, GetEncryptType(group_cipher)));
-		} else {
-			/* send wireless event - for set key done WPA */
-			if (pAd->CommonCfg.bWirelessEvent)
-				RTMPSendWirelessEvent(pAd,
-						      IW_SET_KEY_DONE_WPA1_EVENT_FLAG,
-						      pEntry->Addr,
-						      pEntry->apidx, 0);
-
-			DBGPRINT(RT_DEBUG_OFF,
-				 ("AP SETKEYS DONE - WPA1, AuthMode(%d)=%s, WepStatus(%d)=%s, GroupWepStatus(%d)=%s\n\n",
-				  pEntry->AuthMode,
-				  GetAuthMode(pEntry->AuthMode),
-				  pEntry->WepStatus,
-				  GetEncryptType(pEntry->WepStatus),
-				  group_cipher, GetEncryptType(group_cipher)));
-		}
-	} while (FALSE);
-}
-
-/*
-	========================================================================
-
-	Routine Description:
-		Classify WPA EAP message type
-
-	Arguments:
-		EAPType		Value of EAP message type
-		MsgType		Internal Message definition for MLME state machine
-
-	Return Value:
-		TRUE		Found appropriate message type
-		FALSE		No appropriate message type
-
-	IRQL = DISPATCH_LEVEL
-
-	Note:
-		All these constants are defined in wpa.h
-		For supplicant, there is only EAPOL Key message available
-
-	========================================================================
-*/
-BOOLEAN WpaMsgTypeSubst(u8 EAPType, int * MsgType)
-{
-	switch (EAPType) {
-	case EAPPacket:
-		*MsgType = MT2_EAPPacket;
-		break;
-	case EAPOLStart:
-		*MsgType = MT2_EAPOLStart;
-		break;
-	case EAPOLLogoff:
-		*MsgType = MT2_EAPOLLogoff;
-		break;
-	case EAPOLKey:
-		*MsgType = MT2_EAPOLKey;
-		break;
-	case EAPOLASFAlert:
-		*MsgType = MT2_EAPOLASFAlert;
-		break;
-	default:
-		return FALSE;
-	}
-	return TRUE;
-}
-
-/*
-	========================================================================
-
-	Routine Description:
-		The pseudo-random function(PRF) that hashes various inputs to
-		derive a pseudo-random value. To add liveness to the pseudo-random
-		value, a nonce should be one of the inputs.
-
-		It is used to generate PTK, GTK or some specific random value.
-
-	Arguments:
-		u8	*key,		-	the key material for HMAC_SHA1 use
-		int		key_len		-	the length of key
-		u8	*prefix		-	a prefix label
-		int		prefix_len	-	the length of the label
-		u8	*data		-	a specific data with variable length
-		int		data_len	-	the length of a specific data
-		int		len			-	the output length
-
-	Return Value:
-		u8	*output		-	the calculated result
-
-	Note:
-		802.11i-2004	Annex H.3
-
-	========================================================================
-*/
-void PRF(u8 * key,
-	 int key_len,
-	 u8 * prefix,
-	 int prefix_len,
-	 u8 * data, int data_len, u8 * output, int len)
-{
-	int i;
-	u8 *input;
-	int currentindex = 0;
-	int total_len;
-
-	/* Allocate memory for input */
-	os_alloc_mem(NULL, (u8 **) & input, 1024);
-
-	if (input == NULL) {
-		DBGPRINT(RT_DEBUG_ERROR, ("PRF: no memory!\n"));
-		return;
-	}
-	/* Generate concatenation input */
-	NdisMoveMemory(input, prefix, prefix_len);
-
-	/* Concatenate a single octet containing 0 */
-	input[prefix_len] = 0;
-
-	/* Concatenate specific data */
-	NdisMoveMemory(&input[prefix_len + 1], data, data_len);
-	total_len = prefix_len + 1 + data_len;
-
-	/* Concatenate a single octet containing 0 */
-	/* This octet shall be update later */
-	input[total_len] = 0;
-	total_len++;
-
-	/* Iterate to calculate the result by hmac-sha-1 */
-	/* Then concatenate to last result */
-	for (i = 0; i < (len + 19) / 20; i++) {
-		HMAC_SHA1(key, key_len, input, total_len, &output[currentindex],
-			  SHA1_DIGEST_SIZE);
-		currentindex += 20;
-
-		/* update the last octet */
-		input[total_len - 1]++;
-	}
-	os_free_mem(NULL, input);
-}
-
-/*
-* F(P, S, c, i) = U1 xor U2 xor ... Uc
-* U1 = PRF(P, S || Int(i))
-* U2 = PRF(P, U1)
-* Uc = PRF(P, Uc-1)
-*/
-
-static void F(char *password, unsigned char *ssid, int ssidlength,
-	      int iterations, int count, unsigned char *output)
-{
-	unsigned char digest[36], digest1[SHA1_DIGEST_SIZE];
-	int i, j;
-
-	/* U1 = PRF(P, S || int(i)) */
-	memcpy(digest, ssid, ssidlength);
-	digest[ssidlength] = (unsigned char)((count >> 24) & 0xff);
-	digest[ssidlength + 1] = (unsigned char)((count >> 16) & 0xff);
-	digest[ssidlength + 2] = (unsigned char)((count >> 8) & 0xff);
-	digest[ssidlength + 3] = (unsigned char)(count & 0xff);
-	HMAC_SHA1((unsigned char *)password, (int)strlen(password), digest, ssidlength + 4, digest1, SHA1_DIGEST_SIZE);	/* for WPA update */
-
-	/* output = U1 */
-	memcpy(output, digest1, SHA1_DIGEST_SIZE);
-
-	for (i = 1; i < iterations; i++) {
-		/* Un = PRF(P, Un-1) */
-		HMAC_SHA1((unsigned char *)password, (int)strlen(password), digest1, SHA1_DIGEST_SIZE, digest, SHA1_DIGEST_SIZE);	/* for WPA update */
-		memcpy(digest1, digest, SHA1_DIGEST_SIZE);
-
-		/* output = output xor Un */
-		for (j = 0; j < SHA1_DIGEST_SIZE; j++) {
-			output[j] ^= digest[j];
-		}
-	}
-}
-
-/*
-* password - ascii string up to 63 characters in length
-* ssid - octet string up to 32 octets
-* ssidlength - length of ssid in octets
-* output must be 40 octets in length and outputs 256 bits of key
-*/
-int PasswordHash(char *password, u8 *ssid, int ssidlength, u8 *output)
-{
-	if ((strlen(password) > 63) || (ssidlength > 32))
-		return 0;
-
-	F(password, ssid, ssidlength, 4096, 1, output);
-	F(password, ssid, ssidlength, 4096, 2, &output[SHA1_DIGEST_SIZE]);
-	return 1;
-}
-
-/*
-	========================================================================
-
-	Routine Description:
-		It utilizes PRF-384 or PRF-512 to derive session-specific keys from a PMK.
-		It shall be called by 4-way handshake processing.
-
-	Arguments:
-		pAd	-	pointer to our pAdapter context
-		PMK		-	pointer to PMK
-		ANonce	-	pointer to ANonce
-		AA		-	pointer to Authenticator Address
-		SNonce	-	pointer to SNonce
-		SA		-	pointer to Supplicant Address
-		len		-	indicate the length of PTK (octet)
-
-	Return Value:
-		Output		pointer to the PTK
-
-	Note:
-		Refer to IEEE 802.11i-2004 8.5.1.2
-
-	========================================================================
-*/
-void WpaDerivePTK(struct rt_rtmp_adapter *pAd,
-		  u8 * PMK,
-		  u8 * ANonce,
-		  u8 * AA,
-		  u8 * SNonce,
-		  u8 * SA, u8 * output, u32 len)
-{
-	u8 concatenation[76];
-	u32 CurrPos = 0;
-	u8 temp[32];
-	u8 Prefix[] =
-	    { 'P', 'a', 'i', 'r', 'w', 'i', 's', 'e', ' ', 'k', 'e', 'y', ' ',
-		'e', 'x', 'p', 'a', 'n', 's', 'i', 'o', 'n'
-	};
-
-	/* initiate the concatenation input */
-	NdisZeroMemory(temp, sizeof(temp));
-	NdisZeroMemory(concatenation, 76);
-
-	/* Get smaller address */
-	if (RTMPCompareMemory(SA, AA, 6) == 1)
-		NdisMoveMemory(concatenation, AA, 6);
-	else
-		NdisMoveMemory(concatenation, SA, 6);
-	CurrPos += 6;
-
-	/* Get larger address */
-	if (RTMPCompareMemory(SA, AA, 6) == 1)
-		NdisMoveMemory(&concatenation[CurrPos], SA, 6);
-	else
-		NdisMoveMemory(&concatenation[CurrPos], AA, 6);
-
-	/* store the larger mac address for backward compatible of */
-	/* ralink proprietary STA-key issue */
-	NdisMoveMemory(temp, &concatenation[CurrPos], MAC_ADDR_LEN);
-	CurrPos += 6;
-
-	/* Get smaller Nonce */
-	if (RTMPCompareMemory(ANonce, SNonce, 32) == 0)
-		NdisMoveMemory(&concatenation[CurrPos], temp, 32);	/* patch for ralink proprietary STA-key issue */
-	else if (RTMPCompareMemory(ANonce, SNonce, 32) == 1)
-		NdisMoveMemory(&concatenation[CurrPos], SNonce, 32);
-	else
-		NdisMoveMemory(&concatenation[CurrPos], ANonce, 32);
-	CurrPos += 32;
-
-	/* Get larger Nonce */
-	if (RTMPCompareMemory(ANonce, SNonce, 32) == 0)
-		NdisMoveMemory(&concatenation[CurrPos], temp, 32);	/* patch for ralink proprietary STA-key issue */
-	else if (RTMPCompareMemory(ANonce, SNonce, 32) == 1)
-		NdisMoveMemory(&concatenation[CurrPos], ANonce, 32);
-	else
-		NdisMoveMemory(&concatenation[CurrPos], SNonce, 32);
-	CurrPos += 32;
-
-	hex_dump("concatenation=", concatenation, 76);
-
-	/* Use PRF to generate PTK */
-	PRF(PMK, LEN_MASTER_KEY, Prefix, 22, concatenation, 76, output, len);
-
-}
-
-/*
-	========================================================================
-
-	Routine Description:
-		Generate random number by software.
-
-	Arguments:
-		pAd		-	pointer to our pAdapter context
-		macAddr	-	pointer to local MAC address
-
-	Return Value:
-
-	Note:
-		802.1ii-2004  Annex H.5
-
-	========================================================================
-*/
-void GenRandom(struct rt_rtmp_adapter *pAd, u8 * macAddr, u8 * random)
-{
-	int i, curr;
-	u8 local[80], KeyCounter[32];
-	u8 result[80];
-	unsigned long CurrentTime;
-	u8 prefix[] =
-	    { 'I', 'n', 'i', 't', ' ', 'C', 'o', 'u', 'n', 't', 'e', 'r' };
-
-	/* Zero the related information */
-	NdisZeroMemory(result, 80);
-	NdisZeroMemory(local, 80);
-	NdisZeroMemory(KeyCounter, 32);
-
-	for (i = 0; i < 32; i++) {
-		/* copy the local MAC address */
-		COPY_MAC_ADDR(local, macAddr);
-		curr = MAC_ADDR_LEN;
-
-		/* concatenate the current time */
-		NdisGetSystemUpTime(&CurrentTime);
-		NdisMoveMemory(&local[curr], &CurrentTime, sizeof(CurrentTime));
-		curr += sizeof(CurrentTime);
-
-		/* concatenate the last result */
-		NdisMoveMemory(&local[curr], result, 32);
-		curr += 32;
-
-		/* concatenate a variable */
-		NdisMoveMemory(&local[curr], &i, 2);
-		curr += 2;
-
-		/* calculate the result */
-		PRF(KeyCounter, 32, prefix, 12, local, curr, result, 32);
-	}
-
-	NdisMoveMemory(random, result, 32);
-}
-
-/*
-	========================================================================
-
-	Routine Description:
-		Build cipher suite in RSN-IE.
-		It only shall be called by RTMPMakeRSNIE.
-
-	Arguments:
-		pAd			-	pointer to our pAdapter context
-	ElementID	-	indicate the WPA1 or WPA2
-	WepStatus	-	indicate the encryption type
-		bMixCipher	-	a boolean to indicate the pairwise cipher and group
-						cipher are the same or not
-
-	Return Value:
-
-	Note:
-
-	========================================================================
-*/
-static void RTMPMakeRsnIeCipher(struct rt_rtmp_adapter *pAd,
-				u8 ElementID,
-				u32 WepStatus,
-				IN BOOLEAN bMixCipher,
-				u8 FlexibleCipher,
-				u8 *pRsnIe, u8 * rsn_len)
-{
-	u8 PairwiseCnt;
-
-	*rsn_len = 0;
-
-	/* decide WPA2 or WPA1 */
-	if (ElementID == Wpa2Ie) {
-		struct rt_rsnie2 *pRsnie_cipher = (struct rt_rsnie2 *)pRsnIe;
-
-		/* Assign the verson as 1 */
-		pRsnie_cipher->version = 1;
-
-		switch (WepStatus) {
-			/* TKIP mode */
-		case Ndis802_11Encryption2Enabled:
-			NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA2_TKIP, 4);
-			pRsnie_cipher->ucount = 1;
-			NdisMoveMemory(pRsnie_cipher->ucast[0].oui,
-				       OUI_WPA2_TKIP, 4);
-			*rsn_len = sizeof(struct rt_rsnie2);
-			break;
-
-			/* AES mode */
-		case Ndis802_11Encryption3Enabled:
-			if (bMixCipher)
-				NdisMoveMemory(pRsnie_cipher->mcast,
-					       OUI_WPA2_TKIP, 4);
-			else
-				NdisMoveMemory(pRsnie_cipher->mcast,
-					       OUI_WPA2_CCMP, 4);
-			pRsnie_cipher->ucount = 1;
-			NdisMoveMemory(pRsnie_cipher->ucast[0].oui,
-				       OUI_WPA2_CCMP, 4);
-			*rsn_len = sizeof(struct rt_rsnie2);
-			break;
-
-			/* TKIP-AES mix mode */
-		case Ndis802_11Encryption4Enabled:
-			NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA2_TKIP, 4);
-
-			PairwiseCnt = 1;
-			/* Insert WPA2 TKIP as the first pairwise cipher */
-			if (MIX_CIPHER_WPA2_TKIP_ON(FlexibleCipher)) {
-				NdisMoveMemory(pRsnie_cipher->ucast[0].oui,
-					       OUI_WPA2_TKIP, 4);
-				/* Insert WPA2 AES as the secondary pairwise cipher */
-				if (MIX_CIPHER_WPA2_AES_ON(FlexibleCipher)) {
-					NdisMoveMemory(pRsnie_cipher->ucast[0].
-						       oui + 4, OUI_WPA2_CCMP,
-						       4);
-					PairwiseCnt = 2;
-				}
-			} else {
-				/* Insert WPA2 AES as the first pairwise cipher */
-				NdisMoveMemory(pRsnie_cipher->ucast[0].oui,
-					       OUI_WPA2_CCMP, 4);
-			}
-
-			pRsnie_cipher->ucount = PairwiseCnt;
-			*rsn_len = sizeof(struct rt_rsnie2) + (4 * (PairwiseCnt - 1));
-			break;
-		}
-
-		if ((pAd->OpMode == OPMODE_STA) &&
-		    (pAd->StaCfg.GroupCipher != Ndis802_11Encryption2Enabled) &&
-		    (pAd->StaCfg.GroupCipher != Ndis802_11Encryption3Enabled)) {
-			u32 GroupCipher = pAd->StaCfg.GroupCipher;
-			switch (GroupCipher) {
-			case Ndis802_11GroupWEP40Enabled:
-				NdisMoveMemory(pRsnie_cipher->mcast,
-					       OUI_WPA2_WEP40, 4);
-				break;
-			case Ndis802_11GroupWEP104Enabled:
-				NdisMoveMemory(pRsnie_cipher->mcast,
-					       OUI_WPA2_WEP104, 4);
-				break;
-			}
-		}
-		/* swap for big-endian platform */
-		pRsnie_cipher->version = cpu2le16(pRsnie_cipher->version);
-		pRsnie_cipher->ucount = cpu2le16(pRsnie_cipher->ucount);
-	} else {
-		struct rt_rsnie *pRsnie_cipher = (struct rt_rsnie *)pRsnIe;
-
-		/* Assign OUI and version */
-		NdisMoveMemory(pRsnie_cipher->oui, OUI_WPA_VERSION, 4);
-		pRsnie_cipher->version = 1;
-
-		switch (WepStatus) {
-			/* TKIP mode */
-		case Ndis802_11Encryption2Enabled:
-			NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA_TKIP, 4);
-			pRsnie_cipher->ucount = 1;
-			NdisMoveMemory(pRsnie_cipher->ucast[0].oui,
-				       OUI_WPA_TKIP, 4);
-			*rsn_len = sizeof(struct rt_rsnie);
-			break;
-
-			/* AES mode */
-		case Ndis802_11Encryption3Enabled:
-			if (bMixCipher)
-				NdisMoveMemory(pRsnie_cipher->mcast,
-					       OUI_WPA_TKIP, 4);
-			else
-				NdisMoveMemory(pRsnie_cipher->mcast,
-					       OUI_WPA_CCMP, 4);
-			pRsnie_cipher->ucount = 1;
-			NdisMoveMemory(pRsnie_cipher->ucast[0].oui,
-				       OUI_WPA_CCMP, 4);
-			*rsn_len = sizeof(struct rt_rsnie);
-			break;
-
-			/* TKIP-AES mix mode */
-		case Ndis802_11Encryption4Enabled:
-			NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA_TKIP, 4);
-
-			PairwiseCnt = 1;
-			/* Insert WPA TKIP as the first pairwise cipher */
-			if (MIX_CIPHER_WPA_TKIP_ON(FlexibleCipher)) {
-				NdisMoveMemory(pRsnie_cipher->ucast[0].oui,
-					       OUI_WPA_TKIP, 4);
-				/* Insert WPA AES as the secondary pairwise cipher */
-				if (MIX_CIPHER_WPA_AES_ON(FlexibleCipher)) {
-					NdisMoveMemory(pRsnie_cipher->ucast[0].
-						       oui + 4, OUI_WPA_CCMP,
-						       4);
-					PairwiseCnt = 2;
-				}
-			} else {
-				/* Insert WPA AES as the first pairwise cipher */
-				NdisMoveMemory(pRsnie_cipher->ucast[0].oui,
-					       OUI_WPA_CCMP, 4);
-			}
-
-			pRsnie_cipher->ucount = PairwiseCnt;
-			*rsn_len = sizeof(struct rt_rsnie) + (4 * (PairwiseCnt - 1));
-			break;
-		}
-
-		if ((pAd->OpMode == OPMODE_STA) &&
-		    (pAd->StaCfg.GroupCipher != Ndis802_11Encryption2Enabled) &&
-		    (pAd->StaCfg.GroupCipher != Ndis802_11Encryption3Enabled)) {
-			u32 GroupCipher = pAd->StaCfg.GroupCipher;
-			switch (GroupCipher) {
-			case Ndis802_11GroupWEP40Enabled:
-				NdisMoveMemory(pRsnie_cipher->mcast,
-					       OUI_WPA_WEP40, 4);
-				break;
-			case Ndis802_11GroupWEP104Enabled:
-				NdisMoveMemory(pRsnie_cipher->mcast,
-					       OUI_WPA_WEP104, 4);
-				break;
-			}
-		}
-		/* swap for big-endian platform */
-		pRsnie_cipher->version = cpu2le16(pRsnie_cipher->version);
-		pRsnie_cipher->ucount = cpu2le16(pRsnie_cipher->ucount);
-	}
-}
-
-/*
-	========================================================================
-
-	Routine Description:
-		Build AKM suite in RSN-IE.
-		It only shall be called by RTMPMakeRSNIE.
-
-	Arguments:
-		pAd			-	pointer to our pAdapter context
-	ElementID	-	indicate the WPA1 or WPA2
-	AuthMode	-	indicate the authentication mode
-		apidx		-	indicate the interface index
-
-	Return Value:
-
-	Note:
-
-	========================================================================
-*/
-static void RTMPMakeRsnIeAKM(struct rt_rtmp_adapter *pAd,
-			     u8 ElementID,
-			     u32 AuthMode,
-			     u8 apidx,
-			     u8 *pRsnIe, u8 * rsn_len)
-{
-	struct rt_rsnie_auth *pRsnie_auth;
-	u8 AkmCnt = 1;	/* default as 1 */
-
-	pRsnie_auth = (struct rt_rsnie_auth *) (pRsnIe + (*rsn_len));
-
-	/* decide WPA2 or WPA1 */
-	if (ElementID == Wpa2Ie) {
-
-		switch (AuthMode) {
-		case Ndis802_11AuthModeWPA2:
-		case Ndis802_11AuthModeWPA1WPA2:
-			NdisMoveMemory(pRsnie_auth->auth[0].oui,
-				       OUI_WPA2_8021X_AKM, 4);
-			break;
-
-		case Ndis802_11AuthModeWPA2PSK:
-		case Ndis802_11AuthModeWPA1PSKWPA2PSK:
-			NdisMoveMemory(pRsnie_auth->auth[0].oui,
-				       OUI_WPA2_PSK_AKM, 4);
-			break;
-		default:
-			AkmCnt = 0;
-			break;
-
-		}
-	} else {
-		switch (AuthMode) {
-		case Ndis802_11AuthModeWPA:
-		case Ndis802_11AuthModeWPA1WPA2:
-			NdisMoveMemory(pRsnie_auth->auth[0].oui,
-				       OUI_WPA_8021X_AKM, 4);
-			break;
-
-		case Ndis802_11AuthModeWPAPSK:
-		case Ndis802_11AuthModeWPA1PSKWPA2PSK:
-			NdisMoveMemory(pRsnie_auth->auth[0].oui,
-				       OUI_WPA_PSK_AKM, 4);
-			break;
-
-		case Ndis802_11AuthModeWPANone:
-			NdisMoveMemory(pRsnie_auth->auth[0].oui,
-				       OUI_WPA_NONE_AKM, 4);
-			break;
-		default:
-			AkmCnt = 0;
-			break;
-		}
-	}
-
-	pRsnie_auth->acount = AkmCnt;
-	pRsnie_auth->acount = cpu2le16(pRsnie_auth->acount);
-
-	/* update current RSNIE length */
-	(*rsn_len) += (sizeof(struct rt_rsnie_auth) + (4 * (AkmCnt - 1)));
-
-}
-
-/*
-	========================================================================
-
-	Routine Description:
-		Build capability in RSN-IE.
-		It only shall be called by RTMPMakeRSNIE.
-
-	Arguments:
-		pAd			-	pointer to our pAdapter context
-	ElementID	-	indicate the WPA1 or WPA2
-		apidx		-	indicate the interface index
-
-	Return Value:
-
-	Note:
-
-	========================================================================
-*/
-static void RTMPMakeRsnIeCap(struct rt_rtmp_adapter *pAd,
-			     u8 ElementID,
-			     u8 apidx,
-			     u8 *pRsnIe, u8 * rsn_len)
-{
-	RSN_CAPABILITIES *pRSN_Cap;
-
-	/* it could be ignored in WPA1 mode */
-	if (ElementID == WpaIe)
-		return;
-
-	pRSN_Cap = (RSN_CAPABILITIES *) (pRsnIe + (*rsn_len));
-
-	pRSN_Cap->word = cpu2le16(pRSN_Cap->word);
-
-	(*rsn_len) += sizeof(RSN_CAPABILITIES);	/* update current RSNIE length */
-
-}
-
-/*
-	========================================================================
-
-	Routine Description:
-		Build RSN IE context. It is not included element-ID and length.
-
-	Arguments:
-		pAd			-	pointer to our pAdapter context
-	AuthMode	-	indicate the authentication mode
-	WepStatus	-	indicate the encryption type
-		apidx		-	indicate the interface index
-
-	Return Value:
-
-	Note:
-
-	========================================================================
-*/
-void RTMPMakeRSNIE(struct rt_rtmp_adapter *pAd,
-		   u32 AuthMode, u32 WepStatus, u8 apidx)
-{
-	u8 *pRsnIe = NULL;	/* primary RSNIE */
-	u8 *rsnielen_cur_p = 0;	/* the length of the primary RSNIE */
-	u8 *rsnielen_ex_cur_p = 0;	/* the length of the secondary RSNIE */
-	u8 PrimaryRsnie;
-	BOOLEAN bMixCipher = FALSE;	/* indicate the pairwise and group cipher are different */
-	u8 p_offset;
-	WPA_MIX_PAIR_CIPHER FlexibleCipher = WPA_TKIPAES_WPA2_TKIPAES;	/* it provide the more flexible cipher combination in WPA-WPA2 and TKIPAES mode */
-
-	rsnielen_cur_p = NULL;
-	rsnielen_ex_cur_p = NULL;
-
-	{
-		{
-			if (pAd->StaCfg.WpaSupplicantUP !=
-			    WPA_SUPPLICANT_DISABLE) {
-				if (AuthMode < Ndis802_11AuthModeWPA)
-					return;
-			} else {
-				/* Support WPAPSK or WPA2PSK in STA-Infra mode */
-				/* Support WPANone in STA-Adhoc mode */
-				if ((AuthMode != Ndis802_11AuthModeWPAPSK) &&
-				    (AuthMode != Ndis802_11AuthModeWPA2PSK) &&
-				    (AuthMode != Ndis802_11AuthModeWPANone)
-				    )
-					return;
-			}
-
-			DBGPRINT(RT_DEBUG_TRACE, ("==> RTMPMakeRSNIE(STA)\n"));
-
-			/* Zero RSNIE context */
-			pAd->StaCfg.RSNIE_Len = 0;
-			NdisZeroMemory(pAd->StaCfg.RSN_IE, MAX_LEN_OF_RSNIE);
-
-			/* Pointer to RSNIE */
-			rsnielen_cur_p = &pAd->StaCfg.RSNIE_Len;
-			pRsnIe = pAd->StaCfg.RSN_IE;
-
-			bMixCipher = pAd->StaCfg.bMixCipher;
-		}
-	}
-
-	/* indicate primary RSNIE as WPA or WPA2 */
-	if ((AuthMode == Ndis802_11AuthModeWPA) ||
-	    (AuthMode == Ndis802_11AuthModeWPAPSK) ||
-	    (AuthMode == Ndis802_11AuthModeWPANone) ||
-	    (AuthMode == Ndis802_11AuthModeWPA1WPA2) ||
-	    (AuthMode == Ndis802_11AuthModeWPA1PSKWPA2PSK))
-		PrimaryRsnie = WpaIe;
-	else
-		PrimaryRsnie = Wpa2Ie;
-
-	{
-		/* Build the primary RSNIE */
-		/* 1. insert cipher suite */
-		RTMPMakeRsnIeCipher(pAd, PrimaryRsnie, WepStatus, bMixCipher,
-				    FlexibleCipher, pRsnIe, &p_offset);
-
-		/* 2. insert AKM */
-		RTMPMakeRsnIeAKM(pAd, PrimaryRsnie, AuthMode, apidx, pRsnIe,
-				 &p_offset);
-
-		/* 3. insert capability */
-		RTMPMakeRsnIeCap(pAd, PrimaryRsnie, apidx, pRsnIe, &p_offset);
-	}
-
-	/* 4. update the RSNIE length */
-	*rsnielen_cur_p = p_offset;
-
-	hex_dump("The primary RSNIE", pRsnIe, (*rsnielen_cur_p));
-
-}
-
-/*
-    ==========================================================================
-    Description:
-		Check whether the received frame is EAP frame.
-
-	Arguments:
-		pAd				-	pointer to our pAdapter context
-		pEntry			-	pointer to active entry
-		pData			-	the received frame
-		DataByteCount	-	the received frame's length
-		FromWhichBSSID	-	indicate the interface index
-
-    Return:
-         TRUE			-	This frame is EAP frame
-         FALSE			-	otherwise
-    ==========================================================================
-*/
-BOOLEAN RTMPCheckWPAframe(struct rt_rtmp_adapter *pAd,
-			  struct rt_mac_table_entry *pEntry,
-			  u8 *pData,
-			  unsigned long DataByteCount, u8 FromWhichBSSID)
-{
-	unsigned long Body_len;
-	BOOLEAN Cancelled;
-
-	if (DataByteCount < (LENGTH_802_1_H + LENGTH_EAPOL_H))
-		return FALSE;
-
-	/* Skip LLC header */
-	if (NdisEqualMemory(SNAP_802_1H, pData, 6) ||
-	    /* Cisco 1200 AP may send packet with SNAP_BRIDGE_TUNNEL */
-	    NdisEqualMemory(SNAP_BRIDGE_TUNNEL, pData, 6)) {
-		pData += 6;
-	}
-	/* Skip 2-bytes EAPoL type */
-	if (NdisEqualMemory(EAPOL, pData, 2)) {
-		pData += 2;
-	} else
-		return FALSE;
-
-	switch (*(pData + 1)) {
-	case EAPPacket:
-		Body_len = (*(pData + 2) << 8) | (*(pData + 3));
-		DBGPRINT(RT_DEBUG_TRACE,
-			 ("Receive EAP-Packet frame, TYPE = 0, Length = %ld\n",
-			  Body_len));
-		break;
-	case EAPOLStart:
-		DBGPRINT(RT_DEBUG_TRACE,
-			 ("Receive EAPOL-Start frame, TYPE = 1 \n"));
-		if (pEntry->EnqueueEapolStartTimerRunning !=
-		    EAPOL_START_DISABLE) {
-			DBGPRINT(RT_DEBUG_TRACE,
-				 ("Cancel the EnqueueEapolStartTimerRunning \n"));
-			RTMPCancelTimer(&pEntry->EnqueueStartForPSKTimer,
-					&Cancelled);
-			pEntry->EnqueueEapolStartTimerRunning =
-			    EAPOL_START_DISABLE;
-		}
-		break;
-	case EAPOLLogoff:
-		DBGPRINT(RT_DEBUG_TRACE,
-			 ("Receive EAPOLLogoff frame, TYPE = 2 \n"));
-		break;
-	case EAPOLKey:
-		Body_len = (*(pData + 2) << 8) | (*(pData + 3));
-		DBGPRINT(RT_DEBUG_TRACE,
-			 ("Receive EAPOL-Key frame, TYPE = 3, Length = %ld\n",
-			  Body_len));
-		break;
-	case EAPOLASFAlert:
-		DBGPRINT(RT_DEBUG_TRACE,
-			 ("Receive EAPOLASFAlert frame, TYPE = 4 \n"));
-		break;
-	default:
-		return FALSE;
-
-	}
-	return TRUE;
-}
-
-/*
-    ==========================================================================
-    Description:
-		Report the EAP message type
-
-	Arguments:
-		msg		-	EAPOL_PAIR_MSG_1
-					EAPOL_PAIR_MSG_2
-					EAPOL_PAIR_MSG_3
-					EAPOL_PAIR_MSG_4
-					EAPOL_GROUP_MSG_1
-					EAPOL_GROUP_MSG_2
-
-    Return:
-         message type string
-
-    ==========================================================================
-*/
-char *GetEapolMsgType(char msg)
-{
-	if (msg == EAPOL_PAIR_MSG_1)
-		return "Pairwise Message 1";
-	else if (msg == EAPOL_PAIR_MSG_2)
-		return "Pairwise Message 2";
-	else if (msg == EAPOL_PAIR_MSG_3)
-		return "Pairwise Message 3";
-	else if (msg == EAPOL_PAIR_MSG_4)
-		return "Pairwise Message 4";
-	else if (msg == EAPOL_GROUP_MSG_1)
-		return "Group Message 1";
-	else if (msg == EAPOL_GROUP_MSG_2)
-		return "Group Message 2";
-	else
-		return "Invalid Message";
-}
-
-/*
-	========================================================================
-
-	Routine Description:
-    Check Sanity RSN IE of EAPoL message
-
-	Arguments:
-
-	Return Value:
-
-	========================================================================
-*/
-BOOLEAN RTMPCheckRSNIE(struct rt_rtmp_adapter *pAd,
-		       u8 *pData,
-		       u8 DataLen,
-		       struct rt_mac_table_entry *pEntry, u8 * Offset)
-{
-	u8 *pVIE;
-	u8 len;
-	struct rt_eid * pEid;
-	BOOLEAN result = FALSE;
-
-	pVIE = pData;
-	len = DataLen;
-	*Offset = 0;
-
-	while (len > sizeof(struct rt_rsnie2)) {
-		pEid = (struct rt_eid *) pVIE;
-		/* WPA RSN IE */
-		if ((pEid->Eid == IE_WPA)
-		    && (NdisEqualMemory(pEid->Octet, WPA_OUI, 4))) {
-			if ((pEntry->AuthMode == Ndis802_11AuthModeWPA
-			     || pEntry->AuthMode == Ndis802_11AuthModeWPAPSK)
-			    &&
-			    (NdisEqualMemory
-			     (pVIE, pEntry->RSN_IE, pEntry->RSNIE_Len))
-			    && (pEntry->RSNIE_Len == (pEid->Len + 2))) {
-				result = TRUE;
-			}
-
-			*Offset += (pEid->Len + 2);
-		}
-		/* WPA2 RSN IE */
-		else if ((pEid->Eid == IE_RSN)
-			 && (NdisEqualMemory(pEid->Octet + 2, RSN_OUI, 3))) {
-			if ((pEntry->AuthMode == Ndis802_11AuthModeWPA2
-			     || pEntry->AuthMode == Ndis802_11AuthModeWPA2PSK)
-			    && (pEid->Eid == pEntry->RSN_IE[0])
-			    && ((pEid->Len + 2) >= pEntry->RSNIE_Len)
-			    &&
-			    (NdisEqualMemory
-			     (pEid->Octet, &pEntry->RSN_IE[2],
-			      pEntry->RSNIE_Len - 2))) {
-
-				result = TRUE;
-			}
-
-			*Offset += (pEid->Len + 2);
-		} else {
-			break;
-		}
-
-		pVIE += (pEid->Len + 2);
-		len -= (pEid->Len + 2);
-	}
-
-	return result;
-
-}
-
-/*
-	========================================================================
-
-	Routine Description:
-    Parse KEYDATA field.  KEYDATA[] May contain 2 RSN IE and optionally GTK.
-    GTK  is encaptulated in KDE format at  p.83 802.11i D10
-
-	Arguments:
-
-	Return Value:
-
-	Note:
-        802.11i D10
-
-	========================================================================
-*/
-BOOLEAN RTMPParseEapolKeyData(struct rt_rtmp_adapter *pAd,
-			      u8 *pKeyData,
-			      u8 KeyDataLen,
-			      u8 GroupKeyIndex,
-			      u8 MsgType,
-			      IN BOOLEAN bWPA2, struct rt_mac_table_entry *pEntry)
-{
-	struct rt_kde_encap * pKDE = NULL;
-	u8 *pMyKeyData = pKeyData;
-	u8 KeyDataLength = KeyDataLen;
-	u8 GTKLEN = 0;
-	u8 DefaultIdx = 0;
-	u8 skip_offset;
-
-	/* Verify The RSN IE contained in pairewise_msg_2 && pairewise_msg_3 and skip it */
-	if (MsgType == EAPOL_PAIR_MSG_2 || MsgType == EAPOL_PAIR_MSG_3) {
-		/* Check RSN IE whether it is WPA2/WPA2PSK */
-		if (!RTMPCheckRSNIE
-		    (pAd, pKeyData, KeyDataLen, pEntry, &skip_offset)) {
-			/* send wireless event - for RSN IE different */
-			if (pAd->CommonCfg.bWirelessEvent)
-				RTMPSendWirelessEvent(pAd,
-						      IW_RSNIE_DIFF_EVENT_FLAG,
-						      pEntry->Addr,
-						      pEntry->apidx, 0);
-
-			DBGPRINT(RT_DEBUG_ERROR,
-				 ("RSN_IE Different in msg %d of 4-way handshake!\n",
-				  MsgType));
-			hex_dump("Receive RSN_IE ", pKeyData, KeyDataLen);
-			hex_dump("Desired RSN_IE ", pEntry->RSN_IE,
-				 pEntry->RSNIE_Len);
-
-			return FALSE;
-		} else {
-			if (bWPA2 && MsgType == EAPOL_PAIR_MSG_3) {
-				WpaShowAllsuite(pMyKeyData, skip_offset);
-
-				/* skip RSN IE */
-				pMyKeyData += skip_offset;
-				KeyDataLength -= skip_offset;
-				DBGPRINT(RT_DEBUG_TRACE,
-					 ("RTMPParseEapolKeyData ==> WPA2/WPA2PSK RSN IE matched in Msg 3, Length(%d) \n",
-					  skip_offset));
-			} else
-				return TRUE;
-		}
-	}
-
-	DBGPRINT(RT_DEBUG_TRACE,
-		 ("RTMPParseEapolKeyData ==> KeyDataLength %d without RSN_IE \n",
-		  KeyDataLength));
-	/*hex_dump("remain data", pMyKeyData, KeyDataLength); */
-
-	/* Parse EKD format in pairwise_msg_3_WPA2 && group_msg_1_WPA2 */
-	if (bWPA2
-	    && (MsgType == EAPOL_PAIR_MSG_3 || MsgType == EAPOL_GROUP_MSG_1)) {
-		if (KeyDataLength >= 8)	/* KDE format exclude GTK length */
-		{
-			pKDE = (struct rt_kde_encap *) pMyKeyData;
-
-			DefaultIdx = pKDE->GTKEncap.Kid;
-
-			/* Sanity check - KED length */
-			if (KeyDataLength < (pKDE->Len + 2)) {
-				DBGPRINT(RT_DEBUG_ERROR,
-					 ("ERROR: The len from KDE is too short \n"));
-				return FALSE;
-			}
-			/* Get GTK length - refer to IEEE 802.11i-2004 p.82 */
-			GTKLEN = pKDE->Len - 6;
-			if (GTKLEN < LEN_AES_KEY) {
-				DBGPRINT(RT_DEBUG_ERROR,
-					 ("ERROR: GTK Key length is too short (%d) \n",
-					  GTKLEN));
-				return FALSE;
-			}
-
-		} else {
-			DBGPRINT(RT_DEBUG_ERROR,
-				 ("ERROR: KDE format length is too short \n"));
-			return FALSE;
-		}
-
-		DBGPRINT(RT_DEBUG_TRACE,
-			 ("GTK in KDE format ,DefaultKeyID=%d, KeyLen=%d \n",
-			  DefaultIdx, GTKLEN));
-		/* skip it */
-		pMyKeyData += 8;
-		KeyDataLength -= 8;
-
-	} else if (!bWPA2 && MsgType == EAPOL_GROUP_MSG_1) {
-		DefaultIdx = GroupKeyIndex;
-		DBGPRINT(RT_DEBUG_TRACE,
-			 ("GTK DefaultKeyID=%d \n", DefaultIdx));
-	}
-	/* Sanity check - shared key index must be 1 ~ 3 */
-	if (DefaultIdx < 1 || DefaultIdx > 3) {
-		DBGPRINT(RT_DEBUG_ERROR,
-			 ("ERROR: GTK Key index(%d) is invalid in %s %s \n",
-			  DefaultIdx, ((bWPA2) ? "WPA2" : "WPA"),
-			  GetEapolMsgType(MsgType)));
-		return FALSE;
-	}
-
-	{
-		struct rt_cipher_key *pSharedKey;
-
-		/* set key material, TxMic and RxMic */
-		NdisMoveMemory(pAd->StaCfg.GTK, pMyKeyData, 32);
-		pAd->StaCfg.DefaultKeyId = DefaultIdx;
-
-		pSharedKey = &pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId];
-
-		/* Prepare pair-wise key information into shared key table */
-		NdisZeroMemory(pSharedKey, sizeof(struct rt_cipher_key));
-		pSharedKey->KeyLen = LEN_TKIP_EK;
-		NdisMoveMemory(pSharedKey->Key, pAd->StaCfg.GTK, LEN_TKIP_EK);
-		NdisMoveMemory(pSharedKey->RxMic, &pAd->StaCfg.GTK[16],
-			       LEN_TKIP_RXMICK);
-		NdisMoveMemory(pSharedKey->TxMic, &pAd->StaCfg.GTK[24],
-			       LEN_TKIP_TXMICK);
-
-		/* Update Shared Key CipherAlg */
-		pSharedKey->CipherAlg = CIPHER_NONE;
-		if (pAd->StaCfg.GroupCipher == Ndis802_11Encryption2Enabled)
-			pSharedKey->CipherAlg = CIPHER_TKIP;
-		else if (pAd->StaCfg.GroupCipher ==
-			 Ndis802_11Encryption3Enabled)
-			pSharedKey->CipherAlg = CIPHER_AES;
-		else if (pAd->StaCfg.GroupCipher == Ndis802_11GroupWEP40Enabled)
-			pSharedKey->CipherAlg = CIPHER_WEP64;
-		else if (pAd->StaCfg.GroupCipher ==
-			 Ndis802_11GroupWEP104Enabled)
-			pSharedKey->CipherAlg = CIPHER_WEP128;
-
-		/* Update group key information to ASIC Shared Key Table */
-		AsicAddSharedKeyEntry(pAd,
-				      BSS0,
-				      pAd->StaCfg.DefaultKeyId,
-				      pSharedKey->CipherAlg,
-				      pSharedKey->Key,
-				      pSharedKey->TxMic, pSharedKey->RxMic);
-
-		/* Update ASIC WCID attribute table and IVEIV table */
-		RTMPAddWcidAttributeEntry(pAd,
-					  BSS0,
-					  pAd->StaCfg.DefaultKeyId,
-					  pSharedKey->CipherAlg, NULL);
-	}
-
-	return TRUE;
-
-}
-
-/*
-	========================================================================
-
-	Routine Description:
-		Construct EAPoL message for WPA handshaking
-		Its format is below,
-
-		+--------------------+
-		| Protocol Version	 |  1 octet
-		+--------------------+
-		| Protocol Type		 |	1 octet
-		+--------------------+
-		| Body Length		 |  2 octets
-		+--------------------+
-		| Descriptor Type	 |	1 octet
-		+--------------------+
-		| Key Information    |	2 octets
-		+--------------------+
-		| Key Length	     |  1 octet
-		+--------------------+
-		| Key Repaly Counter |	8 octets
-		+--------------------+
-		| Key Nonce		     |  32 octets
-		+--------------------+
-		| Key IV			 |  16 octets
-		+--------------------+
-		| Key RSC			 |  8 octets
-		+--------------------+
-		| Key ID or Reserved |	8 octets
-		+--------------------+
-		| Key MIC			 |	16 octets
-		+--------------------+
-		| Key Data Length	 |	2 octets
-		+--------------------+
-		| Key Data			 |	n octets
-		+--------------------+
-
-	Arguments:
-		pAd			Pointer	to our adapter
-
-	Return Value:
-		None
-
-	Note:
-
-	========================================================================
-*/
-void ConstructEapolMsg(struct rt_mac_table_entry *pEntry,
-		       u8 GroupKeyWepStatus,
-		       u8 MsgType,
-		       u8 DefaultKeyIdx,
-		       u8 * KeyNonce,
-		       u8 * TxRSC,
-		       u8 * GTK,
-		       u8 * RSNIE,
-		       u8 RSNIE_Len, struct rt_eapol_packet * pMsg)
-{
-	BOOLEAN bWPA2 = FALSE;
-	u8 KeyDescVer;
-
-	/* Choose WPA2 or not */
-	if ((pEntry->AuthMode == Ndis802_11AuthModeWPA2) ||
-	    (pEntry->AuthMode == Ndis802_11AuthModeWPA2PSK))
-		bWPA2 = TRUE;
-
-	/* Init Packet and Fill header */
-	pMsg->ProVer = EAPOL_VER;
-	pMsg->ProType = EAPOLKey;
-
-	/* Default 95 bytes, the EAPoL-Key descriptor exclude Key-data field */
-	SET_u16_TO_ARRARY(pMsg->Body_Len, LEN_EAPOL_KEY_MSG);
-
-	/* Fill in EAPoL descriptor */
-	if (bWPA2)
-		pMsg->KeyDesc.Type = WPA2_KEY_DESC;
-	else
-		pMsg->KeyDesc.Type = WPA1_KEY_DESC;
-
-	/* Key Descriptor Version (bits 0-2) specifies the key descriptor version type */
-	{
-		/* Fill in Key information, refer to IEEE Std 802.11i-2004 page 78 */
-		/* When either the pairwise or the group cipher is AES, the DESC_TYPE_AES(2) shall be used. */
-		KeyDescVer =
-		    (((pEntry->WepStatus == Ndis802_11Encryption3Enabled)
-		      || (GroupKeyWepStatus ==
-			  Ndis802_11Encryption3Enabled)) ? (DESC_TYPE_AES)
-		     : (DESC_TYPE_TKIP));
-	}
-
-	pMsg->KeyDesc.KeyInfo.KeyDescVer = KeyDescVer;
-
-	/* Specify Key Type as Group(0) or Pairwise(1) */
-	if (MsgType >= EAPOL_GROUP_MSG_1)
-		pMsg->KeyDesc.KeyInfo.KeyType = GROUPKEY;
-	else
-		pMsg->KeyDesc.KeyInfo.KeyType = PAIRWISEKEY;
-
-	/* Specify Key Index, only group_msg1_WPA1 */
-	if (!bWPA2 && (MsgType >= EAPOL_GROUP_MSG_1))
-		pMsg->KeyDesc.KeyInfo.KeyIndex = DefaultKeyIdx;
-
-	if (MsgType == EAPOL_PAIR_MSG_3)
-		pMsg->KeyDesc.KeyInfo.Install = 1;
-
-	if ((MsgType == EAPOL_PAIR_MSG_1) || (MsgType == EAPOL_PAIR_MSG_3)
-	    || (MsgType == EAPOL_GROUP_MSG_1))
-		pMsg->KeyDesc.KeyInfo.KeyAck = 1;
-
-	if (MsgType != EAPOL_PAIR_MSG_1)
-		pMsg->KeyDesc.KeyInfo.KeyMic = 1;
-
-	if ((bWPA2 && (MsgType >= EAPOL_PAIR_MSG_3)) ||
-	    (!bWPA2 && (MsgType >= EAPOL_GROUP_MSG_1))) {
-		pMsg->KeyDesc.KeyInfo.Secure = 1;
-	}
-
-	if (bWPA2 && ((MsgType == EAPOL_PAIR_MSG_3) ||
-		      (MsgType == EAPOL_GROUP_MSG_1))) {
-		pMsg->KeyDesc.KeyInfo.EKD_DL = 1;
-	}
-	/* key Information element has done. */
-	*(u16 *) (&pMsg->KeyDesc.KeyInfo) =
-	    cpu2le16(*(u16 *) (&pMsg->KeyDesc.KeyInfo));
-
-	/* Fill in Key Length */
-	{
-		if (MsgType >= EAPOL_GROUP_MSG_1) {
-			/* the length of group key cipher */
-			pMsg->KeyDesc.KeyLength[1] =
-			    ((GroupKeyWepStatus ==
-			      Ndis802_11Encryption2Enabled) ? TKIP_GTK_LENGTH :
-			     LEN_AES_KEY);
-		} else {
-			/* the length of pairwise key cipher */
-			pMsg->KeyDesc.KeyLength[1] =
-			    ((pEntry->WepStatus ==
-			      Ndis802_11Encryption2Enabled) ? LEN_TKIP_KEY :
-			     LEN_AES_KEY);
-		}
-	}
-
-	/* Fill in replay counter */
-	NdisMoveMemory(pMsg->KeyDesc.ReplayCounter, pEntry->R_Counter,
-		       LEN_KEY_DESC_REPLAY);
-
-	/* Fill Key Nonce field */
-	/* ANonce : pairwise_msg1 & pairwise_msg3 */
-	/* SNonce : pairwise_msg2 */
-	/* GNonce : group_msg1_wpa1 */
-	if ((MsgType <= EAPOL_PAIR_MSG_3)
-	    || ((!bWPA2 && (MsgType == EAPOL_GROUP_MSG_1))))
-		NdisMoveMemory(pMsg->KeyDesc.KeyNonce, KeyNonce,
-			       LEN_KEY_DESC_NONCE);
-
-	/* Fill key IV - WPA2 as 0, WPA1 as random */
-	if (!bWPA2 && (MsgType == EAPOL_GROUP_MSG_1)) {
-		/* Suggest IV be random number plus some number, */
-		NdisMoveMemory(pMsg->KeyDesc.KeyIv, &KeyNonce[16],
-			       LEN_KEY_DESC_IV);
-		pMsg->KeyDesc.KeyIv[15] += 2;
-	}
-	/* Fill Key RSC field */
-	/* It contains the RSC for the GTK being installed. */
-	if ((MsgType == EAPOL_PAIR_MSG_3 && bWPA2)
-	    || (MsgType == EAPOL_GROUP_MSG_1)) {
-		NdisMoveMemory(pMsg->KeyDesc.KeyRsc, TxRSC, 6);
-	}
-	/* Clear Key MIC field for MIC calculation later */
-	NdisZeroMemory(pMsg->KeyDesc.KeyMic, LEN_KEY_DESC_MIC);
-
-	ConstructEapolKeyData(pEntry,
-			      GroupKeyWepStatus,
-			      KeyDescVer,
-			      MsgType,
-			      DefaultKeyIdx, GTK, RSNIE, RSNIE_Len, pMsg);
-
-	/* Calculate MIC and fill in KeyMic Field except Pairwise Msg 1. */
-	if (MsgType != EAPOL_PAIR_MSG_1) {
-		CalculateMIC(KeyDescVer, pEntry->PTK, pMsg);
-	}
-
-	DBGPRINT(RT_DEBUG_TRACE,
-		 ("===> ConstructEapolMsg for %s %s\n",
-		  ((bWPA2) ? "WPA2" : "WPA"), GetEapolMsgType(MsgType)));
-	DBGPRINT(RT_DEBUG_TRACE,
-		 ("	     Body length = %d \n",
-		  CONV_ARRARY_TO_u16(pMsg->Body_Len)));
-	DBGPRINT(RT_DEBUG_TRACE,
-		 ("	     Key length  = %d \n",
-		  CONV_ARRARY_TO_u16(pMsg->KeyDesc.KeyLength)));
-
-}
-
-/*
-	========================================================================
-
-	Routine Description:
-		Construct the Key Data field of EAPoL message
-
-	Arguments:
-		pAd			Pointer	to our adapter
-		Elem		Message body
-
-	Return Value:
-		None
-
-	Note:
-
-	========================================================================
-*/
-void ConstructEapolKeyData(struct rt_mac_table_entry *pEntry,
-			   u8 GroupKeyWepStatus,
-			   u8 keyDescVer,
-			   u8 MsgType,
-			   u8 DefaultKeyIdx,
-			   u8 * GTK,
-			   u8 * RSNIE,
-			   u8 RSNIE_LEN, struct rt_eapol_packet * pMsg)
-{
-	u8 *mpool, *Key_Data, *Rc4GTK;
-	u8 ekey[(LEN_KEY_DESC_IV + LEN_EAP_EK)];
-	unsigned long data_offset;
-	BOOLEAN bWPA2Capable = FALSE;
-	struct rt_rtmp_adapter *pAd = pEntry->pAd;
-	BOOLEAN GTK_Included = FALSE;
-
-	/* Choose WPA2 or not */
-	if ((pEntry->AuthMode == Ndis802_11AuthModeWPA2) ||
-	    (pEntry->AuthMode == Ndis802_11AuthModeWPA2PSK))
-		bWPA2Capable = TRUE;
-
-	if (MsgType == EAPOL_PAIR_MSG_1 ||
-	    MsgType == EAPOL_PAIR_MSG_4 || MsgType == EAPOL_GROUP_MSG_2)
-		return;
-
-	/* allocate memory pool */
-	os_alloc_mem(NULL, (u8 **) & mpool, 1500);
-
-	if (mpool == NULL)
-		return;
-
-	/* Rc4GTK Len = 512 */
-	Rc4GTK = (u8 *) ROUND_UP(mpool, 4);
-	/* Key_Data Len = 512 */
-	Key_Data = (u8 *) ROUND_UP(Rc4GTK + 512, 4);
-
-	NdisZeroMemory(Key_Data, 512);
-	SET_u16_TO_ARRARY(pMsg->KeyDesc.KeyDataLen, 0);
-	data_offset = 0;
-
-	/* Encapsulate RSNIE in pairwise_msg2 & pairwise_msg3 */
-	if (RSNIE_LEN
-	    && ((MsgType == EAPOL_PAIR_MSG_2)
-		|| (MsgType == EAPOL_PAIR_MSG_3))) {
-		u8 *pmkid_ptr = NULL;
-		u8 pmkid_len = 0;
-
-		RTMPInsertRSNIE(&Key_Data[data_offset],
-				&data_offset,
-				RSNIE, RSNIE_LEN, pmkid_ptr, pmkid_len);
-	}
-
-	/* Encapsulate KDE format in pairwise_msg3_WPA2 & group_msg1_WPA2 */
-	if (bWPA2Capable
-	    && ((MsgType == EAPOL_PAIR_MSG_3)
-		|| (MsgType == EAPOL_GROUP_MSG_1))) {
-		/* Key Data Encapsulation (KDE) format - 802.11i-2004  Figure-43w and Table-20h */
-		Key_Data[data_offset + 0] = 0xDD;
-
-		if (GroupKeyWepStatus == Ndis802_11Encryption3Enabled) {
-			Key_Data[data_offset + 1] = 0x16;	/* 4+2+16(OUI+DataType+DataField) */
-		} else {
-			Key_Data[data_offset + 1] = 0x26;	/* 4+2+32(OUI+DataType+DataField) */
-		}
-
-		Key_Data[data_offset + 2] = 0x00;
-		Key_Data[data_offset + 3] = 0x0F;
-		Key_Data[data_offset + 4] = 0xAC;
-		Key_Data[data_offset + 5] = 0x01;
-
-		/* GTK KDE format - 802.11i-2004  Figure-43x */
-		Key_Data[data_offset + 6] = (DefaultKeyIdx & 0x03);
-		Key_Data[data_offset + 7] = 0x00;	/* Reserved Byte */
-
-		data_offset += 8;
-	}
-
-	/* Encapsulate GTK */
-	/* Only for pairwise_msg3_WPA2 and group_msg1 */
-	if ((MsgType == EAPOL_PAIR_MSG_3 && bWPA2Capable)
-	    || (MsgType == EAPOL_GROUP_MSG_1)) {
-		/* Fill in GTK */
-		if (GroupKeyWepStatus == Ndis802_11Encryption3Enabled) {
-			NdisMoveMemory(&Key_Data[data_offset], GTK,
-				       LEN_AES_KEY);
-			data_offset += LEN_AES_KEY;
-		} else {
-			NdisMoveMemory(&Key_Data[data_offset], GTK,
-				       TKIP_GTK_LENGTH);
-			data_offset += TKIP_GTK_LENGTH;
-		}
-
-		GTK_Included = TRUE;
-	}
-
-	/* This whole key-data field shall be encrypted if a GTK is included. */
-	/* Encrypt the data material in key data field with KEK */
-	if (GTK_Included) {
-		/*hex_dump("GTK_Included", Key_Data, data_offset); */
-
-		if ((keyDescVer == DESC_TYPE_AES)) {
-			u8 remainder = 0;
-			u8 pad_len = 0;
-
-			/* Key Descriptor Version 2 or 3: AES key wrap, defined in IETF RFC 3394, */
-			/* shall be used to encrypt the Key Data field using the KEK field from */
-			/* the derived PTK. */
-
-			/* If the Key Data field uses the NIST AES key wrap, then the Key Data field */
-			/* shall be padded before encrypting if the key data length is less than 16 */
-			/* octets or if it is not a multiple of 8. The padding consists of appending */
-			/* a single octet 0xdd followed by zero or more 0x00 octets. */
-			if ((remainder = data_offset & 0x07) != 0) {
-				int i;
-
-				pad_len = (8 - remainder);
-				Key_Data[data_offset] = 0xDD;
-				for (i = 1; i < pad_len; i++)
-					Key_Data[data_offset + i] = 0;
-
-				data_offset += pad_len;
-			}
-
-			AES_GTK_KEY_WRAP(&pEntry->PTK[16], Key_Data,
-					 data_offset, Rc4GTK);
-			/* AES wrap function will grow 8 bytes in length */
-			data_offset += 8;
-		} else {
-			/*      Key Descriptor Version 1: ARC4 is used to encrypt the Key Data field
-			   using the KEK field from the derived PTK. */
-
-			/* PREPARE Encrypted  "Key DATA" field.  (Encrypt GTK with RC4, usinf PTK[16]->[31] as Key, IV-field as IV) */
-			/* put TxTsc in Key RSC field */
-			pAd->PrivateInfo.FCSCRC32 = PPPINITFCS32;	/*Init crc32. */
-
-			/* ekey is the contanetion of IV-field, and PTK[16]->PTK[31] */
-			NdisMoveMemory(ekey, pMsg->KeyDesc.KeyIv,
-				       LEN_KEY_DESC_IV);
-			NdisMoveMemory(&ekey[LEN_KEY_DESC_IV], &pEntry->PTK[16],
-				       LEN_EAP_EK);
-			ARCFOUR_INIT(&pAd->PrivateInfo.WEPCONTEXT, ekey, sizeof(ekey));	/*INIT SBOX, KEYLEN+3(IV) */
-			pAd->PrivateInfo.FCSCRC32 =
-			    RTMP_CALC_FCS32(pAd->PrivateInfo.FCSCRC32, Key_Data,
-					    data_offset);
-			WPAARCFOUR_ENCRYPT(&pAd->PrivateInfo.WEPCONTEXT, Rc4GTK,
-					   Key_Data, data_offset);
-		}
-
-		NdisMoveMemory(pMsg->KeyDesc.KeyData, Rc4GTK, data_offset);
-	} else {
-		NdisMoveMemory(pMsg->KeyDesc.KeyData, Key_Data, data_offset);
-	}
-
-	/* Update key data length field and total body length */
-	SET_u16_TO_ARRARY(pMsg->KeyDesc.KeyDataLen, data_offset);
-	INC_u16_TO_ARRARY(pMsg->Body_Len, data_offset);
-
-	os_free_mem(NULL, mpool);
-
-}
-
-/*
-	========================================================================
-
-	Routine Description:
-		Calcaulate MIC. It is used during 4-ways handsharking.
-
-	Arguments:
-		pAd			-	pointer to our pAdapter context
-	PeerWepStatus	-	indicate the encryption type
-
-	Return Value:
-
-	Note:
-
-	========================================================================
-*/
-static void CalculateMIC(u8 KeyDescVer,
-			 u8 * PTK, struct rt_eapol_packet * pMsg)
-{
-	u8 *OutBuffer;
-	unsigned long FrameLen = 0;
-	u8 mic[LEN_KEY_DESC_MIC];
-	u8 digest[80];
-
-	/* allocate memory for MIC calculation */
-	os_alloc_mem(NULL, (u8 **) & OutBuffer, 512);
-
-	if (OutBuffer == NULL) {
-		DBGPRINT(RT_DEBUG_ERROR, ("CalculateMIC: no memory!\n"));
-		return;
-	}
-	/* make a frame for calculating MIC. */
-	MakeOutgoingFrame(OutBuffer, &FrameLen,
-			  CONV_ARRARY_TO_u16(pMsg->Body_Len) + 4, pMsg,
-			  END_OF_ARGS);
-
-	NdisZeroMemory(mic, sizeof(mic));
-
-	/* Calculate MIC */
-	if (KeyDescVer == DESC_TYPE_AES) {
-		HMAC_SHA1(PTK, LEN_EAP_MICK, OutBuffer, FrameLen, digest,
-			  SHA1_DIGEST_SIZE);
-		NdisMoveMemory(mic, digest, LEN_KEY_DESC_MIC);
-	} else {
-		HMAC_MD5(PTK, LEN_EAP_MICK, OutBuffer, FrameLen, mic,
-			 MD5_DIGEST_SIZE);
-	}
-
-	/* store the calculated MIC */
-	NdisMoveMemory(pMsg->KeyDesc.KeyMic, mic, LEN_KEY_DESC_MIC);
-
-	os_free_mem(NULL, OutBuffer);
-}
-
-/*
-	========================================================================
-
-	Routine Description:
-		Some received frames can't decrypt by Asic, so decrypt them by software.
-
-	Arguments:
-		pAd			-	pointer to our pAdapter context
-	PeerWepStatus	-	indicate the encryption type
-
-	Return Value:
-		NDIS_STATUS_SUCCESS		-	decryption successful
-		NDIS_STATUS_FAILURE		-	decryption failure
-
-	========================================================================
-*/
-int RTMPSoftDecryptBroadCastData(struct rt_rtmp_adapter *pAd,
-					 struct rt_rx_blk *pRxBlk,
-					 IN NDIS_802_11_ENCRYPTION_STATUS
-					 GroupCipher, struct rt_cipher_key *pShard_key)
-{
-	struct rt_rxwi * pRxWI = pRxBlk->pRxWI;
-
-	/* handle WEP decryption */
-	if (GroupCipher == Ndis802_11Encryption1Enabled) {
-		if (RTMPSoftDecryptWEP
-		    (pAd, pRxBlk->pData, pRxWI->MPDUtotalByteCount,
-		     pShard_key)) {
-
-			/*Minus IV[4] & ICV[4] */
-			pRxWI->MPDUtotalByteCount -= 8;
-		} else {
-			DBGPRINT(RT_DEBUG_ERROR,
-				 ("ERROR : Software decrypt WEP data fails.\n"));
-			/* give up this frame */
-			return NDIS_STATUS_FAILURE;
-		}
-	}
-	/* handle TKIP decryption */
-	else if (GroupCipher == Ndis802_11Encryption2Enabled) {
-		if (RTMPSoftDecryptTKIP
-		    (pAd, pRxBlk->pData, pRxWI->MPDUtotalByteCount, 0,
-		     pShard_key)) {
-
-			/*Minus 8 bytes MIC, 8 bytes IV/EIV, 4 bytes ICV */
-			pRxWI->MPDUtotalByteCount -= 20;
-		} else {
-			DBGPRINT(RT_DEBUG_ERROR,
-				 ("ERROR : RTMPSoftDecryptTKIP Failed\n"));
-			/* give up this frame */
-			return NDIS_STATUS_FAILURE;
-		}
-	}
-	/* handle AES decryption */
-	else if (GroupCipher == Ndis802_11Encryption3Enabled) {
-		if (RTMPSoftDecryptAES
-		    (pAd, pRxBlk->pData, pRxWI->MPDUtotalByteCount,
-		     pShard_key)) {
-
-			/*8 bytes MIC, 8 bytes IV/EIV (CCMP Header) */
-			pRxWI->MPDUtotalByteCount -= 16;
-		} else {
-			DBGPRINT(RT_DEBUG_ERROR,
-				 ("ERROR : RTMPSoftDecryptAES Failed\n"));
-			/* give up this frame */
-			return NDIS_STATUS_FAILURE;
-		}
-	} else {
-		/* give up this frame */
-		return NDIS_STATUS_FAILURE;
-	}
-
-	return NDIS_STATUS_SUCCESS;
-
-}
-
-u8 *GetSuiteFromRSNIE(u8 *rsnie,
-			 u32 rsnie_len, u8 type, u8 * count)
-{
-	struct rt_eid * pEid;
-	int len;
-	u8 *pBuf;
-	int offset = 0;
-	struct rt_rsnie_auth *pAkm;
-	u16 acount;
-	BOOLEAN isWPA2 = FALSE;
-
-	pEid = (struct rt_eid *) rsnie;
-	len = rsnie_len - 2;	/* exclude IE and length */
-	pBuf = (u8 *)& pEid->Octet[0];
-
-	/* set default value */
-	*count = 0;
-
-	/* Check length */
-	if ((len <= 0) || (pEid->Len != len)) {
-		DBGPRINT_ERR("%s : The length is invalid\n", __func__);
-		return NULL;
-	}
-	/* Check WPA or WPA2 */
-	if (pEid->Eid == IE_WPA) {
-		struct rt_rsnie *pRsnie = (struct rt_rsnie *)pBuf;
-		u16 ucount;
-
-		if (len < sizeof(struct rt_rsnie)) {
-			DBGPRINT_ERR("%s : The length is too short for WPA\n", __func__);
-			return NULL;
-		}
-		/* Get the count of pairwise cipher */
-		ucount = cpu2le16(pRsnie->ucount);
-		if (ucount > 2) {
-			DBGPRINT_ERR("%s : The count(%d) of pairwise cipher is invlaid\n", __func__, ucount);
-			return NULL;
-		}
-		/* Get the group cipher */
-		if (type == GROUP_SUITE) {
-			*count = 1;
-			return pRsnie->mcast;
-		}
-		/* Get the pairwise cipher suite */
-		else if (type == PAIRWISE_SUITE) {
-			DBGPRINT(RT_DEBUG_TRACE,
-				 ("%s : The count of pairwise cipher is %d\n",
-				  __func__, ucount));
-			*count = ucount;
-			return pRsnie->ucast[0].oui;
-		}
-
-		offset = sizeof(struct rt_rsnie) + (4 * (ucount - 1));
-
-	} else if (pEid->Eid == IE_RSN) {
-		struct rt_rsnie2 *pRsnie = (struct rt_rsnie2 *)pBuf;
-		u16 ucount;
-
-		isWPA2 = TRUE;
-
-		if (len < sizeof(struct rt_rsnie2)) {
-			DBGPRINT_ERR("%s : The length is too short for WPA2\n", __func__);
-			return NULL;
-		}
-		/* Get the count of pairwise cipher */
-		ucount = cpu2le16(pRsnie->ucount);
-		if (ucount > 2) {
-			DBGPRINT_ERR("%s : The count(%d) of pairwise cipher is invlaid\n", __func__, ucount);
-			return NULL;
-		}
-		/* Get the group cipher */
-		if (type == GROUP_SUITE) {
-			*count = 1;
-			return pRsnie->mcast;
-		}
-		/* Get the pairwise cipher suite */
-		else if (type == PAIRWISE_SUITE) {
-			DBGPRINT(RT_DEBUG_TRACE,
-				 ("%s : The count of pairwise cipher is %d\n",
-				  __func__, ucount));
-			*count = ucount;
-			return pRsnie->ucast[0].oui;
-		}
-
-		offset = sizeof(struct rt_rsnie2) + (4 * (ucount - 1));
-
-	} else {
-		DBGPRINT_ERR("%s : Unknown IE (%d)\n", __func__, pEid->Eid);
-		return NULL;
-	}
-
-	/* skip group cipher and pairwise cipher suite */
-	pBuf += offset;
-	len -= offset;
-
-	if (len < sizeof(struct rt_rsnie_auth)) {
-		DBGPRINT_ERR("%s : The length of RSNIE is too short\n", __func__);
-		return NULL;
-	}
-	/* pointer to AKM count */
-	pAkm = (struct rt_rsnie_auth *)pBuf;
-
-	/* Get the count of pairwise cipher */
-	acount = cpu2le16(pAkm->acount);
-	if (acount > 2) {
-		DBGPRINT_ERR("%s : The count(%d) of AKM is invlaid\n", __func__, acount);
-		return NULL;
-	}
-	/* Get the AKM suite */
-	if (type == AKM_SUITE) {
-		DBGPRINT(RT_DEBUG_TRACE, ("%s : The count of AKM is %d\n",
-					  __func__, acount));
-		*count = acount;
-		return pAkm->auth[0].oui;
-	}
-	offset = sizeof(struct rt_rsnie_auth) + (4 * (acount - 1));
-
-	pBuf += offset;
-	len -= offset;
-
-	/* The remaining length must larger than (RSN-Capability(2) + PMKID-Count(2) + PMKID(16~)) */
-	if (len >= (sizeof(RSN_CAPABILITIES) + 2 + LEN_PMKID)) {
-		/* Skip RSN capability and PMKID-Count */
-		pBuf += (sizeof(RSN_CAPABILITIES) + 2);
-		len -= (sizeof(RSN_CAPABILITIES) + 2);
-
-		/* Get PMKID */
-		if (type == PMKID_LIST) {
-			*count = 1;
-			return pBuf;
-		}
-	} else {
-		DBGPRINT_ERR("%s : it can't get any more information beyond AKM \n", __func__);
-		return NULL;
-	}
-
-	*count = 0;
-	/*DBGPRINT_ERR(("%s : The type(%d) doesn't support \n", __func__, type)); */
-	return NULL;
-
-}
-
-void WpaShowAllsuite(u8 *rsnie, u32 rsnie_len)
-{
-	u8 *pSuite = NULL;
-	u8 count;
-
-	hex_dump("RSNIE", rsnie, rsnie_len);
-
-	/* group cipher */
-	pSuite = GetSuiteFromRSNIE(rsnie, rsnie_len, GROUP_SUITE, &count);
-	if (pSuite != NULL) {
-		hex_dump("group cipher", pSuite, 4 * count);
-	}
-	/* pairwise cipher */
-	pSuite = GetSuiteFromRSNIE(rsnie, rsnie_len, PAIRWISE_SUITE, &count);
-	if (pSuite != NULL) {
-		hex_dump("pairwise cipher", pSuite, 4 * count);
-	}
-	/* AKM */
-	pSuite = GetSuiteFromRSNIE(rsnie, rsnie_len, AKM_SUITE, &count);
-	if (pSuite != NULL) {
-		hex_dump("AKM suite", pSuite, 4 * count);
-	}
-	/* PMKID */
-	pSuite = GetSuiteFromRSNIE(rsnie, rsnie_len, PMKID_LIST, &count);
-	if (pSuite != NULL) {
-		hex_dump("PMKID", pSuite, LEN_PMKID);
-	}
-
-}
-
-void RTMPInsertRSNIE(u8 *pFrameBuf,
-		     unsigned long *pFrameLen,
-		     u8 *rsnie_ptr,
-		     u8 rsnie_len,
-		     u8 *pmkid_ptr, u8 pmkid_len)
-{
-	u8 *pTmpBuf;
-	unsigned long TempLen = 0;
-	u8 extra_len = 0;
-	u16 pmk_count = 0;
-	u8 ie_num;
-	u8 total_len = 0;
-	u8 WPA2_OUI[3] = { 0x00, 0x0F, 0xAC };
-
-	pTmpBuf = pFrameBuf;
-
-	/* PMKID-List Must larger than 0 and the multiple of 16. */
-	if (pmkid_len > 0 && ((pmkid_len & 0x0f) == 0)) {
-		extra_len = sizeof(u16)+ pmkid_len;
-
-		pmk_count = (pmkid_len >> 4);
-		pmk_count = cpu2le16(pmk_count);
-	} else {
-		DBGPRINT(RT_DEBUG_WARN,
-			 ("%s : The length is PMKID-List is invalid (%d), so don't insert it.\n",
-			  __func__, pmkid_len));
-	}
-
-	if (rsnie_len != 0) {
-		ie_num = IE_WPA;
-		total_len = rsnie_len;
-
-		if (NdisEqualMemory(rsnie_ptr + 2, WPA2_OUI, sizeof(WPA2_OUI))) {
-			ie_num = IE_RSN;
-			total_len += extra_len;
-		}
-
-		/* construct RSNIE body */
-		MakeOutgoingFrame(pTmpBuf, &TempLen,
-				  1, &ie_num,
-				  1, &total_len,
-				  rsnie_len, rsnie_ptr, END_OF_ARGS);
-
-		pTmpBuf += TempLen;
-		*pFrameLen = *pFrameLen + TempLen;
-
-		if (ie_num == IE_RSN) {
-			/* Insert PMKID-List field */
-			if (extra_len > 0) {
-				MakeOutgoingFrame(pTmpBuf, &TempLen,
-						  2, &pmk_count,
-						  pmkid_len, pmkid_ptr,
-						  END_OF_ARGS);
-
-				pTmpBuf += TempLen;
-				*pFrameLen = *pFrameLen + TempLen;
-			}
-		}
-	}
-
-	return;
-}
diff -druN linux-2.6.39-libre/drivers/staging/rt2860/common/crypt_hmac.c linux-3.0-rc7-libre/drivers/staging/rt2860/common/crypt_hmac.c
--- linux-2.6.39-libre/drivers/staging/rt2860/common/crypt_hmac.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rt2860/common/crypt_hmac.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,187 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, Inc.
- *
- * This program is free software; you can redistribute it and/or modify  *
- * it under the terms of the GNU General Public License as published by  *
- * the Free Software Foundation; either version 2 of the License, or     *
- * (at your option) any later version.                                   *
- *                                                                       *
- * This program is distributed in the hope that it will be useful,       *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of        *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
- * GNU General Public License for more details.                          *
- *                                                                       *
- * You should have received a copy of the GNU General Public License     *
- * along with this program; if not, write to the                         *
- * Free Software Foundation, Inc.,                                       *
- * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
- *                                                                       *
- *************************************************************************/
-
-#include "../crypt_hmac.h"
-
-#ifdef HMAC_SHA1_SUPPORT
-/*
-========================================================================
-Routine Description:
-    HMAC using SHA1 hash function
-
-Arguments:
-    key             Secret key
-    key_len         The length of the key in bytes
-    message         Message context
-    message_len     The length of message in bytes
-    macLen          Request the length of message authentication code
-
-Return Value:
-    mac             Message authentication code
-
-Note:
-    None
-========================================================================
-*/
-void HMAC_SHA1(IN const u8 Key[],
-	       u32 KeyLen,
-	       IN const u8 Message[],
-	       u32 MessageLen, u8 MAC[], u32 MACLen)
-{
-	struct rt_sha1_ctx sha_ctx1;
-	struct rt_sha1_ctx sha_ctx2;
-	u8 K0[SHA1_BLOCK_SIZE];
-	u8 Digest[SHA1_DIGEST_SIZE];
-	u32 index;
-
-	NdisZeroMemory(&sha_ctx1, sizeof(struct rt_sha1_ctx));
-	NdisZeroMemory(&sha_ctx2, sizeof(struct rt_sha1_ctx));
-	/*
-	 * If the length of K = B(Block size): K0 = K.
-	 * If the length of K > B: hash K to obtain an L byte string,
-	 * then append (B-L) zeros to create a B-byte string K0 (i.e., K0 = H(K) || 00...00).
-	 * If the length of K < B: append zeros to the end of K to create a B-byte string K0
-	 */
-	NdisZeroMemory(K0, SHA1_BLOCK_SIZE);
-	if (KeyLen <= SHA1_BLOCK_SIZE)
-		NdisMoveMemory(K0, Key, KeyLen);
-	else
-		RT_SHA1(Key, KeyLen, K0);
-	/* End of if */
-
-	/* Exclusive-Or K0 with ipad */
-	/* ipad: Inner pad; the byte x¡¦36¡¦ repeated B times. */
-	for (index = 0; index < SHA1_BLOCK_SIZE; index++)
-		K0[index] ^= 0x36;
-	/* End of for */
-
-	RT_SHA1_Init(&sha_ctx1);
-	/* H(K0^ipad) */
-	SHA1_Append(&sha_ctx1, K0, sizeof(K0));
-	/* H((K0^ipad)||text) */
-	SHA1_Append(&sha_ctx1, Message, MessageLen);
-	SHA1_End(&sha_ctx1, Digest);
-
-	/* Exclusive-Or K0 with opad and remove ipad */
-	/* opad: Outer pad; the byte x¡¦5c¡¦ repeated B times. */
-	for (index = 0; index < SHA1_BLOCK_SIZE; index++)
-		K0[index] ^= 0x36 ^ 0x5c;
-	/* End of for */
-
-	RT_SHA1_Init(&sha_ctx2);
-	/* H(K0^opad) */
-	SHA1_Append(&sha_ctx2, K0, sizeof(K0));
-	/* H( (K0^opad) || H((K0^ipad)||text) ) */
-	SHA1_Append(&sha_ctx2, Digest, SHA1_DIGEST_SIZE);
-	SHA1_End(&sha_ctx2, Digest);
-
-	if (MACLen > SHA1_DIGEST_SIZE)
-		NdisMoveMemory(MAC, Digest, SHA1_DIGEST_SIZE);
-	else
-		NdisMoveMemory(MAC, Digest, MACLen);
-}				/* End of HMAC_SHA1 */
-#endif /* HMAC_SHA1_SUPPORT */
-
-#ifdef HMAC_MD5_SUPPORT
-/*
-========================================================================
-Routine Description:
-    HMAC using MD5 hash function
-
-Arguments:
-    key             Secret key
-    key_len         The length of the key in bytes
-    message         Message context
-    message_len     The length of message in bytes
-    macLen          Request the length of message authentication code
-
-Return Value:
-    mac             Message authentication code
-
-Note:
-    None
-========================================================================
-*/
-void HMAC_MD5(IN const u8 Key[],
-	      u32 KeyLen,
-	      IN const u8 Message[],
-	      u32 MessageLen, u8 MAC[], u32 MACLen)
-{
-	struct rt_md5_ctx_struc md5_ctx1;
-	struct rt_md5_ctx_struc md5_ctx2;
-	u8 K0[MD5_BLOCK_SIZE];
-	u8 Digest[MD5_DIGEST_SIZE];
-	u32 index;
-
-	NdisZeroMemory(&md5_ctx1, sizeof(struct rt_md5_ctx_struc));
-	NdisZeroMemory(&md5_ctx2, sizeof(struct rt_md5_ctx_struc));
-	/*
-	 * If the length of K = B(Block size): K0 = K.
-	 * If the length of K > B: hash K to obtain an L byte string,
-	 * then append (B-L) zeros to create a B-byte string K0 (i.e., K0 = H(K) || 00...00).
-	 * If the length of K < B: append zeros to the end of K to create a B-byte string K0
-	 */
-	NdisZeroMemory(K0, MD5_BLOCK_SIZE);
-	if (KeyLen <= MD5_BLOCK_SIZE) {
-		NdisMoveMemory(K0, Key, KeyLen);
-	} else {
-		RT_MD5(Key, KeyLen, K0);
-	}
-
-	/* Exclusive-Or K0 with ipad */
-	/* ipad: Inner pad; the byte x¡¦36¡¦ repeated B times. */
-	for (index = 0; index < MD5_BLOCK_SIZE; index++)
-		K0[index] ^= 0x36;
-	/* End of for */
-
-	MD5_Init(&md5_ctx1);
-	/* H(K0^ipad) */
-	MD5_Append(&md5_ctx1, K0, sizeof(K0));
-	/* H((K0^ipad)||text) */
-	MD5_Append(&md5_ctx1, Message, MessageLen);
-	MD5_End(&md5_ctx1, Digest);
-
-	/* Exclusive-Or K0 with opad and remove ipad */
-	/* opad: Outer pad; the byte x¡¦5c¡¦ repeated B times. */
-	for (index = 0; index < MD5_BLOCK_SIZE; index++)
-		K0[index] ^= 0x36 ^ 0x5c;
-	/* End of for */
-
-	MD5_Init(&md5_ctx2);
-	/* H(K0^opad) */
-	MD5_Append(&md5_ctx2, K0, sizeof(K0));
-	/* H( (K0^opad) || H((K0^ipad)||text) ) */
-	MD5_Append(&md5_ctx2, Digest, MD5_DIGEST_SIZE);
-	MD5_End(&md5_ctx2, Digest);
-
-	if (MACLen > MD5_DIGEST_SIZE)
-		NdisMoveMemory(MAC, Digest, MD5_DIGEST_SIZE);
-	else
-		NdisMoveMemory(MAC, Digest, MACLen);
-}				/* End of HMAC_SHA256 */
-#endif /* HMAC_MD5_SUPPORT */
-
-/* End of crypt_hmac.c */
diff -druN linux-2.6.39-libre/drivers/staging/rt2860/common/crypt_md5.c linux-3.0-rc7-libre/drivers/staging/rt2860/common/crypt_md5.c
--- linux-2.6.39-libre/drivers/staging/rt2860/common/crypt_md5.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rt2860/common/crypt_md5.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,339 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, Inc.
- *
- * This program is free software; you can redistribute it and/or modify  *
- * it under the terms of the GNU General Public License as published by  *
- * the Free Software Foundation; either version 2 of the License, or     *
- * (at your option) any later version.                                   *
- *                                                                       *
- * This program is distributed in the hope that it will be useful,       *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of        *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
- * GNU General Public License for more details.                          *
- *                                                                       *
- * You should have received a copy of the GNU General Public License     *
- * along with this program; if not, write to the                         *
- * Free Software Foundation, Inc.,                                       *
- * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
- *                                                                       *
- *************************************************************************/
-
-#include "../crypt_md5.h"
-
-#ifdef MD5_SUPPORT
-/*
- * F, G, H and I are basic MD5 functions.
- */
-#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
-#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
-#define H(x, y, z) ((x) ^ (y) ^ (z))
-#define I(x, y, z) ((y) ^ ((x) | (~z)))
-
-#define ROTL(x,n,w) ((x << n) | (x >> (w - n)))
-#define ROTL32(x,n) ROTL(x,n,32)	/* 32 bits word */
-
-#define ROUND1(a, b, c, d, x, s, ac) {          \
-    (a) += F((b),(c),(d)) + (x) + (u32)(ac); \
-    (a)  = ROTL32((a),(s));                     \
-    (a) += (b);                                 \
-}
-#define ROUND2(a, b, c, d, x, s, ac) {          \
-    (a) += G((b),(c),(d)) + (x) + (u32)(ac); \
-    (a)  = ROTL32((a),(s));                     \
-    (a) += (b);                                 \
-}
-#define ROUND3(a, b, c, d, x, s, ac) {          \
-    (a) += H((b),(c),(d)) + (x) + (u32)(ac); \
-    (a)  = ROTL32((a),(s));                     \
-    (a) += (b);                                 \
-}
-#define ROUND4(a, b, c, d, x, s, ac) {          \
-    (a) += I((b),(c),(d)) + (x) + (u32)(ac); \
-    (a)  = ROTL32((a),(s));                     \
-    (a) += (b);                                 \
-}
-static const u32 MD5_DefaultHashValue[4] = {
-	0x67452301UL, 0xefcdab89UL, 0x98badcfeUL, 0x10325476UL
-};
-#endif /* MD5_SUPPORT */
-
-#ifdef MD5_SUPPORT
-/*
-========================================================================
-Routine Description:
-    Initial Md5_CTX_STRUC
-
-Arguments:
-    pMD5_CTX        Pointer to Md5_CTX_STRUC
-
-Return Value:
-    None
-
-Note:
-    None
-========================================================================
-*/
-void MD5_Init(struct rt_md5_ctx_struc *pMD5_CTX)
-{
-	NdisMoveMemory(pMD5_CTX->HashValue, MD5_DefaultHashValue,
-		       sizeof(MD5_DefaultHashValue));
-	NdisZeroMemory(pMD5_CTX->Block, MD5_BLOCK_SIZE);
-	pMD5_CTX->BlockLen = 0;
-	pMD5_CTX->MessageLen = 0;
-}				/* End of MD5_Init */
-
-/*
-========================================================================
-Routine Description:
-    MD5 computation for one block (512 bits)
-
-Arguments:
-    pMD5_CTX        Pointer to Md5_CTX_STRUC
-
-Return Value:
-    None
-
-Note:
-    T[i] := floor(abs(sin(i + 1)) * (2 pow 32)), i is number of round
-========================================================================
-*/
-void MD5_Hash(struct rt_md5_ctx_struc *pMD5_CTX)
-{
-	u32 X_i;
-	u32 X[16];
-	u32 a, b, c, d;
-
-	/* Prepare the message schedule, {X_i} */
-	NdisMoveMemory(X, pMD5_CTX->Block, MD5_BLOCK_SIZE);
-	for (X_i = 0; X_i < 16; X_i++)
-		X[X_i] = cpu2le32(X[X_i]);	/* Endian Swap */
-	/* End of for */
-
-	/* MD5 hash computation */
-	/* Initialize the working variables */
-	a = pMD5_CTX->HashValue[0];
-	b = pMD5_CTX->HashValue[1];
-	c = pMD5_CTX->HashValue[2];
-	d = pMD5_CTX->HashValue[3];
-
-	/*
-	 *  Round 1
-	 *  Let [abcd k s i] denote the operation
-	 *  a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s)
-	 */
-	ROUND1(a, b, c, d, X[0], 7, 0xd76aa478);	/* 1 */
-	ROUND1(d, a, b, c, X[1], 12, 0xe8c7b756);	/* 2 */
-	ROUND1(c, d, a, b, X[2], 17, 0x242070db);	/* 3 */
-	ROUND1(b, c, d, a, X[3], 22, 0xc1bdceee);	/* 4 */
-	ROUND1(a, b, c, d, X[4], 7, 0xf57c0faf);	/* 5 */
-	ROUND1(d, a, b, c, X[5], 12, 0x4787c62a);	/* 6 */
-	ROUND1(c, d, a, b, X[6], 17, 0xa8304613);	/* 7 */
-	ROUND1(b, c, d, a, X[7], 22, 0xfd469501);	/* 8 */
-	ROUND1(a, b, c, d, X[8], 7, 0x698098d8);	/* 9 */
-	ROUND1(d, a, b, c, X[9], 12, 0x8b44f7af);	/* 10 */
-	ROUND1(c, d, a, b, X[10], 17, 0xffff5bb1);	/* 11 */
-	ROUND1(b, c, d, a, X[11], 22, 0x895cd7be);	/* 12 */
-	ROUND1(a, b, c, d, X[12], 7, 0x6b901122);	/* 13 */
-	ROUND1(d, a, b, c, X[13], 12, 0xfd987193);	/* 14 */
-	ROUND1(c, d, a, b, X[14], 17, 0xa679438e);	/* 15 */
-	ROUND1(b, c, d, a, X[15], 22, 0x49b40821);	/* 16 */
-
-	/*
-	 *  Round 2
-	 *  Let [abcd k s i] denote the operation
-	 *  a = b + ((a + G(b,c,d) + X[k] + T[i]) <<< s)
-	 */
-	ROUND2(a, b, c, d, X[1], 5, 0xf61e2562);	/* 17 */
-	ROUND2(d, a, b, c, X[6], 9, 0xc040b340);	/* 18 */
-	ROUND2(c, d, a, b, X[11], 14, 0x265e5a51);	/* 19 */
-	ROUND2(b, c, d, a, X[0], 20, 0xe9b6c7aa);	/* 20 */
-	ROUND2(a, b, c, d, X[5], 5, 0xd62f105d);	/* 21 */
-	ROUND2(d, a, b, c, X[10], 9, 0x2441453);	/* 22 */
-	ROUND2(c, d, a, b, X[15], 14, 0xd8a1e681);	/* 23 */
-	ROUND2(b, c, d, a, X[4], 20, 0xe7d3fbc8);	/* 24 */
-	ROUND2(a, b, c, d, X[9], 5, 0x21e1cde6);	/* 25 */
-	ROUND2(d, a, b, c, X[14], 9, 0xc33707d6);	/* 26 */
-	ROUND2(c, d, a, b, X[3], 14, 0xf4d50d87);	/* 27 */
-	ROUND2(b, c, d, a, X[8], 20, 0x455a14ed);	/* 28 */
-	ROUND2(a, b, c, d, X[13], 5, 0xa9e3e905);	/* 29 */
-	ROUND2(d, a, b, c, X[2], 9, 0xfcefa3f8);	/* 30 */
-	ROUND2(c, d, a, b, X[7], 14, 0x676f02d9);	/* 31 */
-	ROUND2(b, c, d, a, X[12], 20, 0x8d2a4c8a);	/* 32 */
-
-	/*
-	 *  Round 3
-	 *  Let [abcd k s t] denote the operation
-	 *  a = b + ((a + H(b,c,d) + X[k] + T[i]) <<< s)
-	 */
-	ROUND3(a, b, c, d, X[5], 4, 0xfffa3942);	/* 33 */
-	ROUND3(d, a, b, c, X[8], 11, 0x8771f681);	/* 34 */
-	ROUND3(c, d, a, b, X[11], 16, 0x6d9d6122);	/* 35 */
-	ROUND3(b, c, d, a, X[14], 23, 0xfde5380c);	/* 36 */
-	ROUND3(a, b, c, d, X[1], 4, 0xa4beea44);	/* 37 */
-	ROUND3(d, a, b, c, X[4], 11, 0x4bdecfa9);	/* 38 */
-	ROUND3(c, d, a, b, X[7], 16, 0xf6bb4b60);	/* 39 */
-	ROUND3(b, c, d, a, X[10], 23, 0xbebfbc70);	/* 40 */
-	ROUND3(a, b, c, d, X[13], 4, 0x289b7ec6);	/* 41 */
-	ROUND3(d, a, b, c, X[0], 11, 0xeaa127fa);	/* 42 */
-	ROUND3(c, d, a, b, X[3], 16, 0xd4ef3085);	/* 43 */
-	ROUND3(b, c, d, a, X[6], 23, 0x4881d05);	/* 44 */
-	ROUND3(a, b, c, d, X[9], 4, 0xd9d4d039);	/* 45 */
-	ROUND3(d, a, b, c, X[12], 11, 0xe6db99e5);	/* 46 */
-	ROUND3(c, d, a, b, X[15], 16, 0x1fa27cf8);	/* 47 */
-	ROUND3(b, c, d, a, X[2], 23, 0xc4ac5665);	/* 48 */
-
-	/*
-	 *  Round 4
-	 *  Let [abcd k s t] denote the operation
-	 *  a = b + ((a + I(b,c,d) + X[k] + T[i]) <<< s)
-	 */
-	ROUND4(a, b, c, d, X[0], 6, 0xf4292244);	/* 49 */
-	ROUND4(d, a, b, c, X[7], 10, 0x432aff97);	/* 50 */
-	ROUND4(c, d, a, b, X[14], 15, 0xab9423a7);	/* 51 */
-	ROUND4(b, c, d, a, X[5], 21, 0xfc93a039);	/* 52 */
-	ROUND4(a, b, c, d, X[12], 6, 0x655b59c3);	/* 53 */
-	ROUND4(d, a, b, c, X[3], 10, 0x8f0ccc92);	/* 54 */
-	ROUND4(c, d, a, b, X[10], 15, 0xffeff47d);	/* 55 */
-	ROUND4(b, c, d, a, X[1], 21, 0x85845dd1);	/* 56 */
-	ROUND4(a, b, c, d, X[8], 6, 0x6fa87e4f);	/* 57 */
-	ROUND4(d, a, b, c, X[15], 10, 0xfe2ce6e0);	/* 58 */
-	ROUND4(c, d, a, b, X[6], 15, 0xa3014314);	/* 59 */
-	ROUND4(b, c, d, a, X[13], 21, 0x4e0811a1);	/* 60 */
-	ROUND4(a, b, c, d, X[4], 6, 0xf7537e82);	/* 61 */
-	ROUND4(d, a, b, c, X[11], 10, 0xbd3af235);	/* 62 */
-	ROUND4(c, d, a, b, X[2], 15, 0x2ad7d2bb);	/* 63 */
-	ROUND4(b, c, d, a, X[9], 21, 0xeb86d391);	/* 64 */
-
-	/* Compute the i^th intermediate hash value H^(i) */
-	pMD5_CTX->HashValue[0] += a;
-	pMD5_CTX->HashValue[1] += b;
-	pMD5_CTX->HashValue[2] += c;
-	pMD5_CTX->HashValue[3] += d;
-
-	NdisZeroMemory(pMD5_CTX->Block, MD5_BLOCK_SIZE);
-	pMD5_CTX->BlockLen = 0;
-}				/* End of MD5_Hash */
-
-/*
-========================================================================
-Routine Description:
-    The message is appended to block. If block size > 64 bytes, the MD5_Hash
-will be called.
-
-Arguments:
-    pMD5_CTX        Pointer to struct rt_md5_ctx_struc
-    message         Message context
-    messageLen      The length of message in bytes
-
-Return Value:
-    None
-
-Note:
-    None
-========================================================================
-*/
-void MD5_Append(struct rt_md5_ctx_struc *pMD5_CTX,
-		IN const u8 Message[], u32 MessageLen)
-{
-	u32 appendLen = 0;
-	u32 diffLen = 0;
-
-	while (appendLen != MessageLen) {
-		diffLen = MessageLen - appendLen;
-		if ((pMD5_CTX->BlockLen + diffLen) < MD5_BLOCK_SIZE) {
-			NdisMoveMemory(pMD5_CTX->Block + pMD5_CTX->BlockLen,
-				       Message + appendLen, diffLen);
-			pMD5_CTX->BlockLen += diffLen;
-			appendLen += diffLen;
-		} else {
-			NdisMoveMemory(pMD5_CTX->Block + pMD5_CTX->BlockLen,
-				       Message + appendLen,
-				       MD5_BLOCK_SIZE - pMD5_CTX->BlockLen);
-			appendLen += (MD5_BLOCK_SIZE - pMD5_CTX->BlockLen);
-			pMD5_CTX->BlockLen = MD5_BLOCK_SIZE;
-			MD5_Hash(pMD5_CTX);
-		}		/* End of if */
-	}			/* End of while */
-	pMD5_CTX->MessageLen += MessageLen;
-}				/* End of MD5_Append */
-
-/*
-========================================================================
-Routine Description:
-    1. Append bit 1 to end of the message
-    2. Append the length of message in rightmost 64 bits
-    3. Transform the Hash Value to digest message
-
-Arguments:
-    pMD5_CTX        Pointer to struct rt_md5_ctx_struc
-
-Return Value:
-    digestMessage   Digest message
-
-Note:
-    None
-========================================================================
-*/
-void MD5_End(struct rt_md5_ctx_struc *pMD5_CTX, u8 DigestMessage[])
-{
-	u32 index;
-	u64 message_length_bits;
-
-	/* append 1 bits to end of the message */
-	NdisFillMemory(pMD5_CTX->Block + pMD5_CTX->BlockLen, 1, 0x80);
-
-	/* 55 = 64 - 8 - 1: append 1 bit(1 byte) and message length (8 bytes) */
-	if (pMD5_CTX->BlockLen > 55)
-		MD5_Hash(pMD5_CTX);
-	/* End of if */
-
-	/* Append the length of message in rightmost 64 bits */
-	message_length_bits = pMD5_CTX->MessageLen * 8;
-	message_length_bits = cpu2le64(message_length_bits);
-	NdisMoveMemory(&pMD5_CTX->Block[56], &message_length_bits, 8);
-	MD5_Hash(pMD5_CTX);
-
-	/* Return message digest, transform the u32 hash value to bytes */
-	for (index = 0; index < 4; index++)
-		pMD5_CTX->HashValue[index] =
-		    cpu2le32(pMD5_CTX->HashValue[index]);
-	/* End of for */
-	NdisMoveMemory(DigestMessage, pMD5_CTX->HashValue, MD5_DIGEST_SIZE);
-}				/* End of MD5_End */
-
-/*
-========================================================================
-Routine Description:
-    MD5 algorithm
-
-Arguments:
-    message         Message context
-    messageLen      The length of message in bytes
-
-Return Value:
-    digestMessage   Digest message
-
-Note:
-    None
-========================================================================
-*/
-void RT_MD5(IN const u8 Message[],
-	    u32 MessageLen, u8 DigestMessage[])
-{
-	struct rt_md5_ctx_struc md5_ctx;
-
-	NdisZeroMemory(&md5_ctx, sizeof(struct rt_md5_ctx_struc));
-	MD5_Init(&md5_ctx);
-	MD5_Append(&md5_ctx, Message, MessageLen);
-	MD5_End(&md5_ctx, DigestMessage);
-}				/* End of RT_MD5 */
-
-#endif /* MD5_SUPPORT */
-
-/* End of crypt_md5.c */
diff -druN linux-2.6.39-libre/drivers/staging/rt2860/common/crypt_sha2.c linux-3.0-rc7-libre/drivers/staging/rt2860/common/crypt_sha2.c
--- linux-2.6.39-libre/drivers/staging/rt2860/common/crypt_sha2.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rt2860/common/crypt_sha2.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,269 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, Inc.
- *
- * This program is free software; you can redistribute it and/or modify  *
- * it under the terms of the GNU General Public License as published by  *
- * the Free Software Foundation; either version 2 of the License, or     *
- * (at your option) any later version.                                   *
- *                                                                       *
- * This program is distributed in the hope that it will be useful,       *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of        *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
- * GNU General Public License for more details.                          *
- *                                                                       *
- * You should have received a copy of the GNU General Public License     *
- * along with this program; if not, write to the                         *
- * Free Software Foundation, Inc.,                                       *
- * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
- *                                                                       *
- *************************************************************************/
-
-#include "../crypt_sha2.h"
-
-/* Basic operations */
-#define SHR(x,n) (x >> n)	/* SHR(x)^n, right shift n bits , x is w-bit word, 0 <= n <= w */
-#define ROTR(x,n,w) ((x >> n) | (x << (w - n)))	/* ROTR(x)^n, circular right shift n bits , x is w-bit word, 0 <= n <= w */
-#define ROTL(x,n,w) ((x << n) | (x >> (w - n)))	/* ROTL(x)^n, circular left shift n bits , x is w-bit word, 0 <= n <= w */
-#define ROTR32(x,n) ROTR(x,n,32)	/* 32 bits word */
-#define ROTL32(x,n) ROTL(x,n,32)	/* 32 bits word */
-
-/* Basic functions */
-#define Ch(x,y,z) ((x & y) ^ ((~x) & z))
-#define Maj(x,y,z) ((x & y) ^ (x & z) ^ (y & z))
-#define Parity(x,y,z) (x ^ y ^ z)
-
-#ifdef SHA1_SUPPORT
-/* SHA1 constants */
-#define SHA1_MASK 0x0000000f
-static const u32 SHA1_K[4] = {
-	0x5a827999UL, 0x6ed9eba1UL, 0x8f1bbcdcUL, 0xca62c1d6UL
-};
-
-static const u32 SHA1_DefaultHashValue[5] = {
-	0x67452301UL, 0xefcdab89UL, 0x98badcfeUL, 0x10325476UL, 0xc3d2e1f0UL
-};
-
-/*
-========================================================================
-Routine Description:
-    Initial struct rt_sha1_ctx
-
-Arguments:
-    pSHA_CTX        Pointer to struct rt_sha1_ctx
-
-Return Value:
-    None
-
-Note:
-    None
-========================================================================
-*/
-void RT_SHA1_Init(struct rt_sha1_ctx *pSHA_CTX)
-{
-	NdisMoveMemory(pSHA_CTX->HashValue, SHA1_DefaultHashValue,
-		       sizeof(SHA1_DefaultHashValue));
-	NdisZeroMemory(pSHA_CTX->Block, SHA1_BLOCK_SIZE);
-	pSHA_CTX->MessageLen = 0;
-	pSHA_CTX->BlockLen = 0;
-}				/* End of RT_SHA1_Init */
-
-/*
-========================================================================
-Routine Description:
-    SHA1 computation for one block (512 bits)
-
-Arguments:
-    pSHA_CTX        Pointer to struct rt_sha1_ctx
-
-Return Value:
-    None
-
-Note:
-    None
-========================================================================
-*/
-void SHA1_Hash(struct rt_sha1_ctx *pSHA_CTX)
-{
-	u32 W_i, t, s;
-	u32 W[16];
-	u32 a, b, c, d, e, T, f_t = 0;
-
-	/* Prepare the message schedule, {W_i}, 0 < t < 15 */
-	NdisMoveMemory(W, pSHA_CTX->Block, SHA1_BLOCK_SIZE);
-	for (W_i = 0; W_i < 16; W_i++)
-		W[W_i] = cpu2be32(W[W_i]);	/* Endian Swap */
-	/* End of for */
-
-	/* SHA256 hash computation */
-	/* Initialize the working variables */
-	a = pSHA_CTX->HashValue[0];
-	b = pSHA_CTX->HashValue[1];
-	c = pSHA_CTX->HashValue[2];
-	d = pSHA_CTX->HashValue[3];
-	e = pSHA_CTX->HashValue[4];
-
-	/* 80 rounds */
-	for (t = 0; t < 80; t++) {
-		s = t & SHA1_MASK;
-		if (t > 15) {	/* Prepare the message schedule, {W_i}, 16 < t < 79 */
-			W[s] =
-			    (W[(s + 13) & SHA1_MASK]) ^ (W[(s + 8) & SHA1_MASK])
-			    ^ (W[(s + 2) & SHA1_MASK]) ^ W[s];
-			W[s] = ROTL32(W[s], 1);
-		}		/* End of if */
-		switch (t / 20) {
-		case 0:
-			f_t = Ch(b, c, d);
-			break;
-		case 1:
-			f_t = Parity(b, c, d);
-			break;
-		case 2:
-			f_t = Maj(b, c, d);
-			break;
-		case 3:
-			f_t = Parity(b, c, d);
-			break;
-		}		/* End of switch */
-		T = ROTL32(a, 5) + f_t + e + SHA1_K[t / 20] + W[s];
-		e = d;
-		d = c;
-		c = ROTL32(b, 30);
-		b = a;
-		a = T;
-	}			/* End of for */
-
-	/* Compute the i^th intermediate hash value H^(i) */
-	pSHA_CTX->HashValue[0] += a;
-	pSHA_CTX->HashValue[1] += b;
-	pSHA_CTX->HashValue[2] += c;
-	pSHA_CTX->HashValue[3] += d;
-	pSHA_CTX->HashValue[4] += e;
-
-	NdisZeroMemory(pSHA_CTX->Block, SHA1_BLOCK_SIZE);
-	pSHA_CTX->BlockLen = 0;
-}				/* End of SHA1_Hash */
-
-/*
-========================================================================
-Routine Description:
-    The message is appended to block. If block size > 64 bytes, the SHA1_Hash
-will be called.
-
-Arguments:
-    pSHA_CTX        Pointer to struct rt_sha1_ctx
-    message         Message context
-    messageLen      The length of message in bytes
-
-Return Value:
-    None
-
-Note:
-    None
-========================================================================
-*/
-void SHA1_Append(struct rt_sha1_ctx *pSHA_CTX,
-		 IN const u8 Message[], u32 MessageLen)
-{
-	u32 appendLen = 0;
-	u32 diffLen = 0;
-
-	while (appendLen != MessageLen) {
-		diffLen = MessageLen - appendLen;
-		if ((pSHA_CTX->BlockLen + diffLen) < SHA1_BLOCK_SIZE) {
-			NdisMoveMemory(pSHA_CTX->Block + pSHA_CTX->BlockLen,
-				       Message + appendLen, diffLen);
-			pSHA_CTX->BlockLen += diffLen;
-			appendLen += diffLen;
-		} else {
-			NdisMoveMemory(pSHA_CTX->Block + pSHA_CTX->BlockLen,
-				       Message + appendLen,
-				       SHA1_BLOCK_SIZE - pSHA_CTX->BlockLen);
-			appendLen += (SHA1_BLOCK_SIZE - pSHA_CTX->BlockLen);
-			pSHA_CTX->BlockLen = SHA1_BLOCK_SIZE;
-			SHA1_Hash(pSHA_CTX);
-		}		/* End of if */
-	}			/* End of while */
-	pSHA_CTX->MessageLen += MessageLen;
-}				/* End of SHA1_Append */
-
-/*
-========================================================================
-Routine Description:
-    1. Append bit 1 to end of the message
-    2. Append the length of message in rightmost 64 bits
-    3. Transform the Hash Value to digest message
-
-Arguments:
-    pSHA_CTX        Pointer to struct rt_sha1_ctx
-
-Return Value:
-    digestMessage   Digest message
-
-Note:
-    None
-========================================================================
-*/
-void SHA1_End(struct rt_sha1_ctx *pSHA_CTX, u8 DigestMessage[])
-{
-	u32 index;
-	u64 message_length_bits;
-
-	/* Append bit 1 to end of the message */
-	NdisFillMemory(pSHA_CTX->Block + pSHA_CTX->BlockLen, 1, 0x80);
-
-	/* 55 = 64 - 8 - 1: append 1 bit(1 byte) and message length (8 bytes) */
-	if (pSHA_CTX->BlockLen > 55)
-		SHA1_Hash(pSHA_CTX);
-	/* End of if */
-
-	/* Append the length of message in rightmost 64 bits */
-	message_length_bits = pSHA_CTX->MessageLen * 8;
-	message_length_bits = cpu2be64(message_length_bits);
-	NdisMoveMemory(&pSHA_CTX->Block[56], &message_length_bits, 8);
-	SHA1_Hash(pSHA_CTX);
-
-	/* Return message digest, transform the u32 hash value to bytes */
-	for (index = 0; index < 5; index++)
-		pSHA_CTX->HashValue[index] =
-		    cpu2be32(pSHA_CTX->HashValue[index]);
-	/* End of for */
-	NdisMoveMemory(DigestMessage, pSHA_CTX->HashValue, SHA1_DIGEST_SIZE);
-}				/* End of SHA1_End */
-
-/*
-========================================================================
-Routine Description:
-    SHA1 algorithm
-
-Arguments:
-    message         Message context
-    messageLen      The length of message in bytes
-
-Return Value:
-    digestMessage   Digest message
-
-Note:
-    None
-========================================================================
-*/
-void RT_SHA1(IN const u8 Message[],
-	     u32 MessageLen, u8 DigestMessage[])
-{
-
-	struct rt_sha1_ctx sha_ctx;
-
-	NdisZeroMemory(&sha_ctx, sizeof(struct rt_sha1_ctx));
-	RT_SHA1_Init(&sha_ctx);
-	SHA1_Append(&sha_ctx, Message, MessageLen);
-	SHA1_End(&sha_ctx, DigestMessage);
-}				/* End of RT_SHA1 */
-#endif /* SHA1_SUPPORT */
-
-/* End of crypt_sha2.c */
diff -druN linux-2.6.39-libre/drivers/staging/rt2860/common/dfs.c linux-3.0-rc7-libre/drivers/staging/rt2860/common/dfs.c
--- linux-2.6.39-libre/drivers/staging/rt2860/common/dfs.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rt2860/common/dfs.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,68 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, 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.             *
- *                                                                       *
- *************************************************************************
-
-    Module Name:
-    ap_dfs.c
-
-    Abstract:
-    Support DFS function.
-
-    Revision History:
-    Who       When            What
-    --------  ----------      ----------------------------------------------
-*/
-
-#include "../rt_config.h"
-
-/*
-	========================================================================
-
-	Routine Description:
-		Radar channel check routine
-
-	Arguments:
-		pAd 	Pointer to our adapter
-
-	Return Value:
-		TRUE	need to do radar detect
-		FALSE	need not to do radar detect
-
-	========================================================================
-*/
-BOOLEAN RadarChannelCheck(struct rt_rtmp_adapter *pAd, u8 Ch)
-{
-	int i;
-	BOOLEAN result = FALSE;
-
-	for (i = 0; i < pAd->ChannelListNum; i++) {
-		if (Ch == pAd->ChannelList[i].Channel) {
-			result = pAd->ChannelList[i].DfsReq;
-			break;
-		}
-	}
-
-	return result;
-}
diff -druN linux-2.6.39-libre/drivers/staging/rt2860/common/ee_efuse.c linux-3.0-rc7-libre/drivers/staging/rt2860/common/ee_efuse.c
--- linux-2.6.39-libre/drivers/staging/rt2860/common/ee_efuse.c	2011-05-19 02:15:56.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rt2860/common/ee_efuse.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,351 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, 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.             *
- *                                                                       *
- *************************************************************************
-
-	Module Name:
-	ee_efuse.c
-
-	Abstract:
-	Miniport generic portion header file
-
-	Revision History:
-	Who         When          What
-	--------    ----------    ----------------------------------------------
-*/
-
-#include	"../rt_config.h"
-
-#define EFUSE_USAGE_MAP_START	0x2d0
-#define EFUSE_USAGE_MAP_END		0x2fc
-#define EFUSE_USAGE_MAP_SIZE	45
-
-#define EFUSE_EEPROM_DEFULT_FILE	"/*(DEBLOBBED)*/"
-#define MAX_EEPROM_BIN_FILE_SIZE	1024
-
-#define EFUSE_TAG				0x2fe
-
-typedef union _EFUSE_CTRL_STRUC {
-	struct {
-		u32 EFSROM_AOUT:6;
-		u32 EFSROM_MODE:2;
-		u32 EFSROM_LDO_OFF_TIME:6;
-		u32 EFSROM_LDO_ON_TIME:2;
-		u32 EFSROM_AIN:10;
-		u32 RESERVED:4;
-		u32 EFSROM_KICK:1;
-		u32 SEL_EFUSE:1;
-	} field;
-	u32 word;
-} EFUSE_CTRL_STRUC, *PEFUSE_CTRL_STRUC;
-
-/*
-========================================================================
-
-	Routine Description:
-
-	Arguments:
-
-	Return Value:
-
-	Note:
-
-========================================================================
-*/
-u8 eFuseReadRegisters(struct rt_rtmp_adapter *pAd,
-			 u16 Offset, u16 Length, u16 * pData)
-{
-	EFUSE_CTRL_STRUC eFuseCtrlStruc;
-	int i;
-	u16 efuseDataOffset;
-	u32 data;
-
-	RTMP_IO_READ32(pAd, EFUSE_CTRL, &eFuseCtrlStruc.word);
-
-	/*Step0. Write 10-bit of address to EFSROM_AIN (0x580, bit25:bit16). The address must be 16-byte alignment. */
-	/*Use the eeprom logical address and covert to address to block number */
-	eFuseCtrlStruc.field.EFSROM_AIN = Offset & 0xfff0;
-
-	/*Step1. Write EFSROM_MODE (0x580, bit7:bit6) to 0. */
-	eFuseCtrlStruc.field.EFSROM_MODE = 0;
-
-	/*Step2. Write EFSROM_KICK (0x580, bit30) to 1 to kick-off physical read procedure. */
-	eFuseCtrlStruc.field.EFSROM_KICK = 1;
-
-	NdisMoveMemory(&data, &eFuseCtrlStruc, 4);
-	RTMP_IO_WRITE32(pAd, EFUSE_CTRL, data);
-
-	/*Step3. Polling EFSROM_KICK(0x580, bit30) until it become 0 again. */
-	i = 0;
-	while (i < 500) {
-		/*rtmp.HwMemoryReadDword(EFUSE_CTRL, (DWORD *) &eFuseCtrlStruc, 4); */
-		RTMP_IO_READ32(pAd, EFUSE_CTRL, &eFuseCtrlStruc.word);
-		if (eFuseCtrlStruc.field.EFSROM_KICK == 0) {
-			break;
-		}
-		RTMPusecDelay(2);
-		i++;
-	}
-
-	/*if EFSROM_AOUT is not found in physical address, write 0xffff */
-	if (eFuseCtrlStruc.field.EFSROM_AOUT == 0x3f) {
-		for (i = 0; i < Length / 2; i++)
-			*(pData + 2 * i) = 0xffff;
-	} else {
-		/*Step4. Read 16-byte of data from EFUSE_DATA0-3 (0x590-0x59C) */
-		efuseDataOffset = EFUSE_DATA3 - (Offset & 0xC);
-		/*data hold 4 bytes data. */
-		/*In RTMP_IO_READ32 will automatically execute 32-bytes swapping */
-		RTMP_IO_READ32(pAd, efuseDataOffset, &data);
-		/*Decide the upper 2 bytes or the bottom 2 bytes. */
-		/* Little-endian                S       |       S       Big-endian */
-		/* addr 3       2       1       0       |       0       1       2       3 */
-		/* Ori-V        D       C       B       A       |       A       B       C       D */
-		/*After swapping */
-		/*              D       C       B       A       |       D       C       B       A */
-		/*Return 2-bytes */
-		/*The return byte statrs from S. Therefore, the little-endian will return BA, the Big-endian will return DC. */
-		/*For returning the bottom 2 bytes, the Big-endian should shift right 2-bytes. */
-		data = data >> (8 * (Offset & 0x3));
-
-		NdisMoveMemory(pData, &data, Length);
-	}
-
-	return (u8)eFuseCtrlStruc.field.EFSROM_AOUT;
-
-}
-
-/*
-========================================================================
-
-	Routine Description:
-
-	Arguments:
-
-	Return Value:
-
-	Note:
-
-========================================================================
-*/
-void eFusePhysicalReadRegisters(struct rt_rtmp_adapter *pAd,
-				u16 Offset,
-				u16 Length, u16 * pData)
-{
-	EFUSE_CTRL_STRUC eFuseCtrlStruc;
-	int i;
-	u16 efuseDataOffset;
-	u32 data;
-
-	RTMP_IO_READ32(pAd, EFUSE_CTRL, &eFuseCtrlStruc.word);
-
-	/*Step0. Write 10-bit of address to EFSROM_AIN (0x580, bit25:bit16). The address must be 16-byte alignment. */
-	eFuseCtrlStruc.field.EFSROM_AIN = Offset & 0xfff0;
-
-	/*Step1. Write EFSROM_MODE (0x580, bit7:bit6) to 1. */
-	/*Read in physical view */
-	eFuseCtrlStruc.field.EFSROM_MODE = 1;
-
-	/*Step2. Write EFSROM_KICK (0x580, bit30) to 1 to kick-off physical read procedure. */
-	eFuseCtrlStruc.field.EFSROM_KICK = 1;
-
-	NdisMoveMemory(&data, &eFuseCtrlStruc, 4);
-	RTMP_IO_WRITE32(pAd, EFUSE_CTRL, data);
-
-	/*Step3. Polling EFSROM_KICK(0x580, bit30) until it become 0 again. */
-	i = 0;
-	while (i < 500) {
-		RTMP_IO_READ32(pAd, EFUSE_CTRL, &eFuseCtrlStruc.word);
-		if (eFuseCtrlStruc.field.EFSROM_KICK == 0)
-			break;
-		RTMPusecDelay(2);
-		i++;
-	}
-
-	/*Step4. Read 16-byte of data from EFUSE_DATA0-3 (0x59C-0x590) */
-	/*Because the size of each EFUSE_DATA is 4 Bytes, the size of address of each is 2 bits. */
-	/*The previous 2 bits is the EFUSE_DATA number, the last 2 bits is used to decide which bytes */
-	/*Decide which EFUSE_DATA to read */
-	/*590:F E D C */
-	/*594:B A 9 8 */
-	/*598:7 6 5 4 */
-	/*59C:3 2 1 0 */
-	efuseDataOffset = EFUSE_DATA3 - (Offset & 0xC);
-
-	RTMP_IO_READ32(pAd, efuseDataOffset, &data);
-
-	data = data >> (8 * (Offset & 0x3));
-
-	NdisMoveMemory(pData, &data, Length);
-
-}
-
-/*
-========================================================================
-
-	Routine Description:
-
-	Arguments:
-
-	Return Value:
-
-	Note:
-
-========================================================================
-*/
-static void eFuseReadPhysical(struct rt_rtmp_adapter *pAd,
-			      u16 *lpInBuffer,
-			      unsigned long nInBufferSize,
-			      u16 *lpOutBuffer, unsigned long nOutBufferSize)
-{
-	u16 *pInBuf = (u16 *) lpInBuffer;
-	u16 *pOutBuf = (u16 *) lpOutBuffer;
-
-	u16 Offset = pInBuf[0];	/*addr */
-	u16 Length = pInBuf[1];	/*length */
-	int i;
-
-	for (i = 0; i < Length; i += 2) {
-		eFusePhysicalReadRegisters(pAd, Offset + i, 2, &pOutBuf[i / 2]);
-	}
-}
-
-/*
-========================================================================
-
-	Routine Description:
-
-	Arguments:
-
-	Return Value:
-
-	Note:
-
-========================================================================
-*/
-int set_eFuseGetFreeBlockCount_Proc(struct rt_rtmp_adapter *pAd, char *arg)
-{
-	u16 i;
-	u16 LogicalAddress;
-	u16 efusefreenum = 0;
-	if (!pAd->bUseEfuse)
-		return FALSE;
-	for (i = EFUSE_USAGE_MAP_START; i <= EFUSE_USAGE_MAP_END; i += 2) {
-		eFusePhysicalReadRegisters(pAd, i, 2, &LogicalAddress);
-		if ((LogicalAddress & 0xff) == 0) {
-			efusefreenum = (u8)(EFUSE_USAGE_MAP_END - i + 1);
-			break;
-		} else if (((LogicalAddress >> 8) & 0xff) == 0) {
-			efusefreenum = (u8)(EFUSE_USAGE_MAP_END - i);
-			break;
-		}
-
-		if (i == EFUSE_USAGE_MAP_END)
-			efusefreenum = 0;
-	}
-	printk(KERN_DEBUG "efuseFreeNumber is %d\n", efusefreenum);
-	return TRUE;
-}
-
-int set_eFusedump_Proc(struct rt_rtmp_adapter *pAd, char *arg)
-{
-	u16 InBuf[3];
-	int i = 0;
-	if (!pAd->bUseEfuse)
-		return FALSE;
-
-	printk(KERN_DEBUG "Block 0: ");
-
-	for (i = 0; i < EFUSE_USAGE_MAP_END / 2; i++) {
-		InBuf[0] = 2 * i;
-		InBuf[1] = 2;
-		InBuf[2] = 0x0;
-
-		eFuseReadPhysical(pAd, &InBuf[0], 4, &InBuf[2], 2);
-		if (i && i % 4 == 0) {
-			printk(KERN_CONT "\n");
-			printk(KERN_DEBUG "Block %x:", i / 8);
-		}
-		printk(KERN_CONT "%04x ", InBuf[2]);
-	}
-	printk(KERN_CONT "\n");
-
-	return TRUE;
-}
-
-int rtmp_ee_efuse_read16(struct rt_rtmp_adapter *pAd,
-			 u16 Offset, u16 * pValue)
-{
-	eFuseReadRegisters(pAd, Offset, 2, pValue);
-	return (*pValue);
-}
-
-int RtmpEfuseSupportCheck(struct rt_rtmp_adapter *pAd)
-{
-	u16 value;
-
-	if (IS_RT30xx(pAd)) {
-		eFusePhysicalReadRegisters(pAd, EFUSE_TAG, 2, &value);
-		pAd->EFuseTag = (value & 0xff);
-	}
-	return 0;
-}
-
-void eFuseGetFreeBlockCount(struct rt_rtmp_adapter *pAd, u32 *EfuseFreeBlock)
-{
-	u16 i;
-	u16 LogicalAddress;
-	if (!pAd->bUseEfuse) {
-		DBGPRINT(RT_DEBUG_TRACE,
-			 ("eFuseGetFreeBlockCount Only supports efuse Mode\n"));
-		return;
-	}
-	for (i = EFUSE_USAGE_MAP_START; i <= EFUSE_USAGE_MAP_END; i += 2) {
-		eFusePhysicalReadRegisters(pAd, i, 2, &LogicalAddress);
-		if ((LogicalAddress & 0xff) == 0) {
-			*EfuseFreeBlock = (u8)(EFUSE_USAGE_MAP_END - i + 1);
-			break;
-		} else if (((LogicalAddress >> 8) & 0xff) == 0) {
-			*EfuseFreeBlock = (u8)(EFUSE_USAGE_MAP_END - i);
-			break;
-		}
-
-		if (i == EFUSE_USAGE_MAP_END)
-			*EfuseFreeBlock = 0;
-	}
-	DBGPRINT(RT_DEBUG_TRACE,
-		 ("eFuseGetFreeBlockCount is 0x%x\n", *EfuseFreeBlock));
-}
-
-int eFuse_init(struct rt_rtmp_adapter *pAd)
-{
-	u32 EfuseFreeBlock = 0;
-	DBGPRINT(RT_DEBUG_ERROR,
-		 ("NVM is Efuse and its size =%x[%x-%x] \n",
-		  EFUSE_USAGE_MAP_SIZE, EFUSE_USAGE_MAP_START,
-		  EFUSE_USAGE_MAP_END));
-	eFuseGetFreeBlockCount(pAd, &EfuseFreeBlock);
-
-	return 0;
-}
diff -druN linux-2.6.39-libre/drivers/staging/rt2860/common/ee_prom.c linux-3.0-rc7-libre/drivers/staging/rt2860/common/ee_prom.c
--- linux-2.6.39-libre/drivers/staging/rt2860/common/ee_prom.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rt2860/common/ee_prom.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,197 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, 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.             *
- *                                                                       *
- *************************************************************************
-
-	Module Name:
-	ee_prom.c
-
-	Abstract:
-	Miniport generic portion header file
-
-	Revision History:
-	Who         When          What
-	--------    ----------    ----------------------------------------------
-*/
-
-#include	"../rt_config.h"
-
-/* IRQL = PASSIVE_LEVEL */
-static inline void RaiseClock(struct rt_rtmp_adapter *pAd, u32 * x)
-{
-	*x = *x | EESK;
-	RTMP_IO_WRITE32(pAd, E2PROM_CSR, *x);
-	RTMPusecDelay(1);	/* Max frequency = 1MHz in Spec. definition */
-}
-
-/* IRQL = PASSIVE_LEVEL */
-static inline void LowerClock(struct rt_rtmp_adapter *pAd, u32 * x)
-{
-	*x = *x & ~EESK;
-	RTMP_IO_WRITE32(pAd, E2PROM_CSR, *x);
-	RTMPusecDelay(1);
-}
-
-/* IRQL = PASSIVE_LEVEL */
-static inline u16 ShiftInBits(struct rt_rtmp_adapter *pAd)
-{
-	u32 x, i;
-	u16 data = 0;
-
-	RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
-
-	x &= ~(EEDO | EEDI);
-
-	for (i = 0; i < 16; i++) {
-		data = data << 1;
-		RaiseClock(pAd, &x);
-
-		RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
-		LowerClock(pAd, &x);	/*prevent read failed */
-
-		x &= ~(EEDI);
-		if (x & EEDO)
-			data |= 1;
-	}
-
-	return data;
-}
-
-/* IRQL = PASSIVE_LEVEL */
-static inline void ShiftOutBits(struct rt_rtmp_adapter *pAd,
-				u16 data, u16 count)
-{
-	u32 x, mask;
-
-	mask = 0x01 << (count - 1);
-	RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
-
-	x &= ~(EEDO | EEDI);
-
-	do {
-		x &= ~EEDI;
-		if (data & mask)
-			x |= EEDI;
-
-		RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);
-
-		RaiseClock(pAd, &x);
-		LowerClock(pAd, &x);
-
-		mask = mask >> 1;
-	} while (mask);
-
-	x &= ~EEDI;
-	RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);
-}
-
-/* IRQL = PASSIVE_LEVEL */
-static inline void EEpromCleanup(struct rt_rtmp_adapter *pAd)
-{
-	u32 x;
-
-	RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
-
-	x &= ~(EECS | EEDI);
-	RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);
-
-	RaiseClock(pAd, &x);
-	LowerClock(pAd, &x);
-}
-
-static inline void EWEN(struct rt_rtmp_adapter *pAd)
-{
-	u32 x;
-
-	/* reset bits and set EECS */
-	RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
-	x &= ~(EEDI | EEDO | EESK);
-	x |= EECS;
-	RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);
-
-	/* kick a pulse */
-	RaiseClock(pAd, &x);
-	LowerClock(pAd, &x);
-
-	/* output the read_opcode and six pulse in that order */
-	ShiftOutBits(pAd, EEPROM_EWEN_OPCODE, 5);
-	ShiftOutBits(pAd, 0, 6);
-
-	EEpromCleanup(pAd);
-}
-
-static inline void EWDS(struct rt_rtmp_adapter *pAd)
-{
-	u32 x;
-
-	/* reset bits and set EECS */
-	RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
-	x &= ~(EEDI | EEDO | EESK);
-	x |= EECS;
-	RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);
-
-	/* kick a pulse */
-	RaiseClock(pAd, &x);
-	LowerClock(pAd, &x);
-
-	/* output the read_opcode and six pulse in that order */
-	ShiftOutBits(pAd, EEPROM_EWDS_OPCODE, 5);
-	ShiftOutBits(pAd, 0, 6);
-
-	EEpromCleanup(pAd);
-}
-
-/* IRQL = PASSIVE_LEVEL */
-int rtmp_ee_prom_read16(struct rt_rtmp_adapter *pAd,
-			u16 Offset, u16 * pValue)
-{
-	u32 x;
-	u16 data;
-
-	Offset /= 2;
-	/* reset bits and set EECS */
-	RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
-	x &= ~(EEDI | EEDO | EESK);
-	x |= EECS;
-	RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);
-
-	/* patch can not access e-Fuse issue */
-	if (!(IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd))) {
-		/* kick a pulse */
-		RaiseClock(pAd, &x);
-		LowerClock(pAd, &x);
-	}
-	/* output the read_opcode and register number in that order */
-	ShiftOutBits(pAd, EEPROM_READ_OPCODE, 3);
-	ShiftOutBits(pAd, Offset, pAd->EEPROMAddressNum);
-
-	/* Now read the data (16 bits) in from the selected EEPROM word */
-	data = ShiftInBits(pAd);
-
-	EEpromCleanup(pAd);
-
-	*pValue = data;
-
-	return NDIS_STATUS_SUCCESS;
-}
diff -druN linux-2.6.39-libre/drivers/staging/rt2860/common/eeprom.c linux-3.0-rc7-libre/drivers/staging/rt2860/common/eeprom.c
--- linux-2.6.39-libre/drivers/staging/rt2860/common/eeprom.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rt2860/common/eeprom.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,91 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, 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.             *
- *                                                                       *
- *************************************************************************
-
-	Module Name:
-	eeprom.c
-
-	Abstract:
-
-	Revision History:
-	Who			When			What
-	--------	----------		----------------------------------------------
-	Name		Date			Modification logs
-*/
-#include "../rt_config.h"
-
-int RtmpChipOpsEepromHook(struct rt_rtmp_adapter *pAd, int infType)
-{
-	struct rt_rtmp_chip_op *pChipOps = &pAd->chipOps;
-#ifdef RT30xx
-#ifdef RTMP_EFUSE_SUPPORT
-	u32 eFuseCtrl, MacCsr0;
-	int index;
-
-	index = 0;
-	do {
-		RTMP_IO_READ32(pAd, MAC_CSR0, &MacCsr0);
-		pAd->MACVersion = MacCsr0;
-
-		if ((pAd->MACVersion != 0x00)
-		    && (pAd->MACVersion != 0xFFFFFFFF))
-			break;
-
-		RTMPusecDelay(10);
-	} while (index++ < 100);
-
-	pAd->bUseEfuse = FALSE;
-	RTMP_IO_READ32(pAd, EFUSE_CTRL, &eFuseCtrl);
-	pAd->bUseEfuse = ((eFuseCtrl & 0x80000000) == 0x80000000) ? 1 : 0;
-	if (pAd->bUseEfuse) {
-		pChipOps->eeinit = eFuse_init;
-		pChipOps->eeread = rtmp_ee_efuse_read16;
-		return 0;
-	} else
-		DBGPRINT(RT_DEBUG_TRACE, ("NVM is EEPROM\n"));
-#endif /* RTMP_EFUSE_SUPPORT // */
-#endif /* RT30xx // */
-
-	switch (infType) {
-#ifdef RTMP_PCI_SUPPORT
-	case RTMP_DEV_INF_PCI:
-		pChipOps->eeinit = NULL;
-		pChipOps->eeread = rtmp_ee_prom_read16;
-		break;
-#endif /* RTMP_PCI_SUPPORT // */
-#ifdef RTMP_USB_SUPPORT
-	case RTMP_DEV_INF_USB:
-		pChipOps->eeinit = NULL;
-		pChipOps->eeread = RTUSBReadEEPROM16;
-		break;
-#endif /* RTMP_USB_SUPPORT // */
-
-	default:
-		DBGPRINT(RT_DEBUG_ERROR, ("RtmpChipOpsEepromHook() failed!\n"));
-		break;
-	}
-
-	return 0;
-}
diff -druN linux-2.6.39-libre/drivers/staging/rt2860/common/mlme.c linux-3.0-rc7-libre/drivers/staging/rt2860/common/mlme.c
--- linux-2.6.39-libre/drivers/staging/rt2860/common/mlme.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rt2860/common/mlme.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,6068 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, 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.             *
- *                                                                       *
- *************************************************************************
-
-	Module Name:
-	mlme.c
-
-	Abstract:
-
-	Revision History:
-	Who			When			What
-	--------	----------		----------------------------------------------
-	John Chang	2004-08-25		Modify from RT2500 code base
-	John Chang	2004-09-06		modified for RT2600
-*/
-
-#include "../rt_config.h"
-#include <stdarg.h>
-#include <linux/kernel.h>
-
-u8 CISCO_OUI[] = { 0x00, 0x40, 0x96 };
-
-u8 WPA_OUI[] = { 0x00, 0x50, 0xf2, 0x01 };
-u8 RSN_OUI[] = { 0x00, 0x0f, 0xac };
-u8 WME_INFO_ELEM[] = { 0x00, 0x50, 0xf2, 0x02, 0x00, 0x01 };
-u8 WME_PARM_ELEM[] = { 0x00, 0x50, 0xf2, 0x02, 0x01, 0x01 };
-u8 Ccx2QosInfo[] = { 0x00, 0x40, 0x96, 0x04 };
-u8 RALINK_OUI[] = { 0x00, 0x0c, 0x43 };
-u8 BROADCOM_OUI[] = { 0x00, 0x90, 0x4c };
-u8 WPS_OUI[] = { 0x00, 0x50, 0xf2, 0x04 };
-u8 PRE_N_HT_OUI[] = { 0x00, 0x90, 0x4c };
-
-u8 RateSwitchTable[] = {
-/* Item No.   Mode   Curr-MCS   TrainUp   TrainDown             // Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF) */
-	0x11, 0x00, 0, 0, 0,	/* Initial used item after association */
-	0x00, 0x00, 0, 40, 101,
-	0x01, 0x00, 1, 40, 50,
-	0x02, 0x00, 2, 35, 45,
-	0x03, 0x00, 3, 20, 45,
-	0x04, 0x21, 0, 30, 50,
-	0x05, 0x21, 1, 20, 50,
-	0x06, 0x21, 2, 20, 50,
-	0x07, 0x21, 3, 15, 50,
-	0x08, 0x21, 4, 15, 30,
-	0x09, 0x21, 5, 10, 25,
-	0x0a, 0x21, 6, 8, 25,
-	0x0b, 0x21, 7, 8, 25,
-	0x0c, 0x20, 12, 15, 30,
-	0x0d, 0x20, 13, 8, 20,
-	0x0e, 0x20, 14, 8, 20,
-	0x0f, 0x20, 15, 8, 25,
-	0x10, 0x22, 15, 8, 25,
-	0x11, 0x00, 0, 0, 0,
-	0x12, 0x00, 0, 0, 0,
-	0x13, 0x00, 0, 0, 0,
-	0x14, 0x00, 0, 0, 0,
-	0x15, 0x00, 0, 0, 0,
-	0x16, 0x00, 0, 0, 0,
-	0x17, 0x00, 0, 0, 0,
-	0x18, 0x00, 0, 0, 0,
-	0x19, 0x00, 0, 0, 0,
-	0x1a, 0x00, 0, 0, 0,
-	0x1b, 0x00, 0, 0, 0,
-	0x1c, 0x00, 0, 0, 0,
-	0x1d, 0x00, 0, 0, 0,
-	0x1e, 0x00, 0, 0, 0,
-	0x1f, 0x00, 0, 0, 0,
-};
-
-u8 RateSwitchTable11B[] = {
-/* Item No.   Mode   Curr-MCS   TrainUp   TrainDown             // Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF) */
-	0x04, 0x03, 0, 0, 0,	/* Initial used item after association */
-	0x00, 0x00, 0, 40, 101,
-	0x01, 0x00, 1, 40, 50,
-	0x02, 0x00, 2, 35, 45,
-	0x03, 0x00, 3, 20, 45,
-};
-
-u8 RateSwitchTable11BG[] = {
-/* Item No.   Mode   Curr-MCS   TrainUp   TrainDown             // Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF) */
-	0x0a, 0x00, 0, 0, 0,	/* Initial used item after association */
-	0x00, 0x00, 0, 40, 101,
-	0x01, 0x00, 1, 40, 50,
-	0x02, 0x00, 2, 35, 45,
-	0x03, 0x00, 3, 20, 45,
-	0x04, 0x10, 2, 20, 35,
-	0x05, 0x10, 3, 16, 35,
-	0x06, 0x10, 4, 10, 25,
-	0x07, 0x10, 5, 16, 25,
-	0x08, 0x10, 6, 10, 25,
-	0x09, 0x10, 7, 10, 13,
-};
-
-u8 RateSwitchTable11G[] = {
-/* Item No.   Mode   Curr-MCS   TrainUp   TrainDown             // Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF) */
-	0x08, 0x00, 0, 0, 0,	/* Initial used item after association */
-	0x00, 0x10, 0, 20, 101,
-	0x01, 0x10, 1, 20, 35,
-	0x02, 0x10, 2, 20, 35,
-	0x03, 0x10, 3, 16, 35,
-	0x04, 0x10, 4, 10, 25,
-	0x05, 0x10, 5, 16, 25,
-	0x06, 0x10, 6, 10, 25,
-	0x07, 0x10, 7, 10, 13,
-};
-
-u8 RateSwitchTable11N1S[] = {
-/* Item No.   Mode   Curr-MCS   TrainUp   TrainDown             // Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF) */
-	0x0c, 0x0a, 0, 0, 0,	/* Initial used item after association */
-	0x00, 0x00, 0, 40, 101,
-	0x01, 0x00, 1, 40, 50,
-	0x02, 0x00, 2, 25, 45,
-	0x03, 0x21, 0, 20, 35,
-	0x04, 0x21, 1, 20, 35,
-	0x05, 0x21, 2, 20, 35,
-	0x06, 0x21, 3, 15, 35,
-	0x07, 0x21, 4, 15, 30,
-	0x08, 0x21, 5, 10, 25,
-	0x09, 0x21, 6, 8, 14,
-	0x0a, 0x21, 7, 8, 14,
-	0x0b, 0x23, 7, 8, 14,
-};
-
-u8 RateSwitchTable11N2S[] = {
-/* Item No.   Mode   Curr-MCS   TrainUp   TrainDown             // Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF) */
-	0x0e, 0x0c, 0, 0, 0,	/* Initial used item after association */
-	0x00, 0x00, 0, 40, 101,
-	0x01, 0x00, 1, 40, 50,
-	0x02, 0x00, 2, 25, 45,
-	0x03, 0x21, 0, 20, 35,
-	0x04, 0x21, 1, 20, 35,
-	0x05, 0x21, 2, 20, 35,
-	0x06, 0x21, 3, 15, 35,
-	0x07, 0x21, 4, 15, 30,
-	0x08, 0x20, 11, 15, 30,
-	0x09, 0x20, 12, 15, 30,
-	0x0a, 0x20, 13, 8, 20,
-	0x0b, 0x20, 14, 8, 20,
-	0x0c, 0x20, 15, 8, 25,
-	0x0d, 0x22, 15, 8, 15,
-};
-
-u8 RateSwitchTable11N3S[] = {
-/* Item No.     Mode    Curr-MCS        TrainUp TrainDown       // Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF) */
-	0x0b, 0x00, 0, 0, 0,	/* 0x0a, 0x00,  0,  0,  0,      // Initial used item after association */
-	0x00, 0x21, 0, 30, 101,
-	0x01, 0x21, 1, 20, 50,
-	0x02, 0x21, 2, 20, 50,
-	0x03, 0x21, 3, 15, 50,
-	0x04, 0x21, 4, 15, 30,
-	0x05, 0x20, 11, 15, 30,	/* Required by System-Alan @ 20080812 */
-	0x06, 0x20, 12, 15, 30,	/* 0x05, 0x20, 12, 15, 30, */
-	0x07, 0x20, 13, 8, 20,	/* 0x06, 0x20, 13,  8, 20, */
-	0x08, 0x20, 14, 8, 20,	/* 0x07, 0x20, 14,  8, 20, */
-	0x09, 0x20, 15, 8, 25,	/* 0x08, 0x20, 15,  8, 25, */
-	0x0a, 0x22, 15, 8, 25,	/* 0x09, 0x22, 15,  8, 25, */
-};
-
-u8 RateSwitchTable11N2SForABand[] = {
-/* Item No.   Mode   Curr-MCS   TrainUp   TrainDown             // Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF) */
-	0x0b, 0x09, 0, 0, 0,	/* Initial used item after association */
-	0x00, 0x21, 0, 30, 101,
-	0x01, 0x21, 1, 20, 50,
-	0x02, 0x21, 2, 20, 50,
-	0x03, 0x21, 3, 15, 50,
-	0x04, 0x21, 4, 15, 30,
-	0x05, 0x21, 5, 15, 30,
-	0x06, 0x20, 12, 15, 30,
-	0x07, 0x20, 13, 8, 20,
-	0x08, 0x20, 14, 8, 20,
-	0x09, 0x20, 15, 8, 25,
-	0x0a, 0x22, 15, 8, 25,
-};
-
-u8 RateSwitchTable11N3SForABand[] = {	/* 3*3 */
-/* Item No.   Mode   Curr-MCS   TrainUp   TrainDown             // Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF) */
-	0x0b, 0x09, 0, 0, 0,	/* Initial used item after association */
-	0x00, 0x21, 0, 30, 101,
-	0x01, 0x21, 1, 20, 50,
-	0x02, 0x21, 2, 20, 50,
-	0x03, 0x21, 3, 15, 50,
-	0x04, 0x21, 4, 15, 30,
-	0x05, 0x21, 5, 15, 30,
-	0x06, 0x20, 12, 15, 30,
-	0x07, 0x20, 13, 8, 20,
-	0x08, 0x20, 14, 8, 20,
-	0x09, 0x20, 15, 8, 25,
-	0x0a, 0x22, 15, 8, 25,
-};
-
-u8 RateSwitchTable11BGN1S[] = {
-/* Item No.   Mode   Curr-MCS   TrainUp   TrainDown             // Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF) */
-	0x0c, 0x0a, 0, 0, 0,	/* Initial used item after association */
-	0x00, 0x00, 0, 40, 101,
-	0x01, 0x00, 1, 40, 50,
-	0x02, 0x00, 2, 25, 45,
-	0x03, 0x21, 0, 20, 35,
-	0x04, 0x21, 1, 20, 35,
-	0x05, 0x21, 2, 20, 35,
-	0x06, 0x21, 3, 15, 35,
-	0x07, 0x21, 4, 15, 30,
-	0x08, 0x21, 5, 10, 25,
-	0x09, 0x21, 6, 8, 14,
-	0x0a, 0x21, 7, 8, 14,
-	0x0b, 0x23, 7, 8, 14,
-};
-
-u8 RateSwitchTable11BGN2S[] = {
-/* Item No.   Mode   Curr-MCS   TrainUp   TrainDown             // Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF) */
-	0x0e, 0x0c, 0, 0, 0,	/* Initial used item after association */
-	0x00, 0x00, 0, 40, 101,
-	0x01, 0x00, 1, 40, 50,
-	0x02, 0x00, 2, 25, 45,
-	0x03, 0x21, 0, 20, 35,
-	0x04, 0x21, 1, 20, 35,
-	0x05, 0x21, 2, 20, 35,
-	0x06, 0x21, 3, 15, 35,
-	0x07, 0x21, 4, 15, 30,
-	0x08, 0x20, 11, 15, 30,
-	0x09, 0x20, 12, 15, 30,
-	0x0a, 0x20, 13, 8, 20,
-	0x0b, 0x20, 14, 8, 20,
-	0x0c, 0x20, 15, 8, 25,
-	0x0d, 0x22, 15, 8, 15,
-};
-
-u8 RateSwitchTable11BGN3S[] = {	/* 3*3 */
-/* Item No.   Mode   Curr-MCS   TrainUp   TrainDown             // Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF) */
-	0x0a, 0x00, 0, 0, 0,	/* Initial used item after association */
-	0x00, 0x21, 0, 30, 101,	/*50 */
-	0x01, 0x21, 1, 20, 50,
-	0x02, 0x21, 2, 20, 50,
-	0x03, 0x21, 3, 20, 50,
-	0x04, 0x21, 4, 15, 50,
-	0x05, 0x20, 20, 15, 30,
-	0x06, 0x20, 21, 8, 20,
-	0x07, 0x20, 22, 8, 20,
-	0x08, 0x20, 23, 8, 25,
-	0x09, 0x22, 23, 8, 25,
-};
-
-u8 RateSwitchTable11BGN2SForABand[] = {
-/* Item No.   Mode   Curr-MCS   TrainUp   TrainDown             // Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF) */
-	0x0b, 0x09, 0, 0, 0,	/* Initial used item after association */
-	0x00, 0x21, 0, 30, 101,	/*50 */
-	0x01, 0x21, 1, 20, 50,
-	0x02, 0x21, 2, 20, 50,
-	0x03, 0x21, 3, 15, 50,
-	0x04, 0x21, 4, 15, 30,
-	0x05, 0x21, 5, 15, 30,
-	0x06, 0x20, 12, 15, 30,
-	0x07, 0x20, 13, 8, 20,
-	0x08, 0x20, 14, 8, 20,
-	0x09, 0x20, 15, 8, 25,
-	0x0a, 0x22, 15, 8, 25,
-};
-
-u8 RateSwitchTable11BGN3SForABand[] = {	/* 3*3 */
-/* Item No.   Mode   Curr-MCS   TrainUp   TrainDown             // Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF) */
-	0x0c, 0x09, 0, 0, 0,	/* Initial used item after association */
-	0x00, 0x21, 0, 30, 101,	/*50 */
-	0x01, 0x21, 1, 20, 50,
-	0x02, 0x21, 2, 20, 50,
-	0x03, 0x21, 3, 15, 50,
-	0x04, 0x21, 4, 15, 30,
-	0x05, 0x21, 5, 15, 30,
-	0x06, 0x21, 12, 15, 30,
-	0x07, 0x20, 20, 15, 30,
-	0x08, 0x20, 21, 8, 20,
-	0x09, 0x20, 22, 8, 20,
-	0x0a, 0x20, 23, 8, 25,
-	0x0b, 0x22, 23, 8, 25,
-};
-
-extern u8 OfdmRateToRxwiMCS[];
-/* since RT61 has better RX sensibility, we have to limit TX ACK rate not to exceed our normal data TX rate. */
-/* otherwise the WLAN peer may not be able to receive the ACK thus downgrade its data TX rate */
-unsigned long BasicRateMask[12] =
-    { 0xfffff001 /* 1-Mbps */ , 0xfffff003 /* 2 Mbps */ , 0xfffff007 /* 5.5 */ ,
-0xfffff00f /* 11 */ ,
-	0xfffff01f /* 6 */ , 0xfffff03f /* 9 */ , 0xfffff07f /* 12 */ ,
-	    0xfffff0ff /* 18 */ ,
-	0xfffff1ff /* 24 */ , 0xfffff3ff /* 36 */ , 0xfffff7ff /* 48 */ ,
-	    0xffffffff /* 54 */
-};
-
-u8 BROADCAST_ADDR[MAC_ADDR_LEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
-u8 ZERO_MAC_ADDR[MAC_ADDR_LEN] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
-
-/* e.g. RssiSafeLevelForTxRate[RATE_36]" means if the current RSSI is greater than */
-/*              this value, then it's quaranteed capable of operating in 36 mbps TX rate in */
-/*              clean environment. */
-/*                                                                TxRate: 1   2   5.5   11       6        9    12       18       24   36   48   54       72  100 */
-char RssiSafeLevelForTxRate[] =
-    { -92, -91, -90, -87, -88, -86, -85, -83, -81, -78, -72, -71, -40, -40 };
-
-u8 RateIdToMbps[] = { 1, 2, 5, 11, 6, 9, 12, 18, 24, 36, 48, 54, 72, 100 };
-u16 RateIdTo500Kbps[] =
-    { 2, 4, 11, 22, 12, 18, 24, 36, 48, 72, 96, 108, 144, 200 };
-
-u8 SsidIe = IE_SSID;
-u8 SupRateIe = IE_SUPP_RATES;
-u8 ExtRateIe = IE_EXT_SUPP_RATES;
-u8 HtCapIe = IE_HT_CAP;
-u8 AddHtInfoIe = IE_ADD_HT;
-u8 NewExtChanIe = IE_SECONDARY_CH_OFFSET;
-u8 ErpIe = IE_ERP;
-u8 DsIe = IE_DS_PARM;
-u8 TimIe = IE_TIM;
-u8 WpaIe = IE_WPA;
-u8 Wpa2Ie = IE_WPA2;
-u8 IbssIe = IE_IBSS_PARM;
-
-extern u8 WPA_OUI[];
-
-u8 SES_OUI[] = { 0x00, 0x90, 0x4c };
-
-u8 ZeroSsid[32] =
-    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00,
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	    0x00, 0x00, 0x00, 0x00
-};
-
-/*
-	==========================================================================
-	Description:
-		initialize the MLME task and its data structure (queue, spinlock,
-		timer, state machines).
-
-	IRQL = PASSIVE_LEVEL
-
-	Return:
-		always return NDIS_STATUS_SUCCESS
-
-	==========================================================================
-*/
-int MlmeInit(struct rt_rtmp_adapter *pAd)
-{
-	int Status = NDIS_STATUS_SUCCESS;
-
-	DBGPRINT(RT_DEBUG_TRACE, ("--> MLME Initialize\n"));
-
-	do {
-		Status = MlmeQueueInit(&pAd->Mlme.Queue);
-		if (Status != NDIS_STATUS_SUCCESS)
-			break;
-
-		pAd->Mlme.bRunning = FALSE;
-		NdisAllocateSpinLock(&pAd->Mlme.TaskLock);
-
-		{
-			BssTableInit(&pAd->ScanTab);
-
-			/* init STA state machines */
-			AssocStateMachineInit(pAd, &pAd->Mlme.AssocMachine,
-					      pAd->Mlme.AssocFunc);
-			AuthStateMachineInit(pAd, &pAd->Mlme.AuthMachine,
-					     pAd->Mlme.AuthFunc);
-			AuthRspStateMachineInit(pAd, &pAd->Mlme.AuthRspMachine,
-						pAd->Mlme.AuthRspFunc);
-			SyncStateMachineInit(pAd, &pAd->Mlme.SyncMachine,
-					     pAd->Mlme.SyncFunc);
-
-			/* Since we are using switch/case to implement it, the init is different from the above */
-			/* state machine init */
-			MlmeCntlInit(pAd, &pAd->Mlme.CntlMachine, NULL);
-		}
-
-		WpaStateMachineInit(pAd, &pAd->Mlme.WpaMachine,
-				    pAd->Mlme.WpaFunc);
-
-		ActionStateMachineInit(pAd, &pAd->Mlme.ActMachine,
-				       pAd->Mlme.ActFunc);
-
-		/* Init mlme periodic timer */
-		RTMPInitTimer(pAd, &pAd->Mlme.PeriodicTimer,
-			      GET_TIMER_FUNCTION(MlmePeriodicExec), pAd, TRUE);
-
-		/* Set mlme periodic timer */
-		RTMPSetTimer(&pAd->Mlme.PeriodicTimer, MLME_TASK_EXEC_INTV);
-
-		/* software-based RX Antenna diversity */
-		RTMPInitTimer(pAd, &pAd->Mlme.RxAntEvalTimer,
-			      GET_TIMER_FUNCTION(AsicRxAntEvalTimeout), pAd,
-			      FALSE);
-
-		{
-#ifdef RTMP_PCI_SUPPORT
-			if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE)) {
-				/* only PCIe cards need these two timers */
-				RTMPInitTimer(pAd, &pAd->Mlme.PsPollTimer,
-					      GET_TIMER_FUNCTION
-					      (PsPollWakeExec), pAd, FALSE);
-				RTMPInitTimer(pAd, &pAd->Mlme.RadioOnOffTimer,
-					      GET_TIMER_FUNCTION(RadioOnExec),
-					      pAd, FALSE);
-			}
-#endif /* RTMP_PCI_SUPPORT // */
-
-			RTMPInitTimer(pAd, &pAd->Mlme.LinkDownTimer,
-				      GET_TIMER_FUNCTION(LinkDownExec), pAd,
-				      FALSE);
-
-#ifdef RTMP_MAC_USB
-			RTMPInitTimer(pAd, &pAd->Mlme.AutoWakeupTimer,
-				      GET_TIMER_FUNCTION
-				      (RtmpUsbStaAsicForceWakeupTimeout), pAd,
-				      FALSE);
-			pAd->Mlme.AutoWakeupTimerRunning = FALSE;
-#endif /* RTMP_MAC_USB // */
-		}
-
-	} while (FALSE);
-
-	DBGPRINT(RT_DEBUG_TRACE, ("<-- MLME Initialize\n"));
-
-	return Status;
-}
-
-/*
-	==========================================================================
-	Description:
-		main loop of the MLME
-	Pre:
-		Mlme has to be initialized, and there are something inside the queue
-	Note:
-		This function is invoked from MPSetInformation and MPReceive;
-		This task guarantee only one MlmeHandler will run.
-
-	IRQL = DISPATCH_LEVEL
-
-	==========================================================================
- */
-void MlmeHandler(struct rt_rtmp_adapter *pAd)
-{
-	struct rt_mlme_queue_elem *Elem = NULL;
-
-	/* Only accept MLME and Frame from peer side, no other (control/data) frame should */
-	/* get into this state machine */
-
-	NdisAcquireSpinLock(&pAd->Mlme.TaskLock);
-	if (pAd->Mlme.bRunning) {
-		NdisReleaseSpinLock(&pAd->Mlme.TaskLock);
-		return;
-	} else {
-		pAd->Mlme.bRunning = TRUE;
-	}
-	NdisReleaseSpinLock(&pAd->Mlme.TaskLock);
-
-	while (!MlmeQueueEmpty(&pAd->Mlme.Queue)) {
-		if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_MLME_RESET_IN_PROGRESS) ||
-		    RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS) ||
-		    RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) {
-			DBGPRINT(RT_DEBUG_TRACE,
-				 ("Device Halted or Removed or MlmeRest, exit MlmeHandler! (queue num = %ld)\n",
-				  pAd->Mlme.Queue.Num));
-			break;
-		}
-		/*From message type, determine which state machine I should drive */
-		if (MlmeDequeue(&pAd->Mlme.Queue, &Elem)) {
-#ifdef RTMP_MAC_USB
-			if (Elem->MsgType == MT2_RESET_CONF) {
-				DBGPRINT_RAW(RT_DEBUG_TRACE,
-					     ("reset MLME state machine!\n"));
-				MlmeRestartStateMachine(pAd);
-				Elem->Occupied = FALSE;
-				Elem->MsgLen = 0;
-				continue;
-			}
-#endif /* RTMP_MAC_USB // */
-
-			/* if dequeue success */
-			switch (Elem->Machine) {
-				/* STA state machines */
-			case ASSOC_STATE_MACHINE:
-				StateMachinePerformAction(pAd,
-							  &pAd->Mlme.
-							  AssocMachine, Elem);
-				break;
-			case AUTH_STATE_MACHINE:
-				StateMachinePerformAction(pAd,
-							  &pAd->Mlme.
-							  AuthMachine, Elem);
-				break;
-			case AUTH_RSP_STATE_MACHINE:
-				StateMachinePerformAction(pAd,
-							  &pAd->Mlme.
-							  AuthRspMachine, Elem);
-				break;
-			case SYNC_STATE_MACHINE:
-				StateMachinePerformAction(pAd,
-							  &pAd->Mlme.
-							  SyncMachine, Elem);
-				break;
-			case MLME_CNTL_STATE_MACHINE:
-				MlmeCntlMachinePerformAction(pAd,
-							     &pAd->Mlme.
-							     CntlMachine, Elem);
-				break;
-			case WPA_PSK_STATE_MACHINE:
-				StateMachinePerformAction(pAd,
-							  &pAd->Mlme.
-							  WpaPskMachine, Elem);
-				break;
-
-			case ACTION_STATE_MACHINE:
-				StateMachinePerformAction(pAd,
-							  &pAd->Mlme.ActMachine,
-							  Elem);
-				break;
-
-			case WPA_STATE_MACHINE:
-				StateMachinePerformAction(pAd,
-							  &pAd->Mlme.WpaMachine,
-							  Elem);
-				break;
-
-			default:
-				DBGPRINT(RT_DEBUG_TRACE,
-					 ("ERROR: Illegal machine %ld in MlmeHandler()\n",
-					  Elem->Machine));
-				break;
-			}	/* end of switch */
-
-			/* free MLME element */
-			Elem->Occupied = FALSE;
-			Elem->MsgLen = 0;
-
-		} else {
-			DBGPRINT_ERR("MlmeHandler: MlmeQueue empty\n");
-		}
-	}
-
-	NdisAcquireSpinLock(&pAd->Mlme.TaskLock);
-	pAd->Mlme.bRunning = FALSE;
-	NdisReleaseSpinLock(&pAd->Mlme.TaskLock);
-}
-
-/*
-	==========================================================================
-	Description:
-		Destructor of MLME (Destroy queue, state machine, spin lock and timer)
-	Parameters:
-		Adapter - NIC Adapter pointer
-	Post:
-		The MLME task will no longer work properly
-
-	IRQL = PASSIVE_LEVEL
-
-	==========================================================================
- */
-void MlmeHalt(struct rt_rtmp_adapter *pAd)
-{
-	BOOLEAN Cancelled;
-
-	DBGPRINT(RT_DEBUG_TRACE, ("==> MlmeHalt\n"));
-
-	if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) {
-		/* disable BEACON generation and other BEACON related hardware timers */
-		AsicDisableSync(pAd);
-	}
-
-	{
-		/* Cancel pending timers */
-		RTMPCancelTimer(&pAd->MlmeAux.AssocTimer, &Cancelled);
-		RTMPCancelTimer(&pAd->MlmeAux.ReassocTimer, &Cancelled);
-		RTMPCancelTimer(&pAd->MlmeAux.DisassocTimer, &Cancelled);
-		RTMPCancelTimer(&pAd->MlmeAux.AuthTimer, &Cancelled);
-		RTMPCancelTimer(&pAd->MlmeAux.BeaconTimer, &Cancelled);
-		RTMPCancelTimer(&pAd->MlmeAux.ScanTimer, &Cancelled);
-
-#ifdef RTMP_MAC_PCI
-		if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE)
-		    && (pAd->StaCfg.PSControl.field.EnableNewPS == TRUE)) {
-			RTMPCancelTimer(&pAd->Mlme.PsPollTimer, &Cancelled);
-			RTMPCancelTimer(&pAd->Mlme.RadioOnOffTimer, &Cancelled);
-		}
-#endif /* RTMP_MAC_PCI // */
-
-		RTMPCancelTimer(&pAd->Mlme.LinkDownTimer, &Cancelled);
-
-#ifdef RTMP_MAC_USB
-		RTMPCancelTimer(&pAd->Mlme.AutoWakeupTimer, &Cancelled);
-#endif /* RTMP_MAC_USB // */
-	}
-
-	RTMPCancelTimer(&pAd->Mlme.PeriodicTimer, &Cancelled);
-	RTMPCancelTimer(&pAd->Mlme.RxAntEvalTimer, &Cancelled);
-
-	if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) {
-		struct rt_rtmp_chip_op *pChipOps = &pAd->chipOps;
-
-		/* Set LED */
-		RTMPSetLED(pAd, LED_HALT);
-		RTMPSetSignalLED(pAd, -100);	/* Force signal strength Led to be turned off, firmware is not done it. */
-#ifdef RTMP_MAC_USB
-		{
-			LED_CFG_STRUC LedCfg;
-			RTMP_IO_READ32(pAd, LED_CFG, &LedCfg.word);
-			LedCfg.field.LedPolar = 0;
-			LedCfg.field.RLedMode = 0;
-			LedCfg.field.GLedMode = 0;
-			LedCfg.field.YLedMode = 0;
-			RTMP_IO_WRITE32(pAd, LED_CFG, LedCfg.word);
-		}
-#endif /* RTMP_MAC_USB // */
-
-		if (pChipOps->AsicHaltAction)
-			pChipOps->AsicHaltAction(pAd);
-	}
-
-	RTMPusecDelay(5000);	/*  5 msec to guarantee Ant Diversity timer canceled */
-
-	MlmeQueueDestroy(&pAd->Mlme.Queue);
-	NdisFreeSpinLock(&pAd->Mlme.TaskLock);
-
-	DBGPRINT(RT_DEBUG_TRACE, ("<== MlmeHalt\n"));
-}
-
-void MlmeResetRalinkCounters(struct rt_rtmp_adapter *pAd)
-{
-	pAd->RalinkCounters.LastOneSecRxOkDataCnt =
-	    pAd->RalinkCounters.OneSecRxOkDataCnt;
-	/* clear all OneSecxxx counters. */
-	pAd->RalinkCounters.OneSecBeaconSentCnt = 0;
-	pAd->RalinkCounters.OneSecFalseCCACnt = 0;
-	pAd->RalinkCounters.OneSecRxFcsErrCnt = 0;
-	pAd->RalinkCounters.OneSecRxOkCnt = 0;
-	pAd->RalinkCounters.OneSecTxFailCount = 0;
-	pAd->RalinkCounters.OneSecTxNoRetryOkCount = 0;
-	pAd->RalinkCounters.OneSecTxRetryOkCount = 0;
-	pAd->RalinkCounters.OneSecRxOkDataCnt = 0;
-	pAd->RalinkCounters.OneSecReceivedByteCount = 0;
-	pAd->RalinkCounters.OneSecTransmittedByteCount = 0;
-
-	/* TODO: for debug only. to be removed */
-	pAd->RalinkCounters.OneSecOsTxCount[QID_AC_BE] = 0;
-	pAd->RalinkCounters.OneSecOsTxCount[QID_AC_BK] = 0;
-	pAd->RalinkCounters.OneSecOsTxCount[QID_AC_VI] = 0;
-	pAd->RalinkCounters.OneSecOsTxCount[QID_AC_VO] = 0;
-	pAd->RalinkCounters.OneSecDmaDoneCount[QID_AC_BE] = 0;
-	pAd->RalinkCounters.OneSecDmaDoneCount[QID_AC_BK] = 0;
-	pAd->RalinkCounters.OneSecDmaDoneCount[QID_AC_VI] = 0;
-	pAd->RalinkCounters.OneSecDmaDoneCount[QID_AC_VO] = 0;
-	pAd->RalinkCounters.OneSecTxDoneCount = 0;
-	pAd->RalinkCounters.OneSecRxCount = 0;
-	pAd->RalinkCounters.OneSecTxAggregationCount = 0;
-	pAd->RalinkCounters.OneSecRxAggregationCount = 0;
-
-	return;
-}
-
-/*
-	==========================================================================
-	Description:
-		This routine is executed periodically to -
-		1. Decide if it's a right time to turn on PwrMgmt bit of all
-		   outgoiing frames
-		2. Calculate ChannelQuality based on statistics of the last
-		   period, so that TX rate won't toggling very frequently between a
-		   successful TX and a failed TX.
-		3. If the calculated ChannelQuality indicated current connection not
-		   healthy, then a ROAMing attempt is tried here.
-
-	IRQL = DISPATCH_LEVEL
-
-	==========================================================================
- */
-#define ADHOC_BEACON_LOST_TIME		(8*OS_HZ)	/* 8 sec */
-void MlmePeriodicExec(void *SystemSpecific1,
-		      void *FunctionContext,
-		      void *SystemSpecific2, void *SystemSpecific3)
-{
-	unsigned long TxTotalCnt;
-	struct rt_rtmp_adapter *pAd = (struct rt_rtmp_adapter *)FunctionContext;
-
-#ifdef RTMP_MAC_PCI
-	{
-		/* If Hardware controlled Radio enabled, we have to check GPIO pin2 every 2 second. */
-		/* Move code to here, because following code will return when radio is off */
-		if ((pAd->Mlme.PeriodicRound % (MLME_TASK_EXEC_MULTIPLE * 2) ==
-		     0) && (pAd->StaCfg.bHardwareRadio == TRUE)
-		    && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))
-		    && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS))
-		    /*&&(pAd->bPCIclkOff == FALSE) */
-		    ) {
-			u32 data = 0;
-
-			/* Read GPIO pin2 as Hardware controlled radio state */
-#ifndef RT3090
-			RTMP_IO_READ32(pAd, GPIO_CTRL_CFG, &data);
-#endif /* RT3090 // */
-/*KH(PCIE PS):Added based on Jane<-- */
-#ifdef RT3090
-/* Read GPIO pin2 as Hardware controlled radio state */
-/* We need to Read GPIO if HW said so no mater what advance power saving */
-			if ((pAd->OpMode == OPMODE_STA) && (IDLE_ON(pAd))
-			    &&
-			    (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF))
-			    && (pAd->StaCfg.PSControl.field.EnablePSinIdle ==
-				TRUE)) {
-				/* Want to make sure device goes to L0 state before reading register. */
-				RTMPPCIeLinkCtrlValueRestore(pAd, 0);
-				RTMP_IO_FORCE_READ32(pAd, GPIO_CTRL_CFG, &data);
-				RTMPPCIeLinkCtrlSetting(pAd, 3);
-			} else
-				RTMP_IO_FORCE_READ32(pAd, GPIO_CTRL_CFG, &data);
-#endif /* RT3090 // */
-/*KH(PCIE PS):Added based on Jane--> */
-
-			if (data & 0x04) {
-				pAd->StaCfg.bHwRadio = TRUE;
-			} else {
-				pAd->StaCfg.bHwRadio = FALSE;
-			}
-			if (pAd->StaCfg.bRadio !=
-			    (pAd->StaCfg.bHwRadio && pAd->StaCfg.bSwRadio)) {
-				pAd->StaCfg.bRadio = (pAd->StaCfg.bHwRadio
-						      && pAd->StaCfg.bSwRadio);
-				if (pAd->StaCfg.bRadio == TRUE) {
-					MlmeRadioOn(pAd);
-					/* Update extra information */
-					pAd->ExtraInfo = EXTRA_INFO_CLEAR;
-				} else {
-					MlmeRadioOff(pAd);
-					/* Update extra information */
-					pAd->ExtraInfo = HW_RADIO_OFF;
-				}
-			}
-		}
-	}
-#endif /* RTMP_MAC_PCI // */
-
-	/* Do nothing if the driver is starting halt state. */
-	/* This might happen when timer already been fired before cancel timer with mlmehalt */
-	if ((RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_HALT_IN_PROGRESS |
-				  fRTMP_ADAPTER_RADIO_OFF |
-				  fRTMP_ADAPTER_RADIO_MEASUREMENT |
-				  fRTMP_ADAPTER_RESET_IN_PROGRESS))))
-		return;
-
-	RTMP_MLME_PRE_SANITY_CHECK(pAd);
-
-	{
-		/* Do nothing if monitor mode is on */
-		if (MONITOR_ON(pAd))
-			return;
-
-		if (pAd->Mlme.PeriodicRound & 0x1) {
-			/* This is the fix for wifi 11n extension channel overlapping test case.  for 2860D */
-			if (((pAd->MACVersion & 0xffff) == 0x0101) &&
-			    (STA_TGN_WIFI_ON(pAd)) &&
-			    (pAd->CommonCfg.IOTestParm.bToggle == FALSE))
-			{
-				RTMP_IO_WRITE32(pAd, TXOP_CTRL_CFG, 0x24Bf);
-				pAd->CommonCfg.IOTestParm.bToggle = TRUE;
-			} else if ((STA_TGN_WIFI_ON(pAd)) &&
-				   ((pAd->MACVersion & 0xffff) == 0x0101)) {
-				RTMP_IO_WRITE32(pAd, TXOP_CTRL_CFG, 0x243f);
-				pAd->CommonCfg.IOTestParm.bToggle = FALSE;
-			}
-		}
-	}
-
-	pAd->bUpdateBcnCntDone = FALSE;
-
-/*      RECBATimerTimeout(SystemSpecific1,FunctionContext,SystemSpecific2,SystemSpecific3); */
-	pAd->Mlme.PeriodicRound++;
-
-#ifdef RTMP_MAC_USB
-	/* execute every 100ms, update the Tx FIFO Cnt for update Tx Rate. */
-	NICUpdateFifoStaCounters(pAd);
-#endif /* RTMP_MAC_USB // */
-
-	/* execute every 500ms */
-	if ((pAd->Mlme.PeriodicRound % 5 == 0)
-	    && RTMPAutoRateSwitchCheck(pAd)
-	    /*(OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED)) */ )
-	{
-		/* perform dynamic tx rate switching based on past TX history */
-		{
-			if ((OPSTATUS_TEST_FLAG
-			     (pAd, fOP_STATUS_MEDIA_STATE_CONNECTED)
-			    )
-			    && (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE)))
-				MlmeDynamicTxRateSwitching(pAd);
-		}
-	}
-	/* Normal 1 second Mlme PeriodicExec. */
-	if (pAd->Mlme.PeriodicRound % MLME_TASK_EXEC_MULTIPLE == 0) {
-		pAd->Mlme.OneSecPeriodicRound++;
-
-		/*ORIBATimerTimeout(pAd); */
-
-		/* Media status changed, report to NDIS */
-		if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_MEDIA_STATE_CHANGE)) {
-			RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_MEDIA_STATE_CHANGE);
-			if (OPSTATUS_TEST_FLAG
-			    (pAd, fOP_STATUS_MEDIA_STATE_CONNECTED)) {
-				pAd->IndicateMediaState =
-				    NdisMediaStateConnected;
-				RTMP_IndicateMediaState(pAd);
-
-			} else {
-				pAd->IndicateMediaState =
-				    NdisMediaStateDisconnected;
-				RTMP_IndicateMediaState(pAd);
-			}
-		}
-
-		NdisGetSystemUpTime(&pAd->Mlme.Now32);
-
-		/* add the most up-to-date h/w raw counters into software variable, so that */
-		/* the dynamic tuning mechanism below are based on most up-to-date information */
-		NICUpdateRawCounters(pAd);
-
-#ifdef RTMP_MAC_USB
-		RTUSBWatchDog(pAd);
-#endif /* RTMP_MAC_USB // */
-
-		/* Need statistics after read counter. So put after NICUpdateRawCounters */
-		ORIBATimerTimeout(pAd);
-
-		/* if MGMT RING is full more than twice within 1 second, we consider there's */
-		/* a hardware problem stucking the TX path. In this case, try a hardware reset */
-		/* to recover the system */
-		/*      if (pAd->RalinkCounters.MgmtRingFullCount >= 2) */
-		/*              RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_HARDWARE_ERROR); */
-		/*      else */
-		/*              pAd->RalinkCounters.MgmtRingFullCount = 0; */
-
-		/* The time period for checking antenna is according to traffic */
-		{
-			if (pAd->Mlme.bEnableAutoAntennaCheck) {
-				TxTotalCnt =
-				    pAd->RalinkCounters.OneSecTxNoRetryOkCount +
-				    pAd->RalinkCounters.OneSecTxRetryOkCount +
-				    pAd->RalinkCounters.OneSecTxFailCount;
-
-				/* dynamic adjust antenna evaluation period according to the traffic */
-				if (TxTotalCnt > 50) {
-					if (pAd->Mlme.OneSecPeriodicRound %
-					    10 == 0) {
-						AsicEvaluateRxAnt(pAd);
-					}
-				} else {
-					if (pAd->Mlme.OneSecPeriodicRound % 3 ==
-					    0) {
-						AsicEvaluateRxAnt(pAd);
-					}
-				}
-			}
-		}
-
-		STAMlmePeriodicExec(pAd);
-
-		MlmeResetRalinkCounters(pAd);
-
-		{
-#ifdef RTMP_MAC_PCI
-			if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)
-			    && (pAd->bPCIclkOff == FALSE))
-#endif /* RTMP_MAC_PCI // */
-			{
-				/* When Adhoc beacon is enabled and RTS/CTS is enabled, there is a chance that hardware MAC FSM will run into a deadlock */
-				/* and sending CTS-to-self over and over. */
-				/* Software Patch Solution: */
-				/* 1. Polling debug state register 0x10F4 every one second. */
-				/* 2. If in 0x10F4 the ((bit29==1) && (bit7==1)) OR ((bit29==1) && (bit5==1)), it means the deadlock has occurred. */
-				/* 3. If the deadlock occurred, reset MAC/BBP by setting 0x1004 to 0x0001 for a while then setting it back to 0x000C again. */
-
-				u32 MacReg = 0;
-
-				RTMP_IO_READ32(pAd, 0x10F4, &MacReg);
-				if (((MacReg & 0x20000000) && (MacReg & 0x80))
-				    || ((MacReg & 0x20000000)
-					&& (MacReg & 0x20))) {
-					RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x1);
-					RTMPusecDelay(1);
-					RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0xC);
-
-					DBGPRINT(RT_DEBUG_WARN,
-						 ("Warning, MAC specific condition occurs \n"));
-				}
-			}
-		}
-
-		RTMP_MLME_HANDLER(pAd);
-	}
-
-	pAd->bUpdateBcnCntDone = FALSE;
-}
-
-/*
-	==========================================================================
-	Validate SSID for connection try and rescan purpose
-	Valid SSID will have visible chars only.
-	The valid length is from 0 to 32.
-	IRQL = DISPATCH_LEVEL
-	==========================================================================
- */
-BOOLEAN MlmeValidateSSID(u8 *pSsid, u8 SsidLen)
-{
-	int index;
-
-	if (SsidLen > MAX_LEN_OF_SSID)
-		return (FALSE);
-
-	/* Check each character value */
-	for (index = 0; index < SsidLen; index++) {
-		if (pSsid[index] < 0x20)
-			return (FALSE);
-	}
-
-	/* All checked */
-	return (TRUE);
-}
-
-void MlmeSelectTxRateTable(struct rt_rtmp_adapter *pAd,
-			   struct rt_mac_table_entry *pEntry,
-			   u8 ** ppTable,
-			   u8 *pTableSize, u8 *pInitTxRateIdx)
-{
-	do {
-		/* decide the rate table for tuning */
-		if (pAd->CommonCfg.TxRateTableSize > 0) {
-			*ppTable = RateSwitchTable;
-			*pTableSize = RateSwitchTable[0];
-			*pInitTxRateIdx = RateSwitchTable[1];
-
-			break;
-		}
-
-		if ((pAd->OpMode == OPMODE_STA) && ADHOC_ON(pAd)) {
-			if ((pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED) && (pEntry->HTCapability.MCSSet[0] == 0xff) && ((pEntry->HTCapability.MCSSet[1] == 0x00) || (pAd->Antenna.field.TxPath == 1))) {	/* 11N 1S Adhoc */
-				*ppTable = RateSwitchTable11N1S;
-				*pTableSize = RateSwitchTable11N1S[0];
-				*pInitTxRateIdx = RateSwitchTable11N1S[1];
-
-			} else if ((pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED) && (pEntry->HTCapability.MCSSet[0] == 0xff) && (pEntry->HTCapability.MCSSet[1] == 0xff) && (pAd->Antenna.field.TxPath == 2)) {	/* 11N 2S Adhoc */
-				if (pAd->LatchRfRegs.Channel <= 14) {
-					*ppTable = RateSwitchTable11N2S;
-					*pTableSize = RateSwitchTable11N2S[0];
-					*pInitTxRateIdx =
-					    RateSwitchTable11N2S[1];
-				} else {
-					*ppTable = RateSwitchTable11N2SForABand;
-					*pTableSize =
-					    RateSwitchTable11N2SForABand[0];
-					*pInitTxRateIdx =
-					    RateSwitchTable11N2SForABand[1];
-				}
-
-			} else if ((pEntry->RateLen == 4)
-				   && (pEntry->HTCapability.MCSSet[0] == 0)
-				   && (pEntry->HTCapability.MCSSet[1] == 0)
-			    ) {
-				*ppTable = RateSwitchTable11B;
-				*pTableSize = RateSwitchTable11B[0];
-				*pInitTxRateIdx = RateSwitchTable11B[1];
-
-			} else if (pAd->LatchRfRegs.Channel <= 14) {
-				*ppTable = RateSwitchTable11BG;
-				*pTableSize = RateSwitchTable11BG[0];
-				*pInitTxRateIdx = RateSwitchTable11BG[1];
-
-			} else {
-				*ppTable = RateSwitchTable11G;
-				*pTableSize = RateSwitchTable11G[0];
-				*pInitTxRateIdx = RateSwitchTable11G[1];
-
-			}
-			break;
-		}
-		/*if ((pAd->StaActive.SupRateLen + pAd->StaActive.ExtRateLen == 12) && (pAd->StaActive.SupportedPhyInfo.MCSSet[0] == 0xff) && */
-		/*      ((pAd->StaActive.SupportedPhyInfo.MCSSet[1] == 0x00) || (pAd->Antenna.field.TxPath == 1))) */
-		if (((pEntry->RateLen == 12) || (pAd->OpMode == OPMODE_STA)) && (pEntry->HTCapability.MCSSet[0] == 0xff) && ((pEntry->HTCapability.MCSSet[1] == 0x00) || (pAd->CommonCfg.TxStream == 1))) {	/* 11BGN 1S AP */
-			*ppTable = RateSwitchTable11BGN1S;
-			*pTableSize = RateSwitchTable11BGN1S[0];
-			*pInitTxRateIdx = RateSwitchTable11BGN1S[1];
-
-			break;
-		}
-		/*else if ((pAd->StaActive.SupRateLen + pAd->StaActive.ExtRateLen == 12) && (pAd->StaActive.SupportedPhyInfo.MCSSet[0] == 0xff) && */
-		/*      (pAd->StaActive.SupportedPhyInfo.MCSSet[1] == 0xff) && (pAd->Antenna.field.TxPath == 2)) */
-		if (((pEntry->RateLen == 12) || (pAd->OpMode == OPMODE_STA)) && (pEntry->HTCapability.MCSSet[0] == 0xff) && (pEntry->HTCapability.MCSSet[1] == 0xff) && (pAd->CommonCfg.TxStream == 2)) {	/* 11BGN 2S AP */
-			if (pAd->LatchRfRegs.Channel <= 14) {
-				*ppTable = RateSwitchTable11BGN2S;
-				*pTableSize = RateSwitchTable11BGN2S[0];
-				*pInitTxRateIdx = RateSwitchTable11BGN2S[1];
-
-			} else {
-				*ppTable = RateSwitchTable11BGN2SForABand;
-				*pTableSize = RateSwitchTable11BGN2SForABand[0];
-				*pInitTxRateIdx =
-				    RateSwitchTable11BGN2SForABand[1];
-
-			}
-			break;
-		}
-		/*else if ((pAd->StaActive.SupportedPhyInfo.MCSSet[0] == 0xff) && ((pAd->StaActive.SupportedPhyInfo.MCSSet[1] == 0x00) || (pAd->Antenna.field.TxPath == 1))) */
-		if ((pEntry->HTCapability.MCSSet[0] == 0xff) && ((pEntry->HTCapability.MCSSet[1] == 0x00) || (pAd->CommonCfg.TxStream == 1))) {	/* 11N 1S AP */
-			*ppTable = RateSwitchTable11N1S;
-			*pTableSize = RateSwitchTable11N1S[0];
-			*pInitTxRateIdx = RateSwitchTable11N1S[1];
-
-			break;
-		}
-		/*else if ((pAd->StaActive.SupportedPhyInfo.MCSSet[0] == 0xff) && (pAd->StaActive.SupportedPhyInfo.MCSSet[1] == 0xff) && (pAd->Antenna.field.TxPath == 2)) */
-		if ((pEntry->HTCapability.MCSSet[0] == 0xff) && (pEntry->HTCapability.MCSSet[1] == 0xff) && (pAd->CommonCfg.TxStream == 2)) {	/* 11N 2S AP */
-			if (pAd->LatchRfRegs.Channel <= 14) {
-				*ppTable = RateSwitchTable11N2S;
-				*pTableSize = RateSwitchTable11N2S[0];
-				*pInitTxRateIdx = RateSwitchTable11N2S[1];
-			} else {
-				*ppTable = RateSwitchTable11N2SForABand;
-				*pTableSize = RateSwitchTable11N2SForABand[0];
-				*pInitTxRateIdx =
-				    RateSwitchTable11N2SForABand[1];
-			}
-
-			break;
-		}
-		/*else if ((pAd->StaActive.SupRateLen == 4) && (pAd->StaActive.ExtRateLen == 0) && (pAd->StaActive.SupportedPhyInfo.MCSSet[0] == 0) && (pAd->StaActive.SupportedPhyInfo.MCSSet[1] == 0)) */
-		if ((pEntry->RateLen == 4 || pAd->CommonCfg.PhyMode == PHY_11B)
-		    /*Iverson mark for Adhoc b mode,sta will use rate 54  Mbps when connect with sta b/g/n mode */
-		    /* && (pEntry->HTCapability.MCSSet[0] == 0) && (pEntry->HTCapability.MCSSet[1] == 0) */
-		    ) {		/* B only AP */
-			*ppTable = RateSwitchTable11B;
-			*pTableSize = RateSwitchTable11B[0];
-			*pInitTxRateIdx = RateSwitchTable11B[1];
-
-			break;
-		}
-		/*else if ((pAd->StaActive.SupRateLen + pAd->StaActive.ExtRateLen > 8) && (pAd->StaActive.SupportedPhyInfo.MCSSet[0] == 0) && (pAd->StaActive.SupportedPhyInfo.MCSSet[1] == 0)) */
-		if ((pEntry->RateLen > 8)
-		    && (pEntry->HTCapability.MCSSet[0] == 0)
-		    && (pEntry->HTCapability.MCSSet[1] == 0)
-		    ) {		/* B/G  mixed AP */
-			*ppTable = RateSwitchTable11BG;
-			*pTableSize = RateSwitchTable11BG[0];
-			*pInitTxRateIdx = RateSwitchTable11BG[1];
-
-			break;
-		}
-		/*else if ((pAd->StaActive.SupRateLen + pAd->StaActive.ExtRateLen == 8) && (pAd->StaActive.SupportedPhyInfo.MCSSet[0] == 0) && (pAd->StaActive.SupportedPhyInfo.MCSSet[1] == 0)) */
-		if ((pEntry->RateLen == 8)
-		    && (pEntry->HTCapability.MCSSet[0] == 0)
-		    && (pEntry->HTCapability.MCSSet[1] == 0)
-		    ) {		/* G only AP */
-			*ppTable = RateSwitchTable11G;
-			*pTableSize = RateSwitchTable11G[0];
-			*pInitTxRateIdx = RateSwitchTable11G[1];
-
-			break;
-		}
-
-		{
-			/*else if ((pAd->StaActive.SupportedPhyInfo.MCSSet[0] == 0) && (pAd->StaActive.SupportedPhyInfo.MCSSet[1] == 0)) */
-			if ((pEntry->HTCapability.MCSSet[0] == 0) && (pEntry->HTCapability.MCSSet[1] == 0)) {	/* Legacy mode */
-				if (pAd->CommonCfg.MaxTxRate <= RATE_11) {
-					*ppTable = RateSwitchTable11B;
-					*pTableSize = RateSwitchTable11B[0];
-					*pInitTxRateIdx = RateSwitchTable11B[1];
-				} else if ((pAd->CommonCfg.MaxTxRate > RATE_11)
-					   && (pAd->CommonCfg.MinTxRate >
-					       RATE_11)) {
-					*ppTable = RateSwitchTable11G;
-					*pTableSize = RateSwitchTable11G[0];
-					*pInitTxRateIdx = RateSwitchTable11G[1];
-
-				} else {
-					*ppTable = RateSwitchTable11BG;
-					*pTableSize = RateSwitchTable11BG[0];
-					*pInitTxRateIdx =
-					    RateSwitchTable11BG[1];
-				}
-				break;
-			}
-			if (pAd->LatchRfRegs.Channel <= 14) {
-				if (pAd->CommonCfg.TxStream == 1) {
-					*ppTable = RateSwitchTable11N1S;
-					*pTableSize = RateSwitchTable11N1S[0];
-					*pInitTxRateIdx =
-					    RateSwitchTable11N1S[1];
-					DBGPRINT_RAW(RT_DEBUG_ERROR,
-						     ("DRS: unknown mode,default use 11N 1S AP \n"));
-				} else {
-					*ppTable = RateSwitchTable11N2S;
-					*pTableSize = RateSwitchTable11N2S[0];
-					*pInitTxRateIdx =
-					    RateSwitchTable11N2S[1];
-					DBGPRINT_RAW(RT_DEBUG_ERROR,
-						     ("DRS: unknown mode,default use 11N 2S AP \n"));
-				}
-			} else {
-				if (pAd->CommonCfg.TxStream == 1) {
-					*ppTable = RateSwitchTable11N1S;
-					*pTableSize = RateSwitchTable11N1S[0];
-					*pInitTxRateIdx =
-					    RateSwitchTable11N1S[1];
-					DBGPRINT_RAW(RT_DEBUG_ERROR,
-						     ("DRS: unknown mode,default use 11N 1S AP \n"));
-				} else {
-					*ppTable = RateSwitchTable11N2SForABand;
-					*pTableSize =
-					    RateSwitchTable11N2SForABand[0];
-					*pInitTxRateIdx =
-					    RateSwitchTable11N2SForABand[1];
-					DBGPRINT_RAW(RT_DEBUG_ERROR,
-						     ("DRS: unknown mode,default use 11N 2S AP \n"));
-				}
-			}
-			DBGPRINT_RAW(RT_DEBUG_ERROR,
-				     ("DRS: unknown mode (SupRateLen=%d, ExtRateLen=%d, MCSSet[0]=0x%x, MCSSet[1]=0x%x)\n",
-				      pAd->StaActive.SupRateLen,
-				      pAd->StaActive.ExtRateLen,
-				      pAd->StaActive.SupportedPhyInfo.MCSSet[0],
-				      pAd->StaActive.SupportedPhyInfo.
-				      MCSSet[1]));
-		}
-	} while (FALSE);
-}
-
-void STAMlmePeriodicExec(struct rt_rtmp_adapter *pAd)
-{
-	unsigned long TxTotalCnt;
-	int i;
-
-	/*
-	   We return here in ATE mode, because the statistics
-	   that ATE need are not collected via this routine.
-	 */
-#if defined(RT305x)||defined(RT3070)
-	/* request by Gary, if Rssi0 > -42, BBP 82 need to be changed from 0x62 to 0x42, , bbp 67 need to be changed from 0x20 to 0x18 */
-	if (!pAd->CommonCfg.HighPowerPatchDisabled) {
-#ifdef RT3070
-		if ((IS_RT3070(pAd) && ((pAd->MACVersion & 0xffff) < 0x0201)))
-#endif /* RT3070 // */
-		{
-			if ((pAd->StaCfg.RssiSample.AvgRssi0 != 0)
-			    && (pAd->StaCfg.RssiSample.AvgRssi0 >
-				(pAd->BbpRssiToDbmDelta - 35))) {
-				RT30xxWriteRFRegister(pAd, RF_R27, 0x20);
-			} else {
-				RT30xxWriteRFRegister(pAd, RF_R27, 0x23);
-			}
-		}
-	}
-#endif
-#ifdef PCIE_PS_SUPPORT
-/* don't perform idle-power-save mechanism within 3 min after driver initialization. */
-/* This can make rebooter test more robust */
-	if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE)) {
-		if ((pAd->OpMode == OPMODE_STA) && (IDLE_ON(pAd))
-		    && (pAd->Mlme.SyncMachine.CurrState == SYNC_IDLE)
-		    && (pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE)
-		    && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF))) {
-			if (IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd)) {
-				if (pAd->StaCfg.PSControl.field.EnableNewPS ==
-				    TRUE) {
-					DBGPRINT(RT_DEBUG_TRACE,
-						 ("%s\n", __func__));
-					RT28xxPciAsicRadioOff(pAd,
-							      GUI_IDLE_POWER_SAVE,
-							      0);
-				} else {
-					AsicSendCommandToMcu(pAd, 0x30,
-							     PowerSafeCID, 0xff,
-							     0x2);
-					/* Wait command success */
-					AsicCheckCommanOk(pAd, PowerSafeCID);
-					RTMP_SET_FLAG(pAd,
-						      fRTMP_ADAPTER_IDLE_RADIO_OFF);
-					DBGPRINT(RT_DEBUG_TRACE,
-						 ("PSM - rt30xx Issue Sleep command)\n"));
-				}
-			} else if (pAd->Mlme.OneSecPeriodicRound > 180) {
-				if (pAd->StaCfg.PSControl.field.EnableNewPS ==
-				    TRUE) {
-					DBGPRINT(RT_DEBUG_TRACE,
-						 ("%s\n", __func__));
-					RT28xxPciAsicRadioOff(pAd,
-							      GUI_IDLE_POWER_SAVE,
-							      0);
-				} else {
-					AsicSendCommandToMcu(pAd, 0x30,
-							     PowerSafeCID, 0xff,
-							     0x02);
-					/* Wait command success */
-					AsicCheckCommanOk(pAd, PowerSafeCID);
-					RTMP_SET_FLAG(pAd,
-						      fRTMP_ADAPTER_IDLE_RADIO_OFF);
-					DBGPRINT(RT_DEBUG_TRACE,
-						 ("PSM -  rt28xx Issue Sleep command)\n"));
-				}
-			}
-		} else {
-			DBGPRINT(RT_DEBUG_TRACE,
-				 ("STAMlmePeriodicExec MMCHK - CommonCfg.Ssid[%d]=%c%c%c%c... MlmeAux.Ssid[%d]=%c%c%c%c...\n",
-				  pAd->CommonCfg.SsidLen,
-				  pAd->CommonCfg.Ssid[0],
-				  pAd->CommonCfg.Ssid[1],
-				  pAd->CommonCfg.Ssid[2],
-				  pAd->CommonCfg.Ssid[3], pAd->MlmeAux.SsidLen,
-				  pAd->MlmeAux.Ssid[0], pAd->MlmeAux.Ssid[1],
-				  pAd->MlmeAux.Ssid[2], pAd->MlmeAux.Ssid[3]));
-		}
-	}
-#endif /* PCIE_PS_SUPPORT // */
-
-	if (pAd->StaCfg.WpaSupplicantUP == WPA_SUPPLICANT_DISABLE) {
-		/* WPA MIC error should block association attempt for 60 seconds */
-		if (pAd->StaCfg.bBlockAssoc &&
-		    RTMP_TIME_AFTER(pAd->Mlme.Now32,
-				    pAd->StaCfg.LastMicErrorTime +
-				    (60 * OS_HZ)))
-			pAd->StaCfg.bBlockAssoc = FALSE;
-	}
-
-	if ((pAd->PreMediaState != pAd->IndicateMediaState)
-	    && (pAd->CommonCfg.bWirelessEvent)) {
-		if (pAd->IndicateMediaState == NdisMediaStateConnected) {
-			RTMPSendWirelessEvent(pAd, IW_STA_LINKUP_EVENT_FLAG,
-					      pAd->MacTab.Content[BSSID_WCID].
-					      Addr, BSS0, 0);
-		}
-		pAd->PreMediaState = pAd->IndicateMediaState;
-	}
-
-	if (pAd->CommonCfg.PSPXlink && ADHOC_ON(pAd)) {
-	} else {
-		AsicStaBbpTuning(pAd);
-	}
-
-	TxTotalCnt = pAd->RalinkCounters.OneSecTxNoRetryOkCount +
-	    pAd->RalinkCounters.OneSecTxRetryOkCount +
-	    pAd->RalinkCounters.OneSecTxFailCount;
-
-	if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED)) {
-		/* update channel quality for Roaming and UI LinkQuality display */
-		MlmeCalculateChannelQuality(pAd, NULL, pAd->Mlme.Now32);
-	}
-	/* must be AFTER MlmeDynamicTxRateSwitching() because it needs to know if */
-	/* Radio is currently in noisy environment */
-	if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
-		AsicAdjustTxPower(pAd);
-
-	if (INFRA_ON(pAd)) {
-
-		/* Is PSM bit consistent with user power management policy? */
-		/* This is the only place that will set PSM bit ON. */
-		if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
-			MlmeCheckPsmChange(pAd, pAd->Mlme.Now32);
-
-		pAd->RalinkCounters.LastOneSecTotalTxCount = TxTotalCnt;
-
-		if ((RTMP_TIME_AFTER
-		     (pAd->Mlme.Now32,
-		      pAd->StaCfg.LastBeaconRxTime + (1 * OS_HZ)))
-		    &&
-		    (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
-		    &&
-		    (((TxTotalCnt + pAd->RalinkCounters.OneSecRxOkCnt) <
-		      600))) {
-			RTMPSetAGCInitValue(pAd, BW_20);
-			DBGPRINT(RT_DEBUG_TRACE,
-				 ("MMCHK - No BEACON. restore R66 to the low bound(%d) \n",
-				  (0x2E + GET_LNA_GAIN(pAd))));
-		}
-		/*if ((pAd->RalinkCounters.OneSecTxNoRetryOkCount == 0) && */
-		/*    (pAd->RalinkCounters.OneSecTxRetryOkCount == 0)) */
-		{
-			if (pAd->CommonCfg.bAPSDCapable
-			    && pAd->CommonCfg.APEdcaParm.bAPSDCapable) {
-				/* When APSD is enabled, the period changes as 20 sec */
-				if ((pAd->Mlme.OneSecPeriodicRound % 20) == 8)
-					RTMPSendNullFrame(pAd,
-							  pAd->CommonCfg.TxRate,
-							  TRUE);
-			} else {
-				/* Send out a NULL frame every 10 sec to inform AP that STA is still alive (Avoid being age out) */
-				if ((pAd->Mlme.OneSecPeriodicRound % 10) == 8) {
-					if (pAd->CommonCfg.bWmmCapable)
-						RTMPSendNullFrame(pAd,
-								  pAd->
-								  CommonCfg.
-								  TxRate, TRUE);
-					else
-						RTMPSendNullFrame(pAd,
-								  pAd->
-								  CommonCfg.
-								  TxRate,
-								  FALSE);
-				}
-			}
-		}
-
-		if (CQI_IS_DEAD(pAd->Mlme.ChannelQuality)) {
-			DBGPRINT(RT_DEBUG_TRACE,
-				 ("MMCHK - No BEACON. Dead CQI. Auto Recovery attempt #%ld\n",
-				  pAd->RalinkCounters.BadCQIAutoRecoveryCount));
-
-			/* Lost AP, send disconnect & link down event */
-			LinkDown(pAd, FALSE);
-
-			RtmpOSWrielessEventSend(pAd, SIOCGIWAP, -1, NULL, NULL,
-						0);
-
-			/* RTMPPatchMacBbpBug(pAd); */
-			MlmeAutoReconnectLastSSID(pAd);
-		} else if (CQI_IS_BAD(pAd->Mlme.ChannelQuality)) {
-			pAd->RalinkCounters.BadCQIAutoRecoveryCount++;
-			DBGPRINT(RT_DEBUG_TRACE,
-				 ("MMCHK - Bad CQI. Auto Recovery attempt #%ld\n",
-				  pAd->RalinkCounters.BadCQIAutoRecoveryCount));
-			MlmeAutoReconnectLastSSID(pAd);
-		}
-
-		if (pAd->StaCfg.bAutoRoaming) {
-			BOOLEAN rv = FALSE;
-			char dBmToRoam = pAd->StaCfg.dBmToRoam;
-			char MaxRssi = RTMPMaxRssi(pAd,
-						   pAd->StaCfg.RssiSample.
-						   LastRssi0,
-						   pAd->StaCfg.RssiSample.
-						   LastRssi1,
-						   pAd->StaCfg.RssiSample.
-						   LastRssi2);
-
-			/* Scanning, ignore Roaming */
-			if (!RTMP_TEST_FLAG
-			    (pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)
-			    && (pAd->Mlme.SyncMachine.CurrState == SYNC_IDLE)
-			    && (MaxRssi <= dBmToRoam)) {
-				DBGPRINT(RT_DEBUG_TRACE,
-					 ("Rssi=%d, dBmToRoam=%d\n", MaxRssi,
-					  (char)dBmToRoam));
-
-				/* Add auto seamless roaming */
-				if (rv == FALSE)
-					rv = MlmeCheckForFastRoaming(pAd);
-
-				if (rv == FALSE) {
-					if ((pAd->StaCfg.LastScanTime +
-					     10 * OS_HZ) < pAd->Mlme.Now32) {
-						DBGPRINT(RT_DEBUG_TRACE,
-							 ("MMCHK - Roaming, No eligible entry, try new scan!\n"));
-						pAd->StaCfg.ScanCnt = 2;
-						pAd->StaCfg.LastScanTime =
-						    pAd->Mlme.Now32;
-						MlmeAutoScan(pAd);
-					}
-				}
-			}
-		}
-	} else if (ADHOC_ON(pAd)) {
-		/* If all peers leave, and this STA becomes the last one in this IBSS, then change MediaState */
-		/* to DISCONNECTED. But still holding this IBSS (i.e. sending BEACON) so that other STAs can */
-		/* join later. */
-		if (RTMP_TIME_AFTER
-		    (pAd->Mlme.Now32,
-		     pAd->StaCfg.LastBeaconRxTime + ADHOC_BEACON_LOST_TIME)
-		    && OPSTATUS_TEST_FLAG(pAd,
-					  fOP_STATUS_MEDIA_STATE_CONNECTED)) {
-			struct rt_mlme_start_req StartReq;
-
-			DBGPRINT(RT_DEBUG_TRACE,
-				 ("MMCHK - excessive BEACON lost, last STA in this IBSS, MediaState=Disconnected\n"));
-			LinkDown(pAd, FALSE);
-
-			StartParmFill(pAd, &StartReq,
-				      (char *) pAd->MlmeAux.Ssid,
-				      pAd->MlmeAux.SsidLen);
-			MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_START_REQ,
-				    sizeof(struct rt_mlme_start_req), &StartReq);
-			pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_START;
-		}
-
-		for (i = 1; i < MAX_LEN_OF_MAC_TABLE; i++) {
-			struct rt_mac_table_entry *pEntry = &pAd->MacTab.Content[i];
-
-			if (pEntry->ValidAsCLI == FALSE)
-				continue;
-
-			if (RTMP_TIME_AFTER
-			    (pAd->Mlme.Now32,
-			     pEntry->LastBeaconRxTime + ADHOC_BEACON_LOST_TIME))
-				MacTableDeleteEntry(pAd, pEntry->Aid,
-						    pEntry->Addr);
-		}
-	} else			/* no INFRA nor ADHOC connection */
-	{
-
-		if (pAd->StaCfg.bScanReqIsFromWebUI &&
-		    RTMP_TIME_BEFORE(pAd->Mlme.Now32,
-				     pAd->StaCfg.LastScanTime + (30 * OS_HZ)))
-			goto SKIP_AUTO_SCAN_CONN;
-		else
-			pAd->StaCfg.bScanReqIsFromWebUI = FALSE;
-
-		if ((pAd->StaCfg.bAutoReconnect == TRUE)
-		    && RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_START_UP)
-		    &&
-		    (MlmeValidateSSID
-		     (pAd->MlmeAux.AutoReconnectSsid,
-		      pAd->MlmeAux.AutoReconnectSsidLen) == TRUE)) {
-			if ((pAd->ScanTab.BssNr == 0)
-			    && (pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE)) {
-				struct rt_mlme_scan_req ScanReq;
-
-				if (RTMP_TIME_AFTER
-				    (pAd->Mlme.Now32,
-				     pAd->StaCfg.LastScanTime + (10 * OS_HZ))) {
-					DBGPRINT(RT_DEBUG_TRACE,
-						 ("STAMlmePeriodicExec():CNTL - ScanTab.BssNr==0, start a new ACTIVE scan SSID[%s]\n",
-						  pAd->MlmeAux.
-						  AutoReconnectSsid));
-					ScanParmFill(pAd, &ScanReq,
-						     (char *)pAd->MlmeAux.
-						     AutoReconnectSsid,
-						     pAd->MlmeAux.
-						     AutoReconnectSsidLen,
-						     BSS_ANY, SCAN_ACTIVE);
-					MlmeEnqueue(pAd, SYNC_STATE_MACHINE,
-						    MT2_MLME_SCAN_REQ,
-						    sizeof
-						    (struct rt_mlme_scan_req),
-						    &ScanReq);
-					pAd->Mlme.CntlMachine.CurrState =
-					    CNTL_WAIT_OID_LIST_SCAN;
-					/* Reset Missed scan number */
-					pAd->StaCfg.LastScanTime =
-					    pAd->Mlme.Now32;
-				} else if (pAd->StaCfg.BssType == BSS_ADHOC)	/* Quit the forever scan when in a very clean room */
-					MlmeAutoReconnectLastSSID(pAd);
-			} else if (pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE) {
-				if ((pAd->Mlme.OneSecPeriodicRound % 7) == 0) {
-					MlmeAutoScan(pAd);
-					pAd->StaCfg.LastScanTime =
-					    pAd->Mlme.Now32;
-				} else {
-					MlmeAutoReconnectLastSSID(pAd);
-				}
-			}
-		}
-	}
-
-SKIP_AUTO_SCAN_CONN:
-
-	if ((pAd->MacTab.Content[BSSID_WCID].TXBAbitmap != 0)
-	    && (pAd->MacTab.fAnyBASession == FALSE)) {
-		pAd->MacTab.fAnyBASession = TRUE;
-		AsicUpdateProtect(pAd, HT_FORCERTSCTS, ALLN_SETPROTECT, FALSE,
-				  FALSE);
-	} else if ((pAd->MacTab.Content[BSSID_WCID].TXBAbitmap == 0)
-		   && (pAd->MacTab.fAnyBASession == TRUE)) {
-		pAd->MacTab.fAnyBASession = FALSE;
-		AsicUpdateProtect(pAd,
-				  pAd->MlmeAux.AddHtInfo.AddHtInfo2.
-				  OperaionMode, ALLN_SETPROTECT, FALSE, FALSE);
-	}
-
-	return;
-}
-
-/* Link down report */
-void LinkDownExec(void *SystemSpecific1,
-		  void *FunctionContext,
-		  void *SystemSpecific2, void *SystemSpecific3)
-{
-	struct rt_rtmp_adapter *pAd = (struct rt_rtmp_adapter *)FunctionContext;
-
-	if (pAd != NULL) {
-		struct rt_mlme_disassoc_req DisassocReq;
-
-		if ((pAd->StaCfg.PortSecured == WPA_802_1X_PORT_NOT_SECURED) &&
-		    (INFRA_ON(pAd))) {
-			DBGPRINT(RT_DEBUG_TRACE,
-				 ("LinkDownExec(): disassociate with current AP...\n"));
-			DisassocParmFill(pAd, &DisassocReq,
-					 pAd->CommonCfg.Bssid,
-					 REASON_DISASSOC_STA_LEAVING);
-			MlmeEnqueue(pAd, ASSOC_STATE_MACHINE,
-				    MT2_MLME_DISASSOC_REQ,
-				    sizeof(struct rt_mlme_disassoc_req),
-				    &DisassocReq);
-			pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_DISASSOC;
-
-			pAd->IndicateMediaState = NdisMediaStateDisconnected;
-			RTMP_IndicateMediaState(pAd);
-			pAd->ExtraInfo = GENERAL_LINK_DOWN;
-		}
-	}
-}
-
-/* IRQL = DISPATCH_LEVEL */
-void MlmeAutoScan(struct rt_rtmp_adapter *pAd)
-{
-	/* check CntlMachine.CurrState to avoid collision with NDIS SetOID request */
-	if (pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE) {
-		DBGPRINT(RT_DEBUG_TRACE, ("MMCHK - Driver auto scan\n"));
-		MlmeEnqueue(pAd,
-			    MLME_CNTL_STATE_MACHINE,
-			    OID_802_11_BSSID_LIST_SCAN,
-			    pAd->MlmeAux.AutoReconnectSsidLen,
-			    pAd->MlmeAux.AutoReconnectSsid);
-		RTMP_MLME_HANDLER(pAd);
-	}
-}
-
-/* IRQL = DISPATCH_LEVEL */
-void MlmeAutoReconnectLastSSID(struct rt_rtmp_adapter *pAd)
-{
-	if (pAd->StaCfg.bAutoConnectByBssid) {
-		DBGPRINT(RT_DEBUG_TRACE,
-			("Driver auto reconnect to last OID_802_11_BSSID "
-				"setting - %pM\n", pAd->MlmeAux.Bssid));
-
-		pAd->MlmeAux.Channel = pAd->CommonCfg.Channel;
-		MlmeEnqueue(pAd,
-			    MLME_CNTL_STATE_MACHINE,
-			    OID_802_11_BSSID, MAC_ADDR_LEN, pAd->MlmeAux.Bssid);
-
-		pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
-
-		RTMP_MLME_HANDLER(pAd);
-	}
-	/* check CntlMachine.CurrState to avoid collision with NDIS SetOID request */
-	else if ((pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE) &&
-		 (MlmeValidateSSID
-		  (pAd->MlmeAux.AutoReconnectSsid,
-		   pAd->MlmeAux.AutoReconnectSsidLen) == TRUE)) {
-		struct rt_ndis_802_11_ssid OidSsid;
-		OidSsid.SsidLength = pAd->MlmeAux.AutoReconnectSsidLen;
-		NdisMoveMemory(OidSsid.Ssid, pAd->MlmeAux.AutoReconnectSsid,
-			       pAd->MlmeAux.AutoReconnectSsidLen);
-
-		DBGPRINT(RT_DEBUG_TRACE,
-			 ("Driver auto reconnect to last OID_802_11_SSID setting - %s, len - %d\n",
-			  pAd->MlmeAux.AutoReconnectSsid,
-			  pAd->MlmeAux.AutoReconnectSsidLen));
-		MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, OID_802_11_SSID,
-			    sizeof(struct rt_ndis_802_11_ssid), &OidSsid);
-		RTMP_MLME_HANDLER(pAd);
-	}
-}
-
-/*
-	==========================================================================
-	Description:
-		This routine checks if there're other APs out there capable for
-		roaming. Caller should call this routine only when Link up in INFRA mode
-		and channel quality is below CQI_GOOD_THRESHOLD.
-
-	IRQL = DISPATCH_LEVEL
-
-	Output:
-	==========================================================================
- */
-void MlmeCheckForRoaming(struct rt_rtmp_adapter *pAd, unsigned long Now32)
-{
-	u16 i;
-	struct rt_bss_table *pRoamTab = &pAd->MlmeAux.RoamTab;
-	struct rt_bss_entry *pBss;
-
-	DBGPRINT(RT_DEBUG_TRACE, ("==> MlmeCheckForRoaming\n"));
-	/* put all roaming candidates into RoamTab, and sort in RSSI order */
-	BssTableInit(pRoamTab);
-	for (i = 0; i < pAd->ScanTab.BssNr; i++) {
-		pBss = &pAd->ScanTab.BssEntry[i];
-
-		if ((pBss->LastBeaconRxTime + pAd->StaCfg.BeaconLostTime) <
-		    Now32)
-			continue;	/* AP disappear */
-		if (pBss->Rssi <= RSSI_THRESHOLD_FOR_ROAMING)
-			continue;	/* RSSI too weak. forget it. */
-		if (MAC_ADDR_EQUAL(pBss->Bssid, pAd->CommonCfg.Bssid))
-			continue;	/* skip current AP */
-		if (pBss->Rssi <
-		    (pAd->StaCfg.RssiSample.LastRssi0 + RSSI_DELTA))
-			continue;	/* only AP with stronger RSSI is eligible for roaming */
-
-		/* AP passing all above rules is put into roaming candidate table */
-		NdisMoveMemory(&pRoamTab->BssEntry[pRoamTab->BssNr], pBss,
-			       sizeof(struct rt_bss_entry));
-		pRoamTab->BssNr += 1;
-	}
-
-	if (pRoamTab->BssNr > 0) {
-		/* check CntlMachine.CurrState to avoid collision with NDIS SetOID request */
-		if (pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE) {
-			pAd->RalinkCounters.PoorCQIRoamingCount++;
-			DBGPRINT(RT_DEBUG_TRACE,
-				 ("MMCHK - Roaming attempt #%ld\n",
-				  pAd->RalinkCounters.PoorCQIRoamingCount));
-			MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE,
-				    MT2_MLME_ROAMING_REQ, 0, NULL);
-			RTMP_MLME_HANDLER(pAd);
-		}
-	}
-	DBGPRINT(RT_DEBUG_TRACE,
-		 ("<== MlmeCheckForRoaming(# of candidate= %d)\n",
-		  pRoamTab->BssNr));
-}
-
-/*
-	==========================================================================
-	Description:
-		This routine checks if there're other APs out there capable for
-		roaming. Caller should call this routine only when link up in INFRA mode
-		and channel quality is below CQI_GOOD_THRESHOLD.
-
-	IRQL = DISPATCH_LEVEL
-
-	Output:
-	==========================================================================
- */
-BOOLEAN MlmeCheckForFastRoaming(struct rt_rtmp_adapter *pAd)
-{
-	u16 i;
-	struct rt_bss_table *pRoamTab = &pAd->MlmeAux.RoamTab;
-	struct rt_bss_entry *pBss;
-
-	DBGPRINT(RT_DEBUG_TRACE, ("==> MlmeCheckForFastRoaming\n"));
-	/* put all roaming candidates into RoamTab, and sort in RSSI order */
-	BssTableInit(pRoamTab);
-	for (i = 0; i < pAd->ScanTab.BssNr; i++) {
-		pBss = &pAd->ScanTab.BssEntry[i];
-
-		if ((pBss->Rssi <= -50)
-		    && (pBss->Channel == pAd->CommonCfg.Channel))
-			continue;	/* RSSI too weak. forget it. */
-		if (MAC_ADDR_EQUAL(pBss->Bssid, pAd->CommonCfg.Bssid))
-			continue;	/* skip current AP */
-		if (!SSID_EQUAL
-		    (pBss->Ssid, pBss->SsidLen, pAd->CommonCfg.Ssid,
-		     pAd->CommonCfg.SsidLen))
-			continue;	/* skip different SSID */
-		if (pBss->Rssi <
-		    (RTMPMaxRssi
-		     (pAd, pAd->StaCfg.RssiSample.LastRssi0,
-		      pAd->StaCfg.RssiSample.LastRssi1,
-		      pAd->StaCfg.RssiSample.LastRssi2) + RSSI_DELTA))
-			continue;	/* skip AP without better RSSI */
-
-		DBGPRINT(RT_DEBUG_TRACE,
-			 ("LastRssi0 = %d, pBss->Rssi = %d\n",
-			  RTMPMaxRssi(pAd, pAd->StaCfg.RssiSample.LastRssi0,
-				      pAd->StaCfg.RssiSample.LastRssi1,
-				      pAd->StaCfg.RssiSample.LastRssi2),
-			  pBss->Rssi));
-		/* AP passing all above rules is put into roaming candidate table */
-		NdisMoveMemory(&pRoamTab->BssEntry[pRoamTab->BssNr], pBss,
-			       sizeof(struct rt_bss_entry));
-		pRoamTab->BssNr += 1;
-	}
-
-	DBGPRINT(RT_DEBUG_TRACE,
-		 ("<== MlmeCheckForFastRoaming (BssNr=%d)\n", pRoamTab->BssNr));
-	if (pRoamTab->BssNr > 0) {
-		/* check CntlMachine.CurrState to avoid collision with NDIS SetOID request */
-		if (pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE) {
-			pAd->RalinkCounters.PoorCQIRoamingCount++;
-			DBGPRINT(RT_DEBUG_TRACE,
-				 ("MMCHK - Roaming attempt #%ld\n",
-				  pAd->RalinkCounters.PoorCQIRoamingCount));
-			MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE,
-				    MT2_MLME_ROAMING_REQ, 0, NULL);
-			RTMP_MLME_HANDLER(pAd);
-			return TRUE;
-		}
-	}
-
-	return FALSE;
-}
-
-void MlmeSetTxRate(struct rt_rtmp_adapter *pAd,
-		   struct rt_mac_table_entry *pEntry, struct rt_rtmp_tx_rate_switch * pTxRate)
-{
-	u8 MaxMode = MODE_OFDM;
-
-	MaxMode = MODE_HTGREENFIELD;
-
-	if (pTxRate->STBC && (pAd->StaCfg.MaxHTPhyMode.field.STBC)
-	    && (pAd->Antenna.field.TxPath == 2))
-		pAd->StaCfg.HTPhyMode.field.STBC = STBC_USE;
-	else
-		pAd->StaCfg.HTPhyMode.field.STBC = STBC_NONE;
-
-	if (pTxRate->CurrMCS < MCS_AUTO)
-		pAd->StaCfg.HTPhyMode.field.MCS = pTxRate->CurrMCS;
-
-	if (pAd->StaCfg.HTPhyMode.field.MCS > 7)
-		pAd->StaCfg.HTPhyMode.field.STBC = STBC_NONE;
-
-	if (ADHOC_ON(pAd)) {
-		/* If peer adhoc is b-only mode, we can't send 11g rate. */
-		pAd->StaCfg.HTPhyMode.field.ShortGI = GI_800;
-		pEntry->HTPhyMode.field.STBC = STBC_NONE;
-
-		/* */
-		/* For Adhoc MODE_CCK, driver will use AdhocBOnlyJoined flag to roll back to B only if necessary */
-		/* */
-		pEntry->HTPhyMode.field.MODE = pTxRate->Mode;
-		pEntry->HTPhyMode.field.ShortGI =
-		    pAd->StaCfg.HTPhyMode.field.ShortGI;
-		pEntry->HTPhyMode.field.MCS = pAd->StaCfg.HTPhyMode.field.MCS;
-
-		/* Patch speed error in status page */
-		pAd->StaCfg.HTPhyMode.field.MODE = pEntry->HTPhyMode.field.MODE;
-	} else {
-		if (pTxRate->Mode <= MaxMode)
-			pAd->StaCfg.HTPhyMode.field.MODE = pTxRate->Mode;
-
-		if (pTxRate->ShortGI
-		    && (pAd->StaCfg.MaxHTPhyMode.field.ShortGI))
-			pAd->StaCfg.HTPhyMode.field.ShortGI = GI_400;
-		else
-			pAd->StaCfg.HTPhyMode.field.ShortGI = GI_800;
-
-		/* Reexam each bandwidth's SGI support. */
-		if (pAd->StaCfg.HTPhyMode.field.ShortGI == GI_400) {
-			if ((pEntry->HTPhyMode.field.BW == BW_20)
-			    &&
-			    (!CLIENT_STATUS_TEST_FLAG
-			     (pEntry, fCLIENT_STATUS_SGI20_CAPABLE)))
-				pAd->StaCfg.HTPhyMode.field.ShortGI = GI_800;
-			if ((pEntry->HTPhyMode.field.BW == BW_40)
-			    &&
-			    (!CLIENT_STATUS_TEST_FLAG
-			     (pEntry, fCLIENT_STATUS_SGI40_CAPABLE)))
-				pAd->StaCfg.HTPhyMode.field.ShortGI = GI_800;
-		}
-		/* Turn RTS/CTS rate to 6Mbps. */
-		if ((pEntry->HTPhyMode.field.MCS == 0)
-		    && (pAd->StaCfg.HTPhyMode.field.MCS != 0)) {
-			pEntry->HTPhyMode.field.MCS =
-			    pAd->StaCfg.HTPhyMode.field.MCS;
-			if (pAd->MacTab.fAnyBASession) {
-				AsicUpdateProtect(pAd, HT_FORCERTSCTS,
-						  ALLN_SETPROTECT, TRUE,
-						  (BOOLEAN) pAd->MlmeAux.
-						  AddHtInfo.AddHtInfo2.
-						  NonGfPresent);
-			} else {
-				AsicUpdateProtect(pAd,
-						  pAd->MlmeAux.AddHtInfo.
-						  AddHtInfo2.OperaionMode,
-						  ALLN_SETPROTECT, TRUE,
-						  (BOOLEAN) pAd->MlmeAux.
-						  AddHtInfo.AddHtInfo2.
-						  NonGfPresent);
-			}
-		} else if ((pEntry->HTPhyMode.field.MCS == 8)
-			   && (pAd->StaCfg.HTPhyMode.field.MCS != 8)) {
-			pEntry->HTPhyMode.field.MCS =
-			    pAd->StaCfg.HTPhyMode.field.MCS;
-			if (pAd->MacTab.fAnyBASession) {
-				AsicUpdateProtect(pAd, HT_FORCERTSCTS,
-						  ALLN_SETPROTECT, TRUE,
-						  (BOOLEAN) pAd->MlmeAux.
-						  AddHtInfo.AddHtInfo2.
-						  NonGfPresent);
-			} else {
-				AsicUpdateProtect(pAd,
-						  pAd->MlmeAux.AddHtInfo.
-						  AddHtInfo2.OperaionMode,
-						  ALLN_SETPROTECT, TRUE,
-						  (BOOLEAN) pAd->MlmeAux.
-						  AddHtInfo.AddHtInfo2.
-						  NonGfPresent);
-			}
-		} else if ((pEntry->HTPhyMode.field.MCS != 0)
-			   && (pAd->StaCfg.HTPhyMode.field.MCS == 0)) {
-			AsicUpdateProtect(pAd, HT_RTSCTS_6M, ALLN_SETPROTECT,
-					  TRUE,
-					  (BOOLEAN) pAd->MlmeAux.AddHtInfo.
-					  AddHtInfo2.NonGfPresent);
-
-		} else if ((pEntry->HTPhyMode.field.MCS != 8)
-			   && (pAd->StaCfg.HTPhyMode.field.MCS == 8)) {
-			AsicUpdateProtect(pAd, HT_RTSCTS_6M, ALLN_SETPROTECT,
-					  TRUE,
-					  (BOOLEAN) pAd->MlmeAux.AddHtInfo.
-					  AddHtInfo2.NonGfPresent);
-		}
-
-		pEntry->HTPhyMode.field.STBC = pAd->StaCfg.HTPhyMode.field.STBC;
-		pEntry->HTPhyMode.field.ShortGI =
-		    pAd->StaCfg.HTPhyMode.field.ShortGI;
-		pEntry->HTPhyMode.field.MCS = pAd->StaCfg.HTPhyMode.field.MCS;
-		pEntry->HTPhyMode.field.MODE = pAd->StaCfg.HTPhyMode.field.MODE;
-		if ((pAd->StaCfg.MaxHTPhyMode.field.MODE == MODE_HTGREENFIELD)
-		    && pAd->WIFItestbed.bGreenField)
-			pEntry->HTPhyMode.field.MODE = MODE_HTGREENFIELD;
-	}
-
-	pAd->LastTxRate = (u16)(pEntry->HTPhyMode.word);
-}
-
-/*
-	==========================================================================
-	Description:
-		This routine calculates the acumulated TxPER of eaxh TxRate. And
-		according to the calculation result, change CommonCfg.TxRate which
-		is the stable TX Rate we expect the Radio situation could sustained.
-
-		CommonCfg.TxRate will change dynamically within {RATE_1/RATE_6, MaxTxRate}
-	Output:
-		CommonCfg.TxRate -
-
-	IRQL = DISPATCH_LEVEL
-
-	NOTE:
-		call this routine every second
-	==========================================================================
- */
-void MlmeDynamicTxRateSwitching(struct rt_rtmp_adapter *pAd)
-{
-	u8 UpRateIdx = 0, DownRateIdx = 0, CurrRateIdx;
-	unsigned long i, AccuTxTotalCnt = 0, TxTotalCnt;
-	unsigned long TxErrorRatio = 0;
-	BOOLEAN bTxRateChanged = FALSE, bUpgradeQuality = FALSE;
-	struct rt_rtmp_tx_rate_switch *pCurrTxRate, *pNextTxRate = NULL;
-	u8 *pTable;
-	u8 TableSize = 0;
-	u8 InitTxRateIdx = 0, TrainUp, TrainDown;
-	char Rssi, RssiOffset = 0;
-	TX_STA_CNT1_STRUC StaTx1;
-	TX_STA_CNT0_STRUC TxStaCnt0;
-	unsigned long TxRetransmit = 0, TxSuccess = 0, TxFailCount = 0;
-	struct rt_mac_table_entry *pEntry;
-	struct rt_rssi_sample *pRssi = &pAd->StaCfg.RssiSample;
-
-	/* */
-	/* walk through MAC table, see if need to change AP's TX rate toward each entry */
-	/* */
-	for (i = 1; i < MAX_LEN_OF_MAC_TABLE; i++) {
-		pEntry = &pAd->MacTab.Content[i];
-
-		/* check if this entry need to switch rate automatically */
-		if (RTMPCheckEntryEnableAutoRateSwitch(pAd, pEntry) == FALSE)
-			continue;
-
-		if ((pAd->MacTab.Size == 1) || (pEntry->ValidAsDls)) {
-			Rssi = RTMPMaxRssi(pAd,
-					   pRssi->AvgRssi0,
-					   pRssi->AvgRssi1, pRssi->AvgRssi2);
-
-			/* Update statistic counter */
-			RTMP_IO_READ32(pAd, TX_STA_CNT0, &TxStaCnt0.word);
-			RTMP_IO_READ32(pAd, TX_STA_CNT1, &StaTx1.word);
-			pAd->bUpdateBcnCntDone = TRUE;
-			TxRetransmit = StaTx1.field.TxRetransmit;
-			TxSuccess = StaTx1.field.TxSuccess;
-			TxFailCount = TxStaCnt0.field.TxFailCount;
-			TxTotalCnt = TxRetransmit + TxSuccess + TxFailCount;
-
-			pAd->RalinkCounters.OneSecTxRetryOkCount +=
-			    StaTx1.field.TxRetransmit;
-			pAd->RalinkCounters.OneSecTxNoRetryOkCount +=
-			    StaTx1.field.TxSuccess;
-			pAd->RalinkCounters.OneSecTxFailCount +=
-			    TxStaCnt0.field.TxFailCount;
-			pAd->WlanCounters.TransmittedFragmentCount.u.LowPart +=
-			    StaTx1.field.TxSuccess;
-			pAd->WlanCounters.RetryCount.u.LowPart +=
-			    StaTx1.field.TxRetransmit;
-			pAd->WlanCounters.FailedCount.u.LowPart +=
-			    TxStaCnt0.field.TxFailCount;
-
-			/* if no traffic in the past 1-sec period, don't change TX rate, */
-			/* but clear all bad history. because the bad history may affect the next */
-			/* Chariot throughput test */
-			AccuTxTotalCnt =
-			    pAd->RalinkCounters.OneSecTxNoRetryOkCount +
-			    pAd->RalinkCounters.OneSecTxRetryOkCount +
-			    pAd->RalinkCounters.OneSecTxFailCount;
-
-			if (TxTotalCnt)
-				TxErrorRatio =
-				    ((TxRetransmit +
-				      TxFailCount) * 100) / TxTotalCnt;
-		} else {
-			if (INFRA_ON(pAd) && (i == 1))
-				Rssi = RTMPMaxRssi(pAd,
-						   pRssi->AvgRssi0,
-						   pRssi->AvgRssi1,
-						   pRssi->AvgRssi2);
-			else
-				Rssi = RTMPMaxRssi(pAd,
-						   pEntry->RssiSample.AvgRssi0,
-						   pEntry->RssiSample.AvgRssi1,
-						   pEntry->RssiSample.AvgRssi2);
-
-			TxTotalCnt = pEntry->OneSecTxNoRetryOkCount +
-			    pEntry->OneSecTxRetryOkCount +
-			    pEntry->OneSecTxFailCount;
-
-			if (TxTotalCnt)
-				TxErrorRatio =
-				    ((pEntry->OneSecTxRetryOkCount +
-				      pEntry->OneSecTxFailCount) * 100) /
-				    TxTotalCnt;
-		}
-
-		if (TxTotalCnt) {
-			/*
-			   Three AdHoc connections can not work normally if one AdHoc connection is disappeared from a heavy traffic environment generated by ping tool
-			   We force to set LongRtyLimit and ShortRtyLimit to 0 to stop retransmitting packet, after a while, resoring original settings
-			 */
-			if (TxErrorRatio == 100) {
-				TX_RTY_CFG_STRUC TxRtyCfg, TxRtyCfgtmp;
-				unsigned long Index;
-				unsigned long MACValue;
-
-				RTMP_IO_READ32(pAd, TX_RTY_CFG, &TxRtyCfg.word);
-				TxRtyCfgtmp.word = TxRtyCfg.word;
-				TxRtyCfg.field.LongRtyLimit = 0x0;
-				TxRtyCfg.field.ShortRtyLimit = 0x0;
-				RTMP_IO_WRITE32(pAd, TX_RTY_CFG, TxRtyCfg.word);
-
-				RTMPusecDelay(1);
-
-				Index = 0;
-				MACValue = 0;
-				do {
-					RTMP_IO_READ32(pAd, TXRXQ_PCNT,
-						       &MACValue);
-					if ((MACValue & 0xffffff) == 0)
-						break;
-					Index++;
-					RTMPusecDelay(1000);
-				} while ((Index < 330)
-					 &&
-					 (!RTMP_TEST_FLAG
-					  (pAd,
-					   fRTMP_ADAPTER_HALT_IN_PROGRESS)));
-
-				RTMP_IO_READ32(pAd, TX_RTY_CFG, &TxRtyCfg.word);
-				TxRtyCfg.field.LongRtyLimit =
-				    TxRtyCfgtmp.field.LongRtyLimit;
-				TxRtyCfg.field.ShortRtyLimit =
-				    TxRtyCfgtmp.field.ShortRtyLimit;
-				RTMP_IO_WRITE32(pAd, TX_RTY_CFG, TxRtyCfg.word);
-			}
-		}
-
-		CurrRateIdx = pEntry->CurrTxRateIndex;
-
-		MlmeSelectTxRateTable(pAd, pEntry, &pTable, &TableSize,
-				      &InitTxRateIdx);
-
-		if (CurrRateIdx >= TableSize) {
-			CurrRateIdx = TableSize - 1;
-		}
-		/* When switch from Fixed rate -> auto rate, the REAL TX rate might be different from pAd->CommonCfg.TxRateIndex. */
-		/* So need to sync here. */
-		pCurrTxRate =
-		    (struct rt_rtmp_tx_rate_switch *) & pTable[(CurrRateIdx + 1) * 5];
-		if ((pEntry->HTPhyMode.field.MCS != pCurrTxRate->CurrMCS)
-		    /*&& (pAd->StaCfg.bAutoTxRateSwitch == TRUE) */
-		    ) {
-
-			/* Need to sync Real Tx rate and our record. */
-			/* Then return for next DRS. */
-			pCurrTxRate =
-			    (struct rt_rtmp_tx_rate_switch *) & pTable[(InitTxRateIdx + 1)
-							    * 5];
-			pEntry->CurrTxRateIndex = InitTxRateIdx;
-			MlmeSetTxRate(pAd, pEntry, pCurrTxRate);
-
-			/* reset all OneSecTx counters */
-			RESET_ONE_SEC_TX_CNT(pEntry);
-			continue;
-		}
-		/* decide the next upgrade rate and downgrade rate, if any */
-		if ((CurrRateIdx > 0) && (CurrRateIdx < (TableSize - 1))) {
-			UpRateIdx = CurrRateIdx + 1;
-			DownRateIdx = CurrRateIdx - 1;
-		} else if (CurrRateIdx == 0) {
-			UpRateIdx = CurrRateIdx + 1;
-			DownRateIdx = CurrRateIdx;
-		} else if (CurrRateIdx == (TableSize - 1)) {
-			UpRateIdx = CurrRateIdx;
-			DownRateIdx = CurrRateIdx - 1;
-		}
-
-		pCurrTxRate =
-		    (struct rt_rtmp_tx_rate_switch *) & pTable[(CurrRateIdx + 1) * 5];
-
-		if ((Rssi > -65) && (pCurrTxRate->Mode >= MODE_HTMIX)) {
-			TrainUp =
-			    (pCurrTxRate->TrainUp +
-			     (pCurrTxRate->TrainUp >> 1));
-			TrainDown =
-			    (pCurrTxRate->TrainDown +
-			     (pCurrTxRate->TrainDown >> 1));
-		} else {
-			TrainUp = pCurrTxRate->TrainUp;
-			TrainDown = pCurrTxRate->TrainDown;
-		}
-
-		/*pAd->DrsCounters.LastTimeTxRateChangeAction = pAd->DrsCounters.LastSecTxRateChangeAction; */
-
-		/* */
-		/* Keep the last time TxRateChangeAction status. */
-		/* */
-		pEntry->LastTimeTxRateChangeAction =
-		    pEntry->LastSecTxRateChangeAction;
-
-		/* */
-		/* CASE 1. when TX samples are fewer than 15, then decide TX rate solely on RSSI */
-		/*         (criteria copied from RT2500 for Netopia case) */
-		/* */
-		if (TxTotalCnt <= 15) {
-			char idx = 0;
-			u8 TxRateIdx;
-			u8 MCS0 = 0, MCS1 = 0, MCS2 = 0, MCS3 = 0, MCS4 =
-			    0, MCS5 = 0, MCS6 = 0, MCS7 = 0;
-			u8 MCS12 = 0, MCS13 = 0, MCS14 = 0, MCS15 = 0;
-			u8 MCS20 = 0, MCS21 = 0, MCS22 = 0, MCS23 = 0;	/* 3*3 */
-
-			/* check the existence and index of each needed MCS */
-			while (idx < pTable[0]) {
-				pCurrTxRate =
-				    (struct rt_rtmp_tx_rate_switch *) & pTable[(idx + 1) *
-								    5];
-
-				if (pCurrTxRate->CurrMCS == MCS_0) {
-					MCS0 = idx;
-				} else if (pCurrTxRate->CurrMCS == MCS_1) {
-					MCS1 = idx;
-				} else if (pCurrTxRate->CurrMCS == MCS_2) {
-					MCS2 = idx;
-				} else if (pCurrTxRate->CurrMCS == MCS_3) {
-					MCS3 = idx;
-				} else if (pCurrTxRate->CurrMCS == MCS_4) {
-					MCS4 = idx;
-				} else if (pCurrTxRate->CurrMCS == MCS_5) {
-					MCS5 = idx;
-				} else if (pCurrTxRate->CurrMCS == MCS_6) {
-					MCS6 = idx;
-				}
-				/*else if (pCurrTxRate->CurrMCS == MCS_7) */
-				else if ((pCurrTxRate->CurrMCS == MCS_7) && (pCurrTxRate->ShortGI == GI_800))	/* prevent the highest MCS using short GI when 1T and low throughput */
-				{
-					MCS7 = idx;
-				} else if (pCurrTxRate->CurrMCS == MCS_12) {
-					MCS12 = idx;
-				} else if (pCurrTxRate->CurrMCS == MCS_13) {
-					MCS13 = idx;
-				} else if (pCurrTxRate->CurrMCS == MCS_14) {
-					MCS14 = idx;
-				}
-				else if ((pCurrTxRate->CurrMCS == MCS_15) && (pCurrTxRate->ShortGI == GI_800))	/*we hope to use ShortGI as initial rate, however Atheros's chip has bugs when short GI */
-				{
-					MCS15 = idx;
-				} else if (pCurrTxRate->CurrMCS == MCS_20)	/* 3*3 */
-				{
-					MCS20 = idx;
-				} else if (pCurrTxRate->CurrMCS == MCS_21) {
-					MCS21 = idx;
-				} else if (pCurrTxRate->CurrMCS == MCS_22) {
-					MCS22 = idx;
-				} else if (pCurrTxRate->CurrMCS == MCS_23) {
-					MCS23 = idx;
-				}
-				idx++;
-			}
-
-			if (pAd->LatchRfRegs.Channel <= 14) {
-				if (pAd->NicConfig2.field.ExternalLNAForG) {
-					RssiOffset = 2;
-				} else {
-					RssiOffset = 5;
-				}
-			} else {
-				if (pAd->NicConfig2.field.ExternalLNAForA) {
-					RssiOffset = 5;
-				} else {
-					RssiOffset = 8;
-				}
-			}
-
-			/*if (MCS15) */
-			if ((pTable == RateSwitchTable11BGN3S) || (pTable == RateSwitchTable11N3S) || (pTable == RateSwitchTable)) {	/* N mode with 3 stream // 3*3 */
-				if (MCS23 && (Rssi >= -70))
-					TxRateIdx = MCS23;
-				else if (MCS22 && (Rssi >= -72))
-					TxRateIdx = MCS22;
-				else if (MCS21 && (Rssi >= -76))
-					TxRateIdx = MCS21;
-				else if (MCS20 && (Rssi >= -78))
-					TxRateIdx = MCS20;
-				else if (MCS4 && (Rssi >= -82))
-					TxRateIdx = MCS4;
-				else if (MCS3 && (Rssi >= -84))
-					TxRateIdx = MCS3;
-				else if (MCS2 && (Rssi >= -86))
-					TxRateIdx = MCS2;
-				else if (MCS1 && (Rssi >= -88))
-					TxRateIdx = MCS1;
-				else
-					TxRateIdx = MCS0;
-			}
-/*              else if ((pTable == RateSwitchTable11BGN2S) || (pTable == RateSwitchTable11BGN2SForABand) ||(pTable == RateSwitchTable11N2S) ||(pTable == RateSwitchTable11N2SForABand) || (pTable == RateSwitchTable)) */
-			else if ((pTable == RateSwitchTable11BGN2S) || (pTable == RateSwitchTable11BGN2SForABand) || (pTable == RateSwitchTable11N2S) || (pTable == RateSwitchTable11N2SForABand))	/* 3*3 */
-			{	/* N mode with 2 stream */
-				if (MCS15 && (Rssi >= (-70 + RssiOffset)))
-					TxRateIdx = MCS15;
-				else if (MCS14 && (Rssi >= (-72 + RssiOffset)))
-					TxRateIdx = MCS14;
-				else if (MCS13 && (Rssi >= (-76 + RssiOffset)))
-					TxRateIdx = MCS13;
-				else if (MCS12 && (Rssi >= (-78 + RssiOffset)))
-					TxRateIdx = MCS12;
-				else if (MCS4 && (Rssi >= (-82 + RssiOffset)))
-					TxRateIdx = MCS4;
-				else if (MCS3 && (Rssi >= (-84 + RssiOffset)))
-					TxRateIdx = MCS3;
-				else if (MCS2 && (Rssi >= (-86 + RssiOffset)))
-					TxRateIdx = MCS2;
-				else if (MCS1 && (Rssi >= (-88 + RssiOffset)))
-					TxRateIdx = MCS1;
-				else
-					TxRateIdx = MCS0;
-			} else if ((pTable == RateSwitchTable11BGN1S) || (pTable == RateSwitchTable11N1S)) {	/* N mode with 1 stream */
-				if (MCS7 && (Rssi > (-72 + RssiOffset)))
-					TxRateIdx = MCS7;
-				else if (MCS6 && (Rssi > (-74 + RssiOffset)))
-					TxRateIdx = MCS6;
-				else if (MCS5 && (Rssi > (-77 + RssiOffset)))
-					TxRateIdx = MCS5;
-				else if (MCS4 && (Rssi > (-79 + RssiOffset)))
-					TxRateIdx = MCS4;
-				else if (MCS3 && (Rssi > (-81 + RssiOffset)))
-					TxRateIdx = MCS3;
-				else if (MCS2 && (Rssi > (-83 + RssiOffset)))
-					TxRateIdx = MCS2;
-				else if (MCS1 && (Rssi > (-86 + RssiOffset)))
-					TxRateIdx = MCS1;
-				else
-					TxRateIdx = MCS0;
-			} else {	/* Legacy mode */
-				if (MCS7 && (Rssi > -70))
-					TxRateIdx = MCS7;
-				else if (MCS6 && (Rssi > -74))
-					TxRateIdx = MCS6;
-				else if (MCS5 && (Rssi > -78))
-					TxRateIdx = MCS5;
-				else if (MCS4 && (Rssi > -82))
-					TxRateIdx = MCS4;
-				else if (MCS4 == 0)	/* for B-only mode */
-					TxRateIdx = MCS3;
-				else if (MCS3 && (Rssi > -85))
-					TxRateIdx = MCS3;
-				else if (MCS2 && (Rssi > -87))
-					TxRateIdx = MCS2;
-				else if (MCS1 && (Rssi > -90))
-					TxRateIdx = MCS1;
-				else
-					TxRateIdx = MCS0;
-			}
-
-			/*              if (TxRateIdx != pAd->CommonCfg.TxRateIndex) */
-			{
-				pEntry->CurrTxRateIndex = TxRateIdx;
-				pNextTxRate =
-				    (struct rt_rtmp_tx_rate_switch *) &
-				    pTable[(pEntry->CurrTxRateIndex + 1) * 5];
-				MlmeSetTxRate(pAd, pEntry, pNextTxRate);
-			}
-
-			NdisZeroMemory(pEntry->TxQuality,
-				       sizeof(u16)*
-				       MAX_STEP_OF_TX_RATE_SWITCH);
-			NdisZeroMemory(pEntry->PER,
-				       sizeof(u8)*
-				       MAX_STEP_OF_TX_RATE_SWITCH);
-			pEntry->fLastSecAccordingRSSI = TRUE;
-			/* reset all OneSecTx counters */
-			RESET_ONE_SEC_TX_CNT(pEntry);
-
-			continue;
-		}
-
-		if (pEntry->fLastSecAccordingRSSI == TRUE) {
-			pEntry->fLastSecAccordingRSSI = FALSE;
-			pEntry->LastSecTxRateChangeAction = 0;
-			/* reset all OneSecTx counters */
-			RESET_ONE_SEC_TX_CNT(pEntry);
-
-			continue;
-		}
-
-		do {
-			BOOLEAN bTrainUpDown = FALSE;
-
-			pEntry->CurrTxRateStableTime++;
-
-			/* downgrade TX quality if PER >= Rate-Down threshold */
-			if (TxErrorRatio >= TrainDown) {
-				bTrainUpDown = TRUE;
-				pEntry->TxQuality[CurrRateIdx] =
-				    DRS_TX_QUALITY_WORST_BOUND;
-			}
-			/* upgrade TX quality if PER <= Rate-Up threshold */
-			else if (TxErrorRatio <= TrainUp) {
-				bTrainUpDown = TRUE;
-				bUpgradeQuality = TRUE;
-				if (pEntry->TxQuality[CurrRateIdx])
-					pEntry->TxQuality[CurrRateIdx]--;	/* quality very good in CurrRate */
-
-				if (pEntry->TxRateUpPenalty)
-					pEntry->TxRateUpPenalty--;
-				else if (pEntry->TxQuality[UpRateIdx])
-					pEntry->TxQuality[UpRateIdx]--;	/* may improve next UP rate's quality */
-			}
-
-			pEntry->PER[CurrRateIdx] = (u8)TxErrorRatio;
-
-			if (bTrainUpDown) {
-				/* perform DRS - consider TxRate Down first, then rate up. */
-				if ((CurrRateIdx != DownRateIdx)
-				    && (pEntry->TxQuality[CurrRateIdx] >=
-					DRS_TX_QUALITY_WORST_BOUND)) {
-					pEntry->CurrTxRateIndex = DownRateIdx;
-				} else if ((CurrRateIdx != UpRateIdx)
-					   && (pEntry->TxQuality[UpRateIdx] <=
-					       0)) {
-					pEntry->CurrTxRateIndex = UpRateIdx;
-				}
-			}
-		} while (FALSE);
-
-		/* if rate-up happen, clear all bad history of all TX rates */
-		if (pEntry->CurrTxRateIndex > CurrRateIdx) {
-			pEntry->CurrTxRateStableTime = 0;
-			pEntry->TxRateUpPenalty = 0;
-			pEntry->LastSecTxRateChangeAction = 1;	/* rate UP */
-			NdisZeroMemory(pEntry->TxQuality,
-				       sizeof(u16)*
-				       MAX_STEP_OF_TX_RATE_SWITCH);
-			NdisZeroMemory(pEntry->PER,
-				       sizeof(u8)*
-				       MAX_STEP_OF_TX_RATE_SWITCH);
-
-			/* */
-			/* For TxRate fast train up */
-			/* */
-			if (!pAd->StaCfg.StaQuickResponeForRateUpTimerRunning) {
-				RTMPSetTimer(&pAd->StaCfg.
-					     StaQuickResponeForRateUpTimer,
-					     100);
-
-				pAd->StaCfg.
-				    StaQuickResponeForRateUpTimerRunning = TRUE;
-			}
-			bTxRateChanged = TRUE;
-		}
-		/* if rate-down happen, only clear DownRate's bad history */
-		else if (pEntry->CurrTxRateIndex < CurrRateIdx) {
-			pEntry->CurrTxRateStableTime = 0;
-			pEntry->TxRateUpPenalty = 0;	/* no penalty */
-			pEntry->LastSecTxRateChangeAction = 2;	/* rate DOWN */
-			pEntry->TxQuality[pEntry->CurrTxRateIndex] = 0;
-			pEntry->PER[pEntry->CurrTxRateIndex] = 0;
-
-			/* */
-			/* For TxRate fast train down */
-			/* */
-			if (!pAd->StaCfg.StaQuickResponeForRateUpTimerRunning) {
-				RTMPSetTimer(&pAd->StaCfg.
-					     StaQuickResponeForRateUpTimer,
-					     100);
-
-				pAd->StaCfg.
-				    StaQuickResponeForRateUpTimerRunning = TRUE;
-			}
-			bTxRateChanged = TRUE;
-		} else {
-			pEntry->LastSecTxRateChangeAction = 0;	/* rate no change */
-			bTxRateChanged = FALSE;
-		}
-
-		pEntry->LastTxOkCount = TxSuccess;
-		{
-			u8 tmpTxRate;
-
-			/* to fix tcp ack issue */
-			if (!bTxRateChanged
-			    && (pAd->RalinkCounters.OneSecReceivedByteCount >
-				(pAd->RalinkCounters.
-				 OneSecTransmittedByteCount * 5))) {
-				tmpTxRate = DownRateIdx;
-				DBGPRINT_RAW(RT_DEBUG_TRACE,
-					     ("DRS: Rx(%d) is 5 times larger than Tx(%d), use low rate (curr=%d, tmp=%d)\n",
-					      pAd->RalinkCounters.
-					      OneSecReceivedByteCount,
-					      pAd->RalinkCounters.
-					      OneSecTransmittedByteCount,
-					      pEntry->CurrTxRateIndex,
-					      tmpTxRate));
-			} else {
-				tmpTxRate = pEntry->CurrTxRateIndex;
-			}
-
-			pNextTxRate =
-			    (struct rt_rtmp_tx_rate_switch *) & pTable[(tmpTxRate + 1) *
-							    5];
-		}
-		if (bTxRateChanged && pNextTxRate) {
-			MlmeSetTxRate(pAd, pEntry, pNextTxRate);
-		}
-		/* reset all OneSecTx counters */
-		RESET_ONE_SEC_TX_CNT(pEntry);
-	}
-}
-
-/*
-	========================================================================
-	Routine Description:
-		Station side, Auto TxRate faster train up timer call back function.
-
-	Arguments:
-		SystemSpecific1			- Not used.
-		FunctionContext			- Pointer to our Adapter context.
-		SystemSpecific2			- Not used.
-		SystemSpecific3			- Not used.
-
-	Return Value:
-		None
-
-	========================================================================
-*/
-void StaQuickResponeForRateUpExec(void *SystemSpecific1,
-				  void *FunctionContext,
-				  void *SystemSpecific2,
-				  void *SystemSpecific3)
-{
-	struct rt_rtmp_adapter *pAd = (struct rt_rtmp_adapter *)FunctionContext;
-	u8 UpRateIdx = 0, DownRateIdx = 0, CurrRateIdx = 0;
-	unsigned long TxTotalCnt;
-	unsigned long TxErrorRatio = 0;
-	BOOLEAN bTxRateChanged;	/*, bUpgradeQuality = FALSE; */
-	struct rt_rtmp_tx_rate_switch *pCurrTxRate, *pNextTxRate = NULL;
-	u8 *pTable;
-	u8 TableSize = 0;
-	u8 InitTxRateIdx = 0, TrainUp, TrainDown;
-	TX_STA_CNT1_STRUC StaTx1;
-	TX_STA_CNT0_STRUC TxStaCnt0;
-	char Rssi, ratio;
-	unsigned long TxRetransmit = 0, TxSuccess = 0, TxFailCount = 0;
-	struct rt_mac_table_entry *pEntry;
-	unsigned long i;
-
-	pAd->StaCfg.StaQuickResponeForRateUpTimerRunning = FALSE;
-
-	/* */
-	/* walk through MAC table, see if need to change AP's TX rate toward each entry */
-	/* */
-	for (i = 1; i < MAX_LEN_OF_MAC_TABLE; i++) {
-		pEntry = &pAd->MacTab.Content[i];
-
-		/* check if this entry need to switch rate automatically */
-		if (RTMPCheckEntryEnableAutoRateSwitch(pAd, pEntry) == FALSE)
-			continue;
-
-		if (INFRA_ON(pAd) && (i == 1))
-			Rssi = RTMPMaxRssi(pAd,
-					   pAd->StaCfg.RssiSample.AvgRssi0,
-					   pAd->StaCfg.RssiSample.AvgRssi1,
-					   pAd->StaCfg.RssiSample.AvgRssi2);
-		else
-			Rssi = RTMPMaxRssi(pAd,
-					   pEntry->RssiSample.AvgRssi0,
-					   pEntry->RssiSample.AvgRssi1,
-					   pEntry->RssiSample.AvgRssi2);
-
-		CurrRateIdx = pAd->CommonCfg.TxRateIndex;
-
-		MlmeSelectTxRateTable(pAd, pEntry, &pTable, &TableSize,
-				      &InitTxRateIdx);
-
-		/* decide the next upgrade rate and downgrade rate, if any */
-		if ((CurrRateIdx > 0) && (CurrRateIdx < (TableSize - 1))) {
-			UpRateIdx = CurrRateIdx + 1;
-			DownRateIdx = CurrRateIdx - 1;
-		} else if (CurrRateIdx == 0) {
-			UpRateIdx = CurrRateIdx + 1;
-			DownRateIdx = CurrRateIdx;
-		} else if (CurrRateIdx == (TableSize - 1)) {
-			UpRateIdx = CurrRateIdx;
-			DownRateIdx = CurrRateIdx - 1;
-		}
-
-		pCurrTxRate =
-		    (struct rt_rtmp_tx_rate_switch *) & pTable[(CurrRateIdx + 1) * 5];
-
-		if ((Rssi > -65) && (pCurrTxRate->Mode >= MODE_HTMIX)) {
-			TrainUp =
-			    (pCurrTxRate->TrainUp +
-			     (pCurrTxRate->TrainUp >> 1));
-			TrainDown =
-			    (pCurrTxRate->TrainDown +
-			     (pCurrTxRate->TrainDown >> 1));
-		} else {
-			TrainUp = pCurrTxRate->TrainUp;
-			TrainDown = pCurrTxRate->TrainDown;
-		}
-
-		if (pAd->MacTab.Size == 1) {
-			/* Update statistic counter */
-			RTMP_IO_READ32(pAd, TX_STA_CNT0, &TxStaCnt0.word);
-			RTMP_IO_READ32(pAd, TX_STA_CNT1, &StaTx1.word);
-
-			TxRetransmit = StaTx1.field.TxRetransmit;
-			TxSuccess = StaTx1.field.TxSuccess;
-			TxFailCount = TxStaCnt0.field.TxFailCount;
-			TxTotalCnt = TxRetransmit + TxSuccess + TxFailCount;
-
-			pAd->RalinkCounters.OneSecTxRetryOkCount +=
-			    StaTx1.field.TxRetransmit;
-			pAd->RalinkCounters.OneSecTxNoRetryOkCount +=
-			    StaTx1.field.TxSuccess;
-			pAd->RalinkCounters.OneSecTxFailCount +=
-			    TxStaCnt0.field.TxFailCount;
-			pAd->WlanCounters.TransmittedFragmentCount.u.LowPart +=
-			    StaTx1.field.TxSuccess;
-			pAd->WlanCounters.RetryCount.u.LowPart +=
-			    StaTx1.field.TxRetransmit;
-			pAd->WlanCounters.FailedCount.u.LowPart +=
-			    TxStaCnt0.field.TxFailCount;
-
-			if (TxTotalCnt)
-				TxErrorRatio =
-				    ((TxRetransmit +
-				      TxFailCount) * 100) / TxTotalCnt;
-		} else {
-			TxTotalCnt = pEntry->OneSecTxNoRetryOkCount +
-			    pEntry->OneSecTxRetryOkCount +
-			    pEntry->OneSecTxFailCount;
-
-			if (TxTotalCnt)
-				TxErrorRatio =
-				    ((pEntry->OneSecTxRetryOkCount +
-				      pEntry->OneSecTxFailCount) * 100) /
-				    TxTotalCnt;
-		}
-
-		/* */
-		/* CASE 1. when TX samples are fewer than 15, then decide TX rate solely on RSSI */
-		/*         (criteria copied from RT2500 for Netopia case) */
-		/* */
-		if (TxTotalCnt <= 12) {
-			NdisZeroMemory(pAd->DrsCounters.TxQuality,
-				       sizeof(u16)*
-				       MAX_STEP_OF_TX_RATE_SWITCH);
-			NdisZeroMemory(pAd->DrsCounters.PER,
-				       sizeof(u8)*
-				       MAX_STEP_OF_TX_RATE_SWITCH);
-
-			if ((pAd->DrsCounters.LastSecTxRateChangeAction == 1)
-			    && (CurrRateIdx != DownRateIdx)) {
-				pAd->CommonCfg.TxRateIndex = DownRateIdx;
-				pAd->DrsCounters.TxQuality[CurrRateIdx] =
-				    DRS_TX_QUALITY_WORST_BOUND;
-			} else
-			    if ((pAd->DrsCounters.LastSecTxRateChangeAction ==
-				 2) && (CurrRateIdx != UpRateIdx)) {
-				pAd->CommonCfg.TxRateIndex = UpRateIdx;
-			}
-
-			DBGPRINT_RAW(RT_DEBUG_TRACE,
-				     ("QuickDRS: TxTotalCnt <= 15, train back to original rate \n"));
-			return;
-		}
-
-		do {
-			unsigned long OneSecTxNoRetryOKRationCount;
-
-			if (pAd->DrsCounters.LastTimeTxRateChangeAction == 0)
-				ratio = 5;
-			else
-				ratio = 4;
-
-			/* downgrade TX quality if PER >= Rate-Down threshold */
-			if (TxErrorRatio >= TrainDown) {
-				pAd->DrsCounters.TxQuality[CurrRateIdx] =
-				    DRS_TX_QUALITY_WORST_BOUND;
-			}
-
-			pAd->DrsCounters.PER[CurrRateIdx] =
-			    (u8)TxErrorRatio;
-
-			OneSecTxNoRetryOKRationCount = (TxSuccess * ratio);
-
-			/* perform DRS - consider TxRate Down first, then rate up. */
-			if ((pAd->DrsCounters.LastSecTxRateChangeAction == 1)
-			    && (CurrRateIdx != DownRateIdx)) {
-				if ((pAd->DrsCounters.LastTxOkCount + 2) >=
-				    OneSecTxNoRetryOKRationCount) {
-					pAd->CommonCfg.TxRateIndex =
-					    DownRateIdx;
-					pAd->DrsCounters.
-					    TxQuality[CurrRateIdx] =
-					    DRS_TX_QUALITY_WORST_BOUND;
-
-				}
-
-			} else
-			    if ((pAd->DrsCounters.LastSecTxRateChangeAction ==
-				 2) && (CurrRateIdx != UpRateIdx)) {
-				if ((TxErrorRatio >= 50)
-				    || (TxErrorRatio >= TrainDown)) {
-
-				} else if ((pAd->DrsCounters.LastTxOkCount + 2)
-					   >= OneSecTxNoRetryOKRationCount) {
-					pAd->CommonCfg.TxRateIndex = UpRateIdx;
-				}
-			}
-		} while (FALSE);
-
-		/* if rate-up happen, clear all bad history of all TX rates */
-		if (pAd->CommonCfg.TxRateIndex > CurrRateIdx) {
-			pAd->DrsCounters.TxRateUpPenalty = 0;
-			NdisZeroMemory(pAd->DrsCounters.TxQuality,
-				       sizeof(u16)*
-				       MAX_STEP_OF_TX_RATE_SWITCH);
-			NdisZeroMemory(pAd->DrsCounters.PER,
-				       sizeof(u8)*
-				       MAX_STEP_OF_TX_RATE_SWITCH);
-			bTxRateChanged = TRUE;
-		}
-		/* if rate-down happen, only clear DownRate's bad history */
-		else if (pAd->CommonCfg.TxRateIndex < CurrRateIdx) {
-			DBGPRINT_RAW(RT_DEBUG_TRACE,
-				     ("QuickDRS: --TX rate from %d to %d \n",
-				      CurrRateIdx, pAd->CommonCfg.TxRateIndex));
-
-			pAd->DrsCounters.TxRateUpPenalty = 0;	/* no penalty */
-			pAd->DrsCounters.TxQuality[pAd->CommonCfg.TxRateIndex] =
-			    0;
-			pAd->DrsCounters.PER[pAd->CommonCfg.TxRateIndex] = 0;
-			bTxRateChanged = TRUE;
-		} else {
-			bTxRateChanged = FALSE;
-		}
-
-		pNextTxRate =
-		    (struct rt_rtmp_tx_rate_switch *) &
-		    pTable[(pAd->CommonCfg.TxRateIndex + 1) * 5];
-		if (bTxRateChanged && pNextTxRate) {
-			MlmeSetTxRate(pAd, pEntry, pNextTxRate);
-		}
-	}
-}
-
-/*
-	==========================================================================
-	Description:
-		This routine is executed periodically inside MlmePeriodicExec() after
-		association with an AP.
-		It checks if StaCfg.Psm is consistent with user policy (recorded in
-		StaCfg.WindowsPowerMode). If not, enforce user policy. However,
-		there're some conditions to consider:
-		1. we don't support power-saving in ADHOC mode, so Psm=PWR_ACTIVE all
-		   the time when Mibss==TRUE
-		2. When link up in INFRA mode, Psm should not be switch to PWR_SAVE
-		   if outgoing traffic available in TxRing or MgmtRing.
-	Output:
-		1. change pAd->StaCfg.Psm to PWR_SAVE or leave it untouched
-
-	IRQL = DISPATCH_LEVEL
-
-	==========================================================================
- */
-void MlmeCheckPsmChange(struct rt_rtmp_adapter *pAd, unsigned long Now32)
-{
-	unsigned long PowerMode;
-
-	/* condition - */
-	/* 1. Psm maybe ON only happen in INFRASTRUCTURE mode */
-	/* 2. user wants either MAX_PSP or FAST_PSP */
-	/* 3. but current psm is not in PWR_SAVE */
-	/* 4. CNTL state machine is not doing SCANning */
-	/* 5. no TX SUCCESS event for the past 1-sec period */
-	PowerMode = pAd->StaCfg.WindowsPowerMode;
-
-	if (INFRA_ON(pAd) &&
-	    (PowerMode != Ndis802_11PowerModeCAM) &&
-	    (pAd->StaCfg.Psm == PWR_ACTIVE) &&
-/*              (! RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) */
-	    (pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE) &&
-	    RTMP_TEST_PSFLAG(pAd, fRTMP_PS_CAN_GO_SLEEP)
-	    /*&&
-	       (pAd->RalinkCounters.OneSecTxNoRetryOkCount == 0) &&
-	       (pAd->RalinkCounters.OneSecTxRetryOkCount == 0) */
-	    ) {
-		NdisGetSystemUpTime(&pAd->Mlme.LastSendNULLpsmTime);
-		pAd->RalinkCounters.RxCountSinceLastNULL = 0;
-		RTMP_SET_PSM_BIT(pAd, PWR_SAVE);
-		if (!
-		    (pAd->CommonCfg.bAPSDCapable
-		     && pAd->CommonCfg.APEdcaParm.bAPSDCapable)) {
-			RTMPSendNullFrame(pAd, pAd->CommonCfg.TxRate, FALSE);
-		} else {
-			RTMPSendNullFrame(pAd, pAd->CommonCfg.TxRate, TRUE);
-		}
-	}
-}
-
-/* IRQL = PASSIVE_LEVEL */
-/* IRQL = DISPATCH_LEVEL */
-void MlmeSetPsmBit(struct rt_rtmp_adapter *pAd, u16 psm)
-{
-	AUTO_RSP_CFG_STRUC csr4;
-
-	pAd->StaCfg.Psm = psm;
-	RTMP_IO_READ32(pAd, AUTO_RSP_CFG, &csr4.word);
-	csr4.field.AckCtsPsmBit = (psm == PWR_SAVE) ? 1 : 0;
-	RTMP_IO_WRITE32(pAd, AUTO_RSP_CFG, csr4.word);
-
-	DBGPRINT(RT_DEBUG_TRACE, ("MlmeSetPsmBit = %d\n", psm));
-}
-
-/*
-	==========================================================================
-	Description:
-		This routine calculates TxPER, RxPER of the past N-sec period. And
-		according to the calculation result, ChannelQuality is calculated here
-		to decide if current AP is still doing the job.
-
-		If ChannelQuality is not good, a ROAMing attempt may be tried later.
-	Output:
-		StaCfg.ChannelQuality - 0..100
-
-	IRQL = DISPATCH_LEVEL
-
-	NOTE: This routine decide channle quality based on RX CRC error ratio.
-		Caller should make sure a function call to NICUpdateRawCounters(pAd)
-		is performed right before this routine, so that this routine can decide
-		channel quality based on the most up-to-date information
-	==========================================================================
- */
-void MlmeCalculateChannelQuality(struct rt_rtmp_adapter *pAd,
-				 struct rt_mac_table_entry *pMacEntry, unsigned long Now32)
-{
-	unsigned long TxOkCnt, TxCnt, TxPER, TxPRR;
-	unsigned long RxCnt, RxPER;
-	u8 NorRssi;
-	char MaxRssi;
-	struct rt_rssi_sample *pRssiSample = NULL;
-	u32 OneSecTxNoRetryOkCount = 0;
-	u32 OneSecTxRetryOkCount = 0;
-	u32 OneSecTxFailCount = 0;
-	u32 OneSecRxOkCnt = 0;
-	u32 OneSecRxFcsErrCnt = 0;
-	unsigned long ChannelQuality = 0;	/* 0..100, Channel Quality Indication for Roaming */
-	unsigned long BeaconLostTime = pAd->StaCfg.BeaconLostTime;
-
-	if (pAd->OpMode == OPMODE_STA) {
-		pRssiSample = &pAd->StaCfg.RssiSample;
-		OneSecTxNoRetryOkCount =
-		    pAd->RalinkCounters.OneSecTxNoRetryOkCount;
-		OneSecTxRetryOkCount = pAd->RalinkCounters.OneSecTxRetryOkCount;
-		OneSecTxFailCount = pAd->RalinkCounters.OneSecTxFailCount;
-		OneSecRxOkCnt = pAd->RalinkCounters.OneSecRxOkCnt;
-		OneSecRxFcsErrCnt = pAd->RalinkCounters.OneSecRxFcsErrCnt;
-	}
-
-	MaxRssi = RTMPMaxRssi(pAd, pRssiSample->LastRssi0,
-			      pRssiSample->LastRssi1, pRssiSample->LastRssi2);
-
-	/* */
-	/* calculate TX packet error ratio and TX retry ratio - if too few TX samples, skip TX related statistics */
-	/* */
-	TxOkCnt = OneSecTxNoRetryOkCount + OneSecTxRetryOkCount;
-	TxCnt = TxOkCnt + OneSecTxFailCount;
-	if (TxCnt < 5) {
-		TxPER = 0;
-		TxPRR = 0;
-	} else {
-		TxPER = (OneSecTxFailCount * 100) / TxCnt;
-		TxPRR = ((TxCnt - OneSecTxNoRetryOkCount) * 100) / TxCnt;
-	}
-
-	/* */
-	/* calculate RX PER - don't take RxPER into consideration if too few sample */
-	/* */
-	RxCnt = OneSecRxOkCnt + OneSecRxFcsErrCnt;
-	if (RxCnt < 5)
-		RxPER = 0;
-	else
-		RxPER = (OneSecRxFcsErrCnt * 100) / RxCnt;
-
-	/* */
-	/* decide ChannelQuality based on: 1)last BEACON received time, 2)last RSSI, 3)TxPER, and 4)RxPER */
-	/* */
-	if ((pAd->OpMode == OPMODE_STA) && INFRA_ON(pAd) && (OneSecTxNoRetryOkCount < 2) &&	/* no heavy traffic */
-	    ((pAd->StaCfg.LastBeaconRxTime + BeaconLostTime) < Now32)) {
-		DBGPRINT(RT_DEBUG_TRACE,
-			 ("BEACON lost > %ld msec with TxOkCnt=%ld -> CQI=0\n",
-			  BeaconLostTime, TxOkCnt));
-		ChannelQuality = 0;
-	} else {
-		/* Normalize Rssi */
-		if (MaxRssi > -40)
-			NorRssi = 100;
-		else if (MaxRssi < -90)
-			NorRssi = 0;
-		else
-			NorRssi = (MaxRssi + 90) * 2;
-
-		/* ChannelQuality = W1*RSSI + W2*TxPRR + W3*RxPER        (RSSI 0..100), (TxPER 100..0), (RxPER 100..0) */
-		ChannelQuality = (RSSI_WEIGHTING * NorRssi +
-				  TX_WEIGHTING * (100 - TxPRR) +
-				  RX_WEIGHTING * (100 - RxPER)) / 100;
-	}
-
-	if (pAd->OpMode == OPMODE_STA)
-		pAd->Mlme.ChannelQuality =
-		    (ChannelQuality > 100) ? 100 : ChannelQuality;
-
-}
-
-/* IRQL = DISPATCH_LEVEL */
-void MlmeSetTxPreamble(struct rt_rtmp_adapter *pAd, u16 TxPreamble)
-{
-	AUTO_RSP_CFG_STRUC csr4;
-
-	/* */
-	/* Always use Long preamble before verifiation short preamble functionality works well. */
-	/* Todo: remove the following line if short preamble functionality works */
-	/* */
-	/*TxPreamble = Rt802_11PreambleLong; */
-
-	RTMP_IO_READ32(pAd, AUTO_RSP_CFG, &csr4.word);
-	if (TxPreamble == Rt802_11PreambleLong) {
-		DBGPRINT(RT_DEBUG_TRACE,
-			 ("MlmeSetTxPreamble (= long PREAMBLE)\n"));
-		OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_SHORT_PREAMBLE_INUSED);
-		csr4.field.AutoResponderPreamble = 0;
-	} else {
-		/* NOTE: 1Mbps should always use long preamble */
-		DBGPRINT(RT_DEBUG_TRACE,
-			 ("MlmeSetTxPreamble (= short PREAMBLE)\n"));
-		OPSTATUS_SET_FLAG(pAd, fOP_STATUS_SHORT_PREAMBLE_INUSED);
-		csr4.field.AutoResponderPreamble = 1;
-	}
-
-	RTMP_IO_WRITE32(pAd, AUTO_RSP_CFG, csr4.word);
-}
-
-/*
-    ==========================================================================
-    Description:
-        Update basic rate bitmap
-    ==========================================================================
- */
-
-void UpdateBasicRateBitmap(struct rt_rtmp_adapter *pAdapter)
-{
-	int i, j;
-	/* 1  2  5.5, 11,  6,  9, 12, 18, 24, 36, 48,  54 */
-	u8 rate[] = { 2, 4, 11, 22, 12, 18, 24, 36, 48, 72, 96, 108 };
-	u8 *sup_p = pAdapter->CommonCfg.SupRate;
-	u8 *ext_p = pAdapter->CommonCfg.ExtRate;
-	unsigned long bitmap = pAdapter->CommonCfg.BasicRateBitmap;
-
-	/* if A mode, always use fix BasicRateBitMap */
-	/*if (pAdapter->CommonCfg.Channel == PHY_11A) */
-	if (pAdapter->CommonCfg.Channel > 14)
-		pAdapter->CommonCfg.BasicRateBitmap = 0x150;	/* 6, 12, 24M */
-	/* End of if */
-
-	if (pAdapter->CommonCfg.BasicRateBitmap > 4095) {
-		/* (2 ^ MAX_LEN_OF_SUPPORTED_RATES) -1 */
-		return;
-	}
-	/* End of if */
-	for (i = 0; i < MAX_LEN_OF_SUPPORTED_RATES; i++) {
-		sup_p[i] &= 0x7f;
-		ext_p[i] &= 0x7f;
-	}			/* End of for */
-
-	for (i = 0; i < MAX_LEN_OF_SUPPORTED_RATES; i++) {
-		if (bitmap & (1 << i)) {
-			for (j = 0; j < MAX_LEN_OF_SUPPORTED_RATES; j++) {
-				if (sup_p[j] == rate[i])
-					sup_p[j] |= 0x80;
-				/* End of if */
-			}	/* End of for */
-
-			for (j = 0; j < MAX_LEN_OF_SUPPORTED_RATES; j++) {
-				if (ext_p[j] == rate[i])
-					ext_p[j] |= 0x80;
-				/* End of if */
-			}	/* End of for */
-		}		/* End of if */
-	}			/* End of for */
-}				/* End of UpdateBasicRateBitmap */
-
-/* IRQL = PASSIVE_LEVEL */
-/* IRQL = DISPATCH_LEVEL */
-/* bLinkUp is to identify the initial link speed. */
-/* TRUE indicates the rate update at linkup, we should not try to set the rate at 54Mbps. */
-void MlmeUpdateTxRates(struct rt_rtmp_adapter *pAd, IN BOOLEAN bLinkUp, u8 apidx)
-{
-	int i, num;
-	u8 Rate = RATE_6, MaxDesire = RATE_1, MaxSupport = RATE_1;
-	u8 MinSupport = RATE_54;
-	unsigned long BasicRateBitmap = 0;
-	u8 CurrBasicRate = RATE_1;
-	u8 *pSupRate, SupRateLen, *pExtRate, ExtRateLen;
-	PHTTRANSMIT_SETTING pHtPhy = NULL;
-	PHTTRANSMIT_SETTING pMaxHtPhy = NULL;
-	PHTTRANSMIT_SETTING pMinHtPhy = NULL;
-	BOOLEAN *auto_rate_cur_p;
-	u8 HtMcs = MCS_AUTO;
-
-	/* find max desired rate */
-	UpdateBasicRateBitmap(pAd);
-
-	num = 0;
-	auto_rate_cur_p = NULL;
-	for (i = 0; i < MAX_LEN_OF_SUPPORTED_RATES; i++) {
-		switch (pAd->CommonCfg.DesireRate[i] & 0x7f) {
-		case 2:
-			Rate = RATE_1;
-			num++;
-			break;
-		case 4:
-			Rate = RATE_2;
-			num++;
-			break;
-		case 11:
-			Rate = RATE_5_5;
-			num++;
-			break;
-		case 22:
-			Rate = RATE_11;
-			num++;
-			break;
-		case 12:
-			Rate = RATE_6;
-			num++;
-			break;
-		case 18:
-			Rate = RATE_9;
-			num++;
-			break;
-		case 24:
-			Rate = RATE_12;
-			num++;
-			break;
-		case 36:
-			Rate = RATE_18;
-			num++;
-			break;
-		case 48:
-			Rate = RATE_24;
-			num++;
-			break;
-		case 72:
-			Rate = RATE_36;
-			num++;
-			break;
-		case 96:
-			Rate = RATE_48;
-			num++;
-			break;
-		case 108:
-			Rate = RATE_54;
-			num++;
-			break;
-			/*default: Rate = RATE_1;   break; */
-		}
-		if (MaxDesire < Rate)
-			MaxDesire = Rate;
-	}
-
-/*=========================================================================== */
-/*=========================================================================== */
-	{
-		pHtPhy = &pAd->StaCfg.HTPhyMode;
-		pMaxHtPhy = &pAd->StaCfg.MaxHTPhyMode;
-		pMinHtPhy = &pAd->StaCfg.MinHTPhyMode;
-
-		auto_rate_cur_p = &pAd->StaCfg.bAutoTxRateSwitch;
-		HtMcs = pAd->StaCfg.DesiredTransmitSetting.field.MCS;
-
-		if ((pAd->StaCfg.BssType == BSS_ADHOC) &&
-		    (pAd->CommonCfg.PhyMode == PHY_11B) &&
-		    (MaxDesire > RATE_11)) {
-			MaxDesire = RATE_11;
-		}
-	}
-
-	pAd->CommonCfg.MaxDesiredRate = MaxDesire;
-	pMinHtPhy->word = 0;
-	pMaxHtPhy->word = 0;
-	pHtPhy->word = 0;
-
-	/* Auto rate switching is enabled only if more than one DESIRED RATES are */
-	/* specified; otherwise disabled */
-	if (num <= 1) {
-		/*OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED); */
-		/*pAd->CommonCfg.bAutoTxRateSwitch      = FALSE; */
-		*auto_rate_cur_p = FALSE;
-	} else {
-		/*OPSTATUS_SET_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED); */
-		/*pAd->CommonCfg.bAutoTxRateSwitch      = TRUE; */
-		*auto_rate_cur_p = TRUE;
-	}
-
-	if (HtMcs != MCS_AUTO) {
-		/*OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED); */
-		/*pAd->CommonCfg.bAutoTxRateSwitch      = FALSE; */
-		*auto_rate_cur_p = FALSE;
-	} else {
-		/*OPSTATUS_SET_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED); */
-		/*pAd->CommonCfg.bAutoTxRateSwitch      = TRUE; */
-		*auto_rate_cur_p = TRUE;
-	}
-
-	if ((ADHOC_ON(pAd) || INFRA_ON(pAd)) && (pAd->OpMode == OPMODE_STA)) {
-		pSupRate = &pAd->StaActive.SupRate[0];
-		pExtRate = &pAd->StaActive.ExtRate[0];
-		SupRateLen = pAd->StaActive.SupRateLen;
-		ExtRateLen = pAd->StaActive.ExtRateLen;
-	} else {
-		pSupRate = &pAd->CommonCfg.SupRate[0];
-		pExtRate = &pAd->CommonCfg.ExtRate[0];
-		SupRateLen = pAd->CommonCfg.SupRateLen;
-		ExtRateLen = pAd->CommonCfg.ExtRateLen;
-	}
-
-	/* find max supported rate */
-	for (i = 0; i < SupRateLen; i++) {
-		switch (pSupRate[i] & 0x7f) {
-		case 2:
-			Rate = RATE_1;
-			if (pSupRate[i] & 0x80)
-				BasicRateBitmap |= 0x0001;
-			break;
-		case 4:
-			Rate = RATE_2;
-			if (pSupRate[i] & 0x80)
-				BasicRateBitmap |= 0x0002;
-			break;
-		case 11:
-			Rate = RATE_5_5;
-			if (pSupRate[i] & 0x80)
-				BasicRateBitmap |= 0x0004;
-			break;
-		case 22:
-			Rate = RATE_11;
-			if (pSupRate[i] & 0x80)
-				BasicRateBitmap |= 0x0008;
-			break;
-		case 12:
-			Rate = RATE_6;	/*if (pSupRate[i] & 0x80) */
-			BasicRateBitmap |= 0x0010;
-			break;
-		case 18:
-			Rate = RATE_9;
-			if (pSupRate[i] & 0x80)
-				BasicRateBitmap |= 0x0020;
-			break;
-		case 24:
-			Rate = RATE_12;	/*if (pSupRate[i] & 0x80) */
-			BasicRateBitmap |= 0x0040;
-			break;
-		case 36:
-			Rate = RATE_18;
-			if (pSupRate[i] & 0x80)
-				BasicRateBitmap |= 0x0080;
-			break;
-		case 48:
-			Rate = RATE_24;	/*if (pSupRate[i] & 0x80) */
-			BasicRateBitmap |= 0x0100;
-			break;
-		case 72:
-			Rate = RATE_36;
-			if (pSupRate[i] & 0x80)
-				BasicRateBitmap |= 0x0200;
-			break;
-		case 96:
-			Rate = RATE_48;
-			if (pSupRate[i] & 0x80)
-				BasicRateBitmap |= 0x0400;
-			break;
-		case 108:
-			Rate = RATE_54;
-			if (pSupRate[i] & 0x80)
-				BasicRateBitmap |= 0x0800;
-			break;
-		default:
-			Rate = RATE_1;
-			break;
-		}
-		if (MaxSupport < Rate)
-			MaxSupport = Rate;
-
-		if (MinSupport > Rate)
-			MinSupport = Rate;
-	}
-
-	for (i = 0; i < ExtRateLen; i++) {
-		switch (pExtRate[i] & 0x7f) {
-		case 2:
-			Rate = RATE_1;
-			if (pExtRate[i] & 0x80)
-				BasicRateBitmap |= 0x0001;
-			break;
-		case 4:
-			Rate = RATE_2;
-			if (pExtRate[i] & 0x80)
-				BasicRateBitmap |= 0x0002;
-			break;
-		case 11:
-			Rate = RATE_5_5;
-			if (pExtRate[i] & 0x80)
-				BasicRateBitmap |= 0x0004;
-			break;
-		case 22:
-			Rate = RATE_11;
-			if (pExtRate[i] & 0x80)
-				BasicRateBitmap |= 0x0008;
-			break;
-		case 12:
-			Rate = RATE_6;	/*if (pExtRate[i] & 0x80) */
-			BasicRateBitmap |= 0x0010;
-			break;
-		case 18:
-			Rate = RATE_9;
-			if (pExtRate[i] & 0x80)
-				BasicRateBitmap |= 0x0020;
-			break;
-		case 24:
-			Rate = RATE_12;	/*if (pExtRate[i] & 0x80) */
-			BasicRateBitmap |= 0x0040;
-			break;
-		case 36:
-			Rate = RATE_18;
-			if (pExtRate[i] & 0x80)
-				BasicRateBitmap |= 0x0080;
-			break;
-		case 48:
-			Rate = RATE_24;	/*if (pExtRate[i] & 0x80) */
-			BasicRateBitmap |= 0x0100;
-			break;
-		case 72:
-			Rate = RATE_36;
-			if (pExtRate[i] & 0x80)
-				BasicRateBitmap |= 0x0200;
-			break;
-		case 96:
-			Rate = RATE_48;
-			if (pExtRate[i] & 0x80)
-				BasicRateBitmap |= 0x0400;
-			break;
-		case 108:
-			Rate = RATE_54;
-			if (pExtRate[i] & 0x80)
-				BasicRateBitmap |= 0x0800;
-			break;
-		default:
-			Rate = RATE_1;
-			break;
-		}
-		if (MaxSupport < Rate)
-			MaxSupport = Rate;
-
-		if (MinSupport > Rate)
-			MinSupport = Rate;
-	}
-
-	RTMP_IO_WRITE32(pAd, LEGACY_BASIC_RATE, BasicRateBitmap);
-
-	/* bug fix */
-	/* pAd->CommonCfg.BasicRateBitmap = BasicRateBitmap; */
-
-	/* calculate the exptected ACK rate for each TX rate. This info is used to caculate */
-	/* the DURATION field of outgoing uniicast DATA/MGMT frame */
-	for (i = 0; i < MAX_LEN_OF_SUPPORTED_RATES; i++) {
-		if (BasicRateBitmap & (0x01 << i))
-			CurrBasicRate = (u8)i;
-		pAd->CommonCfg.ExpectedACKRate[i] = CurrBasicRate;
-	}
-
-	DBGPRINT(RT_DEBUG_TRACE,
-		 ("MlmeUpdateTxRates[MaxSupport = %d] = MaxDesire %d Mbps\n",
-		  RateIdToMbps[MaxSupport], RateIdToMbps[MaxDesire]));
-	/* max tx rate = min {max desire rate, max supported rate} */
-	if (MaxSupport < MaxDesire)
-		pAd->CommonCfg.MaxTxRate = MaxSupport;
-	else
-		pAd->CommonCfg.MaxTxRate = MaxDesire;
-
-	pAd->CommonCfg.MinTxRate = MinSupport;
-	/* 2003-07-31 john - 2500 doesn't have good sensitivity at high OFDM rates. to increase the success */
-	/* ratio of initial DHCP packet exchange, TX rate starts from a lower rate depending */
-	/* on average RSSI */
-	/*       1. RSSI >= -70db, start at 54 Mbps (short distance) */
-	/*       2. -70 > RSSI >= -75, start at 24 Mbps (mid distance) */
-	/*       3. -75 > RSSI, start at 11 Mbps (long distance) */
-	if (*auto_rate_cur_p) {
-		short dbm = 0;
-
-		dbm = pAd->StaCfg.RssiSample.AvgRssi0 - pAd->BbpRssiToDbmDelta;
-
-		if (bLinkUp == TRUE)
-			pAd->CommonCfg.TxRate = RATE_24;
-		else
-			pAd->CommonCfg.TxRate = pAd->CommonCfg.MaxTxRate;
-
-		if (dbm < -75)
-			pAd->CommonCfg.TxRate = RATE_11;
-		else if (dbm < -70)
-			pAd->CommonCfg.TxRate = RATE_24;
-
-		/* should never exceed MaxTxRate (consider 11B-only mode) */
-		if (pAd->CommonCfg.TxRate > pAd->CommonCfg.MaxTxRate)
-			pAd->CommonCfg.TxRate = pAd->CommonCfg.MaxTxRate;
-
-		pAd->CommonCfg.TxRateIndex = 0;
-	} else {
-		pAd->CommonCfg.TxRate = pAd->CommonCfg.MaxTxRate;
-		pHtPhy->field.MCS =
-		    (pAd->CommonCfg.MaxTxRate >
-		     3) ? (pAd->CommonCfg.MaxTxRate -
-			   4) : pAd->CommonCfg.MaxTxRate;
-		pHtPhy->field.MODE =
-		    (pAd->CommonCfg.MaxTxRate > 3) ? MODE_OFDM : MODE_CCK;
-
-		pAd->MacTab.Content[BSSID_WCID].HTPhyMode.field.STBC =
-		    pHtPhy->field.STBC;
-		pAd->MacTab.Content[BSSID_WCID].HTPhyMode.field.ShortGI =
-		    pHtPhy->field.ShortGI;
-		pAd->MacTab.Content[BSSID_WCID].HTPhyMode.field.MCS =
-		    pHtPhy->field.MCS;
-		pAd->MacTab.Content[BSSID_WCID].HTPhyMode.field.MODE =
-		    pHtPhy->field.MODE;
-	}
-
-	if (pAd->CommonCfg.TxRate <= RATE_11) {
-		pMaxHtPhy->field.MODE = MODE_CCK;
-		pMaxHtPhy->field.MCS = pAd->CommonCfg.TxRate;
-		pMinHtPhy->field.MCS = pAd->CommonCfg.MinTxRate;
-	} else {
-		pMaxHtPhy->field.MODE = MODE_OFDM;
-		pMaxHtPhy->field.MCS = OfdmRateToRxwiMCS[pAd->CommonCfg.TxRate];
-		if (pAd->CommonCfg.MinTxRate >= RATE_6
-		    && (pAd->CommonCfg.MinTxRate <= RATE_54)) {
-			pMinHtPhy->field.MCS =
-			    OfdmRateToRxwiMCS[pAd->CommonCfg.MinTxRate];
-		} else {
-			pMinHtPhy->field.MCS = pAd->CommonCfg.MinTxRate;
-		}
-	}
-
-	pHtPhy->word = (pMaxHtPhy->word);
-	if (bLinkUp && (pAd->OpMode == OPMODE_STA)) {
-		pAd->MacTab.Content[BSSID_WCID].HTPhyMode.word = pHtPhy->word;
-		pAd->MacTab.Content[BSSID_WCID].MaxHTPhyMode.word =
-		    pMaxHtPhy->word;
-		pAd->MacTab.Content[BSSID_WCID].MinHTPhyMode.word =
-		    pMinHtPhy->word;
-	} else {
-		switch (pAd->CommonCfg.PhyMode) {
-		case PHY_11BG_MIXED:
-		case PHY_11B:
-		case PHY_11BGN_MIXED:
-			pAd->CommonCfg.MlmeRate = RATE_1;
-			pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_CCK;
-			pAd->CommonCfg.MlmeTransmit.field.MCS = RATE_1;
-
-/*#ifdef        WIFI_TEST */
-			pAd->CommonCfg.RtsRate = RATE_11;
-/*#else */
-/*                              pAd->CommonCfg.RtsRate = RATE_1; */
-/*#endif */
-			break;
-		case PHY_11G:
-		case PHY_11A:
-		case PHY_11AGN_MIXED:
-		case PHY_11GN_MIXED:
-		case PHY_11N_2_4G:
-		case PHY_11AN_MIXED:
-		case PHY_11N_5G:
-			pAd->CommonCfg.MlmeRate = RATE_6;
-			pAd->CommonCfg.RtsRate = RATE_6;
-			pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_OFDM;
-			pAd->CommonCfg.MlmeTransmit.field.MCS =
-			    OfdmRateToRxwiMCS[pAd->CommonCfg.MlmeRate];
-			break;
-		case PHY_11ABG_MIXED:
-		case PHY_11ABGN_MIXED:
-			if (pAd->CommonCfg.Channel <= 14) {
-				pAd->CommonCfg.MlmeRate = RATE_1;
-				pAd->CommonCfg.RtsRate = RATE_1;
-				pAd->CommonCfg.MlmeTransmit.field.MODE =
-				    MODE_CCK;
-				pAd->CommonCfg.MlmeTransmit.field.MCS = RATE_1;
-			} else {
-				pAd->CommonCfg.MlmeRate = RATE_6;
-				pAd->CommonCfg.RtsRate = RATE_6;
-				pAd->CommonCfg.MlmeTransmit.field.MODE =
-				    MODE_OFDM;
-				pAd->CommonCfg.MlmeTransmit.field.MCS =
-				    OfdmRateToRxwiMCS[pAd->CommonCfg.MlmeRate];
-			}
-			break;
-		default:	/* error */
-			pAd->CommonCfg.MlmeRate = RATE_6;
-			pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_OFDM;
-			pAd->CommonCfg.MlmeTransmit.field.MCS =
-			    OfdmRateToRxwiMCS[pAd->CommonCfg.MlmeRate];
-			pAd->CommonCfg.RtsRate = RATE_1;
-			break;
-		}
-		/* */
-		/* Keep Basic Mlme Rate. */
-		/* */
-		pAd->MacTab.Content[MCAST_WCID].HTPhyMode.word =
-		    pAd->CommonCfg.MlmeTransmit.word;
-		if (pAd->CommonCfg.MlmeTransmit.field.MODE == MODE_OFDM)
-			pAd->MacTab.Content[MCAST_WCID].HTPhyMode.field.MCS =
-			    OfdmRateToRxwiMCS[RATE_24];
-		else
-			pAd->MacTab.Content[MCAST_WCID].HTPhyMode.field.MCS =
-			    RATE_1;
-		pAd->CommonCfg.BasicMlmeRate = pAd->CommonCfg.MlmeRate;
-	}
-
-	DBGPRINT(RT_DEBUG_TRACE,
-		 (" MlmeUpdateTxRates (MaxDesire=%d, MaxSupport=%d, MaxTxRate=%d, MinRate=%d, Rate Switching =%d)\n",
-		  RateIdToMbps[MaxDesire], RateIdToMbps[MaxSupport],
-		  RateIdToMbps[pAd->CommonCfg.MaxTxRate],
-		  RateIdToMbps[pAd->CommonCfg.MinTxRate],
-		  /*OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED) */
-		  *auto_rate_cur_p));
-	DBGPRINT(RT_DEBUG_TRACE,
-		 (" MlmeUpdateTxRates (TxRate=%d, RtsRate=%d, BasicRateBitmap=0x%04lx)\n",
-		  RateIdToMbps[pAd->CommonCfg.TxRate],
-		  RateIdToMbps[pAd->CommonCfg.RtsRate], BasicRateBitmap));
-	DBGPRINT(RT_DEBUG_TRACE,
-		 ("MlmeUpdateTxRates (MlmeTransmit=0x%x, MinHTPhyMode=%x, MaxHTPhyMode=0x%x, HTPhyMode=0x%x)\n",
-		  pAd->CommonCfg.MlmeTransmit.word,
-		  pAd->MacTab.Content[BSSID_WCID].MinHTPhyMode.word,
-		  pAd->MacTab.Content[BSSID_WCID].MaxHTPhyMode.word,
-		  pAd->MacTab.Content[BSSID_WCID].HTPhyMode.word));
-}
-
-/*
-	==========================================================================
-	Description:
-		This function update HT Rate setting.
-		Input Wcid value is valid for 2 case :
-		1. it's used for Station in infra mode that copy AP rate to Mactable.
-		2. OR Station	in adhoc mode to copy peer's HT rate to Mactable.
-
- IRQL = DISPATCH_LEVEL
-
-	==========================================================================
- */
-void MlmeUpdateHtTxRates(struct rt_rtmp_adapter *pAd, u8 apidx)
-{
-	u8 StbcMcs;		/*j, StbcMcs, bitmask; */
-	char i;			/* 3*3 */
-	struct rt_ht_capability *pRtHtCap = NULL;
-	struct rt_ht_phy_info *pActiveHtPhy = NULL;
-	unsigned long BasicMCS;
-	u8 j, bitmask;
-	struct rt_ht_phy_info *pDesireHtPhy = NULL;
-	PHTTRANSMIT_SETTING pHtPhy = NULL;
-	PHTTRANSMIT_SETTING pMaxHtPhy = NULL;
-	PHTTRANSMIT_SETTING pMinHtPhy = NULL;
-	BOOLEAN *auto_rate_cur_p;
-
-	DBGPRINT(RT_DEBUG_TRACE, ("MlmeUpdateHtTxRates===> \n"));
-
-	auto_rate_cur_p = NULL;
-
-	{
-		pDesireHtPhy = &pAd->StaCfg.DesiredHtPhyInfo;
-		pActiveHtPhy = &pAd->StaCfg.DesiredHtPhyInfo;
-		pHtPhy = &pAd->StaCfg.HTPhyMode;
-		pMaxHtPhy = &pAd->StaCfg.MaxHTPhyMode;
-		pMinHtPhy = &pAd->StaCfg.MinHTPhyMode;
-
-		auto_rate_cur_p = &pAd->StaCfg.bAutoTxRateSwitch;
-	}
-
-	if ((ADHOC_ON(pAd) || INFRA_ON(pAd)) && (pAd->OpMode == OPMODE_STA)) {
-		if (pAd->StaActive.SupportedPhyInfo.bHtEnable == FALSE)
-			return;
-
-		pRtHtCap = &pAd->StaActive.SupportedHtPhy;
-		pActiveHtPhy = &pAd->StaActive.SupportedPhyInfo;
-		StbcMcs = (u8)pAd->MlmeAux.AddHtInfo.AddHtInfo3.StbcMcs;
-		BasicMCS =
-		    pAd->MlmeAux.AddHtInfo.MCSSet[0] +
-		    (pAd->MlmeAux.AddHtInfo.MCSSet[1] << 8) + (StbcMcs << 16);
-		if ((pAd->CommonCfg.DesiredHtPhy.TxSTBC) && (pRtHtCap->RxSTBC)
-		    && (pAd->Antenna.field.TxPath == 2))
-			pMaxHtPhy->field.STBC = STBC_USE;
-		else
-			pMaxHtPhy->field.STBC = STBC_NONE;
-	} else {
-		if (pDesireHtPhy->bHtEnable == FALSE)
-			return;
-
-		pRtHtCap = &pAd->CommonCfg.DesiredHtPhy;
-		StbcMcs = (u8)pAd->CommonCfg.AddHTInfo.AddHtInfo3.StbcMcs;
-		BasicMCS =
-		    pAd->CommonCfg.AddHTInfo.MCSSet[0] +
-		    (pAd->CommonCfg.AddHTInfo.MCSSet[1] << 8) + (StbcMcs << 16);
-		if ((pAd->CommonCfg.DesiredHtPhy.TxSTBC) && (pRtHtCap->RxSTBC)
-		    && (pAd->Antenna.field.TxPath == 2))
-			pMaxHtPhy->field.STBC = STBC_USE;
-		else
-			pMaxHtPhy->field.STBC = STBC_NONE;
-	}
-
-	/* Decide MAX ht rate. */
-	if ((pRtHtCap->GF) && (pAd->CommonCfg.DesiredHtPhy.GF))
-		pMaxHtPhy->field.MODE = MODE_HTGREENFIELD;
-	else
-		pMaxHtPhy->field.MODE = MODE_HTMIX;
-
-	if ((pAd->CommonCfg.DesiredHtPhy.ChannelWidth)
-	    && (pRtHtCap->ChannelWidth))
-		pMaxHtPhy->field.BW = BW_40;
-	else
-		pMaxHtPhy->field.BW = BW_20;
-
-	if (pMaxHtPhy->field.BW == BW_20)
-		pMaxHtPhy->field.ShortGI =
-		    (pAd->CommonCfg.DesiredHtPhy.ShortGIfor20 & pRtHtCap->
-		     ShortGIfor20);
-	else
-		pMaxHtPhy->field.ShortGI =
-		    (pAd->CommonCfg.DesiredHtPhy.ShortGIfor40 & pRtHtCap->
-		     ShortGIfor40);
-
-	if (pDesireHtPhy->MCSSet[4] != 0) {
-		pMaxHtPhy->field.MCS = 32;
-	}
-
-	for (i = 23; i >= 0; i--)	/* 3*3 */
-	{
-		j = i / 8;
-		bitmask = (1 << (i - (j * 8)));
-
-		if ((pActiveHtPhy->MCSSet[j] & bitmask)
-		    && (pDesireHtPhy->MCSSet[j] & bitmask)) {
-			pMaxHtPhy->field.MCS = i;
-			break;
-		}
-
-		if (i == 0)
-			break;
-	}
-
-	/* Copy MIN ht rate.  rt2860??? */
-	pMinHtPhy->field.BW = BW_20;
-	pMinHtPhy->field.MCS = 0;
-	pMinHtPhy->field.STBC = 0;
-	pMinHtPhy->field.ShortGI = 0;
-	/*If STA assigns fixed rate. update to fixed here. */
-	if ((pAd->OpMode == OPMODE_STA) && (pDesireHtPhy->MCSSet[0] != 0xff)) {
-		if (pDesireHtPhy->MCSSet[4] != 0) {
-			pMaxHtPhy->field.MCS = 32;
-			pMinHtPhy->field.MCS = 32;
-			DBGPRINT(RT_DEBUG_TRACE,
-				 ("MlmeUpdateHtTxRates<=== Use Fixed MCS = %d\n",
-				  pMinHtPhy->field.MCS));
-		}
-
-		for (i = 23; (char)i >= 0; i--)	/* 3*3 */
-		{
-			j = i / 8;
-			bitmask = (1 << (i - (j * 8)));
-			if ((pDesireHtPhy->MCSSet[j] & bitmask)
-			    && (pActiveHtPhy->MCSSet[j] & bitmask)) {
-				pMaxHtPhy->field.MCS = i;
-				pMinHtPhy->field.MCS = i;
-				break;
-			}
-			if (i == 0)
-				break;
-		}
-	}
-
-	/* Decide ht rate */
-	pHtPhy->field.STBC = pMaxHtPhy->field.STBC;
-	pHtPhy->field.BW = pMaxHtPhy->field.BW;
-	pHtPhy->field.MODE = pMaxHtPhy->field.MODE;
-	pHtPhy->field.MCS = pMaxHtPhy->field.MCS;
-	pHtPhy->field.ShortGI = pMaxHtPhy->field.ShortGI;
-
-	/* use default now. rt2860 */
-	if (pDesireHtPhy->MCSSet[0] != 0xff)
-		*auto_rate_cur_p = FALSE;
-	else
-		*auto_rate_cur_p = TRUE;
-
-	DBGPRINT(RT_DEBUG_TRACE,
-		 (" MlmeUpdateHtTxRates<---.AMsduSize = %d  \n",
-		  pAd->CommonCfg.DesiredHtPhy.AmsduSize));
-	DBGPRINT(RT_DEBUG_TRACE,
-		 ("TX: MCS[0] = %x (choose %d), BW = %d, ShortGI = %d, MODE = %d,  \n",
-		  pActiveHtPhy->MCSSet[0], pHtPhy->field.MCS, pHtPhy->field.BW,
-		  pHtPhy->field.ShortGI, pHtPhy->field.MODE));
-	DBGPRINT(RT_DEBUG_TRACE, ("MlmeUpdateHtTxRates<=== \n"));
-}
-
-void BATableInit(struct rt_rtmp_adapter *pAd, struct rt_ba_table *Tab)
-{
-	int i;
-
-	Tab->numAsOriginator = 0;
-	Tab->numAsRecipient = 0;
-	Tab->numDoneOriginator = 0;
-	NdisAllocateSpinLock(&pAd->BATabLock);
-	for (i = 0; i < MAX_LEN_OF_BA_REC_TABLE; i++) {
-		Tab->BARecEntry[i].REC_BA_Status = Recipient_NONE;
-		NdisAllocateSpinLock(&(Tab->BARecEntry[i].RxReRingLock));
-	}
-	for (i = 0; i < MAX_LEN_OF_BA_ORI_TABLE; i++) {
-		Tab->BAOriEntry[i].ORI_BA_Status = Originator_NONE;
-	}
-}
-
-/* IRQL = DISPATCH_LEVEL */
-void MlmeRadioOff(struct rt_rtmp_adapter *pAd)
-{
-	RTMP_MLME_RADIO_OFF(pAd);
-}
-
-/* IRQL = DISPATCH_LEVEL */
-void MlmeRadioOn(struct rt_rtmp_adapter *pAd)
-{
-	RTMP_MLME_RADIO_ON(pAd);
-}
-
-/* =========================================================================================== */
-/* bss_table.c */
-/* =========================================================================================== */
-
-/*! \brief initialize BSS table
- *	\param p_tab pointer to the table
- *	\return none
- *	\pre
- *	\post
-
- IRQL = PASSIVE_LEVEL
- IRQL = DISPATCH_LEVEL
-
- */
-void BssTableInit(struct rt_bss_table *Tab)
-{
-	int i;
-
-	Tab->BssNr = 0;
-	Tab->BssOverlapNr = 0;
-	for (i = 0; i < MAX_LEN_OF_BSS_TABLE; i++) {
-		NdisZeroMemory(&Tab->BssEntry[i], sizeof(struct rt_bss_entry));
-		Tab->BssEntry[i].Rssi = -127;	/* initial the rssi as a minimum value */
-	}
-}
-
-/*! \brief search the BSS table by SSID
- *	\param p_tab pointer to the bss table
- *	\param ssid SSID string
- *	\return index of the table, BSS_NOT_FOUND if not in the table
- *	\pre
- *	\post
- *	\note search by sequential search
-
- IRQL = DISPATCH_LEVEL
-
- */
-unsigned long BssTableSearch(struct rt_bss_table *Tab, u8 *pBssid, u8 Channel)
-{
-	u8 i;
-
-	for (i = 0; i < Tab->BssNr; i++) {
-		/* */
-		/* Some AP that support A/B/G mode that may used the same BSSID on 11A and 11B/G. */
-		/* We should distinguish this case. */
-		/* */
-		if ((((Tab->BssEntry[i].Channel <= 14) && (Channel <= 14)) ||
-		     ((Tab->BssEntry[i].Channel > 14) && (Channel > 14))) &&
-		    MAC_ADDR_EQUAL(Tab->BssEntry[i].Bssid, pBssid)) {
-			return i;
-		}
-	}
-	return (unsigned long)BSS_NOT_FOUND;
-}
-
-unsigned long BssSsidTableSearch(struct rt_bss_table *Tab,
-			 u8 *pBssid,
-			 u8 *pSsid, u8 SsidLen, u8 Channel)
-{
-	u8 i;
-
-	for (i = 0; i < Tab->BssNr; i++) {
-		/* */
-		/* Some AP that support A/B/G mode that may used the same BSSID on 11A and 11B/G. */
-		/* We should distinguish this case. */
-		/* */
-		if ((((Tab->BssEntry[i].Channel <= 14) && (Channel <= 14)) ||
-		     ((Tab->BssEntry[i].Channel > 14) && (Channel > 14))) &&
-		    MAC_ADDR_EQUAL(Tab->BssEntry[i].Bssid, pBssid) &&
-		    SSID_EQUAL(pSsid, SsidLen, Tab->BssEntry[i].Ssid,
-			       Tab->BssEntry[i].SsidLen)) {
-			return i;
-		}
-	}
-	return (unsigned long)BSS_NOT_FOUND;
-}
-
-unsigned long BssTableSearchWithSSID(struct rt_bss_table *Tab,
-			     u8 *Bssid,
-			     u8 *pSsid,
-			     u8 SsidLen, u8 Channel)
-{
-	u8 i;
-
-	for (i = 0; i < Tab->BssNr; i++) {
-		if ((((Tab->BssEntry[i].Channel <= 14) && (Channel <= 14)) ||
-		     ((Tab->BssEntry[i].Channel > 14) && (Channel > 14))) &&
-		    MAC_ADDR_EQUAL(&(Tab->BssEntry[i].Bssid), Bssid) &&
-		    (SSID_EQUAL
-		     (pSsid, SsidLen, Tab->BssEntry[i].Ssid,
-		      Tab->BssEntry[i].SsidLen)
-		     || (NdisEqualMemory(pSsid, ZeroSsid, SsidLen))
-		     ||
-		     (NdisEqualMemory
-		      (Tab->BssEntry[i].Ssid, ZeroSsid,
-		       Tab->BssEntry[i].SsidLen)))) {
-			return i;
-		}
-	}
-	return (unsigned long)BSS_NOT_FOUND;
-}
-
-unsigned long BssSsidTableSearchBySSID(struct rt_bss_table *Tab,
-			       u8 *pSsid, u8 SsidLen)
-{
-	u8 i;
-
-	for (i = 0; i < Tab->BssNr; i++) {
-		if (SSID_EQUAL
-		    (pSsid, SsidLen, Tab->BssEntry[i].Ssid,
-		     Tab->BssEntry[i].SsidLen)) {
-			return i;
-		}
-	}
-	return (unsigned long)BSS_NOT_FOUND;
-}
-
-/* IRQL = DISPATCH_LEVEL */
-void BssTableDeleteEntry(struct rt_bss_table *Tab,
-			 u8 *pBssid, u8 Channel)
-{
-	u8 i, j;
-
-	for (i = 0; i < Tab->BssNr; i++) {
-		if ((Tab->BssEntry[i].Channel == Channel) &&
-		    (MAC_ADDR_EQUAL(Tab->BssEntry[i].Bssid, pBssid))) {
-			for (j = i; j < Tab->BssNr - 1; j++) {
-				NdisMoveMemory(&(Tab->BssEntry[j]),
-					       &(Tab->BssEntry[j + 1]),
-					       sizeof(struct rt_bss_entry));
-			}
-			NdisZeroMemory(&(Tab->BssEntry[Tab->BssNr - 1]),
-				       sizeof(struct rt_bss_entry));
-			Tab->BssNr -= 1;
-			return;
-		}
-	}
-}
-
-/*
-	========================================================================
-	Routine Description:
-		Delete the Originator Entry in BAtable. Or decrease numAs Originator by 1 if needed.
-
-	Arguments:
-	// IRQL = DISPATCH_LEVEL
-	========================================================================
-*/
-void BATableDeleteORIEntry(struct rt_rtmp_adapter *pAd,
-			   struct rt_ba_ori_entry *pBAORIEntry)
-{
-
-	if (pBAORIEntry->ORI_BA_Status != Originator_NONE) {
-		NdisAcquireSpinLock(&pAd->BATabLock);
-		if (pBAORIEntry->ORI_BA_Status == Originator_Done) {
-			pAd->BATable.numAsOriginator -= 1;
-			DBGPRINT(RT_DEBUG_TRACE,
-				 ("BATableDeleteORIEntry numAsOriginator= %ld\n",
-				  pAd->BATable.numAsRecipient));
-			/* Erase Bitmap flag. */
-		}
-		pAd->MacTab.Content[pBAORIEntry->Wcid].TXBAbitmap &= (~(1 << (pBAORIEntry->TID)));	/* If STA mode,  erase flag here */
-		pAd->MacTab.Content[pBAORIEntry->Wcid].BAOriWcidArray[pBAORIEntry->TID] = 0;	/* If STA mode,  erase flag here */
-		pBAORIEntry->ORI_BA_Status = Originator_NONE;
-		pBAORIEntry->Token = 1;
-		/* Not clear Sequence here. */
-		NdisReleaseSpinLock(&pAd->BATabLock);
-	}
-}
-
-/*! \brief
- *	\param
- *	\return
- *	\pre
- *	\post
-
- IRQL = DISPATCH_LEVEL
-
- */
-void BssEntrySet(struct rt_rtmp_adapter *pAd, struct rt_bss_entry *pBss, u8 *pBssid, char Ssid[], u8 SsidLen, u8 BssType, u16 BeaconPeriod, struct rt_cf_parm * pCfParm, u16 AtimWin, u16 CapabilityInfo, u8 SupRate[], u8 SupRateLen, u8 ExtRate[], u8 ExtRateLen, struct rt_ht_capability_ie * pHtCapability, struct rt_add_ht_info_ie * pAddHtInfo,	/* AP might use this additional ht info IE */
-		 u8 HtCapabilityLen,
-		 u8 AddHtInfoLen,
-		 u8 NewExtChanOffset,
-		 u8 Channel,
-		 char Rssi,
-		 IN LARGE_INTEGER TimeStamp,
-		 u8 CkipFlag,
-		 struct rt_edca_parm *pEdcaParm,
-		 struct rt_qos_capability_parm *pQosCapability,
-		 struct rt_qbss_load_parm *pQbssLoad,
-		 u16 LengthVIE, struct rt_ndis_802_11_variable_ies *pVIE)
-{
-	COPY_MAC_ADDR(pBss->Bssid, pBssid);
-	/* Default Hidden SSID to be TRUE, it will be turned to FALSE after coping SSID */
-	pBss->Hidden = 1;
-	if (SsidLen > 0) {
-		/* For hidden SSID AP, it might send beacon with SSID len equal to 0 */
-		/* Or send beacon /probe response with SSID len matching real SSID length, */
-		/* but SSID is all zero. such as "00-00-00-00" with length 4. */
-		/* We have to prevent this case overwrite correct table */
-		if (NdisEqualMemory(Ssid, ZeroSsid, SsidLen) == 0) {
-			NdisZeroMemory(pBss->Ssid, MAX_LEN_OF_SSID);
-			NdisMoveMemory(pBss->Ssid, Ssid, SsidLen);
-			pBss->SsidLen = SsidLen;
-			pBss->Hidden = 0;
-		}
-	} else
-		pBss->SsidLen = 0;
-	pBss->BssType = BssType;
-	pBss->BeaconPeriod = BeaconPeriod;
-	if (BssType == BSS_INFRA) {
-		if (pCfParm->bValid) {
-			pBss->CfpCount = pCfParm->CfpCount;
-			pBss->CfpPeriod = pCfParm->CfpPeriod;
-			pBss->CfpMaxDuration = pCfParm->CfpMaxDuration;
-			pBss->CfpDurRemaining = pCfParm->CfpDurRemaining;
-		}
-	} else {
-		pBss->AtimWin = AtimWin;
-	}
-
-	pBss->CapabilityInfo = CapabilityInfo;
-	/* The privacy bit indicate security is ON, it maight be WEP, TKIP or AES */
-	/* Combine with AuthMode, they will decide the connection methods. */
-	pBss->Privacy = CAP_IS_PRIVACY_ON(pBss->CapabilityInfo);
-	ASSERT(SupRateLen <= MAX_LEN_OF_SUPPORTED_RATES);
-	if (SupRateLen <= MAX_LEN_OF_SUPPORTED_RATES)
-		NdisMoveMemory(pBss->SupRate, SupRate, SupRateLen);
-	else
-		NdisMoveMemory(pBss->SupRate, SupRate,
-			       MAX_LEN_OF_SUPPORTED_RATES);
-	pBss->SupRateLen = SupRateLen;
-	ASSERT(ExtRateLen <= MAX_LEN_OF_SUPPORTED_RATES);
-	NdisMoveMemory(pBss->ExtRate, ExtRate, ExtRateLen);
-	pBss->NewExtChanOffset = NewExtChanOffset;
-	pBss->ExtRateLen = ExtRateLen;
-	pBss->Channel = Channel;
-	pBss->CentralChannel = Channel;
-	pBss->Rssi = Rssi;
-	/* Update CkipFlag. if not exists, the value is 0x0 */
-	pBss->CkipFlag = CkipFlag;
-
-	/* New for microsoft Fixed IEs */
-	NdisMoveMemory(pBss->FixIEs.Timestamp, &TimeStamp, 8);
-	pBss->FixIEs.BeaconInterval = BeaconPeriod;
-	pBss->FixIEs.Capabilities = CapabilityInfo;
-
-	/* New for microsoft Variable IEs */
-	if (LengthVIE != 0) {
-		pBss->VarIELen = LengthVIE;
-		NdisMoveMemory(pBss->VarIEs, pVIE, pBss->VarIELen);
-	} else {
-		pBss->VarIELen = 0;
-	}
-
-	pBss->AddHtInfoLen = 0;
-	pBss->HtCapabilityLen = 0;
-	if (HtCapabilityLen > 0) {
-		pBss->HtCapabilityLen = HtCapabilityLen;
-		NdisMoveMemory(&pBss->HtCapability, pHtCapability,
-			       HtCapabilityLen);
-		if (AddHtInfoLen > 0) {
-			pBss->AddHtInfoLen = AddHtInfoLen;
-			NdisMoveMemory(&pBss->AddHtInfo, pAddHtInfo,
-				       AddHtInfoLen);
-
-			if ((pAddHtInfo->ControlChan > 2)
-			    && (pAddHtInfo->AddHtInfo.ExtChanOffset ==
-				EXTCHA_BELOW)
-			    && (pHtCapability->HtCapInfo.ChannelWidth ==
-				BW_40)) {
-				pBss->CentralChannel =
-				    pAddHtInfo->ControlChan - 2;
-			} else
-			    if ((pAddHtInfo->AddHtInfo.ExtChanOffset ==
-				 EXTCHA_ABOVE)
-				&& (pHtCapability->HtCapInfo.ChannelWidth ==
-				    BW_40)) {
-				pBss->CentralChannel =
-				    pAddHtInfo->ControlChan + 2;
-			}
-		}
-	}
-
-	BssCipherParse(pBss);
-
-	/* new for QOS */
-	if (pEdcaParm)
-		NdisMoveMemory(&pBss->EdcaParm, pEdcaParm, sizeof(struct rt_edca_parm));
-	else
-		pBss->EdcaParm.bValid = FALSE;
-	if (pQosCapability)
-		NdisMoveMemory(&pBss->QosCapability, pQosCapability,
-			       sizeof(struct rt_qos_capability_parm));
-	else
-		pBss->QosCapability.bValid = FALSE;
-	if (pQbssLoad)
-		NdisMoveMemory(&pBss->QbssLoad, pQbssLoad,
-			       sizeof(struct rt_qbss_load_parm));
-	else
-		pBss->QbssLoad.bValid = FALSE;
-
-	{
-		struct rt_eid * pEid;
-		u16 Length = 0;
-
-		NdisZeroMemory(&pBss->WpaIE.IE[0], MAX_CUSTOM_LEN);
-		NdisZeroMemory(&pBss->RsnIE.IE[0], MAX_CUSTOM_LEN);
-		pEid = (struct rt_eid *) pVIE;
-		while ((Length + 2 + (u16)pEid->Len) <= LengthVIE) {
-			switch (pEid->Eid) {
-			case IE_WPA:
-				if (NdisEqualMemory(pEid->Octet, WPA_OUI, 4)) {
-					if ((pEid->Len + 2) > MAX_CUSTOM_LEN) {
-						pBss->WpaIE.IELen = 0;
-						break;
-					}
-					pBss->WpaIE.IELen = pEid->Len + 2;
-					NdisMoveMemory(pBss->WpaIE.IE, pEid,
-						       pBss->WpaIE.IELen);
-				}
-				break;
-			case IE_RSN:
-				if (NdisEqualMemory
-				    (pEid->Octet + 2, RSN_OUI, 3)) {
-					if ((pEid->Len + 2) > MAX_CUSTOM_LEN) {
-						pBss->RsnIE.IELen = 0;
-						break;
-					}
-					pBss->RsnIE.IELen = pEid->Len + 2;
-					NdisMoveMemory(pBss->RsnIE.IE, pEid,
-						       pBss->RsnIE.IELen);
-				}
-				break;
-			}
-			Length = Length + 2 + (u16)pEid->Len;	/* Eid[1] + Len[1]+ content[Len] */
-			pEid = (struct rt_eid *) ((u8 *) pEid + 2 + pEid->Len);
-		}
-	}
-}
-
-/*!
- *	\brief insert an entry into the bss table
- *	\param p_tab The BSS table
- *	\param Bssid BSSID
- *	\param ssid SSID
- *	\param ssid_len Length of SSID
- *	\param bss_type
- *	\param beacon_period
- *	\param timestamp
- *	\param p_cf
- *	\param atim_win
- *	\param cap
- *	\param rates
- *	\param rates_len
- *	\param channel_idx
- *	\return none
- *	\pre
- *	\post
- *	\note If SSID is identical, the old entry will be replaced by the new one
-
- IRQL = DISPATCH_LEVEL
-
- */
-unsigned long BssTableSetEntry(struct rt_rtmp_adapter *pAd, struct rt_bss_table *Tab, u8 *pBssid, char Ssid[], u8 SsidLen, u8 BssType, u16 BeaconPeriod, struct rt_cf_parm * CfParm, u16 AtimWin, u16 CapabilityInfo, u8 SupRate[], u8 SupRateLen, u8 ExtRate[], u8 ExtRateLen, struct rt_ht_capability_ie * pHtCapability, struct rt_add_ht_info_ie * pAddHtInfo,	/* AP might use this additional ht info IE */
-		       u8 HtCapabilityLen,
-		       u8 AddHtInfoLen,
-		       u8 NewExtChanOffset,
-		       u8 ChannelNo,
-		       char Rssi,
-		       IN LARGE_INTEGER TimeStamp,
-		       u8 CkipFlag,
-		       struct rt_edca_parm *pEdcaParm,
-		       struct rt_qos_capability_parm *pQosCapability,
-		       struct rt_qbss_load_parm *pQbssLoad,
-		       u16 LengthVIE, struct rt_ndis_802_11_variable_ies *pVIE)
-{
-	unsigned long Idx;
-
-	Idx =
-	    BssTableSearchWithSSID(Tab, pBssid, (u8 *) Ssid, SsidLen,
-				   ChannelNo);
-	if (Idx == BSS_NOT_FOUND) {
-		if (Tab->BssNr >= MAX_LEN_OF_BSS_TABLE) {
-			/* */
-			/* It may happen when BSS Table was full. */
-			/* The desired AP will not be added into BSS Table */
-			/* In this case, if we found the desired AP then overwrite BSS Table. */
-			/* */
-			if (!OPSTATUS_TEST_FLAG
-			    (pAd, fOP_STATUS_MEDIA_STATE_CONNECTED)) {
-				if (MAC_ADDR_EQUAL(pAd->MlmeAux.Bssid, pBssid)
-				    || SSID_EQUAL(pAd->MlmeAux.Ssid,
-						  pAd->MlmeAux.SsidLen, Ssid,
-						  SsidLen)) {
-					Idx = Tab->BssOverlapNr;
-					BssEntrySet(pAd, &Tab->BssEntry[Idx],
-						    pBssid, Ssid, SsidLen,
-						    BssType, BeaconPeriod,
-						    CfParm, AtimWin,
-						    CapabilityInfo, SupRate,
-						    SupRateLen, ExtRate,
-						    ExtRateLen, pHtCapability,
-						    pAddHtInfo, HtCapabilityLen,
-						    AddHtInfoLen,
-						    NewExtChanOffset, ChannelNo,
-						    Rssi, TimeStamp, CkipFlag,
-						    pEdcaParm, pQosCapability,
-						    pQbssLoad, LengthVIE, pVIE);
-					Tab->BssOverlapNr =
-					    (Tab->BssOverlapNr++) %
-					    MAX_LEN_OF_BSS_TABLE;
-				}
-				return Idx;
-			} else {
-				return BSS_NOT_FOUND;
-			}
-		}
-		Idx = Tab->BssNr;
-		BssEntrySet(pAd, &Tab->BssEntry[Idx], pBssid, Ssid, SsidLen,
-			    BssType, BeaconPeriod, CfParm, AtimWin,
-			    CapabilityInfo, SupRate, SupRateLen, ExtRate,
-			    ExtRateLen, pHtCapability, pAddHtInfo,
-			    HtCapabilityLen, AddHtInfoLen, NewExtChanOffset,
-			    ChannelNo, Rssi, TimeStamp, CkipFlag, pEdcaParm,
-			    pQosCapability, pQbssLoad, LengthVIE, pVIE);
-		Tab->BssNr++;
-	} else {
-		/* avoid  Hidden SSID form beacon to overwirite correct SSID from probe response */
-		if ((SSID_EQUAL
-		     (Ssid, SsidLen, Tab->BssEntry[Idx].Ssid,
-		      Tab->BssEntry[Idx].SsidLen))
-		    ||
-		    (NdisEqualMemory
-		     (Tab->BssEntry[Idx].Ssid, ZeroSsid,
-		      Tab->BssEntry[Idx].SsidLen))) {
-			BssEntrySet(pAd, &Tab->BssEntry[Idx], pBssid, Ssid,
-				    SsidLen, BssType, BeaconPeriod, CfParm,
-				    AtimWin, CapabilityInfo, SupRate,
-				    SupRateLen, ExtRate, ExtRateLen,
-				    pHtCapability, pAddHtInfo, HtCapabilityLen,
-				    AddHtInfoLen, NewExtChanOffset, ChannelNo,
-				    Rssi, TimeStamp, CkipFlag, pEdcaParm,
-				    pQosCapability, pQbssLoad, LengthVIE, pVIE);
-		}
-	}
-
-	return Idx;
-}
-
-/* IRQL = DISPATCH_LEVEL */
-void BssTableSsidSort(struct rt_rtmp_adapter *pAd,
-		      struct rt_bss_table *OutTab, char Ssid[], u8 SsidLen)
-{
-	int i;
-	BssTableInit(OutTab);
-
-	for (i = 0; i < pAd->ScanTab.BssNr; i++) {
-		struct rt_bss_entry *pInBss = &pAd->ScanTab.BssEntry[i];
-		BOOLEAN bIsHiddenApIncluded = FALSE;
-
-		if (((pAd->CommonCfg.bIEEE80211H == 1) &&
-		     (pAd->MlmeAux.Channel > 14) &&
-		     RadarChannelCheck(pAd, pInBss->Channel))
-		    ) {
-			if (pInBss->Hidden)
-				bIsHiddenApIncluded = TRUE;
-		}
-
-		if ((pInBss->BssType == pAd->StaCfg.BssType) &&
-		    (SSID_EQUAL(Ssid, SsidLen, pInBss->Ssid, pInBss->SsidLen)
-		     || bIsHiddenApIncluded)) {
-			struct rt_bss_entry *pOutBss = &OutTab->BssEntry[OutTab->BssNr];
-
-			/* 2.4G/5G N only mode */
-			if ((pInBss->HtCapabilityLen == 0) &&
-			    ((pAd->CommonCfg.PhyMode == PHY_11N_2_4G)
-			     || (pAd->CommonCfg.PhyMode == PHY_11N_5G))) {
-				DBGPRINT(RT_DEBUG_TRACE,
-					 ("STA is in N-only Mode, this AP don't have Ht capability in Beacon.\n"));
-				continue;
-			}
-			/* New for WPA2 */
-			/* Check the Authmode first */
-			if (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA) {
-				/* Check AuthMode and AuthModeAux for matching, in case AP support dual-mode */
-				if ((pAd->StaCfg.AuthMode != pInBss->AuthMode)
-				    && (pAd->StaCfg.AuthMode !=
-					pInBss->AuthModeAux))
-					/* None matched */
-					continue;
-
-				/* Check cipher suite, AP must have more secured cipher than station setting */
-				if ((pAd->StaCfg.AuthMode ==
-				     Ndis802_11AuthModeWPA)
-				    || (pAd->StaCfg.AuthMode ==
-					Ndis802_11AuthModeWPAPSK)) {
-					/* If it's not mixed mode, we should only let BSS pass with the same encryption */
-					if (pInBss->WPA.bMixMode == FALSE)
-						if (pAd->StaCfg.WepStatus !=
-						    pInBss->WPA.GroupCipher)
-							continue;
-
-					/* check group cipher */
-					if ((pAd->StaCfg.WepStatus <
-					     pInBss->WPA.GroupCipher)
-					    && (pInBss->WPA.GroupCipher !=
-						Ndis802_11GroupWEP40Enabled)
-					    && (pInBss->WPA.GroupCipher !=
-						Ndis802_11GroupWEP104Enabled))
-						continue;
-
-					/* check pairwise cipher, skip if none matched */
-					/* If profile set to AES, let it pass without question. */
-					/* If profile set to TKIP, we must find one mateched */
-					if ((pAd->StaCfg.WepStatus ==
-					     Ndis802_11Encryption2Enabled)
-					    && (pAd->StaCfg.WepStatus !=
-						pInBss->WPA.PairCipher)
-					    && (pAd->StaCfg.WepStatus !=
-						pInBss->WPA.PairCipherAux))
-						continue;
-				} else
-				    if ((pAd->StaCfg.AuthMode ==
-					 Ndis802_11AuthModeWPA2)
-					|| (pAd->StaCfg.AuthMode ==
-					    Ndis802_11AuthModeWPA2PSK)) {
-					/* If it's not mixed mode, we should only let BSS pass with the same encryption */
-					if (pInBss->WPA2.bMixMode == FALSE)
-						if (pAd->StaCfg.WepStatus !=
-						    pInBss->WPA2.GroupCipher)
-							continue;
-
-					/* check group cipher */
-					if ((pAd->StaCfg.WepStatus <
-					     pInBss->WPA.GroupCipher)
-					    && (pInBss->WPA2.GroupCipher !=
-						Ndis802_11GroupWEP40Enabled)
-					    && (pInBss->WPA2.GroupCipher !=
-						Ndis802_11GroupWEP104Enabled))
-						continue;
-
-					/* check pairwise cipher, skip if none matched */
-					/* If profile set to AES, let it pass without question. */
-					/* If profile set to TKIP, we must find one mateched */
-					if ((pAd->StaCfg.WepStatus ==
-					     Ndis802_11Encryption2Enabled)
-					    && (pAd->StaCfg.WepStatus !=
-						pInBss->WPA2.PairCipher)
-					    && (pAd->StaCfg.WepStatus !=
-						pInBss->WPA2.PairCipherAux))
-						continue;
-				}
-			}
-			/* Bss Type matched, SSID matched. */
-			/* We will check wepstatus for qualification Bss */
-			else if (pAd->StaCfg.WepStatus != pInBss->WepStatus) {
-				DBGPRINT(RT_DEBUG_TRACE,
-					 ("StaCfg.WepStatus=%d, while pInBss->WepStatus=%d\n",
-					  pAd->StaCfg.WepStatus,
-					  pInBss->WepStatus));
-				/* */
-				/* For the SESv2 case, we will not qualify WepStatus. */
-				/* */
-				if (!pInBss->bSES)
-					continue;
-			}
-			/* Since the AP is using hidden SSID, and we are trying to connect to ANY */
-			/* It definitely will fail. So, skip it. */
-			/* CCX also require not even try to connect it! */
-			if (SsidLen == 0)
-				continue;
-
-			/* If both station and AP use 40MHz, still need to check if the 40MHZ band's legality in my country region */
-			/* If this 40MHz wideband is not allowed in my country list, use bandwidth 20MHZ instead, */
-			if ((pInBss->CentralChannel != pInBss->Channel) &&
-			    (pAd->CommonCfg.RegTransmitSetting.field.BW ==
-			     BW_40)) {
-				if (RTMPCheckChannel
-				    (pAd, pInBss->CentralChannel,
-				     pInBss->Channel) == FALSE) {
-					pAd->CommonCfg.RegTransmitSetting.field.
-					    BW = BW_20;
-					SetCommonHT(pAd);
-					pAd->CommonCfg.RegTransmitSetting.field.
-					    BW = BW_40;
-				} else {
-					if (pAd->CommonCfg.DesiredHtPhy.
-					    ChannelWidth == BAND_WIDTH_20) {
-						SetCommonHT(pAd);
-					}
-				}
-			}
-			/* copy matching BSS from InTab to OutTab */
-			NdisMoveMemory(pOutBss, pInBss, sizeof(struct rt_bss_entry));
-
-			OutTab->BssNr++;
-		} else if ((pInBss->BssType == pAd->StaCfg.BssType)
-			   && (SsidLen == 0)) {
-			struct rt_bss_entry *pOutBss = &OutTab->BssEntry[OutTab->BssNr];
-
-			/* 2.4G/5G N only mode */
-			if ((pInBss->HtCapabilityLen == 0) &&
-			    ((pAd->CommonCfg.PhyMode == PHY_11N_2_4G)
-			     || (pAd->CommonCfg.PhyMode == PHY_11N_5G))) {
-				DBGPRINT(RT_DEBUG_TRACE,
-					 ("STA is in N-only Mode, this AP don't have Ht capability in Beacon.\n"));
-				continue;
-			}
-			/* New for WPA2 */
-			/* Check the Authmode first */
-			if (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA) {
-				/* Check AuthMode and AuthModeAux for matching, in case AP support dual-mode */
-				if ((pAd->StaCfg.AuthMode != pInBss->AuthMode)
-				    && (pAd->StaCfg.AuthMode !=
-					pInBss->AuthModeAux))
-					/* None matched */
-					continue;
-
-				/* Check cipher suite, AP must have more secured cipher than station setting */
-				if ((pAd->StaCfg.AuthMode ==
-				     Ndis802_11AuthModeWPA)
-				    || (pAd->StaCfg.AuthMode ==
-					Ndis802_11AuthModeWPAPSK)) {
-					/* If it's not mixed mode, we should only let BSS pass with the same encryption */
-					if (pInBss->WPA.bMixMode == FALSE)
-						if (pAd->StaCfg.WepStatus !=
-						    pInBss->WPA.GroupCipher)
-							continue;
-
-					/* check group cipher */
-					if (pAd->StaCfg.WepStatus <
-					    pInBss->WPA.GroupCipher)
-						continue;
-
-					/* check pairwise cipher, skip if none matched */
-					/* If profile set to AES, let it pass without question. */
-					/* If profile set to TKIP, we must find one mateched */
-					if ((pAd->StaCfg.WepStatus ==
-					     Ndis802_11Encryption2Enabled)
-					    && (pAd->StaCfg.WepStatus !=
-						pInBss->WPA.PairCipher)
-					    && (pAd->StaCfg.WepStatus !=
-						pInBss->WPA.PairCipherAux))
-						continue;
-				} else
-				    if ((pAd->StaCfg.AuthMode ==
-					 Ndis802_11AuthModeWPA2)
-					|| (pAd->StaCfg.AuthMode ==
-					    Ndis802_11AuthModeWPA2PSK)) {
-					/* If it's not mixed mode, we should only let BSS pass with the same encryption */
-					if (pInBss->WPA2.bMixMode == FALSE)
-						if (pAd->StaCfg.WepStatus !=
-						    pInBss->WPA2.GroupCipher)
-							continue;
-
-					/* check group cipher */
-					if (pAd->StaCfg.WepStatus <
-					    pInBss->WPA2.GroupCipher)
-						continue;
-
-					/* check pairwise cipher, skip if none matched */
-					/* If profile set to AES, let it pass without question. */
-					/* If profile set to TKIP, we must find one mateched */
-					if ((pAd->StaCfg.WepStatus ==
-					     Ndis802_11Encryption2Enabled)
-					    && (pAd->StaCfg.WepStatus !=
-						pInBss->WPA2.PairCipher)
-					    && (pAd->StaCfg.WepStatus !=
-						pInBss->WPA2.PairCipherAux))
-						continue;
-				}
-			}
-			/* Bss Type matched, SSID matched. */
-			/* We will check wepstatus for qualification Bss */
-			else if (pAd->StaCfg.WepStatus != pInBss->WepStatus)
-				continue;
-
-			/* If both station and AP use 40MHz, still need to check if the 40MHZ band's legality in my country region */
-			/* If this 40MHz wideband is not allowed in my country list, use bandwidth 20MHZ instead, */
-			if ((pInBss->CentralChannel != pInBss->Channel) &&
-			    (pAd->CommonCfg.RegTransmitSetting.field.BW ==
-			     BW_40)) {
-				if (RTMPCheckChannel
-				    (pAd, pInBss->CentralChannel,
-				     pInBss->Channel) == FALSE) {
-					pAd->CommonCfg.RegTransmitSetting.field.
-					    BW = BW_20;
-					SetCommonHT(pAd);
-					pAd->CommonCfg.RegTransmitSetting.field.
-					    BW = BW_40;
-				}
-			}
-			/* copy matching BSS from InTab to OutTab */
-			NdisMoveMemory(pOutBss, pInBss, sizeof(struct rt_bss_entry));
-
-			OutTab->BssNr++;
-		}
-
-		if (OutTab->BssNr >= MAX_LEN_OF_BSS_TABLE)
-			break;
-	}
-
-	BssTableSortByRssi(OutTab);
-}
-
-/* IRQL = DISPATCH_LEVEL */
-void BssTableSortByRssi(struct rt_bss_table *OutTab)
-{
-	int i, j;
-	struct rt_bss_entry TmpBss;
-
-	for (i = 0; i < OutTab->BssNr - 1; i++) {
-		for (j = i + 1; j < OutTab->BssNr; j++) {
-			if (OutTab->BssEntry[j].Rssi > OutTab->BssEntry[i].Rssi) {
-				NdisMoveMemory(&TmpBss, &OutTab->BssEntry[j],
-					       sizeof(struct rt_bss_entry));
-				NdisMoveMemory(&OutTab->BssEntry[j],
-					       &OutTab->BssEntry[i],
-					       sizeof(struct rt_bss_entry));
-				NdisMoveMemory(&OutTab->BssEntry[i], &TmpBss,
-					       sizeof(struct rt_bss_entry));
-			}
-		}
-	}
-}
-
-void BssCipherParse(struct rt_bss_entry *pBss)
-{
-	struct rt_eid * pEid;
-	u8 *pTmp;
-	struct rt_rsn_ie_header * pRsnHeader;
-	struct rt_cipher_suite_struct * pCipher;
-	struct rt_akm_suite * pAKM;
-	u16 Count;
-	int Length;
-	NDIS_802_11_ENCRYPTION_STATUS TmpCipher;
-
-	/* */
-	/* WepStatus will be reset later, if AP announce TKIP or AES on the beacon frame. */
-	/* */
-	if (pBss->Privacy) {
-		pBss->WepStatus = Ndis802_11WEPEnabled;
-	} else {
-		pBss->WepStatus = Ndis802_11WEPDisabled;
-	}
-	/* Set default to disable & open authentication before parsing variable IE */
-	pBss->AuthMode = Ndis802_11AuthModeOpen;
-	pBss->AuthModeAux = Ndis802_11AuthModeOpen;
-
-	/* Init WPA setting */
-	pBss->WPA.PairCipher = Ndis802_11WEPDisabled;
-	pBss->WPA.PairCipherAux = Ndis802_11WEPDisabled;
-	pBss->WPA.GroupCipher = Ndis802_11WEPDisabled;
-	pBss->WPA.RsnCapability = 0;
-	pBss->WPA.bMixMode = FALSE;
-
-	/* Init WPA2 setting */
-	pBss->WPA2.PairCipher = Ndis802_11WEPDisabled;
-	pBss->WPA2.PairCipherAux = Ndis802_11WEPDisabled;
-	pBss->WPA2.GroupCipher = Ndis802_11WEPDisabled;
-	pBss->WPA2.RsnCapability = 0;
-	pBss->WPA2.bMixMode = FALSE;
-
-	Length = (int)pBss->VarIELen;
-
-	while (Length > 0) {
-		/* Parse cipher suite base on WPA1 & WPA2, they should be parsed differently */
-		pTmp = ((u8 *)pBss->VarIEs) + pBss->VarIELen - Length;
-		pEid = (struct rt_eid *) pTmp;
-		switch (pEid->Eid) {
-		case IE_WPA:
-			if (NdisEqualMemory(pEid->Octet, SES_OUI, 3)
-			    && (pEid->Len == 7)) {
-				pBss->bSES = TRUE;
-				break;
-			} else if (NdisEqualMemory(pEid->Octet, WPA_OUI, 4) !=
-				   1) {
-				/* if unsupported vendor specific IE */
-				break;
-			}
-			/* Skip OUI, version, and multicast suite */
-			/* This part should be improved in the future when AP supported multiple cipher suite. */
-			/* For now, it's OK since almost all APs have fixed cipher suite supported. */
-			/* pTmp = (u8 *)pEid->Octet; */
-			pTmp += 11;
-
-			/* Cipher Suite Selectors from Spec P802.11i/D3.2 P26. */
-			/*      Value      Meaning */
-			/*      0                       None */
-			/*      1                       WEP-40 */
-			/*      2                       Tkip */
-			/*      3                       WRAP */
-			/*      4                       AES */
-			/*      5                       WEP-104 */
-			/* Parse group cipher */
-			switch (*pTmp) {
-			case 1:
-				pBss->WPA.GroupCipher =
-				    Ndis802_11GroupWEP40Enabled;
-				break;
-			case 5:
-				pBss->WPA.GroupCipher =
-				    Ndis802_11GroupWEP104Enabled;
-				break;
-			case 2:
-				pBss->WPA.GroupCipher =
-				    Ndis802_11Encryption2Enabled;
-				break;
-			case 4:
-				pBss->WPA.GroupCipher =
-				    Ndis802_11Encryption3Enabled;
-				break;
-			default:
-				break;
-			}
-			/* number of unicast suite */
-			pTmp += 1;
-
-			/* skip all unicast cipher suites */
-			/*Count = *(u16 *)pTmp; */
-			Count = (pTmp[1] << 8) + pTmp[0];
-			pTmp += sizeof(u16);
-
-			/* Parsing all unicast cipher suite */
-			while (Count > 0) {
-				/* Skip OUI */
-				pTmp += 3;
-				TmpCipher = Ndis802_11WEPDisabled;
-				switch (*pTmp) {
-				case 1:
-				case 5:	/* Although WEP is not allowed in WPA related auth mode, we parse it anyway */
-					TmpCipher =
-					    Ndis802_11Encryption1Enabled;
-					break;
-				case 2:
-					TmpCipher =
-					    Ndis802_11Encryption2Enabled;
-					break;
-				case 4:
-					TmpCipher =
-					    Ndis802_11Encryption3Enabled;
-					break;
-				default:
-					break;
-				}
-				if (TmpCipher > pBss->WPA.PairCipher) {
-					/* Move the lower cipher suite to PairCipherAux */
-					pBss->WPA.PairCipherAux =
-					    pBss->WPA.PairCipher;
-					pBss->WPA.PairCipher = TmpCipher;
-				} else {
-					pBss->WPA.PairCipherAux = TmpCipher;
-				}
-				pTmp++;
-				Count--;
-			}
-
-			/* 4. get AKM suite counts */
-			/*Count = *(u16 *)pTmp; */
-			Count = (pTmp[1] << 8) + pTmp[0];
-			pTmp += sizeof(u16);
-			pTmp += 3;
-
-			switch (*pTmp) {
-			case 1:
-				/* Set AP support WPA-enterprise mode */
-				if (pBss->AuthMode == Ndis802_11AuthModeOpen)
-					pBss->AuthMode = Ndis802_11AuthModeWPA;
-				else
-					pBss->AuthModeAux =
-					    Ndis802_11AuthModeWPA;
-				break;
-			case 2:
-				/* Set AP support WPA-PSK mode */
-				if (pBss->AuthMode == Ndis802_11AuthModeOpen)
-					pBss->AuthMode =
-					    Ndis802_11AuthModeWPAPSK;
-				else
-					pBss->AuthModeAux =
-					    Ndis802_11AuthModeWPAPSK;
-				break;
-			default:
-				break;
-			}
-			pTmp += 1;
-
-			/* Fixed for WPA-None */
-			if (pBss->BssType == BSS_ADHOC) {
-				pBss->AuthMode = Ndis802_11AuthModeWPANone;
-				pBss->AuthModeAux = Ndis802_11AuthModeWPANone;
-				pBss->WepStatus = pBss->WPA.GroupCipher;
-				/* Patched bugs for old driver */
-				if (pBss->WPA.PairCipherAux ==
-				    Ndis802_11WEPDisabled)
-					pBss->WPA.PairCipherAux =
-					    pBss->WPA.GroupCipher;
-			} else
-				pBss->WepStatus = pBss->WPA.PairCipher;
-
-			/* Check the Pair & Group, if different, turn on mixed mode flag */
-			if (pBss->WPA.GroupCipher != pBss->WPA.PairCipher)
-				pBss->WPA.bMixMode = TRUE;
-
-			break;
-
-		case IE_RSN:
-			pRsnHeader = (struct rt_rsn_ie_header *) pTmp;
-
-			/* 0. Version must be 1 */
-			if (le2cpu16(pRsnHeader->Version) != 1)
-				break;
-			pTmp += sizeof(struct rt_rsn_ie_header);
-
-			/* 1. Check group cipher */
-			pCipher = (struct rt_cipher_suite_struct *) pTmp;
-			if (!RTMPEqualMemory(pTmp, RSN_OUI, 3))
-				break;
-
-			/* Parse group cipher */
-			switch (pCipher->Type) {
-			case 1:
-				pBss->WPA2.GroupCipher =
-				    Ndis802_11GroupWEP40Enabled;
-				break;
-			case 5:
-				pBss->WPA2.GroupCipher =
-				    Ndis802_11GroupWEP104Enabled;
-				break;
-			case 2:
-				pBss->WPA2.GroupCipher =
-				    Ndis802_11Encryption2Enabled;
-				break;
-			case 4:
-				pBss->WPA2.GroupCipher =
-				    Ndis802_11Encryption3Enabled;
-				break;
-			default:
-				break;
-			}
-			/* set to correct offset for next parsing */
-			pTmp += sizeof(struct rt_cipher_suite_struct);
-
-			/* 2. Get pairwise cipher counts */
-			/*Count = *(u16 *)pTmp; */
-			Count = (pTmp[1] << 8) + pTmp[0];
-			pTmp += sizeof(u16);
-
-			/* 3. Get pairwise cipher */
-			/* Parsing all unicast cipher suite */
-			while (Count > 0) {
-				/* Skip OUI */
-				pCipher = (struct rt_cipher_suite_struct *) pTmp;
-				TmpCipher = Ndis802_11WEPDisabled;
-				switch (pCipher->Type) {
-				case 1:
-				case 5:	/* Although WEP is not allowed in WPA related auth mode, we parse it anyway */
-					TmpCipher =
-					    Ndis802_11Encryption1Enabled;
-					break;
-				case 2:
-					TmpCipher =
-					    Ndis802_11Encryption2Enabled;
-					break;
-				case 4:
-					TmpCipher =
-					    Ndis802_11Encryption3Enabled;
-					break;
-				default:
-					break;
-				}
-				if (TmpCipher > pBss->WPA2.PairCipher) {
-					/* Move the lower cipher suite to PairCipherAux */
-					pBss->WPA2.PairCipherAux =
-					    pBss->WPA2.PairCipher;
-					pBss->WPA2.PairCipher = TmpCipher;
-				} else {
-					pBss->WPA2.PairCipherAux = TmpCipher;
-				}
-				pTmp += sizeof(struct rt_cipher_suite_struct);
-				Count--;
-			}
-
-			/* 4. get AKM suite counts */
-			/*Count = *(u16 *)pTmp; */
-			Count = (pTmp[1] << 8) + pTmp[0];
-			pTmp += sizeof(u16);
-
-			/* 5. Get AKM ciphers */
-			/* Parsing all AKM ciphers */
-			while (Count > 0) {
-				pAKM = (struct rt_akm_suite *) pTmp;
-				if (!RTMPEqualMemory(pTmp, RSN_OUI, 3))
-					break;
-
-				switch (pAKM->Type) {
-				case 1:
-					/* Set AP support WPA-enterprise mode */
-					if (pBss->AuthMode ==
-					    Ndis802_11AuthModeOpen)
-						pBss->AuthMode =
-						    Ndis802_11AuthModeWPA2;
-					else
-						pBss->AuthModeAux =
-						    Ndis802_11AuthModeWPA2;
-					break;
-				case 2:
-					/* Set AP support WPA-PSK mode */
-					if (pBss->AuthMode ==
-					    Ndis802_11AuthModeOpen)
-						pBss->AuthMode =
-						    Ndis802_11AuthModeWPA2PSK;
-					else
-						pBss->AuthModeAux =
-						    Ndis802_11AuthModeWPA2PSK;
-					break;
-				default:
-					if (pBss->AuthMode ==
-					    Ndis802_11AuthModeOpen)
-						pBss->AuthMode =
-						    Ndis802_11AuthModeMax;
-					else
-						pBss->AuthModeAux =
-						    Ndis802_11AuthModeMax;
-					break;
-				}
-				pTmp += (Count * sizeof(struct rt_akm_suite));
-				Count--;
-			}
-
-			/* Fixed for WPA-None */
-			if (pBss->BssType == BSS_ADHOC) {
-				pBss->AuthMode = Ndis802_11AuthModeWPANone;
-				pBss->AuthModeAux = Ndis802_11AuthModeWPANone;
-				pBss->WPA.PairCipherAux =
-				    pBss->WPA2.PairCipherAux;
-				pBss->WPA.GroupCipher = pBss->WPA2.GroupCipher;
-				pBss->WepStatus = pBss->WPA.GroupCipher;
-				/* Patched bugs for old driver */
-				if (pBss->WPA.PairCipherAux ==
-				    Ndis802_11WEPDisabled)
-					pBss->WPA.PairCipherAux =
-					    pBss->WPA.GroupCipher;
-			}
-			pBss->WepStatus = pBss->WPA2.PairCipher;
-
-			/* 6. Get RSN capability */
-			/*pBss->WPA2.RsnCapability = *(u16 *)pTmp; */
-			pBss->WPA2.RsnCapability = (pTmp[1] << 8) + pTmp[0];
-			pTmp += sizeof(u16);
-
-			/* Check the Pair & Group, if different, turn on mixed mode flag */
-			if (pBss->WPA2.GroupCipher != pBss->WPA2.PairCipher)
-				pBss->WPA2.bMixMode = TRUE;
-
-			break;
-		default:
-			break;
-		}
-		Length -= (pEid->Len + 2);
-	}
-}
-
-/* =========================================================================================== */
-/* mac_table.c */
-/* =========================================================================================== */
-
-/*! \brief generates a random mac address value for IBSS BSSID
- *	\param Addr the bssid location
- *	\return none
- *	\pre
- *	\post
- */
-void MacAddrRandomBssid(struct rt_rtmp_adapter *pAd, u8 *pAddr)
-{
-	int i;
-
-	for (i = 0; i < MAC_ADDR_LEN; i++) {
-		pAddr[i] = RandomByte(pAd);
-	}
-
-	pAddr[0] = (pAddr[0] & 0xfe) | 0x02;	/* the first 2 bits must be 01xxxxxxxx */
-}
-
-/*! \brief init the management mac frame header
- *	\param p_hdr mac header
- *	\param subtype subtype of the frame
- *	\param p_ds destination address, don't care if it is a broadcast address
- *	\return none
- *	\pre the station has the following information in the pAd->StaCfg
- *	 - bssid
- *	 - station address
- *	\post
- *	\note this function initializes the following field
-
-	IRQL = PASSIVE_LEVEL
-	IRQL = DISPATCH_LEVEL
-
- */
-void MgtMacHeaderInit(struct rt_rtmp_adapter *pAd,
-		      struct rt_header_802_11 * pHdr80211,
-		      u8 SubType,
-		      u8 ToDs, u8 *pDA, u8 *pBssid)
-{
-	NdisZeroMemory(pHdr80211, sizeof(struct rt_header_802_11));
-
-	pHdr80211->FC.Type = BTYPE_MGMT;
-	pHdr80211->FC.SubType = SubType;
-/*      if (SubType == SUBTYPE_ACK)     // sample, no use, it will conflict with ACTION frame sub type */
-/*              pHdr80211->FC.Type = BTYPE_CNTL; */
-	pHdr80211->FC.ToDs = ToDs;
-	COPY_MAC_ADDR(pHdr80211->Addr1, pDA);
-	COPY_MAC_ADDR(pHdr80211->Addr2, pAd->CurrentAddress);
-	COPY_MAC_ADDR(pHdr80211->Addr3, pBssid);
-}
-
-/* =========================================================================================== */
-/* mem_mgmt.c */
-/* =========================================================================================== */
-
-/*!***************************************************************************
- * This routine build an outgoing frame, and fill all information specified
- * in argument list to the frame body. The actual frame size is the summation
- * of all arguments.
- * input params:
- *		Buffer - pointer to a pre-allocated memory segment
- *		args - a list of <int arg_size, arg> pairs.
- *		NOTE NOTE NOTE! the last argument must be NULL, otherwise this
- *						   function will FAIL!
- * return:
- *		Size of the buffer
- * usage:
- *		MakeOutgoingFrame(Buffer, output_length, 2, &fc, 2, &dur, 6, p_addr1, 6,p_addr2, END_OF_ARGS);
-
- IRQL = PASSIVE_LEVEL
-	IRQL = DISPATCH_LEVEL
-
- ****************************************************************************/
-unsigned long MakeOutgoingFrame(u8 * Buffer, unsigned long * FrameLen, ...)
-{
-	u8 *p;
-	int leng;
-	unsigned long TotLeng;
-	va_list Args;
-
-	/* calculates the total length */
-	TotLeng = 0;
-	va_start(Args, FrameLen);
-	do {
-		leng = va_arg(Args, int);
-		if (leng == END_OF_ARGS) {
-			break;
-		}
-		p = va_arg(Args, void *);
-		NdisMoveMemory(&Buffer[TotLeng], p, leng);
-		TotLeng = TotLeng + leng;
-	} while (TRUE);
-
-	va_end(Args);		/* clean up */
-	*FrameLen = TotLeng;
-	return TotLeng;
-}
-
-/* =========================================================================================== */
-/* mlme_queue.c */
-/* =========================================================================================== */
-
-/*! \brief	Initialize The MLME Queue, used by MLME Functions
- *	\param	*Queue	   The MLME Queue
- *	\return Always	   Return NDIS_STATE_SUCCESS in this implementation
- *	\pre
- *	\post
- *	\note	Because this is done only once (at the init stage), no need to be locked
-
- IRQL = PASSIVE_LEVEL
-
- */
-int MlmeQueueInit(struct rt_mlme_queue *Queue)
-{
-	int i;
-
-	NdisAllocateSpinLock(&Queue->Lock);
-
-	Queue->Num = 0;
-	Queue->Head = 0;
-	Queue->Tail = 0;
-
-	for (i = 0; i < MAX_LEN_OF_MLME_QUEUE; i++) {
-		Queue->Entry[i].Occupied = FALSE;
-		Queue->Entry[i].MsgLen = 0;
-		NdisZeroMemory(Queue->Entry[i].Msg, MGMT_DMA_BUFFER_SIZE);
-	}
-
-	return NDIS_STATUS_SUCCESS;
-}
-
-/*! \brief	 Enqueue a message for other threads, if they want to send messages to MLME thread
- *	\param	*Queue	  The MLME Queue
- *	\param	 Machine  The State Machine Id
- *	\param	 MsgType  The Message Type
- *	\param	 MsgLen   The Message length
- *	\param	*Msg	  The message pointer
- *	\return  TRUE if enqueue is successful, FALSE if the queue is full
- *	\pre
- *	\post
- *	\note	 The message has to be initialized
-
-	IRQL = PASSIVE_LEVEL
-	IRQL = DISPATCH_LEVEL
-
- */
-BOOLEAN MlmeEnqueue(struct rt_rtmp_adapter *pAd,
-		    unsigned long Machine,
-		    unsigned long MsgType, unsigned long MsgLen, void * Msg)
-{
-	int Tail;
-	struct rt_mlme_queue *Queue = (struct rt_mlme_queue *)& pAd->Mlme.Queue;
-
-	/* Do nothing if the driver is starting halt state. */
-	/* This might happen when timer already been fired before cancel timer with mlmehalt */
-	if (RTMP_TEST_FLAG
-	    (pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST))
-		return FALSE;
-
-	/* First check the size, it MUST not exceed the mlme queue size */
-	if (MsgLen > MGMT_DMA_BUFFER_SIZE) {
-		DBGPRINT_ERR("MlmeEnqueue: msg too large, size = %ld \n", MsgLen);
-		return FALSE;
-	}
-
-	if (MlmeQueueFull(Queue)) {
-		return FALSE;
-	}
-
-	NdisAcquireSpinLock(&(Queue->Lock));
-	Tail = Queue->Tail;
-	Queue->Tail++;
-	Queue->Num++;
-	if (Queue->Tail == MAX_LEN_OF_MLME_QUEUE) {
-		Queue->Tail = 0;
-	}
-
-	Queue->Entry[Tail].Wcid = RESERVED_WCID;
-	Queue->Entry[Tail].Occupied = TRUE;
-	Queue->Entry[Tail].Machine = Machine;
-	Queue->Entry[Tail].MsgType = MsgType;
-	Queue->Entry[Tail].MsgLen = MsgLen;
-
-	if (Msg != NULL) {
-		NdisMoveMemory(Queue->Entry[Tail].Msg, Msg, MsgLen);
-	}
-
-	NdisReleaseSpinLock(&(Queue->Lock));
-	return TRUE;
-}
-
-/*! \brief	 This function is used when Recv gets a MLME message
- *	\param	*Queue			 The MLME Queue
- *	\param	 TimeStampHigh	 The upper 32 bit of timestamp
- *	\param	 TimeStampLow	 The lower 32 bit of timestamp
- *	\param	 Rssi			 The receiving RSSI strength
- *	\param	 MsgLen			 The length of the message
- *	\param	*Msg			 The message pointer
- *	\return  TRUE if everything ok, FALSE otherwise (like Queue Full)
- *	\pre
- *	\post
-
- IRQL = DISPATCH_LEVEL
-
- */
-BOOLEAN MlmeEnqueueForRecv(struct rt_rtmp_adapter *pAd,
-			   unsigned long Wcid,
-			   unsigned long TimeStampHigh,
-			   unsigned long TimeStampLow,
-			   u8 Rssi0,
-			   u8 Rssi1,
-			   u8 Rssi2,
-			   unsigned long MsgLen, void * Msg, u8 Signal)
-{
-	int Tail, Machine;
-	struct rt_frame_802_11 * pFrame = (struct rt_frame_802_11 *) Msg;
-	int MsgType;
-	struct rt_mlme_queue *Queue = (struct rt_mlme_queue *)& pAd->Mlme.Queue;
-
-	/* Do nothing if the driver is starting halt state. */
-	/* This might happen when timer already been fired before cancel timer with mlmehalt */
-	if (RTMP_TEST_FLAG
-	    (pAd,
-	     fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST)) {
-		DBGPRINT_ERR("MlmeEnqueueForRecv: fRTMP_ADAPTER_HALT_IN_PROGRESS\n");
-		return FALSE;
-	}
-	/* First check the size, it MUST not exceed the mlme queue size */
-	if (MsgLen > MGMT_DMA_BUFFER_SIZE) {
-		DBGPRINT_ERR("MlmeEnqueueForRecv: frame too large, size = %ld \n", MsgLen);
-		return FALSE;
-	}
-
-	if (MlmeQueueFull(Queue)) {
-		return FALSE;
-	}
-
-	{
-		if (!MsgTypeSubst(pAd, pFrame, &Machine, &MsgType)) {
-			DBGPRINT_ERR("MlmeEnqueueForRecv: un-recongnized mgmt->subtype=%d\n", pFrame->Hdr.FC.SubType);
-			return FALSE;
-		}
-	}
-
-	/* OK, we got all the informations, it is time to put things into queue */
-	NdisAcquireSpinLock(&(Queue->Lock));
-	Tail = Queue->Tail;
-	Queue->Tail++;
-	Queue->Num++;
-	if (Queue->Tail == MAX_LEN_OF_MLME_QUEUE) {
-		Queue->Tail = 0;
-	}
-	Queue->Entry[Tail].Occupied = TRUE;
-	Queue->Entry[Tail].Machine = Machine;
-	Queue->Entry[Tail].MsgType = MsgType;
-	Queue->Entry[Tail].MsgLen = MsgLen;
-	Queue->Entry[Tail].TimeStamp.u.LowPart = TimeStampLow;
-	Queue->Entry[Tail].TimeStamp.u.HighPart = TimeStampHigh;
-	Queue->Entry[Tail].Rssi0 = Rssi0;
-	Queue->Entry[Tail].Rssi1 = Rssi1;
-	Queue->Entry[Tail].Rssi2 = Rssi2;
-	Queue->Entry[Tail].Signal = Signal;
-	Queue->Entry[Tail].Wcid = (u8)Wcid;
-
-	Queue->Entry[Tail].Channel = pAd->LatchRfRegs.Channel;
-
-	if (Msg != NULL) {
-		NdisMoveMemory(Queue->Entry[Tail].Msg, Msg, MsgLen);
-	}
-
-	NdisReleaseSpinLock(&(Queue->Lock));
-
-	RTMP_MLME_HANDLER(pAd);
-
-	return TRUE;
-}
-
-/*! \brief	 Dequeue a message from the MLME Queue
- *	\param	*Queue	  The MLME Queue
- *	\param	*Elem	  The message dequeued from MLME Queue
- *	\return  TRUE if the Elem contains something, FALSE otherwise
- *	\pre
- *	\post
-
- IRQL = DISPATCH_LEVEL
-
- */
-BOOLEAN MlmeDequeue(struct rt_mlme_queue *Queue, struct rt_mlme_queue_elem ** Elem)
-{
-	NdisAcquireSpinLock(&(Queue->Lock));
-	*Elem = &(Queue->Entry[Queue->Head]);
-	Queue->Num--;
-	Queue->Head++;
-	if (Queue->Head == MAX_LEN_OF_MLME_QUEUE) {
-		Queue->Head = 0;
-	}
-	NdisReleaseSpinLock(&(Queue->Lock));
-	return TRUE;
-}
-
-/* IRQL = DISPATCH_LEVEL */
-void MlmeRestartStateMachine(struct rt_rtmp_adapter *pAd)
-{
-#ifdef RTMP_MAC_PCI
-	struct rt_mlme_queue_elem *Elem = NULL;
-#endif /* RTMP_MAC_PCI // */
-	BOOLEAN Cancelled;
-
-	DBGPRINT(RT_DEBUG_TRACE, ("MlmeRestartStateMachine \n"));
-
-#ifdef RTMP_MAC_PCI
-	NdisAcquireSpinLock(&pAd->Mlme.TaskLock);
-	if (pAd->Mlme.bRunning) {
-		NdisReleaseSpinLock(&pAd->Mlme.TaskLock);
-		return;
-	} else {
-		pAd->Mlme.bRunning = TRUE;
-	}
-	NdisReleaseSpinLock(&pAd->Mlme.TaskLock);
-
-	/* Remove all Mlme queues elements */
-	while (!MlmeQueueEmpty(&pAd->Mlme.Queue)) {
-		/*From message type, determine which state machine I should drive */
-		if (MlmeDequeue(&pAd->Mlme.Queue, &Elem)) {
-			/* free MLME element */
-			Elem->Occupied = FALSE;
-			Elem->MsgLen = 0;
-
-		} else {
-			DBGPRINT_ERR("MlmeRestartStateMachine: MlmeQueue empty\n");
-		}
-	}
-#endif /* RTMP_MAC_PCI // */
-
-	{
-		/* Cancel all timer events */
-		/* Be careful to cancel new added timer */
-		RTMPCancelTimer(&pAd->MlmeAux.AssocTimer, &Cancelled);
-		RTMPCancelTimer(&pAd->MlmeAux.ReassocTimer, &Cancelled);
-		RTMPCancelTimer(&pAd->MlmeAux.DisassocTimer, &Cancelled);
-		RTMPCancelTimer(&pAd->MlmeAux.AuthTimer, &Cancelled);
-		RTMPCancelTimer(&pAd->MlmeAux.BeaconTimer, &Cancelled);
-		RTMPCancelTimer(&pAd->MlmeAux.ScanTimer, &Cancelled);
-
-	}
-
-	/* Change back to original channel in case of doing scan */
-	AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
-	AsicLockChannel(pAd, pAd->CommonCfg.Channel);
-
-	/* Resume MSDU which is turned off durning scan */
-	RTMPResumeMsduTransmission(pAd);
-
-	{
-		/* Set all state machines back IDLE */
-		pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
-		pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
-		pAd->Mlme.AuthMachine.CurrState = AUTH_REQ_IDLE;
-		pAd->Mlme.AuthRspMachine.CurrState = AUTH_RSP_IDLE;
-		pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
-		pAd->Mlme.ActMachine.CurrState = ACT_IDLE;
-	}
-
-#ifdef RTMP_MAC_PCI
-	/* Remove running state */
-	NdisAcquireSpinLock(&pAd->Mlme.TaskLock);
-	pAd->Mlme.bRunning = FALSE;
-	NdisReleaseSpinLock(&pAd->Mlme.TaskLock);
-#endif /* RTMP_MAC_PCI // */
-}
-
-/*! \brief	test if the MLME Queue is empty
- *	\param	*Queue	  The MLME Queue
- *	\return TRUE if the Queue is empty, FALSE otherwise
- *	\pre
- *	\post
-
- IRQL = DISPATCH_LEVEL
-
- */
-BOOLEAN MlmeQueueEmpty(struct rt_mlme_queue *Queue)
-{
-	BOOLEAN Ans;
-
-	NdisAcquireSpinLock(&(Queue->Lock));
-	Ans = (Queue->Num == 0);
-	NdisReleaseSpinLock(&(Queue->Lock));
-
-	return Ans;
-}
-
-/*! \brief	 test if the MLME Queue is full
- *	\param	 *Queue		 The MLME Queue
- *	\return  TRUE if the Queue is empty, FALSE otherwise
- *	\pre
- *	\post
-
- IRQL = PASSIVE_LEVEL
- IRQL = DISPATCH_LEVEL
-
- */
-BOOLEAN MlmeQueueFull(struct rt_mlme_queue *Queue)
-{
-	BOOLEAN Ans;
-
-	NdisAcquireSpinLock(&(Queue->Lock));
-	Ans = (Queue->Num == MAX_LEN_OF_MLME_QUEUE
-	       || Queue->Entry[Queue->Tail].Occupied);
-	NdisReleaseSpinLock(&(Queue->Lock));
-
-	return Ans;
-}
-
-/*! \brief	 The destructor of MLME Queue
- *	\param
- *	\return
- *	\pre
- *	\post
- *	\note	Clear Mlme Queue, Set Queue->Num to Zero.
-
- IRQL = PASSIVE_LEVEL
-
- */
-void MlmeQueueDestroy(struct rt_mlme_queue *pQueue)
-{
-	NdisAcquireSpinLock(&(pQueue->Lock));
-	pQueue->Num = 0;
-	pQueue->Head = 0;
-	pQueue->Tail = 0;
-	NdisReleaseSpinLock(&(pQueue->Lock));
-	NdisFreeSpinLock(&(pQueue->Lock));
-}
-
-/*! \brief	 To substitute the message type if the message is coming from external
- *	\param	pFrame		   The frame received
- *	\param	*Machine	   The state machine
- *	\param	*MsgType	   the message type for the state machine
- *	\return TRUE if the substitution is successful, FALSE otherwise
- *	\pre
- *	\post
-
- IRQL = DISPATCH_LEVEL
-
- */
-BOOLEAN MsgTypeSubst(struct rt_rtmp_adapter *pAd,
-		     struct rt_frame_802_11 * pFrame,
-		     int * Machine, int * MsgType)
-{
-	u16 Seq, Alg;
-	u8 EAPType;
-	u8 *pData;
-
-	/* Pointer to start of data frames including SNAP header */
-	pData = (u8 *)pFrame + LENGTH_802_11;
-
-	/* The only data type will pass to this function is EAPOL frame */
-	if (pFrame->Hdr.FC.Type == BTYPE_DATA) {
-		{
-			*Machine = WPA_STATE_MACHINE;
-			EAPType =
-			    *((u8 *) pFrame + LENGTH_802_11 +
-			      LENGTH_802_1_H + 1);
-			return (WpaMsgTypeSubst(EAPType, (int *) MsgType));
-		}
-	}
-
-	switch (pFrame->Hdr.FC.SubType) {
-	case SUBTYPE_ASSOC_REQ:
-		*Machine = ASSOC_STATE_MACHINE;
-		*MsgType = MT2_PEER_ASSOC_REQ;
-		break;
-	case SUBTYPE_ASSOC_RSP:
-		*Machine = ASSOC_STATE_MACHINE;
-		*MsgType = MT2_PEER_ASSOC_RSP;
-		break;
-	case SUBTYPE_REASSOC_REQ:
-		*Machine = ASSOC_STATE_MACHINE;
-		*MsgType = MT2_PEER_REASSOC_REQ;
-		break;
-	case SUBTYPE_REASSOC_RSP:
-		*Machine = ASSOC_STATE_MACHINE;
-		*MsgType = MT2_PEER_REASSOC_RSP;
-		break;
-	case SUBTYPE_PROBE_REQ:
-		*Machine = SYNC_STATE_MACHINE;
-		*MsgType = MT2_PEER_PROBE_REQ;
-		break;
-	case SUBTYPE_PROBE_RSP:
-		*Machine = SYNC_STATE_MACHINE;
-		*MsgType = MT2_PEER_PROBE_RSP;
-		break;
-	case SUBTYPE_BEACON:
-		*Machine = SYNC_STATE_MACHINE;
-		*MsgType = MT2_PEER_BEACON;
-		break;
-	case SUBTYPE_ATIM:
-		*Machine = SYNC_STATE_MACHINE;
-		*MsgType = MT2_PEER_ATIM;
-		break;
-	case SUBTYPE_DISASSOC:
-		*Machine = ASSOC_STATE_MACHINE;
-		*MsgType = MT2_PEER_DISASSOC_REQ;
-		break;
-	case SUBTYPE_AUTH:
-		/* get the sequence number from payload 24 Mac Header + 2 bytes algorithm */
-		NdisMoveMemory(&Seq, &pFrame->Octet[2], sizeof(u16));
-		NdisMoveMemory(&Alg, &pFrame->Octet[0], sizeof(u16));
-		if (Seq == 1 || Seq == 3) {
-			*Machine = AUTH_RSP_STATE_MACHINE;
-			*MsgType = MT2_PEER_AUTH_ODD;
-		} else if (Seq == 2 || Seq == 4) {
-			if (Alg == AUTH_MODE_OPEN || Alg == AUTH_MODE_KEY) {
-				*Machine = AUTH_STATE_MACHINE;
-				*MsgType = MT2_PEER_AUTH_EVEN;
-			}
-		} else {
-			return FALSE;
-		}
-		break;
-	case SUBTYPE_DEAUTH:
-		*Machine = AUTH_RSP_STATE_MACHINE;
-		*MsgType = MT2_PEER_DEAUTH;
-		break;
-	case SUBTYPE_ACTION:
-		*Machine = ACTION_STATE_MACHINE;
-		/*  Sometimes Sta will return with category bytes with MSB = 1, if they receive catogory out of their support */
-		if ((pFrame->Octet[0] & 0x7F) > MAX_PEER_CATE_MSG) {
-			*MsgType = MT2_ACT_INVALID;
-		} else {
-			*MsgType = (pFrame->Octet[0] & 0x7F);
-		}
-		break;
-	default:
-		return FALSE;
-		break;
-	}
-
-	return TRUE;
-}
-
-/* =========================================================================================== */
-/* state_machine.c */
-/* =========================================================================================== */
-
-/*! \brief Initialize the state machine.
- *	\param *S			pointer to the state machine
- *	\param	Trans		State machine transition function
- *	\param	StNr		number of states
- *	\param	MsgNr		number of messages
- *	\param	DefFunc		default function, when there is invalid state/message combination
- *	\param	InitState	initial state of the state machine
- *	\param	Base		StateMachine base, internal use only
- *	\pre p_sm should be a legal pointer
- *	\post
-
- IRQL = PASSIVE_LEVEL
-
- */
-void StateMachineInit(struct rt_state_machine *S,
-		      IN STATE_MACHINE_FUNC Trans[],
-		      unsigned long StNr,
-		      unsigned long MsgNr,
-		      IN STATE_MACHINE_FUNC DefFunc,
-		      unsigned long InitState, unsigned long Base)
-{
-	unsigned long i, j;
-
-	/* set number of states and messages */
-	S->NrState = StNr;
-	S->NrMsg = MsgNr;
-	S->Base = Base;
-
-	S->TransFunc = Trans;
-
-	/* init all state transition to default function */
-	for (i = 0; i < StNr; i++) {
-		for (j = 0; j < MsgNr; j++) {
-			S->TransFunc[i * MsgNr + j] = DefFunc;
-		}
-	}
-
-	/* set the starting state */
-	S->CurrState = InitState;
-}
-
-/*! \brief This function fills in the function pointer into the cell in the state machine
- *	\param *S	pointer to the state machine
- *	\param St	state
- *	\param Msg	incoming message
- *	\param f	the function to be executed when (state, message) combination occurs at the state machine
- *	\pre *S should be a legal pointer to the state machine, st, msg, should be all within the range, Base should be set in the initial state
- *	\post
-
- IRQL = PASSIVE_LEVEL
-
- */
-void StateMachineSetAction(struct rt_state_machine *S,
-			   unsigned long St,
-			   unsigned long Msg, IN STATE_MACHINE_FUNC Func)
-{
-	unsigned long MsgIdx;
-
-	MsgIdx = Msg - S->Base;
-
-	if (St < S->NrState && MsgIdx < S->NrMsg) {
-		/* boundary checking before setting the action */
-		S->TransFunc[St * S->NrMsg + MsgIdx] = Func;
-	}
-}
-
-/*! \brief	 This function does the state transition
- *	\param	 *Adapter the NIC adapter pointer
- *	\param	 *S	  the state machine
- *	\param	 *Elem	  the message to be executed
- *	\return   None
-
- IRQL = DISPATCH_LEVEL
-
- */
-void StateMachinePerformAction(struct rt_rtmp_adapter *pAd,
-			       struct rt_state_machine *S, struct rt_mlme_queue_elem *Elem)
-{
-	(*(S->TransFunc[S->CurrState * S->NrMsg + Elem->MsgType - S->Base]))
-	    (pAd, Elem);
-}
-
-/*
-	==========================================================================
-	Description:
-		The drop function, when machine executes this, the message is simply
-		ignored. This function does nothing, the message is freed in
-		StateMachinePerformAction()
-	==========================================================================
- */
-void Drop(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
-{
-}
-
-/* =========================================================================================== */
-/* lfsr.c */
-/* =========================================================================================== */
-
-/*
-	==========================================================================
-	Description:
-
-	IRQL = PASSIVE_LEVEL
-
-	==========================================================================
- */
-void LfsrInit(struct rt_rtmp_adapter *pAd, unsigned long Seed)
-{
-	if (Seed == 0)
-		pAd->Mlme.ShiftReg = 1;
-	else
-		pAd->Mlme.ShiftReg = Seed;
-}
-
-/*
-	==========================================================================
-	Description:
-	==========================================================================
- */
-u8 RandomByte(struct rt_rtmp_adapter *pAd)
-{
-	unsigned long i;
-	u8 R, Result;
-
-	R = 0;
-
-	if (pAd->Mlme.ShiftReg == 0)
-		NdisGetSystemUpTime((unsigned long *) & pAd->Mlme.ShiftReg);
-
-	for (i = 0; i < 8; i++) {
-		if (pAd->Mlme.ShiftReg & 0x00000001) {
-			pAd->Mlme.ShiftReg =
-			    ((pAd->Mlme.
-			      ShiftReg ^ LFSR_MASK) >> 1) | 0x80000000;
-			Result = 1;
-		} else {
-			pAd->Mlme.ShiftReg = pAd->Mlme.ShiftReg >> 1;
-			Result = 0;
-		}
-		R = (R << 1) | Result;
-	}
-
-	return R;
-}
-
-/*
-	========================================================================
-
-	Routine Description:
-		Verify the support rate for different PHY type
-
-	Arguments:
-		pAd 				Pointer to our adapter
-
-	Return Value:
-		None
-
-	IRQL = PASSIVE_LEVEL
-
-	========================================================================
-*/
-void RTMPCheckRates(struct rt_rtmp_adapter *pAd,
-		    IN u8 SupRate[], IN u8 * SupRateLen)
-{
-	u8 RateIdx, i, j;
-	u8 NewRate[12], NewRateLen;
-
-	NewRateLen = 0;
-
-	if (pAd->CommonCfg.PhyMode == PHY_11B)
-		RateIdx = 4;
-	else
-		RateIdx = 12;
-
-	/* Check for support rates exclude basic rate bit */
-	for (i = 0; i < *SupRateLen; i++)
-		for (j = 0; j < RateIdx; j++)
-			if ((SupRate[i] & 0x7f) == RateIdTo500Kbps[j])
-				NewRate[NewRateLen++] = SupRate[i];
-
-	*SupRateLen = NewRateLen;
-	NdisMoveMemory(SupRate, NewRate, NewRateLen);
-}
-
-BOOLEAN RTMPCheckChannel(struct rt_rtmp_adapter *pAd,
-			 u8 CentralChannel, u8 Channel)
-{
-	u8 k;
-	u8 UpperChannel = 0, LowerChannel = 0;
-	u8 NoEffectChannelinList = 0;
-
-	/* Find upper and lower channel according to 40MHz current operation. */
-	if (CentralChannel < Channel) {
-		UpperChannel = Channel;
-		if (CentralChannel > 2)
-			LowerChannel = CentralChannel - 2;
-		else
-			return FALSE;
-	} else if (CentralChannel > Channel) {
-		UpperChannel = CentralChannel + 2;
-		LowerChannel = Channel;
-	}
-
-	for (k = 0; k < pAd->ChannelListNum; k++) {
-		if (pAd->ChannelList[k].Channel == UpperChannel) {
-			NoEffectChannelinList++;
-		}
-		if (pAd->ChannelList[k].Channel == LowerChannel) {
-			NoEffectChannelinList++;
-		}
-	}
-
-	DBGPRINT(RT_DEBUG_TRACE,
-		 ("Total Channel in Channel List = [%d]\n",
-		  NoEffectChannelinList));
-	if (NoEffectChannelinList == 2)
-		return TRUE;
-	else
-		return FALSE;
-}
-
-/*
-	========================================================================
-
-	Routine Description:
-		Verify the support rate for HT phy type
-
-	Arguments:
-		pAd 				Pointer to our adapter
-
-	Return Value:
-		FALSE if pAd->CommonCfg.SupportedHtPhy doesn't accept the pHtCapability.  (AP Mode)
-
-	IRQL = PASSIVE_LEVEL
-
-	========================================================================
-*/
-BOOLEAN RTMPCheckHt(struct rt_rtmp_adapter *pAd,
-		    u8 Wcid,
-		    struct rt_ht_capability_ie * pHtCapability,
-		    struct rt_add_ht_info_ie * pAddHtInfo)
-{
-	if (Wcid >= MAX_LEN_OF_MAC_TABLE)
-		return FALSE;
-
-	/* If use AMSDU, set flag. */
-	if (pAd->CommonCfg.DesiredHtPhy.AmsduEnable)
-		CLIENT_STATUS_SET_FLAG(&pAd->MacTab.Content[Wcid],
-				       fCLIENT_STATUS_AMSDU_INUSED);
-	/* Save Peer Capability */
-	if (pHtCapability->HtCapInfo.ShortGIfor20)
-		CLIENT_STATUS_SET_FLAG(&pAd->MacTab.Content[Wcid],
-				       fCLIENT_STATUS_SGI20_CAPABLE);
-	if (pHtCapability->HtCapInfo.ShortGIfor40)
-		CLIENT_STATUS_SET_FLAG(&pAd->MacTab.Content[Wcid],
-				       fCLIENT_STATUS_SGI40_CAPABLE);
-	if (pHtCapability->HtCapInfo.TxSTBC)
-		CLIENT_STATUS_SET_FLAG(&pAd->MacTab.Content[Wcid],
-				       fCLIENT_STATUS_TxSTBC_CAPABLE);
-	if (pHtCapability->HtCapInfo.RxSTBC)
-		CLIENT_STATUS_SET_FLAG(&pAd->MacTab.Content[Wcid],
-				       fCLIENT_STATUS_RxSTBC_CAPABLE);
-	if (pAd->CommonCfg.bRdg && pHtCapability->ExtHtCapInfo.RDGSupport) {
-		CLIENT_STATUS_SET_FLAG(&pAd->MacTab.Content[Wcid],
-				       fCLIENT_STATUS_RDG_CAPABLE);
-	}
-
-	if (Wcid < MAX_LEN_OF_MAC_TABLE) {
-		pAd->MacTab.Content[Wcid].MpduDensity =
-		    pHtCapability->HtCapParm.MpduDensity;
-	}
-	/* Will check ChannelWidth for MCSSet[4] below */
-	pAd->MlmeAux.HtCapability.MCSSet[4] = 0x1;
-	switch (pAd->CommonCfg.RxStream) {
-	case 1:
-		pAd->MlmeAux.HtCapability.MCSSet[0] = 0xff;
-		pAd->MlmeAux.HtCapability.MCSSet[1] = 0x00;
-		pAd->MlmeAux.HtCapability.MCSSet[2] = 0x00;
-		pAd->MlmeAux.HtCapability.MCSSet[3] = 0x00;
-		break;
-	case 2:
-		pAd->MlmeAux.HtCapability.MCSSet[0] = 0xff;
-		pAd->MlmeAux.HtCapability.MCSSet[1] = 0xff;
-		pAd->MlmeAux.HtCapability.MCSSet[2] = 0x00;
-		pAd->MlmeAux.HtCapability.MCSSet[3] = 0x00;
-		break;
-	case 3:
-		pAd->MlmeAux.HtCapability.MCSSet[0] = 0xff;
-		pAd->MlmeAux.HtCapability.MCSSet[1] = 0xff;
-		pAd->MlmeAux.HtCapability.MCSSet[2] = 0xff;
-		pAd->MlmeAux.HtCapability.MCSSet[3] = 0x00;
-		break;
-	}
-
-	pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth =
-	    pAddHtInfo->AddHtInfo.RecomWidth & pAd->CommonCfg.DesiredHtPhy.
-	    ChannelWidth;
-
-	DBGPRINT(RT_DEBUG_TRACE,
-		 ("RTMPCheckHt:: HtCapInfo.ChannelWidth=%d, RecomWidth=%d, DesiredHtPhy.ChannelWidth=%d, BW40MAvailForA/G=%d/%d, PhyMode=%d \n",
-		  pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth,
-		  pAddHtInfo->AddHtInfo.RecomWidth,
-		  pAd->CommonCfg.DesiredHtPhy.ChannelWidth,
-		  pAd->NicConfig2.field.BW40MAvailForA,
-		  pAd->NicConfig2.field.BW40MAvailForG,
-		  pAd->CommonCfg.PhyMode));
-
-	pAd->MlmeAux.HtCapability.HtCapInfo.GF =
-	    pHtCapability->HtCapInfo.GF & pAd->CommonCfg.DesiredHtPhy.GF;
-
-	/* Send Assoc Req with my HT capability. */
-	pAd->MlmeAux.HtCapability.HtCapInfo.AMsduSize =
-	    pAd->CommonCfg.DesiredHtPhy.AmsduSize;
-	pAd->MlmeAux.HtCapability.HtCapInfo.MimoPs =
-	    pAd->CommonCfg.DesiredHtPhy.MimoPs;
-	pAd->MlmeAux.HtCapability.HtCapInfo.ShortGIfor20 =
-	    (pAd->CommonCfg.DesiredHtPhy.ShortGIfor20) & (pHtCapability->
-							  HtCapInfo.
-							  ShortGIfor20);
-	pAd->MlmeAux.HtCapability.HtCapInfo.ShortGIfor40 =
-	    (pAd->CommonCfg.DesiredHtPhy.ShortGIfor40) & (pHtCapability->
-							  HtCapInfo.
-							  ShortGIfor40);
-	pAd->MlmeAux.HtCapability.HtCapInfo.TxSTBC =
-	    (pAd->CommonCfg.DesiredHtPhy.TxSTBC) & (pHtCapability->HtCapInfo.
-						    RxSTBC);
-	pAd->MlmeAux.HtCapability.HtCapInfo.RxSTBC =
-	    (pAd->CommonCfg.DesiredHtPhy.RxSTBC) & (pHtCapability->HtCapInfo.
-						    TxSTBC);
-	pAd->MlmeAux.HtCapability.HtCapParm.MaxRAmpduFactor =
-	    pAd->CommonCfg.DesiredHtPhy.MaxRAmpduFactor;
-	pAd->MlmeAux.HtCapability.HtCapParm.MpduDensity =
-	    pAd->CommonCfg.HtCapability.HtCapParm.MpduDensity;
-	pAd->MlmeAux.HtCapability.ExtHtCapInfo.PlusHTC =
-	    pHtCapability->ExtHtCapInfo.PlusHTC;
-	pAd->MacTab.Content[Wcid].HTCapability.ExtHtCapInfo.PlusHTC =
-	    pHtCapability->ExtHtCapInfo.PlusHTC;
-	if (pAd->CommonCfg.bRdg) {
-		pAd->MlmeAux.HtCapability.ExtHtCapInfo.RDGSupport =
-		    pHtCapability->ExtHtCapInfo.RDGSupport;
-		pAd->MlmeAux.HtCapability.ExtHtCapInfo.PlusHTC = 1;
-	}
-
-	if (pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth == BW_20)
-		pAd->MlmeAux.HtCapability.MCSSet[4] = 0x0;	/* BW20 can't transmit MCS32 */
-
-	COPY_AP_HTSETTINGS_FROM_BEACON(pAd, pHtCapability);
-	return TRUE;
-}
-
-/*
-	========================================================================
-
-	Routine Description:
-		Verify the support rate for different PHY type
-
-	Arguments:
-		pAd 				Pointer to our adapter
-
-	Return Value:
-		None
-
-	IRQL = PASSIVE_LEVEL
-
-	========================================================================
-*/
-void RTMPUpdateMlmeRate(struct rt_rtmp_adapter *pAd)
-{
-	u8 MinimumRate;
-	u8 ProperMlmeRate;	/*= RATE_54; */
-	u8 i, j, RateIdx = 12;	/*1, 2, 5.5, 11, 6, 9, 12, 18, 24, 36, 48, 54 */
-	BOOLEAN bMatch = FALSE;
-
-	switch (pAd->CommonCfg.PhyMode) {
-	case PHY_11B:
-		ProperMlmeRate = RATE_11;
-		MinimumRate = RATE_1;
-		break;
-	case PHY_11BG_MIXED:
-	case PHY_11ABGN_MIXED:
-	case PHY_11BGN_MIXED:
-		if ((pAd->MlmeAux.SupRateLen == 4) &&
-		    (pAd->MlmeAux.ExtRateLen == 0))
-			/* B only AP */
-			ProperMlmeRate = RATE_11;
-		else
-			ProperMlmeRate = RATE_24;
-
-		if (pAd->MlmeAux.Channel <= 14)
-			MinimumRate = RATE_1;
-		else
-			MinimumRate = RATE_6;
-		break;
-	case PHY_11A:
-	case PHY_11N_2_4G:	/* rt2860 need to check mlmerate for 802.11n */
-	case PHY_11GN_MIXED:
-	case PHY_11AGN_MIXED:
-	case PHY_11AN_MIXED:
-	case PHY_11N_5G:
-		ProperMlmeRate = RATE_24;
-		MinimumRate = RATE_6;
-		break;
-	case PHY_11ABG_MIXED:
-		ProperMlmeRate = RATE_24;
-		if (pAd->MlmeAux.Channel <= 14)
-			MinimumRate = RATE_1;
-		else
-			MinimumRate = RATE_6;
-		break;
-	default:		/* error */
-		ProperMlmeRate = RATE_1;
-		MinimumRate = RATE_1;
-		break;
-	}
-
-	for (i = 0; i < pAd->MlmeAux.SupRateLen; i++) {
-		for (j = 0; j < RateIdx; j++) {
-			if ((pAd->MlmeAux.SupRate[i] & 0x7f) ==
-			    RateIdTo500Kbps[j]) {
-				if (j == ProperMlmeRate) {
-					bMatch = TRUE;
-					break;
-				}
-			}
-		}
-
-		if (bMatch)
-			break;
-	}
-
-	if (bMatch == FALSE) {
-		for (i = 0; i < pAd->MlmeAux.ExtRateLen; i++) {
-			for (j = 0; j < RateIdx; j++) {
-				if ((pAd->MlmeAux.ExtRate[i] & 0x7f) ==
-				    RateIdTo500Kbps[j]) {
-					if (j == ProperMlmeRate) {
-						bMatch = TRUE;
-						break;
-					}
-				}
-			}
-
-			if (bMatch)
-				break;
-		}
-	}
-
-	if (bMatch == FALSE) {
-		ProperMlmeRate = MinimumRate;
-	}
-
-	pAd->CommonCfg.MlmeRate = MinimumRate;
-	pAd->CommonCfg.RtsRate = ProperMlmeRate;
-	if (pAd->CommonCfg.MlmeRate >= RATE_6) {
-		pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_OFDM;
-		pAd->CommonCfg.MlmeTransmit.field.MCS =
-		    OfdmRateToRxwiMCS[pAd->CommonCfg.MlmeRate];
-		pAd->MacTab.Content[BSS0Mcast_WCID].HTPhyMode.field.MODE =
-		    MODE_OFDM;
-		pAd->MacTab.Content[BSS0Mcast_WCID].HTPhyMode.field.MCS =
-		    OfdmRateToRxwiMCS[pAd->CommonCfg.MlmeRate];
-	} else {
-		pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_CCK;
-		pAd->CommonCfg.MlmeTransmit.field.MCS = pAd->CommonCfg.MlmeRate;
-		pAd->MacTab.Content[BSS0Mcast_WCID].HTPhyMode.field.MODE =
-		    MODE_CCK;
-		pAd->MacTab.Content[BSS0Mcast_WCID].HTPhyMode.field.MCS =
-		    pAd->CommonCfg.MlmeRate;
-	}
-
-	DBGPRINT(RT_DEBUG_TRACE,
-		 ("RTMPUpdateMlmeRate ==>   MlmeTransmit = 0x%x  \n",
-		  pAd->CommonCfg.MlmeTransmit.word));
-}
-
-char RTMPMaxRssi(struct rt_rtmp_adapter *pAd,
-		 char Rssi0, char Rssi1, char Rssi2)
-{
-	char larger = -127;
-
-	if ((pAd->Antenna.field.RxPath == 1) && (Rssi0 != 0)) {
-		larger = Rssi0;
-	}
-
-	if ((pAd->Antenna.field.RxPath >= 2) && (Rssi1 != 0)) {
-		larger = max(Rssi0, Rssi1);
-	}
-
-	if ((pAd->Antenna.field.RxPath == 3) && (Rssi2 != 0)) {
-		larger = max(larger, Rssi2);
-	}
-
-	if (larger == -127)
-		larger = 0;
-
-	return larger;
-}
-
-/*
-    ========================================================================
-    Routine Description:
-        Periodic evaluate antenna link status
-
-    Arguments:
-        pAd         - Adapter pointer
-
-    Return Value:
-        None
-
-    ========================================================================
-*/
-void AsicEvaluateRxAnt(struct rt_rtmp_adapter *pAd)
-{
-	u8 BBPR3 = 0;
-
-	if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS |
-			   fRTMP_ADAPTER_HALT_IN_PROGRESS |
-			   fRTMP_ADAPTER_RADIO_OFF |
-			   fRTMP_ADAPTER_NIC_NOT_EXIST |
-			   fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS) ||
-	    OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE)
-#ifdef RT30xx
-	    || (pAd->EepromAccess)
-#endif /* RT30xx // */
-#ifdef RT3090
-	    || (pAd->bPCIclkOff == TRUE)
-#endif /* RT3090 // */
-	    )
-		return;
-
-	{
-		/*if (pAd->StaCfg.Psm == PWR_SAVE) */
-		/*      return; */
-
-		{
-
-			if (pAd->StaCfg.Psm == PWR_SAVE)
-				return;
-
-			RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &BBPR3);
-			BBPR3 &= (~0x18);
-			if (pAd->Antenna.field.RxPath == 3) {
-				BBPR3 |= (0x10);
-			} else if (pAd->Antenna.field.RxPath == 2) {
-				BBPR3 |= (0x8);
-			} else if (pAd->Antenna.field.RxPath == 1) {
-				BBPR3 |= (0x0);
-			}
-			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, BBPR3);
-#ifdef RTMP_MAC_PCI
-			pAd->StaCfg.BBPR3 = BBPR3;
-#endif /* RTMP_MAC_PCI // */
-			if (OPSTATUS_TEST_FLAG
-			    (pAd, fOP_STATUS_MEDIA_STATE_CONNECTED)
-			    ) {
-				unsigned long TxTotalCnt =
-				    pAd->RalinkCounters.OneSecTxNoRetryOkCount +
-				    pAd->RalinkCounters.OneSecTxRetryOkCount +
-				    pAd->RalinkCounters.OneSecTxFailCount;
-
-				/* dynamic adjust antenna evaluation period according to the traffic */
-				if (TxTotalCnt > 50) {
-					RTMPSetTimer(&pAd->Mlme.RxAntEvalTimer,
-						     20);
-					pAd->Mlme.bLowThroughput = FALSE;
-				} else {
-					RTMPSetTimer(&pAd->Mlme.RxAntEvalTimer,
-						     300);
-					pAd->Mlme.bLowThroughput = TRUE;
-				}
-			}
-		}
-
-	}
-
-}
-
-/*
-    ========================================================================
-    Routine Description:
-        After evaluation, check antenna link status
-
-    Arguments:
-        pAd         - Adapter pointer
-
-    Return Value:
-        None
-
-    ========================================================================
-*/
-void AsicRxAntEvalTimeout(void *SystemSpecific1,
-			  void *FunctionContext,
-			  void *SystemSpecific2, void *SystemSpecific3)
-{
-	struct rt_rtmp_adapter *pAd = (struct rt_rtmp_adapter *)FunctionContext;
-	u8 BBPR3 = 0;
-	char larger = -127, rssi0, rssi1, rssi2;
-
-	if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS |
-			   fRTMP_ADAPTER_HALT_IN_PROGRESS |
-			   fRTMP_ADAPTER_RADIO_OFF |
-			   fRTMP_ADAPTER_NIC_NOT_EXIST) ||
-	    OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE)
-#ifdef RT30xx
-	    || (pAd->EepromAccess)
-#endif /* RT30xx // */
-#ifdef RT3090
-	    || (pAd->bPCIclkOff == TRUE)
-#endif /* RT3090 // */
-	    )
-		return;
-
-	{
-		/*if (pAd->StaCfg.Psm == PWR_SAVE) */
-		/*      return; */
-		{
-			if (pAd->StaCfg.Psm == PWR_SAVE)
-				return;
-
-			/* if the traffic is low, use average rssi as the criteria */
-			if (pAd->Mlme.bLowThroughput == TRUE) {
-				rssi0 = pAd->StaCfg.RssiSample.LastRssi0;
-				rssi1 = pAd->StaCfg.RssiSample.LastRssi1;
-				rssi2 = pAd->StaCfg.RssiSample.LastRssi2;
-			} else {
-				rssi0 = pAd->StaCfg.RssiSample.AvgRssi0;
-				rssi1 = pAd->StaCfg.RssiSample.AvgRssi1;
-				rssi2 = pAd->StaCfg.RssiSample.AvgRssi2;
-			}
-
-			if (pAd->Antenna.field.RxPath == 3) {
-				larger = max(rssi0, rssi1);
-
-				if (larger > (rssi2 + 20))
-					pAd->Mlme.RealRxPath = 2;
-				else
-					pAd->Mlme.RealRxPath = 3;
-			} else if (pAd->Antenna.field.RxPath == 2) {
-				if (rssi0 > (rssi1 + 20))
-					pAd->Mlme.RealRxPath = 1;
-				else
-					pAd->Mlme.RealRxPath = 2;
-			}
-
-			RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &BBPR3);
-			BBPR3 &= (~0x18);
-			if (pAd->Mlme.RealRxPath == 3) {
-				BBPR3 |= (0x10);
-			} else if (pAd->Mlme.RealRxPath == 2) {
-				BBPR3 |= (0x8);
-			} else if (pAd->Mlme.RealRxPath == 1) {
-				BBPR3 |= (0x0);
-			}
-			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, BBPR3);
-#ifdef RTMP_MAC_PCI
-			pAd->StaCfg.BBPR3 = BBPR3;
-#endif /* RTMP_MAC_PCI // */
-		}
-	}
-
-}
-
-void APSDPeriodicExec(void *SystemSpecific1,
-		      void *FunctionContext,
-		      void *SystemSpecific2, void *SystemSpecific3)
-{
-	struct rt_rtmp_adapter *pAd = (struct rt_rtmp_adapter *)FunctionContext;
-
-	if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
-		return;
-
-	pAd->CommonCfg.TriggerTimerCount++;
-
-/* Driver should not send trigger frame, it should be send by application layer */
-/*
-	if (pAd->CommonCfg.bAPSDCapable && pAd->CommonCfg.APEdcaParm.bAPSDCapable
-		&& (pAd->CommonCfg.bNeedSendTriggerFrame ||
-		(((pAd->CommonCfg.TriggerTimerCount%20) == 19) && (!pAd->CommonCfg.bAPSDAC_BE || !pAd->CommonCfg.bAPSDAC_BK || !pAd->CommonCfg.bAPSDAC_VI || !pAd->CommonCfg.bAPSDAC_VO))))
-	{
-		DBGPRINT(RT_DEBUG_TRACE,("Sending trigger frame and enter service period when support APSD\n"));
-		RTMPSendNullFrame(pAd, pAd->CommonCfg.TxRate, TRUE);
-		pAd->CommonCfg.bNeedSendTriggerFrame = FALSE;
-		pAd->CommonCfg.TriggerTimerCount = 0;
-		pAd->CommonCfg.bInServicePeriod = TRUE;
-	}*/
-}
-
-/*
-    ========================================================================
-    Routine Description:
-        Set/reset MAC registers according to bPiggyBack parameter
-
-    Arguments:
-        pAd         - Adapter pointer
-        bPiggyBack  - Enable / Disable Piggy-Back
-
-    Return Value:
-        None
-
-    ========================================================================
-*/
-void RTMPSetPiggyBack(struct rt_rtmp_adapter *pAd, IN BOOLEAN bPiggyBack)
-{
-	TX_LINK_CFG_STRUC TxLinkCfg;
-
-	RTMP_IO_READ32(pAd, TX_LINK_CFG, &TxLinkCfg.word);
-
-	TxLinkCfg.field.TxCFAckEn = bPiggyBack;
-	RTMP_IO_WRITE32(pAd, TX_LINK_CFG, TxLinkCfg.word);
-}
-
-/*
-    ========================================================================
-    Routine Description:
-        check if this entry need to switch rate automatically
-
-    Arguments:
-        pAd
-        pEntry
-
-    Return Value:
-        TURE
-        FALSE
-
-    ========================================================================
-*/
-BOOLEAN RTMPCheckEntryEnableAutoRateSwitch(struct rt_rtmp_adapter *pAd,
-					   struct rt_mac_table_entry *pEntry)
-{
-	BOOLEAN result = TRUE;
-
-	{
-		/* only associated STA counts */
-		if (pEntry && (pEntry->ValidAsCLI)
-		    && (pEntry->Sst == SST_ASSOC)) {
-			result = pAd->StaCfg.bAutoTxRateSwitch;
-		} else
-			result = FALSE;
-	}
-
-	return result;
-}
-
-BOOLEAN RTMPAutoRateSwitchCheck(struct rt_rtmp_adapter *pAd)
-{
-	{
-		if (pAd->StaCfg.bAutoTxRateSwitch)
-			return TRUE;
-	}
-	return FALSE;
-}
-
-/*
-    ========================================================================
-    Routine Description:
-        check if this entry need to fix tx legacy rate
-
-    Arguments:
-        pAd
-        pEntry
-
-    Return Value:
-        TURE
-        FALSE
-
-    ========================================================================
-*/
-u8 RTMPStaFixedTxMode(struct rt_rtmp_adapter *pAd, struct rt_mac_table_entry *pEntry)
-{
-	u8 tx_mode = FIXED_TXMODE_HT;
-
-	{
-		tx_mode =
-		    (u8)pAd->StaCfg.DesiredTransmitSetting.field.
-		    FixedTxMode;
-	}
-
-	return tx_mode;
-}
-
-/*
-    ========================================================================
-    Routine Description:
-        Overwrite HT Tx Mode by Fixed Legency Tx Mode, if specified.
-
-    Arguments:
-        pAd
-        pEntry
-
-    Return Value:
-        TURE
-        FALSE
-
-    ========================================================================
-*/
-void RTMPUpdateLegacyTxSetting(u8 fixed_tx_mode, struct rt_mac_table_entry *pEntry)
-{
-	HTTRANSMIT_SETTING TransmitSetting;
-
-	if (fixed_tx_mode == FIXED_TXMODE_HT)
-		return;
-
-	TransmitSetting.word = 0;
-
-	TransmitSetting.field.MODE = pEntry->HTPhyMode.field.MODE;
-	TransmitSetting.field.MCS = pEntry->HTPhyMode.field.MCS;
-
-	if (fixed_tx_mode == FIXED_TXMODE_CCK) {
-		TransmitSetting.field.MODE = MODE_CCK;
-		/* CCK mode allow MCS 0~3 */
-		if (TransmitSetting.field.MCS > MCS_3)
-			TransmitSetting.field.MCS = MCS_3;
-	} else {
-		TransmitSetting.field.MODE = MODE_OFDM;
-		/* OFDM mode allow MCS 0~7 */
-		if (TransmitSetting.field.MCS > MCS_7)
-			TransmitSetting.field.MCS = MCS_7;
-	}
-
-	if (pEntry->HTPhyMode.field.MODE >= TransmitSetting.field.MODE) {
-		pEntry->HTPhyMode.word = TransmitSetting.word;
-		DBGPRINT(RT_DEBUG_TRACE,
-			 ("RTMPUpdateLegacyTxSetting : wcid-%d, MODE=%s, MCS=%d \n",
-			  pEntry->Aid, GetPhyMode(pEntry->HTPhyMode.field.MODE),
-			  pEntry->HTPhyMode.field.MCS));
-	}
-}
-
-/*
-	==========================================================================
-	Description:
-		dynamic tune BBP R66 to find a balance between sensibility and
-		noise isolation
-
-	IRQL = DISPATCH_LEVEL
-
-	==========================================================================
- */
-void AsicStaBbpTuning(struct rt_rtmp_adapter *pAd)
-{
-	u8 OrigR66Value = 0, R66;	/*, R66UpperBound = 0x30, R66LowerBound = 0x30; */
-	char Rssi;
-
-	/* 2860C did not support Fase CCA, therefore can't tune */
-	if (pAd->MACVersion == 0x28600100)
-		return;
-
-	/* */
-	/* work as a STA */
-	/* */
-	if (pAd->Mlme.CntlMachine.CurrState != CNTL_IDLE)	/* no R66 tuning when SCANNING */
-		return;
-
-	if ((pAd->OpMode == OPMODE_STA)
-	    && (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED)
-	    )
-	    && !(OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
-#ifdef RTMP_MAC_PCI
-	    && (pAd->bPCIclkOff == FALSE)
-#endif /* RTMP_MAC_PCI // */
-	    ) {
-		RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R66, &OrigR66Value);
-		R66 = OrigR66Value;
-
-		if (pAd->Antenna.field.RxPath > 1)
-			Rssi =
-			    (pAd->StaCfg.RssiSample.AvgRssi0 +
-			     pAd->StaCfg.RssiSample.AvgRssi1) >> 1;
-		else
-			Rssi = pAd->StaCfg.RssiSample.AvgRssi0;
-
-		if (pAd->LatchRfRegs.Channel <= 14) {	/*BG band */
-#ifdef RT30xx
-			/* RT3070 is a no LNA solution, it should have different control regarding to AGC gain control */
-			/* Otherwise, it will have some throughput side effect when low RSSI */
-
-			if (IS_RT3070(pAd) || IS_RT3090(pAd) || IS_RT3572(pAd)
-			    || IS_RT3390(pAd)) {
-				if (Rssi > RSSI_FOR_MID_LOW_SENSIBILITY) {
-					R66 =
-					    0x1C + 2 * GET_LNA_GAIN(pAd) + 0x20;
-					if (OrigR66Value != R66) {
-						RTMP_BBP_IO_WRITE8_BY_REG_ID
-						    (pAd, BBP_R66, R66);
-					}
-				} else {
-					R66 = 0x1C + 2 * GET_LNA_GAIN(pAd);
-					if (OrigR66Value != R66) {
-						RTMP_BBP_IO_WRITE8_BY_REG_ID
-						    (pAd, BBP_R66, R66);
-					}
-				}
-			} else
-#endif /* RT30xx // */
-			{
-				if (Rssi > RSSI_FOR_MID_LOW_SENSIBILITY) {
-					R66 = (0x2E + GET_LNA_GAIN(pAd)) + 0x10;
-					if (OrigR66Value != R66) {
-						RTMP_BBP_IO_WRITE8_BY_REG_ID
-						    (pAd, BBP_R66, R66);
-					}
-				} else {
-					R66 = 0x2E + GET_LNA_GAIN(pAd);
-					if (OrigR66Value != R66) {
-						RTMP_BBP_IO_WRITE8_BY_REG_ID
-						    (pAd, BBP_R66, R66);
-					}
-				}
-			}
-		} else {	/*A band */
-			if (pAd->CommonCfg.BBPCurrentBW == BW_20) {
-				if (Rssi > RSSI_FOR_MID_LOW_SENSIBILITY) {
-					R66 =
-					    0x32 + (GET_LNA_GAIN(pAd) * 5) / 3 +
-					    0x10;
-					if (OrigR66Value != R66) {
-						RTMP_BBP_IO_WRITE8_BY_REG_ID
-						    (pAd, BBP_R66, R66);
-					}
-				} else {
-					R66 =
-					    0x32 + (GET_LNA_GAIN(pAd) * 5) / 3;
-					if (OrigR66Value != R66) {
-						RTMP_BBP_IO_WRITE8_BY_REG_ID
-						    (pAd, BBP_R66, R66);
-					}
-				}
-			} else {
-				if (Rssi > RSSI_FOR_MID_LOW_SENSIBILITY) {
-					R66 =
-					    0x3A + (GET_LNA_GAIN(pAd) * 5) / 3 +
-					    0x10;
-					if (OrigR66Value != R66) {
-						RTMP_BBP_IO_WRITE8_BY_REG_ID
-						    (pAd, BBP_R66, R66);
-					}
-				} else {
-					R66 =
-					    0x3A + (GET_LNA_GAIN(pAd) * 5) / 3;
-					if (OrigR66Value != R66) {
-						RTMP_BBP_IO_WRITE8_BY_REG_ID
-						    (pAd, BBP_R66, R66);
-					}
-				}
-			}
-		}
-
-	}
-}
-
-void RTMPSetAGCInitValue(struct rt_rtmp_adapter *pAd, u8 BandWidth)
-{
-	u8 R66 = 0x30;
-
-	if (pAd->LatchRfRegs.Channel <= 14) {	/* BG band */
-#ifdef RT30xx
-		/* Gary was verified Amazon AP and find that RT307x has BBP_R66 invalid default value */
-
-		if (IS_RT3070(pAd) || IS_RT3090(pAd) || IS_RT3572(pAd)
-		    || IS_RT3390(pAd)) {
-			R66 = 0x1C + 2 * GET_LNA_GAIN(pAd);
-			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66);
-		} else
-#endif /* RT30xx // */
-		{
-			R66 = 0x2E + GET_LNA_GAIN(pAd);
-			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66);
-		}
-	} else {		/*A band */
-		{
-			if (BandWidth == BW_20) {
-				R66 =
-				    (u8)(0x32 +
-					     (GET_LNA_GAIN(pAd) * 5) / 3);
-				RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66);
-			} else {
-				R66 =
-				    (u8)(0x3A +
-					     (GET_LNA_GAIN(pAd) * 5) / 3);
-				RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66);
-			}
-		}
-	}
-
-}
diff -druN linux-2.6.39-libre/drivers/staging/rt2860/common/rt_channel.c linux-3.0-rc7-libre/drivers/staging/rt2860/common/rt_channel.c
--- linux-2.6.39-libre/drivers/staging/rt2860/common/rt_channel.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rt2860/common/rt_channel.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,1705 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, Inc.
- *
- * This program is free software; you can redistribute it and/or modify  *
- * it under the terms of the GNU General Public License as published by  *
- * the Free Software Foundation; either version 2 of the License, or     *
- * (at your option) any later version.                                   *
- *                                                                       *
- * This program is distributed in the hope that it will be useful,       *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of        *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
- * GNU General Public License for more details.                          *
- *                                                                       *
- * You should have received a copy of the GNU General Public License     *
- * along with this program; if not, write to the                         *
- * Free Software Foundation, Inc.,                                       *
- * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
- *                                                                       *
- *************************************************************************
-*/
-#include "../rt_config.h"
-
-struct rt_ch_freq_map CH_HZ_ID_MAP[] = {
-	{1, 2412}
-	,
-	{2, 2417}
-	,
-	{3, 2422}
-	,
-	{4, 2427}
-	,
-	{5, 2432}
-	,
-	{6, 2437}
-	,
-	{7, 2442}
-	,
-	{8, 2447}
-	,
-	{9, 2452}
-	,
-	{10, 2457}
-	,
-	{11, 2462}
-	,
-	{12, 2467}
-	,
-	{13, 2472}
-	,
-	{14, 2484}
-	,
-
-	/*  UNII */
-	{36, 5180}
-	,
-	{40, 5200}
-	,
-	{44, 5220}
-	,
-	{48, 5240}
-	,
-	{52, 5260}
-	,
-	{56, 5280}
-	,
-	{60, 5300}
-	,
-	{64, 5320}
-	,
-	{149, 5745}
-	,
-	{153, 5765}
-	,
-	{157, 5785}
-	,
-	{161, 5805}
-	,
-	{165, 5825}
-	,
-	{167, 5835}
-	,
-	{169, 5845}
-	,
-	{171, 5855}
-	,
-	{173, 5865}
-	,
-
-	/* HiperLAN2 */
-	{100, 5500}
-	,
-	{104, 5520}
-	,
-	{108, 5540}
-	,
-	{112, 5560}
-	,
-	{116, 5580}
-	,
-	{120, 5600}
-	,
-	{124, 5620}
-	,
-	{128, 5640}
-	,
-	{132, 5660}
-	,
-	{136, 5680}
-	,
-	{140, 5700}
-	,
-
-	/* Japan MMAC */
-	{34, 5170}
-	,
-	{38, 5190}
-	,
-	{42, 5210}
-	,
-	{46, 5230}
-	,
-
-	/*  Japan */
-	{184, 4920}
-	,
-	{188, 4940}
-	,
-	{192, 4960}
-	,
-	{196, 4980}
-	,
-
-	{208, 5040}
-	,			/* Japan, means J08 */
-	{212, 5060}
-	,			/* Japan, means J12 */
-	{216, 5080}
-	,			/* Japan, means J16 */
-};
-
-int CH_HZ_ID_MAP_NUM = (sizeof(CH_HZ_ID_MAP) / sizeof(struct rt_ch_freq_map));
-
-struct rt_ch_region ChRegion[] = {
-	{			/* Antigua and Berbuda */
-	 "AG",
-	 CE,
-	 {
-	  {1, 13, 20, BOTH, FALSE}
-	  ,			/* 2.4 G, ch 1~13 */
-	  {36, 4, 23, BOTH, FALSE}
-	  ,			/* 5G, ch 36~48 */
-	  {52, 4, 23, BOTH, FALSE}
-	  ,			/* 5G, ch 52~64 */
-	  {100, 11, 30, BOTH, FALSE}
-	  ,			/* 5G, ch 100~140 */
-	  {0}
-	  ,			/* end */
-	  }
-	 }
-	,
-
-	{			/* Argentina */
-	 "AR",
-	 CE,
-	 {
-	  {1, 13, 20, BOTH, FALSE}
-	  ,			/* 2.4 G, ch 1~13 */
-	  {52, 4, 24, BOTH, FALSE}
-	  ,			/* 5G, ch 52~64 */
-	  {149, 4, 30, BOTH, FALSE}
-	  ,			/* 5G, ch 149~161 */
-	  {0}
-	  ,			/* end */
-	  }
-	 }
-	,
-
-	{			/* Aruba */
-	 "AW",
-	 CE,
-	 {
-	  {1, 13, 20, BOTH, FALSE}
-	  ,			/* 2.4 G, ch 1~13 */
-	  {36, 4, 23, BOTH, FALSE}
-	  ,			/* 5G, ch 36~48 */
-	  {52, 4, 23, BOTH, FALSE}
-	  ,			/* 5G, ch 52~64 */
-	  {100, 11, 30, BOTH, FALSE}
-	  ,			/* 5G, ch 100~140 */
-	  {0}
-	  ,			/* end */
-	  }
-	 }
-	,
-
-	{			/* Australia */
-	 "AU",
-	 CE,
-	 {
-	  {1, 13, 20, BOTH, FALSE}
-	  ,			/* 2.4 G, ch 1~13 */
-	  {36, 4, 23, BOTH, FALSE}
-	  ,			/* 5G, ch 36~48 */
-	  {52, 4, 24, BOTH, FALSE}
-	  ,			/* 5G, ch 52~64 */
-	  {149, 5, 30, BOTH, FALSE}
-	  ,			/* 5G, ch 149~165 */
-	  {0}
-	  ,			/* end */
-	  }
-	 }
-	,
-
-	{			/* Austria */
-	 "AT",
-	 CE,
-	 {
-	  {1, 13, 20, BOTH, FALSE}
-	  ,			/* 2.4 G, ch 1~13 */
-	  {36, 4, 23, IDOR, TRUE}
-	  ,			/* 5G, ch 36~48 */
-	  {52, 4, 23, IDOR, TRUE}
-	  ,			/* 5G, ch 52~64 */
-	  {100, 11, 30, BOTH, TRUE}
-	  ,			/* 5G, ch 100~140 */
-	  {0}
-	  ,			/* end */
-	  }
-	 }
-	,
-
-	{			/* Bahamas */
-	 "BS",
-	 CE,
-	 {
-	  {1, 13, 20, BOTH, FALSE}
-	  ,			/* 2.4 G, ch 1~13 */
-	  {36, 4, 23, BOTH, FALSE}
-	  ,			/* 5G, ch 36~48 */
-	  {52, 4, 24, BOTH, FALSE}
-	  ,			/* 5G, ch 52~64 */
-	  {149, 5, 30, BOTH, FALSE}
-	  ,			/* 5G, ch 149~165 */
-	  {0}
-	  ,			/* end */
-	  }
-	 }
-	,
-
-	{			/* Barbados */
-	 "BB",
-	 CE,
-	 {
-	  {1, 13, 20, BOTH, FALSE}
-	  ,			/* 2.4 G, ch 1~13 */
-	  {36, 4, 23, BOTH, FALSE}
-	  ,			/* 5G, ch 36~48 */
-	  {52, 4, 24, BOTH, FALSE}
-	  ,			/* 5G, ch 52~64 */
-	  {100, 11, 30, BOTH, FALSE}
-	  ,			/* 5G, ch 100~140 */
-	  {0}
-	  ,			/* end */
-	  }
-	 }
-	,
-
-	{			/* Bermuda */
-	 "BM",
-	 CE,
-	 {
-	  {1, 13, 20, BOTH, FALSE}
-	  ,			/* 2.4 G, ch 1~13 */
-	  {36, 4, 23, BOTH, FALSE}
-	  ,			/* 5G, ch 36~48 */
-	  {52, 4, 24, BOTH, FALSE}
-	  ,			/* 5G, ch 52~64 */
-	  {100, 11, 30, BOTH, FALSE}
-	  ,			/* 5G, ch 100~140 */
-	  {0}
-	  ,			/* end */
-	  }
-	 }
-	,
-
-	{			/* Brazil */
-	 "BR",
-	 CE,
-	 {
-	  {1, 13, 20, BOTH, FALSE}
-	  ,			/* 2.4 G, ch 1~13 */
-	  {36, 4, 23, BOTH, FALSE}
-	  ,			/* 5G, ch 36~48 */
-	  {52, 4, 24, BOTH, FALSE}
-	  ,			/* 5G, ch 52~64 */
-	  {100, 11, 24, BOTH, FALSE}
-	  ,			/* 5G, ch 100~140 */
-	  {149, 5, 30, BOTH, FALSE}
-	  ,			/* 5G, ch 100~140 */
-	  {0}
-	  ,			/* end */
-	  }
-	 }
-	,
-
-	{			/* Belgium */
-	 "BE",
-	 CE,
-	 {
-	  {1, 13, 20, BOTH, FALSE}
-	  ,			/* 2.4 G, ch 1~13 */
-	  {36, 4, 18, IDOR, FALSE}
-	  ,			/* 5G, ch 36~48 */
-	  {52, 4, 18, IDOR, FALSE}
-	  ,			/* 5G, ch 52~64 */
-	  {0}
-	  ,			/* end */
-	  }
-	 }
-	,
-
-	{			/* Bulgaria */
-	 "BG",
-	 CE,
-	 {
-	  {1, 13, 20, BOTH, FALSE}
-	  ,			/* 2.4 G, ch 1~13 */
-	  {36, 4, 23, IDOR, FALSE}
-	  ,			/* 5G, ch 36~48 */
-	  {52, 4, 23, IDOR, TRUE}
-	  ,			/* 5G, ch 52~64 */
-	  {100, 11, 30, ODOR, TRUE}
-	  ,			/* 5G, ch 100~140 */
-	  {0}
-	  ,			/* end */
-	  }
-	 }
-	,
-
-	{			/* Canada */
-	 "CA",
-	 CE,
-	 {
-	  {1, 13, 20, BOTH, FALSE}
-	  ,			/* 2.4 G, ch 1~13 */
-	  {36, 4, 23, BOTH, FALSE}
-	  ,			/* 5G, ch 36~48 */
-	  {52, 4, 23, BOTH, FALSE}
-	  ,			/* 5G, ch 52~64 */
-	  {149, 5, 30, BOTH, FALSE}
-	  ,			/* 5G, ch 149~165 */
-	  {0}
-	  ,			/* end */
-	  }
-	 }
-	,
-
-	{			/* Cayman IsLands */
-	 "KY",
-	 CE,
-	 {
-	  {1, 13, 20, BOTH, FALSE}
-	  ,			/* 2.4 G, ch 1~13 */
-	  {36, 4, 23, BOTH, FALSE}
-	  ,			/* 5G, ch 36~48 */
-	  {52, 4, 24, BOTH, FALSE}
-	  ,			/* 5G, ch 52~64 */
-	  {100, 11, 30, BOTH, FALSE}
-	  ,			/* 5G, ch 100~140 */
-	  {0}
-	  ,			/* end */
-	  }
-	 }
-	,
-
-	{			/* Chile */
-	 "CL",
-	 CE,
-	 {
-	  {1, 13, 20, BOTH, FALSE}
-	  ,			/* 2.4 G, ch 1~13 */
-	  {36, 4, 20, BOTH, FALSE}
-	  ,			/* 5G, ch 36~48 */
-	  {52, 4, 20, BOTH, FALSE}
-	  ,			/* 5G, ch 52~64 */
-	  {149, 5, 20, BOTH, FALSE}
-	  ,			/* 5G, ch 149~165 */
-	  {0}
-	  ,			/* end */
-	  }
-	 }
-	,
-
-	{			/* China */
-	 "CN",
-	 CE,
-	 {
-	  {1, 13, 20, BOTH, FALSE}
-	  ,			/* 2.4 G, ch 1~13 */
-	  {149, 4, 27, BOTH, FALSE}
-	  ,			/* 5G, ch 149~161 */
-	  {0}
-	  ,			/* end */
-	  }
-	 }
-	,
-
-	{			/* Colombia */
-	 "CO",
-	 CE,
-	 {
-	  {1, 13, 20, BOTH, FALSE}
-	  ,			/* 2.4 G, ch 1~13 */
-	  {36, 4, 17, BOTH, FALSE}
-	  ,			/* 5G, ch 36~48 */
-	  {52, 4, 24, BOTH, FALSE}
-	  ,			/* 5G, ch 52~64 */
-	  {100, 11, 30, BOTH, FALSE}
-	  ,			/* 5G, ch 100~140 */
-	  {149, 5, 30, BOTH, FALSE}
-	  ,			/* 5G, ch 149~165 */
-	  {0}
-	  ,			/* end */
-	  }
-	 }
-	,
-
-	{			/* Costa Rica */
-	 "CR",
-	 CE,
-	 {
-	  {1, 13, 20, BOTH, FALSE}
-	  ,			/* 2.4 G, ch 1~13 */
-	  {36, 4, 17, BOTH, FALSE}
-	  ,			/* 5G, ch 36~48 */
-	  {52, 4, 24, BOTH, FALSE}
-	  ,			/* 5G, ch 52~64 */
-	  {149, 4, 30, BOTH, FALSE}
-	  ,			/* 5G, ch 149~161 */
-	  {0}
-	  ,			/* end */
-	  }
-	 }
-	,
-
-	{			/* Cyprus */
-	 "CY",
-	 CE,
-	 {
-	  {1, 13, 20, BOTH, FALSE}
-	  ,			/* 2.4 G, ch 1~13 */
-	  {36, 4, 23, IDOR, FALSE}
-	  ,			/* 5G, ch 36~48 */
-	  {52, 4, 24, IDOR, TRUE}
-	  ,			/* 5G, ch 52~64 */
-	  {100, 11, 30, BOTH, TRUE}
-	  ,			/* 5G, ch 100~140 */
-	  {0}
-	  ,			/* end */
-	  }
-	 }
-	,
-
-	{			/* Czech_Republic */
-	 "CZ",
-	 CE,
-	 {
-	  {1, 13, 20, BOTH, FALSE}
-	  ,			/* 2.4 G, ch 1~13 */
-	  {36, 4, 23, IDOR, FALSE}
-	  ,			/* 5G, ch 36~48 */
-	  {52, 4, 23, IDOR, TRUE}
-	  ,			/* 5G, ch 52~64 */
-	  {0}
-	  ,			/* end */
-	  }
-	 }
-	,
-
-	{			/* Denmark */
-	 "DK",
-	 CE,
-	 {
-	  {1, 13, 20, BOTH, FALSE}
-	  ,			/* 2.4 G, ch 1~13 */
-	  {36, 4, 23, IDOR, FALSE}
-	  ,			/* 5G, ch 36~48 */
-	  {52, 4, 23, IDOR, TRUE}
-	  ,			/* 5G, ch 52~64 */
-	  {100, 11, 30, BOTH, TRUE}
-	  ,			/* 5G, ch 100~140 */
-	  {0}
-	  ,			/* end */
-	  }
-	 }
-	,
-
-	{			/* Dominican Republic */
-	 "DO",
-	 CE,
-	 {
-	  {1, 0, 20, BOTH, FALSE}
-	  ,			/* 2.4 G, ch 0 */
-	  {149, 4, 20, BOTH, FALSE}
-	  ,			/* 5G, ch 149~161 */
-	  {0}
-	  ,			/* end */
-	  }
-	 }
-	,
-
-	{			/* Equador */
-	 "EC",
-	 CE,
-	 {
-	  {1, 13, 20, BOTH, FALSE}
-	  ,			/* 2.4 G, ch 1~13 */
-	  {100, 11, 27, BOTH, FALSE}
-	  ,			/* 5G, ch 100~140 */
-	  {0}
-	  ,			/* end */
-	  }
-	 }
-	,
-
-	{			/* El Salvador */
-	 "SV",
-	 CE,
-	 {
-	  {1, 13, 20, BOTH, FALSE}
-	  ,			/* 2.4 G, ch 1~13 */
-	  {36, 4, 23, IDOR, FALSE}
-	  ,			/* 5G, ch 36~48 */
-	  {52, 4, 30, BOTH, TRUE}
-	  ,			/* 5G, ch 52~64 */
-	  {149, 4, 36, BOTH, TRUE}
-	  ,			/* 5G, ch 149~165 */
-	  {0}
-	  ,			/* end */
-	  }
-	 }
-	,
-
-	{			/* Finland */
-	 "FI",
-	 CE,
-	 {
-	  {1, 13, 20, BOTH, FALSE}
-	  ,			/* 2.4 G, ch 1~13 */
-	  {36, 4, 23, IDOR, FALSE}
-	  ,			/* 5G, ch 36~48 */
-	  {52, 4, 23, IDOR, TRUE}
-	  ,			/* 5G, ch 52~64 */
-	  {100, 11, 30, BOTH, TRUE}
-	  ,			/* 5G, ch 100~140 */
-	  {0}
-	  ,			/* end */
-	  }
-	 }
-	,
-
-	{			/* France */
-	 "FR",
-	 CE,
-	 {
-	  {1, 13, 20, BOTH, FALSE}
-	  ,			/* 2.4 G, ch 1~13 */
-	  {36, 4, 23, IDOR, FALSE}
-	  ,			/* 5G, ch 36~48 */
-	  {52, 4, 23, IDOR, TRUE}
-	  ,			/* 5G, ch 52~64 */
-	  {0}
-	  ,			/* end */
-	  }
-	 }
-	,
-
-	{			/* Germany */
-	 "DE",
-	 CE,
-	 {
-	  {1, 13, 20, BOTH, FALSE}
-	  ,			/* 2.4 G, ch 1~13 */
-	  {36, 4, 23, IDOR, FALSE}
-	  ,			/* 5G, ch 36~48 */
-	  {52, 4, 23, IDOR, TRUE}
-	  ,			/* 5G, ch 52~64 */
-	  {100, 11, 30, BOTH, TRUE}
-	  ,			/* 5G, ch 100~140 */
-	  {0}
-	  ,			/* end */
-	  }
-	 }
-	,
-
-	{			/* Greece */
-	 "GR",
-	 CE,
-	 {
-	  {1, 13, 20, BOTH, FALSE}
-	  ,			/* 2.4 G, ch 1~13 */
-	  {36, 4, 23, IDOR, FALSE}
-	  ,			/* 5G, ch 36~48 */
-	  {52, 4, 23, IDOR, TRUE}
-	  ,			/* 5G, ch 52~64 */
-	  {100, 11, 30, ODOR, TRUE}
-	  ,			/* 5G, ch 100~140 */
-	  {0}
-	  ,			/* end */
-	  }
-	 }
-	,
-
-	{			/* Guam */
-	 "GU",
-	 CE,
-	 {
-	  {1, 11, 20, BOTH, FALSE}
-	  ,			/* 2.4 G, ch 1~11 */
-	  {36, 4, 17, BOTH, FALSE}
-	  ,			/* 5G, ch 36~48 */
-	  {52, 4, 24, BOTH, FALSE}
-	  ,			/* 5G, ch 52~64 */
-	  {100, 11, 30, BOTH, FALSE}
-	  ,			/* 5G, ch 100~140 */
-	  {149, 5, 30, BOTH, FALSE}
-	  ,			/* 5G, ch 149~165 */
-	  {0}
-	  ,			/* end */
-	  }
-	 }
-	,
-
-	{			/* Guatemala */
-	 "GT",
-	 CE,
-	 {
-	  {1, 13, 20, BOTH, FALSE}
-	  ,			/* 2.4 G, ch 1~13 */
-	  {36, 4, 17, BOTH, FALSE}
-	  ,			/* 5G, ch 36~48 */
-	  {52, 4, 24, BOTH, FALSE}
-	  ,			/* 5G, ch 52~64 */
-	  {149, 4, 30, BOTH, FALSE}
-	  ,			/* 5G, ch 149~161 */
-	  {0}
-	  ,			/* end */
-	  }
-	 }
-	,
-
-	{			/* Haiti */
-	 "HT",
-	 CE,
-	 {
-	  {1, 13, 20, BOTH, FALSE}
-	  ,			/* 2.4 G, ch 1~13 */
-	  {36, 4, 17, BOTH, FALSE}
-	  ,			/* 5G, ch 36~48 */
-	  {52, 4, 24, BOTH, FALSE}
-	  ,			/* 5G, ch 52~64 */
-	  {149, 4, 30, BOTH, FALSE}
-	  ,			/* 5G, ch 149~161 */
-	  {0}
-	  ,			/* end */
-	  }
-	 }
-	,
-
-	{			/* Honduras */
-	 "HN",
-	 CE,
-	 {
-	  {1, 13, 20, BOTH, FALSE}
-	  ,			/* 2.4 G, ch 1~13 */
-	  {149, 4, 27, BOTH, FALSE}
-	  ,			/* 5G, ch 149~161 */
-	  {0}
-	  ,			/* end */
-	  }
-	 }
-	,
-
-	{			/* Hong Kong */
-	 "HK",
-	 CE,
-	 {
-	  {1, 13, 20, BOTH, FALSE}
-	  ,			/* 2.4 G, ch 1~13 */
-	  {36, 4, 23, IDOR, FALSE}
-	  ,			/* 5G, ch 36~48 */
-	  {52, 4, 23, IDOR, FALSE}
-	  ,			/* 5G, ch 52~64 */
-	  {149, 4, 30, BOTH, FALSE}
-	  ,			/* 5G, ch 149~161 */
-	  {0}
-	  ,			/* end */
-	  }
-	 }
-	,
-
-	{			/* Hungary */
-	 "HU",
-	 CE,
-	 {
-	  {1, 13, 20, BOTH, FALSE}
-	  ,			/* 2.4 G, ch 1~13 */
-	  {36, 4, 23, IDOR, FALSE}
-	  ,			/* 5G, ch 36~48 */
-	  {52, 4, 23, IDOR, TRUE}
-	  ,			/* 5G, ch 52~64 */
-	  {0}
-	  ,			/* end */
-	  }
-	 }
-	,
-
-	{			/* Iceland */
-	 "IS",
-	 CE,
-	 {
-	  {1, 13, 20, BOTH, FALSE}
-	  ,			/* 2.4 G, ch 1~13 */
-	  {36, 4, 23, IDOR, FALSE}
-	  ,			/* 5G, ch 36~48 */
-	  {52, 4, 23, IDOR, TRUE}
-	  ,			/* 5G, ch 52~64 */
-	  {100, 11, 30, BOTH, TRUE}
-	  ,			/* 5G, ch 100~140 */
-	  {0}
-	  ,			/* end */
-	  }
-	 }
-	,
-
-	{			/* India */
-	 "IN",
-	 CE,
-	 {
-	  {1, 13, 20, BOTH, FALSE}
-	  ,			/* 2.4 G, ch 1~13 */
-	  {149, 4, 24, IDOR, FALSE}
-	  ,			/* 5G, ch 149~161 */
-	  {0}
-	  ,			/* end */
-	  }
-	 }
-	,
-
-	{			/* Indonesia */
-	 "ID",
-	 CE,
-	 {
-	  {1, 13, 20, BOTH, FALSE}
-	  ,			/* 2.4 G, ch 1~13 */
-	  {149, 4, 27, BOTH, FALSE}
-	  ,			/* 5G, ch 149~161 */
-	  {0}
-	  ,			/* end */
-	  }
-	 }
-	,
-
-	{			/* Ireland */
-	 "IE",
-	 CE,
-	 {
-	  {1, 13, 20, BOTH, FALSE}
-	  ,			/* 2.4 G, ch 1~13 */
-	  {36, 4, 23, IDOR, FALSE}
-	  ,			/* 5G, ch 36~48 */
-	  {52, 4, 23, IDOR, TRUE}
-	  ,			/* 5G, ch 52~64 */
-	  {100, 11, 30, ODOR, TRUE}
-	  ,			/* 5G, ch 100~140 */
-	  {0}
-	  ,			/* end */
-	  }
-	 }
-	,
-
-	{			/* Israel */
-	 "IL",
-	 CE,
-	 {
-	  {1, 3, 20, IDOR, FALSE}
-	  ,			/* 2.4 G, ch 1~3 */
-	  {4, 6, 20, BOTH, FALSE}
-	  ,			/* 2.4 G, ch 4~9 */
-	  {10, 4, 20, IDOR, FALSE}
-	  ,			/* 2.4 G, ch 10~13 */
-	  {0}
-	  ,			/* end */
-	  }
-	 }
-	,
-
-	{			/* Italy */
-	 "IT",
-	 CE,
-	 {
-	  {1, 13, 20, BOTH, FALSE}
-	  ,			/* 2.4 G, ch 1~13 */
-	  {36, 4, 23, IDOR, FALSE}
-	  ,			/* 5G, ch 36~48 */
-	  {52, 4, 23, IDOR, TRUE}
-	  ,			/* 5G, ch 52~64 */
-	  {100, 11, 30, ODOR, TRUE}
-	  ,			/* 5G, ch 100~140 */
-	  {0}
-	  ,			/* end */
-	  }
-	 }
-	,
-
-	{			/* Japan */
-	 "JP",
-	 JAP,
-	 {
-	  {1, 14, 20, BOTH, FALSE}
-	  ,			/* 2.4 G, ch 1~14 */
-	  {36, 4, 23, IDOR, FALSE}
-	  ,			/* 5G, ch 36~48 */
-	  {0}
-	  ,			/* end */
-	  }
-	 }
-	,
-
-	{			/* Jordan */
-	 "JO",
-	 CE,
-	 {
-	  {1, 13, 20, IDOR, FALSE}
-	  ,			/* 2.4 G, ch 1~13 */
-	  {36, 4, 23, IDOR, FALSE}
-	  ,			/* 5G, ch 36~48 */
-	  {149, 4, 23, IDOR, FALSE}
-	  ,			/* 5G, ch 149~161 */
-	  {0}
-	  ,			/* end */
-	  }
-	 }
-	,
-
-	{			/* Latvia */
-	 "LV",
-	 CE,
-	 {
-	  {1, 13, 20, BOTH, FALSE}
-	  ,			/* 2.4 G, ch 1~13 */
-	  {36, 4, 23, IDOR, FALSE}
-	  ,			/* 5G, ch 36~48 */
-	  {52, 4, 23, IDOR, TRUE}
-	  ,			/* 5G, ch 52~64 */
-	  {100, 11, 30, BOTH, TRUE}
-	  ,			/* 5G, ch 100~140 */
-	  {0}
-	  ,			/* end */
-	  }
-	 }
-	,
-
-	{			/* Liechtenstein */
-	 "LI",
-	 CE,
-	 {
-	  {1, 13, 20, BOTH, FALSE}
-	  ,			/* 2.4 G, ch 1~13 */
-	  {52, 4, 23, IDOR, TRUE}
-	  ,			/* 5G, ch 52~64 */
-	  {100, 11, 30, BOTH, TRUE}
-	  ,			/* 5G, ch 100~140 */
-	  {0}
-	  ,			/* end */
-	  }
-	 }
-	,
-
-	{			/* Lithuania */
-	 "LT",
-	 CE,
-	 {
-	  {1, 13, 20, BOTH, FALSE}
-	  ,			/* 2.4 G, ch 1~13 */
-	  {36, 4, 23, IDOR, FALSE}
-	  ,			/* 5G, ch 36~48 */
-	  {52, 4, 23, IDOR, TRUE}
-	  ,			/* 5G, ch 52~64 */
-	  {100, 11, 30, BOTH, TRUE}
-	  ,			/* 5G, ch 100~140 */
-	  {0}
-	  ,			/* end */
-	  }
-	 }
-	,
-
-	{			/* Luxemburg */
-	 "LU",
-	 CE,
-	 {
-	  {1, 13, 20, BOTH, FALSE}
-	  ,			/* 2.4 G, ch 1~13 */
-	  {36, 4, 23, IDOR, FALSE}
-	  ,			/* 5G, ch 36~48 */
-	  {52, 4, 23, IDOR, TRUE}
-	  ,			/* 5G, ch 52~64 */
-	  {100, 11, 30, BOTH, TRUE}
-	  ,			/* 5G, ch 100~140 */
-	  {0}
-	  ,			/* end */
-	  }
-	 }
-	,
-
-	{			/* Malaysia */
-	 "MY",
-	 CE,
-	 {
-	  {36, 4, 23, BOTH, FALSE}
-	  ,			/* 5G, ch 36~48 */
-	  {52, 4, 23, BOTH, FALSE}
-	  ,			/* 5G, ch 52~64 */
-	  {149, 5, 20, BOTH, FALSE}
-	  ,			/* 5G, ch 149~165 */
-	  {0}
-	  ,			/* end */
-	  }
-	 }
-	,
-
-	{			/* Malta */
-	 "MT",
-	 CE,
-	 {
-	  {1, 13, 20, BOTH, FALSE}
-	  ,			/* 2.4 G, ch 1~13 */
-	  {36, 4, 23, IDOR, FALSE}
-	  ,			/* 5G, ch 36~48 */
-	  {52, 4, 23, IDOR, TRUE}
-	  ,			/* 5G, ch 52~64 */
-	  {100, 11, 30, BOTH, TRUE}
-	  ,			/* 5G, ch 100~140 */
-	  {0}
-	  ,			/* end */
-	  }
-	 }
-	,
-
-	{			/* Marocco */
-	 "MA",
-	 CE,
-	 {
-	  {1, 13, 20, BOTH, FALSE}
-	  ,			/* 2.4 G, ch 1~13 */
-	  {36, 4, 24, IDOR, FALSE}
-	  ,			/* 5G, ch 36~48 */
-	  {0}
-	  ,			/* end */
-	  }
-	 }
-	,
-
-	{			/* Mexico */
-	 "MX",
-	 CE,
-	 {
-	  {1, 13, 20, BOTH, FALSE}
-	  ,			/* 2.4 G, ch 1~13 */
-	  {36, 4, 23, BOTH, FALSE}
-	  ,			/* 5G, ch 36~48 */
-	  {52, 4, 24, BOTH, FALSE}
-	  ,			/* 5G, ch 52~64 */
-	  {149, 5, 30, IDOR, FALSE}
-	  ,			/* 5G, ch 149~165 */
-	  {0}
-	  ,			/* end */
-	  }
-	 }
-	,
-
-	{			/* Netherlands */
-	 "NL",
-	 CE,
-	 {
-	  {1, 13, 20, BOTH, FALSE}
-	  ,			/* 2.4 G, ch 1~13 */
-	  {36, 4, 23, IDOR, FALSE}
-	  ,			/* 5G, ch 36~48 */
-	  {52, 4, 24, IDOR, TRUE}
-	  ,			/* 5G, ch 52~64 */
-	  {100, 11, 30, BOTH, TRUE}
-	  ,			/* 5G, ch 100~140 */
-	  {0}
-	  ,			/* end */
-	  }
-	 }
-	,
-
-	{			/* New Zealand */
-	 "NZ",
-	 CE,
-	 {
-	  {1, 13, 20, BOTH, FALSE}
-	  ,			/* 2.4 G, ch 1~13 */
-	  {36, 4, 24, BOTH, FALSE}
-	  ,			/* 5G, ch 36~48 */
-	  {52, 4, 24, BOTH, FALSE}
-	  ,			/* 5G, ch 52~64 */
-	  {149, 4, 30, BOTH, FALSE}
-	  ,			/* 5G, ch 149~161 */
-	  {0}
-	  ,			/* end */
-	  }
-	 }
-	,
-
-	{			/* Norway */
-	 "NO",
-	 CE,
-	 {
-	  {1, 13, 20, BOTH, FALSE}
-	  ,			/* 2.4 G, ch 1~13 */
-	  {36, 4, 24, IDOR, FALSE}
-	  ,			/* 5G, ch 36~48 */
-	  {52, 4, 24, IDOR, TRUE}
-	  ,			/* 5G, ch 52~64 */
-	  {100, 11, 30, BOTH, TRUE}
-	  ,			/* 5G, ch 149~161 */
-	  {0}
-	  ,			/* end */
-	  }
-	 }
-	,
-
-	{			/* Peru */
-	 "PE",
-	 CE,
-	 {
-	  {1, 13, 20, BOTH, FALSE}
-	  ,			/* 2.4 G, ch 1~13 */
-	  {149, 4, 27, BOTH, FALSE}
-	  ,			/* 5G, ch 149~161 */
-	  {0}
-	  ,			/* end */
-	  }
-	 }
-	,
-
-	{			/* Portugal */
-	 "PT",
-	 CE,
-	 {
-	  {1, 13, 20, BOTH, FALSE}
-	  ,			/* 2.4 G, ch 1~13 */
-	  {36, 4, 23, IDOR, FALSE}
-	  ,			/* 5G, ch 36~48 */
-	  {52, 4, 23, IDOR, TRUE}
-	  ,			/* 5G, ch 52~64 */
-	  {100, 11, 30, BOTH, TRUE}
-	  ,			/* 5G, ch 100~140 */
-	  {0}
-	  ,			/* end */
-	  }
-	 }
-	,
-
-	{			/* Poland */
-	 "PL",
-	 CE,
-	 {
-	  {1, 13, 20, BOTH, FALSE}
-	  ,			/* 2.4 G, ch 1~13 */
-	  {36, 4, 23, IDOR, FALSE}
-	  ,			/* 5G, ch 36~48 */
-	  {52, 4, 23, IDOR, TRUE}
-	  ,			/* 5G, ch 52~64 */
-	  {100, 11, 30, BOTH, TRUE}
-	  ,			/* 5G, ch 100~140 */
-	  {0}
-	  ,			/* end */
-	  }
-	 }
-	,
-
-	{			/* Romania */
-	 "RO",
-	 CE,
-	 {
-	  {1, 13, 20, BOTH, FALSE}
-	  ,			/* 2.4 G, ch 1~13 */
-	  {36, 4, 23, IDOR, FALSE}
-	  ,			/* 5G, ch 36~48 */
-	  {52, 4, 23, IDOR, TRUE}
-	  ,			/* 5G, ch 52~64 */
-	  {100, 11, 30, BOTH, TRUE}
-	  ,			/* 5G, ch 100~140 */
-	  {0}
-	  ,			/* end */
-	  }
-	 }
-	,
-
-	{			/* Russia */
-	 "RU",
-	 CE,
-	 {
-	  {1, 13, 20, BOTH, FALSE}
-	  ,			/* 2.4 G, ch 1~13 */
-	  {149, 4, 20, IDOR, FALSE}
-	  ,			/* 5G, ch 149~161 */
-	  {0}
-	  ,			/* end */
-	  }
-	 }
-	,
-
-	{			/* Saudi Arabia */
-	 "SA",
-	 CE,
-	 {
-	  {1, 13, 20, BOTH, FALSE}
-	  ,			/* 2.4 G, ch 1~13 */
-	  {36, 4, 23, BOTH, FALSE}
-	  ,			/* 5G, ch 36~48 */
-	  {52, 4, 23, BOTH, FALSE}
-	  ,			/* 5G, ch 52~64 */
-	  {149, 4, 23, BOTH, FALSE}
-	  ,			/* 5G, ch 149~161 */
-	  {0}
-	  ,			/* end */
-	  }
-	 }
-	,
-
-	{			/* Serbia_and_Montenegro */
-	 "CS",
-	 CE,
-	 {
-	  {1, 13, 20, BOTH, FALSE}
-	  ,			/* 2.4 G, ch 1~13 */
-	  {0}
-	  ,			/* end */
-	  }
-	 }
-	,
-
-	{			/* Singapore */
-	 "SG",
-	 CE,
-	 {
-	  {1, 13, 20, BOTH, FALSE}
-	  ,			/* 2.4 G, ch 1~13 */
-	  {36, 4, 23, BOTH, FALSE}
-	  ,			/* 5G, ch 36~48 */
-	  {52, 4, 23, BOTH, FALSE}
-	  ,			/* 5G, ch 52~64 */
-	  {149, 4, 20, BOTH, FALSE}
-	  ,			/* 5G, ch 149~161 */
-	  {0}
-	  ,			/* end */
-	  }
-	 }
-	,
-
-	{			/* Slovakia */
-	 "SK",
-	 CE,
-	 {
-	  {1, 13, 20, BOTH, FALSE}
-	  ,			/* 2.4 G, ch 1~13 */
-	  {36, 4, 23, IDOR, FALSE}
-	  ,			/* 5G, ch 36~48 */
-	  {52, 4, 23, IDOR, TRUE}
-	  ,			/* 5G, ch 52~64 */
-	  {100, 11, 30, BOTH, TRUE}
-	  ,			/* 5G, ch 100~140 */
-	  {0}
-	  ,			/* end */
-	  }
-	 }
-	,
-
-	{			/* Slovenia */
-	 "SI",
-	 CE,
-	 {
-	  {1, 13, 20, BOTH, FALSE}
-	  ,			/* 2.4 G, ch 1~13 */
-	  {36, 4, 23, IDOR, FALSE}
-	  ,			/* 5G, ch 36~48 */
-	  {52, 4, 23, IDOR, TRUE}
-	  ,			/* 5G, ch 52~64 */
-	  {0}
-	  ,			/* end */
-	  }
-	 }
-	,
-
-	{			/* South Africa */
-	 "ZA",
-	 CE,
-	 {
-	  {1, 13, 20, BOTH, FALSE}
-	  ,			/* 2.4 G, ch 1~13 */
-	  {36, 4, 23, BOTH, FALSE}
-	  ,			/* 5G, ch 36~48 */
-	  {52, 4, 23, IDOR, FALSE}
-	  ,			/* 5G, ch 52~64 */
-	  {100, 11, 30, BOTH, TRUE}
-	  ,			/* 5G, ch 100~140 */
-	  {149, 4, 30, BOTH, FALSE}
-	  ,			/* 5G, ch 149~161 */
-	  {0}
-	  ,			/* end */
-	  }
-	 }
-	,
-
-	{			/* South Korea */
-	 "KR",
-	 CE,
-	 {
-	  {1, 13, 20, BOTH, FALSE}
-	  ,			/* 2.4 G, ch 1~13 */
-	  {36, 4, 20, BOTH, FALSE}
-	  ,			/* 5G, ch 36~48 */
-	  {52, 4, 20, BOTH, FALSE}
-	  ,			/* 5G, ch 52~64 */
-	  {100, 8, 20, BOTH, FALSE}
-	  ,			/* 5G, ch 100~128 */
-	  {149, 4, 20, BOTH, FALSE}
-	  ,			/* 5G, ch 149~161 */
-	  {0}
-	  ,			/* end */
-	  }
-	 }
-	,
-
-	{			/* Spain */
-	 "ES",
-	 CE,
-	 {
-	  {1, 13, 20, BOTH, FALSE}
-	  ,			/* 2.4 G, ch 1~13 */
-	  {36, 4, 17, IDOR, FALSE}
-	  ,			/* 5G, ch 36~48 */
-	  {52, 4, 23, IDOR, TRUE}
-	  ,			/* 5G, ch 52~64 */
-	  {100, 11, 30, BOTH, TRUE}
-	  ,			/* 5G, ch 100~140 */
-	  {0}
-	  ,			/* end */
-	  }
-	 }
-	,
-
-	{			/* Sweden */
-	 "SE",
-	 CE,
-	 {
-	  {1, 13, 20, BOTH, FALSE}
-	  ,			/* 2.4 G, ch 1~13 */
-	  {36, 4, 23, IDOR, FALSE}
-	  ,			/* 5G, ch 36~48 */
-	  {52, 4, 23, IDOR, TRUE}
-	  ,			/* 5G, ch 52~64 */
-	  {100, 11, 30, BOTH, TRUE}
-	  ,			/* 5G, ch 100~140 */
-	  {0}
-	  ,			/* end */
-	  }
-	 }
-	,
-
-	{			/* Switzerland */
-	 "CH",
-	 CE,
-	 {
-	  {1, 13, 20, BOTH, FALSE}
-	  ,			/* 2.4 G, ch 1~13 */
-	  {36, 4, 23, IDOR, TRUE}
-	  ,			/* 5G, ch 36~48 */
-	  {52, 4, 23, IDOR, TRUE}
-	  ,			/* 5G, ch 52~64 */
-	  {0}
-	  ,			/* end */
-	  }
-	 }
-	,
-
-	{			/* Taiwan */
-	 "TW",
-	 CE,
-	 {
-	  {1, 11, 30, BOTH, FALSE}
-	  ,			/* 2.4 G, ch 1~11 */
-	  {52, 4, 23, IDOR, FALSE}
-	  ,			/* 5G, ch 52~64 */
-	  {0}
-	  ,			/* end */
-	  }
-	 }
-	,
-
-	{			/* Turkey */
-	 "TR",
-	 CE,
-	 {
-	  {1, 13, 20, BOTH, FALSE}
-	  ,			/* 2.4 G, ch 1~11 */
-	  {36, 4, 23, BOTH, FALSE}
-	  ,			/* 5G, ch 36~48 */
-	  {52, 4, 23, BOTH, FALSE}
-	  ,			/* 5G, ch 52~64 */
-	  {0}
-	  ,			/* end */
-	  }
-	 }
-	,
-
-	{			/* UK */
-	 "GB",
-	 CE,
-	 {
-	  {1, 13, 20, BOTH, FALSE}
-	  ,			/* 2.4 G, ch 1~11 */
-	  {36, 4, 23, IDOR, FALSE}
-	  ,			/* 5G, ch 52~64 */
-	  {52, 4, 23, IDOR, TRUE}
-	  ,			/* 5G, ch 52~64 */
-	  {100, 11, 30, BOTH, TRUE}
-	  ,			/* 5G, ch 100~140 */
-	  {0}
-	  ,			/* end */
-	  }
-	 }
-	,
-
-	{			/* Ukraine */
-	 "UA",
-	 CE,
-	 {
-	  {1, 13, 20, BOTH, FALSE}
-	  ,			/* 2.4 G, ch 1~11 */
-	  {0}
-	  ,			/* end */
-	  }
-	 }
-	,
-
-	{			/* United_Arab_Emirates */
-	 "AE",
-	 CE,
-	 {
-	  {1, 13, 20, BOTH, FALSE}
-	  ,			/* 2.4 G, ch 1~11 */
-	  {0}
-	  ,			/* end */
-	  }
-	 }
-	,
-
-	{			/* United_States */
-	 "US",
-	 CE,
-	 {
-	  {1, 11, 30, BOTH, FALSE}
-	  ,			/* 2.4 G, ch 1~11 */
-	  {36, 4, 17, IDOR, FALSE}
-	  ,			/* 5G, ch 52~64 */
-	  {52, 4, 24, BOTH, TRUE}
-	  ,			/* 5G, ch 52~64 */
-	  {100, 11, 30, BOTH, TRUE}
-	  ,			/* 5G, ch 100~140 */
-	  {149, 5, 30, BOTH, FALSE}
-	  ,			/* 5G, ch 149~165 */
-	  {0}
-	  ,			/* end */
-	  }
-	 }
-	,
-
-	{			/* Venezuela */
-	 "VE",
-	 CE,
-	 {
-	  {1, 13, 20, BOTH, FALSE}
-	  ,			/* 2.4 G, ch 1~11 */
-	  {149, 4, 27, BOTH, FALSE}
-	  ,			/* 5G, ch 149~161 */
-	  {0}
-	  ,			/* end */
-	  }
-	 }
-	,
-
-	{			/* Default */
-	 "",
-	 CE,
-	 {
-	  {1, 11, 20, BOTH, FALSE}
-	  ,			/* 2.4 G, ch 1~11 */
-	  {36, 4, 20, BOTH, FALSE}
-	  ,			/* 5G, ch 52~64 */
-	  {52, 4, 20, BOTH, FALSE}
-	  ,			/* 5G, ch 52~64 */
-	  {100, 11, 20, BOTH, FALSE}
-	  ,			/* 5G, ch 100~140 */
-	  {149, 5, 20, BOTH, FALSE}
-	  ,			/* 5G, ch 149~165 */
-	  {0}
-	  ,			/* end */
-	  }
-	 }
-	,
-};
-
-static struct rt_ch_region *GetChRegion(u8 *CntryCode)
-{
-	int loop = 0;
-	struct rt_ch_region *pChRegion = NULL;
-
-	while (strcmp((char *)ChRegion[loop].CountReg, "") != 0) {
-		if (strncmp
-		    ((char *)ChRegion[loop].CountReg, (char *)CntryCode,
-		     2) == 0) {
-			pChRegion = &ChRegion[loop];
-			break;
-		}
-		loop++;
-	}
-
-	if (pChRegion == NULL)
-		pChRegion = &ChRegion[loop];
-	return pChRegion;
-}
-
-static void ChBandCheck(u8 PhyMode, u8 *pChType)
-{
-	switch (PhyMode) {
-	case PHY_11A:
-	case PHY_11AN_MIXED:
-		*pChType = BAND_5G;
-		break;
-	case PHY_11ABG_MIXED:
-	case PHY_11AGN_MIXED:
-	case PHY_11ABGN_MIXED:
-		*pChType = BAND_BOTH;
-		break;
-
-	default:
-		*pChType = BAND_24G;
-		break;
-	}
-}
-
-static u8 FillChList(struct rt_rtmp_adapter *pAd,
-			struct rt_ch_desp *pChDesp,
-			u8 Offset, u8 increment)
-{
-	int i, j, l;
-	u8 channel;
-
-	j = Offset;
-	for (i = 0; i < pChDesp->NumOfCh; i++) {
-		channel = pChDesp->FirstChannel + i * increment;
-		for (l = 0; l < MAX_NUM_OF_CHANNELS; l++) {
-			if (channel == pAd->TxPower[l].Channel) {
-				pAd->ChannelList[j].Power =
-				    pAd->TxPower[l].Power;
-				pAd->ChannelList[j].Power2 =
-				    pAd->TxPower[l].Power2;
-				break;
-			}
-		}
-		if (l == MAX_NUM_OF_CHANNELS)
-			continue;
-
-		pAd->ChannelList[j].Channel =
-		    pChDesp->FirstChannel + i * increment;
-		pAd->ChannelList[j].MaxTxPwr = pChDesp->MaxTxPwr;
-		pAd->ChannelList[j].DfsReq = pChDesp->DfsReq;
-		j++;
-	}
-	pAd->ChannelListNum = j;
-
-	return j;
-}
-
-static inline void CreateChList(struct rt_rtmp_adapter *pAd,
-				struct rt_ch_region *pChRegion, u8 Geography)
-{
-	int i;
-	u8 offset = 0;
-	struct rt_ch_desp *pChDesp;
-	u8 ChType;
-	u8 increment;
-
-	if (pChRegion == NULL)
-		return;
-
-	ChBandCheck(pAd->CommonCfg.PhyMode, &ChType);
-
-	for (i = 0; i < 10; i++) {
-		pChDesp = &pChRegion->ChDesp[i];
-		if (pChDesp->FirstChannel == 0)
-			break;
-
-		if (ChType == BAND_5G) {
-			if (pChDesp->FirstChannel <= 14)
-				continue;
-		} else if (ChType == BAND_24G) {
-			if (pChDesp->FirstChannel > 14)
-				continue;
-		}
-
-		if ((pChDesp->Geography == BOTH)
-		    || (pChDesp->Geography == Geography)) {
-			if (pChDesp->FirstChannel > 14)
-				increment = 4;
-			else
-				increment = 1;
-			offset = FillChList(pAd, pChDesp, offset, increment);
-		}
-	}
-}
-
-void BuildChannelListEx(struct rt_rtmp_adapter *pAd)
-{
-	struct rt_ch_region *pChReg;
-
-	pChReg = GetChRegion(pAd->CommonCfg.CountryCode);
-	CreateChList(pAd, pChReg, pAd->CommonCfg.Geography);
-}
-
-void BuildBeaconChList(struct rt_rtmp_adapter *pAd,
-		       u8 *pBuf, unsigned long *pBufLen)
-{
-	int i;
-	unsigned long TmpLen;
-	struct rt_ch_region *pChRegion;
-	struct rt_ch_desp *pChDesp;
-	u8 ChType;
-
-	pChRegion = GetChRegion(pAd->CommonCfg.CountryCode);
-
-	if (pChRegion == NULL)
-		return;
-
-	ChBandCheck(pAd->CommonCfg.PhyMode, &ChType);
-	*pBufLen = 0;
-
-	for (i = 0; i < 10; i++) {
-		pChDesp = &pChRegion->ChDesp[i];
-		if (pChDesp->FirstChannel == 0)
-			break;
-
-		if (ChType == BAND_5G) {
-			if (pChDesp->FirstChannel <= 14)
-				continue;
-		} else if (ChType == BAND_24G) {
-			if (pChDesp->FirstChannel > 14)
-				continue;
-		}
-
-		if ((pChDesp->Geography == BOTH)
-		    || (pChDesp->Geography == pAd->CommonCfg.Geography)) {
-			MakeOutgoingFrame(pBuf + *pBufLen, &TmpLen,
-					  1, &pChDesp->FirstChannel,
-					  1, &pChDesp->NumOfCh,
-					  1, &pChDesp->MaxTxPwr, END_OF_ARGS);
-			*pBufLen += TmpLen;
-		}
-	}
-}
-
-static BOOLEAN IsValidChannel(struct rt_rtmp_adapter *pAd, u8 channel)
-{
-	int i;
-
-	for (i = 0; i < pAd->ChannelListNum; i++) {
-		if (pAd->ChannelList[i].Channel == channel)
-			break;
-	}
-
-	if (i == pAd->ChannelListNum)
-		return FALSE;
-	else
-		return TRUE;
-}
-
-static u8 GetExtCh(u8 Channel, u8 Direction)
-{
-	char ExtCh;
-
-	if (Direction == EXTCHA_ABOVE)
-		ExtCh = Channel + 4;
-	else
-		ExtCh = (Channel - 4) > 0 ? (Channel - 4) : 0;
-
-	return ExtCh;
-}
-
-void N_ChannelCheck(struct rt_rtmp_adapter *pAd)
-{
-	/*u8 ChannelNum = pAd->ChannelListNum; */
-	u8 Channel = pAd->CommonCfg.Channel;
-
-	if ((pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED)
-	    && (pAd->CommonCfg.RegTransmitSetting.field.BW == BW_40)) {
-		if (Channel > 14) {
-			if ((Channel == 36) || (Channel == 44)
-			    || (Channel == 52) || (Channel == 60)
-			    || (Channel == 100) || (Channel == 108)
-			    || (Channel == 116) || (Channel == 124)
-			    || (Channel == 132) || (Channel == 149)
-			    || (Channel == 157)) {
-				pAd->CommonCfg.RegTransmitSetting.field.EXTCHA =
-				    EXTCHA_ABOVE;
-			} else if ((Channel == 40) || (Channel == 48)
-				   || (Channel == 56) || (Channel == 64)
-				   || (Channel == 104) || (Channel == 112)
-				   || (Channel == 120) || (Channel == 128)
-				   || (Channel == 136) || (Channel == 153)
-				   || (Channel == 161)) {
-				pAd->CommonCfg.RegTransmitSetting.field.EXTCHA =
-				    EXTCHA_BELOW;
-			} else {
-				pAd->CommonCfg.RegTransmitSetting.field.BW =
-				    BW_20;
-			}
-		} else {
-			do {
-				u8 ExtCh;
-				u8 Dir =
-				    pAd->CommonCfg.RegTransmitSetting.field.
-				    EXTCHA;
-				ExtCh = GetExtCh(Channel, Dir);
-				if (IsValidChannel(pAd, ExtCh))
-					break;
-
-				Dir =
-				    (Dir ==
-				     EXTCHA_ABOVE) ? EXTCHA_BELOW :
-				    EXTCHA_ABOVE;
-				ExtCh = GetExtCh(Channel, Dir);
-				if (IsValidChannel(pAd, ExtCh)) {
-					pAd->CommonCfg.RegTransmitSetting.field.
-					    EXTCHA = Dir;
-					break;
-				}
-				pAd->CommonCfg.RegTransmitSetting.field.BW =
-				    BW_20;
-			} while (FALSE);
-
-			if (Channel == 14) {
-				pAd->CommonCfg.RegTransmitSetting.field.BW =
-				    BW_20;
-				/*pAd->CommonCfg.RegTransmitSetting.field.EXTCHA = EXTCHA_NONE; // We didn't set the ExtCh as NONE due to it'll set in RTMPSetHT() */
-			}
-		}
-	}
-
-}
-
-void N_SetCenCh(struct rt_rtmp_adapter *pAd)
-{
-	if (pAd->CommonCfg.RegTransmitSetting.field.BW == BW_40) {
-		if (pAd->CommonCfg.RegTransmitSetting.field.EXTCHA ==
-		    EXTCHA_ABOVE) {
-			pAd->CommonCfg.CentralChannel =
-			    pAd->CommonCfg.Channel + 2;
-		} else {
-			if (pAd->CommonCfg.Channel == 14)
-				pAd->CommonCfg.CentralChannel =
-				    pAd->CommonCfg.Channel - 1;
-			else
-				pAd->CommonCfg.CentralChannel =
-				    pAd->CommonCfg.Channel - 2;
-		}
-	} else {
-		pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel;
-	}
-}
-
-u8 GetCuntryMaxTxPwr(struct rt_rtmp_adapter *pAd, u8 channel)
-{
-	int i;
-	for (i = 0; i < pAd->ChannelListNum; i++) {
-		if (pAd->ChannelList[i].Channel == channel)
-			break;
-	}
-
-	if (i == pAd->ChannelListNum)
-		return 0xff;
-	else
-		return pAd->ChannelList[i].MaxTxPwr;
-}
diff -druN linux-2.6.39-libre/drivers/staging/rt2860/common/rtmp_init.c linux-3.0-rc7-libre/drivers/staging/rt2860/common/rtmp_init.c
--- linux-2.6.39-libre/drivers/staging/rt2860/common/rtmp_init.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rt2860/common/rtmp_init.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,3536 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, 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.             *
- *                                                                       *
- *************************************************************************
-
-	Module Name:
-	rtmp_init.c
-
-	Abstract:
-	Miniport generic portion header file
-
-	Revision History:
-	Who         When          What
-	--------    ----------    ----------------------------------------------
-*/
-#include "../rt_config.h"
-
-u8 BIT8[] = { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 };
-char *CipherName[] =
-    { "none", "wep64", "wep128", "TKIP", "AES", "CKIP64", "CKIP128" };
-
-/* */
-/* BBP register initialization set */
-/* */
-struct rt_reg_pair BBPRegTable[] = {
-	{BBP_R65, 0x2C},	/* fix rssi issue */
-	{BBP_R66, 0x38},	/* Also set this default value to pAd->BbpTuning.R66CurrentValue at initial */
-	{BBP_R69, 0x12},
-	{BBP_R70, 0xa},		/* BBP_R70 will change to 0x8 in ApStartUp and LinkUp for rt2860C, otherwise value is 0xa */
-	{BBP_R73, 0x10},
-	{BBP_R81, 0x37},
-	{BBP_R82, 0x62},
-	{BBP_R83, 0x6A},
-	{BBP_R84, 0x99},	/* 0x19 is for rt2860E and after. This is for extension channel overlapping IOT. 0x99 is for rt2860D and before */
-	{BBP_R86, 0x00},	/* middle range issue, Rory @2008-01-28 */
-	{BBP_R91, 0x04},	/* middle range issue, Rory @2008-01-28 */
-	{BBP_R92, 0x00},	/* middle range issue, Rory @2008-01-28 */
-	{BBP_R103, 0x00},	/* near range high-power issue, requested from Gary @2008-0528 */
-	{BBP_R105, 0x05},	/* 0x05 is for rt2860E to turn on FEQ control. It is safe for rt2860D and before, because Bit 7:2 are reserved in rt2860D and before. */
-	{BBP_R106, 0x35},	/* for ShortGI throughput */
-};
-
-#define	NUM_BBP_REG_PARMS	(sizeof(BBPRegTable) / sizeof(struct rt_reg_pair))
-
-/* */
-/* ASIC register initialization sets */
-/* */
-
-struct rt_rtmp_reg_pair MACRegTable[] = {
-#if defined(HW_BEACON_OFFSET) && (HW_BEACON_OFFSET == 0x200)
-	{BCN_OFFSET0, 0xf8f0e8e0},	/* 0x3800(e0), 0x3A00(e8), 0x3C00(f0), 0x3E00(f8), 512B for each beacon */
-	{BCN_OFFSET1, 0x6f77d0c8},	/* 0x3200(c8), 0x3400(d0), 0x1DC0(77), 0x1BC0(6f), 512B for each beacon */
-#elif defined(HW_BEACON_OFFSET) && (HW_BEACON_OFFSET == 0x100)
-	{BCN_OFFSET0, 0xece8e4e0},	/* 0x3800, 0x3A00, 0x3C00, 0x3E00, 512B for each beacon */
-	{BCN_OFFSET1, 0xfcf8f4f0},	/* 0x3800, 0x3A00, 0x3C00, 0x3E00, 512B for each beacon */
-#else
-#error You must re-calculate new value for BCN_OFFSET0 & BCN_OFFSET1 in MACRegTable[]!
-#endif /* HW_BEACON_OFFSET // */
-
-	{LEGACY_BASIC_RATE, 0x0000013f},	/*  Basic rate set bitmap */
-	{HT_BASIC_RATE, 0x00008003},	/* Basic HT rate set , 20M, MCS=3, MM. Format is the same as in TXWI. */
-	{MAC_SYS_CTRL, 0x00},	/* 0x1004, , default Disable RX */
-	{RX_FILTR_CFG, 0x17f97},	/*0x1400  , RX filter control, */
-	{BKOFF_SLOT_CFG, 0x209},	/* default set short slot time, CC_DELAY_TIME should be 2 */
-	/*{TX_SW_CFG0,          0x40a06}, // Gary,2006-08-23 */
-	{TX_SW_CFG0, 0x0},	/* Gary,2008-05-21 for CWC test */
-	{TX_SW_CFG1, 0x80606},	/* Gary,2006-08-23 */
-	{TX_LINK_CFG, 0x1020},	/* Gary,2006-08-23 */
-	/*{TX_TIMEOUT_CFG,      0x00182090},    // CCK has some problem. So increase timieout value. 2006-10-09// MArvek RT */
-	{TX_TIMEOUT_CFG, 0x000a2090},	/* CCK has some problem. So increase timieout value. 2006-10-09// MArvek RT , Modify for 2860E ,2007-08-01 */
-	{MAX_LEN_CFG, MAX_AGGREGATION_SIZE | 0x00001000},	/* 0x3018, MAX frame length. Max PSDU = 16kbytes. */
-	{LED_CFG, 0x7f031e46},	/* Gary, 2006-08-23 */
-
-	{PBF_MAX_PCNT, 0x1F3FBF9F},	/*0x1F3f7f9f},          //Jan, 2006/04/20 */
-
-	{TX_RTY_CFG, 0x47d01f0f},	/* Jan, 2006/11/16, Set TxWI->ACK =0 in Probe Rsp Modify for 2860E ,2007-08-03 */
-
-	{AUTO_RSP_CFG, 0x00000013},	/* Initial Auto_Responder, because QA will turn off Auto-Responder */
-	{CCK_PROT_CFG, 0x05740003 /*0x01740003 */ },	/* Initial Auto_Responder, because QA will turn off Auto-Responder. And RTS threshold is enabled. */
-	{OFDM_PROT_CFG, 0x05740003 /*0x01740003 */ },	/* Initial Auto_Responder, because QA will turn off Auto-Responder. And RTS threshold is enabled. */
-#ifdef RTMP_MAC_USB
-	{PBF_CFG, 0xf40006},	/* Only enable Queue 2 */
-	{MM40_PROT_CFG, 0x3F44084},	/* Initial Auto_Responder, because QA will turn off Auto-Responder */
-	{WPDMA_GLO_CFG, 0x00000030},
-#endif /* RTMP_MAC_USB // */
-	{GF20_PROT_CFG, 0x01744004},	/* set 19:18 --> Short NAV for MIMO PS */
-	{GF40_PROT_CFG, 0x03F44084},
-	{MM20_PROT_CFG, 0x01744004},
-#ifdef RTMP_MAC_PCI
-	{MM40_PROT_CFG, 0x03F54084},
-#endif /* RTMP_MAC_PCI // */
-	{TXOP_CTRL_CFG, 0x0000583f, /*0x0000243f *//*0x000024bf */ },	/*Extension channel backoff. */
-	{TX_RTS_CFG, 0x00092b20},
-	{EXP_ACK_TIME, 0x002400ca},	/* default value */
-
-	{TXOP_HLDR_ET, 0x00000002},
-
-	/* Jerry comments 2008/01/16: we use SIFS = 10us in CCK defaultly, but it seems that 10us
-	   is too small for INTEL 2200bg card, so in MBSS mode, the delta time between beacon0
-	   and beacon1 is SIFS (10us), so if INTEL 2200bg card connects to BSS0, the ping
-	   will always lost. So we change the SIFS of CCK from 10us to 16us. */
-	{XIFS_TIME_CFG, 0x33a41010},
-	{PWR_PIN_CFG, 0x00000003},	/* patch for 2880-E */
-};
-
-struct rt_rtmp_reg_pair STAMACRegTable[] = {
-	{WMM_AIFSN_CFG, 0x00002273},
-	{WMM_CWMIN_CFG, 0x00002344},
-	{WMM_CWMAX_CFG, 0x000034aa},
-};
-
-#define	NUM_MAC_REG_PARMS		(sizeof(MACRegTable) / sizeof(struct rt_rtmp_reg_pair))
-#define	NUM_STA_MAC_REG_PARMS	(sizeof(STAMACRegTable) / sizeof(struct rt_rtmp_reg_pair))
-
-/*
-	========================================================================
-
-	Routine Description:
-		Allocate struct rt_rtmp_adapter data block and do some initialization
-
-	Arguments:
-		Adapter		Pointer to our adapter
-
-	Return Value:
-		NDIS_STATUS_SUCCESS
-		NDIS_STATUS_FAILURE
-
-	IRQL = PASSIVE_LEVEL
-
-	Note:
-
-	========================================================================
-*/
-int RTMPAllocAdapterBlock(void *handle,
-				  struct rt_rtmp_adapter * * ppAdapter)
-{
-	struct rt_rtmp_adapter *pAd;
-	int Status;
-	int index;
-	u8 *pBeaconBuf = NULL;
-
-	DBGPRINT(RT_DEBUG_TRACE, ("--> RTMPAllocAdapterBlock\n"));
-
-	*ppAdapter = NULL;
-
-	do {
-		/* Allocate struct rt_rtmp_adapter memory block */
-		pBeaconBuf = kmalloc(MAX_BEACON_SIZE, MEM_ALLOC_FLAG);
-		if (pBeaconBuf == NULL) {
-			Status = NDIS_STATUS_FAILURE;
-			DBGPRINT_ERR("Failed to allocate memory - BeaconBuf!\n");
-			break;
-		}
-		NdisZeroMemory(pBeaconBuf, MAX_BEACON_SIZE);
-
-		Status = AdapterBlockAllocateMemory(handle, (void **) & pAd);
-		if (Status != NDIS_STATUS_SUCCESS) {
-			DBGPRINT_ERR("Failed to allocate memory - ADAPTER\n");
-			break;
-		}
-		pAd->BeaconBuf = pBeaconBuf;
-		DBGPRINT(RT_DEBUG_OFF,
-			 ("=== pAd = %p, size = %d ===\n", pAd,
-			  (u32)sizeof(struct rt_rtmp_adapter)));
-
-		/* Init spin locks */
-		NdisAllocateSpinLock(&pAd->MgmtRingLock);
-#ifdef RTMP_MAC_PCI
-		NdisAllocateSpinLock(&pAd->RxRingLock);
-#ifdef RT3090
-		NdisAllocateSpinLock(&pAd->McuCmdLock);
-#endif /* RT3090 // */
-#endif /* RTMP_MAC_PCI // */
-
-		for (index = 0; index < NUM_OF_TX_RING; index++) {
-			NdisAllocateSpinLock(&pAd->TxSwQueueLock[index]);
-			NdisAllocateSpinLock(&pAd->DeQueueLock[index]);
-			pAd->DeQueueRunning[index] = FALSE;
-		}
-
-		NdisAllocateSpinLock(&pAd->irq_lock);
-
-	} while (FALSE);
-
-	if ((Status != NDIS_STATUS_SUCCESS) && (pBeaconBuf))
-		kfree(pBeaconBuf);
-
-	*ppAdapter = pAd;
-
-	DBGPRINT_S(Status, ("<-- RTMPAllocAdapterBlock, Status=%x\n", Status));
-	return Status;
-}
-
-/*
-	========================================================================
-
-	Routine Description:
-		Read initial Tx power per MCS and BW from EEPROM
-
-	Arguments:
-		Adapter						Pointer to our adapter
-
-	Return Value:
-		None
-
-	IRQL = PASSIVE_LEVEL
-
-	Note:
-
-	========================================================================
-*/
-void RTMPReadTxPwrPerRate(struct rt_rtmp_adapter *pAd)
-{
-	unsigned long data, Adata, Gdata;
-	u16 i, value, value2;
-	int Apwrdelta, Gpwrdelta;
-	u8 t1, t2, t3, t4;
-	BOOLEAN bApwrdeltaMinus = TRUE, bGpwrdeltaMinus = TRUE;
-
-	/* */
-	/* Get power delta for 20MHz and 40MHz. */
-	/* */
-	DBGPRINT(RT_DEBUG_TRACE, ("Txpower per Rate\n"));
-	RT28xx_EEPROM_READ16(pAd, EEPROM_TXPOWER_DELTA, value2);
-	Apwrdelta = 0;
-	Gpwrdelta = 0;
-
-	if ((value2 & 0xff) != 0xff) {
-		if ((value2 & 0x80))
-			Gpwrdelta = (value2 & 0xf);
-
-		if ((value2 & 0x40))
-			bGpwrdeltaMinus = FALSE;
-		else
-			bGpwrdeltaMinus = TRUE;
-	}
-	if ((value2 & 0xff00) != 0xff00) {
-		if ((value2 & 0x8000))
-			Apwrdelta = ((value2 & 0xf00) >> 8);
-
-		if ((value2 & 0x4000))
-			bApwrdeltaMinus = FALSE;
-		else
-			bApwrdeltaMinus = TRUE;
-	}
-	DBGPRINT(RT_DEBUG_TRACE,
-		 ("Gpwrdelta = %x, Apwrdelta = %x .\n", Gpwrdelta, Apwrdelta));
-
-	/* */
-	/* Get Txpower per MCS for 20MHz in 2.4G. */
-	/* */
-	for (i = 0; i < 5; i++) {
-		RT28xx_EEPROM_READ16(pAd,
-				     EEPROM_TXPOWER_BYRATE_20MHZ_2_4G + i * 4,
-				     value);
-		data = value;
-		if (bApwrdeltaMinus == FALSE) {
-			t1 = (value & 0xf) + (Apwrdelta);
-			if (t1 > 0xf)
-				t1 = 0xf;
-			t2 = ((value & 0xf0) >> 4) + (Apwrdelta);
-			if (t2 > 0xf)
-				t2 = 0xf;
-			t3 = ((value & 0xf00) >> 8) + (Apwrdelta);
-			if (t3 > 0xf)
-				t3 = 0xf;
-			t4 = ((value & 0xf000) >> 12) + (Apwrdelta);
-			if (t4 > 0xf)
-				t4 = 0xf;
-		} else {
-			if ((value & 0xf) > Apwrdelta)
-				t1 = (value & 0xf) - (Apwrdelta);
-			else
-				t1 = 0;
-			if (((value & 0xf0) >> 4) > Apwrdelta)
-				t2 = ((value & 0xf0) >> 4) - (Apwrdelta);
-			else
-				t2 = 0;
-			if (((value & 0xf00) >> 8) > Apwrdelta)
-				t3 = ((value & 0xf00) >> 8) - (Apwrdelta);
-			else
-				t3 = 0;
-			if (((value & 0xf000) >> 12) > Apwrdelta)
-				t4 = ((value & 0xf000) >> 12) - (Apwrdelta);
-			else
-				t4 = 0;
-		}
-		Adata = t1 + (t2 << 4) + (t3 << 8) + (t4 << 12);
-		if (bGpwrdeltaMinus == FALSE) {
-			t1 = (value & 0xf) + (Gpwrdelta);
-			if (t1 > 0xf)
-				t1 = 0xf;
-			t2 = ((value & 0xf0) >> 4) + (Gpwrdelta);
-			if (t2 > 0xf)
-				t2 = 0xf;
-			t3 = ((value & 0xf00) >> 8) + (Gpwrdelta);
-			if (t3 > 0xf)
-				t3 = 0xf;
-			t4 = ((value & 0xf000) >> 12) + (Gpwrdelta);
-			if (t4 > 0xf)
-				t4 = 0xf;
-		} else {
-			if ((value & 0xf) > Gpwrdelta)
-				t1 = (value & 0xf) - (Gpwrdelta);
-			else
-				t1 = 0;
-			if (((value & 0xf0) >> 4) > Gpwrdelta)
-				t2 = ((value & 0xf0) >> 4) - (Gpwrdelta);
-			else
-				t2 = 0;
-			if (((value & 0xf00) >> 8) > Gpwrdelta)
-				t3 = ((value & 0xf00) >> 8) - (Gpwrdelta);
-			else
-				t3 = 0;
-			if (((value & 0xf000) >> 12) > Gpwrdelta)
-				t4 = ((value & 0xf000) >> 12) - (Gpwrdelta);
-			else
-				t4 = 0;
-		}
-		Gdata = t1 + (t2 << 4) + (t3 << 8) + (t4 << 12);
-
-		RT28xx_EEPROM_READ16(pAd,
-				     EEPROM_TXPOWER_BYRATE_20MHZ_2_4G + i * 4 +
-				     2, value);
-		if (bApwrdeltaMinus == FALSE) {
-			t1 = (value & 0xf) + (Apwrdelta);
-			if (t1 > 0xf)
-				t1 = 0xf;
-			t2 = ((value & 0xf0) >> 4) + (Apwrdelta);
-			if (t2 > 0xf)
-				t2 = 0xf;
-			t3 = ((value & 0xf00) >> 8) + (Apwrdelta);
-			if (t3 > 0xf)
-				t3 = 0xf;
-			t4 = ((value & 0xf000) >> 12) + (Apwrdelta);
-			if (t4 > 0xf)
-				t4 = 0xf;
-		} else {
-			if ((value & 0xf) > Apwrdelta)
-				t1 = (value & 0xf) - (Apwrdelta);
-			else
-				t1 = 0;
-			if (((value & 0xf0) >> 4) > Apwrdelta)
-				t2 = ((value & 0xf0) >> 4) - (Apwrdelta);
-			else
-				t2 = 0;
-			if (((value & 0xf00) >> 8) > Apwrdelta)
-				t3 = ((value & 0xf00) >> 8) - (Apwrdelta);
-			else
-				t3 = 0;
-			if (((value & 0xf000) >> 12) > Apwrdelta)
-				t4 = ((value & 0xf000) >> 12) - (Apwrdelta);
-			else
-				t4 = 0;
-		}
-		Adata |= ((t1 << 16) + (t2 << 20) + (t3 << 24) + (t4 << 28));
-		if (bGpwrdeltaMinus == FALSE) {
-			t1 = (value & 0xf) + (Gpwrdelta);
-			if (t1 > 0xf)
-				t1 = 0xf;
-			t2 = ((value & 0xf0) >> 4) + (Gpwrdelta);
-			if (t2 > 0xf)
-				t2 = 0xf;
-			t3 = ((value & 0xf00) >> 8) + (Gpwrdelta);
-			if (t3 > 0xf)
-				t3 = 0xf;
-			t4 = ((value & 0xf000) >> 12) + (Gpwrdelta);
-			if (t4 > 0xf)
-				t4 = 0xf;
-		} else {
-			if ((value & 0xf) > Gpwrdelta)
-				t1 = (value & 0xf) - (Gpwrdelta);
-			else
-				t1 = 0;
-			if (((value & 0xf0) >> 4) > Gpwrdelta)
-				t2 = ((value & 0xf0) >> 4) - (Gpwrdelta);
-			else
-				t2 = 0;
-			if (((value & 0xf00) >> 8) > Gpwrdelta)
-				t3 = ((value & 0xf00) >> 8) - (Gpwrdelta);
-			else
-				t3 = 0;
-			if (((value & 0xf000) >> 12) > Gpwrdelta)
-				t4 = ((value & 0xf000) >> 12) - (Gpwrdelta);
-			else
-				t4 = 0;
-		}
-		Gdata |= ((t1 << 16) + (t2 << 20) + (t3 << 24) + (t4 << 28));
-		data |= (value << 16);
-
-		/* For 20M/40M Power Delta issue */
-		pAd->Tx20MPwrCfgABand[i] = data;
-		pAd->Tx20MPwrCfgGBand[i] = data;
-		pAd->Tx40MPwrCfgABand[i] = Adata;
-		pAd->Tx40MPwrCfgGBand[i] = Gdata;
-
-		if (data != 0xffffffff)
-			RTMP_IO_WRITE32(pAd, TX_PWR_CFG_0 + i * 4, data);
-		DBGPRINT_RAW(RT_DEBUG_TRACE,
-			     ("20MHz BW, 2.4G band-%lx,  Adata = %lx,  Gdata = %lx \n",
-			      data, Adata, Gdata));
-	}
-}
-
-/*
-	========================================================================
-
-	Routine Description:
-		Read initial channel power parameters from EEPROM
-
-	Arguments:
-		Adapter						Pointer to our adapter
-
-	Return Value:
-		None
-
-	IRQL = PASSIVE_LEVEL
-
-	Note:
-
-	========================================================================
-*/
-void RTMPReadChannelPwr(struct rt_rtmp_adapter *pAd)
-{
-	u8 i, choffset;
-	EEPROM_TX_PWR_STRUC Power;
-	EEPROM_TX_PWR_STRUC Power2;
-
-	/* Read Tx power value for all channels */
-	/* Value from 1 - 0x7f. Default value is 24. */
-	/* Power value : 2.4G 0x00 (0) ~ 0x1F (31) */
-	/*             : 5.5G 0xF9 (-7) ~ 0x0F (15) */
-
-	/* 0. 11b/g, ch1 - ch 14 */
-	for (i = 0; i < 7; i++) {
-		RT28xx_EEPROM_READ16(pAd, EEPROM_G_TX_PWR_OFFSET + i * 2,
-				     Power.word);
-		RT28xx_EEPROM_READ16(pAd, EEPROM_G_TX2_PWR_OFFSET + i * 2,
-				     Power2.word);
-		pAd->TxPower[i * 2].Channel = i * 2 + 1;
-		pAd->TxPower[i * 2 + 1].Channel = i * 2 + 2;
-
-		if ((Power.field.Byte0 > 31) || (Power.field.Byte0 < 0))
-			pAd->TxPower[i * 2].Power = DEFAULT_RF_TX_POWER;
-		else
-			pAd->TxPower[i * 2].Power = Power.field.Byte0;
-
-		if ((Power.field.Byte1 > 31) || (Power.field.Byte1 < 0))
-			pAd->TxPower[i * 2 + 1].Power = DEFAULT_RF_TX_POWER;
-		else
-			pAd->TxPower[i * 2 + 1].Power = Power.field.Byte1;
-
-		if ((Power2.field.Byte0 > 31) || (Power2.field.Byte0 < 0))
-			pAd->TxPower[i * 2].Power2 = DEFAULT_RF_TX_POWER;
-		else
-			pAd->TxPower[i * 2].Power2 = Power2.field.Byte0;
-
-		if ((Power2.field.Byte1 > 31) || (Power2.field.Byte1 < 0))
-			pAd->TxPower[i * 2 + 1].Power2 = DEFAULT_RF_TX_POWER;
-		else
-			pAd->TxPower[i * 2 + 1].Power2 = Power2.field.Byte1;
-	}
-
-	/* 1. U-NII lower/middle band: 36, 38, 40; 44, 46, 48; 52, 54, 56; 60, 62, 64 (including central frequency in BW 40MHz) */
-	/* 1.1 Fill up channel */
-	choffset = 14;
-	for (i = 0; i < 4; i++) {
-		pAd->TxPower[3 * i + choffset + 0].Channel = 36 + i * 8 + 0;
-		pAd->TxPower[3 * i + choffset + 0].Power = DEFAULT_RF_TX_POWER;
-		pAd->TxPower[3 * i + choffset + 0].Power2 = DEFAULT_RF_TX_POWER;
-
-		pAd->TxPower[3 * i + choffset + 1].Channel = 36 + i * 8 + 2;
-		pAd->TxPower[3 * i + choffset + 1].Power = DEFAULT_RF_TX_POWER;
-		pAd->TxPower[3 * i + choffset + 1].Power2 = DEFAULT_RF_TX_POWER;
-
-		pAd->TxPower[3 * i + choffset + 2].Channel = 36 + i * 8 + 4;
-		pAd->TxPower[3 * i + choffset + 2].Power = DEFAULT_RF_TX_POWER;
-		pAd->TxPower[3 * i + choffset + 2].Power2 = DEFAULT_RF_TX_POWER;
-	}
-
-	/* 1.2 Fill up power */
-	for (i = 0; i < 6; i++) {
-		RT28xx_EEPROM_READ16(pAd, EEPROM_A_TX_PWR_OFFSET + i * 2,
-				     Power.word);
-		RT28xx_EEPROM_READ16(pAd, EEPROM_A_TX2_PWR_OFFSET + i * 2,
-				     Power2.word);
-
-		if ((Power.field.Byte0 < 16) && (Power.field.Byte0 >= -7))
-			pAd->TxPower[i * 2 + choffset + 0].Power =
-			    Power.field.Byte0;
-
-		if ((Power.field.Byte1 < 16) && (Power.field.Byte1 >= -7))
-			pAd->TxPower[i * 2 + choffset + 1].Power =
-			    Power.field.Byte1;
-
-		if ((Power2.field.Byte0 < 16) && (Power2.field.Byte0 >= -7))
-			pAd->TxPower[i * 2 + choffset + 0].Power2 =
-			    Power2.field.Byte0;
-
-		if ((Power2.field.Byte1 < 16) && (Power2.field.Byte1 >= -7))
-			pAd->TxPower[i * 2 + choffset + 1].Power2 =
-			    Power2.field.Byte1;
-	}
-
-	/* 2. HipperLAN 2 100, 102 ,104; 108, 110, 112; 116, 118, 120; 124, 126, 128; 132, 134, 136; 140 (including central frequency in BW 40MHz) */
-	/* 2.1 Fill up channel */
-	choffset = 14 + 12;
-	for (i = 0; i < 5; i++) {
-		pAd->TxPower[3 * i + choffset + 0].Channel = 100 + i * 8 + 0;
-		pAd->TxPower[3 * i + choffset + 0].Power = DEFAULT_RF_TX_POWER;
-		pAd->TxPower[3 * i + choffset + 0].Power2 = DEFAULT_RF_TX_POWER;
-
-		pAd->TxPower[3 * i + choffset + 1].Channel = 100 + i * 8 + 2;
-		pAd->TxPower[3 * i + choffset + 1].Power = DEFAULT_RF_TX_POWER;
-		pAd->TxPower[3 * i + choffset + 1].Power2 = DEFAULT_RF_TX_POWER;
-
-		pAd->TxPower[3 * i + choffset + 2].Channel = 100 + i * 8 + 4;
-		pAd->TxPower[3 * i + choffset + 2].Power = DEFAULT_RF_TX_POWER;
-		pAd->TxPower[3 * i + choffset + 2].Power2 = DEFAULT_RF_TX_POWER;
-	}
-	pAd->TxPower[3 * 5 + choffset + 0].Channel = 140;
-	pAd->TxPower[3 * 5 + choffset + 0].Power = DEFAULT_RF_TX_POWER;
-	pAd->TxPower[3 * 5 + choffset + 0].Power2 = DEFAULT_RF_TX_POWER;
-
-	/* 2.2 Fill up power */
-	for (i = 0; i < 8; i++) {
-		RT28xx_EEPROM_READ16(pAd,
-				     EEPROM_A_TX_PWR_OFFSET + (choffset - 14) +
-				     i * 2, Power.word);
-		RT28xx_EEPROM_READ16(pAd,
-				     EEPROM_A_TX2_PWR_OFFSET + (choffset - 14) +
-				     i * 2, Power2.word);
-
-		if ((Power.field.Byte0 < 16) && (Power.field.Byte0 >= -7))
-			pAd->TxPower[i * 2 + choffset + 0].Power =
-			    Power.field.Byte0;
-
-		if ((Power.field.Byte1 < 16) && (Power.field.Byte1 >= -7))
-			pAd->TxPower[i * 2 + choffset + 1].Power =
-			    Power.field.Byte1;
-
-		if ((Power2.field.Byte0 < 16) && (Power2.field.Byte0 >= -7))
-			pAd->TxPower[i * 2 + choffset + 0].Power2 =
-			    Power2.field.Byte0;
-
-		if ((Power2.field.Byte1 < 16) && (Power2.field.Byte1 >= -7))
-			pAd->TxPower[i * 2 + choffset + 1].Power2 =
-			    Power2.field.Byte1;
-	}
-
-	/* 3. U-NII upper band: 149, 151, 153; 157, 159, 161; 165, 167, 169; 171, 173 (including central frequency in BW 40MHz) */
-	/* 3.1 Fill up channel */
-	choffset = 14 + 12 + 16;
-	/*for (i = 0; i < 2; i++) */
-	for (i = 0; i < 3; i++) {
-		pAd->TxPower[3 * i + choffset + 0].Channel = 149 + i * 8 + 0;
-		pAd->TxPower[3 * i + choffset + 0].Power = DEFAULT_RF_TX_POWER;
-		pAd->TxPower[3 * i + choffset + 0].Power2 = DEFAULT_RF_TX_POWER;
-
-		pAd->TxPower[3 * i + choffset + 1].Channel = 149 + i * 8 + 2;
-		pAd->TxPower[3 * i + choffset + 1].Power = DEFAULT_RF_TX_POWER;
-		pAd->TxPower[3 * i + choffset + 1].Power2 = DEFAULT_RF_TX_POWER;
-
-		pAd->TxPower[3 * i + choffset + 2].Channel = 149 + i * 8 + 4;
-		pAd->TxPower[3 * i + choffset + 2].Power = DEFAULT_RF_TX_POWER;
-		pAd->TxPower[3 * i + choffset + 2].Power2 = DEFAULT_RF_TX_POWER;
-	}
-	pAd->TxPower[3 * 3 + choffset + 0].Channel = 171;
-	pAd->TxPower[3 * 3 + choffset + 0].Power = DEFAULT_RF_TX_POWER;
-	pAd->TxPower[3 * 3 + choffset + 0].Power2 = DEFAULT_RF_TX_POWER;
-
-	pAd->TxPower[3 * 3 + choffset + 1].Channel = 173;
-	pAd->TxPower[3 * 3 + choffset + 1].Power = DEFAULT_RF_TX_POWER;
-	pAd->TxPower[3 * 3 + choffset + 1].Power2 = DEFAULT_RF_TX_POWER;
-
-	/* 3.2 Fill up power */
-	/*for (i = 0; i < 4; i++) */
-	for (i = 0; i < 6; i++) {
-		RT28xx_EEPROM_READ16(pAd,
-				     EEPROM_A_TX_PWR_OFFSET + (choffset - 14) +
-				     i * 2, Power.word);
-		RT28xx_EEPROM_READ16(pAd,
-				     EEPROM_A_TX2_PWR_OFFSET + (choffset - 14) +
-				     i * 2, Power2.word);
-
-		if ((Power.field.Byte0 < 16) && (Power.field.Byte0 >= -7))
-			pAd->TxPower[i * 2 + choffset + 0].Power =
-			    Power.field.Byte0;
-
-		if ((Power.field.Byte1 < 16) && (Power.field.Byte1 >= -7))
-			pAd->TxPower[i * 2 + choffset + 1].Power =
-			    Power.field.Byte1;
-
-		if ((Power2.field.Byte0 < 16) && (Power2.field.Byte0 >= -7))
-			pAd->TxPower[i * 2 + choffset + 0].Power2 =
-			    Power2.field.Byte0;
-
-		if ((Power2.field.Byte1 < 16) && (Power2.field.Byte1 >= -7))
-			pAd->TxPower[i * 2 + choffset + 1].Power2 =
-			    Power2.field.Byte1;
-	}
-
-	/* 4. Print and Debug */
-	/*choffset = 14 + 12 + 16 + 7; */
-	choffset = 14 + 12 + 16 + 11;
-
-}
-
-/*
-	========================================================================
-
-	Routine Description:
-		Read the following from the registry
-		1. All the parameters
-		2. NetworkAddres
-
-	Arguments:
-		Adapter						Pointer to our adapter
-		WrapperConfigurationContext	For use by NdisOpenConfiguration
-
-	Return Value:
-		NDIS_STATUS_SUCCESS
-		NDIS_STATUS_FAILURE
-		NDIS_STATUS_RESOURCES
-
-	IRQL = PASSIVE_LEVEL
-
-	Note:
-
-	========================================================================
-*/
-int NICReadRegParameters(struct rt_rtmp_adapter *pAd,
-				 void *WrapperConfigurationContext)
-{
-	int Status = NDIS_STATUS_SUCCESS;
-	DBGPRINT_S(Status, ("<-- NICReadRegParameters, Status=%x\n", Status));
-	return Status;
-}
-
-/*
-	========================================================================
-
-	Routine Description:
-		Read initial parameters from EEPROM
-
-	Arguments:
-		Adapter						Pointer to our adapter
-
-	Return Value:
-		None
-
-	IRQL = PASSIVE_LEVEL
-
-	Note:
-
-	========================================================================
-*/
-void NICReadEEPROMParameters(struct rt_rtmp_adapter *pAd, u8 *mac_addr)
-{
-	u32 data = 0;
-	u16 i, value, value2;
-	u8 TmpPhy;
-	EEPROM_TX_PWR_STRUC Power;
-	EEPROM_VERSION_STRUC Version;
-	EEPROM_ANTENNA_STRUC Antenna;
-	EEPROM_NIC_CONFIG2_STRUC NicConfig2;
-
-	DBGPRINT(RT_DEBUG_TRACE, ("--> NICReadEEPROMParameters\n"));
-
-	if (pAd->chipOps.eeinit)
-		pAd->chipOps.eeinit(pAd);
-
-	/* Init EEPROM Address Number, before access EEPROM; if 93c46, EEPROMAddressNum=6, else if 93c66, EEPROMAddressNum=8 */
-	RTMP_IO_READ32(pAd, E2PROM_CSR, &data);
-	DBGPRINT(RT_DEBUG_TRACE, ("--> E2PROM_CSR = 0x%x\n", data));
-
-	if ((data & 0x30) == 0)
-		pAd->EEPROMAddressNum = 6;	/* 93C46 */
-	else if ((data & 0x30) == 0x10)
-		pAd->EEPROMAddressNum = 8;	/* 93C66 */
-	else
-		pAd->EEPROMAddressNum = 8;	/* 93C86 */
-	DBGPRINT(RT_DEBUG_TRACE,
-		 ("--> EEPROMAddressNum = %d\n", pAd->EEPROMAddressNum));
-
-	/* RT2860 MAC no longer auto load MAC address from E2PROM. Driver has to initialize */
-	/* MAC address registers according to E2PROM setting */
-	if (mac_addr == NULL ||
-	    strlen((char *)mac_addr) != 17 ||
-	    mac_addr[2] != ':' || mac_addr[5] != ':' || mac_addr[8] != ':' ||
-	    mac_addr[11] != ':' || mac_addr[14] != ':') {
-		u16 Addr01, Addr23, Addr45;
-
-		RT28xx_EEPROM_READ16(pAd, 0x04, Addr01);
-		RT28xx_EEPROM_READ16(pAd, 0x06, Addr23);
-		RT28xx_EEPROM_READ16(pAd, 0x08, Addr45);
-
-		pAd->PermanentAddress[0] = (u8)(Addr01 & 0xff);
-		pAd->PermanentAddress[1] = (u8)(Addr01 >> 8);
-		pAd->PermanentAddress[2] = (u8)(Addr23 & 0xff);
-		pAd->PermanentAddress[3] = (u8)(Addr23 >> 8);
-		pAd->PermanentAddress[4] = (u8)(Addr45 & 0xff);
-		pAd->PermanentAddress[5] = (u8)(Addr45 >> 8);
-
-		DBGPRINT(RT_DEBUG_TRACE,
-			 ("Initialize MAC Address from E2PROM \n"));
-	} else {
-		int j;
-		char *macptr;
-
-		macptr = (char *)mac_addr;
-
-		for (j = 0; j < MAC_ADDR_LEN; j++) {
-			AtoH(macptr, &pAd->PermanentAddress[j], 1);
-			macptr = macptr + 3;
-		}
-
-		DBGPRINT(RT_DEBUG_TRACE,
-			 ("Initialize MAC Address from module parameter \n"));
-	}
-
-	{
-		/*more conveninet to test mbssid, so ap's bssid &0xf1 */
-		if (pAd->PermanentAddress[0] == 0xff)
-			pAd->PermanentAddress[0] = RandomByte(pAd) & 0xf8;
-
-		/*if (pAd->PermanentAddress[5] == 0xff) */
-		/*      pAd->PermanentAddress[5] = RandomByte(pAd)&0xf8; */
-
-		DBGPRINT_RAW(RT_DEBUG_TRACE,
-			("E2PROM MAC: =%pM\n", pAd->PermanentAddress));
-		if (pAd->bLocalAdminMAC == FALSE) {
-			MAC_DW0_STRUC csr2;
-			MAC_DW1_STRUC csr3;
-			COPY_MAC_ADDR(pAd->CurrentAddress,
-				      pAd->PermanentAddress);
-			csr2.field.Byte0 = pAd->CurrentAddress[0];
-			csr2.field.Byte1 = pAd->CurrentAddress[1];
-			csr2.field.Byte2 = pAd->CurrentAddress[2];
-			csr2.field.Byte3 = pAd->CurrentAddress[3];
-			RTMP_IO_WRITE32(pAd, MAC_ADDR_DW0, csr2.word);
-			csr3.word = 0;
-			csr3.field.Byte4 = pAd->CurrentAddress[4];
-			csr3.field.Byte5 = pAd->CurrentAddress[5];
-			csr3.field.U2MeMask = 0xff;
-			RTMP_IO_WRITE32(pAd, MAC_ADDR_DW1, csr3.word);
-			DBGPRINT_RAW(RT_DEBUG_TRACE,
-				("E2PROM MAC: =%pM\n",
-					pAd->PermanentAddress));
-		}
-	}
-
-	/* if not return early. cause fail at emulation. */
-	/* Init the channel number for TX channel power */
-	RTMPReadChannelPwr(pAd);
-
-	/* if E2PROM version mismatch with driver's expectation, then skip */
-	/* all subsequent E2RPOM retieval and set a system error bit to notify GUI */
-	RT28xx_EEPROM_READ16(pAd, EEPROM_VERSION_OFFSET, Version.word);
-	pAd->EepromVersion =
-	    Version.field.Version + Version.field.FaeReleaseNumber * 256;
-	DBGPRINT(RT_DEBUG_TRACE,
-		 ("E2PROM: Version = %d, FAE release #%d\n",
-		  Version.field.Version, Version.field.FaeReleaseNumber));
-
-	if (Version.field.Version > VALID_EEPROM_VERSION) {
-		DBGPRINT_ERR("E2PROM: WRONG VERSION 0x%x, should be %d\n", Version.field.Version, VALID_EEPROM_VERSION);
-		/*pAd->SystemErrorBitmap |= 0x00000001;
-
-		   // hard-code default value when no proper E2PROM installed
-		   pAd->bAutoTxAgcA = FALSE;
-		   pAd->bAutoTxAgcG = FALSE;
-
-		   // Default the channel power
-		   for (i = 0; i < MAX_NUM_OF_CHANNELS; i++)
-		   pAd->TxPower[i].Power = DEFAULT_RF_TX_POWER;
-
-		   // Default the channel power
-		   for (i = 0; i < MAX_NUM_OF_11JCHANNELS; i++)
-		   pAd->TxPower11J[i].Power = DEFAULT_RF_TX_POWER;
-
-		   for(i = 0; i < NUM_EEPROM_BBP_PARMS; i++)
-		   pAd->EEPROMDefaultValue[i] = 0xffff;
-		   return;  */
-	}
-	/* Read BBP default value from EEPROM and store to array(EEPROMDefaultValue) in pAd */
-	RT28xx_EEPROM_READ16(pAd, EEPROM_NIC1_OFFSET, value);
-	pAd->EEPROMDefaultValue[0] = value;
-
-	RT28xx_EEPROM_READ16(pAd, EEPROM_NIC2_OFFSET, value);
-	pAd->EEPROMDefaultValue[1] = value;
-
-	RT28xx_EEPROM_READ16(pAd, 0x38, value);	/* Country Region */
-	pAd->EEPROMDefaultValue[2] = value;
-
-	for (i = 0; i < 8; i++) {
-		RT28xx_EEPROM_READ16(pAd, EEPROM_BBP_BASE_OFFSET + i * 2,
-				     value);
-		pAd->EEPROMDefaultValue[i + 3] = value;
-	}
-
-	/* We have to parse NIC configuration 0 at here. */
-	/* If TSSI did not have preloaded value, it should reset the TxAutoAgc to false */
-	/* Therefore, we have to read TxAutoAgc control beforehand. */
-	/* Read Tx AGC control bit */
-	Antenna.word = pAd->EEPROMDefaultValue[0];
-	if (Antenna.word == 0xFFFF) {
-#ifdef RT30xx
-		if (IS_RT3090(pAd) || IS_RT3390(pAd)) {
-			Antenna.word = 0;
-			Antenna.field.RfIcType = RFIC_3020;
-			Antenna.field.TxPath = 1;
-			Antenna.field.RxPath = 1;
-		} else
-#endif /* RT30xx // */
-		{
-
-			Antenna.word = 0;
-			Antenna.field.RfIcType = RFIC_2820;
-			Antenna.field.TxPath = 1;
-			Antenna.field.RxPath = 2;
-			DBGPRINT(RT_DEBUG_WARN,
-				 ("E2PROM error, hard code as 0x%04x\n",
-				  Antenna.word));
-		}
-	}
-	/* Choose the desired Tx&Rx stream. */
-	if ((pAd->CommonCfg.TxStream == 0)
-	    || (pAd->CommonCfg.TxStream > Antenna.field.TxPath))
-		pAd->CommonCfg.TxStream = Antenna.field.TxPath;
-
-	if ((pAd->CommonCfg.RxStream == 0)
-	    || (pAd->CommonCfg.RxStream > Antenna.field.RxPath)) {
-		pAd->CommonCfg.RxStream = Antenna.field.RxPath;
-
-		if ((pAd->MACVersion < RALINK_2883_VERSION) &&
-		    (pAd->CommonCfg.RxStream > 2)) {
-			/* only 2 Rx streams for RT2860 series */
-			pAd->CommonCfg.RxStream = 2;
-		}
-	}
-	/* 3*3 */
-	/* read value from EEPROM and set them to CSR174 ~ 177 in chain0 ~ chain2 */
-	/* yet implement */
-	for (i = 0; i < 3; i++) {
-	}
-
-	NicConfig2.word = pAd->EEPROMDefaultValue[1];
-
-	{
-		if ((NicConfig2.word & 0x00ff) == 0xff) {
-			NicConfig2.word &= 0xff00;
-		}
-
-		if ((NicConfig2.word >> 8) == 0xff) {
-			NicConfig2.word &= 0x00ff;
-		}
-	}
-
-	if (NicConfig2.field.DynamicTxAgcControl == 1)
-		pAd->bAutoTxAgcA = pAd->bAutoTxAgcG = TRUE;
-	else
-		pAd->bAutoTxAgcA = pAd->bAutoTxAgcG = FALSE;
-
-	DBGPRINT_RAW(RT_DEBUG_TRACE,
-		     ("NICReadEEPROMParameters: RxPath = %d, TxPath = %d\n",
-		      Antenna.field.RxPath, Antenna.field.TxPath));
-
-	/* Save the antenna for future use */
-	pAd->Antenna.word = Antenna.word;
-
-	/* Set the RfICType here, then we can initialize RFIC related operation callbacks */
-	pAd->Mlme.RealRxPath = (u8)Antenna.field.RxPath;
-	pAd->RfIcType = (u8)Antenna.field.RfIcType;
-
-#ifdef RTMP_RF_RW_SUPPORT
-	RtmpChipOpsRFHook(pAd);
-#endif /* RTMP_RF_RW_SUPPORT // */
-
-#ifdef RTMP_MAC_PCI
-	sprintf((char *)pAd->nickname, "RT2860STA");
-#endif /* RTMP_MAC_PCI // */
-
-	/* */
-	/* Reset PhyMode if we don't support 802.11a */
-	/* Only RFIC_2850 & RFIC_2750 support 802.11a */
-	/* */
-	if ((Antenna.field.RfIcType != RFIC_2850)
-	    && (Antenna.field.RfIcType != RFIC_2750)
-	    && (Antenna.field.RfIcType != RFIC_3052)) {
-		if ((pAd->CommonCfg.PhyMode == PHY_11ABG_MIXED) ||
-		    (pAd->CommonCfg.PhyMode == PHY_11A))
-			pAd->CommonCfg.PhyMode = PHY_11BG_MIXED;
-		else if ((pAd->CommonCfg.PhyMode == PHY_11ABGN_MIXED) ||
-			 (pAd->CommonCfg.PhyMode == PHY_11AN_MIXED) ||
-			 (pAd->CommonCfg.PhyMode == PHY_11AGN_MIXED) ||
-			 (pAd->CommonCfg.PhyMode == PHY_11N_5G))
-			pAd->CommonCfg.PhyMode = PHY_11BGN_MIXED;
-	}
-	/* Read TSSI reference and TSSI boundary for temperature compensation. This is ugly */
-	/* 0. 11b/g */
-	{
-		/* these are tempature reference value (0x00 ~ 0xFE)
-		   ex: 0x00 0x15 0x25 0x45 0x88 0xA0 0xB5 0xD0 0xF0
-		   TssiPlusBoundaryG [4] [3] [2] [1] [0] (smaller) +
-		   TssiMinusBoundaryG[0] [1] [2] [3] [4] (larger) */
-		RT28xx_EEPROM_READ16(pAd, 0x6E, Power.word);
-		pAd->TssiMinusBoundaryG[4] = Power.field.Byte0;
-		pAd->TssiMinusBoundaryG[3] = Power.field.Byte1;
-		RT28xx_EEPROM_READ16(pAd, 0x70, Power.word);
-		pAd->TssiMinusBoundaryG[2] = Power.field.Byte0;
-		pAd->TssiMinusBoundaryG[1] = Power.field.Byte1;
-		RT28xx_EEPROM_READ16(pAd, 0x72, Power.word);
-		pAd->TssiRefG = Power.field.Byte0;	/* reference value [0] */
-		pAd->TssiPlusBoundaryG[1] = Power.field.Byte1;
-		RT28xx_EEPROM_READ16(pAd, 0x74, Power.word);
-		pAd->TssiPlusBoundaryG[2] = Power.field.Byte0;
-		pAd->TssiPlusBoundaryG[3] = Power.field.Byte1;
-		RT28xx_EEPROM_READ16(pAd, 0x76, Power.word);
-		pAd->TssiPlusBoundaryG[4] = Power.field.Byte0;
-		pAd->TxAgcStepG = Power.field.Byte1;
-		pAd->TxAgcCompensateG = 0;
-		pAd->TssiMinusBoundaryG[0] = pAd->TssiRefG;
-		pAd->TssiPlusBoundaryG[0] = pAd->TssiRefG;
-
-		/* Disable TxAgc if the based value is not right */
-		if (pAd->TssiRefG == 0xff)
-			pAd->bAutoTxAgcG = FALSE;
-
-		DBGPRINT(RT_DEBUG_TRACE,
-			 ("E2PROM: G Tssi[-4 .. +4] = %d %d %d %d - %d -%d %d %d %d, step=%d, tuning=%d\n",
-			  pAd->TssiMinusBoundaryG[4],
-			  pAd->TssiMinusBoundaryG[3],
-			  pAd->TssiMinusBoundaryG[2],
-			  pAd->TssiMinusBoundaryG[1], pAd->TssiRefG,
-			  pAd->TssiPlusBoundaryG[1], pAd->TssiPlusBoundaryG[2],
-			  pAd->TssiPlusBoundaryG[3], pAd->TssiPlusBoundaryG[4],
-			  pAd->TxAgcStepG, pAd->bAutoTxAgcG));
-	}
-	/* 1. 11a */
-	{
-		RT28xx_EEPROM_READ16(pAd, 0xD4, Power.word);
-		pAd->TssiMinusBoundaryA[4] = Power.field.Byte0;
-		pAd->TssiMinusBoundaryA[3] = Power.field.Byte1;
-		RT28xx_EEPROM_READ16(pAd, 0xD6, Power.word);
-		pAd->TssiMinusBoundaryA[2] = Power.field.Byte0;
-		pAd->TssiMinusBoundaryA[1] = Power.field.Byte1;
-		RT28xx_EEPROM_READ16(pAd, 0xD8, Power.word);
-		pAd->TssiRefA = Power.field.Byte0;
-		pAd->TssiPlusBoundaryA[1] = Power.field.Byte1;
-		RT28xx_EEPROM_READ16(pAd, 0xDA, Power.word);
-		pAd->TssiPlusBoundaryA[2] = Power.field.Byte0;
-		pAd->TssiPlusBoundaryA[3] = Power.field.Byte1;
-		RT28xx_EEPROM_READ16(pAd, 0xDC, Power.word);
-		pAd->TssiPlusBoundaryA[4] = Power.field.Byte0;
-		pAd->TxAgcStepA = Power.field.Byte1;
-		pAd->TxAgcCompensateA = 0;
-		pAd->TssiMinusBoundaryA[0] = pAd->TssiRefA;
-		pAd->TssiPlusBoundaryA[0] = pAd->TssiRefA;
-
-		/* Disable TxAgc if the based value is not right */
-		if (pAd->TssiRefA == 0xff)
-			pAd->bAutoTxAgcA = FALSE;
-
-		DBGPRINT(RT_DEBUG_TRACE,
-			 ("E2PROM: A Tssi[-4 .. +4] = %d %d %d %d - %d -%d %d %d %d, step=%d, tuning=%d\n",
-			  pAd->TssiMinusBoundaryA[4],
-			  pAd->TssiMinusBoundaryA[3],
-			  pAd->TssiMinusBoundaryA[2],
-			  pAd->TssiMinusBoundaryA[1], pAd->TssiRefA,
-			  pAd->TssiPlusBoundaryA[1], pAd->TssiPlusBoundaryA[2],
-			  pAd->TssiPlusBoundaryA[3], pAd->TssiPlusBoundaryA[4],
-			  pAd->TxAgcStepA, pAd->bAutoTxAgcA));
-	}
-	pAd->BbpRssiToDbmDelta = 0x0;
-
-	/* Read frequency offset setting for RF */
-	RT28xx_EEPROM_READ16(pAd, EEPROM_FREQ_OFFSET, value);
-	if ((value & 0x00FF) != 0x00FF)
-		pAd->RfFreqOffset = (unsigned long)(value & 0x00FF);
-	else
-		pAd->RfFreqOffset = 0;
-	DBGPRINT(RT_DEBUG_TRACE,
-		 ("E2PROM: RF FreqOffset=0x%lx \n", pAd->RfFreqOffset));
-
-	/*CountryRegion byte offset (38h) */
-	value = pAd->EEPROMDefaultValue[2] >> 8;	/* 2.4G band */
-	value2 = pAd->EEPROMDefaultValue[2] & 0x00FF;	/* 5G band */
-
-	if ((value <= REGION_MAXIMUM_BG_BAND)
-	    && (value2 <= REGION_MAXIMUM_A_BAND)) {
-		pAd->CommonCfg.CountryRegion = ((u8)value) | 0x80;
-		pAd->CommonCfg.CountryRegionForABand = ((u8)value2) | 0x80;
-		TmpPhy = pAd->CommonCfg.PhyMode;
-		pAd->CommonCfg.PhyMode = 0xff;
-		RTMPSetPhyMode(pAd, TmpPhy);
-		SetCommonHT(pAd);
-	}
-	/* */
-	/* Get RSSI Offset on EEPROM 0x9Ah & 0x9Ch. */
-	/* The valid value are (-10 ~ 10) */
-	/* */
-	RT28xx_EEPROM_READ16(pAd, EEPROM_RSSI_BG_OFFSET, value);
-	pAd->BGRssiOffset0 = value & 0x00ff;
-	pAd->BGRssiOffset1 = (value >> 8);
-	RT28xx_EEPROM_READ16(pAd, EEPROM_RSSI_BG_OFFSET + 2, value);
-	pAd->BGRssiOffset2 = value & 0x00ff;
-	pAd->ALNAGain1 = (value >> 8);
-	RT28xx_EEPROM_READ16(pAd, EEPROM_LNA_OFFSET, value);
-	pAd->BLNAGain = value & 0x00ff;
-	pAd->ALNAGain0 = (value >> 8);
-
-	/* Validate 11b/g RSSI_0 offset. */
-	if ((pAd->BGRssiOffset0 < -10) || (pAd->BGRssiOffset0 > 10))
-		pAd->BGRssiOffset0 = 0;
-
-	/* Validate 11b/g RSSI_1 offset. */
-	if ((pAd->BGRssiOffset1 < -10) || (pAd->BGRssiOffset1 > 10))
-		pAd->BGRssiOffset1 = 0;
-
-	/* Validate 11b/g RSSI_2 offset. */
-	if ((pAd->BGRssiOffset2 < -10) || (pAd->BGRssiOffset2 > 10))
-		pAd->BGRssiOffset2 = 0;
-
-	RT28xx_EEPROM_READ16(pAd, EEPROM_RSSI_A_OFFSET, value);
-	pAd->ARssiOffset0 = value & 0x00ff;
-	pAd->ARssiOffset1 = (value >> 8);
-	RT28xx_EEPROM_READ16(pAd, (EEPROM_RSSI_A_OFFSET + 2), value);
-	pAd->ARssiOffset2 = value & 0x00ff;
-	pAd->ALNAGain2 = (value >> 8);
-
-	if (((u8)pAd->ALNAGain1 == 0xFF) || (pAd->ALNAGain1 == 0x00))
-		pAd->ALNAGain1 = pAd->ALNAGain0;
-	if (((u8)pAd->ALNAGain2 == 0xFF) || (pAd->ALNAGain2 == 0x00))
-		pAd->ALNAGain2 = pAd->ALNAGain0;
-
-	/* Validate 11a RSSI_0 offset. */
-	if ((pAd->ARssiOffset0 < -10) || (pAd->ARssiOffset0 > 10))
-		pAd->ARssiOffset0 = 0;
-
-	/* Validate 11a RSSI_1 offset. */
-	if ((pAd->ARssiOffset1 < -10) || (pAd->ARssiOffset1 > 10))
-		pAd->ARssiOffset1 = 0;
-
-	/*Validate 11a RSSI_2 offset. */
-	if ((pAd->ARssiOffset2 < -10) || (pAd->ARssiOffset2 > 10))
-		pAd->ARssiOffset2 = 0;
-
-#ifdef RT30xx
-	/* */
-	/* Get TX mixer gain setting */
-	/* 0xff are invalid value */
-	/* Note: RT30xX default value is 0x00 and will program to RF_R17 only when this value is not zero. */
-	/*       RT359X default value is 0x02 */
-	/* */
-	if (IS_RT30xx(pAd) || IS_RT3572(pAd)) {
-		RT28xx_EEPROM_READ16(pAd, EEPROM_TXMIXER_GAIN_2_4G, value);
-		pAd->TxMixerGain24G = 0;
-		value &= 0x00ff;
-		if (value != 0xff) {
-			value &= 0x07;
-			pAd->TxMixerGain24G = (u8)value;
-		}
-	}
-#endif /* RT30xx // */
-
-	/* */
-	/* Get LED Setting. */
-	/* */
-	RT28xx_EEPROM_READ16(pAd, 0x3a, value);
-	pAd->LedCntl.word = (value >> 8);
-	RT28xx_EEPROM_READ16(pAd, EEPROM_LED1_OFFSET, value);
-	pAd->Led1 = value;
-	RT28xx_EEPROM_READ16(pAd, EEPROM_LED2_OFFSET, value);
-	pAd->Led2 = value;
-	RT28xx_EEPROM_READ16(pAd, EEPROM_LED3_OFFSET, value);
-	pAd->Led3 = value;
-
-	RTMPReadTxPwrPerRate(pAd);
-
-#ifdef RT30xx
-#ifdef RTMP_EFUSE_SUPPORT
-	RtmpEfuseSupportCheck(pAd);
-#endif /* RTMP_EFUSE_SUPPORT // */
-#endif /* RT30xx // */
-
-	DBGPRINT(RT_DEBUG_TRACE, ("<-- NICReadEEPROMParameters\n"));
-}
-
-/*
-	========================================================================
-
-	Routine Description:
-		Set default value from EEPROM
-
-	Arguments:
-		Adapter						Pointer to our adapter
-
-	Return Value:
-		None
-
-	IRQL = PASSIVE_LEVEL
-
-	Note:
-
-	========================================================================
-*/
-void NICInitAsicFromEEPROM(struct rt_rtmp_adapter *pAd)
-{
-	u32 data = 0;
-	u8 BBPR1 = 0;
-	u16 i;
-/*      EEPROM_ANTENNA_STRUC    Antenna; */
-	EEPROM_NIC_CONFIG2_STRUC NicConfig2;
-	u8 BBPR3 = 0;
-
-	DBGPRINT(RT_DEBUG_TRACE, ("--> NICInitAsicFromEEPROM\n"));
-	for (i = 3; i < NUM_EEPROM_BBP_PARMS; i++) {
-		u8 BbpRegIdx, BbpValue;
-
-		if ((pAd->EEPROMDefaultValue[i] != 0xFFFF)
-		    && (pAd->EEPROMDefaultValue[i] != 0)) {
-			BbpRegIdx = (u8)(pAd->EEPROMDefaultValue[i] >> 8);
-			BbpValue = (u8)(pAd->EEPROMDefaultValue[i] & 0xff);
-			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BbpRegIdx, BbpValue);
-		}
-	}
-
-	NicConfig2.word = pAd->EEPROMDefaultValue[1];
-
-	{
-		if ((NicConfig2.word & 0x00ff) == 0xff) {
-			NicConfig2.word &= 0xff00;
-		}
-
-		if ((NicConfig2.word >> 8) == 0xff) {
-			NicConfig2.word &= 0x00ff;
-		}
-	}
-
-	/* Save the antenna for future use */
-	pAd->NicConfig2.word = NicConfig2.word;
-
-#ifdef RT30xx
-	/* set default antenna as main */
-	if (pAd->RfIcType == RFIC_3020)
-		AsicSetRxAnt(pAd, pAd->RxAnt.Pair1PrimaryRxAnt);
-#endif /* RT30xx // */
-
-	/* */
-	/* Send LED Setting to MCU. */
-	/* */
-	if (pAd->LedCntl.word == 0xFF) {
-		pAd->LedCntl.word = 0x01;
-		pAd->Led1 = 0x5555;
-		pAd->Led2 = 0x2221;
-
-#ifdef RTMP_MAC_PCI
-		pAd->Led3 = 0xA9F8;
-#endif /* RTMP_MAC_PCI // */
-#ifdef RTMP_MAC_USB
-		pAd->Led3 = 0x5627;
-#endif /* RTMP_MAC_USB // */
-	}
-
-	AsicSendCommandToMcu(pAd, 0x52, 0xff, (u8)pAd->Led1,
-			     (u8)(pAd->Led1 >> 8));
-	AsicSendCommandToMcu(pAd, 0x53, 0xff, (u8)pAd->Led2,
-			     (u8)(pAd->Led2 >> 8));
-	AsicSendCommandToMcu(pAd, 0x54, 0xff, (u8)pAd->Led3,
-			     (u8)(pAd->Led3 >> 8));
-	AsicSendCommandToMcu(pAd, 0x51, 0xff, 0, pAd->LedCntl.field.Polarity);
-
-	pAd->LedIndicatorStrength = 0xFF;
-	RTMPSetSignalLED(pAd, -100);	/* Force signal strength Led to be turned off, before link up */
-
-	{
-		/* Read Hardware controlled Radio state enable bit */
-		if (NicConfig2.field.HardwareRadioControl == 1) {
-			pAd->StaCfg.bHardwareRadio = TRUE;
-
-			/* Read GPIO pin2 as Hardware controlled radio state */
-			RTMP_IO_READ32(pAd, GPIO_CTRL_CFG, &data);
-			if ((data & 0x04) == 0) {
-				pAd->StaCfg.bHwRadio = FALSE;
-				pAd->StaCfg.bRadio = FALSE;
-/*                              RTMP_IO_WRITE32(pAd, PWR_PIN_CFG, 0x00001818); */
-				RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF);
-			}
-		} else
-			pAd->StaCfg.bHardwareRadio = FALSE;
-
-		if (pAd->StaCfg.bRadio == FALSE) {
-			RTMPSetLED(pAd, LED_RADIO_OFF);
-		} else {
-			RTMPSetLED(pAd, LED_RADIO_ON);
-#ifdef RTMP_MAC_PCI
-#ifdef RT3090
-			AsicSendCommandToMcu(pAd, 0x30, PowerRadioOffCID, 0xff,
-					     0x02);
-			AsicCheckCommanOk(pAd, PowerRadioOffCID);
-#endif /* RT3090 // */
-#ifndef RT3090
-			AsicSendCommandToMcu(pAd, 0x30, 0xff, 0xff, 0x02);
-#endif /* RT3090 // */
-			AsicSendCommandToMcu(pAd, 0x31, PowerWakeCID, 0x00,
-					     0x00);
-			/* 2-1. wait command ok. */
-			AsicCheckCommanOk(pAd, PowerWakeCID);
-#endif /* RTMP_MAC_PCI // */
-		}
-	}
-
-#ifdef RTMP_MAC_PCI
-#ifdef RT30xx
-	if (IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd)) {
-		struct rt_rtmp_chip_op *pChipOps = &pAd->chipOps;
-		if (pChipOps->AsicReverseRfFromSleepMode)
-			pChipOps->AsicReverseRfFromSleepMode(pAd);
-	}
-	/* 3090 MCU Wakeup command needs more time to be stable. */
-	/* Before stable, don't issue other MCU command to prevent from firmware error. */
-
-	if ((IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd))
-	    && IS_VERSION_AFTER_F(pAd)
-	    && (pAd->StaCfg.PSControl.field.rt30xxPowerMode == 3)
-	    && (pAd->StaCfg.PSControl.field.EnableNewPS == TRUE)) {
-		DBGPRINT(RT_DEBUG_TRACE, ("%s, release Mcu Lock\n", __func__));
-		RTMP_SEM_LOCK(&pAd->McuCmdLock);
-		pAd->brt30xxBanMcuCmd = FALSE;
-		RTMP_SEM_UNLOCK(&pAd->McuCmdLock);
-	}
-#endif /* RT30xx // */
-#endif /* RTMP_MAC_PCI // */
-
-	/* Turn off patching for cardbus controller */
-	if (NicConfig2.field.CardbusAcceleration == 1) {
-/*              pAd->bTest1 = TRUE; */
-	}
-
-	if (NicConfig2.field.DynamicTxAgcControl == 1)
-		pAd->bAutoTxAgcA = pAd->bAutoTxAgcG = TRUE;
-	else
-		pAd->bAutoTxAgcA = pAd->bAutoTxAgcG = FALSE;
-	/* */
-	/* Since BBP has been progamed, to make sure BBP setting will be */
-	/* upate inside of AsicAntennaSelect, so reset to UNKNOWN_BAND! */
-	/* */
-	pAd->CommonCfg.BandState = UNKNOWN_BAND;
-
-	RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &BBPR3);
-	BBPR3 &= (~0x18);
-	if (pAd->Antenna.field.RxPath == 3) {
-		BBPR3 |= (0x10);
-	} else if (pAd->Antenna.field.RxPath == 2) {
-		BBPR3 |= (0x8);
-	} else if (pAd->Antenna.field.RxPath == 1) {
-		BBPR3 |= (0x0);
-	}
-	RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, BBPR3);
-
-	{
-		/* Handle the difference when 1T */
-		RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R1, &BBPR1);
-		if (pAd->Antenna.field.TxPath == 1) {
-			BBPR1 &= (~0x18);
-		}
-		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R1, BBPR1);
-
-		DBGPRINT(RT_DEBUG_TRACE,
-			 ("Use Hw Radio Control Pin=%d; if used Pin=%d;\n",
-			  pAd->CommonCfg.bHardwareRadio,
-			  pAd->CommonCfg.bHardwareRadio));
-	}
-
-#ifdef RTMP_MAC_USB
-#ifdef RT30xx
-	/* update registers from EEPROM for RT3071 or later(3572/3592). */
-
-	if (IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd)) {
-		u8 RegIdx, RegValue;
-		u16 value;
-
-		/* after RT3071, write BBP from EEPROM 0xF0 to 0x102 */
-		for (i = 0xF0; i <= 0x102; i = i + 2) {
-			value = 0xFFFF;
-			RT28xx_EEPROM_READ16(pAd, i, value);
-			if ((value != 0xFFFF) && (value != 0)) {
-				RegIdx = (u8)(value >> 8);
-				RegValue = (u8)(value & 0xff);
-				RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, RegIdx,
-							     RegValue);
-				DBGPRINT(RT_DEBUG_TRACE,
-					 ("Update BBP Registers from EEPROM(0x%0x), BBP(0x%x) = 0x%x\n",
-					  i, RegIdx, RegValue));
-			}
-		}
-
-		/* after RT3071, write RF from EEPROM 0x104 to 0x116 */
-		for (i = 0x104; i <= 0x116; i = i + 2) {
-			value = 0xFFFF;
-			RT28xx_EEPROM_READ16(pAd, i, value);
-			if ((value != 0xFFFF) && (value != 0)) {
-				RegIdx = (u8)(value >> 8);
-				RegValue = (u8)(value & 0xff);
-				RT30xxWriteRFRegister(pAd, RegIdx, RegValue);
-				DBGPRINT(RT_DEBUG_TRACE,
-					 ("Update RF Registers from EEPROM0x%x), BBP(0x%x) = 0x%x\n",
-					  i, RegIdx, RegValue));
-			}
-		}
-	}
-#endif /* RT30xx // */
-#endif /* RTMP_MAC_USB // */
-
-	DBGPRINT(RT_DEBUG_TRACE,
-		 ("TxPath = %d, RxPath = %d, RFIC=%d, Polar+LED mode=%x\n",
-		  pAd->Antenna.field.TxPath, pAd->Antenna.field.RxPath,
-		  pAd->RfIcType, pAd->LedCntl.word));
-	DBGPRINT(RT_DEBUG_TRACE, ("<-- NICInitAsicFromEEPROM\n"));
-}
-
-/*
-	========================================================================
-
-	Routine Description:
-		Initialize NIC hardware
-
-	Arguments:
-		Adapter						Pointer to our adapter
-
-	Return Value:
-		None
-
-	IRQL = PASSIVE_LEVEL
-
-	Note:
-
-	========================================================================
-*/
-int NICInitializeAdapter(struct rt_rtmp_adapter *pAd, IN BOOLEAN bHardReset)
-{
-	int Status = NDIS_STATUS_SUCCESS;
-	WPDMA_GLO_CFG_STRUC GloCfg;
-#ifdef RTMP_MAC_PCI
-	u32 Value;
-	DELAY_INT_CFG_STRUC IntCfg;
-#endif /* RTMP_MAC_PCI // */
-/*      INT_MASK_CSR_STRUC              IntMask; */
-	unsigned long i = 0, j = 0;
-	AC_TXOP_CSR0_STRUC csr0;
-
-	DBGPRINT(RT_DEBUG_TRACE, ("--> NICInitializeAdapter\n"));
-
-	/* 3. Set DMA global configuration except TX_DMA_EN and RX_DMA_EN bits: */
-retry:
-	i = 0;
-	do {
-		RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &GloCfg.word);
-		if ((GloCfg.field.TxDMABusy == 0)
-		    && (GloCfg.field.RxDMABusy == 0))
-			break;
-
-		RTMPusecDelay(1000);
-		i++;
-	} while (i < 100);
-	DBGPRINT(RT_DEBUG_TRACE,
-		 ("<== DMA offset 0x208 = 0x%x\n", GloCfg.word));
-	GloCfg.word &= 0xff0;
-	GloCfg.field.EnTXWriteBackDDONE = 1;
-	RTMP_IO_WRITE32(pAd, WPDMA_GLO_CFG, GloCfg.word);
-
-	/* Record HW Beacon offset */
-	pAd->BeaconOffset[0] = HW_BEACON_BASE0;
-	pAd->BeaconOffset[1] = HW_BEACON_BASE1;
-	pAd->BeaconOffset[2] = HW_BEACON_BASE2;
-	pAd->BeaconOffset[3] = HW_BEACON_BASE3;
-	pAd->BeaconOffset[4] = HW_BEACON_BASE4;
-	pAd->BeaconOffset[5] = HW_BEACON_BASE5;
-	pAd->BeaconOffset[6] = HW_BEACON_BASE6;
-	pAd->BeaconOffset[7] = HW_BEACON_BASE7;
-
-	/* */
-	/* write all shared Ring's base address into ASIC */
-	/* */
-
-	/* asic simulation sequence put this ahead before loading firmware. */
-	/* pbf hardware reset */
-#ifdef RTMP_MAC_PCI
-	RTMP_IO_WRITE32(pAd, WPDMA_RST_IDX, 0x1003f);	/* 0x10000 for reset rx, 0x3f resets all 6 tx rings. */
-	RTMP_IO_WRITE32(pAd, PBF_SYS_CTRL, 0xe1f);
-	RTMP_IO_WRITE32(pAd, PBF_SYS_CTRL, 0xe00);
-#endif /* RTMP_MAC_PCI // */
-
-	/* Initialze ASIC for TX & Rx operation */
-	if (NICInitializeAsic(pAd, bHardReset) != NDIS_STATUS_SUCCESS) {
-		if (j++ == 0) {
-			NICLoadFirmware(pAd);
-			goto retry;
-		}
-		return NDIS_STATUS_FAILURE;
-	}
-
-#ifdef RTMP_MAC_PCI
-	/* Write AC_BK base address register */
-	Value =
-	    RTMP_GetPhysicalAddressLow(pAd->TxRing[QID_AC_BK].Cell[0].AllocPa);
-	RTMP_IO_WRITE32(pAd, TX_BASE_PTR1, Value);
-	DBGPRINT(RT_DEBUG_TRACE, ("--> TX_BASE_PTR1 : 0x%x\n", Value));
-
-	/* Write AC_BE base address register */
-	Value =
-	    RTMP_GetPhysicalAddressLow(pAd->TxRing[QID_AC_BE].Cell[0].AllocPa);
-	RTMP_IO_WRITE32(pAd, TX_BASE_PTR0, Value);
-	DBGPRINT(RT_DEBUG_TRACE, ("--> TX_BASE_PTR0 : 0x%x\n", Value));
-
-	/* Write AC_VI base address register */
-	Value =
-	    RTMP_GetPhysicalAddressLow(pAd->TxRing[QID_AC_VI].Cell[0].AllocPa);
-	RTMP_IO_WRITE32(pAd, TX_BASE_PTR2, Value);
-	DBGPRINT(RT_DEBUG_TRACE, ("--> TX_BASE_PTR2 : 0x%x\n", Value));
-
-	/* Write AC_VO base address register */
-	Value =
-	    RTMP_GetPhysicalAddressLow(pAd->TxRing[QID_AC_VO].Cell[0].AllocPa);
-	RTMP_IO_WRITE32(pAd, TX_BASE_PTR3, Value);
-	DBGPRINT(RT_DEBUG_TRACE, ("--> TX_BASE_PTR3 : 0x%x\n", Value));
-
-	/* Write MGMT_BASE_CSR register */
-	Value = RTMP_GetPhysicalAddressLow(pAd->MgmtRing.Cell[0].AllocPa);
-	RTMP_IO_WRITE32(pAd, TX_BASE_PTR5, Value);
-	DBGPRINT(RT_DEBUG_TRACE, ("--> TX_BASE_PTR5 : 0x%x\n", Value));
-
-	/* Write RX_BASE_CSR register */
-	Value = RTMP_GetPhysicalAddressLow(pAd->RxRing.Cell[0].AllocPa);
-	RTMP_IO_WRITE32(pAd, RX_BASE_PTR, Value);
-	DBGPRINT(RT_DEBUG_TRACE, ("--> RX_BASE_PTR : 0x%x\n", Value));
-
-	/* Init RX Ring index pointer */
-	pAd->RxRing.RxSwReadIdx = 0;
-	pAd->RxRing.RxCpuIdx = RX_RING_SIZE - 1;
-	RTMP_IO_WRITE32(pAd, RX_CRX_IDX, pAd->RxRing.RxCpuIdx);
-
-	/* Init TX rings index pointer */
-	{
-		for (i = 0; i < NUM_OF_TX_RING; i++) {
-			pAd->TxRing[i].TxSwFreeIdx = 0;
-			pAd->TxRing[i].TxCpuIdx = 0;
-			RTMP_IO_WRITE32(pAd, (TX_CTX_IDX0 + i * 0x10),
-					pAd->TxRing[i].TxCpuIdx);
-		}
-	}
-
-	/* init MGMT ring index pointer */
-	pAd->MgmtRing.TxSwFreeIdx = 0;
-	pAd->MgmtRing.TxCpuIdx = 0;
-	RTMP_IO_WRITE32(pAd, TX_MGMTCTX_IDX, pAd->MgmtRing.TxCpuIdx);
-
-	/* */
-	/* set each Ring's SIZE  into ASIC. Descriptor Size is fixed by design. */
-	/* */
-
-	/* Write TX_RING_CSR0 register */
-	Value = TX_RING_SIZE;
-	RTMP_IO_WRITE32(pAd, TX_MAX_CNT0, Value);
-	RTMP_IO_WRITE32(pAd, TX_MAX_CNT1, Value);
-	RTMP_IO_WRITE32(pAd, TX_MAX_CNT2, Value);
-	RTMP_IO_WRITE32(pAd, TX_MAX_CNT3, Value);
-	RTMP_IO_WRITE32(pAd, TX_MAX_CNT4, Value);
-	Value = MGMT_RING_SIZE;
-	RTMP_IO_WRITE32(pAd, TX_MGMTMAX_CNT, Value);
-
-	/* Write RX_RING_CSR register */
-	Value = RX_RING_SIZE;
-	RTMP_IO_WRITE32(pAd, RX_MAX_CNT, Value);
-#endif /* RTMP_MAC_PCI // */
-
-	/* WMM parameter */
-	csr0.word = 0;
-	RTMP_IO_WRITE32(pAd, WMM_TXOP0_CFG, csr0.word);
-	if (pAd->CommonCfg.PhyMode == PHY_11B) {
-		csr0.field.Ac0Txop = 192;	/* AC_VI: 192*32us ~= 6ms */
-		csr0.field.Ac1Txop = 96;	/* AC_VO: 96*32us  ~= 3ms */
-	} else {
-		csr0.field.Ac0Txop = 96;	/* AC_VI: 96*32us ~= 3ms */
-		csr0.field.Ac1Txop = 48;	/* AC_VO: 48*32us ~= 1.5ms */
-	}
-	RTMP_IO_WRITE32(pAd, WMM_TXOP1_CFG, csr0.word);
-
-#ifdef RTMP_MAC_PCI
-	/* 3. Set DMA global configuration except TX_DMA_EN and RX_DMA_EN bits: */
-	i = 0;
-	do {
-		RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &GloCfg.word);
-		if ((GloCfg.field.TxDMABusy == 0)
-		    && (GloCfg.field.RxDMABusy == 0))
-			break;
-
-		RTMPusecDelay(1000);
-		i++;
-	} while (i < 100);
-
-	GloCfg.word &= 0xff0;
-	GloCfg.field.EnTXWriteBackDDONE = 1;
-	RTMP_IO_WRITE32(pAd, WPDMA_GLO_CFG, GloCfg.word);
-
-	IntCfg.word = 0;
-	RTMP_IO_WRITE32(pAd, DELAY_INT_CFG, IntCfg.word);
-#endif /* RTMP_MAC_PCI // */
-
-	/* reset action */
-	/* Load firmware */
-	/*  Status = NICLoadFirmware(pAd); */
-
-	DBGPRINT(RT_DEBUG_TRACE, ("<-- NICInitializeAdapter\n"));
-	return Status;
-}
-
-/*
-	========================================================================
-
-	Routine Description:
-		Initialize ASIC
-
-	Arguments:
-		Adapter						Pointer to our adapter
-
-	Return Value:
-		None
-
-	IRQL = PASSIVE_LEVEL
-
-	Note:
-
-	========================================================================
-*/
-int NICInitializeAsic(struct rt_rtmp_adapter *pAd, IN BOOLEAN bHardReset)
-{
-	unsigned long Index = 0;
-	u8 R0 = 0xff;
-	u32 MacCsr12 = 0, Counter = 0;
-#ifdef RTMP_MAC_USB
-	u32 MacCsr0 = 0;
-	int Status;
-	u8 Value = 0xff;
-#endif /* RTMP_MAC_USB // */
-#ifdef RT30xx
-	u8 bbpreg = 0;
-	u8 RFValue = 0;
-#endif /* RT30xx // */
-	u16 KeyIdx;
-	int i, apidx;
-
-	DBGPRINT(RT_DEBUG_TRACE, ("--> NICInitializeAsic\n"));
-
-#ifdef RTMP_MAC_PCI
-	RTMP_IO_WRITE32(pAd, PWR_PIN_CFG, 0x3);	/* To fix driver disable/enable hang issue when radio off */
-	if (bHardReset == TRUE) {
-		RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x3);
-	} else
-		RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x1);
-
-	RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x0);
-	/* Initialize MAC register to default value */
-	for (Index = 0; Index < NUM_MAC_REG_PARMS; Index++) {
-		RTMP_IO_WRITE32(pAd, MACRegTable[Index].Register,
-				MACRegTable[Index].Value);
-	}
-
-	{
-		for (Index = 0; Index < NUM_STA_MAC_REG_PARMS; Index++) {
-			RTMP_IO_WRITE32(pAd, STAMACRegTable[Index].Register,
-					STAMACRegTable[Index].Value);
-		}
-	}
-#endif /* RTMP_MAC_PCI // */
-#ifdef RTMP_MAC_USB
-	/* */
-	/* Make sure MAC gets ready after NICLoadFirmware(). */
-	/* */
-	Index = 0;
-
-	/*To avoid hang-on issue when interface up in kernel 2.4, */
-	/*we use a local variable "MacCsr0" instead of using "pAd->MACVersion" directly. */
-	do {
-		RTMP_IO_READ32(pAd, MAC_CSR0, &MacCsr0);
-
-		if ((MacCsr0 != 0x00) && (MacCsr0 != 0xFFFFFFFF))
-			break;
-
-		RTMPusecDelay(10);
-	} while (Index++ < 100);
-
-	pAd->MACVersion = MacCsr0;
-	DBGPRINT(RT_DEBUG_TRACE,
-		 ("MAC_CSR0  [ Ver:Rev=0x%08x]\n", pAd->MACVersion));
-	/* turn on bit13 (set to zero) after rt2860D. This is to solve high-current issue. */
-	RTMP_IO_READ32(pAd, PBF_SYS_CTRL, &MacCsr12);
-	MacCsr12 &= (~0x2000);
-	RTMP_IO_WRITE32(pAd, PBF_SYS_CTRL, MacCsr12);
-
-	RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x3);
-	RTMP_IO_WRITE32(pAd, USB_DMA_CFG, 0x0);
-	Status = RTUSBVenderReset(pAd);
-
-	RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x0);
-
-	/* Initialize MAC register to default value */
-	for (Index = 0; Index < NUM_MAC_REG_PARMS; Index++) {
-#ifdef RT30xx
-		if ((MACRegTable[Index].Register == TX_SW_CFG0)
-		    && (IS_RT3070(pAd) || IS_RT3071(pAd) || IS_RT3572(pAd)
-			|| IS_RT3090(pAd) || IS_RT3390(pAd))) {
-			MACRegTable[Index].Value = 0x00000400;
-		}
-#endif /* RT30xx // */
-		RTMP_IO_WRITE32(pAd, (u16)MACRegTable[Index].Register,
-				MACRegTable[Index].Value);
-	}
-
-	{
-		for (Index = 0; Index < NUM_STA_MAC_REG_PARMS; Index++) {
-			RTMP_IO_WRITE32(pAd,
-					(u16)STAMACRegTable[Index].Register,
-					STAMACRegTable[Index].Value);
-		}
-	}
-#endif /* RTMP_MAC_USB // */
-
-#ifdef RT30xx
-	/* Initialize RT3070 serial MAC registers which is different from RT2870 serial */
-	if (IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd)) {
-		RTMP_IO_WRITE32(pAd, TX_SW_CFG1, 0);
-
-		/* RT3071 version E has fixed this issue */
-		if ((pAd->MACVersion & 0xffff) < 0x0211) {
-			if (pAd->NicConfig2.field.DACTestBit == 1) {
-				RTMP_IO_WRITE32(pAd, TX_SW_CFG2, 0x2C);	/* To fix throughput drop drastically */
-			} else {
-				RTMP_IO_WRITE32(pAd, TX_SW_CFG2, 0x0F);	/* To fix throughput drop drastically */
-			}
-		} else {
-			RTMP_IO_WRITE32(pAd, TX_SW_CFG2, 0x0);
-		}
-	} else if (IS_RT3070(pAd)) {
-		if (((pAd->MACVersion & 0xffff) < 0x0201)) {
-			RTMP_IO_WRITE32(pAd, TX_SW_CFG1, 0);
-			RTMP_IO_WRITE32(pAd, TX_SW_CFG2, 0x2C);	/* To fix throughput drop drastically */
-		} else {
-			RTMP_IO_WRITE32(pAd, TX_SW_CFG2, 0);
-		}
-	}
-#endif /* RT30xx // */
-
-	/* */
-	/* Before program BBP, we need to wait BBP/RF get wake up. */
-	/* */
-	Index = 0;
-	do {
-		RTMP_IO_READ32(pAd, MAC_STATUS_CFG, &MacCsr12);
-
-		if ((MacCsr12 & 0x03) == 0)	/* if BB.RF is stable */
-			break;
-
-		DBGPRINT(RT_DEBUG_TRACE,
-			 ("Check MAC_STATUS_CFG  = Busy = %x\n", MacCsr12));
-		RTMPusecDelay(1000);
-	} while (Index++ < 100);
-
-	/* The commands to firmware should be after these commands, these commands will init firmware */
-	/* PCI and USB are not the same because PCI driver needs to wait for PCI bus ready */
-	RTMP_IO_WRITE32(pAd, H2M_BBP_AGENT, 0);	/* initialize BBP R/W access agent */
-	RTMP_IO_WRITE32(pAd, H2M_MAILBOX_CSR, 0);
-#ifdef RT3090
-	/*2008/11/28:KH add to fix the dead rf frequency offset bug<-- */
-	AsicSendCommandToMcu(pAd, 0x72, 0, 0, 0);
-	/*2008/11/28:KH add to fix the dead rf frequency offset bug--> */
-#endif /* RT3090 // */
-	RTMPusecDelay(1000);
-
-	/* Read BBP register, make sure BBP is up and running before write new data */
-	Index = 0;
-	do {
-		RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R0, &R0);
-		DBGPRINT(RT_DEBUG_TRACE, ("BBP version = %x\n", R0));
-	} while ((++Index < 20) && ((R0 == 0xff) || (R0 == 0x00)));
-	/*ASSERT(Index < 20); //this will cause BSOD on Check-build driver */
-
-	if ((R0 == 0xff) || (R0 == 0x00))
-		return NDIS_STATUS_FAILURE;
-
-	/* Initialize BBP register to default value */
-	for (Index = 0; Index < NUM_BBP_REG_PARMS; Index++) {
-		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBPRegTable[Index].Register,
-					     BBPRegTable[Index].Value);
-	}
-
-#ifdef RTMP_MAC_PCI
-	/* TODO: shiang, check MACVersion, currently, rbus-based chip use this. */
-	if (pAd->MACVersion == 0x28720200) {
-		/*u8 value; */
-		unsigned long value2;
-
-		/*disable MLD by Bruce 20080704 */
-		/*BBP_IO_READ8_BY_REG_ID(pAd, BBP_R105, &value); */
-		/*BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R105, value | 4); */
-
-		/*Maximum PSDU length from 16K to 32K bytes */
-		RTMP_IO_READ32(pAd, MAX_LEN_CFG, &value2);
-		value2 &= ~(0x3 << 12);
-		value2 |= (0x2 << 12);
-		RTMP_IO_WRITE32(pAd, MAX_LEN_CFG, value2);
-	}
-#endif /* RTMP_MAC_PCI // */
-
-	/* for rt2860E and after, init BBP_R84 with 0x19. This is for extension channel overlapping IOT. */
-	/* RT3090 should not program BBP R84 to 0x19, otherwise TX will block. */
-	/*3070/71/72,3090,3090A( are included in RT30xx),3572,3390 */
-	if (((pAd->MACVersion & 0xffff) != 0x0101)
-	    && !(IS_RT30xx(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd)))
-		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R84, 0x19);
-
-#ifdef RT30xx
-/* add by johnli, RF power sequence setup */
-	if (IS_RT30xx(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd)) {	/*update for RT3070/71/72/90/91/92,3572,3390. */
-		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R79, 0x13);
-		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R80, 0x05);
-		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R81, 0x33);
-	}
-
-	if (IS_RT3090(pAd) || IS_RT3390(pAd))	/* RT309x, RT3071/72 */
-	{
-		/* enable DC filter */
-		if ((pAd->MACVersion & 0xffff) >= 0x0211) {
-			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R103, 0xc0);
-		}
-		/* improve power consumption */
-		RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R138, &bbpreg);
-		if (pAd->Antenna.field.TxPath == 1) {
-			/* turn off tx DAC_1 */
-			bbpreg = (bbpreg | 0x20);
-		}
-
-		if (pAd->Antenna.field.RxPath == 1) {
-			/* turn off tx ADC_1 */
-			bbpreg &= (~0x2);
-		}
-		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R138, bbpreg);
-
-		/* improve power consumption in RT3071 Ver.E */
-		if ((pAd->MACVersion & 0xffff) >= 0x0211) {
-			RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R31, &bbpreg);
-			bbpreg &= (~0x3);
-			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R31, bbpreg);
-		}
-	} else if (IS_RT3070(pAd)) {
-		if ((pAd->MACVersion & 0xffff) >= 0x0201) {
-			/* enable DC filter */
-			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R103, 0xc0);
-
-			/* improve power consumption in RT3070 Ver.F */
-			RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R31, &bbpreg);
-			bbpreg &= (~0x3);
-			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R31, bbpreg);
-		}
-		/* TX_LO1_en, RF R17 register Bit 3 to 0 */
-		RT30xxReadRFRegister(pAd, RF_R17, &RFValue);
-		RFValue &= (~0x08);
-		/* to fix rx long range issue */
-		if (pAd->NicConfig2.field.ExternalLNAForG == 0) {
-			RFValue |= 0x20;
-		}
-		/* set RF_R17_bit[2:0] equal to EEPROM setting at 0x48h */
-		if (pAd->TxMixerGain24G >= 1) {
-			RFValue &= (~0x7);	/* clean bit [2:0] */
-			RFValue |= pAd->TxMixerGain24G;
-		}
-		RT30xxWriteRFRegister(pAd, RF_R17, RFValue);
-	}
-/* end johnli */
-#endif /* RT30xx // */
-
-	if (pAd->MACVersion == 0x28600100) {
-		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, 0x16);
-		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, 0x12);
-	}
-
-	if (pAd->MACVersion >= RALINK_2880E_VERSION && pAd->MACVersion < RALINK_3070_VERSION)	/* 3*3 */
-	{
-		/* enlarge MAX_LEN_CFG */
-		u32 csr;
-		RTMP_IO_READ32(pAd, MAX_LEN_CFG, &csr);
-		csr &= 0xFFF;
-		csr |= 0x2000;
-		RTMP_IO_WRITE32(pAd, MAX_LEN_CFG, csr);
-	}
-#ifdef RTMP_MAC_USB
-	{
-		u8 MAC_Value[] =
-		    { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0, 0 };
-
-		/*Initialize WCID table */
-		Value = 0xff;
-		for (Index = 0; Index < 254; Index++) {
-			RTUSBMultiWrite(pAd,
-					(u16)(MAC_WCID_BASE + Index * 8),
-					MAC_Value, 8);
-		}
-	}
-#endif /* RTMP_MAC_USB // */
-
-	/* Add radio off control */
-	{
-		if (pAd->StaCfg.bRadio == FALSE) {
-/*                      RTMP_IO_WRITE32(pAd, PWR_PIN_CFG, 0x00001818); */
-			RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF);
-			DBGPRINT(RT_DEBUG_TRACE, ("Set Radio Off\n"));
-		}
-	}
-
-	/* Clear raw counters */
-	RTMP_IO_READ32(pAd, RX_STA_CNT0, &Counter);
-	RTMP_IO_READ32(pAd, RX_STA_CNT1, &Counter);
-	RTMP_IO_READ32(pAd, RX_STA_CNT2, &Counter);
-	RTMP_IO_READ32(pAd, TX_STA_CNT0, &Counter);
-	RTMP_IO_READ32(pAd, TX_STA_CNT1, &Counter);
-	RTMP_IO_READ32(pAd, TX_STA_CNT2, &Counter);
-
-	/* ASIC will keep garbage value after boot */
-	/* Clear all shared key table when initial */
-	/* This routine can be ignored in radio-ON/OFF operation. */
-	if (bHardReset) {
-		for (KeyIdx = 0; KeyIdx < 4; KeyIdx++) {
-			RTMP_IO_WRITE32(pAd, SHARED_KEY_MODE_BASE + 4 * KeyIdx,
-					0);
-		}
-
-		/* Clear all pairwise key table when initial */
-		for (KeyIdx = 0; KeyIdx < 256; KeyIdx++) {
-			RTMP_IO_WRITE32(pAd,
-					MAC_WCID_ATTRIBUTE_BASE +
-					(KeyIdx * HW_WCID_ATTRI_SIZE), 1);
-		}
-	}
-	/* assert HOST ready bit */
-/*  RTMP_IO_WRITE32(pAd, MAC_CSR1, 0x0); // 2004-09-14 asked by Mark */
-/*  RTMP_IO_WRITE32(pAd, MAC_CSR1, 0x4); */
-
-	/* It isn't necessary to clear this space when not hard reset. */
-	if (bHardReset == TRUE) {
-		/* clear all on-chip BEACON frame space */
-		for (apidx = 0; apidx < HW_BEACON_MAX_COUNT; apidx++) {
-			for (i = 0; i < HW_BEACON_OFFSET >> 2; i += 4)
-				RTMP_IO_WRITE32(pAd,
-						pAd->BeaconOffset[apidx] + i,
-						0x00);
-		}
-	}
-#ifdef RTMP_MAC_USB
-	AsicDisableSync(pAd);
-	/* Clear raw counters */
-	RTMP_IO_READ32(pAd, RX_STA_CNT0, &Counter);
-	RTMP_IO_READ32(pAd, RX_STA_CNT1, &Counter);
-	RTMP_IO_READ32(pAd, RX_STA_CNT2, &Counter);
-	RTMP_IO_READ32(pAd, TX_STA_CNT0, &Counter);
-	RTMP_IO_READ32(pAd, TX_STA_CNT1, &Counter);
-	RTMP_IO_READ32(pAd, TX_STA_CNT2, &Counter);
-	/* Default PCI clock cycle per ms is different as default setting, which is based on PCI. */
-	RTMP_IO_READ32(pAd, USB_CYC_CFG, &Counter);
-	Counter &= 0xffffff00;
-	Counter |= 0x000001e;
-	RTMP_IO_WRITE32(pAd, USB_CYC_CFG, Counter);
-#endif /* RTMP_MAC_USB // */
-
-	{
-		/* for rt2860E and after, init TXOP_CTRL_CFG with 0x583f. This is for extension channel overlapping IOT. */
-		if ((pAd->MACVersion & 0xffff) != 0x0101)
-			RTMP_IO_WRITE32(pAd, TXOP_CTRL_CFG, 0x583f);
-	}
-
-	DBGPRINT(RT_DEBUG_TRACE, ("<-- NICInitializeAsic\n"));
-	return NDIS_STATUS_SUCCESS;
-}
-
-/*
-	========================================================================
-
-	Routine Description:
-		Reset NIC Asics
-
-	Arguments:
-		Adapter						Pointer to our adapter
-
-	Return Value:
-		None
-
-	IRQL = PASSIVE_LEVEL
-
-	Note:
-		Reset NIC to initial state AS IS system boot up time.
-
-	========================================================================
-*/
-void NICIssueReset(struct rt_rtmp_adapter *pAd)
-{
-	u32 Value = 0;
-	DBGPRINT(RT_DEBUG_TRACE, ("--> NICIssueReset\n"));
-
-	/* Abort Tx, prevent ASIC from writing to Host memory */
-	/*RTMP_IO_WRITE32(pAd, TX_CNTL_CSR, 0x001f0000); */
-
-	/* Disable Rx, register value supposed will remain after reset */
-	RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
-	Value &= (0xfffffff3);
-	RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
-
-	/* Issue reset and clear from reset state */
-	RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x03);	/* 2004-09-17 change from 0x01 */
-	RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x00);
-
-	DBGPRINT(RT_DEBUG_TRACE, ("<-- NICIssueReset\n"));
-}
-
-/*
-	========================================================================
-
-	Routine Description:
-		Check ASIC registers and find any reason the system might hang
-
-	Arguments:
-		Adapter						Pointer to our adapter
-
-	Return Value:
-		None
-
-	IRQL = DISPATCH_LEVEL
-
-	========================================================================
-*/
-BOOLEAN NICCheckForHang(struct rt_rtmp_adapter *pAd)
-{
-	return (FALSE);
-}
-
-void NICUpdateFifoStaCounters(struct rt_rtmp_adapter *pAd)
-{
-	TX_STA_FIFO_STRUC StaFifo;
-	struct rt_mac_table_entry *pEntry;
-	u8 i = 0;
-	u8 pid = 0, wcid = 0;
-	char reTry;
-	u8 succMCS;
-
-	do {
-		RTMP_IO_READ32(pAd, TX_STA_FIFO, &StaFifo.word);
-
-		if (StaFifo.field.bValid == 0)
-			break;
-
-		wcid = (u8)StaFifo.field.wcid;
-
-		/* ignore NoACK and MGMT frame use 0xFF as WCID */
-		if ((StaFifo.field.TxAckRequired == 0)
-		    || (wcid >= MAX_LEN_OF_MAC_TABLE)) {
-			i++;
-			continue;
-		}
-
-		/* PID store Tx MCS Rate */
-		pid = (u8)StaFifo.field.PidType;
-
-		pEntry = &pAd->MacTab.Content[wcid];
-
-		pEntry->DebugFIFOCount++;
-
-		if (StaFifo.field.TxBF)	/* 3*3 */
-			pEntry->TxBFCount++;
-
-		if (!StaFifo.field.TxSuccess) {
-			pEntry->FIFOCount++;
-			pEntry->OneSecTxFailCount++;
-
-			if (pEntry->FIFOCount >= 1) {
-				DBGPRINT(RT_DEBUG_TRACE, ("#"));
-				pEntry->NoBADataCountDown = 64;
-
-				if (pEntry->PsMode == PWR_ACTIVE) {
-					int tid;
-					for (tid = 0; tid < NUM_OF_TID; tid++) {
-						BAOriSessionTearDown(pAd,
-								     pEntry->
-								     Aid, tid,
-								     FALSE,
-								     FALSE);
-					}
-
-					/* Update the continuous transmission counter except PS mode */
-					pEntry->ContinueTxFailCnt++;
-				} else {
-					/* Clear the FIFOCount when sta in Power Save mode. Basically we assume */
-					/*     this tx error happened due to sta just go to sleep. */
-					pEntry->FIFOCount = 0;
-					pEntry->ContinueTxFailCnt = 0;
-				}
-				/*pEntry->FIFOCount = 0; */
-			}
-			/*pEntry->bSendBAR = TRUE; */
-		} else {
-			if ((pEntry->PsMode != PWR_SAVE)
-			    && (pEntry->NoBADataCountDown > 0)) {
-				pEntry->NoBADataCountDown--;
-				if (pEntry->NoBADataCountDown == 0) {
-					DBGPRINT(RT_DEBUG_TRACE, ("@\n"));
-				}
-			}
-
-			pEntry->FIFOCount = 0;
-			pEntry->OneSecTxNoRetryOkCount++;
-			/* update NoDataIdleCount when successful send packet to STA. */
-			pEntry->NoDataIdleCount = 0;
-			pEntry->ContinueTxFailCnt = 0;
-		}
-
-		succMCS = StaFifo.field.SuccessRate & 0x7F;
-
-		reTry = pid - succMCS;
-
-		if (StaFifo.field.TxSuccess) {
-			pEntry->TXMCSExpected[pid]++;
-			if (pid == succMCS) {
-				pEntry->TXMCSSuccessful[pid]++;
-			} else {
-				pEntry->TXMCSAutoFallBack[pid][succMCS]++;
-			}
-		} else {
-			pEntry->TXMCSFailed[pid]++;
-		}
-
-		if (reTry > 0) {
-			if ((pid >= 12) && succMCS <= 7) {
-				reTry -= 4;
-			}
-			pEntry->OneSecTxRetryOkCount += reTry;
-		}
-
-		i++;
-		/* ASIC store 16 stack */
-	} while (i < (2 * TX_RING_SIZE));
-
-}
-
-/*
-	========================================================================
-
-	Routine Description:
-		Read statistical counters from hardware registers and record them
-		in software variables for later on query
-
-	Arguments:
-		pAd					Pointer to our adapter
-
-	Return Value:
-		None
-
-	IRQL = DISPATCH_LEVEL
-
-	========================================================================
-*/
-void NICUpdateRawCounters(struct rt_rtmp_adapter *pAd)
-{
-	u32 OldValue;	/*, Value2; */
-	/*unsigned long PageSum, OneSecTransmitCount; */
-	/*unsigned long TxErrorRatio, Retry, Fail; */
-	RX_STA_CNT0_STRUC RxStaCnt0;
-	RX_STA_CNT1_STRUC RxStaCnt1;
-	RX_STA_CNT2_STRUC RxStaCnt2;
-	TX_STA_CNT0_STRUC TxStaCnt0;
-	TX_STA_CNT1_STRUC StaTx1;
-	TX_STA_CNT2_STRUC StaTx2;
-	TX_AGG_CNT_STRUC TxAggCnt;
-	TX_AGG_CNT0_STRUC TxAggCnt0;
-	TX_AGG_CNT1_STRUC TxAggCnt1;
-	TX_AGG_CNT2_STRUC TxAggCnt2;
-	TX_AGG_CNT3_STRUC TxAggCnt3;
-	TX_AGG_CNT4_STRUC TxAggCnt4;
-	TX_AGG_CNT5_STRUC TxAggCnt5;
-	TX_AGG_CNT6_STRUC TxAggCnt6;
-	TX_AGG_CNT7_STRUC TxAggCnt7;
-	struct rt_counter_ralink *pRalinkCounters;
-
-	pRalinkCounters = &pAd->RalinkCounters;
-
-	RTMP_IO_READ32(pAd, RX_STA_CNT0, &RxStaCnt0.word);
-	RTMP_IO_READ32(pAd, RX_STA_CNT2, &RxStaCnt2.word);
-
-	{
-		RTMP_IO_READ32(pAd, RX_STA_CNT1, &RxStaCnt1.word);
-		/* Update RX PLCP error counter */
-		pAd->PrivateInfo.PhyRxErrCnt += RxStaCnt1.field.PlcpErr;
-		/* Update False CCA counter */
-		pAd->RalinkCounters.OneSecFalseCCACnt +=
-		    RxStaCnt1.field.FalseCca;
-	}
-
-	/* Update FCS counters */
-	OldValue = pAd->WlanCounters.FCSErrorCount.u.LowPart;
-	pAd->WlanCounters.FCSErrorCount.u.LowPart += (RxStaCnt0.field.CrcErr);	/* >> 7); */
-	if (pAd->WlanCounters.FCSErrorCount.u.LowPart < OldValue)
-		pAd->WlanCounters.FCSErrorCount.u.HighPart++;
-
-	/* Add FCS error count to private counters */
-	pRalinkCounters->OneSecRxFcsErrCnt += RxStaCnt0.field.CrcErr;
-	OldValue = pRalinkCounters->RealFcsErrCount.u.LowPart;
-	pRalinkCounters->RealFcsErrCount.u.LowPart += RxStaCnt0.field.CrcErr;
-	if (pRalinkCounters->RealFcsErrCount.u.LowPart < OldValue)
-		pRalinkCounters->RealFcsErrCount.u.HighPart++;
-
-	/* Update Duplicate Rcv check */
-	pRalinkCounters->DuplicateRcv += RxStaCnt2.field.RxDupliCount;
-	pAd->WlanCounters.FrameDuplicateCount.u.LowPart +=
-	    RxStaCnt2.field.RxDupliCount;
-	/* Update RX Overflow counter */
-	pAd->Counters8023.RxNoBuffer += (RxStaCnt2.field.RxFifoOverflowCount);
-
-	/*pAd->RalinkCounters.RxCount = 0; */
-#ifdef RTMP_MAC_USB
-	if (pRalinkCounters->RxCount != pAd->watchDogRxCnt) {
-		pAd->watchDogRxCnt = pRalinkCounters->RxCount;
-		pAd->watchDogRxOverFlowCnt = 0;
-	} else {
-		if (RxStaCnt2.field.RxFifoOverflowCount)
-			pAd->watchDogRxOverFlowCnt++;
-		else
-			pAd->watchDogRxOverFlowCnt = 0;
-	}
-#endif /* RTMP_MAC_USB // */
-
-	/*if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED) || */
-	/*      (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED) && (pAd->MacTab.Size != 1))) */
-	if (!pAd->bUpdateBcnCntDone) {
-		/* Update BEACON sent count */
-		RTMP_IO_READ32(pAd, TX_STA_CNT0, &TxStaCnt0.word);
-		RTMP_IO_READ32(pAd, TX_STA_CNT1, &StaTx1.word);
-		RTMP_IO_READ32(pAd, TX_STA_CNT2, &StaTx2.word);
-		pRalinkCounters->OneSecBeaconSentCnt +=
-		    TxStaCnt0.field.TxBeaconCount;
-		pRalinkCounters->OneSecTxRetryOkCount +=
-		    StaTx1.field.TxRetransmit;
-		pRalinkCounters->OneSecTxNoRetryOkCount +=
-		    StaTx1.field.TxSuccess;
-		pRalinkCounters->OneSecTxFailCount +=
-		    TxStaCnt0.field.TxFailCount;
-		pAd->WlanCounters.TransmittedFragmentCount.u.LowPart +=
-		    StaTx1.field.TxSuccess;
-		pAd->WlanCounters.RetryCount.u.LowPart +=
-		    StaTx1.field.TxRetransmit;
-		pAd->WlanCounters.FailedCount.u.LowPart +=
-		    TxStaCnt0.field.TxFailCount;
-	}
-
-	/*if (pAd->bStaFifoTest == TRUE) */
-	{
-		RTMP_IO_READ32(pAd, TX_AGG_CNT, &TxAggCnt.word);
-		RTMP_IO_READ32(pAd, TX_AGG_CNT0, &TxAggCnt0.word);
-		RTMP_IO_READ32(pAd, TX_AGG_CNT1, &TxAggCnt1.word);
-		RTMP_IO_READ32(pAd, TX_AGG_CNT2, &TxAggCnt2.word);
-		RTMP_IO_READ32(pAd, TX_AGG_CNT3, &TxAggCnt3.word);
-		RTMP_IO_READ32(pAd, TX_AGG_CNT4, &TxAggCnt4.word);
-		RTMP_IO_READ32(pAd, TX_AGG_CNT5, &TxAggCnt5.word);
-		RTMP_IO_READ32(pAd, TX_AGG_CNT6, &TxAggCnt6.word);
-		RTMP_IO_READ32(pAd, TX_AGG_CNT7, &TxAggCnt7.word);
-		pRalinkCounters->TxAggCount += TxAggCnt.field.AggTxCount;
-		pRalinkCounters->TxNonAggCount += TxAggCnt.field.NonAggTxCount;
-		pRalinkCounters->TxAgg1MPDUCount +=
-		    TxAggCnt0.field.AggSize1Count;
-		pRalinkCounters->TxAgg2MPDUCount +=
-		    TxAggCnt0.field.AggSize2Count;
-
-		pRalinkCounters->TxAgg3MPDUCount +=
-		    TxAggCnt1.field.AggSize3Count;
-		pRalinkCounters->TxAgg4MPDUCount +=
-		    TxAggCnt1.field.AggSize4Count;
-		pRalinkCounters->TxAgg5MPDUCount +=
-		    TxAggCnt2.field.AggSize5Count;
-		pRalinkCounters->TxAgg6MPDUCount +=
-		    TxAggCnt2.field.AggSize6Count;
-
-		pRalinkCounters->TxAgg7MPDUCount +=
-		    TxAggCnt3.field.AggSize7Count;
-		pRalinkCounters->TxAgg8MPDUCount +=
-		    TxAggCnt3.field.AggSize8Count;
-		pRalinkCounters->TxAgg9MPDUCount +=
-		    TxAggCnt4.field.AggSize9Count;
-		pRalinkCounters->TxAgg10MPDUCount +=
-		    TxAggCnt4.field.AggSize10Count;
-
-		pRalinkCounters->TxAgg11MPDUCount +=
-		    TxAggCnt5.field.AggSize11Count;
-		pRalinkCounters->TxAgg12MPDUCount +=
-		    TxAggCnt5.field.AggSize12Count;
-		pRalinkCounters->TxAgg13MPDUCount +=
-		    TxAggCnt6.field.AggSize13Count;
-		pRalinkCounters->TxAgg14MPDUCount +=
-		    TxAggCnt6.field.AggSize14Count;
-
-		pRalinkCounters->TxAgg15MPDUCount +=
-		    TxAggCnt7.field.AggSize15Count;
-		pRalinkCounters->TxAgg16MPDUCount +=
-		    TxAggCnt7.field.AggSize16Count;
-
-		/* Calculate the transmitted A-MPDU count */
-		pRalinkCounters->TransmittedAMPDUCount.u.LowPart +=
-		    TxAggCnt0.field.AggSize1Count;
-		pRalinkCounters->TransmittedAMPDUCount.u.LowPart +=
-		    (TxAggCnt0.field.AggSize2Count / 2);
-
-		pRalinkCounters->TransmittedAMPDUCount.u.LowPart +=
-		    (TxAggCnt1.field.AggSize3Count / 3);
-		pRalinkCounters->TransmittedAMPDUCount.u.LowPart +=
-		    (TxAggCnt1.field.AggSize4Count / 4);
-
-		pRalinkCounters->TransmittedAMPDUCount.u.LowPart +=
-		    (TxAggCnt2.field.AggSize5Count / 5);
-		pRalinkCounters->TransmittedAMPDUCount.u.LowPart +=
-		    (TxAggCnt2.field.AggSize6Count / 6);
-
-		pRalinkCounters->TransmittedAMPDUCount.u.LowPart +=
-		    (TxAggCnt3.field.AggSize7Count / 7);
-		pRalinkCounters->TransmittedAMPDUCount.u.LowPart +=
-		    (TxAggCnt3.field.AggSize8Count / 8);
-
-		pRalinkCounters->TransmittedAMPDUCount.u.LowPart +=
-		    (TxAggCnt4.field.AggSize9Count / 9);
-		pRalinkCounters->TransmittedAMPDUCount.u.LowPart +=
-		    (TxAggCnt4.field.AggSize10Count / 10);
-
-		pRalinkCounters->TransmittedAMPDUCount.u.LowPart +=
-		    (TxAggCnt5.field.AggSize11Count / 11);
-		pRalinkCounters->TransmittedAMPDUCount.u.LowPart +=
-		    (TxAggCnt5.field.AggSize12Count / 12);
-
-		pRalinkCounters->TransmittedAMPDUCount.u.LowPart +=
-		    (TxAggCnt6.field.AggSize13Count / 13);
-		pRalinkCounters->TransmittedAMPDUCount.u.LowPart +=
-		    (TxAggCnt6.field.AggSize14Count / 14);
-
-		pRalinkCounters->TransmittedAMPDUCount.u.LowPart +=
-		    (TxAggCnt7.field.AggSize15Count / 15);
-		pRalinkCounters->TransmittedAMPDUCount.u.LowPart +=
-		    (TxAggCnt7.field.AggSize16Count / 16);
-	}
-
-}
-
-/*
-	========================================================================
-
-	Routine Description:
-		Reset NIC from error
-
-	Arguments:
-		Adapter						Pointer to our adapter
-
-	Return Value:
-		None
-
-	IRQL = PASSIVE_LEVEL
-
-	Note:
-		Reset NIC from error state
-
-	========================================================================
-*/
-void NICResetFromError(struct rt_rtmp_adapter *pAd)
-{
-	/* Reset BBP (according to alex, reset ASIC will force reset BBP */
-	/* Therefore, skip the reset BBP */
-	/* RTMP_IO_WRITE32(pAd, MAC_CSR1, 0x2); */
-
-	RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x1);
-	/* Remove ASIC from reset state */
-	RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x0);
-
-	NICInitializeAdapter(pAd, FALSE);
-	NICInitAsicFromEEPROM(pAd);
-
-	/* Switch to current channel, since during reset process, the connection should remains on. */
-	AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, FALSE);
-	AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel);
-}
-
-int NICLoadFirmware(struct rt_rtmp_adapter *pAd)
-{
-	int status = NDIS_STATUS_SUCCESS;
-	if (pAd->chipOps.loadFirmware)
-		status = pAd->chipOps.loadFirmware(pAd);
-
-	return status;
-}
-
-/*
-	========================================================================
-
-	Routine Description:
-		erase 8051 firmware image in MAC ASIC
-
-	Arguments:
-		Adapter						Pointer to our adapter
-
-	IRQL = PASSIVE_LEVEL
-
-	========================================================================
-*/
-void NICEraseFirmware(struct rt_rtmp_adapter *pAd)
-{
-	if (pAd->chipOps.eraseFirmware)
-		pAd->chipOps.eraseFirmware(pAd);
-
-}				/* End of NICEraseFirmware */
-
-/*
-	========================================================================
-
-	Routine Description:
-		Load Tx rate switching parameters
-
-	Arguments:
-		Adapter						Pointer to our adapter
-
-	Return Value:
-		NDIS_STATUS_SUCCESS         firmware image load ok
-		NDIS_STATUS_FAILURE         image not found
-
-	IRQL = PASSIVE_LEVEL
-
-	Rate Table Format:
-		1. (B0: Valid Item number) (B1:Initial item from zero)
-		2. Item Number(Dec)      Mode(Hex)     Current MCS(Dec)    TrainUp(Dec)    TrainDown(Dec)
-
-	========================================================================
-*/
-int NICLoadRateSwitchingParams(struct rt_rtmp_adapter *pAd)
-{
-	return NDIS_STATUS_SUCCESS;
-}
-
-/*
-	========================================================================
-
-	Routine Description:
-		Compare two memory block
-
-	Arguments:
-		pSrc1		Pointer to first memory address
-		pSrc2		Pointer to second memory address
-
-	Return Value:
-		0:			memory is equal
-		1:			pSrc1 memory is larger
-		2:			pSrc2 memory is larger
-
-	IRQL = DISPATCH_LEVEL
-
-	Note:
-
-	========================================================================
-*/
-unsigned long RTMPCompareMemory(void *pSrc1, void *pSrc2, unsigned long Length)
-{
-	u8 *pMem1;
-	u8 *pMem2;
-	unsigned long Index = 0;
-
-	pMem1 = (u8 *)pSrc1;
-	pMem2 = (u8 *)pSrc2;
-
-	for (Index = 0; Index < Length; Index++) {
-		if (pMem1[Index] > pMem2[Index])
-			return (1);
-		else if (pMem1[Index] < pMem2[Index])
-			return (2);
-	}
-
-	/* Equal */
-	return (0);
-}
-
-/*
-	========================================================================
-
-	Routine Description:
-		Zero out memory block
-
-	Arguments:
-		pSrc1		Pointer to memory address
-		Length		Size
-
-	Return Value:
-		None
-
-	IRQL = PASSIVE_LEVEL
-	IRQL = DISPATCH_LEVEL
-
-	Note:
-
-	========================================================================
-*/
-void RTMPZeroMemory(void *pSrc, unsigned long Length)
-{
-	u8 *pMem;
-	unsigned long Index = 0;
-
-	pMem = (u8 *)pSrc;
-
-	for (Index = 0; Index < Length; Index++) {
-		pMem[Index] = 0x00;
-	}
-}
-
-/*
-	========================================================================
-
-	Routine Description:
-		Copy data from memory block 1 to memory block 2
-
-	Arguments:
-		pDest		Pointer to destination memory address
-		pSrc		Pointer to source memory address
-		Length		Copy size
-
-	Return Value:
-		None
-
-	IRQL = PASSIVE_LEVEL
-	IRQL = DISPATCH_LEVEL
-
-	Note:
-
-	========================================================================
-*/
-void RTMPMoveMemory(void *pDest, void *pSrc, unsigned long Length)
-{
-	u8 *pMem1;
-	u8 *pMem2;
-	u32 Index;
-
-	ASSERT((Length == 0) || (pDest && pSrc));
-
-	pMem1 = (u8 *)pDest;
-	pMem2 = (u8 *)pSrc;
-
-	for (Index = 0; Index < Length; Index++) {
-		pMem1[Index] = pMem2[Index];
-	}
-}
-
-/*
-	========================================================================
-
-	Routine Description:
-		Initialize port configuration structure
-
-	Arguments:
-		Adapter						Pointer to our adapter
-
-	Return Value:
-		None
-
-	IRQL = PASSIVE_LEVEL
-
-	Note:
-
-	========================================================================
-*/
-void UserCfgInit(struct rt_rtmp_adapter *pAd)
-{
-	u32 key_index, bss_index;
-
-	DBGPRINT(RT_DEBUG_TRACE, ("--> UserCfgInit\n"));
-
-	/* */
-	/*  part I. initialize common configuration */
-	/* */
-#ifdef RTMP_MAC_USB
-	pAd->BulkOutReq = 0;
-
-	pAd->BulkOutComplete = 0;
-	pAd->BulkOutCompleteOther = 0;
-	pAd->BulkOutCompleteCancel = 0;
-	pAd->BulkInReq = 0;
-	pAd->BulkInComplete = 0;
-	pAd->BulkInCompleteFail = 0;
-
-	/*pAd->QuickTimerP = 100; */
-	/*pAd->TurnAggrBulkInCount = 0; */
-	pAd->bUsbTxBulkAggre = 0;
-
-	/* init as unused value to ensure driver will set to MCU once. */
-	pAd->LedIndicatorStrength = 0xFF;
-
-	pAd->CommonCfg.MaxPktOneTxBulk = 2;
-	pAd->CommonCfg.TxBulkFactor = 1;
-	pAd->CommonCfg.RxBulkFactor = 1;
-
-	pAd->CommonCfg.TxPower = 100;	/*mW */
-
-	NdisZeroMemory(&pAd->CommonCfg.IOTestParm,
-		       sizeof(pAd->CommonCfg.IOTestParm));
-#endif /* RTMP_MAC_USB // */
-
-	for (key_index = 0; key_index < SHARE_KEY_NUM; key_index++) {
-		for (bss_index = 0; bss_index < MAX_MBSSID_NUM; bss_index++) {
-			pAd->SharedKey[bss_index][key_index].KeyLen = 0;
-			pAd->SharedKey[bss_index][key_index].CipherAlg =
-			    CIPHER_NONE;
-		}
-	}
-
-	pAd->EepromAccess = FALSE;
-
-	pAd->Antenna.word = 0;
-	pAd->CommonCfg.BBPCurrentBW = BW_20;
-
-	pAd->LedCntl.word = 0;
-#ifdef RTMP_MAC_PCI
-	pAd->LedIndicatorStrength = 0;
-	pAd->RLnkCtrlOffset = 0;
-	pAd->HostLnkCtrlOffset = 0;
-	pAd->StaCfg.PSControl.field.EnableNewPS = TRUE;
-	pAd->CheckDmaBusyCount = 0;
-#endif /* RTMP_MAC_PCI // */
-
-	pAd->bAutoTxAgcA = FALSE;	/* Default is OFF */
-	pAd->bAutoTxAgcG = FALSE;	/* Default is OFF */
-	pAd->RfIcType = RFIC_2820;
-
-	/* Init timer for reset complete event */
-	pAd->CommonCfg.CentralChannel = 1;
-	pAd->bForcePrintTX = FALSE;
-	pAd->bForcePrintRX = FALSE;
-	pAd->bStaFifoTest = FALSE;
-	pAd->bProtectionTest = FALSE;
-	pAd->CommonCfg.Dsifs = 10;	/* in units of usec */
-	pAd->CommonCfg.TxPower = 100;	/*mW */
-	pAd->CommonCfg.TxPowerPercentage = 0xffffffff;	/* AUTO */
-	pAd->CommonCfg.TxPowerDefault = 0xffffffff;	/* AUTO */
-	pAd->CommonCfg.TxPreamble = Rt802_11PreambleAuto;	/* use Long preamble on TX by defaut */
-	pAd->CommonCfg.bUseZeroToDisableFragment = FALSE;
-	pAd->CommonCfg.RtsThreshold = 2347;
-	pAd->CommonCfg.FragmentThreshold = 2346;
-	pAd->CommonCfg.UseBGProtection = 0;	/* 0: AUTO */
-	pAd->CommonCfg.bEnableTxBurst = TRUE;	/*0; */
-	pAd->CommonCfg.PhyMode = 0xff;	/* unknown */
-	pAd->CommonCfg.BandState = UNKNOWN_BAND;
-	pAd->CommonCfg.RadarDetect.CSPeriod = 10;
-	pAd->CommonCfg.RadarDetect.CSCount = 0;
-	pAd->CommonCfg.RadarDetect.RDMode = RD_NORMAL_MODE;
-
-	pAd->CommonCfg.RadarDetect.ChMovingTime = 65;
-	pAd->CommonCfg.RadarDetect.LongPulseRadarTh = 3;
-	pAd->CommonCfg.bAPSDCapable = FALSE;
-	pAd->CommonCfg.bNeedSendTriggerFrame = FALSE;
-	pAd->CommonCfg.TriggerTimerCount = 0;
-	pAd->CommonCfg.bAPSDForcePowerSave = FALSE;
-	pAd->CommonCfg.bCountryFlag = FALSE;
-	pAd->CommonCfg.TxStream = 0;
-	pAd->CommonCfg.RxStream = 0;
-
-	NdisZeroMemory(&pAd->BeaconTxWI, sizeof(pAd->BeaconTxWI));
-
-	NdisZeroMemory(&pAd->CommonCfg.HtCapability,
-		       sizeof(pAd->CommonCfg.HtCapability));
-	pAd->HTCEnable = FALSE;
-	pAd->bBroadComHT = FALSE;
-	pAd->CommonCfg.bRdg = FALSE;
-
-	NdisZeroMemory(&pAd->CommonCfg.AddHTInfo,
-		       sizeof(pAd->CommonCfg.AddHTInfo));
-	pAd->CommonCfg.BACapability.field.MMPSmode = MMPS_ENABLE;
-	pAd->CommonCfg.BACapability.field.MpduDensity = 0;
-	pAd->CommonCfg.BACapability.field.Policy = IMMED_BA;
-	pAd->CommonCfg.BACapability.field.RxBAWinLimit = 64;	/*32; */
-	pAd->CommonCfg.BACapability.field.TxBAWinLimit = 64;	/*32; */
-	DBGPRINT(RT_DEBUG_TRACE,
-		 ("--> UserCfgInit. BACapability = 0x%x\n",
-		  pAd->CommonCfg.BACapability.word));
-
-	pAd->CommonCfg.BACapability.field.AutoBA = FALSE;
-	BATableInit(pAd, &pAd->BATable);
-
-	pAd->CommonCfg.bExtChannelSwitchAnnouncement = 1;
-	pAd->CommonCfg.bHTProtect = 1;
-	pAd->CommonCfg.bMIMOPSEnable = TRUE;
-	/*2008/11/05:KH add to support Antenna power-saving of AP<-- */
-	pAd->CommonCfg.bGreenAPEnable = FALSE;
-	/*2008/11/05:KH add to support Antenna power-saving of AP--> */
-	pAd->CommonCfg.bBADecline = FALSE;
-	pAd->CommonCfg.bDisableReordering = FALSE;
-
-	if (pAd->MACVersion == 0x28720200) {
-		pAd->CommonCfg.TxBASize = 13;	/*by Jerry recommend */
-	} else {
-		pAd->CommonCfg.TxBASize = 7;
-	}
-
-	pAd->CommonCfg.REGBACapability.word = pAd->CommonCfg.BACapability.word;
-
-	/*pAd->CommonCfg.HTPhyMode.field.BW = BW_20; */
-	/*pAd->CommonCfg.HTPhyMode.field.MCS = MCS_AUTO; */
-	/*pAd->CommonCfg.HTPhyMode.field.ShortGI = GI_800; */
-	/*pAd->CommonCfg.HTPhyMode.field.STBC = STBC_NONE; */
-	pAd->CommonCfg.TxRate = RATE_6;
-
-	pAd->CommonCfg.MlmeTransmit.field.MCS = MCS_RATE_6;
-	pAd->CommonCfg.MlmeTransmit.field.BW = BW_20;
-	pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_OFDM;
-
-	pAd->CommonCfg.BeaconPeriod = 100;	/* in mSec */
-
-	/* */
-	/* part II. initialize STA specific configuration */
-	/* */
-	{
-		RX_FILTER_SET_FLAG(pAd, fRX_FILTER_ACCEPT_DIRECT);
-		RX_FILTER_CLEAR_FLAG(pAd, fRX_FILTER_ACCEPT_MULTICAST);
-		RX_FILTER_SET_FLAG(pAd, fRX_FILTER_ACCEPT_BROADCAST);
-		RX_FILTER_SET_FLAG(pAd, fRX_FILTER_ACCEPT_ALL_MULTICAST);
-
-		pAd->StaCfg.Psm = PWR_ACTIVE;
-
-		pAd->StaCfg.OrigWepStatus = Ndis802_11EncryptionDisabled;
-		pAd->StaCfg.PairCipher = Ndis802_11EncryptionDisabled;
-		pAd->StaCfg.GroupCipher = Ndis802_11EncryptionDisabled;
-		pAd->StaCfg.bMixCipher = FALSE;
-		pAd->StaCfg.DefaultKeyId = 0;
-
-		/* 802.1x port control */
-		pAd->StaCfg.PrivacyFilter = Ndis802_11PrivFilter8021xWEP;
-		pAd->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED;
-		pAd->StaCfg.LastMicErrorTime = 0;
-		pAd->StaCfg.MicErrCnt = 0;
-		pAd->StaCfg.bBlockAssoc = FALSE;
-		pAd->StaCfg.WpaState = SS_NOTUSE;
-
-		pAd->CommonCfg.NdisRadioStateOff = FALSE;	/* New to support microsoft disable radio with OID command */
-
-		pAd->StaCfg.RssiTrigger = 0;
-		NdisZeroMemory(&pAd->StaCfg.RssiSample, sizeof(struct rt_rssi_sample));
-		pAd->StaCfg.RssiTriggerMode =
-		    RSSI_TRIGGERED_UPON_BELOW_THRESHOLD;
-		pAd->StaCfg.AtimWin = 0;
-		pAd->StaCfg.DefaultListenCount = 3;	/*default listen count; */
-		pAd->StaCfg.BssType = BSS_INFRA;	/* BSS_INFRA or BSS_ADHOC or BSS_MONITOR */
-		pAd->StaCfg.bScanReqIsFromWebUI = FALSE;
-		OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_DOZE);
-		OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_WAKEUP_NOW);
-
-		pAd->StaCfg.bAutoTxRateSwitch = TRUE;
-		pAd->StaCfg.DesiredTransmitSetting.field.MCS = MCS_AUTO;
-	}
-
-#ifdef PCIE_PS_SUPPORT
-	pAd->brt30xxBanMcuCmd = FALSE;
-	pAd->b3090ESpecialChip = FALSE;
-/*KH Debug:the following must be removed */
-	pAd->StaCfg.PSControl.field.rt30xxPowerMode = 3;
-	pAd->StaCfg.PSControl.field.rt30xxForceASPMTest = 0;
-	pAd->StaCfg.PSControl.field.rt30xxFollowHostASPM = 1;
-#endif /* PCIE_PS_SUPPORT // */
-
-	/* global variables mXXXX used in MAC protocol state machines */
-	OPSTATUS_SET_FLAG(pAd, fOP_STATUS_RECEIVE_DTIM);
-	OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_ADHOC_ON);
-	OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_INFRA_ON);
-
-	/* PHY specification */
-	pAd->CommonCfg.PhyMode = PHY_11BG_MIXED;	/* default PHY mode */
-	OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_SHORT_PREAMBLE_INUSED);	/* CCK use long preamble */
-
-	{
-		/* user desired power mode */
-		pAd->StaCfg.WindowsPowerMode = Ndis802_11PowerModeCAM;
-		pAd->StaCfg.WindowsBatteryPowerMode = Ndis802_11PowerModeCAM;
-		pAd->StaCfg.bWindowsACCAMEnable = FALSE;
-
-		RTMPInitTimer(pAd, &pAd->StaCfg.StaQuickResponeForRateUpTimer,
-			      GET_TIMER_FUNCTION(StaQuickResponeForRateUpExec),
-			      pAd, FALSE);
-		pAd->StaCfg.StaQuickResponeForRateUpTimerRunning = FALSE;
-
-		/* Patch for Ndtest */
-		pAd->StaCfg.ScanCnt = 0;
-
-		pAd->StaCfg.bHwRadio = TRUE;	/* Default Hardware Radio status is On */
-		pAd->StaCfg.bSwRadio = TRUE;	/* Default Software Radio status is On */
-		pAd->StaCfg.bRadio = TRUE;	/* bHwRadio && bSwRadio */
-		pAd->StaCfg.bHardwareRadio = FALSE;	/* Default is OFF */
-		pAd->StaCfg.bShowHiddenSSID = FALSE;	/* Default no show */
-
-		/* Nitro mode control */
-		pAd->StaCfg.bAutoReconnect = TRUE;
-
-		/* Save the init time as last scan time, the system should do scan after 2 seconds. */
-		/* This patch is for driver wake up from standby mode, system will do scan right away. */
-		NdisGetSystemUpTime(&pAd->StaCfg.LastScanTime);
-		if (pAd->StaCfg.LastScanTime > 10 * OS_HZ)
-			pAd->StaCfg.LastScanTime -= (10 * OS_HZ);
-
-		NdisZeroMemory(pAd->nickname, IW_ESSID_MAX_SIZE + 1);
-#ifdef RTMP_MAC_PCI
-		sprintf((char *)pAd->nickname, "RT2860STA");
-#endif /* RTMP_MAC_PCI // */
-#ifdef RTMP_MAC_USB
-		sprintf((char *)pAd->nickname, "RT2870STA");
-#endif /* RTMP_MAC_USB // */
-		RTMPInitTimer(pAd, &pAd->StaCfg.WpaDisassocAndBlockAssocTimer,
-			      GET_TIMER_FUNCTION(WpaDisassocApAndBlockAssoc),
-			      pAd, FALSE);
-		pAd->StaCfg.IEEE8021X = FALSE;
-		pAd->StaCfg.IEEE8021x_required_keys = FALSE;
-		pAd->StaCfg.WpaSupplicantUP = WPA_SUPPLICANT_DISABLE;
-		pAd->StaCfg.bRSN_IE_FromWpaSupplicant = FALSE;
-		pAd->StaCfg.WpaSupplicantUP = WPA_SUPPLICANT_ENABLE;
-
-		NdisZeroMemory(pAd->StaCfg.ReplayCounter, 8);
-
-		pAd->StaCfg.bAutoConnectByBssid = FALSE;
-		pAd->StaCfg.BeaconLostTime = BEACON_LOST_TIME;
-		NdisZeroMemory(pAd->StaCfg.WpaPassPhrase, 64);
-		pAd->StaCfg.WpaPassPhraseLen = 0;
-		pAd->StaCfg.bAutoRoaming = FALSE;
-		pAd->StaCfg.bForceTxBurst = FALSE;
-	}
-
-	/* Default for extra information is not valid */
-	pAd->ExtraInfo = EXTRA_INFO_CLEAR;
-
-	/* Default Config change flag */
-	pAd->bConfigChanged = FALSE;
-
-	/* */
-	/* part III. AP configurations */
-	/* */
-
-	/* */
-	/* part IV. others */
-	/* */
-	/* dynamic BBP R66:sensibity tuning to overcome background noise */
-	pAd->BbpTuning.bEnable = TRUE;
-	pAd->BbpTuning.FalseCcaLowerThreshold = 100;
-	pAd->BbpTuning.FalseCcaUpperThreshold = 512;
-	pAd->BbpTuning.R66Delta = 4;
-	pAd->Mlme.bEnableAutoAntennaCheck = TRUE;
-
-	/* */
-	/* Also initial R66CurrentValue, RTUSBResumeMsduTransmission might use this value. */
-	/* if not initial this value, the default value will be 0. */
-	/* */
-	pAd->BbpTuning.R66CurrentValue = 0x38;
-
-	pAd->Bbp94 = BBPR94_DEFAULT;
-	pAd->BbpForCCK = FALSE;
-
-	/* Default is FALSE for test bit 1 */
-	/*pAd->bTest1 = FALSE; */
-
-	/* initialize MAC table and allocate spin lock */
-	NdisZeroMemory(&pAd->MacTab, sizeof(struct rt_mac_table));
-	InitializeQueueHeader(&pAd->MacTab.McastPsQueue);
-	NdisAllocateSpinLock(&pAd->MacTabLock);
-
-	/*RTMPInitTimer(pAd, &pAd->RECBATimer, RECBATimerTimeout, pAd, TRUE); */
-	/*RTMPSetTimer(&pAd->RECBATimer, REORDER_EXEC_INTV); */
-
-	pAd->CommonCfg.bWiFiTest = FALSE;
-#ifdef RTMP_MAC_PCI
-	pAd->bPCIclkOff = FALSE;
-#endif /* RTMP_MAC_PCI // */
-
-	RTMP_SET_PSFLAG(pAd, fRTMP_PS_CAN_GO_SLEEP);
-	DBGPRINT(RT_DEBUG_TRACE, ("<-- UserCfgInit\n"));
-}
-
-/* IRQL = PASSIVE_LEVEL */
-/* */
-/*  FUNCTION: AtoH(char *, u8 *, int) */
-/* */
-/*  PURPOSE:  Converts ascii string to network order hex */
-/* */
-/*  PARAMETERS: */
-/*    src    - pointer to input ascii string */
-/*    dest   - pointer to output hex */
-/*    destlen - size of dest */
-/* */
-/*  COMMENTS: */
-/* */
-/*    2 ascii bytes make a hex byte so must put 1st ascii byte of pair */
-/*    into upper nibble and 2nd ascii byte of pair into lower nibble. */
-/* */
-/* IRQL = PASSIVE_LEVEL */
-
-void AtoH(char *src, u8 *dest, int destlen)
-{
-	char *srcptr;
-	u8 *destTemp;
-
-	srcptr = src;
-	destTemp = (u8 *)dest;
-
-	while (destlen--) {
-		*destTemp = hex_to_bin(*srcptr++) << 4;	/* Put 1st ascii byte in upper nibble. */
-		*destTemp += hex_to_bin(*srcptr++);	/* Add 2nd ascii byte to above. */
-		destTemp++;
-	}
-}
-
-/*+++Mark by shiang, not use now, need to remove after confirm */
-/*---Mark by shiang, not use now, need to remove after confirm */
-
-/*
-	========================================================================
-
-	Routine Description:
-		Init timer objects
-
-	Arguments:
-		pAd			Pointer to our adapter
-		pTimer				Timer structure
-		pTimerFunc			Function to execute when timer expired
-		Repeat				Ture for period timer
-
-	Return Value:
-		None
-
-	Note:
-
-	========================================================================
-*/
-void RTMPInitTimer(struct rt_rtmp_adapter *pAd,
-		   struct rt_ralink_timer *pTimer,
-		   void *pTimerFunc, void *pData, IN BOOLEAN Repeat)
-{
-	/* */
-	/* Set Valid to TRUE for later used. */
-	/* It will crash if we cancel a timer or set a timer */
-	/* that we haven't initialize before. */
-	/* */
-	pTimer->Valid = TRUE;
-
-	pTimer->PeriodicType = Repeat;
-	pTimer->State = FALSE;
-	pTimer->cookie = (unsigned long)pData;
-
-#ifdef RTMP_TIMER_TASK_SUPPORT
-	pTimer->pAd = pAd;
-#endif /* RTMP_TIMER_TASK_SUPPORT // */
-
-	RTMP_OS_Init_Timer(pAd, &pTimer->TimerObj, pTimerFunc, (void *)pTimer);
-}
-
-/*
-	========================================================================
-
-	Routine Description:
-		Init timer objects
-
-	Arguments:
-		pTimer				Timer structure
-		Value				Timer value in milliseconds
-
-	Return Value:
-		None
-
-	Note:
-		To use this routine, must call RTMPInitTimer before.
-
-	========================================================================
-*/
-void RTMPSetTimer(struct rt_ralink_timer *pTimer, unsigned long Value)
-{
-	if (pTimer->Valid) {
-		pTimer->TimerValue = Value;
-		pTimer->State = FALSE;
-		if (pTimer->PeriodicType == TRUE) {
-			pTimer->Repeat = TRUE;
-			RTMP_SetPeriodicTimer(&pTimer->TimerObj, Value);
-		} else {
-			pTimer->Repeat = FALSE;
-			RTMP_OS_Add_Timer(&pTimer->TimerObj, Value);
-		}
-	} else {
-		DBGPRINT_ERR("RTMPSetTimer failed, Timer hasn't been initialize!\n");
-	}
-}
-
-/*
-	========================================================================
-
-	Routine Description:
-		Init timer objects
-
-	Arguments:
-		pTimer				Timer structure
-		Value				Timer value in milliseconds
-
-	Return Value:
-		None
-
-	Note:
-		To use this routine, must call RTMPInitTimer before.
-
-	========================================================================
-*/
-void RTMPModTimer(struct rt_ralink_timer *pTimer, unsigned long Value)
-{
-	BOOLEAN Cancel;
-
-	if (pTimer->Valid) {
-		pTimer->TimerValue = Value;
-		pTimer->State = FALSE;
-		if (pTimer->PeriodicType == TRUE) {
-			RTMPCancelTimer(pTimer, &Cancel);
-			RTMPSetTimer(pTimer, Value);
-		} else {
-			RTMP_OS_Mod_Timer(&pTimer->TimerObj, Value);
-		}
-	} else {
-		DBGPRINT_ERR("RTMPModTimer failed, Timer hasn't been initialize!\n");
-	}
-}
-
-/*
-	========================================================================
-
-	Routine Description:
-		Cancel timer objects
-
-	Arguments:
-		Adapter						Pointer to our adapter
-
-	Return Value:
-		None
-
-	IRQL = PASSIVE_LEVEL
-	IRQL = DISPATCH_LEVEL
-
-	Note:
-		1.) To use this routine, must call RTMPInitTimer before.
-		2.) Reset NIC to initial state AS IS system boot up time.
-
-	========================================================================
-*/
-void RTMPCancelTimer(struct rt_ralink_timer *pTimer, OUT BOOLEAN * pCancelled)
-{
-	if (pTimer->Valid) {
-		if (pTimer->State == FALSE)
-			pTimer->Repeat = FALSE;
-
-		RTMP_OS_Del_Timer(&pTimer->TimerObj, pCancelled);
-
-		if (*pCancelled == TRUE)
-			pTimer->State = TRUE;
-
-#ifdef RTMP_TIMER_TASK_SUPPORT
-		/* We need to go-through the TimerQ to findout this timer handler and remove it if */
-		/*              it's still waiting for execution. */
-		RtmpTimerQRemove(pTimer->pAd, pTimer);
-#endif /* RTMP_TIMER_TASK_SUPPORT // */
-	} else {
-		DBGPRINT_ERR("RTMPCancelTimer failed, Timer hasn't been initialize!\n");
-	}
-}
-
-/*
-	========================================================================
-
-	Routine Description:
-		Set LED Status
-
-	Arguments:
-		pAd						Pointer to our adapter
-		Status					LED Status
-
-	Return Value:
-		None
-
-	IRQL = PASSIVE_LEVEL
-	IRQL = DISPATCH_LEVEL
-
-	Note:
-
-	========================================================================
-*/
-void RTMPSetLED(struct rt_rtmp_adapter *pAd, u8 Status)
-{
-	/*unsigned long                 data; */
-	u8 HighByte = 0;
-	u8 LowByte;
-
-	LowByte = pAd->LedCntl.field.LedMode & 0x7f;
-	switch (Status) {
-	case LED_LINK_DOWN:
-		HighByte = 0x20;
-		AsicSendCommandToMcu(pAd, 0x50, 0xff, LowByte, HighByte);
-		pAd->LedIndicatorStrength = 0;
-		break;
-	case LED_LINK_UP:
-		if (pAd->CommonCfg.Channel > 14)
-			HighByte = 0xa0;
-		else
-			HighByte = 0x60;
-		AsicSendCommandToMcu(pAd, 0x50, 0xff, LowByte, HighByte);
-		break;
-	case LED_RADIO_ON:
-		HighByte = 0x20;
-		AsicSendCommandToMcu(pAd, 0x50, 0xff, LowByte, HighByte);
-		break;
-	case LED_HALT:
-		LowByte = 0;	/* Driver sets MAC register and MAC controls LED */
-	case LED_RADIO_OFF:
-		HighByte = 0;
-		AsicSendCommandToMcu(pAd, 0x50, 0xff, LowByte, HighByte);
-		break;
-	case LED_WPS:
-		HighByte = 0x10;
-		AsicSendCommandToMcu(pAd, 0x50, 0xff, LowByte, HighByte);
-		break;
-	case LED_ON_SITE_SURVEY:
-		HighByte = 0x08;
-		AsicSendCommandToMcu(pAd, 0x50, 0xff, LowByte, HighByte);
-		break;
-	case LED_POWER_UP:
-		HighByte = 0x04;
-		AsicSendCommandToMcu(pAd, 0x50, 0xff, LowByte, HighByte);
-		break;
-	default:
-		DBGPRINT(RT_DEBUG_WARN,
-			 ("RTMPSetLED::Unknown Status %d\n", Status));
-		break;
-	}
-
-	/* */
-	/* Keep LED status for LED SiteSurvey mode. */
-	/* After SiteSurvey, we will set the LED mode to previous status. */
-	/* */
-	if ((Status != LED_ON_SITE_SURVEY) && (Status != LED_POWER_UP))
-		pAd->LedStatus = Status;
-
-	DBGPRINT(RT_DEBUG_TRACE,
-		 ("RTMPSetLED::Mode=%d,HighByte=0x%02x,LowByte=0x%02x\n",
-		  pAd->LedCntl.field.LedMode, HighByte, LowByte));
-}
-
-/*
-	========================================================================
-
-	Routine Description:
-		Set LED Signal Strength
-
-	Arguments:
-		pAd						Pointer to our adapter
-		Dbm						Signal Strength
-
-	Return Value:
-		None
-
-	IRQL = PASSIVE_LEVEL
-
-	Note:
-		Can be run on any IRQL level.
-
-		According to Microsoft Zero Config Wireless Signal Strength definition as belows.
-		<= -90  No Signal
-		<= -81  Very Low
-		<= -71  Low
-		<= -67  Good
-		<= -57  Very Good
-		 > -57  Excellent
-	========================================================================
-*/
-void RTMPSetSignalLED(struct rt_rtmp_adapter *pAd, IN NDIS_802_11_RSSI Dbm)
-{
-	u8 nLed = 0;
-
-	if (pAd->LedCntl.field.LedMode == LED_MODE_SIGNAL_STREGTH) {
-		if (Dbm <= -90)
-			nLed = 0;
-		else if (Dbm <= -81)
-			nLed = 1;
-		else if (Dbm <= -71)
-			nLed = 3;
-		else if (Dbm <= -67)
-			nLed = 7;
-		else if (Dbm <= -57)
-			nLed = 15;
-		else
-			nLed = 31;
-
-		/* */
-		/* Update Signal Strength to firmware if changed. */
-		/* */
-		if (pAd->LedIndicatorStrength != nLed) {
-			AsicSendCommandToMcu(pAd, 0x51, 0xff, nLed,
-					     pAd->LedCntl.field.Polarity);
-			pAd->LedIndicatorStrength = nLed;
-		}
-	}
-}
-
-/*
-	========================================================================
-
-	Routine Description:
-		Enable RX
-
-	Arguments:
-		pAd						Pointer to our adapter
-
-	Return Value:
-		None
-
-	IRQL <= DISPATCH_LEVEL
-
-	Note:
-		Before Enable RX, make sure you have enabled Interrupt.
-	========================================================================
-*/
-void RTMPEnableRxTx(struct rt_rtmp_adapter *pAd)
-{
-/*      WPDMA_GLO_CFG_STRUC     GloCfg; */
-/*      unsigned long   i = 0; */
-	u32 rx_filter_flag;
-
-	DBGPRINT(RT_DEBUG_TRACE, ("==> RTMPEnableRxTx\n"));
-
-	/* Enable Rx DMA. */
-	RT28XXDMAEnable(pAd);
-
-	/* enable RX of MAC block */
-	if (pAd->OpMode == OPMODE_AP) {
-		rx_filter_flag = APNORMAL;
-
-		RTMP_IO_WRITE32(pAd, RX_FILTR_CFG, rx_filter_flag);	/* enable RX of DMA block */
-	} else {
-		if (pAd->CommonCfg.PSPXlink)
-			rx_filter_flag = PSPXLINK;
-		else
-			rx_filter_flag = STANORMAL;	/* Station not drop control frame will fail WiFi Certification. */
-		RTMP_IO_WRITE32(pAd, RX_FILTR_CFG, rx_filter_flag);
-	}
-
-	RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0xc);
-	DBGPRINT(RT_DEBUG_TRACE, ("<== RTMPEnableRxTx\n"));
-}
-
-/*+++Add by shiang, move from os/linux/rt_main_dev.c */
-void CfgInitHook(struct rt_rtmp_adapter *pAd)
-{
-	pAd->bBroadComHT = TRUE;
-}
-
-int rt28xx_init(struct rt_rtmp_adapter *pAd,
-		char *pDefaultMac, char *pHostName)
-{
-	u32 index;
-	u8 TmpPhy;
-	int Status;
-	u32 MacCsr0 = 0;
-
-#ifdef RTMP_MAC_PCI
-	{
-		/* If dirver doesn't wake up firmware here, */
-		/* NICLoadFirmware will hang forever when interface is up again. */
-		/* RT2860 PCI */
-		if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE) &&
-		    OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE)) {
-			AUTO_WAKEUP_STRUC AutoWakeupCfg;
-			AsicForceWakeup(pAd, TRUE);
-			AutoWakeupCfg.word = 0;
-			RTMP_IO_WRITE32(pAd, AUTO_WAKEUP_CFG,
-					AutoWakeupCfg.word);
-			OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_DOZE);
-		}
-	}
-#endif /* RTMP_MAC_PCI // */
-
-	/* reset Adapter flags */
-	RTMP_CLEAR_FLAGS(pAd);
-
-	/* Init BssTab & ChannelInfo tabbles for auto channel select. */
-
-	/* Allocate BA Reordering memory */
-	ba_reordering_resource_init(pAd, MAX_REORDERING_MPDU_NUM);
-
-	/* Make sure MAC gets ready. */
-	index = 0;
-	do {
-		RTMP_IO_READ32(pAd, MAC_CSR0, &MacCsr0);
-		pAd->MACVersion = MacCsr0;
-
-		if ((pAd->MACVersion != 0x00)
-		    && (pAd->MACVersion != 0xFFFFFFFF))
-			break;
-
-		RTMPusecDelay(10);
-	} while (index++ < 100);
-	DBGPRINT(RT_DEBUG_TRACE,
-		 ("MAC_CSR0  [ Ver:Rev=0x%08x]\n", pAd->MACVersion));
-
-#ifdef RTMP_MAC_PCI
-#ifdef PCIE_PS_SUPPORT
-	/*Iverson patch PCIE L1 issue to make sure that driver can be read,write ,BBP and RF register  at pcie L.1 level */
-	if ((IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd))
-	    && OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE)) {
-		RTMP_IO_READ32(pAd, AUX_CTRL, &MacCsr0);
-		MacCsr0 |= 0x402;
-		RTMP_IO_WRITE32(pAd, AUX_CTRL, MacCsr0);
-		DBGPRINT(RT_DEBUG_TRACE, ("AUX_CTRL = 0x%x\n", MacCsr0));
-	}
-#endif /* PCIE_PS_SUPPORT // */
-
-	/* To fix driver disable/enable hang issue when radio off */
-	RTMP_IO_WRITE32(pAd, PWR_PIN_CFG, 0x2);
-#endif /* RTMP_MAC_PCI // */
-
-	/* Disable DMA */
-	RT28XXDMADisable(pAd);
-
-	/* Load 8051 firmware */
-	Status = NICLoadFirmware(pAd);
-	if (Status != NDIS_STATUS_SUCCESS) {
-		DBGPRINT_ERR("NICLoadFirmware failed, Status[=0x%08x]\n", Status);
-		goto err1;
-	}
-
-	NICLoadRateSwitchingParams(pAd);
-
-	/* Disable interrupts here which is as soon as possible */
-	/* This statement should never be true. We might consider to remove it later */
-#ifdef RTMP_MAC_PCI
-	if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_ACTIVE)) {
-		RTMP_ASIC_INTERRUPT_DISABLE(pAd);
-	}
-#endif /* RTMP_MAC_PCI // */
-
-	Status = RTMPAllocTxRxRingMemory(pAd);
-	if (Status != NDIS_STATUS_SUCCESS) {
-		DBGPRINT_ERR("RTMPAllocDMAMemory failed, Status[=0x%08x]\n", Status);
-		goto err1;
-	}
-
-	RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE);
-
-	/* initialize MLME */
-	/* */
-
-	Status = RtmpMgmtTaskInit(pAd);
-	if (Status != NDIS_STATUS_SUCCESS)
-		goto err2;
-
-	Status = MlmeInit(pAd);
-	if (Status != NDIS_STATUS_SUCCESS) {
-		DBGPRINT_ERR("MlmeInit failed, Status[=0x%08x]\n", Status);
-		goto err2;
-	}
-	/* Initialize pAd->StaCfg, pAd->ApCfg, pAd->CommonCfg to manufacture default */
-	/* */
-	UserCfgInit(pAd);
-	Status = RtmpNetTaskInit(pAd);
-	if (Status != NDIS_STATUS_SUCCESS)
-		goto err3;
-
-/*      COPY_MAC_ADDR(pAd->ApCfg.MBSSID[apidx].Bssid, netif->hwaddr); */
-/*      pAd->bForcePrintTX = TRUE; */
-
-	CfgInitHook(pAd);
-
-	NdisAllocateSpinLock(&pAd->MacTabLock);
-
-	MeasureReqTabInit(pAd);
-	TpcReqTabInit(pAd);
-
-	/* */
-	/* Init the hardware, we need to init asic before read registry, otherwise mac register will be reset */
-	/* */
-	Status = NICInitializeAdapter(pAd, TRUE);
-	if (Status != NDIS_STATUS_SUCCESS) {
-		DBGPRINT_ERR("NICInitializeAdapter failed, Status[=0x%08x]\n", Status);
-		if (Status != NDIS_STATUS_SUCCESS)
-			goto err3;
-	}
-
-	DBGPRINT(RT_DEBUG_OFF, ("1. Phy Mode = %d\n", pAd->CommonCfg.PhyMode));
-
-#ifdef RTMP_MAC_USB
-	pAd->CommonCfg.bMultipleIRP = FALSE;
-
-	if (pAd->CommonCfg.bMultipleIRP)
-		pAd->CommonCfg.NumOfBulkInIRP = RX_RING_SIZE;
-	else
-		pAd->CommonCfg.NumOfBulkInIRP = 1;
-#endif /* RTMP_MAC_USB // */
-
-	/*Init Ba Capability parameters. */
-/*      RT28XX_BA_INIT(pAd); */
-	pAd->CommonCfg.DesiredHtPhy.MpduDensity =
-	    (u8)pAd->CommonCfg.BACapability.field.MpduDensity;
-	pAd->CommonCfg.DesiredHtPhy.AmsduEnable =
-	    (u16)pAd->CommonCfg.BACapability.field.AmsduEnable;
-	pAd->CommonCfg.DesiredHtPhy.AmsduSize =
-	    (u16)pAd->CommonCfg.BACapability.field.AmsduSize;
-	pAd->CommonCfg.DesiredHtPhy.MimoPs =
-	    (u16)pAd->CommonCfg.BACapability.field.MMPSmode;
-	/* UPdata to HT IE */
-	pAd->CommonCfg.HtCapability.HtCapInfo.MimoPs =
-	    (u16)pAd->CommonCfg.BACapability.field.MMPSmode;
-	pAd->CommonCfg.HtCapability.HtCapInfo.AMsduSize =
-	    (u16)pAd->CommonCfg.BACapability.field.AmsduSize;
-	pAd->CommonCfg.HtCapability.HtCapParm.MpduDensity =
-	    (u8)pAd->CommonCfg.BACapability.field.MpduDensity;
-
-	/* after reading Registry, we now know if in AP mode or STA mode */
-
-	/* Load 8051 firmware; crash when FW image not existent */
-	/* Status = NICLoadFirmware(pAd); */
-	/* if (Status != NDIS_STATUS_SUCCESS) */
-	/*    break; */
-
-	DBGPRINT(RT_DEBUG_OFF, ("2. Phy Mode = %d\n", pAd->CommonCfg.PhyMode));
-
-	/* We should read EEPROM for all cases.  rt2860b */
-	NICReadEEPROMParameters(pAd, (u8 *)pDefaultMac);
-
-	DBGPRINT(RT_DEBUG_OFF, ("3. Phy Mode = %d\n", pAd->CommonCfg.PhyMode));
-
-	NICInitAsicFromEEPROM(pAd);	/*rt2860b */
-
-	/* Set PHY to appropriate mode */
-	TmpPhy = pAd->CommonCfg.PhyMode;
-	pAd->CommonCfg.PhyMode = 0xff;
-	RTMPSetPhyMode(pAd, TmpPhy);
-	SetCommonHT(pAd);
-
-	/* No valid channels. */
-	if (pAd->ChannelListNum == 0) {
-		DBGPRINT(RT_DEBUG_ERROR,
-			 ("Wrong configuration. No valid channel found. Check \"ContryCode\" and \"ChannelGeography\" setting.\n"));
-		goto err4;
-	}
-
-	DBGPRINT(RT_DEBUG_OFF,
-		 ("MCS Set = %02x %02x %02x %02x %02x\n",
-		  pAd->CommonCfg.HtCapability.MCSSet[0],
-		  pAd->CommonCfg.HtCapability.MCSSet[1],
-		  pAd->CommonCfg.HtCapability.MCSSet[2],
-		  pAd->CommonCfg.HtCapability.MCSSet[3],
-		  pAd->CommonCfg.HtCapability.MCSSet[4]));
-
-#ifdef RTMP_RF_RW_SUPPORT
-	/*Init RT30xx RFRegisters after read RFIC type from EEPROM */
-	NICInitRFRegisters(pAd);
-#endif /* RTMP_RF_RW_SUPPORT // */
-
-/*              APInitialize(pAd); */
-
-	/* */
-	/* Initialize RF register to default value */
-	/* */
-	AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
-	AsicLockChannel(pAd, pAd->CommonCfg.Channel);
-
-	/* 8051 firmware require the signal during booting time. */
-	/*2008/11/28:KH marked the following codes to patch Frequency offset bug */
-	/*AsicSendCommandToMcu(pAd, 0x72, 0xFF, 0x00, 0x00); */
-
-	if (pAd && (Status != NDIS_STATUS_SUCCESS)) {
-		/* */
-		/* Undo everything if it failed */
-		/* */
-		if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE)) {
-/*                      NdisMDeregisterInterrupt(&pAd->Interrupt); */
-			RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE);
-		}
-/*              RTMPFreeAdapter(pAd); // we will free it in disconnect() */
-	} else if (pAd) {
-		/* Microsoft HCT require driver send a disconnect event after driver initialization. */
-		OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED);
-/*              pAd->IndicateMediaState = NdisMediaStateDisconnected; */
-		RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_MEDIA_STATE_CHANGE);
-
-		DBGPRINT(RT_DEBUG_TRACE,
-			 ("NDIS_STATUS_MEDIA_DISCONNECT Event B!\n"));
-
-#ifdef RTMP_MAC_USB
-		RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS);
-		RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_REMOVE_IN_PROGRESS);
-
-		/* */
-		/* Support multiple BulkIn IRP, */
-		/* the value on pAd->CommonCfg.NumOfBulkInIRP may be large than 1. */
-		/* */
-		for (index = 0; index < pAd->CommonCfg.NumOfBulkInIRP; index++) {
-			RTUSBBulkReceive(pAd);
-			DBGPRINT(RT_DEBUG_TRACE, ("RTUSBBulkReceive!\n"));
-		}
-#endif /* RTMP_MAC_USB // */
-	}			/* end of else */
-
-	/* Set up the Mac address */
-	RtmpOSNetDevAddrSet(pAd->net_dev, &pAd->CurrentAddress[0]);
-
-	DBGPRINT_S(Status, ("<==== rt28xx_init, Status=%x\n", Status));
-
-	return TRUE;
-
-err4:
-err3:
-	MlmeHalt(pAd);
-err2:
-	RTMPFreeTxRxRingMemory(pAd);
-err1:
-
-	os_free_mem(pAd, pAd->mpdu_blk_pool.mem);	/* free BA pool */
-
-	/* shall not set priv to NULL here because the priv didn't been free yet. */
-	/*net_dev->ml_priv = 0; */
-#ifdef ST
-err0:
-#endif /* ST // */
-
-	DBGPRINT(RT_DEBUG_ERROR, ("rt28xx Initialized fail!\n"));
-	return FALSE;
-}
-
-/*---Add by shiang, move from os/linux/rt_main_dev.c */
-
-static int RtmpChipOpsRegister(struct rt_rtmp_adapter *pAd, int infType)
-{
-	struct rt_rtmp_chip_op *pChipOps = &pAd->chipOps;
-	int status;
-
-	memset(pChipOps, 0, sizeof(struct rt_rtmp_chip_op));
-
-	/* set eeprom related hook functions */
-	status = RtmpChipOpsEepromHook(pAd, infType);
-
-	/* set mcu related hook functions */
-	switch (infType) {
-#ifdef RTMP_PCI_SUPPORT
-	case RTMP_DEV_INF_PCI:
-		pChipOps->loadFirmware = RtmpAsicLoadFirmware;
-		pChipOps->eraseFirmware = RtmpAsicEraseFirmware;
-		pChipOps->sendCommandToMcu = RtmpAsicSendCommandToMcu;
-		break;
-#endif /* RTMP_PCI_SUPPORT // */
-#ifdef RTMP_USB_SUPPORT
-	case RTMP_DEV_INF_USB:
-		pChipOps->loadFirmware = RtmpAsicLoadFirmware;
-		pChipOps->sendCommandToMcu = RtmpAsicSendCommandToMcu;
-		break;
-#endif /* RTMP_USB_SUPPORT // */
-	default:
-		break;
-	}
-
-	return status;
-}
-
-int RtmpRaDevCtrlInit(struct rt_rtmp_adapter *pAd, IN RTMP_INF_TYPE infType)
-{
-	/*void  *handle; */
-
-	/* Assign the interface type. We need use it when do register/EEPROM access. */
-	pAd->infType = infType;
-
-	pAd->OpMode = OPMODE_STA;
-	DBGPRINT(RT_DEBUG_TRACE,
-		 ("STA Driver version-%s\n", STA_DRIVER_VERSION));
-
-#ifdef RTMP_MAC_USB
-	sema_init(&(pAd->UsbVendorReq_semaphore), 1);
-	os_alloc_mem(pAd, (u8 **) & pAd->UsbVendorReqBuf,
-		     MAX_PARAM_BUFFER_SIZE - 1);
-	if (pAd->UsbVendorReqBuf == NULL) {
-		DBGPRINT(RT_DEBUG_ERROR,
-			 ("Allocate vendor request temp buffer failed!\n"));
-		return FALSE;
-	}
-#endif /* RTMP_MAC_USB // */
-
-	RtmpChipOpsRegister(pAd, infType);
-
-	return 0;
-}
-
-BOOLEAN RtmpRaDevCtrlExit(struct rt_rtmp_adapter *pAd)
-{
-
-	RTMPFreeAdapter(pAd);
-
-	return TRUE;
-}
-
-/* not yet support MBSS */
-struct net_device *get_netdev_from_bssid(struct rt_rtmp_adapter *pAd, u8 FromWhichBSSID)
-{
-	struct net_device *dev_p = NULL;
-
-	{
-		dev_p = pAd->net_dev;
-	}
-
-	ASSERT(dev_p);
-	return dev_p;		/* return one of MBSS */
-}
diff -druN linux-2.6.39-libre/drivers/staging/rt2860/common/rtmp_mcu.c linux-3.0-rc7-libre/drivers/staging/rt2860/common/rtmp_mcu.c
--- linux-2.6.39-libre/drivers/staging/rt2860/common/rtmp_mcu.c	2011-05-19 02:15:51.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rt2860/common/rtmp_mcu.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,336 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, 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.             *
- *                                                                       *
- *************************************************************************
-
-	Module Name:
-	rtmp_mcu.c
-
-	Abstract:
-	Miniport generic portion header file
-
-	Revision History:
-	Who         When          What
-	--------    ----------    ----------------------------------------------
-*/
-
-#include	"../rt_config.h"
-
-#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)*/
-
-#define FIRMWARE_3070_MIN_VERSION	17
-#define FIRMWARE_3070_FILENAME		"/*(DEBLOBBED)*/"
-/*(DEBLOBBED)*/
-
-#define FIRMWARE_3071_MIN_VERSION	17
-#define FIRMWARE_3071_FILENAME		"/*(DEBLOBBED)*/"	/* for RT3071/RT3072 */
-/*(DEBLOBBED)*/
-
-#else /* RTMP_MAC_PCI */
-
-#define FIRMWAREIMAGE_LENGTH		0x2000
-
-#define FIRMWARE_2860_MIN_VERSION	11
-#define FIRMWARE_2860_FILENAME		"/*(DEBLOBBED)*/"
-/*(DEBLOBBED)*/
-
-#define FIRMWARE_3090_MIN_VERSION	19
-#define FIRMWARE_3090_FILENAME		"/*(DEBLOBBED)*/"	/* for RT3090/RT3390 */
-/*(DEBLOBBED)*/
-
-#endif
-
-/*
-	========================================================================
-
-	Routine Description:
-		erase 8051 firmware image in MAC ASIC
-
-	Arguments:
-		Adapter						Pointer to our adapter
-
-	IRQL = PASSIVE_LEVEL
-
-	========================================================================
-*/
-int RtmpAsicEraseFirmware(struct rt_rtmp_adapter *pAd)
-{
-	unsigned long i;
-
-	for (i = 0; i < MAX_FIRMWARE_IMAGE_SIZE; i += 4)
-		RTMP_IO_WRITE32(pAd, FIRMWARE_IMAGE_BASE + i, 0);
-
-	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;
-}
-
-/*
-	========================================================================
-
-	Routine Description:
-		Load 8051 firmware file into MAC ASIC
-
-	Arguments:
-		Adapter						Pointer to our adapter
-
-	Return Value:
-		NDIS_STATUS_SUCCESS         firmware image load ok
-		NDIS_STATUS_FAILURE         image not found
-
-	IRQL = PASSIVE_LEVEL
-
-	========================================================================
-*/
-int RtmpAsicLoadFirmware(struct rt_rtmp_adapter *pAd)
-{
-	const struct firmware *fw;
-	int Status = NDIS_STATUS_SUCCESS;
-	unsigned long Index;
-	u32 MacReg = 0;
-
-	fw = rtmp_get_firmware(pAd);
-	if (!fw)
-		return NDIS_STATUS_FAILURE;
-
-	RTMP_WRITE_FIRMWARE(pAd, fw->data, FIRMWAREIMAGE_LENGTH);
-
-	/* check if MCU is ready */
-	Index = 0;
-	do {
-		RTMP_IO_READ32(pAd, PBF_SYS_CTRL, &MacReg);
-
-		if (MacReg & 0x80)
-			break;
-
-		RTMPusecDelay(1000);
-	} while (Index++ < 1000);
-
-	if (Index > 1000) {
-		DBGPRINT(RT_DEBUG_ERROR,
-			 ("NICLoadFirmware: MCU is not ready\n"));
-		Status = NDIS_STATUS_FAILURE;
-	}
-
-	DBGPRINT(RT_DEBUG_TRACE, ("<=== %s (status=%d)\n", __func__, Status));
-
-	return Status;
-}
-
-int RtmpAsicSendCommandToMcu(struct rt_rtmp_adapter *pAd,
-			     u8 Command,
-			     u8 Token, u8 Arg0, u8 Arg1)
-{
-	HOST_CMD_CSR_STRUC H2MCmd;
-	H2M_MAILBOX_STRUC H2MMailbox;
-	unsigned long i = 0;
-
-#ifdef PCIE_PS_SUPPORT
-	/* 3090F power solution 3 has hw limitation that needs to ban all mcu command */
-	/* when firmware is in radio state.  For other chip doesn't have this limitation. */
-	if (((IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd))
-	     && IS_VERSION_AFTER_F(pAd)) && IS_VERSION_AFTER_F(pAd)
-	    && (pAd->StaCfg.PSControl.field.rt30xxPowerMode == 3)
-	    && (pAd->StaCfg.PSControl.field.EnableNewPS == TRUE)) {
-		RTMP_SEM_LOCK(&pAd->McuCmdLock);
-		if ((pAd->brt30xxBanMcuCmd == TRUE)
-		    && (Command != WAKE_MCU_CMD) && (Command != RFOFF_MCU_CMD)) {
-			RTMP_SEM_UNLOCK(&pAd->McuCmdLock);
-			DBGPRINT(RT_DEBUG_TRACE,
-				 (" Ban Mcu Cmd %x in sleep mode\n", Command));
-			return FALSE;
-		} else if ((Command == SLEEP_MCU_CMD)
-			   || (Command == RFOFF_MCU_CMD)) {
-			pAd->brt30xxBanMcuCmd = TRUE;
-		} else if (Command != WAKE_MCU_CMD) {
-			pAd->brt30xxBanMcuCmd = FALSE;
-		}
-
-		RTMP_SEM_UNLOCK(&pAd->McuCmdLock);
-
-	}
-	if (((IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd))
-	     && IS_VERSION_AFTER_F(pAd)) && IS_VERSION_AFTER_F(pAd)
-	    && (pAd->StaCfg.PSControl.field.rt30xxPowerMode == 3)
-	    && (pAd->StaCfg.PSControl.field.EnableNewPS == TRUE)
-	    && (Command == WAKE_MCU_CMD)) {
-
-		do {
-			RTMP_IO_FORCE_READ32(pAd, H2M_MAILBOX_CSR,
-					     &H2MMailbox.word);
-			if (H2MMailbox.field.Owner == 0)
-				break;
-
-			RTMPusecDelay(2);
-			DBGPRINT(RT_DEBUG_INFO,
-				 ("AsicSendCommanToMcu::Mail box is busy\n"));
-		} while (i++ < 100);
-
-		if (i > 100) {
-			DBGPRINT_ERR("H2M_MAILBOX still hold by MCU. command fail\n");
-			return FALSE;
-		}
-
-		H2MMailbox.field.Owner = 1;	/* pass ownership to MCU */
-		H2MMailbox.field.CmdToken = Token;
-		H2MMailbox.field.HighByte = Arg1;
-		H2MMailbox.field.LowByte = Arg0;
-		RTMP_IO_FORCE_WRITE32(pAd, H2M_MAILBOX_CSR, H2MMailbox.word);
-
-		H2MCmd.word = 0;
-		H2MCmd.field.HostCommand = Command;
-		RTMP_IO_FORCE_WRITE32(pAd, HOST_CMD_CSR, H2MCmd.word);
-
-	} else
-#endif /* PCIE_PS_SUPPORT // */
-	{
-		do {
-			RTMP_IO_READ32(pAd, H2M_MAILBOX_CSR, &H2MMailbox.word);
-			if (H2MMailbox.field.Owner == 0)
-				break;
-
-			RTMPusecDelay(2);
-		} while (i++ < 100);
-
-		if (i > 100) {
-#ifdef RTMP_MAC_PCI
-#endif /* RTMP_MAC_PCI // */
-			{
-				DBGPRINT_ERR("H2M_MAILBOX still hold by MCU. command fail\n");
-			}
-			return FALSE;
-		}
-#ifdef RTMP_MAC_PCI
-#endif /* RTMP_MAC_PCI // */
-
-		H2MMailbox.field.Owner = 1;	/* pass ownership to MCU */
-		H2MMailbox.field.CmdToken = Token;
-		H2MMailbox.field.HighByte = Arg1;
-		H2MMailbox.field.LowByte = Arg0;
-		RTMP_IO_WRITE32(pAd, H2M_MAILBOX_CSR, H2MMailbox.word);
-
-		H2MCmd.word = 0;
-		H2MCmd.field.HostCommand = Command;
-		RTMP_IO_WRITE32(pAd, HOST_CMD_CSR, H2MCmd.word);
-
-		if (Command != 0x80) {
-		}
-	}
-#ifdef PCIE_PS_SUPPORT
-	/* 3090 MCU Wakeup command needs more time to be stable. */
-	/* Before stable, don't issue other MCU command to prevent from firmware error. */
-	if (((IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd))
-	     && IS_VERSION_AFTER_F(pAd)) && IS_VERSION_AFTER_F(pAd)
-	    && (pAd->StaCfg.PSControl.field.rt30xxPowerMode == 3)
-	    && (pAd->StaCfg.PSControl.field.EnableNewPS == TRUE)
-	    && (Command == WAKE_MCU_CMD)) {
-		RTMPusecDelay(2000);
-		/*Put this is after RF programming. */
-		/*NdisAcquireSpinLock(&pAd->McuCmdLock); */
-		/*pAd->brt30xxBanMcuCmd = FALSE; */
-		/*NdisReleaseSpinLock(&pAd->McuCmdLock); */
-	}
-#endif /* PCIE_PS_SUPPORT // */
-
-	return TRUE;
-}
diff -druN linux-2.6.39-libre/drivers/staging/rt2860/common/rtmp_timer.c linux-3.0-rc7-libre/drivers/staging/rt2860/common/rtmp_timer.c
--- linux-2.6.39-libre/drivers/staging/rt2860/common/rtmp_timer.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rt2860/common/rtmp_timer.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,302 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, 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.             *
- *                                                                       *
- *************************************************************************
-
-    Module Name:
-    rtmp_timer.c
-
-    Abstract:
-    task for timer handling
-
-    Revision History:
-    Who         When            What
-    --------    ----------      ----------------------------------------------
-    Name          Date            Modification logs
-    Shiang Tu	08-28-2008   init version
-
-*/
-
-#include "../rt_config.h"
-
-BUILD_TIMER_FUNCTION(MlmePeriodicExec);
-/*BUILD_TIMER_FUNCTION(MlmeRssiReportExec); */
-BUILD_TIMER_FUNCTION(AsicRxAntEvalTimeout);
-BUILD_TIMER_FUNCTION(APSDPeriodicExec);
-BUILD_TIMER_FUNCTION(AsicRfTuningExec);
-#ifdef RTMP_MAC_USB
-BUILD_TIMER_FUNCTION(BeaconUpdateExec);
-#endif /* RTMP_MAC_USB // */
-
-BUILD_TIMER_FUNCTION(BeaconTimeout);
-BUILD_TIMER_FUNCTION(ScanTimeout);
-BUILD_TIMER_FUNCTION(AuthTimeout);
-BUILD_TIMER_FUNCTION(AssocTimeout);
-BUILD_TIMER_FUNCTION(ReassocTimeout);
-BUILD_TIMER_FUNCTION(DisassocTimeout);
-BUILD_TIMER_FUNCTION(LinkDownExec);
-BUILD_TIMER_FUNCTION(StaQuickResponeForRateUpExec);
-BUILD_TIMER_FUNCTION(WpaDisassocApAndBlockAssoc);
-#ifdef RTMP_MAC_PCI
-BUILD_TIMER_FUNCTION(PsPollWakeExec);
-BUILD_TIMER_FUNCTION(RadioOnExec);
-#endif /* RTMP_MAC_PCI // */
-#ifdef RTMP_MAC_USB
-BUILD_TIMER_FUNCTION(RtmpUsbStaAsicForceWakeupTimeout);
-#endif /* RTMP_MAC_USB // */
-
-#if defined(AP_LED) || defined(STA_LED)
-extern void LedCtrlMain(void *SystemSpecific1,
-			void *FunctionContext,
-			void *SystemSpecific2, void *SystemSpecific3);
-BUILD_TIMER_FUNCTION(LedCtrlMain);
-#endif
-
-#ifdef RTMP_TIMER_TASK_SUPPORT
-static void RtmpTimerQHandle(struct rt_rtmp_adapter *pAd)
-{
-#ifndef KTHREAD_SUPPORT
-	int status;
-#endif
-	struct rt_ralink_timer *pTimer;
-	struct rt_rtmp_timer_task_entry *pEntry;
-	unsigned long irqFlag;
-	struct rt_rtmp_os_task *pTask;
-
-	pTask = &pAd->timerTask;
-	while (!pTask->task_killed) {
-		pTimer = NULL;
-
-#ifdef KTHREAD_SUPPORT
-		RTMP_WAIT_EVENT_INTERRUPTIBLE(pAd, pTask);
-#else
-		RTMP_SEM_EVENT_WAIT(&(pTask->taskSema), status);
-#endif
-
-		if (pAd->TimerQ.status == RTMP_TASK_STAT_STOPED)
-			break;
-
-		/* event happened. */
-		while (pAd->TimerQ.pQHead) {
-			RTMP_INT_LOCK(&pAd->TimerQLock, irqFlag);
-			pEntry = pAd->TimerQ.pQHead;
-			if (pEntry) {
-				pTimer = pEntry->pRaTimer;
-
-				/* update pQHead */
-				pAd->TimerQ.pQHead = pEntry->pNext;
-				if (pEntry == pAd->TimerQ.pQTail)
-					pAd->TimerQ.pQTail = NULL;
-
-				/* return this queue entry to timerQFreeList. */
-				pEntry->pNext = pAd->TimerQ.pQPollFreeList;
-				pAd->TimerQ.pQPollFreeList = pEntry;
-			}
-			RTMP_INT_UNLOCK(&pAd->TimerQLock, irqFlag);
-
-			if (pTimer) {
-				if ((pTimer->handle != NULL)
-				    && (!pAd->PM_FlgSuspend))
-					pTimer->handle(NULL,
-						       (void *)pTimer->cookie,
-						       NULL, pTimer);
-				if ((pTimer->Repeat)
-				    && (pTimer->State == FALSE))
-					RTMP_OS_Add_Timer(&pTimer->TimerObj,
-							  pTimer->TimerValue);
-			}
-		}
-
-#ifndef KTHREAD_SUPPORT
-		if (status != 0) {
-			pAd->TimerQ.status = RTMP_TASK_STAT_STOPED;
-			RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS);
-			break;
-		}
-#endif
-	}
-}
-
-int RtmpTimerQThread(IN void *Context)
-{
-	struct rt_rtmp_os_task *pTask;
-	struct rt_rtmp_adapter *pAd;
-
-	pTask = Context;
-	pAd = pTask->priv;
-
-	RtmpOSTaskCustomize(pTask);
-
-	RtmpTimerQHandle(pAd);
-
-	DBGPRINT(RT_DEBUG_TRACE, ("<---%s\n", __func__));
-#ifndef KTHREAD_SUPPORT
-	pTask->taskPID = THREAD_PID_INIT_VALUE;
-#endif
-	/* notify the exit routine that we're actually exiting now
-	 *
-	 * complete()/wait_for_completion() is similar to up()/down(),
-	 * except that complete() is safe in the case where the structure
-	 * is getting deleted in a parallel mode of execution (i.e. just
-	 * after the down() -- that's necessary for the thread-shutdown
-	 * case.
-	 *
-	 * complete_and_exit() goes even further than this -- it is safe in
-	 * the case that the thread of the caller is going away (not just
-	 * the structure) -- this is necessary for the module-remove case.
-	 * This is important in preemption kernels, which transfer the flow
-	 * of execution immediately upon a complete().
-	 */
-	RtmpOSTaskNotifyToExit(pTask);
-
-	return 0;
-
-}
-
-struct rt_rtmp_timer_task_entry *RtmpTimerQInsert(struct rt_rtmp_adapter *pAd,
-					struct rt_ralink_timer *pTimer)
-{
-	struct rt_rtmp_timer_task_entry *pQNode = NULL, *pQTail;
-	unsigned long irqFlags;
-	struct rt_rtmp_os_task *pTask = &pAd->timerTask;
-
-	RTMP_INT_LOCK(&pAd->TimerQLock, irqFlags);
-	if (pAd->TimerQ.status & RTMP_TASK_CAN_DO_INSERT) {
-		if (pAd->TimerQ.pQPollFreeList) {
-			pQNode = pAd->TimerQ.pQPollFreeList;
-			pAd->TimerQ.pQPollFreeList = pQNode->pNext;
-
-			pQNode->pRaTimer = pTimer;
-			pQNode->pNext = NULL;
-
-			pQTail = pAd->TimerQ.pQTail;
-			if (pAd->TimerQ.pQTail != NULL)
-				pQTail->pNext = pQNode;
-			pAd->TimerQ.pQTail = pQNode;
-			if (pAd->TimerQ.pQHead == NULL)
-				pAd->TimerQ.pQHead = pQNode;
-		}
-	}
-	RTMP_INT_UNLOCK(&pAd->TimerQLock, irqFlags);
-
-	if (pQNode) {
-#ifdef KTHREAD_SUPPORT
-		WAKE_UP(pTask);
-#else
-		RTMP_SEM_EVENT_UP(&pTask->taskSema);
-#endif
-	}
-
-	return pQNode;
-}
-
-BOOLEAN RtmpTimerQRemove(struct rt_rtmp_adapter *pAd, struct rt_ralink_timer *pTimer)
-{
-	struct rt_rtmp_timer_task_entry *pNode, *pPrev = NULL;
-	unsigned long irqFlags;
-
-	RTMP_INT_LOCK(&pAd->TimerQLock, irqFlags);
-	if (pAd->TimerQ.status >= RTMP_TASK_STAT_INITED) {
-		pNode = pAd->TimerQ.pQHead;
-		while (pNode) {
-			if (pNode->pRaTimer == pTimer)
-				break;
-			pPrev = pNode;
-			pNode = pNode->pNext;
-		}
-
-		/* Now move it to freeList queue. */
-		if (pNode) {
-			if (pNode == pAd->TimerQ.pQHead)
-				pAd->TimerQ.pQHead = pNode->pNext;
-			if (pNode == pAd->TimerQ.pQTail)
-				pAd->TimerQ.pQTail = pPrev;
-			if (pPrev != NULL)
-				pPrev->pNext = pNode->pNext;
-
-			/* return this queue entry to timerQFreeList. */
-			pNode->pNext = pAd->TimerQ.pQPollFreeList;
-			pAd->TimerQ.pQPollFreeList = pNode;
-		}
-	}
-	RTMP_INT_UNLOCK(&pAd->TimerQLock, irqFlags);
-
-	return TRUE;
-}
-
-void RtmpTimerQExit(struct rt_rtmp_adapter *pAd)
-{
-	struct rt_rtmp_timer_task_entry *pTimerQ;
-	unsigned long irqFlags;
-
-	RTMP_INT_LOCK(&pAd->TimerQLock, irqFlags);
-	while (pAd->TimerQ.pQHead) {
-		pTimerQ = pAd->TimerQ.pQHead;
-		pAd->TimerQ.pQHead = pTimerQ->pNext;
-		/* remove the timeQ */
-	}
-	pAd->TimerQ.pQPollFreeList = NULL;
-	os_free_mem(pAd, pAd->TimerQ.pTimerQPoll);
-	pAd->TimerQ.pQTail = NULL;
-	pAd->TimerQ.pQHead = NULL;
-#ifndef KTHREAD_SUPPORT
-	pAd->TimerQ.status = RTMP_TASK_STAT_STOPED;
-#endif
-	RTMP_INT_UNLOCK(&pAd->TimerQLock, irqFlags);
-
-}
-
-void RtmpTimerQInit(struct rt_rtmp_adapter *pAd)
-{
-	int i;
-	struct rt_rtmp_timer_task_entry *pQNode, *pEntry;
-	unsigned long irqFlags;
-
-	NdisAllocateSpinLock(&pAd->TimerQLock);
-
-	NdisZeroMemory(&pAd->TimerQ, sizeof(pAd->TimerQ));
-
-	os_alloc_mem(pAd, &pAd->TimerQ.pTimerQPoll,
-		     sizeof(struct rt_rtmp_timer_task_entry) * TIMER_QUEUE_SIZE_MAX);
-	if (pAd->TimerQ.pTimerQPoll) {
-		pEntry = NULL;
-		pQNode = (struct rt_rtmp_timer_task_entry *)pAd->TimerQ.pTimerQPoll;
-		NdisZeroMemory(pAd->TimerQ.pTimerQPoll,
-			       sizeof(struct rt_rtmp_timer_task_entry) *
-			       TIMER_QUEUE_SIZE_MAX);
-
-		RTMP_INT_LOCK(&pAd->TimerQLock, irqFlags);
-		for (i = 0; i < TIMER_QUEUE_SIZE_MAX; i++) {
-			pQNode->pNext = pEntry;
-			pEntry = pQNode;
-			pQNode++;
-		}
-		pAd->TimerQ.pQPollFreeList = pEntry;
-		pAd->TimerQ.pQHead = NULL;
-		pAd->TimerQ.pQTail = NULL;
-		pAd->TimerQ.status = RTMP_TASK_STAT_INITED;
-		RTMP_INT_UNLOCK(&pAd->TimerQLock, irqFlags);
-	}
-}
-#endif /* RTMP_TIMER_TASK_SUPPORT // */
diff -druN linux-2.6.39-libre/drivers/staging/rt2860/common/rt_rf.c linux-3.0-rc7-libre/drivers/staging/rt2860/common/rt_rf.c
--- linux-2.6.39-libre/drivers/staging/rt2860/common/rt_rf.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rt2860/common/rt_rf.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,187 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, 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.             *
- *                                                                       *
- *************************************************************************
-
-	Module Name:
-	rt_rf.c
-
-	Abstract:
-	Ralink Wireless driver RF related functions
-
-	Revision History:
-	Who         When          What
-	--------    ----------    ----------------------------------------------
-*/
-
-#include "../rt_config.h"
-
-#ifdef RTMP_RF_RW_SUPPORT
-/*
-	========================================================================
-
-	Routine Description: Write RT30xx RF register through MAC
-
-	Arguments:
-
-	Return Value:
-
-	IRQL =
-
-	Note:
-
-	========================================================================
-*/
-int RT30xxWriteRFRegister(struct rt_rtmp_adapter *pAd,
-				  u8 regID, u8 value)
-{
-	RF_CSR_CFG_STRUC rfcsr;
-	u32 i = 0;
-
-	do {
-		RTMP_IO_READ32(pAd, RF_CSR_CFG, &rfcsr.word);
-
-		if (!rfcsr.field.RF_CSR_KICK)
-			break;
-		i++;
-	}
-	while ((i < RETRY_LIMIT)
-	       && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)));
-
-	if ((i == RETRY_LIMIT)
-	    || (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))) {
-		DBGPRINT_RAW(RT_DEBUG_ERROR,
-			     ("Retry count exhausted or device removed!\n"));
-		return STATUS_UNSUCCESSFUL;
-	}
-
-	rfcsr.field.RF_CSR_WR = 1;
-	rfcsr.field.RF_CSR_KICK = 1;
-	rfcsr.field.TESTCSR_RFACC_REGNUM = regID;
-	rfcsr.field.RF_CSR_DATA = value;
-
-	RTMP_IO_WRITE32(pAd, RF_CSR_CFG, rfcsr.word);
-
-	return NDIS_STATUS_SUCCESS;
-}
-
-/*
-	========================================================================
-
-	Routine Description: Read RT30xx RF register through MAC
-
-	Arguments:
-
-	Return Value:
-
-	IRQL =
-
-	Note:
-
-	========================================================================
-*/
-int RT30xxReadRFRegister(struct rt_rtmp_adapter *pAd,
-				 u8 regID, u8 *pValue)
-{
-	RF_CSR_CFG_STRUC rfcsr;
-	u32 i = 0, k = 0;
-
-	for (i = 0; i < MAX_BUSY_COUNT; i++) {
-		RTMP_IO_READ32(pAd, RF_CSR_CFG, &rfcsr.word);
-
-		if (rfcsr.field.RF_CSR_KICK == BUSY) {
-			continue;
-		}
-		rfcsr.word = 0;
-		rfcsr.field.RF_CSR_WR = 0;
-		rfcsr.field.RF_CSR_KICK = 1;
-		rfcsr.field.TESTCSR_RFACC_REGNUM = regID;
-		RTMP_IO_WRITE32(pAd, RF_CSR_CFG, rfcsr.word);
-		for (k = 0; k < MAX_BUSY_COUNT; k++) {
-			RTMP_IO_READ32(pAd, RF_CSR_CFG, &rfcsr.word);
-
-			if (rfcsr.field.RF_CSR_KICK == IDLE)
-				break;
-		}
-		if ((rfcsr.field.RF_CSR_KICK == IDLE) &&
-		    (rfcsr.field.TESTCSR_RFACC_REGNUM == regID)) {
-			*pValue = (u8)rfcsr.field.RF_CSR_DATA;
-			break;
-		}
-	}
-	if (rfcsr.field.RF_CSR_KICK == BUSY) {
-		DBGPRINT_ERR("RF read R%d=0x%x fail, i[%d], k[%d]\n", regID, rfcsr.word, i, k);
-		return STATUS_UNSUCCESSFUL;
-	}
-
-	return STATUS_SUCCESS;
-}
-
-void NICInitRFRegisters(struct rt_rtmp_adapter *pAd)
-{
-	if (pAd->chipOps.AsicRfInit)
-		pAd->chipOps.AsicRfInit(pAd);
-}
-
-void RtmpChipOpsRFHook(struct rt_rtmp_adapter *pAd)
-{
-	struct rt_rtmp_chip_op *pChipOps = &pAd->chipOps;
-
-	pChipOps->pRFRegTable = NULL;
-	pChipOps->AsicRfInit = NULL;
-	pChipOps->AsicRfTurnOn = NULL;
-	pChipOps->AsicRfTurnOff = NULL;
-	pChipOps->AsicReverseRfFromSleepMode = NULL;
-	pChipOps->AsicHaltAction = NULL;
-	/* We depends on RfICType and MACVersion to assign the corresponding operation callbacks. */
-
-#ifdef RT30xx
-	if (IS_RT30xx(pAd)) {
-		pChipOps->pRFRegTable = RT30xx_RFRegTable;
-		pChipOps->AsicHaltAction = RT30xxHaltAction;
-#ifdef RT3070
-		if ((IS_RT3070(pAd) || IS_RT3071(pAd))
-		    && (pAd->infType == RTMP_DEV_INF_USB)) {
-			pChipOps->AsicRfInit = NICInitRT3070RFRegisters;
-			if (IS_RT3071(pAd)) {
-				pChipOps->AsicRfTurnOff =
-				    RT30xxLoadRFSleepModeSetup;
-				pChipOps->AsicReverseRfFromSleepMode =
-				    RT30xxReverseRFSleepModeSetup;
-			}
-		}
-#endif /* RT3070 // */
-#ifdef RT3090
-		if (IS_RT3090(pAd) && (pAd->infType == RTMP_DEV_INF_PCI)) {
-			pChipOps->AsicRfTurnOff = RT30xxLoadRFSleepModeSetup;
-			pChipOps->AsicRfInit = NICInitRT3090RFRegisters;
-			pChipOps->AsicReverseRfFromSleepMode =
-			    RT30xxReverseRFSleepModeSetup;
-		}
-#endif /* RT3090 // */
-	}
-#endif /* RT30xx // */
-}
-
-#endif /* RTMP_RF_RW_SUPPORT // */
diff -druN linux-2.6.39-libre/drivers/staging/rt2860/common/spectrum.c linux-3.0-rc7-libre/drivers/staging/rt2860/common/spectrum.c
--- linux-2.6.39-libre/drivers/staging/rt2860/common/spectrum.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rt2860/common/spectrum.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,2205 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, 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.             *
- *                                                                       *
- *************************************************************************
-
-    Module Name:
-	action.c
-
-    Abstract:
-    Handle association related requests either from WSTA or from local MLME
-
-    Revision History:
-    Who          When          What
-    ---------    ----------    ----------------------------------------------
-	Fonchi Wu    2008	  	   created for 802.11h
- */
-
-#include "../rt_config.h"
-#include "action.h"
-
-/* The regulatory information in the USA (US) */
-struct rt_dot11_regulatory_information USARegulatoryInfo[] = {
-/*  "regulatory class"  "number of channels"  "Max Tx Pwr"  "channel list" */
-	{0, {0, 0, {0}
-	     }
-	 }
-	,			/* Invlid entry */
-	{1, {4, 16, {36, 40, 44, 48}
-	     }
-	 }
-	,
-	{2, {4, 23, {52, 56, 60, 64}
-	     }
-	 }
-	,
-	{3, {4, 29, {149, 153, 157, 161}
-	     }
-	 }
-	,
-	{4, {11, 23, {100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140}
-	     }
-	 }
-	,
-	{5, {5, 30, {149, 153, 157, 161, 165}
-	     }
-	 }
-	,
-	{6, {10, 14, {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
-	     }
-	 }
-	,
-	{7, {10, 27, {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
-	     }
-	 }
-	,
-	{8, {5, 17, {11, 13, 15, 17, 19}
-	     }
-	 }
-	,
-	{9, {5, 30, {11, 13, 15, 17, 19}
-	     }
-	 }
-	,
-	{10, {2, 20, {21, 25}
-	      }
-	 }
-	,
-	{11, {2, 33, {21, 25}
-	      }
-	 }
-	,
-	{12, {11, 30, {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}
-	      }
-	 }
-};
-
-#define USA_REGULATORY_INFO_SIZE (sizeof(USARegulatoryInfo) / sizeof(struct rt_dot11_regulatory_information))
-
-/* The regulatory information in Europe */
-struct rt_dot11_regulatory_information EuropeRegulatoryInfo[] = {
-/*  "regulatory class"  "number of channels"  "Max Tx Pwr"  "channel list" */
-	{0, {0, 0, {0}
-	     }
-	 }
-	,			/* Invalid entry */
-	{1, {4, 20, {36, 40, 44, 48}
-	     }
-	 }
-	,
-	{2, {4, 20, {52, 56, 60, 64}
-	     }
-	 }
-	,
-	{3, {11, 30, {100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140}
-	     }
-	 }
-	,
-	{4, {13, 20, {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}
-	     }
-	 }
-};
-
-#define EU_REGULATORY_INFO_SIZE (sizeof(EuropeRegulatoryInfo) / sizeof(struct rt_dot11_regulatory_information))
-
-/* The regulatory information in Japan */
-struct rt_dot11_regulatory_information JapanRegulatoryInfo[] = {
-/*  "regulatory class"  "number of channels"  "Max Tx Pwr"  "channel list" */
-	{0, {0, 0, {0}
-	     }
-	 }
-	,			/* Invalid entry */
-	{1, {4, 22, {34, 38, 42, 46}
-	     }
-	 }
-	,
-	{2, {3, 24, {8, 12, 16}
-	     }
-	 }
-	,
-	{3, {3, 24, {8, 12, 16}
-	     }
-	 }
-	,
-	{4, {3, 24, {8, 12, 16}
-	     }
-	 }
-	,
-	{5, {3, 24, {8, 12, 16}
-	     }
-	 }
-	,
-	{6, {3, 22, {8, 12, 16}
-	     }
-	 }
-	,
-	{7, {4, 24, {184, 188, 192, 196}
-	     }
-	 }
-	,
-	{8, {4, 24, {184, 188, 192, 196}
-	     }
-	 }
-	,
-	{9, {4, 24, {184, 188, 192, 196}
-	     }
-	 }
-	,
-	{10, {4, 24, {184, 188, 192, 196}
-	      }
-	 }
-	,
-	{11, {4, 22, {184, 188, 192, 196}
-	      }
-	 }
-	,
-	{12, {4, 24, {7, 8, 9, 11}
-	      }
-	 }
-	,
-	{13, {4, 24, {7, 8, 9, 11}
-	      }
-	 }
-	,
-	{14, {4, 24, {7, 8, 9, 11}
-	      }
-	 }
-	,
-	{15, {4, 24, {7, 8, 9, 11}
-	      }
-	 }
-	,
-	{16, {6, 24, {183, 184, 185, 187, 188, 189}
-	      }
-	 }
-	,
-	{17, {6, 24, {183, 184, 185, 187, 188, 189}
-	      }
-	 }
-	,
-	{18, {6, 24, {183, 184, 185, 187, 188, 189}
-	      }
-	 }
-	,
-	{19, {6, 24, {183, 184, 185, 187, 188, 189}
-	      }
-	 }
-	,
-	{20, {6, 17, {183, 184, 185, 187, 188, 189}
-	      }
-	 }
-	,
-	{21, {6, 24, {6, 7, 8, 9, 10, 11}
-	      }
-	 }
-	,
-	{22, {6, 24, {6, 7, 8, 9, 10, 11}
-	      }
-	 }
-	,
-	{23, {6, 24, {6, 7, 8, 9, 10, 11}
-	      }
-	 }
-	,
-	{24, {6, 24, {6, 7, 8, 9, 10, 11}
-	      }
-	 }
-	,
-	{25, {8, 24, {182, 183, 184, 185, 186, 187, 188, 189}
-	      }
-	 }
-	,
-	{26, {8, 24, {182, 183, 184, 185, 186, 187, 188, 189}
-	      }
-	 }
-	,
-	{27, {8, 24, {182, 183, 184, 185, 186, 187, 188, 189}
-	      }
-	 }
-	,
-	{28, {8, 24, {182, 183, 184, 185, 186, 187, 188, 189}
-	      }
-	 }
-	,
-	{29, {8, 17, {182, 183, 184, 185, 186, 187, 188, 189}
-	      }
-	 }
-	,
-	{30, {13, 23, {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}
-	      }
-	 }
-	,
-	{31, {1, 23, {14}
-	      }
-	 }
-	,
-	{32, {4, 22, {52, 56, 60, 64}
-	      }
-	 }
-};
-
-#define JP_REGULATORY_INFO_SIZE (sizeof(JapanRegulatoryInfo) / sizeof(struct rt_dot11_regulatory_information))
-
-char RTMP_GetTxPwr(struct rt_rtmp_adapter *pAd, IN HTTRANSMIT_SETTING HTTxMode)
-{
-	struct tx_pwr_cfg {
-		u8 Mode;
-		u8 MCS;
-		u16 req;
-		u8 shift;
-		u32 BitMask;
-	};
-
-	u32 Value;
-	int Idx;
-	u8 PhyMode;
-	char CurTxPwr;
-	u8 TxPwrRef = 0;
-	char DaltaPwr;
-	unsigned long TxPwr[5];
-
-	struct tx_pwr_cfg TxPwrCfg[] = {
-		{MODE_CCK, 0, 0, 4, 0x000000f0},
-		{MODE_CCK, 1, 0, 0, 0x0000000f},
-		{MODE_CCK, 2, 0, 12, 0x0000f000},
-		{MODE_CCK, 3, 0, 8, 0x00000f00},
-
-		{MODE_OFDM, 0, 0, 20, 0x00f00000},
-		{MODE_OFDM, 1, 0, 16, 0x000f0000},
-		{MODE_OFDM, 2, 0, 28, 0xf0000000},
-		{MODE_OFDM, 3, 0, 24, 0x0f000000},
-		{MODE_OFDM, 4, 1, 4, 0x000000f0},
-		{MODE_OFDM, 5, 1, 0, 0x0000000f},
-		{MODE_OFDM, 6, 1, 12, 0x0000f000},
-		{MODE_OFDM, 7, 1, 8, 0x00000f00}
-		, {MODE_HTMIX, 0, 1, 20, 0x00f00000},
-		{MODE_HTMIX, 1, 1, 16, 0x000f0000},
-		{MODE_HTMIX, 2, 1, 28, 0xf0000000},
-		{MODE_HTMIX, 3, 1, 24, 0x0f000000},
-		{MODE_HTMIX, 4, 2, 4, 0x000000f0},
-		{MODE_HTMIX, 5, 2, 0, 0x0000000f},
-		{MODE_HTMIX, 6, 2, 12, 0x0000f000},
-		{MODE_HTMIX, 7, 2, 8, 0x00000f00},
-		{MODE_HTMIX, 8, 2, 20, 0x00f00000},
-		{MODE_HTMIX, 9, 2, 16, 0x000f0000},
-		{MODE_HTMIX, 10, 2, 28, 0xf0000000},
-		{MODE_HTMIX, 11, 2, 24, 0x0f000000},
-		{MODE_HTMIX, 12, 3, 4, 0x000000f0},
-		{MODE_HTMIX, 13, 3, 0, 0x0000000f},
-		{MODE_HTMIX, 14, 3, 12, 0x0000f000},
-		{MODE_HTMIX, 15, 3, 8, 0x00000f00}
-	};
-#define MAX_TXPWR_TAB_SIZE (sizeof(TxPwrCfg) / sizeof(struct tx_pwr_cfg))
-
-	CurTxPwr = 19;
-
-	/* check Tx Power setting from UI. */
-	if (pAd->CommonCfg.TxPowerPercentage > 90) ;
-	else if (pAd->CommonCfg.TxPowerPercentage > 60)	/* reduce Pwr for 1 dB. */
-		CurTxPwr -= 1;
-	else if (pAd->CommonCfg.TxPowerPercentage > 30)	/* reduce Pwr for 3 dB. */
-		CurTxPwr -= 3;
-	else if (pAd->CommonCfg.TxPowerPercentage > 15)	/* reduce Pwr for 6 dB. */
-		CurTxPwr -= 6;
-	else if (pAd->CommonCfg.TxPowerPercentage > 9)	/* reduce Pwr for 9 dB. */
-		CurTxPwr -= 9;
-	else			/* reduce Pwr for 12 dB. */
-		CurTxPwr -= 12;
-
-	if (pAd->CommonCfg.BBPCurrentBW == BW_40) {
-		if (pAd->CommonCfg.CentralChannel > 14) {
-			TxPwr[0] = pAd->Tx40MPwrCfgABand[0];
-			TxPwr[1] = pAd->Tx40MPwrCfgABand[1];
-			TxPwr[2] = pAd->Tx40MPwrCfgABand[2];
-			TxPwr[3] = pAd->Tx40MPwrCfgABand[3];
-			TxPwr[4] = pAd->Tx40MPwrCfgABand[4];
-		} else {
-			TxPwr[0] = pAd->Tx40MPwrCfgGBand[0];
-			TxPwr[1] = pAd->Tx40MPwrCfgGBand[1];
-			TxPwr[2] = pAd->Tx40MPwrCfgGBand[2];
-			TxPwr[3] = pAd->Tx40MPwrCfgGBand[3];
-			TxPwr[4] = pAd->Tx40MPwrCfgGBand[4];
-		}
-	} else {
-		if (pAd->CommonCfg.Channel > 14) {
-			TxPwr[0] = pAd->Tx20MPwrCfgABand[0];
-			TxPwr[1] = pAd->Tx20MPwrCfgABand[1];
-			TxPwr[2] = pAd->Tx20MPwrCfgABand[2];
-			TxPwr[3] = pAd->Tx20MPwrCfgABand[3];
-			TxPwr[4] = pAd->Tx20MPwrCfgABand[4];
-		} else {
-			TxPwr[0] = pAd->Tx20MPwrCfgGBand[0];
-			TxPwr[1] = pAd->Tx20MPwrCfgGBand[1];
-			TxPwr[2] = pAd->Tx20MPwrCfgGBand[2];
-			TxPwr[3] = pAd->Tx20MPwrCfgGBand[3];
-			TxPwr[4] = pAd->Tx20MPwrCfgGBand[4];
-		}
-	}
-
-	switch (HTTxMode.field.MODE) {
-	case MODE_CCK:
-	case MODE_OFDM:
-		Value = TxPwr[1];
-		TxPwrRef = (Value & 0x00000f00) >> 8;
-
-		break;
-
-	case MODE_HTMIX:
-	case MODE_HTGREENFIELD:
-		if (pAd->CommonCfg.TxStream == 1) {
-			Value = TxPwr[2];
-			TxPwrRef = (Value & 0x00000f00) >> 8;
-		} else if (pAd->CommonCfg.TxStream == 2) {
-			Value = TxPwr[3];
-			TxPwrRef = (Value & 0x00000f00) >> 8;
-		}
-		break;
-	}
-
-	PhyMode = (HTTxMode.field.MODE == MODE_HTGREENFIELD)
-	    ? MODE_HTMIX : HTTxMode.field.MODE;
-
-	for (Idx = 0; Idx < MAX_TXPWR_TAB_SIZE; Idx++) {
-		if ((TxPwrCfg[Idx].Mode == PhyMode)
-		    && (TxPwrCfg[Idx].MCS == HTTxMode.field.MCS)) {
-			Value = TxPwr[TxPwrCfg[Idx].req];
-			DaltaPwr =
-			    TxPwrRef - (char)((Value & TxPwrCfg[Idx].BitMask)
-					       >> TxPwrCfg[Idx].shift);
-			CurTxPwr -= DaltaPwr;
-			break;
-		}
-	}
-
-	return CurTxPwr;
-}
-
-void MeasureReqTabInit(struct rt_rtmp_adapter *pAd)
-{
-	NdisAllocateSpinLock(&pAd->CommonCfg.MeasureReqTabLock);
-
-	pAd->CommonCfg.pMeasureReqTab =
-	    kmalloc(sizeof(struct rt_measure_req_tab), GFP_ATOMIC);
-	if (pAd->CommonCfg.pMeasureReqTab)
-		NdisZeroMemory(pAd->CommonCfg.pMeasureReqTab,
-			       sizeof(struct rt_measure_req_tab));
-	else
-		DBGPRINT(RT_DEBUG_ERROR,
-			 ("%s Fail to alloc memory for pAd->CommonCfg.pMeasureReqTab.\n",
-			  __func__));
-
-	return;
-}
-
-void MeasureReqTabExit(struct rt_rtmp_adapter *pAd)
-{
-	NdisFreeSpinLock(&pAd->CommonCfg.MeasureReqTabLock);
-
-	kfree(pAd->CommonCfg.pMeasureReqTab);
-	pAd->CommonCfg.pMeasureReqTab = NULL;
-
-	return;
-}
-
-struct rt_measure_req_entry *MeasureReqLookUp(struct rt_rtmp_adapter *pAd, u8 DialogToken)
-{
-	u32 HashIdx;
-	struct rt_measure_req_tab *pTab = pAd->CommonCfg.pMeasureReqTab;
-	struct rt_measure_req_entry *pEntry = NULL;
-	struct rt_measure_req_entry *pPrevEntry = NULL;
-
-	if (pTab == NULL) {
-		DBGPRINT(RT_DEBUG_ERROR,
-			 ("%s: pMeasureReqTab doesn't exist.\n", __func__));
-		return NULL;
-	}
-
-	RTMP_SEM_LOCK(&pAd->CommonCfg.MeasureReqTabLock);
-
-	HashIdx = MQ_DIALOGTOKEN_HASH_INDEX(DialogToken);
-	pEntry = pTab->Hash[HashIdx];
-
-	while (pEntry) {
-		if (pEntry->DialogToken == DialogToken)
-			break;
-		else {
-			pPrevEntry = pEntry;
-			pEntry = pEntry->pNext;
-		}
-	}
-
-	RTMP_SEM_UNLOCK(&pAd->CommonCfg.MeasureReqTabLock);
-
-	return pEntry;
-}
-
-struct rt_measure_req_entry *MeasureReqInsert(struct rt_rtmp_adapter *pAd, u8 DialogToken)
-{
-	int i;
-	unsigned long HashIdx;
-	struct rt_measure_req_tab *pTab = pAd->CommonCfg.pMeasureReqTab;
-	struct rt_measure_req_entry *pEntry = NULL, *pCurrEntry;
-	unsigned long Now;
-
-	if (pTab == NULL) {
-		DBGPRINT(RT_DEBUG_ERROR,
-			 ("%s: pMeasureReqTab doesn't exist.\n", __func__));
-		return NULL;
-	}
-
-	pEntry = MeasureReqLookUp(pAd, DialogToken);
-	if (pEntry == NULL) {
-		RTMP_SEM_LOCK(&pAd->CommonCfg.MeasureReqTabLock);
-		for (i = 0; i < MAX_MEASURE_REQ_TAB_SIZE; i++) {
-			NdisGetSystemUpTime(&Now);
-			pEntry = &pTab->Content[i];
-
-			if ((pEntry->Valid == TRUE)
-			    && RTMP_TIME_AFTER((unsigned long)Now,
-					       (unsigned long)(pEntry->
-							       lastTime +
-							       MQ_REQ_AGE_OUT)))
-			{
-				struct rt_measure_req_entry *pPrevEntry = NULL;
-				unsigned long HashIdx =
-				    MQ_DIALOGTOKEN_HASH_INDEX(pEntry->
-							      DialogToken);
-				struct rt_measure_req_entry *pProbeEntry =
-				    pTab->Hash[HashIdx];
-
-				/* update Hash list */
-				do {
-					if (pProbeEntry == pEntry) {
-						if (pPrevEntry == NULL) {
-							pTab->Hash[HashIdx] =
-							    pEntry->pNext;
-						} else {
-							pPrevEntry->pNext =
-							    pEntry->pNext;
-						}
-						break;
-					}
-
-					pPrevEntry = pProbeEntry;
-					pProbeEntry = pProbeEntry->pNext;
-				} while (pProbeEntry);
-
-				NdisZeroMemory(pEntry,
-					       sizeof(struct rt_measure_req_entry));
-				pTab->Size--;
-
-				break;
-			}
-
-			if (pEntry->Valid == FALSE)
-				break;
-		}
-
-		if (i < MAX_MEASURE_REQ_TAB_SIZE) {
-			NdisGetSystemUpTime(&Now);
-			pEntry->lastTime = Now;
-			pEntry->Valid = TRUE;
-			pEntry->DialogToken = DialogToken;
-			pTab->Size++;
-		} else {
-			pEntry = NULL;
-			DBGPRINT(RT_DEBUG_ERROR,
-				 ("%s: pMeasureReqTab tab full.\n", __func__));
-		}
-
-		/* add this Neighbor entry into HASH table */
-		if (pEntry) {
-			HashIdx = MQ_DIALOGTOKEN_HASH_INDEX(DialogToken);
-			if (pTab->Hash[HashIdx] == NULL) {
-				pTab->Hash[HashIdx] = pEntry;
-			} else {
-				pCurrEntry = pTab->Hash[HashIdx];
-				while (pCurrEntry->pNext != NULL)
-					pCurrEntry = pCurrEntry->pNext;
-				pCurrEntry->pNext = pEntry;
-			}
-		}
-
-		RTMP_SEM_UNLOCK(&pAd->CommonCfg.MeasureReqTabLock);
-	}
-
-	return pEntry;
-}
-
-void MeasureReqDelete(struct rt_rtmp_adapter *pAd, u8 DialogToken)
-{
-	struct rt_measure_req_tab *pTab = pAd->CommonCfg.pMeasureReqTab;
-	struct rt_measure_req_entry *pEntry = NULL;
-
-	if (pTab == NULL) {
-		DBGPRINT(RT_DEBUG_ERROR,
-			 ("%s: pMeasureReqTab doesn't exist.\n", __func__));
-		return;
-	}
-	/* if empty, return */
-	if (pTab->Size == 0) {
-		DBGPRINT(RT_DEBUG_ERROR, ("pMeasureReqTab empty.\n"));
-		return;
-	}
-
-	pEntry = MeasureReqLookUp(pAd, DialogToken);
-	if (pEntry != NULL) {
-		struct rt_measure_req_entry *pPrevEntry = NULL;
-		unsigned long HashIdx = MQ_DIALOGTOKEN_HASH_INDEX(pEntry->DialogToken);
-		struct rt_measure_req_entry *pProbeEntry = pTab->Hash[HashIdx];
-
-		RTMP_SEM_LOCK(&pAd->CommonCfg.MeasureReqTabLock);
-		/* update Hash list */
-		do {
-			if (pProbeEntry == pEntry) {
-				if (pPrevEntry == NULL) {
-					pTab->Hash[HashIdx] = pEntry->pNext;
-				} else {
-					pPrevEntry->pNext = pEntry->pNext;
-				}
-				break;
-			}
-
-			pPrevEntry = pProbeEntry;
-			pProbeEntry = pProbeEntry->pNext;
-		} while (pProbeEntry);
-
-		NdisZeroMemory(pEntry, sizeof(struct rt_measure_req_entry));
-		pTab->Size--;
-
-		RTMP_SEM_UNLOCK(&pAd->CommonCfg.MeasureReqTabLock);
-	}
-
-	return;
-}
-
-void TpcReqTabInit(struct rt_rtmp_adapter *pAd)
-{
-	NdisAllocateSpinLock(&pAd->CommonCfg.TpcReqTabLock);
-
-	pAd->CommonCfg.pTpcReqTab = kmalloc(sizeof(struct rt_tpc_req_tab), GFP_ATOMIC);
-	if (pAd->CommonCfg.pTpcReqTab)
-		NdisZeroMemory(pAd->CommonCfg.pTpcReqTab, sizeof(struct rt_tpc_req_tab));
-	else
-		DBGPRINT(RT_DEBUG_ERROR,
-			 ("%s Fail to alloc memory for pAd->CommonCfg.pTpcReqTab.\n",
-			  __func__));
-
-	return;
-}
-
-void TpcReqTabExit(struct rt_rtmp_adapter *pAd)
-{
-	NdisFreeSpinLock(&pAd->CommonCfg.TpcReqTabLock);
-
-	kfree(pAd->CommonCfg.pTpcReqTab);
-	pAd->CommonCfg.pTpcReqTab = NULL;
-
-	return;
-}
-
-static struct rt_tpc_req_entry *TpcReqLookUp(struct rt_rtmp_adapter *pAd, u8 DialogToken)
-{
-	u32 HashIdx;
-	struct rt_tpc_req_tab *pTab = pAd->CommonCfg.pTpcReqTab;
-	struct rt_tpc_req_entry *pEntry = NULL;
-	struct rt_tpc_req_entry *pPrevEntry = NULL;
-
-	if (pTab == NULL) {
-		DBGPRINT(RT_DEBUG_ERROR,
-			 ("%s: pTpcReqTab doesn't exist.\n", __func__));
-		return NULL;
-	}
-
-	RTMP_SEM_LOCK(&pAd->CommonCfg.TpcReqTabLock);
-
-	HashIdx = TPC_DIALOGTOKEN_HASH_INDEX(DialogToken);
-	pEntry = pTab->Hash[HashIdx];
-
-	while (pEntry) {
-		if (pEntry->DialogToken == DialogToken)
-			break;
-		else {
-			pPrevEntry = pEntry;
-			pEntry = pEntry->pNext;
-		}
-	}
-
-	RTMP_SEM_UNLOCK(&pAd->CommonCfg.TpcReqTabLock);
-
-	return pEntry;
-}
-
-static struct rt_tpc_req_entry *TpcReqInsert(struct rt_rtmp_adapter *pAd, u8 DialogToken)
-{
-	int i;
-	unsigned long HashIdx;
-	struct rt_tpc_req_tab *pTab = pAd->CommonCfg.pTpcReqTab;
-	struct rt_tpc_req_entry *pEntry = NULL, *pCurrEntry;
-	unsigned long Now;
-
-	if (pTab == NULL) {
-		DBGPRINT(RT_DEBUG_ERROR,
-			 ("%s: pTpcReqTab doesn't exist.\n", __func__));
-		return NULL;
-	}
-
-	pEntry = TpcReqLookUp(pAd, DialogToken);
-	if (pEntry == NULL) {
-		RTMP_SEM_LOCK(&pAd->CommonCfg.TpcReqTabLock);
-		for (i = 0; i < MAX_TPC_REQ_TAB_SIZE; i++) {
-			NdisGetSystemUpTime(&Now);
-			pEntry = &pTab->Content[i];
-
-			if ((pEntry->Valid == TRUE)
-			    && RTMP_TIME_AFTER((unsigned long)Now,
-					       (unsigned long)(pEntry->
-							       lastTime +
-							       TPC_REQ_AGE_OUT)))
-			{
-				struct rt_tpc_req_entry *pPrevEntry = NULL;
-				unsigned long HashIdx =
-				    TPC_DIALOGTOKEN_HASH_INDEX(pEntry->
-							       DialogToken);
-				struct rt_tpc_req_entry *pProbeEntry =
-				    pTab->Hash[HashIdx];
-
-				/* update Hash list */
-				do {
-					if (pProbeEntry == pEntry) {
-						if (pPrevEntry == NULL) {
-							pTab->Hash[HashIdx] =
-							    pEntry->pNext;
-						} else {
-							pPrevEntry->pNext =
-							    pEntry->pNext;
-						}
-						break;
-					}
-
-					pPrevEntry = pProbeEntry;
-					pProbeEntry = pProbeEntry->pNext;
-				} while (pProbeEntry);
-
-				NdisZeroMemory(pEntry, sizeof(struct rt_tpc_req_entry));
-				pTab->Size--;
-
-				break;
-			}
-
-			if (pEntry->Valid == FALSE)
-				break;
-		}
-
-		if (i < MAX_TPC_REQ_TAB_SIZE) {
-			NdisGetSystemUpTime(&Now);
-			pEntry->lastTime = Now;
-			pEntry->Valid = TRUE;
-			pEntry->DialogToken = DialogToken;
-			pTab->Size++;
-		} else {
-			pEntry = NULL;
-			DBGPRINT(RT_DEBUG_ERROR,
-				 ("%s: pTpcReqTab tab full.\n", __func__));
-		}
-
-		/* add this Neighbor entry into HASH table */
-		if (pEntry) {
-			HashIdx = TPC_DIALOGTOKEN_HASH_INDEX(DialogToken);
-			if (pTab->Hash[HashIdx] == NULL) {
-				pTab->Hash[HashIdx] = pEntry;
-			} else {
-				pCurrEntry = pTab->Hash[HashIdx];
-				while (pCurrEntry->pNext != NULL)
-					pCurrEntry = pCurrEntry->pNext;
-				pCurrEntry->pNext = pEntry;
-			}
-		}
-
-		RTMP_SEM_UNLOCK(&pAd->CommonCfg.TpcReqTabLock);
-	}
-
-	return pEntry;
-}
-
-static void TpcReqDelete(struct rt_rtmp_adapter *pAd, u8 DialogToken)
-{
-	struct rt_tpc_req_tab *pTab = pAd->CommonCfg.pTpcReqTab;
-	struct rt_tpc_req_entry *pEntry = NULL;
-
-	if (pTab == NULL) {
-		DBGPRINT(RT_DEBUG_ERROR,
-			 ("%s: pTpcReqTab doesn't exist.\n", __func__));
-		return;
-	}
-	/* if empty, return */
-	if (pTab->Size == 0) {
-		DBGPRINT(RT_DEBUG_ERROR, ("pTpcReqTab empty.\n"));
-		return;
-	}
-
-	pEntry = TpcReqLookUp(pAd, DialogToken);
-	if (pEntry != NULL) {
-		struct rt_tpc_req_entry *pPrevEntry = NULL;
-		unsigned long HashIdx = TPC_DIALOGTOKEN_HASH_INDEX(pEntry->DialogToken);
-		struct rt_tpc_req_entry *pProbeEntry = pTab->Hash[HashIdx];
-
-		RTMP_SEM_LOCK(&pAd->CommonCfg.TpcReqTabLock);
-		/* update Hash list */
-		do {
-			if (pProbeEntry == pEntry) {
-				if (pPrevEntry == NULL) {
-					pTab->Hash[HashIdx] = pEntry->pNext;
-				} else {
-					pPrevEntry->pNext = pEntry->pNext;
-				}
-				break;
-			}
-
-			pPrevEntry = pProbeEntry;
-			pProbeEntry = pProbeEntry->pNext;
-		} while (pProbeEntry);
-
-		NdisZeroMemory(pEntry, sizeof(struct rt_tpc_req_entry));
-		pTab->Size--;
-
-		RTMP_SEM_UNLOCK(&pAd->CommonCfg.TpcReqTabLock);
-	}
-
-	return;
-}
-
-/*
-	==========================================================================
-	Description:
-		Get Current TimeS tamp.
-
-	Parametrs:
-
-	Return	: Current Time Stamp.
-	==========================================================================
- */
-static u64 GetCurrentTimeStamp(struct rt_rtmp_adapter *pAd)
-{
-	/* get current time stamp. */
-	return 0;
-}
-
-/*
-	==========================================================================
-	Description:
-		Get Current Transmit Power.
-
-	Parametrs:
-
-	Return	: Current Time Stamp.
-	==========================================================================
- */
-static u8 GetCurTxPwr(struct rt_rtmp_adapter *pAd, u8 Wcid)
-{
-	return 16;		/* 16 dBm */
-}
-
-/*
-	==========================================================================
-	Description:
-		Get Current Transmit Power.
-
-	Parametrs:
-
-	Return	: Current Time Stamp.
-	==========================================================================
- */
-void InsertChannelRepIE(struct rt_rtmp_adapter *pAd,
-			u8 *pFrameBuf,
-			unsigned long *pFrameLen,
-			char *pCountry, u8 RegulatoryClass)
-{
-	unsigned long TempLen;
-	u8 Len;
-	u8 IEId = IE_AP_CHANNEL_REPORT;
-	u8 *pChListPtr = NULL;
-
-	Len = 1;
-	if (strncmp(pCountry, "US", 2) == 0) {
-		if (RegulatoryClass >= USA_REGULATORY_INFO_SIZE) {
-			DBGPRINT(RT_DEBUG_ERROR,
-				 ("%s: USA Unknow Requlatory class (%d)\n",
-				  __func__, RegulatoryClass));
-			return;
-		}
-
-		Len +=
-		    USARegulatoryInfo[RegulatoryClass].ChannelSet.
-		    NumberOfChannels;
-		pChListPtr =
-		    USARegulatoryInfo[RegulatoryClass].ChannelSet.ChannelList;
-	} else if (strncmp(pCountry, "JP", 2) == 0) {
-		if (RegulatoryClass >= JP_REGULATORY_INFO_SIZE) {
-			DBGPRINT(RT_DEBUG_ERROR,
-				 ("%s: JP Unknow Requlatory class (%d)\n",
-				  __func__, RegulatoryClass));
-			return;
-		}
-
-		Len +=
-		    JapanRegulatoryInfo[RegulatoryClass].ChannelSet.
-		    NumberOfChannels;
-		pChListPtr =
-		    JapanRegulatoryInfo[RegulatoryClass].ChannelSet.ChannelList;
-	} else {
-		DBGPRINT(RT_DEBUG_ERROR, ("%s: Unknow Country (%s)\n",
-					  __func__, pCountry));
-		return;
-	}
-
-	MakeOutgoingFrame(pFrameBuf, &TempLen,
-			  1, &IEId,
-			  1, &Len,
-			  1, &RegulatoryClass,
-			  Len - 1, pChListPtr, END_OF_ARGS);
-
-	*pFrameLen = *pFrameLen + TempLen;
-
-	return;
-}
-
-/*
-	==========================================================================
-	Description:
-		Insert Dialog Token into frame.
-
-	Parametrs:
-		1. frame buffer pointer.
-		2. frame length.
-		3. Dialog token.
-
-	Return	: None.
-	==========================================================================
- */
-void InsertDialogToken(struct rt_rtmp_adapter *pAd,
-		       u8 *pFrameBuf,
-		       unsigned long *pFrameLen, u8 DialogToken)
-{
-	unsigned long TempLen;
-	MakeOutgoingFrame(pFrameBuf, &TempLen, 1, &DialogToken, END_OF_ARGS);
-
-	*pFrameLen = *pFrameLen + TempLen;
-
-	return;
-}
-
-/*
-	==========================================================================
-	Description:
-		Insert TPC Request IE into frame.
-
-	Parametrs:
-		1. frame buffer pointer.
-		2. frame length.
-
-	Return	: None.
-	==========================================================================
- */
-static void InsertTpcReqIE(struct rt_rtmp_adapter *pAd,
-			   u8 *pFrameBuf, unsigned long *pFrameLen)
-{
-	unsigned long TempLen;
-	unsigned long Len = 0;
-	u8 ElementID = IE_TPC_REQUEST;
-
-	MakeOutgoingFrame(pFrameBuf, &TempLen,
-			  1, &ElementID, 1, &Len, END_OF_ARGS);
-
-	*pFrameLen = *pFrameLen + TempLen;
-
-	return;
-}
-
-/*
-	==========================================================================
-	Description:
-		Insert TPC Report IE into frame.
-
-	Parametrs:
-		1. frame buffer pointer.
-		2. frame length.
-		3. Transmit Power.
-		4. Link Margin.
-
-	Return	: None.
-	==========================================================================
- */
-void InsertTpcReportIE(struct rt_rtmp_adapter *pAd,
-		       u8 *pFrameBuf,
-		       unsigned long *pFrameLen,
-		       u8 TxPwr, u8 LinkMargin)
-{
-	unsigned long TempLen;
-	unsigned long Len = sizeof(struct rt_tpc_report_info);
-	u8 ElementID = IE_TPC_REPORT;
-	struct rt_tpc_report_info TpcReportIE;
-
-	TpcReportIE.TxPwr = TxPwr;
-	TpcReportIE.LinkMargin = LinkMargin;
-
-	MakeOutgoingFrame(pFrameBuf, &TempLen,
-			  1, &ElementID,
-			  1, &Len, Len, &TpcReportIE, END_OF_ARGS);
-
-	*pFrameLen = *pFrameLen + TempLen;
-
-	return;
-}
-
-/*
-	==========================================================================
-	Description:
-		Insert Channel Switch Announcement IE into frame.
-
-	Parametrs:
-		1. frame buffer pointer.
-		2. frame length.
-		3. channel switch announcement mode.
-		4. new selected channel.
-		5. channel switch announcement count.
-
-	Return	: None.
-	==========================================================================
- */
-static void InsertChSwAnnIE(struct rt_rtmp_adapter *pAd,
-			    u8 *pFrameBuf,
-			    unsigned long *pFrameLen,
-			    u8 ChSwMode,
-			    u8 NewChannel, u8 ChSwCnt)
-{
-	unsigned long TempLen;
-	unsigned long Len = sizeof(struct rt_ch_sw_ann_info);
-	u8 ElementID = IE_CHANNEL_SWITCH_ANNOUNCEMENT;
-	struct rt_ch_sw_ann_info ChSwAnnIE;
-
-	ChSwAnnIE.ChSwMode = ChSwMode;
-	ChSwAnnIE.Channel = NewChannel;
-	ChSwAnnIE.ChSwCnt = ChSwCnt;
-
-	MakeOutgoingFrame(pFrameBuf, &TempLen,
-			  1, &ElementID, 1, &Len, Len, &ChSwAnnIE, END_OF_ARGS);
-
-	*pFrameLen = *pFrameLen + TempLen;
-
-	return;
-}
-
-/*
-	==========================================================================
-	Description:
-		Insert Measure Request IE into frame.
-
-	Parametrs:
-		1. frame buffer pointer.
-		2. frame length.
-		3. Measure Token.
-		4. Measure Request Mode.
-		5. Measure Request Type.
-		6. Measure Channel.
-		7. Measure Start time.
-		8. Measure Duration.
-
-	Return	: None.
-	==========================================================================
- */
-static void InsertMeasureReqIE(struct rt_rtmp_adapter *pAd,
-			       u8 *pFrameBuf,
-			       unsigned long *pFrameLen,
-			       u8 Len, struct rt_measure_req_info * pMeasureReqIE)
-{
-	unsigned long TempLen;
-	u8 ElementID = IE_MEASUREMENT_REQUEST;
-
-	MakeOutgoingFrame(pFrameBuf, &TempLen,
-			  1, &ElementID,
-			  1, &Len,
-			  sizeof(struct rt_measure_req_info), pMeasureReqIE, END_OF_ARGS);
-
-	*pFrameLen = *pFrameLen + TempLen;
-
-	return;
-}
-
-/*
-	==========================================================================
-	Description:
-		Insert Measure Report IE into frame.
-
-	Parametrs:
-		1. frame buffer pointer.
-		2. frame length.
-		3. Measure Token.
-		4. Measure Request Mode.
-		5. Measure Request Type.
-		6. Length of Report Information
-		7. Pointer of Report Information Buffer.
-
-	Return	: None.
-	==========================================================================
- */
-static void InsertMeasureReportIE(struct rt_rtmp_adapter *pAd,
-				  u8 *pFrameBuf,
-				  unsigned long *pFrameLen,
-				  struct rt_measure_report_info * pMeasureReportIE,
-				  u8 ReportLnfoLen, u8 *pReportInfo)
-{
-	unsigned long TempLen;
-	unsigned long Len;
-	u8 ElementID = IE_MEASUREMENT_REPORT;
-
-	Len = sizeof(struct rt_measure_report_info) + ReportLnfoLen;
-
-	MakeOutgoingFrame(pFrameBuf, &TempLen,
-			  1, &ElementID,
-			  1, &Len, Len, pMeasureReportIE, END_OF_ARGS);
-
-	*pFrameLen = *pFrameLen + TempLen;
-
-	if ((ReportLnfoLen > 0) && (pReportInfo != NULL)) {
-		MakeOutgoingFrame(pFrameBuf + *pFrameLen, &TempLen,
-				  ReportLnfoLen, pReportInfo, END_OF_ARGS);
-
-		*pFrameLen = *pFrameLen + TempLen;
-	}
-	return;
-}
-
-/*
-	==========================================================================
-	Description:
-		Prepare Measurement request action frame and enqueue it into
-		management queue waiting for transmition.
-
-	Parametrs:
-		1. the destination mac address of the frame.
-
-	Return	: None.
-	==========================================================================
- */
-void MakeMeasurementReqFrame(struct rt_rtmp_adapter *pAd,
-			     u8 *pOutBuffer,
-			     unsigned long *pFrameLen,
-			     u8 TotalLen,
-			     u8 Category,
-			     u8 Action,
-			     u8 MeasureToken,
-			     u8 MeasureReqMode,
-			     u8 MeasureReqType, u8 NumOfRepetitions)
-{
-	unsigned long TempLen;
-	struct rt_measure_req_info MeasureReqIE;
-
-	InsertActField(pAd, (pOutBuffer + *pFrameLen), pFrameLen, Category,
-		       Action);
-
-	/* fill Dialog Token */
-	InsertDialogToken(pAd, (pOutBuffer + *pFrameLen), pFrameLen,
-			  MeasureToken);
-
-	/* fill Number of repetitions. */
-	if (Category == CATEGORY_RM) {
-		MakeOutgoingFrame((pOutBuffer + *pFrameLen), &TempLen,
-				  2, &NumOfRepetitions, END_OF_ARGS);
-
-		*pFrameLen += TempLen;
-	}
-	/* prepare Measurement IE. */
-	NdisZeroMemory(&MeasureReqIE, sizeof(struct rt_measure_req_info));
-	MeasureReqIE.Token = MeasureToken;
-	MeasureReqIE.ReqMode.word = MeasureReqMode;
-	MeasureReqIE.ReqType = MeasureReqType;
-	InsertMeasureReqIE(pAd, (pOutBuffer + *pFrameLen), pFrameLen,
-			   TotalLen, &MeasureReqIE);
-
-	return;
-}
-
-/*
-	==========================================================================
-	Description:
-		Prepare Measurement report action frame and enqueue it into
-		management queue waiting for transmition.
-
-	Parametrs:
-		1. the destination mac address of the frame.
-
-	Return	: None.
-	==========================================================================
- */
-void EnqueueMeasurementRep(struct rt_rtmp_adapter *pAd,
-			   u8 *pDA,
-			   u8 DialogToken,
-			   u8 MeasureToken,
-			   u8 MeasureReqMode,
-			   u8 MeasureReqType,
-			   u8 ReportInfoLen, u8 *pReportInfo)
-{
-	u8 *pOutBuffer = NULL;
-	int NStatus;
-	unsigned long FrameLen;
-	struct rt_header_802_11 ActHdr;
-	struct rt_measure_report_info MeasureRepIE;
-
-	/* build action frame header. */
-	MgtMacHeaderInit(pAd, &ActHdr, SUBTYPE_ACTION, 0, pDA,
-			 pAd->CurrentAddress);
-
-	NStatus = MlmeAllocateMemory(pAd, (void *)& pOutBuffer);	/*Get an unused nonpaged memory */
-	if (NStatus != NDIS_STATUS_SUCCESS) {
-		DBGPRINT(RT_DEBUG_TRACE,
-			 ("%s() allocate memory failed \n", __func__));
-		return;
-	}
-	NdisMoveMemory(pOutBuffer, (char *)& ActHdr, sizeof(struct rt_header_802_11));
-	FrameLen = sizeof(struct rt_header_802_11);
-
-	InsertActField(pAd, (pOutBuffer + FrameLen), &FrameLen,
-		       CATEGORY_SPECTRUM, SPEC_MRP);
-
-	/* fill Dialog Token */
-	InsertDialogToken(pAd, (pOutBuffer + FrameLen), &FrameLen, DialogToken);
-
-	/* prepare Measurement IE. */
-	NdisZeroMemory(&MeasureRepIE, sizeof(struct rt_measure_report_info));
-	MeasureRepIE.Token = MeasureToken;
-	MeasureRepIE.ReportMode = MeasureReqMode;
-	MeasureRepIE.ReportType = MeasureReqType;
-	InsertMeasureReportIE(pAd, (pOutBuffer + FrameLen), &FrameLen,
-			      &MeasureRepIE, ReportInfoLen, pReportInfo);
-
-	MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
-	MlmeFreeMemory(pAd, pOutBuffer);
-
-	return;
-}
-
-/*
-	==========================================================================
-	Description:
-		Prepare TPC Request action frame and enqueue it into
-		management queue waiting for transmition.
-
-	Parametrs:
-		1. the destination mac address of the frame.
-
-	Return	: None.
-	==========================================================================
- */
-void EnqueueTPCReq(struct rt_rtmp_adapter *pAd, u8 *pDA, u8 DialogToken)
-{
-	u8 *pOutBuffer = NULL;
-	int NStatus;
-	unsigned long FrameLen;
-
-	struct rt_header_802_11 ActHdr;
-
-	/* build action frame header. */
-	MgtMacHeaderInit(pAd, &ActHdr, SUBTYPE_ACTION, 0, pDA,
-			 pAd->CurrentAddress);
-
-	NStatus = MlmeAllocateMemory(pAd, (void *)& pOutBuffer);	/*Get an unused nonpaged memory */
-	if (NStatus != NDIS_STATUS_SUCCESS) {
-		DBGPRINT(RT_DEBUG_TRACE,
-			 ("%s() allocate memory failed \n", __func__));
-		return;
-	}
-	NdisMoveMemory(pOutBuffer, (char *)& ActHdr, sizeof(struct rt_header_802_11));
-	FrameLen = sizeof(struct rt_header_802_11);
-
-	InsertActField(pAd, (pOutBuffer + FrameLen), &FrameLen,
-		       CATEGORY_SPECTRUM, SPEC_TPCRQ);
-
-	/* fill Dialog Token */
-	InsertDialogToken(pAd, (pOutBuffer + FrameLen), &FrameLen, DialogToken);
-
-	/* Insert TPC Request IE. */
-	InsertTpcReqIE(pAd, (pOutBuffer + FrameLen), &FrameLen);
-
-	MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
-	MlmeFreeMemory(pAd, pOutBuffer);
-
-	return;
-}
-
-/*
-	==========================================================================
-	Description:
-		Prepare TPC Report action frame and enqueue it into
-		management queue waiting for transmition.
-
-	Parametrs:
-		1. the destination mac address of the frame.
-
-	Return	: None.
-	==========================================================================
- */
-void EnqueueTPCRep(struct rt_rtmp_adapter *pAd,
-		   u8 *pDA,
-		   u8 DialogToken, u8 TxPwr, u8 LinkMargin)
-{
-	u8 *pOutBuffer = NULL;
-	int NStatus;
-	unsigned long FrameLen;
-
-	struct rt_header_802_11 ActHdr;
-
-	/* build action frame header. */
-	MgtMacHeaderInit(pAd, &ActHdr, SUBTYPE_ACTION, 0, pDA,
-			 pAd->CurrentAddress);
-
-	NStatus = MlmeAllocateMemory(pAd, (void *)& pOutBuffer);	/*Get an unused nonpaged memory */
-	if (NStatus != NDIS_STATUS_SUCCESS) {
-		DBGPRINT(RT_DEBUG_TRACE,
-			 ("%s() allocate memory failed \n", __func__));
-		return;
-	}
-	NdisMoveMemory(pOutBuffer, (char *)& ActHdr, sizeof(struct rt_header_802_11));
-	FrameLen = sizeof(struct rt_header_802_11);
-
-	InsertActField(pAd, (pOutBuffer + FrameLen), &FrameLen,
-		       CATEGORY_SPECTRUM, SPEC_TPCRP);
-
-	/* fill Dialog Token */
-	InsertDialogToken(pAd, (pOutBuffer + FrameLen), &FrameLen, DialogToken);
-
-	/* Insert TPC Request IE. */
-	InsertTpcReportIE(pAd, (pOutBuffer + FrameLen), &FrameLen, TxPwr,
-			  LinkMargin);
-
-	MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
-	MlmeFreeMemory(pAd, pOutBuffer);
-
-	return;
-}
-
-/*
-	==========================================================================
-	Description:
-		Prepare Channel Switch Announcement action frame and enqueue it into
-		management queue waiting for transmition.
-
-	Parametrs:
-		1. the destination mac address of the frame.
-		2. Channel switch announcement mode.
-		2. a New selected channel.
-
-	Return	: None.
-	==========================================================================
- */
-void EnqueueChSwAnn(struct rt_rtmp_adapter *pAd,
-		    u8 *pDA, u8 ChSwMode, u8 NewCh)
-{
-	u8 *pOutBuffer = NULL;
-	int NStatus;
-	unsigned long FrameLen;
-
-	struct rt_header_802_11 ActHdr;
-
-	/* build action frame header. */
-	MgtMacHeaderInit(pAd, &ActHdr, SUBTYPE_ACTION, 0, pDA,
-			 pAd->CurrentAddress);
-
-	NStatus = MlmeAllocateMemory(pAd, (void *)& pOutBuffer);	/*Get an unused nonpaged memory */
-	if (NStatus != NDIS_STATUS_SUCCESS) {
-		DBGPRINT(RT_DEBUG_TRACE,
-			 ("%s() allocate memory failed \n", __func__));
-		return;
-	}
-	NdisMoveMemory(pOutBuffer, (char *)& ActHdr, sizeof(struct rt_header_802_11));
-	FrameLen = sizeof(struct rt_header_802_11);
-
-	InsertActField(pAd, (pOutBuffer + FrameLen), &FrameLen,
-		       CATEGORY_SPECTRUM, SPEC_CHANNEL_SWITCH);
-
-	InsertChSwAnnIE(pAd, (pOutBuffer + FrameLen), &FrameLen, ChSwMode,
-			NewCh, 0);
-
-	MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
-	MlmeFreeMemory(pAd, pOutBuffer);
-
-	return;
-}
-
-static BOOLEAN DfsRequirementCheck(struct rt_rtmp_adapter *pAd, u8 Channel)
-{
-	BOOLEAN Result = FALSE;
-	int i;
-
-	do {
-		/* check DFS procedure is running. */
-		/* make sure DFS procedure won't start twice. */
-		if (pAd->CommonCfg.RadarDetect.RDMode != RD_NORMAL_MODE) {
-			Result = FALSE;
-			break;
-		}
-		/* check the new channel carried from Channel Switch Announcemnet is valid. */
-		for (i = 0; i < pAd->ChannelListNum; i++) {
-			if ((Channel == pAd->ChannelList[i].Channel)
-			    && (pAd->ChannelList[i].RemainingTimeForUse == 0)) {
-				/* found radar signal in the channel. the channel can't use at least for 30 minutes. */
-				pAd->ChannelList[i].RemainingTimeForUse = 1800;	/*30 min = 1800 sec */
-				Result = TRUE;
-				break;
-			}
-		}
-	} while (FALSE);
-
-	return Result;
-}
-
-void NotifyChSwAnnToPeerAPs(struct rt_rtmp_adapter *pAd,
-			    u8 *pRA,
-			    u8 *pTA, u8 ChSwMode, u8 Channel)
-{
-}
-
-static void StartDFSProcedure(struct rt_rtmp_adapter *pAd,
-			      u8 Channel, u8 ChSwMode)
-{
-	/* start DFS procedure */
-	pAd->CommonCfg.Channel = Channel;
-
-	N_ChannelCheck(pAd);
-
-	pAd->CommonCfg.RadarDetect.RDMode = RD_SWITCHING_MODE;
-	pAd->CommonCfg.RadarDetect.CSCount = 0;
-}
-
-/*
-	==========================================================================
-	Description:
-		Channel Switch Announcement action frame sanity check.
-
-	Parametrs:
-		1. MLME message containing the received frame
-		2. message length.
-		3. Channel switch announcement information buffer.
-
-	Return	: None.
-	==========================================================================
- */
-
-/*
-  Channel Switch Announcement IE.
-  +----+-----+-----------+------------+-----------+
-  | ID | Len |Ch Sw Mode | New Ch Num | Ch Sw Cnt |
-  +----+-----+-----------+------------+-----------+
-    1    1        1           1            1
-*/
-static BOOLEAN PeerChSwAnnSanity(struct rt_rtmp_adapter *pAd,
-				 void * pMsg,
-				 unsigned long MsgLen,
-				 struct rt_ch_sw_ann_info * pChSwAnnInfo)
-{
-	struct rt_frame_802_11 * Fr = (struct rt_frame_802_11 *) pMsg;
-	u8 *pFramePtr = Fr->Octet;
-	BOOLEAN result = FALSE;
-	struct rt_eid * eid_ptr;
-
-	/* skip 802.11 header. */
-	MsgLen -= sizeof(struct rt_header_802_11);
-
-	/* skip category and action code. */
-	pFramePtr += 2;
-	MsgLen -= 2;
-
-	if (pChSwAnnInfo == NULL)
-		return result;
-
-	eid_ptr = (struct rt_eid *) pFramePtr;
-	while (((u8 *) eid_ptr + eid_ptr->Len + 1) <
-	       ((u8 *)pFramePtr + MsgLen)) {
-		switch (eid_ptr->Eid) {
-		case IE_CHANNEL_SWITCH_ANNOUNCEMENT:
-			NdisMoveMemory(&pChSwAnnInfo->ChSwMode, eid_ptr->Octet,
-				       1);
-			NdisMoveMemory(&pChSwAnnInfo->Channel,
-				       eid_ptr->Octet + 1, 1);
-			NdisMoveMemory(&pChSwAnnInfo->ChSwCnt,
-				       eid_ptr->Octet + 2, 1);
-
-			result = TRUE;
-			break;
-
-		default:
-			break;
-		}
-		eid_ptr = (struct rt_eid *) ((u8 *) eid_ptr + 2 + eid_ptr->Len);
-	}
-
-	return result;
-}
-
-/*
-	==========================================================================
-	Description:
-		Measurement request action frame sanity check.
-
-	Parametrs:
-		1. MLME message containing the received frame
-		2. message length.
-		3. Measurement request information buffer.
-
-	Return	: None.
-	==========================================================================
- */
-static BOOLEAN PeerMeasureReqSanity(struct rt_rtmp_adapter *pAd,
-				    void * pMsg,
-				    unsigned long MsgLen,
-				    u8 *pDialogToken,
-				    struct rt_measure_req_info * pMeasureReqInfo,
-				    struct rt_measure_req * pMeasureReq)
-{
-	struct rt_frame_802_11 * Fr = (struct rt_frame_802_11 *) pMsg;
-	u8 *pFramePtr = Fr->Octet;
-	BOOLEAN result = FALSE;
-	struct rt_eid * eid_ptr;
-	u8 *ptr;
-	u64 MeasureStartTime;
-	u16 MeasureDuration;
-
-	/* skip 802.11 header. */
-	MsgLen -= sizeof(struct rt_header_802_11);
-
-	/* skip category and action code. */
-	pFramePtr += 2;
-	MsgLen -= 2;
-
-	if (pMeasureReqInfo == NULL)
-		return result;
-
-	NdisMoveMemory(pDialogToken, pFramePtr, 1);
-	pFramePtr += 1;
-	MsgLen -= 1;
-
-	eid_ptr = (struct rt_eid *) pFramePtr;
-	while (((u8 *) eid_ptr + eid_ptr->Len + 1) <
-	       ((u8 *)pFramePtr + MsgLen)) {
-		switch (eid_ptr->Eid) {
-		case IE_MEASUREMENT_REQUEST:
-			NdisMoveMemory(&pMeasureReqInfo->Token, eid_ptr->Octet,
-				       1);
-			NdisMoveMemory(&pMeasureReqInfo->ReqMode.word,
-				       eid_ptr->Octet + 1, 1);
-			NdisMoveMemory(&pMeasureReqInfo->ReqType,
-				       eid_ptr->Octet + 2, 1);
-			ptr = (u8 *)(eid_ptr->Octet + 3);
-			NdisMoveMemory(&pMeasureReq->ChNum, ptr, 1);
-			NdisMoveMemory(&MeasureStartTime, ptr + 1, 8);
-			pMeasureReq->MeasureStartTime =
-			    SWAP64(MeasureStartTime);
-			NdisMoveMemory(&MeasureDuration, ptr + 9, 2);
-			pMeasureReq->MeasureDuration = SWAP16(MeasureDuration);
-
-			result = TRUE;
-			break;
-
-		default:
-			break;
-		}
-		eid_ptr = (struct rt_eid *) ((u8 *) eid_ptr + 2 + eid_ptr->Len);
-	}
-
-	return result;
-}
-
-/*
-	==========================================================================
-	Description:
-		Measurement report action frame sanity check.
-
-	Parametrs:
-		1. MLME message containing the received frame
-		2. message length.
-		3. Measurement report information buffer.
-		4. basic report information buffer.
-
-	Return	: None.
-	==========================================================================
- */
-
-/*
-  Measurement Report IE.
-  +----+-----+-------+-------------+--------------+----------------+
-  | ID | Len | Token | Report Mode | Measure Type | Measure Report |
-  +----+-----+-------+-------------+--------------+----------------+
-    1     1      1          1             1            variable
-
-  Basic Report.
-  +--------+------------+----------+-----+
-  | Ch Num | Start Time | Duration | Map |
-  +--------+------------+----------+-----+
-      1          8           2        1
-
-  Map Field Bit Format.
-  +-----+---------------+---------------------+-------+------------+----------+
-  | Bss | OFDM Preamble | Unidentified signal | Radar | Unmeasured | Reserved |
-  +-----+---------------+---------------------+-------+------------+----------+
-     0          1                  2              3         4          5-7
-*/
-static BOOLEAN PeerMeasureReportSanity(struct rt_rtmp_adapter *pAd,
-				       void * pMsg,
-				       unsigned long MsgLen,
-				       u8 *pDialogToken,
-				       struct rt_measure_report_info *
-				       pMeasureReportInfo,
-				       u8 *pReportBuf)
-{
-	struct rt_frame_802_11 * Fr = (struct rt_frame_802_11 *) pMsg;
-	u8 *pFramePtr = Fr->Octet;
-	BOOLEAN result = FALSE;
-	struct rt_eid * eid_ptr;
-	u8 *ptr;
-
-	/* skip 802.11 header. */
-	MsgLen -= sizeof(struct rt_header_802_11);
-
-	/* skip category and action code. */
-	pFramePtr += 2;
-	MsgLen -= 2;
-
-	if (pMeasureReportInfo == NULL)
-		return result;
-
-	NdisMoveMemory(pDialogToken, pFramePtr, 1);
-	pFramePtr += 1;
-	MsgLen -= 1;
-
-	eid_ptr = (struct rt_eid *) pFramePtr;
-	while (((u8 *) eid_ptr + eid_ptr->Len + 1) <
-	       ((u8 *)pFramePtr + MsgLen)) {
-		switch (eid_ptr->Eid) {
-		case IE_MEASUREMENT_REPORT:
-			NdisMoveMemory(&pMeasureReportInfo->Token,
-				       eid_ptr->Octet, 1);
-			NdisMoveMemory(&pMeasureReportInfo->ReportMode,
-				       eid_ptr->Octet + 1, 1);
-			NdisMoveMemory(&pMeasureReportInfo->ReportType,
-				       eid_ptr->Octet + 2, 1);
-			if (pMeasureReportInfo->ReportType == RM_BASIC) {
-				struct rt_measure_basic_report * pReport =
-				    (struct rt_measure_basic_report *) pReportBuf;
-				ptr = (u8 *)(eid_ptr->Octet + 3);
-				NdisMoveMemory(&pReport->ChNum, ptr, 1);
-				NdisMoveMemory(&pReport->MeasureStartTime,
-					       ptr + 1, 8);
-				NdisMoveMemory(&pReport->MeasureDuration,
-					       ptr + 9, 2);
-				NdisMoveMemory(&pReport->Map, ptr + 11, 1);
-
-			} else if (pMeasureReportInfo->ReportType == RM_CCA) {
-				struct rt_measure_cca_report * pReport =
-				    (struct rt_measure_cca_report *) pReportBuf;
-				ptr = (u8 *)(eid_ptr->Octet + 3);
-				NdisMoveMemory(&pReport->ChNum, ptr, 1);
-				NdisMoveMemory(&pReport->MeasureStartTime,
-					       ptr + 1, 8);
-				NdisMoveMemory(&pReport->MeasureDuration,
-					       ptr + 9, 2);
-				NdisMoveMemory(&pReport->CCA_Busy_Fraction,
-					       ptr + 11, 1);
-
-			} else if (pMeasureReportInfo->ReportType ==
-				   RM_RPI_HISTOGRAM) {
-				struct rt_measure_rpi_report * pReport =
-				    (struct rt_measure_rpi_report *) pReportBuf;
-				ptr = (u8 *)(eid_ptr->Octet + 3);
-				NdisMoveMemory(&pReport->ChNum, ptr, 1);
-				NdisMoveMemory(&pReport->MeasureStartTime,
-					       ptr + 1, 8);
-				NdisMoveMemory(&pReport->MeasureDuration,
-					       ptr + 9, 2);
-				NdisMoveMemory(&pReport->RPI_Density, ptr + 11,
-					       8);
-			}
-			result = TRUE;
-			break;
-
-		default:
-			break;
-		}
-		eid_ptr = (struct rt_eid *) ((u8 *) eid_ptr + 2 + eid_ptr->Len);
-	}
-
-	return result;
-}
-
-/*
-	==========================================================================
-	Description:
-		TPC Request action frame sanity check.
-
-	Parametrs:
-		1. MLME message containing the received frame
-		2. message length.
-		3. Dialog Token.
-
-	Return	: None.
-	==========================================================================
- */
-static BOOLEAN PeerTpcReqSanity(struct rt_rtmp_adapter *pAd,
-				void * pMsg,
-				unsigned long MsgLen, u8 *pDialogToken)
-{
-	struct rt_frame_802_11 * Fr = (struct rt_frame_802_11 *) pMsg;
-	u8 *pFramePtr = Fr->Octet;
-	BOOLEAN result = FALSE;
-	struct rt_eid * eid_ptr;
-
-	MsgLen -= sizeof(struct rt_header_802_11);
-
-	/* skip category and action code. */
-	pFramePtr += 2;
-	MsgLen -= 2;
-
-	if (pDialogToken == NULL)
-		return result;
-
-	NdisMoveMemory(pDialogToken, pFramePtr, 1);
-	pFramePtr += 1;
-	MsgLen -= 1;
-
-	eid_ptr = (struct rt_eid *) pFramePtr;
-	while (((u8 *) eid_ptr + eid_ptr->Len + 1) <
-	       ((u8 *)pFramePtr + MsgLen)) {
-		switch (eid_ptr->Eid) {
-		case IE_TPC_REQUEST:
-			result = TRUE;
-			break;
-
-		default:
-			break;
-		}
-		eid_ptr = (struct rt_eid *) ((u8 *) eid_ptr + 2 + eid_ptr->Len);
-	}
-
-	return result;
-}
-
-/*
-	==========================================================================
-	Description:
-		TPC Report action frame sanity check.
-
-	Parametrs:
-		1. MLME message containing the received frame
-		2. message length.
-		3. Dialog Token.
-		4. TPC Report IE.
-
-	Return	: None.
-	==========================================================================
- */
-static BOOLEAN PeerTpcRepSanity(struct rt_rtmp_adapter *pAd,
-				void * pMsg,
-				unsigned long MsgLen,
-				u8 *pDialogToken,
-				struct rt_tpc_report_info * pTpcRepInfo)
-{
-	struct rt_frame_802_11 * Fr = (struct rt_frame_802_11 *) pMsg;
-	u8 *pFramePtr = Fr->Octet;
-	BOOLEAN result = FALSE;
-	struct rt_eid * eid_ptr;
-
-	MsgLen -= sizeof(struct rt_header_802_11);
-
-	/* skip category and action code. */
-	pFramePtr += 2;
-	MsgLen -= 2;
-
-	if (pDialogToken == NULL)
-		return result;
-
-	NdisMoveMemory(pDialogToken, pFramePtr, 1);
-	pFramePtr += 1;
-	MsgLen -= 1;
-
-	eid_ptr = (struct rt_eid *) pFramePtr;
-	while (((u8 *) eid_ptr + eid_ptr->Len + 1) <
-	       ((u8 *)pFramePtr + MsgLen)) {
-		switch (eid_ptr->Eid) {
-		case IE_TPC_REPORT:
-			NdisMoveMemory(&pTpcRepInfo->TxPwr, eid_ptr->Octet, 1);
-			NdisMoveMemory(&pTpcRepInfo->LinkMargin,
-				       eid_ptr->Octet + 1, 1);
-			result = TRUE;
-			break;
-
-		default:
-			break;
-		}
-		eid_ptr = (struct rt_eid *) ((u8 *) eid_ptr + 2 + eid_ptr->Len);
-	}
-
-	return result;
-}
-
-/*
-	==========================================================================
-	Description:
-		Channel Switch Announcement action frame handler.
-
-	Parametrs:
-		Elme - MLME message containing the received frame
-
-	Return	: None.
-	==========================================================================
- */
-static void PeerChSwAnnAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
-{
-	struct rt_ch_sw_ann_info ChSwAnnInfo;
-	struct rt_frame_802_11 * pFr = (struct rt_frame_802_11 *) Elem->Msg;
-	u8 index = 0, Channel = 0, NewChannel = 0;
-	unsigned long Bssidx = 0;
-
-	NdisZeroMemory(&ChSwAnnInfo, sizeof(struct rt_ch_sw_ann_info));
-	if (!PeerChSwAnnSanity(pAd, Elem->Msg, Elem->MsgLen, &ChSwAnnInfo)) {
-		DBGPRINT(RT_DEBUG_TRACE,
-			 ("Invalid Channel Switch Action Frame.\n"));
-		return;
-	}
-
-	if (pAd->OpMode == OPMODE_STA) {
-		Bssidx =
-		    BssTableSearch(&pAd->ScanTab, pFr->Hdr.Addr3,
-				   pAd->CommonCfg.Channel);
-		if (Bssidx == BSS_NOT_FOUND) {
-			DBGPRINT(RT_DEBUG_TRACE,
-				 ("PeerChSwAnnAction - Bssidx is not found\n"));
-			return;
-		}
-
-		DBGPRINT(RT_DEBUG_TRACE,
-			 ("\n****Bssidx is %d, Channel = %d\n", index,
-			  pAd->ScanTab.BssEntry[Bssidx].Channel));
-		hex_dump("SSID", pAd->ScanTab.BssEntry[Bssidx].Bssid, 6);
-
-		Channel = pAd->CommonCfg.Channel;
-		NewChannel = ChSwAnnInfo.Channel;
-
-		if ((pAd->CommonCfg.bIEEE80211H == 1) && (NewChannel != 0)
-		    && (Channel != NewChannel)) {
-			/* Switching to channel 1 can prevent from rescanning the current channel immediately (by auto reconnection). */
-			/* In addition, clear the MLME queue and the scan table to discard the RX packets and previous scanning results. */
-			AsicSwitchChannel(pAd, 1, FALSE);
-			AsicLockChannel(pAd, 1);
-			LinkDown(pAd, FALSE);
-			MlmeQueueInit(&pAd->Mlme.Queue);
-			BssTableInit(&pAd->ScanTab);
-			RTMPusecDelay(1000000);	/* use delay to prevent STA do reassoc */
-
-			/* channel sanity check */
-			for (index = 0; index < pAd->ChannelListNum; index++) {
-				if (pAd->ChannelList[index].Channel ==
-				    NewChannel) {
-					pAd->ScanTab.BssEntry[Bssidx].Channel =
-					    NewChannel;
-					pAd->CommonCfg.Channel = NewChannel;
-					AsicSwitchChannel(pAd,
-							  pAd->CommonCfg.
-							  Channel, FALSE);
-					AsicLockChannel(pAd,
-							pAd->CommonCfg.Channel);
-					DBGPRINT(RT_DEBUG_TRACE,
-						 ("&&&&&&&&&&&&&&&&PeerChSwAnnAction - STA receive channel switch announcement IE (New Channel =%d)\n",
-						  NewChannel));
-					break;
-				}
-			}
-
-			if (index >= pAd->ChannelListNum) {
-				DBGPRINT_ERR("&&&&&&&&&&&&&&&&&&&&&&&&&&PeerChSwAnnAction(can not find New Channel=%d in ChannelList[%d]\n", pAd->CommonCfg.Channel, pAd->ChannelListNum);
-			}
-		}
-	}
-
-	return;
-}
-
-/*
-	==========================================================================
-	Description:
-		Measurement Request action frame handler.
-
-	Parametrs:
-		Elme - MLME message containing the received frame
-
-	Return	: None.
-	==========================================================================
- */
-static void PeerMeasureReqAction(struct rt_rtmp_adapter *pAd,
-				 struct rt_mlme_queue_elem *Elem)
-{
-	struct rt_frame_802_11 * pFr = (struct rt_frame_802_11 *) Elem->Msg;
-	u8 DialogToken;
-	struct rt_measure_req_info MeasureReqInfo;
-	struct rt_measure_req MeasureReq;
-	MEASURE_REPORT_MODE ReportMode;
-
-	if (PeerMeasureReqSanity
-	    (pAd, Elem->Msg, Elem->MsgLen, &DialogToken, &MeasureReqInfo,
-	     &MeasureReq)) {
-		ReportMode.word = 0;
-		ReportMode.field.Incapable = 1;
-		EnqueueMeasurementRep(pAd, pFr->Hdr.Addr2, DialogToken,
-				      MeasureReqInfo.Token, ReportMode.word,
-				      MeasureReqInfo.ReqType, 0, NULL);
-	}
-
-	return;
-}
-
-/*
-	==========================================================================
-	Description:
-		Measurement Report action frame handler.
-
-	Parametrs:
-		Elme - MLME message containing the received frame
-
-	Return	: None.
-	==========================================================================
- */
-static void PeerMeasureReportAction(struct rt_rtmp_adapter *pAd,
-				    struct rt_mlme_queue_elem *Elem)
-{
-	struct rt_measure_report_info MeasureReportInfo;
-	struct rt_frame_802_11 * pFr = (struct rt_frame_802_11 *) Elem->Msg;
-	u8 DialogToken;
-	u8 *pMeasureReportInfo;
-
-/*      if (pAd->CommonCfg.bIEEE80211H != TRUE) */
-/*              return; */
-
-	pMeasureReportInfo = kmalloc(sizeof(struct rt_measure_rpi_report), GFP_ATOMIC);
-	if (pMeasureReportInfo == NULL) {
-		DBGPRINT(RT_DEBUG_ERROR,
-			 ("%s unable to alloc memory for measure report buffer (size=%zu).\n",
-			  __func__, sizeof(struct rt_measure_rpi_report)));
-		return;
-	}
-
-	NdisZeroMemory(&MeasureReportInfo, sizeof(struct rt_measure_report_info));
-	NdisZeroMemory(pMeasureReportInfo, sizeof(struct rt_measure_rpi_report));
-	if (PeerMeasureReportSanity
-	    (pAd, Elem->Msg, Elem->MsgLen, &DialogToken, &MeasureReportInfo,
-	     pMeasureReportInfo)) {
-		do {
-			struct rt_measure_req_entry *pEntry = NULL;
-
-			/* Not a autonomous measure report. */
-			/* check the dialog token field. drop it if the dialog token doesn't match. */
-			if ((DialogToken != 0)
-			    && ((pEntry = MeasureReqLookUp(pAd, DialogToken)) ==
-				NULL))
-				break;
-
-			if (pEntry != NULL)
-				MeasureReqDelete(pAd, pEntry->DialogToken);
-
-			if (MeasureReportInfo.ReportType == RM_BASIC) {
-				struct rt_measure_basic_report * pBasicReport =
-				    (struct rt_measure_basic_report *) pMeasureReportInfo;
-				if ((pBasicReport->Map.field.Radar)
-				    &&
-				    (DfsRequirementCheck
-				     (pAd, pBasicReport->ChNum) == TRUE)) {
-					NotifyChSwAnnToPeerAPs(pAd,
-							       pFr->Hdr.Addr1,
-							       pFr->Hdr.Addr2,
-							       1,
-							       pBasicReport->
-							       ChNum);
-					StartDFSProcedure(pAd,
-							  pBasicReport->ChNum,
-							  1);
-				}
-			}
-		} while (FALSE);
-	} else
-		DBGPRINT(RT_DEBUG_TRACE,
-			 ("Invalid Measurement Report Frame.\n"));
-
-	kfree(pMeasureReportInfo);
-
-	return;
-}
-
-/*
-	==========================================================================
-	Description:
-		TPC Request action frame handler.
-
-	Parametrs:
-		Elme - MLME message containing the received frame
-
-	Return	: None.
-	==========================================================================
- */
-static void PeerTpcReqAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
-{
-	struct rt_frame_802_11 * pFr = (struct rt_frame_802_11 *) Elem->Msg;
-	u8 *pFramePtr = pFr->Octet;
-	u8 DialogToken;
-	u8 TxPwr = GetCurTxPwr(pAd, Elem->Wcid);
-	u8 LinkMargin = 0;
-	char RealRssi;
-
-	/* link margin: Ratio of the received signal power to the minimum desired by the station (STA). The */
-	/*                              STA may incorporate rate information and channel conditions, including interference, into its computation */
-	/*                              of link margin. */
-
-	RealRssi = RTMPMaxRssi(pAd, ConvertToRssi(pAd, Elem->Rssi0, RSSI_0),
-			       ConvertToRssi(pAd, Elem->Rssi1, RSSI_1),
-			       ConvertToRssi(pAd, Elem->Rssi2, RSSI_2));
-
-	/* skip Category and action code. */
-	pFramePtr += 2;
-
-	/* Dialog token. */
-	NdisMoveMemory(&DialogToken, pFramePtr, 1);
-
-	LinkMargin = (RealRssi / MIN_RCV_PWR);
-	if (PeerTpcReqSanity(pAd, Elem->Msg, Elem->MsgLen, &DialogToken))
-		EnqueueTPCRep(pAd, pFr->Hdr.Addr2, DialogToken, TxPwr,
-			      LinkMargin);
-
-	return;
-}
-
-/*
-	==========================================================================
-	Description:
-		TPC Report action frame handler.
-
-	Parametrs:
-		Elme - MLME message containing the received frame
-
-	Return	: None.
-	==========================================================================
- */
-static void PeerTpcRepAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
-{
-	u8 DialogToken;
-	struct rt_tpc_report_info TpcRepInfo;
-	struct rt_tpc_req_entry *pEntry = NULL;
-
-	NdisZeroMemory(&TpcRepInfo, sizeof(struct rt_tpc_report_info));
-	if (PeerTpcRepSanity
-	    (pAd, Elem->Msg, Elem->MsgLen, &DialogToken, &TpcRepInfo)) {
-		pEntry = TpcReqLookUp(pAd, DialogToken);
-		if (pEntry != NULL) {
-			TpcReqDelete(pAd, pEntry->DialogToken);
-			DBGPRINT(RT_DEBUG_TRACE,
-				 ("%s: DialogToken=%x, TxPwr=%d, LinkMargin=%d\n",
-				  __func__, DialogToken, TpcRepInfo.TxPwr,
-				  TpcRepInfo.LinkMargin));
-		}
-	}
-
-	return;
-}
-
-/*
-	==========================================================================
-	Description:
-		Spectrun action frames Handler such as channel switch annoucement,
-		measurement report, measurement request actions frames.
-
-	Parametrs:
-		Elme - MLME message containing the received frame
-
-	Return	: None.
-	==========================================================================
- */
-void PeerSpectrumAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
-{
-
-	u8 Action = Elem->Msg[LENGTH_802_11 + 1];
-
-	if (pAd->CommonCfg.bIEEE80211H != TRUE)
-		return;
-
-	switch (Action) {
-	case SPEC_MRQ:
-		/* current rt2860 unable do such measure specified in Measurement Request. */
-		/* reject all measurement request. */
-		PeerMeasureReqAction(pAd, Elem);
-		break;
-
-	case SPEC_MRP:
-		PeerMeasureReportAction(pAd, Elem);
-		break;
-
-	case SPEC_TPCRQ:
-		PeerTpcReqAction(pAd, Elem);
-		break;
-
-	case SPEC_TPCRP:
-		PeerTpcRepAction(pAd, Elem);
-		break;
-
-	case SPEC_CHANNEL_SWITCH:
-
-		PeerChSwAnnAction(pAd, Elem);
-		break;
-	}
-
-	return;
-}
-
-/*
-	==========================================================================
-	Description:
-
-	Parametrs:
-
-	Return	: None.
-	==========================================================================
- */
-int Set_MeasureReq_Proc(struct rt_rtmp_adapter *pAd, char *arg)
-{
-	u32 Aid = 1;
-	u32 ArgIdx;
-	char *thisChar;
-
-	MEASURE_REQ_MODE MeasureReqMode;
-	u8 MeasureReqToken = RandomByte(pAd);
-	u8 MeasureReqType = RM_BASIC;
-	u8 MeasureCh = 1;
-	u64 MeasureStartTime = GetCurrentTimeStamp(pAd);
-	struct rt_measure_req MeasureReq;
-	u8 TotalLen;
-
-	struct rt_header_802_11 ActHdr;
-	u8 *pOutBuffer = NULL;
-	int NStatus;
-	unsigned long FrameLen;
-
-	NStatus = MlmeAllocateMemory(pAd, (void *)& pOutBuffer);	/*Get an unused nonpaged memory */
-	if (NStatus != NDIS_STATUS_SUCCESS) {
-		DBGPRINT(RT_DEBUG_TRACE,
-			 ("%s() allocate memory failed \n", __func__));
-		goto END_OF_MEASURE_REQ;
-	}
-
-	ArgIdx = 1;
-	while ((thisChar = strsep((char **)&arg, "-")) != NULL) {
-		switch (ArgIdx) {
-		case 1:	/* Aid. */
-			Aid = (u8)simple_strtol(thisChar, 0, 16);
-			break;
-
-		case 2:	/* Measurement Request Type. */
-			MeasureReqType = simple_strtol(thisChar, 0, 16);
-			if (MeasureReqType > 3) {
-				DBGPRINT(RT_DEBUG_ERROR,
-					 ("%s: unknow MeasureReqType(%d)\n",
-					  __func__, MeasureReqType));
-				goto END_OF_MEASURE_REQ;
-			}
-			break;
-
-		case 3:	/* Measurement channel. */
-			MeasureCh = (u8)simple_strtol(thisChar, 0, 16);
-			break;
-		}
-		ArgIdx++;
-	}
-
-	DBGPRINT(RT_DEBUG_TRACE,
-		 ("%s::Aid = %d, MeasureReqType=%d MeasureCh=%d\n", __func__,
-		  Aid, MeasureReqType, MeasureCh));
-	if (!VALID_WCID(Aid)) {
-		DBGPRINT(RT_DEBUG_ERROR,
-			 ("%s: unknow sta of Aid(%d)\n", __func__, Aid));
-		goto END_OF_MEASURE_REQ;
-	}
-
-	MeasureReqMode.word = 0;
-	MeasureReqMode.field.Enable = 1;
-
-	MeasureReqInsert(pAd, MeasureReqToken);
-
-	/* build action frame header. */
-	MgtMacHeaderInit(pAd, &ActHdr, SUBTYPE_ACTION, 0,
-			 pAd->MacTab.Content[Aid].Addr, pAd->CurrentAddress);
-
-	NdisMoveMemory(pOutBuffer, (char *)& ActHdr, sizeof(struct rt_header_802_11));
-	FrameLen = sizeof(struct rt_header_802_11);
-
-	TotalLen = sizeof(struct rt_measure_req_info) + sizeof(struct rt_measure_req);
-
-	MakeMeasurementReqFrame(pAd, pOutBuffer, &FrameLen,
-				sizeof(struct rt_measure_req_info), CATEGORY_RM, RM_BASIC,
-				MeasureReqToken, MeasureReqMode.word,
-				MeasureReqType, 0);
-
-	MeasureReq.ChNum = MeasureCh;
-	MeasureReq.MeasureStartTime = cpu2le64(MeasureStartTime);
-	MeasureReq.MeasureDuration = cpu2le16(2000);
-
-	{
-		unsigned long TempLen;
-		MakeOutgoingFrame(pOutBuffer + FrameLen, &TempLen,
-				  sizeof(struct rt_measure_req), &MeasureReq,
-				  END_OF_ARGS);
-		FrameLen += TempLen;
-	}
-
-	MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, (u32)FrameLen);
-
-END_OF_MEASURE_REQ:
-	MlmeFreeMemory(pAd, pOutBuffer);
-
-	return TRUE;
-}
-
-int Set_TpcReq_Proc(struct rt_rtmp_adapter *pAd, char *arg)
-{
-	u32 Aid;
-
-	u8 TpcReqToken = RandomByte(pAd);
-
-	Aid = (u32)simple_strtol(arg, 0, 16);
-
-	DBGPRINT(RT_DEBUG_TRACE, ("%s::Aid = %d\n", __func__, Aid));
-	if (!VALID_WCID(Aid)) {
-		DBGPRINT(RT_DEBUG_ERROR,
-			 ("%s: unknow sta of Aid(%d)\n", __func__, Aid));
-		return TRUE;
-	}
-
-	TpcReqInsert(pAd, TpcReqToken);
-
-	EnqueueTPCReq(pAd, pAd->MacTab.Content[Aid].Addr, TpcReqToken);
-
-	return TRUE;
-}
diff -druN linux-2.6.39-libre/drivers/staging/rt2860/crypt_hmac.h linux-3.0-rc7-libre/drivers/staging/rt2860/crypt_hmac.h
--- linux-2.6.39-libre/drivers/staging/rt2860/crypt_hmac.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rt2860/crypt_hmac.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,65 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, 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.             *
- *                                                                       *
- *************************************************************************
- */
-
-/****************************************************************************
-    Module Name:
-    HMAC
-
-    Abstract:
-    FIPS 198: The Keyed-Hash Message Authentication Code (HMAC)
-
-    Revision History:
-    Who         When            What
-    --------    ----------      ------------------------------------------
-    Eddy        2008/11/24      Create HMAC-SHA1, HMAC-SHA256
-***************************************************************************/
-#ifndef __CRYPT_HMAC_H__
-#define __CRYPT_HMAC_H__
-
-#ifdef CRYPT_TESTPLAN
-#include "crypt_testplan.h"
-#else
-#include "rt_config.h"
-#endif /* CRYPT_TESTPLAN */
-
-#ifdef SHA1_SUPPORT
-#define HMAC_SHA1_SUPPORT
-void HMAC_SHA1(IN const u8 Key[],
-	       u32 KeyLen,
-	       IN const u8 Message[],
-	       u32 MessageLen, u8 MAC[], u32 MACLen);
-#endif /* SHA1_SUPPORT */
-
-#ifdef MD5_SUPPORT
-#define HMAC_MD5_SUPPORT
-void HMAC_MD5(IN const u8 Key[],
-	      u32 KeyLen,
-	      IN const u8 Message[],
-	      u32 MessageLen, u8 MAC[], u32 MACLen);
-#endif /* MD5_SUPPORT */
-
-#endif /* __CRYPT_HMAC_H__ */
diff -druN linux-2.6.39-libre/drivers/staging/rt2860/crypt_md5.h linux-3.0-rc7-libre/drivers/staging/rt2860/crypt_md5.h
--- linux-2.6.39-libre/drivers/staging/rt2860/crypt_md5.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rt2860/crypt_md5.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,73 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, 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.             *
- *                                                                       *
- *************************************************************************
- */
-
-/****************************************************************************
-    Module Name:
-    MD5
-
-    Abstract:
-    RFC1321: The MD5 Message-Digest Algorithm
-
-    Revision History:
-    Who         When            What
-    --------    ----------      ------------------------------------------
-    Eddy        2008/11/24      Create md5
-***************************************************************************/
-
-#ifndef __CRYPT_MD5_H__
-#define __CRYPT_MD5_H__
-
-#ifdef CRYPT_TESTPLAN
-#include "crypt_testplan.h"
-#else
-#include "rt_config.h"
-#endif /* CRYPT_TESTPLAN */
-
-/* Algorithm options */
-#define MD5_SUPPORT
-
-#ifdef MD5_SUPPORT
-#define MD5_BLOCK_SIZE    64	/* 512 bits = 64 bytes */
-#define MD5_DIGEST_SIZE   16	/* 128 bits = 16 bytes */
-
-struct rt_md5_ctx_struc {
-	u32 HashValue[4];
-	u64 MessageLen;
-	u8 Block[MD5_BLOCK_SIZE];
-	u32 BlockLen;
-};
-
-void MD5_Init(struct rt_md5_ctx_struc *pMD5_CTX);
-void MD5_Hash(struct rt_md5_ctx_struc *pMD5_CTX);
-void MD5_Append(struct rt_md5_ctx_struc *pMD5_CTX,
-		IN const u8 Message[], u32 MessageLen);
-void MD5_End(struct rt_md5_ctx_struc *pMD5_CTX, u8 DigestMessage[]);
-void RT_MD5(IN const u8 Message[],
-	    u32 MessageLen, u8 DigestMessage[]);
-#endif /* MD5_SUPPORT */
-
-#endif /* __CRYPT_MD5_H__ */
diff -druN linux-2.6.39-libre/drivers/staging/rt2860/crypt_sha2.h linux-3.0-rc7-libre/drivers/staging/rt2860/crypt_sha2.h
--- linux-2.6.39-libre/drivers/staging/rt2860/crypt_sha2.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rt2860/crypt_sha2.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,73 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, 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.             *
- *                                                                       *
- *************************************************************************
- */
-
-/****************************************************************************
-    Module Name:
-    SHA2
-
-    Abstract:
-    FIPS 180-2: Secure Hash Standard (SHS)
-
-    Revision History:
-    Who         When            What
-    --------    ----------      ------------------------------------------
-    Eddy        2008/11/24      Create SHA1
-    Eddy        2008/07/23      Create SHA256
-***************************************************************************/
-
-#ifndef __CRYPT_SHA2_H__
-#define __CRYPT_SHA2_H__
-
-#ifdef CRYPT_TESTPLAN
-#include "crypt_testplan.h"
-#else
-#include "rt_config.h"
-#endif /* CRYPT_TESTPLAN */
-
-/* Algorithm options */
-#define SHA1_SUPPORT
-
-#ifdef SHA1_SUPPORT
-#define SHA1_BLOCK_SIZE    64	/* 512 bits = 64 bytes */
-#define SHA1_DIGEST_SIZE   20	/* 160 bits = 20 bytes */
-struct rt_sha1_ctx {
-	u32 HashValue[5];	/* 5 = (SHA1_DIGEST_SIZE / 32) */
-	u64 MessageLen;	/* total size */
-	u8 Block[SHA1_BLOCK_SIZE];
-	u32 BlockLen;
-};
-
-void RT_SHA1_Init(struct rt_sha1_ctx *pSHA_CTX);
-void SHA1_Hash(struct rt_sha1_ctx *pSHA_CTX);
-void SHA1_Append(struct rt_sha1_ctx *pSHA_CTX,
-		 IN const u8 Message[], u32 MessageLen);
-void SHA1_End(struct rt_sha1_ctx *pSHA_CTX, u8 DigestMessage[]);
-void RT_SHA1(IN const u8 Message[],
-	     u32 MessageLen, u8 DigestMessage[]);
-#endif /* SHA1_SUPPORT */
-
-#endif /* __CRYPT_SHA2_H__ */
diff -druN linux-2.6.39-libre/drivers/staging/rt2860/dfs.h linux-3.0-rc7-libre/drivers/staging/rt2860/dfs.h
--- linux-2.6.39-libre/drivers/staging/rt2860/dfs.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rt2860/dfs.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,39 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, 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.             *
- *                                                                       *
- *************************************************************************
-
-    Module Name:
-    dfs.h
-
-    Abstract:
-    Support DFS function.
-
-    Revision History:
-    Who       When            What
-    --------  ----------      ----------------------------------------------
-    Fonchi    03-12-2007      created
-*/
-
-BOOLEAN RadarChannelCheck(struct rt_rtmp_adapter *pAd, u8 Ch);
diff -druN linux-2.6.39-libre/drivers/staging/rt2860/eeprom.h linux-3.0-rc7-libre/drivers/staging/rt2860/eeprom.h
--- linux-2.6.39-libre/drivers/staging/rt2860/eeprom.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rt2860/eeprom.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,67 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, 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.             *
- *                                                                       *
- *************************************************************************
-
-	Module Name:
-	eeprom.h
-
-	Abstract:
-	Miniport header file for eeprom related information
-
-	Revision History:
-	Who         When          What
-	--------    ----------    ----------------------------------------------
-*/
-#ifndef __EEPROM_H__
-#define __EEPROM_H__
-
-#ifdef RTMP_PCI_SUPPORT
-/*************************************************************************
-  *	Public function declarations for prom-based chipset
-  ************************************************************************/
-int rtmp_ee_prom_read16(struct rt_rtmp_adapter *pAd,
-			u16 Offset, u16 *pValue);
-#endif /* RTMP_PCI_SUPPORT // */
-#ifdef RTMP_USB_SUPPORT
-/*************************************************************************
-  *	Public function declarations for usb-based prom chipset
-  ************************************************************************/
-int RTUSBReadEEPROM16(struct rt_rtmp_adapter *pAd,
-			   u16 offset, u16 *pData);
-#endif /* RTMP_USB_SUPPORT // */
-
-#ifdef RT30xx
-#ifdef RTMP_EFUSE_SUPPORT
-int rtmp_ee_efuse_read16(struct rt_rtmp_adapter *pAd,
-			 u16 Offset, u16 *pValue);
-#endif /* RTMP_EFUSE_SUPPORT // */
-#endif /* RT30xx // */
-
-/*************************************************************************
-  *	Public function declarations for prom operation callback functions setting
-  ************************************************************************/
-int RtmpChipOpsEepromHook(struct rt_rtmp_adapter *pAd, int infType);
-
-#endif /* __EEPROM_H__ // */
diff -druN linux-2.6.39-libre/drivers/staging/rt2860/iface/rtmp_pci.h linux-3.0-rc7-libre/drivers/staging/rt2860/iface/rtmp_pci.h
--- linux-2.6.39-libre/drivers/staging/rt2860/iface/rtmp_pci.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rt2860/iface/rtmp_pci.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,80 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, 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 __RTMP_PCI_H__
-#define __RTMP_PCI_H__
-
-#define RT28XX_HANDLE_DEV_ASSIGN(handle, dev_p)				\
-	((struct os_cookie *)handle)->pci_dev = dev_p;
-
-#ifdef LINUX
-/* set driver data */
-#define RT28XX_DRVDATA_SET(_a)			pci_set_drvdata(_a, net_dev);
-
-#define RT28XX_PUT_DEVICE(dev_p)
-
-#define SA_SHIRQ IRQF_SHARED
-
-#ifdef PCI_MSI_SUPPORT
-#define RTMP_MSI_ENABLE(_pAd) \
-	{     struct os_cookie *_pObj = (struct os_cookie *)(_pAd->OS_Cookie); \
-		(_pAd)->HaveMsi = pci_enable_msi(_pObj->pci_dev) \
-							== 0 ? TRUE : FALSE; \
-	}
-
-#define RTMP_MSI_DISABLE(_pAd) \
-	{     struct os_cookie *_pObj = (struct os_cookie *)(_pAd->OS_Cookie); \
-		if (_pAd->HaveMsi == TRUE) \
-			pci_disable_msi(_pObj->pci_dev); \
-		_pAd->HaveMsi = FALSE;  \
-	}
-#else
-#define RTMP_MSI_ENABLE(_pAd)		do {} while (0)
-#define RTMP_MSI_DISABLE(_pAd)		do {} while (0)
-#endif /* PCI_MSI_SUPPORT */
-
-#define RTMP_PCI_DEV_UNMAP()						\
-{	if (net_dev->base_addr)	{					\
-		iounmap((void *)(net_dev->base_addr));			\
-		release_mem_region(pci_resource_start(dev_p, 0),	\
-					pci_resource_len(dev_p, 0)); } \
-	if (net_dev->irq) \
-		pci_release_regions(dev_p); }
-
-#define PCI_REG_READ_WORD(pci_dev, offset, Configuration)   {\
-	if (pci_read_config_word(pci_dev, offset, &reg16) == 0)     \
-		Configuration = le2cpu16(reg16);                        \
-	else                                                        \
-		Configuration = 0; }
-
-#define PCI_REG_WIRTE_WORD(pci_dev, offset, Configuration)  {\
-	reg16 = cpu2le16(Configuration);                        \
-	pci_write_config_word(pci_dev, offset, reg16); }
-
-#endif /* LINUX */
-
-#endif /* __RTMP_PCI_H__ */
diff -druN linux-2.6.39-libre/drivers/staging/rt2860/iface/rtmp_usb.h linux-3.0-rc7-libre/drivers/staging/rt2860/iface/rtmp_usb.h
--- linux-2.6.39-libre/drivers/staging/rt2860/iface/rtmp_usb.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rt2860/iface/rtmp_usb.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,196 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, 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 __RTMP_USB_H__
-#define __RTMP_USB_H__
-
-#include "../rtusb_io.h"
-
-#ifdef LINUX
-#include <linux/usb.h>
-#endif /* LINUX */
-
-extern u8 EpToQueue[6];
-
-#define RXBULKAGGRE_ZISE			12
-#define MAX_TXBULK_LIMIT		(LOCAL_TXBUF_SIZE*(BULKAGGRE_ZISE-1))
-#define MAX_TXBULK_SIZE		(LOCAL_TXBUF_SIZE*BULKAGGRE_ZISE)
-#define MAX_RXBULK_SIZE		(LOCAL_TXBUF_SIZE*RXBULKAGGRE_ZISE)
-#define MAX_MLME_HANDLER_MEMORY 20
-
-/* Flags for Bulkflags control for bulk out data */
-#define	fRTUSB_BULK_OUT_DATA_NULL				0x00000001
-#define	fRTUSB_BULK_OUT_RTS					0x00000002
-#define	fRTUSB_BULK_OUT_MLME					0x00000004
-
-#define	fRTUSB_BULK_OUT_PSPOLL				0x00000010
-#define	fRTUSB_BULK_OUT_DATA_FRAG				0x00000020
-#define	fRTUSB_BULK_OUT_DATA_FRAG_2			0x00000040
-#define	fRTUSB_BULK_OUT_DATA_FRAG_3			0x00000080
-#define	fRTUSB_BULK_OUT_DATA_FRAG_4			0x00000100
-
-#define	fRTUSB_BULK_OUT_DATA_NORMAL			0x00010000
-#define	fRTUSB_BULK_OUT_DATA_NORMAL_2			0x00020000
-#define	fRTUSB_BULK_OUT_DATA_NORMAL_3			0x00040000
-#define	fRTUSB_BULK_OUT_DATA_NORMAL_4			0x00080000
-
-/* TODO:move to ./ate/include/iface/ate_usb.h */
-
-#define FREE_HTTX_RING(_pCookie, _pipeId, _txContext)			\
-{									\
-	if ((_txContext)->ENextBulkOutPosition == \
-	(_txContext)->CurWritePosition) {\
-		(_txContext)->bRingEmpty = TRUE;			\
-	}								\
-	/*NdisInterlockedDecrement(&(_p)->TxCount); */\
-}
-
-/******************************************************************************
-
-	USB Bulk operation related definitions
-
-******************************************************************************/
-
-#ifdef LINUX
-#define BULKAGGRE_ZISE			100
-#define RT28XX_PUT_DEVICE			usb_put_dev
-#define RTUSB_ALLOC_URB(iso)		usb_alloc_urb(iso, GFP_ATOMIC)
-#define RTUSB_SUBMIT_URB(pUrb)		usb_submit_urb(pUrb, \
-								GFP_ATOMIC)
-#define RTUSB_URB_ALLOC_BUFFER(pUsb_Dev, \
-							BufSize, \
-							pDma_addr)	\
-							usb_alloc_coherent(\
-							pUsb_Dev, \
-							BufSize, \
-							GFP_ATOMIC, \
-							pDma_addr)
-#define RTUSB_URB_FREE_BUFFER(pUsb_Dev, \
-							BufSize, \
-							pTransferBuf, \
-							Dma_addr)	\
-							usb_free_coherent( \
-							pUsb_Dev, \
-							BufSize, \
-							pTransferBuf, \
-							Dma_addr)
-
-#define RTUSB_FREE_URB(pUrb)	usb_free_urb(pUrb)
-
-/* unlink urb */
-#define RTUSB_UNLINK_URB(pUrb)		usb_kill_urb(pUrb)
-
-extern void dump_urb(struct urb *purb);
-
-#define InterlockedIncrement		atomic_inc
-#define NdisInterlockedIncrement	atomic_inc
-#define InterlockedDecrement		atomic_dec
-#define NdisInterlockedDecrement	atomic_dec
-#define InterlockedExchange		atomic_set
-
-#endif /* LINUX */
-
-#define NT_SUCCESS(status)		(((status) >= 0) ? (TRUE) : (FALSE))
-
-#define USBD_TRANSFER_DIRECTION_OUT		0
-#define USBD_TRANSFER_DIRECTION_IN		0
-#define USBD_SHORT_TRANSFER_OK			0
-#define PURB			struct urb *
-
-#define PIRP		void *
-#define NDIS_OID	u32
-#ifndef USB_ST_NOERROR
-#define USB_ST_NOERROR     0
-#endif
-
-/* vendor-specific control operations */
-#define CONTROL_TIMEOUT_JIFFIES ((100 * OS_HZ) / 1000)
-#define UNLINK_TIMEOUT_MS		3
-
-void RTUSBBulkOutDataPacketComplete(struct urb *purb, struct pt_regs *pt_regs);
-void RTUSBBulkOutMLMEPacketComplete(struct urb *pUrb, struct pt_regs *pt_regs);
-void RTUSBBulkOutNullFrameComplete(struct urb *pUrb, struct pt_regs *pt_regs);
-void RTUSBBulkOutRTSFrameComplete(struct urb *pUrb, struct pt_regs *pt_regs);
-void RTUSBBulkOutPsPollComplete(struct urb *pUrb, struct pt_regs *pt_regs);
-void RTUSBBulkRxComplete(struct urb *pUrb, struct pt_regs *pt_regs);
-
-#ifdef KTHREAD_SUPPORT
-#define RTUSBMlmeUp(pAd) \
-	do {								    \
-		struct rt_rtmp_os_task *_pTask = &((pAd)->mlmeTask);\
-		if (_pTask->kthread_task) {\
-			_pTask->kthread_running = TRUE; \
-		wake_up(&_pTask->kthread_q); \
-		} \
-	} while (0)
-#else
-#define RTUSBMlmeUp(pAd)	        \
-	do {								    \
-		struct rt_rtmp_os_task *_pTask = &((pAd)->mlmeTask);\
-		CHECK_PID_LEGALITY(_pTask->taskPID)		    \
-		{ \
-			RTMP_SEM_EVENT_UP(&(_pTask->taskSema)); \
-		} \
-	} while (0)
-#endif
-
-#ifdef KTHREAD_SUPPORT
-#define RTUSBCMDUp(pAd) \
-	do {	\
-		struct rt_rtmp_os_task *_pTask = &((pAd)->cmdQTask);	\
-		{ \
-			_pTask->kthread_running = TRUE; \
-		wake_up(&_pTask->kthread_q); \
-		} \
-	} while (0)
-
-#else
-#define RTUSBCMDUp(pAd)	                \
-	do {							    \
-		struct rt_rtmp_os_task *_pTask = &((pAd)->cmdQTask);	\
-		CHECK_PID_LEGALITY(_pTask->taskPID)	    \
-		{\
-			RTMP_SEM_EVENT_UP(&(_pTask->taskSema)); \
-		} \
-	} while (0)
-#endif
-
-#define DEVICE_VENDOR_REQUEST_OUT       0x40
-#define DEVICE_VENDOR_REQUEST_IN        0xc0
-/*#define INTERFACE_VENDOR_REQUEST_OUT    0x41*/
-/*#define INTERFACE_VENDOR_REQUEST_IN     0xc1*/
-
-#define BULKOUT_MGMT_RESET_FLAG		0x80
-
-#define RTUSB_SET_BULK_FLAG(_M, _F)	((_M)->BulkFlags |= (_F))
-#define RTUSB_CLEAR_BULK_FLAG(_M, _F)	((_M)->BulkFlags &= ~(_F))
-#define RTUSB_TEST_BULK_FLAG(_M, _F)	(((_M)->BulkFlags & (_F)) != 0)
-
-#define RTMP_IRQ_REQUEST(net_dev)		do {} while (0)
-#define RTMP_IRQ_RELEASE(net_dev)		do {} while (0)
-
-#endif /* __RTMP_USB_H__ */
diff -druN linux-2.6.39-libre/drivers/staging/rt2860/Kconfig linux-3.0-rc7-libre/drivers/staging/rt2860/Kconfig
--- linux-2.6.39-libre/drivers/staging/rt2860/Kconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rt2860/Kconfig	1969-12-31 19:00:00.000000000 -0500
@@ -1,10 +0,0 @@
-config RT2860
-	tristate "Ralink 2860/3090 wireless support"
-	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 -druN linux-2.6.39-libre/drivers/staging/rt2860/Makefile linux-3.0-rc7-libre/drivers/staging/rt2860/Makefile
--- linux-2.6.39-libre/drivers/staging/rt2860/Makefile	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rt2860/Makefile	1969-12-31 19:00:00.000000000 -0500
@@ -1,52 +0,0 @@
-obj-$(CONFIG_RT2860)	+= rt2860sta.o
-
-# TODO: all of these should be removed
-ccflags-y := -DLINUX -DAGGREGATION_SUPPORT -DPIGGYBACK_SUPPORT -DWMM_SUPPORT
-ccflags-y += -DRTMP_MAC_PCI -DRTMP_PCI_SUPPORT -DRT2860
-ccflags-y += -DRTMP_RF_RW_SUPPORT -DRTMP_EFUSE_SUPPORT -DRT30xx -DRT3090
-ccflags-y += -DDBG
-
-rt2860sta-y :=	\
-	common/crypt_md5.o	\
-	common/crypt_sha2.o	\
-	common/crypt_hmac.o	\
-	common/mlme.o		\
-	common/cmm_wep.o	\
-	common/action.o		\
-	common/cmm_data.o	\
-	common/rtmp_init.o	\
-	common/cmm_tkip.o	\
-	common/cmm_aes.o	\
-	common/cmm_sync.o	\
-	common/eeprom.o		\
-	common/cmm_sanity.o	\
-	common/cmm_info.o	\
-	common/cmm_cfg.o	\
-	common/cmm_wpa.o	\
-	common/dfs.o		\
-	common/spectrum.o	\
-	common/rtmp_timer.o	\
-	common/rt_channel.o	\
-	common/cmm_asic.o	\
-	sta/assoc.o		\
-	sta/auth.o		\
-	sta/auth_rsp.o		\
-	sta/sync.o		\
-	sta/sanity.o		\
-	sta/rtmp_data.o		\
-	sta/connect.o		\
-	sta/wpa.o		\
-	rt_linux.o		\
-	rt_main_dev.o		\
-	sta_ioctl.o		\
-	common/ba_action.o	\
-	pci_main_dev.o		\
-	rt_pci_rbus.o		\
-	common/cmm_mac_pci.o	\
-	common/cmm_data_pci.o	\
-	common/ee_prom.o	\
-	common/rtmp_mcu.o	\
-	common/ee_efuse.o	\
-	chips/rt30xx.o		\
-	common/rt_rf.o		\
-	chips/rt3090.o
diff -druN linux-2.6.39-libre/drivers/staging/rt2860/mlme.h linux-3.0-rc7-libre/drivers/staging/rt2860/mlme.h
--- linux-2.6.39-libre/drivers/staging/rt2860/mlme.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rt2860/mlme.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,1050 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, 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.             *
- *                                                                       *
- *************************************************************************
-
-	Module Name:
-	mlme.h
-
-	Abstract:
-
-	Revision History:
-	Who			When			What
-	--------	----------		------------------------------
-	John Chang		2003-08-28		Created
-	John Chang  		2004-09-06      	modified for RT2600
-	Justin P. Mattock	11/07/2010		Fix typos in comments
-
-*/
-#ifndef __MLME_H__
-#define __MLME_H__
-
-#include "rtmp_dot11.h"
-
-/* maximum supported capability information */
-/* ESS, IBSS, Privacy, Short Preamble, Spectrum mgmt, Short Slot */
-#define SUPPORTED_CAPABILITY_INFO   0x0533
-
-#define END_OF_ARGS                 -1
-#define LFSR_MASK                   0x80000057
-#define MLME_TASK_EXEC_INTV         100/*200*/	/* */
-#define LEAD_TIME                   5
-#define MLME_TASK_EXEC_MULTIPLE       10  /*5*/	/* MLME_TASK_EXEC_MULTIPLE * MLME_TASK_EXEC_INTV = 1 sec */
-#define REORDER_EXEC_INTV		100	/* 0.1 sec */
-
-/* The definition of Radar detection duration region */
-#define CE		0
-#define FCC		1
-#define JAP		2
-#define JAP_W53	3
-#define JAP_W56	4
-#define MAX_RD_REGION 5
-
-#define BEACON_LOST_TIME            (4 * OS_HZ)	/* 2048 msec = 2 sec */
-
-#define DLS_TIMEOUT                 1200	/* unit: msec */
-#define AUTH_TIMEOUT                300	/* unit: msec */
-#define ASSOC_TIMEOUT               300	/* unit: msec */
-#define JOIN_TIMEOUT                2000	/* unit: msec */
-#define SHORT_CHANNEL_TIME          90	/* unit: msec */
-#define MIN_CHANNEL_TIME            110	/* unit: msec, for dual band scan */
-#define MAX_CHANNEL_TIME            140	/* unit: msec, for single band scan */
-#define	FAST_ACTIVE_SCAN_TIME	    30	/* Active scan waiting for probe response time */
-#define CW_MIN_IN_BITS              4	/* actual CwMin = 2^CW_MIN_IN_BITS - 1 */
-#define LINK_DOWN_TIMEOUT           20000	/* unit: msec */
-#define AUTO_WAKEUP_TIMEOUT			70	/*unit: msec */
-
-#define CW_MAX_IN_BITS              10	/* actual CwMax = 2^CW_MAX_IN_BITS - 1 */
-
-/* Note: RSSI_TO_DBM_OFFSET has been changed to variable for new RF (2004-0720). */
-/* Should not refer to this constant anymore */
-/*#define RSSI_TO_DBM_OFFSET          120 // for RT2530 RSSI-115 = dBm */
-#define RSSI_FOR_MID_TX_POWER       -55	/* -55 db is considered mid-distance */
-#define RSSI_FOR_LOW_TX_POWER       -45	/* -45 db is considered very short distance and */
-					/* eligible to use a lower TX power */
-#define RSSI_FOR_LOWEST_TX_POWER    -30
-/*#define MID_TX_POWER_DELTA          0   // 0 db from full TX power upon mid-distance to AP */
-#define LOW_TX_POWER_DELTA          6	/* -3 db from full TX power upon very short distance. 1 grade is 0.5 db */
-#define LOWEST_TX_POWER_DELTA       16	/* -8 db from full TX power upon shortest distance. 1 grade is 0.5 db */
-
-#define RSSI_TRIGGERED_UPON_BELOW_THRESHOLD     0
-#define RSSI_TRIGGERED_UPON_EXCCEED_THRESHOLD   1
-#define RSSI_THRESHOLD_FOR_ROAMING              25
-#define RSSI_DELTA                              5
-
-/* Channel Quality Indication */
-#define CQI_IS_GOOD(cqi)            ((cqi) >= 50)
-/*#define CQI_IS_FAIR(cqi)          (((cqi) >= 20) && ((cqi) < 50)) */
-#define CQI_IS_POOR(cqi)            (cqi < 50)	/*(((cqi) >= 5) && ((cqi) < 20)) */
-#define CQI_IS_BAD(cqi)             (cqi < 5)
-#define CQI_IS_DEAD(cqi)            (cqi == 0)
-
-/* weighting factor to calculate Channel quality, total should be 100% */
-#define RSSI_WEIGHTING                   50
-#define TX_WEIGHTING                     30
-#define RX_WEIGHTING                     20
-
-#define BSS_NOT_FOUND                    0xFFFFFFFF
-
-#define MAX_LEN_OF_MLME_QUEUE            40	/*10 */
-
-#define SCAN_PASSIVE                     18	/* scan with no probe request, only wait beacon and probe response */
-#define SCAN_ACTIVE                      19	/* scan with probe request, and wait beacon and probe response */
-#define	SCAN_CISCO_PASSIVE				 20	/* Single channel passive scan */
-#define	SCAN_CISCO_ACTIVE				 21	/* Single channel active scan */
-#define	SCAN_CISCO_NOISE				 22	/* Single channel passive scan for noise histogram collection */
-#define	SCAN_CISCO_CHANNEL_LOAD			 23	/* Single channel passive scan for channel load collection */
-#define FAST_SCAN_ACTIVE                 24	/* scan with probe request, and wait beacon and probe response */
-
-#define MAC_ADDR_IS_GROUP(Addr)       (((Addr[0]) & 0x01))
-#define MAC_ADDR_HASH(Addr)            (Addr[0] ^ Addr[1] ^ Addr[2] ^ Addr[3] ^ Addr[4] ^ Addr[5])
-#define MAC_ADDR_HASH_INDEX(Addr)      (MAC_ADDR_HASH(Addr) % HASH_TABLE_SIZE)
-#define TID_MAC_HASH(Addr, TID)            (TID^Addr[0] ^ Addr[1] ^ Addr[2] ^ Addr[3] ^ Addr[4] ^ Addr[5])
-#define TID_MAC_HASH_INDEX(Addr, TID)      (TID_MAC_HASH(Addr, TID) % HASH_TABLE_SIZE)
-
-/* LED Control */
-/* association ON. one LED ON. another blinking when TX, OFF when idle */
-/* no association, both LED off */
-#define ASIC_LED_ACT_ON(pAd)        RTMP_IO_WRITE32(pAd, MAC_CSR14, 0x00031e46)
-#define ASIC_LED_ACT_OFF(pAd)       RTMP_IO_WRITE32(pAd, MAC_CSR14, 0x00001e46)
-
-/* bit definition of the 2-byte pBEACON->Capability field */
-#define CAP_IS_ESS_ON(x)                 (((x) & 0x0001) != 0)
-#define CAP_IS_IBSS_ON(x)                (((x) & 0x0002) != 0)
-#define CAP_IS_CF_POLLABLE_ON(x)         (((x) & 0x0004) != 0)
-#define CAP_IS_CF_POLL_REQ_ON(x)         (((x) & 0x0008) != 0)
-#define CAP_IS_PRIVACY_ON(x)             (((x) & 0x0010) != 0)
-#define CAP_IS_SHORT_PREAMBLE_ON(x)      (((x) & 0x0020) != 0)
-#define CAP_IS_PBCC_ON(x)                (((x) & 0x0040) != 0)
-#define CAP_IS_AGILITY_ON(x)             (((x) & 0x0080) != 0)
-#define CAP_IS_SPECTRUM_MGMT(x)          (((x) & 0x0100) != 0)	/* 802.11e d9 */
-#define CAP_IS_QOS(x)                    (((x) & 0x0200) != 0)	/* 802.11e d9 */
-#define CAP_IS_SHORT_SLOT(x)             (((x) & 0x0400) != 0)
-#define CAP_IS_APSD(x)                   (((x) & 0x0800) != 0)	/* 802.11e d9 */
-#define CAP_IS_IMMED_BA(x)               (((x) & 0x1000) != 0)	/* 802.11e d9 */
-#define CAP_IS_DSSS_OFDM(x)              (((x) & 0x2000) != 0)
-#define CAP_IS_DELAY_BA(x)               (((x) & 0x4000) != 0)	/* 802.11e d9 */
-
-#define CAP_GENERATE(ess, ibss, priv, s_pre, s_slot, spectrum)  (((ess) ? 0x0001 : 0x0000) | ((ibss) ? 0x0002 : 0x0000) | ((priv) ? 0x0010 : 0x0000) | ((s_pre) ? 0x0020 : 0x0000) | ((s_slot) ? 0x0400 : 0x0000) | ((spectrum) ? 0x0100 : 0x0000))
-
-#define ERP_IS_NON_ERP_PRESENT(x)        (((x) & 0x01) != 0)	/* 802.11g */
-#define ERP_IS_USE_PROTECTION(x)         (((x) & 0x02) != 0)	/* 802.11g */
-#define ERP_IS_USE_BARKER_PREAMBLE(x)    (((x) & 0x04) != 0)	/* 802.11g */
-
-#define DRS_TX_QUALITY_WORST_BOUND       8	/* 3  // just test by gary */
-#define DRS_PENALTY                      8
-
-#define BA_NOTUSE	2
-/*BA Policy subfiled value in ADDBA frame */
-#define IMMED_BA	1
-#define DELAY_BA	0
-
-/* BA Initiator subfield in DELBA frame */
-#define ORIGINATOR	1
-#define RECIPIENT	0
-
-/* ADDBA Status Code */
-#define ADDBA_RESULTCODE_SUCCESS					0
-#define ADDBA_RESULTCODE_REFUSED					37
-#define ADDBA_RESULTCODE_INVALID_PARAMETERS			38
-
-/* DELBA Reason Code */
-#define DELBA_REASONCODE_QSTA_LEAVING				36
-#define DELBA_REASONCODE_END_BA						37
-#define DELBA_REASONCODE_UNKNOWN_BA					38
-#define DELBA_REASONCODE_TIMEOUT					39
-
-/* reset all OneSecTx counters */
-#define RESET_ONE_SEC_TX_CNT(__pEntry) \
-if (((__pEntry)) != NULL) { \
-	(__pEntry)->OneSecTxRetryOkCount = 0; \
-	(__pEntry)->OneSecTxFailCount = 0; \
-	(__pEntry)->OneSecTxNoRetryOkCount = 0; \
-}
-
-/* */
-/* 802.11 frame formats */
-/* */
-/*  HT Capability INFO field in HT Cap IE . */
-struct PACKED rt_ht_cap_info {
-	u16 AdvCoding:1;
-	u16 ChannelWidth:1;
-	u16 MimoPs:2;	/*momi power safe */
-	u16 GF:1;		/*green field */
-	u16 ShortGIfor20:1;
-	u16 ShortGIfor40:1;	/*for40MHz */
-	u16 TxSTBC:1;
-	u16 RxSTBC:2;
-	u16 DelayedBA:1;	/*rt2860c not support */
-	u16 AMsduSize:1;	/* only support as zero */
-	u16 CCKmodein40:1;
-	u16 PSMP:1;
-	u16 Forty_Mhz_Intolerant:1;
-	u16 LSIGTxopProSup:1;
-};
-
-/*  HT Capability INFO field in HT Cap IE . */
-struct PACKED rt_ht_cap_parm {
-	u8 MaxRAmpduFactor:2;
-	u8 MpduDensity:3;
-	u8 rsv:3;		/*momi power safe */
-};
-
-/*  HT Capability INFO field in HT Cap IE . */
-struct PACKED rt_ht_mcs_set {
-	u8 MCSSet[10];
-	u8 SupRate[2];	/* unit : 1Mbps */
-	u8 TxMCSSetDefined:1;
-	u8 TxRxNotEqual:1;
-	u8 TxStream:2;
-	u8 MpduDensity:1;
-	u8 rsv:3;
-	u8 rsv3[3];
-};
-
-/*  HT Capability INFO field in HT Cap IE . */
-struct PACKED rt_ext_ht_cap_info {
-	u16 Pco:1;
-	u16 TranTime:2;
-	u16 rsv:5;		/*momi power safe */
-	u16 MCSFeedback:2;	/*0:no MCS feedback, 2:unsolicited MCS feedback, 3:Full MCS feedback,  1:rsv. */
-	u16 PlusHTC:1;	/*+HTC control field support */
-	u16 RDGSupport:1;	/*reverse Direction Grant  support */
-	u16 rsv2:4;
-};
-
-/*  HT Beamforming field in HT Cap IE . */
-struct PACKED rt_ht_bf_cap {
-	unsigned long TxBFRecCapable:1;
-	unsigned long RxSoundCapable:1;
-	unsigned long TxSoundCapable:1;
-	unsigned long RxNDPCapable:1;
-	unsigned long TxNDPCapable:1;
-	unsigned long ImpTxBFCapable:1;
-	unsigned long Calibration:2;
-	unsigned long ExpCSICapable:1;
-	unsigned long ExpNoComSteerCapable:1;
-	unsigned long ExpComSteerCapable:1;
-	unsigned long ExpCSIFbk:2;
-	unsigned long ExpNoComBF:2;
-	unsigned long ExpComBF:2;
-	unsigned long MinGrouping:2;
-	unsigned long CSIBFAntSup:2;
-	unsigned long NoComSteerBFAntSup:2;
-	unsigned long ComSteerBFAntSup:2;
-	unsigned long CSIRowBFSup:2;
-	unsigned long ChanEstimation:2;
-	unsigned long rsv:3;
-};
-
-/*  HT antenna selection field in HT Cap IE . */
-struct PACKED rt_ht_as_cap {
-	u8 AntSelect:1;
-	u8 ExpCSIFbkTxASEL:1;
-	u8 AntIndFbkTxASEL:1;
-	u8 ExpCSIFbk:1;
-	u8 AntIndFbk:1;
-	u8 RxASel:1;
-	u8 TxSoundPPDU:1;
-	u8 rsv:1;
-};
-
-/* Draft 1.0 set IE length 26, but is extensible.. */
-#define SIZE_HT_CAP_IE		26
-/* The structure for HT Capability IE. */
-struct PACKED rt_ht_capability_ie {
-	struct rt_ht_cap_info HtCapInfo;
-	struct rt_ht_cap_parm HtCapParm;
-/*      struct rt_ht_mcs_set              HtMCSSet; */
-	u8 MCSSet[16];
-	struct rt_ext_ht_cap_info ExtHtCapInfo;
-	struct rt_ht_bf_cap TxBFCap;	/* beamforming cap. rt2860c not support beamforming. */
-	struct rt_ht_as_cap ASCap;	/*antenna selection. */
-};
-
-/* 802.11n draft3 related structure definitions. */
-/* 7.3.2.60 */
-#define dot11OBSSScanPassiveDwell							20	/* in TU. min amount of time that the STA continuously scans each channel when performing an active OBSS scan. */
-#define dot11OBSSScanActiveDwell							10	/* in TU.min amount of time that the STA continuously scans each channel when performing an passive OBSS scan. */
-#define dot11BSSWidthTriggerScanInterval					300	/* in sec. max interval between scan operations to be performed to detect BSS channel width trigger events. */
-#define dot11OBSSScanPassiveTotalPerChannel					200	/* in TU. min total amount of time that the STA scans each channel when performing a passive OBSS scan. */
-#define dot11OBSSScanActiveTotalPerChannel					20	/*in TU. min total amount of time that the STA scans each channel when performing a active OBSS scan */
-#define dot11BSSWidthChannelTransactionDelayFactor			5	/* min ratio between the delay time in performing a switch from 20MHz BSS to 20/40 BSS operation and the maximum */
-																/*      interval between overlapping BSS scan operations. */
-#define dot11BSSScanActivityThreshold						25	/* in %%, max total time that a STA may be active on the medium during a period of */
-																/*      (dot11BSSWidthChannelTransactionDelayFactor * dot11BSSWidthTriggerScanInterval) seconds without */
-																/*      being obligated to perform OBSS Scan operations. default is 25(== 0.25%) */
-
-struct PACKED rt_overlap_bss_scan_ie {
-	u16 ScanPassiveDwell;
-	u16 ScanActiveDwell;
-	u16 TriggerScanInt;	/* Trigger scan interval */
-	u16 PassiveTalPerChannel;	/* passive total per channel */
-	u16 ActiveTalPerChannel;	/* active total per channel */
-	u16 DelayFactor;	/* BSS width channel transition delay factor */
-	u16 ScanActThre;	/* Scan Activity threshold */
-};
-
-/*  7.3.2.56. 20/40 Coexistence element used in  Element ID = 72 = IE_2040_BSS_COEXIST */
-typedef union PACKED _BSS_2040_COEXIST_IE {
-	struct PACKED {
-		u8 InfoReq:1;
-		u8 Intolerant40:1;	/* Inter-BSS. set 1 when prohibits a receiving BSS from operating as a 20/40 Mhz BSS. */
-		u8 BSS20WidthReq:1;	/* Intra-BSS set 1 when prohibits a receiving AP from operating its BSS as a 20/40MHz BSS. */
-		u8 rsv:5;
-	} field;
-	u8 word;
-} BSS_2040_COEXIST_IE, *PBSS_2040_COEXIST_IE;
-
-struct rt_trigger_eventa {
-	BOOLEAN bValid;
-	u8 BSSID[6];
-	u8 RegClass;		/* Regulatory Class */
-	u16 Channel;
-	unsigned long CDCounter;	/* Maintain a separate count down counter for each Event A. */
-};
-
-/* 20/40 trigger event table */
-/* If one Event (A) is deleted or created, or if Event (B) is detected or not detected, STA should send 2040BSSCoexistence to AP. */
-#define MAX_TRIGGER_EVENT		64
-struct rt_trigger_event_tab {
-	u8 EventANo;
-	struct rt_trigger_eventa EventA[MAX_TRIGGER_EVENT];
-	unsigned long EventBCountDown;	/* Count down counter for Event B. */
-};
-
-/* 7.3.27 20/40 Bss Coexistence Mgmt capability used in extended capabilities information IE( ID = 127 = IE_EXT_CAPABILITY). */
-/*      This is the first octet and was defined in 802.11n D3.03 and 802.11yD9.0 */
-struct PACKED rt_ext_cap_info_element {
-	u8 BssCoexistMgmtSupport:1;
-	u8 rsv:1;
-	u8 ExtendChannelSwitch:1;
-	u8 rsv2:5;
-};
-
-/* 802.11n 7.3.2.61 */
-struct PACKED rt_bss_2040_coexist_element {
-	u8 ElementID;	/* ID = IE_2040_BSS_COEXIST = 72 */
-	u8 Len;
-	BSS_2040_COEXIST_IE BssCoexistIe;
-};
-
-/*802.11n 7.3.2.59 */
-struct PACKED rt_bss_2040_intolerant_ch_report {
-	u8 ElementID;	/* ID = IE_2040_BSS_INTOLERANT_REPORT = 73 */
-	u8 Len;
-	u8 RegulatoryClass;
-	u8 ChList[0];
-};
-
-/* The structure for channel switch announcement IE. This is in 802.11n D3.03 */
-struct PACKED rt_cha_switch_announce_ie {
-	u8 SwitchMode;	/*channel switch mode */
-	u8 NewChannel;	/* */
-	u8 SwitchCount;	/* */
-};
-
-/* The structure for channel switch announcement IE. This is in 802.11n D3.03 */
-struct PACKED rt_sec_cha_offset_ie {
-	u8 SecondaryChannelOffset;	/* 1: Secondary above, 3: Secondary below, 0: no Secondary */
-};
-
-/* This structure is extracted from struct struct rt_ht_capability */
-struct rt_ht_phy_info {
-	BOOLEAN bHtEnable;	/* If we should use ht rate. */
-	BOOLEAN bPreNHt;	/* If we should use ht rate. */
-	/*Subtract from HT Capability IE */
-	u8 MCSSet[16];
-};
-
-/*This structure subtracts ralink supports from all 802.11n-related features. */
-/*Features not listed here but contained in 802.11n spec are not supported in rt2860. */
-struct rt_ht_capability {
-	u16 ChannelWidth:1;
-	u16 MimoPs:2;	/*mimo power safe MMPS_ */
-	u16 GF:1;		/*green field */
-	u16 ShortGIfor20:1;
-	u16 ShortGIfor40:1;	/*for40MHz */
-	u16 TxSTBC:1;
-	u16 RxSTBC:2;	/* 2 bits */
-	u16 AmsduEnable:1;	/* Enable to transmit A-MSDU. Suggest disable. We should use A-MPDU to gain best benefit of 802.11n */
-	u16 AmsduSize:1;	/* Max receiving A-MSDU size */
-	u16 rsv:5;
-
-	/*Subtract from Addiont HT INFO IE */
-	u8 MaxRAmpduFactor:2;
-	u8 MpduDensity:3;
-	u8 ExtChanOffset:2;	/* Please note the difference with following     u8   NewExtChannelOffset; from 802.11n */
-	u8 RecomWidth:1;
-
-	u16 OperaionMode:2;
-	u16 NonGfPresent:1;
-	u16 rsv3:1;
-	u16 OBSS_NonHTExist:1;
-	u16 rsv2:11;
-
-	/* New Extension Channel Offset IE */
-	u8 NewExtChannelOffset;
-	/* Extension Capability IE = 127 */
-	u8 BSSCoexist2040;
-};
-
-/*   field in Additional HT Information IE . */
-struct PACKED rt_add_htinfo {
-	u8 ExtChanOffset:2;
-	u8 RecomWidth:1;
-	u8 RifsMode:1;
-	u8 S_PSMPSup:1;	/*Indicate support for scheduled PSMP */
-	u8 SerInterGranu:3;	/*service interval granularity */
-};
-
-struct PACKED rt_add_htinfo2 {
-	u16 OperaionMode:2;
-	u16 NonGfPresent:1;
-	u16 rsv:1;
-	u16 OBSS_NonHTExist:1;
-	u16 rsv2:11;
-};
-
-/* TODO: Need sync with spec about the definition of StbcMcs. In Draft 3.03, it's reserved. */
-struct PACKED rt_add_htinfo3 {
-	u16 StbcMcs:6;
-	u16 DualBeacon:1;
-	u16 DualCTSProtect:1;
-	u16 STBCBeacon:1;
-	u16 LsigTxopProt:1;	/* L-SIG TXOP protection full support */
-	u16 PcoActive:1;
-	u16 PcoPhase:1;
-	u16 rsv:4;
-};
-
-#define SIZE_ADD_HT_INFO_IE		22
-struct PACKED rt_add_ht_info_ie {
-	u8 ControlChan;
-	struct rt_add_htinfo AddHtInfo;
-	struct rt_add_htinfo2 AddHtInfo2;
-	struct rt_add_htinfo3 AddHtInfo3;
-	u8 MCSSet[16];	/* Basic MCS set */
-};
-
-struct PACKED rt_new_ext_chan_ie {
-	u8 NewExtChanOffset;
-};
-
-struct PACKED rt_frame_802_11 {
-	struct rt_header_802_11 Hdr;
-	u8 Octet[1];
-};
-
-/* QoSNull embedding of management action. When HT Control MA field set to 1. */
-struct PACKED rt_ma_body {
-	u8 Category;
-	u8 Action;
-	u8 Octet[1];
-};
-
-struct PACKED rt_header_802_3 {
-	u8 DAAddr1[MAC_ADDR_LEN];
-	u8 SAAddr2[MAC_ADDR_LEN];
-	u8 Octet[2];
-};
-/*//Block ACK related format */
-/* 2-byte BA Parameter  field  in       DELBA frames to terminate an already set up bA */
-struct PACKED rt_delba_parm {
-	u16 Rsv:11;		/* always set to 0 */
-	u16 Initiator:1;	/* 1: originator    0:recipient */
-	u16 TID:4;		/* value of TC os TS */
-};
-
-/* 2-byte BA Parameter Set field  in ADDBA frames to signal parm for setting up a BA */
-struct PACKED rt_ba_parm {
-	u16 AMSDUSupported:1;	/* 0: not permitted             1: permitted */
-	u16 BAPolicy:1;	/* 1: immediately BA    0:delayed BA */
-	u16 TID:4;		/* value of TC os TS */
-	u16 BufSize:10;	/* number of buffer of size 2304 octetsr */
-};
-
-/* 2-byte BA Starting Seq CONTROL field */
-typedef union PACKED _BASEQ_CONTROL {
-	struct PACKED {
-		u16 FragNum:4;	/* always set to 0 */
-		u16 StartSeq:12;	/* sequence number of the 1st MSDU for which this BAR is sent */
-	} field;
-	u16 word;
-} BASEQ_CONTROL, *PBASEQ_CONTROL;
-
-/*BAControl and BARControl are the same */
-/* 2-byte BA CONTROL field in BA frame */
-struct PACKED rt_ba_control {
-	u16 ACKPolicy:1;	/* only related to N-Delayed BA. But not support in RT2860b. 0:NormalACK  1:No ACK */
-	u16 MTID:1;		/*EWC V1.24 */
-	u16 Compressed:1;
-	u16 Rsv:9;
-	u16 TID:4;
-};
-
-/* 2-byte BAR CONTROL field in BAR frame */
-struct PACKED rt_bar_control {
-	u16 ACKPolicy:1;	/* 0:normal ack,  1:no ack. */
-	u16 MTID:1;		/*if this bit1, use  struct rt_frame_mtba_req,  if 0, use struct rt_frame_ba_req */
-	u16 Compressed:1;
-	u16 Rsv1:9;
-	u16 TID:4;
-};
-
-/* BARControl in MTBAR frame */
-struct PACKED rt_mtbar_control {
-	u16 ACKPolicy:1;
-	u16 MTID:1;
-	u16 Compressed:1;
-	u16 Rsv1:9;
-	u16 NumTID:4;
-};
-
-struct PACKED rt_per_tid_info {
-	u16 Rsv1:12;
-	u16 TID:4;
-};
-
-struct rt_each_tid {
-	struct rt_per_tid_info PerTID;
-	BASEQ_CONTROL BAStartingSeq;
-};
-
-/* BAREQ AND MTBAREQ have the same subtype BAR, 802.11n BAR use compressed bitmap. */
-struct PACKED rt_frame_ba_req {
-	struct rt_frame_control FC;
-	u16 Duration;
-	u8 Addr1[MAC_ADDR_LEN];
-	u8 Addr2[MAC_ADDR_LEN];
-	struct rt_bar_control BARControl;
-	BASEQ_CONTROL BAStartingSeq;
-};
-
-struct PACKED rt_frame_mtba_req {
-	struct rt_frame_control FC;
-	u16 Duration;
-	u8 Addr1[MAC_ADDR_LEN];
-	u8 Addr2[MAC_ADDR_LEN];
-	struct rt_mtbar_control MTBARControl;
-	struct rt_per_tid_info PerTIDInfo;
-	BASEQ_CONTROL BAStartingSeq;
-};
-
-/* Compressed format is mandatory in HT STA */
-struct PACKED rt_frame_mtba {
-	struct rt_frame_control FC;
-	u16 Duration;
-	u8 Addr1[MAC_ADDR_LEN];
-	u8 Addr2[MAC_ADDR_LEN];
-	struct rt_ba_control BAControl;
-	BASEQ_CONTROL BAStartingSeq;
-	u8 BitMap[8];
-};
-
-struct PACKED rt_frame_psmp_action {
-	struct rt_header_802_11 Hdr;
-	u8 Category;
-	u8 Action;
-	u8 Psmp;		/* 7.3.1.25 */
-};
-
-struct PACKED rt_frame_action_hdr {
-	struct rt_header_802_11 Hdr;
-	u8 Category;
-	u8 Action;
-};
-
-/*Action Frame */
-/*Action Frame  Category:Spectrum,  Action:Channel Switch. 7.3.2.20 */
-struct PACKED rt_chan_switch_announce {
-	u8 ElementID;	/* ID = IE_CHANNEL_SWITCH_ANNOUNCEMENT = 37 */
-	u8 Len;
-	struct rt_cha_switch_announce_ie CSAnnounceIe;
-};
-
-/*802.11n : 7.3.2.20a */
-struct PACKED rt_second_chan_offset {
-	u8 ElementID;	/* ID = IE_SECONDARY_CH_OFFSET = 62 */
-	u8 Len;
-	struct rt_sec_cha_offset_ie SecChOffsetIe;
-};
-
-struct PACKED rt_frame_spetrum_cs {
-	struct rt_header_802_11 Hdr;
-	u8 Category;
-	u8 Action;
-	struct rt_chan_switch_announce CSAnnounce;
-	struct rt_second_chan_offset SecondChannel;
-};
-
-struct PACKED rt_frame_addba_req {
-	struct rt_header_802_11 Hdr;
-	u8 Category;
-	u8 Action;
-	u8 Token;		/* 1 */
-	struct rt_ba_parm BaParm;		/*  2 - 10 */
-	u16 TimeOutValue;	/* 0 - 0 */
-	BASEQ_CONTROL BaStartSeq;	/* 0-0 */
-};
-
-struct PACKED rt_frame_addba_rsp {
-	struct rt_header_802_11 Hdr;
-	u8 Category;
-	u8 Action;
-	u8 Token;
-	u16 StatusCode;
-	struct rt_ba_parm BaParm;		/*0 - 2 */
-	u16 TimeOutValue;
-};
-
-struct PACKED rt_frame_delba_req {
-	struct rt_header_802_11 Hdr;
-	u8 Category;
-	u8 Action;
-	struct rt_delba_parm DelbaParm;
-	u16 ReasonCode;
-};
-
-/*7.2.1.7 */
-struct PACKED rt_frame_bar {
-	struct rt_frame_control FC;
-	u16 Duration;
-	u8 Addr1[MAC_ADDR_LEN];
-	u8 Addr2[MAC_ADDR_LEN];
-	struct rt_bar_control BarControl;
-	BASEQ_CONTROL StartingSeq;
-};
-
-/*7.2.1.7 */
-struct PACKED rt_frame_ba {
-	struct rt_frame_control FC;
-	u16 Duration;
-	u8 Addr1[MAC_ADDR_LEN];
-	u8 Addr2[MAC_ADDR_LEN];
-	struct rt_bar_control BarControl;
-	BASEQ_CONTROL StartingSeq;
-	u8 bitmask[8];
-};
-
-/* Radio Measurement Request Frame Format */
-struct PACKED rt_frame_rm_req_action {
-	struct rt_header_802_11 Hdr;
-	u8 Category;
-	u8 Action;
-	u8 Token;
-	u16 Repetition;
-	u8 data[0];
-};
-
-struct PACKED rt_ht_ext_channel_switch_announcement_ie {
-	u8 ID;
-	u8 Length;
-	u8 ChannelSwitchMode;
-	u8 NewRegClass;
-	u8 NewChannelNum;
-	u8 ChannelSwitchCount;
-};
-
-/* */
-/* _Limit must be the 2**n - 1 */
-/* _SEQ1 , _SEQ2 must be within 0 ~ _Limit */
-/* */
-#define SEQ_STEPONE(_SEQ1, _SEQ2, _Limit)	((_SEQ1 == ((_SEQ2+1) & _Limit)))
-#define SEQ_SMALLER(_SEQ1, _SEQ2, _Limit)	(((_SEQ1-_SEQ2) & ((_Limit+1)>>1)))
-#define SEQ_LARGER(_SEQ1, _SEQ2, _Limit)	((_SEQ1 != _SEQ2) && !(((_SEQ1-_SEQ2) & ((_Limit+1)>>1))))
-#define SEQ_WITHIN_WIN(_SEQ1, _SEQ2, _WIN, _Limit) (SEQ_LARGER(_SEQ1, _SEQ2, _Limit) &&  \
-												SEQ_SMALLER(_SEQ1, ((_SEQ2+_WIN+1)&_Limit), _Limit))
-
-/* */
-/* Contention-free parameter (without ID and Length) */
-/* */
-struct PACKED rt_cf_parm {
-	BOOLEAN bValid;		/* 1: variable contains valid value */
-	u8 CfpCount;
-	u8 CfpPeriod;
-	u16 CfpMaxDuration;
-	u16 CfpDurRemaining;
-};
-
-struct rt_cipher_suite {
-	NDIS_802_11_ENCRYPTION_STATUS PairCipher;	/* Unicast cipher 1, this one has more secured cipher suite */
-	NDIS_802_11_ENCRYPTION_STATUS PairCipherAux;	/* Unicast cipher 2 if AP announce two unicast cipher suite */
-	NDIS_802_11_ENCRYPTION_STATUS GroupCipher;	/* Group cipher */
-	u16 RsnCapability;	/* RSN capability from beacon */
-	BOOLEAN bMixMode;	/* Indicate Pair & Group cipher might be different */
-};
-
-/* EDCA configuration from AP's BEACON/ProbeRsp */
-struct rt_edca_parm {
-	BOOLEAN bValid;		/* 1: variable contains valid value */
-	BOOLEAN bAdd;		/* 1: variable contains valid value */
-	BOOLEAN bQAck;
-	BOOLEAN bQueueRequest;
-	BOOLEAN bTxopRequest;
-	BOOLEAN bAPSDCapable;
-/*  BOOLEAN     bMoreDataAck; */
-	u8 EdcaUpdateCount;
-	u8 Aifsn[4];		/* 0:AC_BK, 1:AC_BE, 2:AC_VI, 3:AC_VO */
-	u8 Cwmin[4];
-	u8 Cwmax[4];
-	u16 Txop[4];		/* in unit of 32-us */
-	BOOLEAN bACM[4];	/* 1: Admission Control of AC_BK is mandatory */
-};
-
-/* QBSS LOAD information from QAP's BEACON/ProbeRsp */
-struct rt_qbss_load_parm {
-	BOOLEAN bValid;		/* 1: variable contains valid value */
-	u16 StaNum;
-	u8 ChannelUtilization;
-	u16 RemainingAdmissionControl;	/* in unit of 32-us */
-};
-
-/* QBSS Info field in QSTA's assoc req */
-struct PACKED rt_qbss_sta_info_parm {
-	u8 UAPSD_AC_VO:1;
-	u8 UAPSD_AC_VI:1;
-	u8 UAPSD_AC_BK:1;
-	u8 UAPSD_AC_BE:1;
-	u8 Rsv1:1;
-	u8 MaxSPLength:2;
-	u8 Rsv2:1;
-};
-
-/* QBSS Info field in QAP's Beacon/ProbeRsp */
-struct PACKED rt_qbss_ap_info_parm {
-	u8 ParamSetCount:4;
-	u8 Rsv:3;
-	u8 UAPSD:1;
-};
-
-/* QOS Capability reported in QAP's BEACON/ProbeRsp */
-/* QOS Capability sent out in QSTA's AssociateReq/ReAssociateReq */
-struct rt_qos_capability_parm {
-	BOOLEAN bValid;		/* 1: variable contains valid value */
-	BOOLEAN bQAck;
-	BOOLEAN bQueueRequest;
-	BOOLEAN bTxopRequest;
-/*  BOOLEAN     bMoreDataAck; */
-	u8 EdcaUpdateCount;
-};
-
-struct rt_wpa_ie {
-	u8 IELen;
-	u8 IE[MAX_CUSTOM_LEN];
-};
-
-struct rt_bss_entry {
-	u8 Bssid[MAC_ADDR_LEN];
-	u8 Channel;
-	u8 CentralChannel;	/*Store the wide-band central channel for 40MHz. used in 40MHz AP. Or this is the same as Channel. */
-	u8 BssType;
-	u16 AtimWin;
-	u16 BeaconPeriod;
-
-	u8 SupRate[MAX_LEN_OF_SUPPORTED_RATES];
-	u8 SupRateLen;
-	u8 ExtRate[MAX_LEN_OF_SUPPORTED_RATES];
-	u8 ExtRateLen;
-	struct rt_ht_capability_ie HtCapability;
-	u8 HtCapabilityLen;
-	struct rt_add_ht_info_ie AddHtInfo;	/* AP might use this additional ht info IE */
-	u8 AddHtInfoLen;
-	u8 NewExtChanOffset;
-	char Rssi;
-	u8 Privacy;		/* Indicate security function ON/OFF. Don't mess up with auth mode. */
-	u8 Hidden;
-
-	u16 DtimPeriod;
-	u16 CapabilityInfo;
-
-	u16 CfpCount;
-	u16 CfpPeriod;
-	u16 CfpMaxDuration;
-	u16 CfpDurRemaining;
-	u8 SsidLen;
-	char Ssid[MAX_LEN_OF_SSID];
-
-	unsigned long LastBeaconRxTime;	/* OS's timestamp */
-
-	BOOLEAN bSES;
-
-	/* New for WPA2 */
-	struct rt_cipher_suite WPA;	/* AP announced WPA cipher suite */
-	struct rt_cipher_suite WPA2;	/* AP announced WPA2 cipher suite */
-
-	/* New for microsoft WPA support */
-	struct rt_ndis_802_11_fixed_ies FixIEs;
-	NDIS_802_11_AUTHENTICATION_MODE AuthModeAux;	/* Addition mode for WPA2 / WPA capable AP */
-	NDIS_802_11_AUTHENTICATION_MODE AuthMode;
-	NDIS_802_11_WEP_STATUS WepStatus;	/* Unicast Encryption Algorithm extract from VAR_IE */
-	u16 VarIELen;	/* Length of next VIE include EID & Length */
-	u8 VarIEs[MAX_VIE_LEN];
-
-	/* CCX Ckip information */
-	u8 CkipFlag;
-
-	/* CCX 2 TSF */
-	u8 PTSF[4];		/* Parent TSF */
-	u8 TTSF[8];		/* Target TSF */
-
-	/* 802.11e d9, and WMM */
-	struct rt_edca_parm EdcaParm;
-	struct rt_qos_capability_parm QosCapability;
-	struct rt_qbss_load_parm QbssLoad;
-	struct rt_wpa_ie WpaIE;
-	struct rt_wpa_ie RsnIE;
-};
-
-struct rt_bss_table {
-	u8 BssNr;
-	u8 BssOverlapNr;
-	struct rt_bss_entry BssEntry[MAX_LEN_OF_BSS_TABLE];
-};
-
-struct rt_mlme_queue_elem {
-	unsigned long Machine;
-	unsigned long MsgType;
-	unsigned long MsgLen;
-	u8 Msg[MGMT_DMA_BUFFER_SIZE];
-	LARGE_INTEGER TimeStamp;
-	u8 Rssi0;
-	u8 Rssi1;
-	u8 Rssi2;
-	u8 Signal;
-	u8 Channel;
-	u8 Wcid;
-	BOOLEAN Occupied;
-};
-
-struct rt_mlme_queue {
-	unsigned long Num;
-	unsigned long Head;
-	unsigned long Tail;
-	spinlock_t Lock;
-	struct rt_mlme_queue_elem Entry[MAX_LEN_OF_MLME_QUEUE];
-};
-
-typedef void(*STATE_MACHINE_FUNC) (void *Adaptor, struct rt_mlme_queue_elem *Elem);
-
-struct rt_state_machine {
-	unsigned long Base;
-	unsigned long NrState;
-	unsigned long NrMsg;
-	unsigned long CurrState;
-	STATE_MACHINE_FUNC *TransFunc;
-};
-
-/* MLME AUX data structure that holds temporarliy settings during a connection attempt. */
-/* Once this attempt succeeds, all settings will be copy to pAd->StaActive. */
-/* A connection attempt (user set OID, roaming, CCX fast roaming,..) consists of */
-/* several steps (JOIN, AUTH, ASSOC or REASSOC) and may fail at any step. We purposely */
-/* separate this under-trial settings away from pAd->StaActive so that once */
-/* this new attempt failed, driver can auto-recover back to the active settings. */
-struct rt_mlme_aux {
-	u8 BssType;
-	u8 Ssid[MAX_LEN_OF_SSID];
-	u8 SsidLen;
-	u8 Bssid[MAC_ADDR_LEN];
-	u8 AutoReconnectSsid[MAX_LEN_OF_SSID];
-	u8 AutoReconnectSsidLen;
-	u16 Alg;
-	u8 ScanType;
-	u8 Channel;
-	u8 CentralChannel;
-	u16 Aid;
-	u16 CapabilityInfo;
-	u16 BeaconPeriod;
-	u16 CfpMaxDuration;
-	u16 CfpPeriod;
-	u16 AtimWin;
-
-	/* Copy supported rate from desired AP's beacon. We are trying to match */
-	/* AP's supported and extended rate settings. */
-	u8 SupRate[MAX_LEN_OF_SUPPORTED_RATES];
-	u8 ExtRate[MAX_LEN_OF_SUPPORTED_RATES];
-	u8 SupRateLen;
-	u8 ExtRateLen;
-	struct rt_ht_capability_ie HtCapability;
-	u8 HtCapabilityLen;
-	struct rt_add_ht_info_ie AddHtInfo;	/* AP might use this additional ht info IE */
-	u8 NewExtChannelOffset;
-	/*struct rt_ht_capability      SupportedHtPhy; */
-
-	/* new for QOS */
-	struct rt_qos_capability_parm APQosCapability;	/* QOS capability of the current associated AP */
-	struct rt_edca_parm APEdcaParm;	/* EDCA parameters of the current associated AP */
-	struct rt_qbss_load_parm APQbssLoad;	/* QBSS load of the current associated AP */
-
-	/* new to keep Ralink specific feature */
-	unsigned long APRalinkIe;
-
-	struct rt_bss_table SsidBssTab;	/* AP list for the same SSID */
-	struct rt_bss_table RoamTab;	/* AP list eligible for roaming */
-	unsigned long BssIdx;
-	unsigned long RoamIdx;
-
-	BOOLEAN CurrReqIsFromNdis;
-
-	struct rt_ralink_timer BeaconTimer, ScanTimer;
-	struct rt_ralink_timer AuthTimer;
-	struct rt_ralink_timer AssocTimer, ReassocTimer, DisassocTimer;
-};
-
-struct rt_mlme_addba_req {
-	u8 Wcid;		/* */
-	u8 pAddr[MAC_ADDR_LEN];
-	u8 BaBufSize;
-	u16 TimeOutValue;
-	u8 TID;
-	u8 Token;
-	u16 BaStartSeq;
-};
-
-struct rt_mlme_delba_req {
-	u8 Wcid;		/* */
-	u8 Addr[MAC_ADDR_LEN];
-	u8 TID;
-	u8 Initiator;
-};
-
-/* assoc struct is equal to reassoc */
-struct rt_mlme_assoc_req {
-	u8 Addr[MAC_ADDR_LEN];
-	u16 CapabilityInfo;
-	u16 ListenIntv;
-	unsigned long Timeout;
-};
-
-struct rt_mlme_disassoc_req {
-	u8 Addr[MAC_ADDR_LEN];
-	u16 Reason;
-};
-
-struct rt_mlme_auth_req {
-	u8 Addr[MAC_ADDR_LEN];
-	u16 Alg;
-	unsigned long Timeout;
-};
-
-struct rt_mlme_deauth_req {
-	u8 Addr[MAC_ADDR_LEN];
-	u16 Reason;
-};
-
-struct rt_mlme_join_req {
-	unsigned long BssIdx;
-};
-
-struct rt_mlme_scan_req {
-	u8 Bssid[MAC_ADDR_LEN];
-	u8 BssType;
-	u8 ScanType;
-	u8 SsidLen;
-	char Ssid[MAX_LEN_OF_SSID];
-};
-
-struct rt_mlme_start_req {
-	char Ssid[MAX_LEN_OF_SSID];
-	u8 SsidLen;
-};
-
-struct PACKED rt_eid {
-	u8 Eid;
-	u8 Len;
-	u8 Octet[1];
-};
-
-struct PACKED rt_rtmp_tx_rate_switch {
-	u8 ItemNo;
-	u8 STBC:1;
-	u8 ShortGI:1;
-	u8 BW:1;
-	u8 Rsv1:1;
-	u8 Mode:2;
-	u8 Rsv2:2;
-	u8 CurrMCS;
-	u8 TrainUp;
-	u8 TrainDown;
-};
-
-/* ========================== AP mlme.h =============================== */
-#define TBTT_PRELOAD_TIME       384	/* usec. LomgPreamble + 24-byte at 1Mbps */
-#define DEFAULT_DTIM_PERIOD     1
-
-#define MAC_TABLE_AGEOUT_TIME			300	/* unit: sec */
-#define MAC_TABLE_ASSOC_TIMEOUT			5	/* unit: sec */
-#define MAC_TABLE_FULL(Tab)				((Tab).size == MAX_LEN_OF_MAC_TABLE)
-
-/* AP shall drop the sta if continue Tx fail count reach it. */
-#define MAC_ENTRY_LIFE_CHECK_CNT		20	/* packet cnt. */
-
-/* Value domain of pMacEntry->Sst */
-typedef enum _Sst {
-	SST_NOT_AUTH,		/* 0: equivalent to IEEE 802.11/1999 state 1 */
-	SST_AUTH,		/* 1: equivalent to IEEE 802.11/1999 state 2 */
-	SST_ASSOC		/* 2: equivalent to IEEE 802.11/1999 state 3 */
-} SST;
-
-/* value domain of pMacEntry->AuthState */
-typedef enum _AuthState {
-	AS_NOT_AUTH,
-	AS_AUTH_OPEN,		/* STA has been authenticated using OPEN SYSTEM */
-	AS_AUTH_KEY,		/* STA has been authenticated using SHARED KEY */
-	AS_AUTHENTICATING	/* STA is waiting for AUTH seq#3 using SHARED KEY */
-} AUTH_STATE;
-
-/*for-wpa value domain of pMacEntry->WpaState  802.1i D3   p.114 */
-typedef enum _ApWpaState {
-	AS_NOTUSE,		/* 0 */
-	AS_DISCONNECT,		/* 1 */
-	AS_DISCONNECTED,	/* 2 */
-	AS_INITIALIZE,		/* 3 */
-	AS_AUTHENTICATION,	/* 4 */
-	AS_AUTHENTICATION2,	/* 5 */
-	AS_INITPMK,		/* 6 */
-	AS_INITPSK,		/* 7 */
-	AS_PTKSTART,		/* 8 */
-	AS_PTKINIT_NEGOTIATING,	/* 9 */
-	AS_PTKINITDONE,		/* 10 */
-	AS_UPDATEKEYS,		/* 11 */
-	AS_INTEGRITY_FAILURE,	/* 12 */
-	AS_KEYUPDATE,		/* 13 */
-} AP_WPA_STATE;
-
-/* for-wpa value domain of pMacEntry->WpaState  802.1i D3   p.114 */
-typedef enum _GTKState {
-	REKEY_NEGOTIATING,
-	REKEY_ESTABLISHED,
-	KEYERROR,
-} GTK_STATE;
-
-/*  for-wpa  value domain of pMacEntry->WpaState  802.1i D3   p.114 */
-typedef enum _WpaGTKState {
-	SETKEYS,
-	SETKEYS_DONE,
-} WPA_GTK_STATE;
-/* ====================== end of AP mlme.h ============================ */
-
-#endif /* MLME_H__ */
diff -druN linux-2.6.39-libre/drivers/staging/rt2860/oid.h linux-3.0-rc7-libre/drivers/staging/rt2860/oid.h
--- linux-2.6.39-libre/drivers/staging/rt2860/oid.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rt2860/oid.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,779 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, 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.             *
- *                                                                       *
- *************************************************************************
-
-	Module Name:
-	oid.h
-
-	Abstract:
-
-	Revision History:
-	Who			When			What
-	--------	----------		----------------------------------------------
-	Name			Date			Modification logs
-	Justin P. Mattock 	11/07/2010	Fix typos in comments
-*/
-#ifndef _OID_H_
-#define _OID_H_
-
-/*#include <linux/wireless.h> */
-
-#ifndef TRUE
-#define TRUE				1
-#endif
-#ifndef FALSE
-#define FALSE				0
-#endif
-/* */
-/* IEEE 802.11 Structures and definitions */
-/* */
-#define MAX_TX_POWER_LEVEL              100	/* mW */
-#define MAX_RSSI_TRIGGER                -10	/* dBm */
-#define MIN_RSSI_TRIGGER                -200	/* dBm */
-#define MAX_FRAG_THRESHOLD              2346	/* byte count */
-#define MIN_FRAG_THRESHOLD              256	/* byte count */
-#define MAX_RTS_THRESHOLD               2347	/* byte count */
-
-/* new types for Media Specific Indications */
-/* Extension channel offset */
-#define EXTCHA_NONE			0
-#define EXTCHA_ABOVE		0x1
-#define EXTCHA_BELOW		0x3
-
-/* BW */
-#define BAND_WIDTH_20		0
-#define BAND_WIDTH_40		1
-#define BAND_WIDTH_BOTH		2
-#define BAND_WIDTH_10		3	/* 802.11j has 10MHz. This definition is for internal usage. doesn't fill in the IE or other field. */
-/* SHORTGI */
-#define GAP_INTERVAL_400	1	/* only support in HT mode */
-#define GAP_INTERVAL_800	0
-#define GAP_INTERVAL_BOTH	2
-
-#define NdisMediaStateConnected			1
-#define NdisMediaStateDisconnected		0
-
-#define NDIS_802_11_LENGTH_SSID         32
-#define NDIS_802_11_LENGTH_RATES        8
-#define NDIS_802_11_LENGTH_RATES_EX     16
-#define MAC_ADDR_LENGTH                 6
-/*#define MAX_NUM_OF_CHS                                        49 // 14 channels @2.4G +  12@UNII + 4 @MMAC + 11 @HiperLAN2 + 7 @Japan + 1 as NULL termination */
-#define MAX_NUM_OF_CHS				54	/* 14 channels @2.4G +  12@UNII(lower/middle) + 16@HiperLAN2 + 11@UNII(upper) + 0 @Japan + 1 as NULL termination */
-#define MAX_NUMBER_OF_EVENT				10	/* entry # in EVENT table */
-#define MAX_NUMBER_OF_MAC				32	/* if MAX_MBSSID_NUM is 8, this value can't be larger than 211 */
-#define MAX_NUMBER_OF_ACL				64
-#define MAX_LENGTH_OF_SUPPORT_RATES		12	/* 1, 2, 5.5, 11, 6, 9, 12, 18, 24, 36, 48, 54 */
-#define MAX_NUMBER_OF_DLS_ENTRY			4
-
-#define RT_QUERY_SIGNAL_CONTEXT				0x0402
-#define RT_SET_IAPP_PID				0x0404
-#define RT_SET_APD_PID						0x0405
-#define RT_SET_DEL_MAC_ENTRY				0x0406
-#define RT_QUERY_EVENT_TABLE			0x0407
-/* */
-/* IEEE 802.11 OIDs */
-/* */
-#define	OID_GET_SET_TOGGLE			0x8000
-#define	OID_GET_SET_FROM_UI			0x4000
-
-#define OID_802_11_ADD_WEP			0x0112
-#define OID_802_11_DISASSOCIATE			0x0114
-#define OID_802_11_BSSID_LIST_SCAN		0x0508
-#define OID_802_11_SSID				0x0509
-#define OID_802_11_BSSID			0x050A
-#define OID_802_11_MIC_FAILURE_REPORT_FRAME	0x0528
-
-#define	RT_OID_DEVICE_NAME							0x0607
-#define	RT_OID_VERSION_INFO							0x0608
-#define	OID_802_11_BSSID_LIST						0x0609
-#define	OID_802_3_CURRENT_ADDRESS					0x060A
-#define	OID_GEN_MEDIA_CONNECT_STATUS				0x060B
-#define	RT_OID_802_11_QUERY_LINK_STATUS				0x060C
-#define	OID_802_11_RSSI								0x060D
-#define	OID_802_11_STATISTICS						0x060E
-#define	OID_GEN_RCV_OK								0x060F
-#define	OID_GEN_RCV_NO_BUFFER						0x0610
-#define	RT_OID_802_11_QUERY_EEPROM_VERSION			0x0611
-#define	RT_OID_802_11_QUERY_FIRMWARE_VERSION		0x0612
-#define	RT_OID_802_11_QUERY_LAST_RX_RATE			0x0613
-#define	RT_OID_802_11_TX_POWER_LEVEL_1				0x0614
-#define	RT_OID_802_11_QUERY_PIDVID					0x0615
-/*for WPA_SUPPLICANT_SUPPORT */
-#define OID_SET_COUNTERMEASURES                     0x0616
-#define RT_OID_WPA_SUPPLICANT_SUPPORT               0x0621
-#define RT_OID_WE_VERSION_COMPILED                  0x0622
-#define RT_OID_NEW_DRIVER                           0x0623
-
-#define RT_OID_DRIVER_DEVICE_NAME                   0x0645
-#define RT_OID_QUERY_MULTIPLE_CARD_SUPPORT          0x0647
-
-typedef enum _NDIS_802_11_STATUS_TYPE {
-	Ndis802_11StatusType_Authentication,
-	Ndis802_11StatusType_MediaStreamMode,
-	Ndis802_11StatusType_PMKID_CandidateList,
-	Ndis802_11StatusTypeMax	/* not a real type, defined as an upper bound */
-} NDIS_802_11_STATUS_TYPE, *PNDIS_802_11_STATUS_TYPE;
-
-typedef u8 NDIS_802_11_MAC_ADDRESS[6];
-
-struct rt_ndis_802_11_status_indication {
-	NDIS_802_11_STATUS_TYPE StatusType;
-};
-
-/* mask for authentication/integrity fields */
-#define NDIS_802_11_AUTH_REQUEST_AUTH_FIELDS        0x0f
-
-#define NDIS_802_11_AUTH_REQUEST_REAUTH             0x01
-#define NDIS_802_11_AUTH_REQUEST_KEYUPDATE          0x02
-#define NDIS_802_11_AUTH_REQUEST_PAIRWISE_ERROR     0x06
-#define NDIS_802_11_AUTH_REQUEST_GROUP_ERROR        0x0E
-
-struct rt_ndis_802_11_authentication_request {
-	unsigned long Length;		/* Length of structure */
-	NDIS_802_11_MAC_ADDRESS Bssid;
-	unsigned long Flags;
-};
-
-/*Added new types for PMKID Candidate lists. */
-struct rt_pmkid_candidate {
-	NDIS_802_11_MAC_ADDRESS BSSID;
-	unsigned long Flags;
-};
-
-struct rt_ndis_802_11_pmkid_candidate_list {
-	unsigned long Version;		/* Version of the structure */
-	unsigned long NumCandidates;	/* No. of pmkid candidates */
-	struct rt_pmkid_candidate CandidateList[1];
-};
-
-/*Flags for PMKID Candidate list structure */
-#define NDIS_802_11_PMKID_CANDIDATE_PREAUTH_ENABLED	0x01
-
-/* Added new types for OFDM 5G and 2.4G */
-typedef enum _NDIS_802_11_NETWORK_TYPE {
-	Ndis802_11FH,
-	Ndis802_11DS,
-	Ndis802_11OFDM5,
-	Ndis802_11OFDM24,
-	Ndis802_11Automode,
-	Ndis802_11OFDM5_N,
-	Ndis802_11OFDM24_N,
-	Ndis802_11NetworkTypeMax	/* not a real type, defined as an upper bound */
-} NDIS_802_11_NETWORK_TYPE, *PNDIS_802_11_NETWORK_TYPE;
-
-struct rt_ndis_802_11_network_type_list {
-	u32 NumberOfItems;	/* in list below, at least 1 */
-	NDIS_802_11_NETWORK_TYPE NetworkType[1];
-};
-
-typedef enum _NDIS_802_11_POWER_MODE {
-	Ndis802_11PowerModeCAM,
-	Ndis802_11PowerModeMAX_PSP,
-	Ndis802_11PowerModeFast_PSP,
-	Ndis802_11PowerModeLegacy_PSP,
-	Ndis802_11PowerModeMax	/* not a real mode, defined as an upper bound */
-} NDIS_802_11_POWER_MODE, *PNDIS_802_11_POWER_MODE;
-
-typedef unsigned long NDIS_802_11_TX_POWER_LEVEL;	/* in milliwatts */
-
-/* */
-/* Received Signal Strength Indication */
-/* */
-typedef long NDIS_802_11_RSSI;	/* in dBm */
-
-struct rt_ndis_802_11_configuration_fh {
-	unsigned long Length;		/* Length of structure */
-	unsigned long HopPattern;	/* As defined by 802.11, MSB set */
-	unsigned long HopSet;		/* to one if non-802.11 */
-	unsigned long DwellTime;	/* units are Kusec */
-};
-
-struct rt_ndis_802_11_configuration {
-	unsigned long Length;		/* Length of structure */
-	unsigned long BeaconPeriod;	/* units are Kusec */
-	unsigned long ATIMWindow;	/* units are Kusec */
-	unsigned long DSConfig;		/* Frequency, units are kHz */
-	struct rt_ndis_802_11_configuration_fh FHConfig;
-};
-
-struct rt_ndis_802_11_statistics {
-	unsigned long Length;		/* Length of structure */
-	LARGE_INTEGER TransmittedFragmentCount;
-	LARGE_INTEGER MulticastTransmittedFrameCount;
-	LARGE_INTEGER FailedCount;
-	LARGE_INTEGER RetryCount;
-	LARGE_INTEGER MultipleRetryCount;
-	LARGE_INTEGER RTSSuccessCount;
-	LARGE_INTEGER RTSFailureCount;
-	LARGE_INTEGER ACKFailureCount;
-	LARGE_INTEGER FrameDuplicateCount;
-	LARGE_INTEGER ReceivedFragmentCount;
-	LARGE_INTEGER MulticastReceivedFrameCount;
-	LARGE_INTEGER FCSErrorCount;
-	LARGE_INTEGER TKIPLocalMICFailures;
-	LARGE_INTEGER TKIPRemoteMICErrors;
-	LARGE_INTEGER TKIPICVErrors;
-	LARGE_INTEGER TKIPCounterMeasuresInvoked;
-	LARGE_INTEGER TKIPReplays;
-	LARGE_INTEGER CCMPFormatErrors;
-	LARGE_INTEGER CCMPReplays;
-	LARGE_INTEGER CCMPDecryptErrors;
-	LARGE_INTEGER FourWayHandshakeFailures;
-};
-
-typedef unsigned long NDIS_802_11_KEY_INDEX;
-typedef unsigned long long NDIS_802_11_KEY_RSC;
-
-#define MAX_RADIUS_SRV_NUM			2	/* 802.1x failover number */
-
-struct PACKED rt_radius_srv_info {
-	u32 radius_ip;
-	u32 radius_port;
-	u8 radius_key[64];
-	u8 radius_key_len;
-};
-
-struct PACKED rt_radius_key_info {
-	u8 radius_srv_num;
-	struct rt_radius_srv_info radius_srv_info[MAX_RADIUS_SRV_NUM];
-	u8 ieee8021xWEP;	/* dynamic WEP */
-	u8 key_index;
-	u8 key_length;	/* length of key in bytes */
-	u8 key_material[13];
-};
-
-/* It's used by 802.1x daemon to require relative configuration */
-struct PACKED rt_radius_conf {
-	u32 Length;		/* Length of this structure */
-	u8 mbss_num;		/* indicate multiple BSS number */
-	u32 own_ip_addr;
-	u32 retry_interval;
-	u32 session_timeout_interval;
-	u8 EAPifname[8][IFNAMSIZ];
-	u8 EAPifname_len[8];
-	u8 PreAuthifname[8][IFNAMSIZ];
-	u8 PreAuthifname_len[8];
-	struct rt_radius_key_info RadiusInfo[8];
-};
-
-/* Key mapping keys require a BSSID */
-struct rt_ndis_802_11_key {
-	u32 Length;		/* Length of this structure */
-	u32 KeyIndex;
-	u32 KeyLength;		/* length of key in bytes */
-	NDIS_802_11_MAC_ADDRESS BSSID;
-	NDIS_802_11_KEY_RSC KeyRSC;
-	u8 KeyMaterial[1];	/* variable length depending on above field */
-};
-
-struct rt_ndis_802_11_passphrase {
-	u32 KeyLength;		/* length of key in bytes */
-	NDIS_802_11_MAC_ADDRESS BSSID;
-	u8 KeyMaterial[1];	/* variable length depending on above field */
-};
-
-struct rt_ndis_802_11_remove_key {
-	u32 Length;		/* Length of this structure */
-	u32 KeyIndex;
-	NDIS_802_11_MAC_ADDRESS BSSID;
-};
-
-struct rt_ndis_802_11_wep {
-	u32 Length;		/* Length of this structure */
-	u32 KeyIndex;		/* 0 is the per-client key, 1-N are the */
-	/* global keys */
-	u32 KeyLength;		/* length of key in bytes */
-	u8 KeyMaterial[1];	/* variable length depending on above field */
-};
-
-typedef enum _NDIS_802_11_NETWORK_INFRASTRUCTURE {
-	Ndis802_11IBSS,
-	Ndis802_11Infrastructure,
-	Ndis802_11AutoUnknown,
-	Ndis802_11Monitor,
-	Ndis802_11InfrastructureMax	/* Not a real value, defined as upper bound */
-} NDIS_802_11_NETWORK_INFRASTRUCTURE, *PNDIS_802_11_NETWORK_INFRASTRUCTURE;
-
-/* Add new authentication modes */
-typedef enum _NDIS_802_11_AUTHENTICATION_MODE {
-	Ndis802_11AuthModeOpen,
-	Ndis802_11AuthModeShared,
-	Ndis802_11AuthModeAutoSwitch,
-	Ndis802_11AuthModeWPA,
-	Ndis802_11AuthModeWPAPSK,
-	Ndis802_11AuthModeWPANone,
-	Ndis802_11AuthModeWPA2,
-	Ndis802_11AuthModeWPA2PSK,
-	Ndis802_11AuthModeWPA1WPA2,
-	Ndis802_11AuthModeWPA1PSKWPA2PSK,
-	Ndis802_11AuthModeMax	/* Not a real mode, defined as upper bound */
-} NDIS_802_11_AUTHENTICATION_MODE, *PNDIS_802_11_AUTHENTICATION_MODE;
-
-typedef u8 NDIS_802_11_RATES[NDIS_802_11_LENGTH_RATES];	/* Set of 8 data rates */
-typedef u8 NDIS_802_11_RATES_EX[NDIS_802_11_LENGTH_RATES_EX];	/* Set of 16 data rates */
-
-struct PACKED rt_ndis_802_11_ssid {
-	u32 SsidLength;	/* length of SSID field below, in bytes; */
-	/* this can be zero. */
-	u8 Ssid[NDIS_802_11_LENGTH_SSID];	/* SSID information field */
-};
-
-struct PACKED rt_ndis_wlan_bssid {
-	unsigned long Length;		/* Length of this structure */
-	NDIS_802_11_MAC_ADDRESS MacAddress;	/* BSSID */
-	u8 Reserved[2];
-	struct rt_ndis_802_11_ssid Ssid;	/* SSID */
-	unsigned long Privacy;		/* WEP encryption requirement */
-	NDIS_802_11_RSSI Rssi;	/* receive signal strength in dBm */
-	NDIS_802_11_NETWORK_TYPE NetworkTypeInUse;
-	struct rt_ndis_802_11_configuration Configuration;
-	NDIS_802_11_NETWORK_INFRASTRUCTURE InfrastructureMode;
-	NDIS_802_11_RATES SupportedRates;
-};
-
-struct PACKED rt_ndis_802_11_bssid_list {
-	u32 NumberOfItems;	/* in list below, at least 1 */
-	struct rt_ndis_wlan_bssid Bssid[1];
-};
-
-/* Added Capabilities, IELength and IEs for each BSSID */
-struct PACKED rt_ndis_wlan_bssid_ex {
-	unsigned long Length;		/* Length of this structure */
-	NDIS_802_11_MAC_ADDRESS MacAddress;	/* BSSID */
-	u8 Reserved[2];
-	struct rt_ndis_802_11_ssid Ssid;	/* SSID */
-	u32 Privacy;		/* WEP encryption requirement */
-	NDIS_802_11_RSSI Rssi;	/* receive signal */
-	/* strength in dBm */
-	NDIS_802_11_NETWORK_TYPE NetworkTypeInUse;
-	struct rt_ndis_802_11_configuration Configuration;
-	NDIS_802_11_NETWORK_INFRASTRUCTURE InfrastructureMode;
-	NDIS_802_11_RATES_EX SupportedRates;
-	unsigned long IELength;
-	u8 IEs[1];
-};
-
-struct PACKED rt_ndis_802_11_bssid_list_ex {
-	u32 NumberOfItems;	/* in list below, at least 1 */
-	struct rt_ndis_wlan_bssid_ex Bssid[1];
-};
-
-struct PACKED rt_ndis_802_11_fixed_ies {
-	u8 Timestamp[8];
-	u16 BeaconInterval;
-	u16 Capabilities;
-};
-
-struct rt_ndis_802_11_variable_ies {
-	u8 ElementID;
-	u8 Length;		/* Number of bytes in data field */
-	u8 data[1];
-};
-
-typedef unsigned long NDIS_802_11_FRAGMENTATION_THRESHOLD;
-
-typedef unsigned long NDIS_802_11_RTS_THRESHOLD;
-
-typedef unsigned long NDIS_802_11_ANTENNA;
-
-typedef enum _NDIS_802_11_PRIVACY_FILTER {
-	Ndis802_11PrivFilterAcceptAll,
-	Ndis802_11PrivFilter8021xWEP
-} NDIS_802_11_PRIVACY_FILTER, *PNDIS_802_11_PRIVACY_FILTER;
-
-/* Added new encryption types */
-/* Also aliased typedef to new name */
-typedef enum _NDIS_802_11_WEP_STATUS {
-	Ndis802_11WEPEnabled,
-	Ndis802_11Encryption1Enabled = Ndis802_11WEPEnabled,
-	Ndis802_11WEPDisabled,
-	Ndis802_11EncryptionDisabled = Ndis802_11WEPDisabled,
-	Ndis802_11WEPKeyAbsent,
-	Ndis802_11Encryption1KeyAbsent = Ndis802_11WEPKeyAbsent,
-	Ndis802_11WEPNotSupported,
-	Ndis802_11EncryptionNotSupported = Ndis802_11WEPNotSupported,
-	Ndis802_11Encryption2Enabled,
-	Ndis802_11Encryption2KeyAbsent,
-	Ndis802_11Encryption3Enabled,
-	Ndis802_11Encryption3KeyAbsent,
-	Ndis802_11Encryption4Enabled,	/* TKIP or AES mix */
-	Ndis802_11Encryption4KeyAbsent,
-	Ndis802_11GroupWEP40Enabled,
-	Ndis802_11GroupWEP104Enabled,
-} NDIS_802_11_WEP_STATUS, *PNDIS_802_11_WEP_STATUS,
-    NDIS_802_11_ENCRYPTION_STATUS, *PNDIS_802_11_ENCRYPTION_STATUS;
-
-typedef enum _NDIS_802_11_RELOAD_DEFAULTS {
-	Ndis802_11ReloadWEPKeys
-} NDIS_802_11_RELOAD_DEFAULTS, *PNDIS_802_11_RELOAD_DEFAULTS;
-
-#define NDIS_802_11_AI_REQFI_CAPABILITIES      1
-#define NDIS_802_11_AI_REQFI_LISTENINTERVAL    2
-#define NDIS_802_11_AI_REQFI_CURRENTAPADDRESS  4
-
-#define NDIS_802_11_AI_RESFI_CAPABILITIES      1
-#define NDIS_802_11_AI_RESFI_STATUSCODE        2
-#define NDIS_802_11_AI_RESFI_ASSOCIATIONID     4
-
-struct rt_ndis_802_11_ai_reqfi {
-	u16 Capabilities;
-	u16 ListenInterval;
-	NDIS_802_11_MAC_ADDRESS CurrentAPAddress;
-};
-
-struct rt_ndis_802_11_ai_resfi {
-	u16 Capabilities;
-	u16 StatusCode;
-	u16 AssociationId;
-};
-
-struct rt_ndis_802_11_association_information {
-	unsigned long Length;
-	u16 AvailableRequestFixedIEs;
-	struct rt_ndis_802_11_ai_reqfi RequestFixedIEs;
-	unsigned long RequestIELength;
-	unsigned long OffsetRequestIEs;
-	u16 AvailableResponseFixedIEs;
-	struct rt_ndis_802_11_ai_resfi ResponseFixedIEs;
-	unsigned long ResponseIELength;
-	unsigned long OffsetResponseIEs;
-};
-
-struct rt_ndis_802_11_authentication_event {
-	struct rt_ndis_802_11_status_indication Status;
-	struct rt_ndis_802_11_authentication_request Request[1];
-};
-
-/* 802.11 Media stream constraints, associated with OID_802_11_MEDIA_STREAM_MODE */
-typedef enum _NDIS_802_11_MEDIA_STREAM_MODE {
-	Ndis802_11MediaStreamOff,
-	Ndis802_11MediaStreamOn,
-} NDIS_802_11_MEDIA_STREAM_MODE, *PNDIS_802_11_MEDIA_STREAM_MODE;
-
-/* PMKID Structures */
-typedef u8 NDIS_802_11_PMKID_VALUE[16];
-
-struct rt_bssid_info {
-	NDIS_802_11_MAC_ADDRESS BSSID;
-	NDIS_802_11_PMKID_VALUE PMKID;
-};
-
-struct rt_ndis_802_11_pmkid {
-	u32 Length;
-	u32 BSSIDInfoCount;
-	struct rt_bssid_info BSSIDInfo[1];
-};
-
-struct rt_ndis_802_11_authentication_encryption {
-	NDIS_802_11_AUTHENTICATION_MODE AuthModeSupported;
-	NDIS_802_11_ENCRYPTION_STATUS EncryptStatusSupported;
-};
-
-struct rt_ndis_802_11_capability {
-	unsigned long Length;
-	unsigned long Version;
-	unsigned long NoOfPMKIDs;
-	unsigned long NoOfAuthEncryptPairsSupported;
-	struct rt_ndis_802_11_authentication_encryption
-	    AuthenticationEncryptionSupported[1];
-};
-
-#define RT_PRIV_IOCTL							(SIOCIWFIRSTPRIV + 0x01)	/* Sync. with AP for wsc upnp daemon */
-#define RTPRIV_IOCTL_SET							(SIOCIWFIRSTPRIV + 0x02)
-
-#define RTPRIV_IOCTL_STATISTICS                     (SIOCIWFIRSTPRIV + 0x09)
-#define RTPRIV_IOCTL_ADD_PMKID_CACHE                (SIOCIWFIRSTPRIV + 0x0A)
-#define RTPRIV_IOCTL_RADIUS_DATA                    (SIOCIWFIRSTPRIV + 0x0C)
-#define RTPRIV_IOCTL_GSITESURVEY					(SIOCIWFIRSTPRIV + 0x0D)
-#define RT_PRIV_IOCTL_EXT							(SIOCIWFIRSTPRIV + 0x0E)	/* Sync. with RT61 (for wpa_supplicant) */
-#define RTPRIV_IOCTL_GET_MAC_TABLE					(SIOCIWFIRSTPRIV + 0x0F)
-
-#define RTPRIV_IOCTL_SHOW							(SIOCIWFIRSTPRIV + 0x11)
-enum {
-	SHOW_CONN_STATUS = 4,
-	SHOW_DRVIER_VERION = 5,
-	SHOW_BA_INFO = 6,
-	SHOW_DESC_INFO = 7,
-#ifdef RTMP_MAC_USB
-	SHOW_RXBULK_INFO = 8,
-	SHOW_TXBULK_INFO = 9,
-#endif /* RTMP_MAC_USB // */
-	RAIO_OFF = 10,
-	RAIO_ON = 11,
-	SHOW_CFG_VALUE = 20,
-	SHOW_ADHOC_ENTRY_INFO = 21,
-};
-
-#define OID_802_11_BUILD_CHANNEL_EX				0x0714
-#define OID_802_11_GET_CH_LIST					0x0715
-#define OID_802_11_GET_COUNTRY_CODE				0x0716
-#define OID_802_11_GET_CHANNEL_GEOGRAPHY		0x0717
-
-#define RT_OID_WSC_SET_PASSPHRASE                   0x0740	/* passphrase for wpa(2)-psk */
-#define RT_OID_WSC_DRIVER_AUTO_CONNECT              0x0741
-#define RT_OID_WSC_QUERY_DEFAULT_PROFILE            0x0742
-#define RT_OID_WSC_SET_CONN_BY_PROFILE_INDEX        0x0743
-#define RT_OID_WSC_SET_ACTION                       0x0744
-#define RT_OID_WSC_SET_SSID                         0x0745
-#define RT_OID_WSC_SET_PIN_CODE                     0x0746
-#define RT_OID_WSC_SET_MODE                         0x0747	/* PIN or PBC */
-#define RT_OID_WSC_SET_CONF_MODE                    0x0748	/* Enrollee or Registrar */
-#define RT_OID_WSC_SET_PROFILE                      0x0749
-#define	RT_OID_WSC_CONFIG_STATUS					0x074F
-#define RT_OID_802_11_WSC_QUERY_PROFILE				0x0750
-/* for consistency with RT61 */
-#define RT_OID_WSC_QUERY_STATUS						0x0751
-#define RT_OID_WSC_PIN_CODE							0x0752
-#define RT_OID_WSC_UUID								0x0753
-#define RT_OID_WSC_SET_SELECTED_REGISTRAR			0x0754
-#define RT_OID_WSC_EAPMSG							0x0755
-#define RT_OID_WSC_MANUFACTURER						0x0756
-#define RT_OID_WSC_MODEL_NAME						0x0757
-#define RT_OID_WSC_MODEL_NO							0x0758
-#define RT_OID_WSC_SERIAL_NO						0x0759
-#define RT_OID_WSC_MAC_ADDRESS						0x0760
-
-/* New for MeetingHouse Api support */
-#define OID_MH_802_1X_SUPPORTED               0xFFEDC100
-
-/* MIMO Tx parameter, ShortGI, MCS, STBC, etc.  these are fields in TXWI. Don't change this definition! */
-typedef union _HTTRANSMIT_SETTING {
-	struct {
-		u16 MCS:7;	/* MCS */
-		u16 BW:1;	/*channel bandwidth 20MHz or 40 MHz */
-		u16 ShortGI:1;
-		u16 STBC:2;	/*SPACE */
-/*      u16          rsv:3; */
-		u16 rsv:2;
-		u16 TxBF:1;
-		u16 MODE:2;	/* Use definition MODE_xxx. */
-	} field;
-	u16 word;
-} HTTRANSMIT_SETTING, *PHTTRANSMIT_SETTING;
-
-typedef enum _RT_802_11_PREAMBLE {
-	Rt802_11PreambleLong,
-	Rt802_11PreambleShort,
-	Rt802_11PreambleAuto
-} RT_802_11_PREAMBLE, *PRT_802_11_PREAMBLE;
-
-typedef enum _RT_802_11_PHY_MODE {
-	PHY_11BG_MIXED = 0,
-	PHY_11B,
-	PHY_11A,
-	PHY_11ABG_MIXED,
-	PHY_11G,
-	PHY_11ABGN_MIXED,	/* both band   5 */
-	PHY_11N_2_4G,		/* 11n-only with 2.4G band      6 */
-	PHY_11GN_MIXED,		/* 2.4G band      7 */
-	PHY_11AN_MIXED,		/* 5G  band       8 */
-	PHY_11BGN_MIXED,	/* if check 802.11b.      9 */
-	PHY_11AGN_MIXED,	/* if check 802.11b.      10 */
-	PHY_11N_5G,		/* 11n-only with 5G band                11 */
-} RT_802_11_PHY_MODE;
-
-/* put all proprietery for-query objects here to reduce # of Query_OID */
-struct rt_802_11_link_status {
-	unsigned long CurrTxRate;	/* in units of 0.5Mbps */
-	unsigned long ChannelQuality;	/* 0..100 % */
-	unsigned long TxByteCount;	/* both ok and fail */
-	unsigned long RxByteCount;	/* both ok and fail */
-	unsigned long CentralChannel;	/* 40MHz central channel number */
-};
-
-struct rt_802_11_event_log {
-	LARGE_INTEGER SystemTime;	/* timestammp via NdisGetCurrentSystemTime() */
-	u8 Addr[MAC_ADDR_LENGTH];
-	u16 Event;		/* EVENT_xxx */
-};
-
-struct rt_802_11_event_table {
-	unsigned long Num;
-	unsigned long Rsv;		/* to align Log[] at LARGE_INTEGER boundary */
-	struct rt_802_11_event_log Log[MAX_NUMBER_OF_EVENT];
-};
-
-/* MIMO Tx parameter, ShortGI, MCS, STBC, etc.  these are fields in TXWI. Don't change this definition! */
-typedef union _MACHTTRANSMIT_SETTING {
-	struct {
-		u16 MCS:7;	/* MCS */
-		u16 BW:1;	/*channel bandwidth 20MHz or 40 MHz */
-		u16 ShortGI:1;
-		u16 STBC:2;	/*SPACE */
-		u16 rsv:3;
-		u16 MODE:2;	/* Use definition MODE_xxx. */
-	} field;
-	u16 word;
-} MACHTTRANSMIT_SETTING, *PMACHTTRANSMIT_SETTING;
-
-struct rt_802_11_mac_entry {
-	u8 Addr[MAC_ADDR_LENGTH];
-	u8 Aid;
-	u8 Psm;		/* 0:PWR_ACTIVE, 1:PWR_SAVE */
-	u8 MimoPs;		/* 0:MMPS_STATIC, 1:MMPS_DYNAMIC, 3:MMPS_Enabled */
-	char AvgRssi0;
-	char AvgRssi1;
-	char AvgRssi2;
-	u32 ConnectedTime;
-	MACHTTRANSMIT_SETTING TxRate;
-};
-
-struct rt_802_11_mac_table {
-	unsigned long Num;
-	struct rt_802_11_mac_entry Entry[MAX_NUMBER_OF_MAC];
-};
-
-/* structure for query/set hardware register - MAC, BBP, RF register */
-struct rt_802_11_hardware_register {
-	unsigned long HardwareType;	/* 0:MAC, 1:BBP, 2:RF register, 3:EEPROM */
-	unsigned long Offset;		/* Q/S register offset addr */
-	unsigned long Data;		/* R/W data buffer */
-};
-
-struct rt_802_11_ap_config {
-	unsigned long EnableTxBurst;	/* 0-disable, 1-enable */
-	unsigned long EnableTurboRate;	/* 0-disable, 1-enable 72/100mbps turbo rate */
-	unsigned long IsolateInterStaTraffic;	/* 0-disable, 1-enable isolation */
-	unsigned long HideSsid;		/* 0-disable, 1-enable hiding */
-	unsigned long UseBGProtection;	/* 0-AUTO, 1-always ON, 2-always OFF */
-	unsigned long UseShortSlotTime;	/* 0-no use, 1-use 9-us short slot time */
-	unsigned long Rsv1;		/* must be 0 */
-	unsigned long SystemErrorBitmap;	/* ignore upon SET, return system error upon QUERY */
-};
-
-/* structure to query/set STA_CONFIG */
-struct rt_802_11_sta_config {
-	unsigned long EnableTxBurst;	/* 0-disable, 1-enable */
-	unsigned long EnableTurboRate;	/* 0-disable, 1-enable 72/100mbps turbo rate */
-	unsigned long UseBGProtection;	/* 0-AUTO, 1-always ON, 2-always OFF */
-	unsigned long UseShortSlotTime;	/* 0-no use, 1-use 9-us short slot time when applicable */
-	unsigned long AdhocMode;	/* 0-11b rates only (WIFI spec), 1 - b/g mixed, 2 - g only */
-	unsigned long HwRadioStatus;	/* 0-OFF, 1-ON, default is 1, Read-Only */
-	unsigned long Rsv1;		/* must be 0 */
-	unsigned long SystemErrorBitmap;	/* ignore upon SET, return system error upon QUERY */
-};
-
-/* */
-/*  For OID Query or Set about BA structure */
-/* */
-struct rt_oid_bacap {
-	u8 RxBAWinLimit;
-	u8 TxBAWinLimit;
-	u8 Policy;		/* 0: DELAY_BA 1:IMMED_BA  (//BA Policy subfiled value in ADDBA frame)   2:BA-not use. other value invalid */
-	u8 MpduDensity;	/* 0: DELAY_BA 1:IMMED_BA  (//BA Policy subfiled value in ADDBA frame)   2:BA-not use. other value invalid */
-	u8 AmsduEnable;	/*Enable AMSDU transmisstion */
-	u8 AmsduSize;	/* 0:3839, 1:7935 bytes. u32  MSDUSizeToBytes[]        = { 3839, 7935}; */
-	u8 MMPSmode;		/* MIMO power save more, 0:static, 1:dynamic, 2:rsv, 3:mimo enable */
-	BOOLEAN AutoBA;		/* Auto BA will automatically */
-};
-
-struct rt_802_11_acl_entry {
-	u8 Addr[MAC_ADDR_LENGTH];
-	u16 Rsv;
-};
-
-struct PACKED rt_rt_802_11_acl {
-	unsigned long Policy;		/* 0-disable, 1-positive list, 2-negative list */
-	unsigned long Num;
-	struct rt_802_11_acl_entry Entry[MAX_NUMBER_OF_ACL];
-};
-
-struct rt_802_11_wds {
-	unsigned long Num;
-	NDIS_802_11_MAC_ADDRESS Entry[24 /*MAX_NUM_OF_WDS_LINK */];
-	unsigned long KeyLength;
-	u8 KeyMaterial[32];
-};
-
-struct rt_802_11_tx_rates {
-	u8 SupRateLen;
-	u8 SupRate[MAX_LENGTH_OF_SUPPORT_RATES];
-	u8 ExtRateLen;
-	u8 ExtRate[MAX_LENGTH_OF_SUPPORT_RATES];
-};
-
-/* Definition of extra information code */
-#define	GENERAL_LINK_UP			0x0	/* Link is Up */
-#define	GENERAL_LINK_DOWN		0x1	/* Link is Down */
-#define	HW_RADIO_OFF			0x2	/* Hardware radio off */
-#define	SW_RADIO_OFF			0x3	/* Software radio off */
-#define	AUTH_FAIL				0x4	/* Open authentication fail */
-#define	AUTH_FAIL_KEYS			0x5	/* Shared authentication fail */
-#define	ASSOC_FAIL				0x6	/* Association failed */
-#define	EAP_MIC_FAILURE			0x7	/* Deauthentication because MIC failure */
-#define	EAP_4WAY_TIMEOUT		0x8	/* Deauthentication on 4-way handshake timeout */
-#define	EAP_GROUP_KEY_TIMEOUT	0x9	/* Deauthentication on group key handshake timeout */
-#define	EAP_SUCCESS				0xa	/* EAP succeed */
-#define	DETECT_RADAR_SIGNAL		0xb	/* Radar signal occur in current channel */
-#define EXTRA_INFO_MAX			0xb	/* Indicate Last OID */
-
-#define EXTRA_INFO_CLEAR		0xffffffff
-
-/* This is OID setting structure. So only GF or MM as Mode. This is valid when our wirelss mode has 802.11n in use. */
-struct rt_oid_set_ht_phymode {
-	RT_802_11_PHY_MODE PhyMode;	/* */
-	u8 TransmitNo;
-	u8 HtMode;		/*HTMODE_GF or HTMODE_MM */
-	u8 ExtOffset;	/*extension channel above or below */
-	u8 MCS;
-	u8 BW;
-	u8 STBC;
-	u8 SHORTGI;
-	u8 rsv;
-};
-
-#define MAX_CUSTOM_LEN 128
-
-typedef enum _RT_802_11_D_CLIENT_MODE {
-	Rt802_11_D_None,
-	Rt802_11_D_Flexible,
-	Rt802_11_D_Strict,
-} RT_802_11_D_CLIENT_MODE, *PRT_802_11_D_CLIENT_MODE;
-
-struct rt_channel_list_info {
-	u8 ChannelList[MAX_NUM_OF_CHS];	/* list all supported channels for site survey */
-	u8 ChannelListNum;	/* number of channel in ChannelList[] */
-};
-
-/* WSC configured credential */
-struct rt_wsc_credential {
-	struct rt_ndis_802_11_ssid SSID;	/* mandatory */
-	u16 AuthType;	/* mandatory, 1: open, 2: wpa-psk, 4: shared, 8:wpa, 0x10: wpa2, 0x20: wpa2-psk */
-	u16 EncrType;	/* mandatory, 1: none, 2: wep, 4: tkip, 8: aes */
-	u8 Key[64];		/* mandatory, Maximum 64 byte */
-	u16 KeyLength;
-	u8 MacAddr[6];	/* mandatory, AP MAC address */
-	u8 KeyIndex;		/* optional, default is 1 */
-	u8 Rsvd[3];		/* Make alignment */
-};
-
-/* WSC configured profiles */
-struct rt_wsc_profile {
-	u32 ProfileCnt;
-	u32 ApplyProfileIdx;	/* add by johnli, fix WPS test plan 5.1.1 */
-	struct rt_wsc_credential Profile[8];	/* Support up to 8 profiles */
-};
-
-#endif /* _OID_H_ */
diff -druN linux-2.6.39-libre/drivers/staging/rt2860/pci_main_dev.c linux-3.0-rc7-libre/drivers/staging/rt2860/pci_main_dev.c
--- linux-2.6.39-libre/drivers/staging/rt2860/pci_main_dev.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rt2860/pci_main_dev.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,1192 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, 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.             *
- *                                                                       *
- *************************************************************************
-
-    Module Name:
-    pci_main_dev.c
-
-    Abstract:
-    Create and register network interface for PCI based chipsets in Linux platform.
-
-    Revision History:
-    Who         	When            What
-    Justin P. Mattock	11/07/2010	Fix typos in some comments
-    --------    ----------      ----------------------------------------------
-*/
-
-#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 a bug in current version of driver, please e-mail me. */
-/* Otherwise post to forum in ralinktech's web site(www.ralinktech.com) and let all users help you. */
-MODULE_AUTHOR("Jett Chen <jett_chen@ralinktech.com>");
-MODULE_DESCRIPTION("RT2860/RT3090 Wireless Lan Linux Driver");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("rt3090sta");
-
-/* */
-/* Function declarations */
-/* */
-static void __devexit rt2860_remove_one(struct pci_dev *pci_dev);
-static int __devinit rt2860_probe(struct pci_dev *pci_dev,
-				  const struct pci_device_id *ent);
-static void __exit rt2860_cleanup_module(void);
-static int __init rt2860_init_module(void);
-
-static void RTMPInitPCIeDevice(IN struct pci_dev *pci_dev,
-			       struct rt_rtmp_adapter *pAd);
-
-#ifdef CONFIG_PM
-static int rt2860_suspend(struct pci_dev *pci_dev, pm_message_t state);
-static int rt2860_resume(struct pci_dev *pci_dev);
-#endif /* CONFIG_PM // */
-
-/* */
-/* Ralink PCI device table, include all supported chipsets */
-/* */
-static struct pci_device_id rt2860_pci_tbl[] __devinitdata = {
-#ifdef RT2860
-	{PCI_DEVICE(NIC_PCI_VENDOR_ID, NIC2860_PCI_DEVICE_ID)},	/*RT28602.4G */
-	{PCI_DEVICE(NIC_PCI_VENDOR_ID, NIC2860_PCIe_DEVICE_ID)},
-	{PCI_DEVICE(NIC_PCI_VENDOR_ID, NIC2760_PCI_DEVICE_ID)},
-	{PCI_DEVICE(NIC_PCI_VENDOR_ID, NIC2790_PCIe_DEVICE_ID)},
-	{PCI_DEVICE(VEN_AWT_PCI_VENDOR_ID, VEN_AWT_PCIe_DEVICE_ID)},
-	{PCI_DEVICE(EDIMAX_PCI_VENDOR_ID, 0x7708)},
-	{PCI_DEVICE(EDIMAX_PCI_VENDOR_ID, 0x7728)},
-	{PCI_DEVICE(EDIMAX_PCI_VENDOR_ID, 0x7758)},
-	{PCI_DEVICE(EDIMAX_PCI_VENDOR_ID, 0x7727)},
-	{PCI_DEVICE(EDIMAX_PCI_VENDOR_ID, 0x7738)},
-	{PCI_DEVICE(EDIMAX_PCI_VENDOR_ID, 0x7748)},
-	{PCI_DEVICE(EDIMAX_PCI_VENDOR_ID, 0x7768)},
-#endif
-#ifdef RT3090
-	{PCI_DEVICE(NIC_PCI_VENDOR_ID, NIC3090_PCIe_DEVICE_ID)},
-	{PCI_DEVICE(NIC_PCI_VENDOR_ID, NIC3091_PCIe_DEVICE_ID)},
-	{PCI_DEVICE(NIC_PCI_VENDOR_ID, NIC3092_PCIe_DEVICE_ID)},
-#endif /* RT3090 // */
-#ifdef RT3390
-	{PCI_DEVICE(NIC_PCI_VENDOR_ID, NIC3390_PCIe_DEVICE_ID)},
-	{PCI_DEVICE(NIC_PCI_VENDOR_ID, NIC3391_PCIe_DEVICE_ID)},
-	{PCI_DEVICE(NIC_PCI_VENDOR_ID, NIC3392_PCIe_DEVICE_ID)},
-#endif /* RT3390 // */
-	{0,}			/* terminate list */
-};
-
-MODULE_DEVICE_TABLE(pci, rt2860_pci_tbl);
-#ifdef MODULE_VERSION
-MODULE_VERSION(STA_DRIVER_VERSION);
-#endif
-
-/* */
-/* Our PCI driver structure */
-/* */
-static struct pci_driver rt2860_driver = {
-name: "rt2860",
-id_table : rt2860_pci_tbl,
-probe : rt2860_probe,
-remove : __devexit_p(rt2860_remove_one),
-#ifdef CONFIG_PM
-suspend : rt2860_suspend,
-resume : rt2860_resume,
-#endif
-};
-
-/***************************************************************************
- *
- *	PCI device initialization related procedures.
- *
- ***************************************************************************/
-#ifdef CONFIG_PM
-
-void RT2860RejectPendingPackets(struct rt_rtmp_adapter *pAd)
-{
-	/* clear PS packets */
-	/* clear TxSw packets */
-}
-
-static int rt2860_suspend(struct pci_dev *pci_dev, pm_message_t state)
-{
-	struct net_device *net_dev = pci_get_drvdata(pci_dev);
-	struct rt_rtmp_adapter *pAd = (struct rt_rtmp_adapter *)NULL;
-	int retval = 0;
-
-	DBGPRINT(RT_DEBUG_TRACE, ("===> rt2860_suspend()\n"));
-
-	if (net_dev == NULL) {
-		DBGPRINT(RT_DEBUG_ERROR, ("net_dev == NULL!\n"));
-	} else {
-		GET_PAD_FROM_NET_DEV(pAd, net_dev);
-
-		/* we can not use IFF_UP because ra0 down but ra1 up */
-		/* and 1 suspend/resume function for 1 module, not for each interface */
-		/* so Linux will call suspend/resume function once */
-		if (VIRTUAL_IF_NUM(pAd) > 0) {
-			/* avoid users do suspend after interface is down */
-
-			/* stop interface */
-			netif_carrier_off(net_dev);
-			netif_stop_queue(net_dev);
-
-			/* mark device as removed from system and therefore no longer available */
-			netif_device_detach(net_dev);
-
-			/* mark halt flag */
-			RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS);
-			RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF);
-
-			/* take down the device */
-			rt28xx_close((struct net_device *)net_dev);
-
-			RT_MOD_DEC_USE_COUNT();
-		}
-	}
-
-	/* reference to http://vovo2000.com/type-lab/linux/kernel-api/linux-kernel-api.html */
-	/* enable device to generate PME# when suspended */
-	/* pci_choose_state(): Choose the power state of a PCI device to be suspended */
-	retval = pci_enable_wake(pci_dev, pci_choose_state(pci_dev, state), 1);
-	/* save the PCI configuration space of a device before suspending */
-	pci_save_state(pci_dev);
-	/* disable PCI device after use */
-	pci_disable_device(pci_dev);
-
-	retval = pci_set_power_state(pci_dev, pci_choose_state(pci_dev, state));
-
-	DBGPRINT(RT_DEBUG_TRACE, ("<=== rt2860_suspend()\n"));
-	return retval;
-}
-
-static int rt2860_resume(struct pci_dev *pci_dev)
-{
-	struct net_device *net_dev = pci_get_drvdata(pci_dev);
-	struct rt_rtmp_adapter *pAd = (struct rt_rtmp_adapter *)NULL;
-	int retval;
-
-	/* set the power state of a PCI device */
-	/* PCI has 4 power states, DO (normal) ~ D3(less power) */
-	/* in include/linux/pci.h, you can find that */
-	/* #define PCI_D0          ((pci_power_t __force) 0) */
-	/* #define PCI_D1          ((pci_power_t __force) 1) */
-	/* #define PCI_D2          ((pci_power_t __force) 2) */
-	/* #define PCI_D3hot       ((pci_power_t __force) 3) */
-	/* #define PCI_D3cold      ((pci_power_t __force) 4) */
-	/* #define PCI_UNKNOWN     ((pci_power_t __force) 5) */
-	/* #define PCI_POWER_ERROR ((pci_power_t __force) -1) */
-	retval = pci_set_power_state(pci_dev, PCI_D0);
-
-	/* restore the saved state of a PCI device */
-	pci_restore_state(pci_dev);
-
-	/* initialize device before it's used by a driver */
-	if (pci_enable_device(pci_dev)) {
-		printk(KERN_ERR "rt2860: pci enable fail!\n");
-		return 0;
-	}
-
-	DBGPRINT(RT_DEBUG_TRACE, ("===> rt2860_resume()\n"));
-
-	if (net_dev == NULL)
-		DBGPRINT(RT_DEBUG_ERROR, ("net_dev == NULL!\n"));
-	else
-		GET_PAD_FROM_NET_DEV(pAd, net_dev);
-
-	if (pAd != NULL) {
-		/* we can not use IFF_UP because ra0 down but ra1 up */
-		/* and 1 suspend/resume function for 1 module, not for each interface */
-		/* so Linux will call suspend/resume function once */
-		if (VIRTUAL_IF_NUM(pAd) > 0) {
-			/* mark device as attached from system and restart if needed */
-			netif_device_attach(net_dev);
-
-			if (rt28xx_open((struct net_device *)net_dev) != 0) {
-				/* open fail */
-				DBGPRINT(RT_DEBUG_TRACE,
-					 ("<=== rt2860_resume()\n"));
-				return 0;
-			}
-			/* increase MODULE use count */
-			RT_MOD_INC_USE_COUNT();
-
-			RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS);
-			RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF);
-
-			netif_start_queue(net_dev);
-			netif_carrier_on(net_dev);
-			netif_wake_queue(net_dev);
-		}
-	}
-
-	DBGPRINT(RT_DEBUG_TRACE, ("<=== rt2860_resume()\n"));
-	return 0;
-}
-#endif /* CONFIG_PM // */
-
-static int __init rt2860_init_module(void)
-{
-	return pci_register_driver(&rt2860_driver);
-}
-
-/* */
-/* Driver module unload function */
-/* */
-static void __exit rt2860_cleanup_module(void)
-{
-	pci_unregister_driver(&rt2860_driver);
-}
-
-module_init(rt2860_init_module);
-module_exit(rt2860_cleanup_module);
-
-/* */
-/* PCI device probe & initialization function */
-/* */
-static int __devinit rt2860_probe(IN struct pci_dev *pci_dev,
-				  IN const struct pci_device_id *pci_id)
-{
-	struct rt_rtmp_adapter *pAd = (struct rt_rtmp_adapter *)NULL;
-	struct net_device *net_dev;
-	void *handle;
-	char *print_name;
-	unsigned long csr_addr;
-	int rv = 0;
-	struct rt_rtmp_os_netdev_op_hook netDevHook;
-
-	DBGPRINT(RT_DEBUG_TRACE, ("===> rt2860_probe\n"));
-
-/*PCIDevInit============================================== */
-	/* wake up and enable device */
-	rv = pci_enable_device(pci_dev);
-
-	if (rv != 0) {
-		DBGPRINT(RT_DEBUG_ERROR,
-			 ("Enable PCI device failed, errno=%d!\n", rv));
-		return rv;
-	}
-
-	print_name = (char *)pci_name(pci_dev);
-
-	rv = pci_request_regions(pci_dev, print_name);
-
-	if (rv != 0) {
-		DBGPRINT(RT_DEBUG_ERROR,
-			 ("Request PCI resource failed, errno=%d!\n", rv));
-		goto err_out;
-	}
-	/* map physical address to virtual address for accessing register */
-	csr_addr =
-	    (unsigned long)ioremap(pci_resource_start(pci_dev, 0),
-				   pci_resource_len(pci_dev, 0));
-	if (!csr_addr) {
-		DBGPRINT(RT_DEBUG_ERROR,
-			 ("ioremap failed for device %s, region 0x%lX @ 0x%lX\n",
-			  print_name, (unsigned long)pci_resource_len(pci_dev, 0),
-			  (unsigned long)pci_resource_start(pci_dev, 0)));
-		goto err_out_free_res;
-	} else {
-		DBGPRINT(RT_DEBUG_TRACE,
-			 ("%s: at 0x%lx, VA 0x%lx, IRQ %d. \n", print_name,
-			  (unsigned long)pci_resource_start(pci_dev, 0),
-			  (unsigned long)csr_addr, pci_dev->irq));
-	}
-
-	/* Set DMA master */
-	pci_set_master(pci_dev);
-
-/*RtmpDevInit============================================== */
-	/* Allocate struct rt_rtmp_adapter adapter structure */
-	handle = kmalloc(sizeof(struct os_cookie), GFP_KERNEL);
-	if (handle == NULL) {
-		DBGPRINT(RT_DEBUG_ERROR,
-			 ("%s(): Allocate memory for os handle failed!\n",
-			  __func__));
-		goto err_out_iounmap;
-	}
-
-	((struct os_cookie *)handle)->pci_dev = pci_dev;
-
-	rv = RTMPAllocAdapterBlock(handle, &pAd);	/*shiang: we may need the pci_dev for allocate structure of "struct rt_rtmp_adapter" */
-	if (rv != NDIS_STATUS_SUCCESS)
-		goto err_out_iounmap;
-	/* Here are the struct rt_rtmp_adapter structure with pci-bus specific parameters. */
-	pAd->CSRBaseAddress = (u8 *)csr_addr;
-	DBGPRINT(RT_DEBUG_ERROR,
-		 ("pAd->CSRBaseAddress =0x%lx, csr_addr=0x%lx!\n",
-		  (unsigned long)pAd->CSRBaseAddress, csr_addr));
-	RtmpRaDevCtrlInit(pAd, RTMP_DEV_INF_PCI);
-
-/*NetDevInit============================================== */
-	net_dev = RtmpPhyNetDevInit(pAd, &netDevHook);
-	if (net_dev == NULL)
-		goto err_out_free_radev;
-
-	/* Here are the net_device structure with pci-bus specific parameters. */
-	net_dev->irq = pci_dev->irq;	/* Interrupt IRQ number */
-	net_dev->base_addr = csr_addr;	/* Save CSR virtual address and irq to device structure */
-	pci_set_drvdata(pci_dev, net_dev);	/* Set driver data */
-
-/* for supporting Network Manager */
-	/* Set the sysfs physical device reference for the network logical device
-	 * if set prior to registration will cause a symlink during initialization.
-	 */
-	SET_NETDEV_DEV(net_dev, &(pci_dev->dev));
-
-/*All done, it's time to register the net device to linux kernel. */
-	/* Register this device */
-	rv = RtmpOSNetDevAttach(net_dev, &netDevHook);
-	if (rv)
-		goto err_out_free_netdev;
-
-	pAd->StaCfg.OriDevType = net_dev->type;
-	RTMPInitPCIeDevice(pci_dev, pAd);
-
-	DBGPRINT(RT_DEBUG_TRACE, ("<=== rt2860_probe\n"));
-
-	return 0;		/* probe ok */
-
-	/* --------------------------- ERROR HANDLE --------------------------- */
-err_out_free_netdev:
-	RtmpOSNetDevFree(net_dev);
-
-err_out_free_radev:
-	/* free struct rt_rtmp_adapter strcuture and os_cookie */
-	RTMPFreeAdapter(pAd);
-
-err_out_iounmap:
-	iounmap((void *)(csr_addr));
-	release_mem_region(pci_resource_start(pci_dev, 0),
-			   pci_resource_len(pci_dev, 0));
-
-err_out_free_res:
-	pci_release_regions(pci_dev);
-
-err_out:
-	pci_disable_device(pci_dev);
-
-	DBGPRINT(RT_DEBUG_ERROR,
-		 ("<=== rt2860_probe failed with rv = %d!\n", rv));
-
-	return -ENODEV;		/* probe fail */
-}
-
-static void __devexit rt2860_remove_one(IN struct pci_dev *pci_dev)
-{
-	struct net_device *net_dev = pci_get_drvdata(pci_dev);
-	struct rt_rtmp_adapter *pAd = NULL;
-	unsigned long csr_addr = net_dev->base_addr;	/* pAd->CSRBaseAddress; */
-
-	GET_PAD_FROM_NET_DEV(pAd, net_dev);
-
-	DBGPRINT(RT_DEBUG_TRACE, ("===> rt2860_remove_one\n"));
-
-	if (pAd != NULL) {
-		/* Unregister/Free all allocated net_device. */
-		RtmpPhyNetDevExit(pAd, net_dev);
-
-		/* Unmap CSR base address */
-		iounmap((char *)(csr_addr));
-
-		/* release memory region */
-		release_mem_region(pci_resource_start(pci_dev, 0),
-				   pci_resource_len(pci_dev, 0));
-
-		/* Free struct rt_rtmp_adapter related structures. */
-		RtmpRaDevCtrlExit(pAd);
-
-	} else {
-		/* Unregister network device */
-		RtmpOSNetDevDetach(net_dev);
-
-		/* Unmap CSR base address */
-		iounmap((char *)(net_dev->base_addr));
-
-		/* release memory region */
-		release_mem_region(pci_resource_start(pci_dev, 0),
-				   pci_resource_len(pci_dev, 0));
-	}
-
-	/* Free the root net_device */
-	RtmpOSNetDevFree(net_dev);
-
-}
-
-/*
-========================================================================
-Routine Description:
-    Check the chipset vendor/product ID.
-
-Arguments:
-    _dev_p				Point to the PCI or USB device
-
-Return Value:
-    TRUE				Check ok
-	FALSE				Check fail
-
-Note:
-========================================================================
-*/
-BOOLEAN RT28XXChipsetCheck(IN void *_dev_p)
-{
-	/* always TRUE */
-	return TRUE;
-}
-
-/***************************************************************************
- *
- *	PCIe device initialization related procedures.
- *
- ***************************************************************************/
-static void RTMPInitPCIeDevice(struct pci_dev *pci_dev, struct rt_rtmp_adapter *pAd)
-{
-	u16 device_id;
-	struct os_cookie *pObj;
-
-	pObj = (struct os_cookie *)pAd->OS_Cookie;
-	pci_read_config_word(pci_dev, PCI_DEVICE_ID, &device_id);
-	device_id = le2cpu16(device_id);
-	pObj->DeviceID = device_id;
-	if (
-#ifdef RT2860
-		   (device_id == NIC2860_PCIe_DEVICE_ID) ||
-		   (device_id == NIC2790_PCIe_DEVICE_ID) ||
-		   (device_id == VEN_AWT_PCIe_DEVICE_ID) ||
-#endif
-#ifdef RT3090
-		   (device_id == NIC3090_PCIe_DEVICE_ID) ||
-		   (device_id == NIC3091_PCIe_DEVICE_ID) ||
-		   (device_id == NIC3092_PCIe_DEVICE_ID) ||
-#endif /* RT3090 // */
-		   0) {
-		u32 MacCsr0 = 0, Index = 0;
-		do {
-			RTMP_IO_READ32(pAd, MAC_CSR0, &MacCsr0);
-
-			if ((MacCsr0 != 0x00) && (MacCsr0 != 0xFFFFFFFF))
-				break;
-
-			RTMPusecDelay(10);
-		} while (Index++ < 100);
-
-		/* Support advanced power save after 2892/2790. */
-		/* MAC version at offset 0x1000 is 0x2872XXXX/0x2870XXXX(PCIe, USB, SDIO). */
-		if ((MacCsr0 & 0xffff0000) != 0x28600000)
-			OPSTATUS_SET_FLAG(pAd, fOP_STATUS_PCIE_DEVICE);
-	}
-}
-
-void RTMPInitPCIeLinkCtrlValue(struct rt_rtmp_adapter *pAd)
-{
-	int pos;
-	u16 reg16, data2, PCIePowerSaveLevel, Configuration;
-	u32 MacValue;
-	BOOLEAN bFindIntel = FALSE;
-	struct os_cookie *pObj;
-
-	pObj = (struct os_cookie *)pAd->OS_Cookie;
-
-	if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE))
-		return;
-
-	DBGPRINT(RT_DEBUG_TRACE, ("%s.===>\n", __func__));
-	/* Init EEPROM, and save settings */
-	if (!(IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd))) {
-		RT28xx_EEPROM_READ16(pAd, 0x22, PCIePowerSaveLevel);
-		pAd->PCIePowerSaveLevel = PCIePowerSaveLevel & 0xff;
-
-		pAd->LnkCtrlBitMask = 0;
-		if ((PCIePowerSaveLevel & 0xff) == 0xff) {
-			OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_PCIE_DEVICE);
-			DBGPRINT(RT_DEBUG_TRACE,
-				 ("====> PCIePowerSaveLevel = 0x%x.\n",
-				  PCIePowerSaveLevel));
-			return;
-		} else {
-			PCIePowerSaveLevel &= 0x3;
-			RT28xx_EEPROM_READ16(pAd, 0x24, data2);
-
-			if (!
-			    (((data2 & 0xff00) == 0x9200)
-			     && ((data2 & 0x80) != 0))) {
-				if (PCIePowerSaveLevel > 1)
-					PCIePowerSaveLevel = 1;
-			}
-
-			DBGPRINT(RT_DEBUG_TRACE,
-				 ("====> Write 0x83 = 0x%x.\n",
-				  PCIePowerSaveLevel));
-			AsicSendCommandToMcu(pAd, 0x83, 0xff,
-					     (u8)PCIePowerSaveLevel, 0x00);
-			RT28xx_EEPROM_READ16(pAd, 0x22, PCIePowerSaveLevel);
-			PCIePowerSaveLevel &= 0xff;
-			PCIePowerSaveLevel = PCIePowerSaveLevel >> 6;
-			switch (PCIePowerSaveLevel) {
-			case 0:	/* Only support L0 */
-				pAd->LnkCtrlBitMask = 0;
-				break;
-			case 1:	/* Only enable L0s */
-				pAd->LnkCtrlBitMask = 1;
-				break;
-			case 2:	/* enable L1, L0s */
-				pAd->LnkCtrlBitMask = 3;
-				break;
-			case 3:	/* sync with host clk and enable L1, L0s */
-				pAd->LnkCtrlBitMask = 0x103;
-				break;
-			}
-			RT28xx_EEPROM_READ16(pAd, 0x24, data2);
-			if ((PCIePowerSaveLevel & 0xff) != 0xff) {
-				PCIePowerSaveLevel &= 0x3;
-
-				if (!
-				    (((data2 & 0xff00) == 0x9200)
-				     && ((data2 & 0x80) != 0))) {
-					if (PCIePowerSaveLevel > 1)
-						PCIePowerSaveLevel = 1;
-				}
-
-				DBGPRINT(RT_DEBUG_TRACE,
-					 ("====> rt28xx Write 0x83 Command = 0x%x.\n",
-					  PCIePowerSaveLevel));
-
-				AsicSendCommandToMcu(pAd, 0x83, 0xff,
-						     (u8)PCIePowerSaveLevel,
-						     0x00);
-			}
-			DBGPRINT(RT_DEBUG_TRACE,
-				 ("====> LnkCtrlBitMask = 0x%x.\n",
-				  pAd->LnkCtrlBitMask));
-		}
-	} else if (IS_RT3090(pAd) || IS_RT3572(pAd) || IS_RT3390(pAd)) {
-		u8 LinkCtrlSetting = 0;
-
-		/* Check 3090E special setting chip. */
-		RT28xx_EEPROM_READ16(pAd, 0x24, data2);
-		if ((data2 == 0x9280) && ((pAd->MACVersion & 0xffff) == 0x0211)) {
-			pAd->b3090ESpecialChip = TRUE;
-			DBGPRINT_RAW(RT_DEBUG_ERROR, ("Special 3090E chip \n"));
-		}
-
-		RTMP_IO_READ32(pAd, AUX_CTRL, &MacValue);
-		/*enable WAKE_PCIE function, which forces to enable PCIE clock when mpu interrupt asserting. */
-		/*Force PCIE 125MHz CLK to toggle */
-		MacValue |= 0x402;
-		RTMP_IO_WRITE32(pAd, AUX_CTRL, MacValue);
-		DBGPRINT_RAW(RT_DEBUG_ERROR,
-			     (" AUX_CTRL = 0x%32x\n", MacValue));
-
-		/* for RT30xx F and after, PCIe interface, and for power solution 3 */
-		if ((IS_VERSION_AFTER_F(pAd))
-		    && (pAd->StaCfg.PSControl.field.rt30xxPowerMode >= 2)
-		    && (pAd->StaCfg.PSControl.field.rt30xxPowerMode <= 3)) {
-			RTMP_IO_READ32(pAd, AUX_CTRL, &MacValue);
-			DBGPRINT_RAW(RT_DEBUG_ERROR,
-				     (" Read AUX_CTRL = 0x%x\n", MacValue));
-			/* turn on bit 12. */
-			/*enable 32KHz clock mode for power saving */
-			MacValue |= 0x1000;
-			if (MacValue != 0xffffffff) {
-				RTMP_IO_WRITE32(pAd, AUX_CTRL, MacValue);
-				DBGPRINT_RAW(RT_DEBUG_ERROR,
-					     (" Write AUX_CTRL = 0x%x\n",
-					      MacValue));
-				/* 1. if use PCIePowerSetting is 2 or 3, need to program OSC_CTRL to 0x3ff11. */
-				MacValue = 0x3ff11;
-				RTMP_IO_WRITE32(pAd, OSC_CTRL, MacValue);
-				DBGPRINT_RAW(RT_DEBUG_ERROR,
-					     (" OSC_CTRL = 0x%x\n", MacValue));
-				/* 2. Write PCI register Clk ref bit */
-				RTMPrt3xSetPCIePowerLinkCtrl(pAd);
-			} else {
-				/* Error read Aux_Ctrl value.  Force to use solution 1 */
-				DBGPRINT(RT_DEBUG_ERROR,
-					 (" Error Value in AUX_CTRL = 0x%x\n",
-					  MacValue));
-				pAd->StaCfg.PSControl.field.rt30xxPowerMode = 1;
-				DBGPRINT(RT_DEBUG_ERROR,
-					 (" Force to use power solution1 \n"));
-			}
-		}
-		/* 1. read setting from inf file. */
-
-		PCIePowerSaveLevel =
-		    (u16)pAd->StaCfg.PSControl.field.rt30xxPowerMode;
-		DBGPRINT(RT_DEBUG_ERROR,
-			 ("====> rt30xx Read PowerLevelMode =  0x%x.\n",
-			  PCIePowerSaveLevel));
-		/* 2. Check EnableNewPS. */
-		if (pAd->StaCfg.PSControl.field.EnableNewPS == FALSE)
-			PCIePowerSaveLevel = 1;
-
-		if (IS_VERSION_BEFORE_F(pAd)
-		    && (pAd->b3090ESpecialChip == FALSE)) {
-			/* Chip Version E only allow 1, So force set 1. */
-			PCIePowerSaveLevel &= 0x1;
-			pAd->PCIePowerSaveLevel = (u16)PCIePowerSaveLevel;
-			DBGPRINT(RT_DEBUG_TRACE,
-				 ("====> rt30xx E Write 0x83 Command = 0x%x.\n",
-				  PCIePowerSaveLevel));
-
-			AsicSendCommandToMcu(pAd, 0x83, 0xff,
-					     (u8)PCIePowerSaveLevel, 0x00);
-		} else {
-			/* Chip Version F and after only allow 1 or 2 or 3. This might be modified after new chip version come out. */
-			if (!
-			    ((PCIePowerSaveLevel == 1)
-			     || (PCIePowerSaveLevel == 3)))
-				PCIePowerSaveLevel = 1;
-			DBGPRINT(RT_DEBUG_ERROR,
-				 ("====> rt30xx F Write 0x83 Command = 0x%x.\n",
-				  PCIePowerSaveLevel));
-			pAd->PCIePowerSaveLevel = (u16)PCIePowerSaveLevel;
-			/* for 3090F , we need to add high-byte arg for 0x83 command to indicate the link control setting in */
-			/* PCI Configuration Space. Because firmware can't read PCI Configuration Space */
-			if ((pAd->Rt3xxRalinkLinkCtrl & 0x2)
-			    && (pAd->Rt3xxHostLinkCtrl & 0x2)) {
-				LinkCtrlSetting = 1;
-			}
-			DBGPRINT(RT_DEBUG_TRACE,
-				 ("====> rt30xxF LinkCtrlSetting = 0x%x.\n",
-				  LinkCtrlSetting));
-			AsicSendCommandToMcu(pAd, 0x83, 0xff,
-					     (u8)PCIePowerSaveLevel,
-					     LinkCtrlSetting);
-		}
-	}
-	/* Find Ralink PCIe Device's Express Capability Offset */
-	pos = pci_find_capability(pObj->pci_dev, PCI_CAP_ID_EXP);
-
-	if (pos != 0) {
-		/* Ralink PCIe Device's Link Control Register Offset */
-		pAd->RLnkCtrlOffset = pos + PCI_EXP_LNKCTL;
-		pci_read_config_word(pObj->pci_dev, pAd->RLnkCtrlOffset,
-				     &reg16);
-		Configuration = le2cpu16(reg16);
-		DBGPRINT(RT_DEBUG_TRACE,
-			 ("Read (Ralink PCIe Link Control Register) offset 0x%x = 0x%x\n",
-			  pAd->RLnkCtrlOffset, Configuration));
-		pAd->RLnkCtrlConfiguration = (Configuration & 0x103);
-		Configuration &= 0xfefc;
-		Configuration |= (0x0);
-#ifdef RT2860
-		if ((pObj->DeviceID == NIC2860_PCIe_DEVICE_ID)
-		    || (pObj->DeviceID == NIC2790_PCIe_DEVICE_ID)) {
-			reg16 = cpu2le16(Configuration);
-			pci_write_config_word(pObj->pci_dev,
-					      pAd->RLnkCtrlOffset, reg16);
-			DBGPRINT(RT_DEBUG_TRACE,
-				 ("Write (Ralink PCIe Link Control Register)  offset 0x%x = 0x%x\n",
-				  pos + PCI_EXP_LNKCTL, Configuration));
-		}
-#endif /* RT2860 // */
-
-		RTMPFindHostPCIDev(pAd);
-		if (pObj->parent_pci_dev) {
-			u16 vendor_id;
-
-			pci_read_config_word(pObj->parent_pci_dev,
-					     PCI_VENDOR_ID, &vendor_id);
-			vendor_id = le2cpu16(vendor_id);
-			if (vendor_id == PCIBUS_INTEL_VENDOR) {
-				bFindIntel = TRUE;
-				RTMP_SET_PSFLAG(pAd, fRTMP_PS_TOGGLE_L1);
-			}
-			/* Find PCI-to-PCI Bridge Express Capability Offset */
-			pos =
-			    pci_find_capability(pObj->parent_pci_dev,
-						PCI_CAP_ID_EXP);
-
-			if (pos != 0) {
-				BOOLEAN bChange = FALSE;
-				/* PCI-to-PCI Bridge Link Control Register Offset */
-				pAd->HostLnkCtrlOffset = pos + PCI_EXP_LNKCTL;
-				pci_read_config_word(pObj->parent_pci_dev,
-						     pAd->HostLnkCtrlOffset,
-						     &reg16);
-				Configuration = le2cpu16(reg16);
-				DBGPRINT(RT_DEBUG_TRACE,
-					 ("Read (Host PCI-to-PCI Bridge Link Control Register) offset 0x%x = 0x%x\n",
-					  pAd->HostLnkCtrlOffset,
-					  Configuration));
-				pAd->HostLnkCtrlConfiguration =
-				    (Configuration & 0x103);
-				Configuration &= 0xfefc;
-				Configuration |= (0x0);
-
-				switch (pObj->DeviceID) {
-#ifdef RT2860
-				case NIC2860_PCIe_DEVICE_ID:
-				case NIC2790_PCIe_DEVICE_ID:
-					bChange = TRUE;
-					break;
-#endif /* RT2860 // */
-#ifdef RT3090
-				case NIC3090_PCIe_DEVICE_ID:
-				case NIC3091_PCIe_DEVICE_ID:
-				case NIC3092_PCIe_DEVICE_ID:
-					if (bFindIntel == FALSE)
-						bChange = TRUE;
-					break;
-#endif /* RT3090 // */
-				default:
-					break;
-				}
-
-				if (bChange) {
-					reg16 = cpu2le16(Configuration);
-					pci_write_config_word(pObj->
-							      parent_pci_dev,
-							      pAd->
-							      HostLnkCtrlOffset,
-							      reg16);
-					DBGPRINT(RT_DEBUG_TRACE,
-						 ("Write (Host PCI-to-PCI Bridge Link Control Register) offset 0x%x = 0x%x\n",
-						  pAd->HostLnkCtrlOffset,
-						  Configuration));
-				}
-			} else {
-				pAd->HostLnkCtrlOffset = 0;
-				DBGPRINT(RT_DEBUG_ERROR,
-					 ("%s: cannot find PCI-to-PCI Bridge PCI Express Capability!\n",
-					  __func__));
-			}
-		}
-	} else {
-		pAd->RLnkCtrlOffset = 0;
-		pAd->HostLnkCtrlOffset = 0;
-		DBGPRINT(RT_DEBUG_ERROR,
-			 ("%s: cannot find Ralink PCIe Device's PCI Express Capability!\n",
-			  __func__));
-	}
-
-	if (bFindIntel == FALSE) {
-		DBGPRINT(RT_DEBUG_TRACE,
-			 ("Doesn't find Intel PCI host controller. \n"));
-		/* Doesn't switch L0, L1, So set PCIePowerSaveLevel to 0xff */
-		pAd->PCIePowerSaveLevel = 0xff;
-		if ((pAd->RLnkCtrlOffset != 0)
-#ifdef RT3090
-		    && ((pObj->DeviceID == NIC3090_PCIe_DEVICE_ID)
-			|| (pObj->DeviceID == NIC3091_PCIe_DEVICE_ID)
-			|| (pObj->DeviceID == NIC3092_PCIe_DEVICE_ID))
-#endif /* RT3090 // */
-		    ) {
-			pci_read_config_word(pObj->pci_dev, pAd->RLnkCtrlOffset,
-					     &reg16);
-			Configuration = le2cpu16(reg16);
-			DBGPRINT(RT_DEBUG_TRACE,
-				 ("Read (Ralink 30xx PCIe Link Control Register) offset 0x%x = 0x%x\n",
-				  pAd->RLnkCtrlOffset, Configuration));
-			pAd->RLnkCtrlConfiguration = (Configuration & 0x103);
-			Configuration &= 0xfefc;
-			Configuration |= (0x0);
-			reg16 = cpu2le16(Configuration);
-			pci_write_config_word(pObj->pci_dev,
-					      pAd->RLnkCtrlOffset, reg16);
-			DBGPRINT(RT_DEBUG_TRACE,
-				 ("Write (Ralink PCIe Link Control Register)  offset 0x%x = 0x%x\n",
-				  pos + PCI_EXP_LNKCTL, Configuration));
-		}
-	}
-}
-
-void RTMPFindHostPCIDev(struct rt_rtmp_adapter *pAd)
-{
-	u16 reg16;
-	u8 reg8;
-	u32 DevFn;
-	struct pci_dev *pPci_dev;
-	struct os_cookie *pObj;
-
-	pObj = (struct os_cookie *)pAd->OS_Cookie;
-
-	if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE))
-		return;
-
-	DBGPRINT(RT_DEBUG_TRACE, ("%s.===>\n", __func__));
-
-	pObj->parent_pci_dev = NULL;
-	if (pObj->pci_dev->bus->parent) {
-		for (DevFn = 0; DevFn < 255; DevFn++) {
-			pPci_dev =
-			    pci_get_slot(pObj->pci_dev->bus->parent, DevFn);
-			if (pPci_dev) {
-				pci_read_config_word(pPci_dev, PCI_CLASS_DEVICE,
-						     &reg16);
-				reg16 = le2cpu16(reg16);
-				pci_read_config_byte(pPci_dev, PCI_CB_CARD_BUS,
-						     &reg8);
-				if ((reg16 == PCI_CLASS_BRIDGE_PCI)
-				    && (reg8 == pObj->pci_dev->bus->number)) {
-					pObj->parent_pci_dev = pPci_dev;
-				}
-			}
-		}
-	}
-}
-
-/*
-	========================================================================
-
-	Routine Description:
-
-	Arguments:
-		Level = RESTORE_HALT : Restore PCI host and Ralink PCIe Link Control field to its default value.
-		Level = Other Value : Restore from dot11 power save or radio off status. And force PCI host Link Control fields to 0x1
-
-	========================================================================
-*/
-void RTMPPCIeLinkCtrlValueRestore(struct rt_rtmp_adapter *pAd, u8 Level)
-{
-	u16 PCIePowerSaveLevel, reg16;
-	u16 Configuration;
-	struct os_cookie *pObj;
-
-	pObj = (struct os_cookie *)pAd->OS_Cookie;
-
-	if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE))
-		return;
-
-#ifdef RT2860
-	if (!((pObj->DeviceID == NIC2860_PCIe_DEVICE_ID)
-	      || (pObj->DeviceID == NIC2790_PCIe_DEVICE_ID)))
-		return;
-#endif /* RT2860 // */
-	/* Check PSControl Configuration */
-	if (pAd->StaCfg.PSControl.field.EnableNewPS == FALSE)
-		return;
-
-	/*3090 will not execute the following codes. */
-	/* Check interface : If not PCIe interface, return. */
-
-#ifdef RT3090
-	if ((pObj->DeviceID == NIC3090_PCIe_DEVICE_ID)
-	    || (pObj->DeviceID == NIC3091_PCIe_DEVICE_ID)
-	    || (pObj->DeviceID == NIC3092_PCIe_DEVICE_ID))
-		return;
-#endif /* RT3090 // */
-
-	DBGPRINT(RT_DEBUG_TRACE, ("%s.===>\n", __func__));
-	PCIePowerSaveLevel = pAd->PCIePowerSaveLevel;
-	if ((PCIePowerSaveLevel & 0xff) == 0xff) {
-		DBGPRINT(RT_DEBUG_TRACE, ("return  \n"));
-		return;
-	}
-
-	if (pObj->parent_pci_dev && (pAd->HostLnkCtrlOffset != 0)) {
-		PCI_REG_READ_WORD(pObj->parent_pci_dev, pAd->HostLnkCtrlOffset,
-				  Configuration);
-		if ((Configuration != 0) && (Configuration != 0xFFFF)) {
-			Configuration &= 0xfefc;
-			/* If call from interface down, restore to original setting. */
-			if (Level == RESTORE_CLOSE)
-				Configuration |= pAd->HostLnkCtrlConfiguration;
-			else
-				Configuration |= 0x0;
-			PCI_REG_WIRTE_WORD(pObj->parent_pci_dev,
-					   pAd->HostLnkCtrlOffset,
-					   Configuration);
-			DBGPRINT(RT_DEBUG_TRACE,
-				 ("Restore PCI host : offset 0x%x = 0x%x\n",
-				  pAd->HostLnkCtrlOffset, Configuration));
-		} else
-			DBGPRINT(RT_DEBUG_ERROR,
-				 ("Restore PCI host : PCI_REG_READ_WORD failed (Configuration = 0x%x)\n",
-				  Configuration));
-	}
-
-	if (pObj->pci_dev && (pAd->RLnkCtrlOffset != 0)) {
-		PCI_REG_READ_WORD(pObj->pci_dev, pAd->RLnkCtrlOffset,
-				  Configuration);
-		if ((Configuration != 0) && (Configuration != 0xFFFF)) {
-			Configuration &= 0xfefc;
-			/* If call from interface down, restore to original setting. */
-			if (Level == RESTORE_CLOSE)
-				Configuration |= pAd->RLnkCtrlConfiguration;
-			else
-				Configuration |= 0x0;
-			PCI_REG_WIRTE_WORD(pObj->pci_dev, pAd->RLnkCtrlOffset,
-					   Configuration);
-			DBGPRINT(RT_DEBUG_TRACE,
-				 ("Restore Ralink : offset 0x%x = 0x%x\n",
-				  pAd->RLnkCtrlOffset, Configuration));
-		} else
-			DBGPRINT(RT_DEBUG_ERROR,
-				 ("Restore Ralink : PCI_REG_READ_WORD failed (Configuration = 0x%x)\n",
-				  Configuration));
-	}
-
-	DBGPRINT(RT_DEBUG_TRACE, ("%s <===\n", __func__));
-}
-
-/*
-	========================================================================
-
-	Routine Description:
-
-	Arguments:
-		Max : limit Host PCI and Ralink PCIe device's LINK CONTROL field's value.
-		Because now frequently set our device to mode 1 or mode 3 will cause problem.
-
-	========================================================================
-*/
-void RTMPPCIeLinkCtrlSetting(struct rt_rtmp_adapter *pAd, u16 Max)
-{
-	u16 PCIePowerSaveLevel, reg16;
-	u16 Configuration;
-	struct os_cookie *pObj;
-
-	pObj = (struct os_cookie *)pAd->OS_Cookie;
-
-	if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE))
-		return;
-
-#ifdef RT2860
-	if (!((pObj->DeviceID == NIC2860_PCIe_DEVICE_ID)
-	      || (pObj->DeviceID == NIC2790_PCIe_DEVICE_ID)))
-		return;
-#endif /* RT2860 // */
-	/* Check PSControl Configuration */
-	if (pAd->StaCfg.PSControl.field.EnableNewPS == FALSE)
-		return;
-
-	/* Check interface : If not PCIe interface, return. */
-	/*Block 3090 to enter the following function */
-
-#ifdef RT3090
-	if ((pObj->DeviceID == NIC3090_PCIe_DEVICE_ID)
-	    || (pObj->DeviceID == NIC3091_PCIe_DEVICE_ID)
-	    || (pObj->DeviceID == NIC3092_PCIe_DEVICE_ID))
-		return;
-#endif /* RT3090 // */
-	if (!RTMP_TEST_PSFLAG(pAd, fRTMP_PS_CAN_GO_SLEEP)) {
-		DBGPRINT(RT_DEBUG_INFO,
-			 ("RTMPPCIePowerLinkCtrl return on fRTMP_PS_CAN_GO_SLEEP flag\n"));
-		return;
-	}
-
-	DBGPRINT(RT_DEBUG_TRACE, ("%s===>\n", __func__));
-	PCIePowerSaveLevel = pAd->PCIePowerSaveLevel;
-	if ((PCIePowerSaveLevel & 0xff) == 0xff) {
-		DBGPRINT(RT_DEBUG_TRACE, ("return  \n"));
-		return;
-	}
-	PCIePowerSaveLevel = PCIePowerSaveLevel >> 6;
-
-	/* Skip non-exist deice right away */
-	if (pObj->parent_pci_dev && (pAd->HostLnkCtrlOffset != 0)) {
-		PCI_REG_READ_WORD(pObj->parent_pci_dev, pAd->HostLnkCtrlOffset,
-				  Configuration);
-		switch (PCIePowerSaveLevel) {
-		case 0:
-			/* Set b0 and b1 of LinkControl (both 2892 and PCIe bridge) to 00 */
-			Configuration &= 0xfefc;
-			break;
-		case 1:
-			/* Set b0 and b1 of LinkControl (both 2892 and PCIe bridge) to 01 */
-			Configuration &= 0xfefc;
-			Configuration |= 0x1;
-			break;
-		case 2:
-			/*  Set b0 and b1 of LinkControl (both 2892 and PCIe bridge) to 11 */
-			Configuration &= 0xfefc;
-			Configuration |= 0x3;
-			break;
-		case 3:
-			/* Set b0 and b1 of LinkControl (both 2892 and PCIe bridge) to 11 and bit 8 of LinkControl of 2892 to 1 */
-			Configuration &= 0xfefc;
-			Configuration |= 0x103;
-			break;
-		}
-		PCI_REG_WIRTE_WORD(pObj->parent_pci_dev, pAd->HostLnkCtrlOffset,
-				   Configuration);
-		DBGPRINT(RT_DEBUG_TRACE,
-			 ("Write PCI host offset 0x%x = 0x%x\n",
-			  pAd->HostLnkCtrlOffset, Configuration));
-	}
-
-	if (pObj->pci_dev && (pAd->RLnkCtrlOffset != 0)) {
-		/* first 2892 chip not allow to frequently set mode 3. will cause hang problem. */
-		if (PCIePowerSaveLevel > Max)
-			PCIePowerSaveLevel = Max;
-
-		PCI_REG_READ_WORD(pObj->pci_dev, pAd->RLnkCtrlOffset,
-				  Configuration);
-		switch (PCIePowerSaveLevel) {
-		case 0:
-			/* No PCI power safe */
-			/* Set b0 and b1 of LinkControl (both 2892 and PCIe bridge) to 00 . */
-			Configuration &= 0xfefc;
-			break;
-		case 1:
-			/*  L0 */
-			/* Set b0 and b1 of LinkControl (both 2892 and PCIe bridge) to 01 . */
-			Configuration &= 0xfefc;
-			Configuration |= 0x1;
-			break;
-		case 2:
-			/* L0 and L1 */
-			/*  Set b0 and b1 of LinkControl (both 2892 and PCIe bridge) to 11 */
-			Configuration &= 0xfefc;
-			Configuration |= 0x3;
-			break;
-		case 3:
-			/* L0 , L1 and clock management. */
-			/* Set b0 and b1 of LinkControl (both 2892 and PCIe bridge) to 11 and bit 8 of LinkControl of 2892 to 1 */
-			Configuration &= 0xfefc;
-			Configuration |= 0x103;
-			pAd->bPCIclkOff = TRUE;
-			break;
-		}
-		PCI_REG_WIRTE_WORD(pObj->pci_dev, pAd->RLnkCtrlOffset,
-				   Configuration);
-		DBGPRINT(RT_DEBUG_TRACE,
-			 ("Write Ralink device : offset 0x%x = 0x%x\n",
-			  pAd->RLnkCtrlOffset, Configuration));
-	}
-
-	DBGPRINT(RT_DEBUG_TRACE, ("RTMPPCIePowerLinkCtrl <==============\n"));
-}
-
-/*
-	========================================================================
-
-	Routine Description:
-		1. Write a PCI register for rt30xx power solution 3
-
-	========================================================================
-*/
-void RTMPrt3xSetPCIePowerLinkCtrl(struct rt_rtmp_adapter *pAd)
-{
-
-	unsigned long HostConfiguration = 0;
-	unsigned long Configuration;
-	struct os_cookie *pObj;
-	int pos;
-	u16 reg16;
-
-	pObj = (struct os_cookie *)pAd->OS_Cookie;
-
-	DBGPRINT(RT_DEBUG_INFO,
-		 ("RTMPrt3xSetPCIePowerLinkCtrl.===> %lx\n",
-		  pAd->StaCfg.PSControl.word));
-
-	/* Check PSControl Configuration */
-	if (pAd->StaCfg.PSControl.field.EnableNewPS == FALSE)
-		return;
-	RTMPFindHostPCIDev(pAd);
-	if (pObj->parent_pci_dev) {
-		/* Find PCI-to-PCI Bridge Express Capability Offset */
-		pos = pci_find_capability(pObj->parent_pci_dev, PCI_CAP_ID_EXP);
-
-		if (pos != 0)
-			pAd->HostLnkCtrlOffset = pos + PCI_EXP_LNKCTL;
-
-		/* If configured to turn on L1. */
-		HostConfiguration = 0;
-		if (pAd->StaCfg.PSControl.field.rt30xxForceASPMTest == 1) {
-			DBGPRINT(RT_DEBUG_TRACE, ("Enter,PSM : Force ASPM\n"));
-
-			/* Skip non-exist device right away */
-			if ((pAd->HostLnkCtrlOffset != 0)) {
-				PCI_REG_READ_WORD(pObj->parent_pci_dev,
-						  pAd->HostLnkCtrlOffset,
-						  HostConfiguration);
-				/* Prepare Configuration to write to Host */
-				HostConfiguration |= 0x3;
-				PCI_REG_WIRTE_WORD(pObj->parent_pci_dev,
-						   pAd->HostLnkCtrlOffset,
-						   HostConfiguration);
-				pAd->Rt3xxHostLinkCtrl = HostConfiguration;
-				/* Because in rt30xxForceASPMTest Mode, Force turn on L0s, L1. */
-				/* Fix HostConfiguration bit0:1 = 0x3 for later use. */
-				HostConfiguration = 0x3;
-				DBGPRINT(RT_DEBUG_TRACE,
-					 ("PSM : Force ASPM : "
-					  "Host device L1/L0s Value =  0x%lx\n",
-					  HostConfiguration));
-			}
-		} else if (pAd->StaCfg.PSControl.field.rt30xxFollowHostASPM ==
-			   1) {
-
-			/* Skip non-exist deice right away */
-			if ((pAd->HostLnkCtrlOffset != 0)) {
-				PCI_REG_READ_WORD(pObj->parent_pci_dev,
-						  pAd->HostLnkCtrlOffset,
-						  HostConfiguration);
-				pAd->Rt3xxHostLinkCtrl = HostConfiguration;
-				HostConfiguration &= 0x3;
-				DBGPRINT(RT_DEBUG_TRACE,
-					 ("PSM : Follow Host ASPM : "
-					  "Host device L1/L0s Value =  0x%lx\n",
-					  HostConfiguration));
-			}
-		}
-	}
-	/* Prepare to write Ralink setting. */
-	/* Find Ralink PCIe Device's Express Capability Offset */
-	pos = pci_find_capability(pObj->pci_dev, PCI_CAP_ID_EXP);
-
-	if (pos != 0) {
-		/* Ralink PCIe Device's Link Control Register Offset */
-		pAd->RLnkCtrlOffset = pos + PCI_EXP_LNKCTL;
-		pci_read_config_word(pObj->pci_dev, pAd->RLnkCtrlOffset,
-				     &reg16);
-		Configuration = le2cpu16(reg16);
-		DBGPRINT(RT_DEBUG_TRACE,
-			 ("Read (Ralink PCIe Link Control Register) "
-			  "offset 0x%x = 0x%lx\n",
-			  pAd->RLnkCtrlOffset, Configuration));
-		Configuration |= 0x100;
-		if ((pAd->StaCfg.PSControl.field.rt30xxFollowHostASPM == 1)
-		    || (pAd->StaCfg.PSControl.field.rt30xxForceASPMTest == 1)) {
-			switch (HostConfiguration) {
-			case 0:
-				Configuration &= 0xffffffc;
-				break;
-			case 1:
-				Configuration &= 0xffffffc;
-				Configuration |= 0x1;
-				break;
-			case 2:
-				Configuration &= 0xffffffc;
-				Configuration |= 0x2;
-				break;
-			case 3:
-				Configuration |= 0x3;
-				break;
-			}
-		}
-		reg16 = cpu2le16(Configuration);
-		pci_write_config_word(pObj->pci_dev, pAd->RLnkCtrlOffset,
-				      reg16);
-		pAd->Rt3xxRalinkLinkCtrl = Configuration;
-		DBGPRINT(RT_DEBUG_TRACE,
-			 ("PSM :Write Ralink device L1/L0s Value =  0x%lx\n",
-			  Configuration));
-	}
-	DBGPRINT(RT_DEBUG_INFO,
-		 ("PSM :RTMPrt3xSetPCIePowerLinkCtrl <==============\n"));
-}
diff -druN linux-2.6.39-libre/drivers/staging/rt2860/rt_config.h linux-3.0-rc7-libre/drivers/staging/rt2860/rt_config.h
--- linux-2.6.39-libre/drivers/staging/rt2860/rt_config.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rt2860/rt_config.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,71 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, 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.             *
- *                                                                       *
- *************************************************************************
-
-	Module Name:
-	rt_config.h
-
-	Abstract:
-	Central header file to maintain all include files for all NDIS
-	miniport driver routines.
-
-	Revision History:
-	Who         When          What
-	--------    ----------    ----------------------------------------------
-	Paul Lin    08-01-2002    created
-
-*/
-#ifndef	__RT_CONFIG_H__
-#define	__RT_CONFIG_H__
-
-#include    "rtmp_type.h"
-#include "rtmp_os.h"
-
-#include "rtmp_def.h"
-#include "rtmp_chip.h"
-#include "rtmp_timer.h"
-
-#include    "oid.h"
-#include    "mlme.h"
-#include    "wpa.h"
-#include "crypt_md5.h"
-#include "crypt_sha2.h"
-#include "crypt_hmac.h"
-#include    "rtmp.h"
-#include	"ap.h"
-#include	"dfs.h"
-#include	"chlist.h"
-#include	"spectrum.h"
-
-#include "eeprom.h"
-#if defined(RTMP_PCI_SUPPORT) || defined(RTMP_USB_SUPPORT)
-#include "rtmp_mcu.h"
-#endif
-
-#ifdef IGMP_SNOOP_SUPPORT
-#include "igmp_snoop.h"
-#endif /* IGMP_SNOOP_SUPPORT // */
-
-#endif /* __RT_CONFIG_H__ */
diff -druN linux-2.6.39-libre/drivers/staging/rt2860/rt_linux.c linux-3.0-rc7-libre/drivers/staging/rt2860/rt_linux.c
--- linux-2.6.39-libre/drivers/staging/rt2860/rt_linux.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rt2860/rt_linux.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,1367 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, Inc.
- *
- * This program is free software; you can redistribute it and/or modify  *
- * it under the terms of the GNU General Public License as published by  *
- * the Free Software Foundation; either version 2 of the License, or     *
- * (at your option) any later version.                                   *
- *                                                                       *
- * This program is distributed in the hope that it will be useful,       *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of        *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
- * GNU General Public License for more details.                          *
- *                                                                       *
- * You should have received a copy of the GNU General Public License     *
- * along with this program; if not, write to the                         *
- * Free Software Foundation, Inc.,                                       *
- * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
- *                                                                       *
- *************************************************************************
- */
-
-#include <linux/firmware.h>
-#include <linux/sched.h>
-#include <linux/slab.h>
-#include "rt_config.h"
-
-unsigned long RTDebugLevel = RT_DEBUG_ERROR;
-
-/* for wireless system event message */
-char const *pWirelessSysEventText[IW_SYS_EVENT_TYPE_NUM] = {
-	/* system status event */
-	"had associated successfully",	/* IW_ASSOC_EVENT_FLAG */
-	"had disassociated",	/* IW_DISASSOC_EVENT_FLAG */
-	"had deauthenticated",	/* IW_DEAUTH_EVENT_FLAG */
-	"had been aged-out and disassociated",	/* IW_AGEOUT_EVENT_FLAG */
-	"occurred CounterMeasures attack",	/* IW_COUNTER_MEASURES_EVENT_FLAG */
-	"occurred replay counter different in Key Handshaking",	/* IW_REPLAY_COUNTER_DIFF_EVENT_FLAG */
-	"occurred RSNIE different in Key Handshaking",	/* IW_RSNIE_DIFF_EVENT_FLAG */
-	"occurred MIC different in Key Handshaking",	/* IW_MIC_DIFF_EVENT_FLAG */
-	"occurred ICV error in RX",	/* IW_ICV_ERROR_EVENT_FLAG */
-	"occurred MIC error in RX",	/* IW_MIC_ERROR_EVENT_FLAG */
-	"Group Key Handshaking timeout",	/* IW_GROUP_HS_TIMEOUT_EVENT_FLAG */
-	"Pairwise Key Handshaking timeout",	/* IW_PAIRWISE_HS_TIMEOUT_EVENT_FLAG */
-	"RSN IE sanity check failure",	/* IW_RSNIE_SANITY_FAIL_EVENT_FLAG */
-	"set key done in WPA/WPAPSK",	/* IW_SET_KEY_DONE_WPA1_EVENT_FLAG */
-	"set key done in WPA2/WPA2PSK",	/* IW_SET_KEY_DONE_WPA2_EVENT_FLAG */
-	"connects with our wireless client",	/* IW_STA_LINKUP_EVENT_FLAG */
-	"disconnects with our wireless client",	/* IW_STA_LINKDOWN_EVENT_FLAG */
-	"scan completed"	/* IW_SCAN_COMPLETED_EVENT_FLAG */
-	    "scan terminate! Busy! Enqueue fail!"	/* IW_SCAN_ENQUEUE_FAIL_EVENT_FLAG */
-};
-
-/* for wireless IDS_spoof_attack event message */
-char const *pWirelessSpoofEventText[IW_SPOOF_EVENT_TYPE_NUM] = {
-	"detected conflict SSID",	/* IW_CONFLICT_SSID_EVENT_FLAG */
-	"detected spoofed association response",	/* IW_SPOOF_ASSOC_RESP_EVENT_FLAG */
-	"detected spoofed reassociation responses",	/* IW_SPOOF_REASSOC_RESP_EVENT_FLAG */
-	"detected spoofed probe response",	/* IW_SPOOF_PROBE_RESP_EVENT_FLAG */
-	"detected spoofed beacon",	/* IW_SPOOF_BEACON_EVENT_FLAG */
-	"detected spoofed disassociation",	/* IW_SPOOF_DISASSOC_EVENT_FLAG */
-	"detected spoofed authentication",	/* IW_SPOOF_AUTH_EVENT_FLAG */
-	"detected spoofed deauthentication",	/* IW_SPOOF_DEAUTH_EVENT_FLAG */
-	"detected spoofed unknown management frame",	/* IW_SPOOF_UNKNOWN_MGMT_EVENT_FLAG */
-	"detected replay attack"	/* IW_REPLAY_ATTACK_EVENT_FLAG */
-};
-
-/* for wireless IDS_flooding_attack event message */
-char const *pWirelessFloodEventText[IW_FLOOD_EVENT_TYPE_NUM] = {
-	"detected authentication flooding",	/* IW_FLOOD_AUTH_EVENT_FLAG */
-	"detected association request flooding",	/* IW_FLOOD_ASSOC_REQ_EVENT_FLAG */
-	"detected reassociation request flooding",	/* IW_FLOOD_REASSOC_REQ_EVENT_FLAG */
-	"detected probe request flooding",	/* IW_FLOOD_PROBE_REQ_EVENT_FLAG */
-	"detected disassociation flooding",	/* IW_FLOOD_DISASSOC_EVENT_FLAG */
-	"detected deauthentication flooding",	/* IW_FLOOD_DEAUTH_EVENT_FLAG */
-	"detected 802.1x eap-request flooding"	/* IW_FLOOD_EAP_REQ_EVENT_FLAG */
-};
-
-/* timeout -- ms */
-void RTMP_SetPeriodicTimer(struct timer_list *pTimer,
-			   IN unsigned long timeout)
-{
-	timeout = ((timeout * OS_HZ) / 1000);
-	pTimer->expires = jiffies + timeout;
-	add_timer(pTimer);
-}
-
-/* convert NdisMInitializeTimer --> RTMP_OS_Init_Timer */
-void RTMP_OS_Init_Timer(struct rt_rtmp_adapter *pAd,
-			struct timer_list *pTimer,
-			IN TIMER_FUNCTION function, void *data)
-{
-	init_timer(pTimer);
-	pTimer->data = (unsigned long)data;
-	pTimer->function = function;
-}
-
-void RTMP_OS_Add_Timer(struct timer_list *pTimer,
-		       IN unsigned long timeout)
-{
-	if (timer_pending(pTimer))
-		return;
-
-	timeout = ((timeout * OS_HZ) / 1000);
-	pTimer->expires = jiffies + timeout;
-	add_timer(pTimer);
-}
-
-void RTMP_OS_Mod_Timer(struct timer_list *pTimer,
-		       IN unsigned long timeout)
-{
-	timeout = ((timeout * OS_HZ) / 1000);
-	mod_timer(pTimer, jiffies + timeout);
-}
-
-void RTMP_OS_Del_Timer(struct timer_list *pTimer, OUT BOOLEAN *pCancelled)
-{
-	if (timer_pending(pTimer)) {
-		*pCancelled = del_timer_sync(pTimer);
-	} else {
-		*pCancelled = TRUE;
-	}
-
-}
-
-void RTMP_OS_Release_Packet(struct rt_rtmp_adapter *pAd, struct rt_queue_entry *pEntry)
-{
-	/*RTMPFreeNdisPacket(pAd, (struct sk_buff *)pEntry); */
-}
-
-/* Unify all delay routine by using udelay */
-void RTMPusecDelay(unsigned long usec)
-{
-	unsigned long i;
-
-	for (i = 0; i < (usec / 50); i++)
-		udelay(50);
-
-	if (usec % 50)
-		udelay(usec % 50);
-}
-
-void RTMP_GetCurrentSystemTime(LARGE_INTEGER *time)
-{
-	time->u.LowPart = jiffies;
-}
-
-/* pAd MUST allow to be NULL */
-int os_alloc_mem(struct rt_rtmp_adapter *pAd, u8 ** mem, unsigned long size)
-{
-	*mem = kmalloc(size, GFP_ATOMIC);
-	if (*mem)
-		return NDIS_STATUS_SUCCESS;
-	else
-		return NDIS_STATUS_FAILURE;
-}
-
-/* pAd MUST allow to be NULL */
-int os_free_mem(struct rt_rtmp_adapter *pAd, void *mem)
-{
-
-	ASSERT(mem);
-	kfree(mem);
-	return NDIS_STATUS_SUCCESS;
-}
-
-void *RtmpOSNetPktAlloc(struct rt_rtmp_adapter *pAd, IN int size)
-{
-	struct sk_buff *skb;
-	/* Add 2 more bytes for ip header alignment */
-	skb = dev_alloc_skb(size + 2);
-
-	return (void *)skb;
-}
-
-void *RTMP_AllocateFragPacketBuffer(struct rt_rtmp_adapter *pAd,
-					   unsigned long Length)
-{
-	struct sk_buff *pkt;
-
-	pkt = dev_alloc_skb(Length);
-
-	if (pkt == NULL) {
-		DBGPRINT(RT_DEBUG_ERROR,
-			 ("can't allocate frag rx %ld size packet\n", Length));
-	}
-
-	if (pkt) {
-		RTMP_SET_PACKET_SOURCE(OSPKT_TO_RTPKT(pkt), PKTSRC_NDIS);
-	}
-
-	return (void *)pkt;
-}
-
-void *RTMP_AllocateTxPacketBuffer(struct rt_rtmp_adapter *pAd,
-					 unsigned long Length,
-					 IN BOOLEAN Cached,
-					 void **VirtualAddress)
-{
-	struct sk_buff *pkt;
-
-	pkt = dev_alloc_skb(Length);
-
-	if (pkt == NULL) {
-		DBGPRINT(RT_DEBUG_ERROR,
-			 ("can't allocate tx %ld size packet\n", Length));
-	}
-
-	if (pkt) {
-		RTMP_SET_PACKET_SOURCE(OSPKT_TO_RTPKT(pkt), PKTSRC_NDIS);
-		*VirtualAddress = (void *)pkt->data;
-	} else {
-		*VirtualAddress = (void *)NULL;
-	}
-
-	return (void *)pkt;
-}
-
-void build_tx_packet(struct rt_rtmp_adapter *pAd,
-		     void *pPacket,
-		     u8 *pFrame, unsigned long FrameLen)
-{
-
-	struct sk_buff *pTxPkt;
-
-	ASSERT(pPacket);
-	pTxPkt = RTPKT_TO_OSPKT(pPacket);
-
-	NdisMoveMemory(skb_put(pTxPkt, FrameLen), pFrame, FrameLen);
-}
-
-void RTMPFreeAdapter(struct rt_rtmp_adapter *pAd)
-{
-	struct os_cookie *os_cookie;
-	int index;
-
-	os_cookie = (struct os_cookie *)pAd->OS_Cookie;
-
-	kfree(pAd->BeaconBuf);
-
-	NdisFreeSpinLock(&pAd->MgmtRingLock);
-
-#ifdef RTMP_MAC_PCI
-	NdisFreeSpinLock(&pAd->RxRingLock);
-#ifdef RT3090
-	NdisFreeSpinLock(&pAd->McuCmdLock);
-#endif /* RT3090 // */
-#endif /* RTMP_MAC_PCI // */
-
-	for (index = 0; index < NUM_OF_TX_RING; index++) {
-		NdisFreeSpinLock(&pAd->TxSwQueueLock[index]);
-		NdisFreeSpinLock(&pAd->DeQueueLock[index]);
-		pAd->DeQueueRunning[index] = FALSE;
-	}
-
-	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); */
-	kfree(os_cookie);
-}
-
-BOOLEAN OS_Need_Clone_Packet(void)
-{
-	return FALSE;
-}
-
-/*
-	========================================================================
-
-	Routine Description:
-		clone an input NDIS PACKET to another one. The new internally created NDIS PACKET
-		must have only one NDIS BUFFER
-		return - byte copied. 0 means can't create NDIS PACKET
-		NOTE: internally created char should be destroyed by RTMPFreeNdisPacket
-
-	Arguments:
-		pAd 	Pointer to our adapter
-		pInsAMSDUHdr	EWC A-MSDU format has extra 14-bytes header. if TRUE, insert this 14-byte hdr in front of MSDU.
-		*pSrcTotalLen			return total packet length. This length is calculated with 802.3 format packet.
-
-	Return Value:
-		NDIS_STATUS_SUCCESS
-		NDIS_STATUS_FAILURE
-
-	Note:
-
-	========================================================================
-*/
-int RTMPCloneNdisPacket(struct rt_rtmp_adapter *pAd,
-				IN BOOLEAN pInsAMSDUHdr,
-				void *pInPacket,
-				void **ppOutPacket)
-{
-
-	struct sk_buff *pkt;
-
-	ASSERT(pInPacket);
-	ASSERT(ppOutPacket);
-
-	/* 1. Allocate a packet */
-	pkt = dev_alloc_skb(2048);
-
-	if (pkt == NULL) {
-		return NDIS_STATUS_FAILURE;
-	}
-
-	skb_put(pkt, GET_OS_PKT_LEN(pInPacket));
-	NdisMoveMemory(pkt->data, GET_OS_PKT_DATAPTR(pInPacket),
-		       GET_OS_PKT_LEN(pInPacket));
-	*ppOutPacket = OSPKT_TO_RTPKT(pkt);
-
-	RTMP_SET_PACKET_SOURCE(OSPKT_TO_RTPKT(pkt), PKTSRC_NDIS);
-
-	printk(KERN_DEBUG "###Clone###\n");
-
-	return NDIS_STATUS_SUCCESS;
-}
-
-/* the allocated NDIS PACKET must be freed via RTMPFreeNdisPacket() */
-int RTMPAllocateNdisPacket(struct rt_rtmp_adapter *pAd,
-				   void **ppPacket,
-				   u8 *pHeader,
-				   u32 HeaderLen,
-				   u8 *pData, u32 DataLen)
-{
-	void *pPacket;
-	ASSERT(pData);
-	ASSERT(DataLen);
-
-	/* 1. Allocate a packet */
-	pPacket =
-	    (void **) dev_alloc_skb(HeaderLen + DataLen +
-					   RTMP_PKT_TAIL_PADDING);
-	if (pPacket == NULL) {
-		*ppPacket = NULL;
-		pr_devel("RTMPAllocateNdisPacket Fail\n");
-
-		return NDIS_STATUS_FAILURE;
-	}
-	/* 2. clone the frame content */
-	if (HeaderLen > 0)
-		NdisMoveMemory(GET_OS_PKT_DATAPTR(pPacket), pHeader, HeaderLen);
-	if (DataLen > 0)
-		NdisMoveMemory(GET_OS_PKT_DATAPTR(pPacket) + HeaderLen, pData,
-			       DataLen);
-
-	/* 3. update length of packet */
-	skb_put(GET_OS_PKT_TYPE(pPacket), HeaderLen + DataLen);
-
-	RTMP_SET_PACKET_SOURCE(pPacket, PKTSRC_NDIS);
-/*      printk("%s : pPacket = %p, len = %d\n", __func__, pPacket, GET_OS_PKT_LEN(pPacket)); */
-	*ppPacket = pPacket;
-	return NDIS_STATUS_SUCCESS;
-}
-
-/*
-  ========================================================================
-  Description:
-	This routine frees a miniport internally allocated char and its
-	corresponding NDIS_BUFFER and allocated memory.
-  ========================================================================
-*/
-void RTMPFreeNdisPacket(struct rt_rtmp_adapter *pAd, void *pPacket)
-{
-	dev_kfree_skb_any(RTPKT_TO_OSPKT(pPacket));
-}
-
-/* IRQL = DISPATCH_LEVEL */
-/* NOTE: we do have an assumption here, that Byte0 and Byte1 always reasid at the same */
-/*                       scatter gather buffer */
-int Sniff2BytesFromNdisBuffer(char *pFirstBuffer,
-				      u8 DesiredOffset,
-				      u8 *pByte0, u8 *pByte1)
-{
-	*pByte0 = *(u8 *)(pFirstBuffer + DesiredOffset);
-	*pByte1 = *(u8 *)(pFirstBuffer + DesiredOffset + 1);
-
-	return NDIS_STATUS_SUCCESS;
-}
-
-void RTMP_QueryPacketInfo(void *pPacket,
-			  struct rt_packet_info *pPacketInfo,
-			  u8 **pSrcBufVA, u32 * pSrcBufLen)
-{
-	pPacketInfo->BufferCount = 1;
-	pPacketInfo->pFirstBuffer = (char *)GET_OS_PKT_DATAPTR(pPacket);
-	pPacketInfo->PhysicalBufferCount = 1;
-	pPacketInfo->TotalPacketLength = GET_OS_PKT_LEN(pPacket);
-
-	*pSrcBufVA = GET_OS_PKT_DATAPTR(pPacket);
-	*pSrcBufLen = GET_OS_PKT_LEN(pPacket);
-}
-
-void RTMP_QueryNextPacketInfo(void **ppPacket,
-			      struct rt_packet_info *pPacketInfo,
-			      u8 **pSrcBufVA, u32 * pSrcBufLen)
-{
-	void *pPacket = NULL;
-
-	if (*ppPacket)
-		pPacket = GET_OS_PKT_NEXT(*ppPacket);
-
-	if (pPacket) {
-		pPacketInfo->BufferCount = 1;
-		pPacketInfo->pFirstBuffer =
-		    (char *)GET_OS_PKT_DATAPTR(pPacket);
-		pPacketInfo->PhysicalBufferCount = 1;
-		pPacketInfo->TotalPacketLength = GET_OS_PKT_LEN(pPacket);
-
-		*pSrcBufVA = GET_OS_PKT_DATAPTR(pPacket);
-		*pSrcBufLen = GET_OS_PKT_LEN(pPacket);
-		*ppPacket = GET_OS_PKT_NEXT(pPacket);
-	} else {
-		pPacketInfo->BufferCount = 0;
-		pPacketInfo->pFirstBuffer = NULL;
-		pPacketInfo->PhysicalBufferCount = 0;
-		pPacketInfo->TotalPacketLength = 0;
-
-		*pSrcBufVA = NULL;
-		*pSrcBufLen = 0;
-		*ppPacket = NULL;
-	}
-}
-
-void *DuplicatePacket(struct rt_rtmp_adapter *pAd,
-			     void *pPacket, u8 FromWhichBSSID)
-{
-	struct sk_buff *skb;
-	void *pRetPacket = NULL;
-	u16 DataSize;
-	u8 *pData;
-
-	DataSize = (u16)GET_OS_PKT_LEN(pPacket);
-	pData = (u8 *)GET_OS_PKT_DATAPTR(pPacket);
-
-	skb = skb_clone(RTPKT_TO_OSPKT(pPacket), MEM_ALLOC_FLAG);
-	if (skb) {
-		skb->dev = get_netdev_from_bssid(pAd, FromWhichBSSID);
-		pRetPacket = OSPKT_TO_RTPKT(skb);
-	}
-
-	return pRetPacket;
-
-}
-
-void *duplicate_pkt(struct rt_rtmp_adapter *pAd,
-			   u8 *pHeader802_3,
-			   u32 HdrLen,
-			   u8 *pData,
-			   unsigned long DataSize, u8 FromWhichBSSID)
-{
-	struct sk_buff *skb;
-	void *pPacket = NULL;
-
-	skb = __dev_alloc_skb(HdrLen + DataSize + 2, MEM_ALLOC_FLAG);
-	if (skb != NULL) {
-		skb_reserve(skb, 2);
-		NdisMoveMemory(skb_tail_pointer(skb), pHeader802_3, HdrLen);
-		skb_put(skb, HdrLen);
-		NdisMoveMemory(skb_tail_pointer(skb), pData, DataSize);
-		skb_put(skb, DataSize);
-		skb->dev = get_netdev_from_bssid(pAd, FromWhichBSSID);
-		pPacket = OSPKT_TO_RTPKT(skb);
-	}
-
-	return pPacket;
-}
-
-#define TKIP_TX_MIC_SIZE		8
-void *duplicate_pkt_with_TKIP_MIC(struct rt_rtmp_adapter *pAd,
-					 void *pPacket)
-{
-	struct sk_buff *skb, *newskb;
-
-	skb = RTPKT_TO_OSPKT(pPacket);
-	if (skb_tailroom(skb) < TKIP_TX_MIC_SIZE) {
-		/* alloc a new skb and copy the packet */
-		newskb =
-		    skb_copy_expand(skb, skb_headroom(skb), TKIP_TX_MIC_SIZE,
-				    GFP_ATOMIC);
-		dev_kfree_skb_any(skb);
-		if (newskb == NULL) {
-			DBGPRINT(RT_DEBUG_ERROR,
-				 ("Extend Tx.MIC for packet failed!, dropping packet!\n"));
-			return NULL;
-		}
-		skb = newskb;
-	}
-
-	return OSPKT_TO_RTPKT(skb);
-}
-
-void *ClonePacket(struct rt_rtmp_adapter *pAd,
-			 void *pPacket,
-			 u8 *pData, unsigned long DataSize)
-{
-	struct sk_buff *pRxPkt;
-	struct sk_buff *pClonedPkt;
-
-	ASSERT(pPacket);
-	pRxPkt = RTPKT_TO_OSPKT(pPacket);
-
-	/* clone the packet */
-	pClonedPkt = skb_clone(pRxPkt, MEM_ALLOC_FLAG);
-
-	if (pClonedPkt) {
-		/* set the correct dataptr and data len */
-		pClonedPkt->dev = pRxPkt->dev;
-		pClonedPkt->data = pData;
-		pClonedPkt->len = DataSize;
-		skb_set_tail_pointer(pClonedPkt, DataSize)
-		ASSERT(DataSize < 1530);
-	}
-	return pClonedPkt;
-}
-
-/* */
-/* change OS packet DataPtr and DataLen */
-/* */
-void update_os_packet_info(struct rt_rtmp_adapter *pAd,
-			   struct rt_rx_blk *pRxBlk, u8 FromWhichBSSID)
-{
-	struct sk_buff *pOSPkt;
-
-	ASSERT(pRxBlk->pRxPacket);
-	pOSPkt = RTPKT_TO_OSPKT(pRxBlk->pRxPacket);
-
-	pOSPkt->dev = get_netdev_from_bssid(pAd, FromWhichBSSID);
-	pOSPkt->data = pRxBlk->pData;
-	pOSPkt->len = pRxBlk->DataSize;
-	skb_set_tail_pointer(pOSPkt, pOSPkt->len);
-}
-
-void wlan_802_11_to_802_3_packet(struct rt_rtmp_adapter *pAd,
-				 struct rt_rx_blk *pRxBlk,
-				 u8 *pHeader802_3,
-				 u8 FromWhichBSSID)
-{
-	struct sk_buff *pOSPkt;
-
-	ASSERT(pRxBlk->pRxPacket);
-	ASSERT(pHeader802_3);
-
-	pOSPkt = RTPKT_TO_OSPKT(pRxBlk->pRxPacket);
-
-	pOSPkt->dev = get_netdev_from_bssid(pAd, FromWhichBSSID);
-	pOSPkt->data = pRxBlk->pData;
-	pOSPkt->len = pRxBlk->DataSize;
-	skb_set_tail_pointer(pOSPkt, pOSPkt->len);
-
-	/* */
-	/* copy 802.3 header */
-	/* */
-	/* */
-
-	NdisMoveMemory(skb_push(pOSPkt, LENGTH_802_3), pHeader802_3,
-		       LENGTH_802_3);
-}
-
-void announce_802_3_packet(struct rt_rtmp_adapter *pAd, void *pPacket)
-{
-
-	struct sk_buff *pRxPkt;
-
-	ASSERT(pPacket);
-
-	pRxPkt = RTPKT_TO_OSPKT(pPacket);
-
-	/* Push up the protocol stack */
-	pRxPkt->protocol = eth_type_trans(pRxPkt, pRxPkt->dev);
-
-	netif_rx(pRxPkt);
-}
-
-struct rt_rtmp_sg_list *
-rt_get_sg_list_from_packet(void *pPacket, struct rt_rtmp_sg_list *sg)
-{
-	sg->NumberOfElements = 1;
-	sg->Elements[0].Address = GET_OS_PKT_DATAPTR(pPacket);
-	sg->Elements[0].Length = GET_OS_PKT_LEN(pPacket);
-	return sg;
-}
-
-void hex_dump(char *str, unsigned char *pSrcBufVA, unsigned int SrcBufLen)
-{
-	unsigned char *pt;
-	int x;
-
-	if (RTDebugLevel < RT_DEBUG_TRACE)
-		return;
-
-	pt = pSrcBufVA;
-	printk(KERN_DEBUG "%s: %p, len = %d\n", str, pSrcBufVA, SrcBufLen);
-	for (x = 0; x < SrcBufLen; x++) {
-		if (x % 16 == 0)
-			printk(KERN_DEBUG "0x%04x : ", x);
-		printk(KERN_DEBUG "%02x ", ((unsigned char)pt[x]));
-		if (x % 16 == 15)
-			printk(KERN_DEBUG "\n");
-	}
-	printk(KERN_DEBUG "\n");
-}
-
-/*
-	========================================================================
-
-	Routine Description:
-		Send log message through wireless event
-
-		Support standard iw_event with IWEVCUSTOM. It is used below.
-
-		iwreq_data.data.flags is used to store event_flag that is defined by user.
-		iwreq_data.data.length is the length of the event log.
-
-		The format of the event log is composed of the entry's MAC address and
-		the desired log message (refer to pWirelessEventText).
-
-			ex: 11:22:33:44:55:66 has associated successfully
-
-		p.s. The requirement of Wireless Extension is v15 or newer.
-
-	========================================================================
-*/
-void RTMPSendWirelessEvent(struct rt_rtmp_adapter *pAd,
-			   u16 Event_flag,
-			   u8 *pAddr, u8 BssIdx, char Rssi)
-{
-
-	/*union         iwreq_data      wrqu; */
-	char *pBuf = NULL, *pBufPtr = NULL;
-	u16 event, type, BufLen;
-	u8 event_table_len = 0;
-
-	type = Event_flag & 0xFF00;
-	event = Event_flag & 0x00FF;
-
-	switch (type) {
-	case IW_SYS_EVENT_FLAG_START:
-		event_table_len = IW_SYS_EVENT_TYPE_NUM;
-		break;
-
-	case IW_SPOOF_EVENT_FLAG_START:
-		event_table_len = IW_SPOOF_EVENT_TYPE_NUM;
-		break;
-
-	case IW_FLOOD_EVENT_FLAG_START:
-		event_table_len = IW_FLOOD_EVENT_TYPE_NUM;
-		break;
-	}
-
-	if (event_table_len == 0) {
-		DBGPRINT(RT_DEBUG_ERROR,
-			 ("%s : The type(%0x02x) is not valid.\n", __func__,
-			  type));
-		return;
-	}
-
-	if (event >= event_table_len) {
-		DBGPRINT(RT_DEBUG_ERROR,
-			 ("%s : The event(%0x02x) is not valid.\n", __func__,
-			  event));
-		return;
-	}
-	/*Allocate memory and copy the msg. */
-	pBuf = kmalloc(IW_CUSTOM_MAX_LEN, GFP_ATOMIC);
-	if (pBuf != NULL) {
-		/*Prepare the payload */
-		memset(pBuf, 0, IW_CUSTOM_MAX_LEN);
-
-		pBufPtr = pBuf;
-
-		if (pAddr)
-			pBufPtr +=
-			    sprintf(pBufPtr, "(RT2860) STA(%pM) ", pAddr);
-		else if (BssIdx < MAX_MBSSID_NUM)
-			pBufPtr +=
-			    sprintf(pBufPtr, "(RT2860) BSS(wlan%d) ", BssIdx);
-		else
-			pBufPtr += sprintf(pBufPtr, "(RT2860) ");
-
-		if (type == IW_SYS_EVENT_FLAG_START)
-			pBufPtr +=
-			    sprintf(pBufPtr, "%s",
-				    pWirelessSysEventText[event]);
-		else if (type == IW_SPOOF_EVENT_FLAG_START)
-			pBufPtr +=
-			    sprintf(pBufPtr, "%s (RSSI=%d)",
-				    pWirelessSpoofEventText[event], Rssi);
-		else if (type == IW_FLOOD_EVENT_FLAG_START)
-			pBufPtr +=
-			    sprintf(pBufPtr, "%s",
-				    pWirelessFloodEventText[event]);
-		else
-			pBufPtr += sprintf(pBufPtr, "%s", "unknown event");
-
-		pBufPtr[pBufPtr - pBuf] = '\0';
-		BufLen = pBufPtr - pBuf;
-
-		RtmpOSWrielessEventSend(pAd, IWEVCUSTOM, Event_flag, NULL,
-					(u8 *)pBuf, BufLen);
-		/*DBGPRINT(RT_DEBUG_TRACE, ("%s : %s\n", __func__, pBuf)); */
-
-		kfree(pBuf);
-	} else
-		DBGPRINT(RT_DEBUG_ERROR,
-			 ("%s : Can't allocate memory for wireless event.\n",
-			  __func__));
-}
-
-void send_monitor_packets(struct rt_rtmp_adapter *pAd, struct rt_rx_blk *pRxBlk)
-{
-	struct sk_buff *pOSPkt;
-	struct rt_wlan_ng_prism2_header *ph;
-	int rate_index = 0;
-	u16 header_len = 0;
-	u8 temp_header[40] = { 0 };
-
-	u_int32_t ralinkrate[256] = { 2, 4, 11, 22, 12, 18, 24, 36, 48, 72, 96, 108, 109, 110, 111, 112, 13, 26, 39, 52, 78, 104, 117, 130, 26, 52, 78, 104, 156, 208, 234, 260, 27, 54, 81, 108, 162, 216, 243, 270,	/* Last 38 */
-		54, 108, 162, 216, 324, 432, 486, 540, 14, 29, 43, 57, 87, 115,
-		    130, 144, 29, 59, 87, 115, 173, 230, 260, 288, 30, 60, 90,
-		    120, 180, 240, 270, 300, 60, 120, 180, 240, 360, 480, 540,
-		    600, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
-		11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26,
-		    27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41,
-		    42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56,
-		    57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71,
-		    72, 73, 74, 75, 76, 77, 78, 79, 80
-	};
-
-	ASSERT(pRxBlk->pRxPacket);
-	if (pRxBlk->DataSize < 10) {
-		DBGPRINT(RT_DEBUG_ERROR,
-			 ("%s : Size is too small! (%d)\n", __func__,
-			  pRxBlk->DataSize));
-		goto err_free_sk_buff;
-	}
-
-	if (pRxBlk->DataSize + sizeof(struct rt_wlan_ng_prism2_header) >
-	    RX_BUFFER_AGGRESIZE) {
-		DBGPRINT(RT_DEBUG_ERROR,
-			 ("%s : Size is too large! (%zu)\n", __func__,
-			  pRxBlk->DataSize + sizeof(struct rt_wlan_ng_prism2_header)));
-		goto err_free_sk_buff;
-	}
-
-	pOSPkt = RTPKT_TO_OSPKT(pRxBlk->pRxPacket);
-	pOSPkt->dev = get_netdev_from_bssid(pAd, BSS0);
-	if (pRxBlk->pHeader->FC.Type == BTYPE_DATA) {
-		pRxBlk->DataSize -= LENGTH_802_11;
-		if ((pRxBlk->pHeader->FC.ToDs == 1) &&
-		    (pRxBlk->pHeader->FC.FrDs == 1))
-			header_len = LENGTH_802_11_WITH_ADDR4;
-		else
-			header_len = LENGTH_802_11;
-
-		/* QOS */
-		if (pRxBlk->pHeader->FC.SubType & 0x08) {
-			header_len += 2;
-			/* Data skip QOS control field */
-			pRxBlk->DataSize -= 2;
-		}
-		/* Order bit: A-Ralink or HTC+ */
-		if (pRxBlk->pHeader->FC.Order) {
-			header_len += 4;
-			/* Data skip HTC control field */
-			pRxBlk->DataSize -= 4;
-		}
-		/* Copy Header */
-		if (header_len <= 40)
-			NdisMoveMemory(temp_header, pRxBlk->pData, header_len);
-
-		/* skip HW padding */
-		if (pRxBlk->RxD.L2PAD)
-			pRxBlk->pData += (header_len + 2);
-		else
-			pRxBlk->pData += header_len;
-	}			/*end if */
-
-	if (pRxBlk->DataSize < pOSPkt->len) {
-		skb_trim(pOSPkt, pRxBlk->DataSize);
-	} else {
-		skb_put(pOSPkt, (pRxBlk->DataSize - pOSPkt->len));
-	}			/*end if */
-
-	if ((pRxBlk->pData - pOSPkt->data) > 0) {
-		skb_put(pOSPkt, (pRxBlk->pData - pOSPkt->data));
-		skb_pull(pOSPkt, (pRxBlk->pData - pOSPkt->data));
-	}			/*end if */
-
-	if (skb_headroom(pOSPkt) < (sizeof(struct rt_wlan_ng_prism2_header) + header_len)) {
-		if (pskb_expand_head
-		    (pOSPkt, (sizeof(struct rt_wlan_ng_prism2_header) + header_len), 0,
-		     GFP_ATOMIC)) {
-			DBGPRINT(RT_DEBUG_ERROR,
-				 ("%s : Reallocate header size of sk_buff fail!\n",
-				  __func__));
-			goto err_free_sk_buff;
-		}		/*end if */
-	}			/*end if */
-
-	if (header_len > 0)
-		NdisMoveMemory(skb_push(pOSPkt, header_len), temp_header,
-			       header_len);
-
-	ph = (struct rt_wlan_ng_prism2_header *)skb_push(pOSPkt,
-						sizeof(struct rt_wlan_ng_prism2_header));
-	NdisZeroMemory(ph, sizeof(struct rt_wlan_ng_prism2_header));
-
-	ph->msgcode = DIDmsg_lnxind_wlansniffrm;
-	ph->msglen = sizeof(struct rt_wlan_ng_prism2_header);
-	strcpy((char *)ph->devname, (char *)pAd->net_dev->name);
-
-	ph->hosttime.did = DIDmsg_lnxind_wlansniffrm_hosttime;
-	ph->hosttime.status = 0;
-	ph->hosttime.len = 4;
-	ph->hosttime.data = jiffies;
-
-	ph->mactime.did = DIDmsg_lnxind_wlansniffrm_mactime;
-	ph->mactime.status = 0;
-	ph->mactime.len = 0;
-	ph->mactime.data = 0;
-
-	ph->istx.did = DIDmsg_lnxind_wlansniffrm_istx;
-	ph->istx.status = 0;
-	ph->istx.len = 0;
-	ph->istx.data = 0;
-
-	ph->channel.did = DIDmsg_lnxind_wlansniffrm_channel;
-	ph->channel.status = 0;
-	ph->channel.len = 4;
-
-	ph->channel.data = (u_int32_t) pAd->CommonCfg.Channel;
-
-	ph->rssi.did = DIDmsg_lnxind_wlansniffrm_rssi;
-	ph->rssi.status = 0;
-	ph->rssi.len = 4;
-	ph->rssi.data =
-	    (u_int32_t) RTMPMaxRssi(pAd,
-				    ConvertToRssi(pAd, pRxBlk->pRxWI->RSSI0,
-						  RSSI_0), ConvertToRssi(pAd,
-									 pRxBlk->
-									 pRxWI->
-									 RSSI1,
-									 RSSI_1),
-				    ConvertToRssi(pAd, pRxBlk->pRxWI->RSSI2,
-						  RSSI_2));
-
-	ph->signal.did = DIDmsg_lnxind_wlansniffrm_signal;
-	ph->signal.status = 0;
-	ph->signal.len = 4;
-	ph->signal.data = 0;	/*rssi + noise; */
-
-	ph->noise.did = DIDmsg_lnxind_wlansniffrm_noise;
-	ph->noise.status = 0;
-	ph->noise.len = 4;
-	ph->noise.data = 0;
-
-	if (pRxBlk->pRxWI->PHYMODE >= MODE_HTMIX) {
-		rate_index =
-		    16 + ((u8)pRxBlk->pRxWI->BW * 16) +
-		    ((u8)pRxBlk->pRxWI->ShortGI * 32) +
-		    ((u8)pRxBlk->pRxWI->MCS);
-	} else if (pRxBlk->pRxWI->PHYMODE == MODE_OFDM)
-		rate_index = (u8)(pRxBlk->pRxWI->MCS) + 4;
-	else
-		rate_index = (u8)(pRxBlk->pRxWI->MCS);
-	if (rate_index < 0)
-		rate_index = 0;
-	if (rate_index > 255)
-		rate_index = 255;
-
-	ph->rate.did = DIDmsg_lnxind_wlansniffrm_rate;
-	ph->rate.status = 0;
-	ph->rate.len = 4;
-	ph->rate.data = ralinkrate[rate_index];
-
-	ph->frmlen.did = DIDmsg_lnxind_wlansniffrm_frmlen;
-	ph->frmlen.status = 0;
-	ph->frmlen.len = 4;
-	ph->frmlen.data = (u_int32_t) pRxBlk->DataSize;
-
-	pOSPkt->pkt_type = PACKET_OTHERHOST;
-	pOSPkt->protocol = eth_type_trans(pOSPkt, pOSPkt->dev);
-	pOSPkt->ip_summed = CHECKSUM_NONE;
-	netif_rx(pOSPkt);
-
-	return;
-
-err_free_sk_buff:
-	RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE);
-	return;
-
-}
-
-/*******************************************************************************
-
-	Device IRQ related functions.
-
- *******************************************************************************/
-int RtmpOSIRQRequest(struct net_device *pNetDev)
-{
-#ifdef RTMP_PCI_SUPPORT
-	struct net_device *net_dev = pNetDev;
-	struct rt_rtmp_adapter *pAd = NULL;
-	int retval = 0;
-
-	GET_PAD_FROM_NET_DEV(pAd, pNetDev);
-
-	ASSERT(pAd);
-
-	if (pAd->infType == RTMP_DEV_INF_PCI) {
-		struct os_cookie *_pObj = (struct os_cookie *)(pAd->OS_Cookie);
-		RTMP_MSI_ENABLE(pAd);
-		retval =
-		    request_irq(_pObj->pci_dev->irq, rt2860_interrupt, SA_SHIRQ,
-				(net_dev)->name, (net_dev));
-		if (retval != 0)
-			printk(KERN_ERR "rt2860: request_irq  ERROR(%d)\n", retval);
-	}
-
-	return retval;
-#else
-	return 0;
-#endif
-}
-
-int RtmpOSIRQRelease(struct net_device *pNetDev)
-{
-	struct net_device *net_dev = pNetDev;
-	struct rt_rtmp_adapter *pAd = NULL;
-
-	GET_PAD_FROM_NET_DEV(pAd, net_dev);
-
-	ASSERT(pAd);
-
-#ifdef RTMP_PCI_SUPPORT
-	if (pAd->infType == RTMP_DEV_INF_PCI) {
-		struct os_cookie *pObj = (struct os_cookie *)(pAd->OS_Cookie);
-		synchronize_irq(pObj->pci_dev->irq);
-		free_irq(pObj->pci_dev->irq, (net_dev));
-		RTMP_MSI_DISABLE(pAd);
-	}
-#endif /* RTMP_PCI_SUPPORT // */
-
-	return 0;
-}
-
-/*******************************************************************************
-
-	File open/close related functions.
-
- *******************************************************************************/
-struct file *RtmpOSFileOpen(char *pPath, int flag, int mode)
-{
-	struct file *filePtr;
-
-	filePtr = filp_open(pPath, flag, 0);
-	if (IS_ERR(filePtr)) {
-		DBGPRINT(RT_DEBUG_ERROR,
-			 ("%s(): Error %ld opening %s\n", __func__,
-			  -PTR_ERR(filePtr), pPath));
-	}
-
-	return (struct file *)filePtr;
-}
-
-int RtmpOSFileClose(struct file *osfd)
-{
-	filp_close(osfd, NULL);
-	return 0;
-}
-
-void RtmpOSFileSeek(struct file *osfd, int offset)
-{
-	osfd->f_pos = offset;
-}
-
-int RtmpOSFileRead(struct file *osfd, char *pDataPtr, int readLen)
-{
-	/* The object must have a read method */
-	if (osfd->f_op && osfd->f_op->read) {
-		return osfd->f_op->read(osfd, pDataPtr, readLen, &osfd->f_pos);
-	} else {
-		DBGPRINT(RT_DEBUG_ERROR, ("no file read method\n"));
-		return -1;
-	}
-}
-
-int RtmpOSFileWrite(struct file *osfd, char *pDataPtr, int writeLen)
-{
-	return osfd->f_op->write(osfd, pDataPtr, (size_t) writeLen,
-				 &osfd->f_pos);
-}
-
-/*******************************************************************************
-
-	Task create/management/kill related functions.
-
- *******************************************************************************/
-int RtmpOSTaskKill(struct rt_rtmp_os_task *pTask)
-{
-	struct rt_rtmp_adapter *pAd;
-	int ret = NDIS_STATUS_FAILURE;
-
-	pAd = pTask->priv;
-
-#ifdef KTHREAD_SUPPORT
-	if (pTask->kthread_task) {
-		kthread_stop(pTask->kthread_task);
-		ret = NDIS_STATUS_SUCCESS;
-	}
-#else
-	CHECK_PID_LEGALITY(pTask->taskPID) {
-		printk(KERN_INFO "Terminate the task(%s) with pid(%d)!\n",
-		       pTask->taskName, GET_PID_NUMBER(pTask->taskPID));
-		mb();
-		pTask->task_killed = 1;
-		mb();
-		ret = KILL_THREAD_PID(pTask->taskPID, SIGTERM, 1);
-		if (ret) {
-			printk(KERN_WARNING
-			       "kill task(%s) with pid(%d) failed(retVal=%d)!\n",
-			       pTask->taskName, GET_PID_NUMBER(pTask->taskPID),
-			       ret);
-		} else {
-			wait_for_completion(&pTask->taskComplete);
-			pTask->taskPID = THREAD_PID_INIT_VALUE;
-			pTask->task_killed = 0;
-			ret = NDIS_STATUS_SUCCESS;
-		}
-	}
-#endif
-
-	return ret;
-
-}
-
-int RtmpOSTaskNotifyToExit(struct rt_rtmp_os_task *pTask)
-{
-
-#ifndef KTHREAD_SUPPORT
-	complete_and_exit(&pTask->taskComplete, 0);
-#endif
-
-	return 0;
-}
-
-void RtmpOSTaskCustomize(struct rt_rtmp_os_task *pTask)
-{
-
-#ifndef KTHREAD_SUPPORT
-
-	daemonize((char *)&pTask->taskName[0] /*"%s",pAd->net_dev->name */);
-
-	allow_signal(SIGTERM);
-	allow_signal(SIGKILL);
-	current->flags |= PF_NOFREEZE;
-
-	/* signal that we've started the thread */
-	complete(&pTask->taskComplete);
-
-#endif
-}
-
-int RtmpOSTaskAttach(struct rt_rtmp_os_task *pTask,
-			     IN int (*fn) (void *), IN void *arg)
-{
-	int status = NDIS_STATUS_SUCCESS;
-
-#ifdef KTHREAD_SUPPORT
-	pTask->task_killed = 0;
-	pTask->kthread_task = NULL;
-	pTask->kthread_task = kthread_run(fn, arg, pTask->taskName);
-	if (IS_ERR(pTask->kthread_task))
-		status = NDIS_STATUS_FAILURE;
-#else
-	pid_number = kernel_thread(fn, arg, RTMP_OS_MGMT_TASK_FLAGS);
-	if (pid_number < 0) {
-		DBGPRINT(RT_DEBUG_ERROR,
-			 ("Attach task(%s) failed!\n", pTask->taskName));
-		status = NDIS_STATUS_FAILURE;
-	} else {
-		pTask->taskPID = GET_PID(pid_number);
-
-		/* Wait for the thread to start */
-		wait_for_completion(&pTask->taskComplete);
-		status = NDIS_STATUS_SUCCESS;
-	}
-#endif
-	return status;
-}
-
-int RtmpOSTaskInit(struct rt_rtmp_os_task *pTask,
-			   char *pTaskName, void * pPriv)
-{
-	int len;
-
-	ASSERT(pTask);
-
-#ifndef KTHREAD_SUPPORT
-	NdisZeroMemory((u8 *)(pTask), sizeof(struct rt_rtmp_os_task));
-#endif
-
-	len = strlen(pTaskName);
-	len =
-	    len >
-	    (RTMP_OS_TASK_NAME_LEN - 1) ? (RTMP_OS_TASK_NAME_LEN - 1) : len;
-	NdisMoveMemory(&pTask->taskName[0], pTaskName, len);
-	pTask->priv = pPriv;
-
-#ifndef KTHREAD_SUPPORT
-	RTMP_SEM_EVENT_INIT_LOCKED(&(pTask->taskSema));
-	pTask->taskPID = THREAD_PID_INIT_VALUE;
-
-	init_completion(&pTask->taskComplete);
-#endif
-
-	return NDIS_STATUS_SUCCESS;
-}
-
-void RTMP_IndicateMediaState(struct rt_rtmp_adapter *pAd)
-{
-	if (pAd->CommonCfg.bWirelessEvent) {
-		if (pAd->IndicateMediaState == NdisMediaStateConnected) {
-			RTMPSendWirelessEvent(pAd, IW_STA_LINKUP_EVENT_FLAG,
-					      pAd->MacTab.Content[BSSID_WCID].
-					      Addr, BSS0, 0);
-		} else {
-			RTMPSendWirelessEvent(pAd, IW_STA_LINKDOWN_EVENT_FLAG,
-					      pAd->MacTab.Content[BSSID_WCID].
-					      Addr, BSS0, 0);
-		}
-	}
-}
-
-int RtmpOSWrielessEventSend(struct rt_rtmp_adapter *pAd,
-			    u32 eventType,
-			    int flags,
-			    u8 *pSrcMac,
-			    u8 *pData, u32 dataLen)
-{
-	union iwreq_data wrqu;
-
-	memset(&wrqu, 0, sizeof(wrqu));
-
-	if (flags > -1)
-		wrqu.data.flags = flags;
-
-	if (pSrcMac)
-		memcpy(wrqu.ap_addr.sa_data, pSrcMac, MAC_ADDR_LEN);
-
-	if ((pData != NULL) && (dataLen > 0))
-		wrqu.data.length = dataLen;
-
-	wireless_send_event(pAd->net_dev, eventType, &wrqu, (char *)pData);
-	return 0;
-}
-
-int RtmpOSNetDevAddrSet(struct net_device *pNetDev, u8 *pMacAddr)
-{
-	struct net_device *net_dev;
-	struct rt_rtmp_adapter *pAd;
-
-	net_dev = pNetDev;
-	GET_PAD_FROM_NET_DEV(pAd, net_dev);
-
-	/* work-around for SuSE, due to them having their own interface name management system. */
-	{
-		NdisZeroMemory(pAd->StaCfg.dev_name, 16);
-		NdisMoveMemory(pAd->StaCfg.dev_name, net_dev->name,
-			       strlen(net_dev->name));
-	}
-
-	NdisMoveMemory(net_dev->dev_addr, pMacAddr, 6);
-
-	return 0;
-}
-
-/*
-  *	Assign the network dev name for created Ralink WiFi interface.
-  */
-static int RtmpOSNetDevRequestName(struct rt_rtmp_adapter *pAd,
-				   struct net_device *dev,
-				   char *pPrefixStr, int devIdx)
-{
-	struct net_device *existNetDev;
-	char suffixName[IFNAMSIZ];
-	char desiredName[IFNAMSIZ];
-	int ifNameIdx, prefixLen, slotNameLen;
-	int Status;
-
-	prefixLen = strlen(pPrefixStr);
-	ASSERT((prefixLen < IFNAMSIZ));
-
-	for (ifNameIdx = devIdx; ifNameIdx < 32; ifNameIdx++) {
-		memset(suffixName, 0, IFNAMSIZ);
-		memset(desiredName, 0, IFNAMSIZ);
-		strncpy(&desiredName[0], pPrefixStr, prefixLen);
-
-		sprintf(suffixName, "%d", ifNameIdx);
-
-		slotNameLen = strlen(suffixName);
-		ASSERT(((slotNameLen + prefixLen) < IFNAMSIZ));
-		strcat(desiredName, suffixName);
-
-		existNetDev = RtmpOSNetDevGetByName(dev, &desiredName[0]);
-		if (existNetDev == NULL)
-			break;
-		else
-			RtmpOSNetDeviceRefPut(existNetDev);
-	}
-
-	if (ifNameIdx < 32) {
-		strcpy(&dev->name[0], &desiredName[0]);
-		Status = NDIS_STATUS_SUCCESS;
-	} else {
-		DBGPRINT(RT_DEBUG_ERROR,
-			 ("Cannot request DevName with preifx(%s) and in range(0~32) as suffix from OS!\n",
-			  pPrefixStr));
-		Status = NDIS_STATUS_FAILURE;
-	}
-
-	return Status;
-}
-
-void RtmpOSNetDevClose(struct net_device *pNetDev)
-{
-	dev_close(pNetDev);
-}
-
-void RtmpOSNetDevFree(struct net_device *pNetDev)
-{
-	ASSERT(pNetDev);
-
-	free_netdev(pNetDev);
-}
-
-int RtmpOSNetDevAlloc(struct net_device **new_dev_p, u32 privDataSize)
-{
-	/* assign it as null first. */
-	*new_dev_p = NULL;
-
-	DBGPRINT(RT_DEBUG_TRACE,
-		 ("Allocate a net device with private data size=%d!\n",
-		  privDataSize));
-	*new_dev_p = alloc_etherdev(privDataSize);
-	if (*new_dev_p)
-		return NDIS_STATUS_SUCCESS;
-	else
-		return NDIS_STATUS_FAILURE;
-}
-
-struct net_device *RtmpOSNetDevGetByName(struct net_device *pNetDev, char *pDevName)
-{
-	struct net_device *pTargetNetDev = NULL;
-
-	pTargetNetDev = dev_get_by_name(dev_net(pNetDev), pDevName);
-
-	return pTargetNetDev;
-}
-
-void RtmpOSNetDeviceRefPut(struct net_device *pNetDev)
-{
-	/*
-	   every time dev_get_by_name is called, and it has returned a valid struct
-	   net_device*, dev_put should be called afterwards, because otherwise the
-	   machine hangs when the device is unregistered (since dev->refcnt > 1).
-	 */
-	if (pNetDev)
-		dev_put(pNetDev);
-}
-
-int RtmpOSNetDevDestory(struct rt_rtmp_adapter *pAd, struct net_device *pNetDev)
-{
-
-	/* TODO: Need to fix this */
-	printk("WARNING: This function(%s) not implement yet!\n", __func__);
-	return 0;
-}
-
-void RtmpOSNetDevDetach(struct net_device *pNetDev)
-{
-	unregister_netdev(pNetDev);
-}
-
-int RtmpOSNetDevAttach(struct net_device *pNetDev,
-		       struct rt_rtmp_os_netdev_op_hook *pDevOpHook)
-{
-	int ret, rtnl_locked = FALSE;
-
-	DBGPRINT(RT_DEBUG_TRACE, ("RtmpOSNetDevAttach()--->\n"));
-	/* If we need hook some callback function to the net device structure, now do it. */
-	if (pDevOpHook) {
-		struct rt_rtmp_adapter *pAd = NULL;
-
-		GET_PAD_FROM_NET_DEV(pAd, pNetDev);
-
-		pNetDev->netdev_ops = pDevOpHook->netdev_ops;
-
-		/* OS specific flags, here we used to indicate if we are virtual interface */
-		pNetDev->priv_flags = pDevOpHook->priv_flags;
-
-		if (pAd->OpMode == OPMODE_STA)
-			pNetDev->wireless_handlers = &rt28xx_iw_handler_def;
-
-		/* copy the net device mac address to the net_device structure. */
-		NdisMoveMemory(pNetDev->dev_addr, &pDevOpHook->devAddr[0],
-			       MAC_ADDR_LEN);
-
-		rtnl_locked = pDevOpHook->needProtcted;
-	}
-
-	if (rtnl_locked)
-		ret = register_netdevice(pNetDev);
-	else
-		ret = register_netdev(pNetDev);
-
-	DBGPRINT(RT_DEBUG_TRACE, ("<---RtmpOSNetDevAttach(), ret=%d\n", ret));
-	if (ret == 0)
-		return NDIS_STATUS_SUCCESS;
-	else
-		return NDIS_STATUS_FAILURE;
-}
-
-struct net_device *RtmpOSNetDevCreate(struct rt_rtmp_adapter *pAd,
-			    int devType,
-			    int devNum,
-			    int privMemSize, char *pNamePrefix)
-{
-	struct net_device *pNetDev = NULL;
-	int status;
-
-	/* allocate a new network device */
-	status = RtmpOSNetDevAlloc(&pNetDev, 0 /*privMemSize */);
-	if (status != NDIS_STATUS_SUCCESS) {
-		/* allocation fail, exit */
-		DBGPRINT(RT_DEBUG_ERROR,
-			 ("Allocate network device fail (%s)...\n",
-			  pNamePrefix));
-		return NULL;
-	}
-
-	/* find an available interface name, max 32 interfaces */
-	status = RtmpOSNetDevRequestName(pAd, pNetDev, pNamePrefix, devNum);
-	if (status != NDIS_STATUS_SUCCESS) {
-		/* error! no available ra name can be used! */
-		DBGPRINT(RT_DEBUG_ERROR,
-			 ("Assign interface name (%s with suffix 0~32) failed...\n",
-			  pNamePrefix));
-		RtmpOSNetDevFree(pNetDev);
-
-		return NULL;
-	} else {
-		DBGPRINT(RT_DEBUG_TRACE,
-			 ("The name of the new %s interface is %s...\n",
-			  pNamePrefix, pNetDev->name));
-	}
-
-	return pNetDev;
-}
diff -druN linux-2.6.39-libre/drivers/staging/rt2860/rt_linux.h linux-3.0-rc7-libre/drivers/staging/rt2860/rt_linux.h
--- linux-2.6.39-libre/drivers/staging/rt2860/rt_linux.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rt2860/rt_linux.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,835 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, 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.             *
- *                                                                       *
- *************************************************************************
-
-    Module Name:
-	rt_linux.h
-
-    Abstract:
-
-    Revision History:
-    Who          	When         	What
-    Justin P. Mattock	11/07/2010 	Fix typo in a comment
-    ---------    ----------    ----------------------------------------------
-*/
-
-#ifndef __RT_LINUX_H__
-#define __RT_LINUX_H__
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/spinlock.h>
-#include <linux/init.h>
-#include <linux/string.h>
-#include <linux/timer.h>
-#include <linux/errno.h>
-#include <linux/slab.h>
-#include <linux/interrupt.h>
-#include <linux/pci.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/skbuff.h>
-#include <linux/ethtool.h>
-#include <linux/wireless.h>
-#include <linux/proc_fs.h>
-#include <linux/delay.h>
-#include <linux/if_arp.h>
-#include <linux/ctype.h>
-#include <linux/vmalloc.h>
-
-#include <net/iw_handler.h>
-
-/* load firmware */
-#define __KERNEL_SYSCALLS__
-#include <linux/unistd.h>
-#include <asm/uaccess.h>
-#include <asm/types.h>
-#include <asm/unaligned.h>	/* for get_unaligned() */
-
-#define KTHREAD_SUPPORT 1
-/* RT2870 2.1.0.0 has it disabled */
-
-#ifdef KTHREAD_SUPPORT
-#include <linux/err.h>
-#include <linux/kthread.h>
-#endif /* KTHREAD_SUPPORT // */
-
-/***********************************************************************************
- *	Profile related sections
- ***********************************************************************************/
-
-#ifdef RTMP_MAC_PCI
-#define STA_DRIVER_VERSION			"2.1.0.0"
-#endif /* RTMP_MAC_PCI // */
-#ifdef RTMP_MAC_USB
-#define STA_DRIVER_VERSION			"2.1.0.0"
-/* RT3070 version: 2.1.1.0 */
-#endif /* RTMP_MAC_USB // */
-
-extern const struct iw_handler_def rt28xx_iw_handler_def;
-
-/***********************************************************************************
- *	Compiler related definitions
- ***********************************************************************************/
-#undef __inline
-#define __inline	   static inline
-#define IN
-#define OUT
-#define INOUT
-
-/***********************************************************************************
- *	OS Specific definitions and data structures
- ***********************************************************************************/
-typedef int (*HARD_START_XMIT_FUNC) (struct sk_buff *skb,
-				     struct net_device *net_dev);
-
-#ifdef RTMP_MAC_PCI
-#ifndef PCI_DEVICE
-#define PCI_DEVICE(vend,dev) \
-	.vendor = (vend), .device = (dev), \
-	.subvendor = PCI_ANY_ID, .subdevice = PCI_ANY_ID
-#endif /* PCI_DEVICE // */
-#endif /* RTMP_MAC_PCI // */
-
-#define RT_MOD_INC_USE_COUNT() \
-	if (!try_module_get(THIS_MODULE)) \
-	{ \
-		DBGPRINT(RT_DEBUG_ERROR, ("%s: cannot reserve module\n", __func__)); \
-		return -1; \
-	}
-
-#define RT_MOD_DEC_USE_COUNT() module_put(THIS_MODULE);
-
-#define RTMP_INC_REF(_A)		0
-#define RTMP_DEC_REF(_A)		0
-#define RTMP_GET_REF(_A)		0
-
-/* This function will be called when query /proc */
-struct iw_statistics *rt28xx_get_wireless_stats(IN struct net_device *net_dev);
-
-/***********************************************************************************
- *	Network related constant definitions
- ***********************************************************************************/
-#ifndef IFNAMSIZ
-#define IFNAMSIZ 16
-#endif
-
-#define ETH_LENGTH_OF_ADDRESS	6
-
-#define NDIS_STATUS_SUCCESS                     0x00
-#define NDIS_STATUS_FAILURE                     0x01
-#define NDIS_STATUS_INVALID_DATA				0x02
-#define NDIS_STATUS_RESOURCES                   0x03
-
-#define NDIS_SET_PACKET_STATUS(_p, _status)			do{} while(0)
-#define NdisWriteErrorLogEntry(_a, _b, _c, _d)		do{} while(0)
-
-/* statistics counter */
-#define STATS_INC_RX_PACKETS(_pAd, _dev)
-#define STATS_INC_TX_PACKETS(_pAd, _dev)
-
-#define STATS_INC_RX_BYTESS(_pAd, _dev, len)
-#define STATS_INC_TX_BYTESS(_pAd, _dev, len)
-
-#define STATS_INC_RX_ERRORS(_pAd, _dev)
-#define STATS_INC_TX_ERRORS(_pAd, _dev)
-
-#define STATS_INC_RX_DROPPED(_pAd, _dev)
-#define STATS_INC_TX_DROPPED(_pAd, _dev)
-
-/***********************************************************************************
- *	Ralink Specific network related constant definitions
- ***********************************************************************************/
-#define MIN_NET_DEVICE_FOR_AID			0x00	/*0x00~0x3f */
-#define MIN_NET_DEVICE_FOR_MBSSID		0x00	/*0x00,0x10,0x20,0x30 */
-#define MIN_NET_DEVICE_FOR_WDS			0x10	/*0x40,0x50,0x60,0x70 */
-#define MIN_NET_DEVICE_FOR_APCLI		0x20
-#define MIN_NET_DEVICE_FOR_MESH			0x30
-#define MIN_NET_DEVICE_FOR_DLS			0x40
-#define NET_DEVICE_REAL_IDX_MASK		0x0f	/* for each operation mode, we maximum support 15 entities. */
-
-#define NDIS_PACKET_TYPE_DIRECTED		0
-#define NDIS_PACKET_TYPE_MULTICAST		1
-#define NDIS_PACKET_TYPE_BROADCAST		2
-#define NDIS_PACKET_TYPE_ALL_MULTICAST	3
-#define NDIS_PACKET_TYPE_PROMISCUOUS	4
-
-/***********************************************************************************
- *	OS signaling related constant definitions
- ***********************************************************************************/
-
-/***********************************************************************************
- *	OS file operation related data structure definitions
- ***********************************************************************************/
-struct rt_rtmp_os_fs_info {
-	int fsuid;
-	int fsgid;
-	mm_segment_t fs;
-};
-
-#define IS_FILE_OPEN_ERR(_fd)	IS_ERR((_fd))
-
-/***********************************************************************************
- *	OS semaphore related data structure and definitions
- ***********************************************************************************/
-struct os_lock {
-	spinlock_t lock;
-	unsigned long flags;
-};
-
-/* */
-/*  spin_lock enhanced for Nested spin lock */
-/* */
-#define NdisAllocateSpinLock(__lock)      \
-{                                       \
-    spin_lock_init((spinlock_t *)(__lock));               \
-}
-
-#define NdisFreeSpinLock(lock)          \
-	do{}while(0)
-
-#define RTMP_SEM_LOCK(__lock)					\
-{												\
-	spin_lock_bh((spinlock_t *)(__lock));		\
-}
-
-#define RTMP_SEM_UNLOCK(__lock)					\
-{												\
-	spin_unlock_bh((spinlock_t *)(__lock));		\
-}
-
-/* sample, use semaphore lock to replace IRQ lock, 2007/11/15 */
-#define RTMP_IRQ_LOCK(__lock, __irqflags)			\
-{													\
-	__irqflags = 0;									\
-	spin_lock_bh((spinlock_t *)(__lock));			\
-	pAd->irq_disabled |= 1; \
-}
-
-#define RTMP_IRQ_UNLOCK(__lock, __irqflag)			\
-{													\
-	pAd->irq_disabled &= 0;							\
-	spin_unlock_bh((spinlock_t *)(__lock));			\
-}
-
-#define RTMP_INT_LOCK(__lock, __irqflags)			\
-{													\
-	spin_lock_irqsave((spinlock_t *)__lock, __irqflags);	\
-}
-
-#define RTMP_INT_UNLOCK(__lock, __irqflag)			\
-{													\
-	spin_unlock_irqrestore((spinlock_t *)(__lock), ((unsigned long)__irqflag));	\
-}
-
-#define NdisAcquireSpinLock		RTMP_SEM_LOCK
-#define NdisReleaseSpinLock		RTMP_SEM_UNLOCK
-
-#ifndef wait_event_interruptible_timeout
-#define __wait_event_interruptible_timeout(wq, condition, ret) \
-do { \
-        wait_queue_t __wait; \
-        init_waitqueue_entry(&__wait, current); \
-        add_wait_queue(&wq, &__wait); \
-        for (;;) { \
-                set_current_state(TASK_INTERRUPTIBLE); \
-                if (condition) \
-                        break; \
-                if (!signal_pending(current)) { \
-                        ret = schedule_timeout(ret); \
-                        if (!ret) \
-                                break; \
-                        continue; \
-                } \
-                ret = -ERESTARTSYS; \
-                break; \
-        } \
-        current->state = TASK_RUNNING; \
-        remove_wait_queue(&wq, &__wait); \
-} while (0)
-
-#define wait_event_interruptible_timeout(wq, condition, timeout) \
-({ \
-        long __ret = timeout; \
-        if (!(condition)) \
-                __wait_event_interruptible_timeout(wq, condition, __ret); \
-        __ret; \
-})
-#endif
-
-#define RTMP_SEM_EVENT_INIT_LOCKED(_pSema)	sema_init((_pSema), 0)
-#define RTMP_SEM_EVENT_INIT(_pSema)			sema_init((_pSema), 1)
-#define RTMP_SEM_EVENT_WAIT(_pSema, _status)	((_status) = down_interruptible((_pSema)))
-#define RTMP_SEM_EVENT_UP(_pSema)			up(_pSema)
-
-#ifdef KTHREAD_SUPPORT
-#define RTMP_WAIT_EVENT_INTERRUPTIBLE(_pAd, _pTask) \
-{ \
-		wait_event_interruptible(_pTask->kthread_q, \
-								 _pTask->kthread_running || kthread_should_stop()); \
-		_pTask->kthread_running = FALSE; \
-		if (kthread_should_stop()) \
-		{ \
-			RTMP_SET_FLAG(_pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS); \
-			break; \
-		} \
-}
-#endif
-
-#ifdef KTHREAD_SUPPORT
-#define WAKE_UP(_pTask) \
-	do{ \
-		if ((_pTask)->kthread_task) \
-        { \
-			(_pTask)->kthread_running = TRUE; \
-	        wake_up(&(_pTask)->kthread_q); \
-		} \
-	}while(0)
-#endif
-
-/***********************************************************************************
- *	OS Memory Access related data structure and definitions
- ***********************************************************************************/
-#define MEM_ALLOC_FLAG      (GFP_ATOMIC)	/*(GFP_DMA | GFP_ATOMIC) */
-
-#define NdisMoveMemory(Destination, Source, Length) memmove(Destination, Source, Length)
-#define NdisCopyMemory(Destination, Source, Length) memcpy(Destination, Source, Length)
-#define NdisZeroMemory(Destination, Length)         memset(Destination, 0, Length)
-#define NdisFillMemory(Destination, Length, Fill)   memset(Destination, Fill, Length)
-#define NdisCmpMemory(Destination, Source, Length)  memcmp(Destination, Source, Length)
-#define NdisEqualMemory(Source1, Source2, Length)   (!memcmp(Source1, Source2, Length))
-#define RTMPEqualMemory(Source1, Source2, Length)	(!memcmp(Source1, Source2, Length))
-
-#define MlmeAllocateMemory(_pAd, _ppVA)		os_alloc_mem(_pAd, _ppVA, MGMT_DMA_BUFFER_SIZE)
-#define MlmeFreeMemory(_pAd, _pVA)			os_free_mem(_pAd, _pVA)
-
-#define COPY_MAC_ADDR(Addr1, Addr2)             memcpy((Addr1), (Addr2), MAC_ADDR_LEN)
-
-/***********************************************************************************
- *	OS task related data structure and definitions
- ***********************************************************************************/
-#define RTMP_OS_MGMT_TASK_FLAGS	CLONE_VM
-
-#define	THREAD_PID_INIT_VALUE	NULL
-#define	GET_PID(_v)	find_get_pid((_v))
-#define	GET_PID_NUMBER(_v)	pid_nr((_v))
-#define CHECK_PID_LEGALITY(_pid)	if (pid_nr((_pid)) > 0)
-#define KILL_THREAD_PID(_A, _B, _C)	kill_pid((_A), (_B), (_C))
-
-/***********************************************************************************
- * Timer related definitions and data structures.
- **********************************************************************************/
-#define OS_HZ			HZ
-
-typedef void (*TIMER_FUNCTION) (unsigned long);
-
-#define OS_WAIT(_time) \
-{	int _i; \
-	long _loop = ((_time)/(1000/OS_HZ)) > 0 ? ((_time)/(1000/OS_HZ)) : 1;\
-	wait_queue_head_t _wait; \
-	init_waitqueue_head(&_wait); \
-	for (_i=0; _i<(_loop); _i++) \
-		wait_event_interruptible_timeout(_wait, 0, ONE_TICK); }
-
-#define RTMP_TIME_AFTER(a,b)		\
-	(typecheck(unsigned long, (unsigned long)a) && \
-	 typecheck(unsigned long, (unsigned long)b) && \
-	 ((long)(b) - (long)(a) < 0))
-
-#define RTMP_TIME_AFTER_EQ(a,b)	\
-	(typecheck(unsigned long, (unsigned long)a) && \
-	 typecheck(unsigned long, (unsigned long)b) && \
-	 ((long)(a) - (long)(b) >= 0))
-#define RTMP_TIME_BEFORE(a,b)	RTMP_TIME_AFTER_EQ(b,a)
-
-#define ONE_TICK 1
-
-static inline void NdisGetSystemUpTime(unsigned long *time)
-{
-	*time = jiffies;
-}
-
-/***********************************************************************************
- *	OS specific cookie data structure binding to struct rt_rtmp_adapter
- ***********************************************************************************/
-
-struct os_cookie {
-#ifdef RTMP_MAC_PCI
-	struct pci_dev *pci_dev;
-	struct pci_dev *parent_pci_dev;
-	u16 DeviceID;
-	dma_addr_t pAd_pa;
-#endif				/* RTMP_MAC_PCI // */
-#ifdef RTMP_MAC_USB
-	struct usb_device *pUsb_Dev;
-#endif				/* RTMP_MAC_USB // */
-
-	struct tasklet_struct rx_done_task;
-	struct tasklet_struct mgmt_dma_done_task;
-	struct tasklet_struct ac0_dma_done_task;
-	struct tasklet_struct ac1_dma_done_task;
-	struct tasklet_struct ac2_dma_done_task;
-	struct tasklet_struct ac3_dma_done_task;
-	struct tasklet_struct tbtt_task;
-#ifdef RTMP_MAC_PCI
-	struct tasklet_struct fifo_statistic_full_task;
-#endif				/* RTMP_MAC_PCI // */
-#ifdef RTMP_MAC_USB
-	struct tasklet_struct null_frame_complete_task;
-	struct tasklet_struct rts_frame_complete_task;
-	struct tasklet_struct pspoll_frame_complete_task;
-#endif				/* RTMP_MAC_USB // */
-
-	unsigned long apd_pid;	/*802.1x daemon pid */
-	int ioctl_if_type;
-	int ioctl_if;
-};
-
-/***********************************************************************************
- *	OS debugging and printing related definitions and data structure
- ***********************************************************************************/
-#ifdef DBG
-extern unsigned long RTDebugLevel;
-
-#define DBGPRINT_RAW(Level, Fmt)    \
-do{                                   \
-    if (Level <= RTDebugLevel)      \
-    {                               \
-        printk Fmt;               \
-    }                               \
-}while(0)
-
-#define DBGPRINT(Level, Fmt)    DBGPRINT_RAW(Level, Fmt)
-
-#define DBGPRINT_ERR(fmt, args...) printk(KERN_ERR fmt, ##args)
-
-#define DBGPRINT_S(Status, Fmt)		\
-{									\
-	printk Fmt;					\
-}
-
-#else
-#define DBGPRINT(Level, Fmt)
-#define DBGPRINT_RAW(Level, Fmt)
-#define DBGPRINT_S(Status, Fmt)
-#define DBGPRINT_ERR(Fmt)
-#endif
-
-#define ASSERT(x)
-
-void hex_dump(char *str, unsigned char *pSrcBufVA, unsigned int SrcBufLen);
-
-/*********************************************************************************************************
-	The following code are not revised, temporary put it here.
-  *********************************************************************************************************/
-
-/***********************************************************************************
- * Device DMA Access related definitions and data structures.
- **********************************************************************************/
-#ifdef RTMP_MAC_PCI
-struct rt_rtmp_adapter;
-dma_addr_t linux_pci_map_single(struct rt_rtmp_adapter *pAd, void *ptr,
-				size_t size, int sd_idx, int direction);
-void linux_pci_unmap_single(struct rt_rtmp_adapter *pAd, dma_addr_t dma_addr,
-			    size_t size, int direction);
-
-#define PCI_MAP_SINGLE(_handle, _ptr, _size, _sd_idx, _dir) \
-	linux_pci_map_single(_handle, _ptr, _size, _sd_idx, _dir)
-
-#define PCI_UNMAP_SINGLE(_handle, _ptr, _size, _dir) \
-	linux_pci_unmap_single(_handle, _ptr, _size, _dir)
-
-#define PCI_ALLOC_CONSISTENT(_pci_dev, _size, _ptr) \
-	pci_alloc_consistent(_pci_dev, _size, _ptr)
-
-#define PCI_FREE_CONSISTENT(_pci_dev, _size, _virtual_addr, _physical_addr) \
-	pci_free_consistent(_pci_dev, _size, _virtual_addr, _physical_addr)
-
-#define DEV_ALLOC_SKB(_length) \
-	dev_alloc_skb(_length)
-#endif /* RTMP_MAC_PCI // */
-
-/*
- * unsigned long
- * RTMP_GetPhysicalAddressLow(
- *   dma_addr_t  PhysicalAddress);
- */
-#define RTMP_GetPhysicalAddressLow(PhysicalAddress)		(PhysicalAddress)
-
-/*
- * unsigned long
- * RTMP_GetPhysicalAddressHigh(
- *   dma_addr_t  PhysicalAddress);
- */
-#define RTMP_GetPhysicalAddressHigh(PhysicalAddress)		(0)
-
-/*
- * void
- * RTMP_SetPhysicalAddressLow(
- *   dma_addr_t  PhysicalAddress,
- *   unsigned long  Value);
- */
-#define RTMP_SetPhysicalAddressLow(PhysicalAddress, Value)	\
-			PhysicalAddress = Value;
-
-/*
- * void
- * RTMP_SetPhysicalAddressHigh(
- *   dma_addr_t  PhysicalAddress,
- *   unsigned long  Value);
- */
-#define RTMP_SetPhysicalAddressHigh(PhysicalAddress, Value)
-
-#define NdisMIndicateStatus(_w, _x, _y, _z)
-
-/***********************************************************************************
- * Device Register I/O Access related definitions and data structures.
- **********************************************************************************/
-#ifdef RTMP_MAC_PCI
-/*Patch for ASIC turst read/write bug, needs to remove after metel fix */
-#define RTMP_IO_READ32(_A, _R, _pV)								\
-{																\
-    if ((_A)->bPCIclkOff == FALSE)                                  \
-    {                                                               \
-		(*_pV = readl((void *)((_A)->CSRBaseAddress + MAC_CSR0)));		\
-		(*_pV = readl((void *)((_A)->CSRBaseAddress + (_R))));			\
-    }                                                               \
-    else															\
-		*_pV = 0;													\
-}
-
-#define RTMP_IO_FORCE_READ32(_A, _R, _pV)							\
-{																	\
-	(*_pV = readl((void *)((_A)->CSRBaseAddress + MAC_CSR0)));		\
-	(*_pV = readl((void *)((_A)->CSRBaseAddress + (_R))));			\
-}
-
-#define RTMP_IO_READ8(_A, _R, _pV)								\
-{																\
-	(*_pV = readl((void *)((_A)->CSRBaseAddress + MAC_CSR0)));			\
-	(*_pV = readb((void *)((_A)->CSRBaseAddress + (_R))));				\
-}
-#define RTMP_IO_WRITE32(_A, _R, _V)												\
-{																				\
-    if ((_A)->bPCIclkOff == FALSE)                                  \
-    {                                                               \
-	u32 Val;																\
-	Val = readl((void *)((_A)->CSRBaseAddress + MAC_CSR0));			\
-	writel((_V), (void *)((_A)->CSRBaseAddress + (_R)));								\
-    }                                                               \
-}
-
-#define RTMP_IO_FORCE_WRITE32(_A, _R, _V)												\
-{																				\
-	u32 Val;																\
-	Val = readl((void *)((_A)->CSRBaseAddress + MAC_CSR0));			\
-	writel(_V, (void *)((_A)->CSRBaseAddress + (_R)));								\
-}
-
-#if defined(RALINK_2880) || defined(RALINK_3052)
-#define RTMP_IO_WRITE8(_A, _R, _V)            \
-{                    \
-	unsigned long Val;                \
-	u8 _i;                \
-	_i = ((_R) & 0x3);             \
-	Val = readl((void *)((_A)->CSRBaseAddress + ((_R) - _i)));   \
-	Val = Val & (~(0x000000ff << ((_i)*8)));         \
-	Val = Val | ((unsigned long)(_V) << ((_i)*8));         \
-	writel((Val), (void *)((_A)->CSRBaseAddress + ((_R) - _i)));    \
-}
-#else
-#define RTMP_IO_WRITE8(_A, _R, _V)												\
-{																				\
-	u32 Val;																\
-	Val = readl((void *)((_A)->CSRBaseAddress + MAC_CSR0));			\
-	writeb((_V), (u8 *)((_A)->CSRBaseAddress + (_R)));		\
-}
-#endif /* #if defined(BRCM_6358) || defined(RALINK_2880) // */
-
-#define RTMP_IO_WRITE16(_A, _R, _V)												\
-{																				\
-	u32 Val;																\
-	Val = readl((void *)((_A)->CSRBaseAddress + MAC_CSR0));			\
-	writew((_V), (u16 *)((_A)->CSRBaseAddress + (_R)));	\
-}
-#endif /* RTMP_MAC_PCI // */
-#ifdef RTMP_MAC_USB
-/*Patch for ASIC turst read/write bug, needs to remove after metel fix */
-#define RTMP_IO_READ32(_A, _R, _pV)								\
-	RTUSBReadMACRegister((_A), (_R), (u32 *)(_pV))
-
-#define RTMP_IO_READ8(_A, _R, _pV)								\
-{																\
-}
-
-#define RTMP_IO_WRITE32(_A, _R, _V)								\
-	RTUSBWriteMACRegister((_A), (_R), (u32)(_V))
-
-#define RTMP_IO_WRITE8(_A, _R, _V)								\
-{																\
-	u16	_Val = _V;											\
-	RTUSBSingleWrite((_A), (_R), (u16)(_Val));								\
-}
-
-#define RTMP_IO_WRITE16(_A, _R, _V)								\
-{																\
-	RTUSBSingleWrite((_A), (_R), (u16)(_V));								\
-}
-#endif /* RTMP_MAC_USB // */
-
-/***********************************************************************************
- *	Network Related data structure and marco definitions
- ***********************************************************************************/
-#define PKTSRC_NDIS             0x7f
-#define PKTSRC_DRIVER           0x0f
-
-#define RTMP_OS_NETDEV_SET_PRIV(_pNetDev, _pPriv)	((_pNetDev)->ml_priv = (_pPriv))
-#define RTMP_OS_NETDEV_GET_PRIV(_pNetDev)		((_pNetDev)->ml_priv)
-#define RTMP_OS_NETDEV_GET_DEVNAME(_pNetDev)	((_pNetDev)->name)
-#define RTMP_OS_NETDEV_GET_PHYADDR(_PNETDEV)	((_PNETDEV)->dev_addr)
-
-#define RTMP_OS_NETDEV_START_QUEUE(_pNetDev)	netif_start_queue((_pNetDev))
-#define RTMP_OS_NETDEV_STOP_QUEUE(_pNetDev)	netif_stop_queue((_pNetDev))
-#define RTMP_OS_NETDEV_WAKE_QUEUE(_pNetDev)	netif_wake_queue((_pNetDev))
-#define RTMP_OS_NETDEV_CARRIER_OFF(_pNetDev)	netif_carrier_off((_pNetDev))
-
-#define QUEUE_ENTRY_TO_PACKET(pEntry) \
-	(void *)(pEntry)
-
-#define PACKET_TO_QUEUE_ENTRY(pPacket) \
-	(struct rt_queue_entry *)(pPacket)
-
-#define GET_SG_LIST_FROM_PACKET(_p, _sc)	\
-    rt_get_sg_list_from_packet(_p, _sc)
-
-#define RELEASE_NDIS_PACKET(_pAd, _pPacket, _Status)                    \
-{                                                                       \
-        RTMPFreeNdisPacket(_pAd, _pPacket);                             \
-}
-
-/*
- * packet helper
- * 	- convert internal rt packet to os packet or
- *             os packet to rt packet
- */
-#define RTPKT_TO_OSPKT(_p)		((struct sk_buff *)(_p))
-#define OSPKT_TO_RTPKT(_p)		((void *)(_p))
-
-#define GET_OS_PKT_DATAPTR(_pkt) \
-		(RTPKT_TO_OSPKT(_pkt)->data)
-#define SET_OS_PKT_DATAPTR(_pkt, _dataPtr)	\
-		(RTPKT_TO_OSPKT(_pkt)->data) = (_dataPtr)
-
-#define GET_OS_PKT_LEN(_pkt) \
-		(RTPKT_TO_OSPKT(_pkt)->len)
-#define SET_OS_PKT_LEN(_pkt, _len)	\
-		(RTPKT_TO_OSPKT(_pkt)->len) = (_len)
-
-#define GET_OS_PKT_DATATAIL(_pkt) \
-		(skb_tail_pointer(RTPKT_TO_OSPKT(_pkt))
-#define SET_OS_PKT_DATATAIL(_pkt, _start, _len)	\
-		(skb_set_tail_pointer(RTPKT_TO_OSPKT(_pkt), _len))
-
-#define GET_OS_PKT_HEAD(_pkt) \
-		(RTPKT_TO_OSPKT(_pkt)->head)
-
-#define GET_OS_PKT_END(_pkt) \
-		(RTPKT_TO_OSPKT(_pkt)->end)
-
-#define GET_OS_PKT_NETDEV(_pkt) \
-		(RTPKT_TO_OSPKT(_pkt)->dev)
-#define SET_OS_PKT_NETDEV(_pkt, _pNetDev)	\
-		(RTPKT_TO_OSPKT(_pkt)->dev) = (_pNetDev)
-
-#define GET_OS_PKT_TYPE(_pkt) \
-		(RTPKT_TO_OSPKT(_pkt))
-
-#define GET_OS_PKT_NEXT(_pkt) \
-		(RTPKT_TO_OSPKT(_pkt)->next)
-
-#define OS_PKT_CLONED(_pkt)		skb_cloned(RTPKT_TO_OSPKT(_pkt))
-
-#define OS_NTOHS(_Val) \
-		(ntohs(_Val))
-#define OS_HTONS(_Val) \
-		(htons(_Val))
-#define OS_NTOHL(_Val) \
-		(ntohl(_Val))
-#define OS_HTONL(_Val) \
-		(htonl(_Val))
-
-#define CB_OFF  10
-
-/* User Priority */
-#define RTMP_SET_PACKET_UP(_p, _prio)			(RTPKT_TO_OSPKT(_p)->cb[CB_OFF+0] = _prio)
-#define RTMP_GET_PACKET_UP(_p)					(RTPKT_TO_OSPKT(_p)->cb[CB_OFF+0])
-
-/* Fragment # */
-#define RTMP_SET_PACKET_FRAGMENTS(_p, _num)		(RTPKT_TO_OSPKT(_p)->cb[CB_OFF+1] = _num)
-#define RTMP_GET_PACKET_FRAGMENTS(_p)			(RTPKT_TO_OSPKT(_p)->cb[CB_OFF+1])
-
-/* 0x0 ~0x7f: TX to AP's own BSS which has the specified AID. if AID>127, set bit 7 in RTMP_SET_PACKET_EMACTAB too. */
-/*(this value also as MAC(on-chip WCID) table index) */
-/* 0x80~0xff: TX to a WDS link. b0~6: WDS index */
-#define RTMP_SET_PACKET_WCID(_p, _wdsidx)		(RTPKT_TO_OSPKT(_p)->cb[CB_OFF+2] = _wdsidx)
-#define RTMP_GET_PACKET_WCID(_p)          		((u8)(RTPKT_TO_OSPKT(_p)->cb[CB_OFF+2]))
-
-/* 0xff: PKTSRC_NDIS, others: local TX buffer index. This value affects how to a packet */
-#define RTMP_SET_PACKET_SOURCE(_p, _pktsrc)		(RTPKT_TO_OSPKT(_p)->cb[CB_OFF+3] = _pktsrc)
-#define RTMP_GET_PACKET_SOURCE(_p)       		(RTPKT_TO_OSPKT(_p)->cb[CB_OFF+3])
-
-/* RTS/CTS-to-self protection method */
-#define RTMP_SET_PACKET_RTS(_p, _num)      		(RTPKT_TO_OSPKT(_p)->cb[CB_OFF+4] = _num)
-#define RTMP_GET_PACKET_RTS(_p)          		(RTPKT_TO_OSPKT(_p)->cb[CB_OFF+4])
-/* see RTMP_S(G)ET_PACKET_EMACTAB */
-
-/* TX rate index */
-#define RTMP_SET_PACKET_TXRATE(_p, _rate)		(RTPKT_TO_OSPKT(_p)->cb[CB_OFF+5] = _rate)
-#define RTMP_GET_PACKET_TXRATE(_p)		  		(RTPKT_TO_OSPKT(_p)->cb[CB_OFF+5])
-
-/* From which Interface */
-#define RTMP_SET_PACKET_IF(_p, _ifdx)		(RTPKT_TO_OSPKT(_p)->cb[CB_OFF+6] = _ifdx)
-#define RTMP_GET_PACKET_IF(_p)		  		(RTPKT_TO_OSPKT(_p)->cb[CB_OFF+6])
-#define RTMP_SET_PACKET_NET_DEVICE_MBSSID(_p, _bss)		RTMP_SET_PACKET_IF((_p), (_bss))
-#define RTMP_SET_PACKET_NET_DEVICE_WDS(_p, _bss)		RTMP_SET_PACKET_IF((_p), ((_bss) + MIN_NET_DEVICE_FOR_WDS))
-#define RTMP_SET_PACKET_NET_DEVICE_APCLI(_p, _idx)   	RTMP_SET_PACKET_IF((_p), ((_idx) + MIN_NET_DEVICE_FOR_APCLI))
-#define RTMP_SET_PACKET_NET_DEVICE_MESH(_p, _idx)   	RTMP_SET_PACKET_IF((_p), ((_idx) + MIN_NET_DEVICE_FOR_MESH))
-#define RTMP_GET_PACKET_NET_DEVICE_MBSSID(_p)			RTMP_GET_PACKET_IF((_p))
-#define RTMP_GET_PACKET_NET_DEVICE(_p)					RTMP_GET_PACKET_IF((_p))
-
-#define RTMP_SET_PACKET_MOREDATA(_p, _morebit)		(RTPKT_TO_OSPKT(_p)->cb[CB_OFF+7] = _morebit)
-#define RTMP_GET_PACKET_MOREDATA(_p)				(RTPKT_TO_OSPKT(_p)->cb[CB_OFF+7])
-
-/* */
-/*      Specific Packet Type definition */
-/* */
-#define RTMP_PACKET_SPECIFIC_CB_OFFSET	11
-
-#define RTMP_PACKET_SPECIFIC_DHCP		0x01
-#define RTMP_PACKET_SPECIFIC_EAPOL		0x02
-#define RTMP_PACKET_SPECIFIC_IPV4		0x04
-#define RTMP_PACKET_SPECIFIC_WAI		0x08
-#define RTMP_PACKET_SPECIFIC_VLAN		0x10
-#define RTMP_PACKET_SPECIFIC_LLCSNAP	0x20
-
-/*Specific */
-#define RTMP_SET_PACKET_SPECIFIC(_p, _flg)	   	(RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11] = _flg)
-
-/*DHCP */
-#define RTMP_SET_PACKET_DHCP(_p, _flg)   													\
-			do{																				\
-				if (_flg)																	\
-					(RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11]) |= (RTMP_PACKET_SPECIFIC_DHCP);		\
-				else																		\
-					(RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11]) &= (!RTMP_PACKET_SPECIFIC_DHCP);	\
-			}while(0)
-#define RTMP_GET_PACKET_DHCP(_p)		(RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11] & RTMP_PACKET_SPECIFIC_DHCP)
-
-/*EAPOL */
-#define RTMP_SET_PACKET_EAPOL(_p, _flg)   													\
-			do{																				\
-				if (_flg)																	\
-					(RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11]) |= (RTMP_PACKET_SPECIFIC_EAPOL);		\
-				else																		\
-					(RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11]) &= (!RTMP_PACKET_SPECIFIC_EAPOL);	\
-			}while(0)
-#define RTMP_GET_PACKET_EAPOL(_p)		(RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11] & RTMP_PACKET_SPECIFIC_EAPOL)
-
-/*WAI */
-#define RTMP_SET_PACKET_WAI(_p, _flg)   													\
-			do{																				\
-				if (_flg)																	\
-					(RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11]) |= (RTMP_PACKET_SPECIFIC_WAI);		\
-				else																		\
-					(RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11]) &= (!RTMP_PACKET_SPECIFIC_WAI);	\
-			}while(0)
-#define RTMP_GET_PACKET_WAI(_p)		(RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11] & RTMP_PACKET_SPECIFIC_WAI)
-
-#define RTMP_GET_PACKET_LOWRATE(_p)		(RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11] & (RTMP_PACKET_SPECIFIC_EAPOL | RTMP_PACKET_SPECIFIC_DHCP | RTMP_PACKET_SPECIFIC_WAI))
-
-/*VLAN */
-#define RTMP_SET_PACKET_VLAN(_p, _flg)   													\
-			do{																				\
-				if (_flg)																	\
-					(RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11]) |= (RTMP_PACKET_SPECIFIC_VLAN);		\
-				else																		\
-					(RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11]) &= (!RTMP_PACKET_SPECIFIC_VLAN);	\
-			}while(0)
-#define RTMP_GET_PACKET_VLAN(_p)		(RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11] & RTMP_PACKET_SPECIFIC_VLAN)
-
-/*LLC/SNAP */
-#define RTMP_SET_PACKET_LLCSNAP(_p, _flg)   													\
-			do{																				\
-				if (_flg)																	\
-					(RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11]) |= (RTMP_PACKET_SPECIFIC_LLCSNAP);		\
-				else																		\
-					(RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11]) &= (!RTMP_PACKET_SPECIFIC_LLCSNAP);		\
-			}while(0)
-
-#define RTMP_GET_PACKET_LLCSNAP(_p)		(RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11] & RTMP_PACKET_SPECIFIC_LLCSNAP)
-
-/* IP */
-#define RTMP_SET_PACKET_IPV4(_p, _flg)														\
-			do{																				\
-				if (_flg)																	\
-					(RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11]) |= (RTMP_PACKET_SPECIFIC_IPV4);		\
-				else																		\
-					(RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11]) &= (!RTMP_PACKET_SPECIFIC_IPV4);	\
-			}while(0)
-
-#define RTMP_GET_PACKET_IPV4(_p)		(RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11] & RTMP_PACKET_SPECIFIC_IPV4)
-
-/* If this flag is set, it indicates that this EAPoL frame MUST be clear. */
-#define RTMP_SET_PACKET_CLEAR_EAP_FRAME(_p, _flg)   (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+12] = _flg)
-#define RTMP_GET_PACKET_CLEAR_EAP_FRAME(_p)         (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+12])
-
-/* use bit3 of cb[CB_OFF+16] */
-
-#define RTMP_SET_PACKET_5VT(_p, _flg)   (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+22] = _flg)
-#define RTMP_GET_PACKET_5VT(_p)         (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+22])
-
-/* Max skb->cb = 48B = [CB_OFF+38] */
-
-/***********************************************************************************
- *	Other function prototypes definitions
- ***********************************************************************************/
-void RTMP_GetCurrentSystemTime(LARGE_INTEGER *time);
-int rt28xx_packet_xmit(struct sk_buff *skb);
-
-#ifdef RTMP_MAC_PCI
-/* function declarations */
-#define IRQ_HANDLE_TYPE  irqreturn_t
-
-IRQ_HANDLE_TYPE rt2860_interrupt(int irq, void *dev_instance);
-#endif /* RTMP_MAC_PCI // */
-
-int rt28xx_sta_ioctl(struct net_device *net_dev, IN OUT struct ifreq *rq, int cmd);
-
-extern int ra_mtd_write(int num, loff_t to, size_t len, const u_char *buf);
-extern int ra_mtd_read(int num, loff_t from, size_t len, u_char *buf);
-
-#define GET_PAD_FROM_NET_DEV(_pAd, _net_dev)	(_pAd) = (struct rt_rtmp_adapter *)(_net_dev)->ml_priv;
-
-#endif /* __RT_LINUX_H__ // */
diff -druN linux-2.6.39-libre/drivers/staging/rt2860/rt_main_dev.c linux-3.0-rc7-libre/drivers/staging/rt2860/rt_main_dev.c
--- linux-2.6.39-libre/drivers/staging/rt2860/rt_main_dev.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rt2860/rt_main_dev.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,736 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, 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.             *
- *                                                                       *
- *************************************************************************
-
-    Module Name:
-    rt_main_dev.c
-
-    Abstract:
-    Create and register network interface.
-
-    Revision History:
-    Who         	When            What
-    Justin P. Mattock	11/07/2010	Fix typos in comments
-    --------    ----------      ----------------------------------------------
-*/
-
-#include "rt_config.h"
-
-/*---------------------------------------------------------------------*/
-/* Private Variables Used                                              */
-/*---------------------------------------------------------------------*/
-
-char *mac = "";		/* default 00:00:00:00:00:00 */
-char *hostname = "";		/* default CMPC */
-module_param(mac, charp, 0);
-MODULE_PARM_DESC(mac, "rt28xx: wireless mac addr");
-
-/*---------------------------------------------------------------------*/
-/* Prototypes of Functions Used                                        */
-/*---------------------------------------------------------------------*/
-
-/* public function prototype */
-int rt28xx_close(IN struct net_device *net_dev);
-int rt28xx_open(struct net_device *net_dev);
-
-/* private function prototype */
-static int rt28xx_send_packets(IN struct sk_buff *skb_p,
-			       IN struct net_device *net_dev);
-
-static struct net_device_stats *RT28xx_get_ether_stats(IN struct net_device
-						       *net_dev);
-
-/*
-========================================================================
-Routine Description:
-    Close raxx interface.
-
-Arguments:
-	*net_dev			the raxx interface pointer
-
-Return Value:
-    0					Open OK
-	otherwise			Open Fail
-
-Note:
-	1. if open fail, kernel will not call the close function.
-	2. Free memory for
-		(1) Mlme Memory Handler:		MlmeHalt()
-		(2) TX & RX:					RTMPFreeTxRxRingMemory()
-		(3) BA Reordering: 				ba_reordering_resource_release()
-========================================================================
-*/
-int MainVirtualIF_close(IN struct net_device *net_dev)
-{
-	struct rt_rtmp_adapter *pAd = NULL;
-
-	GET_PAD_FROM_NET_DEV(pAd, net_dev);
-
-	/* Sanity check for pAd */
-	if (pAd == NULL)
-		return 0;	/* close ok */
-
-	netif_carrier_off(pAd->net_dev);
-	netif_stop_queue(pAd->net_dev);
-
-	{
-		BOOLEAN Cancelled;
-
-		if (INFRA_ON(pAd) &&
-		    (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))) {
-			struct rt_mlme_disassoc_req DisReq;
-			struct rt_mlme_queue_elem *MsgElem =
-				kmalloc(sizeof(struct rt_mlme_queue_elem),
-					MEM_ALLOC_FLAG);
-
-			if (MsgElem) {
-				COPY_MAC_ADDR(DisReq.Addr,
-					      pAd->CommonCfg.Bssid);
-				DisReq.Reason = REASON_DEAUTH_STA_LEAVING;
-
-				MsgElem->Machine = ASSOC_STATE_MACHINE;
-				MsgElem->MsgType = MT2_MLME_DISASSOC_REQ;
-				MsgElem->MsgLen =
-				    sizeof(struct rt_mlme_disassoc_req);
-				NdisMoveMemory(MsgElem->Msg, &DisReq,
-					       sizeof
-					       (struct rt_mlme_disassoc_req));
-
-				/* Prevent to connect AP again in STAMlmePeriodicExec */
-				pAd->MlmeAux.AutoReconnectSsidLen = 32;
-				NdisZeroMemory(pAd->MlmeAux.AutoReconnectSsid,
-					       pAd->MlmeAux.
-					       AutoReconnectSsidLen);
-
-				pAd->Mlme.CntlMachine.CurrState =
-				    CNTL_WAIT_OID_DISASSOC;
-				MlmeDisassocReqAction(pAd, MsgElem);
-				kfree(MsgElem);
-			}
-
-			RTMPusecDelay(1000);
-		}
-
-		RTMPCancelTimer(&pAd->StaCfg.StaQuickResponeForRateUpTimer,
-				&Cancelled);
-		RTMPCancelTimer(&pAd->StaCfg.WpaDisassocAndBlockAssocTimer,
-				&Cancelled);
-	}
-
-	VIRTUAL_IF_DOWN(pAd);
-
-	RT_MOD_DEC_USE_COUNT();
-
-	return 0;		/* close ok */
-}
-
-/*
-========================================================================
-Routine Description:
-    Open raxx interface.
-
-Arguments:
-	*net_dev			the raxx interface pointer
-
-Return Value:
-    0					Open OK
-	otherwise			Open Fail
-
-Note:
-	1. if open fail, kernel will not call the close function.
-	2. Free memory for
-		(1) Mlme Memory Handler:		MlmeHalt()
-		(2) TX & RX:					RTMPFreeTxRxRingMemory()
-		(3) BA Reordering: 				ba_reordering_resource_release()
-========================================================================
-*/
-int MainVirtualIF_open(IN struct net_device *net_dev)
-{
-	struct rt_rtmp_adapter *pAd = NULL;
-
-	GET_PAD_FROM_NET_DEV(pAd, net_dev);
-
-	/* Sanity check for pAd */
-	if (pAd == NULL)
-		return 0;	/* close ok */
-
-	if (VIRTUAL_IF_UP(pAd) != 0)
-		return -1;
-
-	/* increase MODULE use count */
-	RT_MOD_INC_USE_COUNT();
-
-	netif_start_queue(net_dev);
-	netif_carrier_on(net_dev);
-	netif_wake_queue(net_dev);
-
-	return 0;
-}
-
-/*
-========================================================================
-Routine Description:
-    Close raxx interface.
-
-Arguments:
-	*net_dev			the raxx interface pointer
-
-Return Value:
-    0					Open OK
-	otherwise			Open Fail
-
-Note:
-	1. if open fail, kernel will not call the close function.
-	2. Free memory for
-		(1) Mlme Memory Handler:		MlmeHalt()
-		(2) TX & RX:					RTMPFreeTxRxRingMemory()
-		(3) BA Reordering: 				ba_reordering_resource_release()
-========================================================================
-*/
-int rt28xx_close(struct net_device *dev)
-{
-	struct net_device *net_dev = (struct net_device *)dev;
-	struct rt_rtmp_adapter *pAd = NULL;
-	BOOLEAN Cancelled;
-	u32 i = 0;
-
-#ifdef RTMP_MAC_USB
-	DECLARE_WAIT_QUEUE_HEAD_ONSTACK(unlink_wakeup);
-	DECLARE_WAITQUEUE(wait, current);
-#endif /* RTMP_MAC_USB // */
-
-	GET_PAD_FROM_NET_DEV(pAd, net_dev);
-
-	DBGPRINT(RT_DEBUG_TRACE, ("===> rt28xx_close\n"));
-
-	Cancelled = FALSE;
-	/* Sanity check for pAd */
-	if (pAd == NULL)
-		return 0;	/* close ok */
-
-	{
-#ifdef RTMP_MAC_PCI
-		RTMPPCIeLinkCtrlValueRestore(pAd, RESTORE_CLOSE);
-#endif /* RTMP_MAC_PCI // */
-
-		/* If driver doesn't wake up firmware here, */
-		/* NICLoadFirmware will hang forever when interface is up again. */
-		if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE)) {
-			AsicForceWakeup(pAd, TRUE);
-		}
-#ifdef RTMP_MAC_USB
-		RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_REMOVE_IN_PROGRESS);
-#endif /* RTMP_MAC_USB // */
-
-		MlmeRadioOff(pAd);
-#ifdef RTMP_MAC_PCI
-		pAd->bPCIclkOff = FALSE;
-#endif /* RTMP_MAC_PCI // */
-	}
-
-	RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS);
-
-	for (i = 0; i < NUM_OF_TX_RING; i++) {
-		while (pAd->DeQueueRunning[i] == TRUE) {
-			DBGPRINT(RT_DEBUG_TRACE,
-				 ("Waiting for TxQueue[%d] done..........\n",
-				  i));
-			RTMPusecDelay(1000);
-		}
-	}
-
-#ifdef RTMP_MAC_USB
-	/* ensure there are no more active urbs. */
-	add_wait_queue(&unlink_wakeup, &wait);
-	pAd->wait = &unlink_wakeup;
-
-	/* maybe wait for deletions to finish. */
-	i = 0;
-	/*while((i < 25) && atomic_read(&pAd->PendingRx) > 0) */
-	while (i < 25) {
-		unsigned long IrqFlags;
-
-		RTMP_IRQ_LOCK(&pAd->BulkInLock, IrqFlags);
-		if (pAd->PendingRx == 0) {
-			RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
-			break;
-		}
-		RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
-
-		msleep(UNLINK_TIMEOUT_MS);	/*Time in millisecond */
-		i++;
-	}
-	pAd->wait = NULL;
-	remove_wait_queue(&unlink_wakeup, &wait);
-#endif /* RTMP_MAC_USB // */
-
-	/* Stop Mlme state machine */
-	MlmeHalt(pAd);
-
-	/* Close net tasklets */
-	RtmpNetTaskExit(pAd);
-
-	{
-		MacTableReset(pAd);
-	}
-
-	MeasureReqTabExit(pAd);
-	TpcReqTabExit(pAd);
-
-	/* Close kernel threads */
-	RtmpMgmtTaskExit(pAd);
-
-#ifdef RTMP_MAC_PCI
-	{
-		BOOLEAN brc;
-		/*      unsigned long                   Value; */
-
-		if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_ACTIVE)) {
-			RTMP_ASIC_INTERRUPT_DISABLE(pAd);
-		}
-		/* Receive packets to clear DMA index after disable interrupt. */
-		/* RTMPHandleRxDoneInterrupt(pAd); */
-		/* put radio off to save power when driver unloads.  After radiooff, can't write/read register, so need to finish all. */
-		/* register access before Radio off. */
-
-		brc = RT28xxPciAsicRadioOff(pAd, RTMP_HALT, 0);
-
-/*In  solution 3 of 3090F, the bPCIclkOff will be set to TRUE after calling RT28xxPciAsicRadioOff */
-		pAd->bPCIclkOff = FALSE;
-
-		if (brc == FALSE) {
-			DBGPRINT(RT_DEBUG_ERROR,
-				 ("%s call RT28xxPciAsicRadioOff fail!\n",
-				  __func__));
-		}
-	}
-
-/*
-	if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_ACTIVE))
-	{
-		RTMP_ASIC_INTERRUPT_DISABLE(pAd);
-	}
-
-	// Disable Rx, register value supposed will remain after reset
-	NICIssueReset(pAd);
-*/
-#endif /* RTMP_MAC_PCI // */
-
-	/* Free IRQ */
-	if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE)) {
-#ifdef RTMP_MAC_PCI
-		/* Deregister interrupt function */
-		RtmpOSIRQRelease(net_dev);
-#endif /* RTMP_MAC_PCI // */
-		RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE);
-	}
-	/* Free Ring or USB buffers */
-	RTMPFreeTxRxRingMemory(pAd);
-
-	RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS);
-
-	/* Free BA reorder resource */
-	ba_reordering_resource_release(pAd);
-
-	RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_START_UP);
-
-/*+++Modify by woody to solve the bulk fail+++*/
-	{
-	}
-
-	DBGPRINT(RT_DEBUG_TRACE, ("<=== rt28xx_close\n"));
-	return 0;		/* close ok */
-}				/* End of rt28xx_close */
-
-/*
-========================================================================
-Routine Description:
-    Open raxx interface.
-
-Arguments:
-	*net_dev			the raxx interface pointer
-
-Return Value:
-    0					Open OK
-	otherwise			Open Fail
-
-Note:
-========================================================================
-*/
-int rt28xx_open(struct net_device *dev)
-{
-	struct net_device *net_dev = (struct net_device *)dev;
-	struct rt_rtmp_adapter *pAd = NULL;
-	int retval = 0;
-	/*struct os_cookie *pObj; */
-
-	GET_PAD_FROM_NET_DEV(pAd, net_dev);
-
-	/* Sanity check for pAd */
-	if (pAd == NULL) {
-		/* if 1st open fail, pAd will be free;
-		   So the net_dev->ml_priv will be NULL in 2rd open */
-		return -1;
-	}
-
-	if (net_dev->priv_flags == INT_MAIN) {
-		if (pAd->OpMode == OPMODE_STA)
-			net_dev->wireless_handlers =
-			    (struct iw_handler_def *)&rt28xx_iw_handler_def;
-	}
-	/* Request interrupt service routine for PCI device */
-	/* register the interrupt routine with the os */
-	RtmpOSIRQRequest(net_dev);
-
-	/* Init IRQ parameters stored in pAd */
-	RTMP_IRQ_INIT(pAd);
-
-	/* Chip & other init */
-	if (rt28xx_init(pAd, mac, hostname) == FALSE)
-		goto err;
-
-	/* Enable Interrupt */
-	RTMP_IRQ_ENABLE(pAd);
-
-	/* Now Enable RxTx */
-	RTMPEnableRxTx(pAd);
-	RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_START_UP);
-
-	{
-		u32 reg = 0;
-		RTMP_IO_READ32(pAd, 0x1300, &reg);	/* clear garbage interrupts */
-		printk(KERN_DEBUG "0x1300 = %08x\n", reg);
-	}
-
-	{
-/*      u32 reg; */
-/*      u8  byte; */
-/*      u16 tmp; */
-
-/*      RTMP_IO_READ32(pAd, XIFS_TIME_CFG, &reg); */
-
-/*      tmp = 0x0805; */
-/*      reg  = (reg & 0xffff0000) | tmp; */
-/*      RTMP_IO_WRITE32(pAd, XIFS_TIME_CFG, reg); */
-
-	}
-#ifdef RTMP_MAC_PCI
-	RTMPInitPCIeLinkCtrlValue(pAd);
-#endif /* RTMP_MAC_PCI // */
-
-	return retval;
-
-err:
-/*+++Add by shiang, move from rt28xx_init() to here. */
-	RtmpOSIRQRelease(net_dev);
-/*---Add by shiang, move from rt28xx_init() to here. */
-	return -1;
-}				/* End of rt28xx_open */
-
-static const struct net_device_ops rt2860_netdev_ops = {
-	.ndo_open = MainVirtualIF_open,
-	.ndo_stop = MainVirtualIF_close,
-	.ndo_do_ioctl = rt28xx_sta_ioctl,
-	.ndo_get_stats = RT28xx_get_ether_stats,
-	.ndo_validate_addr = NULL,
-	.ndo_set_mac_address = eth_mac_addr,
-	.ndo_change_mtu = eth_change_mtu,
-	.ndo_start_xmit = rt28xx_send_packets,
-};
-
-struct net_device *RtmpPhyNetDevInit(struct rt_rtmp_adapter *pAd,
-			   struct rt_rtmp_os_netdev_op_hook *pNetDevHook)
-{
-	struct net_device *net_dev = NULL;
-/*      int             Status; */
-
-	net_dev =
-	    RtmpOSNetDevCreate(pAd, INT_MAIN, 0, sizeof(struct rt_rtmp_adapter *),
-			       INF_MAIN_DEV_NAME);
-	if (net_dev == NULL) {
-		printk
-		    ("RtmpPhyNetDevInit(): creation failed for main physical net device!\n");
-		return NULL;
-	}
-
-	NdisZeroMemory((unsigned char *)pNetDevHook,
-		       sizeof(struct rt_rtmp_os_netdev_op_hook));
-	pNetDevHook->netdev_ops = &rt2860_netdev_ops;
-	pNetDevHook->priv_flags = INT_MAIN;
-	pNetDevHook->needProtcted = FALSE;
-
-	net_dev->ml_priv = (void *)pAd;
-	pAd->net_dev = net_dev;
-
-	return net_dev;
-
-}
-
-/*
-========================================================================
-Routine Description:
-    The entry point for Linux kernel sent packet to our driver.
-
-Arguments:
-    sk_buff *skb		the pointer refer to a sk_buffer.
-
-Return Value:
-    0
-
-Note:
-	This function is the entry point of Tx Path for Os delivery packet to
-	our driver. You only can put OS-depened & STA/AP common handle procedures
-	in here.
-========================================================================
-*/
-int rt28xx_packet_xmit(struct sk_buff *skb)
-{
-	struct net_device *net_dev = skb->dev;
-	struct rt_rtmp_adapter *pAd = NULL;
-	int status = NETDEV_TX_OK;
-	void *pPacket = (void *)skb;
-
-	GET_PAD_FROM_NET_DEV(pAd, net_dev);
-
-	/* RT2870STA does this in RTMPSendPackets() */
-
-	{
-		/* Drop send request since we are in monitor mode */
-		if (MONITOR_ON(pAd)) {
-			RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
-			goto done;
-		}
-	}
-
-	/* EapolStart size is 18 */
-	if (skb->len < 14) {
-		/*printk("bad packet size: %d\n", pkt->len); */
-		hex_dump("bad packet", skb->data, skb->len);
-		RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
-		goto done;
-	}
-
-	RTMP_SET_PACKET_5VT(pPacket, 0);
-	STASendPackets((void *)pAd, (void **)&pPacket, 1);
-
-	status = NETDEV_TX_OK;
-done:
-
-	return status;
-}
-
-/*
-========================================================================
-Routine Description:
-    Send a packet to WLAN.
-
-Arguments:
-    skb_p           points to our adapter
-    dev_p           which WLAN network interface
-
-Return Value:
-    0: transmit successfully
-    otherwise: transmit fail
-
-Note:
-========================================================================
-*/
-static int rt28xx_send_packets(IN struct sk_buff *skb_p,
-			       IN struct net_device *net_dev)
-{
-	struct rt_rtmp_adapter *pAd = NULL;
-
-	GET_PAD_FROM_NET_DEV(pAd, net_dev);
-
-	if (!(net_dev->flags & IFF_UP)) {
-		RELEASE_NDIS_PACKET(pAd, (void *)skb_p,
-				    NDIS_STATUS_FAILURE);
-		return NETDEV_TX_OK;
-	}
-
-	NdisZeroMemory((u8 *)&skb_p->cb[CB_OFF], 15);
-	RTMP_SET_PACKET_NET_DEVICE_MBSSID(skb_p, MAIN_MBSSID);
-
-	return rt28xx_packet_xmit(skb_p);
-}
-
-/* This function will be called when query /proc */
-struct iw_statistics *rt28xx_get_wireless_stats(IN struct net_device *net_dev)
-{
-	struct rt_rtmp_adapter *pAd = NULL;
-
-	GET_PAD_FROM_NET_DEV(pAd, net_dev);
-
-	DBGPRINT(RT_DEBUG_TRACE, ("rt28xx_get_wireless_stats --->\n"));
-
-	pAd->iw_stats.status = 0;	/* Status - device dependent for now */
-
-	/* link quality */
-	if (pAd->OpMode == OPMODE_STA)
-		pAd->iw_stats.qual.qual =
-		    ((pAd->Mlme.ChannelQuality * 12) / 10 + 10);
-
-	if (pAd->iw_stats.qual.qual > 100)
-		pAd->iw_stats.qual.qual = 100;
-
-	if (pAd->OpMode == OPMODE_STA) {
-		pAd->iw_stats.qual.level =
-		    RTMPMaxRssi(pAd, pAd->StaCfg.RssiSample.LastRssi0,
-				pAd->StaCfg.RssiSample.LastRssi1,
-				pAd->StaCfg.RssiSample.LastRssi2);
-	}
-
-	pAd->iw_stats.qual.noise = pAd->BbpWriteLatch[66];	/* noise level (dBm) */
-
-	pAd->iw_stats.qual.noise += 256 - 143;
-	pAd->iw_stats.qual.updated = 1;	/* Flags to know if updated */
-#ifdef IW_QUAL_DBM
-	pAd->iw_stats.qual.updated |= IW_QUAL_DBM;	/* Level + Noise are dBm */
-#endif /* IW_QUAL_DBM // */
-
-	pAd->iw_stats.discard.nwid = 0;	/* Rx : Wrong nwid/essid */
-	pAd->iw_stats.miss.beacon = 0;	/* Missed beacons/superframe */
-
-	DBGPRINT(RT_DEBUG_TRACE, ("<--- rt28xx_get_wireless_stats\n"));
-	return &pAd->iw_stats;
-}
-
-void tbtt_tasklet(unsigned long data)
-{
-/*#define MAX_TX_IN_TBTT                (16) */
-
-}
-
-/*
-    ========================================================================
-
-    Routine Description:
-	return ethernet statistics counter
-
-    Arguments:
-	net_dev				Pointer to net_device
-
-    Return Value:
-	net_device_stats*
-
-    Note:
-
-    ========================================================================
-*/
-static struct net_device_stats *RT28xx_get_ether_stats(IN struct net_device
-						       *net_dev)
-{
-	struct rt_rtmp_adapter *pAd = NULL;
-
-	if (net_dev)
-		GET_PAD_FROM_NET_DEV(pAd, net_dev);
-
-	if (pAd) {
-
-		pAd->stats.rx_packets =
-		    pAd->WlanCounters.ReceivedFragmentCount.QuadPart;
-		pAd->stats.tx_packets =
-		    pAd->WlanCounters.TransmittedFragmentCount.QuadPart;
-
-		pAd->stats.rx_bytes = pAd->RalinkCounters.ReceivedByteCount;
-		pAd->stats.tx_bytes = pAd->RalinkCounters.TransmittedByteCount;
-
-		pAd->stats.rx_errors = pAd->Counters8023.RxErrors;
-		pAd->stats.tx_errors = pAd->Counters8023.TxErrors;
-
-		pAd->stats.rx_dropped = 0;
-		pAd->stats.tx_dropped = 0;
-
-		pAd->stats.multicast = pAd->WlanCounters.MulticastReceivedFrameCount.QuadPart;	/* multicast packets received */
-		pAd->stats.collisions = pAd->Counters8023.OneCollision + pAd->Counters8023.MoreCollisions;	/* Collision packets */
-
-		pAd->stats.rx_length_errors = 0;
-		pAd->stats.rx_over_errors = pAd->Counters8023.RxNoBuffer;	/* receiver ring buff overflow */
-		pAd->stats.rx_crc_errors = 0;	/*pAd->WlanCounters.FCSErrorCount;     // recved pkt with crc error */
-		pAd->stats.rx_frame_errors = pAd->Counters8023.RcvAlignmentErrors;	/* recv'd frame alignment error */
-		pAd->stats.rx_fifo_errors = pAd->Counters8023.RxNoBuffer;	/* recv'r fifo overrun */
-		pAd->stats.rx_missed_errors = 0;	/* receiver missed packet */
-
-		/* detailed tx_errors */
-		pAd->stats.tx_aborted_errors = 0;
-		pAd->stats.tx_carrier_errors = 0;
-		pAd->stats.tx_fifo_errors = 0;
-		pAd->stats.tx_heartbeat_errors = 0;
-		pAd->stats.tx_window_errors = 0;
-
-		/* for cslip etc */
-		pAd->stats.rx_compressed = 0;
-		pAd->stats.tx_compressed = 0;
-
-		return &pAd->stats;
-	} else
-		return NULL;
-}
-
-BOOLEAN RtmpPhyNetDevExit(struct rt_rtmp_adapter *pAd, struct net_device *net_dev)
-{
-
-	/* Unregister network device */
-	if (net_dev != NULL) {
-		printk
-		    ("RtmpOSNetDevDetach(): RtmpOSNetDeviceDetach(), dev->name=%s!\n",
-		     net_dev->name);
-		RtmpOSNetDevDetach(net_dev);
-	}
-
-	return TRUE;
-
-}
-
-/*
-========================================================================
-Routine Description:
-    Allocate memory for adapter control block.
-
-Arguments:
-    pAd					Pointer to our adapter
-
-Return Value:
-	NDIS_STATUS_SUCCESS
-	NDIS_STATUS_FAILURE
-	NDIS_STATUS_RESOURCES
-
-Note:
-========================================================================
-*/
-int AdapterBlockAllocateMemory(void *handle, void ** ppAd)
-{
-
-	*ppAd = vmalloc(sizeof(struct rt_rtmp_adapter));
-	/* pci_alloc_consistent(pci_dev, sizeof(struct rt_rtmp_adapter), phy_addr); */
-
-	if (*ppAd) {
-		NdisZeroMemory(*ppAd, sizeof(struct rt_rtmp_adapter));
-		((struct rt_rtmp_adapter *)*ppAd)->OS_Cookie = handle;
-		return NDIS_STATUS_SUCCESS;
-	} else {
-		return NDIS_STATUS_FAILURE;
-	}
-}
diff -druN linux-2.6.39-libre/drivers/staging/rt2860/rtmp_chip.h linux-3.0-rc7-libre/drivers/staging/rt2860/rtmp_chip.h
--- linux-2.6.39-libre/drivers/staging/rt2860/rtmp_chip.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rt2860/rtmp_chip.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,258 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, 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.             *
- *                                                                       *
- *************************************************************************
-
-	Module Name:
-	rtmp_chip.h
-
-	Abstract:
-	Ralink Wireless Chip related definition & structures
-
-	Revision History:
-	Who			When		  What
-	--------	----------	  ----------------------------------------------
-*/
-
-#ifndef	__RTMP_CHIP_H__
-#define	__RTMP_CHIP_H__
-
-#include "rtmp_type.h"
-
-#ifdef RT2860
-#include "chip/rt2860.h"
-#endif /* RT2860 // */
-#ifdef RT2870
-#include "chip/rt2870.h"
-#endif /* RT2870 // */
-#ifdef RT3070
-#include "chip/rt3070.h"
-#endif /* RT3070 // */
-#ifdef RT3090
-#include "chip/rt3090.h"
-#endif /* RT3090 // */
-
-/* We will have a cost down version which mac version is 0x3090xxxx */
-/* */
-/* RT3090A facts */
-/* */
-/* a) 2.4 GHz */
-/* b) Replacement for RT3090 */
-/* c) Internal LNA */
-/* d) Interference over channel #14 */
-/* e) New BBP features (e.g., SIG re-modulation) */
-/* */
-#define IS_RT3090A(_pAd)				((((_pAd)->MACVersion & 0xffff0000) == 0x30900000))
-
-/* We will have a cost down version which mac version is 0x3090xxxx */
-#define IS_RT3090(_pAd)				((((_pAd)->MACVersion & 0xffff0000) == 0x30710000) || (IS_RT3090A(_pAd)))
-
-#define IS_RT3070(_pAd)		(((_pAd)->MACVersion & 0xffff0000) == 0x30700000)
-#define IS_RT3071(_pAd)		(((_pAd)->MACVersion & 0xffff0000) == 0x30710000)
-#define IS_RT2070(_pAd)		(((_pAd)->RfIcType == RFIC_2020) || ((_pAd)->EFuseTag == 0x27))
-
-#define IS_RT30xx(_pAd)		(((_pAd)->MACVersion & 0xfff00000) == 0x30700000||IS_RT3090A(_pAd))
-/*#define IS_RT305X(_pAd)               ((_pAd)->MACVersion == 0x28720200) */
-
-/* RT3572, 3592, 3562, 3062 share the same MAC version */
-#define IS_RT3572(_pAd)		(((_pAd)->MACVersion & 0xffff0000) == 0x35720000)
-#define IS_VERSION_BEFORE_F(_pAd)			(((_pAd)->MACVersion&0xffff) <= 0x0211)
-/* F version is 0x0212, E version is 0x0211. 309x can save more power after F version. */
-#define IS_VERSION_AFTER_F(_pAd)			((((_pAd)->MACVersion&0xffff) >= 0x0212) || (((_pAd)->b3090ESpecialChip == TRUE)))
-/* */
-/* RT3390 facts */
-/* */
-/* a) Base on RT3090 (RF IC: RT3020) */
-/* b) 2.4 GHz */
-/* c) 1x1 */
-/* d) Single chip */
-/* e) Internal components: PA and LNA */
-/* */
-/*RT3390,RT3370 */
-#define IS_RT3390(_pAd)				(((_pAd)->MACVersion & 0xFFFF0000) == 0x33900000)
-
-/* ------------------------------------------------------ */
-/* PCI registers - base address 0x0000 */
-/* ------------------------------------------------------ */
-#define CHIP_PCI_CFG		0x0000
-#define CHIP_PCI_EECTRL		0x0004
-#define CHIP_PCI_MCUCTRL	0x0008
-
-#define OPT_14			0x114
-
-#define RETRY_LIMIT		10
-
-/* ------------------------------------------------------ */
-/* BBP & RF     definition */
-/* ------------------------------------------------------ */
-#define	BUSY		                1
-#define	IDLE		                0
-
-/*------------------------------------------------------------------------- */
-/* EEPROM definition */
-/*------------------------------------------------------------------------- */
-#define EEDO                        0x08
-#define EEDI                        0x04
-#define EECS                        0x02
-#define EESK                        0x01
-#define EERL                        0x80
-
-#define EEPROM_WRITE_OPCODE         0x05
-#define EEPROM_READ_OPCODE          0x06
-#define EEPROM_EWDS_OPCODE          0x10
-#define EEPROM_EWEN_OPCODE          0x13
-
-#define NUM_EEPROM_BBP_PARMS		19	/* Include NIC Config 0, 1, CR, TX ALC step, BBPs */
-#define NUM_EEPROM_TX_G_PARMS		7
-#define EEPROM_NIC1_OFFSET          0x34	/* The address is from NIC config 0, not BBP register ID */
-#define EEPROM_NIC2_OFFSET          0x36	/* The address is from NIC config 0, not BBP register ID */
-#define EEPROM_BBP_BASE_OFFSET		0xf0	/* The address is from NIC config 0, not BBP register ID */
-#define EEPROM_G_TX_PWR_OFFSET		0x52
-#define EEPROM_G_TX2_PWR_OFFSET		0x60
-#define EEPROM_LED1_OFFSET			0x3c
-#define EEPROM_LED2_OFFSET			0x3e
-#define EEPROM_LED3_OFFSET			0x40
-#define EEPROM_LNA_OFFSET			0x44
-#define EEPROM_RSSI_BG_OFFSET		0x46
-#define EEPROM_TXMIXER_GAIN_2_4G	0x48
-#define EEPROM_RSSI_A_OFFSET		0x4a
-#define EEPROM_TXMIXER_GAIN_5G		0x4c
-#define EEPROM_DEFINE_MAX_TXPWR		0x4e
-#define EEPROM_TXPOWER_BYRATE_20MHZ_2_4G	0xde	/* 20MHZ 2.4G tx power. */
-#define EEPROM_TXPOWER_BYRATE_40MHZ_2_4G	0xee	/* 40MHZ 2.4G tx power. */
-#define EEPROM_TXPOWER_BYRATE_20MHZ_5G		0xfa	/* 20MHZ 5G tx power. */
-#define EEPROM_TXPOWER_BYRATE_40MHZ_5G		0x10a	/* 40MHZ 5G tx power. */
-#define EEPROM_A_TX_PWR_OFFSET      0x78
-#define EEPROM_A_TX2_PWR_OFFSET      0xa6
-/*#define EEPROM_Japan_TX_PWR_OFFSET      0x90 // 802.11j */
-/*#define EEPROM_Japan_TX2_PWR_OFFSET      0xbe */
-/*#define EEPROM_TSSI_REF_OFFSET        0x54 */
-/*#define EEPROM_TSSI_DELTA_OFFSET      0x24 */
-/*#define EEPROM_CCK_TX_PWR_OFFSET  0x62 */
-/*#define EEPROM_CALIBRATE_OFFSET       0x7c */
-#define EEPROM_VERSION_OFFSET       0x02
-#define EEPROM_FREQ_OFFSET			0x3a
-#define EEPROM_TXPOWER_BYRATE	0xde	/* 20MHZ power. */
-#define EEPROM_TXPOWER_DELTA		0x50	/* 20MHZ AND 40 MHZ use different power. This is delta in 40MHZ. */
-#define VALID_EEPROM_VERSION        1
-
-/*
-  *   EEPROM operation related marcos
-  */
-#define RT28xx_EEPROM_READ16(_pAd, _offset, _value)			\
-	(_pAd)->chipOps.eeread((struct rt_rtmp_adapter *)(_pAd), (u16)(_offset), (u16 *)&(_value))
-
-/* ------------------------------------------------------------------- */
-/*  E2PROM data layout */
-/* ------------------------------------------------------------------- */
-
-/* */
-/* MCU_LEDCS: MCU LED Control Setting. */
-/* */
-typedef union _MCU_LEDCS_STRUC {
-	struct {
-		u8 LedMode:7;
-		u8 Polarity:1;
-	} field;
-	u8 word;
-} MCU_LEDCS_STRUC, *PMCU_LEDCS_STRUC;
-
-/* */
-/* EEPROM antenna select format */
-/* */
-typedef union _EEPROM_ANTENNA_STRUC {
-	struct {
-		u16 RxPath:4;	/* 1: 1R, 2: 2R, 3: 3R */
-		u16 TxPath:4;	/* 1: 1T, 2: 2T */
-		u16 RfIcType:4;	/* see E2PROM document */
-		u16 Rsv:4;
-	} field;
-	u16 word;
-} EEPROM_ANTENNA_STRUC, *PEEPROM_ANTENNA_STRUC;
-
-typedef union _EEPROM_NIC_CINFIG2_STRUC {
-	struct {
-		u16 HardwareRadioControl:1;	/* 1:enable, 0:disable */
-		u16 DynamicTxAgcControl:1;	/* */
-		u16 ExternalLNAForG:1;	/* */
-		u16 ExternalLNAForA:1;	/* external LNA enable for 2.4G */
-		u16 CardbusAcceleration:1;	/* ! NOTE: 0 - enable, 1 - disable */
-		u16 BW40MSidebandForG:1;
-		u16 BW40MSidebandForA:1;
-		u16 EnableWPSPBC:1;	/* WPS PBC Control bit */
-		u16 BW40MAvailForG:1;	/* 0:enable, 1:disable */
-		u16 BW40MAvailForA:1;	/* 0:enable, 1:disable */
-		u16 Rsv1:1;	/* must be 0 */
-		u16 AntDiversity:1;	/* Antenna diversity */
-		u16 Rsv2:3;	/* must be 0 */
-		u16 DACTestBit:1;	/* control if driver should patch the DAC issue */
-	} field;
-	u16 word;
-} EEPROM_NIC_CONFIG2_STRUC, *PEEPROM_NIC_CONFIG2_STRUC;
-
-/* */
-/* TX_PWR Value valid range 0xFA(-6) ~ 0x24(36) */
-/* */
-typedef union _EEPROM_TX_PWR_STRUC {
-	struct {
-		char Byte0;	/* Low Byte */
-		char Byte1;	/* High Byte */
-	} field;
-	u16 word;
-} EEPROM_TX_PWR_STRUC, *PEEPROM_TX_PWR_STRUC;
-
-typedef union _EEPROM_VERSION_STRUC {
-	struct {
-		u8 FaeReleaseNumber;	/* Low Byte */
-		u8 Version;	/* High Byte */
-	} field;
-	u16 word;
-} EEPROM_VERSION_STRUC, *PEEPROM_VERSION_STRUC;
-
-typedef union _EEPROM_LED_STRUC {
-	struct {
-		u16 PolarityRDY_G:1;	/* Polarity RDY_G setting. */
-		u16 PolarityRDY_A:1;	/* Polarity RDY_A setting. */
-		u16 PolarityACT:1;	/* Polarity ACT setting. */
-		u16 PolarityGPIO_0:1;	/* Polarity GPIO#0 setting. */
-		u16 PolarityGPIO_1:1;	/* Polarity GPIO#1 setting. */
-		u16 PolarityGPIO_2:1;	/* Polarity GPIO#2 setting. */
-		u16 PolarityGPIO_3:1;	/* Polarity GPIO#3 setting. */
-		u16 PolarityGPIO_4:1;	/* Polarity GPIO#4 setting. */
-		u16 LedMode:5;	/* Led mode. */
-		u16 Rsvd:3;	/* Reserved */
-	} field;
-	u16 word;
-} EEPROM_LED_STRUC, *PEEPROM_LED_STRUC;
-
-typedef union _EEPROM_TXPOWER_DELTA_STRUC {
-	struct {
-		u8 DeltaValue:6;	/* Tx Power dalta value (MAX=4) */
-		u8 Type:1;	/* 1: plus the delta value, 0: minus the delta value */
-		u8 TxPowerEnable:1;	/* Enable */
-	} field;
-	u8 value;
-} EEPROM_TXPOWER_DELTA_STRUC, *PEEPROM_TXPOWER_DELTA_STRUC;
-
-#endif /* __RTMP_CHIP_H__ // */
diff -druN linux-2.6.39-libre/drivers/staging/rt2860/rtmp_ckipmic.h linux-3.0-rc7-libre/drivers/staging/rt2860/rtmp_ckipmic.h
--- linux-2.6.39-libre/drivers/staging/rt2860/rtmp_ckipmic.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rt2860/rtmp_ckipmic.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,63 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, 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.             *
- *                                                                       *
- *************************************************************************
-
-	Module Name:
-	rtmp_ckipmic.h
-
-	Abstract:
-
-	Revision History:
-	Who			When			What
-	--------	----------		----------------------------------------------
-	Name		Date			Modification logs
-*/
-#ifndef	__RTMP_CKIPMIC_H__
-#define	__RTMP_CKIPMIC_H__
-
-struct rt_mic_context {
-	/* --- MMH context                            */
-	u8 CK[16];		/* the key                                    */
-	u8 coefficient[16];	/* current aes counter mode coefficients      */
-	unsigned long long accum;	/* accumulated mic, reduced to u32 in final() */
-	u32 position;		/* current position (byte offset) in message  */
-	u8 part[4];		/* for conversion of message to u32 for mmh   */
-};
-
-void xor_128(u8 *a, u8 *b, u8 *out);
-
-u8 RTMPCkipSbox(u8 a);
-
-void xor_32(u8 *a, u8 *b, u8 *out);
-
-void next_key(u8 *key, int round);
-
-void byte_sub(u8 *in, u8 *out);
-
-void shift_row(u8 *in, u8 *out);
-
-void mix_column(u8 *in, u8 *out);
-
-#endif /*__RTMP_CKIPMIC_H__ */
diff -druN linux-2.6.39-libre/drivers/staging/rt2860/rtmp_def.h linux-3.0-rc7-libre/drivers/staging/rt2860/rtmp_def.h
--- linux-2.6.39-libre/drivers/staging/rt2860/rtmp_def.h	2011-05-19 02:15:54.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rt2860/rtmp_def.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,1427 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, 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.             *
- *                                                                       *
- *************************************************************************
-
-    Module Name:
-    rtmp_def.h
-
-    Abstract:
-    Miniport related definition header
-
-    Revision History:
-    Who        	 	When          	What
-    --------    ----------    ----------------------------------------------
-    Paul Lin    	08-01-2002    	created
-    John Chang  	08-05-2003    	add definition for 11g & other drafts
-    Justin P. Mattock	11/07/2010	Fix some typos
-*/
-#ifndef __RTMP_DEF_H__
-#define __RTMP_DEF_H__
-
-#include "oid.h"
-
-/* */
-/*  Debug information verbosity: lower values indicate higher urgency */
-/* */
-#define RT_DEBUG_OFF        0
-#define RT_DEBUG_ERROR      1
-#define RT_DEBUG_WARN       2
-#define RT_DEBUG_TRACE      3
-#define RT_DEBUG_INFO       4
-#define RT_DEBUG_LOUD       5
-
-#define NIC_TAG             ((unsigned long)'0682')
-#define NIC_DBG_char      ("**RT28xx**")
-
-#ifdef RTMP_MAC_USB
-#define TX_RING_SIZE            8	/* 1 */
-#define PRIO_RING_SIZE          8
-#define MGMT_RING_SIZE		32	/* PRIO_RING_SIZE */
-#define RX_RING_SIZE            8
-#define MAX_TX_PROCESS          4
-#define LOCAL_TXBUF_SIZE        2048
-#endif /* RTMP_MAC_USB // */
-
-/*#define PACKED */
-
-#define RALINK_2883_VERSION		((u32)0x28830300)
-#define RALINK_2880E_VERSION	((u32)0x28720200)
-#define RALINK_3070_VERSION		((u32)0x30700200)
-
-#define MAX_RX_PKT_LEN	1520
-
-/* */
-/* Entry number for each DMA descriptor ring */
-/* */
-
-#ifdef RTMP_MAC_PCI
-#define TX_RING_SIZE            64	/*64 */
-#define MGMT_RING_SIZE          128
-#define RX_RING_SIZE            128	/*64 */
-#define MAX_TX_PROCESS          TX_RING_SIZE	/*8 */
-#define MAX_DMA_DONE_PROCESS    TX_RING_SIZE
-#define MAX_TX_DONE_PROCESS     TX_RING_SIZE	/*8 */
-#define LOCAL_TXBUF_SIZE        2
-#endif /* RTMP_MAC_PCI // */
-
-#define MAX_RX_PROCESS          128	/*64 //32 */
-#define NUM_OF_LOCAL_TXBUF      2
-#define TXD_SIZE                16
-#define TXWI_SIZE               16
-#define RXD_SIZE               	16
-#define RXWI_SIZE             	16
-/* TXINFO_SIZE + TXWI_SIZE + 802.11 Header Size + AMSDU sub frame header */
-#define TX_DMA_1ST_BUFFER_SIZE  96	/* only the 1st physical buffer is pre-allocated */
-#define MGMT_DMA_BUFFER_SIZE    1536	/*2048 */
-#define RX_BUFFER_AGGRESIZE     3840	/*3904 //3968 //4096 //2048 //4096 */
-#define RX_BUFFER_NORMSIZE      3840	/*3904 //3968 //4096 //2048 //4096 */
-#define TX_BUFFER_NORMSIZE		RX_BUFFER_NORMSIZE
-#define MAX_FRAME_SIZE          2346	/* Maximum 802.11 frame size */
-#define MAX_AGGREGATION_SIZE    3840	/*3904 //3968 //4096 */
-#define MAX_NUM_OF_TUPLE_CACHE  2
-#define MAX_MCAST_LIST_SIZE     32
-#define MAX_LEN_OF_VENDOR_DESC  64
-/*#define MAX_SIZE_OF_MCAST_PSQ   (NUM_OF_LOCAL_TXBUF >> 2) // AP won't spend more than 1/4 of total buffers on M/BCAST PSQ */
-#define MAX_SIZE_OF_MCAST_PSQ               32
-
-#define MAX_RX_PROCESS_CNT	(RX_RING_SIZE)
-
-/*
-	WMM Note: If memory of your system is not much, please reduce the definition;
-	or when you do WMM test, the queue for low priority AC will be full, i.e.
-	TX_RING_SIZE + MAX_PACKETS_IN_QUEUE packets for the AC will be buffered in
-	WLAN, maybe no packet buffers can get into the Ethernet driver.
-
-	Sometimes no packet buffer can be get into the Ethernet driver, the system will
-	send flow control packet to the sender to slow down its sending rate.
-	So no WMM can be seen in the air.
-*/
-
-/*
-	Need to use 64 in vxworks for test case WMM A5-T07
-	Two dnlink (10Mbps) from a WMM station to a non-WMM station.
-	If use 256, queue is not enough.
-	And in rt_main_end.c, clConfig.clNum = RX_RING_SIZE * 3; is changed to
-	clConfig.clNum = RX_RING_SIZE * 4;
-*/
-/* TODO: For VxWorks the size is 256. Shall we change the value as 256 for all OS? */
-#define MAX_PACKETS_IN_QUEUE				(512)	/*(512)    // to pass WMM A5-WPAPSK */
-
-#define MAX_PACKETS_IN_MCAST_PS_QUEUE		32
-#define MAX_PACKETS_IN_PS_QUEUE				128	/*32 */
-#define WMM_NUM_OF_AC                       4	/* AC0, AC1, AC2, and AC3 */
-
-#ifdef RTMP_EFUSE_SUPPORT
-/*2008/09/11:KH add to support efuse<-- */
-#define MAX_EEPROM_BIN_FILE_SIZE					1024
-#define EFUSE_BUFFER_PATH						"/*(DEBLOBBED)*/"
-/*2008/09/11:KH add to support efuse--> */
-#endif /* RTMP_EFUSE_SUPPORT // */
-
-/* RxFilter */
-#define STANORMAL	 0x17f97
-#define APNORMAL	 0x15f97
-#define PSPXLINK	 0x17f93
-/* */
-/*  struct rt_rtmp_adapter flags */
-/* */
-#define fRTMP_ADAPTER_MAP_REGISTER          0x00000001
-#define fRTMP_ADAPTER_INTERRUPT_IN_USE      0x00000002
-#define fRTMP_ADAPTER_HARDWARE_ERROR        0x00000004
-#define fRTMP_ADAPTER_SCATTER_GATHER        0x00000008
-#define fRTMP_ADAPTER_SEND_PACKET_ERROR     0x00000010
-#define fRTMP_ADAPTER_MLME_RESET_IN_PROGRESS 0x00000020
-#define fRTMP_ADAPTER_HALT_IN_PROGRESS      0x00000040
-#define fRTMP_ADAPTER_RESET_IN_PROGRESS     0x00000080
-#define fRTMP_ADAPTER_NIC_NOT_EXIST         0x00000100
-#define fRTMP_ADAPTER_TX_RING_ALLOCATED     0x00000200
-#define fRTMP_ADAPTER_REMOVE_IN_PROGRESS    0x00000400
-#define fRTMP_ADAPTER_MIMORATE_INUSED       0x00000800
-#define fRTMP_ADAPTER_RX_RING_ALLOCATED     0x00001000
-#define fRTMP_ADAPTER_INTERRUPT_ACTIVE      0x00002000
-#define fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS  0x00004000
-#define	fRTMP_ADAPTER_REASSOC_IN_PROGRESS	0x00008000
-#define	fRTMP_ADAPTER_MEDIA_STATE_PENDING	0x00010000
-#define	fRTMP_ADAPTER_RADIO_OFF				0x00020000
-#define fRTMP_ADAPTER_BULKOUT_RESET			0x00040000
-#define	fRTMP_ADAPTER_BULKIN_RESET			0x00080000
-#define fRTMP_ADAPTER_RDG_ACTIVE			0x00100000
-#define fRTMP_ADAPTER_DYNAMIC_BE_TXOP_ACTIVE 0x00200000
-#define fRTMP_ADAPTER_SCAN_2040 			0x04000000
-#define	fRTMP_ADAPTER_RADIO_MEASUREMENT		0x08000000
-
-#define fRTMP_ADAPTER_START_UP         		0x10000000	/*Device already initialized and enabled Tx/Rx. */
-#define fRTMP_ADAPTER_MEDIA_STATE_CHANGE    0x20000000
-#define fRTMP_ADAPTER_IDLE_RADIO_OFF        0x40000000
-
-/* */
-/*  STA operation status flags */
-/* */
-#define fOP_STATUS_INFRA_ON                 0x00000001
-#define fOP_STATUS_ADHOC_ON                 0x00000002
-#define fOP_STATUS_BG_PROTECTION_INUSED     0x00000004
-#define fOP_STATUS_SHORT_SLOT_INUSED        0x00000008
-#define fOP_STATUS_SHORT_PREAMBLE_INUSED    0x00000010
-#define fOP_STATUS_RECEIVE_DTIM             0x00000020
-#define fOP_STATUS_MEDIA_STATE_CONNECTED    0x00000080
-#define fOP_STATUS_WMM_INUSED               0x00000100
-#define fOP_STATUS_AGGREGATION_INUSED       0x00000200
-#define fOP_STATUS_DOZE                     0x00000400	/* debug purpose */
-#define fOP_STATUS_PIGGYBACK_INUSED         0x00000800	/* piggy-back, and aggregation */
-#define fOP_STATUS_APSD_INUSED				0x00001000
-#define fOP_STATUS_TX_AMSDU_INUSED			0x00002000
-#define fOP_STATUS_MAX_RETRY_ENABLED		0x00004000
-#define fOP_STATUS_WAKEUP_NOW               0x00008000
-#define fOP_STATUS_PCIE_DEVICE       0x00020000
-#define fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE fOP_STATUS_PCIE_DEVICE
-
-/* */
-/*  struct rt_rtmp_adapter PSFlags : related to advanced power save. */
-/* */
-/* Indicate whether driver can go to sleep mode from now. This flag is useful AFTER link up */
-#define fRTMP_PS_CAN_GO_SLEEP          0x00000001
-/* Indicate whether driver has issue a LinkControl command to PCIe L1 */
-#define fRTMP_PS_SET_PCI_CLK_OFF_COMMAND          0x00000002
-/* Indicate driver should disable kick off hardware to send packets from now. */
-#define fRTMP_PS_DISABLE_TX         0x00000004
-/* Indicate driver should IMMEDIATELY go to sleep after receiving AP's beacon in which doesn't indicate unicate nor multicast packets for me */
-/* This flag is used ONLY in RTMPHandleRxDoneInterrupt routine. */
-#define fRTMP_PS_GO_TO_SLEEP_NOW         0x00000008
-#define fRTMP_PS_TOGGLE_L1		0x00000010	/* Use Toggle L1 mechanism for rt28xx PCIe */
-
-#ifdef RT3090
-#define WAKE_MCU_CMD				0x31
-#define SLEEP_MCU_CMD					0x30
-#define RFOFF_MCU_CMD				0x35
-#endif /* RT3090 // */
-
-#define CCKSETPROTECT		0x1
-#define OFDMSETPROTECT		0x2
-#define MM20SETPROTECT		0x4
-#define MM40SETPROTECT		0x8
-#define GF20SETPROTECT		0x10
-#define GR40SETPROTECT		0x20
-#define ALLN_SETPROTECT		(GR40SETPROTECT | GF20SETPROTECT | MM40SETPROTECT | MM20SETPROTECT)
-
-/* */
-/*  AP's client table operation status flags */
-/* */
-#define fCLIENT_STATUS_WMM_CAPABLE          0x00000001	/* CLIENT can parse QOS DATA frame */
-#define fCLIENT_STATUS_AGGREGATION_CAPABLE  0x00000002	/* CLIENT can receive Ralink's proprietary TX aggregation frame */
-#define fCLIENT_STATUS_PIGGYBACK_CAPABLE    0x00000004	/* CLIENT support piggy-back */
-#define fCLIENT_STATUS_AMSDU_INUSED			0x00000008
-#define fCLIENT_STATUS_SGI20_CAPABLE		0x00000010
-#define fCLIENT_STATUS_SGI40_CAPABLE		0x00000020
-#define fCLIENT_STATUS_TxSTBC_CAPABLE		0x00000040
-#define fCLIENT_STATUS_RxSTBC_CAPABLE		0x00000080
-#define fCLIENT_STATUS_HTC_CAPABLE			0x00000100
-#define fCLIENT_STATUS_RDG_CAPABLE			0x00000200
-#define fCLIENT_STATUS_MCSFEEDBACK_CAPABLE  0x00000400
-#define fCLIENT_STATUS_APSD_CAPABLE         0x00000800	/* UAPSD STATION */
-
-#define fCLIENT_STATUS_RALINK_CHIPSET		0x00100000
-/* */
-/*  STA configuration flags */
-/* */
-
-/* 802.11n Operating Mode Definition. 0-3 also used in ASICUPdateProtect switch case */
-#define HT_NO_PROTECT	0
-#define HT_LEGACY_PROTECT	1
-#define HT_40_PROTECT	2
-#define HT_2040_PROTECT	3
-#define HT_RTSCTS_6M	7
-/*following is our own definition in order to turn on our ASIC protection register in INFRASTRUCTURE. */
-#define HT_ATHEROS	8	/* rt2860c has problem with atheros chip. we need to turn on RTS/CTS . */
-#define HT_FORCERTSCTS	9	/* Force turn on RTS/CTS first. then go to evaluate if this force RTS is necessary. */
-
-/* */
-/* RX Packet Filter control flags. Apply on pAd->PacketFilter */
-/* */
-#define fRX_FILTER_ACCEPT_DIRECT            NDIS_PACKET_TYPE_DIRECTED
-#define fRX_FILTER_ACCEPT_MULTICAST         NDIS_PACKET_TYPE_MULTICAST
-#define fRX_FILTER_ACCEPT_BROADCAST         NDIS_PACKET_TYPE_BROADCAST
-#define fRX_FILTER_ACCEPT_ALL_MULTICAST     NDIS_PACKET_TYPE_ALL_MULTICAST
-#define fRX_FILTER_ACCEPT_PROMISCUOUS       NDIS_PACKET_TYPE_PROMISCUOUS
-
-/* */
-/* Error code section */
-/* */
-/* NDIS_ERROR_CODE_ADAPTER_NOT_FOUND */
-#define ERRLOG_READ_PCI_SLOT_FAILED     0x00000101L
-#define ERRLOG_WRITE_PCI_SLOT_FAILED    0x00000102L
-#define ERRLOG_VENDOR_DEVICE_NOMATCH    0x00000103L
-
-/* NDIS_ERROR_CODE_ADAPTER_DISABLED */
-#define ERRLOG_BUS_MASTER_DISABLED      0x00000201L
-
-/* NDIS_ERROR_CODE_UNSUPPORTED_CONFIGURATION */
-#define ERRLOG_INVALID_SPEED_DUPLEX     0x00000301L
-#define ERRLOG_SET_SECONDARY_FAILED     0x00000302L
-
-/* NDIS_ERROR_CODE_OUT_OF_RESOURCES */
-#define ERRLOG_OUT_OF_MEMORY            0x00000401L
-#define ERRLOG_OUT_OF_SHARED_MEMORY     0x00000402L
-#define ERRLOG_OUT_OF_MAP_REGISTERS     0x00000403L
-#define ERRLOG_OUT_OF_BUFFER_POOL       0x00000404L
-#define ERRLOG_OUT_OF_NDIS_BUFFER       0x00000405L
-#define ERRLOG_OUT_OF_PACKET_POOL       0x00000406L
-#define ERRLOG_OUT_OF_NDIS_PACKET       0x00000407L
-#define ERRLOG_OUT_OF_LOOKASIDE_MEMORY  0x00000408L
-
-/* NDIS_ERROR_CODE_HARDWARE_FAILURE */
-#define ERRLOG_SELFTEST_FAILED          0x00000501L
-#define ERRLOG_INITIALIZE_ADAPTER       0x00000502L
-#define ERRLOG_REMOVE_MINIPORT          0x00000503L
-
-/* NDIS_ERROR_CODE_RESOURCE_CONFLICT */
-#define ERRLOG_MAP_IO_SPACE             0x00000601L
-#define ERRLOG_QUERY_ADAPTER_RESOURCES  0x00000602L
-#define ERRLOG_NO_IO_RESOURCE           0x00000603L
-#define ERRLOG_NO_INTERRUPT_RESOURCE    0x00000604L
-#define ERRLOG_NO_MEMORY_RESOURCE       0x00000605L
-
-/* WDS definition */
-#define	MAX_WDS_ENTRY               4
-#define WDS_PAIRWISE_KEY_OFFSET     60	/* WDS links use pairwise key#60 ~ 63 in ASIC pairwise key table */
-
-#define	WDS_DISABLE_MODE            0
-#define	WDS_RESTRICT_MODE           1
-#define	WDS_BRIDGE_MODE             2
-#define	WDS_REPEATER_MODE           3
-#define	WDS_LAZY_MODE               4
-
-#define MAX_MESH_NUM				0
-
-#define MAX_APCLI_NUM				0
-
-#define MAX_MBSSID_NUM				1
-#ifdef MBSS_SUPPORT
-#undef	MAX_MBSSID_NUM
-#define MAX_MBSSID_NUM				(8 - MAX_MESH_NUM - MAX_APCLI_NUM)
-#endif /* MBSS_SUPPORT // */
-
-/* sanity check for apidx */
-#define MBSS_MR_APIDX_SANITY_CHECK(apidx) \
-    { if (apidx > MAX_MBSSID_NUM) { \
-          DBGPRINT(RT_DEBUG_ERROR, ("%s> Error! apidx = %d > MAX_MBSSID_NUM!\n", __func__, apidx)); \
-	  apidx = MAIN_MBSSID; } }
-
-#define VALID_WCID(_wcid)	((_wcid) > 0 && (_wcid) < MAX_LEN_OF_MAC_TABLE )
-
-#define MAIN_MBSSID                 0
-#define FIRST_MBSSID                1
-
-#define MAX_BEACON_SIZE				512
-/* If the MAX_MBSSID_NUM is larger than 6, */
-/* it shall reserve some WCID space(wcid 222~253) for beacon frames. */
-/* -    these wcid 238~253 are reserved for beacon#6(ra6). */
-/* -    these wcid 222~237 are reserved for beacon#7(ra7). */
-#if defined(MAX_MBSSID_NUM) && (MAX_MBSSID_NUM == 8)
-#define HW_RESERVED_WCID	222
-#elif defined(MAX_MBSSID_NUM) && (MAX_MBSSID_NUM == 7)
-#define HW_RESERVED_WCID	238
-#else
-#define HW_RESERVED_WCID	255
-#endif
-
-/* Then dedicate wcid of DFS and Carrier-Sense. */
-#define DFS_CTS_WCID 		(HW_RESERVED_WCID - 1)
-#define CS_CTS_WCID 		(HW_RESERVED_WCID - 2)
-#define LAST_SPECIFIC_WCID	(HW_RESERVED_WCID - 2)
-
-/* If MAX_MBSSID_NUM is 8, the maximum available wcid for the associated STA is 211. */
-/* If MAX_MBSSID_NUM is 7, the maximum available wcid for the associated STA is 228. */
-#define MAX_AVAILABLE_CLIENT_WCID	(LAST_SPECIFIC_WCID - MAX_MBSSID_NUM - 1)
-
-/* TX need WCID to find Cipher Key */
-/* these wcid 212 ~ 219 are reserved for bc/mc packets if MAX_MBSSID_NUM is 8. */
-#define GET_GroupKey_WCID(__wcid, __bssidx) \
-	{										\
-		__wcid = LAST_SPECIFIC_WCID - (MAX_MBSSID_NUM) + __bssidx;	\
-	}
-
-#define IsGroupKeyWCID(__wcid) (((__wcid) < LAST_SPECIFIC_WCID) && ((__wcid) >= (LAST_SPECIFIC_WCID - (MAX_MBSSID_NUM))))
-
-/* definition to support multiple BSSID */
-#define BSS0                            0
-#define BSS1                            1
-#define BSS2                            2
-#define BSS3                            3
-#define BSS4                            4
-#define BSS5                            5
-#define BSS6                            6
-#define BSS7                            7
-
-/*============================================================ */
-/* Length definitions */
-#define PEER_KEY_NO                     2
-#define MAC_ADDR_LEN                    6
-#define TIMESTAMP_LEN                   8
-#define MAX_LEN_OF_SUPPORTED_RATES      MAX_LENGTH_OF_SUPPORT_RATES	/* 1, 2, 5.5, 11, 6, 9, 12, 18, 24, 36, 48, 54 */
-#define MAX_LEN_OF_KEY                  32	/* 32 octets == 256 bits, Redefine for WPA */
-#define MAX_NUM_OF_CHANNELS             MAX_NUM_OF_CHS	/* 14 channels @2.4G +  12@UNII + 4 @MMAC + 11 @HiperLAN2 + 7 @Japan + 1 as NULL termination */
-#define MAX_NUM_OF_11JCHANNELS             20	/* 14 channels @2.4G +  12@UNII + 4 @MMAC + 11 @HiperLAN2 + 7 @Japan + 1 as NULL termination */
-#define MAX_LEN_OF_SSID                 32
-#define CIPHER_TEXT_LEN                 128
-#define HASH_TABLE_SIZE                 256
-#define MAX_VIE_LEN                     1024	/* New for WPA cipher suite variable IE sizes. */
-#define MAX_SUPPORT_MCS             32
-#define MAX_NUM_OF_BBP_LATCH             140
-
-/*============================================================ */
-/* ASIC WCID Table definition. */
-/*============================================================ */
-#define BSSID_WCID		1	/* in infra mode, always put bssid with this WCID */
-#define MCAST_WCID	0x0
-#define BSS0Mcast_WCID	0x0
-#define BSS1Mcast_WCID	0xf8
-#define BSS2Mcast_WCID	0xf9
-#define BSS3Mcast_WCID	0xfa
-#define BSS4Mcast_WCID	0xfb
-#define BSS5Mcast_WCID	0xfc
-#define BSS6Mcast_WCID	0xfd
-#define BSS7Mcast_WCID	0xfe
-#define RESERVED_WCID		0xff
-
-#define MAX_NUM_OF_ACL_LIST				MAX_NUMBER_OF_ACL
-
-#define MAX_LEN_OF_MAC_TABLE            MAX_NUMBER_OF_MAC	/* if MAX_MBSSID_NUM is 8, this value can't be larger than 211 */
-
-#if MAX_LEN_OF_MAC_TABLE>MAX_AVAILABLE_CLIENT_WCID
-#error MAX_LEN_OF_MAC_TABLE can not be larger than MAX_AVAILABLE_CLIENT_WCID!
-#endif
-
-#define MAX_NUM_OF_WDS_LINK_PERBSSID	            3
-#define MAX_NUM_OF_WDS_LINK	            (MAX_NUM_OF_WDS_LINK_PERBSSID*MAX_MBSSID_NUM)
-#define MAX_NUM_OF_EVENT                MAX_NUMBER_OF_EVENT
-#define WDS_LINK_START_WCID				(MAX_LEN_OF_MAC_TABLE-1)
-
-#define NUM_OF_TID			8
-#define MAX_AID_BA                    4
-#define MAX_LEN_OF_BA_REC_TABLE          ((NUM_OF_TID * MAX_LEN_OF_MAC_TABLE)/2)	/*   (NUM_OF_TID*MAX_AID_BA + 32)        //Block ACK recipient */
-#define MAX_LEN_OF_BA_ORI_TABLE          ((NUM_OF_TID * MAX_LEN_OF_MAC_TABLE)/2)	/*   (NUM_OF_TID*MAX_AID_BA + 32)   // Block ACK originator */
-#define MAX_LEN_OF_BSS_TABLE             64
-#define MAX_REORDERING_MPDU_NUM			 512
-
-/* key related definitions */
-#define SHARE_KEY_NUM                   4
-#define MAX_LEN_OF_SHARE_KEY            16	/* byte count */
-#define MAX_LEN_OF_PEER_KEY             16	/* byte count */
-#define PAIRWISE_KEY_NUM                64	/* in MAC ASIC pairwise key table */
-#define GROUP_KEY_NUM                   4
-#define PMK_LEN                         32
-#define WDS_PAIRWISE_KEY_OFFSET         60	/* WDS links uses pairwise key#60 ~ 63 in ASIC pairwise key table */
-#define	PMKID_NO                        4	/* Number of PMKID saved supported */
-#define MAX_LEN_OF_MLME_BUFFER          2048
-
-/* power status related definitions */
-#define PWR_ACTIVE                      0
-#define PWR_SAVE                        1
-#define PWR_MMPS                        2	/*MIMO power save */
-
-/* Auth and Assoc mode related definitions */
-#define AUTH_MODE_OPEN                  0x00
-#define AUTH_MODE_KEY                   0x01
-
-/* BSS Type definitions */
-#define BSS_ADHOC                       0	/* = Ndis802_11IBSS */
-#define BSS_INFRA                       1	/* = Ndis802_11Infrastructure */
-#define BSS_ANY                         2	/* = Ndis802_11AutoUnknown */
-#define BSS_MONITOR			            3	/* = Ndis802_11Monitor */
-
-/* Reason code definitions */
-#define REASON_RESERVED                 0
-#define REASON_UNSPECIFY                1
-#define REASON_NO_longER_VALID          2
-#define REASON_DEAUTH_STA_LEAVING       3
-#define REASON_DISASSOC_INACTIVE        4
-#define REASON_DISASSPC_AP_UNABLE       5
-#define REASON_CLS2ERR                  6
-#define REASON_CLS3ERR                  7
-#define REASON_DISASSOC_STA_LEAVING     8
-#define REASON_STA_REQ_ASSOC_NOT_AUTH   9
-#define REASON_INVALID_IE               13
-#define REASON_MIC_FAILURE              14
-#define REASON_4_WAY_TIMEOUT            15
-#define REASON_GROUP_KEY_HS_TIMEOUT     16
-#define REASON_IE_DIFFERENT             17
-#define REASON_MCIPHER_NOT_VALID        18
-#define REASON_UCIPHER_NOT_VALID        19
-#define REASON_AKMP_NOT_VALID           20
-#define REASON_UNSUPPORT_RSNE_VER       21
-#define REASON_INVALID_RSNE_CAP         22
-#define REASON_8021X_AUTH_FAIL          23
-#define REASON_CIPHER_SUITE_REJECTED    24
-#define REASON_DECLINED                 37
-
-#define REASON_QOS_UNSPECIFY              32
-#define REASON_QOS_LACK_BANDWIDTH         33
-#define REASON_POOR_CHANNEL_CONDITION     34
-#define REASON_QOS_OUTSIDE_TXOP_LIMITION  35
-#define REASON_QOS_QSTA_LEAVING_QBSS      36
-#define REASON_QOS_UNWANTED_MECHANISM     37
-#define REASON_QOS_MECH_SETUP_REQUIRED    38
-#define REASON_QOS_REQUEST_TIMEOUT        39
-#define REASON_QOS_CIPHER_NOT_SUPPORT     45
-
-/* Status code definitions */
-#define MLME_SUCCESS                    0
-#define MLME_UNSPECIFY_FAIL             1
-#define MLME_CANNOT_SUPPORT_CAP         10
-#define MLME_REASSOC_DENY_ASSOC_EXIST   11
-#define MLME_ASSOC_DENY_OUT_SCOPE       12
-#define MLME_ALG_NOT_SUPPORT            13
-#define MLME_SEQ_NR_OUT_OF_SEQUENCE     14
-#define MLME_REJ_CHALLENGE_FAILURE      15
-#define MLME_REJ_TIMEOUT                  16
-#define MLME_ASSOC_REJ_UNABLE_HANDLE_STA  17
-#define MLME_ASSOC_REJ_DATA_RATE          18
-
-#define MLME_ASSOC_REJ_NO_EXT_RATE        22
-#define MLME_ASSOC_REJ_NO_EXT_RATE_PBCC   23
-#define MLME_ASSOC_REJ_NO_CCK_OFDM        24
-
-#define MLME_QOS_UNSPECIFY                32
-#define MLME_REQUEST_DECLINED             37
-#define MLME_REQUEST_WITH_INVALID_PARAM   38
-#define MLME_INVALID_GROUP_CIPHER	  41
-#define MLME_INVALID_PAIRWISE_CIPHER	  42
-#define MLME_INVALID_AKMP			  43
-#define MLME_DLS_NOT_ALLOW_IN_QBSS        48
-#define MLME_DEST_STA_NOT_IN_QBSS         49
-#define MLME_DEST_STA_IS_NOT_A_QSTA       50
-
-#define MLME_INVALID_FORMAT             0x51
-#define MLME_FAIL_NO_RESOURCE           0x52
-#define MLME_STATE_MACHINE_REJECT       0x53
-#define MLME_MAC_TABLE_FAIL             0x54
-
-/* IE code */
-#define IE_SSID                         0
-#define IE_SUPP_RATES                   1
-#define IE_FH_PARM                      2
-#define IE_DS_PARM                      3
-#define IE_CF_PARM                      4
-#define IE_TIM                          5
-#define IE_IBSS_PARM                    6
-#define IE_COUNTRY                      7	/* 802.11d */
-#define IE_802_11D_REQUEST              10	/* 802.11d */
-#define IE_QBSS_LOAD                    11	/* 802.11e d9 */
-#define IE_EDCA_PARAMETER               12	/* 802.11e d9 */
-#define IE_TSPEC                        13	/* 802.11e d9 */
-#define IE_TCLAS                        14	/* 802.11e d9 */
-#define IE_SCHEDULE                     15	/* 802.11e d9 */
-#define IE_CHALLENGE_TEXT               16
-#define IE_POWER_CONSTRAint             32	/* 802.11h d3.3 */
-#define IE_POWER_CAPABILITY             33	/* 802.11h d3.3 */
-#define IE_TPC_REQUEST                  34	/* 802.11h d3.3 */
-#define IE_TPC_REPORT                   35	/* 802.11h d3.3 */
-#define IE_SUPP_CHANNELS                36	/* 802.11h d3.3 */
-#define IE_CHANNEL_SWITCH_ANNOUNCEMENT  37	/* 802.11h d3.3 */
-#define IE_MEASUREMENT_REQUEST          38	/* 802.11h d3.3 */
-#define IE_MEASUREMENT_REPORT           39	/* 802.11h d3.3 */
-#define IE_QUIET                        40	/* 802.11h d3.3 */
-#define IE_IBSS_DFS                     41	/* 802.11h d3.3 */
-#define IE_ERP                          42	/* 802.11g */
-#define IE_TS_DELAY                     43	/* 802.11e d9 */
-#define IE_TCLAS_PROCESSING             44	/* 802.11e d9 */
-#define IE_QOS_CAPABILITY               46	/* 802.11e d6 */
-#define IE_HT_CAP                       45	/* 802.11n d1. HT CAPABILITY. ELEMENT ID TBD */
-#define IE_AP_CHANNEL_REPORT			51	/* 802.11k d6 */
-#define IE_HT_CAP2                         52	/* 802.11n d1. HT CAPABILITY. ELEMENT ID TBD */
-#define IE_RSN                          48	/* 802.11i d3.0 */
-#define IE_WPA2                         48	/* WPA2 */
-#define IE_EXT_SUPP_RATES               50	/* 802.11g */
-#define IE_SUPP_REG_CLASS               59	/* 802.11y. Supported regulatory classes. */
-#define IE_EXT_CHANNEL_SWITCH_ANNOUNCEMENT	60	/* 802.11n */
-#define IE_ADD_HT                         61	/* 802.11n d1. ADDITIONAL HT CAPABILITY. ELEMENT ID TBD */
-#define IE_ADD_HT2                        53	/* 802.11n d1. ADDITIONAL HT CAPABILITY. ELEMENT ID TBD */
-
-/* For 802.11n D3.03 */
-/*#define IE_NEW_EXT_CHA_OFFSET             62    // 802.11n d1. New extension channel offset element */
-#define IE_SECONDARY_CH_OFFSET		62	/* 802.11n D3.03        Secondary Channel Offset element */
-#define IE_WAPI							68	/* WAPI information element */
-#define IE_2040_BSS_COEXIST               72	/* 802.11n D3.0.3 */
-#define IE_2040_BSS_INTOLERANT_REPORT     73	/* 802.11n D3.03 */
-#define IE_OVERLAPBSS_SCAN_PARM           74	/* 802.11n D3.03 */
-#define IE_EXT_CAPABILITY                127	/* 802.11n D3.03 */
-
-#define IE_WPA                          221	/* WPA */
-#define IE_VENDOR_SPECIFIC              221	/* Wifi WMM (WME) */
-
-#define OUI_BROADCOM_HT              51	/* */
-#define OUI_BROADCOM_HTADD              52	/* */
-#define OUI_PREN_HT_CAP              51	/* */
-#define OUI_PREN_ADD_HT              52	/* */
-
-/* CCX information */
-#define IE_AIRONET_CKIP                 133	/* CCX1.0 ID 85H for CKIP */
-#define IE_AP_TX_POWER                  150	/* CCX 2.0 for AP transmit power */
-#define IE_MEASUREMENT_CAPABILITY       221	/* CCX 2.0 */
-#define IE_CCX_V2                       221
-#define IE_AIRONET_IPADDRESS            149	/* CCX ID 95H for IP Address */
-#define IE_AIRONET_CCKMREASSOC          156	/* CCX ID 9CH for CCKM Reassociation Request element */
-#define CKIP_NEGOTIATION_LENGTH         30
-#define AIRONET_IPADDRESS_LENGTH        10
-#define AIRONET_CCKMREASSOC_LENGTH      24
-
-/* ======================================================== */
-/* MLME state machine definition */
-/* ======================================================== */
-
-/* STA MLME state mahcines */
-#define ASSOC_STATE_MACHINE             1
-#define AUTH_STATE_MACHINE              2
-#define AUTH_RSP_STATE_MACHINE          3
-#define SYNC_STATE_MACHINE              4
-#define MLME_CNTL_STATE_MACHINE         5
-#define WPA_PSK_STATE_MACHINE           6
-/*#define LEAP_STATE_MACHINE              7 */
-#define AIRONET_STATE_MACHINE           8
-#define ACTION_STATE_MACHINE           9
-
-/* AP MLME state machines */
-#define AP_ASSOC_STATE_MACHINE          11
-#define AP_AUTH_STATE_MACHINE           12
-#define AP_SYNC_STATE_MACHINE           14
-#define AP_CNTL_STATE_MACHINE           15
-#define WSC_STATE_MACHINE            17
-#define WSC_UPNP_STATE_MACHINE		    18
-
-#define WPA_STATE_MACHINE			23
-
-/* */
-/* STA's CONTROL/CONNECT state machine: states, events, total function # */
-/* */
-#define CNTL_IDLE                       0
-#define CNTL_WAIT_DISASSOC              1
-#define CNTL_WAIT_JOIN                  2
-#define CNTL_WAIT_REASSOC               3
-#define CNTL_WAIT_START                 4
-#define CNTL_WAIT_AUTH                  5
-#define CNTL_WAIT_ASSOC                 6
-#define CNTL_WAIT_AUTH2                 7
-#define CNTL_WAIT_OID_LIST_SCAN         8
-#define CNTL_WAIT_OID_DISASSOC          9
-#ifdef RTMP_MAC_USB
-#define CNTL_WAIT_SCAN_FOR_CONNECT      10
-#endif /* RTMP_MAC_USB // */
-
-#define MT2_ASSOC_CONF                  34
-#define MT2_AUTH_CONF                   35
-#define MT2_DEAUTH_CONF                 36
-#define MT2_DISASSOC_CONF               37
-#define MT2_REASSOC_CONF                38
-#define MT2_PWR_MGMT_CONF               39
-#define MT2_JOIN_CONF                   40
-#define MT2_SCAN_CONF                   41
-#define MT2_START_CONF                  42
-#define MT2_GET_CONF                    43
-#define MT2_SET_CONF                    44
-#define MT2_RESET_CONF                  45
-#define MT2_FT_OTD_CONF					46
-#define MT2_MLME_ROAMING_REQ            52
-
-#define CNTL_FUNC_SIZE                  1
-
-/* */
-/* STA's ASSOC state machine: states, events, total function # */
-/* */
-#define ASSOC_IDLE                      0
-#define ASSOC_WAIT_RSP                  1
-#define REASSOC_WAIT_RSP                2
-#define DISASSOC_WAIT_RSP               3
-#define MAX_ASSOC_STATE                 4
-
-#define ASSOC_MACHINE_BASE              0
-#define MT2_MLME_ASSOC_REQ              0
-#define MT2_MLME_REASSOC_REQ            1
-#define MT2_MLME_DISASSOC_REQ           2
-#define MT2_PEER_DISASSOC_REQ           3
-#define MT2_PEER_ASSOC_REQ              4
-#define MT2_PEER_ASSOC_RSP              5
-#define MT2_PEER_REASSOC_REQ            6
-#define MT2_PEER_REASSOC_RSP            7
-#define MT2_DISASSOC_TIMEOUT            8
-#define MT2_ASSOC_TIMEOUT               9
-#define MT2_REASSOC_TIMEOUT             10
-#define MAX_ASSOC_MSG                   11
-
-#define ASSOC_FUNC_SIZE                 (MAX_ASSOC_STATE * MAX_ASSOC_MSG)
-
-/* */
-/* ACT state machine: states, events, total function # */
-/* */
-#define ACT_IDLE                      0
-#define MAX_ACT_STATE                 1
-
-#define ACT_MACHINE_BASE              0
-
-/*Those PEER_xx_CATE number is based on real Categary value in IEEE spec. Please do not modify it by your self. */
-/*Category */
-#define MT2_PEER_SPECTRUM_CATE              0
-#define MT2_PEER_QOS_CATE              1
-#define MT2_PEER_DLS_CATE             2
-#define MT2_PEER_BA_CATE             3
-#define MT2_PEER_PUBLIC_CATE             4
-#define MT2_PEER_RM_CATE             5
-/* "FT_CATEGORY_BSS_TRANSITION equal to 6" is defined file of "dot11r_ft.h" */
-#define MT2_PEER_HT_CATE             7	/*      7.4.7 */
-#define MAX_PEER_CATE_MSG                   7
-
-#define MT2_MLME_ADD_BA_CATE             8
-#define MT2_MLME_ORI_DELBA_CATE             9
-#define MT2_MLME_REC_DELBA_CATE             10
-#define MT2_MLME_QOS_CATE              11
-#define MT2_MLME_DLS_CATE             12
-#define MT2_ACT_INVALID             13
-#define MAX_ACT_MSG                   14
-
-/*Category field */
-#define CATEGORY_SPECTRUM		0
-#define CATEGORY_QOS			1
-#define CATEGORY_DLS			2
-#define CATEGORY_BA			3
-#define CATEGORY_PUBLIC		4
-#define CATEGORY_RM			5
-#define CATEGORY_HT			7
-
-/* DLS Action frame definition */
-#define ACTION_DLS_REQUEST			0
-#define ACTION_DLS_RESPONSE			1
-#define ACTION_DLS_TEARDOWN			2
-
-/*Spectrum  Action field value 802.11h 7.4.1 */
-#define SPEC_MRQ	0	/* Request */
-#define SPEC_MRP	1	/*Report */
-#define SPEC_TPCRQ	2
-#define SPEC_TPCRP	3
-#define SPEC_CHANNEL_SWITCH	4
-
-/*BA  Action field value */
-#define ADDBA_REQ	0
-#define ADDBA_RESP	1
-#define DELBA   2
-
-/*Public's  Action field value in Public Category.  Some in 802.11y and some in 11n */
-#define ACTION_BSS_2040_COEXIST				0	/* 11n */
-#define ACTION_DSE_ENABLEMENT					1	/* 11y D9.0 */
-#define ACTION_DSE_DEENABLEMENT				2	/* 11y D9.0 */
-#define ACTION_DSE_REG_LOCATION_ANNOUNCE	3	/* 11y D9.0 */
-#define ACTION_EXT_CH_SWITCH_ANNOUNCE		4	/* 11y D9.0 */
-#define ACTION_DSE_MEASUREMENT_REQ			5	/* 11y D9.0 */
-#define ACTION_DSE_MEASUREMENT_REPORT		6	/* 11y D9.0 */
-#define ACTION_MEASUREMENT_PILOT_ACTION		7	/* 11y D9.0 */
-#define ACTION_DSE_POWER_CONSTRAINT			8	/* 11y D9.0 */
-
-/*HT  Action field value */
-#define NOTIFY_BW_ACTION				0
-#define SMPS_ACTION						1
-#define PSMP_ACTION   					2
-#define SETPCO_ACTION					3
-#define MIMO_CHA_MEASURE_ACTION			4
-#define MIMO_N_BEACONFORM				5
-#define MIMO_BEACONFORM					6
-#define ANTENNA_SELECT					7
-#define HT_INFO_EXCHANGE				8
-
-#define ACT_FUNC_SIZE                 (MAX_ACT_STATE * MAX_ACT_MSG)
-/* */
-/* STA's AUTHENTICATION state machine: states, events, total function # */
-/* */
-#define AUTH_REQ_IDLE                   0
-#define AUTH_WAIT_SEQ2                  1
-#define AUTH_WAIT_SEQ4                  2
-#define MAX_AUTH_STATE                  3
-
-#define AUTH_MACHINE_BASE               0
-#define MT2_MLME_AUTH_REQ               0
-#define MT2_PEER_AUTH_EVEN              1
-#define MT2_AUTH_TIMEOUT                2
-#define MAX_AUTH_MSG                    3
-
-#define AUTH_FUNC_SIZE                  (MAX_AUTH_STATE * MAX_AUTH_MSG)
-
-/* */
-/* STA's AUTH_RSP state machine: states, events, total function # */
-/* */
-#define AUTH_RSP_IDLE                   0
-#define AUTH_RSP_WAIT_CHAL              1
-#define MAX_AUTH_RSP_STATE              2
-
-#define AUTH_RSP_MACHINE_BASE           0
-#define MT2_AUTH_CHALLENGE_TIMEOUT      0
-#define MT2_PEER_AUTH_ODD               1
-#define MT2_PEER_DEAUTH                 2
-#define MAX_AUTH_RSP_MSG                3
-
-#define AUTH_RSP_FUNC_SIZE              (MAX_AUTH_RSP_STATE * MAX_AUTH_RSP_MSG)
-
-/* */
-/* STA's SYNC state machine: states, events, total function # */
-/* */
-#define SYNC_IDLE                       0	/* merge NO_BSS,IBSS_IDLE,IBSS_ACTIVE and BSS in to 1 state */
-#define JOIN_WAIT_BEACON                1
-#define SCAN_LISTEN                     2
-#define MAX_SYNC_STATE                  3
-
-#define SYNC_MACHINE_BASE               0
-#define MT2_MLME_SCAN_REQ               0
-#define MT2_MLME_JOIN_REQ               1
-#define MT2_MLME_START_REQ              2
-#define MT2_PEER_BEACON                 3
-#define MT2_PEER_PROBE_RSP              4
-#define MT2_PEER_ATIM                   5
-#define MT2_SCAN_TIMEOUT                6
-#define MT2_BEACON_TIMEOUT              7
-#define MT2_ATIM_TIMEOUT                8
-#define MT2_PEER_PROBE_REQ              9
-#define MAX_SYNC_MSG                    10
-
-#define SYNC_FUNC_SIZE                  (MAX_SYNC_STATE * MAX_SYNC_MSG)
-
-/*Messages for the DLS state machine */
-#define DLS_IDLE						0
-#define MAX_DLS_STATE					1
-
-#define DLS_MACHINE_BASE				0
-#define MT2_MLME_DLS_REQ			    0
-#define MT2_PEER_DLS_REQ			    1
-#define MT2_PEER_DLS_RSP			    2
-#define MT2_MLME_DLS_TEAR_DOWN		    3
-#define MT2_PEER_DLS_TEAR_DOWN		    4
-#define MAX_DLS_MSG				        5
-
-#define DLS_FUNC_SIZE					(MAX_DLS_STATE * MAX_DLS_MSG)
-
-/* */
-/* WSC State machine: states, events, total function # */
-/* */
-
-/* */
-/* AP's CONTROL/CONNECT state machine: states, events, total function # */
-/* */
-#define AP_CNTL_FUNC_SIZE               1
-
-/* */
-/* AP's ASSOC state machine: states, events, total function # */
-/* */
-#define AP_ASSOC_IDLE                   0
-#define AP_MAX_ASSOC_STATE              1
-
-#define AP_ASSOC_MACHINE_BASE           0
-#define APMT2_MLME_DISASSOC_REQ         0
-#define APMT2_PEER_DISASSOC_REQ         1
-#define APMT2_PEER_ASSOC_REQ            2
-#define APMT2_PEER_REASSOC_REQ          3
-#define APMT2_CLS3ERR                   4
-#define AP_MAX_ASSOC_MSG                5
-
-#define AP_ASSOC_FUNC_SIZE              (AP_MAX_ASSOC_STATE * AP_MAX_ASSOC_MSG)
-
-/* */
-/* AP's AUTHENTICATION state machine: states, events, total function # */
-/* */
-#define AP_AUTH_REQ_IDLE                0
-#define AP_MAX_AUTH_STATE               1
-
-#define AP_AUTH_MACHINE_BASE            0
-#define APMT2_MLME_DEAUTH_REQ           0
-#define APMT2_CLS2ERR                   1
-#define APMT2_PEER_DEAUTH               2
-#define APMT2_PEER_AUTH_REQ				3
-#define APMT2_PEER_AUTH_CONFIRM			4
-#define AP_MAX_AUTH_MSG                 5
-
-#define AP_AUTH_FUNC_SIZE               (AP_MAX_AUTH_STATE * AP_MAX_AUTH_MSG)
-
-/* */
-/* AP's SYNC state machine: states, events, total function # */
-/* */
-#define AP_SYNC_IDLE                    0
-#define AP_SCAN_LISTEN					1
-#define AP_MAX_SYNC_STATE               2
-
-#define AP_SYNC_MACHINE_BASE            0
-#define APMT2_PEER_PROBE_REQ            0
-#define APMT2_PEER_BEACON               1
-#define APMT2_MLME_SCAN_REQ				2
-#define APMT2_PEER_PROBE_RSP			3
-#define APMT2_SCAN_TIMEOUT				4
-#define APMT2_MLME_SCAN_CNCL			5
-#define AP_MAX_SYNC_MSG                 6
-
-#define AP_SYNC_FUNC_SIZE               (AP_MAX_SYNC_STATE * AP_MAX_SYNC_MSG)
-
-/* */
-/* Common WPA state machine: states, events, total function # */
-/* */
-#define WPA_PTK                      0
-#define MAX_WPA_PTK_STATE            1
-
-#define WPA_MACHINE_BASE             0
-#define MT2_EAPPacket                0
-#define MT2_EAPOLStart               1
-#define MT2_EAPOLLogoff              2
-#define MT2_EAPOLKey                 3
-#define MT2_EAPOLASFAlert            4
-#define MAX_WPA_MSG                  5
-
-#define WPA_FUNC_SIZE                (MAX_WPA_PTK_STATE * MAX_WPA_MSG)
-
-/* ============================================================================= */
-
-/* value domain of 802.11 header FC.Tyte, which is b3..b2 of the 1st-byte of MAC header */
-#define BTYPE_MGMT                  0
-#define BTYPE_CNTL                  1
-#define BTYPE_DATA                  2
-
-/* value domain of 802.11 MGMT frame's FC.subtype, which is b7..4 of the 1st-byte of MAC header */
-#define SUBTYPE_ASSOC_REQ           0
-#define SUBTYPE_ASSOC_RSP           1
-#define SUBTYPE_REASSOC_REQ         2
-#define SUBTYPE_REASSOC_RSP         3
-#define SUBTYPE_PROBE_REQ           4
-#define SUBTYPE_PROBE_RSP           5
-#define SUBTYPE_BEACON              8
-#define SUBTYPE_ATIM                9
-#define SUBTYPE_DISASSOC            10
-#define SUBTYPE_AUTH                11
-#define SUBTYPE_DEAUTH              12
-#define SUBTYPE_ACTION              13
-#define SUBTYPE_ACTION_NO_ACK              14
-
-/* value domain of 802.11 CNTL frame's FC.subtype, which is b7..4 of the 1st-byte of MAC header */
-#define SUBTYPE_WRAPPER       	7
-#define SUBTYPE_BLOCK_ACK_REQ       8
-#define SUBTYPE_BLOCK_ACK           9
-#define SUBTYPE_PS_POLL             10
-#define SUBTYPE_RTS                 11
-#define SUBTYPE_CTS                 12
-#define SUBTYPE_ACK                 13
-#define SUBTYPE_CFEND               14
-#define SUBTYPE_CFEND_CFACK         15
-
-/* value domain of 802.11 DATA frame's FC.subtype, which is b7..4 of the 1st-byte of MAC header */
-#define SUBTYPE_DATA                0
-#define SUBTYPE_DATA_CFACK          1
-#define SUBTYPE_DATA_CFPOLL         2
-#define SUBTYPE_DATA_CFACK_CFPOLL   3
-#define SUBTYPE_NULL_FUNC           4
-#define SUBTYPE_CFACK               5
-#define SUBTYPE_CFPOLL              6
-#define SUBTYPE_CFACK_CFPOLL        7
-#define SUBTYPE_QDATA               8
-#define SUBTYPE_QDATA_CFACK         9
-#define SUBTYPE_QDATA_CFPOLL        10
-#define SUBTYPE_QDATA_CFACK_CFPOLL  11
-#define SUBTYPE_QOS_NULL            12
-#define SUBTYPE_QOS_CFACK           13
-#define SUBTYPE_QOS_CFPOLL          14
-#define SUBTYPE_QOS_CFACK_CFPOLL    15
-
-/* ACK policy of QOS Control field bit 6:5 */
-#define NORMAL_ACK                  0x00	/* b6:5 = 00 */
-#define NO_ACK                      0x20	/* b6:5 = 01 */
-#define NO_EXPLICIT_ACK             0x40	/* b6:5 = 10 */
-#define BLOCK_ACK                   0x60	/* b6:5 = 11 */
-
-/* */
-/* rtmp_data.c uses this definition */
-/* */
-#define LENGTH_802_11               24
-#define LENGTH_802_11_AND_H         30
-#define LENGTH_802_11_CRC_H         34
-#define LENGTH_802_11_CRC           28
-#define LENGTH_802_11_WITH_ADDR4    30
-#define LENGTH_802_3                14
-#define LENGTH_802_3_TYPE           2
-#define LENGTH_802_1_H              8
-#define LENGTH_EAPOL_H              4
-#define LENGTH_WMMQOS_H				2
-#define LENGTH_CRC                  4
-#define MAX_SEQ_NUMBER              0x0fff
-#define LENGTH_802_3_NO_TYPE		12
-#define LENGTH_802_1Q				4	/* VLAN related */
-
-/* STA_CSR4.field.TxResult */
-#define TX_RESULT_SUCCESS           0
-#define TX_RESULT_ZERO_LENGTH       1
-#define TX_RESULT_UNDER_RUN         2
-#define TX_RESULT_OHY_ERROR         4
-#define TX_RESULT_RETRY_FAIL        6
-
-/* All PHY rate summary in TXD */
-/* Preamble MODE in TxD */
-#define MODE_CCK	0
-#define MODE_OFDM   1
-#define MODE_HTMIX	2
-#define MODE_HTGREENFIELD	3
-
-/* MCS for CCK.  BW.SGI.STBC are reserved */
-#define MCS_longP_RATE_1                      0	/* long preamble CCK 1Mbps */
-#define MCS_longP_RATE_2                      1	/* long preamble CCK 1Mbps */
-#define MCS_longP_RATE_5_5                    2
-#define MCS_longP_RATE_11                     3
-#define MCS_SHORTP_RATE_1                      4	/* long preamble CCK 1Mbps. short is forbidden in 1Mbps */
-#define MCS_SHORTP_RATE_2                      5	/* short preamble CCK 2Mbps */
-#define MCS_SHORTP_RATE_5_5                    6
-#define MCS_SHORTP_RATE_11                     7
-/* To send duplicate legacy OFDM. set BW=BW_40.  SGI.STBC are reserved */
-#define MCS_RATE_6                      0	/* legacy OFDM */
-#define MCS_RATE_9                      1	/* OFDM */
-#define MCS_RATE_12                     2	/* OFDM */
-#define MCS_RATE_18                     3	/* OFDM */
-#define MCS_RATE_24                     4	/* OFDM */
-#define MCS_RATE_36                     5	/* OFDM */
-#define MCS_RATE_48                     6	/* OFDM */
-#define MCS_RATE_54                     7	/* OFDM */
-/* HT */
-#define MCS_0		0	/* 1S */
-#define MCS_1		1
-#define MCS_2		2
-#define MCS_3		3
-#define MCS_4		4
-#define MCS_5		5
-#define MCS_6		6
-#define MCS_7		7
-#define MCS_8		8	/* 2S */
-#define MCS_9		9
-#define MCS_10		10
-#define MCS_11		11
-#define MCS_12		12
-#define MCS_13		13
-#define MCS_14		14
-#define MCS_15		15
-#define MCS_16		16	/* 3*3 */
-#define MCS_17		17
-#define MCS_18		18
-#define MCS_19		19
-#define MCS_20		20
-#define MCS_21		21
-#define MCS_22		22
-#define MCS_23		23
-#define MCS_32		32
-#define MCS_AUTO		33
-
-/* OID_HTPHYMODE */
-/* MODE */
-#define HTMODE_MM	0
-#define HTMODE_GF	1
-
-/* Fixed Tx MODE - HT, CCK or OFDM */
-#define FIXED_TXMODE_HT		0
-#define FIXED_TXMODE_CCK	1
-#define FIXED_TXMODE_OFDM 	2
-/* BW */
-#define BW_20		BAND_WIDTH_20
-#define BW_40		BAND_WIDTH_40
-#define BW_BOTH		BAND_WIDTH_BOTH
-#define BW_10		BAND_WIDTH_10	/* 802.11j has 10MHz. This definition is for internal usage. doesn't fill in the IE or other field. */
-
-/* SHORTGI */
-#define GI_400		GAP_INTERVAL_400	/* only support in HT mode */
-#define GI_BOTH		GAP_INTERVAL_BOTH
-#define GI_800		GAP_INTERVAL_800
-/* STBC */
-#define STBC_NONE	0
-#define STBC_USE	1	/* limited use in rt2860b phy */
-#define RXSTBC_ONE	1	/* rx support of one spatial stream */
-#define RXSTBC_TWO	2	/* rx support of 1 and 2 spatial stream */
-#define RXSTBC_THR	3	/* rx support of 1~3 spatial stream */
-/* MCS FEEDBACK */
-#define MCSFBK_NONE	0	/* not support mcs feedback / */
-#define MCSFBK_RSV	1	/* reserved */
-#define MCSFBK_UNSOLICIT	2	/* only support unsolict mcs feedback */
-#define MCSFBK_MRQ	3	/* response to both MRQ and unsolict mcs feedback */
-
-/* MIMO power safe */
-#define	MMPS_STATIC	0
-#define	MMPS_DYNAMIC		1
-#define   MMPS_RSV		2
-#define MMPS_ENABLE		3
-
-/* A-MSDU size */
-#define	AMSDU_0	0
-#define	AMSDU_1		1
-
-/* MCS use 7 bits */
-#define TXRATEMIMO		0x80
-#define TXRATEMCS		0x7F
-#define TXRATEOFDM		0x7F
-#define RATE_1                      0
-#define RATE_2                      1
-#define RATE_5_5                    2
-#define RATE_11                     3
-#define RATE_6                      4	/* OFDM */
-#define RATE_9                      5	/* OFDM */
-#define RATE_12                     6	/* OFDM */
-#define RATE_18                     7	/* OFDM */
-#define RATE_24                     8	/* OFDM */
-#define RATE_36                     9	/* OFDM */
-#define RATE_48                     10	/* OFDM */
-#define RATE_54                     11	/* OFDM */
-#define RATE_FIRST_OFDM_RATE        RATE_6
-#define RATE_LAST_OFDM_RATE        	RATE_54
-#define RATE_6_5                    12	/* HT mix */
-#define RATE_13                     13	/* HT mix */
-#define RATE_19_5                   14	/* HT mix */
-#define RATE_26                     15	/* HT mix */
-#define RATE_39                     16	/* HT mix */
-#define RATE_52                     17	/* HT mix */
-#define RATE_58_5                   18	/* HT mix */
-#define RATE_65                     19	/* HT mix */
-#define RATE_78                     20	/* HT mix */
-#define RATE_104                    21	/* HT mix */
-#define RATE_117                    22	/* HT mix */
-#define RATE_130                    23	/* HT mix */
-/*#define RATE_AUTO_SWITCH            255 // for StaCfg.FixedTxRate only */
-#define HTRATE_0                      12
-#define RATE_FIRST_MM_RATE        HTRATE_0
-#define RATE_FIRST_HT_RATE        HTRATE_0
-#define RATE_LAST_HT_RATE        HTRATE_0
-
-/* pTxWI->txop */
-#define IFS_HTTXOP                 0	/* The txop will be handles by ASIC. */
-#define IFS_PIFS                    1
-#define IFS_SIFS                    2
-#define IFS_BACKOFF                 3
-
-/* pTxD->RetryMode */
-#define long_RETRY                  1
-#define SHORT_RETRY                 0
-
-/* Country Region definition */
-#define REGION_MINIMUM_BG_BAND            0
-#define REGION_0_BG_BAND                  0	/* 1-11 */
-#define REGION_1_BG_BAND                  1	/* 1-13 */
-#define REGION_2_BG_BAND                  2	/* 10-11 */
-#define REGION_3_BG_BAND                  3	/* 10-13 */
-#define REGION_4_BG_BAND                  4	/* 14 */
-#define REGION_5_BG_BAND                  5	/* 1-14 */
-#define REGION_6_BG_BAND                  6	/* 3-9 */
-#define REGION_7_BG_BAND                  7	/* 5-13 */
-#define REGION_31_BG_BAND                 31	/* 5-13 */
-#define REGION_MAXIMUM_BG_BAND            7
-
-#define REGION_MINIMUM_A_BAND             0
-#define REGION_0_A_BAND                   0	/* 36, 40, 44, 48, 52, 56, 60, 64, 149, 153, 157, 161, 165 */
-#define REGION_1_A_BAND                   1	/* 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140 */
-#define REGION_2_A_BAND                   2	/* 36, 40, 44, 48, 52, 56, 60, 64 */
-#define REGION_3_A_BAND                   3	/* 52, 56, 60, 64, 149, 153, 157, 161 */
-#define REGION_4_A_BAND                   4	/* 149, 153, 157, 161, 165 */
-#define REGION_5_A_BAND                   5	/* 149, 153, 157, 161 */
-#define REGION_6_A_BAND                   6	/* 36, 40, 44, 48 */
-#define REGION_7_A_BAND                   7	/* 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 149, 153, 157, 161, 165, 169, 173 */
-#define REGION_8_A_BAND                   8	/* 52, 56, 60, 64 */
-#define REGION_9_A_BAND                   9	/* 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 132, 136, 140, 149, 153, 157, 161, 165 */
-#define REGION_10_A_BAND                  10	/* 36, 40, 44, 48, 149, 153, 157, 161, 165 */
-#define REGION_11_A_BAND                  11	/* 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 149, 153, 157, 161 */
-#define REGION_12_A_BAND                  12	/* 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140 */
-#define REGION_13_A_BAND                  13	/* 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 149, 153, 157, 161 */
-#define REGION_14_A_BAND                  14	/* 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 136, 140, 149, 153, 157, 161, 165 */
-#define REGION_15_A_BAND                  15	/* 149, 153, 157, 161, 165, 169, 173 */
-#define REGION_MAXIMUM_A_BAND             15
-
-/* pTxD->CipherAlg */
-#define CIPHER_NONE                 0
-#define CIPHER_WEP64                1
-#define CIPHER_WEP128               2
-#define CIPHER_TKIP                 3
-#define CIPHER_AES                  4
-#define CIPHER_CKIP64               5
-#define CIPHER_CKIP128              6
-#define CIPHER_TKIP_NO_MIC          7	/* MIC appended by driver: not a valid value in hardware key table */
-#define CIPHER_SMS4					8
-
-/* LED Status. */
-#define LED_LINK_DOWN               0
-#define LED_LINK_UP                 1
-#define LED_RADIO_OFF               2
-#define LED_RADIO_ON                3
-#define LED_HALT                    4
-#define LED_WPS                     5
-#define LED_ON_SITE_SURVEY          6
-#define LED_POWER_UP                7
-
-/* value domain of pAd->LedCntl.LedMode and E2PROM */
-#define LED_MODE_DEFAULT            0
-#define LED_MODE_TWO_LED			1
-/*#define LED_MODE_SIGNAL_STREGTH               8  // EEPROM define =8 */
-#define LED_MODE_SIGNAL_STREGTH		0x40	/* EEPROM define = 64 */
-
-/* RC4 init value, used fro WEP & TKIP */
-#define PPPINITFCS32                0xffffffff	/* Initial FCS value */
-
-/* value domain of pAd->StaCfg.PortSecured. 802.1X controlled port definition */
-#define WPA_802_1X_PORT_SECURED     1
-#define WPA_802_1X_PORT_NOT_SECURED 2
-
-#define PAIRWISE_KEY                1
-#define GROUP_KEY                   2
-
-/*definition of DRS */
-#define MAX_STEP_OF_TX_RATE_SWITCH	32
-
-/* pre-allocated free NDIS PACKET/BUFFER poll for internal usage */
-#define MAX_NUM_OF_FREE_NDIS_PACKET 128
-
-/*Block ACK */
-#define MAX_TX_REORDERBUF   64
-#define MAX_RX_REORDERBUF   64
-#define DEFAULT_TX_TIMEOUT   30
-#define DEFAULT_RX_TIMEOUT   30
-
-/* definition of Recipient or Originator */
-#define I_RECIPIENT                  TRUE
-#define I_ORIGINATOR                   FALSE
-
-#define DEFAULT_BBP_TX_POWER        0
-#define DEFAULT_RF_TX_POWER         5
-
-#define MAX_INI_BUFFER_SIZE			4096
-#define MAX_PARAM_BUFFER_SIZE		(2048)	/* enough for ACL (18*64) */
-											/*18 : the length of Mac address acceptable format "01:02:03:04:05:06;") */
-											/*64 : MAX_NUM_OF_ACL_LIST */
-/* definition of pAd->OpMode */
-#define OPMODE_STA                  0
-#define OPMODE_AP                   1
-/*#define OPMODE_L3_BRG               2       // as AP and STA at the same time */
-
-/* ========================= AP rtmp_def.h =========================== */
-/* value domain for pAd->EventTab.Log[].Event */
-#define EVENT_RESET_ACCESS_POint    0	/* Log = "hh:mm:ss   Restart Access Point" */
-#define EVENT_ASSOCIATED            1	/* Log = "hh:mm:ss   STA 00:01:02:03:04:05 associated" */
-#define EVENT_DISASSOCIATED         2	/* Log = "hh:mm:ss   STA 00:01:02:03:04:05 left this BSS" */
-#define EVENT_AGED_OUT              3	/* Log = "hh:mm:ss   STA 00:01:02:03:04:05 was aged-out and removed from this BSS" */
-#define EVENT_COUNTER_M             4
-#define EVENT_INVALID_PSK           5
-#define EVENT_MAX_EVENT_TYPE        6
-/* ==== end of AP rtmp_def.h ============ */
-
-/* definition RSSI Number */
-#define RSSI_0					0
-#define RSSI_1					1
-#define RSSI_2					2
-
-/* definition of radar detection */
-#define RD_NORMAL_MODE				0	/* Not found radar signal */
-#define RD_SWITCHING_MODE			1	/* Found radar signal, and doing channel switch */
-#define RD_SILENCE_MODE				2	/* After channel switch, need to be silence a while to ensure radar not found */
-
-/*Driver defined cid for mapping status and command. */
-#define  SLEEPCID	0x11
-#define  WAKECID	0x22
-#define  QUERYPOWERCID	0x33
-#define  OWNERMCU	0x1
-#define  OWNERCPU	0x0
-
-/* MBSSID definition */
-#define ENTRY_NOT_FOUND             0xFF
-
-/* After Linux 2.6.9,
- * VLAN module use Private (from user) interface flags (netdevice->priv_flags).
- * #define IFF_802_1Q_VLAN 0x1         --    802.1Q VLAN device.  in if.h
- * ref to ip_sabotage_out() [ out->priv_flags & IFF_802_1Q_VLAN ] in br_netfilter.c
- *
- * For this reason, we MUST use EVEN value in priv_flags
- */
-#define INT_MAIN                    0x0100
-#define INT_MBSSID                  0x0200
-#define INT_WDS                     0x0300
-#define INT_APCLI                   0x0400
-#define INT_MESH                   	0x0500
-
-#define INF_MAIN_DEV_NAME		"wlan"
-#define INF_MBSSID_DEV_NAME		"ra"
-#define INF_WDS_DEV_NAME		"wds"
-#define INF_APCLI_DEV_NAME		"apcli"
-#define INF_MESH_DEV_NAME		"mesh"
-
-/* WEP Key TYPE */
-#define WEP_HEXADECIMAL_TYPE    0
-#define WEP_ASCII_TYPE          1
-
-/* WIRELESS EVENTS definition */
-/* Max number of char in custom event, refer to wireless_tools.28/wireless.20.h */
-#define IW_CUSTOM_MAX_LEN				  			255	/* In bytes */
-
-/* For system event - start */
-#define	IW_SYS_EVENT_FLAG_START                     0x0200
-#define	IW_ASSOC_EVENT_FLAG                         0x0200
-#define	IW_DISASSOC_EVENT_FLAG                      0x0201
-#define	IW_DEAUTH_EVENT_FLAG                      	0x0202
-#define	IW_AGEOUT_EVENT_FLAG                      	0x0203
-#define	IW_COUNTER_MEASURES_EVENT_FLAG              0x0204
-#define	IW_REPLAY_COUNTER_DIFF_EVENT_FLAG           0x0205
-#define	IW_RSNIE_DIFF_EVENT_FLAG           			0x0206
-#define	IW_MIC_DIFF_EVENT_FLAG           			0x0207
-#define IW_ICV_ERROR_EVENT_FLAG						0x0208
-#define IW_MIC_ERROR_EVENT_FLAG						0x0209
-#define IW_GROUP_HS_TIMEOUT_EVENT_FLAG				0x020A
-#define	IW_PAIRWISE_HS_TIMEOUT_EVENT_FLAG			0x020B
-#define IW_RSNIE_SANITY_FAIL_EVENT_FLAG				0x020C
-#define IW_SET_KEY_DONE_WPA1_EVENT_FLAG				0x020D
-#define IW_SET_KEY_DONE_WPA2_EVENT_FLAG				0x020E
-#define IW_STA_LINKUP_EVENT_FLAG					0x020F
-#define IW_STA_LINKDOWN_EVENT_FLAG					0x0210
-#define IW_SCAN_COMPLETED_EVENT_FLAG				0x0211
-#define IW_SCAN_ENQUEUE_FAIL_EVENT_FLAG				0x0212
-/* if add new system event flag, please update the IW_SYS_EVENT_FLAG_END */
-#define	IW_SYS_EVENT_FLAG_END                       0x0212
-#define	IW_SYS_EVENT_TYPE_NUM						(IW_SYS_EVENT_FLAG_END - IW_SYS_EVENT_FLAG_START + 1)
-/* For system event - end */
-
-/* For spoof attack event - start */
-#define	IW_SPOOF_EVENT_FLAG_START                   0x0300
-#define IW_CONFLICT_SSID_EVENT_FLAG					0x0300
-#define IW_SPOOF_ASSOC_RESP_EVENT_FLAG				0x0301
-#define IW_SPOOF_REASSOC_RESP_EVENT_FLAG			0x0302
-#define IW_SPOOF_PROBE_RESP_EVENT_FLAG				0x0303
-#define IW_SPOOF_BEACON_EVENT_FLAG					0x0304
-#define IW_SPOOF_DISASSOC_EVENT_FLAG				0x0305
-#define IW_SPOOF_AUTH_EVENT_FLAG					0x0306
-#define IW_SPOOF_DEAUTH_EVENT_FLAG					0x0307
-#define IW_SPOOF_UNKNOWN_MGMT_EVENT_FLAG			0x0308
-#define IW_REPLAY_ATTACK_EVENT_FLAG					0x0309
-/* if add new spoof attack event flag, please update the IW_SPOOF_EVENT_FLAG_END */
-#define	IW_SPOOF_EVENT_FLAG_END                     0x0309
-#define	IW_SPOOF_EVENT_TYPE_NUM						(IW_SPOOF_EVENT_FLAG_END - IW_SPOOF_EVENT_FLAG_START + 1)
-/* For spoof attack event - end */
-
-/* For flooding attack event - start */
-#define	IW_FLOOD_EVENT_FLAG_START                   0x0400
-#define IW_FLOOD_AUTH_EVENT_FLAG					0x0400
-#define IW_FLOOD_ASSOC_REQ_EVENT_FLAG				0x0401
-#define IW_FLOOD_REASSOC_REQ_EVENT_FLAG				0x0402
-#define IW_FLOOD_PROBE_REQ_EVENT_FLAG				0x0403
-#define IW_FLOOD_DISASSOC_EVENT_FLAG				0x0404
-#define IW_FLOOD_DEAUTH_EVENT_FLAG					0x0405
-#define IW_FLOOD_EAP_REQ_EVENT_FLAG					0x0406
-/* if add new flooding attack event flag, please update the IW_FLOOD_EVENT_FLAG_END */
-#define	IW_FLOOD_EVENT_FLAG_END                   	0x0406
-#define	IW_FLOOD_EVENT_TYPE_NUM						(IW_FLOOD_EVENT_FLAG_END - IW_FLOOD_EVENT_FLAG_START + 1)
-/* For flooding attack - end */
-
-/* End - WIRELESS EVENTS definition */
-
-/* definition for DLS, kathy */
-#define	MAX_NUM_OF_INIT_DLS_ENTRY   1
-#define	MAX_NUM_OF_DLS_ENTRY        MAX_NUMBER_OF_DLS_ENTRY
-
-/*Block ACK, kathy */
-#define MAX_TX_REORDERBUF		64
-#define MAX_RX_REORDERBUF		64
-#define DEFAULT_TX_TIMEOUT		30
-#define DEFAULT_RX_TIMEOUT		30
-#define MAX_BARECI_SESSION		8
-
-#ifndef IW_ESSID_MAX_SIZE
-/* Maximum size of the ESSID and pAd->nickname strings */
-#define IW_ESSID_MAX_SIZE   		32
-#endif
-
-/* For AsicRadioOff/AsicRadioOn function */
-#define DOT11POWERSAVE		0
-#define GUIRADIO_OFF		1
-#define RTMP_HALT		    2
-#define GUI_IDLE_POWER_SAVE		3
-/* -- */
-
-/* definition for WpaSupport flag */
-#define WPA_SUPPLICANT_DISABLE				0
-#define WPA_SUPPLICANT_ENABLE				1
-#define	WPA_SUPPLICANT_ENABLE_WITH_WEB_UI	2
-
-/* Endian byte swapping codes */
-#define SWAP16(x) \
-    ((u16)( \
-    (((u16)(x) & (u16)0x00ffU) << 8) | \
-    (((u16)(x) & (u16)0xff00U) >> 8) ))
-
-#define SWAP32(x) \
-    ((u32)( \
-    (((u32)(x) & (u32)0x000000ffUL) << 24) | \
-    (((u32)(x) & (u32)0x0000ff00UL) <<  8) | \
-    (((u32)(x) & (u32)0x00ff0000UL) >>  8) | \
-    (((u32)(x) & (u32)0xff000000UL) >> 24) ))
-
-#define SWAP64(x) \
-    ((u64)( \
-    (u64)(((u64)(x) & (u64)0x00000000000000ffULL) << 56) | \
-    (u64)(((u64)(x) & (u64)0x000000000000ff00ULL) << 40) | \
-    (u64)(((u64)(x) & (u64)0x0000000000ff0000ULL) << 24) | \
-    (u64)(((u64)(x) & (u64)0x00000000ff000000ULL) <<  8) | \
-    (u64)(((u64)(x) & (u64)0x000000ff00000000ULL) >>  8) | \
-    (u64)(((u64)(x) & (u64)0x0000ff0000000000ULL) >> 24) | \
-    (u64)(((u64)(x) & (u64)0x00ff000000000000ULL) >> 40) | \
-    (u64)(((u64)(x) & (u64)0xff00000000000000ULL) >> 56) ))
-
-#define cpu2le64(x) ((u64)(x))
-#define le2cpu64(x) ((u64)(x))
-#define cpu2le32(x) ((u32)(x))
-#define le2cpu32(x) ((u32)(x))
-#define cpu2le16(x) ((u16)(x))
-#define le2cpu16(x) ((u16)(x))
-#define cpu2be64(x) SWAP64((x))
-#define be2cpu64(x) SWAP64((x))
-#define cpu2be32(x) SWAP32((x))
-#define be2cpu32(x) SWAP32((x))
-#define cpu2be16(x) SWAP16((x))
-#define be2cpu16(x) SWAP16((x))
-
-#define ABS(_x, _y) ((_x) > (_y)) ? ((_x) -(_y)) : ((_y) -(_x))
-
-#define A2Dec(_X, _p)				\
-{									\
-	u8 *p;						\
-	_X = 0;							\
-	p = _p;							\
-	while (((*p >= '0') && (*p <= '9')))		\
-	{												\
-		if ((*p >= '0') && (*p <= '9'))		\
-			_X = _X * 10 + *p - 48;					\
-		p++;										\
-	}												\
-}
-
-#define A2Hex(_X, _p)				\
-do{									\
-	char *__p;						\
-	(_X) = 0;							\
-	__p = (char *)(_p);							\
-	while (((*__p >= 'a') && (*__p <= 'f')) || ((*__p >= 'A') && (*__p <= 'F')) || ((*__p >= '0') && (*__p <= '9')))		\
-	{												\
-		if ((*__p >= 'a') && (*__p <= 'f'))				\
-			(_X) = (_X) * 16 + *__p - 87;					\
-		else if ((*__p >= 'A') && (*__p <= 'F'))		\
-			(_X) = (_X) * 16 + *__p - 55;					\
-		else if ((*__p >= '0') && (*__p <= '9'))		\
-			(_X) = (_X) * 16 + *__p - 48;					\
-		__p++;										\
-	}												\
-}while(0)
-
-#endif /* __RTMP_DEF_H__ */
diff -druN linux-2.6.39-libre/drivers/staging/rt2860/rtmp_dot11.h linux-3.0-rc7-libre/drivers/staging/rt2860/rtmp_dot11.h
--- linux-2.6.39-libre/drivers/staging/rt2860/rtmp_dot11.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rt2860/rtmp_dot11.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,100 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, 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 __DOT11_BASE_H__
-#define __DOT11_BASE_H__
-
-#include "rtmp_type.h"
-
-/* 4-byte HTC field.  maybe included in any frame except non-QOS data frame.  The Order bit must set 1. */
-struct PACKED rt_ht_control {
-	u32 MA:1;		/*management action payload exist in (QoS Null+HTC) */
-	u32 TRQ:1;		/*sounding request */
-	u32 MRQ:1;		/*MCS feedback. Request for a MCS feedback */
-	u32 MRSorASI:3;	/* MRQ Sequence identifier. unchanged during entire procedure. 0x000-0x110. */
-	u32 MFS:3;		/*SET to the received value of MRS. 0x111 for unsolicited MFB. */
-	u32 MFBorASC:7;	/*Link adaptation feedback containing recommended MCS. 0x7f for no feedback or not available */
-	u32 CalPos:2;	/* calibration position */
-	u32 CalSeq:2;	/*calibration sequence */
-	u32 FBKReq:2;	/*feedback request */
-	u32 CSISTEERING:2;	/*CSI/ STEERING */
-	u32 ZLFAnnouce:1;	/* ZLF announcement */
-	u32 rsv:5;		/*calibration sequence */
-	u32 ACConstraint:1;	/*feedback request */
-	u32 RDG:1;		/*RDG / More PPDU */
-};
-
-/* 2-byte QOS CONTROL field */
-struct PACKED rt_qos_control {
-	u16 TID:4;
-	u16 EOSP:1;
-	u16 AckPolicy:2;	/*0: normal ACK 1:No ACK 2:scheduled under MTBA/PSMP  3: BA */
-	u16 AMsduPresent:1;
-	u16 Txop_QueueSize:8;
-};
-
-/* 2-byte Frame control field */
-struct PACKED rt_frame_control {
-	u16 Ver:2;		/* Protocol version */
-	u16 Type:2;		/* MSDU type */
-	u16 SubType:4;	/* MSDU subtype */
-	u16 ToDs:1;		/* To DS indication */
-	u16 FrDs:1;		/* From DS indication */
-	u16 MoreFrag:1;	/* More fragment bit */
-	u16 Retry:1;		/* Retry status bit */
-	u16 PwrMgmt:1;	/* Power management bit */
-	u16 MoreData:1;	/* More data bit */
-	u16 Wep:1;		/* Wep data */
-	u16 Order:1;		/* Strict order expected */
-};
-
-struct PACKED rt_header_802_11 {
-	struct rt_frame_control FC;
-	u16 Duration;
-	u8 Addr1[MAC_ADDR_LEN];
-	u8 Addr2[MAC_ADDR_LEN];
-	u8 Addr3[MAC_ADDR_LEN];
-	u16 Frag:4;
-	u16 Sequence:12;
-	u8 Octet[0];
-};
-
-struct PACKED rt_pspoll_frame {
-	struct rt_frame_control FC;
-	u16 Aid;
-	u8 Bssid[MAC_ADDR_LEN];
-	u8 Ta[MAC_ADDR_LEN];
-};
-
-struct PACKED rt_rts_frame {
-	struct rt_frame_control FC;
-	u16 Duration;
-	u8 Addr1[MAC_ADDR_LEN];
-	u8 Addr2[MAC_ADDR_LEN];
-};
-
-#endif /* __DOT11_BASE_H__ // */
diff -druN linux-2.6.39-libre/drivers/staging/rt2860/rtmp.h linux-3.0-rc7-libre/drivers/staging/rt2860/rtmp.h
--- linux-2.6.39-libre/drivers/staging/rt2860/rtmp.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rt2860/rtmp.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,4332 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, 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.             *
- *                                                                       *
- *************************************************************************
-
-    Module Name:
-    rtmp.h
-
-    Abstract:
-    Miniport generic portion header file
-
-    Revision History:
-    Who         	When          	What
-    --------    ----------    ----------------------------------------------
-    Paul Lin    	2002-08-01    	created
-    James Tan   	2002-09-06    	modified (Revise NTCRegTable)
-    John Chang  	2004-09-06    	modified for RT2600
-    Justin P. Mattock	11/07/2010	Fix some typos
-*/
-#ifndef __RTMP_H__
-#define __RTMP_H__
-
-#include "spectrum_def.h"
-#include "rtmp_dot11.h"
-#include "rtmp_chip.h"
-
-struct rt_rtmp_adapter;
-
-/*#define DBG           1 */
-
-/*#define DBG_DIAGNOSE          1 */
-
-/*+++Add by shiang for merge MiniportMMRequest() and MiniportDataMMRequest() into one function */
-#define MAX_DATAMM_RETRY	3
-#define MGMT_USE_QUEUE_FLAG	0x80
-/*---Add by shiang for merge MiniportMMRequest() and MiniportDataMMRequest() into one function */
-
-#define	MAXSEQ		(0xFFF)
-
-extern unsigned char SNAP_AIRONET[];
-extern unsigned char CISCO_OUI[];
-extern u8 BaSizeArray[4];
-
-extern u8 BROADCAST_ADDR[MAC_ADDR_LEN];
-extern u8 ZERO_MAC_ADDR[MAC_ADDR_LEN];
-extern unsigned long BIT32[32];
-extern u8 BIT8[8];
-extern char *CipherName[];
-extern char *MCSToMbps[];
-extern u8 RxwiMCSToOfdmRate[12];
-extern u8 SNAP_802_1H[6];
-extern u8 SNAP_BRIDGE_TUNNEL[6];
-extern u8 SNAP_AIRONET[8];
-extern u8 CKIP_LLC_SNAP[8];
-extern u8 EAPOL_LLC_SNAP[8];
-extern u8 EAPOL[2];
-extern u8 IPX[2];
-extern u8 APPLE_TALK[2];
-extern u8 RateIdToPlcpSignal[12];	/* see IEEE802.11a-1999 p.14 */
-extern u8 OfdmRateToRxwiMCS[];
-extern u8 OfdmSignalToRateId[16];
-extern u8 default_cwmin[4];
-extern u8 default_cwmax[4];
-extern u8 default_sta_aifsn[4];
-extern u8 MapUserPriorityToAccessCategory[8];
-
-extern u16 RateUpPER[];
-extern u16 RateDownPER[];
-extern u8 Phy11BNextRateDownward[];
-extern u8 Phy11BNextRateUpward[];
-extern u8 Phy11BGNextRateDownward[];
-extern u8 Phy11BGNextRateUpward[];
-extern u8 Phy11ANextRateDownward[];
-extern u8 Phy11ANextRateUpward[];
-extern char RssiSafeLevelForTxRate[];
-extern u8 RateIdToMbps[];
-extern u16 RateIdTo500Kbps[];
-
-extern u8 CipherSuiteWpaNoneTkip[];
-extern u8 CipherSuiteWpaNoneTkipLen;
-
-extern u8 CipherSuiteWpaNoneAes[];
-extern u8 CipherSuiteWpaNoneAesLen;
-
-extern u8 SsidIe;
-extern u8 SupRateIe;
-extern u8 ExtRateIe;
-
-extern u8 HtCapIe;
-extern u8 AddHtInfoIe;
-extern u8 NewExtChanIe;
-
-extern u8 ErpIe;
-extern u8 DsIe;
-extern u8 TimIe;
-extern u8 WpaIe;
-extern u8 Wpa2Ie;
-extern u8 IbssIe;
-extern u8 Ccx2Ie;
-extern u8 WapiIe;
-
-extern u8 WPA_OUI[];
-extern u8 RSN_OUI[];
-extern u8 WAPI_OUI[];
-extern u8 WME_INFO_ELEM[];
-extern u8 WME_PARM_ELEM[];
-extern u8 Ccx2QosInfo[];
-extern u8 Ccx2IeInfo[];
-extern u8 RALINK_OUI[];
-extern u8 PowerConstraintIE[];
-
-extern u8 RateSwitchTable[];
-extern u8 RateSwitchTable11B[];
-extern u8 RateSwitchTable11G[];
-extern u8 RateSwitchTable11BG[];
-
-extern u8 RateSwitchTable11BGN1S[];
-extern u8 RateSwitchTable11BGN2S[];
-extern u8 RateSwitchTable11BGN2SForABand[];
-extern u8 RateSwitchTable11N1S[];
-extern u8 RateSwitchTable11N2S[];
-extern u8 RateSwitchTable11N2SForABand[];
-
-extern u8 PRE_N_HT_OUI[];
-
-struct rt_rssi_sample {
-	char LastRssi0;		/* last received RSSI */
-	char LastRssi1;		/* last received RSSI */
-	char LastRssi2;		/* last received RSSI */
-	char AvgRssi0;
-	char AvgRssi1;
-	char AvgRssi2;
-	short AvgRssi0X8;
-	short AvgRssi1X8;
-	short AvgRssi2X8;
-};
-
-/* */
-/*  Queue structure and macros */
-/* */
-struct rt_queue_entry;
-
-struct rt_queue_entry {
-	struct rt_queue_entry *Next;
-};
-
-/* Queue structure */
-struct rt_queue_header {
-	struct rt_queue_entry *Head;
-	struct rt_queue_entry *Tail;
-	unsigned long Number;
-};
-
-#define InitializeQueueHeader(QueueHeader)              \
-{                                                       \
-	(QueueHeader)->Head = (QueueHeader)->Tail = NULL;   \
-	(QueueHeader)->Number = 0;                          \
-}
-
-#define RemoveHeadQueue(QueueHeader)                \
-(QueueHeader)->Head;                                \
-{                                                   \
-	struct rt_queue_entry *pNext;                             \
-	if ((QueueHeader)->Head != NULL) {				\
-		pNext = (QueueHeader)->Head->Next;          \
-		(QueueHeader)->Head->Next = NULL;		\
-		(QueueHeader)->Head = pNext;                \
-		if (pNext == NULL)                          \
-			(QueueHeader)->Tail = NULL;             \
-		(QueueHeader)->Number--;                    \
-	}												\
-}
-
-#define InsertHeadQueue(QueueHeader, QueueEntry)            \
-{                                                           \
-		((struct rt_queue_entry *)QueueEntry)->Next = (QueueHeader)->Head; \
-		(QueueHeader)->Head = (struct rt_queue_entry *)(QueueEntry);       \
-		if ((QueueHeader)->Tail == NULL)                        \
-			(QueueHeader)->Tail = (struct rt_queue_entry *)(QueueEntry);   \
-		(QueueHeader)->Number++;                                \
-}
-
-#define InsertTailQueue(QueueHeader, QueueEntry)                \
-{                                                               \
-	((struct rt_queue_entry *)QueueEntry)->Next = NULL;                    \
-	if ((QueueHeader)->Tail)                                    \
-		(QueueHeader)->Tail->Next = (struct rt_queue_entry *)(QueueEntry); \
-	else                                                        \
-		(QueueHeader)->Head = (struct rt_queue_entry *)(QueueEntry);       \
-	(QueueHeader)->Tail = (struct rt_queue_entry *)(QueueEntry);           \
-	(QueueHeader)->Number++;                                    \
-}
-
-#define InsertTailQueueAc(pAd, pEntry, QueueHeader, QueueEntry)			\
-{																		\
-	((struct rt_queue_entry *)QueueEntry)->Next = NULL;							\
-	if ((QueueHeader)->Tail)											\
-		(QueueHeader)->Tail->Next = (struct rt_queue_entry *)(QueueEntry);			\
-	else																\
-		(QueueHeader)->Head = (struct rt_queue_entry *)(QueueEntry);				\
-	(QueueHeader)->Tail = (struct rt_queue_entry *)(QueueEntry);					\
-	(QueueHeader)->Number++;											\
-}
-
-/* */
-/*  Macros for flag and ref count operations */
-/* */
-#define RTMP_SET_FLAG(_M, _F)       ((_M)->Flags |= (_F))
-#define RTMP_CLEAR_FLAG(_M, _F)     ((_M)->Flags &= ~(_F))
-#define RTMP_CLEAR_FLAGS(_M)        ((_M)->Flags = 0)
-#define RTMP_TEST_FLAG(_M, _F)      (((_M)->Flags & (_F)) != 0)
-#define RTMP_TEST_FLAGS(_M, _F)     (((_M)->Flags & (_F)) == (_F))
-/* Macro for power save flag. */
-#define RTMP_SET_PSFLAG(_M, _F)       ((_M)->PSFlags |= (_F))
-#define RTMP_CLEAR_PSFLAG(_M, _F)     ((_M)->PSFlags &= ~(_F))
-#define RTMP_CLEAR_PSFLAGS(_M)        ((_M)->PSFlags = 0)
-#define RTMP_TEST_PSFLAG(_M, _F)      (((_M)->PSFlags & (_F)) != 0)
-#define RTMP_TEST_PSFLAGS(_M, _F)     (((_M)->PSFlags & (_F)) == (_F))
-
-#define OPSTATUS_SET_FLAG(_pAd, _F)     ((_pAd)->CommonCfg.OpStatusFlags |= (_F))
-#define OPSTATUS_CLEAR_FLAG(_pAd, _F)   ((_pAd)->CommonCfg.OpStatusFlags &= ~(_F))
-#define OPSTATUS_TEST_FLAG(_pAd, _F)    (((_pAd)->CommonCfg.OpStatusFlags & (_F)) != 0)
-
-#define CLIENT_STATUS_SET_FLAG(_pEntry, _F)      ((_pEntry)->ClientStatusFlags |= (_F))
-#define CLIENT_STATUS_CLEAR_FLAG(_pEntry, _F)    ((_pEntry)->ClientStatusFlags &= ~(_F))
-#define CLIENT_STATUS_TEST_FLAG(_pEntry, _F)     (((_pEntry)->ClientStatusFlags & (_F)) != 0)
-
-#define RX_FILTER_SET_FLAG(_pAd, _F)    ((_pAd)->CommonCfg.PacketFilter |= (_F))
-#define RX_FILTER_CLEAR_FLAG(_pAd, _F)  ((_pAd)->CommonCfg.PacketFilter &= ~(_F))
-#define RX_FILTER_TEST_FLAG(_pAd, _F)   (((_pAd)->CommonCfg.PacketFilter & (_F)) != 0)
-
-#define STA_NO_SECURITY_ON(_p)          (_p->StaCfg.WepStatus == Ndis802_11EncryptionDisabled)
-#define STA_WEP_ON(_p)                  (_p->StaCfg.WepStatus == Ndis802_11Encryption1Enabled)
-#define STA_TKIP_ON(_p)                 (_p->StaCfg.WepStatus == Ndis802_11Encryption2Enabled)
-#define STA_AES_ON(_p)                  (_p->StaCfg.WepStatus == Ndis802_11Encryption3Enabled)
-
-#define STA_TGN_WIFI_ON(_p)             (_p->StaCfg.bTGnWifiTest == TRUE)
-
-#define CKIP_KP_ON(_p)				((((_p)->StaCfg.CkipFlag) & 0x10) && ((_p)->StaCfg.bCkipCmicOn == TRUE))
-#define CKIP_CMIC_ON(_p)			((((_p)->StaCfg.CkipFlag) & 0x08) && ((_p)->StaCfg.bCkipCmicOn == TRUE))
-
-#define INC_RING_INDEX(_idx, _RingSize)    \
-{                                          \
-    (_idx) = (_idx+1) % (_RingSize);       \
-}
-
-/* StaActive.SupportedHtPhy.MCSSet is copied from AP beacon.  Don't need to update here. */
-#define COPY_HTSETTINGS_FROM_MLME_AUX_TO_ACTIVE_CFG(_pAd)                                 \
-{                                                                                       \
-	_pAd->StaActive.SupportedHtPhy.ChannelWidth = _pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth;      \
-	_pAd->StaActive.SupportedHtPhy.MimoPs = _pAd->MlmeAux.HtCapability.HtCapInfo.MimoPs;      \
-	_pAd->StaActive.SupportedHtPhy.GF = _pAd->MlmeAux.HtCapability.HtCapInfo.GF;      \
-	_pAd->StaActive.SupportedHtPhy.ShortGIfor20 = _pAd->MlmeAux.HtCapability.HtCapInfo.ShortGIfor20;      \
-	_pAd->StaActive.SupportedHtPhy.ShortGIfor40 = _pAd->MlmeAux.HtCapability.HtCapInfo.ShortGIfor40;      \
-	_pAd->StaActive.SupportedHtPhy.TxSTBC = _pAd->MlmeAux.HtCapability.HtCapInfo.TxSTBC;      \
-	_pAd->StaActive.SupportedHtPhy.RxSTBC = _pAd->MlmeAux.HtCapability.HtCapInfo.RxSTBC;      \
-	_pAd->StaActive.SupportedHtPhy.ExtChanOffset = _pAd->MlmeAux.AddHtInfo.AddHtInfo.ExtChanOffset;      \
-	_pAd->StaActive.SupportedHtPhy.RecomWidth = _pAd->MlmeAux.AddHtInfo.AddHtInfo.RecomWidth;      \
-	_pAd->StaActive.SupportedHtPhy.OperaionMode = _pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode;      \
-	_pAd->StaActive.SupportedHtPhy.NonGfPresent = _pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent;      \
-	NdisMoveMemory((_pAd)->MacTab.Content[BSSID_WCID].HTCapability.MCSSet, (_pAd)->StaActive.SupportedPhyInfo.MCSSet, sizeof(u8) * 16);\
-}
-
-#define COPY_AP_HTSETTINGS_FROM_BEACON(_pAd, _pHtCapability)                                 \
-{                                                                                       \
-	_pAd->MacTab.Content[BSSID_WCID].AMsduSize = (u8)(_pHtCapability->HtCapInfo.AMsduSize);	\
-	_pAd->MacTab.Content[BSSID_WCID].MmpsMode = (u8)(_pHtCapability->HtCapInfo.MimoPs);	\
-	_pAd->MacTab.Content[BSSID_WCID].MaxRAmpduFactor = (u8)(_pHtCapability->HtCapParm.MaxRAmpduFactor);	\
-}
-
-/* */
-/* MACRO for 32-bit PCI register read / write */
-/* */
-/* Usage : RTMP_IO_READ32( */
-/*              struct rt_rtmp_adapter *pAd, */
-/*              unsigned long Register_Offset, */
-/*              unsigned long * pValue) */
-/* */
-/*         RTMP_IO_WRITE32( */
-/*              struct rt_rtmp_adapter *pAd, */
-/*              unsigned long Register_Offset, */
-/*              unsigned long Value) */
-/* */
-
-/* */
-/* Common fragment list structure -  Identical to the scatter gather frag list structure */
-/* */
-/*#define struct rt_rtmp_sg_element         SCATTER_GATHER_ELEMENT */
-/*#define struct rt_rtmp_sg_element *PSCATTER_GATHER_ELEMENT */
-#define NIC_MAX_PHYS_BUF_COUNT              8
-
-struct rt_rtmp_sg_element {
-	void *Address;
-	unsigned long Length;
-	unsigned long *Reserved;
-};
-
-struct rt_rtmp_sg_list {
-	unsigned long NumberOfElements;
-	unsigned long *Reserved;
-	struct rt_rtmp_sg_element Elements[NIC_MAX_PHYS_BUF_COUNT];
-};
-
-/* */
-/*  Some utility macros */
-/* */
-#define GET_LNA_GAIN(_pAd)	((_pAd->LatchRfRegs.Channel <= 14) ? (_pAd->BLNAGain) : ((_pAd->LatchRfRegs.Channel <= 64) ? (_pAd->ALNAGain0) : ((_pAd->LatchRfRegs.Channel <= 128) ? (_pAd->ALNAGain1) : (_pAd->ALNAGain2))))
-
-#define INC_COUNTER64(Val)          (Val.QuadPart++)
-
-#define INFRA_ON(_p)                (OPSTATUS_TEST_FLAG(_p, fOP_STATUS_INFRA_ON))
-#define ADHOC_ON(_p)                (OPSTATUS_TEST_FLAG(_p, fOP_STATUS_ADHOC_ON))
-#define MONITOR_ON(_p)              (((_p)->StaCfg.BssType) == BSS_MONITOR)
-#define IDLE_ON(_p)                 (!INFRA_ON(_p) && !ADHOC_ON(_p))
-
-/* Check LEAP & CCKM flags */
-#define LEAP_ON(_p)                 (((_p)->StaCfg.LeapAuthMode) == CISCO_AuthModeLEAP)
-#define LEAP_CCKM_ON(_p)            ((((_p)->StaCfg.LeapAuthMode) == CISCO_AuthModeLEAP) && ((_p)->StaCfg.LeapAuthInfo.CCKM == TRUE))
-
-/* if original Ethernet frame contains no LLC/SNAP, then an extra LLC/SNAP encap is required */
-#define EXTRA_LLCSNAP_ENCAP_FROM_PKT_START(_pBufVA, _pExtraLlcSnapEncap)		\
-{																\
-	if (((*(_pBufVA + 12) << 8) + *(_pBufVA + 13)) > 1500) {	\
-		_pExtraLlcSnapEncap = SNAP_802_1H;						\
-		if (NdisEqualMemory(IPX, _pBufVA + 12, 2) || 			\
-			NdisEqualMemory(APPLE_TALK, _pBufVA + 12, 2)) {	\
-			_pExtraLlcSnapEncap = SNAP_BRIDGE_TUNNEL;			\
-		}														\
-	}															\
-	else {				\
-		_pExtraLlcSnapEncap = NULL;								\
-	}															\
-}
-
-/* New Define for new Tx Path. */
-#define EXTRA_LLCSNAP_ENCAP_FROM_PKT_OFFSET(_pBufVA, _pExtraLlcSnapEncap)	\
-{																\
-	if (((*(_pBufVA) << 8) + *(_pBufVA + 1)) > 1500) {		\
-		_pExtraLlcSnapEncap = SNAP_802_1H;						\
-		if (NdisEqualMemory(IPX, _pBufVA, 2) || 				\
-			NdisEqualMemory(APPLE_TALK, _pBufVA, 2)) {		\
-			_pExtraLlcSnapEncap = SNAP_BRIDGE_TUNNEL;			\
-		}														\
-	}															\
-	else {		\
-		_pExtraLlcSnapEncap = NULL;								\
-	}															\
-}
-
-#define MAKE_802_3_HEADER(_p, _pMac1, _pMac2, _pType)                   \
-{                                                                       \
-    NdisMoveMemory(_p, _pMac1, MAC_ADDR_LEN);                           \
-    NdisMoveMemory((_p + MAC_ADDR_LEN), _pMac2, MAC_ADDR_LEN);          \
-    NdisMoveMemory((_p + MAC_ADDR_LEN * 2), _pType, LENGTH_802_3_TYPE); \
-}
-
-/* if pData has no LLC/SNAP (neither RFC1042 nor Bridge tunnel), keep it that way. */
-/* else if the received frame is LLC/SNAP-encaped IPX or APPLETALK, preserve the LLC/SNAP field */
-/* else remove the LLC/SNAP field from the result Ethernet frame */
-/* Patch for WHQL only, which did not turn on Netbios but use IPX within its payload */
-/* Note: */
-/*     _pData & _DataSize may be altered (remove 8-byte LLC/SNAP) by this MACRO */
-/*     _pRemovedLLCSNAP: pointer to removed LLC/SNAP; NULL is not removed */
-#define CONVERT_TO_802_3(_p8023hdr, _pDA, _pSA, _pData, _DataSize, _pRemovedLLCSNAP)      \
-{                                                                       \
-    char LLC_Len[2];                                                    \
-									\
-    _pRemovedLLCSNAP = NULL;                                            \
-    if (NdisEqualMemory(SNAP_802_1H, _pData, 6)  ||                     \
-	NdisEqualMemory(SNAP_BRIDGE_TUNNEL, _pData, 6))	{		\
-	u8 *pProto = _pData + 6;					\
-									\
-	if ((NdisEqualMemory(IPX, pProto, 2) || NdisEqualMemory(APPLE_TALK, pProto, 2)) &&  \
-		NdisEqualMemory(SNAP_802_1H, _pData, 6))	{	\
-		LLC_Len[0] = (u8)(_DataSize / 256);			\
-		LLC_Len[1] = (u8)(_DataSize % 256);			\
-		MAKE_802_3_HEADER(_p8023hdr, _pDA, _pSA, LLC_Len);	\
-	}								\
-	else	{							\
-		MAKE_802_3_HEADER(_p8023hdr, _pDA, _pSA, pProto);	\
-		_pRemovedLLCSNAP = _pData;				\
-		_DataSize -= LENGTH_802_1_H;				\
-		_pData += LENGTH_802_1_H;				\
-	}								\
-    }                                                                   \
-	else	{							\
-	LLC_Len[0] = (u8)(_DataSize / 256);				\
-	LLC_Len[1] = (u8)(_DataSize % 256);				\
-	MAKE_802_3_HEADER(_p8023hdr, _pDA, _pSA, LLC_Len);		\
-    }                                                                   \
-}
-
-/* Enqueue this frame to MLME engine */
-/* We need to enqueue the whole frame because MLME need to pass data type */
-/* information from 802.11 header */
-#ifdef RTMP_MAC_PCI
-#define REPORT_MGMT_FRAME_TO_MLME(_pAd, Wcid, _pFrame, _FrameSize, _Rssi0, _Rssi1, _Rssi2, _PlcpSignal)        \
-{                                                                                       \
-    u32 High32TSF, Low32TSF;                                                          \
-    RTMP_IO_READ32(_pAd, TSF_TIMER_DW1, &High32TSF);                                       \
-    RTMP_IO_READ32(_pAd, TSF_TIMER_DW0, &Low32TSF);                                        \
-    MlmeEnqueueForRecv(_pAd, Wcid, High32TSF, Low32TSF, (u8)_Rssi0, (u8)_Rssi1, (u8)_Rssi2, _FrameSize, _pFrame, (u8)_PlcpSignal);   \
-}
-#endif /* RTMP_MAC_PCI // */
-#ifdef RTMP_MAC_USB
-#define REPORT_MGMT_FRAME_TO_MLME(_pAd, Wcid, _pFrame, _FrameSize, _Rssi0, _Rssi1, _Rssi2, _PlcpSignal)        \
-{                                                                                       \
-    u32 High32TSF = 0, Low32TSF = 0;                                                          \
-    MlmeEnqueueForRecv(_pAd, Wcid, High32TSF, Low32TSF, (u8)_Rssi0, (u8)_Rssi1, (u8)_Rssi2, _FrameSize, _pFrame, (u8)_PlcpSignal);   \
-}
-#endif /* RTMP_MAC_USB // */
-
-#define MAC_ADDR_EQUAL(pAddr1, pAddr2)           RTMPEqualMemory((void *)(pAddr1), (void *)(pAddr2), MAC_ADDR_LEN)
-#define SSID_EQUAL(ssid1, len1, ssid2, len2)    ((len1 == len2) && (RTMPEqualMemory(ssid1, ssid2, len1)))
-
-/* */
-/* Check if it is Japan W53(ch52,56,60,64) channel. */
-/* */
-#define JapanChannelCheck(channel)  ((channel == 52) || (channel == 56) || (channel == 60) || (channel == 64))
-
-#define STA_EXTRA_SETTING(_pAd)
-
-#define STA_PORT_SECURED(_pAd) \
-{ \
-	BOOLEAN	Cancelled; \
-	(_pAd)->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED; \
-	NdisAcquireSpinLock(&((_pAd)->MacTabLock)); \
-	(_pAd)->MacTab.Content[BSSID_WCID].PortSecured = (_pAd)->StaCfg.PortSecured; \
-	(_pAd)->MacTab.Content[BSSID_WCID].PrivacyFilter = Ndis802_11PrivFilterAcceptAll;\
-	NdisReleaseSpinLock(&(_pAd)->MacTabLock); \
-	RTMPCancelTimer(&((_pAd)->Mlme.LinkDownTimer), &Cancelled);\
-	STA_EXTRA_SETTING(_pAd); \
-}
-
-/* */
-/*  Data buffer for DMA operation, the buffer must be contiguous physical memory */
-/*  Both DMA to / from CPU use the same structure. */
-/* */
-struct rt_rtmp_dmabuf {
-	unsigned long AllocSize;
-	void *AllocVa;		/* TxBuf virtual address */
-	dma_addr_t AllocPa;	/* TxBuf physical address */
-};
-
-/* */
-/* Control block (Descriptor) for all ring descriptor DMA operation, buffer must be */
-/* contiguous physical memory. char stored the binding Rx packet descriptor */
-/* which won't be released, driver has to wait until upper layer return the packet */
-/* before giving up this rx ring descriptor to ASIC. NDIS_BUFFER is associated pair */
-/* to describe the packet buffer. For Tx, char stored the tx packet descriptor */
-/* which driver should ACK upper layer when the tx is physically done or failed. */
-/* */
-struct rt_rtmp_dmacb {
-	unsigned long AllocSize;	/* Control block size */
-	void *AllocVa;		/* Control block virtual address */
-	dma_addr_t AllocPa;	/* Control block physical address */
-	void *pNdisPacket;
-	void *pNextNdisPacket;
-
-	struct rt_rtmp_dmabuf DmaBuf;	/* Associated DMA buffer structure */
-};
-
-struct rt_rtmp_tx_ring {
-	struct rt_rtmp_dmacb Cell[TX_RING_SIZE];
-	u32 TxCpuIdx;
-	u32 TxDmaIdx;
-	u32 TxSwFreeIdx;	/* software next free tx index */
-};
-
-struct rt_rtmp_rx_ring {
-	struct rt_rtmp_dmacb Cell[RX_RING_SIZE];
-	u32 RxCpuIdx;
-	u32 RxDmaIdx;
-	int RxSwReadIdx;	/* software next read index */
-};
-
-struct rt_rtmp_mgmt_ring {
-	struct rt_rtmp_dmacb Cell[MGMT_RING_SIZE];
-	u32 TxCpuIdx;
-	u32 TxDmaIdx;
-	u32 TxSwFreeIdx;	/* software next free tx index */
-};
-
-/* */
-/*  Statistic counter structure */
-/* */
-struct rt_counter_802_3 {
-	/* General Stats */
-	unsigned long GoodTransmits;
-	unsigned long GoodReceives;
-	unsigned long TxErrors;
-	unsigned long RxErrors;
-	unsigned long RxNoBuffer;
-
-	/* Ethernet Stats */
-	unsigned long RcvAlignmentErrors;
-	unsigned long OneCollision;
-	unsigned long MoreCollisions;
-
-};
-
-struct rt_counter_802_11 {
-	unsigned long Length;
-	LARGE_INTEGER LastTransmittedFragmentCount;
-	LARGE_INTEGER TransmittedFragmentCount;
-	LARGE_INTEGER MulticastTransmittedFrameCount;
-	LARGE_INTEGER FailedCount;
-	LARGE_INTEGER RetryCount;
-	LARGE_INTEGER MultipleRetryCount;
-	LARGE_INTEGER RTSSuccessCount;
-	LARGE_INTEGER RTSFailureCount;
-	LARGE_INTEGER ACKFailureCount;
-	LARGE_INTEGER FrameDuplicateCount;
-	LARGE_INTEGER ReceivedFragmentCount;
-	LARGE_INTEGER MulticastReceivedFrameCount;
-	LARGE_INTEGER FCSErrorCount;
-};
-
-struct rt_counter_ralink {
-	unsigned long TransmittedByteCount;	/* both successful and failure, used to calculate TX throughput */
-	unsigned long ReceivedByteCount;	/* both CRC okay and CRC error, used to calculate RX throughput */
-	unsigned long BeenDisassociatedCount;
-	unsigned long BadCQIAutoRecoveryCount;
-	unsigned long PoorCQIRoamingCount;
-	unsigned long MgmtRingFullCount;
-	unsigned long RxCountSinceLastNULL;
-	unsigned long RxCount;
-	unsigned long RxRingErrCount;
-	unsigned long KickTxCount;
-	unsigned long TxRingErrCount;
-	LARGE_INTEGER RealFcsErrCount;
-	unsigned long PendingNdisPacketCount;
-
-	unsigned long OneSecOsTxCount[NUM_OF_TX_RING];
-	unsigned long OneSecDmaDoneCount[NUM_OF_TX_RING];
-	u32 OneSecTxDoneCount;
-	unsigned long OneSecRxCount;
-	u32 OneSecTxAggregationCount;
-	u32 OneSecRxAggregationCount;
-	u32 OneSecReceivedByteCount;
-	u32 OneSecFrameDuplicateCount;
-
-	u32 OneSecTransmittedByteCount;	/* both successful and failure, used to calculate TX throughput */
-	u32 OneSecTxNoRetryOkCount;
-	u32 OneSecTxRetryOkCount;
-	u32 OneSecTxFailCount;
-	u32 OneSecFalseCCACnt;	/* CCA error count, for debug purpose, might move to global counter */
-	u32 OneSecRxOkCnt;	/* RX without error */
-	u32 OneSecRxOkDataCnt;	/* unicast-to-me DATA frame count */
-	u32 OneSecRxFcsErrCnt;	/* CRC error */
-	u32 OneSecBeaconSentCnt;
-	u32 LastOneSecTotalTxCount;	/* OneSecTxNoRetryOkCount + OneSecTxRetryOkCount + OneSecTxFailCount */
-	u32 LastOneSecRxOkDataCnt;	/* OneSecRxOkDataCnt */
-	unsigned long DuplicateRcv;
-	unsigned long TxAggCount;
-	unsigned long TxNonAggCount;
-	unsigned long TxAgg1MPDUCount;
-	unsigned long TxAgg2MPDUCount;
-	unsigned long TxAgg3MPDUCount;
-	unsigned long TxAgg4MPDUCount;
-	unsigned long TxAgg5MPDUCount;
-	unsigned long TxAgg6MPDUCount;
-	unsigned long TxAgg7MPDUCount;
-	unsigned long TxAgg8MPDUCount;
-	unsigned long TxAgg9MPDUCount;
-	unsigned long TxAgg10MPDUCount;
-	unsigned long TxAgg11MPDUCount;
-	unsigned long TxAgg12MPDUCount;
-	unsigned long TxAgg13MPDUCount;
-	unsigned long TxAgg14MPDUCount;
-	unsigned long TxAgg15MPDUCount;
-	unsigned long TxAgg16MPDUCount;
-
-	LARGE_INTEGER TransmittedOctetsInAMSDU;
-	LARGE_INTEGER TransmittedAMSDUCount;
-	LARGE_INTEGER ReceivedOctesInAMSDUCount;
-	LARGE_INTEGER ReceivedAMSDUCount;
-	LARGE_INTEGER TransmittedAMPDUCount;
-	LARGE_INTEGER TransmittedMPDUsInAMPDUCount;
-	LARGE_INTEGER TransmittedOctetsInAMPDUCount;
-	LARGE_INTEGER MPDUInReceivedAMPDUCount;
-};
-
-struct rt_counter_drs {
-	/* record each TX rate's quality. 0 is best, the bigger the worse. */
-	u16 TxQuality[MAX_STEP_OF_TX_RATE_SWITCH];
-	u8 PER[MAX_STEP_OF_TX_RATE_SWITCH];
-	u8 TxRateUpPenalty;	/* extra # of second penalty due to last unstable condition */
-	unsigned long CurrTxRateStableTime;	/* # of second in current TX rate */
-	BOOLEAN fNoisyEnvironment;
-	BOOLEAN fLastSecAccordingRSSI;
-	u8 LastSecTxRateChangeAction;	/* 0: no change, 1:rate UP, 2:rate down */
-	u8 LastTimeTxRateChangeAction;	/*Keep last time value of LastSecTxRateChangeAction */
-	unsigned long LastTxOkCount;
-};
-
-/***************************************************************************
-  *	security key related data structure
-  **************************************************************************/
-struct rt_cipher_key {
-	u8 Key[16];		/* right now we implement 4 keys, 128 bits max */
-	u8 RxMic[8];		/* make alignment */
-	u8 TxMic[8];
-	u8 TxTsc[6];		/* 48bit TSC value */
-	u8 RxTsc[6];		/* 48bit TSC value */
-	u8 CipherAlg;	/* 0-none, 1:WEP64, 2:WEP128, 3:TKIP, 4:AES, 5:CKIP64, 6:CKIP128 */
-	u8 KeyLen;
-	u8 BssId[6];
-	/* Key length for each key, 0: entry is invalid */
-	u8 Type;		/* Indicate Pairwise/Group when reporting MIC error */
-};
-
-/* structure to define WPA Group Key Rekey Interval */
-struct PACKED rt_802_11_wpa_rekey {
-	unsigned long ReKeyMethod;	/* mechanism for rekeying: 0:disable, 1: time-based, 2: packet-based */
-	unsigned long ReKeyInterval;	/* time-based: seconds, packet-based: kilo-packets */
-};
-
-#ifdef RTMP_MAC_USB
-/***************************************************************************
-  *	RTUSB I/O related data structure
-  **************************************************************************/
-struct rt_set_asic_wcid {
-	unsigned long WCID;		/* mechanism for rekeying: 0:disable, 1: time-based, 2: packet-based */
-	unsigned long SetTid;		/* time-based: seconds, packet-based: kilo-packets */
-	unsigned long DeleteTid;	/* time-based: seconds, packet-based: kilo-packets */
-	u8 Addr[MAC_ADDR_LEN];	/* avoid in interrupt when write key */
-};
-
-struct rt_set_asic_wcid_attri {
-	unsigned long WCID;		/* mechanism for rekeying: 0:disable, 1: time-based, 2: packet-based */
-	unsigned long Cipher;		/* ASIC Cipher definition */
-	u8 Addr[ETH_LENGTH_OF_ADDRESS];
-};
-
-/* for USB interface, avoid in interrupt when write key */
-struct rt_add_pairwise_key_entry {
-	u8 MacAddr[6];
-	u16 MacTabMatchWCID;	/* ASIC */
-	struct rt_cipher_key CipherKey;
-};
-
-/* Cipher suite type for mixed mode group cipher, P802.11i-2004 */
-typedef enum _RT_802_11_CIPHER_SUITE_TYPE {
-	Cipher_Type_NONE,
-	Cipher_Type_WEP40,
-	Cipher_Type_TKIP,
-	Cipher_Type_RSVD,
-	Cipher_Type_CCMP,
-	Cipher_Type_WEP104
-} RT_802_11_CIPHER_SUITE_TYPE, *PRT_802_11_CIPHER_SUITE_TYPE;
-#endif /* RTMP_MAC_USB // */
-
-struct rt_rogueap_entry {
-	u8 Addr[MAC_ADDR_LEN];
-	u8 ErrorCode[2];	/*00 01-Invalid authentication type */
-	/*00 02-Authentication timeout */
-	/*00 03-Challenge from AP failed */
-	/*00 04-Challenge to AP failed */
-	BOOLEAN Reported;
-};
-
-struct rt_rogueap_table {
-	u8 RogueApNr;
-	struct rt_rogueap_entry RogueApEntry[MAX_LEN_OF_BSS_TABLE];
-};
-
-/* */
-/* Cisco IAPP format */
-/* */
-struct rt_cisco_iapp_content {
-	u16 Length;		/*IAPP Length */
-	u8 MessageType;	/*IAPP type */
-	u8 FunctionCode;	/*IAPP function type */
-	u8 DestinaionMAC[MAC_ADDR_LEN];
-	u8 SourceMAC[MAC_ADDR_LEN];
-	u16 Tag;		/*Tag(element IE) - Adjacent AP report */
-	u16 TagLength;	/*Length of element not including 4 byte header */
-	u8 OUI[4];		/*0x00, 0x40, 0x96, 0x00 */
-	u8 PreviousAP[MAC_ADDR_LEN];	/*MAC Address of access point */
-	u16 Channel;
-	u16 SsidLen;
-	u8 Ssid[MAX_LEN_OF_SSID];
-	u16 Seconds;		/*Seconds that the client has been disassociated. */
-};
-
-/*
-  *	Fragment Frame structure
-  */
-struct rt_fragment_frame {
-	void *pFragPacket;
-	unsigned long RxSize;
-	u16 Sequence;
-	u16 LastFrag;
-	unsigned long Flags;		/* Some extra frame information. bit 0: LLC presented */
-};
-
-/* */
-/* Packet information for NdisQueryPacket */
-/* */
-struct rt_packet_info {
-	u32 PhysicalBufferCount;	/* Physical breaks of buffer descriptor chained */
-	u32 BufferCount;	/* Number of Buffer descriptor chained */
-	u32 TotalPacketLength;	/* Self explained */
-	char *pFirstBuffer;	/* Pointer to first buffer descriptor */
-};
-
-/* */
-/*  Arcfour Structure Added by PaulWu */
-/* */
-struct rt_arcfourcontext {
-	u32 X;
-	u32 Y;
-	u8 STATE[256];
-};
-
-/* */
-/* Tkip Key structure which RC4 key & MIC calculation */
-/* */
-struct rt_tkip_key_info {
-	u32 nBytesInM;		/* # bytes in M for MICKEY */
-	unsigned long IV16;
-	unsigned long IV32;
-	unsigned long K0;		/* for MICKEY Low */
-	unsigned long K1;		/* for MICKEY Hig */
-	unsigned long L;		/* Current state for MICKEY */
-	unsigned long R;		/* Current state for MICKEY */
-	unsigned long M;		/* Message accumulator for MICKEY */
-	u8 RC4KEY[16];
-	u8 MIC[8];
-};
-
-/* */
-/* Private / Misc data, counters for driver internal use */
-/* */
-struct rt_private {
-	u32 SystemResetCnt;	/* System reset counter */
-	u32 TxRingFullCnt;	/* Tx ring full occurrence number */
-	u32 PhyRxErrCnt;	/* PHY Rx error count, for debug purpose, might move to global counter */
-	/* Variables for WEP encryption / decryption in rtmp_wep.c */
-	u32 FCSCRC32;
-	struct rt_arcfourcontext WEPCONTEXT;
-	/* Tkip stuff */
-	struct rt_tkip_key_info Tx;
-	struct rt_tkip_key_info Rx;
-};
-
-/***************************************************************************
-  *	Channel and BBP related data structures
-  **************************************************************************/
-/* structure to tune BBP R66 (BBP TUNING) */
-struct rt_bbp_r66_tuning {
-	BOOLEAN bEnable;
-	u16 FalseCcaLowerThreshold;	/* default 100 */
-	u16 FalseCcaUpperThreshold;	/* default 512 */
-	u8 R66Delta;
-	u8 R66CurrentValue;
-	BOOLEAN R66LowerUpperSelect;	/*Before LinkUp, Used LowerBound or UpperBound as R66 value. */
-};
-
-/* structure to store channel TX power */
-struct rt_channel_tx_power {
-	u16 RemainingTimeForUse;	/*unit: sec */
-	u8 Channel;
-	char Power;
-	char Power2;
-	u8 MaxTxPwr;
-	u8 DfsReq;
-};
-
-/* structure to store 802.11j channel TX power */
-struct rt_channel_11j_tx_power {
-	u8 Channel;
-	u8 BW;		/* BW_10 or BW_20 */
-	char Power;
-	char Power2;
-	u16 RemainingTimeForUse;	/*unit: sec */
-};
-
-struct rt_soft_rx_ant_diversity {
-	u8 EvaluatePeriod;	/* 0:not evalute status, 1: evaluate status, 2: switching status */
-	u8 EvaluateStableCnt;
-	u8 Pair1PrimaryRxAnt;	/* 0:Ant-E1, 1:Ant-E2 */
-	u8 Pair1SecondaryRxAnt;	/* 0:Ant-E1, 1:Ant-E2 */
-	u8 Pair2PrimaryRxAnt;	/* 0:Ant-E3, 1:Ant-E4 */
-	u8 Pair2SecondaryRxAnt;	/* 0:Ant-E3, 1:Ant-E4 */
-	short Pair1AvgRssi[2];	/* AvgRssi[0]:E1, AvgRssi[1]:E2 */
-	short Pair2AvgRssi[2];	/* AvgRssi[0]:E3, AvgRssi[1]:E4 */
-	short Pair1LastAvgRssi;	/* */
-	short Pair2LastAvgRssi;	/* */
-	unsigned long RcvPktNumWhenEvaluate;
-	BOOLEAN FirstPktArrivedWhenEvaluate;
-	struct rt_ralink_timer RxAntDiversityTimer;
-};
-
-/***************************************************************************
-  *	structure for radar detection and channel switch
-  **************************************************************************/
-struct rt_radar_detect {
-	/*BOOLEAN           IEEE80211H;                     // 0: disable, 1: enable IEEE802.11h */
-	u8 CSCount;		/*Channel switch counter */
-	u8 CSPeriod;		/*Channel switch period (beacon count) */
-	u8 RDCount;		/*Radar detection counter */
-	u8 RDMode;		/*Radar Detection mode */
-	u8 RDDurRegion;	/*Radar detection duration region */
-	u8 BBPR16;
-	u8 BBPR17;
-	u8 BBPR18;
-	u8 BBPR21;
-	u8 BBPR22;
-	u8 BBPR64;
-	unsigned long InServiceMonitorCount;	/* unit: sec */
-	u8 DfsSessionTime;
-	BOOLEAN bFastDfs;
-	u8 ChMovingTime;
-	u8 LongPulseRadarTh;
-};
-
-typedef enum _ABGBAND_STATE_ {
-	UNKNOWN_BAND,
-	BG_BAND,
-	A_BAND,
-} ABGBAND_STATE;
-
-#ifdef RTMP_MAC_PCI
-/* Power save method control */
-typedef union _PS_CONTROL {
-	struct {
-		unsigned long EnablePSinIdle:1;	/* Enable radio off when not connected to AP. radio on only when sitesurvey, */
-		unsigned long EnableNewPS:1;	/* Enable new  Chip power save function . New method can only be applied in chip version after 2872. and PCIe. */
-		unsigned long rt30xxPowerMode:2;	/* Power Level Mode for rt30xx chip */
-		unsigned long rt30xxFollowHostASPM:1;	/* Card Follows Host's setting for rt30xx chip. */
-		unsigned long rt30xxForceASPMTest:1;	/* Force enable L1 for rt30xx chip. This has higher priority than rt30xxFollowHostASPM Mode. */
-		unsigned long rsv:26;	/* Radio Measurement Enable */
-	} field;
-	unsigned long word;
-} PS_CONTROL, *PPS_CONTROL;
-#endif /* RTMP_MAC_PCI // */
-
-/***************************************************************************
-  *	structure for MLME state machine
-  **************************************************************************/
-struct rt_mlme {
-	/* STA state machines */
-	struct rt_state_machine CntlMachine;
-	struct rt_state_machine AssocMachine;
-	struct rt_state_machine AuthMachine;
-	struct rt_state_machine AuthRspMachine;
-	struct rt_state_machine SyncMachine;
-	struct rt_state_machine WpaPskMachine;
-	struct rt_state_machine LeapMachine;
-	STATE_MACHINE_FUNC AssocFunc[ASSOC_FUNC_SIZE];
-	STATE_MACHINE_FUNC AuthFunc[AUTH_FUNC_SIZE];
-	STATE_MACHINE_FUNC AuthRspFunc[AUTH_RSP_FUNC_SIZE];
-	STATE_MACHINE_FUNC SyncFunc[SYNC_FUNC_SIZE];
-	STATE_MACHINE_FUNC ActFunc[ACT_FUNC_SIZE];
-	/* Action */
-	struct rt_state_machine ActMachine;
-
-	/* common WPA state machine */
-	struct rt_state_machine WpaMachine;
-	STATE_MACHINE_FUNC WpaFunc[WPA_FUNC_SIZE];
-
-	unsigned long ChannelQuality;	/* 0..100, Channel Quality Indication for Roaming */
-	unsigned long Now32;		/* latch the value of NdisGetSystemUpTime() */
-	unsigned long LastSendNULLpsmTime;
-
-	BOOLEAN bRunning;
-	spinlock_t TaskLock;
-	struct rt_mlme_queue Queue;
-
-	u32 ShiftReg;
-
-	struct rt_ralink_timer PeriodicTimer;
-	struct rt_ralink_timer APSDPeriodicTimer;
-	struct rt_ralink_timer LinkDownTimer;
-	struct rt_ralink_timer LinkUpTimer;
-#ifdef RTMP_MAC_PCI
-	u8 bPsPollTimerRunning;
-	struct rt_ralink_timer PsPollTimer;
-	struct rt_ralink_timer RadioOnOffTimer;
-#endif				/* RTMP_MAC_PCI // */
-	unsigned long PeriodicRound;
-	unsigned long OneSecPeriodicRound;
-
-	u8 RealRxPath;
-	BOOLEAN bLowThroughput;
-	BOOLEAN bEnableAutoAntennaCheck;
-	struct rt_ralink_timer RxAntEvalTimer;
-
-#ifdef RT30xx
-	u8 CaliBW40RfR24;
-	u8 CaliBW20RfR24;
-#endif				/* RT30xx // */
-
-#ifdef RTMP_MAC_USB
-	struct rt_ralink_timer AutoWakeupTimer;
-	BOOLEAN AutoWakeupTimerRunning;
-#endif				/* RTMP_MAC_USB // */
-};
-
-/***************************************************************************
-  *	802.11 N related data structures
-  **************************************************************************/
-struct reordering_mpdu {
-	struct reordering_mpdu *next;
-	void *pPacket;	/* converted to 802.3 frame */
-	int Sequence;		/* sequence number of MPDU */
-	BOOLEAN bAMSDU;
-};
-
-struct reordering_list {
-	struct reordering_mpdu *next;
-	int qlen;
-};
-
-struct reordering_mpdu_pool {
-	void *mem;
-	spinlock_t lock;
-	struct reordering_list freelist;
-};
-
-typedef enum _REC_BLOCKACK_STATUS {
-	Recipient_NONE = 0,
-	Recipient_USED,
-	Recipient_HandleRes,
-	Recipient_Accept
-} REC_BLOCKACK_STATUS, *PREC_BLOCKACK_STATUS;
-
-typedef enum _ORI_BLOCKACK_STATUS {
-	Originator_NONE = 0,
-	Originator_USED,
-	Originator_WaitRes,
-	Originator_Done
-} ORI_BLOCKACK_STATUS, *PORI_BLOCKACK_STATUS;
-
-struct rt_ba_ori_entry {
-	u8 Wcid;
-	u8 TID;
-	u8 BAWinSize;
-	u8 Token;
-/* Sequence is to fill every outgoing QoS DATA frame's sequence field in 802.11 header. */
-	u16 Sequence;
-	u16 TimeOutValue;
-	ORI_BLOCKACK_STATUS ORI_BA_Status;
-	struct rt_ralink_timer ORIBATimer;
-	void *pAdapter;
-};
-
-struct rt_ba_rec_entry {
-	u8 Wcid;
-	u8 TID;
-	u8 BAWinSize;	/* 7.3.1.14. each buffer is capable of holding a max AMSDU or MSDU. */
-	/*u8 NumOfRxPkt; */
-	/*u8    Curindidx; // the head in the RX reordering buffer */
-	u16 LastIndSeq;
-/*      u16          LastIndSeqAtTimer; */
-	u16 TimeOutValue;
-	struct rt_ralink_timer RECBATimer;
-	unsigned long LastIndSeqAtTimer;
-	unsigned long nDropPacket;
-	unsigned long rcvSeq;
-	REC_BLOCKACK_STATUS REC_BA_Status;
-/*      u8   RxBufIdxUsed; */
-	/* corresponding virtual address for RX reordering packet storage. */
-	/*RTMP_REORDERDMABUF MAP_RXBuf[MAX_RX_REORDERBUF]; */
-	spinlock_t RxReRingLock;	/* Rx Ring spinlock */
-/*      struct _BA_REC_ENTRY *pNext; */
-	void *pAdapter;
-	struct reordering_list list;
-};
-
-struct rt_ba_table {
-	unsigned long numAsRecipient;	/* I am recipient of numAsRecipient clients. These client are in the BARecEntry[] */
-	unsigned long numAsOriginator;	/* I am originator of   numAsOriginator clients. These clients are in the BAOriEntry[] */
-	unsigned long numDoneOriginator;	/* count Done Originator sessions */
-	struct rt_ba_ori_entry BAOriEntry[MAX_LEN_OF_BA_ORI_TABLE];
-	struct rt_ba_rec_entry BARecEntry[MAX_LEN_OF_BA_REC_TABLE];
-};
-
-/*For QureyBATableOID use; */
-struct PACKED rt_oid_ba_rec_entry {
-	u8 MACAddr[MAC_ADDR_LEN];
-	u8 BaBitmap;		/* if (BaBitmap&(1<<TID)), this session with{MACAddr, TID}exists, so read BufSize[TID] for BufferSize */
-	u8 rsv;
-	u8 BufSize[8];
-	REC_BLOCKACK_STATUS REC_BA_Status[8];
-};
-
-/*For QureyBATableOID use; */
-struct PACKED rt_oid_ba_ori_entry {
-	u8 MACAddr[MAC_ADDR_LEN];
-	u8 BaBitmap;		/* if (BaBitmap&(1<<TID)), this session with{MACAddr, TID}exists, so read BufSize[TID] for BufferSize, read ORI_BA_Status[TID] for status */
-	u8 rsv;
-	u8 BufSize[8];
-	ORI_BLOCKACK_STATUS ORI_BA_Status[8];
-};
-
-struct rt_queryba_table {
-	struct rt_oid_ba_ori_entry BAOriEntry[32];
-	struct rt_oid_ba_rec_entry BARecEntry[32];
-	u8 OriNum;		/* Number of below BAOriEntry */
-	u8 RecNum;		/* Number of below BARecEntry */
-};
-
-typedef union _BACAP_STRUC {
-	struct {
-		u32 RxBAWinLimit:8;
-		u32 TxBAWinLimit:8;
-		u32 AutoBA:1;	/* automatically BA */
-		u32 Policy:2;	/* 0: DELAY_BA 1:IMMED_BA  (//BA Policy subfiled value in ADDBA frame)   2:BA-not use */
-		u32 MpduDensity:3;
-		u32 AmsduEnable:1;	/*Enable AMSDU transmisstion */
-		u32 AmsduSize:1;	/* 0:3839, 1:7935 bytes. u32  MSDUSizeToBytes[]        = { 3839, 7935}; */
-		u32 MMPSmode:2;	/* MIMO power save more, 0:static, 1:dynamic, 2:rsv, 3:mimo enable */
-		u32 bHtAdhoc:1;	/* adhoc can use ht rate. */
-		u32 b2040CoexistScanSup:1;	/*As Sta, support do 2040 coexistence scan for AP. As Ap, support monitor trigger event to check if can use BW 40MHz. */
-		u32: 4;
-	} field;
-	u32 word;
-} BACAP_STRUC, *PBACAP_STRUC;
-
-struct rt_oid_add_ba_entry {
-	BOOLEAN IsRecipient;
-	u8 MACAddr[MAC_ADDR_LEN];
-	u8 TID;
-	u8 nMSDU;
-	u16 TimeOut;
-	BOOLEAN bAllTid;	/* If True, delete all TID for BA sessions with this MACaddr. */
-};
-
-#define IS_HT_STA(_pMacEntry)	\
-	(_pMacEntry->MaxHTPhyMode.field.MODE >= MODE_HTMIX)
-
-#define IS_HT_RATE(_pMacEntry)	\
-	(_pMacEntry->HTPhyMode.field.MODE >= MODE_HTMIX)
-
-#define PEER_IS_HT_RATE(_pMacEntry)	\
-	(_pMacEntry->HTPhyMode.field.MODE >= MODE_HTMIX)
-
-/*This structure is for all 802.11n card InterOptibilityTest action. Reset all Num every n second.  (Details see MLMEPeriodic) */
-struct rt_iot {
-	u8 Threshold[2];
-	u8 ReorderTimeOutNum[MAX_LEN_OF_BA_REC_TABLE];	/* compare with threshold[0] */
-	u8 RefreshNum[MAX_LEN_OF_BA_REC_TABLE];	/* compare with threshold[1] */
-	unsigned long OneSecInWindowCount;
-	unsigned long OneSecFrameDuplicateCount;
-	unsigned long OneSecOutWindowCount;
-	u8 DelOriAct;
-	u8 DelRecAct;
-	u8 RTSShortProt;
-	u8 RTSLongProt;
-	BOOLEAN bRTSLongProtOn;
-	BOOLEAN bLastAtheros;
-	BOOLEAN bCurrentAtheros;
-	BOOLEAN bNowAtherosBurstOn;
-	BOOLEAN bNextDisableRxBA;
-	BOOLEAN bToggle;
-};
-
-/* This is the registry setting for 802.11n transmit setting.  Used in advanced page. */
-typedef union _REG_TRANSMIT_SETTING {
-	struct {
-		/*u32  PhyMode:4; */
-		/*u32  MCS:7;                 // MCS */
-		u32 rsv0:10;
-		u32 TxBF:1;
-		u32 BW:1;	/*channel bandwidth 20MHz or 40 MHz */
-		u32 ShortGI:1;
-		u32 STBC:1;	/*SPACE */
-		u32 TRANSNO:2;
-		u32 HTMODE:1;
-		u32 EXTCHA:2;
-		u32 rsv:13;
-	} field;
-	u32 word;
-} REG_TRANSMIT_SETTING, *PREG_TRANSMIT_SETTING;
-
-typedef union _DESIRED_TRANSMIT_SETTING {
-	struct {
-		u16 MCS:7;	/* MCS */
-		u16 PhyMode:4;
-		u16 FixedTxMode:2;	/* If MCS isn't AUTO, fix rate in CCK, OFDM or HT mode. */
-		u16 rsv:3;
-	} field;
-	u16 word;
-} DESIRED_TRANSMIT_SETTING, *PDESIRED_TRANSMIT_SETTING;
-
-#ifdef RTMP_MAC_USB
-/***************************************************************************
-  *	USB-based chip Beacon related data structures
-  **************************************************************************/
-#define BEACON_BITMAP_MASK		0xff
-struct rt_beacon_sync {
-	u8 BeaconBuf[HW_BEACON_MAX_COUNT][HW_BEACON_OFFSET];
-	u8 BeaconTxWI[HW_BEACON_MAX_COUNT][TXWI_SIZE];
-	unsigned long TimIELocationInBeacon[HW_BEACON_MAX_COUNT];
-	unsigned long CapabilityInfoLocationInBeacon[HW_BEACON_MAX_COUNT];
-	BOOLEAN EnableBeacon;	/* trigger to enable beacon transmission. */
-	u8 BeaconBitMap;	/* NOTE: If the MAX_MBSSID_NUM is larger than 8, this parameter needs to change. */
-	u8 DtimBitOn;	/* NOTE: If the MAX_MBSSID_NUM is larger than 8, this parameter needs to change. */
-};
-#endif /* RTMP_MAC_USB // */
-
-/***************************************************************************
-  *	Multiple SSID related data structures
-  **************************************************************************/
-#define WLAN_MAX_NUM_OF_TIM			((MAX_LEN_OF_MAC_TABLE >> 3) + 1)	/* /8 + 1 */
-#define WLAN_CT_TIM_BCMC_OFFSET		0	/* unit: 32B */
-
-/* clear bcmc TIM bit */
-#define WLAN_MR_TIM_BCMC_CLEAR(apidx) \
-	pAd->ApCfg.MBSSID[apidx].TimBitmaps[WLAN_CT_TIM_BCMC_OFFSET] &= ~BIT8[0];
-
-/* set bcmc TIM bit */
-#define WLAN_MR_TIM_BCMC_SET(apidx) \
-	pAd->ApCfg.MBSSID[apidx].TimBitmaps[WLAN_CT_TIM_BCMC_OFFSET] |= BIT8[0];
-
-/* clear a station PS TIM bit */
-#define WLAN_MR_TIM_BIT_CLEAR(ad_p, apidx, wcid) \
-	{	u8 tim_offset = wcid >> 3; \
-		u8 bit_offset = wcid & 0x7; \
-		ad_p->ApCfg.MBSSID[apidx].TimBitmaps[tim_offset] &= (~BIT8[bit_offset]); }
-
-/* set a station PS TIM bit */
-#define WLAN_MR_TIM_BIT_SET(ad_p, apidx, wcid) \
-	{	u8 tim_offset = wcid >> 3; \
-		u8 bit_offset = wcid & 0x7; \
-		ad_p->ApCfg.MBSSID[apidx].TimBitmaps[tim_offset] |= BIT8[bit_offset]; }
-
-/* configuration common to OPMODE_AP as well as OPMODE_STA */
-struct rt_common_config {
-
-	BOOLEAN bCountryFlag;
-	u8 CountryCode[3];
-	u8 Geography;
-	u8 CountryRegion;	/* Enum of country region, 0:FCC, 1:IC, 2:ETSI, 3:SPAIN, 4:France, 5:MKK, 6:MKK1, 7:Israel */
-	u8 CountryRegionForABand;	/* Enum of country region for A band */
-	u8 PhyMode;		/* PHY_11A, PHY_11B, PHY_11BG_MIXED, PHY_ABG_MIXED */
-	u16 Dsifs;		/* in units of usec */
-	unsigned long PacketFilter;	/* Packet filter for receiving */
-	u8 RegulatoryClass;
-
-	char Ssid[MAX_LEN_OF_SSID];	/* NOT NULL-terminated */
-	u8 SsidLen;		/* the actual ssid length in used */
-	u8 LastSsidLen;	/* the actual ssid length in used */
-	char LastSsid[MAX_LEN_OF_SSID];	/* NOT NULL-terminated */
-	u8 LastBssid[MAC_ADDR_LEN];
-
-	u8 Bssid[MAC_ADDR_LEN];
-	u16 BeaconPeriod;
-	u8 Channel;
-	u8 CentralChannel;	/* Central Channel when using 40MHz is indicating. not real channel. */
-
-	u8 SupRate[MAX_LEN_OF_SUPPORTED_RATES];
-	u8 SupRateLen;
-	u8 ExtRate[MAX_LEN_OF_SUPPORTED_RATES];
-	u8 ExtRateLen;
-	u8 DesireRate[MAX_LEN_OF_SUPPORTED_RATES];	/* OID_802_11_DESIRED_RATES */
-	u8 MaxDesiredRate;
-	u8 ExpectedACKRate[MAX_LEN_OF_SUPPORTED_RATES];
-
-	unsigned long BasicRateBitmap;	/* backup basic ratebitmap */
-
-	BOOLEAN bAPSDCapable;
-	BOOLEAN bInServicePeriod;
-	BOOLEAN bAPSDAC_BE;
-	BOOLEAN bAPSDAC_BK;
-	BOOLEAN bAPSDAC_VI;
-	BOOLEAN bAPSDAC_VO;
-
-	/* because TSPEC can modify the APSD flag, we need to keep the APSD flag
-	   requested in association stage from the station;
-	   we need to recover the APSD flag after the TSPEC is deleted. */
-	BOOLEAN bACMAPSDBackup[4];	/* for delivery-enabled & trigger-enabled both */
-	BOOLEAN bACMAPSDTr[4];	/* no use */
-
-	BOOLEAN bNeedSendTriggerFrame;
-	BOOLEAN bAPSDForcePowerSave;	/* Force power save mode, should only use in APSD-STAUT */
-	unsigned long TriggerTimerCount;
-	u8 MaxSPLength;
-	u8 BBPCurrentBW;	/* BW_10,       BW_20, BW_40 */
-	/* move to MULTISSID_STRUCT for MBSS */
-	/*HTTRANSMIT_SETTING    HTPhyMode, MaxHTPhyMode, MinHTPhyMode;// For transmit phy setting in TXWI. */
-	REG_TRANSMIT_SETTING RegTransmitSetting;	/*registry transmit setting. this is for reading registry setting only. not useful. */
-	/*u8       FixedTxMode;              // Fixed Tx Mode (CCK, OFDM), for HT fixed tx mode (GF, MIX) , refer to RegTransmitSetting.field.HTMode */
-	u8 TxRate;		/* Same value to fill in TXD. TxRate is 6-bit */
-	u8 MaxTxRate;	/* RATE_1, RATE_2, RATE_5_5, RATE_11 */
-	u8 TxRateIndex;	/* Tx rate index in RateSwitchTable */
-	u8 TxRateTableSize;	/* Valid Tx rate table size in RateSwitchTable */
-	/*BOOLEAN               bAutoTxRateSwitch; */
-	u8 MinTxRate;	/* RATE_1, RATE_2, RATE_5_5, RATE_11 */
-	u8 RtsRate;		/* RATE_xxx */
-	HTTRANSMIT_SETTING MlmeTransmit;	/* MGMT frame PHY rate setting when operation at Ht rate. */
-	u8 MlmeRate;		/* RATE_xxx, used to send MLME frames */
-	u8 BasicMlmeRate;	/* Default Rate for sending MLME frames */
-
-	u16 RtsThreshold;	/* in unit of BYTE */
-	u16 FragmentThreshold;	/* in unit of BYTE */
-
-	u8 TxPower;		/* in unit of mW */
-	unsigned long TxPowerPercentage;	/* 0~100 % */
-	unsigned long TxPowerDefault;	/* keep for TxPowerPercentage */
-	u8 PwrConstraint;
-
-	BACAP_STRUC BACapability;	/*   NO USE = 0XFF  ;  IMMED_BA =1  ;  DELAY_BA=0 */
-	BACAP_STRUC REGBACapability;	/*   NO USE = 0XFF  ;  IMMED_BA =1  ;  DELAY_BA=0 */
-
-	struct rt_iot IOTestParm;	/* 802.11n InterOpbility Test Parameter; */
-	unsigned long TxPreamble;	/* Rt802_11PreambleLong, Rt802_11PreambleShort, Rt802_11PreambleAuto */
-	BOOLEAN bUseZeroToDisableFragment;	/* Microsoft use 0 as disable */
-	unsigned long UseBGProtection;	/* 0: auto, 1: always use, 2: always not use */
-	BOOLEAN bUseShortSlotTime;	/* 0: disable, 1 - use short slot (9us) */
-	BOOLEAN bEnableTxBurst;	/* 1: enble TX PACKET BURST (when BA is established or AP is not a legacy WMM AP), 0: disable TX PACKET BURST */
-	BOOLEAN bAggregationCapable;	/* 1: enable TX aggregation when the peer supports it */
-	BOOLEAN bPiggyBackCapable;	/* 1: enable TX piggy-back according MAC's version */
-	BOOLEAN bIEEE80211H;	/* 1: enable IEEE802.11h spec. */
-	unsigned long DisableOLBCDetect;	/* 0: enable OLBC detect; 1 disable OLBC detect */
-
-	BOOLEAN bRdg;
-
-	BOOLEAN bWmmCapable;	/* 0:disable WMM, 1:enable WMM */
-	struct rt_qos_capability_parm APQosCapability;	/* QOS capability of the current associated AP */
-	struct rt_edca_parm APEdcaParm;	/* EDCA parameters of the current associated AP */
-	struct rt_qbss_load_parm APQbssLoad;	/* QBSS load of the current associated AP */
-	u8 AckPolicy[4];	/* ACK policy of the specified AC. see ACK_xxx */
-	BOOLEAN bDLSCapable;	/* 0:disable DLS, 1:enable DLS */
-	/* a bitmap of BOOLEAN flags. each bit represent an operation status of a particular */
-	/* BOOLEAN control, either ON or OFF. These flags should always be accessed via */
-	/* OPSTATUS_TEST_FLAG(), OPSTATUS_SET_FLAG(), OP_STATUS_CLEAR_FLAG() macros. */
-	/* see fOP_STATUS_xxx in RTMP_DEF.C for detail bit definition */
-	unsigned long OpStatusFlags;
-
-	BOOLEAN NdisRadioStateOff;	/*For HCT 12.0, set this flag to TRUE instead of called MlmeRadioOff. */
-	ABGBAND_STATE BandState;	/* For setting BBP used on B/G or A mode. */
-
-	/* IEEE802.11H--DFS. */
-	struct rt_radar_detect RadarDetect;
-
-	/* HT */
-	u8 BASize;		/* USer desired BAWindowSize. Should not exceed our max capability */
-	/*struct rt_ht_capability      SupportedHtPhy; */
-	struct rt_ht_capability DesiredHtPhy;
-	struct rt_ht_capability_ie HtCapability;
-	struct rt_add_ht_info_ie AddHTInfo;	/* Useful as AP. */
-	/*This IE is used with channel switch announcement element when changing to a new 40MHz. */
-	/*This IE is included in channel switch announcement frames 7.4.1.5, beacons, probe Rsp. */
-	struct rt_new_ext_chan_ie NewExtChanOffset;	/*7.3.2.20A, 1 if extension channel is above the control channel, 3 if below, 0 if not present */
-
-	BOOLEAN bHTProtect;
-	BOOLEAN bMIMOPSEnable;
-	BOOLEAN bBADecline;
-/*2008/11/05: KH add to support Antenna power-saving of AP<-- */
-	BOOLEAN bGreenAPEnable;
-/*2008/11/05: KH add to support Antenna power-saving of AP--> */
-	BOOLEAN bDisableReordering;
-	BOOLEAN bForty_Mhz_Intolerant;
-	BOOLEAN bExtChannelSwitchAnnouncement;
-	BOOLEAN bRcvBSSWidthTriggerEvents;
-	unsigned long LastRcvBSSWidthTriggerEventsTime;
-
-	u8 TxBASize;
-
-	/* Enable wireless event */
-	BOOLEAN bWirelessEvent;
-	BOOLEAN bWiFiTest;	/* Enable this parameter for WiFi test */
-
-	/* Tx & Rx Stream number selection */
-	u8 TxStream;
-	u8 RxStream;
-
-	BOOLEAN bHardwareRadio;	/* Hardware controlled Radio enabled */
-
-#ifdef RTMP_MAC_USB
-	BOOLEAN bMultipleIRP;	/* Multiple Bulk IN flag */
-	u8 NumOfBulkInIRP;	/* if bMultipleIRP == TRUE, NumOfBulkInIRP will be 4 otherwise be 1 */
-	struct rt_ht_capability SupportedHtPhy;
-	unsigned long MaxPktOneTxBulk;
-	u8 TxBulkFactor;
-	u8 RxBulkFactor;
-
-	BOOLEAN IsUpdateBeacon;
-	struct rt_beacon_sync *pBeaconSync;
-	struct rt_ralink_timer BeaconUpdateTimer;
-	u32 BeaconAdjust;
-	u32 BeaconFactor;
-	u32 BeaconRemain;
-#endif				/* RTMP_MAC_USB // */
-
-	spinlock_t MeasureReqTabLock;
-	struct rt_measure_req_tab *pMeasureReqTab;
-
-	spinlock_t TpcReqTabLock;
-	struct rt_tpc_req_tab *pTpcReqTab;
-
-	BOOLEAN PSPXlink;	/* 0: Disable. 1: Enable */
-
-#if defined(RT305x) || defined(RT30xx)
-	/* request by Gary, for High Power issue */
-	u8 HighPowerPatchDisabled;
-#endif
-
-	BOOLEAN HT_DisallowTKIP;	/* Restrict the encryption type in 11n HT mode */
-};
-
-/* Modified by Wu Xi-Kun 4/21/2006 */
-/* STA configuration and status */
-struct rt_sta_admin_config {
-	/* GROUP 1 - */
-	/*   User configuration loaded from Registry, E2PROM or OID_xxx. These settings describe */
-	/*   the user intended configuration, but not necessary fully equal to the final */
-	/*   settings in ACTIVE BSS after negotiation/compromise with the BSS holder (either */
-	/*   AP or IBSS holder). */
-	/*   Once initialized, user configuration can only be changed via OID_xxx */
-	u8 BssType;		/* BSS_INFRA or BSS_ADHOC */
-	u16 AtimWin;		/* used when starting a new IBSS */
-
-	/* GROUP 2 - */
-	/*   User configuration loaded from Registry, E2PROM or OID_xxx. These settings describe */
-	/*   the user intended configuration, and should be always applied to the final */
-	/*   settings in ACTIVE BSS without compromising with the BSS holder. */
-	/*   Once initialized, user configuration can only be changed via OID_xxx */
-	u8 RssiTrigger;
-	u8 RssiTriggerMode;	/* RSSI_TRIGGERED_UPON_BELOW_THRESHOLD or RSSI_TRIGGERED_UPON_EXCCEED_THRESHOLD */
-	u16 DefaultListenCount;	/* default listen count; */
-	unsigned long WindowsPowerMode;	/* Power mode for AC power */
-	unsigned long WindowsBatteryPowerMode;	/* Power mode for battery if exists */
-	BOOLEAN bWindowsACCAMEnable;	/* Enable CAM power mode when AC on */
-	BOOLEAN bAutoReconnect;	/* Set to TRUE when setting OID_802_11_SSID with no matching BSSID */
-	unsigned long WindowsPowerProfile;	/* Windows power profile, for NDIS5.1 PnP */
-
-	/* MIB:ieee802dot11.dot11smt(1).dot11StationConfigTable(1) */
-	u16 Psm;		/* power management mode   (PWR_ACTIVE|PWR_SAVE) */
-	u16 DisassocReason;
-	u8 DisassocSta[MAC_ADDR_LEN];
-	u16 DeauthReason;
-	u8 DeauthSta[MAC_ADDR_LEN];
-	u16 AuthFailReason;
-	u8 AuthFailSta[MAC_ADDR_LEN];
-
-	NDIS_802_11_PRIVACY_FILTER PrivacyFilter;	/* PrivacyFilter enum for 802.1X */
-	NDIS_802_11_AUTHENTICATION_MODE AuthMode;	/* This should match to whatever microsoft defined */
-	NDIS_802_11_WEP_STATUS WepStatus;
-	NDIS_802_11_WEP_STATUS OrigWepStatus;	/* Original wep status set from OID */
-
-	/* Add to support different cipher suite for WPA2/WPA mode */
-	NDIS_802_11_ENCRYPTION_STATUS GroupCipher;	/* Multicast cipher suite */
-	NDIS_802_11_ENCRYPTION_STATUS PairCipher;	/* Unicast cipher suite */
-	BOOLEAN bMixCipher;	/* Indicate current Pair & Group use different cipher suites */
-	u16 RsnCapability;
-
-	NDIS_802_11_WEP_STATUS GroupKeyWepStatus;
-
-	u8 WpaPassPhrase[64];	/* WPA PSK pass phrase */
-	u32 WpaPassPhraseLen;	/* the length of WPA PSK pass phrase */
-	u8 PMK[32];		/* WPA PSK mode PMK */
-	u8 PTK[64];		/* WPA PSK mode PTK */
-	u8 GTK[32];		/* GTK from authenticator */
-	struct rt_bssid_info SavedPMK[PMKID_NO];
-	u32 SavedPMKNum;	/* Saved PMKID number */
-
-	u8 DefaultKeyId;
-
-	/* WPA 802.1x port control, WPA_802_1X_PORT_SECURED, WPA_802_1X_PORT_NOT_SECURED */
-	u8 PortSecured;
-
-	/* For WPA countermeasures */
-	unsigned long LastMicErrorTime;	/* record last MIC error time */
-	unsigned long MicErrCnt;	/* Should be 0, 1, 2, then reset to zero (after disassociation). */
-	BOOLEAN bBlockAssoc;	/* Block associate attempt for 60 seconds after counter measure occurred. */
-	/* For WPA-PSK supplicant state */
-	WPA_STATE WpaState;	/* Default is SS_NOTUSE and handled by microsoft 802.1x */
-	u8 ReplayCounter[8];
-	u8 ANonce[32];	/* ANonce for WPA-PSK from auhenticator */
-	u8 SNonce[32];	/* SNonce for WPA-PSK */
-
-	u8 LastSNR0;		/* last received BEACON's SNR */
-	u8 LastSNR1;		/* last received BEACON's SNR for 2nd  antenna */
-	struct rt_rssi_sample RssiSample;
-	unsigned long NumOfAvgRssiSample;
-
-	unsigned long LastBeaconRxTime;	/* OS's timestamp of the last BEACON RX time */
-	unsigned long Last11bBeaconRxTime;	/* OS's timestamp of the last 11B BEACON RX time */
-	unsigned long Last11gBeaconRxTime;	/* OS's timestamp of the last 11G BEACON RX time */
-	unsigned long Last20NBeaconRxTime;	/* OS's timestamp of the last 20MHz N BEACON RX time */
-
-	unsigned long LastScanTime;	/* Record last scan time for issue BSSID_SCAN_LIST */
-	unsigned long ScanCnt;		/* Scan counts since most recent SSID, BSSID, SCAN OID request */
-	BOOLEAN bSwRadio;	/* Software controlled Radio On/Off, TRUE: On */
-	BOOLEAN bHwRadio;	/* Hardware controlled Radio On/Off, TRUE: On */
-	BOOLEAN bRadio;		/* Radio state, And of Sw & Hw radio state */
-	BOOLEAN bHardwareRadio;	/* Hardware controlled Radio enabled */
-	BOOLEAN bShowHiddenSSID;	/* Show all known SSID in SSID list get operation */
-
-	/* New for WPA, windows want us to keep association information and */
-	/* Fixed IEs from last association response */
-	struct rt_ndis_802_11_association_information AssocInfo;
-	u16 ReqVarIELen;	/* Length of next VIE include EID & Length */
-	u8 ReqVarIEs[MAX_VIE_LEN];	/* The content saved here should be little-endian format. */
-	u16 ResVarIELen;	/* Length of next VIE include EID & Length */
-	u8 ResVarIEs[MAX_VIE_LEN];
-
-	u8 RSNIE_Len;
-	u8 RSN_IE[MAX_LEN_OF_RSNIE];	/* The content saved here should be little-endian format. */
-
-	unsigned long CLBusyBytes;	/* Save the total bytes received during channel load scan time */
-	u16 RPIDensity[8];	/* Array for RPI density collection */
-
-	u8 RMReqCnt;		/* Number of measurement request saved. */
-	u8 CurrentRMReqIdx;	/* Number of measurement request saved. */
-	BOOLEAN ParallelReq;	/* Parallel measurement, only one request performed, */
-	/* It must be the same channel with maximum duration */
-	u16 ParallelDuration;	/* Maximum duration for parallel measurement */
-	u8 ParallelChannel;	/* Only one channel with parallel measurement */
-	u16 IAPPToken;	/* IAPP dialog token */
-	/* Hack for channel load and noise histogram parameters */
-	u8 NHFactor;		/* Parameter for Noise histogram */
-	u8 CLFactor;		/* Parameter for channel load */
-
-	struct rt_ralink_timer StaQuickResponeForRateUpTimer;
-	BOOLEAN StaQuickResponeForRateUpTimerRunning;
-
-	u8 DtimCount;	/* 0.. DtimPeriod-1 */
-	u8 DtimPeriod;	/* default = 3 */
-
-	/*////////////////////////////////////////////////////////////////////////////////////// */
-	/* This is only for WHQL test. */
-	BOOLEAN WhqlTest;
-	/*////////////////////////////////////////////////////////////////////////////////////// */
-
-	struct rt_ralink_timer WpaDisassocAndBlockAssocTimer;
-	/* Fast Roaming */
-	BOOLEAN bAutoRoaming;	/* 0:disable auto roaming by RSSI, 1:enable auto roaming by RSSI */
-	char dBmToRoam;		/* the condition to roam when receiving Rssi less than this value. It's negative value. */
-
-	BOOLEAN IEEE8021X;
-	BOOLEAN IEEE8021x_required_keys;
-	struct rt_cipher_key DesireSharedKey[4];	/* Record user desired WEP keys */
-	u8 DesireSharedKeyId;
-
-	/* 0: driver ignores wpa_supplicant */
-	/* 1: wpa_supplicant initiates scanning and AP selection */
-	/* 2: driver takes care of scanning, AP selection, and IEEE 802.11 association parameters */
-	u8 WpaSupplicantUP;
-	u8 WpaSupplicantScanCount;
-	BOOLEAN bRSN_IE_FromWpaSupplicant;
-
-	char dev_name[16];
-	u16 OriDevType;
-
-	BOOLEAN bTGnWifiTest;
-	BOOLEAN bScanReqIsFromWebUI;
-
-	HTTRANSMIT_SETTING HTPhyMode, MaxHTPhyMode, MinHTPhyMode;	/* For transmit phy setting in TXWI. */
-	DESIRED_TRANSMIT_SETTING DesiredTransmitSetting;
-	struct rt_ht_phy_info DesiredHtPhyInfo;
-	BOOLEAN bAutoTxRateSwitch;
-
-#ifdef RTMP_MAC_PCI
-	u8 BBPR3;
-	/* PS Control has 2 meanings for advanced power save function. */
-	/* 1. EnablePSinIdle : When no connection, always radio off except need to do site survey. */
-	/* 2. EnableNewPS  : will save more current in sleep or radio off mode. */
-	PS_CONTROL PSControl;
-#endif				/* RTMP_MAC_PCI // */
-
-	BOOLEAN bAutoConnectByBssid;
-	unsigned long BeaconLostTime;	/* seconds */
-	BOOLEAN bForceTxBurst;	/* 1: force enble TX PACKET BURST, 0: disable */
-};
-
-/* This data structure keeps the current active BSS/IBSS's configuration that this STA */
-/* had agreed upon joining the network. Which means these parameters are usually decided */
-/* by the BSS/IBSS creator instead of user configuration. Data in this data structure */
-/* is valid only when either ADHOC_ON(pAd) or INFRA_ON(pAd) is TRUE. */
-/* Normally, after SCAN or failed roaming attempts, we need to recover back to */
-/* the current active settings. */
-struct rt_sta_active_config {
-	u16 Aid;
-	u16 AtimWin;		/* in kusec; IBSS parameter set element */
-	u16 CapabilityInfo;
-	u16 CfpMaxDuration;
-	u16 CfpPeriod;
-
-	/* Copy supported rate from desired AP's beacon. We are trying to match */
-	/* AP's supported and extended rate settings. */
-	u8 SupRate[MAX_LEN_OF_SUPPORTED_RATES];
-	u8 ExtRate[MAX_LEN_OF_SUPPORTED_RATES];
-	u8 SupRateLen;
-	u8 ExtRateLen;
-	/* Copy supported ht from desired AP's beacon. We are trying to match */
-	struct rt_ht_phy_info SupportedPhyInfo;
-	struct rt_ht_capability SupportedHtPhy;
-};
-
-struct rt_mac_table_entry;
-
-struct rt_mac_table_entry {
-	/*Choose 1 from ValidAsWDS and ValidAsCLI  to validize. */
-	BOOLEAN ValidAsCLI;	/* Sta mode, set this TRUE after Linkup,too. */
-	BOOLEAN ValidAsWDS;	/* This is WDS Entry. only for AP mode. */
-	BOOLEAN ValidAsApCli;	/* This is a AP-Client entry, only for AP mode which enable AP-Client functions. */
-	BOOLEAN ValidAsMesh;
-	BOOLEAN ValidAsDls;	/* This is DLS Entry. only for STA mode. */
-	BOOLEAN isCached;
-	BOOLEAN bIAmBadAtheros;	/* Flag if this is Atheros chip that has IOT problem.  We need to turn on RTS/CTS protection. */
-
-	u8 EnqueueEapolStartTimerRunning;	/* Enqueue EAPoL-Start for triggering EAP SM */
-	/*jan for wpa */
-	/* record which entry revoke MIC Failure, if it leaves the BSS itself, AP won't update aMICFailTime MIB */
-	u8 CMTimerRunning;
-	u8 apidx;		/* MBSS number */
-	u8 RSNIE_Len;
-	u8 RSN_IE[MAX_LEN_OF_RSNIE];
-	u8 ANonce[LEN_KEY_DESC_NONCE];
-	u8 SNonce[LEN_KEY_DESC_NONCE];
-	u8 R_Counter[LEN_KEY_DESC_REPLAY];
-	u8 PTK[64];
-	u8 ReTryCounter;
-	struct rt_ralink_timer RetryTimer;
-	struct rt_ralink_timer EnqueueStartForPSKTimer;	/* A timer which enqueue EAPoL-Start for triggering PSK SM */
-	NDIS_802_11_AUTHENTICATION_MODE AuthMode;	/* This should match to whatever microsoft defined */
-	NDIS_802_11_WEP_STATUS WepStatus;
-	NDIS_802_11_WEP_STATUS GroupKeyWepStatus;
-	AP_WPA_STATE WpaState;
-	GTK_STATE GTKState;
-	u16 PortSecured;
-	NDIS_802_11_PRIVACY_FILTER PrivacyFilter;	/* PrivacyFilter enum for 802.1X */
-	struct rt_cipher_key PairwiseKey;
-	void *pAd;
-	int PMKID_CacheIdx;
-	u8 PMKID[LEN_PMKID];
-
-	u8 Addr[MAC_ADDR_LEN];
-	u8 PsMode;
-	SST Sst;
-	AUTH_STATE AuthState;	/* for SHARED KEY authentication state machine used only */
-	BOOLEAN IsReassocSta;	/* Indicate whether this is a reassociation procedure */
-	u16 Aid;
-	u16 CapabilityInfo;
-	u8 LastRssi;
-	unsigned long NoDataIdleCount;
-	u16 StationKeepAliveCount;	/* unit: second */
-	unsigned long PsQIdleCount;
-	struct rt_queue_header PsQueue;
-
-	u32 StaConnectTime;	/* the live time of this station since associated with AP */
-
-	BOOLEAN bSendBAR;
-	u16 NoBADataCountDown;
-
-	u32 CachedBuf[16];	/* u32 (4 bytes) for alignment */
-	u32 TxBFCount;		/* 3*3 */
-	u32 FIFOCount;
-	u32 DebugFIFOCount;
-	u32 DebugTxCount;
-	BOOLEAN bDlsInit;
-
-/*==================================================== */
-/*WDS entry needs these */
-/* if ValidAsWDS==TRUE, MatchWDSTabIdx is the index in WdsTab.MacTab */
-	u32 MatchWDSTabIdx;
-	u8 MaxSupportedRate;
-	u8 CurrTxRate;
-	u8 CurrTxRateIndex;
-	/* to record the each TX rate's quality. 0 is best, the bigger the worse. */
-	u16 TxQuality[MAX_STEP_OF_TX_RATE_SWITCH];
-/*      u16          OneSecTxOkCount; */
-	u32 OneSecTxNoRetryOkCount;
-	u32 OneSecTxRetryOkCount;
-	u32 OneSecTxFailCount;
-	u32 ContinueTxFailCnt;
-	u32 CurrTxRateStableTime;	/* # of second in current TX rate */
-	u8 TxRateUpPenalty;	/* extra # of second penalty due to last unstable condition */
-/*==================================================== */
-
-	BOOLEAN fNoisyEnvironment;
-	BOOLEAN fLastSecAccordingRSSI;
-	u8 LastSecTxRateChangeAction;	/* 0: no change, 1:rate UP, 2:rate down */
-	char LastTimeTxRateChangeAction;	/*Keep last time value of LastSecTxRateChangeAction */
-	unsigned long LastTxOkCount;
-	u8 PER[MAX_STEP_OF_TX_RATE_SWITCH];
-
-	/* a bitmap of BOOLEAN flags. each bit represent an operation status of a particular */
-	/* BOOLEAN control, either ON or OFF. These flags should always be accessed via */
-	/* CLIENT_STATUS_TEST_FLAG(), CLIENT_STATUS_SET_FLAG(), CLIENT_STATUS_CLEAR_FLAG() macros. */
-	/* see fOP_STATUS_xxx in RTMP_DEF.C for detail bit definition. fCLIENT_STATUS_AMSDU_INUSED */
-	unsigned long ClientStatusFlags;
-
-	HTTRANSMIT_SETTING HTPhyMode, MaxHTPhyMode, MinHTPhyMode;	/* For transmit phy setting in TXWI. */
-
-	/* HT EWC MIMO-N used parameters */
-	u16 RXBAbitmap;	/* fill to on-chip  RXWI_BA_BITMASK in 8.1.3RX attribute entry format */
-	u16 TXBAbitmap;	/* This bitmap as originator, only keep in software used to mark AMPDU bit in TXWI */
-	u16 TXAutoBAbitmap;
-	u16 BADeclineBitmap;
-	u16 BARecWcidArray[NUM_OF_TID];	/* The mapping wcid of recipient session. if RXBAbitmap bit is masked */
-	u16 BAOriWcidArray[NUM_OF_TID];	/* The mapping wcid of originator session. if TXBAbitmap bit is masked */
-	u16 BAOriSequence[NUM_OF_TID];	/* The mapping wcid of originator session. if TXBAbitmap bit is masked */
-
-	/* 802.11n features. */
-	u8 MpduDensity;
-	u8 MaxRAmpduFactor;
-	u8 AMsduSize;
-	u8 MmpsMode;		/* MIMO power save more. */
-
-	struct rt_ht_capability_ie HTCapability;
-
-	BOOLEAN bAutoTxRateSwitch;
-
-	u8 RateLen;
-	struct rt_mac_table_entry *pNext;
-	u16 TxSeq[NUM_OF_TID];
-	u16 NonQosDataSeq;
-
-	struct rt_rssi_sample RssiSample;
-
-	u32 TXMCSExpected[16];
-	u32 TXMCSSuccessful[16];
-	u32 TXMCSFailed[16];
-	u32 TXMCSAutoFallBack[16][16];
-
-	unsigned long LastBeaconRxTime;
-
-	unsigned long AssocDeadLine;
-};
-
-struct rt_mac_table {
-	u16 Size;
-	struct rt_mac_table_entry *Hash[HASH_TABLE_SIZE];
-	struct rt_mac_table_entry Content[MAX_LEN_OF_MAC_TABLE];
-	struct rt_queue_header McastPsQueue;
-	unsigned long PsQIdleCount;
-	BOOLEAN fAnyStationInPsm;
-	BOOLEAN fAnyStationBadAtheros;	/* Check if any Station is atheros 802.11n Chip.  We need to use RTS/CTS with Atheros 802,.11n chip. */
-	BOOLEAN fAnyTxOPForceDisable;	/* Check if it is necessary to disable BE TxOP */
-	BOOLEAN fAllStationAsRalink;	/* Check if all stations are ralink-chipset */
-	BOOLEAN fAnyStationIsLegacy;	/* Check if I use legacy rate to transmit to my BSS Station/ */
-	BOOLEAN fAnyStationNonGF;	/* Check if any Station can't support GF. */
-	BOOLEAN fAnyStation20Only;	/* Check if any Station can't support GF. */
-	BOOLEAN fAnyStationMIMOPSDynamic;	/* Check if any Station is MIMO Dynamic */
-	BOOLEAN fAnyBASession;	/* Check if there is BA session.  Force turn on RTS/CTS */
-/*2008/10/28: KH add to support Antenna power-saving of AP<-- */
-/*2008/10/28: KH add to support Antenna power-saving of AP--> */
-};
-
-struct wificonf {
-	BOOLEAN bShortGI;
-	BOOLEAN bGreenField;
-};
-
-struct rt_rtmp_dev_info {
-	u8 chipName[16];
-	RTMP_INF_TYPE infType;
-};
-
-struct rt_rtmp_chip_op {
-	/*  Calibration access related callback functions */
-	int (*eeinit) (struct rt_rtmp_adapter *pAd);	/* int (*eeinit)(struct rt_rtmp_adapter *pAd); */
-	int (*eeread) (struct rt_rtmp_adapter *pAd, u16 offset, u16 *pValue);	/* int (*eeread)(struct rt_rtmp_adapter *pAd, int offset, u16 *pValue); */
-
-	/* MCU related callback functions */
-	int (*loadFirmware) (struct rt_rtmp_adapter *pAd);	/* int (*loadFirmware)(struct rt_rtmp_adapter *pAd); */
-	int (*eraseFirmware) (struct rt_rtmp_adapter *pAd);	/* int (*eraseFirmware)(struct rt_rtmp_adapter *pAd); */
-	int (*sendCommandToMcu) (struct rt_rtmp_adapter *pAd, u8 cmd, u8 token, u8 arg0, u8 arg1);;	/* int (*sendCommandToMcu)(struct rt_rtmp_adapter *pAd, u8 cmd, u8 token, u8 arg0, u8 arg1); */
-
-	/* RF access related callback functions */
-	struct rt_reg_pair *pRFRegTable;
-	void (*AsicRfInit) (struct rt_rtmp_adapter *pAd);
-	void (*AsicRfTurnOn) (struct rt_rtmp_adapter *pAd);
-	void (*AsicRfTurnOff) (struct rt_rtmp_adapter *pAd);
-	void (*AsicReverseRfFromSleepMode) (struct rt_rtmp_adapter *pAd);
-	void (*AsicHaltAction) (struct rt_rtmp_adapter *pAd);
-};
-
-/* */
-/*  The miniport adapter structure */
-/* */
-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;
-
-#ifdef RTMP_MAC_PCI
-/*****************************************************************************************/
-/*      PCI related parameters																  */
-/*****************************************************************************************/
-	u8 *CSRBaseAddress;	/* PCI MMIO Base Address, all access will use */
-	unsigned int irq_num;
-
-	u16 LnkCtrlBitMask;
-	u16 RLnkCtrlConfiguration;
-	u16 RLnkCtrlOffset;
-	u16 HostLnkCtrlConfiguration;
-	u16 HostLnkCtrlOffset;
-	u16 PCIePowerSaveLevel;
-	unsigned long Rt3xxHostLinkCtrl;	/* USed for 3090F chip */
-	unsigned long Rt3xxRalinkLinkCtrl;	/* USed for 3090F chip */
-	u16 DeviceID;	/* Read from PCI config */
-	unsigned long AccessBBPFailCount;
-	BOOLEAN bPCIclkOff;	/* flag that indicates if the PICE power status in Configuration Space.. */
-	BOOLEAN bPCIclkOffDisableTx;	/* */
-
-	BOOLEAN brt30xxBanMcuCmd;	/*when = 0xff means all commands are ok to set . */
-	BOOLEAN b3090ESpecialChip;	/*3090E special chip that write EEPROM 0x24=0x9280. */
-	unsigned long CheckDmaBusyCount;	/* Check Interrupt Status Register Count. */
-
-	u32 int_enable_reg;
-	u32 int_disable_mask;
-	u32 int_pending;
-
-	struct rt_rtmp_dmabuf TxBufSpace[NUM_OF_TX_RING];	/* Shared memory of all 1st pre-allocated TxBuf associated with each TXD */
-	struct rt_rtmp_dmabuf RxDescRing;	/* Shared memory for RX descriptors */
-	struct rt_rtmp_dmabuf TxDescRing[NUM_OF_TX_RING];	/* Shared memory for Tx descriptors */
-	struct rt_rtmp_tx_ring TxRing[NUM_OF_TX_RING];	/* AC0~4 + HCCA */
-#endif				/* RTMP_MAC_PCI // */
-
-	spinlock_t irq_lock;
-	u8 irq_disabled;
-
-#ifdef RTMP_MAC_USB
-/*****************************************************************************************/
-/*      USB related parameters                                                           */
-/*****************************************************************************************/
-	struct usb_config_descriptor *config;
-	u32 BulkInEpAddr;	/* bulk-in endpoint address */
-	u32 BulkOutEpAddr[6];	/* bulk-out endpoint address */
-
-	u32 NumberOfPipes;
-	u16 BulkOutMaxPacketSize;
-	u16 BulkInMaxPacketSize;
-
-	/*======Control Flags */
-	long PendingIoCount;
-	unsigned long BulkFlags;
-	BOOLEAN bUsbTxBulkAggre;	/* Flags for bulk out data priority */
-
-	/*======Cmd Thread */
-	struct rt_cmdq CmdQ;
-	spinlock_t CmdQLock;	/* CmdQLock spinlock */
-	struct rt_rtmp_os_task cmdQTask;
-
-	/*======Semaphores (event) */
-	struct semaphore UsbVendorReq_semaphore;
-	void *UsbVendorReqBuf;
-	wait_queue_head_t *wait;
-#endif				/* RTMP_MAC_USB // */
-
-/*****************************************************************************************/
-/*      RBUS related parameters																  */
-/*****************************************************************************************/
-
-/*****************************************************************************************/
-/*      Both PCI/USB related parameters														  */
-/*****************************************************************************************/
-	/*struct rt_rtmp_dev_info                 chipInfo; */
-	RTMP_INF_TYPE infType;
-
-/*****************************************************************************************/
-/*      Driver Mgmt related parameters														  */
-/*****************************************************************************************/
-	struct rt_rtmp_os_task mlmeTask;
-#ifdef RTMP_TIMER_TASK_SUPPORT
-	/* If you want use timer task to handle the timer related jobs, enable this. */
-	struct rt_rtmp_timer_task_queue TimerQ;
-	spinlock_t TimerQLock;
-	struct rt_rtmp_os_task timerTask;
-#endif				/* RTMP_TIMER_TASK_SUPPORT // */
-
-/*****************************************************************************************/
-/*      Tx related parameters                                                           */
-/*****************************************************************************************/
-	BOOLEAN DeQueueRunning[NUM_OF_TX_RING];	/* for ensuring RTUSBDeQueuePacket get call once */
-	spinlock_t DeQueueLock[NUM_OF_TX_RING];
-
-#ifdef RTMP_MAC_USB
-	/* Data related context and AC specified, 4 AC supported */
-	spinlock_t BulkOutLock[6];	/* BulkOut spinlock for 4 ACs */
-	spinlock_t MLMEBulkOutLock;	/* MLME BulkOut lock */
-
-	struct rt_ht_tx_context TxContext[NUM_OF_TX_RING];
-	spinlock_t TxContextQueueLock[NUM_OF_TX_RING];	/* TxContextQueue spinlock */
-
-	/* 4 sets of Bulk Out index and pending flag */
-	u8 NextBulkOutIndex[4];	/* only used for 4 EDCA bulkout pipe */
-
-	BOOLEAN BulkOutPending[6];	/* used for total 6 bulkout pipe */
-	u8 bulkResetPipeid;
-	BOOLEAN MgmtBulkPending;
-	unsigned long bulkResetReq[6];
-#endif				/* RTMP_MAC_USB // */
-
-	/* resource for software backlog queues */
-	struct rt_queue_header TxSwQueue[NUM_OF_TX_RING];	/* 4 AC + 1 HCCA */
-	spinlock_t TxSwQueueLock[NUM_OF_TX_RING];	/* TxSwQueue spinlock */
-
-	struct rt_rtmp_dmabuf MgmtDescRing;	/* Shared memory for MGMT descriptors */
-	struct rt_rtmp_mgmt_ring MgmtRing;
-	spinlock_t MgmtRingLock;	/* Prio Ring spinlock */
-
-/*****************************************************************************************/
-/*      Rx related parameters                                                           */
-/*****************************************************************************************/
-
-#ifdef RTMP_MAC_PCI
-	struct rt_rtmp_rx_ring RxRing;
-	spinlock_t RxRingLock;	/* Rx Ring spinlock */
-#ifdef RT3090
-	spinlock_t McuCmdLock;	/*MCU Command Queue spinlock */
-#endif				/* RT3090 // */
-#endif				/* RTMP_MAC_PCI // */
-#ifdef RTMP_MAC_USB
-	struct rt_rx_context RxContext[RX_RING_SIZE];	/* 1 for redundant multiple IRP bulk in. */
-	spinlock_t BulkInLock;	/* BulkIn spinlock for 4 ACs */
-	u8 PendingRx;	/* The Maximum pending Rx value should be       RX_RING_SIZE. */
-	u8 NextRxBulkInIndex;	/* Indicate the current RxContext Index which hold by Host controller. */
-	u8 NextRxBulkInReadIndex;	/* Indicate the current RxContext Index which driver can read & process it. */
-	unsigned long NextRxBulkInPosition;	/* Want to contatenate 2 URB buffer while 1st is bulkin failed URB. This Position is 1st URB TransferLength. */
-	unsigned long TransferBufferLength;	/* current length of the packet buffer */
-	unsigned long ReadPosition;	/* current read position in a packet buffer */
-#endif				/* RTMP_MAC_USB // */
-
-/*****************************************************************************************/
-/*      ASIC related parameters                                                          */
-/*****************************************************************************************/
-	u32 MACVersion;	/* MAC version. Record rt2860C(0x28600100) or rt2860D (0x28600101).. */
-
-	/* --------------------------- */
-	/* E2PROM */
-	/* --------------------------- */
-	unsigned long EepromVersion;	/* byte 0: version, byte 1: revision, byte 2~3: unused */
-	unsigned long FirmwareVersion;	/* byte 0: Minor version, byte 1: Major version, otherwise unused. */
-	u16 EEPROMDefaultValue[NUM_EEPROM_BBP_PARMS];
-	u8 EEPROMAddressNum;	/* 93c46=6  93c66=8 */
-	BOOLEAN EepromAccess;
-	u8 EFuseTag;
-
-	/* --------------------------- */
-	/* BBP Control */
-	/* --------------------------- */
-	u8 BbpWriteLatch[140];	/* record last BBP register value written via BBP_IO_WRITE/BBP_IO_WRITE_VY_REG_ID */
-	char BbpRssiToDbmDelta;	/* change from u8 to char for high power */
-	struct rt_bbp_r66_tuning BbpTuning;
-
-	/* ---------------------------- */
-	/* RFIC control */
-	/* ---------------------------- */
-	u8 RfIcType;		/* RFIC_xxx */
-	unsigned long RfFreqOffset;	/* Frequency offset for channel switching */
-	struct rt_rtmp_rf_regs LatchRfRegs;	/* latch the latest RF programming value since RF IC doesn't support READ */
-
-	EEPROM_ANTENNA_STRUC Antenna;	/* Since Antenna definition is different for a & g. We need to save it for future reference. */
-	EEPROM_NIC_CONFIG2_STRUC NicConfig2;
-
-	/* This soft Rx Antenna Diversity mechanism is used only when user set */
-	/* RX Antenna = DIVERSITY ON */
-	struct rt_soft_rx_ant_diversity RxAnt;
-
-	u8 RFProgSeq;
-	struct rt_channel_tx_power TxPower[MAX_NUM_OF_CHANNELS];	/* Store Tx power value for all channels. */
-	struct rt_channel_tx_power ChannelList[MAX_NUM_OF_CHANNELS];	/* list all supported channels for site survey */
-	struct rt_channel_11j_tx_power TxPower11J[MAX_NUM_OF_11JCHANNELS];	/* 802.11j channel and bw */
-	struct rt_channel_11j_tx_power ChannelList11J[MAX_NUM_OF_11JCHANNELS];	/* list all supported channels for site survey */
-
-	u8 ChannelListNum;	/* number of channel in ChannelList[] */
-	u8 Bbp94;
-	BOOLEAN BbpForCCK;
-	unsigned long Tx20MPwrCfgABand[5];
-	unsigned long Tx20MPwrCfgGBand[5];
-	unsigned long Tx40MPwrCfgABand[5];
-	unsigned long Tx40MPwrCfgGBand[5];
-
-	BOOLEAN bAutoTxAgcA;	/* Enable driver auto Tx Agc control */
-	u8 TssiRefA;		/* Store Tssi reference value as 25 temperature. */
-	u8 TssiPlusBoundaryA[5];	/* Tssi boundary for increase Tx power to compensate. */
-	u8 TssiMinusBoundaryA[5];	/* Tssi boundary for decrease Tx power to compensate. */
-	u8 TxAgcStepA;	/* Store Tx TSSI delta increment / decrement value */
-	char TxAgcCompensateA;	/* Store the compensation (TxAgcStep * (idx-1)) */
-
-	BOOLEAN bAutoTxAgcG;	/* Enable driver auto Tx Agc control */
-	u8 TssiRefG;		/* Store Tssi reference value as 25 temperature. */
-	u8 TssiPlusBoundaryG[5];	/* Tssi boundary for increase Tx power to compensate. */
-	u8 TssiMinusBoundaryG[5];	/* Tssi boundary for decrease Tx power to compensate. */
-	u8 TxAgcStepG;	/* Store Tx TSSI delta increment / decrement value */
-	char TxAgcCompensateG;	/* Store the compensation (TxAgcStep * (idx-1)) */
-
-	char BGRssiOffset0;	/* Store B/G RSSI#0 Offset value on EEPROM 0x46h */
-	char BGRssiOffset1;	/* Store B/G RSSI#1 Offset value */
-	char BGRssiOffset2;	/* Store B/G RSSI#2 Offset value */
-
-	char ARssiOffset0;	/* Store A RSSI#0 Offset value on EEPROM 0x4Ah */
-	char ARssiOffset1;	/* Store A RSSI#1 Offset value */
-	char ARssiOffset2;	/* Store A RSSI#2 Offset value */
-
-	char BLNAGain;		/* Store B/G external LNA#0 value on EEPROM 0x44h */
-	char ALNAGain0;		/* Store A external LNA#0 value for ch36~64 */
-	char ALNAGain1;		/* Store A external LNA#1 value for ch100~128 */
-	char ALNAGain2;		/* Store A external LNA#2 value for ch132~165 */
-#ifdef RT30xx
-	/* for 3572 */
-	u8 Bbp25;
-	u8 Bbp26;
-
-	u8 TxMixerGain24G;	/* Tx mixer gain value from EEPROM to improve Tx EVM / Tx DAC, 2.4G */
-	u8 TxMixerGain5G;
-#endif				/* RT30xx // */
-	/* ---------------------------- */
-	/* LED control */
-	/* ---------------------------- */
-	MCU_LEDCS_STRUC LedCntl;
-	u16 Led1;		/* read from EEPROM 0x3c */
-	u16 Led2;		/* EEPROM 0x3e */
-	u16 Led3;		/* EEPROM 0x40 */
-	u8 LedIndicatorStrength;
-	u8 RssiSingalstrengthOffet;
-	BOOLEAN bLedOnScanning;
-	u8 LedStatus;
-
-/*****************************************************************************************/
-/*      802.11 related parameters                                                        */
-/*****************************************************************************************/
-	/* outgoing BEACON frame buffer and corresponding TXD */
-	struct rt_txwi BeaconTxWI;
-	u8 *BeaconBuf;
-	u16 BeaconOffset[HW_BEACON_MAX_COUNT];
-
-	/* pre-build PS-POLL and NULL frame upon link up. for efficiency purpose. */
-	struct rt_pspoll_frame PsPollFrame;
-	struct rt_header_802_11 NullFrame;
-
-#ifdef RTMP_MAC_USB
-	struct rt_tx_context BeaconContext[BEACON_RING_SIZE];
-	struct rt_tx_context NullContext;
-	struct rt_tx_context PsPollContext;
-	struct rt_tx_context RTSContext;
-#endif				/* RTMP_MAC_USB // */
-
-/*=========AP=========== */
-
-/*=======STA=========== */
-	/* ----------------------------------------------- */
-	/* STA specific configuration & operation status */
-	/* used only when pAd->OpMode == OPMODE_STA */
-	/* ----------------------------------------------- */
-	struct rt_sta_admin_config StaCfg;	/* user desired settings */
-	struct rt_sta_active_config StaActive;	/* valid only when ADHOC_ON(pAd) || INFRA_ON(pAd) */
-	char nickname[IW_ESSID_MAX_SIZE + 1];	/* nickname, only used in the iwconfig i/f */
-	int PreMediaState;
-
-/*=======Common=========== */
-	/* OP mode: either AP or STA */
-	u8 OpMode;		/* OPMODE_STA, OPMODE_AP */
-
-	int IndicateMediaState;	/* Base on Indication state, default is NdisMediaStateDisConnected */
-
-	/* MAT related parameters */
-
-	/* configuration: read from Registry & E2PROM */
-	BOOLEAN bLocalAdminMAC;	/* Use user changed MAC */
-	u8 PermanentAddress[MAC_ADDR_LEN];	/* Factory default MAC address */
-	u8 CurrentAddress[MAC_ADDR_LEN];	/* User changed MAC address */
-
-	/* ------------------------------------------------------ */
-	/* common configuration to both OPMODE_STA and OPMODE_AP */
-	/* ------------------------------------------------------ */
-	struct rt_common_config CommonCfg;
-	struct rt_mlme Mlme;
-
-	/* AP needs those variables for site survey feature. */
-	struct rt_mlme_aux MlmeAux;	/* temporary settings used during MLME state machine */
-	struct rt_bss_table ScanTab;	/* store the latest SCAN result */
-
-	/*About MacTab, the sta driver will use #0 and #1 for multicast and AP. */
-	struct rt_mac_table MacTab;	/* ASIC on-chip WCID entry table.  At TX, ASIC always use key according to this on-chip table. */
-	spinlock_t MacTabLock;
-
-	struct rt_ba_table BATable;
-
-	spinlock_t BATabLock;
-	struct rt_ralink_timer RECBATimer;
-
-	/* encryption/decryption KEY tables */
-	struct rt_cipher_key SharedKey[MAX_MBSSID_NUM][4];	/* STA always use SharedKey[BSS0][0..3] */
-
-	/* RX re-assembly buffer for fragmentation */
-	struct rt_fragment_frame FragFrame;	/* Frame storage for fragment frame */
-
-	/* various Counters */
-	struct rt_counter_802_3 Counters8023;	/* 802.3 counters */
-	struct rt_counter_802_11 WlanCounters;	/* 802.11 MIB counters */
-	struct rt_counter_ralink RalinkCounters;	/* Ralink proprietary counters */
-	struct rt_counter_drs DrsCounters;	/* counters for Dynamic TX Rate Switching */
-	struct rt_private PrivateInfo;	/* Private information & counters */
-
-	/* flags, see fRTMP_ADAPTER_xxx flags */
-	unsigned long Flags;		/* Represent current device status */
-	unsigned long PSFlags;		/* Power Save operation flag. */
-
-	/* current TX sequence # */
-	u16 Sequence;
-
-	/* Control disconnect / connect event generation */
-	/*+++Not used anymore */
-	unsigned long LinkDownTime;
-	/*--- */
-	unsigned long LastRxRate;
-	unsigned long LastTxRate;
-	/*+++Used only for Station */
-	BOOLEAN bConfigChanged;	/* Config Change flag for the same SSID setting */
-	/*--- */
-
-	unsigned long ExtraInfo;	/* Extra information for displaying status */
-	unsigned long SystemErrorBitmap;	/* b0: E2PROM version error */
-
-	/*+++Not used anymore */
-	unsigned long MacIcVersion;	/* MAC/BBP serial interface issue solved after ver.D */
-	/*--- */
-
-	/* --------------------------- */
-	/* System event log */
-	/* --------------------------- */
-	struct rt_802_11_event_table EventTab;
-
-	BOOLEAN HTCEnable;
-
-	/*****************************************************************************************/
-	/*      Statistic related parameters                                                     */
-	/*****************************************************************************************/
-#ifdef RTMP_MAC_USB
-	unsigned long BulkOutDataOneSecCount;
-	unsigned long BulkInDataOneSecCount;
-	unsigned long BulkLastOneSecCount;	/* BulkOutDataOneSecCount + BulkInDataOneSecCount */
-	unsigned long watchDogRxCnt;
-	unsigned long watchDogRxOverFlowCnt;
-	unsigned long watchDogTxPendingCnt[NUM_OF_TX_RING];
-	int TransferedLength[NUM_OF_TX_RING];
-#endif				/* RTMP_MAC_USB // */
-
-	BOOLEAN bUpdateBcnCntDone;
-	unsigned long watchDogMacDeadlock;	/* prevent MAC/BBP into deadlock condition */
-	/* ---------------------------- */
-	/* DEBUG paramerts */
-	/* ---------------------------- */
-	/*unsigned long         DebugSetting[4]; */
-	BOOLEAN bBanAllBaSetup;
-	BOOLEAN bPromiscuous;
-
-	/* ---------------------------- */
-	/* rt2860c emulation-use Parameters */
-	/* ---------------------------- */
-	/*unsigned long         rtsaccu[30]; */
-	/*unsigned long         ctsaccu[30]; */
-	/*unsigned long         cfendaccu[30]; */
-	/*unsigned long         bacontent[16]; */
-	/*unsigned long         rxint[RX_RING_SIZE+1]; */
-	/*u8         rcvba[60]; */
-	BOOLEAN bLinkAdapt;
-	BOOLEAN bForcePrintTX;
-	BOOLEAN bForcePrintRX;
-	/*BOOLEAN               bDisablescanning;               //defined in RT2870 USB */
-	BOOLEAN bStaFifoTest;
-	BOOLEAN bProtectionTest;
-	BOOLEAN bBroadComHT;
-	/*+++Following add from RT2870 USB. */
-	unsigned long BulkOutReq;
-	unsigned long BulkOutComplete;
-	unsigned long BulkOutCompleteOther;
-	unsigned long BulkOutCompleteCancel;	/* seems not used now? */
-	unsigned long BulkInReq;
-	unsigned long BulkInComplete;
-	unsigned long BulkInCompleteFail;
-	/*--- */
-
-	struct wificonf WIFItestbed;
-
-	struct reordering_mpdu_pool mpdu_blk_pool;
-
-	unsigned long OneSecondnonBEpackets;	/* record non BE packets per second */
-
-#ifdef LINUX
-	struct iw_statistics iw_stats;
-
-	struct net_device_stats stats;
-#endif				/* LINUX // */
-
-	unsigned long TbttTickCount;
-#ifdef PCI_MSI_SUPPORT
-	BOOLEAN HaveMsi;
-#endif				/* PCI_MSI_SUPPORT // */
-
-	u8 is_on;
-
-#define TIME_BASE			(1000000/OS_HZ)
-#define TIME_ONE_SECOND		(1000000/TIME_BASE)
-	u8 flg_be_adjust;
-	unsigned long be_adjust_last_time;
-
-	u8 FlgCtsEnabled;
-	u8 PM_FlgSuspend;
-
-#ifdef RT30xx
-#ifdef RTMP_EFUSE_SUPPORT
-	BOOLEAN bUseEfuse;
-	u8 EEPROMImage[1024];
-#endif				/* RTMP_EFUSE_SUPPORT // */
-#endif				/* RT30xx // */
-};
-
-#define DELAYINTMASK		0x0003fffb
-#define INTMASK				0x0003fffb
-#define IndMask				0x0003fffc
-#define RxINT				0x00000005	/* Delayed Rx or indivi rx */
-#define TxDataInt			0x000000fa	/* Delayed Tx or indivi tx */
-#define TxMgmtInt			0x00000102	/* Delayed Tx or indivi tx */
-#define TxCoherent			0x00020000	/* tx coherent */
-#define RxCoherent			0x00010000	/* rx coherent */
-#define McuCommand			0x00000200	/* mcu */
-#define PreTBTTInt			0x00001000	/* Pre-TBTT interrupt */
-#define TBTTInt				0x00000800	/* TBTT interrupt */
-#define GPTimeOutInt			0x00008000	/* GPtimeout interrupt */
-#define AutoWakeupInt		0x00004000	/* AutoWakeupInt interrupt */
-#define FifoStaFullInt			0x00002000	/*  fifo statistics full interrupt */
-
-/***************************************************************************
-  *	Rx Path software control block related data structures
-  **************************************************************************/
-struct rt_rx_blk {
-	RT28XX_RXD_STRUC RxD;
-	struct rt_rxwi *pRxWI;
-	struct rt_header_802_11 *pHeader;
-	void *pRxPacket;
-	u8 *pData;
-	u16 DataSize;
-	u16 Flags;
-	u8 UserPriority;	/* for calculate TKIP MIC using */
-};
-
-#define RX_BLK_SET_FLAG(_pRxBlk, _flag)		(_pRxBlk->Flags |= _flag)
-#define RX_BLK_TEST_FLAG(_pRxBlk, _flag)	(_pRxBlk->Flags & _flag)
-#define RX_BLK_CLEAR_FLAG(_pRxBlk, _flag)	(_pRxBlk->Flags &= ~(_flag))
-
-#define fRX_WDS			0x0001
-#define fRX_AMSDU       0x0002
-#define fRX_ARALINK     0x0004
-#define fRX_HTC         0x0008
-#define fRX_PAD         0x0010
-#define fRX_AMPDU       0x0020
-#define fRX_QOS			0x0040
-#define fRX_INFRA		0x0080
-#define fRX_EAP			0x0100
-#define fRX_MESH		0x0200
-#define fRX_APCLI		0x0400
-#define fRX_DLS			0x0800
-#define fRX_WPI			0x1000
-
-#define LENGTH_AMSDU_SUBFRAMEHEAD	14
-#define LENGTH_ARALINK_SUBFRAMEHEAD	14
-#define LENGTH_ARALINK_HEADER_FIELD	 2
-
-/***************************************************************************
-  *	Tx Path software control block related data structures
-  **************************************************************************/
-#define TX_UNKOWN_FRAME			0x00
-#define TX_MCAST_FRAME			0x01
-#define TX_LEGACY_FRAME			0x02
-#define TX_AMPDU_FRAME			0x04
-#define TX_AMSDU_FRAME			0x08
-#define TX_RALINK_FRAME			0x10
-#define TX_FRAG_FRAME			0x20
-
-/*      Currently the sizeof(struct rt_tx_blk) is 148 bytes. */
-struct rt_tx_blk {
-	u8 QueIdx;
-	u8 TxFrameType;	/* Indicate the Transmission type of the all frames in one batch */
-	u8 TotalFrameNum;	/* Total frame number that wants to send-out in one batch */
-	u16 TotalFragNum;	/* Total frame fragments required in one batch */
-	u16 TotalFrameLen;	/* Total length of all frames that wants to send-out in one batch */
-
-	struct rt_queue_header TxPacketList;
-	struct rt_mac_table_entry *pMacEntry;	/* NULL: packet with 802.11 RA field is multicast/broadcast address */
-	HTTRANSMIT_SETTING *pTransmit;
-
-	/* Following structure used for the characteristics of a specific packet. */
-	void *pPacket;
-	u8 *pSrcBufHeader;	/* Reference to the head of sk_buff->data */
-	u8 *pSrcBufData;	/* Reference to the sk_buff->data, will change depending on the handling progresss */
-	u32 SrcBufLen;		/* Length of packet payload which not including Layer 2 header */
-	u8 *pExtraLlcSnapEncap;	/* NULL means no extra LLC/SNAP is required */
-	u8 HeaderBuf[128];	/* TempBuffer for TX_INFO + TX_WI + 802.11 Header + padding + AMSDU SubHeader + LLC/SNAP */
-	/*RT2870 2.1.0.0 uses only 80 bytes */
-	/*RT3070 2.1.1.0 uses only 96 bytes */
-	/*RT3090 2.1.0.0 uses only 96 bytes */
-	u8 MpduHeaderLen;	/* 802.11 header length NOT including the padding */
-	u8 HdrPadLen;	/* recording Header Padding Length; */
-	u8 apidx;		/* The interface associated to this packet */
-	u8 Wcid;		/* The MAC entry associated to this packet */
-	u8 UserPriority;	/* priority class of packet */
-	u8 FrameGap;		/* what kind of IFS does this packet use */
-	u8 MpduReqNum;	/* number of fragments of this frame */
-	u8 TxRate;		/* TODO: Obsoleted? Should change to MCS? */
-	u8 CipherAlg;	/* cipher alogrithm */
-	struct rt_cipher_key *pKey;
-
-	u16 Flags;		/*See following definitions for detail. */
-
-	/*YOU SHOULD NOT TOUCH IT! Following parameters are used for hardware-depended layer. */
-	unsigned long Priv;		/* Hardware specific value saved in here. */
-};
-
-#define fTX_bRtsRequired	0x0001	/* Indicate if need send RTS frame for protection. Not used in RT2860/RT2870. */
-#define fTX_bAckRequired	0x0002	/* the packet need ack response */
-#define fTX_bPiggyBack		0x0004	/* Legacy device use Piggback or not */
-#define fTX_bHTRate		0x0008	/* allow to use HT rate */
-#define fTX_bForceNonQoS	0x0010	/* force to transmit frame without WMM-QoS in HT mode */
-#define fTX_bAllowFrag		0x0020	/* allow to fragment the packet, A-MPDU, A-MSDU, A-Ralink is not allowed to fragment */
-#define fTX_bMoreData		0x0040	/* there are more data packets in PowerSave Queue */
-#define fTX_bWMM		0x0080	/* QOS Data */
-#define fTX_bClearEAPFrame	0x0100
-
-#define TX_BLK_SET_FLAG(_pTxBlk, _flag)		(_pTxBlk->Flags |= _flag)
-#define TX_BLK_TEST_FLAG(_pTxBlk, _flag)	(((_pTxBlk->Flags & _flag) == _flag) ? 1 : 0)
-#define TX_BLK_CLEAR_FLAG(_pTxBlk, _flag)	(_pTxBlk->Flags &= ~(_flag))
-
-/***************************************************************************
-  *	Other static inline function definitions
-  **************************************************************************/
-static inline void ConvertMulticastIP2MAC(u8 *pIpAddr,
-					  u8 **ppMacAddr,
-					  u16 ProtoType)
-{
-	if (pIpAddr == NULL)
-		return;
-
-	if (ppMacAddr == NULL || *ppMacAddr == NULL)
-		return;
-
-	switch (ProtoType) {
-	case ETH_P_IPV6:
-/*                      memset(*ppMacAddr, 0, ETH_LENGTH_OF_ADDRESS); */
-		*(*ppMacAddr) = 0x33;
-		*(*ppMacAddr + 1) = 0x33;
-		*(*ppMacAddr + 2) = pIpAddr[12];
-		*(*ppMacAddr + 3) = pIpAddr[13];
-		*(*ppMacAddr + 4) = pIpAddr[14];
-		*(*ppMacAddr + 5) = pIpAddr[15];
-		break;
-
-	case ETH_P_IP:
-	default:
-/*                      memset(*ppMacAddr, 0, ETH_LENGTH_OF_ADDRESS); */
-		*(*ppMacAddr) = 0x01;
-		*(*ppMacAddr + 1) = 0x00;
-		*(*ppMacAddr + 2) = 0x5e;
-		*(*ppMacAddr + 3) = pIpAddr[1] & 0x7f;
-		*(*ppMacAddr + 4) = pIpAddr[2];
-		*(*ppMacAddr + 5) = pIpAddr[3];
-		break;
-	}
-
-	return;
-}
-
-char *GetPhyMode(int Mode);
-char *GetBW(int BW);
-
-/* */
-/*  Private routines in rtmp_init.c */
-/* */
-int RTMPAllocAdapterBlock(void *handle,
-				  struct rt_rtmp_adapter **ppAdapter);
-
-int RTMPAllocTxRxRingMemory(struct rt_rtmp_adapter *pAd);
-
-void RTMPFreeAdapter(struct rt_rtmp_adapter *pAd);
-
-int NICReadRegParameters(struct rt_rtmp_adapter *pAd,
-				 void *WrapperConfigurationContext);
-
-#ifdef RTMP_RF_RW_SUPPORT
-void NICInitRFRegisters(struct rt_rtmp_adapter *pAd);
-
-void RtmpChipOpsRFHook(struct rt_rtmp_adapter *pAd);
-
-int RT30xxWriteRFRegister(struct rt_rtmp_adapter *pAd,
-				  u8 regID, u8 value);
-
-int RT30xxReadRFRegister(struct rt_rtmp_adapter *pAd,
-				 u8 regID, u8 *pValue);
-#endif /* RTMP_RF_RW_SUPPORT // */
-
-void NICReadEEPROMParameters(struct rt_rtmp_adapter *pAd, u8 *mac_addr);
-
-void NICInitAsicFromEEPROM(struct rt_rtmp_adapter *pAd);
-
-int NICInitializeAdapter(struct rt_rtmp_adapter *pAd, IN BOOLEAN bHardReset);
-
-int NICInitializeAsic(struct rt_rtmp_adapter *pAd, IN BOOLEAN bHardReset);
-
-void NICIssueReset(struct rt_rtmp_adapter *pAd);
-
-void RTMPRingCleanUp(struct rt_rtmp_adapter *pAd, u8 RingType);
-
-void UserCfgInit(struct rt_rtmp_adapter *pAd);
-
-void NICResetFromError(struct rt_rtmp_adapter *pAd);
-
-int NICLoadFirmware(struct rt_rtmp_adapter *pAd);
-
-void NICEraseFirmware(struct rt_rtmp_adapter *pAd);
-
-int NICLoadRateSwitchingParams(struct rt_rtmp_adapter *pAd);
-
-BOOLEAN NICCheckForHang(struct rt_rtmp_adapter *pAd);
-
-void NICUpdateFifoStaCounters(struct rt_rtmp_adapter *pAd);
-
-void NICUpdateRawCounters(struct rt_rtmp_adapter *pAd);
-
-void RTMPZeroMemory(void *pSrc, unsigned long Length);
-
-unsigned long RTMPCompareMemory(void *pSrc1, void *pSrc2, unsigned long Length);
-
-void RTMPMoveMemory(void *pDest, void *pSrc, unsigned long Length);
-
-void AtoH(char *src, u8 *dest, int destlen);
-
-void RTMPPatchMacBbpBug(struct rt_rtmp_adapter *pAd);
-
-void RTMPInitTimer(struct rt_rtmp_adapter *pAd,
-		   struct rt_ralink_timer *pTimer,
-		   void *pTimerFunc, void *pData, IN BOOLEAN Repeat);
-
-void RTMPSetTimer(struct rt_ralink_timer *pTimer, unsigned long Value);
-
-void RTMPModTimer(struct rt_ralink_timer *pTimer, unsigned long Value);
-
-void RTMPCancelTimer(struct rt_ralink_timer *pTimer, OUT BOOLEAN * pCancelled);
-
-void RTMPSetLED(struct rt_rtmp_adapter *pAd, u8 Status);
-
-void RTMPSetSignalLED(struct rt_rtmp_adapter *pAd, IN NDIS_802_11_RSSI Dbm);
-
-void RTMPEnableRxTx(struct rt_rtmp_adapter *pAd);
-
-/* */
-/* prototype in action.c */
-/* */
-void ActionStateMachineInit(struct rt_rtmp_adapter *pAd,
-			    struct rt_state_machine *S,
-			    OUT STATE_MACHINE_FUNC Trans[]);
-
-void MlmeADDBAAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem);
-
-void MlmeDELBAAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem);
-
-void MlmeDLSAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem);
-
-void MlmeInvalidAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem);
-
-void MlmeQOSAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem);
-
-void PeerAddBAReqAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem);
-
-void PeerAddBARspAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem);
-
-void PeerDelBAAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem);
-
-void PeerBAAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem);
-
-void SendPSMPAction(struct rt_rtmp_adapter *pAd, u8 Wcid, u8 Psmp);
-
-void PeerRMAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem);
-
-void PeerPublicAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem);
-
-void PeerHTAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem);
-
-void PeerQOSAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem);
-
-void RECBATimerTimeout(void *SystemSpecific1,
-		       void *FunctionContext,
-		       void *SystemSpecific2, void *SystemSpecific3);
-
-void ORIBATimerTimeout(struct rt_rtmp_adapter *pAd);
-
-void SendRefreshBAR(struct rt_rtmp_adapter *pAd, struct rt_mac_table_entry *pEntry);
-
-void ActHeaderInit(struct rt_rtmp_adapter *pAd,
-		   struct rt_header_802_11 *pHdr80211,
-		   u8 *Addr1, u8 *Addr2, u8 *Addr3);
-
-void BarHeaderInit(struct rt_rtmp_adapter *pAd,
-		   struct rt_frame_bar *pCntlBar, u8 *pDA, u8 *pSA);
-
-void InsertActField(struct rt_rtmp_adapter *pAd,
-		    u8 *pFrameBuf,
-		    unsigned long *pFrameLen, u8 Category, u8 ActCode);
-
-BOOLEAN CntlEnqueueForRecv(struct rt_rtmp_adapter *pAd,
-			   unsigned long Wcid,
-			   unsigned long MsgLen, struct rt_frame_ba_req *pMsg);
-
-/* */
-/* Private routines in rtmp_data.c */
-/* */
-BOOLEAN RTMPHandleRxDoneInterrupt(struct rt_rtmp_adapter *pAd);
-
-BOOLEAN RTMPHandleTxRingDmaDoneInterrupt(struct rt_rtmp_adapter *pAd,
-					 INT_SOURCE_CSR_STRUC TxRingBitmap);
-
-void RTMPHandleMgmtRingDmaDoneInterrupt(struct rt_rtmp_adapter *pAd);
-
-void RTMPHandleTBTTInterrupt(struct rt_rtmp_adapter *pAd);
-
-void RTMPHandlePreTBTTInterrupt(struct rt_rtmp_adapter *pAd);
-
-void RTMPHandleTwakeupInterrupt(struct rt_rtmp_adapter *pAd);
-
-void RTMPHandleRxCoherentInterrupt(struct rt_rtmp_adapter *pAd);
-
-BOOLEAN TxFrameIsAggregatible(struct rt_rtmp_adapter *pAd,
-			      u8 *pPrevAddr1, u8 *p8023hdr);
-
-BOOLEAN PeerIsAggreOn(struct rt_rtmp_adapter *pAd,
-		      unsigned long TxRate, struct rt_mac_table_entry *pMacEntry);
-
-int Sniff2BytesFromNdisBuffer(char *pFirstBuffer,
-				      u8 DesiredOffset,
-				      u8 *pByte0, u8 *pByte1);
-
-int STASendPacket(struct rt_rtmp_adapter *pAd, void *pPacket);
-
-void STASendPackets(void *MiniportAdapterContext,
-		    void **ppPacketArray, u32 NumberOfPackets);
-
-void RTMPDeQueuePacket(struct rt_rtmp_adapter *pAd,
-		       IN BOOLEAN bIntContext,
-		       u8 QueIdx, u8 Max_Tx_Packets);
-
-int RTMPHardTransmit(struct rt_rtmp_adapter *pAd,
-			     void *pPacket,
-			     u8 QueIdx, unsigned long *pFreeTXDLeft);
-
-int STAHardTransmit(struct rt_rtmp_adapter *pAd,
-			    struct rt_tx_blk *pTxBlk, u8 QueIdx);
-
-void STARxEAPOLFrameIndicate(struct rt_rtmp_adapter *pAd,
-			     struct rt_mac_table_entry *pEntry,
-			     struct rt_rx_blk *pRxBlk, u8 FromWhichBSSID);
-
-int RTMPFreeTXDRequest(struct rt_rtmp_adapter *pAd,
-			       u8 RingType,
-			       u8 NumberRequired, u8 *FreeNumberIs);
-
-int MlmeHardTransmit(struct rt_rtmp_adapter *pAd,
-			     u8 QueIdx, void *pPacket);
-
-int MlmeHardTransmitMgmtRing(struct rt_rtmp_adapter *pAd,
-				     u8 QueIdx, void *pPacket);
-
-#ifdef RTMP_MAC_PCI
-int MlmeHardTransmitTxRing(struct rt_rtmp_adapter *pAd,
-				   u8 QueIdx, void *pPacket);
-
-int MlmeDataHardTransmit(struct rt_rtmp_adapter *pAd,
-				 u8 QueIdx, void *pPacket);
-
-void RTMPWriteTxDescriptor(struct rt_rtmp_adapter *pAd,
-			   struct rt_txd *pTxD, IN BOOLEAN bWIV, u8 QSEL);
-#endif /* RTMP_MAC_PCI // */
-
-u16 RTMPCalcDuration(struct rt_rtmp_adapter *pAd, u8 Rate, unsigned long Size);
-
-void RTMPWriteTxWI(struct rt_rtmp_adapter *pAd, struct rt_txwi * pTxWI, IN BOOLEAN FRAG, IN BOOLEAN CFACK, IN BOOLEAN InsTimestamp, IN BOOLEAN AMPDU, IN BOOLEAN Ack, IN BOOLEAN NSeq,	/* HW new a sequence. */
-		   u8 BASize,
-		   u8 WCID,
-		   unsigned long Length,
-		   u8 PID,
-		   u8 TID,
-		   u8 TxRate,
-		   u8 Txopmode,
-		   IN BOOLEAN CfAck, IN HTTRANSMIT_SETTING *pTransmit);
-
-void RTMPWriteTxWI_Data(struct rt_rtmp_adapter *pAd,
-			struct rt_txwi *pTxWI, struct rt_tx_blk *pTxBlk);
-
-void RTMPWriteTxWI_Cache(struct rt_rtmp_adapter *pAd,
-			 struct rt_txwi *pTxWI, struct rt_tx_blk *pTxBlk);
-
-void RTMPSuspendMsduTransmission(struct rt_rtmp_adapter *pAd);
-
-void RTMPResumeMsduTransmission(struct rt_rtmp_adapter *pAd);
-
-int MiniportMMRequest(struct rt_rtmp_adapter *pAd,
-			      u8 QueIdx, u8 *pData, u32 Length);
-
-/*+++mark by shiang, now this function merge to MiniportMMRequest() */
-/*---mark by shiang, now this function merge to MiniportMMRequest() */
-
-void RTMPSendNullFrame(struct rt_rtmp_adapter *pAd,
-		       u8 TxRate, IN BOOLEAN bQosNull);
-
-void RTMPSendDisassociationFrame(struct rt_rtmp_adapter *pAd);
-
-void RTMPSendRTSFrame(struct rt_rtmp_adapter *pAd,
-		      u8 *pDA,
-		      IN unsigned int NextMpduSize,
-		      u8 TxRate,
-		      u8 RTSRate,
-		      u16 AckDuration,
-		      u8 QueIdx, u8 FrameGap);
-
-struct rt_queue_header *RTMPCheckTxSwQueue(struct rt_rtmp_adapter *pAd, u8 * QueIdx);
-
-void RTMPReportMicError(struct rt_rtmp_adapter *pAd, struct rt_cipher_key *pWpaKey);
-
-void WpaMicFailureReportFrame(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem);
-
-void WpaDisassocApAndBlockAssoc(void *SystemSpecific1,
-				void *FunctionContext,
-				void *SystemSpecific2,
-				void *SystemSpecific3);
-
-void WpaStaPairwiseKeySetting(struct rt_rtmp_adapter *pAd);
-
-void WpaStaGroupKeySetting(struct rt_rtmp_adapter *pAd);
-
-int RTMPCloneNdisPacket(struct rt_rtmp_adapter *pAd,
-				IN BOOLEAN pInsAMSDUHdr,
-				void *pInPacket,
-				void **ppOutPacket);
-
-int RTMPAllocateNdisPacket(struct rt_rtmp_adapter *pAd,
-				   void **pPacket,
-				   u8 *pHeader,
-				   u32 HeaderLen,
-				   u8 *pData, u32 DataLen);
-
-void RTMPFreeNdisPacket(struct rt_rtmp_adapter *pAd, void *pPacket);
-
-BOOLEAN RTMPFreeTXDUponTxDmaDone(struct rt_rtmp_adapter *pAd, u8 QueIdx);
-
-BOOLEAN RTMPCheckDHCPFrame(struct rt_rtmp_adapter *pAd, void *pPacket);
-
-BOOLEAN RTMPCheckEtherType(struct rt_rtmp_adapter *pAd, void *pPacket);
-
-/* */
-/* Private routines in rtmp_wep.c */
-/* */
-void RTMPInitWepEngine(struct rt_rtmp_adapter *pAd,
-		       u8 *pKey,
-		       u8 KeyId, u8 KeyLen, u8 *pDest);
-
-void RTMPEncryptData(struct rt_rtmp_adapter *pAd,
-		     u8 *pSrc, u8 *pDest, u32 Len);
-
-BOOLEAN RTMPSoftDecryptWEP(struct rt_rtmp_adapter *pAd,
-			   u8 *pData,
-			   unsigned long DataByteCnt, struct rt_cipher_key *pGroupKey);
-
-void RTMPSetICV(struct rt_rtmp_adapter *pAd, u8 *pDest);
-
-void ARCFOUR_INIT(struct rt_arcfourcontext *Ctx, u8 *pKey, u32 KeyLen);
-
-u8 ARCFOUR_BYTE(struct rt_arcfourcontext *Ctx);
-
-void ARCFOUR_DECRYPT(struct rt_arcfourcontext *Ctx,
-		     u8 *pDest, u8 *pSrc, u32 Len);
-
-void ARCFOUR_ENCRYPT(struct rt_arcfourcontext *Ctx,
-		     u8 *pDest, u8 *pSrc, u32 Len);
-
-void WPAARCFOUR_ENCRYPT(struct rt_arcfourcontext *Ctx,
-			u8 *pDest, u8 *pSrc, u32 Len);
-
-u32 RTMP_CALC_FCS32(u32 Fcs, u8 *Cp, int Len);
-
-/* */
-/* MLME routines */
-/* */
-
-/* Asic/RF/BBP related functions */
-
-void AsicAdjustTxPower(struct rt_rtmp_adapter *pAd);
-
-void AsicUpdateProtect(struct rt_rtmp_adapter *pAd,
-		       u16 OperaionMode,
-		       u8 SetMask,
-		       IN BOOLEAN bDisableBGProtect, IN BOOLEAN bNonGFExist);
-
-void AsicSwitchChannel(struct rt_rtmp_adapter *pAd,
-		       u8 Channel, IN BOOLEAN bScan);
-
-void AsicLockChannel(struct rt_rtmp_adapter *pAd, u8 Channel);
-
-void AsicRfTuningExec(void *SystemSpecific1,
-		      void *FunctionContext,
-		      void *SystemSpecific2, void *SystemSpecific3);
-
-void AsicResetBBPAgent(struct rt_rtmp_adapter *pAd);
-
-void AsicSleepThenAutoWakeup(struct rt_rtmp_adapter *pAd,
-			     u16 TbttNumToNextWakeUp);
-
-void AsicForceSleep(struct rt_rtmp_adapter *pAd);
-
-void AsicForceWakeup(struct rt_rtmp_adapter *pAd, IN BOOLEAN bFromTx);
-
-void AsicSetBssid(struct rt_rtmp_adapter *pAd, u8 *pBssid);
-
-void AsicSetMcastWC(struct rt_rtmp_adapter *pAd);
-
-void AsicDelWcidTab(struct rt_rtmp_adapter *pAd, u8 Wcid);
-
-void AsicEnableRDG(struct rt_rtmp_adapter *pAd);
-
-void AsicDisableRDG(struct rt_rtmp_adapter *pAd);
-
-void AsicDisableSync(struct rt_rtmp_adapter *pAd);
-
-void AsicEnableBssSync(struct rt_rtmp_adapter *pAd);
-
-void AsicEnableIbssSync(struct rt_rtmp_adapter *pAd);
-
-void AsicSetEdcaParm(struct rt_rtmp_adapter *pAd, struct rt_edca_parm *pEdcaParm);
-
-void AsicSetSlotTime(struct rt_rtmp_adapter *pAd, IN BOOLEAN bUseShortSlotTime);
-
-void AsicAddSharedKeyEntry(struct rt_rtmp_adapter *pAd,
-			   u8 BssIndex,
-			   u8 KeyIdx,
-			   u8 CipherAlg,
-			   u8 *pKey, u8 *pTxMic, u8 *pRxMic);
-
-void AsicRemoveSharedKeyEntry(struct rt_rtmp_adapter *pAd,
-			      u8 BssIndex, u8 KeyIdx);
-
-void AsicUpdateWCIDAttribute(struct rt_rtmp_adapter *pAd,
-			     u16 WCID,
-			     u8 BssIndex,
-			     u8 CipherAlg,
-			     IN BOOLEAN bUsePairewiseKeyTable);
-
-void AsicUpdateWCIDIVEIV(struct rt_rtmp_adapter *pAd,
-			 u16 WCID, unsigned long uIV, unsigned long uEIV);
-
-void AsicUpdateRxWCIDTable(struct rt_rtmp_adapter *pAd,
-			   u16 WCID, u8 *pAddr);
-
-void AsicAddKeyEntry(struct rt_rtmp_adapter *pAd,
-		     u16 WCID,
-		     u8 BssIndex,
-		     u8 KeyIdx,
-		     struct rt_cipher_key *pCipherKey,
-		     IN BOOLEAN bUsePairewiseKeyTable, IN BOOLEAN bTxKey);
-
-void AsicAddPairwiseKeyEntry(struct rt_rtmp_adapter *pAd,
-			     u8 *pAddr,
-			     u8 WCID, struct rt_cipher_key *pCipherKey);
-
-void AsicRemovePairwiseKeyEntry(struct rt_rtmp_adapter *pAd,
-				u8 BssIdx, u8 Wcid);
-
-BOOLEAN AsicSendCommandToMcu(struct rt_rtmp_adapter *pAd,
-			     u8 Command,
-			     u8 Token, u8 Arg0, u8 Arg1);
-
-#ifdef RTMP_MAC_PCI
-BOOLEAN AsicCheckCommanOk(struct rt_rtmp_adapter *pAd, u8 Command);
-#endif /* RTMP_MAC_PCI // */
-
-void MacAddrRandomBssid(struct rt_rtmp_adapter *pAd, u8 *pAddr);
-
-void MgtMacHeaderInit(struct rt_rtmp_adapter *pAd,
-		      struct rt_header_802_11 *pHdr80211,
-		      u8 SubType,
-		      u8 ToDs, u8 *pDA, u8 *pBssid);
-
-void MlmeRadioOff(struct rt_rtmp_adapter *pAd);
-
-void MlmeRadioOn(struct rt_rtmp_adapter *pAd);
-
-void BssTableInit(struct rt_bss_table *Tab);
-
-void BATableInit(struct rt_rtmp_adapter *pAd, struct rt_ba_table *Tab);
-
-unsigned long BssTableSearch(struct rt_bss_table *Tab, u8 *pBssid, u8 Channel);
-
-unsigned long BssSsidTableSearch(struct rt_bss_table *Tab,
-			 u8 *pBssid,
-			 u8 *pSsid, u8 SsidLen, u8 Channel);
-
-unsigned long BssTableSearchWithSSID(struct rt_bss_table *Tab,
-			     u8 *Bssid,
-			     u8 *pSsid,
-			     u8 SsidLen, u8 Channel);
-
-unsigned long BssSsidTableSearchBySSID(struct rt_bss_table *Tab,
-			       u8 *pSsid, u8 SsidLen);
-
-void BssTableDeleteEntry(struct rt_bss_table *pTab,
-			 u8 *pBssid, u8 Channel);
-
-void BATableDeleteORIEntry(struct rt_rtmp_adapter *pAd,
-			   struct rt_ba_ori_entry *pBAORIEntry);
-
-void BssEntrySet(struct rt_rtmp_adapter *pAd, struct rt_bss_entry *pBss, u8 *pBssid, char Ssid[], u8 SsidLen, u8 BssType, u16 BeaconPeriod, struct rt_cf_parm * CfParm, u16 AtimWin, u16 CapabilityInfo, u8 SupRate[], u8 SupRateLen, u8 ExtRate[], u8 ExtRateLen, struct rt_ht_capability_ie * pHtCapability, struct rt_add_ht_info_ie * pAddHtInfo,	/* AP might use this additional ht info IE */
-		 u8 HtCapabilityLen,
-		 u8 AddHtInfoLen,
-		 u8 NewExtChanOffset,
-		 u8 Channel,
-		 char Rssi,
-		 IN LARGE_INTEGER TimeStamp,
-		 u8 CkipFlag,
-		 struct rt_edca_parm *pEdcaParm,
-		 struct rt_qos_capability_parm *pQosCapability,
-		 struct rt_qbss_load_parm *pQbssLoad,
-		 u16 LengthVIE, struct rt_ndis_802_11_variable_ies *pVIE);
-
-unsigned long BssTableSetEntry(struct rt_rtmp_adapter *pAd, struct rt_bss_table *pTab, u8 *pBssid, char Ssid[], u8 SsidLen, u8 BssType, u16 BeaconPeriod, struct rt_cf_parm * CfParm, u16 AtimWin, u16 CapabilityInfo, u8 SupRate[], u8 SupRateLen, u8 ExtRate[], u8 ExtRateLen, struct rt_ht_capability_ie * pHtCapability, struct rt_add_ht_info_ie * pAddHtInfo,	/* AP might use this additional ht info IE */
-		       u8 HtCapabilityLen,
-		       u8 AddHtInfoLen,
-		       u8 NewExtChanOffset,
-		       u8 Channel,
-		       char Rssi,
-		       IN LARGE_INTEGER TimeStamp,
-		       u8 CkipFlag,
-		       struct rt_edca_parm *pEdcaParm,
-		       struct rt_qos_capability_parm *pQosCapability,
-		       struct rt_qbss_load_parm *pQbssLoad,
-		       u16 LengthVIE, struct rt_ndis_802_11_variable_ies *pVIE);
-
-void BATableInsertEntry(struct rt_rtmp_adapter *pAd,
-			u16 Aid,
-			u16 TimeOutValue,
-			u16 StartingSeq,
-			u8 TID,
-			u8 BAWinSize,
-			u8 OriginatorStatus, IN BOOLEAN IsRecipient);
-
-void BssTableSsidSort(struct rt_rtmp_adapter *pAd,
-		      struct rt_bss_table *OutTab, char Ssid[], u8 SsidLen);
-
-void BssTableSortByRssi(struct rt_bss_table *OutTab);
-
-void BssCipherParse(struct rt_bss_entry *pBss);
-
-int MlmeQueueInit(struct rt_mlme_queue *Queue);
-
-void MlmeQueueDestroy(struct rt_mlme_queue *Queue);
-
-BOOLEAN MlmeEnqueue(struct rt_rtmp_adapter *pAd,
-		    unsigned long Machine,
-		    unsigned long MsgType, unsigned long MsgLen, void *Msg);
-
-BOOLEAN MlmeEnqueueForRecv(struct rt_rtmp_adapter *pAd,
-			   unsigned long Wcid,
-			   unsigned long TimeStampHigh,
-			   unsigned long TimeStampLow,
-			   u8 Rssi0,
-			   u8 Rssi1,
-			   u8 Rssi2,
-			   unsigned long MsgLen, void *Msg, u8 Signal);
-
-BOOLEAN MlmeDequeue(struct rt_mlme_queue *Queue, struct rt_mlme_queue_elem **Elem);
-
-void MlmeRestartStateMachine(struct rt_rtmp_adapter *pAd);
-
-BOOLEAN MlmeQueueEmpty(struct rt_mlme_queue *Queue);
-
-BOOLEAN MlmeQueueFull(struct rt_mlme_queue *Queue);
-
-BOOLEAN MsgTypeSubst(struct rt_rtmp_adapter *pAd,
-		     struct rt_frame_802_11 *pFrame,
-		     int *Machine, int *MsgType);
-
-void StateMachineInit(struct rt_state_machine *Sm,
-		      IN STATE_MACHINE_FUNC Trans[],
-		      unsigned long StNr,
-		      unsigned long MsgNr,
-		      IN STATE_MACHINE_FUNC DefFunc,
-		      unsigned long InitState, unsigned long Base);
-
-void StateMachineSetAction(struct rt_state_machine *S,
-			   unsigned long St, unsigned long Msg, IN STATE_MACHINE_FUNC F);
-
-void StateMachinePerformAction(struct rt_rtmp_adapter *pAd,
-			       struct rt_state_machine *S, struct rt_mlme_queue_elem *Elem);
-
-void Drop(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem);
-
-void AssocStateMachineInit(struct rt_rtmp_adapter *pAd,
-			   struct rt_state_machine *Sm,
-			   OUT STATE_MACHINE_FUNC Trans[]);
-
-void ReassocTimeout(void *SystemSpecific1,
-		    void *FunctionContext,
-		    void *SystemSpecific2, void *SystemSpecific3);
-
-void AssocTimeout(void *SystemSpecific1,
-		  void *FunctionContext,
-		  void *SystemSpecific2, void *SystemSpecific3);
-
-void DisassocTimeout(void *SystemSpecific1,
-		     void *FunctionContext,
-		     void *SystemSpecific2, void *SystemSpecific3);
-
-/*---------------------------------------------- */
-void MlmeAssocReqAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem);
-
-void MlmeReassocReqAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem);
-
-void MlmeDisassocReqAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem);
-
-void PeerAssocRspAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem);
-
-void PeerReassocRspAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem);
-
-void PeerDisassocAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem);
-
-void DisassocTimeoutAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem);
-
-void AssocTimeoutAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem);
-
-void ReassocTimeoutAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem);
-
-void Cls3errAction(struct rt_rtmp_adapter *pAd, u8 *pAddr);
-
-void InvalidStateWhenAssoc(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem);
-
-void InvalidStateWhenReassoc(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem);
-
-void InvalidStateWhenDisassociate(struct rt_rtmp_adapter *pAd,
-				  struct rt_mlme_queue_elem *Elem);
-
-#ifdef RTMP_MAC_USB
-void MlmeCntlConfirm(struct rt_rtmp_adapter *pAd, unsigned long MsgType, u16 Msg);
-#endif /* RTMP_MAC_USB // */
-
-void ComposePsPoll(struct rt_rtmp_adapter *pAd);
-
-void ComposeNullFrame(struct rt_rtmp_adapter *pAd);
-
-void AssocPostProc(struct rt_rtmp_adapter *pAd,
-		   u8 *pAddr2,
-		   u16 CapabilityInfo,
-		   u16 Aid,
-		   u8 SupRate[],
-		   u8 SupRateLen,
-		   u8 ExtRate[],
-		   u8 ExtRateLen,
-		   struct rt_edca_parm *pEdcaParm,
-		   struct rt_ht_capability_ie *pHtCapability,
-		   u8 HtCapabilityLen, struct rt_add_ht_info_ie *pAddHtInfo);
-
-void AuthStateMachineInit(struct rt_rtmp_adapter *pAd,
-			  struct rt_state_machine *sm, OUT STATE_MACHINE_FUNC Trans[]);
-
-void AuthTimeout(void *SystemSpecific1,
-		 void *FunctionContext,
-		 void *SystemSpecific2, void *SystemSpecific3);
-
-void MlmeAuthReqAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem);
-
-void PeerAuthRspAtSeq2Action(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem);
-
-void PeerAuthRspAtSeq4Action(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem);
-
-void AuthTimeoutAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem);
-
-void Cls2errAction(struct rt_rtmp_adapter *pAd, u8 *pAddr);
-
-void MlmeDeauthReqAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem);
-
-void InvalidStateWhenAuth(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem);
-
-/*============================================= */
-
-void AuthRspStateMachineInit(struct rt_rtmp_adapter *pAd,
-			     struct rt_state_machine *Sm,
-			     IN STATE_MACHINE_FUNC Trans[]);
-
-void PeerDeauthAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem);
-
-void PeerAuthSimpleRspGenAndSend(struct rt_rtmp_adapter *pAd,
-				 struct rt_header_802_11 *pHdr80211,
-				 u16 Alg,
-				 u16 Seq,
-				 u16 Reason, u16 Status);
-
-/* */
-/* Private routines in dls.c */
-/* */
-
-/*======================================== */
-
-void SyncStateMachineInit(struct rt_rtmp_adapter *pAd,
-			  struct rt_state_machine *Sm,
-			  OUT STATE_MACHINE_FUNC Trans[]);
-
-void BeaconTimeout(void *SystemSpecific1,
-		   void *FunctionContext,
-		   void *SystemSpecific2, void *SystemSpecific3);
-
-void ScanTimeout(void *SystemSpecific1,
-		 void *FunctionContext,
-		 void *SystemSpecific2, void *SystemSpecific3);
-
-void InvalidStateWhenScan(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem);
-
-void InvalidStateWhenJoin(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem);
-
-void InvalidStateWhenStart(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem);
-
-void EnqueueProbeRequest(struct rt_rtmp_adapter *pAd);
-
-BOOLEAN ScanRunning(struct rt_rtmp_adapter *pAd);
-/*========================================= */
-
-void MlmeCntlInit(struct rt_rtmp_adapter *pAd,
-		  struct rt_state_machine *S, OUT STATE_MACHINE_FUNC Trans[]);
-
-void MlmeCntlMachinePerformAction(struct rt_rtmp_adapter *pAd,
-				  struct rt_state_machine *S,
-				  struct rt_mlme_queue_elem *Elem);
-
-void CntlIdleProc(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem);
-
-void CntlOidScanProc(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem);
-
-void CntlOidSsidProc(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem);
-
-void CntlOidRTBssidProc(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem);
-
-void CntlMlmeRoamingProc(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem);
-
-void CntlWaitDisassocProc(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem);
-
-void CntlWaitJoinProc(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem);
-
-void CntlWaitReassocProc(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem);
-
-void CntlWaitStartProc(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem);
-
-void CntlWaitAuthProc(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem);
-
-void CntlWaitAuthProc2(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem);
-
-void CntlWaitAssocProc(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem);
-
-void LinkUp(struct rt_rtmp_adapter *pAd, u8 BssType);
-
-void LinkDown(struct rt_rtmp_adapter *pAd, IN BOOLEAN IsReqFromAP);
-
-void IterateOnBssTab(struct rt_rtmp_adapter *pAd);
-
-void IterateOnBssTab2(struct rt_rtmp_adapter *pAd);
-
-void JoinParmFill(struct rt_rtmp_adapter *pAd,
-		  struct rt_mlme_join_req *JoinReq, unsigned long BssIdx);
-
-void AssocParmFill(struct rt_rtmp_adapter *pAd,
-		   struct rt_mlme_assoc_req *AssocReq,
-		   u8 *pAddr,
-		   u16 CapabilityInfo,
-		   unsigned long Timeout, u16 ListenIntv);
-
-void ScanParmFill(struct rt_rtmp_adapter *pAd,
-		  struct rt_mlme_scan_req *ScanReq,
-		  char Ssid[],
-		  u8 SsidLen, u8 BssType, u8 ScanType);
-
-void DisassocParmFill(struct rt_rtmp_adapter *pAd,
-		      struct rt_mlme_disassoc_req *DisassocReq,
-		      u8 *pAddr, u16 Reason);
-
-void StartParmFill(struct rt_rtmp_adapter *pAd,
-		   struct rt_mlme_start_req *StartReq,
-		   char Ssid[], u8 SsidLen);
-
-void AuthParmFill(struct rt_rtmp_adapter *pAd,
-		  struct rt_mlme_auth_req *AuthReq,
-		  u8 *pAddr, u16 Alg);
-
-void EnqueuePsPoll(struct rt_rtmp_adapter *pAd);
-
-void EnqueueBeaconFrame(struct rt_rtmp_adapter *pAd);
-
-void MlmeJoinReqAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem);
-
-void MlmeScanReqAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem);
-
-void MlmeStartReqAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem);
-
-void ScanTimeoutAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem);
-
-void BeaconTimeoutAtJoinAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem);
-
-void PeerBeaconAtScanAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem);
-
-void PeerBeaconAtJoinAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem);
-
-void PeerBeacon(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem);
-
-void PeerProbeReqAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem);
-
-void ScanNextChannel(struct rt_rtmp_adapter *pAd);
-
-unsigned long MakeIbssBeacon(struct rt_rtmp_adapter *pAd);
-
-BOOLEAN MlmeScanReqSanity(struct rt_rtmp_adapter *pAd,
-			  void *Msg,
-			  unsigned long MsgLen,
-			  u8 *BssType,
-			  char ssid[],
-			  u8 *SsidLen, u8 *ScanType);
-
-BOOLEAN PeerBeaconAndProbeRspSanity(struct rt_rtmp_adapter *pAd,
-				    void *Msg,
-				    unsigned long MsgLen,
-				    u8 MsgChannel,
-				    u8 *pAddr2,
-				    u8 *pBssid,
-				    char Ssid[],
-				    u8 *pSsidLen,
-				    u8 *pBssType,
-				    u16 *pBeaconPeriod,
-				    u8 *pChannel,
-				    u8 *pNewChannel,
-				    OUT LARGE_INTEGER *pTimestamp,
-				    struct rt_cf_parm *pCfParm,
-				    u16 *pAtimWin,
-				    u16 *pCapabilityInfo,
-				    u8 *pErp,
-				    u8 *pDtimCount,
-				    u8 *pDtimPeriod,
-				    u8 *pBcastFlag,
-				    u8 *pMessageToMe,
-				    u8 SupRate[],
-				    u8 *pSupRateLen,
-				    u8 ExtRate[],
-				    u8 *pExtRateLen,
-				    u8 *pCkipFlag,
-				    u8 *pAironetCellPowerLimit,
-				    struct rt_edca_parm *pEdcaParm,
-				    struct rt_qbss_load_parm *pQbssLoad,
-				    struct rt_qos_capability_parm *pQosCapability,
-				    unsigned long *pRalinkIe,
-				    u8 *pHtCapabilityLen,
-				    u8 *pPreNHtCapabilityLen,
-				    struct rt_ht_capability_ie *pHtCapability,
-				    u8 *AddHtInfoLen,
-				    struct rt_add_ht_info_ie *AddHtInfo,
-				    u8 *NewExtChannel,
-				    u16 *LengthVIE,
-				    struct rt_ndis_802_11_variable_ies *pVIE);
-
-BOOLEAN PeerAddBAReqActionSanity(struct rt_rtmp_adapter *pAd,
-				 void *pMsg,
-				 unsigned long MsgLen, u8 *pAddr2);
-
-BOOLEAN PeerAddBARspActionSanity(struct rt_rtmp_adapter *pAd,
-				 void *pMsg, unsigned long MsgLen);
-
-BOOLEAN PeerDelBAActionSanity(struct rt_rtmp_adapter *pAd,
-			      u8 Wcid, void *pMsg, unsigned long MsgLen);
-
-BOOLEAN MlmeAssocReqSanity(struct rt_rtmp_adapter *pAd,
-			   void *Msg,
-			   unsigned long MsgLen,
-			   u8 *pApAddr,
-			   u16 *CapabilityInfo,
-			   unsigned long *Timeout, u16 *ListenIntv);
-
-BOOLEAN MlmeAuthReqSanity(struct rt_rtmp_adapter *pAd,
-			  void *Msg,
-			  unsigned long MsgLen,
-			  u8 *pAddr,
-			  unsigned long *Timeout, u16 *Alg);
-
-BOOLEAN MlmeStartReqSanity(struct rt_rtmp_adapter *pAd,
-			   void *Msg,
-			   unsigned long MsgLen,
-			   char Ssid[], u8 *Ssidlen);
-
-BOOLEAN PeerAuthSanity(struct rt_rtmp_adapter *pAd,
-		       void *Msg,
-		       unsigned long MsgLen,
-		       u8 *pAddr,
-		       u16 *Alg,
-		       u16 *Seq,
-		       u16 *Status, char ChlgText[]);
-
-BOOLEAN PeerAssocRspSanity(struct rt_rtmp_adapter *pAd, void *pMsg, unsigned long MsgLen, u8 *pAddr2, u16 *pCapabilityInfo, u16 *pStatus, u16 *pAid, u8 SupRate[], u8 *pSupRateLen, u8 ExtRate[], u8 *pExtRateLen, struct rt_ht_capability_ie *pHtCapability, struct rt_add_ht_info_ie *pAddHtInfo,	/* AP might use this additional ht info IE */
-			   u8 *pHtCapabilityLen,
-			   u8 *pAddHtInfoLen,
-			   u8 *pNewExtChannelOffset,
-			   struct rt_edca_parm *pEdcaParm, u8 *pCkipFlag);
-
-BOOLEAN PeerDisassocSanity(struct rt_rtmp_adapter *pAd,
-			   void *Msg,
-			   unsigned long MsgLen,
-			   u8 *pAddr2, u16 *Reason);
-
-BOOLEAN PeerWpaMessageSanity(struct rt_rtmp_adapter *pAd,
-			     struct rt_eapol_packet *pMsg,
-			     unsigned long MsgLen,
-			     u8 MsgType, struct rt_mac_table_entry *pEntry);
-
-BOOLEAN PeerDeauthSanity(struct rt_rtmp_adapter *pAd,
-			 void *Msg,
-			 unsigned long MsgLen,
-			 u8 *pAddr2, u16 *Reason);
-
-BOOLEAN PeerProbeReqSanity(struct rt_rtmp_adapter *pAd,
-			   void *Msg,
-			   unsigned long MsgLen,
-			   u8 *pAddr2,
-			   char Ssid[], u8 *pSsidLen);
-
-BOOLEAN GetTimBit(char *Ptr,
-		  u16 Aid,
-		  u8 *TimLen,
-		  u8 *BcastFlag,
-		  u8 *DtimCount,
-		  u8 *DtimPeriod, u8 *MessageToMe);
-
-u8 ChannelSanity(struct rt_rtmp_adapter *pAd, u8 channel);
-
-NDIS_802_11_NETWORK_TYPE NetworkTypeInUseSanity(struct rt_bss_entry *pBss);
-
-BOOLEAN MlmeDelBAReqSanity(struct rt_rtmp_adapter *pAd,
-			   void *Msg, unsigned long MsgLen);
-
-BOOLEAN MlmeAddBAReqSanity(struct rt_rtmp_adapter *pAd,
-			   void *Msg, unsigned long MsgLen, u8 *pAddr2);
-
-unsigned long MakeOutgoingFrame(u8 *Buffer, unsigned long *Length, ...);
-
-void LfsrInit(struct rt_rtmp_adapter *pAd, unsigned long Seed);
-
-u8 RandomByte(struct rt_rtmp_adapter *pAd);
-
-void AsicUpdateAutoFallBackTable(struct rt_rtmp_adapter *pAd, u8 *pTxRate);
-
-void MlmePeriodicExec(void *SystemSpecific1,
-		      void *FunctionContext,
-		      void *SystemSpecific2, void *SystemSpecific3);
-
-void LinkDownExec(void *SystemSpecific1,
-		  void *FunctionContext,
-		  void *SystemSpecific2, void *SystemSpecific3);
-
-void STAMlmePeriodicExec(struct rt_rtmp_adapter *pAd);
-
-void MlmeAutoScan(struct rt_rtmp_adapter *pAd);
-
-void MlmeAutoReconnectLastSSID(struct rt_rtmp_adapter *pAd);
-
-BOOLEAN MlmeValidateSSID(u8 *pSsid, u8 SsidLen);
-
-void MlmeCheckForRoaming(struct rt_rtmp_adapter *pAd, unsigned long Now32);
-
-BOOLEAN MlmeCheckForFastRoaming(struct rt_rtmp_adapter *pAd);
-
-void MlmeDynamicTxRateSwitching(struct rt_rtmp_adapter *pAd);
-
-void MlmeSetTxRate(struct rt_rtmp_adapter *pAd,
-		   struct rt_mac_table_entry *pEntry, struct rt_rtmp_tx_rate_switch * pTxRate);
-
-void MlmeSelectTxRateTable(struct rt_rtmp_adapter *pAd,
-			   struct rt_mac_table_entry *pEntry,
-			   u8 **ppTable,
-			   u8 *pTableSize, u8 *pInitTxRateIdx);
-
-void MlmeCalculateChannelQuality(struct rt_rtmp_adapter *pAd,
-				 struct rt_mac_table_entry *pMacEntry, unsigned long Now);
-
-void MlmeCheckPsmChange(struct rt_rtmp_adapter *pAd, unsigned long Now32);
-
-void MlmeSetPsmBit(struct rt_rtmp_adapter *pAd, u16 psm);
-
-void MlmeSetTxPreamble(struct rt_rtmp_adapter *pAd, u16 TxPreamble);
-
-void UpdateBasicRateBitmap(struct rt_rtmp_adapter *pAd);
-
-void MlmeUpdateTxRates(struct rt_rtmp_adapter *pAd,
-		       IN BOOLEAN bLinkUp, u8 apidx);
-
-void MlmeUpdateHtTxRates(struct rt_rtmp_adapter *pAd, u8 apidx);
-
-void RTMPCheckRates(struct rt_rtmp_adapter *pAd,
-		    IN u8 SupRate[], IN u8 *SupRateLen);
-
-BOOLEAN RTMPCheckChannel(struct rt_rtmp_adapter *pAd,
-			 u8 CentralChannel, u8 Channel);
-
-BOOLEAN RTMPCheckHt(struct rt_rtmp_adapter *pAd,
-		    u8 Wcid,
-		    struct rt_ht_capability_ie *pHtCapability,
-		    struct rt_add_ht_info_ie *pAddHtInfo);
-
-void StaQuickResponeForRateUpExec(void *SystemSpecific1,
-				  void *FunctionContext,
-				  void *SystemSpecific2,
-				  void *SystemSpecific3);
-
-void RTMPUpdateMlmeRate(struct rt_rtmp_adapter *pAd);
-
-char RTMPMaxRssi(struct rt_rtmp_adapter *pAd,
-		 char Rssi0, char Rssi1, char Rssi2);
-
-#ifdef RT30xx
-void AsicSetRxAnt(struct rt_rtmp_adapter *pAd, u8 Ant);
-
-void RTMPFilterCalibration(struct rt_rtmp_adapter *pAd);
-
-#ifdef RTMP_EFUSE_SUPPORT
-/*2008/09/11:KH add to support efuse<-- */
-int set_eFuseGetFreeBlockCount_Proc(struct rt_rtmp_adapter *pAd, char *arg);
-
-int set_eFusedump_Proc(struct rt_rtmp_adapter *pAd, char *arg);
-
-void eFusePhysicalReadRegisters(struct rt_rtmp_adapter *pAd,
-				u16 Offset,
-				u16 Length, u16 *pData);
-
-int RtmpEfuseSupportCheck(struct rt_rtmp_adapter *pAd);
-
-void eFuseGetFreeBlockCount(struct rt_rtmp_adapter *pAd, u32 *EfuseFreeBlock);
-
-int eFuse_init(struct rt_rtmp_adapter *pAd);
-/*2008/09/11:KH add to support efuse--> */
-#endif /* RTMP_EFUSE_SUPPORT // */
-
-/* add by johnli, RF power sequence setup */
-void RT30xxLoadRFNormalModeSetup(struct rt_rtmp_adapter *pAd);
-
-void RT30xxLoadRFSleepModeSetup(struct rt_rtmp_adapter *pAd);
-
-void RT30xxReverseRFSleepModeSetup(struct rt_rtmp_adapter *pAd);
-/* end johnli */
-
-#ifdef RT3070
-void NICInitRT3070RFRegisters(struct rt_rtmp_adapter *pAd);
-#endif /* RT3070 // */
-#ifdef RT3090
-void NICInitRT3090RFRegisters(struct rt_rtmp_adapter *pAd);
-#endif /* RT3090 // */
-
-void RT30xxHaltAction(struct rt_rtmp_adapter *pAd);
-
-void RT30xxSetRxAnt(struct rt_rtmp_adapter *pAd, u8 Ant);
-#endif /* RT30xx // */
-
-void AsicEvaluateRxAnt(struct rt_rtmp_adapter *pAd);
-
-void AsicRxAntEvalTimeout(void *SystemSpecific1,
-			  void *FunctionContext,
-			  void *SystemSpecific2, void *SystemSpecific3);
-
-void APSDPeriodicExec(void *SystemSpecific1,
-		      void *FunctionContext,
-		      void *SystemSpecific2, void *SystemSpecific3);
-
-BOOLEAN RTMPCheckEntryEnableAutoRateSwitch(struct rt_rtmp_adapter *pAd,
-					   struct rt_mac_table_entry *pEntry);
-
-u8 RTMPStaFixedTxMode(struct rt_rtmp_adapter *pAd, struct rt_mac_table_entry *pEntry);
-
-void RTMPUpdateLegacyTxSetting(u8 fixed_tx_mode, struct rt_mac_table_entry *pEntry);
-
-BOOLEAN RTMPAutoRateSwitchCheck(struct rt_rtmp_adapter *pAd);
-
-int MlmeInit(struct rt_rtmp_adapter *pAd);
-
-void MlmeHandler(struct rt_rtmp_adapter *pAd);
-
-void MlmeHalt(struct rt_rtmp_adapter *pAd);
-
-void MlmeResetRalinkCounters(struct rt_rtmp_adapter *pAd);
-
-void BuildChannelList(struct rt_rtmp_adapter *pAd);
-
-u8 FirstChannel(struct rt_rtmp_adapter *pAd);
-
-u8 NextChannel(struct rt_rtmp_adapter *pAd, u8 channel);
-
-void ChangeToCellPowerLimit(struct rt_rtmp_adapter *pAd,
-			    u8 AironetCellPowerLimit);
-
-/* */
-/* Prototypes of function definition in rtmp_tkip.c */
-/* */
-void RTMPInitTkipEngine(struct rt_rtmp_adapter *pAd,
-			u8 *pTKey,
-			u8 KeyId,
-			u8 *pTA,
-			u8 *pMICKey,
-			u8 *pTSC, unsigned long *pIV16, unsigned long *pIV32);
-
-void RTMPInitMICEngine(struct rt_rtmp_adapter *pAd,
-		       u8 *pKey,
-		       u8 *pDA,
-		       u8 *pSA, u8 UserPriority, u8 *pMICKey);
-
-BOOLEAN RTMPTkipCompareMICValue(struct rt_rtmp_adapter *pAd,
-				u8 *pSrc,
-				u8 *pDA,
-				u8 *pSA,
-				u8 *pMICKey,
-				u8 UserPriority, u32 Len);
-
-void RTMPCalculateMICValue(struct rt_rtmp_adapter *pAd,
-			   void *pPacket,
-			   u8 *pEncap,
-			   struct rt_cipher_key *pKey, u8 apidx);
-
-void RTMPTkipAppendByte(struct rt_tkip_key_info *pTkip, u8 uChar);
-
-void RTMPTkipAppend(struct rt_tkip_key_info *pTkip, u8 *pSrc, u32 nBytes);
-
-void RTMPTkipGetMIC(struct rt_tkip_key_info *pTkip);
-
-BOOLEAN RTMPSoftDecryptTKIP(struct rt_rtmp_adapter *pAd,
-			    u8 *pData,
-			    unsigned long DataByteCnt,
-			    u8 UserPriority, struct rt_cipher_key *pWpaKey);
-
-BOOLEAN RTMPSoftDecryptAES(struct rt_rtmp_adapter *pAd,
-			   u8 *pData,
-			   unsigned long DataByteCnt, struct rt_cipher_key *pWpaKey);
-
-/* */
-/* Prototypes of function definition in cmm_info.c */
-/* */
-int RT_CfgSetCountryRegion(struct rt_rtmp_adapter *pAd, char *arg, int band);
-
-int RT_CfgSetWirelessMode(struct rt_rtmp_adapter *pAd, char *arg);
-
-int RT_CfgSetShortSlot(struct rt_rtmp_adapter *pAd, char *arg);
-
-int RT_CfgSetWepKey(struct rt_rtmp_adapter *pAd,
-		    char *keyString,
-		    struct rt_cipher_key *pSharedKey, int keyIdx);
-
-int RT_CfgSetWPAPSKKey(struct rt_rtmp_adapter *pAd,
-		       char *keyString,
-		       u8 *pHashStr,
-		       int hashStrLen, u8 *pPMKBuf);
-
-/* */
-/* Prototypes of function definition in cmm_info.c */
-/* */
-void RTMPWPARemoveAllKeys(struct rt_rtmp_adapter *pAd);
-
-void RTMPSetPhyMode(struct rt_rtmp_adapter *pAd, unsigned long phymode);
-
-void RTMPUpdateHTIE(struct rt_ht_capability *pRtHt,
-		    u8 *pMcsSet,
-		    struct rt_ht_capability_ie *pHtCapability,
-		    struct rt_add_ht_info_ie *pAddHtInfo);
-
-void RTMPAddWcidAttributeEntry(struct rt_rtmp_adapter *pAd,
-			       u8 BssIdx,
-			       u8 KeyIdx,
-			       u8 CipherAlg, struct rt_mac_table_entry *pEntry);
-
-char *GetEncryptType(char enc);
-
-char *GetAuthMode(char auth);
-
-void RTMPSetHT(struct rt_rtmp_adapter *pAd, struct rt_oid_set_ht_phymode *pHTPhyMode);
-
-void RTMPSetIndividualHT(struct rt_rtmp_adapter *pAd, u8 apidx);
-
-void RTMPSendWirelessEvent(struct rt_rtmp_adapter *pAd,
-			   u16 Event_flag,
-			   u8 *pAddr, u8 BssIdx, char Rssi);
-
-char ConvertToRssi(struct rt_rtmp_adapter *pAd, char Rssi, u8 RssiNumber);
-
-/*===================================
-	Function prototype in cmm_wpa.c
-  =================================== */
-void RTMPToWirelessSta(struct rt_rtmp_adapter *pAd,
-		       struct rt_mac_table_entry *pEntry,
-		       u8 *pHeader802_3,
-		       u32 HdrLen,
-		       u8 *pData,
-		       u32 DataLen, IN BOOLEAN bClearFrame);
-
-void WpaDerivePTK(struct rt_rtmp_adapter *pAd,
-		  u8 *PMK,
-		  u8 *ANonce,
-		  u8 *AA,
-		  u8 *SNonce,
-		  u8 *SA, u8 *output, u32 len);
-
-void GenRandom(struct rt_rtmp_adapter *pAd, u8 *macAddr, u8 *random);
-
-BOOLEAN RTMPCheckWPAframe(struct rt_rtmp_adapter *pAd,
-			  struct rt_mac_table_entry *pEntry,
-			  u8 *pData,
-			  unsigned long DataByteCount, u8 FromWhichBSSID);
-
-void AES_GTK_KEY_UNWRAP(u8 *key,
-			u8 *plaintext,
-			u32 c_len, u8 *ciphertext);
-
-BOOLEAN RTMPParseEapolKeyData(struct rt_rtmp_adapter *pAd,
-			      u8 *pKeyData,
-			      u8 KeyDataLen,
-			      u8 GroupKeyIndex,
-			      u8 MsgType,
-			      IN BOOLEAN bWPA2, struct rt_mac_table_entry *pEntry);
-
-void ConstructEapolMsg(struct rt_mac_table_entry *pEntry,
-		       u8 GroupKeyWepStatus,
-		       u8 MsgType,
-		       u8 DefaultKeyIdx,
-		       u8 *KeyNonce,
-		       u8 *TxRSC,
-		       u8 *GTK,
-		       u8 *RSNIE,
-		       u8 RSNIE_Len, struct rt_eapol_packet *pMsg);
-
-int RTMPSoftDecryptBroadCastData(struct rt_rtmp_adapter *pAd,
-					 struct rt_rx_blk *pRxBlk,
-					 IN NDIS_802_11_ENCRYPTION_STATUS
-					 GroupCipher,
-					 struct rt_cipher_key *pShard_key);
-
-void RTMPMakeRSNIE(struct rt_rtmp_adapter *pAd,
-		   u32 AuthMode, u32 WepStatus, u8 apidx);
-
-/* */
-/* function prototype in ap_wpa.c */
-/* */
-void RTMPGetTxTscFromAsic(struct rt_rtmp_adapter *pAd,
-			  u8 apidx, u8 *pTxTsc);
-
-void APInstallPairwiseKey(struct rt_rtmp_adapter *pAd, struct rt_mac_table_entry *pEntry);
-
-u32 APValidateRSNIE(struct rt_rtmp_adapter *pAd,
-		     struct rt_mac_table_entry *pEntry,
-		     u8 *pRsnIe, u8 rsnie_len);
-
-void HandleCounterMeasure(struct rt_rtmp_adapter *pAd, struct rt_mac_table_entry *pEntry);
-
-void WPAStart4WayHS(struct rt_rtmp_adapter *pAd,
-		    struct rt_mac_table_entry *pEntry, unsigned long TimeInterval);
-
-void WPAStart2WayGroupHS(struct rt_rtmp_adapter *pAd, struct rt_mac_table_entry *pEntry);
-
-void PeerPairMsg1Action(struct rt_rtmp_adapter *pAd,
-			struct rt_mac_table_entry *pEntry, struct rt_mlme_queue_elem *Elem);
-
-void PeerPairMsg2Action(struct rt_rtmp_adapter *pAd,
-			struct rt_mac_table_entry *pEntry, struct rt_mlme_queue_elem *Elem);
-
-void PeerPairMsg3Action(struct rt_rtmp_adapter *pAd,
-			struct rt_mac_table_entry *pEntry, struct rt_mlme_queue_elem *Elem);
-
-void PeerPairMsg4Action(struct rt_rtmp_adapter *pAd,
-			struct rt_mac_table_entry *pEntry, struct rt_mlme_queue_elem *Elem);
-
-void PeerGroupMsg1Action(struct rt_rtmp_adapter *pAd,
-			 struct rt_mac_table_entry *pEntry, struct rt_mlme_queue_elem *Elem);
-
-void PeerGroupMsg2Action(struct rt_rtmp_adapter *pAd,
-			 struct rt_mac_table_entry *pEntry,
-			 void *Msg, u32 MsgLen);
-
-void WpaDeriveGTK(u8 *PMK,
-		  u8 *GNonce,
-		  u8 *AA, u8 *output, u32 len);
-
-void AES_GTK_KEY_WRAP(u8 *key,
-		      u8 *plaintext,
-		      u32 p_len, u8 *ciphertext);
-
-/*typedef void (*TIMER_FUNCTION)(unsigned long); */
-
-/* timeout -- ms */
-void RTMP_SetPeriodicTimer(struct timer_list *pTimer,
-			   IN unsigned long timeout);
-
-void RTMP_OS_Init_Timer(struct rt_rtmp_adapter *pAd,
-			struct timer_list *pTimer,
-			IN TIMER_FUNCTION function, void *data);
-
-void RTMP_OS_Add_Timer(struct timer_list *pTimer,
-		       IN unsigned long timeout);
-
-void RTMP_OS_Mod_Timer(struct timer_list *pTimer,
-		       IN unsigned long timeout);
-
-void RTMP_OS_Del_Timer(struct timer_list *pTimer,
-		       OUT BOOLEAN *pCancelled);
-
-void RTMP_OS_Release_Packet(struct rt_rtmp_adapter *pAd, struct rt_queue_entry *pEntry);
-
-void RTMPusecDelay(unsigned long usec);
-
-int os_alloc_mem(struct rt_rtmp_adapter *pAd,
-			 u8 **mem, unsigned long size);
-
-int os_free_mem(struct rt_rtmp_adapter *pAd, void *mem);
-
-void RTMP_AllocateSharedMemory(struct rt_rtmp_adapter *pAd,
-			       unsigned long Length,
-			       IN BOOLEAN Cached,
-			       void **VirtualAddress,
-			       dma_addr_t *PhysicalAddress);
-
-void RTMPFreeTxRxRingMemory(struct rt_rtmp_adapter *pAd);
-
-int AdapterBlockAllocateMemory(void *handle, void **ppAd);
-
-void RTMP_AllocateTxDescMemory(struct rt_rtmp_adapter *pAd,
-			       u32 Index,
-			       unsigned long Length,
-			       IN BOOLEAN Cached,
-			       void **VirtualAddress,
-			       dma_addr_t *PhysicalAddress);
-
-void RTMP_AllocateFirstTxBuffer(struct rt_rtmp_adapter *pAd,
-				u32 Index,
-				unsigned long Length,
-				IN BOOLEAN Cached,
-				void **VirtualAddress,
-				dma_addr_t *PhysicalAddress);
-
-void RTMP_FreeFirstTxBuffer(struct rt_rtmp_adapter *pAd,
-			    unsigned long Length,
-			    IN BOOLEAN Cached,
-			    void *VirtualAddress,
-			    dma_addr_t PhysicalAddress);
-
-void RTMP_AllocateMgmtDescMemory(struct rt_rtmp_adapter *pAd,
-				 unsigned long Length,
-				 IN BOOLEAN Cached,
-				 void **VirtualAddress,
-				 dma_addr_t *PhysicalAddress);
-
-void RTMP_AllocateRxDescMemory(struct rt_rtmp_adapter *pAd,
-			       unsigned long Length,
-			       IN BOOLEAN Cached,
-			       void **VirtualAddress,
-			       dma_addr_t *PhysicalAddress);
-
-void RTMP_FreeDescMemory(struct rt_rtmp_adapter *pAd,
-			 unsigned long Length,
-			 void *VirtualAddress,
-			 dma_addr_t PhysicalAddress);
-
-void *RtmpOSNetPktAlloc(struct rt_rtmp_adapter *pAd, IN int size);
-
-void *RTMP_AllocateRxPacketBuffer(struct rt_rtmp_adapter *pAd,
-					 unsigned long Length,
-					 IN BOOLEAN Cached,
-					 void **VirtualAddress,
-					 OUT dma_addr_t *PhysicalAddress);
-
-void *RTMP_AllocateTxPacketBuffer(struct rt_rtmp_adapter *pAd,
-					 unsigned long Length,
-					 IN BOOLEAN Cached,
-					 void **VirtualAddress);
-
-void *RTMP_AllocateFragPacketBuffer(struct rt_rtmp_adapter *pAd,
-					   unsigned long Length);
-
-void RTMP_QueryPacketInfo(void *pPacket,
-			  struct rt_packet_info *pPacketInfo,
-			  u8 **pSrcBufVA, u32 *pSrcBufLen);
-
-void RTMP_QueryNextPacketInfo(void **ppPacket,
-			      struct rt_packet_info *pPacketInfo,
-			      u8 **pSrcBufVA, u32 *pSrcBufLen);
-
-BOOLEAN RTMP_FillTxBlkInfo(struct rt_rtmp_adapter *pAd, struct rt_tx_blk *pTxBlk);
-
-struct rt_rtmp_sg_list *rt_get_sg_list_from_packet(void *pPacket,
-						struct rt_rtmp_sg_list *sg);
-
-void announce_802_3_packet(struct rt_rtmp_adapter *pAd, void *pPacket);
-
-u32 BA_Reorder_AMSDU_Announce(struct rt_rtmp_adapter *pAd, void *pPacket);
-
-struct net_device *get_netdev_from_bssid(struct rt_rtmp_adapter *pAd, u8 FromWhichBSSID);
-
-void *duplicate_pkt(struct rt_rtmp_adapter *pAd,
-			   u8 *pHeader802_3,
-			   u32 HdrLen,
-			   u8 *pData,
-			   unsigned long DataSize, u8 FromWhichBSSID);
-
-void *duplicate_pkt_with_TKIP_MIC(struct rt_rtmp_adapter *pAd,
-					 void *pOldPkt);
-
-void ba_flush_reordering_timeout_mpdus(struct rt_rtmp_adapter *pAd,
-				       struct rt_ba_rec_entry *pBAEntry,
-				       unsigned long Now32);
-
-void BAOriSessionSetUp(struct rt_rtmp_adapter *pAd,
-		       struct rt_mac_table_entry *pEntry,
-		       u8 TID,
-		       u16 TimeOut,
-		       unsigned long DelayTime, IN BOOLEAN isForced);
-
-void BASessionTearDownALL(struct rt_rtmp_adapter *pAd, u8 Wcid);
-
-BOOLEAN OS_Need_Clone_Packet(void);
-
-void build_tx_packet(struct rt_rtmp_adapter *pAd,
-		     void *pPacket,
-		     u8 *pFrame, unsigned long FrameLen);
-
-void BAOriSessionTearDown(struct rt_rtmp_adapter *pAd,
-			  u8 Wcid,
-			  u8 TID,
-			  IN BOOLEAN bPassive, IN BOOLEAN bForceSend);
-
-void BARecSessionTearDown(struct rt_rtmp_adapter *pAd,
-			  u8 Wcid, u8 TID, IN BOOLEAN bPassive);
-
-BOOLEAN ba_reordering_resource_init(struct rt_rtmp_adapter *pAd, int num);
-void ba_reordering_resource_release(struct rt_rtmp_adapter *pAd);
-
-char *rstrtok(char *s, IN const char *ct);
-
-/*//////// common ioctl functions ////////// */
-int SetCommonHT(struct rt_rtmp_adapter *pAd);
-
-int WpaCheckEapCode(struct rt_rtmp_adapter *pAd,
-		    u8 *pFrame, u16 FrameLen, u16 OffSet);
-
-void WpaSendMicFailureToWpaSupplicant(struct rt_rtmp_adapter *pAd,
-				      IN BOOLEAN bUnicast);
-
-int wext_notify_event_assoc(struct rt_rtmp_adapter *pAd);
-
-BOOLEAN STARxDoneInterruptHandle(struct rt_rtmp_adapter *pAd, IN BOOLEAN argc);
-
-/* AMPDU packet indication */
-void Indicate_AMPDU_Packet(struct rt_rtmp_adapter *pAd,
-			   struct rt_rx_blk *pRxBlk, u8 FromWhichBSSID);
-
-/* AMSDU packet indication */
-void Indicate_AMSDU_Packet(struct rt_rtmp_adapter *pAd,
-			   struct rt_rx_blk *pRxBlk, u8 FromWhichBSSID);
-
-/* Normal legacy Rx packet indication */
-void Indicate_Legacy_Packet(struct rt_rtmp_adapter *pAd,
-			    struct rt_rx_blk *pRxBlk, u8 FromWhichBSSID);
-
-void Indicate_EAPOL_Packet(struct rt_rtmp_adapter *pAd,
-			   struct rt_rx_blk *pRxBlk, u8 FromWhichBSSID);
-
-void update_os_packet_info(struct rt_rtmp_adapter *pAd,
-			   struct rt_rx_blk *pRxBlk, u8 FromWhichBSSID);
-
-void wlan_802_11_to_802_3_packet(struct rt_rtmp_adapter *pAd,
-				 struct rt_rx_blk *pRxBlk,
-				 u8 *pHeader802_3,
-				 u8 FromWhichBSSID);
-
-/* remove LLC and get 802_3 Header */
-#define  RTMP_802_11_REMOVE_LLC_AND_CONVERT_TO_802_3(_pRxBlk, _pHeader802_3)	\
-{																				\
-	u8 *_pRemovedLLCSNAP = NULL, *_pDA, *_pSA;                                 \
-																				\
-	if (RX_BLK_TEST_FLAG(_pRxBlk, fRX_MESH))	{            \
-		_pDA = _pRxBlk->pHeader->Addr3;                                         \
-		_pSA = (u8 *)_pRxBlk->pHeader + sizeof(struct rt_header_802_11);                \
-	}                                                                           \
-	else	{\
-		if (RX_BLK_TEST_FLAG(_pRxBlk, fRX_INFRA))	{\
-			_pDA = _pRxBlk->pHeader->Addr1;                                     \
-		if (RX_BLK_TEST_FLAG(_pRxBlk, fRX_DLS))									\
-			_pSA = _pRxBlk->pHeader->Addr2;										\
-		else																	\
-			_pSA = _pRxBlk->pHeader->Addr3;                                     \
-		}                                                                       \
-		else	{	\
-			_pDA = _pRxBlk->pHeader->Addr1;                                     \
-			_pSA = _pRxBlk->pHeader->Addr2;                                     \
-		}                                                                       \
-	}                                                                           \
-																				\
-	CONVERT_TO_802_3(_pHeader802_3, _pDA, _pSA, _pRxBlk->pData, 				\
-		_pRxBlk->DataSize, _pRemovedLLCSNAP);                                   \
-}
-
-void Sta_Announce_or_Forward_802_3_Packet(struct rt_rtmp_adapter *pAd,
-					  void *pPacket,
-					  u8 FromWhichBSSID);
-
-#define ANNOUNCE_OR_FORWARD_802_3_PACKET(_pAd, _pPacket, _FromWhichBSS)\
-			Sta_Announce_or_Forward_802_3_Packet(_pAd, _pPacket, _FromWhichBSS);
-			/*announce_802_3_packet(_pAd, _pPacket); */
-
-void *DuplicatePacket(struct rt_rtmp_adapter *pAd,
-			     void *pPacket, u8 FromWhichBSSID);
-
-void *ClonePacket(struct rt_rtmp_adapter *pAd,
-			 void *pPacket,
-			 u8 *pData, unsigned long DataSize);
-
-/* Normal, AMPDU or AMSDU */
-void CmmRxnonRalinkFrameIndicate(struct rt_rtmp_adapter *pAd,
-				 struct rt_rx_blk *pRxBlk, u8 FromWhichBSSID);
-
-void CmmRxRalinkFrameIndicate(struct rt_rtmp_adapter *pAd,
-			      struct rt_mac_table_entry *pEntry,
-			      struct rt_rx_blk *pRxBlk, u8 FromWhichBSSID);
-
-void Update_Rssi_Sample(struct rt_rtmp_adapter *pAd,
-			struct rt_rssi_sample *pRssi, struct rt_rxwi * pRxWI);
-
-void *GetPacketFromRxRing(struct rt_rtmp_adapter *pAd,
-				 OUT PRT28XX_RXD_STRUC pSaveRxD,
-				 OUT BOOLEAN *pbReschedule,
-				 IN u32 *pRxPending);
-
-void *RTMPDeFragmentDataFrame(struct rt_rtmp_adapter *pAd, struct rt_rx_blk *pRxBlk);
-
-enum {
-	DIDmsg_lnxind_wlansniffrm = 0x00000044,
-	DIDmsg_lnxind_wlansniffrm_hosttime = 0x00010044,
-	DIDmsg_lnxind_wlansniffrm_mactime = 0x00020044,
-	DIDmsg_lnxind_wlansniffrm_channel = 0x00030044,
-	DIDmsg_lnxind_wlansniffrm_rssi = 0x00040044,
-	DIDmsg_lnxind_wlansniffrm_sq = 0x00050044,
-	DIDmsg_lnxind_wlansniffrm_signal = 0x00060044,
-	DIDmsg_lnxind_wlansniffrm_noise = 0x00070044,
-	DIDmsg_lnxind_wlansniffrm_rate = 0x00080044,
-	DIDmsg_lnxind_wlansniffrm_istx = 0x00090044,
-	DIDmsg_lnxind_wlansniffrm_frmlen = 0x000A0044
-};
-enum {
-	P80211ENUM_msgitem_status_no_value = 0x00
-};
-enum {
-	P80211ENUM_truth_false = 0x00,
-	P80211ENUM_truth_true = 0x01
-};
-
-/* Definition from madwifi */
-struct rt_p80211item_uint32 {
-	u32 did;
-	u16 status;
-	u16 len;
-	u32 data;
-};
-
-struct rt_wlan_ng_prism2_header {
-	u32 msgcode;
-	u32 msglen;
-#define WLAN_DEVNAMELEN_MAX 16
-	u8 devname[WLAN_DEVNAMELEN_MAX];
-	struct rt_p80211item_uint32 hosttime;
-	struct rt_p80211item_uint32 mactime;
-	struct rt_p80211item_uint32 channel;
-	struct rt_p80211item_uint32 rssi;
-	struct rt_p80211item_uint32 sq;
-	struct rt_p80211item_uint32 signal;
-	struct rt_p80211item_uint32 noise;
-	struct rt_p80211item_uint32 rate;
-	struct rt_p80211item_uint32 istx;
-	struct rt_p80211item_uint32 frmlen;
-};
-
-/* The radio capture header precedes the 802.11 header. */
-struct PACKED rt_ieee80211_radiotap_header {
-	u8 it_version;	/* Version 0. Only increases
-				 * for drastic changes,
-				 * introduction of compatible
-				 * new fields does not count.
-				 */
-	u8 it_pad;
-	u16 it_len;		/* length of the whole
-				 * header in bytes, including
-				 * it_version, it_pad,
-				 * it_len, and data fields.
-				 */
-	u32 it_present;	/* A bitmap telling which
-				 * fields are present. Set bit 31
-				 * (0x80000000) to extend the
-				 * bitmap by another 32 bits.
-				 * Additional extensions are made
-				 * by setting bit 31.
-				 */
-};
-
-enum ieee80211_radiotap_type {
-	IEEE80211_RADIOTAP_TSFT = 0,
-	IEEE80211_RADIOTAP_FLAGS = 1,
-	IEEE80211_RADIOTAP_RATE = 2,
-	IEEE80211_RADIOTAP_CHANNEL = 3,
-	IEEE80211_RADIOTAP_FHSS = 4,
-	IEEE80211_RADIOTAP_DBM_ANTSIGNAL = 5,
-	IEEE80211_RADIOTAP_DBM_ANTNOISE = 6,
-	IEEE80211_RADIOTAP_LOCK_QUALITY = 7,
-	IEEE80211_RADIOTAP_TX_ATTENUATION = 8,
-	IEEE80211_RADIOTAP_DB_TX_ATTENUATION = 9,
-	IEEE80211_RADIOTAP_DBM_TX_POWER = 10,
-	IEEE80211_RADIOTAP_ANTENNA = 11,
-	IEEE80211_RADIOTAP_DB_ANTSIGNAL = 12,
-	IEEE80211_RADIOTAP_DB_ANTNOISE = 13
-};
-
-#define WLAN_RADIOTAP_PRESENT (			\
-	(1 << IEEE80211_RADIOTAP_TSFT)	|	\
-	(1 << IEEE80211_RADIOTAP_FLAGS) |	\
-	(1 << IEEE80211_RADIOTAP_RATE)  | 	\
-	 0)
-
-struct rt_wlan_radiotap_header {
-	struct rt_ieee80211_radiotap_header wt_ihdr;
-	long long wt_tsft;
-	u8 wt_flags;
-	u8 wt_rate;
-};
-/* Definition from madwifi */
-
-void send_monitor_packets(struct rt_rtmp_adapter *pAd, struct rt_rx_blk *pRxBlk);
-
-void RTMPSetDesiredRates(struct rt_rtmp_adapter *pAdapter, long Rates);
-
-int Set_FixedTxMode_Proc(struct rt_rtmp_adapter *pAd, char *arg);
-
-BOOLEAN RT28XXChipsetCheck(IN void *_dev_p);
-
-void RT28XXDMADisable(struct rt_rtmp_adapter *pAd);
-
-void RT28XXDMAEnable(struct rt_rtmp_adapter *pAd);
-
-void RT28xx_UpdateBeaconToAsic(struct rt_rtmp_adapter *pAd,
-			       int apidx,
-			       unsigned long BeaconLen, unsigned long UpdatePos);
-
-int rt28xx_init(struct rt_rtmp_adapter *pAd,
-		char *pDefaultMac, char *pHostName);
-
-int RtmpNetTaskInit(struct rt_rtmp_adapter *pAd);
-
-void RtmpNetTaskExit(struct rt_rtmp_adapter *pAd);
-
-int RtmpMgmtTaskInit(struct rt_rtmp_adapter *pAd);
-
-void RtmpMgmtTaskExit(struct rt_rtmp_adapter *pAd);
-
-void tbtt_tasklet(unsigned long data);
-
-struct net_device *RtmpPhyNetDevInit(struct rt_rtmp_adapter *pAd,
-			   struct rt_rtmp_os_netdev_op_hook *pNetHook);
-
-BOOLEAN RtmpPhyNetDevExit(struct rt_rtmp_adapter *pAd, struct net_device *net_dev);
-
-int RtmpRaDevCtrlInit(struct rt_rtmp_adapter *pAd, IN RTMP_INF_TYPE infType);
-
-BOOLEAN RtmpRaDevCtrlExit(struct rt_rtmp_adapter *pAd);
-
-#ifdef RTMP_MAC_PCI
-/* */
-/* Function Prototype in cmm_data_pci.c */
-/* */
-u16 RtmpPCI_WriteTxResource(struct rt_rtmp_adapter *pAd,
-			       struct rt_tx_blk *pTxBlk,
-			       IN BOOLEAN bIsLast, u16 *FreeNumber);
-
-u16 RtmpPCI_WriteSingleTxResource(struct rt_rtmp_adapter *pAd,
-				     struct rt_tx_blk *pTxBlk,
-				     IN BOOLEAN bIsLast,
-				     u16 *FreeNumber);
-
-u16 RtmpPCI_WriteMultiTxResource(struct rt_rtmp_adapter *pAd,
-				    struct rt_tx_blk *pTxBlk,
-				    u8 frameNum, u16 *FreeNumber);
-
-u16 RtmpPCI_WriteFragTxResource(struct rt_rtmp_adapter *pAd,
-				   struct rt_tx_blk *pTxBlk,
-				   u8 fragNum, u16 *FreeNumber);
-
-u16 RtmpPCI_WriteSubTxResource(struct rt_rtmp_adapter *pAd,
-				  struct rt_tx_blk *pTxBlk,
-				  IN BOOLEAN bIsLast, u16 *FreeNumber);
-
-void RtmpPCI_FinalWriteTxResource(struct rt_rtmp_adapter *pAd,
-				  struct rt_tx_blk *pTxBlk,
-				  u16 totalMPDUSize,
-				  u16 FirstTxIdx);
-
-void RtmpPCIDataLastTxIdx(struct rt_rtmp_adapter *pAd,
-			  u8 QueIdx, u16 LastTxIdx);
-
-void RtmpPCIDataKickOut(struct rt_rtmp_adapter *pAd,
-			struct rt_tx_blk *pTxBlk, u8 QueIdx);
-
-int RtmpPCIMgmtKickOut(struct rt_rtmp_adapter *pAd,
-		       u8 QueIdx,
-		       void *pPacket,
-		       u8 *pSrcBufVA, u32 SrcBufLen);
-
-int RTMPCheckRxError(struct rt_rtmp_adapter *pAd,
-			     struct rt_header_802_11 *pHeader,
-			     struct rt_rxwi *pRxWI, IN PRT28XX_RXD_STRUC pRxD);
-
-BOOLEAN RT28xxPciAsicRadioOff(struct rt_rtmp_adapter *pAd,
-			      u8 Level, u16 TbttNumToNextWakeUp);
-
-BOOLEAN RT28xxPciAsicRadioOn(struct rt_rtmp_adapter *pAd, u8 Level);
-
-void RTMPInitPCIeLinkCtrlValue(struct rt_rtmp_adapter *pAd);
-
-void RTMPFindHostPCIDev(struct rt_rtmp_adapter *pAd);
-
-void RTMPPCIeLinkCtrlValueRestore(struct rt_rtmp_adapter *pAd, u8 Level);
-
-void RTMPPCIeLinkCtrlSetting(struct rt_rtmp_adapter *pAd, u16 Max);
-
-void RTMPrt3xSetPCIePowerLinkCtrl(struct rt_rtmp_adapter *pAd);
-
-void PsPollWakeExec(void *SystemSpecific1,
-		    void *FunctionContext,
-		    void *SystemSpecific2, void *SystemSpecific3);
-
-void RadioOnExec(void *SystemSpecific1,
-		 void *FunctionContext,
-		 void *SystemSpecific2, void *SystemSpecific3);
-
-void RT28xxPciStaAsicForceWakeup(struct rt_rtmp_adapter *pAd, IN BOOLEAN bFromTx);
-
-void RT28xxPciStaAsicSleepThenAutoWakeup(struct rt_rtmp_adapter *pAd,
-					 u16 TbttNumToNextWakeUp);
-
-void RT28xxPciMlmeRadioOn(struct rt_rtmp_adapter *pAd);
-
-void RT28xxPciMlmeRadioOFF(struct rt_rtmp_adapter *pAd);
-#endif /* RTMP_MAC_PCI // */
-
-#ifdef RTMP_MAC_USB
-/* */
-/* Function Prototype in rtusb_bulk.c */
-/* */
-void RTUSBInitTxDesc(struct rt_rtmp_adapter *pAd,
-		     struct rt_tx_context *pTxContext,
-		     u8 BulkOutPipeId, IN usb_complete_t Func);
-
-void RTUSBInitHTTxDesc(struct rt_rtmp_adapter *pAd,
-		       struct rt_ht_tx_context *pTxContext,
-		       u8 BulkOutPipeId,
-		       unsigned long BulkOutSize, IN usb_complete_t Func);
-
-void RTUSBInitRxDesc(struct rt_rtmp_adapter *pAd, struct rt_rx_context *pRxContext);
-
-void RTUSBCleanUpDataBulkOutQueue(struct rt_rtmp_adapter *pAd);
-
-void RTUSBCancelPendingBulkOutIRP(struct rt_rtmp_adapter *pAd);
-
-void RTUSBBulkOutDataPacket(struct rt_rtmp_adapter *pAd,
-			    u8 BulkOutPipeId, u8 Index);
-
-void RTUSBBulkOutNullFrame(struct rt_rtmp_adapter *pAd);
-
-void RTUSBBulkOutRTSFrame(struct rt_rtmp_adapter *pAd);
-
-void RTUSBCancelPendingBulkInIRP(struct rt_rtmp_adapter *pAd);
-
-void RTUSBCancelPendingIRPs(struct rt_rtmp_adapter *pAd);
-
-void RTUSBBulkOutMLMEPacket(struct rt_rtmp_adapter *pAd, u8 Index);
-
-void RTUSBBulkOutPsPoll(struct rt_rtmp_adapter *pAd);
-
-void RTUSBCleanUpMLMEBulkOutQueue(struct rt_rtmp_adapter *pAd);
-
-void RTUSBKickBulkOut(struct rt_rtmp_adapter *pAd);
-
-void RTUSBBulkReceive(struct rt_rtmp_adapter *pAd);
-
-void DoBulkIn(struct rt_rtmp_adapter *pAd);
-
-void RTUSBInitRxDesc(struct rt_rtmp_adapter *pAd, struct rt_rx_context *pRxContext);
-
-void RTUSBBulkRxHandle(IN unsigned long data);
-
-/* */
-/* Function Prototype in rtusb_io.c */
-/* */
-int RTUSBMultiRead(struct rt_rtmp_adapter *pAd,
-			u16 Offset, u8 *pData, u16 length);
-
-int RTUSBMultiWrite(struct rt_rtmp_adapter *pAd,
-		    u16 Offset, const u8 *pData, u16 length);
-
-int RTUSBMultiWrite_OneByte(struct rt_rtmp_adapter *pAd,
-			    u16 Offset, const u8 *pData);
-
-int RTUSBReadBBPRegister(struct rt_rtmp_adapter *pAd,
-			      u8 Id, u8 *pValue);
-
-int RTUSBWriteBBPRegister(struct rt_rtmp_adapter *pAd,
-			       u8 Id, u8 Value);
-
-int RTUSBWriteRFRegister(struct rt_rtmp_adapter *pAd, u32 Value);
-
-int RTUSB_VendorRequest(struct rt_rtmp_adapter *pAd,
-			     u32 TransferFlags,
-			     u8 ReservedBits,
-			     u8 Request,
-			     u16 Value,
-			     u16 Index,
-			     void *TransferBuffer,
-			     u32 TransferBufferLength);
-
-int RTUSBReadEEPROM(struct rt_rtmp_adapter *pAd,
-			 u16 Offset, u8 *pData, u16 length);
-
-int RTUSBWriteEEPROM(struct rt_rtmp_adapter *pAd,
-			  u16 Offset, u8 *pData, u16 length);
-
-void RTUSBPutToSleep(struct rt_rtmp_adapter *pAd);
-
-int RTUSBWakeUp(struct rt_rtmp_adapter *pAd);
-
-void RTUSBInitializeCmdQ(struct rt_cmdq *cmdq);
-
-int RTUSBEnqueueCmdFromNdis(struct rt_rtmp_adapter *pAd,
-				    IN NDIS_OID Oid,
-				    IN BOOLEAN SetInformation,
-				    void *pInformationBuffer,
-				    u32 InformationBufferLength);
-
-int RTUSBEnqueueInternalCmd(struct rt_rtmp_adapter *pAd,
-				    IN NDIS_OID Oid,
-				    void *pInformationBuffer,
-				    u32 InformationBufferLength);
-
-void RTUSBDequeueCmd(struct rt_cmdq *cmdq, struct rt_cmdqelmt * * pcmdqelmt);
-
-int RTUSBCmdThread(IN void *Context);
-
-void RTUSBBssBeaconExit(struct rt_rtmp_adapter *pAd);
-
-void RTUSBBssBeaconStop(struct rt_rtmp_adapter *pAd);
-
-void RTUSBBssBeaconStart(struct rt_rtmp_adapter *pAd);
-
-void RTUSBBssBeaconInit(struct rt_rtmp_adapter *pAd);
-
-void RTUSBWatchDog(struct rt_rtmp_adapter *pAd);
-
-int RTUSBWriteMACRegister(struct rt_rtmp_adapter *pAd,
-			       u16 Offset, u32 Value);
-
-int RTUSBReadMACRegister(struct rt_rtmp_adapter *pAd,
-			      u16 Offset, u32 *pValue);
-
-int RTUSBSingleWrite(struct rt_rtmp_adapter *pAd,
-			  u16 Offset, u16 Value);
-
-int RTUSBFirmwareWrite(struct rt_rtmp_adapter *pAd,
-		       const u8 *pFwImage, unsigned long FwLen);
-
-int RTUSBVenderReset(struct rt_rtmp_adapter *pAd);
-
-int RTUSBSetHardWareRegister(struct rt_rtmp_adapter *pAdapter, void *pBuf);
-
-int RTUSBQueryHardWareRegister(struct rt_rtmp_adapter *pAdapter,
-				       void *pBuf);
-
-void CMDHandler(struct rt_rtmp_adapter *pAd);
-
-int RTUSBWriteHWMACAddress(struct rt_rtmp_adapter *pAdapter);
-
-void MacTableInitialize(struct rt_rtmp_adapter *pAd);
-
-void MlmeSetPsm(struct rt_rtmp_adapter *pAd, u16 psm);
-
-int RTMPWPAAddKeyProc(struct rt_rtmp_adapter *pAd, void *pBuf);
-
-void AsicRxAntEvalAction(struct rt_rtmp_adapter *pAd);
-
-void append_pkt(struct rt_rtmp_adapter *pAd,
-		u8 *pHeader802_3,
-		u32 HdrLen,
-		u8 *pData,
-		unsigned long DataSize, void **ppPacket);
-
-u32 deaggregate_AMSDU_announce(struct rt_rtmp_adapter *pAd,
-				void *pPacket,
-				u8 *pData, unsigned long DataSize);
-
-int RTMPCheckRxError(struct rt_rtmp_adapter *pAd,
-			     struct rt_header_802_11 *pHeader,
-			     struct rt_rxwi *pRxWI,
-			     IN PRT28XX_RXD_STRUC pRxINFO);
-
-void RTUSBMlmeHardTransmit(struct rt_rtmp_adapter *pAd, struct rt_mgmt *pMgmt);
-
-int MlmeThread(void *Context);
-
-/* */
-/* Function Prototype in rtusb_data.c */
-/* */
-int RTUSBFreeDescriptorRequest(struct rt_rtmp_adapter *pAd,
-				       u8 BulkOutPipeId,
-				       u32 NumberRequired);
-
-BOOLEAN RTUSBNeedQueueBackForAgg(struct rt_rtmp_adapter *pAd, u8 BulkOutPipeId);
-
-void RTMPWriteTxInfo(struct rt_rtmp_adapter *pAd,
-		     struct rt_txinfo *pTxInfo,
-		     u16 USBDMApktLen,
-		     IN BOOLEAN bWiv,
-		     u8 QueueSel, u8 NextValid, u8 TxBurst);
-
-/* */
-/* Function Prototype in cmm_data_usb.c */
-/* */
-u16 RtmpUSB_WriteSubTxResource(struct rt_rtmp_adapter *pAd,
-				  struct rt_tx_blk *pTxBlk,
-				  IN BOOLEAN bIsLast, u16 *FreeNumber);
-
-u16 RtmpUSB_WriteSingleTxResource(struct rt_rtmp_adapter *pAd,
-				     struct rt_tx_blk *pTxBlk,
-				     IN BOOLEAN bIsLast,
-				     u16 *FreeNumber);
-
-u16 RtmpUSB_WriteFragTxResource(struct rt_rtmp_adapter *pAd,
-				   struct rt_tx_blk *pTxBlk,
-				   u8 fragNum, u16 *FreeNumber);
-
-u16 RtmpUSB_WriteMultiTxResource(struct rt_rtmp_adapter *pAd,
-				    struct rt_tx_blk *pTxBlk,
-				    u8 frameNum, u16 *FreeNumber);
-
-void RtmpUSB_FinalWriteTxResource(struct rt_rtmp_adapter *pAd,
-				  struct rt_tx_blk *pTxBlk,
-				  u16 totalMPDUSize, u16 TxIdx);
-
-void RtmpUSBDataLastTxIdx(struct rt_rtmp_adapter *pAd,
-			  u8 QueIdx, u16 TxIdx);
-
-void RtmpUSBDataKickOut(struct rt_rtmp_adapter *pAd,
-			struct rt_tx_blk *pTxBlk, u8 QueIdx);
-
-int RtmpUSBMgmtKickOut(struct rt_rtmp_adapter *pAd,
-		       u8 QueIdx,
-		       void *pPacket,
-		       u8 *pSrcBufVA, u32 SrcBufLen);
-
-void RtmpUSBNullFrameKickOut(struct rt_rtmp_adapter *pAd,
-			     u8 QueIdx,
-			     u8 *pNullFrame, u32 frameLen);
-
-void RtmpUsbStaAsicForceWakeupTimeout(void *SystemSpecific1,
-				      void *FunctionContext,
-				      void *SystemSpecific2,
-				      void *SystemSpecific3);
-
-void RT28xxUsbStaAsicForceWakeup(struct rt_rtmp_adapter *pAd, IN BOOLEAN bFromTx);
-
-void RT28xxUsbStaAsicSleepThenAutoWakeup(struct rt_rtmp_adapter *pAd,
-					 u16 TbttNumToNextWakeUp);
-
-void RT28xxUsbMlmeRadioOn(struct rt_rtmp_adapter *pAd);
-
-void RT28xxUsbMlmeRadioOFF(struct rt_rtmp_adapter *pAd);
-#endif /* RTMP_MAC_USB // */
-
-void AsicTurnOffRFClk(struct rt_rtmp_adapter *pAd, u8 Channel);
-
-void AsicTurnOnRFClk(struct rt_rtmp_adapter *pAd, u8 Channel);
-
-#ifdef RTMP_TIMER_TASK_SUPPORT
-int RtmpTimerQThread(IN void *Context);
-
-struct rt_rtmp_timer_task_entry *RtmpTimerQInsert(struct rt_rtmp_adapter *pAd,
-					struct rt_ralink_timer *pTimer);
-
-BOOLEAN RtmpTimerQRemove(struct rt_rtmp_adapter *pAd,
-			 struct rt_ralink_timer *pTimer);
-
-void RtmpTimerQExit(struct rt_rtmp_adapter *pAd);
-
-void RtmpTimerQInit(struct rt_rtmp_adapter *pAd);
-#endif /* RTMP_TIMER_TASK_SUPPORT // */
-
-void AsicStaBbpTuning(struct rt_rtmp_adapter *pAd);
-
-BOOLEAN StaAddMacTableEntry(struct rt_rtmp_adapter *pAd,
-			    struct rt_mac_table_entry *pEntry,
-			    u8 MaxSupportedRateIn500Kbps,
-			    struct rt_ht_capability_ie *pHtCapability,
-			    u8 HtCapabilityLen,
-			    struct rt_add_ht_info_ie *pAddHtInfo,
-			    u8 AddHtInfoLen, u16 CapabilityInfo);
-
-BOOLEAN AUTH_ReqSend(struct rt_rtmp_adapter *pAd,
-		     struct rt_mlme_queue_elem *pElem,
-		     struct rt_ralink_timer *pAuthTimer,
-		     char *pSMName,
-		     u16 SeqNo,
-		     u8 *pNewElement, unsigned long ElementLen);
-
-void RTMP_IndicateMediaState(struct rt_rtmp_adapter *pAd);
-
-void ReSyncBeaconTime(struct rt_rtmp_adapter *pAd);
-
-void RTMPSetAGCInitValue(struct rt_rtmp_adapter *pAd, u8 BandWidth);
-
-int rt28xx_close(struct net_device *dev);
-int rt28xx_open(struct net_device *dev);
-
-#define VIRTUAL_IF_INC(__pAd) ((__pAd)->VirtualIfCnt++)
-#define VIRTUAL_IF_DEC(__pAd) ((__pAd)->VirtualIfCnt--)
-#define VIRTUAL_IF_NUM(__pAd) ((__pAd)->VirtualIfCnt)
-
-#ifdef LINUX
-__inline int VIRTUAL_IF_UP(struct rt_rtmp_adapter *pAd)
-{
-	if (VIRTUAL_IF_NUM(pAd) == 0) {
-		if (rt28xx_open(pAd->net_dev) != 0) {
-			DBGPRINT(RT_DEBUG_TRACE,
-				 ("rt28xx_open return fail!\n"));
-			return -1;
-		}
-	} else {
-	}
-	VIRTUAL_IF_INC(pAd);
-	return 0;
-}
-
-__inline void VIRTUAL_IF_DOWN(struct rt_rtmp_adapter *pAd)
-{
-	VIRTUAL_IF_DEC(pAd);
-	if (VIRTUAL_IF_NUM(pAd) == 0)
-		rt28xx_close(pAd->net_dev);
-	return;
-}
-#endif /* LINUX // */
-
-/*
-	OS Related funciton prototype definitions.
-	TODO: Maybe we need to move these function prototypes to other proper place.
-*/
-int RtmpOSWrielessEventSend(struct rt_rtmp_adapter *pAd,
-			    u32 eventType,
-			    int flags,
-			    u8 *pSrcMac,
-			    u8 *pData, u32 dataLen);
-
-int RtmpOSNetDevAddrSet(struct net_device *pNetDev, u8 *pMacAddr);
-
-int RtmpOSNetDevAttach(struct net_device *pNetDev,
-		       struct rt_rtmp_os_netdev_op_hook *pDevOpHook);
-
-void RtmpOSNetDevClose(struct net_device *pNetDev);
-
-void RtmpOSNetDevDetach(struct net_device *pNetDev);
-
-int RtmpOSNetDevAlloc(struct net_device **pNewNetDev, u32 privDataSize);
-
-void RtmpOSNetDevFree(struct net_device *pNetDev);
-
-struct net_device *RtmpOSNetDevGetByName(struct net_device *pNetDev, char *pDevName);
-
-void RtmpOSNetDeviceRefPut(struct net_device *pNetDev);
-
-struct net_device *RtmpOSNetDevCreate(struct rt_rtmp_adapter *pAd,
-			    int devType,
-			    int devNum,
-			    int privMemSize, char *pNamePrefix);
-
-/*
-	Task operation related function prototypes
-*/
-void RtmpOSTaskCustomize(struct rt_rtmp_os_task *pTask);
-
-int RtmpOSTaskNotifyToExit(struct rt_rtmp_os_task *pTask);
-
-int RtmpOSTaskKill(struct rt_rtmp_os_task *pTask);
-
-int RtmpOSTaskInit(struct rt_rtmp_os_task *pTask,
-			   char *pTaskName, void * pPriv);
-
-int RtmpOSTaskAttach(struct rt_rtmp_os_task *pTask,
-			     IN int (*fn) (void *), IN void *arg);
-
-/*
-	File operation related function prototypes
-*/
-struct file *RtmpOSFileOpen(IN char *pPath, IN int flag, IN int mode);
-
-int RtmpOSFileClose(struct file *osfd);
-
-void RtmpOSFileSeek(struct file *osfd, IN int offset);
-
-int RtmpOSFileRead(struct file *osfd, IN char *pDataPtr, IN int readLen);
-
-int RtmpOSFileWrite(struct file *osfd, IN char *pDataPtr, IN int writeLen);
-
-#endif /* __RTMP_H__ */
diff -druN linux-2.6.39-libre/drivers/staging/rt2860/rtmp_iface.h linux-3.0-rc7-libre/drivers/staging/rt2860/rtmp_iface.h
--- linux-2.6.39-libre/drivers/staging/rt2860/rtmp_iface.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rt2860/rtmp_iface.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,75 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, 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.             *
- *                                                                       *
- *************************************************************************
-
-    Module Name:
-	rt_iface.h
-
-    Abstract:
-
-    Revision History:
-    Who          When          What
-    ---------    ----------    ----------------------------------------------
- */
-
-#ifndef __RTMP_IFACE_H__
-#define __RTMP_IFACE_H__
-
-#ifdef RTMP_PCI_SUPPORT
-#include "iface/rtmp_pci.h"
-#endif /* RTMP_PCI_SUPPORT // */
-#ifdef RTMP_USB_SUPPORT
-#include "iface/rtmp_usb.h"
-#endif /* RTMP_USB_SUPPORT // */
-
-struct rt_inf_pci_config {
-	unsigned long CSRBaseAddress;	/* PCI MMIO Base Address, all access will use */
-	unsigned int irq_num;
-};
-
-struct rt_inf_usb_config {
-	u8 BulkInEpAddr;	/* bulk-in endpoint address */
-	u8 BulkOutEpAddr[6];	/* bulk-out endpoint address */
-};
-
-struct rt_inf_rbus_config {
-	unsigned long csr_addr;
-	unsigned int irq;
-};
-
-typedef enum _RTMP_INF_TYPE_ {
-	RTMP_DEV_INF_UNKNOWN = 0,
-	RTMP_DEV_INF_PCI = 1,
-	RTMP_DEV_INF_USB = 2,
-	RTMP_DEV_INF_RBUS = 4,
-} RTMP_INF_TYPE;
-
-typedef union _RTMP_INF_CONFIG_ {
-	struct rt_inf_pci_config pciConfig;
-	struct rt_inf_usb_config usbConfig;
-	struct rt_inf_rbus_config rbusConfig;
-} RTMP_INF_CONFIG;
-
-#endif /* __RTMP_IFACE_H__ // */
diff -druN linux-2.6.39-libre/drivers/staging/rt2860/rtmp_mcu.h linux-3.0-rc7-libre/drivers/staging/rt2860/rtmp_mcu.h
--- linux-2.6.39-libre/drivers/staging/rt2860/rtmp_mcu.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rt2860/rtmp_mcu.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,49 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, 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.             *
- *                                                                       *
- *************************************************************************
-
-	Module Name:
-	rtmp_mcu.h
-
-	Abstract:
-	Miniport header file for mcu related information
-
-	Revision History:
-	Who         When          What
-	--------    ----------    ----------------------------------------------
-*/
-
-#ifndef __RTMP_MCU_H__
-#define __RTMP_MCU_H__
-
-int RtmpAsicEraseFirmware(struct rt_rtmp_adapter *pAd);
-
-int RtmpAsicLoadFirmware(struct rt_rtmp_adapter *pAd);
-
-int RtmpAsicSendCommandToMcu(struct rt_rtmp_adapter *pAd,
-			     u8 Command,
-			     u8 Token, u8 Arg0, u8 Arg1);
-
-#endif /* __RTMP_MCU_H__ // */
diff -druN linux-2.6.39-libre/drivers/staging/rt2860/rtmp_os.h linux-3.0-rc7-libre/drivers/staging/rt2860/rtmp_os.h
--- linux-2.6.39-libre/drivers/staging/rt2860/rtmp_os.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rt2860/rtmp_os.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,90 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, 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.             *
- *                                                                       *
- *************************************************************************
-
-    Module Name:
-	rtmp_os.h
-
-    Abstract:
-
-    Revision History:
-    Who          When          What
-    ---------    ----------    ----------------------------------------------
- */
-
-#ifndef __RTMP_OS_H__
-#define __RTMP_OS_H__
-
-#ifdef LINUX
-#include "rt_linux.h"
-#endif /* LINUX // */
-
-/*
-	This data structure mainly strip some callback function defined in
-	"struct net_device" in kernel source "include/linux/netdevice.h".
-
-	The definition of this data structure may various depends on different
-	OS. Use it carefully.
-*/
-struct rt_rtmp_os_netdev_op_hook {
-	const struct net_device_ops *netdev_ops;
-	void *priv;
-	int priv_flags;
-	unsigned char devAddr[6];
-	unsigned char devName[16];
-	unsigned char needProtcted;
-};
-
-typedef enum _RTMP_TASK_STATUS_ {
-	RTMP_TASK_STAT_UNKNOWN = 0,
-	RTMP_TASK_STAT_INITED = 1,
-	RTMP_TASK_STAT_RUNNING = 2,
-	RTMP_TASK_STAT_STOPED = 4,
-} RTMP_TASK_STATUS;
-#define RTMP_TASK_CAN_DO_INSERT		(RTMP_TASK_STAT_INITED |RTMP_TASK_STAT_RUNNING)
-
-#define RTMP_OS_TASK_NAME_LEN	16
-struct rt_rtmp_os_task {
-	char taskName[RTMP_OS_TASK_NAME_LEN];
-	void *priv;
-	/*unsigned long         taskFlags; */
-	RTMP_TASK_STATUS taskStatus;
-#ifndef KTHREAD_SUPPORT
-	struct semaphore taskSema;
-	struct pid *taskPID;
-	struct completion taskComplete;
-#endif
-	unsigned char task_killed;
-#ifdef KTHREAD_SUPPORT
-	struct task_struct *kthread_task;
-	wait_queue_head_t kthread_q;
-	BOOLEAN kthread_running;
-#endif
-};
-
-int RtmpOSIRQRequest(struct net_device *pNetDev);
-int RtmpOSIRQRelease(struct net_device *pNetDev);
-
-#endif /* __RMTP_OS_H__ // */
diff -druN linux-2.6.39-libre/drivers/staging/rt2860/rtmp_timer.h linux-3.0-rc7-libre/drivers/staging/rt2860/rtmp_timer.h
--- linux-2.6.39-libre/drivers/staging/rt2860/rtmp_timer.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rt2860/rtmp_timer.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,148 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, 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.             *
- *                                                                       *
- *************************************************************************
-
-    Module Name:
-	rtmp_timer.h
-
-    Abstract:
-	Ralink Wireless Driver timer related data structures and declarations 
-
-    Revision History:
-	Who          		When                 What
-	--------    ----------      ----------------------------------------------
-	Name          		Date                 Modification logs
-	Shiang Tu    		Aug-28-2008 	     init version
-	Justin P. Mattock	11/07/2010	     Fix a typo
-
-*/
-
-#ifndef __RTMP_TIMER_H__
-#define  __RTMP_TIMER_H__
-
-#include "rtmp_os.h"
-
-#define DECLARE_TIMER_FUNCTION(_func)			\
-	void rtmp_timer_##_func(unsigned long data)
-
-#define GET_TIMER_FUNCTION(_func)				\
-	rtmp_timer_##_func
-
-/* ----------------- Timer Related MARCO ---------------*/
-/* In some os or chipset, we have a lot of timer functions and will read/write register, */
-/* it's not allowed in Linux USB sub-system to do it ( because of sleep issue when */
-/* submit to ctrl pipe). So we need a wrapper function to take care it. */
-
-#ifdef RTMP_TIMER_TASK_SUPPORT
-typedef void(*RTMP_TIMER_TASK_HANDLE) (void *SystemSpecific1,
-				       void *FunctionContext,
-				       void *SystemSpecific2,
-				       void *SystemSpecific3);
-#endif /* RTMP_TIMER_TASK_SUPPORT // */
-
-struct rt_ralink_timer {
-	struct timer_list TimerObj;	/* Ndis Timer object */
-	BOOLEAN Valid;		/* Set to True when call RTMPInitTimer */
-	BOOLEAN State;		/* True if timer cancelled */
-	BOOLEAN PeriodicType;	/* True if timer is periodic timer */
-	BOOLEAN Repeat;		/* True if periodic timer */
-	unsigned long TimerValue;	/* Timer value in milliseconds */
-	unsigned long cookie;		/* os specific object */
-#ifdef RTMP_TIMER_TASK_SUPPORT
-	RTMP_TIMER_TASK_HANDLE handle;
-	void *pAd;
-#endif				/* RTMP_TIMER_TASK_SUPPORT // */
-};
-
-#ifdef RTMP_TIMER_TASK_SUPPORT
-struct rt_rtmp_timer_task_entry {
-	struct rt_ralink_timer *pRaTimer;
-	struct rt_rtmp_timer_task_entry *pNext;
-};
-
-#define TIMER_QUEUE_SIZE_MAX	128
-struct rt_rtmp_timer_task_queue {
-	unsigned int status;
-	unsigned char *pTimerQPoll;
-	struct rt_rtmp_timer_task_entry *pQPollFreeList;
-	struct rt_rtmp_timer_task_entry *pQHead;
-	struct rt_rtmp_timer_task_entry *pQTail;
-};
-
-#define BUILD_TIMER_FUNCTION(_func)										\
-void rtmp_timer_##_func(unsigned long data)										\
-{																			\
-	struct rt_ralink_timer *_pTimer = (struct rt_ralink_timer *)data;				\
-	struct rt_rtmp_timer_task_entry *_pQNode;										\
-	struct rt_rtmp_adapter *_pAd;											\
-																			\
-	_pTimer->handle = _func;													\
-	_pAd = (struct rt_rtmp_adapter *)_pTimer->pAd;										\
-	_pQNode = RtmpTimerQInsert(_pAd, _pTimer);								\
-	if ((_pQNode == NULL) && (_pAd->TimerQ.status & RTMP_TASK_CAN_DO_INSERT))	\
-		RTMP_OS_Add_Timer(&_pTimer->TimerObj, OS_HZ);							\
-}
-#else
-#define BUILD_TIMER_FUNCTION(_func)										\
-void rtmp_timer_##_func(unsigned long data)										\
-{																			\
-	struct rt_ralink_timer *pTimer = (struct rt_ralink_timer *)data;				\
-																			\
-	_func(NULL, (void *)pTimer->cookie, NULL, pTimer);							\
-	if (pTimer->Repeat)														\
-		RTMP_OS_Add_Timer(&pTimer->TimerObj, pTimer->TimerValue);			\
-}
-#endif /* RTMP_TIMER_TASK_SUPPORT // */
-
-DECLARE_TIMER_FUNCTION(MlmePeriodicExec);
-DECLARE_TIMER_FUNCTION(MlmeRssiReportExec);
-DECLARE_TIMER_FUNCTION(AsicRxAntEvalTimeout);
-DECLARE_TIMER_FUNCTION(APSDPeriodicExec);
-DECLARE_TIMER_FUNCTION(AsicRfTuningExec);
-#ifdef RTMP_MAC_USB
-DECLARE_TIMER_FUNCTION(BeaconUpdateExec);
-#endif /* RTMP_MAC_USB // */
-
-DECLARE_TIMER_FUNCTION(BeaconTimeout);
-DECLARE_TIMER_FUNCTION(ScanTimeout);
-DECLARE_TIMER_FUNCTION(AuthTimeout);
-DECLARE_TIMER_FUNCTION(AssocTimeout);
-DECLARE_TIMER_FUNCTION(ReassocTimeout);
-DECLARE_TIMER_FUNCTION(DisassocTimeout);
-DECLARE_TIMER_FUNCTION(LinkDownExec);
-DECLARE_TIMER_FUNCTION(StaQuickResponeForRateUpExec);
-DECLARE_TIMER_FUNCTION(WpaDisassocApAndBlockAssoc);
-DECLARE_TIMER_FUNCTION(PsPollWakeExec);
-DECLARE_TIMER_FUNCTION(RadioOnExec);
-
-#ifdef RTMP_MAC_USB
-DECLARE_TIMER_FUNCTION(RtmpUsbStaAsicForceWakeupTimeout);
-#endif /* RTMP_MAC_USB // */
-
-#if defined(AP_LED) || defined(STA_LED)
-DECLARE_TIMER_FUNCTION(LedCtrlMain);
-#endif
-
-#endif /* __RTMP_TIMER_H__ // */
diff -druN linux-2.6.39-libre/drivers/staging/rt2860/rtmp_type.h linux-3.0-rc7-libre/drivers/staging/rt2860/rtmp_type.h
--- linux-2.6.39-libre/drivers/staging/rt2860/rtmp_type.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rt2860/rtmp_type.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,89 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, 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.             *
- *                                                                       *
- *************************************************************************
-
-    Module Name:
-    rtmp_type.h
-
-    Abstract:
-
-    Revision History:
-    Who         When            What
-    --------    ----------      ----------------------------------------------
-    Name        Date            Modification logs
-    Paul Lin    1-2-2004
-*/
-#ifndef __RTMP_TYPE_H__
-#define __RTMP_TYPE_H__
-
-#include <linux/types.h>
-
-#define PACKED  __attribute__ ((packed))
-
-typedef unsigned char BOOLEAN;
-
-typedef union _LARGE_INTEGER {
-	struct {
-		u32 LowPart;
-		int HighPart;
-	} u;
-	long long QuadPart;
-} LARGE_INTEGER;
-
-/* */
-/* Register set pair for initialzation register set definition */
-/* */
-struct rt_rtmp_reg_pair {
-	unsigned long Register;
-	unsigned long Value;
-};
-
-struct rt_reg_pair {
-	u8 Register;
-	u8 Value;
-};
-
-/* */
-/* Register set pair for initialzation register set definition */
-/* */
-struct rt_rtmp_rf_regs {
-	u8 Channel;
-	unsigned long R1;
-	unsigned long R2;
-	unsigned long R3;
-	unsigned long R4;
-};
-
-struct rt_frequency_item {
-	u8 Channel;
-	u8 N;
-	u8 R;
-	u8 K;
-};
-
-#define STATUS_SUCCESS				0x00
-#define STATUS_UNSUCCESSFUL		0x01
-
-#endif /* __RTMP_TYPE_H__ // */
diff -druN linux-2.6.39-libre/drivers/staging/rt2860/rt_pci_rbus.c linux-3.0-rc7-libre/drivers/staging/rt2860/rt_pci_rbus.c
--- linux-2.6.39-libre/drivers/staging/rt2860/rt_pci_rbus.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rt2860/rt_pci_rbus.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,837 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, 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.             *
- *                                                                       *
- *************************************************************************
-
-    Module Name:
-    rt_pci_rbus.c
-
-    Abstract:
-    Create and register network interface.
-
-    Revision History:
-    Who         	When            What
-    Justin P. Mattock	11/07/2010	Fix a typo
-    --------    ----------      ----------------------------------------------
-*/
-
-#include "rt_config.h"
-#include <linux/pci.h>
-
-IRQ_HANDLE_TYPE rt2860_interrupt(int irq, void *dev_instance);
-
-static void rx_done_tasklet(unsigned long data);
-static void mgmt_dma_done_tasklet(unsigned long data);
-static void ac0_dma_done_tasklet(unsigned long data);
-static void ac1_dma_done_tasklet(unsigned long data);
-static void ac2_dma_done_tasklet(unsigned long data);
-static void ac3_dma_done_tasklet(unsigned long data);
-static void fifo_statistic_full_tasklet(unsigned long data);
-
-/*---------------------------------------------------------------------*/
-/* Symbol & Macro Definitions                                          */
-/*---------------------------------------------------------------------*/
-#define RT2860_INT_RX_DLY				(1<<0)	/* bit 0 */
-#define RT2860_INT_TX_DLY				(1<<1)	/* bit 1 */
-#define RT2860_INT_RX_DONE				(1<<2)	/* bit 2 */
-#define RT2860_INT_AC0_DMA_DONE			(1<<3)	/* bit 3 */
-#define RT2860_INT_AC1_DMA_DONE			(1<<4)	/* bit 4 */
-#define RT2860_INT_AC2_DMA_DONE			(1<<5)	/* bit 5 */
-#define RT2860_INT_AC3_DMA_DONE			(1<<6)	/* bit 6 */
-#define RT2860_INT_HCCA_DMA_DONE		(1<<7)	/* bit 7 */
-#define RT2860_INT_MGMT_DONE			(1<<8)	/* bit 8 */
-
-#define INT_RX			RT2860_INT_RX_DONE
-
-#define INT_AC0_DLY		(RT2860_INT_AC0_DMA_DONE)	/*| RT2860_INT_TX_DLY) */
-#define INT_AC1_DLY		(RT2860_INT_AC1_DMA_DONE)	/*| RT2860_INT_TX_DLY) */
-#define INT_AC2_DLY		(RT2860_INT_AC2_DMA_DONE)	/*| RT2860_INT_TX_DLY) */
-#define INT_AC3_DLY		(RT2860_INT_AC3_DMA_DONE)	/*| RT2860_INT_TX_DLY) */
-#define INT_HCCA_DLY	(RT2860_INT_HCCA_DMA_DONE)	/*| RT2860_INT_TX_DLY) */
-#define INT_MGMT_DLY	RT2860_INT_MGMT_DONE
-
-/***************************************************************************
-  *
-  *	Interface-depended memory allocation/Free related procedures.
-  *		Mainly for Hardware TxDesc/RxDesc/MgmtDesc, DMA Memory for TxData/RxData, etc.,
-  *
-  **************************************************************************/
-/* Function for TxDesc Memory allocation. */
-void RTMP_AllocateTxDescMemory(struct rt_rtmp_adapter *pAd,
-			       u32 Index,
-			       unsigned long Length,
-			       IN BOOLEAN Cached,
-			       void **VirtualAddress,
-			       dma_addr_t *PhysicalAddress)
-{
-	struct os_cookie *pObj = (struct os_cookie *)pAd->OS_Cookie;
-
-	*VirtualAddress =
-	    (void *)pci_alloc_consistent(pObj->pci_dev, sizeof(char) * Length,
-					 PhysicalAddress);
-
-}
-
-/* Function for MgmtDesc Memory allocation. */
-void RTMP_AllocateMgmtDescMemory(struct rt_rtmp_adapter *pAd,
-				 unsigned long Length,
-				 IN BOOLEAN Cached,
-				 void **VirtualAddress,
-				 dma_addr_t *PhysicalAddress)
-{
-	struct os_cookie *pObj = (struct os_cookie *)pAd->OS_Cookie;
-
-	*VirtualAddress =
-	    (void *)pci_alloc_consistent(pObj->pci_dev, sizeof(char) * Length,
-					 PhysicalAddress);
-
-}
-
-/* Function for RxDesc Memory allocation. */
-void RTMP_AllocateRxDescMemory(struct rt_rtmp_adapter *pAd,
-			       unsigned long Length,
-			       IN BOOLEAN Cached,
-			       void **VirtualAddress,
-			       dma_addr_t *PhysicalAddress)
-{
-	struct os_cookie *pObj = (struct os_cookie *)pAd->OS_Cookie;
-
-	*VirtualAddress =
-	    (void *)pci_alloc_consistent(pObj->pci_dev, sizeof(char) * Length,
-					 PhysicalAddress);
-
-}
-
-/* Function for free allocated Desc Memory. */
-void RTMP_FreeDescMemory(struct rt_rtmp_adapter *pAd,
-			 unsigned long Length,
-			 void *VirtualAddress,
-			 dma_addr_t PhysicalAddress)
-{
-	struct os_cookie *pObj = (struct os_cookie *)pAd->OS_Cookie;
-
-	pci_free_consistent(pObj->pci_dev, Length, VirtualAddress,
-			    PhysicalAddress);
-}
-
-/* Function for TxData DMA Memory allocation. */
-void RTMP_AllocateFirstTxBuffer(struct rt_rtmp_adapter *pAd,
-				u32 Index,
-				unsigned long Length,
-				IN BOOLEAN Cached,
-				void **VirtualAddress,
-				dma_addr_t *PhysicalAddress)
-{
-	struct os_cookie *pObj = (struct os_cookie *)pAd->OS_Cookie;
-
-	*VirtualAddress =
-	    (void *)pci_alloc_consistent(pObj->pci_dev, sizeof(char) * Length,
-					 PhysicalAddress);
-}
-
-void RTMP_FreeFirstTxBuffer(struct rt_rtmp_adapter *pAd,
-			    unsigned long Length,
-			    IN BOOLEAN Cached,
-			    void *VirtualAddress,
-			    dma_addr_t PhysicalAddress)
-{
-	struct os_cookie *pObj = (struct os_cookie *)pAd->OS_Cookie;
-
-	pci_free_consistent(pObj->pci_dev, Length, VirtualAddress,
-			    PhysicalAddress);
-}
-
-/*
- * FUNCTION: Allocate a common buffer for DMA
- * ARGUMENTS:
- *     AdapterHandle:  AdapterHandle
- *     Length:  Number of bytes to allocate
- *     Cached:  Whether or not the memory can be cached
- *     VirtualAddress:  Pointer to memory is returned here
- *     PhysicalAddress:  Physical address corresponding to virtual address
- */
-void RTMP_AllocateSharedMemory(struct rt_rtmp_adapter *pAd,
-			       unsigned long Length,
-			       IN BOOLEAN Cached,
-			       void **VirtualAddress,
-			       dma_addr_t *PhysicalAddress)
-{
-	struct os_cookie *pObj = (struct os_cookie *)pAd->OS_Cookie;
-
-	*VirtualAddress =
-	    (void *)pci_alloc_consistent(pObj->pci_dev, sizeof(char) * Length,
-					 PhysicalAddress);
-}
-
-/*
- * FUNCTION: Allocate a packet buffer for DMA
- * ARGUMENTS:
- *     AdapterHandle:  AdapterHandle
- *     Length:  Number of bytes to allocate
- *     Cached:  Whether or not the memory can be cached
- *     VirtualAddress:  Pointer to memory is returned here
- *     PhysicalAddress:  Physical address corresponding to virtual address
- * Notes:
- *     Cached is ignored: always cached memory
- */
-void *RTMP_AllocateRxPacketBuffer(struct rt_rtmp_adapter *pAd,
-					 unsigned long Length,
-					 IN BOOLEAN Cached,
-					 void **VirtualAddress,
-					 OUT dma_addr_t *
-					 PhysicalAddress)
-{
-	struct sk_buff *pkt;
-
-	pkt = dev_alloc_skb(Length);
-
-	if (pkt == NULL) {
-		DBGPRINT(RT_DEBUG_ERROR,
-			 ("can't allocate rx %ld size packet\n", Length));
-	}
-
-	if (pkt) {
-		RTMP_SET_PACKET_SOURCE(OSPKT_TO_RTPKT(pkt), PKTSRC_NDIS);
-		*VirtualAddress = (void *)pkt->data;
-		*PhysicalAddress =
-		    PCI_MAP_SINGLE(pAd, *VirtualAddress, Length, -1,
-				   PCI_DMA_FROMDEVICE);
-	} else {
-		*VirtualAddress = (void *)NULL;
-		*PhysicalAddress = (dma_addr_t)NULL;
-	}
-
-	return (void *)pkt;
-}
-
-void Invalid_Remaining_Packet(struct rt_rtmp_adapter *pAd, unsigned long VirtualAddress)
-{
-	dma_addr_t PhysicalAddress;
-
-	PhysicalAddress =
-	    PCI_MAP_SINGLE(pAd, (void *)(VirtualAddress + 1600),
-			   RX_BUFFER_NORMSIZE - 1600, -1, PCI_DMA_FROMDEVICE);
-}
-
-int RtmpNetTaskInit(struct rt_rtmp_adapter *pAd)
-{
-	struct os_cookie *pObj;
-
-	pObj = (struct os_cookie *)pAd->OS_Cookie;
-
-	tasklet_init(&pObj->rx_done_task, rx_done_tasklet, (unsigned long)pAd);
-	tasklet_init(&pObj->mgmt_dma_done_task, mgmt_dma_done_tasklet,
-		     (unsigned long)pAd);
-	tasklet_init(&pObj->ac0_dma_done_task, ac0_dma_done_tasklet,
-		     (unsigned long)pAd);
-	tasklet_init(&pObj->ac1_dma_done_task, ac1_dma_done_tasklet,
-		     (unsigned long)pAd);
-	tasklet_init(&pObj->ac2_dma_done_task, ac2_dma_done_tasklet,
-		     (unsigned long)pAd);
-	tasklet_init(&pObj->ac3_dma_done_task, ac3_dma_done_tasklet,
-		     (unsigned long)pAd);
-	tasklet_init(&pObj->tbtt_task, tbtt_tasklet, (unsigned long)pAd);
-	tasklet_init(&pObj->fifo_statistic_full_task,
-		     fifo_statistic_full_tasklet, (unsigned long)pAd);
-
-	return NDIS_STATUS_SUCCESS;
-}
-
-void RtmpNetTaskExit(struct rt_rtmp_adapter *pAd)
-{
-	struct os_cookie *pObj;
-
-	pObj = (struct os_cookie *)pAd->OS_Cookie;
-
-	tasklet_kill(&pObj->rx_done_task);
-	tasklet_kill(&pObj->mgmt_dma_done_task);
-	tasklet_kill(&pObj->ac0_dma_done_task);
-	tasklet_kill(&pObj->ac1_dma_done_task);
-	tasklet_kill(&pObj->ac2_dma_done_task);
-	tasklet_kill(&pObj->ac3_dma_done_task);
-	tasklet_kill(&pObj->tbtt_task);
-	tasklet_kill(&pObj->fifo_statistic_full_task);
-}
-
-int RtmpMgmtTaskInit(struct rt_rtmp_adapter *pAd)
-{
-
-	return NDIS_STATUS_SUCCESS;
-}
-
-/*
-========================================================================
-Routine Description:
-    Close kernel threads.
-
-Arguments:
-	*pAd				the raxx interface data pointer
-
-Return Value:
-    NONE
-
-Note:
-========================================================================
-*/
-void RtmpMgmtTaskExit(struct rt_rtmp_adapter *pAd)
-{
-
-	return;
-}
-
-static inline void rt2860_int_enable(struct rt_rtmp_adapter *pAd, unsigned int mode)
-{
-	u32 regValue;
-
-	pAd->int_disable_mask &= ~(mode);
-	regValue = pAd->int_enable_reg & ~(pAd->int_disable_mask);
-	/*if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE)) */
-	{
-		RTMP_IO_WRITE32(pAd, INT_MASK_CSR, regValue);	/* 1:enable */
-	}
-	/*else */
-	/*      DBGPRINT(RT_DEBUG_TRACE, ("fOP_STATUS_DOZE !\n")); */
-
-	if (regValue != 0)
-		RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_ACTIVE);
-}
-
-static inline void rt2860_int_disable(struct rt_rtmp_adapter *pAd, unsigned int mode)
-{
-	u32 regValue;
-
-	pAd->int_disable_mask |= mode;
-	regValue = pAd->int_enable_reg & ~(pAd->int_disable_mask);
-	RTMP_IO_WRITE32(pAd, INT_MASK_CSR, regValue);	/* 0: disable */
-
-	if (regValue == 0) {
-		RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_ACTIVE);
-	}
-}
-
-/***************************************************************************
-  *
-  *	tasklet related procedures.
-  *
-  **************************************************************************/
-static void mgmt_dma_done_tasklet(unsigned long data)
-{
-	unsigned long flags;
-	struct rt_rtmp_adapter *pAd = (struct rt_rtmp_adapter *)data;
-	INT_SOURCE_CSR_STRUC IntSource;
-	struct os_cookie *pObj;
-
-	/* Do nothing if the driver is starting halt state. */
-	/* This might happen when timer already been fired before cancel timer with mlmehalt */
-	if (RTMP_TEST_FLAG
-	    (pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST))
-		return;
-
-	pObj = (struct os_cookie *)pAd->OS_Cookie;
-
-/*      printk("mgmt_dma_done_process\n"); */
-	IntSource.word = 0;
-	IntSource.field.MgmtDmaDone = 1;
-	pAd->int_pending &= ~INT_MGMT_DLY;
-
-	RTMPHandleMgmtRingDmaDoneInterrupt(pAd);
-
-	/* if you use RTMP_SEM_LOCK, sometimes kernel will hang up, without any */
-	/* bug report output */
-	RTMP_INT_LOCK(&pAd->irq_lock, flags);
-	/*
-	 * double check to avoid lose of interrupts
-	 */
-	if (pAd->int_pending & INT_MGMT_DLY) {
-		tasklet_hi_schedule(&pObj->mgmt_dma_done_task);
-		RTMP_INT_UNLOCK(&pAd->irq_lock, flags);
-		return;
-	}
-
-	/* enable TxDataInt again */
-	rt2860_int_enable(pAd, INT_MGMT_DLY);
-	RTMP_INT_UNLOCK(&pAd->irq_lock, flags);
-}
-
-static void rx_done_tasklet(unsigned long data)
-{
-	unsigned long flags;
-	struct rt_rtmp_adapter *pAd = (struct rt_rtmp_adapter *)data;
-	BOOLEAN bReschedule = 0;
-	struct os_cookie *pObj;
-
-	/* Do nothing if the driver is starting halt state. */
-	/* This might happen when timer already been fired before cancel timer with mlmehalt */
-	if (RTMP_TEST_FLAG
-	    (pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST))
-		return;
-
-	pObj = (struct os_cookie *)pAd->OS_Cookie;
-
-	pAd->int_pending &= ~(INT_RX);
-	bReschedule = STARxDoneInterruptHandle(pAd, 0);
-
-	RTMP_INT_LOCK(&pAd->irq_lock, flags);
-	/*
-	 * double check to avoid rotting packet
-	 */
-	if (pAd->int_pending & INT_RX || bReschedule) {
-		tasklet_hi_schedule(&pObj->rx_done_task);
-		RTMP_INT_UNLOCK(&pAd->irq_lock, flags);
-		return;
-	}
-
-	/* enable Rxint again */
-	rt2860_int_enable(pAd, INT_RX);
-	RTMP_INT_UNLOCK(&pAd->irq_lock, flags);
-
-}
-
-void fifo_statistic_full_tasklet(unsigned long data)
-{
-	unsigned long flags;
-	struct rt_rtmp_adapter *pAd = (struct rt_rtmp_adapter *)data;
-	struct os_cookie *pObj;
-
-	/* Do nothing if the driver is starting halt state. */
-	/* This might happen when timer already been fired before cancel timer with mlmehalt */
-	if (RTMP_TEST_FLAG
-	    (pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST))
-		return;
-
-	pObj = (struct os_cookie *)pAd->OS_Cookie;
-
-	pAd->int_pending &= ~(FifoStaFullInt);
-	NICUpdateFifoStaCounters(pAd);
-
-	RTMP_INT_LOCK(&pAd->irq_lock, flags);
-	/*
-	 * double check to avoid rotting packet
-	 */
-	if (pAd->int_pending & FifoStaFullInt) {
-		tasklet_hi_schedule(&pObj->fifo_statistic_full_task);
-		RTMP_INT_UNLOCK(&pAd->irq_lock, flags);
-		return;
-	}
-
-	/* enable Rxint again */
-
-	rt2860_int_enable(pAd, FifoStaFullInt);
-	RTMP_INT_UNLOCK(&pAd->irq_lock, flags);
-
-}
-
-static void ac3_dma_done_tasklet(unsigned long data)
-{
-	unsigned long flags;
-	struct rt_rtmp_adapter *pAd = (struct rt_rtmp_adapter *)data;
-	INT_SOURCE_CSR_STRUC IntSource;
-	struct os_cookie *pObj;
-	BOOLEAN bReschedule = 0;
-
-	/* Do nothing if the driver is starting halt state. */
-	/* This might happen when timer already been fired before cancel timer with mlmehalt */
-	if (RTMP_TEST_FLAG
-	    (pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST))
-		return;
-
-	pObj = (struct os_cookie *)pAd->OS_Cookie;
-
-/*      printk("ac0_dma_done_process\n"); */
-	IntSource.word = 0;
-	IntSource.field.Ac3DmaDone = 1;
-	pAd->int_pending &= ~INT_AC3_DLY;
-
-	bReschedule = RTMPHandleTxRingDmaDoneInterrupt(pAd, IntSource);
-
-	RTMP_INT_LOCK(&pAd->irq_lock, flags);
-	/*
-	 * double check to avoid lose of interrupts
-	 */
-	if ((pAd->int_pending & INT_AC3_DLY) || bReschedule) {
-		tasklet_hi_schedule(&pObj->ac3_dma_done_task);
-		RTMP_INT_UNLOCK(&pAd->irq_lock, flags);
-		return;
-	}
-
-	/* enable TxDataInt again */
-	rt2860_int_enable(pAd, INT_AC3_DLY);
-	RTMP_INT_UNLOCK(&pAd->irq_lock, flags);
-}
-
-static void ac2_dma_done_tasklet(unsigned long data)
-{
-	unsigned long flags;
-	struct rt_rtmp_adapter *pAd = (struct rt_rtmp_adapter *)data;
-	INT_SOURCE_CSR_STRUC IntSource;
-	struct os_cookie *pObj;
-	BOOLEAN bReschedule = 0;
-
-	/* Do nothing if the driver is starting halt state. */
-	/* This might happen when timer already been fired before cancel timer with mlmehalt */
-	if (RTMP_TEST_FLAG
-	    (pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST))
-		return;
-
-	pObj = (struct os_cookie *)pAd->OS_Cookie;
-
-	IntSource.word = 0;
-	IntSource.field.Ac2DmaDone = 1;
-	pAd->int_pending &= ~INT_AC2_DLY;
-
-	bReschedule = RTMPHandleTxRingDmaDoneInterrupt(pAd, IntSource);
-
-	RTMP_INT_LOCK(&pAd->irq_lock, flags);
-
-	/*
-	 * double check to avoid lose of interrupts
-	 */
-	if ((pAd->int_pending & INT_AC2_DLY) || bReschedule) {
-		tasklet_hi_schedule(&pObj->ac2_dma_done_task);
-		RTMP_INT_UNLOCK(&pAd->irq_lock, flags);
-		return;
-	}
-
-	/* enable TxDataInt again */
-	rt2860_int_enable(pAd, INT_AC2_DLY);
-	RTMP_INT_UNLOCK(&pAd->irq_lock, flags);
-}
-
-static void ac1_dma_done_tasklet(unsigned long data)
-{
-	unsigned long flags;
-	struct rt_rtmp_adapter *pAd = (struct rt_rtmp_adapter *)data;
-	INT_SOURCE_CSR_STRUC IntSource;
-	struct os_cookie *pObj;
-	BOOLEAN bReschedule = 0;
-
-	/* Do nothing if the driver is starting halt state. */
-	/* This might happen when timer already been fired before cancel timer with mlmehalt */
-	if (RTMP_TEST_FLAG
-	    (pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST))
-		return;
-
-	pObj = (struct os_cookie *)pAd->OS_Cookie;
-
-/*      printk("ac0_dma_done_process\n"); */
-	IntSource.word = 0;
-	IntSource.field.Ac1DmaDone = 1;
-	pAd->int_pending &= ~INT_AC1_DLY;
-
-	bReschedule = RTMPHandleTxRingDmaDoneInterrupt(pAd, IntSource);
-
-	RTMP_INT_LOCK(&pAd->irq_lock, flags);
-	/*
-	 * double check to avoid lose of interrupts
-	 */
-	if ((pAd->int_pending & INT_AC1_DLY) || bReschedule) {
-		tasklet_hi_schedule(&pObj->ac1_dma_done_task);
-		RTMP_INT_UNLOCK(&pAd->irq_lock, flags);
-		return;
-	}
-
-	/* enable TxDataInt again */
-	rt2860_int_enable(pAd, INT_AC1_DLY);
-	RTMP_INT_UNLOCK(&pAd->irq_lock, flags);
-}
-
-static void ac0_dma_done_tasklet(unsigned long data)
-{
-	unsigned long flags;
-	struct rt_rtmp_adapter *pAd = (struct rt_rtmp_adapter *)data;
-	INT_SOURCE_CSR_STRUC IntSource;
-	struct os_cookie *pObj;
-	BOOLEAN bReschedule = 0;
-
-	/* Do nothing if the driver is starting halt state. */
-	/* This might happen when timer already been fired before cancel timer with mlmehalt */
-	if (RTMP_TEST_FLAG
-	    (pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST))
-		return;
-
-	pObj = (struct os_cookie *)pAd->OS_Cookie;
-
-/*      printk("ac0_dma_done_process\n"); */
-	IntSource.word = 0;
-	IntSource.field.Ac0DmaDone = 1;
-	pAd->int_pending &= ~INT_AC0_DLY;
-
-/*      RTMPHandleMgmtRingDmaDoneInterrupt(pAd); */
-	bReschedule = RTMPHandleTxRingDmaDoneInterrupt(pAd, IntSource);
-
-	RTMP_INT_LOCK(&pAd->irq_lock, flags);
-	/*
-	 * double check to avoid lose of interrupts
-	 */
-	if ((pAd->int_pending & INT_AC0_DLY) || bReschedule) {
-		tasklet_hi_schedule(&pObj->ac0_dma_done_task);
-		RTMP_INT_UNLOCK(&pAd->irq_lock, flags);
-		return;
-	}
-
-	/* enable TxDataInt again */
-	rt2860_int_enable(pAd, INT_AC0_DLY);
-	RTMP_INT_UNLOCK(&pAd->irq_lock, flags);
-}
-
-/***************************************************************************
-  *
-  *	interrupt handler related procedures.
-  *
-  **************************************************************************/
-int print_int_count;
-
-IRQ_HANDLE_TYPE rt2860_interrupt(int irq, void *dev_instance)
-{
-	struct net_device *net_dev = (struct net_device *)dev_instance;
-	struct rt_rtmp_adapter *pAd = NULL;
-	INT_SOURCE_CSR_STRUC IntSource;
-	struct os_cookie *pObj;
-
-	GET_PAD_FROM_NET_DEV(pAd, net_dev);
-
-	pObj = (struct os_cookie *)pAd->OS_Cookie;
-
-	/* Note 03312008: we can not return here before
-	   RTMP_IO_READ32(pAd, INT_SOURCE_CSR, &IntSource.word);
-	   RTMP_IO_WRITE32(pAd, INT_SOURCE_CSR, IntSource.word);
-	   Or kernel will panic after ifconfig ra0 down sometimes */
-
-	/* */
-	/* Initial the Interrupt source. */
-	/* */
-	IntSource.word = 0x00000000L;
-/*      McuIntSource.word = 0x00000000L; */
-
-	/* */
-	/* Get the interrupt sources & saved to local variable */
-	/* */
-	/*RTMP_IO_READ32(pAd, where, &McuIntSource.word); */
-	/*RTMP_IO_WRITE32(pAd, , McuIntSource.word); */
-
-	/* */
-	/* Flag fOP_STATUS_DOZE On, means ASIC put to sleep, elase means ASICK WakeUp */
-	/* And at the same time, clock maybe turned off that say there is no DMA service. */
-	/* when ASIC get to sleep. */
-	/* To prevent system hang on power saving. */
-	/* We need to check it before handle the INT_SOURCE_CSR, ASIC must be wake up. */
-	/* */
-	/* RT2661 => when ASIC is sleeping, MAC register cannot be read and written. */
-	/* RT2860 => when ASIC is sleeping, MAC register can be read and written. */
-/*      if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE)) */
-	{
-		RTMP_IO_READ32(pAd, INT_SOURCE_CSR, &IntSource.word);
-		RTMP_IO_WRITE32(pAd, INT_SOURCE_CSR, IntSource.word);	/* write 1 to clear */
-	}
-/*      else */
-/*              DBGPRINT(RT_DEBUG_TRACE, (">>>fOP_STATUS_DOZE<<<\n")); */
-
-/*      RTMP_IO_READ32(pAd, INT_SOURCE_CSR, &IsrAfterClear); */
-/*      RTMP_IO_READ32(pAd, MCU_INT_SOURCE_CSR, &McuIsrAfterClear); */
-/*      DBGPRINT(RT_DEBUG_INFO, ("====> RTMPHandleInterrupt(ISR=%08x,Mcu ISR=%08x, After clear ISR=%08x, MCU ISR=%08x)\n", */
-/*                      IntSource.word, McuIntSource.word, IsrAfterClear, McuIsrAfterClear)); */
-
-	/* Do nothing if Reset in progress */
-	if (RTMP_TEST_FLAG
-	    (pAd,
-	     (fRTMP_ADAPTER_RESET_IN_PROGRESS |
-	      fRTMP_ADAPTER_HALT_IN_PROGRESS))) {
-		return IRQ_HANDLED;
-	}
-	/* */
-	/* Handle interrupt, walk through all bits */
-	/* Should start from highest priority interrupt */
-	/* The priority can be adjust by altering processing if statement */
-	/* */
-
-#ifdef DBG
-
-#endif
-
-	pAd->bPCIclkOff = FALSE;
-
-	/* If required spinlock, each interrupt service routine has to acquire */
-	/* and release itself. */
-	/* */
-
-	/* Do nothing if NIC doesn't exist */
-	if (IntSource.word == 0xffffffff) {
-		RTMP_SET_FLAG(pAd,
-			      (fRTMP_ADAPTER_NIC_NOT_EXIST |
-			       fRTMP_ADAPTER_HALT_IN_PROGRESS));
-		return IRQ_HANDLED;
-	}
-
-	if (IntSource.word & TxCoherent) {
-		DBGPRINT(RT_DEBUG_ERROR, (">>>TxCoherent<<<\n"));
-		RTMPHandleRxCoherentInterrupt(pAd);
-	}
-
-	if (IntSource.word & RxCoherent) {
-		DBGPRINT(RT_DEBUG_ERROR, (">>>RxCoherent<<<\n"));
-		RTMPHandleRxCoherentInterrupt(pAd);
-	}
-
-	if (IntSource.word & FifoStaFullInt) {
-		if ((pAd->int_disable_mask & FifoStaFullInt) == 0) {
-			/* mask FifoStaFullInt */
-			rt2860_int_disable(pAd, FifoStaFullInt);
-			tasklet_hi_schedule(&pObj->fifo_statistic_full_task);
-		}
-		pAd->int_pending |= FifoStaFullInt;
-	}
-
-	if (IntSource.word & INT_MGMT_DLY) {
-		if ((pAd->int_disable_mask & INT_MGMT_DLY) == 0) {
-			rt2860_int_disable(pAd, INT_MGMT_DLY);
-			tasklet_hi_schedule(&pObj->mgmt_dma_done_task);
-		}
-		pAd->int_pending |= INT_MGMT_DLY;
-	}
-
-	if (IntSource.word & INT_RX) {
-		if ((pAd->int_disable_mask & INT_RX) == 0) {
-
-			/* mask Rxint */
-			rt2860_int_disable(pAd, INT_RX);
-			tasklet_hi_schedule(&pObj->rx_done_task);
-		}
-		pAd->int_pending |= INT_RX;
-	}
-
-	if (IntSource.word & INT_AC3_DLY) {
-
-		if ((pAd->int_disable_mask & INT_AC3_DLY) == 0) {
-			/* mask TxDataInt */
-			rt2860_int_disable(pAd, INT_AC3_DLY);
-			tasklet_hi_schedule(&pObj->ac3_dma_done_task);
-		}
-		pAd->int_pending |= INT_AC3_DLY;
-	}
-
-	if (IntSource.word & INT_AC2_DLY) {
-
-		if ((pAd->int_disable_mask & INT_AC2_DLY) == 0) {
-			/* mask TxDataInt */
-			rt2860_int_disable(pAd, INT_AC2_DLY);
-			tasklet_hi_schedule(&pObj->ac2_dma_done_task);
-		}
-		pAd->int_pending |= INT_AC2_DLY;
-	}
-
-	if (IntSource.word & INT_AC1_DLY) {
-
-		pAd->int_pending |= INT_AC1_DLY;
-
-		if ((pAd->int_disable_mask & INT_AC1_DLY) == 0) {
-			/* mask TxDataInt */
-			rt2860_int_disable(pAd, INT_AC1_DLY);
-			tasklet_hi_schedule(&pObj->ac1_dma_done_task);
-		}
-
-	}
-
-	if (IntSource.word & INT_AC0_DLY) {
-
-/*
-		if (IntSource.word & 0x2) {
-			u32 reg;
-			RTMP_IO_READ32(pAd, DELAY_INT_CFG, &reg);
-			printk("IntSource.word = %08x, DELAY_REG = %08x\n", IntSource.word, reg);
-		}
-*/
-		pAd->int_pending |= INT_AC0_DLY;
-
-		if ((pAd->int_disable_mask & INT_AC0_DLY) == 0) {
-			/* mask TxDataInt */
-			rt2860_int_disable(pAd, INT_AC0_DLY);
-			tasklet_hi_schedule(&pObj->ac0_dma_done_task);
-		}
-
-	}
-
-	if (IntSource.word & PreTBTTInt) {
-		RTMPHandlePreTBTTInterrupt(pAd);
-	}
-
-	if (IntSource.word & TBTTInt) {
-		RTMPHandleTBTTInterrupt(pAd);
-	}
-
-	{
-		if (IntSource.word & AutoWakeupInt)
-			RTMPHandleTwakeupInterrupt(pAd);
-	}
-
-	return IRQ_HANDLED;
-}
-
-/*
- * invalid or writeback cache
- * and convert virtual address to physical address
- */
-dma_addr_t linux_pci_map_single(struct rt_rtmp_adapter *pAd, void *ptr,
-				size_t size, int sd_idx, int direction)
-{
-	struct os_cookie *pObj;
-
-	/*
-	   ------ Porting Information ------
-	   > For Tx Alloc:
-	   mgmt packets => sd_idx = 0
-	   SwIdx: pAd->MgmtRing.TxCpuIdx
-	   pTxD : pAd->MgmtRing.Cell[SwIdx].AllocVa;
-
-	   data packets => sd_idx = 1
-	   TxIdx : pAd->TxRing[pTxBlk->QueIdx].TxCpuIdx
-	   QueIdx: pTxBlk->QueIdx
-	   pTxD  : pAd->TxRing[pTxBlk->QueIdx].Cell[TxIdx].AllocVa;
-
-	   > For Rx Alloc:
-	   sd_idx = -1
-	 */
-
-	pObj = (struct os_cookie *)pAd->OS_Cookie;
-
-	if (sd_idx == 1) {
-		struct rt_tx_blk *pTxBlk;
-		pTxBlk = (struct rt_tx_blk *)ptr;
-		return pci_map_single(pObj->pci_dev, pTxBlk->pSrcBufData,
-				      pTxBlk->SrcBufLen, direction);
-	} else {
-		return pci_map_single(pObj->pci_dev, ptr, size, direction);
-	}
-
-}
-
-void linux_pci_unmap_single(struct rt_rtmp_adapter *pAd, dma_addr_t dma_addr,
-			    size_t size, int direction)
-{
-	struct os_cookie *pObj;
-
-	pObj = (struct os_cookie *)pAd->OS_Cookie;
-
-	pci_unmap_single(pObj->pci_dev, dma_addr, size, direction);
-
-}
diff -druN linux-2.6.39-libre/drivers/staging/rt2860/rt_usb.c linux-3.0-rc7-libre/drivers/staging/rt2860/rt_usb.c
--- linux-2.6.39-libre/drivers/staging/rt2860/rt_usb.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rt2860/rt_usb.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,794 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, 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.             *
- *                                                                       *
- *************************************************************************
-
-	Module Name:
-	rtusb_bulk.c
-
-	Abstract:
-
-	Revision History:
-	Who			When		What
-	--------	----------	----------------------------------------------
-	Name			Date		Modification logs
-	Justin P. Mattock	11/07/2010	Fix some typos.
-
-*/
-
-#include "rt_config.h"
-
-void dump_urb(struct urb *purb)
-{
-	printk(KERN_DEBUG "urb                  :0x%08lx\n", (unsigned long)purb);
-	printk(KERN_DEBUG "\tdev                   :0x%08lx\n", (unsigned long)purb->dev);
-	printk(KERN_DEBUG "\t\tdev->state          :0x%d\n", purb->dev->state);
-	printk(KERN_DEBUG "\tpipe                  :0x%08x\n", purb->pipe);
-	printk(KERN_DEBUG "\tstatus                :%d\n", purb->status);
-	printk(KERN_DEBUG "\ttransfer_flags        :0x%08x\n", purb->transfer_flags);
-	printk(KERN_DEBUG "\ttransfer_buffer       :0x%08lx\n",
-	       (unsigned long)purb->transfer_buffer);
-	printk(KERN_DEBUG "\ttransfer_buffer_length:%d\n", purb->transfer_buffer_length);
-	printk(KERN_DEBUG "\tactual_length         :%d\n", purb->actual_length);
-	printk(KERN_DEBUG "\tsetup_packet          :0x%08lx\n",
-	       (unsigned long)purb->setup_packet);
-	printk(KERN_DEBUG "\tstart_frame           :%d\n", purb->start_frame);
-	printk(KERN_DEBUG "\tnumber_of_packets     :%d\n", purb->number_of_packets);
-	printk(KERN_DEBUG "\tinterval              :%d\n", purb->interval);
-	printk(KERN_DEBUG "\terror_count           :%d\n", purb->error_count);
-	printk(KERN_DEBUG "\tcontext               :0x%08lx\n",
-	       (unsigned long)purb->context);
-	printk(KERN_DEBUG "\tcomplete              :0x%08lx\n\n",
-	       (unsigned long)purb->complete);
-}
-
-/*
-========================================================================
-Routine Description:
-    Create kernel threads & tasklets.
-
-Arguments:
-    *net_dev			Pointer to wireless net device interface
-
-Return Value:
-	NDIS_STATUS_SUCCESS
-	NDIS_STATUS_FAILURE
-
-Note:
-========================================================================
-*/
-int RtmpMgmtTaskInit(struct rt_rtmp_adapter *pAd)
-{
-	struct rt_rtmp_os_task *pTask;
-	int status;
-
-	/*
-	   Creat TimerQ Thread, We need init timerQ related structure before create the timer thread.
-	 */
-	RtmpTimerQInit(pAd);
-
-	pTask = &pAd->timerTask;
-	RtmpOSTaskInit(pTask, "RtmpTimerTask", pAd);
-	status = RtmpOSTaskAttach(pTask, RtmpTimerQThread, pTask);
-	if (status == NDIS_STATUS_FAILURE) {
-		printk(KERN_WARNING "%s: unable to start RtmpTimerQThread\n",
-		       RTMP_OS_NETDEV_GET_DEVNAME(pAd->net_dev));
-		return NDIS_STATUS_FAILURE;
-	}
-
-	/* Creat MLME Thread */
-	pTask = &pAd->mlmeTask;
-	RtmpOSTaskInit(pTask, "RtmpMlmeTask", pAd);
-	status = RtmpOSTaskAttach(pTask, MlmeThread, pTask);
-	if (status == NDIS_STATUS_FAILURE) {
-		printk(KERN_WARNING "%s: unable to start MlmeThread\n",
-		       RTMP_OS_NETDEV_GET_DEVNAME(pAd->net_dev));
-		return NDIS_STATUS_FAILURE;
-	}
-
-	/* Creat Command Thread */
-	pTask = &pAd->cmdQTask;
-	RtmpOSTaskInit(pTask, "RtmpCmdQTask", pAd);
-	status = RtmpOSTaskAttach(pTask, RTUSBCmdThread, pTask);
-	if (status == NDIS_STATUS_FAILURE) {
-		printk(KERN_WARNING "%s: unable to start RTUSBCmdThread\n",
-		       RTMP_OS_NETDEV_GET_DEVNAME(pAd->net_dev));
-		return NDIS_STATUS_FAILURE;
-	}
-
-	return NDIS_STATUS_SUCCESS;
-}
-
-/*
-========================================================================
-Routine Description:
-    Close kernel threads.
-
-Arguments:
-	*pAd				the raxx interface data pointer
-
-Return Value:
-    NONE
-
-Note:
-========================================================================
-*/
-void RtmpMgmtTaskExit(struct rt_rtmp_adapter *pAd)
-{
-	int ret;
-	struct rt_rtmp_os_task *pTask;
-
-	/* Sleep 50 milliseconds so pending io might finish normally */
-	RTMPusecDelay(50000);
-
-	/* We want to wait until all pending receives and sends to the */
-	/* device object. We cancel any */
-	/* irps. Wait until sends and receives have stopped. */
-	RTUSBCancelPendingIRPs(pAd);
-
-	/* We need clear timerQ related structure before exits of the timer thread. */
-	RtmpTimerQExit(pAd);
-
-	/* Terminate Mlme Thread */
-	pTask = &pAd->mlmeTask;
-	ret = RtmpOSTaskKill(pTask);
-	if (ret == NDIS_STATUS_FAILURE) {
-		DBGPRINT(RT_DEBUG_ERROR, ("%s: kill task(%s) failed!\n",
-					  RTMP_OS_NETDEV_GET_DEVNAME(pAd->
-								     net_dev),
-					  pTask->taskName));
-	}
-
-	/* Terminate cmdQ thread */
-	pTask = &pAd->cmdQTask;
-#ifdef KTHREAD_SUPPORT
-	if (pTask->kthread_task)
-#else
-	CHECK_PID_LEGALITY(pTask->taskPID)
-#endif
-	{
-		mb();
-		NdisAcquireSpinLock(&pAd->CmdQLock);
-		pAd->CmdQ.CmdQState = RTMP_TASK_STAT_STOPED;
-		NdisReleaseSpinLock(&pAd->CmdQLock);
-		mb();
-		/*RTUSBCMDUp(pAd); */
-		ret = RtmpOSTaskKill(pTask);
-		if (ret == NDIS_STATUS_FAILURE) {
-			DBGPRINT(RT_DEBUG_ERROR, ("%s: kill task(%s) failed!\n",
-						  RTMP_OS_NETDEV_GET_DEVNAME
-						  (pAd->net_dev),
-						  pTask->taskName));
-		}
-		pAd->CmdQ.CmdQState = RTMP_TASK_STAT_UNKNOWN;
-	}
-
-	/* Terminate timer thread */
-	pTask = &pAd->timerTask;
-	ret = RtmpOSTaskKill(pTask);
-	if (ret == NDIS_STATUS_FAILURE) {
-		DBGPRINT(RT_DEBUG_ERROR, ("%s: kill task(%s) failed!\n",
-					  RTMP_OS_NETDEV_GET_DEVNAME(pAd->
-								     net_dev),
-					  pTask->taskName));
-	}
-
-}
-
-static void rtusb_dataout_complete(unsigned long data)
-{
-	struct rt_rtmp_adapter *pAd;
-	struct urb *pUrb;
-	struct os_cookie *pObj;
-	struct rt_ht_tx_context *pHTTXContext;
-	u8 BulkOutPipeId;
-	int Status;
-	unsigned long IrqFlags;
-
-	pUrb = (struct urb *)data;
-	pHTTXContext = (struct rt_ht_tx_context *)pUrb->context;
-	pAd = pHTTXContext->pAd;
-	pObj = (struct os_cookie *)pAd->OS_Cookie;
-	Status = pUrb->status;
-
-	/* Store BulkOut PipeId */
-	BulkOutPipeId = pHTTXContext->BulkOutPipeId;
-	pAd->BulkOutDataOneSecCount++;
-
-	/*DBGPRINT(RT_DEBUG_LOUD, ("Done-B(%d):I=0x%lx, CWPos=%ld, NBPos=%ld, ENBPos=%ld, bCopy=%d!\n", BulkOutPipeId, in_interrupt(), pHTTXContext->CurWritePosition, */
-	/*              pHTTXContext->NextBulkOutPosition, pHTTXContext->ENextBulkOutPosition, pHTTXContext->bCopySavePad)); */
-
-	RTMP_IRQ_LOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
-	pAd->BulkOutPending[BulkOutPipeId] = FALSE;
-	pHTTXContext->IRPPending = FALSE;
-	pAd->watchDogTxPendingCnt[BulkOutPipeId] = 0;
-
-	if (Status == USB_ST_NOERROR) {
-		pAd->BulkOutComplete++;
-
-		RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
-
-		pAd->Counters8023.GoodTransmits++;
-		/*RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags); */
-		FREE_HTTX_RING(pAd, BulkOutPipeId, pHTTXContext);
-		/*RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags); */
-
-	} else {		/* STATUS_OTHER */
-		u8 *pBuf;
-
-		pAd->BulkOutCompleteOther++;
-
-		pBuf =
-		    &pHTTXContext->TransferBuffer->field.
-		    WirelessPacket[pHTTXContext->NextBulkOutPosition];
-
-		if (!RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS |
-					  fRTMP_ADAPTER_HALT_IN_PROGRESS |
-					  fRTMP_ADAPTER_NIC_NOT_EXIST |
-					  fRTMP_ADAPTER_BULKOUT_RESET))) {
-			RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET);
-			pAd->bulkResetPipeid = BulkOutPipeId;
-			pAd->bulkResetReq[BulkOutPipeId] = pAd->BulkOutReq;
-		}
-		RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
-
-		DBGPRINT_RAW(RT_DEBUG_ERROR,
-			     ("BulkOutDataPacket failed: ReasonCode=%d!\n",
-			      Status));
-		DBGPRINT_RAW(RT_DEBUG_ERROR,
-			     ("\t>>BulkOut Req=0x%lx, Complete=0x%lx, Other=0x%lx\n",
-			      pAd->BulkOutReq, pAd->BulkOutComplete,
-			      pAd->BulkOutCompleteOther));
-		DBGPRINT_RAW(RT_DEBUG_ERROR,
-			     ("\t>>BulkOut Header:%x %x %x %x %x %x %x %x\n",
-			      pBuf[0], pBuf[1], pBuf[2], pBuf[3], pBuf[4],
-			      pBuf[5], pBuf[6], pBuf[7]));
-		/*DBGPRINT_RAW(RT_DEBUG_ERROR, (">>BulkOutCompleteCancel=0x%x, BulkOutCompleteOther=0x%x\n", pAd->BulkOutCompleteCancel, pAd->BulkOutCompleteOther)); */
-
-	}
-
-	/* */
-	/* bInUse = TRUE, means some process are filling TX data, after that must turn on bWaitingBulkOut */
-	/* bWaitingBulkOut = TRUE, means the TX data are waiting for bulk out. */
-	/* */
-	/*RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags); */
-	if ((pHTTXContext->ENextBulkOutPosition !=
-	     pHTTXContext->CurWritePosition)
-	    && (pHTTXContext->ENextBulkOutPosition !=
-		(pHTTXContext->CurWritePosition + 8))
-	    && !RTUSB_TEST_BULK_FLAG(pAd,
-				     (fRTUSB_BULK_OUT_DATA_FRAG <<
-				      BulkOutPipeId))) {
-		/* Indicate There is data available */
-		RTUSB_SET_BULK_FLAG(pAd,
-				    (fRTUSB_BULK_OUT_DATA_NORMAL <<
-				     BulkOutPipeId));
-	}
-	/*RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags); */
-
-	/* Always call Bulk routine, even reset bulk. */
-	/* The protection of rest bulk should be in BulkOut routine */
-	RTUSBKickBulkOut(pAd);
-}
-
-static void rtusb_null_frame_done_tasklet(unsigned long data)
-{
-	struct rt_rtmp_adapter *pAd;
-	struct rt_tx_context *pNullContext;
-	struct urb *pUrb;
-	int Status;
-	unsigned long irqFlag;
-
-	pUrb = (struct urb *)data;
-	pNullContext = (struct rt_tx_context *)pUrb->context;
-	pAd = pNullContext->pAd;
-	Status = pUrb->status;
-
-	/* Reset Null frame context flags */
-	RTMP_IRQ_LOCK(&pAd->BulkOutLock[0], irqFlag);
-	pNullContext->IRPPending = FALSE;
-	pNullContext->InUse = FALSE;
-	pAd->BulkOutPending[0] = FALSE;
-	pAd->watchDogTxPendingCnt[0] = 0;
-
-	if (Status == USB_ST_NOERROR) {
-		RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], irqFlag);
-
-		RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, MAX_TX_PROCESS);
-	} else {		/* STATUS_OTHER */
-		if ((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)) &&
-		    (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) &&
-		    (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) &&
-		    (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET))) {
-			DBGPRINT_RAW(RT_DEBUG_ERROR,
-				     ("Bulk Out Null Frame Failed, ReasonCode=%d!\n",
-				      Status));
-			RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET);
-			pAd->bulkResetPipeid =
-			    (MGMTPIPEIDX | BULKOUT_MGMT_RESET_FLAG);
-			RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], irqFlag);
-			RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT,
-						NULL, 0);
-		} else {
-			RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], irqFlag);
-		}
-	}
-
-	/* Always call Bulk routine, even reset bulk. */
-	/* The protection of rest bulk should be in BulkOut routine */
-	RTUSBKickBulkOut(pAd);
-}
-
-static void rtusb_rts_frame_done_tasklet(unsigned long data)
-{
-	struct rt_rtmp_adapter *pAd;
-	struct rt_tx_context *pRTSContext;
-	struct urb *pUrb;
-	int Status;
-	unsigned long irqFlag;
-
-	pUrb = (struct urb *)data;
-	pRTSContext = (struct rt_tx_context *)pUrb->context;
-	pAd = pRTSContext->pAd;
-	Status = pUrb->status;
-
-	/* Reset RTS frame context flags */
-	RTMP_IRQ_LOCK(&pAd->BulkOutLock[0], irqFlag);
-	pRTSContext->IRPPending = FALSE;
-	pRTSContext->InUse = FALSE;
-
-	if (Status == USB_ST_NOERROR) {
-		RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], irqFlag);
-		RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, MAX_TX_PROCESS);
-	} else {		/* STATUS_OTHER */
-		if ((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)) &&
-		    (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) &&
-		    (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) &&
-		    (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET))) {
-			DBGPRINT_RAW(RT_DEBUG_ERROR,
-				     ("Bulk Out RTS Frame Failed\n"));
-			RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET);
-			pAd->bulkResetPipeid =
-			    (MGMTPIPEIDX | BULKOUT_MGMT_RESET_FLAG);
-			RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], irqFlag);
-			RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT,
-						NULL, 0);
-		} else {
-			RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], irqFlag);
-		}
-	}
-
-	RTMP_SEM_LOCK(&pAd->BulkOutLock[pRTSContext->BulkOutPipeId]);
-	pAd->BulkOutPending[pRTSContext->BulkOutPipeId] = FALSE;
-	RTMP_SEM_UNLOCK(&pAd->BulkOutLock[pRTSContext->BulkOutPipeId]);
-
-	/* Always call Bulk routine, even reset bulk. */
-	/* The protection of rest bulk should be in BulkOut routine */
-	RTUSBKickBulkOut(pAd);
-
-}
-
-static void rtusb_pspoll_frame_done_tasklet(unsigned long data)
-{
-	struct rt_rtmp_adapter *pAd;
-	struct rt_tx_context *pPsPollContext;
-	struct urb *pUrb;
-	int Status;
-
-	pUrb = (struct urb *)data;
-	pPsPollContext = (struct rt_tx_context *)pUrb->context;
-	pAd = pPsPollContext->pAd;
-	Status = pUrb->status;
-
-	/* Reset PsPoll context flags */
-	pPsPollContext->IRPPending = FALSE;
-	pPsPollContext->InUse = FALSE;
-	pAd->watchDogTxPendingCnt[0] = 0;
-
-	if (Status == USB_ST_NOERROR) {
-		RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, MAX_TX_PROCESS);
-	} else {		/* STATUS_OTHER */
-		if ((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)) &&
-		    (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) &&
-		    (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) &&
-		    (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET))) {
-			DBGPRINT_RAW(RT_DEBUG_ERROR,
-				     ("Bulk Out PSPoll Failed\n"));
-			RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET);
-			pAd->bulkResetPipeid =
-			    (MGMTPIPEIDX | BULKOUT_MGMT_RESET_FLAG);
-			RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT,
-						NULL, 0);
-		}
-	}
-
-	RTMP_SEM_LOCK(&pAd->BulkOutLock[0]);
-	pAd->BulkOutPending[0] = FALSE;
-	RTMP_SEM_UNLOCK(&pAd->BulkOutLock[0]);
-
-	/* Always call Bulk routine, even reset bulk. */
-	/* The protection of rest bulk should be in BulkOut routine */
-	RTUSBKickBulkOut(pAd);
-
-}
-
-/*
-========================================================================
-Routine Description:
-    Handle received packets.
-
-Arguments:
-	data				- URB information pointer
-
-Return Value:
-    None
-
-Note:
-========================================================================
-*/
-static void rx_done_tasklet(unsigned long data)
-{
-	struct urb *pUrb;
-	struct rt_rx_context *pRxContext;
-	struct rt_rtmp_adapter *pAd;
-	int Status;
-	unsigned int IrqFlags;
-
-	pUrb = (struct urb *)data;
-	pRxContext = (struct rt_rx_context *)pUrb->context;
-	pAd = pRxContext->pAd;
-	Status = pUrb->status;
-
-	RTMP_IRQ_LOCK(&pAd->BulkInLock, IrqFlags);
-	pRxContext->InUse = FALSE;
-	pRxContext->IRPPending = FALSE;
-	pRxContext->BulkInOffset += pUrb->actual_length;
-	/*NdisInterlockedDecrement(&pAd->PendingRx); */
-	pAd->PendingRx--;
-
-	if (Status == USB_ST_NOERROR) {
-		pAd->BulkInComplete++;
-		pAd->NextRxBulkInPosition = 0;
-		if (pRxContext->BulkInOffset) { /* As jan's comment, it may bulk-in success but size is zero. */
-			pRxContext->Readable = TRUE;
-			INC_RING_INDEX(pAd->NextRxBulkInIndex, RX_RING_SIZE);
-		}
-		RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
-	} else {			/* STATUS_OTHER */
-		pAd->BulkInCompleteFail++;
-		/* Still read this packet although it may comtain wrong bytes. */
-		pRxContext->Readable = FALSE;
-		RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
-
-		/* Parsing all packets. because after reset, the index will reset to all zero. */
-		if ((!RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS |
-					   fRTMP_ADAPTER_BULKIN_RESET |
-					   fRTMP_ADAPTER_HALT_IN_PROGRESS |
-					   fRTMP_ADAPTER_NIC_NOT_EXIST)))) {
-
-			DBGPRINT_RAW(RT_DEBUG_ERROR,
-				     ("Bulk In Failed. Status=%d, BIIdx=0x%x, BIRIdx=0x%x, actual_length= 0x%x\n",
-				      Status, pAd->NextRxBulkInIndex,
-				      pAd->NextRxBulkInReadIndex,
-				      pRxContext->pUrb->actual_length));
-
-			RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKIN_RESET);
-			RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_IN,
-						NULL, 0);
-		}
-	}
-
-	ASSERT((pRxContext->InUse == pRxContext->IRPPending));
-
-	RTUSBBulkReceive(pAd);
-
-	return;
-
-}
-
-static void rtusb_mgmt_dma_done_tasklet(unsigned long data)
-{
-	struct rt_rtmp_adapter *pAd;
-	struct rt_tx_context *pMLMEContext;
-	int index;
-	void *pPacket;
-	struct urb *pUrb;
-	int Status;
-	unsigned long IrqFlags;
-
-	pUrb = (struct urb *)data;
-	pMLMEContext = (struct rt_tx_context *)pUrb->context;
-	pAd = pMLMEContext->pAd;
-	Status = pUrb->status;
-	index = pMLMEContext->SelfIdx;
-
-	ASSERT((pAd->MgmtRing.TxDmaIdx == index));
-
-	RTMP_IRQ_LOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags);
-
-	if (Status != USB_ST_NOERROR) {
-		/*Bulk-Out fail status handle */
-		if ((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)) &&
-		    (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) &&
-		    (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) &&
-		    (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET))) {
-			DBGPRINT_RAW(RT_DEBUG_ERROR,
-				     ("Bulk Out MLME Failed, Status=%d!\n",
-				      Status));
-			/* TODO: How to handle about the MLMEBulkOut failed issue. Need to resend the mgmt pkt? */
-			RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET);
-			pAd->bulkResetPipeid =
-			    (MGMTPIPEIDX | BULKOUT_MGMT_RESET_FLAG);
-		}
-	}
-
-	pAd->BulkOutPending[MGMTPIPEIDX] = FALSE;
-	RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags);
-
-	RTMP_IRQ_LOCK(&pAd->MLMEBulkOutLock, IrqFlags);
-	/* Reset MLME context flags */
-	pMLMEContext->IRPPending = FALSE;
-	pMLMEContext->InUse = FALSE;
-	pMLMEContext->bWaitingBulkOut = FALSE;
-	pMLMEContext->BulkOutSize = 0;
-
-	pPacket = pAd->MgmtRing.Cell[index].pNdisPacket;
-	pAd->MgmtRing.Cell[index].pNdisPacket = NULL;
-
-	/* Increase MgmtRing Index */
-	INC_RING_INDEX(pAd->MgmtRing.TxDmaIdx, MGMT_RING_SIZE);
-	pAd->MgmtRing.TxSwFreeIdx++;
-	RTMP_IRQ_UNLOCK(&pAd->MLMEBulkOutLock, IrqFlags);
-
-	/* No-matter success or fail, we free the mgmt packet. */
-	if (pPacket)
-		RTMPFreeNdisPacket(pAd, pPacket);
-
-	if ((RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS |
-				  fRTMP_ADAPTER_HALT_IN_PROGRESS |
-				  fRTMP_ADAPTER_NIC_NOT_EXIST)))) {
-		/* do nothing and return directly. */
-	} else {
-		if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET) && ((pAd->bulkResetPipeid & BULKOUT_MGMT_RESET_FLAG) == BULKOUT_MGMT_RESET_FLAG)) {	/* For Mgmt Bulk-Out failed, ignore it now. */
-			RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT,
-						NULL, 0);
-		} else {
-
-			/* Always call Bulk routine, even reset bulk. */
-			/* The protection of rest bulk should be in BulkOut routine */
-			if (pAd->MgmtRing.TxSwFreeIdx <
-			    MGMT_RING_SIZE
-			    /* pMLMEContext->bWaitingBulkOut == TRUE */) {
-				RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_MLME);
-			}
-			RTUSBKickBulkOut(pAd);
-		}
-	}
-
-}
-
-static void rtusb_ac3_dma_done_tasklet(unsigned long data)
-{
-	struct rt_rtmp_adapter *pAd;
-	struct rt_ht_tx_context *pHTTXContext;
-	u8 BulkOutPipeId = 3;
-	struct urb *pUrb;
-
-	pUrb = (struct urb *)data;
-	pHTTXContext = (struct rt_ht_tx_context *)pUrb->context;
-	pAd = pHTTXContext->pAd;
-
-	rtusb_dataout_complete((unsigned long)pUrb);
-
-	if ((RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS |
-				  fRTMP_ADAPTER_HALT_IN_PROGRESS |
-				  fRTMP_ADAPTER_NIC_NOT_EXIST)))) {
-		/* do nothing and return directly. */
-	} else {
-		if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET)) {
-			RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT,
-						NULL, 0);
-		} else {
-			pHTTXContext = &pAd->TxContext[BulkOutPipeId];
-			if ((pAd->TxSwQueue[BulkOutPipeId].Number > 0) &&
-			    /*((pHTTXContext->CurWritePosition > (pHTTXContext->NextBulkOutPosition + 0x6000)) || (pHTTXContext->NextBulkOutPosition > pHTTXContext->CurWritePosition + 0x6000)) && */
-			    (pAd->DeQueueRunning[BulkOutPipeId] == FALSE) &&
-			    (pHTTXContext->bCurWriting == FALSE)) {
-				RTMPDeQueuePacket(pAd, FALSE, BulkOutPipeId,
-						  MAX_TX_PROCESS);
-			}
-
-			RTUSB_SET_BULK_FLAG(pAd,
-					    fRTUSB_BULK_OUT_DATA_NORMAL << 3);
-			RTUSBKickBulkOut(pAd);
-		}
-	}
-
-	return;
-}
-
-static void rtusb_ac2_dma_done_tasklet(unsigned long data)
-{
-	struct rt_rtmp_adapter *pAd;
-	struct rt_ht_tx_context *pHTTXContext;
-	u8 BulkOutPipeId = 2;
-	struct urb *pUrb;
-
-	pUrb = (struct urb *)data;
-	pHTTXContext = (struct rt_ht_tx_context *)pUrb->context;
-	pAd = pHTTXContext->pAd;
-
-	rtusb_dataout_complete((unsigned long)pUrb);
-
-	if ((RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS |
-				  fRTMP_ADAPTER_HALT_IN_PROGRESS |
-				  fRTMP_ADAPTER_NIC_NOT_EXIST)))) {
-		/* do nothing and return directly. */
-	} else {
-		if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET)) {
-			RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT,
-						NULL, 0);
-		} else {
-			pHTTXContext = &pAd->TxContext[BulkOutPipeId];
-			if ((pAd->TxSwQueue[BulkOutPipeId].Number > 0) &&
-			    /*((pHTTXContext->CurWritePosition > (pHTTXContext->NextBulkOutPosition + 0x6000)) || (pHTTXContext->NextBulkOutPosition > pHTTXContext->CurWritePosition + 0x6000)) && */
-			    (pAd->DeQueueRunning[BulkOutPipeId] == FALSE) &&
-			    (pHTTXContext->bCurWriting == FALSE)) {
-				RTMPDeQueuePacket(pAd, FALSE, BulkOutPipeId,
-						  MAX_TX_PROCESS);
-			}
-
-			RTUSB_SET_BULK_FLAG(pAd,
-					    fRTUSB_BULK_OUT_DATA_NORMAL << 2);
-			RTUSBKickBulkOut(pAd);
-		}
-	}
-
-	return;
-}
-
-static void rtusb_ac1_dma_done_tasklet(unsigned long data)
-{
-	struct rt_rtmp_adapter *pAd;
-	struct rt_ht_tx_context *pHTTXContext;
-	u8 BulkOutPipeId = 1;
-	struct urb *pUrb;
-
-	pUrb = (struct urb *)data;
-	pHTTXContext = (struct rt_ht_tx_context *)pUrb->context;
-	pAd = pHTTXContext->pAd;
-
-	rtusb_dataout_complete((unsigned long)pUrb);
-
-	if ((RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS |
-				  fRTMP_ADAPTER_HALT_IN_PROGRESS |
-				  fRTMP_ADAPTER_NIC_NOT_EXIST)))) {
-		/* do nothing and return directly. */
-	} else {
-		if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET)) {
-			RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT,
-						NULL, 0);
-		} else {
-			pHTTXContext = &pAd->TxContext[BulkOutPipeId];
-			if ((pAd->TxSwQueue[BulkOutPipeId].Number > 0) &&
-			    /*((pHTTXContext->CurWritePosition > (pHTTXContext->NextBulkOutPosition + 0x6000)) || (pHTTXContext->NextBulkOutPosition > pHTTXContext->CurWritePosition + 0x6000)) && */
-			    (pAd->DeQueueRunning[BulkOutPipeId] == FALSE) &&
-			    (pHTTXContext->bCurWriting == FALSE)) {
-				RTMPDeQueuePacket(pAd, FALSE, BulkOutPipeId,
-						  MAX_TX_PROCESS);
-			}
-
-			RTUSB_SET_BULK_FLAG(pAd,
-					    fRTUSB_BULK_OUT_DATA_NORMAL << 1);
-			RTUSBKickBulkOut(pAd);
-		}
-	}
-	return;
-
-}
-
-static void rtusb_ac0_dma_done_tasklet(unsigned long data)
-{
-	struct rt_rtmp_adapter *pAd;
-	struct rt_ht_tx_context *pHTTXContext;
-	u8 BulkOutPipeId = 0;
-	struct urb *pUrb;
-
-	pUrb = (struct urb *)data;
-	pHTTXContext = (struct rt_ht_tx_context *)pUrb->context;
-	pAd = pHTTXContext->pAd;
-
-	rtusb_dataout_complete((unsigned long)pUrb);
-
-	if ((RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS |
-				  fRTMP_ADAPTER_HALT_IN_PROGRESS |
-				  fRTMP_ADAPTER_NIC_NOT_EXIST)))) {
-		/* do nothing and return directly. */
-	} else {
-		if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET)) {
-			RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT,
-						NULL, 0);
-		} else {
-			pHTTXContext = &pAd->TxContext[BulkOutPipeId];
-			if ((pAd->TxSwQueue[BulkOutPipeId].Number > 0) &&
-			    /*  ((pHTTXContext->CurWritePosition > (pHTTXContext->NextBulkOutPosition + 0x6000)) || (pHTTXContext->NextBulkOutPosition > pHTTXContext->CurWritePosition + 0x6000)) && */
-			    (pAd->DeQueueRunning[BulkOutPipeId] == FALSE) &&
-			    (pHTTXContext->bCurWriting == FALSE)) {
-				RTMPDeQueuePacket(pAd, FALSE, BulkOutPipeId,
-						  MAX_TX_PROCESS);
-			}
-
-			RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL);
-			RTUSBKickBulkOut(pAd);
-		}
-	}
-
-	return;
-
-}
-
-int RtmpNetTaskInit(struct rt_rtmp_adapter *pAd)
-{
-	struct os_cookie *pObj = (struct os_cookie *)pAd->OS_Cookie;
-
-	/* Create receive tasklet */
-	tasklet_init(&pObj->rx_done_task, rx_done_tasklet, (unsigned long)pAd);
-	tasklet_init(&pObj->mgmt_dma_done_task, rtusb_mgmt_dma_done_tasklet,
-		     (unsigned long)pAd);
-	tasklet_init(&pObj->ac0_dma_done_task, rtusb_ac0_dma_done_tasklet,
-		     (unsigned long)pAd);
-	tasklet_init(&pObj->ac1_dma_done_task, rtusb_ac1_dma_done_tasklet,
-		     (unsigned long)pAd);
-	tasklet_init(&pObj->ac2_dma_done_task, rtusb_ac2_dma_done_tasklet,
-		     (unsigned long)pAd);
-	tasklet_init(&pObj->ac3_dma_done_task, rtusb_ac3_dma_done_tasklet,
-		     (unsigned long)pAd);
-	tasklet_init(&pObj->tbtt_task, tbtt_tasklet, (unsigned long)pAd);
-	tasklet_init(&pObj->null_frame_complete_task,
-		     rtusb_null_frame_done_tasklet, (unsigned long)pAd);
-	tasklet_init(&pObj->rts_frame_complete_task,
-		     rtusb_rts_frame_done_tasklet, (unsigned long)pAd);
-	tasklet_init(&pObj->pspoll_frame_complete_task,
-		     rtusb_pspoll_frame_done_tasklet, (unsigned long)pAd);
-
-	return NDIS_STATUS_SUCCESS;
-}
-
-void RtmpNetTaskExit(struct rt_rtmp_adapter *pAd)
-{
-	struct os_cookie *pObj;
-
-	pObj = (struct os_cookie *)pAd->OS_Cookie;
-
-	tasklet_kill(&pObj->rx_done_task);
-	tasklet_kill(&pObj->mgmt_dma_done_task);
-	tasklet_kill(&pObj->ac0_dma_done_task);
-	tasklet_kill(&pObj->ac1_dma_done_task);
-	tasklet_kill(&pObj->ac2_dma_done_task);
-	tasklet_kill(&pObj->ac3_dma_done_task);
-	tasklet_kill(&pObj->tbtt_task);
-	tasklet_kill(&pObj->null_frame_complete_task);
-	tasklet_kill(&pObj->rts_frame_complete_task);
-	tasklet_kill(&pObj->pspoll_frame_complete_task);
-}
diff -druN linux-2.6.39-libre/drivers/staging/rt2860/rtusb_io.h linux-3.0-rc7-libre/drivers/staging/rt2860/rtusb_io.h
--- linux-2.6.39-libre/drivers/staging/rt2860/rtusb_io.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rt2860/rtusb_io.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,185 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, 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 __RTUSB_IO_H__
-#define __RTUSB_IO_H__
-
-#include "rtmp_type.h"
-
-/* New for MeetingHouse Api support */
-#define CMDTHREAD_VENDOR_RESET                      0x0D730101	/* cmd */
-#define CMDTHREAD_VENDOR_UNPLUG                     0x0D730102	/* cmd */
-#define CMDTHREAD_VENDOR_SWITCH_FUNCTION            0x0D730103	/* cmd */
-#define CMDTHREAD_MULTI_WRITE_MAC                   0x0D730107	/* cmd */
-#define CMDTHREAD_MULTI_READ_MAC                    0x0D730108	/* cmd */
-#define CMDTHREAD_VENDOR_EEPROM_WRITE               0x0D73010A	/* cmd */
-#define CMDTHREAD_VENDOR_EEPROM_READ                0x0D73010B	/* cmd */
-#define CMDTHREAD_VENDOR_ENTER_TESTMODE             0x0D73010C	/* cmd */
-#define CMDTHREAD_VENDOR_EXIT_TESTMODE              0x0D73010D	/* cmd */
-#define CMDTHREAD_VENDOR_WRITE_BBP                  0x0D730119	/* cmd */
-#define CMDTHREAD_VENDOR_READ_BBP                   0x0D730118	/* cmd */
-#define CMDTHREAD_VENDOR_WRITE_RF                   0x0D73011A	/* cmd */
-#define CMDTHREAD_VENDOR_FLIP_IQ                    0x0D73011D	/* cmd */
-#define CMDTHREAD_RESET_BULK_OUT                    0x0D730210	/* cmd */
-#define CMDTHREAD_RESET_BULK_IN                     0x0D730211	/* cmd */
-#define CMDTHREAD_SET_PSM_BIT				0x0D730212	/* cmd */
-#define CMDTHREAD_SET_RADIO                         0x0D730214	/* cmd */
-#define CMDTHREAD_UPDATE_TX_RATE                    0x0D730216	/* cmd */
-#define CMDTHREAD_802_11_ADD_KEY_WEP                0x0D730218	/* cmd */
-#define CMDTHREAD_RESET_FROM_ERROR                  0x0D73021A	/* cmd */
-#define CMDTHREAD_LINK_DOWN                         0x0D73021B	/* cmd */
-#define CMDTHREAD_RESET_FROM_NDIS                   0x0D73021C	/* cmd */
-#define CMDTHREAD_CHECK_GPIO                        0x0D730215	/* cmd */
-#define CMDTHREAD_FORCE_WAKE_UP                     0x0D730222	/* cmd */
-#define CMDTHREAD_SET_BW                            0x0D730225	/* cmd */
-#define CMDTHREAD_SET_ASIC_WCID                     0x0D730226	/* cmd */
-#define CMDTHREAD_SET_ASIC_WCID_CIPHER              0x0D730227	/* cmd */
-#define CMDTHREAD_QKERIODIC_EXECUT                  0x0D73023D	/* cmd */
-#define RT_CMD_SET_KEY_TABLE                        0x0D730228	/* cmd */
-#define RT_CMD_SET_RX_WCID_TABLE                    0x0D730229	/* cmd */
-#define CMDTHREAD_SET_CLIENT_MAC_ENTRY              0x0D73023E	/* cmd */
-#define CMDTHREAD_SET_GROUP_KEY						0x0D73023F	/* cmd */
-#define CMDTHREAD_SET_PAIRWISE_KEY					0x0D730240	/* cmd */
-
-#define CMDTHREAD_802_11_QUERY_HARDWARE_REGISTER    0x0D710105	/* cmd */
-#define CMDTHREAD_802_11_SET_PHY_MODE               0x0D79010C	/* cmd */
-#define CMDTHREAD_802_11_SET_STA_CONFIG             0x0D790111	/* cmd */
-#define CMDTHREAD_802_11_SET_PREAMBLE               0x0D790101	/* cmd */
-#define CMDTHREAD_802_11_COUNTER_MEASURE			0x0D790102	/* cmd */
-/* add by johnli, fix "in_interrupt" error when call "MacTableDeleteEntry" in Rx tasklet */
-#define CMDTHREAD_UPDATE_PROTECT					0x0D790103	/* cmd */
-/* end johnli */
-
-/*CMDTHREAD_MULTI_READ_MAC */
-/*CMDTHREAD_MULTI_WRITE_MAC */
-/*CMDTHREAD_VENDOR_EEPROM_READ */
-/*CMDTHREAD_VENDOR_EEPROM_WRITE */
-struct rt_cmdhandler_tlv {
-	u16 Offset;
-	u16 Length;
-	u8 DataFirst;
-};
-
-struct rt_cmdqelmt;
-
-struct rt_cmdqelmt {
-	u32 command;
-	void *buffer;
-	unsigned long bufferlength;
-	BOOLEAN CmdFromNdis;
-	BOOLEAN SetOperation;
-	struct rt_cmdqelmt *next;
-};
-
-struct rt_cmdq {
-	u32 size;
-	struct rt_cmdqelmt *head;
-	struct rt_cmdqelmt *tail;
-	u32 CmdQState;
-};
-
-#define EnqueueCmd(cmdq, cmdqelmt)		\
-{										\
-	if (cmdq->size == 0)				\
-		cmdq->head = cmdqelmt;			\
-	else								\
-		cmdq->tail->next = cmdqelmt;	\
-	cmdq->tail = cmdqelmt;				\
-	cmdqelmt->next = NULL;				\
-	cmdq->size++;						\
-}
-
-/******************************************************************************
-
-	USB Cmd to ASIC Related MACRO
-
-******************************************************************************/
-/* reset MAC of a station entry to 0xFFFFFFFFFFFF */
-#define RTMP_STA_ENTRY_MAC_RESET(pAd, Wcid)					\
-	{	struct rt_set_asic_wcid	SetAsicWcid;						\
-		SetAsicWcid.WCID = Wcid;								\
-		SetAsicWcid.SetTid = 0xffffffff;						\
-		SetAsicWcid.DeleteTid = 0xffffffff;						\
-		RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_SET_ASIC_WCID,	\
-				&SetAsicWcid, sizeof(struct rt_set_asic_wcid));	}
-
-/* add this entry into ASIC RX WCID search table */
-#define RTMP_STA_ENTRY_ADD(pAd, pEntry)							\
-	RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_SET_CLIENT_MAC_ENTRY,	\
-							pEntry, sizeof(struct rt_mac_table_entry));
-
-/* add by johnli, fix "in_interrupt" error when call "MacTableDeleteEntry" in Rx tasklet */
-/* Set MAC register value according operation mode */
-#define RTMP_UPDATE_PROTECT(pAd)	\
-	RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_UPDATE_PROTECT, NULL, 0);
-/* end johnli */
-
-/* remove Pair-wise key material from ASIC */
-/* yet implement */
-#define RTMP_STA_ENTRY_KEY_DEL(pAd, BssIdx, Wcid)
-
-/* add Client security information into ASIC WCID table and IVEIV table */
-#define RTMP_STA_SECURITY_INFO_ADD(pAd, apidx, KeyID, pEntry)						\
-	{	RTMP_STA_ENTRY_MAC_RESET(pAd, pEntry->Aid);								\
-		if (pEntry->Aid >= 1) {														\
-			struct rt_set_asic_wcid_attri	SetAsicWcidAttri;								\
-			SetAsicWcidAttri.WCID = pEntry->Aid;									\
-			if ((pEntry->AuthMode <= Ndis802_11AuthModeAutoSwitch) &&				\
-				(pEntry->WepStatus == Ndis802_11Encryption1Enabled))				\
-			{																		\
-				SetAsicWcidAttri.Cipher = pAd->SharedKey[apidx][KeyID].CipherAlg;	\
-			}																		\
-			else if (pEntry->AuthMode == Ndis802_11AuthModeWPANone)					\
-			{																		\
-				SetAsicWcidAttri.Cipher = pAd->SharedKey[apidx][KeyID].CipherAlg;	\
-			}																		\
-			else SetAsicWcidAttri.Cipher = 0;										\
-            DBGPRINT(RT_DEBUG_TRACE, ("aid cipher = %ld\n",SetAsicWcidAttri.Cipher));       \
-			RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_SET_ASIC_WCID_CIPHER,			\
-							&SetAsicWcidAttri, sizeof(struct rt_set_asic_wcid_attri)); } }
-
-/* Insert the BA bitmap to ASIC for the Wcid entry */
-#define RTMP_ADD_BA_SESSION_TO_ASIC(_pAd, _Aid, _TID)					\
-		do{																\
-			struct rt_set_asic_wcid	SetAsicWcid;							\
-			SetAsicWcid.WCID = (_Aid);									\
-			SetAsicWcid.SetTid = (0x10000<<(_TID));						\
-			SetAsicWcid.DeleteTid = 0xffffffff;							\
-			RTUSBEnqueueInternalCmd((_pAd), CMDTHREAD_SET_ASIC_WCID, &SetAsicWcid, sizeof(struct rt_set_asic_wcid));	\
-		}while(0)
-
-/* Remove the BA bitmap from ASIC for the Wcid entry */
-#define RTMP_DEL_BA_SESSION_FROM_ASIC(_pAd, _Wcid, _TID)				\
-		do{																\
-			struct rt_set_asic_wcid	SetAsicWcid;							\
-			SetAsicWcid.WCID = (_Wcid);									\
-			SetAsicWcid.SetTid = (0xffffffff);							\
-			SetAsicWcid.DeleteTid = (0x10000<<(_TID) );					\
-			RTUSBEnqueueInternalCmd((_pAd), CMDTHREAD_SET_ASIC_WCID, &SetAsicWcid, sizeof(struct rt_set_asic_wcid));	\
-		}while(0)
-
-#endif /* __RTUSB_IO_H__ // */
diff -druN linux-2.6.39-libre/drivers/staging/rt2860/spectrum_def.h linux-3.0-rc7-libre/drivers/staging/rt2860/spectrum_def.h
--- linux-2.6.39-libre/drivers/staging/rt2860/spectrum_def.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rt2860/spectrum_def.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,202 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, 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.             *
- *                                                                       *
- *************************************************************************
-
-    Module Name:
-	spectrum_def.h
-
-    Abstract:
-    Handle association related requests either from WSTA or from local MLME
-
-    Revision History:
-    Who          When          What
-    ---------    ----------    ----------------------------------------------
-	Fonchi Wu    2008	  	   created for 802.11h
- */
-
-#ifndef __SPECTRUM_DEF_H__
-#define __SPECTRUM_DEF_H__
-
-#define MAX_MEASURE_REQ_TAB_SIZE		32
-#define MAX_HASH_MEASURE_REQ_TAB_SIZE	MAX_MEASURE_REQ_TAB_SIZE
-
-#define MAX_TPC_REQ_TAB_SIZE			32
-#define MAX_HASH_TPC_REQ_TAB_SIZE		MAX_TPC_REQ_TAB_SIZE
-
-#define MIN_RCV_PWR				100	/* Negative value ((dBm) */
-
-#define TPC_REQ_AGE_OUT			500	/* ms */
-#define MQ_REQ_AGE_OUT			500	/* ms */
-
-#define TPC_DIALOGTOKEN_HASH_INDEX(_DialogToken)	((_DialogToken) % MAX_HASH_TPC_REQ_TAB_SIZE)
-#define MQ_DIALOGTOKEN_HASH_INDEX(_DialogToken)		((_DialogToken) % MAX_MEASURE_REQ_TAB_SIZE)
-
-struct rt_measure_req_entry;
-
-struct rt_measure_req_entry {
-	struct rt_measure_req_entry *pNext;
-	unsigned long lastTime;
-	BOOLEAN Valid;
-	u8 DialogToken;
-	u8 MeasureDialogToken[3];	/* 0:basic measure, 1: CCA measure, 2: RPI_Histogram measure. */
-};
-
-struct rt_measure_req_tab {
-	u8 Size;
-	struct rt_measure_req_entry *Hash[MAX_HASH_MEASURE_REQ_TAB_SIZE];
-	struct rt_measure_req_entry Content[MAX_MEASURE_REQ_TAB_SIZE];
-};
-
-struct rt_tpc_req_entry;
-
-struct rt_tpc_req_entry {
-	struct rt_tpc_req_entry *pNext;
-	unsigned long lastTime;
-	BOOLEAN Valid;
-	u8 DialogToken;
-};
-
-struct rt_tpc_req_tab {
-	u8 Size;
-	struct rt_tpc_req_entry *Hash[MAX_HASH_TPC_REQ_TAB_SIZE];
-	struct rt_tpc_req_entry Content[MAX_TPC_REQ_TAB_SIZE];
-};
-
-/* The regulatory information */
-struct rt_dot11_channel_set {
-	u8 NumberOfChannels;
-	u8 MaxTxPwr;
-	u8 ChannelList[16];
-};
-
-struct rt_dot11_regulatory_information {
-	u8 RegulatoryClass;
-	struct rt_dot11_channel_set ChannelSet;
-};
-
-#define RM_TPC_REQ				0
-#define RM_MEASURE_REQ			1
-
-#define RM_BASIC				0
-#define RM_CCA					1
-#define RM_RPI_HISTOGRAM		2
-#define RM_CH_LOAD				3
-#define RM_NOISE_HISTOGRAM		4
-
-struct PACKED rt_tpc_report_info {
-	u8 TxPwr;
-	u8 LinkMargin;
-};
-
-struct PACKED rt_ch_sw_ann_info {
-	u8 ChSwMode;
-	u8 Channel;
-	u8 ChSwCnt;
-};
-
-typedef union PACKED _MEASURE_REQ_MODE {
-	struct PACKED {
-		u8 Parallel:1;
-		u8 Enable:1;
-		u8 Request:1;
-		u8 Report:1;
-		u8 DurationMandatory:1;
-		 u8:3;
-	} field;
-	u8 word;
-} MEASURE_REQ_MODE, *PMEASURE_REQ_MODE;
-
-struct PACKED rt_measure_req {
-	u8 ChNum;
-	u64 MeasureStartTime;
-	u16 MeasureDuration;
-};
-
-struct PACKED rt_measure_req_info {
-	u8 Token;
-	MEASURE_REQ_MODE ReqMode;
-	u8 ReqType;
-	u8 Oct[0];
-};
-
-typedef union PACKED _MEASURE_BASIC_REPORT_MAP {
-	struct PACKED {
-		u8 BSS:1;
-
-		u8 OfdmPreamble:1;
-		u8 UnidentifiedSignal:1;
-		u8 Radar:1;
-		u8 Unmeasure:1;
-		u8 Rev:3;
-	} field;
-	u8 word;
-} MEASURE_BASIC_REPORT_MAP, *PMEASURE_BASIC_REPORT_MAP;
-
-struct PACKED rt_measure_basic_report {
-	u8 ChNum;
-	u64 MeasureStartTime;
-	u16 MeasureDuration;
-	MEASURE_BASIC_REPORT_MAP Map;
-};
-
-struct PACKED rt_measure_cca_report {
-	u8 ChNum;
-	u64 MeasureStartTime;
-	u16 MeasureDuration;
-	u8 CCA_Busy_Fraction;
-};
-
-struct PACKED rt_measure_rpi_report {
-	u8 ChNum;
-	u64 MeasureStartTime;
-	u16 MeasureDuration;
-	u8 RPI_Density[8];
-};
-
-typedef union PACKED _MEASURE_REPORT_MODE {
-	struct PACKED {
-		u8 Late:1;
-		u8 Incapable:1;
-		u8 Refused:1;
-		u8 Rev:5;
-	} field;
-	u8 word;
-} MEASURE_REPORT_MODE, *PMEASURE_REPORT_MODE;
-
-struct PACKED rt_measure_report_info {
-	u8 Token;
-	u8 ReportMode;
-	u8 ReportType;
-	u8 Octect[0];
-};
-
-struct PACKED rt_quiet_info {
-	u8 QuietCnt;
-	u8 QuietPeriod;
-	u16 QuietDuration;
-	u16 QuietOffset;
-};
-
-#endif /* __SPECTRUM_DEF_H__ // */
diff -druN linux-2.6.39-libre/drivers/staging/rt2860/spectrum.h linux-3.0-rc7-libre/drivers/staging/rt2860/spectrum.h
--- linux-2.6.39-libre/drivers/staging/rt2860/spectrum.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rt2860/spectrum.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,189 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, 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 __SPECTRUM_H__
-#define __SPECTRUM_H__
-
-#include "rtmp_type.h"
-#include "spectrum_def.h"
-
-char RTMP_GetTxPwr(struct rt_rtmp_adapter *pAd, IN HTTRANSMIT_SETTING HTTxMode);
-
-/*
-	==========================================================================
-	Description:
-		Prepare Measurement request action frame and enqueue it into
-		management queue waiting for transmission.
-
-	Parametrs:
-		1. the destination mac address of the frame.
-
-	Return	: None.
-	==========================================================================
- */
-void MakeMeasurementReqFrame(struct rt_rtmp_adapter *pAd,
-			     u8 *pOutBuffer,
-			     unsigned long *pFrameLen,
-			     u8 TotalLen,
-			     u8 Category,
-			     u8 Action,
-			     u8 MeasureToken,
-			     u8 MeasureReqMode,
-			     u8 MeasureReqType,
-			     u8 NumOfRepetitions);
-
-/*
-	==========================================================================
-	Description:
-		Prepare Measurement report action frame and enqueue it into
-		management queue waiting for transmission.
-
-	Parametrs:
-		1. the destination mac address of the frame.
-
-	Return	: None.
-	==========================================================================
- */
-void EnqueueMeasurementRep(struct rt_rtmp_adapter *pAd,
-			   u8 *pDA,
-			   u8 DialogToken,
-			   u8 MeasureToken,
-			   u8 MeasureReqMode,
-			   u8 MeasureReqType,
-			   u8 ReportInfoLen, u8 *pReportInfo);
-
-/*
-	==========================================================================
-	Description:
-		Prepare TPC Request action frame and enqueue it into
-		management queue waiting for transmission.
-
-	Parametrs:
-		1. the destination mac address of the frame.
-
-	Return	: None.
-	==========================================================================
- */
-void EnqueueTPCReq(struct rt_rtmp_adapter *pAd, u8 *pDA, u8 DialogToken);
-
-/*
-	==========================================================================
-	Description:
-		Prepare TPC Report action frame and enqueue it into
-		management queue waiting for transmission.
-
-	Parametrs:
-		1. the destination mac address of the frame.
-
-	Return	: None.
-	==========================================================================
- */
-void EnqueueTPCRep(struct rt_rtmp_adapter *pAd,
-		   u8 *pDA,
-		   u8 DialogToken, u8 TxPwr, u8 LinkMargin);
-
-/*
-	==========================================================================
-	Description:
-		Prepare Channel Switch Announcement action frame and enqueue it into
-		management queue waiting for transmission.
-
-	Parametrs:
-		1. the destination mac address of the frame.
-		2. Channel switch announcement mode.
-		2. a New selected channel.
-
-	Return	: None.
-	==========================================================================
- */
-void EnqueueChSwAnn(struct rt_rtmp_adapter *pAd,
-		    u8 *pDA, u8 ChSwMode, u8 NewCh);
-
-/*
-	==========================================================================
-	Description:
-		Spectrun action frames Handler such as channel switch announcement,
-		measurement report, measurement request actions frames.
-
-	Parametrs:
-		Elme - MLME message containing the received frame
-
-	Return	: None.
-	==========================================================================
- */
-void PeerSpectrumAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem);
-
-/*
-	==========================================================================
-	Description:
-
-	Parametrs:
-
-	Return	: None.
-	==========================================================================
- */
-int Set_MeasureReq_Proc(struct rt_rtmp_adapter *pAd, char *arg);
-
-int Set_TpcReq_Proc(struct rt_rtmp_adapter *pAd, char *arg);
-
-int Set_PwrConstraint(struct rt_rtmp_adapter *pAd, char *arg);
-
-void MeasureReqTabInit(struct rt_rtmp_adapter *pAd);
-
-void MeasureReqTabExit(struct rt_rtmp_adapter *pAd);
-
-struct rt_measure_req_entry *MeasureReqLookUp(struct rt_rtmp_adapter *pAd, u8 DialogToken);
-
-struct rt_measure_req_entry *MeasureReqInsert(struct rt_rtmp_adapter *pAd, u8 DialogToken);
-
-void MeasureReqDelete(struct rt_rtmp_adapter *pAd, u8 DialogToken);
-
-void InsertChannelRepIE(struct rt_rtmp_adapter *pAd,
-			u8 *pFrameBuf,
-			unsigned long *pFrameLen,
-			char *pCountry, u8 RegulatoryClass);
-
-void InsertTpcReportIE(struct rt_rtmp_adapter *pAd,
-		       u8 *pFrameBuf,
-		       unsigned long *pFrameLen,
-		       u8 TxPwr, u8 LinkMargin);
-
-void InsertDialogToken(struct rt_rtmp_adapter *pAd,
-		       u8 *pFrameBuf,
-		       unsigned long *pFrameLen, u8 DialogToken);
-
-void TpcReqTabInit(struct rt_rtmp_adapter *pAd);
-
-void TpcReqTabExit(struct rt_rtmp_adapter *pAd);
-
-void NotifyChSwAnnToPeerAPs(struct rt_rtmp_adapter *pAd,
-			    u8 *pRA,
-			    u8 *pTA, u8 ChSwMode, u8 Channel);
-
-void RguClass_BuildBcnChList(struct rt_rtmp_adapter *pAd,
-			     u8 *pBuf, unsigned long *pBufLen);
-#endif /* __SPECTRUM_H__ // */
diff -druN linux-2.6.39-libre/drivers/staging/rt2860/sta/assoc.c linux-3.0-rc7-libre/drivers/staging/rt2860/sta/assoc.c
--- linux-2.6.39-libre/drivers/staging/rt2860/sta/assoc.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rt2860/sta/assoc.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,1602 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, 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.             *
- *                                                                       *
- *************************************************************************
-
-	Module Name:
-	assoc.c
-
-	Abstract:
-
-	Revision History:
-	Who			When			What
-	--------	----------		----------------------------------------------
-	John			2004-9-3		porting from RT2500
-	Justin P. Mattock	11/07/2010		Fix typos
-*/
-#include "../rt_config.h"
-
-u8 CipherWpaTemplate[] = {
-	0xdd,			/* WPA IE */
-	0x16,			/* Length */
-	0x00, 0x50, 0xf2, 0x01,	/* oui */
-	0x01, 0x00,		/* Version */
-	0x00, 0x50, 0xf2, 0x02,	/* Multicast */
-	0x01, 0x00,		/* Number of unicast */
-	0x00, 0x50, 0xf2, 0x02,	/* unicast */
-	0x01, 0x00,		/* number of authentication method */
-	0x00, 0x50, 0xf2, 0x01	/* authentication */
-};
-
-u8 CipherWpa2Template[] = {
-	0x30,			/* RSN IE */
-	0x14,			/* Length */
-	0x01, 0x00,		/* Version */
-	0x00, 0x0f, 0xac, 0x02,	/* group cipher, TKIP */
-	0x01, 0x00,		/* number of pairwise */
-	0x00, 0x0f, 0xac, 0x02,	/* unicast */
-	0x01, 0x00,		/* number of authentication method */
-	0x00, 0x0f, 0xac, 0x02,	/* authentication */
-	0x00, 0x00,		/* RSN capability */
-};
-
-u8 Ccx2IeInfo[] = { 0x00, 0x40, 0x96, 0x03, 0x02 };
-
-/*
-	==========================================================================
-	Description:
-		association state machine init, including state transition and timer init
-	Parameters:
-		S - pointer to the association state machine
-
-	IRQL = PASSIVE_LEVEL
-
-	==========================================================================
- */
-void AssocStateMachineInit(struct rt_rtmp_adapter *pAd,
-			   struct rt_state_machine *S, OUT STATE_MACHINE_FUNC Trans[])
-{
-	StateMachineInit(S, Trans, MAX_ASSOC_STATE, MAX_ASSOC_MSG,
-			 (STATE_MACHINE_FUNC) Drop, ASSOC_IDLE,
-			 ASSOC_MACHINE_BASE);
-
-	/* first column */
-	StateMachineSetAction(S, ASSOC_IDLE, MT2_MLME_ASSOC_REQ,
-			      (STATE_MACHINE_FUNC) MlmeAssocReqAction);
-	StateMachineSetAction(S, ASSOC_IDLE, MT2_MLME_REASSOC_REQ,
-			      (STATE_MACHINE_FUNC) MlmeReassocReqAction);
-	StateMachineSetAction(S, ASSOC_IDLE, MT2_MLME_DISASSOC_REQ,
-			      (STATE_MACHINE_FUNC) MlmeDisassocReqAction);
-	StateMachineSetAction(S, ASSOC_IDLE, MT2_PEER_DISASSOC_REQ,
-			      (STATE_MACHINE_FUNC) PeerDisassocAction);
-
-	/* second column */
-	StateMachineSetAction(S, ASSOC_WAIT_RSP, MT2_MLME_ASSOC_REQ,
-			      (STATE_MACHINE_FUNC) InvalidStateWhenAssoc);
-	StateMachineSetAction(S, ASSOC_WAIT_RSP, MT2_MLME_REASSOC_REQ,
-			      (STATE_MACHINE_FUNC) InvalidStateWhenReassoc);
-	StateMachineSetAction(S, ASSOC_WAIT_RSP, MT2_MLME_DISASSOC_REQ,
-			      (STATE_MACHINE_FUNC)
-			      InvalidStateWhenDisassociate);
-	StateMachineSetAction(S, ASSOC_WAIT_RSP, MT2_PEER_DISASSOC_REQ,
-			      (STATE_MACHINE_FUNC) PeerDisassocAction);
-	StateMachineSetAction(S, ASSOC_WAIT_RSP, MT2_PEER_ASSOC_RSP,
-			      (STATE_MACHINE_FUNC) PeerAssocRspAction);
-	/* */
-	/* Patch 3Com AP MOde:3CRWE454G72 */
-	/* We send Assoc request frame to this AP, it always send Reassoc Rsp not Associate Rsp. */
-	/* */
-	StateMachineSetAction(S, ASSOC_WAIT_RSP, MT2_PEER_REASSOC_RSP,
-			      (STATE_MACHINE_FUNC) PeerAssocRspAction);
-	StateMachineSetAction(S, ASSOC_WAIT_RSP, MT2_ASSOC_TIMEOUT,
-			      (STATE_MACHINE_FUNC) AssocTimeoutAction);
-
-	/* third column */
-	StateMachineSetAction(S, REASSOC_WAIT_RSP, MT2_MLME_ASSOC_REQ,
-			      (STATE_MACHINE_FUNC) InvalidStateWhenAssoc);
-	StateMachineSetAction(S, REASSOC_WAIT_RSP, MT2_MLME_REASSOC_REQ,
-			      (STATE_MACHINE_FUNC) InvalidStateWhenReassoc);
-	StateMachineSetAction(S, REASSOC_WAIT_RSP, MT2_MLME_DISASSOC_REQ,
-			      (STATE_MACHINE_FUNC)
-			      InvalidStateWhenDisassociate);
-	StateMachineSetAction(S, REASSOC_WAIT_RSP, MT2_PEER_DISASSOC_REQ,
-			      (STATE_MACHINE_FUNC) PeerDisassocAction);
-	StateMachineSetAction(S, REASSOC_WAIT_RSP, MT2_PEER_REASSOC_RSP,
-			      (STATE_MACHINE_FUNC) PeerReassocRspAction);
-	/* */
-	/* Patch, AP doesn't send Reassociate Rsp frame to Station. */
-	/* */
-	StateMachineSetAction(S, REASSOC_WAIT_RSP, MT2_PEER_ASSOC_RSP,
-			      (STATE_MACHINE_FUNC) PeerReassocRspAction);
-	StateMachineSetAction(S, REASSOC_WAIT_RSP, MT2_REASSOC_TIMEOUT,
-			      (STATE_MACHINE_FUNC) ReassocTimeoutAction);
-
-	/* fourth column */
-	StateMachineSetAction(S, DISASSOC_WAIT_RSP, MT2_MLME_ASSOC_REQ,
-			      (STATE_MACHINE_FUNC) InvalidStateWhenAssoc);
-	StateMachineSetAction(S, DISASSOC_WAIT_RSP, MT2_MLME_REASSOC_REQ,
-			      (STATE_MACHINE_FUNC) InvalidStateWhenReassoc);
-	StateMachineSetAction(S, DISASSOC_WAIT_RSP, MT2_MLME_DISASSOC_REQ,
-			      (STATE_MACHINE_FUNC)
-			      InvalidStateWhenDisassociate);
-	StateMachineSetAction(S, DISASSOC_WAIT_RSP, MT2_PEER_DISASSOC_REQ,
-			      (STATE_MACHINE_FUNC) PeerDisassocAction);
-	StateMachineSetAction(S, DISASSOC_WAIT_RSP, MT2_DISASSOC_TIMEOUT,
-			      (STATE_MACHINE_FUNC) DisassocTimeoutAction);
-
-	/* initialize the timer */
-	RTMPInitTimer(pAd, &pAd->MlmeAux.AssocTimer,
-		      GET_TIMER_FUNCTION(AssocTimeout), pAd, FALSE);
-	RTMPInitTimer(pAd, &pAd->MlmeAux.ReassocTimer,
-		      GET_TIMER_FUNCTION(ReassocTimeout), pAd, FALSE);
-	RTMPInitTimer(pAd, &pAd->MlmeAux.DisassocTimer,
-		      GET_TIMER_FUNCTION(DisassocTimeout), pAd, FALSE);
-}
-
-/*
-	==========================================================================
-	Description:
-		Association timeout procedure. After association timeout, this function
-		will be called and it will put a message into the MLME queue
-	Parameters:
-		Standard timer parameters
-
-	IRQL = DISPATCH_LEVEL
-
-	==========================================================================
- */
-void AssocTimeout(void *SystemSpecific1,
-		  void *FunctionContext,
-		  void *SystemSpecific2, void *SystemSpecific3)
-{
-	struct rt_rtmp_adapter *pAd = (struct rt_rtmp_adapter *)FunctionContext;
-
-	/* Do nothing if the driver is starting halt state. */
-	/* This might happen when timer already been fired before cancel timer with mlmehalt */
-	if (RTMP_TEST_FLAG
-	    (pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST))
-		return;
-
-	MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_ASSOC_TIMEOUT, 0, NULL);
-	RTMP_MLME_HANDLER(pAd);
-}
-
-/*
-	==========================================================================
-	Description:
-		Reassociation timeout procedure. After reassociation timeout, this
-		function will be called and put a message into the MLME queue
-	Parameters:
-		Standard timer parameters
-
-	IRQL = DISPATCH_LEVEL
-
-	==========================================================================
- */
-void ReassocTimeout(void *SystemSpecific1,
-		    void *FunctionContext,
-		    void *SystemSpecific2, void *SystemSpecific3)
-{
-	struct rt_rtmp_adapter *pAd = (struct rt_rtmp_adapter *)FunctionContext;
-
-	/* Do nothing if the driver is starting halt state. */
-	/* This might happen when timer already been fired before cancel timer with mlmehalt */
-	if (RTMP_TEST_FLAG
-	    (pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST))
-		return;
-
-	MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_REASSOC_TIMEOUT, 0, NULL);
-	RTMP_MLME_HANDLER(pAd);
-}
-
-/*
-	==========================================================================
-	Description:
-		Disassociation timeout procedure. After disassociation timeout, this
-		function will be called and put a message into the MLME queue
-	Parameters:
-		Standard timer parameters
-
-	IRQL = DISPATCH_LEVEL
-
-	==========================================================================
- */
-void DisassocTimeout(void *SystemSpecific1,
-		     void *FunctionContext,
-		     void *SystemSpecific2, void *SystemSpecific3)
-{
-	struct rt_rtmp_adapter *pAd = (struct rt_rtmp_adapter *)FunctionContext;
-
-	/* Do nothing if the driver is starting halt state. */
-	/* This might happen when timer already been fired before cancel timer with mlmehalt */
-	if (RTMP_TEST_FLAG
-	    (pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST))
-		return;
-
-	MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_DISASSOC_TIMEOUT, 0, NULL);
-	RTMP_MLME_HANDLER(pAd);
-}
-
-/*
-	==========================================================================
-	Description:
-		mlme assoc req handling procedure
-	Parameters:
-		Adapter - Adapter pointer
-		Elem - MLME Queue Element
-	Pre:
-		the station has been authenticated and the following information is stored in the config
-			-# SSID
-			-# supported rates and their length
-			-# listen interval (Adapter->StaCfg.default_listen_count)
-			-# Transmit power  (Adapter->StaCfg.tx_power)
-	Post  :
-		-# An association request frame is generated and sent to the air
-		-# Association timer starts
-		-# Association state -> ASSOC_WAIT_RSP
-
-	IRQL = DISPATCH_LEVEL
-
-	==========================================================================
- */
-void MlmeAssocReqAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
-{
-	u8 ApAddr[6];
-	struct rt_header_802_11 AssocHdr;
-	u8 WmeIe[9] =
-	    { IE_VENDOR_SPECIFIC, 0x07, 0x00, 0x50, 0xf2, 0x02, 0x00, 0x01,
-       0x00 };
-	u16 ListenIntv;
-	unsigned long Timeout;
-	u16 CapabilityInfo;
-	BOOLEAN TimerCancelled;
-	u8 *pOutBuffer = NULL;
-	int NStatus;
-	unsigned long FrameLen = 0;
-	unsigned long tmp;
-	u16 VarIesOffset;
-	u16 Status;
-
-	/* Block all authentication request during WPA block period */
-	if (pAd->StaCfg.bBlockAssoc == TRUE) {
-		DBGPRINT(RT_DEBUG_TRACE,
-			 ("ASSOC - Block Assoc request during WPA block period!\n"));
-		pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
-		Status = MLME_STATE_MACHINE_REJECT;
-		MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_ASSOC_CONF, 2,
-			    &Status);
-	}
-	/* check sanity first */
-	else if (MlmeAssocReqSanity
-		 (pAd, Elem->Msg, Elem->MsgLen, ApAddr, &CapabilityInfo,
-		  &Timeout, &ListenIntv)) {
-		RTMPCancelTimer(&pAd->MlmeAux.AssocTimer, &TimerCancelled);
-		COPY_MAC_ADDR(pAd->MlmeAux.Bssid, ApAddr);
-
-		/* Get an unused nonpaged memory */
-		NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);
-		if (NStatus != NDIS_STATUS_SUCCESS) {
-			DBGPRINT(RT_DEBUG_TRACE,
-				 ("ASSOC - MlmeAssocReqAction() allocate memory failed \n"));
-			pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
-			Status = MLME_FAIL_NO_RESOURCE;
-			MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE,
-				    MT2_ASSOC_CONF, 2, &Status);
-			return;
-		}
-		/* Add by James 03/06/27 */
-		pAd->StaCfg.AssocInfo.Length =
-		    sizeof(struct rt_ndis_802_11_association_information);
-		/* Association don't need to report MAC address */
-		pAd->StaCfg.AssocInfo.AvailableRequestFixedIEs =
-		    NDIS_802_11_AI_REQFI_CAPABILITIES |
-		    NDIS_802_11_AI_REQFI_LISTENINTERVAL;
-		pAd->StaCfg.AssocInfo.RequestFixedIEs.Capabilities =
-		    CapabilityInfo;
-		pAd->StaCfg.AssocInfo.RequestFixedIEs.ListenInterval =
-		    ListenIntv;
-		/* Only reassociate need this */
-		/*COPY_MAC_ADDR(pAd->StaCfg.AssocInfo.RequestFixedIEs.CurrentAPAddress, ApAddr); */
-		pAd->StaCfg.AssocInfo.OffsetRequestIEs =
-		    sizeof(struct rt_ndis_802_11_association_information);
-
-		NdisZeroMemory(pAd->StaCfg.ReqVarIEs, MAX_VIE_LEN);
-		/* First add SSID */
-		VarIesOffset = 0;
-		NdisMoveMemory(pAd->StaCfg.ReqVarIEs + VarIesOffset, &SsidIe,
-			       1);
-		VarIesOffset += 1;
-		NdisMoveMemory(pAd->StaCfg.ReqVarIEs + VarIesOffset,
-			       &pAd->MlmeAux.SsidLen, 1);
-		VarIesOffset += 1;
-		NdisMoveMemory(pAd->StaCfg.ReqVarIEs + VarIesOffset,
-			       pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen);
-		VarIesOffset += pAd->MlmeAux.SsidLen;
-
-		/* Second add Supported rates */
-		NdisMoveMemory(pAd->StaCfg.ReqVarIEs + VarIesOffset, &SupRateIe,
-			       1);
-		VarIesOffset += 1;
-		NdisMoveMemory(pAd->StaCfg.ReqVarIEs + VarIesOffset,
-			       &pAd->MlmeAux.SupRateLen, 1);
-		VarIesOffset += 1;
-		NdisMoveMemory(pAd->StaCfg.ReqVarIEs + VarIesOffset,
-			       pAd->MlmeAux.SupRate, pAd->MlmeAux.SupRateLen);
-		VarIesOffset += pAd->MlmeAux.SupRateLen;
-		/* End Add by James */
-
-		if ((pAd->CommonCfg.Channel > 14) &&
-		    (pAd->CommonCfg.bIEEE80211H == TRUE))
-			CapabilityInfo |= 0x0100;
-
-		DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - Send ASSOC request...\n"));
-		MgtMacHeaderInit(pAd, &AssocHdr, SUBTYPE_ASSOC_REQ, 0, ApAddr,
-				 ApAddr);
-
-		/* Build basic frame first */
-		MakeOutgoingFrame(pOutBuffer, &FrameLen,
-				  sizeof(struct rt_header_802_11), &AssocHdr,
-				  2, &CapabilityInfo,
-				  2, &ListenIntv,
-				  1, &SsidIe,
-				  1, &pAd->MlmeAux.SsidLen,
-				  pAd->MlmeAux.SsidLen, pAd->MlmeAux.Ssid,
-				  1, &SupRateIe,
-				  1, &pAd->MlmeAux.SupRateLen,
-				  pAd->MlmeAux.SupRateLen, pAd->MlmeAux.SupRate,
-				  END_OF_ARGS);
-
-		if (pAd->MlmeAux.ExtRateLen != 0) {
-			MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp,
-					  1, &ExtRateIe,
-					  1, &pAd->MlmeAux.ExtRateLen,
-					  pAd->MlmeAux.ExtRateLen,
-					  pAd->MlmeAux.ExtRate, END_OF_ARGS);
-			FrameLen += tmp;
-		}
-		/* HT */
-		if ((pAd->MlmeAux.HtCapabilityLen > 0)
-		    && (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED)) {
-			unsigned long TmpLen;
-			u8 HtLen;
-			u8 BROADCOM[4] = { 0x0, 0x90, 0x4c, 0x33 };
-			if (pAd->StaActive.SupportedPhyInfo.bPreNHt == TRUE) {
-				HtLen = SIZE_HT_CAP_IE + 4;
-				MakeOutgoingFrame(pOutBuffer + FrameLen,
-						  &TmpLen, 1, &WpaIe, 1, &HtLen,
-						  4, &BROADCOM[0],
-						  pAd->MlmeAux.HtCapabilityLen,
-						  &pAd->MlmeAux.HtCapability,
-						  END_OF_ARGS);
-			} else {
-				MakeOutgoingFrame(pOutBuffer + FrameLen,
-						  &TmpLen, 1, &HtCapIe, 1,
-						  &pAd->MlmeAux.HtCapabilityLen,
-						  pAd->MlmeAux.HtCapabilityLen,
-						  &pAd->MlmeAux.HtCapability,
-						  END_OF_ARGS);
-			}
-			FrameLen += TmpLen;
-		}
-		/* add Ralink proprietary IE to inform AP this STA is going to use AGGREGATION or PIGGY-BACK+AGGREGATION */
-		/* Case I: (Aggregation + Piggy-Back) */
-		/* 1. user enable aggregation, AND */
-		/* 2. Mac support piggy-back */
-		/* 3. AP annouces it's PIGGY-BACK+AGGREGATION-capable in BEACON */
-		/* Case II: (Aggregation) */
-		/* 1. user enable aggregation, AND */
-		/* 2. AP annouces it's AGGREGATION-capable in BEACON */
-		if (pAd->CommonCfg.bAggregationCapable) {
-			if ((pAd->CommonCfg.bPiggyBackCapable)
-			    && ((pAd->MlmeAux.APRalinkIe & 0x00000003) == 3)) {
-				unsigned long TmpLen;
-				u8 RalinkIe[9] =
-				    { IE_VENDOR_SPECIFIC, 7, 0x00, 0x0c, 0x43,
-			    0x03, 0x00, 0x00, 0x00 };
-				MakeOutgoingFrame(pOutBuffer + FrameLen,
-						  &TmpLen, 9, RalinkIe,
-						  END_OF_ARGS);
-				FrameLen += TmpLen;
-			} else if (pAd->MlmeAux.APRalinkIe & 0x00000001) {
-				unsigned long TmpLen;
-				u8 RalinkIe[9] =
-				    { IE_VENDOR_SPECIFIC, 7, 0x00, 0x0c, 0x43,
-			    0x01, 0x00, 0x00, 0x00 };
-				MakeOutgoingFrame(pOutBuffer + FrameLen,
-						  &TmpLen, 9, RalinkIe,
-						  END_OF_ARGS);
-				FrameLen += TmpLen;
-			}
-		} else {
-			unsigned long TmpLen;
-			u8 RalinkIe[9] =
-			    { IE_VENDOR_SPECIFIC, 7, 0x00, 0x0c, 0x43, 0x06,
-		    0x00, 0x00, 0x00 };
-			MakeOutgoingFrame(pOutBuffer + FrameLen, &TmpLen, 9,
-					  RalinkIe, END_OF_ARGS);
-			FrameLen += TmpLen;
-		}
-
-		if (pAd->MlmeAux.APEdcaParm.bValid) {
-			if (pAd->CommonCfg.bAPSDCapable
-			    && pAd->MlmeAux.APEdcaParm.bAPSDCapable) {
-				struct rt_qbss_sta_info_parm QosInfo;
-
-				NdisZeroMemory(&QosInfo,
-					       sizeof(struct rt_qbss_sta_info_parm));
-				QosInfo.UAPSD_AC_BE = pAd->CommonCfg.bAPSDAC_BE;
-				QosInfo.UAPSD_AC_BK = pAd->CommonCfg.bAPSDAC_BK;
-				QosInfo.UAPSD_AC_VI = pAd->CommonCfg.bAPSDAC_VI;
-				QosInfo.UAPSD_AC_VO = pAd->CommonCfg.bAPSDAC_VO;
-				QosInfo.MaxSPLength =
-				    pAd->CommonCfg.MaxSPLength;
-				WmeIe[8] |= *(u8 *)& QosInfo;
-			} else {
-				/* The Parameter Set Count is set to ��0�� in the association request frames */
-				/* WmeIe[8] |= (pAd->MlmeAux.APEdcaParm.EdcaUpdateCount & 0x0f); */
-			}
-
-			MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp,
-					  9, &WmeIe[0], END_OF_ARGS);
-			FrameLen += tmp;
-		}
-		/* */
-		/* Let WPA(#221) Element ID on the end of this association frame. */
-		/* Otherwise some AP will fail on parsing Element ID and set status fail on Assoc Rsp. */
-		/* For example: Put Vendor Specific IE on the front of WPA IE. */
-		/* This happens on AP (Model No:Linksys WRK54G) */
-		/* */
-		if (((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK) ||
-		     (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK) ||
-		     (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) ||
-		     (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2)
-		    )
-		    ) {
-			u8 RSNIe = IE_WPA;
-
-			if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK)
-			    || (pAd->StaCfg.AuthMode ==
-				Ndis802_11AuthModeWPA2)) {
-				RSNIe = IE_WPA2;
-			}
-
-			if ((pAd->StaCfg.WpaSupplicantUP !=
-			     WPA_SUPPLICANT_ENABLE)
-			    && (pAd->StaCfg.bRSN_IE_FromWpaSupplicant == FALSE))
-				RTMPMakeRSNIE(pAd, pAd->StaCfg.AuthMode,
-					      pAd->StaCfg.WepStatus, BSS0);
-
-			/* Check for WPA PMK cache list */
-			if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) {
-				int idx;
-				BOOLEAN FoundPMK = FALSE;
-				/* Search chched PMKID, append it if existed */
-				for (idx = 0; idx < PMKID_NO; idx++) {
-					if (NdisEqualMemory
-					    (ApAddr,
-					     &pAd->StaCfg.SavedPMK[idx].BSSID,
-					     6)) {
-						FoundPMK = TRUE;
-						break;
-					}
-				}
-				if (FoundPMK) {
-					/* Set PMK number */
-					*(u16 *)& pAd->StaCfg.RSN_IE[pAd->
-									StaCfg.
-									RSNIE_Len]
-					    = 1;
-					NdisMoveMemory(&pAd->StaCfg.
-						       RSN_IE[pAd->StaCfg.
-							      RSNIE_Len + 2],
-						       &pAd->StaCfg.
-						       SavedPMK[idx].PMKID, 16);
-					pAd->StaCfg.RSNIE_Len += 18;
-				}
-			}
-
-			if ((pAd->StaCfg.WpaSupplicantUP ==
-			     WPA_SUPPLICANT_ENABLE)
-			    && (pAd->StaCfg.bRSN_IE_FromWpaSupplicant ==
-				TRUE)) {
-				MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp,
-						  pAd->StaCfg.RSNIE_Len,
-						  pAd->StaCfg.RSN_IE,
-						  END_OF_ARGS);
-			} else {
-				MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp,
-						  1, &RSNIe,
-						  1, &pAd->StaCfg.RSNIE_Len,
-						  pAd->StaCfg.RSNIE_Len,
-						  pAd->StaCfg.RSN_IE,
-						  END_OF_ARGS);
-			}
-
-			FrameLen += tmp;
-
-			if ((pAd->StaCfg.WpaSupplicantUP !=
-			     WPA_SUPPLICANT_ENABLE)
-			    || (pAd->StaCfg.bRSN_IE_FromWpaSupplicant ==
-				FALSE)) {
-				/* Append Variable IE */
-				NdisMoveMemory(pAd->StaCfg.ReqVarIEs +
-					       VarIesOffset, &RSNIe, 1);
-				VarIesOffset += 1;
-				NdisMoveMemory(pAd->StaCfg.ReqVarIEs +
-					       VarIesOffset,
-					       &pAd->StaCfg.RSNIE_Len, 1);
-				VarIesOffset += 1;
-			}
-			NdisMoveMemory(pAd->StaCfg.ReqVarIEs + VarIesOffset,
-				       pAd->StaCfg.RSN_IE,
-				       pAd->StaCfg.RSNIE_Len);
-			VarIesOffset += pAd->StaCfg.RSNIE_Len;
-
-			/* Set Variable IEs Length */
-			pAd->StaCfg.ReqVarIELen = VarIesOffset;
-		}
-
-		MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
-		MlmeFreeMemory(pAd, pOutBuffer);
-
-		RTMPSetTimer(&pAd->MlmeAux.AssocTimer, Timeout);
-		pAd->Mlme.AssocMachine.CurrState = ASSOC_WAIT_RSP;
-	} else {
-		DBGPRINT(RT_DEBUG_TRACE,
-			 ("ASSOC - MlmeAssocReqAction() sanity check failed. BUG!\n"));
-		pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
-		Status = MLME_INVALID_FORMAT;
-		MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_ASSOC_CONF, 2,
-			    &Status);
-	}
-
-}
-
-/*
-	==========================================================================
-	Description:
-		mlme reassoc req handling procedure
-	Parameters:
-		Elem -
-	Pre:
-		-# SSID  (Adapter->StaCfg.ssid[])
-		-# BSSID (AP address, Adapter->StaCfg.bssid)
-		-# Supported rates (Adapter->StaCfg.supported_rates[])
-		-# Supported rates length (Adapter->StaCfg.supported_rates_len)
-		-# Tx power (Adapter->StaCfg.tx_power)
-
-	IRQL = DISPATCH_LEVEL
-
-	==========================================================================
- */
-void MlmeReassocReqAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
-{
-	u8 ApAddr[6];
-	struct rt_header_802_11 ReassocHdr;
-	u8 WmeIe[9] =
-	    { IE_VENDOR_SPECIFIC, 0x07, 0x00, 0x50, 0xf2, 0x02, 0x00, 0x01,
-       0x00 };
-	u16 CapabilityInfo, ListenIntv;
-	unsigned long Timeout;
-	unsigned long FrameLen = 0;
-	BOOLEAN TimerCancelled;
-	int NStatus;
-	unsigned long tmp;
-	u8 *pOutBuffer = NULL;
-	u16 Status;
-
-	/* Block all authentication request during WPA block period */
-	if (pAd->StaCfg.bBlockAssoc == TRUE) {
-		DBGPRINT(RT_DEBUG_TRACE,
-			 ("ASSOC - Block ReAssoc request during WPA block period!\n"));
-		pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
-		Status = MLME_STATE_MACHINE_REJECT;
-		MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_REASSOC_CONF, 2,
-			    &Status);
-	}
-	/* the parameters are the same as the association */
-	else if (MlmeAssocReqSanity
-		 (pAd, Elem->Msg, Elem->MsgLen, ApAddr, &CapabilityInfo,
-		  &Timeout, &ListenIntv)) {
-		RTMPCancelTimer(&pAd->MlmeAux.ReassocTimer, &TimerCancelled);
-
-		NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);	/*Get an unused nonpaged memory */
-		if (NStatus != NDIS_STATUS_SUCCESS) {
-			DBGPRINT(RT_DEBUG_TRACE,
-				 ("ASSOC - MlmeReassocReqAction() allocate memory failed \n"));
-			pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
-			Status = MLME_FAIL_NO_RESOURCE;
-			MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE,
-				    MT2_REASSOC_CONF, 2, &Status);
-			return;
-		}
-
-		COPY_MAC_ADDR(pAd->MlmeAux.Bssid, ApAddr);
-
-		/* make frame, use bssid as the AP address?? */
-		DBGPRINT(RT_DEBUG_TRACE,
-			 ("ASSOC - Send RE-ASSOC request...\n"));
-		MgtMacHeaderInit(pAd, &ReassocHdr, SUBTYPE_REASSOC_REQ, 0,
-				 ApAddr, ApAddr);
-		MakeOutgoingFrame(pOutBuffer, &FrameLen, sizeof(struct rt_header_802_11),
-				  &ReassocHdr, 2, &CapabilityInfo, 2,
-				  &ListenIntv, MAC_ADDR_LEN, ApAddr, 1, &SsidIe,
-				  1, &pAd->MlmeAux.SsidLen,
-				  pAd->MlmeAux.SsidLen, pAd->MlmeAux.Ssid, 1,
-				  &SupRateIe, 1, &pAd->MlmeAux.SupRateLen,
-				  pAd->MlmeAux.SupRateLen, pAd->MlmeAux.SupRate,
-				  END_OF_ARGS);
-
-		if (pAd->MlmeAux.ExtRateLen != 0) {
-			MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp,
-					  1, &ExtRateIe,
-					  1, &pAd->MlmeAux.ExtRateLen,
-					  pAd->MlmeAux.ExtRateLen,
-					  pAd->MlmeAux.ExtRate, END_OF_ARGS);
-			FrameLen += tmp;
-		}
-
-		if (pAd->MlmeAux.APEdcaParm.bValid) {
-			if (pAd->CommonCfg.bAPSDCapable
-			    && pAd->MlmeAux.APEdcaParm.bAPSDCapable) {
-				struct rt_qbss_sta_info_parm QosInfo;
-
-				NdisZeroMemory(&QosInfo,
-					       sizeof(struct rt_qbss_sta_info_parm));
-				QosInfo.UAPSD_AC_BE = pAd->CommonCfg.bAPSDAC_BE;
-				QosInfo.UAPSD_AC_BK = pAd->CommonCfg.bAPSDAC_BK;
-				QosInfo.UAPSD_AC_VI = pAd->CommonCfg.bAPSDAC_VI;
-				QosInfo.UAPSD_AC_VO = pAd->CommonCfg.bAPSDAC_VO;
-				QosInfo.MaxSPLength =
-				    pAd->CommonCfg.MaxSPLength;
-				WmeIe[8] |= *(u8 *)& QosInfo;
-			}
-
-			MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp,
-					  9, &WmeIe[0], END_OF_ARGS);
-			FrameLen += tmp;
-		}
-		/* HT */
-		if ((pAd->MlmeAux.HtCapabilityLen > 0)
-		    && (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED)) {
-			unsigned long TmpLen;
-			u8 HtLen;
-			u8 BROADCOM[4] = { 0x0, 0x90, 0x4c, 0x33 };
-			if (pAd->StaActive.SupportedPhyInfo.bPreNHt == TRUE) {
-				HtLen = SIZE_HT_CAP_IE + 4;
-				MakeOutgoingFrame(pOutBuffer + FrameLen,
-						  &TmpLen, 1, &WpaIe, 1, &HtLen,
-						  4, &BROADCOM[0],
-						  pAd->MlmeAux.HtCapabilityLen,
-						  &pAd->MlmeAux.HtCapability,
-						  END_OF_ARGS);
-			} else {
-				MakeOutgoingFrame(pOutBuffer + FrameLen,
-						  &TmpLen, 1, &HtCapIe, 1,
-						  &pAd->MlmeAux.HtCapabilityLen,
-						  pAd->MlmeAux.HtCapabilityLen,
-						  &pAd->MlmeAux.HtCapability,
-						  END_OF_ARGS);
-			}
-			FrameLen += TmpLen;
-		}
-		/* add Ralink proprietary IE to inform AP this STA is going to use AGGREGATION or PIGGY-BACK+AGGREGATION */
-		/* Case I: (Aggregation + Piggy-Back) */
-		/* 1. user enable aggregation, AND */
-		/* 2. Mac support piggy-back */
-		/* 3. AP annouces it's PIGGY-BACK+AGGREGATION-capable in BEACON */
-		/* Case II: (Aggregation) */
-		/* 1. user enable aggregation, AND */
-		/* 2. AP annouces it's AGGREGATION-capable in BEACON */
-		if (pAd->CommonCfg.bAggregationCapable) {
-			if ((pAd->CommonCfg.bPiggyBackCapable)
-			    && ((pAd->MlmeAux.APRalinkIe & 0x00000003) == 3)) {
-				unsigned long TmpLen;
-				u8 RalinkIe[9] =
-				    { IE_VENDOR_SPECIFIC, 7, 0x00, 0x0c, 0x43,
-			    0x03, 0x00, 0x00, 0x00 };
-				MakeOutgoingFrame(pOutBuffer + FrameLen,
-						  &TmpLen, 9, RalinkIe,
-						  END_OF_ARGS);
-				FrameLen += TmpLen;
-			} else if (pAd->MlmeAux.APRalinkIe & 0x00000001) {
-				unsigned long TmpLen;
-				u8 RalinkIe[9] =
-				    { IE_VENDOR_SPECIFIC, 7, 0x00, 0x0c, 0x43,
-			    0x01, 0x00, 0x00, 0x00 };
-				MakeOutgoingFrame(pOutBuffer + FrameLen,
-						  &TmpLen, 9, RalinkIe,
-						  END_OF_ARGS);
-				FrameLen += TmpLen;
-			}
-		} else {
-			unsigned long TmpLen;
-			u8 RalinkIe[9] =
-			    { IE_VENDOR_SPECIFIC, 7, 0x00, 0x0c, 0x43, 0x04,
-		    0x00, 0x00, 0x00 };
-			MakeOutgoingFrame(pOutBuffer + FrameLen, &TmpLen, 9,
-					  RalinkIe, END_OF_ARGS);
-			FrameLen += TmpLen;
-		}
-
-		MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
-		MlmeFreeMemory(pAd, pOutBuffer);
-
-		RTMPSetTimer(&pAd->MlmeAux.ReassocTimer, Timeout);	/* in mSec */
-		pAd->Mlme.AssocMachine.CurrState = REASSOC_WAIT_RSP;
-	} else {
-		DBGPRINT(RT_DEBUG_TRACE,
-			 ("ASSOC - MlmeReassocReqAction() sanity check failed. BUG!\n"));
-		pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
-		Status = MLME_INVALID_FORMAT;
-		MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_REASSOC_CONF, 2,
-			    &Status);
-	}
-}
-
-/*
-	==========================================================================
-	Description:
-		Upper layer issues disassoc request
-	Parameters:
-		Elem -
-
-	IRQL = PASSIVE_LEVEL
-
-	==========================================================================
- */
-void MlmeDisassocReqAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
-{
-	struct rt_mlme_disassoc_req *pDisassocReq;
-	struct rt_header_802_11 DisassocHdr;
-	struct rt_header_802_11 * pDisassocHdr;
-	u8 *pOutBuffer = NULL;
-	unsigned long FrameLen = 0;
-	int NStatus;
-	BOOLEAN TimerCancelled;
-	unsigned long Timeout = 500;
-	u16 Status;
-
-	/* skip sanity check */
-	pDisassocReq = (struct rt_mlme_disassoc_req *)(Elem->Msg);
-
-	NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);	/*Get an unused nonpaged memory */
-	if (NStatus != NDIS_STATUS_SUCCESS) {
-		DBGPRINT(RT_DEBUG_TRACE,
-			 ("ASSOC - MlmeDisassocReqAction() allocate memory failed\n"));
-		pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
-		Status = MLME_FAIL_NO_RESOURCE;
-		MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_DISASSOC_CONF, 2,
-			    &Status);
-		return;
-	}
-
-	RTMPCancelTimer(&pAd->MlmeAux.DisassocTimer, &TimerCancelled);
-
-	DBGPRINT(RT_DEBUG_TRACE,
-		("ASSOC - Send DISASSOC request[BSSID::%pM (Reason=%d)\n",
-			pDisassocReq->Addr, pDisassocReq->Reason));
-	MgtMacHeaderInit(pAd, &DisassocHdr, SUBTYPE_DISASSOC, 0, pDisassocReq->Addr, pDisassocReq->Addr);	/* patch peap ttls switching issue */
-	MakeOutgoingFrame(pOutBuffer, &FrameLen,
-			  sizeof(struct rt_header_802_11), &DisassocHdr,
-			  2, &pDisassocReq->Reason, END_OF_ARGS);
-	MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
-
-	/* To patch Instance and Buffalo(N) AP */
-	/* Driver has to send deauth to Instance AP, but Buffalo(N) needs to send disassoc to reset Authenticator's state machine */
-	/* Therefore, we send both of them. */
-	pDisassocHdr = (struct rt_header_802_11 *) pOutBuffer;
-	pDisassocHdr->FC.SubType = SUBTYPE_DEAUTH;
-	MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
-
-	MlmeFreeMemory(pAd, pOutBuffer);
-
-	pAd->StaCfg.DisassocReason = REASON_DISASSOC_STA_LEAVING;
-	COPY_MAC_ADDR(pAd->StaCfg.DisassocSta, pDisassocReq->Addr);
-
-	RTMPSetTimer(&pAd->MlmeAux.DisassocTimer, Timeout);	/* in mSec */
-	pAd->Mlme.AssocMachine.CurrState = DISASSOC_WAIT_RSP;
-
-	RtmpOSWrielessEventSend(pAd, SIOCGIWAP, -1, NULL, NULL, 0);
-
-}
-
-/*
-	==========================================================================
-	Description:
-		peer sends assoc rsp back
-	Parameters:
-		Elme - MLME message containing the received frame
-
-	IRQL = DISPATCH_LEVEL
-
-	==========================================================================
- */
-void PeerAssocRspAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
-{
-	u16 CapabilityInfo, Status, Aid;
-	u8 SupRate[MAX_LEN_OF_SUPPORTED_RATES], SupRateLen;
-	u8 ExtRate[MAX_LEN_OF_SUPPORTED_RATES], ExtRateLen;
-	u8 Addr2[MAC_ADDR_LEN];
-	BOOLEAN TimerCancelled;
-	u8 CkipFlag;
-	struct rt_edca_parm EdcaParm;
-	struct rt_ht_capability_ie HtCapability;
-	struct rt_add_ht_info_ie AddHtInfo;	/* AP might use this additional ht info IE */
-	u8 HtCapabilityLen = 0;
-	u8 AddHtInfoLen;
-	u8 NewExtChannelOffset = 0xff;
-
-	if (PeerAssocRspSanity
-	    (pAd, Elem->Msg, Elem->MsgLen, Addr2, &CapabilityInfo, &Status,
-	     &Aid, SupRate, &SupRateLen, ExtRate, &ExtRateLen, &HtCapability,
-	     &AddHtInfo, &HtCapabilityLen, &AddHtInfoLen, &NewExtChannelOffset,
-	     &EdcaParm, &CkipFlag)) {
-		/* The frame is for me ? */
-		if (MAC_ADDR_EQUAL(Addr2, pAd->MlmeAux.Bssid)) {
-			DBGPRINT(RT_DEBUG_TRACE,
-				 ("PeerAssocRspAction():ASSOC - receive ASSOC_RSP to me (status=%d)\n",
-				  Status));
-			DBGPRINT(RT_DEBUG_TRACE,
-				 ("PeerAssocRspAction():MacTable [%d].AMsduSize = %d. ClientStatusFlags = 0x%lx \n",
-				  Elem->Wcid,
-				  pAd->MacTab.Content[BSSID_WCID].AMsduSize,
-				  pAd->MacTab.Content[BSSID_WCID].
-				  ClientStatusFlags));
-			RTMPCancelTimer(&pAd->MlmeAux.AssocTimer,
-					&TimerCancelled);
-
-			if (Status == MLME_SUCCESS) {
-				u8 MaxSupportedRateIn500Kbps = 0;
-				u8 idx;
-
-				/* supported rates array may not be sorted. sort it and find the maximum rate */
-				for (idx = 0; idx < SupRateLen; idx++) {
-					if (MaxSupportedRateIn500Kbps <
-					    (SupRate[idx] & 0x7f))
-						MaxSupportedRateIn500Kbps =
-						    SupRate[idx] & 0x7f;
-				}
-
-				for (idx = 0; idx < ExtRateLen; idx++) {
-					if (MaxSupportedRateIn500Kbps <
-					    (ExtRate[idx] & 0x7f))
-						MaxSupportedRateIn500Kbps =
-						    ExtRate[idx] & 0x7f;
-				}
-				/* go to procedure listed on page 376 */
-				AssocPostProc(pAd, Addr2, CapabilityInfo, Aid,
-					      SupRate, SupRateLen, ExtRate,
-					      ExtRateLen, &EdcaParm,
-					      &HtCapability, HtCapabilityLen,
-					      &AddHtInfo);
-
-				StaAddMacTableEntry(pAd,
-						    &pAd->MacTab.
-						    Content[BSSID_WCID],
-						    MaxSupportedRateIn500Kbps,
-						    &HtCapability,
-						    HtCapabilityLen, &AddHtInfo,
-						    AddHtInfoLen,
-						    CapabilityInfo);
-			}
-			pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
-			MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE,
-				    MT2_ASSOC_CONF, 2, &Status);
-		}
-	} else {
-		DBGPRINT(RT_DEBUG_TRACE,
-			 ("ASSOC - PeerAssocRspAction() sanity check fail\n"));
-	}
-}
-
-/*
-	==========================================================================
-	Description:
-		peer sends reassoc rsp
-	Parametrs:
-		Elem - MLME message cntaining the received frame
-
-	IRQL = DISPATCH_LEVEL
-
-	==========================================================================
- */
-void PeerReassocRspAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
-{
-	u16 CapabilityInfo;
-	u16 Status;
-	u16 Aid;
-	u8 SupRate[MAX_LEN_OF_SUPPORTED_RATES], SupRateLen;
-	u8 ExtRate[MAX_LEN_OF_SUPPORTED_RATES], ExtRateLen;
-	u8 Addr2[MAC_ADDR_LEN];
-	u8 CkipFlag;
-	BOOLEAN TimerCancelled;
-	struct rt_edca_parm EdcaParm;
-	struct rt_ht_capability_ie HtCapability;
-	struct rt_add_ht_info_ie AddHtInfo;	/* AP might use this additional ht info IE */
-	u8 HtCapabilityLen;
-	u8 AddHtInfoLen;
-	u8 NewExtChannelOffset = 0xff;
-
-	if (PeerAssocRspSanity
-	    (pAd, Elem->Msg, Elem->MsgLen, Addr2, &CapabilityInfo, &Status,
-	     &Aid, SupRate, &SupRateLen, ExtRate, &ExtRateLen, &HtCapability,
-	     &AddHtInfo, &HtCapabilityLen, &AddHtInfoLen, &NewExtChannelOffset,
-	     &EdcaParm, &CkipFlag)) {
-		if (MAC_ADDR_EQUAL(Addr2, pAd->MlmeAux.Bssid))	/* The frame is for me ? */
-		{
-			DBGPRINT(RT_DEBUG_TRACE,
-				 ("ASSOC - receive REASSOC_RSP to me (status=%d)\n",
-				  Status));
-			RTMPCancelTimer(&pAd->MlmeAux.ReassocTimer,
-					&TimerCancelled);
-
-			if (Status == MLME_SUCCESS) {
-				/* go to procedure listed on page 376 */
-				AssocPostProc(pAd, Addr2, CapabilityInfo, Aid,
-					      SupRate, SupRateLen, ExtRate,
-					      ExtRateLen, &EdcaParm,
-					      &HtCapability, HtCapabilityLen,
-					      &AddHtInfo);
-
-				{
-					wext_notify_event_assoc(pAd);
-					RtmpOSWrielessEventSend(pAd, SIOCGIWAP,
-								-1,
-								&pAd->MlmeAux.
-								Bssid[0], NULL,
-								0);
-				}
-
-			}
-			/* CkipFlag is no use for reassociate */
-			pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
-			MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE,
-				    MT2_REASSOC_CONF, 2, &Status);
-		}
-	} else {
-		DBGPRINT(RT_DEBUG_TRACE,
-			 ("ASSOC - PeerReassocRspAction() sanity check fail\n"));
-	}
-
-}
-
-/*
-	==========================================================================
-	Description:
-		procedures on IEEE 802.11/1999 p.376
-	Parametrs:
-
-	IRQL = DISPATCH_LEVEL
-
-	==========================================================================
- */
-void AssocPostProc(struct rt_rtmp_adapter *pAd, u8 *pAddr2, u16 CapabilityInfo, u16 Aid, u8 SupRate[], u8 SupRateLen, u8 ExtRate[], u8 ExtRateLen, struct rt_edca_parm *pEdcaParm, struct rt_ht_capability_ie * pHtCapability, u8 HtCapabilityLen, struct rt_add_ht_info_ie * pAddHtInfo)	/* AP might use this additional ht info IE */
-{
-	unsigned long Idx;
-
-	pAd->MlmeAux.BssType = BSS_INFRA;
-	COPY_MAC_ADDR(pAd->MlmeAux.Bssid, pAddr2);
-	pAd->MlmeAux.Aid = Aid;
-	pAd->MlmeAux.CapabilityInfo =
-	    CapabilityInfo & SUPPORTED_CAPABILITY_INFO;
-
-	/* Some HT AP might lost WMM IE. We add WMM ourselves. because HT requires QoS on. */
-	if ((HtCapabilityLen > 0) && (pEdcaParm->bValid == FALSE)) {
-		pEdcaParm->bValid = TRUE;
-		pEdcaParm->Aifsn[0] = 3;
-		pEdcaParm->Aifsn[1] = 7;
-		pEdcaParm->Aifsn[2] = 2;
-		pEdcaParm->Aifsn[3] = 2;
-
-		pEdcaParm->Cwmin[0] = 4;
-		pEdcaParm->Cwmin[1] = 4;
-		pEdcaParm->Cwmin[2] = 3;
-		pEdcaParm->Cwmin[3] = 2;
-
-		pEdcaParm->Cwmax[0] = 10;
-		pEdcaParm->Cwmax[1] = 10;
-		pEdcaParm->Cwmax[2] = 4;
-		pEdcaParm->Cwmax[3] = 3;
-
-		pEdcaParm->Txop[0] = 0;
-		pEdcaParm->Txop[1] = 0;
-		pEdcaParm->Txop[2] = 96;
-		pEdcaParm->Txop[3] = 48;
-
-	}
-
-	NdisMoveMemory(&pAd->MlmeAux.APEdcaParm, pEdcaParm, sizeof(struct rt_edca_parm));
-
-	/* filter out un-supported rates */
-	pAd->MlmeAux.SupRateLen = SupRateLen;
-	NdisMoveMemory(pAd->MlmeAux.SupRate, SupRate, SupRateLen);
-	RTMPCheckRates(pAd, pAd->MlmeAux.SupRate, &pAd->MlmeAux.SupRateLen);
-
-	/* filter out un-supported rates */
-	pAd->MlmeAux.ExtRateLen = ExtRateLen;
-	NdisMoveMemory(pAd->MlmeAux.ExtRate, ExtRate, ExtRateLen);
-	RTMPCheckRates(pAd, pAd->MlmeAux.ExtRate, &pAd->MlmeAux.ExtRateLen);
-
-	if (HtCapabilityLen > 0) {
-		RTMPCheckHt(pAd, BSSID_WCID, pHtCapability, pAddHtInfo);
-	}
-	DBGPRINT(RT_DEBUG_TRACE,
-		 ("AssocPostProc===>  AP.AMsduSize = %d. ClientStatusFlags = 0x%lx \n",
-		  pAd->MacTab.Content[BSSID_WCID].AMsduSize,
-		  pAd->MacTab.Content[BSSID_WCID].ClientStatusFlags));
-
-	DBGPRINT(RT_DEBUG_TRACE,
-		 ("AssocPostProc===>    (Mmps=%d, AmsduSize=%d, )\n",
-		  pAd->MacTab.Content[BSSID_WCID].MmpsMode,
-		  pAd->MacTab.Content[BSSID_WCID].AMsduSize));
-
-	/* Set New WPA information */
-	Idx = BssTableSearch(&pAd->ScanTab, pAddr2, pAd->MlmeAux.Channel);
-	if (Idx == BSS_NOT_FOUND) {
-		DBGPRINT_ERR("ASSOC - Can't find BSS after receiving Assoc response\n");
-	} else {
-		/* Init variable */
-		pAd->MacTab.Content[BSSID_WCID].RSNIE_Len = 0;
-		NdisZeroMemory(pAd->MacTab.Content[BSSID_WCID].RSN_IE,
-			       MAX_LEN_OF_RSNIE);
-
-		/* Store appropriate RSN_IE for WPA SM negotiation later */
-		if ((pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
-		    && (pAd->ScanTab.BssEntry[Idx].VarIELen != 0)) {
-			u8 *pVIE;
-			u16 len;
-			struct rt_eid * pEid;
-
-			pVIE = pAd->ScanTab.BssEntry[Idx].VarIEs;
-			len = pAd->ScanTab.BssEntry[Idx].VarIELen;
-			/*KH need to check again */
-			/* Don't allow to go to sleep mode if authmode is WPA-related. */
-			/*This can make Authentication process more smoothly. */
-			RTMP_CLEAR_PSFLAG(pAd, fRTMP_PS_CAN_GO_SLEEP);
-
-			while (len > 0) {
-				pEid = (struct rt_eid *) pVIE;
-				/* For WPA/WPAPSK */
-				if ((pEid->Eid == IE_WPA)
-				    &&
-				    (NdisEqualMemory(pEid->Octet, WPA_OUI, 4))
-				    && (pAd->StaCfg.AuthMode ==
-					Ndis802_11AuthModeWPA
-					|| pAd->StaCfg.AuthMode ==
-					Ndis802_11AuthModeWPAPSK)) {
-					NdisMoveMemory(pAd->MacTab.
-						       Content[BSSID_WCID].
-						       RSN_IE, pVIE,
-						       (pEid->Len + 2));
-					pAd->MacTab.Content[BSSID_WCID].
-					    RSNIE_Len = (pEid->Len + 2);
-					DBGPRINT(RT_DEBUG_TRACE,
-						 ("AssocPostProc===> Store RSN_IE for WPA SM negotiation \n"));
-				}
-				/* For WPA2/WPA2PSK */
-				else if ((pEid->Eid == IE_RSN)
-					 &&
-					 (NdisEqualMemory
-					  (pEid->Octet + 2, RSN_OUI, 3))
-					 && (pAd->StaCfg.AuthMode ==
-					     Ndis802_11AuthModeWPA2
-					     || pAd->StaCfg.AuthMode ==
-					     Ndis802_11AuthModeWPA2PSK)) {
-					NdisMoveMemory(pAd->MacTab.
-						       Content[BSSID_WCID].
-						       RSN_IE, pVIE,
-						       (pEid->Len + 2));
-					pAd->MacTab.Content[BSSID_WCID].
-					    RSNIE_Len = (pEid->Len + 2);
-					DBGPRINT(RT_DEBUG_TRACE,
-						 ("AssocPostProc===> Store RSN_IE for WPA2 SM negotiation \n"));
-				}
-
-				pVIE += (pEid->Len + 2);
-				len -= (pEid->Len + 2);
-			}
-
-		}
-
-		if (pAd->MacTab.Content[BSSID_WCID].RSNIE_Len == 0) {
-			DBGPRINT(RT_DEBUG_TRACE,
-				 ("AssocPostProc===> no RSN_IE \n"));
-		} else {
-			hex_dump("RSN_IE",
-				 pAd->MacTab.Content[BSSID_WCID].RSN_IE,
-				 pAd->MacTab.Content[BSSID_WCID].RSNIE_Len);
-		}
-	}
-}
-
-/*
-	==========================================================================
-	Description:
-		left part of IEEE 802.11/1999 p.374
-	Parameters:
-		Elem - MLME message containing the received frame
-
-	IRQL = DISPATCH_LEVEL
-
-	==========================================================================
- */
-void PeerDisassocAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
-{
-	u8 Addr2[MAC_ADDR_LEN];
-	u16 Reason;
-
-	DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - PeerDisassocAction()\n"));
-	if (PeerDisassocSanity(pAd, Elem->Msg, Elem->MsgLen, Addr2, &Reason)) {
-		DBGPRINT(RT_DEBUG_TRACE,
-			 ("ASSOC - PeerDisassocAction() Reason = %d\n",
-			  Reason));
-		if (INFRA_ON(pAd)
-		    && MAC_ADDR_EQUAL(pAd->CommonCfg.Bssid, Addr2)) {
-
-			if (pAd->CommonCfg.bWirelessEvent) {
-				RTMPSendWirelessEvent(pAd,
-						      IW_DISASSOC_EVENT_FLAG,
-						      pAd->MacTab.
-						      Content[BSSID_WCID].Addr,
-						      BSS0, 0);
-			}
-
-			LinkDown(pAd, TRUE);
-			pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
-
-			RtmpOSWrielessEventSend(pAd, SIOCGIWAP, -1, NULL, NULL,
-						0);
-		}
-	} else {
-		DBGPRINT(RT_DEBUG_TRACE,
-			 ("ASSOC - PeerDisassocAction() sanity check fail\n"));
-	}
-
-}
-
-/*
-	==========================================================================
-	Description:
-		what the state machine will do after assoc timeout
-	Parameters:
-		Elme -
-
-	IRQL = DISPATCH_LEVEL
-
-	==========================================================================
- */
-void AssocTimeoutAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
-{
-	u16 Status;
-	DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - AssocTimeoutAction\n"));
-	pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
-	Status = MLME_REJ_TIMEOUT;
-	MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_ASSOC_CONF, 2, &Status);
-}
-
-/*
-	==========================================================================
-	Description:
-		what the state machine will do after reassoc timeout
-
-	IRQL = DISPATCH_LEVEL
-
-	==========================================================================
- */
-void ReassocTimeoutAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
-{
-	u16 Status;
-	DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - ReassocTimeoutAction\n"));
-	pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
-	Status = MLME_REJ_TIMEOUT;
-	MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_REASSOC_CONF, 2, &Status);
-}
-
-/*
-	==========================================================================
-	Description:
-		what the state machine will do after disassoc timeout
-
-	IRQL = DISPATCH_LEVEL
-
-	==========================================================================
- */
-void DisassocTimeoutAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
-{
-	u16 Status;
-	DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - DisassocTimeoutAction\n"));
-	pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
-	Status = MLME_SUCCESS;
-	MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_DISASSOC_CONF, 2,
-		    &Status);
-}
-
-void InvalidStateWhenAssoc(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
-{
-	u16 Status;
-	DBGPRINT(RT_DEBUG_TRACE,
-		 ("ASSOC - InvalidStateWhenAssoc(state=%ld), reset ASSOC state machine\n",
-		  pAd->Mlme.AssocMachine.CurrState));
-	pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
-	Status = MLME_STATE_MACHINE_REJECT;
-	MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_ASSOC_CONF, 2, &Status);
-}
-
-void InvalidStateWhenReassoc(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
-{
-	u16 Status;
-	DBGPRINT(RT_DEBUG_TRACE,
-		 ("ASSOC - InvalidStateWhenReassoc(state=%ld), reset ASSOC state machine\n",
-		  pAd->Mlme.AssocMachine.CurrState));
-	pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
-	Status = MLME_STATE_MACHINE_REJECT;
-	MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_REASSOC_CONF, 2, &Status);
-}
-
-void InvalidStateWhenDisassociate(struct rt_rtmp_adapter *pAd,
-				  struct rt_mlme_queue_elem *Elem)
-{
-	u16 Status;
-	DBGPRINT(RT_DEBUG_TRACE,
-		 ("ASSOC - InvalidStateWhenDisassoc(state=%ld), reset ASSOC state machine\n",
-		  pAd->Mlme.AssocMachine.CurrState));
-	pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
-	Status = MLME_STATE_MACHINE_REJECT;
-	MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_DISASSOC_CONF, 2,
-		    &Status);
-}
-
-/*
-	==========================================================================
-	Description:
-		right part of IEEE 802.11/1999 page 374
-	Note:
-		This event should never cause ASSOC state machine perform state
-		transition, and has no relationship with CNTL machine. So we separate
-		this routine as a service outside of ASSOC state transition table.
-
-	IRQL = DISPATCH_LEVEL
-
-	==========================================================================
- */
-void Cls3errAction(struct rt_rtmp_adapter *pAd, u8 *pAddr)
-{
-	struct rt_header_802_11 DisassocHdr;
-	struct rt_header_802_11 * pDisassocHdr;
-	u8 *pOutBuffer = NULL;
-	unsigned long FrameLen = 0;
-	int NStatus;
-	u16 Reason = REASON_CLS3ERR;
-
-	NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);	/*Get an unused nonpaged memory */
-	if (NStatus != NDIS_STATUS_SUCCESS)
-		return;
-
-	DBGPRINT(RT_DEBUG_TRACE,
-		 ("ASSOC - Class 3 Error, Send DISASSOC frame\n"));
-	MgtMacHeaderInit(pAd, &DisassocHdr, SUBTYPE_DISASSOC, 0, pAddr, pAd->CommonCfg.Bssid);	/* patch peap ttls switching issue */
-	MakeOutgoingFrame(pOutBuffer, &FrameLen,
-			  sizeof(struct rt_header_802_11), &DisassocHdr,
-			  2, &Reason, END_OF_ARGS);
-	MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
-
-	/* To patch Instance and Buffalo(N) AP */
-	/* Driver has to send deauth to Instance AP, but Buffalo(N) needs to send disassoc to reset Authenticator's state machine */
-	/* Therefore, we send both of them. */
-	pDisassocHdr = (struct rt_header_802_11 *) pOutBuffer;
-	pDisassocHdr->FC.SubType = SUBTYPE_DEAUTH;
-	MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
-
-	MlmeFreeMemory(pAd, pOutBuffer);
-
-	pAd->StaCfg.DisassocReason = REASON_CLS3ERR;
-	COPY_MAC_ADDR(pAd->StaCfg.DisassocSta, pAddr);
-}
-
-int wext_notify_event_assoc(struct rt_rtmp_adapter *pAd)
-{
-	char custom[IW_CUSTOM_MAX] = { 0 };
-
-	if (pAd->StaCfg.ReqVarIELen <= IW_CUSTOM_MAX) {
-		NdisMoveMemory(custom, pAd->StaCfg.ReqVarIEs,
-			       pAd->StaCfg.ReqVarIELen);
-		RtmpOSWrielessEventSend(pAd, IWEVASSOCREQIE, -1, NULL, custom,
-					pAd->StaCfg.ReqVarIELen);
-	} else
-		DBGPRINT(RT_DEBUG_TRACE,
-			 ("pAd->StaCfg.ReqVarIELen > MAX_CUSTOM_LEN\n"));
-
-	return 0;
-
-}
-
-BOOLEAN StaAddMacTableEntry(struct rt_rtmp_adapter *pAd,
-			    struct rt_mac_table_entry *pEntry,
-			    u8 MaxSupportedRateIn500Kbps,
-			    struct rt_ht_capability_ie * pHtCapability,
-			    u8 HtCapabilityLen,
-			    struct rt_add_ht_info_ie * pAddHtInfo,
-			    u8 AddHtInfoLen, u16 CapabilityInfo)
-{
-	u8 MaxSupportedRate = RATE_11;
-
-	if (ADHOC_ON(pAd))
-		CLIENT_STATUS_CLEAR_FLAG(pEntry, fCLIENT_STATUS_WMM_CAPABLE);
-
-	switch (MaxSupportedRateIn500Kbps) {
-	case 108:
-		MaxSupportedRate = RATE_54;
-		break;
-	case 96:
-		MaxSupportedRate = RATE_48;
-		break;
-	case 72:
-		MaxSupportedRate = RATE_36;
-		break;
-	case 48:
-		MaxSupportedRate = RATE_24;
-		break;
-	case 36:
-		MaxSupportedRate = RATE_18;
-		break;
-	case 24:
-		MaxSupportedRate = RATE_12;
-		break;
-	case 18:
-		MaxSupportedRate = RATE_9;
-		break;
-	case 12:
-		MaxSupportedRate = RATE_6;
-		break;
-	case 22:
-		MaxSupportedRate = RATE_11;
-		break;
-	case 11:
-		MaxSupportedRate = RATE_5_5;
-		break;
-	case 4:
-		MaxSupportedRate = RATE_2;
-		break;
-	case 2:
-		MaxSupportedRate = RATE_1;
-		break;
-	default:
-		MaxSupportedRate = RATE_11;
-		break;
-	}
-
-	if ((pAd->CommonCfg.PhyMode == PHY_11G)
-	    && (MaxSupportedRate < RATE_FIRST_OFDM_RATE))
-		return FALSE;
-
-	/* 11n only */
-	if (((pAd->CommonCfg.PhyMode == PHY_11N_2_4G)
-	     || (pAd->CommonCfg.PhyMode == PHY_11N_5G))
-	    && (HtCapabilityLen == 0))
-		return FALSE;
-
-	if (!pEntry)
-		return FALSE;
-
-	NdisAcquireSpinLock(&pAd->MacTabLock);
-	if (pEntry) {
-		pEntry->PortSecured = WPA_802_1X_PORT_SECURED;
-		if ((MaxSupportedRate < RATE_FIRST_OFDM_RATE) ||
-		    (pAd->CommonCfg.PhyMode == PHY_11B)) {
-			pEntry->RateLen = 4;
-			if (MaxSupportedRate >= RATE_FIRST_OFDM_RATE)
-				MaxSupportedRate = RATE_11;
-		} else
-			pEntry->RateLen = 12;
-
-		pEntry->MaxHTPhyMode.word = 0;
-		pEntry->MinHTPhyMode.word = 0;
-		pEntry->HTPhyMode.word = 0;
-		pEntry->MaxSupportedRate = MaxSupportedRate;
-		if (pEntry->MaxSupportedRate < RATE_FIRST_OFDM_RATE) {
-			pEntry->MaxHTPhyMode.field.MODE = MODE_CCK;
-			pEntry->MaxHTPhyMode.field.MCS =
-			    pEntry->MaxSupportedRate;
-			pEntry->MinHTPhyMode.field.MODE = MODE_CCK;
-			pEntry->MinHTPhyMode.field.MCS =
-			    pEntry->MaxSupportedRate;
-			pEntry->HTPhyMode.field.MODE = MODE_CCK;
-			pEntry->HTPhyMode.field.MCS = pEntry->MaxSupportedRate;
-		} else {
-			pEntry->MaxHTPhyMode.field.MODE = MODE_OFDM;
-			pEntry->MaxHTPhyMode.field.MCS =
-			    OfdmRateToRxwiMCS[pEntry->MaxSupportedRate];
-			pEntry->MinHTPhyMode.field.MODE = MODE_OFDM;
-			pEntry->MinHTPhyMode.field.MCS =
-			    OfdmRateToRxwiMCS[pEntry->MaxSupportedRate];
-			pEntry->HTPhyMode.field.MODE = MODE_OFDM;
-			pEntry->HTPhyMode.field.MCS =
-			    OfdmRateToRxwiMCS[pEntry->MaxSupportedRate];
-		}
-		pEntry->CapabilityInfo = CapabilityInfo;
-		CLIENT_STATUS_CLEAR_FLAG(pEntry,
-					 fCLIENT_STATUS_AGGREGATION_CAPABLE);
-		CLIENT_STATUS_CLEAR_FLAG(pEntry,
-					 fCLIENT_STATUS_PIGGYBACK_CAPABLE);
-	}
-
-	NdisZeroMemory(&pEntry->HTCapability, sizeof(pEntry->HTCapability));
-	/* If this Entry supports 802.11n, upgrade to HT rate. */
-	if ((HtCapabilityLen != 0)
-	    && (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED)) {
-		u8 j, bitmask;	/*k,bitmask; */
-		char i;
-
-		if (ADHOC_ON(pAd))
-			CLIENT_STATUS_SET_FLAG(pEntry,
-					       fCLIENT_STATUS_WMM_CAPABLE);
-		if ((pHtCapability->HtCapInfo.GF)
-		    && (pAd->CommonCfg.DesiredHtPhy.GF)) {
-			pEntry->MaxHTPhyMode.field.MODE = MODE_HTGREENFIELD;
-		} else {
-			pEntry->MaxHTPhyMode.field.MODE = MODE_HTMIX;
-			pAd->MacTab.fAnyStationNonGF = TRUE;
-			pAd->CommonCfg.AddHTInfo.AddHtInfo2.NonGfPresent = 1;
-		}
-
-		if ((pHtCapability->HtCapInfo.ChannelWidth) &&
-		    (pAd->CommonCfg.DesiredHtPhy.ChannelWidth) &&
-		    ((pAd->StaCfg.BssType == BSS_INFRA)
-		     || ((pAd->StaCfg.BssType == BSS_ADHOC)
-			 && (pAddHtInfo->AddHtInfo.ExtChanOffset ==
-			     pAd->CommonCfg.AddHTInfo.AddHtInfo.
-			     ExtChanOffset)))) {
-			pEntry->MaxHTPhyMode.field.BW = BW_40;
-			pEntry->MaxHTPhyMode.field.ShortGI =
-			    ((pAd->CommonCfg.DesiredHtPhy.
-			      ShortGIfor40) & (pHtCapability->HtCapInfo.
-					       ShortGIfor40));
-		} else {
-			pEntry->MaxHTPhyMode.field.BW = BW_20;
-			pEntry->MaxHTPhyMode.field.ShortGI =
-			    ((pAd->CommonCfg.DesiredHtPhy.
-			      ShortGIfor20) & (pHtCapability->HtCapInfo.
-					       ShortGIfor20));
-			pAd->MacTab.fAnyStation20Only = TRUE;
-		}
-
-		/* 3*3 */
-		if (pAd->MACVersion >= RALINK_2883_VERSION
-		    && pAd->MACVersion < RALINK_3070_VERSION)
-			pEntry->MaxHTPhyMode.field.TxBF =
-			    pAd->CommonCfg.RegTransmitSetting.field.TxBF;
-
-		/* find max fixed rate */
-		for (i = 23; i >= 0; i--)	/* 3*3 */
-		{
-			j = i / 8;
-			bitmask = (1 << (i - (j * 8)));
-			if ((pAd->StaCfg.DesiredHtPhyInfo.MCSSet[j] & bitmask)
-			    && (pHtCapability->MCSSet[j] & bitmask)) {
-				pEntry->MaxHTPhyMode.field.MCS = i;
-				break;
-			}
-			if (i == 0)
-				break;
-		}
-
-		if (pAd->StaCfg.DesiredTransmitSetting.field.MCS != MCS_AUTO) {
-			if (pAd->StaCfg.DesiredTransmitSetting.field.MCS == 32) {
-				/* Fix MCS as HT Duplicated Mode */
-				pEntry->MaxHTPhyMode.field.BW = 1;
-				pEntry->MaxHTPhyMode.field.MODE = MODE_HTMIX;
-				pEntry->MaxHTPhyMode.field.STBC = 0;
-				pEntry->MaxHTPhyMode.field.ShortGI = 0;
-				pEntry->MaxHTPhyMode.field.MCS = 32;
-			} else if (pEntry->MaxHTPhyMode.field.MCS >
-				   pAd->StaCfg.HTPhyMode.field.MCS) {
-				/* STA supports fixed MCS */
-				pEntry->MaxHTPhyMode.field.MCS =
-				    pAd->StaCfg.HTPhyMode.field.MCS;
-			}
-		}
-
-		pEntry->MaxHTPhyMode.field.STBC =
-		    (pHtCapability->HtCapInfo.
-		     RxSTBC & (pAd->CommonCfg.DesiredHtPhy.TxSTBC));
-		pEntry->MpduDensity = pHtCapability->HtCapParm.MpduDensity;
-		pEntry->MaxRAmpduFactor =
-		    pHtCapability->HtCapParm.MaxRAmpduFactor;
-		pEntry->MmpsMode = (u8)pHtCapability->HtCapInfo.MimoPs;
-		pEntry->AMsduSize = (u8)pHtCapability->HtCapInfo.AMsduSize;
-		pEntry->HTPhyMode.word = pEntry->MaxHTPhyMode.word;
-
-		if (pAd->CommonCfg.DesiredHtPhy.AmsduEnable
-		    && (pAd->CommonCfg.REGBACapability.field.AutoBA == FALSE))
-			CLIENT_STATUS_SET_FLAG(pEntry,
-					       fCLIENT_STATUS_AMSDU_INUSED);
-		if (pHtCapability->HtCapInfo.ShortGIfor20)
-			CLIENT_STATUS_SET_FLAG(pEntry,
-					       fCLIENT_STATUS_SGI20_CAPABLE);
-		if (pHtCapability->HtCapInfo.ShortGIfor40)
-			CLIENT_STATUS_SET_FLAG(pEntry,
-					       fCLIENT_STATUS_SGI40_CAPABLE);
-		if (pHtCapability->HtCapInfo.TxSTBC)
-			CLIENT_STATUS_SET_FLAG(pEntry,
-					       fCLIENT_STATUS_TxSTBC_CAPABLE);
-		if (pHtCapability->HtCapInfo.RxSTBC)
-			CLIENT_STATUS_SET_FLAG(pEntry,
-					       fCLIENT_STATUS_RxSTBC_CAPABLE);
-		if (pHtCapability->ExtHtCapInfo.PlusHTC)
-			CLIENT_STATUS_SET_FLAG(pEntry,
-					       fCLIENT_STATUS_HTC_CAPABLE);
-		if (pAd->CommonCfg.bRdg
-		    && pHtCapability->ExtHtCapInfo.RDGSupport)
-			CLIENT_STATUS_SET_FLAG(pEntry,
-					       fCLIENT_STATUS_RDG_CAPABLE);
-		if (pHtCapability->ExtHtCapInfo.MCSFeedback == 0x03)
-			CLIENT_STATUS_SET_FLAG(pEntry,
-					       fCLIENT_STATUS_MCSFEEDBACK_CAPABLE);
-		NdisMoveMemory(&pEntry->HTCapability, pHtCapability,
-			       HtCapabilityLen);
-	} else {
-		pAd->MacTab.fAnyStationIsLegacy = TRUE;
-	}
-
-	pEntry->HTPhyMode.word = pEntry->MaxHTPhyMode.word;
-	pEntry->CurrTxRate = pEntry->MaxSupportedRate;
-
-	/* Set asic auto fall back */
-	if (pAd->StaCfg.bAutoTxRateSwitch == TRUE) {
-		u8 *pTable;
-		u8 TableSize = 0;
-
-		MlmeSelectTxRateTable(pAd, pEntry, &pTable, &TableSize,
-				      &pEntry->CurrTxRateIndex);
-		pEntry->bAutoTxRateSwitch = TRUE;
-	} else {
-		pEntry->HTPhyMode.field.MODE = pAd->StaCfg.HTPhyMode.field.MODE;
-		pEntry->HTPhyMode.field.MCS = pAd->StaCfg.HTPhyMode.field.MCS;
-		pEntry->bAutoTxRateSwitch = FALSE;
-
-		/* If the legacy mode is set, overwrite the transmit setting of this entry. */
-		RTMPUpdateLegacyTxSetting((u8)pAd->StaCfg.
-					  DesiredTransmitSetting.field.
-					  FixedTxMode, pEntry);
-	}
-
-	pEntry->PortSecured = WPA_802_1X_PORT_SECURED;
-	pEntry->Sst = SST_ASSOC;
-	pEntry->AuthState = AS_AUTH_OPEN;
-	pEntry->AuthMode = pAd->StaCfg.AuthMode;
-	pEntry->WepStatus = pAd->StaCfg.WepStatus;
-
-	NdisReleaseSpinLock(&pAd->MacTabLock);
-
-	{
-		union iwreq_data wrqu;
-		wext_notify_event_assoc(pAd);
-
-		memcpy(wrqu.ap_addr.sa_data, pAd->MlmeAux.Bssid, MAC_ADDR_LEN);
-		wireless_send_event(pAd->net_dev, SIOCGIWAP, &wrqu, NULL);
-
-	}
-	return TRUE;
-}
diff -druN linux-2.6.39-libre/drivers/staging/rt2860/sta/auth.c linux-3.0-rc7-libre/drivers/staging/rt2860/sta/auth.c
--- linux-2.6.39-libre/drivers/staging/rt2860/sta/auth.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rt2860/sta/auth.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,517 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, 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.             *
- *                                                                       *
- *************************************************************************
-
-	Module Name:
-	auth.c
-
-	Abstract:
-
-	Revision History:
-	Who			When			What
-	--------	----------		----------------------------------------------
-	John			2004-9-3		porting from RT2500
-	Justin P. Mattock	11/07/2010		Fix typos
-*/
-#include "../rt_config.h"
-
-/*
-    ==========================================================================
-    Description:
-        authenticate state machine init, including state transition and timer init
-    Parameters:
-        Sm - pointer to the auth state machine
-    Note:
-        The state machine looks like this
-
-                        AUTH_REQ_IDLE           AUTH_WAIT_SEQ2                   AUTH_WAIT_SEQ4
-    MT2_MLME_AUTH_REQ   mlme_auth_req_action    invalid_state_when_auth          invalid_state_when_auth
-    MT2_PEER_AUTH_EVEN  drop                    peer_auth_even_at_seq2_action    peer_auth_even_at_seq4_action
-    MT2_AUTH_TIMEOUT    Drop                    auth_timeout_action              auth_timeout_action
-
-	IRQL = PASSIVE_LEVEL
-
-    ==========================================================================
- */
-
-void AuthStateMachineInit(struct rt_rtmp_adapter *pAd,
-			  struct rt_state_machine *Sm, OUT STATE_MACHINE_FUNC Trans[])
-{
-	StateMachineInit(Sm, Trans, MAX_AUTH_STATE, MAX_AUTH_MSG,
-			 (STATE_MACHINE_FUNC) Drop, AUTH_REQ_IDLE,
-			 AUTH_MACHINE_BASE);
-
-	/* the first column */
-	StateMachineSetAction(Sm, AUTH_REQ_IDLE, MT2_MLME_AUTH_REQ,
-			      (STATE_MACHINE_FUNC) MlmeAuthReqAction);
-
-	/* the second column */
-	StateMachineSetAction(Sm, AUTH_WAIT_SEQ2, MT2_MLME_AUTH_REQ,
-			      (STATE_MACHINE_FUNC) InvalidStateWhenAuth);
-	StateMachineSetAction(Sm, AUTH_WAIT_SEQ2, MT2_PEER_AUTH_EVEN,
-			      (STATE_MACHINE_FUNC) PeerAuthRspAtSeq2Action);
-	StateMachineSetAction(Sm, AUTH_WAIT_SEQ2, MT2_AUTH_TIMEOUT,
-			      (STATE_MACHINE_FUNC) AuthTimeoutAction);
-
-	/* the third column */
-	StateMachineSetAction(Sm, AUTH_WAIT_SEQ4, MT2_MLME_AUTH_REQ,
-			      (STATE_MACHINE_FUNC) InvalidStateWhenAuth);
-	StateMachineSetAction(Sm, AUTH_WAIT_SEQ4, MT2_PEER_AUTH_EVEN,
-			      (STATE_MACHINE_FUNC) PeerAuthRspAtSeq4Action);
-	StateMachineSetAction(Sm, AUTH_WAIT_SEQ4, MT2_AUTH_TIMEOUT,
-			      (STATE_MACHINE_FUNC) AuthTimeoutAction);
-
-	RTMPInitTimer(pAd, &pAd->MlmeAux.AuthTimer,
-		      GET_TIMER_FUNCTION(AuthTimeout), pAd, FALSE);
-}
-
-/*
-    ==========================================================================
-    Description:
-        function to be executed at timer thread when auth timer expires
-
-	IRQL = DISPATCH_LEVEL
-
-    ==========================================================================
- */
-void AuthTimeout(void *SystemSpecific1,
-		 void *FunctionContext,
-		 void *SystemSpecific2, void *SystemSpecific3)
-{
-	struct rt_rtmp_adapter *pAd = (struct rt_rtmp_adapter *)FunctionContext;
-
-	DBGPRINT(RT_DEBUG_TRACE, ("AUTH - AuthTimeout\n"));
-
-	/* Do nothing if the driver is starting halt state. */
-	/* This might happen when timer already been fired before cancel timer with mlmehalt */
-	if (RTMP_TEST_FLAG
-	    (pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST))
-		return;
-
-	/* send a de-auth to reset AP's state machine (Patch AP-Dir635) */
-	if (pAd->Mlme.AuthMachine.CurrState == AUTH_WAIT_SEQ2)
-		Cls2errAction(pAd, pAd->MlmeAux.Bssid);
-
-	MlmeEnqueue(pAd, AUTH_STATE_MACHINE, MT2_AUTH_TIMEOUT, 0, NULL);
-	RTMP_MLME_HANDLER(pAd);
-}
-
-/*
-    ==========================================================================
-    Description:
-
-	IRQL = DISPATCH_LEVEL
-
-    ==========================================================================
- */
-void MlmeAuthReqAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
-{
-	if (AUTH_ReqSend
-	    (pAd, Elem, &pAd->MlmeAux.AuthTimer, "AUTH", 1, NULL, 0))
-		pAd->Mlme.AuthMachine.CurrState = AUTH_WAIT_SEQ2;
-	else {
-		u16 Status;
-
-		pAd->Mlme.AuthMachine.CurrState = AUTH_REQ_IDLE;
-		Status = MLME_INVALID_FORMAT;
-		MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_AUTH_CONF, 2,
-			    &Status);
-	}
-}
-
-/*
-    ==========================================================================
-    Description:
-
-	IRQL = DISPATCH_LEVEL
-
-    ==========================================================================
- */
-void PeerAuthRspAtSeq2Action(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
-{
-	u8 Addr2[MAC_ADDR_LEN];
-	u16 Seq, Status, RemoteStatus, Alg;
-	u8 ChlgText[CIPHER_TEXT_LEN];
-	u8 CyperChlgText[CIPHER_TEXT_LEN + 8 + 8];
-	u8 Element[2];
-	struct rt_header_802_11 AuthHdr;
-	BOOLEAN TimerCancelled;
-	u8 *pOutBuffer = NULL;
-	int NStatus;
-	unsigned long FrameLen = 0;
-	u16 Status2;
-
-	if (PeerAuthSanity
-	    (pAd, Elem->Msg, Elem->MsgLen, Addr2, &Alg, &Seq, &Status,
-	     (char *)ChlgText)) {
-		if (MAC_ADDR_EQUAL(pAd->MlmeAux.Bssid, Addr2) && Seq == 2) {
-			DBGPRINT(RT_DEBUG_TRACE,
-				 ("AUTH - Receive AUTH_RSP seq#2 to me (Alg=%d, Status=%d)\n",
-				  Alg, Status));
-			RTMPCancelTimer(&pAd->MlmeAux.AuthTimer,
-					&TimerCancelled);
-
-			if (Status == MLME_SUCCESS) {
-				/* Authentication Mode "LEAP" has allow for CCX 1.X */
-				if (pAd->MlmeAux.Alg == Ndis802_11AuthModeOpen) {
-					pAd->Mlme.AuthMachine.CurrState =
-					    AUTH_REQ_IDLE;
-					MlmeEnqueue(pAd,
-						    MLME_CNTL_STATE_MACHINE,
-						    MT2_AUTH_CONF, 2, &Status);
-				} else {
-					/* 2. shared key, need to be challenged */
-					Seq++;
-					RemoteStatus = MLME_SUCCESS;
-
-					/* Get an unused nonpaged memory */
-					NStatus =
-					    MlmeAllocateMemory(pAd,
-							       &pOutBuffer);
-					if (NStatus != NDIS_STATUS_SUCCESS) {
-						DBGPRINT(RT_DEBUG_TRACE,
-							 ("AUTH - PeerAuthRspAtSeq2Action() allocate memory fail\n"));
-						pAd->Mlme.AuthMachine.
-						    CurrState = AUTH_REQ_IDLE;
-						Status2 = MLME_FAIL_NO_RESOURCE;
-						MlmeEnqueue(pAd,
-							    MLME_CNTL_STATE_MACHINE,
-							    MT2_AUTH_CONF, 2,
-							    &Status2);
-						return;
-					}
-
-					DBGPRINT(RT_DEBUG_TRACE,
-						 ("AUTH - Send AUTH request seq#3...\n"));
-					MgtMacHeaderInit(pAd, &AuthHdr,
-							 SUBTYPE_AUTH, 0, Addr2,
-							 pAd->MlmeAux.Bssid);
-					AuthHdr.FC.Wep = 1;
-					/* Encrypt challenge text & auth information */
-					RTMPInitWepEngine(pAd,
-							  pAd->
-							  SharedKey[BSS0][pAd->
-									  StaCfg.
-									  DefaultKeyId].
-							  Key,
-							  pAd->StaCfg.
-							  DefaultKeyId,
-							  pAd->
-							  SharedKey[BSS0][pAd->
-									  StaCfg.
-									  DefaultKeyId].
-							  KeyLen,
-							  CyperChlgText);
-
-					Alg = cpu2le16(*(u16 *) & Alg);
-					Seq = cpu2le16(*(u16 *) & Seq);
-					RemoteStatus =
-					    cpu2le16(*(u16 *) &
-						     RemoteStatus);
-
-					RTMPEncryptData(pAd, (u8 *)& Alg,
-							CyperChlgText + 4, 2);
-					RTMPEncryptData(pAd, (u8 *)& Seq,
-							CyperChlgText + 6, 2);
-					RTMPEncryptData(pAd,
-							(u8 *)& RemoteStatus,
-							CyperChlgText + 8, 2);
-					Element[0] = 16;
-					Element[1] = 128;
-					RTMPEncryptData(pAd, Element,
-							CyperChlgText + 10, 2);
-					RTMPEncryptData(pAd, ChlgText,
-							CyperChlgText + 12,
-							128);
-					RTMPSetICV(pAd, CyperChlgText + 140);
-					MakeOutgoingFrame(pOutBuffer, &FrameLen,
-							  sizeof(struct rt_header_802_11),
-							  &AuthHdr,
-							  CIPHER_TEXT_LEN + 16,
-							  CyperChlgText,
-							  END_OF_ARGS);
-					MiniportMMRequest(pAd, 0, pOutBuffer,
-							  FrameLen);
-					MlmeFreeMemory(pAd, pOutBuffer);
-
-					RTMPSetTimer(&pAd->MlmeAux.AuthTimer,
-						     AUTH_TIMEOUT);
-					pAd->Mlme.AuthMachine.CurrState =
-					    AUTH_WAIT_SEQ4;
-				}
-			} else {
-				pAd->StaCfg.AuthFailReason = Status;
-				COPY_MAC_ADDR(pAd->StaCfg.AuthFailSta, Addr2);
-				pAd->Mlme.AuthMachine.CurrState = AUTH_REQ_IDLE;
-				MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE,
-					    MT2_AUTH_CONF, 2, &Status);
-			}
-		}
-	} else {
-		DBGPRINT(RT_DEBUG_TRACE,
-			 ("AUTH - PeerAuthSanity() sanity check fail\n"));
-	}
-}
-
-/*
-    ==========================================================================
-    Description:
-
-	IRQL = DISPATCH_LEVEL
-
-    ==========================================================================
- */
-void PeerAuthRspAtSeq4Action(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
-{
-	u8 Addr2[MAC_ADDR_LEN];
-	u16 Alg, Seq, Status;
-	char ChlgText[CIPHER_TEXT_LEN];
-	BOOLEAN TimerCancelled;
-
-	if (PeerAuthSanity
-	    (pAd, Elem->Msg, Elem->MsgLen, Addr2, &Alg, &Seq, &Status,
-	     ChlgText)) {
-		if (MAC_ADDR_EQUAL(pAd->MlmeAux.Bssid, Addr2) && Seq == 4) {
-			DBGPRINT(RT_DEBUG_TRACE,
-				 ("AUTH - Receive AUTH_RSP seq#4 to me\n"));
-			RTMPCancelTimer(&pAd->MlmeAux.AuthTimer,
-					&TimerCancelled);
-
-			if (Status != MLME_SUCCESS) {
-				pAd->StaCfg.AuthFailReason = Status;
-				COPY_MAC_ADDR(pAd->StaCfg.AuthFailSta, Addr2);
-			}
-
-			pAd->Mlme.AuthMachine.CurrState = AUTH_REQ_IDLE;
-			MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_AUTH_CONF,
-				    2, &Status);
-		}
-	} else {
-		DBGPRINT(RT_DEBUG_TRACE,
-			 ("AUTH - PeerAuthRspAtSeq4Action() sanity check fail\n"));
-	}
-}
-
-/*
-    ==========================================================================
-    Description:
-
-	IRQL = DISPATCH_LEVEL
-
-    ==========================================================================
- */
-void MlmeDeauthReqAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
-{
-	struct rt_mlme_deauth_req *pInfo;
-	struct rt_header_802_11 DeauthHdr;
-	u8 *pOutBuffer = NULL;
-	int NStatus;
-	unsigned long FrameLen = 0;
-	u16 Status;
-
-	pInfo = (struct rt_mlme_deauth_req *)Elem->Msg;
-
-	NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);	/*Get an unused nonpaged memory */
-	if (NStatus != NDIS_STATUS_SUCCESS) {
-		DBGPRINT(RT_DEBUG_TRACE,
-			 ("AUTH - MlmeDeauthReqAction() allocate memory fail\n"));
-		pAd->Mlme.AuthMachine.CurrState = AUTH_REQ_IDLE;
-		Status = MLME_FAIL_NO_RESOURCE;
-		MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_DEAUTH_CONF, 2,
-			    &Status);
-		return;
-	}
-
-	DBGPRINT(RT_DEBUG_TRACE,
-		 ("AUTH - Send DE-AUTH request (Reason=%d)...\n",
-		  pInfo->Reason));
-	MgtMacHeaderInit(pAd, &DeauthHdr, SUBTYPE_DEAUTH, 0, pInfo->Addr,
-			 pAd->MlmeAux.Bssid);
-	MakeOutgoingFrame(pOutBuffer, &FrameLen, sizeof(struct rt_header_802_11),
-			  &DeauthHdr, 2, &pInfo->Reason, END_OF_ARGS);
-	MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
-	MlmeFreeMemory(pAd, pOutBuffer);
-
-	pAd->StaCfg.DeauthReason = pInfo->Reason;
-	COPY_MAC_ADDR(pAd->StaCfg.DeauthSta, pInfo->Addr);
-	pAd->Mlme.AuthMachine.CurrState = AUTH_REQ_IDLE;
-	Status = MLME_SUCCESS;
-	MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_DEAUTH_CONF, 2, &Status);
-
-	/* send wireless event - for deauthentication */
-	if (pAd->CommonCfg.bWirelessEvent)
-		RTMPSendWirelessEvent(pAd, IW_DEAUTH_EVENT_FLAG,
-				      pAd->MacTab.Content[BSSID_WCID].Addr,
-				      BSS0, 0);
-}
-
-/*
-    ==========================================================================
-    Description:
-
-	IRQL = DISPATCH_LEVEL
-
-    ==========================================================================
- */
-void AuthTimeoutAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
-{
-	u16 Status;
-	DBGPRINT(RT_DEBUG_TRACE, ("AUTH - AuthTimeoutAction\n"));
-	pAd->Mlme.AuthMachine.CurrState = AUTH_REQ_IDLE;
-	Status = MLME_REJ_TIMEOUT;
-	MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_AUTH_CONF, 2, &Status);
-}
-
-/*
-    ==========================================================================
-    Description:
-
-	IRQL = DISPATCH_LEVEL
-
-    ==========================================================================
- */
-void InvalidStateWhenAuth(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
-{
-	u16 Status;
-	DBGPRINT(RT_DEBUG_TRACE,
-		 ("AUTH - InvalidStateWhenAuth (state=%ld), reset AUTH state machine\n",
-		  pAd->Mlme.AuthMachine.CurrState));
-	pAd->Mlme.AuthMachine.CurrState = AUTH_REQ_IDLE;
-	Status = MLME_STATE_MACHINE_REJECT;
-	MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_AUTH_CONF, 2, &Status);
-}
-
-/*
-    ==========================================================================
-    Description:
-        Some STA/AP
-    Note:
-        This action should never trigger AUTH state transition, therefore we
-        separate it from AUTH state machine, and make it as a standalone service
-
-	IRQL = DISPATCH_LEVEL
-
-    ==========================================================================
- */
-void Cls2errAction(struct rt_rtmp_adapter *pAd, u8 *pAddr)
-{
-	struct rt_header_802_11 DeauthHdr;
-	u8 *pOutBuffer = NULL;
-	int NStatus;
-	unsigned long FrameLen = 0;
-	u16 Reason = REASON_CLS2ERR;
-
-	NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);	/*Get an unused nonpaged memory */
-	if (NStatus != NDIS_STATUS_SUCCESS)
-		return;
-
-	DBGPRINT(RT_DEBUG_TRACE,
-		 ("AUTH - Class 2 error, Send DEAUTH frame...\n"));
-	MgtMacHeaderInit(pAd, &DeauthHdr, SUBTYPE_DEAUTH, 0, pAddr,
-			 pAd->MlmeAux.Bssid);
-	MakeOutgoingFrame(pOutBuffer, &FrameLen, sizeof(struct rt_header_802_11),
-			  &DeauthHdr, 2, &Reason, END_OF_ARGS);
-	MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
-	MlmeFreeMemory(pAd, pOutBuffer);
-
-	pAd->StaCfg.DeauthReason = Reason;
-	COPY_MAC_ADDR(pAd->StaCfg.DeauthSta, pAddr);
-}
-
-BOOLEAN AUTH_ReqSend(struct rt_rtmp_adapter *pAd,
-		     struct rt_mlme_queue_elem *pElem,
-		     struct rt_ralink_timer *pAuthTimer,
-		     char *pSMName,
-		     u16 SeqNo,
-		     u8 *pNewElement, unsigned long ElementLen)
-{
-	u16 Alg, Seq, Status;
-	u8 Addr[6];
-	unsigned long Timeout;
-	struct rt_header_802_11 AuthHdr;
-	BOOLEAN TimerCancelled;
-	int NStatus;
-	u8 *pOutBuffer = NULL;
-	unsigned long FrameLen = 0, tmp = 0;
-
-	/* Block all authentication request during WPA block period */
-	if (pAd->StaCfg.bBlockAssoc == TRUE) {
-		DBGPRINT(RT_DEBUG_TRACE,
-			 ("%s - Block Auth request during WPA block period!\n",
-			  pSMName));
-		pAd->Mlme.AuthMachine.CurrState = AUTH_REQ_IDLE;
-		Status = MLME_STATE_MACHINE_REJECT;
-		MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_AUTH_CONF, 2,
-			    &Status);
-	} else
-	    if (MlmeAuthReqSanity
-		(pAd, pElem->Msg, pElem->MsgLen, Addr, &Timeout, &Alg)) {
-		/* reset timer */
-		RTMPCancelTimer(pAuthTimer, &TimerCancelled);
-
-		COPY_MAC_ADDR(pAd->MlmeAux.Bssid, Addr);
-		pAd->MlmeAux.Alg = Alg;
-		Seq = SeqNo;
-		Status = MLME_SUCCESS;
-
-		NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);	/*Get an unused nonpaged memory */
-		if (NStatus != NDIS_STATUS_SUCCESS) {
-			DBGPRINT(RT_DEBUG_TRACE,
-				 ("%s - MlmeAuthReqAction(Alg:%d) allocate memory failed\n",
-				  pSMName, Alg));
-			pAd->Mlme.AuthMachine.CurrState = AUTH_REQ_IDLE;
-			Status = MLME_FAIL_NO_RESOURCE;
-			MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_AUTH_CONF,
-				    2, &Status);
-			return FALSE;
-		}
-
-		DBGPRINT(RT_DEBUG_TRACE,
-			 ("%s - Send AUTH request seq#1 (Alg=%d)...\n", pSMName,
-			  Alg));
-		MgtMacHeaderInit(pAd, &AuthHdr, SUBTYPE_AUTH, 0, Addr,
-				 pAd->MlmeAux.Bssid);
-		MakeOutgoingFrame(pOutBuffer, &FrameLen, sizeof(struct rt_header_802_11),
-				  &AuthHdr, 2, &Alg, 2, &Seq, 2, &Status,
-				  END_OF_ARGS);
-
-		if (pNewElement && ElementLen) {
-			MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp,
-					  ElementLen, pNewElement, END_OF_ARGS);
-			FrameLen += tmp;
-		}
-
-		MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
-		MlmeFreeMemory(pAd, pOutBuffer);
-
-		RTMPSetTimer(pAuthTimer, Timeout);
-		return TRUE;
-	} else {
-		DBGPRINT_ERR("%s - MlmeAuthReqAction() sanity check failed\n", pSMName);
-		return FALSE;
-	}
-
-	return TRUE;
-}
diff -druN linux-2.6.39-libre/drivers/staging/rt2860/sta/auth_rsp.c linux-3.0-rc7-libre/drivers/staging/rt2860/sta/auth_rsp.c
--- linux-2.6.39-libre/drivers/staging/rt2860/sta/auth_rsp.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rt2860/sta/auth_rsp.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,142 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, 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.             *
- *                                                                       *
- *************************************************************************
-
-	Module Name:
-	auth_rsp.c
-
-	Abstract:
-
-	Revision History:
-	Who			When			What
-	--------	----------		----------------------------------------------
-	John		2004-10-1		copy from RT2560
-*/
-#include "../rt_config.h"
-
-/*
-    ==========================================================================
-    Description:
-        authentication state machine init procedure
-    Parameters:
-        Sm - the state machine
-
-	IRQL = PASSIVE_LEVEL
-
-    ==========================================================================
- */
-void AuthRspStateMachineInit(struct rt_rtmp_adapter *pAd,
-			     struct rt_state_machine *Sm,
-			     IN STATE_MACHINE_FUNC Trans[])
-{
-	StateMachineInit(Sm, Trans, MAX_AUTH_RSP_STATE, MAX_AUTH_RSP_MSG,
-			 (STATE_MACHINE_FUNC) Drop, AUTH_RSP_IDLE,
-			 AUTH_RSP_MACHINE_BASE);
-
-	/* column 1 */
-	StateMachineSetAction(Sm, AUTH_RSP_IDLE, MT2_PEER_DEAUTH,
-			      (STATE_MACHINE_FUNC) PeerDeauthAction);
-
-	/* column 2 */
-	StateMachineSetAction(Sm, AUTH_RSP_WAIT_CHAL, MT2_PEER_DEAUTH,
-			      (STATE_MACHINE_FUNC) PeerDeauthAction);
-
-}
-
-/*
-    ==========================================================================
-    Description:
-
-	IRQL = DISPATCH_LEVEL
-
-    ==========================================================================
-*/
-void PeerAuthSimpleRspGenAndSend(struct rt_rtmp_adapter *pAd,
-				 struct rt_header_802_11 * pHdr80211,
-				 u16 Alg,
-				 u16 Seq,
-				 u16 Reason, u16 Status)
-{
-	struct rt_header_802_11 AuthHdr;
-	unsigned long FrameLen = 0;
-	u8 *pOutBuffer = NULL;
-	int NStatus;
-
-	if (Reason != MLME_SUCCESS) {
-		DBGPRINT(RT_DEBUG_TRACE, ("Peer AUTH fail...\n"));
-		return;
-	}
-	/*Get an unused nonpaged memory */
-	NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);
-	if (NStatus != NDIS_STATUS_SUCCESS)
-		return;
-
-	DBGPRINT(RT_DEBUG_TRACE, ("Send AUTH response (seq#2)...\n"));
-	MgtMacHeaderInit(pAd, &AuthHdr, SUBTYPE_AUTH, 0, pHdr80211->Addr2,
-			 pAd->MlmeAux.Bssid);
-	MakeOutgoingFrame(pOutBuffer, &FrameLen, sizeof(struct rt_header_802_11),
-			  &AuthHdr, 2, &Alg, 2, &Seq, 2, &Reason, END_OF_ARGS);
-	MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
-	MlmeFreeMemory(pAd, pOutBuffer);
-}
-
-/*
-    ==========================================================================
-    Description:
-
-	IRQL = DISPATCH_LEVEL
-
-    ==========================================================================
-*/
-void PeerDeauthAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
-{
-	u8 Addr2[MAC_ADDR_LEN];
-	u16 Reason;
-
-	if (PeerDeauthSanity(pAd, Elem->Msg, Elem->MsgLen, Addr2, &Reason)) {
-		if (INFRA_ON(pAd)
-		    && MAC_ADDR_EQUAL(Addr2, pAd->CommonCfg.Bssid)
-		    ) {
-			DBGPRINT(RT_DEBUG_TRACE,
-				 ("AUTH_RSP - receive DE-AUTH from our AP (Reason=%d)\n",
-				  Reason));
-
-			RtmpOSWrielessEventSend(pAd, SIOCGIWAP, -1, NULL, NULL,
-						0);
-
-			/* send wireless event - for deauthentication */
-			if (pAd->CommonCfg.bWirelessEvent)
-				RTMPSendWirelessEvent(pAd, IW_DEAUTH_EVENT_FLAG,
-						      pAd->MacTab.
-						      Content[BSSID_WCID].Addr,
-						      BSS0, 0);
-
-			LinkDown(pAd, TRUE);
-		}
-	} else {
-		DBGPRINT(RT_DEBUG_TRACE,
-			 ("AUTH_RSP - PeerDeauthAction() sanity check fail\n"));
-	}
-}
diff -druN linux-2.6.39-libre/drivers/staging/rt2860/sta/connect.c linux-3.0-rc7-libre/drivers/staging/rt2860/sta/connect.c
--- linux-2.6.39-libre/drivers/staging/rt2860/sta/connect.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rt2860/sta/connect.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,2613 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, 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.             *
- *                                                                       *
- *************************************************************************
-
-	Module Name:
-	connect.c
-
-	Abstract:
-
-	Revision History:
-	Who			When			What
-	--------	----------		----------------------------------------------
-	John			2004-08-08		Major modification from RT2560
-	Justin P. Mattock	11/07/2010		Fix typos
-*/
-#include "../rt_config.h"
-
-u8 CipherSuiteWpaNoneTkip[] = {
-	0x00, 0x50, 0xf2, 0x01,	/* oui */
-	0x01, 0x00,		/* Version */
-	0x00, 0x50, 0xf2, 0x02,	/* Multicast */
-	0x01, 0x00,		/* Number of unicast */
-	0x00, 0x50, 0xf2, 0x02,	/* unicast */
-	0x01, 0x00,		/* number of authentication method */
-	0x00, 0x50, 0xf2, 0x00	/* authentication */
-};
-
-u8 CipherSuiteWpaNoneTkipLen =
-    (sizeof(CipherSuiteWpaNoneTkip) / sizeof(u8));
-
-u8 CipherSuiteWpaNoneAes[] = {
-	0x00, 0x50, 0xf2, 0x01,	/* oui */
-	0x01, 0x00,		/* Version */
-	0x00, 0x50, 0xf2, 0x04,	/* Multicast */
-	0x01, 0x00,		/* Number of unicast */
-	0x00, 0x50, 0xf2, 0x04,	/* unicast */
-	0x01, 0x00,		/* number of authentication method */
-	0x00, 0x50, 0xf2, 0x00	/* authentication */
-};
-
-u8 CipherSuiteWpaNoneAesLen =
-    (sizeof(CipherSuiteWpaNoneAes) / sizeof(u8));
-
-/* 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 firing MLME state machines become final settings */
-/* and are copied to pAd->StaActive */
-#define COPY_SETTINGS_FROM_MLME_AUX_TO_ACTIVE_CFG(_pAd)                                 \
-{                                                                                       \
-	NdisZeroMemory((_pAd)->CommonCfg.Ssid, MAX_LEN_OF_SSID);							\
-	(_pAd)->CommonCfg.SsidLen = (_pAd)->MlmeAux.SsidLen;                                \
-	NdisMoveMemory((_pAd)->CommonCfg.Ssid, (_pAd)->MlmeAux.Ssid, (_pAd)->MlmeAux.SsidLen); \
-	COPY_MAC_ADDR((_pAd)->CommonCfg.Bssid, (_pAd)->MlmeAux.Bssid);                      \
-	(_pAd)->CommonCfg.Channel = (_pAd)->MlmeAux.Channel;                                \
-	(_pAd)->CommonCfg.CentralChannel = (_pAd)->MlmeAux.CentralChannel;                  \
-	(_pAd)->StaActive.Aid = (_pAd)->MlmeAux.Aid;                                        \
-	(_pAd)->StaActive.AtimWin = (_pAd)->MlmeAux.AtimWin;                                \
-	(_pAd)->StaActive.CapabilityInfo = (_pAd)->MlmeAux.CapabilityInfo;                  \
-	(_pAd)->CommonCfg.BeaconPeriod = (_pAd)->MlmeAux.BeaconPeriod;                      \
-	(_pAd)->StaActive.CfpMaxDuration = (_pAd)->MlmeAux.CfpMaxDuration;                  \
-	(_pAd)->StaActive.CfpPeriod = (_pAd)->MlmeAux.CfpPeriod;                            \
-	(_pAd)->StaActive.SupRateLen = (_pAd)->MlmeAux.SupRateLen;                          \
-	NdisMoveMemory((_pAd)->StaActive.SupRate, (_pAd)->MlmeAux.SupRate, (_pAd)->MlmeAux.SupRateLen);\
-	(_pAd)->StaActive.ExtRateLen = (_pAd)->MlmeAux.ExtRateLen;                          \
-	NdisMoveMemory((_pAd)->StaActive.ExtRate, (_pAd)->MlmeAux.ExtRate, (_pAd)->MlmeAux.ExtRateLen);\
-	NdisMoveMemory(&(_pAd)->CommonCfg.APEdcaParm, &(_pAd)->MlmeAux.APEdcaParm, sizeof(struct rt_edca_parm));\
-	NdisMoveMemory(&(_pAd)->CommonCfg.APQosCapability, &(_pAd)->MlmeAux.APQosCapability, sizeof(struct rt_qos_capability_parm));\
-	NdisMoveMemory(&(_pAd)->CommonCfg.APQbssLoad, &(_pAd)->MlmeAux.APQbssLoad, sizeof(struct rt_qbss_load_parm));\
-	COPY_MAC_ADDR((_pAd)->MacTab.Content[BSSID_WCID].Addr, (_pAd)->MlmeAux.Bssid);      \
-	(_pAd)->MacTab.Content[BSSID_WCID].Aid = (_pAd)->MlmeAux.Aid;                       \
-	(_pAd)->MacTab.Content[BSSID_WCID].PairwiseKey.CipherAlg = (_pAd)->StaCfg.PairCipher;\
-	COPY_MAC_ADDR((_pAd)->MacTab.Content[BSSID_WCID].PairwiseKey.BssId, (_pAd)->MlmeAux.Bssid);\
-	(_pAd)->MacTab.Content[BSSID_WCID].RateLen = (_pAd)->StaActive.SupRateLen + (_pAd)->StaActive.ExtRateLen;\
-}
-
-/*
-	==========================================================================
-	Description:
-
-	IRQL = PASSIVE_LEVEL
-
-	==========================================================================
-*/
-void MlmeCntlInit(struct rt_rtmp_adapter *pAd,
-		  struct rt_state_machine *S, OUT STATE_MACHINE_FUNC Trans[])
-{
-	/* Control state machine differs from other state machines, the interface */
-	/* follows the standard interface */
-	pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
-}
-
-/*
-	==========================================================================
-	Description:
-
-	IRQL = DISPATCH_LEVEL
-
-	==========================================================================
-*/
-void MlmeCntlMachinePerformAction(struct rt_rtmp_adapter *pAd,
-				  struct rt_state_machine *S,
-				  struct rt_mlme_queue_elem *Elem)
-{
-	switch (pAd->Mlme.CntlMachine.CurrState) {
-	case CNTL_IDLE:
-		CntlIdleProc(pAd, Elem);
-		break;
-	case CNTL_WAIT_DISASSOC:
-		CntlWaitDisassocProc(pAd, Elem);
-		break;
-	case CNTL_WAIT_JOIN:
-		CntlWaitJoinProc(pAd, Elem);
-		break;
-
-		/* CNTL_WAIT_REASSOC is the only state in CNTL machine that does */
-		/* not triggered directly or indirectly by "RTMPSetInformation(OID_xxx)". */
-		/* Therefore not protected by NDIS's "only one outstanding OID request" */
-		/* rule. Which means NDIS may SET OID in the middle of ROAMing attempts. */
-		/* Current approach is to block new SET request at RTMPSetInformation() */
-		/* when CntlMachine.CurrState is not CNTL_IDLE */
-	case CNTL_WAIT_REASSOC:
-		CntlWaitReassocProc(pAd, Elem);
-		break;
-
-	case CNTL_WAIT_START:
-		CntlWaitStartProc(pAd, Elem);
-		break;
-	case CNTL_WAIT_AUTH:
-		CntlWaitAuthProc(pAd, Elem);
-		break;
-	case CNTL_WAIT_AUTH2:
-		CntlWaitAuthProc2(pAd, Elem);
-		break;
-	case CNTL_WAIT_ASSOC:
-		CntlWaitAssocProc(pAd, Elem);
-		break;
-
-	case CNTL_WAIT_OID_LIST_SCAN:
-		if (Elem->MsgType == MT2_SCAN_CONF) {
-			/* Resume TxRing after SCANING complete. We hope the out-of-service time */
-			/* won't be too long to let upper layer time-out the waiting frames */
-			RTMPResumeMsduTransmission(pAd);
-
-			pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
-
-			/* */
-			/* Set LED status to previous status. */
-			/* */
-			if (pAd->bLedOnScanning) {
-				pAd->bLedOnScanning = FALSE;
-				RTMPSetLED(pAd, pAd->LedStatus);
-			}
-		}
-		break;
-
-	case CNTL_WAIT_OID_DISASSOC:
-		if (Elem->MsgType == MT2_DISASSOC_CONF) {
-			LinkDown(pAd, FALSE);
-			pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
-		}
-		break;
-#ifdef RTMP_MAC_USB
-		/* */
-		/* This state is for that we want to connect to an AP but */
-		/* it didn't find on BSS List table. So we need to scan the air first, */
-		/* after that we can try to connect to the desired AP if available. */
-		/* */
-	case CNTL_WAIT_SCAN_FOR_CONNECT:
-		if (Elem->MsgType == MT2_SCAN_CONF) {
-			/* Resume TxRing after SCANING complete. We hope the out-of-service time */
-			/* won't be too long to let upper layer time-out the waiting frames */
-			RTMPResumeMsduTransmission(pAd);
-#ifdef CCX_SUPPORT
-			if (pAd->StaCfg.CCXReqType != MSRN_TYPE_UNUSED) {
-				/* Cisco scan request is finished, prepare beacon report */
-				MlmeEnqueue(pAd, AIRONET_STATE_MACHINE,
-					    MT2_AIRONET_SCAN_DONE, 0, NULL);
-			}
-#endif /* CCX_SUPPORT // */
-			pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
-
-			/* */
-			/* Check if we can connect to. */
-			/* */
-			BssTableSsidSort(pAd, &pAd->MlmeAux.SsidBssTab,
-					 (char *) pAd->MlmeAux.
-					 AutoReconnectSsid,
-					 pAd->MlmeAux.AutoReconnectSsidLen);
-			if (pAd->MlmeAux.SsidBssTab.BssNr > 0) {
-				MlmeAutoReconnectLastSSID(pAd);
-			}
-		}
-		break;
-#endif /* RTMP_MAC_USB // */
-	default:
-		DBGPRINT_ERR("ERROR! CNTL - Illegal message type(=%ld)", Elem->MsgType);
-		break;
-	}
-}
-
-/*
-	==========================================================================
-	Description:
-
-	IRQL = DISPATCH_LEVEL
-
-	==========================================================================
-*/
-void CntlIdleProc(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
-{
-	struct rt_mlme_disassoc_req DisassocReq;
-
-	if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF))
-		return;
-
-	switch (Elem->MsgType) {
-	case OID_802_11_SSID:
-		CntlOidSsidProc(pAd, Elem);
-		break;
-
-	case OID_802_11_BSSID:
-		CntlOidRTBssidProc(pAd, Elem);
-		break;
-
-	case OID_802_11_BSSID_LIST_SCAN:
-		CntlOidScanProc(pAd, Elem);
-		break;
-
-	case OID_802_11_DISASSOCIATE:
-		DisassocParmFill(pAd, &DisassocReq, pAd->CommonCfg.Bssid,
-				 REASON_DISASSOC_STA_LEAVING);
-		MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_DISASSOC_REQ,
-			    sizeof(struct rt_mlme_disassoc_req), &DisassocReq);
-		pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_DISASSOC;
-
-		if (pAd->StaCfg.WpaSupplicantUP !=
-		    WPA_SUPPLICANT_ENABLE_WITH_WEB_UI) {
-			/* Set the AutoReconnectSsid to prevent it reconnect to old SSID */
-			/* Since calling this indicate user don't want to connect to that SSID anymore. */
-			pAd->MlmeAux.AutoReconnectSsidLen = 32;
-			NdisZeroMemory(pAd->MlmeAux.AutoReconnectSsid,
-				       pAd->MlmeAux.AutoReconnectSsidLen);
-		}
-		break;
-
-	case MT2_MLME_ROAMING_REQ:
-		CntlMlmeRoamingProc(pAd, Elem);
-		break;
-
-	case OID_802_11_MIC_FAILURE_REPORT_FRAME:
-		WpaMicFailureReportFrame(pAd, Elem);
-		break;
-
-	default:
-		DBGPRINT(RT_DEBUG_TRACE,
-			 ("CNTL - Illegal message in CntlIdleProc(MsgType=%ld)\n",
-			  Elem->MsgType));
-		break;
-	}
-}
-
-void CntlOidScanProc(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
-{
-	struct rt_mlme_scan_req ScanReq;
-	unsigned long BssIdx = BSS_NOT_FOUND;
-	struct rt_bss_entry CurrBss;
-
-	/* record current BSS if network is connected. */
-	/* 2003-2-13 do not include current IBSS if this is the only STA in this IBSS. */
-	if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED)) {
-		BssIdx =
-		    BssSsidTableSearch(&pAd->ScanTab, pAd->CommonCfg.Bssid,
-				       (u8 *)pAd->CommonCfg.Ssid,
-				       pAd->CommonCfg.SsidLen,
-				       pAd->CommonCfg.Channel);
-		if (BssIdx != BSS_NOT_FOUND) {
-			NdisMoveMemory(&CurrBss, &pAd->ScanTab.BssEntry[BssIdx],
-				       sizeof(struct rt_bss_entry));
-		}
-	}
-	/* clean up previous SCAN result, add current BSS back to table if any */
-	BssTableInit(&pAd->ScanTab);
-	if (BssIdx != BSS_NOT_FOUND) {
-		/* DDK Note: If the NIC is associated with a particular BSSID and SSID */
-		/*    that are not contained in the list of BSSIDs generated by this scan, the */
-		/*    BSSID description of the currently associated BSSID and SSID should be */
-		/*    appended to the list of BSSIDs in the NIC's database. */
-		/* To ensure this, we append this BSS as the first entry in SCAN result */
-		NdisMoveMemory(&pAd->ScanTab.BssEntry[0], &CurrBss,
-			       sizeof(struct rt_bss_entry));
-		pAd->ScanTab.BssNr = 1;
-	}
-
-	ScanParmFill(pAd, &ScanReq, (char *)Elem->Msg, Elem->MsgLen, BSS_ANY,
-		     SCAN_ACTIVE);
-	MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_SCAN_REQ,
-		    sizeof(struct rt_mlme_scan_req), &ScanReq);
-	pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_LIST_SCAN;
-}
-
-/*
-	==========================================================================
-	Description:
-		Before calling this routine, user desired SSID should already been
-		recorded in CommonCfg.Ssid[]
-	IRQL = DISPATCH_LEVEL
-
-	==========================================================================
-*/
-void CntlOidSsidProc(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
-{
-	struct rt_ndis_802_11_ssid * pOidSsid = (struct rt_ndis_802_11_ssid *) Elem->Msg;
-	struct rt_mlme_disassoc_req DisassocReq;
-	unsigned long Now;
-
-	/* Step 1. record the desired user settings to MlmeAux */
-	NdisZeroMemory(pAd->MlmeAux.Ssid, MAX_LEN_OF_SSID);
-	NdisMoveMemory(pAd->MlmeAux.Ssid, pOidSsid->Ssid, pOidSsid->SsidLength);
-	pAd->MlmeAux.SsidLen = (u8)pOidSsid->SsidLength;
-	NdisZeroMemory(pAd->MlmeAux.Bssid, MAC_ADDR_LEN);
-	pAd->MlmeAux.BssType = pAd->StaCfg.BssType;
-
-	pAd->StaCfg.bAutoConnectByBssid = FALSE;
-
-	/* */
-	/* Update Reconnect Ssid, that user desired to connect. */
-	/* */
-	NdisZeroMemory(pAd->MlmeAux.AutoReconnectSsid, MAX_LEN_OF_SSID);
-	NdisMoveMemory(pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.Ssid,
-		       pAd->MlmeAux.SsidLen);
-	pAd->MlmeAux.AutoReconnectSsidLen = pAd->MlmeAux.SsidLen;
-
-	/* step 2. find all matching BSS in the lastest SCAN result (inBssTab) */
-	/*    & log them into MlmeAux.SsidBssTab for later-on iteration. Sort by RSSI order */
-	BssTableSsidSort(pAd, &pAd->MlmeAux.SsidBssTab,
-			 (char *)pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen);
-
-	DBGPRINT(RT_DEBUG_TRACE,
-		 ("CntlOidSsidProc():CNTL - %d BSS of %d BSS match the desire (%d)SSID - %s\n",
-		  pAd->MlmeAux.SsidBssTab.BssNr, pAd->ScanTab.BssNr,
-		  pAd->MlmeAux.SsidLen, pAd->MlmeAux.Ssid));
-	NdisGetSystemUpTime(&Now);
-
-	if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED) &&
-	    (pAd->CommonCfg.SsidLen ==
-	     pAd->MlmeAux.SsidBssTab.BssEntry[0].SsidLen)
-	    && NdisEqualMemory(pAd->CommonCfg.Ssid,
-			       pAd->MlmeAux.SsidBssTab.BssEntry[0].Ssid,
-			       pAd->CommonCfg.SsidLen)
-	    && MAC_ADDR_EQUAL(pAd->CommonCfg.Bssid,
-			      pAd->MlmeAux.SsidBssTab.BssEntry[0].Bssid)) {
-		/* Case 1. already connected with an AP who has the desired SSID */
-		/*         with highest RSSI */
-
-		/* Add checking Mode "LEAP" for CCX 1.0 */
-		if (((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) ||
-		     (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK) ||
-		     (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) ||
-		     (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK)
-		    ) &&
-		    (pAd->StaCfg.PortSecured == WPA_802_1X_PORT_NOT_SECURED)) {
-			/* case 1.1 For WPA, WPA-PSK, if the 1x port is not secured, we have to redo */
-			/*          connection process */
-			DBGPRINT(RT_DEBUG_TRACE,
-				 ("CntlOidSsidProc():CNTL - disassociate with current AP...\n"));
-			DisassocParmFill(pAd, &DisassocReq,
-					 pAd->CommonCfg.Bssid,
-					 REASON_DISASSOC_STA_LEAVING);
-			MlmeEnqueue(pAd, ASSOC_STATE_MACHINE,
-				    MT2_MLME_DISASSOC_REQ,
-				    sizeof(struct rt_mlme_disassoc_req),
-				    &DisassocReq);
-			pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_DISASSOC;
-		} else if (pAd->bConfigChanged == TRUE) {
-			/* case 1.2 Important Config has changed, we have to reconnect to the same AP */
-			DBGPRINT(RT_DEBUG_TRACE,
-				 ("CntlOidSsidProc():CNTL - disassociate with current AP Because config changed...\n"));
-			DisassocParmFill(pAd, &DisassocReq,
-					 pAd->CommonCfg.Bssid,
-					 REASON_DISASSOC_STA_LEAVING);
-			MlmeEnqueue(pAd, ASSOC_STATE_MACHINE,
-				    MT2_MLME_DISASSOC_REQ,
-				    sizeof(struct rt_mlme_disassoc_req),
-				    &DisassocReq);
-			pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_DISASSOC;
-		} else {
-			/* case 1.3. already connected to the SSID with highest RSSI. */
-			DBGPRINT(RT_DEBUG_TRACE,
-				 ("CntlOidSsidProc():CNTL - already with this BSSID. ignore this SET_SSID request\n"));
-			/* */
-			/* (HCT 12.1) 1c_wlan_mediaevents required */
-			/* media connect events are indicated when associating with the same AP */
-			/* */
-			if (INFRA_ON(pAd)) {
-				/* */
-				/* Since MediaState already is NdisMediaStateConnected */
-				/* We just indicate the connect event again to meet the WHQL required. */
-				/* */
-				pAd->IndicateMediaState =
-				    NdisMediaStateConnected;
-				RTMP_IndicateMediaState(pAd);
-				pAd->ExtraInfo = GENERAL_LINK_UP;	/* Update extra information to link is up */
-			}
-
-			pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
-			RtmpOSWrielessEventSend(pAd, SIOCGIWAP, -1,
-						&pAd->MlmeAux.Bssid[0], NULL,
-						0);
-		}
-	} else if (INFRA_ON(pAd)) {
-		/* */
-		/* For RT61 */
-		/* [88888] OID_802_11_SSID should have returned NDTEST_WEP_AP2(Returned: ) */
-		/* RT61 may lost SSID, and not connect to NDTEST_WEP_AP2 and will connect to NDTEST_WEP_AP2 by Autoreconnect */
-		/* But media status is connected, so the SSID not report correctly. */
-		/* */
-		if (!SSID_EQUAL
-		    (pAd->CommonCfg.Ssid, pAd->CommonCfg.SsidLen,
-		     pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen)) {
-			/* */
-			/* Different SSID means not Roaming case, so we let LinkDown() to Indicate a disconnect event. */
-			/* */
-			pAd->MlmeAux.CurrReqIsFromNdis = TRUE;
-		}
-		/* case 2. active INFRA association existent */
-		/*    roaming is done within miniport driver, nothing to do with configuration */
-		/*    utility. so upon a new SET(OID_802_11_SSID) is received, we just */
-		/*    disassociate with the current associated AP, */
-		/*    then perform a new association with this new SSID, no matter the */
-		/*    new/old SSID are the same or not. */
-		DBGPRINT(RT_DEBUG_TRACE,
-			 ("CntlOidSsidProc():CNTL - disassociate with current AP...\n"));
-		DisassocParmFill(pAd, &DisassocReq, pAd->CommonCfg.Bssid,
-				 REASON_DISASSOC_STA_LEAVING);
-		MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_DISASSOC_REQ,
-			    sizeof(struct rt_mlme_disassoc_req), &DisassocReq);
-		pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_DISASSOC;
-	} else {
-		if (ADHOC_ON(pAd)) {
-			DBGPRINT(RT_DEBUG_TRACE,
-				 ("CntlOidSsidProc():CNTL - drop current ADHOC\n"));
-			LinkDown(pAd, FALSE);
-			OPSTATUS_CLEAR_FLAG(pAd,
-					    fOP_STATUS_MEDIA_STATE_CONNECTED);
-			pAd->IndicateMediaState = NdisMediaStateDisconnected;
-			RTMP_IndicateMediaState(pAd);
-			pAd->ExtraInfo = GENERAL_LINK_DOWN;
-			DBGPRINT(RT_DEBUG_TRACE,
-				 ("CntlOidSsidProc():NDIS_STATUS_MEDIA_DISCONNECT Event C!\n"));
-		}
-
-		if ((pAd->MlmeAux.SsidBssTab.BssNr == 0) &&
-		    (pAd->StaCfg.bAutoReconnect == TRUE) &&
-		    (pAd->MlmeAux.BssType == BSS_INFRA) &&
-		    (MlmeValidateSSID(pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen)
-		     == TRUE)
-		    ) {
-			struct rt_mlme_scan_req ScanReq;
-
-			DBGPRINT(RT_DEBUG_TRACE,
-				 ("CntlOidSsidProc():CNTL - No matching BSS, start a new scan\n"));
-			ScanParmFill(pAd, &ScanReq, (char *)pAd->MlmeAux.Ssid,
-				     pAd->MlmeAux.SsidLen, BSS_ANY,
-				     SCAN_ACTIVE);
-			MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_SCAN_REQ,
-				    sizeof(struct rt_mlme_scan_req), &ScanReq);
-			pAd->Mlme.CntlMachine.CurrState =
-			    CNTL_WAIT_OID_LIST_SCAN;
-			/* Reset Missed scan number */
-			pAd->StaCfg.LastScanTime = Now;
-		} else {
-			pAd->MlmeAux.BssIdx = 0;
-			IterateOnBssTab(pAd);
-		}
-	}
-}
-
-/*
-	==========================================================================
-	Description:
-
-	IRQL = DISPATCH_LEVEL
-
-	==========================================================================
-*/
-void CntlOidRTBssidProc(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
-{
-	unsigned long BssIdx;
-	u8 *pOidBssid = (u8 *)Elem->Msg;
-	struct rt_mlme_disassoc_req DisassocReq;
-	struct rt_mlme_join_req JoinReq;
-
-	/* record user desired settings */
-	COPY_MAC_ADDR(pAd->MlmeAux.Bssid, pOidBssid);
-	pAd->MlmeAux.BssType = pAd->StaCfg.BssType;
-
-	/* find the desired BSS in the latest SCAN result table */
-	BssIdx = BssTableSearch(&pAd->ScanTab, pOidBssid, pAd->MlmeAux.Channel);
-	if (BssIdx == BSS_NOT_FOUND) {
-		struct rt_mlme_scan_req ScanReq;
-
-		DBGPRINT(RT_DEBUG_TRACE,
-			 ("CNTL - BSSID not found. reply NDIS_STATUS_NOT_ACCEPTED\n"));
-		/*pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE; */
-
-		DBGPRINT(RT_DEBUG_TRACE,
-			 ("CNTL - BSSID not found. start a new scan\n"));
-		ScanParmFill(pAd, &ScanReq, (char *)pAd->MlmeAux.Ssid,
-			     pAd->MlmeAux.SsidLen, BSS_ANY, SCAN_ACTIVE);
-		MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_SCAN_REQ,
-			    sizeof(struct rt_mlme_scan_req), &ScanReq);
-		pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_LIST_SCAN;
-		/* Reset Missed scan number */
-		NdisGetSystemUpTime(&pAd->StaCfg.LastScanTime);
-		return;
-	}
-	/* */
-	/* Update Reconnect Ssid, that user desired to connect. */
-	/* */
-	NdisZeroMemory(pAd->MlmeAux.AutoReconnectSsid, MAX_LEN_OF_SSID);
-	pAd->MlmeAux.AutoReconnectSsidLen =
-	    pAd->ScanTab.BssEntry[BssIdx].SsidLen;
-	NdisMoveMemory(pAd->MlmeAux.AutoReconnectSsid,
-		       pAd->ScanTab.BssEntry[BssIdx].Ssid,
-		       pAd->ScanTab.BssEntry[BssIdx].SsidLen);
-
-	/* copy the matched BSS entry from ScanTab to MlmeAux.SsidBssTab. Why? */
-	/* Because we need this entry to become the JOIN target in later on SYNC state machine */
-	pAd->MlmeAux.BssIdx = 0;
-	pAd->MlmeAux.SsidBssTab.BssNr = 1;
-	NdisMoveMemory(&pAd->MlmeAux.SsidBssTab.BssEntry[0],
-		       &pAd->ScanTab.BssEntry[BssIdx], sizeof(struct rt_bss_entry));
-
-	/* Add SSID into MlmeAux for site survey joining hidden SSID */
-	pAd->MlmeAux.SsidLen = pAd->ScanTab.BssEntry[BssIdx].SsidLen;
-	NdisMoveMemory(pAd->MlmeAux.Ssid, pAd->ScanTab.BssEntry[BssIdx].Ssid,
-		       pAd->MlmeAux.SsidLen);
-
-	{
-		if (INFRA_ON(pAd)) {
-			/* disassoc from current AP first */
-			DBGPRINT(RT_DEBUG_TRACE,
-				 ("CNTL - disassociate with current AP ...\n"));
-			DisassocParmFill(pAd, &DisassocReq,
-					 pAd->CommonCfg.Bssid,
-					 REASON_DISASSOC_STA_LEAVING);
-			MlmeEnqueue(pAd, ASSOC_STATE_MACHINE,
-				    MT2_MLME_DISASSOC_REQ,
-				    sizeof(struct rt_mlme_disassoc_req),
-				    &DisassocReq);
-
-			pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_DISASSOC;
-		} else {
-			if (ADHOC_ON(pAd)) {
-				DBGPRINT(RT_DEBUG_TRACE,
-					 ("CNTL - drop current ADHOC\n"));
-				LinkDown(pAd, FALSE);
-				OPSTATUS_CLEAR_FLAG(pAd,
-						    fOP_STATUS_MEDIA_STATE_CONNECTED);
-				pAd->IndicateMediaState =
-				    NdisMediaStateDisconnected;
-				RTMP_IndicateMediaState(pAd);
-				pAd->ExtraInfo = GENERAL_LINK_DOWN;
-				DBGPRINT(RT_DEBUG_TRACE,
-					 ("NDIS_STATUS_MEDIA_DISCONNECT Event C!\n"));
-			}
-			/* Change the wepstatus to original wepstatus */
-			pAd->StaCfg.WepStatus = pAd->StaCfg.OrigWepStatus;
-			pAd->StaCfg.PairCipher = pAd->StaCfg.OrigWepStatus;
-			pAd->StaCfg.GroupCipher = pAd->StaCfg.OrigWepStatus;
-
-			/* Check cipher suite, AP must have more secured cipher than station setting */
-			/* Set the Pairwise and Group cipher to match the intended AP setting */
-			/* We can only connect to AP with less secured cipher setting */
-			if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA)
-			    || (pAd->StaCfg.AuthMode ==
-				Ndis802_11AuthModeWPAPSK)) {
-				pAd->StaCfg.GroupCipher =
-				    pAd->ScanTab.BssEntry[BssIdx].WPA.
-				    GroupCipher;
-
-				if (pAd->StaCfg.WepStatus ==
-				    pAd->ScanTab.BssEntry[BssIdx].WPA.
-				    PairCipher)
-					pAd->StaCfg.PairCipher =
-					    pAd->ScanTab.BssEntry[BssIdx].WPA.
-					    PairCipher;
-				else if (pAd->ScanTab.BssEntry[BssIdx].WPA.
-					 PairCipherAux != Ndis802_11WEPDisabled)
-					pAd->StaCfg.PairCipher =
-					    pAd->ScanTab.BssEntry[BssIdx].WPA.
-					    PairCipherAux;
-				else	/* There is no PairCipher Aux, downgrade our capability to TKIP */
-					pAd->StaCfg.PairCipher =
-					    Ndis802_11Encryption2Enabled;
-			} else
-			    if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2)
-				|| (pAd->StaCfg.AuthMode ==
-				    Ndis802_11AuthModeWPA2PSK)) {
-				pAd->StaCfg.GroupCipher =
-				    pAd->ScanTab.BssEntry[BssIdx].WPA2.
-				    GroupCipher;
-
-				if (pAd->StaCfg.WepStatus ==
-				    pAd->ScanTab.BssEntry[BssIdx].WPA2.
-				    PairCipher)
-					pAd->StaCfg.PairCipher =
-					    pAd->ScanTab.BssEntry[BssIdx].WPA2.
-					    PairCipher;
-				else if (pAd->ScanTab.BssEntry[BssIdx].WPA2.
-					 PairCipherAux != Ndis802_11WEPDisabled)
-					pAd->StaCfg.PairCipher =
-					    pAd->ScanTab.BssEntry[BssIdx].WPA2.
-					    PairCipherAux;
-				else	/* There is no PairCipher Aux, downgrade our capability to TKIP */
-					pAd->StaCfg.PairCipher =
-					    Ndis802_11Encryption2Enabled;
-
-				/* RSN capability */
-				pAd->StaCfg.RsnCapability =
-				    pAd->ScanTab.BssEntry[BssIdx].WPA2.
-				    RsnCapability;
-			}
-			/* Set Mix cipher flag */
-			pAd->StaCfg.bMixCipher =
-			    (pAd->StaCfg.PairCipher ==
-			     pAd->StaCfg.GroupCipher) ? FALSE : TRUE;
-			/*if (pAd->StaCfg.bMixCipher == TRUE)
-			   {
-			   // If mix cipher, re-build RSNIE
-			   RTMPMakeRSNIE(pAd, pAd->StaCfg.AuthMode, pAd->StaCfg.WepStatus, 0);
-			   } */
-			/* No active association, join the BSS immediately */
-			DBGPRINT(RT_DEBUG_TRACE, ("CNTL - joining %pM ...\n",
-					pOidBssid));
-
-			JoinParmFill(pAd, &JoinReq, pAd->MlmeAux.BssIdx);
-			MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_JOIN_REQ,
-				    sizeof(struct rt_mlme_join_req), &JoinReq);
-
-			pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_JOIN;
-		}
-	}
-}
-
-/* Roaming is the only external request triggering CNTL state machine */
-/* despite of other "SET OID" operation. All "SET OID" related operations */
-/* happen in sequence, because no other SET OID will be sent to this device */
-/* until the the previous SET operation is complete (successful o failed). */
-/* So, how do we quarantee this ROAMING request won't corrupt other "SET OID"? */
-/* or been corrupted by other "SET OID"? */
-/* */
-/* IRQL = DISPATCH_LEVEL */
-void CntlMlmeRoamingProc(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
-{
-	u8 BBPValue = 0;
-
-	DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Roaming in MlmeAux.RoamTab...\n"));
-
-	{
-		/*Let BBP register at 20MHz to do (fast) roaming. */
-		RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue);
-		BBPValue &= (~0x18);
-		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue);
-
-		NdisMoveMemory(&pAd->MlmeAux.SsidBssTab, &pAd->MlmeAux.RoamTab,
-			       sizeof(pAd->MlmeAux.RoamTab));
-		pAd->MlmeAux.SsidBssTab.BssNr = pAd->MlmeAux.RoamTab.BssNr;
-
-		BssTableSortByRssi(&pAd->MlmeAux.SsidBssTab);
-		pAd->MlmeAux.BssIdx = 0;
-		IterateOnBssTab(pAd);
-	}
-}
-
-/*
-	==========================================================================
-	Description:
-
-	IRQL = DISPATCH_LEVEL
-
-	==========================================================================
-*/
-void CntlWaitDisassocProc(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
-{
-	struct rt_mlme_start_req StartReq;
-
-	if (Elem->MsgType == MT2_DISASSOC_CONF) {
-		DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Dis-associate successful\n"));
-
-		if (pAd->CommonCfg.bWirelessEvent) {
-			RTMPSendWirelessEvent(pAd, IW_DISASSOC_EVENT_FLAG,
-					      pAd->MacTab.Content[BSSID_WCID].
-					      Addr, BSS0, 0);
-		}
-
-		LinkDown(pAd, FALSE);
-
-		/* case 1. no matching BSS, and user wants ADHOC, so we just start a new one */
-		if ((pAd->MlmeAux.SsidBssTab.BssNr == 0)
-		    && (pAd->StaCfg.BssType == BSS_ADHOC)) {
-			DBGPRINT(RT_DEBUG_TRACE,
-				 ("CNTL - No matching BSS, start a new ADHOC (Ssid=%s)...\n",
-				  pAd->MlmeAux.Ssid));
-			StartParmFill(pAd, &StartReq, (char *)pAd->MlmeAux.Ssid,
-				      pAd->MlmeAux.SsidLen);
-			MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_START_REQ,
-				    sizeof(struct rt_mlme_start_req), &StartReq);
-			pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_START;
-		}
-		/* case 2. try each matched BSS */
-		else {
-			pAd->MlmeAux.BssIdx = 0;
-
-			IterateOnBssTab(pAd);
-		}
-	}
-}
-
-/*
-	==========================================================================
-	Description:
-
-	IRQL = DISPATCH_LEVEL
-
-	==========================================================================
-*/
-void CntlWaitJoinProc(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
-{
-	u16 Reason;
-	struct rt_mlme_auth_req AuthReq;
-
-	if (Elem->MsgType == MT2_JOIN_CONF) {
-		NdisMoveMemory(&Reason, Elem->Msg, sizeof(u16));
-		if (Reason == MLME_SUCCESS) {
-			/* 1. joined an IBSS, we are pretty much done here */
-			if (pAd->MlmeAux.BssType == BSS_ADHOC) {
-				/* */
-				/* 5G bands rules of Japan: */
-				/* Ad hoc must be disabled in W53(ch52,56,60,64) channels. */
-				/* */
-				if ((pAd->CommonCfg.bIEEE80211H == 1) &&
-				    RadarChannelCheck(pAd,
-						      pAd->CommonCfg.Channel)
-				    ) {
-					pAd->Mlme.CntlMachine.CurrState =
-					    CNTL_IDLE;
-					DBGPRINT(RT_DEBUG_TRACE,
-						 ("CNTL - Channel=%d, Join adhoc on W53(52,56,60,64) Channels are not accepted\n",
-						  pAd->CommonCfg.Channel));
-					return;
-				}
-
-				LinkUp(pAd, BSS_ADHOC);
-				pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
-				DBGPRINT(RT_DEBUG_TRACE,
-					("CNTL - join the IBSS = %pM ...\n",
-						pAd->CommonCfg.Bssid));
-
-				pAd->IndicateMediaState =
-				    NdisMediaStateConnected;
-				pAd->ExtraInfo = GENERAL_LINK_UP;
-			}
-			/* 2. joined a new INFRA network, start from authentication */
-			else {
-				{
-					/* either Ndis802_11AuthModeShared or Ndis802_11AuthModeAutoSwitch, try shared key first */
-					if ((pAd->StaCfg.AuthMode ==
-					     Ndis802_11AuthModeShared)
-					    || (pAd->StaCfg.AuthMode ==
-						Ndis802_11AuthModeAutoSwitch)) {
-						AuthParmFill(pAd, &AuthReq,
-							     pAd->MlmeAux.Bssid,
-							     AUTH_MODE_KEY);
-					} else {
-						AuthParmFill(pAd, &AuthReq,
-							     pAd->MlmeAux.Bssid,
-							     AUTH_MODE_OPEN);
-					}
-					MlmeEnqueue(pAd, AUTH_STATE_MACHINE,
-						    MT2_MLME_AUTH_REQ,
-						    sizeof
-						    (struct rt_mlme_auth_req),
-						    &AuthReq);
-				}
-
-				pAd->Mlme.CntlMachine.CurrState =
-				    CNTL_WAIT_AUTH;
-			}
-		} else {
-			/* 3. failed, try next BSS */
-			pAd->MlmeAux.BssIdx++;
-			IterateOnBssTab(pAd);
-		}
-	}
-}
-
-/*
-	==========================================================================
-	Description:
-
-	IRQL = DISPATCH_LEVEL
-
-	==========================================================================
-*/
-void CntlWaitStartProc(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
-{
-	u16 Result;
-
-	if (Elem->MsgType == MT2_START_CONF) {
-		NdisMoveMemory(&Result, Elem->Msg, sizeof(u16));
-		if (Result == MLME_SUCCESS) {
-			/* */
-			/* 5G bands rules of Japan: */
-			/* Ad hoc must be disabled in W53(ch52,56,60,64) channels. */
-			/* */
-			if ((pAd->CommonCfg.bIEEE80211H == 1) &&
-			    RadarChannelCheck(pAd, pAd->CommonCfg.Channel)
-			    ) {
-				pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
-				DBGPRINT(RT_DEBUG_TRACE,
-					 ("CNTL - Channel=%d, Start adhoc on W53(52,56,60,64) Channels are not accepted\n",
-					  pAd->CommonCfg.Channel));
-				return;
-			}
-			NdisZeroMemory(&pAd->StaActive.SupportedPhyInfo.
-				       MCSSet[0], 16);
-			if (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED) {
-				N_ChannelCheck(pAd);
-				SetCommonHT(pAd);
-				NdisMoveMemory(&pAd->MlmeAux.AddHtInfo,
-					       &pAd->CommonCfg.AddHTInfo,
-					       sizeof(struct rt_add_ht_info_ie));
-				RTMPCheckHt(pAd, BSSID_WCID,
-					    &pAd->CommonCfg.HtCapability,
-					    &pAd->CommonCfg.AddHTInfo);
-				pAd->StaActive.SupportedPhyInfo.bHtEnable =
-				    TRUE;
-				NdisMoveMemory(&pAd->StaActive.SupportedPhyInfo.
-					       MCSSet[0],
-					       &pAd->CommonCfg.HtCapability.
-					       MCSSet[0], 16);
-				COPY_HTSETTINGS_FROM_MLME_AUX_TO_ACTIVE_CFG
-				    (pAd);
-
-				if ((pAd->CommonCfg.HtCapability.HtCapInfo.
-				     ChannelWidth == BW_40)
-				    && (pAd->CommonCfg.AddHTInfo.AddHtInfo.
-					ExtChanOffset == EXTCHA_ABOVE)) {
-					pAd->MlmeAux.CentralChannel =
-					    pAd->CommonCfg.Channel + 2;
-				} else
-				    if ((pAd->CommonCfg.HtCapability.HtCapInfo.
-					 ChannelWidth == BW_40)
-					&& (pAd->CommonCfg.AddHTInfo.AddHtInfo.
-					    ExtChanOffset == EXTCHA_BELOW)) {
-					pAd->MlmeAux.CentralChannel =
-					    pAd->CommonCfg.Channel - 2;
-				}
-			} else {
-				pAd->StaActive.SupportedPhyInfo.bHtEnable =
-				    FALSE;
-			}
-			LinkUp(pAd, BSS_ADHOC);
-			pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
-			/* Before send beacon, driver need do radar detection */
-			if ((pAd->CommonCfg.Channel > 14)
-			    && (pAd->CommonCfg.bIEEE80211H == 1)
-			    && RadarChannelCheck(pAd, pAd->CommonCfg.Channel)) {
-				pAd->CommonCfg.RadarDetect.RDMode =
-				    RD_SILENCE_MODE;
-				pAd->CommonCfg.RadarDetect.RDCount = 0;
-			}
-
-			DBGPRINT(RT_DEBUG_TRACE,
-				("CNTL - start a new IBSS = %pM ...\n",
-					pAd->CommonCfg.Bssid));
-		} else {
-			DBGPRINT(RT_DEBUG_TRACE,
-				 ("CNTL - Start IBSS fail. BUG!\n"));
-			pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
-		}
-	}
-}
-
-/*
-	==========================================================================
-	Description:
-
-	IRQL = DISPATCH_LEVEL
-
-	==========================================================================
-*/
-void CntlWaitAuthProc(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
-{
-	u16 Reason;
-	struct rt_mlme_assoc_req AssocReq;
-	struct rt_mlme_auth_req AuthReq;
-
-	if (Elem->MsgType == MT2_AUTH_CONF) {
-		NdisMoveMemory(&Reason, Elem->Msg, sizeof(u16));
-		if (Reason == MLME_SUCCESS) {
-			DBGPRINT(RT_DEBUG_TRACE, ("CNTL - AUTH OK\n"));
-			AssocParmFill(pAd, &AssocReq, pAd->MlmeAux.Bssid,
-				      pAd->MlmeAux.CapabilityInfo,
-				      ASSOC_TIMEOUT,
-				      pAd->StaCfg.DefaultListenCount);
-
-			{
-				MlmeEnqueue(pAd, ASSOC_STATE_MACHINE,
-					    MT2_MLME_ASSOC_REQ,
-					    sizeof(struct rt_mlme_assoc_req),
-					    &AssocReq);
-
-				pAd->Mlme.CntlMachine.CurrState =
-				    CNTL_WAIT_ASSOC;
-			}
-		} else {
-			/* This fail may because of the AP already keep us in its MAC table without */
-			/* ageing-out. The previous authentication attempt must have let it remove us. */
-			/* so try Authentication again may help. For D-Link DWL-900AP+ compatibility. */
-			DBGPRINT(RT_DEBUG_TRACE,
-				 ("CNTL - AUTH FAIL, try again...\n"));
-
-			{
-				if ((pAd->StaCfg.AuthMode ==
-				     Ndis802_11AuthModeShared)
-				    || (pAd->StaCfg.AuthMode ==
-					Ndis802_11AuthModeAutoSwitch)) {
-					/* either Ndis802_11AuthModeShared or Ndis802_11AuthModeAutoSwitch, try shared key first */
-					AuthParmFill(pAd, &AuthReq,
-						     pAd->MlmeAux.Bssid,
-						     AUTH_MODE_KEY);
-				} else {
-					AuthParmFill(pAd, &AuthReq,
-						     pAd->MlmeAux.Bssid,
-						     AUTH_MODE_OPEN);
-				}
-				MlmeEnqueue(pAd, AUTH_STATE_MACHINE,
-					    MT2_MLME_AUTH_REQ,
-					    sizeof(struct rt_mlme_auth_req),
-					    &AuthReq);
-
-			}
-			pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_AUTH2;
-		}
-	}
-}
-
-/*
-	==========================================================================
-	Description:
-
-	IRQL = DISPATCH_LEVEL
-
-	==========================================================================
-*/
-void CntlWaitAuthProc2(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
-{
-	u16 Reason;
-	struct rt_mlme_assoc_req AssocReq;
-	struct rt_mlme_auth_req AuthReq;
-
-	if (Elem->MsgType == MT2_AUTH_CONF) {
-		NdisMoveMemory(&Reason, Elem->Msg, sizeof(u16));
-		if (Reason == MLME_SUCCESS) {
-			DBGPRINT(RT_DEBUG_TRACE, ("CNTL - AUTH OK\n"));
-			AssocParmFill(pAd, &AssocReq, pAd->MlmeAux.Bssid,
-				      pAd->MlmeAux.CapabilityInfo,
-				      ASSOC_TIMEOUT,
-				      pAd->StaCfg.DefaultListenCount);
-			{
-				MlmeEnqueue(pAd, ASSOC_STATE_MACHINE,
-					    MT2_MLME_ASSOC_REQ,
-					    sizeof(struct rt_mlme_assoc_req),
-					    &AssocReq);
-
-				pAd->Mlme.CntlMachine.CurrState =
-				    CNTL_WAIT_ASSOC;
-			}
-		} else {
-			if ((pAd->StaCfg.AuthMode ==
-			     Ndis802_11AuthModeAutoSwitch)
-			    && (pAd->MlmeAux.Alg == Ndis802_11AuthModeShared)) {
-				DBGPRINT(RT_DEBUG_TRACE,
-					 ("CNTL - AUTH FAIL, try OPEN system...\n"));
-				AuthParmFill(pAd, &AuthReq, pAd->MlmeAux.Bssid,
-					     Ndis802_11AuthModeOpen);
-				MlmeEnqueue(pAd, AUTH_STATE_MACHINE,
-					    MT2_MLME_AUTH_REQ,
-					    sizeof(struct rt_mlme_auth_req),
-					    &AuthReq);
-
-				pAd->Mlme.CntlMachine.CurrState =
-				    CNTL_WAIT_AUTH2;
-			} else {
-				/* not success, try next BSS */
-				DBGPRINT(RT_DEBUG_TRACE,
-					 ("CNTL - AUTH FAIL, give up; try next BSS\n"));
-				pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;	/*??????? */
-				pAd->MlmeAux.BssIdx++;
-				IterateOnBssTab(pAd);
-			}
-		}
-	}
-}
-
-/*
-	==========================================================================
-	Description:
-
-	IRQL = DISPATCH_LEVEL
-
-	==========================================================================
-*/
-void CntlWaitAssocProc(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
-{
-	u16 Reason;
-
-	if (Elem->MsgType == MT2_ASSOC_CONF) {
-		NdisMoveMemory(&Reason, Elem->Msg, sizeof(u16));
-		if (Reason == MLME_SUCCESS) {
-			if (pAd->CommonCfg.bWirelessEvent) {
-				RTMPSendWirelessEvent(pAd, IW_ASSOC_EVENT_FLAG,
-						      pAd->MacTab.
-						      Content[BSSID_WCID].Addr,
-						      BSS0, 0);
-			}
-
-			LinkUp(pAd, BSS_INFRA);
-			pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
-			DBGPRINT(RT_DEBUG_TRACE,
-				 ("CNTL - Association successful on BSS #%ld\n",
-				  pAd->MlmeAux.BssIdx));
-		} else {
-			/* not success, try next BSS */
-			DBGPRINT(RT_DEBUG_TRACE,
-				 ("CNTL - Association fails on BSS #%ld\n",
-				  pAd->MlmeAux.BssIdx));
-			pAd->MlmeAux.BssIdx++;
-			IterateOnBssTab(pAd);
-		}
-	}
-}
-
-/*
-	==========================================================================
-	Description:
-
-	IRQL = DISPATCH_LEVEL
-
-	==========================================================================
-*/
-void CntlWaitReassocProc(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
-{
-	u16 Result;
-
-	if (Elem->MsgType == MT2_REASSOC_CONF) {
-		NdisMoveMemory(&Result, Elem->Msg, sizeof(u16));
-		if (Result == MLME_SUCCESS) {
-			/* send wireless event - for association */
-			if (pAd->CommonCfg.bWirelessEvent)
-				RTMPSendWirelessEvent(pAd, IW_ASSOC_EVENT_FLAG,
-						      pAd->MacTab.
-						      Content[BSSID_WCID].Addr,
-						      BSS0, 0);
-
-			/* */
-			/* NDIS requires a new Link UP indication but no Link Down for RE-ASSOC */
-			/* */
-			LinkUp(pAd, BSS_INFRA);
-
-			pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
-			DBGPRINT(RT_DEBUG_TRACE,
-				 ("CNTL - Re-assocition successful on BSS #%ld\n",
-				  pAd->MlmeAux.RoamIdx));
-		} else {
-			/* reassoc failed, try to pick next BSS in the BSS Table */
-			DBGPRINT(RT_DEBUG_TRACE,
-				 ("CNTL - Re-assocition fails on BSS #%ld\n",
-				  pAd->MlmeAux.RoamIdx));
-			{
-				pAd->MlmeAux.RoamIdx++;
-				IterateOnBssTab2(pAd);
-			}
-		}
-	}
-}
-
-void AdhocTurnOnQos(struct rt_rtmp_adapter *pAd)
-{
-#define AC0_DEF_TXOP		0
-#define AC1_DEF_TXOP		0
-#define AC2_DEF_TXOP		94
-#define AC3_DEF_TXOP		47
-
-	/* Turn on QOs if use HT rate. */
-	if (pAd->CommonCfg.APEdcaParm.bValid == FALSE) {
-		pAd->CommonCfg.APEdcaParm.bValid = TRUE;
-		pAd->CommonCfg.APEdcaParm.Aifsn[0] = 3;
-		pAd->CommonCfg.APEdcaParm.Aifsn[1] = 7;
-		pAd->CommonCfg.APEdcaParm.Aifsn[2] = 1;
-		pAd->CommonCfg.APEdcaParm.Aifsn[3] = 1;
-
-		pAd->CommonCfg.APEdcaParm.Cwmin[0] = 4;
-		pAd->CommonCfg.APEdcaParm.Cwmin[1] = 4;
-		pAd->CommonCfg.APEdcaParm.Cwmin[2] = 3;
-		pAd->CommonCfg.APEdcaParm.Cwmin[3] = 2;
-
-		pAd->CommonCfg.APEdcaParm.Cwmax[0] = 10;
-		pAd->CommonCfg.APEdcaParm.Cwmax[1] = 6;
-		pAd->CommonCfg.APEdcaParm.Cwmax[2] = 4;
-		pAd->CommonCfg.APEdcaParm.Cwmax[3] = 3;
-
-		pAd->CommonCfg.APEdcaParm.Txop[0] = 0;
-		pAd->CommonCfg.APEdcaParm.Txop[1] = 0;
-		pAd->CommonCfg.APEdcaParm.Txop[2] = AC2_DEF_TXOP;
-		pAd->CommonCfg.APEdcaParm.Txop[3] = AC3_DEF_TXOP;
-	}
-	AsicSetEdcaParm(pAd, &pAd->CommonCfg.APEdcaParm);
-}
-
-/*
-	==========================================================================
-	Description:
-
-	IRQL = DISPATCH_LEVEL
-
-	==========================================================================
-*/
-void LinkUp(struct rt_rtmp_adapter *pAd, u8 BssType)
-{
-	unsigned long Now;
-	u32 Data;
-	BOOLEAN Cancelled;
-	u8 Value = 0, idx = 0, HashIdx = 0;
-	struct rt_mac_table_entry *pEntry = NULL, *pCurrEntry = NULL;
-
-	/* Init ChannelQuality to prevent DEAD_CQI at initial LinkUp */
-	pAd->Mlme.ChannelQuality = 50;
-
-	pEntry = MacTableLookup(pAd, pAd->CommonCfg.Bssid);
-	if (pEntry) {
-		MacTableDeleteEntry(pAd, pEntry->Aid, pEntry->Addr);
-		pEntry = NULL;
-	}
-
-	pEntry = &pAd->MacTab.Content[BSSID_WCID];
-
-	/* */
-	/* ASSOC - DisassocTimeoutAction */
-	/* CNTL - Dis-associate successful */
-	/* ! LINK DOWN ! */
-	/* [88888] OID_802_11_SSID should have returned NDTEST_WEP_AP2(Returned: ) */
-	/* */
-	/* To prevent DisassocTimeoutAction to call Link down after we link up, */
-	/* cancel the DisassocTimer no matter what it start or not. */
-	/* */
-	RTMPCancelTimer(&pAd->MlmeAux.DisassocTimer, &Cancelled);
-
-	COPY_SETTINGS_FROM_MLME_AUX_TO_ACTIVE_CFG(pAd);
-
-	COPY_HTSETTINGS_FROM_MLME_AUX_TO_ACTIVE_CFG(pAd);
-
-#ifdef RTMP_MAC_PCI
-	/* Before power save before link up function, We will force use 1R. */
-	/* So after link up, check Rx antenna # again. */
-	RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &Value);
-	if (pAd->Antenna.field.RxPath == 3) {
-		Value |= (0x10);
-	} else if (pAd->Antenna.field.RxPath == 2) {
-		Value |= (0x8);
-	} else if (pAd->Antenna.field.RxPath == 1) {
-		Value |= (0x0);
-	}
-	RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, Value);
-	pAd->StaCfg.BBPR3 = Value;
-#endif /* RTMP_MAC_PCI // */
-
-	if (BssType == BSS_ADHOC) {
-		OPSTATUS_SET_FLAG(pAd, fOP_STATUS_ADHOC_ON);
-		OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_INFRA_ON);
-
-		if (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED)
-			AdhocTurnOnQos(pAd);
-
-		DBGPRINT(RT_DEBUG_TRACE, ("Adhoc LINK UP!\n"));
-	} else {
-		OPSTATUS_SET_FLAG(pAd, fOP_STATUS_INFRA_ON);
-		OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_ADHOC_ON);
-
-		DBGPRINT(RT_DEBUG_TRACE, ("Infra LINK UP!\n"));
-	}
-
-	/* 3*3 */
-	/* reset Tx beamforming bit */
-	RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &Value);
-	Value &= (~0x01);
-	Value |= pAd->CommonCfg.RegTransmitSetting.field.TxBF;
-	RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, Value);
-
-	/* Change to AP channel */
-	if ((pAd->CommonCfg.CentralChannel > pAd->CommonCfg.Channel)
-	    && (pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth == BW_40)) {
-		/* Must use 40MHz. */
-		pAd->CommonCfg.BBPCurrentBW = BW_40;
-		AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, FALSE);
-		AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel);
-
-		RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &Value);
-		Value &= (~0x18);
-		Value |= 0x10;
-		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, Value);
-
-		/*  RX : control channel at lower */
-		RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &Value);
-		Value &= (~0x20);
-		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, Value);
-#ifdef RTMP_MAC_PCI
-		pAd->StaCfg.BBPR3 = Value;
-#endif /* RTMP_MAC_PCI // */
-
-		RTMP_IO_READ32(pAd, TX_BAND_CFG, &Data);
-		Data &= 0xfffffffe;
-		RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Data);
-
-		if (pAd->MACVersion == 0x28600100) {
-			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, 0x1A);
-			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, 0x0A);
-			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, 0x16);
-			DBGPRINT(RT_DEBUG_TRACE, ("rt2860C !\n"));
-		}
-
-		DBGPRINT(RT_DEBUG_TRACE,
-			 ("40MHz Lower LINK UP! Control Channel at Below. Central = %d \n",
-			  pAd->CommonCfg.CentralChannel));
-	} else if ((pAd->CommonCfg.CentralChannel < pAd->CommonCfg.Channel)
-		   && (pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth ==
-		       BW_40)) {
-		/* Must use 40MHz. */
-		pAd->CommonCfg.BBPCurrentBW = BW_40;
-		AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, FALSE);
-		AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel);
-
-		RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &Value);
-		Value &= (~0x18);
-		Value |= 0x10;
-		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, Value);
-
-		RTMP_IO_READ32(pAd, TX_BAND_CFG, &Data);
-		Data |= 0x1;
-		RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Data);
-
-		RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &Value);
-		Value |= (0x20);
-		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, Value);
-#ifdef RTMP_MAC_PCI
-		pAd->StaCfg.BBPR3 = Value;
-#endif /* RTMP_MAC_PCI // */
-
-		if (pAd->MACVersion == 0x28600100) {
-			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, 0x1A);
-			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, 0x0A);
-			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, 0x16);
-			DBGPRINT(RT_DEBUG_TRACE, ("rt2860C !\n"));
-		}
-
-		DBGPRINT(RT_DEBUG_TRACE,
-			 ("40MHz Upper LINK UP! Control Channel at UpperCentral = %d \n",
-			  pAd->CommonCfg.CentralChannel));
-	} else {
-		pAd->CommonCfg.BBPCurrentBW = BW_20;
-		pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel;
-		AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
-		AsicLockChannel(pAd, pAd->CommonCfg.Channel);
-
-		RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &Value);
-		Value &= (~0x18);
-		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, Value);
-
-		RTMP_IO_READ32(pAd, TX_BAND_CFG, &Data);
-		Data &= 0xfffffffe;
-		RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Data);
-
-		RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &Value);
-		Value &= (~0x20);
-		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, Value);
-#ifdef RTMP_MAC_PCI
-		pAd->StaCfg.BBPR3 = Value;
-#endif /* RTMP_MAC_PCI // */
-
-		if (pAd->MACVersion == 0x28600100) {
-			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, 0x16);
-			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, 0x08);
-			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, 0x11);
-			DBGPRINT(RT_DEBUG_TRACE, ("rt2860C !\n"));
-		}
-
-		DBGPRINT(RT_DEBUG_TRACE, ("20MHz LINK UP!\n"));
-	}
-
-	RTMPSetAGCInitValue(pAd, pAd->CommonCfg.BBPCurrentBW);
-
-	/* */
-	/* Save BBP_R66 value, it will be used in RTUSBResumeMsduTransmission */
-	/* */
-	RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R66,
-				    &pAd->BbpTuning.R66CurrentValue);
-
-	DBGPRINT(RT_DEBUG_TRACE,
-		 ("LINK UP! (BssType=%d, AID=%d, ssid=%s, Channel=%d, CentralChannel = %d)\n",
-		  BssType, pAd->StaActive.Aid, pAd->CommonCfg.Ssid,
-		  pAd->CommonCfg.Channel, pAd->CommonCfg.CentralChannel));
-
-	DBGPRINT(RT_DEBUG_TRACE,
-		 ("LINK UP! (Density =%d, )\n",
-		  pAd->MacTab.Content[BSSID_WCID].MpduDensity));
-
-	AsicSetBssid(pAd, pAd->CommonCfg.Bssid);
-
-	AsicSetSlotTime(pAd, TRUE);
-	AsicSetEdcaParm(pAd, &pAd->CommonCfg.APEdcaParm);
-
-	/* Call this for RTS protection for legacy rate, we will always enable RTS threshold, but normally it will not hit */
-	AsicUpdateProtect(pAd, 0, (OFDMSETPROTECT | CCKSETPROTECT), TRUE,
-			  FALSE);
-
-	if ((pAd->StaActive.SupportedPhyInfo.bHtEnable == TRUE)) {
-		/* Update HT protection for based on AP's operating mode. */
-		if (pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent == 1) {
-			AsicUpdateProtect(pAd,
-					  pAd->MlmeAux.AddHtInfo.AddHtInfo2.
-					  OperaionMode, ALLN_SETPROTECT, FALSE,
-					  TRUE);
-		} else
-			AsicUpdateProtect(pAd,
-					  pAd->MlmeAux.AddHtInfo.AddHtInfo2.
-					  OperaionMode, ALLN_SETPROTECT, FALSE,
-					  FALSE);
-	}
-
-	NdisZeroMemory(&pAd->DrsCounters, sizeof(struct rt_counter_drs));
-
-	NdisGetSystemUpTime(&Now);
-	pAd->StaCfg.LastBeaconRxTime = Now;	/* last RX timestamp */
-
-	if ((pAd->CommonCfg.TxPreamble != Rt802_11PreambleLong) &&
-	    CAP_IS_SHORT_PREAMBLE_ON(pAd->StaActive.CapabilityInfo)) {
-		MlmeSetTxPreamble(pAd, Rt802_11PreambleShort);
-	}
-
-	OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED);
-
-	if (pAd->CommonCfg.RadarDetect.RDMode == RD_SILENCE_MODE) {
-	}
-	pAd->CommonCfg.RadarDetect.RDMode = RD_NORMAL_MODE;
-
-	if (BssType == BSS_ADHOC) {
-		MakeIbssBeacon(pAd);
-		if ((pAd->CommonCfg.Channel > 14)
-		    && (pAd->CommonCfg.bIEEE80211H == 1)
-		    && RadarChannelCheck(pAd, pAd->CommonCfg.Channel)) {
-			;	/*Do nothing */
-		} else {
-			AsicEnableIbssSync(pAd);
-		}
-
-		/* In ad hoc mode, use MAC table from index 1. */
-		/* p.s ASIC use all 0xff as termination of WCID table search.To prevent it's 0xff-ff-ff-ff-ff-ff, Write 0 here. */
-		RTMP_IO_WRITE32(pAd, MAC_WCID_BASE, 0x00);
-		RTMP_IO_WRITE32(pAd, 0x1808, 0x00);
-
-		/* If WEP is enabled, add key material and cipherAlg into Asic */
-		/* Fill in Shared Key Table(offset: 0x6c00) and Shared Key Mode(offset: 0x7000) */
-
-		if (pAd->StaCfg.WepStatus == Ndis802_11WEPEnabled) {
-			u8 *Key;
-			u8 CipherAlg;
-
-			for (idx = 0; idx < SHARE_KEY_NUM; idx++) {
-				CipherAlg = pAd->SharedKey[BSS0][idx].CipherAlg;
-				Key = pAd->SharedKey[BSS0][idx].Key;
-
-				if (pAd->SharedKey[BSS0][idx].KeyLen > 0) {
-					/* Set key material and cipherAlg to Asic */
-					AsicAddSharedKeyEntry(pAd, BSS0, idx,
-							      CipherAlg, Key,
-							      NULL, NULL);
-
-					if (idx == pAd->StaCfg.DefaultKeyId) {
-						/* Update WCID attribute table and IVEIV table for this group key table */
-						RTMPAddWcidAttributeEntry(pAd,
-									  BSS0,
-									  idx,
-									  CipherAlg,
-									  NULL);
-					}
-				}
-
-			}
-		}
-		/* If WPANone is enabled, add key material and cipherAlg into Asic */
-		/* Fill in Shared Key Table(offset: 0x6c00) and Shared Key Mode(offset: 0x7000) */
-		else if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPANone) {
-			pAd->StaCfg.DefaultKeyId = 0;	/* always be zero */
-
-			NdisZeroMemory(&pAd->SharedKey[BSS0][0],
-				       sizeof(struct rt_cipher_key));
-			pAd->SharedKey[BSS0][0].KeyLen = LEN_TKIP_EK;
-			NdisMoveMemory(pAd->SharedKey[BSS0][0].Key,
-				       pAd->StaCfg.PMK, LEN_TKIP_EK);
-
-			if (pAd->StaCfg.PairCipher ==
-			    Ndis802_11Encryption2Enabled) {
-				NdisMoveMemory(pAd->SharedKey[BSS0][0].RxMic,
-					       &pAd->StaCfg.PMK[16],
-					       LEN_TKIP_RXMICK);
-				NdisMoveMemory(pAd->SharedKey[BSS0][0].TxMic,
-					       &pAd->StaCfg.PMK[16],
-					       LEN_TKIP_TXMICK);
-			}
-			/* Decide its ChiperAlg */
-			if (pAd->StaCfg.PairCipher ==
-			    Ndis802_11Encryption2Enabled)
-				pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_TKIP;
-			else if (pAd->StaCfg.PairCipher ==
-				 Ndis802_11Encryption3Enabled)
-				pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_AES;
-			else {
-				DBGPRINT(RT_DEBUG_TRACE,
-					 ("Unknow Cipher (=%d), set Cipher to AES\n",
-					  pAd->StaCfg.PairCipher));
-				pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_AES;
-			}
-
-			/* Set key material and cipherAlg to Asic */
-			AsicAddSharedKeyEntry(pAd,
-					      BSS0,
-					      0,
-					      pAd->SharedKey[BSS0][0].CipherAlg,
-					      pAd->SharedKey[BSS0][0].Key,
-					      pAd->SharedKey[BSS0][0].TxMic,
-					      pAd->SharedKey[BSS0][0].RxMic);
-
-			/* Update WCID attribute table and IVEIV table for this group key table */
-			RTMPAddWcidAttributeEntry(pAd, BSS0, 0,
-						  pAd->SharedKey[BSS0][0].
-						  CipherAlg, NULL);
-
-		}
-
-	} else			/* BSS_INFRA */
-	{
-		/* Check the new SSID with last SSID */
-		while (Cancelled == TRUE) {
-			if (pAd->CommonCfg.LastSsidLen ==
-			    pAd->CommonCfg.SsidLen) {
-				if (RTMPCompareMemory
-				    (pAd->CommonCfg.LastSsid,
-				     pAd->CommonCfg.Ssid,
-				     pAd->CommonCfg.LastSsidLen) == 0) {
-					/* Link to the old one no linkdown is required. */
-					break;
-				}
-			}
-			/* Send link down event before set to link up */
-			pAd->IndicateMediaState = NdisMediaStateDisconnected;
-			RTMP_IndicateMediaState(pAd);
-			pAd->ExtraInfo = GENERAL_LINK_DOWN;
-			DBGPRINT(RT_DEBUG_TRACE,
-				 ("NDIS_STATUS_MEDIA_DISCONNECT Event AA!\n"));
-			break;
-		}
-
-		/* */
-		/* On WPA mode, Remove All Keys if not connect to the last BSSID */
-		/* Key will be set after 4-way handshake. */
-		/* */
-		if (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA) {
-			unsigned long IV;
-
-			/* Remove all WPA keys */
-			RTMP_CLEAR_PSFLAG(pAd, fRTMP_PS_CAN_GO_SLEEP);
-			RTMPWPARemoveAllKeys(pAd);
-			pAd->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED;
-			pAd->StaCfg.PrivacyFilter =
-			    Ndis802_11PrivFilter8021xWEP;
-
-			/* Fixed connection failed with Range Maximizer - 515 AP (Marvell Chip) when security is WPAPSK/TKIP */
-			/* If IV related values are too large in GroupMsg2, AP would ignore this message. */
-			IV = 1;
-			IV |= (pAd->StaCfg.DefaultKeyId << 30);
-			AsicUpdateWCIDIVEIV(pAd, BSSID_WCID, IV, 0);
-		}
-		/* NOTE: */
-		/* the decision of using "short slot time" or not may change dynamically due to */
-		/* new STA association to the AP. so we have to decide that upon parsing BEACON, not here */
-
-		/* NOTE: */
-		/* the decision to use "RTC/CTS" or "CTS-to-self" protection or not may change dynamically */
-		/* due to new STA association to the AP. so we have to decide that upon parsing BEACON, not here */
-
-		ComposePsPoll(pAd);
-		ComposeNullFrame(pAd);
-
-		AsicEnableBssSync(pAd);
-
-		/* Add BSSID to WCID search table */
-		AsicUpdateRxWCIDTable(pAd, BSSID_WCID, pAd->CommonCfg.Bssid);
-
-		/* If WEP is enabled, add pairwise and shared key */
-		if (((pAd->StaCfg.WpaSupplicantUP) &&
-		     (pAd->StaCfg.WepStatus == Ndis802_11WEPEnabled) &&
-		     (pAd->StaCfg.PortSecured == WPA_802_1X_PORT_SECURED)) ||
-		    ((pAd->StaCfg.WpaSupplicantUP == WPA_SUPPLICANT_DISABLE) &&
-		     (pAd->StaCfg.WepStatus == Ndis802_11WEPEnabled))) {
-			u8 *Key;
-			u8 CipherAlg;
-
-			for (idx = 0; idx < SHARE_KEY_NUM; idx++) {
-				CipherAlg = pAd->SharedKey[BSS0][idx].CipherAlg;
-				Key = pAd->SharedKey[BSS0][idx].Key;
-
-				if (pAd->SharedKey[BSS0][idx].KeyLen > 0) {
-					/* Set key material and cipherAlg to Asic */
-					AsicAddSharedKeyEntry(pAd, BSS0, idx,
-							      CipherAlg, Key,
-							      NULL, NULL);
-
-					if (idx == pAd->StaCfg.DefaultKeyId) {
-						/* Assign group key info */
-						RTMPAddWcidAttributeEntry(pAd,
-									  BSS0,
-									  idx,
-									  CipherAlg,
-									  NULL);
-
-						pEntry->Aid = BSSID_WCID;
-						/* Assign pairwise key info */
-						RTMPAddWcidAttributeEntry(pAd,
-									  BSS0,
-									  idx,
-									  CipherAlg,
-									  pEntry);
-					}
-				}
-			}
-		}
-		/* only INFRASTRUCTURE mode need to indicate connectivity immediately; ADHOC mode */
-		/* should wait until at least 2 active nodes in this BSSID. */
-		OPSTATUS_SET_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED);
-
-		/* For GUI ++ */
-		if (pAd->StaCfg.AuthMode < Ndis802_11AuthModeWPA) {
-			pAd->IndicateMediaState = NdisMediaStateConnected;
-			pAd->ExtraInfo = GENERAL_LINK_UP;
-			RTMP_IndicateMediaState(pAd);
-		} else if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK) ||
-			   (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK))
-		{
-			if (pAd->StaCfg.WpaSupplicantUP ==
-			    WPA_SUPPLICANT_DISABLE)
-				RTMPSetTimer(&pAd->Mlme.LinkDownTimer,
-					     LINK_DOWN_TIMEOUT);
-		}
-		/* -- */
-
-		/* Add BSSID in my MAC Table. */
-		NdisAcquireSpinLock(&pAd->MacTabLock);
-		/* add this MAC entry into HASH table */
-		if (pEntry) {
-			HashIdx = MAC_ADDR_HASH_INDEX(pAd->CommonCfg.Bssid);
-			if (pAd->MacTab.Hash[HashIdx] == NULL) {
-				pAd->MacTab.Hash[HashIdx] = pEntry;
-			} else {
-				pCurrEntry = pAd->MacTab.Hash[HashIdx];
-				while (pCurrEntry->pNext != NULL) {
-					pCurrEntry = pCurrEntry->pNext;
-				}
-				pCurrEntry->pNext = pEntry;
-			}
-		}
-		RTMPMoveMemory(pEntry->Addr, pAd->CommonCfg.Bssid,
-			       MAC_ADDR_LEN);
-		pEntry->Aid = BSSID_WCID;
-		pEntry->pAd = pAd;
-		pEntry->ValidAsCLI = TRUE;	/*Although this is bssid..still set ValidAsCl */
-		pAd->MacTab.Size = 1;	/* infra mode always set MACtab size =1. */
-		pEntry->Sst = SST_ASSOC;
-		pEntry->AuthState = SST_ASSOC;
-		pEntry->AuthMode = pAd->StaCfg.AuthMode;
-		pEntry->WepStatus = pAd->StaCfg.WepStatus;
-		if (pEntry->AuthMode < Ndis802_11AuthModeWPA) {
-			pEntry->WpaState = AS_NOTUSE;
-			pEntry->PrivacyFilter = Ndis802_11PrivFilterAcceptAll;
-		} else {
-			pEntry->WpaState = AS_PTKSTART;
-			pEntry->PrivacyFilter = Ndis802_11PrivFilter8021xWEP;
-		}
-		NdisReleaseSpinLock(&pAd->MacTabLock);
-
-		DBGPRINT(RT_DEBUG_TRACE,
-			 ("LINK UP!  ClientStatusFlags=%lx)\n",
-			  pAd->MacTab.Content[BSSID_WCID].ClientStatusFlags));
-
-		MlmeUpdateTxRates(pAd, TRUE, BSS0);
-		MlmeUpdateHtTxRates(pAd, BSS0);
-		DBGPRINT(RT_DEBUG_TRACE,
-			 ("LINK UP! (StaActive.bHtEnable =%d, )\n",
-			  pAd->StaActive.SupportedPhyInfo.bHtEnable));
-
-		if (pAd->CommonCfg.bAggregationCapable) {
-			if ((pAd->CommonCfg.bPiggyBackCapable)
-			    && (pAd->MlmeAux.APRalinkIe & 0x00000003) == 3) {
-				OPSTATUS_SET_FLAG(pAd,
-						  fOP_STATUS_PIGGYBACK_INUSED);
-				OPSTATUS_SET_FLAG(pAd,
-						  fOP_STATUS_AGGREGATION_INUSED);
-				CLIENT_STATUS_SET_FLAG(pEntry,
-						       fCLIENT_STATUS_AGGREGATION_CAPABLE);
-				CLIENT_STATUS_SET_FLAG(pEntry,
-						       fCLIENT_STATUS_PIGGYBACK_CAPABLE);
-				RTMPSetPiggyBack(pAd, TRUE);
-				DBGPRINT(RT_DEBUG_TRACE,
-					 ("Turn on Piggy-Back\n"));
-			} else if (pAd->MlmeAux.APRalinkIe & 0x00000001) {
-				OPSTATUS_SET_FLAG(pAd,
-						  fOP_STATUS_AGGREGATION_INUSED);
-				CLIENT_STATUS_SET_FLAG(pEntry,
-						       fCLIENT_STATUS_AGGREGATION_CAPABLE);
-				DBGPRINT(RT_DEBUG_TRACE,
-					 ("Ralink Aggregation\n"));
-			}
-		}
-
-		if (pAd->MlmeAux.APRalinkIe != 0x0) {
-			if (CLIENT_STATUS_TEST_FLAG
-			    (pEntry, fCLIENT_STATUS_RDG_CAPABLE)) {
-				AsicEnableRDG(pAd);
-			}
-			OPSTATUS_SET_FLAG(pAd, fCLIENT_STATUS_RALINK_CHIPSET);
-			CLIENT_STATUS_SET_FLAG(pEntry,
-					       fCLIENT_STATUS_RALINK_CHIPSET);
-		} else {
-			OPSTATUS_CLEAR_FLAG(pAd, fCLIENT_STATUS_RALINK_CHIPSET);
-			CLIENT_STATUS_CLEAR_FLAG(pEntry,
-						 fCLIENT_STATUS_RALINK_CHIPSET);
-		}
-	}
-
-	DBGPRINT(RT_DEBUG_TRACE,
-		 ("NDIS_STATUS_MEDIA_CONNECT Event B!.BACapability = %x. ClientStatusFlags = %lx\n",
-		  pAd->CommonCfg.BACapability.word,
-		  pAd->MacTab.Content[BSSID_WCID].ClientStatusFlags));
-
-	/* Set LED */
-	RTMPSetLED(pAd, LED_LINK_UP);
-
-	pAd->Mlme.PeriodicRound = 0;
-	pAd->Mlme.OneSecPeriodicRound = 0;
-	pAd->bConfigChanged = FALSE;	/* Reset config flag */
-	pAd->ExtraInfo = GENERAL_LINK_UP;	/* Update extra information after link is up */
-
-	/* Set basic auto fall back */
-	{
-		u8 *pTable;
-		u8 TableSize = 0;
-
-		MlmeSelectTxRateTable(pAd, &pAd->MacTab.Content[BSSID_WCID],
-				      &pTable, &TableSize,
-				      &pAd->CommonCfg.TxRateIndex);
-		AsicUpdateAutoFallBackTable(pAd, pTable);
-	}
-
-	NdisAcquireSpinLock(&pAd->MacTabLock);
-	pEntry->HTPhyMode.word = pAd->StaCfg.HTPhyMode.word;
-	pEntry->MaxHTPhyMode.word = pAd->StaCfg.HTPhyMode.word;
-	if (pAd->StaCfg.bAutoTxRateSwitch == FALSE) {
-		pEntry->bAutoTxRateSwitch = FALSE;
-
-		if (pEntry->HTPhyMode.field.MCS == 32)
-			pEntry->HTPhyMode.field.ShortGI = GI_800;
-
-		if ((pEntry->HTPhyMode.field.MCS > MCS_7)
-		    || (pEntry->HTPhyMode.field.MCS == 32))
-			pEntry->HTPhyMode.field.STBC = STBC_NONE;
-
-		/* If the legacy mode is set, overwrite the transmit setting of this entry. */
-		if (pEntry->HTPhyMode.field.MODE <= MODE_OFDM)
-			RTMPUpdateLegacyTxSetting((u8)pAd->StaCfg.
-						  DesiredTransmitSetting.field.
-						  FixedTxMode, pEntry);
-	} else
-		pEntry->bAutoTxRateSwitch = TRUE;
-	NdisReleaseSpinLock(&pAd->MacTabLock);
-
-	/*  Let Link Status Page display first initial rate. */
-	pAd->LastTxRate = (u16)(pEntry->HTPhyMode.word);
-	/* Select DAC according to HT or Legacy */
-	if (pAd->StaActive.SupportedPhyInfo.MCSSet[0] != 0x00) {
-		RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R1, &Value);
-		Value &= (~0x18);
-		if (pAd->Antenna.field.TxPath == 2) {
-			Value |= 0x10;
-		}
-		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R1, Value);
-	} else {
-		RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R1, &Value);
-		Value &= (~0x18);
-		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R1, Value);
-	}
-
-	if (pAd->StaActive.SupportedPhyInfo.bHtEnable == FALSE) {
-	} else if (pEntry->MaxRAmpduFactor == 0) {
-		/* If HT AP doesn't support MaxRAmpduFactor = 1, we need to set max PSDU to 0. */
-		/* Because our Init value is 1 at MACRegTable. */
-		RTMP_IO_WRITE32(pAd, MAX_LEN_CFG, 0x0fff);
-	}
-	/* Patch for Marvel AP to gain high throughput */
-	/* Need to set as following, */
-	/* 1. Set txop in register-EDCA_AC0_CFG as 0x60 */
-	/* 2. Set EnTXWriteBackDDONE in register-WPDMA_GLO_CFG as zero */
-	/* 3. PBF_MAX_PCNT as 0x1F3FBF9F */
-	/* 4. kick per two packets when dequeue */
-	/* */
-	/* Txop can only be modified when RDG is off, WMM is disable and TxBurst is enable */
-	/* */
-	/* if 1. Legacy AP WMM on,  or 2. 11n AP, AMPDU disable.  Force turn off burst no matter what bEnableTxBurst is. */
-	if (!((pAd->CommonCfg.RxStream == 1) && (pAd->CommonCfg.TxStream == 1))
-	    && (pAd->StaCfg.bForceTxBurst == FALSE)
-	    &&
-	    (((pAd->StaActive.SupportedPhyInfo.bHtEnable == FALSE)
-	      && OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED))
-	     || ((pAd->StaActive.SupportedPhyInfo.bHtEnable == TRUE)
-		 && (pAd->CommonCfg.BACapability.field.Policy == BA_NOTUSE)))) {
-		RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &Data);
-		Data &= 0xFFFFFF00;
-		RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Data);
-
-		RTMP_IO_WRITE32(pAd, PBF_MAX_PCNT, 0x1F3F7F9F);
-		DBGPRINT(RT_DEBUG_TRACE, ("Txburst 1\n"));
-	} else if (pAd->CommonCfg.bEnableTxBurst) {
-		RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &Data);
-		Data &= 0xFFFFFF00;
-		Data |= 0x60;
-		RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Data);
-		pAd->CommonCfg.IOTestParm.bNowAtherosBurstOn = TRUE;
-
-		RTMP_IO_WRITE32(pAd, PBF_MAX_PCNT, 0x1F3FBF9F);
-		DBGPRINT(RT_DEBUG_TRACE, ("Txburst 2\n"));
-	} else {
-		RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &Data);
-		Data &= 0xFFFFFF00;
-		RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Data);
-
-		RTMP_IO_WRITE32(pAd, PBF_MAX_PCNT, 0x1F3F7F9F);
-		DBGPRINT(RT_DEBUG_TRACE, ("Txburst 3\n"));
-	}
-
-	/* Re-check to turn on TX burst or not. */
-	if ((pAd->CommonCfg.IOTestParm.bLastAtheros == TRUE)
-	    && ((STA_WEP_ON(pAd)) || (STA_TKIP_ON(pAd)))) {
-		pAd->CommonCfg.IOTestParm.bNextDisableRxBA = TRUE;
-		if (pAd->CommonCfg.bEnableTxBurst) {
-			u32 MACValue = 0;
-			/* Force disable  TXOP value in this case. The same action in MLMEUpdateProtect too. */
-			/* I didn't change PBF_MAX_PCNT setting. */
-			RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &MACValue);
-			MACValue &= 0xFFFFFF00;
-			RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, MACValue);
-			pAd->CommonCfg.IOTestParm.bNowAtherosBurstOn = FALSE;
-		}
-	} else {
-		pAd->CommonCfg.IOTestParm.bNextDisableRxBA = FALSE;
-	}
-
-	pAd->CommonCfg.IOTestParm.bLastAtheros = FALSE;
-	COPY_MAC_ADDR(pAd->CommonCfg.LastBssid, pAd->CommonCfg.Bssid);
-	DBGPRINT(RT_DEBUG_TRACE,
-		 ("pAd->bNextDisableRxBA= %d \n",
-		  pAd->CommonCfg.IOTestParm.bNextDisableRxBA));
-	/* BSSID add in one MAC entry too.  Because in Tx, ASIC need to check Cipher and IV/EIV, BAbitmap */
-	/* Pther information in MACTab.Content[BSSID_WCID] is not necessary for driver. */
-	/* Note: As STA, The MACTab.Content[BSSID_WCID]. PairwiseKey and Shared Key for BSS0 are the same. */
-
-	if (pAd->StaCfg.WepStatus <= Ndis802_11WEPDisabled) {
-		if (pAd->StaCfg.WpaSupplicantUP &&
-		    (pAd->StaCfg.WepStatus == Ndis802_11WEPEnabled) &&
-		    (pAd->StaCfg.IEEE8021X == TRUE)) ;
-		else {
-			pAd->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED;
-			pAd->StaCfg.PrivacyFilter =
-			    Ndis802_11PrivFilterAcceptAll;
-		}
-	}
-
-	NdisAcquireSpinLock(&pAd->MacTabLock);
-	pEntry->PortSecured = pAd->StaCfg.PortSecured;
-	NdisReleaseSpinLock(&pAd->MacTabLock);
-
-	/* */
-	/* Patch Atheros AP TX will breakdown issue. */
-	/* AP Model: DLink DWL-8200AP */
-	/* */
-	if (INFRA_ON(pAd) && OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED)
-	    && STA_TKIP_ON(pAd)) {
-		RTMP_IO_WRITE32(pAd, RX_PARSER_CFG, 0x01);
-	} else {
-		RTMP_IO_WRITE32(pAd, RX_PARSER_CFG, 0x00);
-	}
-
-	RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS);
-
-	RTMP_CLEAR_PSFLAG(pAd, fRTMP_PS_GO_TO_SLEEP_NOW);
-}
-
-/*
-	==========================================================================
-
-	Routine	Description:
-		Disconnect current BSSID
-
-	Arguments:
-		pAd				- Pointer to our adapter
-		IsReqFromAP		- Request from AP
-
-	Return Value:
-		None
-
-	IRQL = DISPATCH_LEVEL
-
-	Note:
-		We need more information to know it's this requst from AP.
-		If yes! we need to do extra handling, for example, remove the WPA key.
-		Otherwise on 4-way handshaking will fail, since the WPA key didn't get
-		removed while auto reconnect.
-		Disconnect request from AP, it means we will start afresh 4-way handshaking
-		on WPA mode.
-
-	==========================================================================
-*/
-void LinkDown(struct rt_rtmp_adapter *pAd, IN BOOLEAN IsReqFromAP)
-{
-	u8 i, ByteValue = 0;
-
-	/* Do nothing if monitor mode is on */
-	if (MONITOR_ON(pAd))
-		return;
-
-	RTMP_CLEAR_PSFLAG(pAd, fRTMP_PS_GO_TO_SLEEP_NOW);
-	/* Comment the codes, because the line 2291 call the same function. */
-	/* RTMPCancelTimer(&pAd->Mlme.PsPollTimer, &Cancelled); */
-	/* Not allowed go to sleep within the linkdown function. */
-	RTMP_CLEAR_PSFLAG(pAd, fRTMP_PS_CAN_GO_SLEEP);
-
-	if (pAd->CommonCfg.bWirelessEvent) {
-		RTMPSendWirelessEvent(pAd, IW_STA_LINKDOWN_EVENT_FLAG,
-				      pAd->MacTab.Content[BSSID_WCID].Addr,
-				      BSS0, 0);
-	}
-
-	DBGPRINT(RT_DEBUG_TRACE, ("LINK DOWN!\n"));
-	OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED);
-
-#ifdef RTMP_MAC_PCI
-	if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE)) {
-		BOOLEAN Cancelled;
-		pAd->Mlme.bPsPollTimerRunning = FALSE;
-		RTMPCancelTimer(&pAd->Mlme.PsPollTimer, &Cancelled);
-	}
-
-	pAd->bPCIclkOff = FALSE;
-#endif /* RTMP_MAC_PCI // */
-
-	if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE)
-	    || RTMP_TEST_PSFLAG(pAd, fRTMP_PS_SET_PCI_CLK_OFF_COMMAND)
-	    || RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF)) {
-		AUTO_WAKEUP_STRUC AutoWakeupCfg;
-		AsicForceWakeup(pAd, TRUE);
-		AutoWakeupCfg.word = 0;
-		RTMP_IO_WRITE32(pAd, AUTO_WAKEUP_CFG, AutoWakeupCfg.word);
-		OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_DOZE);
-	}
-#ifdef RTMP_MAC_PCI
-	pAd->bPCIclkOff = FALSE;
-#endif /* RTMP_MAC_PCI // */
-
-	if (ADHOC_ON(pAd))	/* Adhoc mode link down */
-	{
-		DBGPRINT(RT_DEBUG_TRACE, ("LINK DOWN 1!\n"));
-
-		OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_ADHOC_ON);
-		OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED);
-		pAd->IndicateMediaState = NdisMediaStateDisconnected;
-		RTMP_IndicateMediaState(pAd);
-		pAd->ExtraInfo = GENERAL_LINK_DOWN;
-		BssTableDeleteEntry(&pAd->ScanTab, pAd->CommonCfg.Bssid,
-				    pAd->CommonCfg.Channel);
-		DBGPRINT(RT_DEBUG_TRACE,
-			 (" MacTab.Size=%d !\n", pAd->MacTab.Size));
-	} else			/* Infra structure mode */
-	{
-		DBGPRINT(RT_DEBUG_TRACE, ("LINK DOWN 2!\n"));
-
-		OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_INFRA_ON);
-		OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED);
-
-		/* Saved last SSID for linkup comparison */
-		pAd->CommonCfg.LastSsidLen = pAd->CommonCfg.SsidLen;
-		NdisMoveMemory(pAd->CommonCfg.LastSsid, pAd->CommonCfg.Ssid,
-			       pAd->CommonCfg.LastSsidLen);
-		COPY_MAC_ADDR(pAd->CommonCfg.LastBssid, pAd->CommonCfg.Bssid);
-		if (pAd->MlmeAux.CurrReqIsFromNdis == TRUE) {
-			pAd->IndicateMediaState = NdisMediaStateDisconnected;
-			RTMP_IndicateMediaState(pAd);
-			pAd->ExtraInfo = GENERAL_LINK_DOWN;
-			DBGPRINT(RT_DEBUG_TRACE,
-				 ("NDIS_STATUS_MEDIA_DISCONNECT Event A!\n"));
-			pAd->MlmeAux.CurrReqIsFromNdis = FALSE;
-		} else {
-			/* */
-			/* If disassociation request is from NDIS, then we don't need to delete BSSID from entry. */
-			/* Otherwise lost beacon or receive De-Authentication from AP, */
-			/* then we should delete BSSID from BssTable. */
-			/* If we don't delete from entry, roaming will fail. */
-			/* */
-			BssTableDeleteEntry(&pAd->ScanTab, pAd->CommonCfg.Bssid,
-					    pAd->CommonCfg.Channel);
-		}
-
-		/* restore back to - */
-		/*      1. long slot (20 us) or short slot (9 us) time */
-		/*      2. turn on/off RTS/CTS and/or CTS-to-self protection */
-		/*      3. short preamble */
-		OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_BG_PROTECTION_INUSED);
-
-	}
-
-	for (i = 1; i < MAX_LEN_OF_MAC_TABLE; i++) {
-		if (pAd->MacTab.Content[i].ValidAsCLI == TRUE)
-			MacTableDeleteEntry(pAd, pAd->MacTab.Content[i].Aid,
-					    pAd->MacTab.Content[i].Addr);
-	}
-
-	AsicSetSlotTime(pAd, TRUE);	/*FALSE); */
-	AsicSetEdcaParm(pAd, NULL);
-
-	/* Set LED */
-	RTMPSetLED(pAd, LED_LINK_DOWN);
-	pAd->LedIndicatorStrength = 0xF0;
-	RTMPSetSignalLED(pAd, -100);	/* Force signal strength Led to be turned off, firmware has not done it. */
-
-	AsicDisableSync(pAd);
-
-	pAd->Mlme.PeriodicRound = 0;
-	pAd->Mlme.OneSecPeriodicRound = 0;
-
-	if (pAd->StaCfg.BssType == BSS_INFRA) {
-		/* Remove StaCfg Information after link down */
-		NdisZeroMemory(pAd->CommonCfg.Bssid, MAC_ADDR_LEN);
-		NdisZeroMemory(pAd->CommonCfg.Ssid, MAX_LEN_OF_SSID);
-		pAd->CommonCfg.SsidLen = 0;
-	}
-
-	NdisZeroMemory(&pAd->MlmeAux.HtCapability, sizeof(struct rt_ht_capability_ie));
-	NdisZeroMemory(&pAd->MlmeAux.AddHtInfo, sizeof(struct rt_add_ht_info_ie));
-	pAd->MlmeAux.HtCapabilityLen = 0;
-	pAd->MlmeAux.NewExtChannelOffset = 0xff;
-
-	/* Reset WPA-PSK state. Only reset when supplicant enabled */
-	if (pAd->StaCfg.WpaState != SS_NOTUSE) {
-		pAd->StaCfg.WpaState = SS_START;
-		/* Clear Replay counter */
-		NdisZeroMemory(pAd->StaCfg.ReplayCounter, 8);
-
-	}
-	/* */
-	/* if link down come from AP, we need to remove all WPA keys on WPA mode. */
-	/* otherwise will cause 4-way handshaking failed, since the WPA key not empty. */
-	/* */
-	if ((IsReqFromAP) && (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)) {
-		/* Remove all WPA keys */
-		RTMPWPARemoveAllKeys(pAd);
-	}
-	/* 802.1x port control */
-
-	/* Prevent clear PortSecured here with static WEP */
-	/* NetworkManger set security policy first then set SSID to connect AP. */
-	if (pAd->StaCfg.WpaSupplicantUP &&
-	    (pAd->StaCfg.WepStatus == Ndis802_11WEPEnabled) &&
-	    (pAd->StaCfg.IEEE8021X == FALSE)) {
-		pAd->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED;
-	} else {
-		pAd->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED;
-		pAd->StaCfg.PrivacyFilter = Ndis802_11PrivFilter8021xWEP;
-	}
-
-	NdisAcquireSpinLock(&pAd->MacTabLock);
-	NdisZeroMemory(&pAd->MacTab, sizeof(struct rt_mac_table));
-	pAd->MacTab.Content[BSSID_WCID].PortSecured = pAd->StaCfg.PortSecured;
-	NdisReleaseSpinLock(&pAd->MacTabLock);
-
-	pAd->StaCfg.MicErrCnt = 0;
-
-	pAd->IndicateMediaState = NdisMediaStateDisconnected;
-	/* Update extra information to link is up */
-	pAd->ExtraInfo = GENERAL_LINK_DOWN;
-
-	pAd->StaActive.SupportedPhyInfo.bHtEnable = FALSE;
-
-#ifdef RTMP_MAC_USB
-	pAd->bUsbTxBulkAggre = FALSE;
-#endif /* RTMP_MAC_USB // */
-
-	/* Clean association information */
-	NdisZeroMemory(&pAd->StaCfg.AssocInfo,
-		       sizeof(struct rt_ndis_802_11_association_information));
-	pAd->StaCfg.AssocInfo.Length =
-	    sizeof(struct rt_ndis_802_11_association_information);
-	pAd->StaCfg.ReqVarIELen = 0;
-	pAd->StaCfg.ResVarIELen = 0;
-
-	/* */
-	/* Reset RSSI value after link down */
-	/* */
-	pAd->StaCfg.RssiSample.AvgRssi0 = 0;
-	pAd->StaCfg.RssiSample.AvgRssi0X8 = 0;
-	pAd->StaCfg.RssiSample.AvgRssi1 = 0;
-	pAd->StaCfg.RssiSample.AvgRssi1X8 = 0;
-	pAd->StaCfg.RssiSample.AvgRssi2 = 0;
-	pAd->StaCfg.RssiSample.AvgRssi2X8 = 0;
-
-	/* Restore MlmeRate */
-	pAd->CommonCfg.MlmeRate = pAd->CommonCfg.BasicMlmeRate;
-	pAd->CommonCfg.RtsRate = pAd->CommonCfg.BasicMlmeRate;
-
-	/* */
-	/* After Link down, reset piggy-back setting in ASIC. Disable RDG. */
-	/* */
-	if (pAd->CommonCfg.BBPCurrentBW == BW_40) {
-		pAd->CommonCfg.BBPCurrentBW = BW_20;
-		RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &ByteValue);
-		ByteValue &= (~0x18);
-		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, ByteValue);
-	}
-	/* Reset DAC */
-	RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R1, &ByteValue);
-	ByteValue &= (~0x18);
-	if (pAd->Antenna.field.TxPath == 2) {
-		ByteValue |= 0x10;
-	}
-	RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R1, ByteValue);
-
-	RTMPSetPiggyBack(pAd, FALSE);
-	OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_PIGGYBACK_INUSED);
-
-	pAd->CommonCfg.BACapability.word = pAd->CommonCfg.REGBACapability.word;
-
-	/* Restore all settings in the following. */
-	AsicUpdateProtect(pAd, 0,
-			  (ALLN_SETPROTECT | CCKSETPROTECT | OFDMSETPROTECT),
-			  TRUE, FALSE);
-	AsicDisableRDG(pAd);
-	pAd->CommonCfg.IOTestParm.bCurrentAtheros = FALSE;
-	pAd->CommonCfg.IOTestParm.bNowAtherosBurstOn = FALSE;
-
-	RTMP_IO_WRITE32(pAd, MAX_LEN_CFG, 0x1fff);
-	RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS);
-
-/* Allow go to sleep after linkdown steps. */
-	RTMP_SET_PSFLAG(pAd, fRTMP_PS_CAN_GO_SLEEP);
-
-	RtmpOSWrielessEventSend(pAd, SIOCGIWAP, -1, NULL, NULL, 0);
-
-#ifdef RT30xx
-	if ((IS_RT30xx(pAd) || IS_RT3090(pAd) || IS_RT3390(pAd))
-	    && (pAd->Antenna.field.RxPath > 1 || pAd->Antenna.field.TxPath > 1)) {
-		RTMP_ASIC_MMPS_DISABLE(pAd);
-	}
-#endif /* RT30xx // */
-}
-
-/*
-	==========================================================================
-	Description:
-
-	IRQL = DISPATCH_LEVEL
-
-	==========================================================================
-*/
-void IterateOnBssTab(struct rt_rtmp_adapter *pAd)
-{
-	struct rt_mlme_start_req StartReq;
-	struct rt_mlme_join_req JoinReq;
-	unsigned long BssIdx;
-
-	/* Change the wepstatus to original wepstatus */
-	pAd->StaCfg.WepStatus = pAd->StaCfg.OrigWepStatus;
-	pAd->StaCfg.PairCipher = pAd->StaCfg.OrigWepStatus;
-	pAd->StaCfg.GroupCipher = pAd->StaCfg.OrigWepStatus;
-
-	BssIdx = pAd->MlmeAux.BssIdx;
-	if (BssIdx < pAd->MlmeAux.SsidBssTab.BssNr) {
-		/* Check cipher suite, AP must have more secured cipher than station setting */
-		/* Set the Pairwise and Group cipher to match the intended AP setting */
-		/* We can only connect to AP with less secured cipher setting */
-		if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA)
-		    || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK)) {
-			pAd->StaCfg.GroupCipher =
-			    pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA.
-			    GroupCipher;
-
-			if (pAd->StaCfg.WepStatus ==
-			    pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA.
-			    PairCipher)
-				pAd->StaCfg.PairCipher =
-				    pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].
-				    WPA.PairCipher;
-			else if (pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA.
-				 PairCipherAux != Ndis802_11WEPDisabled)
-				pAd->StaCfg.PairCipher =
-				    pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].
-				    WPA.PairCipherAux;
-			else	/* There is no PairCipher Aux, downgrade our capability to TKIP */
-				pAd->StaCfg.PairCipher =
-				    Ndis802_11Encryption2Enabled;
-		} else if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2)
-			   || (pAd->StaCfg.AuthMode ==
-			       Ndis802_11AuthModeWPA2PSK)) {
-			pAd->StaCfg.GroupCipher =
-			    pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA2.
-			    GroupCipher;
-
-			if (pAd->StaCfg.WepStatus ==
-			    pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA2.
-			    PairCipher)
-				pAd->StaCfg.PairCipher =
-				    pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].
-				    WPA2.PairCipher;
-			else if (pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA2.
-				 PairCipherAux != Ndis802_11WEPDisabled)
-				pAd->StaCfg.PairCipher =
-				    pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].
-				    WPA2.PairCipherAux;
-			else	/* There is no PairCipher Aux, downgrade our capability to TKIP */
-				pAd->StaCfg.PairCipher =
-				    Ndis802_11Encryption2Enabled;
-
-			/* RSN capability */
-			pAd->StaCfg.RsnCapability =
-			    pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA2.
-			    RsnCapability;
-		}
-		/* Set Mix cipher flag */
-		pAd->StaCfg.bMixCipher =
-		    (pAd->StaCfg.PairCipher ==
-		     pAd->StaCfg.GroupCipher) ? FALSE : TRUE;
-		/*if (pAd->StaCfg.bMixCipher == TRUE)
-		   {
-		   // If mix cipher, re-build RSNIE
-		   RTMPMakeRSNIE(pAd, pAd->StaCfg.AuthMode, pAd->StaCfg.WepStatus, 0);
-		   } */
-
-		DBGPRINT(RT_DEBUG_TRACE,
-			 ("CNTL - iterate BSS %ld of %d\n", BssIdx,
-			  pAd->MlmeAux.SsidBssTab.BssNr));
-		JoinParmFill(pAd, &JoinReq, BssIdx);
-		MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_JOIN_REQ,
-			    sizeof(struct rt_mlme_join_req), &JoinReq);
-		pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_JOIN;
-	} else if (pAd->StaCfg.BssType == BSS_ADHOC) {
-		DBGPRINT(RT_DEBUG_TRACE,
-			 ("CNTL - All BSS fail; start a new ADHOC (Ssid=%s)...\n",
-			  pAd->MlmeAux.Ssid));
-		StartParmFill(pAd, &StartReq, (char *)pAd->MlmeAux.Ssid,
-			      pAd->MlmeAux.SsidLen);
-		MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_START_REQ,
-			    sizeof(struct rt_mlme_start_req), &StartReq);
-		pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_START;
-	} else			/* no more BSS */
-	{
-
-		{
-			AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
-			AsicLockChannel(pAd, pAd->CommonCfg.Channel);
-			DBGPRINT(RT_DEBUG_TRACE,
-				 ("CNTL - All roaming failed, restore to channel %d, Total BSS[%02d]\n",
-				  pAd->CommonCfg.Channel, pAd->ScanTab.BssNr));
-		}
-
-		pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
-	}
-}
-
-/* for re-association only */
-/* IRQL = DISPATCH_LEVEL */
-void IterateOnBssTab2(struct rt_rtmp_adapter *pAd)
-{
-	struct rt_mlme_assoc_req ReassocReq;
-	unsigned long BssIdx;
-	struct rt_bss_entry *pBss;
-
-	BssIdx = pAd->MlmeAux.RoamIdx;
-	pBss = &pAd->MlmeAux.RoamTab.BssEntry[BssIdx];
-
-	if (BssIdx < pAd->MlmeAux.RoamTab.BssNr) {
-		DBGPRINT(RT_DEBUG_TRACE,
-			 ("CNTL - iterate BSS %ld of %d\n", BssIdx,
-			  pAd->MlmeAux.RoamTab.BssNr));
-
-		AsicSwitchChannel(pAd, pBss->Channel, FALSE);
-		AsicLockChannel(pAd, pBss->Channel);
-
-		/* reassociate message has the same structure as associate message */
-		AssocParmFill(pAd, &ReassocReq, pBss->Bssid,
-			      pBss->CapabilityInfo, ASSOC_TIMEOUT,
-			      pAd->StaCfg.DefaultListenCount);
-		MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_REASSOC_REQ,
-			    sizeof(struct rt_mlme_assoc_req), &ReassocReq);
-
-		pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_REASSOC;
-	} else			/* no more BSS */
-	{
-
-		{
-			AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
-			AsicLockChannel(pAd, pAd->CommonCfg.Channel);
-			DBGPRINT(RT_DEBUG_TRACE,
-				 ("CNTL - All roaming failed, restore to channel %d, Total BSS[%02d]\n",
-				  pAd->CommonCfg.Channel, pAd->ScanTab.BssNr));
-		}
-
-		pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
-	}
-}
-
-/*
-	==========================================================================
-	Description:
-
-	IRQL = DISPATCH_LEVEL
-
-	==========================================================================
-*/
-void JoinParmFill(struct rt_rtmp_adapter *pAd,
-		  struct rt_mlme_join_req *JoinReq, unsigned long BssIdx)
-{
-	JoinReq->BssIdx = BssIdx;
-}
-
-/*
-	==========================================================================
-	Description:
-
-	IRQL = DISPATCH_LEVEL
-
-	==========================================================================
-*/
-void ScanParmFill(struct rt_rtmp_adapter *pAd,
-		  struct rt_mlme_scan_req *ScanReq,
-		  char Ssid[],
-		  u8 SsidLen, u8 BssType, u8 ScanType)
-{
-	NdisZeroMemory(ScanReq->Ssid, MAX_LEN_OF_SSID);
-	ScanReq->SsidLen = SsidLen;
-	NdisMoveMemory(ScanReq->Ssid, Ssid, SsidLen);
-	ScanReq->BssType = BssType;
-	ScanReq->ScanType = ScanType;
-}
-
-/*
-	==========================================================================
-	Description:
-
-	IRQL = DISPATCH_LEVEL
-
-	==========================================================================
-*/
-void StartParmFill(struct rt_rtmp_adapter *pAd,
-		   struct rt_mlme_start_req *StartReq,
-		   char Ssid[], u8 SsidLen)
-{
-	ASSERT(SsidLen <= MAX_LEN_OF_SSID);
-	NdisMoveMemory(StartReq->Ssid, Ssid, SsidLen);
-	StartReq->SsidLen = SsidLen;
-}
-
-/*
-	==========================================================================
-	Description:
-
-	IRQL = DISPATCH_LEVEL
-
-	==========================================================================
-*/
-void AuthParmFill(struct rt_rtmp_adapter *pAd,
-		  struct rt_mlme_auth_req *AuthReq,
-		  u8 *pAddr, u16 Alg)
-{
-	COPY_MAC_ADDR(AuthReq->Addr, pAddr);
-	AuthReq->Alg = Alg;
-	AuthReq->Timeout = AUTH_TIMEOUT;
-}
-
-/*
-	==========================================================================
-	Description:
-
-	IRQL = DISPATCH_LEVEL
-
-	==========================================================================
- */
-#ifdef RTMP_MAC_PCI
-void ComposePsPoll(struct rt_rtmp_adapter *pAd)
-{
-	NdisZeroMemory(&pAd->PsPollFrame, sizeof(struct rt_pspoll_frame));
-	pAd->PsPollFrame.FC.Type = BTYPE_CNTL;
-	pAd->PsPollFrame.FC.SubType = SUBTYPE_PS_POLL;
-	pAd->PsPollFrame.Aid = pAd->StaActive.Aid | 0xC000;
-	COPY_MAC_ADDR(pAd->PsPollFrame.Bssid, pAd->CommonCfg.Bssid);
-	COPY_MAC_ADDR(pAd->PsPollFrame.Ta, pAd->CurrentAddress);
-}
-
-/* IRQL = DISPATCH_LEVEL */
-void ComposeNullFrame(struct rt_rtmp_adapter *pAd)
-{
-	NdisZeroMemory(&pAd->NullFrame, sizeof(struct rt_header_802_11));
-	pAd->NullFrame.FC.Type = BTYPE_DATA;
-	pAd->NullFrame.FC.SubType = SUBTYPE_NULL_FUNC;
-	pAd->NullFrame.FC.ToDs = 1;
-	COPY_MAC_ADDR(pAd->NullFrame.Addr1, pAd->CommonCfg.Bssid);
-	COPY_MAC_ADDR(pAd->NullFrame.Addr2, pAd->CurrentAddress);
-	COPY_MAC_ADDR(pAd->NullFrame.Addr3, pAd->CommonCfg.Bssid);
-}
-#endif /* RTMP_MAC_PCI // */
-#ifdef RTMP_MAC_USB
-void MlmeCntlConfirm(struct rt_rtmp_adapter *pAd, unsigned long MsgType, u16 Msg)
-{
-	MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MsgType, sizeof(u16),
-		    &Msg);
-}
-
-void ComposePsPoll(struct rt_rtmp_adapter *pAd)
-{
-	struct rt_txinfo *pTxInfo;
-	struct rt_txwi * pTxWI;
-
-	DBGPRINT(RT_DEBUG_TRACE, ("ComposePsPoll\n"));
-	NdisZeroMemory(&pAd->PsPollFrame, sizeof(struct rt_pspoll_frame));
-
-	pAd->PsPollFrame.FC.PwrMgmt = 0;
-	pAd->PsPollFrame.FC.Type = BTYPE_CNTL;
-	pAd->PsPollFrame.FC.SubType = SUBTYPE_PS_POLL;
-	pAd->PsPollFrame.Aid = pAd->StaActive.Aid | 0xC000;
-	COPY_MAC_ADDR(pAd->PsPollFrame.Bssid, pAd->CommonCfg.Bssid);
-	COPY_MAC_ADDR(pAd->PsPollFrame.Ta, pAd->CurrentAddress);
-
-	RTMPZeroMemory(&pAd->PsPollContext.TransferBuffer->field.
-		       WirelessPacket[0], 100);
-	pTxInfo =
-	    (struct rt_txinfo *)& pAd->PsPollContext.TransferBuffer->field.
-	    WirelessPacket[0];
-	RTMPWriteTxInfo(pAd, pTxInfo,
-			(u16)(sizeof(struct rt_pspoll_frame) + TXWI_SIZE), TRUE,
-			EpToQueue[MGMTPIPEIDX], FALSE, FALSE);
-	pTxWI =
-	    (struct rt_txwi *) & pAd->PsPollContext.TransferBuffer->field.
-	    WirelessPacket[TXINFO_SIZE];
-	RTMPWriteTxWI(pAd, pTxWI, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, 0,
-		      BSSID_WCID, (sizeof(struct rt_pspoll_frame)), 0, 0,
-		      (u8)pAd->CommonCfg.MlmeTransmit.field.MCS,
-		      IFS_BACKOFF, FALSE, &pAd->CommonCfg.MlmeTransmit);
-	RTMPMoveMemory(&pAd->PsPollContext.TransferBuffer->field.
-		       WirelessPacket[TXWI_SIZE + TXINFO_SIZE],
-		       &pAd->PsPollFrame, sizeof(struct rt_pspoll_frame));
-	/* Append 4 extra zero bytes. */
-	pAd->PsPollContext.BulkOutSize =
-	    TXINFO_SIZE + TXWI_SIZE + sizeof(struct rt_pspoll_frame) + 4;
-}
-
-/* IRQL = DISPATCH_LEVEL */
-void ComposeNullFrame(struct rt_rtmp_adapter *pAd)
-{
-	struct rt_txinfo *pTxInfo;
-	struct rt_txwi * pTxWI;
-
-	NdisZeroMemory(&pAd->NullFrame, sizeof(struct rt_header_802_11));
-	pAd->NullFrame.FC.Type = BTYPE_DATA;
-	pAd->NullFrame.FC.SubType = SUBTYPE_NULL_FUNC;
-	pAd->NullFrame.FC.ToDs = 1;
-	COPY_MAC_ADDR(pAd->NullFrame.Addr1, pAd->CommonCfg.Bssid);
-	COPY_MAC_ADDR(pAd->NullFrame.Addr2, pAd->CurrentAddress);
-	COPY_MAC_ADDR(pAd->NullFrame.Addr3, pAd->CommonCfg.Bssid);
-	RTMPZeroMemory(&pAd->NullContext.TransferBuffer->field.
-		       WirelessPacket[0], 100);
-	pTxInfo =
-	    (struct rt_txinfo *)& pAd->NullContext.TransferBuffer->field.
-	    WirelessPacket[0];
-	RTMPWriteTxInfo(pAd, pTxInfo,
-			(u16)(sizeof(struct rt_header_802_11) + TXWI_SIZE), TRUE,
-			EpToQueue[MGMTPIPEIDX], FALSE, FALSE);
-	pTxWI =
-	    (struct rt_txwi *) & pAd->NullContext.TransferBuffer->field.
-	    WirelessPacket[TXINFO_SIZE];
-	RTMPWriteTxWI(pAd, pTxWI, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, 0,
-		      BSSID_WCID, (sizeof(struct rt_header_802_11)), 0, 0,
-		      (u8)pAd->CommonCfg.MlmeTransmit.field.MCS,
-		      IFS_BACKOFF, FALSE, &pAd->CommonCfg.MlmeTransmit);
-	RTMPMoveMemory(&pAd->NullContext.TransferBuffer->field.
-		       WirelessPacket[TXWI_SIZE + TXINFO_SIZE], &pAd->NullFrame,
-		       sizeof(struct rt_header_802_11));
-	pAd->NullContext.BulkOutSize =
-	    TXINFO_SIZE + TXWI_SIZE + sizeof(pAd->NullFrame) + 4;
-}
-#endif /* RTMP_MAC_USB // */
-
-/*
-	==========================================================================
-	Description:
-		Pre-build a BEACON frame in the shared memory
-
-	IRQL = PASSIVE_LEVEL
-	IRQL = DISPATCH_LEVEL
-
-	==========================================================================
-*/
-unsigned long MakeIbssBeacon(struct rt_rtmp_adapter *pAd)
-{
-	u8 DsLen = 1, IbssLen = 2;
-	u8 LocalErpIe[3] = { IE_ERP, 1, 0x04 };
-	struct rt_header_802_11 BcnHdr;
-	u16 CapabilityInfo;
-	LARGE_INTEGER FakeTimestamp;
-	unsigned long FrameLen = 0;
-	struct rt_txwi * pTxWI = &pAd->BeaconTxWI;
-	u8 *pBeaconFrame = pAd->BeaconBuf;
-	BOOLEAN Privacy;
-	u8 SupRate[MAX_LEN_OF_SUPPORTED_RATES];
-	u8 SupRateLen = 0;
-	u8 ExtRate[MAX_LEN_OF_SUPPORTED_RATES];
-	u8 ExtRateLen = 0;
-	u8 RSNIe = IE_WPA;
-
-	if ((pAd->CommonCfg.PhyMode == PHY_11B)
-	    && (pAd->CommonCfg.Channel <= 14)) {
-		SupRate[0] = 0x82;	/* 1 mbps */
-		SupRate[1] = 0x84;	/* 2 mbps */
-		SupRate[2] = 0x8b;	/* 5.5 mbps */
-		SupRate[3] = 0x96;	/* 11 mbps */
-		SupRateLen = 4;
-		ExtRateLen = 0;
-	} else if (pAd->CommonCfg.Channel > 14) {
-		SupRate[0] = 0x8C;	/* 6 mbps, in units of 0.5 Mbps, basic rate */
-		SupRate[1] = 0x12;	/* 9 mbps, in units of 0.5 Mbps */
-		SupRate[2] = 0x98;	/* 12 mbps, in units of 0.5 Mbps, basic rate */
-		SupRate[3] = 0x24;	/* 18 mbps, in units of 0.5 Mbps */
-		SupRate[4] = 0xb0;	/* 24 mbps, in units of 0.5 Mbps, basic rate */
-		SupRate[5] = 0x48;	/* 36 mbps, in units of 0.5 Mbps */
-		SupRate[6] = 0x60;	/* 48 mbps, in units of 0.5 Mbps */
-		SupRate[7] = 0x6c;	/* 54 mbps, in units of 0.5 Mbps */
-		SupRateLen = 8;
-		ExtRateLen = 0;
-
-		/* */
-		/* Also Update MlmeRate & RtsRate for G only & A only */
-		/* */
-		pAd->CommonCfg.MlmeRate = RATE_6;
-		pAd->CommonCfg.RtsRate = RATE_6;
-		pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_OFDM;
-		pAd->CommonCfg.MlmeTransmit.field.MCS =
-		    OfdmRateToRxwiMCS[pAd->CommonCfg.MlmeRate];
-		pAd->MacTab.Content[BSS0Mcast_WCID].HTPhyMode.field.MODE =
-		    MODE_OFDM;
-		pAd->MacTab.Content[BSS0Mcast_WCID].HTPhyMode.field.MCS =
-		    OfdmRateToRxwiMCS[pAd->CommonCfg.MlmeRate];
-	} else {
-		SupRate[0] = 0x82;	/* 1 mbps */
-		SupRate[1] = 0x84;	/* 2 mbps */
-		SupRate[2] = 0x8b;	/* 5.5 mbps */
-		SupRate[3] = 0x96;	/* 11 mbps */
-		SupRateLen = 4;
-
-		ExtRate[0] = 0x0C;	/* 6 mbps, in units of 0.5 Mbps, */
-		ExtRate[1] = 0x12;	/* 9 mbps, in units of 0.5 Mbps */
-		ExtRate[2] = 0x18;	/* 12 mbps, in units of 0.5 Mbps, */
-		ExtRate[3] = 0x24;	/* 18 mbps, in units of 0.5 Mbps */
-		ExtRate[4] = 0x30;	/* 24 mbps, in units of 0.5 Mbps, */
-		ExtRate[5] = 0x48;	/* 36 mbps, in units of 0.5 Mbps */
-		ExtRate[6] = 0x60;	/* 48 mbps, in units of 0.5 Mbps */
-		ExtRate[7] = 0x6c;	/* 54 mbps, in units of 0.5 Mbps */
-		ExtRateLen = 8;
-	}
-
-	pAd->StaActive.SupRateLen = SupRateLen;
-	NdisMoveMemory(pAd->StaActive.SupRate, SupRate, SupRateLen);
-	pAd->StaActive.ExtRateLen = ExtRateLen;
-	NdisMoveMemory(pAd->StaActive.ExtRate, ExtRate, ExtRateLen);
-
-	/* compose IBSS beacon frame */
-	MgtMacHeaderInit(pAd, &BcnHdr, SUBTYPE_BEACON, 0, BROADCAST_ADDR,
-			 pAd->CommonCfg.Bssid);
-	Privacy = (pAd->StaCfg.WepStatus == Ndis802_11Encryption1Enabled)
-	    || (pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled)
-	    || (pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled);
-	CapabilityInfo =
-	    CAP_GENERATE(0, 1, Privacy,
-			 (pAd->CommonCfg.TxPreamble == Rt802_11PreambleShort),
-			 0, 0);
-
-	MakeOutgoingFrame(pBeaconFrame, &FrameLen,
-			  sizeof(struct rt_header_802_11), &BcnHdr,
-			  TIMESTAMP_LEN, &FakeTimestamp,
-			  2, &pAd->CommonCfg.BeaconPeriod,
-			  2, &CapabilityInfo,
-			  1, &SsidIe,
-			  1, &pAd->CommonCfg.SsidLen,
-			  pAd->CommonCfg.SsidLen, pAd->CommonCfg.Ssid,
-			  1, &SupRateIe,
-			  1, &SupRateLen,
-			  SupRateLen, SupRate,
-			  1, &DsIe,
-			  1, &DsLen,
-			  1, &pAd->CommonCfg.Channel,
-			  1, &IbssIe,
-			  1, &IbssLen, 2, &pAd->StaActive.AtimWin, END_OF_ARGS);
-
-	/* add ERP_IE and EXT_RAE IE of in 802.11g */
-	if (ExtRateLen) {
-		unsigned long tmp;
-
-		MakeOutgoingFrame(pBeaconFrame + FrameLen, &tmp,
-				  3, LocalErpIe,
-				  1, &ExtRateIe,
-				  1, &ExtRateLen,
-				  ExtRateLen, ExtRate, END_OF_ARGS);
-		FrameLen += tmp;
-	}
-	/* If adhoc secruity is set for WPA-None, append the cipher suite IE */
-	if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPANone) {
-		unsigned long tmp;
-		RTMPMakeRSNIE(pAd, pAd->StaCfg.AuthMode, pAd->StaCfg.WepStatus,
-			      BSS0);
-
-		MakeOutgoingFrame(pBeaconFrame + FrameLen, &tmp,
-				  1, &RSNIe,
-				  1, &pAd->StaCfg.RSNIE_Len,
-				  pAd->StaCfg.RSNIE_Len, pAd->StaCfg.RSN_IE,
-				  END_OF_ARGS);
-		FrameLen += tmp;
-	}
-
-	if ((pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED)) {
-		unsigned long TmpLen;
-		u8 HtLen, HtLen1;
-
-		/* add HT Capability IE */
-		HtLen = sizeof(pAd->CommonCfg.HtCapability);
-		HtLen1 = sizeof(pAd->CommonCfg.AddHTInfo);
-
-		MakeOutgoingFrame(pBeaconFrame + FrameLen, &TmpLen,
-				  1, &HtCapIe,
-				  1, &HtLen,
-				  HtLen, &pAd->CommonCfg.HtCapability,
-				  1, &AddHtInfoIe,
-				  1, &HtLen1,
-				  HtLen1, &pAd->CommonCfg.AddHTInfo,
-				  END_OF_ARGS);
-
-		FrameLen += TmpLen;
-	}
-	/*beacon use reserved WCID 0xff */
-	if (pAd->CommonCfg.Channel > 14) {
-		RTMPWriteTxWI(pAd, pTxWI, FALSE, FALSE, TRUE, FALSE, FALSE,
-			      TRUE, 0, 0xff, FrameLen, PID_MGMT, PID_BEACON,
-			      RATE_1, IFS_HTTXOP, FALSE,
-			      &pAd->CommonCfg.MlmeTransmit);
-	} else {
-		/* Set to use 1Mbps for Adhoc beacon. */
-		HTTRANSMIT_SETTING Transmit;
-		Transmit.word = 0;
-		RTMPWriteTxWI(pAd, pTxWI, FALSE, FALSE, TRUE, FALSE, FALSE,
-			      TRUE, 0, 0xff, FrameLen, PID_MGMT, PID_BEACON,
-			      RATE_1, IFS_HTTXOP, FALSE, &Transmit);
-	}
-
-	DBGPRINT(RT_DEBUG_TRACE,
-		 ("MakeIbssBeacon (len=%ld), SupRateLen=%d, ExtRateLen=%d, Channel=%d, PhyMode=%d\n",
-		  FrameLen, SupRateLen, ExtRateLen, pAd->CommonCfg.Channel,
-		  pAd->CommonCfg.PhyMode));
-	return FrameLen;
-}
diff -druN linux-2.6.39-libre/drivers/staging/rt2860/sta/rtmp_data.c linux-3.0-rc7-libre/drivers/staging/rt2860/sta/rtmp_data.c
--- linux-2.6.39-libre/drivers/staging/rt2860/sta/rtmp_data.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rt2860/sta/rtmp_data.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,2552 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, 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.             *
- *                                                                       *
- *************************************************************************
-
-	Module Name:
-	rtmp_data.c
-
-	Abstract:
-	Data path subroutines
-
-	Revision History:
-	Who 	  		When		What
-	Justin P. Mattock	11/07/2010	Fix typos
-	--------	----------		----------------------------------------------
-*/
-#include "../rt_config.h"
-#include <linux/kernel.h>
-
-void STARxEAPOLFrameIndicate(struct rt_rtmp_adapter *pAd,
-			     struct rt_mac_table_entry *pEntry,
-			     struct rt_rx_blk *pRxBlk, u8 FromWhichBSSID)
-{
-	PRT28XX_RXD_STRUC pRxD = &(pRxBlk->RxD);
-	struct rt_rxwi * pRxWI = pRxBlk->pRxWI;
-	u8 *pTmpBuf;
-
-	if (pAd->StaCfg.WpaSupplicantUP) {
-		/* All EAPoL frames have to pass to upper layer (ex. WPA_SUPPLICANT daemon) */
-		/* TBD : process fragmented EAPol frames */
-		{
-			/* In 802.1x mode, if the received frame is EAP-SUCCESS packet, turn on the PortSecured variable */
-			if (pAd->StaCfg.IEEE8021X == TRUE &&
-			    (EAP_CODE_SUCCESS ==
-			     WpaCheckEapCode(pAd, pRxBlk->pData,
-					     pRxBlk->DataSize,
-					     LENGTH_802_1_H))) {
-				u8 *Key;
-				u8 CipherAlg;
-				int idx = 0;
-
-				DBGPRINT_RAW(RT_DEBUG_TRACE,
-					     ("Receive EAP-SUCCESS Packet\n"));
-				/*pAd->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED; */
-				STA_PORT_SECURED(pAd);
-
-				if (pAd->StaCfg.IEEE8021x_required_keys ==
-				    FALSE) {
-					idx = pAd->StaCfg.DesireSharedKeyId;
-					CipherAlg =
-					    pAd->StaCfg.DesireSharedKey[idx].
-					    CipherAlg;
-					Key =
-					    pAd->StaCfg.DesireSharedKey[idx].
-					    Key;
-
-					if (pAd->StaCfg.DesireSharedKey[idx].
-					    KeyLen > 0) {
-#ifdef RTMP_MAC_PCI
-						struct rt_mac_table_entry *pEntry =
-						    &pAd->MacTab.
-						    Content[BSSID_WCID];
-
-						/* Set key material and cipherAlg to Asic */
-						AsicAddSharedKeyEntry(pAd, BSS0,
-								      idx,
-								      CipherAlg,
-								      Key, NULL,
-								      NULL);
-
-						/* Assign group key info */
-						RTMPAddWcidAttributeEntry(pAd,
-									  BSS0,
-									  idx,
-									  CipherAlg,
-									  NULL);
-
-						/* Assign pairwise key info */
-						RTMPAddWcidAttributeEntry(pAd,
-									  BSS0,
-									  idx,
-									  CipherAlg,
-									  pEntry);
-
-						pAd->IndicateMediaState =
-						    NdisMediaStateConnected;
-						pAd->ExtraInfo =
-						    GENERAL_LINK_UP;
-#endif /* RTMP_MAC_PCI // */
-#ifdef RTMP_MAC_USB
-						union {
-							char buf[sizeof
-								 (struct rt_ndis_802_11_wep)
-								 +
-								 MAX_LEN_OF_KEY
-								 - 1];
-							struct rt_ndis_802_11_wep keyinfo;
-						}
-						WepKey;
-						int len;
-
-						NdisZeroMemory(&WepKey,
-							       sizeof(WepKey));
-						len =
-						    pAd->StaCfg.
-						    DesireSharedKey[idx].KeyLen;
-
-						NdisMoveMemory(WepKey.keyinfo.
-							       KeyMaterial,
-							       pAd->StaCfg.
-							       DesireSharedKey
-							       [idx].Key,
-							       pAd->StaCfg.
-							       DesireSharedKey
-							       [idx].KeyLen);
-
-						WepKey.keyinfo.KeyIndex =
-						    0x80000000 + idx;
-						WepKey.keyinfo.KeyLength = len;
-						pAd->SharedKey[BSS0][idx].
-						    KeyLen =
-						    (u8)(len <= 5 ? 5 : 13);
-
-						pAd->IndicateMediaState =
-						    NdisMediaStateConnected;
-						pAd->ExtraInfo =
-						    GENERAL_LINK_UP;
-						/* need to enqueue cmd to thread */
-						RTUSBEnqueueCmdFromNdis(pAd,
-									OID_802_11_ADD_WEP,
-									TRUE,
-									&WepKey,
-									sizeof
-									(WepKey.
-									 keyinfo)
-									+ len -
-									1);
-#endif /* RTMP_MAC_USB // */
-						/* For Preventing ShardKey Table is cleared by remove key procedure. */
-						pAd->SharedKey[BSS0][idx].
-						    CipherAlg = CipherAlg;
-						pAd->SharedKey[BSS0][idx].
-						    KeyLen =
-						    pAd->StaCfg.
-						    DesireSharedKey[idx].KeyLen;
-						NdisMoveMemory(pAd->
-							       SharedKey[BSS0]
-							       [idx].Key,
-							       pAd->StaCfg.
-							       DesireSharedKey
-							       [idx].Key,
-							       pAd->StaCfg.
-							       DesireSharedKey
-							       [idx].KeyLen);
-					}
-				}
-			}
-
-			Indicate_Legacy_Packet(pAd, pRxBlk, FromWhichBSSID);
-			return;
-		}
-	} else {
-		/* Special DATA frame that has to pass to MLME */
-		/*       1. Cisco Aironet frames for CCX2. We need pass it to MLME for special process */
-		/*       2. EAPOL handshaking frames when driver supplicant enabled, pass to MLME for special process */
-		{
-			pTmpBuf = pRxBlk->pData - LENGTH_802_11;
-			NdisMoveMemory(pTmpBuf, pRxBlk->pHeader, LENGTH_802_11);
-			REPORT_MGMT_FRAME_TO_MLME(pAd, pRxWI->WirelessCliID,
-						  pTmpBuf,
-						  pRxBlk->DataSize +
-						  LENGTH_802_11, pRxWI->RSSI0,
-						  pRxWI->RSSI1, pRxWI->RSSI2,
-						  pRxD->PlcpSignal);
-			DBGPRINT_RAW(RT_DEBUG_TRACE,
-				     ("report EAPOL/AIRONET DATA to MLME (len=%d) !\n",
-				      pRxBlk->DataSize));
-		}
-	}
-
-	RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE);
-	return;
-
-}
-
-void STARxDataFrameAnnounce(struct rt_rtmp_adapter *pAd,
-			    struct rt_mac_table_entry *pEntry,
-			    struct rt_rx_blk *pRxBlk, u8 FromWhichBSSID)
-{
-
-	/* non-EAP frame */
-	if (!RTMPCheckWPAframe
-	    (pAd, pEntry, pRxBlk->pData, pRxBlk->DataSize, FromWhichBSSID)) {
-
-		{
-			/* drop all non-EAP DATA frame before */
-			/* this client's Port-Access-Control is secured */
-			if (pRxBlk->pHeader->FC.Wep) {
-				/* unsupported cipher suite */
-				if (pAd->StaCfg.WepStatus ==
-				    Ndis802_11EncryptionDisabled) {
-					/* release packet */
-					RELEASE_NDIS_PACKET(pAd,
-							    pRxBlk->pRxPacket,
-							    NDIS_STATUS_FAILURE);
-					return;
-				}
-			} else {
-				/* encryption in-use but receive a non-EAPOL clear text frame, drop it */
-				if ((pAd->StaCfg.WepStatus !=
-				     Ndis802_11EncryptionDisabled)
-				    && (pAd->StaCfg.PortSecured ==
-					WPA_802_1X_PORT_NOT_SECURED)) {
-					/* release packet */
-					RELEASE_NDIS_PACKET(pAd,
-							    pRxBlk->pRxPacket,
-							    NDIS_STATUS_FAILURE);
-					return;
-				}
-			}
-		}
-		RX_BLK_CLEAR_FLAG(pRxBlk, fRX_EAP);
-		if (!RX_BLK_TEST_FLAG(pRxBlk, fRX_ARALINK)) {
-			/* Normal legacy, AMPDU or AMSDU */
-			CmmRxnonRalinkFrameIndicate(pAd, pRxBlk,
-						    FromWhichBSSID);
-
-		} else {
-			/* ARALINK */
-			CmmRxRalinkFrameIndicate(pAd, pEntry, pRxBlk,
-						 FromWhichBSSID);
-		}
-	} else {
-		RX_BLK_SET_FLAG(pRxBlk, fRX_EAP);
-
-		if (RX_BLK_TEST_FLAG(pRxBlk, fRX_AMPDU)
-		    && (pAd->CommonCfg.bDisableReordering == 0)) {
-			Indicate_AMPDU_Packet(pAd, pRxBlk, FromWhichBSSID);
-		} else {
-			/* Determine the destination of the EAP frame */
-			/* to WPA state machine or upper layer */
-			STARxEAPOLFrameIndicate(pAd, pEntry, pRxBlk,
-						FromWhichBSSID);
-		}
-	}
-}
-
-/* For TKIP frame, calculate the MIC value */
-BOOLEAN STACheckTkipMICValue(struct rt_rtmp_adapter *pAd,
-			     struct rt_mac_table_entry *pEntry, struct rt_rx_blk *pRxBlk)
-{
-	struct rt_header_802_11 * pHeader = pRxBlk->pHeader;
-	u8 *pData = pRxBlk->pData;
-	u16 DataSize = pRxBlk->DataSize;
-	u8 UserPriority = pRxBlk->UserPriority;
-	struct rt_cipher_key *pWpaKey;
-	u8 *pDA, *pSA;
-
-	pWpaKey = &pAd->SharedKey[BSS0][pRxBlk->pRxWI->KeyIndex];
-
-	pDA = pHeader->Addr1;
-	if (RX_BLK_TEST_FLAG(pRxBlk, fRX_INFRA)) {
-		pSA = pHeader->Addr3;
-	} else {
-		pSA = pHeader->Addr2;
-	}
-
-	if (RTMPTkipCompareMICValue(pAd,
-				    pData,
-				    pDA,
-				    pSA,
-				    pWpaKey->RxMic,
-				    UserPriority, DataSize) == FALSE) {
-		DBGPRINT_RAW(RT_DEBUG_ERROR, ("Rx MIC Value error 2\n"));
-
-		if (pAd->StaCfg.WpaSupplicantUP) {
-			WpaSendMicFailureToWpaSupplicant(pAd,
-							 (pWpaKey->Type ==
-							  PAIRWISEKEY) ? TRUE :
-							 FALSE);
-		} else {
-			RTMPReportMicError(pAd, pWpaKey);
-		}
-
-		/* release packet */
-		RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket,
-				    NDIS_STATUS_FAILURE);
-		return FALSE;
-	}
-
-	return TRUE;
-}
-
-/* */
-/* All Rx routines use struct rt_rx_blk structure to hande rx events */
-/* It is very important to build pRxBlk attributes */
-/*  1. pHeader pointer to 802.11 Header */
-/*  2. pData pointer to payload including LLC (just skip Header) */
-/*  3. set payload size including LLC to DataSize */
-/*  4. set some flags with RX_BLK_SET_FLAG() */
-/* */
-void STAHandleRxDataFrame(struct rt_rtmp_adapter *pAd, struct rt_rx_blk *pRxBlk)
-{
-	PRT28XX_RXD_STRUC pRxD = &(pRxBlk->RxD);
-	struct rt_rxwi * pRxWI = pRxBlk->pRxWI;
-	struct rt_header_802_11 * pHeader = pRxBlk->pHeader;
-	void *pRxPacket = pRxBlk->pRxPacket;
-	BOOLEAN bFragment = FALSE;
-	struct rt_mac_table_entry *pEntry = NULL;
-	u8 FromWhichBSSID = BSS0;
-	u8 UserPriority = 0;
-
-	{
-		/* before LINK UP, all DATA frames are rejected */
-		if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED)) {
-			/* release packet */
-			RELEASE_NDIS_PACKET(pAd, pRxPacket,
-					    NDIS_STATUS_FAILURE);
-			return;
-		}
-		/* Drop not my BSS frames */
-		if (pRxD->MyBss == 0) {
-			{
-				/* release packet */
-				RELEASE_NDIS_PACKET(pAd, pRxPacket,
-						    NDIS_STATUS_FAILURE);
-				return;
-			}
-		}
-
-		pAd->RalinkCounters.RxCountSinceLastNULL++;
-		if (pAd->CommonCfg.bAPSDCapable
-		    && pAd->CommonCfg.APEdcaParm.bAPSDCapable
-		    && (pHeader->FC.SubType & 0x08)) {
-			u8 *pData;
-			DBGPRINT(RT_DEBUG_INFO, ("bAPSDCapable\n"));
-
-			/* Qos bit 4 */
-			pData = (u8 *)pHeader + LENGTH_802_11;
-			if ((*pData >> 4) & 0x01) {
-				DBGPRINT(RT_DEBUG_INFO,
-					 ("RxDone- Rcv EOSP frame, driver may fall into sleep\n"));
-				pAd->CommonCfg.bInServicePeriod = FALSE;
-
-				/* Force driver to fall into sleep mode when rcv EOSP frame */
-				if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE)) {
-					u16 TbttNumToNextWakeUp;
-					u16 NextDtim =
-					    pAd->StaCfg.DtimPeriod;
-					unsigned long Now;
-
-					NdisGetSystemUpTime(&Now);
-					NextDtim -=
-					    (u16)(Now -
-						      pAd->StaCfg.
-						      LastBeaconRxTime) /
-					    pAd->CommonCfg.BeaconPeriod;
-
-					TbttNumToNextWakeUp =
-					    pAd->StaCfg.DefaultListenCount;
-					if (OPSTATUS_TEST_FLAG
-					    (pAd, fOP_STATUS_RECEIVE_DTIM)
-					    && (TbttNumToNextWakeUp > NextDtim))
-						TbttNumToNextWakeUp = NextDtim;
-
-					RTMP_SET_PSM_BIT(pAd, PWR_SAVE);
-					/* if WMM-APSD is failed, try to disable following line */
-					AsicSleepThenAutoWakeup(pAd,
-								TbttNumToNextWakeUp);
-				}
-			}
-
-			if ((pHeader->FC.MoreData)
-			    && (pAd->CommonCfg.bInServicePeriod)) {
-				DBGPRINT(RT_DEBUG_TRACE,
-					 ("Sending another trigger frame when More Data bit is set to 1\n"));
-			}
-		}
-		/* Drop NULL, CF-ACK(no data), CF-POLL(no data), and CF-ACK+CF-POLL(no data) data frame */
-		if ((pHeader->FC.SubType & 0x04))	/* bit 2 : no DATA */
-		{
-			/* release packet */
-			RELEASE_NDIS_PACKET(pAd, pRxPacket,
-					    NDIS_STATUS_FAILURE);
-			return;
-		}
-		/* Drop not my BSS frame (we can not only check the MyBss bit in RxD) */
-
-		if (INFRA_ON(pAd)) {
-			/* Infrastructure mode, check address 2 for BSSID */
-			if (!RTMPEqualMemory
-			    (&pHeader->Addr2, &pAd->CommonCfg.Bssid, 6)) {
-				/* Receive frame not my BSSID */
-				/* release packet */
-				RELEASE_NDIS_PACKET(pAd, pRxPacket,
-						    NDIS_STATUS_FAILURE);
-				return;
-			}
-		} else		/* Ad-Hoc mode or Not associated */
-		{
-			/* Ad-Hoc mode, check address 3 for BSSID */
-			if (!RTMPEqualMemory
-			    (&pHeader->Addr3, &pAd->CommonCfg.Bssid, 6)) {
-				/* Receive frame not my BSSID */
-				/* release packet */
-				RELEASE_NDIS_PACKET(pAd, pRxPacket,
-						    NDIS_STATUS_FAILURE);
-				return;
-			}
-		}
-
-		/* */
-		/* find pEntry */
-		/* */
-		if (pRxWI->WirelessCliID < MAX_LEN_OF_MAC_TABLE) {
-			pEntry = &pAd->MacTab.Content[pRxWI->WirelessCliID];
-		} else {
-			/* 1. release packet if infra mode */
-			/* 2. new a pEntry if ad-hoc mode */
-			RELEASE_NDIS_PACKET(pAd, pRxPacket,
-					    NDIS_STATUS_FAILURE);
-			return;
-		}
-
-		/* infra or ad-hoc */
-		if (INFRA_ON(pAd)) {
-			RX_BLK_SET_FLAG(pRxBlk, fRX_INFRA);
-			ASSERT(pRxWI->WirelessCliID == BSSID_WCID);
-		}
-		/* check Atheros Client */
-		if ((pEntry->bIAmBadAtheros == FALSE) && (pRxD->AMPDU == 1)
-		    && (pHeader->FC.Retry)) {
-			pEntry->bIAmBadAtheros = TRUE;
-			pAd->CommonCfg.IOTestParm.bCurrentAtheros = TRUE;
-			pAd->CommonCfg.IOTestParm.bLastAtheros = TRUE;
-			if (!STA_AES_ON(pAd)) {
-				AsicUpdateProtect(pAd, 8, ALLN_SETPROTECT, TRUE,
-						  FALSE);
-			}
-		}
-	}
-
-	pRxBlk->pData = (u8 *) pHeader;
-
-	/* */
-	/* update RxBlk->pData, DataSize */
-	/* 802.11 Header, QOS, HTC, Hw Padding */
-	/* */
-
-	/* 1. skip 802.11 HEADER */
-	{
-		pRxBlk->pData += LENGTH_802_11;
-		pRxBlk->DataSize -= LENGTH_802_11;
-	}
-
-	/* 2. QOS */
-	if (pHeader->FC.SubType & 0x08) {
-		RX_BLK_SET_FLAG(pRxBlk, fRX_QOS);
-		UserPriority = *(pRxBlk->pData) & 0x0f;
-		/* bit 7 in QoS Control field signals the HT A-MSDU format */
-		if ((*pRxBlk->pData) & 0x80) {
-			RX_BLK_SET_FLAG(pRxBlk, fRX_AMSDU);
-		}
-		/* skip QOS contorl field */
-		pRxBlk->pData += 2;
-		pRxBlk->DataSize -= 2;
-	}
-	pRxBlk->UserPriority = UserPriority;
-
-	/* check if need to resend PS Poll when received packet with MoreData = 1 */
-	if ((pAd->StaCfg.Psm == PWR_SAVE) && (pHeader->FC.MoreData == 1)) {
-		if ((((UserPriority == 0) || (UserPriority == 3)) &&
-		     pAd->CommonCfg.bAPSDAC_BE == 0) ||
-		    (((UserPriority == 1) || (UserPriority == 2)) &&
-		     pAd->CommonCfg.bAPSDAC_BK == 0) ||
-		    (((UserPriority == 4) || (UserPriority == 5)) &&
-		     pAd->CommonCfg.bAPSDAC_VI == 0) ||
-		    (((UserPriority == 6) || (UserPriority == 7)) &&
-		     pAd->CommonCfg.bAPSDAC_VO == 0)) {
-			/* non-UAPSD delivery-enabled AC */
-			RTMP_PS_POLL_ENQUEUE(pAd);
-		}
-	}
-	/* 3. Order bit: A-Ralink or HTC+ */
-	if (pHeader->FC.Order) {
-#ifdef AGGREGATION_SUPPORT
-		if ((pRxWI->PHYMODE <= MODE_OFDM)
-		    && (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED)))
-		{
-			RX_BLK_SET_FLAG(pRxBlk, fRX_ARALINK);
-		} else
-#endif /* AGGREGATION_SUPPORT // */
-		{
-			RX_BLK_SET_FLAG(pRxBlk, fRX_HTC);
-			/* skip HTC contorl field */
-			pRxBlk->pData += 4;
-			pRxBlk->DataSize -= 4;
-		}
-	}
-	/* 4. skip HW padding */
-	if (pRxD->L2PAD) {
-		/* just move pData pointer */
-		/* because DataSize excluding HW padding */
-		RX_BLK_SET_FLAG(pRxBlk, fRX_PAD);
-		pRxBlk->pData += 2;
-	}
-
-	if (pRxD->BA) {
-		RX_BLK_SET_FLAG(pRxBlk, fRX_AMPDU);
-	}
-	/* */
-	/* Case I  Process Broadcast & Multicast data frame */
-	/* */
-	if (pRxD->Bcast || pRxD->Mcast) {
-		INC_COUNTER64(pAd->WlanCounters.MulticastReceivedFrameCount);
-
-		/* Drop Mcast/Bcast frame with fragment bit on */
-		if (pHeader->FC.MoreFrag) {
-			/* release packet */
-			RELEASE_NDIS_PACKET(pAd, pRxPacket,
-					    NDIS_STATUS_FAILURE);
-			return;
-		}
-		/* Filter out Bcast frame which AP relayed for us */
-		if (pHeader->FC.FrDs
-		    && MAC_ADDR_EQUAL(pHeader->Addr3, pAd->CurrentAddress)) {
-			/* release packet */
-			RELEASE_NDIS_PACKET(pAd, pRxPacket,
-					    NDIS_STATUS_FAILURE);
-			return;
-		}
-
-		Indicate_Legacy_Packet(pAd, pRxBlk, FromWhichBSSID);
-		return;
-	} else if (pRxD->U2M) {
-		pAd->LastRxRate =
-		    (u16)((pRxWI->MCS) + (pRxWI->BW << 7) +
-			      (pRxWI->ShortGI << 8) + (pRxWI->PHYMODE << 14));
-
-		if (ADHOC_ON(pAd)) {
-			pEntry = MacTableLookup(pAd, pHeader->Addr2);
-			if (pEntry)
-				Update_Rssi_Sample(pAd, &pEntry->RssiSample,
-						   pRxWI);
-		}
-
-		Update_Rssi_Sample(pAd, &pAd->StaCfg.RssiSample, pRxWI);
-
-		pAd->StaCfg.LastSNR0 = (u8)(pRxWI->SNR0);
-		pAd->StaCfg.LastSNR1 = (u8)(pRxWI->SNR1);
-
-		pAd->RalinkCounters.OneSecRxOkDataCnt++;
-
-		if (!((pHeader->Frag == 0) && (pHeader->FC.MoreFrag == 0))) {
-			/* re-assemble the fragmented packets */
-			/* return complete frame (pRxPacket) or NULL */
-			bFragment = TRUE;
-			pRxPacket = RTMPDeFragmentDataFrame(pAd, pRxBlk);
-		}
-
-		if (pRxPacket) {
-			pEntry = &pAd->MacTab.Content[pRxWI->WirelessCliID];
-
-			/* process complete frame */
-			if (bFragment && (pRxD->Decrypted)
-			    && (pEntry->WepStatus ==
-				Ndis802_11Encryption2Enabled)) {
-				/* Minus MIC length */
-				pRxBlk->DataSize -= 8;
-
-				/* For TKIP frame, calculate the MIC value */
-				if (STACheckTkipMICValue(pAd, pEntry, pRxBlk) ==
-				    FALSE) {
-					return;
-				}
-			}
-
-			STARxDataFrameAnnounce(pAd, pEntry, pRxBlk,
-					       FromWhichBSSID);
-			return;
-		} else {
-			/* just return */
-			/* because RTMPDeFragmentDataFrame() will release rx packet, */
-			/* if packet is fragmented */
-			return;
-		}
-	}
-
-	ASSERT(0);
-	/* release packet */
-	RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_FAILURE);
-}
-
-void STAHandleRxMgmtFrame(struct rt_rtmp_adapter *pAd, struct rt_rx_blk *pRxBlk)
-{
-	PRT28XX_RXD_STRUC pRxD = &(pRxBlk->RxD);
-	struct rt_rxwi * pRxWI = pRxBlk->pRxWI;
-	struct rt_header_802_11 * pHeader = pRxBlk->pHeader;
-	void *pRxPacket = pRxBlk->pRxPacket;
-
-	do {
-
-		/* check if need to resend PS Poll when received packet with MoreData = 1 */
-		if ((pAd->StaCfg.Psm == PWR_SAVE)
-		    && (pHeader->FC.MoreData == 1)) {
-			/* for UAPSD, all management frames will be VO priority */
-			if (pAd->CommonCfg.bAPSDAC_VO == 0) {
-				/* non-UAPSD delivery-enabled AC */
-				RTMP_PS_POLL_ENQUEUE(pAd);
-			}
-		}
-
-		/* TODO: if MoreData == 0, station can go to sleep */
-
-		/* We should collect RSSI not only U2M data but also my beacon */
-		if ((pHeader->FC.SubType == SUBTYPE_BEACON)
-		    && (MAC_ADDR_EQUAL(&pAd->CommonCfg.Bssid, &pHeader->Addr2))
-		    && (pAd->RxAnt.EvaluatePeriod == 0)) {
-			Update_Rssi_Sample(pAd, &pAd->StaCfg.RssiSample, pRxWI);
-
-			pAd->StaCfg.LastSNR0 = (u8)(pRxWI->SNR0);
-			pAd->StaCfg.LastSNR1 = (u8)(pRxWI->SNR1);
-		}
-
-		/* First check the size, it MUST not exceed the mlme queue size */
-		if (pRxWI->MPDUtotalByteCount > MGMT_DMA_BUFFER_SIZE) {
-			DBGPRINT_ERR("STAHandleRxMgmtFrame: frame too large, size = %d \n", pRxWI->MPDUtotalByteCount);
-			break;
-		}
-
-		REPORT_MGMT_FRAME_TO_MLME(pAd, pRxWI->WirelessCliID, pHeader,
-					  pRxWI->MPDUtotalByteCount,
-					  pRxWI->RSSI0, pRxWI->RSSI1,
-					  pRxWI->RSSI2, pRxD->PlcpSignal);
-	} while (FALSE);
-
-	RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_SUCCESS);
-}
-
-void STAHandleRxControlFrame(struct rt_rtmp_adapter *pAd, struct rt_rx_blk *pRxBlk)
-{
-	struct rt_rxwi * pRxWI = pRxBlk->pRxWI;
-	struct rt_header_802_11 * pHeader = pRxBlk->pHeader;
-	void *pRxPacket = pRxBlk->pRxPacket;
-
-	switch (pHeader->FC.SubType) {
-	case SUBTYPE_BLOCK_ACK_REQ:
-		{
-			CntlEnqueueForRecv(pAd, pRxWI->WirelessCliID,
-					   (pRxWI->MPDUtotalByteCount),
-					   (struct rt_frame_ba_req *) pHeader);
-		}
-		break;
-	case SUBTYPE_BLOCK_ACK:
-	case SUBTYPE_ACK:
-	default:
-		break;
-	}
-
-	RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_FAILURE);
-}
-
-/*
-	========================================================================
-
-	Routine Description:
-		Process RxDone interrupt, running in DPC level
-
-	Arguments:
-		pAd Pointer to our adapter
-
-	Return Value:
-		None
-
-	IRQL = DISPATCH_LEVEL
-
-	Note:
-		This routine has to maintain Rx ring read pointer.
-		Need to consider QOS DATA format when converting to 802.3
-	========================================================================
-*/
-BOOLEAN STARxDoneInterruptHandle(struct rt_rtmp_adapter *pAd, IN BOOLEAN argc)
-{
-	int Status;
-	u32 RxProcessed, RxPending;
-	BOOLEAN bReschedule = FALSE;
-	PRT28XX_RXD_STRUC pRxD;
-	u8 *pData;
-	struct rt_rxwi * pRxWI;
-	void *pRxPacket;
-	struct rt_header_802_11 * pHeader;
-	struct rt_rx_blk RxCell;
-
-	RxProcessed = RxPending = 0;
-
-	/* process whole rx ring */
-	while (1) {
-
-		if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF |
-				   fRTMP_ADAPTER_RESET_IN_PROGRESS |
-				   fRTMP_ADAPTER_HALT_IN_PROGRESS |
-				   fRTMP_ADAPTER_NIC_NOT_EXIST) ||
-		    !RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_START_UP)) {
-			break;
-		}
-#ifdef RTMP_MAC_PCI
-		if (RxProcessed++ > MAX_RX_PROCESS_CNT) {
-			/* need to reschedule rx handle */
-			bReschedule = TRUE;
-			break;
-		}
-#endif /* RTMP_MAC_PCI // */
-
-		RxProcessed++;	/* test */
-
-		/* 1. allocate a new data packet into rx ring to replace received packet */
-		/*    then processing the received packet */
-		/* 2. the callee must take charge of release of packet */
-		/* 3. As far as driver is concerned , */
-		/*    the rx packet must */
-		/*      a. be indicated to upper layer or */
-		/*      b. be released if it is discarded */
-		pRxPacket =
-		    GetPacketFromRxRing(pAd, &(RxCell.RxD), &bReschedule,
-					&RxPending);
-		if (pRxPacket == NULL) {
-			/* no more packet to process */
-			break;
-		}
-		/* get rx ring descriptor */
-		pRxD = &(RxCell.RxD);
-		/* get rx data buffer */
-		pData = GET_OS_PKT_DATAPTR(pRxPacket);
-		pRxWI = (struct rt_rxwi *) pData;
-		pHeader = (struct rt_header_802_11 *) (pData + RXWI_SIZE);
-
-		/* build RxCell */
-		RxCell.pRxWI = pRxWI;
-		RxCell.pHeader = pHeader;
-		RxCell.pRxPacket = pRxPacket;
-		RxCell.pData = (u8 *) pHeader;
-		RxCell.DataSize = pRxWI->MPDUtotalByteCount;
-		RxCell.Flags = 0;
-
-		/* Increase Total receive byte counter after real data received no mater any error or not */
-		pAd->RalinkCounters.ReceivedByteCount +=
-		    pRxWI->MPDUtotalByteCount;
-		pAd->RalinkCounters.OneSecReceivedByteCount +=
-		    pRxWI->MPDUtotalByteCount;
-		pAd->RalinkCounters.RxCount++;
-
-		INC_COUNTER64(pAd->WlanCounters.ReceivedFragmentCount);
-
-		if (pRxWI->MPDUtotalByteCount < 14)
-			Status = NDIS_STATUS_FAILURE;
-
-		if (MONITOR_ON(pAd)) {
-			send_monitor_packets(pAd, &RxCell);
-			break;
-		}
-
-		/* STARxDoneInterruptHandle() is called in rtusb_bulk.c */
-
-		/* Check for all RxD errors */
-		Status = RTMPCheckRxError(pAd, pHeader, pRxWI, pRxD);
-
-		/* Handle the received frame */
-		if (Status == NDIS_STATUS_SUCCESS) {
-			switch (pHeader->FC.Type) {
-				/* CASE I, receive a DATA frame */
-			case BTYPE_DATA:
-				{
-					/* process DATA frame */
-					STAHandleRxDataFrame(pAd, &RxCell);
-				}
-				break;
-				/* CASE II, receive a MGMT frame */
-			case BTYPE_MGMT:
-				{
-					STAHandleRxMgmtFrame(pAd, &RxCell);
-				}
-				break;
-				/* CASE III. receive a CNTL frame */
-			case BTYPE_CNTL:
-				{
-					STAHandleRxControlFrame(pAd, &RxCell);
-				}
-				break;
-				/* discard other type */
-			default:
-				RELEASE_NDIS_PACKET(pAd, pRxPacket,
-						    NDIS_STATUS_FAILURE);
-				break;
-			}
-		} else {
-			pAd->Counters8023.RxErrors++;
-			/* discard this frame */
-			RELEASE_NDIS_PACKET(pAd, pRxPacket,
-					    NDIS_STATUS_FAILURE);
-		}
-	}
-
-	return bReschedule;
-}
-
-/*
-	========================================================================
-
-	Routine Description:
-	Arguments:
-		pAd 	Pointer to our adapter
-
-	IRQL = DISPATCH_LEVEL
-
-	========================================================================
-*/
-void RTMPHandleTwakeupInterrupt(struct rt_rtmp_adapter *pAd)
-{
-	AsicForceWakeup(pAd, FALSE);
-}
-
-/*
-========================================================================
-Routine Description:
-    Early checking and OS-depened parsing for Tx packet send to our STA driver.
-
-Arguments:
-    void *	MiniportAdapterContext	Pointer refer to the device handle, i.e., the pAd.
-	void **	ppPacketArray			The packet array need to do transmission.
-	u32			NumberOfPackets			Number of packet in packet array.
-
-Return Value:
-	NONE
-
-Note:
-	This function does early checking and classification for send-out packet.
-	You only can put OS-depened & STA related code in here.
-========================================================================
-*/
-void STASendPackets(void *MiniportAdapterContext,
-		    void **ppPacketArray, u32 NumberOfPackets)
-{
-	u32 Index;
-	struct rt_rtmp_adapter *pAd = (struct rt_rtmp_adapter *)MiniportAdapterContext;
-	void *pPacket;
-	BOOLEAN allowToSend = FALSE;
-
-	for (Index = 0; Index < NumberOfPackets; Index++) {
-		pPacket = ppPacketArray[Index];
-
-		do {
-			if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)
-			    || RTMP_TEST_FLAG(pAd,
-					      fRTMP_ADAPTER_HALT_IN_PROGRESS)
-			    || RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF)) {
-				/* Drop send request since hardware is in reset state */
-				break;
-			} else if (!INFRA_ON(pAd) && !ADHOC_ON(pAd)) {
-				/* Drop send request since there are no physical connection yet */
-				break;
-			} else {
-				/* Record that orignal packet source is from NDIS layer,so that */
-				/* later on driver knows how to release this NDIS PACKET */
-				RTMP_SET_PACKET_WCID(pPacket, 0);	/* this field is useless when in STA mode */
-				RTMP_SET_PACKET_SOURCE(pPacket, PKTSRC_NDIS);
-				NDIS_SET_PACKET_STATUS(pPacket,
-						       NDIS_STATUS_PENDING);
-				pAd->RalinkCounters.PendingNdisPacketCount++;
-
-				allowToSend = TRUE;
-			}
-		} while (FALSE);
-
-		if (allowToSend == TRUE)
-			STASendPacket(pAd, pPacket);
-		else
-			RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
-	}
-
-	/* Dequeue outgoing frames from TxSwQueue[] and process it */
-	RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, MAX_TX_PROCESS);
-
-}
-
-/*
-========================================================================
-Routine Description:
-	This routine is used to do packet parsing and classification for Tx packet
-	to STA device, and it will en-queue packets to our TxSwQueue depends on AC
-	class.
-
-Arguments:
-	pAd    		Pointer to our adapter
-	pPacket 	Pointer to send packet
-
-Return Value:
-	NDIS_STATUS_SUCCESS			If success to queue the packet into TxSwQueue.
-	NDIS_STATUS_FAILURE			If failed to do en-queue.
-
-Note:
-	You only can put OS-indepened & STA related code in here.
-========================================================================
-*/
-int STASendPacket(struct rt_rtmp_adapter *pAd, void *pPacket)
-{
-	struct rt_packet_info PacketInfo;
-	u8 *pSrcBufVA;
-	u32 SrcBufLen;
-	u32 AllowFragSize;
-	u8 NumberOfFrag;
-	u8 RTSRequired;
-	u8 QueIdx, UserPriority;
-	struct rt_mac_table_entry *pEntry = NULL;
-	unsigned int IrqFlags;
-	u8 FlgIsIP = 0;
-	u8 Rate;
-
-	/* Prepare packet information structure for buffer descriptor */
-	/* chained within a single NDIS packet. */
-	RTMP_QueryPacketInfo(pPacket, &PacketInfo, &pSrcBufVA, &SrcBufLen);
-
-	if (pSrcBufVA == NULL) {
-		DBGPRINT(RT_DEBUG_ERROR,
-			 ("STASendPacket --> pSrcBufVA == NULL !SrcBufLen=%x\n",
-			  SrcBufLen));
-		/* Resource is low, system did not allocate virtual address */
-		/* return NDIS_STATUS_FAILURE directly to upper layer */
-		RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
-		return NDIS_STATUS_FAILURE;
-	}
-
-	if (SrcBufLen < 14) {
-		DBGPRINT(RT_DEBUG_ERROR,
-			 ("STASendPacket --> Ndis Packet buffer error!\n"));
-		RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
-		return (NDIS_STATUS_FAILURE);
-	}
-	/* In HT rate adhoc mode, A-MPDU is often used. So need to lookup BA Table and MAC Entry. */
-	/* Note multicast packets in adhoc also use BSSID_WCID index. */
-	{
-		if (INFRA_ON(pAd)) {
-			{
-				pEntry = &pAd->MacTab.Content[BSSID_WCID];
-				RTMP_SET_PACKET_WCID(pPacket, BSSID_WCID);
-				Rate = pAd->CommonCfg.TxRate;
-			}
-		} else if (ADHOC_ON(pAd)) {
-			if (*pSrcBufVA & 0x01) {
-				RTMP_SET_PACKET_WCID(pPacket, MCAST_WCID);
-				pEntry = &pAd->MacTab.Content[MCAST_WCID];
-			} else {
-				pEntry = MacTableLookup(pAd, pSrcBufVA);
-			}
-			Rate = pAd->CommonCfg.TxRate;
-		}
-	}
-
-	if (!pEntry) {
-		DBGPRINT(RT_DEBUG_ERROR,
-			("STASendPacket->Cannot find pEntry(%pM) in MacTab!\n",
-				pSrcBufVA));
-		/* Resource is low, system did not allocate virtual address */
-		/* return NDIS_STATUS_FAILURE directly to upper layer */
-		RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
-		return NDIS_STATUS_FAILURE;
-	}
-
-	if (ADHOC_ON(pAd)
-	    ) {
-		RTMP_SET_PACKET_WCID(pPacket, (u8)pEntry->Aid);
-	}
-	/* */
-	/* Check the Ethernet Frame type of this packet, and set the RTMP_SET_PACKET_SPECIFIC flags. */
-	/*              Here we set the PACKET_SPECIFIC flags(LLC, VLAN, DHCP/ARP, EAPOL). */
-	RTMPCheckEtherType(pAd, pPacket);
-
-	/* */
-	/* WPA 802.1x secured port control - drop all non-802.1x frame before port secured */
-	/* */
-	if (((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) ||
-	     (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK) ||
-	     (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) ||
-	     (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK)
-	     || (pAd->StaCfg.IEEE8021X == TRUE)
-	    )
-	    && ((pAd->StaCfg.PortSecured == WPA_802_1X_PORT_NOT_SECURED)
-		|| (pAd->StaCfg.MicErrCnt >= 2))
-	    && (RTMP_GET_PACKET_EAPOL(pPacket) == FALSE)
-	    ) {
-		DBGPRINT(RT_DEBUG_TRACE,
-			 ("STASendPacket --> Drop packet before port secured!\n"));
-		RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
-
-		return (NDIS_STATUS_FAILURE);
-	}
-
-	/* STEP 1. Decide number of fragments required to deliver this MSDU. */
-	/*         The estimation here is not very accurate because difficult to */
-	/*         take encryption overhead into consideration here. The result */
-	/*         "NumberOfFrag" is then just used to pre-check if enough free */
-	/*         TXD are available to hold this MSDU. */
-
-	if (*pSrcBufVA & 0x01)	/* fragmentation not allowed on multicast & broadcast */
-		NumberOfFrag = 1;
-	else if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED))
-		NumberOfFrag = 1;	/* Aggregation overwhelms fragmentation */
-	else if (CLIENT_STATUS_TEST_FLAG(pEntry, fCLIENT_STATUS_AMSDU_INUSED))
-		NumberOfFrag = 1;	/* Aggregation overwhelms fragmentation */
-	else if ((pAd->StaCfg.HTPhyMode.field.MODE == MODE_HTMIX)
-		 || (pAd->StaCfg.HTPhyMode.field.MODE == MODE_HTGREENFIELD))
-		NumberOfFrag = 1;	/* MIMO RATE overwhelms fragmentation */
-	else {
-		/* The calculated "NumberOfFrag" is a rough estimation because of various */
-		/* encryption/encapsulation overhead not taken into consideration. This number is just */
-		/* used to make sure enough free TXD are available before fragmentation takes place. */
-		/* In case the actual required number of fragments of an NDIS packet */
-		/* excceeds "NumberOfFrag"caculated here and not enough free TXD available, the */
-		/* last fragment (i.e. last MPDU) will be dropped in RTMPHardTransmit() due to out of */
-		/* resource, and the NDIS packet will be indicated NDIS_STATUS_FAILURE. This should */
-		/* rarely happen and the penalty is just like a TX RETRY fail. Affordable. */
-
-		AllowFragSize =
-		    (pAd->CommonCfg.FragmentThreshold) - LENGTH_802_11 -
-		    LENGTH_CRC;
-		NumberOfFrag =
-		    ((PacketInfo.TotalPacketLength - LENGTH_802_3 +
-		      LENGTH_802_1_H) / AllowFragSize) + 1;
-		/* To get accurate number of fragmentation, Minus 1 if the size just match to allowable fragment size */
-		if (((PacketInfo.TotalPacketLength - LENGTH_802_3 +
-		      LENGTH_802_1_H) % AllowFragSize) == 0) {
-			NumberOfFrag--;
-		}
-	}
-
-	/* Save fragment number to Ndis packet reserved field */
-	RTMP_SET_PACKET_FRAGMENTS(pPacket, NumberOfFrag);
-
-	/* STEP 2. Check the requirement of RTS: */
-	/*         If multiple fragment required, RTS is required only for the first fragment */
-	/*         if the fragment size is larger than RTS threshold */
-	/*     For RT28xx, Let ASIC send RTS/CTS */
-	/*      RTMP_SET_PACKET_RTS(pPacket, 0); */
-	if (NumberOfFrag > 1)
-		RTSRequired =
-		    (pAd->CommonCfg.FragmentThreshold >
-		     pAd->CommonCfg.RtsThreshold) ? 1 : 0;
-	else
-		RTSRequired =
-		    (PacketInfo.TotalPacketLength >
-		     pAd->CommonCfg.RtsThreshold) ? 1 : 0;
-
-	/* Save RTS requirement to Ndis packet reserved field */
-	RTMP_SET_PACKET_RTS(pPacket, RTSRequired);
-	RTMP_SET_PACKET_TXRATE(pPacket, pAd->CommonCfg.TxRate);
-
-	/* */
-	/* STEP 3. Traffic classification. outcome = <UserPriority, QueIdx> */
-	/* */
-	UserPriority = 0;
-	QueIdx = QID_AC_BE;
-	if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED) &&
-	    CLIENT_STATUS_TEST_FLAG(pEntry, fCLIENT_STATUS_WMM_CAPABLE)) {
-		u16 Protocol;
-		u8 LlcSnapLen = 0, Byte0, Byte1;
-		do {
-			/* get Ethernet protocol field */
-			Protocol =
-			    (u16)((pSrcBufVA[12] << 8) + pSrcBufVA[13]);
-			if (Protocol <= 1500) {
-				/* get Ethernet protocol field from LLC/SNAP */
-				if (Sniff2BytesFromNdisBuffer
-				    (PacketInfo.pFirstBuffer, LENGTH_802_3 + 6,
-				     &Byte0, &Byte1) != NDIS_STATUS_SUCCESS)
-					break;
-
-				Protocol = (u16)((Byte0 << 8) + Byte1);
-				LlcSnapLen = 8;
-			}
-			/* always AC_BE for non-IP packet */
-			if (Protocol != 0x0800)
-				break;
-
-			/* get IP header */
-			if (Sniff2BytesFromNdisBuffer
-			    (PacketInfo.pFirstBuffer, LENGTH_802_3 + LlcSnapLen,
-			     &Byte0, &Byte1) != NDIS_STATUS_SUCCESS)
-				break;
-
-			/* return AC_BE if packet is not IPv4 */
-			if ((Byte0 & 0xf0) != 0x40)
-				break;
-
-			FlgIsIP = 1;
-			UserPriority = (Byte1 & 0xe0) >> 5;
-			QueIdx = MapUserPriorityToAccessCategory[UserPriority];
-
-			/* TODO: have to check ACM bit. apply TSPEC if ACM is ON */
-			/* TODO: downgrade UP & QueIdx before passing ACM */
-			/*
-			   Under WMM ACM control, we dont need to check the bit;
-			   Or when a TSPEC is built for VO but we will change to issue
-			   BA session for BE here, so we will not use BA to send VO packets.
-			 */
-			if (pAd->CommonCfg.APEdcaParm.bACM[QueIdx]) {
-				UserPriority = 0;
-				QueIdx = QID_AC_BE;
-			}
-		} while (FALSE);
-	}
-
-	RTMP_SET_PACKET_UP(pPacket, UserPriority);
-
-	/* Make sure SendTxWait queue resource won't be used by other threads */
-	RTMP_IRQ_LOCK(&pAd->irq_lock, IrqFlags);
-	if (pAd->TxSwQueue[QueIdx].Number >= MAX_PACKETS_IN_QUEUE) {
-		RTMP_IRQ_UNLOCK(&pAd->irq_lock, IrqFlags);
-		RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
-
-		return NDIS_STATUS_FAILURE;
-	} else {
-		InsertTailQueueAc(pAd, pEntry, &pAd->TxSwQueue[QueIdx],
-				  PACKET_TO_QUEUE_ENTRY(pPacket));
-	}
-	RTMP_IRQ_UNLOCK(&pAd->irq_lock, IrqFlags);
-
-	if ((pAd->CommonCfg.BACapability.field.AutoBA == TRUE) &&
-	    IS_HT_STA(pEntry)) {
-		/*struct rt_mac_table_entry *pMacEntry = &pAd->MacTab.Content[BSSID_WCID]; */
-		if (((pEntry->TXBAbitmap & (1 << UserPriority)) == 0) &&
-		    ((pEntry->BADeclineBitmap & (1 << UserPriority)) == 0) &&
-		    (pEntry->PortSecured == WPA_802_1X_PORT_SECURED)
-		    /* For IOT compatibility, if */
-		    /* 1. It is Ralink chip or */
-		    /* 2. It is OPEN or AES mode, */
-		    /* then BA session can be bulit. */
-		    && ((pEntry->ValidAsCLI && pAd->MlmeAux.APRalinkIe != 0x0)
-			|| (pEntry->WepStatus != Ndis802_11WEPEnabled
-			    && pEntry->WepStatus !=
-			    Ndis802_11Encryption2Enabled))
-		    ) {
-			BAOriSessionSetUp(pAd, pEntry, UserPriority, 0, 10,
-					  FALSE);
-		}
-	}
-
-	pAd->RalinkCounters.OneSecOsTxCount[QueIdx]++;	/* TODO: for debug only. to be removed */
-	return NDIS_STATUS_SUCCESS;
-}
-
-/*
-	========================================================================
-
-	Routine Description:
-		This subroutine will scan through relative ring descriptor to find
-		out available free ring descriptor and compare with request size.
-
-	Arguments:
-		pAd Pointer to our adapter
-		QueIdx		Selected TX Ring
-
-	Return Value:
-		NDIS_STATUS_FAILURE 	Not enough free descriptor
-		NDIS_STATUS_SUCCESS 	Enough free descriptor
-
-	IRQL = PASSIVE_LEVEL
-	IRQL = DISPATCH_LEVEL
-
-	Note:
-
-	========================================================================
-*/
-#ifdef RTMP_MAC_PCI
-int RTMPFreeTXDRequest(struct rt_rtmp_adapter *pAd,
-			       u8 QueIdx,
-			       u8 NumberRequired, u8 *FreeNumberIs)
-{
-	unsigned long FreeNumber = 0;
-	int Status = NDIS_STATUS_FAILURE;
-
-	switch (QueIdx) {
-	case QID_AC_BK:
-	case QID_AC_BE:
-	case QID_AC_VI:
-	case QID_AC_VO:
-		if (pAd->TxRing[QueIdx].TxSwFreeIdx >
-		    pAd->TxRing[QueIdx].TxCpuIdx)
-			FreeNumber =
-			    pAd->TxRing[QueIdx].TxSwFreeIdx -
-			    pAd->TxRing[QueIdx].TxCpuIdx - 1;
-		else
-			FreeNumber =
-			    pAd->TxRing[QueIdx].TxSwFreeIdx + TX_RING_SIZE -
-			    pAd->TxRing[QueIdx].TxCpuIdx - 1;
-
-		if (FreeNumber >= NumberRequired)
-			Status = NDIS_STATUS_SUCCESS;
-		break;
-
-	case QID_MGMT:
-		if (pAd->MgmtRing.TxSwFreeIdx > pAd->MgmtRing.TxCpuIdx)
-			FreeNumber =
-			    pAd->MgmtRing.TxSwFreeIdx - pAd->MgmtRing.TxCpuIdx -
-			    1;
-		else
-			FreeNumber =
-			    pAd->MgmtRing.TxSwFreeIdx + MGMT_RING_SIZE -
-			    pAd->MgmtRing.TxCpuIdx - 1;
-
-		if (FreeNumber >= NumberRequired)
-			Status = NDIS_STATUS_SUCCESS;
-		break;
-
-	default:
-		DBGPRINT(RT_DEBUG_ERROR,
-			 ("RTMPFreeTXDRequest::Invalid QueIdx(=%d)\n", QueIdx));
-		break;
-	}
-	*FreeNumberIs = (u8)FreeNumber;
-
-	return (Status);
-}
-#endif /* RTMP_MAC_PCI // */
-#ifdef RTMP_MAC_USB
-/*
-	Actually, this function used to check if the TxHardware Queue still has frame need to send.
-	If no frame need to send, go to sleep, else, still wake up.
-*/
-int RTMPFreeTXDRequest(struct rt_rtmp_adapter *pAd,
-			       u8 QueIdx,
-			       u8 NumberRequired, u8 *FreeNumberIs)
-{
-	/*unsigned long         FreeNumber = 0; */
-	int Status = NDIS_STATUS_FAILURE;
-	unsigned long IrqFlags;
-	struct rt_ht_tx_context *pHTTXContext;
-
-	switch (QueIdx) {
-	case QID_AC_BK:
-	case QID_AC_BE:
-	case QID_AC_VI:
-	case QID_AC_VO:
-		{
-			pHTTXContext = &pAd->TxContext[QueIdx];
-			RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[QueIdx],
-				      IrqFlags);
-			if ((pHTTXContext->CurWritePosition !=
-			     pHTTXContext->ENextBulkOutPosition)
-			    || (pHTTXContext->IRPPending == TRUE)) {
-				Status = NDIS_STATUS_FAILURE;
-			} else {
-				Status = NDIS_STATUS_SUCCESS;
-			}
-			RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[QueIdx],
-					IrqFlags);
-		}
-		break;
-	case QID_MGMT:
-		if (pAd->MgmtRing.TxSwFreeIdx != MGMT_RING_SIZE)
-			Status = NDIS_STATUS_FAILURE;
-		else
-			Status = NDIS_STATUS_SUCCESS;
-		break;
-	default:
-		DBGPRINT(RT_DEBUG_ERROR,
-			 ("RTMPFreeTXDRequest::Invalid QueIdx(=%d)\n", QueIdx));
-		break;
-	}
-
-	return (Status);
-}
-#endif /* RTMP_MAC_USB // */
-
-void RTMPSendDisassociationFrame(struct rt_rtmp_adapter *pAd)
-{
-}
-
-void RTMPSendNullFrame(struct rt_rtmp_adapter *pAd,
-		       u8 TxRate, IN BOOLEAN bQosNull)
-{
-	u8 NullFrame[48];
-	unsigned long Length;
-	struct rt_header_802_11 * pHeader_802_11;
-
-	/* WPA 802.1x secured port control */
-	if (((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) ||
-	     (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK) ||
-	     (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) ||
-	     (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK)
-	     || (pAd->StaCfg.IEEE8021X == TRUE)
-	    ) && (pAd->StaCfg.PortSecured == WPA_802_1X_PORT_NOT_SECURED)) {
-		return;
-	}
-
-	NdisZeroMemory(NullFrame, 48);
-	Length = sizeof(struct rt_header_802_11);
-
-	pHeader_802_11 = (struct rt_header_802_11 *) NullFrame;
-
-	pHeader_802_11->FC.Type = BTYPE_DATA;
-	pHeader_802_11->FC.SubType = SUBTYPE_NULL_FUNC;
-	pHeader_802_11->FC.ToDs = 1;
-	COPY_MAC_ADDR(pHeader_802_11->Addr1, pAd->CommonCfg.Bssid);
-	COPY_MAC_ADDR(pHeader_802_11->Addr2, pAd->CurrentAddress);
-	COPY_MAC_ADDR(pHeader_802_11->Addr3, pAd->CommonCfg.Bssid);
-
-	if (pAd->CommonCfg.bAPSDForcePowerSave) {
-		pHeader_802_11->FC.PwrMgmt = PWR_SAVE;
-	} else {
-		pHeader_802_11->FC.PwrMgmt =
-		    (pAd->StaCfg.Psm == PWR_SAVE) ? 1 : 0;
-	}
-	pHeader_802_11->Duration =
-	    pAd->CommonCfg.Dsifs + RTMPCalcDuration(pAd, TxRate, 14);
-
-	pAd->Sequence++;
-	pHeader_802_11->Sequence = pAd->Sequence;
-
-	/* Prepare QosNull function frame */
-	if (bQosNull) {
-		pHeader_802_11->FC.SubType = SUBTYPE_QOS_NULL;
-
-		/* copy QOS control bytes */
-		NullFrame[Length] = 0;
-		NullFrame[Length + 1] = 0;
-		Length += 2;	/* if pad with 2 bytes for alignment, APSD will fail */
-	}
-
-	HAL_KickOutNullFrameTx(pAd, 0, NullFrame, Length);
-
-}
-
-/* IRQL = DISPATCH_LEVEL */
-void RTMPSendRTSFrame(struct rt_rtmp_adapter *pAd,
-		      u8 *pDA,
-		      IN unsigned int NextMpduSize,
-		      u8 TxRate,
-		      u8 RTSRate,
-		      u16 AckDuration, u8 QueIdx, u8 FrameGap)
-{
-}
-
-/* -------------------------------------------------------- */
-/*  FIND ENCRYPT KEY AND DECIDE CIPHER ALGORITHM */
-/*              Find the WPA key, either Group or Pairwise Key */
-/*              LEAP + TKIP also use WPA key. */
-/* -------------------------------------------------------- */
-/* Decide WEP bit and cipher suite to be used. Same cipher suite should be used for whole fragment burst */
-/* In Cisco CCX 2.0 Leap Authentication */
-/*                 WepStatus is Ndis802_11Encryption1Enabled but the key will use PairwiseKey */
-/*                 Instead of the SharedKey, SharedKey Length may be Zero. */
-void STAFindCipherAlgorithm(struct rt_rtmp_adapter *pAd, struct rt_tx_blk *pTxBlk)
-{
-	NDIS_802_11_ENCRYPTION_STATUS Cipher;	/* To indicate cipher used for this packet */
-	u8 CipherAlg = CIPHER_NONE;	/* cipher alogrithm */
-	u8 KeyIdx = 0xff;
-	u8 *pSrcBufVA;
-	struct rt_cipher_key *pKey = NULL;
-
-	pSrcBufVA = GET_OS_PKT_DATAPTR(pTxBlk->pPacket);
-
-	{
-		/* Select Cipher */
-		if ((*pSrcBufVA & 0x01) && (ADHOC_ON(pAd)))
-			Cipher = pAd->StaCfg.GroupCipher;	/* Cipher for Multicast or Broadcast */
-		else
-			Cipher = pAd->StaCfg.PairCipher;	/* Cipher for Unicast */
-
-		if (RTMP_GET_PACKET_EAPOL(pTxBlk->pPacket)) {
-			ASSERT(pAd->SharedKey[BSS0][0].CipherAlg <=
-			       CIPHER_CKIP128);
-
-			/* 4-way handshaking frame must be clear */
-			if (!(TX_BLK_TEST_FLAG(pTxBlk, fTX_bClearEAPFrame))
-			    && (pAd->SharedKey[BSS0][0].CipherAlg)
-			    && (pAd->SharedKey[BSS0][0].KeyLen)) {
-				CipherAlg = pAd->SharedKey[BSS0][0].CipherAlg;
-				KeyIdx = 0;
-			}
-		} else if (Cipher == Ndis802_11Encryption1Enabled) {
-			KeyIdx = pAd->StaCfg.DefaultKeyId;
-		} else if ((Cipher == Ndis802_11Encryption2Enabled) ||
-			   (Cipher == Ndis802_11Encryption3Enabled)) {
-			if ((*pSrcBufVA & 0x01) && (ADHOC_ON(pAd)))	/* multicast */
-				KeyIdx = pAd->StaCfg.DefaultKeyId;
-			else if (pAd->SharedKey[BSS0][0].KeyLen)
-				KeyIdx = 0;
-			else
-				KeyIdx = pAd->StaCfg.DefaultKeyId;
-		}
-
-		if (KeyIdx == 0xff)
-			CipherAlg = CIPHER_NONE;
-		else if ((Cipher == Ndis802_11EncryptionDisabled)
-			 || (pAd->SharedKey[BSS0][KeyIdx].KeyLen == 0))
-			CipherAlg = CIPHER_NONE;
-		else if (pAd->StaCfg.WpaSupplicantUP &&
-			 (Cipher == Ndis802_11Encryption1Enabled) &&
-			 (pAd->StaCfg.IEEE8021X == TRUE) &&
-			 (pAd->StaCfg.PortSecured ==
-			  WPA_802_1X_PORT_NOT_SECURED))
-			CipherAlg = CIPHER_NONE;
-		else {
-			/*Header_802_11.FC.Wep = 1; */
-			CipherAlg = pAd->SharedKey[BSS0][KeyIdx].CipherAlg;
-			pKey = &pAd->SharedKey[BSS0][KeyIdx];
-		}
-	}
-
-	pTxBlk->CipherAlg = CipherAlg;
-	pTxBlk->pKey = pKey;
-}
-
-void STABuildCommon802_11Header(struct rt_rtmp_adapter *pAd, struct rt_tx_blk *pTxBlk)
-{
-	struct rt_header_802_11 *pHeader_802_11;
-
-	/* */
-	/* MAKE A COMMON 802.11 HEADER */
-	/* */
-
-	/* normal wlan header size : 24 octets */
-	pTxBlk->MpduHeaderLen = sizeof(struct rt_header_802_11);
-
-	pHeader_802_11 =
-	    (struct rt_header_802_11 *) & pTxBlk->HeaderBuf[TXINFO_SIZE + TXWI_SIZE];
-
-	NdisZeroMemory(pHeader_802_11, sizeof(struct rt_header_802_11));
-
-	pHeader_802_11->FC.FrDs = 0;
-	pHeader_802_11->FC.Type = BTYPE_DATA;
-	pHeader_802_11->FC.SubType =
-	    ((TX_BLK_TEST_FLAG(pTxBlk, fTX_bWMM)) ? SUBTYPE_QDATA :
-	     SUBTYPE_DATA);
-
-	if (pTxBlk->pMacEntry) {
-		if (TX_BLK_TEST_FLAG(pTxBlk, fTX_bForceNonQoS)) {
-			pHeader_802_11->Sequence =
-			    pTxBlk->pMacEntry->NonQosDataSeq;
-			pTxBlk->pMacEntry->NonQosDataSeq =
-			    (pTxBlk->pMacEntry->NonQosDataSeq + 1) & MAXSEQ;
-		} else {
-			{
-				pHeader_802_11->Sequence =
-				    pTxBlk->pMacEntry->TxSeq[pTxBlk->
-							     UserPriority];
-				pTxBlk->pMacEntry->TxSeq[pTxBlk->UserPriority] =
-				    (pTxBlk->pMacEntry->
-				     TxSeq[pTxBlk->UserPriority] + 1) & MAXSEQ;
-			}
-		}
-	} else {
-		pHeader_802_11->Sequence = pAd->Sequence;
-		pAd->Sequence = (pAd->Sequence + 1) & MAXSEQ;	/* next sequence */
-	}
-
-	pHeader_802_11->Frag = 0;
-
-	pHeader_802_11->FC.MoreData = TX_BLK_TEST_FLAG(pTxBlk, fTX_bMoreData);
-
-	{
-		if (INFRA_ON(pAd)) {
-			{
-				COPY_MAC_ADDR(pHeader_802_11->Addr1,
-					      pAd->CommonCfg.Bssid);
-				COPY_MAC_ADDR(pHeader_802_11->Addr2,
-					      pAd->CurrentAddress);
-				COPY_MAC_ADDR(pHeader_802_11->Addr3,
-					      pTxBlk->pSrcBufHeader);
-				pHeader_802_11->FC.ToDs = 1;
-			}
-		} else if (ADHOC_ON(pAd)) {
-			COPY_MAC_ADDR(pHeader_802_11->Addr1,
-				      pTxBlk->pSrcBufHeader);
-			COPY_MAC_ADDR(pHeader_802_11->Addr2,
-				      pAd->CurrentAddress);
-			COPY_MAC_ADDR(pHeader_802_11->Addr3,
-				      pAd->CommonCfg.Bssid);
-			pHeader_802_11->FC.ToDs = 0;
-		}
-	}
-
-	if (pTxBlk->CipherAlg != CIPHER_NONE)
-		pHeader_802_11->FC.Wep = 1;
-
-	/* ----------------------------------------------------------------- */
-	/* STEP 2. MAKE A COMMON 802.11 HEADER SHARED BY ENTIRE FRAGMENT BURST. Fill sequence later. */
-	/* ----------------------------------------------------------------- */
-	if (pAd->CommonCfg.bAPSDForcePowerSave)
-		pHeader_802_11->FC.PwrMgmt = PWR_SAVE;
-	else
-		pHeader_802_11->FC.PwrMgmt = (pAd->StaCfg.Psm == PWR_SAVE);
-}
-
-void STABuildCache802_11Header(struct rt_rtmp_adapter *pAd,
-			       struct rt_tx_blk *pTxBlk, u8 * pHeader)
-{
-	struct rt_mac_table_entry *pMacEntry;
-	struct rt_header_802_11 * pHeader80211;
-
-	pHeader80211 = (struct rt_header_802_11 *) pHeader;
-	pMacEntry = pTxBlk->pMacEntry;
-
-	/* */
-	/* Update the cached 802.11 HEADER */
-	/* */
-
-	/* normal wlan header size : 24 octets */
-	pTxBlk->MpduHeaderLen = sizeof(struct rt_header_802_11);
-
-	/* More Bit */
-	pHeader80211->FC.MoreData = TX_BLK_TEST_FLAG(pTxBlk, fTX_bMoreData);
-
-	/* Sequence */
-	pHeader80211->Sequence = pMacEntry->TxSeq[pTxBlk->UserPriority];
-	pMacEntry->TxSeq[pTxBlk->UserPriority] =
-	    (pMacEntry->TxSeq[pTxBlk->UserPriority] + 1) & MAXSEQ;
-
-	{
-		/* Check if the frame can be sent through DLS direct link interface */
-		/* If packet can be sent through DLS, then force aggregation disable. (Hard to determine peer STA's capability) */
-
-		/* The addr3 of normal packet send from DS is Dest Mac address. */
-		if (ADHOC_ON(pAd))
-			COPY_MAC_ADDR(pHeader80211->Addr3,
-				      pAd->CommonCfg.Bssid);
-		else
-			COPY_MAC_ADDR(pHeader80211->Addr3,
-				      pTxBlk->pSrcBufHeader);
-	}
-
-	/* ----------------------------------------------------------------- */
-	/* STEP 2. MAKE A COMMON 802.11 HEADER SHARED BY ENTIRE FRAGMENT BURST. Fill sequence later. */
-	/* ----------------------------------------------------------------- */
-	if (pAd->CommonCfg.bAPSDForcePowerSave)
-		pHeader80211->FC.PwrMgmt = PWR_SAVE;
-	else
-		pHeader80211->FC.PwrMgmt = (pAd->StaCfg.Psm == PWR_SAVE);
-}
-
-static inline u8 *STA_Build_ARalink_Frame_Header(struct rt_rtmp_adapter *pAd,
-						    struct rt_tx_blk *pTxBlk)
-{
-	u8 *pHeaderBufPtr;
-	struct rt_header_802_11 *pHeader_802_11;
-	void *pNextPacket;
-	u32 nextBufLen;
-	struct rt_queue_entry *pQEntry;
-
-	STAFindCipherAlgorithm(pAd, pTxBlk);
-	STABuildCommon802_11Header(pAd, pTxBlk);
-
-	pHeaderBufPtr = &pTxBlk->HeaderBuf[TXINFO_SIZE + TXWI_SIZE];
-	pHeader_802_11 = (struct rt_header_802_11 *) pHeaderBufPtr;
-
-	/* steal "order" bit to mark "aggregation" */
-	pHeader_802_11->FC.Order = 1;
-
-	/* skip common header */
-	pHeaderBufPtr += pTxBlk->MpduHeaderLen;
-
-	if (TX_BLK_TEST_FLAG(pTxBlk, fTX_bWMM)) {
-		/* */
-		/* build QOS Control bytes */
-		/* */
-		*pHeaderBufPtr = (pTxBlk->UserPriority & 0x0F);
-
-		*(pHeaderBufPtr + 1) = 0;
-		pHeaderBufPtr += 2;
-		pTxBlk->MpduHeaderLen += 2;
-	}
-	/* padding at front of LLC header. LLC header should at 4-bytes alignment. */
-	pTxBlk->HdrPadLen = (unsigned long)pHeaderBufPtr;
-	pHeaderBufPtr = (u8 *)ROUND_UP(pHeaderBufPtr, 4);
-	pTxBlk->HdrPadLen = (unsigned long)(pHeaderBufPtr - pTxBlk->HdrPadLen);
-
-	/* For RA Aggregation, */
-	/* put the 2nd MSDU length(extra 2-byte field) after struct rt_qos_control in little endian format */
-	pQEntry = pTxBlk->TxPacketList.Head;
-	pNextPacket = QUEUE_ENTRY_TO_PACKET(pQEntry);
-	nextBufLen = GET_OS_PKT_LEN(pNextPacket);
-	if (RTMP_GET_PACKET_VLAN(pNextPacket))
-		nextBufLen -= LENGTH_802_1Q;
-
-	*pHeaderBufPtr = (u8)nextBufLen & 0xff;
-	*(pHeaderBufPtr + 1) = (u8)(nextBufLen >> 8);
-
-	pHeaderBufPtr += 2;
-	pTxBlk->MpduHeaderLen += 2;
-
-	return pHeaderBufPtr;
-
-}
-
-static inline u8 *STA_Build_AMSDU_Frame_Header(struct rt_rtmp_adapter *pAd,
-						  struct rt_tx_blk *pTxBlk)
-{
-	u8 *pHeaderBufPtr;	/*, pSaveBufPtr; */
-	struct rt_header_802_11 *pHeader_802_11;
-
-	STAFindCipherAlgorithm(pAd, pTxBlk);
-	STABuildCommon802_11Header(pAd, pTxBlk);
-
-	pHeaderBufPtr = &pTxBlk->HeaderBuf[TXINFO_SIZE + TXWI_SIZE];
-	pHeader_802_11 = (struct rt_header_802_11 *) pHeaderBufPtr;
-
-	/* skip common header */
-	pHeaderBufPtr += pTxBlk->MpduHeaderLen;
-
-	/* */
-	/* build QOS Control bytes */
-	/* */
-	*pHeaderBufPtr = (pTxBlk->UserPriority & 0x0F);
-
-	/* */
-	/* A-MSDU packet */
-	/* */
-	*pHeaderBufPtr |= 0x80;
-
-	*(pHeaderBufPtr + 1) = 0;
-	pHeaderBufPtr += 2;
-	pTxBlk->MpduHeaderLen += 2;
-
-	/*pSaveBufPtr = pHeaderBufPtr; */
-
-	/* */
-	/* padding at front of LLC header */
-	/* LLC header should locate at 4-octets aligment */
-	/* */
-	/* @@@ MpduHeaderLen excluding padding @@@ */
-	/* */
-	pTxBlk->HdrPadLen = (unsigned long)pHeaderBufPtr;
-	pHeaderBufPtr = (u8 *)ROUND_UP(pHeaderBufPtr, 4);
-	pTxBlk->HdrPadLen = (unsigned long)(pHeaderBufPtr - pTxBlk->HdrPadLen);
-
-	return pHeaderBufPtr;
-
-}
-
-void STA_AMPDU_Frame_Tx(struct rt_rtmp_adapter *pAd, struct rt_tx_blk *pTxBlk)
-{
-	struct rt_header_802_11 *pHeader_802_11;
-	u8 *pHeaderBufPtr;
-	u16 FreeNumber;
-	struct rt_mac_table_entry *pMacEntry;
-	BOOLEAN bVLANPkt;
-	struct rt_queue_entry *pQEntry;
-
-	ASSERT(pTxBlk);
-
-	while (pTxBlk->TxPacketList.Head) {
-		pQEntry = RemoveHeadQueue(&pTxBlk->TxPacketList);
-		pTxBlk->pPacket = QUEUE_ENTRY_TO_PACKET(pQEntry);
-		if (RTMP_FillTxBlkInfo(pAd, pTxBlk) != TRUE) {
-			RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket,
-					    NDIS_STATUS_FAILURE);
-			continue;
-		}
-
-		bVLANPkt =
-		    (RTMP_GET_PACKET_VLAN(pTxBlk->pPacket) ? TRUE : FALSE);
-
-		pMacEntry = pTxBlk->pMacEntry;
-		if (pMacEntry->isCached) {
-			/* NOTE: Please make sure the size of pMacEntry->CachedBuf[] is smaller than pTxBlk->HeaderBuf[]! */
-			NdisMoveMemory((u8 *)& pTxBlk->
-				       HeaderBuf[TXINFO_SIZE],
-				       (u8 *)& pMacEntry->CachedBuf[0],
-				       TXWI_SIZE + sizeof(struct rt_header_802_11));
-			pHeaderBufPtr =
-			    (u8 *)(&pTxBlk->
-				      HeaderBuf[TXINFO_SIZE + TXWI_SIZE]);
-			STABuildCache802_11Header(pAd, pTxBlk, pHeaderBufPtr);
-		} else {
-			STAFindCipherAlgorithm(pAd, pTxBlk);
-			STABuildCommon802_11Header(pAd, pTxBlk);
-
-			pHeaderBufPtr =
-			    &pTxBlk->HeaderBuf[TXINFO_SIZE + TXWI_SIZE];
-		}
-
-		pHeader_802_11 = (struct rt_header_802_11 *) pHeaderBufPtr;
-
-		/* skip common header */
-		pHeaderBufPtr += pTxBlk->MpduHeaderLen;
-
-		/* */
-		/* build QOS Control bytes */
-		/* */
-		*pHeaderBufPtr = (pTxBlk->UserPriority & 0x0F);
-		*(pHeaderBufPtr + 1) = 0;
-		pHeaderBufPtr += 2;
-		pTxBlk->MpduHeaderLen += 2;
-
-		/* */
-		/* build HTC+ */
-		/* HTC control filed following QoS field */
-		/* */
-		if ((pAd->CommonCfg.bRdg == TRUE)
-		    && CLIENT_STATUS_TEST_FLAG(pTxBlk->pMacEntry,
-					       fCLIENT_STATUS_RDG_CAPABLE)) {
-			if (pMacEntry->isCached == FALSE) {
-				/* mark HTC bit */
-				pHeader_802_11->FC.Order = 1;
-
-				NdisZeroMemory(pHeaderBufPtr, 4);
-				*(pHeaderBufPtr + 3) |= 0x80;
-			}
-			pHeaderBufPtr += 4;
-			pTxBlk->MpduHeaderLen += 4;
-		}
-		/*pTxBlk->MpduHeaderLen = pHeaderBufPtr - pTxBlk->HeaderBuf - TXWI_SIZE - TXINFO_SIZE; */
-		ASSERT(pTxBlk->MpduHeaderLen >= 24);
-
-		/* skip 802.3 header */
-		pTxBlk->pSrcBufData = pTxBlk->pSrcBufHeader + LENGTH_802_3;
-		pTxBlk->SrcBufLen -= LENGTH_802_3;
-
-		/* skip vlan tag */
-		if (bVLANPkt) {
-			pTxBlk->pSrcBufData += LENGTH_802_1Q;
-			pTxBlk->SrcBufLen -= LENGTH_802_1Q;
-		}
-		/* */
-		/* padding at front of LLC header */
-		/* LLC header should locate at 4-octets aligment */
-		/* */
-		/* @@@ MpduHeaderLen excluding padding @@@ */
-		/* */
-		pTxBlk->HdrPadLen = (unsigned long)pHeaderBufPtr;
-		pHeaderBufPtr = (u8 *)ROUND_UP(pHeaderBufPtr, 4);
-		pTxBlk->HdrPadLen = (unsigned long)(pHeaderBufPtr - pTxBlk->HdrPadLen);
-
-		{
-
-			/* */
-			/* Insert LLC-SNAP encapsulation - 8 octets */
-			/* */
-			EXTRA_LLCSNAP_ENCAP_FROM_PKT_OFFSET(pTxBlk->
-							    pSrcBufData - 2,
-							    pTxBlk->
-							    pExtraLlcSnapEncap);
-			if (pTxBlk->pExtraLlcSnapEncap) {
-				NdisMoveMemory(pHeaderBufPtr,
-					       pTxBlk->pExtraLlcSnapEncap, 6);
-				pHeaderBufPtr += 6;
-				/* get 2 octets (TypeofLen) */
-				NdisMoveMemory(pHeaderBufPtr,
-					       pTxBlk->pSrcBufData - 2, 2);
-				pHeaderBufPtr += 2;
-				pTxBlk->MpduHeaderLen += LENGTH_802_1_H;
-			}
-
-		}
-
-		if (pMacEntry->isCached) {
-			RTMPWriteTxWI_Cache(pAd,
-					    (struct rt_txwi *) (&pTxBlk->
-							   HeaderBuf
-							   [TXINFO_SIZE]),
-					    pTxBlk);
-		} else {
-			RTMPWriteTxWI_Data(pAd,
-					   (struct rt_txwi *) (&pTxBlk->
-							  HeaderBuf
-							  [TXINFO_SIZE]),
-					   pTxBlk);
-
-			NdisZeroMemory((u8 *)(&pMacEntry->CachedBuf[0]),
-				       sizeof(pMacEntry->CachedBuf));
-			NdisMoveMemory((u8 *)(&pMacEntry->CachedBuf[0]),
-				       (u8 *)(&pTxBlk->
-						 HeaderBuf[TXINFO_SIZE]),
-				       (pHeaderBufPtr -
-					(u8 *)(&pTxBlk->
-						  HeaderBuf[TXINFO_SIZE])));
-			pMacEntry->isCached = TRUE;
-		}
-
-		/* calculate Transmitted AMPDU count and ByteCount */
-		{
-			pAd->RalinkCounters.TransmittedMPDUsInAMPDUCount.u.
-			    LowPart++;
-			pAd->RalinkCounters.TransmittedOctetsInAMPDUCount.
-			    QuadPart += pTxBlk->SrcBufLen;
-		}
-
-		/*FreeNumber = GET_TXRING_FREENO(pAd, QueIdx); */
-
-		HAL_WriteTxResource(pAd, pTxBlk, TRUE, &FreeNumber);
-
-		/* */
-		/* Kick out Tx */
-		/* */
-		if (!RTMP_TEST_PSFLAG(pAd, fRTMP_PS_DISABLE_TX))
-			HAL_KickOutTx(pAd, pTxBlk, pTxBlk->QueIdx);
-
-		pAd->RalinkCounters.KickTxCount++;
-		pAd->RalinkCounters.OneSecTxDoneCount++;
-	}
-
-}
-
-void STA_AMSDU_Frame_Tx(struct rt_rtmp_adapter *pAd, struct rt_tx_blk *pTxBlk)
-{
-	u8 *pHeaderBufPtr;
-	u16 FreeNumber;
-	u16 subFramePayloadLen = 0;	/* AMSDU Subframe length without AMSDU-Header / Padding. */
-	u16 totalMPDUSize = 0;
-	u8 *subFrameHeader;
-	u8 padding = 0;
-	u16 FirstTx = 0, LastTxIdx = 0;
-	BOOLEAN bVLANPkt;
-	int frameNum = 0;
-	struct rt_queue_entry *pQEntry;
-
-	ASSERT(pTxBlk);
-
-	ASSERT((pTxBlk->TxPacketList.Number > 1));
-
-	while (pTxBlk->TxPacketList.Head) {
-		pQEntry = RemoveHeadQueue(&pTxBlk->TxPacketList);
-		pTxBlk->pPacket = QUEUE_ENTRY_TO_PACKET(pQEntry);
-		if (RTMP_FillTxBlkInfo(pAd, pTxBlk) != TRUE) {
-			RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket,
-					    NDIS_STATUS_FAILURE);
-			continue;
-		}
-
-		bVLANPkt =
-		    (RTMP_GET_PACKET_VLAN(pTxBlk->pPacket) ? TRUE : FALSE);
-
-		/* skip 802.3 header */
-		pTxBlk->pSrcBufData = pTxBlk->pSrcBufHeader + LENGTH_802_3;
-		pTxBlk->SrcBufLen -= LENGTH_802_3;
-
-		/* skip vlan tag */
-		if (bVLANPkt) {
-			pTxBlk->pSrcBufData += LENGTH_802_1Q;
-			pTxBlk->SrcBufLen -= LENGTH_802_1Q;
-		}
-
-		if (frameNum == 0) {
-			pHeaderBufPtr =
-			    STA_Build_AMSDU_Frame_Header(pAd, pTxBlk);
-
-			/* NOTE: TxWI->MPDUtotalByteCount will be updated after final frame was handled. */
-			RTMPWriteTxWI_Data(pAd,
-					   (struct rt_txwi *) (&pTxBlk->
-							  HeaderBuf
-							  [TXINFO_SIZE]),
-					   pTxBlk);
-		} else {
-			pHeaderBufPtr = &pTxBlk->HeaderBuf[0];
-			padding =
-			    ROUND_UP(LENGTH_AMSDU_SUBFRAMEHEAD +
-				     subFramePayloadLen,
-				     4) - (LENGTH_AMSDU_SUBFRAMEHEAD +
-					   subFramePayloadLen);
-			NdisZeroMemory(pHeaderBufPtr,
-				       padding + LENGTH_AMSDU_SUBFRAMEHEAD);
-			pHeaderBufPtr += padding;
-			pTxBlk->MpduHeaderLen = padding;
-		}
-
-		/* */
-		/* A-MSDU subframe */
-		/*   DA(6)+SA(6)+Length(2) + LLC/SNAP Encap */
-		/* */
-		subFrameHeader = pHeaderBufPtr;
-		subFramePayloadLen = pTxBlk->SrcBufLen;
-
-		NdisMoveMemory(subFrameHeader, pTxBlk->pSrcBufHeader, 12);
-
-		pHeaderBufPtr += LENGTH_AMSDU_SUBFRAMEHEAD;
-		pTxBlk->MpduHeaderLen += LENGTH_AMSDU_SUBFRAMEHEAD;
-
-		/* */
-		/* Insert LLC-SNAP encapsulation - 8 octets */
-		/* */
-		EXTRA_LLCSNAP_ENCAP_FROM_PKT_OFFSET(pTxBlk->pSrcBufData - 2,
-						    pTxBlk->pExtraLlcSnapEncap);
-
-		subFramePayloadLen = pTxBlk->SrcBufLen;
-
-		if (pTxBlk->pExtraLlcSnapEncap) {
-			NdisMoveMemory(pHeaderBufPtr,
-				       pTxBlk->pExtraLlcSnapEncap, 6);
-			pHeaderBufPtr += 6;
-			/* get 2 octets (TypeofLen) */
-			NdisMoveMemory(pHeaderBufPtr, pTxBlk->pSrcBufData - 2,
-				       2);
-			pHeaderBufPtr += 2;
-			pTxBlk->MpduHeaderLen += LENGTH_802_1_H;
-			subFramePayloadLen += LENGTH_802_1_H;
-		}
-		/* update subFrame Length field */
-		subFrameHeader[12] = (subFramePayloadLen & 0xFF00) >> 8;
-		subFrameHeader[13] = subFramePayloadLen & 0xFF;
-
-		totalMPDUSize += pTxBlk->MpduHeaderLen + pTxBlk->SrcBufLen;
-
-		if (frameNum == 0)
-			FirstTx =
-			    HAL_WriteMultiTxResource(pAd, pTxBlk, frameNum,
-						     &FreeNumber);
-		else
-			LastTxIdx =
-			    HAL_WriteMultiTxResource(pAd, pTxBlk, frameNum,
-						     &FreeNumber);
-
-		frameNum++;
-
-		pAd->RalinkCounters.KickTxCount++;
-		pAd->RalinkCounters.OneSecTxDoneCount++;
-
-		/* calculate Transmitted AMSDU Count and ByteCount */
-		{
-			pAd->RalinkCounters.TransmittedAMSDUCount.u.LowPart++;
-			pAd->RalinkCounters.TransmittedOctetsInAMSDU.QuadPart +=
-			    totalMPDUSize;
-		}
-
-	}
-
-	HAL_FinalWriteTxResource(pAd, pTxBlk, totalMPDUSize, FirstTx);
-	HAL_LastTxIdx(pAd, pTxBlk->QueIdx, LastTxIdx);
-
-	/* */
-	/* Kick out Tx */
-	/* */
-	if (!RTMP_TEST_PSFLAG(pAd, fRTMP_PS_DISABLE_TX))
-		HAL_KickOutTx(pAd, pTxBlk, pTxBlk->QueIdx);
-}
-
-void STA_Legacy_Frame_Tx(struct rt_rtmp_adapter *pAd, struct rt_tx_blk *pTxBlk)
-{
-	struct rt_header_802_11 *pHeader_802_11;
-	u8 *pHeaderBufPtr;
-	u16 FreeNumber;
-	BOOLEAN bVLANPkt;
-	struct rt_queue_entry *pQEntry;
-
-	ASSERT(pTxBlk);
-
-	pQEntry = RemoveHeadQueue(&pTxBlk->TxPacketList);
-	pTxBlk->pPacket = QUEUE_ENTRY_TO_PACKET(pQEntry);
-	if (RTMP_FillTxBlkInfo(pAd, pTxBlk) != TRUE) {
-		RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket, NDIS_STATUS_FAILURE);
-		return;
-	}
-
-	if (pTxBlk->TxFrameType == TX_MCAST_FRAME) {
-		INC_COUNTER64(pAd->WlanCounters.MulticastTransmittedFrameCount);
-	}
-
-	if (RTMP_GET_PACKET_RTS(pTxBlk->pPacket))
-		TX_BLK_SET_FLAG(pTxBlk, fTX_bRtsRequired);
-	else
-		TX_BLK_CLEAR_FLAG(pTxBlk, fTX_bRtsRequired);
-
-	bVLANPkt = (RTMP_GET_PACKET_VLAN(pTxBlk->pPacket) ? TRUE : FALSE);
-
-	if (pTxBlk->TxRate < pAd->CommonCfg.MinTxRate)
-		pTxBlk->TxRate = pAd->CommonCfg.MinTxRate;
-
-	STAFindCipherAlgorithm(pAd, pTxBlk);
-	STABuildCommon802_11Header(pAd, pTxBlk);
-
-	/* skip 802.3 header */
-	pTxBlk->pSrcBufData = pTxBlk->pSrcBufHeader + LENGTH_802_3;
-	pTxBlk->SrcBufLen -= LENGTH_802_3;
-
-	/* skip vlan tag */
-	if (bVLANPkt) {
-		pTxBlk->pSrcBufData += LENGTH_802_1Q;
-		pTxBlk->SrcBufLen -= LENGTH_802_1Q;
-	}
-
-	pHeaderBufPtr = &pTxBlk->HeaderBuf[TXINFO_SIZE + TXWI_SIZE];
-	pHeader_802_11 = (struct rt_header_802_11 *) pHeaderBufPtr;
-
-	/* skip common header */
-	pHeaderBufPtr += pTxBlk->MpduHeaderLen;
-
-	if (TX_BLK_TEST_FLAG(pTxBlk, fTX_bWMM)) {
-		/* */
-		/* build QOS Control bytes */
-		/* */
-		*(pHeaderBufPtr) =
-		    ((pTxBlk->UserPriority & 0x0F) | (pAd->CommonCfg.
-						      AckPolicy[pTxBlk->
-								QueIdx] << 5));
-		*(pHeaderBufPtr + 1) = 0;
-		pHeaderBufPtr += 2;
-		pTxBlk->MpduHeaderLen += 2;
-	}
-	/* The remaining content of MPDU header should locate at 4-octets alignment */
-	pTxBlk->HdrPadLen = (unsigned long)pHeaderBufPtr;
-	pHeaderBufPtr = (u8 *)ROUND_UP(pHeaderBufPtr, 4);
-	pTxBlk->HdrPadLen = (unsigned long)(pHeaderBufPtr - pTxBlk->HdrPadLen);
-
-	{
-
-		/* */
-		/* Insert LLC-SNAP encapsulation - 8 octets */
-		/* */
-		/* */
-		/* if original Ethernet frame contains no LLC/SNAP, */
-		/* then an extra LLC/SNAP encap is required */
-		/* */
-		EXTRA_LLCSNAP_ENCAP_FROM_PKT_START(pTxBlk->pSrcBufHeader,
-						   pTxBlk->pExtraLlcSnapEncap);
-		if (pTxBlk->pExtraLlcSnapEncap) {
-			u8 vlan_size;
-
-			NdisMoveMemory(pHeaderBufPtr,
-				       pTxBlk->pExtraLlcSnapEncap, 6);
-			pHeaderBufPtr += 6;
-			/* skip vlan tag */
-			vlan_size = (bVLANPkt) ? LENGTH_802_1Q : 0;
-			/* get 2 octets (TypeofLen) */
-			NdisMoveMemory(pHeaderBufPtr,
-				       pTxBlk->pSrcBufHeader + 12 + vlan_size,
-				       2);
-			pHeaderBufPtr += 2;
-			pTxBlk->MpduHeaderLen += LENGTH_802_1_H;
-		}
-
-	}
-
-	/* */
-	/* prepare for TXWI */
-	/* use Wcid as Key Index */
-	/* */
-
-	RTMPWriteTxWI_Data(pAd, (struct rt_txwi *) (&pTxBlk->HeaderBuf[TXINFO_SIZE]),
-			   pTxBlk);
-
-	/*FreeNumber = GET_TXRING_FREENO(pAd, QueIdx); */
-
-	HAL_WriteTxResource(pAd, pTxBlk, TRUE, &FreeNumber);
-
-	pAd->RalinkCounters.KickTxCount++;
-	pAd->RalinkCounters.OneSecTxDoneCount++;
-
-	/* */
-	/* Kick out Tx */
-	/* */
-	if (!RTMP_TEST_PSFLAG(pAd, fRTMP_PS_DISABLE_TX))
-		HAL_KickOutTx(pAd, pTxBlk, pTxBlk->QueIdx);
-}
-
-void STA_ARalink_Frame_Tx(struct rt_rtmp_adapter *pAd, struct rt_tx_blk *pTxBlk)
-{
-	u8 *pHeaderBufPtr;
-	u16 FreeNumber;
-	u16 totalMPDUSize = 0;
-	u16 FirstTx, LastTxIdx;
-	int frameNum = 0;
-	BOOLEAN bVLANPkt;
-	struct rt_queue_entry *pQEntry;
-
-	ASSERT(pTxBlk);
-
-	ASSERT((pTxBlk->TxPacketList.Number == 2));
-
-	FirstTx = LastTxIdx = 0;	/* Is it ok init they as 0? */
-	while (pTxBlk->TxPacketList.Head) {
-		pQEntry = RemoveHeadQueue(&pTxBlk->TxPacketList);
-		pTxBlk->pPacket = QUEUE_ENTRY_TO_PACKET(pQEntry);
-
-		if (RTMP_FillTxBlkInfo(pAd, pTxBlk) != TRUE) {
-			RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket,
-					    NDIS_STATUS_FAILURE);
-			continue;
-		}
-
-		bVLANPkt =
-		    (RTMP_GET_PACKET_VLAN(pTxBlk->pPacket) ? TRUE : FALSE);
-
-		/* skip 802.3 header */
-		pTxBlk->pSrcBufData = pTxBlk->pSrcBufHeader + LENGTH_802_3;
-		pTxBlk->SrcBufLen -= LENGTH_802_3;
-
-		/* skip vlan tag */
-		if (bVLANPkt) {
-			pTxBlk->pSrcBufData += LENGTH_802_1Q;
-			pTxBlk->SrcBufLen -= LENGTH_802_1Q;
-		}
-
-		if (frameNum == 0) {	/* For first frame, we need to create the 802.11 header + padding(optional) + RA-AGG-LEN + SNAP Header */
-
-			pHeaderBufPtr =
-			    STA_Build_ARalink_Frame_Header(pAd, pTxBlk);
-
-			/* It's ok write the TxWI here, because the TxWI->MPDUtotalByteCount */
-			/* will be updated after final frame was handled. */
-			RTMPWriteTxWI_Data(pAd,
-					   (struct rt_txwi *) (&pTxBlk->
-							  HeaderBuf
-							  [TXINFO_SIZE]),
-					   pTxBlk);
-
-			/* */
-			/* Insert LLC-SNAP encapsulation - 8 octets */
-			/* */
-			EXTRA_LLCSNAP_ENCAP_FROM_PKT_OFFSET(pTxBlk->
-							    pSrcBufData - 2,
-							    pTxBlk->
-							    pExtraLlcSnapEncap);
-
-			if (pTxBlk->pExtraLlcSnapEncap) {
-				NdisMoveMemory(pHeaderBufPtr,
-					       pTxBlk->pExtraLlcSnapEncap, 6);
-				pHeaderBufPtr += 6;
-				/* get 2 octets (TypeofLen) */
-				NdisMoveMemory(pHeaderBufPtr,
-					       pTxBlk->pSrcBufData - 2, 2);
-				pHeaderBufPtr += 2;
-				pTxBlk->MpduHeaderLen += LENGTH_802_1_H;
-			}
-		} else {	/* For second aggregated frame, we need create the 802.3 header to headerBuf, because PCI will copy it to SDPtr0. */
-
-			pHeaderBufPtr = &pTxBlk->HeaderBuf[0];
-			pTxBlk->MpduHeaderLen = 0;
-
-			/* A-Ralink sub-sequent frame header is the same as 802.3 header. */
-			/*   DA(6)+SA(6)+FrameType(2) */
-			NdisMoveMemory(pHeaderBufPtr, pTxBlk->pSrcBufHeader,
-				       12);
-			pHeaderBufPtr += 12;
-			/* get 2 octets (TypeofLen) */
-			NdisMoveMemory(pHeaderBufPtr, pTxBlk->pSrcBufData - 2,
-				       2);
-			pHeaderBufPtr += 2;
-			pTxBlk->MpduHeaderLen = LENGTH_ARALINK_SUBFRAMEHEAD;
-		}
-
-		totalMPDUSize += pTxBlk->MpduHeaderLen + pTxBlk->SrcBufLen;
-
-		/*FreeNumber = GET_TXRING_FREENO(pAd, QueIdx); */
-		if (frameNum == 0)
-			FirstTx =
-			    HAL_WriteMultiTxResource(pAd, pTxBlk, frameNum,
-						     &FreeNumber);
-		else
-			LastTxIdx =
-			    HAL_WriteMultiTxResource(pAd, pTxBlk, frameNum,
-						     &FreeNumber);
-
-		frameNum++;
-
-		pAd->RalinkCounters.OneSecTxAggregationCount++;
-		pAd->RalinkCounters.KickTxCount++;
-		pAd->RalinkCounters.OneSecTxDoneCount++;
-
-	}
-
-	HAL_FinalWriteTxResource(pAd, pTxBlk, totalMPDUSize, FirstTx);
-	HAL_LastTxIdx(pAd, pTxBlk->QueIdx, LastTxIdx);
-
-	/* */
-	/* Kick out Tx */
-	/* */
-	if (!RTMP_TEST_PSFLAG(pAd, fRTMP_PS_DISABLE_TX))
-		HAL_KickOutTx(pAd, pTxBlk, pTxBlk->QueIdx);
-
-}
-
-void STA_Fragment_Frame_Tx(struct rt_rtmp_adapter *pAd, struct rt_tx_blk *pTxBlk)
-{
-	struct rt_header_802_11 *pHeader_802_11;
-	u8 *pHeaderBufPtr;
-	u16 FreeNumber;
-	u8 fragNum = 0;
-	struct rt_packet_info PacketInfo;
-	u16 EncryptionOverhead = 0;
-	u32 FreeMpduSize, SrcRemainingBytes;
-	u16 AckDuration;
-	u32 NextMpduSize;
-	BOOLEAN bVLANPkt;
-	struct rt_queue_entry *pQEntry;
-	HTTRANSMIT_SETTING *pTransmit;
-
-	ASSERT(pTxBlk);
-
-	pQEntry = RemoveHeadQueue(&pTxBlk->TxPacketList);
-	pTxBlk->pPacket = QUEUE_ENTRY_TO_PACKET(pQEntry);
-	if (RTMP_FillTxBlkInfo(pAd, pTxBlk) != TRUE) {
-		RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket, NDIS_STATUS_FAILURE);
-		return;
-	}
-
-	ASSERT(TX_BLK_TEST_FLAG(pTxBlk, fTX_bAllowFrag));
-	bVLANPkt = (RTMP_GET_PACKET_VLAN(pTxBlk->pPacket) ? TRUE : FALSE);
-
-	STAFindCipherAlgorithm(pAd, pTxBlk);
-	STABuildCommon802_11Header(pAd, pTxBlk);
-
-	if (pTxBlk->CipherAlg == CIPHER_TKIP) {
-		pTxBlk->pPacket =
-		    duplicate_pkt_with_TKIP_MIC(pAd, pTxBlk->pPacket);
-		if (pTxBlk->pPacket == NULL)
-			return;
-		RTMP_QueryPacketInfo(pTxBlk->pPacket, &PacketInfo,
-				     &pTxBlk->pSrcBufHeader,
-				     &pTxBlk->SrcBufLen);
-	}
-	/* skip 802.3 header */
-	pTxBlk->pSrcBufData = pTxBlk->pSrcBufHeader + LENGTH_802_3;
-	pTxBlk->SrcBufLen -= LENGTH_802_3;
-
-	/* skip vlan tag */
-	if (bVLANPkt) {
-		pTxBlk->pSrcBufData += LENGTH_802_1Q;
-		pTxBlk->SrcBufLen -= LENGTH_802_1Q;
-	}
-
-	pHeaderBufPtr = &pTxBlk->HeaderBuf[TXINFO_SIZE + TXWI_SIZE];
-	pHeader_802_11 = (struct rt_header_802_11 *) pHeaderBufPtr;
-
-	/* skip common header */
-	pHeaderBufPtr += pTxBlk->MpduHeaderLen;
-
-	if (TX_BLK_TEST_FLAG(pTxBlk, fTX_bWMM)) {
-		/* */
-		/* build QOS Control bytes */
-		/* */
-		*pHeaderBufPtr = (pTxBlk->UserPriority & 0x0F);
-
-		*(pHeaderBufPtr + 1) = 0;
-		pHeaderBufPtr += 2;
-		pTxBlk->MpduHeaderLen += 2;
-	}
-	/* */
-	/* padding at front of LLC header */
-	/* LLC header should locate at 4-octets aligment */
-	/* */
-	pTxBlk->HdrPadLen = (unsigned long)pHeaderBufPtr;
-	pHeaderBufPtr = (u8 *)ROUND_UP(pHeaderBufPtr, 4);
-	pTxBlk->HdrPadLen = (unsigned long)(pHeaderBufPtr - pTxBlk->HdrPadLen);
-
-	/* */
-	/* Insert LLC-SNAP encapsulation - 8 octets */
-	/* */
-	/* */
-	/* if original Ethernet frame contains no LLC/SNAP, */
-	/* then an extra LLC/SNAP encap is required */
-	/* */
-	EXTRA_LLCSNAP_ENCAP_FROM_PKT_START(pTxBlk->pSrcBufHeader,
-					   pTxBlk->pExtraLlcSnapEncap);
-	if (pTxBlk->pExtraLlcSnapEncap) {
-		u8 vlan_size;
-
-		NdisMoveMemory(pHeaderBufPtr, pTxBlk->pExtraLlcSnapEncap, 6);
-		pHeaderBufPtr += 6;
-		/* skip vlan tag */
-		vlan_size = (bVLANPkt) ? LENGTH_802_1Q : 0;
-		/* get 2 octets (TypeofLen) */
-		NdisMoveMemory(pHeaderBufPtr,
-			       pTxBlk->pSrcBufHeader + 12 + vlan_size, 2);
-		pHeaderBufPtr += 2;
-		pTxBlk->MpduHeaderLen += LENGTH_802_1_H;
-	}
-
-	/* If TKIP is used and fragmentation is required. Driver has to */
-	/*      append TKIP MIC at tail of the scatter buffer */
-	/*      MAC ASIC will only perform IV/EIV/ICV insertion but no TKIP MIC */
-	if (pTxBlk->CipherAlg == CIPHER_TKIP) {
-		RTMPCalculateMICValue(pAd, pTxBlk->pPacket,
-				      pTxBlk->pExtraLlcSnapEncap, pTxBlk->pKey,
-				      0);
-
-		/* NOTE: DON'T refer the skb->len directly after following copy. Because the length is not adjusted */
-		/*                      to correct length, refer to pTxBlk->SrcBufLen for the packet length in following progress. */
-		NdisMoveMemory(pTxBlk->pSrcBufData + pTxBlk->SrcBufLen,
-			       &pAd->PrivateInfo.Tx.MIC[0], 8);
-		/*skb_put((RTPKT_TO_OSPKT(pTxBlk->pPacket))->tail, 8); */
-		pTxBlk->SrcBufLen += 8;
-		pTxBlk->TotalFrameLen += 8;
-		pTxBlk->CipherAlg = CIPHER_TKIP_NO_MIC;
-	}
-	/* */
-	/* calculate the overhead bytes that encryption algorithm may add. This */
-	/* affects the calculate of "duration" field */
-	/* */
-	if ((pTxBlk->CipherAlg == CIPHER_WEP64)
-	    || (pTxBlk->CipherAlg == CIPHER_WEP128))
-		EncryptionOverhead = 8;	/*WEP: IV[4] + ICV[4]; */
-	else if (pTxBlk->CipherAlg == CIPHER_TKIP_NO_MIC)
-		EncryptionOverhead = 12;	/*TKIP: IV[4] + EIV[4] + ICV[4], MIC will be added to TotalPacketLength */
-	else if (pTxBlk->CipherAlg == CIPHER_TKIP)
-		EncryptionOverhead = 20;	/*TKIP: IV[4] + EIV[4] + ICV[4] + MIC[8] */
-	else if (pTxBlk->CipherAlg == CIPHER_AES)
-		EncryptionOverhead = 16;	/* AES: IV[4] + EIV[4] + MIC[8] */
-	else
-		EncryptionOverhead = 0;
-
-	pTransmit = pTxBlk->pTransmit;
-	/* Decide the TX rate */
-	if (pTransmit->field.MODE == MODE_CCK)
-		pTxBlk->TxRate = pTransmit->field.MCS;
-	else if (pTransmit->field.MODE == MODE_OFDM)
-		pTxBlk->TxRate = pTransmit->field.MCS + RATE_FIRST_OFDM_RATE;
-	else
-		pTxBlk->TxRate = RATE_6_5;
-
-	/* decide how much time an ACK/CTS frame will consume in the air */
-	if (pTxBlk->TxRate <= RATE_LAST_OFDM_RATE)
-		AckDuration =
-		    RTMPCalcDuration(pAd,
-				     pAd->CommonCfg.ExpectedACKRate[pTxBlk->
-								    TxRate],
-				     14);
-	else
-		AckDuration = RTMPCalcDuration(pAd, RATE_6_5, 14);
-
-	/* Init the total payload length of this frame. */
-	SrcRemainingBytes = pTxBlk->SrcBufLen;
-
-	pTxBlk->TotalFragNum = 0xff;
-
-	do {
-
-		FreeMpduSize = pAd->CommonCfg.FragmentThreshold - LENGTH_CRC;
-
-		FreeMpduSize -= pTxBlk->MpduHeaderLen;
-
-		if (SrcRemainingBytes <= FreeMpduSize) {	/* this is the last or only fragment */
-
-			pTxBlk->SrcBufLen = SrcRemainingBytes;
-
-			pHeader_802_11->FC.MoreFrag = 0;
-			pHeader_802_11->Duration =
-			    pAd->CommonCfg.Dsifs + AckDuration;
-
-			/* Indicate the lower layer that this's the last fragment. */
-			pTxBlk->TotalFragNum = fragNum;
-		} else {	/* more fragment is required */
-
-			pTxBlk->SrcBufLen = FreeMpduSize;
-
-			NextMpduSize =
-			    min(((u32)SrcRemainingBytes - pTxBlk->SrcBufLen),
-				((u32)pAd->CommonCfg.FragmentThreshold));
-			pHeader_802_11->FC.MoreFrag = 1;
-			pHeader_802_11->Duration =
-			    (3 * pAd->CommonCfg.Dsifs) + (2 * AckDuration) +
-			    RTMPCalcDuration(pAd, pTxBlk->TxRate,
-					     NextMpduSize + EncryptionOverhead);
-		}
-
-		if (fragNum == 0)
-			pTxBlk->FrameGap = IFS_HTTXOP;
-		else
-			pTxBlk->FrameGap = IFS_SIFS;
-
-		RTMPWriteTxWI_Data(pAd,
-				   (struct rt_txwi *) (&pTxBlk->
-						  HeaderBuf[TXINFO_SIZE]),
-				   pTxBlk);
-
-		HAL_WriteFragTxResource(pAd, pTxBlk, fragNum, &FreeNumber);
-
-		pAd->RalinkCounters.KickTxCount++;
-		pAd->RalinkCounters.OneSecTxDoneCount++;
-
-		/* Update the frame number, remaining size of the NDIS packet payload. */
-
-		/* space for 802.11 header. */
-		if (fragNum == 0 && pTxBlk->pExtraLlcSnapEncap)
-			pTxBlk->MpduHeaderLen -= LENGTH_802_1_H;
-
-		fragNum++;
-		SrcRemainingBytes -= pTxBlk->SrcBufLen;
-		pTxBlk->pSrcBufData += pTxBlk->SrcBufLen;
-
-		pHeader_802_11->Frag++;	/* increase Frag # */
-
-	} while (SrcRemainingBytes > 0);
-
-	/* */
-	/* Kick out Tx */
-	/* */
-	if (!RTMP_TEST_PSFLAG(pAd, fRTMP_PS_DISABLE_TX))
-		HAL_KickOutTx(pAd, pTxBlk, pTxBlk->QueIdx);
-}
-
-#define RELEASE_FRAMES_OF_TXBLK(_pAd, _pTxBlk, _pQEntry, _Status) 										\
-		while(_pTxBlk->TxPacketList.Head)														\
-		{																						\
-			_pQEntry = RemoveHeadQueue(&_pTxBlk->TxPacketList);									\
-			RELEASE_NDIS_PACKET(_pAd, QUEUE_ENTRY_TO_PACKET(_pQEntry), _Status);	\
-		}
-
-/*
-	========================================================================
-
-	Routine Description:
-		Copy frame from waiting queue into relative ring buffer and set
-	appropriate ASIC register to kick hardware encryption before really
-	sent out to air.
-
-	Arguments:
-		pAd 	Pointer to our adapter
-		void *	Pointer to outgoing Ndis frame
-		NumberOfFrag	Number of fragment required
-
-	Return Value:
-		None
-
-	IRQL = DISPATCH_LEVEL
-
-	Note:
-
-	========================================================================
-*/
-int STAHardTransmit(struct rt_rtmp_adapter *pAd,
-			    struct rt_tx_blk *pTxBlk, u8 QueIdx)
-{
-	char *pPacket;
-	struct rt_queue_entry *pQEntry;
-
-	/* --------------------------------------------- */
-	/* STEP 0. DO SANITY CHECK AND SOME EARLY PREPARATION. */
-	/* --------------------------------------------- */
-	/* */
-	ASSERT(pTxBlk->TxPacketList.Number);
-	if (pTxBlk->TxPacketList.Head == NULL) {
-		DBGPRINT(RT_DEBUG_ERROR,
-			 ("pTxBlk->TotalFrameNum == %ld!\n",
-			  pTxBlk->TxPacketList.Number));
-		return NDIS_STATUS_FAILURE;
-	}
-
-	pPacket = QUEUE_ENTRY_TO_PACKET(pTxBlk->TxPacketList.Head);
-
-	/* ------------------------------------------------------------------ */
-	/* STEP 1. WAKE UP PHY */
-	/*              outgoing frame always wakeup PHY to prevent frame lost and */
-	/*              turn off PSM bit to improve performance */
-	/* ------------------------------------------------------------------ */
-	/* not to change PSM bit, just send this frame out? */
-	if ((pAd->StaCfg.Psm == PWR_SAVE)
-	    && OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE)) {
-		DBGPRINT_RAW(RT_DEBUG_INFO, ("AsicForceWakeup At HardTx\n"));
-#ifdef RTMP_MAC_PCI
-		AsicForceWakeup(pAd, TRUE);
-#endif /* RTMP_MAC_PCI // */
-#ifdef RTMP_MAC_USB
-		RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_FORCE_WAKE_UP, NULL, 0);
-#endif /* RTMP_MAC_USB // */
-	}
-	/* It should not change PSM bit, when APSD turn on. */
-	if ((!
-	     (pAd->CommonCfg.bAPSDCapable
-	      && pAd->CommonCfg.APEdcaParm.bAPSDCapable)
-	     && (pAd->CommonCfg.bAPSDForcePowerSave == FALSE))
-	    || (RTMP_GET_PACKET_EAPOL(pTxBlk->pPacket))
-	    || (RTMP_GET_PACKET_WAI(pTxBlk->pPacket))) {
-		if ((pAd->StaCfg.Psm == PWR_SAVE) &&
-		    (pAd->StaCfg.WindowsPowerMode ==
-		     Ndis802_11PowerModeFast_PSP))
-			RTMP_SET_PSM_BIT(pAd, PWR_ACTIVE);
-	}
-
-	switch (pTxBlk->TxFrameType) {
-	case TX_AMPDU_FRAME:
-		STA_AMPDU_Frame_Tx(pAd, pTxBlk);
-		break;
-	case TX_AMSDU_FRAME:
-		STA_AMSDU_Frame_Tx(pAd, pTxBlk);
-		break;
-	case TX_LEGACY_FRAME:
-		STA_Legacy_Frame_Tx(pAd, pTxBlk);
-		break;
-	case TX_MCAST_FRAME:
-		STA_Legacy_Frame_Tx(pAd, pTxBlk);
-		break;
-	case TX_RALINK_FRAME:
-		STA_ARalink_Frame_Tx(pAd, pTxBlk);
-		break;
-	case TX_FRAG_FRAME:
-		STA_Fragment_Frame_Tx(pAd, pTxBlk);
-		break;
-	default:
-		{
-			/* It should not happened! */
-			DBGPRINT(RT_DEBUG_ERROR,
-				 ("Send a packet was not classified! It should not happen!\n"));
-			while (pTxBlk->TxPacketList.Number) {
-				pQEntry =
-				    RemoveHeadQueue(&pTxBlk->TxPacketList);
-				pPacket = QUEUE_ENTRY_TO_PACKET(pQEntry);
-				if (pPacket)
-					RELEASE_NDIS_PACKET(pAd, pPacket,
-							    NDIS_STATUS_FAILURE);
-			}
-		}
-		break;
-	}
-
-	return (NDIS_STATUS_SUCCESS);
-
-}
-
-unsigned long HashBytesPolynomial(u8 * value, unsigned int len)
-{
-	unsigned char *word = value;
-	unsigned int ret = 0;
-	unsigned int i;
-
-	for (i = 0; i < len; i++) {
-		int mod = i % 32;
-		ret ^= (unsigned int)(word[i]) << mod;
-		ret ^= (unsigned int)(word[i]) >> (32 - mod);
-	}
-	return ret;
-}
-
-void Sta_Announce_or_Forward_802_3_Packet(struct rt_rtmp_adapter *pAd,
-					  void *pPacket,
-					  u8 FromWhichBSSID)
-{
-	if (TRUE) {
-		announce_802_3_packet(pAd, pPacket);
-	} else {
-		/* release packet */
-		RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
-	}
-}
diff -druN linux-2.6.39-libre/drivers/staging/rt2860/sta/sanity.c linux-3.0-rc7-libre/drivers/staging/rt2860/sta/sanity.c
--- linux-2.6.39-libre/drivers/staging/rt2860/sta/sanity.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rt2860/sta/sanity.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,362 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, 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.             *
- *                                                                       *
- *************************************************************************
-
-	Module Name:
-	sanity.c
-
-	Abstract:
-
-	Revision History:
-	Who			When			What
-	--------	----------		----------------------------------------------
-	John Chang  		2004-09-01      add WMM support
-	Justin P. Mattock	11/07/2010	Fix typos
-*/
-#include "../rt_config.h"
-
-extern u8 CISCO_OUI[];
-
-extern u8 WPA_OUI[];
-extern u8 RSN_OUI[];
-extern u8 WME_INFO_ELEM[];
-extern u8 WME_PARM_ELEM[];
-extern u8 Ccx2QosInfo[];
-extern u8 RALINK_OUI[];
-extern u8 BROADCOM_OUI[];
-
-/*
-    ==========================================================================
-    Description:
-        MLME message sanity check
-    Return:
-        TRUE if all parameters are OK, FALSE otherwise
-    ==========================================================================
- */
-BOOLEAN MlmeStartReqSanity(struct rt_rtmp_adapter *pAd,
-			   void * Msg,
-			   unsigned long MsgLen,
-			   char Ssid[], u8 * pSsidLen)
-{
-	struct rt_mlme_start_req *Info;
-
-	Info = (struct rt_mlme_start_req *)(Msg);
-
-	if (Info->SsidLen > MAX_LEN_OF_SSID) {
-		DBGPRINT(RT_DEBUG_TRACE,
-			 ("MlmeStartReqSanity fail - wrong SSID length\n"));
-		return FALSE;
-	}
-
-	*pSsidLen = Info->SsidLen;
-	NdisMoveMemory(Ssid, Info->Ssid, *pSsidLen);
-
-	return TRUE;
-}
-
-/*
-    ==========================================================================
-    Description:
-        MLME message sanity check
-    Return:
-        TRUE if all parameters are OK, FALSE otherwise
-
-    IRQL = DISPATCH_LEVEL
-
-    ==========================================================================
- */
-BOOLEAN PeerAssocRspSanity(struct rt_rtmp_adapter *pAd, void * pMsg, unsigned long MsgLen, u8 *pAddr2, u16 * pCapabilityInfo, u16 * pStatus, u16 * pAid, u8 SupRate[], u8 * pSupRateLen, u8 ExtRate[], u8 * pExtRateLen, struct rt_ht_capability_ie * pHtCapability, struct rt_add_ht_info_ie * pAddHtInfo,	/* AP might use this additional ht info IE */
-			   u8 * pHtCapabilityLen,
-			   u8 * pAddHtInfoLen,
-			   u8 * pNewExtChannelOffset,
-			   struct rt_edca_parm *pEdcaParm, u8 * pCkipFlag)
-{
-	char IeType, *Ptr;
-	struct rt_frame_802_11 * pFrame = (struct rt_frame_802_11 *) pMsg;
-	struct rt_eid * pEid;
-	unsigned long Length = 0;
-
-	*pNewExtChannelOffset = 0xff;
-	*pHtCapabilityLen = 0;
-	*pAddHtInfoLen = 0;
-	COPY_MAC_ADDR(pAddr2, pFrame->Hdr.Addr2);
-	Ptr = (char *)pFrame->Octet;
-	Length += LENGTH_802_11;
-
-	NdisMoveMemory(pCapabilityInfo, &pFrame->Octet[0], 2);
-	Length += 2;
-	NdisMoveMemory(pStatus, &pFrame->Octet[2], 2);
-	Length += 2;
-	*pCkipFlag = 0;
-	*pExtRateLen = 0;
-	pEdcaParm->bValid = FALSE;
-
-	if (*pStatus != MLME_SUCCESS)
-		return TRUE;
-
-	NdisMoveMemory(pAid, &pFrame->Octet[4], 2);
-	Length += 2;
-
-	/* Aid already swapped byte order in RTMPFrameEndianChange() for big endian platform */
-	*pAid = (*pAid) & 0x3fff;	/* AID is low 14-bit */
-
-	/* -- get supported rates from payload and advance the pointer */
-	IeType = pFrame->Octet[6];
-	*pSupRateLen = pFrame->Octet[7];
-	if ((IeType != IE_SUPP_RATES)
-	    || (*pSupRateLen > MAX_LEN_OF_SUPPORTED_RATES)) {
-		DBGPRINT(RT_DEBUG_TRACE,
-			 ("PeerAssocRspSanity fail - wrong SupportedRates IE\n"));
-		return FALSE;
-	} else
-		NdisMoveMemory(SupRate, &pFrame->Octet[8], *pSupRateLen);
-
-	Length = Length + 2 + *pSupRateLen;
-
-	/* many AP implement proprietary IEs in non-standard order, we'd better */
-	/* tolerate mis-ordered IEs to get best compatibility */
-	pEid = (struct rt_eid *) & pFrame->Octet[8 + (*pSupRateLen)];
-
-	/* get variable fields from payload and advance the pointer */
-	while ((Length + 2 + pEid->Len) <= MsgLen) {
-		switch (pEid->Eid) {
-		case IE_EXT_SUPP_RATES:
-			if (pEid->Len <= MAX_LEN_OF_SUPPORTED_RATES) {
-				NdisMoveMemory(ExtRate, pEid->Octet, pEid->Len);
-				*pExtRateLen = pEid->Len;
-			}
-			break;
-
-		case IE_HT_CAP:
-		case IE_HT_CAP2:
-			if (pEid->Len >= SIZE_HT_CAP_IE)	/*Note: allow extension! */
-			{
-				NdisMoveMemory(pHtCapability, pEid->Octet,
-					       SIZE_HT_CAP_IE);
-
-				*(u16 *) (&pHtCapability->HtCapInfo) =
-				    cpu2le16(*(u16 *)
-					     (&pHtCapability->HtCapInfo));
-				*(u16 *) (&pHtCapability->ExtHtCapInfo) =
-				    cpu2le16(*(u16 *)
-					     (&pHtCapability->ExtHtCapInfo));
-
-				*pHtCapabilityLen = SIZE_HT_CAP_IE;
-			} else {
-				DBGPRINT(RT_DEBUG_WARN,
-					 ("PeerAssocRspSanity - wrong IE_HT_CAP. \n"));
-			}
-
-			break;
-		case IE_ADD_HT:
-		case IE_ADD_HT2:
-			if (pEid->Len >= sizeof(struct rt_add_ht_info_ie)) {
-				/* This IE allows extension, but we can ignore extra bytes beyond our knowledge , so only */
-				/* copy first sizeof(struct rt_add_ht_info_ie) */
-				NdisMoveMemory(pAddHtInfo, pEid->Octet,
-					       sizeof(struct rt_add_ht_info_ie));
-
-				*(u16 *) (&pAddHtInfo->AddHtInfo2) =
-				    cpu2le16(*(u16 *)
-					     (&pAddHtInfo->AddHtInfo2));
-				*(u16 *) (&pAddHtInfo->AddHtInfo3) =
-				    cpu2le16(*(u16 *)
-					     (&pAddHtInfo->AddHtInfo3));
-
-				*pAddHtInfoLen = SIZE_ADD_HT_INFO_IE;
-			} else {
-				DBGPRINT(RT_DEBUG_WARN,
-					 ("PeerAssocRspSanity - wrong IE_ADD_HT. \n"));
-			}
-
-			break;
-		case IE_SECONDARY_CH_OFFSET:
-			if (pEid->Len == 1) {
-				*pNewExtChannelOffset = pEid->Octet[0];
-			} else {
-				DBGPRINT(RT_DEBUG_WARN,
-					 ("PeerAssocRspSanity - wrong IE_SECONDARY_CH_OFFSET. \n"));
-			}
-			break;
-
-		case IE_VENDOR_SPECIFIC:
-			/* handle WME PARAMTER ELEMENT */
-			if (NdisEqualMemory(pEid->Octet, WME_PARM_ELEM, 6)
-			    && (pEid->Len == 24)) {
-				u8 *ptr;
-				int i;
-
-				/* parsing EDCA parameters */
-				pEdcaParm->bValid = TRUE;
-				pEdcaParm->bQAck = FALSE;	/* pEid->Octet[0] & 0x10; */
-				pEdcaParm->bQueueRequest = FALSE;	/* pEid->Octet[0] & 0x20; */
-				pEdcaParm->bTxopRequest = FALSE;	/* pEid->Octet[0] & 0x40; */
-				/*pEdcaParm->bMoreDataAck    = FALSE; // pEid->Octet[0] & 0x80; */
-				pEdcaParm->EdcaUpdateCount =
-				    pEid->Octet[6] & 0x0f;
-				pEdcaParm->bAPSDCapable =
-				    (pEid->Octet[6] & 0x80) ? 1 : 0;
-				ptr = (u8 *)& pEid->Octet[8];
-				for (i = 0; i < 4; i++) {
-					u8 aci = (*ptr & 0x60) >> 5;	/* b5~6 is AC INDEX */
-					pEdcaParm->bACM[aci] = (((*ptr) & 0x10) == 0x10);	/* b5 is ACM */
-					pEdcaParm->Aifsn[aci] = (*ptr) & 0x0f;	/* b0~3 is AIFSN */
-					pEdcaParm->Cwmin[aci] = *(ptr + 1) & 0x0f;	/* b0~4 is Cwmin */
-					pEdcaParm->Cwmax[aci] = *(ptr + 1) >> 4;	/* b5~8 is Cwmax */
-					pEdcaParm->Txop[aci] = *(ptr + 2) + 256 * (*(ptr + 3));	/* in unit of 32-us */
-					ptr += 4;	/* point to next AC */
-				}
-			}
-			break;
-		default:
-			DBGPRINT(RT_DEBUG_TRACE,
-				 ("PeerAssocRspSanity - ignore unrecognized EID = %d\n",
-				  pEid->Eid));
-			break;
-		}
-
-		Length = Length + 2 + pEid->Len;
-		pEid = (struct rt_eid *) ((u8 *) pEid + 2 + pEid->Len);
-	}
-
-	return TRUE;
-}
-
-/*
-    ==========================================================================
-    Description:
-        MLME message sanity check
-    Return:
-        TRUE if all parameters are OK, FALSE otherwise
-
-	IRQL = DISPATCH_LEVEL
-
-    ==========================================================================
- */
-BOOLEAN PeerProbeReqSanity(struct rt_rtmp_adapter *pAd,
-			   void * Msg,
-			   unsigned long MsgLen,
-			   u8 *pAddr2,
-			   char Ssid[], u8 * pSsidLen)
-{
-	u8 Idx;
-	u8 RateLen;
-	char IeType;
-	struct rt_frame_802_11 * pFrame = (struct rt_frame_802_11 *) Msg;
-
-	COPY_MAC_ADDR(pAddr2, pFrame->Hdr.Addr2);
-
-	if ((pFrame->Octet[0] != IE_SSID)
-	    || (pFrame->Octet[1] > MAX_LEN_OF_SSID)) {
-		DBGPRINT(RT_DEBUG_TRACE,
-			 ("PeerProbeReqSanity fail - wrong SSID IE(Type=%d,Len=%d)\n",
-			  pFrame->Octet[0], pFrame->Octet[1]));
-		return FALSE;
-	}
-
-	*pSsidLen = pFrame->Octet[1];
-	NdisMoveMemory(Ssid, &pFrame->Octet[2], *pSsidLen);
-
-	Idx = *pSsidLen + 2;
-
-	/* -- get supported rates from payload and advance the pointer */
-	IeType = pFrame->Octet[Idx];
-	RateLen = pFrame->Octet[Idx + 1];
-	if (IeType != IE_SUPP_RATES) {
-		DBGPRINT(RT_DEBUG_TRACE,
-			 ("PeerProbeReqSanity fail - wrong SupportRates IE(Type=%d,Len=%d)\n",
-			  pFrame->Octet[Idx], pFrame->Octet[Idx + 1]));
-		return FALSE;
-	} else {
-		if ((pAd->CommonCfg.PhyMode == PHY_11G) && (RateLen < 8))
-			return (FALSE);
-	}
-
-	return TRUE;
-}
-
-/*
-    ==========================================================================
-    Description:
-
-	IRQL = DISPATCH_LEVEL
-
-    ==========================================================================
- */
-BOOLEAN GetTimBit(char * Ptr,
-		  u16 Aid,
-		  u8 * TimLen,
-		  u8 * BcastFlag,
-		  u8 * DtimCount,
-		  u8 * DtimPeriod, u8 * MessageToMe)
-{
-	u8 BitCntl, N1, N2, MyByte, MyBit;
-	char *IdxPtr;
-
-	IdxPtr = Ptr;
-
-	IdxPtr++;
-	*TimLen = *IdxPtr;
-
-	/* get DTIM Count from TIM element */
-	IdxPtr++;
-	*DtimCount = *IdxPtr;
-
-	/* get DTIM Period from TIM element */
-	IdxPtr++;
-	*DtimPeriod = *IdxPtr;
-
-	/* get Bitmap Control from TIM element */
-	IdxPtr++;
-	BitCntl = *IdxPtr;
-
-	if ((*DtimCount == 0) && (BitCntl & 0x01))
-		*BcastFlag = TRUE;
-	else
-		*BcastFlag = FALSE;
-
-	/* Parse Partial Virtual Bitmap from TIM element */
-	N1 = BitCntl & 0xfe;	/* N1 is the first bitmap byte# */
-	N2 = *TimLen - 4 + N1;	/* N2 is the last bitmap byte# */
-
-	if ((Aid < (N1 << 3)) || (Aid >= ((N2 + 1) << 3)))
-		*MessageToMe = FALSE;
-	else {
-		MyByte = (Aid >> 3) - N1;	/* my byte position in the bitmap byte-stream */
-		MyBit = Aid % 16 - ((MyByte & 0x01) ? 8 : 0);
-
-		IdxPtr += (MyByte + 1);
-
-		/*if (*IdxPtr) */
-		/*    DBGPRINT(RT_DEBUG_WARN, ("TIM bitmap = 0x%02x\n", *IdxPtr)); */
-
-		if (*IdxPtr & (0x01 << MyBit))
-			*MessageToMe = TRUE;
-		else
-			*MessageToMe = FALSE;
-	}
-
-	return TRUE;
-}
diff -druN linux-2.6.39-libre/drivers/staging/rt2860/sta/sync.c linux-3.0-rc7-libre/drivers/staging/rt2860/sta/sync.c
--- linux-2.6.39-libre/drivers/staging/rt2860/sta/sync.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rt2860/sta/sync.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,1968 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, 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.             *
- *                                                                       *
- *************************************************************************
-
-	Module Name:
-	sync.c
-
-	Abstract:
-
-	Revision History:
-	Who			When			What
-	--------	----------		----------------------------------------------
-	John Chang		2004-09-01      	modified for rt2561/2661
-	Jan Lee			2006-08-01      	modified for rt2860 for 802.11n
-	Justin P. Mattock	11/07/2010		Fix typos
-*/
-#include "../rt_config.h"
-
-#define ADHOC_ENTRY_BEACON_LOST_TIME	(2*OS_HZ)	/* 2 sec */
-
-/*
-	==========================================================================
-	Description:
-		The sync state machine,
-	Parameters:
-		Sm - pointer to the state machine
-	Note:
-		the state machine looks like the following
-
-	==========================================================================
- */
-void SyncStateMachineInit(struct rt_rtmp_adapter *pAd,
-			  struct rt_state_machine *Sm, OUT STATE_MACHINE_FUNC Trans[])
-{
-	StateMachineInit(Sm, Trans, MAX_SYNC_STATE, MAX_SYNC_MSG,
-			 (STATE_MACHINE_FUNC) Drop, SYNC_IDLE,
-			 SYNC_MACHINE_BASE);
-
-	/* column 1 */
-	StateMachineSetAction(Sm, SYNC_IDLE, MT2_MLME_SCAN_REQ,
-			      (STATE_MACHINE_FUNC) MlmeScanReqAction);
-	StateMachineSetAction(Sm, SYNC_IDLE, MT2_MLME_JOIN_REQ,
-			      (STATE_MACHINE_FUNC) MlmeJoinReqAction);
-	StateMachineSetAction(Sm, SYNC_IDLE, MT2_MLME_START_REQ,
-			      (STATE_MACHINE_FUNC) MlmeStartReqAction);
-	StateMachineSetAction(Sm, SYNC_IDLE, MT2_PEER_BEACON,
-			      (STATE_MACHINE_FUNC) PeerBeacon);
-	StateMachineSetAction(Sm, SYNC_IDLE, MT2_PEER_PROBE_REQ,
-			      (STATE_MACHINE_FUNC) PeerProbeReqAction);
-
-	/*column 2 */
-	StateMachineSetAction(Sm, JOIN_WAIT_BEACON, MT2_MLME_SCAN_REQ,
-			      (STATE_MACHINE_FUNC) InvalidStateWhenScan);
-	StateMachineSetAction(Sm, JOIN_WAIT_BEACON, MT2_MLME_JOIN_REQ,
-			      (STATE_MACHINE_FUNC) InvalidStateWhenJoin);
-	StateMachineSetAction(Sm, JOIN_WAIT_BEACON, MT2_MLME_START_REQ,
-			      (STATE_MACHINE_FUNC) InvalidStateWhenStart);
-	StateMachineSetAction(Sm, JOIN_WAIT_BEACON, MT2_PEER_BEACON,
-			      (STATE_MACHINE_FUNC) PeerBeaconAtJoinAction);
-	StateMachineSetAction(Sm, JOIN_WAIT_BEACON, MT2_BEACON_TIMEOUT,
-			      (STATE_MACHINE_FUNC) BeaconTimeoutAtJoinAction);
-
-	/* column 3 */
-	StateMachineSetAction(Sm, SCAN_LISTEN, MT2_MLME_SCAN_REQ,
-			      (STATE_MACHINE_FUNC) InvalidStateWhenScan);
-	StateMachineSetAction(Sm, SCAN_LISTEN, MT2_MLME_JOIN_REQ,
-			      (STATE_MACHINE_FUNC) InvalidStateWhenJoin);
-	StateMachineSetAction(Sm, SCAN_LISTEN, MT2_MLME_START_REQ,
-			      (STATE_MACHINE_FUNC) InvalidStateWhenStart);
-	StateMachineSetAction(Sm, SCAN_LISTEN, MT2_PEER_BEACON,
-			      (STATE_MACHINE_FUNC) PeerBeaconAtScanAction);
-	StateMachineSetAction(Sm, SCAN_LISTEN, MT2_PEER_PROBE_RSP,
-			      (STATE_MACHINE_FUNC) PeerBeaconAtScanAction);
-	StateMachineSetAction(Sm, SCAN_LISTEN, MT2_SCAN_TIMEOUT,
-			      (STATE_MACHINE_FUNC) ScanTimeoutAction);
-
-	/* timer init */
-	RTMPInitTimer(pAd, &pAd->MlmeAux.BeaconTimer,
-		      GET_TIMER_FUNCTION(BeaconTimeout), pAd, FALSE);
-	RTMPInitTimer(pAd, &pAd->MlmeAux.ScanTimer,
-		      GET_TIMER_FUNCTION(ScanTimeout), pAd, FALSE);
-}
-
-/*
-	==========================================================================
-	Description:
-		Beacon timeout handler, executed in timer thread
-
-	IRQL = DISPATCH_LEVEL
-
-	==========================================================================
- */
-void BeaconTimeout(void *SystemSpecific1,
-		   void *FunctionContext,
-		   void *SystemSpecific2, void *SystemSpecific3)
-{
-	struct rt_rtmp_adapter *pAd = (struct rt_rtmp_adapter *)FunctionContext;
-
-	DBGPRINT(RT_DEBUG_TRACE, ("SYNC - BeaconTimeout\n"));
-
-	/* Do nothing if the driver is starting halt state. */
-	/* This might happen when timer already been fired before cancel timer with mlmehalt */
-	if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS))
-		return;
-
-	if ((pAd->CommonCfg.BBPCurrentBW == BW_40)
-	    ) {
-		u8 BBPValue = 0;
-		AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, FALSE);
-		AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel);
-		RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue);
-		BBPValue &= (~0x18);
-		BBPValue |= 0x10;
-		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue);
-		DBGPRINT(RT_DEBUG_TRACE,
-			 ("SYNC - End of SCAN, restore to 40MHz channel %d, Total BSS[%02d]\n",
-			  pAd->CommonCfg.CentralChannel, pAd->ScanTab.BssNr));
-	}
-
-	MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_BEACON_TIMEOUT, 0, NULL);
-	RTMP_MLME_HANDLER(pAd);
-}
-
-/*
-	==========================================================================
-	Description:
-		Scan timeout handler, executed in timer thread
-
-	IRQL = DISPATCH_LEVEL
-
-	==========================================================================
- */
-void ScanTimeout(void *SystemSpecific1,
-		 void *FunctionContext,
-		 void *SystemSpecific2, void *SystemSpecific3)
-{
-	struct rt_rtmp_adapter *pAd = (struct rt_rtmp_adapter *)FunctionContext;
-
-	/* Do nothing if the driver is starting halt state. */
-	/* This might happen when timer already been fired before cancel timer with mlmehalt */
-	if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS))
-		return;
-
-	if (MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_SCAN_TIMEOUT, 0, NULL)) {
-		RTMP_MLME_HANDLER(pAd);
-	} else {
-		/* To prevent SyncMachine.CurrState is SCAN_LISTEN forever. */
-		pAd->MlmeAux.Channel = 0;
-		ScanNextChannel(pAd);
-		if (pAd->CommonCfg.bWirelessEvent) {
-			RTMPSendWirelessEvent(pAd,
-					      IW_SCAN_ENQUEUE_FAIL_EVENT_FLAG,
-					      pAd->MacTab.Content[BSSID_WCID].
-					      Addr, BSS0, 0);
-		}
-	}
-}
-
-/*
-	==========================================================================
-	Description:
-		MLME SCAN req state machine procedure
-	==========================================================================
- */
-void MlmeScanReqAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
-{
-	u8 Ssid[MAX_LEN_OF_SSID], SsidLen, ScanType, BssType, BBPValue = 0;
-	BOOLEAN TimerCancelled;
-	unsigned long Now;
-	u16 Status;
-	struct rt_header_802_11 * pHdr80211;
-	u8 *pOutBuffer = NULL;
-	int NStatus;
-
-	/* Check the total scan tries for one single OID command */
-	/* If this is the CCX 2.0 Case, skip that! */
-	if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_START_UP)) {
-		DBGPRINT(RT_DEBUG_TRACE,
-			 ("SYNC - MlmeScanReqAction before Startup\n"));
-		return;
-	}
-	/* Increase the scan retry counters. */
-	pAd->StaCfg.ScanCnt++;
-
-#ifdef RTMP_MAC_PCI
-	if ((OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE)) &&
-	    (IDLE_ON(pAd)) &&
-	    (pAd->StaCfg.bRadio == TRUE) &&
-	    (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF))) {
-		if (pAd->StaCfg.PSControl.field.EnableNewPS == FALSE) {
-			AsicSendCommandToMcu(pAd, 0x31, PowerWakeCID, 0x00,
-					     0x02);
-			AsicCheckCommanOk(pAd, PowerWakeCID);
-			RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF);
-			DBGPRINT(RT_DEBUG_TRACE,
-				 ("PSM - Issue Wake up command \n"));
-		} else {
-			RT28xxPciAsicRadioOn(pAd, GUI_IDLE_POWER_SAVE);
-		}
-	}
-#endif /* RTMP_MAC_PCI // */
-
-	/* first check the parameter sanity */
-	if (MlmeScanReqSanity(pAd,
-			      Elem->Msg,
-			      Elem->MsgLen,
-			      &BssType, (char *)Ssid, &SsidLen, &ScanType)) {
-
-		/* Check for channel load and noise hist request */
-		/* Suspend MSDU only at scan request, not the last two mentioned */
-		/* Suspend MSDU transmission here */
-		RTMPSuspendMsduTransmission(pAd);
-
-		/* */
-		/* To prevent data loss. */
-		/* Send a NULL data with turned PSM bit on to current associated AP before SCAN progress. */
-		/* And should send a NULL data with turned PSM bit off to AP, when scan progress done */
-		/* */
-		if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED)
-		    && (INFRA_ON(pAd))) {
-			NStatus = MlmeAllocateMemory(pAd, (void *)& pOutBuffer);
-			if (NStatus == NDIS_STATUS_SUCCESS) {
-				pHdr80211 = (struct rt_header_802_11 *) pOutBuffer;
-				MgtMacHeaderInit(pAd, pHdr80211,
-						 SUBTYPE_NULL_FUNC, 1,
-						 pAd->CommonCfg.Bssid,
-						 pAd->CommonCfg.Bssid);
-				pHdr80211->Duration = 0;
-				pHdr80211->FC.Type = BTYPE_DATA;
-				pHdr80211->FC.PwrMgmt = PWR_SAVE;
-
-				/* Send using priority queue */
-				MiniportMMRequest(pAd, 0, pOutBuffer,
-						  sizeof(struct rt_header_802_11));
-				DBGPRINT(RT_DEBUG_TRACE,
-					 ("MlmeScanReqAction -- Send PSM Data frame for off channel RM\n"));
-				MlmeFreeMemory(pAd, pOutBuffer);
-				RTMPusecDelay(5000);
-			}
-		}
-
-		NdisGetSystemUpTime(&Now);
-		pAd->StaCfg.LastScanTime = Now;
-		/* reset all the timers */
-		RTMPCancelTimer(&pAd->MlmeAux.BeaconTimer, &TimerCancelled);
-		RTMPCancelTimer(&pAd->MlmeAux.ScanTimer, &TimerCancelled);
-
-		/* record desired BSS parameters */
-		pAd->MlmeAux.BssType = BssType;
-		pAd->MlmeAux.ScanType = ScanType;
-		pAd->MlmeAux.SsidLen = SsidLen;
-		NdisZeroMemory(pAd->MlmeAux.Ssid, MAX_LEN_OF_SSID);
-		NdisMoveMemory(pAd->MlmeAux.Ssid, Ssid, SsidLen);
-
-		/* start from the first channel */
-		pAd->MlmeAux.Channel = FirstChannel(pAd);
-
-		/* Let BBP register at 20MHz to do scan */
-		RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue);
-		BBPValue &= (~0x18);
-		RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue);
-		DBGPRINT(RT_DEBUG_TRACE, ("SYNC - BBP R4 to 20MHz.l\n"));
-		ScanNextChannel(pAd);
-	} else {
-		DBGPRINT_ERR("SYNC - MlmeScanReqAction() sanity check fail\n");
-		pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
-		Status = MLME_INVALID_FORMAT;
-		MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_SCAN_CONF, 2,
-			    &Status);
-	}
-}
-
-/*
-	==========================================================================
-	Description:
-		MLME JOIN req state machine procedure
-	==========================================================================
- */
-void MlmeJoinReqAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
-{
-	u8 BBPValue = 0;
-	struct rt_bss_entry *pBss;
-	BOOLEAN TimerCancelled;
-	struct rt_header_802_11 Hdr80211;
-	int NStatus;
-	unsigned long FrameLen = 0;
-	u8 *pOutBuffer = NULL;
-	u8 *pSupRate = NULL;
-	u8 SupRateLen;
-	u8 *pExtRate = NULL;
-	u8 ExtRateLen;
-	u8 ASupRate[] = { 0x8C, 0x12, 0x98, 0x24, 0xb0, 0x48, 0x60, 0x6C };
-	u8 ASupRateLen = sizeof(ASupRate) / sizeof(u8);
-	struct rt_mlme_join_req *pInfo = (struct rt_mlme_join_req *)(Elem->Msg);
-
-	DBGPRINT(RT_DEBUG_TRACE,
-		 ("SYNC - MlmeJoinReqAction(BSS #%ld)\n", pInfo->BssIdx));
-
-#ifdef RTMP_MAC_PCI
-	if ((OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_PCIE_DEVICE)) &&
-	    (IDLE_ON(pAd)) &&
-	    (pAd->StaCfg.bRadio == TRUE) &&
-	    (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF))) {
-		RT28xxPciAsicRadioOn(pAd, GUI_IDLE_POWER_SAVE);
-	}
-#endif /* RTMP_MAC_PCI // */
-
-	/* reset all the timers */
-	RTMPCancelTimer(&pAd->MlmeAux.ScanTimer, &TimerCancelled);
-	RTMPCancelTimer(&pAd->MlmeAux.BeaconTimer, &TimerCancelled);
-
-	pBss = &pAd->MlmeAux.SsidBssTab.BssEntry[pInfo->BssIdx];
-
-	/* record the desired SSID & BSSID we're waiting for */
-	COPY_MAC_ADDR(pAd->MlmeAux.Bssid, pBss->Bssid);
-
-	/* If AP's SSID is not hidden, it is OK for updating ssid to MlmeAux again. */
-	if (pBss->Hidden == 0) {
-		RTMPZeroMemory(pAd->MlmeAux.Ssid, MAX_LEN_OF_SSID);
-		NdisMoveMemory(pAd->MlmeAux.Ssid, pBss->Ssid, pBss->SsidLen);
-		pAd->MlmeAux.SsidLen = pBss->SsidLen;
-	}
-
-	pAd->MlmeAux.BssType = pBss->BssType;
-	pAd->MlmeAux.Channel = pBss->Channel;
-	pAd->MlmeAux.CentralChannel = pBss->CentralChannel;
-
-	/* Let BBP register at 20MHz to do scan */
-	RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue);
-	BBPValue &= (~0x18);
-	RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue);
-
-	DBGPRINT(RT_DEBUG_TRACE, ("SYNC - BBP R4 to 20MHz.l\n"));
-
-	/* switch channel and waiting for beacon timer */
-	AsicSwitchChannel(pAd, pAd->MlmeAux.Channel, FALSE);
-	AsicLockChannel(pAd, pAd->MlmeAux.Channel);
-	RTMPSetTimer(&pAd->MlmeAux.BeaconTimer, JOIN_TIMEOUT);
-
-	do {
-		if (((pAd->CommonCfg.bIEEE80211H == 1) &&
-		     (pAd->MlmeAux.Channel > 14) &&
-		     RadarChannelCheck(pAd, pAd->MlmeAux.Channel))
-		    ) {
-			/* */
-			/* We can't send any Probe request frame to meet 802.11h. */
-			/* */
-			if (pBss->Hidden == 0)
-				break;
-		}
-		/* */
-		/* send probe request */
-		/* */
-		NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);
-		if (NStatus == NDIS_STATUS_SUCCESS) {
-			if (pAd->MlmeAux.Channel <= 14) {
-				pSupRate = pAd->CommonCfg.SupRate;
-				SupRateLen = pAd->CommonCfg.SupRateLen;
-				pExtRate = pAd->CommonCfg.ExtRate;
-				ExtRateLen = pAd->CommonCfg.ExtRateLen;
-			} else {
-				/* */
-				/* Overwrite Support Rate, CCK rate are not allowed */
-				/* */
-				pSupRate = ASupRate;
-				SupRateLen = ASupRateLen;
-				ExtRateLen = 0;
-			}
-
-			if (pAd->MlmeAux.BssType == BSS_INFRA)
-				MgtMacHeaderInit(pAd, &Hdr80211,
-						 SUBTYPE_PROBE_REQ, 0,
-						 pAd->MlmeAux.Bssid,
-						 pAd->MlmeAux.Bssid);
-			else
-				MgtMacHeaderInit(pAd, &Hdr80211,
-						 SUBTYPE_PROBE_REQ, 0,
-						 BROADCAST_ADDR,
-						 BROADCAST_ADDR);
-
-			MakeOutgoingFrame(pOutBuffer, &FrameLen,
-					  sizeof(struct rt_header_802_11), &Hdr80211,
-					  1, &SsidIe,
-					  1, &pAd->MlmeAux.SsidLen,
-					  pAd->MlmeAux.SsidLen,
-					  pAd->MlmeAux.Ssid, 1, &SupRateIe, 1,
-					  &SupRateLen, SupRateLen, pSupRate,
-					  END_OF_ARGS);
-
-			if (ExtRateLen) {
-				unsigned long Tmp;
-				MakeOutgoingFrame(pOutBuffer + FrameLen, &Tmp,
-						  1, &ExtRateIe,
-						  1, &ExtRateLen,
-						  ExtRateLen, pExtRate,
-						  END_OF_ARGS);
-				FrameLen += Tmp;
-			}
-
-			MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
-			MlmeFreeMemory(pAd, pOutBuffer);
-		}
-	} while (FALSE);
-
-	DBGPRINT(RT_DEBUG_TRACE,
-		("SYNC - Switch to ch %d, Wait BEACON from %pM\n",
-			pBss->Channel, pBss->Bssid));
-
-	pAd->Mlme.SyncMachine.CurrState = JOIN_WAIT_BEACON;
-}
-
-/*
-	==========================================================================
-	Description:
-		MLME START Request state machine procedure, starting an IBSS
-	==========================================================================
- */
-void MlmeStartReqAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
-{
-	u8 Ssid[MAX_LEN_OF_SSID], SsidLen;
-	BOOLEAN TimerCancelled;
-
-	/* New for WPA security suites */
-	u8 VarIE[MAX_VIE_LEN];	/* Total VIE length = MAX_VIE_LEN - -5 */
-	struct rt_ndis_802_11_variable_ies *pVIE = NULL;
-	LARGE_INTEGER TimeStamp;
-	BOOLEAN Privacy;
-	u16 Status;
-
-	/* Init Variable IE structure */
-	pVIE = (struct rt_ndis_802_11_variable_ies *)VarIE;
-	pVIE->Length = 0;
-	TimeStamp.u.LowPart = 0;
-	TimeStamp.u.HighPart = 0;
-
-	if (MlmeStartReqSanity
-	    (pAd, Elem->Msg, Elem->MsgLen, (char *)Ssid, &SsidLen)) {
-		/* reset all the timers */
-		RTMPCancelTimer(&pAd->MlmeAux.ScanTimer, &TimerCancelled);
-		RTMPCancelTimer(&pAd->MlmeAux.BeaconTimer, &TimerCancelled);
-
-		/* */
-		/* Start a new IBSS. All IBSS parameters are decided now.... */
-		/* */
-		DBGPRINT(RT_DEBUG_TRACE,
-			 ("MlmeStartReqAction - Start a new IBSS. All IBSS parameters are decided now.... \n"));
-		pAd->MlmeAux.BssType = BSS_ADHOC;
-		NdisMoveMemory(pAd->MlmeAux.Ssid, Ssid, SsidLen);
-		pAd->MlmeAux.SsidLen = SsidLen;
-
-		/* generate a radom number as BSSID */
-		MacAddrRandomBssid(pAd, pAd->MlmeAux.Bssid);
-		DBGPRINT(RT_DEBUG_TRACE,
-			 ("MlmeStartReqAction - generate a radom number as BSSID \n"));
-
-		Privacy =
-		    (pAd->StaCfg.WepStatus == Ndis802_11Encryption1Enabled)
-		    || (pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled)
-		    || (pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled);
-		pAd->MlmeAux.CapabilityInfo =
-		    CAP_GENERATE(0, 1, Privacy,
-				 (pAd->CommonCfg.TxPreamble ==
-				  Rt802_11PreambleShort), 1, 0);
-		pAd->MlmeAux.BeaconPeriod = pAd->CommonCfg.BeaconPeriod;
-		pAd->MlmeAux.AtimWin = pAd->StaCfg.AtimWin;
-		pAd->MlmeAux.Channel = pAd->CommonCfg.Channel;
-
-		pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel;
-		pAd->MlmeAux.CentralChannel = pAd->CommonCfg.CentralChannel;
-
-		pAd->MlmeAux.SupRateLen = pAd->CommonCfg.SupRateLen;
-		NdisMoveMemory(pAd->MlmeAux.SupRate, pAd->CommonCfg.SupRate,
-			       MAX_LEN_OF_SUPPORTED_RATES);
-		RTMPCheckRates(pAd, pAd->MlmeAux.SupRate,
-			       &pAd->MlmeAux.SupRateLen);
-		pAd->MlmeAux.ExtRateLen = pAd->CommonCfg.ExtRateLen;
-		NdisMoveMemory(pAd->MlmeAux.ExtRate, pAd->CommonCfg.ExtRate,
-			       MAX_LEN_OF_SUPPORTED_RATES);
-		RTMPCheckRates(pAd, pAd->MlmeAux.ExtRate,
-			       &pAd->MlmeAux.ExtRateLen);
-
-		if (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED) {
-			RTMPUpdateHTIE(&pAd->CommonCfg.DesiredHtPhy,
-				       &pAd->StaCfg.DesiredHtPhyInfo.MCSSet[0],
-				       &pAd->MlmeAux.HtCapability,
-				       &pAd->MlmeAux.AddHtInfo);
-			pAd->MlmeAux.HtCapabilityLen = sizeof(struct rt_ht_capability_ie);
-			/* Not turn pAd->StaActive.SupportedHtPhy.bHtEnable = TRUE here. */
-			DBGPRINT(RT_DEBUG_TRACE,
-				 ("SYNC -pAd->StaActive.SupportedHtPhy.bHtEnable = TRUE\n"));
-		} else {
-			pAd->MlmeAux.HtCapabilityLen = 0;
-			pAd->StaActive.SupportedPhyInfo.bHtEnable = FALSE;
-			NdisZeroMemory(&pAd->StaActive.SupportedPhyInfo.
-				       MCSSet[0], 16);
-		}
-		/* temporarily not support QOS in IBSS */
-		NdisZeroMemory(&pAd->MlmeAux.APEdcaParm, sizeof(struct rt_edca_parm));
-		NdisZeroMemory(&pAd->MlmeAux.APQbssLoad,
-			       sizeof(struct rt_qbss_load_parm));
-		NdisZeroMemory(&pAd->MlmeAux.APQosCapability,
-			       sizeof(struct rt_qos_capability_parm));
-
-		AsicSwitchChannel(pAd, pAd->MlmeAux.Channel, FALSE);
-		AsicLockChannel(pAd, pAd->MlmeAux.Channel);
-
-		DBGPRINT(RT_DEBUG_TRACE,
-			 ("SYNC - MlmeStartReqAction(ch= %d,sup rates= %d, ext rates=%d)\n",
-			  pAd->MlmeAux.Channel, pAd->MlmeAux.SupRateLen,
-			  pAd->MlmeAux.ExtRateLen));
-
-		pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
-		Status = MLME_SUCCESS;
-		MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_START_CONF, 2,
-			    &Status);
-	} else {
-		DBGPRINT_ERR("SYNC - MlmeStartReqAction() sanity check fail.\n");
-		pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
-		Status = MLME_INVALID_FORMAT;
-		MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_START_CONF, 2,
-			    &Status);
-	}
-}
-
-/*
-	==========================================================================
-	Description:
-		peer sends beacon back when scanning
-	==========================================================================
- */
-void PeerBeaconAtScanAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
-{
-	u8 Bssid[MAC_ADDR_LEN], Addr2[MAC_ADDR_LEN];
-	u8 Ssid[MAX_LEN_OF_SSID], BssType, Channel, NewChannel,
-	    SsidLen, DtimCount, DtimPeriod, BcastFlag, MessageToMe;
-	struct rt_cf_parm CfParm;
-	u16 BeaconPeriod, AtimWin, CapabilityInfo;
-	struct rt_frame_802_11 * pFrame;
-	LARGE_INTEGER TimeStamp;
-	u8 Erp;
-	u8 SupRate[MAX_LEN_OF_SUPPORTED_RATES],
-	    ExtRate[MAX_LEN_OF_SUPPORTED_RATES];
-	u8 SupRateLen, ExtRateLen;
-	u16 LenVIE;
-	u8 CkipFlag;
-	u8 AironetCellPowerLimit;
-	struct rt_edca_parm EdcaParm;
-	struct rt_qbss_load_parm QbssLoad;
-	struct rt_qos_capability_parm QosCapability;
-	unsigned long RalinkIe;
-	u8 VarIE[MAX_VIE_LEN];	/* Total VIE length = MAX_VIE_LEN - -5 */
-	struct rt_ndis_802_11_variable_ies *pVIE = NULL;
-	struct rt_ht_capability_ie HtCapability;
-	struct rt_add_ht_info_ie AddHtInfo;	/* AP might use this additional ht info IE */
-	u8 HtCapabilityLen = 0, PreNHtCapabilityLen = 0;
-	u8 AddHtInfoLen;
-	u8 NewExtChannelOffset = 0xff;
-
-	/* NdisFillMemory(Ssid, MAX_LEN_OF_SSID, 0x00); */
-	pFrame = (struct rt_frame_802_11 *) Elem->Msg;
-	/* Init Variable IE structure */
-	pVIE = (struct rt_ndis_802_11_variable_ies *)VarIE;
-	pVIE->Length = 0;
-
-	RTMPZeroMemory(&HtCapability, sizeof(HtCapability));
-	RTMPZeroMemory(&AddHtInfo, sizeof(struct rt_add_ht_info_ie));
-
-	if (PeerBeaconAndProbeRspSanity(pAd,
-					Elem->Msg,
-					Elem->MsgLen,
-					Elem->Channel,
-					Addr2,
-					Bssid,
-					(char *)Ssid,
-					&SsidLen,
-					&BssType,
-					&BeaconPeriod,
-					&Channel,
-					&NewChannel,
-					&TimeStamp,
-					&CfParm,
-					&AtimWin,
-					&CapabilityInfo,
-					&Erp,
-					&DtimCount,
-					&DtimPeriod,
-					&BcastFlag,
-					&MessageToMe,
-					SupRate,
-					&SupRateLen,
-					ExtRate,
-					&ExtRateLen,
-					&CkipFlag,
-					&AironetCellPowerLimit,
-					&EdcaParm,
-					&QbssLoad,
-					&QosCapability,
-					&RalinkIe,
-					&HtCapabilityLen,
-					&PreNHtCapabilityLen,
-					&HtCapability,
-					&AddHtInfoLen,
-					&AddHtInfo,
-					&NewExtChannelOffset, &LenVIE, pVIE)) {
-		unsigned long Idx;
-		char Rssi = 0;
-
-		Idx = BssTableSearch(&pAd->ScanTab, Bssid, Channel);
-		if (Idx != BSS_NOT_FOUND)
-			Rssi = pAd->ScanTab.BssEntry[Idx].Rssi;
-
-		Rssi =
-		    RTMPMaxRssi(pAd, ConvertToRssi(pAd, Elem->Rssi0, RSSI_0),
-				ConvertToRssi(pAd, Elem->Rssi1, RSSI_1),
-				ConvertToRssi(pAd, Elem->Rssi2, RSSI_2));
-
-		if ((HtCapabilityLen > 0) || (PreNHtCapabilityLen > 0))
-			HtCapabilityLen = SIZE_HT_CAP_IE;
-
-		Idx =
-		    BssTableSetEntry(pAd, &pAd->ScanTab, Bssid, (char *)Ssid,
-				     SsidLen, BssType, BeaconPeriod, &CfParm,
-				     AtimWin, CapabilityInfo, SupRate,
-				     SupRateLen, ExtRate, ExtRateLen,
-				     &HtCapability, &AddHtInfo, HtCapabilityLen,
-				     AddHtInfoLen, NewExtChannelOffset, Channel,
-				     Rssi, TimeStamp, CkipFlag, &EdcaParm,
-				     &QosCapability, &QbssLoad, LenVIE, pVIE);
-
-		if (Idx != BSS_NOT_FOUND) {
-			NdisMoveMemory(pAd->ScanTab.BssEntry[Idx].PTSF,
-				       &Elem->Msg[24], 4);
-			NdisMoveMemory(&pAd->ScanTab.BssEntry[Idx].TTSF[0],
-				       &Elem->TimeStamp.u.LowPart, 4);
-			NdisMoveMemory(&pAd->ScanTab.BssEntry[Idx].TTSF[4],
-				       &Elem->TimeStamp.u.LowPart, 4);
-		}
-
-	}
-	/* sanity check fail, ignored */
-}
-
-/*
-	==========================================================================
-	Description:
-		When waiting joining the (I)BSS, beacon received from external
-	==========================================================================
- */
-void PeerBeaconAtJoinAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
-{
-	u8 Bssid[MAC_ADDR_LEN], Addr2[MAC_ADDR_LEN];
-	u8 Ssid[MAX_LEN_OF_SSID], SsidLen, BssType, Channel, MessageToMe,
-	    DtimCount, DtimPeriod, BcastFlag, NewChannel;
-	LARGE_INTEGER TimeStamp;
-	u16 BeaconPeriod, AtimWin, CapabilityInfo;
-	struct rt_cf_parm Cf;
-	BOOLEAN TimerCancelled;
-	u8 Erp;
-	u8 SupRate[MAX_LEN_OF_SUPPORTED_RATES],
-	    ExtRate[MAX_LEN_OF_SUPPORTED_RATES];
-	u8 SupRateLen, ExtRateLen;
-	u8 CkipFlag;
-	u16 LenVIE;
-	u8 AironetCellPowerLimit;
-	struct rt_edca_parm EdcaParm;
-	struct rt_qbss_load_parm QbssLoad;
-	struct rt_qos_capability_parm QosCapability;
-	u16 Status;
-	u8 VarIE[MAX_VIE_LEN];	/* Total VIE length = MAX_VIE_LEN - -5 */
-	struct rt_ndis_802_11_variable_ies *pVIE = NULL;
-	unsigned long RalinkIe;
-	unsigned long Idx;
-	struct rt_ht_capability_ie HtCapability;
-	struct rt_add_ht_info_ie AddHtInfo;	/* AP might use this additional ht info IE */
-	u8 HtCapabilityLen = 0, PreNHtCapabilityLen = 0;
-	u8 AddHtInfoLen;
-	u8 NewExtChannelOffset = 0xff;
-	u8 CentralChannel;
-	BOOLEAN bAllowNrate = FALSE;
-
-	/* Init Variable IE structure */
-	pVIE = (struct rt_ndis_802_11_variable_ies *)VarIE;
-	pVIE->Length = 0;
-	RTMPZeroMemory(&HtCapability, sizeof(HtCapability));
-	RTMPZeroMemory(&AddHtInfo, sizeof(struct rt_add_ht_info_ie));
-
-	if (PeerBeaconAndProbeRspSanity(pAd,
-					Elem->Msg,
-					Elem->MsgLen,
-					Elem->Channel,
-					Addr2,
-					Bssid,
-					(char *)Ssid,
-					&SsidLen,
-					&BssType,
-					&BeaconPeriod,
-					&Channel,
-					&NewChannel,
-					&TimeStamp,
-					&Cf,
-					&AtimWin,
-					&CapabilityInfo,
-					&Erp,
-					&DtimCount,
-					&DtimPeriod,
-					&BcastFlag,
-					&MessageToMe,
-					SupRate,
-					&SupRateLen,
-					ExtRate,
-					&ExtRateLen,
-					&CkipFlag,
-					&AironetCellPowerLimit,
-					&EdcaParm,
-					&QbssLoad,
-					&QosCapability,
-					&RalinkIe,
-					&HtCapabilityLen,
-					&PreNHtCapabilityLen,
-					&HtCapability,
-					&AddHtInfoLen,
-					&AddHtInfo,
-					&NewExtChannelOffset, &LenVIE, pVIE)) {
-		/* Disqualify 11b only adhoc when we are in 11g only adhoc mode */
-		if ((BssType == BSS_ADHOC)
-		    && (pAd->CommonCfg.PhyMode == PHY_11G)
-		    && ((SupRateLen + ExtRateLen) < 12))
-			return;
-
-		/* BEACON from desired BSS/IBSS found. We should be able to decide most */
-		/* BSS parameters here. */
-		/* Q. But what happen if this JOIN doesn't conclude a successful ASSOCIATION? */
-		/*    Do we need to recover back all parameters belonging to previous BSS? */
-		/* A. Should be not. There's no back-door recover to previous AP. It still needs */
-		/*    a new JOIN-AUTH-ASSOC sequence. */
-		if (MAC_ADDR_EQUAL(pAd->MlmeAux.Bssid, Bssid)) {
-			DBGPRINT(RT_DEBUG_TRACE,
-				 ("SYNC - receive desired BEACON at JoinWaitBeacon... Channel = %d\n",
-				  Channel));
-			RTMPCancelTimer(&pAd->MlmeAux.BeaconTimer,
-					&TimerCancelled);
-
-			/* Update RSSI to prevent No signal display when cards first initialized */
-			pAd->StaCfg.RssiSample.LastRssi0 =
-			    ConvertToRssi(pAd, Elem->Rssi0, RSSI_0);
-			pAd->StaCfg.RssiSample.LastRssi1 =
-			    ConvertToRssi(pAd, Elem->Rssi1, RSSI_1);
-			pAd->StaCfg.RssiSample.LastRssi2 =
-			    ConvertToRssi(pAd, Elem->Rssi2, RSSI_2);
-			pAd->StaCfg.RssiSample.AvgRssi0 =
-			    pAd->StaCfg.RssiSample.LastRssi0;
-			pAd->StaCfg.RssiSample.AvgRssi0X8 =
-			    pAd->StaCfg.RssiSample.AvgRssi0 << 3;
-			pAd->StaCfg.RssiSample.AvgRssi1 =
-			    pAd->StaCfg.RssiSample.LastRssi1;
-			pAd->StaCfg.RssiSample.AvgRssi1X8 =
-			    pAd->StaCfg.RssiSample.AvgRssi1 << 3;
-			pAd->StaCfg.RssiSample.AvgRssi2 =
-			    pAd->StaCfg.RssiSample.LastRssi2;
-			pAd->StaCfg.RssiSample.AvgRssi2X8 =
-			    pAd->StaCfg.RssiSample.AvgRssi2 << 3;
-
-			/* */
-			/* We need to check if SSID only set to any, then we can record the current SSID. */
-			/* Otherwise will cause hidden SSID association failed. */
-			/* */
-			if (pAd->MlmeAux.SsidLen == 0) {
-				NdisMoveMemory(pAd->MlmeAux.Ssid, Ssid,
-					       SsidLen);
-				pAd->MlmeAux.SsidLen = SsidLen;
-			} else {
-				Idx =
-				    BssSsidTableSearch(&pAd->ScanTab, Bssid,
-						       pAd->MlmeAux.Ssid,
-						       pAd->MlmeAux.SsidLen,
-						       Channel);
-
-				if (Idx == BSS_NOT_FOUND) {
-					char Rssi = 0;
-					Rssi =
-					    RTMPMaxRssi(pAd,
-							ConvertToRssi(pAd,
-								      Elem->
-								      Rssi0,
-								      RSSI_0),
-							ConvertToRssi(pAd,
-								      Elem->
-								      Rssi1,
-								      RSSI_1),
-							ConvertToRssi(pAd,
-								      Elem->
-								      Rssi2,
-								      RSSI_2));
-					Idx =
-					    BssTableSetEntry(pAd, &pAd->ScanTab,
-							     Bssid,
-							     (char *) Ssid,
-							     SsidLen, BssType,
-							     BeaconPeriod, &Cf,
-							     AtimWin,
-							     CapabilityInfo,
-							     SupRate,
-							     SupRateLen,
-							     ExtRate,
-							     ExtRateLen,
-							     &HtCapability,
-							     &AddHtInfo,
-							     HtCapabilityLen,
-							     AddHtInfoLen,
-							     NewExtChannelOffset,
-							     Channel, Rssi,
-							     TimeStamp,
-							     CkipFlag,
-							     &EdcaParm,
-							     &QosCapability,
-							     &QbssLoad, LenVIE,
-							     pVIE);
-					if (Idx != BSS_NOT_FOUND) {
-						NdisMoveMemory(pAd->ScanTab.
-							       BssEntry[Idx].
-							       PTSF,
-							       &Elem->Msg[24],
-							       4);
-						NdisMoveMemory(&pAd->ScanTab.
-							       BssEntry[Idx].
-							       TTSF[0],
-							       &Elem->TimeStamp.
-							       u.LowPart, 4);
-						NdisMoveMemory(&pAd->ScanTab.
-							       BssEntry[Idx].
-							       TTSF[4],
-							       &Elem->TimeStamp.
-							       u.LowPart, 4);
-						CapabilityInfo =
-						    pAd->ScanTab.BssEntry[Idx].
-						    CapabilityInfo;
-					}
-				} else {
-					/* */
-					/* Multiple SSID case, used correct CapabilityInfo */
-					/* */
-					CapabilityInfo =
-					    pAd->ScanTab.BssEntry[Idx].
-					    CapabilityInfo;
-				}
-			}
-			NdisMoveMemory(pAd->MlmeAux.Bssid, Bssid, MAC_ADDR_LEN);
-			pAd->MlmeAux.CapabilityInfo =
-			    CapabilityInfo & SUPPORTED_CAPABILITY_INFO;
-			pAd->MlmeAux.BssType = BssType;
-			pAd->MlmeAux.BeaconPeriod = BeaconPeriod;
-			pAd->MlmeAux.Channel = Channel;
-			pAd->MlmeAux.AtimWin = AtimWin;
-			pAd->MlmeAux.CfpPeriod = Cf.CfpPeriod;
-			pAd->MlmeAux.CfpMaxDuration = Cf.CfpMaxDuration;
-			pAd->MlmeAux.APRalinkIe = RalinkIe;
-
-			/* Copy AP's supported rate to MlmeAux for creating association request */
-			/* Also filter out not supported rate */
-			pAd->MlmeAux.SupRateLen = SupRateLen;
-			NdisMoveMemory(pAd->MlmeAux.SupRate, SupRate,
-				       SupRateLen);
-			RTMPCheckRates(pAd, pAd->MlmeAux.SupRate,
-				       &pAd->MlmeAux.SupRateLen);
-			pAd->MlmeAux.ExtRateLen = ExtRateLen;
-			NdisMoveMemory(pAd->MlmeAux.ExtRate, ExtRate,
-				       ExtRateLen);
-			RTMPCheckRates(pAd, pAd->MlmeAux.ExtRate,
-				       &pAd->MlmeAux.ExtRateLen);
-
-			NdisZeroMemory(pAd->StaActive.SupportedPhyInfo.MCSSet,
-				       16);
-
-			if (((pAd->StaCfg.WepStatus != Ndis802_11WEPEnabled)
-			     && (pAd->StaCfg.WepStatus !=
-				 Ndis802_11Encryption2Enabled))
-			    || (pAd->CommonCfg.HT_DisallowTKIP == FALSE)) {
-				bAllowNrate = TRUE;
-			}
-
-			pAd->MlmeAux.NewExtChannelOffset = NewExtChannelOffset;
-			pAd->MlmeAux.HtCapabilityLen = HtCapabilityLen;
-
-			RTMPZeroMemory(&pAd->MlmeAux.HtCapability,
-				       SIZE_HT_CAP_IE);
-			/* filter out un-supported ht rates */
-			if (((HtCapabilityLen > 0) || (PreNHtCapabilityLen > 0))
-			    && ((pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED)
-				&& (bAllowNrate))) {
-				RTMPMoveMemory(&pAd->MlmeAux.AddHtInfo,
-					       &AddHtInfo, SIZE_ADD_HT_INFO_IE);
-
-				/* StaActive.SupportedHtPhy.MCSSet stores Peer AP's 11n Rx capability */
-				NdisMoveMemory(pAd->StaActive.SupportedPhyInfo.
-					       MCSSet, HtCapability.MCSSet, 16);
-				pAd->MlmeAux.NewExtChannelOffset =
-				    NewExtChannelOffset;
-				pAd->MlmeAux.HtCapabilityLen = SIZE_HT_CAP_IE;
-				pAd->StaActive.SupportedPhyInfo.bHtEnable =
-				    TRUE;
-				if (PreNHtCapabilityLen > 0)
-					pAd->StaActive.SupportedPhyInfo.
-					    bPreNHt = TRUE;
-				RTMPCheckHt(pAd, BSSID_WCID, &HtCapability,
-					    &AddHtInfo);
-				/* Copy AP Parameter to StaActive.  This is also in LinkUp. */
-				DBGPRINT(RT_DEBUG_TRACE,
-					 ("PeerBeaconAtJoinAction! (MpduDensity=%d, MaxRAmpduFactor=%d, BW=%d)\n",
-					  pAd->StaActive.SupportedHtPhy.
-					  MpduDensity,
-					  pAd->StaActive.SupportedHtPhy.
-					  MaxRAmpduFactor,
-					  HtCapability.HtCapInfo.ChannelWidth));
-
-				if (AddHtInfoLen > 0) {
-					CentralChannel = AddHtInfo.ControlChan;
-					/* Check again the Bandwidth capability of this AP. */
-					if ((AddHtInfo.ControlChan > 2)
-					    && (AddHtInfo.AddHtInfo.
-						ExtChanOffset == EXTCHA_BELOW)
-					    && (HtCapability.HtCapInfo.
-						ChannelWidth == BW_40)) {
-						CentralChannel =
-						    AddHtInfo.ControlChan - 2;
-					} else
-					    if ((AddHtInfo.AddHtInfo.
-						 ExtChanOffset == EXTCHA_ABOVE)
-						&& (HtCapability.HtCapInfo.
-						    ChannelWidth == BW_40)) {
-						CentralChannel =
-						    AddHtInfo.ControlChan + 2;
-					}
-					/* Check Error . */
-					if (pAd->MlmeAux.CentralChannel !=
-					    CentralChannel)
-						DBGPRINT(RT_DEBUG_ERROR,
-							 ("PeerBeaconAtJoinAction HT===>Beacon Central Channel = %d, Control Channel = %d. Mlmeaux CentralChannel = %d\n",
-							  CentralChannel,
-							  AddHtInfo.ControlChan,
-							  pAd->MlmeAux.
-							  CentralChannel));
-
-					DBGPRINT(RT_DEBUG_TRACE,
-						 ("PeerBeaconAtJoinAction HT===>Central Channel = %d, Control Channel = %d,  .\n",
-						  CentralChannel,
-						  AddHtInfo.ControlChan));
-
-				}
-
-			} else {
-				/* To prevent error, let legacy AP must have same CentralChannel and Channel. */
-				if ((HtCapabilityLen == 0)
-				    && (PreNHtCapabilityLen == 0))
-					pAd->MlmeAux.CentralChannel =
-					    pAd->MlmeAux.Channel;
-
-				pAd->StaActive.SupportedPhyInfo.bHtEnable =
-				    FALSE;
-				pAd->MlmeAux.NewExtChannelOffset = 0xff;
-				RTMPZeroMemory(&pAd->MlmeAux.HtCapability,
-					       SIZE_HT_CAP_IE);
-				pAd->MlmeAux.HtCapabilityLen = 0;
-				RTMPZeroMemory(&pAd->MlmeAux.AddHtInfo,
-					       SIZE_ADD_HT_INFO_IE);
-			}
-
-			RTMPUpdateMlmeRate(pAd);
-
-			/* copy QOS related information */
-			if ((pAd->CommonCfg.bWmmCapable)
-			    || (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED)
-			    ) {
-				NdisMoveMemory(&pAd->MlmeAux.APEdcaParm,
-					       &EdcaParm, sizeof(struct rt_edca_parm));
-				NdisMoveMemory(&pAd->MlmeAux.APQbssLoad,
-					       &QbssLoad,
-					       sizeof(struct rt_qbss_load_parm));
-				NdisMoveMemory(&pAd->MlmeAux.APQosCapability,
-					       &QosCapability,
-					       sizeof(struct rt_qos_capability_parm));
-			} else {
-				NdisZeroMemory(&pAd->MlmeAux.APEdcaParm,
-					       sizeof(struct rt_edca_parm));
-				NdisZeroMemory(&pAd->MlmeAux.APQbssLoad,
-					       sizeof(struct rt_qbss_load_parm));
-				NdisZeroMemory(&pAd->MlmeAux.APQosCapability,
-					       sizeof(struct rt_qos_capability_parm));
-			}
-
-			DBGPRINT(RT_DEBUG_TRACE,
-				 ("SYNC - after JOIN, SupRateLen=%d, ExtRateLen=%d\n",
-				  pAd->MlmeAux.SupRateLen,
-				  pAd->MlmeAux.ExtRateLen));
-
-			if (AironetCellPowerLimit != 0xFF) {
-				/*We need to change our TxPower for CCX 2.0 AP Control of Client Transmit Power */
-				ChangeToCellPowerLimit(pAd,
-						       AironetCellPowerLimit);
-			} else	/*Used the default TX Power Percentage. */
-				pAd->CommonCfg.TxPowerPercentage =
-				    pAd->CommonCfg.TxPowerDefault;
-
-			pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
-			Status = MLME_SUCCESS;
-			MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_JOIN_CONF,
-				    2, &Status);
-		}
-		/* not to me BEACON, ignored */
-	}
-	/* sanity check fail, ignore this frame */
-}
-
-/*
-	==========================================================================
-	Description:
-		receive BEACON from peer
-
-	IRQL = DISPATCH_LEVEL
-
-	==========================================================================
- */
-void PeerBeacon(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
-{
-	u8 Bssid[MAC_ADDR_LEN], Addr2[MAC_ADDR_LEN];
-	char Ssid[MAX_LEN_OF_SSID];
-	struct rt_cf_parm CfParm;
-	u8 SsidLen, MessageToMe = 0, BssType, Channel, NewChannel, index = 0;
-	u8 DtimCount = 0, DtimPeriod = 0, BcastFlag = 0;
-	u16 CapabilityInfo, AtimWin, BeaconPeriod;
-	LARGE_INTEGER TimeStamp;
-	u16 TbttNumToNextWakeUp;
-	u8 Erp;
-	u8 SupRate[MAX_LEN_OF_SUPPORTED_RATES],
-	    ExtRate[MAX_LEN_OF_SUPPORTED_RATES];
-	u8 SupRateLen, ExtRateLen;
-	u8 CkipFlag;
-	u16 LenVIE;
-	u8 AironetCellPowerLimit;
-	struct rt_edca_parm EdcaParm;
-	struct rt_qbss_load_parm QbssLoad;
-	struct rt_qos_capability_parm QosCapability;
-	unsigned long RalinkIe;
-	/* New for WPA security suites */
-	u8 VarIE[MAX_VIE_LEN];	/* Total VIE length = MAX_VIE_LEN - -5 */
-	struct rt_ndis_802_11_variable_ies *pVIE = NULL;
-	struct rt_ht_capability_ie HtCapability;
-	struct rt_add_ht_info_ie AddHtInfo;	/* AP might use this additional ht info IE */
-	u8 HtCapabilityLen, PreNHtCapabilityLen;
-	u8 AddHtInfoLen;
-	u8 NewExtChannelOffset = 0xff;
-
-	if (!(INFRA_ON(pAd) || ADHOC_ON(pAd)
-	    ))
-		return;
-
-	/* Init Variable IE structure */
-	pVIE = (struct rt_ndis_802_11_variable_ies *)VarIE;
-	pVIE->Length = 0;
-	RTMPZeroMemory(&HtCapability, sizeof(HtCapability));
-	RTMPZeroMemory(&AddHtInfo, sizeof(struct rt_add_ht_info_ie));
-
-	if (PeerBeaconAndProbeRspSanity(pAd,
-					Elem->Msg,
-					Elem->MsgLen,
-					Elem->Channel,
-					Addr2,
-					Bssid,
-					Ssid,
-					&SsidLen,
-					&BssType,
-					&BeaconPeriod,
-					&Channel,
-					&NewChannel,
-					&TimeStamp,
-					&CfParm,
-					&AtimWin,
-					&CapabilityInfo,
-					&Erp,
-					&DtimCount,
-					&DtimPeriod,
-					&BcastFlag,
-					&MessageToMe,
-					SupRate,
-					&SupRateLen,
-					ExtRate,
-					&ExtRateLen,
-					&CkipFlag,
-					&AironetCellPowerLimit,
-					&EdcaParm,
-					&QbssLoad,
-					&QosCapability,
-					&RalinkIe,
-					&HtCapabilityLen,
-					&PreNHtCapabilityLen,
-					&HtCapability,
-					&AddHtInfoLen,
-					&AddHtInfo,
-					&NewExtChannelOffset, &LenVIE, pVIE)) {
-		BOOLEAN is_my_bssid, is_my_ssid;
-		unsigned long Bssidx, Now;
-		struct rt_bss_entry *pBss;
-		char RealRssi =
-		    RTMPMaxRssi(pAd, ConvertToRssi(pAd, Elem->Rssi0, RSSI_0),
-				ConvertToRssi(pAd, Elem->Rssi1, RSSI_1),
-				ConvertToRssi(pAd, Elem->Rssi2, RSSI_2));
-
-		is_my_bssid =
-		    MAC_ADDR_EQUAL(Bssid, pAd->CommonCfg.Bssid) ? TRUE : FALSE;
-		is_my_ssid =
-		    SSID_EQUAL(Ssid, SsidLen, pAd->CommonCfg.Ssid,
-			       pAd->CommonCfg.SsidLen) ? TRUE : FALSE;
-
-		/* ignore BEACON not for my SSID */
-		if ((!is_my_ssid) && (!is_my_bssid))
-			return;
-
-		/* It means STA waits disassoc completely from this AP, ignores this beacon. */
-		if (pAd->Mlme.CntlMachine.CurrState == CNTL_WAIT_DISASSOC)
-			return;
-
-		/* Copy Control channel for this BSSID. */
-		if (AddHtInfoLen != 0)
-			Channel = AddHtInfo.ControlChan;
-
-		if ((HtCapabilityLen > 0) || (PreNHtCapabilityLen > 0))
-			HtCapabilityLen = SIZE_HT_CAP_IE;
-
-		/* */
-		/* Housekeeping "SsidBssTab" table for later-on ROAMing usage. */
-		/* */
-		Bssidx = BssTableSearch(&pAd->ScanTab, Bssid, Channel);
-		if (Bssidx == BSS_NOT_FOUND) {
-			/* discover new AP of this network, create BSS entry */
-			Bssidx =
-			    BssTableSetEntry(pAd, &pAd->ScanTab, Bssid, Ssid,
-					     SsidLen, BssType, BeaconPeriod,
-					     &CfParm, AtimWin, CapabilityInfo,
-					     SupRate, SupRateLen, ExtRate,
-					     ExtRateLen, &HtCapability,
-					     &AddHtInfo, HtCapabilityLen,
-					     AddHtInfoLen, NewExtChannelOffset,
-					     Channel, RealRssi, TimeStamp,
-					     CkipFlag, &EdcaParm,
-					     &QosCapability, &QbssLoad, LenVIE,
-					     pVIE);
-			if (Bssidx == BSS_NOT_FOUND)	/* return if BSS table full */
-				return;
-
-			NdisMoveMemory(pAd->ScanTab.BssEntry[Bssidx].PTSF,
-				       &Elem->Msg[24], 4);
-			NdisMoveMemory(&pAd->ScanTab.BssEntry[Bssidx].TTSF[0],
-				       &Elem->TimeStamp.u.LowPart, 4);
-			NdisMoveMemory(&pAd->ScanTab.BssEntry[Bssidx].TTSF[4],
-				       &Elem->TimeStamp.u.LowPart, 4);
-
-		}
-
-		if ((pAd->CommonCfg.bIEEE80211H == 1) && (NewChannel != 0)
-		    && (Channel != NewChannel)) {
-			/* Switching to channel 1 can prevent from rescanning the current channel immediately (by auto reconnection). */
-			/* In addition, clear the MLME queue and the scan table to discard the RX packets and previous scanning results. */
-			AsicSwitchChannel(pAd, 1, FALSE);
-			AsicLockChannel(pAd, 1);
-			LinkDown(pAd, FALSE);
-			MlmeQueueInit(&pAd->Mlme.Queue);
-			BssTableInit(&pAd->ScanTab);
-			RTMPusecDelay(1000000);	/* use delay to prevent STA do reassoc */
-
-			/* channel sanity check */
-			for (index = 0; index < pAd->ChannelListNum; index++) {
-				if (pAd->ChannelList[index].Channel ==
-				    NewChannel) {
-					pAd->ScanTab.BssEntry[Bssidx].Channel =
-					    NewChannel;
-					pAd->CommonCfg.Channel = NewChannel;
-					AsicSwitchChannel(pAd,
-							  pAd->CommonCfg.
-							  Channel, FALSE);
-					AsicLockChannel(pAd,
-							pAd->CommonCfg.Channel);
-					DBGPRINT(RT_DEBUG_TRACE,
-						 ("PeerBeacon - STA receive channel switch announcement IE (New Channel =%d)\n",
-						  NewChannel));
-					break;
-				}
-			}
-
-			if (index >= pAd->ChannelListNum) {
-				DBGPRINT_ERR("PeerBeacon(can not find New Channel=%d in ChannelList[%d]\n", pAd->CommonCfg.Channel, pAd->ChannelListNum);
-			}
-		}
-		/* if the ssid matched & bssid unmatched, we should select the bssid with large value. */
-		/* This might happened when two STA start at the same time */
-		if ((!is_my_bssid) && ADHOC_ON(pAd)) {
-			int i;
-
-			/* Add the safeguard against the mismatch of adhoc wep status */
-			if (pAd->StaCfg.WepStatus !=
-			    pAd->ScanTab.BssEntry[Bssidx].WepStatus) {
-				return;
-			}
-			/* collapse into the ADHOC network which has bigger BSSID value. */
-			for (i = 0; i < 6; i++) {
-				if (Bssid[i] > pAd->CommonCfg.Bssid[i]) {
-					DBGPRINT(RT_DEBUG_TRACE,
-						("SYNC - merge to the IBSS "
-							"with bigger BSSID="
-							"%pM\n", Bssid));
-					AsicDisableSync(pAd);
-					COPY_MAC_ADDR(pAd->CommonCfg.Bssid,
-						      Bssid);
-					AsicSetBssid(pAd, pAd->CommonCfg.Bssid);
-					MakeIbssBeacon(pAd);	/* re-build BEACON frame */
-					AsicEnableIbssSync(pAd);	/* copy BEACON frame to on-chip memory */
-					is_my_bssid = TRUE;
-					break;
-				} else if (Bssid[i] < pAd->CommonCfg.Bssid[i])
-					break;
-			}
-		}
-
-		NdisGetSystemUpTime(&Now);
-		pBss = &pAd->ScanTab.BssEntry[Bssidx];
-		pBss->Rssi = RealRssi;	/* lastest RSSI */
-		pBss->LastBeaconRxTime = Now;	/* last RX timestamp */
-
-		/* */
-		/* BEACON from my BSSID - either IBSS or INFRA network */
-		/* */
-		if (is_my_bssid) {
-			struct rt_rxwi RxWI;
-
-			pAd->StaCfg.DtimCount = DtimCount;
-			pAd->StaCfg.DtimPeriod = DtimPeriod;
-			pAd->StaCfg.LastBeaconRxTime = Now;
-
-			RxWI.RSSI0 = Elem->Rssi0;
-			RxWI.RSSI1 = Elem->Rssi1;
-			RxWI.RSSI2 = Elem->Rssi2;
-
-			Update_Rssi_Sample(pAd, &pAd->StaCfg.RssiSample, &RxWI);
-			if (AironetCellPowerLimit != 0xFF) {
-				/* */
-				/* We get the Cisco (ccx) "TxPower Limit" required */
-				/* Changed to appropriate TxPower Limit for Ciso Compatible Extensions */
-				/* */
-				ChangeToCellPowerLimit(pAd,
-						       AironetCellPowerLimit);
-			} else {
-				/* */
-				/* AironetCellPowerLimit equal to 0xFF means the Cisco (ccx) "TxPower Limit" not exist. */
-				/* Used the default TX Power Percentage, that set from UI. */
-				/* */
-				pAd->CommonCfg.TxPowerPercentage =
-				    pAd->CommonCfg.TxPowerDefault;
-			}
-
-			if (ADHOC_ON(pAd) && (CAP_IS_IBSS_ON(CapabilityInfo))) {
-				u8 MaxSupportedRateIn500Kbps = 0;
-				u8 idx;
-				struct rt_mac_table_entry *pEntry;
-
-				/* supported rates array may not be sorted. sort it and find the maximum rate */
-				for (idx = 0; idx < SupRateLen; idx++) {
-					if (MaxSupportedRateIn500Kbps <
-					    (SupRate[idx] & 0x7f))
-						MaxSupportedRateIn500Kbps =
-						    SupRate[idx] & 0x7f;
-				}
-
-				for (idx = 0; idx < ExtRateLen; idx++) {
-					if (MaxSupportedRateIn500Kbps <
-					    (ExtRate[idx] & 0x7f))
-						MaxSupportedRateIn500Kbps =
-						    ExtRate[idx] & 0x7f;
-				}
-
-				/* look up the existing table */
-				pEntry = MacTableLookup(pAd, Addr2);
-
-				/* Ad-hoc mode is using MAC address as BA session. So we need to continuously find newly joined adhoc station by receiving beacon. */
-				/* To prevent always check this, we use wcid == RESERVED_WCID to recognize it as newly joined adhoc station. */
-				if ((ADHOC_ON(pAd)
-				     && (Elem->Wcid == RESERVED_WCID))
-				    || (pEntry
-					&&
-					((pEntry->LastBeaconRxTime +
-					  ADHOC_ENTRY_BEACON_LOST_TIME) <
-					 Now))) {
-					if (pEntry == NULL)
-						/* Another adhoc joining, add to our MAC table. */
-						pEntry =
-						    MacTableInsertEntry(pAd,
-									Addr2,
-									BSS0,
-									FALSE);
-
-					if (StaAddMacTableEntry(pAd,
-								pEntry,
-								MaxSupportedRateIn500Kbps,
-								&HtCapability,
-								HtCapabilityLen,
-								&AddHtInfo,
-								AddHtInfoLen,
-								CapabilityInfo)
-					    == FALSE) {
-						DBGPRINT(RT_DEBUG_TRACE,
-							 ("ADHOC - Add Entry failed.\n"));
-						return;
-					}
-
-					if (pEntry &&
-					    (Elem->Wcid == RESERVED_WCID)) {
-						idx = pAd->StaCfg.DefaultKeyId;
-						RTMP_STA_SECURITY_INFO_ADD(pAd,
-									   BSS0,
-									   idx,
-									   pEntry);
-					}
-				}
-
-				if (pEntry && pEntry->ValidAsCLI)
-					pEntry->LastBeaconRxTime = Now;
-
-				/* At least another peer in this IBSS, declare MediaState as CONNECTED */
-				if (!OPSTATUS_TEST_FLAG
-				    (pAd, fOP_STATUS_MEDIA_STATE_CONNECTED)) {
-					OPSTATUS_SET_FLAG(pAd,
-							  fOP_STATUS_MEDIA_STATE_CONNECTED);
-
-					pAd->IndicateMediaState =
-					    NdisMediaStateConnected;
-					RTMP_IndicateMediaState(pAd);
-					pAd->ExtraInfo = GENERAL_LINK_UP;
-					AsicSetBssid(pAd, pAd->CommonCfg.Bssid);
-
-					/* 2003/03/12 - john */
-					/* Make sure this entry in "ScanTab" table, thus complies to Microsoft's policy that */
-					/* "site survey" result should always include the current connected network. */
-					/* */
-					Bssidx =
-					    BssTableSearch(&pAd->ScanTab, Bssid,
-							   Channel);
-					if (Bssidx == BSS_NOT_FOUND) {
-						Bssidx =
-						    BssTableSetEntry(pAd,
-								     &pAd->
-								     ScanTab,
-								     Bssid,
-								     Ssid,
-								     SsidLen,
-								     BssType,
-								     BeaconPeriod,
-								     &CfParm,
-								     AtimWin,
-								     CapabilityInfo,
-								     SupRate,
-								     SupRateLen,
-								     ExtRate,
-								     ExtRateLen,
-								     &HtCapability,
-								     &AddHtInfo,
-								     HtCapabilityLen,
-								     AddHtInfoLen,
-								     NewExtChannelOffset,
-								     Channel,
-								     RealRssi,
-								     TimeStamp,
-								     0,
-								     &EdcaParm,
-								     &QosCapability,
-								     &QbssLoad,
-								     LenVIE,
-								     pVIE);
-					}
-					DBGPRINT(RT_DEBUG_TRACE,
-						 ("ADHOC  fOP_STATUS_MEDIA_STATE_CONNECTED.\n"));
-				}
-			}
-
-			if (INFRA_ON(pAd)) {
-				BOOLEAN bUseShortSlot, bUseBGProtection;
-
-				/* decide to use/change to - */
-				/*      1. long slot (20 us) or short slot (9 us) time */
-				/*      2. turn on/off RTS/CTS and/or CTS-to-self protection */
-				/*      3. short preamble */
-
-				/*bUseShortSlot = pAd->CommonCfg.bUseShortSlotTime && CAP_IS_SHORT_SLOT(CapabilityInfo); */
-				bUseShortSlot =
-				    CAP_IS_SHORT_SLOT(CapabilityInfo);
-				if (bUseShortSlot !=
-				    OPSTATUS_TEST_FLAG(pAd,
-						       fOP_STATUS_SHORT_SLOT_INUSED))
-					AsicSetSlotTime(pAd, bUseShortSlot);
-
-				bUseBGProtection = (pAd->CommonCfg.UseBGProtection == 1) ||	/* always use */
-				    ((pAd->CommonCfg.UseBGProtection == 0)
-				     && ERP_IS_USE_PROTECTION(Erp));
-
-				if (pAd->CommonCfg.Channel > 14)	/* always no BG protection in A-band. falsely happened when switching A/G band to a dual-band AP */
-					bUseBGProtection = FALSE;
-
-				if (bUseBGProtection !=
-				    OPSTATUS_TEST_FLAG(pAd,
-						       fOP_STATUS_BG_PROTECTION_INUSED))
-				{
-					if (bUseBGProtection) {
-						OPSTATUS_SET_FLAG(pAd,
-								  fOP_STATUS_BG_PROTECTION_INUSED);
-						AsicUpdateProtect(pAd,
-								  pAd->MlmeAux.
-								  AddHtInfo.
-								  AddHtInfo2.
-								  OperaionMode,
-								  (OFDMSETPROTECT
-								   |
-								   CCKSETPROTECT
-								   |
-								   ALLN_SETPROTECT),
-								  FALSE,
-								  (pAd->MlmeAux.
-								   AddHtInfo.
-								   AddHtInfo2.
-								   NonGfPresent
-								   == 1));
-					} else {
-						OPSTATUS_CLEAR_FLAG(pAd,
-								    fOP_STATUS_BG_PROTECTION_INUSED);
-						AsicUpdateProtect(pAd,
-								  pAd->MlmeAux.
-								  AddHtInfo.
-								  AddHtInfo2.
-								  OperaionMode,
-								  (OFDMSETPROTECT
-								   |
-								   CCKSETPROTECT
-								   |
-								   ALLN_SETPROTECT),
-								  TRUE,
-								  (pAd->MlmeAux.
-								   AddHtInfo.
-								   AddHtInfo2.
-								   NonGfPresent
-								   == 1));
-					}
-
-					DBGPRINT(RT_DEBUG_WARN,
-						 ("SYNC - AP changed B/G protection to %d\n",
-						  bUseBGProtection));
-				}
-				/* check Ht protection mode. and adhere to the Non-GF device indication by AP. */
-				if ((AddHtInfoLen != 0) &&
-				    ((AddHtInfo.AddHtInfo2.OperaionMode !=
-				      pAd->MlmeAux.AddHtInfo.AddHtInfo2.
-				      OperaionMode)
-				     || (AddHtInfo.AddHtInfo2.NonGfPresent !=
-					 pAd->MlmeAux.AddHtInfo.AddHtInfo2.
-					 NonGfPresent))) {
-					pAd->MlmeAux.AddHtInfo.AddHtInfo2.
-					    NonGfPresent =
-					    AddHtInfo.AddHtInfo2.NonGfPresent;
-					pAd->MlmeAux.AddHtInfo.AddHtInfo2.
-					    OperaionMode =
-					    AddHtInfo.AddHtInfo2.OperaionMode;
-					if (pAd->MlmeAux.AddHtInfo.AddHtInfo2.
-					    NonGfPresent == 1) {
-						AsicUpdateProtect(pAd,
-								  pAd->MlmeAux.
-								  AddHtInfo.
-								  AddHtInfo2.
-								  OperaionMode,
-								  ALLN_SETPROTECT,
-								  FALSE, TRUE);
-					} else
-						AsicUpdateProtect(pAd,
-								  pAd->MlmeAux.
-								  AddHtInfo.
-								  AddHtInfo2.
-								  OperaionMode,
-								  ALLN_SETPROTECT,
-								  FALSE, FALSE);
-
-					DBGPRINT(RT_DEBUG_TRACE,
-						 ("SYNC - AP changed N OperaionMode to %d\n",
-						  pAd->MlmeAux.AddHtInfo.
-						  AddHtInfo2.OperaionMode));
-				}
-
-				if (OPSTATUS_TEST_FLAG
-				    (pAd, fOP_STATUS_SHORT_PREAMBLE_INUSED)
-				    && ERP_IS_USE_BARKER_PREAMBLE(Erp)) {
-					MlmeSetTxPreamble(pAd,
-							  Rt802_11PreambleLong);
-					DBGPRINT(RT_DEBUG_TRACE,
-						 ("SYNC - AP forced to use long preamble\n"));
-				}
-
-				if (OPSTATUS_TEST_FLAG
-				    (pAd, fOP_STATUS_WMM_INUSED)
-				    && (EdcaParm.bValid == TRUE)
-				    && (EdcaParm.EdcaUpdateCount !=
-					pAd->CommonCfg.APEdcaParm.
-					EdcaUpdateCount)) {
-					DBGPRINT(RT_DEBUG_TRACE,
-						 ("SYNC - AP change EDCA parameters(from %d to %d)\n",
-						  pAd->CommonCfg.APEdcaParm.
-						  EdcaUpdateCount,
-						  EdcaParm.EdcaUpdateCount));
-					AsicSetEdcaParm(pAd, &EdcaParm);
-				}
-				/* copy QOS related information */
-				NdisMoveMemory(&pAd->CommonCfg.APQbssLoad,
-					       &QbssLoad,
-					       sizeof(struct rt_qbss_load_parm));
-				NdisMoveMemory(&pAd->CommonCfg.APQosCapability,
-					       &QosCapability,
-					       sizeof(struct rt_qos_capability_parm));
-			}
-			/* only INFRASTRUCTURE mode support power-saving feature */
-			if ((INFRA_ON(pAd) && (pAd->StaCfg.Psm == PWR_SAVE))
-			    || (pAd->CommonCfg.bAPSDForcePowerSave)) {
-				u8 FreeNumber;
-				/*  1. AP has backlogged unicast-to-me frame, stay AWAKE, send PSPOLL */
-				/*  2. AP has backlogged broadcast/multicast frame and we want those frames, stay AWAKE */
-				/*  3. we have outgoing frames in TxRing or MgmtRing, better stay AWAKE */
-				/*  4. Psm change to PWR_SAVE, but AP not been informed yet, we better stay AWAKE */
-				/*  5. otherwise, put PHY back to sleep to save battery. */
-				if (MessageToMe) {
-#ifdef RTMP_MAC_PCI
-					if (OPSTATUS_TEST_FLAG
-					    (pAd, fOP_STATUS_PCIE_DEVICE)) {
-						/* Restore to correct BBP R3 value */
-						if (pAd->Antenna.field.RxPath >
-						    1)
-							RTMP_BBP_IO_WRITE8_BY_REG_ID
-							    (pAd, BBP_R3,
-							     pAd->StaCfg.BBPR3);
-						/* Turn clk to 80Mhz. */
-					}
-#endif /* RTMP_MAC_PCI // */
-					if (pAd->CommonCfg.bAPSDCapable
-					    && pAd->CommonCfg.APEdcaParm.
-					    bAPSDCapable
-					    && pAd->CommonCfg.bAPSDAC_BE
-					    && pAd->CommonCfg.bAPSDAC_BK
-					    && pAd->CommonCfg.bAPSDAC_VI
-					    && pAd->CommonCfg.bAPSDAC_VO) {
-						pAd->CommonCfg.
-						    bNeedSendTriggerFrame =
-						    TRUE;
-					} else
-						RTMP_PS_POLL_ENQUEUE(pAd);
-				} else if (BcastFlag && (DtimCount == 0)
-					   && OPSTATUS_TEST_FLAG(pAd,
-								 fOP_STATUS_RECEIVE_DTIM))
-				{
-#ifdef RTMP_MAC_PCI
-					if (OPSTATUS_TEST_FLAG
-					    (pAd, fOP_STATUS_PCIE_DEVICE)) {
-						if (pAd->Antenna.field.RxPath >
-						    1)
-							RTMP_BBP_IO_WRITE8_BY_REG_ID
-							    (pAd, BBP_R3,
-							     pAd->StaCfg.BBPR3);
-					}
-#endif /* RTMP_MAC_PCI // */
-				} else
-				    if ((pAd->TxSwQueue[QID_AC_BK].Number != 0)
-					|| (pAd->TxSwQueue[QID_AC_BE].Number !=
-					    0)
-					|| (pAd->TxSwQueue[QID_AC_VI].Number !=
-					    0)
-					|| (pAd->TxSwQueue[QID_AC_VO].Number !=
-					    0)
-					||
-					(RTMPFreeTXDRequest
-					 (pAd, QID_AC_BK, TX_RING_SIZE - 1,
-					  &FreeNumber) != NDIS_STATUS_SUCCESS)
-					||
-					(RTMPFreeTXDRequest
-					 (pAd, QID_AC_BE, TX_RING_SIZE - 1,
-					  &FreeNumber) != NDIS_STATUS_SUCCESS)
-					||
-					(RTMPFreeTXDRequest
-					 (pAd, QID_AC_VI, TX_RING_SIZE - 1,
-					  &FreeNumber) != NDIS_STATUS_SUCCESS)
-					||
-					(RTMPFreeTXDRequest
-					 (pAd, QID_AC_VO, TX_RING_SIZE - 1,
-					  &FreeNumber) != NDIS_STATUS_SUCCESS)
-					||
-					(RTMPFreeTXDRequest
-					 (pAd, QID_MGMT, MGMT_RING_SIZE - 1,
-					  &FreeNumber) !=
-					 NDIS_STATUS_SUCCESS)) {
-					/* TODO: consider scheduled HCCA. might not be proper to use traditional DTIM-based power-saving scheme */
-					/* can we cheat here (i.e. just check MGMT & AC_BE) for better performance? */
-#ifdef RTMP_MAC_PCI
-					if (OPSTATUS_TEST_FLAG
-					    (pAd, fOP_STATUS_PCIE_DEVICE)) {
-						if (pAd->Antenna.field.RxPath >
-						    1)
-							RTMP_BBP_IO_WRITE8_BY_REG_ID
-							    (pAd, BBP_R3,
-							     pAd->StaCfg.BBPR3);
-					}
-#endif /* RTMP_MAC_PCI // */
-				} else {
-					if ((pAd->CommonCfg.
-					     bACMAPSDTr[QID_AC_VO])
-					    || (pAd->CommonCfg.
-						bACMAPSDTr[QID_AC_VI])
-					    || (pAd->CommonCfg.
-						bACMAPSDTr[QID_AC_BK])
-					    || (pAd->CommonCfg.
-						bACMAPSDTr[QID_AC_BE])) {
-						/*
-						   WMM Spec v1.0 3.6.2.4,
-						   The WMM STA shall remain awake until it receives a
-						   QoS Data or Null frame addressed to it, with the
-						   EOSP subfield in QoS Control field set to 1.
-
-						   So we can not sleep here or we will suffer a case:
-
-						   PS Management Frame -->
-						   Trigger frame -->
-						   Beacon (TIM=0) (Beacon is closer to Trig frame) -->
-						   Station goes to sleep -->
-						   AP delivery queued UAPSD packets -->
-						   Station can NOT receive the reply
-
-						   Maybe we need a timeout timer to avoid that we do
-						   NOT receive the EOSP frame.
-
-						   We can not use More Data to check if SP is ended
-						   due to MaxSPLength.
-						 */
-					} else {
-						u16 NextDtim = DtimCount;
-
-						if (NextDtim == 0)
-							NextDtim = DtimPeriod;
-
-						TbttNumToNextWakeUp =
-						    pAd->StaCfg.
-						    DefaultListenCount;
-						if (OPSTATUS_TEST_FLAG
-						    (pAd,
-						     fOP_STATUS_RECEIVE_DTIM)
-						    && (TbttNumToNextWakeUp >
-							NextDtim))
-							TbttNumToNextWakeUp =
-							    NextDtim;
-
-						if (!OPSTATUS_TEST_FLAG
-						    (pAd, fOP_STATUS_DOZE)) {
-							/* Set a flag to go to sleep . Then after parse this RxDoneInterrupt, will go to sleep mode. */
-							pAd->
-							    ThisTbttNumToNextWakeUp
-							    =
-							    TbttNumToNextWakeUp;
-							AsicSleepThenAutoWakeup
-							    (pAd,
-							     pAd->
-							     ThisTbttNumToNextWakeUp);
-						}
-					}
-				}
-			}
-		}
-		/* not my BSSID, ignore it */
-	}
-	/* sanity check fail, ignore this frame */
-}
-
-/*
-	==========================================================================
-	Description:
-		Receive PROBE REQ from remote peer when operating in IBSS mode
-	==========================================================================
- */
-void PeerProbeReqAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
-{
-	u8 Addr2[MAC_ADDR_LEN];
-	char Ssid[MAX_LEN_OF_SSID];
-	u8 SsidLen;
-	u8 HtLen, AddHtLen, NewExtLen;
-	struct rt_header_802_11 ProbeRspHdr;
-	int NStatus;
-	u8 *pOutBuffer = NULL;
-	unsigned long FrameLen = 0;
-	LARGE_INTEGER FakeTimestamp;
-	u8 DsLen = 1, IbssLen = 2;
-	u8 LocalErpIe[3] = { IE_ERP, 1, 0 };
-	BOOLEAN Privacy;
-	u16 CapabilityInfo;
-	u8 RSNIe = IE_WPA;
-
-	if (!ADHOC_ON(pAd))
-		return;
-
-	if (PeerProbeReqSanity
-	    (pAd, Elem->Msg, Elem->MsgLen, Addr2, Ssid, &SsidLen)) {
-		if ((SsidLen == 0)
-		    || SSID_EQUAL(Ssid, SsidLen, pAd->CommonCfg.Ssid,
-				  pAd->CommonCfg.SsidLen)) {
-			/* allocate and send out ProbeRsp frame */
-			NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);	/*Get an unused nonpaged memory */
-			if (NStatus != NDIS_STATUS_SUCCESS)
-				return;
-
-			/*pAd->StaCfg.AtimWin = 0;  // ?????? */
-
-			Privacy =
-			    (pAd->StaCfg.WepStatus ==
-			     Ndis802_11Encryption1Enabled)
-			    || (pAd->StaCfg.WepStatus ==
-				Ndis802_11Encryption2Enabled)
-			    || (pAd->StaCfg.WepStatus ==
-				Ndis802_11Encryption3Enabled);
-			CapabilityInfo =
-			    CAP_GENERATE(0, 1, Privacy,
-					 (pAd->CommonCfg.TxPreamble ==
-					  Rt802_11PreambleShort), 0, 0);
-
-			MakeOutgoingFrame(pOutBuffer, &FrameLen,
-					  sizeof(struct rt_header_802_11), &ProbeRspHdr,
-					  TIMESTAMP_LEN, &FakeTimestamp,
-					  2, &pAd->CommonCfg.BeaconPeriod,
-					  2, &CapabilityInfo,
-					  1, &SsidIe,
-					  1, &pAd->CommonCfg.SsidLen,
-					  pAd->CommonCfg.SsidLen,
-					  pAd->CommonCfg.Ssid, 1, &SupRateIe, 1,
-					  &pAd->StaActive.SupRateLen,
-					  pAd->StaActive.SupRateLen,
-					  pAd->StaActive.SupRate, 1, &DsIe, 1,
-					  &DsLen, 1, &pAd->CommonCfg.Channel, 1,
-					  &IbssIe, 1, &IbssLen, 2,
-					  &pAd->StaActive.AtimWin, END_OF_ARGS);
-
-			if (pAd->StaActive.ExtRateLen) {
-				unsigned long tmp;
-				MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp,
-						  3, LocalErpIe,
-						  1, &ExtRateIe,
-						  1, &pAd->StaActive.ExtRateLen,
-						  pAd->StaActive.ExtRateLen,
-						  &pAd->StaActive.ExtRate,
-						  END_OF_ARGS);
-				FrameLen += tmp;
-			}
-			/* If adhoc secruity is set for WPA-None, append the cipher suite IE */
-			if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPANone) {
-				unsigned long tmp;
-				MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp,
-						  1, &RSNIe,
-						  1, &pAd->StaCfg.RSNIE_Len,
-						  pAd->StaCfg.RSNIE_Len,
-						  pAd->StaCfg.RSN_IE,
-						  END_OF_ARGS);
-				FrameLen += tmp;
-			}
-
-			if (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED) {
-				unsigned long TmpLen;
-				u8 BROADCOM[4] = { 0x0, 0x90, 0x4c, 0x33 };
-				HtLen = sizeof(pAd->CommonCfg.HtCapability);
-				AddHtLen = sizeof(pAd->CommonCfg.AddHTInfo);
-				NewExtLen = 1;
-				/*New extension channel offset IE is included in Beacon, Probe Rsp or channel Switch Announcement Frame */
-				if (pAd->bBroadComHT == TRUE) {
-					MakeOutgoingFrame(pOutBuffer + FrameLen,
-							  &TmpLen, 1, &WpaIe, 4,
-							  &BROADCOM[0],
-							  pAd->MlmeAux.
-							  HtCapabilityLen,
-							  &pAd->MlmeAux.
-							  HtCapability,
-							  END_OF_ARGS);
-				} else {
-					MakeOutgoingFrame(pOutBuffer + FrameLen,
-							  &TmpLen, 1, &HtCapIe,
-							  1, &HtLen,
-							  sizeof
-							  (struct rt_ht_capability_ie),
-							  &pAd->CommonCfg.
-							  HtCapability, 1,
-							  &AddHtInfoIe, 1,
-							  &AddHtLen,
-							  sizeof
-							  (struct rt_add_ht_info_ie),
-							  &pAd->CommonCfg.
-							  AddHTInfo, 1,
-							  &NewExtChanIe, 1,
-							  &NewExtLen,
-							  sizeof
-							  (struct rt_new_ext_chan_ie),
-							  &pAd->CommonCfg.
-							  NewExtChanOffset,
-							  END_OF_ARGS);
-				}
-				FrameLen += TmpLen;
-			}
-
-			MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
-			MlmeFreeMemory(pAd, pOutBuffer);
-		}
-	}
-}
-
-void BeaconTimeoutAtJoinAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
-{
-	u16 Status;
-	DBGPRINT(RT_DEBUG_TRACE, ("SYNC - BeaconTimeoutAtJoinAction\n"));
-	pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
-	Status = MLME_REJ_TIMEOUT;
-	MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_JOIN_CONF, 2, &Status);
-}
-
-/*
-	==========================================================================
-	Description:
-		Scan timeout procedure. basically add channel index by 1 and rescan
-	==========================================================================
- */
-void ScanTimeoutAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
-{
-	pAd->MlmeAux.Channel = NextChannel(pAd, pAd->MlmeAux.Channel);
-
-	/* Only one channel scanned for CISCO beacon request */
-	if ((pAd->MlmeAux.ScanType == SCAN_CISCO_ACTIVE) ||
-	    (pAd->MlmeAux.ScanType == SCAN_CISCO_PASSIVE) ||
-	    (pAd->MlmeAux.ScanType == SCAN_CISCO_NOISE) ||
-	    (pAd->MlmeAux.ScanType == SCAN_CISCO_CHANNEL_LOAD))
-		pAd->MlmeAux.Channel = 0;
-
-	/* this routine will stop if pAd->MlmeAux.Channel == 0 */
-	ScanNextChannel(pAd);
-}
-
-/*
-	==========================================================================
-	Description:
-	==========================================================================
- */
-void InvalidStateWhenScan(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
-{
-	u16 Status;
-	DBGPRINT(RT_DEBUG_TRACE,
-		 ("AYNC - InvalidStateWhenScan(state=%ld). Reset SYNC machine\n",
-		  pAd->Mlme.SyncMachine.CurrState));
-	pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
-	Status = MLME_STATE_MACHINE_REJECT;
-	MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_SCAN_CONF, 2, &Status);
-}
-
-/*
-	==========================================================================
-	Description:
-	==========================================================================
- */
-void InvalidStateWhenJoin(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
-{
-	u16 Status;
-	DBGPRINT(RT_DEBUG_TRACE,
-		 ("InvalidStateWhenJoin(state=%ld). Reset SYNC machine\n",
-		  pAd->Mlme.SyncMachine.CurrState));
-	pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
-	Status = MLME_STATE_MACHINE_REJECT;
-	MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_JOIN_CONF, 2, &Status);
-}
-
-/*
-	==========================================================================
-	Description:
-	==========================================================================
- */
-void InvalidStateWhenStart(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
-{
-	u16 Status;
-	DBGPRINT(RT_DEBUG_TRACE,
-		 ("InvalidStateWhenStart(state=%ld). Reset SYNC machine\n",
-		  pAd->Mlme.SyncMachine.CurrState));
-	pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
-	Status = MLME_STATE_MACHINE_REJECT;
-	MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_START_CONF, 2, &Status);
-}
-
-/*
-	==========================================================================
-	Description:
-
-	IRQL = DISPATCH_LEVEL
-
-	==========================================================================
- */
-void EnqueuePsPoll(struct rt_rtmp_adapter *pAd)
-{
-
-	if (pAd->StaCfg.WindowsPowerMode == Ndis802_11PowerModeLegacy_PSP)
-		pAd->PsPollFrame.FC.PwrMgmt = PWR_SAVE;
-	MiniportMMRequest(pAd, 0, (u8 *)& pAd->PsPollFrame,
-			  sizeof(struct rt_pspoll_frame));
-}
-
-/*
-	==========================================================================
-	Description:
-	==========================================================================
- */
-void EnqueueProbeRequest(struct rt_rtmp_adapter *pAd)
-{
-	int NState;
-	u8 *pOutBuffer;
-	unsigned long FrameLen = 0;
-	struct rt_header_802_11 Hdr80211;
-
-	DBGPRINT(RT_DEBUG_TRACE, ("force out a ProbeRequest ...\n"));
-
-	NState = MlmeAllocateMemory(pAd, &pOutBuffer);	/*Get an unused nonpaged memory */
-	if (NState == NDIS_STATUS_SUCCESS) {
-		MgtMacHeaderInit(pAd, &Hdr80211, SUBTYPE_PROBE_REQ, 0,
-				 BROADCAST_ADDR, BROADCAST_ADDR);
-
-		/* this ProbeRequest explicitly specify SSID to reduce unwanted ProbeResponse */
-		MakeOutgoingFrame(pOutBuffer, &FrameLen,
-				  sizeof(struct rt_header_802_11), &Hdr80211,
-				  1, &SsidIe,
-				  1, &pAd->CommonCfg.SsidLen,
-				  pAd->CommonCfg.SsidLen, pAd->CommonCfg.Ssid,
-				  1, &SupRateIe,
-				  1, &pAd->StaActive.SupRateLen,
-				  pAd->StaActive.SupRateLen,
-				  pAd->StaActive.SupRate, END_OF_ARGS);
-		MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
-		MlmeFreeMemory(pAd, pOutBuffer);
-	}
-
-}
-
-BOOLEAN ScanRunning(struct rt_rtmp_adapter *pAd)
-{
-	return (pAd->Mlme.SyncMachine.CurrState == SCAN_LISTEN) ? TRUE : FALSE;
-}
diff -druN linux-2.6.39-libre/drivers/staging/rt2860/sta/wpa.c linux-3.0-rc7-libre/drivers/staging/rt2860/sta/wpa.c
--- linux-2.6.39-libre/drivers/staging/rt2860/sta/wpa.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rt2860/sta/wpa.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,374 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, 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.             *
- *                                                                       *
- *************************************************************************
-
-	Module Name:
-	wpa.c
-
-	Abstract:
-
-	Revision History:
-	Who			When			What
-	--------	----------		----------------------------------------------
-	Jan	Lee		03-07-22		Initial
-	Paul Lin		03-11-28		Modify for supplicant
-	Justin P. Mattock	11/07/2010		Fix typos
-*/
-#include "../rt_config.h"
-
-void inc_byte_array(u8 * counter, int len);
-
-/*
-	========================================================================
-
-	Routine Description:
-		Process MIC error indication and record MIC error timer.
-
-	Arguments:
-		pAd 	Pointer to our adapter
-		pWpaKey 		Pointer to the WPA key structure
-
-	Return Value:
-		None
-
-	IRQL = DISPATCH_LEVEL
-
-	Note:
-
-	========================================================================
-*/
-void RTMPReportMicError(struct rt_rtmp_adapter *pAd, struct rt_cipher_key *pWpaKey)
-{
-	unsigned long Now;
-	u8 unicastKey = (pWpaKey->Type == PAIRWISE_KEY ? 1 : 0);
-
-	/* Record Last MIC error time and count */
-	NdisGetSystemUpTime(&Now);
-	if (pAd->StaCfg.MicErrCnt == 0) {
-		pAd->StaCfg.MicErrCnt++;
-		pAd->StaCfg.LastMicErrorTime = Now;
-		NdisZeroMemory(pAd->StaCfg.ReplayCounter, 8);
-	} else if (pAd->StaCfg.MicErrCnt == 1) {
-		if ((pAd->StaCfg.LastMicErrorTime + (60 * OS_HZ)) < Now) {
-			/* Update Last MIC error time, this did not violate two MIC errors within 60 seconds */
-			pAd->StaCfg.LastMicErrorTime = Now;
-		} else {
-
-			if (pAd->CommonCfg.bWirelessEvent)
-				RTMPSendWirelessEvent(pAd,
-						      IW_COUNTER_MEASURES_EVENT_FLAG,
-						      pAd->MacTab.
-						      Content[BSSID_WCID].Addr,
-						      BSS0, 0);
-
-			pAd->StaCfg.LastMicErrorTime = Now;
-			/* Violate MIC error counts, MIC countermeasures kicks in */
-			pAd->StaCfg.MicErrCnt++;
-			/* We shall block all reception */
-			/* We shall clean all Tx ring and disassociate from AP after next EAPOL frame */
-			/* */
-			/* No necessary to clean all Tx ring, on RTMPHardTransmit will stop sending non-802.1X EAPOL packets */
-			/* if pAd->StaCfg.MicErrCnt greater than 2. */
-			/* */
-			/* RTMPRingCleanUp(pAd, QID_AC_BK); */
-			/* RTMPRingCleanUp(pAd, QID_AC_BE); */
-			/* RTMPRingCleanUp(pAd, QID_AC_VI); */
-			/* RTMPRingCleanUp(pAd, QID_AC_VO); */
-			/* RTMPRingCleanUp(pAd, QID_HCCA); */
-		}
-	} else {
-		/* MIC error count >= 2 */
-		/* This should not happen */
-		;
-	}
-	MlmeEnqueue(pAd,
-		    MLME_CNTL_STATE_MACHINE,
-		    OID_802_11_MIC_FAILURE_REPORT_FRAME, 1, &unicastKey);
-
-	if (pAd->StaCfg.MicErrCnt == 2) {
-		RTMPSetTimer(&pAd->StaCfg.WpaDisassocAndBlockAssocTimer, 100);
-	}
-}
-
-#define	LENGTH_EAP_H    4
-/* If the received frame is EAP-Packet ,find out its EAP-Code (Request(0x01), Response(0x02), Success(0x03), Failure(0x04)). */
-int WpaCheckEapCode(struct rt_rtmp_adapter *pAd,
-		    u8 *pFrame, u16 FrameLen, u16 OffSet)
-{
-
-	u8 *pData;
-	int result = 0;
-
-	if (FrameLen < OffSet + LENGTH_EAPOL_H + LENGTH_EAP_H)
-		return result;
-
-	pData = pFrame + OffSet;	/* skip offset bytes */
-
-	if (*(pData + 1) == EAPPacket)	/* 802.1x header - Packet Type */
-	{
-		result = *(pData + 4);	/* EAP header - Code */
-	}
-
-	return result;
-}
-
-void WpaSendMicFailureToWpaSupplicant(struct rt_rtmp_adapter *pAd, IN BOOLEAN bUnicast)
-{
-	char custom[IW_CUSTOM_MAX] = { 0 };
-
-	sprintf(custom, "MLME-MICHAELMICFAILURE.indication");
-	if (bUnicast)
-		sprintf(custom, "%s unicast", custom);
-
-	RtmpOSWrielessEventSend(pAd, IWEVCUSTOM, -1, NULL, (u8 *)custom,
-				strlen(custom));
-
-	return;
-}
-
-void WpaMicFailureReportFrame(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem)
-{
-	u8 *pOutBuffer = NULL;
-	u8 Header802_3[14];
-	unsigned long FrameLen = 0;
-	struct rt_eapol_packet Packet;
-	u8 Mic[16];
-	BOOLEAN bUnicast;
-
-	DBGPRINT(RT_DEBUG_TRACE, ("WpaMicFailureReportFrame ----->\n"));
-
-	bUnicast = (Elem->Msg[0] == 1 ? TRUE : FALSE);
-	pAd->Sequence = ((pAd->Sequence) + 1) & (MAX_SEQ_NUMBER);
-
-	/* init 802.3 header and Fill Packet */
-	MAKE_802_3_HEADER(Header802_3, pAd->CommonCfg.Bssid,
-			  pAd->CurrentAddress, EAPOL);
-
-	NdisZeroMemory(&Packet, sizeof(Packet));
-	Packet.ProVer = EAPOL_VER;
-	Packet.ProType = EAPOLKey;
-
-	Packet.KeyDesc.Type = WPA1_KEY_DESC;
-
-	/* Request field presented */
-	Packet.KeyDesc.KeyInfo.Request = 1;
-
-	if (pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled) {
-		Packet.KeyDesc.KeyInfo.KeyDescVer = 2;
-	} else			/* TKIP */
-	{
-		Packet.KeyDesc.KeyInfo.KeyDescVer = 1;
-	}
-
-	Packet.KeyDesc.KeyInfo.KeyType = (bUnicast ? PAIRWISEKEY : GROUPKEY);
-
-	/* KeyMic field presented */
-	Packet.KeyDesc.KeyInfo.KeyMic = 1;
-
-	/* Error field presented */
-	Packet.KeyDesc.KeyInfo.Error = 1;
-
-	/* Update packet length after decide Key data payload */
-	SET_u16_TO_ARRARY(Packet.Body_Len, LEN_EAPOL_KEY_MSG)
-	    /* Key Replay Count */
-	    NdisMoveMemory(Packet.KeyDesc.ReplayCounter,
-			   pAd->StaCfg.ReplayCounter, LEN_KEY_DESC_REPLAY);
-	inc_byte_array(pAd->StaCfg.ReplayCounter, 8);
-
-	/* Convert to little-endian format. */
-	*((u16 *) & Packet.KeyDesc.KeyInfo) =
-	    cpu2le16(*((u16 *) & Packet.KeyDesc.KeyInfo));
-
-	MlmeAllocateMemory(pAd, (u8 **) & pOutBuffer);	/* allocate memory */
-	if (pOutBuffer == NULL) {
-		return;
-	}
-	/* Prepare EAPOL frame for MIC calculation */
-	/* Be careful, only EAPOL frame is counted for MIC calculation */
-	MakeOutgoingFrame(pOutBuffer, &FrameLen,
-			  CONV_ARRARY_TO_u16(Packet.Body_Len) + 4, &Packet,
-			  END_OF_ARGS);
-
-	/* Prepare and Fill MIC value */
-	NdisZeroMemory(Mic, sizeof(Mic));
-	if (pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled) {	/* AES */
-		u8 digest[20] = { 0 };
-		HMAC_SHA1(pAd->StaCfg.PTK, LEN_EAP_MICK, pOutBuffer, FrameLen,
-			  digest, SHA1_DIGEST_SIZE);
-		NdisMoveMemory(Mic, digest, LEN_KEY_DESC_MIC);
-	} else {		/* TKIP */
-		HMAC_MD5(pAd->StaCfg.PTK, LEN_EAP_MICK, pOutBuffer, FrameLen,
-			 Mic, MD5_DIGEST_SIZE);
-	}
-	NdisMoveMemory(Packet.KeyDesc.KeyMic, Mic, LEN_KEY_DESC_MIC);
-
-	/* copy frame to Tx ring and send MIC failure report frame to authenticator */
-	RTMPToWirelessSta(pAd, &pAd->MacTab.Content[BSSID_WCID],
-			  Header802_3, LENGTH_802_3,
-			  (u8 *)& Packet,
-			  CONV_ARRARY_TO_u16(Packet.Body_Len) + 4, FALSE);
-
-	MlmeFreeMemory(pAd, (u8 *)pOutBuffer);
-
-	DBGPRINT(RT_DEBUG_TRACE, ("WpaMicFailureReportFrame <-----\n"));
-}
-
-/** from wpa_supplicant
- * inc_byte_array - Increment arbitrary length byte array by one
- * @counter: Pointer to byte array
- * @len: Length of the counter in bytes
- *
- * This function increments the last byte of the counter by one and continues
- * rolling over to more significant bytes if the byte was incremented from
- * 0xff to 0x00.
- */
-void inc_byte_array(u8 * counter, int len)
-{
-	int pos = len - 1;
-	while (pos >= 0) {
-		counter[pos]++;
-		if (counter[pos] != 0)
-			break;
-		pos--;
-	}
-}
-
-void WpaDisassocApAndBlockAssoc(void *SystemSpecific1,
-				void *FunctionContext,
-				void *SystemSpecific2,
-				void *SystemSpecific3)
-{
-	struct rt_rtmp_adapter *pAd = (struct rt_rtmp_adapter *)FunctionContext;
-	struct rt_mlme_disassoc_req DisassocReq;
-
-	/* disassoc from current AP first */
-	DBGPRINT(RT_DEBUG_TRACE,
-		 ("RTMPReportMicError - disassociate with current AP after sending second continuous EAPOL frame\n"));
-	DisassocParmFill(pAd, &DisassocReq, pAd->CommonCfg.Bssid,
-			 REASON_MIC_FAILURE);
-	MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_DISASSOC_REQ,
-		    sizeof(struct rt_mlme_disassoc_req), &DisassocReq);
-
-	pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_DISASSOC;
-	pAd->StaCfg.bBlockAssoc = TRUE;
-}
-
-void WpaStaPairwiseKeySetting(struct rt_rtmp_adapter *pAd)
-{
-	struct rt_cipher_key *pSharedKey;
-	struct rt_mac_table_entry *pEntry;
-
-	pEntry = &pAd->MacTab.Content[BSSID_WCID];
-
-	/* Pairwise key shall use key#0 */
-	pSharedKey = &pAd->SharedKey[BSS0][0];
-
-	NdisMoveMemory(pAd->StaCfg.PTK, pEntry->PTK, LEN_PTK);
-
-	/* Prepare pair-wise key information into shared key table */
-	NdisZeroMemory(pSharedKey, sizeof(struct rt_cipher_key));
-	pSharedKey->KeyLen = LEN_TKIP_EK;
-	NdisMoveMemory(pSharedKey->Key, &pAd->StaCfg.PTK[32], LEN_TKIP_EK);
-	NdisMoveMemory(pSharedKey->RxMic, &pAd->StaCfg.PTK[48],
-		       LEN_TKIP_RXMICK);
-	NdisMoveMemory(pSharedKey->TxMic,
-		       &pAd->StaCfg.PTK[48 + LEN_TKIP_RXMICK], LEN_TKIP_TXMICK);
-
-	/* Decide its ChiperAlg */
-	if (pAd->StaCfg.PairCipher == Ndis802_11Encryption2Enabled)
-		pSharedKey->CipherAlg = CIPHER_TKIP;
-	else if (pAd->StaCfg.PairCipher == Ndis802_11Encryption3Enabled)
-		pSharedKey->CipherAlg = CIPHER_AES;
-	else
-		pSharedKey->CipherAlg = CIPHER_NONE;
-
-	/* Update these related information to struct rt_mac_table_entry */
-	NdisMoveMemory(pEntry->PairwiseKey.Key, &pAd->StaCfg.PTK[32],
-		       LEN_TKIP_EK);
-	NdisMoveMemory(pEntry->PairwiseKey.RxMic, &pAd->StaCfg.PTK[48],
-		       LEN_TKIP_RXMICK);
-	NdisMoveMemory(pEntry->PairwiseKey.TxMic,
-		       &pAd->StaCfg.PTK[48 + LEN_TKIP_RXMICK], LEN_TKIP_TXMICK);
-	pEntry->PairwiseKey.CipherAlg = pSharedKey->CipherAlg;
-
-	/* Update pairwise key information to ASIC Shared Key Table */
-	AsicAddSharedKeyEntry(pAd,
-			      BSS0,
-			      0,
-			      pSharedKey->CipherAlg,
-			      pSharedKey->Key,
-			      pSharedKey->TxMic, pSharedKey->RxMic);
-
-	/* Update ASIC WCID attribute table and IVEIV table */
-	RTMPAddWcidAttributeEntry(pAd, BSS0, 0, pSharedKey->CipherAlg, pEntry);
-	STA_PORT_SECURED(pAd);
-	pAd->IndicateMediaState = NdisMediaStateConnected;
-
-	DBGPRINT(RT_DEBUG_TRACE,
-		 ("%s : AID(%d) port secured\n", __func__, pEntry->Aid));
-
-}
-
-void WpaStaGroupKeySetting(struct rt_rtmp_adapter *pAd)
-{
-	struct rt_cipher_key *pSharedKey;
-
-	pSharedKey = &pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId];
-
-	/* Prepare pair-wise key information into shared key table */
-	NdisZeroMemory(pSharedKey, sizeof(struct rt_cipher_key));
-	pSharedKey->KeyLen = LEN_TKIP_EK;
-	NdisMoveMemory(pSharedKey->Key, pAd->StaCfg.GTK, LEN_TKIP_EK);
-	NdisMoveMemory(pSharedKey->RxMic, &pAd->StaCfg.GTK[16],
-		       LEN_TKIP_RXMICK);
-	NdisMoveMemory(pSharedKey->TxMic, &pAd->StaCfg.GTK[24],
-		       LEN_TKIP_TXMICK);
-
-	/* Update Shared Key CipherAlg */
-	pSharedKey->CipherAlg = CIPHER_NONE;
-	if (pAd->StaCfg.GroupCipher == Ndis802_11Encryption2Enabled)
-		pSharedKey->CipherAlg = CIPHER_TKIP;
-	else if (pAd->StaCfg.GroupCipher == Ndis802_11Encryption3Enabled)
-		pSharedKey->CipherAlg = CIPHER_AES;
-	else if (pAd->StaCfg.GroupCipher == Ndis802_11GroupWEP40Enabled)
-		pSharedKey->CipherAlg = CIPHER_WEP64;
-	else if (pAd->StaCfg.GroupCipher == Ndis802_11GroupWEP104Enabled)
-		pSharedKey->CipherAlg = CIPHER_WEP128;
-
-	/* Update group key information to ASIC Shared Key Table */
-	AsicAddSharedKeyEntry(pAd,
-			      BSS0,
-			      pAd->StaCfg.DefaultKeyId,
-			      pSharedKey->CipherAlg,
-			      pSharedKey->Key,
-			      pSharedKey->TxMic, pSharedKey->RxMic);
-
-	/* Update ASIC WCID attribute table and IVEIV table */
-	RTMPAddWcidAttributeEntry(pAd,
-				  BSS0,
-				  pAd->StaCfg.DefaultKeyId,
-				  pSharedKey->CipherAlg, NULL);
-
-}
diff -druN linux-2.6.39-libre/drivers/staging/rt2860/sta_ioctl.c linux-3.0-rc7-libre/drivers/staging/rt2860/sta_ioctl.c
--- linux-2.6.39-libre/drivers/staging/rt2860/sta_ioctl.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rt2860/sta_ioctl.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,2912 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, 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.             *
- *                                                                       *
- *************************************************************************
-
-    Module Name:
-    sta_ioctl.c
-
-    Abstract:
-    IOCTL related subroutines
-
-    Revision History:
-    	Who        		 When          What
-    --------    ----------    ----------------------------------------------
-   	Rory Chen   		01-03-2003    	created
-	Rory Chen   		02-14-2005    	modify to support RT61
-	Justin P. Mattock	11/07/2010	Fix typos
-*/
-
-#include	"rt_config.h"
-
-#ifdef DBG
-extern unsigned long RTDebugLevel;
-#endif
-
-#define NR_WEP_KEYS 				4
-#define WEP_SMALL_KEY_LEN 			(40/8)
-#define WEP_LARGE_KEY_LEN 			(104/8)
-
-#define GROUP_KEY_NO                4
-
-extern u8 CipherWpa2Template[];
-
-struct PACKED rt_version_info {
-	u8 DriverVersionW;
-	u8 DriverVersionX;
-	u8 DriverVersionY;
-	u8 DriverVersionZ;
-	u32 DriverBuildYear;
-	u32 DriverBuildMonth;
-	u32 DriverBuildDay;
-};
-
-static __s32 ralinkrate[] = { 2, 4, 11, 22,	/* CCK */
-	12, 18, 24, 36, 48, 72, 96, 108,	/* OFDM */
-	13, 26, 39, 52, 78, 104, 117, 130, 26, 52, 78, 104, 156, 208, 234, 260,	/* 20MHz, 800ns GI, MCS: 0 ~ 15 */
-	39, 78, 117, 156, 234, 312, 351, 390,	/* 20MHz, 800ns GI, MCS: 16 ~ 23 */
-	27, 54, 81, 108, 162, 216, 243, 270, 54, 108, 162, 216, 324, 432, 486, 540,	/* 40MHz, 800ns GI, MCS: 0 ~ 15 */
-	81, 162, 243, 324, 486, 648, 729, 810,	/* 40MHz, 800ns GI, MCS: 16 ~ 23 */
-	14, 29, 43, 57, 87, 115, 130, 144, 29, 59, 87, 115, 173, 230, 260, 288,	/* 20MHz, 400ns GI, MCS: 0 ~ 15 */
-	43, 87, 130, 173, 260, 317, 390, 433,	/* 20MHz, 400ns GI, MCS: 16 ~ 23 */
-	30, 60, 90, 120, 180, 240, 270, 300, 60, 120, 180, 240, 360, 480, 540, 600,	/* 40MHz, 400ns GI, MCS: 0 ~ 15 */
-	90, 180, 270, 360, 540, 720, 810, 900
-};
-
-int Set_SSID_Proc(struct rt_rtmp_adapter *pAdapter, char *arg);
-
-int Set_NetworkType_Proc(struct rt_rtmp_adapter *pAdapter, char *arg);
-
-void RTMPAddKey(struct rt_rtmp_adapter *pAd, struct rt_ndis_802_11_key *pKey)
-{
-	unsigned long KeyIdx;
-	struct rt_mac_table_entry *pEntry;
-
-	DBGPRINT(RT_DEBUG_TRACE, ("RTMPAddKey ------>\n"));
-
-	if (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA) {
-		if (pKey->KeyIndex & 0x80000000) {
-			if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPANone) {
-				NdisZeroMemory(pAd->StaCfg.PMK, 32);
-				NdisMoveMemory(pAd->StaCfg.PMK,
-					       pKey->KeyMaterial,
-					       pKey->KeyLength);
-				goto end;
-			}
-			/* Update PTK */
-			NdisZeroMemory(&pAd->SharedKey[BSS0][0],
-				       sizeof(struct rt_cipher_key));
-			pAd->SharedKey[BSS0][0].KeyLen = LEN_TKIP_EK;
-			NdisMoveMemory(pAd->SharedKey[BSS0][0].Key,
-				       pKey->KeyMaterial, LEN_TKIP_EK);
-
-			if (pAd->StaCfg.PairCipher ==
-			    Ndis802_11Encryption2Enabled) {
-				NdisMoveMemory(pAd->SharedKey[BSS0][0].RxMic,
-					       pKey->KeyMaterial + LEN_TKIP_EK,
-					       LEN_TKIP_TXMICK);
-				NdisMoveMemory(pAd->SharedKey[BSS0][0].TxMic,
-					       pKey->KeyMaterial + LEN_TKIP_EK +
-					       LEN_TKIP_TXMICK,
-					       LEN_TKIP_RXMICK);
-			} else {
-				NdisMoveMemory(pAd->SharedKey[BSS0][0].TxMic,
-					       pKey->KeyMaterial + LEN_TKIP_EK,
-					       LEN_TKIP_TXMICK);
-				NdisMoveMemory(pAd->SharedKey[BSS0][0].RxMic,
-					       pKey->KeyMaterial + LEN_TKIP_EK +
-					       LEN_TKIP_TXMICK,
-					       LEN_TKIP_RXMICK);
-			}
-
-			/* Decide its ChiperAlg */
-			if (pAd->StaCfg.PairCipher ==
-			    Ndis802_11Encryption2Enabled)
-				pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_TKIP;
-			else if (pAd->StaCfg.PairCipher ==
-				 Ndis802_11Encryption3Enabled)
-				pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_AES;
-			else
-				pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_NONE;
-
-			/* Update these related information to struct rt_mac_table_entry */
-			pEntry = &pAd->MacTab.Content[BSSID_WCID];
-			NdisMoveMemory(pEntry->PairwiseKey.Key,
-				       pAd->SharedKey[BSS0][0].Key,
-				       LEN_TKIP_EK);
-			NdisMoveMemory(pEntry->PairwiseKey.RxMic,
-				       pAd->SharedKey[BSS0][0].RxMic,
-				       LEN_TKIP_RXMICK);
-			NdisMoveMemory(pEntry->PairwiseKey.TxMic,
-				       pAd->SharedKey[BSS0][0].TxMic,
-				       LEN_TKIP_TXMICK);
-			pEntry->PairwiseKey.CipherAlg =
-			    pAd->SharedKey[BSS0][0].CipherAlg;
-
-			/* Update pairwise key information to ASIC Shared Key Table */
-			AsicAddSharedKeyEntry(pAd,
-					      BSS0,
-					      0,
-					      pAd->SharedKey[BSS0][0].CipherAlg,
-					      pAd->SharedKey[BSS0][0].Key,
-					      pAd->SharedKey[BSS0][0].TxMic,
-					      pAd->SharedKey[BSS0][0].RxMic);
-
-			/* Update ASIC WCID attribute table and IVEIV table */
-			RTMPAddWcidAttributeEntry(pAd,
-						  BSS0,
-						  0,
-						  pAd->SharedKey[BSS0][0].
-						  CipherAlg, pEntry);
-
-			if (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA2) {
-				/* set 802.1x port control */
-				/*pAd->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED; */
-				STA_PORT_SECURED(pAd);
-
-				/* Indicate Connected for GUI */
-				pAd->IndicateMediaState =
-				    NdisMediaStateConnected;
-			}
-		} else {
-			/* Update GTK */
-			pAd->StaCfg.DefaultKeyId = (pKey->KeyIndex & 0xFF);
-			NdisZeroMemory(&pAd->
-				       SharedKey[BSS0][pAd->StaCfg.
-						       DefaultKeyId],
-				       sizeof(struct rt_cipher_key));
-			pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].KeyLen =
-			    LEN_TKIP_EK;
-			NdisMoveMemory(pAd->
-				       SharedKey[BSS0][pAd->StaCfg.
-						       DefaultKeyId].Key,
-				       pKey->KeyMaterial, LEN_TKIP_EK);
-
-			if (pAd->StaCfg.GroupCipher ==
-			    Ndis802_11Encryption2Enabled) {
-				NdisMoveMemory(pAd->
-					       SharedKey[BSS0][pAd->StaCfg.
-							       DefaultKeyId].
-					       RxMic,
-					       pKey->KeyMaterial + LEN_TKIP_EK,
-					       LEN_TKIP_TXMICK);
-				NdisMoveMemory(pAd->
-					       SharedKey[BSS0][pAd->StaCfg.
-							       DefaultKeyId].
-					       TxMic,
-					       pKey->KeyMaterial + LEN_TKIP_EK +
-					       LEN_TKIP_TXMICK,
-					       LEN_TKIP_RXMICK);
-			} else {
-				NdisMoveMemory(pAd->
-					       SharedKey[BSS0][pAd->StaCfg.
-							       DefaultKeyId].
-					       TxMic,
-					       pKey->KeyMaterial + LEN_TKIP_EK,
-					       LEN_TKIP_TXMICK);
-				NdisMoveMemory(pAd->
-					       SharedKey[BSS0][pAd->StaCfg.
-							       DefaultKeyId].
-					       RxMic,
-					       pKey->KeyMaterial + LEN_TKIP_EK +
-					       LEN_TKIP_TXMICK,
-					       LEN_TKIP_RXMICK);
-			}
-
-			/* Update Shared Key CipherAlg */
-			pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].
-			    CipherAlg = CIPHER_NONE;
-			if (pAd->StaCfg.GroupCipher ==
-			    Ndis802_11Encryption2Enabled)
-				pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].
-				    CipherAlg = CIPHER_TKIP;
-			else if (pAd->StaCfg.GroupCipher ==
-				 Ndis802_11Encryption3Enabled)
-				pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].
-				    CipherAlg = CIPHER_AES;
-
-			/* Update group key information to ASIC Shared Key Table */
-			AsicAddSharedKeyEntry(pAd,
-					      BSS0,
-					      pAd->StaCfg.DefaultKeyId,
-					      pAd->SharedKey[BSS0][pAd->StaCfg.
-								   DefaultKeyId].
-					      CipherAlg,
-					      pAd->SharedKey[BSS0][pAd->StaCfg.
-								   DefaultKeyId].
-					      Key,
-					      pAd->SharedKey[BSS0][pAd->StaCfg.
-								   DefaultKeyId].
-					      TxMic,
-					      pAd->SharedKey[BSS0][pAd->StaCfg.
-								   DefaultKeyId].
-					      RxMic);
-
-			/* Update ASIC WCID attribute table and IVEIV table */
-			RTMPAddWcidAttributeEntry(pAd,
-						  BSS0,
-						  pAd->StaCfg.DefaultKeyId,
-						  pAd->SharedKey[BSS0][pAd->
-								       StaCfg.
-								       DefaultKeyId].
-						  CipherAlg, NULL);
-
-			/* set 802.1x port control */
-			/*pAd->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED; */
-			STA_PORT_SECURED(pAd);
-
-			/* Indicate Connected for GUI */
-			pAd->IndicateMediaState = NdisMediaStateConnected;
-		}
-	} else			/* dynamic WEP from wpa_supplicant */
-	{
-		u8 CipherAlg;
-		u8 *Key;
-
-		if (pKey->KeyLength == 32)
-			goto end;
-
-		KeyIdx = pKey->KeyIndex & 0x0fffffff;
-
-		if (KeyIdx < 4) {
-			/* it is a default shared key, for Pairwise key setting */
-			if (pKey->KeyIndex & 0x80000000) {
-				pEntry = MacTableLookup(pAd, pKey->BSSID);
-
-				if (pEntry) {
-					DBGPRINT(RT_DEBUG_TRACE,
-						 ("RTMPAddKey: Set Pair-wise Key\n"));
-
-					/* set key material and key length */
-					pEntry->PairwiseKey.KeyLen =
-					    (u8)pKey->KeyLength;
-					NdisMoveMemory(pEntry->PairwiseKey.Key,
-						       &pKey->KeyMaterial,
-						       pKey->KeyLength);
-
-					/* set Cipher type */
-					if (pKey->KeyLength == 5)
-						pEntry->PairwiseKey.CipherAlg =
-						    CIPHER_WEP64;
-					else
-						pEntry->PairwiseKey.CipherAlg =
-						    CIPHER_WEP128;
-
-					/* Add Pair-wise key to Asic */
-					AsicAddPairwiseKeyEntry(pAd,
-								pEntry->Addr,
-								(u8)pEntry->
-								Aid,
-								&pEntry->
-								PairwiseKey);
-
-					/* update WCID attribute table and IVEIV table for this entry */
-					RTMPAddWcidAttributeEntry(pAd, BSS0, KeyIdx,	/* The value may be not zero */
-								  pEntry->
-								  PairwiseKey.
-								  CipherAlg,
-								  pEntry);
-
-				}
-			} else {
-				/* Default key for tx (shared key) */
-				pAd->StaCfg.DefaultKeyId = (u8)KeyIdx;
-
-				/* set key material and key length */
-				pAd->SharedKey[BSS0][KeyIdx].KeyLen =
-				    (u8)pKey->KeyLength;
-				NdisMoveMemory(pAd->SharedKey[BSS0][KeyIdx].Key,
-					       &pKey->KeyMaterial,
-					       pKey->KeyLength);
-
-				/* Set Ciper type */
-				if (pKey->KeyLength == 5)
-					pAd->SharedKey[BSS0][KeyIdx].CipherAlg =
-					    CIPHER_WEP64;
-				else
-					pAd->SharedKey[BSS0][KeyIdx].CipherAlg =
-					    CIPHER_WEP128;
-
-				CipherAlg =
-				    pAd->SharedKey[BSS0][KeyIdx].CipherAlg;
-				Key = pAd->SharedKey[BSS0][KeyIdx].Key;
-
-				/* Set Group key material to Asic */
-				AsicAddSharedKeyEntry(pAd, BSS0, KeyIdx,
-						      CipherAlg, Key, NULL,
-						      NULL);
-
-				/* Update WCID attribute table and IVEIV table for this group key table */
-				RTMPAddWcidAttributeEntry(pAd, BSS0, KeyIdx,
-							  CipherAlg, NULL);
-
-			}
-		}
-	}
-end:
-	return;
-}
-
-char *rtstrchr(const char *s, int c)
-{
-	for (; *s != (char)c; ++s)
-		if (*s == '\0')
-			return NULL;
-	return (char *)s;
-}
-
-/*
-This is required for LinEX2004/kernel2.6.7 to provide iwlist scanning function
-*/
-
-int
-rt_ioctl_giwname(struct net_device *dev,
-		 struct iw_request_info *info, char *name, char *extra)
-{
-	strncpy(name, "Ralink STA", IFNAMSIZ);
-	/* RT2870 2.1.0.0 uses "RT2870 Wireless" */
-	/* RT3090 2.1.0.0 uses "RT2860 Wireless" */
-	return 0;
-}
-
-int rt_ioctl_siwfreq(struct net_device *dev,
-		     struct iw_request_info *info,
-		     struct iw_freq *freq, char *extra)
-{
-	struct rt_rtmp_adapter *pAdapter = NULL;
-	int chan = -1;
-
-	GET_PAD_FROM_NET_DEV(pAdapter, dev);
-
-	/*check if the interface is down */
-	if (!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE)) {
-		DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
-		return -ENETDOWN;
-	}
-
-	if (freq->e > 1)
-		return -EINVAL;
-
-	if ((freq->e == 0) && (freq->m <= 1000))
-		chan = freq->m;	/* Setting by channel number */
-	else
-		MAP_KHZ_TO_CHANNEL_ID((freq->m / 100), chan);	/* Setting by frequency - search the table , like 2.412G, 2.422G, */
-
-	if (ChannelSanity(pAdapter, chan) == TRUE) {
-		pAdapter->CommonCfg.Channel = chan;
-		DBGPRINT(RT_DEBUG_ERROR,
-			 ("==>rt_ioctl_siwfreq::SIOCSIWFREQ[cmd=0x%x] (Channel=%d)\n",
-			  SIOCSIWFREQ, pAdapter->CommonCfg.Channel));
-	} else
-		return -EINVAL;
-
-	return 0;
-}
-
-int rt_ioctl_giwfreq(struct net_device *dev,
-		     struct iw_request_info *info,
-		     struct iw_freq *freq, char *extra)
-{
-	struct rt_rtmp_adapter *pAdapter = NULL;
-	u8 ch;
-	unsigned long m = 2412000;
-
-	GET_PAD_FROM_NET_DEV(pAdapter, dev);
-
-	ch = pAdapter->CommonCfg.Channel;
-
-	DBGPRINT(RT_DEBUG_TRACE, ("==>rt_ioctl_giwfreq  %d\n", ch));
-
-	MAP_CHANNEL_ID_TO_KHZ(ch, m);
-	freq->m = m * 100;
-	freq->e = 1;
-	return 0;
-}
-
-int rt_ioctl_siwmode(struct net_device *dev,
-		     struct iw_request_info *info, __u32 * mode, char *extra)
-{
-	struct rt_rtmp_adapter *pAdapter = NULL;
-
-	GET_PAD_FROM_NET_DEV(pAdapter, dev);
-
-	/*check if the interface is down */
-	if (!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE)) {
-		DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
-		return -ENETDOWN;
-	}
-
-	switch (*mode) {
-	case IW_MODE_ADHOC:
-		Set_NetworkType_Proc(pAdapter, "Adhoc");
-		break;
-	case IW_MODE_INFRA:
-		Set_NetworkType_Proc(pAdapter, "Infra");
-		break;
-	case IW_MODE_MONITOR:
-		Set_NetworkType_Proc(pAdapter, "Monitor");
-		break;
-	default:
-		DBGPRINT(RT_DEBUG_TRACE,
-			 ("===>rt_ioctl_siwmode::SIOCSIWMODE (unknown %d)\n",
-			  *mode));
-		return -EINVAL;
-	}
-
-	/* Reset Ralink supplicant to not use, it will be set to start when UI set PMK key */
-	pAdapter->StaCfg.WpaState = SS_NOTUSE;
-
-	return 0;
-}
-
-int rt_ioctl_giwmode(struct net_device *dev,
-		     struct iw_request_info *info, __u32 * mode, char *extra)
-{
-	struct rt_rtmp_adapter *pAdapter = NULL;
-
-	GET_PAD_FROM_NET_DEV(pAdapter, dev);
-
-	if (ADHOC_ON(pAdapter))
-		*mode = IW_MODE_ADHOC;
-	else if (INFRA_ON(pAdapter))
-		*mode = IW_MODE_INFRA;
-	else if (MONITOR_ON(pAdapter)) {
-		*mode = IW_MODE_MONITOR;
-	} else
-		*mode = IW_MODE_AUTO;
-
-	DBGPRINT(RT_DEBUG_TRACE, ("==>rt_ioctl_giwmode(mode=%d)\n", *mode));
-	return 0;
-}
-
-int rt_ioctl_siwsens(struct net_device *dev,
-		     struct iw_request_info *info, char *name, char *extra)
-{
-	struct rt_rtmp_adapter *pAdapter = NULL;
-
-	GET_PAD_FROM_NET_DEV(pAdapter, dev);
-
-	/*check if the interface is down */
-	if (!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE)) {
-		DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
-		return -ENETDOWN;
-	}
-
-	return 0;
-}
-
-int rt_ioctl_giwsens(struct net_device *dev,
-		     struct iw_request_info *info, char *name, char *extra)
-{
-	return 0;
-}
-
-int rt_ioctl_giwrange(struct net_device *dev,
-		      struct iw_request_info *info,
-		      struct iw_point *data, char *extra)
-{
-	struct rt_rtmp_adapter *pAdapter = NULL;
-	struct iw_range *range = (struct iw_range *)extra;
-	u16 val;
-	int i;
-
-	GET_PAD_FROM_NET_DEV(pAdapter, dev);
-
-	DBGPRINT(RT_DEBUG_TRACE, ("===>rt_ioctl_giwrange\n"));
-	data->length = sizeof(struct iw_range);
-	memset(range, 0, sizeof(struct iw_range));
-
-	range->txpower_capa = IW_TXPOW_DBM;
-
-	if (INFRA_ON(pAdapter) || ADHOC_ON(pAdapter)) {
-		range->min_pmp = 1 * 1024;
-		range->max_pmp = 65535 * 1024;
-		range->min_pmt = 1 * 1024;
-		range->max_pmt = 1000 * 1024;
-		range->pmp_flags = IW_POWER_PERIOD;
-		range->pmt_flags = IW_POWER_TIMEOUT;
-		range->pm_capa = IW_POWER_PERIOD | IW_POWER_TIMEOUT |
-		    IW_POWER_UNICAST_R | IW_POWER_ALL_R;
-	}
-
-	range->we_version_compiled = WIRELESS_EXT;
-	range->we_version_source = 14;
-
-	range->retry_capa = IW_RETRY_LIMIT;
-	range->retry_flags = IW_RETRY_LIMIT;
-	range->min_retry = 0;
-	range->max_retry = 255;
-
-	range->num_channels = pAdapter->ChannelListNum;
-
-	val = 0;
-	for (i = 1; i <= range->num_channels; i++) {
-		u32 m = 2412000;
-		range->freq[val].i = pAdapter->ChannelList[i - 1].Channel;
-		MAP_CHANNEL_ID_TO_KHZ(pAdapter->ChannelList[i - 1].Channel, m);
-		range->freq[val].m = m * 100;	/* OS_HZ */
-
-		range->freq[val].e = 1;
-		val++;
-		if (val == IW_MAX_FREQUENCIES)
-			break;
-	}
-	range->num_frequency = val;
-
-	range->max_qual.qual = 100;	/* what is correct max? This was not
-					 * documented exactly. At least
-					 * 69 has been observed. */
-	range->max_qual.level = 0;	/* dB */
-	range->max_qual.noise = 0;	/* dB */
-
-	/* What would be suitable values for "average/typical" qual? */
-	range->avg_qual.qual = 20;
-	range->avg_qual.level = -60;
-	range->avg_qual.noise = -95;
-	range->sensitivity = 3;
-
-	range->max_encoding_tokens = NR_WEP_KEYS;
-	range->num_encoding_sizes = 2;
-	range->encoding_size[0] = 5;
-	range->encoding_size[1] = 13;
-
-	range->min_rts = 0;
-	range->max_rts = 2347;
-	range->min_frag = 256;
-	range->max_frag = 2346;
-
-	/* IW_ENC_CAPA_* bit field */
-	range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 |
-	    IW_ENC_CAPA_CIPHER_TKIP | IW_ENC_CAPA_CIPHER_CCMP;
-
-	return 0;
-}
-
-int rt_ioctl_siwap(struct net_device *dev,
-		   struct iw_request_info *info,
-		   struct sockaddr *ap_addr, char *extra)
-{
-	struct rt_rtmp_adapter *pAdapter = NULL;
-	NDIS_802_11_MAC_ADDRESS Bssid;
-
-	GET_PAD_FROM_NET_DEV(pAdapter, dev);
-
-	/*check if the interface is down */
-	if (!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE)) {
-		DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
-		return -ENETDOWN;
-	}
-
-	if (pAdapter->Mlme.CntlMachine.CurrState != CNTL_IDLE) {
-		RTMP_MLME_RESET_STATE_MACHINE(pAdapter);
-		DBGPRINT(RT_DEBUG_TRACE,
-			 ("MLME busy, reset MLME state machine!\n"));
-	}
-	/* tell CNTL state machine to call NdisMSetInformationComplete() after completing */
-	/* this request, because this request is initiated by NDIS. */
-	pAdapter->MlmeAux.CurrReqIsFromNdis = FALSE;
-	/* Prevent to connect AP again in STAMlmePeriodicExec */
-	pAdapter->MlmeAux.AutoReconnectSsidLen = 32;
-
-	memcpy(Bssid, ap_addr->sa_data, MAC_ADDR_LEN);
-	MlmeEnqueue(pAdapter,
-		    MLME_CNTL_STATE_MACHINE,
-		    OID_802_11_BSSID,
-		    sizeof(NDIS_802_11_MAC_ADDRESS), (void *) & Bssid);
-
-	DBGPRINT(RT_DEBUG_TRACE, ("IOCTL::SIOCSIWAP %pM\n", Bssid));
-
-	return 0;
-}
-
-int rt_ioctl_giwap(struct net_device *dev,
-		   struct iw_request_info *info,
-		   struct sockaddr *ap_addr, char *extra)
-{
-	struct rt_rtmp_adapter *pAdapter = NULL;
-
-	GET_PAD_FROM_NET_DEV(pAdapter, dev);
-
-	if (INFRA_ON(pAdapter) || ADHOC_ON(pAdapter)) {
-		ap_addr->sa_family = ARPHRD_ETHER;
-		memcpy(ap_addr->sa_data, &pAdapter->CommonCfg.Bssid, ETH_ALEN);
-	}
-	/* Add for RT2870 */
-	else if (pAdapter->StaCfg.WpaSupplicantUP != WPA_SUPPLICANT_DISABLE) {
-		ap_addr->sa_family = ARPHRD_ETHER;
-		memcpy(ap_addr->sa_data, &pAdapter->MlmeAux.Bssid, ETH_ALEN);
-	} else {
-		DBGPRINT(RT_DEBUG_TRACE, ("IOCTL::SIOCGIWAP(=EMPTY)\n"));
-		return -ENOTCONN;
-	}
-
-	return 0;
-}
-
-/*
- * Units are in db above the noise floor. That means the
- * rssi values reported in the tx/rx descriptors in the
- * driver are the SNR expressed in db.
- *
- * If you assume that the noise floor is -95, which is an
- * excellent assumption 99.5 % of the time, then you can
- * derive the absolute signal level (i.e. -95 + rssi).
- * There are some other slight factors to take into account
- * depending on whether the rssi measurement is from 11b,
- * 11g, or 11a.   These differences are at most 2db and
- * can be documented.
- *
- * NB: various calculations are based on the orinoco/wavelan
- *     drivers for compatibility
- */
-static void set_quality(struct rt_rtmp_adapter *pAdapter,
-			struct iw_quality *iq, signed char rssi)
-{
-	__u8 ChannelQuality;
-
-	/* Normalize Rssi */
-	if (rssi >= -50)
-		ChannelQuality = 100;
-	else if (rssi >= -80)	/* between -50 ~ -80dbm */
-		ChannelQuality = (__u8) (24 + ((rssi + 80) * 26) / 10);
-	else if (rssi >= -90)	/* between -80 ~ -90dbm */
-		ChannelQuality = (__u8) ((rssi + 90) * 26) / 10;
-	else
-		ChannelQuality = 0;
-
-	iq->qual = (__u8) ChannelQuality;
-
-	iq->level = (__u8) (rssi);
-	iq->noise = (pAdapter->BbpWriteLatch[66] > pAdapter->BbpTuning.FalseCcaUpperThreshold) ? ((__u8) pAdapter->BbpTuning.FalseCcaUpperThreshold) : ((__u8) pAdapter->BbpWriteLatch[66]);	/* noise level (dBm) */
-	iq->noise += 256 - 143;
-	iq->updated = pAdapter->iw_stats.qual.updated;
-}
-
-int rt_ioctl_iwaplist(struct net_device *dev,
-		      struct iw_request_info *info,
-		      struct iw_point *data, char *extra)
-{
-	struct rt_rtmp_adapter *pAdapter = NULL;
-
-	struct sockaddr addr[IW_MAX_AP];
-	struct iw_quality qual[IW_MAX_AP];
-	int i;
-
-	GET_PAD_FROM_NET_DEV(pAdapter, dev);
-
-	/*check if the interface is down */
-	if (!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE)) {
-		DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
-		data->length = 0;
-		return 0;
-		/*return -ENETDOWN; */
-	}
-
-	for (i = 0; i < IW_MAX_AP; i++) {
-		if (i >= pAdapter->ScanTab.BssNr)
-			break;
-		addr[i].sa_family = ARPHRD_ETHER;
-		memcpy(addr[i].sa_data, &pAdapter->ScanTab.BssEntry[i].Bssid,
-		       MAC_ADDR_LEN);
-		set_quality(pAdapter, &qual[i],
-			    pAdapter->ScanTab.BssEntry[i].Rssi);
-	}
-	data->length = i;
-	memcpy(extra, &addr, i * sizeof(addr[0]));
-	data->flags = 1;	/* signal quality present (sort of) */
-	memcpy(extra + i * sizeof(addr[0]), &qual, i * sizeof(qual[i]));
-
-	return 0;
-}
-
-int rt_ioctl_siwscan(struct net_device *dev,
-		     struct iw_request_info *info,
-		     struct iw_point *data, char *extra)
-{
-	struct rt_rtmp_adapter *pAdapter = NULL;
-
-	unsigned long Now;
-	int Status = NDIS_STATUS_SUCCESS;
-
-	GET_PAD_FROM_NET_DEV(pAdapter, dev);
-
-	/*check if the interface is down */
-	if (!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE)) {
-		DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
-		return -ENETDOWN;
-	}
-
-	if (MONITOR_ON(pAdapter)) {
-		DBGPRINT(RT_DEBUG_TRACE,
-			 ("Driver is in Monitor Mode now!\n"));
-		return -EINVAL;
-	}
-
-	if (pAdapter->StaCfg.WpaSupplicantUP == WPA_SUPPLICANT_ENABLE) {
-		pAdapter->StaCfg.WpaSupplicantScanCount++;
-	}
-
-	pAdapter->StaCfg.bScanReqIsFromWebUI = TRUE;
-	if (RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
-		return NDIS_STATUS_SUCCESS;
-	do {
-		Now = jiffies;
-
-		if ((pAdapter->StaCfg.WpaSupplicantUP == WPA_SUPPLICANT_ENABLE)
-		    && (pAdapter->StaCfg.WpaSupplicantScanCount > 3)) {
-			DBGPRINT(RT_DEBUG_TRACE,
-				 ("WpaSupplicantScanCount > 3\n"));
-			Status = NDIS_STATUS_SUCCESS;
-			break;
-		}
-
-		if ((OPSTATUS_TEST_FLAG
-		     (pAdapter, fOP_STATUS_MEDIA_STATE_CONNECTED))
-		    && ((pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeWPA)
-			|| (pAdapter->StaCfg.AuthMode ==
-			    Ndis802_11AuthModeWPAPSK))
-		    && (pAdapter->StaCfg.PortSecured ==
-			WPA_802_1X_PORT_NOT_SECURED)) {
-			DBGPRINT(RT_DEBUG_TRACE,
-				 ("Link UP, Port Not Secured! ignore this set::OID_802_11_BSSID_LIST_SCAN\n"));
-			Status = NDIS_STATUS_SUCCESS;
-			break;
-		}
-
-		if (pAdapter->Mlme.CntlMachine.CurrState != CNTL_IDLE) {
-			RTMP_MLME_RESET_STATE_MACHINE(pAdapter);
-			DBGPRINT(RT_DEBUG_TRACE,
-				 ("MLME busy, reset MLME state machine!\n"));
-		}
-		/* tell CNTL state machine to call NdisMSetInformationComplete() after completing */
-		/* this request, because this request is initiated by NDIS. */
-		pAdapter->MlmeAux.CurrReqIsFromNdis = FALSE;
-		/* Reset allowed scan retries */
-		pAdapter->StaCfg.ScanCnt = 0;
-		pAdapter->StaCfg.LastScanTime = Now;
-
-		MlmeEnqueue(pAdapter,
-			    MLME_CNTL_STATE_MACHINE,
-			    OID_802_11_BSSID_LIST_SCAN, 0, NULL);
-
-		Status = NDIS_STATUS_SUCCESS;
-		RTMP_MLME_HANDLER(pAdapter);
-	} while (0);
-	return NDIS_STATUS_SUCCESS;
-}
-
-int rt_ioctl_giwscan(struct net_device *dev,
-		     struct iw_request_info *info,
-		     struct iw_point *data, char *extra)
-{
-	struct rt_rtmp_adapter *pAdapter = NULL;
-	int i = 0;
-	char *current_ev = extra, *previous_ev = extra;
-	char *end_buf;
-	char *current_val;
-	char custom[MAX_CUSTOM_LEN] = { 0 };
-	struct iw_event iwe;
-
-	GET_PAD_FROM_NET_DEV(pAdapter, dev);
-
-	if (RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) {
-		/*
-		 * Still scanning, indicate the caller should try again.
-		 */
-		return -EAGAIN;
-	}
-
-	if (pAdapter->StaCfg.WpaSupplicantUP == WPA_SUPPLICANT_ENABLE) {
-		pAdapter->StaCfg.WpaSupplicantScanCount = 0;
-	}
-
-	if (pAdapter->ScanTab.BssNr == 0) {
-		data->length = 0;
-		return 0;
-	}
-
-	if (data->length > 0)
-		end_buf = extra + data->length;
-	else
-		end_buf = extra + IW_SCAN_MAX_DATA;
-
-	for (i = 0; i < pAdapter->ScanTab.BssNr; i++) {
-		if (current_ev >= end_buf) {
-			return -E2BIG;
-		}
-		/*MAC address */
-		/*================================ */
-		memset(&iwe, 0, sizeof(iwe));
-		iwe.cmd = SIOCGIWAP;
-		iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
-		memcpy(iwe.u.ap_addr.sa_data,
-		       &pAdapter->ScanTab.BssEntry[i].Bssid, ETH_ALEN);
-
-		previous_ev = current_ev;
-		current_ev =
-		    iwe_stream_add_event(info, current_ev, end_buf, &iwe,
-					 IW_EV_ADDR_LEN);
-		if (current_ev == previous_ev)
-			return -E2BIG;
-
-		/*
-		   Protocol:
-		   it will show scanned AP's WirelessMode.
-		   it might be
-		   802.11a
-		   802.11a/n
-		   802.11g/n
-		   802.11b/g/n
-		   802.11g
-		   802.11b/g
-		 */
-		memset(&iwe, 0, sizeof(iwe));
-		iwe.cmd = SIOCGIWNAME;
-
-		{
-			struct rt_bss_entry *pBssEntry = &pAdapter->ScanTab.BssEntry[i];
-			BOOLEAN isGonly = FALSE;
-			int rateCnt = 0;
-
-			if (pBssEntry->Channel > 14) {
-				if (pBssEntry->HtCapabilityLen != 0)
-					strcpy(iwe.u.name, "802.11a/n");
-				else
-					strcpy(iwe.u.name, "802.11a");
-			} else {
-				/*
-				   if one of non B mode rate is set supported rate, it means G only.
-				 */
-				for (rateCnt = 0;
-				     rateCnt < pBssEntry->SupRateLen;
-				     rateCnt++) {
-					/*
-					   6Mbps(140) 9Mbps(146) and >=12Mbps(152) are supported rate, it means G only.
-					 */
-					if (pBssEntry->SupRate[rateCnt] == 140
-					    || pBssEntry->SupRate[rateCnt] ==
-					    146
-					    || pBssEntry->SupRate[rateCnt] >=
-					    152)
-						isGonly = TRUE;
-				}
-
-				for (rateCnt = 0;
-				     rateCnt < pBssEntry->ExtRateLen;
-				     rateCnt++) {
-					if (pBssEntry->ExtRate[rateCnt] == 140
-					    || pBssEntry->ExtRate[rateCnt] ==
-					    146
-					    || pBssEntry->ExtRate[rateCnt] >=
-					    152)
-						isGonly = TRUE;
-				}
-
-				if (pBssEntry->HtCapabilityLen != 0) {
-					if (isGonly == TRUE)
-						strcpy(iwe.u.name, "802.11g/n");
-					else
-						strcpy(iwe.u.name,
-						       "802.11b/g/n");
-				} else {
-					if (isGonly == TRUE)
-						strcpy(iwe.u.name, "802.11g");
-					else {
-						if (pBssEntry->SupRateLen == 4
-						    && pBssEntry->ExtRateLen ==
-						    0)
-							strcpy(iwe.u.name,
-							       "802.11b");
-						else
-							strcpy(iwe.u.name,
-							       "802.11b/g");
-					}
-				}
-			}
-		}
-
-		previous_ev = current_ev;
-		current_ev =
-		    iwe_stream_add_event(info, current_ev, end_buf, &iwe,
-					 IW_EV_ADDR_LEN);
-		if (current_ev == previous_ev)
-			return -E2BIG;
-
-		/*ESSID */
-		/*================================ */
-		memset(&iwe, 0, sizeof(iwe));
-		iwe.cmd = SIOCGIWESSID;
-		iwe.u.data.length = pAdapter->ScanTab.BssEntry[i].SsidLen;
-		iwe.u.data.flags = 1;
-
-		previous_ev = current_ev;
-		current_ev =
-		    iwe_stream_add_point(info, current_ev, end_buf, &iwe,
-					 (char *)pAdapter->ScanTab.
-					 BssEntry[i].Ssid);
-		if (current_ev == previous_ev)
-			return -E2BIG;
-
-		/*Network Type */
-		/*================================ */
-		memset(&iwe, 0, sizeof(iwe));
-		iwe.cmd = SIOCGIWMODE;
-		if (pAdapter->ScanTab.BssEntry[i].BssType == Ndis802_11IBSS) {
-			iwe.u.mode = IW_MODE_ADHOC;
-		} else if (pAdapter->ScanTab.BssEntry[i].BssType ==
-			   Ndis802_11Infrastructure) {
-			iwe.u.mode = IW_MODE_INFRA;
-		} else {
-			iwe.u.mode = IW_MODE_AUTO;
-		}
-		iwe.len = IW_EV_UINT_LEN;
-
-		previous_ev = current_ev;
-		current_ev =
-		    iwe_stream_add_event(info, current_ev, end_buf, &iwe,
-					 IW_EV_UINT_LEN);
-		if (current_ev == previous_ev)
-			return -E2BIG;
-
-		/*Channel and Frequency */
-		/*================================ */
-		memset(&iwe, 0, sizeof(iwe));
-		iwe.cmd = SIOCGIWFREQ;
-		iwe.u.freq.m = pAdapter->ScanTab.BssEntry[i].Channel;
-		iwe.u.freq.e = 0;
-		iwe.u.freq.i = 0;
-
-		previous_ev = current_ev;
-		current_ev =
-		    iwe_stream_add_event(info, current_ev, end_buf, &iwe,
-					 IW_EV_FREQ_LEN);
-		if (current_ev == previous_ev)
-			return -E2BIG;
-
-		/*Add quality statistics */
-		/*================================ */
-		memset(&iwe, 0, sizeof(iwe));
-		iwe.cmd = IWEVQUAL;
-		iwe.u.qual.level = 0;
-		iwe.u.qual.noise = 0;
-		set_quality(pAdapter, &iwe.u.qual,
-			    pAdapter->ScanTab.BssEntry[i].Rssi);
-		current_ev =
-		    iwe_stream_add_event(info, current_ev, end_buf, &iwe,
-					 IW_EV_QUAL_LEN);
-		if (current_ev == previous_ev)
-			return -E2BIG;
-
-		/*Encyption key */
-		/*================================ */
-		memset(&iwe, 0, sizeof(iwe));
-		iwe.cmd = SIOCGIWENCODE;
-		if (CAP_IS_PRIVACY_ON
-		    (pAdapter->ScanTab.BssEntry[i].CapabilityInfo))
-			iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
-		else
-			iwe.u.data.flags = IW_ENCODE_DISABLED;
-
-		previous_ev = current_ev;
-		current_ev =
-		    iwe_stream_add_point(info, current_ev, end_buf, &iwe,
-					 (char *)pAdapter->
-					 SharedKey[BSS0][(iwe.u.data.
-							  flags &
-							  IW_ENCODE_INDEX) -
-							 1].Key);
-		if (current_ev == previous_ev)
-			return -E2BIG;
-
-		/*Bit Rate */
-		/*================================ */
-		if (pAdapter->ScanTab.BssEntry[i].SupRateLen) {
-			u8 tmpRate =
-			    pAdapter->ScanTab.BssEntry[i].SupRate[pAdapter->
-								  ScanTab.
-								  BssEntry[i].
-								  SupRateLen -
-								  1];
-			memset(&iwe, 0, sizeof(iwe));
-			iwe.cmd = SIOCGIWRATE;
-			current_val = current_ev + IW_EV_LCP_LEN;
-			if (tmpRate == 0x82)
-				iwe.u.bitrate.value = 1 * 1000000;
-			else if (tmpRate == 0x84)
-				iwe.u.bitrate.value = 2 * 1000000;
-			else if (tmpRate == 0x8B)
-				iwe.u.bitrate.value = 5.5 * 1000000;
-			else if (tmpRate == 0x96)
-				iwe.u.bitrate.value = 11 * 1000000;
-			else
-				iwe.u.bitrate.value = (tmpRate / 2) * 1000000;
-
-			if (tmpRate == 0x6c
-			    && pAdapter->ScanTab.BssEntry[i].HtCapabilityLen >
-			    0) {
-				int rate_count = ARRAY_SIZE(ralinkrate);
-				struct rt_ht_cap_info capInfo =
-				    pAdapter->ScanTab.BssEntry[i].HtCapability.
-				    HtCapInfo;
-				int shortGI =
-				    capInfo.ChannelWidth ? capInfo.
-				    ShortGIfor40 : capInfo.ShortGIfor20;
-				int maxMCS =
-				    pAdapter->ScanTab.BssEntry[i].HtCapability.
-				    MCSSet[1] ? 15 : 7;
-				int rate_index =
-				    12 + ((u8)capInfo.ChannelWidth * 24) +
-				    ((u8)shortGI * 48) + ((u8)maxMCS);
-
-				if (rate_index < 0)
-					rate_index = 0;
-				if (rate_index >= rate_count)
-					rate_index = rate_count - 1;
-				iwe.u.bitrate.value =
-				    ralinkrate[rate_index] * 500000;
-			}
-
-			iwe.u.bitrate.disabled = 0;
-			current_val = iwe_stream_add_value(info, current_ev,
-							   current_val, end_buf,
-							   &iwe,
-							   IW_EV_PARAM_LEN);
-
-			if ((current_val - current_ev) > IW_EV_LCP_LEN)
-				current_ev = current_val;
-			else
-				return -E2BIG;
-		}
-		/*WPA IE */
-		if (pAdapter->ScanTab.BssEntry[i].WpaIE.IELen > 0) {
-			memset(&iwe, 0, sizeof(iwe));
-			memset(&custom[0], 0, MAX_CUSTOM_LEN);
-			memcpy(custom,
-			       &(pAdapter->ScanTab.BssEntry[i].WpaIE.IE[0]),
-			       pAdapter->ScanTab.BssEntry[i].WpaIE.IELen);
-			iwe.cmd = IWEVGENIE;
-			iwe.u.data.length =
-			    pAdapter->ScanTab.BssEntry[i].WpaIE.IELen;
-			current_ev =
-			    iwe_stream_add_point(info, current_ev, end_buf,
-						 &iwe, custom);
-			if (current_ev == previous_ev)
-				return -E2BIG;
-		}
-		/*WPA2 IE */
-		if (pAdapter->ScanTab.BssEntry[i].RsnIE.IELen > 0) {
-			memset(&iwe, 0, sizeof(iwe));
-			memset(&custom[0], 0, MAX_CUSTOM_LEN);
-			memcpy(custom,
-			       &(pAdapter->ScanTab.BssEntry[i].RsnIE.IE[0]),
-			       pAdapter->ScanTab.BssEntry[i].RsnIE.IELen);
-			iwe.cmd = IWEVGENIE;
-			iwe.u.data.length =
-			    pAdapter->ScanTab.BssEntry[i].RsnIE.IELen;
-			current_ev =
-			    iwe_stream_add_point(info, current_ev, end_buf,
-						 &iwe, custom);
-			if (current_ev == previous_ev)
-				return -E2BIG;
-		}
-	}
-
-	data->length = current_ev - extra;
-	pAdapter->StaCfg.bScanReqIsFromWebUI = FALSE;
-	DBGPRINT(RT_DEBUG_ERROR,
-		 ("===>rt_ioctl_giwscan. %d(%d) BSS returned, data->length = %d\n",
-		  i, pAdapter->ScanTab.BssNr, data->length));
-	return 0;
-}
-
-int rt_ioctl_siwessid(struct net_device *dev,
-		      struct iw_request_info *info,
-		      struct iw_point *data, char *essid)
-{
-	struct rt_rtmp_adapter *pAdapter = NULL;
-
-	GET_PAD_FROM_NET_DEV(pAdapter, dev);
-
-	/*check if the interface is down */
-	if (!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE)) {
-		DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
-		return -ENETDOWN;
-	}
-
-	if (data->flags) {
-		char *pSsidString = NULL;
-
-		/* Includes null character. */
-		if (data->length > (IW_ESSID_MAX_SIZE + 1))
-			return -E2BIG;
-
-		pSsidString = kmalloc(MAX_LEN_OF_SSID + 1, MEM_ALLOC_FLAG);
-		if (pSsidString) {
-			NdisZeroMemory(pSsidString, MAX_LEN_OF_SSID + 1);
-			NdisMoveMemory(pSsidString, essid, data->length);
-			if (Set_SSID_Proc(pAdapter, pSsidString) == FALSE)
-				return -EINVAL;
-		} else
-			return -ENOMEM;
-	} else {
-		/* ANY ssid */
-		if (Set_SSID_Proc(pAdapter, "") == FALSE)
-			return -EINVAL;
-	}
-	return 0;
-}
-
-int rt_ioctl_giwessid(struct net_device *dev,
-		      struct iw_request_info *info,
-		      struct iw_point *data, char *essid)
-{
-	struct rt_rtmp_adapter *pAdapter = NULL;
-
-	GET_PAD_FROM_NET_DEV(pAdapter, dev);
-
-	data->flags = 1;
-	if (MONITOR_ON(pAdapter)) {
-		data->length = 0;
-		return 0;
-	}
-
-	if (OPSTATUS_TEST_FLAG(pAdapter, fOP_STATUS_MEDIA_STATE_CONNECTED)) {
-		DBGPRINT(RT_DEBUG_TRACE, ("MediaState is connected\n"));
-		data->length = pAdapter->CommonCfg.SsidLen;
-		memcpy(essid, pAdapter->CommonCfg.Ssid,
-		       pAdapter->CommonCfg.SsidLen);
-	}
-#ifdef RTMP_MAC_USB
-	/* Add for RT2870 */
-	else if (pAdapter->StaCfg.WpaSupplicantUP != WPA_SUPPLICANT_DISABLE) {
-		data->length = pAdapter->CommonCfg.SsidLen;
-		memcpy(essid, pAdapter->CommonCfg.Ssid,
-		       pAdapter->CommonCfg.SsidLen);
-	}
-#endif /* RTMP_MAC_USB // */
-	else {			/*the ANY ssid was specified */
-		data->length = 0;
-		DBGPRINT(RT_DEBUG_TRACE,
-			 ("MediaState is not connected, ess\n"));
-	}
-
-	return 0;
-
-}
-
-int rt_ioctl_siwnickn(struct net_device *dev,
-		      struct iw_request_info *info,
-		      struct iw_point *data, char *nickname)
-{
-	struct rt_rtmp_adapter *pAdapter = NULL;
-
-	GET_PAD_FROM_NET_DEV(pAdapter, dev);
-
-	/*check if the interface is down */
-	if (!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE)) {
-		DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
-		return -ENETDOWN;
-	}
-
-	if (data->length > IW_ESSID_MAX_SIZE)
-		return -EINVAL;
-
-	memset(pAdapter->nickname, 0, IW_ESSID_MAX_SIZE + 1);
-	memcpy(pAdapter->nickname, nickname, data->length);
-
-	return 0;
-}
-
-int rt_ioctl_giwnickn(struct net_device *dev,
-		      struct iw_request_info *info,
-		      struct iw_point *data, char *nickname)
-{
-	struct rt_rtmp_adapter *pAdapter = NULL;
-
-	GET_PAD_FROM_NET_DEV(pAdapter, dev);
-
-	if (data->length > strlen((char *)pAdapter->nickname) + 1)
-		data->length = strlen((char *)pAdapter->nickname) + 1;
-	if (data->length > 0) {
-		memcpy(nickname, pAdapter->nickname, data->length - 1);
-		nickname[data->length - 1] = '\0';
-	}
-	return 0;
-}
-
-int rt_ioctl_siwrts(struct net_device *dev,
-		    struct iw_request_info *info,
-		    struct iw_param *rts, char *extra)
-{
-	struct rt_rtmp_adapter *pAdapter = NULL;
-	u16 val;
-
-	GET_PAD_FROM_NET_DEV(pAdapter, dev);
-
-	/*check if the interface is down */
-	if (!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE)) {
-		DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
-		return -ENETDOWN;
-	}
-
-	if (rts->disabled)
-		val = MAX_RTS_THRESHOLD;
-	else if (rts->value < 0 || rts->value > MAX_RTS_THRESHOLD)
-		return -EINVAL;
-	else if (rts->value == 0)
-		val = MAX_RTS_THRESHOLD;
-	else
-		val = rts->value;
-
-	if (val != pAdapter->CommonCfg.RtsThreshold)
-		pAdapter->CommonCfg.RtsThreshold = val;
-
-	return 0;
-}
-
-int rt_ioctl_giwrts(struct net_device *dev,
-		    struct iw_request_info *info,
-		    struct iw_param *rts, char *extra)
-{
-	struct rt_rtmp_adapter *pAdapter = NULL;
-
-	GET_PAD_FROM_NET_DEV(pAdapter, dev);
-
-	/*check if the interface is down */
-	if (!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE)) {
-		DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
-		return -ENETDOWN;
-	}
-
-	rts->value = pAdapter->CommonCfg.RtsThreshold;
-	rts->disabled = (rts->value == MAX_RTS_THRESHOLD);
-	rts->fixed = 1;
-
-	return 0;
-}
-
-int rt_ioctl_siwfrag(struct net_device *dev,
-		     struct iw_request_info *info,
-		     struct iw_param *frag, char *extra)
-{
-	struct rt_rtmp_adapter *pAdapter = NULL;
-	u16 val;
-
-	GET_PAD_FROM_NET_DEV(pAdapter, dev);
-
-	/*check if the interface is down */
-	if (!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE)) {
-		DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
-		return -ENETDOWN;
-	}
-
-	if (frag->disabled)
-		val = MAX_FRAG_THRESHOLD;
-	else if (frag->value >= MIN_FRAG_THRESHOLD
-		 && frag->value <= MAX_FRAG_THRESHOLD)
-		val = __cpu_to_le16(frag->value & ~0x1);	/* even numbers only */
-	else if (frag->value == 0)
-		val = MAX_FRAG_THRESHOLD;
-	else
-		return -EINVAL;
-
-	pAdapter->CommonCfg.FragmentThreshold = val;
-	return 0;
-}
-
-int rt_ioctl_giwfrag(struct net_device *dev,
-		     struct iw_request_info *info,
-		     struct iw_param *frag, char *extra)
-{
-	struct rt_rtmp_adapter *pAdapter = NULL;
-
-	GET_PAD_FROM_NET_DEV(pAdapter, dev);
-
-	/*check if the interface is down */
-	if (!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE)) {
-		DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
-		return -ENETDOWN;
-	}
-
-	frag->value = pAdapter->CommonCfg.FragmentThreshold;
-	frag->disabled = (frag->value == MAX_FRAG_THRESHOLD);
-	frag->fixed = 1;
-
-	return 0;
-}
-
-#define MAX_WEP_KEY_SIZE 13
-#define MIN_WEP_KEY_SIZE 5
-int rt_ioctl_siwencode(struct net_device *dev,
-		       struct iw_request_info *info,
-		       struct iw_point *erq, char *extra)
-{
-	struct rt_rtmp_adapter *pAdapter = NULL;
-
-	GET_PAD_FROM_NET_DEV(pAdapter, dev);
-
-	/*check if the interface is down */
-	if (!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE)) {
-		DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
-		return -ENETDOWN;
-	}
-
-	if ((erq->length == 0) && (erq->flags & IW_ENCODE_DISABLED)) {
-		pAdapter->StaCfg.PairCipher = Ndis802_11WEPDisabled;
-		pAdapter->StaCfg.GroupCipher = Ndis802_11WEPDisabled;
-		pAdapter->StaCfg.WepStatus = Ndis802_11WEPDisabled;
-		pAdapter->StaCfg.OrigWepStatus = pAdapter->StaCfg.WepStatus;
-		pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeOpen;
-		goto done;
-	} else if (erq->flags & IW_ENCODE_RESTRICTED
-		   || erq->flags & IW_ENCODE_OPEN) {
-		/*pAdapter->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED; */
-		STA_PORT_SECURED(pAdapter);
-		pAdapter->StaCfg.PairCipher = Ndis802_11WEPEnabled;
-		pAdapter->StaCfg.GroupCipher = Ndis802_11WEPEnabled;
-		pAdapter->StaCfg.WepStatus = Ndis802_11WEPEnabled;
-		pAdapter->StaCfg.OrigWepStatus = pAdapter->StaCfg.WepStatus;
-		if (erq->flags & IW_ENCODE_RESTRICTED)
-			pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeShared;
-		else
-			pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeOpen;
-	}
-
-	if (erq->length > 0) {
-		int keyIdx = (erq->flags & IW_ENCODE_INDEX) - 1;
-		/* Check the size of the key */
-		if (erq->length > MAX_WEP_KEY_SIZE) {
-			return -EINVAL;
-		}
-		/* Check key index */
-		if ((keyIdx < 0) || (keyIdx >= NR_WEP_KEYS)) {
-			DBGPRINT(RT_DEBUG_TRACE,
-				 ("==>rt_ioctl_siwencode::Wrong keyIdx=%d! Using default key instead (%d)\n",
-				  keyIdx, pAdapter->StaCfg.DefaultKeyId));
-
-			/*Using default key */
-			keyIdx = pAdapter->StaCfg.DefaultKeyId;
-		} else
-			pAdapter->StaCfg.DefaultKeyId = keyIdx;
-
-		NdisZeroMemory(pAdapter->SharedKey[BSS0][keyIdx].Key, 16);
-
-		if (erq->length == MAX_WEP_KEY_SIZE) {
-			pAdapter->SharedKey[BSS0][keyIdx].KeyLen =
-			    MAX_WEP_KEY_SIZE;
-			pAdapter->SharedKey[BSS0][keyIdx].CipherAlg =
-			    CIPHER_WEP128;
-		} else if (erq->length == MIN_WEP_KEY_SIZE) {
-			pAdapter->SharedKey[BSS0][keyIdx].KeyLen =
-			    MIN_WEP_KEY_SIZE;
-			pAdapter->SharedKey[BSS0][keyIdx].CipherAlg =
-			    CIPHER_WEP64;
-		} else
-			/* Disable the key */
-			pAdapter->SharedKey[BSS0][keyIdx].KeyLen = 0;
-
-		/* Check if the key is not marked as invalid */
-		if (!(erq->flags & IW_ENCODE_NOKEY)) {
-			/* Copy the key in the driver */
-			NdisMoveMemory(pAdapter->SharedKey[BSS0][keyIdx].Key,
-				       extra, erq->length);
-		}
-	} else {
-		/* Do we want to just set the transmit key index ? */
-		int index = (erq->flags & IW_ENCODE_INDEX) - 1;
-		if ((index >= 0) && (index < 4)) {
-			pAdapter->StaCfg.DefaultKeyId = index;
-		} else
-			/* Don't complain if the mode is only changed */
-		if (!(erq->flags & IW_ENCODE_MODE))
-			return -EINVAL;
-	}
-
-done:
-	DBGPRINT(RT_DEBUG_TRACE,
-		 ("==>rt_ioctl_siwencode::erq->flags=%x\n", erq->flags));
-	DBGPRINT(RT_DEBUG_TRACE,
-		 ("==>rt_ioctl_siwencode::AuthMode=%x\n",
-		  pAdapter->StaCfg.AuthMode));
-	DBGPRINT(RT_DEBUG_TRACE,
-		 ("==>rt_ioctl_siwencode::DefaultKeyId=%x, KeyLen = %d\n",
-		  pAdapter->StaCfg.DefaultKeyId,
-		  pAdapter->SharedKey[BSS0][pAdapter->StaCfg.DefaultKeyId].
-		  KeyLen));
-	DBGPRINT(RT_DEBUG_TRACE,
-		 ("==>rt_ioctl_siwencode::WepStatus=%x\n",
-		  pAdapter->StaCfg.WepStatus));
-	return 0;
-}
-
-int
-rt_ioctl_giwencode(struct net_device *dev,
-		   struct iw_request_info *info,
-		   struct iw_point *erq, char *key)
-{
-	int kid;
-	struct rt_rtmp_adapter *pAdapter = NULL;
-
-	GET_PAD_FROM_NET_DEV(pAdapter, dev);
-
-	/*check if the interface is down */
-	if (!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE)) {
-		DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
-		return -ENETDOWN;
-	}
-
-	kid = erq->flags & IW_ENCODE_INDEX;
-	DBGPRINT(RT_DEBUG_TRACE,
-		 ("===>rt_ioctl_giwencode %d\n", erq->flags & IW_ENCODE_INDEX));
-
-	if (pAdapter->StaCfg.WepStatus == Ndis802_11WEPDisabled) {
-		erq->length = 0;
-		erq->flags = IW_ENCODE_DISABLED;
-	} else if ((kid > 0) && (kid <= 4)) {
-		/* copy wep key */
-		erq->flags = kid;	/* NB: base 1 */
-		if (erq->length > pAdapter->SharedKey[BSS0][kid - 1].KeyLen)
-			erq->length = pAdapter->SharedKey[BSS0][kid - 1].KeyLen;
-		memcpy(key, pAdapter->SharedKey[BSS0][kid - 1].Key,
-		       erq->length);
-		/*if ((kid == pAdapter->PortCfg.DefaultKeyId)) */
-		/*erq->flags |= IW_ENCODE_ENABLED; */	/* XXX */
-		if (pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeShared)
-			erq->flags |= IW_ENCODE_RESTRICTED;	/* XXX */
-		else
-			erq->flags |= IW_ENCODE_OPEN;	/* XXX */
-
-	} else if (kid == 0) {
-		if (pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeShared)
-			erq->flags |= IW_ENCODE_RESTRICTED;	/* XXX */
-		else
-			erq->flags |= IW_ENCODE_OPEN;	/* XXX */
-		erq->length =
-		    pAdapter->SharedKey[BSS0][pAdapter->StaCfg.DefaultKeyId].
-		    KeyLen;
-		memcpy(key,
-		       pAdapter->SharedKey[BSS0][pAdapter->StaCfg.DefaultKeyId].
-		       Key, erq->length);
-		/* copy default key ID */
-		if (pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeShared)
-			erq->flags |= IW_ENCODE_RESTRICTED;	/* XXX */
-		else
-			erq->flags |= IW_ENCODE_OPEN;	/* XXX */
-		erq->flags = pAdapter->StaCfg.DefaultKeyId + 1;	/* NB: base 1 */
-		erq->flags |= IW_ENCODE_ENABLED;	/* XXX */
-	}
-
-	return 0;
-
-}
-
-void getBaInfo(struct rt_rtmp_adapter *pAd, char *pOutBuf)
-{
-	int i, j;
-	struct rt_ba_ori_entry *pOriBAEntry;
-	struct rt_ba_rec_entry *pRecBAEntry;
-
-	for (i = 0; i < MAX_LEN_OF_MAC_TABLE; i++) {
-		struct rt_mac_table_entry *pEntry = &pAd->MacTab.Content[i];
-		if (((pEntry->ValidAsCLI || pEntry->ValidAsApCli)
-		     && (pEntry->Sst == SST_ASSOC))
-		    || (pEntry->ValidAsWDS) || (pEntry->ValidAsMesh)) {
-			sprintf(pOutBuf + strlen(pOutBuf), "\n%pM (Aid = %d) "
-				"(AP) -\n", pEntry->Addr, pEntry->Aid);
-
-			sprintf(pOutBuf, "%s[Recipient]\n", pOutBuf);
-			for (j = 0; j < NUM_OF_TID; j++) {
-				if (pEntry->BARecWcidArray[j] != 0) {
-					pRecBAEntry =
-					    &pAd->BATable.BARecEntry[pEntry->
-								     BARecWcidArray
-								     [j]];
-					sprintf(pOutBuf + strlen(pOutBuf),
-						"TID=%d, BAWinSize=%d, LastIndSeq=%d, ReorderingPkts=%d\n",
-						j, pRecBAEntry->BAWinSize,
-						pRecBAEntry->LastIndSeq,
-						pRecBAEntry->list.qlen);
-				}
-			}
-			sprintf(pOutBuf, "%s\n", pOutBuf);
-
-			sprintf(pOutBuf, "%s[Originator]\n", pOutBuf);
-			for (j = 0; j < NUM_OF_TID; j++) {
-				if (pEntry->BAOriWcidArray[j] != 0) {
-					pOriBAEntry =
-					    &pAd->BATable.BAOriEntry[pEntry->
-								     BAOriWcidArray
-								     [j]];
-					sprintf(pOutBuf + strlen(pOutBuf),
-						"TID=%d, BAWinSize=%d, StartSeq=%d, CurTxSeq=%d\n",
-						j, pOriBAEntry->BAWinSize,
-						pOriBAEntry->Sequence,
-						pEntry->TxSeq[j]);
-				}
-			}
-			sprintf(pOutBuf, "%s\n\n", pOutBuf);
-		}
-		if (strlen(pOutBuf) > (IW_PRIV_SIZE_MASK - 30))
-			break;
-	}
-
-	return;
-}
-
-int rt_ioctl_siwmlme(struct net_device *dev,
-		     struct iw_request_info *info,
-		     union iwreq_data *wrqu, char *extra)
-{
-	struct rt_rtmp_adapter *pAd = NULL;
-	struct iw_mlme *pMlme = (struct iw_mlme *)wrqu->data.pointer;
-	struct rt_mlme_queue_elem MsgElem;
-	struct rt_mlme_disassoc_req DisAssocReq;
-	struct rt_mlme_deauth_req DeAuthReq;
-
-	GET_PAD_FROM_NET_DEV(pAd, dev);
-
-	DBGPRINT(RT_DEBUG_TRACE, ("====> %s\n", __func__));
-
-	if (pMlme == NULL)
-		return -EINVAL;
-
-	switch (pMlme->cmd) {
-#ifdef IW_MLME_DEAUTH
-	case IW_MLME_DEAUTH:
-		DBGPRINT(RT_DEBUG_TRACE,
-			 ("====> %s - IW_MLME_DEAUTH\n", __func__));
-		COPY_MAC_ADDR(DeAuthReq.Addr, pAd->CommonCfg.Bssid);
-		DeAuthReq.Reason = pMlme->reason_code;
-		MsgElem.MsgLen = sizeof(struct rt_mlme_deauth_req);
-		NdisMoveMemory(MsgElem.Msg, &DeAuthReq,
-			       sizeof(struct rt_mlme_deauth_req));
-		MlmeDeauthReqAction(pAd, &MsgElem);
-		if (INFRA_ON(pAd)) {
-			LinkDown(pAd, FALSE);
-			pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
-		}
-		break;
-#endif /* IW_MLME_DEAUTH // */
-#ifdef IW_MLME_DISASSOC
-	case IW_MLME_DISASSOC:
-		DBGPRINT(RT_DEBUG_TRACE,
-			 ("====> %s - IW_MLME_DISASSOC\n", __func__));
-		COPY_MAC_ADDR(DisAssocReq.Addr, pAd->CommonCfg.Bssid);
-		DisAssocReq.Reason = pMlme->reason_code;
-
-		MsgElem.Machine = ASSOC_STATE_MACHINE;
-		MsgElem.MsgType = MT2_MLME_DISASSOC_REQ;
-		MsgElem.MsgLen = sizeof(struct rt_mlme_disassoc_req);
-		NdisMoveMemory(MsgElem.Msg, &DisAssocReq,
-			       sizeof(struct rt_mlme_disassoc_req));
-
-		pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_DISASSOC;
-		MlmeDisassocReqAction(pAd, &MsgElem);
-		break;
-#endif /* IW_MLME_DISASSOC // */
-	default:
-		DBGPRINT(RT_DEBUG_TRACE,
-			 ("====> %s - Unknow Command\n", __func__));
-		break;
-	}
-
-	return 0;
-}
-
-int rt_ioctl_siwauth(struct net_device *dev,
-		     struct iw_request_info *info,
-		     union iwreq_data *wrqu, char *extra)
-{
-	struct rt_rtmp_adapter *pAdapter = NULL;
-	struct iw_param *param = &wrqu->param;
-
-	GET_PAD_FROM_NET_DEV(pAdapter, dev);
-
-	/*check if the interface is down */
-	if (!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE)) {
-		DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
-		return -ENETDOWN;
-	}
-	switch (param->flags & IW_AUTH_INDEX) {
-	case IW_AUTH_WPA_VERSION:
-		if (param->value == IW_AUTH_WPA_VERSION_WPA) {
-			pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeWPAPSK;
-			if (pAdapter->StaCfg.BssType == BSS_ADHOC)
-				pAdapter->StaCfg.AuthMode =
-				    Ndis802_11AuthModeWPANone;
-		} else if (param->value == IW_AUTH_WPA_VERSION_WPA2)
-			pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeWPA2PSK;
-
-		DBGPRINT(RT_DEBUG_TRACE,
-			 ("%s::IW_AUTH_WPA_VERSION - param->value = %d!\n",
-			  __func__, param->value));
-		break;
-	case IW_AUTH_CIPHER_PAIRWISE:
-		if (param->value == IW_AUTH_CIPHER_NONE) {
-			pAdapter->StaCfg.WepStatus = Ndis802_11WEPDisabled;
-			pAdapter->StaCfg.OrigWepStatus =
-			    pAdapter->StaCfg.WepStatus;
-			pAdapter->StaCfg.PairCipher = Ndis802_11WEPDisabled;
-		} else if (param->value == IW_AUTH_CIPHER_WEP40 ||
-			   param->value == IW_AUTH_CIPHER_WEP104) {
-			pAdapter->StaCfg.WepStatus = Ndis802_11WEPEnabled;
-			pAdapter->StaCfg.OrigWepStatus =
-			    pAdapter->StaCfg.WepStatus;
-			pAdapter->StaCfg.PairCipher = Ndis802_11WEPEnabled;
-			pAdapter->StaCfg.IEEE8021X = FALSE;
-		} else if (param->value == IW_AUTH_CIPHER_TKIP) {
-			pAdapter->StaCfg.WepStatus =
-			    Ndis802_11Encryption2Enabled;
-			pAdapter->StaCfg.OrigWepStatus =
-			    pAdapter->StaCfg.WepStatus;
-			pAdapter->StaCfg.PairCipher =
-			    Ndis802_11Encryption2Enabled;
-		} else if (param->value == IW_AUTH_CIPHER_CCMP) {
-			pAdapter->StaCfg.WepStatus =
-			    Ndis802_11Encryption3Enabled;
-			pAdapter->StaCfg.OrigWepStatus =
-			    pAdapter->StaCfg.WepStatus;
-			pAdapter->StaCfg.PairCipher =
-			    Ndis802_11Encryption3Enabled;
-		}
-		DBGPRINT(RT_DEBUG_TRACE,
-			 ("%s::IW_AUTH_CIPHER_PAIRWISE - param->value = %d!\n",
-			  __func__, param->value));
-		break;
-	case IW_AUTH_CIPHER_GROUP:
-		if (param->value == IW_AUTH_CIPHER_NONE) {
-			pAdapter->StaCfg.GroupCipher = Ndis802_11WEPDisabled;
-		} else if (param->value == IW_AUTH_CIPHER_WEP40 ||
-			   param->value == IW_AUTH_CIPHER_WEP104) {
-			pAdapter->StaCfg.GroupCipher = Ndis802_11WEPEnabled;
-		} else if (param->value == IW_AUTH_CIPHER_TKIP) {
-			pAdapter->StaCfg.GroupCipher =
-			    Ndis802_11Encryption2Enabled;
-		} else if (param->value == IW_AUTH_CIPHER_CCMP) {
-			pAdapter->StaCfg.GroupCipher =
-			    Ndis802_11Encryption3Enabled;
-		}
-		DBGPRINT(RT_DEBUG_TRACE,
-			 ("%s::IW_AUTH_CIPHER_GROUP - param->value = %d!\n",
-			  __func__, param->value));
-		break;
-	case IW_AUTH_KEY_MGMT:
-		if (param->value == IW_AUTH_KEY_MGMT_802_1X) {
-			if (pAdapter->StaCfg.AuthMode ==
-			    Ndis802_11AuthModeWPAPSK) {
-				pAdapter->StaCfg.AuthMode =
-				    Ndis802_11AuthModeWPA;
-				pAdapter->StaCfg.IEEE8021X = FALSE;
-			} else if (pAdapter->StaCfg.AuthMode ==
-				   Ndis802_11AuthModeWPA2PSK) {
-				pAdapter->StaCfg.AuthMode =
-				    Ndis802_11AuthModeWPA2;
-				pAdapter->StaCfg.IEEE8021X = FALSE;
-			} else
-				/* WEP 1x */
-				pAdapter->StaCfg.IEEE8021X = TRUE;
-		} else if (param->value == 0) {
-			/*pAdapter->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED; */
-			STA_PORT_SECURED(pAdapter);
-		}
-		DBGPRINT(RT_DEBUG_TRACE,
-			 ("%s::IW_AUTH_KEY_MGMT - param->value = %d!\n",
-			  __func__, param->value));
-		break;
-	case IW_AUTH_RX_UNENCRYPTED_EAPOL:
-		break;
-	case IW_AUTH_PRIVACY_INVOKED:
-		/*if (param->value == 0)
-		   {
-		   pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeOpen;
-		   pAdapter->StaCfg.WepStatus = Ndis802_11WEPDisabled;
-		   pAdapter->StaCfg.OrigWepStatus = pAdapter->StaCfg.WepStatus;
-		   pAdapter->StaCfg.PairCipher = Ndis802_11WEPDisabled;
-		   pAdapter->StaCfg.GroupCipher = Ndis802_11WEPDisabled;
-		   } */
-		DBGPRINT(RT_DEBUG_TRACE,
-			 ("%s::IW_AUTH_PRIVACY_INVOKED - param->value = %d!\n",
-			  __func__, param->value));
-		break;
-	case IW_AUTH_DROP_UNENCRYPTED:
-		if (param->value != 0)
-			pAdapter->StaCfg.PortSecured =
-			    WPA_802_1X_PORT_NOT_SECURED;
-		else {
-			/*pAdapter->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED; */
-			STA_PORT_SECURED(pAdapter);
-		}
-		DBGPRINT(RT_DEBUG_TRACE,
-			 ("%s::IW_AUTH_WPA_VERSION - param->value = %d!\n",
-			  __func__, param->value));
-		break;
-	case IW_AUTH_80211_AUTH_ALG:
-		if (param->value & IW_AUTH_ALG_SHARED_KEY) {
-			pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeShared;
-		} else if (param->value & IW_AUTH_ALG_OPEN_SYSTEM) {
-			pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeOpen;
-		} else
-			return -EINVAL;
-		DBGPRINT(RT_DEBUG_TRACE,
-			 ("%s::IW_AUTH_80211_AUTH_ALG - param->value = %d!\n",
-			  __func__, param->value));
-		break;
-	case IW_AUTH_WPA_ENABLED:
-		DBGPRINT(RT_DEBUG_TRACE,
-			 ("%s::IW_AUTH_WPA_ENABLED - Driver supports WPA!(param->value = %d)\n",
-			  __func__, param->value));
-		break;
-	default:
-		return -EOPNOTSUPP;
-	}
-
-	return 0;
-}
-
-int rt_ioctl_giwauth(struct net_device *dev,
-		     struct iw_request_info *info,
-		     union iwreq_data *wrqu, char *extra)
-{
-	struct rt_rtmp_adapter *pAdapter = NULL;
-	struct iw_param *param = &wrqu->param;
-
-	GET_PAD_FROM_NET_DEV(pAdapter, dev);
-
-	/*check if the interface is down */
-	if (!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE)) {
-		DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
-		return -ENETDOWN;
-	}
-
-	switch (param->flags & IW_AUTH_INDEX) {
-	case IW_AUTH_DROP_UNENCRYPTED:
-		param->value =
-		    (pAdapter->StaCfg.WepStatus ==
-		     Ndis802_11WEPDisabled) ? 0 : 1;
-		break;
-
-	case IW_AUTH_80211_AUTH_ALG:
-		param->value =
-		    (pAdapter->StaCfg.AuthMode ==
-		     Ndis802_11AuthModeShared) ? IW_AUTH_ALG_SHARED_KEY :
-		    IW_AUTH_ALG_OPEN_SYSTEM;
-		break;
-
-	case IW_AUTH_WPA_ENABLED:
-		param->value =
-		    (pAdapter->StaCfg.AuthMode >=
-		     Ndis802_11AuthModeWPA) ? 1 : 0;
-		break;
-
-	default:
-		return -EOPNOTSUPP;
-	}
-	DBGPRINT(RT_DEBUG_TRACE,
-		 ("rt_ioctl_giwauth::param->value = %d!\n", param->value));
-	return 0;
-}
-
-void fnSetCipherKey(struct rt_rtmp_adapter *pAdapter,
-		    int keyIdx,
-		    u8 CipherAlg,
-		    IN BOOLEAN bGTK, IN struct iw_encode_ext *ext)
-{
-	NdisZeroMemory(&pAdapter->SharedKey[BSS0][keyIdx], sizeof(struct rt_cipher_key));
-	pAdapter->SharedKey[BSS0][keyIdx].KeyLen = LEN_TKIP_EK;
-	NdisMoveMemory(pAdapter->SharedKey[BSS0][keyIdx].Key, ext->key,
-		       LEN_TKIP_EK);
-	NdisMoveMemory(pAdapter->SharedKey[BSS0][keyIdx].TxMic,
-		       ext->key + LEN_TKIP_EK, LEN_TKIP_TXMICK);
-	NdisMoveMemory(pAdapter->SharedKey[BSS0][keyIdx].RxMic,
-		       ext->key + LEN_TKIP_EK + LEN_TKIP_TXMICK,
-		       LEN_TKIP_RXMICK);
-	pAdapter->SharedKey[BSS0][keyIdx].CipherAlg = CipherAlg;
-
-	/* Update group key information to ASIC Shared Key Table */
-	AsicAddSharedKeyEntry(pAdapter,
-			      BSS0,
-			      keyIdx,
-			      pAdapter->SharedKey[BSS0][keyIdx].CipherAlg,
-			      pAdapter->SharedKey[BSS0][keyIdx].Key,
-			      pAdapter->SharedKey[BSS0][keyIdx].TxMic,
-			      pAdapter->SharedKey[BSS0][keyIdx].RxMic);
-
-	if (bGTK)
-		/* Update ASIC WCID attribute table and IVEIV table */
-		RTMPAddWcidAttributeEntry(pAdapter,
-					  BSS0,
-					  keyIdx,
-					  pAdapter->SharedKey[BSS0][keyIdx].
-					  CipherAlg, NULL);
-	else
-		/* Update ASIC WCID attribute table and IVEIV table */
-		RTMPAddWcidAttributeEntry(pAdapter,
-					  BSS0,
-					  keyIdx,
-					  pAdapter->SharedKey[BSS0][keyIdx].
-					  CipherAlg,
-					  &pAdapter->MacTab.
-					  Content[BSSID_WCID]);
-}
-
-int rt_ioctl_siwencodeext(struct net_device *dev,
-			  struct iw_request_info *info,
-			  union iwreq_data *wrqu, char *extra)
-{
-	struct rt_rtmp_adapter *pAdapter = NULL;
-	struct iw_point *encoding = &wrqu->encoding;
-	struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
-	int keyIdx, alg = ext->alg;
-
-	GET_PAD_FROM_NET_DEV(pAdapter, dev);
-
-	/*check if the interface is down */
-	if (!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE)) {
-		DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
-		return -ENETDOWN;
-	}
-
-	if (encoding->flags & IW_ENCODE_DISABLED) {
-		keyIdx = (encoding->flags & IW_ENCODE_INDEX) - 1;
-		/* set BSSID wcid entry of the Pair-wise Key table as no-security mode */
-		AsicRemovePairwiseKeyEntry(pAdapter, BSS0, BSSID_WCID);
-		pAdapter->SharedKey[BSS0][keyIdx].KeyLen = 0;
-		pAdapter->SharedKey[BSS0][keyIdx].CipherAlg = CIPHER_NONE;
-		AsicRemoveSharedKeyEntry(pAdapter, 0, (u8)keyIdx);
-		NdisZeroMemory(&pAdapter->SharedKey[BSS0][keyIdx],
-			       sizeof(struct rt_cipher_key));
-		DBGPRINT(RT_DEBUG_TRACE,
-			 ("%s::Remove all keys!(encoding->flags = %x)\n",
-			  __func__, encoding->flags));
-	} else {
-		/* Get Key Index and convet to our own defined key index */
-		keyIdx = (encoding->flags & IW_ENCODE_INDEX) - 1;
-		if ((keyIdx < 0) || (keyIdx >= NR_WEP_KEYS))
-			return -EINVAL;
-
-		if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) {
-			pAdapter->StaCfg.DefaultKeyId = keyIdx;
-			DBGPRINT(RT_DEBUG_TRACE,
-				 ("%s::DefaultKeyId = %d\n", __func__,
-				  pAdapter->StaCfg.DefaultKeyId));
-		}
-
-		switch (alg) {
-		case IW_ENCODE_ALG_NONE:
-			DBGPRINT(RT_DEBUG_TRACE,
-				 ("%s::IW_ENCODE_ALG_NONE\n", __func__));
-			break;
-		case IW_ENCODE_ALG_WEP:
-			DBGPRINT(RT_DEBUG_TRACE,
-				 ("%s::IW_ENCODE_ALG_WEP - ext->key_len = %d, keyIdx = %d\n",
-				  __func__, ext->key_len, keyIdx));
-			if (ext->key_len == MAX_WEP_KEY_SIZE) {
-				pAdapter->SharedKey[BSS0][keyIdx].KeyLen =
-				    MAX_WEP_KEY_SIZE;
-				pAdapter->SharedKey[BSS0][keyIdx].CipherAlg =
-				    CIPHER_WEP128;
-			} else if (ext->key_len == MIN_WEP_KEY_SIZE) {
-				pAdapter->SharedKey[BSS0][keyIdx].KeyLen =
-				    MIN_WEP_KEY_SIZE;
-				pAdapter->SharedKey[BSS0][keyIdx].CipherAlg =
-				    CIPHER_WEP64;
-			} else
-				return -EINVAL;
-
-			NdisZeroMemory(pAdapter->SharedKey[BSS0][keyIdx].Key,
-				       16);
-			NdisMoveMemory(pAdapter->SharedKey[BSS0][keyIdx].Key,
-				       ext->key, ext->key_len);
-			if (pAdapter->StaCfg.GroupCipher ==
-			    Ndis802_11GroupWEP40Enabled
-			    || pAdapter->StaCfg.GroupCipher ==
-			    Ndis802_11GroupWEP104Enabled) {
-				/* Set Group key material to Asic */
-				AsicAddSharedKeyEntry(pAdapter, BSS0, keyIdx,
-						      pAdapter->
-						      SharedKey[BSS0][keyIdx].
-						      CipherAlg,
-						      pAdapter->
-						      SharedKey[BSS0][keyIdx].
-						      Key, NULL, NULL);
-
-				/* Update WCID attribute table and IVEIV table for this group key table */
-				RTMPAddWcidAttributeEntry(pAdapter, BSS0,
-							  keyIdx,
-							  pAdapter->
-							  SharedKey[BSS0]
-							  [keyIdx].CipherAlg,
-							  NULL);
-
-				STA_PORT_SECURED(pAdapter);
-
-				/* Indicate Connected for GUI */
-				pAdapter->IndicateMediaState =
-				    NdisMediaStateConnected;
-			}
-			break;
-		case IW_ENCODE_ALG_TKIP:
-			DBGPRINT(RT_DEBUG_TRACE,
-				 ("%s::IW_ENCODE_ALG_TKIP - keyIdx = %d, ext->key_len = %d\n",
-				  __func__, keyIdx, ext->key_len));
-			if (ext->key_len == 32) {
-				if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) {
-					fnSetCipherKey(pAdapter, keyIdx,
-						       CIPHER_TKIP, FALSE, ext);
-					if (pAdapter->StaCfg.AuthMode >=
-					    Ndis802_11AuthModeWPA2) {
-						/*pAdapter->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED; */
-						STA_PORT_SECURED(pAdapter);
-						pAdapter->IndicateMediaState =
-						    NdisMediaStateConnected;
-					}
-				} else if (ext->
-					   ext_flags & IW_ENCODE_EXT_GROUP_KEY)
-				{
-					fnSetCipherKey(pAdapter, keyIdx,
-						       CIPHER_TKIP, TRUE, ext);
-
-					/* set 802.1x port control */
-					/*pAdapter->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED; */
-					STA_PORT_SECURED(pAdapter);
-					pAdapter->IndicateMediaState =
-					    NdisMediaStateConnected;
-				}
-			} else
-				return -EINVAL;
-			break;
-		case IW_ENCODE_ALG_CCMP:
-			if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) {
-				fnSetCipherKey(pAdapter, keyIdx, CIPHER_AES,
-					       FALSE, ext);
-				if (pAdapter->StaCfg.AuthMode >=
-				    Ndis802_11AuthModeWPA2)
-					/*pAdapter->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED; */
-					STA_PORT_SECURED(pAdapter);
-				pAdapter->IndicateMediaState =
-				    NdisMediaStateConnected;
-			} else if (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) {
-				fnSetCipherKey(pAdapter, keyIdx, CIPHER_AES,
-					       TRUE, ext);
-
-				/* set 802.1x port control */
-				/*pAdapter->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED; */
-				STA_PORT_SECURED(pAdapter);
-				pAdapter->IndicateMediaState =
-				    NdisMediaStateConnected;
-			}
-			break;
-		default:
-			return -EINVAL;
-		}
-	}
-
-	return 0;
-}
-
-int
-rt_ioctl_giwencodeext(struct net_device *dev,
-		      struct iw_request_info *info,
-		      union iwreq_data *wrqu, char *extra)
-{
-	struct rt_rtmp_adapter *pAd = NULL;
-	char *pKey = NULL;
-	struct iw_point *encoding = &wrqu->encoding;
-	struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
-	int idx, max_key_len;
-
-	GET_PAD_FROM_NET_DEV(pAd, dev);
-
-	DBGPRINT(RT_DEBUG_TRACE, ("===> rt_ioctl_giwencodeext\n"));
-
-	max_key_len = encoding->length - sizeof(*ext);
-	if (max_key_len < 0)
-		return -EINVAL;
-
-	idx = encoding->flags & IW_ENCODE_INDEX;
-	if (idx) {
-		if (idx < 1 || idx > 4)
-			return -EINVAL;
-		idx--;
-
-		if ((pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled) ||
-		    (pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled)) {
-			if (idx != pAd->StaCfg.DefaultKeyId) {
-				ext->key_len = 0;
-				return 0;
-			}
-		}
-	} else
-		idx = pAd->StaCfg.DefaultKeyId;
-
-	encoding->flags = idx + 1;
-	memset(ext, 0, sizeof(*ext));
-
-	ext->key_len = 0;
-	switch (pAd->StaCfg.WepStatus) {
-	case Ndis802_11WEPDisabled:
-		ext->alg = IW_ENCODE_ALG_NONE;
-		encoding->flags |= IW_ENCODE_DISABLED;
-		break;
-	case Ndis802_11WEPEnabled:
-		ext->alg = IW_ENCODE_ALG_WEP;
-		if (pAd->SharedKey[BSS0][idx].KeyLen > max_key_len)
-			return -E2BIG;
-		else {
-			ext->key_len = pAd->SharedKey[BSS0][idx].KeyLen;
-			pKey = (char *)& (pAd->SharedKey[BSS0][idx].Key[0]);
-		}
-		break;
-	case Ndis802_11Encryption2Enabled:
-	case Ndis802_11Encryption3Enabled:
-		if (pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled)
-			ext->alg = IW_ENCODE_ALG_TKIP;
-		else
-			ext->alg = IW_ENCODE_ALG_CCMP;
-
-		if (max_key_len < 32)
-			return -E2BIG;
-		else {
-			ext->key_len = 32;
-			pKey = (char *)& pAd->StaCfg.PMK[0];
-		}
-		break;
-	default:
-		return -EINVAL;
-	}
-
-	if (ext->key_len && pKey) {
-		encoding->flags |= IW_ENCODE_ENABLED;
-		memcpy(ext->key, pKey, ext->key_len);
-	}
-
-	return 0;
-}
-
-int rt_ioctl_siwgenie(struct net_device *dev,
-		      struct iw_request_info *info,
-		      union iwreq_data *wrqu, char *extra)
-{
-	struct rt_rtmp_adapter *pAd = NULL;
-
-	GET_PAD_FROM_NET_DEV(pAd, dev);
-
-	DBGPRINT(RT_DEBUG_TRACE, ("===> rt_ioctl_siwgenie\n"));
-	pAd->StaCfg.bRSN_IE_FromWpaSupplicant = FALSE;
-	if (wrqu->data.length > MAX_LEN_OF_RSNIE ||
-	    (wrqu->data.length && extra == NULL))
-		return -EINVAL;
-
-	if (wrqu->data.length) {
-		pAd->StaCfg.RSNIE_Len = wrqu->data.length;
-		NdisMoveMemory(&pAd->StaCfg.RSN_IE[0], extra,
-			       pAd->StaCfg.RSNIE_Len);
-		pAd->StaCfg.bRSN_IE_FromWpaSupplicant = TRUE;
-	} else {
-		pAd->StaCfg.RSNIE_Len = 0;
-		NdisZeroMemory(&pAd->StaCfg.RSN_IE[0], MAX_LEN_OF_RSNIE);
-	}
-
-	return 0;
-}
-
-int rt_ioctl_giwgenie(struct net_device *dev,
-		      struct iw_request_info *info,
-		      union iwreq_data *wrqu, char *extra)
-{
-	struct rt_rtmp_adapter *pAd = NULL;
-
-	GET_PAD_FROM_NET_DEV(pAd, dev);
-
-	if ((pAd->StaCfg.RSNIE_Len == 0) ||
-	    (pAd->StaCfg.AuthMode < Ndis802_11AuthModeWPA)) {
-		wrqu->data.length = 0;
-		return 0;
-	}
-
-	if (pAd->StaCfg.WpaSupplicantUP == WPA_SUPPLICANT_ENABLE) {
-		if (wrqu->data.length < pAd->StaCfg.RSNIE_Len)
-			return -E2BIG;
-
-		wrqu->data.length = pAd->StaCfg.RSNIE_Len;
-		memcpy(extra, &pAd->StaCfg.RSN_IE[0], pAd->StaCfg.RSNIE_Len);
-	} else {
-		u8 RSNIe = IE_WPA;
-
-		if (wrqu->data.length < (pAd->StaCfg.RSNIE_Len + 2))	/* ID, Len */
-			return -E2BIG;
-		wrqu->data.length = pAd->StaCfg.RSNIE_Len + 2;
-
-		if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK) ||
-		    (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2))
-			RSNIe = IE_RSN;
-
-		extra[0] = (char)RSNIe;
-		extra[1] = pAd->StaCfg.RSNIE_Len;
-		memcpy(extra + 2, &pAd->StaCfg.RSN_IE[0],
-		       pAd->StaCfg.RSNIE_Len);
-	}
-
-	return 0;
-}
-
-int rt_ioctl_siwpmksa(struct net_device *dev,
-		      struct iw_request_info *info,
-		      union iwreq_data *wrqu, char *extra)
-{
-	struct rt_rtmp_adapter *pAd = NULL;
-	struct iw_pmksa *pPmksa = (struct iw_pmksa *)wrqu->data.pointer;
-	int CachedIdx = 0, idx = 0;
-
-	GET_PAD_FROM_NET_DEV(pAd, dev);
-
-	if (pPmksa == NULL)
-		return -EINVAL;
-
-	DBGPRINT(RT_DEBUG_TRACE, ("===> rt_ioctl_siwpmksa\n"));
-	switch (pPmksa->cmd) {
-	case IW_PMKSA_FLUSH:
-		NdisZeroMemory(pAd->StaCfg.SavedPMK,
-			       sizeof(struct rt_bssid_info) * PMKID_NO);
-		DBGPRINT(RT_DEBUG_TRACE,
-			 ("rt_ioctl_siwpmksa - IW_PMKSA_FLUSH\n"));
-		break;
-	case IW_PMKSA_REMOVE:
-		for (CachedIdx = 0; CachedIdx < pAd->StaCfg.SavedPMKNum;
-		     CachedIdx++) {
-			/* compare the BSSID */
-			if (NdisEqualMemory
-			    (pPmksa->bssid.sa_data,
-			     pAd->StaCfg.SavedPMK[CachedIdx].BSSID,
-			     MAC_ADDR_LEN)) {
-				NdisZeroMemory(pAd->StaCfg.SavedPMK[CachedIdx].
-					       BSSID, MAC_ADDR_LEN);
-				NdisZeroMemory(pAd->StaCfg.SavedPMK[CachedIdx].
-					       PMKID, 16);
-				for (idx = CachedIdx;
-				     idx < (pAd->StaCfg.SavedPMKNum - 1);
-				     idx++) {
-					NdisMoveMemory(&pAd->StaCfg.
-						       SavedPMK[idx].BSSID[0],
-						       &pAd->StaCfg.
-						       SavedPMK[idx +
-								1].BSSID[0],
-						       MAC_ADDR_LEN);
-					NdisMoveMemory(&pAd->StaCfg.
-						       SavedPMK[idx].PMKID[0],
-						       &pAd->StaCfg.
-						       SavedPMK[idx +
-								1].PMKID[0],
-						       16);
-				}
-				pAd->StaCfg.SavedPMKNum--;
-				break;
-			}
-		}
-
-		DBGPRINT(RT_DEBUG_TRACE,
-			 ("rt_ioctl_siwpmksa - IW_PMKSA_REMOVE\n"));
-		break;
-	case IW_PMKSA_ADD:
-		for (CachedIdx = 0; CachedIdx < pAd->StaCfg.SavedPMKNum;
-		     CachedIdx++) {
-			/* compare the BSSID */
-			if (NdisEqualMemory
-			    (pPmksa->bssid.sa_data,
-			     pAd->StaCfg.SavedPMK[CachedIdx].BSSID,
-			     MAC_ADDR_LEN))
-				break;
-		}
-
-		/* Found, replace it */
-		if (CachedIdx < PMKID_NO) {
-			DBGPRINT(RT_DEBUG_OFF,
-				 ("Update PMKID, idx = %d\n", CachedIdx));
-			NdisMoveMemory(&pAd->StaCfg.SavedPMK[CachedIdx].
-				       BSSID[0], pPmksa->bssid.sa_data,
-				       MAC_ADDR_LEN);
-			NdisMoveMemory(&pAd->StaCfg.SavedPMK[CachedIdx].
-				       PMKID[0], pPmksa->pmkid, 16);
-			pAd->StaCfg.SavedPMKNum++;
-		}
-		/* Not found, replace the last one */
-		else {
-			/* Randomly replace one */
-			CachedIdx = (pPmksa->bssid.sa_data[5] % PMKID_NO);
-			DBGPRINT(RT_DEBUG_OFF,
-				 ("Update PMKID, idx = %d\n", CachedIdx));
-			NdisMoveMemory(&pAd->StaCfg.SavedPMK[CachedIdx].
-				       BSSID[0], pPmksa->bssid.sa_data,
-				       MAC_ADDR_LEN);
-			NdisMoveMemory(&pAd->StaCfg.SavedPMK[CachedIdx].
-				       PMKID[0], pPmksa->pmkid, 16);
-		}
-
-		DBGPRINT(RT_DEBUG_TRACE,
-			 ("rt_ioctl_siwpmksa - IW_PMKSA_ADD\n"));
-		break;
-	default:
-		DBGPRINT(RT_DEBUG_TRACE,
-			 ("rt_ioctl_siwpmksa - Unknown Command!\n"));
-		break;
-	}
-
-	return 0;
-}
-
-int rt_ioctl_siwrate(struct net_device *dev,
-		     struct iw_request_info *info,
-		     union iwreq_data *wrqu, char *extra)
-{
-	struct rt_rtmp_adapter *pAd = NULL;
-	u32 rate = wrqu->bitrate.value, fixed = wrqu->bitrate.fixed;
-
-	GET_PAD_FROM_NET_DEV(pAd, dev);
-
-	/*check if the interface is down */
-	if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE)) {
-		DBGPRINT(RT_DEBUG_TRACE,
-			 ("rt_ioctl_siwrate::Network is down!\n"));
-		return -ENETDOWN;
-	}
-
-	DBGPRINT(RT_DEBUG_TRACE,
-		 ("rt_ioctl_siwrate::(rate = %d, fixed = %d)\n", rate, fixed));
-	/* rate = -1 => auto rate
-	   rate = X, fixed = 1 => (fixed rate X)
-	 */
-	if (rate == -1) {
-		/*Auto Rate */
-		pAd->StaCfg.DesiredTransmitSetting.field.MCS = MCS_AUTO;
-		pAd->StaCfg.bAutoTxRateSwitch = TRUE;
-		if ((pAd->CommonCfg.PhyMode <= PHY_11G) ||
-		    (pAd->MacTab.Content[BSSID_WCID].HTPhyMode.field.MODE <=
-		     MODE_OFDM))
-			RTMPSetDesiredRates(pAd, -1);
-
-		SetCommonHT(pAd);
-	} else {
-		if (fixed) {
-			pAd->StaCfg.bAutoTxRateSwitch = FALSE;
-			if ((pAd->CommonCfg.PhyMode <= PHY_11G) ||
-			    (pAd->MacTab.Content[BSSID_WCID].HTPhyMode.field.
-			     MODE <= MODE_OFDM))
-				RTMPSetDesiredRates(pAd, rate);
-			else {
-				pAd->StaCfg.DesiredTransmitSetting.field.MCS =
-				    MCS_AUTO;
-				SetCommonHT(pAd);
-			}
-			DBGPRINT(RT_DEBUG_TRACE,
-				 ("rt_ioctl_siwrate::(HtMcs=%d)\n",
-				  pAd->StaCfg.DesiredTransmitSetting.field.
-				  MCS));
-		} else {
-			/* TODO: rate = X, fixed = 0 => (rates <= X) */
-			return -EOPNOTSUPP;
-		}
-	}
-
-	return 0;
-}
-
-int rt_ioctl_giwrate(struct net_device *dev,
-		     struct iw_request_info *info,
-		     union iwreq_data *wrqu, char *extra)
-{
-	struct rt_rtmp_adapter *pAd = NULL;
-	int rate_index = 0, rate_count = 0;
-	HTTRANSMIT_SETTING ht_setting;
-/* Remove to global variable
-    __s32 ralinkrate[] =
-	{2,  4,   11,  22, // CCK
-	12, 18,   24,  36, 48, 72, 96, 108, // OFDM
-	13, 26,   39,  52,  78, 104, 117, 130, 26,  52,  78, 104, 156, 208, 234, 260, // 20MHz, 800ns GI, MCS: 0 ~ 15
-	39, 78,  117, 156, 234, 312, 351, 390,										  // 20MHz, 800ns GI, MCS: 16 ~ 23
-	27, 54,   81, 108, 162, 216, 243, 270, 54, 108, 162, 216, 324, 432, 486, 540, // 40MHz, 800ns GI, MCS: 0 ~ 15
-	81, 162, 243, 324, 486, 648, 729, 810,										  // 40MHz, 800ns GI, MCS: 16 ~ 23
-	14, 29,   43,  57,  87, 115, 130, 144, 29, 59,   87, 115, 173, 230, 260, 288, // 20MHz, 400ns GI, MCS: 0 ~ 15
-	43, 87,  130, 173, 260, 317, 390, 433,										  // 20MHz, 400ns GI, MCS: 16 ~ 23
-	30, 60,   90, 120, 180, 240, 270, 300, 60, 120, 180, 240, 360, 480, 540, 600, // 40MHz, 400ns GI, MCS: 0 ~ 15
-	90, 180, 270, 360, 540, 720, 810, 900};										  // 40MHz, 400ns GI, MCS: 16 ~ 23
-*/
-	GET_PAD_FROM_NET_DEV(pAd, dev);
-
-	rate_count = ARRAY_SIZE(ralinkrate);
-	/*check if the interface is down */
-	if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE)) {
-		DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
-		return -ENETDOWN;
-	}
-
-	if ((pAd->StaCfg.bAutoTxRateSwitch == FALSE) &&
-	    (INFRA_ON(pAd)) &&
-	    ((pAd->CommonCfg.PhyMode <= PHY_11G)
-	     || (pAd->MacTab.Content[BSSID_WCID].HTPhyMode.field.MODE <=
-		 MODE_OFDM)))
-		ht_setting.word = pAd->StaCfg.HTPhyMode.word;
-	else
-		ht_setting.word =
-		    pAd->MacTab.Content[BSSID_WCID].HTPhyMode.word;
-
-	if (ht_setting.field.MODE >= MODE_HTMIX) {
-/*      rate_index = 12 + ((u8)ht_setting.field.BW *16) + ((u8)ht_setting.field.ShortGI *32) + ((u8)ht_setting.field.MCS); */
-		rate_index =
-		    12 + ((u8)ht_setting.field.BW * 24) +
-		    ((u8)ht_setting.field.ShortGI * 48) +
-		    ((u8)ht_setting.field.MCS);
-	} else if (ht_setting.field.MODE == MODE_OFDM)
-		rate_index = (u8)(ht_setting.field.MCS) + 4;
-	else if (ht_setting.field.MODE == MODE_CCK)
-		rate_index = (u8)(ht_setting.field.MCS);
-
-	if (rate_index < 0)
-		rate_index = 0;
-
-	if (rate_index >= rate_count)
-		rate_index = rate_count - 1;
-
-	wrqu->bitrate.value = ralinkrate[rate_index] * 500000;
-	wrqu->bitrate.disabled = 0;
-
-	return 0;
-}
-
-static const iw_handler rt_handler[] = {
-	(iw_handler) NULL,	/* SIOCSIWCOMMIT */
-	(iw_handler) rt_ioctl_giwname,	/* SIOCGIWNAME   */
-	(iw_handler) NULL,	/* SIOCSIWNWID   */
-	(iw_handler) NULL,	/* SIOCGIWNWID   */
-	(iw_handler) rt_ioctl_siwfreq,	/* SIOCSIWFREQ   */
-	(iw_handler) rt_ioctl_giwfreq,	/* SIOCGIWFREQ   */
-	(iw_handler) rt_ioctl_siwmode,	/* SIOCSIWMODE   */
-	(iw_handler) rt_ioctl_giwmode,	/* SIOCGIWMODE   */
-	(iw_handler) NULL,	/* SIOCSIWSENS   */
-	(iw_handler) NULL,	/* SIOCGIWSENS   */
-	(iw_handler) NULL /* not used */ ,	/* SIOCSIWRANGE  */
-	(iw_handler) rt_ioctl_giwrange,	/* SIOCGIWRANGE  */
-	(iw_handler) NULL /* not used */ ,	/* SIOCSIWPRIV   */
-	(iw_handler) NULL /* kernel code */ ,	/* SIOCGIWPRIV   */
-	(iw_handler) NULL /* not used */ ,	/* SIOCSIWSTATS  */
-	(iw_handler) rt28xx_get_wireless_stats /* kernel code */ ,	/* SIOCGIWSTATS  */
-	(iw_handler) NULL,	/* SIOCSIWSPY    */
-	(iw_handler) NULL,	/* SIOCGIWSPY    */
-	(iw_handler) NULL,	/* SIOCSIWTHRSPY */
-	(iw_handler) NULL,	/* SIOCGIWTHRSPY */
-	(iw_handler) rt_ioctl_siwap,	/* SIOCSIWAP     */
-	(iw_handler) rt_ioctl_giwap,	/* SIOCGIWAP     */
-	(iw_handler) rt_ioctl_siwmlme,	/* SIOCSIWMLME   */
-	(iw_handler) rt_ioctl_iwaplist,	/* SIOCGIWAPLIST */
-	(iw_handler) rt_ioctl_siwscan,	/* SIOCSIWSCAN   */
-	(iw_handler) rt_ioctl_giwscan,	/* SIOCGIWSCAN   */
-	(iw_handler) rt_ioctl_siwessid,	/* SIOCSIWESSID  */
-	(iw_handler) rt_ioctl_giwessid,	/* SIOCGIWESSID  */
-	(iw_handler) rt_ioctl_siwnickn,	/* SIOCSIWNICKN  */
-	(iw_handler) rt_ioctl_giwnickn,	/* SIOCGIWNICKN  */
-	(iw_handler) NULL,	/* -- hole --    */
-	(iw_handler) NULL,	/* -- hole --    */
-	(iw_handler) rt_ioctl_siwrate,	/* SIOCSIWRATE   */
-	(iw_handler) rt_ioctl_giwrate,	/* SIOCGIWRATE   */
-	(iw_handler) rt_ioctl_siwrts,	/* SIOCSIWRTS    */
-	(iw_handler) rt_ioctl_giwrts,	/* SIOCGIWRTS    */
-	(iw_handler) rt_ioctl_siwfrag,	/* SIOCSIWFRAG   */
-	(iw_handler) rt_ioctl_giwfrag,	/* SIOCGIWFRAG   */
-	(iw_handler) NULL,	/* SIOCSIWTXPOW  */
-	(iw_handler) NULL,	/* SIOCGIWTXPOW  */
-	(iw_handler) NULL,	/* SIOCSIWRETRY  */
-	(iw_handler) NULL,	/* SIOCGIWRETRY  */
-	(iw_handler) rt_ioctl_siwencode,	/* SIOCSIWENCODE */
-	(iw_handler) rt_ioctl_giwencode,	/* SIOCGIWENCODE */
-	(iw_handler) NULL,	/* SIOCSIWPOWER  */
-	(iw_handler) NULL,	/* SIOCGIWPOWER  */
-	(iw_handler) NULL,	/* -- hole -- */
-	(iw_handler) NULL,	/* -- hole -- */
-	(iw_handler) rt_ioctl_siwgenie,	/* SIOCSIWGENIE  */
-	(iw_handler) rt_ioctl_giwgenie,	/* SIOCGIWGENIE  */
-	(iw_handler) rt_ioctl_siwauth,	/* SIOCSIWAUTH   */
-	(iw_handler) rt_ioctl_giwauth,	/* SIOCGIWAUTH   */
-	(iw_handler) rt_ioctl_siwencodeext,	/* SIOCSIWENCODEEXT */
-	(iw_handler) rt_ioctl_giwencodeext,	/* SIOCGIWENCODEEXT */
-	(iw_handler) rt_ioctl_siwpmksa,	/* SIOCSIWPMKSA  */
-};
-
-const struct iw_handler_def rt28xx_iw_handler_def = {
-	.standard = (iw_handler *) rt_handler,
-	.num_standard = sizeof(rt_handler) / sizeof(iw_handler),
-#if IW_HANDLER_VERSION >= 7
-	.get_wireless_stats = rt28xx_get_wireless_stats,
-#endif
-};
-
-int rt28xx_sta_ioctl(IN struct net_device *net_dev,
-		     IN OUT struct ifreq *rq, int cmd)
-{
-	struct os_cookie *pObj;
-	struct rt_rtmp_adapter *pAd = NULL;
-	struct iwreq *wrq = (struct iwreq *)rq;
-	BOOLEAN StateMachineTouched = FALSE;
-	int Status = NDIS_STATUS_SUCCESS;
-
-	GET_PAD_FROM_NET_DEV(pAd, net_dev);
-
-	pObj = (struct os_cookie *)pAd->OS_Cookie;
-
-	/*check if the interface is down */
-	if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE)) {
-		{
-			DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
-			return -ENETDOWN;
-		}
-	}
-
-	{			/* determine this ioctl command is coming from which interface. */
-		pObj->ioctl_if_type = INT_MAIN;
-		pObj->ioctl_if = MAIN_MBSSID;
-	}
-
-	switch (cmd) {
-	case SIOCGIFHWADDR:
-		DBGPRINT(RT_DEBUG_TRACE, ("IOCTL::SIOCGIFHWADDR\n"));
-		memcpy(wrq->u.name, pAd->CurrentAddress, ETH_ALEN);
-		break;
-	case SIOCGIWNAME:
-		{
-			char *name = &wrq->u.name[0];
-			rt_ioctl_giwname(net_dev, NULL, name, NULL);
-			break;
-		}
-	case SIOCGIWESSID:	/*Get ESSID */
-		{
-			struct iw_point *essid = &wrq->u.essid;
-			rt_ioctl_giwessid(net_dev, NULL, essid, essid->pointer);
-			break;
-		}
-	case SIOCSIWESSID:	/*Set ESSID */
-		{
-			struct iw_point *essid = &wrq->u.essid;
-			rt_ioctl_siwessid(net_dev, NULL, essid, essid->pointer);
-			break;
-		}
-	case SIOCSIWNWID:	/* set network id (the cell) */
-	case SIOCGIWNWID:	/* get network id */
-		Status = -EOPNOTSUPP;
-		break;
-	case SIOCSIWFREQ:	/*set channel/frequency (Hz) */
-		{
-			struct iw_freq *freq = &wrq->u.freq;
-			rt_ioctl_siwfreq(net_dev, NULL, freq, NULL);
-			break;
-		}
-	case SIOCGIWFREQ:	/* get channel/frequency (Hz) */
-		{
-			struct iw_freq *freq = &wrq->u.freq;
-			rt_ioctl_giwfreq(net_dev, NULL, freq, NULL);
-			break;
-		}
-	case SIOCSIWNICKN:	/*set node name/nickname */
-		{
-			/*struct iw_point *data=&wrq->u.data; */
-			/*rt_ioctl_siwnickn(net_dev, NULL, data, NULL); */
-			break;
-		}
-	case SIOCGIWNICKN:	/*get node name/nickname */
-		{
-			struct iw_point *erq = NULL;
-			erq = &wrq->u.data;
-			erq->length = strlen((char *)pAd->nickname);
-			Status =
-			    copy_to_user(erq->pointer, pAd->nickname,
-					 erq->length);
-			if (Status)
-				Status = -EFAULT;
-			break;
-		}
-	case SIOCGIWRATE:	/*get default bit rate (bps) */
-		rt_ioctl_giwrate(net_dev, NULL, &wrq->u, NULL);
-		break;
-	case SIOCSIWRATE:	/*set default bit rate (bps) */
-		rt_ioctl_siwrate(net_dev, NULL, &wrq->u, NULL);
-		break;
-	case SIOCGIWRTS:	/* get RTS/CTS threshold (bytes) */
-		{
-			struct iw_param *rts = &wrq->u.rts;
-			rt_ioctl_giwrts(net_dev, NULL, rts, NULL);
-			break;
-		}
-	case SIOCSIWRTS:	/*set RTS/CTS threshold (bytes) */
-		{
-			struct iw_param *rts = &wrq->u.rts;
-			rt_ioctl_siwrts(net_dev, NULL, rts, NULL);
-			break;
-		}
-	case SIOCGIWFRAG:	/*get fragmentation thr (bytes) */
-		{
-			struct iw_param *frag = &wrq->u.frag;
-			rt_ioctl_giwfrag(net_dev, NULL, frag, NULL);
-			break;
-		}
-	case SIOCSIWFRAG:	/*set fragmentation thr (bytes) */
-		{
-			struct iw_param *frag = &wrq->u.frag;
-			rt_ioctl_siwfrag(net_dev, NULL, frag, NULL);
-			break;
-		}
-	case SIOCGIWENCODE:	/*get encoding token & mode */
-		{
-			struct iw_point *erq = &wrq->u.encoding;
-			if (erq)
-				rt_ioctl_giwencode(net_dev, NULL, erq,
-						   erq->pointer);
-			break;
-		}
-	case SIOCSIWENCODE:	/*set encoding token & mode */
-		{
-			struct iw_point *erq = &wrq->u.encoding;
-			if (erq)
-				rt_ioctl_siwencode(net_dev, NULL, erq,
-						   erq->pointer);
-			break;
-		}
-	case SIOCGIWAP:	/*get access point MAC addresses */
-		{
-			struct sockaddr *ap_addr = &wrq->u.ap_addr;
-			rt_ioctl_giwap(net_dev, NULL, ap_addr,
-				       ap_addr->sa_data);
-			break;
-		}
-	case SIOCSIWAP:	/*set access point MAC addresses */
-		{
-			struct sockaddr *ap_addr = &wrq->u.ap_addr;
-			rt_ioctl_siwap(net_dev, NULL, ap_addr,
-				       ap_addr->sa_data);
-			break;
-		}
-	case SIOCGIWMODE:	/*get operation mode */
-		{
-			__u32 *mode = &wrq->u.mode;
-			rt_ioctl_giwmode(net_dev, NULL, mode, NULL);
-			break;
-		}
-	case SIOCSIWMODE:	/*set operation mode */
-		{
-			__u32 *mode = &wrq->u.mode;
-			rt_ioctl_siwmode(net_dev, NULL, mode, NULL);
-			break;
-		}
-	case SIOCGIWSENS:	/*get sensitivity (dBm) */
-	case SIOCSIWSENS:	/*set sensitivity (dBm) */
-	case SIOCGIWPOWER:	/*get Power Management settings */
-	case SIOCSIWPOWER:	/*set Power Management settings */
-	case SIOCGIWTXPOW:	/*get transmit power (dBm) */
-	case SIOCSIWTXPOW:	/*set transmit power (dBm) */
-	case SIOCGIWRANGE:	/*Get range of parameters */
-	case SIOCGIWRETRY:	/*get retry limits and lifetime */
-	case SIOCSIWRETRY:	/*set retry limits and lifetime */
-	case RT_PRIV_IOCTL:
-	case RT_PRIV_IOCTL_EXT:
-	case RTPRIV_IOCTL_SET:
-	case RTPRIV_IOCTL_GSITESURVEY:
-	case SIOCGIWPRIV:
-		Status = -EOPNOTSUPP;
-		break;
-	case SIOCETHTOOL:
-		break;
-	default:
-		DBGPRINT(RT_DEBUG_ERROR,
-			 ("IOCTL::unknown IOCTL's cmd = 0x%08x\n", cmd));
-		Status = -EOPNOTSUPP;
-		break;
-	}
-
-	if (StateMachineTouched)	/* Upper layer sent a MLME-related operations */
-		RTMP_MLME_HANDLER(pAd);
-
-	return Status;
-}
-
-/*
-    ==========================================================================
-    Description:
-        Set SSID
-    Return:
-        TRUE if all parameters are OK, FALSE otherwise
-    ==========================================================================
-*/
-int Set_SSID_Proc(struct rt_rtmp_adapter *pAdapter, char *arg)
-{
-	struct rt_ndis_802_11_ssid Ssid, *pSsid = NULL;
-	BOOLEAN StateMachineTouched = FALSE;
-	int success = TRUE;
-
-	if (strlen(arg) <= MAX_LEN_OF_SSID) {
-		NdisZeroMemory(&Ssid, sizeof(struct rt_ndis_802_11_ssid));
-		if (strlen(arg) != 0) {
-			NdisMoveMemory(Ssid.Ssid, arg, strlen(arg));
-			Ssid.SsidLength = strlen(arg);
-		} else		/*ANY ssid */
-		{
-			Ssid.SsidLength = 0;
-			memcpy(Ssid.Ssid, "", 0);
-			pAdapter->StaCfg.BssType = BSS_INFRA;
-			pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeOpen;
-			pAdapter->StaCfg.WepStatus =
-			    Ndis802_11EncryptionDisabled;
-		}
-		pSsid = &Ssid;
-
-		if (pAdapter->Mlme.CntlMachine.CurrState != CNTL_IDLE) {
-			RTMP_MLME_RESET_STATE_MACHINE(pAdapter);
-			DBGPRINT(RT_DEBUG_TRACE,
-				 ("MLME busy, reset MLME state machine!\n"));
-		}
-
-		if ((pAdapter->StaCfg.WpaPassPhraseLen >= 8) &&
-		    (pAdapter->StaCfg.WpaPassPhraseLen <= 64)) {
-			char passphrase_str[65] = { 0 };
-			u8 keyMaterial[40];
-
-			RTMPMoveMemory(passphrase_str,
-				       pAdapter->StaCfg.WpaPassPhrase,
-				       pAdapter->StaCfg.WpaPassPhraseLen);
-			RTMPZeroMemory(pAdapter->StaCfg.PMK, 32);
-			if (pAdapter->StaCfg.WpaPassPhraseLen == 64) {
-				AtoH((char *)pAdapter->StaCfg.WpaPassPhrase,
-				     pAdapter->StaCfg.PMK, 32);
-			} else {
-				PasswordHash((char *)pAdapter->StaCfg.
-					     WpaPassPhrase, Ssid.Ssid,
-					     Ssid.SsidLength, keyMaterial);
-				NdisMoveMemory(pAdapter->StaCfg.PMK,
-					       keyMaterial, 32);
-			}
-		}
-
-		pAdapter->MlmeAux.CurrReqIsFromNdis = TRUE;
-		pAdapter->StaCfg.bScanReqIsFromWebUI = FALSE;
-		pAdapter->bConfigChanged = TRUE;
-
-		MlmeEnqueue(pAdapter,
-			    MLME_CNTL_STATE_MACHINE,
-			    OID_802_11_SSID,
-			    sizeof(struct rt_ndis_802_11_ssid), (void *) pSsid);
-
-		StateMachineTouched = TRUE;
-		DBGPRINT(RT_DEBUG_TRACE,
-			 ("Set_SSID_Proc::(Len=%d,Ssid=%s)\n", Ssid.SsidLength,
-			  Ssid.Ssid));
-	} else
-		success = FALSE;
-
-	if (StateMachineTouched)	/* Upper layer sent a MLME-related operations */
-		RTMP_MLME_HANDLER(pAdapter);
-
-	return success;
-}
-
-/*
-    ==========================================================================
-    Description:
-        Set Network Type(Infrastructure/Adhoc mode)
-    Return:
-        TRUE if all parameters are OK, FALSE otherwise
-    ==========================================================================
-*/
-int Set_NetworkType_Proc(struct rt_rtmp_adapter *pAdapter, char *arg)
-{
-	u32 Value = 0;
-
-	if (strcmp(arg, "Adhoc") == 0) {
-		if (pAdapter->StaCfg.BssType != BSS_ADHOC) {
-			/* Config has changed */
-			pAdapter->bConfigChanged = TRUE;
-			if (MONITOR_ON(pAdapter)) {
-				RTMP_IO_WRITE32(pAdapter, RX_FILTR_CFG,
-						STANORMAL);
-				RTMP_IO_READ32(pAdapter, MAC_SYS_CTRL, &Value);
-				Value &= (~0x80);
-				RTMP_IO_WRITE32(pAdapter, MAC_SYS_CTRL, Value);
-				OPSTATUS_CLEAR_FLAG(pAdapter,
-						    fOP_STATUS_MEDIA_STATE_CONNECTED);
-				pAdapter->StaCfg.bAutoReconnect = TRUE;
-				LinkDown(pAdapter, FALSE);
-			}
-			if (INFRA_ON(pAdapter)) {
-				/*BOOLEAN Cancelled; */
-				/* Set the AutoReconnectSsid to prevent it from reconnecting to the old SSID */
-				/* Since calling this indicates users don't want to connect to that SSID anymore. */
-				pAdapter->MlmeAux.AutoReconnectSsidLen = 32;
-				NdisZeroMemory(pAdapter->MlmeAux.
-					       AutoReconnectSsid,
-					       pAdapter->MlmeAux.
-					       AutoReconnectSsidLen);
-
-				LinkDown(pAdapter, FALSE);
-
-				DBGPRINT(RT_DEBUG_TRACE,
-					 ("NDIS_STATUS_MEDIA_DISCONNECT Event BB!\n"));
-			}
-		}
-		pAdapter->StaCfg.BssType = BSS_ADHOC;
-		pAdapter->net_dev->type = pAdapter->StaCfg.OriDevType;
-		DBGPRINT(RT_DEBUG_TRACE,
-			 ("===>Set_NetworkType_Proc::(AD-HOC)\n"));
-	} else if (strcmp(arg, "Infra") == 0) {
-		if (pAdapter->StaCfg.BssType != BSS_INFRA) {
-			/* Config has changed */
-			pAdapter->bConfigChanged = TRUE;
-			if (MONITOR_ON(pAdapter)) {
-				RTMP_IO_WRITE32(pAdapter, RX_FILTR_CFG,
-						STANORMAL);
-				RTMP_IO_READ32(pAdapter, MAC_SYS_CTRL, &Value);
-				Value &= (~0x80);
-				RTMP_IO_WRITE32(pAdapter, MAC_SYS_CTRL, Value);
-				OPSTATUS_CLEAR_FLAG(pAdapter,
-						    fOP_STATUS_MEDIA_STATE_CONNECTED);
-				pAdapter->StaCfg.bAutoReconnect = TRUE;
-				LinkDown(pAdapter, FALSE);
-			}
-			if (ADHOC_ON(pAdapter)) {
-				/* Set the AutoReconnectSsid to prevent it from reconnecting to the old SSID */
-				/* Since calling this indicates users don't want to connect to that SSID anymore. */
-				pAdapter->MlmeAux.AutoReconnectSsidLen = 32;
-				NdisZeroMemory(pAdapter->MlmeAux.
-					       AutoReconnectSsid,
-					       pAdapter->MlmeAux.
-					       AutoReconnectSsidLen);
-
-				LinkDown(pAdapter, FALSE);
-			}
-		}
-		pAdapter->StaCfg.BssType = BSS_INFRA;
-		pAdapter->net_dev->type = pAdapter->StaCfg.OriDevType;
-		DBGPRINT(RT_DEBUG_TRACE,
-			 ("===>Set_NetworkType_Proc::(INFRA)\n"));
-	} else if (strcmp(arg, "Monitor") == 0) {
-		u8 bbpValue = 0;
-		BCN_TIME_CFG_STRUC csr;
-		OPSTATUS_CLEAR_FLAG(pAdapter, fOP_STATUS_INFRA_ON);
-		OPSTATUS_CLEAR_FLAG(pAdapter, fOP_STATUS_ADHOC_ON);
-		OPSTATUS_SET_FLAG(pAdapter, fOP_STATUS_MEDIA_STATE_CONNECTED);
-		/* disable all periodic state machine */
-		pAdapter->StaCfg.bAutoReconnect = FALSE;
-		/* reset all mlme state machine */
-		RTMP_MLME_RESET_STATE_MACHINE(pAdapter);
-		DBGPRINT(RT_DEBUG_TRACE,
-			 ("fOP_STATUS_MEDIA_STATE_CONNECTED \n"));
-		if (pAdapter->CommonCfg.CentralChannel == 0) {
-			if (pAdapter->CommonCfg.PhyMode == PHY_11AN_MIXED)
-				pAdapter->CommonCfg.CentralChannel = 36;
-			else
-				pAdapter->CommonCfg.CentralChannel = 6;
-		} else
-			N_ChannelCheck(pAdapter);
-
-		if (pAdapter->CommonCfg.PhyMode >= PHY_11ABGN_MIXED &&
-		    pAdapter->CommonCfg.RegTransmitSetting.field.BW == BW_40 &&
-		    pAdapter->CommonCfg.RegTransmitSetting.field.EXTCHA ==
-		    EXTCHA_ABOVE) {
-			/* 40MHz ,control channel at lower */
-			RTMP_BBP_IO_READ8_BY_REG_ID(pAdapter, BBP_R4,
-						    &bbpValue);
-			bbpValue &= (~0x18);
-			bbpValue |= 0x10;
-			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAdapter, BBP_R4,
-						     bbpValue);
-			pAdapter->CommonCfg.BBPCurrentBW = BW_40;
-			/*  RX : control channel at lower */
-			RTMP_BBP_IO_READ8_BY_REG_ID(pAdapter, BBP_R3,
-						    &bbpValue);
-			bbpValue &= (~0x20);
-			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAdapter, BBP_R3,
-						     bbpValue);
-
-			RTMP_IO_READ32(pAdapter, TX_BAND_CFG, &Value);
-			Value &= 0xfffffffe;
-			RTMP_IO_WRITE32(pAdapter, TX_BAND_CFG, Value);
-			pAdapter->CommonCfg.CentralChannel =
-			    pAdapter->CommonCfg.Channel + 2;
-			AsicSwitchChannel(pAdapter,
-					  pAdapter->CommonCfg.CentralChannel,
-					  FALSE);
-			AsicLockChannel(pAdapter,
-					pAdapter->CommonCfg.CentralChannel);
-			DBGPRINT(RT_DEBUG_TRACE,
-				 ("BW_40 ,control_channel(%d), CentralChannel(%d) \n",
-				  pAdapter->CommonCfg.Channel,
-				  pAdapter->CommonCfg.CentralChannel));
-		} else if (pAdapter->CommonCfg.PhyMode >= PHY_11ABGN_MIXED
-			   && pAdapter->CommonCfg.RegTransmitSetting.field.BW ==
-			   BW_40
-			   && pAdapter->CommonCfg.RegTransmitSetting.field.
-			   EXTCHA == EXTCHA_BELOW) {
-			/* 40MHz ,control channel at upper */
-			RTMP_BBP_IO_READ8_BY_REG_ID(pAdapter, BBP_R4,
-						    &bbpValue);
-			bbpValue &= (~0x18);
-			bbpValue |= 0x10;
-			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAdapter, BBP_R4,
-						     bbpValue);
-			pAdapter->CommonCfg.BBPCurrentBW = BW_40;
-			RTMP_IO_READ32(pAdapter, TX_BAND_CFG, &Value);
-			Value |= 0x1;
-			RTMP_IO_WRITE32(pAdapter, TX_BAND_CFG, Value);
-
-			RTMP_BBP_IO_READ8_BY_REG_ID(pAdapter, BBP_R3,
-						    &bbpValue);
-			bbpValue |= (0x20);
-			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAdapter, BBP_R3,
-						     bbpValue);
-			pAdapter->CommonCfg.CentralChannel =
-			    pAdapter->CommonCfg.Channel - 2;
-			AsicSwitchChannel(pAdapter,
-					  pAdapter->CommonCfg.CentralChannel,
-					  FALSE);
-			AsicLockChannel(pAdapter,
-					pAdapter->CommonCfg.CentralChannel);
-			DBGPRINT(RT_DEBUG_TRACE,
-				 ("BW_40 ,control_channel(%d), CentralChannel(%d) \n",
-				  pAdapter->CommonCfg.Channel,
-				  pAdapter->CommonCfg.CentralChannel));
-		} else {
-			/* 20MHz */
-			RTMP_BBP_IO_READ8_BY_REG_ID(pAdapter, BBP_R4,
-						    &bbpValue);
-			bbpValue &= (~0x18);
-			RTMP_BBP_IO_WRITE8_BY_REG_ID(pAdapter, BBP_R4,
-						     bbpValue);
-			pAdapter->CommonCfg.BBPCurrentBW = BW_20;
-			AsicSwitchChannel(pAdapter, pAdapter->CommonCfg.Channel,
-					  FALSE);
-			AsicLockChannel(pAdapter, pAdapter->CommonCfg.Channel);
-			DBGPRINT(RT_DEBUG_TRACE,
-				 ("BW_20, Channel(%d)\n",
-				  pAdapter->CommonCfg.Channel));
-		}
-		/* Enable Rx with promiscuous reception */
-		RTMP_IO_WRITE32(pAdapter, RX_FILTR_CFG, 0x3);
-		/* ASIC supports sniffer function with replacing RSSI with timestamp. */
-		/*RTMP_IO_READ32(pAdapter, MAC_SYS_CTRL, &Value); */
-		/*Value |= (0x80); */
-		/*RTMP_IO_WRITE32(pAdapter, MAC_SYS_CTRL, Value); */
-		/* disable sync */
-		RTMP_IO_READ32(pAdapter, BCN_TIME_CFG, &csr.word);
-		csr.field.bBeaconGen = 0;
-		csr.field.bTBTTEnable = 0;
-		csr.field.TsfSyncMode = 0;
-		RTMP_IO_WRITE32(pAdapter, BCN_TIME_CFG, csr.word);
-
-		pAdapter->StaCfg.BssType = BSS_MONITOR;
-		pAdapter->net_dev->type = ARPHRD_IEEE80211_PRISM;	/*ARPHRD_IEEE80211; // IEEE80211 */
-		DBGPRINT(RT_DEBUG_TRACE,
-			 ("===>Set_NetworkType_Proc::(MONITOR)\n"));
-	}
-	/* Reset Ralink supplicant to not use, it will be set to start when UI set PMK key */
-	pAdapter->StaCfg.WpaState = SS_NOTUSE;
-
-	DBGPRINT(RT_DEBUG_TRACE,
-		 ("Set_NetworkType_Proc::(NetworkType=%d)\n",
-		  pAdapter->StaCfg.BssType));
-
-	return TRUE;
-}
diff -druN linux-2.6.39-libre/drivers/staging/rt2860/TODO linux-3.0-rc7-libre/drivers/staging/rt2860/TODO
--- linux-2.6.39-libre/drivers/staging/rt2860/TODO	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rt2860/TODO	1969-12-31 19:00:00.000000000 -0500
@@ -1,16 +0,0 @@
-I'm hesitant to add a TODO file here, as the wireless developers would
-really have people help them out on the "clean" rt2860 driver that can
-be found at the http://rt2x00.serialmonkey.com/ site.
-
-But, if you wish to clean up this driver instead, here's a short list of
-things that need to be done to get it into a more mergable shape:
-
-TODO:
-	- checkpatch.pl clean
-	- sparse clean
-	- port to in-kernel 80211 stack and common rt2x00 infrastructure
-	- review by the wireless developer community
-
-Please send any patches or complaints about this driver to Greg
-Kroah-Hartman <greg@kroah.com> and don't bother the upstream wireless
-kernel developers about it, they want nothing to do with it.
diff -druN linux-2.6.39-libre/drivers/staging/rt2860/usb_main_dev.c linux-3.0-rc7-libre/drivers/staging/rt2860/usb_main_dev.c
--- linux-2.6.39-libre/drivers/staging/rt2860/usb_main_dev.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rt2860/usb_main_dev.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,927 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, Inc.
- *
- * This program is free software; you can redistribute it and/or modify  *
- * it under the terms of the GNU General Public License as published by  *
- * the Free Software Foundation; either version 2 of the License, or     *
- * (at your option) any later version.                                   *
- *                                                                       *
- * This program is distributed in the hope that it will be useful,       *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of        *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
- * GNU General Public License for more details.                          *
- *                                                                       *
- * You should have received a copy of the GNU General Public License     *
- * along with this program; if not, write to the                         *
- * Free Software Foundation, Inc.,                                       *
- * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
- *                                                                       *
- *************************************************************************/
-
-#include "rt_config.h"
-
-/* Following information will be show when you run 'modinfo' */
-/* If you have a solution for the bug in current version of driver, please e-mail me. */
-/* Otherwise post to the forum at ralinktech's web site(www.ralinktech.com) and let all users help you. */
-MODULE_AUTHOR("Paul Lin <paul_lin@ralinktech.com>");
-MODULE_DESCRIPTION("RT2870/RT3070 Wireless Lan Linux Driver");
-MODULE_LICENSE("GPL");
-#ifdef MODULE_VERSION
-MODULE_VERSION(STA_DRIVER_VERSION);
-#endif
-
-/* module table */
-struct usb_device_id rtusb_usb_id[] = {
-#ifdef RT2870
-	{USB_DEVICE(0x148F, 0x2770)},	/* Ralink */
-	{USB_DEVICE(0x148F, 0x2870)},	/* Ralink */
-	{USB_DEVICE(0x07B8, 0x2870)},	/* AboCom */
-	{USB_DEVICE(0x07B8, 0x2770)},	/* AboCom */
-	{USB_DEVICE(0x0DF6, 0x0039)},	/* Sitecom 2770 */
-	{USB_DEVICE(0x0DF6, 0x003F)},	/* Sitecom 2770 */
-	{USB_DEVICE(0x083A, 0x7512)},	/* Arcadyan 2770 */
-	{USB_DEVICE(0x0789, 0x0162)},	/* Logitec 2870 */
-	{USB_DEVICE(0x0789, 0x0163)},	/* Logitec 2870 */
-	{USB_DEVICE(0x0789, 0x0164)},	/* Logitec 2870 */
-	{USB_DEVICE(0x177f, 0x0302)},	/* lsusb */
-	{USB_DEVICE(0x0B05, 0x1731)},	/* Asus */
-	{USB_DEVICE(0x0B05, 0x1732)},	/* Asus */
-	{USB_DEVICE(0x0B05, 0x1742)},	/* Asus */
-	{USB_DEVICE(0x0DF6, 0x0017)},	/* Sitecom */
-	{USB_DEVICE(0x0DF6, 0x002B)},	/* Sitecom */
-	{USB_DEVICE(0x0DF6, 0x002C)},	/* Sitecom */
-	{USB_DEVICE(0x0DF6, 0x002D)},	/* Sitecom */
-	{USB_DEVICE(0x14B2, 0x3C06)},	/* Conceptronic */
-	{USB_DEVICE(0x14B2, 0x3C28)},	/* Conceptronic */
-	{USB_DEVICE(0x2019, 0xED06)},	/* Planex Communications, Inc. */
-	{USB_DEVICE(0x07D1, 0x3C09)},	/* D-Link */
-	{USB_DEVICE(0x07D1, 0x3C11)},	/* D-Link */
-	{USB_DEVICE(0x14B2, 0x3C07)},	/* AL */
-	{USB_DEVICE(0x050D, 0x8053)},	/* Belkin */
-	{USB_DEVICE(0x050D, 0x825B)},	/* Belkin */
-	{USB_DEVICE(0x050D, 0x935A)},	/* Belkin F6D4050 v1 */
-	{USB_DEVICE(0x050D, 0x935B)},	/* Belkin F6D4050 v2 */
-	{USB_DEVICE(0x14B2, 0x3C23)},	/* Airlink */
-	{USB_DEVICE(0x14B2, 0x3C27)},	/* Airlink */
-	{USB_DEVICE(0x07AA, 0x002F)},	/* Corega */
-	{USB_DEVICE(0x07AA, 0x003C)},	/* Corega */
-	{USB_DEVICE(0x07AA, 0x003F)},	/* Corega */
-	{USB_DEVICE(0x1044, 0x800B)},	/* Gigabyte */
-	{USB_DEVICE(0x15A9, 0x0006)},	/* Sparklan */
-	{USB_DEVICE(0x083A, 0xB522)},	/* SMC */
-	{USB_DEVICE(0x083A, 0xA618)},	/* SMC */
-	{USB_DEVICE(0x083A, 0x8522)},	/* Arcadyan */
-	{USB_DEVICE(0x083A, 0x7522)},	/* Arcadyan */
-	{USB_DEVICE(0x0CDE, 0x0022)},	/* ZCOM */
-	{USB_DEVICE(0x0586, 0x3416)},	/* Zyxel */
-	{USB_DEVICE(0x0586, 0x341a)},	/* Zyxel NWD-270N */
-	{USB_DEVICE(0x0CDE, 0x0025)},	/* Zyxel */
-	{USB_DEVICE(0x1740, 0x9701)},	/* EnGenius */
-	{USB_DEVICE(0x1740, 0x9702)},	/* EnGenius */
-	{USB_DEVICE(0x0471, 0x200f)},	/* Philips */
-	{USB_DEVICE(0x14B2, 0x3C25)},	/* Draytek */
-	{USB_DEVICE(0x13D3, 0x3247)},	/* AzureWave */
-	{USB_DEVICE(0x083A, 0x6618)},	/* Accton */
-	{USB_DEVICE(0x15c5, 0x0008)},	/* Amit */
-	{USB_DEVICE(0x0E66, 0x0001)},	/* Hawking */
-	{USB_DEVICE(0x0E66, 0x0003)},	/* Hawking */
-	{USB_DEVICE(0x129B, 0x1828)},	/* Siemens */
-	{USB_DEVICE(0x157E, 0x300E)},	/* U-Media */
-	{USB_DEVICE(0x050d, 0x805c)},
-	{USB_DEVICE(0x050d, 0x815c)},
-	{USB_DEVICE(0x1482, 0x3C09)},	/* Abocom */
-	{USB_DEVICE(0x14B2, 0x3C09)},	/* Alpha */
-	{USB_DEVICE(0x04E8, 0x2018)},	/* samsung linkstick2 */
-	{USB_DEVICE(0x1690, 0x0740)},	/* Askey */
-	{USB_DEVICE(0x5A57, 0x0280)},	/* Zinwell */
-	{USB_DEVICE(0x5A57, 0x0282)},	/* Zinwell */
-	{USB_DEVICE(0x7392, 0x7718)},
-	{USB_DEVICE(0x7392, 0x7717)},
-	{USB_DEVICE(0x0411, 0x016f)},	/* MelCo.,Inc. WLI-UC-G301N */
-	{USB_DEVICE(0x1737, 0x0070)},	/* Linksys WUSB100 */
-	{USB_DEVICE(0x1737, 0x0071)},	/* Linksys WUSB600N */
-	{USB_DEVICE(0x1737, 0x0078)},	/* Linksys WUSB100v2 */
-	{USB_DEVICE(0x0411, 0x00e8)},	/* Buffalo WLI-UC-G300N */
-	{USB_DEVICE(0x050d, 0x815c)},	/* Belkin F5D8053 */
-	{USB_DEVICE(0x100D, 0x9031)},	/* Motorola 2770 */
-#endif /* RT2870 // */
-#ifdef RT3070
-	{USB_DEVICE(0x148F, 0x3070)},	/* Ralink 3070 */
-	{USB_DEVICE(0x148F, 0x3071)},	/* Ralink 3071 */
-	{USB_DEVICE(0x148F, 0x3072)},	/* Ralink 3072 */
-	{USB_DEVICE(0x0DB0, 0x3820)},	/* Ralink 3070 */
-	{USB_DEVICE(0x0DB0, 0x871C)},	/* Ralink 3070 */
-	{USB_DEVICE(0x0DB0, 0x822C)},	/* Ralink 3070 */
-	{USB_DEVICE(0x0DB0, 0x871B)},	/* Ralink 3070 */
-	{USB_DEVICE(0x0DB0, 0x822B)},	/* Ralink 3070 */
-	{USB_DEVICE(0x0DF6, 0x003E)},	/* Sitecom 3070 */
-	{USB_DEVICE(0x0DF6, 0x0042)},	/* Sitecom 3072 */
-	{USB_DEVICE(0x0DF6, 0x0048)},	/* Sitecom 3070 */
-	{USB_DEVICE(0x0DF6, 0x0047)},	/* Sitecom 3071 */
-	{USB_DEVICE(0x14B2, 0x3C12)},	/* AL 3070 */
-	{USB_DEVICE(0x18C5, 0x0012)},	/* Corega 3070 */
-	{USB_DEVICE(0x083A, 0x7511)},	/* Arcadyan 3070 */
-	{USB_DEVICE(0x083A, 0xA701)},	/* SMC 3070 */
-	{USB_DEVICE(0x083A, 0xA702)},	/* SMC 3072 */
-	{USB_DEVICE(0x1740, 0x9703)},	/* EnGenius 3070 */
-	{USB_DEVICE(0x1740, 0x9705)},	/* EnGenius 3071 */
-	{USB_DEVICE(0x1740, 0x9706)},	/* EnGenius 3072 */
-	{USB_DEVICE(0x1740, 0x9707)},	/* EnGenius 3070 */
-	{USB_DEVICE(0x1740, 0x9708)},	/* EnGenius 3071 */
-	{USB_DEVICE(0x1740, 0x9709)},	/* EnGenius 3072 */
-	{USB_DEVICE(0x13D3, 0x3273)},	/* AzureWave 3070 */
-	{USB_DEVICE(0x13D3, 0x3305)},	/* AzureWave 3070*/
-	{USB_DEVICE(0x1044, 0x800D)},	/* Gigabyte GN-WB32L 3070 */
-	{USB_DEVICE(0x2019, 0xAB25)},	/* Planex Communications, Inc. RT3070 */
-	{USB_DEVICE(0x07B8, 0x3070)},	/* AboCom 3070 */
-	{USB_DEVICE(0x07B8, 0x3071)},	/* AboCom 3071 */
-	{USB_DEVICE(0x07B8, 0x3072)},	/* Abocom 3072 */
-	{USB_DEVICE(0x7392, 0x7711)},	/* Edimax 3070 */
-	{USB_DEVICE(0x1A32, 0x0304)},	/* Quanta 3070 */
-	{USB_DEVICE(0x1EDA, 0x2310)},	/* AirTies 3070 */
-	{USB_DEVICE(0x07D1, 0x3C0A)},	/* D-Link 3072 */
-	{USB_DEVICE(0x07D1, 0x3C0D)},	/* D-Link 3070 */
-	{USB_DEVICE(0x07D1, 0x3C0E)},	/* D-Link 3070 */
-	{USB_DEVICE(0x07D1, 0x3C0F)},	/* D-Link 3070 */
-	{USB_DEVICE(0x07D1, 0x3C16)},	/* D-Link 3070 */
-	{USB_DEVICE(0x07D1, 0x3C17)},	/* D-Link 8070 */
-	{USB_DEVICE(0x1D4D, 0x000C)},	/* Pegatron Corporation 3070 */
-	{USB_DEVICE(0x1D4D, 0x000E)},	/* Pegatron Corporation 3070 */
-	{USB_DEVICE(0x5A57, 0x5257)},	/* Zinwell 3070 */
-	{USB_DEVICE(0x5A57, 0x0283)},	/* Zinwell 3072 */
-	{USB_DEVICE(0x04BB, 0x0945)},	/* I-O DATA 3072 */
-	{USB_DEVICE(0x04BB, 0x0947)},	/* I-O DATA 3070 */
-	{USB_DEVICE(0x04BB, 0x0948)},	/* I-O DATA 3072 */
-	{USB_DEVICE(0x203D, 0x1480)},	/* Encore 3070 */
-	{USB_DEVICE(0x20B8, 0x8888)},	/* PARA INDUSTRIAL 3070 */
-	{USB_DEVICE(0x0B05, 0x1784)},	/* Asus 3072 */
-	{USB_DEVICE(0x203D, 0x14A9)},	/* Encore 3070*/
-	{USB_DEVICE(0x0DB0, 0x899A)},	/* MSI 3070*/
-	{USB_DEVICE(0x0DB0, 0x3870)},	/* MSI 3070*/
-	{USB_DEVICE(0x0DB0, 0x870A)},	/* MSI 3070*/
-	{USB_DEVICE(0x0DB0, 0x6899)},	/* MSI 3070 */
-	{USB_DEVICE(0x0DB0, 0x3822)},	/* MSI 3070 */
-	{USB_DEVICE(0x0DB0, 0x3871)},	/* MSI 3070 */
-	{USB_DEVICE(0x0DB0, 0x871A)},	/* MSI 3070 */
-	{USB_DEVICE(0x0DB0, 0x822A)},	/* MSI 3070 */
-	{USB_DEVICE(0x0DB0, 0x3821)},	/* Ralink 3070 */
-	{USB_DEVICE(0x0DB0, 0x821A)},	/* Ralink 3070 */
-	{USB_DEVICE(0x083A, 0xA703)},	/* IO-MAGIC */
-	{USB_DEVICE(0x13D3, 0x3307)},	/* Azurewave */
-	{USB_DEVICE(0x13D3, 0x3321)},	/* Azurewave */
-	{USB_DEVICE(0x07FA, 0x7712)},	/* Edimax */
-	{USB_DEVICE(0x0789, 0x0166)},	/* Edimax */
-	{USB_DEVICE(0x148F, 0x2070)},	/* Edimax */
-#endif /* RT3070 // */
-	{USB_DEVICE(0x1737, 0x0077)},	/* Linksys WUSB54GC-EU v3 */
-	{USB_DEVICE(0x2001, 0x3C09)},	/* D-Link */
-	{USB_DEVICE(0x2001, 0x3C0A)},	/* D-Link 3072 */
-	{USB_DEVICE(0x2019, 0xED14)},	/* Planex Communications, Inc. */
-	{USB_DEVICE(0x0411, 0x015D)},	/* Buffalo Airstation WLI-UC-GN */
-	{}			/* Terminating entry */
-};
-
-int const rtusb_usb_id_len =
-    sizeof(rtusb_usb_id) / sizeof(struct usb_device_id);
-
-MODULE_DEVICE_TABLE(usb, rtusb_usb_id);
-
-static void rt2870_disconnect(struct usb_device *dev, struct rt_rtmp_adapter *pAd);
-
-static int __devinit rt2870_probe(IN struct usb_interface *intf,
-				  IN struct usb_device *usb_dev,
-				  IN const struct usb_device_id *dev_id,
-				  struct rt_rtmp_adapter **ppAd);
-
-#ifndef PF_NOFREEZE
-#define PF_NOFREEZE  0
-#endif
-
-extern int rt28xx_close(IN struct net_device *net_dev);
-extern int rt28xx_open(struct net_device *net_dev);
-
-static BOOLEAN USBDevConfigInit(IN struct usb_device *dev,
-				IN struct usb_interface *intf,
-				struct rt_rtmp_adapter *pAd);
-
-/*
-========================================================================
-Routine Description:
-    Check the chipset vendor/product ID.
-
-Arguments:
-    _dev_p				Point to the PCI or USB device
-
-Return Value:
-    TRUE				Check ok
-	FALSE				Check fail
-
-Note:
-========================================================================
-*/
-BOOLEAN RT28XXChipsetCheck(IN void *_dev_p)
-{
-	struct usb_interface *intf = (struct usb_interface *)_dev_p;
-	struct usb_device *dev_p = interface_to_usbdev(intf);
-	u32 i;
-
-	for (i = 0; i < rtusb_usb_id_len; i++) {
-		if (dev_p->descriptor.idVendor == rtusb_usb_id[i].idVendor &&
-		    dev_p->descriptor.idProduct == rtusb_usb_id[i].idProduct) {
-			printk(KERN_INFO "rt2870: idVendor = 0x%x, idProduct = 0x%x\n",
-			       dev_p->descriptor.idVendor,
-			       dev_p->descriptor.idProduct);
-			break;
-		}
-	}
-
-	if (i == rtusb_usb_id_len) {
-		printk(KERN_ERR "rt2870: Error! Device Descriptor not matching!\n");
-		return FALSE;
-	}
-
-	return TRUE;
-}
-
-/**************************************************************************/
-/**************************************************************************/
-/*tested for kernel 2.6series */
-/**************************************************************************/
-/**************************************************************************/
-
-#ifdef CONFIG_PM
-static int rt2870_suspend(struct usb_interface *intf, pm_message_t state);
-static int rt2870_resume(struct usb_interface *intf);
-#endif /* CONFIG_PM // */
-
-static BOOLEAN USBDevConfigInit(IN struct usb_device *dev,
-				IN struct usb_interface *intf,
-				struct rt_rtmp_adapter *pAd)
-{
-	struct usb_host_interface *iface_desc;
-	unsigned long BulkOutIdx;
-	u32 i;
-
-	/* get the active interface descriptor */
-	iface_desc = intf->cur_altsetting;
-
-	/* get # of enpoints  */
-	pAd->NumberOfPipes = iface_desc->desc.bNumEndpoints;
-	DBGPRINT(RT_DEBUG_TRACE,
-		 ("NumEndpoints=%d\n", iface_desc->desc.bNumEndpoints));
-
-	/* Configure Pipes */
-	BulkOutIdx = 0;
-
-	for (i = 0; i < pAd->NumberOfPipes; i++) {
-		if ((iface_desc->endpoint[i].desc.bmAttributes ==
-		     USB_ENDPOINT_XFER_BULK) &&
-		    ((iface_desc->endpoint[i].desc.bEndpointAddress &
-		      USB_ENDPOINT_DIR_MASK) == USB_DIR_IN)) {
-			pAd->BulkInEpAddr =
-			    iface_desc->endpoint[i].desc.bEndpointAddress;
-			pAd->BulkInMaxPacketSize =
-			    le2cpu16(iface_desc->endpoint[i].desc.
-				     wMaxPacketSize);
-
-			DBGPRINT_RAW(RT_DEBUG_TRACE,
-				     ("BULK IN MaxPacketSize = %d\n",
-				      pAd->BulkInMaxPacketSize));
-			DBGPRINT_RAW(RT_DEBUG_TRACE,
-				     ("EP address = 0x%2x\n",
-				      iface_desc->endpoint[i].desc.
-				      bEndpointAddress));
-		} else
-		    if ((iface_desc->endpoint[i].desc.bmAttributes ==
-			 USB_ENDPOINT_XFER_BULK)
-			&&
-			((iface_desc->endpoint[i].desc.
-			  bEndpointAddress & USB_ENDPOINT_DIR_MASK) ==
-			 USB_DIR_OUT)) {
-			/* there are 6 bulk out EP. EP6 highest priority. */
-			/* EP1-4 is EDCA.  EP5 is HCCA. */
-			pAd->BulkOutEpAddr[BulkOutIdx++] =
-			    iface_desc->endpoint[i].desc.bEndpointAddress;
-			pAd->BulkOutMaxPacketSize =
-			    le2cpu16(iface_desc->endpoint[i].desc.
-				     wMaxPacketSize);
-
-			DBGPRINT_RAW(RT_DEBUG_TRACE,
-				     ("BULK OUT MaxPacketSize = %d\n",
-				      pAd->BulkOutMaxPacketSize));
-			DBGPRINT_RAW(RT_DEBUG_TRACE,
-				     ("EP address = 0x%2x  \n",
-				      iface_desc->endpoint[i].desc.
-				      bEndpointAddress));
-		}
-	}
-
-	if (!(pAd->BulkInEpAddr && pAd->BulkOutEpAddr[0])) {
-		printk
-		    (KERN_ERR "%s: Could not find both bulk-in and bulk-out endpoints\n",
-		     __FUNCTION__);
-		return FALSE;
-	}
-
-	pAd->config = &dev->config->desc;
-	usb_set_intfdata(intf, pAd);
-
-	return TRUE;
-
-}
-
-static int __devinit rtusb_probe(struct usb_interface *intf,
-		       const struct usb_device_id *id)
-{
-	struct rt_rtmp_adapter *pAd;
-	struct usb_device *dev;
-	int rv;
-
-	dev = interface_to_usbdev(intf);
-	dev = usb_get_dev(dev);
-
-	rv = rt2870_probe(intf, dev, id, &pAd);
-	if (rv != 0)
-		usb_put_dev(dev);
-
-	return rv;
-}
-
-static void rtusb_disconnect(struct usb_interface *intf)
-{
-	struct usb_device *dev = interface_to_usbdev(intf);
-	struct rt_rtmp_adapter *pAd;
-
-	pAd = usb_get_intfdata(intf);
-	usb_set_intfdata(intf, NULL);
-
-	rt2870_disconnect(dev, pAd);
-}
-
-struct usb_driver rtusb_driver = {
-	.name = "rt2870",
-	.probe = rtusb_probe,
-	.disconnect = rtusb_disconnect,
-	.id_table = rtusb_usb_id,
-
-#ifdef CONFIG_PM
-suspend:rt2870_suspend,
-resume:rt2870_resume,
-#endif
-};
-
-#ifdef CONFIG_PM
-
-void RT2870RejectPendingPackets(struct rt_rtmp_adapter *pAd)
-{
-	/* clear PS packets */
-	/* clear TxSw packets */
-}
-
-static int rt2870_suspend(struct usb_interface *intf, pm_message_t state)
-{
-	struct net_device *net_dev;
-	struct rt_rtmp_adapter *pAd = usb_get_intfdata(intf);
-
-	DBGPRINT(RT_DEBUG_TRACE, ("===> rt2870_suspend()\n"));
-	net_dev = pAd->net_dev;
-	netif_device_detach(net_dev);
-
-	pAd->PM_FlgSuspend = 1;
-	if (netif_running(net_dev)) {
-		RTUSBCancelPendingBulkInIRP(pAd);
-		RTUSBCancelPendingBulkOutIRP(pAd);
-	}
-	DBGPRINT(RT_DEBUG_TRACE, ("<=== rt2870_suspend()\n"));
-	return 0;
-}
-
-static int rt2870_resume(struct usb_interface *intf)
-{
-	struct net_device *net_dev;
-	struct rt_rtmp_adapter *pAd = usb_get_intfdata(intf);
-
-	DBGPRINT(RT_DEBUG_TRACE, ("===> rt2870_resume()\n"));
-
-	pAd->PM_FlgSuspend = 0;
-	net_dev = pAd->net_dev;
-	netif_device_attach(net_dev);
-	netif_start_queue(net_dev);
-	netif_carrier_on(net_dev);
-	netif_wake_queue(net_dev);
-
-	DBGPRINT(RT_DEBUG_TRACE, ("<=== rt2870_resume()\n"));
-	return 0;
-}
-#endif /* CONFIG_PM // */
-
-/* Init driver module */
-int __init rtusb_init(void)
-{
-	printk(KERN_DEBUG "rtusb init --->\n");
-	return usb_register(&rtusb_driver);
-}
-
-/* Deinit driver module */
-void __exit rtusb_exit(void)
-{
-	usb_deregister(&rtusb_driver);
-	printk(KERN_DEBUG "<--- rtusb exit\n");
-}
-
-module_init(rtusb_init);
-module_exit(rtusb_exit);
-
-/*---------------------------------------------------------------------	*/
-/* function declarations												*/
-/*---------------------------------------------------------------------	*/
-
-/*
-========================================================================
-Routine Description:
-    MLME kernel thread.
-
-Arguments:
-	*Context			the pAd, driver control block pointer
-
-Return Value:
-    0					close the thread
-
-Note:
-========================================================================
-*/
-int MlmeThread(IN void *Context)
-{
-	struct rt_rtmp_adapter *pAd;
-	struct rt_rtmp_os_task *pTask;
-	int status;
-	status = 0;
-
-	pTask = Context;
-	pAd = pTask->priv;
-
-	RtmpOSTaskCustomize(pTask);
-
-	while (!pTask->task_killed) {
-#ifdef KTHREAD_SUPPORT
-		RTMP_WAIT_EVENT_INTERRUPTIBLE(pAd, pTask);
-#else
-		RTMP_SEM_EVENT_WAIT(&(pTask->taskSema), status);
-
-		/* unlock the device pointers */
-		if (status != 0) {
-			RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS);
-			break;
-		}
-#endif
-
-		/* lock the device pointers , need to check if required */
-		/*down(&(pAd->usbdev_semaphore)); */
-
-		if (!pAd->PM_FlgSuspend)
-			MlmeHandler(pAd);
-	}
-
-	/* notify the exit routine that we're actually exiting now
-	 *
-	 * complete()/wait_for_completion() is similar to up()/down(),
-	 * except that complete() is safe in the case where the structure
-	 * is getting deleted in a parallel mode of execution (i.e. just
-	 * after the down() -- that's necessary for the thread-shutdown
-	 * case.
-	 *
-	 * complete_and_exit() goes even further than this -- it is safe in
-	 * the case that the thread of the caller is going away (not just
-	 * the structure) -- this is necessary for the module-remove case.
-	 * This is important in preemption kernels, which transfer the flow
-	 * of execution immediately upon a complete().
-	 */
-	DBGPRINT(RT_DEBUG_TRACE, ("<---%s\n", __FUNCTION__));
-#ifndef KTHREAD_SUPPORT
-	pTask->taskPID = THREAD_PID_INIT_VALUE;
-	complete_and_exit(&pTask->taskComplete, 0);
-#endif
-	return 0;
-
-}
-
-/*
-========================================================================
-Routine Description:
-    USB command kernel thread.
-
-Arguments:
-	*Context			the pAd, driver control block pointer
-
-Return Value:
-    0					close the thread
-
-Note:
-========================================================================
-*/
-int RTUSBCmdThread(IN void *Context)
-{
-	struct rt_rtmp_adapter *pAd;
-	struct rt_rtmp_os_task *pTask;
-	int status;
-	status = 0;
-
-	pTask = Context;
-	pAd = pTask->priv;
-
-	RtmpOSTaskCustomize(pTask);
-
-	NdisAcquireSpinLock(&pAd->CmdQLock);
-	pAd->CmdQ.CmdQState = RTMP_TASK_STAT_RUNNING;
-	NdisReleaseSpinLock(&pAd->CmdQLock);
-
-	while (pAd && pAd->CmdQ.CmdQState == RTMP_TASK_STAT_RUNNING) {
-#ifdef KTHREAD_SUPPORT
-		RTMP_WAIT_EVENT_INTERRUPTIBLE(pAd, pTask);
-#else
-		/* lock the device pointers */
-		RTMP_SEM_EVENT_WAIT(&(pTask->taskSema), status);
-
-		if (status != 0) {
-			RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS);
-			break;
-		}
-#endif
-
-		if (pAd->CmdQ.CmdQState == RTMP_TASK_STAT_STOPED)
-			break;
-
-		if (!pAd->PM_FlgSuspend)
-			CMDHandler(pAd);
-	}
-
-	if (pAd && !pAd->PM_FlgSuspend) {	/* Clear the CmdQElements. */
-		struct rt_cmdqelmt *pCmdQElmt = NULL;
-
-		NdisAcquireSpinLock(&pAd->CmdQLock);
-		pAd->CmdQ.CmdQState = RTMP_TASK_STAT_STOPED;
-		while (pAd->CmdQ.size) {
-			RTUSBDequeueCmd(&pAd->CmdQ, &pCmdQElmt);
-			if (pCmdQElmt) {
-				if (pCmdQElmt->CmdFromNdis == TRUE) {
-					if (pCmdQElmt->buffer != NULL)
-						os_free_mem(pAd,
-							    pCmdQElmt->buffer);
-					os_free_mem(pAd, (u8 *)pCmdQElmt);
-				} else {
-					if ((pCmdQElmt->buffer != NULL)
-					    && (pCmdQElmt->bufferlength != 0))
-						os_free_mem(pAd,
-							    pCmdQElmt->buffer);
-					os_free_mem(pAd, (u8 *)pCmdQElmt);
-				}
-			}
-		}
-
-		NdisReleaseSpinLock(&pAd->CmdQLock);
-	}
-	/* notify the exit routine that we're actually exiting now
-	 *
-	 * complete()/wait_for_completion() is similar to up()/down(),
-	 * except that complete() is safe in the case where the structure
-	 * is getting deleted in a parallel mode of execution (i.e. just
-	 * after the down() -- that's necessary for the thread-shutdown
-	 * case.
-	 *
-	 * complete_and_exit() goes even further than this -- it is safe in
-	 * the case that the thread of the caller is going away (not just
-	 * the structure) -- this is necessary for the module-remove case.
-	 * This is important in preemption kernels, which transfer the flow
-	 * of execution immediately upon a complete().
-	 */
-	DBGPRINT(RT_DEBUG_TRACE, ("<---RTUSBCmdThread\n"));
-
-#ifndef KTHREAD_SUPPORT
-	pTask->taskPID = THREAD_PID_INIT_VALUE;
-	complete_and_exit(&pTask->taskComplete, 0);
-#endif
-	return 0;
-
-}
-
-void RTUSBWatchDog(struct rt_rtmp_adapter *pAd)
-{
-	struct rt_ht_tx_context *pHTTXContext;
-	int idx;
-	unsigned long irqFlags;
-	PURB pUrb;
-	BOOLEAN needDumpSeq = FALSE;
-	u32 MACValue;
-	u32 TxRxQ_Pcnt;
-
-	idx = 0;
-	RTMP_IO_READ32(pAd, TXRXQ_PCNT, &MACValue);
-	if ((MACValue & 0xff) != 0) {
-		DBGPRINT(RT_DEBUG_TRACE,
-			 ("TX QUEUE 0 Not EMPTY(Value=0x%0x)!\n",
-			  MACValue));
-		RTMP_IO_WRITE32(pAd, PBF_CFG, 0xf40012);
-		while ((MACValue & 0xff) != 0 && (idx++ < 10)) {
-			RTMP_IO_READ32(pAd, TXRXQ_PCNT, &MACValue);
-			RTMPusecDelay(1);
-		}
-		RTMP_IO_WRITE32(pAd, PBF_CFG, 0xf40006);
-	}
-
-	if (pAd->watchDogRxOverFlowCnt >= 2) {
-		DBGPRINT(RT_DEBUG_TRACE,
-			 ("Maybe the Rx Bulk-In hanged! Cancel the pending Rx bulks request!\n"));
-		if ((!RTMP_TEST_FLAG
-		     (pAd,
-		      (fRTMP_ADAPTER_RESET_IN_PROGRESS |
-		       fRTMP_ADAPTER_BULKIN_RESET |
-		       fRTMP_ADAPTER_HALT_IN_PROGRESS |
-		       fRTMP_ADAPTER_NIC_NOT_EXIST)))) {
-			DBGPRINT(RT_DEBUG_TRACE,
-				 ("Call CMDTHREAD_RESET_BULK_IN to cancel the pending Rx Bulk!\n"));
-			RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKIN_RESET);
-			RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_IN,
-						NULL, 0);
-			needDumpSeq = TRUE;
-		}
-		pAd->watchDogRxOverFlowCnt = 0;
-	}
-
-	RTUSBReadMACRegister(pAd, 0x438, &TxRxQ_Pcnt);
-
-	for (idx = 0; idx < NUM_OF_TX_RING; idx++) {
-		pUrb = NULL;
-
-		RTMP_IRQ_LOCK(&pAd->BulkOutLock[idx], irqFlags);
-		if ((pAd->BulkOutPending[idx] == TRUE)
-		    && pAd->watchDogTxPendingCnt) {
-			int actual_length = 0, transfer_buffer_length = 0;
-			BOOLEAN isDataPacket = FALSE;
-			pAd->watchDogTxPendingCnt[idx]++;
-
-			if ((pAd->watchDogTxPendingCnt[idx] > 2) &&
-			    (!RTMP_TEST_FLAG
-			     (pAd,
-			      (fRTMP_ADAPTER_RESET_IN_PROGRESS |
-			       fRTMP_ADAPTER_HALT_IN_PROGRESS |
-			       fRTMP_ADAPTER_NIC_NOT_EXIST |
-			       fRTMP_ADAPTER_BULKOUT_RESET)))
-			    ) {
-				/* FIXME: Following code just support single bulk out. If you wanna support multiple bulk out. Modify it! */
-				pHTTXContext =
-				    (struct rt_ht_tx_context *)(&pAd->TxContext[idx]);
-				if (pHTTXContext->IRPPending) {	/* Check TxContext. */
-					pUrb = pHTTXContext->pUrb;
-
-					actual_length = pUrb->actual_length;
-					transfer_buffer_length =
-					    pUrb->transfer_buffer_length;
-					isDataPacket = TRUE;
-				} else if (idx == MGMTPIPEIDX) {
-					struct rt_tx_context *pMLMEContext, *pNULLContext,
-					    *pPsPollContext;
-
-					/*Check MgmtContext. */
-					pMLMEContext =
-					    (struct rt_tx_context *)(pAd->MgmtRing.
-							   Cell[pAd->MgmtRing.
-								TxDmaIdx].
-							   AllocVa);
-					pPsPollContext =
-					    (struct rt_tx_context *)(&pAd->PsPollContext);
-					pNULLContext =
-					    (struct rt_tx_context *)(&pAd->NullContext);
-
-					if (pMLMEContext->IRPPending) {
-						ASSERT(pMLMEContext->
-						       IRPPending);
-						pUrb = pMLMEContext->pUrb;
-					} else if (pNULLContext->IRPPending) {
-						ASSERT(pNULLContext->
-						       IRPPending);
-						pUrb = pNULLContext->pUrb;
-					} else if (pPsPollContext->IRPPending) {
-						ASSERT(pPsPollContext->
-						       IRPPending);
-						pUrb = pPsPollContext->pUrb;
-					}
-				}
-
-				RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[idx],
-						irqFlags);
-
-				printk(KERN_INFO "%d:%lu LTL=%d , TL=%d L:%d\n",
-				       idx, pAd->watchDogTxPendingCnt[idx],
-				       pAd->TransferedLength[idx],
-				       actual_length, transfer_buffer_length);
-
-				if (pUrb) {
-					if ((isDataPacket
-					     && pAd->TransferedLength[idx] ==
-					     actual_length
-					     && pAd->TransferedLength[idx] <
-					     transfer_buffer_length
-					     && actual_length != 0
-/*                                      && TxRxQ_Pcnt==0 */
-					     && pAd->watchDogTxPendingCnt[idx] >
-					     3)
-					    || isDataPacket == FALSE
-					    || pAd->watchDogTxPendingCnt[idx] >
-					    6) {
-						DBGPRINT(RT_DEBUG_TRACE,
-							 ("Maybe the Tx Bulk-Out hanged! Cancel the pending Tx bulks request of idx(%d)!\n",
-							  idx));
-						DBGPRINT(RT_DEBUG_TRACE,
-							 ("Unlink the pending URB!\n"));
-						/* unlink it now */
-						RTUSB_UNLINK_URB(pUrb);
-						/* Sleep 200 microseconds to give cancellation time to work */
-						/*RTMPusecDelay(200); */
-						needDumpSeq = TRUE;
-					}
-				} else {
-					DBGPRINT(RT_DEBUG_ERROR,
-						 ("Unknown bulkOut URB maybe hanged!\n"));
-				}
-			} else {
-				RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[idx],
-						irqFlags);
-			}
-
-			if (isDataPacket == TRUE)
-				pAd->TransferedLength[idx] = actual_length;
-		} else {
-			RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[idx], irqFlags);
-		}
-	}
-
-	/* For Sigma debug, dump the ba_reordering sequence. */
-	if ((needDumpSeq == TRUE) && (pAd->CommonCfg.bDisableReordering == 0)) {
-		u16 Idx;
-		struct rt_ba_rec_entry *pBAEntry = NULL;
-		u8 count = 0;
-		struct reordering_mpdu *mpdu_blk;
-
-		Idx = pAd->MacTab.Content[BSSID_WCID].BARecWcidArray[0];
-
-		pBAEntry = &pAd->BATable.BARecEntry[Idx];
-		if ((pBAEntry->list.qlen > 0) && (pBAEntry->list.next != NULL)) {
-			DBGPRINT(RT_DEBUG_TRACE,
-				 ("NICUpdateRawCounters():The Queueing pkt in reordering buffer:\n"));
-			NdisAcquireSpinLock(&pBAEntry->RxReRingLock);
-			mpdu_blk = pBAEntry->list.next;
-			while (mpdu_blk) {
-				DBGPRINT(RT_DEBUG_TRACE,
-					 ("\t%d:Seq-%d, bAMSDU-%d!\n", count,
-					  mpdu_blk->Sequence,
-					  mpdu_blk->bAMSDU));
-				mpdu_blk = mpdu_blk->next;
-				count++;
-			}
-
-			DBGPRINT(RT_DEBUG_TRACE,
-				 ("\npBAEntry->LastIndSeq=%d!\n",
-				  pBAEntry->LastIndSeq));
-			NdisReleaseSpinLock(&pBAEntry->RxReRingLock);
-		}
-	}
-}
-
-/*
-========================================================================
-Routine Description:
-    Release allocated resources.
-
-Arguments:
-    *dev				Point to the PCI or USB device
-	pAd					driver control block pointer
-
-Return Value:
-    None
-
-Note:
-========================================================================
-*/
-static void rt2870_disconnect(struct usb_device *dev, struct rt_rtmp_adapter *pAd)
-{
-	DBGPRINT(RT_DEBUG_ERROR,
-		 ("rtusb_disconnect: unregister usbnet usb-%s-%s\n",
-		  dev->bus->bus_name, dev->devpath));
-	if (!pAd) {
-		usb_put_dev(dev);
-		printk(KERN_ERR "rtusb_disconnect: pAd == NULL!\n");
-		return;
-	}
-	RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST);
-
-	/* for debug, wait to show some messages to /proc system */
-	udelay(1);
-
-	RtmpPhyNetDevExit(pAd, pAd->net_dev);
-
-	/* FIXME: Shall we need following delay and flush the schedule?? */
-	udelay(1);
-	flush_scheduled_work();
-	udelay(1);
-
-	/* free the root net_device */
-	RtmpOSNetDevFree(pAd->net_dev);
-
-	RtmpRaDevCtrlExit(pAd);
-
-	/* release a use of the usb device structure */
-	usb_put_dev(dev);
-	udelay(1);
-
-	DBGPRINT(RT_DEBUG_ERROR, (" RTUSB disconnect successfully\n"));
-}
-
-static int __devinit rt2870_probe(IN struct usb_interface *intf,
-				  IN struct usb_device *usb_dev,
-				  IN const struct usb_device_id *dev_id,
-				  struct rt_rtmp_adapter **ppAd)
-{
-	struct net_device *net_dev = NULL;
-	struct rt_rtmp_adapter *pAd = (struct rt_rtmp_adapter *)NULL;
-	int status, rv;
-	void *handle;
-	struct rt_rtmp_os_netdev_op_hook netDevHook;
-
-	DBGPRINT(RT_DEBUG_TRACE, ("===>rt2870_probe()!\n"));
-
-	/* Check chipset vendor/product ID */
-	/*if (RT28XXChipsetCheck(_dev_p) == FALSE) */
-	/*      goto err_out; */
-
-/*RtmpDevInit============================================= */
-	/* Allocate struct rt_rtmp_adapter adapter structure */
-	handle = kmalloc(sizeof(struct os_cookie), GFP_KERNEL);
-	if (handle == NULL) {
-		printk
-		    ("rt2870_probe(): Allocate memory for os handle failed!\n");
-		return -ENOMEM;
-	}
-	((struct os_cookie *)handle)->pUsb_Dev = usb_dev;
-
-	rv = RTMPAllocAdapterBlock(handle, &pAd);
-	if (rv != NDIS_STATUS_SUCCESS) {
-		kfree(handle);
-		goto err_out;
-	}
-/*USBDevInit============================================== */
-	if (USBDevConfigInit(usb_dev, intf, pAd) == FALSE)
-		goto err_out_free_radev;
-
-	RtmpRaDevCtrlInit(pAd, RTMP_DEV_INF_USB);
-
-/*NetDevInit============================================== */
-	net_dev = RtmpPhyNetDevInit(pAd, &netDevHook);
-	if (net_dev == NULL)
-		goto err_out_free_radev;
-
-	/* Here are the net_device structure with usb specific parameters. 
-	 * for supporting Network Manager.
-	 * Set the sysfs physical device reference for the network logical device if set prior to registration will
-	 * cause a symlink during initialization.
-	 */
-	SET_NETDEV_DEV(net_dev, &(usb_dev->dev));
-
-	pAd->StaCfg.OriDevType = net_dev->type;
-
-/*All done, it's time to register the net device to linux kernel. */
-	/* Register this device */
-	status = RtmpOSNetDevAttach(net_dev, &netDevHook);
-	if (status != 0)
-		goto err_out_free_netdev;
-
-#ifdef KTHREAD_SUPPORT
-	init_waitqueue_head(&pAd->mlmeTask.kthread_q);
-	init_waitqueue_head(&pAd->timerTask.kthread_q);
-	init_waitqueue_head(&pAd->cmdQTask.kthread_q);
-#endif
-
-	*ppAd = pAd;
-
-	DBGPRINT(RT_DEBUG_TRACE, ("<===rt2870_probe()!\n"));
-
-	return 0;
-
-	/* --------------------------- ERROR HANDLE --------------------------- */
-err_out_free_netdev:
-	RtmpOSNetDevFree(net_dev);
-
-err_out_free_radev:
-	RTMPFreeAdapter(pAd);
-
-err_out:
-	*ppAd = NULL;
-
-	return -1;
-
-}
diff -druN linux-2.6.39-libre/drivers/staging/rt2860/wpa.h linux-3.0-rc7-libre/drivers/staging/rt2860/wpa.h
--- linux-2.6.39-libre/drivers/staging/rt2860/wpa.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rt2860/wpa.h	1969-12-31 19:00:00.000000000 -0500
@@ -1,390 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, 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.             *
- *                                                                       *
- *************************************************************************
-
-	Module Name:
-	wpa.h
-
-	Abstract:
-
-	Revision History:
-	Who			When			What
-	--------	----------		----------------------------------------------
-	Name			Date			Modification logs
-	Justin P. Mattock	11/07/2010		Fix a typo
-*/
-
-#ifndef	__WPA_H__
-#define	__WPA_H__
-
-/* EAPOL Key descriptor frame format related length */
-#define LEN_KEY_DESC_NONCE			32
-#define LEN_KEY_DESC_IV				16
-#define LEN_KEY_DESC_RSC			8
-#define LEN_KEY_DESC_ID				8
-#define LEN_KEY_DESC_REPLAY			8
-#define LEN_KEY_DESC_MIC			16
-
-/* The length is the EAPoL-Key frame except key data field. */
-/* Please refer to 802.11i-2004 ,Figure 43u in p.78 */
-#define LEN_EAPOL_KEY_MSG			(sizeof(struct rt_key_descripter) - MAX_LEN_OF_RSNIE)
-
-/* EAP Code Type. */
-#define EAP_CODE_REQUEST	1
-#define EAP_CODE_RESPONSE	2
-#define EAP_CODE_SUCCESS    3
-#define EAP_CODE_FAILURE    4
-
-/* EAPOL frame Protocol Version */
-#define	EAPOL_VER					1
-#define	EAPOL_VER2					2
-
-/* EAPOL-KEY Descriptor Type */
-#define	WPA1_KEY_DESC				0xfe
-#define WPA2_KEY_DESC               0x02
-
-/* Key Descriptor Version of Key Information */
-#define	DESC_TYPE_TKIP				1
-#define	DESC_TYPE_AES				2
-
-#define LEN_MSG1_2WAY               0x7f
-#define MAX_LEN_OF_EAP_HS           256
-
-#define LEN_MASTER_KEY				32
-
-/* EAPOL EK, MK */
-#define LEN_EAP_EK					16
-#define LEN_EAP_MICK				16
-#define LEN_EAP_KEY					((LEN_EAP_EK)+(LEN_EAP_MICK))
-/* TKIP key related */
-#define LEN_PMKID					16
-#define LEN_TKIP_EK					16
-#define LEN_TKIP_RXMICK				8
-#define LEN_TKIP_TXMICK				8
-#define LEN_AES_EK					16
-#define LEN_AES_KEY					LEN_AES_EK
-#define LEN_TKIP_KEY				((LEN_TKIP_EK)+(LEN_TKIP_RXMICK)+(LEN_TKIP_TXMICK))
-#define TKIP_AP_TXMICK_OFFSET		((LEN_EAP_KEY)+(LEN_TKIP_EK))
-#define TKIP_AP_RXMICK_OFFSET		(TKIP_AP_TXMICK_OFFSET+LEN_TKIP_TXMICK)
-#define TKIP_GTK_LENGTH				((LEN_TKIP_EK)+(LEN_TKIP_RXMICK)+(LEN_TKIP_TXMICK))
-#define LEN_PTK						((LEN_EAP_KEY)+(LEN_TKIP_KEY))
-#define MIN_LEN_OF_GTK				5
-#define LEN_PMK						32
-#define LEN_PMK_NAME				16
-#define LEN_NONCE					32
-
-/* RSN IE Length definition */
-#define MAX_LEN_OF_RSNIE		255
-#define MIN_LEN_OF_RSNIE         	8
-
-#define KEY_LIFETIME				3600
-
-/*EAP Packet Type */
-#define	EAPPacket		0
-#define	EAPOLStart		1
-#define	EAPOLLogoff		2
-#define	EAPOLKey		3
-#define	EAPOLASFAlert	4
-#define	EAPTtypeMax		5
-
-#define	EAPOL_MSG_INVALID	0
-#define	EAPOL_PAIR_MSG_1	1
-#define	EAPOL_PAIR_MSG_2	2
-#define	EAPOL_PAIR_MSG_3	3
-#define	EAPOL_PAIR_MSG_4	4
-#define	EAPOL_GROUP_MSG_1	5
-#define	EAPOL_GROUP_MSG_2	6
-
-#define PAIRWISEKEY					1
-#define GROUPKEY					0
-
-/* Retry timer counter initial value */
-#define PEER_MSG1_RETRY_TIMER_CTR           0
-#define PEER_MSG3_RETRY_TIMER_CTR           10
-#define GROUP_MSG1_RETRY_TIMER_CTR          20
-
-/*#ifdef CONFIG_AP_SUPPORT */
-/* WPA mechanism retry timer interval */
-#define PEER_MSG1_RETRY_EXEC_INTV           1000	/* 1 sec */
-#define PEER_MSG3_RETRY_EXEC_INTV           3000	/* 3 sec */
-#define GROUP_KEY_UPDATE_EXEC_INTV          1000	/* 1 sec */
-#define PEER_GROUP_KEY_UPDATE_INIV			2000	/* 2 sec */
-
-#define ENQUEUE_EAPOL_START_TIMER			200	/* 200 ms */
-
-/* group rekey interval */
-#define TIME_REKEY                          0
-#define PKT_REKEY                           1
-#define DISABLE_REKEY                       2
-#define MAX_REKEY                           2
-
-#define MAX_REKEY_INTER                     0x3ffffff
-/*#endif // CONFIG_AP_SUPPORT // */
-
-#define GROUP_SUITE					0
-#define PAIRWISE_SUITE				1
-#define AKM_SUITE					2
-#define PMKID_LIST					3
-
-#define EAPOL_START_DISABLE					0
-#define EAPOL_START_PSK						1
-#define EAPOL_START_1X						2
-
-#define MIX_CIPHER_WPA_TKIP_ON(x)       (((x) & 0x08) != 0)
-#define MIX_CIPHER_WPA_AES_ON(x)        (((x) & 0x04) != 0)
-#define MIX_CIPHER_WPA2_TKIP_ON(x)      (((x) & 0x02) != 0)
-#define MIX_CIPHER_WPA2_AES_ON(x)       (((x) & 0x01) != 0)
-
-#ifndef ROUND_UP
-#define ROUND_UP(__x, __y) \
-	(((unsigned long)((__x)+((__y)-1))) & ((unsigned long)~((__y)-1)))
-#endif
-
-#define	SET_u16_TO_ARRARY(_V, _LEN)		\
-{											\
-	_V[0] = (_LEN & 0xFF00) >> 8;			\
-	_V[1] = (_LEN & 0xFF);					\
-}
-
-#define	INC_u16_TO_ARRARY(_V, _LEN)			\
-{												\
-	u16	var_len;							\
-												\
-	var_len = (_V[0]<<8) | (_V[1]);				\
-	var_len += _LEN;							\
-												\
-	_V[0] = (var_len & 0xFF00) >> 8;			\
-	_V[1] = (var_len & 0xFF);					\
-}
-
-#define	CONV_ARRARY_TO_u16(_V)	((_V[0]<<8) | (_V[1]))
-
-#define	ADD_ONE_To_64BIT_VAR(_V)		\
-{										\
-	u8	cnt = LEN_KEY_DESC_REPLAY;	\
-	do									\
-	{									\
-		cnt--;							\
-		_V[cnt]++;						\
-		if (cnt == 0)					\
-			break;						\
-	}while (_V[cnt] == 0);				\
-}
-
-#define IS_WPA_CAPABILITY(a)       (((a) >= Ndis802_11AuthModeWPA) && ((a) <= Ndis802_11AuthModeWPA1PSKWPA2PSK))
-
-/* EAPOL Key Information definition within Key descriptor format */
-struct PACKED rt_key_info {
-	u8 KeyMic:1;
-	u8 Secure:1;
-	u8 Error:1;
-	u8 Request:1;
-	u8 EKD_DL:1;		/* EKD for AP; DL for STA */
-	u8 Rsvd:3;
-	u8 KeyDescVer:3;
-	u8 KeyType:1;
-	u8 KeyIndex:2;
-	u8 Install:1;
-	u8 KeyAck:1;
-};
-
-/* EAPOL Key descriptor format */
-struct PACKED rt_key_descripter {
-	u8 Type;
-	struct rt_key_info KeyInfo;
-	u8 KeyLength[2];
-	u8 ReplayCounter[LEN_KEY_DESC_REPLAY];
-	u8 KeyNonce[LEN_KEY_DESC_NONCE];
-	u8 KeyIv[LEN_KEY_DESC_IV];
-	u8 KeyRsc[LEN_KEY_DESC_RSC];
-	u8 KeyId[LEN_KEY_DESC_ID];
-	u8 KeyMic[LEN_KEY_DESC_MIC];
-	u8 KeyDataLen[2];
-	u8 KeyData[MAX_LEN_OF_RSNIE];
-};
-
-struct PACKED rt_eapol_packet {
-	u8 ProVer;
-	u8 ProType;
-	u8 Body_Len[2];
-	struct rt_key_descripter KeyDesc;
-};
-
-/*802.11i D10 page 83 */
-struct PACKED rt_gtk_encap {
-	u8 Kid:2;
-	u8 tx:1;
-	u8 rsv:5;
-	u8 rsv1;
-	u8 GTK[TKIP_GTK_LENGTH];
-};
-
-struct PACKED rt_kde_encap {
-	u8 Type;
-	u8 Len;
-	u8 OUI[3];
-	u8 DataType;
-	struct rt_gtk_encap GTKEncap;
-};
-
-/* For WPA1 */
-struct PACKED rt_rsnie {
-	u8 oui[4];
-	u16 version;
-	u8 mcast[4];
-	u16 ucount;
-	struct PACKED {
-		u8 oui[4];
-	} ucast[1];
-};
-
-/* For WPA2 */
-struct PACKED rt_rsnie2 {
-	u16 version;
-	u8 mcast[4];
-	u16 ucount;
-	struct PACKED {
-		u8 oui[4];
-	} ucast[1];
-};
-
-/* AKM Suite */
-struct PACKED rt_rsnie_auth {
-	u16 acount;
-	struct PACKED {
-		u8 oui[4];
-	} auth[1];
-};
-
-typedef union PACKED _RSN_CAPABILITIES {
-	struct PACKED {
-		u16 PreAuth:1;
-		u16 No_Pairwise:1;
-		u16 PTKSA_R_Counter:2;
-		u16 GTKSA_R_Counter:2;
-		u16 Rsvd:10;
-	} field;
-	u16 word;
-} RSN_CAPABILITIES, *PRSN_CAPABILITIES;
-
-struct PACKED rt_eap_hdr {
-	u8 ProVer;
-	u8 ProType;
-	u8 Body_Len[2];
-	u8 code;
-	u8 identifier;
-	u8 length[2];	/* including code and identifier, followed by length-2 octets of data */
-};
-
-/* For supplicant state machine states. 802.11i Draft 4.1, p. 97 */
-/* We simplified it */
-typedef enum _WpaState {
-	SS_NOTUSE,		/* 0 */
-	SS_START,		/* 1 */
-	SS_WAIT_MSG_3,		/* 2 */
-	SS_WAIT_GROUP,		/* 3 */
-	SS_FINISH,		/* 4 */
-	SS_KEYUPDATE,		/* 5 */
-} WPA_STATE;
-
-/* */
-/*      The definition of the cipher combination */
-/* */
-/*       bit3   bit2  bit1   bit0 */
-/*      +------------+------------+ */
-/*      |         WPA    |         WPA2   | */
-/*      +------+-----+------+-----+ */
-/*      | TKIP | AES | TKIP | AES | */
-/*      |       0  |  1  |   1  |  0  | -> 0x06 */
-/*      |       0  |  1  |   1  |  1  | -> 0x07 */
-/*      |       1  |  0  |   0  |  1  | -> 0x09 */
-/*      |       1  |  0  |   1  |  1  | -> 0x0B */
-/*      |       1  |  1  |   0  |  1  | -> 0x0D */
-/*      |       1  |  1  |   1  |  0  | -> 0x0E */
-/*      |       1  |  1  |   1  |  1  | -> 0x0F */
-/*      +------+-----+------+-----+ */
-/* */
-typedef enum _WpaMixPairCipher {
-	MIX_CIPHER_NOTUSE = 0x00,
-	WPA_NONE_WPA2_TKIPAES = 0x03,	/* WPA2-TKIPAES */
-	WPA_AES_WPA2_TKIP = 0x06,
-	WPA_AES_WPA2_TKIPAES = 0x07,
-	WPA_TKIP_WPA2_AES = 0x09,
-	WPA_TKIP_WPA2_TKIPAES = 0x0B,
-	WPA_TKIPAES_WPA2_NONE = 0x0C,	/* WPA-TKIPAES */
-	WPA_TKIPAES_WPA2_AES = 0x0D,
-	WPA_TKIPAES_WPA2_TKIP = 0x0E,
-	WPA_TKIPAES_WPA2_TKIPAES = 0x0F,
-} WPA_MIX_PAIR_CIPHER;
-
-struct PACKED rt_rsn_ie_header {
-	u8 Eid;
-	u8 Length;
-	u16 Version;		/* Little endian format */
-};
-
-/* Cipher suite selector types */
-struct PACKED rt_cipher_suite_struct {
-	u8 Oui[3];
-	u8 Type;
-};
-
-/* Authentication and Key Management suite selector */
-struct PACKED rt_akm_suite {
-	u8 Oui[3];
-	u8 Type;
-};
-
-/* RSN capability */
-struct PACKED rt_rsn_capability {
-	u16 Rsv:10;
-	u16 GTKSAReplayCnt:2;
-	u16 PTKSAReplayCnt:2;
-	u16 NoPairwise:1;
-	u16 PreAuth:1;
-};
-
-/*========================================
-	The prototype is defined in cmm_wpa.c
-  ========================================*/
-BOOLEAN WpaMsgTypeSubst(u8 EAPType, int *MsgType);
-
-void PRF(u8 *key, int key_len, u8 *prefix, int prefix_len,
-	 u8 *data, int data_len, u8 *output, int len);
-
-int PasswordHash(char *password,
-		 unsigned char *ssid, int ssidlength, unsigned char *output);
-
-u8 *GetSuiteFromRSNIE(u8 *rsnie, u32 rsnie_len, u8 type, u8 *count);
-
-void WpaShowAllsuite(u8 *rsnie, u32 rsnie_len);
-
-void RTMPInsertRSNIE(u8 *pFrameBuf,
-		     unsigned long *pFrameLen,
-		     u8 *rsnie_ptr,
-		     u8 rsnie_len,
-		     u8 *pmkid_ptr, u8 pmkid_len);
-
-#endif
diff -druN linux-2.6.39-libre/drivers/staging/rt2870/aironet.h linux-3.0-rc7-libre/drivers/staging/rt2870/aironet.h
--- linux-2.6.39-libre/drivers/staging/rt2870/aironet.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rt2870/aironet.h	1969-12-31 19:00:00.000000000 -0500
@@ -1 +0,0 @@
-#include "../rt2860/aironet.h"
diff -druN linux-2.6.39-libre/drivers/staging/rt2870/ap.h linux-3.0-rc7-libre/drivers/staging/rt2870/ap.h
--- linux-2.6.39-libre/drivers/staging/rt2870/ap.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rt2870/ap.h	1969-12-31 19:00:00.000000000 -0500
@@ -1 +0,0 @@
-#include "../rt2860/ap.h"
diff -druN linux-2.6.39-libre/drivers/staging/rt2870/chips/rt3070.c linux-3.0-rc7-libre/drivers/staging/rt2870/chips/rt3070.c
--- linux-2.6.39-libre/drivers/staging/rt2870/chips/rt3070.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rt2870/chips/rt3070.c	1969-12-31 19:00:00.000000000 -0500
@@ -1 +0,0 @@
-#include "../../rt2860/chips/rt3070.c"
diff -druN linux-2.6.39-libre/drivers/staging/rt2870/chips/rt30xx.c linux-3.0-rc7-libre/drivers/staging/rt2870/chips/rt30xx.c
--- linux-2.6.39-libre/drivers/staging/rt2870/chips/rt30xx.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rt2870/chips/rt30xx.c	1969-12-31 19:00:00.000000000 -0500
@@ -1 +0,0 @@
-#include "../../rt2860/chips/rt30xx.c"
diff -druN linux-2.6.39-libre/drivers/staging/rt2870/chlist.h linux-3.0-rc7-libre/drivers/staging/rt2870/chlist.h
--- linux-2.6.39-libre/drivers/staging/rt2870/chlist.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rt2870/chlist.h	1969-12-31 19:00:00.000000000 -0500
@@ -1 +0,0 @@
-#include "../rt2860/chlist.h"
diff -druN linux-2.6.39-libre/drivers/staging/rt2870/common/acction.c linux-3.0-rc7-libre/drivers/staging/rt2870/common/acction.c
--- linux-2.6.39-libre/drivers/staging/rt2870/common/acction.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rt2870/common/acction.c	1969-12-31 19:00:00.000000000 -0500
@@ -1 +0,0 @@
-#include "../../rt2860/common/action.c"
diff -druN linux-2.6.39-libre/drivers/staging/rt2870/common/action.c linux-3.0-rc7-libre/drivers/staging/rt2870/common/action.c
--- linux-2.6.39-libre/drivers/staging/rt2870/common/action.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rt2870/common/action.c	1969-12-31 19:00:00.000000000 -0500
@@ -1 +0,0 @@
-#include "../../rt2860/common/action.c"
diff -druN linux-2.6.39-libre/drivers/staging/rt2870/common/action.h linux-3.0-rc7-libre/drivers/staging/rt2870/common/action.h
--- linux-2.6.39-libre/drivers/staging/rt2870/common/action.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rt2870/common/action.h	1969-12-31 19:00:00.000000000 -0500
@@ -1 +0,0 @@
-#include "../../rt2860/common/action.h"
diff -druN linux-2.6.39-libre/drivers/staging/rt2870/common/ba_action.c linux-3.0-rc7-libre/drivers/staging/rt2870/common/ba_action.c
--- linux-2.6.39-libre/drivers/staging/rt2870/common/ba_action.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rt2870/common/ba_action.c	1969-12-31 19:00:00.000000000 -0500
@@ -1 +0,0 @@
-#include "../../rt2860/common/ba_action.c"
diff -druN linux-2.6.39-libre/drivers/staging/rt2870/common/cmm_aes.c linux-3.0-rc7-libre/drivers/staging/rt2870/common/cmm_aes.c
--- linux-2.6.39-libre/drivers/staging/rt2870/common/cmm_aes.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rt2870/common/cmm_aes.c	1969-12-31 19:00:00.000000000 -0500
@@ -1 +0,0 @@
-#include "../../rt2860/common/cmm_aes.c"
diff -druN linux-2.6.39-libre/drivers/staging/rt2870/common/cmm_asic.c linux-3.0-rc7-libre/drivers/staging/rt2870/common/cmm_asic.c
--- linux-2.6.39-libre/drivers/staging/rt2870/common/cmm_asic.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rt2870/common/cmm_asic.c	1969-12-31 19:00:00.000000000 -0500
@@ -1 +0,0 @@
-#include "../../rt2860/common/cmm_asic.c"
diff -druN linux-2.6.39-libre/drivers/staging/rt2870/common/cmm_cfg.c linux-3.0-rc7-libre/drivers/staging/rt2870/common/cmm_cfg.c
--- linux-2.6.39-libre/drivers/staging/rt2870/common/cmm_cfg.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rt2870/common/cmm_cfg.c	1969-12-31 19:00:00.000000000 -0500
@@ -1 +0,0 @@
-#include "../../rt2860/common/cmm_cfg.c"
diff -druN linux-2.6.39-libre/drivers/staging/rt2870/common/cmm_data.c linux-3.0-rc7-libre/drivers/staging/rt2870/common/cmm_data.c
--- linux-2.6.39-libre/drivers/staging/rt2870/common/cmm_data.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rt2870/common/cmm_data.c	1969-12-31 19:00:00.000000000 -0500
@@ -1 +0,0 @@
-#include "../../rt2860/common/cmm_data.c"
diff -druN linux-2.6.39-libre/drivers/staging/rt2870/common/cmm_data_usb.c linux-3.0-rc7-libre/drivers/staging/rt2870/common/cmm_data_usb.c
--- linux-2.6.39-libre/drivers/staging/rt2870/common/cmm_data_usb.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rt2870/common/cmm_data_usb.c	1969-12-31 19:00:00.000000000 -0500
@@ -1 +0,0 @@
-#include "../../rt2860/common/cmm_data_usb.c"
diff -druN linux-2.6.39-libre/drivers/staging/rt2870/common/cmm_info.c linux-3.0-rc7-libre/drivers/staging/rt2870/common/cmm_info.c
--- linux-2.6.39-libre/drivers/staging/rt2870/common/cmm_info.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rt2870/common/cmm_info.c	1969-12-31 19:00:00.000000000 -0500
@@ -1 +0,0 @@
-#include "../../rt2860/common/cmm_info.c"
diff -druN linux-2.6.39-libre/drivers/staging/rt2870/common/cmm_mac_usb.c linux-3.0-rc7-libre/drivers/staging/rt2870/common/cmm_mac_usb.c
--- linux-2.6.39-libre/drivers/staging/rt2870/common/cmm_mac_usb.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rt2870/common/cmm_mac_usb.c	1969-12-31 19:00:00.000000000 -0500
@@ -1 +0,0 @@
-#include "../../rt2860/common/cmm_mac_usb.c"
diff -druN linux-2.6.39-libre/drivers/staging/rt2870/common/cmm_profile.c linux-3.0-rc7-libre/drivers/staging/rt2870/common/cmm_profile.c
--- linux-2.6.39-libre/drivers/staging/rt2870/common/cmm_profile.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rt2870/common/cmm_profile.c	1969-12-31 19:00:00.000000000 -0500
@@ -1 +0,0 @@
-#include "../../rt2860/common/cmm_profile.c"
diff -druN linux-2.6.39-libre/drivers/staging/rt2870/common/cmm_sanity.c linux-3.0-rc7-libre/drivers/staging/rt2870/common/cmm_sanity.c
--- linux-2.6.39-libre/drivers/staging/rt2870/common/cmm_sanity.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rt2870/common/cmm_sanity.c	1969-12-31 19:00:00.000000000 -0500
@@ -1 +0,0 @@
-#include "../../rt2860/common/cmm_sanity.c"
diff -druN linux-2.6.39-libre/drivers/staging/rt2870/common/cmm_sync.c linux-3.0-rc7-libre/drivers/staging/rt2870/common/cmm_sync.c
--- linux-2.6.39-libre/drivers/staging/rt2870/common/cmm_sync.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rt2870/common/cmm_sync.c	1969-12-31 19:00:00.000000000 -0500
@@ -1 +0,0 @@
-#include "../../rt2860/common/cmm_sync.c"
diff -druN linux-2.6.39-libre/drivers/staging/rt2870/common/cmm_tkip.c linux-3.0-rc7-libre/drivers/staging/rt2870/common/cmm_tkip.c
--- linux-2.6.39-libre/drivers/staging/rt2870/common/cmm_tkip.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rt2870/common/cmm_tkip.c	1969-12-31 19:00:00.000000000 -0500
@@ -1 +0,0 @@
-#include "../../rt2860/common/cmm_tkip.c"
diff -druN linux-2.6.39-libre/drivers/staging/rt2870/common/cmm_wep.c linux-3.0-rc7-libre/drivers/staging/rt2870/common/cmm_wep.c
--- linux-2.6.39-libre/drivers/staging/rt2870/common/cmm_wep.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rt2870/common/cmm_wep.c	1969-12-31 19:00:00.000000000 -0500
@@ -1 +0,0 @@
-#include "../../rt2860/common/cmm_wep.c"
diff -druN linux-2.6.39-libre/drivers/staging/rt2870/common/cmm_wpa.c linux-3.0-rc7-libre/drivers/staging/rt2870/common/cmm_wpa.c
--- linux-2.6.39-libre/drivers/staging/rt2870/common/cmm_wpa.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rt2870/common/cmm_wpa.c	1969-12-31 19:00:00.000000000 -0500
@@ -1 +0,0 @@
-#include "../../rt2860/common/cmm_wpa.c"
diff -druN linux-2.6.39-libre/drivers/staging/rt2870/common/crypt_hmac.c linux-3.0-rc7-libre/drivers/staging/rt2870/common/crypt_hmac.c
--- linux-2.6.39-libre/drivers/staging/rt2870/common/crypt_hmac.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rt2870/common/crypt_hmac.c	1969-12-31 19:00:00.000000000 -0500
@@ -1 +0,0 @@
-#include "../../rt2860/common/crypt_hmac.c"
diff -druN linux-2.6.39-libre/drivers/staging/rt2870/common/crypt_md5.c linux-3.0-rc7-libre/drivers/staging/rt2870/common/crypt_md5.c
--- linux-2.6.39-libre/drivers/staging/rt2870/common/crypt_md5.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rt2870/common/crypt_md5.c	1969-12-31 19:00:00.000000000 -0500
@@ -1 +0,0 @@
-#include "../../rt2860/common/crypt_md5.c"
diff -druN linux-2.6.39-libre/drivers/staging/rt2870/common/crypt_sha2.c linux-3.0-rc7-libre/drivers/staging/rt2870/common/crypt_sha2.c
--- linux-2.6.39-libre/drivers/staging/rt2870/common/crypt_sha2.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rt2870/common/crypt_sha2.c	1969-12-31 19:00:00.000000000 -0500
@@ -1 +0,0 @@
-#include "../../rt2860/common/crypt_sha2.c"
diff -druN linux-2.6.39-libre/drivers/staging/rt2870/common/dfs.c linux-3.0-rc7-libre/drivers/staging/rt2870/common/dfs.c
--- linux-2.6.39-libre/drivers/staging/rt2870/common/dfs.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rt2870/common/dfs.c	1969-12-31 19:00:00.000000000 -0500
@@ -1 +0,0 @@
-#include "../../rt2860/common/dfs.c"
diff -druN linux-2.6.39-libre/drivers/staging/rt2870/common/ee_efuse.c linux-3.0-rc7-libre/drivers/staging/rt2870/common/ee_efuse.c
--- linux-2.6.39-libre/drivers/staging/rt2870/common/ee_efuse.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rt2870/common/ee_efuse.c	1969-12-31 19:00:00.000000000 -0500
@@ -1 +0,0 @@
-#include "../../rt2860/common/ee_efuse.c"
diff -druN linux-2.6.39-libre/drivers/staging/rt2870/common/eeprom.c linux-3.0-rc7-libre/drivers/staging/rt2870/common/eeprom.c
--- linux-2.6.39-libre/drivers/staging/rt2870/common/eeprom.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rt2870/common/eeprom.c	1969-12-31 19:00:00.000000000 -0500
@@ -1 +0,0 @@
-#include "../../rt2860/common/eeprom.c"
diff -druN linux-2.6.39-libre/drivers/staging/rt2870/common/md5.c linux-3.0-rc7-libre/drivers/staging/rt2870/common/md5.c
--- linux-2.6.39-libre/drivers/staging/rt2870/common/md5.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rt2870/common/md5.c	1969-12-31 19:00:00.000000000 -0500
@@ -1 +0,0 @@
-#include "../../rt2860/common/md5.c"
diff -druN linux-2.6.39-libre/drivers/staging/rt2870/common/mlme.c linux-3.0-rc7-libre/drivers/staging/rt2870/common/mlme.c
--- linux-2.6.39-libre/drivers/staging/rt2870/common/mlme.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rt2870/common/mlme.c	1969-12-31 19:00:00.000000000 -0500
@@ -1 +0,0 @@
-#include "../../rt2860/common/mlme.c"
diff -druN linux-2.6.39-libre/drivers/staging/rt2870/common/rt_channel.c linux-3.0-rc7-libre/drivers/staging/rt2870/common/rt_channel.c
--- linux-2.6.39-libre/drivers/staging/rt2870/common/rt_channel.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rt2870/common/rt_channel.c	1969-12-31 19:00:00.000000000 -0500
@@ -1 +0,0 @@
-#include "../../rt2860/common/rt_channel.c"
diff -druN linux-2.6.39-libre/drivers/staging/rt2870/common/rtmp_init.c linux-3.0-rc7-libre/drivers/staging/rt2870/common/rtmp_init.c
--- linux-2.6.39-libre/drivers/staging/rt2870/common/rtmp_init.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rt2870/common/rtmp_init.c	1969-12-31 19:00:00.000000000 -0500
@@ -1 +0,0 @@
-#include "../../rt2860/common/rtmp_init.c"
diff -druN linux-2.6.39-libre/drivers/staging/rt2870/common/rtmp_mcu.c linux-3.0-rc7-libre/drivers/staging/rt2870/common/rtmp_mcu.c
--- linux-2.6.39-libre/drivers/staging/rt2870/common/rtmp_mcu.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rt2870/common/rtmp_mcu.c	1969-12-31 19:00:00.000000000 -0500
@@ -1 +0,0 @@
-#include "../../rt2860/common/rtmp_mcu.c"
diff -druN linux-2.6.39-libre/drivers/staging/rt2870/common/rtmp_timer.c linux-3.0-rc7-libre/drivers/staging/rt2870/common/rtmp_timer.c
--- linux-2.6.39-libre/drivers/staging/rt2870/common/rtmp_timer.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rt2870/common/rtmp_timer.c	1969-12-31 19:00:00.000000000 -0500
@@ -1 +0,0 @@
-#include "../../rt2860/common/rtmp_timer.c"
diff -druN linux-2.6.39-libre/drivers/staging/rt2870/common/rtmp_tkip.c linux-3.0-rc7-libre/drivers/staging/rt2870/common/rtmp_tkip.c
--- linux-2.6.39-libre/drivers/staging/rt2870/common/rtmp_tkip.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rt2870/common/rtmp_tkip.c	1969-12-31 19:00:00.000000000 -0500
@@ -1 +0,0 @@
-#include "../../rt2860/common/rtmp_tkip.c"
diff -druN linux-2.6.39-libre/drivers/staging/rt2870/common/rtmp_wep.c linux-3.0-rc7-libre/drivers/staging/rt2870/common/rtmp_wep.c
--- linux-2.6.39-libre/drivers/staging/rt2870/common/rtmp_wep.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rt2870/common/rtmp_wep.c	1969-12-31 19:00:00.000000000 -0500
@@ -1 +0,0 @@
-#include "../../rt2860/common/rtmp_wep.c"
diff -druN linux-2.6.39-libre/drivers/staging/rt2870/common/rt_rf.c linux-3.0-rc7-libre/drivers/staging/rt2870/common/rt_rf.c
--- linux-2.6.39-libre/drivers/staging/rt2870/common/rt_rf.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rt2870/common/rt_rf.c	1969-12-31 19:00:00.000000000 -0500
@@ -1 +0,0 @@
-#include "../../rt2860/common/rt_rf.c"
diff -druN linux-2.6.39-libre/drivers/staging/rt2870/common/rtusb_bulk.c linux-3.0-rc7-libre/drivers/staging/rt2870/common/rtusb_bulk.c
--- linux-2.6.39-libre/drivers/staging/rt2870/common/rtusb_bulk.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rt2870/common/rtusb_bulk.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,1232 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, 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.             *
- *                                                                       *
- *************************************************************************
-
-	Module Name:
-	rtusb_bulk.c
-
-	Abstract:
-
-	Revision History:
-	Who			When		What
-	--------	----------	----------------------------------------------
-	Name		Date		Modification logs
-	Paul Lin	06-25-2004	created
-
-*/
-
-#ifdef RTMP_MAC_USB
-
-#include "../rt_config.h"
-/* Match total 6 bulkout endpoint to corresponding queue. */
-u8 EpToQueue[6] =
-    { FIFO_EDCA, FIFO_EDCA, FIFO_EDCA, FIFO_EDCA, FIFO_EDCA, FIFO_MGMT };
-
-/*static BOOLEAN SingleBulkOut = FALSE; */
-
-void RTUSB_FILL_BULK_URB(struct urb *pUrb,
-			 struct usb_device *pUsb_Dev,
-			 unsigned int bulkpipe,
-			 void *pTransferBuf,
-			 int BufSize, usb_complete_t Complete, void *pContext)
-{
-
-	usb_fill_bulk_urb(pUrb, pUsb_Dev, bulkpipe, pTransferBuf, BufSize,
-			  (usb_complete_t) Complete, pContext);
-
-}
-
-void RTUSBInitTxDesc(struct rt_rtmp_adapter *pAd,
-		     struct rt_tx_context *pTxContext,
-		     u8 BulkOutPipeId, IN usb_complete_t Func)
-{
-	PURB pUrb;
-	u8 *pSrc = NULL;
-	struct os_cookie *pObj = (struct os_cookie *)pAd->OS_Cookie;
-
-	pUrb = pTxContext->pUrb;
-	ASSERT(pUrb);
-
-	/* Store BulkOut PipeId */
-	pTxContext->BulkOutPipeId = BulkOutPipeId;
-
-	if (pTxContext->bAggregatible) {
-		pSrc = &pTxContext->TransferBuffer->Aggregation[2];
-	} else {
-		pSrc =
-		    (u8 *)pTxContext->TransferBuffer->field.WirelessPacket;
-	}
-
-	/*Initialize a tx bulk urb */
-	RTUSB_FILL_BULK_URB(pUrb,
-			    pObj->pUsb_Dev,
-			    usb_sndbulkpipe(pObj->pUsb_Dev,
-					    pAd->BulkOutEpAddr[BulkOutPipeId]),
-			    pSrc, pTxContext->BulkOutSize, Func, pTxContext);
-
-	if (pTxContext->bAggregatible)
-		pUrb->transfer_dma =
-		    (pTxContext->data_dma + TX_BUFFER_NORMSIZE + 2);
-	else
-		pUrb->transfer_dma = pTxContext->data_dma;
-
-	pUrb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
-
-}
-
-void RTUSBInitHTTxDesc(struct rt_rtmp_adapter *pAd,
-		       struct rt_ht_tx_context *pTxContext,
-		       u8 BulkOutPipeId,
-		       unsigned long BulkOutSize, IN usb_complete_t Func)
-{
-	PURB pUrb;
-	u8 *pSrc = NULL;
-	struct os_cookie *pObj = (struct os_cookie *)pAd->OS_Cookie;
-
-	pUrb = pTxContext->pUrb;
-	ASSERT(pUrb);
-
-	/* Store BulkOut PipeId */
-	pTxContext->BulkOutPipeId = BulkOutPipeId;
-
-	pSrc =
-	    &pTxContext->TransferBuffer->field.WirelessPacket[pTxContext->
-							      NextBulkOutPosition];
-
-	/*Initialize a tx bulk urb */
-	RTUSB_FILL_BULK_URB(pUrb,
-			    pObj->pUsb_Dev,
-			    usb_sndbulkpipe(pObj->pUsb_Dev,
-					    pAd->BulkOutEpAddr[BulkOutPipeId]),
-			    pSrc, BulkOutSize, Func, pTxContext);
-
-	pUrb->transfer_dma =
-	    (pTxContext->data_dma + pTxContext->NextBulkOutPosition);
-	pUrb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
-
-}
-
-void RTUSBInitRxDesc(struct rt_rtmp_adapter *pAd, struct rt_rx_context *pRxContext)
-{
-	PURB pUrb;
-	struct os_cookie *pObj = (struct os_cookie *)pAd->OS_Cookie;
-	unsigned long RX_bulk_size;
-
-	pUrb = pRxContext->pUrb;
-	ASSERT(pUrb);
-
-	if (pAd->BulkInMaxPacketSize == 64)
-		RX_bulk_size = 4096;
-	else
-		RX_bulk_size = MAX_RXBULK_SIZE;
-
-	/*Initialize a rx bulk urb */
-	RTUSB_FILL_BULK_URB(pUrb,
-			    pObj->pUsb_Dev,
-			    usb_rcvbulkpipe(pObj->pUsb_Dev, pAd->BulkInEpAddr),
-			    &(pRxContext->
-			      TransferBuffer[pAd->NextRxBulkInPosition]),
-			    RX_bulk_size - (pAd->NextRxBulkInPosition),
-			    (usb_complete_t) RTUSBBulkRxComplete,
-			    (void *)pRxContext);
-
-	pUrb->transfer_dma = pRxContext->data_dma + pAd->NextRxBulkInPosition;
-	pUrb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
-
-}
-
-/*
-	========================================================================
-
-	Routine Description:
-
-	Arguments:
-
-	Return Value:
-
-	Note:
-
-	========================================================================
-*/
-
-#define BULK_OUT_LOCK(pLock, IrqFlags)	\
-		if (1 /*!(in_interrupt() & 0xffff0000)*/)	\
-			RTMP_IRQ_LOCK((pLock), IrqFlags);
-
-#define BULK_OUT_UNLOCK(pLock, IrqFlags)	\
-		if (1 /*!(in_interrupt() & 0xffff0000)*/)	\
-			RTMP_IRQ_UNLOCK((pLock), IrqFlags);
-
-void RTUSBBulkOutDataPacket(struct rt_rtmp_adapter *pAd,
-			    u8 BulkOutPipeId, u8 Index)
-{
-
-	struct rt_ht_tx_context *pHTTXContext;
-	PURB pUrb;
-	int ret = 0;
-	struct rt_txinfo *pTxInfo, *pLastTxInfo = NULL;
-	struct rt_txwi *pTxWI;
-	unsigned long TmpBulkEndPos, ThisBulkSize;
-	unsigned long IrqFlags = 0, IrqFlags2 = 0;
-	u8 *pWirelessPkt, *pAppendant;
-	BOOLEAN bTxQLastRound = FALSE;
-	u8 allzero[4] = { 0x0, 0x0, 0x0, 0x0 };
-
-	BULK_OUT_LOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
-	if ((pAd->BulkOutPending[BulkOutPipeId] == TRUE)
-	    || RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NEED_STOP_TX)) {
-		BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
-		return;
-	}
-	pAd->BulkOutPending[BulkOutPipeId] = TRUE;
-
-	if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED)
-	    ) {
-		pAd->BulkOutPending[BulkOutPipeId] = FALSE;
-		BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
-		return;
-	}
-	BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
-
-	pHTTXContext = &(pAd->TxContext[BulkOutPipeId]);
-
-	BULK_OUT_LOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags2);
-	if ((pHTTXContext->ENextBulkOutPosition ==
-	     pHTTXContext->CurWritePosition)
-	    || ((pHTTXContext->ENextBulkOutPosition - 8) ==
-		pHTTXContext->CurWritePosition)) {
-		BULK_OUT_UNLOCK(&pAd->TxContextQueueLock[BulkOutPipeId],
-				IrqFlags2);
-
-		BULK_OUT_LOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
-		pAd->BulkOutPending[BulkOutPipeId] = FALSE;
-
-		/* Clear Data flag */
-		RTUSB_CLEAR_BULK_FLAG(pAd,
-				      (fRTUSB_BULK_OUT_DATA_FRAG <<
-				       BulkOutPipeId));
-		RTUSB_CLEAR_BULK_FLAG(pAd,
-				      (fRTUSB_BULK_OUT_DATA_NORMAL <<
-				       BulkOutPipeId));
-
-		BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
-		return;
-	}
-	/* Clear Data flag */
-	RTUSB_CLEAR_BULK_FLAG(pAd,
-			      (fRTUSB_BULK_OUT_DATA_FRAG << BulkOutPipeId));
-	RTUSB_CLEAR_BULK_FLAG(pAd,
-			      (fRTUSB_BULK_OUT_DATA_NORMAL << BulkOutPipeId));
-
-	/*DBGPRINT(RT_DEBUG_TRACE,("BulkOut-B:I=0x%lx, CWPos=%ld, CWRPos=%ld, NBPos=%ld, ENBPos=%ld, bCopy=%d!\n", in_interrupt(), */
-	/*                                                      pHTTXContext->CurWritePosition, pHTTXContext->CurWriteRealPos, pHTTXContext->NextBulkOutPosition, */
-	/*                                                      pHTTXContext->ENextBulkOutPosition, pHTTXContext->bCopySavePad)); */
-	pHTTXContext->NextBulkOutPosition = pHTTXContext->ENextBulkOutPosition;
-	ThisBulkSize = 0;
-	TmpBulkEndPos = pHTTXContext->NextBulkOutPosition;
-	pWirelessPkt = &pHTTXContext->TransferBuffer->field.WirelessPacket[0];
-
-	if ((pHTTXContext->bCopySavePad == TRUE)) {
-		if (RTMPEqualMemory(pHTTXContext->SavedPad, allzero, 4)) {
-			DBGPRINT_RAW(RT_DEBUG_ERROR,
-				     ("e1, allzero : %x  %x  %x  %x  %x  %x  %x  %x \n",
-				      pHTTXContext->SavedPad[0],
-				      pHTTXContext->SavedPad[1],
-				      pHTTXContext->SavedPad[2],
-				      pHTTXContext->SavedPad[3]
-				      , pHTTXContext->SavedPad[4],
-				      pHTTXContext->SavedPad[5],
-				      pHTTXContext->SavedPad[6],
-				      pHTTXContext->SavedPad[7]));
-		}
-		NdisMoveMemory(&pWirelessPkt[TmpBulkEndPos],
-			       pHTTXContext->SavedPad, 8);
-		pHTTXContext->bCopySavePad = FALSE;
-		if (pAd->bForcePrintTX == TRUE)
-			DBGPRINT(RT_DEBUG_TRACE,
-				 ("RTUSBBulkOutDataPacket --> COPY PAD. CurWrite = %ld, NextBulk = %ld.   ENextBulk = %ld.\n",
-				  pHTTXContext->CurWritePosition,
-				  pHTTXContext->NextBulkOutPosition,
-				  pHTTXContext->ENextBulkOutPosition));
-	}
-
-	do {
-		pTxInfo = (struct rt_txinfo *)&pWirelessPkt[TmpBulkEndPos];
-		pTxWI =
-			(struct rt_txwi *)&pWirelessPkt[TmpBulkEndPos + TXINFO_SIZE];
-
-		if (pAd->bForcePrintTX == TRUE)
-			DBGPRINT(RT_DEBUG_TRACE,
-				 ("RTUSBBulkOutDataPacket AMPDU = %d.\n",
-				  pTxWI->AMPDU));
-
-		/* add by Iverson, limit BulkOut size to 4k to pass WMM b mode 2T1R test items */
-		/*if ((ThisBulkSize != 0)  && (pTxWI->AMPDU == 0)) */
-		if ((ThisBulkSize != 0) && (pTxWI->PHYMODE == MODE_CCK)) {
-			if (((ThisBulkSize & 0xffff8000) != 0)
-			    || ((ThisBulkSize & 0x1000) == 0x1000)) {
-				/* Limit BulkOut size to about 4k bytes. */
-				pHTTXContext->ENextBulkOutPosition =
-				    TmpBulkEndPos;
-				break;
-			} else
-			    if (((pAd->BulkOutMaxPacketSize < 512)
-				 && ((ThisBulkSize & 0xfffff800) !=
-				     0))
-				/*|| ( (ThisBulkSize != 0)  && (pTxWI->AMPDU == 0)) */
-				) {
-				/* For USB 1.1 or peer which didn't support AMPDU, limit the BulkOut size. */
-				/* For performance in b/g mode, now just check for USB 1.1 and didn't care about the APMDU or not! 2008/06/04. */
-				pHTTXContext->ENextBulkOutPosition =
-				    TmpBulkEndPos;
-				break;
-			}
-		}
-		/* end Iverson */
-		else {
-			if (((ThisBulkSize & 0xffff8000) != 0) || ((ThisBulkSize & 0x6000) == 0x6000)) {	/* Limit BulkOut size to about 24k bytes. */
-				pHTTXContext->ENextBulkOutPosition =
-				    TmpBulkEndPos;
-				break;
-			} else if (((pAd->BulkOutMaxPacketSize < 512) && ((ThisBulkSize & 0xfffff800) != 0)) /*|| ( (ThisBulkSize != 0)  && (pTxWI->AMPDU == 0)) */) {	/* For USB 1.1 or peer which didn't support AMPDU, limit the BulkOut size. */
-				/* For performance in b/g mode, now just check for USB 1.1 and didn't care about the APMDU or not! 2008/06/04. */
-				pHTTXContext->ENextBulkOutPosition =
-				    TmpBulkEndPos;
-				break;
-			}
-		}
-
-		if (TmpBulkEndPos == pHTTXContext->CurWritePosition) {
-			pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos;
-			break;
-		}
-
-		if (pTxInfo->QSEL != FIFO_EDCA) {
-			DBGPRINT(RT_DEBUG_ERROR,
-				 ("%s(): ====> pTxInfo->QueueSel(%d)!= FIFO_EDCA!!!!\n",
-				  __func__, pTxInfo->QSEL));
-			DBGPRINT(RT_DEBUG_ERROR,
-				 ("\tCWPos=%ld, NBPos=%ld, ENBPos=%ld, bCopy=%d!\n",
-				  pHTTXContext->CurWritePosition,
-				  pHTTXContext->NextBulkOutPosition,
-				  pHTTXContext->ENextBulkOutPosition,
-				  pHTTXContext->bCopySavePad));
-			hex_dump("Wrong QSel Pkt:",
-				 (u8 *)&pWirelessPkt[TmpBulkEndPos],
-				 (pHTTXContext->CurWritePosition -
-				  pHTTXContext->NextBulkOutPosition));
-		}
-
-		if (pTxInfo->USBDMATxPktLen <= 8) {
-			BULK_OUT_UNLOCK(&pAd->TxContextQueueLock[BulkOutPipeId],
-					IrqFlags2);
-			DBGPRINT(RT_DEBUG_ERROR /*RT_DEBUG_TRACE */ ,
-				 ("e2, USBDMATxPktLen==0, Size=%ld, bCSPad=%d, CWPos=%ld, NBPos=%ld, CWRPos=%ld!\n",
-				  pHTTXContext->BulkOutSize,
-				  pHTTXContext->bCopySavePad,
-				  pHTTXContext->CurWritePosition,
-				  pHTTXContext->NextBulkOutPosition,
-				  pHTTXContext->CurWriteRealPos));
-			{
-				DBGPRINT_RAW(RT_DEBUG_ERROR /*RT_DEBUG_TRACE */
-					     ,
-					     ("%x  %x  %x  %x  %x  %x  %x  %x \n",
-					      pHTTXContext->SavedPad[0],
-					      pHTTXContext->SavedPad[1],
-					      pHTTXContext->SavedPad[2],
-					      pHTTXContext->SavedPad[3]
-					      , pHTTXContext->SavedPad[4],
-					      pHTTXContext->SavedPad[5],
-					      pHTTXContext->SavedPad[6],
-					      pHTTXContext->SavedPad[7]));
-			}
-			pAd->bForcePrintTX = TRUE;
-			BULK_OUT_LOCK(&pAd->BulkOutLock[BulkOutPipeId],
-				      IrqFlags);
-			pAd->BulkOutPending[BulkOutPipeId] = FALSE;
-			BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId],
-					IrqFlags);
-			/*DBGPRINT(RT_DEBUG_LOUD,("Out:pTxInfo->USBDMATxPktLen=%d!\n", pTxInfo->USBDMATxPktLen)); */
-			return;
-		}
-		/* Increase Total transmit byte counter */
-		pAd->RalinkCounters.OneSecTransmittedByteCount +=
-		    pTxWI->MPDUtotalByteCount;
-		pAd->RalinkCounters.TransmittedByteCount +=
-		    pTxWI->MPDUtotalByteCount;
-
-		pLastTxInfo = pTxInfo;
-
-		/* Make sure we use EDCA QUEUE. */
-		pTxInfo->QSEL = FIFO_EDCA;
-		ThisBulkSize += (pTxInfo->USBDMATxPktLen + 4);
-		TmpBulkEndPos += (pTxInfo->USBDMATxPktLen + 4);
-
-		if (TmpBulkEndPos != pHTTXContext->CurWritePosition)
-			pTxInfo->USBDMANextVLD = 1;
-
-		if (pTxInfo->SwUseLastRound == 1) {
-			if (pHTTXContext->CurWritePosition == 8)
-				pTxInfo->USBDMANextVLD = 0;
-			pTxInfo->SwUseLastRound = 0;
-
-			bTxQLastRound = TRUE;
-			pHTTXContext->ENextBulkOutPosition = 8;
-
-			break;
-		}
-
-	} while (TRUE);
-
-	/* adjust the pTxInfo->USBDMANextVLD value of last pTxInfo. */
-	if (pLastTxInfo)
-		pLastTxInfo->USBDMANextVLD = 0;
-
-	/*
-	   We need to copy SavedPad when following condition matched!
-	   1. Not the last round of the TxQueue and
-	   2. any match of following cases:
-	   (1). The End Position of this bulk out is reach to the Currenct Write position and
-	   the TxInfo and related header already write to the CurWritePosition.
-	   =>(ENextBulkOutPosition == CurWritePosition) && (CurWriteRealPos > CurWritePosition)
-
-	   (2). The EndPosition of the bulk out is not reach to the Current Write Position.
-	   =>(ENextBulkOutPosition != CurWritePosition)
-	 */
-	if ((bTxQLastRound == FALSE) &&
-	    (((pHTTXContext->ENextBulkOutPosition ==
-	       pHTTXContext->CurWritePosition)
-	      && (pHTTXContext->CurWriteRealPos >
-		  pHTTXContext->CurWritePosition))
-	     || (pHTTXContext->ENextBulkOutPosition !=
-		 pHTTXContext->CurWritePosition))
-	    ) {
-		NdisMoveMemory(pHTTXContext->SavedPad,
-			       &pWirelessPkt[pHTTXContext->
-					     ENextBulkOutPosition], 8);
-		pHTTXContext->bCopySavePad = TRUE;
-		if (RTMPEqualMemory(pHTTXContext->SavedPad, allzero, 4)) {
-			u8 *pBuf = &pHTTXContext->SavedPad[0];
-			DBGPRINT_RAW(RT_DEBUG_ERROR,
-				     ("WARNING-Zero-3:%02x%02x%02x%02x%02x%02x%02x%02x,CWPos=%ld, CWRPos=%ld, bCW=%d, NBPos=%ld, TBPos=%ld, TBSize=%ld\n",
-				      pBuf[0], pBuf[1], pBuf[2], pBuf[3],
-				      pBuf[4], pBuf[5], pBuf[6], pBuf[7],
-				      pHTTXContext->CurWritePosition,
-				      pHTTXContext->CurWriteRealPos,
-				      pHTTXContext->bCurWriting,
-				      pHTTXContext->NextBulkOutPosition,
-				      TmpBulkEndPos, ThisBulkSize));
-
-			pBuf = &pWirelessPkt[pHTTXContext->CurWritePosition];
-			DBGPRINT_RAW(RT_DEBUG_ERROR,
-				     ("\tCWPos=%02x%02x%02x%02x%02x%02x%02x%02x\n",
-				      pBuf[0], pBuf[1], pBuf[2], pBuf[3],
-				      pBuf[4], pBuf[5], pBuf[6], pBuf[7]));
-		}
-		/*DBGPRINT(RT_DEBUG_LOUD,("ENPos==CWPos=%ld, CWRPos=%ld, bCSPad=%d!\n", pHTTXContext->CurWritePosition, pHTTXContext->CurWriteRealPos, pHTTXContext->bCopySavePad)); */
-	}
-
-	if (pAd->bForcePrintTX == TRUE)
-		DBGPRINT(RT_DEBUG_TRACE,
-			 ("BulkOut-A:Size=%ld, CWPos=%ld, NBPos=%ld, ENBPos=%ld, bCopy=%d!\n",
-			  ThisBulkSize, pHTTXContext->CurWritePosition,
-			  pHTTXContext->NextBulkOutPosition,
-			  pHTTXContext->ENextBulkOutPosition,
-			  pHTTXContext->bCopySavePad));
-	/*DBGPRINT(RT_DEBUG_LOUD,("BulkOut-A:Size=%ld, CWPos=%ld, CWRPos=%ld, NBPos=%ld, ENBPos=%ld, bCopy=%d, bLRound=%d!\n", ThisBulkSize, pHTTXContext->CurWritePosition, pHTTXContext->CurWriteRealPos, pHTTXContext->NextBulkOutPosition, pHTTXContext->ENextBulkOutPosition, pHTTXContext->bCopySavePad, bTxQLastRound)); */
-
-	/* USB DMA engine requires to pad extra 4 bytes. This pad doesn't count into real bulkoutsize. */
-	pAppendant = &pWirelessPkt[TmpBulkEndPos];
-	NdisZeroMemory(pAppendant, 8);
-	ThisBulkSize += 4;
-	pHTTXContext->LastOne = TRUE;
-	if ((ThisBulkSize % pAd->BulkOutMaxPacketSize) == 0)
-		ThisBulkSize += 4;
-	pHTTXContext->BulkOutSize = ThisBulkSize;
-
-	pAd->watchDogTxPendingCnt[BulkOutPipeId] = 1;
-	BULK_OUT_UNLOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags2);
-
-	/* Init Tx context descriptor */
-	RTUSBInitHTTxDesc(pAd, pHTTXContext, BulkOutPipeId, ThisBulkSize,
-			  (usb_complete_t) RTUSBBulkOutDataPacketComplete);
-
-	pUrb = pHTTXContext->pUrb;
-	ret = RTUSB_SUBMIT_URB(pUrb);
-	if (ret != 0) {
-		DBGPRINT(RT_DEBUG_ERROR,
-			 ("RTUSBBulkOutDataPacket: Submit Tx URB failed %d\n",
-			  ret));
-
-		BULK_OUT_LOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
-		pAd->BulkOutPending[BulkOutPipeId] = FALSE;
-		pAd->watchDogTxPendingCnt[BulkOutPipeId] = 0;
-		BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
-
-		return;
-	}
-
-	BULK_OUT_LOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
-	pHTTXContext->IRPPending = TRUE;
-	BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
-	pAd->BulkOutReq++;
-
-}
-
-void RTUSBBulkOutDataPacketComplete(struct urb *pUrb, struct pt_regs * pt_regs)
-{
-	struct rt_ht_tx_context *pHTTXContext;
-	struct rt_rtmp_adapter *pAd;
-	struct os_cookie *pObj;
-	u8 BulkOutPipeId;
-
-	pHTTXContext = (struct rt_ht_tx_context *)pUrb->context;
-	pAd = pHTTXContext->pAd;
-	pObj = (struct os_cookie *)pAd->OS_Cookie;
-
-	/* Store BulkOut PipeId */
-	BulkOutPipeId = pHTTXContext->BulkOutPipeId;
-	pAd->BulkOutDataOneSecCount++;
-
-	switch (BulkOutPipeId) {
-	case 0:
-		pObj->ac0_dma_done_task.data = (unsigned long)pUrb;
-		tasklet_hi_schedule(&pObj->ac0_dma_done_task);
-		break;
-	case 1:
-		pObj->ac1_dma_done_task.data = (unsigned long)pUrb;
-		tasklet_hi_schedule(&pObj->ac1_dma_done_task);
-		break;
-	case 2:
-		pObj->ac2_dma_done_task.data = (unsigned long)pUrb;
-		tasklet_hi_schedule(&pObj->ac2_dma_done_task);
-		break;
-	case 3:
-		pObj->ac3_dma_done_task.data = (unsigned long)pUrb;
-		tasklet_hi_schedule(&pObj->ac3_dma_done_task);
-		break;
-	}
-
-}
-
-/*
-	========================================================================
-
-	Routine Description:
-
-	Arguments:
-
-	Return Value:
-
-	Note: NULL frame use BulkOutPipeId = 0
-
-	========================================================================
-*/
-void RTUSBBulkOutNullFrame(struct rt_rtmp_adapter *pAd)
-{
-	struct rt_tx_context *pNullContext = &(pAd->NullContext);
-	PURB pUrb;
-	int ret = 0;
-	unsigned long IrqFlags;
-
-	RTMP_IRQ_LOCK(&pAd->BulkOutLock[0], IrqFlags);
-	if ((pAd->BulkOutPending[0] == TRUE)
-	    || RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NEED_STOP_TX)) {
-		RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], IrqFlags);
-		return;
-	}
-	pAd->BulkOutPending[0] = TRUE;
-	pAd->watchDogTxPendingCnt[0] = 1;
-	pNullContext->IRPPending = TRUE;
-	RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], IrqFlags);
-
-	/* Increase Total transmit byte counter */
-	pAd->RalinkCounters.TransmittedByteCount += pNullContext->BulkOutSize;
-
-	/* Clear Null frame bulk flag */
-	RTUSB_CLEAR_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NULL);
-
-	/* Init Tx context descriptor */
-	RTUSBInitTxDesc(pAd, pNullContext, 0,
-			(usb_complete_t) RTUSBBulkOutNullFrameComplete);
-
-	pUrb = pNullContext->pUrb;
-	ret = RTUSB_SUBMIT_URB(pUrb);
-	if (ret != 0) {
-		RTMP_IRQ_LOCK(&pAd->BulkOutLock[0], IrqFlags);
-		pAd->BulkOutPending[0] = FALSE;
-		pAd->watchDogTxPendingCnt[0] = 0;
-		pNullContext->IRPPending = FALSE;
-		RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], IrqFlags);
-
-		DBGPRINT(RT_DEBUG_ERROR,
-			 ("RTUSBBulkOutNullFrame: Submit Tx URB failed %d\n",
-			  ret));
-		return;
-	}
-
-}
-
-/* NULL frame use BulkOutPipeId = 0 */
-void RTUSBBulkOutNullFrameComplete(struct urb *pUrb, struct pt_regs * pt_regs)
-{
-	struct rt_rtmp_adapter *pAd;
-	struct rt_tx_context *pNullContext;
-	int Status;
-	struct os_cookie *pObj;
-
-	pNullContext = (struct rt_tx_context *)pUrb->context;
-	pAd = pNullContext->pAd;
-	Status = pUrb->status;
-
-	pObj = (struct os_cookie *)pAd->OS_Cookie;
-	pObj->null_frame_complete_task.data = (unsigned long)pUrb;
-	tasklet_hi_schedule(&pObj->null_frame_complete_task);
-}
-
-/*
-	========================================================================
-
-	Routine Description:
-
-	Arguments:
-
-	Return Value:
-
-	Note: MLME use BulkOutPipeId = 0
-
-	========================================================================
-*/
-void RTUSBBulkOutMLMEPacket(struct rt_rtmp_adapter *pAd, u8 Index)
-{
-	struct rt_tx_context *pMLMEContext;
-	PURB pUrb;
-	int ret = 0;
-	unsigned long IrqFlags;
-
-	pMLMEContext =
-	    (struct rt_tx_context *)pAd->MgmtRing.Cell[pAd->MgmtRing.TxDmaIdx].AllocVa;
-	pUrb = pMLMEContext->pUrb;
-
-	if ((pAd->MgmtRing.TxSwFreeIdx >= MGMT_RING_SIZE) ||
-	    (pMLMEContext->InUse == FALSE) ||
-	    (pMLMEContext->bWaitingBulkOut == FALSE)) {
-
-		/* Clear MLME bulk flag */
-		RTUSB_CLEAR_BULK_FLAG(pAd, fRTUSB_BULK_OUT_MLME);
-
-		return;
-	}
-
-	RTMP_IRQ_LOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags);
-	if ((pAd->BulkOutPending[MGMTPIPEIDX] == TRUE)
-	    || RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NEED_STOP_TX)) {
-		RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags);
-		return;
-	}
-
-	pAd->BulkOutPending[MGMTPIPEIDX] = TRUE;
-	pAd->watchDogTxPendingCnt[MGMTPIPEIDX] = 1;
-	pMLMEContext->IRPPending = TRUE;
-	pMLMEContext->bWaitingBulkOut = FALSE;
-	RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags);
-
-	/* Increase Total transmit byte counter */
-	pAd->RalinkCounters.TransmittedByteCount += pMLMEContext->BulkOutSize;
-
-	/* Clear MLME bulk flag */
-	RTUSB_CLEAR_BULK_FLAG(pAd, fRTUSB_BULK_OUT_MLME);
-
-	/* Init Tx context descriptor */
-	RTUSBInitTxDesc(pAd, pMLMEContext, MGMTPIPEIDX,
-			(usb_complete_t) RTUSBBulkOutMLMEPacketComplete);
-
-	/*For mgmt urb buffer, because we use sk_buff, so we need to notify the USB controller do dma mapping. */
-	pUrb->transfer_dma = 0;
-	pUrb->transfer_flags &= (~URB_NO_TRANSFER_DMA_MAP);
-
-	pUrb = pMLMEContext->pUrb;
-	ret = RTUSB_SUBMIT_URB(pUrb);
-	if (ret != 0) {
-		DBGPRINT(RT_DEBUG_ERROR,
-			 ("RTUSBBulkOutMLMEPacket: Submit MLME URB failed %d\n",
-			  ret));
-		RTMP_IRQ_LOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags);
-		pAd->BulkOutPending[MGMTPIPEIDX] = FALSE;
-		pAd->watchDogTxPendingCnt[MGMTPIPEIDX] = 0;
-		pMLMEContext->IRPPending = FALSE;
-		pMLMEContext->bWaitingBulkOut = TRUE;
-		RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags);
-
-		return;
-	}
-	/*DBGPRINT_RAW(RT_DEBUG_INFO, ("<---RTUSBBulkOutMLMEPacket \n")); */
-/*      printk("<---RTUSBBulkOutMLMEPacket,Cpu=%d!, Dma=%d, SwIdx=%d!\n", pAd->MgmtRing.TxCpuIdx, pAd->MgmtRing.TxDmaIdx, pAd->MgmtRing.TxSwFreeIdx); */
-}
-
-void RTUSBBulkOutMLMEPacketComplete(struct urb *pUrb, struct pt_regs * pt_regs)
-{
-	struct rt_tx_context *pMLMEContext;
-	struct rt_rtmp_adapter *pAd;
-	int Status;
-	struct os_cookie *pObj;
-	int index;
-
-	/*DBGPRINT_RAW(RT_DEBUG_INFO, ("--->RTUSBBulkOutMLMEPacketComplete\n")); */
-	pMLMEContext = (struct rt_tx_context *)pUrb->context;
-	pAd = pMLMEContext->pAd;
-	pObj = (struct os_cookie *)pAd->OS_Cookie;
-	Status = pUrb->status;
-	index = pMLMEContext->SelfIdx;
-
-	pObj->mgmt_dma_done_task.data = (unsigned long)pUrb;
-	tasklet_hi_schedule(&pObj->mgmt_dma_done_task);
-}
-
-/*
-	========================================================================
-
-	Routine Description:
-
-	Arguments:
-
-	Return Value:
-
-	Note: PsPoll use BulkOutPipeId = 0
-
-	========================================================================
-*/
-void RTUSBBulkOutPsPoll(struct rt_rtmp_adapter *pAd)
-{
-	struct rt_tx_context *pPsPollContext = &(pAd->PsPollContext);
-	PURB pUrb;
-	int ret = 0;
-	unsigned long IrqFlags;
-
-	RTMP_IRQ_LOCK(&pAd->BulkOutLock[0], IrqFlags);
-	if ((pAd->BulkOutPending[0] == TRUE)
-	    || RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NEED_STOP_TX)) {
-		RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], IrqFlags);
-		return;
-	}
-	pAd->BulkOutPending[0] = TRUE;
-	pAd->watchDogTxPendingCnt[0] = 1;
-	pPsPollContext->IRPPending = TRUE;
-	RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], IrqFlags);
-
-	/* Clear PS-Poll bulk flag */
-	RTUSB_CLEAR_BULK_FLAG(pAd, fRTUSB_BULK_OUT_PSPOLL);
-
-	/* Init Tx context descriptor */
-	RTUSBInitTxDesc(pAd, pPsPollContext, MGMTPIPEIDX,
-			(usb_complete_t) RTUSBBulkOutPsPollComplete);
-
-	pUrb = pPsPollContext->pUrb;
-	ret = RTUSB_SUBMIT_URB(pUrb);
-	if (ret != 0) {
-		RTMP_IRQ_LOCK(&pAd->BulkOutLock[0], IrqFlags);
-		pAd->BulkOutPending[0] = FALSE;
-		pAd->watchDogTxPendingCnt[0] = 0;
-		pPsPollContext->IRPPending = FALSE;
-		RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], IrqFlags);
-
-		DBGPRINT(RT_DEBUG_ERROR,
-			 ("RTUSBBulkOutPsPoll: Submit Tx URB failed %d\n",
-			  ret));
-		return;
-	}
-
-}
-
-/* PS-Poll frame use BulkOutPipeId = 0 */
-void RTUSBBulkOutPsPollComplete(struct urb *pUrb, struct pt_regs * pt_regs)
-{
-	struct rt_rtmp_adapter *pAd;
-	struct rt_tx_context *pPsPollContext;
-	int Status;
-	struct os_cookie *pObj;
-
-	pPsPollContext = (struct rt_tx_context *)pUrb->context;
-	pAd = pPsPollContext->pAd;
-	Status = pUrb->status;
-
-	pObj = (struct os_cookie *)pAd->OS_Cookie;
-	pObj->pspoll_frame_complete_task.data = (unsigned long)pUrb;
-	tasklet_hi_schedule(&pObj->pspoll_frame_complete_task);
-}
-
-void DoBulkIn(struct rt_rtmp_adapter *pAd)
-{
-	struct rt_rx_context *pRxContext;
-	PURB pUrb;
-	int ret = 0;
-	unsigned long IrqFlags;
-
-	RTMP_IRQ_LOCK(&pAd->BulkInLock, IrqFlags);
-	pRxContext = &(pAd->RxContext[pAd->NextRxBulkInIndex]);
-	if ((pAd->PendingRx > 0) || (pRxContext->Readable == TRUE)
-	    || (pRxContext->InUse == TRUE)) {
-		RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
-		return;
-	}
-	pRxContext->InUse = TRUE;
-	pRxContext->IRPPending = TRUE;
-	pAd->PendingRx++;
-	pAd->BulkInReq++;
-	RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
-
-	/* Init Rx context descriptor */
-	NdisZeroMemory(pRxContext->TransferBuffer, pRxContext->BulkInOffset);
-	RTUSBInitRxDesc(pAd, pRxContext);
-
-	pUrb = pRxContext->pUrb;
-	ret = RTUSB_SUBMIT_URB(pUrb);
-	if (ret != 0) {	/* fail */
-
-		RTMP_IRQ_LOCK(&pAd->BulkInLock, IrqFlags);
-		pRxContext->InUse = FALSE;
-		pRxContext->IRPPending = FALSE;
-		pAd->PendingRx--;
-		pAd->BulkInReq--;
-		RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
-		DBGPRINT(RT_DEBUG_ERROR,
-			 ("RTUSBBulkReceive: Submit Rx URB failed %d\n", ret));
-	} else {		/* success */
-		ASSERT((pRxContext->InUse == pRxContext->IRPPending));
-		/*printk("BIDone, Pend=%d,BIIdx=%d,BIRIdx=%d!\n", pAd->PendingRx, pAd->NextRxBulkInIndex, pAd->NextRxBulkInReadIndex); */
-	}
-}
-
-/*
-	========================================================================
-
-	Routine Description:
-	USB_RxPacket initializes a URB and uses the Rx IRP to submit it
-	to USB. It checks if an Rx Descriptor is available and passes the
-	the coresponding buffer to be filled. If no descriptor is available
-	fails the request. When setting the completion routine we pass our
-	Adapter Object as Context.
-
-	Arguments:
-
-	Return Value:
-		TRUE			found matched tuple cache
-		FALSE			no matched found
-
-	Note:
-
-	========================================================================
-*/
-#define fRTMP_ADAPTER_NEED_STOP_RX		\
-		(fRTMP_ADAPTER_NIC_NOT_EXIST | fRTMP_ADAPTER_HALT_IN_PROGRESS |	\
-		 fRTMP_ADAPTER_RADIO_OFF | fRTMP_ADAPTER_RESET_IN_PROGRESS | \
-		 fRTMP_ADAPTER_REMOVE_IN_PROGRESS | fRTMP_ADAPTER_BULKIN_RESET)
-
-#define fRTMP_ADAPTER_NEED_STOP_HANDLE_RX	\
-		(fRTMP_ADAPTER_NIC_NOT_EXIST | fRTMP_ADAPTER_HALT_IN_PROGRESS |	\
-		 fRTMP_ADAPTER_RADIO_OFF | fRTMP_ADAPTER_RESET_IN_PROGRESS | \
-		 fRTMP_ADAPTER_REMOVE_IN_PROGRESS)
-
-void RTUSBBulkReceive(struct rt_rtmp_adapter *pAd)
-{
-	struct rt_rx_context *pRxContext;
-	unsigned long IrqFlags;
-
-	/* sanity check */
-	if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NEED_STOP_HANDLE_RX))
-		return;
-
-	while (1) {
-
-		RTMP_IRQ_LOCK(&pAd->BulkInLock, IrqFlags);
-		pRxContext = &(pAd->RxContext[pAd->NextRxBulkInReadIndex]);
-		if (((pRxContext->InUse == FALSE)
-		     && (pRxContext->Readable == TRUE))
-		    && (pRxContext->bRxHandling == FALSE)) {
-			pRxContext->bRxHandling = TRUE;
-			RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
-
-			/* read RxContext, Since not */
-			STARxDoneInterruptHandle(pAd, TRUE);
-
-			/* Finish to handle this bulkIn buffer. */
-			RTMP_IRQ_LOCK(&pAd->BulkInLock, IrqFlags);
-			pRxContext->BulkInOffset = 0;
-			pRxContext->Readable = FALSE;
-			pRxContext->bRxHandling = FALSE;
-			pAd->ReadPosition = 0;
-			pAd->TransferBufferLength = 0;
-			INC_RING_INDEX(pAd->NextRxBulkInReadIndex,
-				       RX_RING_SIZE);
-			RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
-
-		} else {
-			RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
-			break;
-		}
-	}
-
-	if (!(RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NEED_STOP_RX)))
-		DoBulkIn(pAd);
-
-}
-
-/*
-	========================================================================
-
-	Routine Description:
-		This routine process Rx Irp and call rx complete function.
-
-	Arguments:
-		DeviceObject	Pointer to the device object for next lower
-						device. DeviceObject passed in here belongs to
-						the next lower driver in the stack because we
-						were invoked via IoCallDriver in USB_RxPacket
-						AND it is not OUR device object
-	  Irp				Ptr to completed IRP
-	  Context			Ptr to our Adapter object (context specified
-						in IoSetCompletionRoutine
-
-	Return Value:
-		Always returns STATUS_MORE_PROCESSING_REQUIRED
-
-	Note:
-		Always returns STATUS_MORE_PROCESSING_REQUIRED
-	========================================================================
-*/
-void RTUSBBulkRxComplete(struct urb *pUrb, struct pt_regs *pt_regs)
-{
-	/* use a receive tasklet to handle received packets; */
-	/* or sometimes hardware IRQ will be disabled here, so we can not */
-	/* use spin_lock_bh()/spin_unlock_bh() after IRQ is disabled. :< */
-	struct rt_rx_context *pRxContext;
-	struct rt_rtmp_adapter *pAd;
-	struct os_cookie *pObj;
-
-	pRxContext = (struct rt_rx_context *)pUrb->context;
-	pAd = pRxContext->pAd;
-	pObj = (struct os_cookie *)pAd->OS_Cookie;
-
-	pObj->rx_done_task.data = (unsigned long)pUrb;
-	tasklet_hi_schedule(&pObj->rx_done_task);
-
-}
-
-/*
-	========================================================================
-
-	Routine Description:
-
-	Arguments:
-
-	Return Value:
-
-	Note:
-
-	========================================================================
-*/
-void RTUSBKickBulkOut(struct rt_rtmp_adapter *pAd)
-{
-	/* BulkIn Reset will reset whole USB PHY. So we need to make sure fRTMP_ADAPTER_BULKIN_RESET not flaged. */
-	if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NEED_STOP_TX)
-	    ) {
-		/* 2. PS-Poll frame is next */
-		if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_PSPOLL))
-			RTUSBBulkOutPsPoll(pAd);
-		/* 5. Mlme frame is next */
-		else if ((RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_MLME)) ||
-			 (pAd->MgmtRing.TxSwFreeIdx < MGMT_RING_SIZE)) {
-			RTUSBBulkOutMLMEPacket(pAd, pAd->MgmtRing.TxDmaIdx);
-		}
-		/* 6. Data frame normal is next */
-		if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL)) {
-			if (((!RTMP_TEST_FLAG
-			      (pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
-			     ||
-			     (!OPSTATUS_TEST_FLAG
-			      (pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
-			    )) {
-				RTUSBBulkOutDataPacket(pAd, 0,
-						       pAd->
-						       NextBulkOutIndex[0]);
-			}
-		}
-		if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL_2)) {
-			if (((!RTMP_TEST_FLAG
-			      (pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
-			     ||
-			     (!OPSTATUS_TEST_FLAG
-			      (pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
-			    )) {
-				RTUSBBulkOutDataPacket(pAd, 1,
-						       pAd->
-						       NextBulkOutIndex[1]);
-			}
-		}
-		if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL_3)) {
-			if (((!RTMP_TEST_FLAG
-			      (pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
-			     ||
-			     (!OPSTATUS_TEST_FLAG
-			      (pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
-			    )) {
-				RTUSBBulkOutDataPacket(pAd, 2,
-						       pAd->
-						       NextBulkOutIndex[2]);
-			}
-		}
-		if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL_4)) {
-			if (((!RTMP_TEST_FLAG
-			      (pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
-			     ||
-			     (!OPSTATUS_TEST_FLAG
-			      (pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
-			    )) {
-				RTUSBBulkOutDataPacket(pAd, 3,
-						       pAd->
-						       NextBulkOutIndex[3]);
-			}
-		}
-		/* 7. Null frame is the last */
-		else if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NULL)) {
-			if (!RTMP_TEST_FLAG
-			    (pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) {
-				RTUSBBulkOutNullFrame(pAd);
-			}
-		}
-		/* 8. No data available */
-		else
-			;
-	}
-}
-
-/*
-	========================================================================
-
-	Routine Description:
-	Call from Reset action after BulkOut failed.
-	Arguments:
-
-	Return Value:
-
-	Note:
-
-	========================================================================
-*/
-void RTUSBCleanUpDataBulkOutQueue(struct rt_rtmp_adapter *pAd)
-{
-	u8 Idx;
-	struct rt_ht_tx_context *pTxContext;
-
-	DBGPRINT(RT_DEBUG_TRACE, ("--->CleanUpDataBulkOutQueue\n"));
-
-	for (Idx = 0; Idx < 4; Idx++) {
-		pTxContext = &pAd->TxContext[Idx];
-
-		pTxContext->CurWritePosition = pTxContext->NextBulkOutPosition;
-		pTxContext->LastOne = FALSE;
-		NdisAcquireSpinLock(&pAd->BulkOutLock[Idx]);
-		pAd->BulkOutPending[Idx] = FALSE;
-		NdisReleaseSpinLock(&pAd->BulkOutLock[Idx]);
-	}
-
-	DBGPRINT(RT_DEBUG_TRACE, ("<---CleanUpDataBulkOutQueue\n"));
-}
-
-/*
-	========================================================================
-
-	Routine Description:
-
-	Arguments:
-
-	Return Value:
-
-	Note:
-
-	========================================================================
-*/
-void RTUSBCleanUpMLMEBulkOutQueue(struct rt_rtmp_adapter *pAd)
-{
-	DBGPRINT(RT_DEBUG_TRACE, ("--->CleanUpMLMEBulkOutQueue\n"));
-	DBGPRINT(RT_DEBUG_TRACE, ("<---CleanUpMLMEBulkOutQueue\n"));
-}
-
-/*
-	========================================================================
-
-	Routine Description:
-
-	Arguments:
-
-	Return Value:
-
-	Note:
-
-	========================================================================
-*/
-void RTUSBCancelPendingIRPs(struct rt_rtmp_adapter *pAd)
-{
-	RTUSBCancelPendingBulkInIRP(pAd);
-	RTUSBCancelPendingBulkOutIRP(pAd);
-}
-
-/*
-	========================================================================
-
-	Routine Description:
-
-	Arguments:
-
-	Return Value:
-
-	Note:
-
-	========================================================================
-*/
-void RTUSBCancelPendingBulkInIRP(struct rt_rtmp_adapter *pAd)
-{
-	struct rt_rx_context *pRxContext;
-	u32 i;
-
-	DBGPRINT_RAW(RT_DEBUG_TRACE, ("--->RTUSBCancelPendingBulkInIRP\n"));
-	for (i = 0; i < (RX_RING_SIZE); i++) {
-		pRxContext = &(pAd->RxContext[i]);
-		if (pRxContext->IRPPending == TRUE) {
-			RTUSB_UNLINK_URB(pRxContext->pUrb);
-			pRxContext->IRPPending = FALSE;
-			pRxContext->InUse = FALSE;
-			/*NdisInterlockedDecrement(&pAd->PendingRx); */
-			/*pAd->PendingRx--; */
-		}
-	}
-	DBGPRINT_RAW(RT_DEBUG_TRACE, ("<---RTUSBCancelPendingBulkInIRP\n"));
-}
-
-/*
-	========================================================================
-
-	Routine Description:
-
-	Arguments:
-
-	Return Value:
-
-	Note:
-
-	========================================================================
-*/
-void RTUSBCancelPendingBulkOutIRP(struct rt_rtmp_adapter *pAd)
-{
-	struct rt_ht_tx_context *pHTTXContext;
-	struct rt_tx_context *pMLMEContext;
-	struct rt_tx_context *pBeaconContext;
-	struct rt_tx_context *pNullContext;
-	struct rt_tx_context *pPsPollContext;
-	struct rt_tx_context *pRTSContext;
-	u32 i, Idx;
-/*      unsigned int            IrqFlags; */
-/*      spinlock_t          *pLock; */
-/*      BOOLEAN                         *pPending; */
-
-/*      pLock = &pAd->BulkOutLock[MGMTPIPEIDX]; */
-/*      pPending = &pAd->BulkOutPending[MGMTPIPEIDX]; */
-
-	for (Idx = 0; Idx < 4; Idx++) {
-		pHTTXContext = &(pAd->TxContext[Idx]);
-
-		if (pHTTXContext->IRPPending == TRUE) {
-
-			/* Get the USB_CONTEXT and cancel it's IRP; the completion routine will itself */
-			/* remove it from the HeadPendingSendList and NULL out HeadPendingSendList */
-			/*      when the last IRP on the list has been  cancelled; that's how we exit this loop */
-			/* */
-
-			RTUSB_UNLINK_URB(pHTTXContext->pUrb);
-
-			/* Sleep 200 microseconds to give cancellation time to work */
-			RTMPusecDelay(200);
-		}
-
-		pAd->BulkOutPending[Idx] = FALSE;
-	}
-
-	/*RTMP_IRQ_LOCK(pLock, IrqFlags); */
-	for (i = 0; i < MGMT_RING_SIZE; i++) {
-		pMLMEContext = (struct rt_tx_context *)pAd->MgmtRing.Cell[i].AllocVa;
-		if (pMLMEContext && (pMLMEContext->IRPPending == TRUE)) {
-
-			/* Get the USB_CONTEXT and cancel it's IRP; the completion routine will itself */
-			/* remove it from the HeadPendingSendList and NULL out HeadPendingSendList */
-			/*      when the last IRP on the list has been  cancelled; that's how we exit this loop */
-			/* */
-
-			RTUSB_UNLINK_URB(pMLMEContext->pUrb);
-			pMLMEContext->IRPPending = FALSE;
-
-			/* Sleep 200 microsecs to give cancellation time to work */
-			RTMPusecDelay(200);
-		}
-	}
-	pAd->BulkOutPending[MGMTPIPEIDX] = FALSE;
-	/*RTMP_IRQ_UNLOCK(pLock, IrqFlags); */
-
-	for (i = 0; i < BEACON_RING_SIZE; i++) {
-		pBeaconContext = &(pAd->BeaconContext[i]);
-
-		if (pBeaconContext->IRPPending == TRUE) {
-
-			/* Get the USB_CONTEXT and cancel it's IRP; the completion routine will itself */
-			/* remove it from the HeadPendingSendList and NULL out HeadPendingSendList */
-			/*      when the last IRP on the list has been  cancelled; that's how we exit this loop */
-			/* */
-
-			RTUSB_UNLINK_URB(pBeaconContext->pUrb);
-
-			/* Sleep 200 microsecs to give cancellation time to work */
-			RTMPusecDelay(200);
-		}
-	}
-
-	pNullContext = &(pAd->NullContext);
-	if (pNullContext->IRPPending == TRUE)
-		RTUSB_UNLINK_URB(pNullContext->pUrb);
-
-	pRTSContext = &(pAd->RTSContext);
-	if (pRTSContext->IRPPending == TRUE)
-		RTUSB_UNLINK_URB(pRTSContext->pUrb);
-
-	pPsPollContext = &(pAd->PsPollContext);
-	if (pPsPollContext->IRPPending == TRUE)
-		RTUSB_UNLINK_URB(pPsPollContext->pUrb);
-
-	for (Idx = 0; Idx < 4; Idx++) {
-		NdisAcquireSpinLock(&pAd->BulkOutLock[Idx]);
-		pAd->BulkOutPending[Idx] = FALSE;
-		NdisReleaseSpinLock(&pAd->BulkOutLock[Idx]);
-	}
-}
-
-#endif /* RTMP_MAC_USB // */
diff -druN linux-2.6.39-libre/drivers/staging/rt2870/common/rtusb_data.c linux-3.0-rc7-libre/drivers/staging/rt2870/common/rtusb_data.c
--- linux-2.6.39-libre/drivers/staging/rt2870/common/rtusb_data.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rt2870/common/rtusb_data.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,262 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, 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.             *
- *                                                                       *
- *************************************************************************
-
-	Module Name:
-	rtusb_data.c
-
-	Abstract:
-	Ralink USB driver Tx/Rx functions.
-
-	Revision History:
-	Who         When          What
-	--------    ----------    ----------------------------------------------
-	Jan            03-25-2006    created
-
-*/
-
-#ifdef RTMP_MAC_USB
-
-#include "../rt_config.h"
-
-extern u8 Phy11BGNextRateUpward[];	/* defined in mlme.c */
-extern u8 EpToQueue[];
-
-void REPORT_AMSDU_FRAMES_TO_LLC(struct rt_rtmp_adapter *pAd,
-				u8 *pData, unsigned long DataSize)
-{
-	void *pPacket;
-	u32 nMSDU;
-	struct sk_buff *pSkb;
-
-	nMSDU = 0;
-	/* allocate a rx packet */
-	pSkb = dev_alloc_skb(RX_BUFFER_AGGRESIZE);
-	pPacket = (void *)OSPKT_TO_RTPKT(pSkb);
-	if (pSkb) {
-
-		/* convert 802.11 to 802.3 packet */
-		pSkb->dev = get_netdev_from_bssid(pAd, BSS0);
-		RTMP_SET_PACKET_SOURCE(pPacket, PKTSRC_NDIS);
-		deaggregate_AMSDU_announce(pAd, pPacket, pData, DataSize);
-	} else {
-		DBGPRINT(RT_DEBUG_ERROR, ("Can't allocate skb\n"));
-	}
-}
-
-/*
-	========================================================================
-
-	Routine	Description:
-		This subroutine will scan through releative ring descriptor to find
-		out available free ring descriptor and compare with request size.
-
-	Arguments:
-		pAd	Pointer	to our adapter
-		RingType	Selected Ring
-
-	Return Value:
-		NDIS_STATUS_FAILURE		Not enough free descriptor
-		NDIS_STATUS_SUCCESS		Enough free descriptor
-
-	Note:
-
-	========================================================================
-*/
-int RTUSBFreeDescriptorRequest(struct rt_rtmp_adapter *pAd,
-				       u8 BulkOutPipeId,
-				       u32 NumberRequired)
-{
-/*      u8                   FreeNumber = 0; */
-/*      u32                    Index; */
-	int Status = NDIS_STATUS_FAILURE;
-	unsigned long IrqFlags;
-	struct rt_ht_tx_context *pHTTXContext;
-
-	pHTTXContext = &pAd->TxContext[BulkOutPipeId];
-	RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags);
-	if ((pHTTXContext->CurWritePosition < pHTTXContext->NextBulkOutPosition)
-	    &&
-	    ((pHTTXContext->CurWritePosition + NumberRequired +
-	      LOCAL_TXBUF_SIZE) > pHTTXContext->NextBulkOutPosition)) {
-
-		RTUSB_SET_BULK_FLAG(pAd,
-				    (fRTUSB_BULK_OUT_DATA_NORMAL <<
-				     BulkOutPipeId));
-	} else if ((pHTTXContext->CurWritePosition == 8)
-		   && (pHTTXContext->NextBulkOutPosition <
-		       (NumberRequired + LOCAL_TXBUF_SIZE))) {
-		RTUSB_SET_BULK_FLAG(pAd,
-				    (fRTUSB_BULK_OUT_DATA_NORMAL <<
-				     BulkOutPipeId));
-	} else if (pHTTXContext->bCurWriting == TRUE) {
-		DBGPRINT(RT_DEBUG_TRACE,
-			 ("RTUSBFreeD c3 --> QueIdx=%d, CWPos=%ld, NBOutPos=%ld!\n",
-			  BulkOutPipeId, pHTTXContext->CurWritePosition,
-			  pHTTXContext->NextBulkOutPosition));
-		RTUSB_SET_BULK_FLAG(pAd,
-				    (fRTUSB_BULK_OUT_DATA_NORMAL <<
-				     BulkOutPipeId));
-	} else {
-		Status = NDIS_STATUS_SUCCESS;
-	}
-	RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags);
-
-	return Status;
-}
-
-int RTUSBFreeDescriptorRelease(struct rt_rtmp_adapter *pAd,
-				       u8 BulkOutPipeId)
-{
-	unsigned long IrqFlags;
-	struct rt_ht_tx_context *pHTTXContext;
-
-	pHTTXContext = &pAd->TxContext[BulkOutPipeId];
-	RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags);
-	pHTTXContext->bCurWriting = FALSE;
-	RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags);
-
-	return NDIS_STATUS_SUCCESS;
-}
-
-BOOLEAN RTUSBNeedQueueBackForAgg(struct rt_rtmp_adapter *pAd, u8 BulkOutPipeId)
-{
-	unsigned long IrqFlags;
-	struct rt_ht_tx_context *pHTTXContext;
-	BOOLEAN needQueBack = FALSE;
-
-	pHTTXContext = &pAd->TxContext[BulkOutPipeId];
-
-	RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags);
-	if ((pHTTXContext->IRPPending ==
-	     TRUE) /*&& (pAd->TxSwQueue[BulkOutPipeId].Number == 0) */) {
-		if ((pHTTXContext->CurWritePosition <
-		     pHTTXContext->ENextBulkOutPosition)
-		    &&
-		    (((pHTTXContext->ENextBulkOutPosition +
-		       MAX_AGGREGATION_SIZE) < MAX_TXBULK_LIMIT)
-		     || (pHTTXContext->CurWritePosition >
-			 MAX_AGGREGATION_SIZE))) {
-			needQueBack = TRUE;
-		} else
-		    if ((pHTTXContext->CurWritePosition >
-			 pHTTXContext->ENextBulkOutPosition)
-			&&
-			((pHTTXContext->ENextBulkOutPosition +
-			  MAX_AGGREGATION_SIZE) <
-			 pHTTXContext->CurWritePosition)) {
-			needQueBack = TRUE;
-		}
-	}
-	RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags);
-
-	return needQueBack;
-
-}
-
-/*
-	========================================================================
-
-	Routine Description:
-
-	Arguments:
-
-	Return Value:
-
-	IRQL =
-
-	Note:
-
-	========================================================================
-*/
-void RTUSBRejectPendingPackets(struct rt_rtmp_adapter *pAd)
-{
-	u8 Index;
-	struct rt_queue_entry *pEntry;
-	void *pPacket;
-	struct rt_queue_header *pQueue;
-
-	for (Index = 0; Index < 4; Index++) {
-		NdisAcquireSpinLock(&pAd->TxSwQueueLock[Index]);
-		while (pAd->TxSwQueue[Index].Head != NULL) {
-			pQueue = (struct rt_queue_header *)&(pAd->TxSwQueue[Index]);
-			pEntry = RemoveHeadQueue(pQueue);
-			pPacket = QUEUE_ENTRY_TO_PACKET(pEntry);
-			RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
-		}
-		NdisReleaseSpinLock(&pAd->TxSwQueueLock[Index]);
-
-	}
-
-}
-
-/*
-	========================================================================
-
-	Routine	Description:
-		Calculates the duration which is required to transmit out frames
-	with given size and specified rate.
-
-	Arguments:
-		pTxD		Pointer to transmit descriptor
-		Ack			Setting for Ack requirement bit
-		Fragment	Setting for Fragment bit
-		RetryMode	Setting for retry mode
-		Ifs			Setting for IFS gap
-		Rate		Setting for transmit rate
-		Service		Setting for service
-		Length		Frame length
-		TxPreamble  Short or Long preamble when using CCK rates
-		QueIdx - 0-3, according to 802.11e/d4.4 June/2003
-
-	Return Value:
-		None
-
-	IRQL = PASSIVE_LEVEL
-	IRQL = DISPATCH_LEVEL
-
-	========================================================================
-*/
-
-void RTMPWriteTxInfo(struct rt_rtmp_adapter *pAd,
-		     struct rt_txinfo *pTxInfo,
-		     u16 USBDMApktLen,
-		     IN BOOLEAN bWiv,
-		     u8 QueueSel, u8 NextValid, u8 TxBurst)
-{
-	pTxInfo->USBDMATxPktLen = USBDMApktLen;
-	pTxInfo->QSEL = QueueSel;
-	if (QueueSel != FIFO_EDCA)
-		DBGPRINT(RT_DEBUG_TRACE,
-			 ("====> QueueSel != FIFO_EDCA<============\n"));
-	pTxInfo->USBDMANextVLD = FALSE;	/*NextValid;  // Need to check with Jan about this. */
-	pTxInfo->USBDMATxburst = TxBurst;
-	pTxInfo->WIV = bWiv;
-	pTxInfo->SwUseLastRound = 0;
-	pTxInfo->rsv = 0;
-	pTxInfo->rsv2 = 0;
-}
-
-#endif /* RTMP_MAC_USB // */
diff -druN linux-2.6.39-libre/drivers/staging/rt2870/common/rtusb_io.c linux-3.0-rc7-libre/drivers/staging/rt2870/common/rtusb_io.c
--- linux-2.6.39-libre/drivers/staging/rt2870/common/rtusb_io.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rt2870/common/rtusb_io.c	1969-12-31 19:00:00.000000000 -0500
@@ -1,2104 +0,0 @@
-/*
- *************************************************************************
- * Ralink Tech Inc.
- * 5F., No.36, Taiyuan St., Jhubei City,
- * Hsinchu County 302,
- * Taiwan, R.O.C.
- *
- * (c) Copyright 2002-2007, Ralink Technology, 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.             *
- *                                                                       *
- *************************************************************************
-
-	Module Name:
-	rtusb_io.c
-
-	Abstract:
-
-	Revision History:
-	Who			When	    What
-	--------	----------  ----------------------------------------------
-	Name		Date	    Modification logs
-	Paul Lin    06-25-2004  created
-*/
-
-#ifdef RTMP_MAC_USB
-
-#include "../rt_config.h"
-
-/*
-	========================================================================
-
-	Routine Description: NIC initialization complete
-
-	Arguments:
-
-	Return Value:
-
-	IRQL =
-
-	Note:
-
-	========================================================================
-*/
-
-static int RTUSBFirmwareRun(struct rt_rtmp_adapter *pAd)
-{
-	int Status;
-
-	Status = RTUSB_VendorRequest(pAd,
-				     USBD_TRANSFER_DIRECTION_OUT,
-				     DEVICE_VENDOR_REQUEST_OUT,
-				     0x01, 0x8, 0, NULL, 0);
-
-	return Status;
-}
-
-/*
-	========================================================================
-
-	Routine Description: Write Firmware to NIC.
-
-	Arguments:
-
-	Return Value:
-
-	IRQL =
-
-	Note:
-
-	========================================================================
-*/
-int RTUSBFirmwareWrite(struct rt_rtmp_adapter *pAd,
-		       const u8 *pFwImage, unsigned long FwLen)
-{
-	u32 MacReg;
-	int Status;
-/*      unsigned long           i; */
-	u16 writeLen;
-
-	Status = RTUSBReadMACRegister(pAd, MAC_CSR0, &MacReg);
-
-	writeLen = FwLen;
-	RTUSBMultiWrite(pAd, FIRMWARE_IMAGE_BASE, pFwImage, writeLen);
-
-	Status = RTUSBWriteMACRegister(pAd, 0x7014, 0xffffffff);
-	Status = RTUSBWriteMACRegister(pAd, 0x701c, 0xffffffff);
-	Status = RTUSBFirmwareRun(pAd);
-
-	/*2008/11/28:KH add to fix the dead rf frequency offset bug<-- */
-	RTMPusecDelay(10000);
-	RTUSBWriteMACRegister(pAd, H2M_MAILBOX_CSR, 0);
-	AsicSendCommandToMcu(pAd, 0x72, 0x00, 0x00, 0x00);	/*reset rf by MCU supported by new firmware */
-	/*2008/11/28:KH add to fix the dead rf frequency offset bug--> */
-
-	return Status;
-}
-
-int RTUSBVenderReset(struct rt_rtmp_adapter *pAd)
-{
-	int Status;
-	DBGPRINT_RAW(RT_DEBUG_ERROR, ("-->RTUSBVenderReset\n"));
-	Status = RTUSB_VendorRequest(pAd,
-				     USBD_TRANSFER_DIRECTION_OUT,
-				     DEVICE_VENDOR_REQUEST_OUT,
-				     0x01, 0x1, 0, NULL, 0);
-
-	DBGPRINT_RAW(RT_DEBUG_ERROR, ("<--RTUSBVenderReset\n"));
-	return Status;
-}
-
-/*
-	========================================================================
-
-	Routine Description: Read various length data from RT2573
-
-	Arguments:
-
-	Return Value:
-
-	IRQL =
-
-	Note:
-
-	========================================================================
-*/
-int RTUSBMultiRead(struct rt_rtmp_adapter *pAd,
-			u16 Offset, u8 *pData, u16 length)
-{
-	int Status;
-
-	Status = RTUSB_VendorRequest(pAd,
-				     (USBD_TRANSFER_DIRECTION_IN |
-				      USBD_SHORT_TRANSFER_OK),
-				     DEVICE_VENDOR_REQUEST_IN, 0x7, 0, Offset,
-				     pData, length);
-
-	return Status;
-}
-
-/*
-	========================================================================
-
-	Routine Description: Write various length data to RT2573
-
-	Arguments:
-
-	Return Value:
-
-	IRQL =
-
-	Note:
-
-	========================================================================
-*/
-int RTUSBMultiWrite_OneByte(struct rt_rtmp_adapter *pAd,
-			    u16 Offset, const u8 *pData)
-{
-	int Status;
-
-	/* TODO: In 2870, use this funciton carefully cause it's not stable. */
-	Status = RTUSB_VendorRequest(pAd,
-				     USBD_TRANSFER_DIRECTION_OUT,
-				     DEVICE_VENDOR_REQUEST_OUT,
-				     0x6, 0, Offset, (u8 *)pData, 1);
-
-	return Status;
-}
-
-int RTUSBMultiWrite(struct rt_rtmp_adapter *pAd,
-		    u16 Offset, const u8 *pData, u16 length)
-{
-	int Status;
-
-	u16 index = 0, Value;
-	const u8 *pSrc = pData;
-	u16 resude = 0;
-
-	resude = length % 2;
-	length += resude;
-	do {
-		Value = (u16)(*pSrc | (*(pSrc + 1) << 8));
-		Status = RTUSBSingleWrite(pAd, Offset + index, Value);
-		index += 2;
-		length -= 2;
-		pSrc = pSrc + 2;
-	} while (length > 0);
-
-	return Status;
-}
-
-int RTUSBSingleWrite(struct rt_rtmp_adapter *pAd,
-			  u16 Offset, u16 Value)
-{
-	int Status;
-
-	Status = RTUSB_VendorRequest(pAd,
-				     USBD_TRANSFER_DIRECTION_OUT,
-				     DEVICE_VENDOR_REQUEST_OUT,
-				     0x2, Value, Offset, NULL, 0);
-
-	return Status;
-
-}
-
-/*
-	========================================================================
-
-	Routine Description: Read 32-bit MAC register
-
-	Arguments:
-
-	Return Value:
-
-	IRQL =
-
-	Note:
-
-	========================================================================
-*/
-int RTUSBReadMACRegister(struct rt_rtmp_adapter *pAd,
-			      u16 Offset, u32 *pValue)
-{
-	int Status = 0;
-	u32 localVal;
-
-	Status = RTUSB_VendorRequest(pAd,
-				     (USBD_TRANSFER_DIRECTION_IN |
-				      USBD_SHORT_TRANSFER_OK),
-				     DEVICE_VENDOR_REQUEST_IN, 0x7, 0, Offset,
-				     &localVal, 4);
-
-	*pValue = le2cpu32(localVal);
-
-	if (Status < 0)
-		*pValue = 0xffffffff;
-
-	return Status;
-}
-
-/*
-	========================================================================
-
-	Routine Description: Write 32-bit MAC register
-
-	Arguments:
-
-	Return Value:
-
-	IRQL =
-
-	Note:
-
-	========================================================================
-*/
-int RTUSBWriteMACRegister(struct rt_rtmp_adapter *pAd,
-			       u16 Offset, u32 Value)
-{
-	int Status;
-	u32 localVal;
-
-	localVal = Value;
-
-	Status = RTUSBSingleWrite(pAd, Offset, (u16)(localVal & 0xffff));
-	Status =
-	    RTUSBSingleWrite(pAd, Offset + 2,
-			     (u16)((localVal & 0xffff0000) >> 16));
-
-	return Status;
-}
-
-/*
-	========================================================================
-
-	Routine Description: Read 8-bit BBP register
-
-	Arguments:
-
-	Return Value:
-
-	IRQL =
-
-	Note:
-
-	========================================================================
-*/
-int RTUSBReadBBPRegister(struct rt_rtmp_adapter *pAd,
-			      u8 Id, u8 *pValue)
-{
-	BBP_CSR_CFG_STRUC BbpCsr;
-	u32 i = 0;
-	int status;
-
-	/* Verify the busy condition */
-	do {
-		status = RTUSBReadMACRegister(pAd, BBP_CSR_CFG, &BbpCsr.word);
-		if (status >= 0) {
-			if (!(BbpCsr.field.Busy == BUSY))
-				break;
-		}
-		DBGPRINT(RT_DEBUG_TRACE,
-			 ("RTUSBReadBBPRegister(BBP_CSR_CFG_1):retry count=%d!\n",
-			  i));
-		i++;
-	} while ((i < RETRY_LIMIT)
-		 && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)));
-
-	if ((i == RETRY_LIMIT)
-	    || (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))) {
-		/* */
-		/* Read failed then Return Default value. */
-		/* */
-		*pValue = pAd->BbpWriteLatch[Id];
-
-		DBGPRINT_RAW(RT_DEBUG_ERROR,
-			     ("Retry count exhausted or device removed!!!\n"));
-		return STATUS_UNSUCCESSFUL;
-	}
-	/* Prepare for write material */
-	BbpCsr.word = 0;
-	BbpCsr.field.fRead = 1;
-	BbpCsr.field.Busy = 1;
-	BbpCsr.field.RegNum = Id;
-	RTUSBWriteMACRegister(pAd, BBP_CSR_CFG, BbpCsr.word);
-
-	i = 0;
-	/* Verify the busy condition */
-	do {
-		status = RTUSBReadMACRegister(pAd, BBP_CSR_CFG, &BbpCsr.word);
-		if (status >= 0) {
-			if (!(BbpCsr.field.Busy == BUSY)) {
-				*pValue = (u8)BbpCsr.field.Value;
-				break;
-			}
-		}
-		DBGPRINT(RT_DEBUG_TRACE,
-			 ("RTUSBReadBBPRegister(BBP_CSR_CFG_2):retry count=%d!\n",
-			  i));
-		i++;
-	} while ((i < RETRY_LIMIT)
-		 && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)));
-
-	if ((i == RETRY_LIMIT)
-	    || (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))) {
-		/* */
-		/* Read failed then Return Default value. */
-		/* */
-		*pValue = pAd->BbpWriteLatch[Id];
-
-		DBGPRINT_RAW(RT_DEBUG_ERROR,
-			     ("Retry count exhausted or device removed!!!\n"));
-		return STATUS_UNSUCCESSFUL;
-	}
-
-	return STATUS_SUCCESS;
-}
-
-/*
-	========================================================================
-
-	Routine Description: Write 8-bit BBP register
-
-	Arguments:
-
-	Return Value:
-
-	IRQL =
-
-	Note:
-
-	========================================================================
-*/
-int RTUSBWriteBBPRegister(struct rt_rtmp_adapter *pAd,
-			       u8 Id, u8 Value)
-{
-	BBP_CSR_CFG_STRUC BbpCsr;
-	u32 i = 0;
-	int status;
-	/* Verify the busy condition */
-	do {
-		status = RTUSBReadMACRegister(pAd, BBP_CSR_CFG, &BbpCsr.word);
-		if (status >= 0) {
-			if (!(BbpCsr.field.Busy == BUSY))
-				break;
-		}
-		DBGPRINT(RT_DEBUG_TRACE,
-			 ("RTUSBWriteBBPRegister(BBP_CSR_CFG):retry count=%d!\n",
-			  i));
-		i++;
-	} while ((i < RETRY_LIMIT)
-	       && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)));
-
-	if ((i == RETRY_LIMIT)
-	    || (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))) {
-		DBGPRINT_RAW(RT_DEBUG_ERROR,
-			     ("Retry count exhausted or device removed!!!\n"));
-		return STATUS_UNSUCCESSFUL;
-	}
-	/* Prepare for write material */
-	BbpCsr.word = 0;
-	BbpCsr.field.fRead = 0;
-	BbpCsr.field.Value = Value;
-	BbpCsr.field.Busy = 1;
-	BbpCsr.field.RegNum = Id;
-	RTUSBWriteMACRegister(pAd, BBP_CSR_CFG, BbpCsr.word);
-
-	pAd->BbpWriteLatch[Id] = Value;
-
-	return STATUS_SUCCESS;
-}
-
-/*
-	========================================================================
-
-	Routine Description: Write RF register through MAC
-
-	Arguments:
-
-	Return Value:
-
-	IRQL =
-
-	Note:
-
-	========================================================================
-*/
-int RTUSBWriteRFRegister(struct rt_rtmp_adapter *pAd, u32 Value)
-{
-	PHY_CSR4_STRUC PhyCsr4;
-	u32 i = 0;
-	int status;
-
-	NdisZeroMemory(&PhyCsr4, sizeof(PHY_CSR4_STRUC));
-	do {
-		status = RTUSBReadMACRegister(pAd, RF_CSR_CFG0, &PhyCsr4.word);
-		if (status >= 0) {
-			if (!(PhyCsr4.field.Busy))
-				break;
-		}
-		DBGPRINT(RT_DEBUG_TRACE,
-			 ("RTUSBWriteRFRegister(RF_CSR_CFG0):retry count=%d!\n",
-			  i));
-		i++;
-	} while ((i < RETRY_LIMIT)
-	       && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)));
-
-	if ((i == RETRY_LIMIT)
-	    || (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))) {
-		DBGPRINT_RAW(RT_DEBUG_ERROR,
-			     ("Retry count exhausted or device removed!!!\n"));
-		return STATUS_UNSUCCESSFUL;
-	}
-
-	RTUSBWriteMACRegister(pAd, RF_CSR_CFG0, Value);
-
-	return STATUS_SUCCESS;
-}
-
-/*
-	========================================================================
-
-	Routine Description:
-
-	Arguments:
-
-	Return Value:
-
-	IRQL =
-
-	Note:
-
-	========================================================================
-*/
-int RTUSBReadEEPROM(struct rt_rtmp_adapter *pAd,
-			 u16 Offset, u8 *pData, u16 length)
-{
-	int Status = STATUS_SUCCESS;
-
-	Status = RTUSB_VendorRequest(pAd,
-				     (USBD_TRANSFER_DIRECTION_IN |
-				      USBD_SHORT_TRANSFER_OK),
-				     DEVICE_VENDOR_REQUEST_IN, 0x9, 0, Offset,
-				     pData, length);
-
-	return Status;
-}
-
-/*
-	========================================================================
-
-	Routine Description:
-
-	Arguments:
-
-	Return Value:
-
-	IRQL =
-
-	Note:
-
-	========================================================================
-*/
-int RTUSBWriteEEPROM(struct rt_rtmp_adapter *pAd,
-			  u16 Offset, u8 *pData, u16 length)
-{
-	int Status = STATUS_SUCCESS;
-
-	Status = RTUSB_VendorRequest(pAd,
-				     USBD_TRANSFER_DIRECTION_OUT,
-				     DEVICE_VENDOR_REQUEST_OUT,
-				     0x8, 0, Offset, pData, length);
-
-	return Status;
-}
-
-int RTUSBReadEEPROM16(struct rt_rtmp_adapter *pAd,
-			   u16 offset, u16 *pData)
-{
-	int status;
-	u16 localData;
-
-	status = RTUSBReadEEPROM(pAd, offset, (u8 *)(&localData), 2);
-	if (status == STATUS_SUCCESS)
-		*pData = le2cpu16(localData);
-
-	return status;
-
-}
-
-/*
-	========================================================================
-
-	Routine Description:
-
-	Arguments:
-
-	Return Value:
-
-	IRQL =
-
-	Note:
-
-	========================================================================
-*/
-void RTUSBPutToSleep(struct rt_rtmp_adapter *pAd)
-{
-	u32 value;
-
-	/* Timeout 0x40 x 50us */
-	value = (SLEEPCID << 16) + (OWNERMCU << 24) + (0x40 << 8) + 1;
-	RTUSBWriteMACRegister(pAd, 0x7010, value);
-	RTUSBWriteMACRegister(pAd, 0x404, 0x30);
-	/*RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS); */
-	DBGPRINT_RAW(RT_DEBUG_ERROR, ("Sleep Mailbox testvalue %x\n", value));
-
-}
-
-/*
-	========================================================================
-
-	Routine Description:
-
-	Arguments:
-
-	Return Value:
-
-	IRQL =
-
-	Note:
-
-	========================================================================
-*/
-int RTUSBWakeUp(struct rt_rtmp_adapter *pAd)
-{
-	int Status;
-
-	Status = RTUSB_VendorRequest(pAd,
-				     USBD_TRANSFER_DIRECTION_OUT,
-				     DEVICE_VENDOR_REQUEST_OUT,
-				     0x01, 0x09, 0, NULL, 0);
-
-	return Status;
-}
-
-/*
-	========================================================================
-
-	Routine Description:
-
-	Arguments:
-
-	Return Value:
-
-	IRQL =
-
-	Note:
-
-	========================================================================
-*/
-void RTUSBInitializeCmdQ(struct rt_cmdq *cmdq)
-{
-	cmdq->head = NULL;
-	cmdq->tail = NULL;
-	cmdq->size = 0;
-	cmdq->CmdQState = RTMP_TASK_STAT_INITED;
-}
-
-/*
-	========================================================================
-
-	Routine Description:
-
-	Arguments:
-
-	Return Value:
-
-	IRQL =
-
-	Note:
-
-	========================================================================
-*/
-int RTUSBEnqueueCmdFromNdis(struct rt_rtmp_adapter *pAd,
-				    IN NDIS_OID Oid,
-				    IN BOOLEAN SetInformation,
-				    void *pInformationBuffer,
-				    u32 InformationBufferLength)
-{
-	int status;
-	struct rt_cmdqelmt *cmdqelmt = NULL;
-	struct rt_rtmp_os_task *pTask = &pAd->cmdQTask;
-
-#ifdef KTHREAD_SUPPORT
-	if (pTask->kthread_task == NULL)
-#else
-	CHECK_PID_LEGALITY(pTask->taskPID) {
-	}
-	else
-#endif
-	return NDIS_STATUS_RESOURCES;
-
-	status = os_alloc_mem(pAd, (u8 **) (&cmdqelmt), sizeof(struct rt_cmdqelmt));
-	if ((status != NDIS_STATUS_SUCCESS) || (cmdqelmt == NULL))
-		return NDIS_STATUS_RESOURCES;
-
-	cmdqelmt->buffer = NULL;
-	if (pInformationBuffer != NULL) {
-		status =
-		    os_alloc_mem(pAd, (u8 **) & cmdqelmt->buffer,
-				 InformationBufferLength);
-		if ((status != NDIS_STATUS_SUCCESS)
-		    || (cmdqelmt->buffer == NULL)) {
-			kfree(cmdqelmt);
-			return NDIS_STATUS_RESOURCES;
-		} else {
-			NdisMoveMemory(cmdqelmt->buffer, pInformationBuffer,
-				       InformationBufferLength);
-			cmdqelmt->bufferlength = InformationBufferLength;
-		}
-	} else
-		cmdqelmt->bufferlength = 0;
-
-	cmdqelmt->command = Oid;
-	cmdqelmt->CmdFromNdis = TRUE;
-	if (SetInformation == TRUE)
-		cmdqelmt->SetOperation = TRUE;
-	else
-		cmdqelmt->SetOperation = FALSE;
-
-	NdisAcquireSpinLock(&pAd->CmdQLock);
-	if (pAd->CmdQ.CmdQState & RTMP_TASK_CAN_DO_INSERT) {
-		EnqueueCmd((&pAd->CmdQ), cmdqelmt);
-		status = NDIS_STATUS_SUCCESS;
-	} else {
-		status = NDIS_STATUS_FAILURE;
-	}
-	NdisReleaseSpinLock(&pAd->CmdQLock);
-
-	if (status == NDIS_STATUS_FAILURE) {
-		if (cmdqelmt->buffer)
-			os_free_mem(pAd, cmdqelmt->buffer);
-		os_free_mem(pAd, cmdqelmt);
-	} else
-		RTUSBCMDUp(pAd);
-
-	return NDIS_STATUS_SUCCESS;
-}
-
-/*
-	========================================================================
-
-	Routine Description:
-
-	Arguments:
-
-	Return Value:
-
-	IRQL =
-
-	Note:
-
-	========================================================================
-*/
-int RTUSBEnqueueInternalCmd(struct rt_rtmp_adapter *pAd,
-				    IN NDIS_OID Oid,
-				    void *pInformationBuffer,
-				    u32 InformationBufferLength)
-{
-	int status;
-	struct rt_cmdqelmt *cmdqelmt = NULL;
-
-	status = os_alloc_mem(pAd, (u8 **) & cmdqelmt, sizeof(struct rt_cmdqelmt));
-	if ((status != NDIS_STATUS_SUCCESS) || (cmdqelmt == NULL))
-		return NDIS_STATUS_RESOURCES;
-	NdisZeroMemory(cmdqelmt, sizeof(struct rt_cmdqelmt));
-
-	if (InformationBufferLength > 0) {
-		status =
-		    os_alloc_mem(pAd, (u8 **) & cmdqelmt->buffer,
-				 InformationBufferLength);
-		if ((status != NDIS_STATUS_SUCCESS)
-		    || (cmdqelmt->buffer == NULL)) {
-			os_free_mem(pAd, cmdqelmt);
-			return NDIS_STATUS_RESOURCES;
-		} else {
-			NdisMoveMemory(cmdqelmt->buffer, pInformationBuffer,
-				       InformationBufferLength);
-			cmdqelmt->bufferlength = InformationBufferLength;
-		}
-	} else {
-		cmdqelmt->buffer = NULL;
-		cmdqelmt->bufferlength = 0;
-	}
-
-	cmdqelmt->command = Oid;
-	cmdqelmt->CmdFromNdis = FALSE;
-
-	if (cmdqelmt != NULL) {
-		NdisAcquireSpinLock(&pAd->CmdQLock);
-		if (pAd->CmdQ.CmdQState & RTMP_TASK_CAN_DO_INSERT) {
-			EnqueueCmd((&pAd->CmdQ), cmdqelmt);
-			status = NDIS_STATUS_SUCCESS;
-		} else {
-			status = NDIS_STATUS_FAILURE;
-		}
-		NdisReleaseSpinLock(&pAd->CmdQLock);
-
-		if (status == NDIS_STATUS_FAILURE) {
-			if (cmdqelmt->buffer)
-				os_free_mem(pAd, cmdqelmt->buffer);
-			os_free_mem(pAd, cmdqelmt);
-		} else
-			RTUSBCMDUp(pAd);
-	}
-	return NDIS_STATUS_SUCCESS;
-}
-
-/*
-	========================================================================
-
-	Routine Description:
-
-	Arguments:
-
-	Return Value:
-
-	IRQL =
-
-	Note:
-
-	========================================================================
-*/
-void RTUSBDequeueCmd(struct rt_cmdq *cmdq, struct rt_cmdqelmt * * pcmdqelmt)
-{
-	*pcmdqelmt = cmdq->head;
-
-	if (*pcmdqelmt != NULL) {
-		cmdq->head = cmdq->head->next;
-		cmdq->size--;
-		if (cmdq->size == 0)
-			cmdq->tail = NULL;
-	}
-}
-
-/*
-    ========================================================================
-	  usb_control_msg - Builds a control urb, sends it off and waits for completion
-	  @dev: pointer to the usb device to send the message to
-	  @pipe: endpoint "pipe" to send the message to
-	  @request: USB message request value
-	  @requesttype: USB message request type value
-	  @value: USB message value
-	  @index: USB message index value
-	  @data: pointer to the data to send
-	  @size: length in bytes of the data to send
-	  @timeout: time in jiffies to wait for the message to complete before
-			  timing out (if 0 the wait is forever)
-	  Context: !in_interrupt ()
-
-	  This function sends a simple control message to a specified endpoint
-	  and waits for the message to complete, or timeout.
-	  If successful, it returns the number of bytes transferred, otherwise a negative error number.
-
-	 Don't use this function from within an interrupt context, like a
-	  bottom half handler.	If you need an asynchronous message, or need to send
-	  a message from within interrupt context, use usb_submit_urb()
-	  If a thread in your driver uses this call, make sure your disconnect()
-	  method can wait for it to complete.  Since you don't have a handle on
-	  the URB used, you can't cancel the request.
-
-	Routine Description:
-
-	Arguments:
-
-	Return Value:
-
-	Note:
-
-	========================================================================
-*/
-int RTUSB_VendorRequest(struct rt_rtmp_adapter *pAd,
-			     u32 TransferFlags,
-			     u8 RequestType,
-			     u8 Request,
-			     u16 Value,
-			     u16 Index,
-			     void *TransferBuffer,
-			     u32 TransferBufferLength)
-{
-	int ret = 0;
-	struct os_cookie *pObj = (struct os_cookie *)pAd->OS_Cookie;
-
-	if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) {
-		DBGPRINT(RT_DEBUG_ERROR, ("device disconnected\n"));
-		return -1;
-	} else if (in_interrupt()) {
-		DBGPRINT(RT_DEBUG_ERROR,
-			 ("in_interrupt, RTUSB_VendorRequest Request%02x Value%04x Offset%04x\n",
-			  Request, Value, Index));
-
-		return -1;
-	} else {
-#define MAX_RETRY_COUNT  10
-
-		int retryCount = 0;
-		void *tmpBuf = TransferBuffer;
-
-		ret = down_interruptible(&(pAd->UsbVendorReq_semaphore));
-		if (pAd->UsbVendorReqBuf) {
-			ASSERT(TransferBufferLength < MAX_PARAM_BUFFER_SIZE);
-
-			tmpBuf = (void *)pAd->UsbVendorReqBuf;
-			NdisZeroMemory(pAd->UsbVendorReqBuf,
-				       TransferBufferLength);
-
-			if (RequestType == DEVICE_VENDOR_REQUEST_OUT)
-				NdisMoveMemory(tmpBuf, TransferBuffer,
-					       TransferBufferLength);
-		}
-
-		do {
-			if (RequestType == DEVICE_VENDOR_REQUEST_OUT)
-				ret =
-				    usb_control_msg(pObj->pUsb_Dev,
-						    usb_sndctrlpipe(pObj->
-								    pUsb_Dev,
-								    0), Request,
-						    RequestType, Value, Index,
-						    tmpBuf,
-						    TransferBufferLength,
-						    CONTROL_TIMEOUT_JIFFIES);
-			else if (RequestType == DEVICE_VENDOR_REQUEST_IN)
-				ret =
-				    usb_control_msg(pObj->pUsb_Dev,
-						    usb_rcvctrlpipe(pObj->
-								    pUsb_Dev,
-								    0), Request,
-						    RequestType, Value, Index,
-						    tmpBuf,
-						    TransferBufferLength,
-						    CONTROL_TIMEOUT_JIFFIES);
-			else {
-				DBGPRINT(RT_DEBUG_ERROR,
-					 ("vendor request direction is failed\n"));
-				ret = -1;
-			}
-
-			retryCount++;
-			if (ret < 0) {
-				DBGPRINT(RT_DEBUG_OFF, ("#\n"));
-				RTMPusecDelay(5000);
-			}
-		} while ((ret < 0) && (retryCount < MAX_RETRY_COUNT));
-
-		if ((pAd->UsbVendorReqBuf)
-		    && (RequestType == DEVICE_VENDOR_REQUEST_IN))
-			NdisMoveMemory(TransferBuffer, tmpBuf,
-				       TransferBufferLength);
-		up(&(pAd->UsbVendorReq_semaphore));
-
-		if (ret < 0) {
-			DBGPRINT(RT_DEBUG_ERROR,
-				 ("RTUSB_VendorRequest failed(%d),TxFlags=0x%x, ReqType=%s, Req=0x%x, Index=0x%x\n",
-				  ret, TransferFlags,
-				  (RequestType ==
-				   DEVICE_VENDOR_REQUEST_OUT ? "OUT" : "IN"),
-				  Request, Index));
-			if (Request == 0x2)
-				DBGPRINT(RT_DEBUG_ERROR,
-					 ("\tRequest Value=0x%04x!\n", Value));
-
-			if ((TransferBuffer != NULL)
-			    && (TransferBufferLength > 0))
-				hex_dump("Failed TransferBuffer value",
-					 TransferBuffer, TransferBufferLength);
-		}
-
-	}
-
-	if (ret != -1)
-		return STATUS_SUCCESS;
-	else
-		return STATUS_UNSUCCESSFUL;
-}
-
-/*
-	========================================================================
-
-	Routine Description:
-	  Creates an IRP to submite an IOCTL_INTERNAL_USB_RESET_PORT
-	  synchronously. Callers of this function must be running at
-	  PASSIVE LEVEL.
-
-	Arguments:
-
-	Return Value:
-
-	Note:
-
-	========================================================================
-*/
-int RTUSB_ResetDevice(struct rt_rtmp_adapter *pAd)
-{
-	int Status = TRUE;
-
-	DBGPRINT_RAW(RT_DEBUG_TRACE, ("--->USB_ResetDevice\n"));
-	/*RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS); */
-	return Status;
-}
-
-void CMDHandler(struct rt_rtmp_adapter *pAd)
-{
-	struct rt_cmdqelmt *cmdqelmt;
-	u8 *pData;
-	int NdisStatus = NDIS_STATUS_SUCCESS;
-/*      unsigned long                   Now = 0; */
-	int ntStatus;
-/*      unsigned long   IrqFlags; */
-
-	while (pAd && pAd->CmdQ.size > 0) {
-		NdisStatus = NDIS_STATUS_SUCCESS;
-
-		NdisAcquireSpinLock(&pAd->CmdQLock);
-		RTUSBDequeueCmd(&pAd->CmdQ, &cmdqelmt);
-		NdisReleaseSpinLock(&pAd->CmdQLock);
-
-		if (cmdqelmt == NULL)
-			break;
-
-		pData = cmdqelmt->buffer;
-
-		if (!
-		    (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)
-		     || RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS))) {
-			switch (cmdqelmt->command) {
-			case CMDTHREAD_CHECK_GPIO:
-				{
-					u32 data;
-
-					{
-						/* Read GPIO pin2 as Hardware controlled radio state */
-
-						RTUSBReadMACRegister(pAd,
-								     GPIO_CTRL_CFG,
-								     &data);
-
-						if (data & 0x04) {
-							pAd->StaCfg.bHwRadio =
-							    TRUE;
-						} else {
-							pAd->StaCfg.bHwRadio =
-							    FALSE;
-						}
-
-						if (pAd->StaCfg.bRadio !=
-						    (pAd->StaCfg.bHwRadio
-						     && pAd->StaCfg.bSwRadio)) {
-							pAd->StaCfg.bRadio =
-							    (pAd->StaCfg.
-							     bHwRadio
-							     && pAd->StaCfg.
-							     bSwRadio);
-							if (pAd->StaCfg.
-							    bRadio == TRUE) {
-								DBGPRINT_RAW
-								    (RT_DEBUG_ERROR,
-								     ("!!! Radio On !!!\n"));
-
-								MlmeRadioOn
-								    (pAd);
-								/* Update extra information */
-								pAd->ExtraInfo =
-								    EXTRA_INFO_CLEAR;
-							} else {
-								DBGPRINT_RAW
-								    (RT_DEBUG_ERROR,
-								     ("!!! Radio Off !!!\n"));
-
-								MlmeRadioOff
-								    (pAd);
-								/* Update extra information */
-								pAd->ExtraInfo =
-								    HW_RADIO_OFF;
-							}
-						}
-					}
-				}
-				break;
-
-			case CMDTHREAD_QKERIODIC_EXECUT:
-				{
-					StaQuickResponeForRateUpExec(NULL, pAd,
-								     NULL,
-								     NULL);
-				}
-				break;
-
-			case CMDTHREAD_RESET_BULK_OUT:
-				{
-					u32 MACValue;
-					u8 Index;
-					int ret = 0;
-					struct rt_ht_tx_context *pHTTXContext;
-/*                                              struct rt_rtmp_tx_ring *pTxRing; */
-					unsigned long IrqFlags;
-
-					DBGPRINT_RAW(RT_DEBUG_TRACE,
-						     ("CmdThread : CMDTHREAD_RESET_BULK_OUT(ResetPipeid=0x%0x)===>\n",
-						      pAd->bulkResetPipeid));
-					/* All transfers must be aborted or cancelled before attempting to reset the pipe. */
-					/*RTUSBCancelPendingBulkOutIRP(pAd); */
-					/* Wait 10ms to let previous packet that are already in HW FIFO to clear. by MAXLEE 12-25-2007 */
-					Index = 0;
-					do {
-						RTUSBReadMACRegister(pAd,
-								     TXRXQ_PCNT,
-								     &MACValue);
-						if ((MACValue & 0xf00000
-						     /*0x800000 */) == 0)
-							break;
-						Index++;
-						RTMPusecDelay(10000);
-					} while (Index < 100);
-					MACValue = 0;
-					RTUSBReadMACRegister(pAd, USB_DMA_CFG,
-							     &MACValue);
-					/* To prevent Read Register error, we 2nd check the validity. */
-					if ((MACValue & 0xc00000) == 0)
-						RTUSBReadMACRegister(pAd,
-								     USB_DMA_CFG,
-								     &MACValue);
-					/* To prevent Read Register error, we 3rd check the validity. */
-					if ((MACValue & 0xc00000) == 0)
-						RTUSBReadMACRegister(pAd,
-								     USB_DMA_CFG,
-								     &MACValue);
-					MACValue |= 0x80000;
-					RTUSBWriteMACRegister(pAd, USB_DMA_CFG,
-							      MACValue);
-
-					/* Wait 1ms to prevent next URB to bulkout before HW reset. by MAXLEE 12-25-2007 */
-					RTMPusecDelay(1000);
-
-					MACValue &= (~0x80000);
-					RTUSBWriteMACRegister(pAd, USB_DMA_CFG,
-							      MACValue);
-					DBGPRINT_RAW(RT_DEBUG_TRACE,
-						     ("\tSet 0x2a0 bit19. Clear USB DMA TX path\n"));
-
-					/* Wait 5ms to prevent next URB to bulkout before HW reset. by MAXLEE 12-25-2007 */
-					/*RTMPusecDelay(5000); */
-
-					if ((pAd->
-					     bulkResetPipeid &
-					     BULKOUT_MGMT_RESET_FLAG) ==
-					    BULKOUT_MGMT_RESET_FLAG) {
-						RTMP_CLEAR_FLAG(pAd,
-								fRTMP_ADAPTER_BULKOUT_RESET);
-						if (pAd->MgmtRing.TxSwFreeIdx <
-						    MGMT_RING_SIZE
-						    /* pMLMEContext->bWaitingBulkOut == TRUE */
-						    ) {
-							RTUSB_SET_BULK_FLAG(pAd,
-									    fRTUSB_BULK_OUT_MLME);
-						}
-						RTUSBKickBulkOut(pAd);
-
-						DBGPRINT_RAW(RT_DEBUG_TRACE,
-							     ("\tTX MGMT RECOVER Done!\n"));
-					} else {
-						pHTTXContext =
-						    &(pAd->
-						      TxContext[pAd->
-								bulkResetPipeid]);
-						/*NdisAcquireSpinLock(&pAd->BulkOutLock[pAd->bulkResetPipeid]); */
-						RTMP_INT_LOCK(&pAd->
-							      BulkOutLock[pAd->
-									  bulkResetPipeid],
-							      IrqFlags);
-						if (pAd->
-						    BulkOutPending[pAd->
-								   bulkResetPipeid]
-						    == FALSE) {
-							pAd->
-							    BulkOutPending[pAd->
-									   bulkResetPipeid]
-							    = TRUE;
-							pHTTXContext->
-							    IRPPending = TRUE;
-							pAd->
-							    watchDogTxPendingCnt
-							    [pAd->
-							     bulkResetPipeid] =
-							    1;
-
-							/* no matter what, clean the flag */
-							RTMP_CLEAR_FLAG(pAd,
-									fRTMP_ADAPTER_BULKOUT_RESET);
-
-							/*NdisReleaseSpinLock(&pAd->BulkOutLock[pAd->bulkResetPipeid]); */
-							RTMP_INT_UNLOCK(&pAd->
-									BulkOutLock
-									[pAd->
-									 bulkResetPipeid],
-									IrqFlags);
-							{
-								RTUSBInitHTTxDesc
-								    (pAd,
-								     pHTTXContext,
-								     pAd->
-								     bulkResetPipeid,
-								     pHTTXContext->
-								     BulkOutSize,
-								     (usb_complete_t)
-								     RTUSBBulkOutDataPacketComplete);
-
-								ret = RTUSB_SUBMIT_URB
-								     (pHTTXContext->
-								      pUrb);
-								if (ret != 0) {
-									RTMP_INT_LOCK
-									    (&pAd->
-									     BulkOutLock
-									     [pAd->
-									      bulkResetPipeid],
-									     IrqFlags);
-									pAd->
-									    BulkOutPending
-									    [pAd->
-									     bulkResetPipeid]
-									    =
-									    FALSE;
-									pHTTXContext->
-									    IRPPending
-									    =
-									    FALSE;
-									pAd->
-									    watchDogTxPendingCnt
-									    [pAd->
-									     bulkResetPipeid]
-									    = 0;
-									RTMP_INT_UNLOCK
-									    (&pAd->
-									     BulkOutLock
-									     [pAd->
-									      bulkResetPipeid],
-									     IrqFlags);
-
-									DBGPRINT
-									    (RT_DEBUG_ERROR,
-									     ("CmdThread : CMDTHREAD_RESET_BULK_OUT: Submit Tx URB failed %d\n",
-									      ret));
-								} else {
-									RTMP_IRQ_LOCK
-									    (&pAd->
-									     BulkOutLock
-									     [pAd->
-									      bulkResetPipeid],
-									     IrqFlags);
-									DBGPRINT_RAW
-									    (RT_DEBUG_TRACE,
-									     ("\tCMDTHREAD_RESET_BULK_OUT: TxContext[%d]:CWPos=%ld, NBPos=%ld, ENBPos=%ld, bCopy=%d, pending=%d!\n",
-									      pAd->
-									      bulkResetPipeid,
-									      pHTTXContext->
-									      CurWritePosition,
-									      pHTTXContext->
-									      NextBulkOutPosition,
-									      pHTTXContext->
-									      ENextBulkOutPosition,
-									      pHTTXContext->
-									      bCopySavePad,
-									      pAd->
-									      BulkOutPending
-									      [pAd->
-									       bulkResetPipeid]));
-									DBGPRINT_RAW
-									    (RT_DEBUG_TRACE,
-									     ("\t\tBulkOut Req=0x%lx, Complete=0x%lx, Other=0x%lx\n",
-									      pAd->
-									      BulkOutReq,
-									      pAd->
-									      BulkOutComplete,
-									      pAd->
-									      BulkOutCompleteOther));
-									RTMP_IRQ_UNLOCK
-									    (&pAd->
-									     BulkOutLock
-									     [pAd->
-									      bulkResetPipeid],
-									     IrqFlags);
-									DBGPRINT_RAW
-									    (RT_DEBUG_TRACE,
-									     ("\tCMDTHREAD_RESET_BULK_OUT: Submit Tx DATA URB for failed BulkReq(0x%lx) Done, status=%d!\n",
-									      pAd->
-									      bulkResetReq
-									      [pAd->
-									       bulkResetPipeid],
-									      pHTTXContext->
-									      pUrb->
-									      status));
-
-								}
-							}
-						} else {
-							/*NdisReleaseSpinLock(&pAd->BulkOutLock[pAd->bulkResetPipeid]); */
-							/*RTMP_INT_UNLOCK(&pAd->BulkOutLock[pAd->bulkResetPipeid], IrqFlags); */
-
-							DBGPRINT_RAW
-							    (RT_DEBUG_ERROR,
-							     ("CmdThread : TX DATA RECOVER FAIL for BulkReq(0x%lx) because BulkOutPending[%d] is TRUE!\n",
-							      pAd->
-							      bulkResetReq[pAd->
-									   bulkResetPipeid],
-							      pAd->
-							      bulkResetPipeid));
-							if (pAd->
-							    bulkResetPipeid ==
-							    0) {
-								u8
-								    pendingContext
-								    = 0;
-								struct rt_ht_tx_context *
-								    pHTTXContext
-								    =
-								    (struct rt_ht_tx_context *)
-								    (&pAd->
-								     TxContext
-								     [pAd->
-								      bulkResetPipeid]);
-								struct rt_tx_context *
-								    pMLMEContext
-								    =
-								    (struct rt_tx_context *)
-								    (pAd->
-								     MgmtRing.
-								     Cell[pAd->
-									  MgmtRing.
-									  TxDmaIdx].
-								     AllocVa);
-								struct rt_tx_context *
-								    pNULLContext
-								    =
-								    (struct rt_tx_context *)
-								    (&pAd->
-								     PsPollContext);
-								struct rt_tx_context *
-								    pPsPollContext
-								    =
-								    (struct rt_tx_context *)
-								    (&pAd->
-								     NullContext);
-
-								if (pHTTXContext->IRPPending)
-									pendingContext
-									    |=
-									    1;
-								else if
-								    (pMLMEContext->
-								     IRPPending)
-									pendingContext
-									    |=
-									    2;
-								else if
-								    (pNULLContext->
-								     IRPPending)
-									pendingContext
-									    |=
-									    4;
-								else if
-								    (pPsPollContext->
-								     IRPPending)
-									pendingContext
-									    |=
-									    8;
-								else
-									pendingContext
-									    = 0;
-
-								DBGPRINT_RAW
-								    (RT_DEBUG_ERROR,
-								     ("\tTX Occupied by %d!\n",
-								      pendingContext));
-							}
-							/* no matter what, clean the flag */
-							RTMP_CLEAR_FLAG(pAd,
-									fRTMP_ADAPTER_BULKOUT_RESET);
-
-							RTMP_INT_UNLOCK(&pAd->
-									BulkOutLock
-									[pAd->
-									 bulkResetPipeid],
-									IrqFlags);
-
-							RTUSB_SET_BULK_FLAG(pAd,
-									    (fRTUSB_BULK_OUT_DATA_NORMAL
-									     <<
-									     pAd->
-									     bulkResetPipeid));
-						}
-
-						RTMPDeQueuePacket(pAd, FALSE,
-								  NUM_OF_TX_RING,
-								  MAX_TX_PROCESS);
-						/*RTUSBKickBulkOut(pAd); */
-					}
-
-				}
-				/*
-				   // Don't cancel BULKIN.
-				   while ((atomic_read(&pAd->PendingRx) > 0) &&
-				   (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)))
-				   {
-				   if (atomic_read(&pAd->PendingRx) > 0)
-				   {
-				   DBGPRINT_RAW(RT_DEBUG_ERROR, ("BulkIn IRP Pending!!cancel it!\n"));
-				   RTUSBCancelPendingBulkInIRP(pAd);
-				   }
-				   RTMPusecDelay(100000);
-				   }
-
-				   if ((atomic_read(&pAd->PendingRx) == 0) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)))
-				   {
-				   u8        i;
-				   RTUSBRxPacket(pAd);
-				   pAd->NextRxBulkInReadIndex = 0;      // Next Rx Read index
-				   pAd->NextRxBulkInIndex               = 0;    // Rx Bulk pointer
-				   for (i = 0; i < (RX_RING_SIZE); i++)
-				   {
-				   struct rt_rx_context *pRxContext = &(pAd->RxContext[i]);
-
-				   pRxContext->pAd      = pAd;
-				   pRxContext->InUse            = FALSE;
-				   pRxContext->IRPPending       = FALSE;
-				   pRxContext->Readable = FALSE;
-				   pRxContext->ReorderInUse = FALSE;
-
-				   }
-				   RTUSBBulkReceive(pAd);
-				   DBGPRINT_RAW(RT_DEBUG_ERROR, ("RTUSBBulkReceive\n"));
-				   } */
-				DBGPRINT_RAW(RT_DEBUG_TRACE,
-					     ("CmdThread : CMDTHREAD_RESET_BULK_OUT<===\n"));
-				break;
-
-			case CMDTHREAD_RESET_BULK_IN:
-				DBGPRINT_RAW(RT_DEBUG_TRACE,
-					     ("CmdThread : CMDTHREAD_RESET_BULK_IN === >\n"));
-
-				/* All transfers must be aborted or cancelled before attempting to reset the pipe. */
-				{
-					u32 MACValue;
-					{
-						/*while ((atomic_read(&pAd->PendingRx) > 0) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))) */
-						if ((pAd->PendingRx > 0)
-						    &&
-						    (!RTMP_TEST_FLAG
-						     (pAd,
-						      fRTMP_ADAPTER_NIC_NOT_EXIST))) {
-							DBGPRINT_RAW
-							    (RT_DEBUG_ERROR,
-							     ("BulkIn IRP Pending!!!\n"));
-							RTUSBCancelPendingBulkInIRP
-							    (pAd);
-							RTMPusecDelay(100000);
-							pAd->PendingRx = 0;
-						}
-					}
-					/* Wait 10ms before reading register. */
-					RTMPusecDelay(10000);
-					ntStatus =
-					    RTUSBReadMACRegister(pAd, MAC_CSR0,
-								 &MACValue);
-
-					if ((NT_SUCCESS(ntStatus) == TRUE) &&
-					    (!(RTMP_TEST_FLAG
-					       (pAd,
-						(fRTMP_ADAPTER_RESET_IN_PROGRESS
-						 | fRTMP_ADAPTER_RADIO_OFF |
-						 fRTMP_ADAPTER_HALT_IN_PROGRESS
-						 |
-						 fRTMP_ADAPTER_NIC_NOT_EXIST)))))
-					{
-						u8 i;
-
-						if (RTMP_TEST_FLAG
-						    (pAd,
-						     (fRTMP_ADAPTER_RESET_IN_PROGRESS
-						      | fRTMP_ADAPTER_RADIO_OFF
-						      |
-						      fRTMP_ADAPTER_HALT_IN_PROGRESS
-						      |
-						      fRTMP_ADAPTER_NIC_NOT_EXIST)))
-							break;
-						pAd->NextRxBulkInPosition =
-						    pAd->RxContext[pAd->
-								   NextRxBulkInIndex].
-						    BulkInOffset;
-						DBGPRINT(RT_DEBUG_TRACE,
-							 ("BULK_IN_RESET: NBIIdx=0x%x,NBIRIdx=0x%x, BIRPos=0x%lx. BIReq=x%lx, BIComplete=0x%lx, BICFail0x%lx\n",
-							  pAd->
-							  NextRxBulkInIndex,
-							  pAd->
-							  NextRxBulkInReadIndex,
-							  pAd->
-							  NextRxBulkInPosition,
-							  pAd->BulkInReq,
-							  pAd->BulkInComplete,
-							  pAd->
-							  BulkInCompleteFail));
-						for (i = 0; i < RX_RING_SIZE;
-						     i++) {
-							DBGPRINT(RT_DEBUG_TRACE,
-								 ("\tRxContext[%d]: IRPPending=%d, InUse=%d, Readable=%d!\n",
-								  i,
-								  pAd->
-								  RxContext[i].
-								  IRPPending,
-								  pAd->
-								  RxContext[i].
-								  InUse,
-								  pAd->
-								  RxContext[i].
-								  Readable));
-						}
-						/*
-
-						   DBGPRINT_RAW(RT_DEBUG_ERROR, ("==========================================\n"));
-
-						   pAd->NextRxBulkInReadIndex = 0;      // Next Rx Read index
-						   pAd->NextRxBulkInIndex               = 0;    // Rx Bulk pointer
-						   for (i = 0; i < (RX_RING_SIZE); i++)
-						   {
-						   struct rt_rx_context *pRxContext = &(pAd->RxContext[i]);
-
-						   pRxContext->pAd      = pAd;
-						   pRxContext->InUse            = FALSE;
-						   pRxContext->IRPPending       = FALSE;
-						   pRxContext->Readable = FALSE;
-						   pRxContext->ReorderInUse = FALSE;
-
-						   } */
-						RTMP_CLEAR_FLAG(pAd,
-								fRTMP_ADAPTER_BULKIN_RESET);
-						for (i = 0;
-						     i <
-						     pAd->CommonCfg.
-						     NumOfBulkInIRP; i++) {
-							/*RTUSBBulkReceive(pAd); */
-							struct rt_rx_context *pRxContext;
-							PURB pUrb;
-							int ret = 0;
-							unsigned long IrqFlags;
-
-							RTMP_IRQ_LOCK(&pAd->
-								      BulkInLock,
-								      IrqFlags);
-							pRxContext =
-							    &(pAd->
-							      RxContext[pAd->
-									NextRxBulkInIndex]);
-							if ((pAd->PendingRx > 0)
-							    || (pRxContext->
-								Readable ==
-								TRUE)
-							    || (pRxContext->
-								InUse ==
-								TRUE)) {
-								RTMP_IRQ_UNLOCK
-								    (&pAd->
-								     BulkInLock,
-								     IrqFlags);
-								break;
-							}
-							pRxContext->InUse =
-							    TRUE;
-							pRxContext->IRPPending =
-							    TRUE;
-							pAd->PendingRx++;
-							pAd->BulkInReq++;
-							RTMP_IRQ_UNLOCK(&pAd->
-									BulkInLock,
-									IrqFlags);
-
-							/* Init Rx context descriptor */
-							RTUSBInitRxDesc(pAd,
-									pRxContext);
-							pUrb = pRxContext->pUrb;
-							ret = RTUSB_SUBMIT_URB(pUrb);
-							if (ret != 0) {	/* fail */
-
-								RTMP_IRQ_LOCK
-								    (&pAd->
-								     BulkInLock,
-								     IrqFlags);
-								pRxContext->
-								    InUse =
-								    FALSE;
-								pRxContext->
-								    IRPPending =
-								    FALSE;
-								pAd->
-								    PendingRx--;
-								pAd->
-								    BulkInReq--;
-								RTMP_IRQ_UNLOCK
-								    (&pAd->
-								     BulkInLock,
-								     IrqFlags);
-								DBGPRINT
-								    (RT_DEBUG_ERROR,
-								     ("CMDTHREAD_RESET_BULK_IN: Submit Rx URB failed(%d), status=%d\n",
-								      ret,
-								      pUrb->
-								      status));
-							} else {	/* success */
-								/*DBGPRINT(RT_DEBUG_TRACE, ("BIDone, Pend=%d,BIIdx=%d,BIRIdx=%d!\n", */
-								/*                                                      pAd->PendingRx, pAd->NextRxBulkInIndex, pAd->NextRxBulkInReadIndex)); */
-								DBGPRINT_RAW
-								    (RT_DEBUG_TRACE,
-								     ("CMDTHREAD_RESET_BULK_IN: Submit Rx URB Done, status=%d!\n",
-								      pUrb->
-								      status));
-								ASSERT((pRxContext->InUse == pRxContext->IRPPending));
-							}
-						}
-
-					} else {
-						/* Card must be removed */
-						if (NT_SUCCESS(ntStatus) !=
-						    TRUE) {
-							RTMP_SET_FLAG(pAd,
-								      fRTMP_ADAPTER_NIC_NOT_EXIST);
-							DBGPRINT_RAW
-							    (RT_DEBUG_ERROR,
-							     ("CMDTHREAD_RESET_BULK_IN: Read Register Failed!Card must be removed!!\n\n"));
-						} else {
-							DBGPRINT_RAW
-							    (RT_DEBUG_ERROR,
-							     ("CMDTHREAD_RESET_BULK_IN: Cannot do bulk in because flags(0x%lx) on !\n",
-							      pAd->Flags));
-						}
-					}
-				}
-				DBGPRINT_RAW(RT_DEBUG_TRACE,
-					     ("CmdThread : CMDTHREAD_RESET_BULK_IN <===\n"));
-				break;
-
-			case CMDTHREAD_SET_ASIC_WCID:
-				{
-					struct rt_set_asic_wcid SetAsicWcid;
-					u16 offset;
-					u32 MACValue, MACRValue = 0;
-					SetAsicWcid =
-					    *((struct rt_set_asic_wcid *)(pData));
-
-					if (SetAsicWcid.WCID >=
-					    MAX_LEN_OF_MAC_TABLE)
-						return;
-
-					offset =
-					    MAC_WCID_BASE +
-					    ((u8)SetAsicWcid.WCID) *
-					    HW_WCID_ENTRY_SIZE;
-
-					DBGPRINT_RAW(RT_DEBUG_TRACE,
-						     ("CmdThread : CMDTHREAD_SET_ASIC_WCID : WCID = %ld, SetTid  = %lx, DeleteTid = %lx.\n",
-						      SetAsicWcid.WCID,
-						      SetAsicWcid.SetTid,
-						      SetAsicWcid.DeleteTid));
-					MACValue =
-					    (pAd->MacTab.
-					     Content[SetAsicWcid.WCID].
-					     Addr[3] << 24) +
-					    (pAd->MacTab.
-					     Content[SetAsicWcid.WCID].
-					     Addr[2] << 16) +
-					    (pAd->MacTab.
-					     Content[SetAsicWcid.WCID].
-					     Addr[1] << 8) +
-					    (pAd->MacTab.
-					     Content[SetAsicWcid.WCID].Addr[0]);
-					DBGPRINT_RAW(RT_DEBUG_TRACE,
-						     ("1-MACValue= %x,\n",
-						      MACValue));
-					RTUSBWriteMACRegister(pAd, offset,
-							      MACValue);
-					/* Read bitmask */
-					RTUSBReadMACRegister(pAd, offset + 4,
-							     &MACRValue);
-					if (SetAsicWcid.DeleteTid != 0xffffffff)
-						MACRValue &=
-						    (~SetAsicWcid.DeleteTid);
-					if (SetAsicWcid.SetTid != 0xffffffff)
-						MACRValue |=
-						    (SetAsicWcid.SetTid);
-					MACRValue &= 0xffff0000;
-
-					MACValue =
-					    (pAd->MacTab.
-					     Content[SetAsicWcid.WCID].
-					     Addr[5] << 8) +
-					    pAd->MacTab.Content[SetAsicWcid.
-								WCID].Addr[4];
-					MACValue |= MACRValue;
-					RTUSBWriteMACRegister(pAd, offset + 4,
-							      MACValue);
-
-					DBGPRINT_RAW(RT_DEBUG_TRACE,
-						     ("2-MACValue= %x,\n",
-						      MACValue));
-				}
-				break;
-
-			case CMDTHREAD_SET_ASIC_WCID_CIPHER:
-				{
-					struct rt_set_asic_wcid_attri SetAsicWcidAttri;
-					u16 offset;
-					u32 MACRValue = 0;
-					SHAREDKEY_MODE_STRUC csr1;
-					SetAsicWcidAttri =
-					    *((struct rt_set_asic_wcid_attri *)
-					      (pData));
-
-					if (SetAsicWcidAttri.WCID >=
-					    MAX_LEN_OF_MAC_TABLE)
-						return;
-
-					offset =
-					    MAC_WCID_ATTRIBUTE_BASE +
-					    ((u8)SetAsicWcidAttri.WCID) *
-					    HW_WCID_ATTRI_SIZE;
-
-					DBGPRINT_RAW(RT_DEBUG_TRACE,
-						     ("Cmd : CMDTHREAD_SET_ASIC_WCID_CIPHER : WCID = %ld, Cipher = %lx.\n",
-						      SetAsicWcidAttri.WCID,
-						      SetAsicWcidAttri.Cipher));
-					/* Read bitmask */
-					RTUSBReadMACRegister(pAd, offset,
-							     &MACRValue);
-					MACRValue = 0;
-					MACRValue |=
-					    (((u8)SetAsicWcidAttri.
-					      Cipher) << 1);
-
-					RTUSBWriteMACRegister(pAd, offset,
-							      MACRValue);
-					DBGPRINT_RAW(RT_DEBUG_TRACE,
-						     ("2-offset = %x , MACValue= %x,\n",
-						      offset, MACRValue));
-
-					offset =
-					    PAIRWISE_IVEIV_TABLE_BASE +
-					    ((u8)SetAsicWcidAttri.WCID) *
-					    HW_IVEIV_ENTRY_SIZE;
-					MACRValue = 0;
-					if ((SetAsicWcidAttri.Cipher <=
-					     CIPHER_WEP128))
-						MACRValue |=
-						    (pAd->StaCfg.
-						     DefaultKeyId << 30);
-					else
-						MACRValue |= (0x20000000);
-					RTUSBWriteMACRegister(pAd, offset,
-							      MACRValue);
-					DBGPRINT_RAW(RT_DEBUG_TRACE,
-						     ("2-offset = %x , MACValue= %x,\n",
-						      offset, MACRValue));
-
-					/* */
-					/* Update cipher algorithm. WSTA always use BSS0 */
-					/* */
-					/* for adhoc mode only ,because wep status slow than add key, when use zero config */
-					if (pAd->StaCfg.BssType == BSS_ADHOC) {
-						offset =
-						    MAC_WCID_ATTRIBUTE_BASE;
-
-						RTUSBReadMACRegister(pAd,
-								     offset,
-								     &MACRValue);
-						MACRValue &= (~0xe);
-						MACRValue |=
-						    (((u8)SetAsicWcidAttri.
-						      Cipher) << 1);
-
-						RTUSBWriteMACRegister(pAd,
-								      offset,
-								      MACRValue);
-
-						/*Update group key cipher,,because wep status slow than add key, when use zero config */
-						RTUSBReadMACRegister(pAd,
-								     SHARED_KEY_MODE_BASE
-								     +
-								     4 * (0 /
-									  2),
-								     &csr1.
-								     word);
-
-						csr1.field.Bss0Key0CipherAlg =
-						    SetAsicWcidAttri.Cipher;
-						csr1.field.Bss0Key1CipherAlg =
-						    SetAsicWcidAttri.Cipher;
-
-						RTUSBWriteMACRegister(pAd,
-								      SHARED_KEY_MODE_BASE
-								      +
-								      4 * (0 /
-									   2),
-								      csr1.
-								      word);
-					}
-				}
-				break;
-
-/*Benson modified for USB interface, avoid in interrupt when write key, 20080724 --> */
-			case RT_CMD_SET_KEY_TABLE:	/*General call for AsicAddPairwiseKeyEntry() */
-				{
-					struct rt_add_pairwise_key_entry KeyInfo;
-					KeyInfo =
-					    *((struct rt_add_pairwise_key_entry *)
-					      (pData));
-					AsicAddPairwiseKeyEntry(pAd,
-								KeyInfo.MacAddr,
-								(u8)KeyInfo.
-								MacTabMatchWCID,
-								&KeyInfo.
-								CipherKey);
-				}
-				break;
-
-			case RT_CMD_SET_RX_WCID_TABLE:	/*General call for RTMPAddWcidAttributeEntry() */
-				{
-					struct rt_mac_table_entry *pEntry;
-					u8 KeyIdx = 0;
-					u8 CipherAlg = CIPHER_NONE;
-					u8 ApIdx = BSS0;
-
-					pEntry = (struct rt_mac_table_entry *)(pData);
-
-					RTMPAddWcidAttributeEntry(pAd,
-								  ApIdx,
-								  KeyIdx,
-								  CipherAlg,
-								  pEntry);
-				}
-				break;
-/*Benson modified for USB interface, avoid in interrupt when write key, 20080724 <-- */
-
-			case CMDTHREAD_SET_CLIENT_MAC_ENTRY:
-				{
-					struct rt_mac_table_entry *pEntry;
-					pEntry = (struct rt_mac_table_entry *)pData;
-
-					{
-						AsicRemovePairwiseKeyEntry(pAd,
-									   pEntry->
-									   apidx,
-									   (u8)
-									   pEntry->
-									   Aid);
-						if ((pEntry->AuthMode <=
-						     Ndis802_11AuthModeAutoSwitch)
-						    && (pEntry->WepStatus ==
-							Ndis802_11Encryption1Enabled))
-						{
-							u32 uIV = 1;
-							u8 *ptr;
-
-							ptr = (u8 *)& uIV;
-							*(ptr + 3) =
-							    (pAd->StaCfg.
-							     DefaultKeyId << 6);
-							AsicUpdateWCIDIVEIV(pAd,
-									    pEntry->
-									    Aid,
-									    uIV,
-									    0);
-							AsicUpdateWCIDAttribute
-							    (pAd, pEntry->Aid,
-							     BSS0,
-							     pAd->
-							     SharedKey[BSS0]
-							     [pAd->StaCfg.
-							      DefaultKeyId].
-							     CipherAlg, FALSE);
-						} else if (pEntry->AuthMode ==
-							   Ndis802_11AuthModeWPANone)
-						{
-							u32 uIV = 1;
-							u8 *ptr;
-
-							ptr = (u8 *)& uIV;
-							*(ptr + 3) =
-							    (pAd->StaCfg.
-							     DefaultKeyId << 6);
-							AsicUpdateWCIDIVEIV(pAd,
-									    pEntry->
-									    Aid,
-									    uIV,
-									    0);
-							AsicUpdateWCIDAttribute
-							    (pAd, pEntry->Aid,
-							     BSS0,
-							     pAd->
-							     SharedKey[BSS0]
-							     [pAd->StaCfg.
-							      DefaultKeyId].
-							     CipherAlg, FALSE);
-						} else {
-							/* */
-							/* Other case, disable engine. */
-							/* Don't worry WPA key, we will add WPA Key after 4-Way handshaking. */
-							/* */
-							u16 offset;
-							offset =
-							    MAC_WCID_ATTRIBUTE_BASE
-							    +
-							    (pEntry->Aid *
-							     HW_WCID_ATTRI_SIZE);
-							/* RX_PKEY_MODE:0 for no security; RX_KEY_TAB:0 for shared key table; BSS_IDX:0 */
-							RTUSBWriteMACRegister
-							    (pAd, offset, 0);
-						}
-					}
-
-					AsicUpdateRxWCIDTable(pAd, pEntry->Aid,
-							      pEntry->Addr);
-					DBGPRINT(RT_DEBUG_TRACE,
-						("UpdateRxWCIDTable(): Aid=%d, "
-							"Addr=%pM!\n",
-							pEntry->Aid,
-							pEntry->Addr));
-				}
-				break;
-
-/* add by johnli, fix "in_interrupt" error when call "MacTableDeleteEntry" in Rx tasklet */
-			case CMDTHREAD_UPDATE_PROTECT:
-				{
-					AsicUpdateProtect(pAd, 0,
-							  (ALLN_SETPROTECT),
-							  TRUE, 0);
-				}
-				break;
-/* end johnli */
-
-			case OID_802_11_ADD_WEP:
-				{
-					u32 i;
-					u32 KeyIdx;
-					struct rt_ndis_802_11_wep *pWepKey;
-
-					DBGPRINT(RT_DEBUG_TRACE,
-						 ("CmdThread::OID_802_11_ADD_WEP  \n"));
-
-					pWepKey = (struct rt_ndis_802_11_wep *)pData;
-					KeyIdx = pWepKey->KeyIndex & 0x0fffffff;
-
-					/* it is a shared key */
-					if ((KeyIdx >= 4)
-					    || ((pWepKey->KeyLength != 5)
-						&& (pWepKey->KeyLength !=
-						    13))) {
-						NdisStatus =
-						    NDIS_STATUS_INVALID_DATA;
-						DBGPRINT(RT_DEBUG_ERROR,
-							 ("CmdThread::OID_802_11_ADD_WEP, INVALID_DATA!!\n"));
-					} else {
-						u8 CipherAlg;
-						pAd->SharedKey[BSS0][KeyIdx].
-						    KeyLen =
-						    (u8)pWepKey->KeyLength;
-						NdisMoveMemory(pAd->
-							       SharedKey[BSS0]
-							       [KeyIdx].Key,
-							       &pWepKey->
-							       KeyMaterial,
-							       pWepKey->
-							       KeyLength);
-						CipherAlg =
-						    (pAd->
-						     SharedKey[BSS0][KeyIdx].
-						     KeyLen ==
-						     5) ? CIPHER_WEP64 :
-						    CIPHER_WEP128;
-
-						/* */
-						/* Change the WEP cipher to CKIP cipher if CKIP KP on. */
-						/* Funk UI or Meetinghouse UI will add ckip key from this path. */
-						/* */
-
-						if (pAd->OpMode == OPMODE_STA) {
-							pAd->MacTab.
-							    Content[BSSID_WCID].
-							    PairwiseKey.
-							    CipherAlg =
-							    pAd->
-							    SharedKey[BSS0]
-							    [KeyIdx].CipherAlg;
-							pAd->MacTab.
-							    Content[BSSID_WCID].
-							    PairwiseKey.KeyLen =
-							    pAd->
-							    SharedKey[BSS0]
-							    [KeyIdx].KeyLen;
-						}
-						pAd->SharedKey[BSS0][KeyIdx].
-						    CipherAlg = CipherAlg;
-						if (pWepKey->
-						    KeyIndex & 0x80000000) {
-							/* Default key for tx (shared key) */
-							u8 IVEIV[8];
-							u32 WCIDAttri, Value;
-							u16 offset, offset2;
-							NdisZeroMemory(IVEIV,
-								       8);
-							pAd->StaCfg.
-							    DefaultKeyId =
-							    (u8)KeyIdx;
-							/* Add BSSID to WCTable. because this is Tx wep key. */
-							/* WCID Attribute UDF:3, BSSIdx:3, Alg:3, Keytable:1=PAIRWISE KEY, BSSIdx is 0 */
-							WCIDAttri =
-							    (CipherAlg << 1) |
-							    SHAREDKEYTABLE;
-
-							offset =
-							    MAC_WCID_ATTRIBUTE_BASE
-							    +
-							    (BSSID_WCID *
-							     HW_WCID_ATTRI_SIZE);
-							RTUSBWriteMACRegister
-							    (pAd, offset,
-							     WCIDAttri);
-							/* 1. IV/EIV */
-							/* Specify key index to find shared key. */
-							IVEIV[3] = (u8)(KeyIdx << 6);	/*WEP Eiv bit off. groupkey index is not 0 */
-							offset =
-							    PAIRWISE_IVEIV_TABLE_BASE
-							    +
-							    (BSS0Mcast_WCID *
-							     HW_IVEIV_ENTRY_SIZE);
-							offset2 =
-							    PAIRWISE_IVEIV_TABLE_BASE
-							    +
-							    (BSSID_WCID *
-							     HW_IVEIV_ENTRY_SIZE);
-							for (i = 0; i < 8;) {
-								Value =
-								    IVEIV[i];
-								Value +=
-								    (IVEIV
-								     [i +
-								      1] << 8);
-								Value +=
-								    (IVEIV
-								     [i +
-								      2] << 16);
-								Value +=
-								    (IVEIV
-								     [i +
-								      3] << 24);
-								RTUSBWriteMACRegister
-								    (pAd,
-								     offset + i,
-								     Value);
-								RTUSBWriteMACRegister
-								    (pAd,
-								     offset2 +
-								     i, Value);
-								i += 4;
-							}
-
-							/* 2. WCID Attribute UDF:3, BSSIdx:3, Alg:3, Keytable:use share key, BSSIdx is 0 */
-							WCIDAttri =
-							    (pAd->
-							     SharedKey[BSS0]
-							     [KeyIdx].
-							     CipherAlg << 1) |
-							    SHAREDKEYTABLE;
-							offset =
-							    MAC_WCID_ATTRIBUTE_BASE
-							    +
-							    (BSS0Mcast_WCID *
-							     HW_WCID_ATTRI_SIZE);
-							DBGPRINT(RT_DEBUG_TRACE,
-								 ("BSS0Mcast_WCID : offset = %x, WCIDAttri = %x\n",
-								  offset,
-								  WCIDAttri));
-							RTUSBWriteMACRegister
-							    (pAd, offset,
-							     WCIDAttri);
-
-						}
-						AsicAddSharedKeyEntry(pAd, BSS0,
-								      (u8)
-								      KeyIdx,
-								      CipherAlg,
-								      pWepKey->
-								      KeyMaterial,
-								      NULL,
-								      NULL);
-						DBGPRINT(RT_DEBUG_TRACE,
-							 ("CmdThread::OID_802_11_ADD_WEP (KeyIdx=%d, Len=%d-byte)\n",
-							  KeyIdx,
-							  pWepKey->KeyLength));
-					}
-				}
-				break;
-
-			case CMDTHREAD_802_11_COUNTER_MEASURE:
-				break;
-
-			case CMDTHREAD_SET_GROUP_KEY:
-				WpaStaGroupKeySetting(pAd);
-				break;
-
-			case CMDTHREAD_SET_PAIRWISE_KEY:
-				WpaStaPairwiseKeySetting(pAd);
-				break;
-
-			case CMDTHREAD_SET_PSM_BIT:
-				{
-					u16 *pPsm = (u16 *) pData;
-					MlmeSetPsmBit(pAd, *pPsm);
-				}
-				break;
-			case CMDTHREAD_FORCE_WAKE_UP:
-				AsicForceWakeup(pAd, TRUE);
-				break;
-
-			default:
-				DBGPRINT(RT_DEBUG_ERROR,
-					 ("--> Control Thread !! ERROR !! Unknown(cmdqelmt->command=0x%x) !! \n",
-					  cmdqelmt->command));
-				break;
-			}
-		}
-
-		if (cmdqelmt->CmdFromNdis == TRUE) {
-			if (cmdqelmt->buffer != NULL)
-				os_free_mem(pAd, cmdqelmt->buffer);
-			os_free_mem(pAd, cmdqelmt);
-		} else {
-			if ((cmdqelmt->buffer != NULL)
-			    && (cmdqelmt->bufferlength != 0))
-				os_free_mem(pAd, cmdqelmt->buffer);
-			os_free_mem(pAd, cmdqelmt);
-		}
-	}			/* end of while */
-}
-
-#endif /* RTMP_MAC_USB // */
diff -druN linux-2.6.39-libre/drivers/staging/rt2870/common/spectrum.c linux-3.0-rc7-libre/drivers/staging/rt2870/common/spectrum.c
--- linux-2.6.39-libre/drivers/staging/rt2870/common/spectrum.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rt2870/common/spectrum.c	1969-12-31 19:00:00.000000000 -0500
@@ -1 +0,0 @@
-#include "../../rt2860/common/spectrum.c"
diff -druN linux-2.6.39-libre/drivers/staging/rt2870/dfs.h linux-3.0-rc7-libre/drivers/staging/rt2870/dfs.h
--- linux-2.6.39-libre/drivers/staging/rt2870/dfs.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rt2870/dfs.h	1969-12-31 19:00:00.000000000 -0500
@@ -1 +0,0 @@
-#include "../rt2860/dfs.h"
diff -druN linux-2.6.39-libre/drivers/staging/rt2870/Kconfig linux-3.0-rc7-libre/drivers/staging/rt2870/Kconfig
--- linux-2.6.39-libre/drivers/staging/rt2870/Kconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rt2870/Kconfig	1969-12-31 19:00:00.000000000 -0500
@@ -1,9 +0,0 @@
-config RT2870
-	tristate "Ralink 2870/3070 wireless support"
-	depends on USB && (X86 || ARM) && 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 -druN linux-2.6.39-libre/drivers/staging/rt2870/Makefile linux-3.0-rc7-libre/drivers/staging/rt2870/Makefile
--- linux-2.6.39-libre/drivers/staging/rt2870/Makefile	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rt2870/Makefile	1969-12-31 19:00:00.000000000 -0500
@@ -1,55 +0,0 @@
-#
-obj-$(CONFIG_RT2870)	+= rt2870sta.o
-
-# TODO: all of these should be removed
-ccflags-y := -DLINUX -DAGGREGATION_SUPPORT -DPIGGYBACK_SUPPORT -DWMM_SUPPORT
-ccflags-y += -DRTMP_MAC_USB -DRTMP_USB_SUPPORT -DRT2870 -DRTMP_TIMER_TASK_SUPPORT
-ccflags-y += -DRTMP_RF_RW_SUPPORT -DRTMP_EFUSE_SUPPORT -DRT30xx -DRT3070
-ccflags-y += -DDBG
-
-rt2870sta-y :=		\
-	common/crypt_md5.o	\
-	common/crypt_sha2.o	\
-	common/crypt_hmac.o	\
-	common/mlme.o		\
-	common/cmm_wep.o	\
-	common/action.o		\
-	common/cmm_data.o	\
-	common/rtmp_init.o	\
-	common/cmm_tkip.o	\
-	common/cmm_aes.o	\
-	common/cmm_sync.o	\
-	common/eeprom.o		\
-	common/cmm_sanity.o	\
-	common/cmm_info.o	\
-	common/cmm_cfg.o	\
-	common/cmm_wpa.o	\
-	common/dfs.o		\
-	common/spectrum.o	\
-	common/rtmp_timer.o	\
-	common/rt_channel.o	\
-	common/cmm_asic.o	\
-	sta/assoc.o		\
-	sta/auth.o		\
-	sta/auth_rsp.o		\
-	sta/sync.o		\
-	sta/sanity.o		\
-	sta/rtmp_data.o		\
-	sta/connect.o		\
-	sta/wpa.o		\
-	rt_linux.o		\
-	rt_main_dev.o		\
-	sta_ioctl.o		\
-	common/ba_action.o	\
-	usb_main_dev.o		\
-	rt_usb.o		\
-	common/cmm_mac_usb.o	\
-	common/rtusb_io.o	\
-	common/rtusb_bulk.o	\
-	common/rtusb_data.o	\
-	common/cmm_data_usb.o	\
-	common/rtmp_mcu.o	\
-	common/ee_efuse.o	\
-	chips/rt30xx.o		\
-	common/rt_rf.o		\
-	chips/rt3070.o
diff -druN linux-2.6.39-libre/drivers/staging/rt2870/md5.h linux-3.0-rc7-libre/drivers/staging/rt2870/md5.h
--- linux-2.6.39-libre/drivers/staging/rt2870/md5.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rt2870/md5.h	1969-12-31 19:00:00.000000000 -0500
@@ -1 +0,0 @@
-#include "../rt2860/md5.h"
diff -druN linux-2.6.39-libre/drivers/staging/rt2870/mlme.h linux-3.0-rc7-libre/drivers/staging/rt2870/mlme.h
--- linux-2.6.39-libre/drivers/staging/rt2870/mlme.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rt2870/mlme.h	1969-12-31 19:00:00.000000000 -0500
@@ -1 +0,0 @@
-#include "../rt2860/mlme.h"
diff -druN linux-2.6.39-libre/drivers/staging/rt2870/oid.h linux-3.0-rc7-libre/drivers/staging/rt2870/oid.h
--- linux-2.6.39-libre/drivers/staging/rt2870/oid.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rt2870/oid.h	1969-12-31 19:00:00.000000000 -0500
@@ -1 +0,0 @@
-#include "../rt2860/oid.h"
diff -druN linux-2.6.39-libre/drivers/staging/rt2870/rt28xx.h linux-3.0-rc7-libre/drivers/staging/rt2870/rt28xx.h
--- linux-2.6.39-libre/drivers/staging/rt2870/rt28xx.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rt2870/rt28xx.h	1969-12-31 19:00:00.000000000 -0500
@@ -1 +0,0 @@
-#include "../rt2860/rt28xx.h"
diff -druN linux-2.6.39-libre/drivers/staging/rt2870/rt_config.h linux-3.0-rc7-libre/drivers/staging/rt2870/rt_config.h
--- linux-2.6.39-libre/drivers/staging/rt2870/rt_config.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rt2870/rt_config.h	1969-12-31 19:00:00.000000000 -0500
@@ -1 +0,0 @@
-#include "../rt2860/rt_config.h"
diff -druN linux-2.6.39-libre/drivers/staging/rt2870/rt_linux.c linux-3.0-rc7-libre/drivers/staging/rt2870/rt_linux.c
--- linux-2.6.39-libre/drivers/staging/rt2870/rt_linux.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rt2870/rt_linux.c	1969-12-31 19:00:00.000000000 -0500
@@ -1 +0,0 @@
-#include "../rt2860/rt_linux.c"
diff -druN linux-2.6.39-libre/drivers/staging/rt2870/rt_linux.h linux-3.0-rc7-libre/drivers/staging/rt2870/rt_linux.h
--- linux-2.6.39-libre/drivers/staging/rt2870/rt_linux.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rt2870/rt_linux.h	1969-12-31 19:00:00.000000000 -0500
@@ -1 +0,0 @@
-#include "../rt2860/rt_linux.h"
diff -druN linux-2.6.39-libre/drivers/staging/rt2870/rt_main_dev.c linux-3.0-rc7-libre/drivers/staging/rt2870/rt_main_dev.c
--- linux-2.6.39-libre/drivers/staging/rt2870/rt_main_dev.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rt2870/rt_main_dev.c	1969-12-31 19:00:00.000000000 -0500
@@ -1 +0,0 @@
-#include "../rt2860/rt_main_dev.c"
diff -druN linux-2.6.39-libre/drivers/staging/rt2870/rtmp_ckipmic.h linux-3.0-rc7-libre/drivers/staging/rt2870/rtmp_ckipmic.h
--- linux-2.6.39-libre/drivers/staging/rt2870/rtmp_ckipmic.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rt2870/rtmp_ckipmic.h	1969-12-31 19:00:00.000000000 -0500
@@ -1 +0,0 @@
-#include "../rt2860/rtmp_ckipmic.h"
diff -druN linux-2.6.39-libre/drivers/staging/rt2870/rtmp_def.h linux-3.0-rc7-libre/drivers/staging/rt2870/rtmp_def.h
--- linux-2.6.39-libre/drivers/staging/rt2870/rtmp_def.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rt2870/rtmp_def.h	1969-12-31 19:00:00.000000000 -0500
@@ -1 +0,0 @@
-#include "../rt2860/rtmp_def.h"
diff -druN linux-2.6.39-libre/drivers/staging/rt2870/rtmp.h linux-3.0-rc7-libre/drivers/staging/rt2870/rtmp.h
--- linux-2.6.39-libre/drivers/staging/rt2870/rtmp.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rt2870/rtmp.h	1969-12-31 19:00:00.000000000 -0500
@@ -1 +0,0 @@
-#include "../rt2860/rtmp.h"
diff -druN linux-2.6.39-libre/drivers/staging/rt2870/rtmp_type.h linux-3.0-rc7-libre/drivers/staging/rt2870/rtmp_type.h
--- linux-2.6.39-libre/drivers/staging/rt2870/rtmp_type.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rt2870/rtmp_type.h	1969-12-31 19:00:00.000000000 -0500
@@ -1 +0,0 @@
-#include "../rt2860/rtmp_type.h"
diff -druN linux-2.6.39-libre/drivers/staging/rt2870/rt_profile.c linux-3.0-rc7-libre/drivers/staging/rt2870/rt_profile.c
--- linux-2.6.39-libre/drivers/staging/rt2870/rt_profile.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rt2870/rt_profile.c	1969-12-31 19:00:00.000000000 -0500
@@ -1 +0,0 @@
-#include "../rt2860/rt_profile.c"
diff -druN linux-2.6.39-libre/drivers/staging/rt2870/rt_usb.c linux-3.0-rc7-libre/drivers/staging/rt2870/rt_usb.c
--- linux-2.6.39-libre/drivers/staging/rt2870/rt_usb.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rt2870/rt_usb.c	1969-12-31 19:00:00.000000000 -0500
@@ -1 +0,0 @@
-#include "../rt2860/rt_usb.c"
diff -druN linux-2.6.39-libre/drivers/staging/rt2870/spectrum_def.h linux-3.0-rc7-libre/drivers/staging/rt2870/spectrum_def.h
--- linux-2.6.39-libre/drivers/staging/rt2870/spectrum_def.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rt2870/spectrum_def.h	1969-12-31 19:00:00.000000000 -0500
@@ -1 +0,0 @@
-#include "../rt2860/spectrum_def.h"
diff -druN linux-2.6.39-libre/drivers/staging/rt2870/spectrum.h linux-3.0-rc7-libre/drivers/staging/rt2870/spectrum.h
--- linux-2.6.39-libre/drivers/staging/rt2870/spectrum.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rt2870/spectrum.h	1969-12-31 19:00:00.000000000 -0500
@@ -1 +0,0 @@
-#include "../rt2860/spectrum.h"
diff -druN linux-2.6.39-libre/drivers/staging/rt2870/sta/aironet.c linux-3.0-rc7-libre/drivers/staging/rt2870/sta/aironet.c
--- linux-2.6.39-libre/drivers/staging/rt2870/sta/aironet.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rt2870/sta/aironet.c	1969-12-31 19:00:00.000000000 -0500
@@ -1 +0,0 @@
-#include "../../rt2860/sta/aironet.c"
diff -druN linux-2.6.39-libre/drivers/staging/rt2870/sta/assoc.c linux-3.0-rc7-libre/drivers/staging/rt2870/sta/assoc.c
--- linux-2.6.39-libre/drivers/staging/rt2870/sta/assoc.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rt2870/sta/assoc.c	1969-12-31 19:00:00.000000000 -0500
@@ -1 +0,0 @@
-#include "../../rt2860/sta/assoc.c"
diff -druN linux-2.6.39-libre/drivers/staging/rt2870/sta/auth.c linux-3.0-rc7-libre/drivers/staging/rt2870/sta/auth.c
--- linux-2.6.39-libre/drivers/staging/rt2870/sta/auth.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rt2870/sta/auth.c	1969-12-31 19:00:00.000000000 -0500
@@ -1 +0,0 @@
-#include "../../rt2860/sta/auth.c"
diff -druN linux-2.6.39-libre/drivers/staging/rt2870/sta/auth_rsp.c linux-3.0-rc7-libre/drivers/staging/rt2870/sta/auth_rsp.c
--- linux-2.6.39-libre/drivers/staging/rt2870/sta/auth_rsp.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rt2870/sta/auth_rsp.c	1969-12-31 19:00:00.000000000 -0500
@@ -1 +0,0 @@
-#include "../../rt2860/sta/auth_rsp.c"
diff -druN linux-2.6.39-libre/drivers/staging/rt2870/sta/connect.c linux-3.0-rc7-libre/drivers/staging/rt2870/sta/connect.c
--- linux-2.6.39-libre/drivers/staging/rt2870/sta/connect.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rt2870/sta/connect.c	1969-12-31 19:00:00.000000000 -0500
@@ -1 +0,0 @@
-#include "../../rt2860/sta/connect.c"
diff -druN linux-2.6.39-libre/drivers/staging/rt2870/sta/rtmp_data.c linux-3.0-rc7-libre/drivers/staging/rt2870/sta/rtmp_data.c
--- linux-2.6.39-libre/drivers/staging/rt2870/sta/rtmp_data.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rt2870/sta/rtmp_data.c	1969-12-31 19:00:00.000000000 -0500
@@ -1 +0,0 @@
-#include "../../rt2860/sta/rtmp_data.c"
diff -druN linux-2.6.39-libre/drivers/staging/rt2870/sta/sanity.c linux-3.0-rc7-libre/drivers/staging/rt2870/sta/sanity.c
--- linux-2.6.39-libre/drivers/staging/rt2870/sta/sanity.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rt2870/sta/sanity.c	1969-12-31 19:00:00.000000000 -0500
@@ -1 +0,0 @@
-#include "../../rt2860/sta/sanity.c"
diff -druN linux-2.6.39-libre/drivers/staging/rt2870/sta/sync.c linux-3.0-rc7-libre/drivers/staging/rt2870/sta/sync.c
--- linux-2.6.39-libre/drivers/staging/rt2870/sta/sync.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rt2870/sta/sync.c	1969-12-31 19:00:00.000000000 -0500
@@ -1 +0,0 @@
-#include "../../rt2860/sta/sync.c"
diff -druN linux-2.6.39-libre/drivers/staging/rt2870/sta/wpa.c linux-3.0-rc7-libre/drivers/staging/rt2870/sta/wpa.c
--- linux-2.6.39-libre/drivers/staging/rt2870/sta/wpa.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rt2870/sta/wpa.c	1969-12-31 19:00:00.000000000 -0500
@@ -1 +0,0 @@
-#include "../../rt2860/sta/wpa.c"
diff -druN linux-2.6.39-libre/drivers/staging/rt2870/sta_ioctl.c linux-3.0-rc7-libre/drivers/staging/rt2870/sta_ioctl.c
--- linux-2.6.39-libre/drivers/staging/rt2870/sta_ioctl.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rt2870/sta_ioctl.c	1969-12-31 19:00:00.000000000 -0500
@@ -1 +0,0 @@
-#include "../rt2860/sta_ioctl.c"
diff -druN linux-2.6.39-libre/drivers/staging/rt2870/TODO linux-3.0-rc7-libre/drivers/staging/rt2870/TODO
--- linux-2.6.39-libre/drivers/staging/rt2870/TODO	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rt2870/TODO	1969-12-31 19:00:00.000000000 -0500
@@ -1,17 +0,0 @@
-I'm hesitant to add a TODO file here, as the wireless developers would
-really have people help them out on the "clean" rt2870 driver that can
-be found at the http://rt2x00.serialmonkey.com/ site.
-
-But, if you wish to clean up this driver instead, here's a short list of
-things that need to be done to get it into a more mergable shape:
-
-TODO:
-	- checkpatch.pl clean
-	- sparse clean
-	- port to in-kernel 80211 stack and common rt2x00 infrastructure
-	- remove reading from /etc/ config files
-	- review by the wireless developer community
-
-Please send any patches or complaints about this driver to Greg
-Kroah-Hartman <greg@kroah.com> and don't bother the upstream wireless
-kernel developers about it, they want nothing to do with it.
diff -druN linux-2.6.39-libre/drivers/staging/rt2870/usb_main_dev.c linux-3.0-rc7-libre/drivers/staging/rt2870/usb_main_dev.c
--- linux-2.6.39-libre/drivers/staging/rt2870/usb_main_dev.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rt2870/usb_main_dev.c	1969-12-31 19:00:00.000000000 -0500
@@ -1 +0,0 @@
-#include "../rt2860/usb_main_dev.c"
diff -druN linux-2.6.39-libre/drivers/staging/rt2870/wpa.h linux-3.0-rc7-libre/drivers/staging/rt2870/wpa.h
--- linux-2.6.39-libre/drivers/staging/rt2870/wpa.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rt2870/wpa.h	1969-12-31 19:00:00.000000000 -0500
@@ -1 +0,0 @@
-#include "../rt2860/wpa.h"
diff -druN linux-2.6.39-libre/drivers/staging/rtl8712/ieee80211.h linux-3.0-rc7-libre/drivers/staging/rtl8712/ieee80211.h
--- linux-2.6.39-libre/drivers/staging/rtl8712/ieee80211.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rtl8712/ieee80211.h	2011-07-11 19:51:52.000000000 -0400
@@ -76,7 +76,7 @@
 			u8 reserved[32];
 			u8 data[0];
 		} wpa_ie;
-		struct{
+		struct {
 			int command;
 			int reason_code;
 		} mlme;
@@ -149,11 +149,11 @@
 struct  ieee80211_hdr_3addr_qos {
 	u16 frame_ctl;
 	u16 duration_id;
-	u8 addr1[ETH_ALEN];
-	u8 addr2[ETH_ALEN];
-	u8 addr3[ETH_ALEN];
+	u8  addr1[ETH_ALEN];
+	u8  addr2[ETH_ALEN];
+	u8  addr3[ETH_ALEN];
 	u16 seq_ctl;
-       u16     qc;
+	u16 qc;
 }  __attribute__ ((packed));
 
 struct eapol {
@@ -461,7 +461,7 @@
 	uint rx_message_in_bad_msg_fragments;
 };
 
-struct ieee80211_softmac_stats{
+struct ieee80211_softmac_stats {
 	uint rx_ass_ok;
 	uint rx_ass_err;
 	uint rx_probe_rq;
@@ -754,15 +754,17 @@
 u8 *r8712_set_ie(u8 *pbuf, sint index, uint len, u8 *source, uint *frlen);
 u8 *r8712_get_ie(u8*pbuf, sint index, sint *len, sint limit);
 unsigned char *r8712_get_wpa_ie(unsigned char *pie, int *rsn_ie_len, int limit);
-unsigned char *r8712_get_wpa2_ie(unsigned char *pie, int *rsn_ie_len, int limit);
+unsigned char *r8712_get_wpa2_ie(unsigned char *pie, int *rsn_ie_len,
+				 int limit);
 int r8712_parse_wpa_ie(u8 *wpa_ie, int wpa_ie_len, int *group_cipher,
-		       int *pairwise_cipher);
+			int *pairwise_cipher);
 int r8712_parse_wpa2_ie(u8 *wpa_ie, int wpa_ie_len, int *group_cipher,
-		        int *pairwise_cipher);
-int r8712_get_sec_ie(u8 *in_ie, uint in_len, u8 *rsn_ie, u16 *rsn_len, u8 *wpa_ie,
-	       u16 *wpa_len);
+			int *pairwise_cipher);
+int r8712_get_sec_ie(u8 *in_ie, uint in_len, u8 *rsn_ie, u16 *rsn_len,
+		     u8 *wpa_ie, u16 *wpa_len);
 int r8712_get_wps_ie(u8 *in_ie, uint in_len, u8 *wps_ie, uint *wps_ielen);
-int r8712_generate_ie(struct registry_priv *pregistrypriv, struct _adapter *padapter);
+int r8712_generate_ie(struct registry_priv *pregistrypriv,
+		      struct _adapter *padapter);
 uint r8712_is_cckrates_included(u8 *rate);
 uint r8712_is_cckratesonly_included(u8 *rate);
 
diff -druN linux-2.6.39-libre/drivers/staging/rtl8712/if_ether.h linux-3.0-rc7-libre/drivers/staging/rtl8712/if_ether.h
--- linux-2.6.39-libre/drivers/staging/rtl8712/if_ether.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rtl8712/if_ether.h	2011-07-11 19:51:52.000000000 -0400
@@ -99,8 +99,8 @@
 };
 
 struct _vlan {
-   unsigned short       h_vlan_TCI;	/* Encapsulates priority and VLAN ID*/
-   unsigned short       h_vlan_encapsulated_proto;
+	unsigned short  h_vlan_TCI;	/* Encapsulates priority and VLAN ID*/
+	unsigned short  h_vlan_encapsulated_proto;
 };
 
 
diff -druN linux-2.6.39-libre/drivers/staging/rtl8712/ip.h linux-3.0-rc7-libre/drivers/staging/rtl8712/ip.h
--- linux-2.6.39-libre/drivers/staging/rtl8712/ip.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rtl8712/ip.h	2011-07-11 19:51:52.000000000 -0400
@@ -90,23 +90,23 @@
 #define	IPOPT_TS_PRESPEC	3		/* specified modules only */
 
 struct ip_options {
-  __u32		faddr;				/* Saved first hop address */
-  unsigned char	optlen;
-  unsigned char srr;
-  unsigned char rr;
-  unsigned char ts;
-  unsigned char is_setbyuser:1,	/* Set by setsockopt?			*/
-		is_data:1,	/* Options in __data, rather than skb	*/
-		is_strictroute:1, /* Strict source route		*/
-		srr_is_hit:1,	/* Packet destination addr was our one	*/
-		is_changed:1,	/* IP checksum more not valid		*/
-		rr_needaddr:1,	/* Need to record addr of outgoing dev	*/
-		ts_needtime:1,	/* Need to record timestamp		*/
-		ts_needaddr:1;	/* Need to record addr of outgoing dev  */
-  unsigned char router_alert;
-  unsigned char __pad1;
-  unsigned char __pad2;
-  unsigned char __data[0];
+	__u32		faddr;			/* Saved first hop address */
+	unsigned char	optlen;
+	unsigned char srr;
+	unsigned char rr;
+	unsigned char ts;
+	unsigned char is_setbyuser:1,	/* Set by setsockopt?		      */
+		      is_data:1,	/* Options in __data, rather than skb */
+		      is_strictroute:1, /* Strict source route		      */
+		      srr_is_hit:1,	/* Packet destination addr was our one*/
+		      is_changed:1,	/* IP checksum more not valid	      */
+		      rr_needaddr:1,	/* Need to record addr of outgoing dev*/
+		      ts_needtime:1,	/* Need to record timestamp	      */
+		      ts_needaddr:1;	/* Need to record addr of outgoing dev*/
+	unsigned char router_alert;
+	unsigned char __pad1;
+	unsigned char __pad2;
+	unsigned char __data[0];
 };
 
 #define optlength(opt) (sizeof(struct ip_options) + opt->optlen)
diff -druN linux-2.6.39-libre/drivers/staging/rtl8712/mlme_osdep.h linux-3.0-rc7-libre/drivers/staging/rtl8712/mlme_osdep.h
--- linux-2.6.39-libre/drivers/staging/rtl8712/mlme_osdep.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rtl8712/mlme_osdep.h	2011-07-11 19:51:52.000000000 -0400
@@ -9,8 +9,8 @@
 void r8712_os_indicate_connect(struct _adapter *adapter);
 void r8712_report_sec_ie(struct _adapter *adapter, u8 authmode, u8 *sec_ie);
 int r8712_recv_indicatepkts_in_order(struct _adapter *adapter,
-				     struct recv_reorder_ctrl *precvreorder_ctrl,
-				     int bforced);
+				struct recv_reorder_ctrl *precvreorder_ctrl,
+				int bforced);
 void r8712_indicate_wx_assoc_event(struct _adapter *padapter);
 void r8712_indicate_wx_disassoc_event(struct _adapter *padapter);
 
diff -druN linux-2.6.39-libre/drivers/staging/rtl8712/osdep_service.h linux-3.0-rc7-libre/drivers/staging/rtl8712/osdep_service.h
--- linux-2.6.39-libre/drivers/staging/rtl8712/osdep_service.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rtl8712/osdep_service.h	2011-07-11 19:51:52.000000000 -0400
@@ -145,7 +145,8 @@
 		return false;
 }
 
-static inline void list_insert_tail(struct list_head *plist, struct list_head *phead)
+static inline void list_insert_tail(struct list_head *plist,
+				    struct list_head *phead)
 {
 	list_add_tail(plist, phead);
 }
diff -druN linux-2.6.39-libre/drivers/staging/rtl8712/recv_osdep.h linux-3.0-rc7-libre/drivers/staging/rtl8712/recv_osdep.h
--- linux-2.6.39-libre/drivers/staging/rtl8712/recv_osdep.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rtl8712/recv_osdep.h	2011-07-11 19:51:52.000000000 -0400
@@ -12,7 +12,8 @@
 void r8712_recv_indicatepkt(struct _adapter *adapter,
 			    union recv_frame *precv_frame);
 void r8712_handle_tkip_mic_err(struct _adapter *padapter, u8 bgroup);
-int r8712_init_recv_priv(struct recv_priv *precvpriv, struct _adapter *padapter);
+int r8712_init_recv_priv(struct recv_priv *precvpriv,
+			 struct _adapter *padapter);
 void r8712_free_recv_priv(struct recv_priv *precvpriv);
 int r8712_os_recv_resource_alloc(struct _adapter *padapter,
 				 union recv_frame *precvframe);
@@ -24,4 +25,3 @@
 void r8712_init_recv_timer(struct recv_reorder_ctrl *preorder_ctrl);
 
 #endif
-
diff -druN linux-2.6.39-libre/drivers/staging/rtl8712/rtl8712_event.h linux-3.0-rc7-libre/drivers/staging/rtl8712/rtl8712_event.h
--- linux-2.6.39-libre/drivers/staging/rtl8712/rtl8712_event.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rtl8712/rtl8712_event.h	2011-07-11 19:51:52.000000000 -0400
@@ -5,33 +5,33 @@
 void r8712_got_addbareq_event_callback(struct _adapter *adapter , u8 *pbuf);
 
 enum rtl8712_c2h_event {
-	GEN_EVT_CODE(_Read_MACREG) = 0, /*0*/
+	GEN_EVT_CODE(_Read_MACREG) = 0,		/*0*/
 	GEN_EVT_CODE(_Read_BBREG),
 	GEN_EVT_CODE(_Read_RFREG),
 	GEN_EVT_CODE(_Read_EEPROM),
 	GEN_EVT_CODE(_Read_EFUSE),
-	GEN_EVT_CODE(_Read_CAM),			/*5*/
+	GEN_EVT_CODE(_Read_CAM),		/*5*/
 	GEN_EVT_CODE(_Get_BasicRate),
 	GEN_EVT_CODE(_Get_DataRate),
-	GEN_EVT_CODE(_Survey),	 /*8*/
-	GEN_EVT_CODE(_SurveyDone),	 /*9*/
+	GEN_EVT_CODE(_Survey),			/*8*/
+	GEN_EVT_CODE(_SurveyDone),		/*9*/
 
-	GEN_EVT_CODE(_JoinBss) , /*10*/
+	GEN_EVT_CODE(_JoinBss),			/*10*/
 	GEN_EVT_CODE(_AddSTA),
 	GEN_EVT_CODE(_DelSTA),
-	GEN_EVT_CODE(_AtimDone) ,
+	GEN_EVT_CODE(_AtimDone),
 	GEN_EVT_CODE(_TX_Report),
-	GEN_EVT_CODE(_CCX_Report),			/*15*/
+	GEN_EVT_CODE(_CCX_Report),		/*15*/
 	GEN_EVT_CODE(_DTM_Report),
 	GEN_EVT_CODE(_TX_Rate_Statistics),
 	GEN_EVT_CODE(_C2HLBK),
 	GEN_EVT_CODE(_FWDBG),
-	GEN_EVT_CODE(_C2HFEEDBACK),               /*20*/
+	GEN_EVT_CODE(_C2HFEEDBACK),		/*20*/
 	GEN_EVT_CODE(_ADDBA),
 	GEN_EVT_CODE(_C2HBCN),
 	GEN_EVT_CODE(_ReportPwrState),		/*filen: only for PCIE, USB*/
 	GEN_EVT_CODE(_WPS_PBC),			/*24*/
-	GEN_EVT_CODE(_ADDBAReq_Report),	/*25*/
+	GEN_EVT_CODE(_ADDBAReq_Report),		/*25*/
 	MAX_C2HEVT
 };
 
@@ -48,7 +48,8 @@
 	{0, NULL},
 	{0, NULL},
 	{0, &r8712_survey_event_callback},		/*8*/
-	{sizeof(struct surveydone_event), &r8712_surveydone_event_callback},/*9*/
+	{sizeof(struct surveydone_event),
+		&r8712_surveydone_event_callback},	/*9*/
 
 	{0, &r8712_joinbss_event_callback},		/*10*/
 	{sizeof(struct stassoc_event), &r8712_stassoc_event_callback},
@@ -59,8 +60,8 @@
 	{0, NULL},
 	{0, NULL},
 	{0, NULL},
-	{0, NULL}, /*fwdbg_event_callback},*/
-	{0, NULL},	 /*20*/
+	{0, NULL},	/*fwdbg_event_callback},*/
+	{0, NULL},	/*20*/
 	{0, NULL},
 	{0, NULL},
 	{0, &r8712_cpwm_event_callback},
diff -druN linux-2.6.39-libre/drivers/staging/rtl8712/rtl8712_hal.h linux-3.0-rc7-libre/drivers/staging/rtl8712/rtl8712_hal.h
--- linux-2.6.39-libre/drivers/staging/rtl8712/rtl8712_hal.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rtl8712/rtl8712_hal.h	2011-07-11 19:51:52.000000000 -0400
@@ -21,13 +21,13 @@
 	RTL8712_USB,
 };
 
-enum RTL8712_RF_CONFIG{
+enum RTL8712_RF_CONFIG {
 	RTL8712_RF_1T1R,
 	RTL8712_RF_1T2R,
 	RTL8712_RF_2T2R
 };
 
-enum _RTL8712_HCI_TYPE_{
+enum _RTL8712_HCI_TYPE_ {
 	RTL8712_HCI_TYPE_PCIE = 0x01,
 	RTL8712_HCI_TYPE_AP_PCIE = 0x81,
 	RTL8712_HCI_TYPE_USB = 0x02,
@@ -40,62 +40,62 @@
 
 struct fw_priv {   /*8-bytes alignment required*/
 	/*--- long word 0 ----*/
- unsigned char  signature_0;  /*0x12: CE product, 0x92: IT product*/
- unsigned char  signature_1;  /*0x87: CE product, 0x81: IT product*/
- unsigned char  hci_sel;   /*0x81: PCI-AP, 01:PCIe, 02: 92S-U, 0x82: USB-AP,
+	unsigned char signature_0;  /*0x12: CE product, 0x92: IT product*/
+	unsigned char signature_1;  /*0x87: CE product, 0x81: IT product*/
+	unsigned char hci_sel; /*0x81: PCI-AP, 01:PCIe, 02: 92S-U, 0x82: USB-AP,
 			    * 0x12: 72S-U, 03:SDIO*/
- unsigned char  chip_version; /*the same value as register value*/
- unsigned char  customer_ID_0; /*customer  ID low byte*/
- unsigned char  customer_ID_1; /*customer  ID high byte*/
- unsigned char  rf_config;  /*0x11:  1T1R, 0x12: 1T2R, 0x92: 1T2R turbo,
+	unsigned char chip_version; /*the same value as register value*/
+	unsigned char customer_ID_0; /*customer  ID low byte*/
+	unsigned char customer_ID_1; /*customer  ID high byte*/
+	unsigned char rf_config;  /*0x11:  1T1R, 0x12: 1T2R, 0x92: 1T2R turbo,
 			     * 0x22: 2T2R*/
- unsigned char  usb_ep_num;  /* 4: 4EP, 6: 6EP, 11: 11EP*/
+	unsigned char usb_ep_num;  /* 4: 4EP, 6: 6EP, 11: 11EP*/
 	/*--- long word 1 ----*/
- unsigned char  regulatory_class_0; /*regulatory class bit map 0*/
- unsigned char  regulatory_class_1; /*regulatory class bit map 1*/
- unsigned char  regulatory_class_2; /*regulatory class bit map 2*/
- unsigned char  regulatory_class_3; /*regulatory class bit map 3*/
- unsigned char  rfintfs;    /* 0:SWSI, 1:HWSI, 2:HWPI*/
- unsigned char  def_nettype;
- unsigned char  turboMode;
- unsigned char  lowPowerMode;/* 0: noral mode, 1: low power mode*/
+	unsigned char regulatory_class_0; /*regulatory class bit map 0*/
+	unsigned char regulatory_class_1; /*regulatory class bit map 1*/
+	unsigned char regulatory_class_2; /*regulatory class bit map 2*/
+	unsigned char regulatory_class_3; /*regulatory class bit map 3*/
+	unsigned char rfintfs;    /* 0:SWSI, 1:HWSI, 2:HWPI*/
+	unsigned char def_nettype;
+	unsigned char turboMode;
+	unsigned char lowPowerMode;/* 0: noral mode, 1: low power mode*/
 	/*--- long word 2 ----*/
- unsigned char  lbk_mode; /*0x00: normal, 0x03: MACLBK, 0x01: PHYLBK*/
- unsigned char  mp_mode; /* 1: for MP use, 0: for normal driver */
- unsigned char  vcsType; /* 0:off 1:on 2:auto */
- unsigned char  vcsMode; /* 1:RTS/CTS 2:CTS to self */
- unsigned char  rsvd022;
- unsigned char  rsvd023;
- unsigned char  rsvd024;
- unsigned char  rsvd025;
+	unsigned char lbk_mode; /*0x00: normal, 0x03: MACLBK, 0x01: PHYLBK*/
+	unsigned char mp_mode; /* 1: for MP use, 0: for normal driver */
+	unsigned char vcsType; /* 0:off 1:on 2:auto */
+	unsigned char vcsMode; /* 1:RTS/CTS 2:CTS to self */
+	unsigned char rsvd022;
+	unsigned char rsvd023;
+	unsigned char rsvd024;
+	unsigned char rsvd025;
 	/*--- long word 3 ----*/
- unsigned char  qos_en;    /*1: QoS enable*/
- unsigned char  bw_40MHz_en;   /*1: 40MHz BW enable*/
- unsigned char  AMSDU2AMPDU_en;   /*1: 4181 convert AMSDU to AMPDU,
+	unsigned char qos_en;    /*1: QoS enable*/
+	unsigned char bw_40MHz_en;   /*1: 40MHz BW enable*/
+	unsigned char AMSDU2AMPDU_en;   /*1: 4181 convert AMSDU to AMPDU,
 				   * 0: disable*/
- unsigned char  AMPDU_en;   /*1: 11n AMPDU enable*/
- unsigned char  rate_control_offload;  /*1: FW offloads, 0: driver handles*/
- unsigned char  aggregation_offload;  /*1: FW offloads, 0: driver handles*/
- unsigned char  rsvd030;
- unsigned char  rsvd031;
+	unsigned char AMPDU_en;   /*1: 11n AMPDU enable*/
+	unsigned char rate_control_offload; /*1: FW offloads,0: driver handles*/
+	unsigned char aggregation_offload;  /*1: FW offloads,0: driver handles*/
+	unsigned char rsvd030;
+	unsigned char rsvd031;
 	/*--- long word 4 ----*/
- unsigned char  beacon_offload;   /* 1. FW offloads, 0: driver handles*/
- unsigned char  MLME_offload;   /* 2. FW offloads, 0: driver handles*/
- unsigned char  hwpc_offload;   /* 3. FW offloads, 0: driver handles*/
- unsigned char  tcp_checksum_offload; /* 4. FW offloads, 0: driver handles*/
- unsigned char  tcp_offload;    /* 5. FW offloads, 0: driver handles*/
- unsigned char  ps_control_offload;  /* 6. FW offloads, 0: driver handles*/
- unsigned char  WWLAN_offload;   /* 7. FW offloads, 0: driver handles*/
- unsigned char  rsvd040;
+	unsigned char beacon_offload;   /* 1. FW offloads, 0: driver handles*/
+	unsigned char MLME_offload;   /* 2. FW offloads, 0: driver handles*/
+	unsigned char hwpc_offload;   /* 3. FW offloads, 0: driver handles*/
+	unsigned char tcp_checksum_offload; /*4. FW offloads,0: driver handles*/
+	unsigned char tcp_offload;    /* 5. FW offloads, 0: driver handles*/
+	unsigned char ps_control_offload; /* 6. FW offloads, 0: driver handles*/
+	unsigned char WWLAN_offload;   /* 7. FW offloads, 0: driver handles*/
+	unsigned char rsvd040;
 	/*--- long word 5 ----*/
- unsigned char  tcp_tx_frame_len_L;  /*tcp tx packet length low byte*/
- unsigned char  tcp_tx_frame_len_H;  /*tcp tx packet length high byte*/
- unsigned char  tcp_rx_frame_len_L;  /*tcp rx packet length low byte*/
- unsigned char  tcp_rx_frame_len_H;  /*tcp rx packet length high byte*/
- unsigned char  rsvd050;
- unsigned char  rsvd051;
- unsigned char  rsvd052;
- unsigned char  rsvd053;
+	unsigned char tcp_tx_frame_len_L;  /*tcp tx packet length low byte*/
+	unsigned char tcp_tx_frame_len_H;  /*tcp tx packet length high byte*/
+	unsigned char tcp_rx_frame_len_L;  /*tcp rx packet length low byte*/
+	unsigned char tcp_rx_frame_len_H;  /*tcp rx packet length high byte*/
+	unsigned char rsvd050;
+	unsigned char rsvd051;
+	unsigned char rsvd052;
+	unsigned char rsvd053;
 };
 
 struct fw_hdr {/*8-byte alinment required*/
diff -druN linux-2.6.39-libre/drivers/staging/rtl8712/rtl8712_led.c linux-3.0-rc7-libre/drivers/staging/rtl8712/rtl8712_led.c
--- linux-2.6.39-libre/drivers/staging/rtl8712/rtl8712_led.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rtl8712/rtl8712_led.c	2011-07-11 19:51:52.000000000 -0400
@@ -49,7 +49,7 @@
  * LED object.
  *===========================================================================
  */
-enum _LED_STATE_871x{
+enum _LED_STATE_871x {
 	LED_UNKNOWN = 0,
 	LED_ON = 1,
 	LED_OFF = 2,
diff -druN linux-2.6.39-libre/drivers/staging/rtl8712/rtl8712_recv.c linux-3.0-rc7-libre/drivers/staging/rtl8712/rtl8712_recv.c
--- linux-2.6.39-libre/drivers/staging/rtl8712/rtl8712_recv.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rtl8712/rtl8712_recv.c	2011-07-11 19:51:52.000000000 -0400
@@ -251,7 +251,7 @@
 		recvframe_put(prframe, pnfhdr->len);
 		pfhdr->attrib.icv_len = pnfhdr->attrib.icv_len;
 		plist = get_next(plist);
-	};
+	}
 exit:
 	/* free the defrag_q queue and return the prframe */
 	r8712_free_recvframe_queue(defrag_q, pfree_recv_queue);
diff -druN linux-2.6.39-libre/drivers/staging/rtl8712/rtl8712_recv.h linux-3.0-rc7-libre/drivers/staging/rtl8712/rtl8712_recv.h
--- linux-2.6.39-libre/drivers/staging/rtl8712/rtl8712_recv.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rtl8712/rtl8712_recv.h	2011-07-11 19:51:52.000000000 -0400
@@ -93,7 +93,7 @@
 	end   ----->
 	len = (unsigned int )(tail - data);
 */
-struct recv_frame_hdr{
+struct recv_frame_hdr {
 	struct list_head list;
 	_pkt	*pkt;
 	_pkt *pkt_newalloc;
diff -druN linux-2.6.39-libre/drivers/staging/rtl8712/rtl8712_xmit.h linux-3.0-rc7-libre/drivers/staging/rtl8712/rtl8712_xmit.h
--- linux-2.6.39-libre/drivers/staging/rtl8712/rtl8712_xmit.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rtl8712/rtl8712_xmit.h	2011-07-11 19:51:52.000000000 -0400
@@ -59,25 +59,16 @@
 /*OFFSET 20*/
 #define DISFB BIT(15)
 
-struct tx_desc{
-
+struct tx_desc {
 	/*DWORD 0*/
 	unsigned int txdw0;
-
 	unsigned int txdw1;
-
 	unsigned int txdw2;
-
 	unsigned int txdw3;
-
 	unsigned int txdw4;
-
 	unsigned int txdw5;
-
 	unsigned int txdw6;
-
 	unsigned int txdw7;
-
 };
 
 
diff -druN linux-2.6.39-libre/drivers/staging/rtl8712/rtl871x_cmd.c linux-3.0-rc7-libre/drivers/staging/rtl8712/rtl871x_cmd.c
--- linux-2.6.39-libre/drivers/staging/rtl8712/rtl871x_cmd.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rtl8712/rtl871x_cmd.c	2011-07-11 19:51:52.000000000 -0400
@@ -431,8 +431,7 @@
 	}
 	psecnetwork = (struct ndis_wlan_bssid_ex *)&psecuritypriv->sec_bss;
 	if (psecnetwork == NULL) {
-		if (pcmd != NULL)
-			kfree((unsigned char *)pcmd);
+		kfree(pcmd);
 		return _FAIL;
 	}
 	memset(psecnetwork, 0, t_len);
@@ -478,8 +477,8 @@
 		 * to avoid some IOT issues, especially for Realtek 8192u
 		 * SoftAP.
 		 */
-		if ((padapter->securitypriv.PrivacyAlgrthm != _WEP40_ ) &&
-		    (padapter->securitypriv.PrivacyAlgrthm != _WEP104_ )) {
+		if ((padapter->securitypriv.PrivacyAlgrthm != _WEP40_) &&
+		    (padapter->securitypriv.PrivacyAlgrthm != _WEP104_)) {
 			/* restructure_ht_ie */
 			r8712_restructure_ht_ie(padapter,
 						&pnetwork->network.IEs[0],
diff -druN linux-2.6.39-libre/drivers/staging/rtl8712/rtl871x_cmd.h linux-3.0-rc7-libre/drivers/staging/rtl8712/rtl871x_cmd.h
--- linux-2.6.39-libre/drivers/staging/rtl8712/rtl871x_cmd.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rtl8712/rtl871x_cmd.h	2011-07-11 19:51:52.000000000 -0400
@@ -562,54 +562,54 @@
 };
 
 /*to get TX,RX retry count*/
-struct gettxretrycnt_parm{
+struct gettxretrycnt_parm {
 	unsigned int rsvd;
 };
 
-struct gettxretrycnt_rsp{
+struct gettxretrycnt_rsp {
 	unsigned long tx_retrycnt;
 };
 
-struct getrxretrycnt_parm{
+struct getrxretrycnt_parm {
 	unsigned int rsvd;
 };
 
-struct getrxretrycnt_rsp{
+struct getrxretrycnt_rsp {
 	unsigned long rx_retrycnt;
 };
 
 /*to get BCNOK,BCNERR count*/
-struct getbcnokcnt_parm{
+struct getbcnokcnt_parm {
 	unsigned int rsvd;
 };
 
-struct getbcnokcnt_rsp{
-	unsigned long  bcnokcnt;
+struct getbcnokcnt_rsp {
+	unsigned long bcnokcnt;
 };
 
-struct getbcnerrcnt_parm{
+struct getbcnerrcnt_parm {
 	unsigned int rsvd;
 };
-struct getbcnerrcnt_rsp{
+struct getbcnerrcnt_rsp {
 	unsigned long bcnerrcnt;
 };
 
 /* to get current TX power level*/
-struct getcurtxpwrlevel_parm{
+struct getcurtxpwrlevel_parm {
 	unsigned int rsvd;
 };
 
-struct getcurtxpwrlevel_rsp{
+struct getcurtxpwrlevel_rsp {
 	unsigned short tx_power;
 };
 
 /*dynamic on/off DIG*/
-struct setdig_parm{
+struct setdig_parm {
 	unsigned char dig_on;	/* 1:on , 0:off */
 };
 
 /*dynamic on/off RA*/
-struct setra_parm{
+struct setra_parm {
 	unsigned char ra_on;	/* 1:on , 0:off */
 };
 
diff -druN linux-2.6.39-libre/drivers/staging/rtl8712/rtl871x_event.h linux-3.0-rc7-libre/drivers/staging/rtl8712/rtl871x_event.h
--- linux-2.6.39-libre/drivers/staging/rtl8712/rtl871x_event.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rtl8712/rtl871x_event.h	2011-07-11 19:51:52.000000000 -0400
@@ -45,8 +45,8 @@
 };
 
 struct stadel_event {
- unsigned char macaddr[6];
- unsigned char rsvd[2];
+	unsigned char macaddr[6];
+	unsigned char rsvd[2];
 };
 
 struct addba_event {
@@ -61,7 +61,7 @@
 };
 
 #define C2HEVENT_SZ			32
-struct event_node{
+struct event_node {
 	unsigned char *node;
 	unsigned char evt_code;
 	unsigned short evt_sz;
@@ -85,9 +85,9 @@
 };
 
 struct ADDBA_Req_Report_parm {
- unsigned char MacAddress[ETH_ALEN];
- unsigned short StartSeqNum;
- unsigned char tid;
+	unsigned char MacAddress[ETH_ALEN];
+	unsigned short StartSeqNum;
+	unsigned char tid;
 };
 #include "rtl8712_event.h"
 
diff -druN linux-2.6.39-libre/drivers/staging/rtl8712/rtl871x_io.c linux-3.0-rc7-libre/drivers/staging/rtl8712/rtl871x_io.c
--- linux-2.6.39-libre/drivers/staging/rtl8712/rtl871x_io.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rtl8712/rtl871x_io.c	2011-07-11 19:51:52.000000000 -0400
@@ -73,8 +73,7 @@
 		goto _init_intf_hdl_fail;
 	return _SUCCESS;
 _init_intf_hdl_fail:
-	if (pintf_priv)
-		kfree((u8 *)pintf_priv);
+	kfree(pintf_priv);
 	return _FAIL;
 }
 
@@ -84,8 +83,7 @@
 
 	unload_intf_priv = &r8712_usb_unload_intf_priv;
 	unload_intf_priv(pintfpriv);
-	if (pintfpriv)
-		kfree((u8 *)pintfpriv);
+	kfree(pintfpriv);
 }
 
 static uint register_intf_hdl(u8 *dev, struct intf_hdl *pintfhdl)
diff -druN linux-2.6.39-libre/drivers/staging/rtl8712/rtl871x_ioctl_linux.c linux-3.0-rc7-libre/drivers/staging/rtl8712/rtl871x_ioctl_linux.c
--- linux-2.6.39-libre/drivers/staging/rtl8712/rtl871x_ioctl_linux.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rtl8712/rtl871x_ioctl_linux.c	2011-07-11 19:51:52.000000000 -0400
@@ -291,7 +291,8 @@
 			memset(buf, 0, MAX_WPA_IE_LEN);
 			n = sprintf(buf, "wpa_ie=");
 			for (i = 0; i < wpa_len; i++) {
-				n += snprintf(buf + n, MAX_WPA_IE_LEN - n, "%02x", wpa_ie[i]);
+				n += snprintf(buf + n, MAX_WPA_IE_LEN - n,
+							"%02x", wpa_ie[i]);
 				if (n >= MAX_WPA_IE_LEN)
 					break;
 			}
@@ -310,7 +311,8 @@
 			memset(buf, 0, MAX_WPA_IE_LEN);
 			n = sprintf(buf, "rsn_ie=");
 			for (i = 0; i < rsn_len; i++) {
-				n += snprintf(buf + n, MAX_WPA_IE_LEN - n, "%02x", rsn_ie[i]);
+				n += snprintf(buf + n, MAX_WPA_IE_LEN - n,
+							"%02x", rsn_ie[i]);
 				if (n >= MAX_WPA_IE_LEN)
 					break;
 			}
@@ -1732,8 +1734,7 @@
 		memcpy(param + 1, pext + 1, pext->key_len);
 	}
 	ret = wpa_set_encryption(dev, param, param_len);
-	if (param)
-		kfree((u8 *)param);
+	kfree(param);
 	return ret;
 }
 
diff -druN linux-2.6.39-libre/drivers/staging/rtl8712/rtl871x_ioctl_rtl.c linux-3.0-rc7-libre/drivers/staging/rtl8712/rtl871x_ioctl_rtl.c
--- linux-2.6.39-libre/drivers/staging/rtl8712/rtl871x_ioctl_rtl.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rtl8712/rtl871x_ioctl_rtl.c	2011-07-11 19:51:52.000000000 -0400
@@ -493,7 +493,7 @@
 	return status;
 }
 
-enum _CONNECT_STATE_{
+enum _CONNECT_STATE_ {
 	CHECKINGSTATUS,
 	ASSOCIATED,
 	ADHOCMODE,
diff -druN linux-2.6.39-libre/drivers/staging/rtl8712/rtl871x_ioctl_set.c linux-3.0-rc7-libre/drivers/staging/rtl8712/rtl871x_ioctl_set.c
--- linux-2.6.39-libre/drivers/staging/rtl8712/rtl871x_ioctl_set.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rtl8712/rtl871x_ioctl_set.c	2011-07-11 19:51:52.000000000 -0400
@@ -68,7 +68,10 @@
 	pmlmepriv->fw_state |= _FW_UNDER_LINKING;
 	pmlmepriv->pscanned = plist;
 	pmlmepriv->to_join = true;
-	if (_queue_empty(queue) == true) {
+
+	/* adhoc mode will start with an empty queue, but skip checking */
+	if (!check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) &&
+	    _queue_empty(queue)) {
 		if (pmlmepriv->fw_state & _FW_UNDER_LINKING)
 			pmlmepriv->fw_state ^= _FW_UNDER_LINKING;
 		/* when set_ssid/set_bssid for do_join(), but scanning queue
diff -druN linux-2.6.39-libre/drivers/staging/rtl8712/rtl871x_ioctl_set.h linux-3.0-rc7-libre/drivers/staging/rtl8712/rtl871x_ioctl_set.h
--- linux-2.6.39-libre/drivers/staging/rtl8712/rtl871x_ioctl_set.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rtl8712/rtl871x_ioctl_set.h	2011-07-11 19:51:52.000000000 -0400
@@ -6,19 +6,27 @@
 typedef u8 NDIS_802_11_PMKID_VALUE[16];
 
 struct BSSIDInfo {
-	unsigned char  BSSID[6];
-	NDIS_802_11_PMKID_VALUE  PMKID;
+	unsigned char BSSID[6];
+	NDIS_802_11_PMKID_VALUE PMKID;
 };
 
 u8 r8712_set_802_11_authentication_mode(struct _adapter *pdapter,
 			enum NDIS_802_11_AUTHENTICATION_MODE authmode);
+
 u8 r8712_set_802_11_bssid(struct _adapter *padapter, u8 *bssid);
-u8 r8712_set_802_11_add_wep(struct _adapter *padapter, struct NDIS_802_11_WEP *wep);
+
+u8 r8712_set_802_11_add_wep(struct _adapter *padapter,
+			    struct NDIS_802_11_WEP *wep);
+
 u8 r8712_set_802_11_disassociate(struct _adapter *padapter);
+
 u8 r8712_set_802_11_bssid_list_scan(struct _adapter *padapter);
+
 u8 r8712_set_802_11_infrastructure_mode(struct _adapter *padapter,
 			enum NDIS_802_11_NETWORK_INFRASTRUCTURE networktype);
-void r8712_set_802_11_ssid(struct _adapter *padapter, struct ndis_802_11_ssid *ssid);
+
+void r8712_set_802_11_ssid(struct _adapter *padapter,
+			   struct ndis_802_11_ssid *ssid);
 
 #endif
 
diff -druN linux-2.6.39-libre/drivers/staging/rtl8712/rtl871x_mp.c linux-3.0-rc7-libre/drivers/staging/rtl8712/rtl871x_mp.c
--- linux-2.6.39-libre/drivers/staging/rtl8712/rtl871x_mp.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rtl8712/rtl871x_mp.c	2011-07-11 19:51:52.000000000 -0400
@@ -217,7 +217,10 @@
 	return new_value;
 }
 
-static u8 set_bb_reg(struct _adapter *pAdapter, u16 offset, u32 bitmask, u32 value)
+static u8 set_bb_reg(struct _adapter *pAdapter,
+		     u16 offset,
+		     u32 bitmask,
+		     u32 value)
 {
 	u32 org_value, bit_shift, new_value;
 
@@ -274,8 +277,7 @@
 	pparm = (struct SetChannel_parm *)_malloc(sizeof(struct
 					 SetChannel_parm));
 	if (pparm == NULL) {
-		if (pcmd != NULL)
-			kfree((u8 *)pcmd);
+		kfree(pcmd);
 		return;
 	}
 	pparm->curr_ch = pAdapter->mppriv.curr_ch;
diff -druN linux-2.6.39-libre/drivers/staging/rtl8712/rtl871x_mp_ioctl.h linux-3.0-rc7-libre/drivers/staging/rtl8712/rtl871x_mp_ioctl.h
--- linux-2.6.39-libre/drivers/staging/rtl8712/rtl871x_mp_ioctl.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rtl8712/rtl871x_mp_ioctl.h	2011-07-11 19:51:52.000000000 -0400
@@ -281,23 +281,23 @@
 	MP_ERR_MODE
 };
 
-struct rwreg_param{
+struct rwreg_param {
 	unsigned int offset;
 	unsigned int width;
 	unsigned int value;
 };
 
-struct bbreg_param{
+struct bbreg_param {
 	unsigned int offset;
 	unsigned int phymask;
 	unsigned int value;
 };
 
-struct txpower_param{
+struct txpower_param {
 	unsigned int pwr_index;
 };
 
-struct datarate_param{
+struct datarate_param {
 	unsigned int rate_index;
 };
 
@@ -321,7 +321,7 @@
 	unsigned int oid;
 };
 
-struct mp_ioctl_param{
+struct mp_ioctl_param {
 	unsigned int subcode;
 	unsigned int len;
 	unsigned char data[0];
diff -druN linux-2.6.39-libre/drivers/staging/rtl8712/rtl871x_recv.c linux-3.0-rc7-libre/drivers/staging/rtl8712/rtl871x_recv.c
--- linux-2.6.39-libre/drivers/staging/rtl8712/rtl871x_recv.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rtl8712/rtl871x_recv.c	2011-07-11 19:51:52.000000000 -0400
@@ -307,9 +307,9 @@
 	return _SUCCESS;
 }
 
-static sint sta2sta_data_frame(struct _adapter *adapter, union recv_frame *precv_frame,
-			struct sta_info **psta
-)
+static sint sta2sta_data_frame(struct _adapter *adapter,
+			       union recv_frame *precv_frame,
+			       struct sta_info **psta)
 {
 	u8 *ptr = precv_frame->u.hdr.rx_data;
 	sint ret = _SUCCESS;
@@ -373,8 +373,9 @@
 	return ret;
 }
 
-static sint ap2sta_data_frame(struct _adapter *adapter, union recv_frame *precv_frame,
-		       struct sta_info **psta)
+static sint ap2sta_data_frame(struct _adapter *adapter,
+			      union recv_frame *precv_frame,
+			      struct sta_info **psta)
 {
 	u8 *ptr = precv_frame->u.hdr.rx_data;
 	struct rx_pkt_attrib *pattrib = &precv_frame->u.hdr.attrib;
@@ -431,8 +432,9 @@
 	return _SUCCESS;
 }
 
-static sint sta2ap_data_frame(struct _adapter *adapter, union recv_frame *precv_frame,
-		       struct sta_info **psta)
+static sint sta2ap_data_frame(struct _adapter *adapter,
+			      union recv_frame *precv_frame,
+			      struct sta_info **psta)
 {
 	struct rx_pkt_attrib *pattrib = &precv_frame->u.hdr.attrib;
 	struct	sta_priv *pstapriv = &adapter->stapriv;
diff -druN linux-2.6.39-libre/drivers/staging/rtl8712/rtl871x_recv.h linux-3.0-rc7-libre/drivers/staging/rtl8712/rtl871x_recv.h
--- linux-2.6.39-libre/drivers/staging/rtl8712/rtl871x_recv.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rtl8712/rtl871x_recv.h	2011-07-11 19:51:52.000000000 -0400
@@ -19,9 +19,9 @@
 /* for Rx reordering buffer control */
 struct recv_reorder_ctrl {
 	struct _adapter	*padapter;
-	u16 indicate_seq;/* =wstart_b, init_value=0xffff */
+	u16 indicate_seq; /* =wstart_b, init_value=0xffff */
 	u16 wend_b;
-       u8 wsize_b;
+	u8 wsize_b;
 	struct  __queue pending_recvframe_queue;
 	struct timer_list reordering_ctrl_timer;
 };
diff -druN linux-2.6.39-libre/drivers/staging/rtl8712/rtl871x_rf.h linux-3.0-rc7-libre/drivers/staging/rtl8712/rtl871x_rf.h
--- linux-2.6.39-libre/drivers/staging/rtl8712/rtl871x_rf.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rtl8712/rtl871x_rf.h	2011-07-11 19:51:52.000000000 -0400
@@ -22,7 +22,7 @@
 	u8	modem;
 };
 
-enum	_REG_PREAMBLE_MODE{
+enum	_REG_PREAMBLE_MODE {
 	PREAMBLE_LONG	= 1,
 	PREAMBLE_AUTO	= 2,
 	PREAMBLE_SHORT	= 3,
diff -druN linux-2.6.39-libre/drivers/staging/rtl8712/rtl871x_security.h linux-3.0-rc7-libre/drivers/staging/rtl8712/rtl871x_security.h
--- linux-2.6.39-libre/drivers/staging/rtl8712/rtl871x_security.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rtl8712/rtl871x_security.h	2011-07-11 19:51:52.000000000 -0400
@@ -21,30 +21,31 @@
 #ifndef Ndis802_11AuthModeWPA2PSK
 #define Ndis802_11AuthModeWPA2PSK (Ndis802_11AuthModeWPANone + 2)
 #endif
+
 union pn48 {
 	u64 val;
 #if defined(__BIG_ENDIAN)
-struct {
-  u8 TSC7;
-  u8 TSC6;
-  u8 TSC5;
-  u8 TSC4;
-  u8 TSC3;
-  u8 TSC2;
-  u8 TSC1;
-  u8 TSC0;
-} _byte_;
+	struct {
+		u8 TSC7;
+		u8 TSC6;
+		u8 TSC5;
+		u8 TSC4;
+		u8 TSC3;
+		u8 TSC2;
+		u8 TSC1;
+		u8 TSC0;
+	} _byte_;
 #else
-struct {
-  u8 TSC0;
-  u8 TSC1;
-  u8 TSC2;
-  u8 TSC3;
-  u8 TSC4;
-  u8 TSC5;
-  u8 TSC6;
-  u8 TSC7;
-} _byte_;
+	struct {
+		u8 TSC0;
+		u8 TSC1;
+		u8 TSC2;
+		u8 TSC3;
+		u8 TSC4;
+		u8 TSC5;
+		u8 TSC6;
+		u8 TSC7;
+	} _byte_;
 #endif
 };
 
@@ -174,11 +175,11 @@
 };
 
 void seccalctkipmic(
-	u8 *key,
-	u8 *header,
-	u8 *data,
-	u32 data_len,
-	u8 *Miccode,
+	u8  *key,
+	u8  *header,
+	u8  *data,
+	u32  data_len,
+	u8  *Miccode,
 	u8   priority);
 
 void r8712_secmicsetkey(struct mic_data *pmicdata, u8 * key);
diff -druN linux-2.6.39-libre/drivers/staging/rtl8712/rtl871x_xmit.c linux-3.0-rc7-libre/drivers/staging/rtl8712/rtl871x_xmit.c
--- linux-2.6.39-libre/drivers/staging/rtl8712/rtl871x_xmit.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rtl8712/rtl871x_xmit.c	2011-07-11 19:51:52.000000000 -0400
@@ -996,8 +996,7 @@
 {
 	struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
 
-	if (pxmitpriv->hwxmits)
-		kfree((u8 *)pxmitpriv->hwxmits);
+	kfree(pxmitpriv->hwxmits);
 }
 
 static void init_hwxmits(struct hw_xmit *phwxmit, sint entry)
diff -druN linux-2.6.39-libre/drivers/staging/rtl8712/rtl871x_xmit.h linux-3.0-rc7-libre/drivers/staging/rtl8712/rtl871x_xmit.h
--- linux-2.6.39-libre/drivers/staging/rtl8712/rtl871x_xmit.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rtl8712/rtl871x_xmit.h	2011-07-11 19:51:52.000000000 -0400
@@ -244,7 +244,8 @@
 			 struct pkt_attrib *pattrib);
 int r8712_txframes_sta_ac_pending(struct _adapter *padapter,
 				  struct pkt_attrib *pattrib);
-sint _r8712_init_xmit_priv(struct xmit_priv *pxmitpriv, struct _adapter *padapter);
+sint _r8712_init_xmit_priv(struct xmit_priv *pxmitpriv,
+			   struct _adapter *padapter);
 void _free_xmit_priv(struct xmit_priv *pxmitpriv);
 void r8712_free_xmitframe_ex(struct xmit_priv *pxmitpriv,
 			     struct xmit_frame *pxmitframe);
diff -druN linux-2.6.39-libre/drivers/staging/rtl8712/wifi.h linux-3.0-rc7-libre/drivers/staging/rtl8712/wifi.h
--- linux-2.6.39-libre/drivers/staging/rtl8712/wifi.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rtl8712/wifi.h	2011-07-11 19:51:52.000000000 -0400
@@ -39,38 +39,35 @@
 };
 
 enum WIFI_FRAME_SUBTYPE {
-
-    /* below is for mgt frame */
-    WIFI_ASSOCREQ       = (0 | WIFI_MGT_TYPE),
-    WIFI_ASSOCRSP       = (BIT(4) | WIFI_MGT_TYPE),
-    WIFI_REASSOCREQ     = (BIT(5) | WIFI_MGT_TYPE),
-    WIFI_REASSOCRSP     = (BIT(5) | BIT(4) | WIFI_MGT_TYPE),
-    WIFI_PROBEREQ       = (BIT(6) | WIFI_MGT_TYPE),
-    WIFI_PROBERSP       = (BIT(6) | BIT(4) | WIFI_MGT_TYPE),
-    WIFI_BEACON         = (BIT(7) | WIFI_MGT_TYPE),
-    WIFI_ATIM           = (BIT(7) | BIT(4) | WIFI_MGT_TYPE),
-    WIFI_DISASSOC       = (BIT(7) | BIT(5) | WIFI_MGT_TYPE),
-    WIFI_AUTH           = (BIT(7) | BIT(5) | BIT(4) | WIFI_MGT_TYPE),
-    WIFI_DEAUTH         = (BIT(7) | BIT(6) | WIFI_MGT_TYPE),
-    WIFI_ACTION         = (BIT(7) | BIT(6) | BIT(4) | WIFI_MGT_TYPE),
-
-    /* below is for control frame */
-    WIFI_PSPOLL         = (BIT(7) | BIT(5) | WIFI_CTRL_TYPE),
-    WIFI_RTS            = (BIT(7) | BIT(5) | BIT(4) | WIFI_CTRL_TYPE),
-    WIFI_CTS            = (BIT(7) | BIT(6) | WIFI_CTRL_TYPE),
-    WIFI_ACK            = (BIT(7) | BIT(6) | BIT(4) | WIFI_CTRL_TYPE),
-    WIFI_CFEND          = (BIT(7) | BIT(6) | BIT(5) | WIFI_CTRL_TYPE),
-    WIFI_CFEND_CFACK    = (BIT(7) | BIT(6) | BIT(5) | BIT(4) | WIFI_CTRL_TYPE),
-
-    /* below is for data frame */
-    WIFI_DATA           = (0 | WIFI_DATA_TYPE),
-    WIFI_DATA_CFACK     = (BIT(4) | WIFI_DATA_TYPE),
-    WIFI_DATA_CFPOLL    = (BIT(5) | WIFI_DATA_TYPE),
-    WIFI_DATA_CFACKPOLL = (BIT(5) | BIT(4) | WIFI_DATA_TYPE),
-    WIFI_DATA_NULL      = (BIT(6) | WIFI_DATA_TYPE),
-    WIFI_CF_ACK         = (BIT(6) | BIT(4) | WIFI_DATA_TYPE),
-    WIFI_CF_POLL        = (BIT(6) | BIT(5) | WIFI_DATA_TYPE),
-    WIFI_CF_ACKPOLL     = (BIT(6) | BIT(5) | BIT(4) | WIFI_DATA_TYPE),
+	/* below is for mgt frame */
+	WIFI_ASSOCREQ       = (0 | WIFI_MGT_TYPE),
+	WIFI_ASSOCRSP       = (BIT(4) | WIFI_MGT_TYPE),
+	WIFI_REASSOCREQ     = (BIT(5) | WIFI_MGT_TYPE),
+	WIFI_REASSOCRSP     = (BIT(5) | BIT(4) | WIFI_MGT_TYPE),
+	WIFI_PROBEREQ       = (BIT(6) | WIFI_MGT_TYPE),
+	WIFI_PROBERSP       = (BIT(6) | BIT(4) | WIFI_MGT_TYPE),
+	WIFI_BEACON         = (BIT(7) | WIFI_MGT_TYPE),
+	WIFI_ATIM           = (BIT(7) | BIT(4) | WIFI_MGT_TYPE),
+	WIFI_DISASSOC       = (BIT(7) | BIT(5) | WIFI_MGT_TYPE),
+	WIFI_AUTH           = (BIT(7) | BIT(5) | BIT(4) | WIFI_MGT_TYPE),
+	WIFI_DEAUTH         = (BIT(7) | BIT(6) | WIFI_MGT_TYPE),
+	WIFI_ACTION         = (BIT(7) | BIT(6) | BIT(4) | WIFI_MGT_TYPE),
+	/* below is for control frame */
+	WIFI_PSPOLL         = (BIT(7) | BIT(5) | WIFI_CTRL_TYPE),
+	WIFI_RTS            = (BIT(7) | BIT(5) | BIT(4) | WIFI_CTRL_TYPE),
+	WIFI_CTS            = (BIT(7) | BIT(6) | WIFI_CTRL_TYPE),
+	WIFI_ACK            = (BIT(7) | BIT(6) | BIT(4) | WIFI_CTRL_TYPE),
+	WIFI_CFEND          = (BIT(7) | BIT(6) | BIT(5) | WIFI_CTRL_TYPE),
+	WIFI_CFEND_CFACK = (BIT(7) | BIT(6) | BIT(5) | BIT(4) | WIFI_CTRL_TYPE),
+	/* below is for data frame */
+	WIFI_DATA           = (0 | WIFI_DATA_TYPE),
+	WIFI_DATA_CFACK     = (BIT(4) | WIFI_DATA_TYPE),
+	WIFI_DATA_CFPOLL    = (BIT(5) | WIFI_DATA_TYPE),
+	WIFI_DATA_CFACKPOLL = (BIT(5) | BIT(4) | WIFI_DATA_TYPE),
+	WIFI_DATA_NULL      = (BIT(6) | WIFI_DATA_TYPE),
+	WIFI_CF_ACK         = (BIT(6) | BIT(4) | WIFI_DATA_TYPE),
+	WIFI_CF_POLL        = (BIT(6) | BIT(5) | WIFI_DATA_TYPE),
+	WIFI_CF_ACKPOLL     = (BIT(6) | BIT(5) | BIT(4) | WIFI_DATA_TYPE),
 };
 
 enum WIFI_REASON_CODE	{
@@ -84,7 +81,6 @@
 	_RSON_CLS3_			= 7,
 	_RSON_DISAOC_STA_LEAVING_	= 8,
 	_RSON_ASOC_NOT_AUTH_		= 9,
-
 	/* WPA reason */
 	_RSON_INVALID_IE_		= 13,
 	_RSON_MIC_FAILURE_		= 14,
@@ -97,7 +93,6 @@
 	_RSON_UNSUPPORT_RSNE_VER_	= 21,
 	_RSON_INVALID_RSNE_CAP_		= 22,
 	_RSON_IEEE_802DOT1X_AUTH_FAIL_	= 23,
-
 	/* below are Realtek definitions */
 	_RSON_PMK_NOT_AVAILABLE_	= 24,
 };
diff -druN linux-2.6.39-libre/drivers/staging/rtl8712/wlan_bssdef.h linux-3.0-rc7-libre/drivers/staging/rtl8712/wlan_bssdef.h
--- linux-2.6.39-libre/drivers/staging/rtl8712/wlan_bssdef.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rtl8712/wlan_bssdef.h	2011-07-11 19:51:52.000000000 -0400
@@ -13,23 +13,23 @@
 typedef unsigned char   NDIS_802_11_RATES_EX[NDIS_802_11_LENGTH_RATES_EX];
 
 struct ndis_802_11_ssid {
-  u32  SsidLength;
-  u8  Ssid[32];
+	u32 SsidLength;
+	u8  Ssid[32];
 };
 
 enum NDIS_802_11_NETWORK_TYPE {
-    Ndis802_11FH,
-    Ndis802_11DS,
-    Ndis802_11OFDM5,
-    Ndis802_11OFDM24,
-    Ndis802_11NetworkTypeMax    /* not a real type, defined as an upper bound */
+	Ndis802_11FH,
+	Ndis802_11DS,
+	Ndis802_11OFDM5,
+	Ndis802_11OFDM24,
+	Ndis802_11NetworkTypeMax /* not a real type, defined as an upper bound*/
 };
 
 struct NDIS_802_11_CONFIGURATION_FH {
-    u32           Length;             /* Length of structure */
-    u32           HopPattern;         /* As defined by 802.11, MSB set */
-    u32           HopSet;             /* to one if non-802.11 */
-    u32           DwellTime;          /* units are Kusec */
+	u32 Length;             /* Length of structure */
+	u32 HopPattern;         /* As defined by 802.11, MSB set */
+	u32 HopSet;             /* to one if non-802.11 */
+	u32 DwellTime;          /* units are Kusec */
 };
 
 /*
@@ -37,25 +37,25 @@
 	ODI Handler will convert the channel number to freq. number.
 */
 struct NDIS_802_11_CONFIGURATION {
-    u32           Length;             /* Length of structure */
-    u32           BeaconPeriod;       /* units are Kusec */
-    u32           ATIMWindow;         /* units are Kusec */
-    u32           DSConfig;           /* Frequency, units are kHz */
-    struct NDIS_802_11_CONFIGURATION_FH    FHConfig;
+	u32 Length;             /* Length of structure */
+	u32 BeaconPeriod;       /* units are Kusec */
+	u32 ATIMWindow;         /* units are Kusec */
+	u32 DSConfig;           /* Frequency, units are kHz */
+	struct NDIS_802_11_CONFIGURATION_FH FHConfig;
 };
 
 enum NDIS_802_11_NETWORK_INFRASTRUCTURE {
-    Ndis802_11IBSS,
-    Ndis802_11Infrastructure,
-    Ndis802_11AutoUnknown,
-    Ndis802_11InfrastructureMax, /* Not a real value, defined as upper bound */
-    Ndis802_11APMode
+	Ndis802_11IBSS,
+	Ndis802_11Infrastructure,
+	Ndis802_11AutoUnknown,
+	Ndis802_11InfrastructureMax, /*Not a real value,defined as upper bound*/
+	Ndis802_11APMode
 };
 
 struct NDIS_802_11_FIXED_IEs {
-  u8  Timestamp[8];
-  u16  BeaconInterval;
-  u16  Capabilities;
+	u8  Timestamp[8];
+	u16 BeaconInterval;
+	u16 Capabilities;
 };
 
 /*
@@ -70,44 +70,44 @@
  */
 
 struct ndis_wlan_bssid_ex {
-  u32  Length;
-  unsigned char  MacAddress[6];
-  u8  Reserved[2];
-  struct ndis_802_11_ssid  Ssid;
-  u32  Privacy;
-  s32  Rssi;
-  enum NDIS_802_11_NETWORK_TYPE  NetworkTypeInUse;
-  struct NDIS_802_11_CONFIGURATION  Configuration;
-  enum NDIS_802_11_NETWORK_INFRASTRUCTURE  InfrastructureMode;
-  NDIS_802_11_RATES_EX  SupportedRates;
-  u32  IELength;
-/*(timestamp, beacon interval, and capability information) */
-  u8  IEs[MAX_IE_SZ];
+	u32 Length;
+	unsigned char  MacAddress[6];
+	u8  Reserved[2];
+	struct ndis_802_11_ssid  Ssid;
+	u32 Privacy;
+	s32 Rssi;
+	enum NDIS_802_11_NETWORK_TYPE  NetworkTypeInUse;
+	struct NDIS_802_11_CONFIGURATION  Configuration;
+	enum NDIS_802_11_NETWORK_INFRASTRUCTURE  InfrastructureMode;
+	NDIS_802_11_RATES_EX  SupportedRates;
+	u32 IELength;
+	/*(timestamp, beacon interval, and capability information) */
+	u8 IEs[MAX_IE_SZ];
 };
 
 enum NDIS_802_11_AUTHENTICATION_MODE {
-    Ndis802_11AuthModeOpen,
-    Ndis802_11AuthModeShared,
-    Ndis802_11AuthModeAutoSwitch,
-    Ndis802_11AuthModeWPA,
-    Ndis802_11AuthModeWPAPSK,
-    Ndis802_11AuthModeWPANone,
-    Ndis802_11AuthModeMax     /* Not a real mode, defined as upper bound */
+	Ndis802_11AuthModeOpen,
+	Ndis802_11AuthModeShared,
+	Ndis802_11AuthModeAutoSwitch,
+	Ndis802_11AuthModeWPA,
+	Ndis802_11AuthModeWPAPSK,
+	Ndis802_11AuthModeWPANone,
+	Ndis802_11AuthModeMax      /* Not a real mode, defined as upper bound */
 };
 
 enum {
-    Ndis802_11WEPEnabled,
-    Ndis802_11Encryption1Enabled = Ndis802_11WEPEnabled,
-    Ndis802_11WEPDisabled,
-    Ndis802_11EncryptionDisabled = Ndis802_11WEPDisabled,
-    Ndis802_11WEPKeyAbsent,
-    Ndis802_11Encryption1KeyAbsent = Ndis802_11WEPKeyAbsent,
-    Ndis802_11WEPNotSupported,
-    Ndis802_11EncryptionNotSupported = Ndis802_11WEPNotSupported,
-    Ndis802_11Encryption2Enabled,
-    Ndis802_11Encryption2KeyAbsent,
-    Ndis802_11Encryption3Enabled,
-    Ndis802_11Encryption3KeyAbsent
+	Ndis802_11WEPEnabled,
+	Ndis802_11Encryption1Enabled = Ndis802_11WEPEnabled,
+	Ndis802_11WEPDisabled,
+	Ndis802_11EncryptionDisabled = Ndis802_11WEPDisabled,
+	Ndis802_11WEPKeyAbsent,
+	Ndis802_11Encryption1KeyAbsent = Ndis802_11WEPKeyAbsent,
+	Ndis802_11WEPNotSupported,
+	Ndis802_11EncryptionNotSupported = Ndis802_11WEPNotSupported,
+	Ndis802_11Encryption2Enabled,
+	Ndis802_11Encryption2KeyAbsent,
+	Ndis802_11Encryption3Enabled,
+	Ndis802_11Encryption3KeyAbsent
 };
 
 #define NDIS_802_11_AI_REQFI_CAPABILITIES      1
@@ -119,51 +119,51 @@
 #define NDIS_802_11_AI_RESFI_ASSOCIATIONID     4
 
 struct NDIS_802_11_AI_REQFI {
-    u16 Capabilities;
-    u16 ListenInterval;
-    unsigned char CurrentAPAddress[6];
+	u16 Capabilities;
+	u16 ListenInterval;
+	unsigned char CurrentAPAddress[6];
 };
 
 struct NDIS_802_11_AI_RESFI {
-    u16 Capabilities;
-    u16 StatusCode;
-    u16 AssociationId;
+	u16 Capabilities;
+	u16 StatusCode;
+	u16 AssociationId;
 };
 
 struct NDIS_802_11_ASSOCIATION_INFORMATION {
-    u32                   Length;
-    u16                  AvailableRequestFixedIEs;
-    struct NDIS_802_11_AI_REQFI    RequestFixedIEs;
-    u32                   RequestIELength;
-    u32                   OffsetRequestIEs;
-    u16                  AvailableResponseFixedIEs;
-    struct NDIS_802_11_AI_RESFI    ResponseFixedIEs;
-    u32                   ResponseIELength;
-    u32                   OffsetResponseIEs;
+	u32 Length;
+	u16 AvailableRequestFixedIEs;
+	struct NDIS_802_11_AI_REQFI RequestFixedIEs;
+	u32 RequestIELength;
+	u32 OffsetRequestIEs;
+	u16 AvailableResponseFixedIEs;
+	struct NDIS_802_11_AI_RESFI ResponseFixedIEs;
+	u32 ResponseIELength;
+	u32 OffsetResponseIEs;
 };
 
 /* Key mapping keys require a BSSID*/
 struct NDIS_802_11_KEY {
-    u32           Length;             /* Length of this structure */
-    u32           KeyIndex;
-    u32           KeyLength;          /* length of key in bytes */
-    unsigned char BSSID[6];
-    unsigned long long KeyRSC;
-    u8           KeyMaterial[32];     /* variable length */
+	u32 Length;			/* Length of this structure */
+	u32 KeyIndex;
+	u32 KeyLength;			/* length of key in bytes */
+	unsigned char BSSID[6];
+	unsigned long long KeyRSC;
+	u8  KeyMaterial[32];		/* variable length */
 };
 
 struct NDIS_802_11_REMOVE_KEY {
-    u32                   Length;        /* Length of this structure */
-    u32                   KeyIndex;
-    unsigned char BSSID[6];
+	u32 Length;			/* Length of this structure */
+	u32 KeyIndex;
+	unsigned char BSSID[6];
 };
 
 struct NDIS_802_11_WEP {
-    u32     Length;        /* Length of this structure */
-    u32     KeyIndex;      /* 0 is the per-client key,
-			      * 1-N are the global keys */
-    u32     KeyLength;     /* length of key in bytes */
-    u8     KeyMaterial[16];/* variable length depending on above field */
+	u32 Length;		  /* Length of this structure */
+	u32 KeyIndex;		  /* 0 is the per-client key,
+				   * 1-N are the global keys */
+	u32 KeyLength;		  /* length of key in bytes */
+	u8  KeyMaterial[16];      /* variable length depending on above field */
 };
 
 /* mask for authentication/integrity fields */
@@ -192,15 +192,15 @@
 };
 
 enum VRTL_CARRIER_SENSE {
-    DISABLE_VCS,
-    ENABLE_VCS,
-    AUTO_VCS
+	DISABLE_VCS,
+	ENABLE_VCS,
+	AUTO_VCS
 };
 
 enum VCS_TYPE {
-    NONE_VCS,
-    RTS_CTS,
-    CTS_TO_SELF
+	NONE_VCS,
+	RTS_CTS,
+	CTS_TO_SELF
 };
 
 #define PWR_CAM 0
@@ -211,9 +211,9 @@
 
 enum UAPSD_MAX_SP {
 	NO_LIMIT,
-       TWO_MSDU,
-       FOUR_MSDU,
-       SIX_MSDU
+	TWO_MSDU,
+	FOUR_MSDU,
+	SIX_MSDU
 };
 
 #define NUM_PRE_AUTH_KEY 16
@@ -223,18 +223,18 @@
  *	WPA2
  */
 struct wlan_bssid_ex {
-  u32  Length;
-  unsigned char  MacAddress[6];
-  u8  Reserved[2];
-  struct ndis_802_11_ssid  Ssid;
-  u32  Privacy;
-  s32  Rssi;
-  enum NDIS_802_11_NETWORK_TYPE  NetworkTypeInUse;
-  struct NDIS_802_11_CONFIGURATION  Configuration;
-  enum NDIS_802_11_NETWORK_INFRASTRUCTURE  InfrastructureMode;
-  NDIS_802_11_RATES_EX  SupportedRates;
-  u32  IELength;
-  u8  IEs[MAX_IE_SZ];	/* (timestamp, beacon interval, and capability
+	u32 Length;
+	unsigned char  MacAddress[6];
+	u8  Reserved[2];
+	struct ndis_802_11_ssid  Ssid;
+	u32 Privacy;
+	s32 Rssi;
+	enum NDIS_802_11_NETWORK_TYPE  NetworkTypeInUse;
+	struct NDIS_802_11_CONFIGURATION  Configuration;
+	enum NDIS_802_11_NETWORK_INFRASTRUCTURE  InfrastructureMode;
+	NDIS_802_11_RATES_EX  SupportedRates;
+	u32 IELength;
+	u8  IEs[MAX_IE_SZ];	/* (timestamp, beacon interval, and capability
 				 * information) */
 };
 
diff -druN linux-2.6.39-libre/drivers/staging/rts_pstor/ms.c linux-3.0-rc7-libre/drivers/staging/rts_pstor/ms.c
--- linux-2.6.39-libre/drivers/staging/rts_pstor/ms.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rts_pstor/ms.c	2011-07-11 19:51:52.000000000 -0400
@@ -864,7 +864,7 @@
 		TRACE_RET(chip, STATUS_FAIL);
 	}
 
-	buf = (u8 *)rtsx_alloc_dma_buf(chip, 64 * 512, GFP_KERNEL);
+	buf = kmalloc(64 * 512, GFP_KERNEL);
 	if (buf == NULL) {
 		TRACE_RET(chip, STATUS_ERROR);
 	}
@@ -876,11 +876,11 @@
 		}
 		retval = rtsx_read_register(chip, MS_TRANS_CFG, &val);
 		if (retval != STATUS_SUCCESS) {
-			rtsx_free_dma_buf(chip, buf);
+			kfree(buf);
 			TRACE_RET(chip, STATUS_FAIL);
 		}
 		if (!(val & MS_INT_BREQ)) {
-			rtsx_free_dma_buf(chip, buf);
+			kfree(buf);
 			TRACE_RET(chip, STATUS_FAIL);
 		}
 		retval = ms_transfer_data(chip, MS_TM_AUTO_READ, PRO_READ_LONG_DATA,
@@ -892,7 +892,7 @@
 		}
 	}
 	if (retval != STATUS_SUCCESS) {
-		rtsx_free_dma_buf(chip, buf);
+		kfree(buf);
 		TRACE_RET(chip, STATUS_FAIL);
 	}
 
@@ -900,7 +900,7 @@
 	do {
 		retval = rtsx_read_register(chip, MS_TRANS_CFG, &val);
 		if (retval != STATUS_SUCCESS) {
-			rtsx_free_dma_buf(chip, buf);
+			kfree(buf);
 			TRACE_RET(chip, STATUS_FAIL);
 		}
 
@@ -909,7 +909,7 @@
 
 		retval = ms_transfer_tpc(chip, MS_TM_NORMAL_READ, PRO_READ_LONG_DATA, 0, WAIT_INT);
 		if (retval != STATUS_SUCCESS) {
-			rtsx_free_dma_buf(chip, buf);
+			kfree(buf);
 			TRACE_RET(chip, STATUS_FAIL);
 		}
 
@@ -917,18 +917,18 @@
 	} while (i < 1024);
 
 	if (retval != STATUS_SUCCESS) {
-		rtsx_free_dma_buf(chip, buf);
+		kfree(buf);
 		TRACE_RET(chip, STATUS_FAIL);
 	}
 
 	if ((buf[0] != 0xa5) && (buf[1] != 0xc3)) {
 		/* Signature code is wrong */
-		rtsx_free_dma_buf(chip, buf);
+		kfree(buf);
 		TRACE_RET(chip, STATUS_FAIL);
 	}
 
 	if ((buf[4] < 1) || (buf[4] > 12)) {
-		rtsx_free_dma_buf(chip, buf);
+		kfree(buf);
 		TRACE_RET(chip, STATUS_FAIL);
 	}
 
@@ -950,15 +950,15 @@
 			RTSX_DEBUGP("sys_info_addr = 0x%x, sys_info_size = 0x%x\n",
 					sys_info_addr, sys_info_size);
 			if (sys_info_size != 96)  {
-				rtsx_free_dma_buf(chip, buf);
+				kfree(buf);
 				TRACE_RET(chip, STATUS_FAIL);
 			}
 			if (sys_info_addr < 0x1A0) {
-				rtsx_free_dma_buf(chip, buf);
+				kfree(buf);
 				TRACE_RET(chip, STATUS_FAIL);
 			}
 			if ((sys_info_size + sys_info_addr) > 0x8000) {
-				rtsx_free_dma_buf(chip, buf);
+				kfree(buf);
 				TRACE_RET(chip, STATUS_FAIL);
 			}
 
@@ -984,15 +984,15 @@
 			RTSX_DEBUGP("model_name_addr = 0x%x, model_name_size = 0x%x\n",
 					model_name_addr, model_name_size);
 			if (model_name_size != 48)  {
-				rtsx_free_dma_buf(chip, buf);
+				kfree(buf);
 				TRACE_RET(chip, STATUS_FAIL);
 			}
 			if (model_name_addr < 0x1A0) {
-				rtsx_free_dma_buf(chip, buf);
+				kfree(buf);
 				TRACE_RET(chip, STATUS_FAIL);
 			}
 			if ((model_name_size + model_name_addr) > 0x8000) {
-				rtsx_free_dma_buf(chip, buf);
+				kfree(buf);
 				TRACE_RET(chip, STATUS_FAIL);
 			}
 
@@ -1005,7 +1005,7 @@
 	}
 
 	if (i == buf[4]) {
-		rtsx_free_dma_buf(chip, buf);
+		kfree(buf);
 		TRACE_RET(chip, STATUS_FAIL);
 	}
 
@@ -1042,7 +1042,7 @@
 	memcpy(ms_card->raw_model_name, buf + model_name_addr, 48);
 #endif
 
-	rtsx_free_dma_buf(chip, buf);
+	kfree(buf);
 
 #ifdef SUPPORT_MSXC
 	if (CHK_MSXC(ms_card)) {
@@ -3784,7 +3784,7 @@
 		TRACE_RET(chip, STATUS_FAIL);
 	}
 
-	buf = (u8 *)rtsx_alloc_dma_buf(chip, 1540, GFP_KERNEL);
+	buf = kmalloc(1540, GFP_KERNEL);
 	if (!buf) {
 		TRACE_RET(chip, STATUS_ERROR);
 	}
@@ -3817,9 +3817,7 @@
 	rtsx_stor_set_xfer_buf(buf, bufflen, srb);
 
 GetEKBFinish:
-	if (buf) {
-		rtsx_free_dma_buf(chip, buf);
-	}
+	kfree(buf);
 	return retval;
 }
 
@@ -4022,7 +4020,7 @@
 		TRACE_RET(chip, STATUS_FAIL);
 	}
 
-	buf = (u8 *)rtsx_alloc_dma_buf(chip, 1028, GFP_KERNEL);
+	buf = kmalloc(1028, GFP_KERNEL);
 	if (!buf) {
 		TRACE_RET(chip, STATUS_ERROR);
 	}
@@ -4055,9 +4053,7 @@
 	rtsx_stor_set_xfer_buf(buf, bufflen, srb);
 
 GetICVFinish:
-	if (buf) {
-		rtsx_free_dma_buf(chip, buf);
-	}
+	kfree(buf);
 	return retval;
 }
 
@@ -4081,7 +4077,7 @@
 		TRACE_RET(chip, STATUS_FAIL);
 	}
 
-	buf = (u8 *)rtsx_alloc_dma_buf(chip, 1028, GFP_KERNEL);
+	buf = kmalloc(1028, GFP_KERNEL);
 	if (!buf) {
 		TRACE_RET(chip, STATUS_ERROR);
 	}
@@ -4156,9 +4152,7 @@
 #endif
 
 SetICVFinish:
-	if (buf) {
-		rtsx_free_dma_buf(chip, buf);
-	}
+	kfree(buf);
 	return retval;
 }
 
diff -druN linux-2.6.39-libre/drivers/staging/rts_pstor/rtsx.c linux-3.0-rc7-libre/drivers/staging/rts_pstor/rtsx.c
--- linux-2.6.39-libre/drivers/staging/rts_pstor/rtsx.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rts_pstor/rtsx.c	2011-07-11 19:51:52.000000000 -0400
@@ -594,7 +594,9 @@
 	wait_timeout((delay_use + 5) * 1000);
 
 	for (;;) {
-		wait_timeout(POLLING_INTERVAL);
+
+		set_current_state(TASK_INTERRUPTIBLE);
+		schedule_timeout(POLLING_INTERVAL);
 
 		/* lock the device pointers */
 		mutex_lock(&(dev->dev_mutex));
diff -druN linux-2.6.39-libre/drivers/staging/rts_pstor/rtsx.h linux-3.0-rc7-libre/drivers/staging/rts_pstor/rtsx.h
--- linux-2.6.39-libre/drivers/staging/rts_pstor/rtsx.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rts_pstor/rtsx.h	2011-07-11 19:51:52.000000000 -0400
@@ -98,9 +98,6 @@
 
 #define SCSI_LUN(srb)		((srb)->device->lun)
 
-#define rtsx_alloc_dma_buf(chip, size, flag)	kmalloc((size), (flag))
-#define rtsx_free_dma_buf(chip, ptr)		kfree((ptr))
-
 typedef unsigned long DELAY_PARA_T;
 
 struct rtsx_chip;
diff -druN linux-2.6.39-libre/drivers/staging/rts_pstor/sd.c linux-3.0-rc7-libre/drivers/staging/rts_pstor/sd.c
--- linux-2.6.39-libre/drivers/staging/rts_pstor/sd.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rts_pstor/sd.c	2011-07-11 19:51:52.000000000 -0400
@@ -2227,6 +2227,7 @@
 	retval = sd_read_data(chip, SD_TM_NORMAL_READ, cmd,
 		5, 512, 1, bus_width, NULL, 0, 100);
 	if (retval != STATUS_SUCCESS) {
+		rtsx_clear_sd_error(chip);
 		TRACE_RET(chip, STATUS_FAIL);
 	}
 
@@ -2327,7 +2328,7 @@
 
 			retval = sd_send_cmd_get_rsp(chip, IO_SEND_OP_COND, 0, SD_RSP_TYPE_R4, rsp, 5);
 			if (retval == STATUS_SUCCESS) {
-				int func_num = (rsp[1] >> 4) && 0x07;
+				int func_num = (rsp[1] >> 4) & 0x07;
 				if (func_num) {
 					RTSX_DEBUGP("SD_IO card (Function number: %d)!\n", func_num);
 					chip->sd_io = 1;
diff -druN linux-2.6.39-libre/drivers/staging/rts_pstor/spi.c linux-3.0-rc7-libre/drivers/staging/rts_pstor/spi.c
--- linux-2.6.39-libre/drivers/staging/rts_pstor/spi.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rts_pstor/spi.c	2011-07-11 19:51:52.000000000 -0400
@@ -505,7 +505,7 @@
 		TRACE_RET(chip, STATUS_FAIL);
 	}
 
-	buf = (u8 *)rtsx_alloc_dma_buf(chip, SF_PAGE_LEN, GFP_KERNEL);
+	buf = kmalloc(SF_PAGE_LEN, GFP_KERNEL);
 	if (buf == NULL)
 		TRACE_RET(chip, STATUS_ERROR);
 
@@ -543,7 +543,7 @@
 
 		retval = rtsx_transfer_data(chip, 0, buf, pagelen, 0, DMA_FROM_DEVICE, 10000);
 		if (retval < 0) {
-			rtsx_free_dma_buf(chip, buf);
+			kfree(buf);
 			rtsx_clear_spi_error(chip);
 			spi_set_err_code(chip, SPI_HW_ERR);
 			TRACE_RET(chip, STATUS_FAIL);
@@ -556,7 +556,7 @@
 	}
 
 	scsi_set_resid(srb, 0);
-	rtsx_free_dma_buf(chip, buf);
+	kfree(buf);
 
 	return STATUS_SUCCESS;
 }
@@ -584,14 +584,14 @@
 	}
 
 	if (program_mode == BYTE_PROGRAM) {
-		buf = rtsx_alloc_dma_buf(chip, 4, GFP_KERNEL);
+		buf = kmalloc(4, GFP_KERNEL);
 		if (!buf)
 			TRACE_RET(chip, STATUS_ERROR);
 
 		while (len) {
 			retval = sf_enable_write(chip, SPI_WREN);
 			if (retval != STATUS_SUCCESS) {
-				rtsx_free_dma_buf(chip, buf);
+				kfree(buf);
 				TRACE_RET(chip, STATUS_FAIL);
 			}
 
@@ -605,7 +605,7 @@
 
 			retval = rtsx_send_cmd(chip, 0, 100);
 			if (retval < 0) {
-				rtsx_free_dma_buf(chip, buf);
+				kfree(buf);
 				rtsx_clear_spi_error(chip);
 				spi_set_err_code(chip, SPI_HW_ERR);
 				TRACE_RET(chip, STATUS_FAIL);
@@ -613,7 +613,7 @@
 
 			retval = sf_polling_status(chip, 100);
 			if (retval != STATUS_SUCCESS) {
-				rtsx_free_dma_buf(chip, buf);
+				kfree(buf);
 				TRACE_RET(chip, STATUS_FAIL);
 			}
 
@@ -621,7 +621,7 @@
 			len--;
 		}
 
-		rtsx_free_dma_buf(chip, buf);
+		kfree(buf);
 
 	} else if (program_mode == AAI_PROGRAM) {
 		int first_byte = 1;
@@ -630,7 +630,7 @@
 		if (retval != STATUS_SUCCESS)
 			TRACE_RET(chip, STATUS_FAIL);
 
-		buf = rtsx_alloc_dma_buf(chip, 4, GFP_KERNEL);
+		buf = kmalloc(4, GFP_KERNEL);
 		if (!buf)
 			TRACE_RET(chip, STATUS_ERROR);
 
@@ -650,7 +650,7 @@
 
 			retval = rtsx_send_cmd(chip, 0, 100);
 			if (retval < 0) {
-				rtsx_free_dma_buf(chip, buf);
+				kfree(buf);
 				rtsx_clear_spi_error(chip);
 				spi_set_err_code(chip, SPI_HW_ERR);
 				TRACE_RET(chip, STATUS_FAIL);
@@ -658,14 +658,14 @@
 
 			retval = sf_polling_status(chip, 100);
 			if (retval != STATUS_SUCCESS) {
-				rtsx_free_dma_buf(chip, buf);
+				kfree(buf);
 				TRACE_RET(chip, STATUS_FAIL);
 			}
 
 			len--;
 		}
 
-		rtsx_free_dma_buf(chip, buf);
+		kfree(buf);
 
 		retval = sf_disable_write(chip, SPI_WRDI);
 		if (retval != STATUS_SUCCESS)
@@ -675,7 +675,7 @@
 		if (retval != STATUS_SUCCESS)
 			TRACE_RET(chip, STATUS_FAIL);
 	} else if (program_mode == PAGE_PROGRAM) {
-		buf = rtsx_alloc_dma_buf(chip, SF_PAGE_LEN, GFP_KERNEL);
+		buf = kmalloc(SF_PAGE_LEN, GFP_KERNEL);
 		if (!buf)
 			TRACE_RET(chip, STATUS_NOMEM);
 
@@ -687,7 +687,7 @@
 
 			retval = sf_enable_write(chip, SPI_WREN);
 			if (retval != STATUS_SUCCESS) {
-				rtsx_free_dma_buf(chip, buf);
+				kfree(buf);
 				TRACE_RET(chip, STATUS_FAIL);
 			}
 
@@ -702,7 +702,7 @@
 
 			retval = rtsx_transfer_data(chip, 0, buf, pagelen, 0, DMA_TO_DEVICE, 100);
 			if (retval < 0) {
-				rtsx_free_dma_buf(chip, buf);
+				kfree(buf);
 				rtsx_clear_spi_error(chip);
 				spi_set_err_code(chip, SPI_HW_ERR);
 				TRACE_RET(chip, STATUS_FAIL);
@@ -710,7 +710,7 @@
 
 			retval = sf_polling_status(chip, 100);
 			if (retval != STATUS_SUCCESS) {
-				rtsx_free_dma_buf(chip, buf);
+				kfree(buf);
 				TRACE_RET(chip, STATUS_FAIL);
 			}
 
@@ -718,7 +718,7 @@
 			len -= pagelen;
 		}
 
-		rtsx_free_dma_buf(chip, buf);
+		kfree(buf);
 	} else {
 		spi_set_err_code(chip, SPI_INVALID_COMMAND);
 		TRACE_RET(chip, STATUS_FAIL);
diff -druN linux-2.6.39-libre/drivers/staging/rts_pstor/xd.c linux-3.0-rc7-libre/drivers/staging/rts_pstor/xd.c
--- linux-2.6.39-libre/drivers/staging/rts_pstor/xd.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/rts_pstor/xd.c	2011-07-11 19:51:52.000000000 -0400
@@ -380,7 +380,7 @@
 
 		RTSX_DEBUGP("xD ECC error, dummy write!\n");
 
-		buf = (u8 *)rtsx_alloc_dma_buf(chip, 512, GFP_KERNEL);
+		buf = kmalloc(512, GFP_KERNEL);
 		if (!buf)
 			return;
 
@@ -427,7 +427,7 @@
 			rtsx_write_register(chip, CARD_STOP, SD_STOP | SD_CLR_ERR, SD_STOP | SD_CLR_ERR);
 		}
 
-		rtsx_free_dma_buf(chip, buf);
+		kfree(buf);
 
 		if (chip->asic_code) {
 			rtsx_write_register(chip, CARD_PULL_CTL2, 0xFF, 0x55);
diff -druN linux-2.6.39-libre/drivers/staging/sbe-2t3e3/dc.c linux-3.0-rc7-libre/drivers/staging/sbe-2t3e3/dc.c
--- linux-2.6.39-libre/drivers/staging/sbe-2t3e3/dc.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/sbe-2t3e3/dc.c	2011-07-11 19:51:52.000000000 -0400
@@ -341,10 +341,6 @@
 		sc->ether.tx_ring = kzalloc(SBE_2T3E3_TX_DESC_RING_SIZE *
 					    sizeof(t3e3_tx_desc_t), GFP_KERNEL);
 	if (sc->ether.tx_ring == NULL) {
-#ifdef T3E3_USE_CONTIGMALLOC
-		t3e3_contigmemory_size = SBE_2T3E3_RX_DESC_RING_SIZE *
-			sizeof(t3e3_rx_desc_t);
-#endif
 		kfree(sc->ether.rx_ring);
 		sc->ether.rx_ring = NULL;
 		dev_err(&sc->pdev->dev, "SBE 2T3E3: no buffer space for RX ring\n");
@@ -366,16 +362,8 @@
 					dev_kfree_skb_any(sc->ether.rx_data[j]);
 					sc->ether.rx_data[j] = NULL;
 				}
-#ifdef T3E3_USE_CONTIGMALLOC
-				t3e3_contigmemory_size = SBE_2T3E3_RX_DESC_RING_SIZE *
-					sizeof(t3e3_rx_desc_t);
-#endif
 				kfree(sc->ether.rx_ring);
 				sc->ether.rx_ring = NULL;
-#ifdef T3E3_USE_CONTIGMALLOC
-				t3e3_contigmemory_size = SBE_2T3E3_TX_DESC_RING_SIZE *
-					sizeof(t3e3_tx_desc_t);
-#endif
 				kfree(sc->ether.tx_ring);
 				sc->ether.tx_ring = NULL;
 				dev_err(&sc->pdev->dev, "SBE 2T3E3: token_alloc err:"
@@ -454,23 +442,10 @@
 		}
 	}
 
-	if (sc->ether.rx_ring != NULL) {
-#ifdef T3E3_USE_CONTIGMALLOC
-		t3e3_contigmemory_size = SBE_2T3E3_RX_DESC_RING_SIZE *
-			sizeof(t3e3_rx_desc_t);
-#endif
-		kfree(sc->ether.rx_ring);
-		sc->ether.rx_ring = NULL;
-	}
-
-	if (sc->ether.tx_ring != NULL) {
-#ifdef T3E3_USE_CONTIGMALLOC
-		t3e3_contigmemory_size = SBE_2T3E3_TX_DESC_RING_SIZE *
-			sizeof(t3e3_tx_desc_t);
-#endif
-		kfree(sc->ether.tx_ring);
-		sc->ether.tx_ring = NULL;
-	}
+	kfree(sc->ether.rx_ring);
+	sc->ether.rx_ring = NULL;
+	kfree(sc->ether.tx_ring);
+	sc->ether.tx_ring = NULL;
 }
 
 
diff -druN linux-2.6.39-libre/drivers/staging/sep/sep_driver.c linux-3.0-rc7-libre/drivers/staging/sep/sep_driver.c
--- linux-2.6.39-libre/drivers/staging/sep/sep_driver.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/sep/sep_driver.c	2011-07-11 19:51:52.000000000 -0400
@@ -1095,13 +1095,16 @@
 	if (num_pages > 1) {
 		lli_array[num_pages - 1].block_size =
 			(app_virt_addr + data_size) & (~PAGE_MASK);
+		if (lli_array[num_pages - 1].block_size == 0)
+			lli_array[num_pages - 1].block_size = PAGE_SIZE;
 
 		dev_warn(&sep->pdev->dev,
-			"lli_array[%x].bus_address is %08lx, lli_array[%x].block_size is %x\n",
+			"lli_array[%x].bus_address is "
+			"%08lx, lli_array[%x].block_size is %x\n",
 			num_pages - 1,
-			(unsigned long)lli_array[count].bus_address,
+			(unsigned long)lli_array[num_pages -1].bus_address,
 			num_pages - 1,
-			lli_array[count].block_size);
+			lli_array[num_pages -1].block_size);
 	}
 
 	/* Set output params according to the in_out flag */
diff -druN linux-2.6.39-libre/drivers/staging/sm7xx/smtcfb.c linux-3.0-rc7-libre/drivers/staging/sm7xx/smtcfb.c
--- linux-2.6.39-libre/drivers/staging/sm7xx/smtcfb.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/sm7xx/smtcfb.c	2011-07-11 19:51:52.000000000 -0400
@@ -8,21 +8,24 @@
  * Copyright (C) 2009 Lemote, Inc.
  * Author: Wu Zhangjin, wuzhangjin@gmail.com
  *
+ * Copyright (C) 2011 Igalia, S.L.
+ * Author: Javier M. Mellid <jmunhoz@igalia.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/Big endian support
- *	- Add 2D support for Lynx
- *	- Verified on2.6.19.2  Boyod.yang <boyod.yang@siliconmotion.com.cn>
+ *	- Verified on 2.6.19.2
+ *	Boyod.yang <boyod.yang@siliconmotion.com.cn>
  *
  * Version 0.09.2621.00.01
- *	- Only support Linux Kernel's version 2.6.21.
- *	Boyod.yang  <boyod.yang@siliconmotion.com.cn>
+ *	- Only support Linux Kernel's version 2.6.21
+ *	Boyod.yang <boyod.yang@siliconmotion.com.cn>
  *
  * Version 0.09
- *	- Only support Linux Kernel's version 2.6.12.
+ *	- Only support Linux Kernel's version 2.6.12
  *	Boyod.yang <boyod.yang@siliconmotion.com.cn>
  */
 
@@ -39,16 +42,16 @@
 #include <linux/pm.h>
 #endif
 
-struct screen_info smtc_screen_info;
-
 #include "smtcfb.h"
 
 #ifdef DEBUG
-#define smdbg(format, arg...)	printk(KERN_DEBUG format , ## arg)
+#define smdbg(format, arg...) printk(KERN_DEBUG format , ## arg)
 #else
 #define smdbg(format, arg...)
 #endif
 
+struct screen_info smtc_screen_info;
+
 /*
 * Private structure
 */
@@ -99,17 +102,17 @@
 static struct vesa_mode_table vesa_mode[] = {
 	{"0x301", 640,  480,  8},
 	{"0x303", 800,  600,  8},
-	{"0x305", 1024, 768,	8},
+	{"0x305", 1024, 768,  8},
 	{"0x307", 1280, 1024, 8},
 
 	{"0x311", 640,  480,  16},
 	{"0x314", 800,  600,  16},
-	{"0x317", 1024, 768,	16},
+	{"0x317", 1024, 768,  16},
 	{"0x31A", 1280, 1024, 16},
 
 	{"0x312", 640,  480,  24},
 	{"0x315", 800,  600,  24},
-	{"0x318", 1024, 768,	24},
+	{"0x318", 1024, 768,  24},
 	{"0x31B", 1280, 1024, 24},
 };
 
@@ -125,7 +128,30 @@
 	0x720
 };
 
-#define numSMTCchipIDs (sizeof(smtc_ChipIDs) / sizeof(u16))
+#define numSMTCchipIDs ARRAY_SIZE(smtc_ChipIDs)
+
+static struct fb_var_screeninfo smtcfb_var = {
+	.xres           = 1024,
+	.yres           = 600,
+	.xres_virtual   = 1024,
+	.yres_virtual   = 600,
+	.bits_per_pixel = 16,
+	.red            = {16, 8, 0},
+	.green          = {8, 8, 0},
+	.blue           = {0, 8, 0},
+	.activate       = FB_ACTIVATE_NOW,
+	.height         = -1,
+	.width          = -1,
+	.vmode          = FB_VMODE_NONINTERLACED,
+};
+
+static struct fb_fix_screeninfo smtcfb_fix = {
+	.id             = "sm712fb",
+	.type           = FB_TYPE_PACKED_PIXELS,
+	.visual         = FB_VISUAL_TRUECOLOR,
+	.line_length    = 800 * 3,
+	.accel          = FB_ACCEL_SMI_LYNX,
+};
 
 static void sm712_set_timing(struct smtcfb_info *sfb,
 			     struct par_info *ppar_info)
@@ -268,29 +294,6 @@
 	}
 }
 
-static struct fb_var_screeninfo smtcfb_var = {
-	.xres = 1024,
-	.yres = 600,
-	.xres_virtual = 1024,
-	.yres_virtual = 600,
-	.bits_per_pixel = 16,
-	.red = {16, 8, 0},
-	.green = {8, 8, 0},
-	.blue = {0, 8, 0},
-	.activate = FB_ACTIVATE_NOW,
-	.height = -1,
-	.width = -1,
-	.vmode = FB_VMODE_NONINTERLACED,
-};
-
-static struct fb_fix_screeninfo smtcfb_fix = {
-	.id = "sm712fb",
-	.type = FB_TYPE_PACKED_PIXELS,
-	.visual = FB_VISUAL_TRUECOLOR,
-	.line_length = 800 * 3,
-	.accel = FB_ACCEL_SMI_LYNX,
-};
-
 /* chan_to_field
  *
  * convert a colour value into a field position
@@ -604,20 +607,6 @@
 }
 #endif	/* ! __BIG_ENDIAN */
 
-static struct fb_ops smtcfb_ops = {
-	.owner = THIS_MODULE,
-	.fb_setcolreg = smtc_setcolreg,
-	.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,
-#endif
-
-};
-
 void smtcfb_setmode(struct smtcfb_info *sfb)
 {
 	switch (sfb->fb.var.bits_per_pixel) {
@@ -676,6 +665,47 @@
 	smtc_set_timing(sfb, &hw);
 }
 
+static int smtc_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
+{
+	/* sanity checks */
+	if (var->xres_virtual < var->xres)
+		var->xres_virtual = var->xres;
+
+	if (var->yres_virtual < var->yres)
+		var->yres_virtual = var->yres;
+
+	/* set valid default bpp */
+	if ((var->bits_per_pixel != 8)  && (var->bits_per_pixel != 16) &&
+	    (var->bits_per_pixel != 24) && (var->bits_per_pixel != 32))
+		var->bits_per_pixel = 16;
+
+	return 0;
+}
+
+static int smtc_set_par(struct fb_info *info)
+{
+	struct smtcfb_info *sfb = (struct smtcfb_info *)info;
+
+	smtcfb_setmode(sfb);
+
+	return 0;
+}
+
+static struct fb_ops smtcfb_ops = {
+	.owner        = THIS_MODULE,
+	.fb_check_var = smtc_check_var,
+	.fb_set_par   = smtc_set_par,
+	.fb_setcolreg = smtc_setcolreg,
+	.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,
+#endif
+};
+
 /*
  * Alloc struct smtcfb_info and assign the default value
  */
@@ -684,7 +714,7 @@
 {
 	struct smtcfb_info *sfb;
 
-	sfb = kzalloc(sizeof(struct smtcfb_info), GFP_KERNEL);
+	sfb = kzalloc(sizeof(*sfb), GFP_KERNEL);
 
 	if (!sfb)
 		return NULL;
@@ -753,7 +783,7 @@
 	sfb->fb.screen_base = smtc_VRAMBaseAddress;
 
 	if (!sfb->fb.screen_base) {
-		printk(KERN_INFO "%s: unable to map screen memory\n",
+		printk(KERN_ERR "%s: unable to map screen memory\n",
 				sfb->fb.fix.id);
 		return -ENOMEM;
 	}
@@ -796,7 +826,7 @@
  *	Returns zero.
  *
  */
-static int __init __maybe_unused sm712vga_setup(char *options)
+static int __init sm712vga_setup(char *options)
 {
 	int index;
 
@@ -812,7 +842,7 @@
 	smdbg("\nsm712vga_setup = %s\n", options);
 
 	for (index = 0;
-	     index < (sizeof(vesa_mode) / sizeof(struct vesa_mode_table));
+	     index < ARRAY_SIZE(vesa_mode);
 	     index++) {
 		if (strstr(options, vesa_mode[index].mode_index)) {
 			smtc_screen_info.lfb_width = vesa_mode[index].lfb_width;
@@ -846,7 +876,6 @@
 	err = pci_enable_device(pdev);	/* enable SMTC chip */
 	if (err)
 		return err;
-	err = -ENOMEM;
 
 	hw.chipID = ent->device;
 	sprintf(name, "sm%Xfb", hw.chipID);
@@ -909,7 +938,7 @@
 		}
 #endif
 		if (!smtc_RegBaseAddress) {
-			printk(KERN_INFO
+			printk(KERN_ERR
 				"%s: unable to map memory mapped IO\n",
 				sfb->fb.fix.id);
 			err = -ENOMEM;
@@ -944,7 +973,7 @@
 		smtc_seqw(0x6b, 0x02);
 		break;
 	default:
-		printk(KERN_INFO
+		printk(KERN_ERR
 		"No valid Silicon Motion display chip was detected!\n");
 
 		goto failed_fb;
@@ -976,8 +1005,8 @@
 
 	return 0;
 
- failed:
-	printk(KERN_INFO "Silicon Motion, Inc.  primary display init fail\n");
+failed:
+	printk(KERN_ERR "Silicon Motion, Inc.  primary display init fail\n");
 
 	smtc_unmap_smem(sfb);
 	smtc_unmap_mmio(sfb);
@@ -1016,13 +1045,10 @@
 }
 
 #ifdef CONFIG_PM
-/* Jason (08/14/2009)
- * suspend function, called when the suspend event is triggered
- */
-static int __maybe_unused smtcfb_suspend(struct pci_dev *pdev, pm_message_t msg)
+static int smtcfb_pci_suspend(struct device *device)
 {
+	struct pci_dev *pdev = to_pci_dev(device);
 	struct smtcfb_info *sfb;
-	int retv;
 
 	sfb = pci_get_drvdata(pdev);
 
@@ -1032,25 +1058,9 @@
 	smtc_seqw(0x20, (smtc_seqr(0x20) | 0xc0));
 	smtc_seqw(0x69, (smtc_seqr(0x69) & 0xf7));
 
-	switch (msg.event) {
-	case PM_EVENT_FREEZE:
-	case PM_EVENT_PRETHAW:
-		pdev->dev.power.power_state = msg;
-		return 0;
-	}
-
-	/* when doing suspend, call fb apis and pci apis */
-	if (msg.event == PM_EVENT_SUSPEND) {
-		console_lock();
-		fb_set_suspend(&sfb->fb, 1);
-		console_unlock();
-		retv = pci_save_state(pdev);
-		pci_disable_device(pdev);
-		retv = pci_choose_state(pdev, msg);
-		retv = pci_set_power_state(pdev, retv);
-	}
-
-	pdev->dev.power.power_state = msg;
+	console_lock();
+	fb_set_suspend(&sfb->fb, 1);
+	console_unlock();
 
 	/* additionally turn off all function blocks including internal PLLs */
 	smtc_seqw(0x21, 0xff);
@@ -1058,22 +1068,13 @@
 	return 0;
 }
 
-static int __maybe_unused smtcfb_resume(struct pci_dev *pdev)
+static int smtcfb_pci_resume(struct device *device)
 {
+	struct pci_dev *pdev = to_pci_dev(device);
 	struct smtcfb_info *sfb;
-	int retv;
 
 	sfb = pci_get_drvdata(pdev);
 
-	/* when resuming, restore pci data and fb cursor */
-	if (pdev->dev.power.power_state.event != PM_EVENT_FREEZE) {
-		retv = pci_set_power_state(pdev, PCI_D0);
-		pci_restore_state(pdev);
-		if (pci_enable_device(pdev))
-			return -1;
-		pci_set_master(pdev);
-	}
-
 	/* reinit hardware */
 	sm7xx_init_hw();
 	switch (hw.chipID) {
@@ -1108,22 +1109,30 @@
 
 	return 0;
 }
-#endif
 
-/* Jason (08/13/2009)
- * pci_driver struct used to wrap the original driver
- * so that it can be registered into the kernel and
- * the proper method would be called when suspending and resuming
- */
+static const struct dev_pm_ops sm7xx_pm_ops = {
+	.suspend = smtcfb_pci_suspend,
+	.resume = smtcfb_pci_resume,
+	.freeze = smtcfb_pci_suspend,
+	.thaw = smtcfb_pci_resume,
+	.poweroff = smtcfb_pci_suspend,
+	.restore = smtcfb_pci_resume,
+};
+
+#define SM7XX_PM_OPS (&sm7xx_pm_ops)
+
+#else  /* !CONFIG_PM */
+
+#define SM7XX_PM_OPS NULL
+
+#endif /* !CONFIG_PM */
+
 static struct pci_driver smtcfb_driver = {
 	.name = "smtcfb",
 	.id_table = smtcfb_pci_table,
 	.probe = smtcfb_pci_probe,
 	.remove = __devexit_p(smtcfb_pci_remove),
-#ifdef CONFIG_PM
-	.suspend = smtcfb_suspend,
-	.resume = smtcfb_resume,
-#endif
+	.driver.pm  = SM7XX_PM_OPS,
 };
 
 static int __init smtcfb_init(void)
diff -druN linux-2.6.39-libre/drivers/staging/sm7xx/smtcfb.h linux-3.0-rc7-libre/drivers/staging/sm7xx/smtcfb.h
--- linux-2.6.39-libre/drivers/staging/sm7xx/smtcfb.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/sm7xx/smtcfb.h	2011-07-11 19:51:52.000000000 -0400
@@ -30,11 +30,6 @@
 #define SCREEN_Y_RES      600
 #define SCREEN_BPP        16
 
-#ifndef FIELD_OFFSET
-#define FIELD_OFSFET(type, field) \
-	((unsigned long) (PUCHAR) & (((type *)0)->field))
-#endif
-
 /*Assume SM712 graphics chip has 4MB VRAM */
 #define SM712_VIDEOMEMORYSIZE	  0x00400000
 /*Assume SM722 graphics chip has 8MB VRAM */
@@ -790,4 +785,4 @@
 	 },
 };
 
-#define numVGAModes		(sizeof(VGAMode) / sizeof(struct ModeInit))
+#define numVGAModes		ARRAY_SIZE(VGAMode)
diff -druN linux-2.6.39-libre/drivers/staging/sm7xx/TODO linux-3.0-rc7-libre/drivers/staging/sm7xx/TODO
--- linux-2.6.39-libre/drivers/staging/sm7xx/TODO	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/sm7xx/TODO	2011-07-11 19:51:52.000000000 -0400
@@ -2,9 +2,7 @@
 - Dual head support
 - 2D acceleration support
 - use kernel coding style
-- checkpatch.pl clean
 - refine the code and remove unused code
-- use kernel framebuffer mode setting instead of hard code
 - move it to drivers/video/sm7xx/ or make it be drivers/video/sm7xxfb.c
 
 Please send any patches to Greg Kroah-Hartman <greg@kroah.com> and
diff -druN linux-2.6.39-libre/drivers/staging/tm6000/CARDLIST linux-3.0-rc7-libre/drivers/staging/tm6000/CARDLIST
--- linux-2.6.39-libre/drivers/staging/tm6000/CARDLIST	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/staging/tm6000/CARDLIST	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,16 @@
+  1 -> Generic tm5600 board                   (tm5600)          [6000:0001]
+  2 -> Generic tm6000 board                   (tm6000)          [6000:0001]
+  3 -> Generic tm6010 board                   (tm6010)          [6000:0002]
+  4 -> 10Moons UT821                          (tm5600)          [6000:0001]
+  5 -> 10Moons UT330                          (tm5600)
+  6 -> ADSTech Dual TV                        (tm6000)          [06e1:f332]
+  7 -> FreeCom and similar                    (tm6000)          [14aa:0620]
+  8 -> ADSTech Mini Dual TV                   (tm6000)          [06e1:b339]
+  9 -> Hauppauge WinTV HVR-900H/USB2 Stick    (tm6010)          [2040:6600,2040:6601,2040:6610,2040:6611]
+ 10 -> Beholder Wander                        (tm6010)          [6000:dec0]
+ 11 -> Beholder Voyager                       (tm6010)          [6000:dec1]
+ 12 -> TerraTec Cinergy Hybrid XE/Cinergy Hybrid Stick (tm6010) [0ccd:0086,0ccd:00a5]
+ 13 -> TwinHan TU501                          (tm6010)          [13d3:3240,13d3:3241,13d3:3243,13d3:3264]
+ 14 -> Beholder Wander Lite                   (tm6010)          [6000:dec2]
+ 15 -> Beholder Voyager Lite                  (tm6010)          [6000:dec3]
+
diff -druN linux-2.6.39-libre/drivers/staging/tm6000/tm6000-alsa.c linux-3.0-rc7-libre/drivers/staging/tm6000/tm6000-alsa.c
--- linux-2.6.39-libre/drivers/staging/tm6000/tm6000-alsa.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/tm6000/tm6000-alsa.c	2011-07-11 19:51:52.000000000 -0400
@@ -84,7 +84,6 @@
 
 	tm6000_set_audio_bitrate(core, 48000);
 
-	tm6000_set_reg(core, TM6010_REQ08_R01_A_INIT, 0x80);
 
 	return 0;
 }
@@ -101,8 +100,6 @@
 	/* Disables audio */
 	tm6000_set_reg_mask(core, TM6010_REQ07_RCC_ACTIVE_VIDEO_IF, 0x00, 0x40);
 
-	tm6000_set_reg(core, TM6010_REQ08_R01_A_INIT, 0);
-
 	return 0;
 }
 
diff -druN linux-2.6.39-libre/drivers/staging/tm6000/tm6000-cards.c linux-3.0-rc7-libre/drivers/staging/tm6000/tm6000-cards.c
--- linux-2.6.39-libre/drivers/staging/tm6000/tm6000-cards.c	2011-05-19 02:08:18.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/tm6000/tm6000-cards.c	2011-07-21 06:50:36.000000000 -0400
@@ -54,6 +54,11 @@
 #define TM6010_BOARD_BEHOLD_VOYAGER_LITE	15
 #define TM5600_BOARD_TERRATEC_GRABSTER		16
 
+#define is_generic(model) ((model == TM6000_BOARD_UNKNOWN) || \
+			   (model == TM5600_BOARD_GENERIC) || \
+			   (model == TM6000_BOARD_GENERIC) || \
+			   (model == TM6010_BOARD_GENERIC))
+
 #define TM6000_MAXBOARDS        16
 static unsigned int card[]     = {[0 ... (TM6000_MAXBOARDS - 1)] = UNSET };
 
@@ -64,10 +69,11 @@
 
 struct tm6000_board {
 	char            *name;
+	char		eename[16];		/* EEPROM name */
+	unsigned	eename_size;		/* size of EEPROM name */
+	unsigned	eename_pos;		/* Position where it appears at ROM */
 
 	struct tm6000_capabilities caps;
-	enum            tm6000_inaudio aradio;
-	enum            tm6000_inaudio avideo;
 
 	enum		tm6000_devtype type;	/* variant of the chipset */
 	int             tuner_type;     /* type of the tuner */
@@ -76,6 +82,9 @@
 
 	struct tm6000_gpio gpio;
 
+	struct tm6000_input	vinput[3];
+	struct tm6000_input	rinput;
+
 	char		*ir_codes;
 };
 
@@ -83,11 +92,26 @@
 	[TM6000_BOARD_UNKNOWN] = {
 		.name         = "Unknown tm6000 video grabber",
 		.caps = {
-			.has_tuner    = 1,
+			.has_tuner	= 1,
+			.has_eeprom	= 1,
 		},
 		.gpio = {
 			.tuner_reset	= TM6000_GPIO_1,
 		},
+		.vinput = { {
+			.type	= TM6000_INPUT_TV,
+			.vmux	= TM6000_VMUX_VIDEO_B,
+			.amux	= TM6000_AMUX_ADC1,
+			}, {
+			.type	= TM6000_INPUT_COMPOSITE1,
+			.vmux	= TM6000_VMUX_VIDEO_A,
+			.amux	= TM6000_AMUX_ADC2,
+			}, {
+			.type	= TM6000_INPUT_SVIDEO,
+			.vmux	= TM6000_VMUX_VIDEO_AB,
+			.amux	= TM6000_AMUX_ADC2,
+			},
+		},
 	},
 	[TM5600_BOARD_GENERIC] = {
 		.name         = "Generic tm5600 board",
@@ -96,10 +120,25 @@
 		.tuner_addr   = 0xc2 >> 1,
 		.caps = {
 			.has_tuner	= 1,
+			.has_eeprom	= 1,
 		},
 		.gpio = {
 			.tuner_reset	= TM6000_GPIO_1,
 		},
+		.vinput = { {
+			.type	= TM6000_INPUT_TV,
+			.vmux	= TM6000_VMUX_VIDEO_B,
+			.amux	= TM6000_AMUX_ADC1,
+			}, {
+			.type	= TM6000_INPUT_COMPOSITE1,
+			.vmux	= TM6000_VMUX_VIDEO_A,
+			.amux	= TM6000_AMUX_ADC2,
+			}, {
+			.type	= TM6000_INPUT_SVIDEO,
+			.vmux	= TM6000_VMUX_VIDEO_AB,
+			.amux	= TM6000_AMUX_ADC2,
+			},
+		},
 	},
 	[TM6000_BOARD_GENERIC] = {
 		.name         = "Generic tm6000 board",
@@ -107,11 +146,25 @@
 		.tuner_addr   = 0xc2 >> 1,
 		.caps = {
 			.has_tuner	= 1,
-			.has_dvb	= 1,
+			.has_eeprom	= 1,
 		},
 		.gpio = {
 			.tuner_reset	= TM6000_GPIO_1,
 		},
+		.vinput = { {
+			.type	= TM6000_INPUT_TV,
+			.vmux	= TM6000_VMUX_VIDEO_B,
+			.amux	= TM6000_AMUX_ADC1,
+			}, {
+			.type	= TM6000_INPUT_COMPOSITE1,
+			.vmux	= TM6000_VMUX_VIDEO_A,
+			.amux	= TM6000_AMUX_ADC2,
+			}, {
+			.type	= TM6000_INPUT_SVIDEO,
+			.vmux	= TM6000_VMUX_VIDEO_AB,
+			.amux	= TM6000_AMUX_ADC2,
+			},
+		},
 	},
 	[TM6010_BOARD_GENERIC] = {
 		.name         = "Generic tm6010 board",
@@ -135,10 +188,27 @@
 			.dvb_led	= TM6010_GPIO_5,
 			.ir		= TM6010_GPIO_0,
 		},
+		.vinput = { {
+			.type	= TM6000_INPUT_TV,
+			.vmux	= TM6000_VMUX_VIDEO_B,
+			.amux	= TM6000_AMUX_SIF1,
+			}, {
+			.type	= TM6000_INPUT_COMPOSITE1,
+			.vmux	= TM6000_VMUX_VIDEO_A,
+			.amux	= TM6000_AMUX_ADC2,
+			}, {
+			.type	= TM6000_INPUT_SVIDEO,
+			.vmux	= TM6000_VMUX_VIDEO_AB,
+			.amux	= TM6000_AMUX_ADC2,
+			},
+		},
 	},
 	[TM5600_BOARD_10MOONS_UT821] = {
 		.name         = "10Moons UT 821",
 		.tuner_type   = TUNER_XC2028,
+		.eename       = { '1', '0', 'M', 'O', 'O', 'N', 'S', '5', '6', '0', '0', 0xff, 0x45, 0x5b},
+		.eename_size  = 14,
+		.eename_pos   = 0x14,
 		.type         = TM5600,
 		.tuner_addr   = 0xc2 >> 1,
 		.caps = {
@@ -148,6 +218,20 @@
 		.gpio = {
 			.tuner_reset	= TM6000_GPIO_1,
 		},
+		.vinput = { {
+			.type	= TM6000_INPUT_TV,
+			.vmux	= TM6000_VMUX_VIDEO_B,
+			.amux	= TM6000_AMUX_ADC1,
+			}, {
+			.type	= TM6000_INPUT_COMPOSITE1,
+			.vmux	= TM6000_VMUX_VIDEO_A,
+			.amux	= TM6000_AMUX_ADC2,
+			}, {
+			.type	= TM6000_INPUT_SVIDEO,
+			.vmux	= TM6000_VMUX_VIDEO_AB,
+			.amux	= TM6000_AMUX_ADC2,
+			},
+		},
 	},
 	[TM5600_BOARD_10MOONS_UT330] = {
 		.name         = "10Moons UT 330",
@@ -159,6 +243,20 @@
 			.has_zl10353  = 0,
 			.has_eeprom   = 1,
 		},
+		.vinput = { {
+			.type	= TM6000_INPUT_TV,
+			.vmux	= TM6000_VMUX_VIDEO_B,
+			.amux	= TM6000_AMUX_ADC1,
+			}, {
+			.type	= TM6000_INPUT_COMPOSITE1,
+			.vmux	= TM6000_VMUX_VIDEO_A,
+			.amux	= TM6000_AMUX_ADC2,
+			}, {
+			.type	= TM6000_INPUT_SVIDEO,
+			.vmux	= TM6000_VMUX_VIDEO_AB,
+			.amux	= TM6000_AMUX_ADC2,
+			},
+		},
 	},
 	[TM6000_BOARD_ADSTECH_DUAL_TV] = {
 		.name         = "ADSTECH Dual TV USB",
@@ -171,6 +269,20 @@
 			.has_zl10353  = 1,
 			.has_eeprom   = 1,
 		},
+		.vinput = { {
+			.type	= TM6000_INPUT_TV,
+			.vmux	= TM6000_VMUX_VIDEO_B,
+			.amux	= TM6000_AMUX_ADC1,
+			}, {
+			.type	= TM6000_INPUT_COMPOSITE1,
+			.vmux	= TM6000_VMUX_VIDEO_A,
+			.amux	= TM6000_AMUX_ADC2,
+			}, {
+			.type	= TM6000_INPUT_SVIDEO,
+			.vmux	= TM6000_VMUX_VIDEO_AB,
+			.amux	= TM6000_AMUX_ADC2,
+			},
+		},
 	},
 	[TM6000_BOARD_FREECOM_AND_SIMILAR] = {
 		.name         = "Freecom Hybrid Stick / Moka DVB-T Receiver Dual",
@@ -187,6 +299,20 @@
 		.gpio = {
 			.tuner_reset	= TM6000_GPIO_4,
 		},
+		.vinput = { {
+			.type	= TM6000_INPUT_TV,
+			.vmux	= TM6000_VMUX_VIDEO_B,
+			.amux	= TM6000_AMUX_ADC1,
+			}, {
+			.type	= TM6000_INPUT_COMPOSITE1,
+			.vmux	= TM6000_VMUX_VIDEO_A,
+			.amux	= TM6000_AMUX_ADC2,
+			}, {
+			.type	= TM6000_INPUT_SVIDEO,
+			.vmux	= TM6000_VMUX_VIDEO_AB,
+			.amux	= TM6000_AMUX_ADC2,
+			},
+		},
 	},
 	[TM6000_BOARD_ADSTECH_MINI_DUAL_TV] = {
 		.name         = "ADSTECH Mini Dual TV USB",
@@ -202,9 +328,26 @@
 		.gpio = {
 			.tuner_reset	= TM6000_GPIO_4,
 		},
+		.vinput = { {
+			.type	= TM6000_INPUT_TV,
+			.vmux	= TM6000_VMUX_VIDEO_B,
+			.amux	= TM6000_AMUX_ADC1,
+			}, {
+			.type	= TM6000_INPUT_COMPOSITE1,
+			.vmux	= TM6000_VMUX_VIDEO_A,
+			.amux	= TM6000_AMUX_ADC2,
+			}, {
+			.type	= TM6000_INPUT_SVIDEO,
+			.vmux	= TM6000_VMUX_VIDEO_AB,
+			.amux	= TM6000_AMUX_ADC2,
+			},
+		},
 	},
 	[TM6010_BOARD_HAUPPAUGE_900H] = {
 		.name         = "Hauppauge WinTV HVR-900H / WinTV USB2-Stick",
+		.eename       = { 'H', 0, 'V', 0, 'R', 0, '9', 0, '0', 0, '0', 0, 'H', 0 },
+		.eename_size  = 14,
+		.eename_pos   = 0x42,
 		.tuner_type   = TUNER_XC2028, /* has a XC3028 */
 		.tuner_addr   = 0xc2 >> 1,
 		.demod_addr   = 0x1e >> 1,
@@ -225,6 +368,20 @@
 			.dvb_led	= TM6010_GPIO_5,
 			.ir		= TM6010_GPIO_0,
 		},
+		.vinput = { {
+			.type	= TM6000_INPUT_TV,
+			.vmux	= TM6000_VMUX_VIDEO_B,
+			.amux	= TM6000_AMUX_SIF1,
+			}, {
+			.type	= TM6000_INPUT_COMPOSITE1,
+			.vmux	= TM6000_VMUX_VIDEO_A,
+			.amux	= TM6000_AMUX_ADC2,
+			}, {
+			.type	= TM6000_INPUT_SVIDEO,
+			.vmux	= TM6000_VMUX_VIDEO_AB,
+			.amux	= TM6000_AMUX_ADC2,
+			},
+		},
 	},
 	[TM6010_BOARD_BEHOLD_WANDER] = {
 		.name         = "Beholder Wander DVB-T/TV/FM USB2.0",
@@ -232,43 +389,73 @@
 		.tuner_addr   = 0xc2 >> 1,
 		.demod_addr   = 0x1e >> 1,
 		.type         = TM6010,
-		.avideo       = TM6000_AIP_SIF1,
-		.aradio       = TM6000_AIP_LINE1,
 		.caps = {
 			.has_tuner      = 1,
 			.has_dvb        = 1,
 			.has_zl10353    = 1,
 			.has_eeprom     = 1,
 			.has_remote     = 1,
-			.has_input_comp = 1,
-			.has_input_svid = 1,
+			.has_radio	= 1.
 		},
 		.gpio = {
 			.tuner_reset	= TM6010_GPIO_0,
 			.demod_reset	= TM6010_GPIO_1,
 			.power_led	= TM6010_GPIO_6,
 		},
+		.vinput = { {
+			.type	= TM6000_INPUT_TV,
+			.vmux	= TM6000_VMUX_VIDEO_B,
+			.amux	= TM6000_AMUX_SIF1,
+			}, {
+			.type	= TM6000_INPUT_COMPOSITE1,
+			.vmux	= TM6000_VMUX_VIDEO_A,
+			.amux	= TM6000_AMUX_ADC2,
+			}, {
+			.type	= TM6000_INPUT_SVIDEO,
+			.vmux	= TM6000_VMUX_VIDEO_AB,
+			.amux	= TM6000_AMUX_ADC2,
+			},
+		},
+		.rinput = {
+			.type	= TM6000_INPUT_RADIO,
+			.amux	= TM6000_AMUX_ADC1,
+		},
 	},
 	[TM6010_BOARD_BEHOLD_VOYAGER] = {
 		.name         = "Beholder Voyager TV/FM USB2.0",
 		.tuner_type   = TUNER_XC5000,
 		.tuner_addr   = 0xc2 >> 1,
 		.type         = TM6010,
-		.avideo       = TM6000_AIP_SIF1,
-		.aradio       = TM6000_AIP_LINE1,
 		.caps = {
 			.has_tuner      = 1,
 			.has_dvb        = 0,
 			.has_zl10353    = 0,
 			.has_eeprom     = 1,
 			.has_remote     = 1,
-			.has_input_comp = 1,
-			.has_input_svid = 1,
+			.has_radio	= 1,
 		},
 		.gpio = {
 			.tuner_reset	= TM6010_GPIO_0,
 			.power_led	= TM6010_GPIO_6,
 		},
+		.vinput = { {
+			.type	= TM6000_INPUT_TV,
+			.vmux	= TM6000_VMUX_VIDEO_B,
+			.amux	= TM6000_AMUX_SIF1,
+			}, {
+			.type	= TM6000_INPUT_COMPOSITE1,
+			.vmux	= TM6000_VMUX_VIDEO_A,
+			.amux	= TM6000_AMUX_ADC2,
+			}, {
+			.type	= TM6000_INPUT_SVIDEO,
+			.vmux	= TM6000_VMUX_VIDEO_AB,
+			.amux	= TM6000_AMUX_ADC2,
+			},
+		},
+		.rinput = {
+			.type	= TM6000_INPUT_RADIO,
+			.amux	= TM6000_AMUX_ADC1,
+		},
 	},
 	[TM6010_BOARD_TERRATEC_CINERGY_HYBRID_XE] = {
 		.name         = "Terratec Cinergy Hybrid XE / Cinergy Hybrid-Stick",
@@ -293,11 +480,39 @@
 			.ir		= TM6010_GPIO_0,
 		},
 		.ir_codes = RC_MAP_NEC_TERRATEC_CINERGY_XS,
+		.vinput = { {
+			.type	= TM6000_INPUT_TV,
+			.vmux	= TM6000_VMUX_VIDEO_B,
+			.amux	= TM6000_AMUX_SIF1,
+			}, {
+			.type	= TM6000_INPUT_COMPOSITE1,
+			.vmux	= TM6000_VMUX_VIDEO_A,
+			.amux	= TM6000_AMUX_ADC2,
+			}, {
+			.type	= TM6000_INPUT_SVIDEO,
+			.vmux	= TM6000_VMUX_VIDEO_AB,
+			.amux	= TM6000_AMUX_ADC2,
+			},
+		},
 	},
 	[TM5600_BOARD_TERRATEC_GRABSTER] = {
 		.name         = "Terratec Grabster AV 150/250 MX",
 		.type         = TM5600,
 		.tuner_type   = TUNER_ABSENT,
+		.vinput = { {
+			.type	= TM6000_INPUT_TV,
+			.vmux	= TM6000_VMUX_VIDEO_B,
+			.amux	= TM6000_AMUX_ADC1,
+			}, {
+			.type	= TM6000_INPUT_COMPOSITE1,
+			.vmux	= TM6000_VMUX_VIDEO_A,
+			.amux	= TM6000_AMUX_ADC2,
+			}, {
+			.type	= TM6000_INPUT_SVIDEO,
+			.vmux	= TM6000_VMUX_VIDEO_AB,
+			.amux	= TM6000_AMUX_ADC2,
+			},
+		},
 	},
 	[TM6010_BOARD_TWINHAN_TU501] = {
 		.name         = "Twinhan TU501(704D1)",
@@ -321,6 +536,20 @@
 			.dvb_led	= TM6010_GPIO_5,
 			.ir		= TM6010_GPIO_0,
 		},
+		.vinput = { {
+			.type	= TM6000_INPUT_TV,
+			.vmux	= TM6000_VMUX_VIDEO_B,
+			.amux	= TM6000_AMUX_SIF1,
+			}, {
+			.type	= TM6000_INPUT_COMPOSITE1,
+			.vmux	= TM6000_VMUX_VIDEO_A,
+			.amux	= TM6000_AMUX_ADC2,
+			}, {
+			.type	= TM6000_INPUT_SVIDEO,
+			.vmux	= TM6000_VMUX_VIDEO_AB,
+			.amux	= TM6000_AMUX_ADC2,
+			},
+		},
 	},
 	[TM6010_BOARD_BEHOLD_WANDER_LITE] = {
 		.name         = "Beholder Wander Lite DVB-T/TV/FM USB2.0",
@@ -328,49 +557,63 @@
 		.tuner_addr   = 0xc2 >> 1,
 		.demod_addr   = 0x1e >> 1,
 		.type         = TM6010,
-		.avideo       = TM6000_AIP_SIF1,
-		.aradio       = TM6000_AIP_LINE1,
 		.caps = {
 			.has_tuner      = 1,
 			.has_dvb        = 1,
 			.has_zl10353    = 1,
 			.has_eeprom     = 1,
 			.has_remote     = 0,
-			.has_input_comp = 0,
-			.has_input_svid = 0,
+			.has_radio	= 1,
 		},
 		.gpio = {
 			.tuner_reset	= TM6010_GPIO_0,
 			.demod_reset	= TM6010_GPIO_1,
 			.power_led	= TM6010_GPIO_6,
 		},
+		.vinput = { {
+			.type	= TM6000_INPUT_TV,
+			.vmux	= TM6000_VMUX_VIDEO_B,
+			.amux	= TM6000_AMUX_SIF1,
+			},
+		},
+		.rinput = {
+			.type	= TM6000_INPUT_RADIO,
+			.amux	= TM6000_AMUX_ADC1,
+		},
 	},
 	[TM6010_BOARD_BEHOLD_VOYAGER_LITE] = {
 		.name         = "Beholder Voyager Lite TV/FM USB2.0",
 		.tuner_type   = TUNER_XC5000,
 		.tuner_addr   = 0xc2 >> 1,
 		.type         = TM6010,
-		.avideo       = TM6000_AIP_SIF1,
-		.aradio       = TM6000_AIP_LINE1,
 		.caps = {
 			.has_tuner      = 1,
 			.has_dvb        = 0,
 			.has_zl10353    = 0,
 			.has_eeprom     = 1,
 			.has_remote     = 0,
-			.has_input_comp = 0,
-			.has_input_svid = 0,
+			.has_radio	= 1,
 		},
 		.gpio = {
 			.tuner_reset	= TM6010_GPIO_0,
 			.power_led	= TM6010_GPIO_6,
 		},
+		.vinput = { {
+			.type	= TM6000_INPUT_TV,
+			.vmux	= TM6000_VMUX_VIDEO_B,
+			.amux	= TM6000_AMUX_SIF1,
+			},
+		},
+		.rinput = {
+			.type	= TM6000_INPUT_RADIO,
+			.amux	= TM6000_AMUX_ADC1,
+		},
 	},
 };
 
 /* table of devices that work with this driver */
 struct usb_device_id tm6000_id_table[] = {
-	{ USB_DEVICE(0x6000, 0x0001), .driver_info = TM5600_BOARD_10MOONS_UT821 },
+	{ USB_DEVICE(0x6000, 0x0001), .driver_info = TM5600_BOARD_GENERIC },
 	{ USB_DEVICE(0x6000, 0x0002), .driver_info = TM6010_BOARD_GENERIC },
 	{ USB_DEVICE(0x06e1, 0xf332), .driver_info = TM6000_BOARD_ADSTECH_DUAL_TV },
 	{ USB_DEVICE(0x14aa, 0x0620), .driver_info = TM6000_BOARD_FREECOM_AND_SIMILAR },
@@ -679,12 +922,8 @@
 		memset(&xc2028_cfg, 0, sizeof(xc2028_cfg));
 		memset(&ctl, 0, sizeof(ctl));
 
-		ctl.input1 = 1;
-		ctl.read_not_reliable = 0;
-		ctl.msleep = 10;
 		ctl.demod = XC3028_FE_ZARLINK456;
-		ctl.vhfbw7 = 1;
-		ctl.uhfbw8 = 1;
+
 		xc2028_cfg.tuner = TUNER_XC2028;
 		xc2028_cfg.priv  = &ctl;
 
@@ -729,16 +968,10 @@
 	}
 }
 
-static int tm6000_init_dev(struct tm6000_core *dev)
+static int fill_board_specific_data(struct tm6000_core *dev)
 {
-	struct v4l2_frequency f;
-	int rc = 0;
-
-	mutex_init(&dev->lock);
-
-	mutex_lock(&dev->lock);
+	int rc;
 
-	/* Initializa board-specific data */
 	dev->dev_type   = tm6000_boards[dev->model].type;
 	dev->tuner_type = tm6000_boards[dev->model].tuner_type;
 	dev->tuner_addr = tm6000_boards[dev->model].tuner_addr;
@@ -751,21 +984,85 @@
 
 	dev->caps = tm6000_boards[dev->model].caps;
 
-	dev->avideo = tm6000_boards[dev->model].avideo;
-	dev->aradio = tm6000_boards[dev->model].aradio;
+	dev->vinput[0] = tm6000_boards[dev->model].vinput[0];
+	dev->vinput[1] = tm6000_boards[dev->model].vinput[1];
+	dev->vinput[2] = tm6000_boards[dev->model].vinput[2];
+	dev->rinput = tm6000_boards[dev->model].rinput;
+
 	/* initialize hardware */
 	rc = tm6000_init(dev);
 	if (rc < 0)
-		goto err;
+		return rc;
 
 	rc = v4l2_device_register(&dev->udev->dev, &dev->v4l2_dev);
 	if (rc < 0)
-		goto err;
+		return rc;
 
-	/* register i2c bus */
-	rc = tm6000_i2c_register(dev);
-	if (rc < 0)
-		goto err;
+	return rc;
+}
+
+
+static void use_alternative_detection_method(struct tm6000_core *dev)
+{
+	int i, model = -1;
+
+	if (!dev->eedata_size)
+		return;
+
+	for (i = 0; i < ARRAY_SIZE(tm6000_boards); i++) {
+		if (!tm6000_boards[i].eename_size)
+			continue;
+		if (dev->eedata_size < tm6000_boards[i].eename_pos +
+				       tm6000_boards[i].eename_size)
+			continue;
+
+		if (!memcmp(&dev->eedata[tm6000_boards[i].eename_pos],
+			    tm6000_boards[i].eename,
+			    tm6000_boards[i].eename_size)) {
+			model = i;
+			break;
+		}
+	}
+	if (model < 0) {
+		printk(KERN_INFO "Device has eeprom but is currently unknown\n");
+		return;
+	}
+
+	dev->model = model;
+
+	printk(KERN_INFO "Device identified via eeprom as %s (type = %d)\n",
+	       tm6000_boards[model].name, model);
+}
+
+static int tm6000_init_dev(struct tm6000_core *dev)
+{
+	struct v4l2_frequency f;
+	int rc = 0;
+
+	mutex_init(&dev->lock);
+	mutex_lock(&dev->lock);
+
+	if (!is_generic(dev->model)) {
+		rc = fill_board_specific_data(dev);
+		if (rc < 0)
+			goto err;
+
+		/* register i2c bus */
+		rc = tm6000_i2c_register(dev);
+		if (rc < 0)
+			goto err;
+	} else {
+		/* register i2c bus */
+		rc = tm6000_i2c_register(dev);
+		if (rc < 0)
+			goto err;
+
+		use_alternative_detection_method(dev);
+
+		rc = fill_board_specific_data(dev);
+		if (rc < 0)
+			goto err;
+	}
 
 	/* Default values for STD and resolutions */
 	dev->width = 720;
diff -druN linux-2.6.39-libre/drivers/staging/tm6000/tm6000-core.c linux-3.0-rc7-libre/drivers/staging/tm6000/tm6000-core.c
--- linux-2.6.39-libre/drivers/staging/tm6000/tm6000-core.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/tm6000/tm6000-core.c	2011-07-11 19:51:52.000000000 -0400
@@ -268,19 +268,18 @@
 	struct v4l2_frequency f;
 
 	if (dev->dev_type == TM6010) {
-		/* Enable video */
-
+		/* Enable video and audio */
 		tm6000_set_reg_mask(dev, TM6010_REQ07_RCC_ACTIVE_VIDEO_IF,
 							0x60, 0x60);
+		/* Disable TS input */
 		tm6000_set_reg_mask(dev, TM6010_REQ07_RC0_ACTIVE_VIDEO_SOURCE,
 							0x00, 0x40);
-		tm6000_set_reg(dev, TM6010_REQ08_RF1_AADC_POWER_DOWN, 0xfc);
-
 	} else {
 		/* Enables soft reset */
 		tm6000_set_reg(dev, TM6010_REQ07_R3F_RESET, 0x01);
 
 		if (dev->scaler)
+			/* Disable Hfilter and Enable TS Drop err */
 			tm6000_set_reg(dev, TM6010_REQ07_RC0_ACTIVE_VIDEO_SOURCE, 0x20);
 		else	/* Enable Hfilter and disable TS Drop err */
 			tm6000_set_reg(dev, TM6010_REQ07_RC0_ACTIVE_VIDEO_SOURCE, 0x80);
@@ -300,14 +299,6 @@
 
 		/* Disables soft reset */
 		tm6000_set_reg(dev, TM6010_REQ07_R3F_RESET, 0x00);
-
-		/* E3: Select input 0 - TV tuner */
-		tm6000_set_reg(dev, TM6000_REQ07_RE3_VADC_INP_LPF_SEL1, 0x00);
-		tm6000_set_reg(dev, TM6000_REQ07_REB_VADC_AADC_MODE, 0x60);
-
-		/* This controls input */
-		tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN, TM6000_GPIO_2, 0x0);
-		tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN, TM6000_GPIO_3, 0x01);
 	}
 	msleep(20);
 
@@ -327,7 +318,7 @@
 	v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_frequency, &f);
 
 	msleep(100);
-	tm6000_set_standard(dev, &dev->norm);
+	tm6000_set_standard(dev);
 	tm6000_set_vbi(dev);
 	tm6000_set_audio_bitrate(dev, 48000);
 
@@ -343,21 +334,16 @@
 int tm6000_init_digital_mode(struct tm6000_core *dev)
 {
 	if (dev->dev_type == TM6010) {
-		int val;
-		u8 buf[2];
-
-		/* digital init */
-		val = tm6000_get_reg(dev, TM6010_REQ07_RCC_ACTIVE_VIDEO_IF, 0);
-		val &= ~0x60;
-		tm6000_set_reg(dev, TM6010_REQ07_RCC_ACTIVE_VIDEO_IF, val);
-		val = tm6000_get_reg(dev, TM6010_REQ07_RC0_ACTIVE_VIDEO_SOURCE, 0);
-		val |= 0x40;
-		tm6000_set_reg(dev, TM6010_REQ07_RC0_ACTIVE_VIDEO_SOURCE, val);
+		/* Disable video and audio */
+		tm6000_set_reg_mask(dev, TM6010_REQ07_RCC_ACTIVE_VIDEO_IF,
+				0x00, 0x60);
+		/* Enable TS input */
+		tm6000_set_reg_mask(dev, TM6010_REQ07_RC0_ACTIVE_VIDEO_SOURCE,
+				0x40, 0x40);
+		/* all power down, but not the digital data port */
 		tm6000_set_reg(dev, TM6010_REQ07_RFE_POWER_DOWN, 0x28);
 		tm6000_set_reg(dev, TM6010_REQ08_RE2_POWER_DOWN_CTRL1, 0xfc);
 		tm6000_set_reg(dev, TM6010_REQ08_RE6_POWER_DOWN_CTRL2, 0xff);
-		tm6000_read_write_usb(dev, 0xc0, 0x0e, 0x00c2, 0x0008, buf, 2);
-		printk(KERN_INFO"buf %#x %#x\n", buf[0], buf[1]);
 	} else  {
 		tm6000_set_reg(dev, TM6010_REQ07_RFF_SOFT_RESET, 0x08);
 		tm6000_set_reg(dev, TM6010_REQ07_RFF_SOFT_RESET, 0x00);
@@ -489,14 +475,6 @@
 	{ TM6010_REQ08_REB_SIF_GAIN_CTRL, 0xf0 },
 	{ TM6010_REQ08_REC_REVERSE_YC_CTRL, 0xc2 },
 	{ TM6010_REQ08_RF0_DAUDIO_INPUT_CONFIG, 0x60 },
-	{ TM6010_REQ08_R03_A_AUTO_GAIN_CTRL, 0x00},
-	{ TM6010_REQ08_R04_A_SIF_AMP_CTRL, 0x80},
-	{ TM6010_REQ08_R0C_A_ASD_THRES2, 0x0a},
-	{ TM6010_REQ08_R0D_A_AMD_THRES, 0x40},
-	{ TM6010_REQ08_R1A_A_NICAM_SER_MAX, 0x64},
-	{ TM6010_REQ08_R1B_A_NICAM_SER_MIN, 0x20},
-	{ TM6010_REQ08_R16_A_AGC_GAIN_MAX, 0xfe},
-	{ TM6010_REQ08_R17_A_AGC_GAIN_MIN, 0x01},
 	{ TM6010_REQ08_RF1_AADC_POWER_DOWN, 0xfc },
 
 	{ TM6010_REQ07_R3F_RESET, 0x01 },
@@ -657,24 +635,29 @@
 }
 EXPORT_SYMBOL_GPL(tm6000_set_audio_bitrate);
 
-int tm6000_set_audio_input(struct tm6000_core *dev, enum tm6000_inaudio ainp)
+int tm6000_set_audio_rinput(struct tm6000_core *dev)
 {
 	if (dev->dev_type == TM6010) {
 		/* Audio crossbar setting, default SIF1 */
-		u8 areg_f0 = 0x03;
+		u8 areg_f0;
 
-		switch (ainp) {
-		case TM6000_AIP_SIF1:
-		case TM6000_AIP_SIF2:
+		switch (dev->rinput.amux) {
+		case TM6000_AMUX_SIF1:
+		case TM6000_AMUX_SIF2:
 			areg_f0 = 0x03;
 			break;
-		case TM6000_AIP_LINE1:
+		case TM6000_AMUX_ADC1:
 			areg_f0 = 0x00;
 			break;
-		case TM6000_AIP_LINE2:
+		case TM6000_AMUX_ADC2:
 			areg_f0 = 0x08;
 			break;
+		case TM6000_AMUX_I2S:
+			areg_f0 = 0x04;
+			break;
 		default:
+			printk(KERN_INFO "%s: audio input dosn't support\n",
+				dev->name);
 			return 0;
 			break;
 		}
@@ -682,17 +665,18 @@
 		tm6000_set_reg_mask(dev, TM6010_REQ08_RF0_DAUDIO_INPUT_CONFIG,
 							areg_f0, 0x0f);
 	} else {
+		u8 areg_eb;
 		/* Audio setting, default LINE1 */
-		u8 areg_eb = 0x00;
-
-		switch (ainp) {
-		case TM6000_AIP_LINE1:
+		switch (dev->rinput.amux) {
+		case TM6000_AMUX_ADC1:
 			areg_eb = 0x00;
 			break;
-		case TM6000_AIP_LINE2:
+		case TM6000_AMUX_ADC2:
 			areg_eb = 0x04;
 			break;
 		default:
+			printk(KERN_INFO "%s: audio input dosn't support\n",
+				dev->name);
 			return 0;
 			break;
 		}
@@ -702,7 +686,6 @@
 	}
 	return 0;
 }
-EXPORT_SYMBOL_GPL(tm6000_set_audio_input);
 
 void tm6010_set_mute_sif(struct tm6000_core *dev, u8 mute)
 {
@@ -736,16 +719,16 @@
 
 int tm6000_tvaudio_set_mute(struct tm6000_core *dev, u8 mute)
 {
-	enum tm6000_inaudio ainp;
+	enum tm6000_mux mux;
 
 	if (dev->radio)
-		ainp = dev->aradio;
+		mux = dev->rinput.amux;
 	else
-		ainp = dev->avideo;
+		mux = dev->vinput[dev->input].amux;
 
-	switch (ainp) {
-	case TM6000_AIP_SIF1:
-	case TM6000_AIP_SIF2:
+	switch (mux) {
+	case TM6000_AMUX_SIF1:
+	case TM6000_AMUX_SIF2:
 		if (dev->dev_type == TM6010)
 			tm6010_set_mute_sif(dev, mute);
 		else {
@@ -755,8 +738,8 @@
 			return -EINVAL;
 		}
 		break;
-	case TM6000_AIP_LINE1:
-	case TM6000_AIP_LINE2:
+	case TM6000_AMUX_ADC1:
+	case TM6000_AMUX_ADC2:
 		tm6010_set_mute_adc(dev, mute);
 		break;
 	default:
@@ -765,7 +748,6 @@
 	}
 	return 0;
 }
-EXPORT_SYMBOL_GPL(tm6000_tvaudio_set_mute);
 
 void tm6010_set_volume_sif(struct tm6000_core *dev, int vol)
 {
@@ -797,17 +779,17 @@
 
 void tm6000_set_volume(struct tm6000_core *dev, int vol)
 {
-	enum tm6000_inaudio ainp;
+	enum tm6000_mux mux;
 
 	if (dev->radio) {
-		ainp = dev->aradio;
+		mux = dev->rinput.amux;
 		vol += 8; /* Offset to 0 dB */
 	} else
-		ainp = dev->avideo;
+		mux = dev->vinput[dev->input].amux;
 
-	switch (ainp) {
-	case TM6000_AIP_SIF1:
-	case TM6000_AIP_SIF2:
+	switch (mux) {
+	case TM6000_AMUX_SIF1:
+	case TM6000_AMUX_SIF2:
 		if (dev->dev_type == TM6010)
 			tm6010_set_volume_sif(dev, vol);
 		else
@@ -815,15 +797,14 @@
 					" SIF audio inputs. Please check the %s"
 					" configuration.\n", dev->name);
 		break;
-	case TM6000_AIP_LINE1:
-	case TM6000_AIP_LINE2:
+	case TM6000_AMUX_ADC1:
+	case TM6000_AMUX_ADC2:
 		tm6010_set_volume_adc(dev, vol);
 		break;
 	default:
 		break;
 	}
 }
-EXPORT_SYMBOL_GPL(tm6000_set_volume);
 
 static LIST_HEAD(tm6000_devlist);
 static DEFINE_MUTEX(tm6000_devlist_mutex);
diff -druN linux-2.6.39-libre/drivers/staging/tm6000/tm6000.h linux-3.0-rc7-libre/drivers/staging/tm6000/tm6000.h
--- linux-2.6.39-libre/drivers/staging/tm6000/tm6000.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/tm6000/tm6000.h	2011-07-11 19:51:52.000000000 -0400
@@ -40,11 +40,24 @@
 #define TM6000_VERSION KERNEL_VERSION(0, 0, 2)
 
 /* Inputs */
-
 enum tm6000_itype {
-	TM6000_INPUT_TV	= 0,
-	TM6000_INPUT_COMPOSITE,
+	TM6000_INPUT_TV	= 1,
+	TM6000_INPUT_COMPOSITE1,
+	TM6000_INPUT_COMPOSITE2,
 	TM6000_INPUT_SVIDEO,
+	TM6000_INPUT_DVB,
+	TM6000_INPUT_RADIO,
+};
+
+enum tm6000_mux {
+	TM6000_VMUX_VIDEO_A = 1,
+	TM6000_VMUX_VIDEO_B,
+	TM6000_VMUX_VIDEO_AB,
+	TM6000_AMUX_ADC1,
+	TM6000_AMUX_ADC2,
+	TM6000_AMUX_SIF1,
+	TM6000_AMUX_SIF2,
+	TM6000_AMUX_I2S,
 };
 
 enum tm6000_devtype {
@@ -53,12 +66,12 @@
 	TM6010,
 };
 
-enum tm6000_inaudio {
-	TM6000_AIP_UNK = 0,
-	TM6000_AIP_SIF1,
-	TM6000_AIP_SIF2,
-	TM6000_AIP_LINE1,
-	TM6000_AIP_LINE2,
+struct tm6000_input {
+	enum tm6000_itype	type;
+	enum tm6000_mux		vmux;
+	enum tm6000_mux		amux;
+	unsigned int		v_gpio;
+	unsigned int		a_gpio;
 };
 
 /* ------------------------------------------------------------------
@@ -129,8 +142,7 @@
 	unsigned int    has_zl10353:1;
 	unsigned int    has_eeprom:1;
 	unsigned int    has_remote:1;
-	unsigned int    has_input_comp:1;
-	unsigned int    has_input_svid:1;
+	unsigned int    has_radio:1;
 };
 
 struct tm6000_dvb {
@@ -167,6 +179,8 @@
 	int				model;		/* index in the device_data struct */
 	int				devno;		/* marks the number of this device */
 	enum tm6000_devtype		dev_type;	/* type of device */
+	unsigned char			eedata[256];	/* Eeprom data */
+	unsigned			eedata_size;	/* Size of the eeprom info */
 
 	v4l2_std_id                     norm;           /* Current norm */
 	int				width, height;	/* Selected resolution */
@@ -211,6 +225,9 @@
 	struct v4l2_device		v4l2_dev;
 
 	int				input;
+	struct tm6000_input		vinput[3];	/* video input */
+	struct tm6000_input		rinput;		/* radio input */
+
 	int				freq;
 	unsigned int			fourcc;
 
@@ -218,6 +235,7 @@
 
 	int				ctl_mute;             /* audio */
 	int				ctl_volume;
+	int				amode;
 
 	/* DVB-T support */
 	struct tm6000_dvb		*dvb;
@@ -226,8 +244,6 @@
 	struct snd_tm6000_card		*adev;
 	struct work_struct		wq_trigger;   /* Trigger to start/stop audio for alsa module */
 	atomic_t			stream_started;  /* stream should be running if true */
-	enum tm6000_inaudio		avideo;
-	enum tm6000_inaudio		aradio;
 
 	struct tm6000_IR		*ir;
 
@@ -302,7 +318,7 @@
 int tm6000_init_analog_mode(struct tm6000_core *dev);
 int tm6000_init_digital_mode(struct tm6000_core *dev);
 int tm6000_set_audio_bitrate(struct tm6000_core *dev, int bitrate);
-int tm6000_set_audio_input(struct tm6000_core *dev, enum tm6000_inaudio ainp);
+int tm6000_set_audio_rinput(struct tm6000_core *dev);
 int tm6000_tvaudio_set_mute(struct tm6000_core *dev, u8 mute);
 void tm6000_set_volume(struct tm6000_core *dev, int vol);
 
@@ -323,7 +339,7 @@
 
 /* In tm6000-stds.c */
 void tm6000_get_std_res(struct tm6000_core *dev);
-int tm6000_set_standard(struct tm6000_core *dev, v4l2_std_id *norm);
+int tm6000_set_standard(struct tm6000_core *dev);
 
 /* In tm6000-i2c.c */
 int tm6000_i2c_register(struct tm6000_core *dev);
diff -druN linux-2.6.39-libre/drivers/staging/tm6000/tm6000-i2c.c linux-3.0-rc7-libre/drivers/staging/tm6000/tm6000-i2c.c
--- linux-2.6.39-libre/drivers/staging/tm6000/tm6000-i2c.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/tm6000/tm6000-i2c.c	2011-07-11 19:51:52.000000000 -0400
@@ -237,35 +237,36 @@
 	return rc;
 }
 
-static int tm6000_i2c_eeprom(struct tm6000_core *dev,
-			     unsigned char *eedata, int len)
+static int tm6000_i2c_eeprom(struct tm6000_core *dev)
 {
 	int i, rc;
-	unsigned char *p = eedata;
+	unsigned char *p = dev->eedata;
 	unsigned char bytes[17];
 
 	dev->i2c_client.addr = 0xa0 >> 1;
+	dev->eedata_size = 0;
 
 	bytes[16] = '\0';
-	for (i = 0; i < len; ) {
-	*p = i;
-	rc = tm6000_i2c_recv_regs(dev, 0xa0, i, p, 1);
+	for (i = 0; i < sizeof(dev->eedata); ) {
+		*p = i;
+		rc = tm6000_i2c_recv_regs(dev, 0xa0, i, p, 1);
 		if (rc < 1) {
-			if (p == eedata)
+			if (p == dev->eedata)
 				goto noeeprom;
 			else {
 				printk(KERN_WARNING
 				"%s: i2c eeprom read error (err=%d)\n",
 				dev->name, rc);
 			}
-			return -1;
+			return -EINVAL;
 		}
+		dev->eedata_size++;
 		p++;
 		if (0 == (i % 16))
 			printk(KERN_INFO "%s: i2c eeprom %02x:", dev->name, i);
-		printk(" %02x", eedata[i]);
-		if ((eedata[i] >= ' ') && (eedata[i] <= 'z'))
-			bytes[i%16] = eedata[i];
+		printk(" %02x", dev->eedata[i]);
+		if ((dev->eedata[i] >= ' ') && (dev->eedata[i] <= 'z'))
+			bytes[i%16] = dev->eedata[i];
 		else
 			bytes[i%16] = '.';
 
@@ -280,15 +281,15 @@
 		bytes[i%16] = '\0';
 		for (i %= 16; i < 16; i++)
 			printk("   ");
+		printk("  %s\n", bytes);
 	}
-	printk("  %s\n", bytes);
 
 	return 0;
 
 noeeprom:
 	printk(KERN_INFO "%s: Huh, no eeprom present (err=%d)?\n",
-		       dev->name, rc);
-	return rc;
+	       dev->name, rc);
+	return -EINVAL;
 }
 
 /* ----------------------------------------------------------- */
@@ -314,7 +315,6 @@
  */
 int tm6000_i2c_register(struct tm6000_core *dev)
 {
-	unsigned char eedata[256];
 	int rc;
 
 	dev->i2c_adap.owner = THIS_MODULE;
@@ -329,8 +329,7 @@
 
 	dev->i2c_client.adapter = &dev->i2c_adap;
 	strlcpy(dev->i2c_client.name, "tm6000 internal", I2C_NAME_SIZE);
-
-	tm6000_i2c_eeprom(dev, eedata, sizeof(eedata));
+	tm6000_i2c_eeprom(dev);
 
 	return 0;
 }
diff -druN linux-2.6.39-libre/drivers/staging/tm6000/tm6000-stds.c linux-3.0-rc7-libre/drivers/staging/tm6000/tm6000-stds.c
--- linux-2.6.39-libre/drivers/staging/tm6000/tm6000-stds.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/tm6000/tm6000-stds.c	2011-07-11 19:51:52.000000000 -0400
@@ -22,422 +22,26 @@
 #include "tm6000.h"
 #include "tm6000-regs.h"
 
+static unsigned int tm6010_a_mode = 0;
+module_param(tm6010_a_mode, int, 0644);
+MODULE_PARM_DESC(tm6010_a_mode, "set tm6010 sif audio mode");
+
 struct tm6000_reg_settings {
 	unsigned char req;
 	unsigned char reg;
 	unsigned char value;
 };
 
-enum tm6000_audio_std {
-	BG_NICAM,
-	BTSC,
-	BG_A2,
-	DK_NICAM,
-	EIAJ,
-	FM_RADIO,
-	I_NICAM,
-	KOREA_A2,
-	L_NICAM,
-};
-
-struct tm6000_std_tv_settings {
-	v4l2_std_id id;
-	enum tm6000_audio_std audio_default_std;
-
-	struct tm6000_reg_settings sif[12];
-	struct tm6000_reg_settings nosif[12];
-	struct tm6000_reg_settings common[26];
-};
 
 struct tm6000_std_settings {
 	v4l2_std_id id;
-	enum tm6000_audio_std audio_default_std;
-	struct tm6000_reg_settings common[37];
-};
-
-static struct tm6000_std_tv_settings tv_stds[] = {
-	{
-		.id = V4L2_STD_PAL_M,
-		.audio_default_std = BTSC,
-		.sif = {
-			{TM6010_REQ08_RE2_POWER_DOWN_CTRL1, 0xf2},
-			{TM6010_REQ08_RE3_ADC_IN1_SEL, 0xf8},
-			{TM6010_REQ08_RE4_ADC_IN2_SEL, 0xf3},
-			{TM6010_REQ08_RE6_POWER_DOWN_CTRL2, 0x08},
-			{TM6010_REQ08_REA_BUFF_DRV_CTRL, 0xf1},
-			{TM6010_REQ08_REB_SIF_GAIN_CTRL, 0xe0},
-			{TM6010_REQ08_REC_REVERSE_YC_CTRL, 0xc2},
-			{TM6010_REQ08_RED_GAIN_SEL, 0xe8},
-			{TM6010_REQ08_RF0_DAUDIO_INPUT_CONFIG, 0x62},
-			{TM6010_REQ08_RF1_AADC_POWER_DOWN, 0xfe},
-			{TM6010_REQ07_RFE_POWER_DOWN, 0xcb},
-			{0, 0, 0},
-		},
-		.nosif = {
-			{TM6010_REQ08_RE2_POWER_DOWN_CTRL1, 0xf0},
-			{TM6010_REQ08_RE3_ADC_IN1_SEL, 0xf8},
-			{TM6010_REQ08_RE4_ADC_IN2_SEL, 0xf3},
-			{TM6010_REQ08_RE6_POWER_DOWN_CTRL2, 0x0f},
-			{TM6010_REQ08_REA_BUFF_DRV_CTRL, 0xf1},
-			{TM6010_REQ08_REB_SIF_GAIN_CTRL, 0xe0},
-			{TM6010_REQ08_REC_REVERSE_YC_CTRL, 0xc2},
-			{TM6010_REQ08_RED_GAIN_SEL, 0xe8},
-			{TM6010_REQ08_RF0_DAUDIO_INPUT_CONFIG, 0x60},
-			{TM6010_REQ08_RF1_AADC_POWER_DOWN, 0xfc},
-			{TM6010_REQ07_RFE_POWER_DOWN, 0x8b},
-			{0, 0, 0},
-		},
-		.common = {
-			{TM6010_REQ07_R3F_RESET, 0x01},
-			{TM6010_REQ07_R00_VIDEO_CONTROL0, 0x04},
-			{TM6010_REQ07_R01_VIDEO_CONTROL1, 0x0e},
-			{TM6010_REQ07_R02_VIDEO_CONTROL2, 0x5f},
-			{TM6010_REQ07_R03_YC_SEP_CONTROL, 0x00},
-			{TM6010_REQ07_R07_OUTPUT_CONTROL, 0x31},
-			{TM6010_REQ07_R18_CHROMA_DTO_INCREMENT3, 0x1e},
-			{TM6010_REQ07_R19_CHROMA_DTO_INCREMENT2, 0x83},
-			{TM6010_REQ07_R1A_CHROMA_DTO_INCREMENT1, 0x0a},
-			{TM6010_REQ07_R1B_CHROMA_DTO_INCREMENT0, 0xe0},
-			{TM6010_REQ07_R1C_HSYNC_DTO_INCREMENT3, 0x1c},
-			{TM6010_REQ07_R1D_HSYNC_DTO_INCREMENT2, 0xcc},
-			{TM6010_REQ07_R1E_HSYNC_DTO_INCREMENT1, 0xcc},
-			{TM6010_REQ07_R1F_HSYNC_DTO_INCREMENT0, 0xcd},
-			{TM6010_REQ07_R2E_ACTIVE_VIDEO_HSTART, 0x88},
-			{TM6010_REQ07_R30_ACTIVE_VIDEO_VSTART, 0x20},
-			{TM6010_REQ07_R31_ACTIVE_VIDEO_VHIGHT, 0x61},
-			{TM6010_REQ07_R33_VSYNC_HLOCK_MAX, 0x0c},
-			{TM6010_REQ07_R35_VSYNC_AGC_MAX, 0x1c},
-			{TM6010_REQ07_R82_COMB_FILTER_CONFIG, 0x52},
-			{TM6010_REQ07_R83_CHROMA_LOCK_CONFIG, 0x6F},
-
-			{TM6010_REQ07_R04_LUMA_HAGC_CONTROL, 0xdc},
-			{TM6010_REQ07_R0D_CHROMA_KILL_LEVEL, 0x07},
-
-			{TM6010_REQ07_R3F_RESET, 0x00},
-
-			{0, 0, 0},
-		},
-	}, {
-		.id = V4L2_STD_PAL_Nc,
-		.audio_default_std = BTSC,
-		.sif = {
-			{TM6010_REQ08_RE2_POWER_DOWN_CTRL1, 0xf2},
-			{TM6010_REQ08_RE3_ADC_IN1_SEL, 0xf8},
-			{TM6010_REQ08_RE4_ADC_IN2_SEL, 0xf3},
-			{TM6010_REQ08_RE6_POWER_DOWN_CTRL2, 0x08},
-			{TM6010_REQ08_REA_BUFF_DRV_CTRL, 0xf1},
-			{TM6010_REQ08_REB_SIF_GAIN_CTRL, 0xe0},
-			{TM6010_REQ08_REC_REVERSE_YC_CTRL, 0xc2},
-			{TM6010_REQ08_RED_GAIN_SEL, 0xe8},
-			{TM6010_REQ08_RF0_DAUDIO_INPUT_CONFIG, 0x62},
-			{TM6010_REQ08_RF1_AADC_POWER_DOWN, 0xfe},
-			{TM6010_REQ07_RFE_POWER_DOWN, 0xcb},
-			{0, 0, 0},
-		},
-		.nosif = {
-			{TM6010_REQ08_RE2_POWER_DOWN_CTRL1, 0xf0},
-			{TM6010_REQ08_RE3_ADC_IN1_SEL, 0xf8},
-			{TM6010_REQ08_RE4_ADC_IN2_SEL, 0xf3},
-			{TM6010_REQ08_RE6_POWER_DOWN_CTRL2, 0x0f},
-			{TM6010_REQ08_REA_BUFF_DRV_CTRL, 0xf1},
-			{TM6010_REQ08_REB_SIF_GAIN_CTRL, 0xe0},
-			{TM6010_REQ08_REC_REVERSE_YC_CTRL, 0xc2},
-			{TM6010_REQ08_RED_GAIN_SEL, 0xe8},
-			{TM6010_REQ08_RF0_DAUDIO_INPUT_CONFIG, 0x60},
-			{TM6010_REQ08_RF1_AADC_POWER_DOWN, 0xfc},
-			{TM6010_REQ07_RFE_POWER_DOWN, 0x8b},
-			{0, 0, 0},
-		},
-		.common = {
-			{TM6010_REQ07_R3F_RESET, 0x01},
-			{TM6010_REQ07_R00_VIDEO_CONTROL0, 0x36},
-			{TM6010_REQ07_R01_VIDEO_CONTROL1, 0x0e},
-			{TM6010_REQ07_R02_VIDEO_CONTROL2, 0x5f},
-			{TM6010_REQ07_R03_YC_SEP_CONTROL, 0x02},
-			{TM6010_REQ07_R07_OUTPUT_CONTROL, 0x31},
-			{TM6010_REQ07_R18_CHROMA_DTO_INCREMENT3, 0x1e},
-			{TM6010_REQ07_R19_CHROMA_DTO_INCREMENT2, 0x91},
-			{TM6010_REQ07_R1A_CHROMA_DTO_INCREMENT1, 0x1f},
-			{TM6010_REQ07_R1B_CHROMA_DTO_INCREMENT0, 0x0c},
-			{TM6010_REQ07_R1C_HSYNC_DTO_INCREMENT3, 0x1c},
-			{TM6010_REQ07_R1D_HSYNC_DTO_INCREMENT2, 0xcc},
-			{TM6010_REQ07_R1E_HSYNC_DTO_INCREMENT1, 0xcc},
-			{TM6010_REQ07_R1F_HSYNC_DTO_INCREMENT0, 0xcd},
-			{TM6010_REQ07_R2E_ACTIVE_VIDEO_HSTART, 0x8c},
-			{TM6010_REQ07_R30_ACTIVE_VIDEO_VSTART, 0x2c},
-			{TM6010_REQ07_R31_ACTIVE_VIDEO_VHIGHT, 0xc1},
-			{TM6010_REQ07_R33_VSYNC_HLOCK_MAX, 0x0c},
-			{TM6010_REQ07_R35_VSYNC_AGC_MAX, 0x1c},
-			{TM6010_REQ07_R82_COMB_FILTER_CONFIG, 0x52},
-			{TM6010_REQ07_R83_CHROMA_LOCK_CONFIG, 0x6F},
-
-			{TM6010_REQ07_R04_LUMA_HAGC_CONTROL, 0xdc},
-			{TM6010_REQ07_R0D_CHROMA_KILL_LEVEL, 0x07},
-
-			{TM6010_REQ07_R3F_RESET, 0x00},
-
-			{0, 0, 0},
-		},
-	}, {
-		.id = V4L2_STD_PAL,
-		.audio_default_std = BG_A2,
-		.sif = {
-			{TM6010_REQ08_RE2_POWER_DOWN_CTRL1, 0xf2},
-			{TM6010_REQ08_RE3_ADC_IN1_SEL, 0xf8},
-			{TM6010_REQ08_RE4_ADC_IN2_SEL, 0xf3},
-			{TM6010_REQ08_RE6_POWER_DOWN_CTRL2, 0x08},
-			{TM6010_REQ08_REA_BUFF_DRV_CTRL, 0xf1},
-			{TM6010_REQ08_REB_SIF_GAIN_CTRL, 0xe0},
-			{TM6010_REQ08_REC_REVERSE_YC_CTRL, 0xc2},
-			{TM6010_REQ08_RED_GAIN_SEL, 0xe8},
-			{TM6010_REQ08_RF0_DAUDIO_INPUT_CONFIG, 0x62},
-			{TM6010_REQ08_RF1_AADC_POWER_DOWN, 0xfe},
-			{TM6010_REQ07_RFE_POWER_DOWN, 0xcb},
-			{0, 0, 0}
-		},
-		.nosif = {
-			{TM6010_REQ08_RE2_POWER_DOWN_CTRL1, 0xf0},
-			{TM6010_REQ08_RE3_ADC_IN1_SEL, 0xf8},
-			{TM6010_REQ08_RE4_ADC_IN2_SEL, 0xf3},
-			{TM6010_REQ08_RE6_POWER_DOWN_CTRL2, 0x0f},
-			{TM6010_REQ08_REA_BUFF_DRV_CTRL, 0xf1},
-			{TM6010_REQ08_REB_SIF_GAIN_CTRL, 0xe0},
-			{TM6010_REQ08_REC_REVERSE_YC_CTRL, 0xc2},
-			{TM6010_REQ08_RED_GAIN_SEL, 0xe8},
-			{TM6010_REQ08_RF0_DAUDIO_INPUT_CONFIG, 0x60},
-			{TM6010_REQ08_RF1_AADC_POWER_DOWN, 0xfc},
-			{TM6010_REQ07_RFE_POWER_DOWN, 0x8b},
-			{0, 0, 0},
-		},
-		.common = {
-			{TM6010_REQ07_R3F_RESET, 0x01},
-			{TM6010_REQ07_R00_VIDEO_CONTROL0, 0x32},
-			{TM6010_REQ07_R01_VIDEO_CONTROL1, 0x0e},
-			{TM6010_REQ07_R02_VIDEO_CONTROL2, 0x5f},
-			{TM6010_REQ07_R03_YC_SEP_CONTROL, 0x02},
-			{TM6010_REQ07_R07_OUTPUT_CONTROL, 0x31},
-			{TM6010_REQ07_R18_CHROMA_DTO_INCREMENT3, 0x25},
-			{TM6010_REQ07_R19_CHROMA_DTO_INCREMENT2, 0xd5},
-			{TM6010_REQ07_R1A_CHROMA_DTO_INCREMENT1, 0x63},
-			{TM6010_REQ07_R1B_CHROMA_DTO_INCREMENT0, 0x50},
-			{TM6010_REQ07_R1C_HSYNC_DTO_INCREMENT3, 0x1c},
-			{TM6010_REQ07_R1D_HSYNC_DTO_INCREMENT2, 0xcc},
-			{TM6010_REQ07_R1E_HSYNC_DTO_INCREMENT1, 0xcc},
-			{TM6010_REQ07_R1F_HSYNC_DTO_INCREMENT0, 0xcd},
-			{TM6010_REQ07_R2E_ACTIVE_VIDEO_HSTART, 0x8c},
-			{TM6010_REQ07_R30_ACTIVE_VIDEO_VSTART, 0x2c},
-			{TM6010_REQ07_R31_ACTIVE_VIDEO_VHIGHT, 0xc1},
-			{TM6010_REQ07_R33_VSYNC_HLOCK_MAX, 0x0c},
-			{TM6010_REQ07_R35_VSYNC_AGC_MAX, 0x1c},
-			{TM6010_REQ07_R82_COMB_FILTER_CONFIG, 0x52},
-			{TM6010_REQ07_R83_CHROMA_LOCK_CONFIG, 0x6F},
-
-			{TM6010_REQ07_R04_LUMA_HAGC_CONTROL, 0xdc},
-			{TM6010_REQ07_R0D_CHROMA_KILL_LEVEL, 0x07},
-
-			{TM6010_REQ07_R3F_RESET, 0x00},
-
-			{0, 0, 0},
-		},
-	}, {
-		.id = V4L2_STD_SECAM_B | V4L2_STD_SECAM_G,
-		.audio_default_std = BG_NICAM,
-		.sif = {
-			{TM6010_REQ08_RE2_POWER_DOWN_CTRL1, 0xf2},
-			{TM6010_REQ08_RE3_ADC_IN1_SEL, 0xf8},
-			{TM6010_REQ08_RE4_ADC_IN2_SEL, 0xf3},
-			{TM6010_REQ08_RE6_POWER_DOWN_CTRL2, 0x08},
-			{TM6010_REQ08_REA_BUFF_DRV_CTRL, 0xf1},
-			{TM6010_REQ08_REB_SIF_GAIN_CTRL, 0xe0},
-			{TM6010_REQ08_REC_REVERSE_YC_CTRL, 0xc2},
-			{TM6010_REQ08_RED_GAIN_SEL, 0xe8},
-			{TM6010_REQ08_RF0_DAUDIO_INPUT_CONFIG, 0x62},
-			{TM6010_REQ08_RF1_AADC_POWER_DOWN, 0xfe},
-			{TM6010_REQ07_RFE_POWER_DOWN, 0xcb},
-			{0, 0, 0},
-		},
-		.nosif = {
-			{TM6010_REQ08_RE2_POWER_DOWN_CTRL1, 0xf0},
-			{TM6010_REQ08_RE3_ADC_IN1_SEL, 0xf8},
-			{TM6010_REQ08_RE4_ADC_IN2_SEL, 0xf3},
-			{TM6010_REQ08_RE6_POWER_DOWN_CTRL2, 0x0f},
-			{TM6010_REQ08_REA_BUFF_DRV_CTRL, 0xf1},
-			{TM6010_REQ08_REB_SIF_GAIN_CTRL, 0xe0},
-			{TM6010_REQ08_REC_REVERSE_YC_CTRL, 0xc2},
-			{TM6010_REQ08_RED_GAIN_SEL, 0xe8},
-			{TM6010_REQ08_RF0_DAUDIO_INPUT_CONFIG, 0x60},
-			{TM6010_REQ08_RF1_AADC_POWER_DOWN, 0xfc},
-			{TM6010_REQ07_RFE_POWER_DOWN, 0x8b},
-			{0, 0, 0},
-		},
-		.common = {
-			{TM6010_REQ07_R3F_RESET, 0x01},
-			{TM6010_REQ07_R00_VIDEO_CONTROL0, 0x38},
-			{TM6010_REQ07_R01_VIDEO_CONTROL1, 0x0e},
-			{TM6010_REQ07_R02_VIDEO_CONTROL2, 0x5f},
-			{TM6010_REQ07_R03_YC_SEP_CONTROL, 0x02},
-			{TM6010_REQ07_R07_OUTPUT_CONTROL, 0x31},
-			{TM6010_REQ07_R18_CHROMA_DTO_INCREMENT3, 0x24},
-			{TM6010_REQ07_R19_CHROMA_DTO_INCREMENT2, 0x92},
-			{TM6010_REQ07_R1A_CHROMA_DTO_INCREMENT1, 0xe8},
-			{TM6010_REQ07_R1B_CHROMA_DTO_INCREMENT0, 0xed},
-			{TM6010_REQ07_R1C_HSYNC_DTO_INCREMENT3, 0x1c},
-			{TM6010_REQ07_R1D_HSYNC_DTO_INCREMENT2, 0xcc},
-			{TM6010_REQ07_R1E_HSYNC_DTO_INCREMENT1, 0xcc},
-			{TM6010_REQ07_R1F_HSYNC_DTO_INCREMENT0, 0xcd},
-			{TM6010_REQ07_R2E_ACTIVE_VIDEO_HSTART, 0x8c},
-			{TM6010_REQ07_R30_ACTIVE_VIDEO_VSTART, 0x2c},
-			{TM6010_REQ07_R31_ACTIVE_VIDEO_VHIGHT, 0xc1},
-			{TM6010_REQ07_R33_VSYNC_HLOCK_MAX, 0x2c},
-			{TM6010_REQ07_R35_VSYNC_AGC_MAX, 0x18},
-			{TM6010_REQ07_R82_COMB_FILTER_CONFIG, 0x42},
-			{TM6010_REQ07_R83_CHROMA_LOCK_CONFIG, 0xFF},
-
-			{TM6010_REQ07_R0D_CHROMA_KILL_LEVEL, 0x07},
-
-			{TM6010_REQ07_R3F_RESET, 0x00},
-			{0, 0, 0},
-		},
-	}, {
-		.id = V4L2_STD_SECAM_DK,
-		.audio_default_std = DK_NICAM,
-		.sif = {
-			{TM6010_REQ08_RE2_POWER_DOWN_CTRL1, 0xf2},
-			{TM6010_REQ08_RE3_ADC_IN1_SEL, 0xf8},
-			{TM6010_REQ08_RE4_ADC_IN2_SEL, 0xf3},
-			{TM6010_REQ08_RE6_POWER_DOWN_CTRL2, 0x08},
-			{TM6010_REQ08_REA_BUFF_DRV_CTRL, 0xf1},
-			{TM6010_REQ08_REB_SIF_GAIN_CTRL, 0xe0},
-			{TM6010_REQ08_REC_REVERSE_YC_CTRL, 0xc2},
-			{TM6010_REQ08_RED_GAIN_SEL, 0xe8},
-			{TM6010_REQ08_RF0_DAUDIO_INPUT_CONFIG, 0x62},
-			{TM6010_REQ08_RF1_AADC_POWER_DOWN, 0xfe},
-			{TM6010_REQ07_RFE_POWER_DOWN, 0xcb},
-			{0, 0, 0},
-		},
-		.nosif = {
-			{TM6010_REQ08_RE2_POWER_DOWN_CTRL1, 0xf0},
-			{TM6010_REQ08_RE3_ADC_IN1_SEL, 0xf8},
-			{TM6010_REQ08_RE4_ADC_IN2_SEL, 0xf3},
-			{TM6010_REQ08_RE6_POWER_DOWN_CTRL2, 0x0f},
-			{TM6010_REQ08_REA_BUFF_DRV_CTRL, 0xf1},
-			{TM6010_REQ08_REB_SIF_GAIN_CTRL, 0xe0},
-			{TM6010_REQ08_REC_REVERSE_YC_CTRL, 0xc2},
-			{TM6010_REQ08_RED_GAIN_SEL, 0xe8},
-			{TM6010_REQ08_RF0_DAUDIO_INPUT_CONFIG, 0x60},
-			{TM6010_REQ08_RF1_AADC_POWER_DOWN, 0xfc},
-			{TM6010_REQ07_RFE_POWER_DOWN, 0x8b},
-			{0, 0, 0},
-		},
-		.common = {
-			{TM6010_REQ07_R3F_RESET, 0x01},
-			{TM6010_REQ07_R00_VIDEO_CONTROL0, 0x38},
-			{TM6010_REQ07_R01_VIDEO_CONTROL1, 0x0e},
-			{TM6010_REQ07_R02_VIDEO_CONTROL2, 0x5f},
-			{TM6010_REQ07_R03_YC_SEP_CONTROL, 0x02},
-			{TM6010_REQ07_R07_OUTPUT_CONTROL, 0x31},
-			{TM6010_REQ07_R18_CHROMA_DTO_INCREMENT3, 0x24},
-			{TM6010_REQ07_R19_CHROMA_DTO_INCREMENT2, 0x92},
-			{TM6010_REQ07_R1A_CHROMA_DTO_INCREMENT1, 0xe8},
-			{TM6010_REQ07_R1B_CHROMA_DTO_INCREMENT0, 0xed},
-			{TM6010_REQ07_R1C_HSYNC_DTO_INCREMENT3, 0x1c},
-			{TM6010_REQ07_R1D_HSYNC_DTO_INCREMENT2, 0xcc},
-			{TM6010_REQ07_R1E_HSYNC_DTO_INCREMENT1, 0xcc},
-			{TM6010_REQ07_R1F_HSYNC_DTO_INCREMENT0, 0xcd},
-			{TM6010_REQ07_R2E_ACTIVE_VIDEO_HSTART, 0x8c},
-			{TM6010_REQ07_R30_ACTIVE_VIDEO_VSTART, 0x2c},
-			{TM6010_REQ07_R31_ACTIVE_VIDEO_VHIGHT, 0xc1},
-			{TM6010_REQ07_R33_VSYNC_HLOCK_MAX, 0x2c},
-			{TM6010_REQ07_R35_VSYNC_AGC_MAX, 0x18},
-			{TM6010_REQ07_R82_COMB_FILTER_CONFIG, 0x42},
-			{TM6010_REQ07_R83_CHROMA_LOCK_CONFIG, 0xFF},
-
-			{TM6010_REQ07_R0D_CHROMA_KILL_LEVEL, 0x07},
-
-			{TM6010_REQ07_R3F_RESET, 0x00},
-			{0, 0, 0},
-		},
-	}, {
-		.id = V4L2_STD_NTSC,
-		.audio_default_std = BTSC,
-		.sif = {
-			{TM6010_REQ08_RE2_POWER_DOWN_CTRL1, 0xf2},
-			{TM6010_REQ08_RE3_ADC_IN1_SEL, 0xf8},
-			{TM6010_REQ08_RE4_ADC_IN2_SEL, 0xf3},
-			{TM6010_REQ08_RE6_POWER_DOWN_CTRL2, 0x08},
-			{TM6010_REQ08_REA_BUFF_DRV_CTRL, 0xf1},
-			{TM6010_REQ08_REB_SIF_GAIN_CTRL, 0xe0},
-			{TM6010_REQ08_REC_REVERSE_YC_CTRL, 0xc2},
-			{TM6010_REQ08_RED_GAIN_SEL, 0xe8},
-			{TM6010_REQ08_RF0_DAUDIO_INPUT_CONFIG, 0x62},
-			{TM6010_REQ08_RF1_AADC_POWER_DOWN, 0xfe},
-			{TM6010_REQ07_RFE_POWER_DOWN, 0xcb},
-			{0, 0, 0},
-		},
-		.nosif = {
-			{TM6010_REQ08_RE2_POWER_DOWN_CTRL1, 0xf0},
-			{TM6010_REQ08_RE3_ADC_IN1_SEL, 0xf8},
-			{TM6010_REQ08_RE4_ADC_IN2_SEL, 0xf3},
-			{TM6010_REQ08_RE6_POWER_DOWN_CTRL2, 0x0f},
-			{TM6010_REQ08_REA_BUFF_DRV_CTRL, 0xf1},
-			{TM6010_REQ08_REB_SIF_GAIN_CTRL, 0xe0},
-			{TM6010_REQ08_REC_REVERSE_YC_CTRL, 0xc2},
-			{TM6010_REQ08_RED_GAIN_SEL, 0xe8},
-			{TM6010_REQ08_RF0_DAUDIO_INPUT_CONFIG, 0x60},
-			{TM6010_REQ08_RF1_AADC_POWER_DOWN, 0xfc},
-			{TM6010_REQ07_RFE_POWER_DOWN, 0x8b},
-			{0, 0, 0},
-		},
-		.common = {
-			{TM6010_REQ07_R3F_RESET, 0x01},
-			{TM6010_REQ07_R00_VIDEO_CONTROL0, 0x00},
-			{TM6010_REQ07_R01_VIDEO_CONTROL1, 0x0f},
-			{TM6010_REQ07_R02_VIDEO_CONTROL2, 0x5f},
-			{TM6010_REQ07_R03_YC_SEP_CONTROL, 0x00},
-			{TM6010_REQ07_R07_OUTPUT_CONTROL, 0x31},
-			{TM6010_REQ07_R18_CHROMA_DTO_INCREMENT3, 0x1e},
-			{TM6010_REQ07_R19_CHROMA_DTO_INCREMENT2, 0x8b},
-			{TM6010_REQ07_R1A_CHROMA_DTO_INCREMENT1, 0xa2},
-			{TM6010_REQ07_R1B_CHROMA_DTO_INCREMENT0, 0xe9},
-			{TM6010_REQ07_R1C_HSYNC_DTO_INCREMENT3, 0x1c},
-			{TM6010_REQ07_R1D_HSYNC_DTO_INCREMENT2, 0xcc},
-			{TM6010_REQ07_R1E_HSYNC_DTO_INCREMENT1, 0xcc},
-			{TM6010_REQ07_R1F_HSYNC_DTO_INCREMENT0, 0xcd},
-			{TM6010_REQ07_R2E_ACTIVE_VIDEO_HSTART, 0x88},
-			{TM6010_REQ07_R30_ACTIVE_VIDEO_VSTART, 0x22},
-			{TM6010_REQ07_R31_ACTIVE_VIDEO_VHIGHT, 0x61},
-			{TM6010_REQ07_R33_VSYNC_HLOCK_MAX, 0x1c},
-			{TM6010_REQ07_R35_VSYNC_AGC_MAX, 0x1c},
-			{TM6010_REQ07_R82_COMB_FILTER_CONFIG, 0x42},
-			{TM6010_REQ07_R83_CHROMA_LOCK_CONFIG, 0x6F},
-
-			{TM6010_REQ07_R04_LUMA_HAGC_CONTROL, 0xdd},
-			{TM6010_REQ07_R0D_CHROMA_KILL_LEVEL, 0x07},
-
-			{TM6010_REQ07_R3F_RESET, 0x00},
-
-			{0, 0, 0},
-		},
-	},
+	struct tm6000_reg_settings common[27];
 };
 
 static struct tm6000_std_settings composite_stds[] = {
 	{
 		.id = V4L2_STD_PAL_M,
-		.audio_default_std = BTSC,
 		.common = {
-			{TM6010_REQ08_RE2_POWER_DOWN_CTRL1, 0xf0},
-			{TM6010_REQ08_RE3_ADC_IN1_SEL, 0xf4},
-			{TM6010_REQ08_RE4_ADC_IN2_SEL, 0xf3},
-			{TM6010_REQ08_RE6_POWER_DOWN_CTRL2, 0x0f},
-			{TM6010_REQ08_REA_BUFF_DRV_CTRL, 0xf1},
-			{TM6010_REQ08_REB_SIF_GAIN_CTRL, 0xe0},
-			{TM6010_REQ08_REC_REVERSE_YC_CTRL, 0xc2},
-			{TM6010_REQ08_RED_GAIN_SEL, 0xe8},
-			{TM6010_REQ08_RF0_DAUDIO_INPUT_CONFIG, 0x68},
-			{TM6010_REQ08_RF1_AADC_POWER_DOWN, 0xfc},
-			{TM6010_REQ07_RFE_POWER_DOWN, 0x8b},
-
 			{TM6010_REQ07_R3F_RESET, 0x01},
 			{TM6010_REQ07_R00_VIDEO_CONTROL0, 0x04},
 			{TM6010_REQ07_R01_VIDEO_CONTROL1, 0x0e},
@@ -467,20 +71,7 @@
 		},
 	 }, {
 		.id = V4L2_STD_PAL_Nc,
-		.audio_default_std = BTSC,
 		.common = {
-			{TM6010_REQ08_RE2_POWER_DOWN_CTRL1, 0xf0},
-			{TM6010_REQ08_RE3_ADC_IN1_SEL, 0xf4},
-			{TM6010_REQ08_RE4_ADC_IN2_SEL, 0xf3},
-			{TM6010_REQ08_RE6_POWER_DOWN_CTRL2, 0x0f},
-			{TM6010_REQ08_REA_BUFF_DRV_CTRL, 0xf1},
-			{TM6010_REQ08_REB_SIF_GAIN_CTRL, 0xe0},
-			{TM6010_REQ08_REC_REVERSE_YC_CTRL, 0xc2},
-			{TM6010_REQ08_RED_GAIN_SEL, 0xe8},
-			{TM6010_REQ08_RF0_DAUDIO_INPUT_CONFIG, 0x68},
-			{TM6010_REQ08_RF1_AADC_POWER_DOWN, 0xfc},
-			{TM6010_REQ07_RFE_POWER_DOWN, 0x8b},
-
 			{TM6010_REQ07_R3F_RESET, 0x01},
 			{TM6010_REQ07_R00_VIDEO_CONTROL0, 0x36},
 			{TM6010_REQ07_R01_VIDEO_CONTROL1, 0x0e},
@@ -510,20 +101,7 @@
 		},
 	}, {
 		.id = V4L2_STD_PAL,
-		.audio_default_std = BG_A2,
 		.common = {
-			{TM6010_REQ08_RE2_POWER_DOWN_CTRL1, 0xf0},
-			{TM6010_REQ08_RE3_ADC_IN1_SEL, 0xf4},
-			{TM6010_REQ08_RE4_ADC_IN2_SEL, 0xf3},
-			{TM6010_REQ08_RE6_POWER_DOWN_CTRL2, 0x0f},
-			{TM6010_REQ08_REA_BUFF_DRV_CTRL, 0xf1},
-			{TM6010_REQ08_REB_SIF_GAIN_CTRL, 0xe0},
-			{TM6010_REQ08_REC_REVERSE_YC_CTRL, 0xc2},
-			{TM6010_REQ08_RED_GAIN_SEL, 0xe8},
-			{TM6010_REQ08_RF0_DAUDIO_INPUT_CONFIG, 0x68},
-			{TM6010_REQ08_RF1_AADC_POWER_DOWN, 0xfc},
-			{TM6010_REQ07_RFE_POWER_DOWN, 0x8b},
-
 			{TM6010_REQ07_R3F_RESET, 0x01},
 			{TM6010_REQ07_R00_VIDEO_CONTROL0, 0x32},
 			{TM6010_REQ07_R01_VIDEO_CONTROL1, 0x0e},
@@ -553,62 +131,7 @@
 		},
 	 }, {
 		.id = V4L2_STD_SECAM,
-		.audio_default_std = BG_NICAM,
 		.common = {
-			{TM6010_REQ08_RE2_POWER_DOWN_CTRL1, 0xf0},
-			{TM6010_REQ08_RE3_ADC_IN1_SEL, 0xf4},
-			{TM6010_REQ08_RE4_ADC_IN2_SEL, 0xf3},
-			{TM6010_REQ08_RE6_POWER_DOWN_CTRL2, 0x0f},
-			{TM6010_REQ08_REA_BUFF_DRV_CTRL, 0xf1},
-			{TM6010_REQ08_REB_SIF_GAIN_CTRL, 0xe0},
-			{TM6010_REQ08_REC_REVERSE_YC_CTRL, 0xc2},
-			{TM6010_REQ08_RED_GAIN_SEL, 0xe8},
-			{TM6010_REQ08_RF0_DAUDIO_INPUT_CONFIG, 0x68},
-			{TM6010_REQ08_RF1_AADC_POWER_DOWN, 0xfc},
-			{TM6010_REQ07_RFE_POWER_DOWN, 0x8b},
-
-			{TM6010_REQ07_R3F_RESET, 0x01},
-			{TM6010_REQ07_R00_VIDEO_CONTROL0, 0x38},
-			{TM6010_REQ07_R01_VIDEO_CONTROL1, 0x0e},
-			{TM6010_REQ07_R02_VIDEO_CONTROL2, 0x5f},
-			{TM6010_REQ07_R03_YC_SEP_CONTROL, 0x02},
-			{TM6010_REQ07_R07_OUTPUT_CONTROL, 0x31},
-			{TM6010_REQ07_R18_CHROMA_DTO_INCREMENT3, 0x24},
-			{TM6010_REQ07_R19_CHROMA_DTO_INCREMENT2, 0x92},
-			{TM6010_REQ07_R1A_CHROMA_DTO_INCREMENT1, 0xe8},
-			{TM6010_REQ07_R1B_CHROMA_DTO_INCREMENT0, 0xed},
-			{TM6010_REQ07_R1C_HSYNC_DTO_INCREMENT3, 0x1c},
-			{TM6010_REQ07_R1D_HSYNC_DTO_INCREMENT2, 0xcc},
-			{TM6010_REQ07_R1E_HSYNC_DTO_INCREMENT1, 0xcc},
-			{TM6010_REQ07_R1F_HSYNC_DTO_INCREMENT0, 0xcd},
-			{TM6010_REQ07_R2E_ACTIVE_VIDEO_HSTART, 0x8c},
-			{TM6010_REQ07_R30_ACTIVE_VIDEO_VSTART, 0x2c},
-			{TM6010_REQ07_R31_ACTIVE_VIDEO_VHIGHT, 0xc1},
-			{TM6010_REQ07_R33_VSYNC_HLOCK_MAX, 0x2c},
-			{TM6010_REQ07_R35_VSYNC_AGC_MAX, 0x18},
-			{TM6010_REQ07_R82_COMB_FILTER_CONFIG, 0x42},
-			{TM6010_REQ07_R83_CHROMA_LOCK_CONFIG, 0xFF},
-
-			{TM6010_REQ07_R0D_CHROMA_KILL_LEVEL, 0x07},
-			{TM6010_REQ07_R3F_RESET, 0x00},
-			{0, 0, 0},
-		},
-	}, {
-		.id = V4L2_STD_SECAM_DK,
-		.audio_default_std = DK_NICAM,
-		.common = {
-			{TM6010_REQ08_RE2_POWER_DOWN_CTRL1, 0xf0},
-			{TM6010_REQ08_RE3_ADC_IN1_SEL, 0xf4},
-			{TM6010_REQ08_RE4_ADC_IN2_SEL, 0xf3},
-			{TM6010_REQ08_RE6_POWER_DOWN_CTRL2, 0x0f},
-			{TM6010_REQ08_REA_BUFF_DRV_CTRL, 0xf1},
-			{TM6010_REQ08_REB_SIF_GAIN_CTRL, 0xe0},
-			{TM6010_REQ08_REC_REVERSE_YC_CTRL, 0xc2},
-			{TM6010_REQ08_RED_GAIN_SEL, 0xe8},
-			{TM6010_REQ08_RF0_DAUDIO_INPUT_CONFIG, 0x68},
-			{TM6010_REQ08_RF1_AADC_POWER_DOWN, 0xfc},
-			{TM6010_REQ07_RFE_POWER_DOWN, 0x8b},
-
 			{TM6010_REQ07_R3F_RESET, 0x01},
 			{TM6010_REQ07_R00_VIDEO_CONTROL0, 0x38},
 			{TM6010_REQ07_R01_VIDEO_CONTROL1, 0x0e},
@@ -637,20 +160,7 @@
 		},
 	}, {
 		.id = V4L2_STD_NTSC,
-		.audio_default_std = BTSC,
 		.common = {
-			{TM6010_REQ08_RE2_POWER_DOWN_CTRL1, 0xf0},
-			{TM6010_REQ08_RE3_ADC_IN1_SEL, 0xf4},
-			{TM6010_REQ08_RE4_ADC_IN2_SEL, 0xf3},
-			{TM6010_REQ08_RE6_POWER_DOWN_CTRL2, 0x0f},
-			{TM6010_REQ08_REA_BUFF_DRV_CTRL, 0xf1},
-			{TM6010_REQ08_REB_SIF_GAIN_CTRL, 0xe0},
-			{TM6010_REQ08_REC_REVERSE_YC_CTRL, 0xc2},
-			{TM6010_REQ08_RED_GAIN_SEL, 0xe8},
-			{TM6010_REQ08_RF0_DAUDIO_INPUT_CONFIG, 0x68},
-			{TM6010_REQ08_RF1_AADC_POWER_DOWN, 0xfc},
-			{TM6010_REQ07_RFE_POWER_DOWN, 0x8b},
-
 			{TM6010_REQ07_R3F_RESET, 0x01},
 			{TM6010_REQ07_R00_VIDEO_CONTROL0, 0x00},
 			{TM6010_REQ07_R01_VIDEO_CONTROL1, 0x0f},
@@ -684,20 +194,7 @@
 static struct tm6000_std_settings svideo_stds[] = {
 	{
 		.id = V4L2_STD_PAL_M,
-		.audio_default_std = BTSC,
 		.common = {
-			{TM6010_REQ08_RE2_POWER_DOWN_CTRL1, 0xf0},
-			{TM6010_REQ08_RE3_ADC_IN1_SEL, 0xfc},
-			{TM6010_REQ08_RE4_ADC_IN2_SEL, 0xf8},
-			{TM6010_REQ08_RE6_POWER_DOWN_CTRL2, 0x00},
-			{TM6010_REQ08_REA_BUFF_DRV_CTRL, 0xf2},
-			{TM6010_REQ08_REB_SIF_GAIN_CTRL, 0xf0},
-			{TM6010_REQ08_REC_REVERSE_YC_CTRL, 0xc2},
-			{TM6010_REQ08_RED_GAIN_SEL, 0xe0},
-			{TM6010_REQ08_RF0_DAUDIO_INPUT_CONFIG, 0x68},
-			{TM6010_REQ08_RF1_AADC_POWER_DOWN, 0xfc},
-			{TM6010_REQ07_RFE_POWER_DOWN, 0x8a},
-
 			{TM6010_REQ07_R3F_RESET, 0x01},
 			{TM6010_REQ07_R00_VIDEO_CONTROL0, 0x05},
 			{TM6010_REQ07_R01_VIDEO_CONTROL1, 0x0e},
@@ -727,20 +224,7 @@
 		},
 	}, {
 		.id = V4L2_STD_PAL_Nc,
-		.audio_default_std = BTSC,
 		.common = {
-			{TM6010_REQ08_RE2_POWER_DOWN_CTRL1, 0xf0},
-			{TM6010_REQ08_RE3_ADC_IN1_SEL, 0xfc},
-			{TM6010_REQ08_RE4_ADC_IN2_SEL, 0xf8},
-			{TM6010_REQ08_RE6_POWER_DOWN_CTRL2, 0x00},
-			{TM6010_REQ08_REA_BUFF_DRV_CTRL, 0xf2},
-			{TM6010_REQ08_REB_SIF_GAIN_CTRL, 0xf0},
-			{TM6010_REQ08_REC_REVERSE_YC_CTRL, 0xc2},
-			{TM6010_REQ08_RED_GAIN_SEL, 0xe0},
-			{TM6010_REQ08_RF0_DAUDIO_INPUT_CONFIG, 0x68},
-			{TM6010_REQ08_RF1_AADC_POWER_DOWN, 0xfc},
-			{TM6010_REQ07_RFE_POWER_DOWN, 0x8a},
-
 			{TM6010_REQ07_R3F_RESET, 0x01},
 			{TM6010_REQ07_R00_VIDEO_CONTROL0, 0x37},
 			{TM6010_REQ07_R01_VIDEO_CONTROL1, 0x0e},
@@ -770,20 +254,7 @@
 		},
 	}, {
 		.id = V4L2_STD_PAL,
-		.audio_default_std = BG_A2,
 		.common = {
-			{TM6010_REQ08_RE2_POWER_DOWN_CTRL1, 0xf0},
-			{TM6010_REQ08_RE3_ADC_IN1_SEL, 0xfc},
-			{TM6010_REQ08_RE4_ADC_IN2_SEL, 0xf8},
-			{TM6010_REQ08_RE6_POWER_DOWN_CTRL2, 0x00},
-			{TM6010_REQ08_REA_BUFF_DRV_CTRL, 0xf2},
-			{TM6010_REQ08_REB_SIF_GAIN_CTRL, 0xf0},
-			{TM6010_REQ08_REC_REVERSE_YC_CTRL, 0xc2},
-			{TM6010_REQ08_RED_GAIN_SEL, 0xe0},
-			{TM6010_REQ08_RF0_DAUDIO_INPUT_CONFIG, 0x68},
-			{TM6010_REQ08_RF1_AADC_POWER_DOWN, 0xfc},
-			{TM6010_REQ07_RFE_POWER_DOWN, 0x8a},
-
 			{TM6010_REQ07_R3F_RESET, 0x01},
 			{TM6010_REQ07_R00_VIDEO_CONTROL0, 0x33},
 			{TM6010_REQ07_R01_VIDEO_CONTROL1, 0x0e},
@@ -813,62 +284,7 @@
 		},
 	 }, {
 		.id = V4L2_STD_SECAM,
-		.audio_default_std = BG_NICAM,
 		.common = {
-			{TM6010_REQ08_RE2_POWER_DOWN_CTRL1, 0xf0},
-			{TM6010_REQ08_RE3_ADC_IN1_SEL, 0xfc},
-			{TM6010_REQ08_RE4_ADC_IN2_SEL, 0xf8},
-			{TM6010_REQ08_RE6_POWER_DOWN_CTRL2, 0x00},
-			{TM6010_REQ08_REA_BUFF_DRV_CTRL, 0xf2},
-			{TM6010_REQ08_REB_SIF_GAIN_CTRL, 0xf0},
-			{TM6010_REQ08_REC_REVERSE_YC_CTRL, 0xc2},
-			{TM6010_REQ08_RED_GAIN_SEL, 0xe0},
-			{TM6010_REQ08_RF0_DAUDIO_INPUT_CONFIG, 0x68},
-			{TM6010_REQ08_RF1_AADC_POWER_DOWN, 0xfc},
-			{TM6010_REQ07_RFE_POWER_DOWN, 0x8a},
-
-			{TM6010_REQ07_R3F_RESET, 0x01},
-			{TM6010_REQ07_R00_VIDEO_CONTROL0, 0x39},
-			{TM6010_REQ07_R01_VIDEO_CONTROL1, 0x0e},
-			{TM6010_REQ07_R02_VIDEO_CONTROL2, 0x5f},
-			{TM6010_REQ07_R03_YC_SEP_CONTROL, 0x03},
-			{TM6010_REQ07_R07_OUTPUT_CONTROL, 0x31},
-			{TM6010_REQ07_R18_CHROMA_DTO_INCREMENT3, 0x24},
-			{TM6010_REQ07_R19_CHROMA_DTO_INCREMENT2, 0x92},
-			{TM6010_REQ07_R1A_CHROMA_DTO_INCREMENT1, 0xe8},
-			{TM6010_REQ07_R1B_CHROMA_DTO_INCREMENT0, 0xed},
-			{TM6010_REQ07_R1C_HSYNC_DTO_INCREMENT3, 0x1c},
-			{TM6010_REQ07_R1D_HSYNC_DTO_INCREMENT2, 0xcc},
-			{TM6010_REQ07_R1E_HSYNC_DTO_INCREMENT1, 0xcc},
-			{TM6010_REQ07_R1F_HSYNC_DTO_INCREMENT0, 0xcd},
-			{TM6010_REQ07_R2E_ACTIVE_VIDEO_HSTART, 0x8c},
-			{TM6010_REQ07_R30_ACTIVE_VIDEO_VSTART, 0x2a},
-			{TM6010_REQ07_R31_ACTIVE_VIDEO_VHIGHT, 0xc1},
-			{TM6010_REQ07_R33_VSYNC_HLOCK_MAX, 0x2c},
-			{TM6010_REQ07_R35_VSYNC_AGC_MAX, 0x18},
-			{TM6010_REQ07_R82_COMB_FILTER_CONFIG, 0x42},
-			{TM6010_REQ07_R83_CHROMA_LOCK_CONFIG, 0xFF},
-
-			{TM6010_REQ07_R0D_CHROMA_KILL_LEVEL, 0x07},
-			{TM6010_REQ07_R3F_RESET, 0x00},
-			{0, 0, 0},
-		},
-	}, {
-		.id = V4L2_STD_SECAM_DK,
-		.audio_default_std = DK_NICAM,
-		.common = {
-			{TM6010_REQ08_RE2_POWER_DOWN_CTRL1, 0xf0},
-			{TM6010_REQ08_RE3_ADC_IN1_SEL, 0xfc},
-			{TM6010_REQ08_RE4_ADC_IN2_SEL, 0xf8},
-			{TM6010_REQ08_RE6_POWER_DOWN_CTRL2, 0x00},
-			{TM6010_REQ08_REA_BUFF_DRV_CTRL, 0xf2},
-			{TM6010_REQ08_REB_SIF_GAIN_CTRL, 0xf0},
-			{TM6010_REQ08_REC_REVERSE_YC_CTRL, 0xc2},
-			{TM6010_REQ08_RED_GAIN_SEL, 0xe0},
-			{TM6010_REQ08_RF0_DAUDIO_INPUT_CONFIG, 0x68},
-			{TM6010_REQ08_RF1_AADC_POWER_DOWN, 0xfc},
-			{TM6010_REQ07_RFE_POWER_DOWN, 0x8a},
-
 			{TM6010_REQ07_R3F_RESET, 0x01},
 			{TM6010_REQ07_R00_VIDEO_CONTROL0, 0x39},
 			{TM6010_REQ07_R01_VIDEO_CONTROL1, 0x0e},
@@ -897,20 +313,7 @@
 		},
 	}, {
 		.id = V4L2_STD_NTSC,
-		.audio_default_std = BTSC,
 		.common = {
-			{TM6010_REQ08_RE2_POWER_DOWN_CTRL1, 0xf0},
-			{TM6010_REQ08_RE3_ADC_IN1_SEL, 0xfc},
-			{TM6010_REQ08_RE4_ADC_IN2_SEL, 0xf8},
-			{TM6010_REQ08_RE6_POWER_DOWN_CTRL2, 0x00},
-			{TM6010_REQ08_REA_BUFF_DRV_CTRL, 0xf2},
-			{TM6010_REQ08_REB_SIF_GAIN_CTRL, 0xf0},
-			{TM6010_REQ08_REC_REVERSE_YC_CTRL, 0xc2},
-			{TM6010_REQ08_RED_GAIN_SEL, 0xe0},
-			{TM6010_REQ08_RF0_DAUDIO_INPUT_CONFIG, 0x68},
-			{TM6010_REQ08_RF1_AADC_POWER_DOWN, 0xfc},
-			{TM6010_REQ07_RFE_POWER_DOWN, 0x8a},
-
 			{TM6010_REQ07_R3F_RESET, 0x01},
 			{TM6010_REQ07_R00_VIDEO_CONTROL0, 0x01},
 			{TM6010_REQ07_R01_VIDEO_CONTROL1, 0x0f},
@@ -943,13 +346,11 @@
 };
 
 
-static int tm6000_set_audio_std(struct tm6000_core *dev,
-				enum tm6000_audio_std std)
+static int tm6000_set_audio_std(struct tm6000_core *dev)
 {
 	uint8_t areg_02 = 0x04; /* GC1 Fixed gain 0dB */
-	uint8_t areg_05 = 0x09; /* Auto 4.5 = M Japan, Auto 6.5 = DK */
+	uint8_t areg_05 = 0x01; /* Auto 4.5 = M Japan, Auto 6.5 = DK */
 	uint8_t areg_06 = 0x02; /* Auto de-emphasis, mannual channel mode */
-	uint8_t mono_flag = 0;  /* No mono */
 	uint8_t nicam_flag = 0; /* No NICAM */
 
 	if (dev->radio) {
@@ -958,81 +359,99 @@
 		tm6000_set_reg(dev, TM6010_REQ08_R03_A_AUTO_GAIN_CTRL, 0x00);
 		tm6000_set_reg(dev, TM6010_REQ08_R04_A_SIF_AMP_CTRL, 0x80);
 		tm6000_set_reg(dev, TM6010_REQ08_R05_A_STANDARD_MOD, 0x0c);
-		tm6000_set_reg(dev, TM6010_REQ08_R06_A_SOUND_MOD, 0x00);
+		/* set mono or stereo */
+		if (dev->amode == V4L2_TUNER_MODE_MONO)
+			tm6000_set_reg(dev, TM6010_REQ08_R06_A_SOUND_MOD, 0x00);
+		else if (dev->amode == V4L2_TUNER_MODE_STEREO)
+			tm6000_set_reg(dev, TM6010_REQ08_R06_A_SOUND_MOD, 0x02);
 		tm6000_set_reg(dev, TM6010_REQ08_R09_A_MAIN_VOL, 0x18);
 		tm6000_set_reg(dev, TM6010_REQ08_R0C_A_ASD_THRES2, 0x0a);
 		tm6000_set_reg(dev, TM6010_REQ08_R0D_A_AMD_THRES, 0x40);
-		tm6000_set_reg(dev, TM6010_REQ08_RF1_AADC_POWER_DOWN, 0xfc);
+		tm6000_set_reg(dev, TM6010_REQ08_RF1_AADC_POWER_DOWN, 0xfe);
 		tm6000_set_reg(dev, TM6010_REQ08_R1E_A_GAIN_DEEMPH_OUT, 0x13);
 		tm6000_set_reg(dev, TM6010_REQ08_R01_A_INIT, 0x80);
 		return 0;
 	}
 
-	switch (std) {
-#if 0
-	case DK_MONO:
-		mono_flag = 1;
-		break;
-	case DK_A2_1:
-		break;
-	case DK_A2_3:
-		areg_05 = 0x0b;
-		break;
-	case BG_MONO:
-		mono_flag = 1;
-		areg_05 = 0x05;
-		break;
-#endif
-	case BG_NICAM:
-		areg_05 = 0x07;
-		nicam_flag = 1;
-		break;
-	case BTSC:
-		areg_05 = 0x02;
-		break;
-	case BG_A2:
-		areg_05 = 0x05;
-		break;
-	case DK_NICAM:
-		areg_05 = 0x06;
-		nicam_flag = 1;
-		break;
-	case EIAJ:
-		areg_05 = 0x02;
-		break;
-	case I_NICAM:
-		areg_05 = 0x08;
-		nicam_flag = 1;
+	switch (tm6010_a_mode) {
+	/* auto */
+	case 0:
+		switch (dev->norm) {
+		case V4L2_STD_NTSC_M_KR:
+			areg_05 |= 0x00;
+			break;
+		case V4L2_STD_NTSC_M_JP:
+			areg_05 |= 0x40;
+			break;
+		case V4L2_STD_NTSC_M:
+		case V4L2_STD_PAL_M:
+		case V4L2_STD_PAL_N:
+			areg_05 |= 0x20;
+			break;
+		case V4L2_STD_PAL_Nc:
+			areg_05 |= 0x60;
+			break;
+		case V4L2_STD_SECAM_L:
+			areg_05 |= 0x00;
+			break;
+		case V4L2_STD_DK:
+			areg_05 |= 0x10;
+			break;
+		}
 		break;
-	case KOREA_A2:
-		areg_05 = 0x04;
+	/* A2 */
+	case 1:
+		switch (dev->norm) {
+		case V4L2_STD_B:
+		case V4L2_STD_GH:
+			areg_05 = 0x05;
+			break;
+		case V4L2_STD_DK:
+			areg_05 = 0x09;
+			break;
+		}
 		break;
-	case L_NICAM:
-		areg_02 = 0x02; /* GC1 Fixed gain +12dB */
-		areg_05 = 0x0a;
+	/* NICAM */
+	case 2:
+		switch (dev->norm) {
+		case V4L2_STD_B:
+		case V4L2_STD_GH:
+			areg_05 = 0x07;
+			break;
+		case V4L2_STD_DK:
+			areg_05 = 0x06;
+			break;
+		case V4L2_STD_PAL_I:
+			areg_05 = 0x08;
+			break;
+		case V4L2_STD_SECAM_L:
+			areg_05 = 0x0a;
+			areg_02 = 0x02;
+			break;
+		}
 		nicam_flag = 1;
 		break;
-	default:
-		/* do nothink */
-		break;
-	}
-
-#if 0
-	switch (tv_audio_mode) {
-	case TV_MONO:
-		areg_06 = (nicam_flag) ? 0x03 : 0x00;
-		break;
-	case TV_LANG_A:
-		areg_06 = 0x00;
-		break;
-	case TV_LANG_B:
-		areg_06 = 0x01;
+	/* other */
+	case 3:
+		switch (dev->norm) {
+		/* DK3_A2 */
+		case V4L2_STD_DK:
+			areg_05 = 0x0b;
+			break;
+		/* Korea */
+		case V4L2_STD_NTSC_M_KR:
+			areg_05 = 0x04;
+			break;
+		/* EIAJ */
+		case V4L2_STD_NTSC_M_JP:
+			areg_05 = 0x03;
+			break;
+		default:
+			areg_05 = 0x02;
+			break;
+		}
 		break;
 	}
-#endif
-
-	if (mono_flag)
-		areg_06 = 0x00;
 
 	tm6000_set_reg(dev, TM6010_REQ08_R01_A_INIT, 0x00);
 	tm6000_set_reg(dev, TM6010_REQ08_R02_A_FIX_GAIN_CTRL, areg_02);
@@ -1066,9 +485,6 @@
 	tm6000_set_reg(dev, TM6010_REQ08_R1E_A_GAIN_DEEMPH_OUT, 0x13);
 	tm6000_set_reg(dev, TM6010_REQ08_R1F_A_TEST_INTF_SEL, 0x00);
 	tm6000_set_reg(dev, TM6010_REQ08_R20_A_TEST_PIN_SEL, 0x00);
-	tm6000_set_reg(dev, TM6010_REQ08_RE4_ADC_IN2_SEL, 0xf3);
-	tm6000_set_reg(dev, TM6010_REQ08_R06_A_SOUND_MOD, 0x00);
-	tm6000_set_reg(dev, TM6010_REQ08_RF1_AADC_POWER_DOWN, 0xfc);
 	tm6000_set_reg(dev, TM6010_REQ08_R01_A_INIT, 0x80);
 
 	return 0;
@@ -1095,10 +511,6 @@
 		if (!set[i].req)
 			return 0;
 
-		if ((dev->dev_type != TM6010) &&
-		    (set[i].req == REQ_08_SET_GET_AVREG_BIT))
-				continue;
-
 		rc = tm6000_set_reg(dev, set[i].req, set[i].reg, set[i].value);
 		if (rc < 0) {
 			printk(KERN_ERR "Error %i while setting "
@@ -1111,53 +523,126 @@
 	return 0;
 }
 
-static int tm6000_set_tv(struct tm6000_core *dev, int pos)
-{
-	int rc;
-
-	/* FIXME: This code is for tm6010 - not tested yet - doesn't work with
-	   tm5600
-	 */
-
-	/* FIXME: This is tuner-dependent */
-	int nosif = 0;
-
-	if (nosif) {
-		rc = tm6000_load_std(dev, tv_stds[pos].nosif,
-				     sizeof(tv_stds[pos].nosif));
-	} else {
-		rc = tm6000_load_std(dev, tv_stds[pos].sif,
-				     sizeof(tv_stds[pos].sif));
-	}
-	if (rc < 0)
-		return rc;
-	rc = tm6000_load_std(dev, tv_stds[pos].common,
-			     sizeof(tv_stds[pos].common));
-
-	tm6000_set_audio_std(dev, tv_stds[pos].audio_default_std);
-
-	return rc;
-}
-
-int tm6000_set_standard(struct tm6000_core *dev, v4l2_std_id * norm)
+int tm6000_set_standard(struct tm6000_core *dev)
 {
 	int i, rc = 0;
+	u8 reg_07_fe = 0x8a;
+	u8 reg_08_f1 = 0xfc;
+	u8 reg_08_e2 = 0xf0;
+	u8 reg_08_e6 = 0x0f;
 
-	dev->norm = *norm;
 	tm6000_get_std_res(dev);
 
-	switch (dev->input) {
-	case TM6000_INPUT_TV:
-		for (i = 0; i < ARRAY_SIZE(tv_stds); i++) {
-			if (*norm & tv_stds[i].id) {
-				rc = tm6000_set_tv(dev, i);
-				goto ret;
-			}
+	if (dev->radio) {
+		/* todo */
+	}
+
+	if (dev->dev_type == TM6010) {
+		switch (dev->vinput[dev->input].vmux) {
+		case TM6000_VMUX_VIDEO_A:
+			tm6000_set_reg(dev, TM6010_REQ08_RE3_ADC_IN1_SEL, 0xf4);
+			tm6000_set_reg(dev, TM6010_REQ08_REA_BUFF_DRV_CTRL, 0xf1);
+			tm6000_set_reg(dev, TM6010_REQ08_REB_SIF_GAIN_CTRL, 0xe0);
+			tm6000_set_reg(dev, TM6010_REQ08_REC_REVERSE_YC_CTRL, 0xc2);
+			tm6000_set_reg(dev, TM6010_REQ08_RED_GAIN_SEL, 0xe8);
+			reg_07_fe |= 0x01;
+			break;
+		case TM6000_VMUX_VIDEO_B:
+			tm6000_set_reg(dev, TM6010_REQ08_RE3_ADC_IN1_SEL, 0xf8);
+			tm6000_set_reg(dev, TM6010_REQ08_REA_BUFF_DRV_CTRL, 0xf1);
+			tm6000_set_reg(dev, TM6010_REQ08_REB_SIF_GAIN_CTRL, 0xe0);
+			tm6000_set_reg(dev, TM6010_REQ08_REC_REVERSE_YC_CTRL, 0xc2);
+			tm6000_set_reg(dev, TM6010_REQ08_RED_GAIN_SEL, 0xe8);
+			reg_07_fe |= 0x01;
+			break;
+		case TM6000_VMUX_VIDEO_AB:
+			tm6000_set_reg(dev, TM6010_REQ08_RE3_ADC_IN1_SEL, 0xfc);
+			tm6000_set_reg(dev, TM6010_REQ08_RE4_ADC_IN2_SEL, 0xf8);
+			reg_08_e6 = 0x00;
+			tm6000_set_reg(dev, TM6010_REQ08_REA_BUFF_DRV_CTRL, 0xf2);
+			tm6000_set_reg(dev, TM6010_REQ08_REB_SIF_GAIN_CTRL, 0xf0);
+			tm6000_set_reg(dev, TM6010_REQ08_REC_REVERSE_YC_CTRL, 0xc2);
+			tm6000_set_reg(dev, TM6010_REQ08_RED_GAIN_SEL, 0xe0);
+			break;
+		default:
+			break;
 		}
-		return -EINVAL;
-	case TM6000_INPUT_SVIDEO:
+		switch (dev->vinput[dev->input].amux) {
+		case TM6000_AMUX_ADC1:
+			tm6000_set_reg_mask(dev, TM6010_REQ08_RF0_DAUDIO_INPUT_CONFIG,
+				0x00, 0x0f);
+			break;
+		case TM6000_AMUX_ADC2:
+			tm6000_set_reg_mask(dev, TM6010_REQ08_RF0_DAUDIO_INPUT_CONFIG,
+				0x08, 0x0f);
+			break;
+		case TM6000_AMUX_SIF1:
+			reg_08_e2 |= 0x02;
+			reg_08_e6 = 0x08;
+			reg_07_fe |= 0x40;
+			reg_08_f1 |= 0x02;
+			tm6000_set_reg(dev, TM6010_REQ08_RE4_ADC_IN2_SEL, 0xf3);
+			tm6000_set_reg_mask(dev, TM6010_REQ08_RF0_DAUDIO_INPUT_CONFIG,
+				0x02, 0x0f);
+			break;
+		case TM6000_AMUX_SIF2:
+			reg_08_e2 |= 0x02;
+			reg_08_e6 = 0x08;
+			reg_07_fe |= 0x40;
+			reg_08_f1 |= 0x02;
+			tm6000_set_reg(dev, TM6010_REQ08_RE4_ADC_IN2_SEL, 0xf7);
+			tm6000_set_reg_mask(dev, TM6010_REQ08_RF0_DAUDIO_INPUT_CONFIG,
+				0x02, 0x0f);
+			break;
+		default:
+			break;
+		}
+		tm6000_set_reg(dev, TM6010_REQ08_RE2_POWER_DOWN_CTRL1, reg_08_e2);
+		tm6000_set_reg(dev, TM6010_REQ08_RE6_POWER_DOWN_CTRL2, reg_08_e6);
+		tm6000_set_reg(dev, TM6010_REQ08_RF1_AADC_POWER_DOWN, reg_08_f1);
+		tm6000_set_reg(dev, TM6010_REQ07_RFE_POWER_DOWN, reg_07_fe);
+	} else {
+		switch (dev->vinput[dev->input].vmux) {
+		case TM6000_VMUX_VIDEO_A:
+			tm6000_set_reg(dev, TM6000_REQ07_RE3_VADC_INP_LPF_SEL1, 0x10);
+			tm6000_set_reg(dev, TM6000_REQ07_RE5_VADC_INP_LPF_SEL2, 0x00);
+			tm6000_set_reg(dev, TM6000_REQ07_RE8_VADC_PWDOWN_CTL, 0x0f);
+			tm6000_set_reg(dev,
+			    REQ_03_SET_GET_MCU_PIN, dev->vinput[dev->input].v_gpio, 0);
+			break;
+		case TM6000_VMUX_VIDEO_B:
+			tm6000_set_reg(dev, TM6000_REQ07_RE3_VADC_INP_LPF_SEL1, 0x00);
+			tm6000_set_reg(dev, TM6000_REQ07_RE5_VADC_INP_LPF_SEL2, 0x00);
+			tm6000_set_reg(dev, TM6000_REQ07_RE8_VADC_PWDOWN_CTL, 0x0f);
+			tm6000_set_reg(dev,
+			    REQ_03_SET_GET_MCU_PIN, dev->vinput[dev->input].v_gpio, 0);
+			break;
+		case TM6000_VMUX_VIDEO_AB:
+			tm6000_set_reg(dev, TM6000_REQ07_RE3_VADC_INP_LPF_SEL1, 0x10);
+			tm6000_set_reg(dev, TM6000_REQ07_RE5_VADC_INP_LPF_SEL2, 0x10);
+			tm6000_set_reg(dev, TM6000_REQ07_RE8_VADC_PWDOWN_CTL, 0x00);
+			tm6000_set_reg(dev,
+			    REQ_03_SET_GET_MCU_PIN, dev->vinput[dev->input].v_gpio, 1);
+			break;
+		default:
+			break;
+		}
+		switch (dev->vinput[dev->input].amux) {
+		case TM6000_AMUX_ADC1:
+			tm6000_set_reg_mask(dev,
+				TM6000_REQ07_REB_VADC_AADC_MODE, 0x00, 0x0f);
+			break;
+		case TM6000_AMUX_ADC2:
+			tm6000_set_reg_mask(dev,
+				TM6000_REQ07_REB_VADC_AADC_MODE, 0x04, 0x0f);
+			break;
+		default:
+			break;
+		}
+	}
+	if (dev->vinput[dev->input].type == TM6000_INPUT_SVIDEO) {
 		for (i = 0; i < ARRAY_SIZE(svideo_stds); i++) {
-			if (*norm & svideo_stds[i].id) {
+			if (dev->norm & svideo_stds[i].id) {
 				rc = tm6000_load_std(dev, svideo_stds[i].common,
 						     sizeof(svideo_stds[i].
 							    common));
@@ -1165,14 +650,13 @@
 			}
 		}
 		return -EINVAL;
-	case TM6000_INPUT_COMPOSITE:
+	} else {
 		for (i = 0; i < ARRAY_SIZE(composite_stds); i++) {
-			if (*norm & composite_stds[i].id) {
+			if (dev->norm & composite_stds[i].id) {
 				rc = tm6000_load_std(dev,
 						     composite_stds[i].common,
 						     sizeof(composite_stds[i].
 							    common));
-				tm6000_set_audio_std(dev, composite_stds[i].audio_default_std);
 				goto ret;
 			}
 		}
@@ -1183,6 +667,11 @@
 	if (rc < 0)
 		return rc;
 
+	if ((dev->dev_type == TM6010) &&
+	    ((dev->vinput[dev->input].amux == TM6000_AMUX_SIF1) ||
+	    (dev->vinput[dev->input].amux == TM6000_AMUX_SIF2)))
+		tm6000_set_audio_std(dev);
+
 	msleep(40);
 
 
diff -druN linux-2.6.39-libre/drivers/staging/tm6000/tm6000-usb-isoc.h linux-3.0-rc7-libre/drivers/staging/tm6000/tm6000-usb-isoc.h
--- linux-2.6.39-libre/drivers/staging/tm6000/tm6000-usb-isoc.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/tm6000/tm6000-usb-isoc.h	2011-07-11 19:51:52.000000000 -0400
@@ -39,7 +39,7 @@
 	int				pos, size, pktsize;
 
 		/* Last field: ODD or EVEN? */
-	int				vfield;
+	int				vfield, field;
 
 		/* Stores incomplete commands */
 	u32				tmp_buf;
diff -druN linux-2.6.39-libre/drivers/staging/tm6000/tm6000-video.c linux-3.0-rc7-libre/drivers/staging/tm6000/tm6000-video.c
--- linux-2.6.39-libre/drivers/staging/tm6000/tm6000-video.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/tm6000/tm6000-video.c	2011-07-11 19:51:52.000000000 -0400
@@ -34,6 +34,7 @@
 #include <linux/usb.h>
 #include <linux/videodev2.h>
 #include <media/v4l2-ioctl.h>
+#include <media/tuner.h>
 #include <linux/interrupt.h>
 #include <linux/kthread.h>
 #include <linux/highmem.h>
@@ -228,7 +229,7 @@
 	unsigned long header = 0;
 	int rc = 0;
 	unsigned int cmd, cpysize, pktsize, size, field, block, line, pos = 0;
-	struct tm6000_buffer *vbuf;
+	struct tm6000_buffer *vbuf = NULL;
 	char *voutp = NULL;
 	unsigned int linewidth;
 
@@ -318,7 +319,7 @@
 					if (pos + size > vbuf->vb.size)
 						cmd = TM6000_URB_MSG_ERR;
 					dev->isoc_ctl.vfield = field;
-			}
+				}
 				break;
 			case TM6000_URB_MSG_VBI:
 				break;
@@ -333,6 +334,7 @@
 			size = dev->isoc_ctl.size;
 			pos = dev->isoc_ctl.pos;
 			pktsize = dev->isoc_ctl.pktsize;
+			field = dev->isoc_ctl.field;
 		}
 		cpysize = (endp - ptr > size) ? size : endp - ptr;
 		if (cpysize) {
@@ -343,24 +345,26 @@
 				if (vbuf)
 					memcpy(&voutp[pos], ptr, cpysize);
 				break;
-			case TM6000_URB_MSG_AUDIO:
-				/* Need some code to copy audio buffer */
-				if (dev->fourcc == V4L2_PIX_FMT_YUYV) {
-					/* Swap word bytes */
-					int i;
+			case TM6000_URB_MSG_AUDIO: {
+				int i;
+				for (i = 0; i < cpysize; i += 2)
+					swab16s((u16 *)(ptr + i));
 
-					for (i = 0; i < cpysize; i += 2)
-						swab16s((u16 *)(ptr + i));
-				}
 				tm6000_call_fillbuf(dev, TM6000_AUDIO, ptr, cpysize);
 				break;
+			}
 			case TM6000_URB_MSG_VBI:
 				/* Need some code to copy vbi buffer */
 				break;
-			case TM6000_URB_MSG_PTS:
+			case TM6000_URB_MSG_PTS: {
 				/* Need some code to copy pts */
+				u32 pts;
+				pts = *(u32 *)ptr;
+				dprintk(dev, V4L2_DEBUG_ISOC, "field %d, PTS %x",
+					field, pts);
 				break;
 			}
+			}
 		}
 		if (ptr + pktsize > endp) {
 			/* End of URB packet, but cmd processing is not
@@ -369,6 +373,7 @@
 			dev->isoc_ctl.pos = pos + cpysize;
 			dev->isoc_ctl.size = size - cpysize;
 			dev->isoc_ctl.cmd = cmd;
+			dev->isoc_ctl.field = field;
 			dev->isoc_ctl.pktsize = pktsize - (endp - ptr);
 			ptr += endp - ptr;
 		} else {
@@ -883,14 +888,19 @@
 static int vidioc_querycap(struct file *file, void  *priv,
 					struct v4l2_capability *cap)
 {
+	struct tm6000_core *dev = ((struct tm6000_fh *)priv)->dev;
 
 	strlcpy(cap->driver, "tm6000", sizeof(cap->driver));
 	strlcpy(cap->card, "Trident TVMaster TM5600/6000/6010", sizeof(cap->card));
 	cap->version = TM6000_VERSION;
 	cap->capabilities =	V4L2_CAP_VIDEO_CAPTURE |
 				V4L2_CAP_STREAMING     |
-				V4L2_CAP_TUNER	       |
+				V4L2_CAP_AUDIO         |
 				V4L2_CAP_READWRITE;
+
+	if (dev->tuner_type != TUNER_ABSENT)
+		cap->capabilities |= V4L2_CAP_TUNER;
+
 	return 0;
 }
 
@@ -1077,35 +1087,37 @@
 	return 0;
 }
 
+static const char *iname [] = {
+	[TM6000_INPUT_TV] = "Television",
+	[TM6000_INPUT_COMPOSITE1] = "Composite 1",
+	[TM6000_INPUT_COMPOSITE2] = "Composite 2",
+	[TM6000_INPUT_SVIDEO] = "S-Video",
+};
+
 static int vidioc_enum_input(struct file *file, void *priv,
-				struct v4l2_input *inp)
+				struct v4l2_input *i)
 {
 	struct tm6000_fh   *fh = priv;
 	struct tm6000_core *dev = fh->dev;
+	unsigned int n;
 
-	switch (inp->index) {
-	case TM6000_INPUT_TV:
-		inp->type = V4L2_INPUT_TYPE_TUNER;
-		strcpy(inp->name, "Television");
-		break;
-	case TM6000_INPUT_COMPOSITE:
-		if (dev->caps.has_input_comp) {
-			inp->type = V4L2_INPUT_TYPE_CAMERA;
-			strcpy(inp->name, "Composite");
-		} else
-			return -EINVAL;
-		break;
-	case TM6000_INPUT_SVIDEO:
-		if (dev->caps.has_input_svid) {
-			inp->type = V4L2_INPUT_TYPE_CAMERA;
-			strcpy(inp->name, "S-Video");
-		} else
-			return -EINVAL;
-		break;
-	default:
+	n = i->index;
+	if (n >= 3)
 		return -EINVAL;
-	}
-	inp->std = TM6000_STD;
+
+	if (!dev->vinput[n].type)
+		return -EINVAL;
+
+	i->index = n;
+
+	if (dev->vinput[n].type == TM6000_INPUT_TV)
+		i->type = V4L2_INPUT_TYPE_TUNER;
+	else
+		i->type = V4L2_INPUT_TYPE_CAMERA;
+
+	strcpy(i->name, iname[dev->vinput[n].type]);
+
+	i->std = TM6000_STD;
 
 	return 0;
 }
@@ -1119,38 +1131,26 @@
 
 	return 0;
 }
+
 static int vidioc_s_input(struct file *file, void *priv, unsigned int i)
 {
 	struct tm6000_fh   *fh = priv;
 	struct tm6000_core *dev = fh->dev;
 	int rc = 0;
-	char buf[1];
 
-	switch (i) {
-	case TM6000_INPUT_TV:
-		dev->input = i;
-		*buf = 0;
-		break;
-	case TM6000_INPUT_COMPOSITE:
-	case TM6000_INPUT_SVIDEO:
-		dev->input = i;
-		*buf = 1;
-		break;
-	default:
+	if (i >= 3)
+		return -EINVAL;
+	if (!dev->vinput[i].type)
 		return -EINVAL;
-	}
-	rc = tm6000_read_write_usb(dev, USB_DIR_OUT | USB_TYPE_VENDOR,
-			       REQ_03_SET_GET_MCU_PIN, 0x03, 1, buf, 1);
 
-	if (!rc) {
-		dev->input = i;
-		rc = vidioc_s_std(file, priv, &dev->vfd->current_norm);
-	}
+	dev->input = i;
+
+	rc = vidioc_s_std(file, priv, &dev->vfd->current_norm);
 
 	return rc;
 }
 
-	/* --- controls ---------------------------------------------- */
+/* --- controls ---------------------------------------------- */
 static int vidioc_queryctrl(struct file *file, void *priv,
 				struct v4l2_queryctrl *qc)
 {
@@ -1251,7 +1251,11 @@
 	t->type       = V4L2_TUNER_ANALOG_TV;
 	t->capability = V4L2_TUNER_CAP_NORM;
 	t->rangehigh  = 0xffffffffUL;
-	t->rxsubchans = V4L2_TUNER_SUB_MONO;
+	t->rxsubchans = V4L2_TUNER_SUB_STEREO;
+
+	v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, g_tuner, t);
+
+	t->audmode = dev->amode;
 
 	return 0;
 }
@@ -1267,6 +1271,11 @@
 	if (0 != t->index)
 		return -EINVAL;
 
+	dev->amode = t->audmode;
+	dprintk(dev, 3, "audio mode: %x\n", t->audmode);
+
+	v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_tuner, t);
+
 	return 0;
 }
 
@@ -1320,7 +1329,11 @@
 		le16_to_cpu(dev->udev->descriptor.idVendor),
 		le16_to_cpu(dev->udev->descriptor.idProduct));
 	cap->version = dev->dev_type;
-	cap->capabilities = V4L2_CAP_TUNER;
+	cap->capabilities = V4L2_CAP_TUNER |
+			V4L2_CAP_AUDIO     |
+			V4L2_CAP_RADIO     |
+			V4L2_CAP_READWRITE |
+			V4L2_CAP_STREAMING;
 
 	return 0;
 }
@@ -1337,17 +1350,10 @@
 	memset(t, 0, sizeof(*t));
 	strcpy(t->name, "Radio");
 	t->type = V4L2_TUNER_RADIO;
+	t->rxsubchans = V4L2_TUNER_SUB_STEREO;
 
 	v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, g_tuner, t);
 
-	if ((dev->aradio == TM6000_AIP_LINE1) ||
-				(dev->aradio == TM6000_AIP_LINE2)) {
-		t->rxsubchans = V4L2_TUNER_SUB_MONO;
-	}
-	else {
-		t->rxsubchans = V4L2_TUNER_SUB_STEREO;
-	}
-
 	return 0;
 }
 
@@ -1368,9 +1374,15 @@
 static int radio_enum_input(struct file *file, void *priv,
 					struct v4l2_input *i)
 {
+	struct tm6000_fh *fh = priv;
+	struct tm6000_core *dev = fh->dev;
+
 	if (i->index != 0)
 		return -EINVAL;
 
+	if (!dev->rinput.type)
+		return -EINVAL;
+
 	strcpy(i->name, "Radio");
 	i->type = V4L2_INPUT_TYPE_TUNER;
 
@@ -1379,7 +1391,14 @@
 
 static int radio_g_input(struct file *filp, void *priv, unsigned int *i)
 {
-	*i = 0;
+	struct tm6000_fh *fh = priv;
+	struct tm6000_core *dev = fh->dev;
+
+	if (dev->input !=5)
+		return -EINVAL;
+
+	*i = dev->input -5;
+
 	return 0;
 }
 
@@ -1399,6 +1418,17 @@
 
 static int radio_s_input(struct file *filp, void *priv, unsigned int i)
 {
+	struct tm6000_fh *fh = priv;
+	struct tm6000_core *dev = fh->dev;
+
+	if (i)
+		return -EINVAL;
+
+	if (!dev->rinput.type)
+		return -EINVAL;
+
+	dev->input = i + 5;
+
 	return 0;
 }
 
@@ -1512,16 +1542,12 @@
 
 	if (fh->radio) {
 		dprintk(dev, V4L2_DEBUG_OPEN, "video_open: setting radio device\n");
-		tm6000_set_audio_input(dev, dev->aradio);
-		tm6000_set_volume(dev, dev->ctl_volume);
+		dev->input = 5;
+		tm6000_set_audio_rinput(dev);
 		v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_radio);
 		tm6000_prepare_isoc(dev);
 		tm6000_start_thread(dev);
 	}
-	else {
-		tm6000_set_audio_input(dev, dev->avideo);
-		tm6000_set_volume(dev, dev->ctl_volume);
-	}
 
 	return 0;
 }
@@ -1647,10 +1673,10 @@
 };
 
 static const struct v4l2_file_operations radio_fops = {
-	.owner	  = THIS_MODULE,
-	.open	  = tm6000_open,
-	.release  = tm6000_release,
-	.ioctl	  = video_ioctl2,
+	.owner		= THIS_MODULE,
+	.open		= tm6000_open,
+	.release	= tm6000_release,
+	.unlocked_ioctl	= video_ioctl2,
 };
 
 static const struct v4l2_ioctl_ops radio_ioctl_ops = {
@@ -1730,24 +1756,26 @@
 	printk(KERN_INFO "%s: registered device %s\n",
 	       dev->name, video_device_node_name(dev->vfd));
 
-	dev->radio_dev = vdev_init(dev, &tm6000_radio_template,
-						   "radio");
-	if (!dev->radio_dev) {
-		printk(KERN_INFO "%s: can't register radio device\n",
-		       dev->name);
-		return ret; /* FIXME release resource */
-	}
+	if (dev->caps.has_radio) {
+		dev->radio_dev = vdev_init(dev, &tm6000_radio_template,
+							   "radio");
+		if (!dev->radio_dev) {
+			printk(KERN_INFO "%s: can't register radio device\n",
+			       dev->name);
+			return ret; /* FIXME release resource */
+		}
 
-	ret = video_register_device(dev->radio_dev, VFL_TYPE_RADIO,
-				    radio_nr);
-	if (ret < 0) {
-		printk(KERN_INFO "%s: can't register radio device\n",
-		       dev->name);
-		return ret; /* FIXME release resource */
-	}
+		ret = video_register_device(dev->radio_dev, VFL_TYPE_RADIO,
+					    radio_nr);
+		if (ret < 0) {
+			printk(KERN_INFO "%s: can't register radio device\n",
+			       dev->name);
+			return ret; /* FIXME release resource */
+		}
 
-	printk(KERN_INFO "%s: registered device %s\n",
-	       dev->name, video_device_node_name(dev->radio_dev));
+		printk(KERN_INFO "%s: registered device %s\n",
+		       dev->name, video_device_node_name(dev->radio_dev));
+	}
 
 	printk(KERN_INFO "Trident TVMaster TM5600/TM6000/TM6010 USB2 board (Load status: %d)\n", ret);
 	return ret;
diff -druN linux-2.6.39-libre/drivers/staging/tty/istallion.c linux-3.0-rc7-libre/drivers/staging/tty/istallion.c
--- linux-2.6.39-libre/drivers/staging/tty/istallion.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/tty/istallion.c	2011-07-11 19:51:52.000000000 -0400
@@ -186,7 +186,6 @@
  *	re-used for each stats call.
  */
 static comstats_t	stli_comstats;
-static combrd_t		stli_brdstats;
 static struct asystats	stli_cdkstats;
 
 /*****************************************************************************/
@@ -4005,6 +4004,7 @@
 {
 	struct stlibrd *brdp;
 	unsigned int i;
+	combrd_t stli_brdstats;
 
 	if (copy_from_user(&stli_brdstats, bp, sizeof(combrd_t)))
 		return -EFAULT;
diff -druN linux-2.6.39-libre/drivers/staging/usbip/Kconfig linux-3.0-rc7-libre/drivers/staging/usbip/Kconfig
--- linux-2.6.39-libre/drivers/staging/usbip/Kconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/usbip/Kconfig	2011-07-11 19:51:52.000000000 -0400
@@ -1,43 +1,45 @@
-config USB_IP_COMMON
-	tristate "USB IP support (EXPERIMENTAL)"
+config USBIP_CORE
+	tristate "USB/IP support (EXPERIMENTAL)"
 	depends on USB && NET && EXPERIMENTAL
 	default N
 	---help---
 	  This enables pushing USB packets over IP to allow remote
-	  machines access to USB devices directly.  For more details,
-	  and links to the userspace utility programs to let this work
-	  properly, see http://usbip.sourceforge.net/.
+	  machines direct access to USB devices. It provides the
+	  USB/IP core that is required by both drivers.
 
-	  To compile this driver as a module, choose M here: the
-	  module will be called usbip_common_mod.
+	  For more details, and to get the userspace utility
+	  programs, please see http://usbip.sourceforge.net/.
+
+	  To compile this as a module, choose M here: the module will
+	  be called usbip-core.
 
 	  If unsure, say N.
 
-config USB_IP_VHCI_HCD
-	tristate "USB IP client driver"
-	depends on USB_IP_COMMON
+config USBIP_VHCI_HCD
+	tristate "VHCI hcd"
+	depends on USBIP_CORE
 	default N
 	---help---
-	 This enables the USB IP host controller driver which will
-	 run on the client machine.
+	  This enables the USB/IP virtual host controller driver,
+	  which is run on the remote machine.
 
-	 To compile this driver as a module, choose M here: the
-	 module will be called vhci_hcd.
+	  To compile this driver as a module, choose M here: the
+	  module will be called vhci-hcd.
 
-config USB_IP_HOST
-	tristate "USB IP host driver"
-	depends on USB_IP_COMMON
+config USBIP_HOST
+	tristate "Host driver"
+	depends on USBIP_CORE
 	default N
 	---help---
-	 This enables the USB IP device driver which will run on the
-	 host machine.
+	  This enables the USB/IP host driver, which is run on the
+	  machine that is sharing the USB devices.
 
-	 To compile this driver as a module, choose M here: the
-	 module will be called usbip.
+	  To compile this driver as a module, choose M here: the
+	  module will be called usbip-host.
 
-config USB_IP_DEBUG_ENABLE
-	bool "USB-IP Debug Enable"
-	depends on USB_IP_COMMON
+config USBIP_DEBUG
+	bool "Debug messages for USB/IP"
+	depends on USBIP_CORE
 	default N
 	---help---
-	  This enables the debug messages from the USB-IP drivers.
+	  This enables the debug messages from the USB/IP drivers.
diff -druN linux-2.6.39-libre/drivers/staging/usbip/Makefile linux-3.0-rc7-libre/drivers/staging/usbip/Makefile
--- linux-2.6.39-libre/drivers/staging/usbip/Makefile	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/usbip/Makefile	2011-07-11 19:51:52.000000000 -0400
@@ -1,11 +1,10 @@
-obj-$(CONFIG_USB_IP_COMMON) += usbip_common_mod.o
-usbip_common_mod-y := usbip_common.o usbip_event.o
-
-obj-$(CONFIG_USB_IP_VHCI_HCD) += vhci-hcd.o
-vhci-hcd-y := vhci_sysfs.o vhci_tx.o vhci_rx.o vhci_hcd.o
+ccflags-$(CONFIG_USBIP_DEBUG) := -DDEBUG
 
-obj-$(CONFIG_USB_IP_HOST) += usbip.o
-usbip-y := stub_dev.o stub_main.o stub_rx.o stub_tx.o
+obj-$(CONFIG_USBIP_CORE) += usbip-core.o
+usbip-core-y := usbip_common.o usbip_event.o
 
-ccflags-$(CONFIG_USB_IP_DEBUG_ENABLE) := -DDEBUG
+obj-$(CONFIG_USBIP_VHCI_HCD) += vhci-hcd.o
+vhci-hcd-y := vhci_sysfs.o vhci_tx.o vhci_rx.o vhci_hcd.o
 
+obj-$(CONFIG_USBIP_HOST) += usbip-host.o
+usbip-host-y := stub_dev.o stub_main.o stub_rx.o stub_tx.o
diff -druN linux-2.6.39-libre/drivers/staging/usbip/stub_dev.c linux-3.0-rc7-libre/drivers/staging/usbip/stub_dev.c
--- linux-2.6.39-libre/drivers/staging/usbip/stub_dev.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/usbip/stub_dev.c	2011-07-11 19:51:52.000000000 -0400
@@ -17,18 +17,17 @@
  * USA.
  */
 
-#include <linux/slab.h>
+#include <linux/device.h>
 #include <linux/kthread.h>
 
 #include "usbip_common.h"
 #include "stub.h"
 
-
-
 static int stub_probe(struct usb_interface *interface,
-				const struct usb_device_id *id);
+		      const struct usb_device_id *id);
 static void stub_disconnect(struct usb_interface *interface);
-
+static int stub_pre_reset(struct usb_interface *interface);
+static int stub_post_reset(struct usb_interface *interface);
 
 /*
  * Define device IDs here if you want to explicitly limit exportable devices.
@@ -62,14 +61,10 @@
 	.probe		= stub_probe,
 	.disconnect	= stub_disconnect,
 	.id_table	= stub_table,
+	.pre_reset	= stub_pre_reset,
+	.post_reset	= stub_post_reset,
 };
 
-
-/*-------------------------------------------------------------------------*/
-
-/* Define sysfs entries for a usbip-bound device */
-
-
 /*
  * usbip_status shows status of usbip as long as this driver is bound to the
  * target device.
@@ -128,13 +123,11 @@
 			spin_unlock(&sdev->ud.lock);
 			return -EINVAL;
 		}
-
 #if 0
 		setnodelay(socket);
 		setkeepalive(socket);
 		setreuse(socket);
 #endif
-
 		sdev->ud.tcp_socket = socket;
 
 		spin_unlock(&sdev->ud.lock);
@@ -183,10 +176,8 @@
 
 err_debug:
 	device_remove_file(dev, &dev_attr_usbip_sockfd);
-
 err_sockfd:
 	device_remove_file(dev, &dev_attr_usbip_status);
-
 err_status:
 	return err;
 }
@@ -198,12 +189,6 @@
 	device_remove_file(dev, &dev_attr_usbip_debug);
 }
 
-
-
-/*-------------------------------------------------------------------------*/
-
-/* Event handler functions called by an event handler thread */
-
 static void stub_shutdown_connection(struct usbip_device *ud)
 {
 	struct stub_device *sdev = container_of(ud, struct stub_device, ud);
@@ -215,7 +200,8 @@
 	 * step 1?
 	 */
 	if (ud->tcp_socket) {
-		usbip_udbg("shutdown tcp_socket %p\n", ud->tcp_socket);
+		dev_dbg(&sdev->udev->dev, "shutdown tcp_socket %p\n",
+			ud->tcp_socket);
 		kernel_sock_shutdown(ud->tcp_socket, SHUT_RDWR);
 	}
 
@@ -244,18 +230,15 @@
 		struct stub_unlink *unlink, *tmp;
 
 		spin_lock_irqsave(&sdev->priv_lock, flags);
-
 		list_for_each_entry_safe(unlink, tmp, &sdev->unlink_tx, list) {
 			list_del(&unlink->list);
 			kfree(unlink);
 		}
-
 		list_for_each_entry_safe(unlink, tmp,
 						 &sdev->unlink_free, list) {
 			list_del(&unlink->list);
 			kfree(unlink);
 		}
-
 		spin_unlock_irqrestore(&sdev->priv_lock, flags);
 	}
 }
@@ -266,16 +249,14 @@
 	struct usb_device *udev = sdev->udev;
 	int ret;
 
-	usbip_udbg("device reset");
+	dev_dbg(&udev->dev, "device reset");
 
 	ret = usb_lock_device_for_reset(udev, sdev->interface);
 	if (ret < 0) {
 		dev_err(&udev->dev, "lock for reset\n");
-
 		spin_lock(&ud->lock);
 		ud->status = SDEV_ST_ERROR;
 		spin_unlock(&ud->lock);
-
 		return;
 	}
 
@@ -306,9 +287,6 @@
 	spin_unlock(&ud->lock);
 }
 
-
-/*-------------------------------------------------------------------------*/
-
 /**
  * stub_device_alloc - allocate a new stub_device struct
  * @interface: usb_interface of a new device
@@ -339,13 +317,12 @@
 	 * devnum may change later if a device is reset. However, devid never
 	 * changes during a usbip connection.
 	 */
-	sdev->devid     = (busnum << 16) | devnum;
-
-	sdev->ud.side = USBIP_STUB;
-	sdev->ud.status = SDEV_ST_AVAILABLE;
+	sdev->devid		= (busnum << 16) | devnum;
+	sdev->ud.side		= USBIP_STUB;
+	sdev->ud.status		= SDEV_ST_AVAILABLE;
 	/* sdev->ud.lock = SPIN_LOCK_UNLOCKED; */
 	spin_lock_init(&sdev->ud.lock);
-	sdev->ud.tcp_socket = NULL;
+	sdev->ud.tcp_socket	= NULL;
 
 	INIT_LIST_HEAD(&sdev->priv_init);
 	INIT_LIST_HEAD(&sdev->priv_tx);
@@ -363,7 +340,8 @@
 
 	usbip_start_eh(&sdev->ud);
 
-	usbip_udbg("register new interface\n");
+	dev_dbg(&interface->dev, "register new interface\n");
+
 	return sdev;
 }
 
@@ -373,14 +351,11 @@
 		return -EINVAL;
 
 	kfree(sdev);
-	usbip_udbg("kfree udev ok\n");
+	pr_debug("kfree udev ok\n");
 
 	return 0;
 }
 
-
-/*-------------------------------------------------------------------------*/
-
 /*
  * If a usb device has multiple active interfaces, this driver is bound to all
  * the active interfaces. However, usbip exports *a* usb device (i.e., not *an*
@@ -405,10 +380,9 @@
 	/* check we should claim or not by busid_table */
 	busid_priv = get_busid_priv(udev_busid);
 	if (!busid_priv  || (busid_priv->status == STUB_BUSID_REMOV) ||
-			     (busid_priv->status == STUB_BUSID_OTHER)) {
-		dev_info(&interface->dev,
-			 "this device %s is not in match_busid table. skip!\n",
-			 udev_busid);
+	    (busid_priv->status == STUB_BUSID_OTHER)) {
+		dev_info(&interface->dev, "%s is not in match_busid table... "
+			 "skip!\n", udev_busid);
 
 		/*
 		 * Return value should be ENODEV or ENOXIO to continue trying
@@ -418,36 +392,35 @@
 		return -ENODEV;
 	}
 
-	if (udev->descriptor.bDeviceClass ==  USB_CLASS_HUB) {
-		usbip_udbg("this device %s is a usb hub device. skip!\n",
-								udev_busid);
+	if (udev->descriptor.bDeviceClass == USB_CLASS_HUB) {
+		dev_dbg(&udev->dev, "%s is a usb hub device... skip!\n",
+			 udev_busid);
 		return -ENODEV;
 	}
 
 	if (!strcmp(udev->bus->bus_name, "vhci_hcd")) {
-		usbip_udbg("this device %s is attached on vhci_hcd. skip!\n",
-								udev_busid);
+		dev_dbg(&udev->dev, "%s is attached on vhci_hcd... skip!\n",
+			 udev_busid);
 		return -ENODEV;
 	}
 
-
 	if (busid_priv->status == STUB_BUSID_ALLOC) {
 		sdev = busid_priv->sdev;
 		if (!sdev)
 			return -ENODEV;
 
 		busid_priv->interf_count++;
-		dev_info(&interface->dev,
-		 "USB/IP Stub: register a new interface "
-		 "(bus %u dev %u ifn %u)\n", udev->bus->busnum, udev->devnum,
-		 interface->cur_altsetting->desc.bInterfaceNumber);
+		dev_info(&interface->dev, "usbip-host: register new interface "
+			 "(bus %u dev %u ifn %u)\n",
+			 udev->bus->busnum, udev->devnum,
+			 interface->cur_altsetting->desc.bInterfaceNumber);
 
 		/* set private data to usb_interface */
 		usb_set_intfdata(interface, sdev);
 
 		err = stub_add_files(&interface->dev);
 		if (err) {
-			dev_err(&interface->dev, "create sysfs files for %s\n",
+			dev_err(&interface->dev, "stub_add_files for %s\n",
 				udev_busid);
 			usb_set_intfdata(interface, NULL);
 			busid_priv->interf_count--;
@@ -464,7 +437,7 @@
 	if (!sdev)
 		return -ENOMEM;
 
-	dev_info(&interface->dev, "USB/IP Stub: register a new device "
+	dev_info(&interface->dev, "usbip-host: register new device "
 		 "(bus %u dev %u ifn %u)\n", udev->bus->busnum, udev->devnum,
 		 interface->cur_altsetting->desc.bInterfaceNumber);
 
@@ -479,8 +452,7 @@
 
 	err = stub_add_files(&interface->dev);
 	if (err) {
-		dev_err(&interface->dev, "create sysfs files for %s\n",
-			udev_busid);
+		dev_err(&interface->dev, "stub_add_files for %s\n", udev_busid);
 		usb_set_intfdata(interface, NULL);
 		usb_put_intf(interface);
 
@@ -504,10 +476,8 @@
 		/* 2. wait for the stop of the event handler */
 		usbip_stop_eh(&busid_priv->sdev->ud);
 	}
-
 }
 
-
 /*
  * called in usb_disconnect() or usb_deregister()
  * but only if actconfig(active configuration) exists
@@ -518,10 +488,9 @@
 	const char *udev_busid = dev_name(interface->dev.parent);
 	struct bus_id_priv *busid_priv;
 
-	busid_priv = get_busid_priv(udev_busid);
-
-	usbip_udbg("Enter\n");
+	dev_dbg(&interface->dev, "Enter\n");
 
+	busid_priv = get_busid_priv(udev_busid);
 	if (!busid_priv) {
 		BUG();
 		return;
@@ -531,7 +500,7 @@
 
 	/* get stub_device */
 	if (!sdev) {
-		err(" could not get device from inteface data");
+		dev_err(&interface->dev, "could not get device");
 		/* BUG(); */
 		return;
 	}
@@ -559,7 +528,6 @@
 
 	busid_priv->interf_count = 0;
 
-
 	/* 1. shutdown the current connection */
 	shutdown_busid(busid_priv);
 
@@ -576,5 +544,21 @@
 		busid_priv->status = STUB_BUSID_OTHER;
 		del_match_busid((char *)udev_busid);
 	}
-	usbip_udbg("bye\n");
+}
+
+/* 
+ * Presence of pre_reset and post_reset prevents the driver from being unbound
+ * when the device is being reset
+ */
+ 
+int stub_pre_reset(struct usb_interface *interface)
+{
+	dev_dbg(&interface->dev, "pre_reset\n");
+	return 0;
+}
+
+int stub_post_reset(struct usb_interface *interface)
+{
+	dev_dbg(&interface->dev, "post_reset\n");
+	return 0;
 }
diff -druN linux-2.6.39-libre/drivers/staging/usbip/stub.h linux-3.0-rc7-libre/drivers/staging/usbip/stub.h
--- linux-2.6.39-libre/drivers/staging/usbip/stub.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/usbip/stub.h	2011-07-11 19:51:52.000000000 -0400
@@ -17,13 +17,12 @@
  * USA.
  */
 
-#include <linux/kernel.h>
 #include <linux/list.h>
-#include <linux/spinlock.h>
 #include <linux/slab.h>
-#include <linux/string.h>
-#include <linux/module.h>
-#include <linux/net.h>
+#include <linux/spinlock.h>
+#include <linux/types.h>
+#include <linux/usb.h>
+#include <linux/wait.h>
 
 #define STUB_BUSID_OTHER 0
 #define STUB_BUSID_REMOV 1
@@ -58,7 +57,6 @@
 	struct list_head unlink_tx;
 	struct list_head unlink_free;
 
-
 	wait_queue_head_t tx_waitq;
 };
 
@@ -87,25 +85,22 @@
 	char shutdown_busid;
 };
 
+/* stub_priv is allocated from stub_priv_cache */
 extern struct kmem_cache *stub_priv_cache;
 
-
-/*-------------------------------------------------------------------------*/
-/* prototype declarations */
-
-/* stub_tx.c */
-void stub_complete(struct urb *);
-int stub_tx_loop(void *data);
-
 /* stub_dev.c */
 extern struct usb_driver stub_driver;
 
-/* stub_rx.c */
-int stub_rx_loop(void *data);
-void stub_enqueue_ret_unlink(struct stub_device *, __u32, __u32);
-
 /* stub_main.c */
 struct bus_id_priv *get_busid_priv(const char *busid);
 int del_match_busid(char *busid);
-
 void stub_device_cleanup_urbs(struct stub_device *sdev);
+
+/* stub_rx.c */
+int stub_rx_loop(void *data);
+
+/* stub_tx.c */
+void stub_enqueue_ret_unlink(struct stub_device *sdev, __u32 seqnum,
+			     __u32 status);
+void stub_complete(struct urb *urb);
+int stub_tx_loop(void *data);
diff -druN linux-2.6.39-libre/drivers/staging/usbip/stub_main.c linux-3.0-rc7-libre/drivers/staging/usbip/stub_main.c
--- linux-2.6.39-libre/drivers/staging/usbip/stub_main.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/usbip/stub_main.c	2011-07-11 19:51:52.000000000 -0400
@@ -17,24 +17,17 @@
  * USA.
  */
 
-#include <linux/slab.h>
+#include <linux/string.h>
 
 #include "usbip_common.h"
 #include "stub.h"
 
-/* Version Information */
-#define DRIVER_VERSION "1.0"
 #define DRIVER_AUTHOR "Takahiro Hirofuchi"
-#define DRIVER_DESC "Stub Driver for USB/IP"
+#define DRIVER_DESC "USB/IP Host Driver"
 
 /* stub_priv is allocated from stub_priv_cache */
 struct kmem_cache *stub_priv_cache;
 
-/*-------------------------------------------------------------------------*/
-
-/* Define sysfs entries for the usbip driver */
-
-
 /*
  * busid_tables defines matching busids that usbip can grab. A user can change
  * dynamically what device is locally used and what device is exported to a
@@ -44,7 +37,6 @@
 static struct bus_id_priv busid_table[MAX_BUSID];
 static spinlock_t busid_table_lock;
 
-
 int match_busid(const char *busid)
 {
 	int i;
@@ -148,11 +140,11 @@
 
 	return -1;
 }
+
 static void init_busid_table(void)
 {
 	int i;
 
-
 	for (i = 0; i < MAX_BUSID; i++) {
 		memset(busid_table[i].name, 0, BUSID_SIZE);
 		busid_table[i].status = STUB_BUSID_OTHER;
@@ -160,11 +152,12 @@
 		busid_table[i].sdev = NULL;
 		busid_table[i].shutdown_busid = 0;
 	}
+
 	spin_lock_init(&busid_table_lock);
 }
 
 static ssize_t store_match_busid(struct device_driver *dev, const char *buf,
-		size_t count)
+				 size_t count)
 {
 	int len;
 	char busid[BUSID_SIZE];
@@ -181,33 +174,25 @@
 
 	strncpy(busid, buf + 4, BUSID_SIZE);
 
-
 	if (!strncmp(buf, "add ", 4)) {
 		if (add_match_busid(busid) < 0)
 			return -ENOMEM;
 		else {
-			usbip_udbg("add busid %s\n", busid);
+			pr_debug("add busid %s\n", busid);
 			return count;
 		}
 	} else if (!strncmp(buf, "del ", 4)) {
 		if (del_match_busid(busid) < 0)
 			return -ENODEV;
 		else {
-			usbip_udbg("del busid %s\n", busid);
+			pr_debug("del busid %s\n", busid);
 			return count;
 		}
 	} else
 		return -EINVAL;
 }
-
 static DRIVER_ATTR(match_busid, S_IRUSR|S_IWUSR, show_match_busid,
-							store_match_busid);
-
-
-
-/*-------------------------------------------------------------------------*/
-
-/* Cleanup functions used to free private data */
+		   store_match_busid);
 
 static struct stub_priv *stub_priv_pop_from_listhead(struct list_head *listhead)
 {
@@ -254,27 +239,23 @@
 {
 	struct stub_priv *priv;
 
-	usbip_udbg("free sdev %p\n", sdev);
+	dev_dbg(&sdev->udev->dev, "free sdev %p\n", sdev);
 
 	while ((priv = stub_priv_pop(sdev))) {
 		struct urb *urb = priv->urb;
 
-		usbip_udbg("   free urb %p\n", urb);
+		dev_dbg(&sdev->udev->dev, "free urb %p\n", urb);
 		usb_kill_urb(urb);
 
 		kmem_cache_free(stub_priv_cache, priv);
 
 		kfree(urb->transfer_buffer);
-
 		kfree(urb->setup_packet);
 
 		usb_free_urb(urb);
 	}
 }
 
-
-/*-------------------------------------------------------------------------*/
-
 static int __init usb_stub_init(void)
 {
 	int ret;
@@ -284,20 +265,17 @@
 					    SLAB_HWCACHE_ALIGN, NULL);
 
 	if (!stub_priv_cache) {
-		printk(KERN_ERR KBUILD_MODNAME
-		       ": create stub_priv_cache error\n");
+		pr_err("create stub_priv_cache error\n");
 		return -ENOMEM;
 	}
 
 	ret = usb_register(&stub_driver);
 	if (ret) {
-		printk(KERN_ERR KBUILD_MODNAME ": usb_register failed %d\n",
-		       ret);
+		pr_err("usb_register failed %d\n", ret);
 		goto error_usb_register;
 	}
 
-	printk(KERN_INFO KBUILD_MODNAME ":"
-	       DRIVER_DESC ":" DRIVER_VERSION "\n");
+	pr_info(DRIVER_DESC " " USBIP_VERSION "\n");
 
 	init_busid_table();
 
@@ -305,7 +283,7 @@
 				 &driver_attr_match_busid);
 
 	if (ret) {
-		printk(KERN_ERR KBUILD_MODNAME ": create driver sysfs\n");
+		pr_err("create driver sysfs\n");
 		goto error_create_file;
 	}
 
@@ -337,3 +315,4 @@
 MODULE_AUTHOR(DRIVER_AUTHOR);
 MODULE_DESCRIPTION(DRIVER_DESC);
 MODULE_LICENSE("GPL");
+MODULE_VERSION(USBIP_VERSION);
diff -druN linux-2.6.39-libre/drivers/staging/usbip/stub_rx.c linux-3.0-rc7-libre/drivers/staging/usbip/stub_rx.c
--- linux-2.6.39-libre/drivers/staging/usbip/stub_rx.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/usbip/stub_rx.c	2011-07-11 19:51:52.000000000 -0400
@@ -17,13 +17,13 @@
  * USA.
  */
 
-#include <linux/slab.h>
+#include <asm/byteorder.h>
 #include <linux/kthread.h>
+#include <linux/usb.h>
+#include <linux/usb/hcd.h>
 
 #include "usbip_common.h"
 #include "stub.h"
-#include <linux/usb/hcd.h>
-
 
 static int is_clear_halt_cmd(struct urb *urb)
 {
@@ -43,7 +43,7 @@
 	req = (struct usb_ctrlrequest *) urb->setup_packet;
 
 	return (req->bRequest == USB_REQ_SET_INTERFACE) &&
-		   (req->bRequestType == USB_RECIP_INTERFACE);
+		(req->bRequestType == USB_RECIP_INTERFACE);
 }
 
 static int is_set_configuration_cmd(struct urb *urb)
@@ -53,7 +53,7 @@
 	req = (struct usb_ctrlrequest *) urb->setup_packet;
 
 	return (req->bRequest == USB_REQ_SET_CONFIGURATION) &&
-		   (req->bRequestType == USB_RECIP_DEVICE);
+		(req->bRequestType == USB_RECIP_DEVICE);
 }
 
 static int is_reset_device_cmd(struct urb *urb)
@@ -67,8 +67,8 @@
 	index = le16_to_cpu(req->wIndex);
 
 	if ((req->bRequest == USB_REQ_SET_FEATURE) &&
-			(req->bRequestType == USB_RT_PORT) &&
-			(value == USB_PORT_FEAT_RESET)) {
+	    (req->bRequestType == USB_RT_PORT) &&
+	    (value == USB_PORT_FEAT_RESET)) {
 		usbip_dbg_stub_rx("reset_device_cmd, port %u\n", index);
 		return 1;
 	} else
@@ -102,11 +102,11 @@
 
 	ret = usb_clear_halt(urb->dev, target_pipe);
 	if (ret < 0)
-		usbip_uinfo("clear_halt error: devnum %d endp %d, %d\n",
-					urb->dev->devnum, target_endp, ret);
+		dev_err(&urb->dev->dev, "usb_clear_halt error: devnum %d endp "
+			"%d ret %d\n", urb->dev->devnum, target_endp, ret);
 	else
-		usbip_uinfo("clear_halt done: devnum %d endp %d\n",
-					urb->dev->devnum, target_endp);
+		dev_info(&urb->dev->dev, "usb_clear_halt done: devnum %d endp "
+			 "%d\n", urb->dev->devnum, target_endp);
 
 	return ret;
 }
@@ -122,17 +122,16 @@
 	alternate = le16_to_cpu(req->wValue);
 	interface = le16_to_cpu(req->wIndex);
 
-	usbip_dbg_stub_rx("set_interface: inf %u alt %u\n", interface,
-								alternate);
+	usbip_dbg_stub_rx("set_interface: inf %u alt %u\n",
+			  interface, alternate);
 
 	ret = usb_set_interface(urb->dev, interface, alternate);
 	if (ret < 0)
-		usbip_uinfo("set_interface error: inf %u alt %u, %d\n",
-					interface, alternate, ret);
+		dev_err(&urb->dev->dev, "usb_set_interface error: inf %u alt "
+			"%u ret %d\n", interface, alternate, ret);
 	else
-		usbip_uinfo("set_interface done: inf %u alt %u\n",
-							interface,
-							alternate);
+		dev_info(&urb->dev->dev, "usb_set_interface done: inf %u alt "
+			 "%u\n", interface, alternate);
 
 	return ret;
 }
@@ -161,9 +160,8 @@
 	 * A user may need to set a special configuration value before
 	 * exporting the device.
 	 */
-	usbip_uinfo("set_configuration (%d) to %s\n", config,
-						dev_name(&urb->dev->dev));
-	usbip_uinfo("but, skip!\n");
+	dev_info(&urb->dev->dev, "usb_set_configuration %d to %s... skip!\n",
+		 config, dev_name(&urb->dev->dev));
 
 	return 0;
 	/* return usb_driver_set_configuration(urb->dev, config); */
@@ -174,19 +172,21 @@
 	struct stub_priv *priv = (struct stub_priv *) urb->context;
 	struct stub_device *sdev = priv->sdev;
 
-	usbip_uinfo("reset_device %s\n", dev_name(&urb->dev->dev));
+	dev_info(&urb->dev->dev, "usb_queue_reset_device\n");
 
 	/*
-	 * usb_lock_device_for_reset caused a deadlock: it causes the driver
-	 * to unbind. In the shutdown the rx thread is signalled to shut down
-	 * but this thread is pending in the usb_lock_device_for_reset.
-	 *
-	 * Instead queue the reset.
-	 *
-	 * Unfortunatly an existing usbip connection will be dropped due to
-	 * driver unbinding.
+	 * With the implementation of pre_reset and post_reset the driver no 
+	 * longer unbinds. This allows the use of synchronous reset.
 	 */
-	usb_queue_reset_device(sdev->interface);
+
+	if (usb_lock_device_for_reset(sdev->udev, sdev->interface)<0)
+	{
+		dev_err(&urb->dev->dev, "could not obtain lock to reset device\n");
+		return 0;
+	}
+	usb_reset_device(sdev->udev);
+	usb_unlock_device(sdev->udev);
+
 	return 0;
 }
 
@@ -228,13 +228,12 @@
  * See also comments about unlinking strategy in vhci_hcd.c.
  */
 static int stub_recv_cmd_unlink(struct stub_device *sdev,
-						struct usbip_header *pdu)
+				struct usbip_header *pdu)
 {
 	unsigned long flags;
 
 	struct stub_priv *priv;
 
-
 	spin_lock_irqsave(&sdev->priv_lock, flags);
 
 	list_for_each_entry(priv, &sdev->priv_init, list) {
@@ -289,7 +288,7 @@
 	}
 
 	usbip_dbg_stub_rx("seqnum %d is not pending\n",
-						pdu->u.cmd_unlink.seqnum);
+			  pdu->u.cmd_unlink.seqnum);
 
 	/*
 	 * The urb of the unlink target is not found in priv_init queue. It was
@@ -301,7 +300,6 @@
 
 	spin_unlock_irqrestore(&sdev->priv_lock, flags);
 
-
 	return 0;
 }
 
@@ -370,8 +368,6 @@
 	}
 
 	epd = &ep->desc;
-
-
 #if 0
 	/* epnum 0 is always control */
 	if (epnum == 0) {
@@ -381,7 +377,6 @@
 			return usb_rcvctrlpipe(udev, 0);
 	}
 #endif
-
 	if (usb_endpoint_xfer_control(epd)) {
 		if (dir == USBIP_DIR_OUT)
 			return usb_sndctrlpipe(udev, epnum);
@@ -430,19 +425,19 @@
 		return;
 
 	ep = (usb_pipein(urb->pipe) ? dev->ep_in : dev->ep_out)
-			[usb_pipeendpoint(urb->pipe)];
+		[usb_pipeendpoint(urb->pipe)];
 	if (!ep)
 		return;
 
 	xfertype = usb_endpoint_type(&ep->desc);
 	if (xfertype == USB_ENDPOINT_XFER_CONTROL) {
 		struct usb_ctrlrequest *setup =
-				(struct usb_ctrlrequest *) urb->setup_packet;
+			(struct usb_ctrlrequest *) urb->setup_packet;
 
 		if (!setup)
 			return;
 		is_out = !(setup->bRequestType & USB_DIR_IN) ||
-				!setup->wLength;
+			!setup->wLength;
 	} else {
 		is_out = usb_endpoint_dir_out(&ep->desc);
 	}
@@ -478,7 +473,6 @@
 	struct usb_device *udev = sdev->udev;
 	int pipe = get_pipe(sdev, pdu->base.ep, pdu->base.direction);
 
-
 	priv = stub_priv_alloc(sdev, pdu);
 	if (!priv)
 		return;
@@ -486,7 +480,7 @@
 	/* setup a urb */
 	if (usb_pipeisoc(pipe))
 		priv->urb = usb_alloc_urb(pdu->u.cmd_submit.number_of_packets,
-								GFP_KERNEL);
+					  GFP_KERNEL);
 	else
 		priv->urb = usb_alloc_urb(0, GFP_KERNEL);
 
@@ -500,7 +494,7 @@
 	if (pdu->u.cmd_submit.transfer_buffer_length > 0) {
 		priv->urb->transfer_buffer =
 			kzalloc(pdu->u.cmd_submit.transfer_buffer_length,
-								GFP_KERNEL);
+				GFP_KERNEL);
 		if (!priv->urb->transfer_buffer) {
 			dev_err(&sdev->interface->dev, "malloc x_buff\n");
 			usbip_event_add(ud, SDEV_EVENT_ERROR_MALLOC);
@@ -541,7 +535,7 @@
 
 	if (ret == 0)
 		usbip_dbg_stub_rx("submit urb ok, seqnum %u\n",
-							pdu->base.seqnum);
+				  pdu->base.seqnum);
 	else {
 		dev_err(&sdev->interface->dev, "submit_urb error, %d\n", ret);
 		usbip_dump_header(pdu);
@@ -602,9 +596,8 @@
 		/* NOTREACHED */
 		dev_err(dev, "unknown pdu\n");
 		usbip_event_add(ud, SDEV_EVENT_ERROR_TCP);
-		return;
+		break;
 	}
-
 }
 
 int stub_rx_loop(void *data)
@@ -617,5 +610,6 @@
 
 		stub_rx_pdu(ud);
 	}
+
 	return 0;
 }
diff -druN linux-2.6.39-libre/drivers/staging/usbip/stub_tx.c linux-3.0-rc7-libre/drivers/staging/usbip/stub_tx.c
--- linux-2.6.39-libre/drivers/staging/usbip/stub_tx.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/usbip/stub_tx.c	2011-07-11 19:51:52.000000000 -0400
@@ -17,13 +17,12 @@
  * USA.
  */
 
-#include <linux/slab.h>
 #include <linux/kthread.h>
+#include <linux/socket.h>
 
 #include "usbip_common.h"
 #include "stub.h"
 
-
 static void stub_free_priv_and_urb(struct stub_priv *priv)
 {
 	struct urb *urb = priv->urb;
@@ -71,28 +70,29 @@
 
 	usbip_dbg_stub_tx("complete! status %d\n", urb->status);
 
-
 	switch (urb->status) {
 	case 0:
 		/* OK */
 		break;
 	case -ENOENT:
-		usbip_uinfo("stopped by a call of usb_kill_urb() because of"
-					"cleaning up a virtual connection\n");
+		dev_info(&urb->dev->dev, "stopped by a call to usb_kill_urb() "
+			 "because of cleaning up a virtual connection\n");
 		return;
 	case -ECONNRESET:
-		usbip_uinfo("unlinked by a call of usb_unlink_urb()\n");
+		dev_info(&urb->dev->dev, "unlinked by a call to "
+			 "usb_unlink_urb()\n");
 		break;
 	case -EPIPE:
-		usbip_uinfo("endpoint %d is stalled\n",
-						usb_pipeendpoint(urb->pipe));
+		dev_info(&urb->dev->dev, "endpoint %d is stalled\n",
+			 usb_pipeendpoint(urb->pipe));
 		break;
 	case -ESHUTDOWN:
-		usbip_uinfo("device removed?\n");
+		dev_info(&urb->dev->dev, "device removed?\n");
 		break;
 	default:
-		usbip_uinfo("urb completion with non-zero status %d\n",
-							urb->status);
+		dev_info(&urb->dev->dev, "urb completion with non-zero status "
+			 "%d\n", urb->status);
+		break;
 	}
 
 	/* link a urb to the queue of tx. */
@@ -104,25 +104,20 @@
 	} else
 		list_move_tail(&priv->list, &sdev->priv_tx);
 
-
 	spin_unlock_irqrestore(&sdev->priv_lock, flags);
 
 	/* wake up tx_thread */
 	wake_up(&sdev->tx_waitq);
 }
 
-
-/*-------------------------------------------------------------------------*/
-/* fill PDU */
-
 static inline void setup_base_pdu(struct usbip_header_basic *base,
-		__u32 command, __u32 seqnum)
+				  __u32 command, __u32 seqnum)
 {
 	base->command = command;
 	base->seqnum  = seqnum;
 	base->devid   = 0;
 	base->ep      = 0;
-	base->direction   = 0;
+	base->direction = 0;
 }
 
 static void setup_ret_submit_pdu(struct usbip_header *rpdu, struct urb *urb)
@@ -130,22 +125,16 @@
 	struct stub_priv *priv = (struct stub_priv *) urb->context;
 
 	setup_base_pdu(&rpdu->base, USBIP_RET_SUBMIT, priv->seqnum);
-
 	usbip_pack_pdu(rpdu, urb, USBIP_RET_SUBMIT, 1);
 }
 
 static void setup_ret_unlink_pdu(struct usbip_header *rpdu,
-		struct stub_unlink *unlink)
+				 struct stub_unlink *unlink)
 {
 	setup_base_pdu(&rpdu->base, USBIP_RET_UNLINK, unlink->seqnum);
-
 	rpdu->u.ret_unlink.status = unlink->status;
 }
 
-
-/*-------------------------------------------------------------------------*/
-/* send RET_SUBMIT */
-
 static struct stub_priv *dequeue_from_priv_tx(struct stub_device *sdev)
 {
 	unsigned long flags;
@@ -203,7 +192,7 @@
 		/* 1. setup usbip_header */
 		setup_ret_submit_pdu(&pdu_header, urb);
 		usbip_dbg_stub_tx("setup txdata seqnum: %d urb: %p\n",
-						pdu_header.base.seqnum, urb);
+				  pdu_header.base.seqnum, urb);
 		/*usbip_dump_header(pdu_header);*/
 		usbip_header_correct_endian(&pdu_header, 1);
 
@@ -214,14 +203,14 @@
 
 		/* 2. setup transfer buffer */
 		if (usb_pipein(urb->pipe) &&
-				usb_pipetype(urb->pipe) != PIPE_ISOCHRONOUS &&
-					urb->actual_length > 0) {
+		    usb_pipetype(urb->pipe) != PIPE_ISOCHRONOUS &&
+		    urb->actual_length > 0) {
 			iov[iovnum].iov_base = urb->transfer_buffer;
 			iov[iovnum].iov_len  = urb->actual_length;
 			iovnum++;
 			txsize += urb->actual_length;
 		} else if (usb_pipein(urb->pipe) &&
-				usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS) {
+			   usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS) {
 			/*
 			 * For isochronous packets: actual length is the sum of
 			 * the actual length of the individual, packets, but as
@@ -232,18 +221,23 @@
 
 			int i;
 			for (i = 0; i < urb->number_of_packets; i++) {
-				iov[iovnum].iov_base = urb->transfer_buffer + urb->iso_frame_desc[i].offset;
-				iov[iovnum].iov_len = urb->iso_frame_desc[i].actual_length;
+				iov[iovnum].iov_base = urb->transfer_buffer +
+					urb->iso_frame_desc[i].offset;
+				iov[iovnum].iov_len =
+					urb->iso_frame_desc[i].actual_length;
 				iovnum++;
 				txsize += urb->iso_frame_desc[i].actual_length;
 			}
 
 			if (txsize != sizeof(pdu_header) + urb->actual_length) {
 				dev_err(&sdev->interface->dev,
-					"actual length of urb (%d) does not match iso packet sizes (%d)\n",
-					urb->actual_length, txsize-sizeof(pdu_header));
+					"actual length of urb %d does not "
+					"match iso packet sizes %lu\n",
+					urb->actual_length,
+					txsize-sizeof(pdu_header));
 				kfree(iov);
-				usbip_event_add(&sdev->ud, SDEV_EVENT_ERROR_TCP);
+				usbip_event_add(&sdev->ud,
+						SDEV_EVENT_ERROR_TCP);
 			   return -1;
 			}
 		}
@@ -285,20 +279,14 @@
 	}
 
 	spin_lock_irqsave(&sdev->priv_lock, flags);
-
 	list_for_each_entry_safe(priv, tmp, &sdev->priv_free, list) {
 		stub_free_priv_and_urb(priv);
 	}
-
 	spin_unlock_irqrestore(&sdev->priv_lock, flags);
 
 	return total_size;
 }
 
-
-/*-------------------------------------------------------------------------*/
-/* send RET_UNLINK */
-
 static struct stub_unlink *dequeue_from_unlink_tx(struct stub_device *sdev)
 {
 	unsigned long flags;
@@ -317,7 +305,6 @@
 	return NULL;
 }
 
-
 static int stub_send_ret_unlink(struct stub_device *sdev)
 {
 	unsigned long flags;
@@ -358,13 +345,10 @@
 			return -1;
 		}
 
-
 		usbip_dbg_stub_tx("send txdata\n");
-
 		total_size += txsize;
 	}
 
-
 	spin_lock_irqsave(&sdev->priv_lock, flags);
 
 	list_for_each_entry_safe(unlink, tmp, &sdev->unlink_free, list) {
@@ -377,9 +361,6 @@
 	return total_size;
 }
 
-
-/*-------------------------------------------------------------------------*/
-
 int stub_tx_loop(void *data)
 {
 	struct usbip_device *ud = data;
@@ -410,9 +391,9 @@
 			break;
 
 		wait_event_interruptible(sdev->tx_waitq,
-				(!list_empty(&sdev->priv_tx) ||
-				 !list_empty(&sdev->unlink_tx) ||
-				 kthread_should_stop()));
+					 (!list_empty(&sdev->priv_tx) ||
+					  !list_empty(&sdev->unlink_tx) ||
+					  kthread_should_stop()));
 	}
 
 	return 0;
diff -druN linux-2.6.39-libre/drivers/staging/usbip/usbip_common.c linux-3.0-rc7-libre/drivers/staging/usbip/usbip_common.c
--- linux-2.6.39-libre/drivers/staging/usbip/usbip_common.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/usbip/usbip_common.c	2011-07-11 19:51:52.000000000 -0400
@@ -17,53 +17,46 @@
  * USA.
  */
 
-#include <linux/kernel.h>
+#include <asm/byteorder.h>
 #include <linux/file.h>
-#include <linux/tcp.h>
-#include <linux/in.h>
-#include <linux/kthread.h>
+#include <linux/fs.h>
+#include <linux/kernel.h>
 #include <linux/slab.h>
-#include "usbip_common.h"
+#include <net/sock.h>
 
-/* version information */
-#define DRIVER_VERSION "1.0"
-#define DRIVER_AUTHOR "Takahiro Hirofuchi <hirofuchi _at_ users.sourceforge.net>"
-#define DRIVER_DESC "usbip common driver"
+#include "usbip_common.h"
 
-/*-------------------------------------------------------------------------*/
-/* debug routines */
+#define DRIVER_AUTHOR "Takahiro Hirofuchi <hirofuchi@users.sourceforge.net>"
+#define DRIVER_DESC "USB/IP Core"
 
-#ifdef CONFIG_USB_IP_DEBUG_ENABLE
+#ifdef CONFIG_USBIP_DEBUG
 unsigned long usbip_debug_flag = 0xffffffff;
 #else
 unsigned long usbip_debug_flag;
 #endif
 EXPORT_SYMBOL_GPL(usbip_debug_flag);
 
-
 /* FIXME */
 struct device_attribute dev_attr_usbip_debug;
 EXPORT_SYMBOL_GPL(dev_attr_usbip_debug);
 
-
 static ssize_t show_flag(struct device *dev, struct device_attribute *attr,
-								char *buf)
+			 char *buf)
 {
 	return sprintf(buf, "%lx\n", usbip_debug_flag);
 }
 
 static ssize_t store_flag(struct device *dev, struct device_attribute *attr,
-		const char *buf, size_t count)
+			  const char *buf, size_t count)
 {
 	sscanf(buf, "%lx", &usbip_debug_flag);
-
 	return count;
 }
 DEVICE_ATTR(usbip_debug, (S_IRUGO | S_IWUSR), show_flag, store_flag);
 
 static void usbip_dump_buffer(char *buff, int bufflen)
 {
-	print_hex_dump(KERN_DEBUG, "usb-ip", DUMP_PREFIX_OFFSET, 16, 4,
+	print_hex_dump(KERN_DEBUG, "usbip-core", DUMP_PREFIX_OFFSET, 16, 4,
 		       buff, bufflen, false);
 }
 
@@ -74,29 +67,25 @@
 	unsigned char dev = usb_pipedevice(p);
 	unsigned char dir = usb_pipein(p);
 
-	printk(KERN_DEBUG "dev(%d) ", dev);
-	printk(KERN_DEBUG "ep(%d) ",  ep);
-	printk(KERN_DEBUG "%s ", dir ? "IN" : "OUT");
+	pr_debug("dev(%d) ep(%d) [%s] ", dev, ep, dir ? "IN" : "OUT");
 
 	switch (type) {
 	case PIPE_ISOCHRONOUS:
-		printk(KERN_DEBUG "%s ", "ISO");
+		pr_debug("ISO\n");
 		break;
 	case PIPE_INTERRUPT:
-		printk(KERN_DEBUG "%s ", "INT");
+		pr_debug("INT\n");
 		break;
 	case PIPE_CONTROL:
-		printk(KERN_DEBUG "%s ", "CTL");
+		pr_debug("CTRL\n");
 		break;
 	case PIPE_BULK:
-		printk(KERN_DEBUG "%s ", "BLK");
+		pr_debug("BULK\n");
 		break;
 	default:
-		printk(KERN_DEBUG "ERR");
+		pr_debug("ERR\n");
+		break;
 	}
-
-	printk(KERN_DEBUG "\n");
-
 }
 
 static void usbip_dump_usb_device(struct usb_device *udev)
@@ -104,60 +93,59 @@
 	struct device *dev = &udev->dev;
 	int i;
 
-	dev_dbg(dev, "       devnum(%d) devpath(%s)",
+	dev_dbg(dev, "       devnum(%d) devpath(%s) ",
 		udev->devnum, udev->devpath);
 
 	switch (udev->speed) {
 	case USB_SPEED_HIGH:
-		printk(KERN_DEBUG " SPD_HIGH");
+		pr_debug("SPD_HIGH ");
 		break;
 	case USB_SPEED_FULL:
-		printk(KERN_DEBUG " SPD_FULL");
+		pr_debug("SPD_FULL ");
 		break;
 	case USB_SPEED_LOW:
-		printk(KERN_DEBUG " SPD_LOW");
+		pr_debug("SPD_LOW ");
 		break;
 	case USB_SPEED_UNKNOWN:
-		printk(KERN_DEBUG " SPD_UNKNOWN");
+		pr_debug("SPD_UNKNOWN ");
 		break;
 	default:
-		printk(KERN_DEBUG " SPD_ERROR");
+		pr_debug("SPD_ERROR ");
+		break;
 	}
 
-	printk(KERN_DEBUG " tt %p, ttport %d", udev->tt, udev->ttport);
-	printk(KERN_DEBUG "\n");
+	pr_debug("tt %p, ttport %d\n", udev->tt, udev->ttport);
 
 	dev_dbg(dev, "                    ");
 	for (i = 0; i < 16; i++)
-		printk(KERN_DEBUG " %2u", i);
-	printk(KERN_DEBUG "\n");
+		pr_debug(" %2u", i);
+	pr_debug("\n");
 
 	dev_dbg(dev, "       toggle0(IN) :");
 	for (i = 0; i < 16; i++)
-		printk(KERN_DEBUG " %2u", (udev->toggle[0] & (1 << i)) ? 1 : 0);
-	printk(KERN_DEBUG "\n");
+		pr_debug(" %2u", (udev->toggle[0] & (1 << i)) ? 1 : 0);
+	pr_debug("\n");
 
 	dev_dbg(dev, "       toggle1(OUT):");
 	for (i = 0; i < 16; i++)
-		printk(KERN_DEBUG " %2u", (udev->toggle[1] & (1 << i)) ? 1 : 0);
-	printk(KERN_DEBUG "\n");
-
+		pr_debug(" %2u", (udev->toggle[1] & (1 << i)) ? 1 : 0);
+	pr_debug("\n");
 
 	dev_dbg(dev, "       epmaxp_in   :");
 	for (i = 0; i < 16; i++) {
 		if (udev->ep_in[i])
-			printk(KERN_DEBUG " %2u",
-			     le16_to_cpu(udev->ep_in[i]->desc.wMaxPacketSize));
+			pr_debug(" %2u",
+			    le16_to_cpu(udev->ep_in[i]->desc.wMaxPacketSize));
 	}
-	printk(KERN_DEBUG "\n");
+	pr_debug("\n");
 
 	dev_dbg(dev, "       epmaxp_out  :");
 	for (i = 0; i < 16; i++) {
 		if (udev->ep_out[i])
-			printk(KERN_DEBUG " %2u",
-			     le16_to_cpu(udev->ep_out[i]->desc.wMaxPacketSize));
+			pr_debug(" %2u",
+			    le16_to_cpu(udev->ep_out[i]->desc.wMaxPacketSize));
 	}
-	printk(KERN_DEBUG "\n");
+	pr_debug("\n");
 
 	dev_dbg(dev, "parent %p, bus %p\n", udev->parent, udev->bus);
 
@@ -176,91 +164,84 @@
 {
 	switch (rt & USB_RECIP_MASK) {
 	case USB_RECIP_DEVICE:
-		printk(KERN_DEBUG "DEVICE");
+		pr_debug("DEVICE");
 		break;
 	case USB_RECIP_INTERFACE:
-		printk(KERN_DEBUG "INTERF");
+		pr_debug("INTERF");
 		break;
 	case USB_RECIP_ENDPOINT:
-		printk(KERN_DEBUG "ENDPOI");
+		pr_debug("ENDPOI");
 		break;
 	case USB_RECIP_OTHER:
-		printk(KERN_DEBUG "OTHER ");
+		pr_debug("OTHER ");
 		break;
 	default:
-		printk(KERN_DEBUG "------");
+		pr_debug("------");
+		break;
 	}
 }
 
 static void usbip_dump_usb_ctrlrequest(struct usb_ctrlrequest *cmd)
 {
 	if (!cmd) {
-		printk(KERN_DEBUG "      %s : null pointer\n", __func__);
+		pr_debug("       : null pointer\n");
 		return;
 	}
 
-	printk(KERN_DEBUG "       ");
-	printk(KERN_DEBUG "bRequestType(%02X) ", cmd->bRequestType);
-	printk(KERN_DEBUG "bRequest(%02X) " , cmd->bRequest);
-	printk(KERN_DEBUG "wValue(%04X) ", cmd->wValue);
-	printk(KERN_DEBUG "wIndex(%04X) ", cmd->wIndex);
-	printk(KERN_DEBUG "wLength(%04X) ", cmd->wLength);
-
-	printk(KERN_DEBUG "\n       ");
+	pr_debug("       ");
+	pr_debug("bRequestType(%02X) bRequest(%02X) wValue(%04X) wIndex(%04X) "
+		 "wLength(%04X) ", cmd->bRequestType, cmd->bRequest,
+		 cmd->wValue, cmd->wIndex, cmd->wLength);
+	pr_debug("\n       ");
 
 	if ((cmd->bRequestType & USB_TYPE_MASK) == USB_TYPE_STANDARD) {
-		printk(KERN_DEBUG "STANDARD ");
+		pr_debug("STANDARD ");
 		switch (cmd->bRequest) {
 		case USB_REQ_GET_STATUS:
-			printk(KERN_DEBUG "GET_STATUS");
+			pr_debug("GET_STATUS\n");
 			break;
 		case USB_REQ_CLEAR_FEATURE:
-			printk(KERN_DEBUG "CLEAR_FEAT");
+			pr_debug("CLEAR_FEAT\n");
 			break;
 		case USB_REQ_SET_FEATURE:
-			printk(KERN_DEBUG "SET_FEAT  ");
+			pr_debug("SET_FEAT  \n");
 			break;
 		case USB_REQ_SET_ADDRESS:
-			printk(KERN_DEBUG "SET_ADDRRS");
+			pr_debug("SET_ADDRRS\n");
 			break;
 		case USB_REQ_GET_DESCRIPTOR:
-			printk(KERN_DEBUG "GET_DESCRI");
+			pr_debug("GET_DESCRI\n");
 			break;
 		case USB_REQ_SET_DESCRIPTOR:
-			printk(KERN_DEBUG "SET_DESCRI");
+			pr_debug("SET_DESCRI\n");
 			break;
 		case USB_REQ_GET_CONFIGURATION:
-			printk(KERN_DEBUG "GET_CONFIG");
+			pr_debug("GET_CONFIG\n");
 			break;
 		case USB_REQ_SET_CONFIGURATION:
-			printk(KERN_DEBUG "SET_CONFIG");
+			pr_debug("SET_CONFIG\n");
 			break;
 		case USB_REQ_GET_INTERFACE:
-			printk(KERN_DEBUG "GET_INTERF");
+			pr_debug("GET_INTERF\n");
 			break;
 		case USB_REQ_SET_INTERFACE:
-			printk(KERN_DEBUG "SET_INTERF");
+			pr_debug("SET_INTERF\n");
 			break;
 		case USB_REQ_SYNCH_FRAME:
-			printk(KERN_DEBUG "SYNC_FRAME");
+			pr_debug("SYNC_FRAME\n");
 			break;
 		default:
-			printk(KERN_DEBUG "REQ(%02X) ", cmd->bRequest);
+			pr_debug("REQ(%02X) \n", cmd->bRequest);
+			break;
 		}
-
-		printk(KERN_DEBUG " ");
 		usbip_dump_request_type(cmd->bRequestType);
-
-	} else if ((cmd->bRequestType & USB_TYPE_MASK) == USB_TYPE_CLASS)
-		printk(KERN_DEBUG "CLASS   ");
-
-	else if ((cmd->bRequestType & USB_TYPE_MASK) == USB_TYPE_VENDOR)
-		printk(KERN_DEBUG "VENDOR  ");
-
-	else if ((cmd->bRequestType & USB_TYPE_MASK) == USB_TYPE_RESERVED)
-		printk(KERN_DEBUG "RESERVED");
-
-	printk(KERN_DEBUG "\n");
+	} else if ((cmd->bRequestType & USB_TYPE_MASK) == USB_TYPE_CLASS) {
+		pr_debug("CLASS   \n");
+	} else if ((cmd->bRequestType & USB_TYPE_MASK) == USB_TYPE_VENDOR) {
+		pr_debug("VENDOR  \n");
+	} else if ((cmd->bRequestType & USB_TYPE_MASK) == USB_TYPE_RESERVED) {
+		pr_debug("RESERVED\n");
+	}
 }
 
 void usbip_dump_urb(struct urb *urb)
@@ -268,16 +249,15 @@
 	struct device *dev;
 
 	if (!urb) {
-		printk(KERN_DEBUG KBUILD_MODNAME
-		       ":%s: urb: null pointer!!\n", __func__);
+		pr_debug("urb: null pointer!!\n");
 		return;
 	}
 
 	if (!urb->dev) {
-		printk(KERN_DEBUG KBUILD_MODNAME
-		       ":%s: urb->dev: null pointer!!\n", __func__);
+		pr_debug("urb->dev: null pointer!!\n");
 		return;
 	}
+
 	dev = &urb->dev->dev;
 
 	dev_dbg(dev, "   urb                   :%p\n", urb);
@@ -298,7 +278,7 @@
 	dev_dbg(dev, "   setup_packet          :%p\n", urb->setup_packet);
 
 	if (urb->setup_packet && usb_pipetype(urb->pipe) == PIPE_CONTROL)
-			usbip_dump_usb_ctrlrequest(
+		usbip_dump_usb_ctrlrequest(
 			(struct usb_ctrlrequest *)urb->setup_packet);
 
 	dev_dbg(dev, "   start_frame           :%d\n", urb->start_frame);
@@ -312,47 +292,48 @@
 
 void usbip_dump_header(struct usbip_header *pdu)
 {
-	usbip_udbg("BASE: cmd %u seq %u devid %u dir %u ep %u\n",
-			pdu->base.command,
-			pdu->base.seqnum,
-			pdu->base.devid,
-			pdu->base.direction,
-			pdu->base.ep);
+	pr_debug("BASE: cmd %u seq %u devid %u dir %u ep %u\n",
+		 pdu->base.command,
+		 pdu->base.seqnum,
+		 pdu->base.devid,
+		 pdu->base.direction,
+		 pdu->base.ep);
 
 	switch (pdu->base.command) {
 	case USBIP_CMD_SUBMIT:
-		usbip_udbg("CMD_SUBMIT: "
-				"x_flags %u x_len %u sf %u #p %u iv %u\n",
-				pdu->u.cmd_submit.transfer_flags,
-				pdu->u.cmd_submit.transfer_buffer_length,
-				pdu->u.cmd_submit.start_frame,
-				pdu->u.cmd_submit.number_of_packets,
-				pdu->u.cmd_submit.interval);
-				break;
+		pr_debug("USBIP_CMD_SUBMIT: "
+			 "x_flags %u x_len %u sf %u #p %d iv %d\n",
+			 pdu->u.cmd_submit.transfer_flags,
+			 pdu->u.cmd_submit.transfer_buffer_length,
+			 pdu->u.cmd_submit.start_frame,
+			 pdu->u.cmd_submit.number_of_packets,
+			 pdu->u.cmd_submit.interval);
+		break;
 	case USBIP_CMD_UNLINK:
-		usbip_udbg("CMD_UNLINK: seq %u\n", pdu->u.cmd_unlink.seqnum);
+		pr_debug("USBIP_CMD_UNLINK: seq %u\n",
+			 pdu->u.cmd_unlink.seqnum);
 		break;
 	case USBIP_RET_SUBMIT:
-		usbip_udbg("RET_SUBMIT: st %d al %u sf %d #p %d ec %d\n",
-				pdu->u.ret_submit.status,
-				pdu->u.ret_submit.actual_length,
-				pdu->u.ret_submit.start_frame,
-				pdu->u.ret_submit.number_of_packets,
-				pdu->u.ret_submit.error_count);
+		pr_debug("USBIP_RET_SUBMIT: st %d al %u sf %d #p %d ec %d\n",
+			 pdu->u.ret_submit.status,
+			 pdu->u.ret_submit.actual_length,
+			 pdu->u.ret_submit.start_frame,
+			 pdu->u.ret_submit.number_of_packets,
+			 pdu->u.ret_submit.error_count);
+		break;
 	case USBIP_RET_UNLINK:
-		usbip_udbg("RET_UNLINK: status %d\n", pdu->u.ret_unlink.status);
+		pr_debug("USBIP_RET_UNLINK: status %d\n",
+			 pdu->u.ret_unlink.status);
 		break;
 	default:
 		/* NOT REACHED */
-		usbip_udbg("UNKNOWN\n");
+		pr_err("unknown command\n");
+		break;
 	}
 }
 EXPORT_SYMBOL_GPL(usbip_dump_header);
 
-/*-------------------------------------------------------------------------*/
-/* socket routines */
-
-/*  Send/receive messages over TCP/IP. I refer drivers/block/nbd.c */
+/* Send/receive messages over TCP/IP. I refer drivers/block/nbd.c */
 int usbip_xmit(int send, struct socket *sock, char *buf,
 	       int size, int msg_flags)
 {
@@ -368,27 +349,24 @@
 	usbip_dbg_xmit("enter\n");
 
 	if (!sock || !buf || !size) {
-		printk(KERN_ERR "%s: invalid arg, sock %p buff %p size %d\n",
-		       __func__, sock, buf, size);
+		pr_err("invalid arg, sock %p buff %p size %d\n", sock, buf,
+		       size);
 		return -EINVAL;
 	}
 
-
 	if (usbip_dbg_flag_xmit) {
 		if (send) {
 			if (!in_interrupt())
-				printk(KERN_DEBUG "%-10s:", current->comm);
+				pr_debug("%-10s:", current->comm);
 			else
-				printk(KERN_DEBUG "interrupt  :");
+				pr_debug("interrupt  :");
 
-			printk(KERN_DEBUG "%s: sending... , sock %p, buf %p, "
-			       "size %d, msg_flags %d\n", __func__,
-			       sock, buf, size, msg_flags);
+			pr_debug("sending... , sock %p, buf %p, size %d, "
+				 "msg_flags %d\n", sock, buf, size, msg_flags);
 			usbip_dump_buffer(buf, size);
 		}
 	}
 
-
 	do {
 		sock->sk->sk_allocation = GFP_NOIO;
 		iov.iov_base    = buf;
@@ -404,13 +382,12 @@
 			result = kernel_sendmsg(sock, &msg, &iov, 1, size);
 		else
 			result = kernel_recvmsg(sock, &msg, &iov, 1, size,
-								MSG_WAITALL);
+						MSG_WAITALL);
 
 		if (result <= 0) {
-			usbip_udbg("usbip_xmit: %s sock %p buf %p size %u ret "
-					"%d total %d\n",
-					send ? "send" : "receive", sock, buf,
-					size, result, total);
+			pr_debug("%s sock %p buf %p size %u ret %d total %d\n",
+				 send ? "send" : "receive", sock, buf, size,
+				 result, total);
 			goto err;
 		}
 
@@ -420,24 +397,21 @@
 
 	} while (size > 0);
 
-
 	if (usbip_dbg_flag_xmit) {
 		if (!send) {
 			if (!in_interrupt())
-				printk(KERN_DEBUG "%-10s:", current->comm);
+				pr_debug("%-10s:", current->comm);
 			else
-				printk(KERN_DEBUG "interrupt  :");
+				pr_debug("interrupt  :");
 
-			printk(KERN_DEBUG "usbip_xmit: receiving....\n");
+			pr_debug("receiving....\n");
 			usbip_dump_buffer(bp, osize);
-			printk(KERN_DEBUG "usbip_xmit: received, osize %d ret "
-					"%d size %d total %d\n", osize, result,
-					size, total);
+			pr_debug("received, osize %d ret %d size %d total %d\n",
+				 osize, result, size, total);
 		}
 
 		if (send)
-			printk(KERN_DEBUG "usbip_xmit: send, total %d\n",
-									total);
+			pr_debug("send, total %d\n", total);
 	}
 
 	return total;
@@ -455,7 +429,7 @@
 
 	file = fget(sockfd);
 	if (!file) {
-		printk(KERN_ERR "%s: invalid sockfd\n", __func__);
+		pr_err("invalid sockfd\n");
 		return NULL;
 	}
 
@@ -470,11 +444,6 @@
 }
 EXPORT_SYMBOL_GPL(sockfd_to_socket);
 
-
-
-/*-------------------------------------------------------------------------*/
-/* pdu routines */
-
 /* there may be more cases to tweak the flags. */
 static unsigned int tweak_transfer_flags(unsigned int flags)
 {
@@ -483,7 +452,7 @@
 }
 
 static void usbip_pack_cmd_submit(struct usbip_header *pdu, struct urb *urb,
-								int pack)
+				  int pack)
 {
 	struct usbip_header_cmd_submit *spdu = &pdu->u.cmd_submit;
 
@@ -494,7 +463,7 @@
 	if (pack) {
 		/* vhci_tx.c */
 		spdu->transfer_flags =
-				tweak_transfer_flags(urb->transfer_flags);
+			tweak_transfer_flags(urb->transfer_flags);
 		spdu->transfer_buffer_length	= urb->transfer_buffer_length;
 		spdu->start_frame		= urb->start_frame;
 		spdu->number_of_packets		= urb->number_of_packets;
@@ -511,7 +480,7 @@
 }
 
 static void usbip_pack_ret_submit(struct usbip_header *pdu, struct urb *urb,
-								int pack)
+				  int pack)
 {
 	struct usbip_header_ret_submit *rpdu = &pdu->u.ret_submit;
 
@@ -534,9 +503,8 @@
 	}
 }
 
-
 void usbip_pack_pdu(struct usbip_header *pdu, struct urb *urb, int cmd,
-								int pack)
+		    int pack)
 {
 	switch (cmd) {
 	case USBIP_CMD_SUBMIT:
@@ -546,14 +514,13 @@
 		usbip_pack_ret_submit(pdu, urb, pack);
 		break;
 	default:
-		err("unknown command");
-		/* NOTREACHED */
-		/* BUG(); */
+		/* NOT REACHED */
+		pr_err("unknown command\n");
+		break;
 	}
 }
 EXPORT_SYMBOL_GPL(usbip_pack_pdu);
 
-
 static void correct_endian_basic(struct usbip_header_basic *base, int send)
 {
 	if (send) {
@@ -572,7 +539,7 @@
 }
 
 static void correct_endian_cmd_submit(struct usbip_header_cmd_submit *pdu,
-								int send)
+				      int send)
 {
 	if (send) {
 		pdu->transfer_flags = cpu_to_be32(pdu->transfer_flags);
@@ -592,7 +559,7 @@
 }
 
 static void correct_endian_ret_submit(struct usbip_header_ret_submit *pdu,
-								int send)
+				      int send)
 {
 	if (send) {
 		cpu_to_be32s(&pdu->status);
@@ -604,13 +571,13 @@
 		be32_to_cpus(&pdu->status);
 		be32_to_cpus(&pdu->actual_length);
 		be32_to_cpus(&pdu->start_frame);
-		cpu_to_be32s(&pdu->number_of_packets);
+		be32_to_cpus(&pdu->number_of_packets);
 		be32_to_cpus(&pdu->error_count);
 	}
 }
 
 static void correct_endian_cmd_unlink(struct usbip_header_cmd_unlink *pdu,
-								int send)
+				      int send)
 {
 	if (send)
 		pdu->seqnum = cpu_to_be32(pdu->seqnum);
@@ -619,7 +586,7 @@
 }
 
 static void correct_endian_ret_unlink(struct usbip_header_ret_unlink *pdu,
-								int send)
+				      int send)
 {
 	if (send)
 		cpu_to_be32s(&pdu->status);
@@ -653,16 +620,16 @@
 		correct_endian_ret_unlink(&pdu->u.ret_unlink, send);
 		break;
 	default:
-		/* NOTREACHED */
-		err("unknown command in pdu header: %d", cmd);
-		/* BUG(); */
+		/* NOT REACHED */
+		pr_err("unknown command\n");
+		break;
 	}
 }
 EXPORT_SYMBOL_GPL(usbip_header_correct_endian);
 
 static void usbip_iso_pakcet_correct_endian(
-				struct usbip_iso_packet_descriptor *iso,
-				int send)
+	struct usbip_iso_packet_descriptor *iso,
+	int send)
 {
 	/* does not need all members. but copy all simply. */
 	if (send) {
@@ -679,7 +646,7 @@
 }
 
 static void usbip_pack_iso(struct usbip_iso_packet_descriptor *iso,
-		struct usb_iso_packet_descriptor *uiso, int pack)
+			   struct usb_iso_packet_descriptor *uiso, int pack)
 {
 	if (pack) {
 		iso->offset		= uiso->offset;
@@ -694,7 +661,6 @@
 	}
 }
 
-
 /* must free buffer */
 void *usbip_alloc_iso_desc_pdu(struct urb *urb, ssize_t *bufflen)
 {
@@ -737,7 +703,7 @@
 
 	/* my Bluetooth dongle gets ISO URBs which are np = 0 */
 	if (np == 0) {
-		/* usbip_uinfo("iso np == 0\n"); */
+		/* pr_info("iso np == 0\n"); */
 		/* usbip_dump_urb(urb); */
 		return 0;
 	}
@@ -760,7 +726,6 @@
 		return -EPIPE;
 	}
 
-
 	for (i = 0; i < np; i++) {
 		iso = buff + (i * sizeof(*iso));
 
@@ -773,8 +738,9 @@
 
 	if (total_length != urb->actual_length) {
 		dev_err(&urb->dev->dev,
-		  "total length of iso packets (%d) not equal to actual length of buffer (%d)\n",
-		  total_length, urb->actual_length);
+			"total length of iso packets %d not equal to actual "
+			"length of buffer %d\n",
+			total_length, urb->actual_length);
 
 		if (ud->side == USBIP_STUB)
 			usbip_event_add(ud, SDEV_EVENT_ERROR_TCP);
@@ -823,9 +789,10 @@
 	for (i = np-1; i > 0; i--) {
 		actualoffset -= urb->iso_frame_desc[i].actual_length;
 		memmove(urb->transfer_buffer + urb->iso_frame_desc[i].offset,
-				  urb->transfer_buffer + actualoffset,
-				  urb->iso_frame_desc[i].actual_length);
+			urb->transfer_buffer + actualoffset,
+			urb->iso_frame_desc[i].actual_length);
 	}
+
 	return ret;
 }
 EXPORT_SYMBOL_GPL(usbip_pad_iso);
@@ -872,13 +839,9 @@
 }
 EXPORT_SYMBOL_GPL(usbip_recv_xbuff);
 
-
-/*-------------------------------------------------------------------------*/
-
 static int __init usbip_common_init(void)
 {
-	printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_DESC "" DRIVER_VERSION);
-
+	pr_info(DRIVER_DESC " v" USBIP_VERSION "\n");
 	return 0;
 }
 
@@ -887,12 +850,10 @@
 	return;
 }
 
-
-
-
 module_init(usbip_common_init);
 module_exit(usbip_common_exit);
 
 MODULE_AUTHOR(DRIVER_AUTHOR);
 MODULE_DESCRIPTION(DRIVER_DESC);
 MODULE_LICENSE("GPL");
+MODULE_VERSION(USBIP_VERSION);
diff -druN linux-2.6.39-libre/drivers/staging/usbip/usbip_common.h linux-3.0-rc7-libre/drivers/staging/usbip/usbip_common.h
--- linux-2.6.39-libre/drivers/staging/usbip/usbip_common.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/usbip/usbip_common.h	2011-07-11 19:51:52.000000000 -0400
@@ -17,42 +17,28 @@
  * USA.
  */
 
-#ifndef __VHCI_COMMON_H
-#define __VHCI_COMMON_H
-
+#ifndef __USBIP_COMMON_H
+#define __USBIP_COMMON_H
 
-#include <linux/version.h>
+#include <linux/compiler.h>
+#include <linux/device.h>
+#include <linux/interrupt.h>
+#include <linux/net.h>
+#include <linux/printk.h>
+#include <linux/spinlock.h>
+#include <linux/types.h>
 #include <linux/usb.h>
-#include <asm/byteorder.h>
-#include <net/sock.h>
-
-/*-------------------------------------------------------------------------*/
-
-/*
- * define macros to print messages
- */
-
-/**
- * usbip_udbg - print debug messages if CONFIG_USB_IP_DEBUG_ENABLE is defined
- * @fmt:
- * @args:
- */
-
-#ifdef CONFIG_USB_IP_DEBUG_ENABLE
-
-#define usbip_udbg(fmt, args...)					\
-	do {								\
-		printk(KERN_DEBUG "%-10s:(%s,%d) %s: " fmt,		\
-			(in_interrupt() ? "interrupt" : (current)->comm),\
-			__FILE__, __LINE__, __func__, ##args);		\
-	} while (0)
-
-#else  /* CONFIG_USB_IP_DEBUG_ENABLE */
+#include <linux/wait.h>
 
-#define usbip_udbg(fmt, args...)		do { } while (0)
+#define USBIP_VERSION "1.0.0"
 
-#endif /* CONFIG_USB_IP_DEBUG_ENABLE */
+#undef pr_fmt
 
+#ifdef DEBUG
+#define pr_fmt(fmt)     KBUILD_MODNAME ": %s:%d: " fmt, __func__, __LINE__
+#else
+#define pr_fmt(fmt)     KBUILD_MODNAME ": " fmt
+#endif
 
 enum {
 	usbip_debug_xmit	= (1 << 0),
@@ -87,16 +73,16 @@
 #define usbip_dbg_with_flag(flag, fmt, args...)		\
 	do {						\
 		if (flag & usbip_debug_flag)		\
-			usbip_udbg(fmt , ##args);		\
+			pr_debug(fmt, ##args);		\
 	} while (0)
 
-#define usbip_dbg_sysfs(fmt, args...)		\
+#define usbip_dbg_sysfs(fmt, args...) \
 	usbip_dbg_with_flag(usbip_debug_sysfs, fmt , ##args)
-#define usbip_dbg_xmit(fmt, args...)		\
+#define usbip_dbg_xmit(fmt, args...) \
 	usbip_dbg_with_flag(usbip_debug_xmit, fmt , ##args)
-#define usbip_dbg_urb(fmt, args...)		\
+#define usbip_dbg_urb(fmt, args...) \
 	usbip_dbg_with_flag(usbip_debug_urb, fmt , ##args)
-#define usbip_dbg_eh(fmt, args...)		\
+#define usbip_dbg_eh(fmt, args...) \
 	usbip_dbg_with_flag(usbip_debug_eh, fmt , ##args)
 
 #define usbip_dbg_vhci_rh(fmt, args...)	\
@@ -107,42 +93,16 @@
 	usbip_dbg_with_flag(usbip_debug_vhci_rx, fmt , ##args)
 #define usbip_dbg_vhci_tx(fmt, args...)	\
 	usbip_dbg_with_flag(usbip_debug_vhci_tx, fmt , ##args)
-#define usbip_dbg_vhci_sysfs(fmt, args...)	\
+#define usbip_dbg_vhci_sysfs(fmt, args...) \
 	usbip_dbg_with_flag(usbip_debug_vhci_sysfs, fmt , ##args)
 
-#define usbip_dbg_stub_cmp(fmt, args...)	\
+#define usbip_dbg_stub_cmp(fmt, args...) \
 	usbip_dbg_with_flag(usbip_debug_stub_cmp, fmt , ##args)
-#define usbip_dbg_stub_rx(fmt, args...)	\
+#define usbip_dbg_stub_rx(fmt, args...) \
 	usbip_dbg_with_flag(usbip_debug_stub_rx, fmt , ##args)
-#define usbip_dbg_stub_tx(fmt, args...)	\
+#define usbip_dbg_stub_tx(fmt, args...) \
 	usbip_dbg_with_flag(usbip_debug_stub_tx, fmt , ##args)
 
-
-/**
- * usbip_uerr - print error messages
- * @fmt:
- * @args:
- */
-#define usbip_uerr(fmt, args...)					\
-	do {								\
-		printk(KERN_ERR "%-10s: ***ERROR*** (%s,%d) %s: " fmt,	\
-			(in_interrupt() ? "interrupt" : (current)->comm),\
-			__FILE__, __LINE__, __func__, ##args);	\
-	} while (0)
-
-/**
- * usbip_uinfo - print information messages
- * @fmt:
- * @args:
- */
-#define usbip_uinfo(fmt, args...)				\
-	do {							\
-		printk(KERN_INFO "usbip: " fmt , ## args);	\
-	} while (0)
-
-
-/*-------------------------------------------------------------------------*/
-
 /*
  * USB/IP request headers.
  * Currently, we define 4 request types:
@@ -185,7 +145,7 @@
 #define USBIP_DIR_IN	1
 	__u32 direction;
 	__u32 ep;     /* endpoint number */
-} __attribute__ ((packed));
+} __packed;
 
 /*
  * An additional header for a CMD_SUBMIT packet.
@@ -212,43 +172,40 @@
 
 	/* set setup packet data for a CTRL request */
 	unsigned char setup[8];
-} __attribute__ ((packed));
+} __packed;
 
 /*
  * An additional header for a RET_SUBMIT packet.
  */
 struct usbip_header_ret_submit {
 	__s32 status;
-	__s32 actual_length; /* returned data length */
-	__s32 start_frame; /* ISO and INT */
-	__s32 number_of_packets;  /* ISO only */
-	__s32 error_count; /* ISO only */
-} __attribute__ ((packed));
+	__s32 actual_length;		/* returned data length */
+	__s32 start_frame;		/* ISO and INT */
+	__s32 number_of_packets;	/* ISO only */
+	__s32 error_count;		/* ISO only */
+} __packed;
 
 /*
  * An additional header for a CMD_UNLINK packet.
  */
 struct usbip_header_cmd_unlink {
-	__u32 seqnum; /* URB's seqnum which will be unlinked */
-} __attribute__ ((packed));
-
+	__u32 seqnum;			/* URB's seqnum that will be unlinked */
+} __packed;
 
 /*
  * An additional header for a RET_UNLINK packet.
  */
 struct usbip_header_ret_unlink {
 	__s32 status;
-} __attribute__ ((packed));
-
+} __packed;
 
 /* the same as usb_iso_packet_descriptor but packed for pdu */
 struct usbip_iso_packet_descriptor {
 	__u32 offset;
-	__u32 length;            /* expected length */
+	__u32 length;			/* expected length */
 	__u32 actual_length;
 	__u32 status;
-} __attribute__ ((packed));
-
+} __packed;
 
 /*
  * All usbip packets use a common header to keep code simple.
@@ -262,18 +219,11 @@
 		struct usbip_header_cmd_unlink	cmd_unlink;
 		struct usbip_header_ret_unlink	ret_unlink;
 	} u;
-} __attribute__ ((packed));
-
-
-
-
-/*-------------------------------------------------------------------------*/
-
+} __packed;
 
 int usbip_xmit(int, struct socket *, char *, int, int);
 int usbip_sendmsg(struct socket *, struct msghdr *, int);
 
-
 static inline int interface_to_busnum(struct usb_interface *interface)
 {
 	struct usb_device *udev = interface_to_usbdev(interface);
@@ -304,7 +254,6 @@
 void usbip_dump_urb(struct urb *purb);
 void usbip_dump_header(struct usbip_header *pdu);
 
-
 struct usbip_device;
 
 enum usbip_side {
@@ -331,7 +280,6 @@
 /* a common structure for stub_device and vhci_device */
 struct usbip_device {
 	enum usbip_side side;
-
 	enum usbip_status status;
 
 	/* lock for status */
@@ -370,9 +318,8 @@
 	} eh_ops;
 };
 
-
 void usbip_pack_pdu(struct usbip_header *pdu, struct urb *urb, int cmd,
-								int pack);
+		    int pack);
 
 void usbip_header_correct_endian(struct usbip_header *pdu, int send);
 /* some members of urb must be substituted before. */
@@ -383,12 +330,10 @@
 int usbip_pad_iso(struct usbip_device *ud, struct urb *urb);
 void *usbip_alloc_iso_desc_pdu(struct urb *urb, ssize_t *bufflen);
 
-
 /* usbip_event.c */
 int usbip_start_eh(struct usbip_device *ud);
 void usbip_stop_eh(struct usbip_device *ud);
 void usbip_event_add(struct usbip_device *ud, unsigned long event);
 int usbip_event_happened(struct usbip_device *ud);
 
-
-#endif
+#endif /* __USBIP_COMMON_H */
diff -druN linux-2.6.39-libre/drivers/staging/usbip/usbip_event.c linux-3.0-rc7-libre/drivers/staging/usbip/usbip_event.c
--- linux-2.6.39-libre/drivers/staging/usbip/usbip_event.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/usbip/usbip_event.c	2011-07-11 19:51:52.000000000 -0400
@@ -17,9 +17,10 @@
  * USA.
  */
 
-#include "usbip_common.h"
 #include <linux/kthread.h>
 
+#include "usbip_common.h"
+
 static int event_handler(struct usbip_device *ud)
 {
 	usbip_dbg_eh("enter\n");
@@ -36,21 +37,18 @@
 		 */
 		if (ud->event & USBIP_EH_SHUTDOWN) {
 			ud->eh_ops.shutdown(ud);
-
 			ud->event &= ~USBIP_EH_SHUTDOWN;
 		}
 
 		/* Reset the device. */
 		if (ud->event & USBIP_EH_RESET) {
 			ud->eh_ops.reset(ud);
-
 			ud->event &= ~USBIP_EH_RESET;
 		}
 
 		/* Mark the device as unusable. */
 		if (ud->event & USBIP_EH_UNUSABLE) {
 			ud->eh_ops.unusable(ud);
-
 			ud->event &= ~USBIP_EH_UNUSABLE;
 		}
 
@@ -68,13 +66,14 @@
 
 	while (!kthread_should_stop()) {
 		wait_event_interruptible(ud->eh_waitq,
-					usbip_event_happened(ud) ||
-					kthread_should_stop());
+					 usbip_event_happened(ud) ||
+					 kthread_should_stop());
 		usbip_dbg_eh("wakeup\n");
 
 		if (event_handler(ud) < 0)
 			break;
 	}
+
 	return 0;
 }
 
@@ -85,10 +84,10 @@
 
 	ud->eh = kthread_run(event_handler_loop, ud, "usbip_eh");
 	if (IS_ERR(ud->eh)) {
-		printk(KERN_WARNING
-			"Unable to start control thread\n");
+		pr_warning("Unable to start control thread\n");
 		return PTR_ERR(ud->eh);
 	}
+
 	return 0;
 }
 EXPORT_SYMBOL_GPL(usbip_start_eh);
@@ -106,11 +105,8 @@
 void usbip_event_add(struct usbip_device *ud, unsigned long event)
 {
 	spin_lock(&ud->lock);
-
 	ud->event |= event;
-
 	wake_up(&ud->eh_waitq);
-
 	spin_unlock(&ud->lock);
 }
 EXPORT_SYMBOL_GPL(usbip_event_add);
@@ -120,10 +116,8 @@
 	int happened = 0;
 
 	spin_lock(&ud->lock);
-
 	if (ud->event != 0)
 		happened = 1;
-
 	spin_unlock(&ud->lock);
 
 	return happened;
diff -druN linux-2.6.39-libre/drivers/staging/usbip/userspace/AUTHORS linux-3.0-rc7-libre/drivers/staging/usbip/userspace/AUTHORS
--- linux-2.6.39-libre/drivers/staging/usbip/userspace/AUTHORS	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/staging/usbip/userspace/AUTHORS	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,2 @@
+Takahiro Hirofuchi
+Robert Leibl
diff -druN linux-2.6.39-libre/drivers/staging/usbip/userspace/autogen.sh linux-3.0-rc7-libre/drivers/staging/usbip/userspace/autogen.sh
--- linux-2.6.39-libre/drivers/staging/usbip/userspace/autogen.sh	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/staging/usbip/userspace/autogen.sh	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,9 @@
+#!/bin/sh -x
+
+#aclocal
+#autoheader
+#libtoolize --copy --force
+#automake-1.9 -acf
+#autoconf
+
+autoreconf -i -f -v
diff -druN linux-2.6.39-libre/drivers/staging/usbip/userspace/cleanup.sh linux-3.0-rc7-libre/drivers/staging/usbip/userspace/cleanup.sh
--- linux-2.6.39-libre/drivers/staging/usbip/userspace/cleanup.sh	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/staging/usbip/userspace/cleanup.sh	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,10 @@
+#!/bin/sh -x
+
+
+if [ -r Makefile ]; then
+	make distclean
+fi
+
+FILES="configure cscope.out Makefile.in depcomp compile config.guess config.sub config.h.in~ config.log config.status ltmain.sh libtool config.h.in autom4te.cache missing aclocal.m4 install-sh cmd/Makefile.in lib/Makefile.in Makefile lib/Makefile cmd/Makefile"
+
+rm -Rf $FILES
diff -druN linux-2.6.39-libre/drivers/staging/usbip/userspace/configure.ac linux-3.0-rc7-libre/drivers/staging/usbip/userspace/configure.ac
--- linux-2.6.39-libre/drivers/staging/usbip/userspace/configure.ac	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/staging/usbip/userspace/configure.ac	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,114 @@
+dnl Process this file with autoconf to produce a configure script.
+
+AC_PREREQ(2.59)
+AC_INIT([usbip], [0.1.8], [usbip-devel@lists.sourceforge.net])
+AC_DEFINE([USBIP_VERSION], [0x000106], [numeric version number])
+
+CURRENT=0
+REVISION=1
+AGE=0
+AC_SUBST([LIBUSBIP_VERSION], [$CURRENT:$REVISION:$AGE], [library version])
+
+AC_CONFIG_SRCDIR([src/usbipd.c])
+AC_CONFIG_HEADERS([config.h])
+
+AM_INIT_AUTOMAKE([foreign])
+LT_INIT
+
+# Silent build for automake >= 1.11
+m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
+
+AC_SUBST([EXTRA_CFLAGS], ["-Wall -Werror -Wextra -std=gnu99"])
+
+# Checks for programs.
+AC_PROG_CC
+AC_PROG_INSTALL
+AC_PROG_MAKE_SET
+
+# Checks for header files.
+AC_HEADER_DIRENT
+AC_HEADER_STDC
+AC_CHECK_HEADERS([arpa/inet.h fcntl.h netdb.h netinet/in.h stdint.h stdlib.h dnl
+		  string.h strings.h sys/socket.h syslog.h unistd.h])
+
+# Checks for typedefs, structures, and compiler characteristics.
+AC_TYPE_INT32_T
+AC_TYPE_SIZE_T
+AC_TYPE_SSIZE_T
+AC_TYPE_UINT16_T
+AC_TYPE_UINT32_T
+AC_TYPE_UINT8_T
+
+# Checks for library functions.
+AC_FUNC_REALLOC
+AC_CHECK_FUNCS([bzero memset mkdir regcomp socket strchr strerror strstr dnl
+		strtoul])
+
+AC_CHECK_HEADER([sysfs/libsysfs.h],
+		[AC_CHECK_LIB([sysfs], [sysfs_open_directory_list],
+			      [LIBS="$LIBS -lsysfs"],
+			      [AC_MSG_ERROR([Missing sysfs2 library!])])],
+		[AC_MSG_ERROR([Missing /usr/include/sysfs/libsysfs.h])])
+
+# Checks for libwrap library.
+AC_MSG_CHECKING([whether to use the libwrap (TCP wrappers) library])
+AC_ARG_WITH([tcp-wrappers],
+	    [AS_HELP_STRING([--with-tcp-wrappers],
+			    [use the libwrap (TCP wrappers) library])],
+	    dnl [ACTION-IF-GIVEN]
+	    [saved_LIBS="$LIBS"
+	     if test "$withval" = "yes"; then
+		     AC_MSG_RESULT([yes])
+		     AC_MSG_CHECKING([for hosts_access in -lwrap])
+		     LIBS="-lwrap $LIBS"
+		     AC_TRY_LINK(
+		       [int hosts_access(); int allow_severity, deny_severity;],
+		       [hosts_access()],
+		       [AC_MSG_RESULT([yes]);
+			AC_DEFINE([HAVE_LIBWRAP], [1],
+				  [use tcp wrapper]) wrap_LIB="-lwrap"],
+		       [AC_MSG_RESULT([not found]); exit 1])
+	     else
+		     AC_MSG_RESULT([no])
+	     fi
+	     LIBS="$saved_LIBS"],
+	    dnl [ACTION-IF-NOT-GIVEN]
+	    [AC_MSG_RESULT([(default)])
+	     AC_MSG_CHECKING([for hosts_access in -lwrap])
+	     saved_LIBS="$LIBS"
+	     LIBS="-lwrap $saved_LIBS"
+	     AC_TRY_LINK(
+	       [int hosts_access(); int allow_severity, deny_severity;],
+	       [hosts_access()],
+	       [AC_MSG_RESULT([yes]);
+		AC_DEFINE([HAVE_LIBWRAP], [1], [use tcp wrapper])],
+	       [AC_MSG_RESULT([no]); LIBS="$saved_LIBS"])])
+
+# Sets directory containing usb.ids.
+USBIDS_DIR='${datadir}/usbip'
+AC_ARG_WITH([usbids-dir],
+	    [AS_HELP_STRING([--with-usbids-dir=DIR],
+	       [where usb.ids is found (default ${datadir}/usbip)])],
+	    [USBIDS_DIR=$withval])
+AC_SUBST([USBIDS_DIR])
+
+dnl FIXME: when disabled, empty directry is created
+usbids=install
+AC_ARG_ENABLE([usbids-install],
+	      [AS_HELP_STRING([--enable-usbids-install],
+			      [install usb.ids (default)])],
+	      [AS_CASE([$enableval],
+		       [yes], [usbids=install],
+		       [no], [usbids=notinstall],
+		       [AC_MSG_ERROR(
+			  [bad value ${enableval} for --enable-usbids-install])]
+		      )])
+AM_CONDITIONAL([INSTALL_USBIDS], [test x$usbids = xinstall])
+
+GLIB2_REQUIRED=2.6.0
+PKG_CHECK_MODULES([PACKAGE], [glib-2.0 >= $GLIB2_REQUIRED])
+AC_SUBST([PACKAGE_CFLAGS])
+AC_SUBST([PACKAGE_LIBS])
+
+AC_CONFIG_FILES([Makefile libsrc/Makefile src/Makefile])
+AC_OUTPUT
diff -druN linux-2.6.39-libre/drivers/staging/usbip/userspace/COPYING linux-3.0-rc7-libre/drivers/staging/usbip/userspace/COPYING
--- linux-2.6.39-libre/drivers/staging/usbip/userspace/COPYING	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/staging/usbip/userspace/COPYING	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,340 @@
+		    GNU GENERAL PUBLIC LICENSE
+		       Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+     51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+			    Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users.  This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it.  (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.)  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+  To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have.  You must make sure that they, too, receive or can get the
+source code.  And you must show them these terms so they know their
+rights.
+
+  We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+  Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software.  If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+  Finally, any free program is threatened constantly by software
+patents.  We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary.  To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+		    GNU GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License.  The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language.  (Hereinafter, translation is included without limitation in
+the term "modification".)  Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+  1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+  2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) You must cause the modified files to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    b) You must cause any work that you distribute or publish, that in
+    whole or in part contains or is derived from the Program or any
+    part thereof, to be licensed as a whole at no charge to all third
+    parties under the terms of this License.
+
+    c) If the modified program normally reads commands interactively
+    when run, you must cause it, when started running for such
+    interactive use in the most ordinary way, to print or display an
+    announcement including an appropriate copyright notice and a
+    notice that there is no warranty (or else, saying that you provide
+    a warranty) and that users may redistribute the program under
+    these conditions, and telling the user how to view a copy of this
+    License.  (Exception: if the Program itself is interactive but
+    does not normally print such an announcement, your work based on
+    the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+    a) Accompany it with the complete corresponding machine-readable
+    source code, which must be distributed under the terms of Sections
+    1 and 2 above on a medium customarily used for software interchange; or,
+
+    b) Accompany it with a written offer, valid for at least three
+    years, to give any third party, for a charge no more than your
+    cost of physically performing source distribution, a complete
+    machine-readable copy of the corresponding source code, to be
+    distributed under the terms of Sections 1 and 2 above on a medium
+    customarily used for software interchange; or,
+
+    c) Accompany it with the information you received as to the offer
+    to distribute corresponding source code.  (This alternative is
+    allowed only for noncommercial distribution and only if you
+    received the program in object code or executable form with such
+    an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it.  For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable.  However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License.  Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+  5. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Program or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+  6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+  7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded.  In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+  9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation.  If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+  10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission.  For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this.  Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+			    NO WARRANTY
+
+  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+		     END OF TERMS AND CONDITIONS
+
+	    How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You 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
+
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+    Gnomovision version 69, Copyright (C) year  name of author
+    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+  `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+  <signature of Ty Coon>, 1 April 1989
+  Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs.  If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library.  If this is what you want to do, use the GNU Library General
+Public License instead of this License.
diff -druN linux-2.6.39-libre/drivers/staging/usbip/userspace/doc/usbip.8 linux-3.0-rc7-libre/drivers/staging/usbip/userspace/doc/usbip.8
--- linux-2.6.39-libre/drivers/staging/usbip/userspace/doc/usbip.8	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/staging/usbip/userspace/doc/usbip.8	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,71 @@
+.TH USBIP "8" "February 2009" "usbip" "System Administration Utilities"
+.SH NAME
+usbip \- manage USB/IP devices
+.SH SYNOPSIS
+.B usbip
+[\fIoptions\fR]
+
+.SH DESCRIPTION
+Devices exported by USB/IP servers can be listed, attached and
+detached using this program.
+
+.SH OPTIONS
+.HP
+\fB\-a\fR, \fB\-\-attach\fR <host> <bus_id>
+.IP
+Attach a remote USB device.
+.PP
+
+.HP
+\fB\-x\fR, \fB\-\-attachall\fR <host>
+.IP
+Attach all remote USB devices on the specific host.
+.PP
+
+.HP
+\fB\-d\fR, \fB\-\-detach\fR <ports>
+.IP
+Detach an imported USB device.
+.PP
+
+.HP
+\fB\-l\fR, \fB\-\-list\fR <hosts>
+.IP
+List exported USB devices.
+.PP
+
+.HP
+\fB\-p\fR, \fB\-\-port\fR
+.IP
+List virtual USB port status.
+.PP
+
+.HP
+\fB\-D\fR, \fB\-\-debug\fR
+.IP
+Print debugging information.
+.PP
+
+.HP
+\fB\-v\fR, \fB\-\-version\fR
+.IP
+Show version.
+.PP
+
+.SH EXAMPLES
+
+    client:# usbip --list server
+        - List exportable usb devices on the server.
+
+    client:# usbip --attach server 1-2
+        - Connect the remote USB device.
+
+    client:# usbip --port
+        - Show virtual port status.
+
+    client:# usbip --detach 0
+        - Detach the usb device.
+
+.SH "SEE ALSO"
+\fBusbipd\fP\fB(8)\fB\fP,
+\fBusbip_attach_driver\fP\fB(8)\fB\fP
diff -druN linux-2.6.39-libre/drivers/staging/usbip/userspace/doc/usbip_bind_driver.8 linux-3.0-rc7-libre/drivers/staging/usbip/userspace/doc/usbip_bind_driver.8
--- linux-2.6.39-libre/drivers/staging/usbip/userspace/doc/usbip_bind_driver.8	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/staging/usbip/userspace/doc/usbip_bind_driver.8	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,42 @@
+.TH USBIP_BIND_DRIVER "8" "February 2009" "usbip" "System Administration Utilities"
+.SH NAME
+usbip_bind_driver \- change driver binding for USB/IP
+
+.SH SYNOPSIS
+.B usbip_bind_driver
+[\fIoptions\fR]
+
+.SH DESCRIPTION
+Driver bindings for USB devices can be changed using
+this program. It is used to export and unexport USB
+devices over USB/IP.
+
+.SH OPTIONS
+.TP
+\fB\-u\fR, \fB\-\-usbip\fR <busid>
+Make a device exportable
+.TP
+\fB\-o\fR, \fB\-\-other\fR <busid>
+Use a device by a local driver
+.TP
+\fB\-l\fR, \fB\-\-list\fR
+Print usb devices and their drivers
+.TP
+\fB\-L\fR, \fB\-\-list2\fR
+Print usb devices and their drivers in parseable mode
+
+.SH EXAMPLES
+
+    server:# usbip_bind_driver --list
+        - List driver assignments for usb devices.
+
+    server:# usbip_bind_driver --usbip 1-2
+        - Bind usbip-host.ko to the device of busid 1-2.
+        - A usb device 1-2 is now exportable to other hosts!
+
+    server:# usbip_bind_driver --other 1-2
+        - Shutdown exporting and use the device locally.
+
+.SH "SEE ALSO"
+\fBusbip\fP\fB(8)\fB\fP,
+\fBusbipd\fP\fB(8)\fB\fP
diff -druN linux-2.6.39-libre/drivers/staging/usbip/userspace/doc/usbipd.8 linux-3.0-rc7-libre/drivers/staging/usbip/userspace/doc/usbipd.8
--- linux-2.6.39-libre/drivers/staging/usbip/userspace/doc/usbipd.8	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/staging/usbip/userspace/doc/usbipd.8	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,62 @@
+.TH USBIP "8" "February 2009" "usbip" "System Administration Utilities"
+.SH NAME
+usbipd \- USB/IP server daemon
+.SH SYNOPSIS
+.B usbipd
+[\fIoptions\fR]
+
+.SH DESCRIPTION
+.B usbipd
+provides USB/IP clients access to exported USB devices.
+
+Devices have to explicitly be exported using
+.B usbip_bind_driver
+before usbipd makes them available to other hosts.
+
+The daemon accepts connections from USB/IP clients
+on TCP port 3240.
+
+.SH OPTIONS
+.HP
+\fB\-D\fR, \fB\-\-daemon\fR
+.IP
+Run as a daemon process.
+.PP
+
+.HP
+\fB\-d\fR, \fB\-\-debug\fR
+.IP
+Print debugging information.
+.PP
+
+.HP
+\fB\-v\fR, \fB\-\-version\fR
+.IP
+Show version.
+.PP
+
+.SH LIMITATIONS
+
+.B usbipd
+offers no authentication or authorization for USB/IP. Any
+USB/IP client can connect and use exported devices.
+
+.SH EXAMPLES
+
+    server:# modprobe usbip
+
+    server:# usbipd -D
+        - Start usbip daemon.
+
+    server:# usbip_bind_driver --list
+        - List driver assignments for usb devices.
+
+    server:# usbip_bind_driver --usbip 1-2
+        - Bind usbip-host.ko to the device of busid 1-2.
+        - A usb device 1-2 is now exportable to other hosts!
+        - Use 'usbip_bind_driver --other 1-2' when you want to shutdown exporting and use the device locally.
+
+.SH "SEE ALSO"
+\fBusbip\fP\fB(8)\fB\fP,
+\fBusbip_attach_driver\fP\fB(8)\fB\fP
+
diff -druN linux-2.6.39-libre/drivers/staging/usbip/userspace/INSTALL linux-3.0-rc7-libre/drivers/staging/usbip/userspace/INSTALL
--- linux-2.6.39-libre/drivers/staging/usbip/userspace/INSTALL	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/staging/usbip/userspace/INSTALL	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,237 @@
+Installation Instructions
+*************************
+
+Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005,
+2006, 2007 Free Software Foundation, Inc.
+
+This file is free documentation; the Free Software Foundation gives
+unlimited permission to copy, distribute and modify it.
+
+Basic Installation
+==================
+
+Briefly, the shell commands `./configure; make; make install' should
+configure, build, and install this package.  The following
+more-detailed instructions are generic; see the `README' file for
+instructions specific to this package.
+
+   The `configure' shell script attempts to guess correct values for
+various system-dependent variables used during compilation.  It uses
+those values to create a `Makefile' in each directory of the package.
+It may also create one or more `.h' files containing system-dependent
+definitions.  Finally, it creates a shell script `config.status' that
+you can run in the future to recreate the current configuration, and a
+file `config.log' containing compiler output (useful mainly for
+debugging `configure').
+
+   It can also use an optional file (typically called `config.cache'
+and enabled with `--cache-file=config.cache' or simply `-C') that saves
+the results of its tests to speed up reconfiguring.  Caching is
+disabled by default to prevent problems with accidental use of stale
+cache files.
+
+   If you need to do unusual things to compile the package, please try
+to figure out how `configure' could check whether to do them, and mail
+diffs or instructions to the address given in the `README' so they can
+be considered for the next release.  If you are using the cache, and at
+some point `config.cache' contains results you don't want to keep, you
+may remove or edit it.
+
+   The file `configure.ac' (or `configure.in') is used to create
+`configure' by a program called `autoconf'.  You need `configure.ac' if
+you want to change it or regenerate `configure' using a newer version
+of `autoconf'.
+
+The simplest way to compile this package is:
+
+  1. `cd' to the directory containing the package's source code and type
+     `./configure' to configure the package for your system.
+
+     Running `configure' might take a while.  While running, it prints
+     some messages telling which features it is checking for.
+
+  2. Type `make' to compile the package.
+
+  3. Optionally, type `make check' to run any self-tests that come with
+     the package.
+
+  4. Type `make install' to install the programs and any data files and
+     documentation.
+
+  5. You can remove the program binaries and object files from the
+     source code directory by typing `make clean'.  To also remove the
+     files that `configure' created (so you can compile the package for
+     a different kind of computer), type `make distclean'.  There is
+     also a `make maintainer-clean' target, but that is intended mainly
+     for the package's developers.  If you use it, you may have to get
+     all sorts of other programs in order to regenerate files that came
+     with the distribution.
+
+  6. Often, you can also type `make uninstall' to remove the installed
+     files again.
+
+Compilers and Options
+=====================
+
+Some systems require unusual options for compilation or linking that the
+`configure' script does not know about.  Run `./configure --help' for
+details on some of the pertinent environment variables.
+
+   You can give `configure' initial values for configuration parameters
+by setting variables in the command line or in the environment.  Here
+is an example:
+
+     ./configure CC=c99 CFLAGS=-g LIBS=-lposix
+
+   *Note Defining Variables::, for more details.
+
+Compiling For Multiple Architectures
+====================================
+
+You can compile the package for more than one kind of computer at the
+same time, by placing the object files for each architecture in their
+own directory.  To do this, you can use GNU `make'.  `cd' to the
+directory where you want the object files and executables to go and run
+the `configure' script.  `configure' automatically checks for the
+source code in the directory that `configure' is in and in `..'.
+
+   With a non-GNU `make', it is safer to compile the package for one
+architecture at a time in the source code directory.  After you have
+installed the package for one architecture, use `make distclean' before
+reconfiguring for another architecture.
+
+Installation Names
+==================
+
+By default, `make install' installs the package's commands under
+`/usr/local/bin', include files under `/usr/local/include', etc.  You
+can specify an installation prefix other than `/usr/local' by giving
+`configure' the option `--prefix=PREFIX'.
+
+   You can specify separate installation prefixes for
+architecture-specific files and architecture-independent files.  If you
+pass the option `--exec-prefix=PREFIX' to `configure', the package uses
+PREFIX as the prefix for installing programs and libraries.
+Documentation and other data files still use the regular prefix.
+
+   In addition, if you use an unusual directory layout you can give
+options like `--bindir=DIR' to specify different values for particular
+kinds of files.  Run `configure --help' for a list of the directories
+you can set and what kinds of files go in them.
+
+   If the package supports it, you can cause programs to be installed
+with an extra prefix or suffix on their names by giving `configure' the
+option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
+
+Optional Features
+=================
+
+Some packages pay attention to `--enable-FEATURE' options to
+`configure', where FEATURE indicates an optional part of the package.
+They may also pay attention to `--with-PACKAGE' options, where PACKAGE
+is something like `gnu-as' or `x' (for the X Window System).  The
+`README' should mention any `--enable-' and `--with-' options that the
+package recognizes.
+
+   For packages that use the X Window System, `configure' can usually
+find the X include and library files automatically, but if it doesn't,
+you can use the `configure' options `--x-includes=DIR' and
+`--x-libraries=DIR' to specify their locations.
+
+Specifying the System Type
+==========================
+
+There may be some features `configure' cannot figure out automatically,
+but needs to determine by the type of machine the package will run on.
+Usually, assuming the package is built to be run on the _same_
+architectures, `configure' can figure that out, but if it prints a
+message saying it cannot guess the machine type, give it the
+`--build=TYPE' option.  TYPE can either be a short name for the system
+type, such as `sun4', or a canonical name which has the form:
+
+     CPU-COMPANY-SYSTEM
+
+where SYSTEM can have one of these forms:
+
+     OS KERNEL-OS
+
+   See the file `config.sub' for the possible values of each field.  If
+`config.sub' isn't included in this package, then this package doesn't
+need to know the machine type.
+
+   If you are _building_ compiler tools for cross-compiling, you should
+use the option `--target=TYPE' to select the type of system they will
+produce code for.
+
+   If you want to _use_ a cross compiler, that generates code for a
+platform different from the build platform, you should specify the
+"host" platform (i.e., that on which the generated programs will
+eventually be run) with `--host=TYPE'.
+
+Sharing Defaults
+================
+
+If you want to set default values for `configure' scripts to share, you
+can create a site shell script called `config.site' that gives default
+values for variables like `CC', `cache_file', and `prefix'.
+`configure' looks for `PREFIX/share/config.site' if it exists, then
+`PREFIX/etc/config.site' if it exists.  Or, you can set the
+`CONFIG_SITE' environment variable to the location of the site script.
+A warning: not all `configure' scripts look for a site script.
+
+Defining Variables
+==================
+
+Variables not defined in a site shell script can be set in the
+environment passed to `configure'.  However, some packages may run
+configure again during the build, and the customized values of these
+variables may be lost.  In order to avoid this problem, you should set
+them in the `configure' command line, using `VAR=value'.  For example:
+
+     ./configure CC=/usr/local2/bin/gcc
+
+causes the specified `gcc' to be used as the C compiler (unless it is
+overridden in the site shell script).
+
+Unfortunately, this technique does not work for `CONFIG_SHELL' due to
+an Autoconf bug.  Until the bug is fixed you can use this workaround:
+
+     CONFIG_SHELL=/bin/bash /bin/bash ./configure CONFIG_SHELL=/bin/bash
+
+`configure' Invocation
+======================
+
+`configure' recognizes the following options to control how it operates.
+
+`--help'
+`-h'
+     Print a summary of the options to `configure', and exit.
+
+`--version'
+`-V'
+     Print the version of Autoconf used to generate the `configure'
+     script, and exit.
+
+`--cache-file=FILE'
+     Enable the cache: use and save the results of the tests in FILE,
+     traditionally `config.cache'.  FILE defaults to `/dev/null' to
+     disable caching.
+
+`--config-cache'
+`-C'
+     Alias for `--cache-file=config.cache'.
+
+`--quiet'
+`--silent'
+`-q'
+     Do not print messages saying which checks are being made.  To
+     suppress all normal output, redirect it to `/dev/null' (any error
+     messages will still be shown).
+
+`--srcdir=DIR'
+     Look for the package's source code in directory DIR.  Usually
+     `configure' can determine that directory automatically.
+
+`configure' also accepts some other, not widely useful, options.  Run
+`configure --help' for more details.
+
diff -druN linux-2.6.39-libre/drivers/staging/usbip/userspace/libsrc/Makefile.am linux-3.0-rc7-libre/drivers/staging/usbip/userspace/libsrc/Makefile.am
--- linux-2.6.39-libre/drivers/staging/usbip/userspace/libsrc/Makefile.am	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/staging/usbip/userspace/libsrc/Makefile.am	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,7 @@
+libusbip_la_CPPFLAGS := -DUSBIDS_FILE='"@USBIDS_DIR@/usb.ids"'
+libusbip_la_CFLAGS   := @EXTRA_CFLAGS@
+libusbip_la_LDFLAGS  := -version-info @LIBUSBIP_VERSION@
+
+lib_LTLIBRARIES := libusbip.la
+libusbip_la_SOURCES := names.c names.h stub_driver.c stub_driver.h usbip.h \
+		       usbip_common.c usbip_common.h vhci_driver.c vhci_driver.h
diff -druN linux-2.6.39-libre/drivers/staging/usbip/userspace/libsrc/names.c linux-3.0-rc7-libre/drivers/staging/usbip/userspace/libsrc/names.c
--- linux-2.6.39-libre/drivers/staging/usbip/userspace/libsrc/names.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/staging/usbip/userspace/libsrc/names.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,793 @@
+/*****************************************************************************/
+/*
+ *      names.c  --  USB name database manipulation routines
+ *
+ *      Copyright (C) 1999, 2000  Thomas Sailer (sailer@ife.ee.ethz.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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *
+ */
+
+/*
+ * 	Copyright (C) 2005 Takahiro Hirofuchi
+ * 		- names_deinit() is added.
+ */
+
+/*****************************************************************************/
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <dirent.h>
+#include <string.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <ctype.h>
+
+
+#include "names.h"
+
+
+/* ---------------------------------------------------------------------- */
+
+struct vendor {
+	struct vendor *next;
+	u_int16_t vendorid;
+	char name[1];
+};
+
+struct product {
+	struct product *next;
+	u_int16_t vendorid, productid;
+	char name[1];
+};
+
+struct class {
+	struct class *next;
+	u_int8_t classid;
+	char name[1];
+};
+
+struct subclass {
+	struct subclass *next;
+	u_int8_t classid, subclassid;
+	char name[1];
+};
+
+struct protocol {
+	struct protocol *next;
+	u_int8_t classid, subclassid, protocolid;
+	char name[1];
+};
+
+struct audioterminal {
+	struct audioterminal *next;
+	u_int16_t termt;
+	char name[1];
+};
+
+struct genericstrtable {
+        struct genericstrtable *next;
+        unsigned int num;
+        char name[1];
+};
+
+/* ---------------------------------------------------------------------- */
+
+#define HASH1  0x10
+#define HASH2  0x02
+#define HASHSZ 16
+
+static unsigned int hashnum(unsigned int num)
+{
+	unsigned int mask1 = HASH1 << 27, mask2 = HASH2 << 27;
+
+	for (; mask1 >= HASH1; mask1 >>= 1, mask2 >>= 1)
+		if (num & mask1)
+			num ^= mask2;
+	return num & (HASHSZ-1);
+}
+
+/* ---------------------------------------------------------------------- */
+
+static struct vendor *vendors[HASHSZ] = { NULL, };
+static struct product *products[HASHSZ] = { NULL, };
+static struct class *classes[HASHSZ] = { NULL, };
+static struct subclass *subclasses[HASHSZ] = { NULL, };
+static struct protocol *protocols[HASHSZ] = { NULL, };
+static struct audioterminal *audioterminals[HASHSZ] = { NULL, };
+static struct genericstrtable *hiddescriptors[HASHSZ] = { NULL, };
+static struct genericstrtable *reports[HASHSZ] = { NULL, };
+static struct genericstrtable *huts[HASHSZ] = { NULL, };
+static struct genericstrtable *biass[HASHSZ] = { NULL, };
+static struct genericstrtable *physdess[HASHSZ] = { NULL, };
+static struct genericstrtable *hutus[HASHSZ] = { NULL, };
+static struct genericstrtable *langids[HASHSZ] = { NULL, };
+static struct genericstrtable *countrycodes[HASHSZ] = { NULL, };
+
+/* ---------------------------------------------------------------------- */
+
+static const char *names_genericstrtable(struct genericstrtable *t[HASHSZ], unsigned int index)
+{
+        struct genericstrtable *h;
+
+        for (h = t[hashnum(index)]; h; h = h->next)
+                if (h->num == index)
+                        return h->name;
+        return NULL;
+}
+
+const char *names_hid(u_int8_t hidd)
+{
+	return names_genericstrtable(hiddescriptors, hidd);
+}
+
+const char *names_reporttag(u_int8_t rt)
+{
+	return names_genericstrtable(reports, rt);
+}
+
+const char *names_huts(unsigned int data)
+{
+	return names_genericstrtable(huts, data);
+}
+
+const char *names_hutus(unsigned int data)
+{
+	return names_genericstrtable(hutus, data);
+}
+
+const char *names_langid(u_int16_t langid)
+{
+	return names_genericstrtable(langids, langid);
+}
+
+const char *names_physdes(u_int8_t ph)
+{
+	return names_genericstrtable(physdess, ph);
+}
+
+const char *names_bias(u_int8_t b)
+{
+	return names_genericstrtable(biass, b);
+}
+
+const char *names_countrycode(unsigned int countrycode)
+{
+	return names_genericstrtable(countrycodes, countrycode);
+}
+
+const char *names_vendor(u_int16_t vendorid)
+{
+	struct vendor *v;
+
+	v = vendors[hashnum(vendorid)];
+	for (; v; v = v->next)
+		if (v->vendorid == vendorid)
+			return v->name;
+	return NULL;
+}
+
+const char *names_product(u_int16_t vendorid, u_int16_t productid)
+{
+	struct product *p;
+
+	p = products[hashnum((vendorid << 16) | productid)];
+	for (; p; p = p->next)
+		if (p->vendorid == vendorid && p->productid == productid)
+			return p->name;
+	return NULL;
+}
+
+const char *names_class(u_int8_t classid)
+{
+	struct class *c;
+
+	c = classes[hashnum(classid)];
+	for (; c; c = c->next)
+		if (c->classid == classid)
+			return c->name;
+	return NULL;
+}
+
+const char *names_subclass(u_int8_t classid, u_int8_t subclassid)
+{
+	struct subclass *s;
+
+	s = subclasses[hashnum((classid << 8) | subclassid)];
+	for (; s; s = s->next)
+		if (s->classid == classid && s->subclassid == subclassid)
+			return s->name;
+	return NULL;
+}
+
+const char *names_protocol(u_int8_t classid, u_int8_t subclassid, u_int8_t protocolid)
+{
+	struct protocol *p;
+
+	p = protocols[hashnum((classid << 16) | (subclassid << 8) | protocolid)];
+	for (; p; p = p->next)
+		if (p->classid == classid && p->subclassid == subclassid && p->protocolid == protocolid)
+			return p->name;
+	return NULL;
+}
+
+const char *names_audioterminal(u_int16_t termt)
+{
+	struct audioterminal *at;
+
+	at = audioterminals[hashnum(termt)];
+	for (; at; at = at->next)
+		if (at->termt == termt)
+			return at->name;
+	return NULL;
+}
+
+/* ---------------------------------------------------------------------- */
+/* add a cleanup function by takahiro */
+
+struct pool {
+	struct pool *next;
+	void *mem;
+};
+
+static struct pool *pool_head = NULL;
+
+static void *my_malloc(size_t size)
+{
+	struct pool *p;
+
+	p = calloc(1, sizeof(struct pool));
+	if (!p) {
+		free(p);
+		return NULL;
+	}
+
+	p->mem = calloc(1, size);
+	if (!p->mem)
+		return NULL;
+
+	p->next = pool_head;
+	pool_head = p;
+
+	return p->mem;
+}
+
+void names_free(void)
+{
+	struct pool *pool;
+
+	if (!pool_head)
+		return;
+
+	for (pool = pool_head; pool != NULL; ) {
+		struct pool *tmp;
+
+		if (pool->mem)
+			free(pool->mem);
+
+		tmp = pool;
+		pool = pool->next;
+		free(tmp);
+	}
+}
+
+/* ---------------------------------------------------------------------- */
+
+static int new_vendor(const char *name, u_int16_t vendorid)
+{
+	struct vendor *v;
+	unsigned int h = hashnum(vendorid);
+
+	v = vendors[h];
+	for (; v; v = v->next)
+		if (v->vendorid == vendorid)
+			return -1;
+	v = my_malloc(sizeof(struct vendor) + strlen(name));
+	if (!v)
+		return -1;
+	strcpy(v->name, name);
+	v->vendorid = vendorid;
+	v->next = vendors[h];
+	vendors[h] = v;
+	return 0;
+}
+
+static int new_product(const char *name, u_int16_t vendorid, u_int16_t productid)
+{
+	struct product *p;
+	unsigned int h = hashnum((vendorid << 16) | productid);
+
+	p = products[h];
+	for (; p; p = p->next)
+		if (p->vendorid == vendorid && p->productid == productid)
+			return -1;
+	p = my_malloc(sizeof(struct product) + strlen(name));
+	if (!p)
+		return -1;
+	strcpy(p->name, name);
+	p->vendorid = vendorid;
+	p->productid = productid;
+	p->next = products[h];
+	products[h] = p;
+	return 0;
+}
+
+static int new_class(const char *name, u_int8_t classid)
+{
+	struct class *c;
+	unsigned int h = hashnum(classid);
+
+	c = classes[h];
+	for (; c; c = c->next)
+		if (c->classid == classid)
+			return -1;
+	c = my_malloc(sizeof(struct class) + strlen(name));
+	if (!c)
+		return -1;
+	strcpy(c->name, name);
+	c->classid = classid;
+	c->next = classes[h];
+	classes[h] = c;
+	return 0;
+}
+
+static int new_subclass(const char *name, u_int8_t classid, u_int8_t subclassid)
+{
+	struct subclass *s;
+	unsigned int h = hashnum((classid << 8) | subclassid);
+
+	s = subclasses[h];
+	for (; s; s = s->next)
+		if (s->classid == classid && s->subclassid == subclassid)
+			return -1;
+	s = my_malloc(sizeof(struct subclass) + strlen(name));
+	if (!s)
+		return -1;
+	strcpy(s->name, name);
+	s->classid = classid;
+	s->subclassid = subclassid;
+	s->next = subclasses[h];
+	subclasses[h] = s;
+	return 0;
+}
+
+static int new_protocol(const char *name, u_int8_t classid, u_int8_t subclassid, u_int8_t protocolid)
+{
+	struct protocol *p;
+	unsigned int h = hashnum((classid << 16) | (subclassid << 8) | protocolid);
+
+	p = protocols[h];
+	for (; p; p = p->next)
+		if (p->classid == classid && p->subclassid == subclassid && p->protocolid == protocolid)
+			return -1;
+	p = my_malloc(sizeof(struct protocol) + strlen(name));
+	if (!p)
+		return -1;
+	strcpy(p->name, name);
+	p->classid = classid;
+	p->subclassid = subclassid;
+	p->protocolid = protocolid;
+	p->next = protocols[h];
+	protocols[h] = p;
+	return 0;
+}
+
+static int new_audioterminal(const char *name, u_int16_t termt)
+{
+	struct audioterminal *at;
+	unsigned int h = hashnum(termt);
+
+	at = audioterminals[h];
+	for (; at; at = at->next)
+		if (at->termt == termt)
+			return -1;
+	at = my_malloc(sizeof(struct audioterminal) + strlen(name));
+	if (!at)
+		return -1;
+	strcpy(at->name, name);
+	at->termt = termt;
+	at->next = audioterminals[h];
+	audioterminals[h] = at;
+	return 0;
+}
+
+static int new_genericstrtable(struct genericstrtable *t[HASHSZ], const char *name, unsigned int index)
+{
+        struct genericstrtable *g;
+	unsigned int h = hashnum(index);
+
+        for (g = t[h]; g; g = g->next)
+                if (g->num == index)
+                        return -1;
+        g = my_malloc(sizeof(struct genericstrtable) + strlen(name));
+        if (!g)
+                return -1;
+        strcpy(g->name, name);
+        g->num = index;
+        g->next = t[h];
+        t[h] = g;
+        return 0;
+}
+
+static int new_hid(const char *name, u_int8_t hidd)
+{
+	return new_genericstrtable(hiddescriptors, name, hidd);
+}
+
+static int new_reporttag(const char *name, u_int8_t rt)
+{
+	return new_genericstrtable(reports, name, rt);
+}
+
+static int new_huts(const char *name, unsigned int data)
+{
+	return new_genericstrtable(huts, name, data);
+}
+
+static int new_hutus(const char *name, unsigned int data)
+{
+	return new_genericstrtable(hutus, name, data);
+}
+
+static int new_langid(const char *name, u_int16_t langid)
+{
+	return new_genericstrtable(langids, name, langid);
+}
+
+static int new_physdes(const char *name, u_int8_t ph)
+{
+	return new_genericstrtable(physdess, name, ph);
+}
+static int new_bias(const char *name, u_int8_t b)
+{
+	return new_genericstrtable(biass, name, b);
+}
+
+static int new_countrycode(const char *name, unsigned int countrycode)
+{
+	return new_genericstrtable(countrycodes, name, countrycode);
+}
+
+/* ---------------------------------------------------------------------- */
+
+#define DBG(x)
+
+static void parse(FILE *f)
+{
+	char buf[512], *cp;
+	unsigned int linectr = 0;
+	int lastvendor = -1, lastclass = -1, lastsubclass = -1, lasthut=-1, lastlang=-1;
+	unsigned int u;
+
+	while (fgets(buf, sizeof(buf), f)) {
+		linectr++;
+		/* remove line ends */
+		if ((cp = strchr(buf, 13)))
+			*cp = 0;
+		if ((cp = strchr(buf, 10)))
+			*cp = 0;
+		if (buf[0] == '#' || !buf[0])
+			continue;
+		cp = buf;
+                if (buf[0] == 'P' && buf[1] == 'H' && buf[2] == 'Y' && buf[3] == 'S' && buf[4] == 'D' &&
+                    buf[5] == 'E' && buf[6] == 'S' && /*isspace(buf[7])*/ buf[7] == ' ') {
+                        cp = buf + 8;
+                        while (isspace(*cp))
+                                cp++;
+                        if (!isxdigit(*cp)) {
+                                fprintf(stderr, "Invalid Physdes type at line %u\n", linectr);
+                                continue;
+                        }
+                        u = strtoul(cp, &cp, 16);
+                        while (isspace(*cp))
+                                cp++;
+                        if (!*cp) {
+                                fprintf(stderr, "Invalid Physdes type at line %u\n", linectr);
+                                continue;
+                        }
+                        if (new_physdes(cp, u))
+                                fprintf(stderr, "Duplicate Physdes  type spec at line %u terminal type %04x %s\n", linectr, u, cp);
+                        DBG(printf("line %5u physdes type %02x %s\n", linectr, u, cp));
+                        continue;
+
+                }
+                if (buf[0] == 'P' && buf[1] == 'H' && buf[2] == 'Y' && /*isspace(buf[3])*/ buf[3] == ' ') {
+                        cp = buf + 4;
+                        while (isspace(*cp))
+                                cp++;
+                        if (!isxdigit(*cp)) {
+                                fprintf(stderr, "Invalid PHY type at line %u\n", linectr);
+                                continue;
+                        }
+                        u = strtoul(cp, &cp, 16);
+                        while (isspace(*cp))
+                                cp++;
+                        if (!*cp) {
+                                fprintf(stderr, "Invalid PHY type at line %u\n", linectr);
+                                continue;
+                        }
+                        if (new_physdes(cp, u))
+                                fprintf(stderr, "Duplicate PHY type spec at line %u terminal type %04x %s\n", linectr, u, cp);
+                        DBG(printf("line %5u PHY type %02x %s\n", linectr, u, cp));
+                        continue;
+
+                }
+                if (buf[0] == 'B' && buf[1] == 'I' && buf[2] == 'A' && buf[3] == 'S' && /*isspace(buf[4])*/ buf[4] == ' ') {
+                        cp = buf + 5;
+                        while (isspace(*cp))
+                                cp++;
+                        if (!isxdigit(*cp)) {
+                                fprintf(stderr, "Invalid BIAS type at line %u\n", linectr);
+                                continue;
+                        }
+                        u = strtoul(cp, &cp, 16);
+                        while (isspace(*cp))
+                                cp++;
+                        if (!*cp) {
+                                fprintf(stderr, "Invalid BIAS type at line %u\n", linectr);
+                                continue;
+                        }
+                        if (new_bias(cp, u))
+                                fprintf(stderr, "Duplicate BIAS  type spec at line %u terminal type %04x %s\n", linectr, u, cp);
+                        DBG(printf("line %5u BIAS type %02x %s\n", linectr, u, cp));
+                        continue;
+
+                }
+                if (buf[0] == 'L' && /*isspace(buf[1])*/ buf[1] == ' ') {
+                        cp =  buf+2;
+                        while (isspace(*cp))
+                                cp++;
+                        if (!isxdigit(*cp)) {
+                                fprintf(stderr, "Invalid LANGID spec at line %u\n", linectr);
+                                continue;
+                        }
+                        u = strtoul(cp, &cp, 16);
+                        while (isspace(*cp))
+                                cp++;
+                        if (!*cp) {
+                                fprintf(stderr, "Invalid LANGID spec at line %u\n", linectr);
+                                continue;
+                        }
+                        if (new_langid(cp, u))
+                                fprintf(stderr, "Duplicate LANGID spec at line %u language-id %04x %s\n", linectr, u, cp);
+                        DBG(printf("line %5u LANGID %02x %s\n", linectr, u, cp));
+                        lasthut = lastclass = lastvendor = lastsubclass = -1;
+                        lastlang = u;
+                        continue;
+                }
+		if (buf[0] == 'C' && /*isspace(buf[1])*/ buf[1] == ' ') {
+			/* class spec */
+			cp = buf+2;
+			while (isspace(*cp))
+				cp++;
+			if (!isxdigit(*cp)) {
+				fprintf(stderr, "Invalid class spec at line %u\n", linectr);
+				continue;
+			}
+			u = strtoul(cp, &cp, 16);
+			while (isspace(*cp))
+				cp++;
+			if (!*cp) {
+				fprintf(stderr, "Invalid class spec at line %u\n", linectr);
+				continue;
+			}
+			if (new_class(cp, u))
+				fprintf(stderr, "Duplicate class spec at line %u class %04x %s\n", linectr, u, cp);
+			DBG(printf("line %5u class %02x %s\n", linectr, u, cp));
+			lasthut = lastlang = lastvendor = lastsubclass = -1;
+			lastclass = u;
+			continue;
+		}
+		if (buf[0] == 'A' && buf[1] == 'T' && isspace(buf[2])) {
+			/* audio terminal type spec */
+			cp = buf+3;
+			while (isspace(*cp))
+				cp++;
+			if (!isxdigit(*cp)) {
+				fprintf(stderr, "Invalid audio terminal type at line %u\n", linectr);
+				continue;
+			}
+			u = strtoul(cp, &cp, 16);
+			while (isspace(*cp))
+				cp++;
+			if (!*cp) {
+				fprintf(stderr, "Invalid audio terminal type at line %u\n", linectr);
+				continue;
+			}
+			if (new_audioterminal(cp, u))
+				fprintf(stderr, "Duplicate audio terminal type spec at line %u terminal type %04x %s\n", linectr, u, cp);
+			DBG(printf("line %5u audio terminal type %02x %s\n", linectr, u, cp));
+			continue;
+		}
+		if (buf[0] == 'H' && buf[1] == 'C' && buf[2] == 'C' && isspace(buf[3])) {
+			/* HID Descriptor bCountryCode */
+                        cp =  buf+3;
+                        while (isspace(*cp))
+                                cp++;
+                        if (!isxdigit(*cp)) {
+                                fprintf(stderr, "Invalid HID country code at line %u\n", linectr);
+                                continue;
+                        }
+                        u = strtoul(cp, &cp, 10);
+                        while (isspace(*cp))
+                                cp++;
+                        if (!*cp) {
+                                fprintf(stderr, "Invalid HID country code at line %u\n", linectr);
+                                continue;
+                        }
+                        if (new_countrycode(cp, u))
+                                fprintf(stderr, "Duplicate HID country code at line %u country %02u %s\n", linectr, u, cp);
+                        DBG(printf("line %5u keyboard country code %02u %s\n", linectr, u, cp));
+                        continue;
+		}
+		if (isxdigit(*cp)) {
+			/* vendor */
+			u = strtoul(cp, &cp, 16);
+			while (isspace(*cp))
+				cp++;
+			if (!*cp) {
+				fprintf(stderr, "Invalid vendor spec at line %u\n", linectr);
+				continue;
+			}
+			if (new_vendor(cp, u))
+				fprintf(stderr, "Duplicate vendor spec at line %u vendor %04x %s\n", linectr, u, cp);
+			DBG(printf("line %5u vendor %04x %s\n", linectr, u, cp));
+			lastvendor = u;
+			lasthut = lastlang = lastclass = lastsubclass = -1;
+			continue;
+		}
+		if (buf[0] == '\t' && isxdigit(buf[1])) {
+			/* product or subclass spec */
+			u = strtoul(buf+1, &cp, 16);
+			while (isspace(*cp))
+				cp++;
+			if (!*cp) {
+				fprintf(stderr, "Invalid product/subclass spec at line %u\n", linectr);
+				continue;
+			}
+			if (lastvendor != -1) {
+				if (new_product(cp, lastvendor, u))
+					fprintf(stderr, "Duplicate product spec at line %u product %04x:%04x %s\n", linectr, lastvendor, u, cp);
+				DBG(printf("line %5u product %04x:%04x %s\n", linectr, lastvendor, u, cp));
+				continue;
+			}
+			if (lastclass != -1) {
+				if (new_subclass(cp, lastclass, u))
+					fprintf(stderr, "Duplicate subclass spec at line %u class %02x:%02x %s\n", linectr, lastclass, u, cp);
+				DBG(printf("line %5u subclass %02x:%02x %s\n", linectr, lastclass, u, cp));
+				lastsubclass = u;
+				continue;
+			}
+			if (lasthut != -1) {
+				if (new_hutus(cp, (lasthut << 16)+u))
+					fprintf(stderr, "Duplicate HUT Usage Spec at line %u\n", linectr);
+				continue;
+			}
+			if (lastlang != -1) {
+                                if (new_langid(cp, lastlang+(u<<10)))
+                                        fprintf(stderr, "Duplicate LANGID Usage Spec at line %u\n", linectr);
+                                continue;
+                        }
+			fprintf(stderr, "Product/Subclass spec without prior Vendor/Class spec at line %u\n", linectr);
+			continue;
+		}
+		if (buf[0] == '\t' && buf[1] == '\t' && isxdigit(buf[2])) {
+			/* protocol spec */
+			u = strtoul(buf+2, &cp, 16);
+			while (isspace(*cp))
+				cp++;
+			if (!*cp) {
+				fprintf(stderr, "Invalid protocol spec at line %u\n", linectr);
+				continue;
+			}
+			if (lastclass != -1 && lastsubclass != -1) {
+				if (new_protocol(cp, lastclass, lastsubclass, u))
+					fprintf(stderr, "Duplicate protocol spec at line %u class %02x:%02x:%02x %s\n", linectr, lastclass, lastsubclass, u, cp);
+				DBG(printf("line %5u protocol %02x:%02x:%02x %s\n", linectr, lastclass, lastsubclass, u, cp));
+				continue;
+			}
+			fprintf(stderr, "Protocol spec without prior Class and Subclass spec at line %u\n", linectr);
+			continue;
+		}
+		if (buf[0] == 'H' && buf[1] == 'I' && buf[2] == 'D' && /*isspace(buf[3])*/ buf[3] == ' ') {
+			cp = buf + 4;
+                        while (isspace(*cp))
+                                cp++;
+                        if (!isxdigit(*cp)) {
+                                fprintf(stderr, "Invalid HID type at line %u\n", linectr);
+                                continue;
+                        }
+                        u = strtoul(cp, &cp, 16);
+                        while (isspace(*cp))
+                                cp++;
+                        if (!*cp) {
+                                fprintf(stderr, "Invalid HID type at line %u\n", linectr);
+                                continue;
+                        }
+                        if (new_hid(cp, u))
+                                fprintf(stderr, "Duplicate HID type spec at line %u terminal type %04x %s\n", linectr, u, cp);
+                        DBG(printf("line %5u HID type %02x %s\n", linectr, u, cp));
+                        continue;
+
+		}
+                if (buf[0] == 'H' && buf[1] == 'U' && buf[2] == 'T' && /*isspace(buf[3])*/ buf[3] == ' ') {
+                        cp = buf + 4;
+                        while (isspace(*cp))
+                                cp++;
+                        if (!isxdigit(*cp)) {
+                                fprintf(stderr, "Invalid HUT type at line %u\n", linectr);
+                                continue;
+                        }
+                        u = strtoul(cp, &cp, 16);
+                        while (isspace(*cp))
+                                cp++;
+                        if (!*cp) {
+                                fprintf(stderr, "Invalid HUT type at line %u\n", linectr);
+                                continue;
+                        }
+                        if (new_huts(cp, u))
+                                fprintf(stderr, "Duplicate HUT type spec at line %u terminal type %04x %s\n", linectr, u, cp);
+			lastlang = lastclass = lastvendor = lastsubclass = -1;
+			lasthut = u;
+                        DBG(printf("line %5u HUT type %02x %s\n", linectr, u, cp));
+                        continue;
+
+                }
+                if (buf[0] == 'R' && buf[1] == ' ') {
+                        cp = buf + 2;
+                        while (isspace(*cp))
+                                cp++;
+                        if (!isxdigit(*cp)) {
+                                fprintf(stderr, "Invalid Report type at line %u\n", linectr);
+                                continue;
+                        }
+                        u = strtoul(cp, &cp, 16);
+                        while (isspace(*cp))
+                                cp++;
+                        if (!*cp) {
+                                fprintf(stderr, "Invalid Report type at line %u\n", linectr);
+                                continue;
+                        }
+                        if (new_reporttag(cp, u))
+                                fprintf(stderr, "Duplicate Report type spec at line %u terminal type %04x %s\n", linectr, u, cp);
+                        DBG(printf("line %5u Report type %02x %s\n", linectr, u, cp));
+                        continue;
+
+                }
+                if (buf[0] == 'V' && buf[1] == 'T') {
+			/* add here */
+			continue;
+		}
+		fprintf(stderr, "Unknown line at line %u\n", linectr);
+	}
+}
+
+/* ---------------------------------------------------------------------- */
+
+int names_init(char *n)
+{
+	FILE *f;
+
+	if (!(f = fopen(n, "r"))) {
+		return errno;
+	}
+	parse(f);
+	fclose(f);
+	return 0;
+}
diff -druN linux-2.6.39-libre/drivers/staging/usbip/userspace/libsrc/names.h linux-3.0-rc7-libre/drivers/staging/usbip/userspace/libsrc/names.h
--- linux-2.6.39-libre/drivers/staging/usbip/userspace/libsrc/names.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/staging/usbip/userspace/libsrc/names.h	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,57 @@
+/*****************************************************************************/
+
+/*
+ *      names.h  --  USB name database manipulation routines
+ *
+ *      Copyright (C) 1999, 2000  Thomas Sailer (sailer@ife.ee.ethz.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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ *
+ */
+
+/*
+ *	Copyright (C) 2005 Takahiro Hirofuchi
+ *	       - names_free() is added.
+ */
+
+/*****************************************************************************/
+
+#ifndef _NAMES_H
+#define _NAMES_H
+
+#include <sys/types.h>
+
+/* ---------------------------------------------------------------------- */
+
+extern const char *names_vendor(u_int16_t vendorid);
+extern const char *names_product(u_int16_t vendorid, u_int16_t productid);
+extern const char *names_class(u_int8_t classid);
+extern const char *names_subclass(u_int8_t classid, u_int8_t subclassid);
+extern const char *names_protocol(u_int8_t classid, u_int8_t subclassid, u_int8_t protocolid);
+extern const char *names_audioterminal(u_int16_t termt);
+extern const char *names_hid(u_int8_t hidd);
+extern const char *names_reporttag(u_int8_t rt);
+extern const char *names_huts(unsigned int data);
+extern const char *names_hutus(unsigned int data);
+extern const char *names_langid(u_int16_t langid);
+extern const char *names_physdes(u_int8_t ph);
+extern const char *names_bias(u_int8_t b);
+extern const char *names_countrycode(unsigned int countrycode);
+extern int  names_init(char *n);
+extern void names_free(void);
+
+/* ---------------------------------------------------------------------- */
+#endif /* _NAMES_H */
diff -druN linux-2.6.39-libre/drivers/staging/usbip/userspace/libsrc/stub_driver.c linux-3.0-rc7-libre/drivers/staging/usbip/userspace/libsrc/stub_driver.c
--- linux-2.6.39-libre/drivers/staging/usbip/userspace/libsrc/stub_driver.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/staging/usbip/userspace/libsrc/stub_driver.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,391 @@
+/*
+ * Copyright (C) 2005-2007 Takahiro Hirofuchi
+ */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#include "usbip.h"
+
+/* kernel module name */
+static const char *usbip_stub_driver_name = "usbip-host";
+
+
+struct usbip_stub_driver *stub_driver;
+
+static struct sysfs_driver *open_sysfs_stub_driver(void)
+{
+	int ret;
+
+	char sysfs_mntpath[SYSFS_PATH_MAX];
+	char stub_driver_path[SYSFS_PATH_MAX];
+	struct sysfs_driver *stub_driver;
+
+
+	ret = sysfs_get_mnt_path(sysfs_mntpath, SYSFS_PATH_MAX);
+	if (ret < 0) {
+		err("sysfs must be mounted");
+		return NULL;
+	}
+
+	snprintf(stub_driver_path, SYSFS_PATH_MAX, "%s/%s/usb/%s/%s",
+			sysfs_mntpath, SYSFS_BUS_NAME, SYSFS_DRIVERS_NAME,
+			usbip_stub_driver_name);
+
+	stub_driver = sysfs_open_driver_path(stub_driver_path);
+	if (!stub_driver) {
+		err("usbip-core.ko and usbip-host.ko must be loaded");
+		return NULL;
+	}
+
+	return stub_driver;
+}
+
+
+#define SYSFS_OPEN_RETRIES 100
+
+/* only the first interface value is true! */
+static int32_t read_attr_usbip_status(struct usb_device *udev)
+{
+	char attrpath[SYSFS_PATH_MAX];
+	struct sysfs_attribute *attr;
+	int value = 0;
+	int  ret;
+	struct stat s;
+	int retries = SYSFS_OPEN_RETRIES;
+
+	/* This access is racy!
+	 *
+	 * Just after detach, our driver removes the sysfs
+	 * files and recreates them.
+	 *
+	 * We may try and fail to open the usbip_status of
+	 * an exported device in the (short) window where
+	 * it has been removed and not yet recreated.
+	 *
+	 * This is a bug in the interface. Nothing we can do
+	 * except work around it here by polling for the sysfs
+	 * usbip_status to reappear.
+	 */
+
+	snprintf(attrpath, SYSFS_PATH_MAX, "%s/%s:%d.%d/usbip_status",
+			udev->path, udev->busid,
+			udev->bConfigurationValue,
+			0);
+
+	while (retries > 0) {
+		if (stat(attrpath, &s) == 0)
+			break;
+
+		if (errno != ENOENT) {
+			err("error stat'ing %s", attrpath);
+			return -1;
+		}
+
+		usleep(10000); /* 10ms */
+		retries--;
+	}
+
+	if (retries == 0)
+		err("usbip_status not ready after %d retries",
+			SYSFS_OPEN_RETRIES);
+	else if (retries < SYSFS_OPEN_RETRIES)
+		info("warning: usbip_status ready after %d retries",
+			 SYSFS_OPEN_RETRIES - retries);
+
+	attr = sysfs_open_attribute(attrpath);
+	if (!attr) {
+		err("open %s", attrpath);
+		return -1;
+	}
+
+	ret = sysfs_read_attribute(attr);
+	if (ret) {
+		err("read %s", attrpath);
+		sysfs_close_attribute(attr);
+		return -1;
+	}
+
+	value = atoi(attr->value);
+
+	sysfs_close_attribute(attr);
+
+	return value;
+}
+
+
+static void usbip_exported_device_delete(void *dev)
+{
+	struct usbip_exported_device *edev =
+		(struct usbip_exported_device *) dev;
+
+	sysfs_close_device(edev->sudev);
+	free(dev);
+}
+
+
+static struct usbip_exported_device *usbip_exported_device_new(char *sdevpath)
+{
+	struct usbip_exported_device *edev = NULL;
+
+	edev = (struct usbip_exported_device *) calloc(1, sizeof(*edev));
+	if (!edev) {
+		err("alloc device");
+		return NULL;
+	}
+
+	edev->sudev = sysfs_open_device_path(sdevpath);
+	if (!edev->sudev) {
+		err("open %s", sdevpath);
+		goto err;
+	}
+
+	read_usb_device(edev->sudev, &edev->udev);
+
+	edev->status = read_attr_usbip_status(&edev->udev);
+	if (edev->status < 0)
+		goto err;
+
+	/* reallocate buffer to include usb interface data */
+	size_t size = sizeof(*edev) + edev->udev.bNumInterfaces * sizeof(struct usb_interface);
+	edev = (struct usbip_exported_device *) realloc(edev, size);
+	if (!edev) {
+		err("alloc device");
+		goto err;
+	}
+
+	for (int i=0; i < edev->udev.bNumInterfaces; i++)
+		read_usb_interface(&edev->udev, i, &edev->uinf[i]);
+
+	return edev;
+
+err:
+	if (edev && edev->sudev)
+		sysfs_close_device(edev->sudev);
+	if (edev)
+		free(edev);
+	return NULL;
+}
+
+
+static int check_new(struct dlist *dlist, struct sysfs_device *target)
+{
+	struct sysfs_device *dev;
+
+	dlist_for_each_data(dlist, dev, struct sysfs_device) {
+		if (!strncmp(dev->bus_id, target->bus_id, SYSFS_BUS_ID_SIZE))
+			/* found. not new */
+			return 0;
+	}
+
+	return 1;
+}
+
+static void delete_nothing(void *dev __attribute__((unused)))
+{
+	/* do not delete anything. but, its container will be deleted. */
+}
+
+static int refresh_exported_devices(void)
+{
+	struct sysfs_device	*suinf;  /* sysfs_device of usb_interface */
+	struct dlist		*suinf_list;
+
+	struct sysfs_device	*sudev;  /* sysfs_device of usb_device */
+	struct dlist		*sudev_list;
+
+
+	sudev_list = dlist_new_with_delete(sizeof(struct sysfs_device), delete_nothing);
+
+	suinf_list = sysfs_get_driver_devices(stub_driver->sysfs_driver);
+	if (!suinf_list) {
+		printf("Bind usbip-host.ko to a usb device to be exportable!\n");
+		goto bye;
+	}
+
+	/* collect unique USB devices (not interfaces) */
+	dlist_for_each_data(suinf_list, suinf, struct sysfs_device) {
+
+		/* get usb device of this usb interface */
+		sudev = sysfs_get_device_parent(suinf);
+		if (!sudev) {
+			err("get parent dev of %s", suinf->name);
+			continue;
+		}
+
+		if (check_new(sudev_list, sudev)) {
+			dlist_unshift(sudev_list, sudev);
+		}
+	}
+
+	dlist_for_each_data(sudev_list, sudev, struct sysfs_device) {
+		struct usbip_exported_device *edev;
+
+		edev = usbip_exported_device_new(sudev->path);
+		if (!edev) {
+			err("usbip_exported_device new");
+			continue;
+		}
+
+		dlist_unshift(stub_driver->edev_list, (void *) edev);
+		stub_driver->ndevs++;
+	}
+
+
+	dlist_destroy(sudev_list);
+
+bye:
+
+	return 0;
+}
+
+int usbip_stub_refresh_device_list(void)
+{
+	int ret;
+
+	if (stub_driver->edev_list)
+		dlist_destroy(stub_driver->edev_list);
+
+	stub_driver->ndevs = 0;
+
+	stub_driver->edev_list = dlist_new_with_delete(sizeof(struct usbip_exported_device),
+			usbip_exported_device_delete);
+	if (!stub_driver->edev_list) {
+		err("alloc dlist");
+		return -1;
+	}
+
+	ret = refresh_exported_devices();
+	if (ret < 0)
+		return ret;
+
+	return 0;
+}
+
+int usbip_stub_driver_open(void)
+{
+	int ret;
+
+
+	stub_driver = (struct usbip_stub_driver *) calloc(1, sizeof(*stub_driver));
+	if (!stub_driver) {
+		err("alloc stub_driver");
+		return -1;
+	}
+
+	stub_driver->ndevs = 0;
+
+	stub_driver->edev_list = dlist_new_with_delete(sizeof(struct usbip_exported_device),
+			usbip_exported_device_delete);
+	if (!stub_driver->edev_list) {
+		err("alloc dlist");
+		goto err;
+	}
+
+	stub_driver->sysfs_driver = open_sysfs_stub_driver();
+	if (!stub_driver->sysfs_driver)
+		goto err;
+
+	ret = refresh_exported_devices();
+	if (ret < 0)
+		goto err;
+
+	return 0;
+
+
+err:
+	if (stub_driver->sysfs_driver)
+		sysfs_close_driver(stub_driver->sysfs_driver);
+	if (stub_driver->edev_list)
+		dlist_destroy(stub_driver->edev_list);
+	free(stub_driver);
+
+	stub_driver = NULL;
+	return -1;
+}
+
+
+void usbip_stub_driver_close(void)
+{
+	if (!stub_driver)
+		return;
+
+	if (stub_driver->edev_list)
+		dlist_destroy(stub_driver->edev_list);
+	if (stub_driver->sysfs_driver)
+		sysfs_close_driver(stub_driver->sysfs_driver);
+	free(stub_driver);
+
+	stub_driver = NULL;
+}
+
+int usbip_stub_export_device(struct usbip_exported_device *edev, int sockfd)
+{
+	char attrpath[SYSFS_PATH_MAX];
+	struct sysfs_attribute *attr;
+	char sockfd_buff[30];
+	int ret;
+
+
+	if (edev->status != SDEV_ST_AVAILABLE) {
+		info("device not available, %s", edev->udev.busid);
+		switch( edev->status ) {
+			case SDEV_ST_ERROR:
+				info("     status SDEV_ST_ERROR");
+				break;
+			case SDEV_ST_USED:
+				info("     status SDEV_ST_USED");
+				break;
+			default:
+				info("     status unknown: 0x%x", edev->status);
+		}
+		return -1;
+	}
+
+	/* only the first interface is true */
+	snprintf(attrpath, sizeof(attrpath), "%s/%s:%d.%d/%s",
+			edev->udev.path,
+			edev->udev.busid,
+			edev->udev.bConfigurationValue, 0,
+			"usbip_sockfd");
+
+	attr = sysfs_open_attribute(attrpath);
+	if (!attr) {
+		err("open %s", attrpath);
+		return -1;
+	}
+
+	snprintf(sockfd_buff, sizeof(sockfd_buff), "%d\n", sockfd);
+
+	dbg("write: %s", sockfd_buff);
+
+	ret = sysfs_write_attribute(attr, sockfd_buff, strlen(sockfd_buff));
+	if (ret < 0) {
+		err("write sockfd %s to %s", sockfd_buff, attrpath);
+		goto err_write_sockfd;
+	}
+
+	info("connect %s", edev->udev.busid);
+
+err_write_sockfd:
+	sysfs_close_attribute(attr);
+
+	return ret;
+}
+
+struct usbip_exported_device *usbip_stub_get_device(int num)
+{
+	struct usbip_exported_device *edev;
+	struct dlist		*dlist = stub_driver->edev_list;
+	int count = 0;
+
+	dlist_for_each_data(dlist, edev, struct usbip_exported_device) {
+		if (num == count)
+			return edev;
+		else
+			count++ ;
+	}
+
+	return NULL;
+}
diff -druN linux-2.6.39-libre/drivers/staging/usbip/userspace/libsrc/stub_driver.h linux-3.0-rc7-libre/drivers/staging/usbip/userspace/libsrc/stub_driver.h
--- linux-2.6.39-libre/drivers/staging/usbip/userspace/libsrc/stub_driver.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/staging/usbip/userspace/libsrc/stub_driver.h	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2005-2007 Takahiro Hirofuchi
+ */
+
+#ifndef _USBIP_STUB_DRIVER_H
+#define _USBIP_STUB_DRIVER_H
+
+#include "usbip.h"
+
+
+struct usbip_stub_driver {
+	int ndevs;
+	struct sysfs_driver *sysfs_driver;
+
+	struct dlist *edev_list;	/* list of exported device */
+};
+
+struct usbip_exported_device {
+	struct sysfs_device *sudev;
+
+	int32_t status;
+	struct usb_device    udev;
+	struct usb_interface uinf[];
+};
+
+
+extern struct usbip_stub_driver *stub_driver;
+
+int usbip_stub_driver_open(void);
+void usbip_stub_driver_close(void);
+
+int usbip_stub_refresh_device_list(void);
+int usbip_stub_export_device(struct usbip_exported_device *edev, int sockfd);
+
+struct usbip_exported_device *usbip_stub_get_device(int num);
+#endif
diff -druN linux-2.6.39-libre/drivers/staging/usbip/userspace/libsrc/usbip_common.c linux-3.0-rc7-libre/drivers/staging/usbip/userspace/libsrc/usbip_common.c
--- linux-2.6.39-libre/drivers/staging/usbip/userspace/libsrc/usbip_common.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/staging/usbip/userspace/libsrc/usbip_common.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,282 @@
+/*
+ * Copyright (C) 2005-2007 Takahiro Hirofuchi
+ */
+
+#include "usbip.h"
+#include "names.h"
+
+int usbip_use_syslog = 0;
+int usbip_use_stderr = 0;
+int usbip_use_debug  = 0;
+
+struct speed_string {
+	int num;
+	char *speed;
+	char *desc;
+};
+
+static const struct speed_string speed_strings[] = {
+	{ USB_SPEED_UNKNOWN, "unknown", "Unknown Speed"},
+	{ USB_SPEED_LOW,  "1.5", "Low Speed(1.5Mbps)"  },
+	{ USB_SPEED_FULL, "12",  "Full Speed(12Mbps)" },
+	{ USB_SPEED_HIGH, "480", "High Speed(480Mbps)" },
+	{ 0, NULL, NULL }
+};
+
+struct portst_string {
+	int num;
+	char *desc;
+};
+
+static struct portst_string portst_strings[] = {
+	{ SDEV_ST_AVAILABLE,	"Device Available" },
+	{ SDEV_ST_USED,		"Device in Use" },
+	{ SDEV_ST_ERROR,	"Device Error"},
+	{ VDEV_ST_NULL,		"Port Available"},
+	{ VDEV_ST_NOTASSIGNED,	"Port Initializing"},
+	{ VDEV_ST_USED,		"Port in Use"},
+	{ VDEV_ST_ERROR,	"Port Error"},
+	{ 0, NULL}
+};
+
+const char *usbip_status_string(int32_t status)
+{
+	for (int i=0; portst_strings[i].desc != NULL; i++)
+		if (portst_strings[i].num == status)
+			return portst_strings[i].desc;
+
+	return "Unknown Status";
+}
+
+const char *usbip_speed_string(int num)
+{
+	for (int i=0; speed_strings[i].speed != NULL; i++)
+		if (speed_strings[i].num == num)
+			return speed_strings[i].desc;
+
+	return "Unknown Speed";
+}
+
+
+#define DBG_UDEV_INTEGER(name)\
+	dbg("%-20s = %x", to_string(name), (int) udev->name)
+
+#define DBG_UINF_INTEGER(name)\
+	dbg("%-20s = %x", to_string(name), (int) uinf->name)
+
+void dump_usb_interface(struct usb_interface *uinf)
+{
+	char buff[100];
+	usbip_names_get_class(buff, sizeof(buff),
+			uinf->bInterfaceClass,
+			uinf->bInterfaceSubClass,
+			uinf->bInterfaceProtocol);
+	dbg("%-20s = %s", "Interface(C/SC/P)", buff);
+}
+
+void dump_usb_device(struct usb_device *udev)
+{
+	char buff[100];
+
+
+	dbg("%-20s = %s", "path",  udev->path);
+	dbg("%-20s = %s", "busid", udev->busid);
+
+	usbip_names_get_class(buff, sizeof(buff),
+			udev->bDeviceClass,
+			udev->bDeviceSubClass,
+			udev->bDeviceProtocol);
+	dbg("%-20s = %s", "Device(C/SC/P)", buff);
+
+	DBG_UDEV_INTEGER(bcdDevice);
+
+	usbip_names_get_product(buff, sizeof(buff),
+			udev->idVendor,
+			udev->idProduct);
+	dbg("%-20s = %s", "Vendor/Product", buff);
+
+	DBG_UDEV_INTEGER(bNumConfigurations);
+	DBG_UDEV_INTEGER(bNumInterfaces);
+
+	dbg("%-20s = %s", "speed",
+			usbip_speed_string(udev->speed));
+
+	DBG_UDEV_INTEGER(busnum);
+	DBG_UDEV_INTEGER(devnum);
+}
+
+
+int read_attr_value(struct sysfs_device *dev, const char *name, const char *format)
+{
+	char attrpath[SYSFS_PATH_MAX];
+	struct sysfs_attribute *attr;
+	int num = 0;
+	int ret;
+
+	snprintf(attrpath, sizeof(attrpath), "%s/%s", dev->path, name);
+
+	attr = sysfs_open_attribute(attrpath);
+	if (!attr) {
+		err("open attr %s", attrpath);
+		return 0;
+	}
+
+	ret = sysfs_read_attribute(attr);
+	if (ret < 0) {
+		err("read attr");
+		goto err;
+	}
+
+	ret = sscanf(attr->value, format, &num);
+	if (ret < 1) {
+		err("sscanf");
+		goto err;
+	}
+
+err:
+	sysfs_close_attribute(attr);
+
+	return num;
+}
+
+
+int read_attr_speed(struct sysfs_device *dev)
+{
+	char attrpath[SYSFS_PATH_MAX];
+	struct sysfs_attribute *attr;
+	char speed[100];
+	int ret;
+
+	snprintf(attrpath, sizeof(attrpath), "%s/%s", dev->path, "speed");
+
+	attr = sysfs_open_attribute(attrpath);
+	if (!attr) {
+		err("open attr");
+		return 0;
+	}
+
+	ret = sysfs_read_attribute(attr);
+	if (ret < 0) {
+		err("read attr");
+		goto err;
+	}
+
+	ret = sscanf(attr->value, "%s\n", speed);
+	if (ret < 1) {
+		err("sscanf");
+		goto err;
+	}
+err:
+	sysfs_close_attribute(attr);
+
+	for (int i=0; speed_strings[i].speed != NULL; i++) {
+		if (!strcmp(speed, speed_strings[i].speed))
+			return speed_strings[i].num;
+	}
+
+	return USB_SPEED_UNKNOWN;
+}
+
+#define READ_ATTR(object, type, dev, name, format)\
+	do { (object)->name = (type) read_attr_value(dev, to_string(name), format); } while (0)
+
+
+int read_usb_device(struct sysfs_device *sdev, struct usb_device *udev)
+{
+	uint32_t busnum, devnum;
+
+	READ_ATTR(udev, uint8_t,  sdev, bDeviceClass,		"%02x\n");
+	READ_ATTR(udev, uint8_t,  sdev, bDeviceSubClass,	"%02x\n");
+	READ_ATTR(udev, uint8_t,  sdev, bDeviceProtocol,	"%02x\n");
+
+	READ_ATTR(udev, uint16_t, sdev, idVendor,		"%04x\n");
+	READ_ATTR(udev, uint16_t, sdev, idProduct,		"%04x\n");
+	READ_ATTR(udev, uint16_t, sdev, bcdDevice,		"%04x\n");
+
+	READ_ATTR(udev, uint8_t,  sdev, bConfigurationValue,	"%02x\n");
+	READ_ATTR(udev, uint8_t,  sdev, bNumConfigurations,	"%02x\n");
+	READ_ATTR(udev, uint8_t,  sdev, bNumInterfaces,		"%02x\n");
+
+	READ_ATTR(udev, uint8_t,  sdev, devnum,			"%d\n");
+	udev->speed = read_attr_speed(sdev);
+
+	strncpy(udev->path,  sdev->path,  SYSFS_PATH_MAX);
+	strncpy(udev->busid, sdev->name, SYSFS_BUS_ID_SIZE);
+
+	sscanf(sdev->name, "%u-%u", &busnum, &devnum);
+	udev->busnum = busnum;
+
+	return 0;
+}
+
+int read_usb_interface(struct usb_device *udev, int i, struct usb_interface *uinf)
+{
+	char busid[SYSFS_BUS_ID_SIZE];
+	struct sysfs_device *sif;
+
+	sprintf(busid, "%s:%d.%d", udev->busid, udev->bConfigurationValue, i);
+
+	sif = sysfs_open_device("usb", busid);
+	if (!sif) {
+		err("open sif of %s", busid);
+		return -1;
+	}
+
+	READ_ATTR(uinf, uint8_t,  sif, bInterfaceClass,		"%02x\n");
+	READ_ATTR(uinf, uint8_t,  sif, bInterfaceSubClass,	"%02x\n");
+	READ_ATTR(uinf, uint8_t,  sif, bInterfaceProtocol,	"%02x\n");
+
+	sysfs_close_device(sif);
+
+	return 0;
+}
+
+int usbip_names_init(char *f)
+{
+	return names_init(f);
+}
+
+void usbip_names_free()
+{
+	names_free();
+}
+
+void usbip_names_get_product(char *buff, size_t size, uint16_t vendor, uint16_t product)
+{
+	const char *prod, *vend;
+
+	prod = names_product(vendor, product);
+	if (!prod)
+		prod = "unknown product";
+
+
+	vend = names_vendor(vendor);
+	if (!vend)
+		vend = "unknown vendor";
+
+	snprintf(buff, size, "%s : %s (%04x:%04x)", vend, prod, vendor, product);
+}
+
+void usbip_names_get_class(char *buff, size_t size, uint8_t class, uint8_t subclass, uint8_t protocol)
+{
+	const char *c, *s, *p;
+
+	if (class == 0 && subclass == 0 && protocol == 0) {
+		snprintf(buff, size, "(Defined at Interface level) (%02x/%02x/%02x)", class, subclass, protocol);
+		return;
+	}
+
+	p = names_protocol(class, subclass, protocol);
+	if (!p)
+		p = "unknown protocol";
+
+	s = names_subclass(class, subclass);
+	if (!s)
+		s = "unknown subclass";
+
+	c = names_class(class);
+	if (!c)
+		c = "unknown class";
+
+	snprintf(buff, size, "%s / %s / %s (%02x/%02x/%02x)", c, s, p, class, subclass, protocol);
+}
diff -druN linux-2.6.39-libre/drivers/staging/usbip/userspace/libsrc/usbip_common.h linux-3.0-rc7-libre/drivers/staging/usbip/userspace/libsrc/usbip_common.h
--- linux-2.6.39-libre/drivers/staging/usbip/userspace/libsrc/usbip_common.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/staging/usbip/userspace/libsrc/usbip_common.h	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,149 @@
+/*
+ * Copyright (C) 2005-2007 Takahiro Hirofuchi
+ */
+
+#ifndef _USBIP_COMMON_H
+#define _USBIP_COMMON_H
+
+#include <unistd.h>
+#include <stdint.h>
+#include <syslog.h>
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <strings.h>
+
+#include <sysfs/libsysfs.h>
+#include <netdb.h>
+#include <sys/socket.h>
+
+#ifndef USBIDS_FILE
+#define USBIDS_FILE "/usr/share/hwdata/usb.ids"
+#endif
+
+#ifndef VHCI_STATE_PATH
+#define VHCI_STATE_PATH "/var/run/vhci_hcd"
+#endif
+
+//#include <linux/usb_ch9.h>
+enum usb_device_speed {
+	USB_SPEED_UNKNOWN = 0,                  /* enumerating */
+	USB_SPEED_LOW, USB_SPEED_FULL,          /* usb 1.1 */
+	USB_SPEED_HIGH,                         /* usb 2.0 */
+	USB_SPEED_VARIABLE                      /* wireless (usb 2.5) */
+};
+
+/* FIXME: how to sync with drivers/usbip_common.h ? */
+enum usbip_device_status{
+	/* sdev is available. */
+	SDEV_ST_AVAILABLE = 0x01,
+	/* sdev is now used. */
+	SDEV_ST_USED,
+	/* sdev is unusable because of a fatal error. */
+	SDEV_ST_ERROR,
+
+	/* vdev does not connect a remote device. */
+	VDEV_ST_NULL,
+	/* vdev is used, but the USB address is not assigned yet */
+	VDEV_ST_NOTASSIGNED,
+	VDEV_ST_USED,
+	VDEV_ST_ERROR
+};
+
+extern int usbip_use_syslog;
+extern int usbip_use_stderr;
+extern int usbip_use_debug ;
+
+#define err(fmt, args...)	do { \
+	if (usbip_use_syslog) { \
+		syslog(LOG_ERR, "usbip err: %13s:%4d (%-12s) " fmt "\n", \
+			__FILE__, __LINE__, __FUNCTION__,  ##args); \
+	} \
+	if (usbip_use_stderr) { \
+		fprintf(stderr, "usbip err: %13s:%4d (%-12s) " fmt "\n", \
+			__FILE__, __LINE__, __FUNCTION__,  ##args); \
+	} \
+} while (0)
+
+#define notice(fmt, args...)	do { \
+	if (usbip_use_syslog) { \
+		syslog(LOG_DEBUG, "usbip: " fmt, ##args); \
+	} \
+	if (usbip_use_stderr) { \
+		fprintf(stderr, "usbip: " fmt "\n",  ##args); \
+	} \
+} while (0)
+
+#define info(fmt, args...)	do { \
+	if (usbip_use_syslog) { \
+		syslog(LOG_DEBUG, fmt, ##args); \
+	} \
+	if (usbip_use_stderr) { \
+		fprintf(stderr, fmt "\n",  ##args); \
+	} \
+} while (0)
+
+#define dbg(fmt, args...)	do { \
+	if (usbip_use_debug) { \
+		if (usbip_use_syslog) { \
+			syslog(LOG_DEBUG, "usbip dbg: %13s:%4d (%-12s) " fmt, \
+				__FILE__, __LINE__, __FUNCTION__,  ##args); \
+		} \
+		if (usbip_use_stderr) { \
+			fprintf(stderr, "usbip dbg: %13s:%4d (%-12s) " fmt "\n", \
+				__FILE__, __LINE__, __FUNCTION__,  ##args); \
+		} \
+	} \
+} while (0)
+
+
+#define BUG()	do { err("sorry, it's a bug"); abort(); } while (0)
+
+
+struct usb_interface {
+	uint8_t bInterfaceClass;
+	uint8_t bInterfaceSubClass;
+	uint8_t bInterfaceProtocol;
+	uint8_t padding;	/* alignment */
+} __attribute__((packed));
+
+
+
+struct usb_device {
+	char path[SYSFS_PATH_MAX];
+	char busid[SYSFS_BUS_ID_SIZE];
+
+	uint32_t busnum;
+	uint32_t devnum;
+	uint32_t speed;
+
+	uint16_t idVendor;
+	uint16_t idProduct;
+	uint16_t bcdDevice;
+
+	uint8_t bDeviceClass;
+	uint8_t bDeviceSubClass;
+	uint8_t bDeviceProtocol;
+	uint8_t bConfigurationValue;
+	uint8_t bNumConfigurations;
+	uint8_t bNumInterfaces;
+} __attribute__((packed));
+
+#define to_string(s)	#s
+
+void dump_usb_interface(struct usb_interface *);
+void dump_usb_device(struct usb_device *);
+int read_usb_device(struct sysfs_device *sdev, struct usb_device *udev);
+int read_attr_value(struct sysfs_device *dev, const char *name, const char *format);
+int read_usb_interface(struct usb_device *udev, int i, struct usb_interface *uinf);
+
+const char *usbip_speed_string(int num);
+const char *usbip_status_string(int32_t status);
+
+int usbip_names_init(char *);
+void usbip_names_free(void);
+void usbip_names_get_product(char *buff, size_t size, uint16_t vendor, uint16_t product);
+void usbip_names_get_class(char *buff, size_t size, uint8_t class, uint8_t subclass, uint8_t protocol);
+
+#endif
diff -druN linux-2.6.39-libre/drivers/staging/usbip/userspace/libsrc/usbip.h linux-3.0-rc7-libre/drivers/staging/usbip/userspace/libsrc/usbip.h
--- linux-2.6.39-libre/drivers/staging/usbip/userspace/libsrc/usbip.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/staging/usbip/userspace/libsrc/usbip.h	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2005-2007 Takahiro Hirofuchi
+ */
+
+#ifndef _USBIP_H
+#define _USBIP_H
+
+#ifdef HAVE_CONFIG_H
+#include "../config.h"
+#endif
+
+#include "usbip_common.h"
+#include "stub_driver.h"
+#include "vhci_driver.h"
+#ifdef DMALLOC
+#include <dmalloc.h>
+#endif
+
+#endif
diff -druN linux-2.6.39-libre/drivers/staging/usbip/userspace/libsrc/vhci_driver.c linux-3.0-rc7-libre/drivers/staging/usbip/userspace/libsrc/vhci_driver.c
--- linux-2.6.39-libre/drivers/staging/usbip/userspace/libsrc/vhci_driver.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/staging/usbip/userspace/libsrc/vhci_driver.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,506 @@
+/*
+ * Copyright (C) 2005-2007 Takahiro Hirofuchi
+ */
+
+
+#include "usbip.h"
+
+
+static const char vhci_driver_name[] = "vhci_hcd";
+
+struct usbip_vhci_driver *vhci_driver;
+
+static struct usbip_imported_device *imported_device_init(struct usbip_imported_device *idev, char *busid)
+{
+	struct sysfs_device *sudev;
+
+	sudev = sysfs_open_device("usb", busid);
+	if (!sudev) {
+		err("sysfs_open_device %s", busid);
+		goto err;
+	}
+	read_usb_device(sudev, &idev->udev);
+	sysfs_close_device(sudev);
+
+	/* add class devices of this imported device */
+	struct class_device *cdev;
+	dlist_for_each_data(vhci_driver->cdev_list, cdev, struct class_device) {
+		if (!strncmp(cdev->devpath, idev->udev.path, strlen(idev->udev.path))) {
+			struct class_device *new_cdev;
+
+			/* alloc and copy because dlist is linked from only one list */
+			new_cdev = calloc(1, sizeof(*new_cdev));
+			if (!new_cdev)
+				goto err;
+
+			memcpy(new_cdev, cdev, sizeof(*new_cdev));
+			dlist_unshift(idev->cdev_list, (void*) new_cdev);
+		}
+	}
+
+	return idev;
+
+err:
+	return NULL;
+}
+
+
+
+static int parse_status(char *value)
+{
+	int ret = 0;
+	char *c;
+
+
+	for (int i = 0; i < vhci_driver->nports; i++)
+		bzero(&vhci_driver->idev[i], sizeof(struct usbip_imported_device));
+
+
+	/* skip a header line */
+	c = strchr(value, '\n') + 1;
+
+	while (*c != '\0') {
+		int port, status, speed, devid;
+		unsigned long socket;
+		char lbusid[SYSFS_BUS_ID_SIZE];
+
+		ret = sscanf(c, "%d %d %d %x %lx %s\n",
+				&port, &status, &speed,
+				&devid, &socket, lbusid);
+
+		if (ret < 5) {
+			err("scanf %d", ret);
+			BUG();
+		}
+
+		dbg("port %d status %d speed %d devid %x",
+				port, status, speed, devid);
+		dbg("socket %lx lbusid %s", socket, lbusid);
+
+
+		/* if a device is connected, look at it */
+		{
+			struct usbip_imported_device *idev = &vhci_driver->idev[port];
+
+			idev->port	= port;
+			idev->status	= status;
+
+			idev->devid	= devid;
+
+			idev->busnum	= (devid >> 16);
+			idev->devnum	= (devid & 0x0000ffff);
+
+			idev->cdev_list = dlist_new(sizeof(struct class_device));
+			if (!idev->cdev_list) {
+				err("init new device");
+				return -1;
+			}
+
+			if (idev->status != VDEV_ST_NULL && idev->status != VDEV_ST_NOTASSIGNED) {
+				idev = imported_device_init(idev, lbusid);
+				if (!idev) {
+					err("init new device");
+					return -1;
+				}
+			}
+		}
+
+
+		/* go to the next line */
+		c = strchr(c, '\n') + 1;
+	}
+
+	dbg("exit");
+
+	return 0;
+}
+
+
+static int check_usbip_device(struct sysfs_class_device *cdev)
+{
+	char clspath[SYSFS_PATH_MAX];	/* /sys/class/video4linux/video0/device     */
+	char devpath[SYSFS_PATH_MAX];	/* /sys/devices/platform/vhci_hcd/usb6/6-1:1.1  */
+
+	int ret;
+
+	snprintf(clspath, sizeof(clspath), "%s/device", cdev->path);
+
+	ret = sysfs_get_link(clspath, devpath, SYSFS_PATH_MAX);
+	if (!ret) {
+		if (!strncmp(devpath, vhci_driver->hc_device->path,
+					strlen(vhci_driver->hc_device->path))) {
+			/* found usbip device */
+			struct class_device *cdev;
+
+			cdev = calloc(1, sizeof(*cdev));
+			if (!cdev) {
+				err("calloc cdev");
+				return -1;
+			}
+			dlist_unshift(vhci_driver->cdev_list, (void*) cdev);
+			strncpy(cdev->clspath, clspath, sizeof(cdev->clspath));
+			strncpy(cdev->devpath, devpath, sizeof(cdev->clspath));
+			dbg("  found %s %s", clspath, devpath);
+		}
+	}
+
+	return 0;
+}
+
+
+static int search_class_for_usbip_device(char *cname)
+{
+	struct sysfs_class *class;
+	struct dlist *cdev_list;
+	struct sysfs_class_device *cdev;
+	int ret = 0;
+
+	class = sysfs_open_class(cname);
+	if (!class) {
+		err("open class");
+		return -1;
+	}
+
+	dbg("class %s", class->name);
+
+	cdev_list = sysfs_get_class_devices(class);
+	if (!cdev_list)
+		/* nothing */
+		goto out;
+
+	dlist_for_each_data(cdev_list, cdev, struct sysfs_class_device) {
+		dbg("   cdev %s", cdev->name);
+		ret = check_usbip_device(cdev);
+		if (ret < 0)
+			goto out;
+	}
+
+out:
+	sysfs_close_class(class);
+
+	return ret;
+}
+
+
+static int refresh_class_device_list(void)
+{
+	int ret;
+	struct dlist *cname_list;
+	char *cname;
+
+	/* search under /sys/class */
+	cname_list = sysfs_open_directory_list("/sys/class");
+	if (!cname_list) {
+		err("open class directory");
+		return -1;
+	}
+
+	dlist_for_each_data(cname_list, cname, char) {
+		ret = search_class_for_usbip_device(cname);
+		if (ret < 0) {
+			sysfs_close_list(cname_list);
+			return -1;
+		}
+	}
+
+	sysfs_close_list(cname_list);
+
+	/* seach under /sys/block */
+	ret = search_class_for_usbip_device(SYSFS_BLOCK_NAME);
+	if (ret < 0)
+		return -1;
+
+	return 0;
+}
+
+
+static int refresh_imported_device_list(void)
+{
+	struct sysfs_attribute *attr_status;
+
+
+	attr_status = sysfs_get_device_attr(vhci_driver->hc_device, "status");
+	if (!attr_status) {
+		err("get attr %s of %s", "status", vhci_driver->hc_device->name);
+		return -1;
+	}
+
+	dbg("name %s, path %s, len %d, method %d\n", attr_status->name,
+			attr_status->path, attr_status->len, attr_status->method);
+
+	dbg("%s", attr_status->value);
+
+	return parse_status(attr_status->value);
+}
+
+static int get_nports(void)
+{
+	int nports = 0;
+	struct sysfs_attribute *attr_status;
+
+	attr_status = sysfs_get_device_attr(vhci_driver->hc_device, "status");
+	if (!attr_status) {
+		err("get attr %s of %s", "status", vhci_driver->hc_device->name);
+		return -1;
+	}
+
+	dbg("name %s, path %s, len %d, method %d\n", attr_status->name,
+			attr_status->path, attr_status->len, attr_status->method);
+
+	dbg("%s", attr_status->value);
+
+	{
+		char *c;
+
+		/* skip a header line */
+		c = strchr(attr_status->value, '\n') + 1;
+
+		while (*c != '\0') {
+			/* go to the next line */
+			c = strchr(c, '\n') + 1;
+			nports += 1;
+		}
+	}
+
+	return nports;
+}
+
+static int get_hc_busid(char *sysfs_mntpath, char *hc_busid)
+{
+        struct sysfs_driver *sdriver;
+        char sdriver_path[SYSFS_PATH_MAX];
+
+	struct sysfs_device *hc_dev;
+	struct dlist *hc_devs;
+
+	int found = 0;
+
+        snprintf(sdriver_path, SYSFS_PATH_MAX, "%s/%s/platform/%s/%s",
+                                sysfs_mntpath, SYSFS_BUS_NAME, SYSFS_DRIVERS_NAME,
+                                vhci_driver_name);
+
+        sdriver = sysfs_open_driver_path(sdriver_path);
+        if (!sdriver) {
+		info("%s is not found", sdriver_path);
+                info("load usbip-core.ko and vhci-hcd.ko !");
+                return -1;
+        }
+
+	hc_devs = sysfs_get_driver_devices(sdriver);
+	if (!hc_devs) {
+		err("get hc list");
+		goto err;
+	}
+
+	/* assume only one vhci_hcd */
+	dlist_for_each_data(hc_devs, hc_dev, struct sysfs_device) {
+		strncpy(hc_busid, hc_dev->bus_id, SYSFS_BUS_ID_SIZE);
+		found = 1;
+	}
+
+err:
+	sysfs_close_driver(sdriver);
+
+	if (found)
+		return 0;
+
+	err("not found usbip hc");
+	return -1;
+}
+
+
+/* ---------------------------------------------------------------------- */
+
+int usbip_vhci_driver_open(void)
+{
+	int ret;
+	char hc_busid[SYSFS_BUS_ID_SIZE];
+
+	vhci_driver = (struct usbip_vhci_driver *) calloc(1, sizeof(*vhci_driver));
+	if (!vhci_driver) {
+		err("alloc vhci_driver");
+		return -1;
+	}
+
+	ret = sysfs_get_mnt_path(vhci_driver->sysfs_mntpath, SYSFS_PATH_MAX);
+	if (ret < 0) {
+		err("sysfs must be mounted");
+		goto err;
+	}
+
+	ret = get_hc_busid(vhci_driver->sysfs_mntpath, hc_busid);
+	if (ret < 0)
+		goto err;
+
+	/* will be freed in usbip_driver_close() */
+	vhci_driver->hc_device = sysfs_open_device("platform", hc_busid);
+	if (!vhci_driver->hc_device) {
+		err("get sysfs vhci_driver");
+		goto err;
+	}
+
+	vhci_driver->nports = get_nports();
+
+	info("%d ports available\n", vhci_driver->nports);
+
+	vhci_driver->cdev_list = dlist_new(sizeof(struct class_device));
+	if (!vhci_driver->cdev_list)
+		goto err;
+
+	if (refresh_class_device_list())
+		goto err;
+
+	if (refresh_imported_device_list())
+		goto err;
+
+
+	return 0;
+
+
+err:
+	if (vhci_driver->cdev_list)
+		dlist_destroy(vhci_driver->cdev_list);
+	if (vhci_driver->hc_device)
+		sysfs_close_device(vhci_driver->hc_device);
+	if (vhci_driver)
+		free(vhci_driver);
+
+	vhci_driver = NULL;
+	return -1;
+}
+
+
+void usbip_vhci_driver_close()
+{
+	if (!vhci_driver)
+		return;
+
+	if (vhci_driver->cdev_list)
+		dlist_destroy(vhci_driver->cdev_list);
+
+	for (int i = 0; i < vhci_driver->nports; i++) {
+		if (vhci_driver->idev[i].cdev_list)
+			dlist_destroy(vhci_driver->idev[i].cdev_list);
+	}
+
+	if (vhci_driver->hc_device)
+		sysfs_close_device(vhci_driver->hc_device);
+	free(vhci_driver);
+
+	vhci_driver = NULL;
+}
+
+
+int usbip_vhci_refresh_device_list(void)
+{
+	if (vhci_driver->cdev_list)
+		dlist_destroy(vhci_driver->cdev_list);
+
+
+	for (int i = 0; i < vhci_driver->nports; i++) {
+		if (vhci_driver->idev[i].cdev_list)
+			dlist_destroy(vhci_driver->idev[i].cdev_list);
+	}
+
+	vhci_driver->cdev_list = dlist_new(sizeof(struct class_device));
+	if (!vhci_driver->cdev_list)
+		goto err;
+
+	if (refresh_class_device_list())
+		goto err;
+
+	if (refresh_imported_device_list())
+		goto err;
+
+	return 0;
+err:
+	if (vhci_driver->cdev_list)
+		dlist_destroy(vhci_driver->cdev_list);
+
+	for (int i = 0; i < vhci_driver->nports; i++) {
+		if (vhci_driver->idev[i].cdev_list)
+			dlist_destroy(vhci_driver->idev[i].cdev_list);
+	}
+
+	err("refresh device list");
+	return -1;
+}
+
+
+int usbip_vhci_get_free_port(void)
+{
+	for (int i = 0; i < vhci_driver->nports; i++) {
+		if (vhci_driver->idev[i].status == VDEV_ST_NULL)
+			return i;
+	}
+
+	return -1;
+}
+
+int usbip_vhci_attach_device2(uint8_t port, int sockfd, uint32_t devid,
+		uint32_t speed) {
+	struct sysfs_attribute *attr_attach;
+	char buff[200]; /* what size should be ? */
+	int ret;
+
+	attr_attach = sysfs_get_device_attr(vhci_driver->hc_device, "attach");
+	if (!attr_attach) {
+		err("get attach");
+		return -1;
+	}
+
+	snprintf(buff, sizeof(buff), "%u %u %u %u",
+			port, sockfd, devid, speed);
+	dbg("writing: %s", buff);
+
+	ret = sysfs_write_attribute(attr_attach, buff, strlen(buff));
+	if (ret < 0) {
+		err("write to attach failed");
+		return -1;
+	}
+
+	info("port %d attached", port);
+
+	return 0;
+}
+
+static unsigned long get_devid(uint8_t busnum, uint8_t devnum)
+{
+	return (busnum << 16) | devnum;
+}
+
+/* will be removed */
+int usbip_vhci_attach_device(uint8_t port, int sockfd, uint8_t busnum,
+		uint8_t devnum, uint32_t speed)
+{
+	int devid = get_devid(busnum, devnum);
+
+	return usbip_vhci_attach_device2(port, sockfd, devid, speed);
+}
+
+int usbip_vhci_detach_device(uint8_t port)
+{
+	struct sysfs_attribute  *attr_detach;
+	char buff[200]; /* what size should be ? */
+	int ret;
+
+	attr_detach = sysfs_get_device_attr(vhci_driver->hc_device, "detach");
+	if (!attr_detach) {
+		err("get detach");
+		return -1;
+	}
+
+	snprintf(buff, sizeof(buff), "%u", port);
+	dbg("writing to detach");
+	dbg("writing: %s", buff);
+
+	ret = sysfs_write_attribute(attr_detach, buff, strlen(buff));
+	if (ret < 0) {
+		err("write to detach failed");
+		return -1;
+	}
+
+	info("port %d detached", port);
+
+	return 0;
+}
diff -druN linux-2.6.39-libre/drivers/staging/usbip/userspace/libsrc/vhci_driver.h linux-3.0-rc7-libre/drivers/staging/usbip/userspace/libsrc/vhci_driver.h
--- linux-2.6.39-libre/drivers/staging/usbip/userspace/libsrc/vhci_driver.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/staging/usbip/userspace/libsrc/vhci_driver.h	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2005-2007 Takahiro Hirofuchi
+ */
+
+#ifndef _VHCI_DRIVER_H
+#define _VHCI_DRIVER_H
+
+#include "usbip.h"
+
+
+
+#define MAXNPORT 128
+
+struct class_device {
+	char clspath[SYSFS_PATH_MAX];
+	char devpath[SYSFS_PATH_MAX];
+};
+
+struct usbip_imported_device {
+	uint8_t port;
+	uint32_t status;
+
+	uint32_t devid;
+
+	uint8_t busnum;
+	uint8_t devnum;
+
+
+	struct dlist *cdev_list;	/* list of class device */
+	struct usb_device udev;
+};
+
+struct usbip_vhci_driver {
+	char sysfs_mntpath[SYSFS_PATH_MAX];
+	struct sysfs_device *hc_device; /* /sys/devices/platform/vhci_hcd */
+
+	struct dlist *cdev_list;	/* list of class device */
+
+	int nports;
+	struct usbip_imported_device idev[MAXNPORT];
+};
+
+
+extern struct usbip_vhci_driver *vhci_driver;
+
+int usbip_vhci_driver_open(void);
+void usbip_vhci_driver_close(void);
+
+int  usbip_vhci_refresh_device_list(void);
+
+
+int usbip_vhci_get_free_port(void);
+int usbip_vhci_attach_device2(uint8_t port, int sockfd, uint32_t devid,
+		uint32_t speed);
+
+/* will be removed */
+int usbip_vhci_attach_device(uint8_t port, int sockfd, uint8_t busnum,
+		uint8_t devnum, uint32_t speed);
+
+int usbip_vhci_detach_device(uint8_t port);
+#endif
diff -druN linux-2.6.39-libre/drivers/staging/usbip/userspace/Makefile.am linux-3.0-rc7-libre/drivers/staging/usbip/userspace/Makefile.am
--- linux-2.6.39-libre/drivers/staging/usbip/userspace/Makefile.am	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/staging/usbip/userspace/Makefile.am	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,11 @@
+SUBDIRS := libsrc src
+includedir := @includedir@/usbip
+include_HEADERS := $(addprefix libsrc/, \
+		     usbip.h usbip_common.h vhci_driver.h stub_driver.h)
+
+dist_man_MANS := $(addprefix doc/, usbip.8 usbipd.8 usbip_bind_driver.8)
+
+if INSTALL_USBIDS
+pkgdata_DATA := usb.ids
+EXTRA_DIST := $(pkgdata_DATA)
+endif
diff -druN linux-2.6.39-libre/drivers/staging/usbip/userspace/README linux-3.0-rc7-libre/drivers/staging/usbip/userspace/README
--- linux-2.6.39-libre/drivers/staging/usbip/userspace/README	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/staging/usbip/userspace/README	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,215 @@
+# vim:tw=78:ts=4:expandtab:ai:sw=4
+#
+# README for usbip-utils
+#
+# Copyright (C) 2005-2008 Takahiro Hirofuchi
+
+
+[Requirements]
+    - USB/IP device drivers
+        Its source code is included under $(top)/drivers/.
+
+    - sysfsutils >= 2.0.0
+        sysfsutils library
+
+    - libwrap0-dev
+        tcp wrapper library
+
+    - gcc >= 4.0
+
+    - libglib2.0-dev >= 2.6.0
+
+    - libtool, automake >= 1.9, autoconf >= 2.5.0, pkg-config
+
+[Install]
+    0. Skip here if you see a configure script.
+        $ ./autogen.sh
+
+    1. Compile & install.
+        $ ./configure
+        $ make install
+
+    2. Compile & install USB/IP drivers if not yet.
+
+[Usage]
+    server:# (Attach your USB device physically.)
+
+    server:# insmod usbip-core.ko
+    server:# insmod usbip-host.ko
+        - It was formerly named as stub.ko.
+
+    server:# usbipd -D
+        - Start usbip daemon.
+
+    server:# usbip_bind_driver --list
+        - List driver assignments for usb devices.
+
+    server:# usbip_bind_driver --usbip 1-2
+        - Bind usbip-host.ko to the device of busid 1-2.
+        - A usb device 1-2 is now exportable to other hosts!
+        - Use 'usbip_bind_driver --other 1-2' when you want to shutdown exporting
+          and use the device locally.
+
+
+    client:# insmod usbip-core.ko
+    client:# insmod vhci-hcd.ko
+        - It was formerly named as vhci.ko.
+
+    client:# usbip --list server
+        - List exportable usb devices on the server.
+
+    client:# usbip --attach server 1-2
+        - Connect the remote USB device.
+
+    client:# usbip --port
+        - Show virtual port status.
+
+    client:# usbip --detach 0
+        - Detach the usb device.
+
+
+[Output Example]
+--------------------------------------------------------------------------------------------------------
+- SERVER SIDE (physically attach your USB devices to this host) ----------------------------------------
+--------------------------------------------------------------------------------------------------------
+trois:# insmod (somewhere)/usbip-core.ko
+trois:# insmod (somewhere)/usbip-host.ko
+trois:# usbipd -D
+
+--------------------------------------------------------------------------------------------------------
+In another terminal, let's look up what usb devices are physically attached to
+this host.  We can see a usb storage device of busid 3-3.2 is now bound to
+usb-storage driver. To export this device, we first mark the device as
+"exportable"; the device is bound to usbip driver. Please remember you can not
+export a usb hub.
+
+   trois:# usbip_bind_driver --list
+   List USB devices
+   - busid 3-3.2 (04bb:0206)
+       3-3.2:1.0 -> usb-storage
+
+   - busid 3-3.1 (08bb:2702)
+       3-3.1:1.0 -> snd-usb-audio
+       3-3.1:1.1 -> snd-usb-audio
+
+   - busid 3-3 (0409:0058)
+       3-3:1.0 -> hub
+
+   - busid 3-2 (0711:0902)
+       3-2:1.0 -> none
+
+   - busid 1-1 (05a9:a511)
+       1-1:1.0 -> ov511
+
+   - busid 4-1 (046d:08b2)
+       4-1:1.0 -> none
+       4-1:1.1 -> none
+       4-1:1.2 -> none
+
+   - busid 5-2 (058f:9254)
+       5-2:1.0 -> hub
+
+--------------------------------------------------------------------------------------------------------
+Mark the device of busid 3-3.2 as exportable.
+
+   trois:# usbip_bind_driver --usbip 3-3.2
+   ** (process:24621): DEBUG:  3-3.2:1.0   -> none
+   ** (process:24621): DEBUG: write "add 3-3.2" to /sys/bus/usb/drivers/usbip/match_busid
+   ** Message: bind 3-3.2 to usbip, complete!
+
+   trois:# usbip_bind_driver --list
+   List USB devices
+   - busid 3-3.2 (04bb:0206)
+           3-3.2:1.0 -> usbip
+   (snip)
+
+Iterate the above operation for other devices if you like.
+
+
+--------------------------------------------------------------------------------------------------------
+- CLIENT SIDE ------------------------------------------------------------------------------------------
+--------------------------------------------------------------------------------------------------------
+First, let's list available remote devices which are marked as exportable in
+the server host.
+
+   deux:# insmod (somewhere)/usbip-core.ko
+   deux:# insmod (somewhere)/vhci_hcd.ko
+
+   deux:# usbip --list 10.0.0.3
+   - 10.0.0.3
+          1-1: Prolific Technology, Inc. : unknown product (067b:3507)
+             : /sys/devices/pci0000:00/0000:00:1f.2/usb1/1-1
+             : (Defined at Interface level) / unknown subclass / unknown protocol (00/00/00)
+             :  0 - Mass Storage / SCSI / Bulk (Zip) (08/06/50)
+
+      1-2.2.1: Apple Computer, Inc. : unknown product (05ac:0203)
+             : /sys/devices/pci0000:00/0000:00:1f.2/usb1/1-2/1-2.2/1-2.2.1
+             : (Defined at Interface level) / unknown subclass / unknown protocol (00/00/00)
+             :  0 - Human Interface Devices / Boot Interface Subclass / Keyboard (03/01/01)
+
+      1-2.2.3: OmniVision Technologies, Inc. : OV511+ WebCam (05a9:a511)
+             : /sys/devices/pci0000:00/0000:00:1f.2/usb1/1-2/1-2.2/1-2.2.3
+             : (Defined at Interface level) / unknown subclass / unknown protocol (00/00/00)
+             :  0 - Vendor Specific Class / unknown subclass / unknown protocol (ff/00/00)
+
+          3-1: Logitech, Inc. : QuickCam Pro 4000 (046d:08b2)
+             : /sys/devices/pci0000:00/0000:00:1e.0/0000:02:0a.0/usb3/3-1
+             : (Defined at Interface level) / unknown subclass / unknown protocol (00/00/00)
+             :  0 - Data / unknown subclass / unknown protocol (0a/ff/00)
+             :  1 - Audio / Control Device / unknown protocol (01/01/00)
+             :  2 - Audio / Streaming / unknown protocol (01/02/00)
+
+          4-1: Logitech, Inc. : QuickCam Express (046d:0870)
+             : /sys/devices/pci0000:00/0000:00:1e.0/0000:02:0a.1/usb4/4-1
+             : Vendor Specific Class / Vendor Specific Subclass / Vendor Specific Protocol (ff/ff/ff)
+             :  0 - Vendor Specific Class / Vendor Specific Subclass / Vendor Specific Protocol (ff/ff/ff)
+
+          4-2: Texas Instruments Japan : unknown product (08bb:2702)
+             : /sys/devices/pci0000:00/0000:00:1e.0/0000:02:0a.1/usb4/4-2
+             : (Defined at Interface level) / unknown subclass / unknown protocol (00/00/00)
+             :  0 - Audio / Control Device / unknown protocol (01/01/00)
+             :  1 - Audio / Streaming / unknown protocol (01/02/00)
+
+--------------------------------------------------------------------------------------------------------
+Attach a remote usb device!
+
+   deux:# usbip --attach 10.0.0.3 1-1
+   port 0 attached
+
+--------------------------------------------------------------------------------------------------------
+Show what devices are attached to this client.
+
+   deux:# usbip --port
+   Port 00: <Port in Use> at Full Speed(12Mbps)
+          Prolific Technology, Inc. : unknown product (067b:3507)
+          6-1 -> usbip://10.0.0.3:3240/1-1  (remote bus/dev 001/004)
+          6-1:1.0 used by usb-storage
+                         /sys/class/scsi_device/0:0:0:0/device
+                         /sys/class/scsi_host/host0/device
+                         /sys/block/sda/device
+
+--------------------------------------------------------------------------------------------------------
+Detach the imported device.
+
+   deux:# usbip --detach 0
+   port 0 detached
+
+--------------------------------------------------------------------------------------------------------
+
+
+[Check List]
+    - See Debug Tips in the project wiki.
+        - http://usbip.wiki.sourceforge.net/how-to-debug-usbip
+    - usbip-host.ko must be bound to the target device.
+        - See /proc/bus/usb/devices and find "Driver=..." lines of the device.
+    - Shutdown firewall.
+        - usbip now uses TCP port 3240.
+    - Disable SELinux.
+    - If possible, compile your kernel with CONFIG_USB_DEBUG flag and try
+      again.
+    - Check your kernel and daemon messages.
+        ex. /var/log/{messages, kern.log, daemon.log, syslog}
+
+
+[Contact]
+    Mailing List: usbip-devel _at_ lists.sourceforge.net
diff -druN linux-2.6.39-libre/drivers/staging/usbip/userspace/src/bind-driver.c linux-3.0-rc7-libre/drivers/staging/usbip/userspace/src/bind-driver.c
--- linux-2.6.39-libre/drivers/staging/usbip/userspace/src/bind-driver.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/staging/usbip/userspace/src/bind-driver.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,643 @@
+/*
+ *
+ * Copyright (C) 2005-2007 Takahiro Hirofuchi
+ */
+
+#include "utils.h"
+
+#define _GNU_SOURCE
+#include <getopt.h>
+#include <glib.h>
+
+
+
+static const struct option longopts[] = {
+	{"usbip",	required_argument,	NULL, 'u'},
+	{"other",	required_argument,	NULL, 'o'},
+	{"list",	no_argument,		NULL, 'l'},
+	{"list2",	no_argument,		NULL, 'L'},
+	{"help",	no_argument,		NULL, 'h'},
+#if 0
+	{"allusbip",	no_argument,		NULL, 'a'},
+	{"export-to",   required_argument,	NULL, 'e'},
+	{"unexport",    required_argument,	NULL, 'x'},
+	{"busid",	required_argument,	NULL, 'b'},
+#endif
+
+	{NULL,		0,			NULL,  0}
+};
+
+static const char match_busid_path[] = "/sys/bus/usb/drivers/usbip/match_busid";
+
+
+static void show_help(void)
+{
+	printf("Usage: usbip_bind_driver [OPTION]\n");
+	printf("Change driver binding for USB/IP.\n");
+	printf("  --usbip busid        make a device exportable\n");
+	printf("  --other busid        use a device by a local driver\n");
+	printf("  --list               print usb devices and their drivers\n");
+	printf("  --list2              print usb devices and their drivers in parseable mode\n");
+#if 0
+	printf("  --allusbip           make all devices exportable\n");
+	printf("  --export-to host     export the device to 'host'\n");
+	printf("  --unexport host      unexport a device previously exported to 'host'\n");
+	printf("  --busid busid        the busid used for --export-to\n");
+#endif
+}
+
+static int modify_match_busid(char *busid, int add)
+{
+	int fd;
+	int ret;
+	char buff[BUS_ID_SIZE + 4];
+
+	/* BUS_IS_SIZE includes NULL termination? */
+	if (strnlen(busid, BUS_ID_SIZE) > BUS_ID_SIZE - 1) {
+		g_warning("too long busid");
+		return -1;
+	}
+
+	fd = open(match_busid_path, O_WRONLY);
+	if (fd < 0)
+		return -1;
+
+	if (add)
+		snprintf(buff, BUS_ID_SIZE + 4, "add %s", busid);
+	else
+		snprintf(buff, BUS_ID_SIZE + 4, "del %s", busid);
+
+	g_debug("write \"%s\" to %s", buff, match_busid_path);
+
+	ret = write(fd, buff, sizeof(buff));
+	if (ret < 0) {
+		close(fd);
+		return -1;
+	}
+
+	close(fd);
+
+	return 0;
+}
+
+static const char unbind_path_format[] = "/sys/bus/usb/devices/%s/driver/unbind";
+
+/* buggy driver may cause dead lock */
+static int unbind_interface_busid(char *busid)
+{
+	char unbind_path[PATH_MAX];
+	int fd;
+	int ret;
+
+	snprintf(unbind_path, sizeof(unbind_path), unbind_path_format, busid);
+
+	fd = open(unbind_path, O_WRONLY);
+	if (fd < 0) {
+		g_warning("opening unbind_path failed: %d", fd);
+		return -1;
+	}
+
+	ret = write(fd, busid, strnlen(busid, BUS_ID_SIZE));
+	if (ret < 0) {
+		g_warning("write to unbind_path failed: %d", ret);
+		close(fd);
+		return -1;
+	}
+
+	close(fd);
+
+	return 0;
+}
+
+static int unbind_interface(char *busid, int configvalue, int interface)
+{
+	char inf_busid[BUS_ID_SIZE];
+	g_debug("unbinding interface");
+
+	snprintf(inf_busid, BUS_ID_SIZE, "%s:%d.%d", busid, configvalue, interface);
+
+	return unbind_interface_busid(inf_busid);
+}
+
+
+static const char bind_path_format[] = "/sys/bus/usb/drivers/%s/bind";
+
+static int bind_interface_busid(char *busid, char *driver)
+{
+	char bind_path[PATH_MAX];
+	int fd;
+	int ret;
+
+	snprintf(bind_path, sizeof(bind_path), bind_path_format, driver);
+
+	fd = open(bind_path, O_WRONLY);
+	if (fd < 0)
+		return -1;
+
+	ret = write(fd, busid, strnlen(busid, BUS_ID_SIZE));
+	if (ret < 0) {
+		close(fd);
+		return -1;
+	}
+
+	close(fd);
+
+	return 0;
+}
+
+static int bind_interface(char *busid, int configvalue, int interface, char *driver)
+{
+	char inf_busid[BUS_ID_SIZE];
+
+	snprintf(inf_busid, BUS_ID_SIZE, "%s:%d.%d", busid, configvalue, interface);
+
+	return bind_interface_busid(inf_busid, driver);
+}
+
+static int unbind(char *busid)
+{
+	int configvalue = 0;
+	int ninterface = 0;
+	int devclass = 0;
+	int i;
+	int failed = 0;
+
+	configvalue = read_bConfigurationValue(busid);
+	ninterface  = read_bNumInterfaces(busid);
+	devclass  = read_bDeviceClass(busid);
+
+	if (configvalue < 0 || ninterface < 0 || devclass < 0) {
+		g_warning("read config and ninf value, removed?");
+		return -1;
+	}
+
+	if (devclass == 0x09) {
+		g_message("skip unbinding of hub");
+		return -1;
+	}
+
+	for (i = 0; i < ninterface; i++) {
+		char driver[PATH_MAX];
+		int ret;
+
+		bzero(&driver, sizeof(driver));
+
+		getdriver(busid, configvalue, i, driver, PATH_MAX-1);
+
+		g_debug(" %s:%d.%d	-> %s ", busid, configvalue, i, driver);
+
+		if (!strncmp("none", driver, PATH_MAX))
+			continue; /* unbound interface */
+
+#if 0
+		if (!strncmp("usbip", driver, PATH_MAX))
+			continue; /* already bound to usbip */
+#endif
+
+		/* unbinding */
+		ret = unbind_interface(busid, configvalue, i);
+		if (ret < 0) {
+			g_warning("unbind driver at %s:%d.%d failed",
+					busid, configvalue, i);
+			failed = 1;
+		}
+	}
+
+	if (failed)
+		return -1;
+	else
+		return 0;
+}
+
+/* call at unbound state */
+static int bind_to_usbip(char *busid)
+{
+	int configvalue = 0;
+	int ninterface = 0;
+	int i;
+	int failed = 0;
+
+	configvalue = read_bConfigurationValue(busid);
+	ninterface  = read_bNumInterfaces(busid);
+
+	if (configvalue < 0 || ninterface < 0) {
+		g_warning("read config and ninf value, removed?");
+		return -1;
+	}
+
+	for (i = 0; i < ninterface; i++) {
+		int ret;
+
+		ret = bind_interface(busid, configvalue, i, "usbip");
+		if (ret < 0) {
+			g_warning("bind usbip at %s:%d.%d, failed",
+					busid, configvalue, i);
+			failed = 1;
+			/* need to contine binding at other interfaces */
+		}
+	}
+
+	if (failed)
+		return -1;
+	else
+		return 0;
+}
+
+
+static int use_device_by_usbip(char *busid)
+{
+	int ret;
+
+	ret = unbind(busid);
+	if (ret < 0) {
+		g_warning("unbind drivers of %s, failed", busid);
+		return -1;
+	}
+
+	ret = modify_match_busid(busid, 1);
+	if (ret < 0) {
+		g_warning("add %s to match_busid, failed", busid);
+		return -1;
+	}
+
+	ret = bind_to_usbip(busid);
+	if (ret < 0) {
+		g_warning("bind usbip to %s, failed", busid);
+		modify_match_busid(busid, 0);
+		return -1;
+	}
+
+	g_message("bind %s to usbip, complete!", busid);
+
+	return 0;
+}
+
+
+
+static int use_device_by_other(char *busid)
+{
+	int ret;
+	int config;
+
+	/* read and write the same config value to kick probing */
+	config = read_bConfigurationValue(busid);
+	if (config < 0) {
+		g_warning("read bConfigurationValue of %s, failed", busid);
+		return -1;
+	}
+
+	ret = modify_match_busid(busid, 0);
+	if (ret < 0) {
+		g_warning("del %s to match_busid, failed", busid);
+		return -1;
+	}
+
+	ret = write_bConfigurationValue(busid, config);
+	if (ret < 0) {
+		g_warning("read bConfigurationValue of %s, failed", busid);
+		return -1;
+	}
+
+	g_message("bind %s to other drivers than usbip, complete!", busid);
+
+	return 0;
+}
+
+
+#include <sys/types.h>
+#include <regex.h>
+
+#include <errno.h>
+#include <string.h>
+#include <stdio.h>
+
+
+
+static int is_usb_device(char *busid)
+{
+	int ret;
+
+	regex_t regex;
+	regmatch_t pmatch[1];
+
+	ret = regcomp(&regex, "^[0-9]+-[0-9]+(\\.[0-9]+)*$", REG_NOSUB|REG_EXTENDED);
+	if (ret < 0)
+		g_error("regcomp: %s\n", strerror(errno));
+
+	ret = regexec(&regex, busid, 0, pmatch, 0);
+	if (ret)
+		return 0;	/* not matched */
+
+	return 1;
+}
+
+
+#include <dirent.h>
+static int show_devices(void)
+{
+	DIR *dir;
+
+	dir = opendir("/sys/bus/usb/devices/");
+	if (!dir)
+		g_error("opendir: %s", strerror(errno));
+
+	printf("List USB devices\n");
+	for (;;) {
+		struct dirent *dirent;
+		char *busid;
+
+		dirent = readdir(dir);
+		if (!dirent)
+			break;
+
+		busid = dirent->d_name;
+
+		if (is_usb_device(busid)) {
+			char name[100] = {'\0'};
+			char driver[100] =  {'\0'};
+			int conf, ninf = 0;
+			int i;
+
+			conf = read_bConfigurationValue(busid);
+			ninf = read_bNumInterfaces(busid);
+
+			getdevicename(busid, name, sizeof(name));
+
+			printf(" - busid %s (%s)\n", busid, name);
+
+			for (i = 0; i < ninf; i++) {
+				getdriver(busid, conf, i, driver, sizeof(driver));
+				printf("         %s:%d.%d -> %s\n", busid, conf, i, driver);
+			}
+			printf("\n");
+		}
+	}
+
+	closedir(dir);
+
+	return 0;
+}
+
+static int show_devices2(void)
+{
+	DIR *dir;
+
+	dir = opendir("/sys/bus/usb/devices/");
+	if (!dir)
+		g_error("opendir: %s", strerror(errno));
+
+	for (;;) {
+		struct dirent *dirent;
+		char *busid;
+
+		dirent = readdir(dir);
+		if (!dirent)
+			break;
+
+		busid = dirent->d_name;
+
+		if (is_usb_device(busid)) {
+			char name[100] = {'\0'};
+			char driver[100] =  {'\0'};
+			int conf, ninf = 0;
+			int i;
+
+			conf = read_bConfigurationValue(busid);
+			ninf = read_bNumInterfaces(busid);
+
+			getdevicename(busid, name, sizeof(name));
+
+			printf("busid=%s#usbid=%s#", busid, name);
+
+			for (i = 0; i < ninf; i++) {
+				getdriver(busid, conf, i, driver, sizeof(driver));
+				printf("%s:%d.%d=%s#", busid, conf, i, driver);
+			}
+			printf("\n");
+		}
+	}
+
+	closedir(dir);
+
+	return 0;
+}
+
+
+#if 0
+static int export_to(char *host, char *busid) {
+
+	int ret;
+
+	if( host == NULL ) {
+		printf( "no host given\n\n");
+		show_help();
+		return -1;
+	}
+	if( busid == NULL ) {
+		/* XXX print device list and ask for busnumber, if none is
+		 * given */
+		printf( "no busid given, use --busid switch\n\n");
+		show_help();
+		return -1;
+	}
+
+
+	ret = use_device_by_usbip(busid);
+	if( ret != 0 ) {
+		printf( "could not bind driver to usbip\n");
+		return -1;
+	}
+
+	printf( "DEBUG: exporting device '%s' to '%s'\n", busid, host );
+	ret = export_busid_to_host(host, busid); /* usbip_export.[ch] */
+	if( ret != 0 ) {
+		printf( "could not export device to host\n" );
+		printf( "   host: %s, device: %s\n", host, busid );
+		use_device_by_other(busid);
+		return -1;
+	}
+
+	return 0;
+}
+
+static int unexport_from(char *host, char *busid) {
+
+	int ret;
+
+	if (!host || !busid)
+		g_error("no host or no busid\n");
+
+	g_message("unexport_from: host: '%s', busid: '%s'", host, busid);
+
+	ret = unexport_busid_from_host(host, busid); /* usbip_export.[ch] */
+	if( ret != 0 ) {
+		err( "could not unexport device from host\n" );
+		err( "   host: %s, device: %s\n", host, busid );
+	}
+
+	ret = use_device_by_other(busid);
+	if (ret < 0)
+		g_error("could not unbind device from usbip\n");
+
+	return 0;
+}
+
+
+static int allusbip(void)
+{
+	DIR *dir;
+
+	dir = opendir("/sys/bus/usb/devices/");
+	if (!dir)
+		g_error("opendir: %s", strerror(errno));
+
+	for (;;) {
+		struct dirent *dirent;
+		char *busid;
+
+		dirent = readdir(dir);
+		if (!dirent)
+			break;
+
+		busid = dirent->d_name;
+
+		if (!is_usb_device(busid))
+			continue;
+
+		{
+			char name[PATH_MAX];
+			int conf, ninf = 0;
+			int i;
+			int be_local = 0;
+
+			conf = read_bConfigurationValue(busid);
+			ninf = read_bNumInterfaces(busid);
+
+			getdevicename(busid, name, sizeof(name));
+
+			for (i = 0; i < ninf; i++) {
+				char driver[PATH_MAX];
+
+				getdriver(busid, conf, i, driver, sizeof(driver));
+#if 0
+				if (strncmp(driver, "usbhid", 6) == 0 || strncmp(driver, "usb-storage", 11) == 0) {
+					be_local = 1;
+					break;
+				}
+#endif
+			}
+
+			if (be_local == 0)
+				use_device_by_usbip(busid);
+		}
+	}
+
+	closedir(dir);
+
+	return 0;
+}
+#endif
+
+int main(int argc, char **argv)
+{
+	char *busid = NULL;
+	char *remote_host __attribute__((unused)) = NULL;
+
+	enum {
+		cmd_unknown = 0,
+		cmd_use_by_usbip,
+		cmd_use_by_other,
+		cmd_list,
+		cmd_list2,
+		cmd_allusbip,
+		cmd_export_to,
+		cmd_unexport,
+		cmd_help,
+	} cmd = cmd_unknown;
+
+	if (geteuid() != 0)
+		g_warning("running non-root?");
+
+	for (;;) {
+		int c;
+		int index = 0;
+
+		c = getopt_long(argc, argv, "u:o:hlLae:x:b:", longopts, &index);
+		if (c == -1)
+			break;
+
+		switch (c) {
+			case 'u':
+				cmd = cmd_use_by_usbip;
+				busid = optarg;
+				break;
+			case 'o' :
+				cmd = cmd_use_by_other;
+				busid = optarg;
+				break;
+			case 'l' :
+				cmd = cmd_list;
+				break;
+			case 'L' :
+				cmd = cmd_list2;
+				break;
+			case 'a' :
+				cmd = cmd_allusbip;
+				break;
+			case 'b':
+				busid = optarg;
+				break;
+			case 'e':
+				cmd = cmd_export_to;
+				remote_host = optarg;
+				break;
+			case 'x':
+				cmd = cmd_unexport;
+				remote_host = optarg;
+				break;
+			case 'h': /* fallthrough */
+			case '?':
+				cmd = cmd_help;
+				break;
+			default:
+				g_error("getopt");
+		}
+
+		//if (cmd)
+		//	break;
+	}
+
+	switch (cmd) {
+		case cmd_use_by_usbip:
+			use_device_by_usbip(busid);
+			break;
+		case cmd_use_by_other:
+			use_device_by_other(busid);
+			break;
+		case cmd_list:
+			show_devices();
+			break;
+		case cmd_list2:
+			show_devices2();
+			break;
+#if 0
+		case cmd_allusbip:
+			allusbip();
+			break;
+		case cmd_export_to:
+			export_to(remote_host, busid);
+			break;
+		case cmd_unexport:
+			unexport_from(remote_host, busid);
+			break;
+#endif
+		case cmd_help: /* fallthrough */
+		case cmd_unknown:
+			show_help();
+			break;
+		default:
+			g_error("NOT REACHED");
+	}
+
+	return 0;
+}
diff -druN linux-2.6.39-libre/drivers/staging/usbip/userspace/src/Makefile.am linux-3.0-rc7-libre/drivers/staging/usbip/userspace/src/Makefile.am
--- linux-2.6.39-libre/drivers/staging/usbip/userspace/src/Makefile.am	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/staging/usbip/userspace/src/Makefile.am	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,10 @@
+AM_CPPFLAGS := -I$(top_srcdir)/libsrc -DUSBIDS_FILE='"@USBIDS_DIR@/usb.ids"'
+AM_CFLAGS   := @EXTRA_CFLAGS@ @PACKAGE_CFLAGS@
+LDADD       := $(top_srcdir)/libsrc/libusbip.la @PACKAGE_LIBS@
+
+sbin_PROGRAMS := usbip usbipd usbip_bind_driver
+
+usbip_SOURCES := usbip.c usbip_network.c usbip_network.h
+usbipd_SOURCES := usbipd.c usbip_network.c usbip_network.h
+usbip_bind_driver_SOURCES := bind-driver.c utils.c utils.h \
+			     usbip_network.h usbip_network.c
diff -druN linux-2.6.39-libre/drivers/staging/usbip/userspace/src/usbip.c linux-3.0-rc7-libre/drivers/staging/usbip/userspace/src/usbip.c
--- linux-2.6.39-libre/drivers/staging/usbip/userspace/src/usbip.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/staging/usbip/userspace/src/usbip.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,723 @@
+/*
+ *
+ * Copyright (C) 2005-2007 Takahiro Hirofuchi
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "../config.h"
+#endif
+
+#include "usbip.h"
+#include "usbip_network.h"
+#include <ctype.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <glib.h>
+
+static const char version[] = PACKAGE_STRING;
+
+
+/* /sys/devices/platform/vhci_hcd/usb6/6-1/6-1:1.1  -> 1 */
+static int get_interface_number(char *path)
+{
+	char *c;
+
+	c = strstr(path, vhci_driver->hc_device->bus_id);
+	if (!c)
+		return -1;	/* hc exist? */
+	c++;
+	/* -> usb6/6-1/6-1:1.1 */
+
+	c = strchr(c, '/');
+	if (!c)
+		return -1;	/* hc exist? */
+	c++;
+	/* -> 6-1/6-1:1.1 */
+
+	c = strchr(c, '/');
+	if (!c)
+		return -1;	/* no interface path */
+	c++;
+	/* -> 6-1:1.1 */
+
+	c = strchr(c, ':');
+	if (!c)
+		return -1;	/* no configuration? */
+	c++;
+	/* -> 1.1 */
+
+	c = strchr(c, '.');
+	if (!c)
+		return -1;	/* no interface? */
+	c++;
+	/* -> 1 */
+
+
+	return atoi(c);
+}
+
+
+static struct sysfs_device *open_usb_interface(struct usb_device *udev, int i)
+{
+	struct sysfs_device *suinf;
+	char busid[SYSFS_BUS_ID_SIZE];
+
+	snprintf(busid, SYSFS_BUS_ID_SIZE, "%s:%d.%d",
+			udev->busid, udev->bConfigurationValue, i);
+
+	suinf = sysfs_open_device("usb", busid);
+	if (!suinf)
+		err("sysfs_open_device %s", busid);
+
+	return suinf;
+}
+
+
+#define MAX_BUFF 100
+static int record_connection(char *host, char *port, char *busid, int rhport)
+{
+	int fd;
+	char path[PATH_MAX+1];
+	char buff[MAX_BUFF+1];
+	int ret;
+
+	mkdir(VHCI_STATE_PATH, 0700);
+
+	snprintf(path, PATH_MAX, VHCI_STATE_PATH"/port%d", rhport);
+
+	fd = open(path, O_WRONLY|O_CREAT|O_TRUNC, S_IRWXU);
+	if (fd < 0)
+		return -1;
+
+	snprintf(buff, MAX_BUFF, "%s %s %s\n",
+			host, port, busid);
+
+	ret = write(fd, buff, strlen(buff));
+	if (ret != (ssize_t) strlen(buff)) {
+		close(fd);
+		return -1;
+	}
+
+	close(fd);
+
+	return 0;
+}
+
+static int read_record(int rhport, char *host, char *port, char *busid)
+{
+	FILE *file;
+	char path[PATH_MAX+1];
+
+	snprintf(path, PATH_MAX, VHCI_STATE_PATH"/port%d", rhport);
+
+	file = fopen(path, "r");
+	if (!file) {
+		err("fopen");
+		return -1;
+	}
+
+	if (fscanf(file, "%s %s %s\n", host, port, busid) != 3) {
+		err("fscanf");
+		fclose(file);
+		return -1;
+	}
+
+	fclose(file);
+
+	return 0;
+}
+
+
+int usbip_vhci_imported_device_dump(struct usbip_imported_device *idev)
+{
+	char product_name[100];
+	char host[NI_MAXHOST] = "unknown host";
+	char serv[NI_MAXSERV] = "unknown port";
+	char remote_busid[SYSFS_BUS_ID_SIZE];
+	int ret;
+
+	if (idev->status == VDEV_ST_NULL || idev->status == VDEV_ST_NOTASSIGNED) {
+		info("Port %02d: <%s>", idev->port, usbip_status_string(idev->status));
+		return 0;
+	}
+
+	ret = read_record(idev->port, host, serv, remote_busid);
+	if (ret) {
+		err("read_record");
+		return -1;
+	}
+
+	info("Port %02d: <%s> at %s", idev->port,
+			usbip_status_string(idev->status), usbip_speed_string(idev->udev.speed));
+
+	usbip_names_get_product(product_name, sizeof(product_name),
+			idev->udev.idVendor, idev->udev.idProduct);
+
+	info("       %s",  product_name);
+
+	info("%10s -> usbip://%s:%s/%s  (remote devid %08x (bus/dev %03d/%03d))",
+			idev->udev.busid, host, serv, remote_busid,
+			idev->devid,
+			idev->busnum, idev->devnum);
+
+	for (int i=0; i < idev->udev.bNumInterfaces; i++) {
+		/* show interface information */
+		struct sysfs_device *suinf;
+
+		suinf = open_usb_interface(&idev->udev, i);
+		if (!suinf)
+			continue;
+
+		info("       %6s used by %-17s", suinf->bus_id, suinf->driver_name);
+		sysfs_close_device(suinf);
+
+		/* show class device information */
+		struct class_device *cdev;
+
+		dlist_for_each_data(idev->cdev_list, cdev, struct class_device) {
+			int ifnum = get_interface_number(cdev->devpath);
+			if (ifnum == i) {
+				info("           %s", cdev->clspath);
+			}
+		}
+	}
+
+	return 0;
+}
+
+
+
+
+static int query_exported_devices(int sockfd)
+{
+	int ret;
+	struct op_devlist_reply rep;
+	uint16_t code = OP_REP_DEVLIST;
+
+	bzero(&rep, sizeof(rep));
+
+	ret = usbip_send_op_common(sockfd, OP_REQ_DEVLIST, 0);
+	if (ret < 0) {
+		err("send op_common");
+		return -1;
+	}
+
+	ret = usbip_recv_op_common(sockfd, &code);
+	if (ret < 0) {
+		err("recv op_common");
+		return -1;
+	}
+
+	ret = usbip_recv(sockfd, (void *) &rep, sizeof(rep));
+	if (ret < 0) {
+		err("recv op_devlist");
+		return -1;
+	}
+
+	PACK_OP_DEVLIST_REPLY(0, &rep);
+	dbg("exportable %d devices", rep.ndev);
+
+	for (unsigned int i=0; i < rep.ndev; i++) {
+		char product_name[100];
+		char class_name[100];
+		struct usb_device udev;
+
+		bzero(&udev, sizeof(udev));
+
+		ret = usbip_recv(sockfd, (void *) &udev, sizeof(udev));
+		if (ret < 0) {
+			err("recv usb_device[%d]", i);
+			return -1;
+		}
+		pack_usb_device(0, &udev);
+
+		usbip_names_get_product(product_name, sizeof(product_name),
+				udev.idVendor, udev.idProduct);
+		usbip_names_get_class(class_name, sizeof(class_name), udev.bDeviceClass,
+				udev.bDeviceSubClass, udev.bDeviceProtocol);
+
+		info("%8s: %s", udev.busid, product_name);
+		info("%8s: %s", " ", udev.path);
+		info("%8s: %s", " ", class_name);
+
+		for (int j=0; j < udev.bNumInterfaces; j++) {
+			struct usb_interface uinf;
+
+			ret = usbip_recv(sockfd, (void *) &uinf, sizeof(uinf));
+			if (ret < 0) {
+				err("recv usb_interface[%d]", j);
+				return -1;
+			}
+
+			pack_usb_interface(0, &uinf);
+			usbip_names_get_class(class_name, sizeof(class_name), uinf.bInterfaceClass,
+					uinf.bInterfaceSubClass, uinf.bInterfaceProtocol);
+
+			info("%8s: %2d - %s", " ", j, class_name);
+		}
+
+		info(" ");
+	}
+
+	return rep.ndev;
+}
+
+static int import_device(int sockfd, struct usb_device *udev)
+{
+	int ret;
+	int port;
+
+	ret = usbip_vhci_driver_open();
+	if (ret < 0) {
+		err("open vhci_driver");
+		return -1;
+	}
+
+	port = usbip_vhci_get_free_port();
+	if (port < 0) {
+		err("no free port");
+		usbip_vhci_driver_close();
+		return -1;
+	}
+
+	ret = usbip_vhci_attach_device(port, sockfd, udev->busnum,
+			udev->devnum, udev->speed);
+	if (ret < 0) {
+		err("import device");
+		usbip_vhci_driver_close();
+		return -1;
+	}
+
+	usbip_vhci_driver_close();
+
+	return port;
+}
+
+
+static int query_import_device(int sockfd, char *busid)
+{
+	int ret;
+	struct op_import_request request;
+	struct op_import_reply   reply;
+	uint16_t code = OP_REP_IMPORT;
+
+	bzero(&request, sizeof(request));
+	bzero(&reply, sizeof(reply));
+
+
+	/* send a request */
+	ret = usbip_send_op_common(sockfd, OP_REQ_IMPORT, 0);
+	if (ret < 0) {
+		err("send op_common");
+		return -1;
+	}
+
+	strncpy(request.busid, busid, SYSFS_BUS_ID_SIZE-1);
+
+	PACK_OP_IMPORT_REQUEST(0, &request);
+
+	ret = usbip_send(sockfd, (void *) &request, sizeof(request));
+	if (ret < 0) {
+		err("send op_import_request");
+		return -1;
+	}
+
+
+	/* recieve a reply */
+	ret = usbip_recv_op_common(sockfd, &code);
+	if (ret < 0) {
+		err("recv op_common");
+		return -1;
+	}
+
+	ret = usbip_recv(sockfd, (void *) &reply, sizeof(reply));
+	if (ret < 0) {
+		err("recv op_import_reply");
+		return -1;
+	}
+
+	PACK_OP_IMPORT_REPLY(0, &reply);
+
+
+	/* check the reply */
+	if (strncmp(reply.udev.busid, busid, SYSFS_BUS_ID_SIZE)) {
+		err("recv different busid %s", reply.udev.busid);
+		return -1;
+	}
+
+
+	/* import a device */
+	return import_device(sockfd, &reply.udev);
+}
+
+static int attach_device(char *host, char *busid)
+{
+	int sockfd;
+	int ret;
+	int rhport;
+
+	sockfd = tcp_connect(host, USBIP_PORT_STRING);
+	if (sockfd < 0) {
+		err("tcp connect");
+		return -1;
+	}
+
+	rhport = query_import_device(sockfd, busid);
+	if (rhport < 0) {
+		err("query");
+		return -1;
+	}
+
+	close(sockfd);
+
+	ret = record_connection(host, USBIP_PORT_STRING,
+			busid, rhport);
+	if (ret < 0) {
+		err("record connection");
+		return -1;
+	}
+
+	return 0;
+}
+
+static int detach_port(char *port)
+{
+	int ret;
+	uint8_t portnum;
+
+	for (unsigned int i=0; i < strlen(port); i++)
+		if (!isdigit(port[i])) {
+			err("invalid port %s", port);
+			return -1;
+		}
+
+	/* check max port */
+
+	portnum = atoi(port);
+
+	ret = usbip_vhci_driver_open();
+	if (ret < 0) {
+		err("open vhci_driver");
+		return -1;
+	}
+
+	ret = usbip_vhci_detach_device(portnum);
+	if (ret < 0)
+		return -1;
+
+	usbip_vhci_driver_close();
+
+	return ret;
+}
+
+static int show_exported_devices(char *host)
+{
+	int ret;
+	int sockfd;
+
+	sockfd = tcp_connect(host, USBIP_PORT_STRING);
+	if (sockfd < 0) {
+		err("- %s failed", host);
+		return -1;
+	}
+
+	info("- %s", host);
+
+	ret = query_exported_devices(sockfd);
+	if (ret < 0) {
+		err("query");
+		return -1;
+	}
+
+	close(sockfd);
+	return 0;
+}
+
+static int attach_exported_devices(char *host, int sockfd)
+{
+	int ret;
+	struct op_devlist_reply rep;
+	uint16_t code = OP_REP_DEVLIST;
+
+	bzero(&rep, sizeof(rep));
+
+	ret = usbip_send_op_common(sockfd, OP_REQ_DEVLIST, 0);
+	if(ret < 0) {
+		err("send op_common");
+		return -1;
+	}
+
+	ret = usbip_recv_op_common(sockfd, &code);
+	if(ret < 0) {
+		err("recv op_common");
+		return -1;
+	}
+
+	ret = usbip_recv(sockfd, (void *) &rep, sizeof(rep));
+	if(ret < 0) {
+		err("recv op_devlist");
+		return -1;
+	}
+
+	PACK_OP_DEVLIST_REPLY(0, &rep);
+	dbg("exportable %d devices", rep.ndev);
+
+	for(unsigned int i=0; i < rep.ndev; i++) {
+		char product_name[100];
+		char class_name[100];
+		struct usb_device udev;
+
+		bzero(&udev, sizeof(udev));
+
+		ret = usbip_recv(sockfd, (void *) &udev, sizeof(udev));
+		if(ret < 0) {
+			err("recv usb_device[%d]", i);
+			return -1;
+		}
+		pack_usb_device(0, &udev);
+
+		usbip_names_get_product(product_name, sizeof(product_name),
+				udev.idVendor, udev.idProduct);
+		usbip_names_get_class(class_name, sizeof(class_name), udev.bDeviceClass,
+				udev.bDeviceSubClass, udev.bDeviceProtocol);
+
+		dbg("Attaching usb port %s from host %s on usbip, with deviceid: %s", udev.busid, host, product_name);
+
+		for (int j=0; j < udev.bNumInterfaces; j++) {
+			struct usb_interface uinf;
+
+			ret = usbip_recv(sockfd, (void *) &uinf, sizeof(uinf));
+			if (ret < 0) {
+				err("recv usb_interface[%d]", j);
+				return -1;
+			}
+
+			pack_usb_interface(0, &uinf);
+			usbip_names_get_class(class_name, sizeof(class_name), uinf.bInterfaceClass,
+					uinf.bInterfaceSubClass, uinf.bInterfaceProtocol);
+
+			dbg("interface %2d - %s", j, class_name);
+		}
+
+		attach_device(host, udev.busid);
+	}
+
+	return rep.ndev;
+}
+
+static int attach_devices_all(char *host)
+{
+	int ret;
+	int sockfd;
+
+	sockfd = tcp_connect(host, USBIP_PORT_STRING);
+	if(sockfd < 0) {
+		err("- %s failed", host);
+		return -1;
+	}
+
+	info("- %s", host);
+
+	ret = attach_exported_devices(host, sockfd);
+	if(ret < 0) {
+		err("query");
+		return -1;
+	}
+
+	close(sockfd);
+	return 0;
+}
+
+
+const char help_message[] = "\
+Usage: usbip [options]				\n\
+	-a, --attach [host] [bus_id]		\n\
+		Attach a remote USB device.	\n\
+						\n\
+	-x, --attachall [host]		\n\
+		Attach all remote USB devices on the specific host.	\n\
+						\n\
+	-d, --detach [ports]			\n\
+		Detach an imported USB device.	\n\
+						\n\
+	-l, --list [hosts]			\n\
+		List exported USB devices.	\n\
+						\n\
+	-p, --port				\n\
+		List virtual USB port status. 	\n\
+						\n\
+	-D, --debug				\n\
+		Print debugging information.	\n\
+						\n\
+	-v, --version				\n\
+		Show version.			\n\
+						\n\
+	-h, --help 				\n\
+		Print this help.		\n";
+
+static void show_help(void)
+{
+	printf("%s", help_message);
+}
+
+static int show_port_status(void)
+{
+	int ret;
+	struct usbip_imported_device *idev;
+
+	ret = usbip_vhci_driver_open();
+	if (ret < 0)
+		return ret;
+
+	for (int i = 0; i < vhci_driver->nports; i++) {
+		idev = &vhci_driver->idev[i];
+
+		if (usbip_vhci_imported_device_dump(idev) < 0)
+			ret = -1;
+	}
+
+	usbip_vhci_driver_close();
+
+	return ret;
+}
+
+#define _GNU_SOURCE
+#include <getopt.h>
+static const struct option longopts[] = {
+	{"attach",	no_argument,	NULL, 'a'},
+	{"attachall",	no_argument,	NULL, 'x'},
+	{"detach",	no_argument,	NULL, 'd'},
+	{"port",	no_argument,	NULL, 'p'},
+	{"list",	no_argument,	NULL, 'l'},
+	{"version",	no_argument,	NULL, 'v'},
+	{"help",	no_argument,	NULL, 'h'},
+	{"debug",	no_argument,	NULL, 'D'},
+	{"syslog",	no_argument,	NULL, 'S'},
+	{NULL,		0,		NULL,  0}
+};
+
+int main(int argc, char *argv[])
+{
+	int ret;
+
+	enum {
+		cmd_attach = 1,
+		cmd_attachall,
+		cmd_detach,
+		cmd_port,
+		cmd_list,
+		cmd_help,
+		cmd_version
+	} cmd = 0;
+
+	usbip_use_stderr = 1;
+
+	if (geteuid() != 0)
+		g_warning("running non-root?");
+
+	ret = usbip_names_init(USBIDS_FILE);
+	if (ret)
+		notice("failed to open %s", USBIDS_FILE);
+
+	for (;;) {
+		int c;
+		int index = 0;
+
+		c = getopt_long(argc, argv, "adplvhDSx", longopts, &index);
+
+		if (c == -1)
+			break;
+
+		switch(c) {
+			case 'a':
+				if (!cmd)
+					cmd = cmd_attach;
+				else
+					cmd = cmd_help;
+				break;
+			case 'd':
+				if (!cmd)
+					cmd = cmd_detach;
+				else
+					cmd = cmd_help;
+				break;
+			case 'p':
+				if (!cmd)
+					cmd = cmd_port;
+				else cmd = cmd_help;
+				break;
+			case 'l':
+				if (!cmd)
+					cmd = cmd_list;
+				else
+					cmd = cmd_help;
+				break;
+			case 'v':
+				if (!cmd)
+					cmd = cmd_version;
+				else
+					cmd = cmd_help;
+				break;
+			case 'x':
+				if(!cmd)
+					cmd = cmd_attachall;
+				else
+					cmd = cmd_help;
+				break;
+			case 'h':
+				cmd = cmd_help;
+				break;
+			case 'D':
+				usbip_use_debug = 1;
+				break;
+			case 'S':
+				usbip_use_syslog = 1;
+				break;
+			case '?':
+				break;
+
+			default:
+				err("getopt");
+		}
+	}
+
+	ret = 0;
+	switch(cmd) {
+		case cmd_attach:
+			if (optind == argc - 2)
+				ret = attach_device(argv[optind], argv[optind+1]);
+			else
+				show_help();
+			break;
+		case cmd_detach:
+			while (optind < argc)
+				ret = detach_port(argv[optind++]);
+			break;
+		case cmd_port:
+			ret = show_port_status();
+			break;
+		case cmd_list:
+			while (optind < argc)
+				ret = show_exported_devices(argv[optind++]);
+			break;
+		case cmd_attachall:
+			while(optind < argc)
+				ret = attach_devices_all(argv[optind++]);
+			break;
+		case cmd_version:
+			printf("%s\n", version);
+			break;
+		case cmd_help:
+			show_help();
+			break;
+		default:
+			show_help();
+	}
+
+
+	usbip_names_free();
+
+	exit((ret == 0) ? EXIT_SUCCESS : EXIT_FAILURE);
+}
diff -druN linux-2.6.39-libre/drivers/staging/usbip/userspace/src/usbipd.c linux-3.0-rc7-libre/drivers/staging/usbip/userspace/src/usbipd.c
--- linux-2.6.39-libre/drivers/staging/usbip/userspace/src/usbipd.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/staging/usbip/userspace/src/usbipd.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,570 @@
+/*
+ *
+ * Copyright (C) 2005-2007 Takahiro Hirofuchi
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "../config.h"
+#endif
+
+#include <unistd.h>
+#include <netdb.h>
+#include <strings.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <arpa/inet.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+
+#ifdef HAVE_LIBWRAP
+#include <tcpd.h>
+#endif
+
+#define _GNU_SOURCE
+#include <getopt.h>
+#include <signal.h>
+
+#include "usbip.h"
+#include "usbip_network.h"
+
+#include <glib.h>
+
+static const char version[] = PACKAGE_STRING;
+
+
+static int send_reply_devlist(int sockfd)
+{
+	int ret;
+	struct usbip_exported_device *edev;
+	struct op_devlist_reply reply;
+
+
+	reply.ndev = 0;
+
+	/* how many devices are exported ? */
+	dlist_for_each_data(stub_driver->edev_list, edev, struct usbip_exported_device) {
+		reply.ndev += 1;
+	}
+
+	dbg("%d devices are exported", reply.ndev);
+
+	ret = usbip_send_op_common(sockfd, OP_REP_DEVLIST,  ST_OK);
+	if (ret < 0) {
+		err("send op_common");
+		return ret;
+	}
+
+	PACK_OP_DEVLIST_REPLY(1, &reply);
+
+	ret = usbip_send(sockfd, (void *) &reply, sizeof(reply));
+	if (ret < 0) {
+		err("send op_devlist_reply");
+		return ret;
+	}
+
+	dlist_for_each_data(stub_driver->edev_list, edev, struct usbip_exported_device) {
+		struct usb_device pdu_udev;
+
+		dump_usb_device(&edev->udev);
+		memcpy(&pdu_udev, &edev->udev, sizeof(pdu_udev));
+		pack_usb_device(1, &pdu_udev);
+
+		ret = usbip_send(sockfd, (void *) &pdu_udev, sizeof(pdu_udev));
+		if (ret < 0) {
+			err("send pdu_udev");
+			return ret;
+		}
+
+		for (int i=0; i < edev->udev.bNumInterfaces; i++) {
+			struct usb_interface pdu_uinf;
+
+			dump_usb_interface(&edev->uinf[i]);
+			memcpy(&pdu_uinf, &edev->uinf[i], sizeof(pdu_uinf));
+			pack_usb_interface(1, &pdu_uinf);
+
+			ret = usbip_send(sockfd, (void *) &pdu_uinf, sizeof(pdu_uinf));
+			if (ret < 0) {
+				err("send pdu_uinf");
+				return ret;
+			}
+		}
+	}
+
+	return 0;
+}
+
+
+static int recv_request_devlist(int sockfd)
+{
+	int ret;
+	struct op_devlist_request req;
+
+	bzero(&req, sizeof(req));
+
+	ret = usbip_recv(sockfd, (void *) &req, sizeof(req));
+	if (ret < 0) {
+		err("recv devlist request");
+		return -1;
+	}
+
+	ret = send_reply_devlist(sockfd);
+	if (ret < 0) {
+		err("send devlist reply");
+		return -1;
+	}
+
+	return 0;
+}
+
+
+static int recv_request_import(int sockfd)
+{
+	int ret;
+	struct op_import_request req;
+	struct op_common reply;
+	struct usbip_exported_device *edev;
+	int found = 0;
+	int error = 0;
+
+	bzero(&req, sizeof(req));
+	bzero(&reply, sizeof(reply));
+
+	ret = usbip_recv(sockfd, (void *) &req, sizeof(req));
+	if (ret < 0) {
+		err("recv import request");
+		return -1;
+	}
+
+	PACK_OP_IMPORT_REQUEST(0, &req);
+
+	dlist_for_each_data(stub_driver->edev_list, edev, struct usbip_exported_device) {
+		if (!strncmp(req.busid, edev->udev.busid, SYSFS_BUS_ID_SIZE)) {
+			dbg("found requested device %s", req.busid);
+			found = 1;
+			break;
+		}
+	}
+
+	if (found) {
+		/* should set TCP_NODELAY for usbip */
+		usbip_set_nodelay(sockfd);
+
+		/* export_device needs a TCP/IP socket descriptor */
+		ret = usbip_stub_export_device(edev, sockfd);
+		if (ret < 0)
+			error = 1;
+	} else {
+		info("not found requested device %s", req.busid);
+		error = 1;
+	}
+
+
+	ret = usbip_send_op_common(sockfd, OP_REP_IMPORT, (!error ? ST_OK : ST_NA));
+	if (ret < 0) {
+		err("send import reply");
+		return -1;
+	}
+
+	if (!error) {
+		struct usb_device pdu_udev;
+
+		memcpy(&pdu_udev, &edev->udev, sizeof(pdu_udev));
+		pack_usb_device(1, &pdu_udev);
+
+		ret = usbip_send(sockfd, (void *) &pdu_udev, sizeof(pdu_udev));
+		if (ret < 0) {
+			err("send devinfo");
+			return -1;
+		}
+	}
+
+	return 0;
+}
+
+
+
+static int recv_pdu(int sockfd)
+{
+	int ret;
+	uint16_t code = OP_UNSPEC;
+
+
+	ret = usbip_recv_op_common(sockfd, &code);
+	if (ret < 0) {
+		err("recv op_common, %d", ret);
+		return ret;
+	}
+
+
+	ret = usbip_stub_refresh_device_list();
+	if (ret < 0)
+		return -1;
+
+	switch(code) {
+		case OP_REQ_DEVLIST:
+			ret = recv_request_devlist(sockfd);
+			break;
+
+		case OP_REQ_IMPORT:
+			ret = recv_request_import(sockfd);
+			break;
+
+		case OP_REQ_DEVINFO:
+		case OP_REQ_CRYPKEY:
+
+		default:
+			err("unknown op_code, %d", code);
+			ret = -1;
+	}
+
+
+	return ret;
+}
+
+
+
+
+static void log_addrinfo(struct addrinfo *ai)
+{
+	int ret;
+	char hbuf[NI_MAXHOST];
+	char sbuf[NI_MAXSERV];
+
+	ret = getnameinfo(ai->ai_addr, ai->ai_addrlen, hbuf, sizeof(hbuf),
+			sbuf, sizeof(sbuf), NI_NUMERICHOST | NI_NUMERICSERV);
+	if (ret)
+		err("getnameinfo, %s", gai_strerror(ret));
+
+	info("listen at [%s]:%s", hbuf, sbuf);
+}
+
+static struct addrinfo *my_getaddrinfo(char *host, int ai_family)
+{
+	int ret;
+	struct addrinfo hints, *ai_head;
+
+	bzero(&hints, sizeof(hints));
+
+	hints.ai_family   = ai_family;
+	hints.ai_socktype = SOCK_STREAM;
+	hints.ai_flags    = AI_PASSIVE;
+
+	ret = getaddrinfo(host, USBIP_PORT_STRING, &hints, &ai_head);
+	if (ret) {
+		err("%s: %s", USBIP_PORT_STRING, gai_strerror(ret));
+		return NULL;
+	}
+
+	return ai_head;
+}
+
+#define MAXSOCK 20
+static int listen_all_addrinfo(struct addrinfo *ai_head, int lsock[])
+{
+	struct addrinfo *ai;
+	int n = 0;		/* number of sockets */
+
+	for (ai = ai_head; ai && n < MAXSOCK; ai = ai->ai_next) {
+		int ret;
+
+		lsock[n] = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
+		if (lsock[n] < 0)
+			continue;
+
+		usbip_set_reuseaddr(lsock[n]);
+		usbip_set_nodelay(lsock[n]);
+
+		if (lsock[n] >= FD_SETSIZE) {
+			close(lsock[n]);
+			lsock[n] = -1;
+			continue;
+		}
+
+		ret = bind(lsock[n], ai->ai_addr, ai->ai_addrlen);
+		if (ret < 0) {
+			close(lsock[n]);
+			lsock[n] = -1;
+			continue;
+		}
+
+		ret = listen(lsock[n], SOMAXCONN);
+		if (ret < 0) {
+			close(lsock[n]);
+			lsock[n] = -1;
+			continue;
+		}
+
+		log_addrinfo(ai);
+
+		/* next if succeed */
+		n++;
+	}
+
+	if (n == 0) {
+		err("no socket to listen to");
+		return -1;
+	}
+
+	dbg("listen %d address%s", n, (n==1)?"":"es");
+
+	return n;
+}
+
+#ifdef HAVE_LIBWRAP
+static int tcpd_auth(int csock)
+{
+	int ret;
+	struct request_info request;
+
+	request_init(&request, RQ_DAEMON, "usbipd", RQ_FILE, csock, 0);
+
+	fromhost(&request);
+
+	ret = hosts_access(&request);
+	if (!ret)
+		return -1;
+
+	return 0;
+}
+#endif
+
+static int my_accept(int lsock)
+{
+	int csock;
+	struct sockaddr_storage ss;
+	socklen_t len = sizeof(ss);
+	char host[NI_MAXHOST], port[NI_MAXSERV];
+	int ret;
+
+	bzero(&ss, sizeof(ss));
+
+	csock = accept(lsock, (struct sockaddr *) &ss, &len);
+	if (csock < 0) {
+		err("accept");
+		return -1;
+	}
+
+	ret = getnameinfo((struct sockaddr *) &ss, len,
+			host, sizeof(host), port, sizeof(port),
+			(NI_NUMERICHOST | NI_NUMERICSERV));
+	if (ret)
+		err("getnameinfo, %s", gai_strerror(ret));
+
+#ifdef HAVE_LIBWRAP
+	ret = tcpd_auth(csock);
+	if (ret < 0) {
+		info("deny access from %s", host);
+		close(csock);
+		return -1;
+	}
+#endif
+
+	info("connected from %s:%s", host, port);
+
+	return csock;
+}
+
+
+GMainLoop *main_loop;
+
+static void signal_handler(int i)
+{
+	dbg("signal catched, code %d", i);
+
+	if (main_loop)
+		g_main_loop_quit(main_loop);
+}
+
+static void set_signal(void)
+{
+	struct sigaction act;
+
+	bzero(&act, sizeof(act));
+	act.sa_handler = signal_handler;
+	sigemptyset(&act.sa_mask);
+	sigaction(SIGTERM, &act, NULL);
+	sigaction(SIGINT, &act, NULL);
+}
+
+
+gboolean process_comming_request(GIOChannel *gio, GIOCondition condition,
+				 gpointer data __attribute__((unused)))
+{
+	int ret;
+
+	if (condition & (G_IO_ERR | G_IO_HUP | G_IO_NVAL))
+		g_error("unknown condition");
+
+
+	if (condition & G_IO_IN) {
+		int lsock;
+		int csock;
+
+		lsock = g_io_channel_unix_get_fd(gio);
+
+		csock = my_accept(lsock);
+		if (csock < 0)
+			return TRUE;
+
+		ret = recv_pdu(csock);
+		if (ret < 0)
+			err("process recieved pdu");
+
+		close(csock);
+	}
+
+	return TRUE;
+}
+
+
+static void do_standalone_mode(gboolean daemonize)
+{
+	int ret;
+	int lsock[MAXSOCK];
+	struct addrinfo *ai_head;
+	int n;
+
+
+
+	ret = usbip_names_init(USBIDS_FILE);
+	if (ret)
+		err("open usb.ids");
+
+	ret = usbip_stub_driver_open();
+	if (ret < 0)
+		g_error("driver open failed");
+
+	if (daemonize) {
+		if (daemon(0,0) < 0)
+			g_error("daemonizing failed: %s", g_strerror(errno));
+
+		usbip_use_syslog = 1;
+	}
+
+	set_signal();
+
+	ai_head = my_getaddrinfo(NULL, PF_UNSPEC);
+	if (!ai_head)
+		return;
+
+	n = listen_all_addrinfo(ai_head, lsock);
+	if (n <= 0)
+		g_error("no socket to listen to");
+
+	for (int i = 0; i < n; i++) {
+		GIOChannel *gio;
+
+		gio = g_io_channel_unix_new(lsock[i]);
+		g_io_add_watch(gio, (G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL),
+				process_comming_request, NULL);
+	}
+
+
+	info("usbipd start (%s)", version);
+
+
+	main_loop = g_main_loop_new(FALSE, FALSE);
+	g_main_loop_run(main_loop);
+
+	info("shutdown");
+
+	freeaddrinfo(ai_head);
+	usbip_names_free();
+	usbip_stub_driver_close();
+
+	return;
+}
+
+
+static const char help_message[] = "\
+Usage: usbipd [options]				\n\
+	-D, --daemon				\n\
+		Run as a daemon process.	\n\
+						\n\
+	-d, --debug				\n\
+		Print debugging information.	\n\
+						\n\
+	-v, --version				\n\
+		Show version.			\n\
+						\n\
+	-h, --help 				\n\
+		Print this help.		\n";
+
+static void show_help(void)
+{
+	printf("%s", help_message);
+}
+
+static const struct option longopts[] = {
+	{"daemon",	no_argument,	NULL, 'D'},
+	{"debug",	no_argument,	NULL, 'd'},
+	{"version",	no_argument,	NULL, 'v'},
+	{"help",	no_argument,	NULL, 'h'},
+	{NULL,		0,		NULL,  0}
+};
+
+int main(int argc, char *argv[])
+{
+	gboolean daemonize = FALSE;
+
+	enum {
+		cmd_standalone_mode = 1,
+		cmd_help,
+		cmd_version
+	} cmd = cmd_standalone_mode;
+
+
+	usbip_use_stderr = 1;
+	usbip_use_syslog = 0;
+
+	if (geteuid() != 0)
+		g_warning("running non-root?");
+
+	for (;;) {
+		int c;
+		int index = 0;
+
+		c = getopt_long(argc, argv, "vhdD", longopts, &index);
+
+		if (c == -1)
+			break;
+
+		switch (c) {
+			case 'd':
+				usbip_use_debug = 1;
+				continue;
+			case 'v':
+				cmd = cmd_version;
+				break;
+			case 'h':
+				cmd = cmd_help;
+				break;
+			case 'D':
+				daemonize = TRUE;
+				break;
+			case '?':
+				show_help();
+				exit(EXIT_FAILURE);
+			default:
+				err("getopt");
+		}
+	}
+
+	switch (cmd) {
+		case cmd_standalone_mode:
+			do_standalone_mode(daemonize);
+			break;
+		case cmd_version:
+			printf("%s\n", version);
+			break;
+		case cmd_help:
+			show_help();
+			break;
+		default:
+			info("unknown cmd");
+			show_help();
+	}
+
+	return 0;
+}
diff -druN linux-2.6.39-libre/drivers/staging/usbip/userspace/src/usbip_network.c linux-3.0-rc7-libre/drivers/staging/usbip/userspace/src/usbip_network.c
--- linux-2.6.39-libre/drivers/staging/usbip/userspace/src/usbip_network.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/staging/usbip/userspace/src/usbip_network.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,251 @@
+/*
+ *
+ * Copyright (C) 2005-2007 Takahiro Hirofuchi
+ */
+
+#include "usbip_network.h"
+
+void pack_uint32_t(int pack, uint32_t *num)
+{
+	uint32_t i;
+
+	if (pack)
+		i = htonl(*num);
+	else
+		i = ntohl(*num);
+
+	*num = i;
+}
+
+void pack_uint16_t(int pack, uint16_t *num)
+{
+	uint16_t i;
+
+	if (pack)
+		i = htons(*num);
+	else
+		i = ntohs(*num);
+
+	*num = i;
+}
+
+void pack_usb_device(int pack, struct usb_device *udev)
+{
+	pack_uint32_t(pack, &udev->busnum);
+	pack_uint32_t(pack, &udev->devnum);
+	pack_uint32_t(pack, &udev->speed );
+
+	pack_uint16_t(pack, &udev->idVendor );
+	pack_uint16_t(pack, &udev->idProduct);
+	pack_uint16_t(pack, &udev->bcdDevice);
+}
+
+void pack_usb_interface(int pack __attribute__((unused)),
+			struct usb_interface *udev __attribute__((unused)))
+{
+	/* uint8_t members need nothing */
+}
+
+
+static ssize_t usbip_xmit(int sockfd, void *buff, size_t bufflen, int sending)
+{
+	ssize_t total = 0;
+
+	if (!bufflen)
+		return 0;
+
+	do {
+		ssize_t nbytes;
+
+		if (sending)
+			nbytes = send(sockfd, buff, bufflen, 0);
+		else
+			nbytes = recv(sockfd, buff, bufflen, MSG_WAITALL);
+
+		if (nbytes <= 0)
+			return -1;
+
+		buff	= (void *) ((intptr_t) buff + nbytes);
+		bufflen	-= nbytes;
+		total	+= nbytes;
+
+	} while (bufflen > 0);
+
+
+	return total;
+}
+
+ssize_t usbip_recv(int sockfd, void *buff, size_t bufflen)
+{
+	return usbip_xmit(sockfd, buff, bufflen, 0);
+}
+
+ssize_t usbip_send(int sockfd, void *buff, size_t bufflen)
+{
+	return usbip_xmit(sockfd, buff, bufflen, 1);
+}
+
+int usbip_send_op_common(int sockfd, uint32_t code, uint32_t status)
+{
+	int ret;
+	struct op_common op_common;
+
+	bzero(&op_common, sizeof(op_common));
+
+	op_common.version	= USBIP_VERSION;
+	op_common.code		= code;
+	op_common.status	= status;
+
+	PACK_OP_COMMON(1, &op_common);
+
+	ret = usbip_send(sockfd, (void *) &op_common, sizeof(op_common));
+	if (ret < 0) {
+		err("send op_common");
+		return -1;
+	}
+
+	return 0;
+}
+
+int usbip_recv_op_common(int sockfd, uint16_t *code)
+{
+	int ret;
+	struct op_common op_common;
+
+	bzero(&op_common, sizeof(op_common));
+
+	ret = usbip_recv(sockfd, (void *) &op_common, sizeof(op_common));
+	if (ret < 0) {
+		err("recv op_common, %d", ret);
+		goto err;
+	}
+
+	PACK_OP_COMMON(0, &op_common);
+
+	if (op_common.version != USBIP_VERSION) {
+		err("version mismatch, %d %d", op_common.version, USBIP_VERSION);
+		goto err;
+	}
+
+	switch(*code) {
+		case OP_UNSPEC:
+			break;
+		default:
+			if (op_common.code != *code) {
+				info("unexpected pdu %d for %d", op_common.code, *code);
+				goto err;
+			}
+	}
+
+	if (op_common.status != ST_OK) {
+		info("request failed at peer, %d", op_common.status);
+		goto err;
+	}
+
+	*code = op_common.code;
+
+	return 0;
+err:
+	return -1;
+}
+
+
+int usbip_set_reuseaddr(int sockfd)
+{
+	const int val = 1;
+	int ret;
+
+	ret = setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val));
+	if (ret < 0)
+		err("setsockopt SO_REUSEADDR");
+
+	return ret;
+}
+
+int usbip_set_nodelay(int sockfd)
+{
+	const int val = 1;
+	int ret;
+
+	ret = setsockopt(sockfd, IPPROTO_TCP, TCP_NODELAY, &val, sizeof(val));
+	if (ret < 0)
+		err("setsockopt TCP_NODELAY");
+
+	return ret;
+}
+
+int usbip_set_keepalive(int sockfd)
+{
+	const int val = 1;
+	int ret;
+
+	ret = setsockopt(sockfd, SOL_SOCKET, SO_KEEPALIVE, &val, sizeof(val));
+	if (ret < 0)
+		err("setsockopt SO_KEEPALIVE");
+
+	return ret;
+}
+
+/* IPv6 Ready */
+/*
+ * moved here from vhci_attach.c
+ */
+int tcp_connect(char *hostname, char *service)
+{
+	struct addrinfo hints, *res, *res0;
+	int sockfd;
+	int err;
+
+
+	memset(&hints, 0, sizeof(hints));
+	hints.ai_socktype = SOCK_STREAM;
+
+	/* get all possible addresses */
+	err = getaddrinfo(hostname, service, &hints, &res0);
+	if (err) {
+		err("%s %s: %s", hostname, service, gai_strerror(err));
+		return -1;
+	}
+
+	/* try all the addresses */
+	for (res = res0; res; res = res->ai_next) {
+		char hbuf[NI_MAXHOST], sbuf[NI_MAXSERV];
+
+		err = getnameinfo(res->ai_addr, res->ai_addrlen,
+				hbuf, sizeof(hbuf), sbuf, sizeof(sbuf), NI_NUMERICHOST | NI_NUMERICSERV);
+		if (err) {
+			err("%s %s: %s", hostname, service, gai_strerror(err));
+			continue;
+		}
+
+		dbg("trying %s port %s\n", hbuf, sbuf);
+
+		sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
+		if (sockfd < 0) {
+			err("socket");
+			continue;
+		}
+
+		/* should set TCP_NODELAY for usbip */
+		usbip_set_nodelay(sockfd);
+		/* TODO: write code for heatbeat */
+		usbip_set_keepalive(sockfd);
+
+		err = connect(sockfd, res->ai_addr, res->ai_addrlen);
+		if (err < 0) {
+			close(sockfd);
+			continue;
+		}
+
+		/* connected */
+		dbg("connected to %s:%s", hbuf, sbuf);
+		freeaddrinfo(res0);
+		return sockfd;
+	}
+
+
+	dbg("%s:%s, %s", hostname, service, "no destination to connect to");
+	freeaddrinfo(res0);
+
+	return -1;
+}
diff -druN linux-2.6.39-libre/drivers/staging/usbip/userspace/src/usbip_network.h linux-3.0-rc7-libre/drivers/staging/usbip/userspace/src/usbip_network.h
--- linux-2.6.39-libre/drivers/staging/usbip/userspace/src/usbip_network.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/staging/usbip/userspace/src/usbip_network.h	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,198 @@
+/*
+ * Copyright (C) 2005-2007 Takahiro Hirofuchi
+ */
+
+#ifndef _USBIP_NETWORK_H
+#define _USBIP_NETWORK_H
+
+#include "usbip.h"
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/tcp.h>
+
+
+/* -------------------------------------------------- */
+/* Define Protocol Format                             */
+/* -------------------------------------------------- */
+
+
+/* ---------------------------------------------------------------------- */
+/* Common header for all the kinds of PDUs. */
+struct op_common {
+	uint16_t version;
+
+#define OP_REQUEST	(0x80 << 8)
+#define OP_REPLY	(0x00 << 8)
+	uint16_t code;
+
+	/* add more error code */
+#define ST_OK	0x00
+#define ST_NA	0x01
+	uint32_t status; /* op_code status (for reply) */
+
+} __attribute__((packed));
+
+#define PACK_OP_COMMON(pack, op_common)  do {\
+	pack_uint16_t(pack, &(op_common)->version);\
+	pack_uint16_t(pack, &(op_common)->code   );\
+	pack_uint32_t(pack, &(op_common)->status );\
+} while (0)
+
+
+/* ---------------------------------------------------------------------- */
+/* Dummy Code */
+#define OP_UNSPEC	0x00
+#define OP_REQ_UNSPEC	OP_UNSPEC
+#define OP_REP_UNSPEC	OP_UNSPEC
+
+/* ---------------------------------------------------------------------- */
+/* Retrieve USB device information. (still not used) */
+#define OP_DEVINFO	0x02
+#define OP_REQ_DEVINFO	(OP_REQUEST | OP_DEVINFO)
+#define OP_REP_DEVINFO	(OP_REPLY   | OP_DEVINFO)
+
+struct op_devinfo_request {
+	char busid[SYSFS_BUS_ID_SIZE];
+} __attribute__((packed));
+
+struct op_devinfo_reply {
+	struct usb_device udev;
+	struct usb_interface uinf[];
+} __attribute__((packed));
+
+
+/* ---------------------------------------------------------------------- */
+/* Import a remote USB device. */
+#define OP_IMPORT	0x03
+#define OP_REQ_IMPORT	(OP_REQUEST | OP_IMPORT)
+#define OP_REP_IMPORT   (OP_REPLY   | OP_IMPORT)
+
+struct op_import_request {
+	char busid[SYSFS_BUS_ID_SIZE];
+} __attribute__((packed));
+
+struct op_import_reply {
+	struct usb_device udev;
+//	struct usb_interface uinf[];
+} __attribute__((packed));
+
+#define PACK_OP_IMPORT_REQUEST(pack, request)  do {\
+} while (0)
+
+#define PACK_OP_IMPORT_REPLY(pack, reply)  do {\
+	pack_usb_device(pack, &(reply)->udev);\
+} while (0)
+
+
+
+/* ---------------------------------------------------------------------- */
+/* Export a USB device to a remote host. */
+#define OP_EXPORT	0x06
+#define OP_REQ_EXPORT	(OP_REQUEST | OP_EXPORT)
+#define OP_REP_EXPORT	(OP_REPLY   | OP_EXPORT)
+
+struct op_export_request {
+	struct usb_device udev;
+} __attribute__((packed));
+
+struct op_export_reply {
+	int returncode;
+} __attribute__((packed));
+
+
+#define PACK_OP_EXPORT_REQUEST(pack, request)  do {\
+	pack_usb_device(pack, &(request)->udev);\
+} while (0)
+
+#define PACK_OP_EXPORT_REPLY(pack, reply)  do {\
+} while (0)
+
+/* ---------------------------------------------------------------------- */
+/* un-Export a USB device from a remote host. */
+#define OP_UNEXPORT	0x07
+#define OP_REQ_UNEXPORT	(OP_REQUEST | OP_UNEXPORT)
+#define OP_REP_UNEXPORT	(OP_REPLY   | OP_UNEXPORT)
+
+struct op_unexport_request {
+	struct usb_device udev;
+} __attribute__((packed));
+
+struct op_unexport_reply {
+	int returncode;
+} __attribute__((packed));
+
+#define PACK_OP_UNEXPORT_REQUEST(pack, request)  do {\
+	pack_usb_device(pack, &(request)->udev);\
+} while (0)
+
+#define PACK_OP_UNEXPORT_REPLY(pack, reply)  do {\
+} while (0)
+
+
+
+/* ---------------------------------------------------------------------- */
+/* Negotiate IPSec encryption key. (still not used) */
+#define OP_CRYPKEY	0x04
+#define OP_REQ_CRYPKEY	(OP_REQUEST | OP_CRYPKEY)
+#define OP_REP_CRYPKEY	(OP_REPLY   | OP_CRYPKEY)
+
+struct op_crypkey_request {
+	/* 128bit key */
+	uint32_t key[4];
+} __attribute__((packed));
+
+struct op_crypkey_reply {
+	uint32_t __reserved;
+} __attribute__((packed));
+
+
+/* ---------------------------------------------------------------------- */
+/* Retrieve the list of exported USB devices. */
+#define OP_DEVLIST	0x05
+#define OP_REQ_DEVLIST	(OP_REQUEST | OP_DEVLIST)
+#define OP_REP_DEVLIST	(OP_REPLY   | OP_DEVLIST)
+
+struct op_devlist_request {
+} __attribute__((packed));
+
+struct op_devlist_reply {
+	uint32_t ndev;
+	/* followed by reply_extra[] */
+} __attribute__((packed));
+
+struct op_devlist_reply_extra {
+	struct usb_device    udev;
+	struct usb_interface uinf[];
+} __attribute__((packed));
+
+#define PACK_OP_DEVLIST_REQUEST(pack, request)  do {\
+} while (0)
+
+#define PACK_OP_DEVLIST_REPLY(pack, reply)  do {\
+	pack_uint32_t(pack, &(reply)->ndev);\
+} while (0)
+
+
+/* -------------------------------------------------- */
+/* Declare Prototype Function                         */
+/* -------------------------------------------------- */
+
+void pack_uint32_t(int pack, uint32_t *num);
+void pack_uint16_t(int pack, uint16_t *num);
+void pack_usb_device(int pack, struct usb_device *udev);
+void pack_usb_interface(int pack, struct usb_interface *uinf);
+
+ssize_t usbip_recv(int sockfd, void *buff, size_t bufflen);
+ssize_t usbip_send(int sockfd, void *buff, size_t bufflen);
+int usbip_send_op_common(int sockfd, uint32_t code, uint32_t status);
+int usbip_recv_op_common(int sockfd, uint16_t *code);
+int usbip_set_reuseaddr(int sockfd);
+int usbip_set_nodelay(int sockfd);
+int usbip_set_keepalive(int sockfd);
+
+int tcp_connect(char *hostname, char *service);
+
+#define USBIP_PORT 3240
+#define USBIP_PORT_STRING "3240"
+
+#endif
diff -druN linux-2.6.39-libre/drivers/staging/usbip/userspace/src/utils.c linux-3.0-rc7-libre/drivers/staging/usbip/userspace/src/utils.c
--- linux-2.6.39-libre/drivers/staging/usbip/userspace/src/utils.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/staging/usbip/userspace/src/utils.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,255 @@
+/*
+ *
+ * Copyright (C) 2005-2007 Takahiro Hirofuchi
+ */
+
+#include "utils.h"
+
+int read_integer(char *path)
+{
+	char buff[100];
+	int fd;
+	int ret = 0;
+
+	bzero(buff, sizeof(buff));
+
+	fd = open(path, O_RDONLY);
+	if (fd < 0)
+		return -1;
+
+	ret = read(fd, buff, sizeof(buff));
+	if (ret < 0) {
+		close(fd);
+		return -1;
+	}
+
+	sscanf(buff, "%d", &ret);
+
+	close(fd);
+
+	return ret;
+}
+
+int read_string(char *path, char *string, size_t len)
+{
+	int fd;
+	int ret = 0;
+	char  *p;
+
+	bzero(string, len);
+
+	fd = open(path, O_RDONLY);
+	if (fd < 0) {
+		string = NULL;
+		return -1;
+	}
+
+	ret = read(fd, string, len-1);
+	if (ret < 0) {
+		string = NULL;
+		close(fd);
+		return -1;
+	}
+
+	p = strchr(string, '\n');
+	*p = '\0';
+
+	close(fd);
+
+	return 0;
+}
+
+int write_integer(char *path, int value)
+{
+	int fd;
+	int ret;
+	char buff[100];
+
+	snprintf(buff, sizeof(buff), "%d", value);
+
+	fd = open(path, O_WRONLY);
+	if (fd < 0)
+		return -1;
+
+	ret = write(fd, buff, strlen(buff));
+	if (ret < 0) {
+		close(fd);
+		return -1;
+	}
+
+	close(fd);
+
+	return 0;
+}
+
+int read_bConfigurationValue(char *busid)
+{
+	char path[PATH_MAX];
+
+	snprintf(path, PATH_MAX, "/sys/bus/usb/devices/%s/bConfigurationValue", busid);
+
+	return read_integer(path);
+}
+
+int write_bConfigurationValue(char *busid, int config)
+{
+	char path[PATH_MAX];
+
+	snprintf(path, PATH_MAX, "/sys/bus/usb/devices/%s/bConfigurationValue", busid);
+
+	return write_integer(path, config);
+}
+
+int read_bNumInterfaces(char *busid)
+{
+	char path[PATH_MAX];
+
+	snprintf(path, PATH_MAX, "/sys/bus/usb/devices/%s/bNumInterfaces", busid);
+
+	return read_integer(path);
+}
+
+int read_bDeviceClass(char *busid)
+{
+	char path[PATH_MAX];
+
+	snprintf(path, PATH_MAX, "/sys/bus/usb/devices/%s/bDeviceClass", busid);
+
+	return read_integer(path);
+}
+
+int getdriver(char *busid, int conf, int infnum, char *driver, size_t len)
+{
+	char path[PATH_MAX];
+	char linkto[PATH_MAX];
+	int ret;
+
+	snprintf(path, PATH_MAX, "/sys/bus/usb/devices/%s:%d.%d/driver", busid, conf, infnum);
+
+	/* readlink does not add NULL */
+	bzero(linkto, sizeof(linkto));
+	ret = readlink(path, linkto, sizeof(linkto)-1);
+	if (ret < 0) {
+		strncpy(driver, "none", len);
+		return -1;
+	} else {
+		strncpy(driver, basename(linkto), len);
+		return 0;
+	}
+}
+
+int getdevicename(char *busid, char *name, size_t len)
+{
+	char path[PATH_MAX];
+	char idProduct[10], idVendor[10];
+
+	snprintf(path, PATH_MAX, "/sys/bus/usb/devices/%s/idVendor", busid);
+	read_string(path, idVendor, sizeof(idVendor));
+
+	snprintf(path, PATH_MAX, "/sys/bus/usb/devices/%s/idProduct", busid);
+	read_string(path, idProduct, sizeof(idProduct));
+
+	if (!idVendor[0] || !idProduct[0])
+		return -1;
+
+	snprintf(name, len, "%s:%s", idVendor, idProduct);
+
+	return 0;
+}
+
+#define MAXLINE 100
+
+/* if this cannot read a whole line, return -1 */
+int readline(int sockfd, char *buff, int bufflen)
+{
+	int ret;
+	char c;
+	int index = 0;
+
+
+	while (index < bufflen) {
+		ret = read(sockfd, &c, sizeof(c));
+		if (ret < 0 && errno == EINTR)
+			continue;
+		if (ret <= 0) {
+			return -1;
+		}
+
+		buff[index] = c;
+
+		if ( index > 0 && buff[index-1] == '\r'  && buff[index] == '\n') {
+			/* end of line */
+			buff[index-1] = '\0';	/* get rid of delimitor */
+			return index;
+		} else
+			index++;
+	}
+
+	return -1;
+}
+
+#if 0
+int writeline(int sockfd, char *str, int strlen)
+{
+	int ret;
+	int index = 0;
+	int len;
+	char buff[MAXLINE];
+
+	if (strlen + 3 > MAXLINE)
+		return -1;
+
+	strncpy(buff, str, strlen);
+	buff[strlen+1] = '\r';
+	buff[strlen+2] = '\n';
+	buff[strlen+3] = '\0';
+
+	len = strlen + 3;
+
+	while (len > 0) {
+		ret = write(sockfd, buff+index, len);
+		if (ret <= 0) {
+			return -1;
+		}
+
+		len -= ret;
+		index += ret;
+	}
+
+	return index;
+}
+#endif
+
+int writeline(int sockfd, char *str, int strlen)
+{
+	int ret;
+	int index = 0;
+	int len;
+	char buff[MAXLINE];
+
+	len = strnlen(str, strlen);
+
+	if (strlen + 2 > MAXLINE)
+		return -1;
+
+	memcpy(buff, str, strlen);
+	buff[strlen] = '\r';
+	buff[strlen+1] = '\n';		/* strlen+1 <= MAXLINE-1 */
+
+	len = strlen + 2;
+
+	while (len > 0) {
+		ret = write(sockfd, buff+index, len);
+		if (ret < 0 && errno == EINTR)
+			continue;
+		if (ret <= 0) {
+			return -1;
+		}
+
+		len -= ret;
+		index += ret;
+	}
+
+	return index;
+}
+
diff -druN linux-2.6.39-libre/drivers/staging/usbip/userspace/src/utils.h linux-3.0-rc7-libre/drivers/staging/usbip/userspace/src/utils.h
--- linux-2.6.39-libre/drivers/staging/usbip/userspace/src/utils.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/staging/usbip/userspace/src/utils.h	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,38 @@
+
+#ifdef HAVE_CONFIG_H
+#include "../config.h"
+#endif
+
+#define _GNU_SOURCE
+#include <string.h>
+#include <sys/un.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+
+#include <sysfs/libsysfs.h>
+#include <glib.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <time.h>
+#include <errno.h>
+
+
+
+/* Be sync to kernel header */
+#define BUS_ID_SIZE 20
+
+int read_string(char *path, char *, size_t len);
+int read_integer(char *path);
+int getdevicename(char *busid, char *name, size_t len);
+int getdriver(char *busid, int conf, int infnum, char *driver, size_t len);
+int read_bNumInterfaces(char *busid);
+int read_bConfigurationValue(char *busid);
+int write_integer(char *path, int value);
+int write_bConfigurationValue(char *busid, int config);
+int read_bDeviceClass(char *busid);
+int readline(int sockfd, char *str, int strlen);
+int writeline(int sockfd, char *buff, int bufflen);
diff -druN linux-2.6.39-libre/drivers/staging/usbip/userspace/usb.ids linux-3.0-rc7-libre/drivers/staging/usbip/userspace/usb.ids
--- linux-2.6.39-libre/drivers/staging/usbip/userspace/usb.ids	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/staging/usbip/userspace/usb.ids	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,13209 @@
+#
+#	List of USB ID's
+#
+#	Maintained by Stephen J. Gowdy <gowdy@slac.stanford.edu>
+#	If you have any new entries, send them to the maintainer.
+#	Send entries as patches (diff -u old new).
+#	The latest version can be obtained from
+#		http://www.linux-usb.org/usb.ids
+#
+# $Id: usb.ids,v 1.346 2008/04/23 13:51:46 gowdy Exp $
+#
+
+# Vendors, devices and interfaces. Please keep sorted.
+
+# Syntax:
+# vendor  vendor_name
+#	device  device_name				<-- single tab
+#		interface  interface_name		<-- two tabs
+
+0001  Fry's Electronics
+0002  Ingram
+0003  Club Mac
+0004  Nebraska Furniture Mart
+0145  Unknown
+	0112  Card Reader
+0204  Chipsbank Microelectronics Co., Ltd
+	6025  CBM2080 Flash drive controller
+	6026  CBM1180 Flash drive controller
+02ad  HUMAX Co., Ltd.
+	138c  PVR Mass Storage
+0386  LTS
+	0001  PSX for USB Converter
+03e8  EndPoints, Inc.
+	0004  SE401 WebCam
+	0008  101 Ethernet [klsi]
+	0015  USB ATAPI Enclosure
+	2123  SiPix StyleCam Deluxe
+	8004  Aox 99001
+03e9  Thesys Microelectronics
+03ea  Data Broadcasting Corp.
+03eb  Atmel Corp.
+	2002  Mass Storage Device
+	2015  at90usbkey sample firmware (HID keyboard)
+	2018  at90usbkey sample firmware (CDC ACM)
+	2019  stk525 sample firmware (microphone)
+	201c  at90usbkey sample firmware (HID mouse)
+	201d  at90usbkey sample firmware (HID generic)
+	2022  at90usbkey sample firmware (composite device)
+	2103  JTAG ICE mkII
+	2104  AVR ISP mkII
+	2107  AVR Dragon
+	2ffb  at90usb AVR DFU bootloader
+	2ffd  at89c5130/c5131 DFU bootloader
+	2fff  at89c5132/c51snd1c DFU bootloader
+	3301  at43301 4-port Hub
+	3312  4-port Hub
+	5601  at76c510 Prism-II 802.11b Access Point
+	5603  Cisco 7920 WiFi IP Phone
+	6124  at91sam SAMBA bootloader
+	7603  at76c503a D-Link DWL-120 802.11b Adapter
+	7604  FastVNET
+	7605  at76c503a 802.11b Adapter
+	7606  at76c505 802.11b Adapter
+	7611  at76c510 rfmd2948 802.11b Access Point
+	7613  WL-1130 USB
+	7614  AT76c505a Wireless Adapter
+03ec  Iwatsu America, Inc.
+03ed  Mitel Corp.
+03ee  Mitsumi
+	0000  CD-R/RW Drive
+	2501  eHome Infrared Receiver
+	2502  eHome Infrared Receiver
+	5609  Japanese Keyboard
+	641f  WIF-0402C Bluetooth Adapter
+	6438  Bluetooth Device
+	6440  WML-C52APR Bluetooth Adapter
+	6901  SmartDisk FDD
+	6902  Floppy Disk Drive
+	7500  CD-R/RW
+	ffff  Dongle with BlueCore in DFU mode
+03f0  Hewlett-Packard
+	0004  DeskJet 895c
+	0011  OfficeJet G55
+	0012  DeskJet 1125C Printer Port
+	0024  KU-0316 Keyboard
+	0101  ScanJet 4100c
+	0102  PhotoSmart S20
+	0104  DeskJet 880c/970c
+	0105  ScanJet 4200c
+	0107  CD-Writer Plus
+	010c  Multimedia Keyboard Hub
+	0111  G55xi Printer/Scanner/Copier
+	0117  LaserJet 3200
+	011c  hn210w 802.11b Adapter
+	011d  Integrated Bluetooth Module
+	0121  HP49g+ Calculator
+	0122  HID Internet Keyboard
+	0201  ScanJet 6200c
+	0202  PhotoSmart S20
+	0204  DeskJet 815c
+	0205  ScanJet 3300c
+	0207  CD-Writer Plus 8200e
+	020c  Multimedia Keyboard
+	0211  OfficeJet G85
+	0212  DeskJet 1220C
+	0217  LaserJet 2200
+	0218  APOLLO P2500/2600
+	2624  Pole Display (HP522 2 x 20 Line Display)
+	0304  DeskJet 810c/812c
+	0305  ScanJet 4300c
+	0307  CD-Writer+ CD-4e
+	0311  OfficeJet G85xi
+	0312  Color Inkjet CP1700
+	0314  designjet 30/130 series
+	0317  LaserJet 1200
+	0401  ScanJet 5200c
+	0404  DeskJet 830c/832c
+	0405  ScanJet 3400cse
+	0411  OfficeJet G95
+	0412  Printing Support
+	0417  LaserJet 1200 series
+	0504  DeskJet 885c
+	0505  ScanJet 2100c
+	0507  DVD+RW
+	050c  5219 Wireless Keyboard
+	0511  OfficeJet K60
+	0512  DeckJet 450
+	0517  LaserJet 1000
+	051d  integrated module with Bluetooth wireless technology.
+	0601  ScanJet 6300c
+	0604  DeskJet 840c
+	0605  ScanJet 2200c
+	0611  OfficeJet K60xi
+	0612  business inkjet 3000
+	0624  Bluetooth Dongle
+	0701  ScanJet 5300c/5370c
+	0704  DeskJet 825c
+	0705  ScanJet 4400c
+	0711  OfficeJet K80
+	0712  DeskJet 1180c
+	0714  Printing Support
+	0801  ScanJet 7400c
+	0804  DeskJet 816c
+	0805  HP4470C
+	0811  OfficeJet K80xi
+	0817  LaserJet 3300
+	0901  ScanJet 2300c
+	0904  DeskJet 845c
+	0912  Printing Support
+	0917  LaserJet 3330
+	0924  Modular Smartcard Keyboard
+	0a01  ScanJet 2400c
+	0a17  color LaserJet 3700
+	0b01  Scanjet 82x0C
+	0b17  Laserjet 2300d
+	0c17  LaserJet 1010
+	0c24  Bluetooth Dongle
+	0d12  Officejet 9100 series
+	0d17  LaserJet 1012
+	0e17  LaserJet 1015
+	0f11  OfficeJet V40
+	0f12  Printing Support
+	0f17  LaserJet 1150
+	1001  Photo Scanner 1000
+	1002  photosmart 140 series
+	1004  DeskJet 970c/970cse
+	1005  ScanJet 5400c
+	1011  OfficeJet V40xi
+	1016  Jornada 548 / iPAQ HW6515 Pocket PC
+	1017  LaserJet 1300
+	1024  Smart Card Keyboard
+	1102  photosmart 240 series
+	1104  DeskJet 959c
+	1105  ScanJet 5470c
+	1111  officejet v60
+	1116  Jornada 568 Pocket PC
+	1117  LaserJet 1300n
+	1151  PSC-750xi Printer/Scanner/Copier
+	1202  Photosmart 320 Series
+	1204  DeskJet 930c
+	1205  ScanJet 4500C/5550C
+	1211  officejet v60xi
+	1217  LaserJet 2300L
+	1302  Photosmart 370 Series
+	1305  ScanJet 4570c
+	1311  OfficeJet V30
+	1312  Deskjet 460
+	1317  LaserJet 1005
+	1405  Scanjet 3670
+	1411  PSC 750
+	1424  f2105 Monitor Hub
+	1502  Photosmart 420 Series
+	1504  DeskJet 920c
+	1511  PSC 750xi
+	1512  Printing Support
+	1517  color LaserJet 3500
+	1524  Smart Card Keyboard - KR
+	1602  Photosmart 330 Series
+	1604  DeskJet 940c
+	1605  ScanJet 5530C Photosmart
+	1611  psc 780
+	1617  LaserJet 3015
+	161d  Wireless Rechargeable Optical Mouse (HID)
+	1624  Smart Card Keyboard - JP
+	1702  Photosmart 380 Series
+	1704  deskjet 948C
+	1705  ScanJet 5590
+	1711  psc 780xi
+	1712  Printing Support
+	1717  LaserJet 3020
+	171d  Wireless (Bluetooth + WLAN) Interface [Integrated Module]
+	1801  Inkjet P-2000U
+	1802  Photosmart 470 Series
+	1804  deskjet 916C
+	1805  ScanJet 7650
+	1811  PSC 720
+	1817  LaserJet 3030
+	181d  integrated module with Bluetooth 2.0 wireless technology.
+	1902  Photosmart A430 series
+	1904  DeskJet 3820
+	1911  OfficeJet V45
+	1917  LaserJet 3380
+	1a02  Photosmart A510 series
+	1a11  officejet 5100 series
+	1a17  color LaserJet 4650
+	1b02  Photosmart A610 series
+	1b04  deskjet 3810
+	1b05  ScanJet 4850C/4890C
+	1c02  Photosmart A710 series
+	1c17  Color LaserJet 2550l
+	1d02  Photosmart A310 series
+	1d17  LaserJet 1320
+	1e02  Photosmart A320 Printer series
+	1e11  PSC-950
+	1e17  LaserJet 1160 series
+	1f02  Photosmart A440 Printer series
+	1f11  PSC 920
+	1f12  Officejet Pro K5300
+	1f17  color LaserJet 5550
+	2001  Floppy
+	2002  Hub
+	2004  DeskJet 640c
+	2005  ScanJet 3570c
+	2012  Officejet Pro K5400
+	2102  photosmart 7345
+	2104  DeskJet 630c
+	2112  Officejet Pro L7500
+	2202  photosmart 7600 series
+	2205  ScanJet 3500c
+	2212  Officejet Pro L7600
+	2217  color LaserJet 9500 MFP
+	2302  photosmart 7600 series
+	2304  DeskJet 656c
+	2305  ScanJet 3970c
+	2311  officejet d series
+	2312  Officejet Pro L7700
+	2317  LaserJet 4350
+	2402  photosmart 7700 series
+	2405  ScanJet 4070 Photosmart
+	2417  LaserJet 4250
+	2424  LP1965 19" Monitor Hub
+	2502  photosmart 7700 series
+	2505  ScanJet 3770
+	2512  Officejet Pro L7300
+	2517  LaserJet 2410
+	2524  LP3065 30" Monitor Hub
+	2602  Photosmart A520 series
+	2605  ScanJet 3800c
+	2611  officejet 7100 series
+	2617  Color LaserJet 2820 Series
+	2702  Photosmart A620 series
+	2704  Deskjet 915
+	2717  Color LaserJet 2830
+	2811  PSC-2100
+	2817  Color LaserJet 2840
+	2902  Photosmart A820 series
+	2911  PSC 2200
+	2917  LaserJet 2420
+	2a11  PSC 2150 series
+	2a17  LaserJet 2430
+	2b11  PSC 2170 series
+	2b17  LaserJet 1020
+	2c17  Printing Support
+	2d11  OfficeJet 6110
+	2d17  Printing Support
+	2e11  PSC 1000
+	2e17  Printing Support
+	2f11  PSC 1200
+	2f17  EWS 2605dn
+	3002  photosmart P1000
+	3004  deskjet 980c
+	3005  ScanJet 4670v
+	3011  PSC 1100 series
+	3017  Printing Support
+	3102  PhotoSmart P1100 Printer w/ Card Reader
+	3104  DeskJet 960c
+	3111  officejet 4100 series
+	3117  EWS 2605dtn
+	3202  photosmart 1215
+	3211  officejet 4105 series
+	3217  LaserJet 3050
+	3302  photosmart 1218
+	3304  DeskJet 990c
+	3317  LaserJet 3052
+	3402  photosmart 1115
+	3404  DeskJet 6122
+	3417  LaserJet 3055
+	3502  photosmart 230
+	3504  DeskJet 6127c
+	3511  PSC 2300
+	3517  LaserJet 3390
+	3602  photosmart 1315
+	3611  PSC 2410 Photosmart
+	3617  EWS 2605
+	3711  PSC 2500
+	3717  EWS UPD
+	3802  photosmart 100
+	3817  LaserJet P2015 Series
+	3902  photosmart 130
+	3a02  photosmart 7150
+	3a11  OfficeJet 5500 series
+	3a17  Printing Support
+	3b02  photosmart 7150~
+	3b11  PSC 1300 series
+	3b17  LaserJet M1005 MFP
+	3c02  PhotoSmart 7350
+	3c11  PSC 1358
+	3c17  EWS UPD
+	3d02  photosmart 7350~
+	3d11  OfficeJet 4215
+	3e02  photosmart 7550
+	3f02  photosmart 7550~
+	3f11  PSC-1315/PSC-1317
+	4002  PhotoSmart 720 / PhotoSmart 935 (storage)
+	4004  cp1160
+	4102  PhotoSmart 618
+	4105  ScanJet 4370
+	4111  Officejet 7200 series
+	4117  Printing Support
+	4202  PhotoSmart 812
+	4205  Scanjet G3010
+	4211  Officejet 7300 series
+	4217  EWS CM1015
+	4302  PhotoSmart 850 (ptp)
+	4311  Officejet 7400 series
+	4317  Color LaserJet CM1017
+	4402  PhotoSmart 935 (ptp)
+	4417  EWS UPD
+	4502  PhotoSmart 945 (PTP mode)
+	4505  ScanJet G4010
+	4511  Photosmart 2600
+	4517  EWS UPD
+	4605  ScanJet G4050
+	4611  Photosmart 2700
+	4811  PSC 1600
+	4911  PSC 2350
+	4b11  Officejet 6200
+	4c11  PSC 1500 series
+	4c17  EWS UPD
+	4d11  PSC 1400
+	4d17  EWS UPD
+	4e11  Photosmart 2570 series
+	4f11  Officejet 5600 (USBHUB)
+	5004  DeskJet 995c
+	5011  Photosmart 3100 Series
+	5017  EWS UPD
+	5111  Photosmart 3200 Series
+	5211  Photosmart 3300 Series
+	5311  Officejet 6300
+	5411  Officejet 4300
+	5511  Deskjet F300 series
+	5611  PhotoSmart C3180
+	5617  LaserJet M1120 MFP
+	5711  Photosmart C4100 series
+	5717  LaserJet M1120n MFP
+	5811  Photosmart C5100 series
+	5817  LaserJet M1319f MFP
+	5911  PhotoSmart C6180
+	5a11  Photosmart C7100 series
+	5b11  Officejet J2100 Series
+	5c11  Photosmart C4200 Printer series
+	5d11  Photosmart C5200 series
+	5e11  Photosmart D7400 series
+	6004  DeskJet 5550
+	6102  Hewlett Packard Digital Camera
+	6104  DeskJet 5650c
+	6117  color LaserJet 3550
+	6202  PhotoSmart 215
+	6204  DeskJet 5150c
+	6217  Color LaserJet 4700
+	6302  PhotoSmart 318/612
+	6317  Color LaserJet 4730mfp
+	6402  PhotoSmart 715 (ptp)
+	6411  Photosmart C8100 series
+	6417  LaserJet 5200
+	6502  PhotoSmart 120 (ptp)
+	6511  Photosmart C7200 series
+	6602  PhotoSmart 320
+	6611  Photosmart C4380 series
+	6617  LaserJet 5200L
+	6702  PhotoSmart 720 (ptp)
+	6717  Color LaserJet 3000
+	6802  PhotoSmart 620 (ptp)
+	6811  Photosmart D5300 series
+	6817  Color LaserJet 3800
+	6911  Photosmart D7200 series
+	6917  Color LaserJet 3600
+	6a02  PhotoSmart 735 (ptp)
+	6a11  Photosmart C6200 series
+	6a17  LaserJet 4240
+	6b02  PhotoSmart R707 (PTP mode)
+	6c17  Color LaserJet 4610
+	6f17  Color LaserJet CP6015 series
+	7004  DeskJet 3320c
+	7102  PhotoSmart 635 (PTP mode)
+	7104  DeskJet 3420c
+	7117  CM8060 Color MFP with Edgeline Technology
+	7202  PhotoSmart 43x (ptp)
+	7204  DeskJet 36xx
+	7217  LaserJet M5035 MFP
+	7302  PhotoSmart M307 (PTP mode)
+	7304  DeskJet 35xx
+	7317  LaserJet P3005
+	7404  Printing Support
+	7417  LaserJet M4345 MFP
+	7504  Printing Support
+	7517  LaserJet M3035 MFP
+	7604  Deskjet 3940
+	7617  LaserJet P3004
+	7702  PhotoSmart R817 (PTP mode)
+	7704  Deskjet D4100
+	7717  CM8050 Color MFP with Edgeline Technology
+	7804  Deskjet D1360
+	7817  Color LaserJet CP3505
+	7917  LaserJet M5025 MFP
+	7a02  PhotoSmart M415 (PTP mode)
+	7a17  LaserJet M3027 MFP
+	7b02  PhotoSmart M23 (PTP mode)
+	7b17  Color LaserJet CP4005
+	7c17  Color LaserJet CM6040 Series
+	7d04  Deskjet F2100 Printer series
+	7d17  Color LaserJet CM4730 MFP
+	7e04  Deskjet F4100 Printer series
+	8017  LaserJet P4515
+	8104  Printing Support
+	8117  LaserJet P4015
+	811c  Ethernet HN210E
+	8204  Printing Support
+	8217  LaserJet P4014
+	8317  LaserJet M9050 MFP
+	8404  Deskjet 6800 Series
+	8417  LaserJet M9040 MFP
+	8504  Deskjet 6600 Series
+	8604  Deskjet 5440
+	8704  deskjet 5900 series
+	8804  Deskjet 6980 Series
+	8904  Deskjet 6940 Series
+	9002  Photosmart M437
+	9102  Photosmart M537
+	9302  Photosmart R930 series
+	9402  Photosmart R837
+	9502  Photosmart R840 series
+	9602  Photosmart M730 series
+	9702  Photosmart R740 series
+	9802  Photosmart Mz60 series
+	9902  Photosmart M630 series
+	9a02  Photosmart E330 series
+	9b02  Photosmart M540 series
+	9c02  Photosmart M440 series
+	a004  DeskJet 5850c
+	b002  photosmart 7200 series
+	b102  photosmart 7200 series
+	b202  photosmart 7600 series
+	b302  photosmart 7600 series
+	b402  photosmart 7700 series
+	b502  photosmart 7700 series
+	b602  photosmart 7900 series
+	b702  photosmart 7900 series
+	b802  Photosmart 7400 Series
+	b902  Photosmart 7800 Series
+	ba02  Photosmart 8100 Series
+	bb02  Photosmart 8400 Series
+	bc02  Photosmart 8700 Series
+	bd02  Photosmart Pro B9100 series
+	bef4  NEC Picty760
+	c002  Photosmart 7800 Series
+	c102  Photosmart 8000 Series
+	c202  Photosmart 8200 Series
+	c302  Deskjet D2300
+	c402  Photosmart D5100 series
+	c502  Photosmart D6100 series
+	c602  Photosmart D7100 series
+	c702  Photosmart D7300 series
+	c802  Photosmart D5060 Printer
+	d104  Bluetooth Dongle
+	efbe  NEC Picty900
+	f0be  NEC Picty920
+	f1be  NEC Picty800
+03f1  Genoa Technology
+03f2  Oak Technology, Inc.
+03f3  Adaptec, Inc.
+	0020  AWN-8020 WLAN
+	0080  AVC-1100 Audio Capture
+	0083  AVC-2200 Device
+	0087  AVC-2210 Loader
+	0088  AVC-2210 Device
+	008b  AVC-2310 Loader
+	008c  AVC-2310 Device
+	0094  eHome Infrared Receiver
+	009b  AVC-1410 GameBridge TV NTSC
+	2000  USBXchange
+	2001  USBXchange Adapter
+	2002  USB2-Xchange
+	2003  USB2-Xchange Adapter
+	adcc  Composite Device Support
+03f4  Diebold, Inc.
+03f5  Siemens Electromechanical
+03f8  Epson Imaging Technology Center
+03f9  KeyTronic Corp.
+	0100  Keyboard
+	0101  Keyboard
+	0102  Keyboard Mouse
+03fb  OPTi, Inc.
+03fc  Elitegroup Computer Systems
+03fd  Xilinx, Inc.
+03fe  Farallon Comunications
+0400  National Semiconductor Corp.
+	0807  Bluetooth Dongle
+	080a  Bluetooth Device
+	1000  Mustek BearPaw 1200 Scanner
+	1001  Mustek BearPaw 2400 Scanner
+	1237  Hub
+	a000  Smart Display Reference Device
+	c35b  Printing Support
+0401  National Registry, Inc.
+0402  ALi Corp.
+	5462  M5462 IDE Controller
+	5602  Video Camera Controller
+	5603  USB 2.0 Q-tec Webcam 300
+	5621  USB 2.0 Storage Device
+	5623  VistaScan Astra 3600
+	5627  Welland ME-740PS USB2 3.5" Power Saving Enclosure
+	5632  USB 2.0 Host-to-Host Link
+	5635  USB 2.0 Flash Card Reader
+	5636  USB 2.0 Storage Device
+	5637  M5637 IDE Controller
+0403  Future Technology Devices International, Ltd
+	0000  H4SMK 7 Port Hub
+	0232  Serial Converter
+	6001  FT232 USB-Serial (UART) IC
+	6007  Serial Converter
+	6008  Serial Converter
+	6009  Serial Converter
+	6010  FT2232C Dual USB-UART/FIFO IC
+	8040  4 Port Hub
+	8070  7 Port Hub
+	8370  7 Port Hub
+	8371  PS/2 Keyboard And Mouse
+	8372  FT8U100AX Serial Port
+	c630  lcd2usb interface
+	c7d0  RR-CirKits LocoBuffer-USB
+	cc48  product FTDI TACTRIX_OPENPORT_13M 0xcc48 OpenPort 1.3 Mitsubishi
+	cc49  product FTDI TACTRIX_OPENPORT_13S 0xcc49 OpenPort 1.3 Subaru
+	cc4a  product FTDI TACTRIX_OPENPORT_13U 0xcc4a OpenPort 1.3 Universal
+	d010  SCS PTC-IIusb
+	d011  SCS Position-Tracker/TNC
+	d012  SCS DRAGON 1
+	d013  SCS DRAGON 1
+	d6f8  UNI Black BOX
+	e700  Elster Unicom III Optical Probe
+	e888  Expert ISDN Control USB
+	e889  USB-RS232 OptoBridge
+	e88a  Expert mouseCLOCK USB II
+	e88b  Precision Clock MSF USB
+	e88c  Expert mouseCLOCK USB II HBG
+	ea90  Eclo 1-Wire Adapter
+	f208  Papenmeier Braille-Display
+	f680  Suunto Sports Instrument
+	f918  Ant8 Logic Probe
+	fa00  Matrix Orbital USB Serial
+	fa01  Matrix Orbital MX2 or MX3
+	fa02  Matrix Orbital MX4 or MX5
+	fa03  Matrix Orbital VK/LK202 Family
+	fa04  Matrix Orbital VK/LK204 Family
+	fc08  Crystalfontz CFA-632 USB LCD
+	fc09  Crystalfontz CFA-634 USB LCD
+	fc0b  Crystalfontz CFA-633 USB LCD
+	fc0c  Crystalfontz CFA-631 USB LCD
+	fc0d  Crystalfontz CFA-635 USB LCD
+	fc82  SEMC DSS-20 SyncStation
+	fd48  ShipModul MiniPlex-4xUSB NMEA Multiplexer
+	ff08  ToolHouse LoopBack Adapter
+	ff18  Logbook Bus
+	ff19  Logbook Bus
+	ff1a  Logbook Bus
+	ff1b  Logbook Bus
+	ff1c  Logbook Bus
+	ff1d  Logbook Bus
+	ff1e  Logbook Bus
+	ff1f  Logbook Bus
+0404  NCR Corp.
+	0202  78XX Scanner
+	0203  78XX Scanner - Embedded System
+	0310  K590 Printer, Self-Service
+	0311  7167 Printer, Receipt/Slip
+	0312  7197 Printer Receipt
+	0320  5932-USB Keyboard
+	0321  5953-USB Dynakey
+	0322  5932-USB Enhanced Keyboard
+	0323  5932-USB Enhanced Keyboard, Flash-Recovery/Download
+	0324  5953-USB Enhanced Dynakey
+	0325  5953-USB Enhanced Dynakey Flash-Recovery/Download
+	0328  K016: USB-MSR ISO 3-track MSR: POS Standard (See HID pages)
+	0329  K018: USB-MSR JIS 2-Track MSR: POS Standard
+	032a  K016: USB-MSR ISO 3-Track MSR: HID Keyboard Mode
+	032b  K016/K018: USB-MSR Flash-Recovery/Download
+0405  Synopsys, Inc.
+0406  Fujitsu-ICL Computers
+0407  Fujitsu Personal Systems, Inc.
+0408  Quanta Computer, Inc.
+0409  NEC Corp.
+	0011  PC98 Series Layout Keyboard Mouse
+	0012  ATerm IT75DSU ISDN TA
+	0014  Japanese Keyboard
+	0019  109 Japanese Keyboard with Bus-Powered Hub
+	001a  PC98 Series Layout Keyboard with Bus-Powered Hub
+	0025  Mini Keyboard with Bus-Powered Hub
+	0027  MultiSync Monitor
+	002c  Clik!-USB Drive
+	0034  109 Japanese Keyboard with One-touch start buttons
+	003f  Wireless Keyboard with One-touch start buttons
+	0040  Floppy
+	004e  SuperScript 1400 Series
+	004f  Wireless Keyboard with One-touch start buttons
+	0058  HighSpeed Hub
+	0059  HighSpeed Hub
+	005a  HighSpeed Hub
+	006a  Conceptronic USB Harddisk Box
+	0081  SuperScript 1400 Series
+	0082  SuperScript 1400 Series
+	0094  Japanese Keyboard with One-touch start buttons
+	0095  Japanese Keyboard
+	00a9  AtermIT21L 128K Support Standard
+	00aa  AtermITX72 128K Support Standard
+	00ab  AtermITX62 128K Support Standard
+	00ac  AtermIT42 128K Support Standard
+	00ae  INSMATEV70G-MAX Standard
+	00af  AtermITX70 128K Support Standard
+	00b0  AtermITX80 128K Support Standard
+	00b2  AtermITX80D 128K Support Standard
+	00c0  Wireless Remocon
+	00f7  Smart Display PK-SD10
+	011d  e228 Mobile Phone
+	0203  HID Audio Controls
+	55aa  Hub
+	55ab  Hub [iMac/iTouch kbd]
+	8010  Intellibase Hub
+	8011  Intellibase Hub
+	efbe  P!cty 900 [HP DJ]
+	f0be  P!cty 920 [HP DJ 812c]
+040a  Kodak Co.
+	0001  DVC-323
+	0002  DVC-325
+	0100  DC-220
+	0110  DC-260
+	0111  DC-265
+	0112  DC-290
+	0120  DC-240
+	0121  DC-240 (PTP firmware)
+	0130  DC-280
+	0131  DC-5000
+	0132  DC-3400
+	0140  DC-4800
+	0160  DC4800
+	0170  DX3900
+	0200  Digital Camera
+	0300  EZ-200
+	0400  MC3
+	0402  Digital Camera
+	0403  Z7590
+	0500  DX3500
+	0510  DX3600
+	0525  DX3215
+	0530  DX3700
+	0535  EasyShare CX4230 Camera
+	0540  LS420
+	0550  DX4900
+	0555  DX4330
+	0560  CX4200
+	0565  CX4210
+	0566  CX4300
+	0567  LS753
+	0568  LS443
+	0569  LS663
+	0570  DX6340
+	0571  CX6330
+	0572  DX6440
+	0573  CX6230
+	0574  CX6200
+	0575  DX6490
+	0576  DX4530
+	0577  DX7630
+	0578  CX7300/CX7310
+	0579  CX7220
+	057a  CX7330
+	057b  CX7430
+	057c  CX7530
+	057d  DX7440
+	057e  C300
+	057f  DX7590
+	0580  Z730
+	0581  Digital Camera
+	0582  Digital Camera
+	0583  Digital Camera
+	0584  CX6445
+	0585  Digital Camera
+	0586  CX7525
+	0587  Digital Camera
+	0588  Digital Camera
+	0589  EasyShare C360
+	058a  C310
+	058b  Digital Camera
+	058c  C330
+	058d  C340
+	058e  V530
+	058f  V550
+	0590  Digital Camera
+	0591  Digital Camera
+	0592  Digital Camera
+	0593  Digital Camera
+	0594  Digital Camera
+	0595  Digital Camera
+	0596  Digital Camera
+	0597  Digital Camera
+	0598  Digital Camera
+	0599  Digital Camera
+	059a  Digital Camera
+	059b  Digital Camera
+	059c  Digital Camera
+	059d  Digital Camera
+	059e  Digital Camera
+	059f  Digital Camera
+	05a0  Digital Camera
+	05a1  Digital Camera
+	05a2  Digital Camera
+	05a3  Digital Camera
+	05a4  Digital Camera
+	05a5  Digital Camera
+	05a6  Digital Camera
+	05a7  Digital Camera
+	05a8  Digital Camera
+	05a9  Digital Camera
+	05aa  Digital Camera
+	05ab  Digital Camera
+	05ac  Digital Camera
+	05ad  Digital Camera
+	05ae  Digital Camera
+	05af  Digital Camera
+	05b0  Digital Camera
+	05b1  Digital Camera
+	05b2  Digital Camera
+	05b3  EasyShare Z710 Camera
+	05b4  Digital Camera
+	05b5  Digital Camera
+	05b6  Digital Camera
+	05b7  Digital Camera
+	05b8  Digital Camera
+	05b9  Digital Camera
+	05ba  Digital Camera
+	05bb  Digital Camera
+	05bc  Digital Camera
+	05bd  Digital Camera
+	05be  Digital Camera
+	05bf  Digital Camera
+	05c0  Digital Camera
+	05c1  Digital Camera
+	05c2  Digital Camera
+	05c3  Digital Camera
+	05c4  Digital Camera
+	05c5  Digital Camera
+	4000  InkJet Color Printer
+	410d  EasyShare G600 Printer Dock
+	5010  Wireless Adapter
+	5012  DBT-220 Bluetooth Adapter
+	6001  i30
+	6002  i40
+	6003  i50
+	6004  i60
+	6005  i80
+040b  Weltrend Semiconductor
+	6510  Weltrend Bar Code Reader
+	6520  XBOX Xploder
+040c  VTech Computers, Ltd
+040d  VIA Technologies, Inc.
+	3184  VNT VT6656 USB-802.11 Wireless LAN Adapter
+	6205  USB 2.0 Card Reader
+040e  MCCI
+040f  Echo Speech Corp.
+0411  MelCo., Inc.
+	0001  LUA-TX Ethernet [pegasus]
+	0005  LUA-TX Ethernet
+	0006  WLI-USB-L11 Wireless LAN Adapter
+	0009  LUA2-TX Ethernet
+	000b  WLI-USB-L11G-WR Wireless LAN Adapter
+	000d  WLI-USB-L11G Wireless LAN Adapter
+	0012  LUA-KTX Ethernet
+	0013  USB2-IDE Adapter
+	0016  WLI-USB-S11 802.11b Adapter
+	0018  USB2-IDE Adapter
+	001c  USB-IDE Bridge: DUB-PxxG
+	0027  WLI-USB-KS11G 802.11b Adapter
+	003d  LUA-U2-KTX Ethernet
+	0044  WLI-USB-KB11 Wireless LAN Adapter
+	004d  WLI-USB-B11 Wireless LAN Adapter
+	0050  WLI2-USB2-G54 Wireless LAN Adapter
+	005e  WLI-U2-KG54-YB WLAN
+	0065  Python2 WDM Encoder
+	0066  WLI-U2-KG54 WLAN
+	0067  WLI-U2-KG54-AI WLAN
+	008b  Nintendo Wi-Fi
+	0091  WLI-U2-KAMG54 Wireless LAN Adapter
+	0092  WLI-U2-KAMG54 Bootloader
+	0097  WLI-U2-KG54-BB
+	00a9  WLI-U2-AMG54HP Wireless LAN Adapter
+	00aa  WLI-U2-AMG54HP Bootloader
+	00b3  PC-OP-RS1 RemoteStation
+	00ca  802.11n Network Adapter
+	00cb  WLI-U2-G300N 802.11n Adapter
+	00d8  WLI-U2-SG54HP
+	00d9  WLI-U2-G54HP
+	00da  WLI-U2-KG54L
+0412  Award Software International
+0413  Leadtek Research, Inc.
+	1310  WinFast TV - NTSC + FM
+	1311  WinFast TV - NTSC + MTS + FM
+	1312  WinFast TV - PAL BG + FM
+	1313  WinFast TV - PAL BG+TXT + FM
+	1314  WinFast TV Audio - PHP PAL I
+	1315  WinFast TV Audio - PHP PAL I+TXT
+	1316  WinFast TV Audio - PHP PAL DK
+	1317  WinFast TV Audio - PHP PAL DK+TXT
+	1318  WinFast TV - PAL I/DK + FM
+	1319  WinFast TV - PAL N + FM
+	131a  WinFast TV Audio - PHP SECAM LL
+	131b  WinFast TV Audio - PHP SECAM LL+TXT
+	131c  WinFast TV Audio - PHP SECAM DK
+	131d  WinFast TV - SECAM DK + TXT + FM
+	131e  WinFast TV - NTSC Japan + FM
+	1320  WinFast TV - NTSC
+	1321  WinFast TV - NTSC + MTS
+	1322  WinFast TV - PAL BG
+	1323  WinFast TV - PAL BG+TXT
+	1324  WinFast TV Audio - PHP PAL I
+	1325  WinFast TV Audio - PHP PAL I+TXT
+	1326  WinFast TV Audio - PHP PAL DK
+	1327  WinFast TV Audio - PHP PAL DK+TXT
+	1328  WinFast TV - PAL I/DK
+	1329  WinFast TV - PAL N
+	132a  WinFast TV Audio - PHP SECAM LL
+	132b  WinFast TV Audio - PHP SECAM LL+TXT
+	132c  WinFast TV Audio - PHP SECAM DK
+	132d  WinFast TV - SECAM DK + TXT
+	132e  WinFast TV - NTSC Japan
+	6023  EMP Audio Device
+	6024  WinFast PalmTop/Novo TV Video
+	6025  WinFast DTV Dongle (cold state)
+	6026  WinFast DTV Dongle (warm state)
+	6125  WinFast DTV Dongle
+	6126  WinFast DTV Dongle BDA Driver
+	6f00  WinFast DTV Dongle (STK7700P based)
+0414  Giga-Byte Technology Co., Ltd
+0416  Winbond Electronics Corp.
+	0035  W89C35 802.11bg WLAN Adapter
+	0101  Hub
+	0961  AVL Flash Card Reader
+	3810  Smart Card Controller
+	3811  Generic Controller - Single interface
+	3812  Smart Card Controller_2Interface
+	3813  Panel Display
+	5518  4-Port Hub
+	551a  PC Sync Keypad
+	551b  PC Async Keypad
+	551c  Sync Tenkey
+	551d  Async Tenkey
+	551e  Keyboard
+	551f  Keyboard w/ Sys and Media
+	5521  Keyboard
+	6481  16-bit Scanner
+	7721  Memory Stick Reader/Writer
+	7722  Memory Stick Reader/Writer
+	7723  SD Card Reader
+0417  Symbios Logic
+0418  AST Research
+0419  Samsung Info. Systems America, Inc.
+	0001  IrDA Remote Controller
+	3001  Xerox P1202 Laser Printer
+	3003  Olivetti PG L12L
+	3201  Docuprint P8ex
+	3404  SCX-5x12 Series
+	3406  MFP 830 Series
+	3407  ML-912
+	3601  InkJet Color Printer
+	3602  InkJet Color Printer
+	4602  Remote NDIS Network Device
+	8001  Hub
+	8002  SyncMaster 757DFX HID Device
+041a  Phoenix Technologies, Ltd
+041b  d'TV
+041d  S3, Inc.
+041e  Creative Technology, Ltd
+	1002  Nomad II
+	1003  Blaster GamePad Cobra
+	1050  GamePad Cobra
+	3000  SoundBlaster Extigy
+	3002  SB External Composite Device
+	3010  SoundBlaster MP3+
+	3014  SB External Composite Device
+	3015  Sound Blaster Digital Music LX
+	3020  SoundBlaster Audigy 2 NX
+	3030  SB External Composite Device
+	3040  SoundBlaster Live! 24-bit External SB0490
+	3060  Sound Blaster Audigy 2 ZS External
+	3061  SoundBlaster Audigy 2 ZS Video Editor
+	3090  Sound Blaster Digital Music SX
+	3f02  E-Mu 0202
+	3f04  E-Mu 0404
+	4003  VideoBlaster WebCam Go Plus [W9967CF]
+	4004  Nomad II MG
+	4005  WebCam Blaster Go ES
+	4007  Go Mini
+	400a  PC-Cam 300
+	400b  PC-Cam 600
+	400c  WebCam 5 [pwc]
+	400d  WebCam PD1001
+	400f  PC-CAM 550 (Composite)
+	4011  WebCam PRO eX
+	4012  PC-CAM350
+	4013  PC-Cam 750
+	4015  CardCam Value
+	4016  CardCam
+	4017  WebCam Mobile
+	4018  WebCam Vista
+	4019  Audio Device
+	401c  WebCam NX [PD1110]
+	401d  WebCam NX Ultra
+	401e  WebCam NX Pro
+	401f  Webcam Notebook
+	4020  WebCam NX
+	4021  WebCam NX Ultra
+	4022  WebCam NX Pro
+	4028  Vista Plus cam [VF0090]
+	402f  DC-CAM 3000Z
+	4034  WebCam Instant
+	4035  WebCam Instant
+	4036  Webcam Live!/Live! Pro
+	4037  WebCam Live!
+	4038  ORITE CCD Webcam(PC370R)
+	4039  WebCam Live! Effects
+	403a  WebCam NX Pro 2
+	403c  WebCam Live! Ultra
+	403d  WebCam Notebook Ultra
+	403e  WebCam Vista Plus
+	4041  WebCam Live! Motion
+	4045  Live! Cam Voice
+	4049  Live! Cam Voice
+	4051  Live! Cam Notebook Pro
+	4052  Live! Cam Vista IM
+	4053  Live! Cam Video IM
+	4054  Live! Cam Video IM
+	4055  Live! Cam Video IM Pro
+	4056  Live! Cam Video IM Pro
+	4057  Live! Cam Optia
+	4058  Live! Cam Optia AF
+	4068  WebCam Live! Notebook
+	4100  Nomad Jukebox 2
+	4101  Nomad Jukebox 3
+	4102  NOMAD MuVo^2
+	4106  Nomad MuVo
+	4107  NOMAD MuVo
+	4108  Nomad Jukebox Zen
+	4109  Nomad Jukebox Zen NX
+	410b  Nomad Jukebox Zen USB 2.0
+	410c  Nomad MuVo NX
+	410f  NOMAD MuVo^2 (Flash)
+	4110  Nomad Jukebox Zen Xtra
+	4111  Dell Digital Jukebox
+	4116  MuVo^2
+	4117  Nomad MuVo TX
+	411b  Zen Touch
+	411c  Nomad MuVo USB 2.0
+	411d  Zen
+	411e  Zen Micro
+	4123  Zen Portable Media Center
+	4124  MuVo^2 FM (uHDD)
+	4126  Dell DJ (2nd gen)
+	4127  Dell DJ
+	4128  NOMAD Jukebox Zen Xtra (mtp)
+	412b  MuVo N200 with FM radio
+	4130  Zen Micro (mtp)
+	4131  Zen Touch (mtp)
+	4133  Mass Storage Device
+	4134  Zen Neeon
+	4136  Zen Sleek
+	4137  Zen Sleek (mtp)
+	4139  Zen Nano Plus
+	413c  Zen MicroPhoto
+	4151  Zen Vision:M (mtp)
+	4155  Zen Stone plus
+	500f  Broadband Blaster 8012U-V
+	5015  TECOM Bluetooth Device
+	ffff  WebCam Live! Ultra
+041f  LCS Telegraphics
+0420  Chips and Technologies
+	1307  Celly SIM Card Reader
+0421  Nokia Mobile Phones
+	0018  6288 GSM Smartphone
+	0019  6288 GSM Smartphone (imaging mode)
+	001a  6288 GSM Smartphone (file transfer mode)
+	0024  5610 XpressMusic (Storage mode)
+	0025  5610 XpressMusic (PC-Suite mode)
+	0028  5610 XpressMusic (Imaging mode)
+	0096  N810 Internet Tablet
+	0103  ADL Flashing Engine AVALON Parent
+	0104  ADL Re-Flashing Engine Parent
+	0105  E-61 (Firmware update mode)
+	0106  ROM Parent
+	0400  7600 Phone Parent
+	0401  6650 GSM Phone
+	0402  6255 Phone Parent
+	0404  5510
+	0405  9500 GSM Communicator
+	0407  Music Player HDR-1(tm)
+	040b  N-Gage GSM Phone
+	040d  6620 Phone Parent
+	040e  6651 Phone Parent
+	040f  6230 GSM Phone
+	0410  6630 Imaging Smartphone
+	0411  7610 Phone Parent
+	0413  6260 Phone Parent
+	0414  7370
+	0415  9300 GSM Smartphone
+	0416  6170 Phone Parent
+	0417  7270 Phone Parent
+	0418  E-70 (PC-Suite mode)
+	0419  E-60 (PC-Suite mode)
+	041a  9500 GSM Communicator (RNDIS)
+	041b  9300 GSM Smartphone (RNDIS)
+	041c  7710 Phone Parent
+	041d  6670 Phone Parent
+	041e  6680
+	041f  6235 Phone Parent
+	0421  3230 Phone Parent
+	0422  6681 Phone Parent
+	0423  6682 Phone Parent
+	0428  6230i Modem
+	0429  6230i MultiMedia Card
+	0431  770 Internet Tablet
+	0432  N90 Phone Parent
+	0435  E-70 (IP Passthrough/RNDIS mode)
+	0436  E-60 (IP Passthrough/RNDIS mode)
+	0437  6265 Phone Parent
+	043a  N70 USB Phone Parent
+	043b  3155 Phone Parent
+	043c  6155 Phone Parent
+	043d  6270 Phone Parent
+	0443  N70 Phone Parent
+	044c  NM850iG Phone Parent
+	044d  E-61 (PC Suite mode)
+	044e  E-61 (Data Exchange mode)
+	044f  E-61 (IP Passthrough/RNDIS mode)
+	0453  9300 Phone Parent
+	0456  6111 Phone Parent
+	045a  6280 Phone Parent
+	045d  6282 Phone Parent
+	046e  6110 Navigator
+	0485  MTP Device
+	04c3  N800 Internet Tablet
+	04ce  E90 Communicator (PC-Suite mode)
+	04cf  E90 Communicator (Storage mode)
+	04f9  6300 (PC-Suite mode)
+	0600  Digital Pen SU-1B
+	0800  Connectivity Cable DKU-5
+	0801  Data Cable DKU-6
+	0802  CA-42 Phone Parent
+0422  ADI Systems, Inc.
+0423  Computer Access Technology Corp.
+	000a  NetMate Ethernet
+	000c  NetMate2 Ethernet
+	000d  USB Chief Analyzer
+	0100  Generic Universal Protocol Analyzer
+	0101  UPA USBTracer
+	0200  Generic 10K Universal Protocol Analyzer
+	020a  PETracer ML
+	0300  Generic Universal Protocol Analyzer
+	0301  2500H Tracer Trainer
+	030a  PETracer x1
+	1237  Andromeda Hub
+0424  Standard Microsystems Corp.
+	0001  Integrated Hub
+	0acd  Sitecom Internal Multi Memory reader/writer MD-005
+	0fdc  Floppy
+	10cd  Sitecom Internal Multi Memory reader/writer MD-005
+	2020  USB Hub
+	20cd  Sitecom Internal Multi Memory reader/writer MD-005
+	20fc  6-in-1 Card Reader
+	2228  9-in-2 Card Reader
+	223a  8-in-1 Card Reader
+	2503  USB 2.0 Hub
+	2504  USB 2.0 Hub
+	2524  USB MultiSwitch Hub
+0425  Motorola Semiconductors HK, Ltd
+	0101  G-Tech Wireless Mouse & Keyboard
+0426  Integrated Device Technology, Inc.
+	0426  WDM Driver
+0427  Motorola Electronics Taiwan, Ltd
+0428  Advanced Gravis Computer Tech, Ltd
+	4001  GamePad Pro
+0429  Cirrus Logic
+042a  Ericsson Austrian, AG
+042b  Intel Corp.
+	9316  8x931Hx Customer Hub
+042c  Innovative Semiconductors, Inc.
+042d  Micronics
+042e  Acer, Inc.
+	0380  MP3 Player
+042f  Molex, Inc.
+0430  Sun Microsystems, Inc.
+	0002  109 Keyboard
+	0005  Type 6 Keyboard
+	000a  109 Japanese Keyboard
+	000b  109 Japanese Keyboard
+	0082  109 Japanese Keyboard
+	0083  109 Japanese Keyboard
+	0100  3-button Mouse
+	36ba  Bus Powered Hub
+0431  Itac Systems, Inc.
+	0100  Mouse-Trak 3-button Track Ball
+0432  Unisys Corp.
+0433  Alps Electric, Inc.
+	1101  IBM Game Controller
+	abab  Keyboard
+0434  Samsung Info. Systems America, Inc.
+0435  Hyundai Electronics America
+0436  Taugagreining HF
+	0005  CameraMate (DPCM_USB)
+0437  Framatome Connectors USA
+0438  Advanced Micro Devices, Inc.
+0439  Voice Technologies Group
+043d  Lexmark International, Inc.
+	0001  Laser Printer
+	0002  Optra E310 Printer
+	0003  Laser Printer
+	0004  Laser Printer
+	0005  Laser Printer
+	0006  Laser Printer
+	0007  Laser Printer
+	0008  Inkjet Color Printer
+	0009  Optra S2450 Printer
+	000a  Laser Printer
+	000b  Inkjet Color Printer
+	000c  Optra E312 Printer
+	000d  Laser Printer
+	000e  Laser Printer
+	000f  Laser Printer
+	0010  Laser Printer
+	0011  Laser Printer
+	0012  Inkjet Color Printer
+	0013  Inkjet Color Printer
+	0014  InkJet Color Printer
+	0015  InkJet Color Printer
+	0016  Z12 Color Jetprinter
+	0017  Z32 printer
+	0018  Z52 Printer
+	0019  Forms Printer
+	001a  Z65 Printer
+	001b  InkJet Photo Printer
+	001c  Kodak Personal Picture Maker 200 Printer
+	001d  InkJet Color Printer
+	001e  InkJet Photo Printer
+	001f  Kodak Personal Picture Maker 200 Card Reader
+	0020  Z51 Printer
+	0021  Z33 Printer
+	0022  InkJet Color Printer
+	0023  Laser Printer
+	0024  Laser Printer
+	0025  InkJet Color Printer
+	0026  InkJet Color Printer
+	0027  InkJet Color Printer
+	0028  InkJet Color Printer
+	0029  Scan Print Copy
+	002a  Scan Print Copy
+	002b  Scan Print Copy
+	002c  Scan Print Copy
+	002d  X70/X73 Scan/Print/Copy
+	002e  Scan Print Copy
+	002f  Scan Print Copy
+	0030  Scan Print Copy
+	0031  Scan Print Copy
+	0032  Scan Print Copy
+	0033  Scan Print Copy
+	0034  Scan Print Copy
+	0035  Scan Print Copy
+	0036  Scan Print Copy
+	0037  Scan Print Copy
+	0038  Scan Print Copy
+	0039  Scan Print Copy
+	003a  Scan Print Copy
+	003b  Scan Print Copy
+	003c  Scan Print Copy
+	003d  X83 Scan/Print/Copy
+	003e  Scan Print Copy
+	003f  Scan Print Copy
+	0040  Scan Print Copy
+	0041  Scan Print Copy
+	0042  Scan Print Copy
+	0043  Scan Print Copy
+	0044  Scan Print Copy
+	0045  Scan Print Copy
+	0046  Scan Print Copy
+	0047  Scan Print Copy
+	0048  Scan Print Copy
+	0049  Scan Print Copy
+	004a  Scan Print Copy
+	004b  Scan Print Copy
+	004c  Scan Print Copy
+	004d  Laser Printer
+	004e  Laser Printer
+	004f  InkJet Color Printer
+	0050  InkJet Color Printer
+	0051  Laser Printer
+	0052  Laser Printer
+	0053  InkJet Color Printer
+	0054  InkJet Color Printer
+	0057  Z35 Printer
+	0058  Laser Printer
+	005a  X63
+	005c  InkJet Color Printer
+	0060  X74/X75 Scanner
+	0061  X74 Hub
+	0065  X5130
+	0069  X74/X75 Printer
+	006d  X125
+	0072  X6170 Printer
+	0073  InkJet Color Printer
+	0078  InkJet Color Printer
+	0079  InkJet Color Printer
+	007a  Generic Hub
+	007b  InkJet Color Printer
+	007c  Lexmark X1110/X1130/X1140/X1150/X1170/X1180/X1185
+	007d  Photo 3150
+	008a  4200 Series
+	008b  InkJet Color Printer
+	008c  to CF/SM/SD/MS Card Reader
+	008e  InkJet Color Printer
+	008f  X422
+	0093  X5250
+	0095  E220 Printer
+	0096  2200 Series
+	0097  P6250
+	0098  7100 Series
+	009e  P910 Series Human Interface Device
+	009f  InkJet Color Printer
+	00a9  IBM Infoprint 1410 MFP
+	00ab  InkJet Color Printer
+	00b2  3300 Series
+	00b8  7300 Series
+	00b9  8300 Series
+	00ba  InkJet Color Printer
+	00bb  2300 Series
+	00bd  Printing Support
+	00be  Printing Support
+	00bf  Printing Support
+	00c0  6300 Series
+	00c1  4300 Series
+	00c7  Printing Support
+	00c8  Printing Support
+	00c9  Printing Support
+	00cb  Printing Support
+	00d0  9300 Series
+	00d3  X340 Scanner
+	00d4  X342n Scanner
+	00d5  Printing Support
+	00d6  X340 Scanner
+	00e8  X642e
+	00e9  2400 Series
+	00f6  3400 Series
+	00f7  InkJet Color Printer
+	00ff  InkJet Color Printer
+	010b  2500 Series
+	010d  3500-4500 Series
+	010f  6500 Series
+	4303  Xerox WorkCentre Pro 412
+043e  LG Electronics USA, Inc.
+	42bd  Flatron 795FT Plus Monitor
+	4a4d  Flatron 915FT Plus Monitor
+	7001  MF-PD100 Soul Digital MP3 Player
+	7013  MP3 Player
+	8484  LPC-U30 Webcam II
+	8585  LPC-UC35 Webcam
+	8888  Electronics VCS Camera II(LPC-U20)
+	9800  Remote Control Receiver_iMON
+	9803  eHome Infrared Receiver
+	9804  DMB Receiver Control
+	9c01  LGE Sync
+043f  RadiSys Corp.
+0440  Eizo Nanao Corp.
+0441  Winbond Systems Lab.
+	1456  Hub
+0442  Ericsson, Inc.
+	abba  Bluetooth Device
+0443  Gateway, Inc.
+	000e  Multimedia Keyboard
+	002e  Millennium Keyboard
+0445  Lucent Technologies, Inc.
+0446  NMB Technologies Corp.
+	6781  Keyboard with PS/2 Mouse Port
+	6782  Keyboard
+0447  Momentum Microsystems
+044a  Shamrock Tech. Co., Ltd
+044b  WSI
+044c  CCL/ITRI
+044d  Siemens Nixdorf AG
+044e  Alps Electric Co., Ltd
+	1104  Japanese Keyboard
+	2002  MD-5500 Printer
+	2014  Bluetooth Device
+	3001  UGTZ4 Bluetooth
+	3002  Bluetooth Device
+	3003  Bluetooth Device
+	3004  Bluetooth Adapter
+	3005  Integrated Bluetooth Device
+	3006  Bluetooth Adapter
+	3007  GlidePoint PS/2 TouchPad
+	300c  Bluetooth Controller (ALPS/UGPZ6)
+	300d  Bluetooth Controller (ALPS/UGPZ6)
+	ffff  Compaq Bluetooth Multiport Module
+044f  ThrustMaster, Inc.
+	0400  HOTAS Cougar
+	a003  Rage 3D Game Pad
+	a01b  PK-GP301 Driving Wheel
+	a0a0  Top Gun Joystick
+	a0a1  Top Gun Joystick (rev2)
+	a0a3  Fusion Digital GamePad
+	a201  PK-GP201 PlayStick
+	b203  360 Modena Pro Wheel
+	b300  Firestorm Dual Power
+	b304  Firestorm Dual Power
+	b307  vibrating Upad
+	b603  force feedback Wheel
+	b605  force feedback Racing Wheel
+	b700  Tacticalboard
+0450  DFI, Inc.
+0451  Texas Instruments, Inc.
+	1234  Bluetooth Device
+	1428  Hub
+	1446  TUSB2040/2070 Hub
+	2036  TUSB2036 Hub
+	2046  TUSB2046 Hub
+	2077  TUSB2077 Hub
+	3410  TUSB3410 Microcontroller
+	3f02  SMC WSKP100 Wi-Fi Phone
+	5409  Frontier Labs NEX IA+ Digital Audio Player
+	6000  AU5 ADSL Modem (pre-reenum)
+	6001  AU5 ADSL Modem
+	6060  RNDIS/BeWAN ADSL2+
+	6070  RNDIS/BeWAN ADSL2+
+	625f  Trekstor USB-Stick 12 CS-D 12 GB
+	dbc0  Device Bay Controller
+	e001  GraphLink
+	e004  TI-89 Titanium Calculator
+	e008  TI-84 Plus Silver Calculator
+	f430  MSP-FET430UIF JTAG Tool
+	ffff  Bluetooth Device
+0452  Mitsubishi Electronics America, Inc.
+	0021  HID Monitor Controls
+	0050  Diamond Pro 900u CRT Monitor
+	0051  Integrated Hub
+0453  CMD Technology
+	6781  NMB Keyboard
+	6783  Chicony Composite Keyboard
+0454  Vobis Microcomputer AG
+0455  Telematics International, Inc.
+0456  Analog Devices, Inc.
+0457  Silicon Integrated Systems Corp.
+	0150  Super Talent 1GB Flash Drive
+	0151  Super Flash 1GB / GXT  64MB Flash Drive
+	0162  SiS162 usb Wireless LAN Adapter
+	0163  802.11 Wireless LAN Adapter
+	5401  Wireless Adapter RO80211GS-USB
+0458  KYE Systems Corp. (Mouse Systems)
+	0001  Mouse
+	0002  Genius NetMouse Pro
+	0003  Genius NetScroll+
+	0006  Easy Mouse+ USB(USB\Vid_0458&Pid;_0006) Mouse
+	000b  NetMouse Wheel(P+U)
+	000c  TACOMA Fingerprint V1.06.01
+	000e  VideoCAM Web
+	0013  TACOMA Fingerprint Mouse V1.06.01
+	001a  Genius WebScroll+
+	0036  Pocket Mouse LE
+	004c  Slimstar Pro Keyboard
+	0056  Ergo 300 Mouse
+	0057  Enhanced Gaming Device
+	0059  Enhanced Laser Device
+	005a  Enhanced Device
+	005b  Enhanced Device
+	005c  Enhanced Laser Gaming Device
+	005d  Enhanced Device
+	0061  Bluetooth Dongle
+	0083  Bluetooth Dongle
+	0100  EasyPen Tablet
+	0101  CueCat
+	1001  Joystick
+	1002  Game Pad
+	1003  Genius VideoCam
+	1004  Flight2000 F-23 Joystick
+	100a  Aashima Technology Trust Sight Fighter Vibration Feedback Joystick
+	2001  ColorPage-Vivid Pro Scanner
+	2004  ColorPage-HR6 V1 Scanner
+	2005  ColorPage-HR6/Vivid3
+	2007  ColorPage-HR6 V2 Scanner
+	2008  ColorPage-HR6 V2 Scanner
+	2009  ColorPage-HR6A Scanner
+	2011  ColorPage-Vivid3x Scanner
+	2012  Plustek Scanner
+	2013  ColorPage-HR7 Scanner
+	2014  ColorPage-Vivid4
+	2015  ColorPage-HR7LE Scanner
+	2016  ColorPage-HR6X Scanner
+	2017  ColorPage-Vivid3xe
+	2018  ColorPage-HR7X
+	2019  ColorPage-HR6X Slim
+	201a  ColorPage-Vivid4xe
+	201b  ColorPage-Vivid4x
+	201c  ColorPage-HR8
+	201d  ColorPage-Vivid 1200 X
+	201e  ColorPage-Slim 1200
+	201f  ColorPage-Vivid 1200 XE
+	2020  ColorPage-Slim 1200 USB2
+	2021  ColorPage-SF600
+	301d  Genius MaxFire MiniPad
+	6001  GF3000F Ethernet Adapter
+	7004  VideoCAM Express
+	7007  VideoCAM Web
+	7009  G-Shot G312 Still Camera Device
+	700c  VideoCAM Web V3
+	700d  G-Shot G511 Composite Device
+	700f  VideoCAM Web V4
+	7012  WebCAM USB2.0
+	7014  VideoCAM Live V3
+	701c  G-Shot G512 Still Camera
+	7020  Sim 321C
+0459  Adobe Systems, Inc.
+045a  SONICblue, Inc.
+	07da  Supra Express 56K modem
+	0b4a  SupraMax 2890 56K Modem [Lucent Atlas]
+	0b68  SupraMax 56K Modem
+	5001  Rio 600 MP3 Player
+	5002  Rio 800 MP3 Player
+	5003  Nike Psa/Play MP3 Player
+	5005  Rio S10 MP3 Player
+	5006  Rio S50 MP3 Player
+	5007  Rio S35 MP3 Player
+	5008  Rio 900 MP3 Player
+	5009  Rio S30 MP3 Player
+	500d  Fuse MP3 Player
+	500e  Chiba MP3 Player
+	500f  Cali MP3 Player
+	5010  Rio S11 MP3 Player
+	501c  Virgin MPF-1000
+	501d  Rio Fuse
+	501e  Rio Chiba
+	501f  Rio Cali
+	503f  Cali256 MP3 Player
+	5202  Rio Riot MP3 Player
+	5210  Rio Karma Music Player
+	5220  Rio Nitrus MP3 Player
+	5221  Rio Eigen
+045b  Hitachi, Ltd
+045d  Nortel Networks, Ltd
+045e  Microsoft Corp.
+	0007  SideWinder Game Pad
+	0008  SideWinder Precision Pro
+	0009  IntelliMouse
+	000b  Natural Keyboard Elite
+	000e  SideWinder® Freestyle Pro
+	0014  Digital Sound System 80
+	001a  SideWinder Precision Racing Wheel
+	001b  SideWinder Force Feedback 2 Joystick
+	001c  Internet Keyboard Pro
+	001d  Natural Keyboard Pro
+	001e  IntelliMouse Explorer
+	0023  Trackball Optical
+	0024  Trackball Explorer
+	0025  IntelliEye Mouse
+	0026  SideWinder GamePad Pro
+	0027  SideWinder PnP GamePad
+	0028  SideWinder Dual Strike
+	0029  IntelliMouse Optical
+	002b  Internet Keyboard Pro
+	002d  Internet Keyboard
+	002f  Integrated Hub
+	0033  Sidewinder Strategic Commander
+	0034  SideWinder Force Feedback Wheel
+	0038  SideWinder Precision 2
+	0039  IntelliMouse Optical
+	003b  SideWinder Game Voice
+	003c  SideWinder Joystick
+	0040  Wheel Mouse Optical
+	0047  IntelliMouse Explorer 3.0
+	0048  Office Keyboard 1.0A
+	0053  Optical Mouse
+	0059  Wireless IntelliMouse Explorer
+	005c  Office Keyboard (106/109)
+	005f  Wireless MultiMedia Keyboard
+	0061  Wireless MultiMedia Keyboard (106/109)
+	0063  Wireless Natural MultiMedia Keyboard
+	0065  Wireless Natural MultiMedia Keyboard (106/109)
+	006a  Wireless Optical Mouse (IntelliPoint)
+	006d  eHome Remote Control Keyboard keys
+	006e  MN510 802.11b Adapter
+	006f  Smart Display Reference Device
+	0070  Wireless MultiMedia Keyboard
+	0071  Wireless MultiMedia Keyboard (106/109)
+	0072  Wireless Natural MultiMedia Keyboard
+	0073  Wireless Natural MultiMedia Keyboard (106/109)
+	007a  10/100 USB NIC
+	007d  Notebook Optical Mouse
+	007e  Wireless Transceiver for Bluetooth
+	0080  Digital Media Pro Keyboard
+	0083  Basic Optical Mouse
+	0084  Basic Optical Mouse
+	008a  Wireless Keyboard and Mouse
+	008b  Dual Receiver Wireless Mouse (IntelliPoint)
+	008c  Wireless Intellimouse Explorer 2.0
+	0095  IntelliMouse Explorer 4.0 (IntelliPoint)
+	009c  Wireless Transceiver for Bluetooth 2.0
+	00a0  eHome Infrared Receiver
+	00b0  Digital Media Pro Keyboard
+	00b9  Wireless Optical Mouse 3.0
+	00bb  Fingerprint Reader
+	00bc  Fingerprint Reader
+	00bd  Fingerprint Reader
+	00c2  Wireless Adapter MN-710
+	00c9  MTP Device
+	00ce  Generic PPC Flash device
+	00d1  Optical Mouse with Tilt Wheel
+	00da  eHome Infrared Receiver
+	00db  Natural Ergonomic Keyboard 4000 V1.0
+	00e1  Wireless Laser Mouse 6000 Reciever
+	00f4  LifeCam VX-6000.
+	00f5  LifeCam VX-3000.
+	00f7  LifeCam VX-1000.
+	00f8  LifeCam NX-6000.
+	0202  Xbox Controller
+	0280  XBox Device
+	0284  Xbox DVD Playback Kit
+	0285  Xbox Controller S
+	0288  Xbox Controller S Hub
+	0289  Xbox Controller S
+	028b  Xbox360 DVD Emulator
+	028d  Xbox360 Memory Unit 64MB
+	028e  Xbox360 Controller
+	028f  Xbox360 Wireless Controller
+	0290  Xbox360 Performance Pipe (PIX)
+	0292  Xbox360 Wireless Networking Adapter
+	029c  Xbox360 HD-DVD Drive
+	029d  Xbox360 HD-DVD Drive
+	029e  Xbox360 HD-DVD Memory Unit
+	0400  Windows Powered Pocket PC 2002
+	0401  Windows Powered Pocket PC 2002
+	0402  Windows Powered Pocket PC 2002
+	0403  Windows Powered Pocket PC 2002
+	0404  Windows Powered Pocket PC 2002
+	0405  Windows Powered Pocket PC 2002
+	0406  Windows Powered Pocket PC 2002
+	0407  Windows Powered Pocket PC 2002
+	0408  Windows Powered Pocket PC 2002
+	0409  Windows Powered Pocket PC 2002
+	040a  Windows Powered Pocket PC 2002
+	040b  Windows Powered Pocket PC 2002
+	040c  Windows Powered Pocket PC 2002
+	040d  Windows Powered Pocket PC 2002
+	040e  Windows Powered Pocket PC 2002
+	040f  Windows Powered Pocket PC 2002
+	0410  Windows Powered Pocket PC 2002
+	0411  Windows Powered Pocket PC 2002
+	0412  Windows Powered Pocket PC 2002
+	0413  Windows Powered Pocket PC 2002
+	0414  Windows Powered Pocket PC 2002
+	0415  Windows Powered Pocket PC 2002
+	0416  Windows Powered Pocket PC 2002
+	0417  Windows Powered Pocket PC 2002
+	0432  Windows Powered Pocket PC 2003
+	0433  Windows Powered Pocket PC 2003
+	0434  Windows Powered Pocket PC 2003
+	0435  Windows Powered Pocket PC 2003
+	0436  Windows Powered Pocket PC 2003
+	0437  Windows Powered Pocket PC 2003
+	0438  Windows Powered Pocket PC 2003
+	0439  Windows Powered Pocket PC 2003
+	043a  Windows Powered Pocket PC 2003
+	043b  Windows Powered Pocket PC 2003
+	043c  Windows Powered Pocket PC 2003
+	043d  Becker Traffic Assist Highspeed 7934
+	043e  Windows Powered Pocket PC 2003
+	043f  Windows Powered Pocket PC 2003
+	0440  Windows Powered Pocket PC 2003
+	0441  Windows Powered Pocket PC 2003
+	0442  Windows Powered Pocket PC 2003
+	0443  Windows Powered Pocket PC 2003
+	0444  Windows Powered Pocket PC 2003
+	0445  Windows Powered Pocket PC 2003
+	0446  Windows Powered Pocket PC 2003
+	0447  Windows Powered Pocket PC 2003
+	0448  Windows Powered Pocket PC 2003
+	0449  Windows Powered Pocket PC 2003
+	044a  Windows Powered Pocket PC 2003
+	044b  Windows Powered Pocket PC 2003
+	044c  Windows Powered Pocket PC 2003
+	044d  Windows Powered Pocket PC 2003
+	044e  Windows Powered Pocket PC 2003
+	044f  Windows Powered Pocket PC 2003
+	0450  Windows Powered Pocket PC 2003
+	0451  Windows Powered Pocket PC 2003
+	0452  Windows Powered Pocket PC 2003
+	0453  Windows Powered Pocket PC 2003
+	0454  Windows Powered Pocket PC 2003
+	0455  Windows Powered Pocket PC 2003
+	0456  Windows Powered Pocket PC 2003
+	0457  Windows Powered Pocket PC 2003
+	0458  Windows Powered Pocket PC 2003
+	0459  Windows Powered Pocket PC 2003
+	045a  Windows Powered Pocket PC 2003
+	045b  Windows Powered Pocket PC 2003
+	045c  Windows Powered Pocket PC 2003
+	045d  Windows Powered Pocket PC 2003
+	045e  Windows Powered Pocket PC 2003
+	045f  Windows Powered Pocket PC 2003
+	0460  Windows Powered Pocket PC 2003
+	0461  Windows Powered Pocket PC 2003
+	0462  Windows Powered Pocket PC 2003
+	0463  Windows Powered Pocket PC 2003
+	0464  Windows Powered Pocket PC 2003
+	0465  Windows Powered Pocket PC 2003
+	0466  Windows Powered Pocket PC 2003
+	0467  Windows Powered Pocket PC 2003
+	0468  Windows Powered Pocket PC 2003
+	0469  Windows Powered Pocket PC 2003
+	046a  Windows Powered Pocket PC 2003
+	046b  Windows Powered Pocket PC 2003
+	046c  Windows Powered Pocket PC 2003
+	046d  Windows Powered Pocket PC 2003
+	046e  Windows Powered Pocket PC 2003
+	046f  Windows Powered Pocket PC 2003
+	0470  Windows Powered Pocket PC 2003
+	0471  Windows Powered Pocket PC 2003
+	0472  Windows Powered Pocket PC 2003
+	0473  Windows Powered Pocket PC 2003
+	0474  Windows Powered Pocket PC 2003
+	0475  Windows Powered Pocket PC 2003
+	0476  Windows Powered Pocket PC 2003
+	0477  Windows Powered Pocket PC 2003
+	0478  Windows Powered Pocket PC 2003
+	0479  Windows Powered Pocket PC 2003
+	047a  Windows Powered Pocket PC 2003
+	047b  Windows Powered Pocket PC 2003
+	04c8  Windows Powered Smartphone 2002
+	04c9  Windows Powered Smartphone 2002
+	04ca  Windows Powered Smartphone 2002
+	04cb  Windows Powered Smartphone 2002
+	04cc  Windows Powered Smartphone 2002
+	04cd  Windows Powered Smartphone 2002
+	04ce  Windows Powered Smartphone 2002
+	04d7  Windows Powered Smartphone 2003
+	04d8  Windows Powered Smartphone 2003
+	04d9  Windows Powered Smartphone 2003
+	04da  Windows Powered Smartphone 2003
+	04db  Windows Powered Smartphone 2003
+	04dc  Windows Powered Smartphone 2003
+	04dd  Windows Powered Smartphone 2003
+	04de  Windows Powered Smartphone 2003
+	04df  Windows Powered Smartphone 2003
+	04e0  Windows Powered Smartphone 2003
+	04e1  Windows Powered Smartphone 2003
+	04e2  Windows Powered Smartphone 2003
+	04e3  Windows Powered Smartphone 2003
+	04e4  Windows Powered Smartphone 2003
+	04e5  Windows Powered Smartphone 2003
+	04e6  Windows Powered Smartphone 2003
+	04e7  Windows Powered Smartphone 2003
+	04e8  Windows Powered Smartphone 2003
+	04e9  Windows Powered Smartphone 2003
+	04ea  Windows Powered Smartphone 2003
+	0708  Transceiver v 3.0 for Bluetooth
+	070a  Charon Bluetooth Dongle (DFU)
+	930a  ISOUSB.SYS Intel 82930 Isochronous IO Test Board
+	fff8  Keyboard
+0460  Ace Cad Enterprise Co., Ltd
+0461  Primax Electronics, Ltd
+	0300  G2-300 Scanner
+	0301  G2E-300 Scanner
+	0302  G2-300 #2 Scanner
+	0303  G2E-300 #2 Scanner
+	0340  Colorado 9600 Scanner
+	0341  Colorado 600u Scanner
+	0345  Visioneer 6200 Scanner
+	0346  Memorex Maxx 6136u Scanner
+	0347  Primascan Colorado 2600u/Visioneer 4400 Scanner
+	0360  Colorado 19200 Scanner
+	0361  Colorado 1200u Scanner
+	0363  VistaScan Astra 3600(ENG)
+	0364  LG Electronics Scanworks 600U Scanner
+	0365  VistaScan Astra 3600(ENG)
+	0366  6400
+	0367  VistaScan Astra 3600(ENG)
+	0371  Visioneer Onetouch 8920 Scanner
+	0374  UMAX Astra 2500
+	0375  VistaScan Astra 3600(ENG)
+	0377  Medion MD 5345 Scanner
+	0378  VistaScan Astra 3600(ENG)
+	037b  Medion MD 6190 Scanner
+	037c  VistaScan Astra 3600(ENG)
+	0380  G2-600 Scanner
+	0381  ReadyScan 636i Scanner
+	0382  G2-600 #2 Scanner
+	0383  G2E-600 Scanner
+	038a  UMAX Astra 3000/3600
+	038b  Xerox 2400 Onetouch
+	038c  UMAX Astra 4100
+	0392  Medion/Lifetec/Tevion/Cytron MD 6190
+	03a8  9420M
+	0813  IBM UltraPort Camera
+	0815  Micro Innovations WebCam
+	0819  Fujifilm IX-30 Camera [webcam mode]
+	081a  Fujifilm IX-30 Camera [storage mode]
+	081c  Elitegroup ECS-C11 Camera
+	081d  Elitegroup ECS-C11 Storage
+	0a00  Web Cam 320
+	4d01  Comfort Keyboard
+	4d02  Mouse-in-a-Box
+	4d03  Kensington Mouse-in-a-box
+	4d04  Mouse
+	4d06  Balless Mouse (HID)
+	4d2a  PoPo Elixir Mouse (HID)
+	4d2b  Wireless Laser Mini Mouse (HID)
+	4d2c  PoPo Mini Pointer Mouse (HID)
+	4d2e  Optical Mobile Mouse (HID)
+0463  MGE UPS Systems
+	0001  UPS
+	ffff  UPS
+0464  AMP/Tycoelectronics Corp.
+0467  AT&T Paradyne
+0468  Wieson Technologies Co., Ltd
+046a  Cherry GmbH
+	0001  My3000 Keyboard
+	0003  My3000 Hub
+	0004  CyBoard Keyboard
+	0005  XX33 SmartCard Reader Keyboard
+	0010  SmartBoard XX44
+	0023  Cymotion Master Linux Keyboard
+	002d  SmartTerminal XX44
+	003e  SmartTerminal ST-2xxx
+046b  American Megatrends, Inc.
+	0001  Keyboard
+	0101  PS/2 Keyboard, Mouse & Joystick Ports
+	0301  USB 1.0 Hub
+	0500  Serial & Parallel Ports
+046c  Toshiba Corp., Digital Media Equipment
+046d  Logitech, Inc.
+	0082  Acer Aspire 5672 Webcam
+	0200  WingMan Extreme Joystick
+	0203  M2452 Keyboard
+	0301  M4848 Mouse
+	0401  HP PageScan
+	0402  NEC PageScan
+	040f  Logitech/Storm PageScan
+	0430  Mic (Cordless)
+	0801  QuickCam Home
+	0810  QuickCam Pro
+	0820  QuickCam VC
+	0830  QuickClip
+	0840  QuickCam Express
+	0850  QuickCam Web
+	0870  QuickCam Express
+	0890  QuickCam Traveler
+	0892  OrbiCam
+	0894  CrystalCam
+	0895  QuickCam for Dell Notebooks
+	0896  OrbiCam
+	0897  QuickCam for Dell Notebooks
+	0899  QuickCam for Dell Notebooks
+	08a0  QuickCam IM
+	08a1  QuickCam IM with sound
+	08a2  Labtec WebCam Pro
+	08a3  QuickCam QuickCam Chat
+	08a6  QuickCam IM
+	08a7  QuickCam Image
+	08a9  Notebook Deluxe
+	08aa  Labtec Notebooks
+	08ac  QuickCam Cool
+	08ad  QuickCam Communicate STX
+	08ae  Quickcam for Notebooks
+	08af  QuickCam Easy/Cool
+	08b0  QuickCam 3000 Pro [pwc]
+	08b1  QuickCam Notebook Pro
+	08b2  QuickCam Pro 4000
+	08b3  QuickCam Zoom
+	08b4  QuickCam Zoom
+	08b5  QuickCam Sphere
+	08b9  QuickCam IM
+	08bd  Microphone (Pro 4000)
+	08c0  QuickCam Pro 3000
+	08c1  QuickCam Fusion
+	08c2  QuickCam PTZ
+	08c3  Camera (Notebooks Pro)
+	08c5  QuickCam Pro 5000
+	08c6  QuickCam for DELL Notebooks
+	08c9  QuickCam Ultra Vision
+	08ca  Mic (Fusion)
+	08cb  Mic (Notebooks Pro)
+	08cc  Mic (PTZ)
+	08ce  QuickCam Pro 5000
+	08cf  QuickCam UpdateMe
+	08d0  QuickCam Express
+	08d7  QuickCam Communicate STX
+	08d8  QuickCam for Notebook Deluxe
+	08d9  QuickCam IM/Connect
+	08da  QuickCam Messanger
+	08dd  QuickCam for Notebooks
+	08e0  QuickCam Express
+	08e1  Labtec WebCam
+	08f0  QuickCam Messenger
+	08f1  QuickCam Express
+	08f2  Microphone (Messenger)
+	08f3  QuickCam Express
+	08f4  Labtec WebCam
+	08f5  QuickCam Messenger Communicate
+	08f6  Quickcam Messenger Plus
+	0900  ClickSmart 310
+	0901  ClickSmart 510
+	0903  ClickSmart 820
+	0905  ClickSmart 820
+	0910  QuickCam Cordless
+	0920  QuickCam Express
+	0921  Labtec WebCam
+	0922  QuickCam Live
+	0928  Quickcam Express
+	0929  Labtec WebCam Pro
+	092a  QuickCam for Notebooks
+	092b  Labtec WebCam Plus
+	092c  QuickCam Chat
+	092d  QuickCam Express / Go
+	092e  QuickCam Chat
+	092f  QuickCam Express Plus
+	0950  Pocket Camera
+	0960  ClickSmart 420
+	0970  Pocket750
+	0990  QuickCam Pro 9000
+	0991  QuickCam Pro for Notebooks
+	0992  QuickCam Communicate Deluxe
+	0994  QuickCam Orbit/Sphere AF
+	09b0  OrbiCam
+	09c0  QuickCam for Dell Notebooks Mic
+	09c1  QuickCam Deluxe for Notebooks
+	0a01  USB Headset
+	0a02  Premium Stereo USB Headset 350
+	0a03  Logitech USB Microphone
+	0a04  V20 portable speakers (USB powered)
+	0b02  BT Mini-Receiver (HID proxy mode)
+	8801  Video Camera
+	b305  BT Mini-Receiver
+	bfe4  Premium Optical Wheel Mouse
+	c000  N43 [Pilot Mouse]
+	c001  N48/M-BB48 [FirstMouse Plus]
+	c002  M-BA47 [MouseMan Plus]
+	c003  MouseMan
+	c004  WingMan Gaming Mouse
+	c005  WingMan Gaming Wheel Mouse
+	c00b  MouseMan Wheel
+	c00c  Optical Wheel Mouse
+	c00d  MouseMan Wheel+
+	c00e  M-BJ58/M-BJ69 Optical Wheel Mouse
+	c00f  MouseMan Traveler/Mobile
+	c011  Optical MouseMan
+	c012  Mouseman Dual Optical
+	c014  Corded Workstation Mouse
+	c015  Corded Workstation Mouse
+	c016  M-UV69a/HP M-UV96 Optical Wheel Mouse
+	c018  Optical Wheel Mouse
+	c019  Optical Tilt Wheel Mouse
+	c01a  M-BQ85 Optical Wheel Mouse
+	c01b  MX310 Optical Mouse
+	c01c  Optical Mouse
+	c01d  MX510 Optical Mouse
+	c01e  MX518 Optical Mouse
+	c024  MX300 Optical Mouse
+	c025  MX500 Optical Mouse
+	c030  iFeel Mouse
+	c031  iFeel Mouse+
+	c032  MouseMan iFeel
+	c033  iFeel MouseMan+
+	c034  MouseMan Optical
+	c035  Mouse
+	c036  Mouse
+	c037  Mouse
+	c038  Mouse
+	c03d  M-BT69a Pilot Optical Mouse
+	c03e  Premium Optical Wheel Mouse
+	c03f  UltraX Optical Mouse
+	c040  Corded Tilt-Wheel Mouse
+	c043  MX320 Laser Mouse
+	c044  LX3 Optical Mouse
+	c045  Optical Mouse
+	c046  RX1000 Laser Mouse
+	c047  Laser Mouse
+	c049  G5 Laser Mouse
+	c050  RX 250 Optical Mouse
+	c051  G3 (MX518) Optical Mouse
+	c053  Laser Mouse
+	c101  UltraX Media Remote
+	c201  WingMan Extreme Joystick with Throttle
+	c202  WingMan Formula
+	c207  WingMan Extreme Digital 3D
+	c208  WingMan Gamepad Extreme
+	c209  WingMan Gamepad
+	c20a  WingMan RumblePad
+	c20b  WingMan Action Pad
+	c20c  WingMan Precision
+	c20d  WingMan Attack 2
+	c20e  WingMan Formula GP
+	c211  iTouch Cordless Reciever
+	c212  WingMan Extreme Digital 3D
+	c213  J-UH16 (Freedom 2.4 Cordless Joystick)
+	c214  ATK3 (Attack III Joystick)
+	c215  Extreme 3D Pro
+	c216  Dual Action Gamepad
+	c218  Logitech RumblePad 2 USB
+	c219  Cordless RumblePad 2
+	c21a  Precision Gamepad
+	c221  G15 Keyboard / Keyboard
+	c222  G15 Keyboard / LCD
+	c223  G15 Keyboard / USB Hub
+	c281  WingMan Force
+	c283  WingMan Force 3D
+	c285  WingMan Strike Force 3D
+	c286  Force 3D Pro
+	c291  WingMan Formula Force
+	c293  WingMan Formula Force GP
+	c294  Driving Force
+	c295  Momo Force Steering Wheel
+	c298  Driving Force Pro
+	c2a0  Wingman Force Feedback Mouse
+	c2a1  WingMan Force Feedback Mouse
+	c301  iTouch Keyboard
+	c302  iTouch Pro Keyboard
+	c303  iTouch Keyboard
+	c305  Internet Keyboard
+	c307  Internet Keyboard
+	c308  Internet Navigator Keyboard
+	c309  Internet Keyboard
+	c30a  iTouch Composite
+	c30c  Internet Keys (X)
+	c30d  Internet Keys
+	c30e  UltraX Keys (X)
+	c30f  Logicool HID-Compliant Keyboard (106 key)
+	c315  Classic New Touch Keyboard
+	c316  HID-Compliant Keyboard
+	c401  TrackMan Marble Wheel
+	c402  Marble Mouse (2-button)
+	c403  Turbo TrackMan Marble FX
+	c404  TrackMan Wheel
+	c408  Marble Mouse (4-button)
+	c501  Cordless Mouse Receiver
+	c502  Cordless Mouse & iTouch Keys
+	c503  Cordless Mouse+Keyboard Receiver
+	c504  Cordless Mouse+Keyboard Receiver
+	c505  Cordless Mouse+Keyboard Receiver
+	c506  MX-700 Cordless Mouse Receiver
+	c508  Cordless Trackball
+	c509  Cordless Keyboard
+	c50a  Cordless Mouse
+	c50b  Cordless Desktop Optical
+	c50d  Cordless Mouse
+	c50e  MX-1000 Cordless Mouse Receiver
+	c510  Cordless Mouse
+	c512  LX-700 Cordless Desktop Receiver
+	c513  MX3000 Cordless Desktop Receiver
+	c514  Cordless Mouse
+	c517  LX710 Cordless Desktop Laser
+	c518  MX610 Laser Cordless Mouse
+	c51a  MX Revolution/G7 Cordless Mouse
+	c521  MX620 Laser Cordless Mouse
+	c625  3Dconnexion Space Pilot 3D Mouse
+	c626  3DConnexion Space Navigator 3D Mouse
+	c627  3DConnexion Space Explorer 3D Mouse
+	c702  Cordless Presenter
+	c703  Elite Keyboard Y-RP20 + Mouse MX900 (Bluetooth)
+	c707  Bluetooth wireless hub
+	c708  Bluetooth wireless hub
+	c709  BT Mini-Receiver (HCI mode)
+	c70a  MX5000 Cordless Desktop
+	c70b  BT Mini-Receiver (HID proxy mode)
+	c70c  BT Mini-Receiver (HID proxy mode)
+	c70d  Bluetooth wireless hub
+	c70e  MX1000 Bluetooth Laser Mouse
+	c70f  Bluetooth wireless hub
+	c712  Bluetooth wireless hub
+	c715  Bluetooth wireless hub
+	c71a  Bluetooth wireless hub
+	c71d  Bluetooth wireless hub
+	c720  Bluetooth wireless hub
+	ca03  MOMO Racing
+	ca04  Formula Vibration Feedback Wheel
+	d001  QuickCam Pro
+046e  Behavior Tech. Computer Corp.
+	0100  Keyboard
+	3001  Mass Storage Device
+	3002  Mass Storage Device
+	3003  Mass Storage Device
+	3005  Mass Storage Device
+	3008  Mass Storage Device
+	5250  KeyMaestro Multimedia Keyboard
+	5273  KeyMaestro Multimedia Keyboard
+	5308  KeyMaestro Keyboard
+	5408  KeyMaestro Multimedia Keyboard/Hub
+	5720  Smart Card Reader
+	6782  BTC 7932 mouse+keyboard
+046f  Crystal Semiconductor
+0471  Philips
+	0101  DSS350 Digital Speaker System
+	0104  DSS330 Digital Speaker System [uda1321]
+	0105  UDA1321
+	0160  MP3 Player
+	0161  MP3 Player
+	0201  Hub
+	0222  Creative Nomad Jukebox
+	0302  PCA645VC WebCam [pwc]
+	0303  PCA646VC WebCam [pwc]
+	0304  Askey VC010 WebCam [pwc]
+	0307  PCVC675K WebCam [pwc]
+	0308  PCVC680K WebCam [pwc]
+	030b  PC VGA Camera (Vesta Fun)
+	030c  PCVC690K WebCam [pwc]
+	0310  PCVC730K WebCam [pwc]
+	0311  PCVC740K ToUcam Pro [pwc]
+	0312  PCVC750K WebCam [pwc]
+	0314  DMVC 1000K
+	0316  DMVC 2000K Video Capture
+	0321  FunCam
+	0325  SPC 200NC PC Camera
+	0326  SPC 300NC PC Camera
+	0327  WebCam SPC 6000 NC (WebCam w/ mic)
+	0329  ORITE CCD Webcam(PC370R)
+	0401  Semiconductors CICT Keyboard
+	0402  PS/2 Mouse on Semiconductors CICT Keyboard
+	0406  15 inch Detachable Monitor
+	0407  10 inch Mobile Monitor
+	0471  Digital Speaker System
+	0601  OVU1020 IR Dongle (Kbd+Mouse)
+	0602  ATI Remote Wonder II Input Device
+	0603  ATI Remote Wonder II Controller
+	0608  eHome Infrared Receiver
+	060a  TSU9600 Remote Control
+	060e  RF Dongle
+	0619  TSU9400 Remote Control
+	0700  Semiconductors CICT Hub
+	0701  150P1 TFT Display
+	0809  AVNET Bluetooth Device
+	0811  JR24 CDRW
+	0815  eHome Infrared Receiver
+	1120  Creative Rhomba MP3 player
+	1125  Nike psa[128max Player
+	1137  HDD065 MP3 player
+	1201  Arima Bluetooth Device
+	1230  Wireless Adapter 11g
+	1232  SNU6500 Wireless Adapter
+	1233  Wireless Adapter Bootloader Download
+	1236  SNU5600
+	1237  TalkTalk SNU5630NS/05 Wireless Adapter
+	1552  ISP 1581 Hi-Speed USB MPEG2 Encoder Reference Kit
+	1801  Diva MP3 player
+	200a  Wireless Network Adapter
+	200f  802.11n Wireless Adapter
+	485d  Senselock SenseIV v2.x
+0472  Chicony Electronics Co., Ltd
+	0065  PFU-65 Keyboard
+0473  Sanyo Information Business Co., Ltd
+0474  Sanyo Electric Co., Ltd
+	0110  Digital Voice Recorder R200
+	0217  Xacti J2
+	022f  C5 Digital Media Camera (mass storage mode)
+	0230  C5 Digital Media Camera (PictBridge mode)
+	0231  C5 Digital Media Camera (PC control mode)
+	0401  Optical Drive
+	0701  SCP-4900 Cellphone
+	071f  Usb Com Port Enumerator
+0475  Relisys/Teco Information System
+	0100  NEC Petiscan
+	0103  Eclipse 1200U/Episode
+	0210  Scorpio Ultra 3
+0476  AESP
+0477  Seagate Technology, Inc.
+0478  Connectix Corp.
+	0001  QuickCam
+	0002  QuickClip
+	0003  QuickCam Pro
+0479  Advanced Peripheral Laboratories
+047a  Semtech Corp.
+	0004  ScreenCoder UR7HCTS2-USB
+047b  Silitek Corp.
+	0001  Keyboard
+	0002  Keyboard and Mouse
+	00f9  SK-1789u Keyboard
+	0101  BlueTooth Keyboard and Mouse
+	020b  SK-3105 SmartCard Reader
+	050e  Internet Compact Keyboard
+	1000  Trust Office Scan USB 19200
+	1002  HP ScanJet 4300c Parallel Port
+047c  Dell Computer Corp.
+047d  Kensington
+	1001  Mouse*in*a*Box
+	1002  Expert Mouse Pro
+	1003  Orbit TrackBall
+	1004  MouseWorks
+	1005  TurboBall
+	1006  TurboRing
+	1009  Orbit TrackBall for Mac
+	1012  PocketMouse
+	1013  Mouse*in*a*Box Optical Pro
+	1014  Expert Mouse Pro Wireless
+	1015  Expert Mouse
+	1016  ADB/USB Orbit
+	1018  Studio Mouse
+	101d  Mouse*in*a*Box Optical Pro
+	101e  Studio Mouse Wireless
+	101f  PocketMouse Pro
+	1020  Expert Mouse Trackball
+	1021  Expert Mouse Wireless
+	1022  Orbit Optical
+	1023  Pocket Mouse Pro Wireless
+	1024  PocketMouse
+	1025  Mouse*in*a*Box Optical Elite Wireless
+	1026  Pocket Mouse Pro
+	1027  StudioMouse
+	1028  StudioMouse Wireless
+	1029  Mouse*in*a*Box Optical Elite
+	102a  Mouse*in*a*Box Optical
+	102b  PocketMouse
+	102c  Iridio
+	102d  Pilot Optical
+	102e  Pilot Optical Pro
+	102f  Pilot Optical Pro Wireless
+	104a  PilotMouse Mini Retractable
+	105d  PocketMouse Bluetooth
+	105e  Bluetooth EDR Dongle
+	1061  PocketMouse Grip
+	1062  PocketMouse Max
+	1063  PocketMouse Max Wireless
+	1064  PocketMouse 2.0 Wireless
+	1065  PocketMouse 2.0
+	1066  PocketMouse Max Glow
+	1067  ValueMouse
+	1068  ValueOpt White
+	1069  ValueOpt Black
+	106a  PilotMouse Laser Wireless Mini
+	106b  PilotMouse Laser - 3 Button
+	106c  PilotMouse Laser - Gaming
+	106d  PilotMouse Laser - Wired
+	106e  PilotMouse Micro Laser
+	1070  ValueOpt Travel
+	1071  ValueOpt RF TX
+	1072  PocketMouse Colour
+	1073  PilotMouse Laser - 6 Button
+	1074  PilotMouse Laser Wireless Mini
+	1075  SlimBlade Presenter Media Mouse
+	1076  SlimBlade Media Mouse
+	1077  SlimBlade Presenter Mouse
+	1152  Bluetooth EDR Dongle
+	2002  Optical Elite Wireless
+	2010  Wireless Presentation Remote
+	2021  PilotBoard Wireless
+	2030  PilotBoard Wireless
+	2034  SlimBlade Media Notebook Set
+	4003  Gravis Xterminator Digital Gamepad
+	4005  Gravis Eliminator GamePad Pro
+	4006  Gravis Eliminator AfterShock
+	4007  Gravis Xterminator Force
+	4008  Gravis Destroyer TiltPad
+	5001  Cabo I Camera
+	5002  VideoCam CABO II
+	5003  VideoCam
+047e  Agere Systems, Inc. (Lucent)
+	0300  ORiNOCO Card
+	1001  USS720 Parallel Port
+	2892  Systems Soft Modem
+	bad1  Lucent 56k Modem
+	f101  Atlas Modem
+047f  Plantronics, Inc.
+	0101  Bulk Driver
+	0301  Bulk Driver
+	0ca1  USB DSP v4 Audio Interface
+0480  Toshiba America Info. Systems, Inc.
+	0001  InTouch Module
+	0004  InTouch Module
+	0011  InTouch Module
+	0014  InTouch Module
+0481  Zenith Data Systems
+0482  Kyocera Corp.
+	000e  FS-1020D Printer
+	0100  Finecam S3x
+	0101  Finecam S4
+	0103  Finecam S5
+	0105  Finecam L3
+	0106  Finecam
+	0107  Digital Camera Device
+	0108  Digital Camera Device
+	0203  AH-K3001V
+	0204  iBurst Terminal
+0483  SGS Thomson Microelectronics
+	0137  BeWAN ADSL USB ST (blue or green)
+	1307  Cytronix 6in1 card reader
+	163d  Cool Icam Digi-MP3
+	2015  TouchChip® Fingerprint Reader
+	2016  Fingerprint Reader
+	2017  Biometric Smart Card Reader
+	2018  BioSimKey
+	2302  Portable Flash Device (PFD)
+	4810  ISDN adapter
+	481d  BT Digital Access adapter
+	5000  ST Micro Bluetooth Device
+	5001  ST Micro Bluetooth Device
+	7270  ST Micro Serial Bridge
+	7554  56k SoftModem
+	ff10  Swann ST56 Modem
+0484  Specialix
+0485  Nokia Monitors
+0486  ASUS Computers, Inc.
+0487  Stewart Connector
+0488  Cirque Corp.
+0489  Foxconn / Hon Hai
+	0502  SmartMedia Card Reader Firmware Loader
+	0503  SmartMedia Card Reader
+048a  S-MOS Systems, Inc.
+048c  Alps Electric Ireland, Ltd
+048d  Integrated Technology Express, Inc.
+048f  Eicon Tech.
+0490  United Microelectronics Corp.
+0491  Capetronic
+	0003  Taxan Monitor Control
+0492  Samsung SemiConductor, Inc.
+0493  MAG Technology Co., Ltd
+0495  ESS Technology, Inc.
+0496  Micron Electronics
+0497  Smile International
+0498  Capetronic (Kaohsiung) Corp.
+0499  Yamaha Corp.
+	1000  UX256 MIDI I/F
+	1001  MU1000
+	1002  MU2000
+	1003  MU500
+	1004  UW500
+	1005  MOTIF6
+	1006  MOTIF7
+	1007  MOTIF8
+	1008  UX96 MIDI I/F
+	1009  UX16 MIDI I/F
+	100a  EOS BX
+	100c  UC-MX
+	100d  UC-KX
+	100e  S08
+	100f  CLP-150
+	1010  CLP-170
+	1011  P-250
+	1012  TYROS
+	1013  PF-500
+	1014  S90
+	1015  MOTIF-R
+	1016  MDP-5
+	1017  CVP-204
+	1018  CVP-206
+	1019  CVP-208
+	101a  CVP-210
+	101b  PSR-1100
+	101c  PSR-2100
+	101d  CLP-175
+	101e  PSR-K1
+	101f  EZ-J24
+	1020  EZ-250i
+	1021  MOTIF ES 6
+	1022  MOTIF ES 7
+	1023  MOTIF ES 8
+	1024  CVP-301
+	1025  CVP-303
+	1026  CVP-305
+	1027  CVP-307
+	1028  CVP-309
+	1029  CVP-309GP
+	102a  PSR-1500
+	102b  PSR-3000
+	102e  ELS-01/01C
+	1030  PSR-295/293
+	1031  DGX-205/203
+	1032  DGX-305
+	1033  DGX-505
+	2000  DGP-7
+	2001  DGP-5
+	3001  YST-MS55D USB Speaker
+	4000  NetVolante RTA54i Broadband&ISDN Router
+	4001  NetVolante RTW65b Broadband Wireless Router
+	4002  NetVolante RTW65i Broadband&ISDN Wireless Router
+	4004  NetVolante RTA55i Broadband VoIP Router
+	5000  CS1D
+	5001  DSP1D
+	5002  DME32
+	5003  DM2000
+	5004  02R96
+	5005  ACU16-C
+	5006  NHB32-C
+	5007  DM1000
+	5008  01V96
+	5009  SPX2000
+	500a  PM5D
+	500b  DME64N
+	500c  DME24N
+	6001  CRW2200UX Lightspeed 2 External CD-RW Drive
+	7000  DTX
+	7010  UB99
+049a  Gandalf Technologies, Ltd
+049b  Curtis Computer Products
+049c  Acer Advanced Labs, Inc.
+	0002  Keyboard (???)
+049d  VLSI Technology
+049f  Compaq Computer Corp.
+	0002  InkJet Color Printer
+	0003  iPAQ PocketPC
+	000e  Internet Keyboard
+	0012  InkJet Color Printer
+	0018  PA-1/PA-2 MP3 Player
+	0019  InkJet Color Printer
+	001a  S4 100 Scanner
+	001e  IJ650 Inkjet Printer
+	001f  WL215 Adapter
+	0021  S200 Scanner
+	0027  Bluetooth Multiport Module by Compaq
+	002a  1400P Inkjet Printer
+	002b  A3000
+	002c  Lexmark X125
+	0032  802.11b Adapter [ipaq h5400]
+	0033  802.11b Adapter [orinoco]
+	0036  Bluetooth Multiport Module
+	0051  KU-0133 Easy Access Interner Keyboard
+	0076  Wireless LAN MultiPort W200
+	0080  GPRS Multiport
+	0086  Bluetooth Device
+	504a  Personal Jukebox PJB100
+	505a  Linux-USB "CDC Subset" Device, or Itsy (experimental)
+	8511  iPAQ Networking 10/100 Ethernet [pegasus2]
+04a0  Digital Equipment Corp.
+04a1  SystemSoft Corp.
+	fff0  Telex Composite Device
+04a2  FirePower Systems
+04a3  Trident Microsystems, Inc.
+04a4  Hitachi, Ltd
+	0004  DVD-CAM DZ-MV100A Camcorder
+	001e  DVDCAM USB HS Interface
+04a5  Acer Peripherals Inc. (now BenQ Corp.)
+	0001  Keyboard
+	0002  API Ergo K/B
+	0003  API Generic K/B Mouse
+	12a6  AcerScan C310U
+	1a20  Prisa 310U
+	1a2a  Prisa 620U
+	2022  Prisa 320U/340U
+	2040  Prisa 620UT
+	205e  ScanPrisa 640BU
+	2060  Prisa 620U+/640U
+	207e  Prisa 640BU
+	209e  ScanPrisa 640BT
+	20ae  S2W 3000U
+	20b0  S2W 3300U/4300U
+	20be  Prisa 640BT
+	20c0  Prisa 1240UT
+	20de  S2W 4300U+
+	20f8  Benq 5000
+	20fc  Benq 5000
+	20fe  SW2 5300U
+	2137  Benq 5150/5250
+	2202  Benq 7400UT
+	3003  Benq WebCam
+	3008  Benq 1500
+	300a  Benq 3410
+	300c  Benq 1016
+	3019  Benq DC C40
+	4000  P30 Composite Device
+	6001  Mass Storage Device
+	6002  Mass Storage Device
+	6003  ATA/ATAPI Adapter
+	6004  Mass Storage Device
+	6005  Mass Storage Device
+	6006  Mass Storage Device
+	6007  Mass Storage Device
+	6008  Mass Storage Device
+	6009  Mass Storage Device
+	600a  Mass Storage Device
+	600b  Mass Storage Device
+	600c  Mass Storage Device
+	600d  Mass Storage Device
+	600e  Mass Storage Device
+	600f  Mass Storage Device
+	6010  Mass Storage Device
+	6011  Mass Storage Device
+	6012  Mass Storage Device
+	6013  Mass Storage Device
+	6014  Mass Storage Device
+	6015  Mass Storage Device
+	6125  MP3 Player
+	6180  MP3 Player
+	6200  MP3 Player
+	7500  Hi-Speed Mass Storage Device
+	9000  AWL300 Wireless Adapter
+	9001  AWL400 Wireless Adapter
+	9213  Kbd Hub
+04a6  Nokia Display Products
+	00b9  Audio
+	0180  Hub Type P
+	0181  HID Monitor Controls
+04a7  Visioneer
+	0100  StrobePro
+	0101  Strobe Pro Scanner (1.01)
+	0102  StrobePro Scanner
+	0211  OneTouch 7600 Scanner
+	0221  OneTouch 5300 Scanner
+	0223  OneTouch 8200
+	0224  OneTouch 4800 USB/Microtek Scanport 3000
+	0225  VistaScan Astra 3600(ENG)
+	0226  OneTouch 5300 USB
+	0229  OneTouch 7100
+	022a  OneTouch 6600
+	022c  OneTouch 9000/9020
+	0231  6100 Scanner
+	0311  6200 EPP/USB Scanner
+	0321  OneTouch 8100 EPP/USB Scanner
+	0331  OneTouch 8600 EPP/USB Scanner
+	0341  6400
+	0361  VistaScan Astra 3600(ENG)
+	0362  OneTouch 9320
+	0371  OneTouch 8700/8920
+	0380  OneTouch 7700
+	0382  Photo Port 7700
+	0390  9650
+	03a0  Xerox 4800 One Touch
+	0410  OneTouch Pro 8800/8820
+	0421  9450 USB
+	0423  9750 Scanner
+	0424  Strobe XP 450
+	0425  Strobe XP 100
+	0426  Strobe XP 200
+	0427  Strobe XP 100
+	0444  OneTouch 7300
+	0445  CardReader 100
+	0446  Xerox DocuMate 510
+	0447  XEROX DocuMate 520
+	0448  XEROX DocuMate 250
+	0449  Xerox DocuMate 252
+	044a  Xerox 6400
+	044c  Xerox DocuMate 262
+	0474  Strobe XP 300
+	0475  Xerox DocuMate 272
+	0478  Strobe XP 220
+	0479  Strobe XP 470
+	047a  9450
+	047b  9650
+	047d  9420
+	0480  9520
+	048f  Strobe XP 470
+	0491  Strobe XP 450
+	0493  9750
+	0494  Strobe XP 120
+	0497  Patriot 430
+	0498  Patriot 680
+	0499  Patriot 780
+	049b  Strobe XP 100
+	04a0  7400
+04a8  Multivideo Labs, Inc.
+	0101  Hub
+	0303  Peripheral Switch
+	0404  Peripheral Switch
+04a9  Canon, Inc.
+	1005  BJ Printer Hub
+	1035  PD Printer Storage
+	1050  BJC-8200
+	1051  BJC-3000 Color Printer
+	1052  BJC-6100
+	1053  BJC-6200
+	1054  BJC-6500
+	1055  BJC-85
+	1056  BJC-2110 Color Printer
+	1057  LR1
+	105a  BJC-55
+	105b  S600 Printer
+	105c  S400
+	105d  S450 Printer
+	105e  S800
+	1062  S500 Printer
+	1063  S4500
+	1064  S300 Printer
+	1065  S100
+	1066  S630
+	1067  S900
+	1068  S9000
+	1069  S820
+	106a  S200 Printer
+	106b  S520 Printer
+	106d  S750 Printer
+	106e  S820D
+	1070  S530D
+	1072  I850 Printer
+	1073  I550 Printer
+	1074  S330 Printer
+	1076  i70
+	1077  i950
+	107a  S830D
+	107b  i320
+	107c  i470D
+	107d  i9100
+	107e  i450
+	107f  i860
+	1082  i350
+	1084  i250
+	1085  i255
+	1086  i560
+	1088  i965
+	108a  i455
+	108b  i900D
+	108c  i475D
+	108d  PIXMA iP2000
+	108f  i80
+	1090  i9900 Photo Printer
+	1091  PIXMA iP1500
+	1093  PIXMA iP4000
+	1094  PIXMA iP3000x Printer
+	1095  PIXMA iP6000D
+	1097  PIXMA iP5000
+	1098  PIXMA iP1000
+	1099  PIXMA iP8500
+	109c  PIXMA iP4000R
+	109d  iP90
+	10a0  PIXMA iP1600 Printer
+	10a2  iP4200
+	10a4  iP5200R
+	10a5  iP5200
+	10a7  iP6210D
+	10a8  iP6220D
+	10a9  iP6600D
+	10b6  PIXMA iP4300 Printer
+	1404  W6400PG
+	1405  W8400PG
+	150f  BIJ2350 PCL
+	1510  BIJ1350 PCL
+	1512  BIJ1350D PCL
+	1601  DR-2080C Scanner
+	1607  DR-6080 Scanner
+	1700  PIXMA MP110 Scanner
+	1701  PIXMA MP130 Scanner
+	1702  MP410 Composite
+	1703  MP430 Composite
+	1704  MP330 Composite
+	1706  PIXMA MP750 Scanner
+	1707  PIXMA MP780 Scanner
+	1708  PIXMA MP760 Scanner
+	1709  PIXMA MP150 Scanner
+	170a  PIXMA MP170 Scanner
+	170b  PIXMA MP450 Scanner
+	170c  PIXMA MP500 Scanner
+	170d  PIXMA MP800 Scanner
+	170e  MP800R
+	1710  MP950
+	1712  MP530
+	1713  PIXMA MP830 Scanner
+	1714  MP160
+	1715  MP180 Storage
+	1716  MP460 Composite
+	1717  MP510
+	1718  MP600 Storage
+	171a  MP810 Storage
+	171b  MP960
+	1721  MP210 ser
+	1723  MP470 ser
+	1725  MP610 ser
+	1726  MP970 ser
+	1727  MX300 ser
+	1728  MX310 ser
+	1729  MX700 ser
+	172b  MP140 ser
+	2200  CanoScan LiDE 25
+	2201  CanoScan FB320U
+	2202  CanoScan FB620U
+	2204  CanoScan FB630U
+	2205  CanoScan FB1210U
+	2206  CanoScan N650U/N656U
+	2207  CanoScan 1220U
+	2208  CanoScan D660U
+	220a  CanoScan D2400UF
+	220b  CanoScan D646U
+	220c  CanoScan D1250U2
+	220d  CanoScan N670U/N676U/LiDE 20
+	220e  CanoScan N1240U/LiDE 30
+	220f  CanoScan 8000F
+	2210  CanoScan 9900F
+	2212  CanoScan 5000F
+	2213  CanoScan LiDE 50/LiDE 35/LiDE 40
+	2214  CanoScan LiDE 80
+	2215  CanoScan 3000/3000F/3000ex
+	2216  CanoScan 3200F
+	2217  CanoScan 5200F
+	2219  CanoScan 9950F
+	221b  CanoScan 4200F
+	221c  CanoScan LiDE 60
+	221e  CanoScan 8400F
+	221f  CanoScan LiDE 500F
+	2220  CanoScan LIDE 25
+	2225  CanoScan LiDE 70
+	2228  CanoScan 4400F
+	2602  MultiPASS C555
+	2603  MultiPASS C755
+	260a  CAPT Printer
+	260e  LBP-2000
+	2610  MPC600F
+	2611  SmartBase MPC400
+	2612  MultiPASS C855
+	2617  CAPT Printer
+	261a  iR1600
+	261b  iR1610
+	261c  iC2300
+	261f  MPC200 Printer
+	2621  iR2000
+	2622  iR2010
+	2623  FAX-B180C
+	2629  FAXPHONE L75
+	262b  LaserShot LBP-1120 Printer
+	262d  iR C3200
+	262f  MultiPASS MP730
+	2630  MultiPASS MP700
+	2631  LASER CLASS 700
+	2632  FAX-L2000
+	2635  MPC190
+	2637  iR C6800
+	2638  iR C3100
+	263c  Smartbase MP360
+	263d  MP370
+	263e  MP390 FAX
+	263f  MP375
+	2646  MF5530 Scanner Device V1.9.1
+	2647  MF5550 Composite
+	264e  MF5630
+	264f  MF5650 (FAX)
+	2650  iR 6800C EUR
+	2651  iR 3100C EUR
+	2655  FP-L170/MF350/L380/L398
+	2659  MF8100
+	265b  CAPT Printer
+	265c  iR C3220
+	265d  MF5730
+	265e  MF5750
+	265f  MF5770
+	2660  MF3110
+	2663  iR3570/iR4570
+	2664  iR2270/iR2870
+	2665  iR C2620
+	2666  iR C5800
+	2667  iR85PLUS
+	2669  iR105PLUS
+	266a  CAPT Device
+	266b  iR8070
+	266c  iR9070
+	266d  iR 5800C EUR
+	266e  CAPT Device
+	266f  iR2230
+	2670  iR3530
+	2671  iR5570/iR6570
+	2672  iR C3170
+	2673  iR 3170C EUR
+	2674  L120
+	2675  iR2830
+	2676  CAPT Device
+	2677  iR C2570
+	2678  iR 2570C EUR
+	2679  CAPT Device
+	267a  iR2016
+	267b  iR2020
+	267d  MF7100 Series
+	2684  MF3200 Series
+	2687  iR4530
+	2688  LBP3460
+	268c  iR C6870
+	268d  iR 6870C EUR
+	268e  iR C5870
+	268f  iR 5870C EUR
+	2691  iR7105
+	26a3  MF4100 Series
+	26b5  MF4200 Series
+	3041  PowerShot S10
+	3042  CanoScan FS4000US Film Scanner
+	3043  PowerShot S20
+	3044  EOS D30
+	3045  PowerShot S100
+	3046  IXY Digital
+	3047  Digital IXUS
+	3048  PowerShot G1
+	3049  PowerShot Pro90 IS
+	304a  CP-10
+	304b  IXY Digital 300
+	304c  PowerShot S300
+	304d  Digital IXUS 300
+	304e  PowerShot A20
+	304f  PowerShot A10
+	3050  PowerShot unknown 1
+	3051  PowerShot S110
+	3052  Digital IXUS V
+	3055  PowerShot G2
+	3056  PowerShot S40
+	3057  PowerShot S30
+	3058  PowerShot A40
+	3059  PowerShot A30
+	305b  ZR45MC Digital Camcorder
+	305c  PowerShot unknown 2
+	3060  EOS D60
+	3061  PowerShot A100
+	3062  PowerShot A200
+	3063  CP-100
+	3065  PowerShot S200
+	3066  Digital IXUS 330
+	3067  MV550i Digital Video Camera
+	3069  PowerShot G3
+	306a  Digital unknown 3
+	306b  MVX2i Digital Video Camera
+	306c  PowerShot S45
+	306d  PowerShot S45 PtP Mode
+	306e  PowerShot G3 (normal mode)
+	306f  PowerShot G3 (ptp)
+	3070  PowerShot S230
+	3071  PowerShot S230 (ptp)
+	3072  PowerShot SD100 / Digital IXUS II (ptp)
+	3073  PowerShot A70 (ptp)
+	3074  PowerShot A60 (ptp)
+	3075  IXUS 400 Camera
+	3076  PowerShot A300
+	3077  PowerShot S50
+	3078  ZR70MC Digital Camcorder
+	307a  MV650i (normal mode)
+	307b  MV630i Digital Video Camera
+	307c  MV630i (normal mode)
+	307d  CP-300
+	307f  Optura 20
+	3080  MVX150i (normal mode) / Optura 20 (normal mode)
+	3081  Optura 10
+	3082  MVX100i / Optura 10
+	3083  EOS 10D
+	3084  EOS 300D / EOS Digital Rebel
+	3085  PowerShot G5
+	3087  Elura 50 (PTP mode)
+	3088  Elura 50 (normal mode)
+	308d  MVX3i
+	308e  FV M1 (normal mode) / MVX 3i (normal mode) / Optura Xi (normal mode)
+	3093  Optura 300
+	3096  IXY DV M2 (normal mode) / MVX 10i (normal mode)
+	3099  EOS 300D (ptp)
+	309a  PowerShot A80
+	309b  Digital IXUS (ptp)
+	309c  PowerShot S1 IS
+	309d  Camera
+	309f  Camera
+	30a0  Camera
+	30a1  Camera
+	30a2  Camera
+	30a8  Elura 60E/Optura 40 (ptp)
+	30a9  MVX25i (normal mode) / Optura 40 (normal mode)
+	30b1  PowerShot S70 (normal mode) / PowerShot S70 (PTP mode)
+	30b2  PowerShot S60 (normal mode) / PowerShot S60 (PTP mode)
+	30b3  PowerShot G6 (normal mode) / PowerShot G6 (PTP mode)
+	30b4  PowerShot S500
+	30b5  PowerShot A75
+	30b6  Digital IXUS II2  / Digital IXUS II2 (PTP mode) / PowerShot SD110 (PTP mode) / PowerShot SD110 Digital ELPH
+	30b7  PowerShot A400 / PowerShot A400 (PTP mode)
+	30b8  PowerShot A310 / PowerShot A310 (PTP mode)
+	30b9  Powershot A85
+	30ba  PowerShot S410 Digital Elph
+	30bb  PowerShot A95
+	30bd  CP-220
+	30be  CP-330
+	30bf  Digital IXUS 40
+	30c0  Digital IXUS 30 (PTP mode) / PowerShot SD200 (PTP mode)
+	30c1  Digital IXUS 50 (normal mode) / IXY Digital 55 (normal mode) / PowerShot A520 (PTP mode) / PowerShot SD400 (normal mode)
+	30c2  PowerShot A510 (normal mode) / PowerShot A510 (PTP mode)
+	30c4  Digital IXUS i5 (normal mode) / IXY Digital L2 (normal mode) / PowerShot SD20 (normal mode)
+	30ea  EOS 1D Mark II (PTP mode)
+	30eb  EOS 20D
+	30ec  EOS 20D (ptp)
+	30ee  EOS 350D
+	30ef  EOS 350D (ptp)
+	30f0  PowerShot S2 IS (PTP mode)
+	30f2  Digital IXUS 700 (normal mode) / Digital IXUS 700 (PTP mode) / IXY Digital 600 (normal mode) / PowerShot SD500 (normal mode) / PowerShot SD500 (PTP mode)
+	30f6  SELPHY CP400
+	30f8  Powershot A430
+	30f9  PowerShot A410 (PTP mode)
+	30fc  PowerShot A620 (PTP mode)
+	30fd  PowerShot A610 (normal mode)/PowerShot A610 (PTP mode)
+	30ff  Digital IXUS 55 (PTP mode)/PowerShot SD450 (PTP mode)
+	310b  SELPHY CP600
+	310e  Digital IXUS 50 (PTP mode)
+	3116  Digital IXUS 750 (PTP mode)
+	3117  PowerShot A700
+	3138  PowerShot A710 IS
+	315a  PowerShot G9
+	3176  PowerShot A590
+	31ff  Digital IXUS 55
+04aa  DaeWoo Telecom, Ltd
+04ab  Chromatic Research
+04ac  Micro Audiometrics Corp.
+04ad  Dooin Electronics
+	2501  Bluetooth Device
+04af  Winnov L.P.
+04b0  Nikon Corp.
+	0102  Coolpix 990
+	0103  Coolpix 880
+	0104  Coolpix 995
+	0106  Coolpix 775
+	0107  Coolpix 5000
+	0108  Coolpix 2500
+	0109  Coolpix 2500 (ptp)
+	010a  Coolpix 4500
+	010b  Coolpix 4500 (ptp)
+	010d  Coolpix 5700 (ptp)
+	010e  Coolpix 4300 (storage)
+	010f  Coolpix 4300 (ptp)
+	0110  Coolpix 3500 (Sierra Mode)
+	0111  Coolpix 3500 (ptp)
+	0112  Coolpix 885 (ptp)
+	0113  Coolpix 5000 (ptp)
+	0114  Coolpix 3100 (storage)
+	0115  Coolpix 3100 (ptp)
+	0117  Coolpix 2100 (ptp)
+	0119  Coolpix 5400 (ptp)
+	011d  Coolpix 3700 (ptp)
+	0121  Coolpix 3200 (ptp)
+	0122  Coolpix 2200 (ptp)
+	0126  Coolpix 8800
+	0129  Coolpix 4800 (ptp)
+	012c  Coolpix 4100 (storage)
+	012d  Coolpix 4100 (ptp)
+	012e  Coolpix 5600 (ptp)
+	0130  Coolpix 4600 (ptp)
+	0135  Coolpix 5900 (ptp)
+	0136  Coolpix 7900 (storage)
+	0137  Coolpix 7900 (ptp)
+	0141  Coolpix P2 (storage)
+	0142  Coolpix P2 (ptp)
+	0163  Coolpix P5100 (ptp)
+	0169  Coolpix P50 (ptp)
+	0202  Coolpix SQ (ptp)
+	0203  Coolpix 4200 (mass storage mode)
+	0204  Coolpix 4200 (ptp)
+	0205  Coolpix 5200 (storage)
+	0206  Coolpix 5200 (ptp)
+	0301  Coolpix 2000 (storage)
+	0302  Coolpix 2000 (ptp)
+	0402  DSC D100 (ptp)
+	0403  D2H (mass storage mode)
+	0404  D2H SLR (ptp)
+	0405  D70 (mass storage mode)
+	0406  DSC D70 (ptp)
+	0408  D2X SLR (ptp)
+	0409  D50 digital camera
+	040a  D50 (ptp)
+	040c  D2Hs
+	040e  DSC D70s (ptp)
+	0413  D40 (mass storage mode)
+	4000  Coolscan LS 40 ED
+	4001  LS 50 ED/Coolscan V ED
+	4002  Super Coolscan LS-5000 ED
+04b1  Pan International
+04b3  IBM Corp.
+	3003  Rapid Access III Keyboard
+	3004  Media Access Pro Keyboard
+	300a  Rapid Access IIIe Keyboard
+	3016  UltraNav Keyboard Hub
+	3018  UltraNav Keyboard
+	301b  SK-8815 Keyboard
+	301c  Enhanced Performance Keyboard
+	3020  Enhanced Performance Keyboard
+	3100  NetVista Mouse
+	3103  ScrollPoint Pro Mouse
+	3104  ScrollPoint Wireless Mouse
+	3105  ScrollPoint Optical (HID)
+	3107  ThinkPad 800dpi Optical Travel Mouse
+	3108  800dpi Optical Mouse w/ Scroll Point
+	3109  Optical ScrollPoint Pro Mouse
+	310b  Red Wheel Mouse
+	4427  Portable CD ROM
+	4482  Serial Converter
+	4525  Double sided CRT
+	4550  NVRAM (128 KB)
+	4554  Cash Drawer
+	4580  Hub w/ NVRAM
+	4581  4800-2xx Hub w/ Cash Drawer
+	4604  Keyboard w/ Card Reader
+	4671  4820 LCD w/ MSR/KB
+04b4  Cypress Semiconductor Corp.
+	0000  Dacal DC-101 CD Library
+	0001  Mouse
+	0002  CY7C63x0x Thermometer
+	0101  Keyboard/Hub
+	0102  Keyboard with APM
+	0130  MyIRC Remote Receiver
+	0bad  MetaGeek Wi-Spy
+	1002  CY7C63001 R100 FM Radio
+	1006  Human Interface Device
+	4381  SCAPS USC-1 Scanner Controller
+	4611  Storage Adapter FX2 (CY)
+	4616  Flash Disk (TPP)
+	5500  HID->COM RS232 Adapter
+	6370  ViewMate Desktop Mouse CC2201
+	6560  CY7C65640 USB-2.0 "TetraHub"
+	6830  CY7C68300A EZ-USB AT2 USB 2.0 to ATA/ATAPI
+	6831  Storage Adapter ISD-300LP (CY)
+	7417  Wireless PC Lock
+	8613  CY7C68013 EZ-USB FX2 USB 2.0 Development Kit
+	8614  DTV-DVB UDST7020BDA DVB-S Box(DVBS for MCE2005)
+	cc04  Centor USB RACIA-ALVAR USB PORT
+	cc06  Centor-P RACIA-ALVAR USB PORT
+	d5d5  CY7C63x0x Zoltrix Z-Boxer GamePad
+	f000  CY30700 Licorice evaluation board
+04b5  ROHM LSI Systems USA, LLC
+04b6  Hint Corp.
+04b7  Compal Electronics, Inc.
+04b8  Seiko Epson Corp.
+	0001  Stylus Color 740 / Photo 750
+	0002  ISD Smart Cable for Mac
+	0003  ISD Smart Cable
+	0004  Printer
+	0005  Stylus D88+
+	0006  Printer
+	0007  Printer
+	0101  Perfection 636
+	0102  GT-2200
+	0103  Perfection 610
+	0104  Perfection 1200
+	0105  StylusScan 2000
+	0106  Stylus Scan 2500
+	0107  Expression 1600U
+	0109  Expression 1640 XL
+	010a  Perfection 1640SU
+	010b  Perfection 1240
+	010c  Perfection 640
+	010e  Perfection 1680
+	010f  Perfection 1250
+	0110  Perfection 1650
+	0112  Perfection 2450
+	0114  Perfection 660
+	0116  Perfection 3170 (GT-9400)
+	0118  Perfection 4180 (GF-F600)
+	0119  Perfection 4490 Photo
+	011a  1000 ICS
+	011b  Perfection 2400 Photo
+	011c  Perfection 3200
+	011d  Perfection 1260 Photo
+	011e  Perfection 1660 Photo
+	011f  Perfection 1670
+	0120  Perfection 1270 scanner
+	0121  Perfection 2480 Photo
+	0122  Perfection 3590 scanner
+	0126  GT-15000 (ES-7000)
+	0128  Perfection 4870 (GT-X700)
+	0129  Expression 10000XL (ES-10000G)
+	012a  Perfection 4990 Photo scanner
+	012b  GT-2500 (ES-H300)
+	012c  Perfection V350 (GT-F700)
+	012d  Perfection V10/V100 (GT-S600/F650)
+	012f  Perfection V350 (GT-F700)
+	0202  Receipt Printer M129C
+	0401  CP 800 Digital Camera
+	0402  PhotoPC 850z
+	0403  PhotoPC 3000z
+	0509  JVC PIX-MC10
+	0601  Stylus Photo 875DC Card Reader
+	0602  Stylus Photo 895 Card Reader
+	0801  Stylus CX5200/CX5400/CX6600
+	0802  Stylus CX3200
+	0803  Printer (Composite Device)
+	0804  Storage Device
+	0805  Stylus CX6400
+	0806  Stylus Photo RX600/610
+	0807  Stylus Photo RX500/510
+	0808  Stylus CX5200
+	0809  Storage Device
+	080a  Storage Device
+	080c  ME100
+	080d  Stylus CX4500/4600
+	080e  CX-3500/3600/3650 MFP
+	080f  Stylus Photo RX425 scanner
+	0810  Stylus Photo RX700 (PM-A900)
+	0811  Stylus Photo RX620 all-in-one
+	0812  MFP Composite Device
+	0813  Stylus CX6500/6600
+	0814  (PM-A700)
+	0815  AcuLaser CX11 (LP-A500)
+	0816  Printer (Composite Device)
+	0817  (LP-M5500)
+	0818  Stylus CX3700/CX3800/DX3800
+	0819  Stylus CX4700/CX4800/DX4800 (PX-A750)
+	081a  Stylus Photo RX520/RX530 (PM-A750)
+	081b  MFP Composite Device
+	081c  Stylus Photo RX640/RX650 (PM-A890)
+	081d  (PM-A950)
+	081e  MFP Composite Device
+	081f  Stylus CX7700/7800
+	0820  CX4200 MP scanner
+	0821  MFP Composite Device
+	0822  Storage Device
+	0823  MFP Composite Device
+	0824  Storage Device
+	0825  MFP Composite Device
+	0826  Storage Device
+	0827  Stylus Photo RX560/580/590 (PM-A820)
+	0828  (PM-A970)
+	0829  (PM-T990)
+	082a  (PM-A920)
+	082b  Stylus DX5050
+	082c  Storage Device
+	082d  Storage Device
+	082e  0x082e  DX-60x0 MFP scanner
+	082f  Stylus DX4050
+	0830  Stylus CX2800/CX2900/ME200
+	0831  MFP Composite Device
+	0832  MFP Composite Device
+	0833  (LP-M5600)
+	0834  MFP Composite Device
+	0835  AcuLaser CX21
+	0836  MFP Composite Device
+	0837  MFP Composite Device
+	0838  CX7300/CX7400/DX7400
+	0839  CX8300/CX8400/DX8400
+	083a  CX9300F/CX9400Fax/DX9400F
+	083b  MFP Composite Device
+	083c  MFP Composite Device
+	083d  MFP Composite Device
+	083e  MFP Composite Device
+	083f  Stylus DX4450
+04b9  Rainbow Technologies, Inc.
+	0300  SafeNet USB SuperPro/UltraPro
+	1000  iKey 1000 Token
+	1001  iKey 1200 Token
+	1002  iKey Token
+	1003  iKey Token
+	1004  iKey Token
+	1005  iKey Token
+	1006  iKey Token
+	1200  iKey 2000 Token
+	1201  iKey Token
+	1202  iKey 2032 Token
+	1203  iKey Token
+	1204  iKey Token
+	1205  iKey Token
+	1206  iKey Token
+	1300  iKey 3000 Token
+	1301  iKey 3000
+	1302  iKey Token
+	1303  iKey Token
+	1304  iKey Token
+	1305  iKey Token
+	1306  iKey Token
+04ba  Toucan Systems, Ltd
+04bb  I-O Data Device, Inc.
+	0101  USB2-IDE/ATAPI Bridge Adapter
+	0201  USB2-IDE/ATAPI Bridge Adapter
+	0204  DVD Multi-plus unit iU-CD2
+	0206  DVD Multi-plus unit DVR-UEH8
+	0301  Storage Device
+	0314  USB-SSMRW SD-card
+	0319  USB2-IDE/ATAPI Bridge Adapter
+	031a  USB2-IDE/ATAPI Bridge Adapter
+	031b  USB2-IDE/ATAPI Bridge Adapter
+	031e  USB-SDRW SD-card
+	0502  Nogatech Live! (BT)
+	0901  USB ETT
+	0904  ET/TX Ethernet [pegasus]
+	0913  ET/TX-S Ethernet [pegasus2]
+	0919  USB WN-B11
+	0922  IOData AirPort WN-B11/USBS 802.11b
+	0930  ETG-US2
+	0937  WN-WAG/USL Wireless LAN Adapter
+	0938  WN-G54/USL Wireless LAN Adapter
+	0a03  Serial USB-RSAQ1
+	0a07  USB2-iCN Adapter
+	0a08  USB2-iCN Adapter
+	0c01  FM-10 Pro Disk
+04bd  Toshiba Electronics Taiwan Corp.
+04be  Telia Research AB
+04bf  TDK Corp.
+	0100  MediaReader CF
+	0115  USB-PDC Adapter UPA9664
+	0116  USB-cdmaOne Adapter UCA1464
+	0117  USB-PHS Adapter UHA6400
+	0118  USB-PHS Adapter UPA6400
+	0135  MediaReader Dual
+	0202  73S1121F Smart Card Reader-
+	0309  Bluetooth USB dongle
+	030a  IBM Bluetooth Ultraport Module
+	030b  Bluetooth Device
+	030c  Ultraport Bluetooth Device
+	0310  Integrated Bluetooth
+	0311  Integrated Bluetooth Device
+	0317  Bluetooth UltraPort Module from IBM
+	0318  IBM Integrated Bluetooth
+	0319  Bluetooth Adapter
+	0320  Bluetooth Adapter
+	0321  Bluetooth Device
+	0a28  INDI AV-IN Device
+04c1  U.S. Robotics (3Com)
+	0020  56K Voice Pro
+	0022  56K Voice Pro
+	007e  ISDN TA
+	0082  OfficeConnect Analog Modem
+	008f  Pro ISDN TA
+	0097  OfficeConnect Analog
+	009d  HomeConnect WebCam [vicam]
+	00a9  ISDN Pro TA-U
+	00b9  HomeConnect IDSL Modem
+	3021  56k Voice FaxModem Pro
+04c2  Methode Electronics Far East PTE, Ltd
+04c3  Maxi Switch, Inc.
+	1102  Mouse
+	2102  Mouse
+04c4  Lockheed Martin Energy Research
+04c5  Fujitsu, Ltd
+	1029  fi-4010c Scanner
+	1033  fi-4110CU
+	1041  fi-4120c Scanner
+	1042  fi-4220c Scanner
+	105b  AH-F401U Air H device
+	1096  fi-5110EOX
+	1097  fi-5110C
+	10ae  fi-4120C2
+	10af  fi-4220C2
+	10e0  fi-5120c Scanner
+	10e1  fi-5220C
+	10e7  fi-5900C
+	10fe  S500
+04c6  Toshiba America Electronic Components
+04c7  Micro Macro Technologies
+04c8  Konica Corp.
+	0720  Digital Color Camera
+	0721  e-miniD Camera
+	0722  e-mini
+	0723  KD-200Z Camera
+	0726  KD-310Z Camera
+	0728  Revio C2 Mass Storage Device
+	0729  Revio C2 Digital Camera
+	072c  Revio KD20M
+	072d  Revio KD410Z
+04ca  Lite-On Technology Corp.
+	1766  HID Monitor Controls
+	9304  Hub
+04cb  Fuji Photo Film Co., Ltd
+	0100  FinePix 30i/40i/50i, A101/201, 1300/2200, 1400/2400/2600/2800/4500/4700/4800/4900/6800/6900 Zoom
+	0103  FinePix NX-500/NX-700 printer
+	0104  FinePix A101, 2600/2800/4800/6800 Zoom (PC CAM)
+	0108  FinePix F601 Zoom (DSC)
+	0109  FinePix F601 Zoom (PC CAM)
+	010a  FinePix S602 (Pro) Zoom (DSC)
+	010b  FinePix S602 (Pro) Zoom (PC CAM)
+	010d  FinePix Digital Camera 020531
+	010e  FinePix F402 Zoom (DSC)
+	010f  FinePix F402 Zoom (PC CAM)
+	0110  FinePix M603 Zoom (DSC)
+	0111  FinePix M603 Zoom (PC CAM)
+	0112  FinePix A202, A200 Zoom (DSC)
+	0113  FinePix A202, A200 Zoom (PC CAM)
+	0114  FinePix F401 Zoom (DSC)
+	0115  FinePix F401 Zoom (PC CAM)
+	0116  FinePix A203 Zoom (DSC)
+	0117  FinePix A203 Zoom (PC CAM)
+	0118  FinePix A303 Zoom (DSC)
+	0119  FinePix A303 Zoom (PC CAM)
+	011a  FinePix S304/3800 Zoom (DSC)
+	011b  FinePix S304/3800 Zoom (PC CAM)
+	011c  FinePix A204/2650 Zoom (DSC)
+	011d  FinePix A204/2650 Zoom (PC CAM)
+	0120  FinePix F700 Zoom (DSC)
+	0121  FinePix F700 Zoom (PC CAM)
+	0122  FinePix F410 Zoom (DSC)
+	0123  FinePix F410 Zoom (PC CAM)
+	0124  FinePix A310 Zoom (DSC)
+	0125  FinePix A310 Zoom (PC CAM)
+	0126  FinePix A210 Zoom (DSC)
+	0127  FinePix A210 Zoom (PC CAM)
+	0128  FinePix A205(S) Zoom (DSC)
+	0129  FinePix A205(S) Zoom (PC CAM)
+	012a  FinePix F610 Zoom (DSC)
+	012b  FinePix Digital Camera 030513
+	012c  FinePix S7000 Zoom (DSC)
+	012d  FinePix S7000 Zoom (PC CAM)
+	012f  FinePix Digital Camera 030731
+	0130  FinePix S5000 Zoom (DSC)
+	0131  FinePix S5000 Zoom (PC CAM)
+	013b  FinePix Digital Camera 030722
+	013c  FinePix S3000 Zoom (DSC)
+	013d  FinePix S3000 Zoom (PC CAM)
+	013e  FinePix F420 Zoom (DSC)
+	013f  FinePix F420 Zoom (PC CAM)
+	0142  FinePix S7000 Zoom (PTP)
+	0148  FinePix A330 Zoom (DSC)
+	0149  FinePix A330 Zoom (UVC)
+	014a  FinePix A330 Zoom (PTP)
+	014b  FinePix A340 Zoom (DSC)
+	0159  FinePix F710 Zoom (DSC)
+	0165  FinePix S3500 Zoom (DSC)
+	0168  FinePix E500 Zoom (DSC)
+	0169  FinePix E500 Zoom (UVC)
+	016b  FinePix E510 Zoom (DSC)
+	016c  FinePix E510 Zoom (PC CAM)
+	016e  FinePix S5500 Zoom (DSC)
+	016f  FinePix S5500 Zoom (UVC)
+	0171  FinePix E550 Zoom (DSC)
+	0172  FinePix E550 Zoom (PTP)
+	0177  FinePix F10 (DSC)
+	0179  Finepix F10 (PTP)
+	0186  FinePix S5200/S5600 Zoom (DSC)
+	0188  FinePix S5200/S5600 Zoom (PTP)
+	018e  FinePix S9500 Zoom (DSC)
+	018f  FinePix S9500 Zoom (PTP)
+	0192  FinePix E900 Zoom (DSC)
+	0193  FinePix E900 Zoom (PTP)
+	019b  FinePix F30 (PTP)
+	01bf  FinePix F6000fd/S6500fd Zoom (PTP)
+	01c0  FinePix F20 (PTP)
+	01c1  FinePix F31fd (PTP)
+	01c4  FinePix S5700 Zoom (PTP)
+	01c5  FinePix F40fd (PTP)
+	01c6  FinePix A820 Zoom (PTP)
+	01d2  FinePix A800 Zoom (PTP)
+	01d5  FinePix F47 (PTP)
+04cc  Philips Semiconductors
+	1122  Hub
+	1521  USB 2.0 Hub
+	8116  Camera
+04cd  Tatung Co. Of America
+04ce  ScanLogic Corp.
+	0002  SL11R-IDE IDE Bridge
+	0100  USB2PRN Printer Class
+	0300  Phantom 336CX - C3 scanner
+	04ce  SL11DEMO, VID: 0x4ce, PID: 0x4ce
+	07d1  SL11R, VID: 0x4ce, PID: 0x07D1
+04cf  Myson Century, Inc.
+	0800  MTP800 Mass Storage Device
+	8810  CS8810 Mass Storage Device
+	8811  CS8811 Mass Storage Device
+	8813  CS8813 Mass Storage Device
+	8818  USB2.0 to ATAPI Bridge Controller
+04d0  Digi International
+04d1  ITT Canon
+04d2  Altec Lansing Technologies
+	0070  ADA70 Speakers
+	0305  Non-Compliant Audio Device
+	0311  ADA-310 Speakers
+	2060  Claritel-i750 - vp
+	ff05  ADA-305 Speakers
+	ff47  Lansing HID Audio Controls
+	ff49  Lansing HID Audio Controls
+04d3  VidUS, Inc.
+04d4  LSI Logic, Inc.
+04d5  Forte Technologies, Inc.
+04d6  Mentor Graphics
+04d7  Oki Semiconductor
+	1be4  Bluetooth Device
+04d8  Microchip Technology, Inc.
+	0002  USB-LCD 2x20
+	8000  In-Circuit Debugger
+	8001  ICD2 in-circuit debugger
+04d9  Holtek Semiconductor, Inc.
+	1203  MC Industries Keyboard
+04da  Panasonic (Matsushita)
+	0901  LS-120 Camera
+	0b01  CD-R/RW Drive
+	0b03  SuperDisk 240MB
+	0d01  CD-R Drive KXL-840AN
+	0d09  CD-R Drive KXL-RW32AN
+	0d0a  CD-R Drive KXL-CB20AN
+	0d0d  CDRCB03
+	0d0e  DVD-ROM & CD-R/RW
+	0f40  Printer
+	1500  MFSUSB Driver
+	1b00  MultiMediaCard
+	2121  EB-VS6
+	2317  DVC USB-SERIAL Driver for WinXP
+	2319  NV-GS15 (webcam mode)
+	231d  DVC Web Camera Device
+	231e  DVC DV Stream Device
+	2372  Lumix DMC-FZ10 Camera
+	2374  DMC-FZ20
+04db  Hypertec Pty, Ltd
+04dc  Huan Hsin Holdings, Ltd
+04dd  Sharp Corp.
+	13a6  MFC2000
+	6006  AL-1216
+	6007  AL-1045
+	6008  AL-1255
+	6009  AL-1530CS
+	600a  AL-1540CS
+	600b  AL-1456
+	600c  AL-1555
+	600d  AL-1225
+	600e  AL-1551CS
+	600f  AR-122E
+	6010  AR-152E
+	6011  AR-157E
+	6012  SN-1045
+	6013  SN-1255
+	6014  SN-1456
+	6015  SN-1555
+	6016  AR-153E
+	6017  AR-122E N
+	6018  AR-153E N
+	6019  AR-152E N
+	601a  AR-157E N
+	601b  AL-1217
+	601c  AL-1226
+	601d  AR-123E
+	7002  DVC Ver.1.0
+	7004  VE-CG40U Digital Still Camera
+	7005  VE-CG30 Digital Still Camera
+	7007  VL-Z7S Digital Camcorder
+	8004  Zaurus SL-5000D/SL-5500 PDA
+	8005  Zaurus A-300
+	8006  Zaurus SL-B500/SL-5600 PDA
+	8007  Zaurus C-700 PDA
+	9014  IM-DR80 Portable NetMD Player
+	9031  Zaurus C-750/C-760/C-860/SL-C3000 PDA
+	9032  Zaurus SL-6000
+	903a  GSM GPRS
+	9050  Zaurus C-860 PDA
+	9056  Viewcam Z
+	9073  AM-900
+	9074  GSM GPRS
+	90a9  Sharp Composite
+	90d0  USB-to-Serial Comm. Port
+	90f2  Sharp 3G GSM USB Control
+	9120  WS004SH
+	9122  WS007SH
+	9123  W-ZERO3 ES Smartphone
+	91a3  922SH Internet Machine
+04de  MindShare, Inc.
+04df  Interlink Electronics
+04e1  Iiyama North America, Inc.
+	0201  Monitor Hub
+04e2  Exar Corp.
+04e3  Zilog, Inc.
+04e4  ACC Microelectronics
+04e5  Promise Technology
+04e6  SCM Microsystems, Inc.
+	0001  E-USB ATA Bridge
+	0002  eUSCSI SCSI Bridge
+	0003  eUSB SmartMedia Card Reader
+	0005  eUSB SmartMedia/CompactFlash Card Reader
+	0006  eUSB SmartMedia Card Reader
+	0007  Hifd
+	0009  eUSB ATA/ATAPI Adapter
+	000a  eUSB CompactFlash Adapter
+	000b  eUSCSI Bridge
+	000c  eUSCSI Bridge
+	000d  Dazzle MS
+	0012  Dazzle SD/MMC
+	0101  eUSB ATA Bridge
+	0311  Dazzle DM-CF
+	0312  Dazzle DM-SD/MMC
+	0313  Dazzle SM
+	0314  Dazzle MS
+	0322  e-Film Reader-5
+	0325  eUSB ORCA Quad Reader
+	0327  Digital Media Reader
+	03fe  DMHS2 DFU Adapter
+	0406  eUSB SmartDM Reader
+	04e6  eUSB DFU Adapter
+	04e7  STCII DFU Adapter
+	04e8  eUSBDM DFU Adapter
+	04e9  DM-E DFU Adapter
+	0500  Veridicom 5thSense Fingerprint Sensor and eUSB SmartCard
+	0701  DCS200 Loader Device
+	0702  DVD Creation Station 200
+	0703  DVC100 Loader Device
+	0704  Digital Video Creator 100
+	1001  SCR300 Smart Card Reader
+	1010  USBAT-2 CompactFlash Card Reader
+	1014  e-Film Reader-3
+	1020  USBAT ATA/ATAPI Adapter
+	2007  RSA SecurID ComboReader
+	2009  Citibank Smart Card Reader
+	200a  Reflex v.2 Smart Card Reader
+	200d  STR391 Reader
+	5111  SCR331-DI SmartCard Reader
+	5113  SCR333 SmartCard Reader
+	5114  SCR331-DI SmartCard Reader
+	5115  SCR335 SmartCard Reader
+	5116  SCR331-LC1 SmartCard Reader
+	5117  SCR3320 - Smart Card Reader
+	5118  Expresscard SIM Card Reader
+	5119  SCR3340 - ExpressCard54 Smart Card Reader
+	511b  SmartCard Reader
+	511d  SCR3311 Smart Card Reader
+	5120  SCR331-DI SmartCard Reader
+	5121  SDI010 Smart Card Reader
+	5151  SCR338 Keyboard Smart Card Reader
+	5410  SCR35xx Smart Card Reader
+	e000  SCRx31 Reader
+	e001  SCR331 SmartCard Reader
+	e003  SPR532 PinPad SmartCard Reader
+04e7  Elo TouchSystems
+	0001  TouchScreen
+	0002  Touchmonitor Interface 2600 Rev 2
+	0004  4000U CarrollTouch® Touchmonitor Interface
+	0007  2500U IntelliTouch® Touchmonitor Interface
+	0008  3000U AccuTouch® Touchmonitor Interface
+	0009  4000U CarrollTouch® Touchmonitor Interface
+	0020  Touchscreen Interface (2700)
+	0021  Touchmonitor Interface
+	0030  4500U CarrollTouch® Touchmonitor Interface
+	0032  Touchmonitor Interface
+	0033  Touchmonitor Interface
+	0041  5010 Surface Capacitive Touchmonitor Interface
+	0042  Touchmonitor Interface
+	0050  2216 AccuTouch® Touchmonitor Interface
+	0071  Touchmonitor Interface
+	0072  Touchmonitor Interface
+	0081  Touchmonitor Interface
+	0082  Touchmonitor Interface
+	00ff  Touchmonitor Interface
+04e8  Samsung Electronics Co., Ltd
+	0110  Connect3D Flash Drive
+	0111  Connect3D Flash Drive
+	1003  MP3 Player and Recorder
+	1006  SDC-200Z
+	3004  ML-4600
+	3005  Docuprint P1210
+	3008  ML-6060 laser printer
+	300c  ML-1210 Printer
+	300e  Laser Printer
+	3104  ML-3550N
+	3226  Laser Printer
+	3228  Laser Printer
+	322a  Laser Printer
+	322c  Laser Printer
+	3230  ML-1440
+	3232  Laser Printer
+	3236  ML-1450
+	3238  ML-1430
+	323a  ML-1710 Printer
+	323b  Phaser 3130
+	323c  Laser Printer
+	323d  Phaser 3120
+	323e  Laser Printer
+	3240  Laser Printer
+	3242  Laser Printer
+	3248  Color Laser Printer
+	324a  Laser Printer
+	324c  ML-1740 Printer
+	324d  Phaser 3121
+	325f  Phaser 3425 Laser Printer
+	3260  CLP-510 Color Laser Printer
+	3268  ML-1610 Mono Laser Printer
+	326c  ML-2010P Mono Laser Printer
+	3409  SCX-4216F Scanner
+	340c  SCX-5x15 Series
+	340d  SCX-6x20 Series
+	340e  MFP 560 Series
+	340f  Printing Support
+	3412  SCX-4x20 Series
+	3413  SCX-4100 Scanner
+	3415  Composite Device
+	3419  Composite Device
+	341a  Printing Support
+	341b  SCX-4200 Series
+	341c  Composite Device
+	341d  Composite Device
+	341f  Composite Device
+	3420  Composite Device
+	3605  InkJet Color Printer
+	3606  InkJet Color Printer
+	3609  InkJet Color Printer
+	3902  InkJet Color Printer
+	3903  Xerox WorkCentre XK50cx
+	390f  InkJet Color Printer
+	3911  SCX-1020 Series
+	5000  YP-MF Series
+	5001  YP-100
+	5002  YP-30
+	5003  YP-700
+	5004  YP-30
+	5005  YP-300
+	5006  YP-750
+	500d  MP3 Player
+	5010  MP3 Player
+	5011  YP-780
+	5013  YP-60
+	5015  yepp upgrade
+	501b  MP3 Player
+	503b  YP-U1 MP3 Player
+	5050  YP-U2 MP3 Player
+	507d  YP-U3 MP3 Player
+	508b  YP-S5 MP3 Player
+	5a00  YP-NEU
+	5a01  YP-NDU
+	5a03  Yepp MP3 Player
+	5a04  YP-800
+	5a08  YP-90
+	5a0f  MTP Device
+	5b01  Memory Stick Reader/Writer
+	5b02  Memory Stick Reader/Writer
+	5b03  Memory Stick Reader/Writer
+	5b04  Memory Stick Reader/Writer
+	5b05  Memory Stick Reader/Writer
+	5b11  SEW-2001u Card
+	5f00  NEXiO Sync
+	5f01  NEXiO Sync
+	5f02  NEXiO Sync
+	5f03  NEXiO Sync
+	5f04  NEXiO Sync
+	6601  Z100 Mobile Phone
+	6611  MITs Sync
+	6613  MITs Sync
+	6615  MITs Sync
+	6617  MITs Sync
+	6619  MITs Sync
+	661b  MITs Sync
+	661e  Handheld
+	6620  Handheld
+	6622  Handheld
+	6624  Handheld
+	662e  MITs Sync
+	6630  MITs Sync
+	6632  MITs Sync
+	663f  SGH-E720/SGH-E840
+	6640  Usb Modem Enumerator
+	7011  SEW-2003U Card
+	7021  Bluetooth Device
+	7061  eHome Infrared Receiver
+	7081  Human Interface Device
+	8001  Handheld
+	e020  SERI E02 SCOM 6200 UMTS Phone
+	e021  SERI E02 SCOM 6200 Virtual UARTs
+	e022  SERI E02 SCOM 6200 Flash Load Disk
+	ff30  SG_iMON
+04e9  PC-Tel, Inc.
+04ea  Brooktree Corp.
+04eb  Northstar Systems, Inc.
+04ec  Tokyo Electron Device, Ltd
+04ed  Annabooks
+04ef  Pacific Electronic International, Inc.
+04f0  Daewoo Electronics Co., Ltd
+04f1  Victor Company of Japan, Ltd
+	0001  GC-QX3 Digital Still Camera
+	0004  GR-DVL815U Digital Video Camera
+	0006  DV Camera Storage
+	0008  GZ-MG30AA/MC500E Digital Video Camera
+	0009  GR-DX25EK Digital Video Camera
+	000a  GR-D72 Digital Video Camera
+	3008  MP-PRX1 Ethernet
+04f2  Chicony Electronics Co., Ltd
+	0001  KU-8933 Keyboard
+	0002  NT68P81 Keyboard
+	0110  KU-2971 Keyboard
+	0111  KU-9908 Keyboard
+	0112  KU-8933 Keyboard with PS/2 Mouse port
+	0116  KU-2971 German Keyboard
+	0403  KU-0420 keyboard
+	a001  E-Video DC-100 Camera
+	a120  ORITE CCD Webcam(PC370R)
+	a121  ORITE CCD Webcam(PC370R)
+	a122  ORITE CCD Webcam(PC370R)
+	a123  ORITE CCD Webcam(PC370R)
+	a124  ORITE CCD Webcam(PC370R)
+	a133  Gateway Webcam
+	a204  DSC WIA Device (1300)
+	a208  DSC WIA Device (2320)
+	a209  Labtec DC-2320
+	a20a  DSC WIA Device (3310)
+	a20c  DSC WIA Device (3320)
+	a210  Audio Device
+	b009  Integrated Camera
+	b010  Integrated Camera
+	b012  1.3 MPixel UVC webcam
+	b018  Video Device
+	b022  Camera
+	b025  Camera
+	b027  Gateway Webcam
+	b028  VGA UVC WebCam
+04f3  Elan Microelectronics Corp.
+	0210  AM-400 Hama Optical Mouse
+04f4  Harting Elektronik, Inc.
+04f5  Fujitsu-ICL Systems, Inc.
+04f6  Norand Corp.
+04f7  Newnex Technology Corp.
+04f8  FuturePlus Systems
+04f9  Brother Industries, Ltd
+	0002  HL-1050 Laser Printer
+	0005  Printer
+	0006  HL-1240 Laser Printer
+	0007  HL-1250 Laser Printer
+	0008  HL-1270 Laser Printer
+	0009  Printer
+	000a  P2500 Series
+	000b  Printer
+	000c  Printer
+	000d  HL-1440 Laser Printer
+	000e  HL-1450 series
+	000f  HL-1470N series
+	0010  Printer
+	0011  Printer
+	0012  Printer
+	0013  Printer
+	0014  Printer
+	0015  Printer
+	0016  Printer
+	0017  Printer
+	0018  Printer
+	001c  Printer
+	001e  Printer
+	0020  HL-5130 series
+	0021  HL-5140 series
+	0022  HL-5150D series
+	0023  HL-5170DN series
+	0024  Printer
+	0025  Printer
+	0027  HL-2030 Laser Printer
+	0028  Printer
+	0029  Printer
+	002a  Printer
+	002b  Printer
+	002c  Printer
+	002d  Printer
+	0100  MFC8600/9650 Series
+	0101  MFC9600/9870 Series
+	0102  MFC9750/1200 Series
+	0104  MFC-8300J
+	0105  MFC-9600J
+	0106  MFC-7300C
+	0107  MFC-7400C
+	0108  MFC-9200C
+	0109  MFC-830
+	010a  MFC-840
+	010b  MFC-860
+	010c  MFC-7400J
+	010d  MFC-9200J
+	010e  MFC3100C Scanner
+	010f  MFC 5100C
+	0110  MFC4800 Scanner
+	0111  MFC 6800
+	0112  DCP1000 Port(FaxModem)
+	0113  MFC-8500
+	0114  MFC9700 Port(FaxModem)
+	0115  MFC9800 Scanner
+	0116  DCP1400 Scanner
+	0119  MFC-9660
+	011b  MFC-9880
+	011c  MFC-9760
+	011d  MFC-9070
+	011e  MFC-9180
+	011f  MFC-9160
+	0120  MFC580 Port(FaxModem)
+	0121  MFC-590
+	0122  MFC-5100J
+	0129  Imagistics 2500 (MFC-8640D clone)
+	012f  FAX-4750e
+	0132  MFC-5200C RemovableDisk
+	0135  MFC-100 Scanner
+	0136  MFC-150CL Scanner
+	013c  MFC-890 Port
+	013d  MFC-5200J Printer
+	013e  MFC-4420C RemovableDisk
+	013f  MFC-4820C RemovableDisk
+	0140  DCP-8020
+	0141  DCP-8025D
+	0142  MFC-8420
+	0143  MFC-8820D
+	0144  DCP-4020C RemovableDisk
+	0146  MFC-3220C
+	0147  FAX-1820C Printer
+	0148  MFC-3320CN Printer
+	0149  FAX-1920CN Printer
+	014a  MFC-3420C
+	014b  MFC-3820CN
+	014d  FAX-1815C Printer
+	014e  MFC-8820J
+	0150  MFC-8220 Port(FaxModem)
+	0151  MFC-8210J
+	0157  MFC-3420J Printer
+	0158  MFC-3820JN Port(FaxModem)
+	015d  MFC Composite Device
+	015e  DCP-8045D
+	015f  MFC-8440
+	0160  MFC-8840D
+	0161  MFC-210C
+	0162  MFC-420CN Remote Setup Port
+	0163  MFC-410CN RemovableDisk
+	0165  MFC-620CN
+	0166  MFC-610CLN RemovableDisk
+	0168  MFC-620CLN
+	0169  DCP-110C RemovableDisk
+	016b  DCP-310CN RemovableDisk
+	016c  FAX-2440C Printer
+	016d  MFC-5440CN
+	016e  MFC-5840CN Remote Setup Port
+	0170  FAX-1840C Printer
+	0171  FAX-1835C Printer
+	0172  FAX-1940CN Printer
+	0173  MFC-3240C Remote Setup Port
+	0174  MFC-3340CN RemovableDisk
+	017b  Imagistics sx2100
+	0180  MFC-7420
+	0181  MFC-7820N Port(FaxModem)
+	0182  Composite Device
+	0183  DCP-7020
+	0184  DCP-7025 Printer
+	0185  MFC-7220 Printer
+	0186  Composite Device
+	0187  FAX-2820 Printer
+	0188  FAX-2920 Printer
+	018a  MFC-9420CN
+	018c  DCP-115C
+	018d  DCP-116C
+	018e  DCP-117C
+	018f  DCP-118C
+	0190  DCP-120C
+	0191  DCP-315CN
+	0192  DCP-340CW
+	0193  MFC-215C
+	0194  MFC-425CN
+	0195  MFC-820CW Remote Setup Port
+	0196  MFC-820CN Remote Setup Port
+	0197  MFC-640CW
+	019a  MFC-840CLN Remote Setup Port
+	01a2  MFC-8640D
+	01a3  Composite Device
+	01a4  DCP-8065DN Printer
+	01a5  MFC-8460N Port(FaxModem)
+	01a6  MFC-8860DN Port(FaxModem)
+	01a7  MFC-8870DW Printer
+	01a8  DCP-130C
+	01a9  DCP-330C
+	01aa  DCP-540CN
+	01ab  MFC-240C
+	01ae  DCP-750CW RemovableDisk
+	01af  MFC-440CN
+	01b0  MFC-660CN
+	01b1  MFC-665CW Remote Setup Port
+	01b2  MFC-845CW Remote Setup Port
+	01b4  MFC-460CN Remote Setup Port
+	01b5  MFC-630CD
+	01b6  MFC-850CDN
+	01b7  MFC-5460CN Remote Setup Port
+	01b8  MFC-5860CN
+	01ba  MFC-3360C
+	01bd  MFC-8660DN
+	01be  DCP-750CN RemovableDisk
+	01bf  MFC-860CDN Remote Setup Port
+	01c0  DCP-128C
+	01c1  DCP-129C
+	01c2  DCP-131C
+	01c3  DCP-329C
+	01c4  DCP-331C
+	01c5  MFC-239C
+	01ca  MFC-9440CN Remote Setup Port
+	01ce  DCP-135C
+	01cf  DCP-150C
+	01d0  DCP-350C
+	01d1  DCP-560CN
+	01d4  MFC-230C
+	01d5  MFC-235C
+	01d6  MFC-260C
+	01df  DCP-155C
+	01e0  MFC-265C
+	01e1  DCP-153C
+	01e2  DCP-157C
+	01e3  DCP-353C
+	01e4  DCP-357C
+	1000  Printer
+	1002  Printer
+	2002  PTUSB Printing
+	2004  PT-2300/2310 p-Touch Laber Printer
+	2015  QL-500 P-touch label printer
+	2100  Card Reader Writer
+04fa  Dallas Semiconductor
+	2490  DS1490F 2-in-1 Fob, 1-Wire adapter
+	4201  DS4201 Audio DAC
+04fb  Biostar Microtech International Corp.
+04fc  Sunplus Technology Co., Ltd
+	0003  CM1092 Optical Scroller Mouse
+	0013  ViewMate Desktop Mouse CC2201
+	0015  ViewMate Desktop Mouse CC2201
+	0232  Fingerprint
+	0561  Flexcam 100
+	1533  Mass Storage
+	504a  SPCA504a Digital Camera
+	504b  Aiptek, 1.3 mega PockerCam
+	5330  Digitrex 2110
+	5331  Vivitar Vivicam 10
+	5720  Card Reader Driver
+	7333  Finet Technology Palmpix DC-85
+	757a  Aiptek, MP315 MP3 Player
+	ffff  PureDigital Ritz Disposable
+04fd  Soliton Systems, K.K.
+	0003  Smart Card Reader II
+04fe  PFU, Ltd
+04ff  E-CMOS Corp.
+0500  Siam United Hi-Tech
+	0001  DART Keyboard Mouse
+	0002  DART-2 Keyboard
+0501  Fujikura DDK, Ltd
+0502  Acer, Inc.
+	0001  Handheld
+	0736  Handheld
+	15b1  PDA n311
+	1631  c10 Series
+	1632  c20 Series
+	16e1  n10 Handheld Sync
+	16e2  n20 Pocket PC Sync
+	16e3  n30 Handheld Sync
+	d001  Divio NW801/DVC-V6+ Digital Camera
+0503  Hitachi America, Ltd
+0504  Hayes Microcomputer Products
+0506  3Com Corp.
+	009d  HomeConnect Camera
+	00a0  3CREB96 Bluetooth Adapter
+	00a1  Bluetooth Device
+	00a2  Bluetooth Device
+	00df  3Com Home Connect lite
+	0100  HomeConnect ADSL Modem Driver
+	03e8  3C19250 Ethernet [klsi]
+	0a01  3CRSHEW696 Wireless Adapter
+	0a11  3CRWE254G72 802.11g Adapter
+	11f8  HomeConnect 3C460
+	2922  HomeConnect Cable Modem External with
+	3021  U.S.Robotics 56000 Voice FaxModem Pro
+	4601  3C460B 10/100 Ethernet Adapter
+	f002  3CP4218 ADSL Modem (pre-init)
+	f003  3CP4218 ADSL Modem
+	f100  3CP4218 ADSL Modem (pre-init)
+0507  Hosiden Corp.
+	0011  Konami ParaParaParadise Controller
+0508  Clarion Co., Ltd
+0509  Aztech Systems, Ltd
+	0801  ADSL Modem
+	0802  ADSL Modem (RFC1483)
+	0806  DSL Modem
+	080f  Binatone ADSL500 Modem Network Interface
+	0812  Pirelli ADSL Modem Network Interface
+050a  Cinch Connectors
+050b  Cable System International
+050c  InnoMedia, Inc.
+050d  Belkin Components
+	0004  Direct Connect
+	0012  F8T012 Bluetooth Adapter
+	0013  F8T013 Bluetooth Adapter
+	0050  F5D6050 802.11b Wireless Adapter
+	0081  F8T001v2 Bluetooth
+	0083  Bluetooth Device
+	0084  F8T003v2 Bluetooth
+	0102  Flip KVM
+	0103  F5U103 Serial Adapter [etek]
+	0106  VideoBus II Adapter, Video
+	0108  F1DE108B KVM
+	0109  F5U109/F5U409 PDA Adapter
+	0115  SCSI Adapter
+	0119  F5U120-PC Dual PS/2 Ports
+	0121  F5D5050 100Mbps Ethernet
+	0122  Ethernet Adapter
+	0131  Bluetooth Device with trace filter
+	0201  Peripheral Switch
+	0208  USBView II Video Adapter [nt1004]
+	0210  F5U228 Hi-Speed USB 2.0 DVD Creator
+	0211  F5U211 USB 2.0 15-in-1 Media Reader & Writer
+	0224  F5U224 USB 2.0 4-Port Hub
+	0234  F5U234 USB 2.0 4-Port Hub
+	0237  F5U237 USB 2.0 7-Port Hub
+	0240  F5U240 USB 2.0 CF Card Reader
+	0257  F5U257 Serial
+	0409  F5U409 Serial
+	0551  F6C550-AVR UPS
+	0802  Nostromo n40 Gamepad
+	0803  Nostromo 1745 GamePad
+	0805  Nostromo N50 GamePad
+	0815  Nostromo n52 HID SpeedPad Mouse Wheel
+	0826  ErgoFit Wireless Optical Mouse (HID)
+	0980  HID UPS Battery
+	1202  F5U120-PC Parallel Printer Port
+	1203  F5U120-PC Serial Port
+	258a  F5U258 Host to Host cable
+	3101  F1DF102U/F1DG102U Flip Hub
+	3201  F1DF102U/F1DG102U Flip KVM
+	4050  ZD1211B
+	5055  F5D5055
+	6051  11Mbps Wireless Network Adapter
+	7050  F5D7050 ver 1000 WiFi
+	7051  F5D7051 54g USB Network Adapter
+	705a  F5D7050A Wireless Adapter
+	705b  Wireless G Adapter
+	705c  F5D7050 v4000 Wireless Adapter
+	905b  F5D9050 ver 3 Wireless Adapter
+	905c  Wireless G Plus MIMO Network Adapter
+050e  Neon Technology, Inc.
+050f  KC Technology, Inc.
+	0001  Hub
+	0003  KC82C160S Hub
+	0180  KC-180 IrDA Dongle
+	0190  KC2190 USB Host-to-Host cable
+0510  Sejin Electron, Inc.
+	0001  Keyboard
+	1000  Keyboard with PS/2 Mouse Port
+	e001  Mouse
+0511  N'Able (DataBook) Technologies, Inc.
+0512  Hualon Microelectronics Corp.
+0513  digital-X, Inc.
+0514  FCI Electronics
+0515  ACTC
+0516  Longwell Electronics
+0517  Butterfly Communications
+0518  EzKEY Corp.
+	0001  USB to PS2 Adaptor v1.09
+	0002  EZ-9900C Keyboard
+0519  Star Micronics Co., Ltd
+	c002  Xlive Bluetooth XBM-100S MP3 Player
+051a  WYSE Technology
+	a005  Smart Display Version 9973
+051b  Silicon Graphics
+051c  Shuttle, Inc.
+	c001  eHome Infrared Receiver
+	c002  eHome Infrared Receiver
+051d  American Power Conversion
+	0001  UPS
+	0002  Uninterruptible Power Supply
+	0003  UPS
+051e  Scientific Atlanta, Inc.
+051f  IO Systems (Elite Electronics), Inc.
+0520  Taiwan Semiconductor Manufacturing Co.
+0521  Airborn Connectors
+0522  Advanced Connectek, Inc.
+0523  ATEN GmbH
+0524  Sola Electronics
+0525  Netchip Technology, Inc.
+	100d  RFMD Bluetooth Device
+	1080  NET1080 USB-USB Bridge
+	a140  USB Clik! 40
+	a141  (OME) PocketZip 40 MP3 Player Driver
+	a220  GVC Bluetooth Wireless Adapter
+	a4a0  Linux-USB "Gadget Zero"
+	a4a1  Linux-USB Ethernet Gadget
+	a4a2  Linux-USB Ethernet/RNDIS Gadget
+	a4a3  Linux-USB user-mode isochronous source/sink
+	a4a4  Linux-USB user-mode bulk source/sink
+	a4a5  Linux-USB File Storage Gadget
+	a4a6  Linux-USB Serial Gadget
+	a4a7  Linux-USB Serial Gadget (CDC ACM mode)
+	a4a8  Linux-USB Printer Gadget
+0526  Temic MHS S.A.
+0527  ALTRA
+0528  ATI Technologies, Inc.
+	7561  TV Wonder
+	7562  TV Wonder, Edition (FN5)
+	7563  TV Wonder, Edition (FI)
+	7564  TV Wonder, Edition (FQ)
+	7565  TV Wonder, Edition (NTSC+)
+	7566  TV Wonder, Edition (FN5)
+	7567  TV Wonder, Edition (FI)
+	7568  TV Wonder, Edition (FQ)
+	7569  Live! Pro (A)
+	756a  Live! Pro Audio (O)
+0529  Aladdin Knowledge Systems
+	0001  HASP v0.06
+	030b  eToken R1 v3.1.3.x
+	0313  eToken R1 v3.2.3.x
+	031b  eToken R1 v3.3.3.x
+	0323  eToken R1 v3.4.3.x
+	0412  eToken R2 v2.2.4.x
+	041a  eToken R2 v2.2.4.x
+	0422  eToken R2 v2.4.4.x
+	042a  eToken R2 v2.5.4.x
+	050c  eToken Pro v4.1.5.x
+	0514  eToken Pro v4.2.5.4
+	0600  eToken Pro 64k (4.2)
+052a  Crescent Heart Software
+052b  Tekom Technologies, Inc.
+	0102  Ca508A HP1020 Camera v.1.3.1.6
+	0801  Yakumo MegaImage 37
+	1512  Yakumo MegaImage IV
+	1513  Aosta CX100 WebCam
+	1514  Aosta CX100 WebCam Storage
+	1905  Yakumo MegaImage 47
+	1911  Yakumo MegaImage 47 SL
+	2202  WDM Still Image Capture
+	2203  Sound Vision Stream Driver
+	3a06  DigiLife DDV-5120A
+	d001  P35U Camera Capture
+052c  Canon Information Systems, Inc.
+052d  Avid Electronics Corp.
+052e  Standard Microsystems Corp.
+052f  Unicore Software, Inc.
+0530  American Microsystems, Inc.
+0531  Wacom Technology Corp.
+0532  Systech Corp.
+0533  Alcatel Mobile Phones
+0534  Motorola, Inc.
+0535  LIH TZU Electric Co., Ltd
+0536  Hand Held Products (Welch Allyn, Inc.)
+	01a0  PDT
+0537  Inventec Corp.
+0538  Caldera International, Inc. (SCO)
+0539  Shyh Shiun Terminals Co., Ltd
+053a  Preh Werke GmbH & Co. KG
+053b  Global Village Communication
+053c  Institut of Microelectronic & Mechatronic Systems
+053d  Silicon Architect
+053e  Mobility Electronics
+053f  Synopsys, Inc.
+0540  UniAccess AB
+	0101  Panache Surf ISDN TA
+0541  Sirf Technology, Inc.
+0543  ViewSonic Corp.
+	00fe  G773 Monitor Hub
+	00ff  P815 Monitor Hub
+	0bf2  airpanel V150 Wireless Smart Display
+	0bf3  airpanel V110 Wireless Smart Display
+	0ed9  Color Pocket PC V35
+	0f01  airsync Wi-Fi Wireless Adapter
+	1527  Color Pocket PC V36
+	1529  Color Pocket PC V37
+	152b  Color Pocket PC V38
+	152e  Pocket PC
+	1921  Communicator Pocket PC
+	1922  Smartphone
+	1923  Pocket PC V30
+	1a11  Wireless 802.11g Adapter
+	1e60  TA310 - ATSC/NTSC/PAL Driver(PCM4)
+	4153  ViewSonic G773 Control (?)
+0544  Cristie Electronics, Ltd
+0545  Xirlink, Inc.
+	7333  Trution Web Camera
+	8002  IBM NetCamera
+	8009  Veo PC Camera
+	800c  Veo StingRay
+	800d  Veo PC Camera
+	8080  IBM C-It WebCam
+	808a  Veo PC Camera
+	808b  Veo PC Camera
+	808d  Veo PC Camera
+	810a  Veo Advanced Connect WebCam
+	810b  Veo PC Camera
+	810c  Veo PC Camera
+	8135  Veo Mobile/Advanced Web Camera
+	813a  Veo PC Camera
+	813b  Veo PC Camera
+	813c  Veo Mobile/Advanced Web Camera
+	8333  Veo Stingray/Connect Web Camera
+	888c  eVision 123 digital camera
+	888d  eVision 123 digital camera
+0546  Polaroid Corp.
+	0daf  PDC 2300Z
+	1bed  PDC 1320 Camera
+	3097  PDC 310
+	3187  Digital Cam
+	dccf  Sound Vision Stream Driver
+0547  Anchor Chips, Inc.
+	0001  ICSI Bluetooth Device
+	1002  Python2 WDM Encoder
+	2131  AN2131 EZUSB Microcontroller
+	2235  AN2235 EZUSB-FX Microcontroller
+	2710  EZ-Link Loader (EZLNKLDR.SYS)
+	2720  AN2720 USB-USB Bridge
+	2727  Xircom PGUNET USB-USB Bridge
+	2750  EZ-Link (EZLNKUSB.SYS)
+	2810  Cypress USB ATAPI Bridge
+	7777  Bluetooth Device
+	9999  AN2131 uninitialized (?)
+0548  Tyan Computer Corp.
+	1005  EZ Cart II GameBoy Flash Programmer
+0549  Pixera Corp.
+054a  Fujitsu Microelectronics, Inc.
+054b  New Media Corp.
+054c  Sony Corp.
+	0001  HUB
+	0002  Standard HUB
+	0010  DSC-S30/S70/S75/F505V/F505/FD92/W1 Cybershot/Mavica Digital Camera
+	0014  Nogatech USBVision (SY)
+	0022  Storage Adapter V2 (TPP)
+	0023  CD Writer
+	0024  Mavica CD-1000 Camera
+	0025  NW-MS7 Walkman MemoryStick Reader
+	002b  Portable USB Harddrive V2
+	002c  USB Floppy Disk Drive
+	002d  MSAC-US1 MemoryStick Reader
+	002e  Sony HandyCam MemoryStick Reader
+	0030  Storage Adapter V2 (TPP)
+	0032  MemoryStick MSC-U01 Reader
+	0035  Network Walkman (E)
+	0036  Net MD
+	0037  MG Memory Stick Reader/Writer
+	0038  Clie PEG-S300/D PalmOS PDA
+	0039  Network Walkman (MS)
+	003c  VAIO-MX LCD Control
+	0045  Digital Imaging Video
+	0046  Network Walkman
+	004a  Memory Stick Hi-Fi System
+	004b  Memory Stick Reader/Writer
+	004e  DSC-xxx (ptp)
+	0056  MG Memory Stick Reader/Writer
+	0058  Clie PEG-N7x0C PalmOS PDA Mass Storage
+	0066  Clie PEG-N7x0C/PEG-T425 PalmOS PDA Serial
+	0069  Memorystick MSC-U03 Reader
+	006d  Clie PEG-T425 PDA Mass Storage
+	006f  Network Walkman (EV)
+	0073  Storage CRX1750U
+	0075  Net MD
+	0076  Storage Adapter ACR-U20
+	007c  Net MD
+	007f  IC Recorder (MS)
+	0080  Net MD
+	0081  Net MD
+	0084  Net MD
+	0085  Net MD
+	0086  Net MD
+	008b  Micro Vault 64M Mass Storage
+	0095  Sony Clie s360
+	0099  Clie NR70 PDA Mass Storage
+	009a  Clie NR70 PDA Serial
+	00ab  Visual Communication Camera (PCGA-UVC10)
+	00af  DPP-EX Series Digital Photo Printer
+	00bf  IC Recorder (S)
+	00c0  Handycam DCR-30
+	00c6  Net MD
+	00c7  Net MD
+	00c8  MZ-N710 Minidisc Walkman
+	00c9  Net MD
+	00ca  MZ-DN430 Minidisc Walkman
+	00cb  MSAC-US20 Memory Stick Reader
+	00da  Sony Clie nx60
+	00e8  Network Walkman (MS)
+	00e9  Handheld
+	00eb  Net MD
+	0101  Net MD
+	0103  IC Recorder (ST)
+	0105  Micro Vault Hub
+	0107  VCC-U01 Visual Communication Camera
+	0110  Digital Imaging Video
+	0113  Net MD
+	0116  IC Recorder (P)
+	0144  Clie PEG-TH55 PDA
+	0147  Visual Communication Camera (PCGA-UVC11)
+	014c  Aiwa AM-NX9 Net MD Music Recorder MDLP
+	014d  Memory Stick Reader/Writer
+	0154  Eyetoy Audio Device
+	015f  IC Recorder (BM)
+	0169  Clie PEG-TJ35 PDA Serial
+	016a  Clie PEG-TJ35 PDA Mass Storage
+	016b  Mobile HDD
+	016d  IC Recorder (SX)
+	016e  DPP-EX50 Digital Photo Printer
+	0171  Fingerprint Sensor 3500
+	017e  Net MD
+	017f  Hi-MD WALKMAN
+	0180  Net MD
+	0181  Hi-MD WALKMAN
+	0182  Net MD
+	0183  Hi-MD WALKMAN
+	0184  Net MD
+	0185  Hi-MD WALKMAN
+	0186  Net MD
+	0187  Hi-MD WALKMAN
+	0188  Net MD
+	018a  Net MD
+	018b  Hi-MD SOUND GATE
+	019e  Micro Vault 1.0G Mass Storage
+	01ad  ATRAC HDD PA
+	01bd  MRW62E Multi-Card Reader/Writer
+	01c3  NW-E55 Network Walkman
+	01c6  MEMORY P-AUDIO
+	01c7  Printing Support
+	01d0  DVD+RW External Drive DRU-700A
+	01d5  IC RECORDER
+	01de  VRD-VC10 [Video Capture]
+	01e9  Net MD
+	01ea  Hi-MD WALKMAN
+	01ee  IC RECORDER
+	01fa  Sony IC Recorder (P)
+	01fb  NW-E405 Network Walkman
+	020f  Device
+	0210  ATRAC HDD PA
+	0219  Net MD
+	021a  Hi-MD WALKMAN
+	021b  Net MD
+	021c  Hi-MD WALKMAN
+	021d  Net MD
+	0227  Printing Support
+	022c  Net MD
+	022d  Hi-MD AUDIO
+	0233  ATRAC HDD PA
+	0236  Mobile HDD
+	023b  DVD+RW External Drive DRU-800UL
+	023c  Net MD
+	023d  Hi-MD WALKMAN
+	0243  MicroVault Flash Drive
+	0257  IFU-WLM2 USB Wireless LAN Module (Wireless Mode)
+	0258  IFU-WLM2 USB Wireless LAN Module (Memory Mode)
+	0259  IC RECORDER
+	0267  Tachikoma Device
+	0268  Batoh Device
+	0269  HDD WALKMAN
+	026a  HDD WALKMAN
+	0271  IC Recorder (P)
+	027c  NETWORK WALKMAN
+	027e  SONY Communicator
+	027f  IC RECORDER
+	0286  Net MD
+	0287  Hi-MD WALKMAN
+	029b  PRS-500 eBook reader
+	02ae  PlayStation 3 Memory Card Adaptor
+	02af  Handycam DCR-DVD306E
+	02c4  Device
+	02d2  PSP
+054d  Try Corp.
+054e  Proside Corp.
+054f  WYSE Technology Taiwan
+0550  Fuji Xerox Co., Ltd
+	0002  InkJet Color Printer
+	0004  InkJet Color Printer
+	0005  InkJet Color Printer
+0551  CompuTrend Systems, Inc.
+0552  Philips Monitors
+0553  STMicroelectronics Imaging Division (VLSI Vision)
+	0001  TerraCAM
+	0002  CPiA WebCam
+	0100  STV0672 Camera
+	0140  Video Camera
+	0150  CDE CAM 100
+	0151  Digital Blue QX5 Microscope
+	0200  Dual-mode Camera0
+	0201  Dual-mode Camera1
+	0202  Aiptek PenCam 1
+	0674  Multi-mode Camera
+	0679  NMS Video Camera (Webcam)
+	1002  Che-ez! Splash
+0554  Dictaphone Corp.
+0555  ANAM S&T Co., Ltd
+0556  Asahi Kasei Microsystems Co., Ltd
+	0001  AK5370 I/F A/D Converter
+0557  ATEN International Co., Ltd
+	2001  UC-1284 Printer Port
+	2002  10Mbps Ethernet [klsi]
+	2004  UC-100KM PS/2 Mouse and Keyboard adapter
+	2006  UC-1284B Printer Port
+	2007  UC-110T 100Mbps Ethernet [pegasus]
+	2008  UC-232A Serial Port [pl2303]
+	2009  UC-210T Ethernet
+	2202  CS124U Miniview II KVM Switch
+	2600  IDE Bridge
+	4000  DSB-650 10Mbps Ethernet [klsi]
+	7000  Hub
+0558  Truevision, Inc.
+0559  Cadence Design Systems, Inc.
+055a  Kenwood USA
+055b  KnowledgeTek, Inc.
+055c  Proton Electronic Ind.
+055d  Samsung Electro-Mechanics Co.
+	0001  Keyboard
+	0bb1  Bluetooth Device
+	1030  Optical Wheel Mouse (OMS3CB/OMGB30)
+	1031  Optical Wheel Mouse (OMA3CB/OMGI30)
+	1040  Mouse HID Device
+	1050  E-Mail Optical Wheel Mouse (OMS3CE)
+	1080  Optical Wheel Mouse (OMS3CH)
+	2020  Floppy Disk Drive
+	6780  Keyboard V1
+	6781  Keyboard Mouse
+	8001  E.M. Hub
+	9000  AnyCam [pwc]
+	9001  MPC-C30 AnyCam Premium for Notebooks [pwc]
+	a010  WLAN Adapter(SWL-2300)
+	a011  Boot Device
+	a012  WLAN Adapter(SWL-2300)
+	a013  WLAN Adapter(SWL-2350)
+	a230  Boot Device
+	b000  11Mbps WLAN Mini Adapter
+	b230  Netopia 802.11b WLAN Adapter
+	b231  LG Wireless LAN 11b Adapter
+055e  CTX Opto-Electronics Corp.
+055f  Mustek Systems, Inc.
+	0001  ScanExpress 1200 CU
+	0002  ScanExpress 600 CU
+	0003  ScanExpress 1200 USB
+	0006  ScanExpress 1200 UB
+	0007  ScanExpress 1200 USB Plus
+	0008  ScanExpress 1200 CU Plus
+	0010  BearPaw 1200F
+	0210  ScanExpress A3 USB
+	0218  BearPaw 2400 TA
+	0219  BearPaw 2400 TA Plus
+	021a  BearPaw 2448 TA Plus
+	021c  BearPaw 1200 CU Plus
+	021d  BearPaw 2400 CU Plus
+	021e  BearPaw 1200 TA/CS
+	021f  SNAPSCAN e22
+	0400  BearPaw 2400 TA Pro
+	0401  P 3600 A3 Pro
+	0408  BearPaw 2448 CU Pro
+	0873  ScanExpress 600 USB
+	1000  BearPaw 4800 TA Pro
+	a350  gSmart 350
+	a800  MDC 800 Camera
+	b500  MDC 3000 Camera
+	c005  PC CAM 300A
+	c200  gSmart 300
+	c220  gSmart mini
+	c360  Mustek DV 4000
+	c420  gSmart mini 2
+	c440  Mustek DV 3000
+	c520  gSmart mini 3
+	c530  Mustek Gsmart LCD 2
+	c631  MDC-4000
+	c650  Mustek MDC5500Z
+	d001  WCam 300
+	d003  PC CAM 300A
+	d004  PC CAM 300A
+0560  Interface Corp.
+0561  Oasis Design, Inc.
+0562  Telex Communications, Inc.
+	0001  Enhanced Microphone
+	0002  Telex Microphone
+0563  Immersion Corp.
+0564  Chinon Industries, Inc.
+0565  Peracom Networks, Inc.
+	0001  Serial Port [etek]
+	0002  Enet Ethernet [klsi]
+	0003  @Home Networks Ethernet [klsi]
+	0005  Enet2 Ethernet [klsi]
+	0041  Peracom Remote NDIS Ethernet Adapter
+0566  Monterey International Corp.
+	0110  ViewMate Desktop Mouse CC2201
+	1001  ViewMate Desktop Mouse CC2201
+	1002  ViewMate Desktop Mouse CC2201
+	1003  ViewMate Desktop Mouse CC2201
+	1004  ViewMate Desktop Mouse CC2201
+	1005  ViewMate Desktop Mouse CC2201
+	1006  ViewMate Desktop Mouse CC2201
+	1007  ViewMate Desktop Mouse CC2201
+	2800  MIC K/B
+	2801  MIC K/B Mouse
+	2802  Kbd Hub
+0567  Xyratex International, Ltd
+0568  Quartz Ingenierie
+0569  SegaSoft
+056a  Wacom Co., Ltd
+	0000  PenPartner
+	0001  PenPartner 4x5
+	0002  PenPartner 6x8
+	0010  Graphire
+	0011  Graphire 2
+	0013  Graphire 3 4x5
+	0020  Intuos 4x5
+	0021  Intuos 6x8
+	0022  Intuos 9x12
+	0023  Intuos 12x12
+	0024  Intuos 12x18
+	0030  PL400
+	0031  PL500
+	0032  PL600
+	0034  PL550
+	0035  PL800
+	0041  Intuos2 4x5
+	0042  Intuos 2 6x8
+	0043  Intuos 2
+	0044  Intuos2 12x12
+	0045  Intuos2 12x18
+	0400  PenPartner 4x5
+	4850  PenPartner 6x8
+056b  Decicon, Inc.
+056c  eTEK Labs
+	0006  KwikLink Host-Host Connector
+	8007  Kwik232 Serial Port
+	8100  KwikLink Host-Host Connector
+	8101  KwikLink USB-USB Bridge
+056d  EIZO Corp.
+	0000  Hub
+	0001  Monitor
+	0002  HID Monitor Controls
+	0003  Device Bay Controller
+056e  Elecom Co., Ltd
+	0002  29UO Mouse
+	200c  LD-USB/TX
+	4002  Laneed 100Mbps Ethernet LD-USB/TX [pegasus]
+	4005  LD-USBL/TX
+	400b  LD-USB/TX
+	4010  LD-USB20
+	5003  UC-SGT
+	5004  UC-SGT
+	abc1  LD-USB/TX
+056f  Korea Data Systems Co., Ltd
+	cd00  CDM-751 CD organizer
+0570  Epson America
+0571  Interex, Inc.
+	0002  echoFX InterView Lite
+0572  Conexant Systems (Rockwell), Inc.
+	0001  Ezcam II WebCam
+	0002  Ezcam II WebCam
+	0040  Wondereye CP-115 WebCam
+	0041  WebCam Notebook
+	0042  WebCam Notebook
+	1232  V.90 modem
+	1234  Typhoon Redfun Modem V90 56k
+	1252  HCF V90 Data Fax Voice Modem
+	1253  Zoom V.92 Faxmodem
+	1300  SoftK56 Data Fax Voice CARP
+	1301  Modem Enumerator
+	2000  SoftGate 802.11 Adapter
+	2002  SoftGate 802.11 Adapter
+	8390  WinFast PalmTop/Novo TV Video
+	8392  WinFast PalmTop/Novo TV Video
+	cafe  AccessRunner ADSL Modem
+	cb00  E-Tech ADSL Modem v2
+	cb01  GeekADSL Promax Q31 ADSL Modem
+	cb06  StarModem Network Interface
+0573  Zoran Co. Personal Media Division (Nogatech)
+	0003  USBGear USBG-V1
+	0400  D-Link V100
+	0600  Dazzle USBVision (1006)
+	1300  leadtek USBVision (1006)
+	2000  X10 va10a Wireless Camera
+	2001  Dazzle EmMe (2001)
+	2101  Zoran Co. PMD (Nogatech) AV-grabber Manhattan
+	2d00  Osprey 50
+	2d01  Hauppauge USB-Live Model 600
+	3000  Dazzle MicroCam (NTSC)
+	3001  Dazzle MicroCam (PAL)
+	4000  Nogatech TV! (NTSC)
+	4001  Nogatech TV! (PAL)
+	4002  Nogatech TV! (PAL-I-)
+	4003  Nogatech TV! (MF-)
+	4008  Nogatech TV! (NTSC) (T)
+	4009  Nogatech TV! (PAL) (T)
+	4010  Nogatech TV! (NTSC) (A)
+	4100  USB-TV FM (NTSC)
+	4110  PNY USB-TV (NTSC) FM
+	4400  Nogatech TV! Pro (NTSC)
+	4401  Nogatech TV! Pro (PAL)
+	4450  PixelView PlayTv-USB PRO (PAL) FM
+	4451  Nogatech TV! Pro (PAL+)
+	4452  Nogatech TV! Pro (PAL-I+)
+	4500  Nogatech TV! Pro (NTSC)
+	4501  Nogatech TV! Pro (PAL)
+	4550  ZTV ZT-721 2.4GHz USB A/V Receiver
+	4551  Dazzle TV! Pro Audio (P+)
+	4d00  Hauppauge WinTV-USB USA
+	4d01  Hauppauge WinTV-USB
+	4d02  Hauppauge WinTV-USB UK
+	4d03  Hauppauge WinTV-USB France
+	4d04  Hauppauge WinTV (PAL D/K)
+	4d10  Hauppauge WinTV-USB with FM USA radio
+	4d11  Hauppauge WinTV-USB (PAL) with FM radio
+	4d12  Hauppauge WinTV-USB UK with FM Radio
+	4d14  Hauppauge WinTV (PAL D/K FM)
+	4d20  Hauppauge WinTV-USB II (PAL) with FM radio
+	4d21  Hauppauge WinTV-USB II (PAL)
+	4d22  Hauppauge WinTV-USB II (PAL) Model 566
+	4d23  Hauppauge WinTV-USB France 4D23
+	4d24  Hauppauge WinTV Pro (PAL D/K)
+	4d25  Hauppauge WinTV-USB Model 40209 rev B234
+	4d26  Hauppauge WinTV-USB Model 40209 rev B243
+	4d27  Hauppauge WinTV-USB Model 40204 Rev B281
+	4d28  Hauppauge WinTV-USB Model 40204 rev B283
+	4d29  Hauppauge WinTV-USB Model 40205 rev B298
+	4d2a  Hauppague WinTV-USB Model 602 Rev B285
+	4d2b  Hauppague WinTV-USB Model 602 Rev B282
+	4d2c  Hauppauge WinTV Pro (PAL/SECAM)
+	4d30  Hauppauge WinTV-USB FM Model 40211 Rev B123
+	4d31  Hauppauge WinTV-USB III (PAL) with FM radio Model 568
+	4d32  Hauppauge WinTV-USB III (PAL) FM Model 573
+	4d34  Hauppauge WinTV Pro (PAL D/K FM)
+	4d35  Hauppauge WinTV-USB III (PAL) FM Model 597
+	4d36  Hauppauge WinTV Pro (PAL B/G FM)
+	4d37  Hauppauge WinTV-USB Model 40219 rev E189
+	4d38  Hauppauge WinTV Pro (NTSC FM)
+0574  City University of Hong Kong
+0575  Philips Creative Display Solutions
+0576  BAFO/Quality Computer Accessories
+0577  ELSA
+0578  Intrinsix Corp.
+0579  GVC Corp.
+057a  Samsung Electronics America
+057b  Y-E Data, Inc.
+	0000  FlashBuster-U Floppy
+	0001  Tri-Media Reader Floppy
+	0006  Tri-Media Reader Card Reader
+	0010  Memory Stick Reader Writer
+	0020  HEXA Media Drive 6-in-1 Card Reader Writer
+	0030  Memory Card Viewer (TV)
+057c  AVM GmbH
+	0b00  ISDN-Controller B1 Family
+	0c00  ISDN-Controller FRITZ!Card
+	1000  ISDN-Controller FRITZ!Card v2.0
+	1900  ISDN-Controller FRITZ!Card v2.1
+	2000  ISDN-Connector FRITZ!X
+	2200  BlueFRITZ!
+	2300  Teledat X130 DSL
+	2800  ISDN-Connector TA
+	3200  Teledat X130 DSL
+	3500  FRITZ!Card DSL SL
+	3701  FRITZ!Box SL
+	3702  FRITZ!Box
+	3800  BlueFRITZ! Bluetooth Stick
+	3a00  FRITZ!Box Fon
+	3c00  FRITZ!Box WLAN
+	3d00  Fritz!Box
+	3e01  FRITZ!Box (Annex A)
+	4001  FRITZ!Box Fon (Annex A)
+	4101  FRITZ!Box WLAN (Annex A)
+	4201  FRITZ!Box Fon WLAN (Annex A)
+	4601  Eumex 5520PC (WinXP/2000)
+	4602  Eumex 400 (WinXP/2000)
+	4701  AVM FRITZ!Box Fon ata
+	5401  Eumex 300 IP
+	5601  AVM FRITZ!WLAN Stick
+	6201  WLAN USB v1.1
+	62ff  WLAN USB v1.1 [no firmware]
+057d  Shark Multimedia, Inc.
+057e  Nintendo Co., Ltd
+	0306  Wii Remote Controller RVL-003
+057f  QuickShot, Ltd
+	6238  USB StrikePad
+0580  Denron, Inc.
+0581  Racal Data Group
+0582  Roland Corp.
+	0000  UA-100
+	0002  UM-4/MPU-64 MIDI Interface
+	0003  SoundCanvas SC-8850
+	0004  U-8
+	0005  Edirol UM-2 MIDI Adapter
+	0007  SoundCanvas SC-8820
+	0008  PC-300
+	0009  Edirol UM-1SX MIDI Adapter
+	000b  SK-500
+	000c  SC-D70
+	0010  EDIROL UA-5
+	0011  Edirol UA-5 Sound Capture
+	0012  XV-5050
+	0013  XV-5050
+	0014  EDIROL UM-880 MIDI I/F (native)
+	0015  EDIROL UM-880 MIDI I/F (generic)
+	0016  EDIROL SD-90
+	0017  EDIROL SD-90
+	001b  MMP-2
+	001c  MMP-2
+	001d  V-SYNTH
+	001e  V-SYNTH
+	0023  EDIROL UM-550
+	0024  EDIROL UM-550
+	0025  EDIROL UA-20
+	0026  EDIROL UA-20
+	0027  EDIROL SD-20
+	0028  EDIROL SD-20
+	0029  EDIROL SD-80
+	002a  EDIROL SD-80
+	002b  EDIROL UA-700
+	002c  EDIROL UA-700
+	002d  XV-2020 Synthesizer
+	002e  XV-2020 Synthesizer
+	002f  VariOS
+	0030  VariOS
+	0033  EDIROL PCR
+	0034  EDIROL PCR
+	0037  Digital Piano
+	0038  Digital Piano
+	003b  BOSS GS-10
+	003c  BOSS GS-10
+	0040  GI-20
+	0041  GI-20
+	0042  RS-70
+	0043  RS-70
+	0044  EDIROL UA-1000
+	0047  EDIROL UR-80 WAVE
+	0048  EDIROL UR-80 MIDI
+	0049  EDIROL UR-80 WAVE
+	004a  EDIROL UR-80 MIDI
+	004b  EDIROL M-100FX
+	004c  EDIROL PCR-A WAVE
+	004d  EDIROL PCR-A MIDI
+	004e  EDIROL PCR-A WAVE
+	004f  EDIROL PCR-A MIDI
+	0050  EDIROL UA-3FX
+	0052  EDIROL UM-1SX
+	0054  Digital Piano
+	0060  EXR Series
+	0064  EDIROL PCR-1 WAVE
+	0065  EDIROL PCR-1 MIDI
+	0066  EDIROL PCR-1 WAVE
+	0067  EDIROL PCR-1 MIDI
+	006a  SP-606
+	006b  SP-606
+	006d  FANTOM-X
+	006e  FANTOM-X
+	0073  EDIROL UA-25
+	0074  EDIROL UA-25
+	0075  BOSS DR-880
+	0076  BOSS DR-880
+	007a  RD
+	007b  RD
+	007d  EDIROL UA-101
+	0080  G-70
+	0081  G-70
+	008b  EDIROL PC-50
+	008c  EDIROL PC-50
+	008d  EDIROL UA-101 USB1
+	0092  EDIROL PC-80 WAVE
+	0093  EDIROL PC-80 MIDI
+	0096  EDIROL UA-1EX
+	009a  EDIROL UM-3EX
+	009d  EDIROL UM-1
+	00a2  Digital Piano
+	00a3  EDIROL UA-4FX
+	00a6  Juno-G
+	00ad  SH-201
+	00c4  EDIROL M-16DX
+0583  Padix Co., Ltd (Rockfire)
+	2030  RM-203 USB Nest [mode 1]
+	2031  RM-203 USB Nest [mode 2]
+	2032  RM-203 USB Nest [mode 3]
+	2033  RM-203 USB Nest [mode 4]
+	2050  PX-205 PSX Bridge
+	3050  QF-305u Gamepad
+	688f  QF-688uv Windstorm Pro Joystick
+	7070  QF-707u Bazooka Joystick
+0584  RATOC System, Inc.
+	0008  Fujifilm MemoryCard ReaderWriter
+	b000  REX-USB60
+0585  FlashPoint Technology, Inc.
+	0001  Digital Camera
+	0002  Digital Camera
+	0003  Digital Camera
+	0004  Digital Camera
+	0005  Digital Camera
+	0006  Digital Camera
+	0007  Digital Camera
+	0008  Digital Camera
+	0009  Digital Camera
+	000a  Digital Camera
+	000b  Digital Camera
+	000c  Digital Camera
+	000d  Digital Camera
+	000e  Digital Camera
+	000f  Digital Camera
+0586  ZyXEL Communications Corp.
+	1000  Omni NET Modem / ISDN TA
+	1500  Omni 56K Plus
+	2011  Scorpion-980N keyboard
+	3304  LAN Modem
+	330a  ADSL Modem Interface
+	330e  USB Broadband ADSL Modem Rev 1.10
+	3400  ZyAIR B-220 IEEE 802.11b Adapter
+	3401  ZyAIR G-220
+	3402  (ZD1211)IEEE 802.11b+g Adapter
+	3407  G-200 v2
+	3409  AG-225H
+	340a  M-202
+	340f  G-220 v2
+	3410  Wi-Fi Wireless LAN Adapter
+	3412  Wi-Fi Wireless LAN Adapter
+	3413  AG-225H v2 802.11a/g Wi-Fi Finder & Adapter
+	3415  G-210H 802.11g Wireless Adapter
+0587  America Kotobuki Electronics Industries, Inc.
+0588  Sapien Design
+0589  Victron
+058a  Nohau Corp.
+058b  Infineon Technologies
+058c  In Focus Systems
+	0007  Flash
+	0008  LP130
+	000a  LP530
+	0010  Projector
+	0011  Projector
+	0012  Projector
+	0013  Projector
+	0014  Projector
+	0015  Projector
+	0016  Projector
+	0017  Projector
+	0018  Projector
+	0019  Projector
+	001a  Projector
+	001b  Projector
+	001c  Projector
+	001d  Projector
+	001e  Projector
+	001f  Projector
+058d  Micrel Semiconductor
+058e  Tripath Technology, Inc.
+058f  Alcor Micro Corp.
+	2412  SCard R/W CSR-145
+	2802  Monterey Keyboard
+	5492  Hub
+	6232  Hi-Speed 16-in-1 Flash Card Reader/Writer
+	6360  Multimedia Card Reader
+	6361  Multimedia Card Reader
+	6362  Hi-Speed 21-in-1 Flash Card Reader/Writer (Internal/External)
+	6377  Multimedia Card Reader
+	6386  Memory Card
+	6387  Transcend JetFlash Flash Drive
+	6390  USB 2.0-IDE bridge
+	9213  MacAlly Kbd Hub
+	9215  AU9814 Hub
+	9254  Hub
+	9310  Mass Storage (UID4/5A & UID7A)
+	9320  Micro Storage Driver for Win98
+	9321  Micro Storage Driver for Win98
+	9330  SD Reader
+	9331  Micro Storage Driver for Win98
+	9340  Delkin eFilm Reader-32
+	9350  Delkin eFilm Reader-32
+	9360  8-in-1 Media Card Reader
+	9361  Multimedia Card Reader
+	9368  Multimedia Card Reader
+	9380  Flash drive
+	9382  Acer/Sweex Flash drive
+	9410  Keyboard
+	9472  Keyboard Hub
+	9510  ChunghwaTL USB02 Smartcard Reader
+	9520  EMV Certified Smart Card Reader
+	9720  USB-Serial Adapter
+0590  Omron Corp.
+	0004  Cable Modem
+	000b  MR56SVS
+	0028  HJ-720IT Pedometer
+0591  Questra Consulting
+0592  Powerware Corp.
+	0002  UPS (X-Slot)
+0593  Incite
+0594  Princeton Graphic Systems
+0595  Zoran Microelectronics, Ltd
+	1001  Digitrex DSC-1300/DSC-2100 (mass storage mode)
+	4343  Digital Camera EX-20 DSC
+0596  MicroTouch Systems, Inc.
+	0001  Touchscreen
+	0002  Touch Screen Controller
+0597  Trisignal Communications
+0598  Niigata Canotec Co., Inc.
+0599  Brilliance Semiconductor, Inc.
+059a  Spectrum Signal Processing, Inc.
+059b  Iomega Corp.
+	0001  Zip 100 (Type 1)
+	000b  Zip 100 (Type 2)
+	0021  Win98 Disk Controller
+	0030  Zip 250 (Ver 1)
+	0031  Zip 100 (Type 3)
+	0032  Zip 250 (Ver 2)
+	0034  Zip 100 Driver
+	0037  Zip 750 MB
+	0040  SCSI Bridge
+	0042  Rev 70 GB
+	0050  Zip CD 650 Writer
+	0053  CDRW55292EXT CD-RW External Drive
+	0057  Mass Storage Device
+	005d  Mass Storage Device
+	005f  Mass Storage Device
+	0060  PCMCIA PocketZip Dock
+	0061  Varo PocketZip 40 MP3 Player
+	006d  HipZip MP3 Player
+	007c  Ultra Max USB/1394
+	00db  FotoShow Zip 250 Driver
+	0150  Mass Storage Device
+	015d  Super DVD Writer
+	0173  Hi-Speed USB-to-IDE Bridge Controller
+	0174  Hi-Speed USB-to-IDE Bridge Controller
+	0176  Hi-Speed USB-to-IDE Bridge Controller
+	0177  Hi-Speed USB-to-IDE Bridge Controller
+	0178  Hi-Speed USB-to-IDE Bridge Controller
+	0179  Hi-Speed USB-to-IDE Bridge Controller
+	017a  HDD
+	017b  HDD/1394A
+	017c  HDD/1394B
+	0251  Optical
+	0252  Optical
+	1052  DVD+RW External Drive
+059c  A-Trend Technology Co., Ltd
+059d  Advanced Input Devices
+059e  Intelligent Instrumentation
+059f  LaCie, Ltd
+	0201  StudioDrive USB2
+	0202  StudioDrive USB2
+	0203  StudioDrive USB2
+	0211  PocketDrive
+	0212  PocketDrive
+	0213  PocketDrive USB2
+	0323  LaCie d2 Drive USB2
+	0641  Mobile Hard Drive
+	1010  Desktop Hard Drive
+	a601  HardDrive
+	a602  CD R/W
+05a0  Vetronix Corp.
+05a1  USC Corp.
+05a2  Fuji Film Microdevices Co., Ltd
+05a3  ARC International
+05a4  Ortek Technology, Inc.
+	9720  Keyboard Mouse
+	9722  Keyboard
+	9731  MCK-600W/MCK-800USB Keyboard
+05a5  Sampo Technology Corp.
+05a6  Cisco Systems, Inc.
+	0001  CVA124 Cable Voice Adapter (WDM)
+	0002  CVA122 Cable Voice Adapter (WDM)
+	0003  CVA124E Cable Voice Adapter (WDM)
+	0004  CVA122E Cable Voice Adapter (WDM)
+05a7  Bose Corp.
+05a8  Spacetec IMC Corp.
+05a9  OmniVision Technologies, Inc.
+	0511  OV511 WebCam
+	0518  OV518 WebCam
+	0519  OV519 Microphone
+	1550  VEHO Filmscanner
+	2800  SuperCAM
+	4519  Webcam Classic
+	8519  OV519 WebCam
+	a511  OV511+ WebCam
+	a518  D-Link DSB-C310 WebCam
+05aa  Utilux South China, Ltd
+05ab  In-System Design
+	0002  Parallel Port
+	0030  Storage Adapter V2 (TPP)
+	0031  ATA Bridge
+	0060  USB 2.0 ATA Bridge
+	0061  Storage Adapter V3 (TPP-I)
+	0101  Storage Adapter (TPP)
+	0130  Compact Flash and Microdrive Reader (TPP)
+	0200  USS725 ATA Bridge
+	0201  Storage Adapter (TPP)
+	0202  ATA Bridge
+	0300  Portable Hard Drive (TPP)
+	0301  Portable Hard Drive V2
+	0350  Portable Hard Drive (TPP)
+	0351  Portable Hard Drive V2
+	081a  ATA Bridge
+	0cda  ATA Bridge for CD-R/RW
+	1001  BAYI Printer Class Support
+	5700  Storage Adapter V2 (TPP)
+	5701  USB Storage Adapter V2
+	5901  Smart Board (TPP)
+	5a01  ATI Storage Adapter (TPP)
+	5d01  DataBook Adapter (TPP)
+05ac  Apple, Inc.
+	0201  USB Keyboard [Alps or Logitech, M2452]
+	0202  Keyboard [ALPS]
+	0205  Extended Keyboard [Mitsumi]
+	0206  Extended Keyboard [Mitsumi]
+	020b  Pro Keyboard [Mitsumi, A1048/US layout]
+	020c  Extended Keyboard [Mitsumi]
+	020d  Pro Keyboard [Mitsumi, A1048/JIS layout]
+	020e  Internal Keyboard/Trackpad
+	020f  Internal Keyboard/Trackpad
+	021b  Internal Keyboard/Trackpad
+	0220  Aluminum Keyboard
+	0221  Keyboard (Aluminium) (ISO)
+	0229  Internal Keyboard/Trackpad (MacBook Pro) (ANSI)
+	022a  Internal Keyboard/Trackpad (MacBook Pro) (ISO)
+	022b  Internal Keyboard/Trackpad (MacBook Pro) (JIS)
+	0301  USB Mouse [Mitsumi, M4848]
+	0302  Optical Mouse [Fujitsu]
+	0304  Optical USB Mouse [Mitsumi]
+	0306  Optical USB Mouse [Fujitsu]
+	1000  Bluetooth HCI MacBookPro (HID mode)
+	1001  Keyboard Hub [ALPS]
+	1002  Extended Keyboard Hub [Mitsumi]
+	1003  Hub in Pro Keyboard [Mitsumi, A1048]
+	1006  Hub in Aluminum Keyboard
+	1101  Speakers
+	1201  3G iPod
+	1202  iPod 2G
+	1203  iPod 4.Gen Grayscale 40G
+	1204  iPod [Photo]
+	1205  iPod Mini 1.Gen/2.Gen
+	1206  iPod '06'
+	1207  iPod '07'
+	1208  iPod '08'
+	1209  iPod Video
+	120a  iPod Nano
+	1260  iPod Nano 2.Gen
+	1261  iPod Classic
+	1300  iPod Shuffle
+	1301  iPod Shuffle 2.Gen
+	8202  HCF V.90 Data/Fax Modem
+	8203  Bluetooth HCI
+	8204  Bluetooth HCI [Bluetooth 2.0 + EDR, build-in]
+	8205  Bluetooth HCI MacBookPro
+	8206  Bluetooth USB Host Controller
+	8240  IR Receiver [build-in]
+	8300  Built-in iSight (no firmware loaded)
+	8501  Built-in iSight [Micron]
+	912f  Hub in 30" Cinema Display
+	9221  30" Cinema Display
+	ffff  Bluetooth in DFU mode - Driver
+05ad  Y.C. Cable U.S.A., Inc.
+05ae  Synopsys, Inc.
+05af  Jing-Mold Enterprise Co., Ltd
+	0821  IDE to
+	9167  KB 9151B - 678
+	9267  KB 9251B - 678 Mouse
+05b0  Fountain Technologies, Inc.
+05b1  First International Computer, Inc.
+	1389  Bluetooth Wireless Adapter
+05b4  LG Semicon Co., Ltd
+	4857  M-Any DAH-210
+	6001  Digisette DUO-MP3 AR-100
+05b5  Dialogic Corp.
+05b6  Proxima Corp.
+05b7  Medianix Semiconductor, Inc.
+05b8  Agiler, Inc.
+	3002  Scroll Mouse
+05b9  Philips Research Laboratories
+05ba  DigitalPersona, Inc.
+05bb  Grey Cell Systems
+05bc  3G Green Green Globe Co., Ltd
+	0004  Trackball
+05bd  RAFI GmbH & Co. KG
+05be  Tyco Electronics (Raychem)
+05bf  S & S Research
+05c0  Keil Software
+05c1  Kawasaki Microelectronics, Inc.
+05c2  Media Phonics (Suisse) S.A.
+05c5  Digi International, Inc.
+	0002  AccelePort USB 2
+	0004  AccelePort USB 4
+	0008  AccelePort USB 8
+05c6  Qualcomm, Inc.
+	3100  CDMA Wireless Modem/Phone
+	3196  CDMA Wireless Modem
+	3197  CDMA Wireless Modem/Phone
+05c7  Qtronix Corp.
+	0113  PC Line Mouse
+	1001  Lynx Mouse
+	2001  Keyboard
+	2011  SCorpius Keyboard
+	6001  Ten-Keypad
+05c8  Cheng Uei Precision Industry Co., Ltd (Foxlink)
+05c9  Semtech Corp.
+05ca  Ricoh Co., Ltd
+	0101  RDC-5300 Camera
+	0325  Caplio GX (ptp)
+	032d  Caplio GX 8 (ptp)
+	032f  Caplio R3 (ptp)
+	03a1  IS200e
+	0403  Printing Support
+	0405  Type 101
+	0406  Type 102
+	1830  Visual Communication Camera VGP-VCC2
+	1835  Visual Communication Camera VGP-VCC5
+	1870  Webcam 1000
+	2201  RDC-7 Camera
+	2202  Caplio RR30
+	2203  Caplio 300G
+	2204  Caplio G3
+	2205  Caplio RR30 / Medion MD 6126 Camera
+	2206  Konica DG-3Z
+	2207  Caplio Pro G3
+	2208  Caplio G4
+	2209  Caplio 400G wide
+	220a  KONICA MINOLTA DG-4Wide
+	220b  Caplio RX
+	220c  Caplio GX
+	220d  Caplio R1/RZ1
+	220e  Sea & Sea 5000G
+	220f  Rollei dr5 / Rollei dr5 (PTP mode)
+	2211  Caplio R1S
+	2212  Caplio R1v Camera
+	2213  Caplio R2
+	2214  Caplio GX 8
+	2215  DSC 725
+	2216  Caplio R3
+	2222  RDC-i500
+05cb  PowerVision Technologies, Inc.
+	1483  PV8630 interface (scanners, webcams)
+05cc  ELSA AG
+	2100  MicroLink ISDN Office
+	2219  MicroLink ISDN
+	2265  MicroLink 56k
+	2267  MicroLink 56k (V.250)
+	2280  MicroLink 56k Fun
+	3000  Micolink USB2Ethernet [pegasus]
+	3100  AirLancer USB-11
+	3363  MicroLink ADSL Fun
+05cd  Silicom, Ltd
+05ce  sci-worx GmbH
+05cf  Sung Forn Co., Ltd
+05d0  GE Medical Systems Lunar
+05d1  Brainboxes, Ltd
+	0003  Bluetooth Adapter BL-554
+05d2  Wave Systems Corp.
+05d3  Tohoku Ricoh Co., Ltd
+05d5  Super Gate Technology Co., Ltd
+05d6  Philips Semiconductors, CICT
+05d7  Thomas & Betts Corp.
+	0099  10Mbps Ethernet [klsi]
+05d8  Ultima Electronics Corp.
+	4001  Artec Ultima 2000
+	4002  Artec Ultima 2000 (GT6801 based)/Lifetec LT9385/ScanMagic 1200 UB Plus Scanner
+	4003  Artec E+ 48U
+	4004  Artec E+ Pro
+	4005  MEM48U
+	4006  TRUST EASY WEBSCAN 19200
+	4007  TRUST 240H EASY WEBSCAN GOLD
+	4008  Trust Easy Webscan 19200
+	4009  Umax Astraslim
+	4013  IT Scan 1200
+	8105  Artec T1 USB TVBOX (cold)
+	8106  Artec T1 USB TVBOX (warm)
+	8107  Artec T1 USB TVBOX with AN2235 (cold)
+	8108  Artec T1 USB TVBOX with AN2235 (warm)
+	8109  Artec T1 USB2.0 TVBOX (cold
+05d9  Axiohm Transaction Solutions
+	a225  A225 Printer
+	a758  A758 Printer
+	a794  A794 Printer
+05da  Microtek International, Inc.
+	0091  ScanMaker X6u
+	0093  ScanMaker V6USL
+	0094  Phantom 336CX/C3
+	0099  ScanMaker X6/X6U
+	009a  Phantom C6
+	00a0  Phantom 336CX/C3 (#2)
+	00a3  ScanMaker V6USL
+	00ac  ScanMaker V6UL
+	00b6  ScanMaker V6UPL
+	00ef  ScanMaker V6UPL
+	1006  Jenoptik JD350 entrance
+	1011  NHJ Che-ez! Kiss Digital Camera
+	1018  Digital Dream Enigma 1.3
+	1020  Digital Dream l'espion xtra
+	1025  Take-it Still Camera Device
+	1026  Take-it
+	1043  Take-It 1300 DSC Bulk Driver
+	1045  Take-it D1
+	1047  Take-it Camera Composite Device
+	1048  Take-it Q3
+	1049  3M Still Camera Device
+	1051  Camcorder Series
+	1052  Mass Storage Device
+	1053  Take-it DV Composite Device
+	1054  Mass Storage Device
+	1055  Digital Camera Series(536)
+	1056  Mass Storage Device
+	1057  Take-it DSC Camera Device(536)
+	1058  Mass Storage Device
+	1059  Camcorder DSC Series
+	1060  Microtek Take-it MV500
+	2007  ArtixScan DI 1210
+	200c  1394_USB2 Scanner
+	200e  ArtixScan DI 810
+	2017  UF ICE Scanner
+	201c  4800 Scanner
+	201d  ArtixScan DI 1610
+	201f  4800 Scanner-ICE
+	202e  ArtixScan DI 2020
+	208b  ScanMaker 6800
+	208f  ArtixScan DI 2010
+	209e  ScanMaker 4700LP
+	20a7  ScanMaker 5600
+	20b0  ScanMaker X12USL
+	20b1  ScanMaker 8700
+	20b4  ScanMaker 4700
+	20bd  ScanMaker 5700
+	20c9  ScanMaker 6700
+	20d2  Microtek ArtixScan 1800f
+	20d6  PS4000
+	20de  ScanMaker 9800XL
+	20e0  ScanMaker 9700XL
+	20ed  ScanMaker 4700
+	20ee  Micortek ScanMaker X12USL
+	3008  Scanner
+	300a  4800 ICE Scanner
+	300b  4800 Scanner
+	300f  MiniScan C5
+	3020  4800dpi Scanner
+	3021  1200dpi Scanner
+	3022  Scanner 4800dpi
+	3023  USB1200II Scanner
+	30c1  USB600 Scanner
+	30ce  ScanMaker 3800
+	30cf  ScanMaker 4800
+	30d4  USB1200 Scanner
+	30d8  Scanner
+	30d9  USB2400 Scanner
+	30e4  ScanMaker 4100
+	30e5  USB3200 Scanner
+	30e6  ScanMaker i320
+	40b3  ScanMaker 3600
+	40b8  ScanMaker 3700
+	40c7  ScanMaker 4600
+	40ca  ScanMaker 3600
+	40cb  ScanMaker 3700
+	40dd  ScanMaker 3750i
+	40ff  ScanMaker 3600
+	5003  Goya
+	5013  3200 Scanner
+	80a3  ScanMaker V6USL (#2)
+	80ac  ScanMaker V6UL/SpicyU
+05db  Sun Corp. (Suntac?)
+	0003  SUNTAC U-Cable type D2
+	0005  SUNTAC U-Cable type P1
+	0009  SUNTAC Slipper U
+	000a  SUNTAC Ir-Trinity
+	000b  SUNTAC U-Cable type A3
+	0011  SUNTAC U-Cable type A4
+05dc  Lexar Media, Inc.
+	0001  jumpSHOT CompactFlash Reader
+	0002  JumpShot
+	0003  JumpShot
+	0080  Jumpdrive Secure 64MB
+	0081  RBC Compact Flash Drive
+	00a7  JumpDrive Impact
+	0100  JumpDrive PRO
+	0200  JumpDrive 2.0 Pro
+	0300  Jumpdrive Geysr
+	0301  JumpDrive Classic
+	0302  JD Micro
+	0303  JD Micro Pro
+	0304  JD Secure II
+	0310  JumpDrive
+	0311  JumpDrive Classic
+	0312  JD Micro
+	0313  JD Micro Pro
+	0320  JumpDrive
+	0321  JD Micro
+	0322  JD Micro Pro
+	0323  UFC
+	0330  JumpDrive Expression
+	0340  JumpDrive TAD
+	0350  Express Card
+	0400  UFDC
+	0401  UFDC
+	0403  Locked B Device
+	0405  Locked C Device
+	0407  Locked D Device
+	0409  Locked E Device
+	040b  Locked F Device
+	040d  Locked G Device
+	040f  Locked H Device
+	0410  JumpDrive
+	0411  JumpDrive
+	0413  Locked J Device
+	0415  Locked K Device
+	0417  Locked L Device
+	0419  Locked M Device
+	041b  Locked N Device
+	041d  Locked O Device
+	041f  Locked P Device
+	0420  JumpDrive
+	0421  JumpDrive
+	0423  Locked R Device
+	0425  Locked S Device
+	0427  Locked T Device
+	0429  Locked U Device
+	042b  Locked V Device
+	042d  Locked W Device
+	042f  Locked X Device
+	0431  Locked Y Device
+	0433  Locked Z Device
+	4d02  MP3 Player
+	4d12  MP3 Player
+	a300  JumpDrive2
+	a400  JumpDrive trade; Pro 40-501
+	a410  JumpDrive 128MB/256MB
+	a411  JumpDrive Traveler
+	a420  JumpDrive Pro
+	a421  JumpDrive Pro II
+	a422  JumpDrive Micro Pro
+	a430  JumpDrive Secure
+	a431  JumpDrive Secure II
+	a432  JumpDrive Classic
+	a440  JumpDrive Lightning
+	a450  JumpDrive TouchGuard
+	a460  JD Mercury
+	a501  JumpDrive Classic
+	a510  JumpDrive Sport
+	a530  JumpDrive Expression
+	a531  JumpDrive Secure II
+	a560  JumpDrive FireFly
+	a701  JumpDrive FireFly
+	b002  USB CF Reader
+	b018  Multi-Card Reader
+05dd  Delta Electronics, Inc.
+	ff31  AWU-120
+	ff32  FriendlyNET AeroLAN AL2011
+	ff35  PCW 100 - Wireless 802.11b Adapter
+	ff91  2Wire PC Port Phoneline 10Mbps Adapter
+05df  Silicon Vision, Inc.
+05e0  Symbol Technologies
+	0700  Bar Code Scanner (CS1504)
+	0800  Spectrum24 Wireless LAN Adapter
+	1200  DS6608 Bar Code Scanner
+	1900  SNAPI Imaging Device
+	2000  MC3090 Rugged Mobile Computer
+	200d  MC70 Rugged Mobile Computer
+05e1  Syntek Semiconductor Co., Ltd
+	0500  DC-112X
+	0501  WebCam, Chipset DC-1125 similar to 174f:a311 - Asus F2F, F2J, F3J, F3T, G1, Z53JA
+	0890  STK011 Camera
+	0892  STK013 Camera
+	0895  STK016 Camera
+	0896  STK017 Camera
+05e2  ElecVision, Inc.
+05e3  Genesys Logic, Inc.
+	000a  Keyboard with PS/2 Port
+	000b  Mouse
+	0100  Nintendo Game Boy Advance SP
+	0120  Pacific Image Electronics PrimeFilm 1800u slide/negative scanner
+	0131  CF/SM Reader/Writer
+	0142  Multiple Slides Scanner-3600
+	0143  Multiple Frames Film Scanner-36series
+	0180  Plustek Scanner
+	0182  Wize Media 1000
+	0189  ScanJet 4600 series
+	018a  Xerox 6400
+	0300  GLUSB98PT Parallel Port
+	0301  USB2LPT Cable Release2
+	0406  Hub
+	0501  GL620USB Host-Host interface
+	0502  GL620USB GeneLink USB-USB Bridge
+	0504  HID Keyboard Filter
+	0604  USB 1.1 Hub
+	0605  USB 2.0 Hub [ednet]
+	0606  USB 2.0 Hub / D-Link DUB-H4 USB 2.0 Hub
+	0608  USB-2.0 4-Port HUB
+	0660  USB 2.0 Hub
+	0700  SIIG US2256 CompactFlash Card Reader
+	0701  USB 2.0 IDE Adapter
+	0702  USB 2.0 IDE Adapter
+	0703  Card Reader
+	0704  Card Reader
+	0705  Card Reader
+	0706  Card Reader
+	0707  Card Reader
+	0708  Card Reader
+	0709  Card Reader
+	070a  Pen Flash
+	070b  DMHS1B Rev 3 DFU Adapter
+	070e  X-PRO CR20xA USB 2.0 Internal Card Reader
+	070f  Pen Flash
+	0710  USB 2.0 33-in-1 Card Reader
+	0711  Card Reader
+	0712  Delkin Mass Storage Device
+	0715  USB 2.0 microSD Reader
+	0760  USB 2.0 Card Reader/Writer
+	0761  Genesys Mass Storage Device
+	0780  USBFS DFU Adapter
+	07a0  Pen Flash
+	0927  Card Reader
+	1205  Afilias Optical Mouse H3003
+	a700  Pen Flash
+	f102  VX7012 TV Box
+	f103  VX7012 TV Box
+	f104  VX7012 TV Box
+	fd21  3M TL20 Temperature Logger
+	fe00  Razer Mouse
+05e4  Red Wing Corp.
+05e5  Fuji Electric Co., Ltd
+05e6  Keithley Instruments
+05e8  ICC, Inc.
+05e9  Kawasaki LSI
+	0008  KL5KUSB101B Ethernet [klsi]
+	0009  Sony 10Mbps Ethernet [pegasus]
+	000c  USB-to-RS-232
+	000d  USB-to-RS-232
+	0014  RS-232 J104
+	0040  Ethernet Adapter
+	2008  Ethernet Adapter
+05eb  FFC, Ltd
+05ec  COM21, Inc.
+05ee  Cytechinfo Inc.
+05ef  AVB, Inc. [anko?]
+	020a  Top Shot Pegasus Joystick
+	8884  Mag Turbo Force Wheel
+	8888  Top Shot Force Feedback Racing Wheel
+05f0  Canopus Co., Ltd
+	0101  DA-Port DAC
+05f1  Compass Communications
+05f2  Dexin Corp., Ltd
+	0010  AQ Mouse
+05f3  PI Engineering, Inc.
+	0007  Kinesis Advantage PRO MPC/USB Keyboard
+	0081  Kinesis Integrated Hub
+	020b  PS2 Adapter
+	0232  X-Keys Switch Interface, Programming Mode
+	0261  X-Keys Switch Interface, SPLAT Mode
+	0264  X-Keys Switch Interface, Composite Mode
+05f5  Unixtar Technology, Inc.
+05f6  AOC International
+05f7  RFC Distribution(s) PTE, Ltd
+05f9  PSC Scanning, Inc.
+05fa  Siemens Telecommunications Systems, Ltd
+	3301  Keyboard with PS/2 Mouse Port
+	3302  Keyboard
+	3303  Keyboard with PS/2 Mouse Port
+05fc  Harman Multimedia
+	7849  Harman/Kardon SoundSticks
+05fd  InterAct, Inc.
+	0239  SV-239 HammerHead Digital
+	0251  Raider Pro
+	0253  ProPad 8 Digital
+	0286  SV-286 Cyclone Digital
+	262a  3dfx HammerHead FX
+	262f  HammerHead Fx
+	daae  Game Shark
+05fe  Chic Technology Corp.
+	0001  Mouse
+	0003  Cypress USB Mouse
+	0005  Viewmaster 4D Browser Mouse
+	0007  Twinhead Mouse
+	0009  Inland Pro 4500/5000 Mouse
+	0011  Browser Mouse
+	1010  Optical Wireless
+05ff  LeCroy Corp.
+0600  Barco Display Systems
+0601  Jazz Hipster Corp.
+	0003  Internet Security Co., Ltd. SecureKey
+0602  Vista Imaging, Inc.
+	1001  ViCam WebCam
+0603  Novatek Microelectronics Corp.
+	00f1  Keyboard
+	6871  Mouse
+0604  Jean Co., Ltd
+0605  Anchor C&C Co., Ltd
+0606  Royal Information Electronics Co., Ltd
+0607  Bridge Information Co., Ltd
+0608  Genrad Ads
+0609  SMK Manufacturing, Inc.
+	031d  eHome Infrared Receiver
+	0322  eHome Infrared Receiver
+	ff12  SMK Bluetooth Device
+060a  Worthington Data Solutions, Inc.
+060b  Solid Year
+	0001  MacAlly Keyboard
+	1006  Japanese Keyboard - 260U
+	2101  Keyboard
+	5811  ACK-571U Wireless Keyboard
+	5903  Japanese Keyboard - 595U
+	6001  SolidTek USB 2p HUB
+	6002  SolidTek USB Keyboard
+	6003  Japanese Keyboard - 600HM
+	a001  Maxwell Compact Pc PM3
+060c  EEH Datalink GmbH
+060d  Auctor Corp.
+060e  Transmonde Technologies, Inc.
+060f  Joinsoon Electronics Mfg. Co., Ltd
+0610  Costar Electronics, Inc.
+0611  Totoku Electric Co., Ltd
+0613  TransAct Technologies, Inc.
+0614  Bio-Rad Laboratories
+0615  Quabbin Wire & Cable Co., Inc.
+0616  Future Techno Designs PVT, Ltd
+0617  Swiss Federal Insitute of Technology
+0618  MacAlly
+	0101  Mouse
+0619  Seiko Instruments, Inc.
+	0101  SLP-100 Driver
+	0102  SLP-200 Driver
+	0103  SLP-100N Driver
+	0104  SLP-200N Driver
+	0105  SLP-240 Driver
+061a  Veridicom International, Inc.
+	0110  5thSense Fingerprint Sensor
+	0200  FPS200 Fingerprint Sensor
+	8200  VKI-A Fingerprint Sensor/Flash Storage (dumb)
+	9200  VKI-B Fingerprint Sensor/Flash Storage (smart)
+061b  Promptus Communications, Inc.
+061c  Act Labs, Ltd
+061d  Quatech, Inc.
+061e  Nissei Electric Co.
+	0001  nissei 128DE-USB -
+	0010  nissei 128DE-PNA -
+0620  Alaris, Inc.
+	0004  QuickVideo weeCam
+	0007  QuickVideo weeCam
+	000a  QuickVideo weeCam
+	000b  QuickVideo weeCam
+0621  ODU-Steckverbindungssysteme GmbH & Co. KG
+0622  Iotech, Inc.
+0623  Littelfuse, Inc.
+0624  Avocent Corp.
+0625  TiMedia Technology Co., Ltd
+0626  Nippon Systems Development Co., Ltd
+0627  Adomax Technology Co., Ltd
+0628  Tasking Software, Inc.
+0629  Zida Technologies, Ltd
+062a  Creative Labs
+	0000  Optical mouse
+	0001  Notebook Optical Mouse
+	0201  Defender Office Keyboard (K7310) S Zodiak KM-9010
+	9003  VoIP Conference Hub (A16GH)
+	9004  USR9602 USB Internet Mini Phone
+062b  Greatlink Electronics Taiwan, Ltd
+062c  Institute for Information Industry
+062d  Taiwan Tai-Hao Enterprises Co., Ltd
+062e  Mainsuper Enterprises Co., Ltd
+062f  Sin Sheng Terminal & Machine, Inc.
+0631  JUJO Electronics Corp.
+0633  Cyrix Corp.
+0634  Micron Technology, Inc.
+0635  Methode Electronics, Inc.
+0636  Sierra Imaging, Inc.
+	0003  Vivicam 35Xx
+0638  Avision, Inc.
+	0268  iVina 1200U Scanner
+	026a  Minolta Dimage Scan Dual II
+	0a10  iVina FB1600/UMAX Astra 4500
+	0a13  AV600U
+	0a16  SC-215
+	0a30  UMAX Astra 6700 Scanner
+	0a41  Avision AM3000/MF3000 Series
+	0f01  fi-4010CU
+	4004  Minolta Dimage Scan Elite II
+0639  Chrontel, Inc.
+063a  Techwin Corp.
+063b  Taugagreining HF
+063c  Yamaichi Electronics Co., Ltd (Sakura)
+063d  Fong Kai Industrial Co., Ltd
+063e  RealMedia Technology, Inc.
+063f  New Technology Cable, Ltd
+0640  Hitex Development Tools
+0641  Woods Industries, Inc.
+0642  VIA Medical Corp.
+0644  TEAC Corp.
+	0000  Floppy
+	1000  CD-ROM Drive
+	800d  TASCAM Portastudio DP-01FX
+	d001  CD-R/RW Unit
+	d002  CD-R/RW Unit
+	d010  CD-RW/DVD Unit
+0645  Who? Vision Systems, Inc.
+0646  UMAX
+0647  Acton Research Corp.
+	0100  ARC SpectraPro UV/VIS/IR Monochromator/Spectrograph
+	0101  ARC AM-VM Mono Airpath/Vacuum Monochromator/Spectrograph
+	0102  ARC Inspectrum Mono
+	0103  ARC Filterwheel
+	03e9  Inspectrum 128x1024 F VIS Spectrograph
+	03ea  Inspectrum 256x1024 F VIS Spectrograph
+	03eb  Inspectrum 128x1024 B VIS Spectrograph
+	03ec  Inspectrum 256x1024 B VIS Spectrograph
+0648  Inside Out Networks
+0649  Weli Science Co., Ltd
+064b  White Mountain DSP, Inc.
+064c  Ji-Haw Industrial Co., Ltd
+064d  TriTech Microelectronics, Ltd
+064e  Suyin Corp.
+064f  WIBU-Systems AG
+	0bd7  BOX/U
+	0bd8  BOX/RU
+0650  Dynapro Systems
+0651  Likom Technology Sdn. Bhd.
+0652  Stargate Solutions, Inc.
+0653  CNF, Inc.
+0654  Granite Microsystems, Inc.
+	0005  Device Bay Controller
+	0006  Hub
+	0007  Device Bay Controller
+	0016  Hub
+0655  Space Shuttle Hi-Tech Co., Ltd
+0656  Glory Mark Electronic, Ltd
+0657  Tekcon Electronics Corp.
+0658  Sigma Designs, Inc.
+0659  Aethra
+065a  Optoelectronics Co., Ltd
+	0001  Barcode scanner
+065b  Tracewell Systems
+065e  Silicon Graphics
+065f  Good Way Technology Co., Ltd & GWC technology Inc.
+0660  TSAY-E (BVI) International, Inc.
+0661  Hamamatsu Photonics K.K.
+0662  Kansai Electric Co., Ltd
+0663  Topmax Electronic Co., Ltd
+	0103  CobraPad
+0667  Aiwa Co., Ltd
+	0fa1  TD-U8000 Tape Drive
+0668  WordWand
+0669  Oce' Printing Systems GmbH
+066a  Total Technologies, Ltd
+066b  Linksys, Inc.
+	0105  SCM eUSB SmartMedia Card Reader
+	010a  Melco MCR-U2 SmartMedia / CompactFlash Reader
+	200c  USB10TX
+	2202  USB10TX Ethernet [pegasus]
+	2203  USB100TX Ethernet [pegasus]
+	2204  USB100TX HomePNA Ethernet [pegasus]
+	2206  USB Ethernet [pegasus]
+	2207  HomeLink Phoneline 10M Network Adapter
+	2211  WUSB11 802.11b Adapter
+	2212  WUSB11v2.5 802.11b Adapter
+	2213  WUSB12v1.1 802.11b Adapter
+	2219  Instant Wireless Network Adapter
+	400b  USB10TX
+066d  Entrega, Inc.
+066e  Acer Semiconductor America, Inc.
+066f  SigmaTel, Inc.
+	003b  MP3 Player
+	003e  MP3 Player
+	003f  MP3 Player
+	0040  MP3 Player
+	0041  MP3 Player
+	0042  MP3 Player
+	0043  MP3 Player
+	004b  A-Max PA11 MP3 Player
+	3400  STMP3400 D-Major MP3 Player
+	3410  STMP3410 D-Major MP3 Player
+	3500  Player Recovery Device
+	4200  STIr4200 IrDA Bridge
+	4210  STIr4210 IrDA Bridge
+	8000  MSCN MP3 Player
+	8001  SigmaTel MSCN Audio Player
+	8004  MSCNMMC MP3 Player
+	8008  i-Bead 100 MP3 Player
+	8020  MP3 Player
+	8034  MP3 Player
+	8036  MP3 Player
+	8038  MP3 Player
+	8056  MP3 Player
+	8060  MP3 Player
+	8066  MP3 Player
+	807e  MP3 Player
+	8092  MP3 Player
+	8096  MP3 Player
+	809a  MP3 Player
+	80aa  MP3 Player
+	80ac  MP3 Player
+	80b8  MP3 Player
+	80ba  MP3 Player
+	80bc  MP3 Player
+	80bf  MP3 Player
+	80c5  MP3 Player
+	80c8  MP3 Player
+	80ca  MP3 Player
+	80cc  MP3 Player
+	8104  MP3 Player
+	8106  MP3 Player
+	8108  MP3 Player
+	810a  MP3 Player
+	810c  MP3 Player
+	8122  MP3 Player
+	8124  MP3 Player
+	8126  MP3 Player
+	8128  MP3 Player
+	8134  MP3 Player
+	8136  MP3 Player
+	8138  MP3 Player
+	813a  MP3 Player
+	813e  MP3 Player
+	8140  MP3 Player
+	8142  MP3 Player
+	8144  MP3 Player
+	8146  MP3 Player
+	8148  MP3 Player
+	814c  MP3 Player
+	8201  MP3 Player
+	8202  Jens of Sweden / I-BEAD 150M/150H MP3 player
+	8203  MP3 Player
+	8204  MP3 Player
+	8205  MP3 Player
+	8206  Digital MP3 Music Player
+	8207  MP3 Player
+	8208  MP3 Player
+	8209  MP3 Player
+	820a  MP3 Player
+	820b  MP3 Player
+	820c  MP3 Player
+	820d  MP3 Player
+	820e  MP3 Player
+	820f  MP3 Player
+	8210  MP3 Player
+	8211  MP3 Player
+	8212  MP3 Player
+	8213  MP3 Player
+	8214  MP3 Player
+	8215  MP3 Player
+	8216  MP3 Player
+	8217  MP3 Player
+	8218  MP3 Player
+	8219  MP3 Player
+	821a  MP3 Player
+	821b  MP3 Player
+	821c  MP3 Player
+	821d  MP3 Player
+	821e  MP3 Player
+	821f  MP3 Player
+	8220  MP3 Player
+	8221  MP3 Player
+	8222  MP3 Player
+	8223  MP3 Player
+	8224  MP3 Player
+	8225  MP3 Player
+	8226  MP3 Player
+	8227  MP3 Player
+	8228  MP3 Player
+	8229  MP3 Player
+	8230  MP3 Player
+	9000  MP3 Player
+	9001  MP3 Player
+	9002  MP3 Player
+0672  Labtec, Inc.
+	1041  LCS1040 Speaker System
+	5000  SpaceBall 4000 FLX
+0673  HCL
+	5000  Keyboard
+0674  Key Mouse Electronic Enterprise Co., Ltd
+0675  Draytech
+	0110  Vigor 128 ISDN TA
+	0550  Vigor550
+0676  Teles AG
+0677  Aiwa Co., Ltd
+	07d5  TM-ED1285(USB)
+	0fa1  TD-U8000 Tape Drive
+0678  ACard Technology Corp.
+067b  Prolific Technology, Inc.
+	0000  PL2301 USB-USB Bridge
+	0001  PL2302 USB-USB Bridge
+	04bb  PL2303 Serial (IODATA USB-RSAQ2)
+	0610  Onext EG210U MODEM
+	0611  AlDiga AL-11U Quad-band GSM/GPRS/EDGE modem
+	2303  PL2303 Serial Port
+	2305  PL2305 Parallel Port
+	2307  PL2307 USB-ATAPI4 Bridge
+	2313  FITEL PHS U Cable Adaptor
+	2315  Flash Disk Embedded Hub
+	2316  Flash Disk Security Device
+	2317  Mass Storage Device
+	2501  PL2501 USB-USB Bridge (USB 2.0)
+	2507  PL2507 Hi-speed USB to IDE bridge controller
+	2515  Flash Disk Embedded Hub
+	2517  Flash Disk Mass Storage Device
+	25a1  PL25A1 Host-Host Bridge
+	3400  Hi-Speed Flash Disk with TruePrint AES3400
+	3500  Hi-Speed Flash Disk with TruePrint AES3500
+	3507  PL3507 ATAPI6 Bridge
+	aaa0  Prolific Pharos
+	aaa2  PL2303 Serial Adapter (IODATA USB-RSAQ3)
+067c  Efficient Networks, Inc.
+	1001  Siemens SpeedStream 100MBps Ethernet
+	1022  Siemens SpeedStream 1022 802.11b Adapter
+	1023  SpeedStream Wireless
+	4020  SpeedStream 4020 ATM/ADSL Installer
+	4031  Efficient ADSL Modem
+	4032  SpeedStream 4031 ATM/ADSL Installer
+	4033  SpeedStream 4031 ATM/ADSL Installer
+	4060  Alcatel Speedstream 4060 ADSL Modem
+	4062  Efficient Networks 4060 Loader
+	5667  Efficient Networks Virtual Bus for ADSL Modem
+	c031  SpeedStream 4031 ATM/ADSL Installer
+	c032  SpeedStream 4031 ATM/ADSL Installer
+	c033  SpeedStream 4031 ATM/ADSL Installer
+	c060  SpeedStream 4060 Miniport ATM/ADSL Adapter
+	d667  Efficient Networks Virtual Bus for ADSL Modem
+	e240  Speedstream Ethernet Adapter E240
+	e540  Speedstream Ethernet Adapter E240
+067d  Hohner Corp.
+067e  Intermec
+	1001  Mobile Computer
+067f  Virata, Ltd
+	4552  DSL-200 ADSL Modem
+	6542  DSL Modem
+	6549  DSL Modem
+	7541  DSL Modem
+0680  Realtek Semiconductor Corp., CPP Div. (Avance Logic)
+	0002  Arowana Optical Wheel Mouse MSOP-01
+0681  Siemens Information and Communication Products
+	0001  Dect Base
+	0002  Gigaset 3075 Passive ISDN
+	0005  ID-Mouse with Fingerprint Reader
+	0012  I-Gate 802.11b Adapter
+	001b  WLL013
+	0022  Gigaset SX353 ISDN
+	002b  A-100-I ADSL Modem
+	002e  ADSL Router_S-141
+	0034  GSM module MC35/ES75 USB Modem
+	3c06  54g USB Network Adapter
+0682  Victor Company of Japan, Ltd
+0684  Actiontec Electronics, Inc.
+0686  Minolta Co., Ltd
+	2001  PagePro 4110W
+	3001  PagePro 4100
+	3006  PagePro 1250W
+	302e  Develop D 1650iD PCL
+	3034  Develop D 2050iD PCL
+	4001  Dimage 2300
+	4003  Dimage 2330 Zoom Camera
+	4004  Scan Elite II
+	4005  Minolta DiMAGE E201 Mass Storage Device
+	4006  Dimage 7 Camera
+	4007  Dimage S304 Camera
+	4008  Dimage 5 Camera
+	4009  Dimage X Camera
+	400a  Dimage S404 Camera
+	400b  Dimage 7i Camera
+	400c  Dimage F100 Camera
+	400d  Scan Dual III
+	400e  Dimage 5400
+	400f  Dimage 7Hi Camera
+	4010  Dimage Xi Camera
+	4011  Dimage F300 Camera
+	4012  Dimage F200 Camera
+	4014  Dimage S414 Camera
+	4015  Dimage XT Camera [storage]
+	4016  Dimage XT Camera [remote mode]
+	4017  Dimage E223
+	4018  Dimage Z1  Camera
+	401a  Dimage A1 Camera
+	401c  Dimage X20 Camera
+	401e  Dimage E323 Camera
+068a  Pertech, Inc.
+068b  Potrans International, Inc.
+068e  CH Products, Inc.
+	00e2  HFX OEM Joystick
+	00f1  Pro Throttle
+	00f2  Flight Sim Pedals
+	00f3  Fighterstick
+	00ff  Flight Sim Yoke
+	0500  GameStick 3D
+	0501  CH Pro Pedals
+	0504  F-16 Combat Stick
+0690  Golden Bridge Electech, Inc.
+0693  Hagiwara Sys-Com Co., Ltd
+	0002  FlashGate SmartMedia Card Reader
+	0003  FlashGate CompactFlash Card Reader
+	0005  FlashGate
+	0006  SM PCCard R/W and SPD
+	0007  FlashGate ME (Authenticated)
+	000a  SDCard/MMC Reader/Writer
+0694  Lego Group
+	0001  Mindstorms Tower
+0698  Chuntex (CTX)
+	1786  1300ex Monitor
+	9999  VLxxxx Monitor+Hub
+0699  Tektronix, Inc.
+069a  Askey Computer Corp.
+	0001  VC010 WebCam [pwc]
+	0303  Cable Modem
+	0311  ADSL Router Remote NDIS Device
+	0318  Remote NDIS Device
+	0319  220V Remote NDIS Device
+	0320  IEEE 802.11b Wireless LAN Card
+	0321  Dynalink WLL013 / Compex WLU11A 802.11b Adapter
+	0402  Scientific Atlanta WebSTAR 100 & 200 series Cable Modem
+	0811  BT Virtual Bus for Helium
+	0821  BT Voyager 1010 802.11b Adapter
+	4402  Scientific Atlanta WebSTAR 2000 series Cable Modem
+	4403  Scientific Atlanta WebSTAR 300 series Cable Modem
+	4501  Scientific-Atlanta WebSTAR 2000 series Cable Modem
+069b  Thomson, Inc.
+	0704  DCM245 Cable Modem
+	070c  MP3 Player
+	070d  MP3 Player
+	070e  MP3 Player
+	070f  RCA Lyra RD1071 MP3 Player
+	2220  RCA Kazoo RD1000 MP3 Player
+	300a  RCA Lyra MP3 Player
+	3012  MP3 Player
+	3013  MP3 Player
+	5557  RCA CDS6300
+069d  Hughes Network Systems (HNS)
+	0001  Satellite Receiver Device
+	0002  Satellite Device
+069e  Marx
+	0005  CryptoBox v1.2
+069f  Allied Data Technologies BV
+	0010  Tornado Speakerphone FaxModem 56.0
+	0011  Tornado Speakerphone FaxModem 56.0
+	1000  ADT VvBus for CopperJet
+06a2  Topro Technology, Inc.
+06a3  Saitek PLC
+	0006  Cyborg Gold Joystick
+	0109  P880 Pad
+	0160  ST290 Pro
+	0200  Xbox Adrenalin Hub
+	0241  Xbox Adrenalin Gamepad
+	0255  X52 Flight Controller
+	040b  P990 Dual Analog Pad
+	040c  P2900 Wireless Pad
+	0422  ST90 Joystick
+	0460  ST290 Pro Flight Stick
+	0463  ST290
+	0464  Cyborg Evo
+	0471  Cyborg Graphite Stick
+	0501  R100 Sports Wheel
+	0502  ST200 Stick
+	0506  R220 Digital Wheel
+	051e  Cyborg Digital II Stick
+	052d  P750 Gamepad
+	053c  X45 Flight Controller
+	053f  X36F Flightstick
+	056c  P2000 Tilt Pad
+	056f  P2000 Tilt Pad
+	05d2  PC Dash 2
+	075c  X52 Flight Controller
+	0805  R440 Force Wheel
+	1003  GM2 Action Pad
+	1009  Action Pad
+	100a  SP550 Pad and Joystick Combo
+	100b  SP550 Pad
+	1509  P3000 Wireless Pad
+	1589  P3000 Wireless Pad
+	2541  X45 Flight Controller
+	3509  P3000 RF GamePad
+	353e  Cyborg Evo Wireless
+	3589  P3000 Wireless Pad
+	35be  Cyborg Evo
+	5509  P3000 Wireless Pad
+	8000  Gamers' Keyboard
+	801e  Cyborg 3D Digital Stick II
+	8021  Eclipse II Keyboard
+	802d  P750 Pad
+	803f  X36 Flight Controller
+	806f  P2000 Tilt Pad
+	80c0  Pro Gamer Command Unit
+	a502  Gaming Mouse
+	ff04  R440 Force Wheel
+	ff0c  Cyborg Force Rumble Pad
+	ff0d  P2600 Rumble Force Pad
+	ff12  Cyborg 3D Force Stick
+	ff17  ST 330 Rumble Force Stick
+	ff52  Cyborg 3D Rumble Force Joystick
+	ffb5  Cyborg Evo Force Joystick
+06a4  Xiamen Doowell Electron Co., Ltd
+06a5  Divio
+	0000  Typhoon Webcam 100k [nw8000]
+	d001  ProLink DS3303u WebCam
+	d800  Chicony TwinkleCam
+	d820  Wize Media 1000
+06a7  MicroStore, Inc.
+06a8  Topaz Systems, Inc.
+	0042  SignatureGem 1X5 Pad
+	0043  SignatureGem 1X5-HID Pad
+06a9  Westell
+	0005  WireSpeed Dual Connect Modem
+	0006  WireSpeed Dual Connect Modem
+	000a  WireSpeed Dual Connect Modem
+	000b  WireSpeed Dual Connect Modem
+	000e  802.11g Adapter
+06aa  Sysgration, Ltd
+06ac  Fujitsu Laboratories of America, Inc.
+06ad  Greatland Electronics Taiwan, Ltd
+06ae  Professional Multimedia Testing Centre
+06af  Harting, Inc. of North America
+06b8  Pixela Corp.
+06b9  Alcatel Telecom
+	0121  SpeedTouch 121g Wireless Dongle
+	2001  SPEED TOUCH Card
+	4061  SpeedTouch ISDN or ADSL Modem
+	a5a5  DynaMiTe Modem
+06ba  Smooth Cord & Connector Co., Ltd
+06bb  EDA, Inc.
+06bc  Oki Data Corp.
+06bd  AGFA-Gevaert NV
+	0001  SnapScan 1212U
+	0002  SnapScan 1236U
+	0100  SnapScan Touch
+	0101  SNAPSCAN ELITE
+	0200  ScanMaker 8700
+	02bf  DUOSCAN f40
+	0400  CL30
+	0401  Mass Storage
+	0403  ePhoto CL18 Camera
+	0404  ePhoto CL20 Camera
+	2061  SnapScan 1212U (?)
+	208d  Snapscan e40
+	208f  SnapScan e50
+	2091  SnapScan e20
+	2093  SnapScan e10
+	2095  SnapScan e25
+	2097  SnapScan e26
+	20fd  SnapScan e52
+	20ff  SnapScan e42
+06be  AME Optimedia Technology Co., Ltd
+	1005  Dazzle DPVM! (1005)
+	d001  P35U Camera Capture
+06bf  Leoco Corp.
+06c2  Phidgets Inc. (formerly GLAB)
+	0030  PhidgetRFID
+	0038  4-Motor PhidgetServo v3.0
+	0039  1-Motor PhidgetServo v3.0
+	003a  8-Motor PhidgetAvancedServo
+	0040  PhidgetInterface Kit 0-0-4
+	0044  PhidgetInterface Kit 0-16-16
+	0045  PhidgetInterface Kit 8-8-8
+	0048  PhidgetStepper (Under Development)
+	0049  PhidgetTextLED Ver 1.0
+	004a  PhidgetLED Ver 1.0
+	004b  PhidgetEncoder Ver 1.0
+	0051  PhidgetInterface Kit 0-5-7 (Custom)
+	0052  PhidgetTextLCD
+	0053  PhidgetInterfaceKit 0-8-8
+	0058  PhidgetMotorControl Ver 1.0
+	0070  PhidgetTemperatureSensor Ver 1.0
+	0071  PhidgetAccelerometer Ver 1.0
+	0072  PhidgetWeightSensor Ver 1.0
+	0073  PhidgetHumiditySensor
+	0074  PhidgetPHSensor
+	0075  PhidgetGyroscope
+06c4  Bizlink International Corp.
+06c5  Hagenuk, GmbH
+06c6  Infowave Software, Inc.
+06c8  SIIG, Inc.
+06c9  Taxan (Europe), Ltd
+	0005  Monitor Control
+	0007  Monitor Control
+	0009  Monitor Control
+06ca  Newer Technology, Inc.
+06cb  Synaptics, Inc.
+	0001  HID Device
+	0002  HID Device
+	0003  HID Device
+	0005  Touchpad/FPS
+	0006  HID Device
+	0007  HID Device
+	0008  HID Device
+	0009  Composite TouchPad and TrackPoint
+	000e  HID Device
+	0010  Composite Human Interface Device
+	0013  Human Interface Device
+06cc  Terayon Communication Systems
+	0101  Cable Modem
+	0102  Cable Modem
+	0103  Cable Modem
+	0104  Cable Modem
+	0304  Cable Modem
+06cd  Keyspan
+	0101  USA-28 PDA [no firmware]
+	0102  USA-28X PDA [no firmware]
+	0103  USA-19 PDA [no firmware]
+	0104  PDA [prerenum]
+	0105  USA-18X PDA [no firmware]
+	0106  USA-19W PDA [no firmware]
+	0107  USA-19 PDA
+	0108  USA-19W PDA
+	0109  USA-49W serial adapter [no firmware]
+	010a  USA-49W serial adapter
+	010b  USA-19Qi serial adapter [no firmware]
+	010c  USA-19Qi serial adapter
+	010d  USA-19Q serial Adapter (no firmware)
+	010e  USA-19Q serial Adapter
+	010f  USA-28 PDA
+	0110  USA-28Xb PDA
+	0111  USA-18 serial Adapter
+	0112  USA-18X PDA
+	0113  USA-28Xb PDA [no firmware]
+	0114  USA-28Xa PDA [no firmware]
+	0115  USA-28Xa PDA
+	0116  USA-18XA serial Adapter (no firmware)
+	0117  USA-18XA serial Adapter
+	0118  USA-19QW PDA [no firmware]
+	0119  USA-19QW PDA
+	011a  USA-49Wlc serial adapter [no firmware]
+	011b  MPR Serial Preloader (MPRQI)
+	011c  MPR Serial (MPRQI)
+	011d  MPR Serial Preloader (MPRQ)
+	011e  MPR Serial (MPRQ)
+	0121  USA-19hs serial adapter
+	012a  USA-49Wlc serial adapter
+	0201  Digital Media Remote
+	0202  UIA-11 remote control
+06cf  SpheronVR AG
+	1010  PanoCam 10
+	1012  PanoCam 12/12X
+06d0  LapLink, Inc.
+	0622  LapLink Gold USB-USB Bridge [net1080]
+06d1  Daewoo Electronics Co., Ltd
+06d3  Mitsubishi Electric Corp.
+	0380  CP8000D Port
+	0381  CP770D Port
+	0385  CP900D Port
+	0387  CP980D Port
+	038b  CP3020D Port
+	038c  CP900DW(ID) Port
+	0393  CP9500D/DW Port
+	0394  CP9000D/DW Port
+	03a1  CP9550D/DW Port
+06d4  Cisco Systems
+06d5  Toshiba
+	4000  Japanese Keyboard
+06d6  Aashima Technology B.V.
+	002d  Trust PowerC@m 350FT
+	002e  Trust PowerC@m 350FS
+	0030  Trust 710 LCD POWERC@M ZOOM - MSD
+	0031  Trust 710 LCD POWERC@M ZOOM
+	003a  Trust PowerC@m 770Z
+	003c  Trust 910z PowerC@m
+	003f  Trust 735S POWERC@M ZOOM, WDM DSC Bulk Driver
+	0050  Trust 738AV LCD PV Digital Camera
+	0062  TRUST 782AV LCD P. V. Video Capture
+	0066  TRUST Digital PCTV and Movie Editor
+	006b  TRUST AUDIO VIDEO EDITOR
+06d7  Network Computing Devices (NCD)
+06d8  Technical Marketing Research, Inc.
+06da  Phoenixtec Power Co., Ltd
+	0002  UPS
+06db  Paradyne
+06dc  Foxlink Image Technology Co., Ltd
+	0012  Scan 1200c Scanner
+	0014  Prolink Winscan Pro 2448U
+06de  Heisei Electronics Co., Ltd
+06e0  Multi-Tech Systems, Inc.
+	f101  MT5634ZBA-USB MultiModemUSB (old firmware)
+	f103  MT5634MU MultiMobileUSB
+	f104  MT5634ZBA-USB MultiModemUSB (new firmware)
+	f107  MT5634ZBA-USB-V92 MultiModemUSB
+06e1  ADS Technologies, Inc.
+	0008  UBS-10BT Ethernet [klsi]
+	0009  UBS-10BT Ethernet
+	0833  Mass Storage Device
+	a160  Instant Video-To-Go RDX-160 (no firmware)
+	a161  Instant Video-To-Go RDX-160
+	a190  Instand VCD Capture
+	a191  Instant VideoXpress
+	a337  Mini DigitalTV
+	a701  DVD Xpress
+	b337  Mini DigitalTV
+	b701  DVD Xpress B
+06e4  Alcatel Microelectronics
+06e6  Tiger Jet Network, Inc.
+	0200  Internet Phone
+	0201  Internet Phone
+	0202  Composite Device
+	0203  Internet Phone
+	0210  Composite Device
+	0211  Internet Phone
+	0212  Internet Phone
+	031c  Internet Phone
+	031d  Internet Phone
+	031e  Internet Phone
+	3200  Composite Device
+	3201  Internet Phone
+	3202  Composite Device
+	3203  Composite Device
+	7200  Composite Device
+	7210  Composite Device
+	7250  Composite Device
+	825c  Internet Phone
+	831c  Internet Phone
+	831d  Composite Device
+	831e  Composite Device
+	b200  Composite Device
+	b201  Composite Device
+	b202  Internet Phone
+	b210  Internet Phone
+	b211  Composite Device
+	b212  Composite Device
+	b250  Composite Device
+	b251  Internet Phone
+	b252  Internet Phone
+	c200  Internet Phone
+	c201  Internet Phone
+	c202  Composite Device
+	c203  Internet Phone
+	c210  Personal PhoneGateway
+	c211  Personal PhoneGateway
+	c212  Personal PhoneGateway
+	c213  PPG Device
+	c25c  Composite Device
+	c290  PPG Device
+	c291  PPG Device
+	c292  PPG Device
+	c293  Personal PhoneGateway
+	c31c  Composite Device
+	c39c  Personal PhoneGateway
+	c39d  PPG Device
+	c39e  PPG Device
+	c39f  PPG Device
+	c700  Internet Phone
+	c701  Internet Phone
+	c702  Composite Device
+	c703  Internet Phone
+	c710  VoIP Combo Device
+	c711  VoIP Combo
+	c712  VoIP Combo Device
+	c713  VoIP Combo Device
+	cf00  Composite Device
+	cf01  Internet Phone
+	cf02  Internet Phone
+	cf03  Composite Device
+	d210  Personal PhoneGateway
+	d211  PPG Device
+	d212  PPG Device
+	d213  Personal PhoneGateway
+	d700  Composite Device
+	d701  Composite Device
+	d702  Internet Phone
+	d703  Composite Device
+	d710  VoIP Combo
+	d711  VoIP Combo Device
+	d712  VoIP Combo
+	d713  VoIP Combo
+	df00  Composite Device
+	df01  Composite Device
+	df02  Internet Phone
+	df03  Internet Phone
+	f200  Internet Phone
+	f201  Internet Phone
+	f202  Composite Device
+	f203  Composite Device
+	f210  Internet Phone
+	f250  Composite Device
+	f252  Internet Phone
+	f310  Internet Phone
+	f350  Composite Device
+06ea  Sirius Technologies
+	0001  NetCom Roadster II 56k
+	0002  Roadster II 56k
+06eb  PC Expert Tech. Co., Ltd
+06ef  I.A.C. Geometrische Ingenieurs B.V.
+06f0  T.N.C Industrial Co., Ltd
+	de01  DualCam Video Camera
+	de02  DualCam Still Camera
+06f1  Opcode Systems, Inc.
+	a011  SonicPort
+	a021  SonicPort Optical
+06f2  Emine Technology Co.
+	0011  KVM Switch Keyboard
+06f6  Wintrend Technology Co., Ltd
+06f7  Wailly Technology Ltd
+	0003  USB->Din 4 Adaptor
+06f8  Guillemot Corp.
+	a300  Dual Analog Leader GamePad
+	b000  Hercules DJ Console
+	c000  Hercules Muse Pocket
+	d002  Hercules DJ Console
+	e000  HWGUSB2-54 WLAN
+	e010  HWGUSB2-54-LB
+	e020  HWGUSB2-54V2-AP
+06fa  HSD S.r.L
+06fc  Motorola Semiconductor Products Sector
+06fd  Boston Acoustics
+	0101  Audio Device
+	0102  Audio Device
+	0201  2-piece Audio Device
+06fe  Gallant Computer, Inc.
+0701  Supercomal Wire & Cable SDN. BHD.
+0703  Bvtech Industry, Inc.
+0705  NKK Corp.
+0706  Ariel Corp.
+0707  Standard Microsystems Corp.
+	0100  2202 Ethernet [klsi]
+	0200  2202 Ethernet [pegasus]
+	0201  EZ Connect USB Ethernet
+	ee04  SMCWUSB32 802.11b Wireless LAN Card
+	ee06  EZ-Connect 802.11g Adapter
+	ee13  EZ-Connect 802.11g Adapter
+0708  Putercom Co., Ltd
+	047e  USB-1284 BRIDGE
+0709  Silicon Systems, Ltd (SSL)
+070a  Oki Electric Industry Co., Ltd
+	4002  Bluetooth Device
+	4003  Bluetooth Device
+070d  Comoss Electronic Co., Ltd
+070e  Excel Cell Electronic Co., Ltd
+0710  Connect Tech, Inc.
+	0001  WhiteHeat (fake ID)
+	8001  WhiteHeat
+0711  Magic Control Technology Corp.
+	0100  Hub
+	0180  IRXpress Infrared Device
+	0181  IRXpress Infrared Device
+	0200  BAY-3U1S1P Serial Port
+	0210  MCT1S Serial Port
+	0230  MCT-232 Serial Port
+	0231  PS/2 Mouse Port
+	0232  Serial On Port
+	0240  PS/2 to USB Converter
+	0300  BAY-3U1S1P Parallel Port
+	0302  Parallel Port
+	0900  SVGA Adapter
+0713  Interval Research Corp.
+0714  NewMotion, Inc.
+	0003  ADB to USB convertor
+0717  ZNK Corp.
+0718  Imation Corp.
+	0002  SuperDisk 120MB
+	0003  SuperDisk 120MB (Authenticated)
+	0060  Flash Drive
+	0061  Flash Drive
+	0062  Flash Drive
+	0063  Swivel Flash Drive
+	0064  Flash Drive
+	0065  Flash Drive
+	0066  Flash Drive
+	0067  Flash Drive
+	0068  Flash Drive
+	0084  USB Flash Drive Mini
+0719  Tremon Enterprises Co., Ltd
+071b  Domain Technologies, Inc.
+	0002  DTI-56362-USB Digital Interface Unit
+	0101  Audio4-USB DSP Data Acquisition Unit
+	0201  Audio4-5410 DSP Data Acquisition Unit
+	0301  SB-USB JTAG Emulator
+071c  Xionics Document Technologies, Inc.
+071d  Eicon Networks Corp.
+	1000  Diva ISDN TA
+	1003  Diva
+	2000  Teledat Surf
+071e  Ariston Technologies
+0723  Centillium Communications Corp.
+	0002  Palladia 300/400 Adsl Modem
+0726  Vanguard International Semiconductor-America
+0729  Amitm
+	1000  USC-1000 Serial Port
+072e  Sunix Co., Ltd
+072f  Advanced Card Systems, Ltd
+	0001  AC1030-based SmartCard Reader
+	0008  ACR 80 Smart Card Reader
+	1000  PLDT Drive
+	1001  PLDT Drive
+	8002  AET63 BioTRUSTKey
+	8003  ACR120
+	8103  ACR120
+	9000  ACR38 AC1038-based Smart Card Reader
+	90cc  ACR38 SmartCard Reader
+	90cf  ACR38 SAM Smart Card Reader
+	90d0  PertoSmart EMV - Card Reader
+0731  Susteen, Inc.
+	0528  SonyEricsson DCU-11 Cable
+0732  Goldfull Electronics & Telecommunications Corp.
+0733  ViewQuest Technologies, Inc.
+	0101  Digital Video Camera
+	0110  VQ110
+	0401  CS330 WebCam
+	0402  M-318B WebCam
+	0430  Intel Pro Share WebCam
+	0630  VQ630 Dual Mode Digital Camera(Bulk)
+	0631  Hercules Dualpix
+	0780  Smart Cam Deluxe(composite)
+	1310  Epsilon 1.3/Jenoptik JD C1.3/UMAX AstraPix 470
+	1311  Digital Dream Epsilon 1.3
+	2211  Jenoptik
+0734  Lasat Communications A/S
+	0001  560V Modem
+	0002  Lasat 560V Modem
+	043a  DVS Audio
+0735  Asuscom Network
+	2100  ISDN Adapter
+	2101  ISDN Adapter
+	6694  ISDN Adapter
+	c541  ISDN TA 280
+0736  Lorom Industrial Co., Ltd
+0738  Mad Catz, Inc.
+	4507  XBox Device
+	4516  XBox Device
+	4520  XBox Device
+	4526  XBox Device
+	4536  XBox Device
+	4540  XBox Device
+	4556  XBox Device
+	4566  XBox Device
+	4576  XBox Device
+	4586  XBox Device
+	4588  XBox Device
+073a  Chaplet Systems, Inc.
+073b  Suncom Technologies
+073d  Eutron S.p.a.
+	0005  Crypto Token
+	0007  CryptoIdentity CCID
+	0025  SmartKey 3
+	0c00  Pocket Reader
+	0d00  StarSign Bio Token 3.0 EU
+073c  Industrial Electronic Engineers, Inc.
+	0305  Pole Display (PC305-3415  2 x 20 Line Display)
+	0322  Pole Display (PC322-3415  2 x 20 Line Display)
+	0324  Pole Display (LB324-USB   4 x 20 Line Display)
+	0330  Pole Display (P330-3415   2 x 20 Line Display)
+	0450  Pole Display (L450-USB   Graphic Line Display)
+	0505  Pole Display (SPC505-3415 2 x 20 Line Display)
+	0522  Pole Display (SPC522-3415 2 x 20 Line Display)
+	0624  Pole Display (SP324-3415  2 x 20 Line Display)
+073e  NEC, Inc.
+	0301  Game Pad
+0745  Syntech Information Co., Ltd
+0746  Onkyo Corp.
+	5500  SE-U55 Audio Device
+0747  Labway Corp.
+0748  Strong Man Enterprise Co., Ltd
+0749  EVer Electronics Corp.
+074a  Ming Fortune Industry Co., Ltd
+074b  Polestar Tech. Corp.
+074c  C-C-C Group PLC
+074d  Micronas GmbH
+	3553  Composite USB-Device
+	3554  Composite USB-Device
+	3556  Composite USB-Device
+074e  Digital Stream Corp.
+	0001  PS/2 Adapter
+	0002  PS/2 Adapter
+0755  Aureal Semiconductor
+0757  Network Technologies, Inc.
+075b  Sophisticated Circuits, Inc.
+	0001  Kick-off! Watchdog
+0763  Midiman
+	0115  KeyRig 25
+	0117  Trigger Finger
+	0119  MidAir
+	0150  M-Audio Uno
+	0160  M-Audio 1x1
+	0192  M-Audio Keystation 88es
+	0193  ProKeys 88
+	0194  ProKeys 88sx
+	0195  Oxygen 8 v2
+	0196  Oxygen 49
+	0197  Oxygen 61
+	0198  Axiom 25
+	0199  Axiom 49
+	019a  Axiom 61
+	019b  KeyRig 49
+	019c  KeyStudio
+	1001  MidiSport 2x2
+	1002  MidiSport 2x2
+	1003  MidiSport 2x2
+	1010  MidiSport 1x1
+	1011  MidiSport 1x1
+	1014  M-Audio Keystation Loader
+	1015  M-Audio Keystation
+	1020  Midisport 4x4
+	1021  MidiSport 4x4
+	1030  Midisport 8x8
+	1031  MidiSport 8x8/s Loader
+	1033  MidiSport 8x8/s
+	1040  M-Audio MidiSport 2x4 Loader
+	1041  M-Audio MidiSport 2x4
+	2001  M Audio Quattro
+	2002  M Audio Duo
+	2003  M Audio AudioPhile
+	2004  M-Audio MobilePre
+	2006  M-Audio Transit
+	2007  M-Audio Sonica Theater
+	2008  M-Audio Ozone
+	200d  M-Audio OmniStudio
+	200f  M-Audio MobilePre
+	2010  M-Audio Fast Track
+	2013  M-Audio JamLab
+	2015  M-Audio RunTime DFU
+	2016  M-Audio RunTime DFU
+	2019  M-Audio Ozone Academic
+	201a  M-Audio Micro
+	201b  M-Audio RunTime DFU
+	201d  M-Audio Producer
+	2080  M-Audio RunTime DFU
+	2081  M-Audio RunTime DFU
+	2803  M-Audio Audiophile DFU
+	2804  M-Audio MobilePre DFU
+	2806  M-Audio Transit DFU
+	2815  M-Audio DFU
+	2816  M-Audio DFU
+	281b  M-Audio DFU
+	2880  M-Audio DFU
+	2881  M-Audio DFU
+0764  Cyber Power System, Inc.
+	0005  Cyber Power UPS
+	0501  CP1500 AVR UPS
+0765  X-Rite, Inc.
+0766  Jess-Link Products Co., Ltd
+0767  Tokheim Corp.
+0768  Camtel Technology Corp.
+	0006  Camtel Technology USB TV Genie Pro FM Model TVB330
+	0023  eHome Infrared Receiver
+0769  Surecom Technology Corp.
+	11f2  EP-9001-g 802.11g 54M WLAN Adapter
+	11f3  RT2570
+	11f7  802.11g 54M WLAN Adapter
+	31f3  RT2573
+076a  Smart Technology Enablers, Inc.
+076b  OmniKey AG
+	0596  CardMan 2020
+	1021  CardMan 1021
+	1221  CardMan 1221
+	1784  CardMan 6020
+	3021  CardMan 3121
+	3610  CardMan 3620
+	3621  CardMan 3621
+	3821  CardMan 3821
+	4321  CardMan 4321
+	5121  CardMan 5121
+	5125  CardMan 5125
+	6622  CardMan 6121
+	a011  CCID Smart Card Reader Keyboard
+	a021  CCID Smart Card Reader
+	a022  CardMan Smart@Link
+	c000  CardMan 3x21 CS
+	c001  CardMan 5121 CS
+076c  Partner Tech
+076d  Denso Corp.
+076e  Kuan Tech Enterprise Co., Ltd
+076f  Jhen Vei Electronic Co., Ltd
+0770  Welch Allyn, Inc - Medical Division
+0774  AmTRAN Technology Co., Ltd
+0775  Longshine Electronics Corp.
+0776  Inalways Corp.
+0777  Comda Enterprise Corp.
+0778  Volex, Inc.
+0779  Fairchild Semiconductor
+077a  Sankyo Seiki Mfg. Co., Ltd
+077b  Linksys
+	08be  BEFCMU10 v4 Cable Modem
+	2219  WUSB11 V2.6 802.11b Adapter
+	2226  USB200M 100baseTX Adapter
+077c  Forward Electronics Co., Ltd
+	0005  NEC Keyboard
+077d  Griffin Technology
+	0223  IMic Audio In/Out
+	0405  iMate, ADB Adapter
+	0410  PowerMate
+	041a  PowerWave
+	07af  iMic
+	627a  Radio SHARK
+077f  Well Excellent & Most Corp.
+0781  SanDisk Corp.
+	0001  SDDR-05a ImageMate CompactFlash Reader
+	0002  SDDR-31 ImageMate II CompactFlash Reader
+	0005  SDDR-05b (CF II) ImageMate CompactFlash Reader
+	0100  ImageMate SDDR-12
+	0200  SDDR-09 (SSFDC) ImageMate SmartMedia Reader [eusb]
+	0400  SecureMate SD/MMC Reader
+	0621  SDDR-86 Imagemate 6-in-1 Reader
+	0720  Sansa C200 series in recovery mode
+	0729  Sansa E200 series in recovery mode
+	0810  SDDR-75 ImageMate CF-SM Reader
+	0830  ImageMate CF/MMC/SD Reader
+	1234  Cruzer Mini Flash Drive
+	5150  SDCZ2 Cruzer Mini Flash Drive (thin)
+	5151  Cruzer Micro 256/512MB Flash Drive
+	5153  Cruzer USB-Flash-Drive
+	5406  Cruzer Micro 1/4GB Flash Drive
+	5408  Cruzer Titanium U3
+	6100  Ultra II SD Plus 2GB
+	7100  Cruzer Mini
+	7101  Pen Flash
+	7102  Cruzer Mini
+	7103  Cruzer Mini
+	7104  Cruzer Micro Mini 256MB Flash Drive
+	7105  Cruzer Mini
+	7106  Cruzer Mini
+	7112  Cruzer Micro 128MB Flash Drive
+	7113  Cruzer Micro 256MB Flash Drive
+	7114  Cruzer Mini
+	7115  Cruzer Mini
+	7420  Sansa E200 series (mtp)
+	7421  Sansa E200 series
+	7432  Sansa Clip (mtp)
+	7433  Sansa Clip (msc)
+	7450  Sansa C250
+	7451  Sansa C240
+	7480  Sansa Connect
+	7481  Sansa Connect (in recovery mode)
+	8181  Pen Flash
+	8183  Hi-Speed Mass Storage Device
+	8185  SDCZ2 Cruzer Mini Flash Drive (older, thick)
+	8888  Card Reader
+	8889  SDDR-88 Imagemate 8-in-1 Reader
+	8919  Card Reader
+	8989  ImageMate 12-in-1 Reader
+	9191  ImageMate CF
+	9219  Card Reader
+	9292  ImageMate CF Reader/Writer
+	9393  ImageMate SD-MMC
+	9595  ImageMate xD-SM
+	9797  ImageMate MS-PRO
+	9919  Card Reader
+	9999  SDDR-99 5-in-1 Reader
+	a7e8  SDDR-113 MicroMate SDHC Reader
+	b2b3  SDDR-103 MobileMate SD+ Reader
+0782  Trackerball
+0783  C3PO
+	0003  LTC31 SmartCard Reader
+0784  Vivitar, Inc.
+	0100  Vivicam 2655
+	1310  Vivicam 3305
+	1688  Vivicam 3665
+	1689  Gateway DC-M42/Labtec DC-505/Vivitar Vivicam 3705
+	2620  AOL Photocam Plus
+	2888  Polaroid DC700
+	3330  Nytec ND-3200 Camera
+	4300  Traveler D1
+	5260  Werlisa Sport PX 100 / JVC GC-A33 Camera
+	5300  Pretec dc530
+0785  NTT-ME
+	0001  MN128mini-V ISDN TA
+	0003  MN128mini-J ISDN TA
+0789  Logitec Corp.
+	0026  LHD Device
+	0033  DVD Multi-plus unit LDR-H443SU2
+	0063  LDR Device
+	0064  LDR-R Device
+	00b3  DVD Multi-plus unit LDR-H443U2
+	010c  Realtek RTL8187 Wireless 802.11g 54Mbps Network Adapter
+078b  Happ Controls, Inc.
+	0010  Driving UGCI
+	0020  Flying UGCI
+	0030  Fighting UGCI
+078c  GTCO/CalComp
+	0400  Digitizer (Whiteboard)
+078e  Brincom, Inc.
+0790  Pro-Image Manufacturing Co., Ltd
+0791  Copartner Wire and Cable Mfg. Corp.
+0792  Axis Communications AB
+0793  Wha Yu Industrial Co., Ltd
+0794  ABL Electronics Corp.
+0795  RealChip, Inc.
+0796  Certicom Corp.
+0797  Grandtech Semiconductor Corp.
+	6801  Flatbed Scanner
+	6802  InkJet Color Printer
+	8001  SmartCam
+	801a  Typhoon StyloCam
+	801c  Meade Binoculars/Camera
+	8901  ScanHex SX-35a
+	8909  ScanHex SX-35b
+	8911  ScanHex SX-35c
+0798  Optelec
+	0001  Braille Voyager
+079b  Sagem
+	0027  USB-Serial Controller
+	004a  XG-760A
+	004b  Wi-Fi 11g adapter
+	0056  Agfa AP1100 Photo Printer
+	0062  XG-76NA
+079d  Alfadata Computer Corp.
+	0201  GamePort Adapter
+07a1  Digicom S.p.A.
+	d952  Palladio USB V.92 Modem
+07a2  National Technical Systems
+07a3  Onnto Corp.
+07a4  Be, Inc.
+07a6  ADMtek, Inc.
+	07c2  AN986A Ethernet
+	0986  AN986 Pegasus Ethernet
+	8266  Infineon WildCard-USB Wireless LAN Adapter
+	8511  ADM8511 Pegasus II Ethernet
+	8513  AN8513 Ethernet
+	8515  AN8515 Ethernet
+07aa  Corega K.K.
+	0001  Ether USB-T Ethernet [klsi]
+	0004  FEther USB-TX Ethernet [pegasus]
+	000c  WirelessLAN USB-11
+	000d  FEther USB-TXS
+	0012  Stick-11 802.11b Adapter
+	0017  FEther USB2-TX
+	001a  ULUSB-11 Key
+	002f  CG-WLUSB2GNL
+	7613  Stick-11 V2 802.11b Adapter
+	9601  FEther USB-TXC
+07ab  Freecom Technologies
+	fc01  IDE bridge
+	fc02  Cable II USB-2
+	fc03  USB2-IDE IDE bridge
+	fcf8  Freecom Classic SL Network Drive
+07af  Microtech
+	0004  SCSI-DB25 SCSI Bridge [shuttle]
+	0005  SCSI-HD50 SCSI Bridge [shuttle]
+	0006  CameraMate SmartMedia and CompactFlash Card Reader [eusb/shuttle]
+	fc01  Freecom USB-IDE
+07b0  Trust Technologies
+	0001  ISDN TA
+	0002  ISDN TA128 Plus
+	0003  ISDN TA128 Deluxe
+	0005  ISDN TA128 SE
+	0006  ISDN TA128 CE
+	0007  ISDN TA
+	0008  ISDN TA
+07b1  IMP, Inc.
+07b2  Motorola BCS, Inc.
+	0100  SURFboard Voice over IP Cable Modem
+	0900  SURFboard Gateway
+	0950  SURFboard SBG950 Gateway
+	1000  SURFboard SBG1000 Gateway
+	4100  SurfBoard SB4100 Cable Modem
+	4200  SurfBoard SB4200 Cable Modem
+	4210  SurfBoard 4210 Cable Modem
+	4220  SURFboard SB4220 Cable Modem
+	4500  CG4500 Communications Gateway
+	450b  CG4501 Communications Gateway
+	450e  CG4500E Communications Gateway
+	5100  SurfBoard SB5100 Cable Modem
+	5101  SurfBoard SB5101 Cable Modem
+	5120  SurfBoard SB5120 Cable Modem (RNDIS)
+	7030  Wireless Adapter WU830G
+07b3  Plustek, Inc.
+	0001  OpticPro 1212U Scanner
+	0003  Scanner
+	0010  OpticPro U12 Scanner
+	0011  OpticPro U24 Scanner
+	0013  OpticPro UT12 Scanner
+	0014  Scanner
+	0015  OpticPro U24 Scanner
+	0017  OpticPro UT12/16/24 Scanner
+	0204  Scanner
+	0400  OpticPro 1248U Scanner
+	0401  OpticPro 1248U Scanner #2
+	0403  OpticPro U16B Scanner
+	0404  Scanner
+	0405  A8 Namecard-s Controller
+	0406  A8 Namecard-D Controller
+	0410  Scanner
+	0412  Scanner
+	0800  OpticPro ST48 Scanner
+	0c03  OpticPro ST64+ Scanner
+07b4  Olympus Optical Co., Ltd
+	0100  Camedia C-2100/C-3000 Ultra Zoom Camera
+	0102  Camedia E-10/C-220/C-50 Camera
+	0105  Camedia C-310Z/C-700/C-750UZ/C-755/C-765UZ/C-3040/C-4000/C-5050Z/D-560/C-3020Z Zoom Camera
+	0109  C-370Z/D-535Z/X-450
+	0112  MAUSB-100 xD Card Reader
+	0113  Mju 500
+	0114  C-350Z Camera
+	0118  Mju Mini Digital/Mju Digital 500 Camera
+	0184  P-S100 port
+	0203  Digital Voice Recorder DW-90
+	0206  Digital Voice Recorder DS-330
+	0207  Digital Voice Recorder & Camera W-10
+	0209  Digital Voice Recorder DM-20
+	020d  Digital Voice Recorder VN-240PC
+07b5  Mega World International, Ltd
+	0017  Joystick
+	0213  Thrustmaster Firestorm Digital 3 Gamepad
+	9902  GamePad
+07b6  Marubun Corp.
+07b7  TIME Interconnect, Ltd
+07b8  D-Link Corp.
+	110c  XX1
+	1201  IEEE 802.11b Adapter
+	200c  XX2
+	2573  Wireless LAN Card
+	4000  DU-E10 Ethernet [klsi]
+	4002  DU-E100 Ethernet [pegasus]
+	4003  1/10/100 Ethernet Adapter
+	4004  XX4
+	4007  XX5
+	400b  XX6
+	400c  XX7
+	401a  RTL8151
+	4102  USB 1.1 10/100M Fast Ethernet Adapter
+	4104  XX9
+	420a  UF200 Ethernet
+	6001  WL54
+	a001  Wireless Network Adapter
+	abc1  DU-E10 Ethernet [pegasus]
+	b000  BWU613
+	b02a  AboCom Bluetooth Device
+	b02b  Bluetooth dongle
+	b02c  BCM92045DG-Flash with trace filter
+	b02d  BCM92045DG-Flash with trace filter
+	b02e  BCM92045DG-Flash with trace filter
+	b030  BCM92045DG-Flash with trace filter
+	b031  BCM92045DG-Flash with trace filter
+	b032  BCM92045DG-Flash with trace filter
+	b033  BCM92045DG-Flash with trace filter
+	b21a  802.11g Wireless Adapter
+	b21b  HWU54DM
+	b21c  RT2573
+	b21d  RT2573
+	b21e  RT2573
+	b21f  WUG2700
+	d011  MP3 Player
+	e001  Mass Storage Device
+	e002  Mass Storage Device
+	e003  Mass Storage Device
+	e004  Mass Storage Device
+	e005  Mass Storage Device
+	e006  Mass Storage Device
+	e007  Mass Storage Device
+	e008  Mass Storage Device
+	e009  Mass Storage Device
+	e00a  Mass Storage Device
+	e4f0  Card Reader Driver
+	f101  DSB-560 Modem [atlas]
+07bc  Canon Computer Systems, Inc.
+07bd  Webgear, Inc.
+07be  Veridicom
+07c0  Code Mercenaries Hard- und Software GmbH
+	1121  The Claw
+	1500  IO-Warrior 40
+	1501  IO-Warrior 24
+	1502  IO-Warrior 48
+	1503  IO-Warrior 28
+07c1  Keisokugiken
+	0068  HKS-0200 USBDAQ
+07c4  Datafab Systems, Inc.
+	0102  USB to LS120
+	0103  USB to IDE
+	1234  USB to ATAPI
+	a000  CompactFlash Card Reader
+	a001  CompactFlash & SmartMedia Card Reader [eusb]
+	a002  Disk Drive
+	a003  Datafab-based Reader
+	a004  USB to MMC Class Drive
+	a005  CompactFlash & SmartMedia Card Reader
+	a006  SmartMedia Card Reader
+	a007  Memory Stick Class Drive
+	a103  MDSM-B reader
+	a107  USB to Memory Stick (LC1) Drive
+	a109  LC1 CompactFlash & SmartMedia Card Reader
+	a10b  USB to CF+MS(LC1)
+	a200  DF-UT-06 Hama MMC/SD Reader
+	a400  CompactFlash & Microdrive Reader
+	a600  Card Reader
+	ad01  Mass Storage Device
+	ae01  Mass Storage Device
+	af01  Mass Storage Device
+	b000  USB to CF(LC1)
+	b001  USB to CF+PCMCIA
+	b004  MMC/SD Reader
+	b006  USB to PCMCIA
+	b00a  USB to CF+SD Drive(LC1)
+	b00b  USB to Memory Stick(LC1)
+07c5  APG Cash Drawer
+07c6  ShareWave, Inc.
+07c7  Powertech Industrial Co., Ltd
+07c8  B.U.G., Inc.
+	0202  MN128-SOHO PAL
+07c9  Allied Telesyn International
+	b100  AT-USB100
+07ca  AVerMedia Technologies, Inc.
+	0002  AVerTV PVR USB/EZMaker Pro Device
+	0026  AVerTV
+	1228  MPEG-2 Capture Device (M038)
+	e880  MPEG-2 Capture Device (E880)
+	e882  MPEG-2 Capture Device (E882)
+07cb  Kingmax Technology, Inc.
+07cc  Carry Computer Eng., Co., Ltd
+	0000  CF Card Reader
+	0001  Reader (UICSE)
+	0002  Reader (UIS)
+	0003  SM Card Reader
+	0004  SM/CF/PCMCIA Card Reader
+	0005  Reader (UISA2SE)
+	0006  SM/CF/PCMCIA Card Reader
+	0007  Reader (UISA6SE)
+	000c  SM/CF Card Reader
+	000d  SM/CF Card Reader
+	000e  Reader (UISDA)
+	000f  Reader (UICLIK)
+	0010  Reader (UISMA)
+	0012  Reader (UISC6SE-FLASH)
+	0014  Litronic Fortezza Reader
+	0030  Mass Storage (UISDMC12S)
+	0040  Mass Storage (UISDMC13S)
+	0100  Reader (UID)
+	0101  Reader (UIM)
+	0102  Reader (UISDMA)
+	0103  Reader (UISDMC)
+	0104  Reader (UISDM)
+	0200  6-in-1 Card Reader
+	0201  Mass Storage (UISDMC1S & UISDMC3S)
+	0202  Mass Storage (UISDMC5S)
+	0203  Mass Storage (UISMC5S)
+	0204  Mass Storage (UIM4/5S & UIM7S)
+	0205  Mass Storage (UIS4/5S & UIS7S)
+	0206  Mass Storage (UISDMC10S & UISDMC11S)
+	0207  Mass Storage (UPIDMA)
+	0208  Mass Storage (UCFC II)
+	0210  Mass Storage (UPIXXA)
+	0213  Mass Storage (UPIDA)
+	0214  Mass Storage (UPIMA)
+	0215  Mass Storage (UPISA)
+	0217  Mass Storage (UPISDMA)
+	0223  Mass Storage (UCIDA)
+	0224  Mass Storage (UCIMA)
+	0225  Mass Storage (UIS7S)
+	0227  Mass Storage (UCIDMA)
+	0234  Mass Storage (UIM7S)
+	0235  Mass Storage (UIS4S-S)
+	0237  Velper (UISDMC4S)
+	0300  6-in-1 Card Reader
+	0301  6-in-1 Card Reader
+	0303  Mass Storage (UID10W)
+	0304  Mass Storage (UIM10W)
+	0305  Mass Storage (UIS10W)
+	0308  Mass Storage (UIC10W)
+	0309  Mass Storage (UISC3W)
+	0310  Mass Storage (UISDMA2W)
+	0311  Mass Storage (UISDMC14W)
+	0320  Mass Storage (UISDMC4W)
+	0321  Mass Storage (UISDMC37W)
+	0330  WINTERREADER Reader
+	0350  9-in-1 Card Reader
+	0500  Mass Storage
+	0501  Mass Storage
+07cd  Elektor
+	0001  USBuart Serial Port
+07cf  Casio Computer Co., Ltd
+	1001  QV-8000SX/5700/3000EX Digicam; Exilim EX-M20
+	1003  Exilim EX-S500
+	1004  Exilim EX-Z120
+	1011  USB-CASIO PC CAMERA
+	2002  E-125 Cassiopeia Pocket PC
+	3801  WMP-1 MP3-Watch
+	4001  Label Printer KL-P1000
+	4007  CW50 Device
+	4104  Cw75 Device
+	4107  CW-L300 Device
+	4500  LV-20 Digital Camera
+	6801  PL-40R
+	6802  MIDI Keyboard
+07d0  Dazzle
+	0001  Digital Video Creator I
+	0002  Global Village VideoFX Grabber
+	0003  Fusion Model DVC-50 Rev 1 (NTSC)
+	0004  DVC-800 (PAL) Grabber
+	0005  Fusion Video and Audio Ports
+	0006  DVC 150 Loader Device
+	0007  DVC 150
+	0327  Fusion Digital Media Reader
+	1001  DM-FLEX DFU Adapter
+	1002  DMHS2 DFU Adapter
+	1102  CF Reader/Writer
+	1103  SD Reader/Writer
+	1104  SM Reader/Writer
+	1105  MS Reader/Writer
+	1106  xD/SM Reader/Writer
+	1202  MultiSlot Reader/Writer
+	2000  FX2 DFU Adapter
+	2001  eUSB CompactFlash Reader
+	4100  Kingsun SF-620 Infrared Adapter
+	4959  Kingsun KS-959 Infrared Adapter
+07d1  D-Link System
+	13ec  VvBus for Helium 2xx
+	13ed  VvBus for Helium 2xx
+	13f1  DSL-302G Modem
+	13f2  DSL-502G Router
+	3a07  WUA-2340 Adapter
+	3a08  predator Bootloader Download
+	3a0d  DWA-120 Wireless 108G Adapter
+	3b01  AirPlus G DWL-G122 Wireless Adapter
+	3b10  RangeBooster N Adapter
+	3b11  Wireless N Adapter DWA-130
+	3c03  DWL-G122 802.11g Adapter [ralink rt73]
+	3c04  WUA-1340
+	3c05  EH103 Wireless G Adapter
+	3c07  Wireless G DWA-110 Adapter
+	3c09  DWA-140 802.11n Adapter [ralink rt2870]
+	5100  Remote NDIS Device
+	f101  DBT-122 Bluetooth
+	fc01  DBT-120 Bluetooth Adapter
+07d2  Aptio Products, Inc.
+07d3  Cyberdata Corp.
+07d7  GCC Technologies, Inc.
+07da  Arasan Chip Systems
+07de  Diamond Multimedia
+	2820  VC500 Video Capture Dongle
+07df  David Electronics Co., Ltd
+07e1  Ambient Technologies, Inc.
+	5201  V.90 Modem
+07e2  Elmeg GmbH & Co., Ltd
+07e3  Planex Communications, Inc.
+07e4  Movado Enterprise Co., Ltd
+	0967  SCard R/W CSR-145
+	0968  SCard R/W CSR-145
+07e5  QPS, Inc.
+	05c2  IDE-to-USB2.0 PCA
+	5c01  Que! CDRW
+07e6  Allied Cable Corp.
+07e7  Mirvo Toys, Inc.
+07e8  Labsystems
+07ea  Iwatsu Electric Co., Ltd
+07eb  Double-H Technology Co., Ltd
+07ec  Taiyo Electric Wire & Cable Co., Ltd
+07ee  Torex Retail (formerly Logware)
+	0002  Cash Drawer I/F
+07ef  STSN
+	0001  Internet Access Device
+07f6  Circuit Assembly Corp.
+07f7  Century Corp.
+	0005  ScanLogic/Century Corporation uATA
+	011e  Century USB Disk Enclosure
+07f9  Dotop Technology, Inc.
+07fa  Draytek
+	0778  miniVigor 128 ISDN TA
+	1012  BeWAN ADSL USB ST (grey)
+	a904  BeWAN ADSL
+	a905  BeWAN ADSL ST
+07fd  Mark of the Unicorn
+	0000  FastLane MIDI Interface
+	0001  FastLane Quad MIDI Interface
+	0002  MOTU Audio for 64 bit
+0801  Mag-Tek
+	0002  Mini Swipe Reader
+0802  Mako Technologies, LLC
+0803  Zoom Telephonics, Inc.
+	1300  V92 Faxmodem
+	4310  Wireless-G
+	5241  Cable Modem
+	5551  DSL Modem
+	9700  2986L FaxModem
+	9800  Cable Modem
+	a312  Wireless-G
+0809  Genicom Technology, Inc.
+080a  Evermuch Technology Co., Ltd
+080c  Datalogic S.p.A.
+	0300  Gryphon D120 Barcode Scanner
+	0400  Gryphon D120 Barcode Scanner
+	0500  Gryphon D120 Barcode Scanner
+	0600  Gryphon M100 Barcode Scanner
+080d  Teco Image Systems Co., Ltd
+	0102  Hercules Scan@home 48
+	0104  3.2Slim
+	0110  UMAX AstraSlim 1200 Scanner
+0810  Personal Communication Systems, Inc.
+0813  Mattel, Inc.
+	0001  Intel Play QX3 Microscope
+	0002  Dual Mode Camera Plus
+081a  MG Logic
+	1000  Duo Pen Tablet
+081b  Indigita Corp.
+	0600  Storage Adapter
+	0601  Storage Adapter
+081c  Mipsys
+081e  AlphaSmart, Inc.
+	df00  Handheld
+0822  Reudo Corp.
+	2001  IRXpress Infrared Device
+0825  GC Protronics
+0826  Data Transit
+0827  BroadLogic, Inc.
+0828  Sato Corp.
+0829  DirecTV Broadband, Inc. (Telocity)
+082d  Handspring
+	0100  Visor
+	0200  Treo
+	0300  Treo 600
+	0400  Handheld
+	0500  Handheld
+	0600  Handheld
+0830  Palm, Inc.
+	0001  m500
+	0002  m505
+	0003  m515
+	0004  Handheld
+	0005  Handheld
+	0006  Handheld
+	0010  Handheld
+	0011  Handheld
+	0012  Handheld
+	0013  Handheld
+	0014  Handheld
+	0020  i705
+	0021  Handheld
+	0022  Handheld
+	0023  Handheld
+	0024  Handheld
+	0030  Handheld
+	0031  Tungsten W
+	0032  Handheld
+	0033  Handheld
+	0034  Handheld
+	0040  m125
+	0041  Handheld
+	0042  Handheld
+	0043  Handheld
+	0044  Handheld
+	0050  m130
+	0051  Handheld
+	0052  Handheld
+	0053  Handheld
+	0054  Handheld
+	0060  Tungsten C/E/T/T2/T3 / Zire 71
+	0061  Lifedrive / Treo 650/680 / Tunsten E2/T5/TX / Zire 21/31/72 / Z22
+	0062  Handheld
+	0063  Handheld
+	0064  Handheld
+	0070  Zire
+	0071  Handheld
+	0072  Handheld
+	0080  Serial Adapter [for Palm III]
+	0081  Handheld
+	0082  Handheld
+0832  Kouwell Electronics Corp.
+	5850  Cable
+0833  Sourcenext Corp.
+	012e  KeikaiDenwa 8 with charger
+	039f  KeikaiDenwa 8
+0835  Action Star Enterprise Co., Ltd
+0839  Samsung Techwin Co., Ltd
+	0005  Digimax Camera
+	0008  Digimax 230 Camera
+	0009  Digimax 340
+	000a  Digimax 410
+	000e  Digimax 360
+	0010  Digimax 300
+	1003  Digimax 210SE
+	1005  Digimax 220
+	1009  Digimax V4
+	1012  6500 Document Camera
+	1058  S730 Camera
+	1542  Digimax 50 Duo
+	3000  Digimax 35 MP3
+083a  Accton Technology Corp.
+	1046  10/100 Ethernet [pegasus]
+	1060  HomeLine Adapter
+	1f4d  SMC8013WG Broadband Remote NDIS Device
+	3046  10/100 Series Adapter
+	3060  1/10/100 Adapter
+	3501  2664W
+	3502  WN3501D Wireless Adapter
+	3503  T-Sinus 111 Wireless Adapter
+	4501  T-Sinus 154data
+	4505  SMCWUSB-G
+	5046  SpeedStream 10/100 Ethernet [pegasus]
+	5501  Wireless Adapter 11g
+	6500  Cable Modem
+	6618  802.11n Wireless Adapter
+	7522  802.11N Wireless Adapter
+	a618  SMC EZ Connect N Draft 11n Wireless Adapter
+	b004  CPWUE001 USB/Ethernet Adapter
+	b522  EZ Connect N Draft 11n Wireless USB2.0 Adapter
+	bb01  BlueExpert Bluetooth Device
+	c003  802.11b Wireless Adapter
+	c501  Zoom Wireless-G
+	c561  802.11a/g Wireless Adapter
+	e501  ZD1211B
+	f501  802.11g Wireless Adapter
+	f502  802.11g Wireless Adapter
+083f  Global Village
+	b100  TelePort V.90 Fax/Modem
+0840  Argosy Research, Inc.
+	0060  Storage Adapter Bridge Module
+0841  Rioport.com, Inc.
+	0001  Rio 500
+0844  Welland Industrial Co., Ltd
+0846  NetGear, Inc.
+	1001  EA101 Ethernet [klsi]
+	1002  Ethernet
+	1020  Ethernet 10/100, USB1.1
+	1040  USB 2.0 Ethernet
+	4110  MA111 WiFi (v1)
+	4200  WG121 WiFi (v1)
+	4210  WG121 WiFi (v2)
+	4220  WG111 WiFi (v1)
+	4230  MA111 WiFi (v2)
+	4240  WG111 WiFi (v2)
+	4260  WG111v3 802.11g Adapter [realtek RTL8187B]
+	4300  WG111U
+	4301  WG111U (no firmware)
+	6a00  WG111 WiFi (v2)
+	7100  WN121T Wireless Adapter
+	9000  RangeMax NEXT Wireless-N Adapter WN111
+	a001  PA101 Phoneline10X Adapter
+084d  Minton Optic Industry Co., Inc.
+	0001  Jenoptik JD800i
+	0003  S-Cam F5 Digital Camera
+	0011  Argus DC3500 Digital Camera
+	0014  Praktica DC 32
+	0019  Praktica DPix3000
+	0025  Praktica DC 60
+	1001  ScanHex SX-35d
+084e  KB Gear
+	0001  KBGear JamCam
+	1002  Pablo Tablet
+084f  Empeg
+	0001  Empeg-Car Mark I/II Player
+0850  Fast Point Technologies, Inc.
+0851  Macronix International Co., Ltd
+	1542  SiPix Blink
+	1543  Maxell WS30 Slim Digital Camera
+	a168  MXIC
+0852  CSEM
+0853  Topre Corporation
+	0100  HHKB Professional
+0854  ActiveWire, Inc.
+	0100  I/O Board
+	0101  I/O Board, rev1
+0856  B&B Electronics
+	ac01  uLinks USOTL4 RS422/485 Adapter
+0858  Hitachi Maxell, Ltd
+	3102  Bluetooth Device
+	ffff  Maxell module with BlueCore in DFU mode
+0859  Minolta Systems Laboratory, Inc.
+085a  Xircom
+	0001  Portstation Dual Serial Port
+	0003  Portstation Paraller Port
+	0008  Ethernet
+	0009  Ethernet
+	000b  Portstation Dual PS/2 Port
+	0021  1 port to Serial Converter
+	0022  Parallel Port
+	0023  2 port to Serial Converter
+	0024  Parallel Port
+	0027  1 port to Serial Converter
+	0028  PortGear to SCSI Converter
+	0032  PortStation SCSI Module
+	003c  Bluetooth Adapter
+	0299  Colorvision, Inc. Monitor Spyder
+	8021  1 port to Serial
+	8023  2 port to Serial
+	8027  PGSDB9 Serial Port
+085c  ColorVision, Inc.
+	0200  Monitor Spyder
+0862  Teletrol Systems, Inc.
+0863  Filanet Corp.
+0864  NetGear, Inc.
+	4100  MA101 802.11b Adapter
+	4102  MA101 802.11b Adapter
+0867  Data Translation, Inc.
+	9812  ECON Data acquisition unit
+	9816  DT9816 ECON data acquisition module
+	9836  DT9836 data acquisition card
+086a  Emagic Soft- und Hardware GmbH
+	0001  Unitor8
+	0002  AMT8
+	0003  MT4
+086c  DeTeWe - Deutsche Telephonwerke AG & Co.
+	1001  Eumex 504PC ISDN TA
+	1002  Eumex 504PC (FlashLoad)
+	1003  TA33 ISDN TA
+	1004  TA33 (FlashLoad)
+	1005  Eumex 604PC HomeNet
+	1006  Eumex 604PC HomeNet (FlashLoad)
+	1007  Eumex 704PC DSL
+	1008  Eumex 704PC DSL (FlashLoad)
+	1009  Eumex 724PC DSL
+	100a  Eumex 724PC DSL (FlashLoad)
+	100b  OpenCom 30
+	100c  OpenCom 30 (FlashLoad)
+	100d  BeeTel Home 100
+	100e  BeeTel Home 100 (FlashLoad)
+	1011  USB2DECT
+	1012  USB2DECT (FlashLoad)
+	1013  Eumex 704PC LAN
+	1014  Eumex 704PC LAN (FlashLoad)
+	1021  OpenCom 40
+	1022  OpenCom 40 (FlashLoad)
+	1023  OpenCom 45
+	1024  OpenCom 45 (FlashLoad)
+	1025  Sinus 61 data
+	1029  dect BOX
+	102c  Eumex 604PC HomeNet [FlashLoad]
+	1030  Eumex 704PC DSL [FlashLoad]
+	1032  OpenCom 40 [FlashLoad]
+	1033  OpenCom 30 plus
+	1034  OpenCom 30 plus (FlashLoad)
+	1055  Eumex 220 ISDN TA
+	2000  OpenCom 1000
+086e  System TALKS, Inc.
+	1920  SGC-X2UL
+086f  MEC IMEX, Inc.
+0870  Metricom
+	0001  Ricochet GS
+0871  SanDisk, Inc.
+	0001  SDDR-01 Compact Flash Reader
+	0002  SDDR-31 Compact Flash Reader
+	0005  SDDR-05 Compact Flash Reader
+0873  Xpeed, Inc.
+0874  A-Tec Subsystem, Inc.
+0879  Comtrol Corp.
+087c  Adesso/Kbtek America, Inc.
+087d  Jaton Corp.
+	5704  Ethernet
+087e  Fujitsu Computer Products of America
+087f  Virtual IP Group, Inc.
+0880  APT Technologies, Inc.
+0883  Recording Industry Association of America (RIAA)
+0885  Boca Research, Inc.
+0886  XAC Automation Corp.
+	0630  Intel PC Camera CS630
+0887  Hannstar Electronics Corp.
+088b  MassWorks, Inc.
+	4944  MassWorks ID-75 TouchScreen
+0892  DioGraphy, Inc.
+	0101  Smartdio Reader/Writer
+089c  United Technologies Research Cntr.
+089d  Icron Technologies Corp.
+089e  NST Co., Ltd
+089f  Primex Aerospace Co.
+08a5  e9, Inc.
+08a8  Andrea Electronics
+08ae  Macally (Mace Group, Inc.)
+08b4  Sorenson Vision, Inc.
+08b8  J. Gordon Electronic Design, Inc.
+	01f4  USBSIMM1
+08b9  RadioShack Corp. (Tandy)
+08bb  Texas Instruments Japan
+	2702  Speakers
+	2900  PCM2900 Audio Codec
+	2904  PCM2904 Audio Codec
+08bd  Citizen Watch Co., Ltd
+	1100  X1-USB Floppy
+08c3  Precise Biometrics
+	0001  100 SC
+	0002  100 A
+	0003  100 SC BioKeyboard
+	0006  100 A BioKeyboard
+	0100  100 MC ISP
+	0101  100 MC FingerPrint and SmartCard Reader
+	0300  100 AX
+	0400  100 SC
+	0401  150 MC
+	0402  200 MC FingerPrint and SmartCard Reader
+	0404  100 SC Upgrade
+	0405  150 MC Upgrade
+	0406  100 MC Upgrade
+08c4  Proxim, Inc.
+	02f2  Farallon Home Phoneline Adapter
+08c7  Key Nice Enterprise Co., Ltd
+08c8  2Wire, Inc.
+08c9  Nippon Telegraph and Telephone Corp.
+08ca  Aiptek International, Inc.
+	0010  Tablet
+	0020  APT-6000U Tablet
+	0021  APT-2 Tablet
+	0022  Tablet
+	0023  Tablet
+	0024  Tablet
+	0100  Pen Drive
+	0102  DualCam
+	0103  Pocket DV Digital Camera
+	0104  Pocket DVII
+	0105  Mega DV(Disk)
+	0106  Pocket DV3100+
+	0107  Pocket DV 3100
+	0109  Nisis DV4 Digital Camera
+	010a  Trust 738AV LCD PV Mass Storage
+	0111  PenCam VGA Plus
+	2008  Mini PenCam 2
+	2010  Pocket CAM 3 Mega (webcam)
+	2011  Pocket CAM 3 Mega (storage)
+	2018  Pencam SD 2
+	2024  Pocket DV3500
+	2042  DV 5100M Composite Device
+	2043  DV 5100M(Disk)
+08cd  Jue Hsun Ind. Corp.
+08ce  Long Well Electronics Corp.
+08cf  Productivity Enhancement Products
+08d1  smartBridges, Inc.
+	0001  smartNIC Ethernet [catc]
+	0003  smartNIC 2 PnP Ethernet
+08d3  Virtual Ink
+08d4  Fujitsu Siemens Computers
+	0009  SCR SmartCard Reader
+08d9  Increment P Corp.
+08dd  Billionton Systems, Inc.
+	0112  Wireless LAN Adapter
+	0113  Wireless LAN Adapter
+	0986  USB-100N Ethernet [pegasus]
+	0987  USBLP-100 HomePNA Ethernet [pegasus]
+	0988  USBEL-100 Ethernet [pegasus]
+	1986  10/100 LAN Adapter
+	2103  DVB-T TV-Tuner Card-R
+	8511  USBE-100 Ethernet [pegasus2]
+	90ff  USB2AR Ethernet
+08de  ???
+	7a01  802.11b Adapter
+08df  Spyrus, Inc.
+	0001  Rosetta Token V1
+	0002  Rosetta Token V2
+	0003  Rosetta Token V3
+	0a00  Lynks Interface
+08e3  Olitec, Inc.
+	0002  USB-RS232 Bridge
+	0100  Interface ADSL
+	0101  Interface ADSL
+	0102  ADSL
+	0301  RNIS
+08e4  Pioneer Corp.
+08e5  Litronic
+08e6  Gemplus
+	0001  GemPC-Touch 430
+	0430  GemPC430 SmartCard Reader
+	0432  GemPC432 SmartCard Reader
+	0435  GemPC435 SmartCard Reader
+	0437  GemPC433 SL SmartCard Reader
+	1359  UA SECURE STORAGE TOKEN
+	2202  Gem e-Seal Pro Token
+	3437  GemPC Twin SmartCard Reader
+	3438  GemPC Key SmartCard Reader
+	3478  PinPad Smart Card Reader
+	4433  GemPC433-Swap
+	5501  GemProx-PU Contactless Smart Card Reader
+	ace0  UA HYBRID TOKEN
+08e7  Pan-International Wire & Cable
+08e8  Integrated Memory Logic
+08e9  Extended Systems, Inc.
+	0100  XTNDAccess IrDA Dongle
+08ea  Ericsson, Inc., Blue Ridge Labs
+	00c9  ADSL Modem HM120dp Loader
+	00ca  ADSL WAN Modem HM120dp
+	00ce  HM230d Virtual Bus for Helium
+	abba  USB Driver for Bluetooth Wireless Technology
+	abbb  Bluetooth Device in DFU State
+08ec  M-Systems Flash Disk Pioneers
+	0001  TravelDrive 2C
+	0002  TravelDrive 2C
+	0005  TravelDrive 2C
+	0008  TravelDrive 2C
+	0010  DiskOnKey
+	0011  DiskOnKey
+	0012  TravelDrive 2C
+	0014  TravelDrive 2C
+	0015  Kingston DataTraveler ELITE
+	0016  Kingston DataTraveler U3
+	0020  TravelDrive
+	0021  TravelDrive
+	0022  TravelDrive
+	0023  TravelDrive
+	0024  TravelDrive
+	0025  TravelDrive
+	0026  TravelDrive
+	0027  TravelDrive
+	0028  TravelDrive
+	0029  TravelDrive
+	0030  TravelDrive
+	0822  TravelDrive 2C
+	0832  Hi-Speed Mass Storage Device
+	0998  Kingston Data Traveler2.0 Disk Driver
+	0999  Kingston Data Traveler2.0 Disk Driver
+	1000  TravelDrive 2C
+	2000  TravelDrive 2C
+	2038  TravelDrive
+	2039  TravelDrive
+	204a  TravelDrive
+	204b  TravelDrive
+08ee  CCSI/Hesso
+08f0  Corex Technologies
+08f1  CTI Electronics Corp.
+08f5  SysTec Co., Ltd
+08f6  Logic 3 International, Ltd
+08f7  Vernier
+	0001  LabPro
+	0002  EasyTemp
+08f8  Keen Top International Enterprise Co., Ltd
+08f9  Wipro Technologies
+08fa  Caere
+08fb  Socket Communications
+08fc  Sicon Cable Technology Co., Ltd
+08fd  Digianswer A/S
+	0001  Bluetooth Device
+08ff  AuthenTec, Inc.
+	1600  AES1600
+	1610  AES1600
+	2500  AES2501
+	2501  AES2501
+	2502  AES2501
+	2503  AES2501
+	2504  AES2501
+	2505  AES2501
+	2506  AES2501
+	2507  AES2501
+	2508  AES2501
+	2509  AES2501
+	250a  AES2501
+	250b  AES2501
+	250c  AES2501
+	250d  AES2501
+	250e  AES2501
+	250f  AES2501
+	2510  AES2510
+	2580  AES2501 Fingerprint Sensor
+	2588  AES2501
+	2589  AES2501
+	258a  AES2501
+	258b  AES2501
+	258c  AES2501
+	258d  AES2501
+	258e  AES2501
+	258f  AES2501
+	3400  AES3400 TruePrint Sensor
+	3401  AES3400 Sensor
+	3402  AES3400 Sensor
+	3403  AES3400 Sensor
+	3404  AES3400 TruePrint Sensor
+	3405  AES3400 TruePrint Sensor
+	3406  AES3400 TruePrint Sensor
+	3407  AES3400 TruePrint Sensor
+	4902  BioMV with TruePrint AES3500
+	4903  BioMV with TruePrint AES3400
+	5500  AES4000
+	5501  AES4000 TruePrint Sensor
+	5503  AES4000 TruePrint Sensor
+	5505  AES4000 TruePrint Sensor
+	5507  AES4000 TruePrint Sensor
+	55ff  AES4000 TruePrint Sensor.
+	5700  AES3500 Fingerprint Reader
+	5701  AES3500 TruePrint Sensor
+	5702  AES3500 TruePrint Sensor
+	5703  AES3500 TruePrint Sensor
+	5704  AES3500-BZ TruePrint Sensor
+	5705  AES3500-BZ TruePrint Sensor
+	5706  AES3500-BZ TruePrint Sensor
+	5707  AES3500-BZ TruePrint Sensor
+	5710  AES3500 TruePrint Sensor
+	5711  AES3500 TruePrint Sensor
+	5712  AES3500 TruePrint Sensor
+	5713  AES3500 TruePrint Sensor
+	5714  AES3500-BZ TruePrint Sensor
+	5715  AES3500-BZ TruePrint Sensor
+	5716  AES3500-BZ TruePrint Sensor
+	5717  AES3500-BZ TruePrint Sensor
+	5730  AES3500 TruePrint Sensor
+	5731  AES3500 TruePrint Sensor
+	5732  AES3500 TruePrint Sensor
+	5733  AES3500 TruePrint Sensor
+	5734  AES3500-BZ TruePrint Sensor
+	5735  AES3500-BZ TruePrint Sensor
+	5736  AES3500-BZ TruePrint Sensor
+	5737  AES3500-BZ TruePrint Sensor
+	afe3  FingerLoc Sensor Module (Anchor)
+	afe4  FingerLoc Sensor Module (Anchor)
+	afe5  FingerLoc Sensor Module (Anchor)
+	afe6  FingerLoc Sensor Module (Anchor)
+	fffd  AES2510 Sensor (USB Emulator)
+	ffff  Sensor (Emulator)
+0900  Pinnacle Systems, Inc.
+0901  VST Technologies
+	0001  Hard Drive Adapter (TPP)
+	0002  SigmaDrive Adapter (TPP)
+0906  Faraday Technology Corp.
+0909  Audio-Technica Corp.
+090a  Trumpion Microelectronics, Inc.
+	1001  T33520 USB Flash Card Controller
+	1100  Comotron C3310 MP3 player
+	1200  MP3 player
+	1540  Digitex Container Flash Disk
+090b  Neurosmith
+090c  Feiya Technology Corp.
+	1000  Memory Bar
+	1132  5-in-1 Card Reader
+090d  Multiport Computer Vertriebs GmbH
+090e  Shining Technology, Inc.
+090f  Fujitsu Devices, Inc.
+0910  Alation Systems, Inc.
+0911  Philips Speech Processing
+	2512  SpeechMike Pro
+0912  Voquette, Inc.
+0915  GlobeSpan, Inc.
+	0001  DSL Modem
+	0002  ADSL ATM Modem
+	0005  LAN Modem
+	2000  802.11 Adapter
+	2002  802.11 Adapter
+	8000  ADSL LAN Modem
+	8005  DSL-302G Modem
+	8101  ADSL WAN Modem
+	8102  DSL-200 ADSL Modem
+	8103  DSL-200 ADSL Modem
+	8104  DSL-200 Modem
+	8400  DSL Modem
+	8401  DSL Modem
+	8402  DSL Modem
+	8500  DSL Modem
+	8501  DSL Modem
+0917  SmartDisk Corp.
+	0001  eFilm Reader-11 SM/CF
+	0002  eFilm Reader-11 SM
+	0003  eFilm Reader-11 CF
+	0200  FireFly
+	0201  FireLite
+	0202  STORAGE ADAPTER (FirePower)
+	0204  FlashTrax Storage
+	0205  STORAGE ADAPTER (CrossFire)
+	0206  FireFly 20G HDD
+	0207  FireLite
+	020f  STORAGE ADAPTER (FireLite)
+	da01  eFilm Reader-11 Test
+	ffff  eFilm Reader-11 (Class/PDR)
+0919  Tiger Electronics
+	0100  Fast Flicks Digital Camera
+091e  Garmin International
+	0003  GPSmap (various models)
+	0004  Garmin iQue 3600
+	0200  Data Card Programmer (install)
+	1200  Data Card Programmer
+0920  Echelon Co.
+	7500  Network Interface
+0921  GoHubs, Inc.
+	1001  GoCOM232 Serial
+0922  Dymo-CoStar Corp.
+	0007  LabelWriter 330
+	0009  LabelWriter 310
+0923  IC Media Corp.
+	010f  SIIG MobileCam
+0924  Xerox
+	23dd  DocuPrint M760 (X760_USB)
+	3d5b  Phaser 6115MFP TWAIN Scanner
+	420f  WorkCentre PE220 Series
+	421f  M20 Scanner
+	423b  Printing Support
+	ffef  WorkCenter M15
+	fffb  DocuPrint M750 (X750_USB)
+0925  Lakeview Research
+	8101  Phidgets, Inc., 1-Motor PhidgetServo v2.0
+	8104  Phidgets, Inc., 4-Motor PhidgetServo v2.0
+	8800  WiseGroup Ltd, MP-8800 Quad Joypad
+	8866  WiseGroup Ltd, MP-8866 Dual Joypad
+0927  Summus, Ltd
+0928  Oxford Semiconductor, Ltd
+0929  American Biometric Co.
+092a  Toshiba Information & Industrial Sys. And Services
+092b  Sena Technologies, Inc.
+092f  Northern Embedded Science/CAVNEX
+	0004  JTAG-4
+	0005  JTAG-5
+0930  Toshiba Corp.
+	0009  Gigabeat F/X (HDD audio player)
+	000c  Gigabeat F (mtp)
+	0010  Gigabeat S (mtp)
+	0301  PCX1100U Cable Modem (WDM)
+	0302  PCX2000 Cable Modem (WDM)
+	0305  Cable Modem PCX3000
+	0307  Cable Modem PCX2500
+	0308  PCX2200 Cable Modem (WDM)
+	0309  PCX5000 Cable Modem (WDM)
+	030b  Cable Modem PCX2600
+	0501  Bluetooth Controller
+	0502  Integrated Bluetooth
+	0503  Bluetooth Controller
+	0505  Integrated Bluetooth
+	0506  Integrated Bluetooth
+	0507  Bluetooth Adapter
+	0508  Integrated Bluetooth HCI
+	0509  BT EDR Dongle
+	0706  PocketPC e740
+	0707  Pocket PC e330 Series
+	0708  Pocket PC e350 Series
+	0709  Pocket PC e750 Series
+	070a  Pocket PC e400 Series
+	070b  Pocket PC e800 Series
+	1300  Wireless Broadband (CDMA EV-DO) SM-Bus Minicard Status Port
+	1301  Wireless Broadband (CDMA EV-DO) Minicard Status Port
+	1302  Wireless Broadband (3G HSDPA) SM-Bus Minicard Status Port
+	1303  Wireless Broadband (3G HSDPA) Minicard Status Port
+	1308  Broadband (3G HSDPA) SM-Bus Minicard Diagnostics Port
+	642f  TravelDrive
+	6506  TravelDrive 2C
+	6507  TravelDrive 2C
+	6508  TravelDrive 2C
+	6509  TravelDrive 2C
+	6510  TravelDrive 2C
+	6517  TravelDrive 2C
+	6518  TravelDrive 2C
+	6519  Kingston DataTraveler 2.0 USB Stick
+	651a  TravelDrive 2C
+	651b  TravelDrive 2C
+	651c  TravelDrive 2C
+	651d  TravelDrive 2C
+	651e  TravelDrive 2C
+	651f  TravelDrive 2C
+	6520  TravelDrive 2C
+	6521  TravelDrive 2C
+	6522  TravelDrive 2C
+	6523  TravelDrive
+	6524  TravelDrive
+	6525  TravelDrive
+	6526  TravelDrive
+	6527  TravelDrive
+	6528  TravelDrive
+	6529  TravelDrive
+	652a  TravelDrive
+	652b  TravelDrive
+	652c  TravelDrive
+	652d  TravelDrive
+	652f  TravelDrive
+	6530  TravelDrive
+	6531  TravelDrive
+	6532  256M USB Stick
+	6533  512M USB Stick
+	6534  TravelDrive
+	653c  Kingston DataTraveler 2.0 USB Stick (512M)
+	653d  Kingston DataTraveler 2.0 USB Stick (1GB)
+	653e  USB Flash Memory
+	6540  TransMemory USB Flash Memory
+0931  Harmonic Data Systems, Ltd
+0932  Crescentec Corp.
+	0300  VideoAdvantage
+	0302  Syntek DC-112X
+	0320  VideoAdvantage
+	1100  Video Enhamcement Device
+	1112  Veo Web Camera
+	a311  Video Enhancement Device
+0933  Quantum Corp.
+0934  Netcom Systems
+0939  Lumberg, Inc.
+093a  Pixart Imaging, Inc.
+	0007  CMOS 100K-R Rev. 1.90
+	010e  Digital camera, CD302N/Elta Medi@ digi-cam/HE-501A
+	010f  Argus DC-1610/DC-1620/Emprex PCD3600/Philips P44417B keychain camera/Precision Mini,Model HA513A/Vivitar Vivicam 55
+	2460  Q-TEC WEBCAM 100
+	2468  Cammaestro 2.5DU/X-EYE/Orite SC-120/ICGear TravelCam/Easy Snap Snake Eye WebCam
+	2470  SoC PC-Camera
+	2471  SoC PC-Camera
+	2500  USB Optical Mouse
+	2600  Typhoon Easycam USB 330K (newer)/Typhoon Easycam USB 2.0 VGA 1.3M/Sansun SN-508
+	2601  SPC 610NC Laptop Camera
+093b  Plextor Corp.
+	0010  Storage Adapter
+	0011  PlexWriter 40/12/40U
+	0042  PX-712UF DVD RW
+	a002  ConvertX M402U XLOADER
+	a003  ConvertX AV100U A/V Capture Audio
+	a004  ConvertX TV402U XLOADER
+	a005  KWorld EMP Audio Device
+	a102  ConvertX M402U A/V Capture
+	a104  ConvertX PX-TV402U/NA
+093c  Intrepid Control Systems, Inc.
+	0601  ValueCAN
+	0701  NeoVI Blue vehicle bus interface
+093d  InnoSync, Inc.
+093e  J.S.T. Mfg. Co., Ltd
+093f  Olympia Telecom Vertriebs GmbH
+0940  Japan Storage Battery Co., Ltd
+0941  Photobit Corp.
+0942  i2Go.com, LLC
+0943  HCL Technologies India Private, Ltd
+0944  KORG, Inc.
+0945  Pasco Scientific
+0948  Kronauer music in digital
+	0301  USB Pro (24/48)
+	0302  USB Pro (24/96 playback)
+	0303  USB Pro (24/96 record)
+	0304  USB Pro (16/48)
+	1105  USB One
+094b  Linkup Systems Corp.
+094d  Cable Television Laboratories
+094f  Yano
+	0101  U640MO-03
+	05fc  METALWEAR-HDD
+0951  Kingston Technology
+	0008  Ethernet
+	000a  KNU101TX 100baseTX Ethernet
+	1600  Data Traveler II Pen Drive
+	1601  Data Traveler II+ Pen Drive
+	1602  Data Traveler Mini
+	1603  Data Traveler 1GB/2GB Pen Drive
+0954  RPM Systems Corp.
+0955  NVidia Corp.
+0956  BSquare Corp.
+0957  Agilent Technologies, Inc.
+	0200  E-Video DC-350 Camera
+	0202  E-Video DC-350 Camera
+0958  CompuLink Research, Inc.
+0959  Cologne Chip AG
+	2bd0  Intelligent ISDN (Ver. 3.60.04)
+095a  Portsmith
+	3003  Express Ethernet
+095b  Medialogic Corp.
+095c  K-Tec Electronics
+095d  Polycom, Inc.
+	0001  Polycom ViaVideo
+0967  Acer (??)
+	0204  WarpLink 802.11b Adapter
+0968  Catalyst Enterprises, Inc.
+096e  Feitian Technologies, Inc.
+	0802  ePass2000 (G&D STARCOS SPK 2.4)
+0971  Gretag-Macbeth AG
+0973  Schlumberger
+	0001  e-gate Smart Card
+0974  Datagraphix, a business unit of Anacomp
+0975  OL'E Communications, Inc.
+0976  Adirondack Wire & Cable
+0977  Lightsurf Technologies
+0978  Beckhoff GmbH
+0979  Jeilin Technology Corp., Ltd
+	0224  JL2005A Toy Camera
+	0226  JL2005A Toy Camera
+097a  Minds At Work LLC
+	0001  Digital Wallet
+097b  Knudsen Engineering, Ltd
+097c  Marunix Co., Ltd
+097d  Rosun Technologies, Inc.
+097f  Barun Electronics Co., Ltd
+0981  Oak Technology, Ltd
+0984  Apricorn
+	0200  Hard Drive Storage (TPP)
+0985  cab Produkttechnik GmbH & Co KG
+	00a3  A3/200 or A3/300 Label Printer
+0986  Matsushita Electric Works, Ltd.
+098c  Vitana Corp.
+098d  INDesign
+098e  Integrated Intellectual Property, Inc.
+098f  Kenwood TMI Corp.
+0993  Gemstar eBook Group, Ltd
+	0001  REB1100 eBook Reader
+	0002  eBook
+0996  Integrated Telecom Express, Inc.
+099a  Zippy Technology Corp.
+	610c  EL-610 Super Mini Electron luminescent Keyboard
+09a3  PairGain Technologies
+09a4  Contech Research, Inc.
+09a5  VCON Telecommunications
+09a6  Poinchips
+	8001  Mass Storage Device
+09a7  Data Transmission Network Corp.
+09a8  Lin Shiung Enterprise Co., Ltd
+09a9  Smart Card Technologies Co., Ltd
+09aa  Intersil Corp.
+	1000  Prism GT 802.11b/g Adapter
+	3642  Prism 2.x 802.11b Adapter
+09ab  Japan Cash Machine Co., Ltd.
+09ae  Tripp Lite
+09b2  Franklin Electronic Publishers, Inc.
+	0001  eBookman Palm Computer
+09b3  Altius Solutions, Inc.
+09b4  MDS Telephone Systems
+09b5  Celltrix Technology Co., Ltd
+09bc  Grundig
+	0002  MPaxx MP150 MP3 Player
+09be  MySmart.Com
+	0001  MySmartPad
+09bf  Auerswald GmbH & Co. KG
+	00c0  COMpact 2104 ISDN PBX
+	00db  COMpact 4410/2206 ISDN ISDN
+	00f1  COMfort System Telephones
+09c1  Arris Interactive LLC
+	1337  TOUCHSTONE DEVICE
+09c2  Nisca Corp.
+09c3  ActivCard, Inc.
+	0007  Reader V2
+	0008  SmartCard Reader
+09c4  ACTiSYS Corp.
+	0011  ACT-IR2000U IrDA Dongle
+09c5  Memory Corp.
+09cc  Workbit Corp.
+	0404  BAFO USB-ATA/ATAPI Bridge Controller
+09cd  Psion Dacom Home Networks, Ltd
+09ce  City Electronics, Ltd
+09cf  Electronics Testing Center, Taiwan
+09d1  NeoMagic, Inc.
+09d2  Vreelin Engineering, Inc.
+09d3  Com One
+	0001  ISDN TA
+09d7  Novatel Wireless
+	0100  NovAtel FlexPack GPS receiver
+09d9  KRF Tech, Ltd
+09da  A4 Tech Co., Ltd
+	0006  Optical Mouse WOP-35 / Trust 450L Optical Mouse
+	000a  Port Mouse
+	0018  Trust Human Interface Device
+	001a  Wireless Mouse & RXM-15 Receiver
+	002a  Wireless Optical Mouse NB-30
+09db  Measurement Computing Corp.
+	0075  MiniLab 1008
+	0076  PMD-1024
+	007a  PMD-1208LS
+	0081  USB-1616FS
+	0088  USB-1616FS internal hub
+09dc  Aimex Corp.
+09dd  Fellowes, Inc.
+09df  Addonics Technologies Corp.
+09e1  Intellon Corp.
+	5121  MicroLink dLAN
+09e5  Jo-Dan International, Inc.
+09e6  Silutia, Inc.
+09e7  Real 3D, Inc.
+09e8  AKAI  Professional M.I. Corp.
+09e9  Chen-Source, Inc.
+09eb  IM Networks, Inc.
+	4331  iRhythm Tuner Remote
+09ef  Xitel
+	0101  MD-Port DG2 MiniDisc Interface
+09f5  AresCom
+	0168  Network Adapter
+	0188  LAN Adapter
+	0850  Adapter
+09f6  RocketChips, Inc.
+09f7  Edu-Science (H.K.), Ltd
+09f8  SoftConnex Technologies, Inc.
+09f9  Bay Associates
+09fa  Mtek Vision
+09fb  Altera
+09ff  Gain Technology Corp.
+0a00  Liquid Audio
+0a01  ViA, Inc.
+0a07  Ontrak Control Systems Inc.
+	0064  ADU100 Data Acquisition Interface
+	00c8  ADU200 Relay I/O Interface
+	00d0  ADU208 Data Acquisition Interface
+0a0b  Cybex Computer Products Co.
+0a11  Xentec, Inc.
+0a12  Cambridge Silicon Radio, Ltd
+	0001  Bluetooth Dongle (HCI mode)
+	0002  Frontline Test Equipment Bluetooth Device
+	0003  Nanosira
+	0004  Nanosira WHQL Reference Radio
+	0005  Nanosira-Multimedia
+	0006  Nanosira-Multimedia WHQL Reference Radio
+	0007  Nanosira3-ROM
+	0008  Nanosira3-ROM
+	0009  Nanosira4-EDR WHQL Reference Radio
+	000a  Nanosira4-EDR-ROM
+	000b  Nanosira5-ROM
+	0043  Bluetooth Device
+	0100  Casira with BlueCore2-External Module
+	0101  Casira with BlueCore2-Flash Module
+	0102  Casira with BlueCore3-Multimedia Module
+	0103  Casira with BlueCore3-Flash Module
+	0104  Casira with BlueCore4-External Module
+	0105  Casira with BlueCore4-Multimedia Module
+	1000  Bluetooth Dongle (HID proxy mode)
+	1010  Bluetooth Device
+	1011  Bluetooth Device
+	1012  Bluetooth Device
+	ffff  USB Bluetooth Device in DFU State
+0a13  Telebyte, Inc.
+0a14  Spacelabs Medical, Inc.
+0a15  Scalar Corp.
+0a16  Trek Technology (S) PTE, Ltd
+	1111  ThumbDrive
+	8888  IBM USB Memory Key
+	9988  Trek2000 TD-G2
+0a17  Pentax Corp.
+	0004  Pentax Optio 330
+	0006  Pentax Optio S
+	0007  Pentax Optio 550
+	0009  Pentax Optio 33WR
+	000a  Pentax Optio 555
+	000c  Pentax Optio 43WR (mass storage mode)
+	000d  Pentax Optio 43WR
+	0015  Pentax Optio S40/S5i
+	003b  Pentax Optio 50 (mass storage mode)
+	003d  Pentax Optio S55
+	0043  Pentax *ist DL
+	0047  Pentax Optio S60
+	0052  Optio 60 Digital Camera
+	006e  Pentax K10D
+	0070  Pentax K100D
+	1001  EI2000 Camera powered by Digita!
+0a18  Heidelberger Druckmaschinen AG
+0a19  Hua Geng Technologies, Inc.
+0a21  Medtronic Physio Control Corp.
+0a22  Century Semiconductor USA, Inc.
+0a2c  AK-Modul-Bus Computer GmbH
+	0008  GPIO Ports
+0a34  TG3 Electronics, Inc.
+	0110  Deck 82-key backlit keyboard
+0a39  Gilat Satellite Networks, Ltd
+0a3a  PentaMedia Co., Ltd
+	0163  KN-W510U 1.0 Wireless LAN Adapter
+0a3c  NTT DoCoMo, Inc.
+0a3d  Varo Vision
+0a3f  Swissonic AG
+0a43  Boca Systems, Inc.
+0a46  Davicom Semiconductor, Inc.
+	0268  ST268
+	9601  DM9601 To Fast Ethernet Adapter
+0a47  Hirose Electric
+0a48  I/O Interconnect
+	3233  Multimedia Card Reader
+	3239  Multimedia Card Reader
+	3258  Dane Elec zMate SD Reader
+	3259  Dane Elec zMate CF Reader
+	5000  MediaGear xD-SM
+	500a  Mass Storage Device
+	500f  Mass Storage Device
+	5010  Mass Storage Device
+	5011  Mass Storage Device
+	5014  Mass Storage Device
+	5020  Mass Storage Device
+	5021  Mass Storage Device
+	5022  Mass Storage Device
+	5023  Mass Storage Device
+	5024  Mass Storage Device
+	5025  Mass Storage Device
+0a4b  Fujitsu Media Devices, Ltd
+0a4c  Computex Co., Ltd
+0a4d  Evolution Electronics, Ltd
+	0064  MK-225 Driver
+	0065  MK-225C Driver
+	0066  MK-225C Driver
+	0067  MK-425C Driver
+	0078  MK-37 Driver
+	0079  MK-37C Driver
+	007a  MK-37C Driver
+	008c  TerraTec MIDI MASTER
+	008d  MK-249C Driver
+	008e  MK-249C MIDI Keyboard
+	008f  MK-449C Driver
+	0090  Keystation 49e Driver
+	0091  Keystation 61es Driver
+	00a0  MK-361 Driver
+	00a1  MK-361C Driver
+	00a2  MK-361C Driver
+	00a3  MK-461C MIDI Keyboard
+	00b5  Keystation Pro 88 Driver
+	00d2  E-Keys Driver
+	00f0  UC-16 Driver
+	00f1  X-Session Driver
+	00f5  UC-33e MIDI Controller
+0a4e  Steinberg Soft-und Hardware GmbH
+0a4f  Litton Systems, Inc.
+0a50  Mimaki Engineering Co., Ltd
+0a51  Sony Electronics, Inc.
+0a52  Jebsee Electronics Co., Ltd
+0a53  Portable Peripheral Co., Ltd
+	1000  Scanner
+	2000  Q-Scan A6 Scanner
+	2001  Q-Scan A6 Scanner
+	2013  Media Drive A6 Scanner
+	2014  Media Drive A6 Scanner
+	2015  BizCardReader 600C
+	2016  BizCardReader 600C
+	202a  Scanshell-CSSN
+	3000  Q-Scan A8 Scanner
+	3002  Q-Scan A8 Reader
+	3015  BizCardReader 300G
+	5001  BizCardReader 900C
+0a5a  Electronics For Imaging, Inc.
+0a5b  EAsics NV
+0a5c  Broadcom Corp.
+	0201  iLine10(tm) Network Adapter
+	2000  Bluetooth Device
+	2009  Bluetooth Controller
+	200a  Bluetooth dongle
+	200f  Bluetooth Controller
+	201d  Bluetooth Device
+	201e  IBM Integrated Bluetooth IV
+	2020  Bluetooth Dongle
+	2033  BCM2033 Bluetooth
+	2035  BCM2035 Bluetooth
+	2038  Blutonium Device
+	2039  Bluetooth Device
+	2045  Bluetooth Controller
+	2046  Bluetooth Device
+	2047  Bluetooth Device
+	205e  Bluetooth Device
+	2100  Bluetooth 2.0+eDR dongle
+	2101  A-Link BlueUsbA2 Bluetooth
+	2102  ANYCOM Blue USB-200/250
+	2110  Bluetooth Controller
+	2111  ANYCOM Blue USB-UHE 200/250
+	2120  2045 Bluetooth 2.0 USB-UHE Device with trace filter
+	2121  BCM2210 Bluetooth
+	2122  Bluetooth 2.0+EDR dongle
+	2130  2045 Bluetooth 2.0 USB-UHE Device with trace filter
+	2131  2045 Bluetooth 2.0 Device with trace filter
+	6300  Pirelli Remote NDIS Device
+0a5d  Diatrend Corp.
+0a5f  Zebra
+	0009  LP2844 Printer
+	930a  Printer
+0a62  MPMan
+	0010  MPMan MP-F40 MP3 Player
+0a66  ClearCube Technology
+0a67  Medeli Electronics Co., Ltd
+0a68  Comaide Corp.
+0a69  Chroma ate, Inc.
+0a6b  Green House Co., Ltd
+	0001  Compact Flash R/W with MP3 player
+0a6c  Integrated Circuit Systems, Inc.
+0a6d  UPS Manufacturing
+0a6e  Benwin
+0a6f  Core Technology, Inc.
+	0400  Xanboo
+0a70  International Game Technology
+0a72  Sanwa Denshi
+0a7d  NSTL, Inc.
+0a7e  Octagon Systems Corp.
+0a80  Rexon Technology Corp., Ltd
+0a81  Chesen Electronics Corp.
+	0101  Keyboard
+	0103  Keyboard
+	0203  Mouse
+	0205  PS/2 Keyboard+Mouse Adapter
+0a82  Syscan
+	4600  TravelScan 460/464
+0a83  NextComm, Inc.
+0a84  Maui Innovative Peripherals
+0a85  Idexx Labs
+0a86  NITGen Co., Ltd
+0a8d  Picturetel
+0a8e  Japan Aviation Electronics Industry, Ltd
+	2011  Filter Driver For JAE XMC R/W
+0a90  Candy Technology Co., Ltd
+0a91  Globlink Technology, Inc.
+	3801  Targus PAKP003 Mouse
+0a92  EGO SYStems, Inc.
+	0011  SYS WaveTerminal U2A
+	0021  GIGAPort
+	0031  GIGAPortAG
+	0053  AudioTrak Optoplay
+	0061  Waveterminal U24
+	0071  MAYA EX7
+	0091  Maya 44
+	00b1  MAYA EX5
+	1000  MIDI Mate
+	1010  RoMI/O
+	1020  M4U
+	1030  M8U
+	1090  KeyControl49
+	10a0  KeyControl25
+0a93  C Technologies AB
+	0002  C-Pen 10
+	0005  MyPen Light
+	000d  Input Pen
+	0010  C-Pen 20
+0a94  Intersense
+0aa3  Lava Computer Mfg., Inc.
+0aa4  Develco Elektronik
+0aa5  First International Digital
+	0002  irock! 500 Series
+	0801  MP3 Player
+0aa6  Perception Digital, Ltd
+	0101  Hercules Jukebox
+	1501  Store 'n' Go HD Drive
+0aa7  Wincor Nixdorf International GmbH
+	0100  POS Keyboard, TA58P-USB
+	0101  POS Keyboard, TA85P-USB
+	0102  POS Keyboard, TA59-USB
+	0103  POS Keyboard, TA60-USB
+	0104  SNIkey Keyboard, SNIKey-KB-USB
+	0200  Operator Display, BA63-USB
+	0201  Operator Display, BA66-USB
+	0202  Operator Display & Scanner, XiCheck-BA63
+	0203  Operator Display & Scanner, XiCheck-BA66
+	0204  Graphics Operator Display, BA63GV
+	0300  POS Printer (printer class mode), TH210
+	0301  POS Printer (native mode), TH210
+	0302  POS Printer (printer class mode), TH220
+	0303  POS Printer (native mode), TH220
+	0304  POS Printer, TH230
+	0305  Lottery Printer, XiPrintPlus
+	0306  POS Printer (printer class mode), TH320
+	0307  POS Printer (native mode), TH320
+	0308  POS Printer (printer class mode), TH420
+	0309  POS Printer (native mode), TH420
+	030a  POS Printer, TH200B
+	0400  Lottery Scanner, Xiscan S
+	0401  Lottery Scanner, Xiscan 3
+	4304  Banking Printer TP07
+0aa8  TriGem Computer, Inc.
+	0060  TG 11Mbps WLAN Mini Adapter
+	1001  DreamComboM4100
+	3002  InkJet Color Printer
+	8001  TG_iMON
+	8002  TG_KLOSS
+	a001  TG_X2
+	a002  TGVFD_KLOSS
+	ffda  iMON_VFD
+0aa9  Baromtec Co.
+	f01b  Medion MD 6242 MP3 Player
+0aaa  Japan CBM Corp.
+0aab  Vision Shape Europe SA
+0aac  iCompression, Inc.
+0aad  Rohde & Schwarz GmbH & Co. KG
+0aae  NEC infrontia Corp. (Nitsuko)
+0aaf  Digitalway Co., Ltd
+0ab0  Arrow Strong Electronics Co., Ltd
+0aba  Ellisys
+	8001  USB Tracker 110 Protocol Analyzer
+0abe  Stereo-Link
+	0101  SL1200 DAC
+0ac3  Sanyo Semiconductor Company Micro
+0ac4  Leco Corp.
+0ac5  I & C Corp.
+0ac6  Singing Electrons, Inc.
+0ac7  Panwest Corp.
+0ac8  Z-Star Microelectronics Corp.
+	0301  Web Camera
+	0302  ZC0302 WebCam
+	0321  USB 2.0 Webcam
+	0323  Luxya WC-1200 USB 2.0 Webcam
+	301b  ZC0301 WebCam
+	303b  ZC0303 WebCam
+	305b  ZC0305 WebCam
+	307b  USB 1.1 WebCam
+	c002  Visual Communication Camera VGP-VCC1
+0ac9  Micro Solutions, Inc.
+	0000  Backpack CD-ReWriter
+	0001  BACKPACK  2 Cable
+	0010  BACKPACK
+	0011  Backpack 40GB Hard Drive
+	0110  BACKPACK
+	0111  BackPack
+	1234  BACKPACK
+0aca  OPEN Networks Ltd
+	1060  OPEN NT1 Plus II
+0acc  Koga Electronics Co.
+0acd  ID Tech
+	0401  ID TECH Spectrum III Hybrid Smartcard Reader
+0ace  ZyDAS
+	1201  802.11b WiFi
+	1211  802.11b/g USB2 WiFi
+	1215  WLA-54L WiFi
+	1608  ONMI FAXMODEM 56K UNO (ZyXEL)
+0acf  Intoto, Inc.
+0ad0  Intellix Corp.
+0ad1  Remotec Technology, Ltd
+0ad2  Service & Quality Technology Co., Ltd
+0ae3  Allion Computer, Inc.
+0ae4  Taito Corp.
+0ae7  Neodym Systems, Inc.
+0ae8  System Support Co., Ltd
+0ae9  North Shore Circuit Design L.L.P.
+0aea  SciEssence, LLC
+0aeb  TTP Communications, Ltd
+0aec  Neodio Technologies Corp.
+	2101  SmartMedia Card Reader
+	2102  CompactFlash Card Reader
+	2103  MMC/SD Card Reader
+	2104  MemoryStick Card Reader
+	2201  SmartMedia+CompactFlash Card Reader
+	2202  SmartMedia+MMC/SD Card Reader
+	2203  SmartMedia+MemoryStick Card Reader
+	2204  CompactFlash+MMC/SD Card Reader
+	2205  CompactFlash+MemoryStick Card Reader
+	2206  MMC/SD+MemoryStick Card Reader
+	2301  SmartMedia+CompactFlash+MMC/SD Card Reader
+	2302  SmartMedia+CompactFlash+MemoryStick Card Reader
+	2303  SmartMedia+MMC/SD+MemoryStick Card Reader
+	2304  CompactFlash+MMC/SD+MemoryStick Card Reader
+	3016  MMC/SD+Memory Stick Card Reader
+	3050  ND3050 8-in-1 Card Reader
+	3060  1.1 FS Card Reader
+	3101  MMC/SD Card Reader
+	3102  MemoryStick Card Reader
+	3201  MMC/SD+MemoryStick Card Reader
+	3216  HS Card Reader
+	3260  7-in-1 Card Reader
+	5010  ND5010 Card Reader
+0af0  Option
+	5000  UMTS Card
+	6000  GlobeTrotter 3G datacard
+	6300  GT 3G Quad UMTS/GPRS Card
+	6600  GlobeTrotter 3G+ datacard
+0af6  Silver I Co., Ltd
+0af7  B2C2, Inc.
+	0101  Digital TV USB Receiver (DVB-S/T/C / ATSC)
+0af9  Hama, Inc.
+	0010  USB SightCam 100
+	0011  Micro Innovations IC50C WebCam
+0afc  Zaptronix Ltd
+0afd  Tateno Dennou, Inc.
+0afe  Cummins Engine Co.
+0aff  Jump Zone Network Products, Inc.
+0b00  INGENICO
+0b05  ASUSTek Computer, Inc.
+	1101  Mass Storage (UISDMC4S)
+	1706  WL-167G 802.11g Adapter [ralink]
+	1707  WL-167g Wireless Adapter
+	1708  Mass Storage Device
+	170b  Mass Storage Device
+	170c  WL-159g
+	170d  802.11b/g Wireless Network Adapter
+	1712  BT-183 Bluetooth 2.0+EDR adapter
+	1715  2045 Bluetooth 2.0 Device with trace filter
+	1716  Bluetooth Device
+	171b  A9T wireless
+	171c  802.11b/g Wireless Network Adapter
+	1723  WL-167G v2 802.11g Adapter [ralink]
+	1724  RT2573
+	1726  Laptop OLED Display
+	172a  ASUS 802.11n Network Adapter
+	172b  802.11n Network Adapter
+	1731  ASUS 802.11n Network Adapter
+	1732  802.11n Network Adapter
+	173c  BT-183 Bluetooth 2.0
+	1742  802.11n Network Adapter
+	6101  Cable Modem
+	620a  Remote NDIS Device
+0b0c  Todos Data System AB
+	0009  Todos Argos Mini II Smart Card Reader
+0b0e  GN Netcom
+0b0f  AVID Technology
+0b10  Pcally
+0b11  I Tech Solutions Co., Ltd
+0b1e  Electronic Warfare Assoc., Inc. (EWA)
+0b1f  Insyde Software Corp.
+0b20  TransDimension, Inc.
+0b21  Yokogawa Electric Corp.
+0b22  Japan System Development Co., Ltd
+0b23  Pan-Asia Electronics Co., Ltd
+0b24  Link Evolution Corp.
+0b27  Ritek Corp.
+0b28  Kenwood Corp.
+0b2c  Village Center, Inc.
+0b30  PNY Technologies, Inc.
+	0006  SM Media-Shuttle Card Reader
+0b33  Contour Design, Inc.
+	0020  ShuttleXpress
+0b37  Hitachi ULSI Systems Co., Ltd
+0b39  Omnidirectional Control Technology, Inc.
+	0109  USB TO Ethernet
+	0421  Serial
+	0801  USB-Parallel Bridge
+	0901  OCT To Fast Ethernet Converter
+	0c03  LAN DOCK Serial Converter
+0b3a  IPaxess
+0b3b  Tekram Technology Co., Ltd
+	0163  TL-WN320G 1.0 WLAN Adapter
+	1601  Allnet 0193 802.11b Adapter
+	1602  ZyXEL ZyAIR B200 802.11b Adapter
+	1612  AIR.Mate 2@net 802.11b Adapter
+	1613  802.11b Wireless LAN Adapter
+	1620  Allnet USB 2.0 Wireless Network Adapter
+	1630  QuickWLAN
+	5630  ZD1211
+	6630  ZD1211
+0b3c  Olivetti Techcenter
+	a010  Simple_Way Printer/Scanner/Copier
+0b3e  Kikusui Electronics Corp.
+0b41  Hal Corp.
+	0011  Crossam2+USB IR commander
+0b43  Play.com, Inc.
+	0003  PS2 Controller Converter
+0b47  Sportbug.com, Inc.
+0b48  TechnoTrend AG
+	1003  Technotrend/Hauppauge USB-Nova
+	1004  TT-PCline
+	1005  Technotrend/Hauppauge USB-Nova
+	1006  Technotrend/Hauppauge DEC3000-s
+	1007  TT-micro plus Device
+	1008  Technotrend/Hauppauge DEC2000-t
+	1009  Technotrend/Hauppauge DEC2540-t
+0b49  ASCII Corp.
+	064f  Trance Vibrator
+0b4b  Pine Corp. Ltd.
+	0100  D'music MP3 Player
+0b4d  Graphtec America, Inc.
+	110a  Graphtec CC200-20
+0b4e  Musical Electronics, Ltd
+	6500  MP3 Player
+	8028  MP3 Player
+	8920  MP3 Player
+0b50  Dumpries Co., Ltd
+0b51  Comfort Keyboard Co.
+	0020  Comfort Keyboard
+0b52  Colorado MicroDisplay, Inc.
+0b54  Sinbon Electronics Co., Ltd
+0b56  TYI Systems, Ltd
+0b57  Beijing HanwangTechnology Co., Ltd
+0b59  Lake Communications, Ltd
+0b5a  Corel Corp.
+0b5f  Green Electronics Co., Ltd
+0b60  Nsine, Ltd
+0b61  NEC Viewtechnology, Ltd
+0b62  Orange Micro, Inc.
+	000b  Bluetooth Device
+	0059  iBOT2 WebCam
+0b63  ADLink Technology, Inc.
+0b64  Wonderful Wire Cable Co., Ltd
+0b65  Expert Magnetics Corp.
+0b69  CacheVision
+0b6a  Maxim Integrated Products
+0b6f  Nagano Japan Radio Co., Ltd
+0b70  PortalPlayer, Inc.
+	00ba  iRiver H10 20GB
+0b71  SHIN-EI Sangyo Co., Ltd
+0b72  Embedded Wireless Technology Co., Ltd
+0b73  Computone Corp.
+0b75  Roland DG Corp.
+0b79  Sunrise Telecom, Inc.
+0b7a  Zeevo, Inc.
+	07d0  Bluetooth Dongle
+0b7b  Taiko Denki Co., Ltd
+0b7c  ITRAN Communications, Ltd
+0b7d  Astrodesign, Inc.
+0b84  Rextron Technology, Inc.
+0b85  Elkat Electronics, Sdn., Bhd.
+0b86  Exputer Systems, Inc.
+	5100  XMC5100 Zippy Drive
+	5110  XMC5110 Flash Drive
+	5200  XMC5200 Zippy Drive
+	5201  XMC5200 Zippy Drive
+	5202  XMC5200 Zippy Drive
+	5280  XMC5280 Storage Drive
+	fff0  ISP5200 Debugger
+0b87  Plus-One I & T, Inc.
+0b88  Sigma Koki Co., Ltd, Technology Center
+0b89  Advanced Digital Broadcast, Ltd
+0b95  ASIX Electronics Corp.
+	1720  10/100 Ethernet
+	1780  AX88178
+	7720  AX88772
+0b96  Sewon Telecom
+0b97  O2 Micro, Inc.
+	7732  Smart Card Reader
+	7761  Oz776 1.1 Hub
+	7762  Oz776 SmartCard Reader
+	7772  OZ776 CCID Smartcard Reader
+0b98  Playmates Toys, Inc.
+0b99  Audio International, Inc.
+0b9b  Dipl.-Ing. Stefan Kunde
+	4012  Reflex RC-controller Interface
+0b9d  Softprotec Co.
+0b9f  Chippo Technologies
+0baf  U.S. Robotics
+	00e5  USR6000
+	00eb  USR1120 802.11b Adapter
+	00ec  56K Faxmodem
+	00f1  SureConnect ADSL ATM Adapter
+	00f2  SureConnect ADSL Loader
+	00f5  SureConnect ADSL ATM Adapter
+	00f6  SureConnect ADSL Loader
+	00f7  SureConnect ADSL ATM Adapter
+	00f8  SureConnect ADSL Loader
+	00f9  SureConnect ADSL ATM Adapter
+	00fa  SureConnect ADSL Loader
+	00fb  SureConnect ADSL Ethernet/USB Router
+	0118  U5 802.11g Adapter
+	011b  Wireless MAXg Adapter
+	0121  USR5423 WLAN
+	6112  FaxModem Model 5633
+0bb0  Concord Camera Corp.
+	0100  Sound Vision Stream
+	5007  3340z/Rollei DC3100
+0bb1  Infinilink Corp.
+0bb2  Ambit Microsystems Corp.
+	0302  WLAN
+	6098  USB Cable Modem
+0bb3  Ofuji Technology
+0bb4  High Tech Computer Corp.
+	00ce  mmO2 XDA GSM/GPRS Pocket PC
+	00cf  SPV C500 Smart Phone
+	0a01  PocketPC Sync
+	0a02  Himalaya GSM/GPRS Pocket PC
+	0a03  PocketPC Sync
+	0a04  PocketPC Sync
+	0a05  PocketPC Sync
+	0a06  PocketPC Sync
+	0a07  Magician PocketPC SmartPhone / O2 XDA
+	0a08  PocketPC Sync
+	0a09  PocketPC Sync
+	0a0a  PocketPC Sync
+	0a0b  PocketPC Sync
+	0a0c  PocketPC Sync
+	0a0d  PocketPC Sync
+	0a0e  PocketPC Sync
+	0a0f  PocketPC Sync
+	0a10  PocketPC Sync
+	0a11  PocketPC Sync
+	0a12  PocketPC Sync
+	0a13  PocketPC Sync
+	0a14  PocketPC Sync
+	0a15  PocketPC Sync
+	0a16  PocketPC Sync
+	0a17  PocketPC Sync
+	0a18  PocketPC Sync
+	0a19  PocketPC Sync
+	0a1a  PocketPC Sync
+	0a1b  PocketPC Sync
+	0a1c  PocketPC Sync
+	0a1d  PocketPC Sync
+	0a1e  PocketPC Sync
+	0a1f  PocketPC Sync
+	0a20  PocketPC Sync
+	0a21  PocketPC Sync
+	0a22  PocketPC Sync
+	0a23  PocketPC Sync
+	0a24  PocketPC Sync
+	0a25  PocketPC Sync
+	0a26  PocketPC Sync
+	0a27  PocketPC Sync
+	0a28  PocketPC Sync
+	0a29  PocketPC Sync
+	0a2a  PocketPC Sync
+	0a2b  PocketPC Sync
+	0a2c  PocketPC Sync
+	0a2d  PocketPC Sync
+	0a2e  PocketPC Sync
+	0a2f  PocketPC Sync
+	0a30  PocketPC Sync
+	0a31  PocketPC Sync
+	0a32  PocketPC Sync
+	0a33  PocketPC Sync
+	0a34  PocketPC Sync
+	0a35  PocketPC Sync
+	0a36  PocketPC Sync
+	0a37  PocketPC Sync
+	0a38  PocketPC Sync
+	0a39  PocketPC Sync
+	0a3a  PocketPC Sync
+	0a3b  PocketPC Sync
+	0a3c  PocketPC Sync
+	0a3d  PocketPC Sync
+	0a3e  PocketPC Sync
+	0a3f  PocketPC Sync
+	0a40  PocketPC Sync
+	0a41  PocketPC Sync
+	0a42  PocketPC Sync
+	0a43  PocketPC Sync
+	0a44  PocketPC Sync
+	0a45  PocketPC Sync
+	0a46  PocketPC Sync
+	0a47  PocketPC Sync
+	0a48  PocketPC Sync
+	0a49  PocketPC Sync
+	0a4a  PocketPC Sync
+	0a4b  PocketPC Sync
+	0a4c  PocketPC Sync
+	0a4d  PocketPC Sync
+	0a4e  PocketPC Sync
+	0a4f  PocketPC Sync
+	0a50  HTC SmartPhone Sync
+	0a51  SPV C400 / T-Mobile SDA GSM/GPRS Pocket PC
+	0a52  SmartPhone Sync
+	0a53  SmartPhone Sync
+	0a54  SmartPhone Sync
+	0a55  SmartPhone Sync
+	0a56  SmartPhone Sync
+	0a57  SmartPhone Sync
+	0a58  SmartPhone Sync
+	0a59  SmartPhone Sync
+	0a5a  SmartPhone Sync
+	0a5b  SmartPhone Sync
+	0a5c  SmartPhone Sync
+	0a5d  SmartPhone Sync
+	0a5e  SmartPhone Sync
+	0a5f  SmartPhone Sync
+	0a60  SmartPhone Sync
+	0a61  SmartPhone Sync
+	0a62  SmartPhone Sync
+	0a63  SmartPhone Sync
+	0a64  SmartPhone Sync
+	0a65  SmartPhone Sync
+	0a66  SmartPhone Sync
+	0a67  SmartPhone Sync
+	0a68  SmartPhone Sync
+	0a69  SmartPhone Sync
+	0a6a  SmartPhone Sync
+	0a6b  SmartPhone Sync
+	0a6c  SmartPhone Sync
+	0a6d  SmartPhone Sync
+	0a6e  SmartPhone Sync
+	0a6f  SmartPhone Sync
+	0a70  SmartPhone Sync
+	0a71  SmartPhone Sync
+	0a72  SmartPhone Sync
+	0a73  SmartPhone Sync
+	0a74  SmartPhone Sync
+	0a75  SmartPhone Sync
+	0a76  SmartPhone Sync
+	0a77  SmartPhone Sync
+	0a78  SmartPhone Sync
+	0a79  SmartPhone Sync
+	0a7a  SmartPhone Sync
+	0a7b  SmartPhone Sync
+	0a7c  SmartPhone Sync
+	0a7d  SmartPhone Sync
+	0a7e  SmartPhone Sync
+	0a7f  SmartPhone Sync
+	0a80  SmartPhone Sync
+	0a81  SmartPhone Sync
+	0a82  SmartPhone Sync
+	0a83  SmartPhone Sync
+	0a84  SmartPhone Sync
+	0a85  SmartPhone Sync
+	0a86  SmartPhone Sync
+	0a87  SmartPhone Sync
+	0a88  SmartPhone Sync
+	0a89  SmartPhone Sync
+	0a8a  SmartPhone Sync
+	0a8b  SmartPhone Sync
+	0a8c  SmartPhone Sync
+	0a8d  SmartPhone Sync
+	0a8e  SmartPhone Sync
+	0a8f  SmartPhone Sync
+	0a90  SmartPhone Sync
+	0a91  SmartPhone Sync
+	0a92  SmartPhone Sync
+	0a93  SmartPhone Sync
+	0a94  SmartPhone Sync
+	0a95  SmartPhone Sync
+	0a96  SmartPhone Sync
+	0a97  SmartPhone Sync
+	0a98  SmartPhone Sync
+	0a99  SmartPhone Sync
+	0a9a  SmartPhone Sync
+	0a9b  SmartPhone Sync
+	0a9c  SmartPhone Sync
+	0a9d  SmartPhone Sync
+	0a9e  SmartPhone Sync
+	0a9f  SmartPhone Sync
+	0b04  Hermes / TyTN / T-Mobile MDA Vario II / O2 Xda Trion
+	0b06  Athena / Advantage x7500 / Dopod U1000 / T-Mobile AMEO
+	0b0c  Elf / Touch / P3450 / T-Mobile MDA Touch / O2 Xda Nova / Dopod S1
+	0bce  Vario MDA
+0bb5  Murata Manufacturing Co., Ltd
+0bb6  Network Alchemy
+0bb7  Joytech Computer Co., Ltd
+0bb8  Hitachi Semiconductor and Devices Sales Co., Ltd
+0bb9  Eiger M&C Co., Ltd
+0bba  ZAccess Systems
+0bbb  General Meters Corp.
+0bbc  Assistive Technology, Inc.
+0bbd  System Connection, Inc.
+0bc0  Knilink Technology, Inc.
+0bc1  Fuw Yng Electronics Co., Ltd
+0bc2  Seagate RSS LLC
+	2000  Storage Adapter V3 (TPP)
+0bc3  IPWireless, Inc.
+0bc4  Microcube Corp.
+0bc5  JCN Co., Ltd
+0bc6  ExWAY, Inc.
+0bc7  X10 Wireless Technology, Inc.
+	0001  ActiveHome (ACPI-compliant)
+	0002  Firecracker Interface (ACPI-compliant)
+	0003  VGA Video Sender (ACPI-compliant)
+	0004  X10 Receiver
+	0005  Wireless Transceiver (ACPI-compliant)
+	0006  Wireless Transceiver (ACPI-compliant)
+	0007  Wireless Transceiver (ACPI-compliant)
+	0008  Wireless Transceiver (ACPI-compliant)
+	0009  Wireless Transceiver (ACPI-compliant)
+	000a  Wireless Transceiver (ACPI-compliant)
+	000b  Transceiver (ACPI-compliant)
+	000c  Transceiver (ACPI-compliant)
+	000d  Transceiver (ACPI-compliant)
+	000e  Transceiver (ACPI-compliant)
+	000f  Transceiver (ACPI-compliant)
+0bc8  Telmax Communications
+0bc9  ECI Telecom, Ltd
+0bca  Startek Engineering, Inc.
+0bcb  Perfect Technic Enterprise Co., Ltd
+0bd7  Andrew Pargeter & Associates
+	a021  Amptek DP4 multichannel signal analyzer
+0bda  Realtek Semiconductor Corp.
+	0103  USB 2.0 Card Reader
+	0104  Mass Storage Device
+	0106  Mass Storage Device
+	0107  Mass Storage Device
+	0108  Mass Storage Device
+	0111  Card Reader
+	0113  Mass Storage Device
+	0115  Mass Storage Device
+	0116  Mass Storage Device
+	0117  Mass Storage Device
+	0118  Mass Storage Device
+	0151  Mass Stroage Device
+	0152  Mass Stroage Device
+	0153  Mass Stroage Device
+	0156  Mass Stroage Device
+	0157  Mass Stroage Device
+	0158  Mass Stroage Device
+	0161  Mass Stroage Device
+	0168  Mass Stroage Device
+	0169  Mass Stroage Device
+	0171  Mass Stroage Device
+	0176  Mass Stroage Device
+	0178  Mass Stroage Device
+	2831  2831U Device
+	8150  RTL8150 Fast Ethernet Adapter
+	8151  RTL8151 Adapteon Business Mobile Networks BV
+	8187  RTL8187 Wireless Adapter
+	8189  RTL8187B Wireless 802.11g 54Mbps Network Adapter
+	8197  RTL8187B Wireless Adapter
+0bdb  Ericsson Business Mobile Networks BV
+	1000  BV Bluetooth Device
+	1002  Bluetooth Device 1.2
+0bdc  Y Media Corp.
+0bdd  Orange PCS
+0be2  Kanda Tsushin Kogyo Co., Ltd
+0be3  TOYO Corp.
+0be4  Elka International, Ltd
+0be5  DOME imaging systems, Inc.
+0be6  Dong Guan Humen Wonderful Wire Cable Factory
+0bee  LTK Industries, Ltd
+0bef  Way2Call Communications
+0bf0  Pace Micro Technology PLC
+0bf1  Intracom S.A.
+	0001  netMod Driver Ver 2.4.17 (CAPI)
+	0002  netMod Driver Ver 2.4 (CAPI)
+	0003  netMod Driver Ver 2.4 (CAPI)
+0bf2  Konexx
+0bf6  Addonics Technologies, Inc.
+	0103  Storage Device
+	1234  Storage Device
+	a000  Cable 205 (TPP)
+	a001  Cable 205
+	a002  IDE Bridge
+0bf7  Sunny Giken, Inc.
+0bf8  Fujitsu Siemens Computers
+	1001  Fujitsu Pocket Loox 600 PDA
+0c04  MOTO Development Group, Inc.
+0c05  Appian Graphics
+0c06  Hasbro Games, Inc.
+0c07  Infinite Data Storage, Ltd
+0c08  Agate
+	0378  Q 16MB Storage Device
+0c09  Comjet Information System
+	a5a5  Litto Version USB2.0
+0c0a  Highpoint Technologies, Inc.
+0c0b  Dura Micro, Inc. (Acomdata)
+	27cb  6-in-1 Flash Reader and Writer
+	27d7  Multi Memory reader/writer MD-005
+	27da  Multi Memory reader/writer MD-005
+	27dc  Multi Memory reader/writer MD-005
+	27e7  3,5'' HDD case MD-231
+	27ee  3,5'' HDD case MD-231
+	2814  3,5'' HDD case MD-231
+	2815  3,5'' HDD case MD-231
+	281d  3,5'' HDD case MD-231
+	a109  CF/SM Reader and Writer
+	a10c  SD/MS Reader and Writer
+	b001  USB 2.0 Mass Storage IDE adapter
+	b004  MMC/SD Reader and Writer
+0c12  Zeroplus
+	0005  PSX Vibration Feedback Converter
+	8809  Red Octane Ignition Xbox DDR Pad
+0c15  Iris Graphics
+0c16  Gyration, Inc.
+	0080  eHome Infrared Receiver
+	0081  eHome Infrared Receiver
+0c17  Cyberboard A/S
+0c18  SynerTek Korea, Inc.
+0c19  cyberPIXIE, Inc.
+0c1a  Silicon Motion, Inc.
+0c1b  MIPS Technologies
+0c1c  Hang Zhou Silan Electronics Co., Ltd
+0c22  Tally Printer Corp.
+0c23  Lernout + Hauspie
+0c24  Taiyo Yuden
+	0001  Bluetooth Adaptor
+	0002  Bluetooth Device2
+	0005  Bluetooth Device(BC04-External)
+	000b  Bluetooth Device(BC04-External)
+	000c  Bluetooth Adaptor
+	000e  Bluetooth Device(BC04-External)
+	000f  Bluetooth Driver (V2.0+EDR)
+	0010  Bluetooth Device(BC04-External)
+	0012  Bluetooth Device(BC04-External)
+	0018  Bluetooth Device(BC04-External)
+	0019  Bluetooth Device
+	0c24  Bluetooth Device(SAMPLE)
+	ffff  Bluetooth module with BlueCore in DFU mode
+0c25  Sampo Corp.
+	0310  Scream Cam
+0c27  RFIDeas, Inc
+	3bfa  pcProx Card Reader
+0c2e  Metro
+	0200  Metrologic Scanner
+0c35  Eagletron, Inc.
+0c36  E Ink Corp.
+0c37  e.Digital
+0c38  Der An Electric Wire & Cable Co., Ltd
+0c39  IFR
+0c3a  Furui Precise Component (Kunshan) Co., Ltd
+0c3b  Komatsu, Ltd
+0c3c  Radius Co., Ltd
+0c3d  Innocom, Inc.
+0c3e  Nextcell, Inc.
+0c44  Motorola iDEN
+	0021  iDEN P2k0 Device
+	0022  iDEN P2k1 Device
+	03a2  iDEN Smartphone
+0c45  Microdia
+	1020  Mass Storage Reader
+	1028  Mass Storage Reader
+	1030  Mass Storage Reader
+	1031  Sonix Mass Storage Device
+	1032  Mass Storage Reader
+	1033  Sonix Mass Storage Device
+	1034  Mass Storage Reader
+	1035  Mass Storage Reader
+	1036  Mass Storage Reader
+	1037  Sonix Mass Storage Device
+	1050  CF Card Reader
+	1058  HDD Reader
+	1060  iFlash SM-Direct Card Reader
+	1061  Mass Storage Reader
+	1062  Mass Storage Reader
+	1063  Sonix Mass Storage Device
+	1064  Mass Storage Reader
+	1065  Mass Storage Reader
+	1066  Mass Storage Reader
+	1067  Mass Storage Reader
+	1158  A56AK
+	184c  VoIP Phone
+	6001  Genius VideoCAM NB
+	6005  Sweex Mini WebCam
+	6007  VideoCAM Eye
+	6009  VideoCAM ExpressII
+	600d  TwinkleCam USB camera
+	6011  PC Camera (SN9C102)
+	6019  PC Camera (SN9C102)
+	6024  VideoCAM ExpressII
+	6025  VideoCAM ExpressII
+	6028  Typhoon Easycam USB 330K (older)
+	6029  Triplex i-mini PC Camera
+	602a  Meade ETX-105EC Camera
+	602b  VideoCAM NB 300
+	602c  Clas Ohlson TWC-30XOP WebCam
+	602d  VideoCAM ExpressII
+	602e  VideoCAM Messenger
+	6030  VideoCAM ExpressII
+	603f  VideoCAM ExpressII
+	6040  CCD PC Camera (PC390A)
+	606a  CCD PC Camera (PC390A)
+	607a  CCD PC Camera (PC390A)
+	607b  Win2 PC Camera
+	607c  CCD PC Camera (PC390A)
+	607e  CCD PC Camera (PC390A)
+	6080  Audio (Microphone)
+	6082  VideoCAM Look
+	6083  VideoCAM Look
+	608c  VideoCAM Look
+	608e  VideoCAM Look
+	608f  VideoCAM Look
+	60a8  VideoCAM Look
+	60aa  VideoCAM Look
+	60ab  PC Camera
+	60af  VideoCAM Look
+	60b0  Genius VideoCam Look
+	60c0  PC Camera with Mic (SN9C105)
+	60c8  Win2 PC Camera
+	60cc  Composite Device
+	60ec  Composite Device
+	60ef  Win2 PC Camera
+	60fa  PC Camera with Mic (SN9C105)
+	60fb  Composite Device
+	60fc  PC Camera with Mic (SN9C105)
+	60fe  Audio (Microphone)
+	6108  Win2 PC Camera
+	6122  PC Camera (SN9C110)
+	6123  PC Camera (SN9C110)
+	612a  PC Camera (SN9C110)
+	612c  PC Camera (SN9C110)
+	612e  PC Camera (SN9C110)
+	612f  PC Camera (SN9C110)
+	6130  PC Camera (SN9C120)
+	6138  Win2 PC Camera
+	613a  PC Camera (SN9C120)
+	613b  Win2 PC Camera
+	613c  PC Camera (SN9C120)
+	613e  PC Camera (SN9C120)
+	6240  PC Camera (SN9C201)
+	6242  PC Camera (SN9C201)
+	6243  PC Camera (SN9C201)
+	6248  PC Camera (SN9C201)
+	624b  PC Camera (SN9C201)
+	624c  PC Camera (SN9C201)
+	624e  PC Camera (SN9C201)
+	624f  PC Camera (SN9C201)
+	6260  PC Camera (SN9C201)
+	6270  U-CAM PC Camera NE878
+	627a  PC Camera (SN9C201)
+	627b  PC Camera (SN9C201)
+	627c  PC Camera (SN9C201)
+	627f  PC Camera (SN9C201)
+	6280  Composite Device
+	6282  Audio (Microphone)
+	6283  Audio (Microphone)
+	6288  Audio (Microphone)
+	628a  Composite Device
+	628b  PC Camera (SN9C202)
+	628c  PC Camera (SN9C202)
+	628e  Composite Device
+	628f  Composite Device
+	62a0  Audio (Microphone)
+	62b0  Audio (Microphone)
+	62ba  PC Camera (SN9C202)
+	62bb  PC Camera (SN9C202)
+	62bc  Composite Device
+	62c0  Pavilion Webcam
+	8000  DC31VC
+	8006  Dual Mode Camera (8006 VGA)
+	800a  Vivitar Vivicam3350B
+0c46  WaveRider Communications, Inc.
+0c4b  Reiner SCT Kartensysteme GmbH
+	0100  cyberJack e-com/pinpad
+	0300  cyberJack pinpad(a)
+0c52  Sealevel Systems, Inc.
+	2101  Serial Converter
+0c53  ViewPLUS, Inc.
+0c54  Glory, Ltd
+0c55  Spectrum Digital, Inc.
+	0510  Spectrum Digital XDS510 JTAG Debugger
+	0540  SPI540
+	5416  TMS320C5416 DSK
+	6416  TMS320C6416 DDB
+0c56  Billion Bright, Ltd
+0c57  Imaginative Design Operation Co., Ltd
+0c58  Vidar Systems Corp.
+0c59  Dong Guan Shinko Wire Co., Ltd
+0c5a  TRS International Mfg., Inc.
+0c5e  Xytronix Research & Design
+0c62  Chant Sincere Co., Ltd
+0c63  Toko, Inc.
+0c64  Signality System Engineering Co., Ltd
+0c65  Eminence Enterprise Co., Ltd
+0c66  Rexon Electronics Corp.
+0c67  Concept Telecom, Ltd
+0c70  MCT Elektronikladen
+	0000  USB08 Development board
+0c74  Optronic Laboratories Inc.
+	0002  OL 700-30 Goniometer
+0c76  JMTek, LLC.
+	0001  Mass Storage Controller
+	0002  Mass Storage Controller
+	0003  USBdisk
+	0004  Mass Storage Controller
+	0005  Transcend USB Flash disk
+	0006  Transcend JetFlash
+	0007  Mass Storage Device
+0c77  Sipix Group, Ltd
+	1001  SiPix Web2
+	1002  SiPix SC2100
+	1010  SiPix Snap
+	1011  SiPix Blink 2
+	1015  SiPix CAMeleon
+0c78  Detto Corp.
+0c79  NuConnex Technologies Pte., Ltd
+0c7a  Wing-Span Enterprise Co., Ltd
+0c86  NDA Technologies, Inc.
+0c88  Kyocera Wireless Corp.
+	0021  Handheld
+	17da  Qualcomm Kyocera CDMA Technologies MSM
+0c89  Honda Tsushin Kogyo Co., Ltd
+0c8a  Pathway Connectivity, Inc.
+0c8b  Wavefly Corp.
+0c8c  Coactive Networks
+0c8d  Tempo
+0c8e  Cesscom Co., Ltd
+	6000  Luxian Series
+0c8f  Applied Microsystems
+0c98  Berkshire Products, Inc.
+	1140  USB PC Watchdog
+0c99  Innochips Co., Ltd
+0c9a  Hanwool Robotics Corp.
+0c9b  Jobin Yvon, Inc.
+0c9d  SemTek
+	0170  3873 Manual Insert card reader
+0ca2  Zyfer
+0ca3  Sega Corp.
+0ca4  ST&T Instrument Corp.
+0ca5  BAE Systems Canada, Inc.
+0ca6  Castles Technology Co., Ltd
+	0010  EZUSB PC/SC Smart Card Reader
+	0050  EZ220PU Reader Controller
+	1077  Bludrive Family Smart Card Reader
+	107e  Reader Controller
+	2010  myPad110 PC/SC Smart Card Reader
+0ca7  Information Systems Laboratories
+0cad  Motorola CGISS
+	9001  PowerPad Pocket PC Device
+0cae  Ascom Business Systems, Ltd
+0caf  Buslink
+	2507  Hi-Speed USB-to-IDE Bridge Controller
+	2515  Flash Disk Embedded Hub
+	2516  Flash Disk Security Device
+	2517  Flash Disk Mass Storage Device
+	25c7  Hi-Speed USB-to-IDE Bridge Controller
+	3a00  Hard Drive
+	3a20  Mass Storage Device
+	3acd  Mass Storage Device
+0cb0  Flying Pig Systems
+0cb1  Innovonics, Inc.
+0cb6  Celestix Networks, Pte., Ltd
+0cb7  Singatron Enterprise Co., Ltd
+0cb8  Opticis Co., Ltd
+0cba  Trust Electronic (Shanghai) Co., Ltd
+0cbb  Shanghai Darong Electronics Co., Ltd
+0cbc  Palmax Technology Co., Ltd
+	0101  Pocket PC P6C
+	0201  Personal Digital Assistant
+	0301  Personal Digital Assistant P6M+
+	0401  Pocket PC
+0cbd  Pentel Co., Ltd (Electronics Equipment Div.)
+0cbe  Keryx Technologies, Inc.
+0cbf  Union Genius Computer Co., Ltd
+0cc0  Kuon Yi Industrial Corp.
+0cc1  Given Imaging, Ltd
+0cc2  Timex Corp.
+0cc3  Rimage Corp.
+0cc4  emsys GmbH
+0cc5  Sendo
+0cc6  Intermagic Corp.
+0cc7  Kontron Medical AG
+0cc8  Technotools Corp.
+0cc9  BroadMAX Technologies, Inc.
+0cca  Amphenol
+0ccb  SKNet Co., Ltd
+0ccc  Domex Technology Corp.
+0ccd  TerraTec Electronic GmbH
+	0012  PHASE 26
+	0013  PHASE 26
+	0014  PHASE 26
+	0015  Flash Update for TerraTec PHASE 26
+	0021  Cameo Grabster 200
+	0023  Mystify Claw
+	0028  Aureon 5.1 MkII
+	0032  MIDI HUBBLE
+	0035  Miditech Play'n Roll
+	0036  Cinergy 250 Audio
+	0037  Cinergy 250 Audio
+	0038  Cinergy T^2 DVB-T Receiver
+	0039  Grabster AV 400
+	003b  Cinergy 400
+	003c  Grabster AV 250
+	0042  Cinergy Hybrid T XS
+	0043  Cinergy T XS
+	004e  Cinergy T XS
+	004f  Cinergy Analog XS
+	005c  Cinergy T²
+	0069  Cinergy T XE DVB-T Receiver
+0cd4  Bang Olufsen
+	0101  BeolinkPC2
+0cd7  NewChip S.r.l.
+0cd8  JS Digitech, Inc.
+	2007  Smart Card Reader/JSTU-9700
+0cd9  Hitachi Shin Din Cable, Ltd
+0cde  Z-Com
+	0001  M4Y-750
+	0002  XI-725/726 Prism2.5 802.11b Adapter
+	0003  Sagem 802.11b Dongle
+	0004  Sagem 802.11b Dongle
+	0005  XI-735 Prism3 802.11b Adapter
+	0006  Medion 40900 802.11b Adapter
+	0008  Sitecom Wireless Network Adapter 100G+ WL-125
+	0009  (ZD1211)IEEE 802.11b+g Adapter
+	0011  ZD1211
+	0012  AR5523
+	0013  AR5523 driver (no firmware)
+	0014  NB 802.11g Wireless LAN Adapter(3887A)
+	0015  Zoom Wireless-G
+	0016  NB 802.11g Wireless LAN Adapter(3887A)
+	0018  NB 802.11a/b/g Wireless LAN Adapter(3887A)
+	001a  ZD1211B
+	001c  802.11b/g Wireless Network Adapter
+	0020  Wi-Fi Wireless LAN Adapter
+	0022  802.11b/g/n Wireless Network Adapter
+0ce9  pico Technology
+	1001  PicoScope3204
+0cf1  e-Conn Electronic Co., Ltd
+0cf2  ENE Technology, Inc.
+0cf3  Atheros Communications, Inc.
+	0001  AR5523
+	0002  AR5523 (no firmware)
+	0003  AR5523
+	0004  AR5523 (no firmware)
+	0005  AR5523
+	0006  AR5523 (no firmware)
+0cf4  Fomtex Corp.
+0cf5  Cellink Co., Ltd
+0cf6  Compucable Corp.
+0cf7  ishoni Networks
+0cf8  Clarisys, Inc.
+	0750  Claritel-i750 - vp
+0cf9  Central System Research Co., Ltd
+0cfa  Inviso, Inc.
+0cfc  Minolta-QMS, Inc.
+0cff  SAFA MEDIA Co., Ltd.
+	0320  SR-380N
+0d06  telos EDV Systementwicklung GmbH
+0d08  UTStarcom
+	0602  DV007 [serial]
+	0603  DV007 [storage]
+0d0b  Contemporary Controls
+0d0c  Astron Electronics Co., Ltd
+0d0d  MKNet Corp.
+0d0e  Hybrid Networks, Inc.
+0d0f  Feng Shin Cable Co., Ltd
+0d10  Elastic Networks
+	0001  StormPort (WDM)
+0d11  Maspro Denkoh Corp.
+0d12  Hansol Electronics, Inc.
+0d13  BMF Corp.
+0d14  Array Comm, Inc.
+0d15  OnStream b.v.
+0d16  Hi-Touch Imaging Technologies Co., Ltd
+	0001  PhotoShuttle
+	0002  Photo Printer 730 series
+	0004  Photo Printer 63xPL/PS
+	0100  Photo Printer 63xPL/PS
+	0102  Photo Printer 64xPS
+	0103  Photo Printer 730 series
+	0104  Photo Printer 63xPL/PS
+	0105  Photo Printer 64xPS
+	0200  Photo Printer 64xDL
+0d17  NALTEC, Inc.
+0d18  coaXmedia
+0d19  Hank Connection Industrial Co., Ltd
+0d32  Leo Hui Electric Wire & Cable Co., Ltd
+0d33  AirSpeak, Inc.
+0d34  Rearden Steel Technologies
+0d35  Dah Kun Co., Ltd
+0d3a  Posiflex Technologies, Inc.
+0d3c  Sri Cable Technology, Ltd
+0d3d  Tangtop Technology Co., Ltd
+	0001  HID Keyboard
+0d3e  Fitcom, inc.
+0d3f  MTS Systems Corp.
+0d40  Ascor, Inc.
+0d41  Ta Yun Terminals Industrial Co., Ltd
+0d42  Full Der Co., Ltd
+0d46  Kobil Systems GmbH
+	2012  KAAN Standard Plus (Smartcard reader)
+	3003  mIDentity Light / KAAN SIM III
+	4000  mIDentity (mass storage)
+	4001  mIDentity Basic/Classic (composite device)
+	4081  mIDentity Basic/Classic (installationless)
+0d49  Maxtor
+	3000  Drive
+	3010  3000LE Drive
+	3100  Hi-Speed USB-IDE Bridge Controller
+	5000  5000XT Drive
+	5010  5000LE Drive
+	5020  Mobile Hard Disk Drive
+	7000  OneTouch
+	7010  OneTouch
+0d4a  NF Corp.
+0d4b  Grape Systems, Inc.
+0d4c  Tedas AG
+0d4d  Coherent, Inc.
+0d4e  Agere Systems Netherland BV
+	047a  WLAN Card
+	1000  Wireless Card Model 0801
+	1001  Wireless Card Model 0802
+0d4f  EADS Airbus France
+0d50  Cleware GmbH
+	0011  USB-Temp2 Thermometer
+0d51  Volex (Asia) Pte., Ltd
+0d53  HMI Co., Ltd
+0d54  Holon Corp.
+0d55  ASKA Technologies, Inc.
+0d56  AVLAB Technology, Inc.
+0d57  Solomon Microtech, Ltd
+0d5c  Belkin
+	a002  F5D6050 802.11b Adapter
+0d5e  Myacom, Ltd
+	2346  BT Digital Access adapter
+0d5f  CSI, Inc.
+0d60  IVL Technologies, Ltd
+0d61  Meilu Electronics (Shenzhen) Co., Ltd
+0d62  Darfon Electronics Corp.
+	0003  Smartcard Reader
+	0004  Filter Driver
+	0306  M530 Mouse
+	0800  Magic Wheel
+	2021  AM805 Keyboard
+	2026  TECOM Bluetooth Device
+	a100  Benq Mouse
+0d63  Fritz Gegauf AG
+0d64  DXG Technology Corp.
+	0105  Dual Mode Digital Camera 1.3M
+	0107  Horus MT-409 Camera
+	0108  Dual Mode Digital Camera
+	0202  Dual Mode Video Camera Device
+	0303  DXG-305V Camera
+	1001  SiPix Stylecam/UMAX AstraPix 320s
+	1002  Fashion Cam 01 Dual-Mode DSC (Video Camera)
+	1003  Fashion Cam Dual-Mode DSC (Controller)
+	1021  D-Link DSC 350F
+	1208  Dual Mode Still Camera Device
+	2208  Mass Storage
+	3105  Dual Mode Digital Camera Disk
+	3108  Digicam Mass Storage Device
+0d65  KMJP Co., Ltd
+0d66  TMT
+0d67  Advanet, Inc.
+0d68  Super Link Electronics Co., Ltd
+0d69  NSI
+0d6a  Megapower International Corp.
+0d6b  And-Or Logic
+0d70  Try Computer Co., Ltd
+0d71  Hirakawa Hewtech Corp.
+0d72  Winmate Communication, Inc.
+0d73  Hit's Communications, Inc.
+0d76  MFP Korea, Inc.
+0d77  Power Sentry/Newpoint
+0d78  Japan Distributor Corp.
+0d7a  MARX Datentechnik GmbH
+0d7b  Wellco Technology Co., Ltd
+0d7c  Taiwan Line Tek Electronic Co., Ltd
+0d7d  Phison Electronics Corp.
+	0100  PS1001/1011/1006/1026 Flash Disk
+	0110  Gigabyte FlexDrive
+	0120  Disk Pro 64MB
+	0124  GIGABYTE Disk
+	0240  I/O-Magic/Transcend 6-in-1 Card Reader
+	110e  NEC uPD720121/130 USB-ATA/ATAPI Bridge
+	1240  Apacer 6-in-1 Card Reader 2.0
+	1270  Wolverine SixPac 6000
+	1300  Flash Disk
+	1320  PS2031 Flash Disk
+	1400  Attache 256MB USB 2.0 Flash Drive
+	1420  PS2044 Pen Drive
+	1470  Vosonic X's-Drive II+ VP2160
+	1900  USB Thumb Drive
+0d7e  American Computer & Digital Components
+	2507  Hi-Speed USB-to-IDE Bridge Controller
+	2517  Hi-Speed Mass Storage Device
+	25c7  Hi-Speed USB-to-IDE Bridge Controller
+0d7f  Essential Reality LLC
+0d80  H.R. Silvine Electronics, Inc.
+0d81  TechnoVision
+0d83  Think Outside, Inc.
+0d89  Oz Software
+0d8a  King Jim Co., Ltd
+	0101  TEPRA PRO
+0d8b  Ascom Telecommunications, Ltd
+0d8c  C-Media Electronics, Inc.
+	0001  Audio Device
+	0002  Composite Device
+	0003  Sound Device
+	0006  Storm HP-USB500 5.1 Headset
+	000c  Audio Adapter
+	000d  Composite Device
+	000e  Audio Adapter (Planet UP-100, Genius G-Talk)
+	0102  CM106 Like Sound Device
+	0103  Turtle Beach Audio Advantage Micro
+	0201  CM6501
+	5000  Mass Storage Controller
+	5200  Mass Storage Controller(0D8C,5200)
+	b213  USB Phone CM109 (aka CT2000,VPT1000)
+0d8d  Promotion & Display Technology, Ltd
+	0234  V-234 Composite Device
+	0550  V-550 Composite Device
+	0551  V-551 Composite Device
+	0552  V-552 Composite Device
+	0651  V-651 Composite Device
+	0652  V-652 Composite Device
+	0653  V-653 Composite Device
+	0654  V-654 Composite Device
+	0655  V-655 Composite Device
+	0656  V-656 Composite Device
+	0657  V-657 Composite Device
+	0658  V-658 Composite Device
+	0659  V-659 Composite Device
+	0660  V-660 Composite Device
+	0661  V-661 Composite Device
+	0662  V-662 Composite Device
+	0850  V-850 Composite Device
+	0851  V-851 Composite Device
+	0852  V-852 Composite Device
+	0901  V-901 Composite Device
+	0902  V-902 Composite Device
+	0903  V-903 Composite Device
+	4754  Voyager DMP Composite Device
+	bb00  Bloomberg Composite Device
+	bb01  Bloomberg Composite Device
+	bb02  Bloomberg Composite Device
+	bb03  Bloomberg Composite Device
+	bb04  Bloomberg Composite Device
+	bb05  Bloomberg Composite Device
+	fffe  Global Tuner Composite Device
+	ffff  Voyager DMP Composite Device
+0d8e  Global Sun Technology, Inc.
+	0163  802.11g 54 Mbps Wireless Dongle
+	1621  802.11b Wireless Adapter
+	3762  802.11g Wireless Mini adapter
+	3763  802.11g Wireless dongle
+	7100  802.11b Adapter
+	7110  WL-210
+	7801  AR5523
+	7802  AR5523 (no firmware)
+	7811  AR5523
+	7812  AR5523 (no firmware)
+	7a01  PRISM25 802.11b Adapter
+0d8f  Pitney Bowes
+0d90  Sure-Fire Electrical Corp.
+0d96  Skanhex Technology, Inc.
+	0000  Jenoptik JD350 video
+	3300  SX330z Camera
+	4100  SX410z Camera
+	4102  MD 9700 Camera
+	4104  Jenoptik JD-4100z3s
+	410a  Medion 9801/Novatech SX-410z
+	5200  SX-520z Camera
+0d97  Santa Barbara Instrument Group
+	0001  SBIG Astronomy Camera (without firmware)
+	0101  SBIG Astronomy Camera (with firmware)
+0d98  Mars Semiconductor Corp.
+	0300  Avaya Wireless Card
+0d99  Trazer Technologies, Inc.
+0d9a  RTX Telecom AS
+	0001  Bluetooth Device
+0d9b  Tat Shing Electrical Co.
+0d9c  Chee Chen Hi-Technology Co., Ltd
+0d9d  Sanwa Supply, Inc.
+0d9e  Avaya
+	0300  Wireless Card
+0d9f  Powercom Co., Ltd
+0da0  Danger Research
+0da1  Suzhou Peter's Precise Industrial Co., Ltd
+0da2  Land Instruments International, Ltd
+0da3  Nippon Electro-Sensory Devices Corp.
+0da4  Polar Electro OY
+	0001  Interface
+0da7  IOGear, Inc.
+0da8  softDSP Co., Ltd
+	0001  SDS 200A Oscilloscope
+0dab  Cubig Group
+	0100  DVR/CVR-M140 MP3 Player
+0dad  Westover Scientific
+0db0  Micro Star International
+	1020  PC2PC WLAN Card
+	1967  Bluetooth Dongle
+	4011  Medion Flash XL V2.0 Card Reader
+	4600  802.11b/g Turbo Wireless Adapter
+	5501  Mass Storage Device
+	5502  Mass Storage Device
+	5513  MP3 Player
+	5515  MP3 Player
+	5516  MP3 Player
+	6823  UB11B/MS-6823 802.11b Wi-Fi adapter
+	6826  IEEE 802.11g Wireless Network Adapter
+	6855  Bluetooth Device
+	6861  MSI-6861 802.11g WiFi adapter
+	6865  RT2570
+	6869  RT2570
+	6874  RT2573
+	6877  RT2573
+	6881  Bluetooth Class I EDR Device
+	688a  Bluetooth Class I EDR Device
+	6970  Bluetooth adapter
+	697a  Bluetooth Dongle
+	6982  Medion Flash XL Card Reader
+	a861  RT2573
+	a874  RT2573
+	a970  Bluetooth dongle
+	a97a  Bluetooth EDR Device
+	b970  Bluetooth EDR Device
+	b97a  Bluetooth EDR Device
+0db1  Wen Te Electronics Co., Ltd
+0db2  Shian Hwi Plug Parts, Plastic Factory
+0db3  Tekram Technology Co., Ltd
+0db4  Chung Fu Chen Yeh Enterprise Corp.
+0db7  ELCON Systemtechnik
+	0002  Goldpfeil P-LAN
+0dbe  Jiuh Shiuh Precision Industry Co., Ltd
+0dbf  Quik Tech Solutions
+	0002  SmartDongle Security Key
+	0200  HDD Storage Solution
+	021b  USB-2.0 IDE Adapter
+	0300  Storage Adapter
+	0333  Storage Adapter
+	0707  ZIV Drive
+0dc0  Great Notions
+0dc1  Tamagawa Seiki Co., Ltd
+0dc3  Athena Smartcard Solutions, Inc.
+	0801  ASEDrive III
+	0802  ASEDrive IIIe
+	1104  ASEDrive IIIe KB
+	1701  ASEKey
+	1702  ASEKey
+0dc4  Macpower Peripherals, Ltd
+	0040  Mass Storage Device
+	0041  Mass Storage Device
+	0042  Mass Storage Device
+	0101  Hi-Speed Mass Storage Device
+0dc5  SDK Co., Ltd
+0dc6  Precision Squared Technology Corp.
+0dc7  First Cable Line, Inc.
+0dcd  NetworkFab Corp.
+	0001  Remote Interface Adapter
+	0002  High Bandwidth Codec
+0dd0  Access Solutions
+	1002  Triple Talk Speech Synthesizer
+0dd1  Contek Electronics Co., Ltd
+0dd2  Power Quotient International Co., Ltd
+	0003  Mass Storage (P)
+0dd3  MediaQ
+0dd4  Custom Engineering SPA
+0dd5  California Micro Devices
+0dd7  Kocom Co., Ltd
+0dd8  Netac Technology Co., Ltd
+	1060  USB-CF-Card
+	e007  OnlyDisk U222 Pendrive
+0dd9  HighSpeed Surfing
+0dda  Integrated Circuit Solution, Inc.
+	0001  Multi-Card Reader 6in1
+	0002  Multi-Card Reader 7in1
+	0003  Flash Disk
+	0005  Internal Multi-Card Reader 6in1
+	0008  SD single card reader
+	0009  MS single card reader
+	000a  MS+SD Dual Card Reader
+	000b  SM single card reader
+	0101  All-In-One Card Reader
+	0102  All-In-One Card Reader
+	0301  MP3 Player
+	0302  Multi-Card MP3 Player
+	1001  Multi-Flash Disk
+	2001  Multi-Card Reader
+	2002  Q018 default PID
+	2003  Multi-Card Reader
+	2005  Datalux DLX-1611 16in1 Card Reader
+	2006  All-In-One Card Reader
+	2007  USB to ATAPI bridge
+	2008  All-In-One Card Reader
+	2013  SD/MS Combo Card Reader
+	2014  SD/MS Single Card Reader
+	2023  card reader SD/MS DEMO board with ICSI brand name (MaskROM version)
+	2024  card reader SD/MS DEMO board with Generic brand name (MaskROM version)
+	2026  USB2.0 Card Reader
+	2027  USB 2.0 Card Reader
+	2315  UFD MP3 player (model 2)
+	2318  UFD MP3 player (model 1)
+	2321  UFD MP3 player
+0ddb  Tamarack, Inc.
+0ddd  Datelink Technology Co., Ltd
+0dde  Ubicom, Inc.
+0de0  BD Consumer Healthcare
+0dea  UTECH Electronic (D.G.) Co., Ltd.
+0ded  Novasonics
+0dee  Lifetime Memory Products
+	4010  Storage Adapter
+0def  Full Rise Electronic Co., Ltd
+0df6  Sitecom Europe B.V.
+	0001  C-Media VOIP Device
+	0004  Bluetooth 2.0 Adapter 100m
+	0007  Bluetooth 2.0 Adapter 10m
+	000b  Bluetooth 2.0.USB Adapter DFU
+	000d  WL-168 Wireless Network Adapter 54g
+	0017  WL-182
+	0019  Bluetooth 2.0 adapter 10m CN-512v2 001
+	001a  Bluetooth 2.0 adapter 100m CN-521v2 001
+	061c  LN-028
+	21f4  44 St Bluetooth Device
+	2200  Sitecom bluetooth2.0 class 2 dongle CN-512
+	2208  Sitecom bluetooth2.0 class 2 dongle CN-520
+	2209  Sitecom bluetooth2.0 class 1 dongle CN-521
+	9071  zd1211 802.11g Adapter
+	9075  ZD1211B
+	90ac  WL-172
+	9712  WL-113 rev 2
+0df7  Mobile Action Technology, Inc.
+	0620  MA-620 Infrared Adapter
+	0700  MA-700 Bluetooth Adapter
+	0720  MA-720 Bluetooth Adapter
+	0722  Bluetooth Dongle
+	0800  Data Cable
+	0820  Data Cable
+	1800  Generic Card Reader
+	1802  Card Reader
+0dfa  Toyo Communication Equipment Co., Ltd
+0dfc  GeneralTouch Technology Co., Ltd
+	0001  Touchscreen
+0e03  Nippon Systemware Co., Ltd
+0e08  Winbest Technology Co., Ltd
+0e0c  Gesytec
+	0101  LonUSB LonTalk Network Adapter
+0e16  JMTek, LLC
+0e17  Walex Electronic, Ltd
+0e1b  Crewave
+0e21  Cowon Systems, Inc.
+	0300  iAudio CW200
+	0400  MP3 Player
+	0510  iAudio X5
+	0513  iAudio X5, side USB port
+	0520  iAudio M5
+	0700  iAudio U3
+0e22  Symbian Ltd.
+0e23  Liou Yuane Enterprise Co., Ltd
+0e25  VinChip Systems, Inc.
+0e26  J-Phone East Co., Ltd
+0e30  HeartMath LLC
+0e34  Micro Computer Control Corp.
+0e35  3Pea Technologies, Inc.
+0e36  TiePie engineering
+	0008  Handyscope HS3
+	0009  Handyscope HS3 (br)
+	000a  Handyscope HS4
+	000b  Handyscope HS4 (br)
+	000e  Handyscope HS4 Diff
+	000f  Handyscope HS4 Diff (br)
+	0010  Handyscope HS2
+	0018  Handyprobe HP2
+	0042  TiePieSCOPE HS801
+	00fd  USB To Parallel adapter
+	00fe  USB To Parallel adapter
+0e38  Stratitec, Inc.
+0e39  Smart Modular Technologies, Inc.
+	0137  Bluetooth Device
+0e3a  Neostar Technology Co., Ltd
+	1100  CW-1100 Wireless Network Adapter
+0e3b  Mansella, Ltd
+0e41  Line6, Inc.
+	4250  BassPODxt
+	4252  BassPODxt Pro
+	4642  BassPODxt Live
+	4650  PODxt Live
+	4750  GuitarPort
+	5044  PODxt
+	5050  PODxt Pro
+	534d  SeaMonkey
+0e44  Sun-Riseful Technology Co., Ltd.
+0e48  Julia Corp., Ltd
+	0100  CardPro SmartCard Reader
+0e4a  Shenzhen Bao Hing Electric Wire & Cable Mfr. Co.
+0e4c  Radica Games, Ltd
+0e55  Speed Dragon Multimedia, Ltd
+	110b  MS3303H USB-to-Serial Bridge
+0e56  Kingston Technology Company, Inc.
+	6021  K-PEX 100
+0e5a  Active Co., Ltd
+0e5b  Union Power Information Industrial Co., Ltd
+0e5c  Bitland Information Technology Co., Ltd
+	6118  LCD Device
+	6119  remote receive and control device
+	6441  C-Media Sound Device
+0e5d  Neltron Industrial Co., Ltd
+0e66  Hawking
+	400b  UF100 10/100 Network Adapter
+	400c  UF100 Ethernet [pegasus2]
+0e67  Fossil, Inc.
+	0002  Wrist PDA
+0e6a  Megawin Technology Co., Ltd
+0e70  Tokyo Electronic Industry Co., Ltd
+0e72  Hsi-Chin Electronics Co., Ltd
+0e75  TVS Electronics, Ltd
+0e79  Archos, Inc.
+	1106  Pocket Medai Assistant - PMA400
+0e7b  On-Tech Industry Co., Ltd
+0e7e  Gmate, Inc.
+	0001  Yopy 3000 PDA
+	1001  YP3X00 PDA
+0e82  Ching Tai Electric Wire & Cable Co., Ltd
+0e83  Shin An Wire & Cable Co.
+0e8c  Well Force Electronic Co., Ltd
+0e8d  MediaTek Inc.
+0e8f  GreenAsia Inc.
+	0012  Joystick
+0e90  WiebeTech, LLC
+	0100  Storage Adapter V1
+0e91  VTech Engineering Canada, Ltd
+0e92  C's Glory Enterprise Co., Ltd
+0e93  eM Technics Co., Ltd
+0e95  Future Technology Co., Ltd
+0e96  Aplux Communications, Ltd
+	c001  TRUST 380 USB2 SPACEC@M
+0e97  Fingerworks, Inc.
+0e98  Advanced Analogic Technologies, Inc.
+0e99  Parallel Dice Co., Ltd
+0e9a  TA HSING Industries, Ltd
+0e9b  ADTEC Corp.
+0e9c  Streamzap, Inc.
+	0000  Streamzap Remote Control
+0e9f  Tamura Corp.
+0ea0  Ours Technology, Inc.
+	2126  7-in-1 Card Reader
+	2168  Transcend JetFlash 2.0 / Astone USB Drive
+	6803  OTI-6803 Flash Disk
+	6808  OTI-6808 Flash Disk
+	6828  OTI-6828 Flash Disk
+0ea6  Nihon Computer Co., Ltd
+0ea7  MSL Enterprises Corp.
+0ea8  CenDyne, Inc.
+0ead  Humax Co., Ltd
+0eb0  NovaTech
+	9020  NovaTech NV-902W
+	9021  RT2573
+0eb1  WIS Technologies, Inc.
+	6666  WinFast WalkieTV TV Loader
+	6668  WinFast WalkieTV TV Loader
+	7007  WinFast WalkieTV WDM Capture
+0eb2  Y-S Electronic Co., Ltd
+0eb3  Saint Technology Corp.
+0eb7  Endor AG
+0ebe  VWeb Corp.
+0ebf  Omega Technology of Taiwan, Inc.
+0ec0  LHI Technology (China) Co., Ltd
+0ec1  Abit Computer Corp.
+0ec2  Sweetray Industrial, Ltd
+0ec3  Axell Co., Ltd
+0ec4  Ballracing Developments, Ltd
+0ec5  GT Information System Co., Ltd
+0ec6  InnoVISION Multimedia, Ltd
+0ec7  Theta Link Corp.
+	1008  So., Show 301 Digital Camera
+0ecd  Lite-On IT Corp.
+	1400  CD\RW 40X
+0ece  TaiSol Electronics Co., Ltd
+0ecf  Phogenix Imaging, LLC
+0ed1  WinMaxGroup
+	6660  USB Flash Disk 64M-C
+	6680  USB Flash Disk 64M-B
+	7634  MP3 Player
+0ed2  Kyoto Micro Computer Co., Ltd
+0ed3  Wing-Tech Enterprise Co., Ltd
+0ed5  Fiberbyte
+	e000  USB-inSync Device
+	f000  Fiberbyte USB-inSync Device
+	f201  Fiberbyte USB-inSync DAQ-2500X
+0eda  Noriake Itron Corp.
+0edf  e-MDT Co., Ltd
+	2060  FID irock! 100 Series
+0ee0  Shima Seiki Mfg., Ltd
+0ee1  Sarotech Co., Ltd
+0ee2  AMI Semiconductor, Inc.
+0ee3  ComTrue Technology Corp.
+	1000  Image Tank 1.5
+0ee4  Sunrich Technology, Ltd
+0eee  Digital Stream Technology, Inc.
+	8810  Mass Storage Drive
+0eef  D-WAV Scientific Co., Ltd
+	0001  eGalax TouchScreen
+	0002  Touchscreen Controller(Professional)
+0ef0  Hitachi Cable, Ltd
+0ef1  Aichi Micro Intelligent Corp.
+0ef2  I/O Magic Corp.
+0ef3  Lynn Products, Inc.
+0ef4  DSI Datotech
+0ef5  PointChips
+	2202  Flash Disk
+	2366  Flash Disk
+0ef6  Yield Microelectronics Corp.
+0ef7  SM Tech Co., Ltd (Tulip)
+0efd  Oasis Semiconductor
+0efe  Wem Technology, Inc.
+0f06  Visual Frontier Enterprise Co., Ltd
+0f08  CSL Wire & Plug (Shen Zhen) Co.
+0f0c  CAS Corp.
+0f0d  Hori Co., Ltd
+0f0e  Energy Full Corp.
+0f12  Mars Engineering Corp.
+0f13  Acetek Technology Co., Ltd
+0f19  Oracom Co., Ltd
+0f1b  Onset Computer Corp.
+0f1c  Funai Electric Co., Ltd
+0f1d  Iwill Corp.
+0f21  IOI Technology Corp.
+0f22  Senior Industries, Inc.
+0f23  Leader Tech Manufacturer Co., Ltd
+0f24  Flex-P Industries, Snd., Bhd.
+0f2d  ViPower, Inc.
+0f2e  Geniality Maple Technology Co., Ltd
+0f2f  Priva Design Services
+0f30  Jess Technology Co., Ltd
+	001c  PS3 Guitar Controller Dongle
+	0110  10-Button Joypad
+0f31  Chrysalis Development
+0f32  YFC-BonEagle Electric Co., Ltd
+0f37  Kokuyo Co., Ltd
+0f38  Nien-Yi Industrial Corp.
+0f3d  Airprime, Incorporated
+	0112  CDMA 1xEVDO PC Card, PC 5220
+0f41  RDC Semiconductor Co., Ltd
+0f42  Nital Consulting Services, Inc.
+0f44  Polhemus
+	ef11  Patriot (firmware not loaded)
+	ef12  Patriot
+	ff11  Liberty (firmware not loaded)
+	ff12  Liberty
+0f4b  St. John Technology Co., Ltd
+0f4c  WorldWide Cable Opto Corp.
+0f4d  Microtune, Inc.
+	1000  Bluetooth Dongle
+0f4e  Freedom Scientific
+0f52  Wing Key Electrical Co., Ltd
+0f53  Dongguan White Horse Cable Factory, Ltd
+0f54  Kawai Musical Instruments Mfg. Co., Ltd
+0f55  AmbiCom, Inc.
+0f5c  Prairiecomm, Inc.
+0f5d  NewAge International, LLC
+	9455  Compact Drive
+0f5f  Key Technology Corp.
+0f60  NTK, Ltd
+0f61  Varian, Inc.
+0f62  Acrox Technologies Co., Ltd
+	1001  Targus Mini Trackball Optical Mouse
+0f68  Kobe Steel, Ltd
+0f69  Dionex Corp.
+0f6a  Vibren Technologies, Inc.
+0f6e  INTELLIGENT SYSTEMS
+	0100  GameBoy Color Emulator
+	0201  GameBoy Advance Flash Gang Writer
+	0202  GameBoy Advance Capture
+	0300  Gamecube DOL Viewer
+	0400  NDS Emulator
+	0401  NDS UIC
+	0402  NDS Writer
+	0403  NDS Capture
+	0404  NDS Emulator (Lite)
+0f73  DFI
+0f7c  DQ Technology, Inc.
+0f7d  NetBotz, Inc.
+0f7e  Fluke Corp.
+0f88  VTech Holdings, Ltd
+	3012  RT2570
+	3014  ZD1211B
+0f8b  Yazaki Corp.
+0f8c  Young Generation International Corp.
+0f8d  Uniwill Computer Corp.
+0f8e  Kingnet Technology Co., Ltd
+0f8f  Soma Networks
+0f97  CviLux Corp.
+0f98  CyberBank Corp.
+0f9c  Hyun Won, Inc.
+	0301  M-Any Premium DAH-610 MP3/WMA Player
+	0332  mobiBLU DAH-1200 MP3/Ogg Player
+0f9e  Lucent Technologies
+0fa3  Starconn Electronic Co., Ltd
+0fa4  ATL Technology
+0fa5  Sotec Co., Ltd
+0fa7  Epox Computer Co., Ltd
+0fa8  Logic Controls, Inc.
+0faf  Winpoint Electronic Corp.
+0fb0  Haurtian Wire & Cable Co., Ltd
+0fb1  Inclose Design, Inc.
+0fb2  Juan-Chern Industrial Co., Ltd
+0fb8  Wistron Corp.
+	0002  eHome Infrared Receiver
+0fb9  AACom Corp.
+0fba  San Shing Electronics Co., Ltd
+0fbb  Bitwise Systems, Inc.
+0fc1  Mitac Internatinal Corp.
+0fc2  Plug and Jack Industrial, Inc.
+0fc5  Delcom Engineering
+	1222  I/O Development Board
+0fc6  Dataplus Supplies, Inc.
+0fca  Research In Motion, Ltd.
+	0001  Blackberry Handheld
+0fce  Sony Ericsson Mobile Communications AB
+	1010  WMC Modem
+	d008  V800-Vodafone 802SE WMC Modem
+	d016  K750i Phone
+	d017  K608i Phone
+	d019  VDC EGPRS Modem
+	d025  520 WMC Data Modem
+	d038  W850i Phone
+	d041  K510i Phone
+	d042  W810i Phone
+	d046  K610i Phone
+0fcf  Dynastream Innovations, Inc.
+0fd0  Tulip Computers B.V.
+0fd1  Giant Electronics Ltd.
+0fd4  Tenovis GmbH & Co., KG
+0fd5  Direct Access Technology, Inc.
+0fdc  Micro Plus
+0fe4  IN-Tech Electronics, Ltd
+0fe5  Greenconn (U.S.A.), Inc.
+0fe9  DVICO
+	db00  FusionHDTV DVB-T (MT352+LgZ201) (uninitialized)
+	db01  FusionHDTV DVB-T (MT352+LgZ201) (initialized)
+	db10  FusionHDTV DVB-T (MT352+Thomson7579) (uninitialized)
+	db11  FusionHDTV DVB-T (MT352+Thomson7579) (initialized)
+0fea  United Computer Accessories
+0feb  CRS Electronic Co., Ltd
+0fec  UMC Electronics Co., Ltd
+0fed  Access Co., Ltd
+0fee  Xsido Corp.
+0fef  MJ Research, Inc.
+0ff6  Core Valley Co., Ltd
+0ff7  CHI SHING Computer Accessories Co., Ltd
+0fff  Aopen, Inc.
+1000  Speed Tech Corp.
+1001  Ritronics Components (S) Pte., Ltd
+1003  Sigma Corp.
+	0100  Sigma SD10
+1004  LG Electronics, Inc.
+	1fae  U8120 3G Cellphone
+	6000  VX4400/VX6000 Cellphone
+	6005  T5100
+	6800  CDMA Modem
+	7000  LG LDP-7024D(LD)USB
+1005  Apacer Technology, Inc.
+	1001  MP3 Player
+	1004  MP3 Player
+	1006  MP3 Player
+	b113  Handy Steno 2.0/HT203
+	b223  CD-RW + 6 in 1 Card Reader Digital Storage / Converter
+1006  iRiver, Ltd.
+	3001  iHP-100
+	3002  iHP-120/140 MP3 Player
+	3003  H320/H340
+	3004  H340 (mtp)
+1009  Emuzed, Inc.
+	000e  eHome Infrared Receiver
+	0013  Angel MPEG Device
+	0015  Lumanate Wave PAL SECAM DVBT Device
+	0016  Lumanate Wave NTSC/ATSC Combo Device
+100a  AV Chaseway, Ltd
+	2402  MP3 Player
+	2404  MP3 Player
+	2405  MP3 Player
+	2406  MP3 Player
+	a0c0  MP3 Player
+100b  Chou Chin Industrial Co., Ltd
+100d  Netopia, Inc.
+	3342  Cayman 3352 DSL Modem
+	3382  3380 Series Network Interface
+	cb01  Cayman 3341 Ethernet DSL Router
+1010  Fukuda Denshi Co., Ltd
+1011  Mobile Media Tech.
+	0001  AccFast Mp3
+1012  SDKM Fibres, Wires & Cables Berhad
+1013  TST-Touchless Sensor Technology AG
+1014  Densitron Technologies PLC
+1015  Softronics Pty., Ltd
+1016  Xiamen Hung's Enterprise Co., Ltd
+1017  Speedy Industrial Supplies, Pte., Ltd
+1019  Elitegroup Computer Systems (ECS)
+	0c55  USB Flash Reader, Desknote UCR-61S2B
+1020  Labtec
+	000a  Wireless Optical Mouse
+1022  Shinko Shoji Co., Ltd
+1025  Hyper-Paltek
+	005e  USB DVB-T device
+	005f  USB DVB-T device
+	0300  MP3 Player
+	0350  MP3 Player
+1026  Newly Corp.
+1027  Time Domain
+1028  Inovys Corp.
+1029  Atlantic Coast Telesys
+102a  Ramos Technology Co., Ltd
+102b  Infotronic America, Inc.
+102c  Etoms Electronics Corp.
+	6251  Q-Cam
+102d  Winic Corp.
+1031  Comax Technology, Inc.
+1032  C-One Technology Corp.
+1033  Nucam Corp.
+	0068  3,5'' HDD case MD-231
+1038  Ideazon, Inc.
+	0100  Zboard
+1039  devolo AG
+	2140  dsl+ 1100 duo
+103d  Stanton
+	0100  ScratchAmp
+	0101  ScratchAmp
+1043  iCreate Technologies Corp.
+	160f  Wireless Network Adapter
+	4901  AV-836 Video Capture Device
+	8006  Flash Disk 32-256 MB
+1044  Chu Yuen Enterprise Co., Ltd
+	7001  U7000 TV tuner device
+	8001  GN-54G
+	8002  GN-BR402W
+	8003  GN-WLBM101
+	8004  GN-WLBZ101 802.11b Adapter
+	8005  GN-WLBZ201 802.11b Adapter
+	8006  GN-WBZB-M 802.11b Adapter
+	8007  GN-WBKG
+	8008  GN-WB01GS
+	800a  GN-WI05GS
+	800b  GN-WB30N 802.11n WLAN Card
+1046  Winbond Electronics Corp. [hex]
+	8901  Bluetooth Device
+	9967  W9967CF/W9968CF WebCam IC
+1048  Targus Group International
+104c  AMCO TEC International, Inc.
+1053  Immanuel Electronics Co., Ltd
+1054  BMS International Beheer N.V.
+	5004  DSL 7420 Loader
+	5005  DSL 7420 LAN Modem
+1055  Complex Micro Interconnection Co., Ltd
+1056  Hsin Chen Ent Co., Ltd
+1057  ON Semiconductor
+1058  Western Digital Technologies, Inc.
+	0200  Firewire USB Combo
+	0400  External HDD
+	0500  hub
+	0702  Passport External HDD
+	0901  MyBook External HDD
+	1001  External Hard Disk
+1059  Giesecke & Devrient GmbH
+	000b  StarSign Bio Token 3.0
+105c  Hong Ji Electric Wire & Cable (Dongguan) Co., Ltd
+105d  Delkin Devices, Inc.
+105e  Valence Semiconductor Design, Ltd
+105f  Chin Shong Enterprise Co., Ltd
+1060  Easthome Industrial Co., Ltd
+1063  Motorola Electronics Taiwan, Ltd [hex]
+	1555  MC141555 Hub
+	4100  SB4100 USB Cable Modem
+1065  CCYU Technology
+	0020  USB-DVR2 Dev Board
+	2136  EasyDisk ED1064
+106a  Loyal Legend, Ltd
+106c  Curitel Communications, Inc.
+	1101  CDMA 2000 1xRTT USB modem (HX-550C)
+	1102  Packet Service
+	1103  Packet Service Diagnostic Serial Port (WDM)
+	1104  Packet Service Diagnostic Serial Port (WDM)
+	1105  Composite Device
+	1106  Packet Service Diagnostic Serial Port (WDM)
+	1301  Composite Device
+	1302  Packet Service Diagnostic Serial Port (WDM)
+	1303  Packet Service
+	1304  Packet Service
+	1401  Composite Device
+	1402  Packet Service
+	1403  Packet Service Diagnostic Serial Port (WDM)
+	1501  Packet Service
+	1502  Packet Service Diagnostic Serial Port (WDM)
+	1503  Packet Service
+	1601  Packet Service
+	1602  Packet Service Diagnostic Serial Port (WDM)
+	1603  Packet Service
+	2101  AudioVox 8900 Cell Phone
+	2102  Packet Service
+	2103  Packet Service Diagnostic Serial Port (WDM)
+	2301  Packet Service
+	2302  Packet Service Diagnostic Serial Port (WDM)
+	2303  Packet Service
+	2401  Packet Service Diagnostic Serial Port (WDM)
+	2402  Packet Service
+	2403  Packet Service Diagnostic Serial Port (WDM)
+	2501  Packet Service
+	2502  Packet Service Diagnostic Serial Port (WDM)
+	2503  Packet Service
+	2601  Packet Service
+	2602  Packet Service Diagnostic Serial Port (WDM)
+	2603  Packet Service
+	3701  Broadband Wireless modem
+	3702  Pantech PX-500
+	3eb4  Packet Service Diagnostic Serial Port (WDM)
+	4101  Packet Service Diagnostic Serial Port (WDM)
+	4102  Packet Service
+	4301  Composite Device
+	4302  Packet Service Diagnostic Serial Port (WDM)
+	4401  Composite Device
+	4402  Packet Service
+	4501  Packet Service
+	4502  Packet Service Diagnostic Serial Port (WDM)
+	4601  Composite Device
+	4602  Packet Service Diagnostic Serial Port (WDM)
+	5101  Packet Service
+	5102  Packet Service Diagnostic Serial Port (WDM)
+	5301  Packet Service Diagnostic Serial Port (WDM)
+	5302  Packet Service
+	5401  Packet Service
+	5402  Packet Service Diagnostic Serial Port (WDM)
+	5501  Packet Service Diagnostic Serial Port (WDM)
+	5502  Packet Service
+	5601  Packet Service Diagnostic Serial Port (WDM)
+	5602  Packet Service
+	7101  Composite Device
+	7102  Packet Service
+	a000  Packet Service
+	a001  Packet Service Diagnostic Serial Port (WDM)
+	c100  Packet Service
+	c200  Packet Service
+	c500  Packet Service Diagnostic Serial Port (WDM)
+	e200  Packet Service
+106d  San Chieh Manufacturing, Ltd
+106e  ConectL
+106f  Money Controls
+1076  GCT Semiconductor, Inc.
+	0031  Bluetooth Device
+	0032  Bluetooth Device
+107d  Arlec Australia, Ltd
+107e  Midoriya Electric Co., Ltd
+107f  KidzMouse, Inc.
+1082  Shin-Etsukaken Co., Ltd
+1083  Canon Electronics, Inc.
+1084  Pantech Co., Ltd
+108a  Chloride Power Protection
+108b  Grand-tek Technology Co., Ltd
+108c  Robert Bosch GmbH
+108e  Lotes Co., Ltd.
+1099  Surface Optics Corp.
+109a  DATASOFT Systems GmbH
+109f  eSOL Co., Ltd
+	3163  Trigem Mobile SmartDisplay84
+	3164  Trigem Mobile SmartDisplay121
+10a0  Hirotech, Inc.
+10a3  Mitsubishi Materials Corp.
+10a9  SK Teletech Co., Ltd
+10aa  Cables To Go
+10ab  USI Co., Ltd
+	1002  Bluetooth Device
+	1003  BC02-EXT in DFU
+	1005  Bluetooth Adptr
+	1006  BC04-EXT in DFU
+	10c5  Sony-Ericsson / Samsung DataCable
+10ac  Honeywell, Inc.
+10ae  Princeton Technology Corp.
+10af  Liebert Corp.
+	0000  UPS
+	0001  PowerSure PSA UPS
+	0002  PowerSure PST UPS
+	0003  PowerSure PSP UPS
+	0004  PowerSure PSI UPS
+	0005  UPStation GXT 2U UPS
+	0006  UPStation GXT UPS
+	0007  Nfinity Power Systems UPS
+	0008  PowerSure Interactive UPS
+10b5  Comodo (PLX?)
+	9060  Test Board
+10b8  DiBcom
+	0bb8  DiBcom USB DVB-T reference design (MOD300) (cold)
+	0bb9  DiBcom USB DVB-T reference design (MOD300) (warm)
+	0bc6  DiBcom USB2.0 DVB-T reference design (MOD3000P) (cold)
+	0bc7  DiBcom USB2.0 DVB-T reference design (MOD3000P) (warm)
+10bb  TM Technology, Inc.
+10bc  Dinging Technology Co., Ltd
+10bd  TMT Technology, Inc.
+	1427  Ethernet
+10bf  SmartHome
+	0001  SmartHome PowerLinc
+10c4  Cygnal Integrated Products, Inc.
+	0002  F32x USBXpress Device
+	80a9  CP210x to UART Bridge Controller
+	80ca  ATM2400 Sensor Device
+	ea60  CP210x Composite Device
+10c5  Sanei Electric, Inc.
+10c6  Intec, Inc.
+10cb  Eratech
+10cc  GBM Connector Co., Ltd
+	1101  MP3 Player
+10cd  Kycon, Inc.
+10ce  Silicon Labs
+	ea6a  MobiData EDGE USB Modem
+10cf  Velleman Components, Inc.
+	5500  8055 Experiment Interface Board (address=0)
+	5501  8055 Experiment Interface Board (address=1)
+	5502  8055 Experiment Interface Board (address=2)
+	5503  8055 Experiment Interface Board (address=3)
+10d1  Hottinger Baldwin Measurement
+	0101  USB-Module for Spider8, CP32
+	0202  CP22 - Communication Processor
+	0301  CP42 - Communication Processor
+10d4  Man Boon Manufactory, Ltd
+10d5  Uni Class Technology Co., Ltd
+10d6  Actions Semiconductor Co., Ltd
+	1000  MP3 Player
+	1100  MPMan MP-Ki 128 MP3 Player/Recorder
+	1101  D-Wave 2GB MP4 Player
+	8888  ADFU Device
+	ff51  ADFU Device
+10de  Authenex, Inc.
+10df  In-Win Development, Inc.
+10e0  Post-Op Video, Inc.
+10e1  CablePlus, Ltd
+10e2  Nada Electronics, Ltd
+10ec  Vast Technologies, Inc.
+10f5  Turtle Beach
+	0200  Audio Advantage Roadie
+10fb  Pictos Technologies, Inc.
+10fd  Anubis Electronics, Ltd
+	804d  Typhoon Webshot II Webcam [zc0301]
+	8050  FlyCAM-USB 300 XP2
+	de00  WinFast WalkieTV WDM Capture Driver.
+1100  VirTouch, Ltd
+	0001  VTPlayer VTP-1 Braille Mouse
+1101  EasyPass Industrial Co., Ltd
+	0001  FSK Electronics Super GSM Reader
+1108  Brightcom Technologies, Ltd
+1110  Analog Devices Canada, Ltd (Allied Telesyn)
+	5c01  Huawei MT-882 Remote NDIS Network Device
+	6489  ADSL ETH/USB RTR
+	9000  ADSL LAN Adapter
+	9001  ADSL Loader
+	900f  AT-AR215 DSL Modem
+	9010  AT-AR215 DSL Modem
+	9021  ADSL WAN Adapter
+	9022  ADSL Loader
+	9023  ADSL WAN Adapter
+	9024  ADSL Loader
+	9031  ADSL LAN Adapter
+	9032  ADSL Loader
+1111  Pandora International Ltd.
+	8888  Evolution Device
+1112  YM ELECTRIC CO., Ltd
+1113  Medion AG
+111e  VSO Electric Co., Ltd
+112e  Master Hill Electric Wire and Cable Co., Ltd
+112f  Cellon International, Inc.
+1130  Tenx Technology, Inc.
+	f211  USB audio headset
+1131  Integrated System Solution Corp.
+	1001  KY-BT100 Bluetooth Adapter
+	1002  Bluetooth Device
+	1003  Bluetooth Device
+	1004  Bluetooth Device
+1132  Toshiba Corp., Digital Media Equipment [hex]
+	4331  PDR-M4/M5/M70 Digital Camera
+	4332  PDR-M60 Digital Camera
+	4333  PDR-M2300/PDR-M700
+	4334  PDR-M65
+	4335  PDR-M61
+	4337  PDR-M11
+	4338  PDR-M25
+113c  Arin Tech Co., Ltd
+113d  Mapower Electronics Co., Ltd
+1141  V One Multimedia, Pte., Ltd
+1142  CyberScan Technologies, Inc.
+1145  Japan Radio Company
+	0001  AirH PHONE AH-J3001V/J3002V
+1146  Shimane SANYO Electric Co., Ltd.
+1147  Ever Great Electric Wire and Cable Co., Ltd
+114b  Sphairon Access Systems GmbH
+	0110  Turbolink UB801R WLAN USB Adapter
+114c  Tinius Olsen Testing Machine Co., Inc.
+114d  Alpha Imaging Technology Corp.
+115b  Salix Technology Co., Ltd.
+1162  Secugen Corp.
+1163  DeLorme Publishing, Inc.
+	0100  Earthmate GPS
+1164  YUAN High-Tech Development Co., Ltd
+	0300  ELSAVISION 460D
+	0601  Analog TV Tuner
+	0900  TigerBird BMP837 USB2.0 WDM Encoder
+	0bc7  Digital TV Tuner
+1165  Telson Electronics Co., Ltd
+1166  Bantam Interactive Technologies
+1167  Salient Systems Corp.
+1168  BizConn International Corp.
+116e  Gigastorage Corp.
+116f  Silicon 10 Technology Corp.
+1175  Shengyih Steel Mold Co., Ltd
+117d  Santa Electronic, Inc.
+117e  JNC, Inc.
+1182  Venture Corp., Ltd
+1183  Compaq Computer Corp. [hex] (Digital Dream ??)
+	0001  DigitalDream l'espion XS
+	19c7  ISDN TA
+	4008  56k FaxModem
+	504a  PJB-100 Personal Jukebox
+1184  Kyocera Elco Corp.
+1188  Bloomberg L.P.
+1189  Acer Communications & Multimedia
+	0893  EP-1427X-2 Ethernet Adapter
+118f  You Yang Technology Co., Ltd
+1190  Tripace
+1191  Loyalty Founder Enterprise Co., Ltd
+1196  Yankee Robotics, LLC
+	0010  Trifid Camera without code
+	0011  Trifid Camera
+1197  Technoimagia Co., Ltd
+1198  StarShine Technology Corp.
+1199  Sierra Wireless, Inc.
+	0019  AC595U
+	0021  AC597E
+	0110  Composite Device
+	0112  CDMA 1xEVDO PC Card, AirCard 580
+	0120  AC595U
+	0218  MC5720 Wireless Modem
+	6467  MP Series Network Adapter
+	6468  MP Series Network Adapter
+	6469  MP Series Network Adapter
+	6802  MC8755 Device
+	6803  MC8765 Device
+	6804  MC8755 Device
+	6805  MC8765 Device
+	6812  MC8775 Device
+	6820  AC875 Device
+	6832  MC8780 Device
+	6833  MC8781 Device
+	683a  MC8785 Device
+	6850  AirCard 880 Device
+	6851  AirCard 881 Device
+	6852  AirCard 880E Device
+	6853  AirCard 881E Device
+	6854  AirCard 885 Device
+	6870  MC8780 Device
+	6871  MC8781 Device
+119a  ZHAN QI Technology Co., Ltd
+119b  ruwido austria GmbH
+	0400  Infrared Keyboard V2.01
+11a0  Chipcon AS
+	eb11  CC2400EB 2.0 ZigBee Sniffer
+11a3  Technovas Co., Ltd
+	8031  MP3 Player
+	8032  MP3 Player
+11aa  GlobalMedia Group, LLC
+	1518  iREZ K2
+11ab  Exito Electronics Co., Ltd
+11b0  ATECH FLASH TECHNOLOGY
+11db  Topfield Co., Ltd.
+	1000  PVR
+	1100  PVR
+11e6  K.I. Technology Co. Ltd.
+11f5  Siemens AG (?)
+	0001  SX1
+	0003  Mobile phone USB cable
+	0004  X75
+11f6  Prolific
+	2001  Willcom WSIM
+11f7  Alcatel (?)
+	02df  TD10 Mobile phone USB cable
+1209  InterBiometrics
+	1001  USB Hub
+	1002  USB Relais
+	1003  IBSecureCam-P
+	1004  IBSecureCam-O
+	1005  IBSecureCam-N
+120e  Hudson Soft Co., Ltd
+121e  Jungsoft Co., Ltd
+	3403  Muzio JM250 Audio Player
+1223  SKYCABLE ENTERPRISE. CO., LTD.
+1230  Chipidea-Microelectronica, S.A.
+1235  Novation EMS
+	0001  ReMOTE Audio/XStation
+	0002  Speedio
+	4661  ReMOTE25
+1241  Belkin
+	1111  Mouse
+	1122  Typhoon Stream Optical Mouse USB+PS/2
+	1155  PS2/USB Browser Combo Mouse
+	1166  MI-2150 Trust Mouse
+	1177  F8E842-DL Mouse
+	1503  Keyboard
+124a  AirVast
+	4017  PC-Chips 802.11b Adapter
+124b  Nyko (Honey Bee)
+	4d01  Airflo EX Joystick
+125f  A-DATA Technology Co., Ltd.
+1264  Covidien Energy-based Devices
+1267  Logic3 / SpectraVideo plc
+	0103  G-720 Keyboard
+	0201  A4Tech SWOP-3 Mouse
+	a001  JP260 PC Game Pad
+	c002  Wireless Optical Mouse
+126c  Aristocrat Technologies
+126d  Bel Stewart
+126e  Strobe Data, Inc.
+126f  TwinMOS
+	1325  Mobile Disk
+	2168  Mobile Disk III
+	a006  G240
+1275  Xaxero Marine Software Engineering, Ltd.
+	0002  WeatherFax 2000 Demodulator
+	0080  SkyEye Weather Satellite Receiver
+1286  Marvell Semiconductor, Inc.
+	8001  BLOB boot loader firmware
+1292  Innomedia
+	0258  Creative Labs VoIP Blaster
+1293  Belkin Components [hex]
+	0002  F5U002 Parallel Port [uss720]
+	2101  104-key keyboard
+1294  RISO KAGAKU CORP.
+129b  CyberTAN Technology
+	1666  TG54USB
+12a7  Trendchip Technologies Corp.
+12ab  Honey Bee Electronic International Ltd.
+12ba  Licensed by Sony Computer Entertainment America
+	0200  Harmonix Guitar for PlayStation(R)3
+	0210  Harmonix Drum Kit for PlayStation(R)3
+12d1  Huawei Technologies Co., Ltd.
+	1001  E620 USB Modem
+	1003  E220 HSDPA Modem / E270 HSDPA/HSUPA Modem
+12d2  LINE TECH INDUSTRIAL CO., LTD.
+12d7  BETTER WIRE FACTORY CO., LTD.
+12ef  Tapwave, Inc.
+	0100  Tapwave Handheld [Tapwave Zodiac]
+12f5  Dynamic System Electronics Corp.
+12f7  Memorex Products, Inc.
+	1a00  TD Classic 003B
+	1e23  TravelDrive 2007 Flash Drive
+12fd  AIN Comm. Technology Co., Ltd
+	1001  AWU2000b 802.11b Stick
+1307  Transcend Information, Inc.
+	0163  512MB USB Flash Drive
+	1169  TS2GJF210 JetFlash 210 2GB
+1310  Roper
+	0001  Class 1 Bluetooth Dongle
+1312  ICS Electronics
+131d  Natural Point
+	0155  TrackIR 3 Pro Head Tracker
+132b  Konica Minolta
+	0000  Dimage A2 Camera
+	0001  Minolta DiMAGE A2 (ptp)
+	0003  Dimage Xg Camera
+	0006  Dimage Z2 Camera
+	0007  Minolta DiMAGE Z2 (PictBridge mode)
+	0008  Dimage X21 Camera
+	000a  Dimage Scan Dual IV
+	000b  Dimage Z10 Camera
+	000d  Dimage X50 Camera [storage?]
+	000f  Dimage X50 Camera [p2p?]
+	0010  Dimage G600 Camera
+	0012  Dimage Scan Elite5400 2
+	0013  Dimage X31 Camera
+	0015  Dimage G530 Camera
+	0017  Dimage Z3 Camera
+	0018  Minolta DiMAGE Z3 (PictBridge mode)
+	0019  Dimage A200 Camera
+	0021  Dimage Z5 Camera
+	0022  Minolta DiMAGE Z5 (PictBridge mode)
+1342  Mobility
+	0200  EasiDock 200 Hub
+	0201  EasiDock 200 Keyboard and Mouse Port
+	0202  EasiDock 200 Serial Port
+	0203  EasiDock 200 Printer Port
+	0204  Ethernet
+	0304  EasiDock Ethernet
+1348  Katsuragawa Electric Co., Ltd.
+134e  Digby's Bitpile, Inc. DBA D Bit
+136b  STEC
+1370  Swissbit
+	6828  Victorinox Flash Drive
+1371  Dick Smith Electronics
+	9022  RT2573
+	9032  C-Net CWD-854 rev F
+1376  Vimtron Electronics Co., Ltd.
+1385  Netgear, Inc
+	4250  WG111T
+	4251  WG111T (no firmware)
+	5f00  WPN111 RangeMax(TM) Wireless USB 2.0 Adapter
+	5f01  WPN111 (no firmware)
+138e  Jungo LTD
+	9000  Raisonance S.A. STM32 ARM evaluation board
+1390  TOMTOM B.V.
+1395  Sennheiser Communications
+	3556  USB Headset
+1398  Q-tec
+	2103  USB 2.0 Storage Device
+13ad  Baltech
+	9999  Card reader
+13b0  PerkinElmer Optoelectronics
+	000a  Alesis Photon X25 MIDI Controller
+13b1  Linksys
+	000b  WUSB11 v4.0 802.11b Adapter
+	000d  WUSB54G Wireless Adapter
+	0011  WUSB54GP v4.0 802.11g Adapter
+	0018  USB200M 10/100 Ethernet Adapter
+	001a  HU200TS Wireless Adapter
+	0020  WUSB54GC 802.11g Adapter [ralink rt73]
+	0023  WUSB54GR
+	0024  WUSBF54G v1.1 802.11g Adapter w/ Wi-Fi Finder
+13b3  Nippon Dics Co., Ltd.
+13be  Ricoh Printing Systems, Ltd.
+13ca  JyeTai Precision Industrial Co., Ltd.
+13cf  Wisair Ltd.
+13d1  A-Max Technology Macao Commercial Offshore Co. Ltd.
+13d2  Shark Multimedia
+	0400  Pocket Ethernet [klsi]
+13d3  IMC Networks
+	3201  VisionDTV USB-Ter/HAMA USB DVB-T device cold
+	3202  VisionDTV USB-Ter/HAMA USB DVB-T device warm
+	3203  DTV-DVB UDST7020BDA DVB-S Box(DVBS for MCE2005)
+	3204  DTV-DVB UDST7020BDA DVB-S Box(DVBS for MCE2005)
+	3205  DNTV Live! Tiny USB2 BDA (No Remote)
+	3206  DNTV Live! Tiny USB2 BDA (No Remote)
+	3207  DTV-DVB UDST7020BDA DVB-S Box(DVBS for MCE2005)
+	3208  DTV-DVB UDST7020BDA DVB-S Box(DVBS for MCE2005)
+	3209  DTV-DVB UDST7022BDA DVB-S Box(Without HID)
+	3211  DTV-DVB Hybrid Analog/Capture / Pinnacle PCTV 310e
+	3212  DTV-DVB UDTT704C - DVBT/NTSC/PAL Driver(PCM4)
+	3213  DTV-DVB UDTT704D - DVBT/NTSC/PAL Driver (PCM4)
+	3214  DTV-DVB UDTT704F -(MiniCard) DVBT/NTSC/PAL Driver(Without HID)
+	3215  DTV-DVB UDAT7240 - ATSC/NTSC/PAL Driver(PCM4)
+	3216  DTV-DVB UDTT 7047-USB 2.0 DVB-T Driver
+	3217  Digital-TV Receiver.
+	3219  DTV-DVB UDTT7049 - DVB-T Driver(Without HID)
+	3220  DTV-DVB UDTT 7047M-USB 2.0 DVB-T Driver
+	3223  DNTV Live! Tiny USB2 BDA (No Remote)
+	3224  DNTV Live! Tiny USB2 BDA (No Remote)
+	3226  DigitalNow TinyTwin DVB-T Receiver
+	3236  DTV-DVB UDTT 7047A-USB 2.0 DVB-T Driver
+	3237  DTV-DVB UDTT 704J - dual DVB-T Driver
+	3239  DTV-DVB UDTT704D - DVBT/NTSC/PAL Driver(Without HID)
+	3240  DTV-DVB UDXTTM6010 - A/D Driver(Without HID)
+	3241  DTV-DVB UDXTTM6010 - A/D Driver(Without HID)
+	3242  DTV-DVB UDAT7240LP - ATSC/NTSC/PAL Driver(Without HID)
+	3243  DTV-DVB UDXTTM6010 - A/D Driver(Without HID)
+	3244  DTV-DVB UDTT 7047Z-USB 2.0 DVB-T Driver
+	3247  802.11 n/g/b Wireless LAN Adapter
+	7020  DTV-DVB UDST7020BDA DVB-S Box(DVBS for MCE2005)
+	7022  DTV-DVB UDST7022BDA DVB-S Box(Without HID)
+13dc  ALEREON, INC.
+13dd  i.Tech Dynamic Limited
+13e1  Kaibo Wire & Cable (Shenzhen) Co., Ltd.
+13e5  Rane
+	0001  SL-1
+13e6  TechnoScope Co., Ltd.
+13fd  Initio Corporation
+13fe  Kingston Technology Company Inc.
+	1a00  512MB/1GB Flash Drive
+	1a23  512MB Flash Drive
+	1d00  DataTraveler 2.0 1GB/4GB Flash Drive / Patriot Xporter 4GB Flash Drive
+	1f00  DataTraveler 2.0 4GB Flash Drive
+1400  Axxion Group Corp.
+1402  Bowe Bell & Howell
+1403  Sitronix
+	0001  Digital Photo Frame
+140e  Telechips, Inc.
+1410  Novatel Wireless
+	1110  Merlin S620
+	1120  Merlin EX720
+	1130  Merlin S720
+	1400  Merlin U740
+	2110  Ovation U720/MCD3000
+	4100  U727
+1415  Nam Tai E&E Products Ltd. or OmniVision Technologies, Inc.
+	0000  Sony SingStar USBMIC
+	2000  Sony Playstation Eye
+1419  ABILITY ENTERPRISE CO., LTD.
+1429  Vega Technologies Industrial (Austria) Co.
+1430  RedOctane
+1431  Pertech Resources, Inc.
+1435  Wistron NeWeb
+	0711  UR055G
+	0826  AR5523
+	0827  AR5523 (no firmware)
+	0828  AR5523
+	0829  AR5523 (no firmware)
+1436  Denali Software, Inc.
+143c  Altek Corporation
+1453  Radio Shack
+	4026  26-183 Serial Cable
+1456  Extending Wire & Cable Co., Ltd.
+1457  First International Computer, Inc.
+	5117  OpenMoko Neo1973 kernel usbnet (g_ether, CDC Ethernet) mode
+	5118  OpenMoko Neo1973 Debug board (V2+)
+	5119  OpenMoko Neo1973 u-boot cdc_acm serial port
+	5120  OpenMoko Neo1973 u-boot usbtty generic serial
+	5121  OpenMoko Neo1973 kernel mass storage (g_storage) mode
+	5122  OpenMoko Neo1973 kernel cdc_ether USB network
+	5123  OpenMoko Neo1973 internal USB CSR4 module
+	5124  OpenMoko Neo1973 Bluetooth Device ID service
+1461  Staccato Communications
+1462  Micro Star International
+	5512  MegaStick-1 Flash Stick
+1472  Huawei-3Com
+	0009  Aolynk WUB320g
+147a  Formosa Industrial Computing, Inc.
+	e015  eHome Infrared Receiver
+	e016  eHome Infrared Receiver
+147f  Hama GmbH & Co., KG
+1484  Elsa AG [hex]
+	1746  Ecomo 19H99 Monitor
+	7616  Elsa Hub
+1485  Silicom
+	0001  U2E
+	0002  Psion Gold Port Ethernet
+1487  DSP Group, Ltd.
+148e  EVATRONIX SA
+148f  Ralink Technology, Corp.
+	1706  RT2500USB Wireless Adapter
+	2570  802.11g WiFi
+	2573  RT2501USB Wireless Adapter
+	2671  RT2601USB Wireless Adapter
+	9020  RT2500USB Wireless Adapter
+	9021  RT2501USB Wireless Adapter
+1497  Panstrong Company Ltd.
+149a  Imagination Technologies
+	2107  DBX1 DSP core
+14aa  AVerMedia (again) or C&E
+	0001  Avermedia AverTV DVBT USB1.1 (cold)
+	0002  Avermedia AverTV DVBT USB1.1 (warm)
+	0201  AVermedia/Yakumo/Hama/Typhoon DVB-T USB2.0 (cold)
+	0221  AVermedia DVBT Tuner Dongle
+	0301  AVermedia/Yakumo/Hama/Typhoon DVB-T USB2.0 (warm)
+14ad  CTK Corporation
+14ae  Printronix Inc.
+14af  ATP Electronics Inc.
+14b0  StarTech.com Ltd.
+14b2  Atheros Communications Inc
+	3a93  USB WLAN Device
+	3c02  C54RU WLAN
+	3c22  C54RU
+14c0  Rockwell Automation, Inc.
+14c2  Gemlight Computer, Ltd
+	0250  Storage Adapter V2
+	0350  Storage Adapter V2
+14cd  Super Top
+	6600  USB 2.0 IDE DEVICE
+14d8  JAMER INDUSTRIES CO., LTD.
+14dd  Raritan Computer, Inc.
+14e5  SAIN Information & Communications Co., Ltd.
+14ea  Planex Communications
+	ab10  GW-US54GZ
+	ab11  GU-1000T
+	ab13  GW-US54Mini
+14ed  Shure Inc.
+1500  Ellisys
+1501  Pine-Tum Enterprise Co., Ltd.
+1513  Hypercom
+1516  CompUSA
+	8628  128M Pen Drive
+1518  Cheshire Engineering Corp.
+	0001  HDReye High Dynamic Range Camera
+	0002  HDReye (before firmware loads)
+1520  Bitwire Corp.
+1524  ENE Technology Inc
+	6680  UTS 6680
+1527  Silicon Portals
+	0200  YAP Phone (no firmware)
+	0201  YAP Phone
+1529  UBIQUAM Co., Ltd.
+	3100  CDMA 1xRTT USB Modem (U-100/105/200/300/520)
+152d  JMicron Technology Corp. / JMicron USA Technology Corp.
+	2338  JM20337 Hi-Speed USB to SATA & PATA Combo Bridge
+152e  LG (HLDS)
+	e001  GSA-5120D DVD-RW
+1532  Razer USA, Ltd
+	0001  RZ01-020300 Optical Mouse [Diamondback]
+	0003  Krait Mouse
+	0007  DeathAdder Mouse
+	0102  Tarantula Keyboard
+1546  U-Blox AG
+154b  PNY
+	0010  USB 2.0 Flash Drive
+154d  ConnectCounty Holdings Berhad
+154e  D&M Holdings, Inc. (Denon/Marantz)
+	3000  Marantz RC9001 Remote Control
+1554  Prolink Microsystems Corp.
+1557  OQO
+	0002  model 01 WiFi interface
+	0003  model 01 Bluetooth interface
+	7720  model 01+ Ethernet
+	8150  model 01 Ethernet interface
+1568  Sunf Pu Technology Co., Ltd
+156f  Quantum Corporation
+1570  ALLTOP TECHNOLOGY CO., LTD.
+157b  Ketron SRL
+157e  TRENDnet
+	3006  TEW-444UB EU
+	3007  TEW-444UB EU (no firmware)
+	300a  TEW-429UB 802.11g Adapter with HotSpot Detector
+	300b  TEW-429UB
+	300d  TEW-429UB C1
+	3204  ALL0298 v2
+	3205  AR5523
+	3206  AR5523 (no firmware)
+1582  Fiberline
+	6003  WL-430U
+1587  SMA Technologie AG
+158d  Oakley Inc.
+1598  Kunshan Guoji Electronics Co., Ltd.
+15a2  Freescale Semiconductor, Inc.
+15a8  Teams Power Limited
+15aa  Gearway Electronics (Dong Guan) Co., Ltd.
+15ba  Olimex Ltd.
+	0003  OpenOCD JTAG
+	0004  OpenOCD JTAG TINY
+15c2  SoundGraph Inc.
+	ffdc  iMON PAD Remote Controller
+15c6  Laboratoires MXM
+	1000  DigistimSP (cold)
+	1001  DigistimSP (warm)
+	1002  DigimapSP USB (cold)
+	1003  DigimapSP USB (warm)
+15c9  D-Box Technologies
+15ca  Textech International Ltd.
+	00c3  Mini Optical Mouse
+15d5  Coulomb Electronics Ltd.
+15dc  Hynix Semiconductor Inc.
+15e0  Seong Ji Industrial Co., Ltd.
+15e1  RSA
+	2007  RSA SecurID (R) Authenticator
+15e8  SohoWare
+	9100  NUB100 Ethernet [pegasus]
+	9110  10/100 USB Ethernet
+15e9  Pacific Digital Corp.
+	04ce  MemoryFrame MF-570
+	1968  MemoryFrame MF-570
+	1969  Digital Frame
+15ec  Belcarra Technologies Corp.
+15f4  HanfTek
+	0001  HanfTek UMT-010 USB2.0 DVB-T (cold)
+	0025  HanfTek UMT-010 USB2.0 DVB-T (warm)
+1604  Tascam
+	8000  US-428 Audio/Midi Controller (without fw)
+	8001  US-428 Audio/Midi Controller
+	8004  US-224 Audio/Midi Controller (without fw)
+	8005  US-224 Audio/Midi Controller
+	8006  US-122 Audio/Midi Interface (without fw)
+	8007  US-122 Audio/Midi Interface
+1606  Umax [hex]
+	0002  Astra 1236U Scanner
+	0010  Astra 1220U
+	0030  Astra 2000U
+	0050  Scanner
+	0060  Astra 3400U
+	0130  Astra 2100U
+	0160  Astra 5400U
+	0230  Astra 2200/2200SU
+	0350  Astra 4800/4850 Scanner
+	1030  Astra 4000U
+	1220  Genesys Logic Scanner Controller NT5.0
+	2010  AstraCam Digital Camera
+	2020  AstraCam 1000
+	2030  AstraCam 1800 Digital Camera
+1608  Inside Out Networks [hex]
+	0001  EdgePort/4 Serial Port
+	0002  Edgeport/8
+	0003  Rapidport/4
+	0004  Edgeport/4
+	0005  Edgeport/2
+	0006  Edgeport/4i
+	0007  Edgeport/2i
+	0008  Edgeport/8
+	000c  Edgeport/421
+	000d  Edgeport/21
+	000e  Edgeport/4
+	000f  Edgeport/8
+	0010  Edgeport/2
+	0011  Edgeport/4
+	0012  Edgeport/416
+	0014  Edgeport/8i
+	0018  Edgeport/412
+	0019  Edgeport/412
+	001a  Edgeport/2+2i
+	0101  Edgeport/4
+	0105  Edgeport/2
+	0106  Edgeport/4i
+	0107  Edgeport/2i
+	010c  Edgeport/421
+	010d  Edgeport/21
+	0110  Edgeport/2
+	0111  Edgeport/4
+	0112  Edgeport/416
+	0114  Edgeport/8i
+	0201  Edgeport/4
+	0203  Rapidport/4
+	0204  Edgeport/4
+	0205  Edgeport/2
+	0206  Edgeport/4i
+	0207  Edgeport/2i
+	020c  Edgeport/421
+	020d  Edgeport/21
+	020e  Edgeport/4
+	020f  Edgeport/8
+	0210  Edgeport/2
+	0211  Edgeport/4
+	0212  Edgeport/416
+	0214  Edgeport/8i
+	0215  Edgeport/1
+	0216  EPOS/44
+	0217  Edgeport/42
+	021a  Edgeport/2+2i
+	021b  Edgeport/2c
+	021c  Edgeport/221c
+	021d  Edgeport/22c
+	021e  Edgeport/21c
+	021f  Edgeport/62
+	0240  Edgeport/1
+	0241  Edgeport/1i
+	0242  Edgeport/4s
+	0243  Edgeport/8s
+	0244  Edgeport/8
+	0245  Edgeport/22c
+	0301  Watchport/P
+	0302  Watchport/M
+	0303  Watchport/W
+	0304  Watchport/T
+	0305  Watchport/H
+	0306  Watchport/E
+	0307  Watchport/L
+	0308  Watchport/R
+	0309  Watchport/A
+	030a  Watchport/D
+	030b  Watchport/D
+	030c  Power Management Port
+	030e  Power Management Port
+	030f  Watchport/G
+	0310  Watchport/Tc
+	0311  Watchport/Hc
+	1403  MultiTech Systems MT4X56 Modem
+	1a17  Agilent Technologies (E6473)
+1619  L & K Precision Technology Co., Ltd.
+1621  Wionics Research
+1628  Stonestreet One, Inc.
+162a  Airgo Networks Inc.
+162f  WiQuest Communications, Inc.
+1631  Good Way Technology
+	6200  GWUSB2E
+	c019  RT2573
+1645  Entrega [hex]
+	0001  1S Serial Port
+	0002  2S Serial Port
+	0003  1S25 Serial Port
+	0004  4S Serial Port
+	0005  E45 Ethernet [klsi]
+	0006  Parallel Port
+	0007  U1-SC25 SCSI
+	0008  Ethernet
+	0016  Bi-directional to Parallel Printer Converter
+	0080  1 port to Serial Converter
+	0081  1 port to Serial Converter
+	0093  1S9 Serial Port
+	8000  EZ-USB
+	8001  1 port to Serial
+	8002  2x Serial Port
+	8003  1 port to Serial
+	8004  2U4S serial/usb hub
+	8005  Ethernet
+	8080  1 port to Serial
+	8081  1 port to Serial
+	8093  PortGear Serial Port
+164a  ChipX
+1657  Struck Innovative Systeme GmbH
+	3150  SIS3150 USB2.0 to VME interface
+1660  Creatix Polymedia GmbH
+1668  Actiontec Electronics, Inc. [hex]
+	0009  Gateway
+	0333  Modem
+	0358  InternetPhoneWizard
+	0405  Gateway
+	0408  Prism2.5 802.11b Adapter
+	0413  Gateway
+	0421  Prism2.5 802.11b Adapter
+	0441  IBM Integrated Bluetooth II
+	0500  BTM200B BlueTooth Adapter
+	1050  802.11g Wireless Mini adapter
+	1441  IBM Integrated Bluetooth II
+	2441  BMDC-2 IBM Bluetooth III w.56k
+	3441  IBM Integrated Bluetooth III
+	6010  Gateway
+	6097  802.11b Wireless Adapter
+	6106  ROPEX FreeLan 802.11b
+	7605  UAT1 Wireless Ethernet Adapter
+1669  PiKRON Ltd. [hex]
+	1001  uLan2USB Converter - PS1 protocol
+1679  Total Phase
+	2001  Beagle USB 12 Protocol Analyzer
+1682  Maxwise Production Enterprise Ltd.
+1684  Godspeed Computer Corp.
+1686  ZOOM Corporation
+	0045  H4 Digital Recorder
+1687  Kingmax Digital Inc.
+168c  Atheros Communications
+	0001  AR5523
+	0002  AR5523 (no firmware)
+1690  Askey Computer Corp. [hex]
+	0101  Creative Modem Blaster DE5670
+	0102  CDC Modem Board
+	0103  Askey 1456 VQE-R3 Modem [conexant]
+	0104  HCF V90 Data Fax RTAD Modem
+	0107  HCF V.90 Data,Fax,RTAD Modem
+	0109  Askey MagicXpress V.90 Pocket Modem [conexant]
+	0203  Voyager ADSL Modem Loader
+	0204  Voyager ADSL Modem
+	0205  DSL Modem
+	0206  GlobeSpan ADSL WAN Modem
+	0208  DSL Modem
+	0209  Voyager 100 ADSL Modem
+	0211  Globespan Virata ADSL LAN Modem
+	0212  DSL Modem
+	0213  HM121d DSL Modem
+	0214  HM121d DSL Modem
+	0215  Voyager 105 ADSL Modem
+	0701  WLAN
+	0710  SMCWUSBT-G
+	0711  SMCWUSBT-G (no firmware)
+	0712  AR5523
+	0713  AR5523 (no firmware)
+	0715  Voyager 1055 Laptop Adapter
+	0722  RT2573
+	0726  Wi-Fi Wireless LAN Adapter
+	0901  Voyager 205 ADSL Router
+1696  Hitachi Video and Information System, Inc.
+1697  VTec Test, Inc.
+16a5  Shenzhen Zhengerya Cable Co., Ltd.
+16ab  Global Sun Technology
+	7801  AR5523
+	7802  AR5523 (no firmware)
+	7811  AR5523
+	7812  AR5523 (no firmware)
+16ac  Dongguan ChingLung Wire & Cable Co., Ltd.
+16c0  VOTI
+	03e8  free for internal lab use 1000
+	03e9  free for internal lab use 1001
+	03ea  free for internal lab use 1002
+	03eb  free for internal lab use 1003
+	03ec  free for internal lab use 1004
+	03ed  free for internal lab use 1005
+	03ee  free for internal lab use 1006
+	03ef  free for internal lab use 1007
+	03f0  free for internal lab use 1008
+	03f1  free for internal lab use 1009
+	076b  OpenPCD 13.56MHz RFID Reader
+	076c  OpenPICC 13.56MHz RFID Simulator (native)
+	08ac  OpenBeacon USB stick
+16cc  silex technology, Inc.
+16d3  Frontline Test Equipment, Inc.
+16d5  AnyDATA Corporation
+	6501  CDMA 2000 1xRTT/EV-DO USB Modem
+16d8  CMOTECH Co., Ltd.
+	5141  CMOTECH CDMA Technologies USB modem
+	5543  CDMA 2000 1xRTT/1xEVDO USB modem
+	6280  CMOTECH CDMA Technologies USB modem
+16df  King Billion Electronics Co., Ltd.
+16f5  Futurelogic Inc.
+1706  BlueView Technologies, Inc.
+1707  ARTIMI
+170b  Swissonic
+	0011  MIDI-USB 1x1
+170d  Avnera
+1733  Cellink Technology Co., Ltd
+	0101  RF Wireless Optical Mouse OP-701
+1736  CANON IMAGING SYSTEM TECHNOLOGIES INC.
+1737  Linksys
+	0039  USB1000
+1740  Senao
+	2000  NUB-8301
+1743  General Atomics
+174c  ASMedia Technology Inc.
+174f  Syntek
+	5a35  1.3MPixel Web Cam - Asus G1s
+	6a31  Web Cam - Asus A8J, F3S, F5R, VX2S, V1S
+	6a33  Web Cam - Asus F3SA, F9J, F9S
+	6a51  2.0MPixel Web Cam - Asus Z96J, Z96S, S96S
+	6a54  Web Cam
+	6d51  2.0Mpixel Web Cam - Eurocom D900C
+	8a12  0.3MPixel Web Cam - Packard Bell MX37-T-003
+	a311  1.3MPixel Web Cam - Asus A3A, A6J, A6K, A6M, A6R, A6T, A6V, A7T, A7sv, A7U
+	a312  1.3MPixel Web Cam
+	a821  Web Cam - Packard Bell BU45, PB Easynote MX66-208W
+	aa11  Web Cam
+1759  LucidPort Technology, Inc.
+1772  System Level Solutions, Inc.
+1781  Multiple Vendors
+	083e  MetaGeek Wi-Spy
+	0938  Iguanaworks USB IR Transceiver
+1782  Spreadtrum Communications Inc.
+1784  TopSeed Technology Corp.
+1788  ShenZhen Litkconn Technology Co., Ltd.
+1796  Printrex, Inc.
+1797  JALCO CO., LTD.
+17a5  Advanced Connection Technology Inc.
+17a7  MICOMSOFT CO., LTD.
+17b3  Grey Innovation
+	0004  Linux-USB Midi Gadget
+17c3  Singim International Corp.
+17cc  Native Instruments
+	0815  Audio Kontrol 1
+	1940  RigKontrol3
+	1969  RigKontrol2
+	1978  Audio 8 DJ
+	4711  Kore Controller
+	4712  Kore Controller 2
+17cf  Hip Hing Cable & Plug Mfy. Ltd.
+17d0  Sanford L.P.
+17d3  Korea Techtron Co., Ltd.
+17e9  Newnham Research
+	0051  USB VGA Adaptor
+17eb  Cornice, Inc.
+17ef  Lenovo
+	3815  ChipsBnk 2GB USB Stick
+17f5  K.K. Rocky
+17f6  Unicomp, Inc
+1822  Twinhan
+	3201  VisionDTV USB-Ter/HAMA USB DVB-T device cold
+	3202  VisionDTV USB-Ter/HAMA USB DVB-T device warm
+1831  Gwo Jinn Industries Co., Ltd.
+1832  Huizhou Shenghua Industrial Co., Ltd.
+1854  Memory Devices Ltd.
+185b  Compro
+	d000  Compro Videomate DVB-U2000 - DVB-T USB cold
+	d001  Compro Videomate DVB-U2000 - DVB-T USB warm
+1861  Tech Technology Industrial Company
+1862  Teridian Semiconductor Corp.
+1871  Aveo Technology Corp.
+1894  Topseed
+	5632  Atek Tote Remote
+	5641  TSAM-004 Presentation Remote
+1897  Evertop Wire Cable Co.
+18b6  Mikkon Technology Limited
+18b7  Zotek Electronic Co., Ltd.
+18c5  AMIT
+	0002  CG-WLUSB2GO
+18d5  Starline International Group Limited
+18d9  Kaba
+	01xy  LEGIC advant desktop reader
+18e3  Fitipower Integrated Technology Inc
+18e8  Qcom
+	6196  RT2573
+	6229  RT2573
+18ea  Matrox Graphics, Inc.
+	0002  DualHead2Go [Analog Edition]
+	0004  TripleHead2Go [Digital Edition]
+18fd  FineArch Inc.
+190d  Motorola GSG
+1914  Alco Digital Devices Limited
+1915  Linksys
+	2233  WUSB11 v2.8 802.11b Adapter
+	2234  WUSB54G 802.11g Adapter
+192f  Avago Technologies, Pte.
+1930  Shenzhen Xianhe Technology Co., Ltd.
+1931  Ningbo Broad Telecommunication Co., Ltd.
+1949  Lab126
+1951  Hyperstone AG
+1953  Ironkey Inc.
+1954  Radiient Technologies
+195d  Itron Technology iONE
+	7002  Libra-Q11 IR remote
+	7006  Libra-Q26 / 1.0 Remote
+	7777  Scorpius wireless keyboard
+1967  CASIO HITACHI Mobile Communications Co., Ltd.
+196b  Wispro Technology Inc.
+1970  Dane-Elec Corp. USA
+1975  Dongguan Guneetal Wire & Cable Co., Ltd.
+1976  Chipsbrand Microelectronics (HK) Co., Ltd.
+1977  T-Logic
+	0111  TL203 MP3 Player and Voice Recorder
+1989  Nuconn Technology Corp.
+198f  Beceem Communications Inc.
+1990  Acron Precision Industrial Co., Ltd.
+1995  Trillium Technology Pty. Ltd.
+	3202  REC-ADPT-USB (recorder)
+	3203  REC-A-ADPT-USB (recorder)
+199e  The Imaging Source Europe GmbH
+199f  Benica Corporation
+19a8  Biforst Technology Inc.
+19af  S Life
+	6611  Celestia VoIP Phone
+19b5  B & W Group
+19b6  Infotech Logistic, LLC
+19ca  Mindtribe
+	0001  Sandio 3D HID Mouse
+19cf  Parrot SA
+19e1  WeiDuan Electronic Accessory (S.Z.) Co., Ltd.
+19e8  Industrial Technology Research Institute
+19ef  Pak Heng Technology (Shenzhen) Co., Ltd.
+19ff  Best Buy
+	0201  Rocketfish Wireless 2.4G Laser Mouse
+1a08  Bellwood International, Inc.
+1a0a  USB-IF non-workshop
+	badd  USB OTG Compliance test device
+1a12  KES Co., Ltd.
+1a25  Amphenol East Asia Ltd.
+1a2a  Seagate Branded Solutions
+1a36  Biwin Technology Ltd.
+1a40  TERMINUS TECHNOLOGY INC.
+1a41  Action Electronics Co., Ltd.
+1a4a  Silicon Image
+1a4b  SafeBoot International B.V.
+1a61  Abbott Diabetes Care
+1a6a  Spansion Inc.
+1a6d  SamYoung Electronics Co., Ltd
+1a6e  Global Unichip Corp.
+1a6f  Sagem Orga GmbH
+1a79  Bayer Health Care LLC
+1a7b  Lumberg Connect  GmbH & Co. KG
+1a89  Dynalith Systems Co., Ltd.
+1a8b  SGS Taiwan Ltd.
+1a98  Leica Camera AG
+1aa4  Data Drive Thru, Inc.
+1aa5  UBeacon Technologies, Inc.
+1aa6  eFortune Technology Corp.
+1acb  Salcomp Plc
+1ad1  Desay Wire Co., Ltd.
+1ae4  ic-design Reinhard Gottinger GmbH
+1aed  High Top Precision Electronic Co., Ltd.
+1aef  Conntech Electronic (Suzhou) Corporation
+1b04  Meilhaus Electronic GmBH
+	0630  ME-630
+	0940  ME-94
+	0950  ME-95
+	0960  ME-96
+	1000  ME-1000
+	100a  ME-1000
+	100b  ME-1000
+	1400  ME-1400
+	140a  ME-1400A
+	140b  ME-1400B
+	140c  ME-1400C
+	140d  ME-1400D
+	140e  ME-1400E
+	14ea  ME-1400EA
+	14eb  ME-1400EB
+	1604  ME-1600/4U
+	1608  ME-1600/8U
+	160c  ME-1600/12U
+	160f  ME-1600/16U
+	168f  ME-1600/16U8I
+	4610  ME-4610
+	4650  ME-4650
+	4660  ME-4660
+	4661  ME-4660I
+	4662  ME-4660
+	4663  ME-4660I
+	4670  ME-4670
+	4671  ME-4670I
+	4672  ME-4670S
+	4673  ME-4670IS
+	4680  ME-4680
+	4681  ME-4680I
+	4682  ME-4680S
+	4683  ME-4680IS
+	6004  ME-6000/4
+	6008  ME-6000/8
+	600f  ME-6000/16
+	6014  ME-6000I/4
+	6018  ME-6000I/8
+	601f  ME-6000I/16
+	6034  ME-6000ISLE/4
+	6038  ME-6000ISLE/8
+	603f  ME-6000ISLE/16
+	6044  ME-6000/4/DIO
+	6048  ME-6000/8/DIO
+	604f  ME-6000/16/DIO
+	6054  ME-6000I/4/DIO
+	6058  ME-6000I/8/DIO
+	605f  ME-6000I/16/DIO
+	6074  ME-6000ISLE/4/DIO
+	6078  ME-6000ISLE/8/DIO
+	607f  ME-6000ISLE/16/DIO
+	6104  ME-6100/4
+	6108  ME-6100/8
+	610f  ME-6100/16
+	6114  ME-6100I/4
+	6118  ME-6100I/8
+	611f  ME-6100I/16
+	6134  ME-6100ISLE/4
+	6138  ME-6100ISLE/8
+	613f  ME-6100ISLE/16
+	6144  ME-6100/4/DIO
+	6148  ME-6100/8/DIO
+	614f  ME-6100/16/DIO
+	6154  ME-6100I/4/DIO
+	6158  ME-6100I/8/DIO
+	615f  ME-6100I/16/DIO
+	6174  ME-6100ISLE/4/DIO
+	6178  ME-6100ISLE/8/DIO
+	617f  ME-6100ISLE/16/DIO
+	6259  ME-6200I/9/DIO
+	6359  ME-6300I/9/DIO
+	810a  ME-8100A
+	810b  ME-8100B
+	820a  ME-8200A
+	820b  ME-8200B
+1b20  MStar Semiconductor, Inc.
+1b22  WiLinx Corp.
+1b26  Cellex Power Products, Inc.
+1b27  Current Electronics Inc.
+1b28  NAVIsis Inc.
+1b32  Ugobe Life Forms, Inc.
+1b36  ViXS Systems, Inc.
+1b3f  Generalplus Technology Inc.
+1b47  Energizer Holdings, Inc.
+	0001  CHUSB Duo Charger (NiMH AA/AAA USB smart charger)
+1b48  Plastron Precision Co., Ltd.
+1b59  K.S. Terminals Inc.
+1b5a  Chao Zhou Kai Yuan Electric Co., Ltd.
+1b65  The Hong Kong Standards and Testing Centre Ltd.
+1b72  ATERGI TECHNOLOGY CO., LTD.
+1b76  Legend Silicon Corp.
+1b86  Dongguan Guanshang Electronics Co., Ltd.
+1b88  ShenMing Electron (Dong Guan) Co., Ltd.
+1b8c  Altium Limited
+1b8d  e-MOVE Technology Co., Ltd.
+1b8e  Amlogic, Inc.
+1b8f  MA LABS, Inc.
+1b98  YMax Communications Corp.
+1b99  Shenzhen Yuanchuan Electronic
+1ba1  JINQ CHERN ENTERPRISE CO., LTD.
+1ba2  Lite Metals & Plastic (Shenzhen) Co., Ltd.
+1ba4  Ember Corporation
+	0001  InSight USB Link
+1ba8  China Telecommunication Technology Labs
+1bad  Harmonix Music
+	0002  Harmonix Guitar for Xbox 360
+	0003  Harmonix Drum Kit for Xbox 360
+1bbb  T & A Mobile Phones
+1bc4  Ford Motor Co.
+1bc5  AVIXE Technology (China) Ltd.
+1bce  Contac Cable Industrial Limited
+1bcf  Sunplus Innovation Technology Inc.
+1bd0  Hangzhou Riyue Electronic Co., Ltd.
+1bde  P-TWO INDUSTRIES, INC.
+1bef  Shenzhen Tongyuan Network-Communication Cables Co., Ltd
+1bf0  RealVision Inc.
+1bf5  Extranet Systems Inc.
+1bf6  Orient Semiconductor Electronics, Ltd.
+1bfd  TouchPack
+	1688  Resistive Touch Screen
+1c02  Kreton Corporation
+1c04  QNAP System Inc.
+1c0d  Relm Wireless
+1c10  Lanterra Industrial Co., Ltd.
+1c13  ALECTRONIC LIMITED
+1c1a  Datel Electronics Ltd.
+1c1b  Volkswagen of America, Inc.
+1c1f  Goldvish S.A.
+1c20  Fuji Electric Device Technology Co., Ltd.
+1c21  ADDMM LLC
+1c22  ZHONGSHAN CHIANG YU ELECTRIC CO., LTD.
+1c26  Shanghai Haiying Electronics Co., Ltd.
+1c27  HuiYang D & S Cable Co., Ltd.
+1c31  LS Cable Ltd.
+1c37  Authorizer Technologies, Inc.
+1c3d  NONIN MEDICAL INC.
+1c3e  Wep Peripherals
+1c49  Cherng Weei Technology Corp.
+1c6b  Philips & Lite-ON Digital Solutions Corporation
+1c6c  Skydigital Inc.
+1c77  Kaetat Industrial Co., Ltd.
+1c78  Datascope Corp.
+1c79  Unigen Corporation
+1c7a  LighTuning Technology Inc.
+1c7b  LUXSHARE PRECISION INDUSTRY (SHENZHEN) CO., LTD.
+1c87  2N TELEKOMUNIKACE a.s.
+1c88  Somagic, Inc.
+1c89  HONGKONG WEIDIDA ELECTRON LIMITED
+1c8e  ASTRON INTERNATIONAL CORP.
+1c98  ALPINE ELECTRONICS, INC.
+1ca0  ACCARIO Inc.
+1cb3  Aces Electronic Co., Ltd.
+1cb4  OPEX CORPORATION
+1cbe  Luminary Micro Inc.
+1cbf  FORTAT SKYMARK INDUSTRIAL COMPANY
+1cc0  PlantSense
+1cca  NextWave Broadband Inc.
+1ccd  Bodatong Technology (Shenzhen) Co., Ltd.
+1cd4  adp corporation
+1cd5  Firecomms Ltd.
+1cd6  Antonio Precise Products Manufactory Ltd.
+1cde  Telecommunications Technology Association (TTA)
+1cdf  WonTen Technology Co., Ltd.
+1ce0  EDIMAX TECHNOLOGY CO., LTD.
+1ce1  Amphenol KAE
+1cfc  ANDES TECHNOLOGY CORPORATION
+1cfd  Flextronics Digital Design Japan, LTD.
+1d08  NINGBO HENTEK DRAGON ELECTRONICS CO., LTD.
+1d09  TechFaith Wireless Technology Limited
+1d0a  Johnson Controls, Inc. The Automotive Business Unit
+1d0b  HAN HUA CABLE & WIRE TECHNOLOGY (J.X.) CO., LTD.
+1d14  ALPHA-SAT TECHNOLOGY LIMITED
+1d1f  Diostech Co., Ltd.
+1d20  SAMTACK INC.
+1d50  OpenMoko, Inc.
+1d5b  Smartronix, Inc.
+1d6b  Linux Foundation
+	0001  1.1 root hub
+	0002  2.0 root hub
+	0003  3.0 root hub
+1ebb  NuCORE Technology, Inc.
+2001  D-Link Corp. [hex]
+	0001  DWL-120 WIRELESS ADAPTER
+	0201  DHN-120 10Mb Home Phoneline Adapter
+	1a00  10/100 Ethernet
+	200c  10/100 Ethernet
+	3200  DWL-120 802.11b (Atmel RFMD503A) [usbvnetr]
+	3500  Elitegroup Computer Systems WLAN card WL-162
+	3700  DWL-122 802.11b
+	3701  DWL-G120 Spinnaker 802.11b
+	3702  DWL-120 rev F
+	3703  DWL-122 802.11b
+	3704  DWL-G122 802.11g rev. A2
+	3705  AirPlus G DWL-G120 Wireless Adapter(rev.C)
+	3761  IEEE 802.11g USB2.0 Wireless Network Adapter-PN
+	3a00  DWL-AG132
+	3a01  DWL-AG132 (no firmware)
+	3a02  DWL-G132
+	3a03  DWL-G132 (no firmware)
+	3a04  DWL-AG122
+	3a05  DWL-AG122 (no firmware)
+	3a80  AirPlus Xtreme G DWL-G132 Wireless Adapter
+	3a81  predator Bootloader Download
+	3a82  AirPremier AG DWL-AG132 Wireless Adapter
+	3a83  predator Bootloader Download
+	3b00  AirPlus DWL-120+ Wireless Adapter
+	3b01  WLAN Boot Device
+	3c00  DWL-G122 802.11g rev. B1 [ralink]
+	3c01  AirPlus AG DWL-AG122 Wireless Adapter
+	3c02  AirPlus G DWL-G122 Wireless Adapter
+	3c05  DUB-E100 Fast Ethernet [asix]
+	4000  DSB-650C Ethernet [klsi]
+	4001  DSB-650TX Ethernet [pegasus]
+	4002  DSB-650TX Ethernet [pegasus]
+	4003  DSB-650TX-PNA Ethernet [pegasus]
+	400b  10/100 Ethernet
+	4102  10/100 Ethernet
+	5100  DSL-200 ADSL ATM Modem
+	5102  DSL-200 ADSL Loader
+	5b00  Remote NDIS Network Device
+	9414  Cable Modem
+	9b00  Broadband Cable Modem Remote NDIS Device
+	abc1  DSB-650 Ethernet [pegasus]
+	f013  DLink 7 port USB2.0 Hub
+	f10d  Accent Communications Modem
+	f110  DUB-AV300 A/V Capture
+	f111  DBT-122 Bluetooth adapter
+	f112  DUB-T210 Audio Device
+	f116  Formosa 2
+	f117  Formosa 3
+	f118  Formosa 4
+2019  PLANEX
+	3220  GW-US11S WLAN
+	5303  GW-US54GXS
+	ab01  GW-US54HP
+	ab50  GW-US54Mini2
+	c002  GW-US54SG
+	c007  GW-US54GZL
+	ed02  GW-USMM
+2040  Hauppauge
+	6502  WinTV HVR-900
+	6503  WinTV HVR-930
+	7050  Nova-T Stick
+	9300  WinTV NOVA-T USB2 (cold)
+	9301  WinTV NOVA-T USB2 (warm)
+2101  ActionStar
+	0201  SIIG 4-to-2 Printer Switch
+2162  Creative (?)
+	2031  Network Blaster Wireless Adapter
+	500c  DE5771 Modem Blaster
+	8001  Broadxent BritePort DSL Bridge 8010U
+2222  MacAlly
+	0004  iWebKey Keyboard
+	4050  AirStick joystick
+2233  RadioShack Corporation
+	6323  USB Electronic Scale
+22b8  Motorola PCS
+	0001  Wally 2.2 chipset
+	0002  Wally 2.4 chipset
+	0005  V.60c/V.60i GSM Phone
+	0850  Bluetooth Device
+	1001  Patriot 1.0 (GSM) chipset
+	1002  Patriot 2.0 chipset
+	1005  T280e GSM/GPRS Phone
+	1101  Patriot 1.0 (TDMA) chipset
+	1801  Rainbow chipset flash
+	2035  Bluetooth Device
+	2805  GSM Modem
+	2821  T720 GSM Phone
+	2822  V.120e GSM Phone
+	2823  Flash Interface
+	2a01  MSM6050 chipset
+	2a02  CDMA modem
+	2a03  MSM6050 chipset flash
+	2a21  V710 GSM Phone (P2K)
+	2a22  V710 GSM Phone (AT)
+	2a23  MSM6100 chipset flash
+	2a41  MSM6300 chipset
+	2a42  Usb Modem
+	2a43  MSM6300 chipset flash
+	2a61  E815 GSM Phone (P2K)
+	2a62  E815 GSM Phone (AT)
+	2a63  MSM6500 chipset flash
+	2a81  MSM6025 chipset
+	2a83  MSM6025 chipset flash
+	2ac1  MSM6100 chipset
+	2ac3  MSM6100 chipset flash
+	3001  A835/E1000 GSM Phone (P2K)
+	3002  A835/E1000 GSM Phone (AT)
+	3801  C350L/C450 (P2K)
+	3802  C330/C350L/C450/EZX GSM Phone (AT)
+	3803  Neptune LT chipset flash
+	4001  OMAP 1.0 chipset
+	4002  A920/A925 UMTS Phone
+	4003  OMAP 1.0 chipset flash
+	4008  OMAP 1.0 chipset RDL
+	4204  MPx200 Smartphone
+	4214  MPc GSM
+	4224  MPx220 Smartphone
+	4234  MPc CDMA
+	4244  MPx100 Smartphone
+	4801  Neptune LTS chipset
+	4803  Neptune LTS chipset flash
+	4810  Triplet GSM Phone (storage)
+	4901  Triplet GSM Phone (P2K)
+	4902  Triplet GSM Phone (AT)
+	4903  Neptune LTE chipset flash
+	4a01  Neptune LTX chipset
+	4a03  Neptune LTX chipset flash
+	4a32  L6-imode Phone
+	5801  Neptune ULS chipset
+	5803  Neptune ULS chipset flash
+	5901  Neptune VLT chipset
+	5903  Neptune VLT chipset flash
+	6001  Dalhart EZX
+	6003  Dalhart flash
+	6004  EZX GSM Phone (CDC Net)
+	6008  Dalhart RDL
+	6009  EZX GSM Phone (P2K)
+	600a  Dalhart EZX config 17
+	600b  Dalhart EZX config 18
+	600c  EZX GSM Phone (USBLAN)
+	6021  JUIX chipset
+	6023  JUIX chipset flash
+	6026  Flash RAM Downloader/miniOS
+	6027  USBLAN
+	604c  EZX GSM Phone (Storage)
+	6101  Talon integrated chipset
+	6401  Argon chipset
+	6403  Argon chipset flash
+	6415  ROKR Z6 (MTP mode)
+	6604  Washington CDMA Phone
+	6631  CDC Modem
+22b9  eTurboTouch Technology, Inc.
+22ba  Technology Innovation Holdings, Ltd
+2304  Pinnacle Systems, Inc. [hex]
+	0109  Studio PCTV USB (SECAM)
+	0110  Studio PCTV USB (PAL)
+	0111  Miro PCTV USB
+	0112  Studio PCTV USB (NTSC) with FM radio
+	0201  Systems MovieBox Device
+	0204  MovieBox USB_B
+	0205  DVC 150B
+	0206  Systems MovieBox Deluxe Device
+	0207  Dazzle DVC90 Video Device
+	0208  Studio PCTV USB2
+	020e  PCTV 200e
+	020f  PCTV 400e BDA Device
+	0210  Studio PCTV USB (PAL) with FM radio
+	0212  Studio PCTV USB (NTSC)
+	0213  500-USB Device
+	0214  Studio PCTV USB (PAL) with FM radio
+	0216  PCTV 60e
+	0219  PCTV 260e
+	021a  Dazzle DVC100 Audio Device
+	021b  Dazzle DVC130/DVC170
+	021d  Dazzle DVC130
+	021e  Dazzle DVC170
+	021f  PCTV Sat HDTV Pro BDA Device
+	0222  PCTV Sat Pro BDA Device
+	0223  DazzleTV Sat BDA Device
+	0226  PCTV 330e
+	0227  PCTV for Mac, HD Stick
+	0228  PCTV DVB-T Flash Stick
+	022a  PCTV 160e
+	022b  PCTV 71e
+	0232  PCTV 170e
+	0300  Studio Linx Video input cable (NTSC)
+	0301  Studio Linx Video input cable (PAL)
+	0302  Dazzle DVC120
+	0419  PCTV Bungee USB (PAL) with FM radio
+	061d  PCTV Deluxe (NTSC) Device
+	061e  PCTV Deluxe (PAL) Device
+2318  Shining Technologies, Inc. [hex]
+	0011  CitiDISK Jr. IDE Enclosure
+2375  Digit@lway, Inc.
+	0001  Digital Audio Player
+2406  SANHO Digital Electronics Co., Ltd.
+	6688  PD7X Portable Storage
+2478  Tripp-Lite
+	2008  U209-000-R Serial Port
+2632  TwinMOS
+	3209  7-in-1 Card Reader
+2650  Electronics For Imaging, Inc. [hex]
+2730  Citizen
+	200f  CT-S310 Label printer
+2735  DigitalWay
+	0003  MPIO 1.5GB Hard Disc Drive
+2770  NHJ, Ltd
+	0a01  ScanJet 4600 series
+	905c  Che-Ez Snap SNAP-U/Digigr8/Soundstar TDC-35
+	9060  A130
+	9120  Che-ez! Snap / iClick Tiny VGA Digital Camera
+	9130  TCG 501
+	913c  Argus DC-1730
+	9150  Mini Cam
+	9153  iClick 5X
+	915d  Cyberpix S-210S / Little Tikes My Real Digital Camera
+	930b  CCD Webcam(PC370R)
+	930c  CCD Webcam(PC370R)
+2899  Toptronic Industrial Co., Ltd
+2c02  Planex Communications
+	14ea  GW-US11H WLAN
+2fb2  Fujitsu, Ltd
+3125  Eagletron
+	0001  TrackerPod Camera Stand
+3176  Whanam Electronics Co., Ltd
+3275  VidzMedia Pte Ltd
+	4fb1  MonsterTV P2H
+3334  AEI
+	1701  Fast Ethernet
+3340  Yakumo
+	043a  Mio A701 DigiWalker PPCPhone
+	0e3a  Pocket PC 300 GPS SL / Typhoon MyGuide 3500
+	a0a3  deltaX 5 BT (D) PDA
+3504  Micro Star
+	f110  Security Key
+3538  Power Quotient International Co., Ltd
+	0001  Travel Flash
+	0015  Mass Storge Device
+	0022  Hi-Speed Mass Storage Device
+	0042  Cool Drive U339 Flash Disk
+3579  DIVA
+	6901  Media Reader
+3636  InVibro
+3838  WEM
+	0001  5-in-1 Card Reader
+3923  National Instruments Corp.
+	12c0  DAQPad-6020E
+	12d0  DAQPad-6507
+	12e0  NI 4350
+	12f0  NI 5102
+	1750  DAQPad-6508
+	17b0  USB-ISA-Bridge
+	1820  DAQPad-6020E (68 pin I/O)
+	1830  DAQPad-6020E (BNC)
+	1f00  DAQPad-6024E
+	1f10  DAQPad-6024E
+	1f20  DAQPad-6025E
+	1f30  DAQPad-6025E
+	1f40  DAQPad-6036E
+	1f50  DAQPad-6036E
+	2f80  DAQPad-6052E
+	2f90  DAQPad-6052E
+	703c  USB-485 RS485 Cable
+	7254  NI MIO (data acquisition card) firmware updater
+	729e  USB-6251 (OEM) data acquisition card
+40bb  I-O Data
+	0a09  USB2.0-SCSI Bridge USB2-SC
+4101  i-rocks
+	1301  IR-2510 usb phone
+4102  iRiver, Ltd.
+	1001  iFP-100 series mp3 player
+	1003  iFP-300 series mp3 player
+	1005  iFP-500 series mp3 player
+	1007  iFP-700 series mp3/ogg vorbis player
+	1008  iFP-800 series mp3/ogg vorbis player
+	100a  iFP-1000 series mp3/ogg vorbis player
+	1014  T20 series mp3/ogg vorbis player (ums firmware)
+	1101  iFP-100 series mp3 player (ums firmware)
+	1103  iFP-300 series mp3 player (ums firmware)
+	1105  iFP-500 series mp3 player (ums firmware)
+	1113  T10 (alternate)
+	1117  T10
+	1119  T30 series mp3/ogg/wma player
+	2002  H10 6GB
+	2101  H10 20GB (mtp)
+	2102  H10 5GB (mtp)
+	2105  H10 5/6GB (mtp)
+413c  Dell Computer Corp.
+	0058  Port Replicator
+	1001  Keyboard Hub
+	1002  Keyboard Hub
+	2001  Keyboard HID Support
+	2002  SK-8125 Keyboard
+	2003  Keyboard
+	2005  RT7D50 Keyboard
+	2100  SK-3106 Keyboard
+	2101  SmartCard Reader Keyboard
+	2500  DRAC4 Remote Access Card
+	3010  Optical Wheel Mouse
+	3200  Mouse
+	4001  Axim X5
+	4002  Axim X3
+	4003  Axim X30
+	4004  Axim Sync
+	4005  Axim Sync
+	4006  Axim Sync
+	4007  Axim Sync
+	4008  Axim Sync
+	4009  Axim Sync
+	4011  Axim X51v
+	5103  AIO Printer A940
+	5105  AIO Printer A920
+	5107  AIO Printer A960
+	5109  Photo AIO Printer 922
+	5110  Photo AIO Printer 962
+	5111  Photo AIO Printer 942
+	5112  Photo AIO Printer 924
+	5113  Photo AIO Printer 944
+	5114  Photo AIO Printer 964
+	5115  Photo AIO Printer 926
+	5116  AIO Printer 946
+	5117  Photo AIO Printer 966
+	5118  AIO 810
+	5124  Laser MFP 1815
+	5128  Photo AIO 928
+	5200  Laser Printer
+	5202  Printing Support
+	5203  Printing Support
+	5210  Printing Support
+	5211  Printing Support
+	5220  Laser MFP 1600n
+	5225  Printing Support
+	5226  Printing Support
+	5300  Laser Printer
+	5400  Laser Printer
+	5401  Laser Printer
+	5601  Laser Printer 3100cn
+	5602  Laser Printer 3000cn
+	5631  Laser Printer 5100cn
+	5905  Printing Support
+	8000  BC02 Bluetooth USB Adapter
+	8010  TrueMobile Bluetooth Module in
+	8100  TrueMobile 1180 802.11b Adapter
+	8102  TrueMobile 1300 USB2.0 WLAN Card
+	8103  Wireless 350 Bluetooth
+	8104  Wireless 1450 Dual-band (802.11a/b/g) USB2.0 Adapter
+	8105  U2 in HID - Driver
+	8106  Wireless 350 Bluetooth Internal Card in
+	8110  Wireless 3xx Bluetooth Internal Card
+	8111  Wireless 3xx Bluetooth Internal Card in
+	8114  Wireless 5700 Mobile Broadband (CDMA EV-DO) Minicard Modem
+	8115  Wireless 5500 Mobile Broadband (3G HSDPA) Minicard Modem
+	8116  Wireless 5505 Mobile Broadband (3G HSDPA) Minicard Modem
+	8117  Wireless 5700 Mobile Broadband (CDMA EV-DO) Expresscard Modem
+	8118  Wireless 5510 Mobile Broadband (3G HSDPA) Expresscard Status Port
+	8120  Bluetooth adapter
+	8121  Eastfold in HID
+	8122  Eastfold in DFU
+	8123  eHome Infrared Receiver
+	8124  eHome Infrared Receiver
+	8126  Wireless 355 Bluetooth
+	8127  Wireless 355 Module with Bluetooth 2.0 + EDR Technology.
+	8128  Wireless 5700-Sprint Mobile Broadband (CDMA EV-DO) Mini-Card Status Port
+	8129  Wireless 5700-Telus Mobile Broadband (CDMA EV-DO) Mini-Card Status Port
+	8131  Wireless 360 Bluetooth 2.0 + EDR module.
+	8133  Wireless 5720 VZW Mobile Broadband (EVDO Rev-A) Minicard GPS Port
+	8134  Wireless 5720 Sprint Mobile Broadband (EVDO Rev-A) Minicard Status Port
+	8135  Wireless 5720 TELUS Mobile Broadband (EVDO Rev-A) Minicard Diagnostics Port
+	8136  Wireless 5520 Cingular Mobile Broadband (3G HSDPA) Minicard Diagnostics Port
+	8137  Wireless 5520 Voda L Mobile Broadband (3G HSDPA) Minicard Status Port
+	8138  Wireless 5520 Voda I Mobile Broadband (3G HSDPA) Minicard EAP-SIM Port
+	8140  Wireless 360 Bluetooth
+	8142  Mobile 360 in DFU
+	8501  Bluetooth Adapter
+	a001  Hub
+	a005  Internal 2.0 Hub
+	a700  Hub (in 1905FP LCD Monitor)
+4146  USBest Technology
+	9281  Iomega Micro Mini 128MB Flash Drive
+	ba01  Intuix Flash Drive
+4242  USB Design by Example
+	4201  Buttons and Lights HID device
+	4220  Echo 1 Camera
+4348  WinChipHead
+	5523  USB->RS 232 adapter with Prolifec PL 2303 chipset
+	5537  13.56Mhz RFID Card Reader and Writer
+	5584  CH34x printer adapter cable
+4572  Shuttle, Inc.
+	4572  Shuttle PN31 Remote
+4586  Panram
+	1026  Crystal Bar Flash Drive
+4670  EMS Production
+	9394  Game Cube USB Memory Adaptor 64M
+4752  Miditech
+	0011  Midistart-2
+4766  Aceeca
+	0001  MEZ1000 RDA
+4855  Memorex
+	7288  Ultra Traveldrive 160G 2.5" HDD
+5032  Grandtec
+	0bb8  Grandtec USB1.1 DVB-T (cold)
+	0bb9  Grandtec USB1.1 DVB-T (warm)
+	0fa0  Grandtec USB1.1 DVB-T (cold)
+	0fa1  Grandtec USB1.1 DVB-T (warm)
+5041  Linksys (?)
+	2234  WUSB54G 802.11g Adapter
+5173  Sweex
+	1809  ZD1211
+5345  Owon
+	1234  PDS6062T Oscilloscope
+544d  Transmeta Corp.
+5543  UC-Logic Technology Corp.
+	0002  SuperPen WP3325U Tablet
+	0003  Genius MousePen 4x3 Tablet/Aquila L1 Tablet
+	0004  Genius MousePen 5x4 Tablet
+	0005  Genius MousePen 8x6 Tablet
+	0041  Genius PenSketch 6x8 Tablet
+	0042  Genius PenSketch 12x9 Tablet
+55aa  OnSpec Electronic, Inc.
+	0015  Hard Drive
+	0102  SuperDisk
+	0103  IDE Hard Drive
+	0201  DDI to Reader-19
+	1234  ATAPI Bridge
+	a103  Sandisk SDDR-55 SmartMedia Card Reader
+	b000  USB to CompactFlash Card Reader
+	b004  OnSpec MMC/SD Reader/Writer
+	b00b  USB to Memory Stick Card Reader
+	b00c  USB to SmartMedia Card Reader
+	b012  Mitsumi FA402M 8-in-2 Card Reader
+	b200  Compact Flash Reader
+	b204  MMC/ SD Reader
+	b207  Memory Stick Reader
+5986  Acer, Inc
+	0102  Crystal Eye webcam
+5a57  Zinwell
+	0260  RT2570
+6189  Sitecom
+	182d  USB 2.0 Ethernet
+	2068  USB to serial cable (v2)
+6253  TwinHan Technology Co., Ltd
+	0100  Ir reciver f. remote control
+636c  CoreLogic, Inc.
+6547  Arkmicro Technologies Inc.
+	0232  ARK3116 Serial
+6666  Prototype product Vendor ID
+	0667  WiseGroup Smart Joy PSX, PS-PC Smart JoyPad
+	2667  JCOP BlueZ Smartcard reader
+	8804  WiseGroup SuperJoy Box 5
+6891  3Com
+	a727  3CRUSB10075
+6993  Freshtel
+	b001  FT-102 VoIP USB Phone
+6a75  Shanghai Jujo Electronics Co., Ltd
+7104  CME (Central Music Co.)
+	2202  UF5/UF6/UF7/UF8 MIDI Master Keyboard
+8086  Intel Corp.
+	0001  AnyPoint (TM) Home Network 1.6 Mbps Wireless Adapter
+	0100  Personal Audio Player 3000
+	0101  Personal Audio Player 3000
+	0110  Easy PC Camera
+	0120  PC Camera CS120
+	0200  AnyPoint(TM) Wireless II Network 11Mbps Adapter
+	0431  Intel Pro Video PC Camera
+	0510  Digital Movie Creator
+	0630  Pocket PC Camera
+	0780  CS780 Microphone Input
+	07d3  BLOB boot loader firmware
+	0dad  Cherry MiniatureCard Keyboard
+	1010  AnyPoint(TM) Home Network 10 Mbps Phoneline Adapter
+	110a  Bluetooth Controller from (Ericsson P4A)
+	110b  Bluetooth Controller from (Intel/CSR)
+	1110  PRO/Wireless LAN Module
+	1111  PRO/Wireless 2011B 802.11b Adapter
+	1134  Hollister Mobile Monitor
+	1234  Prototype Reader/Writer
+	3100  PRO/DSL 3220 Modem - WAN
+	3101  PRO/DSL 3220 Modem
+	3240  AnyPoint® 3240 Modem - WAN
+	3241  AnyPoint® 3240 Modem
+	8602  Miniature Card Slot
+	9303  Intel 8x930Hx Hub
+	9890  82930 Test Board
+	beef  SCM Miniature Card Reader/Writer
+	c013  Wireless HID Station
+	f001  XScale PXA27x Bulverde flash
+8341  EGO Systems, Inc.
+	2000  Flashdisk
+9016  Sitecom
+	182d  WL-022
+9710  MosChip Semiconductor
+	7703  MCS7703 Serial Port Adapter
+	7705  Printer cable
+	7715  Printer cable
+	7780  MS7780 4Mbps Fast IRDA Adapter
+	7830  MCS7830 Ethernet
+a727  3Com
+	6893  AR5523
+	6895  AR5523
+	6897  AR5523
+c251  Keil Software, Inc.
+	2710  ULink
+eb1a  eMPIA Technology, Inc.
+	17de  KWorld V-Stream XPERT DTV - DVB-T USB cold
+	17df  KWorld V-Stream XPERT DTV - DVB-T USB warm
+	2710  SilverCrest WebCam
+	2750  ECS Elitegroup G220 integrated webcam
+	2800  Terratec Cinergy 200
+	2801  GrabBeeX+ Video Encoder
+f003  Hewlett Packard
+	6002  PhotoSmart C500
+
+# List of known device classes, subclasses and protocols
+
+# Syntax:
+# C class  class_name
+#	subclass  subclass_name			<-- single tab
+#		protocol  protocol_name		<-- two tabs
+
+C 00  (Defined at Interface level)
+C 01  Audio
+	01  Control Device
+	02  Streaming
+	03  MIDI Streaming
+C 02  Communications
+	01  Direct Line
+	02  Abstract (modem)
+		00  None
+		01  AT-commands (v.25ter)
+		02  AT-commands (PCCA101)
+		03  AT-commands (PCCA101 + wakeup)
+		04  AT-commands (GSM)
+		05  AT-commands (3G)
+		06  AT-commands (CDMA)
+		fe  Defined by command set descriptor
+		ff  Vendor Specific (MSFT RNDIS?)
+	03  Telephone
+	04  Multi-Channel
+	05  CAPI Control
+	06  Ethernet Networking
+	07  ATM Networking
+	08  Wireless Handset Control
+	09  Device Management
+	0a  Mobile Direct Line
+	0b  OBEX
+	0c  Ethernet Emulation
+		07  Ethernet Emulation (EEM)
+C 03  Human Interface Device
+	00  No Subclass
+		00  None
+		01  Keyboard
+		02  Mouse
+	01  Boot Interface Subclass
+		00  None
+		01  Keyboard
+		02  Mouse
+C 05  Physical Interface Device
+C 06  Imaging
+	01  Still Image Capture
+		01  Picture Transfer Protocol (PIMA 15470)
+C 07  Printer
+	01  Printer
+		00  Reserved/Undefined
+		01  Unidirectional
+		02  Bidirectional
+		03  IEEE 1284.4 compatible bidirectional
+		ff  Vendor Specific
+C 08  Mass Storage
+	01  RBC (typically Flash)
+		00  Control/Bulk/Interrupt
+		01  Control/Bulk
+		50  Bulk (Zip)
+	02  SFF-8020i, MMC-2 (ATAPI)
+	03  QIC-157
+	04  Floppy (UFI)
+		00  Control/Bulk/Interrupt
+		01  Control/Bulk
+		50  Bulk (Zip)
+	05  SFF-8070i
+	06  SCSI
+		00  Control/Bulk/Interrupt
+		01  Control/Bulk
+		50  Bulk (Zip)
+C 09  Hub
+	00  Unused
+		00  Full speed (or root) hub
+		01  Single TT
+		02  TT per port
+C 0a  CDC Data
+	00  Unused
+		30  I.430 ISDN BRI
+		31  HDLC
+		32  Transparent
+		50  Q.921M
+		51  Q.921
+		52  Q.921TM
+		90  V.42bis
+		91  Q.932 EuroISDN
+		92  V.120 V.24 rate ISDN
+		93  CAPI 2.0
+		fd  Host Based Driver
+		fe  CDC PUF
+		ff  Vendor specific
+C 0b  Chip/SmartCard
+C 0d  Content Security
+C 0e  Video
+	00  Undefined
+	01  Video Control
+	02  Video Streaming
+	03  Video Interface Collection
+C dc  Diagnostic
+	01  Reprogrammable Diagnostics
+		01  USB2 Compliance
+C e0  Wireless
+	01  Radio Frequency
+		01  Bluetooth
+		02  Ultra WideBand Radio Control
+		03  RNDIS
+	02  Wireless USB Wire Adapter
+		01  Host Wire Adapter Control/Data Streaming
+		02  Device Wire Adapter Control/Data Streaming
+		03  Device Wire Adapter Isochronous Streaming
+C ef  Miscellaneous Device
+	01  ?
+		01  Microsoft ActiveSync
+		02  Palm Sync
+	02  ?
+		01  Interface Association
+		02  Wire Adapter Multifunction Peripheral
+	03  ?
+		01  Cable Based Association
+C fe  Application Specific Interface
+	01  Device Firmware Update
+	02  IRDA Bridge
+	03  Test and Measurement
+		01  TMC
+		02  USB488
+C ff  Vendor Specific Class
+	ff  Vendor Specific Subclass
+		ff  Vendor Specific Protocol
+
+# List of Audio Class Terminal Types
+
+# Syntax:
+# AT terminal_type  terminal_type_name
+
+AT 0100  USB Undefined
+AT 0101  USB Streaming
+AT 01ff  USB Vendor Specific
+AT 0200  Input Undefined
+AT 0201  Microphone
+AT 0202  Desktop Microphone
+AT 0203  Personal Microphone
+AT 0204  Omni-directional Microphone
+AT 0205  Microphone Array
+AT 0206  Processing Microphone Array
+AT 0300  Output Undefined
+AT 0301  Speaker
+AT 0302  Headphones
+AT 0303  Head Mounted Display Audio
+AT 0304  Desktop Speaker
+AT 0305  Room Speaker
+AT 0306  Communication Speaker
+AT 0307  Low Frequency Effects Speaker
+AT 0400  Bidirectional Undefined
+AT 0401  Handset
+AT 0402  Headset
+AT 0403  Speakerphone, no echo reduction
+AT 0404  Echo-suppressing speakerphone
+AT 0405  Echo-canceling speakerphone
+AT 0500  Telephony Undefined
+AT 0501  Phone line
+AT 0502  Telephone
+AT 0503  Down Line Phone
+AT 0600  External Undefined
+AT 0601  Analog Connector
+AT 0602  Digital Audio Interface
+AT 0603  Line Connector
+AT 0604  Legacy Audio Connector
+AT 0605  SPDIF interface
+AT 0606  1394 DA stream
+AT 0607  1394 DV stream soundtrack
+AT 0700  Embedded Undefined
+AT 0701  Level Calibration Noise Source
+AT 0702  Equalization Noise
+AT 0703  CD Player
+AT 0704  DAT
+AT 0705  DCC
+AT 0706  MiniDisc
+AT 0707  Analog Tape
+AT 0708  Phonograph
+AT 0709  VCR Audio
+AT 070a  Video Disc Audio
+AT 070b  DVD Audio
+AT 070c  TV Tuner Audio
+AT 070d  Satellite Receiver Audio
+AT 070e  Cable Tuner Audio
+AT 070f  DSS Audio
+AT 0710  Radio Receiver
+AT 0711  Radio Transmitter
+AT 0712  Multitrack Recorder
+AT 0713  Synthesizer
+
+# List of HID Descriptor Types
+
+# Syntax:
+# HID descriptor_type  descriptor_type_name
+
+HID 21  HID
+HID 22  Report
+HID 23  Physical
+
+# List of HID Descriptor Item Types
+# Note: 2 bits LSB encode data length following
+
+# Syntax:
+# R item_type  item_type_name
+
+# Main Items
+R 80  Input
+R 90  Output
+R b0  Feature
+R a0  Collection
+R c0  End Collection
+
+# Global Items
+R 04  Usage Page
+R 14  Logical Minimum
+R 24  Logical Maximum
+R 34  Physical Minimum
+R 44  Physical Maximum
+R 54  Unit Exponent
+R 64  Unit
+R 74  Report Size
+R 84  Report ID
+R 94  Report Count
+R a4  Push
+R b4  Pop
+
+# Local Items
+R 08  Usage
+R 18  Usage Minimum
+R 28  Usage Maximum
+R 38  Designator Index
+R 48  Designator Minimum
+R 58  Designator Maximum
+R 78  String Index
+R 88  String Minimum
+R 98  String Maximum
+R a8  Delimiter
+
+# List of Physical Descriptor Bias Types
+
+# Syntax:
+# BIAS item_type  item_type_name
+
+BIAS 0  Not Applicable
+BIAS 1  Right Hand
+BIAS 2  Left Hand
+BIAS 3  Both Hands
+BIAS 4  Either Hand
+
+# List of Physical Descriptor Item Types
+
+# Syntax:
+# PHY item_type  item_type_name
+
+PHY 00  None
+PHY 01  Hand
+PHY 02  Eyeball
+PHY 03  Eyebrow
+PHY 04  Eyelid
+PHY 05  Ear
+PHY 06  Nose
+PHY 07  Mouth
+PHY 08  Upper Lip
+PHY 09  Lower Lip
+PHY 0a  Jaw
+PHY 0b  Neck
+PHY 0c  Upper Arm
+PHY 0d  Elbow
+PHY 0e  Forearm
+PHY 0f  Wrist
+PHY 10  Palm
+PHY 11  Thumb
+PHY 12  Index Finger
+PHY 13  Middle Finger
+PHY 14  Ring Finger
+PHY 15  Little Finger
+PHY 16  Head
+PHY 17  Shoulder
+PHY 18  Hip
+PHY 19  Waist
+PHY 1a  Thigh
+PHY 1b  Knee
+PHY 1c  calf
+PHY 1d  Ankle
+PHY 1e  Foot
+PHY 1f  Heel
+PHY 20  Ball of Foot
+PHY 21  Big Toe
+PHY 22  Second Toe
+PHY 23  Third Toe
+PHY 24  Fourth Toe
+PHY 25  Fifth Toe
+PHY 26  Brow
+PHY 27  Cheek
+
+# List of HID Usages
+
+# Syntax:
+# HUT hi  _usage_page  hid_usage_page_name
+#	hid_usage  hid_usage_name
+
+HUT 00  Undefined
+HUT 01  Generic Desktop Controls
+	000  Undefined
+	001  Pointer
+	002  Mouse
+	004  Joystick
+	005  Gamepad
+	006  Keyboard
+	007  Keypad
+	008  Multi-Axis Controller
+	030  Direction-X
+	031  Direction-Y
+	032  Direction-Z
+	033  Rotate-X
+	034  Rotate-Y
+	035  Rotate-Z
+	036  Slider
+	037  Dial
+	038  Wheel
+	039  Hat Switch
+	03a  Counted Buffer
+	03b  Byte Count
+	03c  Motion Wakeup
+	03d  Start
+	03e  Select
+	040  Vector-X
+	041  Vector-Y
+	042  Vector-Z
+	043  Vector-X relative Body
+	044  Vector-Y relative Body
+	045  Vector-Z relative Body
+	046  Vector
+	080  System Control
+	081  System Power Down
+	082  System Sleep
+	083  System Wake Up
+	084  System Context Menu
+	085  System Main Menu
+	086  System App Menu
+	087  System Menu Help
+	088  System Menu Exit
+	089  System Menu Select
+	08a  System Menu Right
+	08b  System Menu Left
+	08c  System Menu Up
+	08d  System Menu Down
+	090  Direction Pad Up
+	091  Direction Pad Down
+	092  Direction Pad Right
+	093  Direction Pad Left
+HUT 02  Simulation Controls
+	000  Undefined
+	001  Flight Simulation Device
+	002  Automobile Simulation Device
+	003  Tank Simulation Device
+	004  Spaceship Simulation Device
+	005  Submarine Simulation Device
+	006  Sailing Simulation Device
+	007  Motorcycle Simulation Device
+	008  Sports Simulation Device
+	009  Airplane Simualtion Device
+	00a  Helicopter Simulation Device
+	00b  Magic Carpet Simulation Device
+	00c  Bicycle Simulation Device
+	020  Flight Control Stick
+	021  Flight Stick
+	022  Cyclic Control
+	023  Cyclic Trim
+	024  Flight Yoke
+	025  Track Control
+	0b0  Aileron
+	0b1  Aileron Trim
+	0b2  Anti-Torque Control
+	0b3  Autopilot Enable
+	0b4  Chaff Release
+	0b5  Collective Control
+	0b6  Dive Break
+	0b7  Electronic Countermeasures
+	0b8  Elevator
+	0b9  Elevator Trim
+	0ba  Rudder
+	0bb  Throttle
+	0bc  Flight COmmunications
+	0bd  Flare Release
+	0be  Landing Gear
+	0bf  Toe Break
+	0c0  Trigger
+	0c1  Weapon Arm
+	0c2  Weapons Select
+	0c3  Wing Flaps
+	0c4  Accelerator
+	0c5  Brake
+	0c6  Clutch
+	0c7  Shifter
+	0c8  Steering
+	0c9  Turret Direction
+	0ca  Barrel Elevation
+	0cb  Drive Plane
+	0cc  Ballast
+	0cd  Bicylce Crank
+	0ce  Handle Bars
+	0cf  Front Brake
+	0d0  Rear Brake
+HUT 03  VR Controls
+	000  Unidentified
+	001  Belt
+	002  Body Suit
+	003  Flexor
+	004  Glove
+	005  Head Tracker
+	006  Head Mounted Display
+	007  Hand Tracker
+	008  Oculometer
+	009  Vest
+	00a  Animatronic Device
+	020  Stereo Enable
+	021  Display Enable
+HUT 04  Sport Controls
+	000  Unidentified
+	001  Baseball Bat
+	002  Golf Club
+	003  Rowing Machine
+	004  Treadmill
+	030  Oar
+	031  Slope
+	032  Rate
+	033  Stick Speed
+	034  Stick Face Angle
+	035  Stick Heel/Toe
+	036  Stick Follow Through
+	047  Stick Temp
+	038  Stick Type
+	039  Stick Height
+	050  Putter
+	051  1 Iron
+	052  2 Iron
+	053  3 Iron
+	054  4 Iron
+	055  5 Iron
+	056  6 Iron
+	057  7 Iron
+	058  8 Iron
+	059  9 Iron
+	05a  10 Iron
+	05b  11 Iron
+	05c  Sand Wedge
+	05d  Loft Wedge
+	05e  Power Wedge
+	05f  1 Wood
+	060  3 Wood
+	061  5 Wood
+	062  7 Wood
+	063  9 Wood
+HUT 05  Game Controls
+	000  Undefined
+	001  3D Game Controller
+	002  Pinball Device
+	003  Gun Device
+	020  Point Of View
+	021  Turn Right/Left
+	022  Pitch Right/Left
+	023  Roll Forward/Backward
+	024  Move Right/Left
+	025  Move Forward/Backward
+	026  Move Up/Down
+	027  Lean Right/Left
+	028  Lean Forward/Backward
+	029  Height of POV
+	02a  Flipper
+	02b  Secondary Flipper
+	02c  Bump
+	02d  New Game
+	02e  Shoot Ball
+	02f  Player
+	030  Gun Bolt
+	031  Gun Clip
+	032  Gun Selector
+	033  Gun Single Shot
+	034  Gun Burst
+	035  Gun Automatic
+	036  Gun Safety
+	037  Gamepad Fire/Jump
+	038  Gamepad Fun
+	039  Gamepad Trigger
+HUT 07  Keyboard
+	000  No Event
+	001  Keyboard ErrorRollOver
+	002  Keyboard POSTfail
+	003  Keyboard Error Undefined
+	004  A
+	005  B
+	006  C
+	007  D
+	008  E
+	009  F
+	00a  G
+	00b  H
+	00c  I
+	00d  J
+	00e  K
+	00f  L
+	010  M
+	011  N
+	012  O
+	013  P
+	014  Q
+	015  R
+	016  S
+	017  T
+	018  U
+	019  V
+	01a  W
+	01b  X
+	01c  Y
+	01d  Z
+	01e  1 and ! (One and Exclamation)
+	01f  2 and @ (2 and at)
+	020  3 and # (3 and Hash)
+	021  4 and $ (4 and Dollar Sign)
+	022  5 and % (5 and Percent Sign)
+	023  6 and ^ (6 and circumflex)
+	024  7 and & (Seven and Ampersand)
+	025  8 and * (Eight and asterisk)
+	026  9 and ( (Nine and Parenthesis Left)
+	027  0 and ) (Zero and Parenthesis Right)
+	028  Return (Enter)
+	029  Escape
+	02a  Delete (Backspace)
+	02b  Tab
+	02c  Space Bar
+	02d  - and _ (Minus and underscore)
+	02e  = and + (Equal and Plus)
+	02f  [ and { (Bracket and Braces Left)
+	030  ] and } (Bracket and Braces Right)
+	031  \ and | (Backslash and Bar)
+	032  # and ~ (Hash and Tilde, Non-US Keyboard near right shift)
+	033  ; and : (Semicolon and Colon)
+	034  � and " (Accent Acute and Double Quotes)
+	035  ` and ~ (Accent Grace and Tilde)
+	036  , and < (Comma and Less)
+	037  . and > (Period and Greater)
+	038  / and ? (Slash and Question Mark)
+	039  Caps Lock
+	03a  F1
+	03b  F2
+	03c  F3
+	03d  F4
+	03e  F5
+	03f  F6
+	040  F7
+	041  F8
+	042  F9
+	043  F10
+	044  F11
+	045  F12
+	046  Print Screen
+	047  Scroll Lock
+	048  Pause
+	049  Insert
+	04a  Home
+	04b  Page Up
+	04c  Delete Forward (without Changing Position)
+	04d  End
+	04e  Page Down
+	04f  Right Arrow
+	050  Left Arrow
+	051  Down Arrow
+	052  Up Arrow
+	053  Num Lock and Clear
+	054  Keypad / (Division Sign)
+	055  Keypad * (Multiplication Sign)
+	056  Keypad - (Subtraction Sign)
+	057  Keypad + (Addition Sign)
+	058  Keypad Enter
+	059  Keypad 1 and END
+	05a  Keypad 2 and Down Arrow
+	05b  Keypad 3 and Page Down
+	05c  Keypad 4 and Left Arrow
+	05d  Keypad 5 (Tactilei Raised)
+	05f  Keypad 6 and Right Arrow
+	060  Keypad 7 and Home
+	061  Keypad 8 and Up Arrow
+	062  Keypad 8 and Page Up
+	063  Keypad . (decimal delimiter) and Delete
+	064  \ and | (Backslash and Bar, UK and Non-US Keyboard near left shift)
+	065  Keyboard Application (Windows Key for Win95 or Compose)
+	066  Power (not a key)
+	067  Keypad = (Equal Sign)
+	068  F13
+	069  F14
+	06a  F15
+	06b  F16
+	06c  F17
+	06d  F18
+	06e  F19
+	06f  F20
+	070  F21
+	071  F22
+	072  F23
+	073  F24
+	074  Execute
+	075  Help
+	076  Menu
+	077  Select
+	078  Stop
+	079  Again
+	07a  Undo
+	07b  Cut
+	07c  Copy
+	07d  Paste
+	07e  Find
+	07f  Mute
+	080  Volume Up
+	081  Volume Down
+	082  Locking Caps Lock
+	083  Locking Num Lock
+	084  Locking Scroll Lock
+	085  Keypad Comma
+	086  Keypad Equal Sign (AS/400)
+	087  International 1 (PC98)
+	088  International 2 (PC98)
+	089  International 3 (PC98)
+	08a  International 4 (PC98)
+	08b  International 5 (PC98)
+	08c  International 6 (PC98)
+	08d  International 7 (Toggle Single/Double Byte Mode)
+	08e  International 8
+	08f  International 9
+	090  LANG 1 (Hangul/English Toggle, Korea)
+	091  LANG 2 (Hanja Conversion, Korea)
+	092  LANG 3 (Katakana, Japan)
+	093  LANG 4 (Hiragana, Japan)
+	094  LANG 5 (Zenkaku/Hankaku, Japan)
+	095  LANG 6
+	096  LANG 7
+	097  LANG 8
+	098  LANG 9
+	099  Alternate Erase
+	09a  SysReq/Attention
+	09b  Cancel
+	09c  Clear
+	09d  Prior
+	09e  Return
+	09f  Separator
+	0a0  Out
+	0a1  Open
+	0a2  Clear/Again
+	0a3  CrSel/Props
+	0a4  ExSel
+	0e0  Control Left
+	0e1  Shift Left
+	0e2  Alt Left
+	0e3  GUI Left
+	0e4  Control Right
+	0e5  Shift Right
+	0e6  Alt Rigth
+	0e7  GUI Right
+HUT 08  LEDs
+	000  Undefined
+	001  NumLock
+	002  CapsLock
+	003  Scroll Lock
+	004  Compose
+	005  Kana
+	006  Power
+	007  Shift
+	008  Do not disturb
+	009  Mute
+	00a  Tone Enabke
+	00b  High Cut Filter
+	00c  Low Cut Filter
+	00d  Equalizer Enable
+	00e  Sound Field ON
+	00f  Surround On
+	010  Repeat
+	011  Stereo
+	012  Sampling Rate Detect
+	013  Spinning
+	014  CAV
+	015  CLV
+	016  Recording Format Detect
+	017  Off-Hook
+	018  Ring
+	019  Message Waiting
+	01a  Data Mode
+	01b  Battery Operation
+	01c  Battery OK
+	01d  Battery Low
+	01e  Speaker
+	01f  Head Set
+	020  Hold
+	021  Microphone
+	022  Coverage
+	023  Night Mode
+	024  Send Calls
+	025  Call Pickup
+	026  Conference
+	027  Stand-by
+	028  Camera On
+	029  Camera Off
+	02a  On-Line
+	02b  Off-Line
+	02c  Busy
+	02d  Ready
+	02e  Paper-Out
+	02f  Paper-Jam
+	030  Remote
+	031  Forward
+	032  Reverse
+	033  Stop
+	034  Rewind
+	035  Fast Forward
+	036  Play
+	037  Pause
+	038  Record
+	039  Error
+	03a  Usage Selected Indicator
+	03b  Usage In Use Indicator
+	03c  Usage Multi Indicator
+	03d  Indicator On
+	03e  Indicator Flash
+	03f  Indicator Slow Blink
+	040  Indicator Fast Blink
+	041  Indicator Off
+	042  Flash On Time
+	043  Slow Blink On Time
+	044  Slow Blink Off Time
+	045  Fast Blink On Time
+	046  Fast Blink Off Time
+	047  Usage Color Indicator
+	048  Indicator Red
+	049  Indicator Green
+	04a  Indicator Amber
+	04b  Generic Indicator
+	04c  System Suspend
+	04d  External Power Connected
+HUT 09  Buttons
+	000  No Button Pressed
+	001  Button 1 (Primary)
+	002  Button 2 (Secondary)
+	003  Button 3 (Tertiary)
+	004  Button 4
+	005  Button 5
+HUT 0a  Ordinal
+	001  Instance 1
+	002  Instance 2
+	003  Instance 3
+HUT 0b  Telephony
+	000  Unassigned
+	001  Phone
+	002  Answering Machine
+	003  Message Controls
+	004  Handset
+	005  Headset
+	006  Telephony Key Pad
+	007  Programmable Button
+	020  Hook Switch
+	021  Flash
+	022  Feature
+	023  Hold
+	024  Redial
+	025  Transfer
+	026  Drop
+	027  Park
+	028  Forward Calls
+	029  Alternate Function
+	02a  Line
+	02b  Speaker Phone
+	02c  Conference
+	02d  Ring Enable
+	02e  Ring Select
+	02f  Phone Mute
+	030  Caller ID
+	050  Speed Dial
+	051  Store Number
+	052  Recall Number
+	053  Phone Directory
+	070  Voice Mail
+	071  Screen Calls
+	072  Do Not Disturb
+	073  Message
+	074  Answer On/Offf
+	090  Inside Dial Tone
+	091  Outside Dial Tone
+	092  Inside Ring Tone
+	093  Outside Ring Tone
+	094  Priority Ring Tone
+	095  Inside Ringback
+	096  Priority Ringback
+	097  Line Busy Tone
+	098  Recorder Tone
+	099  Call Waiting Tone
+	09a  Confirmation Tone 1
+	09b  Confirmation Tone 2
+	09c  Tones Off
+	09d  Outside Ringback
+	0b0  Key 1
+	0b1  Key 2
+	0b3  Key 3
+	0b4  Key 4
+	0b5  Key 5
+	0b6  Key 6
+	0b7  Key 7
+	0b8  Key 8
+	0b9  Key 9
+	0ba  Key Star
+	0bb  Key Pound
+	0bc  Key A
+	0bd  Key B
+	0be  Key C
+	0bf  Key D
+HUT 0c  Consumer
+	000  Unassigned
+	001  Consumer Control
+	002  Numeric Key Pad
+	003  Programmable Buttons
+	020  +10
+	021  +100
+	022  AM/PM
+	030  Power
+	031  Reset
+	032  Sleep
+	033  Sleep After
+	034  Sleep Mode
+	035  Illumination
+	036  Function Buttons
+	040  Menu
+	041  Menu Pick
+	042  Menu Up
+	043  Menu Down
+	044  Menu Left
+	045  Menu Right
+	046  Menu Escape
+	047  Menu Value Increase
+	048  Menu Value Decrease
+	060  Data on Screen
+	061  Closed Caption
+	062  Closed Caption Select
+	063  VCR/TV
+	064  Broadcast Mode
+	065  Snapshot
+	066  Still
+	080  Selection
+	081  Assign Selection
+	082  Mode Step
+	083  Recall Last
+	084  Enter Channel
+	085  Order Movie
+	086  Channel
+	087  Media Selection
+	088  Media Select Computer
+	089  Media Select TV
+	08a  Media Select WWW
+	08b  Media Select DVD
+	08c  Media Select Telephone
+	08d  Media Select Program Guide
+	08e  Media Select Video Phone
+	08f  Media Select Games
+	090  Media Select Messages
+	091  Media Select CD
+	092  Media Select VCR
+	093  Media Select Tuner
+	094  Quit
+	095  Help
+	096  Media Select Tape
+	097  Media Select Cable
+	098  Media Select Satellite
+	099  Media Select Security
+	09a  Media Select Home
+	09b  Media Select Call
+	09c  Channel Increment
+	09d  Channel Decrement
+	09e  Media Select SAP
+	0a0  VCR Plus
+	0a1  Once
+	0a2  Daily
+	0a3  Weekly
+	0a4  Monthly
+	0b0  Play
+	0b1  Pause
+	0b2  Record
+	0b3  Fast Forward
+	0b4  Rewind
+	0b5  Scan Next Track
+	0b6  Scan Previous Track
+	0b7  Stop
+	0b8  Eject
+	0b9  Random Play
+	0ba  Select Disc
+	0bb  Enter Disc
+	0bc  Repeat
+	0bd  Tracking
+	0be  Track Normal
+	0bf  Slow Tracking
+	0c0  Frame Forward
+	0c1  Frame Back
+	0c2  Mark
+	0c3  Clear Mark
+	0c4  Repeat from Mark
+	0c5  Return to Mark
+	0c6  Search Mark Forward
+	0c7  Search Mark Backward
+	0c8  Counter Reset
+	0c9  Show Counter
+	0ca  Tracking Increment
+	0cb  Tracking Decrement
+	0cc  Stop/Eject
+	0cd  Play/Pause
+	0ce  Play/Skip
+	0e0  Volume
+	0e1  Balance
+	0e2  Mute
+	0e3  Bass
+	0e4  Treble
+	0e5  Bass Boost
+	0e6  Surround Mode
+	0e7  Loudness
+	0e8  MPX
+	0e9  Volume Increment
+	0ea  Volume Decrement
+	0f0  Speed Select
+	0f1  Playback Speed
+	0f2  Standard Play
+	0f3  Long Play
+	0f4  Extended Play
+	0f5  Slow
+	100  Fan Enable
+	101  Fan Speed
+	102  Light Enable
+	103  Light Illumination Level
+	104  Climate Control Enable
+	105  Room Temperature
+	106  Security Enable
+	107  Fire Alarm
+	108  Police Alarm
+	150  Balance Right
+	151  Balance Left
+	152  Bass Increment
+	153  Bass Decrement
+	154  Treble Increment
+	155  Treble Decrement
+	160  Speaker System
+	161  Channel Left
+	162  Channel Right
+	163  Channel Center
+	164  Channel Front
+	165  Channel Center Front
+	166  Channel Side
+	167  Channel Surround
+	168  Channel Low Frequency Enhancement
+	169  Channel Top
+	16a  Channel Unknown
+	170  Sub-Channel
+	171  Sub-Channel Increment
+	172  Sub-Channel Decrement
+	173  Alternative Audio Increment
+	174  Alternative Audio Decrement
+	180  Application Launch Buttons
+	181  AL Launch Button Configuration Tool
+	182  AL Launch Button Configuration
+	183  AL Consumer Control Configuration
+	184  AL Word Processor
+	185  AL Text Editor
+	186  AL Spreadsheet
+	187  AL Graphics Editor
+	188  AL Presentation App
+	189  AL Database App
+	18a  AL Email Reader
+	18b  AL Newsreader
+	18c  AL Voicemail
+	18d  AL Contacts/Address Book
+	18e  AL Calendar/Schedule
+	18f  AL Task/Project Manager
+	190  AL Log/Jounal/Timecard
+	191  AL Checkbook/Finance
+	192  AL Calculator
+	193  AL A/V Capture/Playback
+	194  AL Local Machine Browser
+	195  AL LAN/Wan Browser
+	196  AL Internet Browser
+	197  AL Remote Networking/ISP Connect
+	198  AL Network Conference
+	199  AL Network Chat
+	19a  AL Telephony/Dialer
+	19b  AL Logon
+	19c  AL Logoff
+	19d  AL Logon/Logoff
+	19e  AL Terminal Local/Screensaver
+	19f  AL Control Panel
+	1a0  AL Command Line Processor/Run
+	1a1  AL Process/Task Manager
+	1a2  AL Select Task/Application
+	1a3  AL Next Task/Application
+	1a4  AL Previous Task/Application
+	1a5  AL Preemptive Halt Task/Application
+	200  Generic GUI Application Controls
+	201  AC New
+	202  AC Open
+	203  AC CLose
+	204  AC Exit
+	205  AC Maximize
+	206  AC Minimize
+	207  AC Save
+	208  AC Print
+	209  AC Properties
+	21a  AC Undo
+	21b  AC Copy
+	21c  AC Cut
+	21d  AC Paste
+	21e  AC Select All
+	21f  AC Find
+	220  AC Find and Replace
+	221  AC Search
+	222  AC Go To
+	223  AC Home
+	224  AC Back
+	225  AC Forward
+	226  AC Stop
+	227  AC Refresh
+	228  AC Previous Link
+	229  AC Next Link
+	22b  AC History
+	22c  AC Subscriptions
+	22d  AC Zoom In
+	22e  AC Zoom Out
+	22f  AC Zoom
+	230  AC Full Screen View
+	231  AC Normal View
+	232  AC View Toggle
+	233  AC Scroll Up
+	234  AC Scroll Down
+	235  AC Scroll
+	236  AC Pan Left
+	237  AC Pan Right
+	238  AC Pan
+	239  AC New Window
+	23a  AC Tile Horizontally
+	23b  AC Tile Vertically
+	23c  AC Format
+HUT 0d  Digitizer
+	000  Undefined
+	001  Digitizer
+	002  Pen
+	003  Light Pen
+	004  Touch Screen
+	005  Touch Pad
+	006  White Board
+	007  Coordinate Measuring Machine
+	008  3D Digitizer
+	009  Stereo Plotter
+	00a  Articulated Arm
+	00b  Armature
+	00c  Multiple Point Digitizer
+	00d  Free Space Wand
+	020  Stylus
+	021  Puck
+	022  Finger
+	030  Tip Pressure
+	031  Barrel Pressure
+	032  In Range
+	033  Touch
+	034  Untouch
+	035  Tap
+	036  Quality
+	037  Data Valid
+	038  Transducer Index
+	039  Tablet Function Keys
+	03a  Program Change Keys
+	03b  Battery Strength
+	03c  Invert
+	03d  X Tilt
+	03e  Y Tilt
+	03f  Azimuth
+	040  Altitude
+	041  Twist
+	042  Tip Switch
+	043  Secondary Tip Switch
+	044  Barrel Switch
+	045  Eraser
+	046  Tablet Pick
+HUT 0f  PID Page
+	000  Undefined
+	001  Physical Interface Device
+	020  Normal
+	021  Set Effect Report
+	022  Effect Block Index
+	023  Parameter Block Offset
+	024  ROM Flag
+	025  Effect Type
+	026  ET Constant Force
+	027  ET Ramp
+	028  ET Custom Force Data
+	030  ET Square
+	031  ET Sine
+	032  ET Triangle
+	033  ET Sawtooth Up
+	034  ET Sawtooth Down
+	040  ET Spring
+	041  ET Damper
+	042  ET Inertia
+	043  ET Friction
+	050  Duration
+	051  Sample Period
+	052  Gain
+	053  Trigger Button
+	054  Trigger Repeat Interval
+	055  Axes Enable
+	056  Direction Enable
+	057  Direction
+	058  Type Specific Block Offset
+	059  Block Type
+	05A  Set Envelope Report
+	05B  Attack Level
+	05C  Attack Time
+	05D  Fade Level
+	05E  Fade Time
+	05F  Set Condition Report
+	060  CP Offset
+	061  Positive Coefficient
+	062  Negative Coefficient
+	063  Positive Saturation
+	064  Negative Saturation
+	065  Dead Band
+	066  Download Force Sample
+	067  Isoch Custom Force Enable
+	068  Custom Force Data Report
+	069  Custom Force Data
+	06A  Custom Force Vendor Defined Data
+	06B  Set Custom Force Report
+	06C  Custom Force Data Offset
+	06D  Sample Count
+	06E  Set Periodic Report
+	06F  Offset
+	070  Magnitude
+	071  Phase
+	072  Period
+	073  Set Constant Force Report
+	074  Set Ramp Force Report
+	075  Ramp Start
+	076  Ramp End
+	077  Effect Operation Report
+	078  Effect Operation
+	079  Op Effect Start
+	07A  Op Effect Start Solo
+	07B  Op Effect Stop
+	07C  Loop Count
+	07D  Device Gain Report
+	07E  Device Gain
+	07F  PID Pool Report
+	080  RAM Pool Size
+	081  ROM Pool Size
+	082  ROM Effect Block Count
+	083  Simultaneous Effects Max
+	084  Pool Alignment
+	085  PID Pool Move Report
+	086  Move Source
+	087  Move Destination
+	088  Move Length
+	089  PID Block Load Report
+	08B  Block Load Status
+	08C  Block Load Success
+	08D  Block Load Full
+	08E  Block Load Error
+	08F  Block Handle
+	090  PID Block Free Report
+	091  Type Specific Block Handle
+	092  PID State Report
+	094  Effect Playing
+	095  PID Device Control Report
+	096  PID Device Control
+	097  DC Enable Actuators
+	098  DC Disable Actuators
+	099  DC Stop All Effects
+	09A  DC Device Reset
+	09B  DC Device Pause
+	09C  DC Device Continue
+	09F  Device Paused
+	0A0  Actuators Enabled
+	0A4  Safety Switch
+	0A5  Actuator Override Switch
+	0A6  Actuator Power
+	0A7  Start Delay
+	0A8  Parameter Block Size
+	0A9  Device Managed Pool
+	0AA  Shared Parameter Blocks
+	0AB  Create New Effect Report
+	0AC  RAM Pool Available
+HUT 10  Unicode
+HUT 14  Alphanumeric Display
+	000  Undefined
+	001  Alphanumeric Display
+	020  Display Attributes Report
+	021  ASCII Character Set
+	022  Data Read Back
+	023  Font Read Back
+	024  Display Control Report
+	025  Clear Display
+	026  Display Enable
+	027  Screen Saver Delay
+	028  Screen Saver Enable
+	029  Vertical Scroll
+	02a  Horizontal Scroll
+	02b  Character Report
+	02c  Display Data
+	02d  Display Status
+	02e  Stat Not Ready
+	02f  Stat Ready
+	030  Err Not a loadable Character
+	031  Err Font Data Cannot Be Read
+	032  Cursur Position Report
+	033  Row
+	034  Column
+	035  Rows
+	036  Columns
+	037  Cursor Pixel Positioning
+	038  Cursor Mode
+	039  Cursor Enable
+	03a  Cursor Blink
+	03b  Font Report
+	03c  Font Data
+	03d  Character Width
+	03e  Character Height
+	03f  Character Spacing Horizontal
+	040  Character Spacing Vertical
+	041  Unicode Character Set
+HUT 80  USB Monitor
+	001  Monitor Control
+	002  EDID Information
+	003  VDIF Information
+	004  VESA Version
+HUT 81  USB Monitor Enumerated Values
+HUT 82  Monitor VESA Virtual Controls
+	001  Degauss
+	010  Brightness
+	012  Contrast
+	016  Red Video Gain
+	018  Green Video Gain
+	01a  Blue Video Gain
+	01c  Focus
+	020  Horizontal Position
+	022  Horizontal Size
+	024  Horizontal Pincushion
+	026  Horizontal Pincushion Balance
+	028  Horizontal Misconvergence
+	02a  Horizontal Linearity
+	02c  Horizontal Linearity Balance
+	030  Vertical Position
+	032  Vertical Size
+	034  Vertical Pincushion
+	036  Vertical Pincushion Balance
+	038  Vertical Misconvergence
+	03a  Vertical Linearity
+	03c  Vertical Linearity Balance
+	040  Parallelogram Balance (Key Distortion)
+	042  Trapezoidal Distortion (Key)
+	044  Tilt (Rotation)
+	046  Top Corner Distortion Control
+	048  Top Corner Distortion Balance
+	04a  Bottom Corner Distortion Control
+	04c  Bottom Corner Distortion Balance
+	056  Horizontal Moire
+	058  Vertical Moire
+	05e  Input Level Select
+	060  Input Source Select
+	06c  Red Video Black Level
+	06e  Green Video Black Level
+	070  Blue Video Black Level
+	0a2  Auto Size Center
+	0a4  Polarity Horizontal Sychronization
+	0a6  Polarity Vertical Synchronization
+	0aa  Screen Orientation
+	0ac  Horizontal Frequency in Hz
+	0ae  Vertical Frequency in 0.1 Hz
+	0b0  Settings
+	0ca  On Screen Display (OSD)
+	0d4  Stereo Mode
+HUT 84  Power Device Page
+	000  Undefined
+	001  iName
+	002  Present Status
+	003  Changed Status
+	004  UPS
+	005  Power Supply
+	010  Battery System
+	011  Battery System ID
+	012  Battery
+	013  Battery ID
+	014  Charger
+	015  Charger ID
+	016  Power Converter
+	017  Power Converter ID
+	018  Outlet System
+	019  Outlet System ID
+	01a  Input
+	01b  Input ID
+	01c  Output
+	01d  Output ID
+	01e  Flow
+	01f  Flow ID
+	020  Outlet
+	021  Outlet ID
+	022  Gang
+	023  Gang ID
+	024  Power Summary
+	025  Power Summary ID
+	030  Voltage
+	031  Current
+	032  Frequency
+	033  Apparent Power
+	034  Active Power
+	035  Percent Load
+	036  Temperature
+	037  Humidity
+	038  Bad Count
+	040  Config Voltage
+	041  Config Current
+	042  Config Frequency
+	043  Config Apparent Power
+	044  Config Active Power
+	045  Config Percent Load
+	046  Config Temperature
+	047  Config Humidity
+	050  Switch On Control
+	051  Switch Off Control
+	052  Toggle Control
+	053  Low Voltage Transfer
+	054  High Voltage Transfer
+	055  Delay Before Reboot
+	056  Delay Before Startup
+	057  Delay Before Shutdown
+	058  Test
+	059  Module Reset
+	05a  Audible Alarm Control
+	060  Present
+	061  Good
+	062  Internal Failure
+	063  Voltage out of range
+	064  Frequency out of range
+	065  Overload
+	066  Over Charged
+	067  Over Temperature
+	068  Shutdown Requested
+	069  Shutdown  Imminent
+	06a  Reserved
+	06b  Switch On/Off
+	06c  Switchable
+	06d  Used
+	06e  Boost
+	06f  Buck
+	070  Initialized
+	071  Tested
+	072  Awaiting Power
+	073  Communication Lost
+	0fd  iManufacturer
+	0fe  iProduct
+	0ff  iSerialNumber
+HUT 85  Battery System Page
+	000  Undefined
+	001  SMB Battery Mode
+	002  SMB Battery Status
+	003  SMB Alarm Warning
+	004  SMB Charger Mode
+	005  SMB Charger Status
+	006  SMB Charger Spec Info
+	007  SMB Selector State
+	008  SMB Selector Presets
+	009  SMB Selector Info
+	010  Optional Mfg. Function 1
+	011  Optional Mfg. Function 2
+	012  Optional Mfg. Function 3
+	013  Optional Mfg. Function 4
+	014  Optional Mfg. Function 5
+	015  Connection to SMBus
+	016  Output Connection
+	017  Charger Connection
+	018  Battery Insertion
+	019  Use Next
+	01a  OK to use
+	01b  Battery  Supported
+	01c  SelectorRevision
+	01d  Charging Indicator
+	028  Manufacturer Access
+	029  Remaining Capacity Limit
+	02a  Remaining Time Limit
+	02b  At Rate
+	02c  Capacity Mode
+	02d  Broadcast To Charger
+	02e  Primary Battery
+	02f  Charge Controller
+	040  Terminate Charge
+	041  Terminate Discharge
+	042  Below Remaining Capacity Limit
+	043  Remaining Time Limit Expired
+	044  Charging
+	045  Discharging
+	046  Fully Charged
+	047  Fully Discharged
+	048  Conditioning Flag
+	049  At Rate OK
+	04a  SMB Error Code
+	04b  Need Replacement
+	060  At Rate Time To Full
+	061  At Rate Time To Empty
+	062  Average Current
+	063  Max Error
+	064  Relative State Of Charge
+	065  Absolute State Of Charge
+	066  Remaining Capacity
+	067  Full Charge Capacity
+	068  Run Time To Empty
+	069  Average Time To Empty
+	06a  Average Time To Full
+	06b  Cycle Count
+	080  Batt. Pack Model Level
+	081  Internal Charge Controller
+	082  Primary Battery Support
+	083  Design Capacity
+	084  Specification Info
+	085  Manufacturer Date
+	086  Serial Number
+	087  iManufacturerName
+	088  iDeviceName
+	089  iDeviceChemistry
+	08a  Manufacturer Data
+	08b  Rechargeable
+	08c  Warning Capacity Limit
+	08d  Capacity Granularity 1
+	08e  Capacity Granularity 2
+	08f  iOEMInformation
+	0c0  Inhibit Charge
+	0c1  Enable Polling
+	0c2  Reset To Zero
+	0d0  AC Present
+	0d1  Battery Present
+	0d2  Power Fail
+	0d3  Alarm Inhibited
+	0d4  Thermistor Under Range
+	0d5  Thermistor Hot
+	0d6  Thermistor Cold
+	0d7  Thermistor Over Range
+	0d8  Voltage Out Of Range
+	0d9  Current Out Of Range
+	0da  Current Not Regulated
+	0db  Voltage Not Regulated
+	0dc  Master Mode
+	0f0  Charger Selector Support
+	0f1  Charger Spec
+	0f2  Level 2
+	0f3  Level 3
+HUT 86  Power Pages
+HUT 87  Power Pages
+HUT 8c  Bar Code Scanner Page (POS)
+HUT 8d  Scale Page (POS)
+HUT 90  Camera Control Page
+HUT 91  Arcade Control Page
+HUT f0  Cash Device
+	0f1  Cash Drawer
+	0f2  Cash Drawer Number
+	0f3  Cash Drawer Set
+	0f4  Cash Drawer Status
+HUT ff  Vendor Specific
+
+# List of Languages
+
+# Syntax:
+# L language_id  language_name
+#	dialect_id  dialect_name
+
+L 0001  Arabic
+	01  Saudi Arabia
+	02  Iraq
+	03  Egypt
+	04  Libya
+	05  Algeria
+	06  Morocco
+	07  Tunesia
+	08  Oman
+	09  Yemen
+	0a  Syria
+	0b  Jordan
+	0c  Lebanon
+	0d  Kuwait
+	0e  U.A.E
+	0f  Bahrain
+	10  Qatar
+L 0002  Bulgarian
+L 0003  Catalan
+L 0004  Chinese
+	01  Traditional
+	02  Simplified
+	03  Hongkong SAR, PRC
+	04  Singapore
+	05  Macau SAR
+L 0005  Czech
+L 0006  Danish
+L 0007  German
+	01  German
+	02  Swiss
+	03  Austrian
+	04  Luxembourg
+	05  Liechtenstein
+L 0008  Greek
+L 0009  English
+	01  US
+	02  UK
+	03  Australian
+	04  Canadian
+	05  New Zealand
+	06  Ireland
+	07  South Africa
+	08  Jamaica
+	09  Carribean
+	0a  Belize
+	0b  Trinidad
+	0c  Zimbabwe
+	0d  Philippines
+L 000a  Spanish
+	01  Castilian
+	02  Mexican
+	03  Modern
+	04  Guatemala
+	05  Costa Rica
+	06  Panama
+	07  Dominican Republic
+	08  Venzuela
+	09  Colombia
+	0a  Peru
+	0b  Argentina
+	0c  Ecuador
+	0d  Chile
+	0e  Uruguay
+	0f  Paraguay
+	10  Bolivia
+	11  El Salvador
+	12  Honduras
+	13  Nicaragua
+	14  Puerto Rico
+L 000b  Finnish
+L 000c  French
+	01  French
+	02  Belgian
+	03  Canadian
+	04  Swiss
+	05  Luxembourg
+	06  Monaco
+L 000d  Hebrew
+L 000e  Hungarian
+L 000f  Idelandic
+L 0010  Italian
+	01  Italian
+	02  Swiss
+L 0011  Japanese
+L 0012  Korean
+	01  Korean
+L 0013  Dutch
+	01  Dutch
+	02  Belgian
+L 0014  Norwegian
+	01  Bokmal
+	02  Nynorsk
+L 0015  Polish
+L 0016	Portuguese
+	01  Portuguese
+	02  Brazilian
+L 0017  forgotten
+L 0018  Romanian
+L 0019  Russian
+L 001a  Serbian
+	01  Croatian
+	02  Latin
+	03  Cyrillic
+L 001b  Slovak
+L 001c  Albanian
+L 001d  Swedish
+	01  Swedish
+	02  Finland
+L 001e  Thai
+L 001f  Turkish
+L 0020  Urdu
+	01  Pakistan
+	02  India
+L 0021  Indonesian
+L 0022  Ukrainian
+L 0023  Belarusian
+L 0024  Slovenian
+L 0025  Estonian
+L 0026  Latvian
+L 0027  Lithuanian
+	01  Lithuanian
+L 0028  forgotten
+L 0029  Farsi
+L 002a  Vietnamese
+L 002b  Armenian
+L 002c  Azeri
+	01  Cyrillic
+	02  Latin
+L 002d  Basque
+L 002e  forgotten
+L 002f  Macedonian
+L 0036  Afrikaans
+L 0037  Georgian
+L 0038  Faeroese
+L 0039  Hindi
+L 003e  Malay
+	01  Malaysia
+	02  Brunei Darassalam
+L 003f  Kazak
+L 0041  Awahili
+L 0043  Uzbek
+	01  Latin
+	02  Cyrillic
+L 0044  Tatar
+L 0045  Bengali
+L 0046  Punjabi
+L 0047  Gujarati
+L 0048  Oriya
+L 0049  Tamil
+L 004a  Telugu
+L 004b  Kannada
+L 004c  Malayalam
+L 004d  Assamese
+L 004e  Marathi
+L 004f  Sanskrit
+L 0057  Konkani
+L 0058  Manipuri
+L 0059  Sindhi
+L 0060  Kashmiri
+	02  India
+L 0061  Nepali
+	02  India
+
+# HID Descriptor bCountryCode
+# HID Specification 1.11 (2001-06-27) page 23
+#
+# Syntax:
+# HCC country_code keymap_type
+
+HCC 00  Not supported
+HCC 01  Arabic
+HCC 02  Belgian
+HCC 03  Canadian-Bilingual
+HCC 04  Canadian-French
+HCC 05  Czech Republic
+HCC 06  Danish
+HCC 07  Finnish
+HCC 08  French
+HCC 09  German
+HCC 10  Greek
+HCC 11  Hebrew
+HCC 12  Hungary
+HCC 13  International (ISO)
+HCC 14  Italian
+HCC 15  Japan (Katakana)
+HCC 16  Korean
+HCC 17  Latin American
+HCC 18  Netherlands/Dutch
+HCC 19  Norwegian
+HCC 20  Persian (Farsi)
+HCC 21  Poland
+HCC 22  Portuguese
+HCC 23  Russia
+HCC 24  Slovakia
+HCC 25  Spanish
+HCC 26  Swedish
+HCC 27  Swiss/French
+HCC 28  Swiss/German
+HCC 29  Switzerland
+HCC 30  Taiwan
+HCC 31  Turkish-Q
+HCC 32  UK
+HCC 33  US
+HCC 34  Yugoslavia
+HCC 35  Turkish-F
+
+# List of Video Class Terminal Types
+
+# Syntax:
+# VT terminal_type  terminal_type_name
+
+VT 0100  USB Vendor Specific
+VT 0101  USB Streaming
+VT 0200  Input Vendor Specific
+VT 0201  Camera Sensor
+VT 0202  Sequential Media
+VT 0300  Output Vendor Specific
+VT 0301  Generic Display
+VT 0302  Sequential Media
+VT 0400  External Vendor Specific
+VT 0401  Composite Video
+VT 0402  S-Video
+VT 0403  Component Video
diff -druN linux-2.6.39-libre/drivers/staging/usbip/vhci.h linux-3.0-rc7-libre/drivers/staging/usbip/vhci.h
--- linux-2.6.39-libre/drivers/staging/usbip/vhci.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/usbip/vhci.h	2011-07-11 19:51:52.000000000 -0400
@@ -17,9 +17,14 @@
  * USA.
  */
 
-#include <linux/platform_device.h>
+#include <linux/device.h>
+#include <linux/list.h>
+#include <linux/spinlock.h>
+#include <linux/sysfs.h>
+#include <linux/types.h>
+#include <linux/usb.h>
 #include <linux/usb/hcd.h>
-
+#include <linux/wait.h>
 
 struct vhci_device {
 	struct usb_device *udev;
@@ -33,12 +38,11 @@
 	/* speed of a remote device */
 	enum usb_device_speed speed;
 
-	/*  vhci root-hub port to which this device is attached  */
+	/* vhci root-hub port to which this device is attached */
 	__u32 rhport;
 
 	struct usbip_device ud;
 
-
 	/* lock for the below link lists */
 	spinlock_t priv_lock;
 
@@ -54,7 +58,6 @@
 	wait_queue_head_t waitq_tx;
 };
 
-
 /* urb->hcpriv, use container_of() */
 struct vhci_priv {
 	unsigned long seqnum;
@@ -64,7 +67,6 @@
 	struct urb *urb;
 };
 
-
 struct vhci_unlink {
 	/* seqnum of this request */
 	unsigned long seqnum;
@@ -85,12 +87,12 @@
 
 /* for usb_bus.hcpriv */
 struct vhci_hcd {
-	spinlock_t	lock;
+	spinlock_t lock;
 
-	u32	port_status[VHCI_NPORTS];
+	u32 port_status[VHCI_NPORTS];
 
-	unsigned	resuming:1;
-	unsigned long	re_timeout;
+	unsigned resuming:1;
+	unsigned long re_timeout;
 
 	atomic_t seqnum;
 
@@ -102,24 +104,20 @@
 	struct vhci_device vdev[VHCI_NPORTS];
 };
 
-
 extern struct vhci_hcd *the_controller;
 extern struct attribute_group dev_attr_group;
-
-
-/*-------------------------------------------------------------------------*/
-/* prototype declaration */
+#define hardware (&the_controller->pdev.dev)
 
 /* vhci_hcd.c */
 void rh_port_connect(int rhport, enum usb_device_speed speed);
 void rh_port_disconnect(int rhport);
-int vhci_rx_loop(void *data);
-int vhci_tx_loop(void *data);
 
-struct urb *pickup_urb_and_free_priv(struct vhci_device *vdev,
-					    __u32 seqnum);
+/* vhci_rx.c */
+struct urb *pickup_urb_and_free_priv(struct vhci_device *vdev, __u32 seqnum);
+int vhci_rx_loop(void *data);
 
-#define hardware		(&the_controller->pdev.dev)
+/* vhci_tx.c */
+int vhci_tx_loop(void *data);
 
 static inline struct vhci_device *port_to_vdev(__u32 port)
 {
diff -druN linux-2.6.39-libre/drivers/staging/usbip/vhci_hcd.c linux-3.0-rc7-libre/drivers/staging/usbip/vhci_hcd.c
--- linux-2.6.39-libre/drivers/staging/usbip/vhci_hcd.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/usbip/vhci_hcd.c	2011-07-11 19:51:52.000000000 -0400
@@ -17,21 +17,18 @@
  * USA.
  */
 
-#include <linux/slab.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
 #include <linux/kthread.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
 
 #include "usbip_common.h"
 #include "vhci.h"
 
-#define DRIVER_VERSION "1.0"
 #define DRIVER_AUTHOR "Takahiro Hirofuchi"
-#define DRIVER_DESC "Virtual Host Controller Interface Driver for USB/IP"
-#define DRIVER_LICENCE "GPL"
-MODULE_AUTHOR(DRIVER_AUTHOR);
-MODULE_DESCRIPTION(DRIVER_DESC);
-MODULE_LICENSE(DRIVER_LICENCE);
-
-
+#define DRIVER_DESC "USB/IP 'Virtual' Host Controller (VHCI) Driver"
 
 /*
  * TODO
@@ -43,15 +40,13 @@
  *	- clean up everything
  */
 
-
 /* See usb gadget dummy hcd */
 
-
 static int vhci_hub_status(struct usb_hcd *hcd, char *buff);
 static int vhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
-		u16 wIndex, char *buff, u16 wLength);
+			    u16 wIndex, char *buff, u16 wLength);
 static int vhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb,
-							gfp_t mem_flags);
+			    gfp_t mem_flags);
 static int vhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status);
 static int vhci_start(struct usb_hcd *vhci_hcd);
 static void vhci_stop(struct usb_hcd *hcd);
@@ -62,57 +57,53 @@
 
 struct vhci_hcd *the_controller;
 
-static const char *bit_desc[] = {
+static const char * const bit_desc[] = {
 	"CONNECTION",		/*0*/
 	"ENABLE",		/*1*/
 	"SUSPEND",		/*2*/
 	"OVER_CURRENT",		/*3*/
 	"RESET",		/*4*/
-	"R5",		/*5*/
-	"R6",		/*6*/
-	"R7",		/*7*/
+	"R5",			/*5*/
+	"R6",			/*6*/
+	"R7",			/*7*/
 	"POWER",		/*8*/
 	"LOWSPEED",		/*9*/
 	"HIGHSPEED",		/*10*/
 	"PORT_TEST",		/*11*/
 	"INDICATOR",		/*12*/
-	"R13",		/*13*/
-	"R14",		/*14*/
-	"R15",		/*15*/
+	"R13",			/*13*/
+	"R14",			/*14*/
+	"R15",			/*15*/
 	"C_CONNECTION",		/*16*/
 	"C_ENABLE",		/*17*/
 	"C_SUSPEND",		/*18*/
 	"C_OVER_CURRENT",	/*19*/
 	"C_RESET",		/*20*/
-	"R21",		/*21*/
-	"R22",		/*22*/
-	"R23",		/*23*/
-	"R24",		/*24*/
-	"R25",		/*25*/
-	"R26",		/*26*/
-	"R27",		/*27*/
-	"R28",		/*28*/
-	"R29",		/*29*/
-	"R30",		/*30*/
-	"R31",		/*31*/
+	"R21",			/*21*/
+	"R22",			/*22*/
+	"R23",			/*23*/
+	"R24",			/*24*/
+	"R25",			/*25*/
+	"R26",			/*26*/
+	"R27",			/*27*/
+	"R28",			/*28*/
+	"R29",			/*29*/
+	"R30",			/*30*/
+	"R31",			/*31*/
 };
 
-
 static void dump_port_status(u32 status)
 {
 	int i = 0;
 
-	printk(KERN_DEBUG "status %08x:", status);
+	pr_debug("status %08x:", status);
 	for (i = 0; i < 32; i++) {
 		if (status & (1 << i))
-			printk(" %s", bit_desc[i]);
+			pr_debug(" %s", bit_desc[i]);
 	}
-
-	printk("\n");
+	pr_debug("\n");
 }
 
-
-
 void rh_port_connect(int rhport, enum usb_device_speed speed)
 {
 	unsigned long	flags;
@@ -156,26 +147,20 @@
 	the_controller->port_status[rhport] |=
 					(1 << USB_PORT_FEAT_C_CONNECTION);
 
-
 	/* not yet complete the disconnection
 	 * spin_lock(&vdev->ud.lock);
 	 * vdev->ud.status = VHC_ST_DISCONNECT;
 	 * spin_unlock(&vdev->ud.lock); */
 
 	spin_unlock_irqrestore(&the_controller->lock, flags);
-
 	usb_hcd_poll_rh_status(vhci_to_hcd(the_controller));
 }
 
-
-
-/*----------------------------------------------------------------------*/
-
-#define PORT_C_MASK \
-	((USB_PORT_STAT_C_CONNECTION \
-	  | USB_PORT_STAT_C_ENABLE \
-	  | USB_PORT_STAT_C_SUSPEND \
-	  | USB_PORT_STAT_C_OVERCURRENT \
+#define PORT_C_MASK				\
+	((USB_PORT_STAT_C_CONNECTION		\
+	  | USB_PORT_STAT_C_ENABLE		\
+	  | USB_PORT_STAT_C_SUSPEND		\
+	  | USB_PORT_STAT_C_OVERCURRENT		\
 	  | USB_PORT_STAT_C_RESET) << 16)
 
 /*
@@ -210,7 +195,6 @@
 	int		rhport;
 	int		changed = 0;
 
-
 	*event_bits = 0;
 
 	vhci = hcd_to_vhci(hcd);
@@ -232,7 +216,7 @@
 		}
 	}
 
-	usbip_uinfo("changed %d\n", changed);
+	pr_info("changed %d\n", changed);
 
 	if (hcd->state == HC_STATE_SUSPENDED)
 		usb_hcd_resume_root_hub(hcd);
@@ -278,10 +262,9 @@
 	 * wIndex shows the port number and begins from 1.
 	 */
 	usbip_dbg_vhci_rh("typeReq %x wValue %x wIndex %x\n", typeReq, wValue,
-								wIndex);
+			  wIndex);
 	if (wIndex > VHCI_NPORTS)
-		printk(KERN_ERR "%s: invalid port number %d\n", __func__,
-								wIndex);
+		pr_err("invalid port number %d\n", wIndex);
 	rhport = ((__u8)(wIndex & 0x00ff)) - 1;
 
 	dum = hcd_to_vhci(hcd);
@@ -311,7 +294,7 @@
 			break;
 		case USB_PORT_FEAT_POWER:
 			usbip_dbg_vhci_rh(" ClearPortFeature: "
-						"USB_PORT_FEAT_POWER\n");
+					  "USB_PORT_FEAT_POWER\n");
 			dum->port_status[rhport] = 0;
 			/* dum->address = 0; */
 			/* dum->hdev = 0; */
@@ -319,23 +302,24 @@
 			break;
 		case USB_PORT_FEAT_C_RESET:
 			usbip_dbg_vhci_rh(" ClearPortFeature: "
-						"USB_PORT_FEAT_C_RESET\n");
+					  "USB_PORT_FEAT_C_RESET\n");
 			switch (dum->vdev[rhport].speed) {
 			case USB_SPEED_HIGH:
 				dum->port_status[rhport] |=
-						USB_PORT_STAT_HIGH_SPEED;
+					USB_PORT_STAT_HIGH_SPEED;
 				break;
 			case USB_SPEED_LOW:
 				dum->port_status[rhport] |=
-						USB_PORT_STAT_LOW_SPEED;
+					USB_PORT_STAT_LOW_SPEED;
 				break;
 			default:
 				break;
 			}
 		default:
 			usbip_dbg_vhci_rh(" ClearPortFeature: default %x\n",
-								wValue);
+					  wValue);
 			dum->port_status[rhport] &= ~(1 << wValue);
+			break;
 		}
 		break;
 	case GetHubDescriptor:
@@ -349,8 +333,7 @@
 	case GetPortStatus:
 		usbip_dbg_vhci_rh(" GetPortStatus port %x\n", wIndex);
 		if (wIndex > VHCI_NPORTS || wIndex < 1) {
-			printk(KERN_ERR "%s: invalid port number %d\n",
-			       __func__, wIndex);
+			pr_err("invalid port number %d\n", wIndex);
 			retval = -EPIPE;
 		}
 
@@ -360,7 +343,6 @@
 		 * complete it!!
 		 *                                   */
 		if (dum->resuming && time_after(jiffies, dum->re_timeout)) {
-			printk(KERN_ERR "%s: not yet\n", __func__);
 			dum->port_status[rhport] |=
 					(1 << USB_PORT_FEAT_C_SUSPEND);
 			dum->port_status[rhport] &=
@@ -375,39 +357,38 @@
 		}
 
 		if ((dum->port_status[rhport] & (1 << USB_PORT_FEAT_RESET)) !=
-				0 && time_after(jiffies, dum->re_timeout)) {
+		    0 && time_after(jiffies, dum->re_timeout)) {
 			dum->port_status[rhport] |=
-						(1 << USB_PORT_FEAT_C_RESET);
+				(1 << USB_PORT_FEAT_C_RESET);
 			dum->port_status[rhport] &=
-						~(1 << USB_PORT_FEAT_RESET);
+				~(1 << USB_PORT_FEAT_RESET);
 			dum->re_timeout = 0;
 
 			if (dum->vdev[rhport].ud.status ==
-							VDEV_ST_NOTASSIGNED) {
+			    VDEV_ST_NOTASSIGNED) {
 				usbip_dbg_vhci_rh(" enable rhport %d "
-						"(status %u)\n",
-						rhport,
-						dum->vdev[rhport].ud.status);
+						  "(status %u)\n",
+						  rhport,
+						  dum->vdev[rhport].ud.status);
 				dum->port_status[rhport] |=
-							USB_PORT_STAT_ENABLE;
+					USB_PORT_STAT_ENABLE;
 			}
 #if 0
 			if (dum->driver) {
-
 				dum->port_status[rhport] |=
-							USB_PORT_STAT_ENABLE;
+					USB_PORT_STAT_ENABLE;
 				/* give it the best speed we agree on */
 				dum->gadget.speed = dum->driver->speed;
 				dum->gadget.ep0->maxpacket = 64;
 				switch (dum->gadget.speed) {
 				case USB_SPEED_HIGH:
 					dum->port_status[rhport] |=
-					USB_PORT_STAT_HIGH_SPEED;
+						USB_PORT_STAT_HIGH_SPEED;
 					break;
 				case USB_SPEED_LOW:
 					dum->gadget.ep0->maxpacket = 8;
 					dum->port_status[rhport] |=
-					USB_PORT_STAT_LOW_SPEED;
+						USB_PORT_STAT_LOW_SPEED;
 					break;
 				default:
 					dum->gadget.speed = USB_SPEED_FULL;
@@ -415,14 +396,12 @@
 				}
 			}
 #endif
-
 		}
 		((u16 *) buf)[0] = cpu_to_le16(dum->port_status[rhport]);
-		((u16 *) buf)[1] =
-				cpu_to_le16(dum->port_status[rhport] >> 16);
+		((u16 *) buf)[1] = cpu_to_le16(dum->port_status[rhport] >> 16);
 
 		usbip_dbg_vhci_rh(" GetPortStatus bye %x %x\n", ((u16 *)buf)[0],
-							((u16 *)buf)[1]);
+				  ((u16 *)buf)[1]);
 		break;
 	case SetHubFeature:
 		usbip_dbg_vhci_rh(" SetHubFeature\n");
@@ -432,11 +411,10 @@
 		switch (wValue) {
 		case USB_PORT_FEAT_SUSPEND:
 			usbip_dbg_vhci_rh(" SetPortFeature: "
-					"USB_PORT_FEAT_SUSPEND\n");
-			printk(KERN_ERR "%s: not yet\n", __func__);
+					  "USB_PORT_FEAT_SUSPEND\n");
 #if 0
 			dum->port_status[rhport] |=
-						(1 << USB_PORT_FEAT_SUSPEND);
+				(1 << USB_PORT_FEAT_SUSPEND);
 			if (dum->driver->suspend) {
 				spin_unlock(&dum->lock);
 				dum->driver->suspend(&dum->gadget);
@@ -446,13 +424,13 @@
 			break;
 		case USB_PORT_FEAT_RESET:
 			usbip_dbg_vhci_rh(" SetPortFeature: "
-						"USB_PORT_FEAT_RESET\n");
+					  "USB_PORT_FEAT_RESET\n");
 			/* if it's already running, disconnect first */
 			if (dum->port_status[rhport] & USB_PORT_STAT_ENABLE) {
 				dum->port_status[rhport] &=
-						~(USB_PORT_STAT_ENABLE |
-						  USB_PORT_STAT_LOW_SPEED |
-						  USB_PORT_STAT_HIGH_SPEED);
+					~(USB_PORT_STAT_ENABLE |
+					  USB_PORT_STAT_LOW_SPEED |
+					  USB_PORT_STAT_HIGH_SPEED);
 #if 0
 				if (dum->driver) {
 					dev_dbg(hardware, "disconnect\n");
@@ -468,13 +446,14 @@
 			/* FALLTHROUGH */
 		default:
 			usbip_dbg_vhci_rh(" SetPortFeature: default %d\n",
-								wValue);
+					  wValue);
 			dum->port_status[rhport] |= (1 << wValue);
+			break;
 		}
 		break;
 
 	default:
-		printk(KERN_ERR "%s: default: no such request\n", __func__);
+		pr_err("default: no such request\n");
 		/* dev_dbg (hardware,
 		 *		"hub control req%04x v%04x i%04x l%d\n",
 		 *		typeReq, wValue, wIndex, wLength); */
@@ -484,7 +463,7 @@
 	}
 
 	if (usbip_dbg_flag_vhci_rh) {
-		printk(KERN_DEBUG "port %d\n", rhport);
+		pr_debug("port %d\n", rhport);
 		dump_port_status(prev_port_status[rhport]);
 		dump_port_status(dum->port_status[rhport]);
 	}
@@ -495,10 +474,6 @@
 	return retval;
 }
 
-
-
-/*----------------------------------------------------------------------*/
-
 static struct vhci_device *get_vdev(struct usb_device *udev)
 {
 	int i;
@@ -520,7 +495,7 @@
 	unsigned long flag;
 
 	if (!vdev) {
-		err("could not get virtual device");
+		pr_err("could not get virtual device");
 		/* BUG(); */
 		return;
 	}
@@ -538,14 +513,13 @@
 
 	priv->seqnum = atomic_inc_return(&the_controller->seqnum);
 	if (priv->seqnum == 0xffff)
-		usbip_uinfo("seqnum max\n");
+		dev_info(&urb->dev->dev, "seqnum max\n");
 
 	priv->vdev = vdev;
 	priv->urb = urb;
 
 	urb->hcpriv = (void *) priv;
 
-
 	list_add_tail(&priv->list, &vdev->priv_tx);
 
 	wake_up(&vdev->waitq_tx);
@@ -561,7 +535,7 @@
 	struct vhci_device *vdev;
 
 	usbip_dbg_vhci_hc("enter, usb_hcd %p urb %p mem_flags %d\n",
-		    hcd, urb, mem_flags);
+			  hcd, urb, mem_flags);
 
 	/* patch to usb_sg_init() is in 2.5.60 */
 	BUG_ON(!urb->transfer_buffer && urb->transfer_buffer_length);
@@ -578,8 +552,9 @@
 
 	/* refuse enqueue for dead connection */
 	spin_lock(&vdev->ud.lock);
-	if (vdev->ud.status == VDEV_ST_NULL || vdev->ud.status == VDEV_ST_ERROR) {
-		usbip_uerr("enqueue for inactive port %d\n", vdev->rhport);
+	if (vdev->ud.status == VDEV_ST_NULL ||
+	    vdev->ud.status == VDEV_ST_ERROR) {
+		dev_err(dev, "enqueue for inactive port %d\n", vdev->rhport);
 		spin_unlock(&vdev->ud.lock);
 		spin_unlock_irqrestore(&the_controller->lock, flags);
 		return -ENODEV;
@@ -599,11 +574,10 @@
 	 *  2. Set_Address request to DevAddr(0) EndPoint(0)
 	 *
 	 */
-
 	if (usb_pipedevice(urb->pipe) == 0) {
 		__u8 type = usb_pipetype(urb->pipe);
 		struct usb_ctrlrequest *ctrlreq =
-				(struct usb_ctrlrequest *) urb->setup_packet;
+			(struct usb_ctrlrequest *) urb->setup_packet;
 
 		if (type != PIPE_CONTROL || !ctrlreq) {
 			dev_err(dev, "invalid request to devnum 0\n");
@@ -636,8 +610,8 @@
 		case USB_REQ_GET_DESCRIPTOR:
 			if (ctrlreq->wValue == (USB_DT_DEVICE << 8))
 				usbip_dbg_vhci_hc("Not yet?: "
-						"Get_Descriptor to device 0 "
-						"(get max pipe size)\n");
+						  "Get_Descriptor to device 0 "
+						  "(get max pipe size)\n");
 
 			if (vdev->udev)
 				usb_put_dev(vdev->udev);
@@ -657,7 +631,6 @@
 
 out:
 	vhci_tx_urb(urb);
-
 	spin_unlock_irqrestore(&the_controller->lock, flags);
 
 	return 0;
@@ -724,8 +697,7 @@
 	struct vhci_priv *priv;
 	struct vhci_device *vdev;
 
-	usbip_uinfo("vhci_hcd: dequeue a urb %p\n", urb);
-
+	pr_info("dequeue a urb %p\n", urb);
 
 	spin_lock_irqsave(&the_controller->lock, flags);
 
@@ -755,8 +727,7 @@
 
 		spin_lock_irqsave(&vdev->priv_lock, flags2);
 
-		usbip_uinfo("vhci_hcd: device %p seems to be disconnected\n",
-									vdev);
+		pr_info("device %p seems to be disconnected\n", vdev);
 		list_del(&priv->list);
 		kfree(priv);
 		urb->hcpriv = NULL;
@@ -768,14 +739,13 @@
 		 * vhci_rx will receive RET_UNLINK and give back the URB.
 		 * Otherwise, we give back it here.
 		 */
-		usbip_uinfo("vhci_hcd: vhci_urb_dequeue() gives back urb %p\n",
-									urb);
+		pr_info("gives back urb %p\n", urb);
 
 		usb_hcd_unlink_urb_from_ep(hcd, urb);
 
 		spin_unlock_irqrestore(&the_controller->lock, flags);
 		usb_hcd_giveback_urb(vhci_to_hcd(the_controller), urb,
-								urb->status);
+				     urb->status);
 		spin_lock_irqsave(&the_controller->lock, flags);
 
 	} else {
@@ -788,7 +758,7 @@
 		/* setup CMD_UNLINK pdu */
 		unlink = kzalloc(sizeof(struct vhci_unlink), GFP_ATOMIC);
 		if (!unlink) {
-			usbip_uerr("malloc vhci_unlink\n");
+			pr_err("malloc vhci_unlink\n");
 			spin_unlock_irqrestore(&vdev->priv_lock, flags2);
 			spin_unlock_irqrestore(&the_controller->lock, flags);
 			usbip_event_add(&vdev->ud, VDEV_EVENT_ERROR_MALLOC);
@@ -797,12 +767,11 @@
 
 		unlink->seqnum = atomic_inc_return(&the_controller->seqnum);
 		if (unlink->seqnum == 0xffff)
-			usbip_uinfo("seqnum max\n");
+			pr_info("seqnum max\n");
 
 		unlink->unlink_seqnum = priv->seqnum;
 
-		usbip_uinfo("vhci_hcd: device %p seems to be still connected\n",
-									vdev);
+		pr_info("device %p seems to be still connected\n", vdev);
 
 		/* send cmd_unlink and try to cancel the pending URB in the
 		 * peer */
@@ -825,7 +794,7 @@
 	spin_lock(&vdev->priv_lock);
 
 	list_for_each_entry_safe(unlink, tmp, &vdev->unlink_tx, list) {
-		usbip_uinfo("unlink cleanup tx %lu\n", unlink->unlink_seqnum);
+		pr_info("unlink cleanup tx %lu\n", unlink->unlink_seqnum);
 		list_del(&unlink->list);
 		kfree(unlink);
 	}
@@ -834,12 +803,12 @@
 		struct urb *urb;
 
 		/* give back URB of unanswered unlink request */
-		usbip_uinfo("unlink cleanup rx %lu\n", unlink->unlink_seqnum);
+		pr_info("unlink cleanup rx %lu\n", unlink->unlink_seqnum);
 
 		urb = pickup_urb_and_free_priv(vdev, unlink->unlink_seqnum);
 		if (!urb) {
-			usbip_uinfo("the urb (seqnum %lu) was already given back\n",
-							unlink->unlink_seqnum);
+			pr_info("the urb (seqnum %lu) was already given back\n",
+				unlink->unlink_seqnum);
 			list_del(&unlink->list);
 			kfree(unlink);
 			continue;
@@ -851,7 +820,8 @@
 		usb_hcd_unlink_urb_from_ep(vhci_to_hcd(the_controller), urb);
 		spin_unlock(&the_controller->lock);
 
-		usb_hcd_giveback_urb(vhci_to_hcd(the_controller), urb, urb->status);
+		usb_hcd_giveback_urb(vhci_to_hcd(the_controller), urb,
+				     urb->status);
 
 		list_del(&unlink->list);
 		kfree(unlink);
@@ -871,7 +841,7 @@
 
 	/* need this? see stub_dev.c */
 	if (ud->tcp_socket) {
-		usbip_udbg("shutdown tcp_socket %p\n", ud->tcp_socket);
+		pr_debug("shutdown tcp_socket %p\n", ud->tcp_socket);
 		kernel_sock_shutdown(ud->tcp_socket, SHUT_RDWR);
 	}
 
@@ -881,14 +851,14 @@
 	if (vdev->ud.tcp_tx)
 		kthread_stop(vdev->ud.tcp_tx);
 
-	usbip_uinfo("stop threads\n");
+	pr_info("stop threads\n");
 
 	/* active connection is closed */
 	if (vdev->ud.tcp_socket != NULL) {
 		sock_release(vdev->ud.tcp_socket);
 		vdev->ud.tcp_socket = NULL;
 	}
-	usbip_uinfo("release socket\n");
+	pr_info("release socket\n");
 
 	vhci_device_unlink_cleanup(vdev);
 
@@ -914,7 +884,7 @@
 	 */
 	rh_port_disconnect(vdev->rhport);
 
-	usbip_uinfo("disconnect device\n");
+	pr_info("disconnect device\n");
 }
 
 
@@ -932,7 +902,6 @@
 	vdev->udev = NULL;
 
 	ud->tcp_socket = NULL;
-
 	ud->status = VDEV_ST_NULL;
 
 	spin_unlock(&ud->lock);
@@ -941,9 +910,7 @@
 static void vhci_device_unusable(struct usbip_device *ud)
 {
 	spin_lock(&ud->lock);
-
 	ud->status = VDEV_ST_ERROR;
-
 	spin_unlock(&ud->lock);
 }
 
@@ -972,9 +939,6 @@
 	usbip_start_eh(&vdev->ud);
 }
 
-
-/*----------------------------------------------------------------------*/
-
 static int vhci_start(struct usb_hcd *hcd)
 {
 	struct vhci_hcd *vhci = hcd_to_vhci(hcd);
@@ -983,7 +947,6 @@
 
 	usbip_dbg_vhci_hc("enter vhci_start\n");
 
-
 	/* initialize private data of usb_hcd */
 
 	for (rhport = 0; rhport < VHCI_NPORTS; rhport++) {
@@ -995,17 +958,14 @@
 	atomic_set(&vhci->seqnum, 0);
 	spin_lock_init(&vhci->lock);
 
-
-
 	hcd->power_budget = 0; /* no limit */
 	hcd->state  = HC_STATE_RUNNING;
 	hcd->uses_new_polling = 1;
 
-
 	/* vhci_hcd is now ready to be controlled through sysfs */
 	err = sysfs_create_group(&vhci_dev(vhci)->kobj, &dev_attr_group);
 	if (err) {
-		usbip_uerr("create sysfs files\n");
+		pr_err("create sysfs files\n");
 		return err;
 	}
 
@@ -1019,7 +979,6 @@
 
 	usbip_dbg_vhci_hc("stop VHCI controller\n");
 
-
 	/* 1. remove the userland interface of vhci_hcd */
 	sysfs_remove_group(&vhci_dev(vhci)->kobj, &dev_attr_group);
 
@@ -1030,20 +989,14 @@
 		usbip_event_add(&vdev->ud, VDEV_EVENT_REMOVED);
 		usbip_stop_eh(&vdev->ud);
 	}
-
-
-	usbip_uinfo("vhci_stop done\n");
 }
 
-/*----------------------------------------------------------------------*/
-
 static int vhci_get_frame_number(struct usb_hcd *hcd)
 {
-	usbip_uerr("Not yet implemented\n");
+	pr_err("Not yet implemented\n");
 	return 0;
 }
 
-
 #ifdef CONFIG_PM
 
 /* FIXME: suspend/resume */
@@ -1091,8 +1044,6 @@
 #define vhci_bus_resume       NULL
 #endif
 
-
-
 static struct hc_driver vhci_hc_driver = {
 	.description	= driver_name,
 	.product_desc	= driver_desc,
@@ -1119,8 +1070,6 @@
 	struct usb_hcd		*hcd;
 	int			ret;
 
-	usbip_uinfo("proving...\n");
-
 	usbip_dbg_vhci_hc("name %s id %d\n", pdev->name, pdev->id);
 
 	/* will be removed */
@@ -1135,7 +1084,7 @@
 	 */
 	hcd = usb_create_hcd(&vhci_hc_driver, &pdev->dev, dev_name(&pdev->dev));
 	if (!hcd) {
-		usbip_uerr("create hcd failed\n");
+		pr_err("create hcd failed\n");
 		return -ENOMEM;
 	}
 	hcd->has_tt = 1;
@@ -1149,18 +1098,16 @@
 	 */
 	ret = usb_add_hcd(hcd, 0, 0);
 	if (ret != 0) {
-		usbip_uerr("usb_add_hcd failed %d\n", ret);
+		pr_err("usb_add_hcd failed %d\n", ret);
 		usb_put_hcd(hcd);
 		the_controller = NULL;
 		return ret;
 	}
 
-
 	usbip_dbg_vhci_hc("bye\n");
 	return 0;
 }
 
-
 static int vhci_hcd_remove(struct platform_device *pdev)
 {
 	struct usb_hcd	*hcd;
@@ -1178,12 +1125,9 @@
 	usb_put_hcd(hcd);
 	the_controller = NULL;
 
-
 	return 0;
 }
 
-
-
 #ifdef CONFIG_PM
 
 /* what should happen for USB/IP under suspend/resume? */
@@ -1194,25 +1138,23 @@
 	int connected = 0;
 	int ret = 0;
 
-	dev_dbg(&pdev->dev, "%s\n", __func__);
-
 	hcd = platform_get_drvdata(pdev);
 
 	spin_lock(&the_controller->lock);
 
 	for (rhport = 0; rhport < VHCI_NPORTS; rhport++)
 		if (the_controller->port_status[rhport] &
-						USB_PORT_STAT_CONNECTION)
+		    USB_PORT_STAT_CONNECTION)
 			connected += 1;
 
 	spin_unlock(&the_controller->lock);
 
 	if (connected > 0) {
-		usbip_uinfo("We have %d active connection%s. Do not suspend.\n",
-				connected, (connected == 1 ? "" : "s"));
+		dev_info(&pdev->dev, "We have %d active connection%s. Do not "
+			 "suspend.\n", connected, (connected == 1 ? "" : "s"));
 		ret =  -EBUSY;
 	} else {
-		usbip_uinfo("suspend vhci_hcd");
+		dev_info(&pdev->dev, "suspend vhci_hcd");
 		clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
 	}
 
@@ -1239,7 +1181,6 @@
 
 #endif
 
-
 static struct platform_driver vhci_driver = {
 	.probe	= vhci_hcd_probe,
 	.remove	= __devexit_p(vhci_hcd_remove),
@@ -1251,8 +1192,6 @@
 	},
 };
 
-/*----------------------------------------------------------------------*/
-
 /*
  * The VHCI 'device' is 'virtual'; not a real plug&play hardware.
  * We need to add this virtual device as a platform device arbitrarily:
@@ -1277,13 +1216,9 @@
 {
 	int ret;
 
-	usbip_dbg_vhci_hc("enter\n");
 	if (usb_disabled())
 		return -ENODEV;
 
-	printk(KERN_INFO KBUILD_MODNAME ": %s, %s\n", driver_name,
-	       DRIVER_VERSION);
-
 	ret = platform_driver_register(&vhci_driver);
 	if (ret < 0)
 		goto err_driver_register;
@@ -1292,26 +1227,25 @@
 	if (ret < 0)
 		goto err_platform_device_register;
 
-	usbip_dbg_vhci_hc("bye\n");
+	pr_info(DRIVER_DESC " v" USBIP_VERSION "\n");
 	return ret;
 
-	/* error occurred */
 err_platform_device_register:
 	platform_driver_unregister(&vhci_driver);
-
 err_driver_register:
-	usbip_dbg_vhci_hc("bye\n");
 	return ret;
 }
-module_init(vhci_init);
 
 static void __exit vhci_cleanup(void)
 {
-	usbip_dbg_vhci_hc("enter\n");
-
 	platform_device_unregister(&the_pdev);
 	platform_driver_unregister(&vhci_driver);
-
-	usbip_dbg_vhci_hc("bye\n");
 }
+
+module_init(vhci_init);
 module_exit(vhci_cleanup);
+
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_LICENSE("GPL");
+MODULE_VERSION(USBIP_VERSION);
diff -druN linux-2.6.39-libre/drivers/staging/usbip/vhci_rx.c linux-3.0-rc7-libre/drivers/staging/usbip/vhci_rx.c
--- linux-2.6.39-libre/drivers/staging/usbip/vhci_rx.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/usbip/vhci_rx.c	2011-07-11 19:51:52.000000000 -0400
@@ -17,16 +17,14 @@
  * USA.
  */
 
-#include <linux/slab.h>
 #include <linux/kthread.h>
+#include <linux/slab.h>
 
 #include "usbip_common.h"
 #include "vhci.h"
 
-
 /* get URB from transmitted urb queue. caller must hold vdev->priv_lock */
-struct urb *pickup_urb_and_free_priv(struct vhci_device *vdev,
-					    __u32 seqnum)
+struct urb *pickup_urb_and_free_priv(struct vhci_device *vdev, __u32 seqnum)
 {
 	struct vhci_priv *priv, *tmp;
 	struct urb *urb = NULL;
@@ -38,12 +36,12 @@
 			status = urb->status;
 
 			usbip_dbg_vhci_rx("find urb %p vurb %p seqnum %u\n",
-				    urb, priv, seqnum);
+					  urb, priv, seqnum);
 
 			/* TODO: fix logic here to improve indent situtation */
 			if (status != -EINPROGRESS) {
 				if (status == -ENOENT ||
-				     status == -ECONNRESET)
+				    status == -ECONNRESET)
 					dev_info(&urb->dev->dev,
 						 "urb %p was unlinked "
 						 "%ssynchronuously.\n", urb,
@@ -66,36 +64,30 @@
 }
 
 static void vhci_recv_ret_submit(struct vhci_device *vdev,
-						struct usbip_header *pdu)
+				 struct usbip_header *pdu)
 {
 	struct usbip_device *ud = &vdev->ud;
 	struct urb *urb;
 
 	spin_lock(&vdev->priv_lock);
-
 	urb = pickup_urb_and_free_priv(vdev, pdu->base.seqnum);
-
 	spin_unlock(&vdev->priv_lock);
 
 	if (!urb) {
-		usbip_uerr("cannot find a urb of seqnum %u\n",
-							pdu->base.seqnum);
-		usbip_uinfo("max seqnum %d\n",
-					atomic_read(&the_controller->seqnum));
+		pr_err("cannot find a urb of seqnum %u\n", pdu->base.seqnum);
+		pr_info("max seqnum %d\n",
+			atomic_read(&the_controller->seqnum));
 		usbip_event_add(ud, VDEV_EVENT_ERROR_TCP);
 		return;
 	}
 
-
 	/* unpack the pdu to a urb */
 	usbip_pack_pdu(pdu, urb, USBIP_RET_SUBMIT, 0);
 
-
 	/* recv transfer buffer */
 	if (usbip_recv_xbuff(ud, urb) < 0)
 		return;
 
-
 	/* recv iso_packet_descriptor */
 	if (usbip_recv_iso(ud, urb) < 0)
 		return;
@@ -107,7 +99,6 @@
 	if (usbip_dbg_flag_vhci_rx)
 		usbip_dump_urb(urb);
 
-
 	usbip_dbg_vhci_rx("now giveback urb %p\n", urb);
 
 	spin_lock(&the_controller->lock);
@@ -116,25 +107,23 @@
 
 	usb_hcd_giveback_urb(vhci_to_hcd(the_controller), urb, urb->status);
 
-
 	usbip_dbg_vhci_rx("Leave\n");
 
 	return;
 }
 
-
 static struct vhci_unlink *dequeue_pending_unlink(struct vhci_device *vdev,
-		struct usbip_header *pdu)
+						  struct usbip_header *pdu)
 {
 	struct vhci_unlink *unlink, *tmp;
 
 	spin_lock(&vdev->priv_lock);
 
 	list_for_each_entry_safe(unlink, tmp, &vdev->unlink_rx, list) {
-		usbip_uinfo("unlink->seqnum %lu\n", unlink->seqnum);
+		pr_info("unlink->seqnum %lu\n", unlink->seqnum);
 		if (unlink->seqnum == pdu->base.seqnum) {
 			usbip_dbg_vhci_rx("found pending unlink, %lu\n",
-							unlink->seqnum);
+					  unlink->seqnum);
 			list_del(&unlink->list);
 
 			spin_unlock(&vdev->priv_lock);
@@ -147,9 +136,8 @@
 	return NULL;
 }
 
-
 static void vhci_recv_ret_unlink(struct vhci_device *vdev,
-						struct usbip_header *pdu)
+				 struct usbip_header *pdu)
 {
 	struct vhci_unlink *unlink;
 	struct urb *urb;
@@ -158,15 +146,13 @@
 
 	unlink = dequeue_pending_unlink(vdev, pdu);
 	if (!unlink) {
-		usbip_uinfo("cannot find the pending unlink %u\n",
-							pdu->base.seqnum);
+		pr_info("cannot find the pending unlink %u\n",
+			pdu->base.seqnum);
 		return;
 	}
 
 	spin_lock(&vdev->priv_lock);
-
 	urb = pickup_urb_and_free_priv(vdev, unlink->unlink_seqnum);
-
 	spin_unlock(&vdev->priv_lock);
 
 	if (!urb) {
@@ -175,21 +161,21 @@
 		 * already received the result of its submit result and gave
 		 * back the URB.
 		 */
-		usbip_uinfo("the urb (seqnum %d) was already given backed\n",
-							pdu->base.seqnum);
+		pr_info("the urb (seqnum %d) was already given backed\n",
+			pdu->base.seqnum);
 	} else {
 		usbip_dbg_vhci_rx("now giveback urb %p\n", urb);
 
 		/* If unlink is succeed, status is -ECONNRESET */
 		urb->status = pdu->u.ret_unlink.status;
-		usbip_uinfo("%d\n", urb->status);
+		pr_info("urb->status %d\n", urb->status);
 
 		spin_lock(&the_controller->lock);
 		usb_hcd_unlink_urb_from_ep(vhci_to_hcd(the_controller), urb);
 		spin_unlock(&the_controller->lock);
 
 		usb_hcd_giveback_urb(vhci_to_hcd(the_controller), urb,
-								urb->status);
+				     urb->status);
 	}
 
 	kfree(unlink);
@@ -202,9 +188,7 @@
 	int empty = 0;
 
 	spin_lock(&vdev->priv_lock);
-
 	empty = list_empty(&vdev->priv_rx);
-
 	spin_unlock(&vdev->priv_lock);
 
 	return empty;
@@ -217,7 +201,6 @@
 	struct usbip_header pdu;
 	struct vhci_device *vdev = container_of(ud, struct vhci_device, ud);
 
-
 	usbip_dbg_vhci_rx("Enter\n");
 
 	memset(&pdu, 0, sizeof(pdu));
@@ -226,26 +209,26 @@
 	ret = usbip_xmit(0, ud->tcp_socket, (char *) &pdu, sizeof(pdu), 0);
 	if (ret < 0) {
 		if (ret == -ECONNRESET)
-			usbip_uinfo("connection reset by peer\n");
+			pr_info("connection reset by peer\n");
 		else if (ret == -EAGAIN) {
 			/* ignore if connection was idle */
 			if (vhci_priv_tx_empty(vdev))
 				return;
-			usbip_uinfo("connection timed out with pending urbs\n");
+			pr_info("connection timed out with pending urbs\n");
 		} else if (ret != -ERESTARTSYS)
-			usbip_uinfo("xmit failed %d\n", ret);
+			pr_info("xmit failed %d\n", ret);
 
 		usbip_event_add(ud, VDEV_EVENT_ERROR_TCP);
 		return;
 	}
 	if (ret == 0) {
-		usbip_uinfo("connection closed");
+		pr_info("connection closed");
 		usbip_event_add(ud, VDEV_EVENT_DOWN);
 		return;
 	}
 	if (ret != sizeof(pdu)) {
-		usbip_uerr("received pdu size is %d, should be %d\n",
-					ret, (unsigned int)sizeof(pdu));
+		pr_err("received pdu size is %d, should be %d\n", ret,
+		       (unsigned int)sizeof(pdu));
 		usbip_event_add(ud, VDEV_EVENT_ERROR_TCP);
 		return;
 	}
@@ -263,21 +246,18 @@
 		vhci_recv_ret_unlink(vdev, &pdu);
 		break;
 	default:
-		/* NOTREACHED */
-		usbip_uerr("unknown pdu %u\n", pdu.base.command);
+		/* NOT REACHED */
+		pr_err("unknown pdu %u\n", pdu.base.command);
 		usbip_dump_header(&pdu);
 		usbip_event_add(ud, VDEV_EVENT_ERROR_TCP);
+		break;
 	}
 }
 
-
-/*-------------------------------------------------------------------------*/
-
 int vhci_rx_loop(void *data)
 {
 	struct usbip_device *ud = data;
 
-
 	while (!kthread_should_stop()) {
 		if (usbip_event_happened(ud))
 			break;
diff -druN linux-2.6.39-libre/drivers/staging/usbip/vhci_sysfs.c linux-3.0-rc7-libre/drivers/staging/usbip/vhci_sysfs.c
--- linux-2.6.39-libre/drivers/staging/usbip/vhci_sysfs.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/usbip/vhci_sysfs.c	2011-07-11 19:51:52.000000000 -0400
@@ -17,12 +17,12 @@
  * USA.
  */
 
+#include <linux/kthread.h>
+#include <linux/net.h>
+
 #include "usbip_common.h"
 #include "vhci.h"
 
-#include <linux/in.h>
-#include <linux/kthread.h>
-
 /* TODO: refine locking ?*/
 
 /* Sysfs entry to show port status */
@@ -53,20 +53,19 @@
 		struct vhci_device *vdev = port_to_vdev(i);
 
 		spin_lock(&vdev->ud.lock);
-
 		out += sprintf(out, "%03u %03u ", i, vdev->ud.status);
 
 		if (vdev->ud.status == VDEV_ST_USED) {
 			out += sprintf(out, "%03u %08x ",
-					vdev->speed, vdev->devid);
+				       vdev->speed, vdev->devid);
 			out += sprintf(out, "%16p ", vdev->ud.tcp_socket);
 			out += sprintf(out, "%s", dev_name(&vdev->udev->dev));
 
-		} else
+		} else {
 			out += sprintf(out, "000 000 000 0000000000000000 0-0");
+		}
 
 		out += sprintf(out, "\n");
-
 		spin_unlock(&vdev->ud.lock);
 	}
 
@@ -90,7 +89,7 @@
 
 	spin_lock(&vdev->ud.lock);
 	if (vdev->ud.status == VDEV_ST_NULL) {
-		usbip_uerr("not connected %d\n", vdev->ud.status);
+		pr_err("not connected %d\n", vdev->ud.status);
 
 		/* unlock */
 		spin_unlock(&vdev->ud.lock);
@@ -118,7 +117,7 @@
 
 	/* check rhport */
 	if (rhport >= VHCI_NPORTS) {
-		usbip_uerr("invalid port %u\n", rhport);
+		dev_err(dev, "invalid port %u\n", rhport);
 		return -EINVAL;
 	}
 
@@ -127,6 +126,7 @@
 		return -EINVAL;
 
 	usbip_dbg_vhci_sysfs("Leave\n");
+
 	return count;
 }
 static DEVICE_ATTR(detach, S_IWUSR, NULL, store_detach);
@@ -136,7 +136,7 @@
 {
 	/* check rhport */
 	if ((rhport < 0) || (rhport >= VHCI_NPORTS)) {
-		usbip_uerr("port %u\n", rhport);
+		pr_err("port %u\n", rhport);
 		return -EINVAL;
 	}
 
@@ -148,7 +148,7 @@
 	case USB_SPEED_WIRELESS:
 		break;
 	default:
-		usbip_uerr("speed %d\n", speed);
+		pr_err("speed %d\n", speed);
 		return -EINVAL;
 	}
 
@@ -183,8 +183,7 @@
 	sscanf(buf, "%u %u %u %u", &rhport, &sockfd, &devid, &speed);
 
 	usbip_dbg_vhci_sysfs("rhport(%u) sockfd(%u) devid(%u) speed(%u)\n",
-				rhport, sockfd, devid, speed);
-
+			     rhport, sockfd, devid, speed);
 
 	/* check received parameters */
 	if (valid_args(rhport, speed) < 0)
@@ -199,9 +198,7 @@
 
 	/* begin a lock */
 	spin_lock(&the_controller->lock);
-
 	vdev = port_to_vdev(rhport);
-
 	spin_lock(&vdev->ud.lock);
 
 	if (vdev->ud.status != VDEV_ST_NULL) {
@@ -209,12 +206,12 @@
 		spin_unlock(&vdev->ud.lock);
 		spin_unlock(&the_controller->lock);
 
-		usbip_uerr("port %d already used\n", rhport);
+		dev_err(dev, "port %d already used\n", rhport);
 		return -EINVAL;
 	}
 
-	usbip_uinfo("rhport(%u) sockfd(%d) devid(%u) speed(%u)\n",
-				rhport, sockfd, devid, speed);
+	dev_info(dev, "rhport(%u) sockfd(%d) devid(%u) speed(%u)\n",
+		 rhport, sockfd, devid, speed);
 
 	vdev->devid         = devid;
 	vdev->speed         = speed;
diff -druN linux-2.6.39-libre/drivers/staging/usbip/vhci_tx.c linux-3.0-rc7-libre/drivers/staging/usbip/vhci_tx.c
--- linux-2.6.39-libre/drivers/staging/usbip/vhci_tx.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/usbip/vhci_tx.c	2011-07-11 19:51:52.000000000 -0400
@@ -17,29 +17,26 @@
  * USA.
  */
 
-#include <linux/slab.h>
 #include <linux/kthread.h>
+#include <linux/slab.h>
 
 #include "usbip_common.h"
 #include "vhci.h"
 
-
 static void setup_cmd_submit_pdu(struct usbip_header *pdup,  struct urb *urb)
 {
 	struct vhci_priv *priv = ((struct vhci_priv *)urb->hcpriv);
 	struct vhci_device *vdev = priv->vdev;
 
 	usbip_dbg_vhci_tx("URB, local devnum %u, remote devid %u\n",
-				usb_pipedevice(urb->pipe), vdev->devid);
+			  usb_pipedevice(urb->pipe), vdev->devid);
 
-	pdup->base.command = USBIP_CMD_SUBMIT;
-	pdup->base.seqnum  = priv->seqnum;
-	pdup->base.devid   = vdev->devid;
-	if (usb_pipein(urb->pipe))
-		pdup->base.direction = USBIP_DIR_IN;
-	else
-		pdup->base.direction = USBIP_DIR_OUT;
-	pdup->base.ep      = usb_pipeendpoint(urb->pipe);
+	pdup->base.command   = USBIP_CMD_SUBMIT;
+	pdup->base.seqnum    = priv->seqnum;
+	pdup->base.devid     = vdev->devid;
+	pdup->base.direction = usb_pipein(urb->pipe) ?
+		USBIP_DIR_IN : USBIP_DIR_OUT;
+	pdup->base.ep	     = usb_pipeendpoint(urb->pipe);
 
 	usbip_pack_pdu(pdup, urb, USBIP_CMD_SUBMIT, 1);
 
@@ -65,8 +62,6 @@
 	return NULL;
 }
 
-
-
 static int vhci_send_cmd_submit(struct vhci_device *vdev)
 {
 	struct vhci_priv *priv = NULL;
@@ -90,7 +85,6 @@
 
 		usbip_dbg_vhci_tx("setup txdata urb %p\n", urb);
 
-
 		/* 1. setup usbip_header */
 		setup_cmd_submit_pdu(&pdu_header, urb);
 		usbip_header_correct_endian(&pdu_header, 1);
@@ -124,8 +118,8 @@
 
 		ret = kernel_sendmsg(vdev->ud.tcp_socket, &msg, iov, 3, txsize);
 		if (ret != txsize) {
-			usbip_uerr("sendmsg failed!, retval %d for %zd\n", ret,
-									txsize);
+			pr_err("sendmsg failed!, ret=%d for %zd\n", ret,
+			       txsize);
 			kfree(iso_buffer);
 			usbip_event_add(&vdev->ud, VDEV_EVENT_ERROR_TCP);
 			return -1;
@@ -140,9 +134,6 @@
 	return total_size;
 }
 
-
-/*-------------------------------------------------------------------------*/
-
 static struct vhci_unlink *dequeue_from_unlink_tx(struct vhci_device *vdev)
 {
 	unsigned long flags;
@@ -182,7 +173,6 @@
 
 		usbip_dbg_vhci_tx("setup cmd unlink, %lu\n", unlink->seqnum);
 
-
 		/* 1. setup usbip_header */
 		pdu_header.base.command = USBIP_CMD_UNLINK;
 		pdu_header.base.seqnum  = unlink->seqnum;
@@ -198,13 +188,12 @@
 
 		ret = kernel_sendmsg(vdev->ud.tcp_socket, &msg, iov, 1, txsize);
 		if (ret != txsize) {
-			usbip_uerr("sendmsg failed!, retval %d for %zd\n", ret,
-									txsize);
+			pr_err("sendmsg failed!, ret=%d for %zd\n", ret,
+			       txsize);
 			usbip_event_add(&vdev->ud, VDEV_EVENT_ERROR_TCP);
 			return -1;
 		}
 
-
 		usbip_dbg_vhci_tx("send txdata\n");
 
 		total_size += txsize;
@@ -213,9 +202,6 @@
 	return total_size;
 }
 
-
-/*-------------------------------------------------------------------------*/
-
 int vhci_tx_loop(void *data)
 {
 	struct usbip_device *ud = data;
@@ -229,9 +215,9 @@
 			break;
 
 		wait_event_interruptible(vdev->waitq_tx,
-				(!list_empty(&vdev->priv_tx) ||
-				 !list_empty(&vdev->unlink_tx) ||
-				 kthread_should_stop()));
+					 (!list_empty(&vdev->priv_tx) ||
+					  !list_empty(&vdev->unlink_tx) ||
+					  kthread_should_stop()));
 
 		usbip_dbg_vhci_tx("pending urbs ?, now wake up\n");
 	}
diff -druN linux-2.6.39-libre/drivers/staging/vt6655/bssdb.c linux-3.0-rc7-libre/drivers/staging/vt6655/bssdb.c
--- linux-2.6.39-libre/drivers/staging/vt6655/bssdb.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/vt6655/bssdb.c	2011-07-11 19:51:52.000000000 -0400
@@ -1289,7 +1289,7 @@
              memset(pDevice->skb->cb, 0, sizeof(pDevice->skb->cb));
              netif_rx(pDevice->skb);
              pDevice->skb = dev_alloc_skb((int)pDevice->rx_buf_sz);
-         };
+         }
    #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
   // if(pDevice->bWPASuppWextEnabled == true)
       {
@@ -1489,7 +1489,7 @@
                     }
                 }
             }
-        };
+        }
 
         if ((pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) ||
             (pMgmt->eCurrMode == WMAC_MODE_ESS_AP)) {
@@ -1543,9 +1543,9 @@
                         }
                     }
                 }
-            };
+            }
         }
-    };
+    }
 
     return;
 
diff -druN linux-2.6.39-libre/drivers/staging/vt6655/device.h linux-3.0-rc7-libre/drivers/staging/vt6655/device.h
--- linux-2.6.39-libre/drivers/staging/vt6655/device.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/vt6655/device.h	2011-07-11 19:51:52.000000000 -0400
@@ -396,7 +396,7 @@
 
     struct pci_dev*             pcid;
 
-#if CONFIG_PM
+#ifdef CONFIG_PM
     u32                         pci_state[16];
 #endif
 
diff -druN linux-2.6.39-libre/drivers/staging/vt6655/device_main.c linux-3.0-rc7-libre/drivers/staging/vt6655/device_main.c
--- linux-2.6.39-libre/drivers/staging/vt6655/device_main.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/vt6655/device_main.c	2011-07-11 19:51:52.000000000 -0400
@@ -900,7 +900,7 @@
 	        if(ii>20)
 		  break;
               }
-           };
+           }
     return true;
 }
 
@@ -1446,7 +1446,7 @@
         if (!device_alloc_frag_buf(pDevice, pDeF)) {
             DBG_PRT(MSG_LEVEL_ERR,KERN_ERR "%s: can not alloc frag bufs\n",
                 pDevice->dev->name);
-        };
+        }
     }
     pDevice->cbDFCB = CB_MAX_RX_FRAG;
     pDevice->cbFreeDFCB = pDevice->cbDFCB;
@@ -2104,7 +2104,7 @@
         dev_kfree_skb_irq(skb);
         spin_unlock_irq(&pDevice->lock);
         return 0;
-    };
+    }
 
     cbMPDULen = skb->len;
     pbMPDU = skb->data;
@@ -2136,7 +2136,7 @@
     if (pDevice->bStopTx0Pkt == true) {
         dev_kfree_skb_irq(skb);
         return false;
-    };
+    }
 
     if (AVAIL_TD(pDevice, TYPE_TXDMA0) <= 0) {
         dev_kfree_skb_irq(skb);
@@ -2865,7 +2865,7 @@
             pDevice->bBeaconSent = false;
             if (pDevice->bEnablePSMode) {
                 PSbIsNextTBTTWakeUp((void *)pDevice);
-            };
+            }
 
             if ((pDevice->eOPMode == OP_MODE_AP) ||
                 (pDevice->eOPMode == OP_MODE_ADHOC)) {
@@ -2876,7 +2876,7 @@
 
             if (pDevice->eOPMode == OP_MODE_ADHOC && pDevice->pMgmt->wCurrATIMWindow > 0) {
                 // todo adhoc PS mode
-            };
+            }
 
         }
 
@@ -2885,7 +2885,7 @@
             if (pDevice->eOPMode == OP_MODE_ADHOC) {
                 pDevice->bIsBeaconBufReadySet = false;
                 pDevice->cbBeaconBufReadySetCnt = 0;
-            };
+            }
 
             if (pDevice->eOPMode == OP_MODE_AP) {
                 if(pMgmt->byDTIMCount > 0) {
diff -druN linux-2.6.39-libre/drivers/staging/vt6655/dpc.c linux-3.0-rc7-libre/drivers/staging/vt6655/dpc.c
--- linux-2.6.39-libre/drivers/staging/vt6655/dpc.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/vt6655/dpc.c	2011-07-11 19:51:52.000000000 -0400
@@ -700,7 +700,7 @@
                 pDevice->pMgmt->bInTIMWake = false;
             }
         }
-    };
+    }
 
     // Now it only supports 802.11g Infrastructure Mode, and support rate must up to 54 Mbps
     if (pDevice->bDiversityEnable && (FrameSize>50) &&
@@ -884,7 +884,7 @@
                      memset(pDevice->skb->cb, 0, sizeof(pDevice->skb->cb));
                      netif_rx(pDevice->skb);
                      pDevice->skb = dev_alloc_skb((int)pDevice->rx_buf_sz);
-                 };
+                 }
 
                 return false;
 
@@ -1049,7 +1049,7 @@
                                          );
                     DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "dpc: send vMgrDeAuthenBeginSta 1\n");
                     return true;
-                };
+                }
                 if (pMgmt->sNodeDBTable[iSANodeIndex].eNodeState < NODE_ASSOC) {
                     // send deassoc notification
                     // reason = (7) class 3 received from nonassoc sta
@@ -1061,7 +1061,7 @@
                                          );
                     DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "dpc: send vMgrDisassocBeginSta 2\n");
                     return true;
-                };
+                }
 
                 if (pMgmt->sNodeDBTable[iSANodeIndex].bPSEnable) {
                     // delcare received ps-poll event
@@ -1486,7 +1486,7 @@
                     bRelayOnly = true;
                 }
             }
-        };
+        }
     }
 
     if (bRelayOnly || bRelayAndForward) {
diff -druN linux-2.6.39-libre/drivers/staging/vt6655/ioctl.c linux-3.0-rc7-libre/drivers/staging/vt6655/ioctl.c
--- linux-2.6.39-libre/drivers/staging/vt6655/ioctl.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/vt6655/ioctl.c	2011-07-11 19:51:52.000000000 -0400
@@ -91,7 +91,7 @@
         if (copy_from_user(&sScanCmd, pReq->data, sizeof(SCmdScan))) {
 			result = -EFAULT;
 			break;
-		};
+		}
 
         pItemSSID = (PWLAN_IE_SSID)sScanCmd.ssid;
         if (pItemSSID->len != 0) {
@@ -128,7 +128,7 @@
         if (copy_from_user(&sZoneTypeCmd, pReq->data, sizeof(SCmdZoneTypeSet))) {
 			result = -EFAULT;
 			break;
-		};
+		}
 
           if(sZoneTypeCmd.bWrite==true) {
 	  //////write zonetype
@@ -167,7 +167,7 @@
 	   if (copy_to_user(pReq->data, &sZoneTypeCmd, sizeof(SCmdZoneTypeSet))) {
 			result = -EFAULT;
 			break;
-		};
+		}
 	}
 
 	     break;
@@ -186,7 +186,7 @@
         if (copy_from_user(&sJoinCmd, pReq->data, sizeof(SCmdBSSJoin))) {
 			result = -EFAULT;
 			break;
-		};
+		}
 
         pItemSSID = (PWLAN_IE_SSID)sJoinCmd.ssid;
         memset(pMgmt->abyDesireSSID, 0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1);
@@ -234,7 +234,7 @@
         if (copy_from_user(&sWEPCmd, pReq->data, sizeof(SCmdSetWEP))) {
 			result = -EFAULT;
 			break;
-		};
+		}
 	    if (sWEPCmd.bEnableWep != true) {
             pDevice->bEncryptionEnable = false;
             pDevice->eEncryptionStatus = Ndis802_11EncryptionDisabled;
@@ -300,7 +300,7 @@
         if (copy_to_user(pReq->data, &sLinkStatus, sizeof(SCmdLinkStatus))) {
 			result = -EFAULT;
 			break;
-		};
+		}
 
         break;
 
@@ -312,12 +312,12 @@
             if (!pBSS->bActive)
                 continue;
             cbListCount++;
-        };
+        }
         sList.uItem = cbListCount;
         if (copy_to_user(pReq->data, &sList, sizeof(SBSSIDList))) {
 			result = -EFAULT;
 			break;
-		};
+		}
         pReq->wResult = 0;
         break;
 
@@ -325,7 +325,7 @@
         if (copy_from_user(&sList, pReq->data, sizeof(SBSSIDList))) {
 			result = -EFAULT;
 			break;
-		};
+		}
         pList = (PSBSSIDList)kmalloc(sizeof(SBSSIDList) + (sList.uItem * sizeof(SBSSIDItem)), (int)GFP_ATOMIC);
         if (pList == NULL) {
             result = -ENOMEM;
@@ -367,7 +367,7 @@
         if (copy_to_user(pReq->data, pList, sizeof(SBSSIDList) + (sList.uItem * sizeof(SBSSIDItem)))) {
 			result = -EFAULT;
 			break;
-		};
+		}
         kfree(pList);
         pReq->wResult = 0;
         break;
@@ -376,14 +376,14 @@
         if (copy_to_user(pReq->data, &(pDevice->s802_11Counter), sizeof(SDot11MIBCount))) {
 			result = -EFAULT;
 			break;
-		};
+		}
         break;
 
     case WLAN_CMD_GET_STAT:
         if (copy_to_user(pReq->data, &(pDevice->scStatistic), sizeof(SStatCounter))) {
 			result = -EFAULT;
 			break;
-		};
+		}
         break;
     case WLAN_CMD_STOP_MAC:
 
@@ -427,7 +427,7 @@
         if (copy_from_user(&sValue, pReq->data, sizeof(SCmdValue))) {
 			result = -EFAULT;
 			break;
-		};
+		}
 		if (sValue.dwValue == 1) {
             if (vt6655_hostap_set_hostapd(pDevice, 1, 1) == 0){
                 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Enable HOSTAP\n");
@@ -455,7 +455,7 @@
         if (copy_from_user(&sValue, pReq->data, sizeof(SCmdValue))) {
 			result = -EFAULT;
 			break;
-		};
+		}
 
 		if (sValue.dwValue == 1) {
             pDevice->bEnable8021x = true;
@@ -475,7 +475,7 @@
         if (copy_from_user(&sValue, pReq->data, sizeof(SCmdValue))) {
 			result = -EFAULT;
 			break;
-		};
+		}
 
 		if (sValue.dwValue == 1) {
             pDevice->bEnableHostWEP = true;
@@ -494,7 +494,7 @@
         if (copy_from_user(&sValue, pReq->data, sizeof(SCmdValue))) {
 			result = -EFAULT;
 			break;
-		};
+		}
 		if (sValue.dwValue == 1) {
                      DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "up wpadev\n");
 		   memcpy(pDevice->wpadev->dev_addr, pDevice->dev->dev_addr, ETH_ALEN);
@@ -519,7 +519,7 @@
         if (copy_from_user(&sStartAPCmd, pReq->data, sizeof(SCmdStartAP))) {
 			result = -EFAULT;
 			break;
-		};
+		}
 
 	    if (sStartAPCmd.wBSSType == AP) {
 	        pMgmt->eConfigMode = WMAC_CONFIG_AP;
@@ -606,13 +606,13 @@
             if (!pNode->bActive)
                 continue;
             cbListCount++;
-        };
+        }
 
         sNodeList.uItem = cbListCount;
         if (copy_to_user(pReq->data, &sNodeList, sizeof(SNodeList))) {
 			result = -EFAULT;
 			break;
-		};
+		}
         pReq->wResult = 0;
         break;
 
@@ -621,7 +621,7 @@
         if (copy_from_user(&sNodeList, pReq->data, sizeof(SNodeList))) {
 			result = -EFAULT;
 			break;
-		};
+		}
         pNodeList = (PSNodeList)kmalloc(sizeof(SNodeList) + (sNodeList.uItem * sizeof(SNodeItem)), (int)GFP_ATOMIC);
         if (pNodeList == NULL) {
             result = -ENOMEM;
@@ -657,11 +657,11 @@
     		    if (jj >= pNodeList->uItem)
     		        break;
     		}
-		};
+		}
         if (copy_to_user(pReq->data, pNodeList, sizeof(SNodeList) + (sNodeList.uItem * sizeof(SNodeItem)))) {
 			result = -EFAULT;
 			break;
-		};
+		}
         kfree(pNodeList);
         pReq->wResult = 0;
         break;
diff -druN linux-2.6.39-libre/drivers/staging/vt6655/power.c linux-3.0-rc7-libre/drivers/staging/vt6655/power.c
--- linux-2.6.39-libre/drivers/staging/vt6655/power.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/vt6655/power.c	2011-07-11 19:51:52.000000000 -0400
@@ -221,7 +221,7 @@
         ((pDevice->dwIsr& ISR_RXDMA0) != 0) &&
         ((pDevice->dwIsr & ISR_RXDMA1) != 0)){
         return false;
-    };
+    }
 
     if (pMgmt->eCurrMode != WMAC_MODE_IBSS_STA) {
         if (bCheckCountToWakeUp &&
diff -druN linux-2.6.39-libre/drivers/staging/vt6655/rxtx.c linux-3.0-rc7-libre/drivers/staging/vt6655/rxtx.c
--- linux-2.6.39-libre/drivers/staging/vt6655/rxtx.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/vt6655/rxtx.c	2011-07-11 19:51:52.000000000 -0400
@@ -2902,13 +2902,13 @@
         if (pDevice->bEnableHostWEP) {
             uNodeIndex = 0;
             bNodeExist = true;
-        };
+        }
     }
     else {
         if (pDevice->bEnableHostWEP) {
             if (BSSDBbIsSTAInNodeDB(pDevice->pMgmt, (unsigned char *)(p80211Header->sA3.abyAddr1), &uNodeIndex))
                 bNodeExist = true;
-        };
+        }
         bNeedACK = true;
         pTxBufHead->wFIFOCtl |= FIFOCTL_NEEDACK;
     };
diff -druN linux-2.6.39-libre/drivers/staging/vt6655/wcmd.c linux-3.0-rc7-libre/drivers/staging/vt6655/wcmd.c
--- linux-2.6.39-libre/drivers/staging/vt6655/wcmd.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/vt6655/wcmd.c	2011-07-11 19:51:52.000000000 -0400
@@ -385,7 +385,7 @@
                 spin_unlock_irq(&pDevice->lock);
                 vCommandTimerWait((void *)pDevice, 10);
                 return;
-            };
+            }
 
             if (pMgmt->uScanChannel == 0 ) {
                 pMgmt->uScanChannel = pDevice->byMinChannel;
@@ -519,7 +519,7 @@
                 vCommandTimerWait((void *)pDevice, 10);
                 spin_unlock_irq(&pDevice->lock);
                 return;
-            };
+            }
             DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" CARDbRadioPowerOff\n");
 	//2008-09-02  <mark>	by chester
            // CARDbRadioPowerOff(pDevice);
@@ -532,7 +532,7 @@
                 vCommandTimerWait((void *)pDevice, 10);
                 spin_unlock_irq(&pDevice->lock);
                 return;
-            };
+            }
 //2008-09-02  <mark> by chester
            // CARDbRadioPowerOff(pDevice);
             s_bCommandComplete(pDevice);
@@ -619,7 +619,7 @@
                     vMgrCreateOwnIBSS((void *)pDevice, &Status);
                     if (Status != CMD_STATUS_SUCCESS){
                         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " WLAN_CMD_IBSS_CREATE fail ! \n");
-                    };
+                    }
                     BSSvAddMulticastNode(pDevice);
                 }
             }
@@ -631,7 +631,7 @@
                     vMgrCreateOwnIBSS((void *)pDevice, &Status);
                     if (Status != CMD_STATUS_SUCCESS){
                         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO" WLAN_CMD_IBSS_CREATE fail ! \n");
-                    };
+                    }
                     BSSvAddMulticastNode(pDevice);
                     if (netif_queue_stopped(pDevice->dev)){
                         netif_wake_queue(pDevice->dev);
@@ -783,7 +783,7 @@
                 vMgrCreateOwnIBSS((void *)pDevice, &Status);
                 if (Status != CMD_STATUS_SUCCESS){
                     DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " vMgrCreateOwnIBSS fail ! \n");
-                };
+                }
                 // alway turn off unicast bit
                 MACvRegBitsOff(pDevice->PortOffset, MAC_REG_RCR, RCR_UNICAST);
                 pDevice->byRxMode &= ~RCR_UNICAST;
@@ -814,7 +814,7 @@
                     }
                     pMgmt->sNodeDBTable[0].wEnQueueCnt--;
                 }
-            };
+            }
 
             // PS nodes tx
             for (ii = 1; ii < (MAX_NODE_NUM + 1); ii++) {
diff -druN linux-2.6.39-libre/drivers/staging/vt6655/wmgr.c linux-3.0-rc7-libre/drivers/staging/vt6655/wmgr.c
--- linux-2.6.39-libre/drivers/staging/vt6655/wmgr.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/vt6655/wmgr.c	2011-07-11 19:51:52.000000000 -0400
@@ -661,7 +661,7 @@
     if (*pStatus == CMD_STATUS_PENDING) {
         pMgmt->eCurrState = WMAC_STATE_IDLE;
         *pStatus = CMD_STATUS_SUCCESS;
-    };
+    }
 
     return;
 }
@@ -1019,7 +1019,7 @@
             (sFrame.pSuppRates == 0)){
             DBG_PORT80(0xCC);
             return;
-        };
+        }
 
         pMgmt->sAssocInfo.AssocInfo.ResponseFixedIEs.Capabilities = *(sFrame.pwCapInfo);
         pMgmt->sAssocInfo.AssocInfo.ResponseFixedIEs.StatusCode = *(sFrame.pwStatus);
@@ -1039,7 +1039,7 @@
             if ( (pMgmt->wCurrAID >> 14) != (BIT0 | BIT1) )
             {
                 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "AID from AP, has two msb clear.\n");
-            };
+            }
             DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "Association Successful, AID=%d.\n", pMgmt->wCurrAID & ~(BIT14|BIT15));
             pMgmt->eCurrState = WMAC_STATE_ASSOC;
             BSSvUpdateAPNode((void *)pDevice, sFrame.pwCapInfo, sFrame.pSuppRates, sFrame.pExtSuppRates);
@@ -1692,7 +1692,7 @@
         //try to send associate packet again because of inactivity timeout
       //  if (pMgmt->eCurrState == WMAC_STATE_ASSOC) {
        //     vMgrReAssocBeginSta((PSDevice)pDevice, pMgmt, &CmdStatus);
-      //  };
+      //  }
         if ((pDevice->bWPADEVUp) && (pDevice->skb != NULL)) {
              wpahdr = (viawget_wpa_header *)pDevice->skb->data;
              wpahdr->type = VIAWGET_DISASSOC_MSG;
@@ -1707,7 +1707,7 @@
              memset(pDevice->skb->cb, 0, sizeof(pDevice->skb->cb));
              netif_rx(pDevice->skb);
              pDevice->skb = dev_alloc_skb((int)pDevice->rx_buf_sz);
-         };
+         }
 
  #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
   // if(pDevice->bWPASuppWextEnabled == true)
@@ -1778,7 +1778,7 @@
                     netif_stop_queue(pDevice->dev);
                     pDevice->bLinkPass = false;
                 }
-            };
+            }
 
             if ((pDevice->bWPADEVUp) && (pDevice->skb != NULL)) {
                  wpahdr = (viawget_wpa_header *)pDevice->skb->data;
@@ -1793,7 +1793,7 @@
                  memset(pDevice->skb->cb, 0, sizeof(pDevice->skb->cb));
                  netif_rx(pDevice->skb);
                  pDevice->skb = dev_alloc_skb((int)pDevice->rx_buf_sz);
-           };
+           }
 
    #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
   // if(pDevice->bWPASuppWextEnabled == true)
@@ -1912,7 +1912,7 @@
         (sFrame.pSuppRates == 0) ) {
         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Rx beacon frame error\n");
         return;
-    };
+    }
 
 
     if (sFrame.pDSParms != NULL) {
@@ -2054,7 +2054,7 @@
                    sFrame.pSSID->len
                    ) == 0) {
             bIsSSIDEqual = true;
-        };
+        }
     }
 
     if ((WLAN_GET_CAP_INFO_ESS(*sFrame.pwCapInfo)== true) &&
@@ -2138,8 +2138,8 @@
     if (WLAN_GET_CAP_INFO_ESS(*sFrame.pwCapInfo)) {
         if (sFrame.pCFParms->wCFPDurRemaining > 0) {
             // TODO: deal with CFP period to set NAV
-        };
-    };
+        }
+    }
 
     HIDWORD(qwTimestamp) = cpu_to_le32(HIDWORD(*sFrame.pqwTimestamp));
     LODWORD(qwTimestamp) = cpu_to_le32(LODWORD(*sFrame.pqwTimestamp));
@@ -2160,7 +2160,7 @@
     }
     else if (HIDWORD(qwTimestamp) < HIDWORD(qwLocalTSF)) {
         bTSFOffsetPostive = false;
-    };
+    }
 
     if (bTSFOffsetPostive) {
         qwTSFOffset = CARDqGetTSFOffset(pRxPacket->byRxRate, (qwTimestamp), (qwLocalTSF));
@@ -2218,7 +2218,7 @@
                 if (pMgmt->bInTIM) {
                     PSvSendPSPOLL((PSDevice)pDevice);
 //                    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "BCN:PS-POLL sent..\n");
-                };
+                }
 
             }
             else {
@@ -2231,7 +2231,7 @@
                 }
                 if(PSbConsiderPowerDown(pDevice, false, false)) {
                    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "BCN: Power down now...\n");
-                };
+                }
             }
 
         }
@@ -2316,7 +2316,7 @@
                 pMgmt->sNodeDBTable[0].bActive = true;
                 pMgmt->sNodeDBTable[0].uInActiveCount = 0;
 
-            };
+            }
         }
         else if (bIsSSIDEqual) {
 
@@ -2356,9 +2356,9 @@
                      // Prepare beacon frame
                      bMgrPrepareBeaconToSend((void *)pDevice, pMgmt);
               //  }
-            };
+            }
         }
-    };
+    }
     // endian issue ???
     // Update TSF
     if (bUpdateTSF) {
@@ -2590,7 +2590,7 @@
             pMgmt->byCSSPK = KEY_CTL_WEP;
             pMgmt->byCSSGK = KEY_CTL_WEP;
         }
-    };
+    }
 
     pMgmt->byERPContext = 0;
 
@@ -2683,7 +2683,7 @@
        *pStatus = CMD_STATUS_RESOURCES;
         DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "BSS finding:BSS list is empty.\n");
        return;
-    };
+    }
 
     // memset(pMgmt->abyDesireBSSID, 0,  WLAN_BSSID_LEN);
     // Search known BSS list for prefer BSSID or SSID
@@ -2699,7 +2699,7 @@
        pItemSSID = (PWLAN_IE_SSID)pMgmt->abyDesireSSID;
        DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Scanning [%s] not found, disconnected !\n", pItemSSID->abySSID);
        return;
-    };
+    }
 
     DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "AP(BSS) finding:Found a AP(BSS)..\n");
     if (WLAN_GET_CAP_INFO_ESS(cpu_to_le16(pCurr->wCapInfo))){
@@ -3179,7 +3179,7 @@
             }
             wEndIndex = ii;
         }
-    };
+    }
 
 
     // Round start index down to nearest even number
@@ -4343,7 +4343,7 @@
         DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Probe resp:Fail addr:[%p] \n", pRxPacket->p80211Header);
         DBG_PORT80(0xCC);
         return;
-    };
+    }
 
     if(sFrame.pSSID->len == 0)
        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Rx Probe resp: SSID len = 0 \n");
@@ -4625,7 +4625,7 @@
             //DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "rx beacon\n");
             if (pMgmt->eScanState != WMAC_NO_SCANNING) {
                 bInScan = true;
-            };
+            }
             s_vMgrRxBeacon(pDevice, pMgmt, pRxPacket, bInScan);
             break;
 
diff -druN linux-2.6.39-libre/drivers/staging/vt6655/wpactl.c linux-3.0-rc7-libre/drivers/staging/vt6655/wpactl.c
--- linux-2.6.39-libre/drivers/staging/vt6655/wpactl.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/vt6655/wpactl.c	2011-07-11 19:51:52.000000000 -0400
@@ -653,7 +653,7 @@
 
          }
 
-    };
+    }
 
   kfree(ptempBSS);
 
@@ -679,7 +679,7 @@
         if (!pBSS->bActive)
             continue;
         count++;
-    };
+    }
 
     pBuf = kcalloc(count, sizeof(struct viawget_scan_result), (int)GFP_ATOMIC);
 
@@ -723,7 +723,7 @@
 
     if (copy_to_user(param->u.scan_results.buf, pBuf, sizeof(struct viawget_scan_result) * count)) {
 		ret = -EFAULT;
-	};
+	}
 	param->u.scan_results.scan_count = count;
     DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " param->u.scan_results.scan_count = %d\n", count)
 
@@ -832,7 +832,7 @@
 		break;
 	default:
 		pDevice->eEncryptionStatus = Ndis802_11EncryptionDisabled;
-	};
+	}
 
 //DavidWang add for WPA_supplicant support open/share mode
 
@@ -875,7 +875,7 @@
     if (pCurr == NULL){
     printk("wpa_set_associate---->hidden mode site survey before associate.......\n");
     bScheduleCommand((void *) pDevice, WLAN_CMD_BSSID_SCAN, pMgmt->abyDesireSSID);
-  };
+  }
 }
 /****************************************************************/
     bScheduleCommand((void *) pDevice, WLAN_CMD_SSID, NULL);
diff -druN linux-2.6.39-libre/drivers/staging/vt6656/bssdb.c linux-3.0-rc7-libre/drivers/staging/vt6656/bssdb.c
--- linux-2.6.39-libre/drivers/staging/vt6656/bssdb.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/vt6656/bssdb.c	2011-07-11 19:51:52.000000000 -0400
@@ -1192,7 +1192,7 @@
              memset(pDevice->skb->cb, 0, sizeof(pDevice->skb->cb));
              netif_rx(pDevice->skb);
              pDevice->skb = dev_alloc_skb((int)pDevice->rx_buf_sz);
-         };
+         }
    #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
   // if(pDevice->bWPASuppWextEnabled == TRUE)
       {
@@ -1416,7 +1416,7 @@
 			}
                 }
             }
-        };
+        }
 
 	if ((pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) ||
             (pMgmt->eCurrMode == WMAC_MODE_ESS_AP)) {
@@ -1472,9 +1472,9 @@
 		      }
                     }
                 }
-            };
+            }
         }
-    };
+    }
 
     return;
 
diff -druN linux-2.6.39-libre/drivers/staging/vt6656/dpc.c linux-3.0-rc7-libre/drivers/staging/vt6656/dpc.c
--- linux-2.6.39-libre/drivers/staging/vt6656/dpc.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/vt6656/dpc.c	2011-07-11 19:51:52.000000000 -0400
@@ -730,7 +730,7 @@
                 pMgmt->bInTIMWake = FALSE;
             }
         }
-    };
+    }
 
     // Now it only supports 802.11g Infrastructure Mode, and support rate must up to 54 Mbps
     if (pDevice->bDiversityEnable && (FrameSize>50) &&
@@ -913,7 +913,7 @@
                      memset(pDevice->skb->cb, 0, sizeof(pDevice->skb->cb));
                      netif_rx(pDevice->skb);
                      pDevice->skb = dev_alloc_skb((int)pDevice->rx_buf_sz);
-                 };
+                 }
 
                 return FALSE;
 
@@ -1045,7 +1045,7 @@
                                          );
                     DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "dpc: send vMgrDeAuthenBeginSta 1\n");
                     return TRUE;
-                };
+                }
                 if (pMgmt->sNodeDBTable[iSANodeIndex].eNodeState < NODE_ASSOC) {
                     // send deassoc notification
                     // reason = (7) class 3 received from nonassoc sta
@@ -1057,7 +1057,7 @@
                                          );
                     DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "dpc: send vMgrDisassocBeginSta 2\n");
                     return TRUE;
-                };
+                }
 
                 if (pMgmt->sNodeDBTable[iSANodeIndex].bPSEnable) {
                     // delcare received ps-poll event
@@ -1488,7 +1488,7 @@
                     bRelayOnly = TRUE;
                 }
             }
-        };
+        }
     }
 
     if (bRelayOnly || bRelayAndForward) {
diff -druN linux-2.6.39-libre/drivers/staging/vt6656/firmware.c linux-3.0-rc7-libre/drivers/staging/vt6656/firmware.c
--- linux-2.6.39-libre/drivers/staging/vt6656/firmware.c	2011-05-19 02:16:10.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/vt6656/firmware.c	2011-07-21 06:58:16.000000000 -0400
@@ -41,7 +41,7 @@
 //static int          msglevel                =MSG_LEVEL_DEBUG;
 
 #define FIRMWARE_VERSION	0x133		/* version 1.51 */
-#define FIRMWARE_NAME		"vntwusb/*(DEBLOBBED)*/
+#define FIRMWARE_NAME		"/*(DEBLOBBED)*/"
 
 #define FIRMWARE_CHUNK_SIZE	0x400
 
@@ -68,8 +68,6 @@
 	u16 wLength;
 	int ii;
 
-    printk("vt6656: missing Free firmware\n");
-    return (FALSE);
 	DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"---->Download firmware\n");
 	spin_unlock_irq(&pDevice->lock);
 
@@ -77,7 +75,7 @@
 		struct device *dev = &pDevice->usb->dev;
 		int rc;
 
-		rc = r/*(DEBLOBBED)*/e(&pDevice->firmware, FIRMWARE_NAME, dev);
+		rc = reject_firmware(&pDevice->firmware, FIRMWARE_NAME, dev);
 		if (rc) {
 			dev_err(dev, "firmware file %s request failed (%d)\n",
 				FIRMWARE_NAME, rc);
diff -druN linux-2.6.39-libre/drivers/staging/vt6656/ioctl.c linux-3.0-rc7-libre/drivers/staging/vt6656/ioctl.c
--- linux-2.6.39-libre/drivers/staging/vt6656/ioctl.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/vt6656/ioctl.c	2011-07-11 19:51:52.000000000 -0400
@@ -90,7 +90,7 @@
         if (copy_from_user(&sScanCmd, pReq->data, sizeof(SCmdScan))) {
 			result = -EFAULT;
 			break;
-		};
+		}
 
         pItemSSID = (PWLAN_IE_SSID)sScanCmd.ssid;
         if (pItemSSID->len != 0) {
@@ -124,7 +124,7 @@
         if (copy_from_user(&sZoneTypeCmd, pReq->data, sizeof(SCmdZoneTypeSet))) {
 			result = -EFAULT;
 			break;
-		};
+		}
 
           if(sZoneTypeCmd.bWrite==TRUE) {
 	  //////write zonetype
@@ -163,7 +163,7 @@
 	   if (copy_to_user(pReq->data, &sZoneTypeCmd, sizeof(SCmdZoneTypeSet))) {
 			result = -EFAULT;
 			break;
-		};
+		}
 	}
 
 	     break;
@@ -173,7 +173,7 @@
         if (copy_from_user(&sJoinCmd, pReq->data, sizeof(SCmdBSSJoin))) {
 			result = -EFAULT;
 			break;
-		};
+		}
 
         pItemSSID = (PWLAN_IE_SSID)sJoinCmd.ssid;
         memset(pMgmt->abyDesireSSID, 0, WLAN_IEHDR_LEN + WLAN_SSID_MAXLEN + 1);
@@ -223,7 +223,7 @@
         if (copy_from_user(&sWEPCmd, pReq->data, sizeof(SCmdSetWEP))) {
 			result = -EFAULT;
 			break;
-		};
+		}
 	    if (sWEPCmd.bEnableWep != TRUE) {
 	        int uu;
 
@@ -295,7 +295,7 @@
         if (copy_to_user(pReq->data, &sLinkStatus, sizeof(SCmdLinkStatus))) {
 			result = -EFAULT;
 			break;
-		};
+		}
 
         break;
 
@@ -307,12 +307,12 @@
             if (!pBSS->bActive)
                 continue;
             cbListCount++;
-        };
+        }
         sList.uItem = cbListCount;
         if (copy_to_user(pReq->data, &sList, sizeof(SBSSIDList))) {
 			result = -EFAULT;
 			break;
-		};
+		}
         pReq->wResult = 0;
         break;
 
@@ -320,7 +320,7 @@
         if (copy_from_user(&sList, pReq->data, sizeof(SBSSIDList))) {
 			result = -EFAULT;
 			break;
-		};
+		}
         pList = (PSBSSIDList)kmalloc(sizeof(SBSSIDList) + (sList.uItem * sizeof(SBSSIDItem)), (int)GFP_ATOMIC);
         if (pList == NULL) {
             result = -ENOMEM;
@@ -362,7 +362,7 @@
         if (copy_to_user(pReq->data, pList, sizeof(SBSSIDList) + (sList.uItem * sizeof(SBSSIDItem)))) {
 			result = -EFAULT;
 			break;
-		};
+		}
         kfree(pList);
         pReq->wResult = 0;
         break;
@@ -371,14 +371,14 @@
         if (copy_to_user(pReq->data, &(pDevice->s802_11Counter), sizeof(SDot11MIBCount))) {
 			result = -EFAULT;
 			break;
-		};
+		}
         break;
 
     case WLAN_CMD_GET_STAT:
         if (copy_to_user(pReq->data, &(pDevice->scStatistic), sizeof(SStatCounter))) {
 			result = -EFAULT;
 			break;
-		};
+		}
         break;
     case WLAN_CMD_STOP_MAC:
 
@@ -415,7 +415,7 @@
         if (copy_from_user(&sValue, pReq->data, sizeof(SCmdValue))) {
 			result = -EFAULT;
 			break;
-		};
+		}
 		if (sValue.dwValue == 1) {
             if (vt6656_hostap_set_hostapd(pDevice, 1, 1) == 0){
                 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Enable HOSTAP\n");
@@ -443,7 +443,7 @@
         if (copy_from_user(&sValue, pReq->data, sizeof(SCmdValue))) {
 			result = -EFAULT;
 			break;
-		};
+		}
 
 		if (sValue.dwValue == 1) {
             pDevice->bEnable8021x = TRUE;
@@ -463,7 +463,7 @@
         if (copy_from_user(&sValue, pReq->data, sizeof(SCmdValue))) {
 			result = -EFAULT;
 			break;
-		};
+		}
 
 		if (sValue.dwValue == 1) {
             pDevice->bEnableHostWEP = TRUE;
@@ -482,7 +482,7 @@
         if (copy_from_user(&sValue, pReq->data, sizeof(SCmdValue))) {
 			result = -EFAULT;
 			break;
-		};
+		}
 		if (sValue.dwValue == 1) {
                      DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "up wpadev\n");
 		   memcpy(pDevice->wpadev->dev_addr,
@@ -507,7 +507,7 @@
         if (copy_from_user(&sStartAPCmd, pReq->data, sizeof(SCmdStartAP))) {
 			result = -EFAULT;
 			break;
-		};
+		}
 
 	    if (sStartAPCmd.wBSSType == AP) {
 	        pMgmt->eConfigMode = WMAC_CONFIG_AP;
@@ -594,13 +594,13 @@
             if (!pNode->bActive)
                 continue;
             cbListCount++;
-        };
+        }
 
         sNodeList.uItem = cbListCount;
         if (copy_to_user(pReq->data, &sNodeList, sizeof(SNodeList))) {
 			result = -EFAULT;
 			break;
-		};
+		}
         pReq->wResult = 0;
         break;
 
@@ -609,7 +609,7 @@
         if (copy_from_user(&sNodeList, pReq->data, sizeof(SNodeList))) {
 			result = -EFAULT;
 			break;
-		};
+		}
         pNodeList = (PSNodeList)kmalloc(sizeof(SNodeList) + (sNodeList.uItem * sizeof(SNodeItem)), (int)GFP_ATOMIC);
         if (pNodeList == NULL) {
             result = -ENOMEM;
@@ -645,11 +645,11 @@
     		    if (jj >= pNodeList->uItem)
     		        break;
     		}
-		};
+		}
         if (copy_to_user(pReq->data, pNodeList, sizeof(SNodeList) + (sNodeList.uItem * sizeof(SNodeItem)))) {
 			result = -EFAULT;
 			break;
-		};
+		}
         kfree(pNodeList);
         pReq->wResult = 0;
         break;
diff -druN linux-2.6.39-libre/drivers/staging/vt6656/main_usb.c linux-3.0-rc7-libre/drivers/staging/vt6656/main_usb.c
--- linux-2.6.39-libre/drivers/staging/vt6656/main_usb.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/vt6656/main_usb.c	2011-07-11 19:51:52.000000000 -0400
@@ -709,7 +709,7 @@
 	        if(ii>20)
 		  break;
               }
-           };
+           }
     return TRUE;
 }
 
@@ -955,7 +955,6 @@
 	pDevice->pInterruptURB = usb_alloc_urb(0, GFP_ATOMIC);
 	if (pDevice->pInterruptURB == NULL) {
 	    DBG_PRT(MSG_LEVEL_ERR,KERN_ERR"Failed to alloc int urb\n");
-   	    usb_kill_urb(pDevice->pControlURB);
 	    usb_free_urb(pDevice->pControlURB);
 	    goto free_rx_tx;
 	}
@@ -963,8 +962,6 @@
     pDevice->intBuf.pDataBuf = kmalloc(MAX_INTERRUPT_SIZE, GFP_KERNEL);
 	if (pDevice->intBuf.pDataBuf == NULL) {
 	    DBG_PRT(MSG_LEVEL_ERR,KERN_ERR"Failed to alloc int buf\n");
-   	    usb_kill_urb(pDevice->pControlURB);
-   	    usb_kill_urb(pDevice->pInterruptURB);
 	    usb_free_urb(pDevice->pControlURB);
 	    usb_free_urb(pDevice->pInterruptURB);
 	    goto free_rx_tx;
@@ -995,7 +992,7 @@
             DBG_PRT(MSG_LEVEL_ERR,KERN_ERR "%s: can not alloc frag bufs\n",
                 pDevice->dev->name);
             goto free_frag;
-        };
+        }
     }
     pDevice->cbDFCB = CB_MAX_RX_FRAG;
     pDevice->cbFreeDFCB = pDevice->cbDFCB;
diff -druN linux-2.6.39-libre/drivers/staging/vt6656/rxtx.c linux-3.0-rc7-libre/drivers/staging/vt6656/rxtx.c
--- linux-2.6.39-libre/drivers/staging/vt6656/rxtx.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/vt6656/rxtx.c	2011-07-11 19:51:52.000000000 -0400
@@ -2441,13 +2441,13 @@
         if (pDevice->bEnableHostWEP) {
             uNodeIndex = 0;
             bNodeExist = TRUE;
-        };
+        }
     }
     else {
         if (pDevice->bEnableHostWEP) {
             if (BSSbIsSTAInNodeDB(pDevice, (PBYTE)(p80211Header->sA3.abyAddr1), &uNodeIndex))
                 bNodeExist = TRUE;
-        };
+        }
         bNeedACK = TRUE;
         pTxBufHead->wFIFOCtl |= FIFOCTL_NEEDACK;
     };
diff -druN linux-2.6.39-libre/drivers/staging/vt6656/wcmd.c linux-3.0-rc7-libre/drivers/staging/vt6656/wcmd.c
--- linux-2.6.39-libre/drivers/staging/vt6656/wcmd.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/vt6656/wcmd.c	2011-07-11 19:51:52.000000000 -0400
@@ -642,7 +642,7 @@
                     if (Status != CMD_STATUS_SUCCESS){
 			DBG_PRT(MSG_LEVEL_DEBUG,
 				KERN_INFO "WLAN_CMD_IBSS_CREATE fail!\n");
-                    };
+                    }
                     BSSvAddMulticastNode(pDevice);
                 }
                 s_bClearBSSID_SCAN(pDevice);
@@ -658,7 +658,7 @@
                     if (Status != CMD_STATUS_SUCCESS){
 			DBG_PRT(MSG_LEVEL_DEBUG,
 				KERN_INFO "WLAN_CMD_IBSS_CREATE fail!\n");
-                    };
+                    }
                     BSSvAddMulticastNode(pDevice);
                     s_bClearBSSID_SCAN(pDevice);
 /*
@@ -793,7 +793,7 @@
 		if (Status != CMD_STATUS_SUCCESS) {
 			DBG_PRT(MSG_LEVEL_DEBUG,
 				KERN_INFO "vMgrCreateOwnIBSS fail!\n");
-                };
+                }
                 // alway turn off unicast bit
                 MACvRegBitsOff(pDevice, MAC_REG_RCR, RCR_UNICAST);
                 pDevice->byRxMode &= ~RCR_UNICAST;
@@ -827,7 +827,7 @@
 
                     pMgmt->sNodeDBTable[0].wEnQueueCnt--;
                 }
-            };
+            }
 
             // PS nodes tx
             for (ii = 1; ii < (MAX_NODE_NUM + 1); ii++) {
diff -druN linux-2.6.39-libre/drivers/staging/vt6656/wmgr.c linux-3.0-rc7-libre/drivers/staging/vt6656/wmgr.c
--- linux-2.6.39-libre/drivers/staging/vt6656/wmgr.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/vt6656/wmgr.c	2011-07-11 19:51:52.000000000 -0400
@@ -593,7 +593,7 @@
     if (*pStatus == CMD_STATUS_PENDING) {
         pMgmt->eCurrState = WMAC_STATE_IDLE;
         *pStatus = CMD_STATUS_SUCCESS;
-    };
+    }
 
     return;
 }
@@ -942,7 +942,7 @@
 	    || (sFrame.pSuppRates == NULL)) {
 		DBG_PORT80(0xCC);
 		return;
-        };
+        }
 
         pMgmt->sAssocInfo.AssocInfo.ResponseFixedIEs.Capabilities = *(sFrame.pwCapInfo);
         pMgmt->sAssocInfo.AssocInfo.ResponseFixedIEs.StatusCode = *(sFrame.pwStatus);
@@ -962,7 +962,7 @@
             if ( (pMgmt->wCurrAID >> 14) != (BIT0 | BIT1) )
             {
                 DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "AID from AP, has two msb clear.\n");
-            };
+            }
             DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "Association Successful, AID=%d.\n", pMgmt->wCurrAID & ~(BIT14|BIT15));
             pMgmt->eCurrState = WMAC_STATE_ASSOC;
 	    BSSvUpdateAPNode((void *) pDevice,
@@ -1621,7 +1621,7 @@
              memset(pDevice->skb->cb, 0, sizeof(pDevice->skb->cb));
              netif_rx(pDevice->skb);
              pDevice->skb = dev_alloc_skb((int)pDevice->rx_buf_sz);
-         };
+         }
 
         //TODO: do something let upper layer know or
         //try to send associate packet again because of inactivity timeout
@@ -1636,7 +1636,7 @@
 		  pDevice->byReAssocCount ++;
 		  return;       //mike add: you'll retry for many times, so it cann't be regarded as disconnected!
               }
-        };
+        }
 
    #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
   // if(pDevice->bWPASuppWextEnabled == TRUE)
@@ -1710,7 +1710,7 @@
                     pDevice->bLinkPass = FALSE;
                     ControlvMaskByte(pDevice,MESSAGE_REQUEST_MACREG,MAC_REG_PAPEDELAY,LEDSTS_STS,LEDSTS_SLOW);
                 }
-            };
+            }
 
             if ((pDevice->bWPADEVUp) && (pDevice->skb != NULL)) {
                  wpahdr = (viawget_wpa_header *)pDevice->skb->data;
@@ -1725,7 +1725,7 @@
                  memset(pDevice->skb->cb, 0, sizeof(pDevice->skb->cb));
                  netif_rx(pDevice->skb);
                  pDevice->skb = dev_alloc_skb((int)pDevice->rx_buf_sz);
-           };
+           }
 
    #ifdef WPA_SUPPLICANT_DRIVER_WEXT_SUPPORT
   // if(pDevice->bWPASuppWextEnabled == TRUE)
@@ -1845,7 +1845,7 @@
 
 	DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Rx beacon frame error\n");
 	return;
-    };
+    }
 
     if( byCurrChannel > CB_MAX_CHANNEL_24G )
     {
@@ -1974,7 +1974,7 @@
                    sFrame.pSSID->len
                    ) == 0) {
             bIsSSIDEqual = TRUE;
-        };
+        }
     }
 
     if ((WLAN_GET_CAP_INFO_ESS(*sFrame.pwCapInfo)== TRUE) &&
@@ -2074,8 +2074,8 @@
     if (WLAN_GET_CAP_INFO_ESS(*sFrame.pwCapInfo)) {
         if (sFrame.pCFParms->wCFPDurRemaining > 0) {
             // TODO: deal with CFP period to set NAV
-        };
-    };
+        }
+    }
 
     HIDWORD(qwTimestamp) = cpu_to_le32(HIDWORD(*sFrame.pqwTimestamp));
     LODWORD(qwTimestamp) = cpu_to_le32(LODWORD(*sFrame.pqwTimestamp));
@@ -2096,7 +2096,7 @@
     }
     else if (HIDWORD(qwTimestamp) < HIDWORD(qwLocalTSF)) {
         bTSFOffsetPostive = FALSE;
-    };
+    }
 
     if (bTSFOffsetPostive) {
         qwTSFOffset = CARDqGetTSFOffset(pRxPacket->byRxRate, (qwTimestamp), (qwLocalTSF));
@@ -2154,7 +2154,7 @@
                 if (pMgmt->bInTIM) {
                     PSvSendPSPOLL((PSDevice)pDevice);
 //                    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "BCN:PS-POLL sent..\n");
-                };
+                }
 
             }
             else {
@@ -2167,7 +2167,7 @@
                 }
                 if(PSbConsiderPowerDown(pDevice, FALSE, FALSE)) {
                    DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "BCN: Power down now...\n");
-                };
+                }
             }
 
         }
@@ -2247,7 +2247,7 @@
                 pMgmt->sNodeDBTable[0].bActive = TRUE;
                 pMgmt->sNodeDBTable[0].uInActiveCount = 0;
 
-            };
+            }
         }
         else if (bIsSSIDEqual) {
 
@@ -2292,9 +2292,9 @@
                      // Prepare beacon frame
 			bMgrPrepareBeaconToSend((void *) pDevice, pMgmt);
               //  }
-            };
+            }
         }
-    };
+    }
     // endian issue ???
     // Update TSF
     if (bUpdateTSF) {
@@ -2556,7 +2556,7 @@
             pMgmt->byCSSPK = KEY_CTL_WEP;
             pMgmt->byCSSGK = KEY_CTL_WEP;
         }
-    };
+    }
 
     pMgmt->byERPContext = 0;
 
@@ -2614,7 +2614,7 @@
        *pStatus = CMD_STATUS_RESOURCES;
         DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "BSS finding:BSS list is empty.\n");
        return;
-    };
+    }
 
     // memset(pMgmt->abyDesireBSSID, 0,  WLAN_BSSID_LEN);
     // Search known BSS list for prefer BSSID or SSID
@@ -2630,7 +2630,7 @@
        pItemSSID = (PWLAN_IE_SSID)pMgmt->abyDesireSSID;
        DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "Scanning [%s] not found, disconnected !\n", pItemSSID->abySSID);
        return;
-    };
+    }
 
     DBG_PRT(MSG_LEVEL_NOTICE, KERN_INFO "AP(BSS) finding:Found a AP(BSS)..\n");
 
@@ -3061,7 +3061,7 @@
         MACvRegBitsOn(pDevice, MAC_REG_RCR, RCR_BSSID);
         pDevice->byRxMode |= RCR_BSSID;
         pMgmt->bCurrBSSIDFilterOn = TRUE;
-    };
+    }
 
     if (pDevice->byBBType == BB_TYPE_11A) {
         memcpy(pMgmt->abyCurrSuppRates, &abyCurrSuppRatesA[0], sizeof(abyCurrSuppRatesA));
@@ -3167,7 +3167,7 @@
             }
             wEndIndex = (WORD)ii;
         }
-    };
+    }
 
 
     // Round start index down to nearest even number
@@ -4209,7 +4209,7 @@
 		pRxPacket->p80211Header);
 	DBG_PORT80(0xCC);
 	return;
-    };
+    }
 
     if(sFrame.pSSID->len == 0)
        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Rx Probe resp: SSID len = 0 \n");
@@ -4491,7 +4491,7 @@
             //DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "rx beacon\n");
             if (pMgmt->eScanState != WMAC_NO_SCANNING) {
                 bInScan = TRUE;
-            };
+            }
             s_vMgrRxBeacon(pDevice, pMgmt, pRxPacket, bInScan);
             break;
 
diff -druN linux-2.6.39-libre/drivers/staging/vt6656/wpactl.c linux-3.0-rc7-libre/drivers/staging/vt6656/wpactl.c
--- linux-2.6.39-libre/drivers/staging/vt6656/wpactl.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/vt6656/wpactl.c	2011-07-11 19:51:52.000000000 -0400
@@ -660,7 +660,7 @@
 
          }
 
-    };
+    }
 
   kfree(ptempBSS);
 
@@ -673,7 +673,7 @@
         if (!pBSS->bActive)
             continue;
         count++;
-    };
+    }
 
     pBuf = kcalloc(count, sizeof(struct viawget_scan_result), (int)GFP_ATOMIC);
 
@@ -729,7 +729,7 @@
 
     if (copy_to_user(param->u.scan_results.buf, pBuf, sizeof(struct viawget_scan_result) * count)) {
 		ret = -EFAULT;
-	};
+	}
 	param->u.scan_results.scan_count = count;
     DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO " param->u.scan_results.scan_count = %d\n", count)
 
@@ -831,7 +831,7 @@
 		break;
 	default:
 		pDevice->eEncryptionStatus = Ndis802_11EncryptionDisabled;
-	};
+	}
 
            pMgmt->Roam_dbm = param->u.wpa_associate.roam_dbm;
          // if ((pMgmt->Roam_dbm > 40)&&(pMgmt->Roam_dbm<80))
@@ -886,7 +886,7 @@
     bScheduleCommand((void *) pDevice,
 		     WLAN_CMD_BSSID_SCAN,
 		     pMgmt->abyDesireSSID);
-  };
+  }
 }
 /****************************************************************/
 
diff -druN linux-2.6.39-libre/drivers/staging/westbridge/astoria/arch/arm/mach-omap2/cyashalomap_kernel.c linux-3.0-rc7-libre/drivers/staging/westbridge/astoria/arch/arm/mach-omap2/cyashalomap_kernel.c
--- linux-2.6.39-libre/drivers/staging/westbridge/astoria/arch/arm/mach-omap2/cyashalomap_kernel.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/westbridge/astoria/arch/arm/mach-omap2/cyashalomap_kernel.c	2011-07-11 19:51:52.000000000 -0400
@@ -768,7 +768,7 @@
 		cy_as_hal_print_message(KERN_INFO "%s virt_addr=%x\n",
 					gpio_vma_tab[i].name,
 					(u32)gpio_vma_tab[i].virt_addr);
-	};
+	}
 
 	/*
 	 * force OMAP_GPIO_126  to rleased state,
diff -druN linux-2.6.39-libre/drivers/staging/westbridge/astoria/block/cyasblkdev_block.c linux-3.0-rc7-libre/drivers/staging/westbridge/astoria/block/cyasblkdev_block.c
--- linux-2.6.39-libre/drivers/staging/westbridge/astoria/block/cyasblkdev_block.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/westbridge/astoria/block/cyasblkdev_block.c	2011-07-11 19:51:52.000000000 -0400
@@ -515,7 +515,7 @@
 	while (blk_end_request(gl_bd->queue.req,
 	status, blk_rq_sectors(gl_bd->queue.req)*512)) {
 		retry_cnt++;
-	};
+	}
 
 	#ifndef WESTBRIDGE_NDEBUG
 	cy_as_hal_print_message(
diff -druN linux-2.6.39-libre/drivers/staging/winbond/mto.c linux-3.0-rc7-libre/drivers/staging/winbond/mto.c
--- linux-2.6.39-libre/drivers/staging/winbond/mto.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/winbond/mto.c	2011-07-11 19:51:52.000000000 -0400
@@ -40,14 +40,9 @@
 	2, 4, 11, 22, 12, 18, 24, 36, 48, 72, 96, 108
 };
 
-static int TotalTxPkt;
-static int TotalTxPktRetry;
 /* this record the retry rate at different data rate */
 static int retryrate_rec[MTO_MAX_DATA_RATE_LEVELS];
 
-static int PeriodTotalTxPkt;
-static int PeriodTotalTxPktRetry;
-
 static u8 boSparseTxTraffic;
 
 void MTO_Init(struct wbsoft_priv *adapter);
@@ -174,9 +169,4 @@
 		MTO_HAL()->dto_tx_retry_count += index;
 		MTO_HAL()->dto_tx_frag_count += (index + 1);
 	}
-	TotalTxPkt++;
-	TotalTxPktRetry += (index + 1);
-
-	PeriodTotalTxPkt++;
-	PeriodTotalTxPktRetry += (index + 1);
 }
diff -druN linux-2.6.39-libre/drivers/staging/winbond/phy_calibration.c linux-3.0-rc7-libre/drivers/staging/winbond/phy_calibration.c
--- linux-2.6.39-libre/drivers/staging/winbond/phy_calibration.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/winbond/phy_calibration.c	2011-07-11 19:51:52.000000000 -0400
@@ -27,10 +27,10 @@
 #define DEG2RAD(X)      0.017453 * (X)
 
 static const s32 Angles[] = {
-    FIXED(DEG2RAD(45.0)),     FIXED(DEG2RAD(26.565)),   FIXED(DEG2RAD(14.0362)),
-    FIXED(DEG2RAD(7.12502)),  FIXED(DEG2RAD(3.57633)),  FIXED(DEG2RAD(1.78991)),
-    FIXED(DEG2RAD(0.895174)), FIXED(DEG2RAD(0.447614)), FIXED(DEG2RAD(0.223811)),
-    FIXED(DEG2RAD(0.111906)), FIXED(DEG2RAD(0.055953)), FIXED(DEG2RAD(0.027977))
+	FIXED(DEG2RAD(45.0)),     FIXED(DEG2RAD(26.565)),   FIXED(DEG2RAD(14.0362)),
+	FIXED(DEG2RAD(7.12502)),  FIXED(DEG2RAD(3.57633)),  FIXED(DEG2RAD(1.78991)),
+	FIXED(DEG2RAD(0.895174)), FIXED(DEG2RAD(0.447614)), FIXED(DEG2RAD(0.223811)),
+	FIXED(DEG2RAD(0.111906)), FIXED(DEG2RAD(0.055953)), FIXED(DEG2RAD(0.027977))
 };
 
 /****************** LOCAL FUNCTION DECLARATION SECTION **********************/
diff -druN linux-2.6.39-libre/drivers/staging/winbond/wb35tx.c linux-3.0-rc7-libre/drivers/staging/winbond/wb35tx.c
--- linux-2.6.39-libre/drivers/staging/winbond/wb35tx.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/winbond/wb35tx.c	2011-07-11 19:51:52.000000000 -0400
@@ -291,7 +291,6 @@
 	if (atomic_inc_return(&pWb35Tx->TxResultCount) == 1) {
 		pWb35Tx->EP2vm_state = VM_RUNNING;
 		Wb35Tx_EP2VM(adapter);
-	}
-	else
+	} else
 		atomic_dec(&pWb35Tx->TxResultCount);
 }
diff -druN linux-2.6.39-libre/drivers/staging/wlags49_h2/ap_h25.c linux-3.0-rc7-libre/drivers/staging/wlags49_h2/ap_h25.c
--- linux-2.6.39-libre/drivers/staging/wlags49_h2/ap_h25.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/staging/wlags49_h2/ap_h25.c	2011-07-21 06:56:22.000000000 -0400
@@ -0,0 +1 @@
+extern int deblobbed; /*(DEBLOBBED)*/
diff -druN linux-2.6.39-libre/drivers/staging/wlags49_h2/ap_h2.c linux-3.0-rc7-libre/drivers/staging/wlags49_h2/ap_h2.c
--- linux-2.6.39-libre/drivers/staging/wlags49_h2/ap_h2.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/staging/wlags49_h2/ap_h2.c	2011-07-21 06:56:16.000000000 -0400
@@ -0,0 +1 @@
+extern int deblobbed; /*(DEBLOBBED)*/
diff -druN linux-2.6.39-libre/drivers/staging/wlags49_h2/sta_h25.c linux-3.0-rc7-libre/drivers/staging/wlags49_h2/sta_h25.c
--- linux-2.6.39-libre/drivers/staging/wlags49_h2/sta_h25.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/staging/wlags49_h2/sta_h25.c	2011-07-21 06:56:22.000000000 -0400
@@ -0,0 +1 @@
+extern int deblobbed; /*(DEBLOBBED)*/
diff -druN linux-2.6.39-libre/drivers/staging/wlags49_h2/sta_h2.c linux-3.0-rc7-libre/drivers/staging/wlags49_h2/sta_h2.c
--- linux-2.6.39-libre/drivers/staging/wlags49_h2/sta_h2.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/staging/wlags49_h2/sta_h2.c	2011-07-21 06:56:16.000000000 -0400
@@ -0,0 +1 @@
+extern int deblobbed; /*(DEBLOBBED)*/
diff -druN linux-2.6.39-libre/drivers/staging/wlags49_h2/wl_cs.c linux-3.0-rc7-libre/drivers/staging/wlags49_h2/wl_cs.c
--- linux-2.6.39-libre/drivers/staging/wlags49_h2/wl_cs.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/wlags49_h2/wl_cs.c	2011-07-11 19:51:52.000000000 -0400
@@ -378,7 +378,7 @@
 } /* wl_adapter_close */
 /*============================================================================*/
 
-static struct pcmcia_device_id wl_adapter_ids[] = {
+static const struct pcmcia_device_id wl_adapter_ids[] = {
 #if !((HCF_TYPE) & HCF_TYPE_HII5)
 	PCMCIA_DEVICE_MANF_CARD(0x0156, 0x0003),
 	PCMCIA_DEVICE_PROD_ID12("Agere Systems", "Wireless PC Card Model 0110",
diff -druN linux-2.6.39-libre/drivers/staging/wlags49_h2/wl_main.c linux-3.0-rc7-libre/drivers/staging/wlags49_h2/wl_main.c
--- linux-2.6.39-libre/drivers/staging/wlags49_h2/wl_main.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/wlags49_h2/wl_main.c	2011-07-21 06:56:18.000000000 -0400
@@ -1132,7 +1132,8 @@
 		if ( cp == NULL ) {
 			DBG_TRACE( DbgInfo, "Downloading STA firmware...\n" );
 //			hcf_status = dhf_download_fw( &lp->hcfCtx, &station );
-			hcf_status = dhf_download_fw( &lp->hcfCtx, &fw_image );
+//			hcf_status = dhf_download_fw( &lp->hcfCtx, &fw_image ); /*(DEBLOBBED)*/
+			hcf_status = HCF_ERR_INCOMP_FW;
 		}
 		if ( hcf_status != HCF_SUCCESS ) {
 			DBG_ERROR( DbgInfo, "Firmware Download failed\n" );
diff -druN linux-2.6.39-libre/drivers/staging/wlan-ng/cfg80211.c linux-3.0-rc7-libre/drivers/staging/wlan-ng/cfg80211.c
--- linux-2.6.39-libre/drivers/staging/wlan-ng/cfg80211.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/wlan-ng/cfg80211.c	2011-07-11 19:51:52.000000000 -0400
@@ -695,7 +695,7 @@
 
 void prism2_roamed(wlandevice_t *wlandev)
 {
-	cfg80211_roamed(wlandev->netdev, wlandev->bssid,
+	cfg80211_roamed(wlandev->netdev, NULL, wlandev->bssid,
 		NULL, 0, NULL, 0, GFP_KERNEL);
 }
 
diff -druN linux-2.6.39-libre/drivers/staging/xgifb/vb_def.h linux-3.0-rc7-libre/drivers/staging/xgifb/vb_def.h
--- linux-2.6.39-libre/drivers/staging/xgifb/vb_def.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/xgifb/vb_def.h	2011-07-11 19:51:52.000000000 -0400
@@ -1,4 +1,5 @@
-/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/xgi/initdef.h,v 1.4 2000/12/02 01:16:17 dawes Exp $ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/xgi/initdef.h
+ * ,v 1.4 2000/12/02 01:16:17 dawes Exp $*/
 #ifndef _INITDEF_
 #define _INITDEF_
 
@@ -7,38 +8,38 @@
 #endif
 /* shampoo */
 
-#define SEQ_ADDRESS_PORT	  0x0014
-#define SEQ_DATA_PORT		  0x0015
-#define MISC_OUTPUT_REG_READ_PORT 0x001C
-#define MISC_OUTPUT_REG_WRITE_PORT 0x0012
-#define GRAPH_DATA_PORT		  0x1F
-#define GRAPH_ADDRESS_PORT	  0x1E
-#define XGI_MASK_DUAL_CHIP	  0x04  /* SR3A */
-#define CRTC_ADDRESS_PORT_COLOR   0x0024
+#define SEQ_ADDRESS_PORT            0x0014
+#define SEQ_DATA_PORT               0x0015
+#define MISC_OUTPUT_REG_READ_PORT   0x001C
+#define MISC_OUTPUT_REG_WRITE_PORT  0x0012
+#define GRAPH_DATA_PORT             0x1F
+#define GRAPH_ADDRESS_PORT          0x1E
+#define XGI_MASK_DUAL_CHIP          0x04  /* SR3A */
+#define CRTC_ADDRESS_PORT_COLOR     0x0024
 #define VIDEO_SUBSYSTEM_ENABLE_PORT 0x0013
-#define PCI_COMMAND		0x04
+#define PCI_COMMAND                 0x04
 
 /* ~shampoo */
 
 
-#define VB_XGI301	      0x0001  /*301b*/
-#define VB_XGI301B        0x0002
-#define VB_XGI302B        0x0004
+#define VB_XGI301       0x0001 /*301b*/
+#define VB_XGI301B      0x0002
+#define VB_XGI302B      0x0004
 #define VB_XGI301LV     0x0008 /*301lv*/
 #define VB_XGI302LV     0x0010
-#define VB_XGI301C      0x0020       /* for 301C */
-#define  VB_NoLCD        0x8000
+#define VB_XGI301C      0x0020 /* for 301C */
+#define  VB_NoLCD       0x8000
 /*end 301b*/
 
-#define VB_YPbPrInfo     0x07          /*301lv*/
-#define VB_YPbPr525i     0x00
-#define VB_YPbPr525p     0x01
-#define VB_YPbPr750p     0x02
-#define VB_YPbPr1080i    0x03
+#define VB_YPbPrInfo    0x07   /*301lv*/
+#define VB_YPbPr525i    0x00
+#define VB_YPbPr525p    0x01
+#define VB_YPbPr750p    0x02
+#define VB_YPbPr1080i   0x03
 
 /* #define CRT1Len 17 */
-#define LVDSCRT1Len             15
-#define CHTVRegDataLen          5
+#define LVDSCRT1Len     15
+#define CHTVRegDataLen  5
 
 /* #define ModeInfoFlag 0x07 */
 /* #define IsTextMode 0x07 */
@@ -70,8 +71,8 @@
 #define NoSupportTV             0x0070
 #define NoSupportHiVisionTV     0x0060
 #define NoSupportLCD            0x0058
-#define SupportCHTV 		0x0800
-#define SupportCRT2in301C       0x0100       /* for 301C */
+#define SupportCHTV             0x0800
+#define SupportCRT2in301C       0x0100  /* for 301C */
 #define SupportTV1024           0x0800  /*301b*/
 #define SupportYPbPr            0x1000  /*301lv*/
 #define InterlaceMode           0x0080
@@ -104,7 +105,7 @@
 #define DisableCRT2Display      0x2000
 #define DriverMode              0x4000
 #define HotKeySwitch            0x8000
-#define SetCHTVOverScan  	0x8000
+#define SetCHTVOverScan         0x8000
 /* #define SetCRT2ToLCDA 0x8000 301b */
 #define PanelRGB18Bit           0x0100
 #define PanelRGB24Bit           0x0000
@@ -112,8 +113,8 @@
 #define TVOverScan              0x10
 #define TVOverScanShift         4
 #define ClearBufferFlag         0x20
-#define EnableDualEdge 		0x01		/*301b*/
-#define SetToLCDA		0x02
+#define EnableDualEdge          0x01 /*301b*/
+#define SetToLCDA               0x02
 
 #define YPbPrModeInfo           0x38
 /* #define YPbPrMode525i 0x00 */
@@ -123,7 +124,7 @@
 
 #define SetSCARTOutput          0x01
 #define BoardTVType             0x02
-#define  EnablePALMN           0x40
+#define  EnablePALMN            0x40
 /* #define ProgrammingCRT2 0x01 */
 /* #define TVSimuMode 0x02 */
 /* #define RPLLDIV2XO 0x04 */
@@ -133,9 +134,9 @@
 #define CheckWinDos             0x40
 #define SetJDOSMode             0x80
 
-#define Panel320x480              0x07/*fstn*/
+#define Panel320x480            0x07 /*fstn*/
 /* [ycchen] 02/12/03 Modify for Multi-Sync. LCD Support */
-#define PanelResInfo            0x1F	/* CR36 Panel Type/LCDResInfo */
+#define PanelResInfo            0x1F /* CR36 Panel Type/LCDResInfo */
 #define PanelRefInfo            0x60
 #define Panel800x600            0x01
 #define Panel1024x768           0x02
@@ -200,7 +201,7 @@
 #define SoftDramType            0x80
 #define VCLK40                  0x04
 
-#define VCLK162             	0x21
+#define VCLK162                 0x21
 
 #define LCDRGB18Bit             0x01
 #define LoadDACFlag             0x1000
@@ -228,11 +229,11 @@
 #define StStructSize            0x06
 
 
-#define XGI_CRT2_PORT_00        0x00 - 0x030
-#define XGI_CRT2_PORT_04        0x04 - 0x030
-#define XGI_CRT2_PORT_10        0x10 - 0x30
-#define XGI_CRT2_PORT_12        0x12 - 0x30
-#define XGI_CRT2_PORT_14        0x14 - 0x30
+#define XGI_CRT2_PORT_00        (0x00 - 0x030)
+#define XGI_CRT2_PORT_04        (0x04 - 0x030)
+#define XGI_CRT2_PORT_10        (0x10 - 0x30)
+#define XGI_CRT2_PORT_12        (0x12 - 0x30)
+#define XGI_CRT2_PORT_14        (0x14 - 0x30)
 
 
 #define LCDNonExpanding         0x10
@@ -274,8 +275,8 @@
 #define _PanelType0E             0x70
 #define _PanelType0F             0x78
 
-
-#define PRIMARY_VGA       0     /* 1: XGI is primary vga 0:XGI is secondary vga */
+/* 1: XGI is primary vga 0:XGI is secondary vga */
+#define PRIMARY_VGA             0
 #define BIOSIDCodeAddr          0x235
 #define OEMUtilIDCodeAddr       0x237
 #define VBModeIDTableAddr       0x239
@@ -362,656 +363,660 @@
 #define VideoSenseDataOffset  0xC1
 #define OutputSelectOffset    0xF3
 
-#define ECLK_MCLK_DISTANCE  0x14
+#define ECLK_MCLK_DISTANCE        0x14
 #define VBIOSTablePointerStart    0x200
-#define StandTablePtrOffset       VBIOSTablePointerStart+0x02
-#define EModeIDTablePtrOffset     VBIOSTablePointerStart+0x04
-#define CRT1TablePtrOffset        VBIOSTablePointerStart+0x06
-#define ScreenOffsetPtrOffset     VBIOSTablePointerStart+0x08
-#define VCLKDataPtrOffset         VBIOSTablePointerStart+0x0A
-#define MCLKDataPtrOffset         VBIOSTablePointerStart+0x0E
-#define CRT2PtrDataPtrOffset      VBIOSTablePointerStart+0x10
-#define TVAntiFlickPtrOffset      VBIOSTablePointerStart+0x12
-#define TVDelayPtr1Offset         VBIOSTablePointerStart+0x14
-#define TVPhaseIncrPtr1Offset     VBIOSTablePointerStart+0x16
-#define TVYFilterPtr1Offset       VBIOSTablePointerStart+0x18
-#define LCDDelayPtr1Offset        VBIOSTablePointerStart+0x20
-#define TVEdgePtr1Offset          VBIOSTablePointerStart+0x24
-#define CRT2Delay1Offset          VBIOSTablePointerStart+0x28
-#define LCDDataDesOffset     VBIOSTablePointerStart-0x02
-#define LCDDataPtrOffset          VBIOSTablePointerStart+0x2A
-#define LCDDesDataPtrOffset     VBIOSTablePointerStart+0x2C
-#define LCDDataList		VBIOSTablePointerStart+0x22	/* add for GetLCDPtr */
-#define TVDataList		VBIOSTablePointerStart+0x36	/* add for GetTVPtr */
+#define StandTablePtrOffset       (VBIOSTablePointerStart+0x02)
+#define EModeIDTablePtrOffset     (VBIOSTablePointerStart+0x04)
+#define CRT1TablePtrOffset        (VBIOSTablePointerStart+0x06)
+#define ScreenOffsetPtrOffset     (VBIOSTablePointerStart+0x08)
+#define VCLKDataPtrOffset         (VBIOSTablePointerStart+0x0A)
+#define MCLKDataPtrOffset         (VBIOSTablePointerStart+0x0E)
+#define CRT2PtrDataPtrOffset      (VBIOSTablePointerStart+0x10)
+#define TVAntiFlickPtrOffset      (VBIOSTablePointerStart+0x12)
+#define TVDelayPtr1Offset         (VBIOSTablePointerStart+0x14)
+#define TVPhaseIncrPtr1Offset     (VBIOSTablePointerStart+0x16)
+#define TVYFilterPtr1Offset       (VBIOSTablePointerStart+0x18)
+#define LCDDelayPtr1Offset        (VBIOSTablePointerStart+0x20)
+#define TVEdgePtr1Offset          (VBIOSTablePointerStart+0x24)
+#define CRT2Delay1Offset          (VBIOSTablePointerStart+0x28)
+#define LCDDataDesOffset          (VBIOSTablePointerStart-0x02)
+#define LCDDataPtrOffset          (VBIOSTablePointerStart+0x2A)
+#define LCDDesDataPtrOffset       (VBIOSTablePointerStart+0x2C)
+/* add LCDDataList for GetLCDPtr */
+#define LCDDataList               (VBIOSTablePointerStart+0x22)
+/* add TVDataList for GetTVPtr */
+#define TVDataList                (VBIOSTablePointerStart+0x36)
 /*  */
 /* Modify from 310.inc */
 /*  */
 /*  */
 
 
-#define		ShowMsgFlag                  0x20               /* SoftSetting */
-#define		ShowVESAFlag                 0x10
-#define		HotPlugFunction              0x08
-#define		ModeSoftSetting              0x04
-#define		TVSoftSetting                0x02
-#define		LCDSoftSetting               0x01
+#define ShowMsgFlag                  0x20    /* SoftSetting */
+#define ShowVESAFlag                 0x10
+#define HotPlugFunction              0x08
+#define ModeSoftSetting              0x04
+#define TVSoftSetting                0x02
+#define LCDSoftSetting               0x01
 
-#define		GatingCRTinLCDA              0x10
-#define		SetHiTVOutput                0x08
-#define		SetYPbPrOutput               0x04
-#define		BoardTVType                  0x02
-#define		SetSCARTOutput               0x01
+#define GatingCRTinLCDA              0x10
+#define SetHiTVOutput                0x08
+#define SetYPbPrOutput               0x04
+#define BoardTVType                  0x02
+#define SetSCARTOutput               0x01
 
-#define		ModeSettingYPbPr             0x02               /* TVModeSetting, Others as same as CR30 */
+/* TVModeSetting, Others as same as CR30 */
+#define ModeSettingYPbPr             0x02
 
 /* TVModeSetting same as CR35 */
 
 /* LCDModeSetting same as CR37 */
 
-#define		EnableNewTVFont              0x10               /* MiscCapability */
+#define EnableNewTVFont              0x10    /* MiscCapability */
 
-#define		EnableLCDOutput              0x80               /* LCDCfgSetting */
+#define EnableLCDOutput              0x80    /* LCDCfgSetting */
 
-#define		SoftDRAMType                 0x80               /* DRAMSetting */
-#define		SoftDRAMConfig               0x40
-#define		MosSelDRAMType               0x20
-#define		SDRAM                        000h
-#define		SGRAM                        0x01
-#define		ESDRAM                       0x02
+#define SoftDRAMType                 0x80    /* DRAMSetting */
+#define SoftDRAMConfig               0x40
+#define MosSelDRAMType               0x20
+#define SDRAM                        000h
+#define SGRAM                        0x01
+#define ESDRAM                       0x02
 
-#define		EnableAGPCfgSetting          0x01               /* AGPCfgSetting */
+#define EnableAGPCfgSetting          0x01    /* AGPCfgSetting */
 
 /* ---------------- SetMode Stack */
-#define		CRT1Len                      15
-#define		VCLKLen                      4
-#define		DefThreshold                 0x0100
-#define		ExtRegsSize                  (57+8+37+70+63+28+768+1)/64+1
+#define CRT1Len           15
+#define VCLKLen           4
+#define DefThreshold      0x0100
+#define ExtRegsSize       ((57+8+37+70+63+28+768+1)/64+1)
 
-#define		VGA_XGI315                   0x0001       /* VGA Type Info */
-#define		VGA_SNewis315e                  0x0002       /* 315 series */
-#define		VGA_XGI550                   0x0004
-#define		VGA_XGI640                   0x0008
-#define		VGA_XGI740                   0x0010
-#define		VGA_XGI650                   0x0020
-#define		VGA_XGI650M                  0x0040
-#define		VGA_XGI651                   0x0080
-#define		VGA_XGI340                   0x0001       /* 340 series */
-#define		VGA_XGI330                   0x0001       /* 330 series */
-#define		VGA_XGI660                   0x0001       /* 660 series */
+#define VGA_XGI315        0x0001       /* VGA Type Info */
+#define VGA_SNewis315e    0x0002       /* 315 series */
+#define VGA_XGI550        0x0004
+#define VGA_XGI640        0x0008
+#define VGA_XGI740        0x0010
+#define VGA_XGI650        0x0020
+#define VGA_XGI650M       0x0040
+#define VGA_XGI651        0x0080
+#define VGA_XGI340        0x0001       /* 340 series */
+#define VGA_XGI330        0x0001       /* 330 series */
+#define VGA_XGI660        0x0001       /* 660 series */
 
-#define		VB_XGI301                    0x0001       /* VB Type Info */
-#define		VB_XGI301B                   0x0002       /* 301 series */
-#define		VB_XGI302B                   0x0004
-#define		VB_NoLCD                     0x8000
-#define		VB_XGI301LV                  0x0008
-#define		VB_XGI302LV                  0x0010
-#define		VB_LVDS_NS                   0x0001       /* 3rd party chip */
-#define		VB_CH7017                    0x0002
-#define         VB_CH7007                    0x0080       /* [Billy] 07/05/03 */
+#define VB_XGI301         0x0001       /* VB Type Info */
+#define VB_XGI301B        0x0002       /* 301 series */
+#define VB_XGI302B        0x0004
+#define VB_NoLCD          0x8000
+#define VB_XGI301LV       0x0008
+#define VB_XGI302LV       0x0010
+#define VB_LVDS_NS        0x0001       /* 3rd party chip */
+#define VB_CH7017         0x0002
+#define VB_CH7007         0x0080       /* [Billy] 07/05/03 */
 /* #define VB_LVDS_SI 0x0004 */
 
-#define		ModeInfoFlag                 0x0007
-#define		IsTextMode                   0x0007
-#define		ModeText                     0x0000
-#define		ModeCGA                      0x0001
-#define		ModeEGA                      0x0002       /* 16 colors mode */
-#define		ModeVGA                      0x0003       /* 256 colors mode */
-#define		Mode15Bpp                    0x0004       /* 15 Bpp Color Mode */
-#define		Mode16Bpp                    0x0005       /* 16 Bpp Color Mode */
-#define		Mode24Bpp                    0x0006       /* 24 Bpp Color Mode */
-#define		Mode32Bpp                    0x0007       /* 32 Bpp Color Mode */
+#define ModeInfoFlag      0x0007
+#define IsTextMode        0x0007
+#define ModeText          0x0000
+#define ModeCGA           0x0001
+#define ModeEGA           0x0002    /* 16 colors mode */
+#define ModeVGA           0x0003    /* 256 colors mode */
+#define Mode15Bpp         0x0004    /* 15 Bpp Color Mode */
+#define Mode16Bpp         0x0005    /* 16 Bpp Color Mode */
+#define Mode24Bpp         0x0006    /* 24 Bpp Color Mode */
+#define Mode32Bpp         0x0007    /* 32 Bpp Color Mode */
 
-#define		DACInfoFlag                  0x0018
-#define		MONODAC                      0x0000
-#define		CGADAC                       0x0008
-#define		EGADAC                       0x0010
-#define		VGADAC                       0x0018
+#define DACInfoFlag       0x0018
+#define MONODAC           0x0000
+#define CGADAC            0x0008
+#define EGADAC            0x0010
+#define VGADAC            0x0018
 
-#define		MemoryInfoFlag               0x01e0
-#define		MemorySizeShift              5
-#define		Need1MSize                   0x0000
-#define		Need2MSize                   0x0020
-#define		Need4MSize                   0x0060
-#define		Need8MSize                   0x00e0
-#define		Need16MSize                  0x01e0
+#define MemoryInfoFlag    0x01e0
+#define MemorySizeShift   5
+#define Need1MSize        0x0000
+#define Need2MSize        0x0020
+#define Need4MSize        0x0060
+#define Need8MSize        0x00e0
+#define Need16MSize       0x01e0
 
-#define		Charx8Dot                    0x0200
-#define		LineCompareOff               0x0400
-#define		CRT2Mode                     0x0800
-#define		HalfDCLK                     0x1000
-#define		NoSupportSimuTV              0x2000
-#define		DoubleScanMode               0x8000
+#define Charx8Dot         0x0200
+#define LineCompareOff    0x0400
+#define CRT2Mode          0x0800
+#define HalfDCLK          0x1000
+#define NoSupportSimuTV   0x2000
+#define DoubleScanMode    0x8000
 
 /* -------------- Ext_InfoFlag */
-#define		SupportModeInfo              0x0007
-#define		Support256                   0x0003
-#define		Support15Bpp                 0x0004
-#define		Support16Bpp                 0x0005
-#define		Support24Bpp                 0x0006
-#define		Support32Bpp                 0x0007
+#define SupportModeInfo     0x0007
+#define Support256          0x0003
+#define Support15Bpp        0x0004
+#define Support16Bpp        0x0005
+#define Support24Bpp        0x0006
+#define Support32Bpp        0x0007
 
-#define		SupportAllCRT2               0x0078
-#define		SupportTV                    0x0008
-#define		SupportHiVisionTV            0x0010
-#define		SupportLCD                   0x0020
-#define		SupportRAMDAC2               0x0040
-#define		NoSupportTV                  0x0070
-#define		NoSupportHiVisionTV          0x0060
-#define		NoSupportLCD                 0x0058
-#define		SupportTV1024                0x0800       /* 301btest */
-#define		SupportYPbPr                 0x1000       /* 301lv */
-#define		InterlaceMode                0x0080
-#define		SyncPP                       0x0000
-#define		SyncPN                       0x4000
-#define		SyncNP                       0x8000
-#define		SyncNN                       0xC000
+#define SupportAllCRT2      0x0078
+#define SupportTV           0x0008
+#define SupportHiVisionTV   0x0010
+#define SupportLCD          0x0020
+#define SupportRAMDAC2      0x0040
+#define NoSupportTV         0x0070
+#define NoSupportHiVisionTV 0x0060
+#define NoSupportLCD        0x0058
+#define SupportTV1024       0x0800 /* 301btest */
+#define SupportYPbPr        0x1000 /* 301lv */
+#define InterlaceMode       0x0080
+#define SyncPP              0x0000
+#define SyncPN              0x4000
+#define SyncNP              0x8000
+#define SyncNN              0xC000
 
 /* -------------- SetMode Stack/Scratch */
-#define		SetSimuScanMode              0x0001       /* VBInfo/CR30 & CR31 */
-#define		SwitchToCRT2                 0x0002
-#define		SetCRT2ToTV1                 0x009C
-#define		SetCRT2ToTV                  0x089C
-#define		SetCRT2ToAVIDEO              0x0004
-#define		SetCRT2ToSVIDEO              0x0008
-#define		SetCRT2ToSCART               0x0010
-#define		SetCRT2ToLCD                 0x0020
-#define		SetCRT2ToRAMDAC              0x0040
-#define		SetCRT2ToHiVisionTV          0x0080
-#define		SetCRT2ToLCDA                0x0100
-#define		SetInSlaveMode               0x0200
-#define		SetNotSimuMode               0x0400
-#define		HKEventMode                  0x0800
-#define		SetCRT2ToYPbPr               0x0800
-#define		LoadDACFlag                  0x1000
-#define		DisableCRT2Display           0x2000
-#define		DriverMode                   0x4000
-#define		SetCRT2ToDualEdge            0x8000
-#define		HotKeySwitch                 0x8000
+#define SetSimuScanMode     0x0001    /* VBInfo/CR30 & CR31 */
+#define SwitchToCRT2        0x0002
+#define SetCRT2ToTV1        0x009C
+#define SetCRT2ToTV         0x089C
+#define SetCRT2ToAVIDEO     0x0004
+#define SetCRT2ToSVIDEO     0x0008
+#define SetCRT2ToSCART      0x0010
+#define SetCRT2ToLCD        0x0020
+#define SetCRT2ToRAMDAC     0x0040
+#define SetCRT2ToHiVisionTV 0x0080
+#define SetCRT2ToLCDA       0x0100
+#define SetInSlaveMode      0x0200
+#define SetNotSimuMode      0x0400
+#define HKEventMode         0x0800
+#define SetCRT2ToYPbPr      0x0800
+#define LoadDACFlag         0x1000
+#define DisableCRT2Display  0x2000
+#define DriverMode          0x4000
+#define SetCRT2ToDualEdge   0x8000
+#define HotKeySwitch        0x8000
 
-#define		ProgrammingCRT2              0x0001       /* Set Flag */
-#define		EnableVCMode                 0x0002
-#define		SetHKEventMode               0x0004
-#define		ReserveTVOption              0x0008
-#define		DisableRelocateIO            0x0010
-#define		Win9xDOSMode                 0x0020
-#define		JDOSMode                     0x0040
+#define ProgrammingCRT2     0x0001       /* Set Flag */
+#define EnableVCMode        0x0002
+#define SetHKEventMode      0x0004
+#define ReserveTVOption     0x0008
+#define DisableRelocateIO   0x0010
+#define Win9xDOSMode        0x0020
+#define JDOSMode            0x0040
 /* #define SetWin9xforJap 0x0080 // not used now */
 /* #define SetWin9xforKorea 0x0100 // not used now */
-#define		GatingCRT                    0x0800
-#define		DisableChB                   0x1000
-#define		EnableChB                    0x2000
-#define		DisableChA                   0x4000
-#define		EnableChA                    0x8000
+#define GatingCRT           0x0800
+#define DisableChB          0x1000
+#define EnableChB           0x2000
+#define DisableChA          0x4000
+#define EnableChA           0x8000
 
-#define		SetNTSCTV                    0x0000       /* TV Info */
-#define		SetPALTV                     0x0001
-#define		SetNTSCJ                     0x0002
-#define		SetPALMTV                    0x0004
-#define		SetPALNTV                    0x0008
-#define		SetCHTVUnderScan             0x0000
+#define SetNTSCTV           0x0000 /* TV Info */
+#define SetPALTV            0x0001
+#define SetNTSCJ            0x0002
+#define SetPALMTV           0x0004
+#define SetPALNTV           0x0008
+#define SetCHTVUnderScan    0x0000
 /* #define SetCHTVOverScan 0x0010 */
-#define		SetYPbPrMode525i             0x0020
-#define		SetYPbPrMode525p             0x0040
-#define		SetYPbPrMode750p             0x0080
-#define		SetYPbPrMode1080i            0x0100
-#define		SetTVStdMode                 0x0200
-#define		SetTVLowResolution           0x0400
-#define		SetTVSimuMode                0x0800
-#define		TVSimuMode                   0x0800
-#define		RPLLDIV2XO                   0x1000
-#define		NTSC1024x768                 0x2000
-#define		SetTVLockMode                0x4000
+#define SetYPbPrMode525i     0x0020
+#define SetYPbPrMode525p     0x0040
+#define SetYPbPrMode750p     0x0080
+#define SetYPbPrMode1080i    0x0100
+#define SetTVStdMode         0x0200
+#define SetTVLowResolution   0x0400
+#define SetTVSimuMode        0x0800
+#define TVSimuMode           0x0800
+#define RPLLDIV2XO           0x1000
+#define NTSC1024x768         0x2000
+#define SetTVLockMode        0x4000
 
-#define		LCDVESATiming                0x0001       /* LCD Info/CR37 */
-#define		EnableLVDSDDA                0x0002
-#define		EnableScalingLCD             0x0008
-#define		SetPWDEnable                 0x0004
-#define		SetLCDtoNonExpanding         0x0010
-#define		SetLCDPolarity               0x00e0
-#define		SetLCDDualLink               0x0100
-#define		SetLCDLowResolution          0x0200
-#define		SetLCDStdMode                0x0400
+#define LCDVESATiming        0x0001 /* LCD Info/CR37 */
+#define EnableLVDSDDA        0x0002
+#define EnableScalingLCD     0x0008
+#define SetPWDEnable         0x0004
+#define SetLCDtoNonExpanding 0x0010
+#define SetLCDPolarity       0x00e0
+#define SetLCDDualLink       0x0100
+#define SetLCDLowResolution  0x0200
+#define SetLCDStdMode        0x0400
 
-#define		DefaultLCDCap                0x80ea       /* LCD Capability shampoo */
-#define		RLVDSDHL00                   0x0000
-#define		RLVDSDHL01                   0x0001
-#define		RLVDSDHL10                   0x0002       /* default */
-#define		RLVDSDHL11                   0x0003
-#define		EnableLCD24bpp               0x0004       /* default */
-#define		DisableLCD24bpp              0x0000
-#define		RLVDSClkSFT0                 0x0000
-#define		RLVDSClkSFT1                 0x0008       /* default */
-#define		EnableLVDSDCBal              0x0010
-#define		DisableLVDSDCBal             0x0000       /* default */
-#define		SinglePolarity               0x0020       /* default */
-#define		MultiPolarity                0x0000
-#define		LCDPolarity                  0x00c0       /* default: SyncNN */
-#define		LCDSingleLink                0x0000       /* default */
-#define		LCDDualLink                  0x0100
-#define		EnableSpectrum               0x0200
-#define		DisableSpectrum              0x0000       /* default */
-#define		PWDEnable                    0x0400
-#define		PWDDisable                   0x0000       /* default */
-#define		PWMEnable                    0x0800
-#define		PWMDisable                   0x0000       /* default */
-#define		EnableVBCLKDRVLOW            0x4000
-#define		EnableVBCLKDRVHigh           0x0000       /* default */
-#define		EnablePLLSPLOW               0x8000
-#define		EnablePLLSPHigh              0x0000       /* default */
+/* LCD Capability shampoo */
+#define DefaultLCDCap        0x80ea
+#define RLVDSDHL00           0x0000
+#define RLVDSDHL01           0x0001
+#define RLVDSDHL10           0x0002 /* default */
+#define RLVDSDHL11           0x0003
+#define EnableLCD24bpp       0x0004 /* default */
+#define DisableLCD24bpp      0x0000
+#define RLVDSClkSFT0         0x0000
+#define RLVDSClkSFT1         0x0008 /* default */
+#define EnableLVDSDCBal      0x0010
+#define DisableLVDSDCBal     0x0000 /* default */
+#define SinglePolarity       0x0020 /* default */
+#define MultiPolarity        0x0000
+#define LCDPolarity          0x00c0 /* default: SyncNN */
+#define LCDSingleLink        0x0000 /* default */
+#define LCDDualLink          0x0100
+#define EnableSpectrum       0x0200
+#define DisableSpectrum      0x0000 /* default */
+#define PWDEnable            0x0400
+#define PWDDisable           0x0000 /* default */
+#define PWMEnable            0x0800
+#define PWMDisable           0x0000 /* default */
+#define EnableVBCLKDRVLOW    0x4000
+#define EnableVBCLKDRVHigh   0x0000 /* default */
+#define EnablePLLSPLOW       0x8000
+#define EnablePLLSPHigh      0x0000 /* default */
 
-#define		LCDBToA                      0x20               /* LCD SetFlag */
-#define		StLCDBToA                    0x40
-#define		LockLCDBToA                  0x80
-#define 	LCDToFull             	     0x10
-#define		AVIDEOSense                  0x01               /* CR32 */
-#define		SVIDEOSense                  0x02
-#define		SCARTSense                   0x04
-#define		LCDSense                     0x08
-#define		Monitor2Sense                0x10
-#define		Monitor1Sense                0x20
-#define		HiTVSense                    0x40
+#define LCDBToA              0x20   /* LCD SetFlag */
+#define StLCDBToA            0x40
+#define LockLCDBToA          0x80
+#define   LCDToFull          0x10
+#define AVIDEOSense          0x01   /* CR32 */
+#define SVIDEOSense          0x02
+#define SCARTSense           0x04
+#define LCDSense             0x08
+#define Monitor2Sense        0x10
+#define Monitor1Sense        0x20
+#define HiTVSense            0x40
 
-#ifdef                   NewScratch
-#define		YPbPrSense                   0x80    /* NEW SCRATCH */
+#ifdef NewScratch
+#define YPbPrSense           0x80   /* NEW SCRATCH */
 #endif
 
-#define		TVSense                      0xc7
+#define TVSense              0xc7
 
-#define		TVOverScan                   0x10               /* CR35 */
-#define		TVOverScanShift              4
+#define TVOverScan           0x10               /* CR35 */
+#define TVOverScanShift      4
 
-#ifdef                   NewScratch
-#define		NTSCMode                     0x00
-#define		PALMode                      0x00
-#define		NTSCJMode                    0x02
-#define		PALMNMode                    0x0c
-#define		YPbPrMode                    0xe0
-#define		YPbPrMode525i                0x00
-#define		YPbPrMode525p                0x20
-#define		YPbPrMode750p                0x40
-#define		YPbPrMode1080i               0x60
+#ifdef NewScratch
+#define NTSCMode             0x00
+#define PALMode              0x00
+#define NTSCJMode            0x02
+#define PALMNMode            0x0c
+#define YPbPrMode            0xe0
+#define YPbPrMode525i        0x00
+#define YPbPrMode525p        0x20
+#define YPbPrMode750p        0x40
+#define YPbPrMode1080i       0x60
 #else                    /* Old Scratch */
-#define		ClearBufferFlag              0x20
+#define ClearBufferFlag      0x20
 #endif
 
 
-#define		LCDRGB18Bit                  0x01               /* CR37 */
-#define		LCDNonExpanding              0x10
-#define		LCDNonExpandingShift         4
-#define		LCDSync                      0x20
-#define		LCDSyncBit                   0xe0               /* H/V polarity & sync ID */
-#define		LCDSyncShift                 6
+#define LCDRGB18Bit          0x01               /* CR37 */
+#define LCDNonExpanding      0x10
+#define LCDNonExpandingShift 4
+#define LCDSync              0x20
+#define LCDSyncBit           0xe0 /* H/V polarity & sync ID */
+#define LCDSyncShift         6
 
-#ifdef                   NewScratch
-#define		ScalingLCD                   0x08
-#else                    /* Old Scratch */
-#define		ExtChipType                  0x0e
-#define		ExtChip301                   0x02
-#define		ExtChipLVDS                  0x04
-#define		ExtChipCH7019                0x06
-#define		ScalingLCD                   0x10
+#ifdef NewScratch
+#define ScalingLCD           0x08
+#else  /* Old Scratch */
+#define ExtChipType          0x0e
+#define ExtChip301           0x02
+#define ExtChipLVDS          0x04
+#define ExtChipCH7019        0x06
+#define ScalingLCD           0x10
 #endif
 
-#define		EnableDualEdge               0x01               /* CR38 */
-#define		SetToLCDA                    0x02
-#ifdef                   NewScratch
-#define		SetYPbPr                     0x04
-#define		DisableChannelA              0x08
-#define		DisableChannelB              0x10
-#define		ExtChipType                  0xe0
-#define		ExtChip301                   0x20
-#define		ExtChipLVDS                  0x40
-#define		ExtChipCH7019                0x60
+#define EnableDualEdge       0x01 /* CR38 */
+#define SetToLCDA            0x02
+#ifdef NewScratch
+#define SetYPbPr             0x04
+#define DisableChannelA      0x08
+#define DisableChannelB      0x10
+#define ExtChipType          0xe0
+#define ExtChip301           0x20
+#define ExtChipLVDS          0x40
+#define ExtChipCH7019        0x60
 #else                    /* Old Scratch */
-#define		YPbPrSense                   0x04
-#define		SetYPbPr                     0x08
-#define		YPbPrMode                    0x30
-#define		YPbPrMode525i                0x00
-#define		YPbPrMode525p                0x10
-#define		YPbPrMode750p                0x20
-#define		YPbPrMode1080i               0x30
-#define		PALMNMode                    0xc0
+#define YPbPrSense           0x04
+#define SetYPbPr             0x08
+#define YPbPrMode            0x30
+#define YPbPrMode525i        0x00
+#define YPbPrMode525p        0x10
+#define YPbPrMode750p        0x20
+#define YPbPrMode1080i       0x30
+#define PALMNMode            0xc0
 #endif
 
-#define		BacklightControlBit          0x01               /* CR3A */
-#define		Win9xforJap                  0x40
-#define		Win9xforKorea                0x80
+#define BacklightControlBit  0x01 /* CR3A */
+#define Win9xforJap          0x40
+#define Win9xforKorea        0x80
 
-#define		ForceMDBits                  0x07               /* CR3B */
-#define		ForceMD_JDOS                 0x00
-#define		ForceMD_640x400T             0x01
-#define		ForceMD_640x350T             0x02
-#define		ForceMD_720x400T             0x03
-#define		ForceMD_640x480E             0x04
-#define		ForceMD_640x400E             0x05
-#define		ForceP1Bit                   0x10
-#define		ForceP2Bit                   0x20
-#define		EnableForceMDinBIOS          0x40
-#define		EnableForceMDinDrv           0x80
+#define ForceMDBits          0x07 /* CR3B */
+#define ForceMD_JDOS         0x00
+#define ForceMD_640x400T     0x01
+#define ForceMD_640x350T     0x02
+#define ForceMD_720x400T     0x03
+#define ForceMD_640x480E     0x04
+#define ForceMD_640x400E     0x05
+#define ForceP1Bit           0x10
+#define ForceP2Bit           0x20
+#define EnableForceMDinBIOS  0x40
+#define EnableForceMDinDrv   0x80
 
-#ifdef                   NewScratch                      /* New Scratch */
+#ifdef NewScratch /* New Scratch */
 /* ---------------------- VUMA Information */
-#define		LCDSettingFromCMOS           0x04               /* CR3C */
-#define		TVSettingFromCMOS            0x08
-#define		DisplayDeviceFromCMOS        0x10
-#define		HKSupportInSBIOS             0x20
-#define		OSDSupportInSBIOS            0x40
-#define		DisableLogo                  0x80
+#define LCDSettingFromCMOS    0x04 /* CR3C */
+#define TVSettingFromCMOS     0x08
+#define DisplayDeviceFromCMOS 0x10
+#define HKSupportInSBIOS      0x20
+#define OSDSupportInSBIOS     0x40
+#define DisableLogo           0x80
 
 /* ---------------------- HK Evnet Definition */
-#define		HKEvent                      0x0f               /* CR3D */
-#define		HK_ModeSwitch                0x01
-#define		HK_Expanding                 0x02
-#define		HK_OverScan                  0x03
-#define		HK_Brightness                0x04
-#define		HK_Contrast                  0x05
-#define		HK_Mute                      0x06
-#define		HK_Volume                    0x07
-#define		ModeSwitchStatus             0xf0
-#define		ActiveCRT1                   0x10
-#define		ActiveLCD                    0x0020
-#define		ActiveTV                     0x40
-#define		ActiveCRT2                   0x80
+#define HKEvent               0x0f /* CR3D */
+#define HK_ModeSwitch         0x01
+#define HK_Expanding          0x02
+#define HK_OverScan           0x03
+#define HK_Brightness         0x04
+#define HK_Contrast           0x05
+#define HK_Mute               0x06
+#define HK_Volume             0x07
+#define ModeSwitchStatus      0xf0
+#define ActiveCRT1            0x10
+#define ActiveLCD             0x0020
+#define ActiveTV              0x40
+#define ActiveCRT2            0x80
 
-#define		TVSwitchStatus               0x1f               /* CR3E */
-#define		ActiveAVideo                 0x01
-#define		ActiveSVideo                 0x02
-#define		ActiveSCART                  0x04
-#define		ActiveHiTV                   0x08
-#define		ActiveYPbPr                  0x10
+#define TVSwitchStatus        0x1f /* CR3E */
+#define ActiveAVideo          0x01
+#define ActiveSVideo          0x02
+#define ActiveSCART           0x04
+#define ActiveHiTV            0x08
+#define ActiveYPbPr           0x10
 
-#define		EnableHKEvent                0x01               /* CR3F */
-#define		EnableOSDEvent               0x02
-#define		StartOSDEvent                0x04
-#define		IgnoreHKEvent                0x08
-#define		IgnoreOSDEvent               0x10
+#define EnableHKEvent         0x01 /* CR3F */
+#define EnableOSDEvent        0x02
+#define StartOSDEvent         0x04
+#define IgnoreHKEvent         0x08
+#define IgnoreOSDEvent        0x10
 #else                    /* Old Scratch */
-#define		OSD_SBIOS                    0x02       /* SR17 */
-#define		DisableLogo                  0x04
-#define		SelectKDOS                   0x08
-#define		KorWinMode                   0x10
-#define		KorMode3Bit                  0x0020
-#define		PSCCtrlBit                  0x40
-#define		NPSCCtrlBitShift             6
-#define		BlueScreenBit                0x80
+#define OSD_SBIOS               0x02 /* SR17 */
+#define DisableLogo             0x04
+#define SelectKDOS              0x08
+#define KorWinMode              0x10
+#define KorMode3Bit             0x0020
+#define PSCCtrlBit              0x40
+#define NPSCCtrlBitShift        6
+#define BlueScreenBit           0x80
 
-#define		HKEvent                      0x0f       /* CR79 */
-#define		HK_ModeSwitch                0x01
-#define		HK_Expanding                 0x02
-#define		HK_OverScan                  0x03
-#define		HK_Brightness                0x04
-#define		HK_Contrast                  0x05
-#define		HK_Mute                      0x06
-#define		HK_Volume                    0x07
-#define		ActivePAL                    0x0020
-#define		ActivePALShift               5
-#define		ActiveNonExpanding           0x40
-#define		ActiveNonExpandingShift      6
-#define		ActiveOverScan               0x80
-#define		ActiveOverScanShift          7
+#define HKEvent                 0x0f /* CR79 */
+#define HK_ModeSwitch           0x01
+#define HK_Expanding            0x02
+#define HK_OverScan             0x03
+#define HK_Brightness           0x04
+#define HK_Contrast             0x05
+#define HK_Mute                 0x06
+#define HK_Volume               0x07
+#define ActivePAL               0x0020
+#define ActivePALShift          5
+#define ActiveNonExpanding      0x40
+#define ActiveNonExpandingShift 6
+#define ActiveOverScan          0x80
+#define ActiveOverScanShift     7
 
-#define		ModeSwitchStatus             0x0b       /* SR15 */
-#define		ActiveCRT1                   0x01
-#define		ActiveLCD                    0x02
-#define		ActiveCRT2                   0x08
+#define ModeSwitchStatus        0x0b /* SR15 */
+#define ActiveCRT1              0x01
+#define ActiveLCD               0x02
+#define ActiveCRT2              0x08
 
-#define		TVSwitchStatus               0xf0       /* SR16 */
-#define		TVConfigShift                3
-#define		ActiveTV                     0x01
-#define		ActiveYPbPr                  0x04
-#define		ActiveAVideo                 0x10
-#define		ActiveSVideo                 0x0020
-#define		ActiveSCART                  0x40
-#define		ActiveHiTV                   0x80
+#define TVSwitchStatus          0xf0 /* SR16 */
+#define TVConfigShift           3
+#define ActiveTV                0x01
+#define ActiveYPbPr             0x04
+#define ActiveAVideo            0x10
+#define ActiveSVideo            0x0020
+#define ActiveSCART             0x40
+#define ActiveHiTV              0x80
 
-#define		EnableHKEvent                0x01       /* CR7A */
-#define		EnableOSDEvent               0x02
-#define		StartOSDEvent                0x04
-#define		CMOSSupport                  0x08
-#define		HotKeySupport                0x10
-#define		IngoreHKOSDEvent             0x20
+#define EnableHKEvent           0x01 /* CR7A */
+#define EnableOSDEvent          0x02
+#define StartOSDEvent           0x04
+#define CMOSSupport             0x08
+#define HotKeySupport           0x10
+#define IngoreHKOSDEvent        0x20
 #endif
 
 /* //------------- Misc. Definition */
-#define		SelectCRT1Rate               00h
+#define SelectCRT1Rate               00h
 /* #define SelectCRT2Rate 04h */
 
-#define		DDC1DelayTime                1000
-#ifdef           TRUMPION
-#define		DDC2DelayTime                15
+#define DDC1DelayTime           1000
+#ifdef TRUMPION
+#define DDC2DelayTime           15
 #else
-#define		DDC2DelayTime                150
+#define DDC2DelayTime           150
 #endif
 
-#define		R_FACTOR                     04Dh
-#define		G_FACTOR                     097h
-#define		B_FACTOR                     01Ch
+#define R_FACTOR                04Dh
+#define G_FACTOR                097h
+#define B_FACTOR                01Ch
 /* --------------------------------------------------------- */
 /* translated from asm code 301def.h */
 /*  */
 /* --------------------------------------------------------- */
-#define		LCDDataLen                   8
-#define		HiTVDataLen                  12
-#define		TVDataLen                    12
-#define		LVDSCRT1Len_H                8
-#define		LVDSCRT1Len_V                7
-#define		LVDSDataLen                  6
-#define		LVDSDesDataLen               6
-#define		LCDDesDataLen                6
-#define		LVDSDesDataLen2              8
-#define		LCDDesDataLen2               8
-#define		CHTVRegLen                   16
-#define		CHLVRegLen                   12
+#define LCDDataLen           8
+#define HiTVDataLen          12
+#define TVDataLen            12
+#define LVDSCRT1Len_H        8
+#define LVDSCRT1Len_V        7
+#define LVDSDataLen          6
+#define LVDSDesDataLen       6
+#define LCDDesDataLen        6
+#define LVDSDesDataLen2      8
+#define LCDDesDataLen2       8
+#define CHTVRegLen           16
+#define CHLVRegLen           12
 
-#define		StHiTVHT                     892
-#define		StHiTVVT                     1126
-#define		StHiTextTVHT                 1000
-#define		StHiTextTVVT                 1126
-#define		ExtHiTVHT                    2100
-#define		ExtHiTVVT                    1125
-#define		NTSCHT                       1716
-#define		NTSCVT                        525
-#define		NTSC1024x768HT               1908
-#define		NTSC1024x768VT                525
-#define		PALHT                        1728
-#define		PALVT                         625
+#define StHiTVHT             892
+#define StHiTVVT             1126
+#define StHiTextTVHT         1000
+#define StHiTextTVVT         1126
+#define ExtHiTVHT            2100
+#define ExtHiTVVT            1125
+#define NTSCHT               1716
+#define NTSCVT                525
+#define NTSC1024x768HT       1908
+#define NTSC1024x768VT        525
+#define PALHT                1728
+#define PALVT                 625
 
-#define		YPbPrTV525iHT                1716            /* YPbPr */
-#define		YPbPrTV525iVT                 525
-#define		YPbPrTV525pHT                1716
-#define		YPbPrTV525pVT                 525
-#define		YPbPrTV750pHT                1650
-#define		YPbPrTV750pVT                 750
+#define YPbPrTV525iHT        1716 /* YPbPr */
+#define YPbPrTV525iVT         525
+#define YPbPrTV525pHT        1716
+#define YPbPrTV525pVT         525
+#define YPbPrTV750pHT        1650
+#define YPbPrTV750pVT         750
 
-#define		CRT2VCLKSel                  0xc0
+#define CRT2VCLKSel          0xc0
 
-#define		CRT2Delay1      	     0x04            /* XGI301 */
-#define		CRT2Delay2      	     0x0A            /* 301B,302 */
+#define CRT2Delay1           0x04 /* XGI301 */
+#define CRT2Delay2           0x0A /* 301B,302 */
 
 
-#define		VCLK25_175           0x00
-#define		VCLK28_322           0x01
-#define		VCLK31_5             0x02
-#define		VCLK36               0x03
-#define		VCLK40               0x04
-#define		VCLK43_163           0x05
-#define		VCLK44_9             0x06
-#define		VCLK49_5             0x07
-#define		VCLK50               0x08
-#define		VCLK52_406           0x09
-#define		VCLK56_25            0x0A
-#define		VCLK65               0x0B
-#define		VCLK67_765           0x0C
-#define		VCLK68_179           0x0D
-#define		VCLK72_852           0x0E
-#define		VCLK75               0x0F
-#define		VCLK75_8             0x10
-#define		VCLK78_75            0x11
-#define		VCLK79_411           0x12
-#define		VCLK83_95            0x13
-#define		VCLK84_8             0x14
-#define		VCLK86_6             0x15
-#define		VCLK94_5             0x16
-#define		VCLK104_998          0x17
-#define		VCLK105_882          0x18
-#define		VCLK108_2            0x19
-#define		VCLK109_175          0x1A
-#define		VCLK113_309          0x1B
-#define		VCLK116_406          0x1C
-#define		VCLK132_258          0x1D
-#define		VCLK135_5            0x1E
-#define		VCLK139_054          0x1F
-#define		VCLK157_5            0x20
-#define		VCLK162              0x21
-#define		VCLK175              0x22
-#define		VCLK189              0x23
-#define		VCLK194_4            0x24
-#define		VCLK202_5            0x25
-#define		VCLK229_5            0x26
-#define		VCLK234              0x27
-#define		VCLK252_699          0x28
-#define		VCLK254_817          0x29
-#define		VCLK265_728          0x2A
-#define		VCLK266_952          0x2B
-#define		VCLK269_655          0x2C
-#define		VCLK272_042          0x2D
-#define		VCLK277_015          0x2E
-#define		VCLK286_359          0x2F
-#define		VCLK291_132          0x30
-#define		VCLK291_766          0x31
-#define		VCLK309_789          0x32
-#define		VCLK315_195          0x33
-#define		VCLK323_586          0x34
-#define		VCLK330_615          0x35
-#define		VCLK332_177          0x36
-#define		VCLK340_477          0x37
-#define		VCLK375_847          0x38
-#define		VCLK388_631          0x39
-#define		VCLK125_999          0x51
-#define		VCLK148_5            0x52
-#define		VCLK178_992          0x54
-#define		VCLK217_325          0x55
-#define		VCLK299_505          0x56
-#define		YPbPr750pVCLK        0x57
+#define VCLK25_175           0x00
+#define VCLK28_322           0x01
+#define VCLK31_5             0x02
+#define VCLK36               0x03
+#define VCLK40               0x04
+#define VCLK43_163           0x05
+#define VCLK44_9             0x06
+#define VCLK49_5             0x07
+#define VCLK50               0x08
+#define VCLK52_406           0x09
+#define VCLK56_25            0x0A
+#define VCLK65               0x0B
+#define VCLK67_765           0x0C
+#define VCLK68_179           0x0D
+#define VCLK72_852           0x0E
+#define VCLK75               0x0F
+#define VCLK75_8             0x10
+#define VCLK78_75            0x11
+#define VCLK79_411           0x12
+#define VCLK83_95            0x13
+#define VCLK84_8             0x14
+#define VCLK86_6             0x15
+#define VCLK94_5             0x16
+#define VCLK104_998          0x17
+#define VCLK105_882          0x18
+#define VCLK108_2            0x19
+#define VCLK109_175          0x1A
+#define VCLK113_309          0x1B
+#define VCLK116_406          0x1C
+#define VCLK132_258          0x1D
+#define VCLK135_5            0x1E
+#define VCLK139_054          0x1F
+#define VCLK157_5            0x20
+#define VCLK162              0x21
+#define VCLK175              0x22
+#define VCLK189              0x23
+#define VCLK194_4            0x24
+#define VCLK202_5            0x25
+#define VCLK229_5            0x26
+#define VCLK234              0x27
+#define VCLK252_699          0x28
+#define VCLK254_817          0x29
+#define VCLK265_728          0x2A
+#define VCLK266_952          0x2B
+#define VCLK269_655          0x2C
+#define VCLK272_042          0x2D
+#define VCLK277_015          0x2E
+#define VCLK286_359          0x2F
+#define VCLK291_132          0x30
+#define VCLK291_766          0x31
+#define VCLK309_789          0x32
+#define VCLK315_195          0x33
+#define VCLK323_586          0x34
+#define VCLK330_615          0x35
+#define VCLK332_177          0x36
+#define VCLK340_477          0x37
+#define VCLK375_847          0x38
+#define VCLK388_631          0x39
+#define VCLK125_999          0x51
+#define VCLK148_5            0x52
+#define VCLK178_992          0x54
+#define VCLK217_325          0x55
+#define VCLK299_505          0x56
+#define YPbPr750pVCLK        0x57
 
-#define		TVVCLKDIV2              0x3A
-#define		TVVCLK                  0x3B
-#define		HiTVVCLKDIV2          0x3C
-#define		HiTVVCLK              0x3D
-#define		HiTVSimuVCLK          0x3E
-#define		HiTVTextVCLK          0x3F
-#define		VCLK39_77              0x40
+#define TVVCLKDIV2           0x3A
+#define TVVCLK               0x3B
+#define HiTVVCLKDIV2         0x3C
+#define HiTVVCLK             0x3D
+#define HiTVSimuVCLK         0x3E
+#define HiTVTextVCLK         0x3F
+#define VCLK39_77            0x40
 /* #define YPbPr750pVCLK 0x0F */
-#define		YPbPr525pVCLK           0x3A
+#define YPbPr525pVCLK           0x3A
 /* #define ;;YPbPr525iVCLK 0x3B */
 /* #define ;;YPbPr525iVCLK_2 0x3A */
-#define		NTSC1024VCLK         0x41
-#define		VCLK25_175_41        0x42                  /* ; ScaleLCD */
-#define		VCLK25_175_42        0x43
-#define		VCLK28_322_43        0x44
-#define		VCLK40_44            0x45
-#define		VCLKQVGA_1           0x46                   /* ; QVGA */
-#define		VCLKQVGA_2           0x47
-#define		VCLKQVGA_3           0x48
-#define		VCLK35_2             0x49                    /* ; 800x480 */
-#define		VCLK122_61           0x4A
-#define		VCLK80_350           0x4B
-#define		VCLK107_385          0x4C
+#define NTSC1024VCLK         0x41
+#define VCLK25_175_41        0x42 /* ; ScaleLCD */
+#define VCLK25_175_42        0x43
+#define VCLK28_322_43        0x44
+#define VCLK40_44            0x45
+#define VCLKQVGA_1           0x46 /* ; QVGA */
+#define VCLKQVGA_2           0x47
+#define VCLKQVGA_3           0x48
+#define VCLK35_2             0x49 /* ; 800x480 */
+#define VCLK122_61           0x4A
+#define VCLK80_350           0x4B
+#define VCLK107_385          0x4C
 
-#define		CHTVVCLK30_2         0x50                 /* ;;CHTV */
-#define		CHTVVCLK28_1         0x51
-#define		CHTVVCLK43_6         0x52
-#define		CHTVVCLK26_4         0x53
-#define		CHTVVCLK24_6         0x54
-#define		CHTVVCLK47_8         0x55
-#define		CHTVVCLK31_5         0x56
-#define		CHTVVCLK26_2         0x57
-#define		CHTVVCLK39           0x58
-#define		CHTVVCLK36           0x59
+#define CHTVVCLK30_2         0x50 /* ;;CHTV */
+#define CHTVVCLK28_1         0x51
+#define CHTVVCLK43_6         0x52
+#define CHTVVCLK26_4         0x53
+#define CHTVVCLK24_6         0x54
+#define CHTVVCLK47_8         0x55
+#define CHTVVCLK31_5         0x56
+#define CHTVVCLK26_2         0x57
+#define CHTVVCLK39           0x58
+#define CHTVVCLK36           0x59
 
-#define		CH7007TVVCLK30_2     0x00                 /* [Billy] 2007/05/18 For CH7007 */
-#define		CH7007TVVCLK28_1     0x01
-#define		CH7007TVVCLK43_6     0x02
-#define		CH7007TVVCLK26_4     0x03
-#define		CH7007TVVCLK24_6     0x04
-#define		CH7007TVVCLK47_8     0x05
-#define		CH7007TVVCLK31_5     0x06
-#define		CH7007TVVCLK26_2     0x07
-#define		CH7007TVVCLK39       0x08
-#define		CH7007TVVCLK36       0x09
+#define CH7007TVVCLK30_2     0x00 /* [Billy] 2007/05/18 For CH7007 */
+#define CH7007TVVCLK28_1     0x01
+#define CH7007TVVCLK43_6     0x02
+#define CH7007TVVCLK26_4     0x03
+#define CH7007TVVCLK24_6     0x04
+#define CH7007TVVCLK47_8     0x05
+#define CH7007TVVCLK31_5     0x06
+#define CH7007TVVCLK26_2     0x07
+#define CH7007TVVCLK39       0x08
+#define CH7007TVVCLK36       0x09
 
-#define		RES320x200                   0x00
-#define		RES320x240                   0x01
-#define		RES400x300                   0x02
-#define		RES512x384                   0x03
-#define		RES640x400                   0x04
-#define		RES640x480x60                0x05
-#define		RES640x480x72                0x06
-#define		RES640x480x75                0x07
-#define		RES640x480x85                0x08
-#define		RES640x480x100               0x09
-#define		RES640x480x120               0x0A
-#define		RES640x480x160               0x0B
-#define		RES640x480x200               0x0C
-#define		RES800x600x56                0x0D
-#define		RES800x600x60                0x0E
-#define		RES800x600x72                0x0F
-#define		RES800x600x75                0x10
-#define		RES800x600x85                0x11
-#define		RES800x600x100               0x12
-#define		RES800x600x120               0x13
-#define		RES800x600x160               0x14
-#define		RES1024x768x43               0x15
-#define		RES1024x768x60               0x16
-#define		RES1024x768x70               0x17
-#define		RES1024x768x75               0x18
-#define		RES1024x768x85               0x19
-#define		RES1024x768x100              0x1A
-#define		RES1024x768x120              0x1B
-#define		RES1280x1024x43              0x1C
-#define		RES1280x1024x60              0x1D
-#define		RES1280x1024x75              0x1E
-#define		RES1280x1024x85              0x1F
-#define		RES1600x1200x60              0x20
-#define		RES1600x1200x65              0x21
-#define		RES1600x1200x70              0x22
-#define		RES1600x1200x75              0x23
-#define		RES1600x1200x85              0x24
-#define		RES1600x1200x100             0x25
-#define		RES1600x1200x120             0x26
-#define		RES1920x1440x60              0x27
-#define		RES1920x1440x65              0x28
-#define		RES1920x1440x70              0x29
-#define		RES1920x1440x75              0x2A
-#define		RES1920x1440x85              0x2B
-#define		RES1920x1440x100             0x2C
-#define		RES2048x1536x60              0x2D
-#define		RES2048x1536x65              0x2E
-#define		RES2048x1536x70              0x2F
-#define		RES2048x1536x75              0x30
-#define		RES2048x1536x85              0x31
-#define		RES800x480x60                0x32
-#define		RES800x480x75                0x33
-#define		RES800x480x85                0x34
-#define		RES1024x576x60               0x35
-#define		RES1024x576x75               0x36
-#define		RES1024x576x85               0x37
-#define		RES1280x720x60               0x38
-#define		RES1280x720x75               0x39
-#define		RES1280x720x85               0x3A
-#define		RES1280x960x60               0x3B
-#define		RES720x480x60                0x3C
-#define		RES720x576x56                0x3D
-#define		RES856x480x79I               0x3E
-#define		RES856x480x60                0x3F
-#define		RES1280x768x60               0x40
-#define		RES1400x1050x60              0x41
-#define		RES1152x864x60               0x42
-#define		RES1152x864x75               0x43
-#define		RES1024x768x160              0x44
-#define		RES1280x960x75               0x45
-#define		RES1280x960x85               0x46
-#define		RES1280x960x120              0x47
+#define RES320x200           0x00
+#define RES320x240           0x01
+#define RES400x300           0x02
+#define RES512x384           0x03
+#define RES640x400           0x04
+#define RES640x480x60        0x05
+#define RES640x480x72        0x06
+#define RES640x480x75        0x07
+#define RES640x480x85        0x08
+#define RES640x480x100       0x09
+#define RES640x480x120       0x0A
+#define RES640x480x160       0x0B
+#define RES640x480x200       0x0C
+#define RES800x600x56        0x0D
+#define RES800x600x60        0x0E
+#define RES800x600x72        0x0F
+#define RES800x600x75        0x10
+#define RES800x600x85        0x11
+#define RES800x600x100       0x12
+#define RES800x600x120       0x13
+#define RES800x600x160       0x14
+#define RES1024x768x43       0x15
+#define RES1024x768x60       0x16
+#define RES1024x768x70       0x17
+#define RES1024x768x75       0x18
+#define RES1024x768x85       0x19
+#define RES1024x768x100      0x1A
+#define RES1024x768x120      0x1B
+#define RES1280x1024x43      0x1C
+#define RES1280x1024x60      0x1D
+#define RES1280x1024x75      0x1E
+#define RES1280x1024x85      0x1F
+#define RES1600x1200x60      0x20
+#define RES1600x1200x65      0x21
+#define RES1600x1200x70      0x22
+#define RES1600x1200x75      0x23
+#define RES1600x1200x85      0x24
+#define RES1600x1200x100     0x25
+#define RES1600x1200x120     0x26
+#define RES1920x1440x60      0x27
+#define RES1920x1440x65      0x28
+#define RES1920x1440x70      0x29
+#define RES1920x1440x75      0x2A
+#define RES1920x1440x85      0x2B
+#define RES1920x1440x100     0x2C
+#define RES2048x1536x60      0x2D
+#define RES2048x1536x65      0x2E
+#define RES2048x1536x70      0x2F
+#define RES2048x1536x75      0x30
+#define RES2048x1536x85      0x31
+#define RES800x480x60        0x32
+#define RES800x480x75        0x33
+#define RES800x480x85        0x34
+#define RES1024x576x60       0x35
+#define RES1024x576x75       0x36
+#define RES1024x576x85       0x37
+#define RES1280x720x60       0x38
+#define RES1280x720x75       0x39
+#define RES1280x720x85       0x3A
+#define RES1280x960x60       0x3B
+#define RES720x480x60        0x3C
+#define RES720x576x56        0x3D
+#define RES856x480x79I       0x3E
+#define RES856x480x60        0x3F
+#define RES1280x768x60       0x40
+#define RES1400x1050x60      0x41
+#define RES1152x864x60       0x42
+#define RES1152x864x75       0x43
+#define RES1024x768x160      0x44
+#define RES1280x960x75       0x45
+#define RES1280x960x85       0x46
+#define RES1280x960x120      0x47
 
-#define 	LFBDRAMTrap                  0x30
+#define LFBDRAMTrap          0x30
 #endif
diff -druN linux-2.6.39-libre/drivers/staging/xgifb/vb_ext.c linux-3.0-rc7-libre/drivers/staging/xgifb/vb_ext.c
--- linux-2.6.39-libre/drivers/staging/xgifb/vb_ext.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/xgifb/vb_ext.c	2011-07-11 19:51:52.000000000 -0400
@@ -1,5 +1,5 @@
 #include <linux/version.h>
-#include <asm/io.h>
+#include <linux/io.h>
 #include <linux/types.h>
 #include "XGIfb.h"
 
@@ -26,7 +26,9 @@
 		return 1;
 }
 
-static unsigned char XGINew_Sense(unsigned short tempbx, unsigned short tempcx, struct vb_device_info *pVBInfo)
+static unsigned char XGINew_Sense(unsigned short tempbx,
+				  unsigned short tempcx,
+				  struct vb_device_info *pVBInfo)
 {
 	unsigned short temp, i, tempch;
 
@@ -50,7 +52,9 @@
 		return 0;
 }
 
-static unsigned char XGINew_GetLCDDDCInfo(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo)
+static unsigned char
+XGINew_GetLCDDDCInfo(struct xgi_hw_device_info *HwDeviceExtension,
+		     struct vb_device_info *pVBInfo)
 {
 	unsigned short temp;
 
@@ -154,7 +158,9 @@
 	}
 }
 
-static unsigned char XGINew_BridgeIsEnable(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo)
+static unsigned char
+XGINew_BridgeIsEnable(struct xgi_hw_device_info *HwDeviceExtension,
+		      struct vb_device_info *pVBInfo)
 {
 	unsigned short flag;
 
@@ -170,7 +176,9 @@
 	return 0;
 }
 
-static unsigned char XGINew_SenseHiTV(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo)
+static unsigned char
+XGINew_SenseHiTV(struct xgi_hw_device_info *HwDeviceExtension,
+		 struct vb_device_info *pVBInfo)
 {
 	unsigned short tempbx, tempcx, temp, i, tempch;
 
@@ -238,21 +246,29 @@
 	}
 }
 
-void XGI_GetSenseStatus(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo)
+void XGI_GetSenseStatus(struct xgi_hw_device_info *HwDeviceExtension,
+			struct vb_device_info *pVBInfo)
 {
-	unsigned short tempax = 0, tempbx, tempcx, temp, P2reg0 = 0, SenseModeNo = 0,
-			OutputSelect = *pVBInfo->pOutputSelect, ModeIdIndex, i;
+	unsigned short  tempax = 0, tempbx, tempcx, temp,
+			P2reg0 = 0, SenseModeNo = 0,
+			OutputSelect = *pVBInfo->pOutputSelect,
+			ModeIdIndex, i;
 	pVBInfo->BaseAddr = (unsigned long) HwDeviceExtension->pjIOAddress;
 
 	if (pVBInfo->IF_DEF_LVDS == 1) {
-		tempax = xgifb_reg_get(pVBInfo->P3c4, 0x1A); /* ynlai 02/27/2002 */
+		/* ynlai 02/27/2002 */
+		tempax = xgifb_reg_get(pVBInfo->P3c4, 0x1A);
 		tempbx = xgifb_reg_get(pVBInfo->P3c4, 0x1B);
 		tempax = ((tempax & 0xFE) >> 1) | (tempbx << 8);
 		if (tempax == 0x00) { /* Get Panel id from DDC */
 			temp = XGINew_GetLCDDDCInfo(HwDeviceExtension, pVBInfo);
 			if (temp == 1) { /* LCD connect */
-				xgifb_reg_and_or(pVBInfo->P3d4, 0x39, 0xFF, 0x01); /* set CR39 bit0="1" */
-				xgifb_reg_and_or(pVBInfo->P3d4, 0x37, 0xEF, 0x00); /* clean CR37 bit4="0" */
+				/* set CR39 bit0="1" */
+				xgifb_reg_and_or(pVBInfo->P3d4,
+						 0x39, 0xFF, 0x01);
+				/* clean CR37 bit4="0" */
+				xgifb_reg_and_or(pVBInfo->P3d4,
+						 0x37, 0xEF, 0x00);
 				temp = LCDSense;
 			} else { /* LCD don't connect */
 				temp = 0;
@@ -273,25 +289,47 @@
 			xgifb_reg_and_or(pVBInfo->P3d4, 0x32, 0xA0, temp);
 		} else {
 			if (XGI_BridgeIsOn(pVBInfo)) {
-				P2reg0 = xgifb_reg_get(pVBInfo->Part2Port, 0x00);
-				if (!XGINew_BridgeIsEnable(HwDeviceExtension, pVBInfo)) {
+				P2reg0 = xgifb_reg_get(pVBInfo->Part2Port,
+						       0x00);
+				if (!XGINew_BridgeIsEnable(HwDeviceExtension,
+							   pVBInfo)) {
 					SenseModeNo = 0x2e;
-					/* xgifb_reg_set(pVBInfo->P3d4, 0x30, 0x41); */
-					/* XGISetModeNew(HwDeviceExtension, 0x2e); // ynlai InitMode */
+				/* xgifb_reg_set(pVBInfo->P3d4, 0x30, 0x41);
+				 * XGISetModeNew(HwDeviceExtension, 0x2e);
+				 * // ynlai InitMode */
 
-					temp = XGI_SearchModeID(SenseModeNo, &ModeIdIndex, pVBInfo);
-					XGI_GetVGAType(HwDeviceExtension, pVBInfo);
+					temp = XGI_SearchModeID(SenseModeNo,
+								&ModeIdIndex,
+								pVBInfo);
+					XGI_GetVGAType(HwDeviceExtension,
+						       pVBInfo);
 					XGI_GetVBType(pVBInfo);
 					pVBInfo->SetFlag = 0x00;
 					pVBInfo->ModeType = ModeVGA;
-					pVBInfo->VBInfo = SetCRT2ToRAMDAC | LoadDACFlag | SetInSlaveMode;
-					XGI_GetLCDInfo(0x2e, ModeIdIndex, pVBInfo);
-					XGI_GetTVInfo(0x2e, ModeIdIndex, pVBInfo);
-					XGI_EnableBridge(HwDeviceExtension, pVBInfo);
-					XGI_SetCRT2Group301(SenseModeNo, HwDeviceExtension, pVBInfo);
-					XGI_SetCRT2ModeRegs(0x2e, HwDeviceExtension, pVBInfo);
-					/* XGI_DisableBridge( HwDeviceExtension, pVBInfo ) ; */
-					xgifb_reg_and_or(pVBInfo->P3c4, 0x01, 0xDF, 0x20); /* Display Off 0212 */
+					pVBInfo->VBInfo = SetCRT2ToRAMDAC |
+							  LoadDACFlag |
+							  SetInSlaveMode;
+					XGI_GetLCDInfo(0x2e,
+						       ModeIdIndex,
+						       pVBInfo);
+					XGI_GetTVInfo(0x2e,
+						      ModeIdIndex,
+						      pVBInfo);
+					XGI_EnableBridge(HwDeviceExtension,
+							 pVBInfo);
+					XGI_SetCRT2Group301(SenseModeNo,
+							    HwDeviceExtension,
+							    pVBInfo);
+					XGI_SetCRT2ModeRegs(0x2e,
+							    HwDeviceExtension,
+							    pVBInfo);
+					/* XGI_DisableBridge(HwDeviceExtension,
+					 *		     pVBInfo ) ; */
+					/* Display Off 0212 */
+					xgifb_reg_and_or(pVBInfo->P3c4,
+							 0x01,
+							 0xDF,
+							 0x20);
 					for (i = 0; i < 20; i++)
 						XGI_LongWait(pVBInfo);
 				}
@@ -304,29 +342,38 @@
 
 				tempcx = 0x0E08;
 				if (XGINew_Sense(tempbx, tempcx, pVBInfo)) {
-					if (XGINew_Sense(tempbx, tempcx, pVBInfo))
+					if (XGINew_Sense(tempbx,
+							 tempcx,
+							 pVBInfo))
 						tempax |= Monitor2Sense;
 				}
 
 				if (pVBInfo->VBType & VB_XGI301C)
-					xgifb_reg_or(pVBInfo->Part4Port, 0x0d, 0x04);
+					xgifb_reg_or(pVBInfo->Part4Port,
+						     0x0d,
+						     0x04);
 
-				if (XGINew_SenseHiTV(HwDeviceExtension, pVBInfo)) { /* add by kuku for Multi-adapter sense HiTV */
+				/* add by kuku for Multi-adapter sense HiTV */
+				if (XGINew_SenseHiTV(HwDeviceExtension,
+						     pVBInfo)) {
 					tempax |= HiTVSense;
 					if ((pVBInfo->VBType & VB_XGI301C))
-						tempax ^= (HiTVSense | YPbPrSense);
+						tempax ^= (HiTVSense |
+							   YPbPrSense);
 				}
 
-				if (!(tempax & (HiTVSense | YPbPrSense))) { /* start */
-
+				/* start */
+				if (!(tempax & (HiTVSense | YPbPrSense))) {
 					tempbx = *pVBInfo->pYCSenseData;
-
 					if (!(XGINew_Is301B(pVBInfo)))
 						tempbx = *pVBInfo->pYCSenseData2;
-
 					tempcx = 0x0604;
-					if (XGINew_Sense(tempbx, tempcx, pVBInfo)) {
-						if (XGINew_Sense(tempbx, tempcx, pVBInfo))
+					if (XGINew_Sense(tempbx,
+							 tempcx,
+							 pVBInfo)) {
+						if (XGINew_Sense(tempbx,
+								 tempcx,
+								 pVBInfo))
 							tempax |= SVIDEOSense;
 					}
 
@@ -337,8 +384,12 @@
 							tempbx = *pVBInfo->pVideoSenseData2;
 
 						tempcx = 0x0804;
-						if (XGINew_Sense(tempbx, tempcx, pVBInfo)) {
-							if (XGINew_Sense(tempbx, tempcx, pVBInfo))
+						if (XGINew_Sense(tempbx,
+								 tempcx,
+								 pVBInfo)) {
+							if (XGINew_Sense(tempbx,
+									 tempcx,
+									 pVBInfo))
 								tempax |= AVIDEOSense;
 						}
 					} else {
@@ -349,7 +400,9 @@
 								tempbx = *pVBInfo->pVideoSenseData2;
 
 							tempcx = 0x0804;
-							if (XGINew_Sense(tempbx, tempcx, pVBInfo)) {
+							if (XGINew_Sense(tempbx,
+									 tempcx,
+									 pVBInfo)) {
 								if (XGINew_Sense(tempbx, tempcx, pVBInfo))
 									tempax |= AVIDEOSense;
 							}
@@ -370,7 +423,9 @@
 
 			if (!(P2reg0 & 0x20)) {
 				pVBInfo->VBInfo = DisableCRT2Display;
-				/* XGI_SetCRT2Group301(SenseModeNo, HwDeviceExtension, pVBInfo); */
+				/* XGI_SetCRT2Group301(SenseModeNo,
+				 *		       HwDeviceExtension,
+				 *		       pVBInfo); */
 			}
 		}
 	}
@@ -378,7 +433,8 @@
 
 }
 
-unsigned short XGINew_SenseLCD(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo)
+unsigned short XGINew_SenseLCD(struct xgi_hw_device_info *HwDeviceExtension,
+			       struct vb_device_info *pVBInfo)
 {
 	/* unsigned short SoftSetting ; */
 	unsigned short temp;
diff -druN linux-2.6.39-libre/drivers/staging/xgifb/vb_ext.h linux-3.0-rc7-libre/drivers/staging/xgifb/vb_ext.h
--- linux-2.6.39-libre/drivers/staging/xgifb/vb_ext.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/xgifb/vb_ext.h	2011-07-11 19:51:52.000000000 -0400
@@ -1,27 +1,28 @@
-#ifndef  _VBEXT_
-#define  _VBEXT_
+#ifndef _VBEXT_
+#define _VBEXT_
 
 struct DWORDREGS {
-    unsigned long    Eax, Ebx, Ecx, Edx, Esi, Edi, Ebp;
+	unsigned long Eax, Ebx, Ecx, Edx, Esi, Edi, Ebp;
 };
 
 struct WORDREGS {
-    unsigned short ax, hi_ax, bx, hi_bx, cx, hi_cx, dx, hi_dx, si,
-	    hi_si, di, hi_di, bp, hi_bp;
+	unsigned short  ax, hi_ax, bx, hi_bx, cx, hi_cx, dx, hi_dx, si,
+			hi_si, di, hi_di, bp, hi_bp;
 };
 
 struct BYTEREGS {
-     unsigned char al, ah, hi_al, hi_ah, bl, bh, hi_bl, hi_bh, cl, ch,
-	     hi_cl, hi_ch, dl, dh, hi_dl, hi_dh;
+	unsigned char   al, ah, hi_al, hi_ah, bl, bh, hi_bl, hi_bh, cl, ch,
+			hi_cl, hi_ch, dl, dh, hi_dl, hi_dh;
 };
 
-typedef union   _X86_REGS    {
-    struct  DWORDREGS e;
-    struct  WORDREGS x;
-    struct  BYTEREGS h;
+typedef union _X86_REGS {
+	struct  DWORDREGS e;
+	struct  WORDREGS x;
+	struct  BYTEREGS h;
 } X86_REGS, *PX86_REGS;
 
-extern   void     XGI_GetSenseStatus(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo);
+extern void XGI_GetSenseStatus(struct xgi_hw_device_info *HwDeviceExtension,
+			       struct vb_device_info *pVBInfo);
 extern unsigned short XGINew_SenseLCD(struct xgi_hw_device_info *,
 				      struct vb_device_info *pVBInfo);
 
diff -druN linux-2.6.39-libre/drivers/staging/xgifb/vb_init.c linux-3.0-rc7-libre/drivers/staging/xgifb/vb_init.c
--- linux-2.6.39-libre/drivers/staging/xgifb/vb_init.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/xgifb/vb_init.c	2011-07-11 19:51:52.000000000 -0400
@@ -13,7 +13,7 @@
 #include "vb_ext.h"
 
 
-#include <asm/io.h>
+#include <linux/io.h>
 
 static unsigned char XGINew_ChannelAB, XGINew_DataBusWidth;
 
@@ -39,8 +39,9 @@
 
 static int XGINew_RAMType;
 
-static unsigned char XGINew_GetXG20DRAMType(struct xgi_hw_device_info *HwDeviceExtension,
-					struct vb_device_info *pVBInfo)
+static unsigned char
+XGINew_GetXG20DRAMType(struct xgi_hw_device_info *HwDeviceExtension,
+		       struct vb_device_info *pVBInfo)
 {
 	unsigned char data, temp;
 
@@ -50,10 +51,9 @@
 			return data;
 		} else {
 			data = xgifb_reg_get(pVBInfo->P3c4, 0x39) & 0x02;
-
 			if (data == 0)
-				data = (xgifb_reg_get(pVBInfo->P3c4, 0x3A) & 0x02) >> 1;
-
+				data = (xgifb_reg_get(pVBInfo->P3c4, 0x3A) &
+				       0x02) >> 1;
 			return data;
 		}
 	} else if (HwDeviceExtension->jChipType == XG27) {
@@ -62,19 +62,22 @@
 			return data;
 		}
 		temp = xgifb_reg_get(pVBInfo->P3c4, 0x3B);
-
-		if ((temp & 0x88) == 0x80) /* SR3B[7][3]MAA15 MAA11 (Power on Trapping) */
+		/* SR3B[7][3]MAA15 MAA11 (Power on Trapping) */
+		if ((temp & 0x88) == 0x80)
 			data = 0; /* DDR */
 		else
 			data = 1; /* DDRII */
 		return data;
 	} else if (HwDeviceExtension->jChipType == XG21) {
-		xgifb_reg_and(pVBInfo->P3d4, 0xB4, ~0x02); /* Independent GPIO control */
+		/* Independent GPIO control */
+		xgifb_reg_and(pVBInfo->P3d4, 0xB4, ~0x02);
 		udelay(800);
 		xgifb_reg_or(pVBInfo->P3d4, 0x4A, 0x80); /* Enable GPIOH read */
-		temp = xgifb_reg_get(pVBInfo->P3d4, 0x48); /* GPIOF 0:DVI 1:DVO */
+		/* GPIOF 0:DVI 1:DVO */
+		temp = xgifb_reg_get(pVBInfo->P3d4, 0x48);
 		/* HOTPLUG_SUPPORT */
-		/* for current XG20 & XG21, GPIOH is floating, driver will fix DDR temporarily */
+		/* for current XG20 & XG21, GPIOH is floating, driver will
+		 * fix DDR temporarily */
 		if (temp & 0x01) /* DVI read GPIOH */
 			data = 1; /* DDRII */
 		else
@@ -92,7 +95,8 @@
 	}
 }
 
-static void XGINew_DDR1x_MRS_340(unsigned long P3c4, struct vb_device_info *pVBInfo)
+static void XGINew_DDR1x_MRS_340(unsigned long P3c4,
+				 struct vb_device_info *pVBInfo)
 {
 	xgifb_reg_set(P3c4, 0x18, 0x01);
 	xgifb_reg_set(P3c4, 0x19, 0x20);
@@ -126,24 +130,42 @@
 		struct vb_device_info *pVBInfo)
 {
 
-	xgifb_reg_set(pVBInfo->P3c4, 0x28, pVBInfo->MCLKData[XGINew_RAMType].SR28);
-	xgifb_reg_set(pVBInfo->P3c4, 0x29, pVBInfo->MCLKData[XGINew_RAMType].SR29);
-	xgifb_reg_set(pVBInfo->P3c4, 0x2A, pVBInfo->MCLKData[XGINew_RAMType].SR2A);
+	xgifb_reg_set(pVBInfo->P3c4,
+		      0x28,
+		      pVBInfo->MCLKData[XGINew_RAMType].SR28);
+	xgifb_reg_set(pVBInfo->P3c4,
+		      0x29,
+		      pVBInfo->MCLKData[XGINew_RAMType].SR29);
+	xgifb_reg_set(pVBInfo->P3c4,
+		      0x2A,
+		      pVBInfo->MCLKData[XGINew_RAMType].SR2A);
 
-	xgifb_reg_set(pVBInfo->P3c4, 0x2E, pVBInfo->ECLKData[XGINew_RAMType].SR2E);
-	xgifb_reg_set(pVBInfo->P3c4, 0x2F, pVBInfo->ECLKData[XGINew_RAMType].SR2F);
-	xgifb_reg_set(pVBInfo->P3c4, 0x30, pVBInfo->ECLKData[XGINew_RAMType].SR30);
+	xgifb_reg_set(pVBInfo->P3c4,
+		      0x2E,
+		      pVBInfo->ECLKData[XGINew_RAMType].SR2E);
+	xgifb_reg_set(pVBInfo->P3c4,
+		      0x2F,
+		      pVBInfo->ECLKData[XGINew_RAMType].SR2F);
+	xgifb_reg_set(pVBInfo->P3c4,
+		      0x30,
+		      pVBInfo->ECLKData[XGINew_RAMType].SR30);
 
-	/* [Vicent] 2004/07/07, When XG42 ECLK = MCLK = 207MHz, Set SR32 D[1:0] = 10b */
-	/* [Hsuan] 2004/08/20, Modify SR32 value, when MCLK=207MHZ, ELCK=250MHz, Set SR32 D[1:0] = 10b */
+	/* [Vicent] 2004/07/07,
+	 * When XG42 ECLK = MCLK = 207MHz, Set SR32 D[1:0] = 10b */
+	/* [Hsuan] 2004/08/20,
+	 * Modify SR32 value, when MCLK=207MHZ, ELCK=250MHz,
+	 * Set SR32 D[1:0] = 10b */
 	if (HwDeviceExtension->jChipType == XG42) {
-		if ((pVBInfo->MCLKData[XGINew_RAMType].SR28 == 0x1C)
-				&& (pVBInfo->MCLKData[XGINew_RAMType].SR29 == 0x01)
-				&& (((pVBInfo->ECLKData[XGINew_RAMType].SR2E == 0x1C)
-						&& (pVBInfo->ECLKData[XGINew_RAMType].SR2F == 0x01))
-					|| ((pVBInfo->ECLKData[XGINew_RAMType].SR2E == 0x22)
-						&& (pVBInfo->ECLKData[XGINew_RAMType].SR2F == 0x01))))
-			xgifb_reg_set(pVBInfo->P3c4, 0x32, ((unsigned char) xgifb_reg_get(pVBInfo->P3c4, 0x32) & 0xFC) | 0x02);
+		if ((pVBInfo->MCLKData[XGINew_RAMType].SR28 == 0x1C) &&
+		    (pVBInfo->MCLKData[XGINew_RAMType].SR29 == 0x01) &&
+		    (((pVBInfo->ECLKData[XGINew_RAMType].SR2E == 0x1C) &&
+		      (pVBInfo->ECLKData[XGINew_RAMType].SR2F == 0x01)) ||
+		     ((pVBInfo->ECLKData[XGINew_RAMType].SR2E == 0x22) &&
+		      (pVBInfo->ECLKData[XGINew_RAMType].SR2F == 0x01))))
+			xgifb_reg_set(pVBInfo->P3c4,
+				      0x32,
+				      ((unsigned char) xgifb_reg_get(
+					  pVBInfo->P3c4, 0x32) & 0xFC) | 0x02);
 	}
 }
 
@@ -152,7 +174,8 @@
 			unsigned long P3c4, struct vb_device_info *pVBInfo)
 {
 	unsigned long P3d4 = P3c4 + 0x10;
-	XGINew_RAMType = (int) XGINew_GetXG20DRAMType(HwDeviceExtension, pVBInfo);
+	XGINew_RAMType = (int) XGINew_GetXG20DRAMType(HwDeviceExtension,
+						      pVBInfo);
 	XGINew_SetMemoryClock(HwDeviceExtension, pVBInfo);
 
 	/* Set Double Frequency */
@@ -216,7 +239,8 @@
 	xgifb_reg_set(P3c4, 0x16, 0xA0); /* Set SR16 */
 	udelay(15);
 
-	xgifb_reg_set(P3c4, 0x1B, 0x04); /* Set SR1B refresh control 000:close; 010:open */
+	/* Set SR1B refresh control 000:close; 010:open */
+	xgifb_reg_set(P3c4, 0x1B, 0x04);
 	udelay(200);
 
 }
@@ -226,7 +250,8 @@
 {
 	unsigned long P3d4 = P3c4 + 0x10;
 
-	XGINew_RAMType = (int) XGINew_GetXG20DRAMType(HwDeviceExtension, pVBInfo);
+	XGINew_RAMType = (int) XGINew_GetXG20DRAMType(HwDeviceExtension,
+						      pVBInfo);
 	XGINew_SetMemoryClock(HwDeviceExtension, pVBInfo);
 
 	xgifb_reg_set(P3d4, 0x97, 0x11); /* CR97 */
@@ -268,9 +293,9 @@
 	udelay(200);
 }
 
-static void XGINew_DDR1x_MRS_XG20(unsigned long P3c4, struct vb_device_info *pVBInfo)
+static void XGINew_DDR1x_MRS_XG20(unsigned long P3c4,
+				  struct vb_device_info *pVBInfo)
 {
-
 	xgifb_reg_set(P3c4, 0x18, 0x01);
 	xgifb_reg_set(P3c4, 0x19, 0x40);
 	xgifb_reg_set(P3c4, 0x16, 0x00);
@@ -306,9 +331,15 @@
 
 	if (HwDeviceExtension->jChipType >= XG20) {
 		XGINew_SetMemoryClock(HwDeviceExtension, pVBInfo);
-		xgifb_reg_set(P3d4, 0x82, pVBInfo->CR40[11][XGINew_RAMType]); /* CR82 */
-		xgifb_reg_set(P3d4, 0x85, pVBInfo->CR40[12][XGINew_RAMType]); /* CR85 */
-		xgifb_reg_set(P3d4, 0x86, pVBInfo->CR40[13][XGINew_RAMType]); /* CR86 */
+		xgifb_reg_set(P3d4,
+			      0x82,
+			      pVBInfo->CR40[11][XGINew_RAMType]); /* CR82 */
+		xgifb_reg_set(P3d4,
+			      0x85,
+			      pVBInfo->CR40[12][XGINew_RAMType]); /* CR85 */
+		xgifb_reg_set(P3d4,
+			      0x86,
+			      pVBInfo->CR40[13][XGINew_RAMType]); /* CR86 */
 
 		xgifb_reg_set(P3d4, 0x98, 0x01);
 		xgifb_reg_set(P3d4, 0x9A, 0x02);
@@ -320,24 +351,46 @@
 		switch (HwDeviceExtension->jChipType) {
 		case XG41:
 		case XG42:
-			xgifb_reg_set(P3d4, 0x82, pVBInfo->CR40[11][XGINew_RAMType]); /* CR82 */
-			xgifb_reg_set(P3d4, 0x85, pVBInfo->CR40[12][XGINew_RAMType]); /* CR85 */
-			xgifb_reg_set(P3d4, 0x86, pVBInfo->CR40[13][XGINew_RAMType]); /* CR86 */
+			/* CR82 */
+			xgifb_reg_set(P3d4,
+				      0x82,
+				      pVBInfo->CR40[11][XGINew_RAMType]);
+			/* CR85 */
+			xgifb_reg_set(P3d4,
+				      0x85,
+				      pVBInfo->CR40[12][XGINew_RAMType]);
+			/* CR86 */
+			xgifb_reg_set(P3d4,
+				      0x86,
+				      pVBInfo->CR40[13][XGINew_RAMType]);
 			break;
 		default:
 			xgifb_reg_set(P3d4, 0x82, 0x88);
 			xgifb_reg_set(P3d4, 0x86, 0x00);
-			xgifb_reg_get(P3d4, 0x86); /* Insert read command for delay */
+			/* Insert read command for delay */
+			xgifb_reg_get(P3d4, 0x86);
 			xgifb_reg_set(P3d4, 0x86, 0x88);
 			xgifb_reg_get(P3d4, 0x86);
-			xgifb_reg_set(P3d4, 0x86, pVBInfo->CR40[13][XGINew_RAMType]);
+			xgifb_reg_set(P3d4,
+				      0x86,
+				      pVBInfo->CR40[13][XGINew_RAMType]);
 			xgifb_reg_set(P3d4, 0x82, 0x77);
 			xgifb_reg_set(P3d4, 0x85, 0x00);
-			xgifb_reg_get(P3d4, 0x85); /* Insert read command for delay */
+
+			/* Insert read command for delay */
+			xgifb_reg_get(P3d4, 0x85);
 			xgifb_reg_set(P3d4, 0x85, 0x88);
-			xgifb_reg_get(P3d4, 0x85); /* Insert read command for delay */
-			xgifb_reg_set(P3d4, 0x85, pVBInfo->CR40[12][XGINew_RAMType]); /* CR85 */
-			xgifb_reg_set(P3d4, 0x82, pVBInfo->CR40[11][XGINew_RAMType]); /* CR82 */
+
+			/* Insert read command for delay */
+			xgifb_reg_get(P3d4, 0x85);
+			/* CR85 */
+			xgifb_reg_set(P3d4,
+				      0x85,
+				      pVBInfo->CR40[12][XGINew_RAMType]);
+			/* CR82 */
+			xgifb_reg_set(P3d4,
+				      0x82,
+				      pVBInfo->CR40[11][XGINew_RAMType]);
 			break;
 		}
 
@@ -354,13 +407,15 @@
 {
 	unsigned long P3d4 = Port, P3c4 = Port - 0x10;
 
-	/* keep following setting sequence, each setting in the same reg insert idle */
+	/* keep following setting sequence, each setting in
+	 * the same reg insert idle */
 	xgifb_reg_set(P3d4, 0x82, 0x77);
 	xgifb_reg_set(P3d4, 0x86, 0x00);
 	xgifb_reg_get(P3d4, 0x86); /* Insert read command for delay */
 	xgifb_reg_set(P3d4, 0x86, 0x88);
 	xgifb_reg_get(P3d4, 0x86); /* Insert read command for delay */
-	xgifb_reg_set(P3d4, 0x86, pVBInfo->CR40[13][XGINew_RAMType]); /* CR86 */
+	/* CR86 */
+	xgifb_reg_set(P3d4, 0x86, pVBInfo->CR40[13][XGINew_RAMType]);
 	xgifb_reg_set(P3d4, 0x82, 0x77);
 	xgifb_reg_set(P3d4, 0x85, 0x00);
 	xgifb_reg_get(P3d4, 0x85); /* Insert read command for delay */
@@ -368,7 +423,8 @@
 	xgifb_reg_get(P3d4, 0x85); /* Insert read command for delay */
 	xgifb_reg_set(P3d4, 0x85, pVBInfo->CR40[12][XGINew_RAMType]); /* CR85 */
 	if (HwDeviceExtension->jChipType == XG27)
-		xgifb_reg_set(P3d4, 0x82, pVBInfo->CR40[11][XGINew_RAMType]); /* CR82 */
+		/* CR82 */
+		xgifb_reg_set(P3d4, 0x82, pVBInfo->CR40[11][XGINew_RAMType]);
 	else
 		xgifb_reg_set(P3d4, 0x82, 0xA8); /* CR82 */
 
@@ -395,12 +451,14 @@
 
 	temp2 = 0;
 	for (i = 0; i < 4; i++) {
-		temp = pVBInfo->CR6B[XGINew_RAMType][i]; /* CR6B DQS fine tune delay */
+		/* CR6B DQS fine tune delay */
+		temp = pVBInfo->CR6B[XGINew_RAMType][i];
 		for (j = 0; j < 4; j++) {
 			temp1 = ((temp >> (2 * j)) & 0x03) << 2;
 			temp2 |= temp1;
 			xgifb_reg_set(P3d4, 0x6B, temp2);
-			xgifb_reg_get(P3d4, 0x6B); /* Insert read command for delay */
+			/* Insert read command for delay */
+			xgifb_reg_get(P3d4, 0x6B);
 			temp2 &= 0xF0;
 			temp2 += 0x10;
 		}
@@ -408,12 +466,14 @@
 
 	temp2 = 0;
 	for (i = 0; i < 4; i++) {
-		temp = pVBInfo->CR6E[XGINew_RAMType][i]; /* CR6E DQM fine tune delay */
+		/* CR6E DQM fine tune delay */
+		temp = pVBInfo->CR6E[XGINew_RAMType][i];
 		for (j = 0; j < 4; j++) {
 			temp1 = ((temp >> (2 * j)) & 0x03) << 2;
 			temp2 |= temp1;
 			xgifb_reg_set(P3d4, 0x6E, temp2);
-			xgifb_reg_get(P3d4, 0x6E); /* Insert read command for delay */
+			/* Insert read command for delay */
+			xgifb_reg_get(P3d4, 0x6E);
 			temp2 &= 0xF0;
 			temp2 += 0x10;
 		}
@@ -421,15 +481,18 @@
 
 	temp3 = 0;
 	for (k = 0; k < 4; k++) {
-		xgifb_reg_and_or(P3d4, 0x6E, 0xFC, temp3); /* CR6E_D[1:0] select channel */
+		/* CR6E_D[1:0] select channel */
+		xgifb_reg_and_or(P3d4, 0x6E, 0xFC, temp3);
 		temp2 = 0;
 		for (i = 0; i < 8; i++) {
-			temp = pVBInfo->CR6F[XGINew_RAMType][8 * k + i]; /* CR6F DQ fine tune delay */
+			/* CR6F DQ fine tune delay */
+			temp = pVBInfo->CR6F[XGINew_RAMType][8 * k + i];
 			for (j = 0; j < 4; j++) {
 				temp1 = (temp >> (2 * j)) & 0x03;
 				temp2 |= temp1;
 				xgifb_reg_set(P3d4, 0x6F, temp2);
-				xgifb_reg_get(P3d4, 0x6F); /* Insert read command for delay */
+				/* Insert read command for delay */
+				xgifb_reg_get(P3d4, 0x6F);
 				temp2 &= 0xF8;
 				temp2 += 0x08;
 			}
@@ -441,7 +504,8 @@
 	xgifb_reg_set(P3d4, 0x81, pVBInfo->CR40[10][XGINew_RAMType]); /* CR81 */
 
 	temp2 = 0x80;
-	temp = pVBInfo->CR89[XGINew_RAMType][0]; /* CR89 terminator type select */
+	/* CR89 terminator type select */
+	temp = pVBInfo->CR89[XGINew_RAMType][0];
 	for (j = 0; j < 4; j++) {
 		temp1 = (temp >> (2 * j)) & 0x03;
 		temp2 |= temp1;
@@ -468,19 +532,20 @@
 	if (HwDeviceExtension->jChipType == XG27)
 		xgifb_reg_set(P3d4, 0x8F, *pVBInfo->pCR8F); /* CR8F */
 
-	for (j = 0; j <= 6; j++)
+	for (j = 0; j <= 6; j++) /* CR90 - CR96 */
 		xgifb_reg_set(P3d4, (0x90 + j),
-				pVBInfo->CR40[14 + j][XGINew_RAMType]); /* CR90 - CR96 */
+				pVBInfo->CR40[14 + j][XGINew_RAMType]);
 
-	for (j = 0; j <= 2; j++)
+	for (j = 0; j <= 2; j++) /* CRC3 - CRC5 */
 		xgifb_reg_set(P3d4, (0xC3 + j),
-				pVBInfo->CR40[21 + j][XGINew_RAMType]); /* CRC3 - CRC5 */
+				pVBInfo->CR40[21 + j][XGINew_RAMType]);
 
-	for (j = 0; j < 2; j++)
+	for (j = 0; j < 2; j++) /* CR8A - CR8B */
 		xgifb_reg_set(P3d4, (0x8A + j),
-				pVBInfo->CR40[1 + j][XGINew_RAMType]); /* CR8A - CR8B */
+				pVBInfo->CR40[1 + j][XGINew_RAMType]);
 
-	if ((HwDeviceExtension->jChipType == XG41) || (HwDeviceExtension->jChipType == XG42))
+	if ((HwDeviceExtension->jChipType == XG41) ||
+	    (HwDeviceExtension->jChipType == XG42))
 		xgifb_reg_set(P3d4, 0x8C, 0x87);
 
 	xgifb_reg_set(P3d4, 0x59, pVBInfo->CR40[4][XGINew_RAMType]); /* CR59 */
@@ -550,7 +615,10 @@
 		memsize = data >> 4;
 
 		/* [2004/03/25] Vicent, Fix DRAM Sizing Error */
-		xgifb_reg_set(pVBInfo->P3c4, 0x14, (xgifb_reg_get(pVBInfo->P3c4, 0x14) & 0x0F) | (data & 0xF0));
+		xgifb_reg_set(pVBInfo->P3c4,
+			      0x14,
+			      (xgifb_reg_get(pVBInfo->P3c4, 0x14) & 0x0F) |
+			       (data & 0xF0));
 
 		/* data |= XGINew_ChannelAB << 2; */
 		/* data |= (XGINew_DataBusWidth / 64) << 1; */
@@ -591,7 +659,10 @@
 		memsize = data >> 4;
 
 		/* [2004/03/25] Vicent, Fix DRAM Sizing Error */
-		xgifb_reg_set(pVBInfo->P3c4, 0x14, (xgifb_reg_get(pVBInfo->P3c4, 0x14) & 0x0F) | (data & 0xF0));
+		xgifb_reg_set(pVBInfo->P3c4,
+			      0x14,
+			      (xgifb_reg_get(pVBInfo->P3c4, 0x14) & 0x0F) |
+				(data & 0xF0));
 		udelay(15);
 
 		/* data |= XGINew_ChannelAB << 2; */
@@ -617,7 +688,8 @@
 		*((unsigned long *) (pVBInfo->FBAddr + Position)) = Position;
 	}
 
-	udelay(500); /* [Vicent] 2004/04/16. Fix #1759 Memory Size error in Multi-Adapter. */
+	udelay(500); /* [Vicent] 2004/04/16.
+			Fix #1759 Memory Size error in Multi-Adapter. */
 
 	Position = 0;
 
@@ -626,7 +698,8 @@
 
 	for (i = StartAddr; i <= StopAddr; i++) {
 		Position = 1 << i;
-		if ((*(unsigned long *) (pVBInfo->FBAddr + Position)) != Position)
+		if ((*(unsigned long *) (pVBInfo->FBAddr + Position)) !=
+		    Position)
 			return 0;
 	}
 	return 1;
@@ -665,67 +738,96 @@
 					> 0x1000000) {
 
 				XGINew_DataBusWidth = 32; /* 32 bits */
-				xgifb_reg_set(pVBInfo->P3c4, 0x13, 0xB1); /* 22bit + 2 rank + 32bit */
+				/* 22bit + 2 rank + 32bit */
+				xgifb_reg_set(pVBInfo->P3c4, 0x13, 0xB1);
 				xgifb_reg_set(pVBInfo->P3c4, 0x14, 0x52);
 				udelay(15);
 
 				if (XGINew_ReadWriteRest(24, 23, pVBInfo) == 1)
 					return;
 
-				if ((HwDeviceExtension->ulVideoMemorySize - 1) > 0x800000) {
-					xgifb_reg_set(pVBInfo->P3c4, 0x13, 0x31); /* 22bit + 1 rank + 32bit */
-					xgifb_reg_set(pVBInfo->P3c4, 0x14, 0x42);
+				if ((HwDeviceExtension->ulVideoMemorySize - 1) >
+				    0x800000) {
+					/* 22bit + 1 rank + 32bit */
+					xgifb_reg_set(pVBInfo->P3c4,
+						      0x13,
+						      0x31);
+					xgifb_reg_set(pVBInfo->P3c4,
+						      0x14,
+						      0x42);
 					udelay(15);
 
-					if (XGINew_ReadWriteRest(23, 23, pVBInfo) == 1)
+					if (XGINew_ReadWriteRest(23,
+								 23,
+								 pVBInfo) == 1)
 						return;
 				}
 			}
 
-			if ((HwDeviceExtension->ulVideoMemorySize - 1) > 0x800000) {
+			if ((HwDeviceExtension->ulVideoMemorySize - 1) >
+			    0x800000) {
 				XGINew_DataBusWidth = 16; /* 16 bits */
-				xgifb_reg_set(pVBInfo->P3c4, 0x13, 0xB1); /* 22bit + 2 rank + 16bit */
+				/* 22bit + 2 rank + 16bit */
+				xgifb_reg_set(pVBInfo->P3c4, 0x13, 0xB1);
 				xgifb_reg_set(pVBInfo->P3c4, 0x14, 0x41);
 				udelay(15);
 
 				if (XGINew_ReadWriteRest(23, 22, pVBInfo) == 1)
 					return;
 				else
-					xgifb_reg_set(pVBInfo->P3c4, 0x13, 0x31);
+					xgifb_reg_set(pVBInfo->P3c4,
+						      0x13,
+						      0x31);
 				udelay(15);
 			}
 
 		} else { /* Dual_16_8 */
-			if ((HwDeviceExtension->ulVideoMemorySize - 1) > 0x800000) {
-
+			if ((HwDeviceExtension->ulVideoMemorySize - 1) >
+			    0x800000) {
 				XGINew_DataBusWidth = 16; /* 16 bits */
-				xgifb_reg_set(pVBInfo->P3c4, 0x13, 0xB1); /* (0x31:12x8x2) 22bit + 2 rank */
-				xgifb_reg_set(pVBInfo->P3c4, 0x14, 0x41); /* 0x41:16Mx16 bit*/
+				/* (0x31:12x8x2) 22bit + 2 rank */
+				xgifb_reg_set(pVBInfo->P3c4, 0x13, 0xB1);
+				/* 0x41:16Mx16 bit*/
+				xgifb_reg_set(pVBInfo->P3c4, 0x14, 0x41);
 				udelay(15);
 
 				if (XGINew_ReadWriteRest(23, 22, pVBInfo) == 1)
 					return;
 
-				if ((HwDeviceExtension->ulVideoMemorySize - 1) > 0x400000) {
-					xgifb_reg_set(pVBInfo->P3c4, 0x13, 0x31); /* (0x31:12x8x2) 22bit + 1 rank */
-					xgifb_reg_set(pVBInfo->P3c4, 0x14, 0x31); /* 0x31:8Mx16 bit*/
+				if ((HwDeviceExtension->ulVideoMemorySize - 1) >
+				    0x400000) {
+					/* (0x31:12x8x2) 22bit + 1 rank */
+					xgifb_reg_set(pVBInfo->P3c4,
+						      0x13,
+						      0x31);
+					/* 0x31:8Mx16 bit*/
+					xgifb_reg_set(pVBInfo->P3c4,
+						      0x14,
+						      0x31);
 					udelay(15);
 
-					if (XGINew_ReadWriteRest(22, 22, pVBInfo) == 1)
+					if (XGINew_ReadWriteRest(22,
+								 22,
+								 pVBInfo) == 1)
 						return;
 				}
 			}
 
-			if ((HwDeviceExtension->ulVideoMemorySize - 1) > 0x400000) {
+			if ((HwDeviceExtension->ulVideoMemorySize - 1) >
+			    0x400000) {
 				XGINew_DataBusWidth = 8; /* 8 bits */
-				xgifb_reg_set(pVBInfo->P3c4, 0x13, 0xB1); /* (0x31:12x8x2) 22bit + 2 rank */
-				xgifb_reg_set(pVBInfo->P3c4, 0x14, 0x30); /* 0x30:8Mx8 bit*/
+				/* (0x31:12x8x2) 22bit + 2 rank */
+				xgifb_reg_set(pVBInfo->P3c4, 0x13, 0xB1);
+				/* 0x30:8Mx8 bit*/
+				xgifb_reg_set(pVBInfo->P3c4, 0x14, 0x30);
 				udelay(15);
 
 				if (XGINew_ReadWriteRest(22, 21, pVBInfo) == 1)
 					return;
-				else
-					xgifb_reg_set(pVBInfo->P3c4, 0x13, 0x31); /* (0x31:12x8x2) 22bit + 1 rank */
+				else /* (0x31:12x8x2) 22bit + 1 rank */
+					xgifb_reg_set(pVBInfo->P3c4,
+						      0x13,
+						      0x31);
 				udelay(15);
 			}
 		}
@@ -911,13 +1013,18 @@
 
 	if (HwDeviceExtension->jChipType >= XG20) {
 		for (i = 0; i < 12; i++) {
-			XGINew_SetDRAMSizingType(i, XGINew_DDRDRAM_TYPE20, pVBInfo);
-			memsize = XGINew_SetDRAMSize20Reg(i, XGINew_DDRDRAM_TYPE20, pVBInfo);
+			XGINew_SetDRAMSizingType(i,
+						 XGINew_DDRDRAM_TYPE20,
+						 pVBInfo);
+			memsize = XGINew_SetDRAMSize20Reg(i,
+							  XGINew_DDRDRAM_TYPE20,
+							  pVBInfo);
 			if (memsize == 0)
 				continue;
 
 			addr = memsize + (XGINew_ChannelAB - 2) + 20;
-			if ((HwDeviceExtension->ulVideoMemorySize - 1) < (unsigned long) (1 << addr))
+			if ((HwDeviceExtension->ulVideoMemorySize - 1) <
+			    (unsigned long) (1 << addr))
 				continue;
 
 			if (XGINew_ReadWriteRest(addr, 5, pVBInfo) == 1)
@@ -925,14 +1032,19 @@
 		}
 	} else {
 		for (i = 0; i < 4; i++) {
-			XGINew_SetDRAMSizingType(i, XGINew_DDRDRAM_TYPE340, pVBInfo);
-			memsize = XGINew_SetDRAMSizeReg(i, XGINew_DDRDRAM_TYPE340, pVBInfo);
+			XGINew_SetDRAMSizingType(i,
+						 XGINew_DDRDRAM_TYPE340,
+						 pVBInfo);
+			memsize = XGINew_SetDRAMSizeReg(i,
+							XGINew_DDRDRAM_TYPE340,
+							pVBInfo);
 
 			if (memsize == 0)
 				continue;
 
 			addr = memsize + (XGINew_ChannelAB - 2) + 20;
-			if ((HwDeviceExtension->ulVideoMemorySize - 1) < (unsigned long) (1 << addr))
+			if ((HwDeviceExtension->ulVideoMemorySize - 1) <
+			    (unsigned long) (1 << addr))
 				continue;
 
 			if (XGINew_ReadWriteRest(addr, 9, pVBInfo) == 1)
@@ -953,7 +1065,8 @@
 	XGISetModeNew(HwDeviceExtension, 0x2e);
 
 	data = xgifb_reg_get(pVBInfo->P3c4, 0x21);
-	xgifb_reg_set(pVBInfo->P3c4, 0x21, (unsigned short) (data & 0xDF)); /* disable read cache */
+	/* disable read cache */
+	xgifb_reg_set(pVBInfo->P3c4, 0x21, (unsigned short) (data & 0xDF));
 	XGI_DisplayOff(HwDeviceExtension, pVBInfo);
 
 	/* data = xgifb_reg_get(pVBInfo->P3c4, 0x1); */
@@ -961,12 +1074,15 @@
 	/* xgifb_reg_set(pVBInfo->P3c4, 0x01, data); *//* Turn OFF Display */
 	XGINew_DDRSizing340(HwDeviceExtension, pVBInfo);
 	data = xgifb_reg_get(pVBInfo->P3c4, 0x21);
-	xgifb_reg_set(pVBInfo->P3c4, 0x21, (unsigned short) (data | 0x20)); /* enable read cache */
+	/* enable read cache */
+	xgifb_reg_set(pVBInfo->P3c4, 0x21, (unsigned short) (data | 0x20));
 }
 
-static void ReadVBIOSTablData(unsigned char ChipType, struct vb_device_info *pVBInfo)
+static void ReadVBIOSTablData(unsigned char ChipType,
+			      struct vb_device_info *pVBInfo)
 {
-	volatile unsigned char *pVideoMemory = (unsigned char *) pVBInfo->ROMAddr;
+	volatile unsigned char *pVideoMemory =
+		(unsigned char *) pVBInfo->ROMAddr;
 	unsigned long i;
 	unsigned char j, k;
 	/* Volari customize data area end */
@@ -980,24 +1096,34 @@
 			if (j != 0xff) {
 				k = 0;
 				do {
-					pVBInfo->XG21_LVDSCapList[k].LVDS_Capability
-						= pVideoMemory[i] | (pVideoMemory[i + 1] << 8);
+					pVBInfo->XG21_LVDSCapList[k].
+						 LVDS_Capability
+						= pVideoMemory[i] |
+						 (pVideoMemory[i + 1] << 8);
 					pVBInfo->XG21_LVDSCapList[k].LVDSHT
-						= pVideoMemory[i + 2] | (pVideoMemory[i + 3] << 8);
+						= pVideoMemory[i + 2] |
+						  (pVideoMemory[i + 3] << 8);
 					pVBInfo->XG21_LVDSCapList[k].LVDSVT
-						= pVideoMemory[i + 4] | (pVideoMemory[i	+ 5] << 8);
+						= pVideoMemory[i + 4] |
+						  (pVideoMemory[i + 5] << 8);
 					pVBInfo->XG21_LVDSCapList[k].LVDSHDE
-						= pVideoMemory[i + 6] | (pVideoMemory[i	+ 7] << 8);
+						= pVideoMemory[i + 6] |
+						  (pVideoMemory[i + 7] << 8);
 					pVBInfo->XG21_LVDSCapList[k].LVDSVDE
-						= pVideoMemory[i + 8] | (pVideoMemory[i + 9] << 8);
+						= pVideoMemory[i + 8] |
+						  (pVideoMemory[i + 9] << 8);
 					pVBInfo->XG21_LVDSCapList[k].LVDSHFP
-						= pVideoMemory[i + 10] | (pVideoMemory[i + 11] << 8);
+						= pVideoMemory[i + 10] |
+						  (pVideoMemory[i + 11] << 8);
 					pVBInfo->XG21_LVDSCapList[k].LVDSVFP
-						= pVideoMemory[i + 12] | (pVideoMemory[i + 13] << 8);
+						= pVideoMemory[i + 12] |
+						  (pVideoMemory[i + 13] << 8);
 					pVBInfo->XG21_LVDSCapList[k].LVDSHSYNC
-						= pVideoMemory[i + 14] | (pVideoMemory[i + 15] << 8);
+						= pVideoMemory[i + 14] |
+						  (pVideoMemory[i + 15] << 8);
 					pVBInfo->XG21_LVDSCapList[k].LVDSVSYNC
-						= pVideoMemory[i + 16] | (pVideoMemory[i + 17] << 8);
+						= pVideoMemory[i + 16] |
+						  (pVideoMemory[i + 17] << 8);
 					pVBInfo->XG21_LVDSCapList[k].VCLKData1
 						= pVideoMemory[i + 18];
 					pVBInfo->XG21_LVDSCapList[k].VCLKData2
@@ -1015,26 +1141,38 @@
 					i += 25;
 					j--;
 					k++;
-				} while ((j > 0) && (k < (sizeof(XGI21_LCDCapList) / sizeof(struct XGI21_LVDSCapStruct))));
+				} while ((j > 0) &&
+					 (k < (sizeof(XGI21_LCDCapList) /
+					       sizeof(struct
+							XGI21_LVDSCapStruct))));
 			} else {
 				pVBInfo->XG21_LVDSCapList[0].LVDS_Capability
-						= pVideoMemory[i] | (pVideoMemory[i + 1] << 8);
+						= pVideoMemory[i] |
+						  (pVideoMemory[i + 1] << 8);
 				pVBInfo->XG21_LVDSCapList[0].LVDSHT
-						= pVideoMemory[i + 2] | (pVideoMemory[i + 3] << 8);
+						= pVideoMemory[i + 2] |
+						  (pVideoMemory[i + 3] << 8);
 				pVBInfo->XG21_LVDSCapList[0].LVDSVT
-						= pVideoMemory[i + 4] | (pVideoMemory[i + 5] << 8);
+						= pVideoMemory[i + 4] |
+						  (pVideoMemory[i + 5] << 8);
 				pVBInfo->XG21_LVDSCapList[0].LVDSHDE
-						= pVideoMemory[i + 6] | (pVideoMemory[i + 7] << 8);
+						= pVideoMemory[i + 6] |
+						  (pVideoMemory[i + 7] << 8);
 				pVBInfo->XG21_LVDSCapList[0].LVDSVDE
-						= pVideoMemory[i + 8] | (pVideoMemory[i + 9] << 8);
+						= pVideoMemory[i + 8] |
+						  (pVideoMemory[i + 9] << 8);
 				pVBInfo->XG21_LVDSCapList[0].LVDSHFP
-						= pVideoMemory[i + 10] | (pVideoMemory[i + 11] << 8);
+						= pVideoMemory[i + 10] |
+						  (pVideoMemory[i + 11] << 8);
 				pVBInfo->XG21_LVDSCapList[0].LVDSVFP
-						= pVideoMemory[i + 12] | (pVideoMemory[i + 13] << 8);
+						= pVideoMemory[i + 12] |
+						  (pVideoMemory[i + 13] << 8);
 				pVBInfo->XG21_LVDSCapList[0].LVDSHSYNC
-						= pVideoMemory[i + 14] | (pVideoMemory[i + 15] << 8);
+						= pVideoMemory[i + 14] |
+						  (pVideoMemory[i + 15] << 8);
 				pVBInfo->XG21_LVDSCapList[0].LVDSVSYNC
-						= pVideoMemory[i + 16] | (pVideoMemory[i + 17] << 8);
+						= pVideoMemory[i + 16] |
+						  (pVideoMemory[i + 17] << 8);
 				pVBInfo->XG21_LVDSCapList[0].VCLKData1
 						= pVideoMemory[i + 18];
 				pVBInfo->XG21_LVDSCapList[0].VCLKData2
@@ -1197,21 +1335,31 @@
 	if ((pVideoMemory[0x65] & 0x01)) { /* For XG21 LVDS */
 		pVBInfo->IF_DEF_LVDS = 1;
 		xgifb_reg_or(pVBInfo->P3d4, 0x32, LCDSense);
-		xgifb_reg_and_or(pVBInfo->P3d4, 0x38, ~0xE0, 0xC0); /* LVDS on chip */
+		/* LVDS on chip */
+		xgifb_reg_and_or(pVBInfo->P3d4, 0x38, ~0xE0, 0xC0);
 	} else {
 #endif
-		xgifb_reg_and_or(pVBInfo->P3d4, 0x4A, ~0x03, 0x03); /* Enable GPIOA/B read  */
+		/* Enable GPIOA/B read  */
+		xgifb_reg_and_or(pVBInfo->P3d4, 0x4A, ~0x03, 0x03);
 		Temp = xgifb_reg_get(pVBInfo->P3d4, 0x48) & 0xC0;
 		if (Temp == 0xC0) { /* DVI & DVO GPIOA/B pull high */
 			XGINew_SenseLCD(HwDeviceExtension, pVBInfo);
 			xgifb_reg_or(pVBInfo->P3d4, 0x32, LCDSense);
-			xgifb_reg_and_or(pVBInfo->P3d4, 0x4A, ~0x20, 0x20); /* Enable read GPIOF */
+			/* Enable read GPIOF */
+			xgifb_reg_and_or(pVBInfo->P3d4, 0x4A, ~0x20, 0x20);
 			Temp = xgifb_reg_get(pVBInfo->P3d4, 0x48) & 0x04;
 			if (!Temp)
-				xgifb_reg_and_or(pVBInfo->P3d4, 0x38, ~0xE0, 0x80); /* TMDS on chip */
+				xgifb_reg_and_or(pVBInfo->P3d4,
+						 0x38,
+						 ~0xE0,
+						 0x80); /* TMDS on chip */
 			else
-				xgifb_reg_and_or(pVBInfo->P3d4, 0x38, ~0xE0, 0xA0); /* Only DVO on chip */
-			xgifb_reg_and(pVBInfo->P3d4, 0x4A, ~0x20); /* Disable read GPIOF */
+				xgifb_reg_and_or(pVBInfo->P3d4,
+						 0x38,
+						 ~0xE0,
+						 0xA0); /* Only DVO on chip */
+			/* Disable read GPIOF */
+			xgifb_reg_and(pVBInfo->P3d4, 0x4A, ~0x20);
 		}
 #if 1
 	}
@@ -1225,16 +1373,19 @@
 
 	pVBInfo->IF_DEF_LVDS = 0;
 	bCR4A = xgifb_reg_get(pVBInfo->P3d4, 0x4A);
-	xgifb_reg_and_or(pVBInfo->P3d4, 0x4A, ~0x07, 0x07); /* Enable GPIOA/B/C read  */
+	/* Enable GPIOA/B/C read  */
+	xgifb_reg_and_or(pVBInfo->P3d4, 0x4A, ~0x07, 0x07);
 	Temp = xgifb_reg_get(pVBInfo->P3d4, 0x48) & 0x07;
 	xgifb_reg_set(pVBInfo->P3d4, 0x4A, bCR4A);
 
 	if (Temp <= 0x02) {
 		pVBInfo->IF_DEF_LVDS = 1;
-		xgifb_reg_and_or(pVBInfo->P3d4, 0x38, ~0xE0, 0xC0); /* LVDS setting */
+		/* LVDS setting */
+		xgifb_reg_and_or(pVBInfo->P3d4, 0x38, ~0xE0, 0xC0);
 		xgifb_reg_set(pVBInfo->P3d4, 0x30, 0x21);
 	} else {
-		xgifb_reg_and_or(pVBInfo->P3d4, 0x38, ~0xE0, 0xA0); /* TMDS/DVO setting */
+		/* TMDS/DVO setting */
+		xgifb_reg_and_or(pVBInfo->P3d4, 0x38, ~0xE0, 0xA0);
 	}
 	xgifb_reg_or(pVBInfo->P3d4, 0x32, LCDSense);
 
@@ -1245,7 +1396,8 @@
 	unsigned char CR38, CR4A, temp;
 
 	CR4A = xgifb_reg_get(pVBInfo->P3d4, 0x4A);
-	xgifb_reg_and_or(pVBInfo->P3d4, 0x4A, ~0x10, 0x10); /* enable GPIOE read */
+	/* enable GPIOE read */
+	xgifb_reg_and_or(pVBInfo->P3d4, 0x4A, ~0x10, 0x10);
 	CR38 = xgifb_reg_get(pVBInfo->P3d4, 0x38);
 	temp = 0;
 	if ((CR38 & 0xE0) > 0x80) {
@@ -1264,7 +1416,8 @@
 	unsigned char CR4A, temp;
 
 	CR4A = xgifb_reg_get(pVBInfo->P3d4, 0x4A);
-	xgifb_reg_and_or(pVBInfo->P3d4, 0x4A, ~0x03, 0x03); /* enable GPIOA/B/C read */
+	/* enable GPIOA/B/C read */
+	xgifb_reg_and_or(pVBInfo->P3d4, 0x4A, ~0x03, 0x03);
 	temp = xgifb_reg_get(pVBInfo->P3d4, 0x48);
 	if (temp <= 2)
 		temp &= 0x03;
@@ -1344,7 +1497,8 @@
 	printk("5");
 
 	if (HwDeviceExtension->jChipType < XG20) /* kuku 2004/06/25 */
-		XGI_GetVBType(pVBInfo); /* Run XGI_GetVBType before InitTo330Pointer */
+		/* Run XGI_GetVBType before InitTo330Pointer */
+		XGI_GetVBType(pVBInfo);
 
 	InitTo330Pointer(HwDeviceExtension->jChipType, pVBInfo);
 
@@ -1381,7 +1535,8 @@
 		xgifb_reg_set(pVBInfo->P3c4, i, 0);
 	printk("9");
 
-	if (HwDeviceExtension->jChipType == XG42) /* [Hsuan] 2004/08/20 Auto over driver for XG42 */
+	/* [Hsuan] 2004/08/20 Auto over driver for XG42 */
+	if (HwDeviceExtension->jChipType == XG42)
 		xgifb_reg_set(pVBInfo->P3c4, 0x3B, 0xC0);
 
 	/* for (i = 0x30; i <= 0x3F; i++) */
@@ -1397,7 +1552,8 @@
 
 	/* 3.SetMemoryClock
 
-	 XGINew_RAMType = (int)XGINew_GetXG20DRAMType(HwDeviceExtension, pVBInfo);
+	 XGINew_RAMType = (int)XGINew_GetXG20DRAMType(HwDeviceExtension,
+						      pVBInfo);
 	*/
 
 	printk("11");
@@ -1411,8 +1567,10 @@
 	xgifb_reg_set(pVBInfo->P3c4, 0x11, 0x0F);
 	xgifb_reg_set(pVBInfo->P3c4, 0x1F, *pVBInfo->pSR1F);
 	/* xgifb_reg_set(pVBInfo->P3c4, 0x20, 0x20); */
-	xgifb_reg_set(pVBInfo->P3c4, 0x20, 0xA0); /* alan, 2001/6/26 Frame buffer can read/write SR20 */
-	xgifb_reg_set(pVBInfo->P3c4, 0x36, 0x70); /* Hsuan, 2006/01/01 H/W request for slow corner chip */
+	/* alan, 2001/6/26 Frame buffer can read/write SR20 */
+	xgifb_reg_set(pVBInfo->P3c4, 0x20, 0xA0);
+	/* Hsuan, 2006/01/01 H/W request for slow corner chip */
+	xgifb_reg_set(pVBInfo->P3c4, 0x36, 0x70);
 	if (HwDeviceExtension->jChipType == XG27) /* Alan 12/07/2006 */
 		xgifb_reg_set(pVBInfo->P3c4, 0x36, *pVBInfo->pSR36);
 
@@ -1441,14 +1599,24 @@
 
 			ChipsetID &= 0x0000FFFF;
 
-			if ((ChipsetID == 0x700E) || (ChipsetID == 0x1022) || (ChipsetID == 0x1106) || (ChipsetID == 0x10DE)) {
+			if ((ChipsetID == 0x700E) ||
+			    (ChipsetID == 0x1022) ||
+			    (ChipsetID == 0x1106) ||
+			    (ChipsetID == 0x10DE)) {
 				if (ChipsetID == 0x1106) {
-					if ((VendorID == 0x1019) && (GraphicVendorID == 0x1019))
-						xgifb_reg_set(pVBInfo->P3d4, 0x5F, 0x0D);
+					if ((VendorID == 0x1019) &&
+					    (GraphicVendorID == 0x1019))
+						xgifb_reg_set(pVBInfo->P3d4,
+							      0x5F,
+							      0x0D);
 					else
-						xgifb_reg_set(pVBInfo->P3d4, 0x5F, 0x0B);
+						xgifb_reg_set(pVBInfo->P3d4,
+							      0x5F,
+							      0x0B);
 				} else {
-					xgifb_reg_set(pVBInfo->P3d4, 0x5F, 0x0B);
+					xgifb_reg_set(pVBInfo->P3d4,
+						      0x5F,
+						      0x0B);
 				}
 			}
 		}
@@ -1458,13 +1626,19 @@
 
 		/* Set AGP customize registers (in SetDefAGPRegs) Start */
 		for (i = 0x47; i <= 0x4C; i++)
-			xgifb_reg_set(pVBInfo->P3d4, i, pVBInfo->AGPReg[i - 0x47]);
+			xgifb_reg_set(pVBInfo->P3d4,
+				      i,
+				      pVBInfo->AGPReg[i - 0x47]);
 
 		for (i = 0x70; i <= 0x71; i++)
-			xgifb_reg_set(pVBInfo->P3d4, i, pVBInfo->AGPReg[6 + i - 0x70]);
+			xgifb_reg_set(pVBInfo->P3d4,
+				      i,
+				      pVBInfo->AGPReg[6 + i - 0x70]);
 
 		for (i = 0x74; i <= 0x77; i++)
-			xgifb_reg_set(pVBInfo->P3d4, i, pVBInfo->AGPReg[8 + i - 0x74]);
+			xgifb_reg_set(pVBInfo->P3d4,
+				      i,
+				      pVBInfo->AGPReg[8 + i - 0x74]);
 		/* Set AGP customize registers (in SetDefAGPRegs) End */
 		/* [Hsuan]2004/12/14 AGP Input Delay Adjustment on 850 */
 		/*        outl(0x80000000, 0xcf8); */
@@ -1472,7 +1646,10 @@
 		/*        if (ChipsetID == 0x25308086) */
 		/*            xgifb_reg_set(pVBInfo->P3d4, 0x77, 0xF0); */
 
-		HwDeviceExtension->pQueryVGAConfigSpace(HwDeviceExtension, 0x50, 0, &Temp); /* Get */
+		HwDeviceExtension->pQueryVGAConfigSpace(HwDeviceExtension,
+							0x50,
+							0,
+							&Temp); /* Get */
 		Temp >>= 20;
 		Temp &= 0xF;
 
@@ -1490,12 +1667,16 @@
 	if (HwDeviceExtension->jChipType < XG20) { /* kuku 2004/06/25 */
 		/* Set VB */
 		XGI_UnLockCRT2(HwDeviceExtension, pVBInfo);
-		xgifb_reg_and_or(pVBInfo->Part0Port, 0x3F, 0xEF, 0x00); /* alan, disable VideoCapture */
+		/* alan, disable VideoCapture */
+		xgifb_reg_and_or(pVBInfo->Part0Port, 0x3F, 0xEF, 0x00);
 		xgifb_reg_set(pVBInfo->Part1Port, 0x00, 0x00);
-		temp1 = (unsigned char) xgifb_reg_get(pVBInfo->P3d4, 0x7B); /* chk if BCLK>=100MHz */
+		/* chk if BCLK>=100MHz */
+		temp1 = (unsigned char) xgifb_reg_get(pVBInfo->P3d4, 0x7B);
 		temp = (unsigned char) ((temp1 >> 4) & 0x0F);
 
-		xgifb_reg_set(pVBInfo->Part1Port, 0x02, (*pVBInfo->pCRT2Data_1_2));
+		xgifb_reg_set(pVBInfo->Part1Port,
+			      0x02,
+			      (*pVBInfo->pCRT2Data_1_2));
 
 		printk("16");
 
@@ -1504,10 +1685,15 @@
 
 	xgifb_reg_set(pVBInfo->P3c4, 0x27, 0x1F);
 
-	if ((HwDeviceExtension->jChipType == XG42)
-			&& XGINew_GetXG20DRAMType(HwDeviceExtension, pVBInfo) != 0) { /* Not DDR */
-		xgifb_reg_set(pVBInfo->P3c4, 0x31, (*pVBInfo->pSR31 & 0x3F) | 0x40);
-		xgifb_reg_set(pVBInfo->P3c4, 0x32, (*pVBInfo->pSR32 & 0xFC) | 0x01);
+	if ((HwDeviceExtension->jChipType == XG42) &&
+	    XGINew_GetXG20DRAMType(HwDeviceExtension, pVBInfo) != 0) {
+		/* Not DDR */
+		xgifb_reg_set(pVBInfo->P3c4,
+			      0x31,
+			      (*pVBInfo->pSR31 & 0x3F) | 0x40);
+		xgifb_reg_set(pVBInfo->P3c4,
+			      0x32,
+			      (*pVBInfo->pSR32 & 0xFC) | 0x01);
 	} else {
 		xgifb_reg_set(pVBInfo->P3c4, 0x31, *pVBInfo->pSR31);
 		xgifb_reg_set(pVBInfo->P3c4, 0x32, *pVBInfo->pSR32);
@@ -1522,9 +1708,15 @@
 		if (XGI_BridgeIsOn(pVBInfo) == 1) {
 			if (pVBInfo->IF_DEF_LVDS == 0) {
 				xgifb_reg_set(pVBInfo->Part2Port, 0x00, 0x1C);
-				xgifb_reg_set(pVBInfo->Part4Port, 0x0D, *pVBInfo->pCRT2Data_4_D);
-				xgifb_reg_set(pVBInfo->Part4Port, 0x0E, *pVBInfo->pCRT2Data_4_E);
-				xgifb_reg_set(pVBInfo->Part4Port, 0x10, *pVBInfo->pCRT2Data_4_10);
+				xgifb_reg_set(pVBInfo->Part4Port,
+					      0x0D,
+					      *pVBInfo->pCRT2Data_4_D);
+				xgifb_reg_set(pVBInfo->Part4Port,
+					      0x0E,
+					      *pVBInfo->pCRT2Data_4_E);
+				xgifb_reg_set(pVBInfo->Part4Port,
+					      0x10,
+					      *pVBInfo->pCRT2Data_4_10);
 				xgifb_reg_set(pVBInfo->Part4Port, 0x0F, 0x3F);
 			}
 
@@ -1542,31 +1734,42 @@
 	printk("183");
 	/* XGINew_DetectMonitor(HwDeviceExtension); */
 	pVBInfo->IF_DEF_CH7007 = 0;
-	if ((HwDeviceExtension->jChipType == XG21) && (pVBInfo->IF_DEF_CH7007)) {
+	if ((HwDeviceExtension->jChipType == XG21) &&
+	    (pVBInfo->IF_DEF_CH7007)) {
 		printk("184");
-		XGI_GetSenseStatus(HwDeviceExtension, pVBInfo); /* sense CRT2 */
+		/* sense CRT2 */
+		XGI_GetSenseStatus(HwDeviceExtension, pVBInfo);
 		printk("185");
 
 	}
 	if (HwDeviceExtension->jChipType == XG21) {
 		printk("186");
 
-		xgifb_reg_and_or(pVBInfo->P3d4, 0x32, ~Monitor1Sense, Monitor1Sense); /* Z9 default has CRT */
+		xgifb_reg_and_or(pVBInfo->P3d4,
+				 0x32,
+				 ~Monitor1Sense,
+				 Monitor1Sense); /* Z9 default has CRT */
 		temp = GetXG21FPBits(pVBInfo);
 		xgifb_reg_and_or(pVBInfo->P3d4, 0x37, ~0x01, temp);
 		printk("187");
 
 	}
 	if (HwDeviceExtension->jChipType == XG27) {
-		xgifb_reg_and_or(pVBInfo->P3d4, 0x32, ~Monitor1Sense, Monitor1Sense); /* Z9 default has CRT */
+		xgifb_reg_and_or(pVBInfo->P3d4,
+				 0x32,
+				 ~Monitor1Sense,
+				 Monitor1Sense); /* Z9 default has CRT */
 		temp = GetXG27FPBits(pVBInfo);
 		xgifb_reg_and_or(pVBInfo->P3d4, 0x37, ~0x03, temp);
 	}
 	printk("19");
 
-	XGINew_RAMType = (int) XGINew_GetXG20DRAMType(HwDeviceExtension, pVBInfo);
+	XGINew_RAMType = (int) XGINew_GetXG20DRAMType(HwDeviceExtension,
+						      pVBInfo);
 
-	XGINew_SetDRAMDefaultRegister340(HwDeviceExtension, pVBInfo->P3d4, pVBInfo);
+	XGINew_SetDRAMDefaultRegister340(HwDeviceExtension,
+					 pVBInfo->P3d4,
+					 pVBInfo);
 
 	printk("20");
 	XGINew_SetDRAMSize_340(HwDeviceExtension, pVBInfo);
@@ -1594,7 +1797,9 @@
 	/* OutPortLong(0xcf8, base); */
 	/* Temp = (InPortLong(0xcfc) & 0xFFFF); */
 	/* if (Temp == 0x1039) { */
-	xgifb_reg_set(pVBInfo->P3c4, 0x22, (unsigned char) ((*pVBInfo->pSR22) & 0xFE));
+	xgifb_reg_set(pVBInfo->P3c4,
+		      0x22,
+		      (unsigned char) ((*pVBInfo->pSR22) & 0xFE));
 	/* } else { */
 	/*	xgifb_reg_set(pVBInfo->P3c4, 0x22, *pVBInfo->pSR22); */
 	/* } */
diff -druN linux-2.6.39-libre/drivers/staging/xgifb/vb_init.h linux-3.0-rc7-libre/drivers/staging/xgifb/vb_init.h
--- linux-2.6.39-libre/drivers/staging/xgifb/vb_init.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/xgifb/vb_init.h	2011-07-11 19:51:52.000000000 -0400
@@ -1,7 +1,6 @@
-#ifndef  _VBINIT_
-#define  _VBINIT_
-extern   unsigned char    XGIInitNew(struct xgi_hw_device_info *HwDeviceExtension) ;
+#ifndef _VBINIT_
+#define _VBINIT_
+extern unsigned char XGIInitNew(struct xgi_hw_device_info *HwDeviceExtension);
 extern struct XGI21_LVDSCapStruct  XGI21_LCDCapList[13];
-
 #endif
 
diff -druN linux-2.6.39-libre/drivers/staging/xgifb/vb_setmode.c linux-3.0-rc7-libre/drivers/staging/xgifb/vb_setmode.c
--- linux-2.6.39-libre/drivers/staging/xgifb/vb_setmode.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/xgifb/vb_setmode.c	2011-07-11 19:51:52.000000000 -0400
@@ -1,5 +1,5 @@
 
-#include <asm/io.h>
+#include <linux/io.h>
 #include <linux/delay.h>
 #include <linux/types.h>
 #include <linux/version.h>
@@ -71,7 +71,8 @@
 			= (struct XGI_CRT1TableStruct *) XGI_CRT1Table;
 
 	/* add for new UNIVGABIOS */
-	/* XGINew_UBLCDDataTable = (struct XGI_LCDDataTablStruct *) XGI_LCDDataTable; */
+	/* XGINew_UBLCDDataTable =
+	 *	(struct XGI_LCDDataTablStruct *) XGI_LCDDataTable; */
 	/* XGINew_UBTVDataTable = (XGI_TVDataTablStruct *) XGI_TVDataTable; */
 
 	pVBInfo->MCLKData = (struct XGI_MCLKDataStruct *) XGI340New_MCLKData;
@@ -190,8 +191,9 @@
 
 }
 
-static unsigned char XGI_GetModePtr(unsigned short ModeNo, unsigned short ModeIdIndex,
-		struct vb_device_info *pVBInfo)
+static unsigned char XGI_GetModePtr(unsigned short ModeNo,
+				    unsigned short ModeIdIndex,
+				    struct vb_device_info *pVBInfo)
 {
 	unsigned char index;
 
@@ -207,21 +209,24 @@
 }
 
 /*
-unsigned char XGI_SetBIOSData(unsigned short ModeNo, unsigned short ModeIdIndex) {
+unsigned char XGI_SetBIOSData(unsigned short ModeNo,
+			      unsigned short ModeIdIndex) {
 	return (0);
 }
 */
 
-/* unsigned char XGI_ClearBankRegs(unsigned short ModeNo, unsigned short ModeIdIndex) {
+/* unsigned char XGI_ClearBankRegs(unsigned short ModeNo,
+				   unsigned short ModeIdIndex) {
 	return( 0 ) ;
 }
 */
 
-static void XGI_SetSeqRegs(unsigned short ModeNo, unsigned short StandTableIndex,
-		unsigned short ModeIdIndex, struct vb_device_info *pVBInfo)
+static void XGI_SetSeqRegs(unsigned short ModeNo,
+			   unsigned short StandTableIndex,
+			   unsigned short ModeIdIndex,
+			   struct vb_device_info *pVBInfo)
 {
 	unsigned char tempah, SRdata;
-
 	unsigned short i, modeflag;
 
 	if (ModeNo <= 0x13)
@@ -246,19 +251,25 @@
 	xgifb_reg_set(pVBInfo->P3c4, 0x01, tempah); /* Set SR1 */
 
 	for (i = 02; i <= 04; i++) {
-		SRdata = pVBInfo->StandTable[StandTableIndex].SR[i - 1]; /* Get SR2,3,4 from file */
+		/* Get SR2,3,4 from file */
+		SRdata = pVBInfo->StandTable[StandTableIndex].SR[i - 1];
 		xgifb_reg_set(pVBInfo->P3c4, i, SRdata); /* Set SR2 3 4 */
 	}
 }
 
 static void XGI_SetMiscRegs(unsigned short StandTableIndex,
-		struct vb_device_info *pVBInfo)
+			    struct vb_device_info *pVBInfo)
 {
 	unsigned char Miscdata;
 
-	Miscdata = pVBInfo->StandTable[StandTableIndex].MISC; /* Get Misc from file */
+	/* Get Misc from file */
+	Miscdata = pVBInfo->StandTable[StandTableIndex].MISC;
 	/*
-	if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV | VB_XGI301C)) {
+	if (pVBInfo->VBType & (VB_XGI301B |
+			       VB_XGI302B |
+			       VB_XGI301LV |
+			       VB_XGI302LV |
+			       VB_XGI301C)) {
 		if (pVBInfo->VBInfo & SetCRT2ToLCDA) {
 			Miscdata |= 0x0C;
 		}
@@ -269,7 +280,8 @@
 }
 
 static void XGI_SetCRTCRegs(struct xgi_hw_device_info *HwDeviceExtension,
-		unsigned short StandTableIndex, struct vb_device_info *pVBInfo)
+			    unsigned short StandTableIndex,
+			    struct vb_device_info *pVBInfo)
 {
 	unsigned char CRTCdata;
 	unsigned short i;
@@ -279,11 +291,13 @@
 	xgifb_reg_set(pVBInfo->P3d4, 0x11, CRTCdata); /* Unlock CRTC */
 
 	for (i = 0; i <= 0x18; i++) {
-		CRTCdata = pVBInfo->StandTable[StandTableIndex].CRTC[i]; /* Get CRTC from file */
+		/* Get CRTC from file */
+		CRTCdata = pVBInfo->StandTable[StandTableIndex].CRTC[i];
 		xgifb_reg_set(pVBInfo->P3d4, i, CRTCdata); /* Set CRTC(3d4) */
 	}
 	/*
-	if ((HwDeviceExtension->jChipType == XGI_630) && (HwDeviceExtension->jChipRevision == 0x30)) {
+	if ((HwDeviceExtension->jChipType == XGI_630) &&
+	    (HwDeviceExtension->jChipRevision == 0x30)) {
 		if (pVBInfo->VBInfo & SetInSlaveMode) {
 			if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToTV)) {
 				xgifb_reg_set(pVBInfo->P3d4, 0x18, 0xFE);
@@ -293,8 +307,10 @@
 	*/
 }
 
-static void XGI_SetATTRegs(unsigned short ModeNo, unsigned short StandTableIndex,
-		unsigned short ModeIdIndex, struct vb_device_info *pVBInfo)
+static void XGI_SetATTRegs(unsigned short ModeNo,
+			   unsigned short StandTableIndex,
+			   unsigned short ModeIdIndex,
+			   struct vb_device_info *pVBInfo)
 {
 	unsigned char ARdata;
 	unsigned short i, modeflag;
@@ -313,8 +329,8 @@
 				} else {
 					if (pVBInfo->VBInfo & (SetCRT2ToTV
 							| SetCRT2ToLCD)) {
-						if (pVBInfo->VBInfo
-								& SetInSlaveMode)
+						if (pVBInfo->VBInfo &
+						    SetInSlaveMode)
 							ARdata = 0;
 					}
 				}
@@ -334,13 +350,14 @@
 }
 
 static void XGI_SetGRCRegs(unsigned short StandTableIndex,
-		struct vb_device_info *pVBInfo)
+			   struct vb_device_info *pVBInfo)
 {
 	unsigned char GRdata;
 	unsigned short i;
 
 	for (i = 0; i <= 0x08; i++) {
-		GRdata = pVBInfo->StandTable[StandTableIndex].GRC[i]; /* Get GR from file */
+		/* Get GR from file */
+		GRdata = pVBInfo->StandTable[StandTableIndex].GRC[i];
 		xgifb_reg_set(pVBInfo->P3ce, i, GRdata); /* Set GR(3ce) */
 	}
 
@@ -382,7 +399,8 @@
 	unsigned short tempax, tempbx, resinfo, modeflag, infoflag;
 
 	if (ModeNo <= 0x13)
-		modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; /* si+St_ModeFlag */
+		/* si+St_ModeFlag */
+		modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag;
 	else
 		modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
 
@@ -398,12 +416,14 @@
 				tempax |= SupportCRT2in301C;
 		}
 
-		if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) { /* 301b */
+		/* 301b */
+		if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
 			tempax |= SupportLCD;
 
 			if (pVBInfo->LCDResInfo != Panel1280x1024) {
 				if (pVBInfo->LCDResInfo != Panel1280x960) {
-					if (pVBInfo->LCDInfo & LCDNonExpanding) {
+					if (pVBInfo->LCDInfo &
+					    LCDNonExpanding) {
 						if (resinfo >= 9) {
 							tempax = 0;
 							return 0;
@@ -414,8 +434,8 @@
 		}
 
 		if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) { /* for HiTV */
-			if ((pVBInfo->VBType & VB_XGI301LV)
-					&& (pVBInfo->VBExtInfo == VB_YPbPr1080i)) {
+			if ((pVBInfo->VBType & VB_XGI301LV) &&
+			    (pVBInfo->VBExtInfo == VB_YPbPr1080i)) {
 				tempax |= SupportYPbPr;
 				if (pVBInfo->VBInfo & SetInSlaveMode) {
 					if (resinfo == 4)
@@ -444,9 +464,11 @@
 				}
 			}
 		} else {
-			if (pVBInfo->VBInfo & (SetCRT2ToAVIDEO
-					| SetCRT2ToSVIDEO | SetCRT2ToSCART
-					| SetCRT2ToYPbPr | SetCRT2ToHiVisionTV)) {
+			if (pVBInfo->VBInfo & (SetCRT2ToAVIDEO |
+					       SetCRT2ToSVIDEO |
+					       SetCRT2ToSCART |
+					       SetCRT2ToYPbPr |
+					       SetCRT2ToHiVisionTV)) {
 				tempax |= SupportTV;
 
 				if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B
@@ -457,10 +479,10 @@
 
 				if (!(pVBInfo->VBInfo & SetPALTV)) {
 					if (modeflag & NoSupportSimuTV) {
-						if (pVBInfo->VBInfo
-								& SetInSlaveMode) {
-							if (!(pVBInfo->VBInfo
-									& SetNotSimuMode)) {
+						if (pVBInfo->VBInfo &
+						    SetInSlaveMode) {
+							if (!(pVBInfo->VBInfo &
+							      SetNotSimuMode)) {
 								return 0;
 							}
 						}
@@ -490,10 +512,10 @@
 		}
 	}
 
-	for (; pVBInfo->RefIndex[RefreshRateTableIndex + (*i)].ModeID == tempbx; (*i)--) {
-		infoflag
-				= pVBInfo->RefIndex[RefreshRateTableIndex
-						+ (*i)].Ext_InfoFlag;
+	for (; pVBInfo->RefIndex[RefreshRateTableIndex + (*i)].ModeID ==
+	       tempbx; (*i)--) {
+		infoflag = pVBInfo->RefIndex[RefreshRateTableIndex + (*i)].
+				Ext_InfoFlag;
 		if (infoflag & tempax)
 			return 1;
 
@@ -502,9 +524,8 @@
 	}
 
 	for ((*i) = 0;; (*i)++) {
-		infoflag
-				= pVBInfo->RefIndex[RefreshRateTableIndex
-						+ (*i)].Ext_InfoFlag;
+		infoflag = pVBInfo->RefIndex[RefreshRateTableIndex + (*i)].
+				Ext_InfoFlag;
 		if (pVBInfo->RefIndex[RefreshRateTableIndex + (*i)].ModeID
 				!= tempbx) {
 			return 0;
@@ -521,7 +542,8 @@
 {
 	unsigned short sync, temp;
 
-	sync = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_InfoFlag >> 8; /* di+0x00 */
+	/* di+0x00 */
+	sync = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_InfoFlag >> 8;
 	sync &= 0xC0;
 	temp = 0x2F;
 	temp |= sync;
@@ -538,7 +560,8 @@
 	/* xgifb_reg_set(pVBInfo->P3d4, 0x56, 0); */
 	/* xgifb_reg_and_or(pVBInfo->P3d4, 0x11, 0x7f, 0x00); */
 
-	data = (unsigned char) xgifb_reg_get(pVBInfo->P3d4, 0x11); /* unlock cr0-7 */
+	/* unlock cr0-7 */
+	data = (unsigned char) xgifb_reg_get(pVBInfo->P3d4, 0x11);
 	data &= 0x7F;
 	xgifb_reg_set(pVBInfo->P3d4, 0x11, data);
 
@@ -591,8 +614,9 @@
 	}
 }
 
-static void XGI_SetCRT1Timing_V(unsigned short ModeIdIndex, unsigned short ModeNo,
-		struct vb_device_info *pVBInfo)
+static void XGI_SetCRT1Timing_V(unsigned short ModeIdIndex,
+				unsigned short ModeNo,
+				struct vb_device_info *pVBInfo)
 {
 	unsigned char data;
 	unsigned short i, j;
@@ -650,7 +674,8 @@
 	unsigned char index, data;
 	unsigned short i;
 
-	index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC; /* Get index */
+	/* Get index */
+	index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
 	index = index & IndexMask;
 
 	data = (unsigned char) xgifb_reg_get(pVBInfo->P3d4, 0x11);
@@ -688,9 +713,12 @@
 
 	if (ModeNo <= 0x13) {
 		StandTableIndex = XGI_GetModePtr(ModeNo, ModeIdIndex, pVBInfo);
-		Tempax = pVBInfo->StandTable[StandTableIndex].CRTC[4]; /* CR04 HRS */
-		xgifb_reg_set(pVBInfo->P3c4, 0x2E, Tempax); /* SR2E [7:0]->HRS */
-		Tempbx = pVBInfo->StandTable[StandTableIndex].CRTC[5]; /* Tempbx: CR05 HRE */
+		/* CR04 HRS */
+		Tempax = pVBInfo->StandTable[StandTableIndex].CRTC[4];
+		/* SR2E [7:0]->HRS */
+		xgifb_reg_set(pVBInfo->P3c4, 0x2E, Tempax);
+		/* Tempbx: CR05 HRE */
+		Tempbx = pVBInfo->StandTable[StandTableIndex].CRTC[5];
 		Tempbx &= 0x1F; /* Tempbx: HRE[4:0] */
 		Tempcx = Tempax;
 		Tempcx &= 0xE0; /* Tempcx: HRS[7:5] */
@@ -698,27 +726,34 @@
 		if (Tempbx < (Tempax & 0x1F)) /* IF HRE < HRS */
 			Tempdx |= 0x20; /* Tempdx: HRE = HRE + 0x20 */
 		Tempdx <<= 2; /* Tempdx << 2 */
-		xgifb_reg_set(pVBInfo->P3c4, 0x2F, Tempdx); /* SR2F [7:2]->HRE */
+		/* SR2F [7:2]->HRE */
+		xgifb_reg_set(pVBInfo->P3c4, 0x2F, Tempdx);
 		xgifb_reg_and_or(pVBInfo->P3c4, 0x30, 0xE3, 00);
 
-		Tempax = pVBInfo->StandTable[StandTableIndex].CRTC[16]; /* Tempax: CR16 VRS */
+		/* Tempax: CR16 VRS */
+		Tempax = pVBInfo->StandTable[StandTableIndex].CRTC[16];
 		Tempbx = Tempax; /* Tempbx=Tempax */
 		Tempax &= 0x01; /* Tempax: VRS[0] */
 		xgifb_reg_or(pVBInfo->P3c4, 0x33, Tempax); /* SR33[0]->VRS */
-		Tempax = pVBInfo->StandTable[StandTableIndex].CRTC[7]; /* Tempax: CR7 VRS */
+
+		/* Tempax: CR7 VRS */
+		Tempax = pVBInfo->StandTable[StandTableIndex].CRTC[7];
 		Tempdx = Tempbx >> 1; /* Tempdx: VRS[7:1] */
 		Tempcx = Tempax & 0x04; /* Tempcx: CR7[2] */
 		Tempcx <<= 5; /* Tempcx[7]: VRS[8] */
 		Tempdx |= Tempcx; /* Tempdx: VRS[8:1] */
-		xgifb_reg_set(pVBInfo->P3c4, 0x34, Tempdx); /* SR34[7:0]: VRS[8:1] */
+		/* SR34[7:0]: VRS[8:1] */
+		xgifb_reg_set(pVBInfo->P3c4, 0x34, Tempdx);
 
-		Temp1 = Tempcx << 1; /* Temp1[8]: VRS[8] unsigned char -> unsigned short */
+		/* Temp1[8]: VRS[8] unsigned char -> unsigned short */
+		Temp1 = Tempcx << 1;
 		Temp1 |= Tempbx; /* Temp1[8:0]: VRS[8:0] */
 		Tempax &= 0x80; /* Tempax[7]: CR7[7] */
 		Temp2 = Tempax << 2; /* Temp2[9]: VRS[9] */
 		Temp1 |= Temp2; /* Temp1[9:0]: VRS[9:0] */
 
-		Tempax = pVBInfo->StandTable[StandTableIndex].CRTC[17]; /* CR16 VRE */
+		/* CR16 VRE */
+		Tempax = pVBInfo->StandTable[StandTableIndex].CRTC[17];
 		Tempax &= 0x0F; /* Tempax[3:0]: VRE[3:0] */
 		Temp2 = Temp1 & 0x3F0; /* Temp2[9:4]: VRS[9:4] */
 		Temp2 |= Tempax; /* Temp2[9:0]: VRE[9:0] */
@@ -733,12 +768,15 @@
 		Tempbx = (unsigned char) Temp1; /* Tempbx[1:0]: VRS[10:9] */
 		Tempax |= Tempbx; /* VRE[5:0]VRS[10:9] */
 		Tempax &= 0x7F;
-		xgifb_reg_set(pVBInfo->P3c4, 0x3F, Tempax); /* SR3F D[7:2]->VRE D[1:0]->VRS */
+		/* SR3F D[7:2]->VRE D[1:0]->VRS */
+		xgifb_reg_set(pVBInfo->P3c4, 0x3F, Tempax);
 	} else {
 		index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
-		Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[3]; /* Tempax: CR4 HRS */
+		/* Tempax: CR4 HRS */
+		Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[3];
 		Tempcx = Tempax; /* Tempcx: HRS */
-		xgifb_reg_set(pVBInfo->P3c4, 0x2E, Tempax); /* SR2E[7:0]->HRS */
+		/* SR2E[7:0]->HRS */
+		xgifb_reg_set(pVBInfo->P3c4, 0x2E, Tempax);
 
 		Tempdx = pVBInfo->XGINEWUB_CRT1Table[index].CR[5]; /* SRB */
 		Tempdx &= 0xC0; /* Tempdx[7:6]: SRB[7:6] */
@@ -766,14 +804,17 @@
 		Tempax <<= 2; /* Tempax[7:2]: HRE[5:0] */
 		Tempdx >>= 6; /* Tempdx[7:6]->[1:0] HRS[9:8] */
 		Tempax |= Tempdx; /* HRE[5:0]HRS[9:8] */
-		xgifb_reg_set(pVBInfo->P3c4, 0x2F, Tempax); /* SR2F D[7:2]->HRE, D[1:0]->HRS */
+		/* SR2F D[7:2]->HRE, D[1:0]->HRS */
+		xgifb_reg_set(pVBInfo->P3c4, 0x2F, Tempax);
 		xgifb_reg_and_or(pVBInfo->P3c4, 0x30, 0xE3, 00);
 
-		Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[10]; /* CR10 VRS */
+		/* CR10 VRS */
+		Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[10];
 		Tempbx = Tempax; /* Tempbx: VRS */
 		Tempax &= 0x01; /* Tempax[0]: VRS[0] */
 		xgifb_reg_or(pVBInfo->P3c4, 0x33, Tempax); /* SR33[0]->VRS[0] */
-		Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[9]; /* CR7[2][7] VRE */
+		/* CR7[2][7] VRE */
+		Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[9];
 		Tempcx = Tempbx >> 1; /* Tempcx[6:0]: VRS[7:1] */
 		Tempdx = Tempax & 0x04; /* Tempdx[2]: CR7[2] */
 		Tempdx <<= 5; /* Tempdx[7]: VRS[8] */
@@ -786,15 +827,18 @@
 		Tempax &= 0x80;
 		Temp2 = Tempax << 2; /* Temp2[9]: VRS[9] */
 		Temp1 |= Temp2; /* Temp1[9:0]: VRS[9:0] */
-		Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[14]; /* Tempax: SRA */
+		/* Tempax: SRA */
+		Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[14];
 		Tempax &= 0x08; /* Tempax[3]: VRS[3] */
 		Temp2 = Tempax;
 		Temp2 <<= 7; /* Temp2[10]: VRS[10] */
 		Temp1 |= Temp2; /* Temp1[10:0]: VRS[10:0] */
 
-		Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[11]; /* Tempax: CR11 VRE */
+		/* Tempax: CR11 VRE */
+		Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[11];
 		Tempax &= 0x0F; /* Tempax[3:0]: VRE[3:0] */
-		Tempbx = pVBInfo->XGINEWUB_CRT1Table[index].CR[14]; /* Tempbx: SRA */
+		/* Tempbx: SRA */
+		Tempbx = pVBInfo->XGINEWUB_CRT1Table[index].CR[14];
 		Tempbx &= 0x20; /* Tempbx[5]: VRE[5] */
 		Tempbx >>= 1; /* Tempbx[4]: VRE[4] */
 		Tempax |= Tempbx; /* Tempax[4:0]: VRE[4:0] */
@@ -813,21 +857,26 @@
 		Tempbx = (unsigned char) Temp1;
 		Tempax |= Tempbx; /* Tempax[7:0]: VRE[5:0]VRS[10:9] */
 		Tempax &= 0x7F;
-		xgifb_reg_set(pVBInfo->P3c4, 0x3F, Tempax); /* SR3F D[7:2]->VRE D[1:0]->VRS */
+		/* SR3F D[7:2]->VRE D[1:0]->VRS */
+		xgifb_reg_set(pVBInfo->P3c4, 0x3F, Tempax);
 	}
 }
 
-static void XGI_SetXG27CRTC(unsigned short ModeNo, unsigned short ModeIdIndex,
-		unsigned short RefreshRateTableIndex,
-		struct vb_device_info *pVBInfo)
+static void XGI_SetXG27CRTC(unsigned short ModeNo,
+			    unsigned short ModeIdIndex,
+			    unsigned short RefreshRateTableIndex,
+			    struct vb_device_info *pVBInfo)
 {
 	unsigned short StandTableIndex, index, Tempax, Tempbx, Tempcx, Tempdx;
 
 	if (ModeNo <= 0x13) {
 		StandTableIndex = XGI_GetModePtr(ModeNo, ModeIdIndex, pVBInfo);
-		Tempax = pVBInfo->StandTable[StandTableIndex].CRTC[4]; /* CR04 HRS */
-		xgifb_reg_set(pVBInfo->P3c4, 0x2E, Tempax); /* SR2E [7:0]->HRS */
-		Tempbx = pVBInfo->StandTable[StandTableIndex].CRTC[5]; /* Tempbx: CR05 HRE */
+		/* CR04 HRS */
+		Tempax = pVBInfo->StandTable[StandTableIndex].CRTC[4];
+		/* SR2E [7:0]->HRS */
+		xgifb_reg_set(pVBInfo->P3c4, 0x2E, Tempax);
+		/* Tempbx: CR05 HRE */
+		Tempbx = pVBInfo->StandTable[StandTableIndex].CRTC[5];
 		Tempbx &= 0x1F; /* Tempbx: HRE[4:0] */
 		Tempcx = Tempax;
 		Tempcx &= 0xE0; /* Tempcx: HRS[7:5] */
@@ -835,39 +884,50 @@
 		if (Tempbx < (Tempax & 0x1F)) /* IF HRE < HRS */
 			Tempdx |= 0x20; /* Tempdx: HRE = HRE + 0x20 */
 		Tempdx <<= 2; /* Tempdx << 2 */
-		xgifb_reg_set(pVBInfo->P3c4, 0x2F, Tempdx); /* SR2F [7:2]->HRE */
+		/* SR2F [7:2]->HRE */
+		xgifb_reg_set(pVBInfo->P3c4, 0x2F, Tempdx);
 		xgifb_reg_and_or(pVBInfo->P3c4, 0x30, 0xE3, 00);
 
-		Tempax = pVBInfo->StandTable[StandTableIndex].CRTC[16]; /* Tempax: CR10 VRS */
+		/* Tempax: CR10 VRS */
+		Tempax = pVBInfo->StandTable[StandTableIndex].CRTC[16];
 		xgifb_reg_set(pVBInfo->P3c4, 0x34, Tempax); /* SR34[7:0]->VRS */
 		Tempcx = Tempax; /* Tempcx=Tempax=VRS[7:0] */
-		Tempax = pVBInfo->StandTable[StandTableIndex].CRTC[7]; /* Tempax[7][2]: CR7[7][2] VRS[9][8] */
+		/* Tempax[7][2]: CR7[7][2] VRS[9][8] */
+		Tempax = pVBInfo->StandTable[StandTableIndex].CRTC[7];
 		Tempbx = Tempax; /* Tempbx=CR07 */
 		Tempax &= 0x04; /* Tempax[2]: CR07[2] VRS[8] */
 		Tempax >>= 2;
-		xgifb_reg_and_or(pVBInfo->P3c4, 0x35, ~0x01, Tempax); /* SR35 D[0]->VRS D[8] */
+		/* SR35 D[0]->VRS D[8] */
+		xgifb_reg_and_or(pVBInfo->P3c4, 0x35, ~0x01, Tempax);
 		Tempcx |= (Tempax << 8); /* Tempcx[8] |= VRS[8] */
 		Tempcx |= (Tempbx & 0x80) << 2; /* Tempcx[9] |= VRS[9] */
 
-		Tempax = pVBInfo->StandTable[StandTableIndex].CRTC[17]; /* CR11 VRE */
+		/* CR11 VRE */
+		Tempax = pVBInfo->StandTable[StandTableIndex].CRTC[17];
 		Tempax &= 0x0F; /* Tempax: VRE[3:0] */
 		Tempbx = Tempcx; /* Tempbx=Tempcx=VRS[9:0] */
 		Tempbx &= 0x3F0; /* Tempbx[9:4]: VRS[9:4] */
 		Tempbx |= Tempax; /* Tempbx[9:0]: VRE[9:0] */
 		if (Tempax <= (Tempcx & 0x0F)) /* VRE[3:0]<=VRS[3:0] */
 			Tempbx |= 0x10; /* Tempbx: VRE + 0x10 */
-		Tempax = (unsigned char) Tempbx & 0xFF; /* Tempax[7:0]: VRE[7:0] */
+		/* Tempax[7:0]: VRE[7:0] */
+		Tempax = (unsigned char) Tempbx & 0xFF;
 		Tempax <<= 2; /* Tempax << 2: VRE[5:0] */
 		Tempcx = (Tempcx & 0x600) >> 8; /* Tempcx VRS[10:9] */
-		xgifb_reg_and_or(pVBInfo->P3c4, 0x3F, ~0xFC, Tempax); /* SR3F D[7:2]->VRE D[5:0] */
-		xgifb_reg_and_or(pVBInfo->P3c4, 0x35, ~0x06, Tempcx); /* SR35 D[2:1]->VRS[10:9] */
+		/* SR3F D[7:2]->VRE D[5:0] */
+		xgifb_reg_and_or(pVBInfo->P3c4, 0x3F, ~0xFC, Tempax);
+		/* SR35 D[2:1]->VRS[10:9] */
+		xgifb_reg_and_or(pVBInfo->P3c4, 0x35, ~0x06, Tempcx);
 	} else {
 		index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
-		Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[3]; /* Tempax: CR4 HRS */
+		/* Tempax: CR4 HRS */
+		Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[3];
 		Tempbx = Tempax; /* Tempbx: HRS[7:0] */
-		xgifb_reg_set(pVBInfo->P3c4, 0x2E, Tempax); /* SR2E[7:0]->HRS */
+		/* SR2E[7:0]->HRS */
+		xgifb_reg_set(pVBInfo->P3c4, 0x2E, Tempax);
 
-		Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[5]; /* SR0B */
+		/* SR0B */
+		Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[5];
 		Tempax &= 0xC0; /* Tempax[7:6]: SR0B[7:6]: HRS[9:8]*/
 		Tempbx |= (Tempax << 2); /* Tempbx: HRS[9:0] */
 
@@ -883,7 +943,8 @@
 		Tempbx = Tempbx & 0x3C0; /* Tempbx[9:6]: HRS[9:6] */
 		Tempbx |= Tempcx; /* Tempbx: HRS[9:6]HRE[5:0] */
 
-		Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[3]; /* Tempax: CR4 HRS */
+		/* Tempax: CR4 HRS */
+		Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[3];
 		Tempax &= 0x3F; /* Tempax: HRS[5:0] */
 		if (Tempcx <= Tempax) /* HRE[5:0] < HRS[5:0] */
 			Tempbx += 0x40; /* Tempbx= Tempbx + 0x40 : HRE[9:0]*/
@@ -892,27 +953,35 @@
 		Tempax &= 0xC0; /* Tempax[7:6]: SR0B[7:6]: HRS[9:8]*/
 		Tempax >>= 6; /* Tempax[1:0]: HRS[9:8]*/
 		Tempax |= ((Tempbx << 2) & 0xFF); /* Tempax[7:2]: HRE[5:0] */
-		xgifb_reg_set(pVBInfo->P3c4, 0x2F, Tempax); /* SR2F [7:2][1:0]: HRE[5:0]HRS[9:8] */
+		/* SR2F [7:2][1:0]: HRE[5:0]HRS[9:8] */
+		xgifb_reg_set(pVBInfo->P3c4, 0x2F, Tempax);
 		xgifb_reg_and_or(pVBInfo->P3c4, 0x30, 0xE3, 00);
 
-		Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[10]; /* CR10 VRS */
-		xgifb_reg_set(pVBInfo->P3c4, 0x34, Tempax); /* SR34[7:0]->VRS[7:0] */
+		/* CR10 VRS */
+		Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[10];
+		/* SR34[7:0]->VRS[7:0] */
+		xgifb_reg_set(pVBInfo->P3c4, 0x34, Tempax);
 
 		Tempcx = Tempax; /* Tempcx <= VRS[7:0] */
-		Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[9]; /* CR7[7][2] VRS[9][8] */
+		/* CR7[7][2] VRS[9][8] */
+		Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[9];
 		Tempbx = Tempax; /* Tempbx <= CR07[7:0] */
 		Tempax = Tempax & 0x04; /* Tempax[2]: CR7[2]: VRS[8] */
 		Tempax >>= 2; /* Tempax[0]: VRS[8] */
-		xgifb_reg_and_or(pVBInfo->P3c4, 0x35, ~0x01, Tempax); /* SR35[0]: VRS[8] */
+		/* SR35[0]: VRS[8] */
+		xgifb_reg_and_or(pVBInfo->P3c4, 0x35, ~0x01, Tempax);
 		Tempcx |= (Tempax << 8); /* Tempcx <= VRS[8:0] */
 		Tempcx |= ((Tempbx & 0x80) << 2); /* Tempcx <= VRS[9:0] */
-		Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[14]; /* Tempax: SR0A */
+		/* Tempax: SR0A */
+		Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[14];
 		Tempax &= 0x08; /* SR0A[3] VRS[10] */
 		Tempcx |= (Tempax << 7); /* Tempcx <= VRS[10:0] */
 
-		Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[11]; /* Tempax: CR11 VRE */
+		/* Tempax: CR11 VRE */
+		Tempax = pVBInfo->XGINEWUB_CRT1Table[index].CR[11];
 		Tempax &= 0x0F; /* Tempax[3:0]: VRE[3:0] */
-		Tempbx = pVBInfo->XGINEWUB_CRT1Table[index].CR[14]; /* Tempbx: SR0A */
+		/* Tempbx: SR0A */
+		Tempbx = pVBInfo->XGINEWUB_CRT1Table[index].CR[14];
 		Tempbx &= 0x20; /* Tempbx[5]: SR0A[5]: VRE[4] */
 		Tempbx >>= 1; /* Tempbx[4]: VRE[4] */
 		Tempax |= Tempbx; /* Tempax[4:0]: VRE[4:0] */
@@ -923,10 +992,13 @@
 		if (Tempbx <= Tempcx) /* VRE <= VRS */
 			Tempbx |= 0x20; /* VRE + 0x20 */
 
-		Tempax = (Tempbx << 2) & 0xFF; /* Tempax: Tempax[7:0]; VRE[5:0]00 */
-		xgifb_reg_and_or(pVBInfo->P3c4, 0x3F, ~0xFC, Tempax); /* SR3F[7:2]:VRE[5:0] */
+		/* Tempax: Tempax[7:0]; VRE[5:0]00 */
+		Tempax = (Tempbx << 2) & 0xFF;
+		/* SR3F[7:2]:VRE[5:0] */
+		xgifb_reg_and_or(pVBInfo->P3c4, 0x3F, ~0xFC, Tempax);
 		Tempax = Tempcx >> 8;
-		xgifb_reg_and_or(pVBInfo->P3c4, 0x35, ~0x07, Tempax); /* SR35[2:0]:VRS[10:8] */
+		/* SR35[2:0]:VRS[10:8] */
+		xgifb_reg_and_or(pVBInfo->P3c4, 0x35, ~0x07, Tempax);
 	}
 }
 
@@ -970,20 +1042,25 @@
 	if (ModeNo <= 0x13) {
 		b3CC = (unsigned char) inb(XGI_P3cc);
 		if (b3CC & 0x40)
-			xgifb_reg_or(pVBInfo->P3c4, 0x30, 0x20); /* Hsync polarity */
+			/* Hsync polarity */
+			xgifb_reg_or(pVBInfo->P3c4, 0x30, 0x20);
 		if (b3CC & 0x80)
-			xgifb_reg_or(pVBInfo->P3c4, 0x35, 0x80); /* Vsync polarity */
+			/* Vsync polarity */
+			xgifb_reg_or(pVBInfo->P3c4, 0x35, 0x80);
 	} else {
 		Data = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
 		if (Data & 0x4000)
-			xgifb_reg_or(pVBInfo->P3c4, 0x30, 0x20); /* Hsync polarity */
+			/* Hsync polarity */
+			xgifb_reg_or(pVBInfo->P3c4, 0x30, 0x20);
 		if (Data & 0x8000)
-			xgifb_reg_or(pVBInfo->P3c4, 0x35, 0x80); /* Vsync polarity */
+			/* Vsync polarity */
+			xgifb_reg_or(pVBInfo->P3c4, 0x35, 0x80);
 	}
 }
 
 static void XGI_SetXG27LCD(struct vb_device_info *pVBInfo,
-		unsigned short RefreshRateTableIndex, unsigned short ModeNo)
+			   unsigned short RefreshRateTableIndex,
+			   unsigned short ModeNo)
 {
 	unsigned short Data, Temp, b3CC;
 	unsigned short XGI_P3cc;
@@ -1018,15 +1095,19 @@
 	if (ModeNo <= 0x13) {
 		b3CC = (unsigned char) inb(XGI_P3cc);
 		if (b3CC & 0x40)
-			xgifb_reg_or(pVBInfo->P3c4, 0x30, 0x20); /* Hsync polarity */
+			/* Hsync polarity */
+			xgifb_reg_or(pVBInfo->P3c4, 0x30, 0x20);
 		if (b3CC & 0x80)
-			xgifb_reg_or(pVBInfo->P3c4, 0x35, 0x80); /* Vsync polarity */
+			/* Vsync polarity */
+			xgifb_reg_or(pVBInfo->P3c4, 0x35, 0x80);
 	} else {
 		Data = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
 		if (Data & 0x4000)
-			xgifb_reg_or(pVBInfo->P3c4, 0x30, 0x20); /* Hsync polarity */
+			/* Hsync polarity */
+			xgifb_reg_or(pVBInfo->P3c4, 0x30, 0x20);
 		if (Data & 0x8000)
-			xgifb_reg_or(pVBInfo->P3c4, 0x35, 0x80); /* Vsync polarity */
+			/* Vsync polarity */
+			xgifb_reg_or(pVBInfo->P3c4, 0x35, 0x80);
 	}
 }
 
@@ -1036,8 +1117,9 @@
 /* Output : CRT1 CRTC */
 /* Description : Modify CRT1 Hsync/Vsync to fix LCD mode timing */
 /* --------------------------------------------------------------------- */
-static void XGI_UpdateXG21CRTC(unsigned short ModeNo, struct vb_device_info *pVBInfo,
-		unsigned short RefreshRateTableIndex)
+static void XGI_UpdateXG21CRTC(unsigned short ModeNo,
+			       struct vb_device_info *pVBInfo,
+			       unsigned short RefreshRateTableIndex)
 {
 	int i, index = -1;
 
@@ -1048,13 +1130,13 @@
 				index = i;
 		}
 	} else {
-		if (ModeNo == 0x2E
-				&& (pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC
-						== RES640x480x60))
+		if (ModeNo == 0x2E &&
+		    (pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC ==
+							      RES640x480x60))
 			index = 12;
-		else if (ModeNo == 0x2E
-				&& (pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC
-						== RES640x480x72))
+		else if (ModeNo == 0x2E &&
+			 (pVBInfo->RefIndex[RefreshRateTableIndex].
+				Ext_CRT1CRTC == RES640x480x72))
 			index = 13;
 		else if (ModeNo == 0x2F)
 			index = 14;
@@ -1157,16 +1239,19 @@
 	unsigned short resindex;
 
 	if (ModeNo <= 0x13)
-		resindex = pVBInfo->SModeIDTable[ModeIdIndex].St_ResInfo; /* si+St_ResInfo */
+		/* si+St_ResInfo */
+		resindex = pVBInfo->SModeIDTable[ModeIdIndex].St_ResInfo;
 	else
-		resindex = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO; /* si+Ext_ResInfo */
+		/* si+Ext_ResInfo */
+		resindex = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO;
 	return resindex;
 }
 
-static void XGI_SetCRT1Offset(unsigned short ModeNo, unsigned short ModeIdIndex,
-		unsigned short RefreshRateTableIndex,
-		struct xgi_hw_device_info *HwDeviceExtension,
-		struct vb_device_info *pVBInfo)
+static void XGI_SetCRT1Offset(unsigned short ModeNo,
+			      unsigned short ModeIdIndex,
+			      unsigned short RefreshRateTableIndex,
+			      struct xgi_hw_device_info *HwDeviceExtension,
+			      struct vb_device_info *pVBInfo)
 {
 	unsigned short temp, ah, al, temp2, i, DisplayUnit;
 
@@ -1254,29 +1339,39 @@
 {
 	unsigned short tempbx;
 
-	unsigned short LCDXlat1VCLK[4] = { VCLK65 + 2, VCLK65 + 2, VCLK65 + 2,
-			VCLK65 + 2 };
-	unsigned short LCDXlat2VCLK[4] = { VCLK108_2 + 5, VCLK108_2 + 5,
-			VCLK108_2 + 5, VCLK108_2 + 5 };
+	unsigned short LCDXlat1VCLK[4] = { VCLK65 + 2,
+					   VCLK65 + 2,
+					   VCLK65 + 2,
+					   VCLK65 + 2 };
+	unsigned short LCDXlat2VCLK[4] = { VCLK108_2 + 5,
+					   VCLK108_2 + 5,
+					   VCLK108_2 + 5,
+					   VCLK108_2 + 5 };
 	unsigned short LVDSXlat1VCLK[4] = { VCLK40, VCLK40, VCLK40, VCLK40 };
-	unsigned short LVDSXlat2VCLK[4] = { VCLK65 + 2, VCLK65 + 2, VCLK65 + 2,
-			VCLK65 + 2 };
-	unsigned short LVDSXlat3VCLK[4] = { VCLK65 + 2, VCLK65 + 2, VCLK65 + 2,
-			VCLK65 + 2 };
+	unsigned short LVDSXlat2VCLK[4] = { VCLK65 + 2,
+					    VCLK65 + 2,
+					    VCLK65 + 2,
+					    VCLK65 + 2 };
+	unsigned short LVDSXlat3VCLK[4] = { VCLK65 + 2,
+					    VCLK65 + 2,
+					    VCLK65 + 2,
+					    VCLK65 + 2 };
 
 	unsigned short CRT2Index, VCLKIndex;
 	unsigned short modeflag, resinfo;
 	unsigned char *CHTVVCLKPtr = NULL;
 
 	if (ModeNo <= 0x13) {
-		modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; /* si+St_ResInfo */
+		/* si+St_ResInfo */
+		modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag;
 		resinfo = pVBInfo->SModeIDTable[ModeIdIndex].St_ResInfo;
 		CRT2Index = pVBInfo->SModeIDTable[ModeIdIndex].St_CRT2CRTC;
 	} else {
-		modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; /* si+Ext_ResInfo */
+		/* si+Ext_ResInfo */
+		modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
 		resinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO;
-		CRT2Index
-				= pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
+		CRT2Index = pVBInfo->RefIndex[RefreshRateTableIndex].
+				Ext_CRT2CRTC;
 	}
 
 	if (pVBInfo->IF_DEF_LVDS == 0) {
@@ -1291,41 +1386,35 @@
 				if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) {
 					if (pVBInfo->SetFlag & RPLLDIV2XO) {
 						VCLKIndex = HiTVVCLKDIV2;
-
 						VCLKIndex += 25;
-
 					} else {
 						VCLKIndex = HiTVVCLK;
-
 						VCLKIndex += 25;
-
 					}
 
 					if (pVBInfo->SetFlag & TVSimuMode) {
 						if (modeflag & Charx8Dot) {
-							VCLKIndex
-									= HiTVSimuVCLK;
-
+							VCLKIndex =
+								HiTVSimuVCLK;
 							VCLKIndex += 25;
-
 						} else {
-							VCLKIndex
-									= HiTVTextVCLK;
-
+							VCLKIndex =
+								HiTVTextVCLK;
 							VCLKIndex += 25;
-
 						}
 					}
 
-					if (pVBInfo->VBType & VB_XGI301LV) { /* 301lv */
-						if (!(pVBInfo->VBExtInfo
-								== VB_YPbPr1080i)) {
-							VCLKIndex
-									= YPbPr750pVCLK;
+					/* 301lv */
+					if (pVBInfo->VBType & VB_XGI301LV) {
+						if (!(pVBInfo->VBExtInfo ==
+						     VB_YPbPr1080i)) {
+							VCLKIndex =
+								YPbPr750pVCLK;
 							if (!(pVBInfo->VBExtInfo
-									== VB_YPbPr750p)) {
-								VCLKIndex
-										= YPbPr525pVCLK;
+									==
+							     VB_YPbPr750p)) {
+								VCLKIndex =
+								  YPbPr525pVCLK;
 								if (!(pVBInfo->VBExtInfo
 										== VB_YPbPr525p)) {
 									VCLKIndex
@@ -1340,27 +1429,27 @@
 					}
 				} else {
 					if (pVBInfo->VBInfo & SetCRT2ToTV) {
-						if (pVBInfo->SetFlag
-								& RPLLDIV2XO) {
+						if (pVBInfo->SetFlag &
+						    RPLLDIV2XO) {
 							VCLKIndex = TVVCLKDIV2;
-
 							VCLKIndex += 25;
-
 						} else {
 							VCLKIndex = TVVCLK;
-
 							VCLKIndex += 25;
-
 						}
 					}
 				}
 			} else { /* for CRT2 */
+				/* Port 3cch */
 				VCLKIndex = (unsigned char) inb(
-						(pVBInfo->P3ca + 0x02)); /* Port 3cch */
+						(pVBInfo->P3ca + 0x02));
 				VCLKIndex = ((VCLKIndex >> 2) & 0x03);
 				if (ModeNo > 0x13) {
-					VCLKIndex
-							= pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRTVCLK; /* di+Ext_CRTVCLK */
+					/* di+Ext_CRTVCLK */
+					VCLKIndex =
+						pVBInfo->RefIndex[
+							RefreshRateTableIndex].
+								Ext_CRTVCLK;
 					VCLKIndex &= IndexMask;
 				}
 			}
@@ -1403,12 +1492,11 @@
 			}
 		} else {
 			VCLKIndex = VCLKIndex >> 6;
-			if ((pVBInfo->LCDResInfo == Panel800x600)
-					|| (pVBInfo->LCDResInfo == Panel320x480))
+			if ((pVBInfo->LCDResInfo == Panel800x600) ||
+			    (pVBInfo->LCDResInfo == Panel320x480))
 				VCLKIndex = LVDSXlat1VCLK[VCLKIndex];
-			else if ((pVBInfo->LCDResInfo == Panel1024x768)
-					|| (pVBInfo->LCDResInfo
-							== Panel1024x768x75))
+			else if ((pVBInfo->LCDResInfo == Panel1024x768) ||
+				 (pVBInfo->LCDResInfo == Panel1024x768x75))
 				VCLKIndex = LVDSXlat2VCLK[VCLKIndex];
 			else
 				VCLKIndex = LVDSXlat3VCLK[VCLKIndex];
@@ -1419,10 +1507,11 @@
 	return VCLKIndex;
 }
 
-static void XGI_SetCRT1VCLK(unsigned short ModeNo, unsigned short ModeIdIndex,
-		struct xgi_hw_device_info *HwDeviceExtension,
-		unsigned short RefreshRateTableIndex,
-		struct vb_device_info *pVBInfo)
+static void XGI_SetCRT1VCLK(unsigned short ModeNo,
+			    unsigned short ModeIdIndex,
+			    struct xgi_hw_device_info *HwDeviceExtension,
+			    unsigned short RefreshRateTableIndex,
+			    struct vb_device_info *pVBInfo)
 {
 	unsigned char index, data;
 	unsigned short vclkindex;
@@ -1461,7 +1550,8 @@
 	}
 
 	if (HwDeviceExtension->jChipType >= XG20) {
-		if (pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag & HalfDCLK) {
+		if (pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag &
+		    HalfDCLK) {
 			data = xgifb_reg_get(pVBInfo->P3c4, 0x2B);
 			xgifb_reg_set(pVBInfo->P3c4, 0x2B, data);
 			data = xgifb_reg_get(pVBInfo->P3c4, 0x2C);
@@ -1575,10 +1665,11 @@
 
 	if (ModeNo > 0x13) {
 		modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
-		infoflag
-				= pVBInfo->RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
+		infoflag = pVBInfo->RefIndex[RefreshRateTableIndex].
+				Ext_InfoFlag;
 	} else
-		modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; /* si+St_ModeFlag */
+		/* si+St_ModeFlag */
+		modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag;
 
 	if (xgifb_reg_get(pVBInfo->P3d4, 0x31) & 0x01)
 		xgifb_reg_and_or(pVBInfo->P3c4, 0x1F, 0x3F, 0x00);
@@ -1652,7 +1743,8 @@
 
 	/* if (modeflag&HalfDCLK) //030305 fix lowresolution bug */
 	/* if (XGINew_IF_DEF_NEW_LOWRES) */
-	/* XGI_VesaLowResolution(ModeNo, ModeIdIndex); //030305 fix lowresolution bug */
+	/* XGI_VesaLowResolution(ModeNo, ModeIdIndex);
+	 * //030305 fix lowresolution bug */
 
 	data = xgifb_reg_get(pVBInfo->P3d4, 0x31);
 
@@ -1681,7 +1773,9 @@
 }
 
 /*
-void XGI_VesaLowResolution(unsigned short ModeNo, unsigned short ModeIdIndex, struct vb_device_info *pVBInfo)
+void XGI_VesaLowResolution(unsigned short ModeNo,
+			   unsigned short ModeIdIndex,
+			   struct vb_device_info *pVBInfo)
 {
 	unsigned short modeflag;
 
@@ -1693,17 +1787,37 @@
 	if (ModeNo > 0x13) {
 		if (modeflag & DoubleScanMode) {
 			if (modeflag & HalfDCLK) {
-				if (pVBInfo->VBType & VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV | VB_XGI301C)) {
-					if (!(pVBInfo->VBInfo & SetCRT2ToRAMDAC)) {
-						if (pVBInfo->VBInfo & SetInSlaveMode) {
-							xgifb_reg_and_or(pVBInfo->P3c4, 0x01, 0xf7, 0x00);
-							xgifb_reg_and_or(pVBInfo->P3c4, 0x0f, 0x7f, 0x00);
+				if (pVBInfo->VBType & VB_XGI301B |
+						      VB_XGI302B |
+						      VB_XGI301LV |
+						      VB_XGI302LV |
+						      VB_XGI301C)) {
+					if (!(pVBInfo->VBInfo &
+					     SetCRT2ToRAMDAC)) {
+						if (pVBInfo->VBInfo &
+						    SetInSlaveMode) {
+							xgifb_reg_and_or(
+								pVBInfo->P3c4,
+								0x01,
+								0xf7,
+								0x00);
+							xgifb_reg_and_or(
+								pVBInfo->P3c4,
+								0x0f,
+								0x7f,
+								0x00);
 							return;
 						}
 					}
 				}
-				xgifb_reg_and_or(pVBInfo->P3c4, 0x0f, 0xff, 0x80);
-				xgifb_reg_and_or(pVBInfo->P3c4, 0x01, 0xf7, 0x00);
+				xgifb_reg_and_or(pVBInfo->P3c4,
+						 0x0f,
+						 0xff,
+						 0x80);
+				xgifb_reg_and_or(pVBInfo->P3c4,
+						 0x01,
+						 0xf7,
+						 0x00);
 				return;
 			}
 		}
@@ -1712,8 +1826,11 @@
 }
 */
 
-static void XGI_WriteDAC(unsigned short dl, unsigned short ah, unsigned short al,
-		unsigned short dh, struct vb_device_info *pVBInfo)
+static void XGI_WriteDAC(unsigned short dl,
+			 unsigned short ah,
+			 unsigned short al,
+			 unsigned short dh,
+			 struct vb_device_info *pVBInfo)
 {
 	unsigned short temp, bh, bl;
 
@@ -1831,15 +1948,18 @@
 	}
 }
 
-static void XGI_GetLVDSResInfo(unsigned short ModeNo, unsigned short ModeIdIndex,
-		struct vb_device_info *pVBInfo)
+static void XGI_GetLVDSResInfo(unsigned short ModeNo,
+			       unsigned short ModeIdIndex,
+			       struct vb_device_info *pVBInfo)
 {
 	unsigned short resindex, xres, yres, modeflag;
 
 	if (ModeNo <= 0x13)
-		modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ResInfo; /* si+St_ResInfo */
+		/* si+St_ResInfo */
+		modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ResInfo;
 	else
-		modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO; /* si+Ext_ResInfo */
+		/* si+Ext_ResInfo */
+		modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO;
 
 	/* if (ModeNo > 0x13) */
 	/*	modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; */
@@ -1847,9 +1967,11 @@
 	/*	modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; */
 
 	if (ModeNo <= 0x13)
-		resindex = pVBInfo->SModeIDTable[ModeIdIndex].St_ResInfo; /* si+St_ResInfo */
+		/* si+St_ResInfo */
+		resindex = pVBInfo->SModeIDTable[ModeIdIndex].St_ResInfo;
 	else
-		resindex = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO; /* si+Ext_ResInfo */
+		/* si+Ext_ResInfo */
+		resindex = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO;
 
 	/* resindex = XGI_GetResInfo(ModeNo, ModeIdIndex, pVBInfo); */
 
@@ -1903,19 +2025,21 @@
 
 	if (tempbx <= 1) { /* ExpLink */
 		if (ModeNo <= 0x13) {
-			tempal = pVBInfo->SModeIDTable[ModeIdIndex].St_CRT2CRTC; /* find no Ext_CRT2CRTC2 */
+			/* find no Ext_CRT2CRTC2 */
+			tempal = pVBInfo->SModeIDTable[ModeIdIndex].St_CRT2CRTC;
 		} else {
-			tempal
-					= pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
+			tempal = pVBInfo->RefIndex[RefreshRateTableIndex].
+					Ext_CRT2CRTC;
 		}
 
 		if (pVBInfo->VBInfo & SetCRT2ToLCDA) {
 			if (ModeNo <= 0x13)
-				tempal
-						= pVBInfo->SModeIDTable[ModeIdIndex].St_CRT2CRTC2;
+				tempal = pVBInfo->SModeIDTable[ModeIdIndex].
+						St_CRT2CRTC2;
 			else
-				tempal
-						= pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC2;
+				tempal = pVBInfo->RefIndex[
+						RefreshRateTableIndex].
+							Ext_CRT2CRTC2;
 		}
 
 		if (tempbx & 0x01)
@@ -1933,7 +2057,8 @@
 			tempcx = LVDSDesDataLen2;
 	}
 	/* mov di, word ptr cs:LCDDataList[bx] */
-	/* tempdi = pVideoMemory[LCDDataList + tempbx * 2] | (pVideoMemory[LCDDataList + tempbx * 2 + 1] << 8); */
+	/* tempdi = pVideoMemory[LCDDataList + tempbx * 2] |
+		    (pVideoMemory[LCDDataList + tempbx * 2 + 1] << 8); */
 
 	switch (tempbx) {
 	case 0:
@@ -2243,36 +2368,36 @@
 			return &XGI_CetLCDDes1024x768Data[tempal];
 			break;
 		case 3:
-			if ((pVBInfo->VBType & VB_XGI301LV) || (pVBInfo->VBType
-					& VB_XGI302LV))
+			if ((pVBInfo->VBType & VB_XGI301LV) ||
+				(pVBInfo->VBType & VB_XGI302LV))
 				return &XGI_ExtLCDDLDes1280x1024Data[tempal];
 			else
 				return &XGI_ExtLCDDes1280x1024Data[tempal];
 			break;
 		case 4:
-			if ((pVBInfo->VBType & VB_XGI301LV) || (pVBInfo->VBType
-					& VB_XGI302LV))
+			if ((pVBInfo->VBType & VB_XGI301LV) ||
+			    (pVBInfo->VBType & VB_XGI302LV))
 				return &XGI_StLCDDLDes1280x1024Data[tempal];
 			else
 				return &XGI_StLCDDes1280x1024Data[tempal];
 			break;
 		case 5:
-			if ((pVBInfo->VBType & VB_XGI301LV) || (pVBInfo->VBType
-					& VB_XGI302LV))
+			if ((pVBInfo->VBType & VB_XGI301LV) ||
+			    (pVBInfo->VBType & VB_XGI302LV))
 				return &XGI_CetLCDDLDes1280x1024Data[tempal];
 			else
 				return &XGI_CetLCDDes1280x1024Data[tempal];
 			break;
 		case 6:
-			if ((pVBInfo->VBType & VB_XGI301LV) || (pVBInfo->VBType
-					& VB_XGI302LV))
+			if ((pVBInfo->VBType & VB_XGI301LV) ||
+			    (pVBInfo->VBType & VB_XGI302LV))
 				return &XGI_ExtLCDDLDes1400x1050Data[tempal];
 			else
 				return &XGI_ExtLCDDes1400x1050Data[tempal];
 			break;
 		case 7:
-			if ((pVBInfo->VBType & VB_XGI301LV) || (pVBInfo->VBType
-					& VB_XGI302LV))
+			if ((pVBInfo->VBType & VB_XGI301LV) ||
+			    (pVBInfo->VBType & VB_XGI302LV))
 				return &XGI_StLCDDLDes1400x1050Data[tempal];
 			else
 				return &XGI_StLCDDes1400x1050Data[tempal];
@@ -2284,15 +2409,15 @@
 			return &XGI_CetLCDDes1400x1050Data2[tempal];
 			break;
 		case 10:
-			if ((pVBInfo->VBType & VB_XGI301LV) || (pVBInfo->VBType
-					& VB_XGI302LV))
+			if ((pVBInfo->VBType & VB_XGI301LV) ||
+			    (pVBInfo->VBType & VB_XGI302LV))
 				return &XGI_ExtLCDDLDes1600x1200Data[tempal];
 			else
 				return &XGI_ExtLCDDes1600x1200Data[tempal];
 			break;
 		case 11:
-			if ((pVBInfo->VBType & VB_XGI301LV) || (pVBInfo->VBType
-					& VB_XGI302LV))
+			if ((pVBInfo->VBType & VB_XGI301LV) ||
+			    (pVBInfo->VBType & VB_XGI302LV))
 				return &XGI_StLCDDLDes1600x1200Data[tempal];
 			else
 				return &XGI_StLCDDes1600x1200Data[tempal];
@@ -2310,22 +2435,22 @@
 			return &XGI_CetLCDDes1024x768x75Data[tempal];
 			break;
 		case 16:
-			if ((pVBInfo->VBType & VB_XGI301LV) || (pVBInfo->VBType
-					& VB_XGI302LV))
+			if ((pVBInfo->VBType & VB_XGI301LV) ||
+			    (pVBInfo->VBType & VB_XGI302LV))
 				return &XGI_ExtLCDDLDes1280x1024x75Data[tempal];
 			else
 				return &XGI_ExtLCDDes1280x1024x75Data[tempal];
 			break;
 		case 17:
-			if ((pVBInfo->VBType & VB_XGI301LV) || (pVBInfo->VBType
-					& VB_XGI302LV))
+			if ((pVBInfo->VBType & VB_XGI301LV) ||
+			    (pVBInfo->VBType & VB_XGI302LV))
 				return &XGI_StLCDDLDes1280x1024x75Data[tempal];
 			else
 				return &XGI_StLCDDes1280x1024x75Data[tempal];
 			break;
 		case 18:
-			if ((pVBInfo->VBType & VB_XGI301LV) || (pVBInfo->VBType
-					& VB_XGI302LV))
+			if ((pVBInfo->VBType & VB_XGI301LV) ||
+			    (pVBInfo->VBType & VB_XGI302LV))
 				return &XGI_CetLCDDLDes1280x1024x75Data[tempal];
 			else
 				return &XGI_CetLCDDes1280x1024x75Data[tempal];
@@ -2423,7 +2548,8 @@
 		i++;
 	}
 
-	if (table == 0x00) { /* 07/05/22 */
+	/* 07/05/22 */
+	if (table == 0x00) {
 	} else if (table == 0x01) {
 	} else if (table == 0x04) {
 		switch (tempdi[i].DATAPTR) {
@@ -2528,14 +2654,12 @@
 	if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
 		if (!(pVBInfo->LCDInfo & (SetLCDtoNonExpanding
 				| EnableScalingLCD))) {
-			if ((pVBInfo->LCDResInfo == Panel1024x768)
-					|| (pVBInfo->LCDResInfo
-							== Panel1024x768x75)) {
+			if ((pVBInfo->LCDResInfo == Panel1024x768) ||
+			    (pVBInfo->LCDResInfo == Panel1024x768x75)) {
 				pVBInfo->HDE = 1024;
 				pVBInfo->VDE = 768;
-			} else if ((pVBInfo->LCDResInfo == Panel1280x1024)
-					|| (pVBInfo->LCDResInfo
-							== Panel1280x1024x75)) {
+			} else if ((pVBInfo->LCDResInfo == Panel1280x1024) ||
+				   (pVBInfo->LCDResInfo == Panel1280x1024x75)) {
 				pVBInfo->HDE = 1280;
 				pVBInfo->VDE = 1024;
 			} else if (pVBInfo->LCDResInfo == Panel1400x1050) {
@@ -2569,17 +2693,17 @@
 
 	index = index & IndexMask;
 
-	if ((pVBInfo->IF_DEF_ScaleLCD == 0) || ((pVBInfo->IF_DEF_ScaleLCD == 1)
-			&& (!(pVBInfo->LCDInfo & EnableScalingLCD)))) {
+	if ((pVBInfo->IF_DEF_ScaleLCD == 0) ||
+	    ((pVBInfo->IF_DEF_ScaleLCD == 1) &&
+	    (!(pVBInfo->LCDInfo & EnableScalingLCD)))) {
 		tempbx = 0;
 
 		if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
-			LCDPtr
-					= (struct XGI_LVDSCRT1HDataStruct *) XGI_GetLcdPtr(
-							tempbx, ModeNo,
-							ModeIdIndex,
-							RefreshRateTableIndex,
-							pVBInfo);
+			LCDPtr = (struct XGI_LVDSCRT1HDataStruct *)
+					XGI_GetLcdPtr(tempbx, ModeNo,
+						      ModeIdIndex,
+						      RefreshRateTableIndex,
+						      pVBInfo);
 
 			for (i = 0; i < 8; i++)
 				pVBInfo->TimingH[0].data[i] = LCDPtr[0].Reg[i];
@@ -2587,23 +2711,30 @@
 
 		if (pVBInfo->IF_DEF_CH7007 == 1) {
 			if (pVBInfo->VBInfo & SetCRT2ToTV) {
-				CH7007TV_TimingHPtr
-						= (struct XGI_CH7007TV_TimingHStruct *) XGI_GetTVPtr(
-								tempbx,
-								ModeNo,
-								ModeIdIndex,
-								RefreshRateTableIndex,
-								pVBInfo);
+				CH7007TV_TimingHPtr =
+					(struct XGI_CH7007TV_TimingHStruct *)
+						XGI_GetTVPtr(
+							tempbx,
+							ModeNo,
+							ModeIdIndex,
+							RefreshRateTableIndex,
+							pVBInfo);
 
 				for (i = 0; i < 8; i++)
-					pVBInfo->TimingH[0].data[i]
-							= CH7007TV_TimingHPtr[0].data[i];
+					pVBInfo->TimingH[0].data[i] =
+						CH7007TV_TimingHPtr[0].data[i];
 			}
 		}
 
 		/* if (pVBInfo->IF_DEF_CH7017 == 1) {
 			if (pVBInfo->VBInfo & SetCRT2ToTV)
-				TVPtr = (struct XGI330_CHTVDataStruct *)XGI_GetTVPtr(tempbx, ModeNo, ModeIdIndex, RefreshRateTableIndex, pVBInfo);
+				TVPtr = (struct XGI330_CHTVDataStruct *)
+						XGI_GetTVPtr(
+							tempbx,
+							ModeNo,
+							ModeIdIndex,
+							RefreshRateTableIndex,
+							pVBInfo);
 		}
 		*/
 
@@ -2619,34 +2750,41 @@
 		tempbx = 1;
 
 		if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
-			LCDPtr1
-					= (struct XGI_LVDSCRT1VDataStruct *) XGI_GetLcdPtr(
-							tempbx, ModeNo,
-							ModeIdIndex,
-							RefreshRateTableIndex,
-							pVBInfo);
+			LCDPtr1 = (struct XGI_LVDSCRT1VDataStruct *)
+					XGI_GetLcdPtr(
+						tempbx,
+						ModeNo,
+						ModeIdIndex,
+						RefreshRateTableIndex,
+						pVBInfo);
 			for (i = 0; i < 7; i++)
 				pVBInfo->TimingV[0].data[i] = LCDPtr1[0].Reg[i];
 		}
 
 		if (pVBInfo->IF_DEF_CH7007 == 1) {
 			if (pVBInfo->VBInfo & SetCRT2ToTV) {
-				CH7007TV_TimingVPtr
-						= (struct XGI_CH7007TV_TimingVStruct *) XGI_GetTVPtr(
-								tempbx,
-								ModeNo,
-								ModeIdIndex,
-								RefreshRateTableIndex,
-								pVBInfo);
+				CH7007TV_TimingVPtr =
+					(struct XGI_CH7007TV_TimingVStruct *)
+						XGI_GetTVPtr(
+							tempbx,
+							ModeNo,
+							ModeIdIndex,
+							RefreshRateTableIndex,
+							pVBInfo);
 
 				for (i = 0; i < 7; i++)
-					pVBInfo->TimingV[0].data[i]
-							= CH7007TV_TimingVPtr[0].data[i];
+					pVBInfo->TimingV[0].data[i] =
+						CH7007TV_TimingVPtr[0].data[i];
 			}
 		}
 		/* if (pVBInfo->IF_DEF_CH7017 == 1) {
 			if (pVBInfo->VBInfo & SetCRT2ToTV)
-				TVPtr = (struct XGI330_CHTVDataStruct *)XGI_GetTVPtr(tempbx, ModeNo, ModeIdIndex, RefreshRateTableIndex, pVBInfo);
+				TVPtr = (struct XGI330_CHTVDataStruct *)
+					XGI_GetTVPtr(tempbx,
+						     ModeNo,
+						     ModeIdIndex,
+						     RefreshRateTableIndex,
+						     pVBInfo);
 		}
 		*/
 
@@ -2723,8 +2861,9 @@
 	return i;
 }
 
-static void XGI_GetLCDSync(unsigned short *HSyncWidth, unsigned short *VSyncWidth,
-		struct vb_device_info *pVBInfo)
+static void XGI_GetLCDSync(unsigned short *HSyncWidth,
+			   unsigned short *VSyncWidth,
+			   struct vb_device_info *pVBInfo)
 {
 	unsigned short Index;
 
@@ -2754,33 +2893,35 @@
 				& (SetCRT2ToLCD | SetCRT2ToLCDA))) {
 			if (pVBInfo->IF_DEF_OEMUtil == 1) {
 				tempbx = 8;
-				LCDPtr
-						= (struct XGI330_LCDDataDesStruct *) XGI_GetLcdPtr(
-								tempbx,
-								ModeNo,
-								ModeIdIndex,
-								RefreshRateTableIndex,
-								pVBInfo);
+				LCDPtr = (struct XGI330_LCDDataDesStruct *)
+					XGI_GetLcdPtr(tempbx,
+						      ModeNo,
+						      ModeIdIndex,
+						      RefreshRateTableIndex,
+						      pVBInfo);
 			}
 
-			if ((pVBInfo->IF_DEF_OEMUtil == 0) || (LCDPtr == NULL)) {
+			if ((pVBInfo->IF_DEF_OEMUtil == 0) ||
+			    (LCDPtr == NULL)) {
 				tempbx = 3;
 				if (pVBInfo->LCDInfo & EnableScalingLCD)
-					LCDPtr1
-							= (struct XGI330_LCDDataDesStruct2 *) XGI_GetLcdPtr(
-									tempbx,
-									ModeNo,
-									ModeIdIndex,
-									RefreshRateTableIndex,
-									pVBInfo);
+					LCDPtr1 =
+					    (struct XGI330_LCDDataDesStruct2 *)
+							XGI_GetLcdPtr(
+							  tempbx,
+							  ModeNo,
+							  ModeIdIndex,
+							  RefreshRateTableIndex,
+							  pVBInfo);
 				else
-					LCDPtr
-							= (struct XGI330_LCDDataDesStruct *) XGI_GetLcdPtr(
-									tempbx,
-									ModeNo,
-									ModeIdIndex,
-									RefreshRateTableIndex,
-									pVBInfo);
+					LCDPtr =
+					    (struct XGI330_LCDDataDesStruct *)
+							XGI_GetLcdPtr(
+							  tempbx,
+							  ModeNo,
+							  ModeIdIndex,
+							  RefreshRateTableIndex,
+							  pVBInfo);
 			}
 
 			XGI_GetLCDSync(&tempax, &tempbx, pVBInfo);
@@ -2788,14 +2929,12 @@
 			push2 = tempax;
 
 			/* GetLCDResInfo */
-			if ((pVBInfo->LCDResInfo == Panel1024x768)
-					|| (pVBInfo->LCDResInfo
-							== Panel1024x768x75)) {
+			if ((pVBInfo->LCDResInfo == Panel1024x768) ||
+			    (pVBInfo->LCDResInfo == Panel1024x768x75)) {
 				tempax = 1024;
 				tempbx = 768;
-			} else if ((pVBInfo->LCDResInfo == Panel1280x1024)
-					|| (pVBInfo->LCDResInfo
-							== Panel1280x1024x75)) {
+			} else if ((pVBInfo->LCDResInfo == Panel1280x1024) ||
+				   (pVBInfo->LCDResInfo == Panel1280x1024x75)) {
 				tempax = 1280;
 				tempbx = 1024;
 			} else if (pVBInfo->LCDResInfo == Panel1400x1050) {
@@ -2813,8 +2952,8 @@
 				pVBInfo->VGAVDE = tempbx;
 			}
 
-			if ((pVBInfo->IF_DEF_ScaleLCD == 1)
-					&& (pVBInfo->LCDInfo & EnableScalingLCD)) {
+			if ((pVBInfo->IF_DEF_ScaleLCD == 1) &&
+			    (pVBInfo->LCDInfo & EnableScalingLCD)) {
 				tempax = pVBInfo->HDE;
 				tempbx = pVBInfo->VDE;
 			}
@@ -2961,16 +3100,18 @@
 
 			if (pVBInfo->VBType & VB_XGI301C) {
 				temp2 = push3;
-				xgifb_reg_set(pVBInfo->Part4Port, 0x3c,
-						(unsigned short) (temp2 & 0xff));
-				xgifb_reg_set(pVBInfo->Part4Port, 0x3b,
-						(unsigned short) ((temp2 >> 8)
-								& 0xff));
+				xgifb_reg_set(pVBInfo->Part4Port,
+					      0x3c,
+					      (unsigned short) (temp2 & 0xff));
+				xgifb_reg_set(pVBInfo->Part4Port,
+					      0x3b,
+					      (unsigned short) ((temp2 >> 8) &
+					      0xff));
 				tempbx = (unsigned short) (temp2 >> 16);
 				xgifb_reg_and_or(pVBInfo->Part4Port, 0x3a,
 						~0xc0,
-						(unsigned short) ((tempbx
-								& 0xff) << 6));
+						(unsigned short) ((tempbx &
+								   0xff) << 6));
 
 				tempcx = pVBInfo->VGAVDE;
 				if (tempcx == pVBInfo->VDE)
@@ -3072,12 +3213,14 @@
 	unsigned char *CHTVVCLKPtr = NULL;
 
 	if (ModeNo <= 0x13)
-		modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; /* si+St_ResInfo */
+		/* si+St_ResInfo */
+		modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag;
 	else
-		modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; /* si+Ext_ResInfo */
+		/* si+Ext_ResInfo */
+		modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
 
-	if ((pVBInfo->SetFlag & ProgrammingCRT2) && (!(pVBInfo->LCDInfo
-			& EnableScalingLCD))) { /* {LCDA/LCDB} */
+	if ((pVBInfo->SetFlag & ProgrammingCRT2) &&
+	    (!(pVBInfo->LCDInfo & EnableScalingLCD))) { /* {LCDA/LCDB} */
 		index = XGI_GetLCDCapPtr(pVBInfo);
 		tempal = pVBInfo->LCDCapList[index].LCD_VCLK;
 
@@ -3085,8 +3228,12 @@
 			return tempal;
 
 		/* {TV} */
-		if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV
-				| VB_XGI302LV | VB_XGI301C)) {
+		if (pVBInfo->VBType &
+		    (VB_XGI301B |
+		     VB_XGI302B |
+		     VB_XGI301LV |
+		     VB_XGI302LV |
+		     VB_XGI301C)) {
 			if (pVBInfo->VBInfo & SetCRT2ToHiVisionTV) {
 				tempal = HiTVVCLKDIV2;
 				if (!(pVBInfo->TVInfo & RPLLDIV2XO))
@@ -3121,11 +3268,14 @@
 			if (pVBInfo->VBInfo & SetCRT2ToTV)
 				return tempal;
 		}
-		/* else if ((pVBInfo->IF_DEF_CH7017==1)&&(pVBInfo->VBType&VB_CH7017)) {
+		/* else if ((pVBInfo->IF_DEF_CH7017==1) &&
+			    (pVBInfo->VBType&VB_CH7017)) {
 			if (ModeNo<=0x13)
-				*tempal = pVBInfo->SModeIDTable[ModeIdIndex].St_CRT2CRTC;
+				*tempal = pVBInfo->SModeIDTable[ModeIdIndex].
+						St_CRT2CRTC;
 			else
-				*tempal = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
+				*tempal = pVBInfo->RefIndex[
+					RefreshRateTableIndex].Ext_CRT2CRTC;
 			*tempal = *tempal & 0x1F;
 			tempbx = 0;
 			if (pVBInfo->TVInfo & SetPALTV)
@@ -3136,15 +3286,18 @@
 		} */
 	} /* {End of VB} */
 
-	if ((pVBInfo->IF_DEF_CH7007 == 1) && (pVBInfo->VBType & VB_CH7007)) { /* [Billy] 07/05/08 CH7007 */
-		/* VideoDebugPrint((0, "XGI_GetVCLKPtr: pVBInfo->IF_DEF_CH7007==1\n")); */
+	if ((pVBInfo->IF_DEF_CH7007 == 1) &&
+	    (pVBInfo->VBType & VB_CH7007)) { /* [Billy] 07/05/08 CH7007 */
+		/* VideoDebugPrint((
+			0,
+			"XGI_GetVCLKPtr: pVBInfo->IF_DEF_CH7007==1\n")); */
 		if ((pVBInfo->VBInfo & SetCRT2ToTV)) {
 			if (ModeNo <= 0x13) {
-				tempal
-						= pVBInfo->SModeIDTable[ModeIdIndex].St_CRT2CRTC;
+				tempal = pVBInfo->SModeIDTable[ModeIdIndex].
+					St_CRT2CRTC;
 			} else {
-				tempal
-						= pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
+				tempal = pVBInfo->RefIndex[
+					RefreshRateTableIndex].Ext_CRT2CRTC;
 			}
 
 			tempal = tempal & 0x0F;
@@ -3208,7 +3361,8 @@
 	tempal = tempal >> 2;
 	tempal &= 0x03;
 
-	if ((pVBInfo->LCDInfo & EnableScalingLCD) && (modeflag & Charx8Dot)) /* for Dot8 Scaling LCD */
+	/* for Dot8 Scaling LCD */
+	if ((pVBInfo->LCDInfo & EnableScalingLCD) && (modeflag & Charx8Dot))
 		tempal = tempal ^ tempal; /* ; set to VCLK25MHz always */
 
 	if (ModeNo <= 0x13)
@@ -3222,7 +3376,9 @@
 		unsigned char *di_1, struct vb_device_info *pVBInfo)
 {
 	if (pVBInfo->IF_DEF_CH7007 == 1) { /* [Billy] 2007/05/16 */
-		/* VideoDebugPrint((0, "XGI_GetVCLKLen: pVBInfo->IF_DEF_CH7007==1\n")); */
+		/* VideoDebugPrint((
+			0,
+			"XGI_GetVCLKLen: pVBInfo->IF_DEF_CH7007==1\n")); */
 		*di_0 = (unsigned char) XGI_CH7007VCLKData[tempal].SR2B;
 		*di_1 = (unsigned char) XGI_CH7007VCLKData[tempal].SR2C;
 	} else if (pVBInfo->VBType & (VB_XGI301 | VB_XGI301B | VB_XGI302B
@@ -3291,7 +3447,8 @@
 		temp &= 0x0f;
 
 		if (!(temp == 0x08)) {
-			tempax = xgifb_reg_get(pVBInfo->Part1Port, 0x13); /* Check ChannelA by Part1_13 [2003/10/03] */
+			/* Check ChannelA by Part1_13 [2003/10/03] */
+			tempax = xgifb_reg_get(pVBInfo->Part1Port, 0x13);
 			if (tempax & 0x04)
 				tempcl = tempcl | ActiveLCD;
 
@@ -3388,13 +3545,12 @@
 						tempbx = VB_XGI301LV;
 						if (flag >= 0xE0) {
 							tempbx = VB_XGI302LV;
-							tempah
-									= xgifb_reg_get(
-											pVBInfo->Part4Port,
-											0x39);
+							tempah = xgifb_reg_get(
+							    pVBInfo->Part4Port,
+							    0x39);
 							if (tempah != 0xFF)
-								tempbx
-										= VB_XGI301C;
+								tempbx =
+								    VB_XGI301C;
 						}
 					}
 				}
@@ -3436,7 +3592,8 @@
 	tempbx = 0;
 
 	if (pVBInfo->VBType & 0xFFFF) {
-		temp = xgifb_reg_get(pVBInfo->P3d4, 0x30); /* Check Display Device */
+		/* Check Display Device */
+		temp = xgifb_reg_get(pVBInfo->P3d4, 0x30);
 		tempbx = tempbx | temp;
 		temp = xgifb_reg_get(pVBInfo->P3d4, 0x31);
 		push = temp;
@@ -3455,29 +3612,34 @@
 			if ((pVBInfo->Set_VGAType >= XG20)
 					|| (pVBInfo->Set_VGAType >= XG40)) {
 				if (pVBInfo->IF_DEF_LVDS == 0) {
-					/* if ((pVBInfo->VBType & VB_XGI302B) || (pVBInfo->VBType & VB_XGI301LV) || (pVBInfo->VBType & VB_XGI302LV) || (pVBInfo->VBType & VB_XGI301C)) */
-					if (pVBInfo->VBType & (VB_XGI302B
-							| VB_XGI301LV
-							| VB_XGI302LV
-							| VB_XGI301C)) {
+					/* if ((pVBInfo->VBType & VB_XGI302B)
+					    || (pVBInfo->VBType & VB_XGI301LV)
+					    || (pVBInfo->VBType & VB_XGI302LV)
+					    || (pVBInfo->VBType & VB_XGI301C))
+					*/
+					if (pVBInfo->VBType &
+					    (VB_XGI302B |
+					     VB_XGI301LV |
+					     VB_XGI302LV |
+					     VB_XGI301C)) {
 						if (temp & EnableDualEdge) {
-							tempbx
-									|= SetCRT2ToDualEdge;
+							tempbx |=
+							    SetCRT2ToDualEdge;
 
 							if (temp & SetToLCDA)
-								tempbx
-										|= SetCRT2ToLCDA;
+								tempbx |=
+								  SetCRT2ToLCDA;
 						}
 					}
 				} else if (pVBInfo->IF_DEF_CH7017 == 1) {
 					if (pVBInfo->VBType & VB_CH7017) {
 						if (temp & EnableDualEdge) {
-							tempbx
-									|= SetCRT2ToDualEdge;
+							tempbx |=
+							    SetCRT2ToDualEdge;
 
 							if (temp & SetToLCDA)
-								tempbx
-										|= SetCRT2ToLCDA;
+								tempbx |=
+								  SetCRT2ToLCDA;
 						}
 					}
 				}
@@ -3485,29 +3647,30 @@
 		}
 
 		if (pVBInfo->IF_DEF_YPbPr == 1) {
-			if (((pVBInfo->IF_DEF_LVDS == 0) && ((pVBInfo->VBType
-					& VB_XGI301LV) || (pVBInfo->VBType
-					& VB_XGI302LV) || (pVBInfo->VBType
-					& VB_XGI301C)))
-					|| ((pVBInfo->IF_DEF_CH7017 == 1)
-							&& (pVBInfo->VBType
-									& VB_CH7017))
-					|| ((pVBInfo->IF_DEF_CH7007 == 1)
-							&& (pVBInfo->VBType
-									& VB_CH7007))) { /* [Billy] 07/05/04 */
+			/* [Billy] 07/05/04 */
+			if (((pVBInfo->IF_DEF_LVDS == 0) &&
+			    ((pVBInfo->VBType & VB_XGI301LV) ||
+			    (pVBInfo->VBType & VB_XGI302LV) ||
+			    (pVBInfo->VBType & VB_XGI301C))) ||
+			    ((pVBInfo->IF_DEF_CH7017 == 1) &&
+			    (pVBInfo->VBType & VB_CH7017)) ||
+			    ((pVBInfo->IF_DEF_CH7007 == 1) &&
+			    (pVBInfo->VBType & VB_CH7007))) {
 				if (temp & SetYPbPr) { /* temp = CR38 */
 					if (pVBInfo->IF_DEF_HiVision == 1) {
+						/* shampoo add for new
+						 * scratch */
 						temp = xgifb_reg_get(
 								pVBInfo->P3d4,
-								0x35); /* shampoo add for new scratch */
+								0x35);
 						temp &= YPbPrMode;
 						tempbx |= SetCRT2ToHiVisionTV;
 
 						if (temp != YPbPrMode1080i) {
-							tempbx
-									&= (~SetCRT2ToHiVisionTV);
-							tempbx
-									|= SetCRT2ToYPbPr;
+							tempbx &=
+							 (~SetCRT2ToHiVisionTV);
+							tempbx |=
+							 SetCRT2ToYPbPr;
 						}
 					}
 
@@ -3532,11 +3695,13 @@
 			}
 		} else { /* 3nd party chip */
 			if (pVBInfo->IF_DEF_CH7017 == 1)
-				temp = (SetCRT2ToTV | SetCRT2ToLCD
-						| SetCRT2ToLCDA);
-			else if (pVBInfo->IF_DEF_CH7007 == 1) { /* [Billy] 07/05/03 */
+				temp = (SetCRT2ToTV |
+					SetCRT2ToLCD |
+					SetCRT2ToLCDA);
+			/* [Billy] 07/05/03 */
+			else if (pVBInfo->IF_DEF_CH7007 == 1)
 				temp = SetCRT2ToTV;
-			} else
+			else
 				temp = SetCRT2ToLCD;
 		}
 
@@ -3549,60 +3714,67 @@
 			if (!(pVBInfo->VBType & VB_NoLCD)) {
 				if (tempbx & SetCRT2ToLCDA) {
 					if (tempbx & SetSimuScanMode)
-						tempbx
-								&= (~(SetCRT2ToLCD
-										| SetCRT2ToRAMDAC
-										| SwitchToCRT2));
+						tempbx &= (~(SetCRT2ToLCD |
+							   SetCRT2ToRAMDAC |
+							   SwitchToCRT2));
 					else
-						tempbx
-								&= (~(SetCRT2ToLCD
-										| SetCRT2ToRAMDAC
-										| SetCRT2ToTV
-										| SwitchToCRT2));
+						tempbx &= (~(SetCRT2ToLCD |
+							     SetCRT2ToRAMDAC |
+							     SetCRT2ToTV |
+							     SwitchToCRT2));
 				}
 			}
 		}
 
 		/* shampoo add */
-		if (!(tempbx & (SwitchToCRT2 | SetSimuScanMode))) { /* for driver abnormal */
+		/* for driver abnormal */
+		if (!(tempbx & (SwitchToCRT2 | SetSimuScanMode))) {
 			if (pVBInfo->IF_DEF_CRT2Monitor == 1) {
 				if (tempbx & SetCRT2ToRAMDAC) {
-					tempbx &= (0xFF00 | SetCRT2ToRAMDAC
-							| SwitchToCRT2
-							| SetSimuScanMode);
+					tempbx &= (0xFF00 |
+						   SetCRT2ToRAMDAC |
+						   SwitchToCRT2 |
+						   SetSimuScanMode);
 					tempbx &= (0x00FF | (~SetCRT2ToYPbPr));
 				}
 			} else {
-				tempbx &= (~(SetCRT2ToRAMDAC | SetCRT2ToLCD
-						| SetCRT2ToTV));
+				tempbx &= (~(SetCRT2ToRAMDAC |
+					   SetCRT2ToLCD |
+					   SetCRT2ToTV));
 			}
 		}
 
 		if (!(pVBInfo->VBType & VB_NoLCD)) {
 			if (tempbx & SetCRT2ToLCD) {
-				tempbx &= (0xFF00 | SetCRT2ToLCD | SwitchToCRT2
-						| SetSimuScanMode);
+				tempbx &= (0xFF00 |
+					   SetCRT2ToLCD |
+					   SwitchToCRT2 |
+					   SetSimuScanMode);
 				tempbx &= (0x00FF | (~SetCRT2ToYPbPr));
 			}
 		}
 
 		if (tempbx & SetCRT2ToSCART) {
-			tempbx &= (0xFF00 | SetCRT2ToSCART | SwitchToCRT2
-					| SetSimuScanMode);
+			tempbx &= (0xFF00 |
+				   SetCRT2ToSCART |
+				   SwitchToCRT2 |
+				   SetSimuScanMode);
 			tempbx &= (0x00FF | (~SetCRT2ToYPbPr));
 		}
 
 		if (pVBInfo->IF_DEF_YPbPr == 1) {
 			if (tempbx & SetCRT2ToYPbPr)
-				tempbx &= (0xFF00 | SwitchToCRT2
-						| SetSimuScanMode);
+				tempbx &= (0xFF00 |
+					   SwitchToCRT2 |
+					   SetSimuScanMode);
 		}
 
 		if (pVBInfo->IF_DEF_HiVision == 1) {
 			if (tempbx & SetCRT2ToHiVisionTV)
-				tempbx &= (0xFF00 | SetCRT2ToHiVisionTV
-						| SwitchToCRT2
-						| SetSimuScanMode);
+				tempbx &= (0xFF00 |
+					   SetCRT2ToHiVisionTV |
+					   SwitchToCRT2 |
+					   SetSimuScanMode);
 		}
 
 		if (tempax & DisableCRT2Display) { /* Set Display Device Info */
@@ -3611,38 +3783,35 @@
 		}
 
 		if (!(tempbx & DisableCRT2Display)) {
-			if ((!(tempbx & DriverMode))
-					|| (!(modeflag & CRT2Mode))) {
+			if ((!(tempbx & DriverMode)) ||
+			    (!(modeflag & CRT2Mode))) {
 				if (pVBInfo->IF_DEF_LCDA == 1) {
 					if (!(tempbx & SetCRT2ToLCDA))
-						tempbx
-								|= (SetInSlaveMode
-										| SetSimuScanMode);
+						tempbx |= (SetInSlaveMode |
+							   SetSimuScanMode);
 				}
 
 				if (pVBInfo->IF_DEF_VideoCapture == 1) {
-					if (((HwDeviceExtension->jChipType
-							== XG40)
-							&& (pVBInfo->Set_VGAType
-									== XG40))
-							|| ((HwDeviceExtension->jChipType
-									== XG41)
-									&& (pVBInfo->Set_VGAType
-											== XG41))
-							|| ((HwDeviceExtension->jChipType
-									== XG42)
-									&& (pVBInfo->Set_VGAType
-											== XG42))
-							|| ((HwDeviceExtension->jChipType
-									== XG45)
-									&& (pVBInfo->Set_VGAType
-											== XG45))) {
+					if (((HwDeviceExtension->jChipType ==
+					      XG40) &&
+					     (pVBInfo->Set_VGAType == XG40)) ||
+					    ((HwDeviceExtension->jChipType ==
+					      XG41) &&
+					     (pVBInfo->Set_VGAType == XG41)) ||
+					    ((HwDeviceExtension->jChipType ==
+					      XG42) &&
+					     (pVBInfo->Set_VGAType == XG42)) ||
+					    ((HwDeviceExtension->jChipType ==
+					      XG45) &&
+					     (pVBInfo->Set_VGAType == XG45))) {
 						if (ModeNo <= 13) {
-							if (!(tempbx
-									& SetCRT2ToRAMDAC)) { /*CRT2 not need to support*/
-								tempbx
-										&= (0x00FF
-												| (~SetInSlaveMode));
+							if (!(tempbx &
+							     SetCRT2ToRAMDAC)) {
+								/*CRT2 not need
+								 * to support*/
+								tempbx &=
+								  (0x00FF |
+								  (~SetInSlaveMode));
 								pVBInfo->SetFlag
 										|= EnableVCMode;
 							}
@@ -3651,11 +3820,13 @@
 				}
 			}
 
-			/* LCD+TV can't support in slave mode (Force LCDA+TV->LCDB) */
-			if ((tempbx & SetInSlaveMode) && (tempbx
-					& SetCRT2ToLCDA)) {
-				tempbx ^= (SetCRT2ToLCD | SetCRT2ToLCDA
-						| SetCRT2ToDualEdge);
+			/* LCD+TV can't support in slave mode
+			 * (Force LCDA+TV->LCDB) */
+			if ((tempbx & SetInSlaveMode) &&
+			    (tempbx & SetCRT2ToLCDA)) {
+				tempbx ^= (SetCRT2ToLCD |
+					  SetCRT2ToLCDA |
+					  SetCRT2ToDualEdge);
 				pVBInfo->SetFlag |= ReserveTVOption;
 			}
 		}
@@ -3674,33 +3845,40 @@
 
 	if (pVBInfo->VBInfo & SetCRT2ToTV) {
 		if (ModeNo <= 0x13) {
-			modeflag
-					= pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; /* si+St_ModeFlag */
-			resinfo = pVBInfo->SModeIDTable[ModeIdIndex].St_ResInfo; /* si+St_ResInfo */
+			modeflag = pVBInfo->SModeIDTable[ModeIdIndex].
+					St_ModeFlag; /* si+St_ModeFlag */
+			resinfo = pVBInfo->SModeIDTable[ModeIdIndex].
+					St_ResInfo; /* si+St_ResInfo */
 		} else {
-			modeflag
-					= pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
-			resinfo
-					= pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO; /* si+Ext_ResInfo */
+			modeflag = pVBInfo->EModeIDTable[ModeIdIndex].
+					Ext_ModeFlag;
+			resinfo = pVBInfo->EModeIDTable[ModeIdIndex].
+					Ext_RESINFO; /* si+Ext_ResInfo */
 		}
 
 		if (pVBInfo->VBInfo & SetCRT2ToTV) {
 			temp = xgifb_reg_get(pVBInfo->P3d4, 0x35);
 			tempbx = temp;
 			if (tempbx & SetPALTV) {
-				tempbx &= (SetCHTVOverScan | SetPALMTV
-						| SetPALNTV | SetPALTV);
+				tempbx &= (SetCHTVOverScan |
+					   SetPALMTV |
+					   SetPALNTV |
+					   SetPALTV);
 				if (tempbx & SetPALMTV)
-					tempbx &= ~SetPALTV; /* set to NTSC if PAL-M */
+					/* set to NTSC if PAL-M */
+					tempbx &= ~SetPALTV;
 			} else
-				tempbx &= (SetCHTVOverScan | SetNTSCJ
-						| SetPALTV);
+				tempbx &= (SetCHTVOverScan |
+					   SetNTSCJ |
+					   SetPALTV);
 			/*
 			if (pVBInfo->IF_DEF_LVDS == 0) {
-				index1 = xgifb_reg_get(pVBInfo->P3d4, 0x38); //PAL-M/PAL-N Info
-				temp2 = (index1 & 0xC0) >> 5; //00:PAL, 01:PAL-M, 10:PAL-N
+				//PAL-M/PAL-N Info
+				index1 = xgifb_reg_get(pVBInfo->P3d4, 0x38);
+				//00:PAL, 01:PAL-M, 10:PAL-N
+				temp2 = (index1 & 0xC0) >> 5;
 				tempbx |= temp2;
-				if (temp2 & 0x02)          //PAL-M
+				if (temp2 & 0x02) //PAL-M
 					tempbx &= (~SetPALTV);
 			}
 			*/
@@ -3746,12 +3924,13 @@
 		}
 
 		if (pVBInfo->IF_DEF_LVDS == 0) { /* shampoo */
-			if ((pVBInfo->VBInfo & SetInSlaveMode)
-					&& (!(pVBInfo->VBInfo & SetNotSimuMode)))
+			if ((pVBInfo->VBInfo & SetInSlaveMode) &&
+			    (!(pVBInfo->VBInfo & SetNotSimuMode)))
 				tempbx |= TVSimuMode;
 
-			if (!(tempbx & SetPALTV) && (modeflag > 13) && (resinfo
-					== 8)) /* NTSC 1024x768, */
+			if (!(tempbx & SetPALTV) &&
+			    (modeflag > 13) &&
+			    (resinfo == 8)) /* NTSC 1024x768, */
 				tempbx |= NTSC1024x768;
 
 			tempbx |= RPLLDIV2XO;
@@ -3760,12 +3939,15 @@
 				if (pVBInfo->VBInfo & SetInSlaveMode)
 					tempbx &= (~RPLLDIV2XO);
 			} else {
-				if (tempbx & (SetYPbPrMode525p
-						| SetYPbPrMode750p))
+				if (tempbx &
+				    (SetYPbPrMode525p | SetYPbPrMode750p))
 					tempbx &= (~RPLLDIV2XO);
-				else if (!(pVBInfo->VBType & (VB_XGI301B
-						| VB_XGI302B | VB_XGI301LV
-						| VB_XGI302LV | VB_XGI301C))) {
+				else if (!(pVBInfo->VBType &
+					 (VB_XGI301B |
+					  VB_XGI302B |
+					  VB_XGI301LV |
+					  VB_XGI302LV |
+					  VB_XGI301C))) {
 					if (tempbx & TVSimuMode)
 						tempbx &= (~RPLLDIV2XO);
 				}
@@ -3785,10 +3967,12 @@
 	pVBInfo->LCDInfo = 0;
 
 	if (ModeNo <= 0x13) {
-		modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; /* si+St_ModeFlag // */
+		/* si+St_ModeFlag // */
+		modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag;
 	} else {
 		modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
-		resinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO; /* si+Ext_ResInfo // */
+		/* si+Ext_ResInfo // */
+		resinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO;
 	}
 
 	temp = xgifb_reg_get(pVBInfo->P3d4, 0x36); /* Get LCD Res.Info */
@@ -3857,7 +4041,8 @@
 		if ((pVBInfo->LCDResInfo == Panel1400x1050) && (pVBInfo->VBInfo
 				& SetCRT2ToLCD) && (ModeNo > 0x13) && (resinfo
 				== 9) && (!(tempbx & EnableScalingLCD)))
-			tempbx |= SetLCDtoNonExpanding; /* set to center in 1280x1024 LCDB for Panel1400x1050 */
+			/* set to center in 1280x1024 LCDB for Panel1400x1050 */
+			tempbx |= SetLCDtoNonExpanding;
 	}
 
 	/*
@@ -3875,7 +4060,7 @@
 				if (ModeNo > 0x13) {
 					if (pVBInfo->LCDResInfo
 							== Panel1024x768) {
-						if (resinfo == 4) { /* 512x384  */
+						if (resinfo == 4) {/* 512x384 */
 							tempbx |= EnableLVDSDDA;
 						}
 					}
@@ -3895,8 +4080,8 @@
 
 	if (pVBInfo->IF_DEF_PWD == 1) {
 		if (pVBInfo->LCDInfo & SetPWDEnable) {
-			if ((pVBInfo->VBType & VB_XGI302LV) || (pVBInfo->VBType
-					& VB_XGI301C)) {
+			if ((pVBInfo->VBType & VB_XGI302LV) ||
+			    (pVBInfo->VBType & VB_XGI301C)) {
 				if (!(tempax & PWDEnable))
 					pVBInfo->LCDInfo &= ~SetPWDEnable;
 			}
@@ -3908,13 +4093,13 @@
 			if (pVBInfo->VBInfo & SetInSlaveMode) {
 				if (!(tempax & LockLCDBToA)) {
 					if (ModeNo <= 0x13) {
-						pVBInfo->VBInfo
-								&= ~(SetSimuScanMode
-										| SetInSlaveMode
-										| SetCRT2ToLCD);
-						pVBInfo->VBInfo
-								|= SetCRT2ToLCDA
-										| SetCRT2ToDualEdge;
+						pVBInfo->VBInfo &=
+							~(SetSimuScanMode |
+							  SetInSlaveMode |
+							  SetCRT2ToLCD);
+						pVBInfo->VBInfo |=
+							SetCRT2ToLCDA |
+							SetCRT2ToDualEdge;
 					}
 				}
 			}
@@ -3925,9 +4110,15 @@
 	if (pVBInfo->IF_DEF_LVDS == 0) {
 		if (tempax & (LockLCDBToA | StLCDBToA)) {
 			if (pVBInfo->VBInfo & SetInSlaveMode) {
-				if (!((!(tempax & LockLCDBToA)) && (ModeNo > 0x13))) {
-					pVBInfo->VBInfo&=~(SetSimuScanMode|SetInSlaveMode|SetCRT2ToLCD);
-					pVBInfo->VBInfo|=SetCRT2ToLCDA|SetCRT2ToDualEdge;
+				if (!((!(tempax & LockLCDBToA)) &&
+				    (ModeNo > 0x13))) {
+					pVBInfo->VBInfo &=
+						~(SetSimuScanMode |
+						  SetInSlaveMode |
+						  SetCRT2ToLCD);
+					pVBInfo->VBInfo |=
+						SetCRT2ToLCDA |
+						SetCRT2ToDualEdge;
 				}
 			}
 		}
@@ -3943,11 +4134,16 @@
 	if (ModeNo <= 5)
 		ModeNo |= 1;
 	if (ModeNo <= 0x13) {
-		/* for (*ModeIdIndex=0; *ModeIdIndex < sizeof(pVBInfo->SModeIDTable) / sizeof(struct XGI_StStruct); (*ModeIdIndex)++) */
+		/* for (*ModeIdIndex=0;
+			*ModeIdIndex < sizeof(pVBInfo->SModeIDTable)
+				/ sizeof(struct XGI_StStruct);
+			(*ModeIdIndex)++) */
 		for (*ModeIdIndex = 0;; (*ModeIdIndex)++) {
-			if (pVBInfo->SModeIDTable[*ModeIdIndex].St_ModeID == ModeNo)
+			if (pVBInfo->SModeIDTable[*ModeIdIndex].St_ModeID ==
+			    ModeNo)
 				break;
-			if (pVBInfo->SModeIDTable[*ModeIdIndex].St_ModeID == 0xFF)
+			if (pVBInfo->SModeIDTable[*ModeIdIndex].St_ModeID ==
+			    0xFF)
 				return 0;
 		}
 
@@ -3957,11 +4153,16 @@
 			(*ModeIdIndex) += 2; /* 400 lines */
 		/* else 350 lines */
 	} else {
-		/* for (*ModeIdIndex=0; *ModeIdIndex < sizeof(pVBInfo->EModeIDTable) / sizeof(struct XGI_ExtStruct); (*ModeIdIndex)++) */
+		/* for (*ModeIdIndex=0;
+			*ModeIdIndex < sizeof(pVBInfo->EModeIDTable)
+				/ sizeof(struct XGI_ExtStruct);
+			(*ModeIdIndex)++) */
 		for (*ModeIdIndex = 0;; (*ModeIdIndex)++) {
-			if (pVBInfo->EModeIDTable[*ModeIdIndex].Ext_ModeID == ModeNo)
+			if (pVBInfo->EModeIDTable[*ModeIdIndex].Ext_ModeID ==
+			    ModeNo)
 				break;
-			if (pVBInfo->EModeIDTable[*ModeIdIndex].Ext_ModeID == 0xFF)
+			if (pVBInfo->EModeIDTable[*ModeIdIndex].Ext_ModeID ==
+			    0xFF)
 				return 0;
 		}
 	}
@@ -4002,19 +4203,22 @@
 	tmp = temp;
 
 	if (HwDeviceExtension->jChipType == XG40) {
-		temp = 1 << ((temp & 0x0F0) >> 4); /* memory size per channel SR14[7:4] */
+		/* memory size per channel SR14[7:4] */
+		temp = 1 << ((temp & 0x0F0) >> 4);
 		if ((tmp & 0x0c) == 0x0C) { /* Qual channels */
 			temp <<= 2;
 		} else if ((tmp & 0x0c) == 0x08) { /* Dual channels */
 			temp <<= 1;
 		}
 	} else if (HwDeviceExtension->jChipType == XG42) {
-		temp = 1 << ((temp & 0x0F0) >> 4); /* memory size per channel SR14[7:4] */
+		/* memory size per channel SR14[7:4] */
+		temp = 1 << ((temp & 0x0F0) >> 4);
 		if ((tmp & 0x04) == 0x04) { /* Dual channels */
 			temp <<= 1;
 		}
 	} else if (HwDeviceExtension->jChipType == XG45) {
-		temp = 1 << ((temp & 0x0F0) >> 4); /* memory size per channel SR14[7:4] */
+		/* memory size per channel SR14[7:4] */
+		temp = 1 << ((temp & 0x0F0) >> 4);
 		if ((tmp & 0x0c) == 0x0C) { /* Qual channels */
 			temp <<= 2;
 		} else if ((tmp & 0x0c) == 0x08) { /* triple channels */
@@ -4033,7 +4237,13 @@
 #endif
 
 /*
-void XGINew_IsLowResolution(unsigned short ModeNo, unsigned short ModeIdIndex, unsigned char XGINew_CheckMemorySize(struct xgi_hw_device_info *HwDeviceExtension, unsigned short ModeNo, unsigned short ModeIdIndex, struct vb_device_info *pVBInfo)
+void XGINew_IsLowResolution(unsigned short ModeNo,
+			    unsigned short ModeIdIndex,
+			    unsigned char XGINew_CheckMemorySize(
+				struct xgi_hw_device_info *HwDeviceExtension,
+				unsigned short ModeNo,
+				unsigned short ModeIdIndex,
+				struct vb_device_info *pVBInfo)
 {
 	unsigned short data ;
 	unsigned short ModeFlag ;
@@ -4122,35 +4332,43 @@
 	if (pXGIHWDE->jChipType == XG21) {
 		if (pVBInfo->IF_DEF_LVDS == 1) {
 			if (!(XGI_XG21GetPSCValue(pVBInfo) & 0x1)) {
-				XGI_XG21BLSignalVDD(0x01, 0x01, pVBInfo); /* LVDS VDD on */
+				/* LVDS VDD on */
+				XGI_XG21BLSignalVDD(0x01, 0x01, pVBInfo);
 				XGI_XG21SetPanelDelay(2, pVBInfo);
 			}
 			if (!(XGI_XG21GetPSCValue(pVBInfo) & 0x20))
-				XGI_XG21BLSignalVDD(0x20, 0x20, pVBInfo); /* LVDS signal on */
+				/* LVDS signal on */
+				XGI_XG21BLSignalVDD(0x20, 0x20, pVBInfo);
 			XGI_XG21SetPanelDelay(3, pVBInfo);
-			XGI_XG21BLSignalVDD(0x02, 0x02, pVBInfo); /* LVDS backlight on */
+			/* LVDS backlight on */
+			XGI_XG21BLSignalVDD(0x02, 0x02, pVBInfo);
 		} else {
-			XGI_XG21BLSignalVDD(0x20, 0x20, pVBInfo); /* DVO/DVI signal on */
+			/* DVO/DVI signal on */
+			XGI_XG21BLSignalVDD(0x20, 0x20, pVBInfo);
 		}
 
 	}
 
-	if (pVBInfo->IF_DEF_CH7007 == 1) { /* [Billy] 07/05/23 For CH7007 */
-
+	/* [Billy] 07/05/23 For CH7007 */
+	if (pVBInfo->IF_DEF_CH7007 == 1) {
 	}
 
 	if (pXGIHWDE->jChipType == XG27) {
 		if (pVBInfo->IF_DEF_LVDS == 1) {
 			if (!(XGI_XG27GetPSCValue(pVBInfo) & 0x1)) {
-				XGI_XG27BLSignalVDD(0x01, 0x01, pVBInfo); /* LVDS VDD on */
+				/* LVDS VDD on */
+				XGI_XG27BLSignalVDD(0x01, 0x01, pVBInfo);
 				XGI_XG21SetPanelDelay(2, pVBInfo);
 			}
 			if (!(XGI_XG27GetPSCValue(pVBInfo) & 0x20))
-				XGI_XG27BLSignalVDD(0x20, 0x20, pVBInfo); /* LVDS signal on */
+				/* LVDS signal on */
+				XGI_XG27BLSignalVDD(0x20, 0x20, pVBInfo);
 			XGI_XG21SetPanelDelay(3, pVBInfo);
-			XGI_XG27BLSignalVDD(0x02, 0x02, pVBInfo); /* LVDS backlight on */
+			/* LVDS backlight on */
+			XGI_XG27BLSignalVDD(0x02, 0x02, pVBInfo);
 		} else {
-			XGI_XG27BLSignalVDD(0x20, 0x20, pVBInfo); /* DVO/DVI signal on */
+			/* DVO/DVI signal on */
+			XGI_XG27BLSignalVDD(0x20, 0x20, pVBInfo);
 		}
 
 	}
@@ -4162,10 +4380,12 @@
 
 	if (pXGIHWDE->jChipType == XG21) {
 		if (pVBInfo->IF_DEF_LVDS == 1) {
-			XGI_XG21BLSignalVDD(0x02, 0x00, pVBInfo); /* LVDS backlight off */
+			/* LVDS backlight off */
+			XGI_XG21BLSignalVDD(0x02, 0x00, pVBInfo);
 			XGI_XG21SetPanelDelay(3, pVBInfo);
 		} else {
-			XGI_XG21BLSignalVDD(0x20, 0x00, pVBInfo); /* DVO/DVI signal off */
+			/* DVO/DVI signal off */
+			XGI_XG21BLSignalVDD(0x20, 0x00, pVBInfo);
 		}
 	}
 
@@ -4177,12 +4397,14 @@
 
 	if (pXGIHWDE->jChipType == XG27) {
 		if ((XGI_XG27GetPSCValue(pVBInfo) & 0x2)) {
-			XGI_XG27BLSignalVDD(0x02, 0x00, pVBInfo); /* LVDS backlight off */
+			/* LVDS backlight off */
+			XGI_XG27BLSignalVDD(0x02, 0x00, pVBInfo);
 			XGI_XG21SetPanelDelay(3, pVBInfo);
 		}
 
 		if (pVBInfo->IF_DEF_LVDS == 0)
-			XGI_XG27BLSignalVDD(0x20, 0x00, pVBInfo); /* DVO/DVI signal off */
+			/* DVO/DVI signal off */
+			XGI_XG27BLSignalVDD(0x20, 0x00, pVBInfo);
 	}
 
 	xgifb_reg_and_or(pVBInfo->P3c4, 0x01, 0xDF, 0x20);
@@ -4200,8 +4422,10 @@
 #if 0
 static void XGI_WaitDisplay(struct vb_device_info *pVBInfo)
 {
-	while (!(inb(pVBInfo->P3da) & 0x01));
-	while (inb(pVBInfo->P3da) & 0x01);
+	while (!(inb(pVBInfo->P3da) & 0x01))
+		;
+	while (inb(pVBInfo->P3da) & 0x01)
+		;
 }
 #endif
 
@@ -4211,18 +4435,21 @@
 		xgifb_reg_or(pVBInfo->Part1Port, 0x01, 0x40);
 }
 
-static void XGI_SaveCRT2Info(unsigned short ModeNo, struct vb_device_info *pVBInfo)
+static void XGI_SaveCRT2Info(unsigned short ModeNo,
+			     struct vb_device_info *pVBInfo)
 {
 	unsigned short temp1, temp2;
 
-	xgifb_reg_set(pVBInfo->P3d4, 0x34, ModeNo); /* reserve CR34 for CRT1 Mode No */
+	/* reserve CR34 for CRT1 Mode No */
+	xgifb_reg_set(pVBInfo->P3d4, 0x34, ModeNo);
 	temp1 = (pVBInfo->VBInfo & SetInSlaveMode) >> 8;
 	temp2 = ~(SetInSlaveMode >> 8);
 	xgifb_reg_and_or(pVBInfo->P3d4, 0x31, temp2, temp1);
 }
 
-static void XGI_GetCRT2ResInfo(unsigned short ModeNo, unsigned short ModeIdIndex,
-		struct vb_device_info *pVBInfo)
+static void XGI_GetCRT2ResInfo(unsigned short ModeNo,
+			       unsigned short ModeIdIndex,
+			       struct vb_device_info *pVBInfo)
 {
 	unsigned short xres, yres, modeflag, resindex;
 
@@ -4230,11 +4457,13 @@
 	if (ModeNo <= 0x13) {
 		xres = pVBInfo->StResInfo[resindex].HTotal;
 		yres = pVBInfo->StResInfo[resindex].VTotal;
-		/* modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; si+St_ResInfo */
+		/* si+St_ResInfo */
+		/* modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag;*/
 	} else {
 		xres = pVBInfo->ModeResInfo[resindex].HTotal; /* xres->ax */
 		yres = pVBInfo->ModeResInfo[resindex].VTotal; /* yres->bx */
-		modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; /* si+St_ModeFlag */
+		/* si+St_ModeFlag */
+		modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
 
 		/*
 		if (pVBInfo->IF_DEF_FSTN) {
@@ -4306,9 +4535,10 @@
 	return 0;
 }
 
-static void XGI_GetRAMDAC2DATA(unsigned short ModeNo, unsigned short ModeIdIndex,
-		unsigned short RefreshRateTableIndex,
-		struct vb_device_info *pVBInfo)
+static void XGI_GetRAMDAC2DATA(unsigned short ModeNo,
+			       unsigned short ModeIdIndex,
+			       unsigned short RefreshRateTableIndex,
+			       struct vb_device_info *pVBInfo)
 {
 	unsigned short tempax, tempbx, temp1, temp2, modeflag = 0, tempcx,
 			StandTableIndex, CRT1Index;
@@ -4324,24 +4554,23 @@
 		temp1 = pVBInfo->StandTable[StandTableIndex].CRTC[7];
 	} else {
 		modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
-		CRT1Index
-				= pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
+		CRT1Index = pVBInfo->RefIndex[RefreshRateTableIndex].
+				Ext_CRT1CRTC;
 		CRT1Index &= IndexMask;
-		temp1
-				= (unsigned short) pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[0];
-		temp2
-				= (unsigned short) pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[5];
+		temp1 = (unsigned short) pVBInfo->
+			XGINEWUB_CRT1Table[CRT1Index].CR[0];
+		temp2 = (unsigned short) pVBInfo->
+			XGINEWUB_CRT1Table[CRT1Index].CR[5];
 		tempax = (temp1 & 0xFF) | ((temp2 & 0x03) << 8);
-		tempbx
-				= (unsigned short) pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[8];
-		tempcx
-				= (unsigned short) pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[14]
-						<< 8;
+		tempbx = (unsigned short) pVBInfo->
+			XGINEWUB_CRT1Table[CRT1Index].CR[8];
+		tempcx = (unsigned short) pVBInfo->
+			XGINEWUB_CRT1Table[CRT1Index].CR[14] << 8;
 		tempcx &= 0x0100;
 		tempcx = tempcx << 2;
 		tempbx |= tempcx;
-		temp1
-				= (unsigned short) pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[9];
+		temp1 = (unsigned short) pVBInfo->
+			XGINEWUB_CRT1Table[CRT1Index].CR[9];
 	}
 
 	if (temp1 & 0x01)
@@ -4373,10 +4602,12 @@
 	struct XGI_TVDataStruct *TVPtr = NULL;
 
 	if (ModeNo <= 0x13) {
-		modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; /* si+St_ResInfo */
+		/* si+St_ResInfo */
+		modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag;
 		resinfo = pVBInfo->SModeIDTable[ModeIdIndex].St_ResInfo;
 	} else {
-		modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; /* si+Ext_ResInfo */
+		/* si+Ext_ResInfo */
+		modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
 		resinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO;
 	}
 
@@ -4598,7 +4829,8 @@
 	return ColorDepth[index];
 }
 
-static unsigned short XGI_GetOffset(unsigned short ModeNo, unsigned short ModeIdIndex,
+static unsigned short XGI_GetOffset(unsigned short ModeNo,
+				    unsigned short ModeIdIndex,
 		unsigned short RefreshRateTableIndex,
 		struct xgi_hw_device_info *HwDeviceExtension,
 		struct vb_device_info *pVBInfo)
@@ -4610,7 +4842,8 @@
 	if (ModeNo <= 0x14)
 		infoflag = 0;
 	else
-		infoflag = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
+		infoflag = pVBInfo->
+				RefIndex[RefreshRateTableIndex].Ext_InfoFlag;
 
 	index = (modeinfo >> 8) & 0xFF;
 
@@ -4657,8 +4890,10 @@
 
 static void XGI_SetCRT2FIFO(struct vb_device_info *pVBInfo)
 {
-	xgifb_reg_set(pVBInfo->Part1Port, 0x01, 0x3B); /* threshold high ,disable auto threshold */
-	xgifb_reg_and_or(pVBInfo->Part1Port, 0x02, ~(0x3F), 0x04); /* threshold low default 04h */
+	/* threshold high ,disable auto threshold */
+	xgifb_reg_set(pVBInfo->Part1Port, 0x01, 0x3B);
+	/* threshold low default 04h */
+	xgifb_reg_and_or(pVBInfo->Part1Port, 0x02, ~(0x3F), 0x04);
 }
 
 static void XGI_PreSetGroup1(unsigned short ModeNo, unsigned short ModeIdIndex,
@@ -4669,7 +4904,8 @@
 	unsigned short tempcx = 0, CRT1Index = 0, resinfo = 0;
 
 	if (ModeNo > 0x13) {
-		CRT1Index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
+		CRT1Index = pVBInfo->
+				RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
 		CRT1Index &= IndexMask;
 		resinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO;
 	}
@@ -4695,7 +4931,8 @@
 			pushbx = 0, CRT1Index = 0, modeflag, resinfo = 0;
 
 	if (ModeNo > 0x13) {
-		CRT1Index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
+		CRT1Index = pVBInfo->
+				RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
 		CRT1Index &= IndexMask;
 		resinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO;
 	}
@@ -4707,11 +4944,13 @@
 
 	/* bainy change table name */
 	if (modeflag & HalfDCLK) {
-		temp = (pVBInfo->VGAHT / 2 - 1) & 0x0FF; /* BTVGA2HT 0x08,0x09 */
+		/* BTVGA2HT 0x08,0x09 */
+		temp = (pVBInfo->VGAHT / 2 - 1) & 0x0FF;
 		xgifb_reg_set(pVBInfo->Part1Port, 0x08, temp);
 		temp = (((pVBInfo->VGAHT / 2 - 1) & 0xFF00) >> 8) << 4;
 		xgifb_reg_and_or(pVBInfo->Part1Port, 0x09, ~0x0F0, temp);
-		temp = (pVBInfo->VGAHDE / 2 + 16) & 0x0FF; /* BTVGA2HDEE 0x0A,0x0C */
+		/* BTVGA2HDEE 0x0A,0x0C */
+		temp = (pVBInfo->VGAHDE / 2 + 16) & 0x0FF;
 		xgifb_reg_set(pVBInfo->Part1Port, 0x0A, temp);
 		tempcx = ((pVBInfo->VGAHT - pVBInfo->VGAHDE) / 2) >> 2;
 		pushbx = pVBInfo->VGAHDE / 2 + 16;
@@ -4721,8 +4960,9 @@
 
 		if (pVBInfo->VBInfo & SetCRT2ToRAMDAC) {
 			tempbx = pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[4];
-			tempbx |= ((pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[14]
-							& 0xC0) << 2);
+			tempbx |= ((pVBInfo->
+					XGINEWUB_CRT1Table[CRT1Index].CR[14] &
+						0xC0) << 2);
 			tempbx = (tempbx - 3) << 3; /* (VGAHRS-3)*8 */
 			tempcx = pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[5];
 			tempcx &= 0x1F;
@@ -4745,7 +4985,8 @@
 		xgifb_reg_set(pVBInfo->Part1Port, 0x08, temp);
 		temp = (((pVBInfo->VGAHT - 1) & 0xFF00) >> 8) << 4;
 		xgifb_reg_and_or(pVBInfo->Part1Port, 0x09, ~0x0F0, temp);
-		temp = (pVBInfo->VGAHDE + 16) & 0x0FF; /* BTVGA2HDEE 0x0A,0x0C */
+		/* BTVGA2HDEE 0x0A,0x0C */
+		temp = (pVBInfo->VGAHDE + 16) & 0x0FF;
 		xgifb_reg_set(pVBInfo->Part1Port, 0x0A, temp);
 		tempcx = (pVBInfo->VGAHT - pVBInfo->VGAHDE) >> 2; /* cx */
 		pushbx = pVBInfo->VGAHDE + 16;
@@ -4755,8 +4996,9 @@
 
 		if (pVBInfo->VBInfo & SetCRT2ToRAMDAC) {
 			tempbx = pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[3];
-			tempbx |= ((pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[5]
-							& 0xC0) << 2);
+			tempbx |= ((pVBInfo->
+					XGINEWUB_CRT1Table[CRT1Index].CR[5] &
+						0xC0) << 2);
 			tempbx = (tempbx - 3) << 3; /* (VGAHRS-3)*8 */
 			tempcx = pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[4];
 			tempcx &= 0x1F;
@@ -4801,8 +5043,10 @@
 	tempax = pVBInfo->VGAVDE;
 	tempbx = pVBInfo->VGAVDE;
 	tempcx = pVBInfo->VGAVT;
-	tempbx = (pVBInfo->VGAVT + pVBInfo->VGAVDE) >> 1; /* BTVGA2VRS 0x10,0x11 */
-	tempcx = ((pVBInfo->VGAVT - pVBInfo->VGAVDE) >> 4) + tempbx + 1; /* BTVGA2VRE 0x11 */
+	/* BTVGA2VRS 0x10,0x11 */
+	tempbx = (pVBInfo->VGAVT + pVBInfo->VGAVDE) >> 1;
+	/* BTVGA2VRE 0x11 */
+	tempcx = ((pVBInfo->VGAVT - pVBInfo->VGAVDE) >> 4) + tempbx + 1;
 
 	if (pVBInfo->VBInfo & SetCRT2ToRAMDAC) {
 		tempbx = pVBInfo->XGINEWUB_CRT1Table[CRT1Index].CR[10];
@@ -4860,12 +5104,15 @@
 			modeflag, CRT1Index;
 
 	if (ModeNo <= 0x13) {
-		modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; /* si+St_ResInfo */
+		/* si+St_ResInfo */
+		modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag;
 		resinfo = pVBInfo->SModeIDTable[ModeIdIndex].St_ResInfo;
 	} else {
-		modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; /* si+Ext_ResInfo */
+		/* si+Ext_ResInfo */
+		modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
 		resinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO;
-		CRT1Index = pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
+		CRT1Index = pVBInfo->
+				RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
 		CRT1Index &= IndexMask;
 	}
 
@@ -4911,8 +5158,10 @@
 		}
 	}
 
-	xgifb_reg_set(pVBInfo->Part1Port, 0x05, temp); /* 0x05 Horizontal Display Start */
-	xgifb_reg_set(pVBInfo->Part1Port, 0x06, 0x03); /* 0x06 Horizontal Blank end */
+	/* 0x05 Horizontal Display Start */
+	xgifb_reg_set(pVBInfo->Part1Port, 0x05, temp);
+	/* 0x06 Horizontal Blank end */
+	xgifb_reg_set(pVBInfo->Part1Port, 0x06, 0x03);
 
 	if (!(pVBInfo->VBInfo & DisableCRT2Display)) { /* 030226 bainy */
 		if (pVBInfo->VBInfo & SetCRT2ToTV)
@@ -4960,15 +5209,14 @@
 				if (pVBInfo->LCDResInfo != Panel1280x960) {
 					if (pVBInfo->VGAHDE >= 800) {
 						temp -= 7;
-						if (pVBInfo->ModeType
-								== ModeEGA) {
-							if (pVBInfo->VGAVDE
-									== 1024) {
+						if (pVBInfo->ModeType ==
+							ModeEGA) {
+							if (pVBInfo->VGAVDE ==
+							    1024) {
 								temp += 15;
-								if (pVBInfo->LCDResInfo
-										!= Panel1280x1024) {
-									temp
-											+= 7;
+								if (pVBInfo->LCDResInfo != Panel1280x1024) {
+									temp +=
+									    7;
 								}
 							}
 						}
@@ -4989,8 +5237,10 @@
 		}
 	}
 
-	xgifb_reg_set(pVBInfo->Part1Port, 0x07, temp); /* 0x07 Horizontal Retrace Start */
-	xgifb_reg_set(pVBInfo->Part1Port, 0x08, 0); /* 0x08 Horizontal Retrace End */
+	/* 0x07 Horizontal Retrace Start */
+	xgifb_reg_set(pVBInfo->Part1Port, 0x07, temp);
+	/* 0x08 Horizontal Retrace End */
+	xgifb_reg_set(pVBInfo->Part1Port, 0x08, 0);
 
 	if (pVBInfo->VBInfo & SetCRT2ToTV) {
 		if (pVBInfo->TVInfo & TVSimuMode) {
@@ -5087,7 +5337,8 @@
 	temp = tempbx & 0x00FF;
 	tempbx--;
 	temp = tempbx & 0x00FF;
-	xgifb_reg_set(pVBInfo->Part1Port, 0x10, temp); /* 0x10 vertical Blank Start */
+	/* 0x10 vertical Blank Start */
+	xgifb_reg_set(pVBInfo->Part1Port, 0x10, temp);
 	tempbx = push2;
 	tempbx--;
 	temp = tempbx & 0x00FF;
@@ -5110,7 +5361,8 @@
 	if (tempbx & 0x0400)
 		tempcx |= 0x0600;
 
-	xgifb_reg_set(pVBInfo->Part1Port, 0x11, 0x00); /* 0x11 Vertival Blank End */
+	/* 0x11 Vertival Blank End */
+	xgifb_reg_set(pVBInfo->Part1Port, 0x11, 0x00);
 
 	tempax = push1;
 	tempax -= tempbx; /* 0x0C Vertical Retrace Start */
@@ -5129,12 +5381,12 @@
 			} else {
 				if (pVBInfo->TVInfo & TVSimuMode) {
 					if (pVBInfo->TVInfo & SetPALTV) {
-						if (pVBInfo->VBType
-								& VB_XGI301LV) {
-							if (!(pVBInfo->TVInfo
-									& (SetYPbPrMode525p
-											| SetYPbPrMode750p
-											| SetYPbPrMode1080i)))
+						if (pVBInfo->VBType &
+						    VB_XGI301LV) {
+							if (!(pVBInfo->TVInfo &
+							    (SetYPbPrMode525p |
+							    SetYPbPrMode750p |
+							    SetYPbPrMode1080i)))
 								tempbx += 40;
 						} else {
 							tempbx += 40;
@@ -5149,10 +5401,10 @@
 		if (pVBInfo->TVInfo & TVSimuMode) {
 			if (pVBInfo->TVInfo & SetPALTV) {
 				if (pVBInfo->VBType & VB_XGI301LV) {
-					if (!(pVBInfo->TVInfo
-							& (SetYPbPrMode525p
-									| SetYPbPrMode750p
-									| SetYPbPrMode1080i)))
+					if (!(pVBInfo->TVInfo &
+					    (SetYPbPrMode525p |
+					     SetYPbPrMode750p |
+					     SetYPbPrMode1080i)))
 						tempbx += 40;
 				} else {
 					tempbx += 40;
@@ -5199,7 +5451,8 @@
 	tempbx = push1; /* pop ax */
 	temp = tempbx & 0x00FF;
 	temp &= 0x0F;
-	xgifb_reg_set(pVBInfo->Part1Port, 0x0D, temp); /* 0x0D vertical Retrace End */
+	/* 0x0D vertical Retrace End */
+	xgifb_reg_set(pVBInfo->Part1Port, 0x0D, temp);
 
 	if (tempbx & 0x0010)
 		tempcx |= 0x2000;
@@ -5242,14 +5495,16 @@
 	unsigned long longtemp, tempeax, tempebx, temp2, tempecx;
 
 	if (ModeNo <= 0x13) {
-		modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; /* si+St_ResInfo */
+		/* si+St_ResInfo */
+		modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag;
 		resinfo = pVBInfo->SModeIDTable[ModeIdIndex].St_ResInfo;
 		crt2crtc = pVBInfo->SModeIDTable[ModeIdIndex].St_CRT2CRTC;
 	} else {
-		modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; /* si+Ext_ResInfo */
+		/* si+Ext_ResInfo */
+		modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
 		resinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO;
-		crt2crtc
-				= pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT2CRTC;
+		crt2crtc = pVBInfo->RefIndex[RefreshRateTableIndex].
+				Ext_CRT2CRTC;
 	}
 
 	tempax = 0;
@@ -5308,7 +5563,8 @@
 		xgifb_reg_set(pVBInfo->Part2Port, i, TimingPoint[j]);
 
 	for (i = 0x39; i <= 0x45; i++, j++)
-		xgifb_reg_set(pVBInfo->Part2Port, i, TimingPoint[j]); /* di->temp2[j] */
+		/* di->temp2[j] */
+		xgifb_reg_set(pVBInfo->Part2Port, i, TimingPoint[j]);
 
 	if (pVBInfo->VBInfo & SetCRT2ToTV)
 		xgifb_reg_and_or(pVBInfo->Part2Port, 0x3A, 0x1F, 0x00);
@@ -5453,9 +5709,10 @@
 		tempbx = 853;
 
 	if (pVBInfo->VBInfo & SetCRT2ToTV) {
-		if (pVBInfo->VBType & (VB_XGI301LV | VB_XGI302LV | VB_XGI301C)) {
-			if (!(pVBInfo->TVInfo & (SetYPbPrMode525p
-					| SetYPbPrMode750p)))
+		if (pVBInfo->VBType &
+		    (VB_XGI301LV | VB_XGI302LV | VB_XGI301C)) {
+			if (!(pVBInfo->TVInfo &
+			    (SetYPbPrMode525p | SetYPbPrMode750p)))
 				tempbx = tempbx >> 1;
 		} else
 			tempbx = tempbx >> 1;
@@ -5688,13 +5945,15 @@
 	struct XGI_LCDDesStruct *LCDBDesPtr = NULL;
 
 	if (ModeNo <= 0x13) {
-		modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; /* si+St_ResInfo */
+		/* si+St_ResInfo */
+		modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag;
 		resinfo = pVBInfo->SModeIDTable[ModeIdIndex].St_ResInfo;
 	} else {
-		modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; /* si+Ext_ResInfo */
+		/* si+Ext_ResInfo */
+		modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
 		resinfo = pVBInfo->EModeIDTable[ModeIdIndex].Ext_RESINFO;
-		CRT1Index
-				= pVBInfo->RefIndex[RefreshRateTableIndex].Ext_CRT1CRTC;
+		CRT1Index = pVBInfo->RefIndex[RefreshRateTableIndex].
+			Ext_CRT1CRTC;
 		CRT1Index &= IndexMask;
 	}
 
@@ -5755,7 +6014,8 @@
 	if ((tempah == Panel1024x768) || (tempah == Panel1024x768x75)) {
 		tempbx = 1024;
 		tempcx = 768;
-	} else if ((tempah == Panel1280x1024) || (tempah == Panel1280x1024x75)) {
+	} else if ((tempah == Panel1280x1024) ||
+		   (tempah == Panel1280x1024x75)) {
 		tempbx = 1280;
 		tempcx = 1024;
 	} else if (tempah == Panel1400x1050) {
@@ -5965,16 +6225,23 @@
 	for (i = 0x80, j = 0; i <= 0xBF; i++, j++)
 		xgifb_reg_set(pVBInfo->Part2Port, i, Tap4TimingPtr->Reg[j]);
 
-	if ((pVBInfo->VBInfo & SetCRT2ToTV) && (!(pVBInfo->VBInfo & SetCRT2ToHiVisionTV))) {
-		Tap4TimingPtr = XGI_GetTap4Ptr(1, pVBInfo); /* Set Vertical Scaling */
+	if ((pVBInfo->VBInfo & SetCRT2ToTV) &&
+	    (!(pVBInfo->VBInfo & SetCRT2ToHiVisionTV))) {
+		/* Set Vertical Scaling */
+		Tap4TimingPtr = XGI_GetTap4Ptr(1, pVBInfo);
 		for (i = 0xC0, j = 0; i < 0xFF; i++, j++)
-			xgifb_reg_set(pVBInfo->Part2Port, i, Tap4TimingPtr->Reg[j]);
+			xgifb_reg_set(pVBInfo->Part2Port,
+				      i,
+				      Tap4TimingPtr->Reg[j]);
 	}
 
-	if ((pVBInfo->VBInfo & SetCRT2ToTV) && (!(pVBInfo->VBInfo & SetCRT2ToHiVisionTV)))
-		xgifb_reg_and_or(pVBInfo->Part2Port, 0x4E, ~0x14, 0x04); /* Enable V.Scaling */
+	if ((pVBInfo->VBInfo & SetCRT2ToTV) &&
+	    (!(pVBInfo->VBInfo & SetCRT2ToHiVisionTV)))
+		/* Enable V.Scaling */
+		xgifb_reg_and_or(pVBInfo->Part2Port, 0x4E, ~0x14, 0x04);
 	else
-		xgifb_reg_and_or(pVBInfo->Part2Port, 0x4E, ~0x14, 0x10); /* Enable H.Scaling */
+		/* Enable H.Scaling */
+		xgifb_reg_and_or(pVBInfo->Part2Port, 0x4E, ~0x14, 0x10);
 #endif
 }
 
@@ -5986,9 +6253,11 @@
 	unsigned short modeflag;
 
 	if (ModeNo <= 0x13)
-		modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; /* si+St_ResInfo */
+		/* si+St_ResInfo */
+		modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag;
 	else
-		modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; /* si+Ext_ResInfo */
+		/* si+Ext_ResInfo */
+		modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
 
 	xgifb_reg_set(pVBInfo->Part3Port, 0x00, 0x00);
 	if (pVBInfo->TVInfo & SetPALTV) {
@@ -6047,9 +6316,11 @@
 	unsigned long tempebx, tempeax, templong;
 
 	if (ModeNo <= 0x13)
-		modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; /* si+St_ResInfo */
+		/* si+St_ResInfo */
+		modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag;
 	else
-		modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; /* si+Ext_ResInfo */
+		/* si+Ext_ResInfo */
+		modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
 
 	temp = pVBInfo->RVBHCFACT;
 	xgifb_reg_set(pVBInfo->Part4Port, 0x13, temp);
@@ -6162,7 +6433,9 @@
 		if (XGI_IsLCDDualLink(pVBInfo))
 			tempax = tempax >> 1;
 
-		/* if((pVBInfo->VBInfo&(SetCRT2ToLCD))||((pVBInfo->TVInfo&SetYPbPrMode525p)||(pVBInfo->TVInfo&SetYPbPrMode750p))) { */
+		/* if((pVBInfo->VBInfo&(SetCRT2ToLCD)) ||
+		      ((pVBInfo->TVInfo&SetYPbPrMode525p) ||
+		      (pVBInfo->TVInfo&SetYPbPrMode750p))) { */
 		if (pVBInfo->VBInfo & SetCRT2ToLCD) {
 			if (tempax > 800)
 				tempax -= 800;
@@ -6179,12 +6452,17 @@
 		/*
 		if (pVBInfo->VBInfo & (SetCRT2ToTV | SetCRT2ToHiVisionTV)) {
 			if (pVBInfo->VBType & VB_XGI301LV) {
-				if (!(pVBInfo->TVInfo & (SetYPbPrMode525p | SetYPbPrMode750p | SetYPbPrMode1080i))) {
+				if (!(pVBInfo->TVInfo &
+				      (SetYPbPrMode525p |
+				       SetYPbPrMode750p |
+				       SetYPbPrMode1080i))) {
 					if (pVBInfo->VGAHDE > 800) {
 						if (pVBInfo->VGAHDE == 1024)
-							tempax = (tempax * 25 / 32) - 1;
+							tempax =(tempax * 25 /
+								 32) - 1;
 						else
-							tempax = (tempax * 20 / 32) - 1;
+							tempax = (tempax * 20 /
+								  32) - 1;
 					}
 				}
 			} else {
@@ -6297,7 +6575,8 @@
 	if (tempbh & 0x20) {
 		temp = (tempbl >> 4) & 0x02;
 
-		xgifb_reg_and_or(pVBInfo->P3d4, 0xB4, ~0x02, temp); /* CR B4[1] */
+		/* CR B4[1] */
+		xgifb_reg_and_or(pVBInfo->P3d4, 0xB4, ~0x02, temp);
 
 	}
 
@@ -6325,7 +6604,8 @@
 	if (tempbh & 0x20) {
 		temp = (tempbl >> 4) & 0x02;
 
-		xgifb_reg_and_or(pVBInfo->P3d4, 0xB4, ~0x02, temp); /* CR B4[1] */
+		/* CR B4[1] */
+		xgifb_reg_and_or(pVBInfo->P3d4, 0xB4, ~0x02, temp);
 
 	}
 	xgifb_reg_and_or(pVBInfo->P3d4, 0xB4, ~tempbh0, tempbl0);
@@ -6390,11 +6670,13 @@
 	if (ModeNo <= 0x13) {
 		xres = pVBInfo->StResInfo[resindex].HTotal;
 		yres = pVBInfo->StResInfo[resindex].VTotal;
-		modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; /* si+St_ResInfo */
+		/* si+St_ResInfo */
+		modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag;
 	} else {
 		xres = pVBInfo->ModeResInfo[resindex].HTotal; /* xres->ax */
 		yres = pVBInfo->ModeResInfo[resindex].VTotal; /* yres->bx */
-		modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; /* si+St_ModeFlag */
+		/* si+St_ModeFlag */
+		modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
 	}
 
 	if (!(modeflag & Charx8Dot)) {
@@ -6419,12 +6701,13 @@
 		return 0;
 
 	if (ModeNo > 0x13) {
-		if ((xres
-				!= (pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSHDE))
-				|| (yres
-						!= (pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSVDE))) {
-			colordepth = XGI_GetColorDepth(ModeNo, ModeIdIndex,
-					pVBInfo);
+		if ((xres != (pVBInfo->XG21_LVDSCapList[lvdstableindex].
+				LVDSHDE)) ||
+		    (yres != (pVBInfo->XG21_LVDSCapList[lvdstableindex].
+				LVDSVDE))) {
+			colordepth = XGI_GetColorDepth(ModeNo,
+						       ModeIdIndex,
+						       pVBInfo);
 			if (colordepth > 2)
 				return 0;
 
@@ -6439,8 +6722,10 @@
 
 	temp = xgifb_reg_get(pVBInfo->P3d4, 0x37); /* D[0] 1: 18bit */
 	temp = (temp & 1) << 6;
-	xgifb_reg_and_or(pVBInfo->P3c4, 0x06, ~0x40, temp); /* SR06[6] 18bit Dither */
-	xgifb_reg_and_or(pVBInfo->P3c4, 0x09, ~0xc0, temp | 0x80); /* SR09[7] enable FP output, SR09[6] 1: sigle 18bits, 0: dual 12bits */
+	/* SR06[6] 18bit Dither */
+	xgifb_reg_and_or(pVBInfo->P3c4, 0x06, ~0x40, temp);
+	/* SR09[7] enable FP output, SR09[6] 1: sigle 18bits, 0: dual 12bits */
+	xgifb_reg_and_or(pVBInfo->P3c4, 0x09, ~0xc0, temp | 0x80);
 
 }
 
@@ -6448,15 +6733,19 @@
 {
 	unsigned char temp;
 
-	temp = xgifb_reg_get(pVBInfo->P3d4, 0x37); /* D[1:0] 01: 18bit, 00: dual 12, 10: single 24 */
+	/* D[1:0] 01: 18bit, 00: dual 12, 10: single 24 */
+	temp = xgifb_reg_get(pVBInfo->P3d4, 0x37);
 	temp = (temp & 3) << 6;
-	xgifb_reg_and_or(pVBInfo->P3c4, 0x06, ~0xc0, temp & 0x80); /* SR06[7]0: dual 12/1: single 24 [6] 18bit Dither <= 0 h/w recommend */
-	xgifb_reg_and_or(pVBInfo->P3c4, 0x09, ~0xc0, temp | 0x80); /* SR09[7] enable FP output, SR09[6] 1: sigle 18bits, 0: 24bits */
+	/* SR06[7]0: dual 12/1: single 24 [6] 18bit Dither <= 0 h/w recommend */
+	xgifb_reg_and_or(pVBInfo->P3c4, 0x06, ~0xc0, temp & 0x80);
+	/* SR09[7] enable FP output, SR09[6] 1: sigle 18bits, 0: 24bits */
+	xgifb_reg_and_or(pVBInfo->P3c4, 0x09, ~0xc0, temp | 0x80);
 
 }
 
-static void XGI_SetXG21LVDSPara(unsigned short ModeNo, unsigned short ModeIdIndex,
-		struct vb_device_info *pVBInfo)
+static void XGI_SetXG21LVDSPara(unsigned short ModeNo,
+				unsigned short ModeIdIndex,
+				struct vb_device_info *pVBInfo)
 {
 	unsigned char temp, Miscdata;
 	unsigned short xres, yres, modeflag, resindex, lvdstableindex;
@@ -6466,28 +6755,33 @@
 
 	lvdstableindex = XGI_GetLVDSOEMTableIndex(pVBInfo);
 
-	temp = (unsigned char) ((pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDS_Capability
-					& (LCDPolarity << 8)) >> 8);
+	temp = (unsigned char) ((pVBInfo->XG21_LVDSCapList[lvdstableindex].
+						LVDS_Capability &
+				(LCDPolarity << 8)) >> 8);
 	temp &= LCDPolarity;
 	Miscdata = (unsigned char) inb(pVBInfo->P3cc);
 
 	outb((Miscdata & 0x3F) | temp, pVBInfo->P3c2);
 
-	temp = (unsigned char) (pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDS_Capability
-					& LCDPolarity);
-	xgifb_reg_and_or(pVBInfo->P3c4, 0x35, ~0x80, temp & 0x80); /* SR35[7] FP VSync polarity */
-	xgifb_reg_and_or(pVBInfo->P3c4, 0x30, ~0x20, (temp & 0x40) >> 1); /* SR30[5] FP HSync polarity */
+	temp = (unsigned char) (pVBInfo->XG21_LVDSCapList[lvdstableindex].
+						LVDS_Capability & LCDPolarity);
+	/* SR35[7] FP VSync polarity */
+	xgifb_reg_and_or(pVBInfo->P3c4, 0x35, ~0x80, temp & 0x80);
+	/* SR30[5] FP HSync polarity */
+	xgifb_reg_and_or(pVBInfo->P3c4, 0x30, ~0x20, (temp & 0x40) >> 1);
 
 	XGI_SetXG21FPBits(pVBInfo);
 	resindex = XGI_GetResInfo(ModeNo, ModeIdIndex, pVBInfo);
 	if (ModeNo <= 0x13) {
 		xres = pVBInfo->StResInfo[resindex].HTotal;
 		yres = pVBInfo->StResInfo[resindex].VTotal;
-		modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; /* si+St_ResInfo */
+		/* si+St_ResInfo */
+		modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag;
 	} else {
 		xres = pVBInfo->ModeResInfo[resindex].HTotal; /* xres->ax */
 		yres = pVBInfo->ModeResInfo[resindex].VTotal; /* yres->bx */
-		modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; /* si+St_ModeFlag */
+		/* si+St_ModeFlag */
+		modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
 	}
 
 	if (!(modeflag & Charx8Dot))
@@ -6619,18 +6913,21 @@
 
 		xgifb_reg_and_or(pVBInfo->P3c4, 0x31, ~0x30, value);
 		xgifb_reg_set(pVBInfo->P3c4,
-				0x2B,
-				pVBInfo->XG21_LVDSCapList[lvdstableindex].VCLKData1);
+			      0x2B,
+			      pVBInfo->XG21_LVDSCapList[lvdstableindex].
+						VCLKData1);
 		xgifb_reg_set(pVBInfo->P3c4,
-				0x2C,
-				pVBInfo->XG21_LVDSCapList[lvdstableindex].VCLKData2);
+			      0x2C,
+			      pVBInfo->XG21_LVDSCapList[lvdstableindex].
+						VCLKData2);
 		value += 0x10;
 	}
 
 	if (!(modeflag & Charx8Dot)) {
 		inb(pVBInfo->P3da); /* reset 3da */
 		outb(0x13, pVBInfo->P3c0); /* set index */
-		outb(0x00, pVBInfo->P3c0); /* set data, panning = 0, shift left 1 dot*/
+		/* set data, panning = 0, shift left 1 dot*/
+		outb(0x00, pVBInfo->P3c0);
 
 		inb(pVBInfo->P3da); /* Enable Attribute */
 		outb(0x20, pVBInfo->P3c0);
@@ -6641,8 +6938,9 @@
 }
 
 /* no shadow case */
-static void XGI_SetXG27LVDSPara(unsigned short ModeNo, unsigned short ModeIdIndex,
-		struct vb_device_info *pVBInfo)
+static void XGI_SetXG27LVDSPara(unsigned short ModeNo,
+				unsigned short ModeIdIndex,
+				struct vb_device_info *pVBInfo)
 {
 	unsigned char temp, Miscdata;
 	unsigned short xres, yres, modeflag, resindex, lvdstableindex;
@@ -6651,28 +6949,33 @@
 	unsigned short value;
 
 	lvdstableindex = XGI_GetLVDSOEMTableIndex(pVBInfo);
-	temp = (unsigned char) ((pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDS_Capability
-					& (LCDPolarity << 8)) >> 8);
+	temp = (unsigned char) ((pVBInfo->XG21_LVDSCapList[lvdstableindex].
+					LVDS_Capability &
+				(LCDPolarity << 8)) >> 8);
 	temp &= LCDPolarity;
 	Miscdata = (unsigned char) inb(pVBInfo->P3cc);
 
 	outb((Miscdata & 0x3F) | temp, pVBInfo->P3c2);
 
-	temp = (unsigned char) (pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDS_Capability
-					& LCDPolarity);
-	xgifb_reg_and_or(pVBInfo->P3c4, 0x35, ~0x80, temp & 0x80); /* SR35[7] FP VSync polarity */
-	xgifb_reg_and_or(pVBInfo->P3c4, 0x30, ~0x20, (temp & 0x40) >> 1); /* SR30[5] FP HSync polarity */
+	temp = (unsigned char) (pVBInfo->XG21_LVDSCapList[lvdstableindex].
+					LVDS_Capability & LCDPolarity);
+	/* SR35[7] FP VSync polarity */
+	xgifb_reg_and_or(pVBInfo->P3c4, 0x35, ~0x80, temp & 0x80);
+	/* SR30[5] FP HSync polarity */
+	xgifb_reg_and_or(pVBInfo->P3c4, 0x30, ~0x20, (temp & 0x40) >> 1);
 
 	XGI_SetXG27FPBits(pVBInfo);
 	resindex = XGI_GetResInfo(ModeNo, ModeIdIndex, pVBInfo);
 	if (ModeNo <= 0x13) {
 		xres = pVBInfo->StResInfo[resindex].HTotal;
 		yres = pVBInfo->StResInfo[resindex].VTotal;
-		modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag; /* si+St_ResInfo */
+		/* si+St_ResInfo */
+		modeflag = pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag;
 	} else {
 		xres = pVBInfo->ModeResInfo[resindex].HTotal; /* xres->ax */
 		yres = pVBInfo->ModeResInfo[resindex].VTotal; /* yres->bx */
-		modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag; /* si+St_ModeFlag */
+		/* si+St_ModeFlag */
+		modeflag = pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag;
 	}
 
 	if (!(modeflag & Charx8Dot))
@@ -6713,7 +7016,8 @@
 	if (LVDSVRS > LVDSVT)
 		LVDSVRS -= LVDSVT;
 
-	LVDSVRE = LVDSVRS + pVBInfo->XG21_LVDSCapList[lvdstableindex].LVDSVSYNC;
+	LVDSVRE = LVDSVRS + pVBInfo->XG21_LVDSCapList[lvdstableindex].
+					LVDSVSYNC;
 	if (LVDSVRE > LVDSVT)
 		LVDSVRE -= LVDSVT;
 
@@ -6803,18 +7107,21 @@
 
 		xgifb_reg_and_or(pVBInfo->P3c4, 0x31, ~0x30, value);
 		xgifb_reg_set(pVBInfo->P3c4,
-				0x2B,
-				pVBInfo->XG21_LVDSCapList[lvdstableindex].VCLKData1);
+			      0x2B,
+			      pVBInfo->XG21_LVDSCapList[lvdstableindex].
+					VCLKData1);
 		xgifb_reg_set(pVBInfo->P3c4,
-				0x2C,
-				pVBInfo->XG21_LVDSCapList[lvdstableindex].VCLKData2);
+			      0x2C,
+			      pVBInfo->XG21_LVDSCapList[lvdstableindex].
+					VCLKData2);
 		value += 0x10;
 	}
 
 	if (!(modeflag & Charx8Dot)) {
 		inb(pVBInfo->P3da); /* reset 3da */
 		outb(0x13, pVBInfo->P3c0); /* set index */
-		outb(0x00, pVBInfo->P3c0); /* set data, panning = 0, shift left 1 dot*/
+		/* set data, panning = 0, shift left 1 dot*/
+		outb(0x00, pVBInfo->P3c0);
 
 		inb(pVBInfo->P3da); /* Enable Attribute */
 		outb(0x20, pVBInfo->P3c0);
@@ -6908,14 +7215,19 @@
 
 	/*
 	if (CH7017) {
-		if (!(pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2toLCDA)) || (XGI_DisableChISLCD(pVBInfo))) {
+		if (!(pVBInfo->VBInfo &
+		    (SetCRT2ToLCD | SetCRT2toLCDA)) ||
+		    (XGI_DisableChISLCD(pVBInfo))) {
 			if (!XGI_IsLCDON(pVBInfo)) {
 				if (DISCHARGE) {
 					tempbx = XGINew_GetCH7005(0x61);
-					if (tempbx < 0x01) // first time we power up
-						XGINew_SetCH7005(0x0066); // and disable power sequence
+					// first time we power up
+					if (tempbx < 0x01)
+						// and disable power sequence
+						XGINew_SetCH7005(0x0066);
 					else
-						XGINew_SetCH7005(0x5f66); // leave VDD on - disable power
+						// leave VDD on - disable power
+						XGINew_SetCH7005(0x5f66);
 				}
 			}
 		}
@@ -6925,29 +7237,35 @@
 	if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV
 			| VB_XGI302LV | VB_XGI301C)) {
 		tempah = 0x3F;
-		if (!(pVBInfo->VBInfo & (DisableCRT2Display | SetSimuScanMode))) {
+		if (!(pVBInfo->VBInfo &
+		    (DisableCRT2Display | SetSimuScanMode))) {
 			if (pVBInfo->VBInfo & SetCRT2ToLCDA) {
 				if (pVBInfo->VBInfo & SetCRT2ToDualEdge) {
 					tempah = 0x7F; /* Disable Channel A */
 					if (!(pVBInfo->VBInfo & SetCRT2ToLCDA))
-						tempah = 0xBF; /* Disable Channel B */
+						/* Disable Channel B */
+						tempah = 0xBF;
 
 					if (pVBInfo->SetFlag & DisableChB)
-						tempah &= 0xBF; /* force to disable Cahnnel */
+						/* force to disable Cahnnel */
+						tempah &= 0xBF;
 
 					if (pVBInfo->SetFlag & DisableChA)
-						tempah &= 0x7F; /* Force to disable Channel B */
+						/* Force to disable Channel B */
+						tempah &= 0x7F;
 				}
 			}
 		}
 
-		xgifb_reg_and(pVBInfo->Part4Port, 0x1F, tempah); /* disable part4_1f */
+		/* disable part4_1f */
+		xgifb_reg_and(pVBInfo->Part4Port, 0x1F, tempah);
 
 		if (pVBInfo->VBType & (VB_XGI302LV | VB_XGI301C)) {
 			if (((pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)))
 					|| (XGI_DisableChISLCD(pVBInfo))
 					|| (XGI_IsLCDON(pVBInfo)))
-				xgifb_reg_or(pVBInfo->Part4Port, 0x30, 0x80); /* LVDS Driver power down */
+				/* LVDS Driver power down */
+				xgifb_reg_or(pVBInfo->Part4Port, 0x30, 0x80);
 		}
 
 		if ((pVBInfo->SetFlag & DisableChA) || (pVBInfo->VBInfo
@@ -6961,38 +7279,48 @@
 		if (pVBInfo->VBInfo & SetCRT2ToLCDA) {
 			if ((pVBInfo->SetFlag & DisableChA) || (pVBInfo->VBInfo
 					& SetCRT2ToLCDA))
-				xgifb_reg_and(pVBInfo->Part1Port, 0x1e, 0xdf); /* Power down */
+				/* Power down */
+				xgifb_reg_and(pVBInfo->Part1Port, 0x1e, 0xdf);
 		}
 
-		xgifb_reg_and(pVBInfo->P3c4, 0x32, 0xdf); /* disable TV as primary VGA swap */
+		/* disable TV as primary VGA swap */
+		xgifb_reg_and(pVBInfo->P3c4, 0x32, 0xdf);
 
 		if ((pVBInfo->VBInfo & (SetSimuScanMode | SetCRT2ToDualEdge)))
 			xgifb_reg_and(pVBInfo->Part2Port, 0x00, 0xdf);
 
-		if ((pVBInfo->SetFlag & DisableChB) || (pVBInfo->VBInfo
-				& (DisableCRT2Display | SetSimuScanMode))
-				|| ((!(pVBInfo->VBInfo & SetCRT2ToLCDA))
-						&& (pVBInfo->VBInfo
-								& (SetCRT2ToRAMDAC
-										| SetCRT2ToLCD
-										| SetCRT2ToTV))))
-			xgifb_reg_or(pVBInfo->Part1Port, 0x00, 0x80); /* BScreenOff=1 */
+		if ((pVBInfo->SetFlag & DisableChB) ||
+		    (pVBInfo->VBInfo &
+			(DisableCRT2Display | SetSimuScanMode)) ||
+		    ((!(pVBInfo->VBInfo & SetCRT2ToLCDA)) &&
+		    (pVBInfo->VBInfo &
+			(SetCRT2ToRAMDAC | SetCRT2ToLCD | SetCRT2ToTV))))
+			/* BScreenOff=1 */
+			xgifb_reg_or(pVBInfo->Part1Port, 0x00, 0x80);
 
-		if ((pVBInfo->SetFlag & DisableChB) || (pVBInfo->VBInfo
-				& (DisableCRT2Display | SetSimuScanMode))
-				|| (!(pVBInfo->VBInfo & SetCRT2ToLCDA))
-				|| (pVBInfo->VBInfo & (SetCRT2ToRAMDAC
-						| SetCRT2ToLCD | SetCRT2ToTV))) {
-			tempah = xgifb_reg_get(pVBInfo->Part1Port, 0x00); /* save Part1 index 0 */
-			xgifb_reg_or(pVBInfo->Part1Port, 0x00, 0x10); /* BTDAC = 1, avoid VB reset */
-			xgifb_reg_and(pVBInfo->Part1Port, 0x1E, 0xDF); /* disable CRT2 */
-			xgifb_reg_set(pVBInfo->Part1Port, 0x00, tempah); /* restore Part1 index 0 */
+		if ((pVBInfo->SetFlag & DisableChB) ||
+		    (pVBInfo->VBInfo &
+			(DisableCRT2Display | SetSimuScanMode)) ||
+		    (!(pVBInfo->VBInfo & SetCRT2ToLCDA)) ||
+		    (pVBInfo->VBInfo &
+			(SetCRT2ToRAMDAC | SetCRT2ToLCD | SetCRT2ToTV))) {
+			/* save Part1 index 0 */
+			tempah = xgifb_reg_get(pVBInfo->Part1Port, 0x00);
+			/* BTDAC = 1, avoid VB reset */
+			xgifb_reg_or(pVBInfo->Part1Port, 0x00, 0x10);
+			/* disable CRT2 */
+			xgifb_reg_and(pVBInfo->Part1Port, 0x1E, 0xDF);
+			/* restore Part1 index 0 */
+			xgifb_reg_set(pVBInfo->Part1Port, 0x00, tempah);
 		}
 	} else { /* {301} */
 		if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToTV)) {
-			xgifb_reg_or(pVBInfo->Part1Port, 0x00, 0x80); /* BScreenOff=1 */
-			xgifb_reg_and(pVBInfo->Part1Port, 0x1E, 0xDF); /* Disable CRT2 */
-			xgifb_reg_and(pVBInfo->P3c4, 0x32, 0xDF); /* Disable TV asPrimary VGA swap */
+			/* BScreenOff=1 */
+			xgifb_reg_or(pVBInfo->Part1Port, 0x00, 0x80);
+			/* Disable CRT2 */
+			xgifb_reg_and(pVBInfo->Part1Port, 0x1E, 0xDF);
+			/* Disable TV asPrimary VGA swap */
+			xgifb_reg_and(pVBInfo->P3c4, 0x32, 0xDF);
 		}
 
 		if (pVBInfo->VBInfo & (DisableCRT2Display | SetCRT2ToLCDA
@@ -7116,12 +7444,19 @@
 			/*
 			if (pVBInfo->VBInfo & SetCRT2ToRAMDAC)
 				tempbl = CRT2Delay1;	// Get CRT2 Delay
-			if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV | VB_XGI302LV | VB_XGI301C))
+			if (pVBInfo->VBType &
+			    (VB_XGI301B |
+			     VB_XGI302B |
+			     VB_XGI301LV |
+			     VB_XGI302LV |
+			     VB_XGI301C))
 				tempbl = CRT2Delay2;
 			*/
 			if (pVBInfo->VBInfo & (SetCRT2ToLCD | SetCRT2ToLCDA)) {
-				index = XGI_GetLCDCapPtr(pVBInfo); /* Get LCD Delay */
-				tempbh = pVBInfo->LCDCapList[index].LCD_DelayCompensation;
+				/* Get LCD Delay */
+				index = XGI_GetLCDCapPtr(pVBInfo);
+				tempbh = pVBInfo->LCDCapList[index].
+						LCD_DelayCompensation;
 
 				if (!(pVBInfo->VBInfo & SetCRT2ToLCDA))
 					tempbl = tempbh;
@@ -7147,9 +7482,10 @@
 		tempbl = 0;
 		tempbh = 0;
 		if (pVBInfo->VBInfo & SetCRT2ToLCD) {
-			tempah
-					= pVBInfo->LCDCapList[XGI_GetLCDCapPtr(
-							pVBInfo)].LCD_DelayCompensation; /* / Get LCD Delay */
+			/* / Get LCD Delay */
+			tempah = pVBInfo->LCDCapList[
+					XGI_GetLCDCapPtr(pVBInfo)].
+						LCD_DelayCompensation;
 			tempah &= 0x0f;
 			tempah = tempah << 4;
 			xgifb_reg_and_or(pVBInfo->Part1Port, 0x2D, 0x0f,
@@ -7158,7 +7494,8 @@
 	}
 }
 
-static void XGI_SetLCDCap_A(unsigned short tempcx, struct vb_device_info *pVBInfo)
+static void XGI_SetLCDCap_A(unsigned short tempcx,
+			    struct vb_device_info *pVBInfo)
 {
 	unsigned short temp;
 
@@ -7166,7 +7503,8 @@
 
 	if (temp & LCDRGB18Bit) {
 		xgifb_reg_and_or(pVBInfo->Part1Port, 0x19, 0x0F,
-				(unsigned short) (0x20 | (tempcx & 0x00C0))); /* Enable Dither */
+				/* Enable Dither */
+				(unsigned short) (0x20 | (tempcx & 0x00C0)));
 		xgifb_reg_and_or(pVBInfo->Part1Port, 0x1A, 0x7F, 0x80);
 	} else {
 		xgifb_reg_and_or(pVBInfo->Part1Port, 0x19, 0x0F,
@@ -7176,10 +7514,17 @@
 
 	/*
 	if (tempcx & EnableLCD24bpp) {	// 24bits
-		xgifb_reg_and_or(pVBInfo->Part1Port, 0x19, 0x0F, (unsigned short)(0x30 | (tempcx&0x00C0)));
+		xgifb_reg_and_or(pVBInfo->Part1Port,
+				 0x19,
+				 0x0F,
+				 (unsigned short)(0x30 | (tempcx&0x00C0)));
 		xgifb_reg_and_or(pVBInfo->Part1Port, 0x1A, 0x7F, 0x00);
 	} else {
-		xgifb_reg_and_or(pVBInfo->Part1Port, 0x19, 0x0F, (unsigned short)(0x20 | (tempcx&0x00C0))); // Enable Dither
+		xgifb_reg_and_or(pVBInfo->Part1Port,
+				 0x19,
+				 0x0F,
+				 // Enable Dither
+				 (unsigned short)(0x20 | (tempcx&0x00C0)));
 		xgifb_reg_and_or(pVBInfo->Part1Port, 0x1A, 0x7F, 0x80);
 	}
 	*/
@@ -7191,7 +7536,8 @@
 /* Output : */
 /* Description : */
 /* --------------------------------------------------------------------- */
-static void XGI_SetLCDCap_B(unsigned short tempcx, struct vb_device_info *pVBInfo)
+static void XGI_SetLCDCap_B(unsigned short tempcx,
+			    struct vb_device_info *pVBInfo)
 {
 	if (tempcx & EnableLCD24bpp) /* 24bits */
 		xgifb_reg_and_or(pVBInfo->Part2Port, 0x1A, 0xE0,
@@ -7209,7 +7555,8 @@
 
 	index = XGI_GetLCDCapPtr(pVBInfo);
 
-	xgifb_reg_and(pVBInfo->Part4Port, 0x30, 0x8F); /* disable down spectrum D[4] */
+	/* disable down spectrum D[4] */
+	xgifb_reg_and(pVBInfo->Part4Port, 0x30, 0x8F);
 	XGI_LongWait(pVBInfo);
 	xgifb_reg_or(pVBInfo->Part4Port, 0x30, 0x20); /* reset spectrum */
 	XGI_LongWait(pVBInfo);
@@ -7232,9 +7579,14 @@
 
 	tempcx = pVBInfo->LCDCapList[XGI_GetLCDCapPtr(pVBInfo)].LCD_Capability;
 
-	if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B | VB_XGI301LV
-			| VB_XGI302LV | VB_XGI301C)) {
-		if (pVBInfo->VBType & (VB_XGI301LV | VB_XGI302LV | VB_XGI301C)) { /* 301LV/302LV only */
+	if (pVBInfo->VBType &
+	    (VB_XGI301B |
+	     VB_XGI302B |
+	     VB_XGI301LV |
+	     VB_XGI302LV |
+	     VB_XGI301C)) { /* 301LV/302LV only */
+		if (pVBInfo->VBType &
+		    (VB_XGI301LV | VB_XGI302LV | VB_XGI301C)) {
 			/* Set 301LV Capability */
 			xgifb_reg_set(pVBInfo->Part4Port, 0x24,
 					(unsigned char) (tempcx & 0x1F));
@@ -7269,8 +7621,9 @@
 /* Output : */
 /* Description : Set TV Customized Param. */
 /* --------------------------------------------------------------------- */
-static void XGI_SetAntiFlicker(unsigned short ModeNo, unsigned short ModeIdIndex,
-		struct vb_device_info *pVBInfo)
+static void XGI_SetAntiFlicker(unsigned short ModeNo,
+			       unsigned short ModeIdIndex,
+			       struct vb_device_info *pVBInfo)
 {
 	unsigned short tempbx, index;
 
@@ -7294,8 +7647,9 @@
 	xgifb_reg_and_or(pVBInfo->Part2Port, 0x0A, 0x8F, tempah);
 }
 
-static void XGI_SetEdgeEnhance(unsigned short ModeNo, unsigned short ModeIdIndex,
-		struct vb_device_info *pVBInfo)
+static void XGI_SetEdgeEnhance(unsigned short ModeNo,
+			       unsigned short ModeIdIndex,
+			       struct vb_device_info *pVBInfo)
 {
 	unsigned short tempbx, index;
 
@@ -7388,10 +7742,11 @@
 	}
 
 	if (ModeNo <= 0x13)
-		tempal = pVBInfo->SModeIDTable[ModeIdIndex].VB_StTVYFilterIndex;
+		tempal = pVBInfo->SModeIDTable[ModeIdIndex].
+				VB_StTVYFilterIndex;
 	else
-		tempal
-				= pVBInfo->EModeIDTable[ModeIdIndex].VB_ExtTVYFilterIndex;
+		tempal = pVBInfo->EModeIDTable[ModeIdIndex].
+				VB_ExtTVYFilterIndex;
 
 	if (tempcl == 0)
 		index = tempal * 4;
@@ -7424,8 +7779,9 @@
 /* Output : */
 /* Description : Customized Param. for 301 */
 /* --------------------------------------------------------------------- */
-static void XGI_OEM310Setting(unsigned short ModeNo, unsigned short ModeIdIndex,
-		struct vb_device_info *pVBInfo)
+static void XGI_OEM310Setting(unsigned short ModeNo,
+			      unsigned short ModeIdIndex,
+			      struct vb_device_info *pVBInfo)
 {
 	if (pVBInfo->SetFlag & Win9xDOSMode)
 		return;
@@ -7462,7 +7818,8 @@
 
 	unsigned char tempah;
 
-	/* xgifb_reg_set(pVBInfo->Part1Port, 0x03, 0x00); // fix write part1 index 0 BTDRAM bit Bug */
+	/* // fix write part1 index 0 BTDRAM bit Bug
+	 * xgifb_reg_set(pVBInfo->Part1Port, 0x03, 0x00); */
 	tempah = 0;
 	if (!(pVBInfo->VBInfo & DisableCRT2Display)) {
 		tempah = xgifb_reg_get(pVBInfo->Part1Port, 0x00);
@@ -7476,7 +7833,8 @@
 				tempcl = pVBInfo->ModeType;
 				tempcl -= ModeVGA;
 				if (tempcl >= 0) {
-					tempah = (0x008 >> tempcl); /* BT Color */
+					/* BT Color */
+					tempah = (0x008 >> tempcl);
 					if (tempah == 0)
 						tempah = 1;
 					tempah |= 0x040;
@@ -7525,8 +7883,8 @@
 
 		if (pVBInfo->VBInfo & (SetCRT2ToRAMDAC | SetCRT2ToTV
 				| SetCRT2ToLCD | SetCRT2ToLCDA)) {
-			if ((pVBInfo->VBInfo & SetCRT2ToLCDA)
-					&& (!(pVBInfo->VBInfo & SetSimuScanMode))) {
+			if ((pVBInfo->VBInfo & SetCRT2ToLCDA) &&
+			    (!(pVBInfo->VBInfo & SetSimuScanMode))) {
 				tempbl &= 0xf7;
 				tempah |= 0x01;
 				xgifb_reg_and_or(pVBInfo->Part1Port, 0x2e,
@@ -7537,23 +7895,26 @@
 					tempah |= 0x01;
 				}
 
-				if (pVBInfo->VBInfo & (SetCRT2ToRAMDAC
-						| SetCRT2ToTV | SetCRT2ToLCD)) {
+				if (pVBInfo->VBInfo &
+				    (SetCRT2ToRAMDAC |
+				     SetCRT2ToTV |
+				     SetCRT2ToLCD)) {
 					tempbl &= 0xf8;
 					tempah = 0x01;
 
 					if (!(pVBInfo->VBInfo & SetInSlaveMode))
 						tempah |= 0x02;
 
-					if (!(pVBInfo->VBInfo & SetCRT2ToRAMDAC)) {
+					if (!(pVBInfo->VBInfo &
+					      SetCRT2ToRAMDAC)) {
 						tempah = tempah ^ 0x05;
-						if (!(pVBInfo->VBInfo
-								& SetCRT2ToLCD))
+						if (!(pVBInfo->VBInfo &
+						      SetCRT2ToLCD))
 							tempah = tempah ^ 0x01;
 					}
 
-					if (!(pVBInfo->VBInfo
-							& SetCRT2ToDualEdge))
+					if (!(pVBInfo->VBInfo &
+					      SetCRT2ToDualEdge))
 						tempah |= 0x08;
 					xgifb_reg_and_or(pVBInfo->Part1Port,
 							0x2e, tempbl, tempah);
@@ -7578,7 +7939,8 @@
 		tempah |= 0x080;
 
 		if (pVBInfo->VBInfo & SetCRT2ToTV) {
-			/* if (!(pVBInfo->TVInfo & (SetYPbPrMode525p | SetYPbPrMode750p))) { */
+			/* if (!(pVBInfo->TVInfo &
+				 (SetYPbPrMode525p | SetYPbPrMode750p))) { */
 			tempah |= 0x020;
 			if (ModeNo > 0x13) {
 				if (pVBInfo->VBInfo & DriverMode)
@@ -7594,7 +7956,9 @@
 			tempah |= 0x40;
 
 		if (pVBInfo->VBInfo & SetCRT2ToTV) {
-			/* if ((!(pVBInfo->VBInfo & SetCRT2ToHiVisionTV)) && (!(pVBInfo->TVInfo & (SetYPbPrMode525p | SetYPbPrMode750p)))) { */
+			/* if ((!(pVBInfo->VBInfo & SetCRT2ToHiVisionTV)) &&
+			       (!(pVBInfo->TVInfo &
+				  (SetYPbPrMode525p | SetYPbPrMode750p)))) { */
 			if (pVBInfo->TVInfo & RPLLDIV2XO)
 				tempah |= 0x40;
 			/* } */
@@ -7805,13 +8169,12 @@
 				if (pVBInfo->VBType & (VB_XGI301B | VB_XGI302B
 						| VB_XGI301LV | VB_XGI302LV
 						| VB_XGI301C))
-					temp
-							= LCDARefreshIndex[pVBInfo->LCDResInfo
-									& 0x0F]; /* 301b */
+					/* 301b */
+					temp = LCDARefreshIndex[
+						pVBInfo->LCDResInfo & 0x0F];
 				else
-					temp
-							= LCDRefreshIndex[pVBInfo->LCDResInfo
-									& 0x0F];
+					temp = LCDRefreshIndex[
+						pVBInfo->LCDResInfo & 0x0F];
 
 				if (index > temp)
 					index = temp;
@@ -7825,35 +8188,34 @@
 	ModeNo = pVBInfo->RefIndex[RefreshRateTableIndex].ModeID;
 	if (pXGIHWDE->jChipType >= XG20) { /* for XG20, XG21, XG27 */
 		/*
-		if (pVBInfo->RefIndex[RefreshRateTableIndex].Ext_InfoFlag & XG2xNotSupport) {
+		if (pVBInfo->RefIndex[RefreshRateTableIndex].Ext_InfoFlag &
+		    XG2xNotSupport) {
 			index++;
 		}
 		*/
-		if ((pVBInfo->RefIndex[RefreshRateTableIndex].XRes == 800)
-				&& (pVBInfo->RefIndex[RefreshRateTableIndex].YRes
-						== 600)) {
+		if ((pVBInfo->RefIndex[RefreshRateTableIndex].XRes == 800) &&
+		    (pVBInfo->RefIndex[RefreshRateTableIndex].YRes == 600)) {
 			index++;
 		}
-		/* Alan 10/19/2007; do the similar adjustment like XGISearchCRT1Rate() */
-		if ((pVBInfo->RefIndex[RefreshRateTableIndex].XRes == 1024)
-				&& (pVBInfo->RefIndex[RefreshRateTableIndex].YRes
-						== 768)) {
+		/* Alan 10/19/2007;
+		 * do the similar adjustment like XGISearchCRT1Rate() */
+		if ((pVBInfo->RefIndex[RefreshRateTableIndex].XRes == 1024) &&
+		    (pVBInfo->RefIndex[RefreshRateTableIndex].YRes == 768)) {
 			index++;
 		}
-		if ((pVBInfo->RefIndex[RefreshRateTableIndex].XRes == 1280)
-				&& (pVBInfo->RefIndex[RefreshRateTableIndex].YRes
-						== 1024)) {
+		if ((pVBInfo->RefIndex[RefreshRateTableIndex].XRes == 1280) &&
+		    (pVBInfo->RefIndex[RefreshRateTableIndex].YRes == 1024)) {
 			index++;
 		}
 	}
 
 	i = 0;
 	do {
-		if (pVBInfo->RefIndex[RefreshRateTableIndex + i].ModeID
-				!= ModeNo)
+		if (pVBInfo->RefIndex[RefreshRateTableIndex + i].
+			ModeID != ModeNo)
 			break;
-		temp
-				= pVBInfo->RefIndex[RefreshRateTableIndex + i].Ext_InfoFlag;
+		temp = pVBInfo->RefIndex[RefreshRateTableIndex + i].
+			Ext_InfoFlag;
 		temp &= ModeInfoFlag;
 		if (temp < pVBInfo->ModeType)
 			break;
@@ -7863,9 +8225,8 @@
 	} while (index != 0xFFFF);
 	if (!(pVBInfo->VBInfo & SetCRT2ToRAMDAC)) {
 		if (pVBInfo->VBInfo & SetInSlaveMode) {
-			temp
-					= pVBInfo->RefIndex[RefreshRateTableIndex
-							+ i - 1].Ext_InfoFlag;
+			temp = pVBInfo->RefIndex[RefreshRateTableIndex + i - 1].
+				Ext_InfoFlag;
 			if (temp & InterlaceMode)
 				i++;
 		}
@@ -8055,11 +8416,14 @@
 			| VB_XGI302LV | VB_XGI301C)) {
 		if (!(pVBInfo->SetFlag & DisableChA)) {
 			if (pVBInfo->SetFlag & EnableChA) {
-				xgifb_reg_set(pVBInfo->Part1Port, 0x1E, 0x20); /* Power on */
+				/* Power on */
+				xgifb_reg_set(pVBInfo->Part1Port, 0x1E, 0x20);
 			} else {
-				if (pVBInfo->VBInfo & SetCRT2ToDualEdge) { /* SetCRT2ToLCDA ) */
+				/* SetCRT2ToLCDA ) */
+				if (pVBInfo->VBInfo & SetCRT2ToDualEdge) {
+					/* Power on */
 					xgifb_reg_set(pVBInfo->Part1Port,
-							0x1E, 0x20); /* Power on */
+							0x1E, 0x20);
 				}
 			}
 		}
@@ -8072,7 +8436,8 @@
 						pVBInfo->P3c4, 0x32);
 				tempah &= 0xDF;
 				if (pVBInfo->VBInfo & SetInSlaveMode) {
-					if (!(pVBInfo->VBInfo & SetCRT2ToRAMDAC))
+					if (!(pVBInfo->VBInfo &
+					      SetCRT2ToRAMDAC))
 						tempah |= 0x20;
 				}
 				xgifb_reg_set(pVBInfo->P3c4, 0x32, tempah);
@@ -8082,10 +8447,11 @@
 						pVBInfo->Part1Port, 0x2E);
 
 				if (!(tempah & 0x80))
+					/* BVBDOENABLE = 1 */
 					xgifb_reg_or(pVBInfo->Part1Port,
-							0x2E, 0x80); /* BVBDOENABLE = 1 */
-
-				xgifb_reg_and(pVBInfo->Part1Port, 0x00, 0x7F); /* BScreenOFF = 0 */
+							0x2E, 0x80);
+				/* BScreenOFF = 0 */
+				xgifb_reg_and(pVBInfo->Part1Port, 0x00, 0x7F);
 			}
 		}
 
@@ -8095,15 +8461,17 @@
 					0x20); /* shampoo 0129 */
 			if (pVBInfo->VBType & (VB_XGI302LV | VB_XGI301C)) {
 				if (!XGI_DisableChISLCD(pVBInfo)) {
-					if (XGI_EnableChISLCD(pVBInfo)
-							|| (pVBInfo->VBInfo
-									& (SetCRT2ToLCD
-											| SetCRT2ToLCDA)))
+					if (XGI_EnableChISLCD(pVBInfo) ||
+					    (pVBInfo->VBInfo &
+					    (SetCRT2ToLCD | SetCRT2ToLCDA)))
+						/* LVDS PLL power on */
 						xgifb_reg_and(
-								pVBInfo->Part4Port,
-								0x2A, 0x7F); /* LVDS PLL power on */
+							pVBInfo->Part4Port,
+							0x2A,
+							0x7F);
 				}
-				xgifb_reg_and(pVBInfo->Part4Port, 0x30, 0x7F); /* LVDS Driver power on */
+				/* LVDS Driver power on */
+				xgifb_reg_and(pVBInfo->Part4Port, 0x30, 0x7F);
 			}
 		}
 
@@ -8114,33 +8482,35 @@
 
 			if (!(pVBInfo->VBInfo & SetSimuScanMode)) {
 				if (pVBInfo->VBInfo & SetCRT2ToLCDA) {
-					if (pVBInfo->VBInfo & SetCRT2ToDualEdge) {
+					if (pVBInfo->VBInfo &
+					    SetCRT2ToDualEdge) {
 						tempah = tempah & 0x40;
-						if (pVBInfo->VBInfo
-								& SetCRT2ToLCDA)
+						if (pVBInfo->VBInfo &
+						    SetCRT2ToLCDA)
 							tempah = tempah ^ 0xC0;
 
-						if (pVBInfo->SetFlag
-								& DisableChB)
+						if (pVBInfo->SetFlag &
+						    DisableChB)
 							tempah &= 0xBF;
 
-						if (pVBInfo->SetFlag
-								& DisableChA)
+						if (pVBInfo->SetFlag &
+						    DisableChA)
 							tempah &= 0x7F;
 
-						if (pVBInfo->SetFlag
-								& EnableChB)
+						if (pVBInfo->SetFlag &
+						    EnableChB)
 							tempah |= 0x40;
 
-						if (pVBInfo->SetFlag
-								& EnableChA)
+						if (pVBInfo->SetFlag &
+						    EnableChA)
 							tempah |= 0x80;
 					}
 				}
 			}
 		}
 
-		xgifb_reg_or(pVBInfo->Part4Port, 0x1F, tempah); /* EnablePart4_1F */
+		/* EnablePart4_1F */
+		xgifb_reg_or(pVBInfo->Part4Port, 0x1F, tempah);
 
 		if (pVBInfo->SetFlag & Win9xDOSMode) {
 			XGI_DisplayOn(HwDeviceExtension, pVBInfo);
@@ -8150,7 +8520,8 @@
 		if (!(pVBInfo->SetFlag & DisableChA)) {
 			XGI_VBLongWait(pVBInfo);
 			if (!(pVBInfo->SetFlag & GatingCRT)) {
-				XGI_DisableGatingCRT(HwDeviceExtension, pVBInfo);
+				XGI_DisableGatingCRT(HwDeviceExtension,
+						     pVBInfo);
 				XGI_DisplayOn(HwDeviceExtension, pVBInfo);
 				XGI_VBLongWait(pVBInfo);
 			}
@@ -8159,12 +8530,14 @@
 	else { /* LVDS */
 		if (pVBInfo->VBInfo & (SetCRT2ToTV | SetCRT2ToLCD
 				| SetCRT2ToLCDA))
-			xgifb_reg_or(pVBInfo->Part1Port, 0x1E, 0x20); /* enable CRT2 */
+			/* enable CRT2 */
+			xgifb_reg_or(pVBInfo->Part1Port, 0x1E, 0x20);
 
 		tempah = (unsigned char) xgifb_reg_get(pVBInfo->Part1Port,
 				0x2E);
 		if (!(tempah & 0x80))
-			xgifb_reg_or(pVBInfo->Part1Port, 0x2E, 0x80); /* BVBDOENABLE = 1 */
+			/* BVBDOENABLE = 1 */
+			xgifb_reg_or(pVBInfo->Part1Port, 0x2E, 0x80);
 
 		xgifb_reg_and(pVBInfo->Part1Port, 0x00, 0x7F);
 		XGI_DisplayOn(HwDeviceExtension, pVBInfo);
@@ -8222,8 +8595,8 @@
 				RefreshRateTableIndex, pVBInfo);
 	}
 
-	if ((HwDeviceExtension->jChipType >= XG20)
-			&& (HwDeviceExtension->jChipType < XG27)) { /* fix H/W DCLK/2 bug */
+	if ((HwDeviceExtension->jChipType >= XG20) &&
+	    (HwDeviceExtension->jChipType < XG27)) { /* fix H/W DCLK/2 bug */
 		if ((ModeNo == 0x00) | (ModeNo == 0x01)) {
 			xgifb_reg_set(pVBInfo->P3c4, 0x2B, 0x4E);
 			xgifb_reg_set(pVBInfo->P3c4, 0x2C, 0xE9);
@@ -8242,8 +8615,10 @@
 		temp = xgifb_reg_get(pVBInfo->P3d4, 0x38);
 		if (temp & 0xA0) {
 
-			/* xgifb_reg_and(pVBInfo->P3d4, 0x4A, ~0x20); *//* Enable write GPIOF */
-			/* xgifb_reg_and(pVBInfo->P3d4, 0x48, ~0x20); *//* P. DWN */
+			/* Enable write GPIOF */
+			/* xgifb_reg_and(pVBInfo->P3d4, 0x4A, ~0x20); */
+			/* P. DWN */
+			/* xgifb_reg_and(pVBInfo->P3d4, 0x48, ~0x20); */
 			/* XG21 CRT1 Timing */
 			if (HwDeviceExtension->jChipType == XG27)
 				XGI_SetXG27CRTC(ModeNo, ModeIdIndex,
@@ -8270,7 +8645,8 @@
 					XGI_SetXG21LVDSPara(ModeNo,
 							ModeIdIndex, pVBInfo);
 			}
-			/* xgifb_reg_or(pVBInfo->P3d4, 0x48, 0x20); *//* P. ON */
+			/* P. ON */
+			/* xgifb_reg_or(pVBInfo->P3d4, 0x48, 0x20); */
 		}
 	}
 
@@ -8289,7 +8665,8 @@
 			unsigned short ModeNo)
 {
 	unsigned short ModeIdIndex;
-	/* unsigned char *pVBInfo->FBAddr = HwDeviceExtension->pjVideoMemoryAddress; */
+	/* unsigned char *pVBInfo->FBAddr =
+				HwDeviceExtension->pjVideoMemoryAddress; */
 	struct vb_device_info VBINF;
 	struct vb_device_info *pVBInfo = &VBINF;
 	pVBInfo->ROMAddr = HwDeviceExtension->pjVirtualRomBase;
@@ -8334,7 +8711,8 @@
 	pVBInfo->Part4Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_14;
 	pVBInfo->Part5Port = pVBInfo->BaseAddr + XGI_CRT2_PORT_14 + 2;
 
-	if (HwDeviceExtension->jChipType == XG21) { /* for x86 Linux, XG21 LVDS */
+	/* for x86 Linux, XG21 LVDS */
+	if (HwDeviceExtension->jChipType == XG21) {
 		if ((xgifb_reg_get(pVBInfo->P3d4, 0x38) & 0xE0) == 0xC0)
 			pVBInfo->IF_DEF_LVDS = 1;
 	}
@@ -8417,17 +8795,17 @@
 	} /* !XG20 */
 	else {
 		if (pVBInfo->IF_DEF_LVDS == 1)
-			if (!XGI_XG21CheckLVDSMode(ModeNo, ModeIdIndex, pVBInfo))
+			if (!XGI_XG21CheckLVDSMode(ModeNo,
+						   ModeIdIndex,
+						   pVBInfo))
 				return 0;
 
 		if (ModeNo <= 0x13) {
-			pVBInfo->ModeType
-					= pVBInfo->SModeIDTable[ModeIdIndex].St_ModeFlag
-							& ModeInfoFlag;
+			pVBInfo->ModeType = pVBInfo->SModeIDTable[ModeIdIndex].
+						St_ModeFlag & ModeInfoFlag;
 		} else {
-			pVBInfo->ModeType
-					= pVBInfo->EModeIDTable[ModeIdIndex].Ext_ModeFlag
-							& ModeInfoFlag;
+			pVBInfo->ModeType = pVBInfo->EModeIDTable[ModeIdIndex].
+						Ext_ModeFlag & ModeInfoFlag;
 		}
 
 		pVBInfo->SetFlag = 0;
@@ -8455,7 +8833,10 @@
 	pVBInfo->ModeType = modeflag&ModeInfoFlag;
 	pVBInfo->SetFlag = 0x00;
 	pVBInfo->VBInfo = DisableCRT2Display;
-	temp = XGINew_CheckMemorySize(HwDeviceExtension, ModeNo, ModeIdIndex, pVBInfo);
+	temp = XGINew_CheckMemorySize(HwDeviceExtension,
+				      ModeNo,
+				      ModeIdIndex,
+				      pVBInfo);
 
 	if (temp == 0)
 		return (0);
diff -druN linux-2.6.39-libre/drivers/staging/xgifb/vb_setmode.h linux-3.0-rc7-libre/drivers/staging/xgifb/vb_setmode.h
--- linux-2.6.39-libre/drivers/staging/xgifb/vb_setmode.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/xgifb/vb_setmode.h	2011-07-11 19:51:52.000000000 -0400
@@ -1,38 +1,71 @@
-#ifndef  _VBSETMODE_
-#define  _VBSETMODE_
+#ifndef _VBSETMODE_
+#define _VBSETMODE_
 
-extern   void     InitTo330Pointer(unsigned char, struct vb_device_info *);
-extern   void     XGI_UnLockCRT2(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *);
-extern   void     XGI_LockCRT2(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *);
-extern   void     XGI_LongWait(struct vb_device_info *);
-extern   void     XGI_SetCRT2ModeRegs(unsigned short ModeNo,
-				      struct xgi_hw_device_info *,
-				      struct vb_device_info *);
-extern   void     XGI_DisableBridge(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *);
-extern   void     XGI_EnableBridge(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *);
-extern   void     XGI_DisplayOff(struct xgi_hw_device_info *, struct vb_device_info *);
-extern   void     XGI_DisplayOn(struct xgi_hw_device_info *, struct vb_device_info *);
-extern   void     XGI_GetVBType(struct vb_device_info *);
-extern   void     XGI_SenseCRT1(struct vb_device_info *);
-extern   void     XGI_GetVGAType(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *);
-extern   void     XGI_GetVBInfo(unsigned short ModeNo, unsigned short ModeIdIndex, struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *);
-extern   void     XGI_GetTVInfo(unsigned short ModeNo, unsigned short ModeIdIndex, struct vb_device_info *);
-extern   unsigned short   XGI_GetResInfo(unsigned short ModeNo, unsigned short ModeIdIndex, struct vb_device_info *pVBInfo);
+extern void InitTo330Pointer(unsigned char, struct vb_device_info *);
+extern void XGI_UnLockCRT2(struct xgi_hw_device_info *HwDeviceExtension,
+			   struct vb_device_info *);
+extern void XGI_LockCRT2(struct xgi_hw_device_info *HwDeviceExtension,
+			 struct vb_device_info *);
+extern void XGI_LongWait(struct vb_device_info *);
+extern void XGI_SetCRT2ModeRegs(unsigned short ModeNo,
+				struct xgi_hw_device_info *,
+				struct vb_device_info *);
+extern void XGI_DisableBridge(struct xgi_hw_device_info *HwDeviceExtension,
+			      struct vb_device_info *);
+extern void XGI_EnableBridge(struct xgi_hw_device_info *HwDeviceExtension,
+			     struct vb_device_info *);
+extern void XGI_DisplayOff(struct xgi_hw_device_info *,
+			   struct vb_device_info *);
+extern void XGI_DisplayOn(struct xgi_hw_device_info *,
+			  struct vb_device_info *);
+extern void XGI_GetVBType(struct vb_device_info *);
+extern void XGI_SenseCRT1(struct vb_device_info *);
+extern void XGI_GetVGAType(struct xgi_hw_device_info *HwDeviceExtension,
+			   struct vb_device_info *);
+extern void XGI_GetVBInfo(unsigned short ModeNo,
+			  unsigned short ModeIdIndex,
+			  struct xgi_hw_device_info *HwDeviceExtension,
+			  struct vb_device_info *);
+extern void XGI_GetTVInfo(unsigned short ModeNo,
+			  unsigned short ModeIdIndex,
+			  struct vb_device_info *);
+extern unsigned short XGI_GetResInfo(unsigned short ModeNo,
+				     unsigned short ModeIdIndex,
+				     struct vb_device_info *pVBInfo);
 
-extern   unsigned char  XGISetModeNew(struct xgi_hw_device_info *HwDeviceExtension, unsigned short ModeNo) ;
+extern unsigned char XGISetModeNew(struct xgi_hw_device_info *HwDeviceExtension,
+				   unsigned short ModeNo) ;
 
-extern   unsigned char  XGI_SearchModeID(unsigned short ModeNo, unsigned short  *ModeIdIndex, struct vb_device_info *);
-extern   unsigned char  XGI_GetLCDInfo(unsigned short ModeNo, unsigned short ModeIdIndex, struct vb_device_info *);
-extern   unsigned char  XGI_BridgeIsOn(struct vb_device_info *);
-extern   unsigned char  XGI_SetCRT2Group301(unsigned short ModeNo, struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *);
-extern   unsigned short   XGI_GetRatePtrCRT2(struct xgi_hw_device_info *pXGIHWDE, unsigned short ModeNo, unsigned short ModeIdIndex, struct vb_device_info *);
+extern unsigned char XGI_SearchModeID(unsigned short ModeNo,
+				      unsigned short *ModeIdIndex,
+				      struct vb_device_info *);
+extern unsigned char XGI_GetLCDInfo(unsigned short ModeNo,
+				    unsigned short ModeIdIndex,
+				    struct vb_device_info *);
+extern unsigned char XGI_BridgeIsOn(struct vb_device_info *);
 
-extern   void     XGI_SetXG21FPBits(struct vb_device_info *pVBInfo);
-extern   void     XGI_SetXG27FPBits(struct vb_device_info *pVBInfo);
-extern   void     XGI_XG21BLSignalVDD(unsigned short tempbh, unsigned short tempbl, struct vb_device_info *pVBInfo);
-extern   void     XGI_XG27BLSignalVDD(unsigned short tempbh, unsigned short tempbl, struct vb_device_info *pVBInfo);
-extern   void     XGI_XG21SetPanelDelay(unsigned short tempbl, struct vb_device_info *pVBInfo);
-extern   unsigned char  XGI_XG21CheckLVDSMode(unsigned short ModeNo, unsigned short ModeIdIndex, struct vb_device_info *pVBInfo);
-extern   unsigned short XGI_GetLVDSOEMTableIndex(struct vb_device_info *pVBInfo);
+extern unsigned char
+XGI_SetCRT2Group301(unsigned short ModeNo,
+		    struct xgi_hw_device_info *HwDeviceExtension,
+		    struct vb_device_info *);
+extern unsigned short XGI_GetRatePtrCRT2(struct xgi_hw_device_info *pXGIHWDE,
+					 unsigned short ModeNo,
+					 unsigned short ModeIdIndex,
+					 struct vb_device_info *);
+
+extern void XGI_SetXG21FPBits(struct vb_device_info *pVBInfo);
+extern void XGI_SetXG27FPBits(struct vb_device_info *pVBInfo);
+extern void XGI_XG21BLSignalVDD(unsigned short tempbh,
+				unsigned short tempbl,
+				struct vb_device_info *pVBInfo);
+extern void XGI_XG27BLSignalVDD(unsigned short tempbh,
+				unsigned short tempbl,
+				struct vb_device_info *pVBInfo);
+extern void XGI_XG21SetPanelDelay(unsigned short tempbl,
+				  struct vb_device_info *pVBInfo);
+extern unsigned char XGI_XG21CheckLVDSMode(unsigned short ModeNo,
+					   unsigned short ModeIdIndex,
+					   struct vb_device_info *pVBInfo);
+extern unsigned short XGI_GetLVDSOEMTableIndex(struct vb_device_info *pVBInfo);
 
 #endif
diff -druN linux-2.6.39-libre/drivers/staging/xgifb/vb_struct.h linux-3.0-rc7-libre/drivers/staging/xgifb/vb_struct.h
--- linux-2.6.39-libre/drivers/staging/xgifb/vb_struct.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/xgifb/vb_struct.h	2011-07-11 19:51:52.000000000 -0400
@@ -7,369 +7,324 @@
 #define EXTERN extern
 #endif
 
-
-
-
-struct XGI_PanelDelayTblStruct
-{
- unsigned char timer[2];
+struct XGI_PanelDelayTblStruct {
+	unsigned char timer[2];
 };
 
-struct XGI_LCDDataStruct
-{
- unsigned short RVBHCMAX;
- unsigned short RVBHCFACT;
- unsigned short VGAHT;
- unsigned short VGAVT;
- unsigned short LCDHT;
- unsigned short LCDVT;
+struct XGI_LCDDataStruct {
+	unsigned short RVBHCMAX;
+	unsigned short RVBHCFACT;
+	unsigned short VGAHT;
+	unsigned short VGAVT;
+	unsigned short LCDHT;
+	unsigned short LCDVT;
 };
 
 
-struct XGI_LVDSCRT1HDataStruct
-{
- unsigned char Reg[8];
+struct XGI_LVDSCRT1HDataStruct {
+	unsigned char Reg[8];
 };
 
-struct XGI_LVDSCRT1VDataStruct
-{
- unsigned char Reg[7];
+struct XGI_LVDSCRT1VDataStruct {
+	unsigned char Reg[7];
 };
 
-
-struct XGI_TVDataStruct
-{
- unsigned short RVBHCMAX;
- unsigned short RVBHCFACT;
- unsigned short VGAHT;
- unsigned short VGAVT;
- unsigned short TVHDE;
- unsigned short TVVDE;
- unsigned short RVBHRS;
- unsigned char FlickerMode;
- unsigned short HALFRVBHRS;
- unsigned char RY1COE;
- unsigned char RY2COE;
- unsigned char RY3COE;
- unsigned char RY4COE;
+struct XGI_TVDataStruct {
+	unsigned short RVBHCMAX;
+	unsigned short RVBHCFACT;
+	unsigned short VGAHT;
+	unsigned short VGAVT;
+	unsigned short TVHDE;
+	unsigned short TVVDE;
+	unsigned short RVBHRS;
+	unsigned char FlickerMode;
+	unsigned short HALFRVBHRS;
+	unsigned char RY1COE;
+	unsigned char RY2COE;
+	unsigned char RY3COE;
+	unsigned char RY4COE;
 };
 
-struct XGI_LVDSDataStruct
-{
- unsigned short VGAHT;
- unsigned short VGAVT;
- unsigned short LCDHT;
- unsigned short LCDVT;
+struct XGI_LVDSDataStruct {
+	unsigned short VGAHT;
+	unsigned short VGAVT;
+	unsigned short LCDHT;
+	unsigned short LCDVT;
 };
 
-struct XGI_LVDSDesStruct
-{
- unsigned short LCDHDES;
- unsigned short LCDVDES;
+struct XGI_LVDSDesStruct {
+	unsigned short LCDHDES;
+	unsigned short LCDVDES;
 };
 
-struct XGI_LVDSCRT1DataStruct
-{
- unsigned char CR[15];
+struct XGI_LVDSCRT1DataStruct {
+	unsigned char CR[15];
 };
 
 /*add for LCDA*/
 
-struct XGI_StStruct
-{
- unsigned char St_ModeID;
- unsigned short St_ModeFlag;
- unsigned char St_StTableIndex;
- unsigned char St_CRT2CRTC;
- unsigned char St_CRT2CRTC2;
- unsigned char St_ResInfo;
- unsigned char VB_StTVFlickerIndex;
- unsigned char VB_StTVEdgeIndex;
- unsigned char VB_StTVYFilterIndex;
+struct XGI_StStruct {
+	unsigned char St_ModeID;
+	unsigned short St_ModeFlag;
+	unsigned char St_StTableIndex;
+	unsigned char St_CRT2CRTC;
+	unsigned char St_CRT2CRTC2;
+	unsigned char St_ResInfo;
+	unsigned char VB_StTVFlickerIndex;
+	unsigned char VB_StTVEdgeIndex;
+	unsigned char VB_StTVYFilterIndex;
 };
 
-struct XGI_StandTableStruct
-{
- unsigned char CRT_COLS;
- unsigned char ROWS;
- unsigned char CHAR_HEIGHT;
- unsigned short CRT_LEN;
- unsigned char SR[4];
- unsigned char MISC;
- unsigned char CRTC[0x19];
- unsigned char ATTR[0x14];
- unsigned char GRC[9];
+struct XGI_StandTableStruct {
+	unsigned char CRT_COLS;
+	unsigned char ROWS;
+	unsigned char CHAR_HEIGHT;
+	unsigned short CRT_LEN;
+	unsigned char SR[4];
+	unsigned char MISC;
+	unsigned char CRTC[0x19];
+	unsigned char ATTR[0x14];
+	unsigned char GRC[9];
 };
 
-struct XGI_ExtStruct
-{
- unsigned char Ext_ModeID;
- unsigned short Ext_ModeFlag;
- unsigned short Ext_ModeInfo;
- unsigned short Ext_Point;
- unsigned short Ext_VESAID;
- unsigned char Ext_VESAMEMSize;
- unsigned char Ext_RESINFO;
- unsigned char VB_ExtTVFlickerIndex;
- unsigned char VB_ExtTVEdgeIndex;
- unsigned char VB_ExtTVYFilterIndex;
- unsigned char REFindex;
+struct XGI_ExtStruct {
+	unsigned char Ext_ModeID;
+	unsigned short Ext_ModeFlag;
+	unsigned short Ext_ModeInfo;
+	unsigned short Ext_Point;
+	unsigned short Ext_VESAID;
+	unsigned char Ext_VESAMEMSize;
+	unsigned char Ext_RESINFO;
+	unsigned char VB_ExtTVFlickerIndex;
+	unsigned char VB_ExtTVEdgeIndex;
+	unsigned char VB_ExtTVYFilterIndex;
+	unsigned char REFindex;
 };
 
-struct XGI_Ext2Struct
-{
- unsigned short Ext_InfoFlag;
- unsigned char Ext_CRT1CRTC;
- unsigned char Ext_CRTVCLK;
- unsigned char Ext_CRT2CRTC;
- unsigned char Ext_CRT2CRTC2;
- unsigned char  ModeID;
- unsigned short XRes;
- unsigned short YRes;
- /* unsigned short ROM_OFFSET; */
+struct XGI_Ext2Struct {
+	unsigned short Ext_InfoFlag;
+	unsigned char Ext_CRT1CRTC;
+	unsigned char Ext_CRTVCLK;
+	unsigned char Ext_CRT2CRTC;
+	unsigned char Ext_CRT2CRTC2;
+	unsigned char  ModeID;
+	unsigned short XRes;
+	unsigned short YRes;
+	/* unsigned short ROM_OFFSET; */
 };
 
 
-struct XGI_MCLKDataStruct
-{
- unsigned char SR28, SR29, SR2A;
- unsigned short CLOCK;
+struct XGI_MCLKDataStruct {
+	unsigned char SR28, SR29, SR2A;
+	unsigned short CLOCK;
 };
 
-struct XGI_ECLKDataStruct
-{
- unsigned char SR2E, SR2F, SR30;
- unsigned short CLOCK;
+struct XGI_ECLKDataStruct {
+	unsigned char SR2E, SR2F, SR30;
+	unsigned short CLOCK;
 };
 
-struct XGI_VCLKDataStruct
-{
- unsigned char SR2B, SR2C;
- unsigned short CLOCK;
+struct XGI_VCLKDataStruct {
+	unsigned char SR2B, SR2C;
+	unsigned short CLOCK;
 };
 
-struct XGI_VBVCLKDataStruct
-{
- unsigned char Part4_A, Part4_B;
- unsigned short CLOCK;
+struct XGI_VBVCLKDataStruct {
+	unsigned char Part4_A, Part4_B;
+	unsigned short CLOCK;
 };
 
-struct XGI_StResInfoStruct
-{
- unsigned short HTotal;
- unsigned short VTotal;
+struct XGI_StResInfoStruct {
+	unsigned short HTotal;
+	unsigned short VTotal;
 };
 
-struct XGI_ModeResInfoStruct
-{
- unsigned short HTotal;
- unsigned short VTotal;
- unsigned char  XChar;
- unsigned char  YChar;
+struct XGI_ModeResInfoStruct {
+	unsigned short HTotal;
+	unsigned short VTotal;
+	unsigned char  XChar;
+	unsigned char  YChar;
 };
 
-struct XGI_LCDNBDesStruct
-{
-  unsigned char NB[12];
+struct XGI_LCDNBDesStruct {
+	unsigned char NB[12];
 };
- /*add for new UNIVGABIOS*/
-struct XGI_LCDDesStruct
-{
- unsigned short LCDHDES;
- unsigned short LCDHRS;
- unsigned short LCDVDES;
- unsigned short LCDVRS;
+
+/*add for new UNIVGABIOS*/
+struct XGI_LCDDesStruct {
+	unsigned short LCDHDES;
+	unsigned short LCDHRS;
+	unsigned short LCDVDES;
+	unsigned short LCDVRS;
 };
 
-struct XGI_LCDDataTablStruct
-{
- unsigned char  PANELID;
- unsigned short MASK;
- unsigned short CAP;
- unsigned short DATAPTR;
+struct XGI_LCDDataTablStruct {
+	unsigned char  PANELID;
+	unsigned short MASK;
+	unsigned short CAP;
+	unsigned short DATAPTR;
 };
 
-struct XGI_TVTablDataStruct
-{
- unsigned short MASK;
- unsigned short CAP;
- unsigned short DATAPTR;
+struct XGI_TVTablDataStruct {
+	unsigned short MASK;
+	unsigned short CAP;
+	unsigned short DATAPTR;
 };
 
-struct XGI330_LCDDataDesStruct
-{
- unsigned short LCDHDES;
- unsigned short LCDHRS;
- unsigned short LCDVDES;
- unsigned short LCDVRS;
+struct XGI330_LCDDataDesStruct {
+	unsigned short LCDHDES;
+	unsigned short LCDHRS;
+	unsigned short LCDVDES;
+	unsigned short LCDVRS;
 };
 
 
-struct XGI330_LVDSDataStruct
-{
- unsigned short VGAHT;
- unsigned short VGAVT;
- unsigned short LCDHT;
- unsigned short LCDVT;
+struct XGI330_LVDSDataStruct {
+	unsigned short VGAHT;
+	unsigned short VGAVT;
+	unsigned short LCDHT;
+	unsigned short LCDVT;
 };
 
-struct XGI330_LCDDataDesStruct2
-{
- unsigned short LCDHDES;
- unsigned short LCDHRS;
- unsigned short LCDVDES;
- unsigned short LCDVRS;
- unsigned short LCDHSync;
- unsigned short LCDVSync;
+struct XGI330_LCDDataDesStruct2 {
+	unsigned short LCDHDES;
+	unsigned short LCDHRS;
+	unsigned short LCDVDES;
+	unsigned short LCDVRS;
+	unsigned short LCDHSync;
+	unsigned short LCDVSync;
 };
 
-struct XGI330_LCDDataStruct
-{
- unsigned short RVBHCMAX;
- unsigned short RVBHCFACT;
- unsigned short VGAHT;
- unsigned short VGAVT;
- unsigned short LCDHT;
- unsigned short LCDVT;
+struct XGI330_LCDDataStruct {
+	unsigned short RVBHCMAX;
+	unsigned short RVBHCFACT;
+	unsigned short VGAHT;
+	unsigned short VGAVT;
+	unsigned short LCDHT;
+	unsigned short LCDVT;
 };
 
 
-struct XGI330_TVDataStruct
-{
- unsigned short RVBHCMAX;
- unsigned short RVBHCFACT;
- unsigned short VGAHT;
- unsigned short VGAVT;
- unsigned short TVHDE;
- unsigned short TVVDE;
- unsigned short RVBHRS;
- unsigned char FlickerMode;
- unsigned short HALFRVBHRS;
+struct XGI330_TVDataStruct {
+	unsigned short RVBHCMAX;
+	unsigned short RVBHCFACT;
+	unsigned short VGAHT;
+	unsigned short VGAVT;
+	unsigned short TVHDE;
+	unsigned short TVVDE;
+	unsigned short RVBHRS;
+	unsigned char FlickerMode;
+	unsigned short HALFRVBHRS;
 };
 
-struct XGI330_LCDDataTablStruct
-{
- unsigned char  PANELID;
- unsigned short MASK;
- unsigned short CAP;
- unsigned short DATAPTR;
+struct XGI330_LCDDataTablStruct {
+	unsigned char  PANELID;
+	unsigned short MASK;
+	unsigned short CAP;
+	unsigned short DATAPTR;
 };
 
-struct XGI330_TVDataTablStruct
-{
- unsigned short MASK;
- unsigned short CAP;
- unsigned short DATAPTR;
+struct XGI330_TVDataTablStruct {
+	unsigned short MASK;
+	unsigned short CAP;
+	unsigned short DATAPTR;
 };
 
 
-struct XGI330_CHTVDataStruct
-{
- unsigned short VGAHT;
- unsigned short VGAVT;
- unsigned short LCDHT;
- unsigned short LCDVT;
+struct XGI330_CHTVDataStruct {
+	unsigned short VGAHT;
+	unsigned short VGAVT;
+	unsigned short LCDHT;
+	unsigned short LCDVT;
 };
 
-struct XGI_TimingHStruct
-{
-  unsigned char data[8];
+struct XGI_TimingHStruct {
+	unsigned char data[8];
 };
 
-struct XGI_TimingVStruct
-{
-  unsigned char data[7];
+struct XGI_TimingVStruct {
+	unsigned char data[7];
 };
 
-struct XGI_CH7007TV_TimingHStruct
-{
-  unsigned char data[10];
+struct XGI_CH7007TV_TimingHStruct {
+	unsigned char data[10];
 };
 
-struct XGI_CH7007TV_TimingVStruct
-{
-  unsigned char data[10];
+struct XGI_CH7007TV_TimingVStruct {
+	unsigned char data[10];
 };
 
-struct XGI_XG21CRT1Struct
-{
- unsigned char ModeID, CR02, CR03, CR15, CR16;
+struct XGI_XG21CRT1Struct {
+	unsigned char ModeID, CR02, CR03, CR15, CR16;
 };
 
-struct XGI330_CHTVRegDataStruct
-{
- unsigned char Reg[16];
+struct XGI330_CHTVRegDataStruct {
+	unsigned char Reg[16];
 };
 
-struct XGI330_LCDCapStruct
-{
-		unsigned char	   LCD_ID;
-		unsigned short	   LCD_Capability;
-		unsigned char	   LCD_SetFlag;
-		unsigned char	   LCD_DelayCompensation;
-		unsigned char	   LCD_HSyncWidth;
-		unsigned char	   LCD_VSyncWidth;
-		unsigned char	   LCD_VCLK;
-		unsigned char	   LCDA_VCLKData1;
-		unsigned char	   LCDA_VCLKData2;
-		unsigned char	   LCUCHAR_VCLKData1;
-		unsigned char	   LCUCHAR_VCLKData2;
-		unsigned char	   PSC_S1;
-		unsigned char	   PSC_S2;
-		unsigned char	   PSC_S3;
-		unsigned char	   PSC_S4;
-		unsigned char	   PSC_S5;
-		unsigned char	   PWD_2B;
-		unsigned char	   PWD_2C;
-		unsigned char	   PWD_2D;
-		unsigned char	   PWD_2E;
-		unsigned char	   PWD_2F;
-		unsigned char	   Spectrum_31;
-		unsigned char	   Spectrum_32;
-		unsigned char	   Spectrum_33;
-		unsigned char	   Spectrum_34;
+struct XGI330_LCDCapStruct {
+	unsigned char	LCD_ID;
+	unsigned short	LCD_Capability;
+	unsigned char	LCD_SetFlag;
+	unsigned char	LCD_DelayCompensation;
+	unsigned char	LCD_HSyncWidth;
+	unsigned char	LCD_VSyncWidth;
+	unsigned char	LCD_VCLK;
+	unsigned char	LCDA_VCLKData1;
+	unsigned char	LCDA_VCLKData2;
+	unsigned char	LCUCHAR_VCLKData1;
+	unsigned char	LCUCHAR_VCLKData2;
+	unsigned char	PSC_S1;
+	unsigned char	PSC_S2;
+	unsigned char	PSC_S3;
+	unsigned char	PSC_S4;
+	unsigned char	PSC_S5;
+	unsigned char	PWD_2B;
+	unsigned char	PWD_2C;
+	unsigned char	PWD_2D;
+	unsigned char	PWD_2E;
+	unsigned char	PWD_2F;
+	unsigned char	Spectrum_31;
+	unsigned char	Spectrum_32;
+	unsigned char	Spectrum_33;
+	unsigned char	Spectrum_34;
 };
 
-struct XGI21_LVDSCapStruct
-{
-		unsigned short	   LVDS_Capability;
-		unsigned short	   LVDSHT;
-		unsigned short	   LVDSVT;
-		unsigned short	   LVDSHDE;
-		unsigned short	   LVDSVDE;
-		unsigned short	   LVDSHFP;
-		unsigned short	   LVDSVFP;
-		unsigned short	   LVDSHSYNC;
-		unsigned short	   LVDSVSYNC;
-		unsigned char	   VCLKData1;
-		unsigned char	   VCLKData2;
-		unsigned char	   PSC_S1;
-		unsigned char	   PSC_S2;
-		unsigned char	   PSC_S3;
-		unsigned char	   PSC_S4;
-		unsigned char	   PSC_S5;
+struct XGI21_LVDSCapStruct {
+	unsigned short LVDS_Capability;
+	unsigned short LVDSHT;
+	unsigned short LVDSVT;
+	unsigned short LVDSHDE;
+	unsigned short LVDSVDE;
+	unsigned short LVDSHFP;
+	unsigned short LVDSVFP;
+	unsigned short LVDSHSYNC;
+	unsigned short LVDSVSYNC;
+	unsigned char  VCLKData1;
+	unsigned char  VCLKData2;
+	unsigned char  PSC_S1;
+	unsigned char  PSC_S2;
+	unsigned char  PSC_S3;
+	unsigned char  PSC_S4;
+	unsigned char  PSC_S5;
 };
 
-struct XGI_CRT1TableStruct
-{
-  unsigned char CR[16];
+struct XGI_CRT1TableStruct {
+	unsigned char CR[16];
 };
 
 
-struct XGI330_VCLKDataStruct
-{
-    unsigned char SR2B, SR2C;
-    unsigned short CLOCK;
+struct XGI330_VCLKDataStruct {
+	unsigned char SR2B, SR2C;
+	unsigned short CLOCK;
 };
 
-struct XGI301C_Tap4TimingStruct
-{
-    unsigned short DE;
-    unsigned char  Reg[64];   /* C0-FF */
+struct XGI301C_Tap4TimingStruct {
+	unsigned short DE;
+	unsigned char  Reg[64];   /* C0-FF */
 };
 
-struct XGI_New_StandTableStruct
-{
+struct XGI_New_StandTableStruct {
 	unsigned char  CRT_COLS;
 	unsigned char  ROWS;
 	unsigned char  CHAR_HEIGHT;
@@ -381,36 +336,37 @@
 	unsigned char  GRC[9];
 };
 
-struct vb_device_info
-{
-    unsigned char  ISXPDOS;
-    unsigned long   P3c4,P3d4,P3c0,P3ce,P3c2,P3cc;
-    unsigned long   P3ca,P3c6,P3c7,P3c8,P3c9,P3da;
-    unsigned long   Part0Port,Part1Port,Part2Port;
-    unsigned long   Part3Port,Part4Port,Part5Port;
-    unsigned short   RVBHCFACT,RVBHCMAX,RVBHRS;
-    unsigned short   VGAVT,VGAHT,VGAVDE,VGAHDE;
-    unsigned short   VT,HT,VDE,HDE;
-    unsigned short   LCDHRS,LCDVRS,LCDHDES,LCDVDES;
+struct vb_device_info {
+	unsigned char  ISXPDOS;
+	unsigned long   P3c4, P3d4, P3c0, P3ce, P3c2, P3cc;
+	unsigned long   P3ca, P3c6, P3c7, P3c8, P3c9, P3da;
+	unsigned long   Part0Port, Part1Port, Part2Port;
+	unsigned long   Part3Port, Part4Port, Part5Port;
+	unsigned short   RVBHCFACT, RVBHCMAX, RVBHRS;
+	unsigned short   VGAVT, VGAHT, VGAVDE, VGAHDE;
+	unsigned short   VT, HT, VDE, HDE;
+	unsigned short   LCDHRS, LCDVRS, LCDHDES, LCDVDES;
 
-    unsigned short   ModeType;
-    unsigned short   IF_DEF_LVDS,IF_DEF_TRUMPION,IF_DEF_DSTN;/* ,IF_DEF_FSTN; add for dstn */
-    unsigned short   IF_DEF_CRT2Monitor,IF_DEF_VideoCapture;
-    unsigned short   IF_DEF_LCDA,IF_DEF_CH7017,IF_DEF_YPbPr,IF_DEF_ScaleLCD,IF_DEF_OEMUtil,IF_DEF_PWD;
-    unsigned short   IF_DEF_ExpLink;
-    unsigned short   IF_DEF_CH7005,IF_DEF_HiVision;
-    unsigned short   IF_DEF_CH7007; /* Billy 2007/05/03 */
-    unsigned short   LCDResInfo,LCDTypeInfo, VBType;/*301b*/
-    unsigned short   VBInfo,TVInfo,LCDInfo, Set_VGAType;
-    unsigned short   VBExtInfo;/*301lv*/
-    unsigned short   SetFlag;
-    unsigned short   NewFlickerMode;
-    unsigned short   SelectCRT2Rate;
+	unsigned short   ModeType;
+	/* ,IF_DEF_FSTN; add for dstn */
+	unsigned short   IF_DEF_LVDS, IF_DEF_TRUMPION, IF_DEF_DSTN;
+	unsigned short   IF_DEF_CRT2Monitor, IF_DEF_VideoCapture;
+	unsigned short   IF_DEF_LCDA, IF_DEF_CH7017, IF_DEF_YPbPr,
+			 IF_DEF_ScaleLCD, IF_DEF_OEMUtil, IF_DEF_PWD;
+	unsigned short   IF_DEF_ExpLink;
+	unsigned short   IF_DEF_CH7005, IF_DEF_HiVision;
+	unsigned short   IF_DEF_CH7007; /* Billy 2007/05/03 */
+	unsigned short   LCDResInfo, LCDTypeInfo, VBType;/*301b*/
+	unsigned short   VBInfo, TVInfo, LCDInfo, Set_VGAType;
+	unsigned short   VBExtInfo;/*301lv*/
+	unsigned short   SetFlag;
+	unsigned short   NewFlickerMode;
+	unsigned short   SelectCRT2Rate;
 
-    unsigned char *ROMAddr;
-    unsigned char *FBAddr;
-    unsigned long BaseAddr;
-    unsigned long RelIO;
+	unsigned char *ROMAddr;
+	unsigned char *FBAddr;
+	unsigned long BaseAddr;
+	unsigned long RelIO;
 
 	unsigned char (*CR6B)[4];
 	unsigned char (*CR6E)[4];
@@ -420,107 +376,106 @@
 	unsigned char (*SR15)[8];
 	unsigned char (*CR40)[8];
 
-    unsigned char  *pSoftSetting;
-    unsigned char  *pOutputSelect;
+	unsigned char  *pSoftSetting;
+	unsigned char  *pOutputSelect;
 
-    unsigned short *pRGBSenseData;
-    unsigned short *pRGBSenseData2; /*301b*/
-    unsigned short *pVideoSenseData;
-    unsigned short *pVideoSenseData2;
-    unsigned short *pYCSenseData;
-    unsigned short *pYCSenseData2;
+	unsigned short *pRGBSenseData;
+	unsigned short *pRGBSenseData2; /*301b*/
+	unsigned short *pVideoSenseData;
+	unsigned short *pVideoSenseData2;
+	unsigned short *pYCSenseData;
+	unsigned short *pYCSenseData2;
 
-    unsigned char  *pSR07;
-    unsigned char  *CR49;
-    unsigned char  *pSR1F;
-    unsigned char  *AGPReg;
-    unsigned char  *SR16;
-    unsigned char  *pSR21;
-    unsigned char  *pSR22;
-    unsigned char  *pSR23;
-    unsigned char  *pSR24;
-    unsigned char  *SR25;
-    unsigned char  *pSR31;
-    unsigned char  *pSR32;
-    unsigned char  *pSR33;
-    unsigned char  *pSR36;      /* alan 12/07/2006 */
-    unsigned char  *pCRCF;
-    unsigned char  *pCRD0;      /* alan 12/07/2006 */
-    unsigned char  *pCRDE;      /* alan 12/07/2006 */
-    unsigned char  *pCR8F;      /* alan 12/07/2006 */
-    unsigned char  *pSR40;      /* alan 12/07/2006 */
-    unsigned char  *pSR41;      /* alan 12/07/2006 */
-    unsigned char  *pDVOSetting;
-    unsigned char  *pCR2E;
-    unsigned char  *pCR2F;
-    unsigned char  *pCR46;
-    unsigned char  *pCR47;
-    unsigned char  *pCRT2Data_1_2;
-    unsigned char  *pCRT2Data_4_D;
-    unsigned char  *pCRT2Data_4_E;
-    unsigned char  *pCRT2Data_4_10;
-    struct XGI_MCLKDataStruct  *MCLKData;
-    struct XGI_ECLKDataStruct  *ECLKData;
+	unsigned char  *pSR07;
+	unsigned char  *CR49;
+	unsigned char  *pSR1F;
+	unsigned char  *AGPReg;
+	unsigned char  *SR16;
+	unsigned char  *pSR21;
+	unsigned char  *pSR22;
+	unsigned char  *pSR23;
+	unsigned char  *pSR24;
+	unsigned char  *SR25;
+	unsigned char  *pSR31;
+	unsigned char  *pSR32;
+	unsigned char  *pSR33;
+	unsigned char  *pSR36;      /* alan 12/07/2006 */
+	unsigned char  *pCRCF;
+	unsigned char  *pCRD0;      /* alan 12/07/2006 */
+	unsigned char  *pCRDE;      /* alan 12/07/2006 */
+	unsigned char  *pCR8F;      /* alan 12/07/2006 */
+	unsigned char  *pSR40;      /* alan 12/07/2006 */
+	unsigned char  *pSR41;      /* alan 12/07/2006 */
+	unsigned char  *pDVOSetting;
+	unsigned char  *pCR2E;
+	unsigned char  *pCR2F;
+	unsigned char  *pCR46;
+	unsigned char  *pCR47;
+	unsigned char  *pCRT2Data_1_2;
+	unsigned char  *pCRT2Data_4_D;
+	unsigned char  *pCRT2Data_4_E;
+	unsigned char  *pCRT2Data_4_10;
+	struct XGI_MCLKDataStruct  *MCLKData;
+	struct XGI_ECLKDataStruct  *ECLKData;
 
-    unsigned char   *XGI_TVDelayList;
-    unsigned char   *XGI_TVDelayList2;
-    unsigned char   *CHTVVCLKUNTSC;
-    unsigned char   *CHTVVCLKONTSC;
-    unsigned char   *CHTVVCLKUPAL;
-    unsigned char   *CHTVVCLKOPAL;
-    unsigned char   *NTSCTiming;
-    unsigned char   *PALTiming;
-    unsigned char   *HiTVExtTiming;
-    unsigned char   *HiTVSt1Timing;
-    unsigned char   *HiTVSt2Timing;
-    unsigned char   *HiTVTextTiming;
-    unsigned char   *YPbPr750pTiming;
-    unsigned char   *YPbPr525pTiming;
-    unsigned char   *YPbPr525iTiming;
-    unsigned char   *HiTVGroup3Data;
-    unsigned char   *HiTVGroup3Simu;
-    unsigned char   *HiTVGroup3Text;
-    unsigned char   *Ren525pGroup3;
-    unsigned char   *Ren750pGroup3;
-    unsigned char   *ScreenOffset;
-    unsigned char   *pXGINew_DRAMTypeDefinition;
-    unsigned char   *pXGINew_I2CDefinition ;
-    unsigned char   *pXGINew_CR97 ;
+	unsigned char   *XGI_TVDelayList;
+	unsigned char   *XGI_TVDelayList2;
+	unsigned char   *CHTVVCLKUNTSC;
+	unsigned char   *CHTVVCLKONTSC;
+	unsigned char   *CHTVVCLKUPAL;
+	unsigned char   *CHTVVCLKOPAL;
+	unsigned char   *NTSCTiming;
+	unsigned char   *PALTiming;
+	unsigned char   *HiTVExtTiming;
+	unsigned char   *HiTVSt1Timing;
+	unsigned char   *HiTVSt2Timing;
+	unsigned char   *HiTVTextTiming;
+	unsigned char   *YPbPr750pTiming;
+	unsigned char   *YPbPr525pTiming;
+	unsigned char   *YPbPr525iTiming;
+	unsigned char   *HiTVGroup3Data;
+	unsigned char   *HiTVGroup3Simu;
+	unsigned char   *HiTVGroup3Text;
+	unsigned char   *Ren525pGroup3;
+	unsigned char   *Ren750pGroup3;
+	unsigned char   *ScreenOffset;
+	unsigned char   *pXGINew_DRAMTypeDefinition;
+	unsigned char   *pXGINew_I2CDefinition ;
+	unsigned char   *pXGINew_CR97 ;
 
-    struct XGI330_LCDCapStruct  *LCDCapList;
-    struct XGI21_LVDSCapStruct  *XG21_LVDSCapList;
+	struct XGI330_LCDCapStruct  *LCDCapList;
+	struct XGI21_LVDSCapStruct  *XG21_LVDSCapList;
 
-    struct XGI_TimingHStruct  *TimingH;
-    struct XGI_TimingVStruct  *TimingV;
+	struct XGI_TimingHStruct  *TimingH;
+	struct XGI_TimingVStruct  *TimingV;
 
-    struct XGI_StStruct          *SModeIDTable;
-    struct XGI_StandTableStruct  *StandTable;
-    struct XGI_ExtStruct         *EModeIDTable;
-    struct XGI_Ext2Struct        *RefIndex;
-    /* XGINew_CRT1TableStruct *CRT1Table; */
-    struct XGI_CRT1TableStruct    *XGINEWUB_CRT1Table;
-    struct XGI_VCLKDataStruct    *VCLKData;
-    struct XGI_VBVCLKDataStruct  *VBVCLKData;
-    struct XGI_StResInfoStruct   *StResInfo;
-    struct XGI_ModeResInfoStruct *ModeResInfo;
-    struct XGI_XG21CRT1Struct	  *UpdateCRT1;
+	struct XGI_StStruct          *SModeIDTable;
+	struct XGI_StandTableStruct  *StandTable;
+	struct XGI_ExtStruct         *EModeIDTable;
+	struct XGI_Ext2Struct        *RefIndex;
+	/* XGINew_CRT1TableStruct *CRT1Table; */
+	struct XGI_CRT1TableStruct    *XGINEWUB_CRT1Table;
+	struct XGI_VCLKDataStruct    *VCLKData;
+	struct XGI_VBVCLKDataStruct  *VBVCLKData;
+	struct XGI_StResInfoStruct   *StResInfo;
+	struct XGI_ModeResInfoStruct *ModeResInfo;
+	struct XGI_XG21CRT1Struct	  *UpdateCRT1;
 };  /* _struct vb_device_info */
 
 
-struct TimingInfo
-{
-    unsigned short    Horizontal_ACTIVE;
-    unsigned short    Horizontal_FP;
-    unsigned short    Horizontal_SYNC;
-    unsigned short    Horizontal_BP;
-    unsigned short    Vertical_ACTIVE;
-    unsigned short    Vertical_FP;
-    unsigned short    Vertical_SYNC;
-    unsigned short    Vertical_BP;
-    double    DCLK;
-    unsigned char     FrameRate;
-    unsigned char     Interlace;
-    unsigned short    Margin;
+struct TimingInfo {
+	unsigned short Horizontal_ACTIVE;
+	unsigned short Horizontal_FP;
+	unsigned short Horizontal_SYNC;
+	unsigned short Horizontal_BP;
+	unsigned short Vertical_ACTIVE;
+	unsigned short Vertical_FP;
+	unsigned short Vertical_SYNC;
+	unsigned short Vertical_BP;
+	double	       DCLK;
+	unsigned char  FrameRate;
+	unsigned char  Interlace;
+	unsigned short Margin;
 };
 
 #define _VB_STRUCT_
diff -druN linux-2.6.39-libre/drivers/staging/xgifb/vb_table.h linux-3.0-rc7-libre/drivers/staging/xgifb/vb_table.h
--- linux-2.6.39-libre/drivers/staging/xgifb/vb_table.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/xgifb/vb_table.h	2011-07-11 19:51:52.000000000 -0400
@@ -1,186 +1,206 @@
 #define  Tap4
 
-//yilin modify for xgi20
-static struct XGI_MCLKDataStruct XGI340New_MCLKData[] =
-{
- { 0x16,0x01,0x01,166},
- { 0x19,0x02,0x01,124},
- { 0x7C,0x08,0x01,200},
- { 0x79,0x06,0x01,250},
- { 0x29,0x01,0x81,301},
- { 0x5c,0x23,0x01,166},
- { 0x5c,0x23,0x01,166},
- { 0x5c,0x23,0x01,166}
+/* yilin modify for xgi20 */
+static struct XGI_MCLKDataStruct XGI340New_MCLKData[] = {
+	{0x16, 0x01, 0x01, 166},
+	{0x19, 0x02, 0x01, 124},
+	{0x7C, 0x08, 0x01, 200},
+	{0x79, 0x06, 0x01, 250},
+	{0x29, 0x01, 0x81, 301},
+	{0x5c, 0x23, 0x01, 166},
+	{0x5c, 0x23, 0x01, 166},
+	{0x5c, 0x23, 0x01, 166}
 };
 
-static struct XGI_MCLKDataStruct XGI27New_MCLKData[] =
-{
- { 0x5c,0x23,0x01,166},
- { 0x19,0x02,0x01,124},
- { 0x7C,0x08,0x80,200},
- { 0x79,0x06,0x80,250},
- { 0x29,0x01,0x81,300},
- { 0x5c,0x23,0x01,166},
- { 0x5c,0x23,0x01,166},
- { 0x5c,0x23,0x01,166}
+static struct XGI_MCLKDataStruct XGI27New_MCLKData[] = {
+	{0x5c, 0x23, 0x01, 166},
+	{0x19, 0x02, 0x01, 124},
+	{0x7C, 0x08, 0x80, 200},
+	{0x79, 0x06, 0x80, 250},
+	{0x29, 0x01, 0x81, 300},
+	{0x5c, 0x23, 0x01, 166},
+	{0x5c, 0x23, 0x01, 166},
+	{0x5c, 0x23, 0x01, 166}
 };
 
-//yilin modify for xgi20
-static struct XGI_ECLKDataStruct XGI340_ECLKData[] =
-{
- { 0x5c,0x23,0x01,166},
- { 0x55,0x84,0x01,123},
- { 0x7C,0x08,0x01,200},
- { 0x79,0x06,0x01,250},
- { 0x29,0x01,0x81,301},
- { 0x5c,0x23,0x01,166},
- { 0x5c,0x23,0x01,166},
- { 0x5c,0x23,0x01,166}
+/* yilin modify for xgi20 */
+static struct XGI_ECLKDataStruct XGI340_ECLKData[] = {
+	{0x5c, 0x23, 0x01, 166},
+	{0x55, 0x84, 0x01, 123},
+	{0x7C, 0x08, 0x01, 200},
+	{0x79, 0x06, 0x01, 250},
+	{0x29, 0x01, 0x81, 301},
+	{0x5c, 0x23, 0x01, 166},
+	{0x5c, 0x23, 0x01, 166},
+	{0x5c, 0x23, 0x01, 166}
 };
 
-
-
 static unsigned char XGI340_SR13[4][8] = {
-{0x35,0x45,0xb1,0x00,0x00,0x00,0x00,0x00},/* SR13 */
-{0x41,0x51,0x5c,0x00,0x00,0x00,0x00,0x00},/* SR14 */
-{0x31,0x42,0x42,0x00,0x00,0x00,0x00,0x00},/* SR18 */
-{0x03,0x03,0x03,0x00,0x00,0x00,0x00,0x00}/* SR1B */
+	{0x35, 0x45, 0xb1, 0x00, 0x00, 0x00, 0x00, 0x00}, /* SR13 */
+	{0x41, 0x51, 0x5c, 0x00, 0x00, 0x00, 0x00, 0x00}, /* SR14 */
+	{0x31, 0x42, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00}, /* SR18 */
+	{0x03, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00}  /* SR1B */
 };
 
-static unsigned char XGI340_cr41[24][8] =
-{{0x20,0x50,0x60,0x00,0x00,0x00,0x00,0x00},/* 0 CR41 */
-{0xc4,0x40,0x84,0x00,0x00,0x00,0x00,0x00},/* 1 CR8A */
-{0xc4,0x40,0x84,0x00,0x00,0x00,0x00,0x00},/* 2 CR8B */
-{0xb5,0xa4,0xa4,0x00,0x00,0x00,0x00,0x00},
-{0xf0,0xf0,0xf0,0x00,0x00,0x00,0x00,0x00},
-{0x90,0x90,0x24,0x00,0x00,0x00,0x00,0x00},/* 5 CR68 */
-{0x77,0x77,0x44,0x00,0x00,0x00,0x00,0x00},/* 6 CR69 */
-{0x77,0x77,0x44,0x00,0x00,0x00,0x00,0x00},/* 7 CR6A */
-{0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00},/* 8 CR6D */
-{0x55,0x55,0x55,0x00,0x00,0x00,0x00,0x00},/* 9 CR80 */
-{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/* 10 CR81 */
-{0x88,0xa8,0x48,0x00,0x00,0x00,0x00,0x00},/* 11 CR82 */
-{0x44,0x44,0x77,0x00,0x00,0x00,0x00,0x00},/* 12 CR85 */
-{0x48,0x48,0x88,0x00,0x00,0x00,0x00,0x00},/* 13 CR86 */
-{0x54,0x54,0x44,0x00,0x00,0x00,0x00,0x00},/* 14 CR90 */
-{0x54,0x54,0x44,0x00,0x00,0x00,0x00,0x00},/* 15 CR91 */
-{0x0a,0x0a,0x07,0x00,0x00,0x00,0x00,0x00},/* 16 CR92 */
-{0x44,0x44,0x44,0x00,0x00,0x00,0x00,0x00},/* 17 CR93 */
-{0x10,0x10,0x0A,0x00,0x00,0x00,0x00,0x00},/* 18 CR94 */
-{0x11,0x11,0x0a,0x00,0x00,0x00,0x00,0x00},/* 19 CR95 */
-{0x05,0x05,0x05,0x00,0x00,0x00,0x00,0x00},/* 20 CR96 */
-{0xf0,0xf0,0xf0,0x00,0x00,0x00,0x00,0x00},/* 21 CRC3 */
-{0x05,0x00,0x02,0x00,0x00,0x00,0x00,0x00},/* 22 CRC4 */
-{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}/* 23 CRC5 */
+static unsigned char XGI340_cr41[24][8] = {
+	{0x20, 0x50, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0 CR41 */
+	{0xc4, 0x40, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 1 CR8A */
+	{0xc4, 0x40, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 2 CR8B */
+	{0xb5, 0xa4, 0xa4, 0x00, 0x00, 0x00, 0x00, 0x00},
+	{0xf0, 0xf0, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00},
+	{0x90, 0x90, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 5 CR68 */
+	{0x77, 0x77, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 6 CR69 */
+	{0x77, 0x77, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 7 CR6A */
+	{0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 8 CR6D */
+	{0x55, 0x55, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 9 CR80 */
+	{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 10 CR81 */
+	{0x88, 0xa8, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 11 CR82 */
+	{0x44, 0x44, 0x77, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 12 CR85 */
+	{0x48, 0x48, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 13 CR86 */
+	{0x54, 0x54, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 14 CR90 */
+	{0x54, 0x54, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 15 CR91 */
+	{0x0a, 0x0a, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 16 CR92 */
+	{0x44, 0x44, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 17 CR93 */
+	{0x10, 0x10, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 18 CR94 */
+	{0x11, 0x11, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 19 CR95 */
+	{0x05, 0x05, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 20 CR96 */
+	{0xf0, 0xf0, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 21 CRC3 */
+	{0x05, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 22 CRC4 */
+	{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}  /* 23 CRC5 */
 };
 
-
-static unsigned char XGI27_cr41[24][8] =
-{
-{0x20,0x40,0x60,0x00,0x00,0x00,0x00,0x00},/* 0 CR41 */
-{0xC4,0x40,0x84,0x00,0x00,0x00,0x00,0x00},/* 1 CR8A */
-{0xC4,0x40,0x84,0x00,0x00,0x00,0x00,0x00},/* 2 CR8B */
-{0xB5,0x13,0xa4,0x00,0x00,0x00,0x00,0x00},/* 3 CR40[7],CR99[2:0],CR45[3:0]*/
-{0xf0,0xf5,0xf0,0x00,0x00,0x00,0x00,0x00},/* 4 CR59 */
-{0x90,0x90,0x24,0x00,0x00,0x00,0x00,0x00},/* 5 CR68 */
-{0x77,0x67,0x44,0x00,0x00,0x00,0x00,0x00},/* 6 CR69 */
-{0x77,0x77,0x44,0x00,0x00,0x00,0x00,0x00},/* 7 CR6A */
-{0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00},/* 8 CR6D */
-{0x55,0x55,0x55,0x00,0x00,0x00,0x00,0x00},/* 9 CR80 */
-{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},/* 10 CR81 */
-{0x88,0xcc,0x48,0x00,0x00,0x00,0x00,0x00},/* 11 CR82 */
-{0x44,0x88,0x77,0x00,0x00,0x00,0x00,0x00},/* 12 CR85 */
-{0x48,0x88,0x88,0x00,0x00,0x00,0x00,0x00},/* 13 CR86 */
-{0x54,0x32,0x44,0x00,0x00,0x00,0x00,0x00},/* 14 CR90 */
-{0x54,0x33,0x44,0x00,0x00,0x00,0x00,0x00},/* 15 CR91 */
-{0x0a,0x07,0x07,0x00,0x00,0x00,0x00,0x00},/* 16 CR92 */
-{0x44,0x63,0x44,0x00,0x00,0x00,0x00,0x00},/* 17 CR93 */
-{0x10,0x14,0x0A,0x00,0x00,0x00,0x00,0x00},/* 18 CR94 */
-{0x11,0x0B,0x0C,0x00,0x00,0x00,0x00,0x00},/* 19 CR95 */
-{0x05,0x22,0x05,0x00,0x00,0x00,0x00,0x00},/* 20 CR96 */
-{0xf0,0xf0,0x00,0x00,0x00,0x00,0x00,0x00},/* 21 CRC3 */
-{0x05,0x00,0x02,0x00,0x00,0x00,0x00,0x00},/* 22 CRC4 */
-{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}/* 23 CRC5 */
+static unsigned char XGI27_cr41[24][8] = {
+	{0x20, 0x40, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 0 CR41 */
+	{0xC4, 0x40, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 1 CR8A */
+	{0xC4, 0x40, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 2 CR8B */
+	{0xB5, 0x13, 0xa4, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 3 CR40[7],
+							       CR99[2:0],
+							       CR45[3:0]*/
+	{0xf0, 0xf5, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 4 CR59 */
+	{0x90, 0x90, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 5 CR68 */
+	{0x77, 0x67, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 6 CR69 */
+	{0x77, 0x77, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 7 CR6A */
+	{0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 8 CR6D */
+	{0x55, 0x55, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 9 CR80 */
+	{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 10 CR81 */
+	{0x88, 0xcc, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 11 CR82 */
+	{0x44, 0x88, 0x77, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 12 CR85 */
+	{0x48, 0x88, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 13 CR86 */
+	{0x54, 0x32, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 14 CR90 */
+	{0x54, 0x33, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 15 CR91 */
+	{0x0a, 0x07, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 16 CR92 */
+	{0x44, 0x63, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 17 CR93 */
+	{0x10, 0x14, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 18 CR94 */
+	{0x11, 0x0B, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 19 CR95 */
+	{0x05, 0x22, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 20 CR96 */
+	{0xf0, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 21 CRC3 */
+	{0x05, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00}, /* 22 CRC4 */
+	{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}  /* 23 CRC5 */
 };
 
 static unsigned char XGI340_CR6B[8][4] = {
-{0xaa,0xaa,0xaa,0xaa},
-{0xaa,0xaa,0xaa,0xaa},
-{0xaa,0xaa,0xaa,0xaa},
-{0x00,0x00,0x00,0x00},
-{0x00,0x00,0x00,0x00},
-{0x00,0x00,0x00,0x00},
-{0x00,0x00,0x00,0x00},
-{0x00,0x00,0x00,0x00}
+	{0xaa, 0xaa, 0xaa, 0xaa},
+	{0xaa, 0xaa, 0xaa, 0xaa},
+	{0xaa, 0xaa, 0xaa, 0xaa},
+	{0x00, 0x00, 0x00, 0x00},
+	{0x00, 0x00, 0x00, 0x00},
+	{0x00, 0x00, 0x00, 0x00},
+	{0x00, 0x00, 0x00, 0x00},
+	{0x00, 0x00, 0x00, 0x00}
 };
 
 static unsigned char XGI340_CR6E[8][4] = {
-{0x00,0x00,0x00,0x00},
-{0x00,0x00,0x00,0x00},
-{0x00,0x00,0x00,0x00},
-{0x00,0x00,0x00,0x00},
-{0x00,0x00,0x00,0x00},
-{0x00,0x00,0x00,0x00},
-{0x00,0x00,0x00,0x00},
-{0x00,0x00,0x00,0x00}
+	{0x00, 0x00, 0x00, 0x00},
+	{0x00, 0x00, 0x00, 0x00},
+	{0x00, 0x00, 0x00, 0x00},
+	{0x00, 0x00, 0x00, 0x00},
+	{0x00, 0x00, 0x00, 0x00},
+	{0x00, 0x00, 0x00, 0x00},
+	{0x00, 0x00, 0x00, 0x00},
+	{0x00, 0x00, 0x00, 0x00}
 };
 
 static unsigned char XGI340_CR6F[8][32] = {
-{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
-{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
-{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
-{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
-{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
-{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
-{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
-{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}
+	{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+	{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+	{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+	{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+	{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+	{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+	{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+	{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
 };
 
 static unsigned char XGI340_CR89[8][2] = {
-{0x00,0x00},
-{0x00,0x00},
-{0x00,0x00},
-{0x00,0x00},
-{0x00,0x00},
-{0x00,0x00},
-{0x00,0x00},
-{0x00,0x00}
+	{0x00, 0x00},
+	{0x00, 0x00},
+	{0x00, 0x00},
+	{0x00, 0x00},
+	{0x00, 0x00},
+	{0x00, 0x00},
+	{0x00, 0x00},
+	{0x00, 0x00}
 };
-			 /* CR47,CR48,CR49,CR4A,CR4B,CR4C,CR70,CR71,CR74,CR75,CR76,CR77 */
+/* CR47,CR48,CR49,CR4A,CR4B,CR4C,CR70,CR71,CR74,CR75,CR76,CR77 */
 static unsigned char XGI340_AGPReg[12] = {
-				   0x28, 0x23, 0x00, 0x20, 0x00, 0x20, 0x00,
-				   0x05, 0xd0, 0x10, 0x10, 0x00};
+	0x28, 0x23, 0x00, 0x20, 0x00, 0x20,
+	0x00, 0x05, 0xd0, 0x10, 0x10, 0x00
+};
 
 static unsigned char XGI340_SR16[4] = {0x03, 0x83, 0x03, 0x83};
 
 #if 0
 static unsigned char XGI330_SR15_1[8][8] = {
-{0x0,0x0,0x00,0x00,0x20,0x20,0x00,0x00},
-{0x5,0x15,0x15,0x15,0x15,0x15,0x00,0x00},
-{0xba,0xba,0xba,0xba,0xBA,0xBA,0x00,0x00},
-{0x55,0x57,0x57,0xAB,0xAB,0xAB,0x00,0x00},
-{0x60,0x34,0x34,0x34,0x34,0x34,0x00,0x00},
-{0x0,0x80,0x80,0x80,0x83,0x83,0x00,0x00},
-{0x50,0x50,0x50,0x3C,0x3C,0x3C,0x00,0x00},
-{0x0,0xa5,0xfb,0xf6,0xF6,0xF6,0x00,0x00}
+	{0x0, 0x0, 0x00, 0x00, 0x20, 0x20, 0x00, 0x00},
+	{0x5, 0x15, 0x15, 0x15, 0x15, 0x15, 0x00, 0x00},
+	{0xba, 0xba, 0xba, 0xba, 0xBA, 0xBA, 0x00, 0x00},
+	{0x55, 0x57, 0x57, 0xAB, 0xAB, 0xAB, 0x00, 0x00},
+	{0x60, 0x34, 0x34, 0x34, 0x34, 0x34, 0x00, 0x00},
+	{0x0, 0x80, 0x80, 0x80, 0x83, 0x83, 0x00, 0x00},
+	{0x50, 0x50, 0x50, 0x3C, 0x3C, 0x3C, 0x00, 0x00},
+	{0x0, 0xa5, 0xfb, 0xf6, 0xF6, 0xF6, 0x00, 0x00}
 };
 
 static unsigned char XGI330_cr40_1[15][8] = {
-{0x66,0x40,0x40,0x28,0x24,0x24,0x00,0x00},
-{0x66,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
-{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
-{0x00,0x00,0x00,0x00,0x0F,0x0F,0x00,0x00},
-{0x00,0xf0,0xf0,0xf0,0xF0,0xF0,0x00,0x00},
-{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
-{0x10,0x10,0x10,0x10,0x20,0x20,0x00,0x00},
-{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
-{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
-{0x88,0x88,0x88,0xAA,0xAC,0xAC,0x00,0x00},
-{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
-{0x00,0x00,0x00,0x00,0x77,0x77,0x00,0x00},
-{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
-{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
-{0x00,0xA2,0x00,0x00,0xA2,0xA2,0x00,0x00},
+	{0x66, 0x40, 0x40, 0x28, 0x24, 0x24, 0x00, 0x00},
+	{0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+	{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+	{0x00, 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x00, 0x00},
+	{0x00, 0xf0, 0xf0, 0xf0, 0xF0, 0xF0, 0x00, 0x00},
+	{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+	{0x10, 0x10, 0x10, 0x10, 0x20, 0x20, 0x00, 0x00},
+	{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+	{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+	{0x88, 0x88, 0x88, 0xAA, 0xAC, 0xAC, 0x00, 0x00},
+	{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+	{0x00, 0x00, 0x00, 0x00, 0x77, 0x77, 0x00, 0x00},
+	{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+	{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+	{0x00, 0xA2, 0x00, 0x00, 0xA2, 0xA2, 0x00, 0x00},
 };
 #endif
 
@@ -191,3248 +211,3380 @@
 static unsigned char XG40_CRCF = 0x13;
 static unsigned char XG40_DRAMTypeDefinition = 0xFF ;
 
-static struct XGI_StStruct XGI330_SModeIDTable[] =
-{
- {0x01,0x9208,0x01,0x00,0x10,0x00,0x00,0x01,0x00},
- {0x01,0x1210,0x14,0x01,0x00,0x01,0x00,0x01,0x00},
- {0x01,0x1010,0x17,0x02,0x11,0x00,0x00,0x01,0x01},
- {0x03,0x8208,0x03,0x00,0x14,0x00,0x00,0x01,0x02},
- {0x03,0x0210,0x16,0x01,0x04,0x01,0x00,0x01,0x02},
- {0x03,0x0010,0x18,0x02,0x15,0x00,0x00,0x01,0x03},
- {0x05,0x9209,0x05,0x00,0x10,0x00,0x00,0x00,0x04},
- {0x06,0x8209,0x06,0x00,0x14,0x00,0x00,0x00,0x05},
- {0x07,0x0000,0x07,0x03,0x05,0x03,0x00,0x01,0x03},
- {0x07,0x0000,0x19,0x02,0x15,0x02,0x00,0x01,0x03},
- {0x0d,0x920a,0x0d,0x00,0x10,0x00,0x00,0x00,0x04},
- {0x0e,0x820a,0x0e,0x00,0x14,0x00,0x00,0x00,0x05},
- {0x0f,0x0202,0x11,0x01,0x04,0x01,0x00,0x00,0x05},
- {0x10,0x0212,0x12,0x01,0x04,0x01,0x00,0x00,0x05},
- {0x11,0x0212,0x1a,0x04,0x24,0x04,0x00,0x00,0x05},
- {0x12,0x0212,0x1b,0x04,0x24,0x04,0x00,0x00,0x05},
- {0x13,0x021b,0x1c,0x00,0x14,0x00,0x00,0x00,0x04},
- {0x12,0x0010,0x18,0x02,0x24,0x02,0x00,0x00,0x05},/* St_CRT2CRTC2 not sure */
- {0x12,0x0210,0x18,0x01,0x24,0x01,0x00,0x00,0x05},/* St_CRT2CRTC2 not sure */
- {0xff,0x0000,0x00,0x00,0x00,0x00,0x00,0x00,0x00}
+static struct XGI_StStruct XGI330_SModeIDTable[] = {
+	{0x01, 0x9208, 0x01, 0x00, 0x10, 0x00, 0x00, 0x01, 0x00},
+	{0x01, 0x1210, 0x14, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00},
+	{0x01, 0x1010, 0x17, 0x02, 0x11, 0x00, 0x00, 0x01, 0x01},
+	{0x03, 0x8208, 0x03, 0x00, 0x14, 0x00, 0x00, 0x01, 0x02},
+	{0x03, 0x0210, 0x16, 0x01, 0x04, 0x01, 0x00, 0x01, 0x02},
+	{0x03, 0x0010, 0x18, 0x02, 0x15, 0x00, 0x00, 0x01, 0x03},
+	{0x05, 0x9209, 0x05, 0x00, 0x10, 0x00, 0x00, 0x00, 0x04},
+	{0x06, 0x8209, 0x06, 0x00, 0x14, 0x00, 0x00, 0x00, 0x05},
+	{0x07, 0x0000, 0x07, 0x03, 0x05, 0x03, 0x00, 0x01, 0x03},
+	{0x07, 0x0000, 0x19, 0x02, 0x15, 0x02, 0x00, 0x01, 0x03},
+	{0x0d, 0x920a, 0x0d, 0x00, 0x10, 0x00, 0x00, 0x00, 0x04},
+	{0x0e, 0x820a, 0x0e, 0x00, 0x14, 0x00, 0x00, 0x00, 0x05},
+	{0x0f, 0x0202, 0x11, 0x01, 0x04, 0x01, 0x00, 0x00, 0x05},
+	{0x10, 0x0212, 0x12, 0x01, 0x04, 0x01, 0x00, 0x00, 0x05},
+	{0x11, 0x0212, 0x1a, 0x04, 0x24, 0x04, 0x00, 0x00, 0x05},
+	{0x12, 0x0212, 0x1b, 0x04, 0x24, 0x04, 0x00, 0x00, 0x05},
+	{0x13, 0x021b, 0x1c, 0x00, 0x14, 0x00, 0x00, 0x00, 0x04},
+	{0x12, 0x0010, 0x18, 0x02, 0x24, 0x02, 0x00, 0x00, 0x05},/* St_CRT2CRTC2
+								    not sure */
+	{0x12, 0x0210, 0x18, 0x01, 0x24, 0x01, 0x00, 0x00, 0x05},/* St_CRT2CRTC2
+								    not sure */
+	{0xff, 0x0000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
 };
 
 
-static struct XGI_ExtStruct  XGI330_EModeIDTable[] =
-{
- {0x6a,0x2212,0x0407,0x3a81,0x0102,0x08,0x07,0x00,0x00,0x07,0x0e},
- {0x2e,0x0a1b,0x0306,0x3a57,0x0101,0x08,0x06,0x00,0x00,0x05,0x06},
- {0x2f,0x0a1b,0x0305,0x3a50,0x0100,0x08,0x05,0x00,0x00,0x05,0x05},
- {0x30,0x2a1b,0x0407,0x3a81,0x0103,0x08,0x07,0x00,0x00,0x07,0x0e},
- {0x31,0x0a1b,0x030d,0x3b85,0x0000,0x08,0x0d,0x00,0x00,0x06,0x3d},
- {0x32,0x0a1b,0x0a0e,0x3b8c,0x0000,0x08,0x0e,0x00,0x00,0x06,0x3e},
- {0x33,0x0a1d,0x0a0d,0x3b85,0x0000,0x08,0x0d,0x00,0x00,0x06,0x3d},
- {0x34,0x2a1d,0x0a0e,0x3b8c,0x0000,0x08,0x0e,0x00,0x00,0x06,0x3e},
- {0x35,0x0a1f,0x0a0d,0x3b85,0x0000,0x08,0x0d,0x00,0x00,0x06,0x3d},
- {0x36,0x2a1f,0x0a0e,0x3b8c,0x0000,0x08,0x0e,0x00,0x00,0x06,0x3e},
- {0x37,0x0212,0x0508,0x3aab,0x0104,0x08,0x08,0x00,0x00,0x00,0x16},
- {0x38,0x0a1b,0x0508,0x3aab,0x0105,0x08,0x08,0x00,0x00,0x00,0x16},
- {0x3a,0x0e3b,0x0609,0x3adc,0x0107,0x08,0x09,0x00,0x00,0x00,0x1e},
- {0x3c,0x0e3b,0x070a,0x3af2,0x0130,0x08,0x0a,0x00,0x00,0x00,0x22},	/* mode 1600x1200 add CRT2MODE [2003/10/07] */
- {0x3d,0x0e7d,0x070a,0x3af2,0x0131,0x08,0x0a,0x00,0x00,0x00,0x22},	/* mode 1600x1200 add CRT2MODE */
- {0x40,0x9a1c,0x0000,0x3a34,0x010d,0x08,0x00,0x00,0x00,0x04,0x00},
- {0x41,0x9a1d,0x0000,0x3a34,0x010e,0x08,0x00,0x00,0x00,0x04,0x00},	/* ModeIdIndex = 0x10 */
- {0x43,0x0a1c,0x0306,0x3a57,0x0110,0x08,0x06,0x00,0x00,0x05,0x06},
- {0x44,0x0a1d,0x0306,0x3a57,0x0111,0x08,0x06,0x00,0x00,0x05,0x06},
- {0x46,0x2a1c,0x0407,0x3a81,0x0113,0x08,0x07,0x00,0x00,0x07,0x0e},
- {0x47,0x2a1d,0x0407,0x3a81,0x0114,0x08,0x07,0x00,0x00,0x07,0x0e},
- {0x49,0x0a3c,0x0508,0x3aab,0x0116,0x08,0x08,0x00,0x00,0x00,0x16},
- {0x4a,0x0a3d,0x0508,0x3aab,0x0117,0x08,0x08,0x00,0x00,0x00,0x16},
- {0x4c,0x0e7c,0x0609,0x3adc,0x0119,0x08,0x09,0x00,0x00,0x00,0x1e},
- {0x4d,0x0e7d,0x0609,0x3adc,0x011a,0x08,0x09,0x00,0x00,0x00,0x1e},
- {0x50,0x9a1b,0x0001,0x3a3b,0x0132,0x08,0x01,0x00,0x00,0x04,0x02},
- {0x51,0xba1b,0x0103,0x3a42,0x0133,0x08,0x03,0x00,0x00,0x07,0x03},
- {0x52,0x9a1b,0x0204,0x3a49,0x0134,0x08,0x04,0x00,0x00,0x00,0x04},
- {0x56,0x9a1d,0x0001,0x3a3b,0x0135,0x08,0x01,0x00,0x00,0x04,0x02},
- {0x57,0xba1d,0x0103,0x3a42,0x0136,0x08,0x03,0x00,0x00,0x07,0x03},
- {0x58,0x9a1d,0x0204,0x3a49,0x0137,0x08,0x04,0x00,0x00,0x00,0x04},
- {0x59,0x9a1b,0x0000,0x3a34,0x0138,0x08,0x00,0x00,0x00,0x04,0x00},
- {0x5A,0x021b,0x0014,0x3b83,0x0138,0x08,0x01,0x00,0x00,0x04,0x3f},	/* ModeIdIndex = 0x20 */
- {0x5B,0x0a1d,0x0014,0x3b83,0x0135,0x08,0x01,0x00,0x00,0x04,0x3f},
- {0x5d,0x0a1d,0x0305,0x3a50,0x0139,0x08,0x05,0x00,0x00,0x07,0x05},
- {0x62,0x0a3f,0x0306,0x3a57,0x013a,0x08,0x06,0x00,0x00,0x05,0x06},
- {0x63,0x2a3f,0x0407,0x3a81,0x013b,0x08,0x07,0x00,0x00,0x07,0x0e},
- {0x64,0x0a7f,0x0508,0x3aab,0x013c,0x08,0x08,0x00,0x00,0x00,0x16},
- {0x65,0x0eff,0x0609,0x3adc,0x013d,0x08,0x09,0x00,0x00,0x00,0x1e},
- {0x66,0x0eff,0x070a,0x3af2,0x013e,0x08,0x0a,0x00,0x00,0x00,0x22},	/* mode 1600x1200 add CRT2MODE */
- {0x68,0x067b,0x080b,0x3b17,0x013f,0x08,0x0b,0x00,0x00,0x00,0x29},
- {0x69,0x06fd,0x080b,0x3b17,0x0140,0x08,0x0b,0x00,0x00,0x00,0x29},
- {0x6b,0x07ff,0x080b,0x3b17,0x0141,0x10,0x0b,0x00,0x00,0x00,0x29},
- {0x6c,0x067b,0x090c,0x3b37,0x0000,0x08,0x0c,0x00,0x00,0x00,0x2f},
- {0x6d,0x06fd,0x090c,0x3b37,0x0000,0x10,0x0c,0x00,0x00,0x00,0x2f},
- {0x6e,0x07ff,0x090c,0x3b37,0x0000,0x10,0x0c,0x00,0x00,0x00,0x2f},
- {0x70,0x2a1b,0x0410,0x3b52,0x0000,0x08,0x10,0x00,0x00,0x07,0x34},
- {0x71,0x0a1b,0x0511,0x3b63,0x0000,0x08,0x11,0x00,0x00,0x00,0x37},
- {0x74,0x0a1d,0x0511,0x3b63,0x0000,0x08,0x11,0x00,0x00,0x00,0x37},	/* ModeIdIndex = 0x30 */
- {0x75,0x0a3d,0x0612,0x3b74,0x0000,0x08,0x12,0x00,0x00,0x00,0x3a},
- {0x76,0x2a1f,0x0410,0x3b52,0x0000,0x08,0x10,0x00,0x00,0x07,0x34},
- {0x77,0x0a1f,0x0511,0x3b63,0x0000,0x08,0x11,0x00,0x00,0x00,0x37},
- {0x78,0x0a3f,0x0612,0x3b74,0x0000,0x08,0x12,0x00,0x00,0x00,0x3a},
- {0x79,0x0a3b,0x0612,0x3b74,0x0000,0x08,0x12,0x00,0x00,0x00,0x3a},
- {0x7a,0x2a1d,0x0410,0x3b52,0x0000,0x08,0x10,0x00,0x00,0x07,0x34},
- {0x7b,0x0e3b,0x060f,0x3ad0,0x0000,0x08,0x0f,0x00,0x00,0x00,0x1d},
- {0x7c,0x0e7d,0x060f,0x3ad0,0x0000,0x08,0x0f,0x00,0x00,0x00,0x1d},
- {0x7d,0x0eff,0x060f,0x3ad0,0x0000,0x08,0x0f,0x00,0x00,0x00,0x1d},
- {0x20,0x0e3b,0x0D16,0x49e0,0x0000,0x08,0x16,0x00,0x00,0x00,0x43},
- {0x21,0x0e7d,0x0D16,0x49e0,0x0000,0x08,0x16,0x00,0x00,0x00,0x43},
- {0x22,0x0eff,0x0D16,0x49e0,0x0000,0x08,0x16,0x00,0x00,0x00,0x43},
- {0x23,0x0e3b,0x0614,0x49d5,0x0000,0x08,0x14,0x00,0x00,0x00,0x41},
- {0x24,0x0e7d,0x0614,0x49d5,0x0000,0x08,0x14,0x00,0x00,0x00,0x41},
- {0x25,0x0eff,0x0614,0x49d5,0x0000,0x08,0x14,0x00,0x00,0x00,0x41},
- {0x26,0x063b,0x0c15,0x49dc,0x0000,0x08,0x15,0x00,0x00,0x00,0x42},	/* ModeIdIndex = 0x40 */
- {0x27,0x067d,0x0c15,0x49dc,0x0000,0x08,0x15,0x00,0x00,0x00,0x42},
- {0x28,0x06ff,0x0c15,0x49dc,0x0000,0x08,0x15,0x00,0x00,0x00,0x42},
- {0xff,0x0000,0x0000,0x0000,0x0000,0x00,0x00,0x00,0x00,0x00,0x00}
+static struct XGI_ExtStruct XGI330_EModeIDTable[] = {
+	{0x6a, 0x2212, 0x0407, 0x3a81, 0x0102, 0x08,
+		0x07, 0x00, 0x00, 0x07, 0x0e},
+	{0x2e, 0x0a1b, 0x0306, 0x3a57, 0x0101, 0x08,
+		0x06, 0x00, 0x00, 0x05, 0x06},
+	{0x2f, 0x0a1b, 0x0305, 0x3a50, 0x0100, 0x08,
+		0x05, 0x00, 0x00, 0x05, 0x05},
+	{0x30, 0x2a1b, 0x0407, 0x3a81, 0x0103, 0x08,
+		0x07, 0x00, 0x00, 0x07, 0x0e},
+	{0x31, 0x0a1b, 0x030d, 0x3b85, 0x0000, 0x08,
+		0x0d, 0x00, 0x00, 0x06, 0x3d},
+	{0x32, 0x0a1b, 0x0a0e, 0x3b8c, 0x0000, 0x08,
+		0x0e, 0x00, 0x00, 0x06, 0x3e},
+	{0x33, 0x0a1d, 0x0a0d, 0x3b85, 0x0000, 0x08,
+		0x0d, 0x00, 0x00, 0x06, 0x3d},
+	{0x34, 0x2a1d, 0x0a0e, 0x3b8c, 0x0000, 0x08,
+		0x0e, 0x00, 0x00, 0x06, 0x3e},
+	{0x35, 0x0a1f, 0x0a0d, 0x3b85, 0x0000, 0x08,
+		0x0d, 0x00, 0x00, 0x06, 0x3d},
+	{0x36, 0x2a1f, 0x0a0e, 0x3b8c, 0x0000, 0x08,
+		0x0e, 0x00, 0x00, 0x06, 0x3e},
+	{0x37, 0x0212, 0x0508, 0x3aab, 0x0104, 0x08,
+		0x08, 0x00, 0x00, 0x00, 0x16},
+	{0x38, 0x0a1b, 0x0508, 0x3aab, 0x0105, 0x08,
+		0x08, 0x00, 0x00, 0x00, 0x16},
+	{0x3a, 0x0e3b, 0x0609, 0x3adc, 0x0107, 0x08,
+		0x09, 0x00, 0x00, 0x00, 0x1e},
+	{0x3c, 0x0e3b, 0x070a, 0x3af2, 0x0130, 0x08,
+		0x0a, 0x00, 0x00, 0x00, 0x22},	/* mode 1600x1200
+						   add CRT2MODE [2003/10/07] */
+	{0x3d, 0x0e7d, 0x070a, 0x3af2, 0x0131, 0x08,
+		0x0a, 0x00, 0x00, 0x00, 0x22},	/* mode 1600x1200
+						   add CRT2MODE */
+	{0x40, 0x9a1c, 0x0000, 0x3a34, 0x010d, 0x08,
+		0x00, 0x00, 0x00, 0x04, 0x00},
+	{0x41, 0x9a1d, 0x0000, 0x3a34, 0x010e, 0x08,
+		0x00, 0x00, 0x00, 0x04, 0x00},	/* ModeIdIndex = 0x10 */
+	{0x43, 0x0a1c, 0x0306, 0x3a57, 0x0110, 0x08,
+		0x06, 0x00, 0x00, 0x05, 0x06},
+	{0x44, 0x0a1d, 0x0306, 0x3a57, 0x0111, 0x08,
+		0x06, 0x00, 0x00, 0x05, 0x06},
+	{0x46, 0x2a1c, 0x0407, 0x3a81, 0x0113, 0x08,
+		0x07, 0x00, 0x00, 0x07, 0x0e},
+	{0x47, 0x2a1d, 0x0407, 0x3a81, 0x0114, 0x08,
+		0x07, 0x00, 0x00, 0x07, 0x0e},
+	{0x49, 0x0a3c, 0x0508, 0x3aab, 0x0116, 0x08,
+		0x08, 0x00, 0x00, 0x00, 0x16},
+	{0x4a, 0x0a3d, 0x0508, 0x3aab, 0x0117, 0x08,
+		0x08, 0x00, 0x00, 0x00, 0x16},
+	{0x4c, 0x0e7c, 0x0609, 0x3adc, 0x0119, 0x08,
+		0x09, 0x00, 0x00, 0x00, 0x1e},
+	{0x4d, 0x0e7d, 0x0609, 0x3adc, 0x011a, 0x08,
+		0x09, 0x00, 0x00, 0x00, 0x1e},
+	{0x50, 0x9a1b, 0x0001, 0x3a3b, 0x0132, 0x08,
+		0x01, 0x00, 0x00, 0x04, 0x02},
+	{0x51, 0xba1b, 0x0103, 0x3a42, 0x0133, 0x08,
+		0x03, 0x00, 0x00, 0x07, 0x03},
+	{0x52, 0x9a1b, 0x0204, 0x3a49, 0x0134, 0x08,
+		0x04, 0x00, 0x00, 0x00, 0x04},
+	{0x56, 0x9a1d, 0x0001, 0x3a3b, 0x0135, 0x08,
+		0x01, 0x00, 0x00, 0x04, 0x02},
+	{0x57, 0xba1d, 0x0103, 0x3a42, 0x0136, 0x08,
+		0x03, 0x00, 0x00, 0x07, 0x03},
+	{0x58, 0x9a1d, 0x0204, 0x3a49, 0x0137, 0x08,
+		0x04, 0x00, 0x00, 0x00, 0x04},
+	{0x59, 0x9a1b, 0x0000, 0x3a34, 0x0138, 0x08,
+		0x00, 0x00, 0x00, 0x04, 0x00},
+	{0x5A, 0x021b, 0x0014, 0x3b83, 0x0138, 0x08,
+		0x01, 0x00, 0x00, 0x04, 0x3f},	/* ModeIdIndex = 0x20 */
+	{0x5B, 0x0a1d, 0x0014, 0x3b83, 0x0135, 0x08,
+		0x01, 0x00, 0x00, 0x04, 0x3f},
+	{0x5d, 0x0a1d, 0x0305, 0x3a50, 0x0139, 0x08,
+		0x05, 0x00, 0x00, 0x07, 0x05},
+	{0x62, 0x0a3f, 0x0306, 0x3a57, 0x013a, 0x08,
+		0x06, 0x00, 0x00, 0x05, 0x06},
+	{0x63, 0x2a3f, 0x0407, 0x3a81, 0x013b, 0x08,
+		0x07, 0x00, 0x00, 0x07, 0x0e},
+	{0x64, 0x0a7f, 0x0508, 0x3aab, 0x013c, 0x08,
+		0x08, 0x00, 0x00, 0x00, 0x16},
+	{0x65, 0x0eff, 0x0609, 0x3adc, 0x013d, 0x08,
+		0x09, 0x00, 0x00, 0x00, 0x1e},
+	{0x66, 0x0eff, 0x070a, 0x3af2, 0x013e, 0x08,
+		0x0a, 0x00, 0x00, 0x00, 0x22},	/* mode 1600x1200
+						   add CRT2MODE */
+	{0x68, 0x067b, 0x080b, 0x3b17, 0x013f, 0x08,
+		0x0b, 0x00, 0x00, 0x00, 0x29},
+	{0x69, 0x06fd, 0x080b, 0x3b17, 0x0140, 0x08,
+		0x0b, 0x00, 0x00, 0x00, 0x29},
+	{0x6b, 0x07ff, 0x080b, 0x3b17, 0x0141, 0x10,
+		0x0b, 0x00, 0x00, 0x00, 0x29},
+	{0x6c, 0x067b, 0x090c, 0x3b37, 0x0000, 0x08,
+		0x0c, 0x00, 0x00, 0x00, 0x2f},
+	{0x6d, 0x06fd, 0x090c, 0x3b37, 0x0000, 0x10,
+		0x0c, 0x00, 0x00, 0x00, 0x2f},
+	{0x6e, 0x07ff, 0x090c, 0x3b37, 0x0000, 0x10,
+		0x0c, 0x00, 0x00, 0x00, 0x2f},
+	{0x70, 0x2a1b, 0x0410, 0x3b52, 0x0000, 0x08,
+		0x10, 0x00, 0x00, 0x07, 0x34},
+	{0x71, 0x0a1b, 0x0511, 0x3b63, 0x0000, 0x08,
+		0x11, 0x00, 0x00, 0x00, 0x37},
+	{0x74, 0x0a1d, 0x0511, 0x3b63, 0x0000, 0x08,
+		0x11, 0x00, 0x00, 0x00, 0x37},	/* ModeIdIndex = 0x30 */
+	{0x75, 0x0a3d, 0x0612, 0x3b74, 0x0000, 0x08,
+		0x12, 0x00, 0x00, 0x00, 0x3a},
+	{0x76, 0x2a1f, 0x0410, 0x3b52, 0x0000, 0x08,
+		0x10, 0x00, 0x00, 0x07, 0x34},
+	{0x77, 0x0a1f, 0x0511, 0x3b63, 0x0000, 0x08,
+		0x11, 0x00, 0x00, 0x00, 0x37},
+	{0x78, 0x0a3f, 0x0612, 0x3b74, 0x0000, 0x08,
+		0x12, 0x00, 0x00, 0x00, 0x3a},
+	{0x79, 0x0a3b, 0x0612, 0x3b74, 0x0000, 0x08,
+		0x12, 0x00, 0x00, 0x00, 0x3a},
+	{0x7a, 0x2a1d, 0x0410, 0x3b52, 0x0000, 0x08,
+		0x10, 0x00, 0x00, 0x07, 0x34},
+	{0x7b, 0x0e3b, 0x060f, 0x3ad0, 0x0000, 0x08,
+		0x0f, 0x00, 0x00, 0x00, 0x1d},
+	{0x7c, 0x0e7d, 0x060f, 0x3ad0, 0x0000, 0x08,
+		0x0f, 0x00, 0x00, 0x00, 0x1d},
+	{0x7d, 0x0eff, 0x060f, 0x3ad0, 0x0000, 0x08,
+		0x0f, 0x00, 0x00, 0x00, 0x1d},
+	{0x20, 0x0e3b, 0x0D16, 0x49e0, 0x0000, 0x08,
+		0x16, 0x00, 0x00, 0x00, 0x43},
+	{0x21, 0x0e7d, 0x0D16, 0x49e0, 0x0000, 0x08,
+		0x16, 0x00, 0x00, 0x00, 0x43},
+	{0x22, 0x0eff, 0x0D16, 0x49e0, 0x0000, 0x08,
+		0x16, 0x00, 0x00, 0x00, 0x43},
+	{0x23, 0x0e3b, 0x0614, 0x49d5, 0x0000, 0x08,
+		0x14, 0x00, 0x00, 0x00, 0x41},
+	{0x24, 0x0e7d, 0x0614, 0x49d5, 0x0000, 0x08,
+		0x14, 0x00, 0x00, 0x00, 0x41},
+	{0x25, 0x0eff, 0x0614, 0x49d5, 0x0000, 0x08,
+		0x14, 0x00, 0x00, 0x00, 0x41},
+	{0x26, 0x063b, 0x0c15, 0x49dc, 0x0000, 0x08,
+		0x15, 0x00, 0x00, 0x00, 0x42},	/* ModeIdIndex = 0x40 */
+	{0x27, 0x067d, 0x0c15, 0x49dc, 0x0000, 0x08,
+		0x15, 0x00, 0x00, 0x00, 0x42},
+	{0x28, 0x06ff, 0x0c15, 0x49dc, 0x0000, 0x08,
+		0x15, 0x00, 0x00, 0x00, 0x42},
+	{0xff, 0x0000, 0x0000, 0x0000, 0x0000, 0x00,
+		0x00, 0x00, 0x00, 0x00, 0x00}
 };
 
-static struct XGI_StandTableStruct XGI330_StandTable[] =
-{
+static struct XGI_StandTableStruct XGI330_StandTable[] = {
 /* MD_0_200 */
- {
-  0x28,0x18,0x08,0x0800,
-  {0x09,0x03,0x00,0x02},
-  0x63,
-  {0x2d,0x27,0x28,0x90,0x2b,0xa0,0xbf,0x1f,
-   0x00,0xc7,0x06,0x07,0x00,0x00,0x00,0x00,
-   0x9c,0x8e,0x8f,0x14,0x1f,0x96,0xb9,0xa3,
-   0xff},
-  {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
-   0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
-   0x08,0x00,0x0f,0x00},
-  {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
-   0xff}
- },
+	{
+		0x28, 0x18, 0x08, 0x0800,
+		{0x09, 0x03, 0x00, 0x02},
+		0x63,
+		{0x2d, 0x27, 0x28, 0x90, 0x2b, 0xa0, 0xbf, 0x1f,
+		 0x00, 0xc7, 0x06, 0x07, 0x00, 0x00, 0x00, 0x00,
+		 0x9c, 0x8e, 0x8f, 0x14, 0x1f, 0x96, 0xb9, 0xa3,
+		 0xff},
+		{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+		 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
+		 0x08, 0x00, 0x0f, 0x00},
+		{0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0e, 0x00,
+		 0xff}
+	},
 /* MD_1_200 */
- {
-  0x28,0x18,0x08,0x0800,
-  {0x09,0x03,0x00,0x02},
-  0x63,
-  {0x2d,0x27,0x28,0x90,0x2b,0xa0,0xbf,0x1f,
-   0x00,0xc7,0x06,0x07,0x00,0x00,0x00,0x00,
-   0x9c,0x8e,0x8f,0x14,0x1f,0x96,0xb9,0xa3,
-   0xff},
-  {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
-   0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
-   0x08,0x00,0x0f,0x00},
-  {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
-   0xff}
- },
+	{
+		0x28, 0x18, 0x08, 0x0800,
+		{0x09, 0x03, 0x00, 0x02},
+		0x63,
+		{0x2d, 0x27, 0x28, 0x90, 0x2b, 0xa0, 0xbf, 0x1f,
+		 0x00, 0xc7, 0x06, 0x07, 0x00, 0x00, 0x00, 0x00,
+		 0x9c, 0x8e, 0x8f, 0x14, 0x1f, 0x96, 0xb9, 0xa3,
+		 0xff},
+		{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+		 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
+		 0x08, 0x00, 0x0f, 0x00},
+		{0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0e, 0x00,
+		 0xff}
+	},
 /* MD_2_200 */
- {
-  0x50,0x18,0x08,0x1000,
-  {0x01,0x03,0x00,0x02},
-  0x63,
-  {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
-   0x00,0xc7,0x06,0x07,0x00,0x00,0x00,0x00,
-   0x9c,0x8e,0x8f,0x28,0x1f,0x96,0xb9,0xa3,
-   0xff},
-  {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
-   0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
-   0x08,0x00,0x0f,0x00},
-  {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
-   0xff}
- },
+	{
+		0x50, 0x18, 0x08, 0x1000,
+		{0x01, 0x03, 0x00, 0x02},
+		 0x63,
+		{0x5f, 0x4f, 0x50, 0x82, 0x55, 0x81, 0xbf, 0x1f,
+		 0x00, 0xc7, 0x06, 0x07, 0x00, 0x00, 0x00, 0x00,
+		 0x9c, 0x8e, 0x8f, 0x28, 0x1f, 0x96, 0xb9, 0xa3,
+		 0xff},
+		{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+		 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
+		 0x08, 0x00, 0x0f, 0x00},
+		{0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0e, 0x00,
+		 0xff}
+	},
 /* MD_3_200 */
- {
-  0x50,0x18,0x08,0x1000,
-  {0x01,0x03,0x00,0x02},
-  0x63,
-  {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
-   0x00,0xc7,0x06,0x07,0x00,0x00,0x00,0x00,
-   0x9c,0x8e,0x8f,0x28,0x1f,0x96,0xb9,0xa3,
-   0xff},
-  {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
-   0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
-   0x08,0x00,0x0f,0x00},
-  {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
-   0xff}
- },
+	{
+		0x50, 0x18, 0x08, 0x1000,
+		{0x01, 0x03, 0x00, 0x02},
+		 0x63,
+		{0x5f, 0x4f, 0x50, 0x82, 0x55, 0x81, 0xbf, 0x1f,
+		 0x00, 0xc7, 0x06, 0x07, 0x00, 0x00, 0x00, 0x00,
+		 0x9c, 0x8e, 0x8f, 0x28, 0x1f, 0x96, 0xb9, 0xa3,
+		 0xff},
+		{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+		 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
+		 0x08, 0x00, 0x0f, 0x00},
+		{0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0e, 0x00,
+		 0xff}
+	},
 /* MD_4 */
- {
-  0x28,0x18,0x08,0x4000,
-  {0x09,0x03,0x00,0x02},
-  0x63,
-  {0x2d,0x27,0x28,0x90,0x2c,0x80,0xbf,0x1f,
-   0x00,0xc1,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x9c,0x8e,0x8f,0x14,0x00,0x96,0xb9,0xa2,
-   0xff},
-  {0x00,0x13,0x15,0x17,0x02,0x04,0x06,0x07,
-   0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
-   0x01,0x00,0x03,0x00},
-  {0x00,0x00,0x00,0x00,0x00,0x30,0x0f,0x00,
-   0xff}
- },
+	{
+		0x28, 0x18, 0x08, 0x4000,
+		{0x09, 0x03, 0x00, 0x02},
+		 0x63,
+		{0x2d, 0x27, 0x28, 0x90, 0x2c, 0x80, 0xbf, 0x1f,
+		 0x00, 0xc1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		 0x9c, 0x8e, 0x8f, 0x14, 0x00, 0x96, 0xb9, 0xa2,
+		 0xff},
+		{0x00, 0x13, 0x15, 0x17, 0x02, 0x04, 0x06, 0x07,
+		 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
+		 0x01, 0x00, 0x03, 0x00},
+		{0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x0f, 0x00,
+		 0xff}
+	},
 /* MD_5 */
- {
-  0x28,0x18,0x08,0x4000,
-  {0x09,0x03,0x00,0x02},
-  0x63,
-  {0x2d,0x27,0x28,0x90,0x2c,0x80,0xbf,0x1f,
-   0x00,0xc1,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x9c,0x8e,0x8f,0x14,0x00,0x96,0xb9,0xa2,
-   0xff},
-  {0x00,0x13,0x15,0x17,0x02,0x04,0x06,0x07,
-   0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
-   0x01,0x00,0x03,0x00},
-  {0x00,0x00,0x00,0x00,0x00,0x30,0x0f,0x00,
-   0xff}
- },
+	{
+		0x28, 0x18, 0x08, 0x4000,
+		{0x09, 0x03, 0x00, 0x02},
+		 0x63,
+		{0x2d, 0x27, 0x28, 0x90, 0x2c, 0x80, 0xbf, 0x1f,
+		 0x00, 0xc1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		 0x9c, 0x8e, 0x8f, 0x14, 0x00, 0x96, 0xb9, 0xa2,
+		 0xff},
+		{0x00, 0x13, 0x15, 0x17, 0x02, 0x04, 0x06, 0x07,
+		 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
+		 0x01, 0x00, 0x03, 0x00},
+		{0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x0f, 0x00,
+		 0xff}
+	},
 /* MD_6 */
- {
-  0x50,0x18,0x08,0x4000,
-  {0x01,0x01,0x00,0x06},
-  0x63,
-  {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
-   0x00,0xc1,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x9c,0x8e,0x8f,0x28,0x00,0x96,0xb9,0xc2,
-   0xff},
-  {0x00,0x17,0x17,0x17,0x17,0x17,0x17,0x17,
-   0x17,0x17,0x17,0x17,0x17,0x17,0x17,0x17,
-   0x01,0x00,0x01,0x00},
-  {0x00,0x00,0x00,0x00,0x00,0x00,0x0d,0x00,
-   0xff}
- },
+	{
+		0x50, 0x18, 0x08, 0x4000,
+		{0x01, 0x01, 0x00, 0x06},
+		 0x63,
+		{0x5f, 0x4f, 0x50, 0x82, 0x55, 0x81, 0xbf, 0x1f,
+		 0x00, 0xc1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		 0x9c, 0x8e, 0x8f, 0x28, 0x00, 0x96, 0xb9, 0xc2,
+		 0xff},
+		{0x00, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17,
+		 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17,
+		 0x01, 0x00, 0x01, 0x00},
+		{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x00,
+		 0xff}
+	},
 /* MD_7 */
- {
-  0x50,0x18,0x0e,0x1000,
-  {0x00,0x03,0x00,0x03},
-  0xa6,
-  {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
-   0x00,0x4d,0x0b,0x0c,0x00,0x00,0x00,0x00,
-   0x83,0x85,0x5d,0x28,0x0d,0x63,0xba,0xa3,
-   0xff},
-  {0x00,0x08,0x08,0x08,0x08,0x08,0x08,0x08,
-   0x10,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
-   0x0e,0x00,0x0f,0x08},
-  {0x00,0x00,0x00,0x00,0x00,0x10,0x0a,0x00,
-   0xff}
- },
+	{
+		0x50, 0x18, 0x0e, 0x1000,
+		{0x00, 0x03, 0x00, 0x03},
+		 0xa6,
+		{0x5f, 0x4f, 0x50, 0x82, 0x55, 0x81, 0xbf, 0x1f,
+		 0x00, 0x4d, 0x0b, 0x0c, 0x00, 0x00, 0x00, 0x00,
+		 0x83, 0x85, 0x5d, 0x28, 0x0d, 0x63, 0xba, 0xa3,
+		 0xff},
+		{0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
+		 0x10, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+		 0x0e, 0x00, 0x0f, 0x08},
+		{0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0a, 0x00,
+		 0xff}
+	},
 /* MDA_DAC */
- {
-  0x00,0x00,0x00,0x0000,
-  {0x00,0x00,0x00,0x15},
-  0x15,
-  {0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x15,
-   0x15,0x15,0x15,0x15,0x15,0x15,0x3f,0x3f,
-   0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x00,0x00,
-   0x00},
-  {0x00,0x00,0x00,0x00,0x00,0x15,0x15,0x15,
-   0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x15,
-   0x15,0x15,0x15,0x15},
-  {0x15,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,
-   0x3f}
- },
+	{
+		0x00, 0x00, 0x00, 0x0000,
+		{0x00, 0x00, 0x00, 0x15},
+		 0x15,
+		{0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15,
+		 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x3f, 0x3f,
+		 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x00, 0x00,
+		 0x00},
+		{0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x15, 0x15,
+		 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15,
+		 0x15, 0x15, 0x15, 0x15},
+		{0x15, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f,
+		 0x3f}
+	},
 /* CGA_DAC */
- {
-  0x00,0x10,0x04,0x0114,
-  {0x11,0x09,0x15,0x00},
-  0x10,
-  {0x04,0x14,0x01,0x11,0x09,0x15,0x2a,0x3a,
-   0x2e,0x3e,0x2b,0x3b,0x2f,0x3f,0x2a,0x3a,
-   0x2e,0x3e,0x2b,0x3b,0x2f,0x3f,0x00,0x10,
-   0x04},
-  {0x14,0x01,0x11,0x09,0x15,0x00,0x10,0x04,
-   0x14,0x01,0x11,0x09,0x15,0x2a,0x3a,0x2e,
-   0x3e,0x2b,0x3b,0x2f},
-  {0x3f,0x2a,0x3a,0x2e,0x3e,0x2b,0x3b,0x2f,
-   0x3f}
- },
+	{
+		0x00, 0x10, 0x04, 0x0114,
+		{0x11, 0x09, 0x15, 0x00},
+		 0x10,
+		{0x04, 0x14, 0x01, 0x11, 0x09, 0x15, 0x2a, 0x3a,
+		 0x2e, 0x3e, 0x2b, 0x3b, 0x2f, 0x3f, 0x2a, 0x3a,
+		 0x2e, 0x3e, 0x2b, 0x3b, 0x2f, 0x3f, 0x00, 0x10,
+		 0x04},
+		{0x14, 0x01, 0x11, 0x09, 0x15, 0x00, 0x10, 0x04,
+		 0x14, 0x01, 0x11, 0x09, 0x15, 0x2a, 0x3a, 0x2e,
+		 0x3e, 0x2b, 0x3b, 0x2f},
+		{0x3f, 0x2a, 0x3a, 0x2e, 0x3e, 0x2b, 0x3b, 0x2f,
+		 0x3f}
+	},
 /* EGA_DAC */
- {
-  0x00,0x10,0x04,0x0114,
-  {0x11,0x05,0x15,0x20},
-  0x30,
-  {0x24,0x34,0x21,0x31,0x25,0x35,0x08,0x18,
-   0x0c,0x1c,0x09,0x19,0x0d,0x1d,0x28,0x38,
-   0x2c,0x3c,0x29,0x39,0x2d,0x3d,0x02,0x12,
-   0x06},
-  {0x16,0x03,0x13,0x07,0x17,0x22,0x32,0x26,
-   0x36,0x23,0x33,0x27,0x37,0x0a,0x1a,0x0e,
-   0x1e,0x0b,0x1b,0x0f},
-  {0x1f,0x2a,0x3a,0x2e,0x3e,0x2b,0x3b,0x2f,
-   0x3f}
- },
+	{
+		0x00, 0x10, 0x04, 0x0114,
+		{0x11, 0x05, 0x15, 0x20},
+		 0x30,
+		{0x24, 0x34, 0x21, 0x31, 0x25, 0x35, 0x08, 0x18,
+		 0x0c, 0x1c, 0x09, 0x19, 0x0d, 0x1d, 0x28, 0x38,
+		 0x2c, 0x3c, 0x29, 0x39, 0x2d, 0x3d, 0x02, 0x12,
+		 0x06},
+		{0x16, 0x03, 0x13, 0x07, 0x17, 0x22, 0x32, 0x26,
+		 0x36, 0x23, 0x33, 0x27, 0x37, 0x0a, 0x1a, 0x0e,
+		 0x1e, 0x0b, 0x1b, 0x0f},
+		{0x1f, 0x2a, 0x3a, 0x2e, 0x3e, 0x2b, 0x3b, 0x2f,
+		 0x3f}
+	},
 /* VGA_DAC */
- {
-  0x00,0x10,0x04,0x0114,
-  {0x11,0x09,0x15,0x2a},
-  0x3a,
-  {0x2e,0x3e,0x2b,0x3b,0x2f,0x3f,0x00,0x05,
-   0x08,0x0b,0x0e,0x11,0x14,0x18,0x1c,0x20,
-   0x24,0x28,0x2d,0x32,0x38,0x3f,0x00,0x10,
-   0x1f},
-  {0x2f,0x3f,0x1f,0x27,0x2f,0x37,0x3f,0x2d,
-   0x31,0x36,0x3a,0x3f,0x00,0x07,0x0e,0x15,
-   0x1c,0x0e,0x11,0x15},
-  {0x18,0x1c,0x14,0x16,0x18,0x1a,0x1c,0x00,
-   0x04}
- },
- {
-  0x08,0x0c,0x10,0x0a08,
-  {0x0c,0x0e,0x10,0x0b},
-  0x0c,
-  {0x0d,0x0f,0x10,0x10,0x01,0x08,0x00,0x00,
-   0x00,0x00,0x01,0x00,0x02,0x02,0x01,0x00,
-   0x04,0x04,0x01,0x00,0x05,0x02,0x05,0x00,
-   0x06},
-  {0x01,0x06,0x05,0x06,0x00,0x08,0x01,0x08,
-   0x00,0x07,0x02,0x07,0x06,0x07,0x00,0x00,
-   0x00,0x00,0x00,0x00},
-  {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x00}
- },
+	{
+		0x00, 0x10, 0x04, 0x0114,
+		{0x11, 0x09, 0x15, 0x2a},
+		 0x3a,
+		{0x2e, 0x3e, 0x2b, 0x3b, 0x2f, 0x3f, 0x00, 0x05,
+		 0x08, 0x0b, 0x0e, 0x11, 0x14, 0x18, 0x1c, 0x20,
+		 0x24, 0x28, 0x2d, 0x32, 0x38, 0x3f, 0x00, 0x10,
+		 0x1f},
+		{0x2f, 0x3f, 0x1f, 0x27, 0x2f, 0x37, 0x3f, 0x2d,
+		 0x31, 0x36, 0x3a, 0x3f, 0x00, 0x07, 0x0e, 0x15,
+		 0x1c, 0x0e, 0x11, 0x15},
+		{0x18, 0x1c, 0x14, 0x16, 0x18, 0x1a, 0x1c, 0x00,
+		 0x04}
+	},
+	{
+		0x08, 0x0c, 0x10, 0x0a08,
+		{0x0c, 0x0e, 0x10, 0x0b},
+		 0x0c,
+		{0x0d, 0x0f, 0x10, 0x10, 0x01, 0x08, 0x00, 0x00,
+		 0x00, 0x00, 0x01, 0x00, 0x02, 0x02, 0x01, 0x00,
+		 0x04, 0x04, 0x01, 0x00, 0x05, 0x02, 0x05, 0x00,
+		 0x06},
+		{0x01, 0x06, 0x05, 0x06, 0x00, 0x08, 0x01, 0x08,
+		 0x00, 0x07, 0x02, 0x07, 0x06, 0x07, 0x00, 0x00,
+		 0x00, 0x00, 0x00, 0x00},
+		{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		 0x00}
+	},
 /* MD_D */
- {
-  0x28,0x18,0x08,0x2000,
-  {0x09,0x0f,0x00,0x06},
-  0x63,
-  {0x2d,0x27,0x28,0x90,0x2c,0x80,0xbf,0x1f,
-   0x00,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x9c,0x8e,0x8f,0x14,0x00,0x96,0xb9,0xe3,
-   0xff},
-  {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
-   0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
-   0x01,0x00,0x0f,0x00},
-  {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x0f,
-   0xff}
- },
+	{
+		0x28, 0x18, 0x08, 0x2000,
+		{0x09, 0x0f, 0x00, 0x06},
+		 0x63,
+		{0x2d, 0x27, 0x28, 0x90, 0x2c, 0x80, 0xbf, 0x1f,
+		 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		 0x9c, 0x8e, 0x8f, 0x14, 0x00, 0x96, 0xb9, 0xe3,
+		 0xff},
+		{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+		 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
+		 0x01, 0x00, 0x0f, 0x00},
+		{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x0f,
+		 0xff}
+	},
 /* MD_E */
- {
-  0x50,0x18,0x08,0x4000,
-  {0x01,0x0f,0x00,0x06},
-  0x63,
-  {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
-   0x00,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x9c,0x8e,0x8f,0x28,0x00,0x96,0xb9,0xe3,
-   0xff},
-  {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
-   0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
-   0x01,0x00,0x0f,0x00},
-  {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x0f,
-   0xff}
- },
+	{
+		0x50, 0x18, 0x08, 0x4000,
+		{0x01, 0x0f, 0x00, 0x06},
+		 0x63,
+		{0x5f, 0x4f, 0x50, 0x82, 0x55, 0x81, 0xbf, 0x1f,
+		 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		 0x9c, 0x8e, 0x8f, 0x28, 0x00, 0x96, 0xb9, 0xe3,
+		 0xff},
+		{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+		 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
+		 0x01, 0x00, 0x0f, 0x00},
+		{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x0f,
+		 0xff}
+	},
 /* ExtVGATable */
- {
-  0x00,0x00,0x00,0x0000,
-  {0x01,0x0f,0x00,0x0e},
-  0x23,
-  {0x5f,0x4f,0x50,0x82,0x54,0x80,0x0b,0x3e,
-   0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,
-   0xea,0x8c,0xdf,0x28,0x40,0xe7,0x04,0xa3,
-   0xff},
-  {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
-   0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,
-   0x01,0x00,0x00,0x00},
-  {0x00,0x00,0x00,0x00,0x00,0x40,0x05,0x0f,
-   0xff}
- },
+	{
+		0x00, 0x00, 0x00, 0x0000,
+		{0x01, 0x0f, 0x00, 0x0e},
+		 0x23,
+		{0x5f, 0x4f, 0x50, 0x82, 0x54, 0x80, 0x0b, 0x3e,
+		 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		 0xea, 0x8c, 0xdf, 0x28, 0x40, 0xe7, 0x04, 0xa3,
+		 0xff},
+		{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+		 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+		 0x01, 0x00, 0x00, 0x00},
+		{0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0f,
+		 0xff}
+	},
 /* ROM_SAVEPTR */
- {
-  0x9f,0x3b,0x00,0x00c0,
-  {0x00,0x00,0x00,0x00},
-  0x00,
-  {0x00,0x00,0x00,0x00,0x00,0x00,0xbb,0x3f,
-   0x00,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x00,0x00,0x1a,0x00,0xac,0x3e,0x00,0xc0,
-   0x00},
-  {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x00,0x00,0x00,0x00},
-  {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x00}
- },
+	{
+		0x9f, 0x3b, 0x00, 0x00c0,
+		{0x00, 0x00, 0x00, 0x00},
+		 0x00,
+		{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbb, 0x3f,
+		 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		 0x00, 0x00, 0x1a, 0x00, 0xac, 0x3e, 0x00, 0xc0,
+		 0x00},
+		{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		 0x00, 0x00, 0x00, 0x00},
+		{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		 0x00}
+	},
 /* MD_F */
- {
-  0x50,0x18,0x0e,0x8000,
-  {0x01,0x0f,0x00,0x06},
-  0xa2,
-  {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
-   0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x82,0x84,0x5d,0x28,0x0f,0x63,0xba,0xe3,
-   0xff},
-  {0x00,0x08,0x00,0x00,0x18,0x18,0x00,0x00,
-   0x00,0x08,0x00,0x00,0x00,0x18,0x00,0x00,
-   0x0b,0x00,0x05,0x00},
-  {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x05,
-   0xff}
- },
+	{
+		0x50, 0x18, 0x0e, 0x8000,
+		{0x01, 0x0f, 0x00, 0x06},
+		 0xa2,
+		{0x5f, 0x4f, 0x50, 0x82, 0x55, 0x81, 0xbf, 0x1f,
+		 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		 0x82, 0x84, 0x5d, 0x28, 0x0f, 0x63, 0xba, 0xe3,
+		 0xff},
+		{0x00, 0x08, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00,
+		 0x00, 0x08, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00,
+		 0x0b, 0x00, 0x05, 0x00},
+		{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x05,
+		 0xff}
+	},
 /* MD_10 */
- {
-  0x50,0x18,0x0e,0x8000,
-  {0x01,0x0f,0x00,0x06},
-  0xa3,
-  {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
-   0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x82,0x84,0x5d,0x28,0x0f,0x63,0xba,0xe3,
-   0xff},
-  {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
-   0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
-   0x01,0x00,0x0f,0x00},
-  {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x0f,
-   0xff}
- },
+	{
+		0x50, 0x18, 0x0e, 0x8000,
+		{0x01, 0x0f, 0x00, 0x06},
+		 0xa3,
+		{0x5f, 0x4f, 0x50, 0x82, 0x55, 0x81, 0xbf, 0x1f,
+		 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		 0x82, 0x84, 0x5d, 0x28, 0x0f, 0x63, 0xba, 0xe3,
+		 0xff},
+		{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07,
+		 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
+		 0x01, 0x00, 0x0f, 0x00},
+		{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x0f,
+		 0xff}
+	},
 /* MD_0_350 */
- {
-  0x28,0x18,0x0e,0x0800,
-  {0x09,0x03,0x00,0x02},
-  0xa3,
-  {0x2d,0x27,0x28,0x90,0x2b,0xb1,0xbf,0x1f,
-   0x00,0x4d,0x0b,0x0c,0x00,0x00,0x00,0x00,
-   0x83,0x85,0x5d,0x14,0x1f,0x63,0xba,0xa3,
-   0xff},
-  {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
-   0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
-   0x08,0x00,0x0f,0x00},
-  {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
-   0xff}
- },
+	{
+		0x28, 0x18, 0x0e, 0x0800,
+		{0x09, 0x03, 0x00, 0x02},
+		 0xa3,
+		{0x2d, 0x27, 0x28, 0x90, 0x2b, 0xb1, 0xbf, 0x1f,
+		 0x00, 0x4d, 0x0b, 0x0c, 0x00, 0x00, 0x00, 0x00,
+		 0x83, 0x85, 0x5d, 0x14, 0x1f, 0x63, 0xba, 0xa3,
+		 0xff},
+		{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07,
+		 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
+		 0x08, 0x00, 0x0f, 0x00},
+		{0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0e, 0x00,
+		 0xff}
+	},
 /* MD_1_350 */
- {
-  0x28,0x18,0x0e,0x0800,
-  {0x09,0x03,0x00,0x02},
-  0xa3,
-  {0x2d,0x27,0x28,0x90,0x2b,0xa0,0xbf,0x1f,
-   0x00,0x4d,0x0b,0x0c,0x00,0x00,0x00,0x00,
-   0x83,0x85,0x5d,0x14,0x1f,0x63,0xba,0xa3,
-   0xff},
-  {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
-   0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
-   0x08,0x00,0x0f,0x00},
-  {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
-   0xff}
- },
+	{
+		0x28, 0x18, 0x0e, 0x0800,
+		{0x09, 0x03, 0x00, 0x02},
+		 0xa3,
+		{0x2d, 0x27, 0x28, 0x90, 0x2b, 0xa0, 0xbf, 0x1f,
+		 0x00, 0x4d, 0x0b, 0x0c, 0x00, 0x00, 0x00, 0x00,
+		 0x83, 0x85, 0x5d, 0x14, 0x1f, 0x63, 0xba, 0xa3,
+		 0xff},
+		{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07,
+		 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
+		 0x08, 0x00, 0x0f, 0x00},
+		{0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0e, 0x00,
+		 0xff}
+	},
 /* MD_2_350 */
- {
-  0x50,0x18,0x0e,0x1000,
-  {0x01,0x03,0x00,0x02},
-  0xa3,
-  {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
-   0x00,0x4d,0x0b,0x0c,0x00,0x00,0x00,0x00,
-   0x83,0x85,0x5d,0x28,0x1f,0x63,0xba,0xa3,
-   0xff},
-  {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
-   0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
-   0x08,0x00,0x0f,0x00},
-  {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
-   0xff}
- },
+	{
+		0x50, 0x18, 0x0e, 0x1000,
+		{0x01, 0x03, 0x00, 0x02},
+		 0xa3,
+		{0x5f, 0x4f, 0x50, 0x82, 0x55, 0x81, 0xbf, 0x1f,
+		 0x00, 0x4d, 0x0b, 0x0c, 0x00, 0x00, 0x00, 0x00,
+		 0x83, 0x85, 0x5d, 0x28, 0x1f, 0x63, 0xba, 0xa3,
+		 0xff},
+		{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07,
+		 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
+		 0x08, 0x00, 0x0f, 0x00},
+		{0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0e, 0x00,
+		 0xff}
+	},
 /* MD_3_350 */
- {
-  0x50,0x18,0x0e,0x1000,
-  {0x01,0x03,0x00,0x02},
-  0xa3,
-  {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
-   0x00,0x4d,0x0b,0x0c,0x00,0x00,0x00,0x00,
-   0x83,0x85,0x5d,0x28,0x1f,0x63,0xba,0xa3,
-   0xff},
-  {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
-   0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
-   0x08,0x00,0x0f,0x00},
-  {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
-   0xff}
- },
+	{
+		0x50, 0x18, 0x0e, 0x1000,
+		{0x01, 0x03, 0x00, 0x02},
+		 0xa3,
+		{0x5f, 0x4f, 0x50, 0x82, 0x55, 0x81, 0xbf, 0x1f,
+		 0x00, 0x4d, 0x0b, 0x0c, 0x00, 0x00, 0x00, 0x00,
+		 0x83, 0x85, 0x5d, 0x28, 0x1f, 0x63, 0xba, 0xa3,
+		 0xff},
+		{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07,
+		 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
+		 0x08, 0x00, 0x0f, 0x00},
+		{0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0e, 0x00,
+		 0xff}
+	},
 /* MD_0_1_400 */
- {
-  0x28,0x18,0x10,0x0800,
-  {0x08,0x03,0x00,0x02},
-  0x67,
-  {0x2d,0x27,0x28,0x90,0x2b,0xb1,0xbf,0x1f,
-   0x00,0x4f,0x0d,0x0e,0x00,0x00,0x00,0x00,
-   0x9c,0x8e,0x8f,0x14,0x1f,0x96,0xb9,0xa3,
-   0xff},
-  {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
-   0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
-   0x0c,0x00,0x0f,0x08},
-  {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
-   0xff}
- },
+	{
+		0x28, 0x18, 0x10, 0x0800,
+		{0x08, 0x03, 0x00, 0x02},
+		 0x67,
+		{0x2d, 0x27, 0x28, 0x90, 0x2b, 0xb1, 0xbf, 0x1f,
+		 0x00, 0x4f, 0x0d, 0x0e, 0x00, 0x00, 0x00, 0x00,
+		 0x9c, 0x8e, 0x8f, 0x14, 0x1f, 0x96, 0xb9, 0xa3,
+		 0xff},
+		{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07,
+		 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
+		 0x0c, 0x00, 0x0f, 0x08},
+		{0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0e, 0x00,
+		 0xff}
+	},
 /* MD_2_3_400 */
- {
-  0x50,0x18,0x10,0x1000,
-  {0x00,0x03,0x00,0x02},
-  0x67,
-  {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
-   0x00,0x4f,0x0d,0x0e,0x00,0x00,0x00,0x00,
-   0x9c,0x8e,0x8f,0x28,0x1f,0x96,0xb9,0xa3,
-   0xff},
-  {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
-   0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
-   0x0c,0x00,0x0f,0x08},
-  {0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,
-   0xff}
- },
+	{
+		0x50, 0x18, 0x10, 0x1000,
+		{0x00, 0x03, 0x00, 0x02},
+		 0x67,
+		{0x5f, 0x4f, 0x50, 0x82, 0x55, 0x81, 0xbf, 0x1f,
+		 0x00, 0x4f, 0x0d, 0x0e, 0x00, 0x00, 0x00, 0x00,
+		 0x9c, 0x8e, 0x8f, 0x28, 0x1f, 0x96, 0xb9, 0xa3,
+		 0xff},
+		{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07,
+		 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
+		 0x0c, 0x00, 0x0f, 0x08},
+		{0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0e, 0x00,
+		 0xff}
+	},
 /* MD_7_400 */
- {
-  0x50,0x18,0x10,0x1000,
-  {0x00,0x03,0x00,0x02},
-  0x66,
-  {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
-   0x00,0x4f,0x0d,0x0e,0x00,0x00,0x00,0x00,
-   0x9c,0x8e,0x8f,0x28,0x0f,0x96,0xb9,0xa3,
-   0xff},
-  {0x00,0x08,0x08,0x08,0x08,0x08,0x08,0x08,
-   0x10,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
-   0x0e,0x00,0x0f,0x08},
-  {0x00,0x00,0x00,0x00,0x00,0x10,0x0a,0x00,
-   0xff}
- },
+	{
+		0x50, 0x18, 0x10, 0x1000,
+		{0x00, 0x03, 0x00, 0x02},
+		 0x66,
+		{0x5f, 0x4f, 0x50, 0x82, 0x55, 0x81, 0xbf, 0x1f,
+		 0x00, 0x4f, 0x0d, 0x0e, 0x00, 0x00, 0x00, 0x00,
+		 0x9c, 0x8e, 0x8f, 0x28, 0x0f, 0x96, 0xb9, 0xa3,
+		 0xff},
+		{0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
+		 0x10, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+		 0x0e, 0x00, 0x0f, 0x08},
+		{0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0a, 0x00,
+		 0xff}
+	},
 /* MD_11 */
- {
-  0x50,0x1d,0x10,0xa000,
-  {0x01,0x0f,0x00,0x06},
-  0xe3,
-  {0x5f,0x4f,0x50,0x82,0x55,0x81,0x0b,0x3e,
-   0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,
-   0xe9,0x8b,0xdf,0x28,0x00,0xe7,0x04,0xc3,
-   0xff},
-  {0x00,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,
-   0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,0x3f,
-   0x01,0x00,0x0f,0x00},
-  {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x01,
-   0xff}
- },
+	{
+		0x50, 0x1d, 0x10, 0xa000,
+		{0x01, 0x0f, 0x00, 0x06},
+		 0xe3,
+		{0x5f, 0x4f, 0x50, 0x82, 0x55, 0x81, 0x0b, 0x3e,
+		 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		 0xe9, 0x8b, 0xdf, 0x28, 0x00, 0xe7, 0x04, 0xc3,
+		 0xff},
+		{0x00, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f,
+		 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f,
+		 0x01, 0x00, 0x0f, 0x00},
+		{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x01,
+		 0xff}
+	},
 /* ExtEGATable */
- {
-  0x50,0x1d,0x10,0xa000,
-  {0x01,0x0f,0x00,0x06},
-  0xe3,
-  {0x5f,0x4f,0x50,0x82,0x55,0x81,0x0b,0x3e,
-   0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,
-   0xe9,0x8b,0xdf,0x28,0x00,0xe7,0x04,0xe3,
-   0xff},
-  {0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07,
-   0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
-   0x01,0x00,0x0f,0x00},
-  {0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x0f,
-   0xff}
- },
+	{
+		0x50, 0x1d, 0x10, 0xa000,
+		{0x01, 0x0f, 0x00, 0x06},
+		 0xe3,
+		{0x5f, 0x4f, 0x50, 0x82, 0x55, 0x81, 0x0b, 0x3e,
+		 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		 0xe9, 0x8b, 0xdf, 0x28, 0x00, 0xe7, 0x04, 0xe3,
+		 0xff},
+		{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07,
+		 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
+		 0x01, 0x00, 0x0f, 0x00},
+		{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x0f,
+		 0xff}
+	},
 /* MD_13 */
- {
-  0x28,0x18,0x08,0x2000,
-  {0x01,0x0f,0x00,0x0e},
-  0x63,
-  {0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,
-   0x00,0x41,0x00,0x00,0x00,0x00,0x00,0x00,
-   0x9c,0x8e,0x8f,0x28,0x40,0x96,0xb9,0xa3,
-   0xff},
-  {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
-   0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,
-   0x41,0x00,0x0f,0x00},
-  {0x00,0x00,0x00,0x00,0x00,0x40,0x05,0x0f,
-   0xff}
- }
+	{
+		0x28, 0x18, 0x08, 0x2000,
+		{0x01, 0x0f, 0x00, 0x0e},
+		 0x63,
+		{0x5f, 0x4f, 0x50, 0x82, 0x55, 0x81, 0xbf, 0x1f,
+		 0x00, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+		 0x9c, 0x8e, 0x8f, 0x28, 0x40, 0x96, 0xb9, 0xa3,
+		 0xff},
+		{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+		 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+		 0x41, 0x00, 0x0f, 0x00},
+		{0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0f,
+		 0xff}
+	}
 };
 
-static struct XGI_TimingHStruct XGI_TimingH[] =
-{{{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}};
+static struct XGI_TimingHStruct XGI_TimingH[] = {
+	{ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} }
+};
 
-static struct XGI_TimingVStruct XGI_TimingV[] =
-{{{0x00,0x00,0x00,0x00,0x00,0x00,0x00}}};
+static struct XGI_TimingVStruct XGI_TimingV[] = {
+	{ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} }
+};
 
-static struct XGI_XG21CRT1Struct XGI_UpdateCRT1Table[] =
-{
- {0x01,0x27,0x91,0x8f,0xc0},	/* 00 */
- {0x03,0x4f,0x83,0x8f,0xc0},	/* 01 */
- {0x05,0x27,0x91,0x8f,0xc0},	/* 02 */
- {0x06,0x4f,0x83,0x8f,0xc0},	/* 03 */
- {0x07,0x4f,0x83,0x8f,0xc0},	/* 04 */
- {0x0d,0x27,0x91,0x8f,0xc0},	/* 05 */
- {0x0e,0x4f,0x83,0x8f,0xc0},	/* 06 */
- {0x0f,0x4f,0x83,0x5d,0xc0},	/* 07 */
- {0x10,0x4f,0x83,0x5d,0xc0},	/* 08 */
- {0x11,0x4f,0x83,0xdf,0x0c},	/* 09 */
- {0x12,0x4f,0x83,0xdf,0x0c},	/* 10 */
- {0x13,0x4f,0x83,0x8f,0xc0},	/* 11 */
- {0x2e,0x4f,0x83,0xdf,0x0c},	/* 12 */
- {0x2e,0x4f,0x87,0xdf,0xc0},	/* 13 */
- {0x2f,0x4f,0x83,0x8f,0xc0},	/* 14 */
- {0x50,0x27,0x91,0xdf,0x0c},	/* 15 */
- {0x59,0x27,0x91,0x8f,0xc0}	/* 16 */
+static struct XGI_XG21CRT1Struct XGI_UpdateCRT1Table[] = {
+	{0x01, 0x27, 0x91, 0x8f, 0xc0},	/* 00 */
+	{0x03, 0x4f, 0x83, 0x8f, 0xc0},	/* 01 */
+	{0x05, 0x27, 0x91, 0x8f, 0xc0},	/* 02 */
+	{0x06, 0x4f, 0x83, 0x8f, 0xc0},	/* 03 */
+	{0x07, 0x4f, 0x83, 0x8f, 0xc0},	/* 04 */
+	{0x0d, 0x27, 0x91, 0x8f, 0xc0},	/* 05 */
+	{0x0e, 0x4f, 0x83, 0x8f, 0xc0},	/* 06 */
+	{0x0f, 0x4f, 0x83, 0x5d, 0xc0},	/* 07 */
+	{0x10, 0x4f, 0x83, 0x5d, 0xc0},	/* 08 */
+	{0x11, 0x4f, 0x83, 0xdf, 0x0c},	/* 09 */
+	{0x12, 0x4f, 0x83, 0xdf, 0x0c},	/* 10 */
+	{0x13, 0x4f, 0x83, 0x8f, 0xc0},	/* 11 */
+	{0x2e, 0x4f, 0x83, 0xdf, 0x0c},	/* 12 */
+	{0x2e, 0x4f, 0x87, 0xdf, 0xc0},	/* 13 */
+	{0x2f, 0x4f, 0x83, 0x8f, 0xc0},	/* 14 */
+	{0x50, 0x27, 0x91, 0xdf, 0x0c},	/* 15 */
+	{0x59, 0x27, 0x91, 0x8f, 0xc0}	/* 16 */
 };
 
-static struct XGI_CRT1TableStruct XGI_CRT1Table[] =
-{
- {{0x2d,0x28,0x90,0x2c,0x90,0x00,0x04,0x00,
-    0xbf,0x1f,0x9c,0x8e,0x96,0xb9,0x30}}, /* 0x0 */
- {{0x2d,0x28,0x90,0x2c,0x90,0x00,0x04,0x00,
-    0x0b,0x3e,0xe9,0x8b,0xe7,0x04,0x00}}, /* 0x1 */
- {{0x3D,0x31,0x81,0x37,0x1F,0x00,0x05,0x00,
-    0x72,0xF0,0x58,0x8C,0x57,0x73,0xA0}}, /* 0x2 */
- {{0x4F,0x3F,0x93,0x45,0x0D,0x00,0x01,0x00,
-    0x24,0xF5,0x02,0x88,0xFF,0x25,0x90}}, /* 0x3 */
- {{0x5F,0x50,0x82,0x55,0x81,0x00,0x05,0x00,
-    0xBF,0x1F,0x9C,0x8E,0x96,0xB9,0x30}}, /* 0x4 */
- {{0x5F,0x50,0x82,0x55,0x81,0x00,0x05,0x00,
-    0x0B,0x3E,0xE9,0x8B,0xE7,0x04,0x00}}, /* 0x5 */
- {{0x63,0x50,0x86,0x56,0x9B,0x00,0x01,0x00,
-    0x06,0x3E,0xE8,0x8B,0xE7,0xFF,0x10}}, /* 0x6 */
- {{0x64,0x4F,0x88,0x55,0x9D,0x00,0x01,0x00,
-    0xF2,0x1F,0xE0,0x83,0xDF,0xF3,0x10}}, /* 0x7 */
- {{0x63,0x4F,0x87,0x5A,0x81,0x00,0x05,0x00,
-    0xFB,0x1F,0xE0,0x83,0xDF,0xFC,0x10}}, /* 0x8 */
- {{0x65,0x4F,0x89,0x58,0x80,0x00,0x05,0x60,
-    0xFB,0x1F,0xE0,0x83,0xDF,0xFC,0x80}}, /* 0x9 */
- {{0x65,0x4F,0x89,0x58,0x80,0x00,0x05,0x60,
-    0x01,0x3E,0xE0,0x83,0xDF,0x02,0x80}}, /* 0xa */
- {{0x67,0x4F,0x8B,0x58,0x81,0x00,0x05,0x60,
-    0x0D,0x3E,0xE0,0x83,0xDF,0x0E,0x90}}, /* 0xb */
- {{0x65,0x4F,0x89,0x57,0x9F,0x00,0x01,0x00,
-   0xFB,0x1F,0xE6,0x8A,0xDF,0xFC,0x10}}, /* 0xc */
- {{0x7B,0x63,0x9F,0x6A,0x93,0x00,0x05,0x00,    /* ; 0D (800x600,56Hz) */
-    0x6F,0xF0,0x58,0x8A,0x57,0x70,0xA0}},         /* ; (VCLK 36.0MHz) */
- {{0x7F,0x63,0x83,0x6C,0x1C,0x00,0x06,0x00,    /* ; 0E (800x600,60Hz) */
-    0x72,0xF0,0x58,0x8C,0x57,0x73,0xA0}},         /* ; (VCLK 40.0MHz) */
- {{0x7D,0x63,0x81,0x6E,0x1D,0x00,0x06,0x00,    /* ; 0F (800x600,72Hz) */
-    0x98,0xF0,0x7C,0x82,0x57,0x99,0x80}},         /* ; (VCLK 50.0MHz) */
- {{0x7F,0x63,0x83,0x69,0x13,0x00,0x06,0x00,    /* ; 10 (800x600,75Hz) */
-    0x6F,0xF0,0x58,0x8B,0x57,0x70,0xA0}},         /* ; (VCLK 49.5MHz) */
- {{0x7E,0x63,0x82,0x6B,0x13,0x00,0x06,0x00,    /* ; 11 (800x600,85Hz) */
-    0x75,0xF0,0x58,0x8B,0x57,0x76,0xA0}},         /* ; (VCLK 56.25MHz) */
- {{0x81,0x63,0x85,0x6D,0x18,0x00,0x06,0x60,    /* ; 12 (800x600,100Hz) */
-    0x7A,0xF0,0x58,0x8B,0x57,0x7B,0xA0}},         /* ; (VCLK 75.8MHz) */
- {{0x83,0x63,0x87,0x6E,0x19,0x00,0x06,0x60,    /* ; 13 (800x600,120Hz) */
-    0x81,0xF0,0x58,0x8B,0x57,0x82,0xA0}},         /* ; (VCLK 79.411MHz) */
- {{0x85,0x63,0x89,0x6F,0x1A,0x00,0x06,0x60,    /* ; 14 (800x600,160Hz) */
-   0x91,0xF0,0x58,0x8B,0x57,0x92,0xA0}},         /* ; (VCLK 105.822MHz) */
- {{0x99,0x7F,0x9D,0x84,0x1A,0x00,0x02,0x00,
-    0x96,0x1F,0x7F,0x83,0x7F,0x97,0x10}}, /* 0x15 */
- {{0xA3,0x7F,0x87,0x86,0x97,0x00,0x02,0x00,
-    0x24,0xF5,0x02,0x88,0xFF,0x25,0x90}}, /* 0x16 */
- {{0xA1,0x7F,0x85,0x86,0x97,0x00,0x02,0x00,
-    0x24,0xF5,0x02,0x88,0xFF,0x25,0x90}}, /* 0x17 */
- {{0x9F,0x7F,0x83,0x85,0x91,0x00,0x02,0x00,
-    0x1E,0xF5,0x00,0x83,0xFF,0x1F,0x90}}, /* 0x18 */
- {{0xA7,0x7F,0x8B,0x89,0x95,0x00,0x02,0x00,
-    0x26,0xF5,0x00,0x83,0xFF,0x27,0x90}}, /* 0x19 */
- {{0xA9,0x7F,0x8D,0x8C,0x9A,0x00,0x02,0x62,
-    0x2C,0xF5,0x00,0x83,0xFF,0x2D,0x14}}, /* 0x1a */
- {{0xAB,0x7F,0x8F,0x8D,0x9B,0x00,0x02,0x62,
-    0x35,0xF5,0x00,0x83,0xFF,0x36,0x14}}, /* 0x1b */
- {{0xCF,0x9F,0x93,0xB2,0x01,0x00,0x03,0x00,
-    0x14,0xBA,0x00,0x83,0xFF,0x15,0x00}}, /* 0x1c */
- {{0xCE,0x9F,0x92,0xA9,0x17,0x00,0x07,0x00,
-    0x28,0x5A,0x00,0x83,0xFF,0x29,0x89}}, /* 0x1d */
- {{0xCE,0x9F,0x92,0xA5,0x17,0x00,0x07,0x00,
-    0x28,0x5A,0x00,0x83,0xFF,0x29,0x89}}, /* 0x1e */
- {{0xD3,0x9F,0x97,0xAB,0x1F,0x00,0x07,0x00,
-    0x2E,0x5A,0x00,0x83,0xFF,0x2F,0x89}}, /* 0x1f */
- {{0x09,0xC7,0x8D,0xD3,0x0B,0x01,0x04,0x00,
-    0xE0,0x10,0xB0,0x83,0xAF,0xE1,0x2F}}, /* 0x20 */
- {{0x09,0xC7,0x8D,0xD3,0x0B,0x01,0x04,0x00,
-    0xE0,0x10,0xB0,0x83,0xAF,0xE1,0x2F}}, /* 0x21 */
- {{0x09,0xC7,0x8D,0xD3,0x0B,0x01,0x04,0x00,
-    0xE0,0x10,0xB0,0x83,0xAF,0xE1,0x2F}}, /* 0x22 */
- {{0x09,0xC7,0x8D,0xD3,0x0B,0x01,0x04,0x00,
-    0xE0,0x10,0xB0,0x83,0xAF,0xE1,0x2F}}, /* 0x23 */
- {{0x09,0xC7,0x8D,0xD3,0x0B,0x01,0x04,0x00,
-    0xE0,0x10,0xB0,0x83,0xAF,0xE1,0x2F}}, /* 0x24 */
- {{0x09,0xC7,0x8D,0xD3,0x0B,0x01,0x04,0x00,
-    0xE0,0x10,0xB0,0x83,0xAF,0xE1,0x2F}}, /* 0x25 */
- {{0x09,0xC7,0x8D,0xD3,0x0B,0x01,0x04,0x00,
-    0xE0,0x10,0xB0,0x83,0xAF,0xE1,0x2F}}, /* 0x26 */
- {{0x40,0xEF,0x84,0x03,0x1D,0x41,0x01,0x00,
-    0xDA,0x1F,0xA0,0x83,0x9F,0xDB,0x1F}}, /* 0x27 */
- {{0x43,0xEF,0x87,0x06,0x00,0x41,0x05,0x62,
-    0xD4,0x1F,0xA0,0x83,0x9F,0xD5,0x9F}}, /* 0x28 */
- {{0x45,0xEF,0x89,0x07,0x01,0x41,0x05,0x62,
-    0xD9,0x1F,0xA0,0x83,0x9F,0xDA,0x9F}}, /* 0x29 */
- {{0x40,0xEF,0x84,0x03,0x1D,0x41,0x01,0x00,
-    0xDA,0x1F,0xA0,0x83,0x9F,0xDB,0x1F}}, /* 0x2a */
- {{0x40,0xEF,0x84,0x03,0x1D,0x41,0x01,0x00,
-    0xDA,0x1F,0xA0,0x83,0x9F,0xDB,0x1F}}, /* 0x2b */
- {{0x40,0xEF,0x84,0x03,0x1D,0x41,0x01,0x00,
-    0xDA,0x1F,0xA0,0x83,0x9F,0xDB,0x1F}}, /* 0x2c */
- {{0x59,0xFF,0x9D,0x17,0x13,0x41,0x05,0x44,
-    0x33,0xBA,0x00,0x83,0xFF,0x34,0x0F}}, /* 0x2d */
- {{0x5B,0xFF,0x9F,0x18,0x14,0x41,0x05,0x44,
-    0x38,0xBA,0x00,0x83,0xFF,0x39,0x0F}}, /* 0x2e */
- {{0x5B,0xFF,0x9F,0x18,0x14,0x41,0x05,0x44,
-    0x3D,0xBA,0x00,0x83,0xFF,0x3E,0x0F}}, /* 0x2f */
- {{0x5D,0xFF,0x81,0x19,0x95,0x41,0x05,0x44,
-    0x41,0xBA,0x00,0x84,0xFF,0x42,0x0F}}, /* 0x30 */
- {{0x55,0xFF,0x99,0x0D,0x0C,0x41,0x05,0x00,
-    0x3E,0xBA,0x00,0x84,0xFF,0x3F,0x0F}}, /* 0x31 */
- {{0x7F,0x63,0x83,0x6C,0x1C,0x00,0x06,0x00,
-    0x72,0xBA,0x27,0x8B,0xDF,0x73,0x80}}, /* 0x32 */
- {{0x7F,0x63,0x83,0x69,0x13,0x00,0x06,0x00,
-    0x6F,0xBA,0x26,0x89,0xDF,0x6F,0x80}}, /* 0x33 */
- {{0x7F,0x63,0x82,0x6B,0x13,0x00,0x06,0x00,
-    0x75,0xBA,0x29,0x8C,0xDF,0x75,0x80}}, /* 0x34 */
- {{0xA3,0x7F,0x87,0x86,0x97,0x00,0x02,0x00,
-    0x24,0xF1,0xAF,0x85,0x3F,0x25,0xB0}}, /* 0x35 */
- {{0x9F,0x7F,0x83,0x85,0x91,0x00,0x02,0x00,
-    0x1E,0xF1,0xAD,0x81,0x3F,0x1F,0xB0}}, /* 0x36 */
- {{0xA7,0x7F,0x88,0x89,0x15,0x00,0x02,0x00,
-    0x26,0xF1,0xB1,0x85,0x3F,0x27,0xB0}}, /* 0x37 */
- {{0xCE,0x9F,0x92,0xA9,0x17,0x00,0x07,0x00,
-    0x28,0xC4,0x7A,0x8E,0xCF,0x29,0xA1}}, /* 0x38 */
- {{0xCE,0x9F,0x92,0xA5,0x17,0x00,0x07,0x00,
-    0x28,0xD4,0x7A,0x8E,0xCF,0x29,0xA1}}, /* 0x39 */
- {{0xD3,0x9F,0x97,0xAB,0x1F,0x00,0x07,0x00,
-    0x2E,0xD4,0x7D,0x81,0xCF,0x2F,0xA1}}, /* 0x3a */
- {{0xDC,0x9F,0x00,0xAB,0x19,0x00,0x07,0x00,
-    0xE6,0xEF,0xC0,0xC3,0xBF,0xE7,0x90}}, /* 0x3b */
- {{0x6B,0x59,0x8F,0x5E,0x8C,0x00,0x05,0x00,
-    0x0B,0x3E,0xE9,0x8B,0xE7,0x04,0x00}}, /* 0x3c */
- {{0x7B,0x63,0x9F,0x6A,0x93,0x00,0x05,0x00,
-    0x6F,0xF0,0x58,0x8A,0x57,0x70,0xA0}}, /* 0x3d */
- {{0x86,0x6A,0x8a,0x74,0x06,0x00,0x02,0x00,
-    0x8c,0x15,0x4f,0x83,0xef,0x8d,0x30}}, /* 0x3e */
- {{0x81,0x6A,0x85,0x70,0x00,0x00,0x02,0x00,
-    0x0f,0x3e,0xeb,0x8e,0xdf,0x10,0x00}}, /* 0x3f */
- {{0xCE,0x9F,0x92,0xA9,0x17,0x00,0x07,0x00,
-    0x20,0xF5,0x03,0x88,0xFF,0x21,0x90}}, /* 0x40 */
- {{0xE6,0xAE,0x8A,0xBD,0x90,0x00,0x03,0x00,
-    0x3D,0x10,0x1A,0x8D,0x19,0x3E,0x2F}}, /* 0x41 */
- {{0xB9,0x8F,0x9D,0x9B,0x8A,0x00,0x06,0x00,
-    0x7D,0xFF,0x60,0x83,0x5F,0x7E,0x90}}, /* 0x42 */
- {{0xC3,0x8F,0x87,0x9B,0x0B,0x00,0x07,0x00,
-    0x82,0xFF,0x60,0x83,0x5F,0x83,0x90}},  /* 0x43 */
- {{0xAD,0x7F,0x91,0x8E,0x9C,0x00,0x02,0x82,
-    0x49,0xF5,0x00,0x83,0xFF,0x4A,0x90}},  /* 0x44 */
- {{0xCD,0x9F,0x91,0xA7,0x19,0x00,0x07,0x60,
-    0xE6,0xFF,0xC0,0x83,0xBF,0xE7,0x90}},  /* 0x45 */
- {{0xD3,0x9F,0x97,0xAB,0x1F,0x00,0x07,0x60,
-    0xF1,0xFF,0xC0,0x83,0xBF,0xF2,0x90}},  /* 0x46 */
- {{0xD7,0x9F,0x9B,0xAC,0x1E,0x00,0x07,0x00,
-    0x03,0xDE,0xC0,0x84,0xBF,0x04,0x90}}  /* 0x47 */
+static struct XGI_CRT1TableStruct XGI_CRT1Table[] = {
+	{ {0x2d, 0x28, 0x90, 0x2c, 0x90, 0x00, 0x04, 0x00,
+	  0xbf, 0x1f, 0x9c, 0x8e, 0x96, 0xb9, 0x30} }, /* 0x0 */
+	{ {0x2d, 0x28, 0x90, 0x2c, 0x90, 0x00, 0x04, 0x00,
+	  0x0b, 0x3e, 0xe9, 0x8b, 0xe7, 0x04, 0x00} }, /* 0x1 */
+	{ {0x3D, 0x31, 0x81, 0x37, 0x1F, 0x00, 0x05, 0x00,
+	  0x72, 0xF0, 0x58, 0x8C, 0x57, 0x73, 0xA0} }, /* 0x2 */
+	{ {0x4F, 0x3F, 0x93, 0x45, 0x0D, 0x00, 0x01, 0x00,
+	  0x24, 0xF5, 0x02, 0x88, 0xFF, 0x25, 0x90} }, /* 0x3 */
+	{ {0x5F, 0x50, 0x82, 0x55, 0x81, 0x00, 0x05, 0x00,
+	  0xBF, 0x1F, 0x9C, 0x8E, 0x96, 0xB9, 0x30} }, /* 0x4 */
+	{ {0x5F, 0x50, 0x82, 0x55, 0x81, 0x00, 0x05, 0x00,
+	  0x0B, 0x3E, 0xE9, 0x8B, 0xE7, 0x04, 0x00} }, /* 0x5 */
+	{ {0x63, 0x50, 0x86, 0x56, 0x9B, 0x00, 0x01, 0x00,
+	  0x06, 0x3E, 0xE8, 0x8B, 0xE7, 0xFF, 0x10} }, /* 0x6 */
+	{ {0x64, 0x4F, 0x88, 0x55, 0x9D, 0x00, 0x01, 0x00,
+	  0xF2, 0x1F, 0xE0, 0x83, 0xDF, 0xF3, 0x10} }, /* 0x7 */
+	{ {0x63, 0x4F, 0x87, 0x5A, 0x81, 0x00, 0x05, 0x00,
+	  0xFB, 0x1F, 0xE0, 0x83, 0xDF, 0xFC, 0x10} }, /* 0x8 */
+	{ {0x65, 0x4F, 0x89, 0x58, 0x80, 0x00, 0x05, 0x60,
+	  0xFB, 0x1F, 0xE0, 0x83, 0xDF, 0xFC, 0x80} }, /* 0x9 */
+	{ {0x65, 0x4F, 0x89, 0x58, 0x80, 0x00, 0x05, 0x60,
+	  0x01, 0x3E, 0xE0, 0x83, 0xDF, 0x02, 0x80} }, /* 0xa */
+	{ {0x67, 0x4F, 0x8B, 0x58, 0x81, 0x00, 0x05, 0x60,
+	  0x0D, 0x3E, 0xE0, 0x83, 0xDF, 0x0E, 0x90} }, /* 0xb */
+	{ {0x65, 0x4F, 0x89, 0x57, 0x9F, 0x00, 0x01, 0x00,
+	  0xFB, 0x1F, 0xE6, 0x8A, 0xDF, 0xFC, 0x10} }, /* 0xc */
+	{ {0x7B, 0x63, 0x9F, 0x6A, 0x93, 0x00, 0x05, 0x00, /* ;
+						0D (800x600,56Hz) */
+	  0x6F, 0xF0, 0x58, 0x8A, 0x57, 0x70, 0xA0} },     /* ;
+						(VCLK 36.0MHz) */
+	{ {0x7F, 0x63, 0x83, 0x6C, 0x1C, 0x00, 0x06, 0x00, /* ;
+						0E (800x600,60Hz) */
+	  0x72, 0xF0, 0x58, 0x8C, 0x57, 0x73, 0xA0} },     /* ;
+						(VCLK 40.0MHz) */
+	{ {0x7D, 0x63, 0x81, 0x6E, 0x1D, 0x00, 0x06, 0x00, /* ;
+						0F (800x600,72Hz) */
+	  0x98, 0xF0, 0x7C, 0x82, 0x57, 0x99, 0x80} },     /* ;
+						(VCLK 50.0MHz) */
+	{ {0x7F, 0x63, 0x83, 0x69, 0x13, 0x00, 0x06, 0x00, /* ;
+						10 (800x600,75Hz) */
+	  0x6F, 0xF0, 0x58, 0x8B, 0x57, 0x70, 0xA0} },     /* ;
+						(VCLK 49.5MHz) */
+	{ {0x7E, 0x63, 0x82, 0x6B, 0x13, 0x00, 0x06, 0x00, /* ;
+						11 (800x600,85Hz) */
+	  0x75, 0xF0, 0x58, 0x8B, 0x57, 0x76, 0xA0} },     /* ;
+						(VCLK 56.25MHz) */
+	{ {0x81, 0x63, 0x85, 0x6D, 0x18, 0x00, 0x06, 0x60, /* ;
+						12 (800x600,100Hz) */
+	  0x7A, 0xF0, 0x58, 0x8B, 0x57, 0x7B, 0xA0} },     /* ;
+						(VCLK 75.8MHz) */
+	{ {0x83, 0x63, 0x87, 0x6E, 0x19, 0x00, 0x06, 0x60, /* ;
+						13 (800x600,120Hz) */
+	  0x81, 0xF0, 0x58, 0x8B, 0x57, 0x82, 0xA0} },     /* ;
+						(VCLK 79.411MHz) */
+	{ {0x85, 0x63, 0x89, 0x6F, 0x1A, 0x00, 0x06, 0x60, /* ;
+						14 (800x600,160Hz) */
+	  0x91, 0xF0, 0x58, 0x8B, 0x57, 0x92, 0xA0} },     /* ;
+						(VCLK 105.822MHz) */
+	{ {0x99, 0x7F, 0x9D, 0x84, 0x1A, 0x00, 0x02, 0x00,
+	  0x96, 0x1F, 0x7F, 0x83, 0x7F, 0x97, 0x10} }, /* 0x15 */
+	{ {0xA3, 0x7F, 0x87, 0x86, 0x97, 0x00, 0x02, 0x00,
+	  0x24, 0xF5, 0x02, 0x88, 0xFF, 0x25, 0x90} }, /* 0x16 */
+	{ {0xA1, 0x7F, 0x85, 0x86, 0x97, 0x00, 0x02, 0x00,
+	  0x24, 0xF5, 0x02, 0x88, 0xFF, 0x25, 0x90} }, /* 0x17 */
+	{ {0x9F, 0x7F, 0x83, 0x85, 0x91, 0x00, 0x02, 0x00,
+	  0x1E, 0xF5, 0x00, 0x83, 0xFF, 0x1F, 0x90} }, /* 0x18 */
+	{ {0xA7, 0x7F, 0x8B, 0x89, 0x95, 0x00, 0x02, 0x00,
+	  0x26, 0xF5, 0x00, 0x83, 0xFF, 0x27, 0x90} }, /* 0x19 */
+	{ {0xA9, 0x7F, 0x8D, 0x8C, 0x9A, 0x00, 0x02, 0x62,
+	  0x2C, 0xF5, 0x00, 0x83, 0xFF, 0x2D, 0x14} }, /* 0x1a */
+	{ {0xAB, 0x7F, 0x8F, 0x8D, 0x9B, 0x00, 0x02, 0x62,
+	  0x35, 0xF5, 0x00, 0x83, 0xFF, 0x36, 0x14} }, /* 0x1b */
+	{ {0xCF, 0x9F, 0x93, 0xB2, 0x01, 0x00, 0x03, 0x00,
+	  0x14, 0xBA, 0x00, 0x83, 0xFF, 0x15, 0x00} }, /* 0x1c */
+	{ {0xCE, 0x9F, 0x92, 0xA9, 0x17, 0x00, 0x07, 0x00,
+	  0x28, 0x5A, 0x00, 0x83, 0xFF, 0x29, 0x89} }, /* 0x1d */
+	{ {0xCE, 0x9F, 0x92, 0xA5, 0x17, 0x00, 0x07, 0x00,
+	  0x28, 0x5A, 0x00, 0x83, 0xFF, 0x29, 0x89} }, /* 0x1e */
+	{ {0xD3, 0x9F, 0x97, 0xAB, 0x1F, 0x00, 0x07, 0x00,
+	  0x2E, 0x5A, 0x00, 0x83, 0xFF, 0x2F, 0x89} }, /* 0x1f */
+	{ {0x09, 0xC7, 0x8D, 0xD3, 0x0B, 0x01, 0x04, 0x00,
+	  0xE0, 0x10, 0xB0, 0x83, 0xAF, 0xE1, 0x2F} }, /* 0x20 */
+	{ {0x09, 0xC7, 0x8D, 0xD3, 0x0B, 0x01, 0x04, 0x00,
+	  0xE0, 0x10, 0xB0, 0x83, 0xAF, 0xE1, 0x2F} }, /* 0x21 */
+	{ {0x09, 0xC7, 0x8D, 0xD3, 0x0B, 0x01, 0x04, 0x00,
+	  0xE0, 0x10, 0xB0, 0x83, 0xAF, 0xE1, 0x2F} }, /* 0x22 */
+	{ {0x09, 0xC7, 0x8D, 0xD3, 0x0B, 0x01, 0x04, 0x00,
+	  0xE0, 0x10, 0xB0, 0x83, 0xAF, 0xE1, 0x2F} }, /* 0x23 */
+	{ {0x09, 0xC7, 0x8D, 0xD3, 0x0B, 0x01, 0x04, 0x00,
+	  0xE0, 0x10, 0xB0, 0x83, 0xAF, 0xE1, 0x2F} }, /* 0x24 */
+	{ {0x09, 0xC7, 0x8D, 0xD3, 0x0B, 0x01, 0x04, 0x00,
+	  0xE0, 0x10, 0xB0, 0x83, 0xAF, 0xE1, 0x2F} }, /* 0x25 */
+	{ {0x09, 0xC7, 0x8D, 0xD3, 0x0B, 0x01, 0x04, 0x00,
+	  0xE0, 0x10, 0xB0, 0x83, 0xAF, 0xE1, 0x2F} }, /* 0x26 */
+	{ {0x40, 0xEF, 0x84, 0x03, 0x1D, 0x41, 0x01, 0x00,
+	  0xDA, 0x1F, 0xA0, 0x83, 0x9F, 0xDB, 0x1F} }, /* 0x27 */
+	{ {0x43, 0xEF, 0x87, 0x06, 0x00, 0x41, 0x05, 0x62,
+	  0xD4, 0x1F, 0xA0, 0x83, 0x9F, 0xD5, 0x9F} }, /* 0x28 */
+	{ {0x45, 0xEF, 0x89, 0x07, 0x01, 0x41, 0x05, 0x62,
+	  0xD9, 0x1F, 0xA0, 0x83, 0x9F, 0xDA, 0x9F} }, /* 0x29 */
+	{ {0x40, 0xEF, 0x84, 0x03, 0x1D, 0x41, 0x01, 0x00,
+	  0xDA, 0x1F, 0xA0, 0x83, 0x9F, 0xDB, 0x1F} }, /* 0x2a */
+	{ {0x40, 0xEF, 0x84, 0x03, 0x1D, 0x41, 0x01, 0x00,
+	  0xDA, 0x1F, 0xA0, 0x83, 0x9F, 0xDB, 0x1F} }, /* 0x2b */
+	{ {0x40, 0xEF, 0x84, 0x03, 0x1D, 0x41, 0x01, 0x00,
+	  0xDA, 0x1F, 0xA0, 0x83, 0x9F, 0xDB, 0x1F} }, /* 0x2c */
+	{ {0x59, 0xFF, 0x9D, 0x17, 0x13, 0x41, 0x05, 0x44,
+	  0x33, 0xBA, 0x00, 0x83, 0xFF, 0x34, 0x0F} }, /* 0x2d */
+	{ {0x5B, 0xFF, 0x9F, 0x18, 0x14, 0x41, 0x05, 0x44,
+	  0x38, 0xBA, 0x00, 0x83, 0xFF, 0x39, 0x0F} }, /* 0x2e */
+	{ {0x5B, 0xFF, 0x9F, 0x18, 0x14, 0x41, 0x05, 0x44,
+	  0x3D, 0xBA, 0x00, 0x83, 0xFF, 0x3E, 0x0F} }, /* 0x2f */
+	{ {0x5D, 0xFF, 0x81, 0x19, 0x95, 0x41, 0x05, 0x44,
+	  0x41, 0xBA, 0x00, 0x84, 0xFF, 0x42, 0x0F} }, /* 0x30 */
+	{ {0x55, 0xFF, 0x99, 0x0D, 0x0C, 0x41, 0x05, 0x00,
+	  0x3E, 0xBA, 0x00, 0x84, 0xFF, 0x3F, 0x0F} }, /* 0x31 */
+	{ {0x7F, 0x63, 0x83, 0x6C, 0x1C, 0x00, 0x06, 0x00,
+	  0x72, 0xBA, 0x27, 0x8B, 0xDF, 0x73, 0x80} }, /* 0x32 */
+	{ {0x7F, 0x63, 0x83, 0x69, 0x13, 0x00, 0x06, 0x00,
+	  0x6F, 0xBA, 0x26, 0x89, 0xDF, 0x6F, 0x80} }, /* 0x33 */
+	{ {0x7F, 0x63, 0x82, 0x6B, 0x13, 0x00, 0x06, 0x00,
+	  0x75, 0xBA, 0x29, 0x8C, 0xDF, 0x75, 0x80} }, /* 0x34 */
+	{ {0xA3, 0x7F, 0x87, 0x86, 0x97, 0x00, 0x02, 0x00,
+	  0x24, 0xF1, 0xAF, 0x85, 0x3F, 0x25, 0xB0} }, /* 0x35 */
+	{ {0x9F, 0x7F, 0x83, 0x85, 0x91, 0x00, 0x02, 0x00,
+	  0x1E, 0xF1, 0xAD, 0x81, 0x3F, 0x1F, 0xB0} }, /* 0x36 */
+	{ {0xA7, 0x7F, 0x88, 0x89, 0x15, 0x00, 0x02, 0x00,
+	  0x26, 0xF1, 0xB1, 0x85, 0x3F, 0x27, 0xB0} }, /* 0x37 */
+	{ {0xCE, 0x9F, 0x92, 0xA9, 0x17, 0x00, 0x07, 0x00,
+	  0x28, 0xC4, 0x7A, 0x8E, 0xCF, 0x29, 0xA1} }, /* 0x38 */
+	{ {0xCE, 0x9F, 0x92, 0xA5, 0x17, 0x00, 0x07, 0x00,
+	  0x28, 0xD4, 0x7A, 0x8E, 0xCF, 0x29, 0xA1} }, /* 0x39 */
+	{ {0xD3, 0x9F, 0x97, 0xAB, 0x1F, 0x00, 0x07, 0x00,
+	  0x2E, 0xD4, 0x7D, 0x81, 0xCF, 0x2F, 0xA1} }, /* 0x3a */
+	{ {0xDC, 0x9F, 0x00, 0xAB, 0x19, 0x00, 0x07, 0x00,
+	  0xE6, 0xEF, 0xC0, 0xC3, 0xBF, 0xE7, 0x90} }, /* 0x3b */
+	{ {0x6B, 0x59, 0x8F, 0x5E, 0x8C, 0x00, 0x05, 0x00,
+	  0x0B, 0x3E, 0xE9, 0x8B, 0xE7, 0x04, 0x00} }, /* 0x3c */
+	{ {0x7B, 0x63, 0x9F, 0x6A, 0x93, 0x00, 0x05, 0x00,
+	  0x6F, 0xF0, 0x58, 0x8A, 0x57, 0x70, 0xA0} }, /* 0x3d */
+	{ {0x86, 0x6A, 0x8a, 0x74, 0x06, 0x00, 0x02, 0x00,
+	  0x8c, 0x15, 0x4f, 0x83, 0xef, 0x8d, 0x30} }, /* 0x3e */
+	{ {0x81, 0x6A, 0x85, 0x70, 0x00, 0x00, 0x02, 0x00,
+	  0x0f, 0x3e, 0xeb, 0x8e, 0xdf, 0x10, 0x00} }, /* 0x3f */
+	{ {0xCE, 0x9F, 0x92, 0xA9, 0x17, 0x00, 0x07, 0x00,
+	  0x20, 0xF5, 0x03, 0x88, 0xFF, 0x21, 0x90} }, /* 0x40 */
+	{ {0xE6, 0xAE, 0x8A, 0xBD, 0x90, 0x00, 0x03, 0x00,
+	  0x3D, 0x10, 0x1A, 0x8D, 0x19, 0x3E, 0x2F} }, /* 0x41 */
+	{ {0xB9, 0x8F, 0x9D, 0x9B, 0x8A, 0x00, 0x06, 0x00,
+	  0x7D, 0xFF, 0x60, 0x83, 0x5F, 0x7E, 0x90} }, /* 0x42 */
+	{ {0xC3, 0x8F, 0x87, 0x9B, 0x0B, 0x00, 0x07, 0x00,
+	  0x82, 0xFF, 0x60, 0x83, 0x5F, 0x83, 0x90} },  /* 0x43 */
+	{ {0xAD, 0x7F, 0x91, 0x8E, 0x9C, 0x00, 0x02, 0x82,
+	  0x49, 0xF5, 0x00, 0x83, 0xFF, 0x4A, 0x90} },  /* 0x44 */
+	{ {0xCD, 0x9F, 0x91, 0xA7, 0x19, 0x00, 0x07, 0x60,
+	  0xE6, 0xFF, 0xC0, 0x83, 0xBF, 0xE7, 0x90} },  /* 0x45 */
+	{ {0xD3, 0x9F, 0x97, 0xAB, 0x1F, 0x00, 0x07, 0x60,
+	  0xF1, 0xFF, 0xC0, 0x83, 0xBF, 0xF2, 0x90} },  /* 0x46 */
+	{ {0xD7, 0x9F, 0x9B, 0xAC, 0x1E, 0x00, 0x07, 0x00,
+	  0x03, 0xDE, 0xC0, 0x84, 0xBF, 0x04, 0x90} }  /* 0x47 */
 };
 
 #if 0
 static struct XGI330_CHTVRegDataStruct XGI_CHTVRegUNTSC[] = {
-                /* Index:000h,001h,002h,004h,003h,005h,006h,007h,008h,015h,01Fh,00Ch,00Dh,00Eh,00Fh,010h */
-                {{      0x4A,0x77,0xBB,0x94,0x84,0x48,0xFE,0x50,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x01  }},/* 00 (640x200,640x400) */
-                {{      0x4A,0x77,0xBB,0x94,0x84,0x48,0xFE,0x50,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x01  }},/* 01 (640x350) */
-                {{      0x4A,0x77,0xBB,0x94,0x84,0x48,0xFE,0x50,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x01  }},/* 02 (720x400) */
-                {{      0x4A,0x77,0xBB,0x94,0x84,0x48,0xFE,0x50,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x01  }},/* 03 (720x350) */
-                {{      0x6A,0x77,0xBB,0x6E,0x84,0x2E,0x02,0x5A,0x04,0x00,0x80,0x20,0x7E,0x80,0x97,0x00  }},/* 04 (640x480) ;;5/6/02 */
-                {{      0xCF,0x77,0xB7,0xC8,0x84,0x3B,0x02,0x5A,0x04,0x00,0x80,0x19,0x88,0xAE,0xA3,0x00  }},/* 05 (800x600) ;;1/12/02 */
-                {{      0xEE,0x77,0xBB,0x66,0x87,0x32,0x01,0x5A,0x04,0x00,0x80,0x1B,0xD4,0x2F,0x6F,0x00  }}/* 06 (1024x768) ;;5/6/02 */
-          };
+	/* Index: 000h, 001h, 002h, 004h, 003h, 005h, 006h, 007h,
+		  008h, 015h, 01Fh, 00Ch, 00Dh, 00Eh, 00Fh, 010h */
+	/* 00 (640x200,640x400) */
+	{ {0x4A, 0x77, 0xBB, 0x94, 0x84, 0x48, 0xFE, 0x50,
+	   0x04, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x01  } },
+	/* 01 (640x350) */
+	{ {0x4A, 0x77, 0xBB, 0x94, 0x84, 0x48, 0xFE, 0x50,
+	   0x04, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x01  } },
+	/* 02 (720x400) */
+	{ {0x4A, 0x77, 0xBB, 0x94, 0x84, 0x48, 0xFE, 0x50,
+	   0x04, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x01  } },
+	/* 03 (720x350) */
+	{ {0x4A, 0x77, 0xBB, 0x94, 0x84, 0x48, 0xFE, 0x50,
+	   0x04, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x01  } },
+	/* 04 (640x480) ;;5/6/02 */
+	{ {0x6A, 0x77, 0xBB, 0x6E, 0x84, 0x2E, 0x02, 0x5A,
+	   0x04, 0x00, 0x80, 0x20, 0x7E, 0x80, 0x97, 0x00  } },
+	/* 05 (800x600) ;;1/12/02 */
+	{ {0xCF, 0x77, 0xB7, 0xC8, 0x84, 0x3B, 0x02, 0x5A,
+	   0x04, 0x00, 0x80, 0x19, 0x88, 0xAE, 0xA3, 0x00  } },
+	/* 06 (1024x768) ;;5/6/02 */
+	{ {0xEE, 0x77, 0xBB, 0x66, 0x87, 0x32, 0x01, 0x5A,
+	   0x04, 0x00, 0x80, 0x1B, 0xD4, 0x2F, 0x6F, 0x00  } }
+};
 
 static struct XGI330_CHTVRegDataStruct XGI_CHTVRegONTSC[] = {
-                /* Index:000h,001h,002h,004h,003h,005h,006h,007h,008h,015h,01Fh,00Ch,00Dh,00Eh,00Fh,010h */
-                {{      0x49,0x77,0xBB,0x7B,0x84,0x34,0x00,0x50,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x01  }},/* 00 (640x200,640x400) */
-                {{      0x49,0x77,0xBB,0x7B,0x84,0x34,0x00,0x50,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x01  }},/* 01 (640x350) */
-                {{      0x49,0x77,0xBB,0x7B,0x84,0x34,0x00,0x50,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x01  }},/* 02 (720x400) */
-                {{      0x49,0x77,0xBB,0x7B,0x84,0x34,0x00,0x50,0x04,0x00,0x80,0x00,0x00,0x00,0x00,0x01  }},/* 03 (720x350) */
-                {{      0x69,0x77,0xBB,0x6E,0x84,0x1E,0x00,0x5A,0x04,0x00,0x80,0x25,0x1A,0x80,0x26,0x00  }},/* 04 (640x480) ;;5/6/02 */
-                {{      0xCE,0x77,0xB7,0xB6,0x83,0x2C,0x02,0x5A,0x04,0x00,0x80,0x1C,0x00,0x82,0x97,0x00  }},/* 05 (800x600) ;;5/6/02 */
-                {{      0xED,0x77,0xBB,0x66,0x8C,0x21,0x02,0x5A,0x04,0x00,0x80,0x1F,0xA0,0x7E,0x73,0x00  }}/* 06 (1024x768) ;;5/6/02 */
-          };
+	/* Index: 000h, 001h, 002h, 004h, 003h, 005h, 006h, 007h,
+		  008h, 015h, 01Fh, 00Ch, 00Dh, 00Eh, 00Fh, 010h */
+	/* 00 (640x200,640x400) */
+	{ {0x49, 0x77, 0xBB, 0x7B, 0x84, 0x34, 0x00, 0x50,
+	   0x04, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x01} },
+	/* 01 (640x350) */
+	{ {0x49, 0x77, 0xBB, 0x7B, 0x84, 0x34, 0x00 , 0x50,
+	   0x04, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x01} },
+	/* 02 (720x400) */
+	{ {0x49, 0x77, 0xBB, 0x7B, 0x84, 0x34, 0x00 , 0x50,
+	   0x04, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x01} },
+	/* 03 (720x350) */
+	{ {0x49, 0x77, 0xBB, 0x7B, 0x84, 0x34, 0x00 , 0x50,
+	   0x04, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x01} },
+	/* 04 (640x480) ;;5/6/02 */
+	{ {0x69, 0x77, 0xBB, 0x6E, 0x84, 0x1E, 0x00 , 0x5A,
+	   0x04, 0x00, 0x80, 0x25, 0x1A, 0x80, 0x26, 0x00} },
+	/* 05 (800x600) ;;5/6/02 */
+	{ {0xCE, 0x77, 0xB7, 0xB6, 0x83, 0x2C, 0x02 , 0x5A,
+	   0x04, 0x00, 0x80, 0x1C, 0x00, 0x82, 0x97, 0x00} },
+	/* 06 (1024x768) ;;5/6/02 */
+	{ {0xED, 0x77, 0xBB, 0x66, 0x8C, 0x21, 0x02 , 0x5A,
+	   0x04, 0x00, 0x80, 0x1F, 0xA0, 0x7E, 0x73, 0x00} }
+};
 
 static struct XGI330_CHTVRegDataStruct XGI_CHTVRegUPAL[] = {
-                /* Index:000h,001h,002h,004h,003h,005h,006h,007h,008h,015h,01Fh,00Ch,00Dh,00Eh,00Fh,010h */
-                {{      0x41,0x7F,0xB7,0x34,0xAD,0x50,0x34,0x83,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x01  }},/* ; 00 (640x200,640x400) */
-                {{      0x41,0x7F,0xB7,0x80,0x85,0x50,0x00,0x83,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x01  }},/* ; 01 (640x350) */
-                {{      0x41,0x7F,0xB7,0x34,0xAD,0x50,0x34,0x83,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x01  }},/* ; 02 (720x400) */
-                {{      0x41,0x7F,0xB7,0x12,0x85,0x50,0x00,0x83,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x01  }},/* ; 03 (720x350) */
-                {{      0x61,0x7F,0xB7,0x99,0x84,0x35,0x04,0x5A,0x05,0x00,0x80,0x26,0x2A,0x55,0x5D,0x00  }},/* ; 04 (640x480) */
-                {{      0xC3,0x7F,0xB7,0x7A,0x84,0x40,0x02,0x5A,0x05,0x00,0x80,0x1F,0x84,0x3D,0x28,0x00  }},/* ; 05 (800x600) ;;1/12/02 */
-                {{      0xE5,0x7F,0xB7,0x1D,0xA7,0x3E,0x04,0x5A,0x05,0x00,0x80,0x20,0x3E,0xE4,0x22,0x00  }}/* ; 06 (1024x768) ;;1/12/02 */
-	  };
+	/* Index: 000h, 001h, 002h, 004h, 003h, 005h, 006h, 007h,
+		  008h, 015h, 01Fh, 00Ch, 00Dh, 00Eh, 00Fh, 010h */
+	/* ; 00 (640x200,640x400) */
+	{ {0x41, 0x7F, 0xB7, 0x34, 0xAD, 0x50, 0x34, 0x83,
+	   0x05, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x01} },
+	/* ; 01 (640x350) */
+	{ {0x41, 0x7F, 0xB7, 0x80, 0x85, 0x50, 0x00, 0x83,
+	   0x05, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x01} },
+	/* ; 02 (720x400) */
+	{ {0x41, 0x7F, 0xB7, 0x34, 0xAD, 0x50, 0x34, 0x83,
+	   0x05, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x01} },
+	/* ; 03 (720x350) */
+	{ {0x41, 0x7F, 0xB7, 0x12, 0x85, 0x50, 0x00, 0x83,
+	   0x05, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x01} },
+	/* ; 04 (640x480) */
+	{ {0x61, 0x7F, 0xB7, 0x99, 0x84, 0x35, 0x04, 0x5A,
+	   0x05, 0x00, 0x80, 0x26, 0x2A, 0x55, 0x5D, 0x00} },
+	/* ; 05 (800x600) ;;1/12/02 */
+	{ {0xC3, 0x7F, 0xB7, 0x7A, 0x84, 0x40, 0x02, 0x5A,
+	   0x05, 0x00, 0x80, 0x1F, 0x84, 0x3D, 0x28, 0x00} },
+	/* ; 06 (1024x768) ;;1/12/02 */
+	{ {0xE5, 0x7F, 0xB7, 0x1D, 0xA7, 0x3E, 0x04, 0x5A,
+	   0x05, 0x00, 0x80, 0x20, 0x3E, 0xE4, 0x22, 0x00} }
+};
 
 static struct XGI330_CHTVRegDataStruct XGI_CHTVRegOPAL[] = {
-                /* Index:000,0x01,0x02,0x04,0x03,0x05,0x06,0x07,0x08,0x15,0x1F,0x0C,0x0D,0x0E,0x0F,0x10h */
-                {{      0x41,0x7F,0xB7,0x36,0xAD,0x50,0x34,0x83,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x01 }},/* 00 (640x200,640x400) */
-                {{      0x41,0x7F,0xB7,0x86,0x85,0x50,0x00,0x83,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x01 }},/* 01 (640x350) */
-                {{      0x41,0x7F,0xB7,0x36,0xAD,0x50,0x34,0x83,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x01 }},/* 02 (720x400) */
-                {{      0x41,0x7F,0xB7,0x86,0x85,0x50,0x00,0x83,0x05,0x00,0x80,0x00,0x00,0x00,0x00,0x01 }},/* 03 (720x350) */
-                {{      0x61,0x7F,0xB7,0x99,0x84,0x35,0x04,0x5A,0x05,0x00,0x80,0x26,0x2A,0x55,0x5D,0x00 }},/* 04 (640x480) */
-                {{      0xC1,0x7F,0xB7,0x4D,0x8C,0x1E,0x31,0x5A,0x05,0x00,0x80,0x26,0x78,0x19,0x34,0x00 }},/* 05 (800x600) ;;1/12/02 */
-                {{      0xE4,0x7F,0xB7,0x1E,0xAF,0x29,0x37,0x5A,0x05,0x00,0x80,0x25,0x8C,0xB2,0x2A,0x00 }}/* 06 (1024x768) ;;1/12/02 */
-	     };
+	/* Index: 000, 0x01, 0x02, 0x04, 0x03, 0x05, 0x06, 0x07,
+		  0x08, 0x15, 0x1F, 0x0C, 0x0D, 0x0E, 0x0F, 0x10h */
+	/* 00 (640x200,640x400) */
+	{ {0x41, 0x7F, 0xB7, 0x36, 0xAD, 0x50, 0x34, 0x83,
+	   0x05, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x01} },
+	/* 01 (640x350) */
+	{ {0x41, 0x7F, 0xB7, 0x86, 0x85, 0x50, 0x00, 0x83,
+	   0x05, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x01} },
+	/* 02 (720x400) */
+	{ {0x41, 0x7F, 0xB7, 0x36, 0xAD, 0x50, 0x34, 0x83,
+	   0x05, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x01} },
+	/* 03 (720x350) */
+	{ {0x41, 0x7F, 0xB7, 0x86, 0x85, 0x50, 0x00, 0x83,
+	   0x05, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x01} },
+	/* 04 (640x480) */
+	{ {0x61, 0x7F, 0xB7, 0x99, 0x84, 0x35, 0x04, 0x5A,
+	   0x05, 0x00, 0x80, 0x26, 0x2A, 0x55, 0x5D, 0x00} },
+	/* 05 (800x600) ;;1/12/02 */
+	{ {0xC1, 0x7F, 0xB7, 0x4D, 0x8C, 0x1E, 0x31, 0x5A,
+	   0x05, 0x00, 0x80, 0x26, 0x78, 0x19, 0x34, 0x00} },
+	/* 06 (1024x768) ;;1/12/02 */
+	{ {0xE4, 0x7F, 0xB7, 0x1E, 0xAF, 0x29, 0x37, 0x5A,
+	   0x05, 0x00, 0x80, 0x25, 0x8C, 0xB2, 0x2A, 0x00} }
+};
 #endif
 
 static unsigned char XGI_CH7017LV1024x768[] = {
-					0x60, 0x02, 0x00, 0x07, 0x40, 0xED, 0xA3,
-					0xC8, 0xC7, 0xAC, 0xE0, 0x02};
+	0x60, 0x02, 0x00, 0x07, 0x40, 0xED,
+	0xA3, 0xC8, 0xC7, 0xAC, 0xE0, 0x02};
 static unsigned char XGI_CH7017LV1400x1050[] = {
-					 0x60, 0x03, 0x11, 0x00, 0x40, 0xE3, 0xAD,
-					 0xDB, 0xF6, 0xAC, 0xE0, 0x02};
-
+	0x60, 0x03, 0x11, 0x00, 0x40, 0xE3,
+	0xAD, 0xDB, 0xF6, 0xAC, 0xE0, 0x02};
 
 /*add for new UNIVGABIOS*/
-static struct XGI330_LCDDataStruct  XGI_StLCD1024x768Data[] =
-{
- {   62,  25, 800, 546,1344, 806},
- {   32,  15, 930, 546,1344, 806},
- {   62,  25, 800, 546,1344, 806}, /* chiawen for dot9 -> dot8 */
- {  104,  45, 945, 496,1344, 806},
- {   62,  25, 800, 546,1344, 806},
- {   31,  18,1008, 624,1344, 806},
- {    1,   1,1344, 806,1344, 806}
+static struct XGI330_LCDDataStruct  XGI_StLCD1024x768Data[] = {
+	{62,  25, 800,  546, 1344, 806},
+	{32,  15, 930,  546, 1344, 806},
+	{62,  25, 800,  546, 1344, 806}, /*chiawenfordot9->dot8*/
+	{104, 45, 945,  496, 1344, 806},
+	{62,  25, 800,  546, 1344, 806},
+	{31,  18, 1008, 624, 1344, 806},
+	{1,   1,  1344, 806, 1344, 806}
 };
 
-static struct XGI330_LCDDataStruct  XGI_ExtLCD1024x768Data[] =
-{
- {   42,  25,1536, 419,1344, 806}, /* { 12, 5, 896, 512,1344, 806}, // alan 09/12/2003 */
- {   48,  25,1536, 369,1344, 806}, /* { 12, 5, 896, 510,1344, 806}, // alan 09/12/2003 */
- {   42,  25,1536, 419,1344, 806}, /* { 32, 15,1008, 505,1344, 806}, // alan 09/12/2003 */
- {   48,  25,1536, 369,1344, 806}, /* { 32, 15,1008, 514,1344, 806}, // alan 09/12/2003 */
- {   12,   5, 896, 500,1344, 806},
- {   42,  25,1024, 625,1344, 806},
- {    1,   1,1344, 806,1344, 806},
- {   12,   5, 896, 500,1344, 806},
- {   42,  25,1024, 625,1344, 806},
- {    1,   1,1344, 806,1344, 806},
- {   12,   5, 896, 500,1344, 806},
- {   42,  25,1024, 625,1344, 806},
- {    1,   1,1344, 806,1344, 806}
+static struct XGI330_LCDDataStruct  XGI_ExtLCD1024x768Data[] = {
+	/* { 12, 5, 896, 512,1344, 806}, // alan 09/12/2003 */
+	{42, 25, 1536, 419, 1344, 806},
+	/* { 12, 5, 896, 510,1344, 806}, // alan 09/12/2003 */
+	{48, 25, 1536, 369, 1344, 806},
+	/* { 32, 15,1008, 505,1344, 806}, // alan 09/12/2003 */
+	{42, 25, 1536, 419, 1344, 806},
+	/* { 32, 15,1008, 514,1344, 806}, // alan 09/12/2003 */
+	{48, 25, 1536, 369, 1344, 806},
+	{12, 5,  896,  500, 1344, 806},
+	{42, 25, 1024, 625, 1344, 806},
+	{1,  1,  1344, 806, 1344, 806},
+	{12, 5,  896,  500, 1344, 806},
+	{42, 25, 1024, 625, 1344, 806},
+	{1,  1,  1344, 806, 1344, 806},
+	{12, 5,  896,  500, 1344, 806},
+	{42, 25, 1024, 625, 1344, 806},
+	{1,  1,  1344, 806, 1344, 806}
 };
 
-/*struct XGI330_LCDDataStruct  XGI_St2LCD1024x768Data[] =
-{
- {   62,  25, 800, 546,1344, 806},
- {   32,  15, 930, 546,1344, 806},
- {   62,  25, 800, 546,1344, 806},
- {  104,  45, 945, 496,1344, 806},
- {   62,  25, 800, 546,1344, 806},
- {   31,  18,1008, 624,1344, 806},
- {    1,   1,1344, 806,1344, 806}
+/*struct XGI330_LCDDataStruct  XGI_St2LCD1024x768Data[] = {
+	{62,  25, 800,  546, 1344, 806},
+	{32,  15, 930,  546, 1344, 806},
+	{62,  25, 800,  546, 1344, 806},
+	{104, 45, 945,  496, 1344, 806},
+	{62,  25, 800,  546, 1344, 806},
+	{31,  18, 1008, 624, 1344, 806},
+	{1,   1,  1344, 806, 1344, 806}
 };*/
 
-static struct XGI330_LCDDataStruct  XGI_CetLCD1024x768Data[] =
-{
-	{         1,1,1344,806,1344,806           }, /* ; 00 (320x200,320x400,640x200,640x400) */
-        {         1,1,1344,806,1344,806           }, /* 01 (320x350,640x350) */
-        {         1,1,1344,806,1344,806           }, /* 02 (360x400,720x400) */
-        {         1,1,1344,806,1344,806           }, /* 03 (720x350) */
-        {         1,1,1344,806,1344,806           }, /* 04 (640x480x60Hz) */
-        {         1,1,1344,806,1344,806           }, /* 05 (800x600x60Hz) */
-        {         1,1,1344,806,1344,806           }  /* 06 (1024x768x60Hz) */
+static struct XGI330_LCDDataStruct  XGI_CetLCD1024x768Data[] = {
+	{1, 1, 1344, 806, 1344, 806}, /* ; 00 (320x200,320x400,
+					       640x200,640x400) */
+	{1, 1, 1344, 806, 1344, 806}, /* 01 (320x350,640x350) */
+	{1, 1, 1344, 806, 1344, 806}, /* 02 (360x400,720x400) */
+	{1, 1, 1344, 806, 1344, 806}, /* 03 (720x350) */
+	{1, 1, 1344, 806, 1344, 806}, /* 04 (640x480x60Hz) */
+	{1, 1, 1344, 806, 1344, 806}, /* 05 (800x600x60Hz) */
+	{1, 1, 1344, 806, 1344, 806}  /* 06 (1024x768x60Hz) */
 };
 
-static struct XGI330_LCDDataStruct  XGI_StLCD1280x1024Data[] =
-{
- {   22,   5, 800, 510,1650,1088},
- {   22,   5, 800, 510,1650,1088},
- {  176,  45, 900, 510,1650,1088},
- {  176,  45, 900, 510,1650,1088},
- {   22,   5, 800, 510,1650,1088},
- {   13,   5,1024, 675,1560,1152},
- {   16,   9,1266, 804,1688,1072},
- {    1,   1,1688,1066,1688,1066}
+static struct XGI330_LCDDataStruct  XGI_StLCD1280x1024Data[] = {
+	{22,  5,  800,  510,  1650, 1088},
+	{22,  5,  800,  510,  1650, 1088},
+	{176, 45, 900,  510,  1650, 1088},
+	{176, 45, 900,  510,  1650, 1088},
+	{22,  5,  800,  510,  1650, 1088},
+	{13,  5,  1024, 675,  1560, 1152},
+	{16,  9,  1266, 804,  1688, 1072},
+	{1,   1,  1688, 1066, 1688, 1066}
 };
 
-static struct XGI330_LCDDataStruct  XGI_ExtLCD1280x1024Data[] =
-{
- {  211,  60,1024, 501,1688,1066},
- {  211,  60,1024, 508,1688,1066},
- {  211,  60,1024, 501,1688,1066},
- {  211,  60,1024, 508,1688,1066},
- {  211,  60,1024, 500,1688,1066},
- {  211,  75,1024, 625,1688,1066},
- {  211, 120,1280, 798,1688,1066},
- {    1,   1,1688,1066,1688,1066}
+static struct XGI330_LCDDataStruct  XGI_ExtLCD1280x1024Data[] = {
+	{211, 60,  1024, 501,  1688, 1066},
+	{211, 60,  1024, 508,  1688, 1066},
+	{211, 60,  1024, 501,  1688, 1066},
+	{211, 60,  1024, 508,  1688, 1066},
+	{211, 60,  1024, 500,  1688, 1066},
+	{211, 75,  1024, 625,  1688, 1066},
+	{211, 120, 1280, 798,  1688, 1066},
+	{1,   1,   1688, 1066, 1688, 1066}
 };
 
 #if 0
-static struct XGI330_LCDDataStruct  XGI_St2LCD1280x1024Data[] =
-{
- {   22,   5, 800, 510,1650,1088},
- {   22,   5, 800, 510,1650,1088},
- {  176,  45, 900, 510,1650,1088},
- {  176,  45, 900, 510,1650,1088},
- {   22,   5, 800, 510,1650,1088},
- {   13,   5,1024, 675,1560,1152},
- {   16,   9,1266, 804,1688,1072},
- {    1,   1,1688,1066,1688,1066}
+static struct XGI330_LCDDataStruct  XGI_St2LCD1280x1024Data[] = {
+	{22,  5,  800,  510,  1650, 1088},
+	{22,  5,  800,  510,  1650, 1088},
+	{176, 45, 900,  510,  1650, 1088},
+	{176, 45, 900,  510,  1650, 1088},
+	{22,  5,  800,  510,  1650, 1088},
+	{13,  5,  1024, 675,  1560, 1152},
+	{16,  9,  1266, 804,  1688, 1072},
+	{1,   1,  1688, 1066, 1688, 1066}
 };
 #endif
 
-static struct XGI330_LCDDataStruct  XGI_CetLCD1280x1024Data[] =
-{
-	{         1,1,1688,1066,1688,1066         }, /* 00 (320x200,320x400,640x200,640x400) */
-        {         1,1,1688,1066,1688,1066         }, /* 01 (320x350,640x350) */
-        {         1,1,1688,1066,1688,1066         }, /* 02 (360x400,720x400) */
-        {         1,1,1688,1066,1688,1066         }, /* 03 (720x350) */
-        {         1,1,1688,1066,1688,1066         }, /* 04 (640x480x60Hz) */
-        {         1,1,1688,1066,1688,1066         }, /* 05 (800x600x60Hz) */
-        {         1,1,1688,1066,1688,1066         }, /* 06 (1024x768x60Hz) */
-        {         1,1,1688,1066,1688,1066         }, /* 07 (1280x1024x60Hz) */
-        {         1,1,1688,1066,1688,1066         } /* 08 (1400x1050x60Hz) */
+static struct XGI330_LCDDataStruct  XGI_CetLCD1280x1024Data[] = {
+	{1, 1, 1688, 1066, 1688, 1066}, /* 00 (320x200,320x400,
+					       640x200,640x400) */
+	{1, 1, 1688, 1066, 1688, 1066}, /* 01 (320x350,640x350) */
+	{1, 1, 1688, 1066, 1688, 1066}, /* 02 (360x400,720x400) */
+	{1, 1, 1688, 1066, 1688, 1066}, /* 03 (720x350) */
+	{1, 1, 1688, 1066, 1688, 1066}, /* 04 (640x480x60Hz) */
+	{1, 1, 1688, 1066, 1688, 1066}, /* 05 (800x600x60Hz) */
+	{1, 1, 1688, 1066, 1688, 1066}, /* 06 (1024x768x60Hz) */
+	{1, 1, 1688, 1066, 1688, 1066}, /* 07 (1280x1024x60Hz) */
+	{1, 1, 1688, 1066, 1688, 1066}  /* 08 (1400x1050x60Hz) */
 };
 
-static struct XGI330_LCDDataStruct  XGI_StLCD1400x1050Data[] =
-{
-	{         211,100,2100,408,1688,1066      }, /* 00 (320x200,320x400,640x200,640x400) */
-        {         211,64,1536,358,1688,1066       }, /* 01 (320x350,640x350) */
-        {         211,100,2100,408,1688,1066      }, /* 02 (360x400,720x400) */
-        {         211,64,1536,358,1688,1066       }, /* 03 (720x350) */
-        {         211,48,840,488,1688,1066        }, /* 04 (640x480x60Hz) */
-        {         211,72,1008,609,1688,1066       }, /* 05 (800x600x60Hz) */
-        {         211,128,1400,776,1688,1066      }, /* 06 (1024x768x60Hz) */
-        {         1,1,1688,1066,1688,1066         }, /* 07 (1280x1024x60Hz w/o Scaling) */
-        {         1,1,1688,1066,1688,1066         }  /* 08 (1400x1050x60Hz) */
+static struct XGI330_LCDDataStruct  XGI_StLCD1400x1050Data[] = {
+	{211, 100, 2100, 408,  1688, 1066}, /* 00 (320x200,320x400,
+						   640x200,640x400) */
+	{211, 64,  1536, 358,  1688, 1066}, /* 01 (320x350,640x350) */
+	{211, 100, 2100, 408,  1688, 1066}, /* 02 (360x400,720x400) */
+	{211, 64,  1536, 358,  1688, 1066}, /* 03 (720x350) */
+	{211, 48,  840,  488,  1688, 1066}, /* 04 (640x480x60Hz) */
+	{211, 72,  1008, 609,  1688, 1066}, /* 05 (800x600x60Hz) */
+	{211, 128, 1400, 776,  1688, 1066}, /* 06 (1024x768x60Hz) */
+	{1,   1,   1688, 1066, 1688, 1066}, /* 07 (1280x1024x60Hz
+						  w/o Scaling) */
+	{1,   1,   1688, 1066, 1688, 1066}  /* 08 (1400x1050x60Hz) */
 };
 
-static struct XGI330_LCDDataStruct  XGI_ExtLCD1400x1050Data[] =
-{
-	{         211,100,2100,408,1688,1066      }, /* 00 (320x200,320x400,640x200,640x400) */
-        {         211,64,1536,358,1688,1066       }, /* 01 (320x350,640x350) */
-        {         211,100,2100,408,1688,1066      }, /* 02 (360x400,720x400) */
-        {         211,64,1536,358,1688,1066       }, /* 03 (720x350) */
-        {         211,48,840,488,1688,1066        }, /* 04 (640x480x60Hz) */
-        {         211,72,1008,609,1688,1066       }, /* 05 (800x600x60Hz) */
-        {         211,128,1400,776,1688,1066      }, /* 06 (1024x768x60Hz) */
-        {         1,1,1688,1066,1688,1066         }, /* 07 (1280x1024x60Hz w/o Scaling) */
-        {         1,1,1688,1066,1688,1066         }  /* 08 (1400x1050x60Hz) */
+static struct XGI330_LCDDataStruct  XGI_ExtLCD1400x1050Data[] = {
+	{211, 100, 2100, 408,  1688, 1066}, /* 00 (320x200,320x400,
+						   640x200,640x400) */
+	{211, 64,  1536, 358,  1688, 1066}, /* 01 (320x350,640x350) */
+	{211, 100, 2100, 408,  1688, 1066}, /* 02 (360x400,720x400) */
+	{211, 64,  1536, 358,  1688, 1066}, /* 03 (720x350) */
+	{211, 48,  840,  488,  1688, 1066}, /* 04 (640x480x60Hz) */
+	{211, 72,  1008, 609,  1688, 1066}, /* 05 (800x600x60Hz) */
+	{211, 128, 1400, 776,  1688, 1066}, /* 06 (1024x768x60Hz) */
+	{1,   1,   1688, 1066, 1688, 1066}, /* 07 (1280x1024x60Hz
+						  w/o Scaling) */
+	{1,   1,   1688, 1066, 1688, 1066}  /* 08 (1400x1050x60Hz) */
 };
 
-static struct XGI330_LCDDataStruct  XGI_ExtLCD1600x1200Data[] =
-{
-        {         4,1,1620,420,2160,1250          }, /* { 3,1,2160,425,2160,1250 }, // 00 (320x200,320x400,640x200,640x400) // alan 10/14/2003 */
-        {         27,7,1920,375,2160,1250         }, /* 01 (320x350,640x350) */
-        {         4,1,1620,420,2160,1250          }, /* { 3,1,2160,425,2160,1250 }, // 02 (360x400,720x400) // alan 10/14/2003 */
-        {         27,7,1920,375,2160,1250         }, /* 03 (720x350) */
-        {         27,4,800,500,2160,1250          }, /* 04 (640x480x60Hz) */
-        {         4,1,1080,625,2160,1250          }, /* 05 (800x600x60Hz) */
-        {         5,2,1350,800,2160,1250          }, /* 06 (1024x768x60Hz) */
-        {         27,16,1500,1064,2160,1250       }, /* 07 (1280x1024x60Hz) */
-        {         9,7,1920,1106,2160,1250         }, /* 08 (1400x1050x60Hz) */
-        {         1,1,2160,1250,2160,1250         }  /* 09 (1600x1200x60Hz) ;302lv */
+static struct XGI330_LCDDataStruct  XGI_ExtLCD1600x1200Data[] = {
+	{4,  1,  1620, 420,  2160, 1250}, /* { 3,1,2160,425,2160,1250 },
+					  // 00 (320x200,320x400,
+					  //	 640x200,640x400)
+					  //	 // alan 10/14/2003 */
+	{27, 7,  1920, 375,  2160, 1250}, /* 01 (320x350,640x350) */
+	{4,  1,  1620, 420,  2160, 1250}, /* { 3,1,2160,425,2160,1250 },
+					  // 02 (360x400,720x400)
+					  // // alan 10/14/2003 */
+	{27, 7,  1920, 375,  2160, 1250}, /* 03 (720x350) */
+	{27, 4,  800,  500,  2160, 1250}, /* 04 (640x480x60Hz) */
+	{4,  1,  1080, 625,  2160, 1250}, /* 05 (800x600x60Hz) */
+	{5,  2,  1350, 800,  2160, 1250}, /* 06 (1024x768x60Hz) */
+	{27, 16, 1500, 1064, 2160, 1250}, /* 07 (1280x1024x60Hz) */
+	{9,  7,  1920, 1106, 2160, 1250}, /* 08 (1400x1050x60Hz) */
+	{1,  1,  2160, 1250, 2160, 1250}  /* 09 (1600x1200x60Hz) ;302lv */
 };
 
-static struct XGI330_LCDDataStruct  XGI_StLCD1600x1200Data[] =
-{
-        {         27,4,800,500,2160,1250          },/* 00 (320x200,320x400,640x200,640x400) */
-        {         27,4,800,500,2160,1250          },/* 01 (320x350,640x350) */
-        {         27,4,800,500,2160,1250          },/* 02 (360x400,720x400) */
-        {         27,4,800,500,2160,1250          },/* 03 (720x350) */
-        {         27,4,800,500,2160,1250          },/* 04 (320x240,640x480) */
-        {         4,1,1080,625,2160,1250          },/* 05 (400x300,800x600) */
-        {         5,2,1350,800,2160,1250          },/* 06 (512x384,1024x768) */
-        {         135,88,1600,1100,2160,1250      },/* 07 (1280x1024) */
-        {         1,1,1800,1500,2160,1250         },/* 08 (1400x1050) */
-        {         1,1,2160,1250,2160,1250         } /* 09 (1600x1200) */
+static struct XGI330_LCDDataStruct  XGI_StLCD1600x1200Data[] = {
+	{27,  4,  800,  500,  2160, 1250}, /* 00 (320x200,320x400,
+						  640x200,640x400) */
+	{27,  4,  800,  500,  2160, 1250}, /* 01 (320x350,640x350) */
+	{27,  4,  800,  500,  2160, 1250}, /* 02 (360x400,720x400) */
+	{27,  4,  800,  500,  2160, 1250}, /* 03 (720x350) */
+	{27,  4,  800,  500,  2160, 1250}, /* 04 (320x240,640x480) */
+	{4,   1,  1080, 625,  2160, 1250}, /* 05 (400x300,800x600) */
+	{5,   2,  1350, 800,  2160, 1250}, /* 06 (512x384,1024x768) */
+	{135, 88, 1600, 1100, 2160, 1250}, /* 07 (1280x1024) */
+	{1,   1,  1800, 1500, 2160, 1250}, /* 08 (1400x1050) */
+	{1,   1,  2160, 1250, 2160, 1250}  /* 09 (1600x1200) */
 };
 
-static struct XGI330_LCDDataStruct  XGI_CetLCD1400x1050Data[] =
-{
-	{         1,1,1688,1066,1688,1066         }, /* 00 (320x200,320x400,640x200,640x400) */
-        {         1,1,1688,1066,1688,1066         }, /* 01 (320x350,640x350) */
-        {         1,1,1688,1066,1688,1066         }, /* 02 (360x400,720x400) */
-        {         1,1,1688,1066,1688,1066         }, /* 03 (720x350) */
-        {         1,1,1688,1066,1688,1066         }, /* 04 (640x480x60Hz) */
-        {         1,1,1688,1066,1688,1066         }, /* 05 (800x600x60Hz) */
-        {         1,1,1688,1066,1688,1066         }, /* 06 (1024x768x60Hz) */
-        {         1,1,1688,1066,1688,1066         }, /* 07 (1280x1024x60Hz) */
-        {         1,1,1688,1066,1688,1066         }  /* 08 (1400x1050x60Hz) */
+static struct XGI330_LCDDataStruct  XGI_CetLCD1400x1050Data[] = {
+	{1, 1, 1688, 1066, 1688, 1066}, /* 00 (320x200,320x400,
+					       640x200,640x400) */
+	{1, 1, 1688, 1066, 1688, 1066}, /* 01 (320x350,640x350) */
+	{1, 1, 1688, 1066, 1688, 1066}, /* 02 (360x400,720x400) */
+	{1, 1, 1688, 1066, 1688, 1066}, /* 03 (720x350) */
+	{1, 1, 1688, 1066, 1688, 1066}, /* 04 (640x480x60Hz) */
+	{1, 1, 1688, 1066, 1688, 1066}, /* 05 (800x600x60Hz) */
+	{1, 1, 1688, 1066, 1688, 1066}, /* 06 (1024x768x60Hz) */
+	{1, 1, 1688, 1066, 1688, 1066}, /* 07 (1280x1024x60Hz) */
+	{1, 1, 1688, 1066, 1688, 1066}  /* 08 (1400x1050x60Hz) */
 };
 
-static struct XGI330_LCDDataStruct  XGI_NoScalingData[] =
-{
- {    1,   1, 800, 449, 800, 449},
- {    1,   1, 800, 449, 800, 449},
- {    1,   1, 900, 449, 900, 449},
- {    1,   1, 900, 449, 900, 449},
- {    1,   1, 800, 525, 800, 525},
- {    1,   1,1056, 628,1056, 628},
- {    1,   1,1344, 806,1344, 806},
- {    1,   1,1688,1066,1688,1066}
+static struct XGI330_LCDDataStruct  XGI_NoScalingData[] = {
+	{1, 1, 800,  449,  800,  449},
+	{1, 1, 800,  449,  800,  449},
+	{1, 1, 900,  449,  900,  449},
+	{1, 1, 900,  449,  900,  449},
+	{1, 1, 800,  525,  800,  525},
+	{1, 1, 1056, 628,  1056, 628},
+	{1, 1, 1344, 806,  1344, 806},
+	{1, 1, 1688, 1066, 1688, 1066}
 };
 
-static struct XGI330_LCDDataStruct  XGI_ExtLCD1024x768x75Data[] =
-{
-        {42,25,1536,419,1344,806 }, /* ; 00 (320x200,320x400,640x200,640x400) */
-        {48,25,1536,369,1344,806 }, /* ; 01 (320x350,640x350) */
-        {42,25,1536,419,1344,806 }, /* ; 02 (360x400,720x400) */
-        {48,25,1536,369,1344,806 }, /* ; 03 (720x350) */
-        {8,5,1312,500,1312,800   }, /* ; 04 (640x480x75Hz) */
-        {41,25,1024,625,1312,800 }, /* ; 05 (800x600x75Hz) */
-        {1,1,1312,800,1312,800   }  /* ; 06 (1024x768x75Hz) */
+static struct XGI330_LCDDataStruct  XGI_ExtLCD1024x768x75Data[] = {
+	{42, 25, 1536, 419, 1344, 806}, /* ; 00 (320x200,320x400,
+						 640x200,640x400) */
+	{48, 25, 1536, 369, 1344, 806}, /* ; 01 (320x350,640x350) */
+	{42, 25, 1536, 419, 1344, 806}, /* ; 02 (360x400,720x400) */
+	{48, 25, 1536, 369, 1344, 806}, /* ; 03 (720x350) */
+	{8,  5,  1312, 500, 1312, 800}, /* ; 04 (640x480x75Hz) */
+	{41, 25, 1024, 625, 1312, 800}, /* ; 05 (800x600x75Hz) */
+	{1,  1,  1312, 800, 1312, 800}  /* ; 06 (1024x768x75Hz) */
 };
 
 #if 0
-static struct XGI330_LCDDataStruct  XGI_StLCD1024x768x75Data[] =
-{
-        {42,25,1536,419,1344,806 }, /* ; 00 (320x200,320x400,640x200,640x400) */
-        {48,25,1536,369,1344,806 }, /* ; 01 (320x350,640x350) */
-        {42,25,1536,419,1344,806 }, /* ; 02 (360x400,720x400) */
-        {48,25,1536,369,1344,806 }, /* ; 03 (720x350) */
-        {8,5,1312,500,1312,800   }, /* ; 04 (640x480x75Hz) */
-        {41,25,1024,625,1312,800 }, /* ; 05 (800x600x75Hz) */
-        {1,1,1312,800,1312,800   }  /* ; 06 (1024x768x75Hz) */
+static struct XGI330_LCDDataStruct  XGI_StLCD1024x768x75Data[] = {
+	{42, 25, 1536, 419, 1344, 806}, /* ; 00 (320x200,320x400,
+						 640x200,640x400) */
+	{48, 25, 1536, 369, 1344, 806}, /* ; 01 (320x350,640x350) */
+	{42, 25, 1536, 419, 1344, 806}, /* ; 02 (360x400,720x400) */
+	{48, 25, 1536, 369, 1344, 806}, /* ; 03 (720x350) */
+	{8,  5,  1312, 500, 1312, 800}, /* ; 04 (640x480x75Hz) */
+	{41, 25, 1024, 625, 1312, 800}, /* ; 05 (800x600x75Hz) */
+	{1,  1,  1312, 800, 1312, 800}  /* ; 06 (1024x768x75Hz) */
 };
 #endif
 
-static struct XGI330_LCDDataStruct  XGI_CetLCD1024x768x75Data[] =
-{
-        {1,1,1312,800,1312,800}, /* ; 00 (320x200,320x400,640x200,640x400) */
-        {1,1,1312,800,1312,800}, /* ; 01 (320x350,640x350) */
-        {1,1,1312,800,1312,800}, /* ; 02 (360x400,720x400) */
-        {1,1,1312,800,1312,800}, /* ; 03 (720x350) */
-        {1,1,1312,800,1312,800}, /* ; 04 (640x480x75Hz) */
-        {1,1,1312,800,1312,800}, /* ; 05 (800x600x75Hz) */
-        {1,1,1312,800,1312,800} /* ; 06 (1024x768x75Hz) */
+static struct XGI330_LCDDataStruct  XGI_CetLCD1024x768x75Data[] = {
+	{1, 1, 1312, 800, 1312, 800}, /* ; 00 (320x200,320x400,
+					       640x200,640x400) */
+	{1, 1, 1312, 800, 1312, 800}, /* ; 01 (320x350,640x350) */
+	{1, 1, 1312, 800, 1312, 800}, /* ; 02 (360x400,720x400) */
+	{1, 1, 1312, 800, 1312, 800}, /* ; 03 (720x350) */
+	{1, 1, 1312, 800, 1312, 800}, /* ; 04 (640x480x75Hz) */
+	{1, 1, 1312, 800, 1312, 800}, /* ; 05 (800x600x75Hz) */
+	{1, 1, 1312, 800, 1312, 800}  /* ; 06 (1024x768x75Hz) */
 };
 
-static struct XGI330_LCDDataStruct  XGI_ExtLCD1280x1024x75Data[] =
-{
-        {211,60,1024,501,1688,1066   }, /* ; 00 (320x200,320x400,640x200,640x400) */
-        {211,60,1024,508,1688,1066   }, /* ; 01 (320x350,640x350) */
-        {211,60,1024,501,1688,1066   }, /* ; 02 (360x400,720x400) */
-        {211,60,1024,508,1688,1066   }, /* ; 03 (720x350) */
-        {211,45,768,498,1688,1066    }, /* ; 04 (640x480x75Hz) */
-        {211,75,1024,625,1688,1066   }, /* ; 05 (800x600x75Hz) */
-        {211,120,1280,798,1688,1066  }, /* ; 06 (1024x768x75Hz) */
-        {1,1,1688,1066,1688,1066     }  /* ; 07 (1280x1024x75Hz) */
+static struct XGI330_LCDDataStruct  XGI_ExtLCD1280x1024x75Data[] = {
+	{211, 60,  1024, 501,  1688, 1066}, /* ; 00 (320x200,320x400,
+						     640x200,640x400) */
+	{211, 60,  1024, 508,  1688, 1066}, /* ; 01 (320x350,640x350) */
+	{211, 60,  1024, 501,  1688, 1066}, /* ; 02 (360x400,720x400) */
+	{211, 60,  1024, 508,  1688, 1066}, /* ; 03 (720x350) */
+	{211, 45,  768,  498,  1688, 1066}, /* ; 04 (640x480x75Hz) */
+	{211, 75,  1024, 625,  1688, 1066}, /* ; 05 (800x600x75Hz) */
+	{211, 120, 1280, 798,  1688, 1066}, /* ; 06 (1024x768x75Hz) */
+	{1,   1,   1688, 1066, 1688, 1066}  /* ; 07 (1280x1024x75Hz) */
 };
 
-static struct XGI330_LCDDataStruct  XGI_StLCD1280x1024x75Data[] =
-{
-        {211,60,1024,501,1688,1066 }, /* ; 00 (320x200,320x400,640x200,640x400) */
-        {211,60,1024,508,1688,1066 }, /* ; 01 (320x350,640x350) */
-        {211,60,1024,501,1688,1066 }, /* ; 02 (360x400,720x400) */
-        {211,60,1024,508,1688,1066 }, /* ; 03 (720x350) */
-        {211,45,768,498,1688,1066  }, /* ; 04 (640x480x75Hz) */
-        {211,75,1024,625,1688,1066 }, /* ; 05 (800x600x75Hz) */
-        {211,120,1280,798,1688,1066}, /* ; 06 (1024x768x75Hz) */
-        {1,1,1688,1066,1688,1066   }  /* ; 07 (1280x1024x75Hz) */
+static struct XGI330_LCDDataStruct  XGI_StLCD1280x1024x75Data[] = {
+	{211, 60,  1024, 501,  1688, 1066}, /* ; 00 (320x200,320x400,
+						     640x200,640x400) */
+	{211, 60,  1024, 508,  1688, 1066}, /* ; 01 (320x350,640x350) */
+	{211, 60,  1024, 501,  1688, 1066}, /* ; 02 (360x400,720x400) */
+	{211, 60,  1024, 508,  1688, 1066}, /* ; 03 (720x350) */
+	{211, 45,  768,  498,  1688, 1066}, /* ; 04 (640x480x75Hz) */
+	{211, 75,  1024, 625,  1688, 1066}, /* ; 05 (800x600x75Hz) */
+	{211, 120, 1280, 798,  1688, 1066}, /* ; 06 (1024x768x75Hz) */
+	{1,   1,   1688, 1066, 1688, 1066}  /* ; 07 (1280x1024x75Hz) */
 };
 
-static struct XGI330_LCDDataStruct  XGI_CetLCD1280x1024x75Data[] =
-{
-        {1,1,1688,1066,1688,1066}, /* ; 00 (320x200,320x400,640x200,640x400) */
-        {1,1,1688,1066,1688,1066}, /* ; 01 (320x350,640x350) */
-        {1,1,1688,1066,1688,1066}, /* ; 02 (360x400,720x400) */
-        {1,1,1688,1066,1688,1066}, /* ; 03 (720x350) */
-        {1,1,1688,1066,1688,1066}, /* ; 04 (640x480x75Hz) */
-        {1,1,1688,1066,1688,1066}, /* ; 05 (800x600x75Hz) */
-        {1,1,1688,1066,1688,1066}, /* ; 06 (1024x768x75Hz) */
-        {1,1,1688,1066,1688,1066}  /* ; 07 (1280x1024x75Hz) */
+static struct XGI330_LCDDataStruct  XGI_CetLCD1280x1024x75Data[] = {
+	{1, 1, 1688, 1066, 1688, 1066}, /* ; 00 (320x200,320x400,
+						 640x200,640x400) */
+	{1, 1, 1688, 1066, 1688, 1066}, /* ; 01 (320x350,640x350) */
+	{1, 1, 1688, 1066, 1688, 1066}, /* ; 02 (360x400,720x400) */
+	{1, 1, 1688, 1066, 1688, 1066}, /* ; 03 (720x350) */
+	{1, 1, 1688, 1066, 1688, 1066}, /* ; 04 (640x480x75Hz) */
+	{1, 1, 1688, 1066, 1688, 1066}, /* ; 05 (800x600x75Hz) */
+	{1, 1, 1688, 1066, 1688, 1066}, /* ; 06 (1024x768x75Hz) */
+	{1, 1, 1688, 1066, 1688, 1066}  /* ; 07 (1280x1024x75Hz) */
 };
 
-static struct XGI330_LCDDataStruct  XGI_NoScalingDatax75[] =
-{
-        {1,1,800,449,800,449    }, /* ; 00 (320x200,320x400,640x200,640x400) */
-        {1,1,800,449,800,449    }, /* ; 01 (320x350,640x350) */
-        {1,1,900,449,900,449    }, /* ; 02 (360x400,720x400) */
-        {1,1,900,449,900,449    }, /* ; 03 (720x350) */
-        {1,1,840,500,840,500    }, /* ; 04 (640x480x75Hz) */
-        {1,1,1056,625,1056,625  }, /* ; 05 (800x600x75Hz) */
-        {1,1,1312,800,1312,800  }, /* ; 06 (1024x768x75Hz) */
-        {1,1,1688,1066,1688,1066}, /* ; 07 (1280x1024x75Hz) */
-        {1,1,1688,1066,1688,1066}, /* ; 08 (1400x1050x75Hz) ;;[ycchen] 12/19/02 */
-        {1,1,2160,1250,2160,1250}, /* ; 09 (1600x1200x75Hz) */
-        {1,1,1688,806,1688,806  }  /* ; 0A (1280x768x75Hz) */
+static struct XGI330_LCDDataStruct  XGI_NoScalingDatax75[] = {
+	{1, 1, 800,  449,  800,  449},  /* ; 00 (320x200, 320x400,
+						 640x200, 640x400) */
+	{1, 1, 800,  449,  800,  449},  /* ; 01 (320x350, 640x350) */
+	{1, 1, 900,  449,  900,  449},  /* ; 02 (360x400, 720x400) */
+	{1, 1, 900,  449,  900,  449},  /* ; 03 (720x350) */
+	{1, 1, 840,  500,  840,  500},  /* ; 04 (640x480x75Hz) */
+	{1, 1, 1056, 625,  1056, 625},  /* ; 05 (800x600x75Hz) */
+	{1, 1, 1312, 800,  1312, 800},  /* ; 06 (1024x768x75Hz) */
+	{1, 1, 1688, 1066, 1688, 1066}, /* ; 07 (1280x1024x75Hz) */
+	{1, 1, 1688, 1066, 1688, 1066}, /* ; 08 (1400x1050x75Hz)
+					   ;;[ycchen] 12/19/02 */
+	{1, 1, 2160, 1250, 2160, 1250}, /* ; 09 (1600x1200x75Hz) */
+	{1, 1, 1688, 806,  1688, 806}   /* ; 0A (1280x768x75Hz) */
 };
 
-static struct XGI330_LCDDataDesStruct  XGI_ExtLCDDes1024x768Data[] =
-{
-   {  9,1057,0, 771  }, /* ; 00 (320x200,320x400,640x200,640x400) */
-   {  9,1057,0, 771  }, /* ; 01 (320x350,640x350) */
-   {  9,1057,0, 771  }, /* ; 02 (360x400,720x400) */
-   {  9,1057,0, 771  }, /* ; 03 (720x350) */
-   {  9,1057,0, 771  }, /* ; 04 (640x480x60Hz) */
-   {  9,1057,0, 771  }, /* ; 05 (800x600x60Hz) */
-   {  9,1057,805, 770  }  /* ; 06 (1024x768x60Hz) */
+static struct XGI330_LCDDataDesStruct  XGI_ExtLCDDes1024x768Data[] = {
+	{9, 1057, 0,   771}, /* ; 00 (320x200,320x400,640x200,640x400) */
+	{9, 1057, 0,   771}, /* ; 01 (320x350,640x350) */
+	{9, 1057, 0,   771}, /* ; 02 (360x400,720x400) */
+	{9, 1057, 0,   771}, /* ; 03 (720x350) */
+	{9, 1057, 0,   771}, /* ; 04 (640x480x60Hz) */
+	{9, 1057, 0,   771}, /* ; 05 (800x600x60Hz) */
+	{9, 1057, 805, 770}  /* ; 06 (1024x768x60Hz) */
 };
 
-static struct XGI330_LCDDataDesStruct  XGI_StLCDDes1024x768Data[] =
-{
-        { 9,1057,737,703   }, /* ; 00 (320x200,320x400,640x200,640x400) */
-        { 9,1057,686,651   }, /* ; 01 (320x350,640x350) */
-        { 9,1057,737,703   }, /* ; 02 (360x400,720x400) */
-        { 9,1057,686,651   }, /* ; 03 (720x350) */
-        { 9,1057,776,741   }, /* ; 04 (640x480x60Hz) */
-        { 9,1057, 0 ,771   }, /* ; 05 (800x600x60Hz) */
-        { 9,1057,805,770   }  /* ; 06 (1024x768x60Hz) */
+static struct XGI330_LCDDataDesStruct  XGI_StLCDDes1024x768Data[] = {
+	{9, 1057, 737, 703}, /* ; 00 (320x200,320x400,640x200,640x400) */
+	{9, 1057, 686, 651}, /* ; 01 (320x350,640x350) */
+	{9, 1057, 737, 703}, /* ; 02 (360x400,720x400) */
+	{9, 1057, 686, 651}, /* ; 03 (720x350) */
+	{9, 1057, 776, 741}, /* ; 04 (640x480x60Hz) */
+	{9, 1057, 0,   771}, /* ; 05 (800x600x60Hz) */
+	{9, 1057, 805, 770}  /* ; 06 (1024x768x60Hz) */
 };
 
-static struct XGI330_LCDDataDesStruct  XGI_CetLCDDes1024x768Data[] =
-{
-       	{      1152,856,622,587   }, /* ; 00 (320x200,320x400,640x200,640x400) */
-        {      1152,856,597,562   }, /* ; 01 (320x350,640x350) */
-        {      1152,856,622,587   }, /* ; 02 (360x400,720x400) */
-        {      1152,856,597,562   }, /* ; 03 (720x350) */
-        {      1152,856,662,627   }, /* ; 04 (640x480x60Hz) */
-        {      1232,936,722,687   }, /* ; 05 (800x600x60Hz) */
-        {      0,1048,805,770   }  /* ; 06 (1024x768x60Hz) */
+static struct XGI330_LCDDataDesStruct  XGI_CetLCDDes1024x768Data[] = {
+	{1152, 856,  622, 587}, /* ; 00 (320x200,320x400,640x200,640x400) */
+	{1152, 856,  597, 562}, /* ; 01 (320x350,640x350) */
+	{1152, 856,  622, 587}, /* ; 02 (360x400,720x400) */
+	{1152, 856,  597, 562}, /* ; 03 (720x350) */
+	{1152, 856,  662, 627}, /* ; 04 (640x480x60Hz) */
+	{1232, 936,  722, 687}, /* ; 05 (800x600x60Hz) */
+	{0,    1048, 805, 770}  /* ; 06 (1024x768x60Hz) */
 };
 
-static struct XGI330_LCDDataDesStruct XGI_ExtLCDDLDes1280x1024Data[] =
-{
-        {      18,1346,981,940     },/* 00 (320x200,320x400,640x200,640x400) */
-        {      18,1346,926,865     },/* 01 (320x350,640x350) */
-        {      18,1346,981,940     },/* 02 (360x400,720x400) */
-        {      18,1346,926,865     },/* 03 (720x350) */
-        {      18,1346,0,1025     },/* 04 (640x480x60Hz) */
-        {      18,1346,0,1025     },/* 05 (800x600x60Hz) */
-        {      18,1346,1065,1024     },/* 06 (1024x768x60Hz) */
-        {      18,1346,1065,1024     }/* 07 (1280x1024x60Hz) */
+static struct XGI330_LCDDataDesStruct XGI_ExtLCDDLDes1280x1024Data[] = {
+	{18, 1346, 981,  940},  /* 00 (320x200,320x400,640x200,640x400) */
+	{18, 1346, 926,  865},  /* 01 (320x350,640x350) */
+	{18, 1346, 981,  940},  /* 02 (360x400,720x400) */
+	{18, 1346, 926,  865},  /* 03 (720x350) */
+	{18, 1346, 0,    1025}, /* 04 (640x480x60Hz) */
+	{18, 1346, 0,    1025}, /* 05 (800x600x60Hz) */
+	{18, 1346, 1065, 1024}, /* 06 (1024x768x60Hz) */
+	{18, 1346, 1065, 1024}  /* 07 (1280x1024x60Hz) */
 };
 
-static struct XGI330_LCDDataDesStruct XGI_StLCDDLDes1280x1024Data[] =
-{
-        {      18,1346,970,907     },/* 00 (320x200,320x400,640x200,640x400) */
-        {      18,1346,917,854     },/* 01 (320x350,640x350) */
-        {      18,1346,970,907     },/* 02 (360x400,720x400) */
-        {      18,1346,917,854     },/* 03 (720x350) */
-        {      18,1346,0,1025     },/* 04 (640x480x60Hz) */
-        {      18,1346,0,1025     },/* 05 (800x600x60Hz) */
-        {      18,1346,1065,1024     },/* 06 (1024x768x60Hz) */
-        {      18,1346,1065,1024     }/* 07 (1280x1024x60Hz) */
+static struct XGI330_LCDDataDesStruct XGI_StLCDDLDes1280x1024Data[] = {
+	{18, 1346, 970,  907},  /* 00 (320x200,320x400,640x200,640x400) */
+	{18, 1346, 917,  854},  /* 01 (320x350,640x350) */
+	{18, 1346, 970,  907},  /* 02 (360x400,720x400) */
+	{18, 1346, 917,  854},  /* 03 (720x350) */
+	{18, 1346, 0,    1025}, /* 04 (640x480x60Hz) */
+	{18, 1346, 0,    1025}, /* 05 (800x600x60Hz) */
+	{18, 1346, 1065, 1024}, /* 06 (1024x768x60Hz) */
+	{18, 1346, 1065, 1024}  /* 07 (1280x1024x60Hz) */
 };
 
-static struct XGI330_LCDDataDesStruct  XGI_CetLCDDLDes1280x1024Data[] =
-{
-        {      1368,1008,752,711    }, /* 00 (320x200,320x400,640x200,640x400) */
-        {      1368,1008,729,688    }, /* 01 (320x350,640x350) */
-        {      1368,1008,752,711    }, /* 02 (360x400,720x400) */
-    	{      1368,1008,729,688    }, /* 03 (720x350) */
-        {      1368,1008,794,753    }, /* 04 (640x480x60Hz) */
-        {      1448,1068,854,813    }, /* 05 (800x600x60Hz) */
-        {      1560,1200,938,897    }, /* 06 (1024x768x60Hz) */
-        {      18,1346,1065,1024    }  /* 07 (1280x1024x60Hz) */
+static struct XGI330_LCDDataDesStruct  XGI_CetLCDDLDes1280x1024Data[] = {
+	{1368, 1008, 752,  711}, /* 00 (320x200,320x400,640x200,640x400) */
+	{1368, 1008, 729,  688}, /* 01 (320x350,640x350) */
+	{1368, 1008, 752,  711}, /* 02 (360x400,720x400) */
+	{1368, 1008, 729,  688}, /* 03 (720x350) */
+	{1368, 1008, 794,  753}, /* 04 (640x480x60Hz) */
+	{1448, 1068, 854,  813}, /* 05 (800x600x60Hz) */
+	{1560, 1200, 938,  897}, /* 06 (1024x768x60Hz) */
+	{18,   1346, 1065, 1024} /* 07 (1280x1024x60Hz) */
 };
 
-static struct XGI330_LCDDataDesStruct  XGI_ExtLCDDes1280x1024Data[] =
-{
-        {      9,1337,981,940    }, /* ; 00 (320x200,320x400,640x200,640x400) */
-        {      9,1337,926,884    }, /* ; 01 (320x350,640x350) alan, 2003/09/30 */
-        {      9,1337,981,940    }, /* ; 02 (360x400,720x400) */
-        {      9,1337,926,884    }, /* ; 03 (720x350) alan, 2003/09/30 */
-        {      9,1337,0,1025    }, /* ; 04 (640x480x60Hz) */
-        {      9,1337,0,1025    }, /* ; 05 (800x600x60Hz) */
-        {      9,1337,1065,1024    }, /* ; 06 (1024x768x60Hz) */
-        {      9,1337,1065,1024    }  /* ; 07 (1280x1024x60Hz) */
+static struct XGI330_LCDDataDesStruct  XGI_ExtLCDDes1280x1024Data[] = {
+	{9, 1337, 981,  940},  /* ; 00 (320x200,320x400,640x200,640x400) */
+	{9, 1337, 926,  884},  /* ; 01 (320x350,640x350) alan, 2003/09/30 */
+	{9, 1337, 981,  940},  /* ; 02 (360x400,720x400) */
+	{9, 1337, 926,  884},  /* ; 03 (720x350) alan, 2003/09/30 */
+	{9, 1337, 0,    1025}, /* ; 04 (640x480x60Hz) */
+	{9, 1337, 0,    1025}, /* ; 05 (800x600x60Hz) */
+	{9, 1337, 1065, 1024}, /* ; 06 (1024x768x60Hz) */
+	{9, 1337, 1065, 1024}  /* ; 07 (1280x1024x60Hz) */
 };
 
-static struct XGI330_LCDDataDesStruct  XGI_StLCDDes1280x1024Data[] =
-{
-        {      9,1337,970,907    }, /* ; 00 (320x200,320x400,640x200,640x400) */
-        {      9,1337,917,854    }, /* ; 01 (320x350,640x350) */
-        {      9,1337,970,907    }, /* ; 02 (360x400,720x400) */
-        {      9,1337,917,854    }, /* ; 03 (720x350) */
-        {      9,1337,0,1025    }, /* ; 04 (640x480x60Hz) */
-        {      9,1337,0,1025    }, /* ; 05 (800x600x60Hz) */
-        {      9,1337,1065,1024    }, /* ; 06 (1024x768x60Hz) */
-        {      9,1337,1065,1024    }  /* ; 07 (1280x1024x60Hz) */
+static struct XGI330_LCDDataDesStruct  XGI_StLCDDes1280x1024Data[] = {
+	{9, 1337, 970,  907},  /* ; 00 (320x200,320x400,640x200,640x400) */
+	{9, 1337, 917,  854},  /* ; 01 (320x350,640x350) */
+	{9, 1337, 970,  907},  /* ; 02 (360x400,720x400) */
+	{9, 1337, 917,  854},  /* ; 03 (720x350) */
+	{9, 1337, 0,    1025}, /* ; 04 (640x480x60Hz) */
+	{9, 1337, 0,    1025}, /* ; 05 (800x600x60Hz) */
+	{9, 1337, 1065, 1024}, /* ; 06 (1024x768x60Hz) */
+	{9, 1337, 1065, 1024}  /* ; 07 (1280x1024x60Hz) */
 };
 
-static struct XGI330_LCDDataDesStruct  XGI_CetLCDDes1280x1024Data[] =
-{
-        {      1368,1008,752,711    }, /* 00 (320x200,320x400,640x200,640x400) */
-        {      1368,1008,729,688    }, /* 01 (320x350,640x350) */
-        {      1368,1008,752,711    }, /* 02 (360x400,720x400) */
-    	{      1368,1008,729,688    }, /* 03 (720x350) */
-        {      1368,1008,794,753    }, /* 04 (640x480x60Hz) */
-        {      1448,1068,854,813    }, /* 05 (800x600x60Hz) */
-        {      1560,1200,938,897    }, /* 06 (1024x768x60Hz) */
-        {      9,1337,1065,1024    }  /* 07 (1280x1024x60Hz) */
+static struct XGI330_LCDDataDesStruct  XGI_CetLCDDes1280x1024Data[] = {
+	{1368, 1008, 752,  711}, /* 00 (320x200,320x400,640x200,640x400) */
+	{1368, 1008, 729,  688}, /* 01 (320x350,640x350) */
+	{1368, 1008, 752,  711}, /* 02 (360x400,720x400) */
+	{1368, 1008, 729,  688}, /* 03 (720x350) */
+	{1368, 1008, 794,  753}, /* 04 (640x480x60Hz) */
+	{1448, 1068, 854,  813}, /* 05 (800x600x60Hz) */
+	{1560, 1200, 938,  897}, /* 06 (1024x768x60Hz) */
+	{9,    1337, 1065, 1024} /* 07 (1280x1024x60Hz) */
 };
 
-static struct XGI330_LCDDataDesStruct  XGI_StLCDDLDes1400x1050Data[] =
-{
-        {      18,1464,0,1051    }, /* 00 (320x200,320x400,640x200,640x400) */
-        {      18,1464,0,1051    }, /* 01 (320x350,640x350) */
-        {      18,1464,0,1051    }, /* 02 (360x400,720x400) */
-        {      18,1464,0,1051    }, /* 03 (720x350) */
-        {      18,1464,0,1051    }, /* 04 (640x480x60Hz) */
-        {      18,1464,0,1051    }, /* 05 (800x600x60Hz) */
-        {      18,1464,0,1051    }, /* 06 (1024x768x60Hz) */
-        {      1646,1406,1053,1038    }, /* 07 (1280x1024x60Hz) */
-        {      18,1464,0,1051    }  /* 08 (1400x1050x60Hz) */
+static struct XGI330_LCDDataDesStruct  XGI_StLCDDLDes1400x1050Data[] = {
+	{18,   1464, 0,    1051}, /* 00 (320x200,320x400,640x200,640x400) */
+	{18,   1464, 0,    1051}, /* 01 (320x350,640x350) */
+	{18,   1464, 0,    1051}, /* 02 (360x400,720x400) */
+	{18,   1464, 0,    1051}, /* 03 (720x350) */
+	{18,   1464, 0,    1051}, /* 04 (640x480x60Hz) */
+	{18,   1464, 0,    1051}, /* 05 (800x600x60Hz) */
+	{18,   1464, 0,    1051}, /* 06 (1024x768x60Hz) */
+	{1646, 1406, 1053, 1038}, /* 07 (1280x1024x60Hz) */
+	{18,   1464, 0,    1051}  /* 08 (1400x1050x60Hz) */
 };
 
-static struct XGI330_LCDDataDesStruct  XGI_ExtLCDDLDes1400x1050Data[] =
-{
-        {      18,1464,0,1051    }, /* 00 (320x200,320x400,640x200,640x400) */
-        {      18,1464,0,1051    }, /* 01 (320x350,640x350) */
-        {      18,1464,0,1051    }, /* 02 (360x400,720x400) */
-        {      18,1464,0,1051    }, /* 03 (720x350) */
-        {      18,1464,0,1051    }, /* 04 (640x480x60Hz) */
-        {      18,1464,0,1051    }, /* 05 (800x600x60Hz) */
-        {      18,1464,0,1051    }, /* 06 (1024x768x60Hz) */
-        {      1646,1406,1053,1038    }, /* 07 (1280x1024x60Hz) */
-        {      18,1464,0,1051    }  /* 08 (1400x1050x60Hz) */
+static struct XGI330_LCDDataDesStruct  XGI_ExtLCDDLDes1400x1050Data[] = {
+	{18,   1464, 0,    1051}, /* 00 (320x200,320x400,640x200,640x400) */
+	{18,   1464, 0,    1051}, /* 01 (320x350,640x350) */
+	{18,   1464, 0,    1051}, /* 02 (360x400,720x400) */
+	{18,   1464, 0,    1051}, /* 03 (720x350) */
+	{18,   1464, 0,    1051}, /* 04 (640x480x60Hz) */
+	{18,   1464, 0,    1051}, /* 05 (800x600x60Hz) */
+	{18,   1464, 0,    1051}, /* 06 (1024x768x60Hz) */
+	{1646, 1406, 1053, 1038}, /* 07 (1280x1024x60Hz) */
+	{18,   1464, 0,    1051}  /* 08 (1400x1050x60Hz) */
 };
 
-static struct XGI330_LCDDataDesStruct  XGI_StLCDDes1400x1050Data[] =
-{
-        {      9,1455,0,1051     },/* 00 (320x200,320x400,640x200,640x400) */
-        {      9,1455,0,1051     },/* 01 (320x350,640x350) */
-        {      9,1455,0,1051     },/* 02 (360x400,720x400) */
-        {      9,1455,0,1051     },/* 03 (720x350) */
-        {      9,1455,0,1051     },/* 04 (640x480x60Hz) */
-        {      9,1455,0,1051     },/* 05 (800x600x60Hz) */
-        {      9,1455,0,1051     },/* 06 (1024x768x60Hz) */
-        {      1637,1397,1053,1038     },/* 07 (1280x1024x60Hz) */
-        {      9,1455,0,1051     } /* 08 (1400x1050x60Hz) */
+static struct XGI330_LCDDataDesStruct  XGI_StLCDDes1400x1050Data[] = {
+	{9,    1455, 0,    1051}, /* 00 (320x200,320x400,640x200,640x400) */
+	{9,    1455, 0,    1051}, /* 01 (320x350,640x350) */
+	{9,    1455, 0,    1051}, /* 02 (360x400,720x400) */
+	{9,    1455, 0,    1051}, /* 03 (720x350) */
+	{9,    1455, 0,    1051}, /* 04 (640x480x60Hz) */
+	{9,    1455, 0,    1051}, /* 05 (800x600x60Hz) */
+	{9,    1455, 0,    1051}, /* 06 (1024x768x60Hz) */
+	{1637, 1397, 1053, 1038}, /* 07 (1280x1024x60Hz) */
+	{9,    1455, 0,    1051}  /* 08 (1400x1050x60Hz) */
 };
 
-static struct XGI330_LCDDataDesStruct  XGI_ExtLCDDes1400x1050Data[] =
-{
-        {      9,1455,0,1051     },/* 00 (320x200,320x400,640x200,640x400) */
-        {      9,1455,0,1051     },/* 01 (320x350,640x350) */
-        {      9,1455,0,1051     },/* 02 (360x400,720x400) */
-        {      9,1455,0,1051     },/* 03 (720x350) */
-        {      9,1455,0,1051     },/* 04 (640x480x60Hz) */
-        {      9,1455,0,1051     },/* 05 (800x600x60Hz) */
-        {      9,1455,0,1051     },/* 06 (1024x768x60Hz) */
-        {      1637,1397,1053,1038     },/* 07 (1280x1024x60Hz) */
-        {      9,1455,0,1051     } /* 08 (1400x1050x60Hz) */
+static struct XGI330_LCDDataDesStruct  XGI_ExtLCDDes1400x1050Data[] = {
+	{9,    1455, 0,    1051}, /* 00 (320x200,320x400,640x200,640x400) */
+	{9,    1455, 0,    1051}, /* 01 (320x350,640x350) */
+	{9,    1455, 0,    1051}, /* 02 (360x400,720x400) */
+	{9,    1455, 0,    1051}, /* 03 (720x350) */
+	{9,    1455, 0,    1051}, /* 04 (640x480x60Hz) */
+	{9,    1455, 0,    1051}, /* 05 (800x600x60Hz) */
+	{9,    1455, 0,    1051}, /* 06 (1024x768x60Hz) */
+	{1637, 1397, 1053, 1038}, /* 07 (1280x1024x60Hz) */
+	{9,    1455, 0,    1051}  /* 08 (1400x1050x60Hz) */
 };
 
-static struct XGI330_LCDDataDesStruct  XGI_CetLCDDes1400x1050Data[] =
-{
-        {      1308,1068,781,766    }, /* 00 (320x200,320x400,640x200,640x400) */
-        {      1308,1068,781,766    }, /* 01 (320x350,640x350) */
-        {      1308,1068,781,766    }, /* 02 (360x400,720x400) */
-        {      1308,1068,781,766    }, /* 03 (720x350) */
-        {      1308,1068,781,766    }, /* 04 (640x480x60Hz) */
-        {      1388,1148,841,826    }, /* 05 (800x600x60Hz) */
-        {      1490,1250,925,910    }, /* 06 (1024x768x60Hz) */
-        {      1646,1406,1053,1038    }, /* 07 (1280x1024x60Hz) */
-        {      18,1464,0,1051    } /* 08 (1400x1050x60Hz) */
+static struct XGI330_LCDDataDesStruct  XGI_CetLCDDes1400x1050Data[] = {
+	{1308, 1068, 781,  766},  /* 00 (320x200,320x400,640x200,640x400) */
+	{1308, 1068, 781,  766},  /* 01 (320x350,640x350) */
+	{1308, 1068, 781,  766},  /* 02 (360x400,720x400) */
+	{1308, 1068, 781,  766},  /* 03 (720x350) */
+	{1308, 1068, 781,  766},  /* 04 (640x480x60Hz) */
+	{1388, 1148, 841,  826},  /* 05 (800x600x60Hz) */
+	{1490, 1250, 925,  910},  /* 06 (1024x768x60Hz) */
+	{1646, 1406, 1053, 1038}, /* 07 (1280x1024x60Hz) */
+	{18,   1464, 0,    1051}  /* 08 (1400x1050x60Hz) */
 };
 
-static struct XGI330_LCDDataDesStruct  XGI_CetLCDDes1400x1050Data2[] =
-{
-        {      0,1448,0,1051    }, /* 00 (320x200,320x400,640x200,640x400) */
-        {      0,1448,0,1051    }, /* 01 (320x350,640x350) */
-        {      0,1448,0,1051    }, /* 02 (360x400,720x400) */
-        {      0,1448,0,1051    }, /* 03 (720x350) */
-        {      0,1448,0,1051    }  /* 04 (640x480x60Hz) */
+static struct XGI330_LCDDataDesStruct  XGI_CetLCDDes1400x1050Data2[] = {
+	{0, 1448, 0, 1051}, /* 00 (320x200,320x400,640x200,640x400) */
+	{0, 1448, 0, 1051}, /* 01 (320x350,640x350) */
+	{0, 1448, 0, 1051}, /* 02 (360x400,720x400) */
+	{0, 1448, 0, 1051}, /* 03 (720x350) */
+	{0, 1448, 0, 1051}  /* 04 (640x480x60Hz) */
 };
 
-
-
-static struct XGI330_LCDDataDesStruct  XGI_ExtLCDDLDes1600x1200Data[] =
-{
-	{      18,1682,0,1201    }, /* 00 (320x200,320x400,640x200,640x400) */
-        {      18,1682,0,1201    }, /* 01 (320x350,640x350) */
-        {      18,1682,0,1201    }, /* 02 (360x400,720x400) */
-        {      18,1682,0,1201    }, /* 03 (720x350) */
-        {      18,1682,0,1201    }, /* 04 (640x480x60Hz) */
-        {      18,1682,0,1201    }, /* 05 (800x600x60Hz) */
-        {      18,1682,0,1201    }, /* 06 (1024x768x60Hz) */
-        {      18,1682,0,1201    }, /* 07 (1280x1024x60Hz) */
-        {      18,1682,0,1201    }, /* 08 (1400x1050x60Hz) */
-        {      18,1682,0,1201    }  /* 09 (1600x1200x60Hz) */
+static struct XGI330_LCDDataDesStruct  XGI_ExtLCDDLDes1600x1200Data[] = {
+	{18, 1682, 0, 1201}, /* 00 (320x200,320x400,640x200,640x400) */
+	{18, 1682, 0, 1201}, /* 01 (320x350,640x350) */
+	{18, 1682, 0, 1201}, /* 02 (360x400,720x400) */
+	{18, 1682, 0, 1201}, /* 03 (720x350) */
+	{18, 1682, 0, 1201}, /* 04 (640x480x60Hz) */
+	{18, 1682, 0, 1201}, /* 05 (800x600x60Hz) */
+	{18, 1682, 0, 1201}, /* 06 (1024x768x60Hz) */
+	{18, 1682, 0, 1201}, /* 07 (1280x1024x60Hz) */
+	{18, 1682, 0, 1201}, /* 08 (1400x1050x60Hz) */
+	{18, 1682, 0, 1201}  /* 09 (1600x1200x60Hz) */
 };
 
-static struct XGI330_LCDDataDesStruct  XGI_StLCDDLDes1600x1200Data[] =
-{
-        {      18,1682,1150,1101    }, /* 00 (320x200,320x400,640x200,640x400) */
-        {      18,1682,1083,1034    }, /* 01 (320x350,640x350) */
-        {      18,1682,1150,1101    }, /* 02 (360x400,720x400) */
-        {      18,1682,1083,1034    }, /* 03 (720x350) */
-        {      18,1682,0,1201    }, /* 04 (640x480x60Hz) */
-        {      18,1682,0,1201    }, /* 05 (800x600x60Hz) */
-        {      18,1682,0,1201    }, /* 06 (1024x768x60Hz) */
-        {      18,1682,1232,1183    }, /* 07 (1280x1024x60Hz) */
-        {      18,1682,0,1201    }, /* 08 (1400x1050x60Hz) */
-        {      18,1682,0,1201    } /* 09 (1600x1200x60Hz) */
+static struct XGI330_LCDDataDesStruct  XGI_StLCDDLDes1600x1200Data[] = {
+	{18, 1682, 1150, 1101}, /* 00 (320x200,320x400,640x200,640x400) */
+	{18, 1682, 1083, 1034}, /* 01 (320x350,640x350) */
+	{18, 1682, 1150, 1101}, /* 02 (360x400,720x400) */
+	{18, 1682, 1083, 1034}, /* 03 (720x350) */
+	{18, 1682, 0,    1201}, /* 04 (640x480x60Hz) */
+	{18, 1682, 0,    1201}, /* 05 (800x600x60Hz) */
+	{18, 1682, 0,    1201}, /* 06 (1024x768x60Hz) */
+	{18, 1682, 1232, 1183}, /* 07 (1280x1024x60Hz) */
+	{18, 1682, 0,    1201}, /* 08 (1400x1050x60Hz) */
+	{18, 1682, 0,    1201} /* 09 (1600x1200x60Hz) */
 };
 
-static struct XGI330_LCDDataDesStruct  XGI_ExtLCDDes1600x1200Data[] =
-{
-        {      9,1673,0,1201     },/* 00 (320x200,320x400,640x200,640x400) */
-        {      9,1673,0,1201     },/* 01 (320x350,640x350) */
-        {      9,1673,0,1201     },/* 02 (360x400,720x400) */
-        {      9,1673,0,1201     },/* 03 (720x350) */
-        {      9,1673,0,1201     },/* 04 (640x480x60Hz) */
-        {      9,1673,0,1201     },/* 05 (800x600x60Hz) */
-        {      9,1673,0,1201     },/* 06 (1024x768x60Hz) */
-        {      9,1673,0,1201     },/* 07 (1280x1024x60Hz) */
-        {      9,1673,0,1201     },/* 08 (1400x1050x60Hz) */
-        {      9,1673,0,1201     } /* 09 (1600x1200x60Hz) */
+static struct XGI330_LCDDataDesStruct  XGI_ExtLCDDes1600x1200Data[] = {
+	{9, 1673, 0, 1201}, /* 00 (320x200,320x400,640x200,640x400) */
+	{9, 1673, 0, 1201}, /* 01 (320x350,640x350) */
+	{9, 1673, 0, 1201}, /* 02 (360x400,720x400) */
+	{9, 1673, 0, 1201}, /* 03 (720x350) */
+	{9, 1673, 0, 1201}, /* 04 (640x480x60Hz) */
+	{9, 1673, 0, 1201}, /* 05 (800x600x60Hz) */
+	{9, 1673, 0, 1201}, /* 06 (1024x768x60Hz) */
+	{9, 1673, 0, 1201}, /* 07 (1280x1024x60Hz) */
+	{9, 1673, 0, 1201}, /* 08 (1400x1050x60Hz) */
+	{9, 1673, 0, 1201}  /* 09 (1600x1200x60Hz) */
 };
 
-static struct XGI330_LCDDataDesStruct  XGI_StLCDDes1600x1200Data[] =
-{
-	{      9,1673,1150,1101     },/* 00 (320x200,320x400,640x200,640x400) */
-        {      9,1673,1083,1034     },/* 01 (320x350,640x350) */
-        {      9,1673,1150,1101     },/* 02 (360x400,720x400) */
-        {      9,1673,1083,1034     },/* 03 (720x350) */
-        {      9,1673,0,1201     },/* 04 (640x480x60Hz) */
-        {      9,1673,0,1201     },/* 05 (800x600x60Hz) */
-        {      9,1673,0,1201     },/* 06 (1024x768x60Hz) */
-        {      9,1673,1232,1183     },/* 07 (1280x1024x60Hz) */
-        {      9,1673,0,1201     },/* 08 (1400x1050x60Hz) */
-        {      9,1673,0,1201     } /* 09 (1600x1200x60Hz) */
+static struct XGI330_LCDDataDesStruct  XGI_StLCDDes1600x1200Data[] = {
+	{9, 1673, 1150, 1101}, /* 00 (320x200,320x400,640x200,640x400) */
+	{9, 1673, 1083, 1034}, /* 01 (320x350,640x350) */
+	{9, 1673, 1150, 1101}, /* 02 (360x400,720x400) */
+	{9, 1673, 1083, 1034}, /* 03 (720x350) */
+	{9, 1673, 0,    1201}, /* 04 (640x480x60Hz) */
+	{9, 1673, 0,    1201}, /* 05 (800x600x60Hz) */
+	{9, 1673, 0,    1201}, /* 06 (1024x768x60Hz) */
+	{9, 1673, 1232, 1183}, /* 07 (1280x1024x60Hz) */
+	{9, 1673, 0,    1201}, /* 08 (1400x1050x60Hz) */
+	{9, 1673, 0,    1201}  /* 09 (1600x1200x60Hz) */
 };
 
-static struct XGI330_LCDDataDesStruct2  XGI_NoScalingDesData[] =
-{
-        {     9,657,448,405,96,2  }, /* 00 (320x200,320x400,640x200,640x400) */
-        {     9,657,448,355,96,2  }, /* 01 (320x350,640x350) */
-        {     9,657,448,405,96,2  }, /* 02 (360x400,720x400) */
-        {     9,657,448,355,96,2  }, /* 03 (720x350) */
-        {     9,657,1,483,96,2  }, /* 04 (640x480x60Hz) */
-        {     9,849,627,600,128,4  }, /* 05 (800x600x60Hz) */
-        {     9,1057,805,770,0136,6  }, /* 06 (1024x768x60Hz) */
-        {     9,1337,0,1025,112,3  }, /* 07 (1280x1024x60Hz) */
-        {     9,1457,0,1051,112,3  }, /* 08 (1400x1050x60Hz) }, //;[ycchen] 12/19/02 */
-        {     9,1673,0,1201,192,3  }, /* 09 (1600x1200x60Hz) */
-        {     9,1337,0,771,112,6  }  /* 0A (1280x768x60Hz) */
+static struct XGI330_LCDDataDesStruct2  XGI_NoScalingDesData[] = {
+	{9, 657,  448, 405,  96,   2}, /* 00 (320x200,320x400,
+					      640x200,640x400) */
+	{9, 657,  448, 355,  96,   2}, /* 01 (320x350,640x350) */
+	{9, 657,  448, 405,  96,   2}, /* 02 (360x400,720x400) */
+	{9, 657,  448, 355,  96,   2}, /* 03 (720x350) */
+	{9, 657,  1,   483,  96,   2}, /* 04 (640x480x60Hz) */
+	{9, 849,  627, 600,  128,  4}, /* 05 (800x600x60Hz) */
+	{9, 1057, 805, 770,  0136, 6}, /* 06 (1024x768x60Hz) */
+	{9, 1337, 0,   1025, 112,  3}, /* 07 (1280x1024x60Hz) */
+	{9, 1457, 0,   1051, 112,  3}, /* 08 (1400x1050x60Hz) },
+					//;[ycchen] 12/19/02 */
+	{9, 1673, 0,   1201, 192,  3}, /* 09 (1600x1200x60Hz) */
+	{9, 1337, 0,   771,  112,  6}  /* 0A (1280x768x60Hz) */
 };
 
-static struct XGI330_LCDDataDesStruct  XGI_ExtLCDDes1024x768x75Data[] =		/* ;;1024x768x75Hz */
-{
-        {9,1049,0,769},    /* ; 00 (320x200,320x400,640x200,640x400) */
-        {9,1049,0,769},    /* ; 01 (320x350,640x350) */
-        {9,1049,0,769},    /* ; 02 (360x400,720x400) */
-        {9,1049,0,769},    /* ; 03 (720x350) */
-        {9,1049,0,769},    /* ; 04 (640x480x75Hz) */
-        {9,1049,0,769},    /* ; 05 (800x600x75Hz) */
-        {9,1049,0,769}     /* ; 06 (1024x768x75Hz) */
+/* ;;1024x768x75Hz */
+static struct XGI330_LCDDataDesStruct  XGI_ExtLCDDes1024x768x75Data[] = {
+	{9, 1049, 0, 769}, /* ; 00 (320x200,320x400,640x200,640x400) */
+	{9, 1049, 0, 769}, /* ; 01 (320x350,640x350) */
+	{9, 1049, 0, 769}, /* ; 02 (360x400,720x400) */
+	{9, 1049, 0, 769}, /* ; 03 (720x350) */
+	{9, 1049, 0, 769}, /* ; 04 (640x480x75Hz) */
+	{9, 1049, 0, 769}, /* ; 05 (800x600x75Hz) */
+	{9, 1049, 0, 769}  /* ; 06 (1024x768x75Hz) */
 };
 
-static struct XGI330_LCDDataDesStruct  XGI_StLCDDes1024x768x75Data[] =
-{
-        {9,1049,0,769},    /* ; 00 (320x200,320x400,640x200,640x400) */
-        {9,1049,0,769},    /* ; 01 (320x350,640x350) */
-        {9,1049,0,769},    /* ; 02 (360x400,720x400) */
-        {9,1049,0,769},    /* ; 03 (720x350) */
-        {9,1049,0,769},    /* ; 04 (640x480x75Hz) */
-        {9,1049,0,769},    /* ; 05 (800x600x75Hz) */
-        {9,1049,0,769}     /* ; 06 (1024x768x75Hz) */
+static struct XGI330_LCDDataDesStruct  XGI_StLCDDes1024x768x75Data[] = {
+	{9, 1049, 0, 769}, /* ; 00 (320x200,320x400,640x200,640x400) */
+	{9, 1049, 0, 769}, /* ; 01 (320x350,640x350) */
+	{9, 1049, 0, 769}, /* ; 02 (360x400,720x400) */
+	{9, 1049, 0, 769}, /* ; 03 (720x350) */
+	{9, 1049, 0, 769}, /* ; 04 (640x480x75Hz) */
+	{9, 1049, 0, 769}, /* ; 05 (800x600x75Hz) */
+	{9, 1049, 0, 769}  /* ; 06 (1024x768x75Hz) */
 };
 
-static struct XGI330_LCDDataDesStruct  XGI_CetLCDDes1024x768x75Data[] =	/* ;;1024x768x75Hz */
-{
-        {1152,856,622,587},     /* ; 00 (320x200,320x400,640x200,640x400) */
-        {1152,856,597,562},     /* ; 01 (320x350,640x350) */
-        {1192,896,622,587},     /* ; 02 (360x400,720x400) */
-        {1192,896,597,562},     /* ; 03 (720x350) */
-        {1129,857,656,625},     /* ; 04 (640x480x75Hz) */
-        {1209,937,716,685},     /* ; 05 (800x600x75Hz) */
-        {9,1049,0,769} 	   	/* ; 06 (1024x768x75Hz) */
+/* ;;1024x768x75Hz */
+static struct XGI330_LCDDataDesStruct  XGI_CetLCDDes1024x768x75Data[] = {
+	{1152, 856,  622, 587}, /* ; 00 (320x200,320x400,640x200,640x400) */
+	{1152, 856,  597, 562}, /* ; 01 (320x350,640x350) */
+	{1192, 896,  622, 587}, /* ; 02 (360x400,720x400) */
+	{1192, 896,  597, 562}, /* ; 03 (720x350) */
+	{1129, 857,  656, 625}, /* ; 04 (640x480x75Hz) */
+	{1209, 937,  716, 685}, /* ; 05 (800x600x75Hz) */
+	{9,    1049, 0,   769}	/* ; 06 (1024x768x75Hz) */
 };
 
-static struct XGI330_LCDDataDesStruct  XGI_ExtLCDDLDes1280x1024x75Data[] =         /* ;;1280x1024x75Hz */
-{
-        {18,1314,0,1025     },/* ; 00 (320x200,320x400,640x200,640x400) */
-        {18,1314,0,1025     },/* ; 01 (320x350,640x350) */
-        {18,1314,0,1025     },/* ; 02 (360x400,720x400) */
-        {18,1314,0,1025     },/* ; 03 (720x350) */
-        {18,1314,0,1025     },/* ; 04 (640x480x60Hz) */
-        {18,1314,0,1025     },/* ; 05 (800x600x60Hz) */
-        {18,1314,0,1025     },/* ; 06 (1024x768x60Hz) */
-        {18,1314,0,1025     }/* ; 07 (1280x1024x60Hz) */
+/* ;;1280x1024x75Hz */
+static struct XGI330_LCDDataDesStruct  XGI_ExtLCDDLDes1280x1024x75Data[] = {
+	{18, 1314, 0, 1025}, /* ; 00 (320x200,320x400,640x200,640x400) */
+	{18, 1314, 0, 1025}, /* ; 01 (320x350,640x350) */
+	{18, 1314, 0, 1025}, /* ; 02 (360x400,720x400) */
+	{18, 1314, 0, 1025}, /* ; 03 (720x350) */
+	{18, 1314, 0, 1025}, /* ; 04 (640x480x60Hz) */
+	{18, 1314, 0, 1025}, /* ; 05 (800x600x60Hz) */
+	{18, 1314, 0, 1025}, /* ; 06 (1024x768x60Hz) */
+	{18, 1314, 0, 1025}  /* ; 07 (1280x1024x60Hz) */
 };
 
-static struct XGI330_LCDDataDesStruct  XGI_StLCDDLDes1280x1024x75Data[] =
-{
-        {18,1314,0,1025     },/* ; 00 (320x200,320x400,640x200,640x400) */
-        {18,1314,0,1025     },/* ; 01 (320x350,640x350) */
-        {18,1314,0,1025     },/* ; 02 (360x400,720x400) */
-        {18,1314,0,1025     },/* ; 03 (720x350) */
-        {18,1314,0,1025     },/* ; 04 (640x480x60Hz) */
-        {18,1314,0,1025     },/* ; 05 (800x600x60Hz) */
-        {18,1314,0,1025     },/* ; 06 (1024x768x60Hz) */
-        {18,1314,0,1025     }/* ; 07 (1280x1024x60Hz) */
+static struct XGI330_LCDDataDesStruct  XGI_StLCDDLDes1280x1024x75Data[] = {
+	{18, 1314, 0, 1025}, /* ; 00 (320x200,320x400,640x200,640x400) */
+	{18, 1314, 0, 1025}, /* ; 01 (320x350,640x350) */
+	{18, 1314, 0, 1025}, /* ; 02 (360x400,720x400) */
+	{18, 1314, 0, 1025}, /* ; 03 (720x350) */
+	{18, 1314, 0, 1025}, /* ; 04 (640x480x60Hz) */
+	{18, 1314, 0, 1025}, /* ; 05 (800x600x60Hz) */
+	{18, 1314, 0, 1025}, /* ; 06 (1024x768x60Hz) */
+	{18, 1314, 0, 1025}  /* ; 07 (1280x1024x60Hz) */
 };
 
-static struct XGI330_LCDDataDesStruct  XGI_CetLCDDLDes1280x1024x75Data[] =	/* 1280x1024x75Hz */
-{
-        {1368,1008,752,711},    /* ; 00 (320x200,320x400,640x200,640x400) */
-        {1368,1008,729,688},    /* ; 01 (320x350,640x350) */
-        {1408,1048,752,711},    /* ; 02 (360x400,720x400) */
-        {1408,1048,729,688},    /* ; 03 (720x350) */
-        {1377,985,794,753},    /* ; 04 (640x480x75Hz) */
-        {1457,1065,854,813},    /* ; 05 (800x600x75Hz) */
-        {1569,1177,938,897},    /* ; 06 (1024x768x75Hz) */
-        {18,1314,0,1025}     	  /* ; 07 (1280x1024x75Hz) */
+/* 1280x1024x75Hz */
+static struct XGI330_LCDDataDesStruct  XGI_CetLCDDLDes1280x1024x75Data[] = {
+	{1368, 1008, 752, 711}, /* ; 00 (320x200,320x400,640x200,640x400) */
+	{1368, 1008, 729, 688}, /* ; 01 (320x350,640x350) */
+	{1408, 1048, 752, 711}, /* ; 02 (360x400,720x400) */
+	{1408, 1048, 729, 688}, /* ; 03 (720x350) */
+	{1377, 985,  794, 753}, /* ; 04 (640x480x75Hz) */
+	{1457, 1065, 854, 813}, /* ; 05 (800x600x75Hz) */
+	{1569, 1177, 938, 897}, /* ; 06 (1024x768x75Hz) */
+	{18,   1314, 0,   1025} /* ; 07 (1280x1024x75Hz) */
 };
 
-static struct XGI330_LCDDataDesStruct  XGI_ExtLCDDes1280x1024x75Data[] =         /* ;;1280x1024x75Hz */
-{
-	{9,1305,0,1025},/* ; 00 (320x200,320x400,640x200,640x400) */
-        {9,1305,0,1025},/* ; 01 (320x350,640x350) */
-        {9,1305,0,1025},/* ; 02 (360x400,720x400) */
-        {9,1305,0,1025},/* ; 03 (720x350) */
-        {9,1305,0,1025},/* ; 04 (640x480x60Hz) */
-        {9,1305,0,1025},/* ; 05 (800x600x60Hz) */
-        {9,1305,0,1025},/* ; 06 (1024x768x60Hz) */
-        {9,1305,0,1025} /* ; 07 (1280x1024x60Hz) */
+/* ;;1280x1024x75Hz */
+static struct XGI330_LCDDataDesStruct  XGI_ExtLCDDes1280x1024x75Data[] = {
+	{9, 1305, 0, 1025}, /* ; 00 (320x200,320x400,640x200,640x400) */
+	{9, 1305, 0, 1025}, /* ; 01 (320x350,640x350) */
+	{9, 1305, 0, 1025}, /* ; 02 (360x400,720x400) */
+	{9, 1305, 0, 1025}, /* ; 03 (720x350) */
+	{9, 1305, 0, 1025}, /* ; 04 (640x480x60Hz) */
+	{9, 1305, 0, 1025}, /* ; 05 (800x600x60Hz) */
+	{9, 1305, 0, 1025}, /* ; 06 (1024x768x60Hz) */
+	{9, 1305, 0, 1025}  /* ; 07 (1280x1024x60Hz) */
 };
 
-static struct XGI330_LCDDataDesStruct  XGI_StLCDDes1280x1024x75Data[] =
-{
-	{9,1305,0,1025},/* ; 00 (320x200,320x400,640x200,640x400) */
-        {9,1305,0,1025},/* ; 01 (320x350,640x350) */
-        {9,1305,0,1025},/* ; 02 (360x400,720x400) */
-        {9,1305,0,1025},/* ; 03 (720x350) */
-        {9,1305,0,1025},/* ; 04 (640x480x60Hz) */
-        {9,1305,0,1025},/* ; 05 (800x600x60Hz) */
-        {9,1305,0,1025},/* ; 06 (1024x768x60Hz) */
-        {9,1305,0,1025} /* ; 07 (1280x1024x60Hz) */
+static struct XGI330_LCDDataDesStruct  XGI_StLCDDes1280x1024x75Data[] = {
+	{9, 1305, 0, 1025}, /* ; 00 (320x200,320x400,640x200,640x400) */
+	{9, 1305, 0, 1025}, /* ; 01 (320x350,640x350) */
+	{9, 1305, 0, 1025}, /* ; 02 (360x400,720x400) */
+	{9, 1305, 0, 1025}, /* ; 03 (720x350) */
+	{9, 1305, 0, 1025}, /* ; 04 (640x480x60Hz) */
+	{9, 1305, 0, 1025}, /* ; 05 (800x600x60Hz) */
+	{9, 1305, 0, 1025}, /* ; 06 (1024x768x60Hz) */
+	{9, 1305, 0, 1025}  /* ; 07 (1280x1024x60Hz) */
 };
 
-static struct XGI330_LCDDataDesStruct  XGI_CetLCDDes1280x1024x75Data[] =	/* 1280x1024x75Hz */
-{
-        {1368,1008,752,711},    /* ; 00 (320x200,320x400,640x200,640x400) */
-        {1368,1008,729,688},    /* ; 01 (320x350,640x350) */
-        {1408,1048,752,711},    /* ; 02 (360x400,720x400) */
-        {1408,1048,729,688},    /* ; 03 (720x350) */
-        {1377,985,794,753},    /* ; 04 (640x480x75Hz) */
-        {1457,1065,854,813},    /* ; 05 (800x600x75Hz) */
-        {1569,1177,938,897},    /* ; 06 (1024x768x75Hz) */
-        {9,1305,0,1025}     	  /* ; 07 (1280x1024x75Hz) */
+/* 1280x1024x75Hz */
+static struct XGI330_LCDDataDesStruct  XGI_CetLCDDes1280x1024x75Data[] = {
+	{1368, 1008, 752, 711}, /* ; 00 (320x200,320x400,640x200,640x400) */
+	{1368, 1008, 729, 688}, /* ; 01 (320x350,640x350) */
+	{1408, 1048, 752, 711}, /* ; 02 (360x400,720x400) */
+	{1408, 1048, 729, 688}, /* ; 03 (720x350) */
+	{1377, 985,  794, 753}, /* ; 04 (640x480x75Hz) */
+	{1457, 1065, 854, 813}, /* ; 05 (800x600x75Hz) */
+	{1569, 1177, 938, 897}, /* ; 06 (1024x768x75Hz) */
+	{9,    1305, 0,   1025} /* ; 07 (1280x1024x75Hz) */
 };
 
-static struct XGI330_LCDDataDesStruct2 XGI_NoScalingDesDatax75[] = /* Scaling LCD 75Hz */
-{
-	{9,657,448,405,96,2},   /* ; 00 (320x200,320x400,640x200,640x400) */
-        {9,657,448,355,96,2},   /* ; 01 (320x350,640x350) */
-        {9,738,448,405,108,2},   /* ; 02 (360x400,720x400) */
-        {9,738,448,355,108,2},   /* ; 03 (720x350) */
-        {9,665,0,481,64,3},   /* ; 04 (640x480x75Hz) */
-        {9,825,0,601,80,3},   /* ; 05 (800x600x75Hz) */
-        {9,1049,0,769,96,3},   /* ; 06 (1024x768x75Hz) */
-        {9,1305,0,1025,144,3},   /* ; 07 (1280x1024x75Hz) */
-        {9,1457,0,1051,112,3},   /* ; 08 (1400x1050x60Hz) ;;[ycchen] 12/19/02 */
-        {9,1673,0,1201,192,3},   /* ; 09 (1600x1200x75Hz) */
-        {9,1337,0,771,112,6}    /* ; 0A (1280x768x60Hz) */
+/* Scaling LCD 75Hz */
+static struct XGI330_LCDDataDesStruct2 XGI_NoScalingDesDatax75[] =  {
+	{9, 657,  448, 405,  96,  2}, /* ; 00 (320x200,320x400,
+					       640x200,640x400) */
+	{9, 657,  448, 355,  96,  2}, /* ; 01 (320x350,640x350) */
+	{9, 738,  448, 405,  108, 2}, /* ; 02 (360x400,720x400) */
+	{9, 738,  448, 355,  108, 2}, /* ; 03 (720x350) */
+	{9, 665,  0,   481,  64,  3}, /* ; 04 (640x480x75Hz) */
+	{9, 825,  0,   601,  80,  3}, /* ; 05 (800x600x75Hz) */
+	{9, 1049, 0,   769,  96,  3}, /* ; 06 (1024x768x75Hz) */
+	{9, 1305, 0,   1025, 144, 3}, /* ; 07 (1280x1024x75Hz) */
+	{9, 1457, 0,   1051, 112, 3}, /* ; 08 (1400x1050x60Hz)
+					 ;;[ycchen] 12/19/02 */
+	{9, 1673, 0,   1201, 192, 3}, /* ; 09 (1600x1200x75Hz) */
+	{9, 1337, 0,   771,  112, 6}  /* ; 0A (1280x768x60Hz) */
 };
 
-static struct XGI330_TVDataStruct  XGI_StPALData[] =
-{
- {    1,   1, 864, 525,1270, 400, 100,   0, 760},
- {    1,   1, 864, 525,1270, 350, 100,   0, 760},
- {    1,   1, 864, 525,1270, 400,   0,   0, 720},
- {    1,   1, 864, 525,1270, 350,   0,   0, 720},
- {    1,   1, 864, 525,1270, 480,  50,   0, 760},
- {    1,   1, 864, 525,1270, 600,  50,   0,   0}
+static struct XGI330_TVDataStruct  XGI_StPALData[] = {
+	{1, 1, 864, 525, 1270, 400, 100, 0, 760},
+	{1, 1, 864, 525, 1270, 350, 100, 0, 760},
+	{1, 1, 864, 525, 1270, 400,   0, 0, 720},
+	{1, 1, 864, 525, 1270, 350,   0, 0, 720},
+	{1, 1, 864, 525, 1270, 480,  50, 0, 760},
+	{1, 1, 864, 525, 1270, 600,  50, 0,   0}
 };
 
-static struct XGI330_TVDataStruct  XGI_ExtPALData[] =
-{
- {    2,   1,1080, 463,1270, 500,  50,   0,  50},
- {   15,   7,1152, 413,1270, 500,  50,   0,  50},
- {    2,   1,1080, 463,1270, 500,  50,   0,  50},
- {   15,   7,1152, 413,1270, 500,  50,   0,  50},
- {    2,   1, 900, 543,1270, 500,   0,   0,  50},
- {    4,   3,1080, 663,1270, 500, 438,   0, 438},
- {    1,   1,1125, 831,1270, 500, 686,   0, 686},     /*301b*/
- {    3,   2,1080, 619,1270, 540, 438,   0, 438}
+static struct XGI330_TVDataStruct  XGI_ExtPALData[] = {
+	{2,  1, 1080, 463, 1270, 500,  50, 0,  50},
+	{15, 7, 1152, 413, 1270, 500,  50, 0,  50},
+	{2,  1, 1080, 463, 1270, 500,  50, 0,  50},
+	{15, 7, 1152, 413, 1270, 500,  50, 0,  50},
+	{2,  1,  900, 543, 1270, 500,   0, 0,  50},
+	{4,  3, 1080, 663, 1270, 500, 438, 0, 438},
+	{1,  1, 1125, 831, 1270, 500, 686, 0, 686}, /*301b*/
+	{3,  2, 1080, 619, 1270, 540, 438, 0, 438}
 };
 
-static struct XGI330_TVDataStruct  XGI_StNTSCData[] =
-{
- {    1,   1, 858, 525,1270, 400,  50,   0, 760},
- {    1,   1, 858, 525,1270, 350,  50,   0, 640},
- {    1,   1, 858, 525,1270, 400,   0,   0, 720},
- {    1,   1, 858, 525,1270, 350,   0,   0, 720},
- {    1,   1, 858, 525,1270, 480,   0,   0, 760}
+static struct XGI330_TVDataStruct  XGI_StNTSCData[] = {
+	{1, 1, 858, 525, 1270, 400, 50, 0, 760},
+	{1, 1, 858, 525, 1270, 350, 50, 0, 640},
+	{1, 1, 858, 525, 1270, 400,  0, 0, 720},
+	{1, 1, 858, 525, 1270, 350,  0, 0, 720},
+	{1, 1, 858, 525, 1270, 480,  0, 0, 760}
 };
 
-static struct XGI330_TVDataStruct  XGI_ExtNTSCData[] =
-{
- {    9,  5, 1001, 453,1270, 420, 171,   0, 171},
- {   12,  5,  858, 403,1270, 420, 171,   0, 171},
- {    9,  5, 1001, 453,1270, 420, 171,   0, 171},
- {   12,  5,  858, 403,1270, 420, 171,   0, 171},
- {  143,  80, 836, 523,1270, 420, 224,   0,   0},
- {  143, 120,1008, 643,1270, 420,   0,   1,   0},
- {   1,    1,1120, 821,1516, 420,   0,   1,   0}, /*301b*/
- {    2,   1, 858, 503,1584, 480,   0,   1,   0},
- {    3,   2,1001, 533,1270, 420,   0,   0,   0}
+static struct XGI330_TVDataStruct  XGI_ExtNTSCData[] = {
+	{9,     5, 1001, 453, 1270, 420, 171, 0, 171},
+	{12,    5,  858, 403, 1270, 420, 171, 0, 171},
+	{9,     5, 1001, 453, 1270, 420, 171, 0, 171},
+	{12,    5,  858, 403, 1270, 420, 171, 0, 171},
+	{143,  80,  836, 523, 1270, 420, 224, 0,   0},
+	{143, 120, 1008, 643, 1270, 420,   0, 1,   0},
+	{1,     1, 1120, 821, 1516, 420,   0, 1,   0}, /*301b*/
+	{2,     1,  858, 503, 1584, 480,   0, 1,   0},
+	{3,     2, 1001, 533, 1270, 420,   0, 0,   0}
 };
 
-static struct XGI330_TVDataStruct  XGI_St1HiTVData[] =
-{
-    	{        1,1,892,563,690,800,0,0,0               }, /* 00 (320x200,320x400,640x200,640x400) */
-        {        1,1,892,563,690,700,0,0,0               }, /* 01 (320x350,640x350) */
-        {        1,1,1000,563,785,800,0,0,0              }, /* 02 (360x400,720x400) */
-        {        1,1,1000,563,785,700,0,0,0              }, /* 03 (720x350) */
-        {        1,1,892,563,690,960,0,0,0               }, /* 04 (320x240,640x480) */
-        {        8,5,1050,683,1648,960,0x150,1,0         }  /* 05 (400x300,800x600) */
+static struct XGI330_TVDataStruct  XGI_St1HiTVData[] = {
+	{1, 1, 892,  563, 690,  800, 0,     0, 0}, /* 00 (320x200,320x400,
+							  640x200,640x400) */
+	{1, 1, 892,  563, 690,  700, 0,     0, 0}, /* 01 (320x350,640x350) */
+	{1, 1, 1000, 563, 785,  800, 0,     0, 0}, /* 02 (360x400,720x400) */
+	{1, 1, 1000, 563, 785,  700, 0,     0, 0}, /* 03 (720x350) */
+	{1, 1, 892,  563, 690,  960, 0,     0, 0}, /* 04 (320x240,640x480) */
+	{8, 5, 1050, 683, 1648, 960, 0x150, 1, 0}  /* 05 (400x300,800x600) */
 };
 
-static struct XGI330_TVDataStruct  XGI_St2HiTVData[] =
-{
-        {        3,1,840,483,1648,960,0x032,0,0          }, /* 00 (320x200,320x400,640x200,640x400) */
-        {        1,1,892,563,690,700,0,0,0               }, /* 01 (320x350,640x350) */
-        {        3,1,840,483,1648,960,0x032,0,0          }, /* 02 (360x400,720x400) */
-        {        1,1,1000,563,785,700,0,0,0              }, /* 03 (720x350) */
-        {        5,2,840,563,1648,960,0x08D,1,0          }, /* 04 (320x240,640x480) */
-        {        8,5,1050,683,1648,960,0x17C,1,0         }  /* 05 (400x300,800x600) */
-
+static struct XGI330_TVDataStruct  XGI_St2HiTVData[] = {
+	{3, 1, 840,  483, 1648, 960, 0x032, 0, 0}, /* 00 (320x200,320x400,
+							  640x200,640x400) */
+	{1, 1, 892,  563, 690,  700, 0,     0, 0}, /* 01 (320x350,640x350) */
+	{3, 1, 840,  483, 1648, 960, 0x032, 0, 0}, /* 02 (360x400,720x400) */
+	{1, 1, 1000, 563, 785,  700, 0,     0, 0}, /* 03 (720x350) */
+	{5, 2, 840,  563, 1648, 960, 0x08D, 1, 0}, /* 04 (320x240,640x480) */
+	{8, 5, 1050, 683, 1648, 960, 0x17C, 1, 0}  /* 05 (400x300,800x600) */
 };
 
-static struct XGI330_TVDataStruct  XGI_ExtHiTVData[] =
-{
-        {        6,1,840,563,1632,960,0,0,0              }, /* 00 (320x200,320x400,640x200,640x400) */
-        {        3,1,960,563,1632,960,0,0,0              }, /* 01 (320x350,640x350) */
-        {        3,1,840,483,1632,960,0,0,0              }, /* 02 (360x400,720x400) */
-        {        3,1,960,563,1632,960,0,0,0              }, /* 03 (720x350) */
-        {        5,1,840,563,1648,960,0x166,1,0          }, /* 04 (320x240,640x480) */
-        {        16,5,1050,683,1648,960,0x143,1,0        }, /* 05 (400x300,800x600) */
-        {        25,12,1260,851,1648,960,0x032,0,0       }, /* 06 (512x384,1024x768) */
-        {        5,4,1575,1124,1648,960,0x128,0,0        }, /* 07 (1280x1024) */
-        {        4,1,1050,563,1548,960,0x143,1,0         }, /* 08 (800x480) */
-        {        5,2,1400,659,1648,960,0x032,0,0         }, /* 09 (1024x576) */
-        {        8,5,1750,803,1648,960,0x128,0,0         }  /* 0A (1280x720) */
-
+static struct XGI330_TVDataStruct  XGI_ExtHiTVData[] = {
+	{6,  1,  840,  563,  1632, 960, 0,     0, 0}, /* 00 (320x200,320x400,
+							     640x200,640x400) */
+	{3,  1,  960,  563,  1632, 960, 0,     0, 0}, /* 01 (320x350,640x350) */
+	{3,  1,  840,  483,  1632, 960, 0,     0, 0}, /* 02 (360x400,720x400) */
+	{3,  1,  960,  563,  1632, 960, 0,     0, 0}, /* 03 (720x350) */
+	{5,  1,  840,  563,  1648, 960, 0x166, 1, 0}, /* 04 (320x240,640x480) */
+	{16, 5,  1050, 683,  1648, 960, 0x143, 1, 0}, /* 05 (400x300,800x600) */
+	{25, 12, 1260, 851,  1648, 960, 0x032, 0, 0}, /* 06 (512x384,1024x768)*/
+	{5,  4,  1575, 1124, 1648, 960, 0x128, 0, 0}, /* 07 (1280x1024) */
+	{4,  1,  1050, 563,  1548, 960, 0x143, 1, 0}, /* 08 (800x480) */
+	{5,  2,  1400, 659,  1648, 960, 0x032, 0, 0}, /* 09 (1024x576) */
+	{8,  5,  1750, 803,  1648, 960, 0x128, 0, 0}  /* 0A (1280x720) */
 };
 
-static struct XGI330_TVDataStruct  XGI_ExtYPbPr525iData[] =
-{
- {    9,  5, 1001, 453,1270, 420, 171,   0, 171},
- {   12,  5,  858, 403,1270, 420, 171,   0, 171},
- {    9,  5, 1001, 453,1270, 420, 171,   0, 171},
- {   12,  5,  858, 403,1270, 420, 171,   0, 171},
- {  143,  80, 836, 523,1250, 420, 224,   0,   0},
- {  143, 120,1008, 643,1250, 420,   0,   1,   0},
- {   1,    1,1120, 821,1516, 420,   0,   1,   0}, /*301b*/
- {    2,   1, 858, 503,1584, 480,   0,   1,   0},
- {    3,   2,1001, 533,1250, 420,   0,   0,   0}
+static struct XGI330_TVDataStruct  XGI_ExtYPbPr525iData[] = {
+	{  9,  5,  1001, 453, 1270, 420, 171,   0, 171},
+	{ 12,  5,   858, 403, 1270, 420, 171,   0, 171},
+	{  9,  5,  1001, 453, 1270, 420, 171,   0, 171},
+	{ 12,  5,   858, 403, 1270, 420, 171,   0, 171},
+	{143,  80,  836, 523, 1250, 420, 224,   0,   0},
+	{143, 120, 1008, 643, 1250, 420,   0,   1,   0},
+	{ 1,    1, 1120, 821, 1516, 420,   0,   1,   0}, /*301b*/
+	{  2,   1,  858, 503, 1584, 480,   0,   1,   0},
+	{  3,   2, 1001, 533, 1250, 420,   0,   0,   0}
 };
 
-static struct XGI330_TVDataStruct  XGI_StYPbPr525iData[] =
-{
- {    1,   1, 858, 525,1270, 400,  50,   0, 760},
- {    1,   1, 858, 525,1270, 350,  50,   0, 640},
- {    1,   1, 858, 525,1270, 400,   0,   0, 720},
- {    1,   1, 858, 525,1270, 350,   0,   0, 720},
- {    1,   1, 858, 525,1270, 480,   0,   0, 760},
+static struct XGI330_TVDataStruct  XGI_StYPbPr525iData[] = {
+	{1, 1, 858, 525, 1270, 400, 50, 0, 760},
+	{1, 1, 858, 525, 1270, 350, 50, 0, 640},
+	{1, 1, 858, 525, 1270, 400,  0, 0, 720},
+	{1, 1, 858, 525, 1270, 350,  0, 0, 720},
+	{1, 1, 858, 525, 1270, 480,  0, 0, 760},
 };
 
-static struct XGI330_TVDataStruct  XGI_ExtYPbPr525pData[] =
-{
- {    9,  5, 1001, 453,1270, 420, 171,   0, 171},
- {   12,  5,  858, 403,1270, 420, 171,   0, 171},
- {    9,  5, 1001, 453,1270, 420, 171,   0, 171},
- {   12,  5,  858, 403,1270, 420, 171,   0, 171},
- {  143,  80, 836, 523,1270, 420, 224,   0,   0},
- {  143, 120,1008, 643,1270, 420,   0,   1,   0},
- {   1,    1,1120, 821,1516, 420,   0,   1,   0}, /*301b*/
- {    2,   1, 858, 503,1584, 480,   0,   1,   0},
- {    3,   2,1001, 533,1270, 420,   0,   0,   0}
- };
+static struct XGI330_TVDataStruct  XGI_ExtYPbPr525pData[] = {
+	{  9,   5,  1001, 453, 1270, 420, 171, 0, 171},
+	{ 12,   5,   858, 403, 1270, 420, 171, 0, 171},
+	{  9,   5,  1001, 453, 1270, 420, 171, 0, 171},
+	{ 12,   5,   858, 403, 1270, 420, 171, 0, 171},
+	{143,  80,   836, 523, 1270, 420, 224, 0,   0},
+	{143, 120,  1008, 643, 1270, 420,   0, 1,   0},
+	{ 1,    1,  1120, 821, 1516, 420,   0, 1,   0}, /*301b*/
+	{  2,   1,   858, 503, 1584, 480,   0, 1,   0},
+	{  3,   2,  1001, 533, 1270, 420,   0, 0,   0}
+};
 
-static struct XGI330_TVDataStruct  XGI_StYPbPr525pData[] =
-{
- {    1,   1,1716, 525,1270, 400,  50,   0, 760},
- {    1,   1,1716, 525,1270, 350,  50,   0, 640},
- {    1,   1,1716, 525,1270, 400,   0,   0, 720},
- {    1,   1,1716, 525,1270, 350,   0,   0, 720},
- {    1,   1,1716, 525,1270, 480,   0,   0, 760},
+static struct XGI330_TVDataStruct  XGI_StYPbPr525pData[] = {
+	{1, 1, 1716, 525, 1270, 400, 50, 0, 760},
+	{1, 1, 1716, 525, 1270, 350, 50, 0, 640},
+	{1, 1, 1716, 525, 1270, 400,  0, 0, 720},
+	{1, 1, 1716, 525, 1270, 350,  0, 0, 720},
+	{1, 1, 1716, 525, 1270, 480,  0, 0, 760},
 };
 
-static struct XGI330_TVDataStruct  XGI_ExtYPbPr750pData[] =
-{
- {    3,   1, 935, 470,1130, 680,  50,   0,   0},       /* 00 (320x200,320x400,640x200,640x400) */
- {   24,   7, 935, 420,1130, 680,  50,   0,   0},       /* 01 (320x350,640x350) */
- {    3,   1, 935, 470,1130, 680,  50,   0,   0},       /* 02 (360x400,720x400) */
- {   24,   7, 935, 420,1130, 680,  50,   0,   0},       /* 03 (720x350) */
- {    2,   1,1100, 590,1130, 640,  50,   0,   0},       /* 04 (320x240,640x480) */
- {    3,   2,1210, 690,1130, 660,  50,   0,   0},       /* 05 (400x300,800x600) */
- {    1,   1,1375, 878,1130, 640, 638,   0,   0},       /* 06 (1024x768) */
- {    2,   1, 858, 503,1130, 480,   0,   1,   0},        /* 07 (720x480) */
- {    5,   4,1815, 570,1130, 660,  50,   0,   0},
- {    5,   3,1100, 686,1130, 640,  50,   1,   0},
- {   10,   9,1320, 830,1130, 640,  50,   0,   0}
+static struct XGI330_TVDataStruct  XGI_ExtYPbPr750pData[] = {
+	{ 3, 1,  935, 470, 1130, 680,  50, 0, 0}, /* 00 (320x200,320x400,
+							 640x200,640x400) */
+	{24, 7,  935, 420, 1130, 680,  50, 0, 0}, /* 01 (320x350,640x350) */
+	{ 3, 1,  935, 470, 1130, 680,  50, 0, 0}, /* 02 (360x400,720x400) */
+	{24, 7,  935, 420, 1130, 680,  50, 0, 0}, /* 03 (720x350) */
+	{ 2, 1, 1100, 590, 1130, 640,  50, 0, 0}, /* 04 (320x240,640x480) */
+	{ 3, 2, 1210, 690, 1130, 660,  50, 0, 0}, /* 05 (400x300,800x600) */
+	{ 1, 1, 1375, 878, 1130, 640, 638, 0, 0}, /* 06 (1024x768) */
+	{ 2, 1,  858, 503, 1130, 480,   0, 1, 0}, /* 07 (720x480) */
+	{ 5, 4, 1815, 570, 1130, 660,  50, 0, 0},
+	{ 5, 3, 1100, 686, 1130, 640,  50, 1, 0},
+	{10, 9, 1320, 830, 1130, 640,  50, 0, 0}
 };
 
-static struct XGI330_TVDataStruct  XGI_StYPbPr750pData[] =
-{
- {    1,   1,1650, 750,1280, 400,  50,   0, 760},
- {    1,   1,1650, 750,1280, 350,  50,   0, 640},
- {    1,   1,1650, 750,1280, 400,   0,   0, 720},
- {    1,   1,1650, 750,1280, 350,   0,   0, 720},
- {    1,   1,1650, 750,1280, 480,   0,   0, 760},
+static struct XGI330_TVDataStruct  XGI_StYPbPr750pData[] = {
+	{1, 1, 1650, 750, 1280, 400, 50, 0, 760},
+	{1, 1, 1650, 750, 1280, 350, 50, 0, 640},
+	{1, 1, 1650, 750, 1280, 400,  0, 0, 720},
+	{1, 1, 1650, 750, 1280, 350,  0, 0, 720},
+	{1, 1, 1650, 750, 1280, 480,  0, 0, 760},
 };
 
 static unsigned char XGI330_NTSCTiming[] = {
-  0x17,0x1d,0x03,0x09,0x05,0x06,0x0c,0x0c,
-  0x94,0x49,0x01,0x0a,0x06,0x0d,0x04,0x0a,
-  0x06,0x14,0x0d,0x04,0x0a,0x00,0x85,0x1b,
-  0x0c,0x50,0x00,0x97,0x00,0xda,0x4a,0x17,
-  0x7d,0x05,0x4b,0x00,0x00,0xe2,0x00,0x02,
-  0x03,0x0a,0x65,0x9d,0x08,0x92,0x8f,0x40,
-  0x60,0x80,0x14,0x90,0x8c,0x60,0x14,0x50,
-  0x00,0x40,0x44,0x00,0xdb,0x02,0x3b,0x00};
+	0x17, 0x1d, 0x03, 0x09, 0x05, 0x06, 0x0c, 0x0c,
+	0x94, 0x49, 0x01, 0x0a, 0x06, 0x0d, 0x04, 0x0a,
+	0x06, 0x14, 0x0d, 0x04, 0x0a, 0x00, 0x85, 0x1b,
+	0x0c, 0x50, 0x00, 0x97, 0x00, 0xda, 0x4a, 0x17,
+	0x7d, 0x05, 0x4b, 0x00, 0x00, 0xe2, 0x00, 0x02,
+	0x03, 0x0a, 0x65, 0x9d, 0x08, 0x92, 0x8f, 0x40,
+	0x60, 0x80, 0x14, 0x90, 0x8c, 0x60, 0x14, 0x50,
+	0x00, 0x40, 0x44, 0x00, 0xdb, 0x02, 0x3b, 0x00
+};
 
 static unsigned char XGI330_PALTiming[] = {
-  0x21,0x5A,0x35,0x6e,0x04,0x38,0x3d,0x70,
-  0x94,0x49,0x01,0x12,0x06,0x3e,0x35,0x6d,
-  0x06,0x14,0x3e,0x35,0x6d,0x00,0x45,0x2b,
-  0x70,0x50,0x00,0x9b,0x00,0xd9,0x5d,0x17,
-  0x7d,0x05,0x45,0x00,0x00,0xe8,0x00,0x02,
-  0x0d,0x00,0x68,0xb0,0x0b,0x92,0x8f,0x40,
-  0x60,0x80,0x14,0x90,0x8c,0x60,0x14,0x63,
-  0x00,0x40,0x3e,0x00,0xe1,0x02,0x28,0x00};
-
-static unsigned char XGI330_HiTVExtTiming[] =
-{
-      0x2D,0x60,0x2C,0x5F,0x08,0x31,0x3A,0x64,
-      0x28,0x02,0x01,0x3D,0x06,0x3E,0x35,0x6D,
-      0x06,0x14,0x3E,0x35,0x6D,0x00,0xC5,0x3F,
-      0x64,0x90,0x33,0x8C,0x18,0x36,0x3E,0x13,
-      0x2A,0xDE,0x2A,0x44,0x40,0x2A,0x44,0x40,
-      0x8E,0x8E,0x82,0x07,0x0B,
-      0x92,0x0F,0x40,0x60,0x80,0x14,0x90,0x8C,
-      0x60,0x14,0x3D,0x63,0x4F,
-      0x27,0x00,0xfc,0xff,0x6a,0x00
-
+	0x21, 0x5A, 0x35, 0x6e, 0x04, 0x38, 0x3d, 0x70,
+	0x94, 0x49, 0x01, 0x12, 0x06, 0x3e, 0x35, 0x6d,
+	0x06, 0x14, 0x3e, 0x35, 0x6d, 0x00, 0x45, 0x2b,
+	0x70, 0x50, 0x00, 0x9b, 0x00, 0xd9, 0x5d, 0x17,
+	0x7d, 0x05, 0x45, 0x00, 0x00, 0xe8, 0x00, 0x02,
+	0x0d, 0x00, 0x68, 0xb0, 0x0b, 0x92, 0x8f, 0x40,
+	0x60, 0x80, 0x14, 0x90, 0x8c, 0x60, 0x14, 0x63,
+	0x00, 0x40, 0x3e, 0x00, 0xe1, 0x02, 0x28, 0x00
 };
 
-static unsigned char XGI330_HiTVSt1Timing[] =
-{
-      0x32,0x65,0x2C,0x5F,0x08,0x31,0x3A,0x65,
-      0x28,0x02,0x01,0x3D,0x06,0x3E,0x35,0x6D,
-      0x06,0x14,0x3E,0x35,0x6D,0x00,0xC5,0x3F,
-      0x65,0x90,0x7B,0xA8,0x03,0xF0,0x87,0x03,
-      0x11,0x15,0x11,0xCF,0x10,0x11,0xCF,0x10,
-      0x35,0x35,0x3B,0x69,0x1D,
-      0x92,0x0F,0x40,0x60,0x80,0x14,0x90,0x8C,
-      0x60,0x04,0x86,0xAF,0x5D,
-      0x0E,0x00,0xfc,0xff,0x2d,0x00
+static unsigned char XGI330_HiTVExtTiming[] = {
+	0x2D, 0x60, 0x2C, 0x5F, 0x08, 0x31, 0x3A, 0x64,
+	0x28, 0x02, 0x01, 0x3D, 0x06, 0x3E, 0x35, 0x6D,
+	0x06, 0x14, 0x3E, 0x35, 0x6D, 0x00, 0xC5, 0x3F,
+	0x64, 0x90, 0x33, 0x8C, 0x18, 0x36, 0x3E, 0x13,
+	0x2A, 0xDE, 0x2A, 0x44, 0x40, 0x2A, 0x44, 0x40,
+	0x8E, 0x8E, 0x82, 0x07, 0x0B,
+	0x92, 0x0F, 0x40, 0x60, 0x80, 0x14, 0x90, 0x8C,
+	0x60, 0x14, 0x3D, 0x63, 0x4F,
+	0x27, 0x00, 0xfc, 0xff, 0x6a, 0x00
 };
 
-static unsigned char XGI330_HiTVSt2Timing[] =
-{
-      0x32,0x65,0x2C,0x5F,0x08,0x31,0x3A,0x64,
-      0x28,0x02,0x01,0x3D,0x06,0x3E,0x35,0x6D,
-      0x06,0x14,0x3E,0x35,0x6D,0x00,0xC5,0x3F,
-      0x64,0x90,0x33,0x8C,0x18,0x36,0x3E,0x13,
-      0x2A,0xDE,0x2A,0x44,0x40,0x2A,0x44,0x40,
-      0x8E,0x8E,0x82,0x07,0x0B,
-      0x92,0x0F,0x40,0x60,0x80,0x14,0x90,0x8C,
-      0x60,0x14,0x3D,0x63,0x4F,
-      0x27,0x00,0xFC,0xff,0x6a,0x00
+static unsigned char XGI330_HiTVSt1Timing[] = {
+	0x32, 0x65, 0x2C, 0x5F, 0x08, 0x31, 0x3A, 0x65,
+	0x28, 0x02, 0x01, 0x3D, 0x06, 0x3E, 0x35, 0x6D,
+	0x06, 0x14, 0x3E, 0x35, 0x6D, 0x00, 0xC5, 0x3F,
+	0x65, 0x90, 0x7B, 0xA8, 0x03, 0xF0, 0x87, 0x03,
+	0x11, 0x15, 0x11, 0xCF, 0x10, 0x11, 0xCF, 0x10,
+	0x35, 0x35, 0x3B, 0x69, 0x1D,
+	0x92, 0x0F, 0x40, 0x60, 0x80, 0x14, 0x90, 0x8C,
+	0x60, 0x04, 0x86, 0xAF, 0x5D,
+	0x0E, 0x00, 0xfc, 0xff, 0x2d, 0x00
 };
 
-static unsigned char XGI330_HiTVTextTiming[] =
-{
-      0x32,0x65,0x2C,0x5F,0x08,0x31,0x3A,0x65,
-      0x28,0x02,0x01,0x3D,0x06,0x3E,0x35,0x6D,
-      0x06,0x14,0x3E,0x35,0x6D,0x00,0xC5,0x3F,
-      0x65,0x90,0xE7,0xBC,0x03,0x0C,0x97,0x03,
-      0x14,0x78,0x14,0x08,0x20,0x14,0x08,0x20,
-      0xC8,0xC8,0x3B,0xD2,0x26,
-      0x92,0x0F,0x40,0x60,0x80,0x14,0x90,0x8C,
-      0x60,0x04,0x96,0x72,0x5C,
-      0x11,0x00,0xFC,0xFF,0x32,0x00
+static unsigned char XGI330_HiTVSt2Timing[] = {
+	0x32, 0x65, 0x2C, 0x5F, 0x08, 0x31, 0x3A, 0x64,
+	0x28, 0x02, 0x01, 0x3D, 0x06, 0x3E, 0x35, 0x6D,
+	0x06, 0x14, 0x3E, 0x35, 0x6D, 0x00, 0xC5, 0x3F,
+	0x64, 0x90, 0x33, 0x8C, 0x18, 0x36, 0x3E, 0x13,
+	0x2A, 0xDE, 0x2A, 0x44, 0x40, 0x2A, 0x44, 0x40,
+	0x8E, 0x8E, 0x82, 0x07, 0x0B,
+	0x92, 0x0F, 0x40, 0x60, 0x80, 0x14, 0x90, 0x8C,
+	0x60, 0x14, 0x3D, 0x63, 0x4F,
+	0x27, 0x00, 0xFC, 0xff, 0x6a, 0x00
 };
 
-static unsigned char XGI330_YPbPr750pTiming[] =
-{
-      0x30,0x1d,0xe8,0x09,0x09,0xed,0x0c,0x0c,
-      0x98,0x0a,0x01,0x0c,0x06,0x0d,0x04,0x0a,
-      0x06,0x14,0x0d,0x04,0x0a,0x00,0x85,0x3f,
-      0xed,0x50,0x70,0x9f,0x16,0x59,0x60,0x13,
-      0x27,0x0b,0x27,0xfc,0x30,0x27,0x1c,0xb0,
-      0x4b,0x4b,0x6f,0x2f,0x63,
-      0x92,0x0F,0x40,0x60,0x80,0x14,0x90,0x8C,
-      0x60,0x14,0x73,0x00,0x40,
-      0x11,0x00,0xfc,0xff,0x32,0x00
+static unsigned char XGI330_HiTVTextTiming[] = {
+	0x32, 0x65, 0x2C, 0x5F, 0x08, 0x31, 0x3A, 0x65,
+	0x28, 0x02, 0x01, 0x3D, 0x06, 0x3E, 0x35, 0x6D,
+	0x06, 0x14, 0x3E, 0x35, 0x6D, 0x00, 0xC5, 0x3F,
+	0x65, 0x90, 0xE7, 0xBC, 0x03, 0x0C, 0x97, 0x03,
+	0x14, 0x78, 0x14, 0x08, 0x20, 0x14, 0x08, 0x20,
+	0xC8, 0xC8, 0x3B, 0xD2, 0x26,
+	0x92, 0x0F, 0x40, 0x60, 0x80, 0x14, 0x90, 0x8C,
+	0x60, 0x04, 0x96, 0x72, 0x5C,
+	0x11, 0x00, 0xFC, 0xFF, 0x32, 0x00
 };
 
-static unsigned char XGI330_YPbPr525pTiming[] =
-{
-      0x3E,0x11,0x06,0x09,0x0b,0x0c,0x0c,0x0c,
-      0x98,0x0a,0x01,0x0d,0x06,0x0d,0x04,0x0a,
-      0x06,0x14,0x0d,0x04,0x0a,0x00,0x85,0x3f,
-      0x0c,0x50,0xb2,0x9f,0x16,0x59,0x4f,0x13,
-      0xad,0x11,0xad,0x1d,0x40,0x8a,0x3d,0xb8,
-      0x51,0x5e,0x60,0x49,0x7d,
-      0x92,0x0F,0x40,0x60,0x80,0x14,0x90,0x8C,
-      0x60,0x14,0x4B,0x43,0x41,
-      0x11,0x00,0xFC,0xFF,0x32,0x00
+static unsigned char XGI330_YPbPr750pTiming[] = {
+	0x30, 0x1d, 0xe8, 0x09, 0x09, 0xed, 0x0c, 0x0c,
+	0x98, 0x0a, 0x01, 0x0c, 0x06, 0x0d, 0x04, 0x0a,
+	0x06, 0x14, 0x0d, 0x04, 0x0a, 0x00, 0x85, 0x3f,
+	0xed, 0x50, 0x70, 0x9f, 0x16, 0x59, 0x60, 0x13,
+	0x27, 0x0b, 0x27, 0xfc, 0x30, 0x27, 0x1c, 0xb0,
+	0x4b, 0x4b, 0x6f, 0x2f, 0x63,
+	0x92, 0x0F, 0x40, 0x60, 0x80, 0x14, 0x90, 0x8C,
+	0x60, 0x14, 0x73, 0x00, 0x40,
+	0x11, 0x00, 0xfc, 0xff, 0x32, 0x00
 };
 
-static unsigned char XGI330_YPbPr525iTiming[] =
-{
-      0x1B,0x21,0x03,0x09,0x05,0x06,0x0C,0x0C,
-      0x94,0x49,0x01,0x0A,0x06,0x0D,0x04,0x0A,
-      0x06,0x14,0x0D,0x04,0x0A,0x00,0x85,0x1B,
-      0x0C,0x50,0x00,0x97,0x00,0xDA,0x4A,0x17,
-      0x7D,0x05,0x4B,0x00,0x00,0xE2,0x00,0x02,
-      0x03,0x0A,0x65,0x9D,0x08,
-      0x92,0x8F,0x40,0x60,0x80,0x14,0x90,0x8C,
-      0x60,0x14,0x4B,0x00,0x40,
-      0x44,0x00,0xDB,0x02,0x3B,0x00
+static unsigned char XGI330_YPbPr525pTiming[] = {
+	0x3E, 0x11, 0x06, 0x09, 0x0b, 0x0c, 0x0c, 0x0c,
+	0x98, 0x0a, 0x01, 0x0d, 0x06, 0x0d, 0x04, 0x0a,
+	0x06, 0x14, 0x0d, 0x04, 0x0a, 0x00, 0x85, 0x3f,
+	0x0c, 0x50, 0xb2, 0x9f, 0x16, 0x59, 0x4f, 0x13,
+	0xad, 0x11, 0xad, 0x1d, 0x40, 0x8a, 0x3d, 0xb8,
+	0x51, 0x5e, 0x60, 0x49, 0x7d,
+	0x92, 0x0F, 0x40, 0x60, 0x80, 0x14, 0x90, 0x8C,
+	0x60, 0x14, 0x4B, 0x43, 0x41,
+	0x11, 0x00, 0xFC, 0xFF, 0x32, 0x00
+};
 
+static unsigned char XGI330_YPbPr525iTiming[] = {
+	0x1B, 0x21, 0x03, 0x09, 0x05, 0x06, 0x0C, 0x0C,
+	0x94, 0x49, 0x01, 0x0A, 0x06, 0x0D, 0x04, 0x0A,
+	0x06, 0x14, 0x0D, 0x04, 0x0A, 0x00, 0x85, 0x1B,
+	0x0C, 0x50, 0x00, 0x97, 0x00, 0xDA, 0x4A, 0x17,
+	0x7D, 0x05, 0x4B, 0x00, 0x00, 0xE2, 0x00, 0x02,
+	0x03, 0x0A, 0x65, 0x9D, 0x08,
+	0x92, 0x8F, 0x40, 0x60, 0x80, 0x14, 0x90, 0x8C,
+	0x60, 0x14, 0x4B, 0x00, 0x40,
+	0x44, 0x00, 0xDB, 0x02, 0x3B, 0x00
 };
 
-static unsigned char XGI330_HiTVGroup3Data[] =
-{
-      0x00,0x1A,0x22,0x63,0x62,0x22,0x08,0x5F,
-      0x05,0x21,0xB2,0xB2,0x55,0x77,0x2A,0xA6,
-      0x25,0x2F,0x47,0xFA,0xC8,0xFF,0x8E,0x20,
-      0x8C,0x6E,0x60,0x2E,0x58,0x48,0x72,0x44,
-      0x56,0x36,0x4F,0x6E,0x3F,0x80,0x00,0x80,
-      0x4F,0x7F,0x03,0xA8,0x7D,0x20,0x1A,0xA9,
-      0x14,0x05,0x03,0x7E,0x64,0x31,0x14,0x75,
-      0x18,0x05,0x18,0x05,0x4C,0xA8,0x01
+static unsigned char XGI330_HiTVGroup3Data[] = {
+	0x00, 0x1A, 0x22, 0x63, 0x62, 0x22, 0x08, 0x5F,
+	0x05, 0x21, 0xB2, 0xB2, 0x55, 0x77, 0x2A, 0xA6,
+	0x25, 0x2F, 0x47, 0xFA, 0xC8, 0xFF, 0x8E, 0x20,
+	0x8C, 0x6E, 0x60, 0x2E, 0x58, 0x48, 0x72, 0x44,
+	0x56, 0x36, 0x4F, 0x6E, 0x3F, 0x80, 0x00, 0x80,
+	0x4F, 0x7F, 0x03, 0xA8, 0x7D, 0x20, 0x1A, 0xA9,
+	0x14, 0x05, 0x03, 0x7E, 0x64, 0x31, 0x14, 0x75,
+	0x18, 0x05, 0x18, 0x05, 0x4C, 0xA8, 0x01
 };
 
-static unsigned char XGI330_HiTVGroup3Simu[] =
-{
-      0x00,0x1A,0x22,0x63,0x62,0x22,0x08,0x95,
-      0xDB,0x20,0xB8,0xB8,0x55,0x47,0x2A,0xA6,
-      0x25,0x2F,0x47,0xFA,0xC8,0xFF,0x8E,0x20,
-      0x8C,0x6E,0x60,0x15,0x26,0xD3,0xE4,0x11,
-      0x56,0x36,0x4F,0x6E,0x3F,0x80,0x00,0x80,
-      0x67,0x36,0x01,0x47,0x0E,0x10,0xBE,0xB4,
-      0x01,0x05,0x03,0x7E,0x65,0x31,0x14,0x75,
-      0x18,0x05,0x18,0x05,0x4C,0xA8,0x01
+static unsigned char XGI330_HiTVGroup3Simu[] = {
+	0x00, 0x1A, 0x22, 0x63, 0x62, 0x22, 0x08, 0x95,
+	0xDB, 0x20, 0xB8, 0xB8, 0x55, 0x47, 0x2A, 0xA6,
+	0x25, 0x2F, 0x47, 0xFA, 0xC8, 0xFF, 0x8E, 0x20,
+	0x8C, 0x6E, 0x60, 0x15, 0x26, 0xD3, 0xE4, 0x11,
+	0x56, 0x36, 0x4F, 0x6E, 0x3F, 0x80, 0x00, 0x80,
+	0x67, 0x36, 0x01, 0x47, 0x0E, 0x10, 0xBE, 0xB4,
+	0x01, 0x05, 0x03, 0x7E, 0x65, 0x31, 0x14, 0x75,
+	0x18, 0x05, 0x18, 0x05, 0x4C, 0xA8, 0x01
 };
 
-static unsigned char XGI330_HiTVGroup3Text[] =
-{
-      0x00,0x1A,0x22,0x63,0x62,0x22,0x08,0xA7,
-      0xF5,0x20,0xCE,0xCE,0x55,0x47,0x2A,0xA6,
-      0x25,0x2F,0x47,0xFA,0xC8,0xFF,0x8E,0x20,
-      0x8C,0x6E,0x60,0x18,0x2C,0x0C,0x20,0x22,
-      0x56,0x36,0x4F,0x6E,0x3F,0x80,0x00,0x80,
-      0x93,0x3C,0x01,0x50,0x2F,0x10,0xF4,0xCA,
-      0x01,0x05,0x03,0x7E,0x65,0x31,0x14,0x75,
-      0x18,0x05,0x18,0x05,0x4C,0xA8,0x01
+static unsigned char XGI330_HiTVGroup3Text[] = {
+	0x00, 0x1A, 0x22, 0x63, 0x62, 0x22, 0x08, 0xA7,
+	0xF5, 0x20, 0xCE, 0xCE, 0x55, 0x47, 0x2A, 0xA6,
+	0x25, 0x2F, 0x47, 0xFA, 0xC8, 0xFF, 0x8E, 0x20,
+	0x8C, 0x6E, 0x60, 0x18, 0x2C, 0x0C, 0x20, 0x22,
+	0x56, 0x36, 0x4F, 0x6E, 0x3F, 0x80, 0x00, 0x80,
+	0x93, 0x3C, 0x01, 0x50, 0x2F, 0x10, 0xF4, 0xCA,
+	0x01, 0x05, 0x03, 0x7E, 0x65, 0x31, 0x14, 0x75,
+	0x18, 0x05, 0x18, 0x05, 0x4C, 0xA8, 0x01
 };
 
-static unsigned char XGI330_Ren525pGroup3[] =
-{
-  0x00,0x14,0x15,0x25,0x55,0x15,0x0b,0x13,
-  0xB1,0x41,0x62,0x62,0xFF,0xF4,0x45,0xa6,
-  0x25,0x2F,0x67,0xF6,0xbf,0xFF,0x8E,0x20,
-  0xAC,0xDA,0x60,0xFe,0x6A,0x9A,0x06,0x10,
-  0xd1,0x04,0x18,0x0a,0xFF,0x80,0x00,0x80,
-  0x3c,0x77,0x00,0xEF,0xE0,0x10,0xB0,0xE0,
-  0x10,0x4F,0x0F,0x0F,0x05,0x0F,0x08,0x6E,
-  0x1a,0x1F,0x25,0x2a,0x4C,0xAA,0x01
+static unsigned char XGI330_Ren525pGroup3[] = {
+	0x00, 0x14, 0x15, 0x25, 0x55, 0x15, 0x0b, 0x13,
+	0xB1, 0x41, 0x62, 0x62, 0xFF, 0xF4, 0x45, 0xa6,
+	0x25, 0x2F, 0x67, 0xF6, 0xbf, 0xFF, 0x8E, 0x20,
+	0xAC, 0xDA, 0x60, 0xFe, 0x6A, 0x9A, 0x06, 0x10,
+	0xd1, 0x04, 0x18, 0x0a, 0xFF, 0x80, 0x00, 0x80,
+	0x3c, 0x77, 0x00, 0xEF, 0xE0, 0x10, 0xB0, 0xE0,
+	0x10, 0x4F, 0x0F, 0x0F, 0x05, 0x0F, 0x08, 0x6E,
+	0x1a, 0x1F, 0x25, 0x2a, 0x4C, 0xAA, 0x01
 };
 
-static unsigned char XGI330_Ren750pGroup3[] =
-{
-  0x00,0x14,0x15,0x25,0x55,0x15,0x0b,0x7a,
-  0x54,0x41,0xE7,0xE7,0xFF,0xF4,0x45,0xa6,
-  0x25,0x2F,0x67,0xF6,0xbf,0xFF,0x8E,0x20,
-  0xAC,0x6A,0x60,0x2b,0x52,0xCD,0x61,0x10,
-  0x51,0x04,0x18,0x0a,0x1F,0x80,0x00,0x80,
-  0xFF,0xA4,0x04,0x2B,0x94,0x21,0x72,0x94,
-  0x26,0x05,0x01,0x0F,0xed,0x0F,0x0A,0x64,
-  0x18,0x1D,0x23,0x28,0x4C,0xAA,0x01
+static unsigned char XGI330_Ren750pGroup3[] = {
+	0x00, 0x14, 0x15, 0x25, 0x55, 0x15, 0x0b, 0x7a,
+	0x54, 0x41, 0xE7, 0xE7, 0xFF, 0xF4, 0x45, 0xa6,
+	0x25, 0x2F, 0x67, 0xF6, 0xbf, 0xFF, 0x8E, 0x20,
+	0xAC, 0x6A, 0x60, 0x2b, 0x52, 0xCD, 0x61, 0x10,
+	0x51, 0x04, 0x18, 0x0a, 0x1F, 0x80, 0x00, 0x80,
+	0xFF, 0xA4, 0x04, 0x2B, 0x94, 0x21, 0x72, 0x94,
+	0x26, 0x05, 0x01, 0x0F, 0xed, 0x0F, 0x0A, 0x64,
+	0x18, 0x1D, 0x23, 0x28, 0x4C, 0xAA, 0x01
 };
 
 #if 0
-static struct XGI_PanelDelayTblStruct XGI330_PanelDelayTbl[] =
-{
-{{0x00,0x00}},
-{{0x00,0x00}},
-{{0x00,0x00}},
-{{0x00,0x00}},
-{{0x00,0x00}},
-{{0x00,0x00}},
-{{0x00,0x00}},
-{{0x00,0x00}},
-{{0x00,0x00}},
-{{0x00,0x00}},
-{{0x00,0x00}},
-{{0x00,0x00}},
-{{0x00,0x00}},
-{{0x00,0x00}},
-{{0x00,0x00}},
-{{0x00,0x00}}
+static struct XGI_PanelDelayTblStruct XGI330_PanelDelayTbl[] = {
+	{ {0x00, 0x00} },
+	{ {0x00, 0x00} },
+	{ {0x00, 0x00} },
+	{ {0x00, 0x00} },
+	{ {0x00, 0x00} },
+	{ {0x00, 0x00} },
+	{ {0x00, 0x00} },
+	{ {0x00, 0x00} },
+	{ {0x00, 0x00} },
+	{ {0x00, 0x00} },
+	{ {0x00, 0x00} },
+	{ {0x00, 0x00} },
+	{ {0x00, 0x00} },
+	{ {0x00, 0x00} },
+	{ {0x00, 0x00} },
+	{ {0x00, 0x00} }
 };
 
-static struct XGI330_LVDSDataStruct  XGI330_LVDS320x480Data_1[] =
-{
- {848, 433,400,525},
- {848, 389,400,525},
- {848, 433,400,525},
- {848, 389,400,525},
- {848, 518,400, 525},
- {1056, 628,400,525},
- {400, 525,400,525},
- {800, 449,1000, 644},
- {800, 525,1000, 635}
+static struct XGI330_LVDSDataStruct  XGI330_LVDS320x480Data_1[] = {
+	{848,  433, 400,  525},
+	{848,  389, 400,  525},
+	{848,  433, 400,  525},
+	{848,  389, 400,  525},
+	{848,  518, 400,  525},
+	{1056, 628, 400,  525},
+	{400,  525, 400,  525},
+	{800,  449, 1000, 644},
+	{800,  525, 1000, 635}
 };
 
-static struct XGI330_LVDSDataStruct  XGI330_LVDS800x600Data_1[] =
-{
- {848, 433,1060, 629},
- {848, 389,1060, 629},
- {848, 433,1060, 629},
- {848, 389,1060, 629},
- {848, 518,1060, 629},
- {1056, 628,1056, 628},
- {1056, 628,1056, 628},
- {800, 449,1000, 644},
- {800, 525,1000, 635}
+static struct XGI330_LVDSDataStruct  XGI330_LVDS800x600Data_1[] = {
+	{848,  433, 1060, 629},
+	{848,  389, 1060, 629},
+	{848,  433, 1060, 629},
+	{848,  389, 1060, 629},
+	{848,  518, 1060, 629},
+	{1056, 628, 1056, 628},
+	{1056, 628, 1056, 628},
+	{800,  449, 1000, 644},
+	{800,  525, 1000, 635}
 };
 
-static struct XGI330_LVDSDataStruct  XGI330_LVDS800x600Data_2[] =
-{
- {1056, 628,1056, 628},
- {1056, 628,1056, 628},
- {1056, 628,1056, 628},
- {1056, 628,1056, 628},
- {1056, 628,1056, 628},
- {1056, 628,1056, 628},
- {1056, 628,1056, 628},
- {800, 449,1000, 644},
- {800, 525,1000, 635}
+static struct XGI330_LVDSDataStruct  XGI330_LVDS800x600Data_2[] = {
+	{1056, 628, 1056, 628},
+	{1056, 628, 1056, 628},
+	{1056, 628, 1056, 628},
+	{1056, 628, 1056, 628},
+	{1056, 628, 1056, 628},
+	{1056, 628, 1056, 628},
+	{1056, 628, 1056, 628},
+	{800,  449, 1000, 644},
+	{800,  525, 1000, 635}
 };
 #endif
 
-static struct XGI330_LVDSDataStruct  XGI_LVDS1024x768Data_1[] =
-{
- { 960 , 438 , 1344 , 806 } ,	/* 00 (320x200,320x400,640x200,640x400) */
- { 960 , 388 , 1344 , 806 } ,	/* 01 (320x350,640x350) */
- { 1040, 438 , 1344 , 806 } ,	/* 02 (360x400,720x400) */
- { 1040, 388 , 1344 , 806 } ,	/* 03 (720x350) */
- { 960 , 518 , 1344 , 806 } ,	/* 04 (320x240,640x480) */
- {1120 , 638 , 1344 , 806 } ,	/* 05 (400x300,800x600) */
- {1344 , 806 , 1344 , 806 }	/* 06 (512x384,1024x768) */
+static struct XGI330_LVDSDataStruct  XGI_LVDS1024x768Data_1[] = {
+	{ 960, 438, 1344, 806},	/* 00 (320x200,320x400,640x200,640x400) */
+	{ 960, 388, 1344, 806},	/* 01 (320x350,640x350) */
+	{1040, 438, 1344, 806},	/* 02 (360x400,720x400) */
+	{1040, 388, 1344, 806},	/* 03 (720x350) */
+	{ 960, 518, 1344, 806},	/* 04 (320x240,640x480) */
+	{1120, 638, 1344, 806},	/* 05 (400x300,800x600) */
+	{1344, 806, 1344, 806}	/* 06 (512x384,1024x768) */
 };
 
 
-static struct XGI330_LVDSDataStruct  XGI_LVDS1024x768Data_2[] =
-{
- {1344, 806,1344, 806},
- {1344, 806,1344, 806},
- {1344, 806,1344, 806},
- {1344, 806,1344, 806},
- {1344, 806,1344, 806},
- {1344, 806,1344, 806},
- {1344, 806,1344, 806},
- {800, 449,1280, 801},
- {800, 525,1280, 813}
+static struct XGI330_LVDSDataStruct  XGI_LVDS1024x768Data_2[] = {
+	{1344, 806, 1344, 806},
+	{1344, 806, 1344, 806},
+	{1344, 806, 1344, 806},
+	{1344, 806, 1344, 806},
+	{1344, 806, 1344, 806},
+	{1344, 806, 1344, 806},
+	{1344, 806, 1344, 806},
+	{800,  449, 1280, 801},
+	{800,  525, 1280, 813}
 };
 
-static struct XGI330_LVDSDataStruct  XGI_LVDS1280x1024Data_1[] =
-{
- {1048, 442,1688, 1066},
- {1048, 392,1688, 1066},
- {1048, 442,1688, 1066},
- {1048, 392,1688, 1066},
- {1048, 522,1688, 1066},
- {1208, 642,1688, 1066},
- {1432, 810,1688, 1066},
- {1688, 1066,1688, 1066}
+static struct XGI330_LVDSDataStruct  XGI_LVDS1280x1024Data_1[] = {
+	{1048, 442,  1688, 1066},
+	{1048, 392,  1688, 1066},
+	{1048, 442,  1688, 1066},
+	{1048, 392,  1688, 1066},
+	{1048, 522,  1688, 1066},
+	{1208, 642,  1688, 1066},
+	{1432, 810,  1688, 1066},
+	{1688, 1066, 1688, 1066}
 };
 
-static struct XGI330_LVDSDataStruct  XGI_LVDS1280x1024Data_2[] =
-{
- {1344, 806,1344, 806},
- {1344, 806,1344, 806},
- {1344, 806,1344, 806},
- {1344, 806,1344, 806},
- {1344, 806,1344, 806},
- {1344, 806,1344, 806},
- {1344, 806,1344, 806},
- {800, 449,1280, 801},
- {800, 525,1280, 813}
+static struct XGI330_LVDSDataStruct  XGI_LVDS1280x1024Data_2[] = {
+	{1344, 806, 1344, 806},
+	{1344, 806, 1344, 806},
+	{1344, 806, 1344, 806},
+	{1344, 806, 1344, 806},
+	{1344, 806, 1344, 806},
+	{1344, 806, 1344, 806},
+	{1344, 806, 1344, 806},
+	{800,  449, 1280, 801},
+	{800,  525, 1280, 813}
 };
 /*
-struct XGI330_LVDSDataStruct  XGI_LVDS1280x768Data_1[] =
-{
- {768,438,1408,806},
- {768,388,1408,806},
- {768,438,1408,806},
- {768,388,1408,806},
- {768,518,1408,806},
- {928,638,1408,806},
- {1408,806,1408,806},
- {1408,806,1408,806},
- {1408,806,1408,806}
+struct XGI330_LVDSDataStruct  XGI_LVDS1280x768Data_1[] = {
+	{768,  438, 1408, 806},
+	{768,  388, 1408, 806},
+	{768,  438, 1408, 806},
+	{768,  388, 1408, 806},
+	{768,  518, 1408, 806},
+	{928,  638, 1408, 806},
+	{1408, 806, 1408, 806},
+	{1408, 806, 1408, 806},
+	{1408, 806, 1408, 806}
 };
 
-struct XGI330_LVDSDataStruct  XGI_LVDS1280x768Data_2[] =
-{
- {1408, 806,1408, 806},
- {1408, 806,1408, 806},
- {1408, 806,1408, 806},
- {1408, 806,1408, 806},
- {1408, 806,1408, 806},
- {1408, 806,1408, 806},
- {1408, 806,1408, 806},
- {1408, 806,1408, 806},
- {1408, 806,1408, 806}
+struct XGI330_LVDSDataStruct  XGI_LVDS1280x768Data_2[] = {
+	{1408, 806, 1408, 806},
+	{1408, 806, 1408, 806},
+	{1408, 806, 1408, 806},
+	{1408, 806, 1408, 806},
+	{1408, 806, 1408, 806},
+	{1408, 806, 1408, 806},
+	{1408, 806, 1408, 806},
+	{1408, 806, 1408, 806},
+	{1408, 806, 1408, 806}
 };
 
-struct XGI330_LVDSDataStruct  XGI_LVDS1280x768NData_1[] =
-{
- {704, 438,1344, 806},
- {704, 388,1344, 806},
- {704, 438,1344, 806},
- {704, 388,1344, 806},
- {704, 518,1344, 806},
- {864, 638,1344, 806},
- {1088, 806,1344, 806},
- {1344, 806,1344, 806},
- {1344, 806,1344, 806}
+struct XGI330_LVDSDataStruct  XGI_LVDS1280x768NData_1[] = {
+	{704,  438, 1344, 806},
+	{704,  388, 1344, 806},
+	{704,  438, 1344, 806},
+	{704,  388, 1344, 806},
+	{704,  518, 1344, 806},
+	{864,  638, 1344, 806},
+	{1088, 806, 1344, 806},
+	{1344, 806, 1344, 806},
+	{1344, 806, 1344, 806}
 };
 
-struct XGI330_LVDSDataStruct  XGI_LVDS1280x768NData_2[] =
-{
- {1344, 806,1344, 806},
- {1344, 806,1344, 806},
- {1344, 806,1344, 806},
- {1344, 806,1344, 806},
- {1344, 806,1344, 806},
- {1344, 806,1344, 806},
- {1344, 806,1344, 806},
- {1344, 806,1344, 806},
- {1344, 806,1344, 806}
+struct XGI330_LVDSDataStruct  XGI_LVDS1280x768NData_2[] = {
+	{1344, 806, 1344, 806},
+	{1344, 806, 1344, 806},
+	{1344, 806, 1344, 806},
+	{1344, 806, 1344, 806},
+	{1344, 806, 1344, 806},
+	{1344, 806, 1344, 806},
+	{1344, 806, 1344, 806},
+	{1344, 806, 1344, 806},
+	{1344, 806, 1344, 806}
 };
 
-struct XGI330_LVDSDataStruct  XGI_LVDS1280x768SData_1[] =
-{
- {1048,438,1688,806},
- {1048,388,1688,806},
- {1148,438,1688,806},
- {1148,388,1688,806},
- {1048,518,1688,806},
- {1208,638,1688,806},
- {1432,806,1688,806},
- {1688,806,1688,806},
- {1688,806,1688,806}
+struct XGI330_LVDSDataStruct  XGI_LVDS1280x768SData_1[] = {
+	{1048, 438, 1688, 806},
+	{1048, 388, 1688, 806},
+	{1148, 438, 1688, 806},
+	{1148, 388, 1688, 806},
+	{1048, 518, 1688, 806},
+	{1208, 638, 1688, 806},
+	{1432, 806, 1688, 806},
+	{1688, 806, 1688, 806},
+	{1688, 806, 1688, 806}
 };
 
-struct XGI330_LVDSDataStruct  XGI_LVDS1280x768SData_2[] =
-{
- {1688,806,1688,806},
- {1688,806,1688,806},
- {1688,806,1688,806},
- {1688,806,1688,806},
- {1688,806,1688,806},
- {1688,806,1688,806},
- {1688,806,1688,806},
- {1688,806,1688,806},
- {1688,806,1688,806}
+struct XGI330_LVDSDataStruct  XGI_LVDS1280x768SData_2[] = {
+	{1688, 806, 1688, 806},
+	{1688, 806, 1688, 806},
+	{1688, 806, 1688, 806},
+	{1688, 806, 1688, 806},
+	{1688, 806, 1688, 806},
+	{1688, 806, 1688, 806},
+	{1688, 806, 1688, 806},
+	{1688, 806, 1688, 806},
+	{1688, 806, 1688, 806}
 };
 */
-static struct XGI330_LVDSDataStruct  XGI_LVDS1400x1050Data_1[] =
-{
- {928,416,1688,1066},
- {928,366,1688,1066},
- {928,416,1688,1066},
- {928,366,1688,1066},
- {928,496,1688,1066},
- {1088,616,1688,1066},
- {1312,784,1688,1066},
- {1568,1040,1688,1066},
- {1688,1066,1688,1066}
+static struct XGI330_LVDSDataStruct  XGI_LVDS1400x1050Data_1[] = {
+	{928,   416, 1688, 1066},
+	{928,   366, 1688, 1066},
+	{928,   416, 1688, 1066},
+	{928,   366, 1688, 1066},
+	{928,   496, 1688, 1066},
+	{1088,  616, 1688, 1066},
+	{1312,  784, 1688, 1066},
+	{1568, 1040, 1688, 1066},
+	{1688, 1066, 1688, 1066}
 };
 
-static struct XGI330_LVDSDataStruct  XGI_LVDS1400x1050Data_2[] =
-{
- {1688,1066,1688,1066},
- {1688,1066,1688,1066},
- {1688,1066,1688,1066},
- {1688,1066,1688,1066},
- {1688,1066,1688,1066},
- {1688,1066,1688,1066},
- {1688,1066,1688,1066},
- {1688,1066,1688,1066},
- {1688,1066,1688,1066}
+static struct XGI330_LVDSDataStruct  XGI_LVDS1400x1050Data_2[] = {
+	{1688, 1066, 1688, 1066},
+	{1688, 1066, 1688, 1066},
+	{1688, 1066, 1688, 1066},
+	{1688, 1066, 1688, 1066},
+	{1688, 1066, 1688, 1066},
+	{1688, 1066, 1688, 1066},
+	{1688, 1066, 1688, 1066},
+	{1688, 1066, 1688, 1066},
+	{1688, 1066, 1688, 1066}
 };
 
-static struct XGI330_LVDSDataStruct XGI_LVDS1600x1200Data_1[] =
-{      /* ;;[ycchen] 12/05/02 LCDHTxLCDVT=2048x1320 */
-        {        1088,520,2048,1320      },/* 00 (320x200,320x400,640x200,640x400) */
-        {        1088,470,2048,1320      },/* 01 (320x350,640x350) */
-        {        1088,520,2048,1320      },/* 02 (360x400,720x400) */
-        {        1088,470,2048,1320      },/* 03 (720x350) */
-        {        1088,600,2048,1320      },/* 04 (320x240,640x480) */
-        {        1248,720,2048,1320      },/* 05 (400x300,800x600) */
-        {        1472,888,2048,1320      },/* 06 (512x384,1024x768) */
-        {        1728,1144,2048,1320     },/* 07 (640x512,1280x1024) */
-        {        1848,1170,2048,1320     },/* 08 (1400x1050) */
-        {        2048,1320,2048,1320     } /* 09 (1600x1200) */
+/* ;;[ycchen] 12/05/02 LCDHTxLCDVT=2048x1320 */
+static struct XGI330_LVDSDataStruct XGI_LVDS1600x1200Data_1[] = {
+	{1088, 520,  2048, 1320}, /* 00 (320x200,320x400,640x200,640x400) */
+	{1088, 470,  2048, 1320}, /* 01 (320x350,640x350) */
+	{1088, 520,  2048, 1320}, /* 02 (360x400,720x400) */
+	{1088, 470,  2048, 1320}, /* 03 (720x350) */
+	{1088, 600,  2048, 1320}, /* 04 (320x240,640x480) */
+	{1248, 720,  2048, 1320}, /* 05 (400x300,800x600) */
+	{1472, 888,  2048, 1320}, /* 06 (512x384,1024x768) */
+	{1728, 1144, 2048, 1320}, /* 07 (640x512,1280x1024) */
+	{1848, 1170, 2048, 1320}, /* 08 (1400x1050) */
+	{2048, 1320, 2048, 1320}  /* 09 (1600x1200) */
 };
 
-static struct XGI330_LVDSDataStruct XGI_LVDSNoScalingData[] =
-{
-        {        800,449,800,449             }, /* 00 (320x200,320x400,640x200,640x400) */
-        {        800,449,800,449             }, /* 01 (320x350,640x350) */
-        {        800,449,800,449             }, /* 02 (360x400,720x400) */
-        {        800,449,800,449             }, /* 03 (720x350) */
-        {        800,525,800,525             }, /* 04 (640x480x60Hz) */
-        {        1056,628,1056,628           }, /* 05 (800x600x60Hz) */
-        {        1344,806,1344,806           }, /* 06 (1024x768x60Hz) */
-        {        1688,1066,1688,1066         }, /* 07 (1280x1024x60Hz) */
-        {        1688,1066,1688,1066         }, /* 08 (1400x1050x60Hz) ;;[ycchen] 12/19/02 */
-        {        2160,1250,2160,1250         }, /* 09 (1600x1200x60Hz) */
-        {        1688,806,1688,806           }  /* 0A (1280x768x60Hz) */
+static struct XGI330_LVDSDataStruct XGI_LVDSNoScalingData[] = {
+	{ 800,  449,  800,  449}, /* 00 (320x200,320x400,640x200,640x400) */
+	{ 800,  449,  800,  449}, /* 01 (320x350,640x350) */
+	{ 800,  449,  800,  449}, /* 02 (360x400,720x400) */
+	{ 800,  449,  800,  449}, /* 03 (720x350) */
+	{ 800,  525,  800,  525}, /* 04 (640x480x60Hz) */
+	{1056,  628, 1056,  628}, /* 05 (800x600x60Hz) */
+	{1344,  806, 1344,  806}, /* 06 (1024x768x60Hz) */
+	{1688, 1066, 1688, 1066}, /* 07 (1280x1024x60Hz) */
+	{1688, 1066, 1688, 1066}, /* 08 (1400x1050x60Hz) ;;[ycchen] 12/19/02 */
+	{2160, 1250, 2160, 1250}, /* 09 (1600x1200x60Hz) */
+	{1688,  806, 1688,  806}  /* 0A (1280x768x60Hz) */
 };
 
-static struct XGI330_LVDSDataStruct XGI_LVDS1024x768Data_1x75[] =
-{
-	{960,438,1312,800  }, /* 00 (320x200,320x400,640x200,640x400) */
-        {960,388,1312,800  }, /* 01 (320x350,640x350) */
-        {1040,438,1312,800 }, /* 02 (360x400,720x400) */
-        {1040,388,1312,800 }, /* 03 (720x350) */
-        {928,512,1312,800  }, /* 04 (320x240,640x480) */
-        {1088,632,1312,800 }, /* 05 (400x300,800x600) */
-        {1312,800,1312,800 }, /* 06 (512x384,1024x768) */
+static struct XGI330_LVDSDataStruct XGI_LVDS1024x768Data_1x75[] = {
+	{ 960, 438, 1312, 800}, /* 00 (320x200,320x400,640x200,640x400) */
+	{ 960, 388, 1312, 800}, /* 01 (320x350,640x350) */
+	{1040, 438, 1312, 800}, /* 02 (360x400,720x400) */
+	{1040, 388, 1312, 800}, /* 03 (720x350) */
+	{ 928, 512, 1312, 800}, /* 04 (320x240,640x480) */
+	{1088, 632, 1312, 800}, /* 05 (400x300,800x600) */
+	{1312, 800, 1312, 800}, /* 06 (512x384,1024x768) */
 };
 
 
-static struct XGI330_LVDSDataStruct XGI_LVDS1024x768Data_2x75[] =
-{
-        {1312,800,1312,800}, /* ; 00 (320x200,320x400,640x200,640x400) */
-        {1312,800,1312,800}, /* ; 01 (320x350,640x350) */
-        {1312,800,1312,800}, /* ; 02 (360x400,720x400) */
-        {1312,800,1312,800}, /* ; 03 (720x350) */
-        {1312,800,1312,800}, /* ; 04 (320x240,640x480) */
-        {1312,800,1312,800}, /* ; 05 (400x300,800x600) */
-        {1312,800,1312,800}, /* ; 06 (512x384,1024x768) */
+static struct XGI330_LVDSDataStruct XGI_LVDS1024x768Data_2x75[] = {
+	{1312, 800, 1312, 800}, /* ; 00 (320x200,320x400,640x200,640x400) */
+	{1312, 800, 1312, 800}, /* ; 01 (320x350,640x350) */
+	{1312, 800, 1312, 800}, /* ; 02 (360x400,720x400) */
+	{1312, 800, 1312, 800}, /* ; 03 (720x350) */
+	{1312, 800, 1312, 800}, /* ; 04 (320x240,640x480) */
+	{1312, 800, 1312, 800}, /* ; 05 (400x300,800x600) */
+	{1312, 800, 1312, 800}, /* ; 06 (512x384,1024x768) */
 };
 
-static struct XGI330_LVDSDataStruct XGI_LVDS1280x1024Data_1x75[] =
-{
-        {1048,442,1688,1066  }, /* ; 00 (320x200,320x400,640x200,640x400) */
-        {1048,392,1688,1066  }, /* ; 01 (320x350,640x350) */
-        {1128,442,1688,1066  }, /* ; 02 (360x400,720x400) */
-        {1128,392,1688,1066  }, /* ; 03 (720x350) */
-        {1048,522,1688,1066  }, /* ; 04 (320x240,640x480) */
-        {1208,642,1688,1066  }, /* ; 05 (400x300,800x600) */
-        {1432,810,1688,1066  }, /* ; 06 (512x384,1024x768) */
-        {1688,1066,1688,1066 }, /* ; 06; 07 (640x512,1280x1024) */
+static struct XGI330_LVDSDataStruct XGI_LVDS1280x1024Data_1x75[] = {
+	{1048,  442, 1688, 1066  }, /* ; 00 (320x200,320x400,640x200,640x400) */
+	{1048,  392, 1688, 1066  }, /* ; 01 (320x350,640x350) */
+	{1128,  442, 1688, 1066  }, /* ; 02 (360x400,720x400) */
+	{1128,  392, 1688, 1066  }, /* ; 03 (720x350) */
+	{1048,  522, 1688, 1066  }, /* ; 04 (320x240,640x480) */
+	{1208,  642, 1688, 1066  }, /* ; 05 (400x300,800x600) */
+	{1432,  810, 1688, 1066  }, /* ; 06 (512x384,1024x768) */
+	{1688, 1066, 1688, 1066 },  /* ; 06; 07 (640x512,1280x1024) */
 };
 
-static struct XGI330_LVDSDataStruct XGI_LVDS1280x1024Data_2x75[] =
-{
-        {1688,1066,1688,1066 }, /* ; 00 (320x200,320x400,640x200,640x400) */
-        {1688,1066,1688,1066 }, /* ; 01 (320x350,640x350) */
-        {1688,1066,1688,1066 }, /* ; 02 (360x400,720x400) */
-        {1688,1066,1688,1066 }, /* ; 03 (720x350) */
-        {1688,1066,1688,1066 }, /* ; 04 (320x240,640x480) */
-        {1688,1066,1688,1066 }, /* ; 05 (400x300,800x600) */
-        {1688,1066,1688,1066 }, /* ; 06 (512x384,1024x768) */
-        {1688,1066,1688,1066 }, /* ; 06; 07 (640x512,1280x1024) */
+static struct XGI330_LVDSDataStruct XGI_LVDS1280x1024Data_2x75[] = {
+	{1688, 1066, 1688, 1066 }, /* ; 00 (320x200,320x400,640x200,640x400) */
+	{1688, 1066, 1688, 1066 }, /* ; 01 (320x350,640x350) */
+	{1688, 1066, 1688, 1066 }, /* ; 02 (360x400,720x400) */
+	{1688, 1066, 1688, 1066 }, /* ; 03 (720x350) */
+	{1688, 1066, 1688, 1066 }, /* ; 04 (320x240,640x480) */
+	{1688, 1066, 1688, 1066 }, /* ; 05 (400x300,800x600) */
+	{1688, 1066, 1688, 1066 }, /* ; 06 (512x384,1024x768) */
+	{1688, 1066, 1688, 1066 }, /* ; 06; 07 (640x512,1280x1024) */
 };
 
-static struct XGI330_LVDSDataStruct XGI_LVDSNoScalingDatax75[] =
-{
-        {800,449,800,449     }, /* ; 00 (320x200,320x400,640x200,640x400) */
-        {800,449,800,449     }, /* ; 01 (320x350,640x350) */
-        {900,449,900,449     }, /* ; 02 (360x400,720x400) */
-        {900,449,900,449     }, /* ; 03 (720x350) */
-        {800,500,800,500     }, /* ; 04 (640x480x75Hz) */
-        {1056,625,1056,625   }, /* ; 05 (800x600x75Hz) */
-        {1312,800,1312,800   }, /* ; 06 (1024x768x75Hz) */
-        {1688,1066,1688,1066 }, /* ; 07 (1280x1024x75Hz) */
-        {1688,1066,1688,1066 }, /* ; 08 (1400x1050x75Hz) ;;[ycchen] 12/19/02 */
-        {2160,1250,2160,1250 }, /* ; 09 (1600x1200x75Hz) */
-        {1688,806,1688,806   }, /* ; 0A (1280x768x75Hz) */
+static struct XGI330_LVDSDataStruct XGI_LVDSNoScalingDatax75[] = {
+	{ 800,  449,  800, 449},  /* ; 00 (320x200,320x400,640x200,640x400) */
+	{ 800,  449,  800, 449},  /* ; 01 (320x350,640x350) */
+	{ 900,  449,  900, 449},  /* ; 02 (360x400,720x400) */
+	{ 900,  449,  900, 449},  /* ; 03 (720x350) */
+	{ 800,  500,  800, 500},  /* ; 04 (640x480x75Hz) */
+	{1056,  625, 1056, 625},  /* ; 05 (800x600x75Hz) */
+	{1312,  800, 1312, 800},  /* ; 06 (1024x768x75Hz) */
+	{1688, 1066, 1688, 1066}, /* ; 07 (1280x1024x75Hz) */
+	{1688, 1066, 1688, 1066}, /* ; 08 (1400x1050x75Hz)
+				     ;;[ycchen] 12/19/02 */
+	{2160, 1250, 2160, 1250}, /* ; 09 (1600x1200x75Hz) */
+	{1688,  806, 1688, 806},  /* ; 0A (1280x768x75Hz) */
 };
 
-static struct XGI330_LVDSDataStruct XGI_LVDS1024x768Des_1[] =
-{
-	{      0,1048,   0, 771     }, /* 00 (320x200,320x400,640x200,640x400) */
-        {      0,1048,   0, 771     }, /* 01 (320x350,640x350) */
-        {      0,1048,   0, 771     }, /* 02 (360x400,720x400) */
-        {      0,1048,   0, 771     }, /* 03 (720x350) */
-        {      0,1048,   0, 771     }, /* 04 (640x480x60Hz) */
-        {      0,1048,   0, 771     }, /* 05 (800x600x60Hz) */
-        {      0,1048, 805, 770     }  /* 06 (1024x768x60Hz) */
+static struct XGI330_LVDSDataStruct XGI_LVDS1024x768Des_1[] = {
+	{0, 1048,   0, 771}, /* 00 (320x200,320x400,640x200,640x400) */
+	{0, 1048,   0, 771}, /* 01 (320x350,640x350) */
+	{0, 1048,   0, 771}, /* 02 (360x400,720x400) */
+	{0, 1048,   0, 771}, /* 03 (720x350) */
+	{0, 1048,   0, 771}, /* 04 (640x480x60Hz) */
+	{0, 1048,   0, 771}, /* 05 (800x600x60Hz) */
+	{0, 1048, 805, 770}  /* 06 (1024x768x60Hz) */
 } ;
 
-static struct XGI330_LVDSDataStruct XGI_LVDS1024x768Des_2[] =
-{
-    	{      1142, 856, 622, 587     }, /* 00 (320x200,320x400,640x200,640x400) */
-        {      1142, 856, 597, 562     }, /* 01 (320x350,640x350) */
-        {      1142, 856, 622, 587     }, /* 02 (360x400,720x400) */
-        {      1142, 856, 597, 562     }, /* 03 (720x350) */
-        {      1142,1048, 722, 687     }, /* 04 (640x480x60Hz) */
-        {      1232, 936, 722, 687     }, /* 05 (800x600x60Hz) */
-        {         0,1048, 805, 771     }  /* 06 (1024x768x60Hz) */
+static struct XGI330_LVDSDataStruct XGI_LVDS1024x768Des_2[] = {
+	{1142,  856, 622, 587}, /* 00 (320x200,320x400,640x200,640x400) */
+	{1142,  856, 597, 562}, /* 01 (320x350,640x350) */
+	{1142,  856, 622, 587}, /* 02 (360x400,720x400) */
+	{1142,  856, 597, 562}, /* 03 (720x350) */
+	{1142, 1048, 722, 687}, /* 04 (640x480x60Hz) */
+	{1232,  936, 722, 687}, /* 05 (800x600x60Hz) */
+	{   0, 1048, 805, 771}  /* 06 (1024x768x60Hz) */
 };
 
-static struct XGI330_LVDSDataStruct XGI_LVDS1024x768Des_3[] =
-{
-    	{       320,  24, 622, 587     }, /* 00 (320x200,320x400,640x200,640x400) */
-        {       320,  24, 597, 562     }, /* 01 (320x350,640x350) */
-        {       320,  24, 622, 587     }, /* 02 (360x400,720x400) */
-        {       320,  24, 597, 562     }, /* 03 (720x350) */
-        {       320,  24, 722, 687     }  /* 04 (640x480x60Hz) */
+static struct XGI330_LVDSDataStruct XGI_LVDS1024x768Des_3[] = {
+	{320, 24, 622, 587}, /* 00 (320x200,320x400,640x200,640x400) */
+	{320, 24, 597, 562}, /* 01 (320x350,640x350) */
+	{320, 24, 622, 587}, /* 02 (360x400,720x400) */
+	{320, 24, 597, 562}, /* 03 (720x350) */
+	{320, 24, 722, 687}  /* 04 (640x480x60Hz) */
 };
 
-static struct XGI330_LVDSDataStruct XGI_LVDS1280x1024Des_1[] =
-{
-    	{      0,1328,    0, 1025     }, /* 00 (320x200,320x400,640x200,640x400) */
-        {      0,1328,    0, 1025     }, /* 01 (320x350,640x350) */
-        {      0,1328,    0, 1025     }, /* 02 (360x400,720x400) */
-        {      0,1328,    0, 1025     }, /* 03 (720x350) */
-        {      0,1328,    0, 1025     }, /* 04 (640x480x60Hz) */
-        {      0,1328,    0, 1025     }, /* 05 (800x600x60Hz) */
-        {      0,1328,    0, 1025     }, /* 06 (1024x768x60Hz) */
-        {      0,1328, 1065, 1024     }  /* 07 (1280x1024x60Hz) */
+static struct XGI330_LVDSDataStruct XGI_LVDS1280x1024Des_1[] = {
+	{0, 1328,    0, 1025}, /* 00 (320x200,320x400,640x200,640x400) */
+	{0, 1328,    0, 1025}, /* 01 (320x350,640x350) */
+	{0, 1328,    0, 1025}, /* 02 (360x400,720x400) */
+	{0, 1328,    0, 1025}, /* 03 (720x350) */
+	{0, 1328,    0, 1025}, /* 04 (640x480x60Hz) */
+	{0, 1328,    0, 1025}, /* 05 (800x600x60Hz) */
+	{0, 1328,    0, 1025}, /* 06 (1024x768x60Hz) */
+	{0, 1328, 1065, 1024}  /* 07 (1280x1024x60Hz) */
 };
 
  /* The Display setting for DE Mode Panel */
-static struct XGI330_LVDSDataStruct XGI_LVDS1280x1024Des_2[] =
-{
-    	{      1368,1008,752,711     }, /* 00 (320x200,320x400,640x200,640x400) */
-        {      1368,1008,729,688     }, /* 01 (320x350,640x350) */
-        {      1408,1048,752,711     }, /* 02 (360x400,720x400) */
-        {      1408,1048,729,688     }, /* 03 (720x350) */
-        {      1368,1008,794,753     }, /* 04 (640x480x60Hz) */
-        {      1448,1068,854,813     }, /* 05 (800x600x60Hz) */
-        {      1560,1200,938,897     }, /* 06 (1024x768x60Hz) */
-        {      0000,1328,0,1025     }  /* 07 (1280x1024x60Hz) */
+static struct XGI330_LVDSDataStruct XGI_LVDS1280x1024Des_2[] = {
+	{1368, 1008, 752, 711}, /* 00 (320x200,320x400,640x200,640x400) */
+	{1368, 1008, 729, 688}, /* 01 (320x350,640x350) */
+	{1408, 1048, 752, 711}, /* 02 (360x400,720x400) */
+	{1408, 1048, 729, 688}, /* 03 (720x350) */
+	{1368, 1008, 794, 753}, /* 04 (640x480x60Hz) */
+	{1448, 1068, 854, 813}, /* 05 (800x600x60Hz) */
+	{1560, 1200, 938, 897}, /* 06 (1024x768x60Hz) */
+	{0000, 1328,   0, 1025} /* 07 (1280x1024x60Hz) */
 };
 
-static struct XGI330_LVDSDataStruct XGI_LVDS1400x1050Des_1[] =
-{
-    	{      0,1448,0,1051     }, /* 00 (320x200,320x400,640x200,640x400) */
-        {      0,1448,0,1051     }, /* 01 (320x350,640x350) */
-        {      0,1448,0,1051     }, /* 02 (360x400,720x400) */
-        {      0,1448,0,1051     }, /* 03 (720x350) */
-        {      0,1448,0,1051     }, /* 04 (640x480x60Hz) */
-        {      0,1448,0,1051     }, /* 05 (800x600x60Hz) */
-        {      0,1448,0,1051     }, /* 06 (1024x768x60Hz) */
-        {      0,1448,0,1051     }, /* 07 (1280x1024x60Hz) */
-        {      0,1448,0,1051     }  /* 08 (1400x1050x60Hz) */
+static struct XGI330_LVDSDataStruct XGI_LVDS1400x1050Des_1[] = {
+	{0, 1448, 0, 1051}, /* 00 (320x200,320x400,640x200,640x400) */
+	{0, 1448, 0, 1051}, /* 01 (320x350,640x350) */
+	{0, 1448, 0, 1051}, /* 02 (360x400,720x400) */
+	{0, 1448, 0, 1051}, /* 03 (720x350) */
+	{0, 1448, 0, 1051}, /* 04 (640x480x60Hz) */
+	{0, 1448, 0, 1051}, /* 05 (800x600x60Hz) */
+	{0, 1448, 0, 1051}, /* 06 (1024x768x60Hz) */
+	{0, 1448, 0, 1051}, /* 07 (1280x1024x60Hz) */
+	{0, 1448, 0, 1051}  /* 08 (1400x1050x60Hz) */
 };
 
-static struct XGI330_LVDSDataStruct XGI_LVDS1400x1050Des_2[] =
-{
-    	{      1308,1068, 781, 766     }, /* 00 (320x200,320x400,640x200,640x400) */
-        {      1308,1068, 781, 766     }, /* 01 (320x350,640x350) */
-        {      1308,1068, 781, 766     }, /* 02 (360x400,720x400) */
-        {      1308,1068, 781, 766     }, /* 03 (720x350) */
-        {      1308,1068, 781, 766     }, /* 04 (640x480x60Hz) */
-        {      1388,1148, 841, 826     }, /* 05 (800x600x60Hz) */
-        {      1490,1250, 925, 910     }, /* 06 (1024x768x60Hz) */
-        {      1608,1368,1053,1038     }, /* 07 (1280x1024x60Hz) */
-        {      0,1448,0,1051     }  /* 08 (1400x1050x60Hz) */
+static struct XGI330_LVDSDataStruct XGI_LVDS1400x1050Des_2[] = {
+	{1308, 1068,  781,  766}, /* 00 (320x200,320x400,640x200,640x400) */
+	{1308, 1068,  781,  766}, /* 01 (320x350,640x350) */
+	{1308, 1068,  781,  766}, /* 02 (360x400,720x400) */
+	{1308, 1068,  781,  766}, /* 03 (720x350) */
+	{1308, 1068,  781,  766}, /* 04 (640x480x60Hz) */
+	{1388, 1148,  841,  826}, /* 05 (800x600x60Hz) */
+	{1490, 1250,  925,  910}, /* 06 (1024x768x60Hz) */
+	{1608, 1368, 1053, 1038}, /* 07 (1280x1024x60Hz) */
+	{   0, 1448,    0, 1051}  /* 08 (1400x1050x60Hz) */
 };
 
-static struct XGI330_LVDSDataStruct XGI_LVDS1600x1200Des_1[] =
-{
-    	{      0,1664,0,1201     }, /* 00 (320x200,320x400,640x200,640x400) */
-        {      0,1664,0,1201     }, /* 01 (320x350,640x350) */
-        {      0,1664,0,1201     }, /* 02 (360x400,720x400) */
-        {      0,1664,0,1201     }, /* 03 (720x350) */
-        {      0,1664,0,1201     }, /* 04 (640x480x60Hz) */
-        {      0,1664,0,1201     }, /* 05 (800x600x60Hz) */
-        {      0,1664,0,1201     }, /* 06 (1024x768x60Hz) */
-        {      0,1664,0,1201     }, /* 07 (1280x1024x60Hz) */
-        {      0,1664,0,1201     }, /* 08 (1400x1050x60Hz) */
-        {      0,1664,0,1201     }  /* 09 (1600x1200x60Hz) */
+static struct XGI330_LVDSDataStruct XGI_LVDS1600x1200Des_1[] = {
+	{0, 1664, 0, 1201}, /* 00 (320x200,320x400,640x200,640x400) */
+	{0, 1664, 0, 1201}, /* 01 (320x350,640x350) */
+	{0, 1664, 0, 1201}, /* 02 (360x400,720x400) */
+	{0, 1664, 0, 1201}, /* 03 (720x350) */
+	{0, 1664, 0, 1201}, /* 04 (640x480x60Hz) */
+	{0, 1664, 0, 1201}, /* 05 (800x600x60Hz) */
+	{0, 1664, 0, 1201}, /* 06 (1024x768x60Hz) */
+	{0, 1664, 0, 1201}, /* 07 (1280x1024x60Hz) */
+	{0, 1664, 0, 1201}, /* 08 (1400x1050x60Hz) */
+	{0, 1664, 0, 1201}  /* 09 (1600x1200x60Hz) */
 };
 
-
-
-static struct XGI330_LCDDataDesStruct2  XGI_LVDSNoScalingDesData[] =
-{
-    	{     0, 648, 448, 405,  96,   2   }, /* 00 (320x200,320x400,640x200,640x400) */
-        {     0, 648, 448, 355,  96,   2   }, /* 01 (320x350,640x350) */
-        {     0, 648, 448, 405,  96,   2   }, /* 02 (360x400,720x400) */
-        {     0, 648, 448, 355,  96,   2   }, /* 03 (720x350) */
-        {     0, 648,  1, 483,  96,   2   }, /* 04 (640x480x60Hz) */
-        {     0, 840, 627, 600, 128,   4   }, /* 05 (800x600x60Hz) */
-        {     0,1048, 805, 770, 136,   6   }, /* 06 (1024x768x60Hz) */
-        {     0,1328,0,1025, 112,   3   }, /* 07 (1280x1024x60Hz) */
-        {     0,1438,0,1051, 112,   3   }, /* 08 (1400x1050x60Hz) ;;[ycchen] 12/19/02 */
-        {     0,1664,0,1201, 192,   3   }, /* 09 (1600x1200x60Hz) */
-        {     0,1328,0,0771, 112,   6   }  /* 0A (1280x768x60Hz) */
+static struct XGI330_LCDDataDesStruct2  XGI_LVDSNoScalingDesData[] = {
+	{0,  648,  448,  405,  96, 2}, /* 00 (320x200,320x400,
+					      640x200,640x400) */
+	{0,  648,  448,  355,  96, 2}, /* 01 (320x350,640x350) */
+	{0,  648,  448,  405,  96, 2}, /* 02 (360x400,720x400) */
+	{0,  648,  448,  355,  96, 2}, /* 03 (720x350) */
+	{0,  648,    1,  483,  96, 2}, /* 04 (640x480x60Hz) */
+	{0,  840,  627,  600, 128, 4}, /* 05 (800x600x60Hz) */
+	{0, 1048,  805,  770, 136, 6}, /* 06 (1024x768x60Hz) */
+	{0, 1328,    0, 1025, 112, 3}, /* 07 (1280x1024x60Hz) */
+	{0, 1438,    0, 1051, 112, 3}, /* 08 (1400x1050x60Hz)
+					;;[ycchen] 12/19/02 */
+	{0, 1664,    0, 1201, 192, 3}, /* 09 (1600x1200x60Hz) */
+	{0, 1328,    0, 0771, 112, 6}  /* 0A (1280x768x60Hz) */
 };
 
-static struct XGI330_LVDSDataStruct XGI_LVDS1024x768Des_1x75[] =			/* ; 1024x768 Full-screen */
-{
-        {0,1040,0,769}, /* ; 00 (320x200,320x400,640x200,640x400) */
-        {0,1040,0,769}, /* ; 01 (320x350,640x350) */
-        {0,1040,0,769}, /* ; 02 (360x400,720x400) */
-        {0,1040,0,769}, /* ; 03 (720x350) */
-        {0,1040,0,769}, /* ; 04 (640x480x75Hz) */
-        {0,1040,0,769}, /* ; 05 (800x600x75Hz) */
-        {0,1040,0,769} /* ; 06 (1024x768x75Hz) */
+/* ; 1024x768 Full-screen */
+static struct XGI330_LVDSDataStruct XGI_LVDS1024x768Des_1x75[] = {
+	{0, 1040, 0, 769}, /* ; 00 (320x200,320x400,640x200,640x400) */
+	{0, 1040, 0, 769}, /* ; 01 (320x350,640x350) */
+	{0, 1040, 0, 769}, /* ; 02 (360x400,720x400) */
+	{0, 1040, 0, 769}, /* ; 03 (720x350) */
+	{0, 1040, 0, 769}, /* ; 04 (640x480x75Hz) */
+	{0, 1040, 0, 769}, /* ; 05 (800x600x75Hz) */
+	{0, 1040, 0, 769}  /* ; 06 (1024x768x75Hz) */
 };
 
-static struct XGI330_LVDSDataStruct XGI_LVDS1024x768Des_2x75[] = /* ; 1024x768 center-screen (Enh. Mode) */
-{
-        {1142, 856,622,587 }, /* 00 (320x200,320x400,640x200,640x400) */
-        {1142, 856,597,562 }, /* 01 (320x350,640x350) */
-        {1142, 856,622,587 }, /* 02 (360x400,720x400) */
-        {1142, 856,597,562 }, /* 03 (720x350) */
-        {1142,1048,722,687 }, /* 04 (640x480x60Hz) */
-        {1232, 936,722,687 }, /* 05 (800x600x60Hz) */
-        {   0,1048,805,771 }  /* 06 (1024x768x60Hz) */
+/* ; 1024x768 center-screen (Enh. Mode) */
+static struct XGI330_LVDSDataStruct XGI_LVDS1024x768Des_2x75[] = {
+	{1142,  856, 622, 587}, /* 00 (320x200,320x400,640x200,640x400) */
+	{1142,  856, 597, 562}, /* 01 (320x350,640x350) */
+	{1142,  856, 622, 587}, /* 02 (360x400,720x400) */
+	{1142,  856, 597, 562}, /* 03 (720x350) */
+	{1142, 1048, 722, 687}, /* 04 (640x480x60Hz) */
+	{1232,  936, 722, 687}, /* 05 (800x600x60Hz) */
+	{   0, 1048, 805, 771}  /* 06 (1024x768x60Hz) */
 };
 
-static struct XGI330_LVDSDataStruct XGI_LVDS1024x768Des_3x75[] = /* ; 1024x768 center-screen (St.Mode) */
-{
-        {320,24,622,587  }, /* ; 00 (320x200,320x400,640x200,640x400) */
-        {320,24,597,562  }, /* ; 01 (320x350,640x350) */
-        {320,24,622,587  }, /* ; 02 (360x400,720x400) */
-        {320,24,597,562  }, /* ; 03 (720x350) */
-        {320,24,722,687  } /* ; 04 (640x480x60Hz) */
+/* ; 1024x768 center-screen (St.Mode) */
+static struct XGI330_LVDSDataStruct XGI_LVDS1024x768Des_3x75[] =  {
+	{320, 24, 622, 587}, /* ; 00 (320x200,320x400,640x200,640x400) */
+	{320, 24, 597, 562}, /* ; 01 (320x350,640x350) */
+	{320, 24, 622, 587}, /* ; 02 (360x400,720x400) */
+	{320, 24, 597, 562}, /* ; 03 (720x350) */
+	{320, 24, 722, 687}  /* ; 04 (640x480x60Hz) */
 };
 
-static struct XGI330_LVDSDataStruct XGI_LVDS1280x1024Des_1x75[] =
-{
-        {0,1296,0,1025}, /* ; 00 (320x200,320x400,640x200,640x400) */
-        {0,1296,0,1025}, /* ; 01 (320x350,640x350) */
-        {0,1296,0,1025}, /* ; 02 (360x400,720x400) */
-        {0,1296,0,1025}, /* ; 03 (720x350) */
-        {0,1296,0,1025}, /* ; 04 (640x480x75Hz) */
-        {0,1296,0,1025}, /* ; 05 (800x600x75Hz) */
-        {0,1296,0,1025}, /* ; 06 (1024x768x75Hz) */
-        {0,1296,0,1025} /* ; 07 (1280x1024x75Hz) */
+static struct XGI330_LVDSDataStruct XGI_LVDS1280x1024Des_1x75[] = {
+	{0, 1296, 0, 1025}, /* ; 00 (320x200,320x400,640x200,640x400) */
+	{0, 1296, 0, 1025}, /* ; 01 (320x350,640x350) */
+	{0, 1296, 0, 1025}, /* ; 02 (360x400,720x400) */
+	{0, 1296, 0, 1025}, /* ; 03 (720x350) */
+	{0, 1296, 0, 1025}, /* ; 04 (640x480x75Hz) */
+	{0, 1296, 0, 1025}, /* ; 05 (800x600x75Hz) */
+	{0, 1296, 0, 1025}, /* ; 06 (1024x768x75Hz) */
+	{0, 1296, 0, 1025}  /* ; 07 (1280x1024x75Hz) */
 };
 
 /* The Display setting for DE Mode Panel */
-static struct XGI330_LVDSDataStruct XGI_LVDS1280x1024Des_2x75[] =   /* [ycchen] 02/18/03 Set DE as default */
-{
-        {1368,976,752,711 }, /* ; 00 (320x200,320x400,640x200,640x400) */
-        {1368,976,729,688 }, /* ; 01 (320x350,640x350) */
-        {1408,976,752,711 }, /* ; 02 (360x400,720x400) */
-        {1408,976,729,688 }, /* ; 03 (720x350) */
-        {1368,976,794,753 }, /* ; 04 (640x480x75Hz) */
-        {1448,1036,854,813}, /* ; 05 (800x600x75Hz) */
-        {1560,1168,938,897}, /* ; 06 (1024x768x75Hz) */
-        {0,1296,0,1025    } /* ; 07 (1280x1024x75Hz) */
+/* [ycchen] 02/18/03 Set DE as default */
+static struct XGI330_LVDSDataStruct XGI_LVDS1280x1024Des_2x75[] = {
+	{1368,  976, 752,  711}, /* ; 00 (320x200,320x400,640x200,640x400) */
+	{1368,  976, 729,  688}, /* ; 01 (320x350,640x350) */
+	{1408,  976, 752,  711}, /* ; 02 (360x400,720x400) */
+	{1408,  976, 729,  688}, /* ; 03 (720x350) */
+	{1368,  976, 794,  753}, /* ; 04 (640x480x75Hz) */
+	{1448, 1036, 854,  813}, /* ; 05 (800x600x75Hz) */
+	{1560, 1168, 938,  897}, /* ; 06 (1024x768x75Hz) */
+	{   0, 1296,   0, 1025}  /* ; 07 (1280x1024x75Hz) */
 };
 
-static struct XGI330_LCDDataDesStruct2 XGI_LVDSNoScalingDesDatax75[] =  /* Scaling LCD 75Hz */
-{
-       { 0,648,448,405,96,2  }, /* ; 00 (320x200,320x400,640x200,640x400) */
-       { 0,648,448,355,96,2  }, /* ; 01 (320x350,640x350) */
-       { 0,729,448,405,108,2 }, /* ; 02 (360x400,720x400) */
-       { 0,729,448,355,108,2 }, /* ; 03 (720x350) */
-       { 0,656,0,481,64,3    }, /* ; 04 (640x480x75Hz) */
-       { 0,816,0,601,80,3    }, /* ; 05 (800x600x75Hz) */
-       { 0,1040,0,769,96,3   }, /* ; 06 (1024x768x75Hz) */
-       { 0,1296,0,1025,144,3 }, /* ; 07 (1280x1024x75Hz) */
-       { 0,1448,0,1051,112,3 }, /* ; 08 (1400x1050x75Hz) ;;[ycchen] 12/19/02 */
-       { 0,1664,0,1201,192,3 }, /* ; 09 (1600x1200x75Hz) */
-       { 0,1328,0,771,112,6  }  /* ; 0A (1280x768x75Hz) */
+/* Scaling LCD 75Hz */
+static struct XGI330_LCDDataDesStruct2 XGI_LVDSNoScalingDesDatax75[] = {
+	{0,  648, 448,  405,  96, 2}, /* ; 00 (320x200,320x400,
+					       640x200,640x400) */
+	{0,  648, 448,  355,  96, 2}, /* ; 01 (320x350,640x350) */
+	{0,  729, 448,  405, 108, 2}, /* ; 02 (360x400,720x400) */
+	{0,  729, 448,  355, 108, 2}, /* ; 03 (720x350) */
+	{0,  656,   0,  481,  64, 3}, /* ; 04 (640x480x75Hz) */
+	{0,  816,   0,  601,  80, 3}, /* ; 05 (800x600x75Hz) */
+	{0, 1040,   0,  769,  96, 3}, /* ; 06 (1024x768x75Hz) */
+	{0, 1296,   0, 1025, 144, 3}, /* ; 07 (1280x1024x75Hz) */
+	{0, 1448,   0, 1051, 112, 3}, /* ; 08 (1400x1050x75Hz)
+					 ;;[ycchen] 12/19/02 */
+	{0, 1664,   0, 1201, 192, 3}, /* ; 09 (1600x1200x75Hz) */
+	{0, 1328,   0,  771, 112, 6}  /* ; 0A (1280x768x75Hz) */
 };
 
 #if 0
-static struct XGI330_LVDSDataStruct  XGI330_LVDS640x480Data_1[] =
-{
- {800, 449, 800, 449},
- {800, 449, 800, 449},
- {800, 449, 800, 449},
- {800, 449, 800, 449},
- {800, 525, 800, 525},
- {1056, 628,1056, 628},
- {1056, 628,1056, 628},
- {1056, 628,1056, 628},
- {1056, 628,1056, 628}
+static struct XGI330_LVDSDataStruct  XGI330_LVDS640x480Data_1[] = {
+	{ 800, 449,  800, 449},
+	{ 800, 449,  800, 449},
+	{ 800, 449,  800, 449},
+	{ 800, 449,  800, 449},
+	{ 800, 525,  800, 525},
+	{1056, 628, 1056, 628},
+	{1056, 628, 1056, 628},
+	{1056, 628, 1056, 628},
+	{1056, 628, 1056, 628}
 };
 #endif
 
-static struct XGI330_CHTVDataStruct  XGI_CHTVUNTSCData[] =
-{
- {840, 600, 840, 600},
- {840, 600, 840, 600},
- {840, 600, 840, 600},
- {840, 600, 840, 600},
- {784, 600, 784, 600},
- {1064, 750,1064, 750}
+static struct XGI330_CHTVDataStruct  XGI_CHTVUNTSCData[] = {
+	{ 840, 600,  840, 600},
+	{ 840, 600,  840, 600},
+	{ 840, 600,  840, 600},
+	{ 840, 600,  840, 600},
+	{ 784, 600,  784, 600},
+	{1064, 750, 1064, 750}
 };
 
-static struct XGI330_CHTVDataStruct  XGI_CHTVONTSCData[] =
-{
- {840, 525, 840, 525},
- {840, 525, 840, 525},
- {840, 525, 840, 525},
- {840, 525, 840, 525},
- {784, 525, 784, 525},
- {1040, 700,1040, 700}
+static struct XGI330_CHTVDataStruct  XGI_CHTVONTSCData[] = {
+	{ 840, 525,  840, 525},
+	{ 840, 525,  840, 525},
+	{ 840, 525,  840, 525},
+	{ 840, 525,  840, 525},
+	{ 784, 525,  784, 525},
+	{1040, 700, 1040, 700}
 };
 
-static struct XGI330_CHTVDataStruct  XGI_CHTVUPALData[] =
-{
- {1008, 625,1008, 625},
- {1008, 625,1008, 625},
- {1008, 625,1008, 625},
- {1008, 625,1008, 625},
- {840, 750, 840, 750},
- {936, 836, 936, 836}
+static struct XGI330_CHTVDataStruct  XGI_CHTVUPALData[] = {
+	{1008, 625, 1008, 625},
+	{1008, 625, 1008, 625},
+	{1008, 625, 1008, 625},
+	{1008, 625, 1008, 625},
+	{ 840, 750,  840, 750},
+	{ 936, 836,  936, 836}
 };
 
-static struct XGI330_CHTVDataStruct  XGI_CHTVOPALData[] =
-{
- {1008, 625,1008, 625},
- {1008, 625,1008, 625},
- {1008, 625,1008, 625},
- {1008, 625,1008, 625},
- {840, 625, 840, 625},
- {960, 750, 960, 750}
+static struct XGI330_CHTVDataStruct  XGI_CHTVOPALData[] = {
+	{1008, 625, 1008, 625},
+	{1008, 625, 1008, 625},
+	{1008, 625, 1008, 625},
+	{1008, 625, 1008, 625},
+	{840,  625,  840, 625},
+	{960,  750,  960, 750}
 };
 
-static struct XGI_LVDSCRT1HDataStruct  XGI_LVDSCRT11024x768_1_H[] =
-{
-	        /* CR00,CR02,CR03,CR04,CR05,SR0B,SR0C,SR0E */
-                {{      0x4B,0x27,0x8F,0x32,0x1B,0x00,0x45,0x00 }}, /* 00 (320x) */
-                {{      0x4B,0x27,0x8F,0x2B,0x03,0x00,0x44,0x00 }}, /* 01 (360x) */
-                {{      0x55,0x31,0x99,0x46,0x1D,0x00,0x55,0x00 }}, /* 02 (400x) */
-                {{      0x63,0x3F,0x87,0x4A,0x93,0x00,0x01,0x00 }}, /* 03 (512x) */
-                {{      0x73,0x4F,0x97,0x55,0x86,0x00,0x05,0x00 }}, /* 04 (640x) */
-                {{      0x73,0x4F,0x97,0x55,0x86,0x00,0x05,0x00 }}, /* 05 (720x) */
-                {{      0x87,0x63,0x8B,0x69,0x1A,0x00,0x26,0x00 }}, /* 06 (800x) */
-                {{      0xA3,0x7F,0x87,0x86,0x97,0x00,0x02,0x00 }} /* 07 (1024x) */
+/* CR00,CR02,CR03,CR04,CR05,SR0B,SR0C,SR0E */
+static struct XGI_LVDSCRT1HDataStruct  XGI_LVDSCRT11024x768_1_H[] = {
+	{ {0x4B, 0x27, 0x8F, 0x32, 0x1B, 0x00, 0x45, 0x00} }, /* 00 (320x) */
+	{ {0x4B, 0x27, 0x8F, 0x2B, 0x03, 0x00, 0x44, 0x00} }, /* 01 (360x) */
+	{ {0x55, 0x31, 0x99, 0x46, 0x1D, 0x00, 0x55, 0x00} }, /* 02 (400x) */
+	{ {0x63, 0x3F, 0x87, 0x4A, 0x93, 0x00, 0x01, 0x00} }, /* 03 (512x) */
+	{ {0x73, 0x4F, 0x97, 0x55, 0x86, 0x00, 0x05, 0x00} }, /* 04 (640x) */
+	{ {0x73, 0x4F, 0x97, 0x55, 0x86, 0x00, 0x05, 0x00} }, /* 05 (720x) */
+	{ {0x87, 0x63, 0x8B, 0x69, 0x1A, 0x00, 0x26, 0x00} }, /* 06 (800x) */
+	{ {0xA3, 0x7F, 0x87, 0x86, 0x97, 0x00, 0x02, 0x00} }  /* 07 (1024x) */
 };
 
-static struct XGI_LVDSCRT1HDataStruct  XGI_LVDSCRT11280x1024_1_H[] =
-{
-		/* CR00,CR02,CR03,CR04,CR05,SR0B,SR0C,SR0E */
-                {{      0x56,0x27,0x9A,0x30,0x1E,0x00,0x05,0x00 }}, /* 00 (320x) */
-                {{      0x56,0x27,0x9A,0x30,0x1E,0x00,0x05,0x00 }}, /* 01 (360x) */
-                {{      0x60,0x31,0x84,0x3A,0x88,0x00,0x01,0x00 }}, /* 02 (400x) */
-                {{      0x6E,0x3F,0x92,0x48,0x96,0x00,0x01,0x00 }}, /* 03 (512x) */
-                {{      0x7E,0x4F,0x82,0x58,0x06,0x00,0x06,0x00 }}, /* 04 (640x) */
-                {{      0x7E,0x4F,0x82,0x58,0x06,0x00,0x06,0x00 }}, /* 05 (720x) */
-                {{      0x92,0x63,0x96,0x6C,0x1A,0x00,0x06,0x00 }}, /* 06 (800x) */
-                {{      0xAE,0x7F,0x92,0x88,0x96,0x00,0x02,0x00 }}, /* 07 (1024x) */
-                {{      0xCE,0x9F,0x92,0xA8,0x16,0x00,0x07,0x00 }} /* 08 (1280x) */
+/* CR00,CR02,CR03,CR04,CR05,SR0B,SR0C,SR0E */
+static struct XGI_LVDSCRT1HDataStruct  XGI_LVDSCRT11280x1024_1_H[] = {
+	{ {0x56, 0x27, 0x9A, 0x30, 0x1E, 0x00, 0x05, 0x00 } }, /* 00 (320x) */
+	{ {0x56, 0x27, 0x9A, 0x30, 0x1E, 0x00, 0x05, 0x00 } }, /* 01 (360x) */
+	{ {0x60, 0x31, 0x84, 0x3A, 0x88, 0x00, 0x01, 0x00 } }, /* 02 (400x) */
+	{ {0x6E, 0x3F, 0x92, 0x48, 0x96, 0x00, 0x01, 0x00 } }, /* 03 (512x) */
+	{ {0x7E, 0x4F, 0x82, 0x58, 0x06, 0x00, 0x06, 0x00 } }, /* 04 (640x) */
+	{ {0x7E, 0x4F, 0x82, 0x58, 0x06, 0x00, 0x06, 0x00 } }, /* 05 (720x) */
+	{ {0x92, 0x63, 0x96, 0x6C, 0x1A, 0x00, 0x06, 0x00 } }, /* 06 (800x) */
+	{ {0xAE, 0x7F, 0x92, 0x88, 0x96, 0x00, 0x02, 0x00 } }, /* 07 (1024x) */
+	{ {0xCE, 0x9F, 0x92, 0xA8, 0x16, 0x00, 0x07, 0x00 } }  /* 08 (1280x) */
 };
 
-static struct XGI_LVDSCRT1HDataStruct  XGI_LVDSCRT11024x768_2_H[] =
-{
-		/* CR00,CR02,CR03,CR04,CR05,SR0B,SR0C,SR0E */
-                {{      0x63,0x27,0x87,0x3B,0x8C,0x00,0x01,0x00 }}, /* 00 (320x) */
-                {{      0x63,0x27,0x87,0x3B,0x8C,0x00,0x01,0x00 }}, /* 01 (360x) */
-                {{      0x63,0x31,0x87,0x3D,0x8E,0x00,0x01,0x00 }}, /* 02 (400x) */
-                {{      0x63,0x3F,0x87,0x45,0x96,0x00,0x01,0x00 }}, /* 03 (512x) */
-                {{      0xA3,0x4F,0x87,0x6E,0x9F,0x00,0x06,0x00 }}, /* 04 (640x) */
-                {{      0xA3,0x4F,0x87,0x6E,0x9F,0x00,0x06,0x00 }}, /* 05 (720x) */
-                {{      0xA3,0x63,0x87,0x78,0x89,0x00,0x02,0x00 }}, /* 06 (800x) */
-                {{      0xA3,0x7F,0x87,0x86,0x97,0x00,0x02,0x00 }} /* 07 (1024x) */
+/* CR00,CR02,CR03,CR04,CR05,SR0B,SR0C,SR0E */
+static struct XGI_LVDSCRT1HDataStruct  XGI_LVDSCRT11024x768_2_H[] = {
+	{ {0x63, 0x27, 0x87, 0x3B, 0x8C, 0x00, 0x01, 0x00} }, /* 00 (320x) */
+	{ {0x63, 0x27, 0x87, 0x3B, 0x8C, 0x00, 0x01, 0x00} }, /* 01 (360x) */
+	{ {0x63, 0x31, 0x87, 0x3D, 0x8E, 0x00, 0x01, 0x00} }, /* 02 (400x) */
+	{ {0x63, 0x3F, 0x87, 0x45, 0x96, 0x00, 0x01, 0x00} }, /* 03 (512x) */
+	{ {0xA3, 0x4F, 0x87, 0x6E, 0x9F, 0x00, 0x06, 0x00} }, /* 04 (640x) */
+	{ {0xA3, 0x4F, 0x87, 0x6E, 0x9F, 0x00, 0x06, 0x00} }, /* 05 (720x) */
+	{ {0xA3, 0x63, 0x87, 0x78, 0x89, 0x00, 0x02, 0x00} }, /* 06 (800x) */
+	{ {0xA3, 0x7F, 0x87, 0x86, 0x97, 0x00, 0x02, 0x00} }  /* 07 (1024x) */
 };
 
-static struct XGI_LVDSCRT1HDataStruct  XGI_LVDSCRT11280x1024_2_H[] =
-{
-                /* CR00,CR02,CR03,CR04,CR05,SR0B,SR0C,SR0E */
-                {{      0x7E,0x3B,0x9A,0x44,0x12,0x00,0x01,0x00 }}, /* 00 (320x) */
-                {{      0x7E,0x3B,0x9A,0x44,0x12,0x00,0x01,0x00 }}, /* 01 (360x) */
-                {{      0x7E,0x40,0x84,0x49,0x91,0x00,0x01,0x00 }}, /* 02 (400x) */
-                {{      0x7E,0x47,0x93,0x50,0x9E,0x00,0x01,0x00 }}, /* 03 (512x) */
-                {{      0xCE,0x77,0x8A,0x80,0x8E,0x00,0x02,0x00 }}, /* 04 (640x) */
-                {{      0xCE,0x77,0x8A,0x80,0x8E,0x00,0x02,0x00 }}, /* 05 (720x) */
-                {{      0xCE,0x81,0x94,0x8A,0x98,0x00,0x02,0x00 }}, /* 06 (800x) */
-                {{      0xCE,0x8F,0x82,0x98,0x06,0x00,0x07,0x00 }}, /* 07 (1024x) */
-                {{      0xCE,0x9F,0x92,0xA8,0x16,0x00,0x07,0x00 }} /* 08 (1280x) */
+/* CR00,CR02,CR03,CR04,CR05,SR0B,SR0C,SR0E */
+static struct XGI_LVDSCRT1HDataStruct  XGI_LVDSCRT11280x1024_2_H[] = {
+	{ {0x7E, 0x3B, 0x9A, 0x44, 0x12, 0x00, 0x01, 0x00} }, /* 00 (320x) */
+	{ {0x7E, 0x3B, 0x9A, 0x44, 0x12, 0x00, 0x01, 0x00} }, /* 01 (360x) */
+	{ {0x7E, 0x40, 0x84, 0x49, 0x91, 0x00, 0x01, 0x00} }, /* 02 (400x) */
+	{ {0x7E, 0x47, 0x93, 0x50, 0x9E, 0x00, 0x01, 0x00} }, /* 03 (512x) */
+	{ {0xCE, 0x77, 0x8A, 0x80, 0x8E, 0x00, 0x02, 0x00} }, /* 04 (640x) */
+	{ {0xCE, 0x77, 0x8A, 0x80, 0x8E, 0x00, 0x02, 0x00} }, /* 05 (720x) */
+	{ {0xCE, 0x81, 0x94, 0x8A, 0x98, 0x00, 0x02, 0x00} }, /* 06 (800x) */
+	{ {0xCE, 0x8F, 0x82, 0x98, 0x06, 0x00, 0x07, 0x00} }, /* 07 (1024x) */
+	{ {0xCE, 0x9F, 0x92, 0xA8, 0x16, 0x00, 0x07, 0x00} }  /* 08 (1280x) */
 };
 
-static struct XGI_LVDSCRT1HDataStruct XGI_LVDSCRT11400x1050_1_H[] =
-{               /* CR00,CR02,CR03,CR04,CR05,SR0B,SR0C,SR0E */
-                {{      0x47,0x27,0x8B,0x2C,0x1A,0x00,0x05,0x00 }}, /* 00 (320x) */
-                {{      0x47,0x27,0x8B,0x30,0x1E,0x00,0x05,0x00 }}, /* 01 (360x) */
-                {{      0x51,0x31,0x95,0x36,0x04,0x00,0x01,0x00 }}, /* 02 (400x) */
-                {{      0x5F,0x3F,0x83,0x44,0x92,0x00,0x01,0x00 }}, /* 03 (512x) */
-                {{      0x6F,0x4F,0x93,0x54,0x82,0x00,0x05,0x00 }}, /* 04 (640x) */
-                {{      0x6F,0x4F,0x93,0x54,0x82,0x00,0x05,0x00 }}, /* 05 (720x) */
-                {{      0x83,0x63,0x87,0x68,0x16,0x00,0x06,0x00 }}, /* 06 (800x) */
-                {{      0x9F,0x7F,0x83,0x84,0x92,0x00,0x02,0x00 }}, /* 07 (1024x) */
-                {{      0xBF,0x9F,0x83,0xA4,0x12,0x00,0x07,0x00 }}, /* 08 (1280x) */
-                {{      0xCE,0xAE,0x92,0xB3,0x01,0x00,0x03,0x00 }} /* 09 (1400x) */
+/* CR00,CR02,CR03,CR04,CR05,SR0B,SR0C,SR0E */
+static struct XGI_LVDSCRT1HDataStruct XGI_LVDSCRT11400x1050_1_H[] = {
+	{ {0x47, 0x27, 0x8B, 0x2C, 0x1A, 0x00, 0x05, 0x00} }, /* 00 (320x) */
+	{ {0x47, 0x27, 0x8B, 0x30, 0x1E, 0x00, 0x05, 0x00} }, /* 01 (360x) */
+	{ {0x51, 0x31, 0x95, 0x36, 0x04, 0x00, 0x01, 0x00} }, /* 02 (400x) */
+	{ {0x5F, 0x3F, 0x83, 0x44, 0x92, 0x00, 0x01, 0x00} }, /* 03 (512x) */
+	{ {0x6F, 0x4F, 0x93, 0x54, 0x82, 0x00, 0x05, 0x00} }, /* 04 (640x) */
+	{ {0x6F, 0x4F, 0x93, 0x54, 0x82, 0x00, 0x05, 0x00} }, /* 05 (720x) */
+	{ {0x83, 0x63, 0x87, 0x68, 0x16, 0x00, 0x06, 0x00} }, /* 06 (800x) */
+	{ {0x9F, 0x7F, 0x83, 0x84, 0x92, 0x00, 0x02, 0x00} }, /* 07 (1024x) */
+	{ {0xBF, 0x9F, 0x83, 0xA4, 0x12, 0x00, 0x07, 0x00} }, /* 08 (1280x) */
+	{ {0xCE, 0xAE, 0x92, 0xB3, 0x01, 0x00, 0x03, 0x00} }  /* 09 (1400x) */
 };
 
-static struct XGI_LVDSCRT1HDataStruct XGI_LVDSCRT11400x1050_2_H[] =
-{               /* CR00,CR02,CR03,CR04,CR05,SR0B,SR0C,SR0E */
-                {{      0x76,0x3F,0x83,0x45,0x8C,0x00,0x41,0x00 }}, /* 00 (320x) */
-                {{      0x76,0x3F,0x83,0x45,0x8C,0x00,0x41,0x00 }}, /* 01 (360x) */
-                {{      0x76,0x31,0x9A,0x48,0x9F,0x00,0x41,0x00 }}, /* 02 (400x) */
-                {{      0x76,0x3F,0x9A,0x4F,0x96,0x00,0x41,0x00 }}, /* 03 (512x) */
-                {{      0xCE,0x7E,0x82,0x87,0x9E,0x00,0x02,0x00 }}, /* 04 (640x) */
-                {{      0xCE,0x7E,0x82,0x87,0x9E,0x00,0x02,0x00 }}, /* 05 (720x) */
-                {{      0xCE,0x63,0x92,0x96,0x04,0x00,0x07,0x00 }}, /* 06 (800x) */
-                {{      0xCE,0x7F,0x92,0xA4,0x12,0x00,0x07,0x00 }}, /* 07 (1024x) */
-                {{      0xCE,0x9F,0x92,0xB4,0x02,0x00,0x03,0x00 }}, /* 08 (1280x) */
-                {{      0xCE,0xAE,0x92,0xBC,0x0A,0x00,0x03,0x00 }} /* 09 (1400x) */
+/* CR00,CR02,CR03,CR04,CR05,SR0B,SR0C,SR0E */
+static struct XGI_LVDSCRT1HDataStruct XGI_LVDSCRT11400x1050_2_H[] = {
+	{ {0x76, 0x3F, 0x83, 0x45, 0x8C, 0x00, 0x41, 0x00} }, /* 00 (320x) */
+	{ {0x76, 0x3F, 0x83, 0x45, 0x8C, 0x00, 0x41, 0x00} }, /* 01 (360x) */
+	{ {0x76, 0x31, 0x9A, 0x48, 0x9F, 0x00, 0x41, 0x00} }, /* 02 (400x) */
+	{ {0x76, 0x3F, 0x9A, 0x4F, 0x96, 0x00, 0x41, 0x00} }, /* 03 (512x) */
+	{ {0xCE, 0x7E, 0x82, 0x87, 0x9E, 0x00, 0x02, 0x00} }, /* 04 (640x) */
+	{ {0xCE, 0x7E, 0x82, 0x87, 0x9E, 0x00, 0x02, 0x00} }, /* 05 (720x) */
+	{ {0xCE, 0x63, 0x92, 0x96, 0x04, 0x00, 0x07, 0x00} }, /* 06 (800x) */
+	{ {0xCE, 0x7F, 0x92, 0xA4, 0x12, 0x00, 0x07, 0x00} }, /* 07 (1024x) */
+	{ {0xCE, 0x9F, 0x92, 0xB4, 0x02, 0x00, 0x03, 0x00} }, /* 08 (1280x) */
+	{ {0xCE, 0xAE, 0x92, 0xBC, 0x0A, 0x00, 0x03, 0x00} }  /* 09 (1400x) */
 };
 
-static struct XGI_LVDSCRT1HDataStruct XGI_LVDSCRT11600x1200_1_H[] =
 /* ;302lv channelA [ycchen] 12/05/02 LCDHT=2048 */
-{   /* ; CR00,CR02,CR03,CR04,CR05,SR0B,SR0C,SR0E */
-                {{      0x5B,0x27,0x9F,0x32,0x0A,0x00,0x01,0x00 }},/* 00 (320x) */
-                {{      0x5B,0x27,0x9F,0x32,0x0A,0x00,0x01,0x00 }},/* 01 (360x) */
-                {{      0x65,0x31,0x89,0x3C,0x94,0x00,0x01,0x00 }},/* 02 (400x) */
-                {{      0x73,0x3F,0x97,0x4A,0x82,0x00,0x05,0x00 }},/* 03 (512x) */
-                {{      0x83,0x4F,0x87,0x51,0x09,0x00,0x06,0x00 }},/* 04 (640x) */
-		{{      0x83,0x4F,0x87,0x51,0x09,0x00,0x06,0x00 }},/* 05 (720x) */
-		{{      0x97,0x63,0x9B,0x65,0x1D,0x00,0x06,0xF0 }},/* 06 (800x) */
-		{{      0xB3,0x7F,0x97,0x81,0x99,0x00,0x02,0x00 }},/* 07 (1024x) */
-		{{      0xD3,0x9F,0x97,0xA1,0x19,0x00,0x07,0x00 }},/* 08 (1280x) */
-		{{      0xE2,0xAE,0x86,0xB9,0x91,0x00,0x03,0x00 }},/* 09 (1400x) */
-		{{      0xFB,0xC7,0x9F,0xC9,0x81,0x00,0x07,0x00 }} /* 0A (1600x) */
+/* ; CR00,CR02,CR03,CR04,CR05,SR0B,SR0C,SR0E */
+static struct XGI_LVDSCRT1HDataStruct XGI_LVDSCRT11600x1200_1_H[] = {
+	{ {0x5B, 0x27, 0x9F, 0x32, 0x0A, 0x00, 0x01, 0x00} }, /* 00 (320x) */
+	{ {0x5B, 0x27, 0x9F, 0x32, 0x0A, 0x00, 0x01, 0x00} }, /* 01 (360x) */
+	{ {0x65, 0x31, 0x89, 0x3C, 0x94, 0x00, 0x01, 0x00} }, /* 02 (400x) */
+	{ {0x73, 0x3F, 0x97, 0x4A, 0x82, 0x00, 0x05, 0x00} }, /* 03 (512x) */
+	{ {0x83, 0x4F, 0x87, 0x51, 0x09, 0x00, 0x06, 0x00} }, /* 04 (640x) */
+	{ {0x83, 0x4F, 0x87, 0x51, 0x09, 0x00, 0x06, 0x00} }, /* 05 (720x) */
+	{ {0x97, 0x63, 0x9B, 0x65, 0x1D, 0x00, 0x06, 0xF0} }, /* 06 (800x) */
+	{ {0xB3, 0x7F, 0x97, 0x81, 0x99, 0x00, 0x02, 0x00} }, /* 07 (1024x) */
+	{ {0xD3, 0x9F, 0x97, 0xA1, 0x19, 0x00, 0x07, 0x00} }, /* 08 (1280x) */
+	{ {0xE2, 0xAE, 0x86, 0xB9, 0x91, 0x00, 0x03, 0x00} }, /* 09 (1400x) */
+	{ {0xFB, 0xC7, 0x9F, 0xC9, 0x81, 0x00, 0x07, 0x00} }  /* 0A (1600x) */
 };
 
-static struct XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11024x768_1_V[] =
-{               /* CR06,CR07,CR10,CR11,CR15,CR16,SR0A+CR09(5->7) */
-                {{      0x97,0x1F,0x60,0x87,0x5D,0x83,0x10      }}, /* 00 (x350) */
-                {{      0xB4,0x1F,0x92,0x89,0x8F,0xB5,0x30      }}, /* 01 (x400) */
-                {{      0x04,0x3E,0xE2,0x89,0xDF,0x05,0x00      }}, /* 02 (x480) */
-                {{      0x7C,0xF0,0x5A,0x8F,0x57,0x7D,0xA0      }}, /* 03 (x600) */
-                {{      0x24,0xF5,0x02,0x88,0xFF,0x25,0x90      }} /* 04 (x768) */
+/* CR06,CR07,CR10,CR11,CR15,CR16,SR0A+CR09(5->7) */
+static struct XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11024x768_1_V[] = {
+	{ {0x97, 0x1F, 0x60, 0x87, 0x5D, 0x83, 0x10} }, /* 00 (x350) */
+	{ {0xB4, 0x1F, 0x92, 0x89, 0x8F, 0xB5, 0x30} }, /* 01 (x400) */
+	{ {0x04, 0x3E, 0xE2, 0x89, 0xDF, 0x05, 0x00} }, /* 02 (x480) */
+	{ {0x7C, 0xF0, 0x5A, 0x8F, 0x57, 0x7D, 0xA0} }, /* 03 (x600) */
+	{ {0x24, 0xF5, 0x02, 0x88, 0xFF, 0x25, 0x90} }  /* 04 (x768) */
 };
 
-static struct XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11024x768_2_V[] =
-{               /* CR06,CR07,CR10,CR11,CR15,CR16,SR0A */
-                {{      0x24,0xBB,0x31,0x87,0x5D,0x25,0x30      }}, /* 00 (x350) */
-                {{      0x24,0xBB,0x4A,0x80,0x8F,0x25,0x30      }}, /* 01 (x400) */
-                {{      0x24,0xBB,0x72,0x88,0xDF,0x25,0x30      }}, /* 02 (x480) */
-                {{      0x24,0xF1,0xAE,0x84,0x57,0x25,0xB0      }}, /* 03 (x600) */
-                {{      0x24,0xF5,0x02,0x88,0xFF,0x25,0x90      }} /* 04 (x768) */
+/* CR06,CR07,CR10,CR11,CR15,CR16,SR0A */
+static struct XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11024x768_2_V[] = {
+	{ {0x24, 0xBB, 0x31, 0x87, 0x5D, 0x25, 0x30} }, /* 00 (x350) */
+	{ {0x24, 0xBB, 0x4A, 0x80, 0x8F, 0x25, 0x30} }, /* 01 (x400) */
+	{ {0x24, 0xBB, 0x72, 0x88, 0xDF, 0x25, 0x30} }, /* 02 (x480) */
+	{ {0x24, 0xF1, 0xAE, 0x84, 0x57, 0x25, 0xB0} }, /* 03 (x600) */
+	{ {0x24, 0xF5, 0x02, 0x88, 0xFF, 0x25, 0x90} }  /* 04 (x768) */
 };
 
-static struct XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11280x1024_1_V[] =
-{               /* CR06,CR07,CR10,CR11,CR15,CR16,SR0A */
-                {{       0x86,0x1F,0x5E,0x82,0x5D,0x87,0x00     }}, /* 00 (x350) */
-                {{       0xB8,0x1F,0x90,0x84,0x8F,0xB9,0x30     }}, /* 01 (x400) */
-                {{       0x08,0x3E,0xE0,0x84,0xDF,0x09,0x00     }}, /* 02 (x480) */
-                {{       0x80,0xF0,0x58,0x8C,0x57,0x81,0xA0     }}, /* 03 (x600) */
-                {{       0x28,0xF5,0x00,0x84,0xFF,0x29,0x90     }}, /* 04 (x768) */
-                {{       0x28,0x5A,0x13,0x87,0xFF,0x29,0xA9     }} /* 05 (x1024) */
+/* CR06,CR07,CR10,CR11,CR15,CR16,SR0A */
+static struct XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11280x1024_1_V[] = {
+	{ {0x86, 0x1F, 0x5E, 0x82, 0x5D, 0x87, 0x00} }, /* 00 (x350) */
+	{ {0xB8, 0x1F, 0x90, 0x84, 0x8F, 0xB9, 0x30} }, /* 01 (x400) */
+	{ {0x08, 0x3E, 0xE0, 0x84, 0xDF, 0x09, 0x00} }, /* 02 (x480) */
+	{ {0x80, 0xF0, 0x58, 0x8C, 0x57, 0x81, 0xA0} }, /* 03 (x600) */
+	{ {0x28, 0xF5, 0x00, 0x84, 0xFF, 0x29, 0x90} }, /* 04 (x768) */
+	{ {0x28, 0x5A, 0x13, 0x87, 0xFF, 0x29, 0xA9} }  /* 05 (x1024) */
 };
 
-static struct XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11280x1024_2_V[] =
-{               /* CR06,CR07,CR10,CR11,CR15,CR16,SR0A */
-                {{      0x28,0xD2,0xAF,0x83,0xAE,0xD8,0xA1      }}, /* 00 (x350) */
-                {{      0x28,0xD2,0xC8,0x8C,0xC7,0xF2,0x81      }}, /* 01 (x400) */
-                {{      0x28,0xD2,0xF0,0x84,0xEF,0x1A,0xB1      }}, /* 02 (x480) */
-                {{      0x28,0xDE,0x2C,0x8F,0x2B,0x56,0x91      }}, /* 03 (x600) */
-                {{      0x28,0xDE,0x80,0x83,0x7F,0xAA,0x91      }}, /* 04 (x768) */
-                {{      0x28,0x5A,0x13,0x87,0xFF,0x29,0xA9      }} /* 05 (x1024) */
+/* CR06,CR07,CR10,CR11,CR15,CR16,SR0A */
+static struct XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11280x1024_2_V[] = {
+	{ {0x28, 0xD2, 0xAF, 0x83, 0xAE, 0xD8, 0xA1} }, /* 00 (x350) */
+	{ {0x28, 0xD2, 0xC8, 0x8C, 0xC7, 0xF2, 0x81} }, /* 01 (x400) */
+	{ {0x28, 0xD2, 0xF0, 0x84, 0xEF, 0x1A, 0xB1} }, /* 02 (x480) */
+	{ {0x28, 0xDE, 0x2C, 0x8F, 0x2B, 0x56, 0x91} }, /* 03 (x600) */
+	{ {0x28, 0xDE, 0x80, 0x83, 0x7F, 0xAA, 0x91} }, /* 04 (x768) */
+	{ {0x28, 0x5A, 0x13, 0x87, 0xFF, 0x29, 0xA9} }  /* 05 (x1024) */
 };
 
-static struct XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11400x1050_1_V[] =
-{               /* CR06,CR07,CR10,CR11,CR15,CR16,SR0A */
-                {{      0x6C,0x1F,0x60,0x84,0x5D,0x6D,0x10      }}, /* 00 (x350) */
-                {{      0x9E,0x1F,0x93,0x86,0x8F,0x9F,0x30      }}, /* 01 (x400) */
-                {{      0xEE,0x1F,0xE2,0x86,0xDF,0xEF,0x10      }}, /* 02 (x480) */
-                {{      0x66,0xF0,0x5A,0x8e,0x57,0x67,0xA0      }}, /* 03 (x600) */
-                {{      0x0E,0xF5,0x02,0x86,0xFF,0x0F,0x90      }}, /* 04 (x768) */
-                {{      0x0E,0x5A,0x02,0x86,0xFF,0x0F,0x89      }}, /* 05 (x1024) */
-                {{      0x28,0x10,0x1A,0x80,0x19,0x29,0x0F      }} /* 06 (x1050) */
+/* CR06,CR07,CR10,CR11,CR15,CR16,SR0A */
+static struct XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11400x1050_1_V[] = {
+	{ {0x6C, 0x1F, 0x60, 0x84, 0x5D, 0x6D, 0x10} }, /* 00 (x350) */
+	{ {0x9E, 0x1F, 0x93, 0x86, 0x8F, 0x9F, 0x30} }, /* 01 (x400) */
+	{ {0xEE, 0x1F, 0xE2, 0x86, 0xDF, 0xEF, 0x10} }, /* 02 (x480) */
+	{ {0x66, 0xF0, 0x5A, 0x8e, 0x57, 0x67, 0xA0} }, /* 03 (x600) */
+	{ {0x0E, 0xF5, 0x02, 0x86, 0xFF, 0x0F, 0x90} }, /* 04 (x768) */
+	{ {0x0E, 0x5A, 0x02, 0x86, 0xFF, 0x0F, 0x89} }, /* 05 (x1024) */
+	{ {0x28, 0x10, 0x1A, 0x80, 0x19, 0x29, 0x0F} }  /* 06 (x1050) */
 };
 
-static struct XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11400x1050_2_V[] =
-{              /* CR06,CR07,CR10,CR11,CR15,CR16,SR0A */
-                {{      0x28,0x92,0xB6,0x83,0xB5,0xCF,0x81      }}, /* 00 (x350) */
-                {{      0x28,0x92,0xD5,0x82,0xD4,0xEE,0x81      }}, /* 01 (x400) */
-                {{      0x28,0x92,0xFD,0x8A,0xFC,0x16,0xB1      }}, /* 02 (x480) */
-                {{      0x28,0xD4,0x39,0x86,0x57,0x29,0x81      }}, /* 03 (x600) */
-                {{      0x28,0xD4,0x8D,0x9A,0xFF,0x29,0xA1      }}, /* 04 (x768) */
-                {{      0x28,0x5A,0x0D,0x9A,0xFF,0x29,0xA9      }}, /* 05 (x1024) */
-                {{      0x28,0x10,0x1A,0x87,0x19,0x29,0x8F      }} /* 06 (x1050) */
+/* CR06,CR07,CR10,CR11,CR15,CR16,SR0A */
+static struct XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11400x1050_2_V[] = {
+	{ {0x28, 0x92, 0xB6, 0x83, 0xB5, 0xCF, 0x81} }, /* 00 (x350) */
+	{ {0x28, 0x92, 0xD5, 0x82, 0xD4, 0xEE, 0x81} }, /* 01 (x400) */
+	{ {0x28, 0x92, 0xFD, 0x8A, 0xFC, 0x16, 0xB1} }, /* 02 (x480) */
+	{ {0x28, 0xD4, 0x39, 0x86, 0x57, 0x29, 0x81} }, /* 03 (x600) */
+	{ {0x28, 0xD4, 0x8D, 0x9A, 0xFF, 0x29, 0xA1} }, /* 04 (x768) */
+	{ {0x28, 0x5A, 0x0D, 0x9A, 0xFF, 0x29, 0xA9} }, /* 05 (x1024) */
+	{ {0x28, 0x10, 0x1A, 0x87, 0x19, 0x29, 0x8F} }  /* 06 (x1050) */
 };
 
-static struct XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11600x1200_1_V[] =
-{
-               /* CR06,CR07,CR10,CR11,CR15,CR16,SR0A+CR09(5->7) */
-                {{      0xd4,0x1F,0x81,0x84,0x5D,0xd5,0x10      }}, /* 00 (x350) */
-                {{      0x06,0x3e,0xb3,0x86,0x8F,0x07,0x20      }}, /* 01 (x400) */
-                {{      0x56,0xba,0x03,0x86,0xDF,0x57,0x00      }}, /* 02 (x480) */
-                {{      0xce,0xF0,0x7b,0x8e,0x57,0xcf,0xa0      }}, /* 03 (x600) */
-                {{      0x76,0xF5,0x23,0x86,0xFF,0x77,0x90      }}, /* 04 (x768) */
-                {{      0x76,0x5A,0x23,0x86,0xFF,0x77,0x89      }}, /* 05 (x1024) */
-                {{      0x90,0x10,0x1A,0x8E,0x19,0x91,0x2F      }}, /* 06 (x1050) */
-                {{      0x26,0x11,0xd3,0x86,0xaF,0x27,0x3f      }} /* 07 (x1200) */
+/* CR06,CR07,CR10,CR11,CR15,CR16,SR0A+CR09(5->7) */
+static struct XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11600x1200_1_V[] = {
+	{ {0xd4, 0x1F, 0x81, 0x84, 0x5D, 0xd5, 0x10} }, /* 00 (x350) */
+	{ {0x06, 0x3e, 0xb3, 0x86, 0x8F, 0x07, 0x20} }, /* 01 (x400) */
+	{ {0x56, 0xba, 0x03, 0x86, 0xDF, 0x57, 0x00} }, /* 02 (x480) */
+	{ {0xce, 0xF0, 0x7b, 0x8e, 0x57, 0xcf, 0xa0} }, /* 03 (x600) */
+	{ {0x76, 0xF5, 0x23, 0x86, 0xFF, 0x77, 0x90} }, /* 04 (x768) */
+	{ {0x76, 0x5A, 0x23, 0x86, 0xFF, 0x77, 0x89} }, /* 05 (x1024) */
+	{ {0x90, 0x10, 0x1A, 0x8E, 0x19, 0x91, 0x2F} }, /* 06 (x1050) */
+	{ {0x26, 0x11, 0xd3, 0x86, 0xaF, 0x27, 0x3f} }  /* 07 (x1200) */
 };
 
-static struct XGI_LVDSCRT1HDataStruct XGI_LVDSCRT11024x768_1_Hx75[] =
-{ 	/* CR00,CR02,CR03,CR04,CR05,SR0B,SR0C,SR0E */
-    {{      0x4B,0x27,0x8F,0x32,0x1B,0x00,0x45,0x00 }},/* ; 00 (320x) */
-    {{      0x4B,0x27,0x8F,0x2B,0x03,0x00,0x44,0x00 }},/* ; 01 (360x) */
-    {{      0x55,0x31,0x99,0x46,0x1D,0x00,0x55,0x00 }},/* ; 02 (400x) */
-    {{      0x63,0x3F,0x87,0x4A,0x93,0x00,0x01,0x00 }},/* ; 03 (512x) */
-    {{      0x6F,0x4F,0x93,0x54,0x80,0x00,0x05,0x00 }},/* ; 04 (640x) */
-    {{      0x6F,0x4F,0x93,0x54,0x80,0x00,0x05,0x00 }},/* ; 05 (720x) */
-    {{      0x83,0x63,0x87,0x68,0x14,0x00,0x26,0x00 }},/* ; 06 (800x) */
-    {{      0x9F,0x7F,0x83,0x85,0x91,0x00,0x02,0x00 }} /* ; 07 (1024x) */
+/* CR00,CR02,CR03,CR04,CR05,SR0B,SR0C,SR0E */
+static struct XGI_LVDSCRT1HDataStruct XGI_LVDSCRT11024x768_1_Hx75[] = {
+	{ {0x4B, 0x27, 0x8F, 0x32, 0x1B, 0x00, 0x45, 0x00} },/* ; 00 (320x) */
+	{ {0x4B, 0x27, 0x8F, 0x2B, 0x03, 0x00, 0x44, 0x00} },/* ; 01 (360x) */
+	{ {0x55, 0x31, 0x99, 0x46, 0x1D, 0x00, 0x55, 0x00} },/* ; 02 (400x) */
+	{ {0x63, 0x3F, 0x87, 0x4A, 0x93, 0x00, 0x01, 0x00} },/* ; 03 (512x) */
+	{ {0x6F, 0x4F, 0x93, 0x54, 0x80, 0x00, 0x05, 0x00} },/* ; 04 (640x) */
+	{ {0x6F, 0x4F, 0x93, 0x54, 0x80, 0x00, 0x05, 0x00} },/* ; 05 (720x) */
+	{ {0x83, 0x63, 0x87, 0x68, 0x14, 0x00, 0x26, 0x00} },/* ; 06 (800x) */
+	{ {0x9F, 0x7F, 0x83, 0x85, 0x91, 0x00, 0x02, 0x00} } /* ; 07 (1024x) */
 };
 
-static struct XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11024x768_1_Vx75[] =
-{	/* CR06,CR07,CR10,CR11,CR15,CR16,SR0A+CR09(5->7) */
-    {{      0x97,0x1F,0x60,0x87,0x5D,0x83,0x10      }},/* ; 00 (x350) */
-    {{      0xB4,0x1F,0x92,0x89,0x8F,0xB5,0x30      }},/* ; 01 (x400) */
-    {{      0xFE,0x1F,0xE0,0x84,0xDF,0xFF,0x10      }},/* ; 02 (x480) */
-    {{      0x76,0xF0,0x58,0x8C,0x57,0x77,0xA0      }},/* ; 03 (x600) */
-    {{      0x1E,0xF5,0x00,0x83,0xFF,0x1F,0x90      }} /* ; 04 (x768) */
+/* CR06,CR07,CR10,CR11,CR15,CR16,SR0A+CR09(5->7) */
+static struct XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11024x768_1_Vx75[] = {
+	{ {0x97, 0x1F, 0x60, 0x87, 0x5D, 0x83, 0x10} },/* ; 00 (x350) */
+	{ {0xB4, 0x1F, 0x92, 0x89, 0x8F, 0xB5, 0x30} },/* ; 01 (x400) */
+	{ {0xFE, 0x1F, 0xE0, 0x84, 0xDF, 0xFF, 0x10} },/* ; 02 (x480) */
+	{ {0x76, 0xF0, 0x58, 0x8C, 0x57, 0x77, 0xA0} },/* ; 03 (x600) */
+	{ {0x1E, 0xF5, 0x00, 0x83, 0xFF, 0x1F, 0x90} } /* ; 04 (x768) */
 };
 
-static struct XGI_LVDSCRT1HDataStruct XGI_LVDSCRT11024x768_2_Hx75[] =
-{       /* CR00,CR02,CR03,CR04,CR05,SR0B,SR0C,SR0E */
-    {{      0x63,0x27,0x87,0x3B,0x8C,0x00,0x01,0x00 }},/* ; 00 (320x) */
-    {{      0x63,0x27,0x87,0x3B,0x8C,0x00,0x01,0x00 }},/* ; 01 (360x) */
-    {{      0x63,0x31,0x87,0x3D,0x8E,0x00,0x01,0x00 }},/* ; 02 (400x) */
-    {{      0x63,0x3F,0x87,0x45,0x96,0x00,0x01,0x00 }},/* ; 03 (512x) */
-    {{      0xA3,0x4F,0x87,0x6E,0x9F,0x00,0x06,0x00 }},/* ; 04 (640x) */
-    {{      0xA3,0x4F,0x87,0x6E,0x9F,0x00,0x06,0x00 }},/* ; 05 (720x) */
-    {{      0xA3,0x63,0x87,0x78,0x89,0x00,0x02,0x00 }},/* ; 06 (800x) */
-    {{      0xA3,0x7F,0x87,0x86,0x97,0x00,0x02,0x00 }} /* ; 07 (1024x) */
+/* CR00,CR02,CR03,CR04,CR05,SR0B,SR0C,SR0E */
+static struct XGI_LVDSCRT1HDataStruct XGI_LVDSCRT11024x768_2_Hx75[] = {
+	{ {0x63, 0x27, 0x87, 0x3B, 0x8C, 0x00, 0x01, 0x00} },/* ; 00 (320x) */
+	{ {0x63, 0x27, 0x87, 0x3B, 0x8C, 0x00, 0x01, 0x00} },/* ; 01 (360x) */
+	{ {0x63, 0x31, 0x87, 0x3D, 0x8E, 0x00, 0x01, 0x00} },/* ; 02 (400x) */
+	{ {0x63, 0x3F, 0x87, 0x45, 0x96, 0x00, 0x01, 0x00} },/* ; 03 (512x) */
+	{ {0xA3, 0x4F, 0x87, 0x6E, 0x9F, 0x00, 0x06, 0x00} },/* ; 04 (640x) */
+	{ {0xA3, 0x4F, 0x87, 0x6E, 0x9F, 0x00, 0x06, 0x00} },/* ; 05 (720x) */
+	{ {0xA3, 0x63, 0x87, 0x78, 0x89, 0x00, 0x02, 0x00} },/* ; 06 (800x) */
+	{ {0xA3, 0x7F, 0x87, 0x86, 0x97, 0x00, 0x02, 0x00} } /* ; 07 (1024x) */
 };
 
-static struct XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11024x768_2_Vx75[] =
-{       /* CR06,CR07,CR10,CR11,CR15,CR16,SR0A */
-    {{      0x24,0xBB,0x31,0x87,0x5D,0x25,0x30      }},/* ; 00 (x350) */
-    {{      0x24,0xBB,0x4A,0x80,0x8F,0x25,0x30      }},/* ; 01 (x400) */
-    {{      0x24,0xBB,0x72,0x88,0xDF,0x25,0x30      }},/* ; 02 (x480) */
-    {{      0x24,0xF1,0xAE,0x84,0x57,0x25,0xB0      }},/* ; 03 (x600) */
-    {{      0x24,0xF5,0x02,0x88,0xFF,0x25,0x90      }} /* ; 04 (x768) */
+/* CR06,CR07,CR10,CR11,CR15,CR16,SR0A */
+static struct XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11024x768_2_Vx75[] = {
+	{ {0x24, 0xBB, 0x31, 0x87, 0x5D, 0x25, 0x30} },/* ; 00 (x350) */
+	{ {0x24, 0xBB, 0x4A, 0x80, 0x8F, 0x25, 0x30} },/* ; 01 (x400) */
+	{ {0x24, 0xBB, 0x72, 0x88, 0xDF, 0x25, 0x30} },/* ; 02 (x480) */
+	{ {0x24, 0xF1, 0xAE, 0x84, 0x57, 0x25, 0xB0} },/* ; 03 (x600) */
+	{ {0x24, 0xF5, 0x02, 0x88, 0xFF, 0x25, 0x90} } /* ; 04 (x768) */
 };
 
-static struct XGI_LVDSCRT1HDataStruct XGI_LVDSCRT11280x1024_1_Hx75[] =
-{      /* CR00,CR02,CR03,CR04,CR05,SR0B,SR0C,SR0E */
-    {{      0x56,0x27,0x9A,0x30,0x1E,0x00,0x05,0x00 }},/* ; 00 (320x) */
-    {{      0x56,0x27,0x9A,0x30,0x1E,0x00,0x05,0x00 }},/* ; 01 (360x) */
-    {{      0x60,0x31,0x84,0x3A,0x88,0x00,0x01,0x00 }},/* ; 02 (400x) */
-    {{      0x6E,0x3F,0x92,0x48,0x96,0x00,0x01,0x00 }},/* ; 03 (512x) */
-    {{      0x7E,0x4F,0x82,0x54,0x06,0x00,0x06,0x00 }},/* ; 04 (640x) */
-    {{      0x7E,0x4F,0x82,0x54,0x06,0x00,0x06,0x00 }},/* ; 05 (720x) */
-    {{      0x92,0x63,0x96,0x68,0x1A,0x00,0x06,0x00 }},/* ; 06 (800x) */
-    {{      0xAE,0x7F,0x92,0x84,0x96,0x00,0x02,0x00 }},/* ; 07 (1024x) */
-    {{      0xCE,0x9F,0x92,0xA5,0x17,0x00,0x07,0x00 }} /* ; 08 (1280x) */
+/* CR00,CR02,CR03,CR04,CR05,SR0B,SR0C,SR0E */
+static struct XGI_LVDSCRT1HDataStruct XGI_LVDSCRT11280x1024_1_Hx75[] = {
+	{ {0x56, 0x27, 0x9A, 0x30, 0x1E, 0x00, 0x05, 0x00} },/* ; 00 (320x) */
+	{ {0x56, 0x27, 0x9A, 0x30, 0x1E, 0x00, 0x05, 0x00} },/* ; 01 (360x) */
+	{ {0x60, 0x31, 0x84, 0x3A, 0x88, 0x00, 0x01, 0x00} },/* ; 02 (400x) */
+	{ {0x6E, 0x3F, 0x92, 0x48, 0x96, 0x00, 0x01, 0x00} },/* ; 03 (512x) */
+	{ {0x7E, 0x4F, 0x82, 0x54, 0x06, 0x00, 0x06, 0x00} },/* ; 04 (640x) */
+	{ {0x7E, 0x4F, 0x82, 0x54, 0x06, 0x00, 0x06, 0x00} },/* ; 05 (720x) */
+	{ {0x92, 0x63, 0x96, 0x68, 0x1A, 0x00, 0x06, 0x00} },/* ; 06 (800x) */
+	{ {0xAE, 0x7F, 0x92, 0x84, 0x96, 0x00, 0x02, 0x00} },/* ; 07 (1024x) */
+	{ {0xCE, 0x9F, 0x92, 0xA5, 0x17, 0x00, 0x07, 0x00} } /* ; 08 (1280x) */
 };
 
-static struct XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11280x1024_1_Vx75[] =
-{	/* CR06,CR07,CR10,CR11,CR15,CR16,SR0A */
-    {{      0x86,0xD1,0xBC,0x80,0xBB,0xE5,0x00      }},/* ; 00 (x350) */
-    {{      0xB8,0x1F,0x90,0x84,0x8F,0xB9,0x30      }},/* ; 01 (x400) */
-    {{      0x08,0x3E,0xE0,0x84,0xDF,0x09,0x00      }},/* ; 02 (x480) */
-    {{      0x80,0xF0,0x58,0x8C,0x57,0x81,0xA0      }},/* ; 03 (x600) */
-    {{      0x28,0xF5,0x00,0x84,0xFF,0x29,0x90      }},/* ; 04 (x768) */
-    {{      0x28,0x5A,0x13,0x87,0xFF,0x29,0xA9      }} /* ; 05 (x1024) */
+/* CR06,CR07,CR10,CR11,CR15,CR16,SR0A */
+static struct XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11280x1024_1_Vx75[] = {
+	{ {0x86, 0xD1, 0xBC, 0x80, 0xBB, 0xE5, 0x00} },/* ; 00 (x350) */
+	{ {0xB8, 0x1F, 0x90, 0x84, 0x8F, 0xB9, 0x30} },/* ; 01 (x400) */
+	{ {0x08, 0x3E, 0xE0, 0x84, 0xDF, 0x09, 0x00} },/* ; 02 (x480) */
+	{ {0x80, 0xF0, 0x58, 0x8C, 0x57, 0x81, 0xA0} },/* ; 03 (x600) */
+	{ {0x28, 0xF5, 0x00, 0x84, 0xFF, 0x29, 0x90} },/* ; 04 (x768) */
+	{ {0x28, 0x5A, 0x13, 0x87, 0xFF, 0x29, 0xA9} } /* ; 05 (x1024) */
 };
-
-static struct XGI_LVDSCRT1HDataStruct XGI_LVDSCRT11280x1024_2_Hx75[] =
-{
-	/* CR00,CR02,CR03,CR04,CR05,SR0B,SR0C,SR0E */
-    {{      0x7E,0x3B,0x9A,0x44,0x12,0x00,0x01,0x00 }},/* ; 00 (320x) */
-    {{      0x7E,0x3B,0x9A,0x44,0x12,0x00,0x01,0x00 }},/* ; 01 (360x) */
-    {{      0x7E,0x40,0x84,0x49,0x91,0x00,0x01,0x00 }},/* ; 02 (400x) */
-    {{      0x7E,0x47,0x93,0x50,0x9E,0x00,0x01,0x00 }},/* ; 03 (512x) */
-    {{      0xCE,0x77,0x8A,0x80,0x8E,0x00,0x02,0x00 }},/* ; 04 (640x) */
-    {{      0xCE,0x77,0x8A,0x80,0x8E,0x00,0x02,0x00 }},/* ; 05 (720x) */
-    {{      0xCE,0x81,0x94,0x8A,0x98,0x00,0x02,0x00 }},/* ; 06 (800x) */
-    {{      0xCE,0x8F,0x82,0x98,0x06,0x00,0x07,0x00 }},/* ; 07 (1024x) */
-    {{      0xCE,0x9F,0x92,0xA8,0x16,0x00,0x07,0x00 }} /* ; 08 (1280x) */
+/* CR00,CR02,CR03,CR04,CR05,SR0B,SR0C,SR0E */
+static struct XGI_LVDSCRT1HDataStruct XGI_LVDSCRT11280x1024_2_Hx75[] = {
+	{ {0x7E, 0x3B, 0x9A, 0x44, 0x12, 0x00, 0x01, 0x00} },/* ; 00 (320x) */
+	{ {0x7E, 0x3B, 0x9A, 0x44, 0x12, 0x00, 0x01, 0x00} },/* ; 01 (360x) */
+	{ {0x7E, 0x40, 0x84, 0x49, 0x91, 0x00, 0x01, 0x00} },/* ; 02 (400x) */
+	{ {0x7E, 0x47, 0x93, 0x50, 0x9E, 0x00, 0x01, 0x00} },/* ; 03 (512x) */
+	{ {0xCE, 0x77, 0x8A, 0x80, 0x8E, 0x00, 0x02, 0x00} },/* ; 04 (640x) */
+	{ {0xCE, 0x77, 0x8A, 0x80, 0x8E, 0x00, 0x02, 0x00} },/* ; 05 (720x) */
+	{ {0xCE, 0x81, 0x94, 0x8A, 0x98, 0x00, 0x02, 0x00} },/* ; 06 (800x) */
+	{ {0xCE, 0x8F, 0x82, 0x98, 0x06, 0x00, 0x07, 0x00} },/* ; 07 (1024x) */
+	{ {0xCE, 0x9F, 0x92, 0xA8, 0x16, 0x00, 0x07, 0x00} } /* ; 08 (1280x) */
 };
 
-static struct XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11280x1024_2_Vx75[] =
-{
-        /* CR06,CR07,CR10,CR11,CR15,CR16,SR0A */
-     {{     0x28,0xD2,0xAF,0x83,0xAE,0xD8,0xA1     }},/* ; 00 (x350) */
-     {{     0x28,0xD2,0xC8,0x8C,0xC7,0xF2,0x81     }},/* ; 01 (x400) */
-     {{     0x28,0xD2,0xF0,0x84,0xEF,0x1A,0xB1     }},/* ; 02 (x480) */
-     {{     0x28,0xDE,0x2C,0x8F,0x2B,0x56,0x91     }},/* ; 03 (x600) */
-     {{     0x28,0xDE,0x80,0x83,0x7F,0xAA,0x91     }},/* ; 04 (x768) */
-     {{     0x28,0x5A,0x13,0x87,0xFF,0x29,0xA9     }} /* ; 05 (x1024) */
+/* CR06,CR07,CR10,CR11,CR15,CR16,SR0A */
+static struct XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11280x1024_2_Vx75[] = {
+	{ {0x28, 0xD2, 0xAF, 0x83, 0xAE, 0xD8, 0xA1} },/* ; 00 (x350) */
+	{ {0x28, 0xD2, 0xC8, 0x8C, 0xC7, 0xF2, 0x81} },/* ; 01 (x400) */
+	{ {0x28, 0xD2, 0xF0, 0x84, 0xEF, 0x1A, 0xB1} },/* ; 02 (x480) */
+	{ {0x28, 0xDE, 0x2C, 0x8F, 0x2B, 0x56, 0x91} },/* ; 03 (x600) */
+	{ {0x28, 0xDE, 0x80, 0x83, 0x7F, 0xAA, 0x91} },/* ; 04 (x768) */
+	{ {0x28, 0x5A, 0x13, 0x87, 0xFF, 0x29, 0xA9} } /* ; 05 (x1024) */
 };
 
 #if 0
-static struct XGI_LVDSCRT1DataStruct  XGI_CHTVCRT1UNTSC[] =
-{
- {{0x64,0x4f,0x88,0x56,0x9f,0x56,0x3e,
-    0xe8,0x84,0x8f,0x57,0x20,0x00,0x01,0x00 }},
- {{0x64,0x4f,0x88,0x56,0x9f,0x56,0x3e,
-    0xd0,0x82,0x5d,0x57,0x00,0x00,0x01,0x00 }},
- {{0x64,0x4f,0x88,0x56,0x9f,0x56,0x3e,
-    0xe8,0x84,0x8f,0x57,0x20,0x00,0x01,0x00 }},
- {{0x64,0x4f,0x88,0x56,0x9f,0x56,0x3e,
-    0xd0,0x82,0x5d,0x57,0x00,0x00,0x01,0x00 }},
- {{0x5d,0x4f,0x81,0x53,0x9c,0x56,0xba,
-    0x18,0x84,0xdf,0x57,0x00,0x00,0x01,0x00 }},
- {{0x80,0x63,0x84,0x6c,0x17,0xec,0xf0,
-   0x90,0x8c,0x57,0xed,0x20,0x00,0x06,0x01 }}
+static struct XGI_LVDSCRT1DataStruct  XGI_CHTVCRT1UNTSC[] = {
+	{ {0x64, 0x4f, 0x88, 0x56, 0x9f, 0x56, 0x3e,
+	  0xe8, 0x84, 0x8f, 0x57, 0x20, 0x00, 0x01, 0x00 } },
+	{ {0x64, 0x4f, 0x88, 0x56, 0x9f, 0x56, 0x3e,
+	  0xd0, 0x82, 0x5d, 0x57, 0x00, 0x00, 0x01, 0x00 } },
+	{ {0x64, 0x4f, 0x88, 0x56, 0x9f, 0x56, 0x3e,
+	  0xe8, 0x84, 0x8f, 0x57, 0x20, 0x00, 0x01, 0x00 } },
+	{ {0x64, 0x4f, 0x88, 0x56, 0x9f, 0x56, 0x3e,
+	  0xd0, 0x82, 0x5d, 0x57, 0x00, 0x00, 0x01, 0x00 } },
+	{ {0x5d, 0x4f, 0x81, 0x53, 0x9c, 0x56, 0xba,
+	  0x18, 0x84, 0xdf, 0x57, 0x00, 0x00, 0x01, 0x00 } },
+	{ {0x80, 0x63, 0x84, 0x6c, 0x17, 0xec, 0xf0,
+	  x90, 0x8c, 0x57, 0xed, 0x20, 0x00, 0x06, 0x01 } }
 };
 
-static struct XGI_LVDSCRT1DataStruct  XGI_CHTVCRT1ONTSC[] =
-{
- {{0x64,0x4f,0x88,0x5a,0x9f,0x0b,0x3e,
-    0xc0,0x84,0x8f,0x0c,0x20,0x00,0x01,0x00 }},
- {{0x64,0x4f,0x88,0x5a,0x9f,0x0b,0x3e,
-    0xb0,0x8d,0x5d,0x0c,0x00,0x00,0x01,0x00 }},
- {{0x64,0x4f,0x88,0x5a,0x9f,0x0b,0x3e,
-    0xc0,0x84,0x8f,0x0c,0x20,0x00,0x01,0x00 }},
- {{0x64,0x4f,0x88,0x5a,0x9f,0x0b,0x3e,
-    0xb0,0x8d,0x5d,0x0c,0x00,0x00,0x01,0x00 }},
- {{0x5d,0x4f,0x81,0x56,0x9c,0x0b,0x3e,
-    0xe8,0x84,0xdf,0x0c,0x00,0x00,0x01,0x00 }},
- {{0x7d,0x63,0x81,0x6a,0x16,0xba,0xf0,
-   0x7f,0x86,0x57,0xbb,0x00,0x00,0x06,0x01 }}
+static struct XGI_LVDSCRT1DataStruct  XGI_CHTVCRT1ONTSC[] = {
+	{ {0x64, 0x4f, 0x88, 0x5a, 0x9f, 0x0b, 0x3e,
+	  0xc0, 0x84, 0x8f, 0x0c, 0x20, 0x00, 0x01, 0x00 } },
+	{ {0x64, 0x4f, 0x88, 0x5a, 0x9f, 0x0b, 0x3e,
+	  0xb0, 0x8d, 0x5d, 0x0c, 0x00, 0x00, 0x01, 0x00 } },
+	{ {0x64, 0x4f, 0x88, 0x5a, 0x9f, 0x0b, 0x3e,
+	  0xc0, 0x84, 0x8f, 0x0c, 0x20, 0x00, 0x01, 0x00 } },
+	{ {0x64, 0x4f, 0x88, 0x5a, 0x9f, 0x0b, 0x3e,
+	  0xb0, 0x8d, 0x5d, 0x0c, 0x00, 0x00, 0x01, 0x00 } },
+	{ {0x5d, 0x4f, 0x81, 0x56, 0x9c, 0x0b, 0x3e,
+	  0xe8, 0x84, 0xdf, 0x0c, 0x00, 0x00, 0x01, 0x00 } },
+	{ {0x7d, 0x63, 0x81, 0x6a, 0x16, 0xba, 0xf0,
+	  x7f, 0x86, 0x57, 0xbb, 0x00, 0x00, 0x06, 0x01 } }
 };
 
-static struct XGI_LVDSCRT1DataStruct  XGI_CHTVCRT1UPAL[] =
-{
- {{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
-    0xf8,0x83,0x8f,0x70,0x20,0x00,0x05,0x00 }},
- {{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
-    0xde,0x81,0x5d,0x70,0x00,0x00,0x05,0x00 }},
- {{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
-    0xf8,0x83,0x8f,0x70,0x20,0x00,0x05,0x00 }},
- {{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
-    0xde,0x81,0x5d,0x70,0x00,0x00,0x05,0x00 }},
- {{0x64,0x4f,0x88,0x55,0x80,0xec,0xba,
-    0x50,0x84,0xdf,0xed,0x00,0x00,0x05,0x00 }},
- {{0x70,0x63,0x94,0x68,0x8d,0x42,0xf1,
-   0xc8,0x8c,0x57,0xe9,0x20,0x00,0x05,0x01 }}
+static struct XGI_LVDSCRT1DataStruct  XGI_CHTVCRT1UPAL[] = {
+	{ {0x79, 0x4f, 0x9d, 0x5a, 0x90, 0x6f, 0x3e,
+	  0xf8, 0x83, 0x8f, 0x70, 0x20, 0x00, 0x05, 0x00 } },
+	{ {0x79, 0x4f, 0x9d, 0x5a, 0x90, 0x6f, 0x3e,
+	  0xde, 0x81, 0x5d, 0x70, 0x00, 0x00, 0x05, 0x00 } },
+	{ {0x79, 0x4f, 0x9d, 0x5a, 0x90, 0x6f, 0x3e,
+	  0xf8, 0x83, 0x8f, 0x70, 0x20, 0x00, 0x05, 0x00 } },
+	{ {0x79, 0x4f, 0x9d, 0x5a, 0x90, 0x6f, 0x3e,
+	  0xde, 0x81, 0x5d, 0x70, 0x00, 0x00, 0x05, 0x00 } },
+	{ {0x64, 0x4f, 0x88, 0x55, 0x80, 0xec, 0xba,
+	  0x50, 0x84, 0xdf, 0xed, 0x00, 0x00, 0x05, 0x00 } },
+	{ {0x70, 0x63, 0x94, 0x68, 0x8d, 0x42, 0xf1,
+	  xc8, 0x8c, 0x57, 0xe9, 0x20, 0x00, 0x05, 0x01 } }
 };
 
-static struct XGI_LVDSCRT1DataStruct  XGI_CHTVCRT1OPAL[] =
-{
- {{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
-    0xf0,0x83,0x8f,0x70,0x20,0x00,0x05,0x00 }},
- {{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
-    0xde,0x81,0x5d,0x70,0x00,0x00,0x05,0x00 }},
- {{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
-    0xf0,0x83,0x8f,0x70,0x20,0x00,0x05,0x00 }},
- {{0x79,0x4f,0x9d,0x5a,0x90,0x6f,0x3e,
-    0xde,0x81,0x5d,0x70,0x00,0x00,0x05,0x00 }},
- {{0x64,0x4f,0x88,0x55,0x80,0x6f,0xba,
-    0x20,0x83,0xdf,0x70,0x00,0x00,0x05,0x00 }},
- {{0x73,0x63,0x97,0x69,0x8e,0xec,0xf0,
-   0x90,0x8c,0x57,0xed,0x20,0x00,0x05,0x01 }}
+static struct XGI_LVDSCRT1DataStruct  XGI_CHTVCRT1OPAL[] = {
+	{ {0x79, 0x4f, 0x9d, 0x5a, 0x90, 0x6f, 0x3e,
+	  0xf0, 0x83, 0x8f, 0x70, 0x20, 0x00, 0x05, 0x00 } },
+	{ {0x79, 0x4f, 0x9d, 0x5a, 0x90, 0x6f, 0x3e,
+	  0xde, 0x81, 0x5d, 0x70, 0x00, 0x00, 0x05, 0x00 } },
+	{ {0x79, 0x4f, 0x9d, 0x5a, 0x90, 0x6f, 0x3e,
+	  0xf0, 0x83, 0x8f, 0x70, 0x20, 0x00, 0x05, 0x00 } },
+	{ {0x79, 0x4f, 0x9d, 0x5a, 0x90, 0x6f, 0x3e,
+	  0xde, 0x81, 0x5d, 0x70, 0x00, 0x00, 0x05, 0x00 } },
+	{ {0x64, 0x4f, 0x88, 0x55, 0x80, 0x6f, 0xba,
+	  0x20, 0x83, 0xdf, 0x70, 0x00, 0x00, 0x05, 0x00 } },
+	{ {0x73, 0x63, 0x97, 0x69, 0x8e, 0xec, 0xf0,
+	  x90, 0x8c, 0x57, 0xed, 0x20, 0x00, 0x05, 0x01 } }
 };
 #endif
 
 /*add for new UNIVGABIOS*/
-static struct XGI330_LCDDataTablStruct XGI_LCDDataTable[] =
-{
-  {Panel1024x768,0x0019,0x0001,0},  /* XGI_ExtLCD1024x768Data */
-  {Panel1024x768,0x0019,0x0000,1},  /* XGI_StLCD1024x768Data */
-  {Panel1024x768,0x0018,0x0010,2},  /* XGI_CetLCD1024x768Data */
-  {Panel1280x1024,0x0019,0x0001,3},  /* XGI_ExtLCD1280x1024Data */
-  {Panel1280x1024,0x0019,0x0000,4},  /* XGI_StLCD1280x1024Data */
-  {Panel1280x1024,0x0018,0x0010,5},  /* XGI_CetLCD1280x1024Data */
-  {Panel1400x1050,0x0019,0x0001,6},  /* XGI_ExtLCD1400x1050Data */
-  {Panel1400x1050,0x0019,0x0000,7},  /* XGI_StLCD1400x1050Data */
-  {Panel1400x1050,0x0018,0x0010,8},  /* XGI_CetLCD1400x1050Data */
-  {Panel1600x1200,0x0019,0x0001,9},   /* XGI_ExtLCD1600x1200Data */
-  {Panel1600x1200,0x0019,0x0000,10},  /* XGI_StLCD1600x1200Data */
-  {PanelRef60Hz,0x0008,0x0008,11},  	/* XGI_NoScalingData */
-  {Panel1024x768x75,0x0019,0x0001,12}, 	/* XGI_ExtLCD1024x768x75Data */
-  {Panel1024x768x75,0x0019,0x0000,13}, 	/* XGI_StLCD1024x768x75Data */
-  {Panel1024x768x75,0x0018,0x0010,14}, 	/* XGI_CetLCD1024x768x75Data */
-  {Panel1280x1024x75,0x0019,0x0001,15}, /* XGI_ExtLCD1280x1024x75Data */
-  {Panel1280x1024x75,0x0019,0x0000,16}, /* XGI_StLCD1280x1024x75Data */
-  {Panel1280x1024x75,0x0018,0x0010,17}, /* XGI_CetLCD1280x1024x75Data */
-  {PanelRef75Hz,0x0008,0x0008,18},	/* XGI_NoScalingDatax75 */
-  {0xFF,0x0000,0x0000,0}   		/* End of table */
+static struct XGI330_LCDDataTablStruct XGI_LCDDataTable[] = {
+	{Panel1024x768, 0x0019, 0x0001, 0}, /* XGI_ExtLCD1024x768Data */
+	{Panel1024x768, 0x0019, 0x0000, 1}, /* XGI_StLCD1024x768Data */
+	{Panel1024x768, 0x0018, 0x0010, 2}, /* XGI_CetLCD1024x768Data */
+	{Panel1280x1024, 0x0019, 0x0001, 3}, /* XGI_ExtLCD1280x1024Data */
+	{Panel1280x1024, 0x0019, 0x0000, 4}, /* XGI_StLCD1280x1024Data */
+	{Panel1280x1024, 0x0018, 0x0010, 5}, /* XGI_CetLCD1280x1024Data */
+	{Panel1400x1050, 0x0019, 0x0001, 6}, /* XGI_ExtLCD1400x1050Data */
+	{Panel1400x1050, 0x0019, 0x0000, 7}, /* XGI_StLCD1400x1050Data */
+	{Panel1400x1050, 0x0018, 0x0010, 8}, /* XGI_CetLCD1400x1050Data */
+	{Panel1600x1200, 0x0019, 0x0001, 9}, /* XGI_ExtLCD1600x1200Data */
+	{Panel1600x1200, 0x0019, 0x0000, 10}, /* XGI_StLCD1600x1200Data */
+	{PanelRef60Hz, 0x0008, 0x0008, 11}, /* XGI_NoScalingData */
+	{Panel1024x768x75, 0x0019, 0x0001, 12}, /* XGI_ExtLCD1024x768x75Data */
+	{Panel1024x768x75, 0x0019, 0x0000, 13}, /* XGI_StLCD1024x768x75Data */
+	{Panel1024x768x75, 0x0018, 0x0010, 14}, /* XGI_CetLCD1024x768x75Data */
+	{Panel1280x1024x75, 0x0019, 0x0001, 15}, /* XGI_ExtLCD1280x1024x75Data*/
+	{Panel1280x1024x75, 0x0019, 0x0000, 16}, /* XGI_StLCD1280x1024x75Data */
+	{Panel1280x1024x75, 0x0018, 0x0010, 17}, /* XGI_CetLCD1280x1024x75Data*/
+	{PanelRef75Hz, 0x0008, 0x0008, 18}, /* XGI_NoScalingDatax75 */
+	{0xFF, 0x0000, 0x0000, 0} /* End of table */
 };
 
-static struct XGI330_LCDDataTablStruct XGI_LCDDesDataTable[] =
-{
-  {Panel1024x768,0x0019,0x0001,0}, /* XGI_ExtLCDDes1024x768Data */
-  {Panel1024x768,0x0019,0x0000,1}, /* XGI_StLCDDes1024x768Data */
-  {Panel1024x768,0x0018,0x0010,2}, /* XGI_CetLCDDes1024x768Data */
-  {Panel1280x1024,0x0019,0x0001,3}, /* XGI_ExtLCDDes1280x1024Data */
-  {Panel1280x1024,0x0019,0x0000,4}, /* XGI_StLCDDes1280x1024Data */
-  {Panel1280x1024,0x0018,0x0010,5}, /* XGI_CetLCDDes1280x1024Data */
-  {Panel1400x1050,0x0019,0x0001,6}, /* XGI_ExtLCDDes1400x1050Data */
-  {Panel1400x1050,0x0019,0x0000,7}, /* XGI_StLCDDes1400x1050Data */
-  {Panel1400x1050,0x0418,0x0010,8}, /* XGI_CetLCDDes1400x1050Data */
-  {Panel1400x1050,0x0418,0x0410,9}, /* XGI_CetLCDDes1400x1050Data2 */
-  {Panel1600x1200,0x0019,0x0001,10}, /* XGI_ExtLCDDes1600x1200Data */
-  {Panel1600x1200,0x0019,0x0000,11}, /* XGI_StLCDDes1600x1200Data */
-  {PanelRef60Hz,0x0008,0x0008,12}, 	/* XGI_NoScalingDesData */
-  {Panel1024x768x75,0x0019,0x0001,13}, 	/* XGI_ExtLCDDes1024x768x75Data */
-  {Panel1024x768x75,0x0019,0x0000,14},	/* XGI_StLCDDes1024x768x75Data */
-  {Panel1024x768x75,0x0018,0x0010,15},  /* XGI_CetLCDDes1024x768x75Data */
-  {Panel1280x1024x75,0x0019,0x0001,16},	/* XGI_ExtLCDDes1280x1024x75Data */
-  {Panel1280x1024x75,0x0019,0x0000,17}, /* XGI_StLCDDes1280x1024x75Data */
-  {Panel1280x1024x75,0x0018,0x0010,18},	/* XGI_CetLCDDes1280x1024x75Data */
-  {PanelRef75Hz,0x0008,0x0008,19},	/* XGI_NoScalingDesDatax75 */
-  {0xFF,0x0000,0x0000,0}
+static struct XGI330_LCDDataTablStruct XGI_LCDDesDataTable[] = {
+	{Panel1024x768, 0x0019, 0x0001, 0}, /* XGI_ExtLCDDes1024x768Data */
+	{Panel1024x768, 0x0019, 0x0000, 1}, /* XGI_StLCDDes1024x768Data */
+	{Panel1024x768, 0x0018, 0x0010, 2}, /* XGI_CetLCDDes1024x768Data */
+	{Panel1280x1024, 0x0019, 0x0001, 3}, /* XGI_ExtLCDDes1280x1024Data */
+	{Panel1280x1024, 0x0019, 0x0000, 4}, /* XGI_StLCDDes1280x1024Data */
+	{Panel1280x1024, 0x0018, 0x0010, 5}, /* XGI_CetLCDDes1280x1024Data */
+	{Panel1400x1050, 0x0019, 0x0001, 6}, /* XGI_ExtLCDDes1400x1050Data */
+	{Panel1400x1050, 0x0019, 0x0000, 7}, /* XGI_StLCDDes1400x1050Data */
+	{Panel1400x1050, 0x0418, 0x0010, 8}, /* XGI_CetLCDDes1400x1050Data */
+	{Panel1400x1050, 0x0418, 0x0410, 9}, /* XGI_CetLCDDes1400x1050Data2 */
+	{Panel1600x1200, 0x0019, 0x0001, 10}, /* XGI_ExtLCDDes1600x1200Data */
+	{Panel1600x1200, 0x0019, 0x0000, 11}, /* XGI_StLCDDes1600x1200Data */
+	{PanelRef60Hz, 0x0008, 0x0008, 12}, /* XGI_NoScalingDesData */
+	{Panel1024x768x75, 0x0019, 0x0001, 13}, /*XGI_ExtLCDDes1024x768x75Data*/
+	{Panel1024x768x75, 0x0019, 0x0000, 14}, /* XGI_StLCDDes1024x768x75Data*/
+	{Panel1024x768x75, 0x0018, 0x0010, 15}, /*XGI_CetLCDDes1024x768x75Data*/
+	/* XGI_ExtLCDDes1280x1024x75Data */
+	{Panel1280x1024x75, 0x0019, 0x0001, 16},
+	/* XGI_StLCDDes1280x1024x75Data */
+	{Panel1280x1024x75, 0x0019, 0x0000, 17},
+	/* XGI_CetLCDDes1280x1024x75Data */
+	{Panel1280x1024x75, 0x0018, 0x0010, 18},
+	{PanelRef75Hz, 0x0008, 0x0008, 19}, /* XGI_NoScalingDesDatax75 */
+	{0xFF, 0x0000, 0x0000, 0}
 };
 
-static struct XGI330_LCDDataTablStruct XGI_EPLLCDCRT1Ptr_H[] =
-{
-  {Panel1024x768,0x0018,0x0000,0}, /* XGI_LVDSCRT11024x768_1_H */
-  {Panel1024x768,0x0018,0x0010,1}, /* XGI_LVDSCRT11024x768_2_H */
-  {Panel1280x1024,0x0018,0x0000,2}, /* XGI_LVDSCRT11280x1024_1_H */
-  {Panel1280x1024,0x0018,0x0010,3}, /* XGI_LVDSCRT11280x1024_2_H */
-  {Panel1400x1050,0x0018,0x0000,4}, /* XGI_LVDSCRT11400x1050_1_H */
-  {Panel1400x1050,0x0018,0x0010,5}, /* XGI_LVDSCRT11400x1050_2_H */
-  {Panel1600x1200,0x0018,0x0000,6},  /* XGI_LVDSCRT11600x1200_1_H */
-  {Panel1024x768x75,0x0018,0x0000,7},	/* XGI_LVDSCRT11024x768_1_Hx75 */
-  {Panel1024x768x75,0x0018,0x0010,8},	/* XGI_LVDSCRT11024x768_2_Hx75 */
-  {Panel1280x1024x75,0x0018,0x0000,9},	/* XGI_LVDSCRT11280x1024_1_Hx75 */
-  {Panel1280x1024x75,0x0018,0x0010,10},	/* XGI_LVDSCRT11280x1024_2_Hx75 */
-  {0xFF,0x0000,0x0000,0}
+static struct XGI330_LCDDataTablStruct XGI_EPLLCDCRT1Ptr_H[] = {
+	{Panel1024x768, 0x0018, 0x0000, 0}, /* XGI_LVDSCRT11024x768_1_H */
+	{Panel1024x768, 0x0018, 0x0010, 1}, /* XGI_LVDSCRT11024x768_2_H */
+	{Panel1280x1024, 0x0018, 0x0000, 2}, /* XGI_LVDSCRT11280x1024_1_H */
+	{Panel1280x1024, 0x0018, 0x0010, 3}, /* XGI_LVDSCRT11280x1024_2_H */
+	{Panel1400x1050, 0x0018, 0x0000, 4}, /* XGI_LVDSCRT11400x1050_1_H */
+	{Panel1400x1050, 0x0018, 0x0010, 5}, /* XGI_LVDSCRT11400x1050_2_H */
+	{Panel1600x1200, 0x0018, 0x0000, 6}, /* XGI_LVDSCRT11600x1200_1_H */
+	{Panel1024x768x75, 0x0018, 0x0000, 7}, /* XGI_LVDSCRT11024x768_1_Hx75 */
+	{Panel1024x768x75, 0x0018, 0x0010, 8}, /* XGI_LVDSCRT11024x768_2_Hx75 */
+	{Panel1280x1024x75, 0x0018, 0x0000, 9}, /*XGI_LVDSCRT11280x1024_1_Hx75*/
+	{Panel1280x1024x75, 0x0018, 0x0010, 10},/*XGI_LVDSCRT11280x1024_2_Hx75*/
+	{0xFF, 0x0000, 0x0000, 0}
 };
 
-static struct XGI330_LCDDataTablStruct XGI_EPLLCDCRT1Ptr_V[] =
-{
-  {Panel1024x768,0x0018,0x0000,0}, /* XGI_LVDSCRT11024x768_1_V */
-  {Panel1024x768,0x0018,0x0010,1}, /* XGI_LVDSCRT11024x768_2_V */
-  {Panel1280x1024,0x0018,0x0000,2}, /* XGI_LVDSCRT11280x1024_1_V */
-  {Panel1280x1024,0x0018,0x0010,3}, /* XGI_LVDSCRT11280x1024_2_V */
-  {Panel1400x1050,0x0018,0x0000,4}, /* XGI_LVDSCRT11400x1050_1_V */
-  {Panel1400x1050,0x0018,0x0010,5}, /* XGI_LVDSCRT11400x1050_2_V */
-  {Panel1600x1200,0x0018,0x0000,6}, /* XGI_LVDSCRT11600x1200_1_V */
-  {Panel1024x768x75,0x0018,0x0000,7},	/* XGI_LVDSCRT11024x768_1_Vx75 */
-  {Panel1024x768x75,0x0018,0x0010,8},	/* XGI_LVDSCRT11024x768_2_Vx75 */
-  {Panel1280x1024x75,0x0018,0x0000,9},	/* XGI_LVDSCRT11280x1024_1_Vx75 */
-  {Panel1280x1024x75,0x0018,0x0010,10},	/* XGI_LVDSCRT11280x1024_2_Vx75 */
-  {0xFF,0x0000,0x0000,0}
+static struct XGI330_LCDDataTablStruct XGI_EPLLCDCRT1Ptr_V[] = {
+	{Panel1024x768, 0x0018, 0x0000, 0}, /* XGI_LVDSCRT11024x768_1_V */
+	{Panel1024x768, 0x0018, 0x0010, 1}, /* XGI_LVDSCRT11024x768_2_V */
+	{Panel1280x1024, 0x0018, 0x0000, 2}, /* XGI_LVDSCRT11280x1024_1_V */
+	{Panel1280x1024, 0x0018, 0x0010, 3}, /* XGI_LVDSCRT11280x1024_2_V */
+	{Panel1400x1050, 0x0018, 0x0000, 4}, /* XGI_LVDSCRT11400x1050_1_V */
+	{Panel1400x1050, 0x0018, 0x0010, 5}, /* XGI_LVDSCRT11400x1050_2_V */
+	{Panel1600x1200, 0x0018, 0x0000, 6}, /* XGI_LVDSCRT11600x1200_1_V */
+	{Panel1024x768x75, 0x0018, 0x0000, 7}, /* XGI_LVDSCRT11024x768_1_Vx75 */
+	{Panel1024x768x75, 0x0018, 0x0010, 8}, /* XGI_LVDSCRT11024x768_2_Vx75 */
+	{Panel1280x1024x75, 0x0018, 0x0000, 9}, /*XGI_LVDSCRT11280x1024_1_Vx75*/
+	{Panel1280x1024x75, 0x0018, 0x0010, 10},/*XGI_LVDSCRT11280x1024_2_Vx75*/
+	{0xFF, 0x0000, 0x0000, 0}
 };
 
-static struct XGI330_LCDDataTablStruct XGI_EPLLCDDataPtr[] =
-{
-  {Panel1024x768,0x0018,0x0000,0}, /* XGI_LVDS1024x768Data_1 */
-  {Panel1024x768,0x0018,0x0010,1}, /* XGI_LVDS1024x768Data_2 */
-  {Panel1280x1024,0x0018,0x0000,2}, /* XGI_LVDS1280x1024Data_1 */
-  {Panel1280x1024,0x0018,0x0010,3}, /* XGI_LVDS1280x1024Data_2 */
-  {Panel1400x1050,0x0018,0x0000,4}, /* XGI_LVDS1400x1050Data_1 */
-  {Panel1400x1050,0x0018,0x0010,5}, /* XGI_LVDS1400x1050Data_2 */
-  {Panel1600x1200,0x0018,0x0000,6}, /* XGI_LVDS1600x1200Data_1 */
-  {PanelRef60Hz,0x0008,0x0008,7}, /* XGI_LVDSNoScalingData */
-  {Panel1024x768x75,0x0018,0x0000,8},	/* XGI_LVDS1024x768Data_1x75 */
-  {Panel1024x768x75,0x0018,0x0010,9},	/* XGI_LVDS1024x768Data_2x75 */
-  {Panel1280x1024x75,0x0018,0x0000,10},	/* XGI_LVDS1280x1024Data_1x75 */
-  {Panel1280x1024x75,0x0018,0x0010,11}, /* XGI_LVDS1280x1024Data_2x75 */
-  {PanelRef75Hz,0x0008,0x0008,12},	/* XGI_LVDSNoScalingDatax75 */
-  {0xFF,0x0000,0x0000,0}
+static struct XGI330_LCDDataTablStruct XGI_EPLLCDDataPtr[] = {
+	{Panel1024x768, 0x0018, 0x0000, 0}, /* XGI_LVDS1024x768Data_1 */
+	{Panel1024x768, 0x0018, 0x0010, 1}, /* XGI_LVDS1024x768Data_2 */
+	{Panel1280x1024, 0x0018, 0x0000, 2}, /* XGI_LVDS1280x1024Data_1 */
+	{Panel1280x1024, 0x0018, 0x0010, 3}, /* XGI_LVDS1280x1024Data_2 */
+	{Panel1400x1050, 0x0018, 0x0000, 4}, /* XGI_LVDS1400x1050Data_1 */
+	{Panel1400x1050, 0x0018, 0x0010, 5}, /* XGI_LVDS1400x1050Data_2 */
+	{Panel1600x1200, 0x0018, 0x0000, 6}, /* XGI_LVDS1600x1200Data_1 */
+	{PanelRef60Hz, 0x0008, 0x0008, 7}, /* XGI_LVDSNoScalingData */
+	{Panel1024x768x75, 0x0018, 0x0000, 8}, /* XGI_LVDS1024x768Data_1x75 */
+	{Panel1024x768x75, 0x0018, 0x0010, 9}, /* XGI_LVDS1024x768Data_2x75 */
+	{Panel1280x1024x75, 0x0018, 0x0000, 10}, /* XGI_LVDS1280x1024Data_1x75*/
+	{Panel1280x1024x75, 0x0018, 0x0010, 11},  /*XGI_LVDS1280x1024Data_2x75*/
+	{PanelRef75Hz, 0x0008, 0x0008, 12}, /* XGI_LVDSNoScalingDatax75 */
+	{0xFF, 0x0000, 0x0000, 0}
 };
 
-static struct XGI330_LCDDataTablStruct XGI_EPLLCDDesDataPtr[] =
-{
-  {Panel1024x768,0x0018,0x0000,0}, /* XGI_LVDS1024x768Des_1 */
-  {Panel1024x768,0x0618,0x0410,1}, /* XGI_LVDS1024x768Des_3 */
-  {Panel1024x768,0x0018,0x0010,2}, /* XGI_LVDS1024x768Des_2 */
-  {Panel1280x1024,0x0018,0x0000,3}, /* XGI_LVDS1280x1024Des_1 */
-  {Panel1280x1024,0x0018,0x0010,4}, /* XGI_LVDS1280x1024Des_2 */
-  {Panel1400x1050,0x0018,0x0000,5}, /* XGI_LVDS1400x1050Des_1 */
-  {Panel1400x1050,0x0018,0x0010,6}, /* XGI_LVDS1400x1050Des_2 */
-  {Panel1600x1200,0x0018,0x0000,7}, /* XGI_LVDS1600x1200Des_1 */
-  {PanelRef60Hz,0x0008,0x0008,8}, 	/* XGI_LVDSNoScalingDesData */
-  {Panel1024x768x75,0x0018,0x0000,9},	/* XGI_LVDS1024x768Des_1x75 */
-  {Panel1024x768x75,0x0618,0x0410,10},	/* XGI_LVDS1024x768Des_3x75 */
-  {Panel1024x768x75,0x0018,0x0010,11},	/* XGI_LVDS1024x768Des_2x75 */
-  {Panel1280x1024x75,0x0018,0x0000,12},	/* XGI_LVDS1280x1024Des_1x75 */
-  {Panel1280x1024x75,0x0018,0x0010,13},	/* XGI_LVDS1280x1024Des_2x75 */
-  {PanelRef75Hz,0x0008,0x0008,14},	/* XGI_LVDSNoScalingDesDatax75 */
-  {0xFF,0x0000,0x0000,0}
+static struct XGI330_LCDDataTablStruct XGI_EPLLCDDesDataPtr[] = {
+	{Panel1024x768, 0x0018, 0x0000, 0}, /* XGI_LVDS1024x768Des_1 */
+	{Panel1024x768, 0x0618, 0x0410, 1}, /* XGI_LVDS1024x768Des_3 */
+	{Panel1024x768, 0x0018, 0x0010, 2}, /* XGI_LVDS1024x768Des_2 */
+	{Panel1280x1024, 0x0018, 0x0000, 3}, /* XGI_LVDS1280x1024Des_1 */
+	{Panel1280x1024, 0x0018, 0x0010, 4}, /* XGI_LVDS1280x1024Des_2 */
+	{Panel1400x1050, 0x0018, 0x0000, 5}, /* XGI_LVDS1400x1050Des_1 */
+	{Panel1400x1050, 0x0018, 0x0010, 6}, /* XGI_LVDS1400x1050Des_2 */
+	{Panel1600x1200, 0x0018, 0x0000, 7}, /* XGI_LVDS1600x1200Des_1 */
+	{PanelRef60Hz, 0x0008, 0x0008, 8},  /* XGI_LVDSNoScalingDesData */
+	{Panel1024x768x75, 0x0018, 0x0000, 9}, /* XGI_LVDS1024x768Des_1x75 */
+	{Panel1024x768x75, 0x0618, 0x0410, 10}, /* XGI_LVDS1024x768Des_3x75 */
+	{Panel1024x768x75, 0x0018, 0x0010, 11}, /* XGI_LVDS1024x768Des_2x75 */
+	{Panel1280x1024x75, 0x0018, 0x0000, 12}, /* XGI_LVDS1280x1024Des_1x75 */
+	{Panel1280x1024x75, 0x0018, 0x0010, 13}, /* XGI_LVDS1280x1024Des_2x75 */
+	{PanelRef75Hz, 0x0008, 0x0008, 14}, /* XGI_LVDSNoScalingDesDatax75 */
+	{0xFF, 0x0000, 0x0000, 0}
 };
 
-static struct XGI330_LCDDataTablStruct XGI_EPLCHLCDRegPtr[] =
-{
-  {Panel1024x768,0x0000,0x0000,0}, /* XGI_CH7017LV1024x768 */
-  {Panel1400x1050,0x0000,0x0000,1}, /* XGI_CH7017LV1400x1050 */
-  {0xFF,0x0000,0x0000,0}
+static struct XGI330_LCDDataTablStruct XGI_EPLCHLCDRegPtr[] = {
+	{Panel1024x768, 0x0000, 0x0000, 0}, /* XGI_CH7017LV1024x768 */
+	{Panel1400x1050, 0x0000, 0x0000, 1}, /* XGI_CH7017LV1400x1050 */
+	{0xFF, 0x0000, 0x0000, 0}
 };
 
-static struct XGI330_TVDataTablStruct XGI_TVDataTable[] =
-{
- {0x09E1,0x0001,0},	/* XGI_ExtPALData */
- {0x09E1,0x0000,1},	/* XGI_ExtNTSCData */
- {0x09E1,0x0801,2},	/* XGI_StPALData */
- {0x09E1,0x0800,3},	/* XGI_StNTSCData */
- {0x49E0,0x0100,4},	/* XGI_ExtHiTVData */
- {0x49E0,0x4100,5},	/* XGI_St2HiTVData */
- {0x49E0,0x4900,13},	/* XGI_St1HiTVData */
- {0x09E0,0x0020,6},	/* XGI_ExtYPbPr525iData */
- {0x09E0,0x0040,7},	/* XGI_ExtYPbPr525pData */
- {0x09E0,0x0080,8},	/* XGI_ExtYPbPr750pData */
- {0x09E0,0x0820,9},	/* XGI_StYPbPr525iData */
- {0x09E0,0x0840,10},	/* XGI_StYPbPr525pData */
- {0x09E0,0x0880,11}, 	/* XGI_StYPbPr750pData */
- {0xffff,0x0000,12}  	/* END */
+static struct XGI330_TVDataTablStruct XGI_TVDataTable[] = {
+	{0x09E1, 0x0001, 0}, /* XGI_ExtPALData */
+	{0x09E1, 0x0000, 1}, /* XGI_ExtNTSCData */
+	{0x09E1, 0x0801, 2}, /* XGI_StPALData */
+	{0x09E1, 0x0800, 3}, /* XGI_StNTSCData */
+	{0x49E0, 0x0100, 4}, /* XGI_ExtHiTVData */
+	{0x49E0, 0x4100, 5}, /* XGI_St2HiTVData */
+	{0x49E0, 0x4900, 13}, /* XGI_St1HiTVData */
+	{0x09E0, 0x0020, 6}, /* XGI_ExtYPbPr525iData */
+	{0x09E0, 0x0040, 7}, /* XGI_ExtYPbPr525pData */
+	{0x09E0, 0x0080, 8}, /* XGI_ExtYPbPr750pData */
+	{0x09E0, 0x0820, 9}, /* XGI_StYPbPr525iData */
+	{0x09E0, 0x0840, 10}, /* XGI_StYPbPr525pData */
+	{0x09E0, 0x0880, 11}, /* XGI_StYPbPr750pData */
+	{0xffff, 0x0000, 12}  /* END */
 };
 
 #if 0
-static unsigned short TVLenList[] =
-{
-   LVDSCRT1Len_H,
-   LVDSCRT1Len_V,
-   LVDSDataLen,
-   0,
-   TVDataLen,
-   0,
-   0,
-   CHTVRegLen
-} ;
+static unsigned short TVLenList[] = {
+	LVDSCRT1Len_H,
+	LVDSCRT1Len_V,
+	LVDSDataLen,
+	0,
+	TVDataLen,
+	0,
+	0,
+	CHTVRegLen
+};
 #endif
 
 /* Chrontel 7017 TV CRT1 Timing List */
-static struct XGI330_TVDataTablStruct XGI_EPLCHTVCRT1Ptr[] =
-{
-  {0x0011,0x0000,0}, /* XGI_CHTVCRT1UNTSC */
-  {0x0011,0x0010,1}, /* XGI_CHTVCRT1ONTSC */
-  {0x0011,0x0001,2}, /* XGI_CHTVCRT1UPAL */
-  {0x0011,0x0011,3}, /* XGI_CHTVCRT1OPAL */
-  {0xFFFF,0x0000,4}
+static struct XGI330_TVDataTablStruct XGI_EPLCHTVCRT1Ptr[] = {
+	{0x0011, 0x0000, 0}, /* XGI_CHTVCRT1UNTSC */
+	{0x0011, 0x0010, 1}, /* XGI_CHTVCRT1ONTSC */
+	{0x0011, 0x0001, 2}, /* XGI_CHTVCRT1UPAL */
+	{0x0011, 0x0011, 3}, /* XGI_CHTVCRT1OPAL */
+	{0xFFFF, 0x0000, 4}
 };
 
 /* ;;Chrontel 7017 TV Timing List */
-static struct XGI330_TVDataTablStruct XGI_EPLCHTVDataPtr[] =
-{
-  {0x0011,0x0000,0}, /* XGI_CHTVUNTSCData */
-  {0x0011,0x0010,1}, /* XGI_CHTVONTSCData */
-  {0x0011,0x0001,2}, /* XGI_CHTVUPALData */
-  {0x0011,0x0011,3}, /* XGI_CHTVOPALData */
-  {0xFFFF,0x0000,4}
+static struct XGI330_TVDataTablStruct XGI_EPLCHTVDataPtr[] = {
+	{0x0011, 0x0000, 0}, /* XGI_CHTVUNTSCData */
+	{0x0011, 0x0010, 1}, /* XGI_CHTVONTSCData */
+	{0x0011, 0x0001, 2}, /* XGI_CHTVUPALData */
+	{0x0011, 0x0011, 3}, /* XGI_CHTVOPALData */
+	{0xFFFF, 0x0000, 4}
 };
 
 /* ;;Chrontel 7017 TV Reg. List */
-static struct XGI330_TVDataTablStruct XGI_EPLCHTVRegPtr[] =
-{
-  {0x0011,0x0000,0}, /* XGI_CHTVRegUNTSC */
-  {0x0011,0x0010,1}, /* XGI_CHTVRegONTSC */
-  {0x0011,0x0001,2}, /* XGI_CHTVRegUPAL */
-  {0x0011,0x0011,3}, /* XGI_CHTVRegOPAL */
-  {0xFFFF,0x0000,4}
+static struct XGI330_TVDataTablStruct XGI_EPLCHTVRegPtr[] = {
+	{0x0011, 0x0000, 0}, /* XGI_CHTVRegUNTSC */
+	{0x0011, 0x0010, 1}, /* XGI_CHTVRegONTSC */
+	{0x0011, 0x0001, 2}, /* XGI_CHTVRegUPAL */
+	{0x0011, 0x0011, 3}, /* XGI_CHTVRegOPAL */
+	{0xFFFF, 0x0000, 4}
 };
 
-static unsigned short LCDLenList[] =
-{
-   LVDSCRT1Len_H,
-   LVDSCRT1Len_V,
-   LVDSDataLen,
-   LCDDesDataLen,
-   LCDDataLen,
-   LCDDesDataLen,
-   0,
-   LCDDesDataLen,
-   LCDDesDataLen,
-   0
-} ;
+static unsigned short LCDLenList[] = {
+	LVDSCRT1Len_H,
+	LVDSCRT1Len_V,
+	LVDSDataLen,
+	LCDDesDataLen,
+	LCDDataLen,
+	LCDDesDataLen,
+	0,
+	LCDDesDataLen,
+	LCDDesDataLen,
+	0
+};
 
 #if 0
-static struct XGI330_LCDCapStruct  XGI660_LCDDLCapList[] =  /* 660, Dual link */
-{
+/* 660, Dual link */
+static struct XGI330_LCDCapStruct  XGI660_LCDDLCapList[] = {
 /* LCDCap1024x768 */
-		{Panel1024x768, DefaultLCDCap, 0, 0x014, 0x88, 0x06, VCLK65,
-		 0x6C, 0xC3, 0x35, 0x62, 0x02, 0x14, 0x0A, 0x02, 0x00,
-		 0x30, 0x10, 0x5A, 0x10, 0x10, 0x0A, 0xC0, 0x28, 0x10},
+	{Panel1024x768, DefaultLCDCap, 0, 0x014, 0x88, 0x06, VCLK65,
+	 0x6C, 0xC3, 0x35, 0x62, 0x02, 0x14, 0x0A, 0x02, 0x00,
+	 0x30, 0x10, 0x5A, 0x10, 0x10, 0x0A, 0xC0, 0x28, 0x10},
 /* LCDCap1280x1024 */
-                {Panel1280x1024, LCDDualLink+DefaultLCDCap, StLCDBToA, 0x053, 0x70, 0x03, VCLK108_2,
-		 0x70, 0x44, 0xF8, 0x2F, 0x02, 0x14, 0x0A, 0x02, 0x00,
-		 0x30, 0x10, 0x5A, 0x10, 0x10, 0x0A, 0xC0, 0x30, 0x10},
+	{Panel1280x1024, LCDDualLink+DefaultLCDCap, StLCDBToA,
+	0x053, 0x70, 0x03, VCLK108_2,
+	 0x70, 0x44, 0xF8, 0x2F, 0x02, 0x14, 0x0A, 0x02, 0x00,
+	 0x30, 0x10, 0x5A, 0x10, 0x10, 0x0A, 0xC0, 0x30, 0x10},
 /* LCDCap1400x1050 */
-                {Panel1400x1050, LCDDualLink+DefaultLCDCap, StLCDBToA, 0x053, 0x70, 0x03, VCLK108_2,
-		 0x70, 0x44, 0xF8, 0x2F, 0x02, 0x14, 0x0A, 0x02, 0x00,
-		 0x30, 0x10, 0x5A, 0x10, 0x10, 0x0A, 0xC0, 0x30, 0x10},
+	{Panel1400x1050, LCDDualLink+DefaultLCDCap, StLCDBToA,
+	0x053, 0x70, 0x03, VCLK108_2,
+	 0x70, 0x44, 0xF8, 0x2F, 0x02, 0x14, 0x0A, 0x02, 0x00,
+	 0x30, 0x10, 0x5A, 0x10, 0x10, 0x0A, 0xC0, 0x30, 0x10},
 /* LCDCap1600x1200 */
-                {Panel1600x1200, LCDDualLink+DefaultLCDCap, LCDToFull, 0x053, 0xC0, 0x03, VCLK162,
-		 0x43, 0x22, 0x70, 0x24, 0x02, 0x14, 0x0A, 0x02, 0x00,
-		 0x30, 0x10, 0x5A, 0x10, 0x10, 0x0A, 0xC0, 0x30, 0x10},
+	{Panel1600x1200, LCDDualLink+DefaultLCDCap, LCDToFull,
+	0x053, 0xC0, 0x03, VCLK162,
+	 0x43, 0x22, 0x70, 0x24, 0x02, 0x14, 0x0A, 0x02, 0x00,
+	 0x30, 0x10, 0x5A, 0x10, 0x10, 0x0A, 0xC0, 0x30, 0x10},
 /* LCDCap1024x768x75 */
-		{Panel1024x768x75, DefaultLCDCap, 0, 0x014, 0x60, 0, VCLK78_75,
-		 0x2B, 0x61, 0x2B, 0x61, 0x02, 0x14, 0x0A, 0x02, 0x00,
-		 0x30, 0x10, 0x5A, 0x10, 0x10, 0x0A, 0xC0, 0x28, 0x10},
+	{Panel1024x768x75, DefaultLCDCap, 0, 0x014, 0x60, 0, VCLK78_75,
+	 0x2B, 0x61, 0x2B, 0x61, 0x02, 0x14, 0x0A, 0x02, 0x00,
+	 0x30, 0x10, 0x5A, 0x10, 0x10, 0x0A, 0xC0, 0x28, 0x10},
 /* LCDCap1280x1024x75 */
-                {Panel1280x1024x75, LCDDualLink+DefaultLCDCap, StLCDBToA, 0x053, 0x90, 0x03, VCLK135_5,
-		 0x54, 0x42, 0x4A, 0x61, 0x02, 0x14, 0x0A, 0x02, 0x00,
-		 0x30, 0x10, 0x5A, 0x10, 0x10, 0x0A, 0xC0, 0x30, 0x10},
+	{Panel1280x1024x75, LCDDualLink+DefaultLCDCap, StLCDBToA,
+	0x053, 0x90, 0x03, VCLK135_5,
+	 0x54, 0x42, 0x4A, 0x61, 0x02, 0x14, 0x0A, 0x02, 0x00,
+	 0x30, 0x10, 0x5A, 0x10, 0x10, 0x0A, 0xC0, 0x30, 0x10},
 /* LCDCapDefault */
-                {0xFF, DefaultLCDCap, 0, 0x053, 0x88, 0x06, VCLK65,
-		0x6C, 0xC3, 0x35, 0x62, 0x02, 0x14, 0x0A, 0x02, 0x00,
-		0x30, 0x10, 0x5A, 0x10, 0x10, 0x0A, 0xC0, 0x28, 0x10}
+	{0xFF, DefaultLCDCap, 0, 0x053, 0x88, 0x06, VCLK65,
+	0x6C, 0xC3, 0x35, 0x62, 0x02, 0x14, 0x0A, 0x02, 0x00,
+	0x30, 0x10, 0x5A, 0x10, 0x10, 0x0A, 0xC0, 0x28, 0x10}
 };
 #endif
 
-static struct XGI330_LCDCapStruct  XGI_LCDDLCapList[] =  /* Dual link only */
-{
+/* Dual link only */
+static struct XGI330_LCDCapStruct  XGI_LCDDLCapList[] = {
 /* LCDCap1024x768 */
-		{Panel1024x768, DefaultLCDCap, 0, 0x012, 0x88, 0x06, VCLK65,
-		0x6C, 0xC3, 0x35, 0x62, 0x02, 0x14, 0x0A, 0x02, 0x00,
-		0x30, 0x10, 0x5A, 0x10, 0x10, 0x0A, 0xC0, 0x28, 0x10},
+	{Panel1024x768, DefaultLCDCap, 0, 0x012, 0x88, 0x06, VCLK65,
+	0x6C, 0xC3, 0x35, 0x62, 0x02, 0x14, 0x0A, 0x02, 0x00,
+	0x30, 0x10, 0x5A, 0x10, 0x10, 0x0A, 0xC0, 0x28, 0x10},
 /* LCDCap1280x1024 */
-		{Panel1280x1024, LCDDualLink+DefaultLCDCap, StLCDBToA, 0x012, 0x70, 0x03, VCLK108_2,
-		0x70, 0x44, 0xF8, 0x2F, 0x02, 0x14, 0x0A, 0x02, 0x00,
-		0x30, 0x10, 0x5A, 0x10, 0x10, 0x0A, 0xC0, 0x30, 0x10},
+	{Panel1280x1024, LCDDualLink+DefaultLCDCap, StLCDBToA,
+	0x012, 0x70, 0x03, VCLK108_2,
+	0x70, 0x44, 0xF8, 0x2F, 0x02, 0x14, 0x0A, 0x02, 0x00,
+	0x30, 0x10, 0x5A, 0x10, 0x10, 0x0A, 0xC0, 0x30, 0x10},
 /* LCDCap1400x1050 */
-		{Panel1400x1050, LCDDualLink+DefaultLCDCap, StLCDBToA, 0x012, 0x70, 0x03, VCLK108_2,
-		 0x70, 0x44, 0xF8, 0x2F, 0x02, 0x14, 0x0A, 0x02, 0x00,
-		 0x30, 0x10, 0x5A, 0x10, 0x10, 0x0A, 0xC0, 0x30, 0x10},
+	{Panel1400x1050, LCDDualLink+DefaultLCDCap, StLCDBToA,
+	0x012, 0x70, 0x03, VCLK108_2,
+	 0x70, 0x44, 0xF8, 0x2F, 0x02, 0x14, 0x0A, 0x02, 0x00,
+	 0x30, 0x10, 0x5A, 0x10, 0x10, 0x0A, 0xC0, 0x30, 0x10},
 /* LCDCap1600x1200 */
-		{Panel1600x1200, LCDDualLink+DefaultLCDCap, LCDToFull, 0x012, 0xC0, 0x03, VCLK162,
-		 0x43, 0x22, 0x70, 0x24, 0x02, 0x14, 0x0A, 0x02, 0x00,
-		 0x30, 0x10, 0x5A, 0x10, 0x10, 0x0A, 0xC0, 0x30, 0x10},
+	{Panel1600x1200, LCDDualLink+DefaultLCDCap, LCDToFull,
+	0x012, 0xC0, 0x03, VCLK162,
+	 0x43, 0x22, 0x70, 0x24, 0x02, 0x14, 0x0A, 0x02, 0x00,
+	 0x30, 0x10, 0x5A, 0x10, 0x10, 0x0A, 0xC0, 0x30, 0x10},
 /* LCDCap1024x768x75 */
-		{Panel1024x768x75, DefaultLCDCap, 0, 0x012, 0x60, 0, VCLK78_75,
-		 0x2B, 0x61, 0x2B, 0x61, 0x02, 0x14, 0x0A, 0x02, 0x00,
-		 0x30, 0x10, 0x5A, 0x10, 0x10, 0x0A, 0xC0, 0x28, 0x10},
+	{Panel1024x768x75, DefaultLCDCap, 0, 0x012, 0x60, 0, VCLK78_75,
+	 0x2B, 0x61, 0x2B, 0x61, 0x02, 0x14, 0x0A, 0x02, 0x00,
+	 0x30, 0x10, 0x5A, 0x10, 0x10, 0x0A, 0xC0, 0x28, 0x10},
 /* LCDCap1280x1024x75 */
-		{Panel1280x1024x75, LCDDualLink+DefaultLCDCap, StLCDBToA, 0x012, 0x90, 0x03, VCLK135_5,
-		 0x54, 0x42, 0x4A, 0x61, 0x02, 0x14, 0x0A, 0x02, 0x00,
-		 0x30, 0x10, 0x5A, 0x10, 0x10, 0x0A, 0xC0, 0x30, 0x10},
+	{Panel1280x1024x75, LCDDualLink+DefaultLCDCap, StLCDBToA,
+	0x012, 0x90, 0x03, VCLK135_5,
+	 0x54, 0x42, 0x4A, 0x61, 0x02, 0x14, 0x0A, 0x02, 0x00,
+	 0x30, 0x10, 0x5A, 0x10, 0x10, 0x0A, 0xC0, 0x30, 0x10},
 /* LCDCapDefault */
-		{0xFF, DefaultLCDCap, 0, 0x012, 0x88, 0x06, VCLK65,
-		0x6C, 0xC3, 0x35, 0x62, 0x02, 0x14, 0x0A, 0x02, 0x00,
-		0x30, 0x10, 0x5A, 0x10, 0x10, 0x0A, 0xC0, 0x28, 0x10}
+	{0xFF, DefaultLCDCap, 0, 0x012, 0x88, 0x06, VCLK65,
+	0x6C, 0xC3, 0x35, 0x62, 0x02, 0x14, 0x0A, 0x02, 0x00,
+	0x30, 0x10, 0x5A, 0x10, 0x10, 0x0A, 0xC0, 0x28, 0x10}
 };
 
 #if 0
-static struct XGI330_LCDCapStruct  XGI660_LCDCapList[] =
-{
+static struct XGI330_LCDCapStruct  XGI660_LCDCapList[] = {
 /* LCDCap1024x768 */
-                {Panel1024x768, DefaultLCDCap, 0, 0x014, 0x88, 0x06, VCLK65,
-		0x6C, 0xC3, 0x35, 0x62, 0x02, 0x14, 0x0A, 0x02, 0x00,
-		0x30, 0x10, 0x5A, 0x10, 0x10, 0x0A, 0xC0, 0x28, 0x10},
+	{Panel1024x768, DefaultLCDCap, 0, 0x014, 0x88, 0x06, VCLK65,
+	0x6C, 0xC3, 0x35, 0x62, 0x02, 0x14, 0x0A, 0x02, 0x00,
+	0x30, 0x10, 0x5A, 0x10, 0x10, 0x0A, 0xC0, 0x28, 0x10},
 /* LCDCap1280x1024 */
-                {Panel1280x1024, DefaultLCDCap, StLCDBToA, 0x053, 0x70, 0x03, VCLK108_2,
-		0x70, 0x44, 0xF8, 0x2F, 0x02, 0x14, 0x0A, 0x02, 0x00,
-		0x30, 0x10, 0x5A, 0x10, 0x10, 0x0A, 0xC0, 0x30, 0x10},
+	{Panel1280x1024, DefaultLCDCap, StLCDBToA, 0x053, 0x70, 0x03, VCLK108_2,
+	0x70, 0x44, 0xF8, 0x2F, 0x02, 0x14, 0x0A, 0x02, 0x00,
+	0x30, 0x10, 0x5A, 0x10, 0x10, 0x0A, 0xC0, 0x30, 0x10},
 /* LCDCap1400x1050 */
-                {Panel1400x1050, DefaultLCDCap, StLCDBToA, 0x053, 0x70, 0x03, VCLK108_2,
-		 0x70, 0x44, 0xF8, 0x2F, 0x02, 0x14, 0x0A, 0x02, 0x00,
-		 0x30, 0x10, 0x5A, 0x10, 0x10, 0x0A, 0xC0, 0x30, 0x10},
+	{Panel1400x1050, DefaultLCDCap, StLCDBToA, 0x053, 0x70, 0x03, VCLK108_2,
+	 0x70, 0x44, 0xF8, 0x2F, 0x02, 0x14, 0x0A, 0x02, 0x00,
+	 0x30, 0x10, 0x5A, 0x10, 0x10, 0x0A, 0xC0, 0x30, 0x10},
 /* LCDCap1600x1200 */
-                {Panel1600x1200, DefaultLCDCap, LCDToFull, 0x053, 0xC0, 0x03, VCLK162,
-		 0x5A, 0x23, 0x5A, 0x23, 0x02, 0x14, 0x0A, 0x02, 0x00,
-		 0x30, 0x10, 0x5A, 0x10, 0x10, 0x0A, 0xC0, 0x30, 0x10},
+	{Panel1600x1200, DefaultLCDCap, LCDToFull, 0x053, 0xC0, 0x03, VCLK162,
+	 0x5A, 0x23, 0x5A, 0x23, 0x02, 0x14, 0x0A, 0x02, 0x00,
+	 0x30, 0x10, 0x5A, 0x10, 0x10, 0x0A, 0xC0, 0x30, 0x10},
 /* LCDCap1024x768x75 */
-		{Panel1024x768x75, DefaultLCDCap, 0, 0x014, 0x60, 0, VCLK78_75,
-		 0x2B, 0x61, 0x2B, 0x61, 0x02, 0x14, 0x0A, 0x02, 0x00,
-		 0x30, 0x10, 0x5A, 0x10, 0x10, 0x0A, 0xC0, 0x28, 0x10},
+	{Panel1024x768x75, DefaultLCDCap, 0, 0x014, 0x60, 0, VCLK78_75,
+	 0x2B, 0x61, 0x2B, 0x61, 0x02, 0x14, 0x0A, 0x02, 0x00,
+	 0x30, 0x10, 0x5A, 0x10, 0x10, 0x0A, 0xC0, 0x28, 0x10},
 /* LCDCap1280x1024x75 */
-                {Panel1280x1024x75,+DefaultLCDCap, StLCDBToA, 0x053, 0x90, 0x03, VCLK135_5,
-		 0x54, 0x42, 0x4A, 0x61, 0x02, 0x14, 0x0A, 0x02, 0x00,
-		 0x30, 0x10, 0x5A, 0x10, 0x10, 0x0A, 0xC0, 0x30, 0x10},
+	{Panel1280x1024x75, + DefaultLCDCap, StLCDBToA,
+	0x053, 0x90, 0x03, VCLK135_5,
+	 0x54, 0x42, 0x4A, 0x61, 0x02, 0x14, 0x0A, 0x02, 0x00,
+	 0x30, 0x10, 0x5A, 0x10, 0x10, 0x0A, 0xC0, 0x30, 0x10},
 /* LCDCapDefault */
-                {0xFF, DefaultLCDCap, 0, 0x053, 0x88, 0x06, VCLK65,
-		0x6C, 0xC3, 0x35, 0x62, 0x02, 0x14, 0x0A, 0x02, 0x00,
-		0x30, 0x10, 0x5A, 0x10, 0x10, 0x0A, 0xC0, 0x28, 0x10}
+	{0xFF, DefaultLCDCap, 0, 0x053, 0x88, 0x06, VCLK65,
+	0x6C, 0xC3, 0x35, 0x62, 0x02, 0x14, 0x0A, 0x02, 0x00,
+	0x30, 0x10, 0x5A, 0x10, 0x10, 0x0A, 0xC0, 0x28, 0x10}
 };
 #endif
 
-static struct XGI330_LCDCapStruct  XGI_LCDCapList[] =
-{
+static struct XGI330_LCDCapStruct  XGI_LCDCapList[] = {
 /* LCDCap1024x768 */
-		{Panel1024x768, DefaultLCDCap, 0, 0x012, 0x88, 0x06, VCLK65,
-		0x6C, 0xC3, 0x35, 0x62, 0x02, 0x14, 0x0A, 0x02, 0x00,
-		0x30, 0x10, 0x5A, 0x10, 0x10, 0x0A, 0xC0, 0x28, 0x10},
+	{Panel1024x768, DefaultLCDCap, 0, 0x012, 0x88, 0x06, VCLK65,
+	0x6C, 0xC3, 0x35, 0x62, 0x02, 0x14, 0x0A, 0x02, 0x00,
+	0x30, 0x10, 0x5A, 0x10, 0x10, 0x0A, 0xC0, 0x28, 0x10},
 /* LCDCap1280x1024 */
-		{Panel1280x1024, DefaultLCDCap, StLCDBToA, 0x012, 0x70, 0x03, VCLK108_2,
-		0x70, 0x44, 0xF8, 0x2F, 0x02, 0x14, 0x0A, 0x02, 0x00,
-		0x30, 0x10, 0x5A, 0x10, 0x10, 0x0A, 0xC0, 0x30, 0x10},
+	{Panel1280x1024, DefaultLCDCap, StLCDBToA,
+	0x012, 0x70, 0x03, VCLK108_2,
+	0x70, 0x44, 0xF8, 0x2F, 0x02, 0x14, 0x0A, 0x02, 0x00,
+	0x30, 0x10, 0x5A, 0x10, 0x10, 0x0A, 0xC0, 0x30, 0x10},
 /* LCDCap1400x1050 */
-		{Panel1400x1050, DefaultLCDCap, StLCDBToA, 0x012, 0x70, 0x03, VCLK108_2,
-		 0x70, 0x44, 0xF8, 0x2F, 0x02, 0x14, 0x0A, 0x02, 0x00,
-		 0x30, 0x10, 0x5A, 0x10, 0x10, 0x0A, 0xC0, 0x30, 0x10},
+	{Panel1400x1050, DefaultLCDCap, StLCDBToA,
+	0x012, 0x70, 0x03, VCLK108_2,
+	 0x70, 0x44, 0xF8, 0x2F, 0x02, 0x14, 0x0A, 0x02, 0x00,
+	 0x30, 0x10, 0x5A, 0x10, 0x10, 0x0A, 0xC0, 0x30, 0x10},
 /* LCDCap1600x1200 */
-		{Panel1600x1200, DefaultLCDCap, LCDToFull, 0x012, 0xC0, 0x03, VCLK162,
-		 0x5A, 0x23, 0x5A, 0x23, 0x02, 0x14, 0x0A, 0x02, 0x00,
-		 0x30, 0x10, 0x5A, 0x10, 0x10, 0x0A, 0xC0, 0x30, 0x10},
+	{Panel1600x1200, DefaultLCDCap, LCDToFull,
+	0x012, 0xC0, 0x03, VCLK162,
+	 0x5A, 0x23, 0x5A, 0x23, 0x02, 0x14, 0x0A, 0x02, 0x00,
+	 0x30, 0x10, 0x5A, 0x10, 0x10, 0x0A, 0xC0, 0x30, 0x10},
 /* LCDCap1024x768x75 */
-		{Panel1024x768x75, DefaultLCDCap, 0, 0x012, 0x60, 0, VCLK78_75,
-		 0x2B, 0x61, 0x2B, 0x61, 0x02, 0x14, 0x0A, 0x02, 0x00,
-		 0x30, 0x10, 0x5A, 0x10, 0x10, 0x0A, 0xC0, 0x28, 0x10},
+	{Panel1024x768x75, DefaultLCDCap, 0, 0x012, 0x60, 0, VCLK78_75,
+	 0x2B, 0x61, 0x2B, 0x61, 0x02, 0x14, 0x0A, 0x02, 0x00,
+	 0x30, 0x10, 0x5A, 0x10, 0x10, 0x0A, 0xC0, 0x28, 0x10},
 /* LCDCap1280x1024x75 */
-		{Panel1280x1024x75, DefaultLCDCap, StLCDBToA, 0x012, 0x90, 0x03, VCLK135_5,
-		 0x54, 0x42, 0x4A, 0x61, 0x02, 0x14, 0x0A, 0x02, 0x00,
-		 0x30, 0x10, 0x5A, 0x10, 0x10, 0x0A, 0xC0, 0x30, 0x10},
+	{Panel1280x1024x75, DefaultLCDCap, StLCDBToA,
+	0x012, 0x90, 0x03, VCLK135_5,
+	 0x54, 0x42, 0x4A, 0x61, 0x02, 0x14, 0x0A, 0x02, 0x00,
+	 0x30, 0x10, 0x5A, 0x10, 0x10, 0x0A, 0xC0, 0x30, 0x10},
 /* LCDCapDefault */
-		{0xFF, DefaultLCDCap, 0, 0x012, 0x88, 0x06, VCLK65,
-		0x6C, 0xC3, 0x35, 0x62, 0x02, 0x14, 0x0A, 0x02, 0x00,
-		0x30, 0x10, 0x5A, 0x10, 0x10, 0x0A, 0xC0, 0x28, 0x10}
+	{0xFF, DefaultLCDCap, 0, 0x012, 0x88, 0x06, VCLK65,
+	0x6C, 0xC3, 0x35, 0x62, 0x02, 0x14, 0x0A, 0x02, 0x00,
+	0x30, 0x10, 0x5A, 0x10, 0x10, 0x0A, 0xC0, 0x28, 0x10}
 };
 
-struct XGI21_LVDSCapStruct XGI21_LCDCapList[] =
-{
-    {DisableLCD24bpp + LCDPolarity,
-     2160,1250,1600,1200,  64,  1,  192,   3,
-     0x70,0x24,0x20,0x04,0x0A,0x02,0xC8
-    },
-    {DisableLCD24bpp + LCDPolarity,
-     1688,1066,1280,1024,  48,  1,  112,   3,
-     0x70,0x44,0x20,0x04,0x0A,0x02,0xC8
-    },
-    {DisableLCD24bpp + LCDPolarity + (LCDPolarity << 8),
-     1344, 806,1024, 768,  24,  3,  136,   6,
-     0x6C,0x65,0x20,0x04,0x0A,0x02,0xC8
-    },
-    {DisableLCD24bpp + LCDPolarity,
-     1056, 628, 800, 600,  40,   1, 128,   4,
-     0x42,0xE2,0x20,0x14,0x0A,0x02,0x00
-    },
-    {DisableLCD24bpp + LCDPolarity,
-      928, 525, 800, 480,  40,  13,  48,   3,
-     0x52,0xC5,0x20,0x14,0x0A,0x02,0x00
-    },
-    {DisableLCD24bpp + LCDPolarity + (LCDPolarity << 8),
-      800, 525, 640, 480,  16,  10,  96,   2,
-     0x1B,0xE1,0x20,0x04,0x0A,0x02,0xC8
-    }
-
+struct XGI21_LVDSCapStruct XGI21_LCDCapList[] = {
+	{DisableLCD24bpp + LCDPolarity,
+	 2160, 1250, 1600, 1200,   64,    1,  192,    3,
+	 0x70, 0x24, 0x20, 0x04, 0x0A, 0x02, 0xC8
+	},
+	{DisableLCD24bpp + LCDPolarity,
+	 1688, 1066, 1280, 1024,   48,    1,   112,    3,
+	 0x70, 0x44, 0x20, 0x04, 0x0A, 0x02, 0xC8
+	},
+	{DisableLCD24bpp + LCDPolarity + (LCDPolarity << 8),
+	 1344,  806, 1024,  768,   24,    3,   136,    6,
+	 0x6C, 0x65, 0x20, 0x04, 0x0A, 0x02, 0xC8
+	},
+	{DisableLCD24bpp + LCDPolarity,
+	 1056,  628,  800,  600,   40,    1,  128,    4,
+	 0x42, 0xE2, 0x20, 0x14, 0x0A, 0x02, 0x00
+	},
+	{DisableLCD24bpp + LCDPolarity,
+	  928,  525,  800,  480,   40,   13,   48,    3,
+	 0x52, 0xC5, 0x20, 0x14, 0x0A, 0x02, 0x00
+	},
+	{DisableLCD24bpp + LCDPolarity + (LCDPolarity << 8),
+	  800,  525,  640,  480,   16,   10,   96,    2,
+	 0x1B, 0xE1, 0x20, 0x04, 0x0A, 0x02, 0xC8
+	}
 };
 
-static struct XGI_Ext2Struct XGI330_RefIndex[] =
-{
-{Support32Bpp + SupportAllCRT2 + SyncPN,			RES320x200,	 VCLK25_175, 0x00,0x10,0x59, 320, 200},/* 00 */
-{Support32Bpp + SupportAllCRT2 + SyncPN,			RES320x200,	 VCLK25_175, 0x00,0x10,0x00, 320, 400},/* 01 */
-{Support32Bpp + SupportAllCRT2 + SyncNN,			RES320x240,	 VCLK25_175, 0x04,0x20,0x50, 320, 240},/* 02 */
-{Support32Bpp + SupportAllCRT2 + SyncPP,			RES400x300,	 VCLK40,     0x05,0x32,0x51, 400, 300},/* 03 */
-{Support32Bpp + NoSupportTV + SyncNN + SupportTV1024,		RES512x384,	 VCLK65,     0x06,0x43,0x52, 512, 384},/* 04 */
-{Support32Bpp + SupportAllCRT2 + SyncPN,			RES640x400,	 VCLK25_175, 0x00,0x14,0x2f, 640, 400},/* 05 */
-{Support32Bpp + SupportAllCRT2 + SyncNN,			RES640x480x60,	 VCLK25_175, 0x04,0x24,0x2e, 640, 480},/* 06 640x480x60Hz (LCD 640x480x60z) */
-{Support32Bpp + NoSupportHiVisionTV + SyncNN,			RES640x480x72,	 VCLK31_5,   0x04,0x24,0x2e, 640, 480},/* 07 640x480x72Hz (LCD 640x480x70Hz) */
-{Support32Bpp + NoSupportHiVisionTV + SyncNN,			RES640x480x75,	 VCLK31_5,   0x47,0x24,0x2e, 640, 480},/* 08 640x480x75Hz (LCD 640x480x75Hz) */
-{Support32Bpp + SupportRAMDAC2 + SyncNN,			RES640x480x85,	 VCLK36,     0x8A,0x24,0x2e, 640, 480},/* 09 640x480x85Hz */
-{Support32Bpp + SupportRAMDAC2 + SyncPN,			RES640x480x100,	 VCLK43_163, 0x00,0x24,0x2e, 640, 480},/* 0a 640x480x100Hz */
-{Support32Bpp + SupportRAMDAC2 + SyncPN,			RES640x480x120,	 VCLK52_406, 0x00,0x24,0x2e, 640, 480},/* 0b 640x480x120Hz */
-{Support32Bpp + SupportRAMDAC2 + SyncPN,			RES640x480x160,	 VCLK72_852, 0x00,0x24,0x2e, 640, 480},/* 0c 640x480x160Hz */
-{Support32Bpp + SupportRAMDAC2 + SyncNN,			RES640x480x200,	 VCLK86_6,   0x00,0x24,0x2e, 640, 480},/* 0d 640x480x200Hz */
-{Support32Bpp + NoSupportLCD + SyncPP,				RES800x600x56,	 VCLK36,     0x05,0x36,0x6a, 800, 600},/* 0e 800x600x56Hz */
-{Support32Bpp + NoSupportTV + SyncPP,				RES800x600x60,	 VCLK40,     0x05,0x36,0x6a, 800, 600},/* 0f 800x600x60Hz (LCD 800x600x60Hz) */
-{Support32Bpp + NoSupportHiVisionTV + SyncPP,			RES800x600x72,	 VCLK50,     0x48,0x36,0x6a, 800, 600},/* 10 800x600x72Hz (LCD 800x600x70Hz) */
-{Support32Bpp + NoSupportHiVisionTV + SyncPP,			RES800x600x75,	 VCLK49_5,   0x8B,0x36,0x6a, 800, 600},/* 11 800x600x75Hz (LCD 800x600x75Hz) */
-{Support32Bpp + SupportRAMDAC2 + SyncPP,			RES800x600x85,	 VCLK56_25,  0x00,0x36,0x6a, 800, 600},/* 12 800x600x85Hz */
-{Support32Bpp + SupportRAMDAC2 + SyncPN,			RES800x600x100,	 VCLK68_179, 0x00,0x36,0x6a, 800, 600},/* 13 800x600x100Hz */
-{Support32Bpp + SupportRAMDAC2 + SyncPN,			RES800x600x120,	 VCLK83_95,  0x00,0x36,0x6a, 800, 600},/* 14 800x600x120Hz */
-{Support32Bpp + SupportRAMDAC2 + SyncPN,			RES800x600x160,	 VCLK116_406,0x00,0x36,0x6a, 800, 600},/* 15 800x600x160Hz */
-{Support32Bpp + InterlaceMode + SyncPP,				RES1024x768x43,	 VCLK44_9,   0x00,0x47,0x37,1024, 768},/* 16 1024x768x43Hz */
-{Support32Bpp + NoSupportTV + SyncNN + SupportTV1024,		RES1024x768x60,	 VCLK65,     0x06,0x47,0x37,1024, 768},/* 17 1024x768x60Hz (LCD 1024x768x60Hz) */
-{Support32Bpp + NoSupportHiVisionTV + SyncNN,			RES1024x768x70,	 VCLK75,     0x49,0x47,0x37,1024, 768},/* 18 1024x768x70Hz (LCD 1024x768x70Hz) */
-{Support32Bpp + NoSupportHiVisionTV + SyncPP,			RES1024x768x75,	 VCLK78_75,  0x00,0x47,0x37,1024, 768},/* 19 1024x768x75Hz (LCD 1024x768x75Hz) */
-{Support32Bpp + SupportRAMDAC2 + SyncPP,			RES1024x768x85,	 VCLK94_5,   0x8C,0x47,0x37,1024, 768},/* 1a 1024x768x85Hz */
-{Support32Bpp + SupportRAMDAC2 + SyncPN,			RES1024x768x100, VCLK113_309,0x00,0x47,0x37,1024, 768},/* 1b 1024x768x100Hz */
-{Support32Bpp + SupportRAMDAC2 + SyncPN,			RES1024x768x120, VCLK139_054,0x00,0x47,0x37,1024, 768},/* 1c 1024x768x120Hz */
-{Support32Bpp + SupportLCD + SyncPP,				RES1280x960x60,	 VCLK108_2,  0x08,0x58,0x7b,1280, 960},/* 1d 1280x960x60Hz */
-{Support32Bpp + InterlaceMode + SyncPP,				RES1280x1024x43, VCLK78_75,  0x00,0x58,0x3a,1280,1024},/* 1e 1280x1024x43Hz */
-{Support32Bpp + NoSupportTV + SyncPP,				RES1280x1024x60, VCLK108_2,  0x07,0x58,0x3a,1280,1024},/* 1f 1280x1024x60Hz (LCD 1280x1024x60Hz) */
-{Support32Bpp + NoSupportTV + SyncPP,				RES1280x1024x75, VCLK135_5,  0x00,0x58,0x3a,1280,1024},/* 20 1280x1024x75Hz (LCD 1280x1024x75Hz) */
-{Support32Bpp + SyncPP,						RES1280x1024x85, VCLK157_5,  0x00,0x58,0x3a,1280,1024},/* 21 1280x1024x85Hz */
-{Support32Bpp + SupportLCD + SyncPP + SupportCRT2in301C,	RES1600x1200x60, VCLK162,    0x09,0x7A,0x3c,1600,1200},/* 22 1600x1200x60Hz */
-{Support32Bpp + SyncPP + SupportCRT2in301C,			RES1600x1200x65, VCLK175,    0x00,0x69,0x3c,1600,1200},/* 23 1600x1200x65Hz */
-{Support32Bpp + SyncPP + SupportCRT2in301C,			RES1600x1200x70, VCLK189,    0x00,0x69,0x3c,1600,1200},/* 24 1600x1200x70Hz */
-{Support32Bpp + SyncPP + SupportCRT2in301C,			RES1600x1200x75, VCLK202_5,  0x00,0x69,0x3c,1600,1200},/* 25 1600x1200x75Hz */
-{Support32Bpp + SyncPP,						RES1600x1200x85, VCLK229_5,  0x00,0x69,0x3c,1600,1200},/* 26 1600x1200x85Hz */
-{Support32Bpp + SyncPP,						RES1600x1200x100,VCLK269_655,0x00,0x69,0x3c,1600,1200},/* 27 1600x1200x100Hz */
-{Support32Bpp + SyncPP,						RES1600x1200x120,VCLK323_586,0x00,0x69,0x3c,1600,1200},/* 28 1600x1200x120Hz */
-{Support32Bpp + SupportLCD + SyncNP,				RES1920x1440x60, VCLK234,    0x00,0x00,0x68,1920,1440},/* 29 1920x1440x60Hz */
-{Support32Bpp + SyncPN,						RES1920x1440x65, VCLK254_817,0x00,0x00,0x68,1920,1440},/* 2a 1920x1440x65Hz */
-{Support32Bpp + SyncPN,						RES1920x1440x70, VCLK277_015,0x00,0x00,0x68,1920,1440},/* 2b 1920x1440x70Hz */
-{Support32Bpp + SyncPN,						RES1920x1440x75, VCLK291_132,0x00,0x00,0x68,1920,1440},/* 2c 1920x1440x75Hz */
-{Support32Bpp + SyncPN,						RES1920x1440x85, VCLK330_615,0x00,0x00,0x68,1920,1440},/* 2d 1920x1440x85Hz */
-{Support16Bpp + SyncPN,						RES1920x1440x100,VCLK388_631,0x00,0x00,0x68,1920,1440},/* 2e 1920x1440x100Hz */
-{Support32Bpp + SupportLCD + SyncPN,				RES2048x1536x60, VCLK266_952,0x00,0x00,0x6c,2048,1536},/* 2f 2048x1536x60Hz */
-{Support32Bpp + SyncPN,						RES2048x1536x65, VCLK291_766,0x00,0x00,0x6c,2048,1536},/* 30 2048x1536x65Hz */
-{Support32Bpp + SyncPN,						RES2048x1536x70, VCLK315_195,0x00,0x00,0x6c,2048,1536},/* 31 2048x1536x70Hz */
-{Support32Bpp + SyncPN,						RES2048x1536x75, VCLK340_477,0x00,0x00,0x6c,2048,1536},/* 32 2048x1536x75Hz */
-{Support16Bpp + SyncPN,						RES2048x1536x85, VCLK375_847,0x00,0x00,0x6c,2048,1536},/* 33 2048x1536x85Hz */
-{Support32Bpp + SupportHiVisionTV + SupportRAMDAC2 + SyncPP + SupportYPbPr,	RES800x480x60,	 VCLK39_77,  0x08,0x00,0x70, 800, 480},/* 34 800x480x60Hz */
-{Support32Bpp + SupportRAMDAC2 + SyncPP,			RES800x480x75,	 VCLK49_5,   0x08,0x00,0x70, 800, 480},/* 35 800x480x75Hz */
-{Support32Bpp + SupportRAMDAC2 + SyncPP,			RES800x480x85,	 VCLK56_25,  0x08,0x00,0x70, 800, 480},/* 36 800x480x85Hz */
-{Support32Bpp + SupportHiVisionTV + SupportRAMDAC2 + SyncPP + SupportYPbPr,	RES1024x576x60,	 VCLK65,     0x09,0x00,0x71,1024, 576},/* 37 1024x576x60Hz */
-{Support32Bpp + SupportRAMDAC2 + SyncPP,			RES1024x576x75,	 VCLK78_75,  0x09,0x00,0x71,1024, 576},/* 38 1024x576x75Hz */
-{Support32Bpp + SupportRAMDAC2 + SyncPP,			RES1024x576x85,	 VCLK94_5,   0x09,0x00,0x71,1024, 576},/* 39 1024x576x85Hz */
-{Support32Bpp + SupportHiVisionTV + SupportRAMDAC2 + SyncPP + SupportYPbPr,	RES1280x720x60,	 VCLK108_2,  0x0A,0x00,0x75,1280, 720},/* 3a 1280x720x60Hz */
-{Support32Bpp + SupportRAMDAC2 + SyncPP,			RES1280x720x75,	 VCLK135_5,  0x0A,0x00,0x75,1280, 720},/* 3b 1280x720x75Hz */
-{Support32Bpp + SupportRAMDAC2 + SyncPP,			RES1280x720x85,	 VCLK157_5,  0x0A,0x00,0x75,1280, 720},/* 3c 1280x720x85Hz */
-{Support32Bpp + SupportTV + SyncNN,				RES720x480x60,	 VCLK28_322, 0x06,0x00,0x31, 720, 480},/* 3d 720x480x60Hz */
-{Support32Bpp + SupportTV + SyncPP,				RES720x576x56,	 VCLK36,     0x06,0x00,0x32, 720, 576},/* 3e 720x576x56Hz */
-{Support32Bpp + InterlaceMode + NoSupportLCD + SyncPP,		RES856x480x79I,	 VCLK35_2,   0x00,0x00,0x00, 856, 480},/* 3f 856x480x79I */
-{Support32Bpp + NoSupportLCD + SyncNN,				RES856x480x60,	 VCLK35_2,   0x00,0x00,0x00, 856, 480},/* 40 856x480x60Hz */
-{Support32Bpp + NoSupportHiVisionTV + SyncPP,			RES1280x768x60,	 VCLK79_411, 0x08,0x48,0x23,1280, 768},/* 41 1280x768x60Hz */
-{Support32Bpp + NoSupportHiVisionTV + SyncPP,			RES1400x1050x60, VCLK122_61, 0x08,0x69,0x26,1400,1050},/* 42 1400x1050x60Hz */
-{Support32Bpp + SupportRAMDAC2 + SyncPP,			RES1152x864x60,	 VCLK80_350, 0x37,0x00,0x20,1152, 864},/* 43 1152x864x60Hz */
-{Support32Bpp + SupportRAMDAC2 + SyncPP,			RES1152x864x75,	 VCLK107_385,0x37,0x00,0x20,1152, 864},/* 44 1152x864x75Hz */
-{Support32Bpp + SupportLCD + SupportRAMDAC2 + SyncPP,		RES1280x960x75,	 VCLK125_999,0x3A,0x88,0x7b,1280, 960},/* 45 1280x960x75Hz */
-{Support32Bpp + SupportLCD + SupportRAMDAC2 + SyncPP,		RES1280x960x85,	 VCLK148_5,  0x0A,0x88,0x7b,1280, 960},/* 46 1280x960x85Hz */
-{Support32Bpp + SupportLCD + SupportRAMDAC2 + SyncPP,		RES1280x960x120, VCLK217_325,0x3A,0x88,0x7b,1280, 960},/* 47 1280x960x120Hz */
-{Support32Bpp + SupportRAMDAC2 + SyncPN,			RES1024x768x160, VCLK139_054,0x30,0x47,0x37,1024, 768},/* 48 1024x768x160Hz */
+static struct XGI_Ext2Struct XGI330_RefIndex[] = {
+	{Support32Bpp + SupportAllCRT2 + SyncPN, RES320x200, VCLK25_175,
+	0x00, 0x10, 0x59, 320, 200},/* 00 */
+	{Support32Bpp + SupportAllCRT2 + SyncPN, RES320x200, VCLK25_175,
+	0x00, 0x10, 0x00, 320, 400},/* 01 */
+	{Support32Bpp + SupportAllCRT2 + SyncNN, RES320x240, VCLK25_175,
+	0x04, 0x20, 0x50, 320, 240},/* 02 */
+	{Support32Bpp + SupportAllCRT2 + SyncPP, RES400x300, VCLK40,
+	0x05, 0x32, 0x51, 400, 300},/* 03 */
+	{Support32Bpp + NoSupportTV + SyncNN + SupportTV1024, RES512x384,
+	VCLK65, 0x06, 0x43, 0x52, 512, 384},/* 04 */
+	{Support32Bpp + SupportAllCRT2 + SyncPN, RES640x400, VCLK25_175,
+	0x00, 0x14, 0x2f, 640, 400},/* 05 */
+	{Support32Bpp + SupportAllCRT2 + SyncNN, RES640x480x60, VCLK25_175,
+	0x04, 0x24, 0x2e, 640, 480},/* 06 640x480x60Hz (LCD 640x480x60z) */
+	{Support32Bpp + NoSupportHiVisionTV + SyncNN, RES640x480x72, VCLK31_5,
+	0x04, 0x24, 0x2e, 640, 480},/* 07 640x480x72Hz (LCD 640x480x70Hz) */
+	{Support32Bpp + NoSupportHiVisionTV + SyncNN, RES640x480x75, VCLK31_5,
+	0x47, 0x24, 0x2e, 640, 480},/* 08 640x480x75Hz (LCD 640x480x75Hz) */
+	{Support32Bpp + SupportRAMDAC2 + SyncNN, RES640x480x85, VCLK36,
+	0x8A, 0x24, 0x2e, 640, 480},/* 09 640x480x85Hz */
+	{Support32Bpp + SupportRAMDAC2 + SyncPN, RES640x480x100, VCLK43_163,
+	0x00, 0x24, 0x2e, 640, 480},/* 0a 640x480x100Hz */
+	{Support32Bpp + SupportRAMDAC2 + SyncPN, RES640x480x120, VCLK52_406,
+	0x00, 0x24, 0x2e, 640, 480},/* 0b 640x480x120Hz */
+	{Support32Bpp + SupportRAMDAC2 + SyncPN, RES640x480x160, VCLK72_852,
+	0x00, 0x24, 0x2e, 640, 480},/* 0c 640x480x160Hz */
+	{Support32Bpp + SupportRAMDAC2 + SyncNN, RES640x480x200, VCLK86_6,
+	0x00, 0x24, 0x2e, 640, 480},/* 0d 640x480x200Hz */
+	{Support32Bpp + NoSupportLCD + SyncPP, RES800x600x56, VCLK36,
+	0x05, 0x36, 0x6a, 800, 600},/* 0e 800x600x56Hz */
+	{Support32Bpp + NoSupportTV + SyncPP, RES800x600x60, VCLK40,
+	0x05, 0x36, 0x6a, 800, 600},/* 0f 800x600x60Hz (LCD 800x600x60Hz) */
+	{Support32Bpp + NoSupportHiVisionTV + SyncPP, RES800x600x72, VCLK50,
+	0x48, 0x36, 0x6a, 800, 600},/* 10 800x600x72Hz (LCD 800x600x70Hz) */
+	{Support32Bpp + NoSupportHiVisionTV + SyncPP, RES800x600x75, VCLK49_5,
+	0x8B, 0x36, 0x6a, 800, 600},/* 11 800x600x75Hz (LCD 800x600x75Hz) */
+	{Support32Bpp + SupportRAMDAC2 + SyncPP, RES800x600x85, VCLK56_25,
+	0x00, 0x36, 0x6a, 800, 600},/* 12 800x600x85Hz */
+	{Support32Bpp + SupportRAMDAC2 + SyncPN, RES800x600x100, VCLK68_179,
+	0x00, 0x36, 0x6a, 800, 600},/* 13 800x600x100Hz */
+	{Support32Bpp + SupportRAMDAC2 + SyncPN, RES800x600x120, VCLK83_95,
+	0x00, 0x36, 0x6a, 800, 600},/* 14 800x600x120Hz */
+	{Support32Bpp + SupportRAMDAC2 + SyncPN, RES800x600x160, VCLK116_406,
+	0x00, 0x36, 0x6a, 800, 600},/* 15 800x600x160Hz */
+	{Support32Bpp + InterlaceMode + SyncPP, RES1024x768x43, VCLK44_9,
+	0x00, 0x47, 0x37, 1024, 768},/* 16 1024x768x43Hz */
+	/* 17 1024x768x60Hz (LCD 1024x768x60Hz) */
+	{Support32Bpp + NoSupportTV + SyncNN + SupportTV1024, RES1024x768x60,
+	VCLK65, 0x06, 0x47, 0x37, 1024, 768},
+	{Support32Bpp + NoSupportHiVisionTV + SyncNN, RES1024x768x70, VCLK75,
+	0x49, 0x47, 0x37, 1024, 768},/* 18 1024x768x70Hz (LCD 1024x768x70Hz) */
+	{Support32Bpp + NoSupportHiVisionTV + SyncPP, RES1024x768x75, VCLK78_75,
+	0x00, 0x47, 0x37, 1024, 768},/* 19 1024x768x75Hz (LCD 1024x768x75Hz) */
+	{Support32Bpp + SupportRAMDAC2 + SyncPP, RES1024x768x85, VCLK94_5,
+	0x8C, 0x47, 0x37, 1024, 768},/* 1a 1024x768x85Hz */
+	{Support32Bpp + SupportRAMDAC2 + SyncPN, RES1024x768x100, VCLK113_309,
+	0x00, 0x47, 0x37, 1024, 768},/* 1b 1024x768x100Hz */
+	{Support32Bpp + SupportRAMDAC2 + SyncPN, RES1024x768x120, VCLK139_054,
+	0x00, 0x47, 0x37, 1024, 768},/* 1c 1024x768x120Hz */
+	{Support32Bpp + SupportLCD + SyncPP, RES1280x960x60, VCLK108_2,
+	0x08, 0x58, 0x7b, 1280, 960},/* 1d 1280x960x60Hz */
+	{Support32Bpp + InterlaceMode + SyncPP, RES1280x1024x43, VCLK78_75,
+	0x00, 0x58, 0x3a, 1280, 1024},/* 1e 1280x1024x43Hz */
+	{Support32Bpp + NoSupportTV + SyncPP, RES1280x1024x60, VCLK108_2,
+	0x07, 0x58, 0x3a, 1280, 1024},/*1f 1280x1024x60Hz (LCD 1280x1024x60Hz)*/
+	{Support32Bpp + NoSupportTV + SyncPP, RES1280x1024x75, VCLK135_5,
+	0x00, 0x58, 0x3a, 1280, 1024},/*20 1280x1024x75Hz (LCD 1280x1024x75Hz)*/
+	{Support32Bpp + SyncPP, RES1280x1024x85, VCLK157_5,
+	0x00, 0x58, 0x3a, 1280, 1024},/* 21 1280x1024x85Hz */
+	/* 22 1600x1200x60Hz */
+	{Support32Bpp + SupportLCD + SyncPP + SupportCRT2in301C,
+	RES1600x1200x60, VCLK162, 0x09, 0x7A, 0x3c, 1600, 1200},
+	{Support32Bpp + SyncPP + SupportCRT2in301C, RES1600x1200x65, VCLK175,
+	0x00, 0x69, 0x3c, 1600, 1200},/* 23 1600x1200x65Hz */
+	{Support32Bpp + SyncPP + SupportCRT2in301C, RES1600x1200x70, VCLK189,
+	0x00, 0x69, 0x3c, 1600, 1200},/* 24 1600x1200x70Hz */
+	{Support32Bpp + SyncPP + SupportCRT2in301C, RES1600x1200x75, VCLK202_5,
+	0x00, 0x69, 0x3c, 1600, 1200},/* 25 1600x1200x75Hz */
+	{Support32Bpp + SyncPP, RES1600x1200x85, VCLK229_5,
+	0x00, 0x69, 0x3c, 1600, 1200},/* 26 1600x1200x85Hz */
+	{Support32Bpp + SyncPP, RES1600x1200x100, VCLK269_655,
+	0x00, 0x69, 0x3c, 1600, 1200},/* 27 1600x1200x100Hz */
+	{Support32Bpp + SyncPP, RES1600x1200x120, VCLK323_586,
+	0x00, 0x69, 0x3c, 1600, 1200},/* 28 1600x1200x120Hz */
+	{Support32Bpp + SupportLCD + SyncNP, RES1920x1440x60, VCLK234,
+	0x00, 0x00, 0x68, 1920, 1440},/* 29 1920x1440x60Hz */
+	{Support32Bpp + SyncPN, RES1920x1440x65, VCLK254_817,
+	0x00, 0x00, 0x68, 1920, 1440},/* 2a 1920x1440x65Hz */
+	{Support32Bpp + SyncPN, RES1920x1440x70, VCLK277_015,
+	0x00, 0x00, 0x68, 1920, 1440},/* 2b 1920x1440x70Hz */
+	{Support32Bpp + SyncPN, RES1920x1440x75, VCLK291_132,
+	0x00, 0x00, 0x68, 1920, 1440},/* 2c 1920x1440x75Hz */
+	{Support32Bpp + SyncPN, RES1920x1440x85, VCLK330_615,
+	0x00, 0x00, 0x68, 1920, 1440},/* 2d 1920x1440x85Hz */
+	{Support16Bpp + SyncPN, RES1920x1440x100, VCLK388_631,
+	0x00, 0x00, 0x68, 1920, 1440},/* 2e 1920x1440x100Hz */
+	{Support32Bpp + SupportLCD + SyncPN, RES2048x1536x60, VCLK266_952,
+	0x00, 0x00, 0x6c, 2048, 1536},/* 2f 2048x1536x60Hz */
+	{Support32Bpp + SyncPN, RES2048x1536x65, VCLK291_766,
+	0x00, 0x00, 0x6c, 2048, 1536},/* 30 2048x1536x65Hz */
+	{Support32Bpp + SyncPN, RES2048x1536x70, VCLK315_195,
+	0x00, 0x00, 0x6c, 2048, 1536},/* 31 2048x1536x70Hz */
+	{Support32Bpp + SyncPN, RES2048x1536x75, VCLK340_477,
+	0x00, 0x00, 0x6c, 2048, 1536},/* 32 2048x1536x75Hz */
+	{Support16Bpp + SyncPN, RES2048x1536x85, VCLK375_847,
+	0x00, 0x00, 0x6c, 2048, 1536},/* 33 2048x1536x85Hz */
+	{Support32Bpp + SupportHiVisionTV + SupportRAMDAC2 +
+	 SyncPP + SupportYPbPr, RES800x480x60, VCLK39_77,
+	 0x08, 0x00, 0x70, 800, 480},/* 34 800x480x60Hz */
+	{Support32Bpp + SupportRAMDAC2 + SyncPP, RES800x480x75, VCLK49_5,
+	0x08, 0x00, 0x70, 800, 480},/* 35 800x480x75Hz */
+	{Support32Bpp + SupportRAMDAC2 + SyncPP, RES800x480x85, VCLK56_25,
+	0x08, 0x00, 0x70, 800, 480},/* 36 800x480x85Hz */
+	{Support32Bpp + SupportHiVisionTV + SupportRAMDAC2 +
+	 SyncPP + SupportYPbPr, RES1024x576x60, VCLK65,
+	 0x09, 0x00, 0x71, 1024, 576},/* 37 1024x576x60Hz */
+	{Support32Bpp + SupportRAMDAC2 + SyncPP, RES1024x576x75, VCLK78_75,
+	0x09, 0x00, 0x71, 1024, 576},/* 38 1024x576x75Hz */
+	{Support32Bpp + SupportRAMDAC2 + SyncPP, RES1024x576x85, VCLK94_5,
+	0x09, 0x00, 0x71, 1024, 576},/* 39 1024x576x85Hz */
+	{Support32Bpp + SupportHiVisionTV + SupportRAMDAC2 +
+	SyncPP + SupportYPbPr, RES1280x720x60, VCLK108_2,
+	0x0A, 0x00, 0x75, 1280, 720},/* 3a 1280x720x60Hz*/
+	{Support32Bpp + SupportRAMDAC2 + SyncPP, RES1280x720x75, VCLK135_5,
+	0x0A, 0x00, 0x75, 1280, 720},/* 3b 1280x720x75Hz */
+	{Support32Bpp + SupportRAMDAC2 + SyncPP, RES1280x720x85, VCLK157_5,
+	0x0A, 0x00, 0x75, 1280, 720},/* 3c 1280x720x85Hz */
+	{Support32Bpp + SupportTV + SyncNN, RES720x480x60, VCLK28_322,
+	0x06, 0x00, 0x31,  720, 480},/* 3d 720x480x60Hz */
+	{Support32Bpp + SupportTV + SyncPP, RES720x576x56, VCLK36,
+	0x06, 0x00, 0x32, 720, 576},/* 3e 720x576x56Hz */
+	{Support32Bpp + InterlaceMode + NoSupportLCD + SyncPP, RES856x480x79I,
+	VCLK35_2, 0x00, 0x00, 0x00,  856, 480},/* 3f 856x480x79I */
+	{Support32Bpp + NoSupportLCD + SyncNN, RES856x480x60, VCLK35_2,
+	0x00, 0x00, 0x00,  856, 480},/* 40 856x480x60Hz */
+	{Support32Bpp + NoSupportHiVisionTV + SyncPP, RES1280x768x60,
+	VCLK79_411, 0x08, 0x48, 0x23, 1280, 768},/* 41 1280x768x60Hz */
+	{Support32Bpp + NoSupportHiVisionTV + SyncPP, RES1400x1050x60,
+	VCLK122_61, 0x08, 0x69, 0x26, 1400, 1050},/* 42 1400x1050x60Hz */
+	{Support32Bpp + SupportRAMDAC2 + SyncPP, RES1152x864x60, VCLK80_350,
+	0x37, 0x00, 0x20, 1152, 864},/* 43 1152x864x60Hz */
+	{Support32Bpp + SupportRAMDAC2 + SyncPP, RES1152x864x75, VCLK107_385,
+	0x37, 0x00, 0x20, 1152, 864},/* 44 1152x864x75Hz */
+	{Support32Bpp + SupportLCD + SupportRAMDAC2 + SyncPP, RES1280x960x75,
+	VCLK125_999, 0x3A, 0x88, 0x7b, 1280, 960},/* 45 1280x960x75Hz */
+	{Support32Bpp + SupportLCD + SupportRAMDAC2 + SyncPP, RES1280x960x85,
+	VCLK148_5, 0x0A, 0x88, 0x7b, 1280, 960},/* 46 1280x960x85Hz */
+	{Support32Bpp + SupportLCD + SupportRAMDAC2 + SyncPP, RES1280x960x120,
+	VCLK217_325, 0x3A, 0x88, 0x7b, 1280, 960},/* 47 1280x960x120Hz */
+	{Support32Bpp + SupportRAMDAC2 + SyncPN, RES1024x768x160, VCLK139_054,
+	0x30, 0x47, 0x37, 1024, 768},/* 48 1024x768x160Hz */
 };
 
 
 #if 0
-static struct XGI330_VCLKDataStruct XGI330_VCLKData[] =
-{
- { 0x1b,0xe1, 25}, /* 0x0 */
- { 0x4e,0xe4, 28}, /* 0x1 */
- { 0x57,0xe4, 31}, /* 0x2 */
- { 0xc3,0xc8, 36}, /* 0x3 */
- { 0x42,0xe2, 40}, /* 0x4 */
- { 0xfe,0xcd, 43}, /* 0x5 */
- { 0x5d,0xc4, 44}, /* 0x6 */
- { 0x52,0xe2, 49}, /* 0x7 */
- { 0x53,0xe2, 50}, /* 0x8 */
- { 0x74,0x67, 52}, /* 0x9 */
- { 0x6d,0x66, 56}, /* 0xa */
- { 0x6c,0xc3, 65}, /* 0xb */
- { 0x46,0x44, 67}, /* 0xc */
- { 0xb1,0x46, 68}, /* 0xd */
- { 0xd3,0x4a, 72}, /* 0xe */
- { 0x29,0x61, 75}, /* 0xf */
- { 0x6e,0x46, 76}, /* 0x10 */
- { 0x2b,0x61, 78}, /* 0x11 */
- { 0x31,0x42, 79}, /* 0x12 */
- { 0xab,0x44, 83}, /* 0x13 */
- { 0x46,0x25, 84}, /* 0x14 */
- { 0x78,0x29, 86}, /* 0x15 */
- { 0x62,0x44, 94}, /* 0x16 */
- { 0x2b,0x41,104}, /* 0x17 */
- { 0x3a,0x23,105}, /* 0x18 */
- { 0x70,0x44,108}, /* 0x19 */
- { 0x3c,0x23,109}, /* 0x1a */
- { 0x5e,0x43,113}, /* 0x1b */
- { 0xbc,0x44,116}, /* 0x1c */
- { 0xe0,0x46,132}, /* 0x1d */
- { 0x54,0x42,135}, /* 0x1e */
- { 0xea,0x2a,139}, /* 0x1f */
- { 0x41,0x22,157}, /* 0x20 */
- { 0x70,0x24,162}, /* 0x21 */
- { 0x30,0x21,175}, /* 0x22 */
- { 0x4e,0x22,189}, /* 0x23 */
- { 0xde,0x26,194}, /* 0x24 */
- { 0x62,0x06,202}, /* 0x25 */
- { 0x3f,0x03,229}, /* 0x26 */
- { 0xb8,0x06,234}, /* 0x27 */
- { 0x34,0x02,253}, /* 0x28 */
- { 0x58,0x04,255}, /* 0x29 */
- { 0x24,0x01,265}, /* 0x2a */
- { 0x9b,0x02,267}, /* 0x2b */
- { 0x70,0x05,270}, /* 0x2c */
- { 0x25,0x01,272}, /* 0x2d */
- { 0x9c,0x02,277}, /* 0x2e */
- { 0x27,0x01,286}, /* 0x2f */
- { 0x3c,0x02,291}, /* 0x30 */
- { 0xef,0x0a,292}, /* 0x31 */
- { 0xf6,0x0a,310}, /* 0x32 */
- { 0x95,0x01,315}, /* 0x33 */
- { 0xf0,0x09,324}, /* 0x34 */
- { 0xfe,0x0a,331}, /* 0x35 */
- { 0xf3,0x09,332}, /* 0x36 */
- { 0xea,0x08,340}, /* 0x37 */
- { 0xe8,0x07,376}, /* 0x38 */
- { 0xde,0x06,389}, /* 0x39 */
- { 0x52,0x2a, 54}, /* 0x3a */
- { 0x52,0x6a, 27}, /* 0x3b */
- { 0x62,0x24, 70}, /* 0x3c */
- { 0x62,0x64, 70}, /* 0x3d */
- { 0xa8,0x4c, 30}, /* 0x3e */
- { 0x20,0x26, 33}, /* 0x3f */
- { 0x31,0xc2, 39}, /* 0x40 */
- { 0x60,0x36, 30}, /* 0x41 */
- { 0x40,0x4A, 28}, /* 0x42 */
- { 0x9F,0x46, 44}, /* 0x43 */
- { 0x97,0x2C, 26}, /* 0x44 */
- { 0x44,0xE4, 25}, /* 0x45 */
- { 0x7E,0x32, 47}, /* 0x46 */
- { 0x08,0x24, 31}, /* 0x47 */
- { 0x97,0x2c, 26}, /* 0x48 */
- { 0xCE,0x3c, 39}, /* 0x49 */
- { 0x52,0x4A, 36}, /* 0x4a */
- { 0x2C,0x61, 95}, /* 0x4b */
- { 0x78,0x27,108}, /* 0x4c */
- { 0x66,0x43,123},  /* 0x4d */
- { 0x2c,0x61, 80},  /* 0x4e */
- { 0x3b,0x61,108}  /* 0x4f */
+static struct XGI330_VCLKDataStruct XGI330_VCLKData[] = {
+	{0x1b, 0xe1,  25}, /* 0x0 */
+	{0x4e, 0xe4,  28}, /* 0x1 */
+	{0x57, 0xe4,  31}, /* 0x2 */
+	{0xc3, 0xc8,  36}, /* 0x3 */
+	{0x42, 0xe2,  40}, /* 0x4 */
+	{0xfe, 0xcd,  43}, /* 0x5 */
+	{0x5d, 0xc4,  44}, /* 0x6 */
+	{0x52, 0xe2,  49}, /* 0x7 */
+	{0x53, 0xe2,  50}, /* 0x8 */
+	{0x74, 0x67,  52}, /* 0x9 */
+	{0x6d, 0x66,  56}, /* 0xa */
+	{0x6c, 0xc3,  65}, /* 0xb */
+	{0x46, 0x44,  67}, /* 0xc */
+	{0xb1, 0x46,  68}, /* 0xd */
+	{0xd3, 0x4a,  72}, /* 0xe */
+	{0x29, 0x61,  75}, /* 0xf */
+	{0x6e, 0x46,  76}, /* 0x10 */
+	{0x2b, 0x61,  78}, /* 0x11 */
+	{0x31, 0x42,  79}, /* 0x12 */
+	{0xab, 0x44,  83}, /* 0x13 */
+	{0x46, 0x25,  84}, /* 0x14 */
+	{0x78, 0x29,  86}, /* 0x15 */
+	{0x62, 0x44,  94}, /* 0x16 */
+	{0x2b, 0x41, 104}, /* 0x17 */
+	{0x3a, 0x23, 105}, /* 0x18 */
+	{0x70, 0x44, 108}, /* 0x19 */
+	{0x3c, 0x23, 109}, /* 0x1a */
+	{0x5e, 0x43, 113}, /* 0x1b */
+	{0xbc, 0x44, 116}, /* 0x1c */
+	{0xe0, 0x46, 132}, /* 0x1d */
+	{0x54, 0x42, 135}, /* 0x1e */
+	{0xea, 0x2a, 139}, /* 0x1f */
+	{0x41, 0x22, 157}, /* 0x20 */
+	{0x70, 0x24, 162}, /* 0x21 */
+	{0x30, 0x21, 175}, /* 0x22 */
+	{0x4e, 0x22, 189}, /* 0x23 */
+	{0xde, 0x26, 194}, /* 0x24 */
+	{0x62, 0x06, 202}, /* 0x25 */
+	{0x3f, 0x03, 229}, /* 0x26 */
+	{0xb8, 0x06, 234}, /* 0x27 */
+	{0x34, 0x02, 253}, /* 0x28 */
+	{0x58, 0x04, 255}, /* 0x29 */
+	{0x24, 0x01, 265}, /* 0x2a */
+	{0x9b, 0x02, 267}, /* 0x2b */
+	{0x70, 0x05, 270}, /* 0x2c */
+	{0x25, 0x01, 272}, /* 0x2d */
+	{0x9c, 0x02, 277}, /* 0x2e */
+	{0x27, 0x01, 286}, /* 0x2f */
+	{0x3c, 0x02, 291}, /* 0x30 */
+	{0xef, 0x0a, 292}, /* 0x31 */
+	{0xf6, 0x0a, 310}, /* 0x32 */
+	{0x95, 0x01, 315}, /* 0x33 */
+	{0xf0, 0x09, 324}, /* 0x34 */
+	{0xfe, 0x0a, 331}, /* 0x35 */
+	{0xf3, 0x09, 332}, /* 0x36 */
+	{0xea, 0x08, 340}, /* 0x37 */
+	{0xe8, 0x07, 376}, /* 0x38 */
+	{0xde, 0x06, 389}, /* 0x39 */
+	{0x52, 0x2a,  54}, /* 0x3a */
+	{0x52, 0x6a,  27}, /* 0x3b */
+	{0x62, 0x24,  70}, /* 0x3c */
+	{0x62, 0x64,  70}, /* 0x3d */
+	{0xa8, 0x4c,  30}, /* 0x3e */
+	{0x20, 0x26,  33}, /* 0x3f */
+	{0x31, 0xc2,  39}, /* 0x40 */
+	{0x60, 0x36,  30}, /* 0x41 */
+	{0x40, 0x4A,  28}, /* 0x42 */
+	{0x9F, 0x46,  44}, /* 0x43 */
+	{0x97, 0x2C,  26}, /* 0x44 */
+	{0x44, 0xE4,  25}, /* 0x45 */
+	{0x7E, 0x32,  47}, /* 0x46 */
+	{0x08, 0x24,  31}, /* 0x47 */
+	{0x97, 0x2c,  26}, /* 0x48 */
+	{0xCE, 0x3c,  39}, /* 0x49 */
+	{0x52, 0x4A,  36}, /* 0x4a */
+	{0x2C, 0x61,  95}, /* 0x4b */
+	{0x78, 0x27, 108}, /* 0x4c */
+	{0x66, 0x43, 123},  /* 0x4d */
+	{0x2c, 0x61,  80},  /* 0x4e */
+	{0x3b, 0x61, 108}  /* 0x4f */
 };
 
-static struct XGI_VBVCLKDataStruct XGI330_VBVCLKData[] =
-{
- { 0x1b,0xe1, 25}, /* 0x0 */
- { 0x4e,0xe4, 28}, /* 0x1 */
- { 0x57,0xe4, 31}, /* 0x2 */
- { 0xc3,0xc8, 36}, /* 0x3 */
- { 0x42,0x47, 40}, /* 0x4 */
- { 0xfe,0xcd, 43}, /* 0x5 */
- { 0x5d,0xc4, 44}, /* 0x6 */
- { 0x52,0x47, 49}, /* 0x7 */
- { 0x53,0x47, 50}, /* 0x8 */
- { 0x74,0x67, 52}, /* 0x9 */
- { 0x6d,0x66, 56}, /* 0xa */
- { 0x5a,0x64, 65}, /* 0xb */
- { 0x46,0x44, 67}, /* 0xc */
- { 0xb1,0x46, 68}, /* 0xd */
- { 0xd3,0x4a, 72}, /* 0xe */
- { 0x29,0x61, 75}, /* 0xf */
- { 0x6d,0x46, 75}, /* 0x10 */
- { 0x41,0x43, 78}, /* 0x11 */
- { 0x31,0x42, 79}, /* 0x12 */
- { 0xab,0x44, 83}, /* 0x13 */
- { 0x46,0x25, 84}, /* 0x14 */
- { 0x78,0x29, 86}, /* 0x15 */
- { 0x62,0x44, 94}, /* 0x16 */
- { 0x2b,0x22,104}, /* 0x17 */
- { 0x49,0x24,105}, /* 0x18 */
- { 0xf8,0x2f,108}, /* 0x19 */
- { 0x3c,0x23,109}, /* 0x1a */
- { 0x5e,0x43,113}, /* 0x1b */
- { 0xbc,0x44,116}, /* 0x1c */
- { 0xe0,0x46,132}, /* 0x1d */
- { 0xd4,0x28,135}, /* 0x1e */
- { 0xea,0x2a,139}, /* 0x1f */
- { 0x41,0x22,157}, /* 0x20 */
- { 0x70,0x24,162}, /* 0x21 */
- { 0x30,0x21,175}, /* 0x22 */
- { 0x4e,0x22,189}, /* 0x23 */
- { 0xde,0x26,194}, /* 0x24 */
- { 0x70,0x07,202}, /* 0x25 */
- { 0x3f,0x03,229}, /* 0x26 */
- { 0xb8,0x06,234}, /* 0x27 */
- { 0x34,0x02,253}, /* 0x28 */
- { 0x58,0x04,255}, /* 0x29 */
- { 0x24,0x01,265}, /* 0x2a */
- { 0x9b,0x02,267}, /* 0x2b */
- { 0x70,0x05,270}, /* 0x2c */
- { 0x25,0x01,272}, /* 0x2d */
- { 0x9c,0x02,277}, /* 0x2e */
- { 0x27,0x01,286}, /* 0x2f */
- { 0x3c,0x02,291}, /* 0x30 */
- { 0xef,0x0a,292}, /* 0x31 */
- { 0xf6,0x0a,310}, /* 0x32 */
- { 0x95,0x01,315}, /* 0x33 */
- { 0xf0,0x09,324}, /* 0x34 */
- { 0xfe,0x0a,331}, /* 0x35 */
- { 0xf3,0x09,332}, /* 0x36 */
- { 0xea,0x08,340}, /* 0x37 */
- { 0xe8,0x07,376}, /* 0x38 */
- { 0xde,0x06,389}, /* 0x39 */
- { 0x52,0x2a, 54}, /* 0x3a */
- { 0x52,0x6a, 27}, /* 0x3b */
- { 0x62,0x24, 70}, /* 0x3c */
- { 0x62,0x64, 70}, /* 0x3d */
- { 0xa8,0x4c, 30}, /* 0x3e */
- { 0x20,0x26, 33}, /* 0x3f */
- { 0x31,0xc2, 39}, /* 0x40 */
- { 0x2e,0x48, 25}, /* 0x41 */
- { 0x24,0x46, 25}, /* 0x42 */
- { 0x26,0x64, 28}, /* 0x43 */
- { 0x37,0x64, 40}, /* 0x44 */
- { 0xa1,0x42,108}, /* 0x45 */
- { 0x37,0x61,100}, /* 0x46 */
- { 0x78,0x27,108}, /* 0x47 */
- { 0x5e,0x64,68},  /* 0x48 chiawen for fuj1280x768*/
- { 0x70,0x44,108}, /* 0x49 chiawen for 1400x1050*/
+static struct XGI_VBVCLKDataStruct XGI330_VBVCLKData[] = {
+	{0x1b, 0xe1,  25}, /* 0x0 */
+	{0x4e, 0xe4,  28}, /* 0x1 */
+	{0x57, 0xe4,  31}, /* 0x2 */
+	{0xc3, 0xc8,  36}, /* 0x3 */
+	{0x42, 0x47,  40}, /* 0x4 */
+	{0xfe, 0xcd,  43}, /* 0x5 */
+	{0x5d, 0xc4,  44}, /* 0x6 */
+	{0x52, 0x47,  49}, /* 0x7 */
+	{0x53, 0x47,  50}, /* 0x8 */
+	{0x74, 0x67,  52}, /* 0x9 */
+	{0x6d, 0x66,  56}, /* 0xa */
+	{0x5a, 0x64,  65}, /* 0xb */
+	{0x46, 0x44,  67}, /* 0xc */
+	{0xb1, 0x46,  68}, /* 0xd */
+	{0xd3, 0x4a,  72}, /* 0xe */
+	{0x29, 0x61,  75}, /* 0xf */
+	{0x6d, 0x46,  75}, /* 0x10 */
+	{0x41, 0x43,  78}, /* 0x11 */
+	{0x31, 0x42,  79}, /* 0x12 */
+	{0xab, 0x44,  83}, /* 0x13 */
+	{0x46, 0x25,  84}, /* 0x14 */
+	{0x78, 0x29,  86}, /* 0x15 */
+	{0x62, 0x44,  94}, /* 0x16 */
+	{0x2b, 0x22, 104}, /* 0x17 */
+	{0x49, 0x24, 105}, /* 0x18 */
+	{0xf8, 0x2f, 108}, /* 0x19 */
+	{0x3c, 0x23, 109}, /* 0x1a */
+	{0x5e, 0x43, 113}, /* 0x1b */
+	{0xbc, 0x44, 116}, /* 0x1c */
+	{0xe0, 0x46, 132}, /* 0x1d */
+	{0xd4, 0x28, 135}, /* 0x1e */
+	{0xea, 0x2a, 139}, /* 0x1f */
+	{0x41, 0x22, 157}, /* 0x20 */
+	{0x70, 0x24, 162}, /* 0x21 */
+	{0x30, 0x21, 175}, /* 0x22 */
+	{0x4e, 0x22, 189}, /* 0x23 */
+	{0xde, 0x26, 194}, /* 0x24 */
+	{0x70, 0x07, 202}, /* 0x25 */
+	{0x3f, 0x03, 229}, /* 0x26 */
+	{0xb8, 0x06, 234}, /* 0x27 */
+	{0x34, 0x02, 253}, /* 0x28 */
+	{0x58, 0x04, 255}, /* 0x29 */
+	{0x24, 0x01, 265}, /* 0x2a */
+	{0x9b, 0x02, 267}, /* 0x2b */
+	{0x70, 0x05, 270}, /* 0x2c */
+	{0x25, 0x01, 272}, /* 0x2d */
+	{0x9c, 0x02, 277}, /* 0x2e */
+	{0x27, 0x01, 286}, /* 0x2f */
+	{0x3c, 0x02, 291}, /* 0x30 */
+	{0xef, 0x0a, 292}, /* 0x31 */
+	{0xf6, 0x0a, 310}, /* 0x32 */
+	{0x95, 0x01, 315}, /* 0x33 */
+	{0xf0, 0x09, 324}, /* 0x34 */
+	{0xfe, 0x0a, 331}, /* 0x35 */
+	{0xf3, 0x09, 332}, /* 0x36 */
+	{0xea, 0x08, 340}, /* 0x37 */
+	{0xe8, 0x07, 376}, /* 0x38 */
+	{0xde, 0x06, 389}, /* 0x39 */
+	{0x52, 0x2a,  54}, /* 0x3a */
+	{0x52, 0x6a,  27}, /* 0x3b */
+	{0x62, 0x24,  70}, /* 0x3c */
+	{0x62, 0x64,  70}, /* 0x3d */
+	{0xa8, 0x4c,  30}, /* 0x3e */
+	{0x20, 0x26,  33}, /* 0x3f */
+	{0x31, 0xc2,  39}, /* 0x40 */
+	{0x2e, 0x48,  25}, /* 0x41 */
+	{0x24, 0x46,  25}, /* 0x42 */
+	{0x26, 0x64,  28}, /* 0x43 */
+	{0x37, 0x64,  40}, /* 0x44 */
+	{0xa1, 0x42, 108}, /* 0x45 */
+	{0x37, 0x61, 100}, /* 0x46 */
+	{0x78, 0x27, 108}, /* 0x47 */
+	{0x5e, 0x64, 68},  /* 0x48 chiawen for fuj1280x768*/
+	{0x70, 0x44, 108}, /* 0x49 chiawen for 1400x1050*/
 };
 #endif
 
 static unsigned char XGI330_ScreenOffset[] = {
-					0x14, 0x19, 0x20, 0x28, 0x32, 0x40,
-					0x50, 0x64, 0x78, 0x80, 0x2d, 0x35,
-					0x57, 0x48};
+	0x14, 0x19, 0x20, 0x28, 0x32, 0x40,
+	0x50, 0x64, 0x78, 0x80, 0x2d, 0x35,
+	0x57, 0x48
+};
 
-static struct XGI_StResInfoStruct XGI330_StResInfo[] =
-{
- { 640,400},
- { 640,350},
- { 720,400},
- { 720,350},
- { 640,480}
+static struct XGI_StResInfoStruct XGI330_StResInfo[] = {
+	{640, 400},
+	{640, 350},
+	{720, 400},
+	{720, 350},
+	{640, 480}
 };
 
-static struct XGI_ModeResInfoStruct XGI330_ModeResInfo[] =
-{
- {  320, 200, 8, 8},
- {  320, 240, 8, 8},
- {  320, 400, 8, 8},
- {  400, 300, 8, 8},
- {  512, 384, 8, 8},
- {  640, 400, 8,16},
- {  640, 480, 8,16},
- {  800, 600, 8,16},
- { 1024, 768, 8,16},
- { 1280,1024, 8,16},
- { 1600,1200, 8,16},
- { 1920,1440, 8,16},
- { 2048,1536, 8,16},
- {  720, 480, 8,16},
- {  720, 576, 8,16},
- { 1280, 960, 8,16},
- {  800, 480, 8,16},
- { 1024, 576, 8,16},
- { 1280, 720, 8,16},
- {  856, 480, 8,16},
- { 1280, 768, 8,16},
- { 1400,1050, 8,16},
- { 1152, 864, 8,16}
+static struct XGI_ModeResInfoStruct XGI330_ModeResInfo[] = {
+	{ 320,  200, 8,  8},
+	{ 320,  240, 8,  8},
+	{ 320,  400, 8,  8},
+	{ 400,  300, 8,  8},
+	{ 512,  384, 8,  8},
+	{ 640,  400, 8, 16},
+	{ 640,  480, 8, 16},
+	{ 800,  600, 8, 16},
+	{1024,  768, 8, 16},
+	{1280, 1024, 8, 16},
+	{1600, 1200, 8, 16},
+	{1920, 1440, 8, 16},
+	{2048, 1536, 8, 16},
+	{ 720,  480, 8, 16},
+	{ 720,  576, 8, 16},
+	{1280,  960, 8, 16},
+	{ 800,  480, 8, 16},
+	{1024,  576, 8, 16},
+	{1280,  720, 8, 16},
+	{ 856,  480, 8, 16},
+	{1280,  768, 8, 16},
+	{1400, 1050, 8, 16},
+	{1152,  864, 8, 16}
 };
 
 static unsigned char XGI330_OutputSelect = 0x40;
@@ -3441,22 +3593,22 @@
 
 #if 0
 static unsigned char XGI330New_SR15[8][8] = {
-{0x0,0x4,0x60,0x60},
-{0xf,0xf,0xf,0xf},
-{0xba,0xba,0xba,0xba},
-{0xa9,0xa9,0xac,0xac},
-{0xa0,0xa0,0xa0,0xa8},
-{0x0,0x0,0x2,0x2},
-{0x30,0x30,0x40,0x40},
-{0x0,0xa5,0xfb,0xf6}
+	{ 0x0,  0x4, 0x60, 0x60},
+	{ 0xf,  0xf,  0xf,  0xf},
+	{0xba, 0xba, 0xba, 0xba},
+	{0xa9, 0xa9, 0xac, 0xac},
+	{0xa0, 0xa0, 0xa0, 0xa8},
+	{ 0x0,  0x0,  0x2,  0x2},
+	{0x30, 0x30, 0x40, 0x40},
+	{ 0x0, 0xa5, 0xfb, 0xf6}
 };
 
 static unsigned char XGI330New_CR40[5][8] = {
-{0x77,0x77,0x44,0x44},
-{0x77,0x77,0x44,0x44},
-{0x0,0x0,0x0,0x0},
-{0x5b,0x5b,0xab,0xab},
-{0x0,0x0,0xf0,0xf8}
+	{0x77, 0x77, 0x44, 0x44},
+	{0x77, 0x77, 0x44, 0x44},
+	{ 0x0,  0x0,  0x0,  0x0},
+	{0x5b, 0x5b, 0xab, 0xab},
+	{ 0x0,  0x0, 0xf0, 0xf8}
 };
 #endif
 
@@ -3509,7 +3661,9 @@
 static unsigned char XG27_CR97 = 0xC1 ;
 static unsigned char XG27_SR36 = 0x30 ;
 static unsigned char XG27_CR8F = 0x0C ;
-static unsigned char XG27_CRD0[] = {0, 0, 0, 0, 0, 0, 0, 0x82, 0x00, 0x66, 0x01, 0x00};
+static unsigned char XG27_CRD0[] = {
+	0, 0, 0, 0, 0, 0, 0, 0x82, 0x00, 0x66, 0x01, 0x00
+};
 static unsigned char XG27_CRDE[] = {0, 0};
 static unsigned char XG27_SR40 = 0x04 ;
 static unsigned char XG27_SR41 = 0x00 ;
@@ -3522,871 +3676,660 @@
 
 static unsigned char XGI330_CHTVVCLKOPAL[] = {0x00};
 
-static unsigned char XGI7007_CHTVVCLKUNTSC[] = {CH7007TVVCLK30_2,
-                               CH7007TVVCLK30_2,
-                               CH7007TVVCLK30_2,
-                               CH7007TVVCLK30_2,
-                               CH7007TVVCLK28_1,
-                               CH7007TVVCLK47_8
-                              };
-
-static unsigned char XGI7007_CHTVVCLKONTSC[] = {CH7007TVVCLK26_4,
-                               CH7007TVVCLK26_4,
-                               CH7007TVVCLK26_4,
-                               CH7007TVVCLK26_4,
-                               CH7007TVVCLK24_6,
-                               CH7007TVVCLK43_6
-                              };
-
-static unsigned char XGI7007_CHTVVCLKUPAL[] = {CH7007TVVCLK31_5,
-                              CH7007TVVCLK31_5,
-                              CH7007TVVCLK31_5,
-                              CH7007TVVCLK31_5,
-                              CH7007TVVCLK26_2,
-                              CH7007TVVCLK39
-                             };
-
-static unsigned char XGI7007_CHTVVCLKOPAL[] = {CH7007TVVCLK31_5,
-                              CH7007TVVCLK31_5,
-                              CH7007TVVCLK31_5,
-                              CH7007TVVCLK31_5,
-                              CH7007TVVCLK26_2,
-                              CH7007TVVCLK36
-                             };
-
-static struct XGI330_VCLKDataStruct XGI_CH7007VCLKData[] =
-{
- { 0x60,0x36,30},  /* 0 30.2 MHZ */
- { 0x40,0x4A,28},  /* 1 28.19 MHZ */
- { 0x9F,0x46,44},  /* 2 43.6 MHZ */
- { 0x97,0x2C,26},  /* 3 26.4 MHZ */
- { 0x44,0xE4,25},  /* 4 24.6 MHZ */
- { 0x7E,0x32,47},  /* 5 47.832 MHZ */
- { 0x8A,0x24,31},  /* 6 31.5 MHZ */
- { 0x97,0x2C,26},  /* 7 26.2 MHZ */
- { 0xCE,0x3C,39},  /* 8 39 MHZ   */
- { 0x52,0x4A,36},  /* 9 36 MHZ   */
- { 0xFF,0x00,0 }   /* End mark      */
+static unsigned char XGI7007_CHTVVCLKUNTSC[] = {
+	CH7007TVVCLK30_2,
+	CH7007TVVCLK30_2,
+	CH7007TVVCLK30_2,
+	CH7007TVVCLK30_2,
+	CH7007TVVCLK28_1,
+	CH7007TVVCLK47_8
 };
 
-static struct XGI330_VCLKDataStruct XGI_VCLKData[] =
-{
-               	/* SR2B,SR2C,SR2D */
- 		{      0x1B,0xE1,25               },/* 00 (25.175MHz) */
-
-		{      0x4E,0xE4,28               },/* 01 (28.322MHz) */
-
-                {      0x57,0xE4,31               },/* 02 (31.500MHz) */
-
-                {      0xC3,0xC8,36               },/* 03 (36.000MHz) */
-
-                {      0x42,0xE2,40               },/* 04 (40.000MHz) */
-
-                {      0xFE,0xCD,43               },/* 05 (43.163MHz) */
-
-                {      0x5D,0xC4,44               },/* 06 (44.900MHz) */
-
-                {      0x52,0xE2,49               },/* 07 (49.500MHz) */
-
-                {      0x53,0xE2,50               },/* 08 (50.000MHz) */
-
-                {      0x74,0x67,52               },/* 09 (52.406MHz) */
-
-                {      0x6D,0x66,56               },/* 0A (56.250MHz) */
-
-                {      0x6C,0xC3,65               },/* 0B (65.000MHz) */
-
-                {      0x46,0x44,67               },/* 0C (67.765MHz) */
-
-                {      0xB1,0x46,68               },/* 0D (68.179MHz) */
-
-                {      0xD3,0x4A,72               },/* 0E (72.852MHz) */
-
-                {      0x29,0x61,75              },/* 0F (75.000MHz) */
-
-                {      0x6E,0x46,76               },/* 10 (75.800MHz) */
-
-                {      0x2B,0x61,78               },/* 11 (78.750MHz) */
-
-                {      0x31,0x42,79               },/* 12 (79.411MHz) */
-
-                {      0xAB,0x44,83               },/* 13 (83.950MHz) */
-
-                {      0x46,0x25,84               },/* 14 (84.800MHz) */
-
-                {      0x78,0x29,86               },/* 15 (86.600MHz) */
-
-                {      0x62,0x44,94               },/* 16 (94.500MHz) */
-
-                {      0x2B,0x41,104               },/* 17 (104.998MHz) */
-
-                {      0x3A,0x23,105               },/* 18 (105.882MHz) */
-
-                {      0x70,0x44,108               },/* 19 (107.862MHz) */
-
-                {      0x3C,0x23,109               },/* 1A (109.175MHz) */
-
-                {      0x5E,0x43,113              },/* 1B (113.309MHz) */
-
-                {      0xBC,0x44,116              },/* 1C (116.406MHz) */
-
-                {      0xE0,0x46,132              },/* 1D (132.258MHz) */
-
-                {      0x54,0x42,135               },/* 1E (135.500MHz) */
-
-                {      0x9C,0x22,139               },/* 1F (139.275MHz) */
-
-                {      0x41,0x22,157               },/* 20 (157.500MHz) */
-
-                {      0x70,0x24,162               },/* 21 (161.793MHz) */
-
-                {      0x30,0x21,175               },/* 22 (175.000MHz) */
-
-                {      0x4E,0x22,189              },/* 23 (188.520MHz) */
-
-                {      0xDE,0x26,194              },/* 24 (194.400MHz) */
-
-                {      0x62,0x06,202               },/* 25 (202.500MHz) */
-
-                {      0x3F,0x03,229               },/* 26 (229.500MHz) */
-
-                {      0xB8,0x06,234               },/* 27 (233.178MHz) */
-
-                {      0x34,0x02,253               },/* 28 (252.699MHz) */
-
-                {      0x58,0x04,255               },/* 29 (254.817MHz) */
-
-                {      0x24,0x01,265              },/* 2A (265.728MHz) */
-
-                {      0x9B,0x02,267               },/* 2B (266.952MHz) */
-
-                {      0x70,0x05,270               },/* 2C (269.65567MHz) */
-
-                {      0x25,0x01,272               },/* 2D (272.04199MHz) */
-
-                {      0x9C,0x02,277               },/* 2E (277.015MHz) */
-
-                {      0x27,0x01,286               },/* 2F (286.359985MHz) */
-
-                {      0xB3,0x04,291               },/* 30 (291.13266MHz) */
-
-                {      0xBC,0x05,292               },/* 31 (291.766MHz) */
-
-                {      0xF6,0x0A,310               },/* 32 (309.789459MHz) */
-
-                {      0x95,0x01,315               },/* 33 (315.195MHz) */
-
-                {      0xF0,0x09,324               },/* 34 (323.586792MHz) */
-
-                {      0xFE,0x0A,331               },/* 35 (330.615631MHz) */
-
-                {      0xF3,0x09,332              },/* 36 (332.177612MHz) */
-
-                {      0x5E,0x03,340              },/* 37 (340.477MHz) */
-
-                {      0xE8,0x07,376              },/* 38 (375.847504MHz) */
-
-                {      0xDE, 0x06,389             },/* 39 (388.631439MHz) */
-
-                {      0x52,0x2A,54               },/* 3A (54.000MHz) */
-
-                {      0x52,0x6A,27              },/* 3B (27.000MHz) */
-
-                {      0x62,0x24,70               },/* 3C (70.874991MHz) */
-
-                {      0x62,0x64,70               },/* 3D (70.1048912MHz) */
-
-                {      0xA8,0x4C,30               },/* 3E (30.1048912MHz) */
-
-                {      0x20,0x26,33               },/* 3F (33.7499957MHz) */
-
-                {      0x31,0xc2,39               },/* 40 (39.77MHz) */
-
-                {      0x11,0x21,30               },/* 41 (30MHz) }// NTSC 1024X768 */
-
-                {      0x2E,0x48,25               },/* 42 (25.175MHz) }// ScaleLCD */
-
-                {      0x24,0x46,25               },/* 43 (25.175MHz) */
-
-                {      0x26,0x64,28               },/* 44 (28.322MHz) */
-
-                {      0x37,0x64,40               },/* 45 (40.000MHz) */
-
-                {      0xA1,0x42,108               },/* 46 (95.000MHz) }// QVGA */
-
-                {      0x37,0x61,100               },/* 47 (100.00MHz) */
-
-                {      0x78,0x27,108               },/* 48 (108.200MHz) */
-
-                {      0xBF,0xC8,35               },/* 49 (35.2MHz) */
-
-                {      0x66,0x43,123               },/* 4A (122.61Mhz) */
-
-                {      0x2C,0x61,80               },/* 4B (80.350Mhz) */
-
-                {      0x3B,0x61,108               },/* 4C (107.385Mhz) */
-
-
-/*                {      0x60,0x36,30               },// 4D (30.200MHz)   }// No use
-
-                {      0x60,0x36,30               },// 4E (30.200MHz)   }// No use
-
-                {      0x60,0x36,30               },// 4F (30.200MHz)   }// No use
-
-                {      0x60,0x36,30               },// 50 (30.200MHz)   }// CHTV
-
-                {      0x40,0x4A,28               },// 51 (28.190MHz)
-
-                {      0x9F,0x46,44               },// 52 (43.600MHz)
-
-                {      0x97,0x2C,26               },// 53 (26.400MHz)
-
-                {      0x44,0xE4,25               },// 54 (24.600MHz)
-
-                {      0x7E,0x32,47               },// 55 (47.832MHz)
-
-                {      0x8A,0x24,31               },// 56 (31.500MHz)
+static unsigned char XGI7007_CHTVVCLKONTSC[] = {
+	CH7007TVVCLK26_4,
+	CH7007TVVCLK26_4,
+	CH7007TVVCLK26_4,
+	CH7007TVVCLK26_4,
+	CH7007TVVCLK24_6,
+	CH7007TVVCLK43_6
+};
 
-                {      0x97,0x2C,26               },// 57 (26.200MHz)
+static unsigned char XGI7007_CHTVVCLKUPAL[] = {
+	CH7007TVVCLK31_5,
+	CH7007TVVCLK31_5,
+	CH7007TVVCLK31_5,
+	CH7007TVVCLK31_5,
+	CH7007TVVCLK26_2,
+	CH7007TVVCLK39
+};
 
-                {      0xCE,0x3C,39               },// 58 (39.000MHz)
+static unsigned char XGI7007_CHTVVCLKOPAL[] = {
+	CH7007TVVCLK31_5,
+	CH7007TVVCLK31_5,
+	CH7007TVVCLK31_5,
+	CH7007TVVCLK31_5,
+	CH7007TVVCLK26_2,
+	CH7007TVVCLK36
+};
 
-                {      0x52,0x4A,36               },// 59 (36.000MHz)
+static struct XGI330_VCLKDataStruct XGI_CH7007VCLKData[] = {
+	{0x60, 0x36, 30},  /* 0 30.2 MHZ */
+	{0x40, 0x4A, 28},  /* 1 28.19 MHZ */
+	{0x9F, 0x46, 44},  /* 2 43.6 MHZ */
+	{0x97, 0x2C, 26},  /* 3 26.4 MHZ */
+	{0x44, 0xE4, 25},  /* 4 24.6 MHZ */
+	{0x7E, 0x32, 47},  /* 5 47.832 MHZ */
+	{0x8A, 0x24, 31},  /* 6 31.5 MHZ */
+	{0x97, 0x2C, 26},  /* 7 26.2 MHZ */
+	{0xCE, 0x3C, 39},  /* 8 39 MHZ   */
+	{0x52, 0x4A, 36},  /* 9 36 MHZ   */
+	{0xFF, 0x00,  0}   /* End mark      */
+};
 
+static struct XGI330_VCLKDataStruct XGI_VCLKData[] = {
+	/* SR2B,SR2C,SR2D */
+	{0x1B, 0xE1,  25}, /* 00 (25.175MHz) */
+	{0x4E, 0xE4,  28}, /* 01 (28.322MHz) */
+	{0x57, 0xE4,  31}, /* 02 (31.500MHz) */
+	{0xC3, 0xC8,  36}, /* 03 (36.000MHz) */
+	{0x42, 0xE2,  40}, /* 04 (40.000MHz) */
+	{0xFE, 0xCD,  43}, /* 05 (43.163MHz) */
+	{0x5D, 0xC4,  44}, /* 06 (44.900MHz) */
+	{0x52, 0xE2,  49}, /* 07 (49.500MHz) */
+	{0x53, 0xE2,  50}, /* 08 (50.000MHz) */
+	{0x74, 0x67,  52}, /* 09 (52.406MHz) */
+	{0x6D, 0x66,  56}, /* 0A (56.250MHz) */
+	{0x6C, 0xC3,  65}, /* 0B (65.000MHz) */
+	{0x46, 0x44,  67}, /* 0C (67.765MHz) */
+	{0xB1, 0x46,  68}, /* 0D (68.179MHz) */
+	{0xD3, 0x4A,  72}, /* 0E (72.852MHz) */
+	{0x29, 0x61,  75}, /* 0F (75.000MHz) */
+	{0x6E, 0x46,  76}, /* 10 (75.800MHz) */
+	{0x2B, 0x61,  78}, /* 11 (78.750MHz) */
+	{0x31, 0x42,  79}, /* 12 (79.411MHz) */
+	{0xAB, 0x44,  83}, /* 13 (83.950MHz) */
+	{0x46, 0x25,  84}, /* 14 (84.800MHz) */
+	{0x78, 0x29,  86}, /* 15 (86.600MHz) */
+	{0x62, 0x44,  94}, /* 16 (94.500MHz) */
+	{0x2B, 0x41, 104}, /* 17 (104.998MHz) */
+	{0x3A, 0x23, 105}, /* 18 (105.882MHz) */
+	{0x70, 0x44, 108}, /* 19 (107.862MHz) */
+	{0x3C, 0x23, 109}, /* 1A (109.175MHz) */
+	{0x5E, 0x43, 113}, /* 1B (113.309MHz) */
+	{0xBC, 0x44, 116}, /* 1C (116.406MHz) */
+	{0xE0, 0x46, 132}, /* 1D (132.258MHz) */
+	{0x54, 0x42, 135}, /* 1E (135.500MHz) */
+	{0x9C, 0x22, 139}, /* 1F (139.275MHz) */
+	{0x41, 0x22, 157}, /* 20 (157.500MHz) */
+	{0x70, 0x24, 162}, /* 21 (161.793MHz) */
+	{0x30, 0x21, 175}, /* 22 (175.000MHz) */
+	{0x4E, 0x22, 189}, /* 23 (188.520MHz) */
+	{0xDE, 0x26, 194}, /* 24 (194.400MHz) */
+	{0x62, 0x06, 202}, /* 25 (202.500MHz) */
+	{0x3F, 0x03, 229}, /* 26 (229.500MHz) */
+	{0xB8, 0x06, 234}, /* 27 (233.178MHz) */
+	{0x34, 0x02, 253}, /* 28 (252.699MHz) */
+	{0x58, 0x04, 255}, /* 29 (254.817MHz) */
+	{0x24, 0x01, 265}, /* 2A (265.728MHz) */
+	{0x9B, 0x02, 267}, /* 2B (266.952MHz) */
+	{0x70, 0x05, 270}, /* 2C (269.65567MHz) */
+	{0x25, 0x01, 272}, /* 2D (272.04199MHz) */
+	{0x9C, 0x02, 277}, /* 2E (277.015MHz) */
+	{0x27, 0x01, 286}, /* 2F (286.359985MHz) */
+	{0xB3, 0x04, 291}, /* 30 (291.13266MHz) */
+	{0xBC, 0x05, 292}, /* 31 (291.766MHz) */
+	{0xF6, 0x0A, 310}, /* 32 (309.789459MHz) */
+	{0x95, 0x01, 315}, /* 33 (315.195MHz) */
+	{0xF0, 0x09, 324}, /* 34 (323.586792MHz) */
+	{0xFE, 0x0A, 331}, /* 35 (330.615631MHz) */
+	{0xF3, 0x09, 332}, /* 36 (332.177612MHz) */
+	{0x5E, 0x03, 340}, /* 37 (340.477MHz) */
+	{0xE8, 0x07, 376}, /* 38 (375.847504MHz) */
+	{0xDE, 0x06, 389}, /* 39 (388.631439MHz) */
+	{0x52, 0x2A,  54}, /* 3A (54.000MHz) */
+	{0x52, 0x6A,  27}, /* 3B (27.000MHz) */
+	{0x62, 0x24,  70}, /* 3C (70.874991MHz) */
+	{0x62, 0x64,  70}, /* 3D (70.1048912MHz) */
+	{0xA8, 0x4C,  30}, /* 3E (30.1048912MHz) */
+	{0x20, 0x26,  33}, /* 3F (33.7499957MHz) */
+	{0x31, 0xc2,  39}, /* 40 (39.77MHz) */
+	{0x11, 0x21,  30}, /* 41 (30MHz) }// NTSC 1024X768 */
+	{0x2E, 0x48,  25}, /* 42 (25.175MHz) }// ScaleLCD */
+	{0x24, 0x46,  25}, /* 43 (25.175MHz) */
+	{0x26, 0x64,  28}, /* 44 (28.322MHz) */
+	{0x37, 0x64,  40}, /* 45 (40.000MHz) */
+	{0xA1, 0x42, 108}, /* 46 (95.000MHz) }// QVGA */
+	{0x37, 0x61, 100}, /* 47 (100.00MHz) */
+	{0x78, 0x27, 108}, /* 48 (108.200MHz) */
+	{0xBF, 0xC8,  35}, /* 49 (35.2MHz) */
+	{0x66, 0x43, 123}, /* 4A (122.61Mhz) */
+	{0x2C, 0x61,  80}, /* 4B (80.350Mhz) */
+	{0x3B, 0x61, 108}, /* 4C (107.385Mhz) */
+/*
+	{0x60, 0x36, 30},// 4D (30.200MHz)   }// No use
+	{0x60, 0x36, 30},// 4E (30.200MHz)   }// No use
+	{0x60, 0x36, 30},// 4F (30.200MHz)   }// No use
+	{0x60, 0x36, 30},// 50 (30.200MHz)   }// CHTV
+	{0x40, 0x4A, 28},// 51 (28.190MHz)
+	{0x9F, 0x46, 44},// 52 (43.600MHz)
+	{0x97, 0x2C, 26},// 53 (26.400MHz)
+	{0x44, 0xE4, 25},// 54 (24.600MHz)
+	{0x7E, 0x32, 47},// 55 (47.832MHz)
+	{0x8A, 0x24, 31},// 56 (31.500MHz)
+	{0x97, 0x2C, 26},// 57 (26.200MHz)
+	{0xCE, 0x3C, 39},// 58 (39.000MHz)
+	{0x52, 0x4A, 36},// 59 (36.000MHz)
 */
-		{      0x69,0x61,191		  }, /* 4D (190.96MHz ) */
-		{      0x4F,0x22,192		  }, /* 4E (192.069MHz) */
-		{      0x28,0x26,322		  }, /* 4F (322.273MHz) */
-		{      0x5C,0x6B,27		  }, /* 50 (27.74HMz) */
-		{      0x57,0x24,126		  }, /* 51 (125.999MHz) */
-		{      0x5C,0x42,148		  }, /* 52 (148.5MHz) */
-		{      0x42,0x61,120		  }, /* 53 (120.839MHz) */
-		{      0x62,0x61,178		  }, /* 54 (178.992MHz) */
-		{      0x59,0x22,217		  }, /* 55 (217.325MHz) */
-		{      0x29,0x01,300		  }, /* 56 (299.505Mhz) */
-		{      0x52,0x63,74		  }, /* 57 (74.25MHz) */
-
-
-                {      0xFF,0x00,0                }/* End mark */
- }  ;
-
-static struct XGI330_VCLKDataStruct XGI_VBVCLKData[] =
-{
-                {      0x1B,0xE1,25               },/* 00 (25.175MHz) */
-
-                {      0x4E,0xE4,28               },/* 01 (28.322MHz) */
-
-                {      0x57,0xE4,31               },/* 02 (31.500MHz) */
-
-                {      0xC3,0xC8,36               },/* 03 (36.000MHz) */
-
-                {      0x42,0x47,40               },/* 04 (40.000MHz) */
-
-                {      0xFE,0xCD,43               },/* 05 (43.163MHz) */
-
-                {      0x5D,0xC4,44               },/* 06 (44.900MHz) */
-
-                {      0x52,0x47,49               },/* 07 (49.500MHz) */
-
-                {      0x53,0x47,50               },/* 08 (50.000MHz) */
-
-                {      0x74,0x67,52               },/* 09 (52.406MHz) */
-
-                {      0x6D,0x66,56               },/* 0A (56.250MHz) */
-
-                {      0x35,0x62,65               },/* 0B (65.000MHz) */
-
-                {      0x46,0x44,67               },/* 0C (67.765MHz) */
-
-                {      0xB1,0x46,68               },/* 0D (68.179MHz) */
-
-                {      0xD3,0x4A,72               },/* 0E (72.852MHz) */
-
-                {      0x29,0x61,75               },/* 0F (75.000MHz) */
-
-                {      0x6D,0x46,75               },/* 10 (75.800MHz) */
-
-                {      0x41,0x43,78               },/* 11 (78.750MHz) */
-
-                {      0x31,0x42,79               },/* 12 (79.411MHz) */
-
-                {      0xAB,0x44,83               },/* 13 (83.950MHz) */
-
-                {      0x46,0x25,84               },/* 14 (84.800MHz) */
-
-                {      0x78,0x29,86               },/* 15 (86.600MHz) */
-
-                {      0x62,0x44,94               },/* 16 (94.500MHz) */
-
-                {      0x2B,0x22,104               },/* 17 (104.998MHz) */
-
-                {      0x49,0x24,105               },/* 18 (105.882MHz) */
-
-                {      0xF8,0x2F,108               },/* 19 (108.279MHz) */
-
-                {      0x3C,0x23,109               },/* 1A (109.175MHz) */
-
-                {      0x5E,0x43,113               },/* 1B (113.309MHz) */
-
-                {      0xBC,0x44,116               },/* 1C (116.406MHz) */
-
-                {      0xE0,0x46,132               },/* 1D (132.258MHz) */
-
-                {      0xD4,0x28,135               },/* 1E (135.220MHz) */
-
-                {      0xEA,0x2A,139               },/* 1F (139.275MHz) */
-
-                {      0x41,0x22,157               },/* 20 (157.500MHz) */
-
-                {      0x70,0x24,162               },/* 21 (161.793MHz) */
-
-                {      0x30,0x21,175               },/* 22 (175.000MHz) */
-
-                {      0x4E,0x22,189               },/* 23 (188.520MHz) */
-
-                {      0xDE,0x26,194               },/* 24 (194.400MHz) */
-
-                {      0x70,0x07,202               },/* 25 (202.500MHz) */
-
-                {      0x3F,0x03,229               },/* 26 (229.500MHz) */
-
-                {      0xB8,0x06,234               },/* 27 (233.178MHz) */
-
-                {      0x34,0x02,253               },/* 28 (252.699997 MHz) */
-
-                {      0x58,0x04,255               },/* 29 (254.817MHz) */
-
-                {      0x24,0x01,265               },/* 2A (265.728MHz) */
-
-                {      0x9B,0x02,267               },/* 2B (266.952MHz) */
-
-                {      0x70,0x05,270               },/* 2C (269.65567 MHz) */
-
-                {      0x25,0x01,272               },/* 2D (272.041992 MHz) */
-
-                {      0x9C,0x02,277               },/* 2E (277.015MHz) */
-
-                {      0x27,0x01,286               },/* 2F (286.359985 MHz) */
-
-                {      0x3C,0x02,291               },/* 30 (291.132660 MHz) */
-
-                {      0xEF,0x0A,292               },/* 31 (291.766MHz) */
-
-                {      0xF6,0x0A,310               },/* 32 (309.789459 MHz) */
-
-                {      0x95,0x01,315               },/* 33 (315.195MHz) */
-
-                {      0xF0,0x09,324               },/* 34 (323.586792 MHz) */
-
-                {      0xFE,0x0A,331               },/* 35 (330.615631 MHz) */
-
-                {      0xF3,0x09,332               },/* 36 (332.177612 MHz) */
-
-                {      0xEA,0x08,340               },/* 37 (340.477MHz) */
-
-                {      0xE8,0x07,376               },/* 38 (375.847504 MHz) */
-
-                {      0xDE,0x06,389               },/* 39 (388.631439 MHz) */
-
-                {      0x52,0x2A,54                },/* 3A (54.000MHz) */
-
-                {      0x52,0x6A,27                },/* 3B (27.000MHz) */
-
-
-                {      0x62,0x24,70                },/* 3C (70.874991MHz) */
-
-
-                {      0x62,0x64,70                },/* 3D (70.1048912MHz) */
-
-                {      0xA8,0x4C,30                },/* 3E (30.1048912MHz) */
-
-                {      0x20,0x26,33                },/* 3F (33.7499957MHz) */
-
-                {      0x31,0xc2,39                },/* 40 (39.77MHz) */
-
-                {      0x11,0x21,30                },/* 41 (30MHz) }// NTSC 1024X768 */
-
-                {      0x2E,0x48,25                },/* 42 (25.175MHz) }// ScaleLCD */
-
-                {      0x24,0x46,25                },/* 43 (25.175MHz) */
-
-                {      0x26,0x64,28                },/* 44 (28.322MHz) */
-
-                {      0x37,0x64,40                },/* 45 (40.000MHz) */
-
-                {      0xA1,0x42,108               },/* 46 (95.000MHz) }// QVGA */
-
-                {      0x37,0x61,100               },/* 47 (100.00MHz) */
-
-                {      0x78,0x27,108               },/* 48 (108.200MHz) */
-
-                {      0xBF,0xC8,35                },/* 49 (35.2MHz) */
-
-                {      0x66,0x43,123               },/* 4A (122.61Mhz) */
-
-                {      0x2C,0x61,80                },/* 4B (80.350Mhz) */
-
-                {      0x3B,0x61,108               },/* 4C (107.385Mhz) */
+	{0x69, 0x61, 191}, /* 4D (190.96MHz ) */
+	{0x4F, 0x22, 192}, /* 4E (192.069MHz) */
+	{0x28, 0x26, 322}, /* 4F (322.273MHz) */
+	{0x5C, 0x6B,  27}, /* 50 (27.74HMz) */
+	{0x57, 0x24, 126}, /* 51 (125.999MHz) */
+	{0x5C, 0x42, 148}, /* 52 (148.5MHz) */
+	{0x42, 0x61, 120}, /* 53 (120.839MHz) */
+	{0x62, 0x61, 178}, /* 54 (178.992MHz) */
+	{0x59, 0x22, 217}, /* 55 (217.325MHz) */
+	{0x29, 0x01, 300}, /* 56 (299.505Mhz) */
+	{0x52, 0x63,  74}, /* 57 (74.25MHz) */
+	{0xFF, 0x00,   0}  /* End mark */
+};
 
+static struct XGI330_VCLKDataStruct XGI_VBVCLKData[] = {
+	{0x1B, 0xE1,  25}, /* 00 (25.175MHz) */
+	{0x4E, 0xE4,  28}, /* 01 (28.322MHz) */
+	{0x57, 0xE4,  31}, /* 02 (31.500MHz) */
+	{0xC3, 0xC8,  36}, /* 03 (36.000MHz) */
+	{0x42, 0x47,  40}, /* 04 (40.000MHz) */
+	{0xFE, 0xCD,  43}, /* 05 (43.163MHz) */
+	{0x5D, 0xC4,  44}, /* 06 (44.900MHz) */
+	{0x52, 0x47,  49}, /* 07 (49.500MHz) */
+	{0x53, 0x47,  50}, /* 08 (50.000MHz) */
+	{0x74, 0x67,  52}, /* 09 (52.406MHz) */
+	{0x6D, 0x66,  56}, /* 0A (56.250MHz) */
+	{0x35, 0x62,  65}, /* 0B (65.000MHz) */
+	{0x46, 0x44,  67}, /* 0C (67.765MHz) */
+	{0xB1, 0x46,  68}, /* 0D (68.179MHz) */
+	{0xD3, 0x4A,  72}, /* 0E (72.852MHz) */
+	{0x29, 0x61,  75}, /* 0F (75.000MHz) */
+	{0x6D, 0x46,  75}, /* 10 (75.800MHz) */
+	{0x41, 0x43,  78}, /* 11 (78.750MHz) */
+	{0x31, 0x42,  79}, /* 12 (79.411MHz) */
+	{0xAB, 0x44,  83}, /* 13 (83.950MHz) */
+	{0x46, 0x25,  84}, /* 14 (84.800MHz) */
+	{0x78, 0x29,  86}, /* 15 (86.600MHz) */
+	{0x62, 0x44,  94}, /* 16 (94.500MHz) */
+	{0x2B, 0x22, 104}, /* 17 (104.998MHz) */
+	{0x49, 0x24, 105}, /* 18 (105.882MHz) */
+	{0xF8, 0x2F, 108}, /* 19 (108.279MHz) */
+	{0x3C, 0x23, 109}, /* 1A (109.175MHz) */
+	{0x5E, 0x43, 113}, /* 1B (113.309MHz) */
+	{0xBC, 0x44, 116}, /* 1C (116.406MHz) */
+	{0xE0, 0x46, 132}, /* 1D (132.258MHz) */
+	{0xD4, 0x28, 135}, /* 1E (135.220MHz) */
+	{0xEA, 0x2A, 139}, /* 1F (139.275MHz) */
+	{0x41, 0x22, 157}, /* 20 (157.500MHz) */
+	{0x70, 0x24, 162}, /* 21 (161.793MHz) */
+	{0x30, 0x21, 175}, /* 22 (175.000MHz) */
+	{0x4E, 0x22, 189}, /* 23 (188.520MHz) */
+	{0xDE, 0x26, 194}, /* 24 (194.400MHz) */
+	{0x70, 0x07, 202}, /* 25 (202.500MHz) */
+	{0x3F, 0x03, 229}, /* 26 (229.500MHz) */
+	{0xB8, 0x06, 234}, /* 27 (233.178MHz) */
+	{0x34, 0x02, 253}, /* 28 (252.699997 MHz) */
+	{0x58, 0x04, 255}, /* 29 (254.817MHz) */
+	{0x24, 0x01, 265}, /* 2A (265.728MHz) */
+	{0x9B, 0x02, 267}, /* 2B (266.952MHz) */
+	{0x70, 0x05, 270}, /* 2C (269.65567 MHz) */
+	{0x25, 0x01, 272}, /* 2D (272.041992 MHz) */
+	{0x9C, 0x02, 277}, /* 2E (277.015MHz) */
+	{0x27, 0x01, 286}, /* 2F (286.359985 MHz) */
+	{0x3C, 0x02, 291}, /* 30 (291.132660 MHz) */
+	{0xEF, 0x0A, 292}, /* 31 (291.766MHz) */
+	{0xF6, 0x0A, 310}, /* 32 (309.789459 MHz) */
+	{0x95, 0x01, 315}, /* 33 (315.195MHz) */
+	{0xF0, 0x09, 324}, /* 34 (323.586792 MHz) */
+	{0xFE, 0x0A, 331}, /* 35 (330.615631 MHz) */
+	{0xF3, 0x09, 332}, /* 36 (332.177612 MHz) */
+	{0xEA, 0x08, 340}, /* 37 (340.477MHz) */
+	{0xE8, 0x07, 376}, /* 38 (375.847504 MHz) */
+	{0xDE, 0x06, 389}, /* 39 (388.631439 MHz) */
+	{0x52, 0x2A,  54}, /* 3A (54.000MHz) */
+	{0x52, 0x6A,  27}, /* 3B (27.000MHz) */
+	{0x62, 0x24,  70}, /* 3C (70.874991MHz) */
+	{0x62, 0x64,  70}, /* 3D (70.1048912MHz) */
+	{0xA8, 0x4C,  30}, /* 3E (30.1048912MHz) */
+	{0x20, 0x26,  33}, /* 3F (33.7499957MHz) */
+	{0x31, 0xc2,  39}, /* 40 (39.77MHz) */
+	{0x11, 0x21,  30}, /* 41 (30MHz) }// NTSC 1024X768 */
+	{0x2E, 0x48,  25}, /* 42 (25.175MHz) }// ScaleLCD */
+	{0x24, 0x46,  25}, /* 43 (25.175MHz) */
+	{0x26, 0x64,  28}, /* 44 (28.322MHz) */
+	{0x37, 0x64,  40}, /* 45 (40.000MHz) */
+	{0xA1, 0x42, 108}, /* 46 (95.000MHz) }// QVGA */
+	{0x37, 0x61, 100}, /* 47 (100.00MHz) */
+	{0x78, 0x27, 108}, /* 48 (108.200MHz) */
+	{0xBF, 0xC8, 35 }, /* 49 (35.2MHz) */
+	{0x66, 0x43, 123}, /* 4A (122.61Mhz) */
+	{0x2C, 0x61, 80 }, /* 4B (80.350Mhz) */
+	{0x3B, 0x61, 108}, /* 4C (107.385Mhz) */
 /*
-                {      0x60,0x36,30               },// 4D (30.200MHz)   }// No use
-
-                {      0x60,0x36,30               },// 4E (30.200MHz)   }// No use
-
-                {      0x60,0x36,30               },// 4F (30.200MHz)   }// No use
-
-                {      0x60,0x36,30               },// 50 (30.200MHz)   }// CHTV
-
-                {      0x40,0x4A,28               },// 51 (28.190MHz)
-
-                {      0x9F,0x46,44               },// 52 (43.600MHz)
-
-                {      0x97,0x2C,26               },// 53 (26.400MHz)
-
-                {      0x44,0xE4,25               },// 54 (24.600MHz)
-
-                {      0x7E,0x32,47               },// 55 (47.832MHz)
-
-                {      0x8A,0x24,31               },// 56 (31.500MHz)
-
-                {      0x97,0x2C,26               },// 57 (26.200MHz)
-
-                {      0xCE,0x3C,39               },// 58 (39.000MHz)
-
-                {      0x52,0x4A,36               },// 59 (36.000MHz)
+	{0x60, 0x36, 30}, // 4D (30.200MHz)   }// No use
+	{0x60, 0x36, 30}, // 4E (30.200MHz)   }// No use
+	{0x60, 0x36, 30}, // 4F (30.200MHz)   }// No use
+	{0x60, 0x36, 30}, // 50 (30.200MHz)   }// CHTV
+	{0x40, 0x4A, 28}, // 51 (28.190MHz)
+	{0x9F, 0x46, 44}, // 52 (43.600MHz)
+	{0x97, 0x2C, 26}, // 53 (26.400MHz)
+	{0x44, 0xE4, 25}, // 54 (24.600MHz)
+	{0x7E, 0x32, 47}, // 55 (47.832MHz)
+	{0x8A, 0x24, 31}, // 56 (31.500MHz)
+	{0x97, 0x2C, 26}, // 57 (26.200MHz)
+	{0xCE, 0x3C, 39}, // 58 (39.000MHz)
+	{0x52, 0x4A, 36}, // 59 (36.000MHz)
 */
-		{      0x69,0x61,191		  }, /* 4D (190.96MHz ) */
-		{      0x4F,0x22,192		  }, /* 4E (192.069MHz) */
-		{      0x28,0x26,322		  }, /* 4F (322.273MHz) */
-		{      0x5C,0x6B,27		  }, /* 50 (27.74HMz) */
-		{      0x57,0x24,126		  }, /* 51 (125.999MHz) */
-		{      0x5C,0x42,148		  }, /* 52 (148.5MHz) */
-		{      0x42,0x61,120		  }, /* 53 (120.839MHz) */
-		{      0x62,0x61,178		  }, /* 54 (178.992MHz) */
-		{      0x59,0x22,217		  }, /* 55 (217.325MHz) */
-		{      0x29,0x01,300		  }, /* 56 (299.505Mhz) */
-		{      0x52,0x63,74		  }, /* 57 (74.25MHz) */
-
-
-                {      0xFF,0x00,0                }      /* End mark */
+	{0x69, 0x61, 191}, /* 4D (190.96MHz ) */
+	{0x4F, 0x22, 192}, /* 4E (192.069MHz) */
+	{0x28, 0x26, 322}, /* 4F (322.273MHz) */
+	{0x5C, 0x6B,  27}, /* 50 (27.74HMz) */
+	{0x57, 0x24, 126}, /* 51 (125.999MHz) */
+	{0x5C, 0x42, 148}, /* 52 (148.5MHz) */
+	{0x42, 0x61, 120}, /* 53 (120.839MHz) */
+	{0x62, 0x61, 178}, /* 54 (178.992MHz) */
+	{0x59, 0x22, 217}, /* 55 (217.325MHz) */
+	{0x29, 0x01, 300}, /* 56 (299.505Mhz) */
+	{0x52, 0x63,  74}, /* 57 (74.25MHz) */
+	{0xFF, 0x00,   0}  /* End mark */
 };
 
 #if 0
-static unsigned char XGI660_TVDelayList[] =
-{
-          0x44,            /* ; 0 ExtNTSCDelay */
-          0x44,            /* ; 1 StNTSCDelay */
-          0x44,            /* ; 2 ExtPALDelay */
-          0x44,            /* ; 3 StPALDelay */
-          0x44,            /* ; 4 ExtHiTVDelay(1080i) */
-          0x44,            /* ; 5 StHiTVDelay(1080i) */
-          0x44,            /* ; 6 ExtYPbPrDelay(525i) */
-          0x44,            /* ; 7 StYPbPrDealy(525i) */
-          0x44,            /* ; 8 ExtYPbPrDelay(525p) */
-          0x44,            /* ; 9 StYPbPrDealy(525p) */
-          0x44,            /* ; A ExtYPbPrDelay(750p) */
-          0x44             /* ; B StYPbPrDealy(750p) */
+static unsigned char XGI660_TVDelayList[] = {
+	0x44, /* ; 0 ExtNTSCDelay */
+	0x44, /* ; 1 StNTSCDelay */
+	0x44, /* ; 2 ExtPALDelay */
+	0x44, /* ; 3 StPALDelay */
+	0x44, /* ; 4 ExtHiTVDelay(1080i) */
+	0x44, /* ; 5 StHiTVDelay(1080i) */
+	0x44, /* ; 6 ExtYPbPrDelay(525i) */
+	0x44, /* ; 7 StYPbPrDealy(525i) */
+	0x44, /* ; 8 ExtYPbPrDelay(525p) */
+	0x44, /* ; 9 StYPbPrDealy(525p) */
+	0x44, /* ; A ExtYPbPrDelay(750p) */
+	0x44  /* ; B StYPbPrDealy(750p) */
 };
 
-static unsigned char XGI660_TVDelayList2[] =
-{
-          0x44,           /* ; 0 ExtNTSCDelay */
-          0x44,           /* ; 1 StNTSCDelay */
-          0x44,           /* ; 2 ExtPALDelay */
-          0x44,           /* ; 3 StPALDelay */
-          0x44,           /* ; 4 ExtHiTVDelay */
-          0x44,           /* ; 5 StHiTVDelay */
-          0x44,           /* ; 6 ExtYPbPrDelay(525i) */
-          0x44,           /* ; 7 StYPbPrDealy(525i) */
-          0x44,           /* ; 8 ExtYPbPrDelay(525p) */
-          0x44,           /* ; 9 StYPbPrDealy(525p) */
-          0x44,           /* ; A ExtYPbPrDelay(750p) */
-          0x44            /* ; B StYPbPrDealy(750p) */
+static unsigned char XGI660_TVDelayList2[] = {
+	0x44, /* ; 0 ExtNTSCDelay */
+	0x44, /* ; 1 StNTSCDelay */
+	0x44, /* ; 2 ExtPALDelay */
+	0x44, /* ; 3 StPALDelay */
+	0x44, /* ; 4 ExtHiTVDelay */
+	0x44, /* ; 5 StHiTVDelay */
+	0x44, /* ; 6 ExtYPbPrDelay(525i) */
+	0x44, /* ; 7 StYPbPrDealy(525i) */
+	0x44, /* ; 8 ExtYPbPrDelay(525p) */
+	0x44, /* ; 9 StYPbPrDealy(525p) */
+	0x44, /* ; A ExtYPbPrDelay(750p) */
+	0x44  /* ; B StYPbPrDealy(750p) */
 };
 #endif
 
-static unsigned char XGI301TVDelayList[] =
-{
-	0x22,            /* ; 0 ExtNTSCDelay */
-	0x22,            /* ; 1 StNTSCDelay */
-	0x22,            /* ; 2 ExtPALDelay */
-	0x22,            /* ; 3 StPALDelay */
-	0x88,            /* ; 4 ExtHiTVDelay(1080i) */
-	0xBB,            /* ; 5 StHiTVDelay(1080i) */
-	0x22,            /* ; 6 ExtYPbPrDelay(525i) */
-	0x22,            /* ; 7 StYPbPrDealy(525i) */
-	0x22,            /* ; 8 ExtYPbPrDelay(525p) */
-	0x22,            /* ; 9 StYPbPrDealy(525p) */
-	0x22,            /* ; A ExtYPbPrDelay(750p) */
-	0x22            /* B StYPbPrDealy(750p) */
+static unsigned char XGI301TVDelayList[] = {
+	0x22, /* ; 0 ExtNTSCDelay */
+	0x22, /* ; 1 StNTSCDelay */
+	0x22, /* ; 2 ExtPALDelay */
+	0x22, /* ; 3 StPALDelay */
+	0x88, /* ; 4 ExtHiTVDelay(1080i) */
+	0xBB, /* ; 5 StHiTVDelay(1080i) */
+	0x22, /* ; 6 ExtYPbPrDelay(525i) */
+	0x22, /* ; 7 StYPbPrDealy(525i) */
+	0x22, /* ; 8 ExtYPbPrDelay(525p) */
+	0x22, /* ; 9 StYPbPrDealy(525p) */
+	0x22, /* ; A ExtYPbPrDelay(750p) */
+	0x22  /* B StYPbPrDealy(750p) */
 };
 
-static unsigned char XGI301TVDelayList2[] =
-{
-	0x22,           /* ; 0 ExtNTSCDelay */
-	0x22,           /* ; 1 StNTSCDelay */
-	0x22,           /* ; 2 ExtPALDelay */
-	0x22,           /* ; 3 StPALDelay */
-	0x22,           /* ; 4 ExtHiTVDelay */
-	0x22,           /* ; 5 StHiTVDelay */
-	0x22,           /* ; 6 ExtYPbPrDelay(525i) */
-	0x22,           /* ; 7 StYPbPrDealy(525i) */
-	0x22,           /* ; 8 ExtYPbPrDelay(525p) */
-	0x22,           /* ; 9 StYPbPrDealy(525p) */
-	0x22,           /* ; A ExtYPbPrDelay(750p) */
-	0x22            /* ; B StYPbPrDealy(750p) */
+static unsigned char XGI301TVDelayList2[] = {
+	0x22, /* ; 0 ExtNTSCDelay */
+	0x22, /* ; 1 StNTSCDelay */
+	0x22, /* ; 2 ExtPALDelay */
+	0x22, /* ; 3 StPALDelay */
+	0x22, /* ; 4 ExtHiTVDelay */
+	0x22, /* ; 5 StHiTVDelay */
+	0x22, /* ; 6 ExtYPbPrDelay(525i) */
+	0x22, /* ; 7 StYPbPrDealy(525i) */
+	0x22, /* ; 8 ExtYPbPrDelay(525p) */
+	0x22, /* ; 9 StYPbPrDealy(525p) */
+	0x22, /* ; A ExtYPbPrDelay(750p) */
+	0x22  /* ; B StYPbPrDealy(750p) */
 };
 
 
-static unsigned char TVAntiFlickList[] =
-{/* NTSCAntiFlicker */
-                      0x04,           /* ; 0 Adaptive */
-                      0x00,           /* ; 1 new anti-flicker ? */
-/* PALAntiFlicker */
-                      0x04,           /* ; 0 Adaptive */
-                      0x08,           /* ; 1 new anti-flicker ? */
-/* HiTVAntiFlicker */
-                      0x04,           /* ; 0 ? */
-                      0x00            /* ; 1 new anti-flicker ? */
+static unsigned char TVAntiFlickList[] = {/* NTSCAntiFlicker */
+	0x04, /* ; 0 Adaptive */
+	0x00, /* ; 1 new anti-flicker ? */
+
+	0x04, /* ; 0 Adaptive */
+	0x08, /* ; 1 new anti-flicker ? */
+
+	0x04, /* ; 0 ? */
+	0x00  /* ; 1 new anti-flicker ? */
 };
 
 
-static unsigned char TVEdgeList[] =
-{
-      0x00,            /* ; 0 NTSC No Edge enhance */
-      0x04,            /* ; 1 NTSC Adaptive Edge enhance */
-      0x00,            /* ; 0 PAL No Edge enhance */
-      0x04,            /* ; 1 PAL Adaptive Edge enhance */
-      0x00,            /* ; 0 HiTV */
-      0x00             /* ; 1 HiTV */
+static unsigned char TVEdgeList[] = {
+	0x00, /* ; 0 NTSC No Edge enhance */
+	0x04, /* ; 1 NTSC Adaptive Edge enhance */
+	0x00, /* ; 0 PAL No Edge enhance */
+	0x04, /* ; 1 PAL Adaptive Edge enhance */
+	0x00, /* ; 0 HiTV */
+	0x00  /* ; 1 HiTV */
 };
 
-static unsigned long TVPhaseList[] =
-{      0x08BAED21, /* ; 0 NTSC phase */
-       0x00E3052A, /* ; 1 PAL phase */
-       0x9B2EE421, /* ; 2 PAL-M phase */
-       0xBA3EF421, /* ; 3 PAL-N phase */
-       0xA7A28B1E, /* ; 4 NTSC 1024x768 */
-       0xE00A831E, /* ; 5 PAL-M 1024x768 */
-       0x00000000, /* ; 6 reserved */
-       0x00000000, /* ; 7 reserved */
-       0xD67BF021, /* ; 8 NTSC phase */
-       0xE986092A, /* ; 9 PAL phase */
-       0xA4EFE621, /* ; A PAL-M phase */
-       0x4694F621, /* ; B PAL-N phase */
-       0x8BDE711C, /* ; C NTSC 1024x768 */
-       0xE00A831E  /* ; D PAL-M 1024x768 */
+static unsigned long TVPhaseList[] = {
+	0x08BAED21, /* ; 0 NTSC phase */
+	0x00E3052A, /* ; 1 PAL phase */
+	0x9B2EE421, /* ; 2 PAL-M phase */
+	0xBA3EF421, /* ; 3 PAL-N phase */
+	0xA7A28B1E, /* ; 4 NTSC 1024x768 */
+	0xE00A831E, /* ; 5 PAL-M 1024x768 */
+	0x00000000, /* ; 6 reserved */
+	0x00000000, /* ; 7 reserved */
+	0xD67BF021, /* ; 8 NTSC phase */
+	0xE986092A, /* ; 9 PAL phase */
+	0xA4EFE621, /* ; A PAL-M phase */
+	0x4694F621, /* ; B PAL-N phase */
+	0x8BDE711C, /* ; C NTSC 1024x768 */
+	0xE00A831E  /* ; D PAL-M 1024x768 */
 };
 
-static unsigned char NTSCYFilter1[] =
-{
-		      0x00,0xF4,0x10,0x38     ,/* 0 : 320x text mode */
-                      0x00,0xF4,0x10,0x38     ,/* 1 : 360x text mode */
-                      0xEB,0x04,0x25,0x18     ,/* 2 : 640x text mode */
-                      0xF1,0x04,0x1F,0x18     ,/* 3 : 720x text mode */
-                      0x00,0xF4,0x10,0x38     ,/* 4 : 320x gra. mode */
-                      0xEB,0x04,0x25,0x18     ,/* 5 : 640x gra. mode */
-                      0xEB,0x15,0x25,0xF6     /* 6 : 800x gra. mode */
+static unsigned char NTSCYFilter1[] = {
+	0x00, 0xF4, 0x10, 0x38, /* 0 : 320x text mode */
+	0x00, 0xF4, 0x10, 0x38, /* 1 : 360x text mode */
+	0xEB, 0x04, 0x25, 0x18, /* 2 : 640x text mode */
+	0xF1, 0x04, 0x1F, 0x18, /* 3 : 720x text mode */
+	0x00, 0xF4, 0x10, 0x38, /* 4 : 320x gra. mode */
+	0xEB, 0x04, 0x25, 0x18, /* 5 : 640x gra. mode */
+	0xEB, 0x15, 0x25, 0xF6  /* 6 : 800x gra. mode */
 };
 
-static unsigned char PALYFilter1[] =
-{
-		      0x00,0xF4,0x10,0x38, /* 0 : 320x text mode */
-                      0x00,0xF4,0x10,0x38     ,/* 1 : 360x text mode */
-                      0xF1,0xF7,0x1F,0x32     ,/* 2 : 640x text mode */
-                      0xF3,0x00,0x1D,0x20     ,/* 3 : 720x text mode */
-                      0x00,0xF4,0x10,0x38     ,/* 4 : 320x gra. mode */
-                      0xF1,0xF7,0x1F,0x32     ,/* 5 : 640x gra. mode */
-                      0xFC,0xFB,0x14,0x2A     /* 6 : 800x gra. mode */
+static unsigned char PALYFilter1[] = {
+	0x00, 0xF4, 0x10, 0x38, /* 0 : 320x text mode */
+	0x00, 0xF4, 0x10, 0x38, /* 1 : 360x text mode */
+	0xF1, 0xF7, 0x1F, 0x32, /* 2 : 640x text mode */
+	0xF3, 0x00, 0x1D, 0x20, /* 3 : 720x text mode */
+	0x00, 0xF4, 0x10, 0x38, /* 4 : 320x gra. mode */
+	0xF1, 0xF7, 0x1F, 0x32, /* 5 : 640x gra. mode */
+	0xFC, 0xFB, 0x14, 0x2A  /* 6 : 800x gra. mode */
 };
 
-static unsigned char PALMYFilter1[] =
-{
-		      0x00,0xF4,0x10,0x38, /* 0 : 320x text mode */
-                      0x00,0xF4,0x10,0x38, /* 1 : 360x text mode */
-                      0xEB,0x04,0x10,0x18, /* 2 : 640x text mode */
-                      0xF7,0x06,0x19,0x14, /* 3 : 720x text mode */
-                      0x00,0xF4,0x10,0x38, /* 4 : 320x gra. mode */
-                      0xEB,0x04,0x25,0x18, /* 5 : 640x gra. mode */
-                      0xEB,0x15,0x25,0xF6, /* 6 : 800x gra. mode */
-                      0xFF,0xFF,0xFF,0xFF  /* End of Table */
+static unsigned char PALMYFilter1[] = {
+	0x00, 0xF4, 0x10, 0x38, /* 0 : 320x text mode */
+	0x00, 0xF4, 0x10, 0x38, /* 1 : 360x text mode */
+	0xEB, 0x04, 0x10, 0x18, /* 2 : 640x text mode */
+	0xF7, 0x06, 0x19, 0x14, /* 3 : 720x text mode */
+	0x00, 0xF4, 0x10, 0x38, /* 4 : 320x gra. mode */
+	0xEB, 0x04, 0x25, 0x18, /* 5 : 640x gra. mode */
+	0xEB, 0x15, 0x25, 0xF6, /* 6 : 800x gra. mode */
+	0xFF, 0xFF, 0xFF, 0xFF  /* End of Table */
 };
 
-static unsigned char PALNYFilter1[] =
-{
-		      0x00,0xF4,0x10,0x38, /* 0 : 320x text mode */
-                      0x00,0xF4,0x10,0x38, /* 1 : 360x text mode */
-                      0xEB,0x04,0x10,0x18, /* 2 : 640x text mode */
-                      0xF7,0x06,0x19,0x14, /* 3 : 720x text mode */
-                      0x00,0xF4,0x10,0x38, /* 4 : 320x gra. mode */
-                      0xEB,0x04,0x25,0x18, /* 5 : 640x gra. mode */
-                      0xEB,0x15,0x25,0xF6, /* 6 : 800x gra. mode */
-                      0xFF,0xFF,0xFF,0xFF  /* End of Table */
+static unsigned char PALNYFilter1[] = {
+	0x00, 0xF4, 0x10, 0x38, /* 0 : 320x text mode */
+	0x00, 0xF4, 0x10, 0x38, /* 1 : 360x text mode */
+	0xEB, 0x04, 0x10, 0x18, /* 2 : 640x text mode */
+	0xF7, 0x06, 0x19, 0x14, /* 3 : 720x text mode */
+	0x00, 0xF4, 0x10, 0x38, /* 4 : 320x gra. mode */
+	0xEB, 0x04, 0x25, 0x18, /* 5 : 640x gra. mode */
+	0xEB, 0x15, 0x25, 0xF6, /* 6 : 800x gra. mode */
+	0xFF, 0xFF, 0xFF, 0xFF  /* End of Table */
 };
 
-static unsigned char NTSCYFilter2[] =
-{
-		      0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46, /* 0 : 320x text mode */
-                      0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C, /* 1 : 360x text mode */
-                      0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46, /* 2 : 640x text mode */
-                      0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C, /* 3 : 720x text mode */
-                      0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46, /* 4 : 320x gra. mode */
-                      0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46, /* 5 : 640x gra. mode */
-                      0x01,0x01,0xFC,0xF8,0x08,0x26,0x38, /* 6 : 800x gra. mode */
-                      0xFF,0xFF,0xFC,0x00,0x0F,0x22,0x28  /* 7 : 1024xgra. mode */
+static unsigned char NTSCYFilter2[] = {
+	0xFF, 0x03, 0x02, 0xF6, 0xFC, 0x27, 0x46, /* 0 : 320x text mode */
+	0x01, 0x02, 0xFE, 0xF7, 0x03, 0x27, 0x3C, /* 1 : 360x text mode */
+	0xFF, 0x03, 0x02, 0xF6, 0xFC, 0x27, 0x46, /* 2 : 640x text mode */
+	0x01, 0x02, 0xFE, 0xF7, 0x03, 0x27, 0x3C, /* 3 : 720x text mode */
+	0xFF, 0x03, 0x02, 0xF6, 0xFC, 0x27, 0x46, /* 4 : 320x gra. mode */
+	0xFF, 0x03, 0x02, 0xF6, 0xFC, 0x27, 0x46, /* 5 : 640x gra. mode */
+	0x01, 0x01, 0xFC, 0xF8, 0x08, 0x26, 0x38, /* 6 : 800x gra. mode */
+	0xFF, 0xFF, 0xFC, 0x00, 0x0F, 0x22, 0x28  /* 7 : 1024xgra. mode */
 };
 
-static unsigned char PALYFilter2[] =
-{
-		      0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46, /* 0 : 320x text mode */
-                      0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C, /* 1 : 360x text mode */
-                      0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46, /* 2 : 640x text mode */
-                      0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C, /* 3 : 720x text mode */
-                      0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46, /* 4 : 320x gra. mode */
-                      0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46, /* 5 : 640x gra. mode */
-                      0x01,0x01,0xFC,0xF8,0x08,0x26,0x38, /* 6 : 800x gra. mode */
-                      0xFF,0xFF,0xFC,0x00,0x0F,0x22,0x28  /* 7 : 1024xgra. mode */
+static unsigned char PALYFilter2[] = {
+	0xFF, 0x03, 0x02, 0xF6, 0xFC, 0x27, 0x46, /* 0 : 320x text mode */
+	0x01, 0x02, 0xFE, 0xF7, 0x03, 0x27, 0x3C, /* 1 : 360x text mode */
+	0xFF, 0x03, 0x02, 0xF6, 0xFC, 0x27, 0x46, /* 2 : 640x text mode */
+	0x01, 0x02, 0xFE, 0xF7, 0x03, 0x27, 0x3C, /* 3 : 720x text mode */
+	0xFF, 0x03, 0x02, 0xF6, 0xFC, 0x27, 0x46, /* 4 : 320x gra. mode */
+	0xFF, 0x03, 0x02, 0xF6, 0xFC, 0x27, 0x46, /* 5 : 640x gra. mode */
+	0x01, 0x01, 0xFC, 0xF8, 0x08, 0x26, 0x38, /* 6 : 800x gra. mode */
+	0xFF, 0xFF, 0xFC, 0x00, 0x0F, 0x22, 0x28  /* 7 : 1024xgra. mode */
 };
 
-static unsigned char PALMYFilter2[] =
-{
-		      0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46, /* 0 : 320x text mode */
-                      0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C, /* 1 : 360x text mode */
-                      0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46, /* 2 : 640x text mode */
-                      0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C, /* 3 : 720x text mode */
-                      0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46, /* 4 : 320x gra. mode */
-                      0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46, /* 5 : 640x gra. mode */
-                      0x01,0x01,0xFC,0xF8,0x08,0x26,0x38, /* 6 : 800x gra. mode */
-                      0xFF,0xFF,0xFC,0x00,0x0F,0x22,0x28  /* 7 : 1024xgra. mode */
+static unsigned char PALMYFilter2[] = {
+	0xFF, 0x03, 0x02, 0xF6, 0xFC, 0x27, 0x46, /* 0 : 320x text mode */
+	0x01, 0x02, 0xFE, 0xF7, 0x03, 0x27, 0x3C, /* 1 : 360x text mode */
+	0xFF, 0x03, 0x02, 0xF6, 0xFC, 0x27, 0x46, /* 2 : 640x text mode */
+	0x01, 0x02, 0xFE, 0xF7, 0x03, 0x27, 0x3C, /* 3 : 720x text mode */
+	0xFF, 0x03, 0x02, 0xF6, 0xFC, 0x27, 0x46, /* 4 : 320x gra. mode */
+	0xFF, 0x03, 0x02, 0xF6, 0xFC, 0x27, 0x46, /* 5 : 640x gra. mode */
+	0x01, 0x01, 0xFC, 0xF8, 0x08, 0x26, 0x38, /* 6 : 800x gra. mode */
+	0xFF, 0xFF, 0xFC, 0x00, 0x0F, 0x22, 0x28  /* 7 : 1024xgra. mode */
 };
 
-static unsigned char PALNYFilter2[] =
-{
-		      0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46, /* 0 : 320x text mode */
-                      0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C, /* 1 : 360x text mode */
-                      0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46, /* 2 : 640x text mode */
-                      0x01,0x02,0xFE,0xF7,0x03,0x27,0x3C, /* 3 : 720x text mode */
-                      0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46, /* 4 : 320x gra. mode */
-                      0xFF,0x03,0x02,0xF6,0xFC,0x27,0x46, /* 5 : 640x gra. mode */
-                      0x01,0x01,0xFC,0xF8,0x08,0x26,0x38, /* 6 : 800x gra. mode */
-                      0xFF,0xFF,0xFC,0x00,0x0F,0x22,0x28  /* 7 : 1024xgra. mode */
+static unsigned char PALNYFilter2[] = {
+	0xFF, 0x03, 0x02, 0xF6, 0xFC, 0x27, 0x46, /* 0 : 320x text mode */
+	0x01, 0x02, 0xFE, 0xF7, 0x03, 0x27, 0x3C, /* 1 : 360x text mode */
+	0xFF, 0x03, 0x02, 0xF6, 0xFC, 0x27, 0x46, /* 2 : 640x text mode */
+	0x01, 0x02, 0xFE, 0xF7, 0x03, 0x27, 0x3C, /* 3 : 720x text mode */
+	0xFF, 0x03, 0x02, 0xF6, 0xFC, 0x27, 0x46, /* 4 : 320x gra. mode */
+	0xFF, 0x03, 0x02, 0xF6, 0xFC, 0x27, 0x46, /* 5 : 640x gra. mode */
+	0x01, 0x01, 0xFC, 0xF8, 0x08, 0x26, 0x38, /* 6 : 800x gra. mode */
+	0xFF, 0xFF, 0xFC, 0x00, 0x0F, 0x22, 0x28  /* 7 : 1024xgra. mode */
 };
 
-static unsigned char XGI_NTSC1024AdjTime[] =
-{
-      0xa7,0x07,0xf2,0x6e,0x17,0x8b,0x73,0x53,
-      0x13,0x40,0x34,0xF4,0x63,0xBB,0xCC,0x7A,
-      0x58,0xe4,0x73,0xd0,0x13
+static unsigned char XGI_NTSC1024AdjTime[] = {
+	0xa7, 0x07, 0xf2, 0x6e, 0x17, 0x8b, 0x73, 0x53,
+	0x13, 0x40, 0x34, 0xF4, 0x63, 0xBB, 0xCC, 0x7A,
+	0x58, 0xe4, 0x73, 0xd0, 0x13
 };
 
-static struct XGI301C_Tap4TimingStruct HiTVTap4Timing[] =
-{
-	{0,{
-	0x00,0x20,0x00,0x00,0x7F,0x20,0x02,0x7F, /* ; C0-C7 */
-	0x7D,0x20,0x04,0x7F,0x7D,0x1F,0x06,0x7E, /* ; C8-CF */
-	0x7C,0x1D,0x09,0x7E,0x7C,0x1B,0x0B,0x7E, /* ; D0-D7 */
-	0x7C,0x19,0x0E,0x7D,0x7C,0x17,0x11,0x7C, /* ; D8-DF */
-	0x7C,0x14,0x14,0x7C,0x7C,0x11,0x17,0x7C, /* ; E0-E7 */
-	0x7D,0x0E,0x19,0x7C,0x7E,0x0B,0x1B,0x7C, /* ; EA-EF */
-	0x7E,0x09,0x1D,0x7C,0x7F,0x06,0x1F,0x7C, /* ; F0-F7 */
-	0x7F,0x04,0x20,0x7D,0x00,0x02,0x20,0x7E  /* ; F8-FF */
+static struct XGI301C_Tap4TimingStruct HiTVTap4Timing[] = {
+	{0, {
+	0x00, 0x20, 0x00, 0x00, 0x7F, 0x20, 0x02, 0x7F, /* ; C0-C7 */
+	0x7D, 0x20, 0x04, 0x7F, 0x7D, 0x1F, 0x06, 0x7E, /* ; C8-CF */
+	0x7C, 0x1D, 0x09, 0x7E, 0x7C, 0x1B, 0x0B, 0x7E, /* ; D0-D7 */
+	0x7C, 0x19, 0x0E, 0x7D, 0x7C, 0x17, 0x11, 0x7C, /* ; D8-DF */
+	0x7C, 0x14, 0x14, 0x7C, 0x7C, 0x11, 0x17, 0x7C, /* ; E0-E7 */
+	0x7D, 0x0E, 0x19, 0x7C, 0x7E, 0x0B, 0x1B, 0x7C, /* ; EA-EF */
+	0x7E, 0x09, 0x1D, 0x7C, 0x7F, 0x06, 0x1F, 0x7C, /* ; F0-F7 */
+	0x7F, 0x04, 0x20, 0x7D, 0x00, 0x02, 0x20, 0x7E  /* ; F8-FF */
 	}
 	}
 };
 
-static struct XGI301C_Tap4TimingStruct EnlargeTap4Timing[] =
-{
-	{0,{
-	0x00,0x20,0x00,0x00,0x7F,0x20,0x02,0x7F, /* ; C0-C7 */
-	0x7D,0x20,0x04,0x7F,0x7D,0x1F,0x06,0x7E, /* ; C8-CF */
-	0x7C,0x1D,0x09,0x7E,0x7C,0x1B,0x0B,0x7E, /* ; D0-D7 */
-	0x7C,0x19,0x0E,0x7D,0x7C,0x17,0x11,0x7C, /* ; D8-DF */
-	0x7C,0x14,0x14,0x7C,0x7C,0x11,0x17,0x7C, /* ; E0-E7 */
-	0x7D,0x0E,0x19,0x7C,0x7E,0x0B,0x1B,0x7C, /* ; EA-EF */
-	0x7E,0x09,0x1D,0x7C,0x7F,0x06,0x1F,0x7C, /* ; F0-F7 */
-	0x7F,0x04,0x20,0x7D,0x00,0x02,0x20,0x7E   /* ; F8-FF */
+static struct XGI301C_Tap4TimingStruct EnlargeTap4Timing[] = {
+	{0, {
+	0x00, 0x20, 0x00, 0x00, 0x7F, 0x20, 0x02, 0x7F, /* ; C0-C7 */
+	0x7D, 0x20, 0x04, 0x7F, 0x7D, 0x1F, 0x06, 0x7E, /* ; C8-CF */
+	0x7C, 0x1D, 0x09, 0x7E, 0x7C, 0x1B, 0x0B, 0x7E, /* ; D0-D7 */
+	0x7C, 0x19, 0x0E, 0x7D, 0x7C, 0x17, 0x11, 0x7C, /* ; D8-DF */
+	0x7C, 0x14, 0x14, 0x7C, 0x7C, 0x11, 0x17, 0x7C, /* ; E0-E7 */
+	0x7D, 0x0E, 0x19, 0x7C, 0x7E, 0x0B, 0x1B, 0x7C, /* ; EA-EF */
+	0x7E, 0x09, 0x1D, 0x7C, 0x7F, 0x06, 0x1F, 0x7C, /* ; F0-F7 */
+	0x7F, 0x04, 0x20, 0x7D, 0x00, 0x02, 0x20, 0x7E   /* ; F8-FF */
 	}
 	}
 };
 
-static struct XGI301C_Tap4TimingStruct NoScaleTap4Timing[] =
-{
-	{0,{
-	0x00,0x20,0x00,0x00,0x7F,0x20,0x02,0x7F, /* ; C0-C7 */
-	0x7D,0x20,0x04,0x7F,0x7D,0x1F,0x06,0x7E, /* ; C8-CF */
-	0x7C,0x1D,0x09,0x7E,0x7C,0x1B,0x0B,0x7E, /* ; D0-D7 */
-	0x7C,0x19,0x0E,0x7D,0x7C,0x17,0x11,0x7C, /* ; D8-DF */
-	0x7C,0x14,0x14,0x7C,0x7C,0x11,0x17,0x7C, /* ; E0-E7 */
-	0x7D,0x0E,0x19,0x7C,0x7E,0x0B,0x1B,0x7C, /* ; EA-EF */
-	0x7E,0x09,0x1D,0x7C,0x7F,0x06,0x1F,0x7C, /* ; F0-F7 */
-	0x7F,0x04,0x20,0x7D,0x00,0x02,0x20,0x7E  /* ; F8-FF */
+static struct XGI301C_Tap4TimingStruct NoScaleTap4Timing[] = {
+	{0, {
+	0x00, 0x20, 0x00, 0x00, 0x7F, 0x20, 0x02, 0x7F, /* ; C0-C7 */
+	0x7D, 0x20, 0x04, 0x7F, 0x7D, 0x1F, 0x06, 0x7E, /* ; C8-CF */
+	0x7C, 0x1D, 0x09, 0x7E, 0x7C, 0x1B, 0x0B, 0x7E, /* ; D0-D7 */
+	0x7C, 0x19, 0x0E, 0x7D, 0x7C, 0x17, 0x11, 0x7C, /* ; D8-DF */
+	0x7C, 0x14, 0x14, 0x7C, 0x7C, 0x11, 0x17, 0x7C, /* ; E0-E7 */
+	0x7D, 0x0E, 0x19, 0x7C, 0x7E, 0x0B, 0x1B, 0x7C, /* ; EA-EF */
+	0x7E, 0x09, 0x1D, 0x7C, 0x7F, 0x06, 0x1F, 0x7C, /* ; F0-F7 */
+	0x7F, 0x04, 0x20, 0x7D, 0x00, 0x02, 0x20, 0x7E  /* ; F8-FF */
 	}
 	}
 };
 
-static struct XGI301C_Tap4TimingStruct PALTap4Timing[] =
-{
-	{600,  {
-                0x05,0x19,0x05,0x7D,0x03,0x19,0x06,0x7E, /* ; C0-C7 */
-                0x02,0x19,0x08,0x7D,0x01,0x18,0x0A,0x7D, /* ; C8-CF */
-                0x00,0x18,0x0C,0x7C,0x7F,0x17,0x0E,0x7C, /* ; D0-D7 */
-                0x7E,0x16,0x0F,0x7D,0x7E,0x14,0x11,0x7D, /* ; D8-DF */
-                0x7D,0x13,0x13,0x7D,0x7D,0x11,0x14,0x7E, /* ; E0-E7 */
-                0x7D,0x0F,0x16,0x7E,0x7D,0x0E,0x17,0x7E, /* ; EA-EF */
-                0x7D,0x0C,0x18,0x7F,0x7D,0x0A,0x18,0x01, /* ; F0-F7 */
-                0x7D,0x08,0x19,0x02,0x7D,0x06,0x19,0x04  /* ; F8-FF */
-                }
- 	},
-        {768,	{
-                0x08,0x12,0x08,0x7E,0x07,0x12,0x09,0x7E, /* ; C0-C7 */
-                0x06,0x12,0x0A,0x7E,0x05,0x11,0x0B,0x7F, /* ; C8-CF */
-                0x04,0x11,0x0C,0x7F,0x03,0x11,0x0C,0x00, /* ; D0-D7 */
-                0x03,0x10,0x0D,0x00,0x02,0x0F,0x0E,0x01, /* ; D8-DF */
-                0x01,0x0F,0x0F,0x01,0x01,0x0E,0x0F,0x02, /* ; E0-E7 */
-                0x00,0x0D,0x10,0x03,0x7F,0x0C,0x11,0x04, /* ; EA-EF */
-                0x7F,0x0C,0x11,0x04,0x7F,0x0B,0x11,0x05, /* ; F0-F7 */
-                0x7E,0x0A,0x12,0x06,0x7E,0x09,0x12,0x07  /* ; F8-FF */
-                }
-        },
-        {0xFFFF,
-        	{
-                0x04,0x1A,0x04,0x7E,0x02,0x1B,0x05,0x7E, /* ; C0-C7 */
-                0x01,0x1A,0x07,0x7E,0x00,0x1A,0x09,0x7D, /* ; C8-CF */
-                0x7F,0x19,0x0B,0x7D,0x7E,0x18,0x0D,0x7D, /* ; D0-D7 */
-                0x7D,0x17,0x10,0x7C,0x7D,0x15,0x12,0x7C, /* ; D8-DF */
-                0x7C,0x14,0x14,0x7C,0x7C,0x12,0x15,0x7D, /* ; E0-E7 */
-                0x7C,0x10,0x17,0x7D,0x7C,0x0D,0x18,0x7F, /* ; EA-EF */
-                0x7D,0x0B,0x19,0x7F,0x7D,0x09,0x1A,0x00, /* ; F0-F7 */
-                0x7D,0x07,0x1A,0x02,0x7E,0x05,0x1B,0x02  /* ; F8-FF */
-                }
-        }
+static struct XGI301C_Tap4TimingStruct PALTap4Timing[] = {
+	{600,	{
+		0x05, 0x19, 0x05, 0x7D, 0x03, 0x19, 0x06, 0x7E, /* ; C0-C7 */
+		0x02, 0x19, 0x08, 0x7D, 0x01, 0x18, 0x0A, 0x7D, /* ; C8-CF */
+		0x00, 0x18, 0x0C, 0x7C, 0x7F, 0x17, 0x0E, 0x7C, /* ; D0-D7 */
+		0x7E, 0x16, 0x0F, 0x7D, 0x7E, 0x14, 0x11, 0x7D, /* ; D8-DF */
+		0x7D, 0x13, 0x13, 0x7D, 0x7D, 0x11, 0x14, 0x7E, /* ; E0-E7 */
+		0x7D, 0x0F, 0x16, 0x7E, 0x7D, 0x0E, 0x17, 0x7E, /* ; EA-EF */
+		0x7D, 0x0C, 0x18, 0x7F, 0x7D, 0x0A, 0x18, 0x01, /* ; F0-F7 */
+		0x7D, 0x08, 0x19, 0x02, 0x7D, 0x06, 0x19, 0x04  /* ; F8-FF */
+		}
+	},
+	{768,	{
+		0x08, 0x12, 0x08, 0x7E, 0x07, 0x12, 0x09, 0x7E, /* ; C0-C7 */
+		0x06, 0x12, 0x0A, 0x7E, 0x05, 0x11, 0x0B, 0x7F, /* ; C8-CF */
+		0x04, 0x11, 0x0C, 0x7F, 0x03, 0x11, 0x0C, 0x00, /* ; D0-D7 */
+		0x03, 0x10, 0x0D, 0x00, 0x02, 0x0F, 0x0E, 0x01, /* ; D8-DF */
+		0x01, 0x0F, 0x0F, 0x01, 0x01, 0x0E, 0x0F, 0x02, /* ; E0-E7 */
+		0x00, 0x0D, 0x10, 0x03, 0x7F, 0x0C, 0x11, 0x04, /* ; EA-EF */
+		0x7F, 0x0C, 0x11, 0x04, 0x7F, 0x0B, 0x11, 0x05, /* ; F0-F7 */
+		0x7E, 0x0A, 0x12, 0x06, 0x7E, 0x09, 0x12, 0x07  /* ; F8-FF */
+		}
+	},
+	{0xFFFF, {
+		 0x04, 0x1A, 0x04, 0x7E, 0x02, 0x1B, 0x05, 0x7E, /* ; C0-C7 */
+		 0x01, 0x1A, 0x07, 0x7E, 0x00, 0x1A, 0x09, 0x7D, /* ; C8-CF */
+		 0x7F, 0x19, 0x0B, 0x7D, 0x7E, 0x18, 0x0D, 0x7D, /* ; D0-D7 */
+		 0x7D, 0x17, 0x10, 0x7C, 0x7D, 0x15, 0x12, 0x7C, /* ; D8-DF */
+		 0x7C, 0x14, 0x14, 0x7C, 0x7C, 0x12, 0x15, 0x7D, /* ; E0-E7 */
+		 0x7C, 0x10, 0x17, 0x7D, 0x7C, 0x0D, 0x18, 0x7F, /* ; EA-EF */
+		 0x7D, 0x0B, 0x19, 0x7F, 0x7D, 0x09, 0x1A, 0x00, /* ; F0-F7 */
+		 0x7D, 0x07, 0x1A, 0x02, 0x7E, 0x05, 0x1B, 0x02  /* ; F8-FF */
+		 }
+	}
 };
 
-static struct XGI301C_Tap4TimingStruct NTSCTap4Timing[] =
-{
+static struct XGI301C_Tap4TimingStruct NTSCTap4Timing[] = {
 	{480,	{
-              	0x04,0x1A,0x04,0x7E,0x03,0x1A,0x06,0x7D, /* ; C0-C7 */
-              	0x01,0x1A,0x08,0x7D,0x00,0x19,0x0A,0x7D, /* ; C8-CF */
-              	0x7F,0x19,0x0C,0x7C,0x7E,0x18,0x0E,0x7C, /* ; D0-D7 */
-              	0x7E,0x17,0x10,0x7B,0x7D,0x15,0x12,0x7C, /* ; D8-DF */
-              	0x7D,0x13,0x13,0x7D,0x7C,0x12,0x15,0x7D, /* ; E0-E7 */
-              	0x7C,0x10,0x17,0x7D,0x7C,0x0E,0x18,0x7E, /* ; EA-EF */
-              	0x7D,0x0C,0x19,0x7E,0x7D,0x0A,0x19,0x00, /* ; F0-F7 */
-              	0x7D,0x08,0x1A,0x01,0x7E,0x06,0x1A,0x02  /* ; F8-FF */
-        	}
-        },
-        {600,	{
-              	0x07,0x14,0x07,0x7E,0x06,0x14,0x09,0x7D, /* ; C0-C7 */
-              	0x05,0x14,0x0A,0x7D,0x04,0x13,0x0B,0x7E, /* ; C8-CF */
-              	0x03,0x13,0x0C,0x7E,0x02,0x12,0x0D,0x7F, /* ; D0-D7 */
-              	0x01,0x12,0x0E,0x7F,0x01,0x11,0x0F,0x7F, /* ; D8-DF */
-              	0x01,0x10,0x10,0x00,0x7F,0x0F,0x11,0x01, /* ; E0-E7 */
-              	0x7F,0x0E,0x12,0x01,0x7E,0x0D,0x12,0x03, /* ; EA-EF */
-              	0x7E,0x0C,0x13,0x03,0x7E,0x0B,0x13,0x04, /* ; F0-F7 */
-              	0x7E,0x0A,0x14,0x04,0x7D,0x09,0x14,0x06  /* ; F8-FF */
-        	}
-        },
-        {0xFFFF,
-        	{
-              	0x09,0x0F,0x09,0x7F,0x08,0x0F,0x09,0x00, /* ; C0-C7 */
-              	0x07,0x0F,0x0A,0x00,0x06,0x0F,0x0A,0x01, /* ; C8-CF */
-              	0x06,0x0E,0x0B,0x01,0x05,0x0E,0x0B,0x02, /* ; D0-D7 */
-              	0x04,0x0E,0x0C,0x02,0x04,0x0D,0x0C,0x03, /* ; D8-DF */
-              	0x03,0x0D,0x0D,0x03,0x02,0x0C,0x0D,0x05, /* ; E0-E7 */
-              	0x02,0x0C,0x0E,0x04,0x01,0x0B,0x0E,0x06, /* ; EA-EF */
-              	0x01,0x0B,0x0E,0x06,0x00,0x0A,0x0F,0x07, /* ; F0-F7 */
-              	0x00,0x0A,0x0F,0x07,0x00,0x09,0x0F,0x08  /* ; F8-FF */
-        	}
-        }
+		0x04, 0x1A, 0x04, 0x7E, 0x03, 0x1A, 0x06, 0x7D, /* ; C0-C7 */
+		0x01, 0x1A, 0x08, 0x7D, 0x00, 0x19, 0x0A, 0x7D, /* ; C8-CF */
+		0x7F, 0x19, 0x0C, 0x7C, 0x7E, 0x18, 0x0E, 0x7C, /* ; D0-D7 */
+		0x7E, 0x17, 0x10, 0x7B, 0x7D, 0x15, 0x12, 0x7C, /* ; D8-DF */
+		0x7D, 0x13, 0x13, 0x7D, 0x7C, 0x12, 0x15, 0x7D, /* ; E0-E7 */
+		0x7C, 0x10, 0x17, 0x7D, 0x7C, 0x0E, 0x18, 0x7E, /* ; EA-EF */
+		0x7D, 0x0C, 0x19, 0x7E, 0x7D, 0x0A, 0x19, 0x00, /* ; F0-F7 */
+		0x7D, 0x08, 0x1A, 0x01, 0x7E, 0x06, 0x1A, 0x02  /* ; F8-FF */
+		}
+	},
+	{600,	{
+		0x07, 0x14, 0x07, 0x7E, 0x06, 0x14, 0x09, 0x7D, /* ; C0-C7 */
+		0x05, 0x14, 0x0A, 0x7D, 0x04, 0x13, 0x0B, 0x7E, /* ; C8-CF */
+		0x03, 0x13, 0x0C, 0x7E, 0x02, 0x12, 0x0D, 0x7F, /* ; D0-D7 */
+		0x01, 0x12, 0x0E, 0x7F, 0x01, 0x11, 0x0F, 0x7F, /* ; D8-DF */
+		0x01, 0x10, 0x10, 0x00, 0x7F, 0x0F, 0x11, 0x01, /* ; E0-E7 */
+		0x7F, 0x0E, 0x12, 0x01, 0x7E, 0x0D, 0x12, 0x03, /* ; EA-EF */
+		0x7E, 0x0C, 0x13, 0x03, 0x7E, 0x0B, 0x13, 0x04, /* ; F0-F7 */
+		0x7E, 0x0A, 0x14, 0x04, 0x7D, 0x09, 0x14, 0x06  /* ; F8-FF */
+		}
+	},
+	{0xFFFF, {
+		 0x09, 0x0F, 0x09, 0x7F, 0x08, 0x0F, 0x09, 0x00, /* ; C0-C7 */
+		 0x07, 0x0F, 0x0A, 0x00, 0x06, 0x0F, 0x0A, 0x01, /* ; C8-CF */
+		 0x06, 0x0E, 0x0B, 0x01, 0x05, 0x0E, 0x0B, 0x02, /* ; D0-D7 */
+		 0x04, 0x0E, 0x0C, 0x02, 0x04, 0x0D, 0x0C, 0x03, /* ; D8-DF */
+		 0x03, 0x0D, 0x0D, 0x03, 0x02, 0x0C, 0x0D, 0x05, /* ; E0-E7 */
+		 0x02, 0x0C, 0x0E, 0x04, 0x01, 0x0B, 0x0E, 0x06, /* ; EA-EF */
+		 0x01, 0x0B, 0x0E, 0x06, 0x00, 0x0A, 0x0F, 0x07, /* ; F0-F7 */
+		 0x00, 0x0A, 0x0F, 0x07, 0x00, 0x09, 0x0F, 0x08  /* ; F8-FF */
+		 }
+	}
 };
 
-static struct XGI301C_Tap4TimingStruct YPbPr525pTap4Timing[] =
-{
+static struct XGI301C_Tap4TimingStruct YPbPr525pTap4Timing[] = {
 	{480,	{
-              	0x04,0x1A,0x04,0x7E,0x03,0x1A,0x06,0x7D, /* ; C0-C7 */
-              	0x01,0x1A,0x08,0x7D,0x00,0x19,0x0A,0x7D, /* ; C8-CF */
-              	0x7F,0x19,0x0C,0x7C,0x7E,0x18,0x0E,0x7C, /* ; D0-D7 */
-              	0x7E,0x17,0x10,0x7B,0x7D,0x15,0x12,0x7C, /* ; D8-DF */
-              	0x7D,0x13,0x13,0x7D,0x7C,0x12,0x15,0x7D, /* ; E0-E7 */
-              	0x7C,0x10,0x17,0x7D,0x7C,0x0E,0x18,0x7E, /* ; EA-EF */
-              	0x7D,0x0C,0x19,0x7E,0x7D,0x0A,0x19,0x00, /* ; F0-F7 */
-              	0x7D,0x08,0x1A,0x01,0x7E,0x06,0x1A,0x02  /* ; F8-FF */
-        	}
-        },
-        {600,	{
-              	0x07,0x14,0x07,0x7E,0x06,0x14,0x09,0x7D, /* ; C0-C7 */
-              	0x05,0x14,0x0A,0x7D,0x04,0x13,0x0B,0x7E, /* ; C8-CF */
-              	0x03,0x13,0x0C,0x7E,0x02,0x12,0x0D,0x7F, /* ; D0-D7 */
-              	0x01,0x12,0x0E,0x7F,0x01,0x11,0x0F,0x7F, /* ; D8-DF */
-              	0x01,0x10,0x10,0x00,0x7F,0x0F,0x11,0x01, /* ; E0-E7 */
-              	0x7F,0x0E,0x12,0x01,0x7E,0x0D,0x12,0x03, /* ; EA-EF */
-              	0x7E,0x0C,0x13,0x03,0x7E,0x0B,0x13,0x04, /* ; F0-F7 */
-              	0x7E,0x0A,0x14,0x04,0x7D,0x09,0x14,0x06  /* ; F8-FF */
-        	}
-        },
-        {0xFFFF,
-        	{
-              	0x09,0x0F,0x09,0x7F,0x08,0x0F,0x09,0x00, /* ; C0-C7 */
-              	0x07,0x0F,0x0A,0x00,0x06,0x0F,0x0A,0x01, /* ; C8-CF */
-              	0x06,0x0E,0x0B,0x01,0x05,0x0E,0x0B,0x02, /* ; D0-D7 */
-              	0x04,0x0E,0x0C,0x02,0x04,0x0D,0x0C,0x03, /* ; D8-DF */
-              	0x03,0x0D,0x0D,0x03,0x02,0x0C,0x0D,0x05, /* ; E0-E7 */
-              	0x02,0x0C,0x0E,0x04,0x01,0x0B,0x0E,0x06, /* ; EA-EF */
-              	0x01,0x0B,0x0E,0x06,0x00,0x0A,0x0F,0x07, /* ; F0-F7 */
-              	0x00,0x0A,0x0F,0x07,0x00,0x09,0x0F,0x08  /* ; F8-FF */
-        	}
-        }
+		0x04, 0x1A, 0x04, 0x7E, 0x03, 0x1A, 0x06, 0x7D, /* ; C0-C7 */
+		0x01, 0x1A, 0x08, 0x7D, 0x00, 0x19, 0x0A, 0x7D, /* ; C8-CF */
+		0x7F, 0x19, 0x0C, 0x7C, 0x7E, 0x18, 0x0E, 0x7C, /* ; D0-D7 */
+		0x7E, 0x17, 0x10, 0x7B, 0x7D, 0x15, 0x12, 0x7C, /* ; D8-DF */
+		0x7D, 0x13, 0x13, 0x7D, 0x7C, 0x12, 0x15, 0x7D, /* ; E0-E7 */
+		0x7C, 0x10, 0x17, 0x7D, 0x7C, 0x0E, 0x18, 0x7E, /* ; EA-EF */
+		0x7D, 0x0C, 0x19, 0x7E, 0x7D, 0x0A, 0x19, 0x00, /* ; F0-F7 */
+		0x7D, 0x08, 0x1A, 0x01, 0x7E, 0x06, 0x1A, 0x02  /* ; F8-FF */
+		}
+	},
+	{600,	{
+		0x07, 0x14, 0x07, 0x7E, 0x06, 0x14, 0x09, 0x7D, /* ; C0-C7 */
+		0x05, 0x14, 0x0A, 0x7D, 0x04, 0x13, 0x0B, 0x7E, /* ; C8-CF */
+		0x03, 0x13, 0x0C, 0x7E, 0x02, 0x12, 0x0D, 0x7F, /* ; D0-D7 */
+		0x01, 0x12, 0x0E, 0x7F, 0x01, 0x11, 0x0F, 0x7F, /* ; D8-DF */
+		0x01, 0x10, 0x10, 0x00, 0x7F, 0x0F, 0x11, 0x01, /* ; E0-E7 */
+		0x7F, 0x0E, 0x12, 0x01, 0x7E, 0x0D, 0x12, 0x03, /* ; EA-EF */
+		0x7E, 0x0C, 0x13, 0x03, 0x7E, 0x0B, 0x13, 0x04, /* ; F0-F7 */
+		0x7E, 0x0A, 0x14, 0x04, 0x7D, 0x09, 0x14, 0x06  /* ; F8-FF */
+		}
+	},
+	{0xFFFF, {
+		0x09, 0x0F, 0x09, 0x7F, 0x08, 0x0F, 0x09, 0x00, /* ; C0-C7 */
+		0x07, 0x0F, 0x0A, 0x00, 0x06, 0x0F, 0x0A, 0x01, /* ; C8-CF */
+		0x06, 0x0E, 0x0B, 0x01, 0x05, 0x0E, 0x0B, 0x02, /* ; D0-D7 */
+		0x04, 0x0E, 0x0C, 0x02, 0x04, 0x0D, 0x0C, 0x03, /* ; D8-DF */
+		0x03, 0x0D, 0x0D, 0x03, 0x02, 0x0C, 0x0D, 0x05, /* ; E0-E7 */
+		0x02, 0x0C, 0x0E, 0x04, 0x01, 0x0B, 0x0E, 0x06, /* ; EA-EF */
+		0x01, 0x0B, 0x0E, 0x06, 0x00, 0x0A, 0x0F, 0x07, /* ; F0-F7 */
+		0x00, 0x0A, 0x0F, 0x07, 0x00, 0x09, 0x0F, 0x08  /* ; F8-FF */
+		}
+	}
 };
 
-static struct XGI301C_Tap4TimingStruct YPbPr525iTap4Timing[] =
-{
+static struct XGI301C_Tap4TimingStruct YPbPr525iTap4Timing[] = {
 	{480,	{
-              	0x04,0x1A,0x04,0x7E,0x03,0x1A,0x06,0x7D, /* ; C0-C7 */
-              	0x01,0x1A,0x08,0x7D,0x00,0x19,0x0A,0x7D, /* ; C8-CF */
-              	0x7F,0x19,0x0C,0x7C,0x7E,0x18,0x0E,0x7C, /* ; D0-D7 */
-              	0x7E,0x17,0x10,0x7B,0x7D,0x15,0x12,0x7C, /* ; D8-DF */
-              	0x7D,0x13,0x13,0x7D,0x7C,0x12,0x15,0x7D, /* ; E0-E7 */
-              	0x7C,0x10,0x17,0x7D,0x7C,0x0E,0x18,0x7E, /* ; EA-EF */
-              	0x7D,0x0C,0x19,0x7E,0x7D,0x0A,0x19,0x00, /* ; F0-F7 */
-              	0x7D,0x08,0x1A,0x01,0x7E,0x06,0x1A,0x02  /* ; F8-FF */
-        	}
-        },
-        {600,	{
-              	0x07,0x14,0x07,0x7E,0x06,0x14,0x09,0x7D, /* ; C0-C7 */
-              	0x05,0x14,0x0A,0x7D,0x04,0x13,0x0B,0x7E, /* ; C8-CF */
-              	0x03,0x13,0x0C,0x7E,0x02,0x12,0x0D,0x7F, /* ; D0-D7 */
-              	0x01,0x12,0x0E,0x7F,0x01,0x11,0x0F,0x7F, /* ; D8-DF */
-              	0x01,0x10,0x10,0x00,0x7F,0x0F,0x11,0x01, /* ; E0-E7 */
-              	0x7F,0x0E,0x12,0x01,0x7E,0x0D,0x12,0x03, /* ; EA-EF */
-              	0x7E,0x0C,0x13,0x03,0x7E,0x0B,0x13,0x04, /* ; F0-F7 */
-              	0x7E,0x0A,0x14,0x04,0x7D,0x09,0x14,0x06  /* ; F8-FF */
-        	}
-        },
-        {0xFFFF,
-        	{
-              	0x09,0x0F,0x09,0x7F,0x08,0x0F,0x09,0x00, /* ; C0-C7 */
-              	0x07,0x0F,0x0A,0x00,0x06,0x0F,0x0A,0x01, /* ; C8-CF */
-              	0x06,0x0E,0x0B,0x01,0x05,0x0E,0x0B,0x02, /* ; D0-D7 */
-              	0x04,0x0E,0x0C,0x02,0x04,0x0D,0x0C,0x03, /* ; D8-DF */
-              	0x03,0x0D,0x0D,0x03,0x02,0x0C,0x0D,0x05, /* ; E0-E7 */
-              	0x02,0x0C,0x0E,0x04,0x01,0x0B,0x0E,0x06, /* ; EA-EF */
-              	0x01,0x0B,0x0E,0x06,0x00,0x0A,0x0F,0x07, /* ; F0-F7 */
-              	0x00,0x0A,0x0F,0x07,0x00,0x09,0x0F,0x08  /* ; F8-FF */
-        	}
-        }
+		0x04, 0x1A, 0x04, 0x7E, 0x03, 0x1A, 0x06, 0x7D, /* ; C0-C7 */
+		0x01, 0x1A, 0x08, 0x7D, 0x00, 0x19, 0x0A, 0x7D, /* ; C8-CF */
+		0x7F, 0x19, 0x0C, 0x7C, 0x7E, 0x18, 0x0E, 0x7C, /* ; D0-D7 */
+		0x7E, 0x17, 0x10, 0x7B, 0x7D, 0x15, 0x12, 0x7C, /* ; D8-DF */
+		0x7D, 0x13, 0x13, 0x7D, 0x7C, 0x12, 0x15, 0x7D, /* ; E0-E7 */
+		0x7C, 0x10, 0x17, 0x7D, 0x7C, 0x0E, 0x18, 0x7E, /* ; EA-EF */
+		0x7D, 0x0C, 0x19, 0x7E, 0x7D, 0x0A, 0x19, 0x00, /* ; F0-F7 */
+		0x7D, 0x08, 0x1A, 0x01, 0x7E, 0x06, 0x1A, 0x02  /* ; F8-FF */
+		}
+	},
+	{600,	{
+		0x07, 0x14, 0x07, 0x7E, 0x06, 0x14, 0x09, 0x7D, /* ; C0-C7 */
+		0x05, 0x14, 0x0A, 0x7D, 0x04, 0x13, 0x0B, 0x7E, /* ; C8-CF */
+		0x03, 0x13, 0x0C, 0x7E, 0x02, 0x12, 0x0D, 0x7F, /* ; D0-D7 */
+		0x01, 0x12, 0x0E, 0x7F, 0x01, 0x11, 0x0F, 0x7F, /* ; D8-DF */
+		0x01, 0x10, 0x10, 0x00, 0x7F, 0x0F, 0x11, 0x01, /* ; E0-E7 */
+		0x7F, 0x0E, 0x12, 0x01, 0x7E, 0x0D, 0x12, 0x03, /* ; EA-EF */
+		0x7E, 0x0C, 0x13, 0x03, 0x7E, 0x0B, 0x13, 0x04, /* ; F0-F7 */
+		0x7E, 0x0A, 0x14, 0x04, 0x7D, 0x09, 0x14, 0x06  /* ; F8-FF */
+		}
+	},
+	{0xFFFF, {
+		0x09, 0x0F, 0x09, 0x7F, 0x08, 0x0F, 0x09, 0x00, /* ; C0-C7 */
+		0x07, 0x0F, 0x0A, 0x00, 0x06, 0x0F, 0x0A, 0x01, /* ; C8-CF */
+		0x06, 0x0E, 0x0B, 0x01, 0x05, 0x0E, 0x0B, 0x02, /* ; D0-D7 */
+		0x04, 0x0E, 0x0C, 0x02, 0x04, 0x0D, 0x0C, 0x03, /* ; D8-DF */
+		0x03, 0x0D, 0x0D, 0x03, 0x02, 0x0C, 0x0D, 0x05, /* ; E0-E7 */
+		0x02, 0x0C, 0x0E, 0x04, 0x01, 0x0B, 0x0E, 0x06, /* ; EA-EF */
+		0x01, 0x0B, 0x0E, 0x06, 0x00, 0x0A, 0x0F, 0x07, /* ; F0-F7 */
+		0x00, 0x0A, 0x0F, 0x07, 0x00, 0x09, 0x0F, 0x08  /* ; F8-FF */
+		}
+	}
 };
 
-static struct XGI301C_Tap4TimingStruct YPbPr750pTap4Timing[] =
-{        {0xFFFF,
-               {
-               0x05,0x19,0x05,0x7D,0x03,0x19,0x06,0x7E, /* ; C0-C7 */
-               0x02,0x19,0x08,0x7D,0x01,0x18,0x0A,0x7D, /* ; C8-CF */
-               0x00,0x18,0x0C,0x7C,0x7F,0x17,0x0E,0x7C, /* ; D0-D7 */
-               0x7E,0x16,0x0F,0x7D,0x7E,0x14,0x11,0x7D, /* ; D8-DF */
-               0x7D,0x13,0x13,0x7D,0x7D,0x11,0x14,0x7E, /* ; E0-E7 */
-               0x7D,0x0F,0x16,0x7E,0x7D,0x0E,0x17,0x7E, /* ; EA-EF */
-               0x7D,0x0C,0x18,0x7F,0x7D,0x0A,0x18,0x01, /* ; F0-F7 */
-               0x7D,0x08,0x19,0x02,0x7D,0x06,0x19,0x04 /* F8-FF */
-               }
-        }
+static struct XGI301C_Tap4TimingStruct YPbPr750pTap4Timing[] = {
+	{0xFFFF, {
+		 0x05, 0x19, 0x05, 0x7D, 0x03, 0x19, 0x06, 0x7E, /* ; C0-C7 */
+		 0x02, 0x19, 0x08, 0x7D, 0x01, 0x18, 0x0A, 0x7D, /* ; C8-CF */
+		 0x00, 0x18, 0x0C, 0x7C, 0x7F, 0x17, 0x0E, 0x7C, /* ; D0-D7 */
+		 0x7E, 0x16, 0x0F, 0x7D, 0x7E, 0x14, 0x11, 0x7D, /* ; D8-DF */
+		 0x7D, 0x13, 0x13, 0x7D, 0x7D, 0x11, 0x14, 0x7E, /* ; E0-E7 */
+		 0x7D, 0x0F, 0x16, 0x7E, 0x7D, 0x0E, 0x17, 0x7E, /* ; EA-EF */
+		 0x7D, 0x0C, 0x18, 0x7F, 0x7D, 0x0A, 0x18, 0x01, /* ; F0-F7 */
+		 0x7D, 0x08, 0x19, 0x02, 0x7D, 0x06, 0x19, 0x04 /* F8-FF */
+		 }
+	}
 };
diff -druN linux-2.6.39-libre/drivers/staging/xgifb/vb_util.c linux-3.0-rc7-libre/drivers/staging/xgifb/vb_util.c
--- linux-2.6.39-libre/drivers/staging/xgifb/vb_util.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/xgifb/vb_util.c	2011-07-11 19:51:52.000000000 -0400
@@ -3,7 +3,7 @@
 #include "vb_struct.h"
 
 #include "XGIfb.h"
-#include <asm/io.h>
+#include <linux/io.h>
 #include <linux/types.h>
 
 #include "vb_util.h"
diff -druN linux-2.6.39-libre/drivers/staging/xgifb/vgatypes.h linux-3.0-rc7-libre/drivers/staging/xgifb/vgatypes.h
--- linux-2.6.39-libre/drivers/staging/xgifb/vgatypes.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/xgifb/vgatypes.h	2011-07-11 19:51:52.000000000 -0400
@@ -1,4 +1,3 @@
-
 #ifndef _VGATYPES_
 #define _VGATYPES_
 
@@ -6,79 +5,79 @@
 
 #ifndef XGI_VB_CHIP_TYPE
 enum XGI_VB_CHIP_TYPE {
-    VB_CHIP_Legacy = 0,
-    VB_CHIP_301,
-    VB_CHIP_301B,
-    VB_CHIP_301LV,
-    VB_CHIP_302,
-    VB_CHIP_302B,
-    VB_CHIP_302LV,
-    VB_CHIP_301C,
-    VB_CHIP_302ELV,
-    VB_CHIP_UNKNOWN, /* other video bridge or no video bridge */
-    MAX_VB_CHIP
+	VB_CHIP_Legacy = 0,
+	VB_CHIP_301,
+	VB_CHIP_301B,
+	VB_CHIP_301LV,
+	VB_CHIP_302,
+	VB_CHIP_302B,
+	VB_CHIP_302LV,
+	VB_CHIP_301C,
+	VB_CHIP_302ELV,
+	VB_CHIP_UNKNOWN, /* other video bridge or no video bridge */
+	MAX_VB_CHIP
 };
 #endif
 
 #ifndef XGI_LCD_TYPE
 enum XGI_LCD_TYPE {
-    LCD_INVALID = 0,
-    LCD_320x480,       /* FSTN, DSTN */
-    LCD_640x480,
-    LCD_640x480_2,     /* FSTN, DSTN */
-    LCD_640x480_3,     /* FSTN, DSTN */
-    LCD_800x600,
-    LCD_848x480,
-    LCD_1024x600,
-    LCD_1024x768,
-    LCD_1152x768,
-    LCD_1152x864,
-    LCD_1280x720,
-    LCD_1280x768,
-    LCD_1280x800,
-    LCD_1280x960,
-    LCD_1280x1024,
-    LCD_1400x1050,
-    LCD_1600x1200,
-    LCD_1680x1050,
-    LCD_1920x1440,
-    LCD_2048x1536,
-    LCD_CUSTOM,
-    LCD_UNKNOWN
+	LCD_INVALID = 0,
+	LCD_320x480,       /* FSTN, DSTN */
+	LCD_640x480,
+	LCD_640x480_2,     /* FSTN, DSTN */
+	LCD_640x480_3,     /* FSTN, DSTN */
+	LCD_800x600,
+	LCD_848x480,
+	LCD_1024x600,
+	LCD_1024x768,
+	LCD_1152x768,
+	LCD_1152x864,
+	LCD_1280x720,
+	LCD_1280x768,
+	LCD_1280x800,
+	LCD_1280x960,
+	LCD_1280x1024,
+	LCD_1400x1050,
+	LCD_1600x1200,
+	LCD_1680x1050,
+	LCD_1920x1440,
+	LCD_2048x1536,
+	LCD_CUSTOM,
+	LCD_UNKNOWN
 };
 #endif
 
-struct XGI_DSReg
-{
-  unsigned char  jIdx;
-  unsigned char  jVal;
+struct XGI_DSReg {
+	unsigned char jIdx;
+	unsigned char jVal;
 };
 
-struct xgi_hw_device_info
-{
-    unsigned long  ulExternalChip;       /* NO VB or other video bridge*/
-                                 /* if ujVBChipID = VB_CHIP_UNKNOWN, */
+struct xgi_hw_device_info {
+	unsigned long ulExternalChip; /* NO VB or other video bridge*/
+				      /* if ujVBChipID = VB_CHIP_UNKNOWN, */
 
-    unsigned char *pjVirtualRomBase;    /* ROM image */
+	unsigned char *pjVirtualRomBase; /* ROM image */
 
-    unsigned char *pjVideoMemoryAddress;/* base virtual memory address */
-                                 /* of Linear VGA memory */
+	unsigned char *pjVideoMemoryAddress;/* base virtual memory address */
+					    /* of Linear VGA memory */
 
-    unsigned long  ulVideoMemorySize;    /* size, in bytes, of the memory on the board */
+	unsigned long ulVideoMemorySize; /* size, in bytes, of the
+					    memory on the board */
 
-    unsigned char *pjIOAddress;          /* base I/O address of VGA ports (0x3B0) */
+	unsigned char *pjIOAddress; /* base I/O address of VGA ports (0x3B0) */
 
-    unsigned char  jChipType;            /* Used to Identify Graphics Chip */
-                                 /* defined in the data structure type  */
-                                 /* "XGI_CHIP_TYPE" */
+	unsigned char jChipType; /* Used to Identify Graphics Chip */
+				 /* defined in the data structure type  */
+				 /* "XGI_CHIP_TYPE" */
 
-    unsigned char  jChipRevision;        /* Used to Identify Graphics Chip Revision */
+	unsigned char jChipRevision; /* Used to Identify Graphics
+					Chip Revision */
 
-    unsigned char  ujVBChipID;           /* the ID of video bridge */
-                                 /* defined in the data structure type */
-                                 /* "XGI_VB_CHIP_TYPE" */
+	unsigned char ujVBChipID; /* the ID of video bridge */
+				  /* defined in the data structure type */
+				  /* "XGI_VB_CHIP_TYPE" */
 
-    unsigned long  ulCRT2LCDType;        /* defined in the data structure type */
+	unsigned long ulCRT2LCDType; /* defined in the data structure type */
 
 	unsigned char(*pQueryVGAConfigSpace)(struct xgi_hw_device_info *,
 					    unsigned long, unsigned long,
@@ -87,7 +86,5 @@
 
 /* Additional IOCTL for communication xgifb <> X driver        */
 /* If changing this, xgifb.h must also be changed (for xgifb) */
-
-
 #endif
 
diff -druN linux-2.6.39-libre/drivers/staging/xgifb/XGIfb.h linux-3.0-rc7-libre/drivers/staging/xgifb/XGIfb.h
--- linux-2.6.39-libre/drivers/staging/xgifb/XGIfb.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/xgifb/XGIfb.h	2011-07-11 19:51:52.000000000 -0400
@@ -1,7 +1,7 @@
 #ifndef _LINUX_XGIFB
 #define _LINUX_XGIFB
-#include <asm/ioctl.h>
-#include <asm/types.h>
+#include <linux/ioctl.h>
+#include <linux/types.h>
 
 #define DISPTYPE_CRT1       0x00000008L
 #define DISPTYPE_CRT2       0x00000004L
@@ -13,99 +13,99 @@
 #define DISPMODE_MIRROR	    0x00000010L
 #define DISPMODE_DUALVIEW   0x00000040L
 
-#define HASVB_NONE      	0x00
-#define HASVB_301       	0x01
-#define HASVB_LVDS      	0x02
-#define HASVB_TRUMPION  	0x04
-#define HASVB_LVDS_CHRONTEL	0x10
-#define HASVB_302       	0x20
-#define HASVB_303       	0x40
-#define HASVB_CHRONTEL  	0x80
+#define HASVB_NONE	    0x00
+#define HASVB_301	    0x01
+#define HASVB_LVDS	    0x02
+#define HASVB_TRUMPION	    0x04
+#define HASVB_LVDS_CHRONTEL 0x10
+#define HASVB_302	    0x20
+#define HASVB_303	    0x40
+#define HASVB_CHRONTEL	    0x80
 
 #ifndef XGIFB_ID
-#define XGIFB_ID          0x53495346    /* Identify myself with 'XGIF' */
+#define XGIFB_ID	0x53495346 /* Identify myself with 'XGIF' */
 #endif
 
 enum XGI_CHIP_TYPE {
-    XG40 = 32,
-    XG41,
-    XG42,
-    XG45,
-    XG20 = 48,
-    XG21,
-    XG27,
+	XG40 = 32,
+	XG41,
+	XG42,
+	XG45,
+	XG20 = 48,
+	XG21,
+	XG27,
 };
 
 enum xgi_tvtype {
 	TVMODE_NTSC = 0,
 	TVMODE_PAL,
 	TVMODE_HIVISION,
-	TVTYPE_PALM,	// vicki@030226
-    	TVTYPE_PALN,	// vicki@030226
-    	TVTYPE_NTSCJ,	// vicki@030226
+	TVTYPE_PALM,	/* vicki@030226 */
+	TVTYPE_PALN,	/* vicki@030226 */
+	TVTYPE_NTSCJ,	/* vicki@030226 */
 	TVMODE_TOTAL
 };
 
-enum xgi_tv_plug {	/* vicki@030226 */
-//	TVPLUG_Legacy = 0,
-//	TVPLUG_COMPOSITE,
-//	TVPLUG_SVIDEO,
-//	TVPLUG_SCART,
-//	TVPLUG_TOTAL
-    	TVPLUG_UNKNOWN = 0,
-    	TVPLUG_COMPOSITE = 1,
-    	TVPLUG_SVIDEO = 2,
-    	TVPLUG_COMPOSITE_AND_SVIDEO = 3,
-    	TVPLUG_SCART = 4,
-    	TVPLUG_YPBPR_525i = 5,
-    	TVPLUG_YPBPR_525P = 6,
-    	TVPLUG_YPBPR_750P = 7,
-    	TVPLUG_YPBPR_1080i = 8,
+enum xgi_tv_plug { /* vicki@030226 */
+/*	TVPLUG_Legacy = 0, */
+/*	TVPLUG_COMPOSITE,  */
+/*	TVPLUG_SVIDEO,	   */
+/*	TVPLUG_SCART,	   */
+/*	TVPLUG_TOTAL	   */
+	TVPLUG_UNKNOWN = 0,
+	TVPLUG_COMPOSITE = 1,
+	TVPLUG_SVIDEO = 2,
+	TVPLUG_COMPOSITE_AND_SVIDEO = 3,
+	TVPLUG_SCART = 4,
+	TVPLUG_YPBPR_525i = 5,
+	TVPLUG_YPBPR_525P = 6,
+	TVPLUG_YPBPR_750P = 7,
+	TVPLUG_YPBPR_1080i = 8,
 	TVPLUG_TOTAL
 };
 
-struct video_info{
-        int           chip_id;
-        unsigned int  video_size;
-        unsigned long video_base;
-        char  *       video_vbase;
-        unsigned long mmio_base;
+struct video_info {
+	int           chip_id;
+	unsigned int  video_size;
+	unsigned long video_base;
+	char	      *video_vbase;
+	unsigned long mmio_base;
 	unsigned long mmio_size;
-        char  *       mmio_vbase;
-        unsigned long vga_base;
-        unsigned long mtrr;
+	char	      *mmio_vbase;
+	unsigned long vga_base;
+	unsigned long mtrr;
 
-        int    video_bpp;
-        int    video_cmap_len;
-        int    video_width;
-        int    video_height;
-        int    video_vwidth;
-        int    video_vheight;
-        int    org_x;
-        int    org_y;
-        int    video_linelength;
-        unsigned int refresh_rate;
+	int    video_bpp;
+	int    video_cmap_len;
+	int    video_width;
+	int    video_height;
+	int    video_vwidth;
+	int    video_vheight;
+	int    org_x;
+	int    org_y;
+	int    video_linelength;
+	unsigned int refresh_rate;
 
-        unsigned long disp_state;
-        unsigned char hasVB;
-        unsigned char TV_type;
-        unsigned char TV_plug;
+	unsigned long disp_state;
+	unsigned char hasVB;
+	unsigned char TV_type;
+	unsigned char TV_plug;
 
 	enum XGI_CHIP_TYPE chip;
-        unsigned char revision_id;
+	unsigned char revision_id;
 
-        unsigned short DstColor;
-        unsigned long  XGI310_AccelDepth;
-        unsigned long  CommandReg;
+	unsigned short DstColor;
+	unsigned long  XGI310_AccelDepth;
+	unsigned long  CommandReg;
 
-        unsigned int   pcibus;
-        unsigned int   pcislot;
-        unsigned int   pcifunc;
+	unsigned int   pcibus;
+	unsigned int   pcislot;
+	unsigned int   pcifunc;
 
-        unsigned short subsysvendor;
-        unsigned short subsysdevice;
+	unsigned short subsysvendor;
+	unsigned short subsysdevice;
 
-        char reserved[236];
+	char reserved[236];
 };
 
 
diff -druN linux-2.6.39-libre/drivers/staging/xgifb/XGI_main_26.c linux-3.0-rc7-libre/drivers/staging/xgifb/XGI_main_26.c
--- linux-2.6.39-libre/drivers/staging/xgifb/XGI_main_26.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/xgifb/XGI_main_26.c	2011-07-11 19:51:52.000000000 -0400
@@ -33,7 +33,7 @@
 #define XGIFB_PAN
 #endif
 
-#include <asm/io.h>
+#include <linux/io.h>
 #ifdef CONFIG_MTRR
 #include <asm/mtrr.h>
 #endif
@@ -41,7 +41,9 @@
 #include "XGIfb.h"
 #include "vgatypes.h"
 #include "XGI_main.h"
+#include "vb_init.h"
 #include "vb_util.h"
+#include "vb_setmode.h"
 
 #define Index_CR_GPIO_Reg1 0x48
 #define Index_CR_GPIO_Reg2 0x49
@@ -50,7 +52,6 @@
 #define GPIOG_EN    (1<<6)
 #define GPIOG_WRITE (1<<6)
 #define GPIOG_READ  (1<<1)
-int XGIfb_GetXG21DefaultLVDSModeIdx(void);
 
 #define XGIFB_ROM_SIZE	65536
 
@@ -69,69 +70,69 @@
 {
 	u8 i, reg;
 
-	outXGIIDXREG(XGISR, 0x05, 0x86);
+	xgifb_reg_set(XGISR, 0x05, 0x86);
 	/*
-	outXGIIDXREG(XGISR, 0x08, 0x4f);
-	outXGIIDXREG(XGISR, 0x0f, 0x20);
-	outXGIIDXREG(XGISR, 0x11, 0x4f);
-	outXGIIDXREG(XGISR, 0x13, 0x45);
-	outXGIIDXREG(XGISR, 0x14, 0x51);
-	outXGIIDXREG(XGISR, 0x1e, 0x41);
-	outXGIIDXREG(XGISR, 0x1f, 0x0);
-	outXGIIDXREG(XGISR, 0x20, 0xa1);
-	outXGIIDXREG(XGISR, 0x22, 0xfb);
-	outXGIIDXREG(XGISR, 0x26, 0x22);
-	outXGIIDXREG(XGISR, 0x3e, 0x07);
+	xgifb_reg_set(XGISR, 0x08, 0x4f);
+	xgifb_reg_set(XGISR, 0x0f, 0x20);
+	xgifb_reg_set(XGISR, 0x11, 0x4f);
+	xgifb_reg_set(XGISR, 0x13, 0x45);
+	xgifb_reg_set(XGISR, 0x14, 0x51);
+	xgifb_reg_set(XGISR, 0x1e, 0x41);
+	xgifb_reg_set(XGISR, 0x1f, 0x0);
+	xgifb_reg_set(XGISR, 0x20, 0xa1);
+	xgifb_reg_set(XGISR, 0x22, 0xfb);
+	xgifb_reg_set(XGISR, 0x26, 0x22);
+	xgifb_reg_set(XGISR, 0x3e, 0x07);
 	*/
 
-	/* outXGIIDXREG(XGICR, 0x19, 0x00); */
-	/* outXGIIDXREG(XGICR, 0x1a, 0x3C); */
-	/* outXGIIDXREG(XGICR, 0x22, 0xff); */
-	/* outXGIIDXREG(XGICR, 0x3D, 0x10); */
+	/* xgifb_reg_set(XGICR, 0x19, 0x00); */
+	/* xgifb_reg_set(XGICR, 0x1a, 0x3C); */
+	/* xgifb_reg_set(XGICR, 0x22, 0xff); */
+	/* xgifb_reg_set(XGICR, 0x3D, 0x10); */
 
-	/* outXGIIDXREG(XGICR, 0x4a, 0xf3); */
+	/* xgifb_reg_set(XGICR, 0x4a, 0xf3); */
 
-	/* outXGIIDXREG(XGICR, 0x57, 0x0); */
-	/* outXGIIDXREG(XGICR, 0x7a, 0x2c); */
+	/* xgifb_reg_set(XGICR, 0x57, 0x0); */
+	/* xgifb_reg_set(XGICR, 0x7a, 0x2c); */
 
-	/* outXGIIDXREG(XGICR, 0x82, 0xcc); */
-	/* outXGIIDXREG(XGICR, 0x8c, 0x0); */
+	/* xgifb_reg_set(XGICR, 0x82, 0xcc); */
+	/* xgifb_reg_set(XGICR, 0x8c, 0x0); */
 	/*
-	outXGIIDXREG(XGICR, 0x99, 0x1);
-	outXGIIDXREG(XGICR, 0x41, 0x40);
+	xgifb_reg_set(XGICR, 0x99, 0x1);
+	xgifb_reg_set(XGICR, 0x41, 0x40);
 	*/
 
 	for (i = 0; i < 0x4f; i++) {
-		inXGIIDXREG(XGISR, i, reg);
+		reg = xgifb_reg_get(XGISR, i);
 		printk("\no 3c4 %x", i);
 		printk("\ni 3c5 => %x", reg);
 	}
 
 	for (i = 0; i < 0xF0; i++) {
-		inXGIIDXREG(XGICR, i, reg);
+		reg = xgifb_reg_get(XGICR, i);
 		printk("\no 3d4 %x", i);
 		printk("\ni 3d5 => %x", reg);
 	}
 	/*
-	outXGIIDXREG(XGIPART1,0x2F,1);
+	xgifb_reg_set(XGIPART1,0x2F,1);
 	for (i=1; i < 0x50; i++) {
-		inXGIIDXREG(XGIPART1, i, reg);
+		reg = xgifb_reg_get(XGIPART1, i);
 		printk("\no d004 %x", i);
 		printk("\ni d005 => %x", reg);
 	}
 
 	for (i=0; i < 0x50; i++) {
-		 inXGIIDXREG(XGIPART2, i, reg);
+		 reg = xgifb_reg_get(XGIPART2, i);
 		 printk("\no d010 %x", i);
 		 printk("\ni d011 => %x", reg);
 	}
 	for (i=0; i < 0x50; i++) {
-		inXGIIDXREG(XGIPART3, i, reg);
+		reg = xgifb_reg_get(XGIPART3, i);
 		printk("\no d012 %x",i);
 		printk("\ni d013 => %x",reg);
 	}
 	for (i=0; i < 0x50; i++) {
-		inXGIIDXREG(XGIPART4, i, reg);
+		reg = xgifb_reg_get(XGIPART4, i);
 		printk("\no d014 %x",i);
 		printk("\ni d015 => %x",reg);
 	}
@@ -348,10 +349,10 @@
 	else {
 		j = 0;
 		while (XGI_Pr->EModeIDTable[j].Ext_ModeID != 0xff) {
-			if (XGI_Pr->EModeIDTable[j].Ext_ModeID
-					== XGI_Pr->RefIndex[RefreshRateTableIndex].ModeID) {
-				if (XGI_Pr->EModeIDTable[j].Ext_ModeFlag
-						& DoubleScanMode) {
+			if (XGI_Pr->EModeIDTable[j].Ext_ModeID ==
+			    XGI_Pr->RefIndex[RefreshRateTableIndex].ModeID) {
+				if (XGI_Pr->EModeIDTable[j].Ext_ModeFlag &
+				    DoubleScanMode) {
 					*vmode = FB_VMODE_DOUBLE;
 				}
 				break;
@@ -377,30 +378,22 @@
 	XGI_Pr->P3c8 = BaseAddr + 0x18;
 	XGI_Pr->P3c9 = BaseAddr + 0x19;
 	XGI_Pr->P3da = BaseAddr + 0x2A;
-	XGI_Pr->Part1Port = BaseAddr + XGI_CRT2_PORT_04; /* Digital video interface registers (LCD) */
-	XGI_Pr->Part2Port = BaseAddr + XGI_CRT2_PORT_10; /* 301 TV Encoder registers */
-	XGI_Pr->Part3Port = BaseAddr + XGI_CRT2_PORT_12; /* 301 Macrovision registers */
-	XGI_Pr->Part4Port = BaseAddr + XGI_CRT2_PORT_14; /* 301 VGA2 (and LCD) registers */
-	XGI_Pr->Part5Port = BaseAddr + XGI_CRT2_PORT_14 + 2; /* 301 palette address port registers */
-
-}
-
-void XGIfb_set_reg4(u16 port, unsigned long data)
-{
-	outl((u32)(data & 0xffffffff), port);
-}
-
-u32 XGIfb_get_reg3(u16 port)
-{
-	u32 data;
+	/* Digital video interface registers (LCD) */
+	XGI_Pr->Part1Port = BaseAddr + XGI_CRT2_PORT_04;
+	/* 301 TV Encoder registers */
+	XGI_Pr->Part2Port = BaseAddr + XGI_CRT2_PORT_10;
+	/* 301 Macrovision registers */
+	XGI_Pr->Part3Port = BaseAddr + XGI_CRT2_PORT_12;
+	/* 301 VGA2 (and LCD) registers */
+	XGI_Pr->Part4Port = BaseAddr + XGI_CRT2_PORT_14;
+	/* 301 palette address port registers */
+	XGI_Pr->Part5Port = BaseAddr + XGI_CRT2_PORT_14 + 2;
 
-	data = inl(port);
-	return data;
 }
 
 /* ------------ Interface for init & mode switching code ------------- */
 
-unsigned char XGIfb_query_VGA_config_space(
+static unsigned char XGIfb_query_VGA_config_space(
 		struct xgi_hw_device_info *pXGIhw_ext, unsigned long offset,
 		unsigned long set, unsigned long *value)
 {
@@ -436,62 +429,34 @@
 	return 1;
 }
 
-/*
-unsigned char XGIfb_query_north_bridge_space(struct xgi_hw_device_info *pXGIhw_ext,
-	unsigned long offset, unsigned long set, unsigned long *value)
+/* ------------------ Internal helper routines ----------------- */
+
+static int XGIfb_GetXG21DefaultLVDSModeIdx(void)
 {
-	static struct pci_dev *pdev = NULL;
-	static unsigned char init = 0, valid_pdev = 0;
-	u16 nbridge_id = 0;
 
-	if (!init) {
-		init = 1;
-		switch (xgi_video_info.chip) {
-		case XGI_540:
-			nbridge_id = PCI_DEVICE_ID_XG_540;
-			break;
-		case XGI_630:
-			nbridge_id = PCI_DEVICE_ID_XG_630;
-			break;
-		case XGI_730:
-			nbridge_id = PCI_DEVICE_ID_XG_730;
-			break;
-		case XGI_550:
-			nbridge_id = PCI_DEVICE_ID_XG_550;
-			break;
-		case XGI_650:
-			nbridge_id = PCI_DEVICE_ID_XG_650;
-			break;
-		case XGI_740:
-			nbridge_id = PCI_DEVICE_ID_XG_740;
-			break;
-		default:
-			nbridge_id = 0;
-			break;
-		}
+	int found_mode = 0;
+	int XGIfb_mode_idx = 0;
 
-		pdev = pci_get_device(PCI_VENDOR_ID_SI, nbridge_id, pdev);
-		if (pdev) {
-			valid_pdev = 1;
-			pci_dev_put(pdev);
+	found_mode = 0;
+	while ((XGIbios_mode[XGIfb_mode_idx].mode_no != 0)
+			&& (XGIbios_mode[XGIfb_mode_idx].xres
+					<= XGI21_LCDCapList[0].LVDSHDE)) {
+		if ((XGIbios_mode[XGIfb_mode_idx].xres
+				== XGI21_LCDCapList[0].LVDSHDE)
+				&& (XGIbios_mode[XGIfb_mode_idx].yres
+						== XGI21_LCDCapList[0].LVDSVDE)
+				&& (XGIbios_mode[XGIfb_mode_idx].bpp == 8)) {
+			XGIfb_mode_no = XGIbios_mode[XGIfb_mode_idx].mode_no;
+			found_mode = 1;
+			break;
 		}
+		XGIfb_mode_idx++;
 	}
+	if (!found_mode)
+		XGIfb_mode_idx = 0;
 
-	if (!valid_pdev) {
-		printk(KERN_DEBUG "XGIfb: Can't find XGI %d North Bridge device.\n",
-			nbridge_id);
-		return 0;
-	}
-
-	if (set == 0)
-		pci_read_config_dword(pdev, offset, (u32 *)value);
-	else
-		pci_write_config_dword(pdev, offset, (u32)(*value));
-
-	return 1;
+	return XGIfb_mode_idx;
 }
-*/
-/* ------------------ Internal helper routines ----------------- */
 
 static void XGIfb_search_mode(const char *name)
 {
@@ -551,8 +516,8 @@
 	vesamode &= 0x1dff; /* Clean VESA mode number from other flags */
 
 	while (XGIbios_mode[i].mode_no != 0) {
-		if ((XGIbios_mode[i].vesa_mode_no_1 == vesamode)
-				|| (XGIbios_mode[i].vesa_mode_no_2 == vesamode)) {
+		if ((XGIbios_mode[i].vesa_mode_no_1 == vesamode) ||
+		    (XGIbios_mode[i].vesa_mode_no_2 == vesamode)) {
 			xgifb_mode_idx = i;
 			j = 1;
 			break;
@@ -569,11 +534,13 @@
 	unsigned char *pData;
 	int i, j, k;
 
-	inXGIIDXREG(XGISR, 0x1e, tmp);
-	outXGIIDXREG(XGISR, 0x1e, tmp | 4);
+	tmp = xgifb_reg_get(XGISR, 0x1e);
+	xgifb_reg_set(XGISR, 0x1e, tmp | 4);
 
 	pData = xgi_video_info.mmio_vbase + 0x20000;
-	if ((pData[0x0] == 0x55) && (pData[0x1] == 0xAA) && (pData[0x65] & 0x1)) {
+	if ((pData[0x0] == 0x55) &&
+	    (pData[0x1] == 0xAA) &&
+	    (pData[0x65] & 0x1)) {
 		i = pData[0x316] | (pData[0x317] << 8);
 		j = pData[i - 1];
 		if (j == 0xff)
@@ -616,33 +583,6 @@
 	return 0;
 }
 
-int XGIfb_GetXG21DefaultLVDSModeIdx(void)
-{
-
-	int found_mode = 0;
-	int XGIfb_mode_idx = 0;
-
-	found_mode = 0;
-	while ((XGIbios_mode[XGIfb_mode_idx].mode_no != 0)
-			&& (XGIbios_mode[XGIfb_mode_idx].xres
-					<= XGI21_LCDCapList[0].LVDSHDE)) {
-		if ((XGIbios_mode[XGIfb_mode_idx].xres
-				== XGI21_LCDCapList[0].LVDSHDE)
-				&& (XGIbios_mode[XGIfb_mode_idx].yres
-						== XGI21_LCDCapList[0].LVDSVDE)
-				&& (XGIbios_mode[XGIfb_mode_idx].bpp == 8)) {
-			XGIfb_mode_no = XGIbios_mode[XGIfb_mode_idx].mode_no;
-			found_mode = 1;
-			break;
-		}
-		XGIfb_mode_idx++;
-	}
-	if (!found_mode)
-		XGIfb_mode_idx = 0;
-
-	return XGIfb_mode_idx;
-}
-
 static int XGIfb_validate_mode(int myindex)
 {
 	u16 xres, yres;
@@ -656,8 +596,8 @@
 				return -1;
 			if (XGIbios_mode[myindex].yres > yres)
 				return -1;
-			if ((XGIbios_mode[myindex].xres < xres)
-					&& (XGIbios_mode[myindex].yres < yres)) {
+			if ((XGIbios_mode[myindex].xres < xres) &&
+			    (XGIbios_mode[myindex].yres < yres)) {
 				if (XGIbios_mode[myindex].bpp > 8)
 					return -1;
 			}
@@ -733,7 +673,7 @@
 		if (XGIbios_mode[myindex].yres > yres)
 			return -1;
 		if ((XGIhw_ext.ulExternalChip == 0x01) || /* LVDS */
-				(XGIhw_ext.ulExternalChip == 0x05)) { /* LVDS+Chrontel */
+		    (XGIhw_ext.ulExternalChip == 0x05)) { /* LVDS+Chrontel */
 			switch (XGIbios_mode[myindex].xres) {
 			case 512:
 				if (XGIbios_mode[myindex].yres != 512)
@@ -752,13 +692,11 @@
 					return -1;
 				break;
 			case 1024:
-				if ((XGIbios_mode[myindex].yres != 600)
-						&& (XGIbios_mode[myindex].yres
-								!= 768))
+				if ((XGIbios_mode[myindex].yres != 600) &&
+				    (XGIbios_mode[myindex].yres != 768))
 					return -1;
-				if ((XGIbios_mode[myindex].yres == 600)
-						&& (XGIhw_ext.ulCRT2LCDType
-								!= LCD_1024x600))
+				if ((XGIbios_mode[myindex].yres == 600) &&
+				    (XGIhw_ext.ulCRT2LCDType != LCD_1024x600))
 					return -1;
 				break;
 			case 1152:
@@ -768,13 +706,11 @@
 					return -1;
 				break;
 			case 1280:
-				if ((XGIbios_mode[myindex].yres != 768)
-						&& (XGIbios_mode[myindex].yres
-								!= 1024))
+				if ((XGIbios_mode[myindex].yres != 768) &&
+				    (XGIbios_mode[myindex].yres != 1024))
 					return -1;
-				if ((XGIbios_mode[myindex].yres == 768)
-						&& (XGIhw_ext.ulCRT2LCDType
-								!= LCD_1280x768))
+				if ((XGIbios_mode[myindex].yres == 768) &&
+				    (XGIhw_ext.ulCRT2LCDType != LCD_1280x768))
 					return -1;
 				break;
 			case 1400:
@@ -795,9 +731,8 @@
 					return -1;
 				break;
 			case 640:
-				if ((XGIbios_mode[myindex].yres != 400)
-						&& (XGIbios_mode[myindex].yres
-								!= 480))
+				if ((XGIbios_mode[myindex].yres != 400) &&
+				    (XGIbios_mode[myindex].yres != 480))
 					return -1;
 				break;
 			case 800:
@@ -809,13 +744,12 @@
 					return -1;
 				break;
 			case 1280:
-				if ((XGIbios_mode[myindex].yres != 960)
-						&& (XGIbios_mode[myindex].yres
-								!= 1024))
+				if ((XGIbios_mode[myindex].yres != 960) &&
+				    (XGIbios_mode[myindex].yres != 1024))
 					return -1;
 				if (XGIbios_mode[myindex].yres == 960) {
-					if (XGIhw_ext.ulCRT2LCDType
-							== LCD_1400x1050)
+					if (XGIhw_ext.ulCRT2LCDType ==
+					    LCD_1400x1050)
 						return -1;
 				}
 				break;
@@ -847,8 +781,8 @@
 					return -1;
 			}
 			/*  TW: LVDS/CHRONTEL does not support 720 */
-			if (xgi_video_info.hasVB == HASVB_LVDS_CHRONTEL
-					|| xgi_video_info.hasVB	== HASVB_CHRONTEL) {
+			if (xgi_video_info.hasVB == HASVB_LVDS_CHRONTEL ||
+			    xgi_video_info.hasVB == HASVB_CHRONTEL) {
 				return -1;
 			}
 			break;
@@ -900,31 +834,31 @@
 
 	XGIfb_rate_idx = 0;
 	while ((XGIfb_vrate[i].idx != 0) && (XGIfb_vrate[i].xres <= xres)) {
-		if ((XGIfb_vrate[i].xres == xres) && (XGIfb_vrate[i].yres
-				== yres)) {
+		if ((XGIfb_vrate[i].xres == xres) &&
+		    (XGIfb_vrate[i].yres == yres)) {
 			if (XGIfb_vrate[i].refresh == rate) {
 				XGIfb_rate_idx = XGIfb_vrate[i].idx;
 				break;
 			} else if (XGIfb_vrate[i].refresh > rate) {
 				if ((XGIfb_vrate[i].refresh - rate) <= 3) {
 					DPRINTK("XGIfb: Adjusting rate from %d up to %d\n",
-							rate, XGIfb_vrate[i].refresh);
+						rate, XGIfb_vrate[i].refresh);
 					XGIfb_rate_idx = XGIfb_vrate[i].idx;
-					xgi_video_info.refresh_rate
-							= XGIfb_vrate[i].refresh;
+					xgi_video_info.refresh_rate =
+						XGIfb_vrate[i].refresh;
 				} else if (((rate - XGIfb_vrate[i - 1].refresh)
 						<= 2) && (XGIfb_vrate[i].idx
 						!= 1)) {
 					DPRINTK("XGIfb: Adjusting rate from %d down to %d\n",
-							rate, XGIfb_vrate[i-1].refresh);
+						rate, XGIfb_vrate[i-1].refresh);
 					XGIfb_rate_idx = XGIfb_vrate[i - 1].idx;
-					xgi_video_info.refresh_rate
-							= XGIfb_vrate[i - 1].refresh;
+					xgi_video_info.refresh_rate =
+						XGIfb_vrate[i - 1].refresh;
 				}
 				break;
 			} else if ((rate - XGIfb_vrate[i].refresh) <= 2) {
 				DPRINTK("XGIfb: Adjusting rate from %d down to %d\n",
-						rate, XGIfb_vrate[i].refresh);
+					rate, XGIfb_vrate[i].refresh);
 				XGIfb_rate_idx = XGIfb_vrate[i].idx;
 				break;
 			}
@@ -934,8 +868,8 @@
 	if (XGIfb_rate_idx > 0) {
 		return XGIfb_rate_idx;
 	} else {
-		printk(KERN_INFO
-				"XGIfb: Unsupported rate %d for %dx%d\n", rate, xres, yres);
+		printk(KERN_INFO "XGIfb: Unsupported rate %d for %dx%d\n",
+		       rate, xres, yres);
 		return 0;
 	}
 }
@@ -991,6 +925,282 @@
 	}
 }
 
+/* --------------------- SetMode routines ------------------------- */
+
+static void XGIfb_pre_setmode(void)
+{
+	u8 cr30 = 0, cr31 = 0;
+
+	cr31 = xgifb_reg_get(XGICR, 0x31);
+	cr31 &= ~0x60;
+
+	switch (xgi_video_info.disp_state & DISPTYPE_DISP2) {
+	case DISPTYPE_CRT2:
+		cr30 = (XGI_VB_OUTPUT_CRT2 | XGI_SIMULTANEOUS_VIEW_ENABLE);
+		cr31 |= XGI_DRIVER_MODE;
+		break;
+	case DISPTYPE_LCD:
+		cr30 = (XGI_VB_OUTPUT_LCD | XGI_SIMULTANEOUS_VIEW_ENABLE);
+		cr31 |= XGI_DRIVER_MODE;
+		break;
+	case DISPTYPE_TV:
+		if (xgi_video_info.TV_type == TVMODE_HIVISION)
+			cr30 = (XGI_VB_OUTPUT_HIVISION
+					| XGI_SIMULTANEOUS_VIEW_ENABLE);
+		else if (xgi_video_info.TV_plug == TVPLUG_SVIDEO)
+			cr30 = (XGI_VB_OUTPUT_SVIDEO
+					| XGI_SIMULTANEOUS_VIEW_ENABLE);
+		else if (xgi_video_info.TV_plug == TVPLUG_COMPOSITE)
+			cr30 = (XGI_VB_OUTPUT_COMPOSITE
+					| XGI_SIMULTANEOUS_VIEW_ENABLE);
+		else if (xgi_video_info.TV_plug == TVPLUG_SCART)
+			cr30 = (XGI_VB_OUTPUT_SCART
+					| XGI_SIMULTANEOUS_VIEW_ENABLE);
+		cr31 |= XGI_DRIVER_MODE;
+
+		if (XGIfb_tvmode == 1 || xgi_video_info.TV_type == TVMODE_PAL)
+			cr31 |= 0x01;
+		else
+			cr31 &= ~0x01;
+		break;
+	default: /* disable CRT2 */
+		cr30 = 0x00;
+		cr31 |= (XGI_DRIVER_MODE | XGI_VB_OUTPUT_DISABLE);
+	}
+
+	xgifb_reg_set(XGICR, IND_XGI_SCRATCH_REG_CR30, cr30);
+	xgifb_reg_set(XGICR, IND_XGI_SCRATCH_REG_CR31, cr31);
+	xgifb_reg_set(XGICR, IND_XGI_SCRATCH_REG_CR33, (XGIfb_rate_idx & 0x0F));
+}
+
+static void XGIfb_post_setmode(void)
+{
+	u8 reg;
+	unsigned char doit = 1;
+	/*
+	xgifb_reg_set(XGISR,IND_XGI_PASSWORD,XGI_PASSWORD);
+	xgifb_reg_set(XGICR, 0x13, 0x00);
+	xgifb_reg_and_or(XGISR,0x0E, 0xF0, 0x01);
+	*test*
+	*/
+	if (xgi_video_info.video_bpp == 8) {
+		/* TW: We can't switch off CRT1 on LVDS/Chrontel
+		 * in 8bpp Modes */
+		if ((xgi_video_info.hasVB == HASVB_LVDS) ||
+		    (xgi_video_info.hasVB == HASVB_LVDS_CHRONTEL)) {
+			doit = 0;
+		}
+		/* TW: We can't switch off CRT1 on 301B-DH
+		 * in 8bpp Modes if using LCD */
+		if (xgi_video_info.disp_state & DISPTYPE_LCD)
+			doit = 0;
+	}
+
+	/* TW: We can't switch off CRT1 if bridge is in slave mode */
+	if (xgi_video_info.hasVB != HASVB_NONE) {
+		reg = xgifb_reg_get(XGIPART1, 0x00);
+
+		if ((reg & 0x50) == 0x10)
+			doit = 0;
+
+	} else {
+		XGIfb_crt1off = 0;
+	}
+
+	reg = xgifb_reg_get(XGICR, 0x17);
+	if ((XGIfb_crt1off) && (doit))
+		reg &= ~0x80;
+	else
+		reg |= 0x80;
+	xgifb_reg_set(XGICR, 0x17, reg);
+
+	xgifb_reg_and(XGISR, IND_XGI_RAMDAC_CONTROL, ~0x04);
+
+	if ((xgi_video_info.disp_state & DISPTYPE_TV) && (xgi_video_info.hasVB
+			== HASVB_301)) {
+
+		reg = xgifb_reg_get(XGIPART4, 0x01);
+
+		if (reg < 0xB0) { /* Set filter for XGI301 */
+			switch (xgi_video_info.video_width) {
+			case 320:
+				filter_tb = (xgi_video_info.TV_type ==
+					     TVMODE_NTSC) ? 4 : 12;
+				break;
+			case 640:
+				filter_tb = (xgi_video_info.TV_type ==
+					     TVMODE_NTSC) ? 5 : 13;
+				break;
+			case 720:
+				filter_tb = (xgi_video_info.TV_type ==
+					     TVMODE_NTSC) ? 6 : 14;
+				break;
+			case 800:
+				filter_tb = (xgi_video_info.TV_type ==
+					     TVMODE_NTSC) ? 7 : 15;
+				break;
+			default:
+				filter = -1;
+				break;
+			}
+			xgifb_reg_or(XGIPART1, XGIfb_CRT2_write_enable, 0x01);
+
+			if (xgi_video_info.TV_type == TVMODE_NTSC) {
+
+				xgifb_reg_and(XGIPART2, 0x3a, 0x1f);
+
+				if (xgi_video_info.TV_plug == TVPLUG_SVIDEO) {
+
+					xgifb_reg_and(XGIPART2, 0x30, 0xdf);
+
+				} else if (xgi_video_info.TV_plug
+						== TVPLUG_COMPOSITE) {
+
+					xgifb_reg_or(XGIPART2, 0x30, 0x20);
+
+					switch (xgi_video_info.video_width) {
+					case 640:
+						xgifb_reg_set(XGIPART2,
+							      0x35,
+							      0xEB);
+						xgifb_reg_set(XGIPART2,
+							      0x36,
+							      0x04);
+						xgifb_reg_set(XGIPART2,
+							      0x37,
+							      0x25);
+						xgifb_reg_set(XGIPART2,
+							      0x38,
+							      0x18);
+						break;
+					case 720:
+						xgifb_reg_set(XGIPART2,
+							      0x35,
+							      0xEE);
+						xgifb_reg_set(XGIPART2,
+							      0x36,
+							      0x0C);
+						xgifb_reg_set(XGIPART2,
+							      0x37,
+							      0x22);
+						xgifb_reg_set(XGIPART2,
+							      0x38,
+							      0x08);
+						break;
+					case 800:
+						xgifb_reg_set(XGIPART2,
+							      0x35,
+							      0xEB);
+						xgifb_reg_set(XGIPART2,
+							      0x36,
+							      0x15);
+						xgifb_reg_set(XGIPART2,
+							      0x37,
+							      0x25);
+						xgifb_reg_set(XGIPART2,
+							      0x38,
+							      0xF6);
+						break;
+					}
+				}
+
+			} else if (xgi_video_info.TV_type == TVMODE_PAL) {
+
+				xgifb_reg_and(XGIPART2, 0x3A, 0x1F);
+
+				if (xgi_video_info.TV_plug == TVPLUG_SVIDEO) {
+
+					xgifb_reg_and(XGIPART2, 0x30, 0xDF);
+
+				} else if (xgi_video_info.TV_plug
+						== TVPLUG_COMPOSITE) {
+
+					xgifb_reg_or(XGIPART2, 0x30, 0x20);
+
+					switch (xgi_video_info.video_width) {
+					case 640:
+						xgifb_reg_set(XGIPART2,
+							      0x35,
+							      0xF1);
+						xgifb_reg_set(XGIPART2,
+							      0x36,
+							      0xF7);
+						xgifb_reg_set(XGIPART2,
+							      0x37,
+							      0x1F);
+						xgifb_reg_set(XGIPART2,
+							      0x38,
+							      0x32);
+						break;
+					case 720:
+						xgifb_reg_set(XGIPART2,
+							      0x35,
+							      0xF3);
+						xgifb_reg_set(XGIPART2,
+							      0x36,
+							      0x00);
+						xgifb_reg_set(XGIPART2,
+							      0x37,
+							      0x1D);
+						xgifb_reg_set(XGIPART2,
+							      0x38,
+							      0x20);
+						break;
+					case 800:
+						xgifb_reg_set(XGIPART2,
+							      0x35,
+							      0xFC);
+						xgifb_reg_set(XGIPART2,
+							      0x36,
+							      0xFB);
+						xgifb_reg_set(XGIPART2,
+							      0x37,
+							      0x14);
+						xgifb_reg_set(XGIPART2,
+							      0x38,
+							      0x2A);
+						break;
+					}
+				}
+			}
+
+			if ((filter >= 0) && (filter <= 7)) {
+				DPRINTK("FilterTable[%d]-%d: %02x %02x %02x %02x\n",
+					filter_tb, filter,
+					XGI_TV_filter[filter_tb].
+						filter[filter][0],
+					XGI_TV_filter[filter_tb].
+						filter[filter][1],
+					XGI_TV_filter[filter_tb].
+						filter[filter][2],
+					XGI_TV_filter[filter_tb].
+						filter[filter][3]
+				);
+				xgifb_reg_set(
+					XGIPART2,
+					0x35,
+					(XGI_TV_filter[filter_tb].
+						filter[filter][0]));
+				xgifb_reg_set(
+					XGIPART2,
+					0x36,
+					(XGI_TV_filter[filter_tb].
+						filter[filter][1]));
+				xgifb_reg_set(
+					XGIPART2,
+					0x37,
+					(XGI_TV_filter[filter_tb].
+						filter[filter][2]));
+				xgifb_reg_set(
+					XGIPART2,
+					0x38,
+					(XGI_TV_filter[filter_tb].
+						filter[filter][3]));
+			}
+		}
+	}
+}
+
 static int XGIfb_do_set_var(struct fb_var_screeninfo *var, int isactive,
 		struct fb_info *info)
 {
@@ -1039,7 +1249,10 @@
 	}
 
 	printk(KERN_DEBUG "XGIfb: Change mode to %dx%dx%d-%dHz\n",
-			var->xres, var->yres, var->bits_per_pixel, xgi_video_info.refresh_rate);
+	       var->xres,
+	       var->yres,
+	       var->bits_per_pixel,
+	       xgi_video_info.refresh_rate);
 
 	old_mode = xgifb_mode_idx;
 	xgifb_mode_idx = 0;
@@ -1064,8 +1277,8 @@
 		xgifb_mode_idx = -1;
 
 	if (xgifb_mode_idx < 0) {
-		printk(KERN_ERR "XGIfb: Mode %dx%dx%d not supported\n", var->xres,
-				var->yres, var->bits_per_pixel);
+		printk(KERN_ERR "XGIfb: Mode %dx%dx%d not supported\n",
+		       var->xres, var->yres, var->bits_per_pixel);
 		xgifb_mode_idx = old_mode;
 		return -EINVAL;
 	}
@@ -1079,16 +1292,19 @@
 
 		XGIfb_pre_setmode();
 		if (XGISetModeNew(&XGIhw_ext, XGIfb_mode_no) == 0) {
-			printk(KERN_ERR "XGIfb: Setting mode[0x%x] failed\n", XGIfb_mode_no);
+			printk(KERN_ERR "XGIfb: Setting mode[0x%x] failed\n",
+			       XGIfb_mode_no);
 			return -EINVAL;
 		}
 		info->fix.line_length = ((info->var.xres_virtual
 				* info->var.bits_per_pixel) >> 6);
 
-		outXGIIDXREG(XGISR, IND_XGI_PASSWORD, XGI_PASSWORD);
+		xgifb_reg_set(XGISR, IND_XGI_PASSWORD, XGI_PASSWORD);
 
-		outXGIIDXREG(XGICR, 0x13, (info->fix.line_length & 0x00ff));
-		outXGIIDXREG(XGISR, 0x0E, (info->fix.line_length & 0xff00) >> 8);
+		xgifb_reg_set(XGICR, 0x13, (info->fix.line_length & 0x00ff));
+		xgifb_reg_set(XGISR,
+			      0x0E,
+			      (info->fix.line_length & 0xff00) >> 8);
 
 		XGIfb_post_setmode();
 
@@ -1112,16 +1328,16 @@
 			xgi_video_info.XGI310_AccelDepth = 0x00000000;
 			xgi_video_info.video_cmap_len = 256;
 #if defined(__powerpc__)
-			inXGIIDXREG(XGICR, 0x4D, cr_data);
-			outXGIIDXREG(XGICR, 0x4D, (cr_data & 0xE0));
+			cr_data = xgifb_reg_get(XGICR, 0x4D);
+			xgifb_reg_set(XGICR, 0x4D, (cr_data & 0xE0));
 #endif
 			break;
 		case 16:
 			xgi_video_info.DstColor = 0x8000;
 			xgi_video_info.XGI310_AccelDepth = 0x00010000;
 #if defined(__powerpc__)
-			inXGIIDXREG(XGICR, 0x4D, cr_data);
-			outXGIIDXREG(XGICR, 0x4D, ((cr_data & 0xE0) | 0x0B));
+			cr_data = xgifb_reg_get(XGICR, 0x4D);
+			xgifb_reg_set(XGICR, 0x4D, ((cr_data & 0xE0) | 0x0B));
 #endif
 			xgi_video_info.video_cmap_len = 16;
 			break;
@@ -1130,13 +1346,14 @@
 			xgi_video_info.XGI310_AccelDepth = 0x00020000;
 			xgi_video_info.video_cmap_len = 16;
 #if defined(__powerpc__)
-			inXGIIDXREG(XGICR, 0x4D, cr_data);
-			outXGIIDXREG(XGICR, 0x4D, ((cr_data & 0xE0) | 0x15));
+			cr_data = xgifb_reg_get(XGICR, 0x4D);
+			xgifb_reg_set(XGICR, 0x4D, ((cr_data & 0xE0) | 0x15));
 #endif
 			break;
 		default:
 			xgi_video_info.video_cmap_len = 16;
-			printk(KERN_ERR "XGIfb: Unsupported depth %d", xgi_video_info.video_bpp);
+			printk(KERN_ERR "XGIfb: Unsupported depth %d",
+			       xgi_video_info.video_bpp);
 			break;
 		}
 	}
@@ -1179,20 +1396,23 @@
 		break;
 	}
 
-	outXGIIDXREG(XGISR, IND_XGI_PASSWORD, XGI_PASSWORD);
+	xgifb_reg_set(XGISR, IND_XGI_PASSWORD, XGI_PASSWORD);
 
-	outXGIIDXREG(XGICR, 0x0D, base & 0xFF);
-	outXGIIDXREG(XGICR, 0x0C, (base >> 8) & 0xFF);
-	outXGIIDXREG(XGISR, 0x0D, (base >> 16) & 0xFF);
-	outXGIIDXREG(XGISR, 0x37, (base >> 24) & 0x03);
-	setXGIIDXREG(XGISR, 0x37, 0xDF, (base >> 21) & 0x04);
+	xgifb_reg_set(XGICR, 0x0D, base & 0xFF);
+	xgifb_reg_set(XGICR, 0x0C, (base >> 8) & 0xFF);
+	xgifb_reg_set(XGISR, 0x0D, (base >> 16) & 0xFF);
+	xgifb_reg_set(XGISR, 0x37, (base >> 24) & 0x03);
+	xgifb_reg_and_or(XGISR, 0x37, 0xDF, (base >> 21) & 0x04);
 
 	if (xgi_video_info.disp_state & DISPTYPE_DISP2) {
-		orXGIIDXREG(XGIPART1, XGIfb_CRT2_write_enable, 0x01);
-		outXGIIDXREG(XGIPART1, 0x06, (base & 0xFF));
-		outXGIIDXREG(XGIPART1, 0x05, ((base >> 8) & 0xFF));
-		outXGIIDXREG(XGIPART1, 0x04, ((base >> 16) & 0xFF));
-		setXGIIDXREG(XGIPART1, 0x02, 0x7F, ((base >> 24) & 0x01) << 7);
+		xgifb_reg_or(XGIPART1, XGIfb_CRT2_write_enable, 0x01);
+		xgifb_reg_set(XGIPART1, 0x06, (base & 0xFF));
+		xgifb_reg_set(XGIPART1, 0x05, ((base >> 8) & 0xFF));
+		xgifb_reg_set(XGIPART1, 0x04, ((base >> 16) & 0xFF));
+		xgifb_reg_and_or(XGIPART1,
+				 0x02,
+				 0x7F,
+				 ((base >> 24) & 0x01) << 7);
 	}
 	/* printk("End of pan_var"); */
 	return 0;
@@ -1235,15 +1455,15 @@
 
 	switch (info->var.bits_per_pixel) {
 	case 8:
-		outXGIREG(XGIDACA, regno);
-		outXGIREG(XGIDACD, (red >> 10));
-		outXGIREG(XGIDACD, (green >> 10));
-		outXGIREG(XGIDACD, (blue >> 10));
+		outb(regno, XGIDACA);
+		outb((red >> 10), XGIDACD);
+		outb((green >> 10), XGIDACD);
+		outb((blue >> 10), XGIDACD);
 		if (xgi_video_info.disp_state & DISPTYPE_DISP2) {
-			outXGIREG(XGIDAC2A, regno);
-			outXGIREG(XGIDAC2D, (red >> 8));
-			outXGIREG(XGIDAC2D, (green >> 8));
-			outXGIREG(XGIDAC2D, (blue >> 8));
+			outb(regno, XGIDAC2A);
+			outb((red >> 8), XGIDAC2D);
+			outb((green >> 8), XGIDAC2D);
+			outb((blue >> 8), XGIDAC2D);
 		}
 		break;
 	case 16:
@@ -1262,6 +1482,41 @@
 	return 0;
 }
 
+/* ----------- FBDev related routines for all series ---------- */
+
+static int XGIfb_get_fix(struct fb_fix_screeninfo *fix, int con,
+		struct fb_info *info)
+{
+	DEBUGPRN("inside get_fix");
+	memset(fix, 0, sizeof(struct fb_fix_screeninfo));
+
+	strcpy(fix->id, myid);
+
+	fix->smem_start = xgi_video_info.video_base;
+
+	fix->smem_len = xgi_video_info.video_size;
+
+	fix->type = video_type;
+	fix->type_aux = 0;
+	if (xgi_video_info.video_bpp == 8)
+		fix->visual = FB_VISUAL_PSEUDOCOLOR;
+	else
+		fix->visual = FB_VISUAL_DIRECTCOLOR;
+	fix->xpanstep = 0;
+#ifdef XGIFB_PAN
+	if (XGIfb_ypan)
+		fix->ypanstep = 1;
+#endif
+	fix->ywrapstep = 0;
+	fix->line_length = xgi_video_info.video_linelength;
+	fix->mmio_start = xgi_video_info.mmio_base;
+	fix->mmio_len = xgi_video_info.mmio_size;
+	fix->accel = FB_ACCEL_XGI_XABRE;
+
+	DEBUGPRN("end of get_fix");
+	return 0;
+}
+
 static int XGIfb_set_par(struct fb_info *info)
 {
 	int err;
@@ -1307,7 +1562,8 @@
 	if (var->pixclock && htotal && vtotal) {
 		drate = 1000000000 / var->pixclock;
 		hrate = (drate * 1000) / htotal;
-		xgi_video_info.refresh_rate = (unsigned int) (hrate * 2	/ vtotal);
+		xgi_video_info.refresh_rate =
+			(unsigned int) (hrate * 2 / vtotal);
 		printk(KERN_DEBUG
 			"%s: pixclock = %d ,htotal=%d, vtotal=%d\n"
 			"%s: drate=%d, hrate=%d, refresh_rate=%d\n",
@@ -1350,10 +1606,10 @@
 			var->xres, var->yres, var->bits_per_pixel);
 		search_idx = 0;
 		while (XGIbios_mode[search_idx].mode_no != 0) {
-
 			if ((var->xres <= XGIbios_mode[search_idx].xres) &&
-				(var->yres <= XGIbios_mode[search_idx].yres) &&
-				(var->bits_per_pixel == XGIbios_mode[search_idx].bpp)) {
+			    (var->yres <= XGIbios_mode[search_idx].yres) &&
+			    (var->bits_per_pixel ==
+			     XGIbios_mode[search_idx].bpp)) {
 				if (XGIfb_validate_mode(search_idx) > 0) {
 					found_mode = 1;
 					break;
@@ -1393,7 +1649,8 @@
 	} /* else { */
 		/* TW: Now patch yres_virtual if we use panning */
 		/* May I do this? */
-		/* var->yres_virtual = xgi_video_info.heapstart / (var->xres * (var->bits_per_pixel >> 3)); */
+		/* var->yres_virtual = xgi_video_info.heapstart /
+			(var->xres * (var->bits_per_pixel >> 3)); */
 		/* if (var->yres_virtual <= var->yres) { */
 		/* TW: Paranoia check */
 		/* var->yres_virtual = var->yres; */
@@ -1460,51 +1717,16 @@
 {
 	u8 reg;
 
-	inXGIIDXREG(XGICR, 0x17, reg);
+	reg = xgifb_reg_get(XGICR, 0x17);
 
 	if (blank > 0)
 		reg &= 0x7f;
 	else
 		reg |= 0x80;
 
-	outXGIIDXREG(XGICR, 0x17, reg);
-	outXGIIDXREG(XGISR, 0x00, 0x01); /* Synchronous Reset */
-	outXGIIDXREG(XGISR, 0x00, 0x03); /* End Reset */
-	return 0;
-}
-
-/* ----------- FBDev related routines for all series ---------- */
-
-static int XGIfb_get_fix(struct fb_fix_screeninfo *fix, int con,
-		struct fb_info *info)
-{
-	DEBUGPRN("inside get_fix");
-	memset(fix, 0, sizeof(struct fb_fix_screeninfo));
-
-	strcpy(fix->id, myid);
-
-	fix->smem_start = xgi_video_info.video_base;
-
-	fix->smem_len = xgi_video_info.video_size;
-
-	fix->type = video_type;
-	fix->type_aux = 0;
-	if (xgi_video_info.video_bpp == 8)
-		fix->visual = FB_VISUAL_PSEUDOCOLOR;
-	else
-		fix->visual = FB_VISUAL_DIRECTCOLOR;
-	fix->xpanstep = 0;
-#ifdef XGIFB_PAN
-	if (XGIfb_ypan)
-		fix->ypanstep = 1;
-#endif
-	fix->ywrapstep = 0;
-	fix->line_length = xgi_video_info.video_linelength;
-	fix->mmio_start = xgi_video_info.mmio_base;
-	fix->mmio_len = xgi_video_info.mmio_size;
-	fix->accel = FB_ACCEL_XGI_XABRE;
-
-	DEBUGPRN("end of get_fix");
+	xgifb_reg_set(XGICR, 0x17, reg);
+	xgifb_reg_set(XGISR, 0x00, 0x01); /* Synchronous Reset */
+	xgifb_reg_set(XGISR, 0x00, 0x03); /* End Reset */
 	return 0;
 }
 
@@ -1537,9 +1759,9 @@
 
 	/* xorg driver sets 32MB * 1 channel */
 	if (xgi_video_info.chip == XG27)
-		outXGIIDXREG(XGISR, IND_XGI_DRAM_SIZE, 0x51);
+		xgifb_reg_set(XGISR, IND_XGI_DRAM_SIZE, 0x51);
 
-	inXGIIDXREG(XGISR, IND_XGI_DRAM_SIZE, reg);
+	reg = xgifb_reg_get(XGISR, IND_XGI_DRAM_SIZE);
 	switch ((reg & XGI_DRAM_SIZE_MASK) >> 4) {
 	case XGI_DRAM_SIZE_1MB:
 		xgi_video_info.video_size = 0x100000;
@@ -1614,8 +1836,9 @@
 	/* xgi_video_info.video_size = 0x200000; */ /* 1024x768x16 */
 	/* xgi_video_info.video_size = 0x1000000; */ /* benchmark */
 
-	printk("XGIfb: SR14=%x DramSzie %x ChannelNum %x\n", reg,
-			xgi_video_info.video_size, ChannelNum);
+	printk("XGIfb: SR14=%x DramSzie %x ChannelNum %x\n",
+	       reg,
+	       xgi_video_info.video_size, ChannelNum);
 	return 0;
 
 }
@@ -1636,7 +1859,7 @@
 		break;
 	}
 
-	inXGIIDXREG(XGICR, IND_XGI_SCRATCH_REG_CR32, cr32);
+	cr32 = xgifb_reg_get(XGICR, IND_XGI_SCRATCH_REG_CR32);
 
 	if ((cr32 & XGI_CRT1) && !XGIfb_crt1off)
 		XGIfb_crt1off = 0;
@@ -1673,7 +1896,7 @@
 		xgi_video_info.TV_plug = TVPLUG_SCART;
 
 	if (xgi_video_info.TV_type == 0) {
-		inXGIIDXREG(XGICR, 0x38, temp);
+		temp = xgifb_reg_get(XGICR, 0x38);
 		if (temp & 0x10)
 			xgi_video_info.TV_type = TVMODE_PAL;
 		else
@@ -1689,30 +1912,11 @@
 	}
 }
 
-static void XGIfb_get_VB_type(void)
-{
-	u8 reg;
-
-	if (!XGIfb_has_VB()) {
-		inXGIIDXREG(XGICR, IND_XGI_SCRATCH_REG_CR37, reg);
-		switch ((reg & XGI_EXTERNAL_CHIP_MASK) >> 1) {
-		case XGI310_EXTERNAL_CHIP_LVDS:
-			xgi_video_info.hasVB = HASVB_LVDS;
-			break;
-		case XGI310_EXTERNAL_CHIP_LVDS_CHRONTEL:
-			xgi_video_info.hasVB = HASVB_LVDS_CHRONTEL;
-			break;
-		default:
-			break;
-		}
-	}
-}
-
 static int XGIfb_has_VB(void)
 {
 	u8 vb_chipid;
 
-	inXGIIDXREG(XGIPART4, 0x00, vb_chipid);
+	vb_chipid = xgifb_reg_get(XGIPART4, 0x00);
 	switch (vb_chipid) {
 	case 0x01:
 		xgi_video_info.hasVB = HASVB_301;
@@ -1727,344 +1931,23 @@
 	return 1;
 }
 
-/* ------------------ Sensing routines ------------------ */
-
-/* TW: Determine and detect attached devices on XGI30x */
-int XGIDoSense(int tempbl, int tempbh, int tempcl, int tempch)
-{
-	int temp, i;
-
-	outXGIIDXREG(XGIPART4, 0x11, tempbl);
-	temp = tempbh | tempcl;
-	setXGIIDXREG(XGIPART4, 0x10, 0xe0, temp);
-	for (i = 0; i < 10; i++)
-		XGI_LongWait(&XGI_Pr);
-	tempch &= 0x7f;
-	inXGIIDXREG(XGIPART4, 0x03, temp);
-	temp ^= 0x0e;
-	temp &= tempch;
-	return temp;
-}
-
-void XGI_Sense30x(void)
-{
-	u8 backupP4_0d;
-	u8 testsvhs_tempbl, testsvhs_tempbh;
-	u8 testsvhs_tempcl, testsvhs_tempch;
-	u8 testcvbs_tempbl, testcvbs_tempbh;
-	u8 testcvbs_tempcl, testcvbs_tempch;
-	u8 testvga2_tempbl, testvga2_tempbh;
-	u8 testvga2_tempcl, testvga2_tempch;
-	int myflag, result;
-
-	inXGIIDXREG(XGIPART4, 0x0d, backupP4_0d);
-	outXGIIDXREG(XGIPART4, 0x0d, (backupP4_0d | 0x04));
-
-	testvga2_tempbh = 0x00;
-	testvga2_tempbl = 0xd1;
-	testsvhs_tempbh = 0x00;
-	testsvhs_tempbl = 0xb9;
-	testcvbs_tempbh = 0x00;
-	testcvbs_tempbl = 0xb3;
-	if ((XGIhw_ext.ujVBChipID != VB_CHIP_301) && (XGIhw_ext.ujVBChipID
-			!= VB_CHIP_302)) {
-		testvga2_tempbh = 0x01;
-		testvga2_tempbl = 0x90;
-		testsvhs_tempbh = 0x01;
-		testsvhs_tempbl = 0x6b;
-		testcvbs_tempbh = 0x01;
-		testcvbs_tempbl = 0x74;
-		if (XGIhw_ext.ujVBChipID == VB_CHIP_301LV
-				|| XGIhw_ext.ujVBChipID == VB_CHIP_302LV) {
-			testvga2_tempbh = 0x00;
-			testvga2_tempbl = 0x00;
-			testsvhs_tempbh = 0x02;
-			testsvhs_tempbl = 0x00;
-			testcvbs_tempbh = 0x01;
-			testcvbs_tempbl = 0x00;
-		}
-	}
-	if (XGIhw_ext.ujVBChipID != VB_CHIP_301LV && XGIhw_ext.ujVBChipID
-			!= VB_CHIP_302LV) {
-		inXGIIDXREG(XGIPART4, 0x01, myflag);
-		if (myflag & 0x04) {
-			testvga2_tempbh = 0x00;
-			testvga2_tempbl = 0xfd;
-			testsvhs_tempbh = 0x00;
-			testsvhs_tempbl = 0xdd;
-			testcvbs_tempbh = 0x00;
-			testcvbs_tempbl = 0xee;
-		}
-	}
-	if ((XGIhw_ext.ujVBChipID == VB_CHIP_301LV) || (XGIhw_ext.ujVBChipID
-			== VB_CHIP_302LV)) {
-		testvga2_tempbh = 0x00;
-		testvga2_tempbl = 0x00;
-		testvga2_tempch = 0x00;
-		testvga2_tempcl = 0x00;
-		testsvhs_tempch = 0x04;
-		testsvhs_tempcl = 0x08;
-		testcvbs_tempch = 0x08;
-		testcvbs_tempcl = 0x08;
-	} else {
-		testvga2_tempch = 0x0e;
-		testvga2_tempcl = 0x08;
-		testsvhs_tempch = 0x06;
-		testsvhs_tempcl = 0x04;
-		testcvbs_tempch = 0x08;
-		testcvbs_tempcl = 0x04;
-	}
-
-	if (testvga2_tempch || testvga2_tempcl || testvga2_tempbh
-			|| testvga2_tempbl) {
-		result = XGIDoSense(testvga2_tempbl, testvga2_tempbh,
-				testvga2_tempcl, testvga2_tempch);
-		if (result) {
-			printk(KERN_INFO "XGIfb: Detected secondary VGA connection\n");
-			orXGIIDXREG(XGICR, 0x32, 0x10);
-		}
-	}
-
-	result = XGIDoSense(testsvhs_tempbl, testsvhs_tempbh, testsvhs_tempcl,
-			testsvhs_tempch);
-	if (result) {
-		printk(KERN_INFO "XGIfb: Detected TV connected to SVHS output\n");
-		/* TW: So we can be sure that there IS a SVHS output */
-		xgi_video_info.TV_plug = TVPLUG_SVIDEO;
-		orXGIIDXREG(XGICR, 0x32, 0x02);
-	}
-
-	if (!result) {
-		result = XGIDoSense(testcvbs_tempbl, testcvbs_tempbh,
-				testcvbs_tempcl, testcvbs_tempch);
-		if (result) {
-			printk(KERN_INFO "XGIfb: Detected TV connected to CVBS output\n");
-			/* TW: So we can be sure that there IS a CVBS output */
-			xgi_video_info.TV_plug = TVPLUG_COMPOSITE;
-			orXGIIDXREG(XGICR, 0x32, 0x01);
-		}
-	}
-	XGIDoSense(0, 0, 0, 0);
-
-	outXGIIDXREG(XGIPART4, 0x0d, backupP4_0d);
-}
-
-/* --------------------- SetMode routines ------------------------- */
-
-static void XGIfb_pre_setmode(void)
-{
-	u8 cr30 = 0, cr31 = 0;
-
-	inXGIIDXREG(XGICR, 0x31, cr31);
-	cr31 &= ~0x60;
-
-	switch (xgi_video_info.disp_state & DISPTYPE_DISP2) {
-	case DISPTYPE_CRT2:
-		cr30 = (XGI_VB_OUTPUT_CRT2 | XGI_SIMULTANEOUS_VIEW_ENABLE);
-		cr31 |= XGI_DRIVER_MODE;
-		break;
-	case DISPTYPE_LCD:
-		cr30 = (XGI_VB_OUTPUT_LCD | XGI_SIMULTANEOUS_VIEW_ENABLE);
-		cr31 |= XGI_DRIVER_MODE;
-		break;
-	case DISPTYPE_TV:
-		if (xgi_video_info.TV_type == TVMODE_HIVISION)
-			cr30 = (XGI_VB_OUTPUT_HIVISION
-					| XGI_SIMULTANEOUS_VIEW_ENABLE);
-		else if (xgi_video_info.TV_plug == TVPLUG_SVIDEO)
-			cr30 = (XGI_VB_OUTPUT_SVIDEO
-					| XGI_SIMULTANEOUS_VIEW_ENABLE);
-		else if (xgi_video_info.TV_plug == TVPLUG_COMPOSITE)
-			cr30 = (XGI_VB_OUTPUT_COMPOSITE
-					| XGI_SIMULTANEOUS_VIEW_ENABLE);
-		else if (xgi_video_info.TV_plug == TVPLUG_SCART)
-			cr30 = (XGI_VB_OUTPUT_SCART
-					| XGI_SIMULTANEOUS_VIEW_ENABLE);
-		cr31 |= XGI_DRIVER_MODE;
-
-		if (XGIfb_tvmode == 1 || xgi_video_info.TV_type == TVMODE_PAL)
-			cr31 |= 0x01;
-		else
-			cr31 &= ~0x01;
-		break;
-	default: /* disable CRT2 */
-		cr30 = 0x00;
-		cr31 |= (XGI_DRIVER_MODE | XGI_VB_OUTPUT_DISABLE);
-	}
-
-	outXGIIDXREG(XGICR, IND_XGI_SCRATCH_REG_CR30, cr30);
-	outXGIIDXREG(XGICR, IND_XGI_SCRATCH_REG_CR31, cr31);
-	outXGIIDXREG(XGICR, IND_XGI_SCRATCH_REG_CR33, (XGIfb_rate_idx & 0x0F));
-}
-
-static void XGIfb_post_setmode(void)
+static void XGIfb_get_VB_type(void)
 {
 	u8 reg;
-	unsigned char doit = 1;
-	/*
-	outXGIIDXREG(XGISR,IND_XGI_PASSWORD,XGI_PASSWORD);
-	outXGIIDXREG(XGICR, 0x13, 0x00);
-	setXGIIDXREG(XGISR,0x0E, 0xF0, 0x01);
-	*test*
-	*/
-	if (xgi_video_info.video_bpp == 8) {
-		/* TW: We can't switch off CRT1 on LVDS/Chrontel in 8bpp Modes */
-		if ((xgi_video_info.hasVB == HASVB_LVDS)
-				|| (xgi_video_info.hasVB == HASVB_LVDS_CHRONTEL)) {
-			doit = 0;
-		}
-		/* TW: We can't switch off CRT1 on 301B-DH in 8bpp Modes if using LCD */
-		if (xgi_video_info.disp_state & DISPTYPE_LCD)
-			doit = 0;
-	}
-
-	/* TW: We can't switch off CRT1 if bridge is in slave mode */
-	if (xgi_video_info.hasVB != HASVB_NONE) {
-		inXGIIDXREG(XGIPART1, 0x00, reg);
-
-		if ((reg & 0x50) == 0x10)
-			doit = 0;
-
-	} else {
-		XGIfb_crt1off = 0;
-	}
-
-	inXGIIDXREG(XGICR, 0x17, reg);
-	if ((XGIfb_crt1off) && (doit))
-		reg &= ~0x80;
-	else
-		reg |= 0x80;
-	outXGIIDXREG(XGICR, 0x17, reg);
-
-	andXGIIDXREG(XGISR, IND_XGI_RAMDAC_CONTROL, ~0x04);
-
-	if ((xgi_video_info.disp_state & DISPTYPE_TV) && (xgi_video_info.hasVB
-			== HASVB_301)) {
-
-		inXGIIDXREG(XGIPART4, 0x01, reg);
-
-		if (reg < 0xB0) { /* Set filter for XGI301 */
-
-			switch (xgi_video_info.video_width) {
-			case 320:
-				filter_tb = (xgi_video_info.TV_type == TVMODE_NTSC) ? 4 : 12;
-				break;
-			case 640:
-				filter_tb = (xgi_video_info.TV_type == TVMODE_NTSC) ? 5 : 13;
-				break;
-			case 720:
-				filter_tb = (xgi_video_info.TV_type == TVMODE_NTSC) ? 6 : 14;
-				break;
-			case 800:
-				filter_tb = (xgi_video_info.TV_type == TVMODE_NTSC) ? 7 : 15;
-				break;
-			default:
-				filter = -1;
-				break;
-			}
-
-			orXGIIDXREG(XGIPART1, XGIfb_CRT2_write_enable, 0x01);
-
-			if (xgi_video_info.TV_type == TVMODE_NTSC) {
-
-				andXGIIDXREG(XGIPART2, 0x3a, 0x1f);
-
-				if (xgi_video_info.TV_plug == TVPLUG_SVIDEO) {
-
-					andXGIIDXREG(XGIPART2, 0x30, 0xdf);
-
-				} else if (xgi_video_info.TV_plug
-						== TVPLUG_COMPOSITE) {
-
-					orXGIIDXREG(XGIPART2, 0x30, 0x20);
-
-					switch (xgi_video_info.video_width) {
-					case 640:
-						outXGIIDXREG(XGIPART2, 0x35, 0xEB);
-						outXGIIDXREG(XGIPART2, 0x36, 0x04);
-						outXGIIDXREG(XGIPART2, 0x37, 0x25);
-						outXGIIDXREG(XGIPART2, 0x38, 0x18);
-						break;
-					case 720:
-						outXGIIDXREG(XGIPART2, 0x35, 0xEE);
-						outXGIIDXREG(XGIPART2, 0x36, 0x0C);
-						outXGIIDXREG(XGIPART2, 0x37, 0x22);
-						outXGIIDXREG(XGIPART2, 0x38, 0x08);
-						break;
-					case 800:
-						outXGIIDXREG(XGIPART2, 0x35, 0xEB);
-						outXGIIDXREG(XGIPART2, 0x36, 0x15);
-						outXGIIDXREG(XGIPART2, 0x37, 0x25);
-						outXGIIDXREG(XGIPART2, 0x38, 0xF6);
-						break;
-					}
-				}
-
-			} else if (xgi_video_info.TV_type == TVMODE_PAL) {
-
-				andXGIIDXREG(XGIPART2, 0x3A, 0x1F);
-
-				if (xgi_video_info.TV_plug == TVPLUG_SVIDEO) {
-
-					andXGIIDXREG(XGIPART2, 0x30, 0xDF);
-
-				} else if (xgi_video_info.TV_plug
-						== TVPLUG_COMPOSITE) {
-
-					orXGIIDXREG(XGIPART2, 0x30, 0x20);
-
-					switch (xgi_video_info.video_width) {
-					case 640:
-						outXGIIDXREG(XGIPART2, 0x35, 0xF1);
-						outXGIIDXREG(XGIPART2, 0x36, 0xF7);
-						outXGIIDXREG(XGIPART2, 0x37, 0x1F);
-						outXGIIDXREG(XGIPART2, 0x38, 0x32);
-						break;
-					case 720:
-						outXGIIDXREG(XGIPART2, 0x35, 0xF3);
-						outXGIIDXREG(XGIPART2, 0x36, 0x00);
-						outXGIIDXREG(XGIPART2, 0x37, 0x1D);
-						outXGIIDXREG(XGIPART2, 0x38, 0x20);
-						break;
-					case 800:
-						outXGIIDXREG(XGIPART2, 0x35, 0xFC);
-						outXGIIDXREG(XGIPART2, 0x36, 0xFB);
-						outXGIIDXREG(XGIPART2, 0x37, 0x14);
-						outXGIIDXREG(XGIPART2, 0x38, 0x2A);
-						break;
-					}
-				}
-			}
-
-			if ((filter >= 0) && (filter <= 7)) {
-				DPRINTK("FilterTable[%d]-%d: %02x %02x %02x %02x\n", filter_tb, filter,
-						XGI_TV_filter[filter_tb].filter[filter][0],
-						XGI_TV_filter[filter_tb].filter[filter][1],
-						XGI_TV_filter[filter_tb].filter[filter][2],
-						XGI_TV_filter[filter_tb].filter[filter][3]
-				);
-				outXGIIDXREG(
-						XGIPART2,
-						0x35,
-						(XGI_TV_filter[filter_tb].filter[filter][0]));
-				outXGIIDXREG(
-						XGIPART2,
-						0x36,
-						(XGI_TV_filter[filter_tb].filter[filter][1]));
-				outXGIIDXREG(
-						XGIPART2,
-						0x37,
-						(XGI_TV_filter[filter_tb].filter[filter][2]));
-				outXGIIDXREG(
-						XGIPART2,
-						0x38,
-						(XGI_TV_filter[filter_tb].filter[filter][3]));
-			}
 
+	if (!XGIfb_has_VB()) {
+		reg = xgifb_reg_get(XGICR, IND_XGI_SCRATCH_REG_CR37);
+		switch ((reg & XGI_EXTERNAL_CHIP_MASK) >> 1) {
+		case XGI310_EXTERNAL_CHIP_LVDS:
+			xgi_video_info.hasVB = HASVB_LVDS;
+			break;
+		case XGI310_EXTERNAL_CHIP_LVDS_CHRONTEL:
+			xgi_video_info.hasVB = HASVB_LVDS_CHRONTEL;
+			break;
+		default:
+			break;
 		}
-
 	}
-
 }
 
 XGIINITSTATIC int __init XGIfb_setup(char *options)
@@ -2086,15 +1969,19 @@
 		if (!strncmp(this_opt, "mode:", 5)) {
 			XGIfb_search_mode(this_opt + 5);
 		} else if (!strncmp(this_opt, "vesa:", 5)) {
-			XGIfb_search_vesamode(simple_strtoul(this_opt + 5, NULL, 0));
+			XGIfb_search_vesamode(simple_strtoul(
+						this_opt + 5, NULL, 0));
 		} else if (!strncmp(this_opt, "mode:", 5)) {
 			XGIfb_search_mode(this_opt + 5);
 		} else if (!strncmp(this_opt, "vesa:", 5)) {
-			XGIfb_search_vesamode(simple_strtoul(this_opt + 5, NULL, 0));
+			XGIfb_search_vesamode(simple_strtoul(
+						this_opt + 5, NULL, 0));
 		} else if (!strncmp(this_opt, "vrate:", 6)) {
-			xgi_video_info.refresh_rate = simple_strtoul(this_opt + 6, NULL, 0);
+			xgi_video_info.refresh_rate = simple_strtoul(
+						this_opt + 6, NULL, 0);
 		} else if (!strncmp(this_opt, "rate:", 5)) {
-			xgi_video_info.refresh_rate = simple_strtoul(this_opt + 5, NULL, 0);
+			xgi_video_info.refresh_rate = simple_strtoul(
+						this_opt + 5, NULL, 0);
 		} else if (!strncmp(this_opt, "off", 3)) {
 			XGIfb_off = 1;
 		} else if (!strncmp(this_opt, "crt1off", 7)) {
@@ -2104,7 +1991,8 @@
 		} else if (!strncmp(this_opt, "forcecrt2type:", 14)) {
 			XGIfb_search_crt2type(this_opt + 14);
 		} else if (!strncmp(this_opt, "forcecrt1:", 10)) {
-			XGIfb_forcecrt1 = (int)simple_strtoul(this_opt + 10, NULL, 0);
+			XGIfb_forcecrt1 = (int)simple_strtoul(
+						this_opt + 10, NULL, 0);
 		} else if (!strncmp(this_opt, "tvmode:", 7)) {
 			XGIfb_search_tvstd(this_opt + 7);
 		} else if (!strncmp(this_opt, "tvstandard:", 11)) {
@@ -2122,12 +2010,15 @@
 		} else if (!strncmp(this_opt, "noypan", 6)) {
 			XGIfb_ypan = 0;
 		} else if (!strncmp(this_opt, "userom:", 7)) {
-			XGIfb_userom = (int)simple_strtoul(this_opt + 7, NULL, 0);
+			XGIfb_userom = (int)simple_strtoul(
+						this_opt + 7, NULL, 0);
 			/* } else if (!strncmp(this_opt, "useoem:", 7)) { */
-			/* XGIfb_useoem = (int)simple_strtoul(this_opt + 7, NULL, 0); */
+			/* XGIfb_useoem = (int)simple_strtoul(
+						this_opt + 7, NULL, 0); */
 		} else {
 			XGIfb_search_mode(this_opt);
-			/* printk(KERN_INFO "XGIfb: Invalid option %s\n", this_opt); */
+			/* printk(KERN_INFO "XGIfb: Invalid option %s\n",
+				  this_opt); */
 		}
 
 		/* TW: Panning only with acceleration */
@@ -2178,7 +2069,9 @@
 		return -ENOMEM;
 
 	xgi_video_info.chip_id = pdev->device;
-	pci_read_config_byte(pdev, PCI_REVISION_ID, &xgi_video_info.revision_id);
+	pci_read_config_byte(pdev,
+			     PCI_REVISION_ID,
+			     &xgi_video_info.revision_id);
 	XGIhw_ext.jChipRevision = xgi_video_info.revision_id;
 
 	xgi_video_info.pcibus = pdev->bus->number;
@@ -2194,7 +2087,7 @@
 	XGIhw_ext.pjIOAddress = (unsigned char *)xgi_video_info.vga_base;
 	/* XGI_Pr.RelIO  = ioremap(pci_resource_start(pdev, 2), 128) + 0x30; */
 	printk("XGIfb: Relocate IO address: %lx [%08lx]\n",
-			(unsigned long)pci_resource_start(pdev, 2), XGI_Pr.RelIO);
+	       (unsigned long)pci_resource_start(pdev, 2), XGI_Pr.RelIO);
 
 	if (pci_enable_device(pdev)) {
 		ret = -EIO;
@@ -2203,8 +2096,8 @@
 
 	XGIRegInit(&XGI_Pr, (unsigned long)XGIhw_ext.pjIOAddress);
 
-	outXGIIDXREG(XGISR, IND_XGI_PASSWORD, XGI_PASSWORD);
-	inXGIIDXREG(XGISR, IND_XGI_PASSWORD, reg1);
+	xgifb_reg_set(XGISR, IND_XGI_PASSWORD, XGI_PASSWORD);
+	reg1 = xgifb_reg_get(XGISR, IND_XGI_PASSWORD);
 
 	if (reg1 != 0xa1) { /*I/O error */
 		printk("\nXGIfb: I/O error!!!");
@@ -2214,8 +2107,8 @@
 
 	switch (xgi_video_info.chip_id) {
 	case PCI_DEVICE_ID_XG_20:
-		orXGIIDXREG(XGICR, Index_CR_GPIO_Reg3, GPIOG_EN);
-		inXGIIDXREG(XGICR, Index_CR_GPIO_Reg1, CR48);
+		xgifb_reg_or(XGICR, Index_CR_GPIO_Reg3, GPIOG_EN);
+		CR48 = xgifb_reg_get(XGICR, Index_CR_GPIO_Reg1);
 		if (CR48&GPIOG_READ)
 			xgi_video_info.chip = XG21;
 		else
@@ -2249,7 +2142,8 @@
 	if ((xgi_video_info.chip == XG21) || (XGIfb_userom)) {
 		XGIhw_ext.pjVirtualRomBase = xgifb_copy_rom(pdev);
 		if (XGIhw_ext.pjVirtualRomBase)
-			printk(KERN_INFO "XGIfb: Video ROM found and mapped to %p\n", XGIhw_ext.pjVirtualRomBase);
+			printk(KERN_INFO "XGIfb: Video ROM found and mapped to %p\n",
+			       XGIhw_ext.pjVirtualRomBase);
 		else
 			printk(KERN_INFO "XGIfb: Video ROM not found\n");
 	} else {
@@ -2264,17 +2158,23 @@
 		goto error;
 	}
 
-	if ((xgifb_mode_idx < 0) || ((XGIbios_mode[xgifb_mode_idx].mode_no) != 0xFF)) {
+	if ((xgifb_mode_idx < 0) ||
+	    ((XGIbios_mode[xgifb_mode_idx].mode_no) != 0xFF)) {
 		/* Enable PCI_LINEAR_ADDRESSING and MMIO_ENABLE  */
-		orXGIIDXREG(XGISR, IND_XGI_PCI_ADDRESS_SET, (XGI_PCI_ADDR_ENABLE | XGI_MEM_MAP_IO_ENABLE));
+		xgifb_reg_or(XGISR,
+			     IND_XGI_PCI_ADDRESS_SET,
+			     (XGI_PCI_ADDR_ENABLE | XGI_MEM_MAP_IO_ENABLE));
 		/* Enable 2D accelerator engine */
-		orXGIIDXREG(XGISR, IND_XGI_MODULE_ENABLE, XGI_ENABLE_2D);
+		xgifb_reg_or(XGISR, IND_XGI_MODULE_ENABLE, XGI_ENABLE_2D);
 	}
 
 	XGIhw_ext.ulVideoMemorySize = xgi_video_info.video_size;
 
-	if (!request_mem_region(xgi_video_info.video_base, xgi_video_info.video_size, "XGIfb FB")) {
-		printk("unable request memory size %x", xgi_video_info.video_size);
+	if (!request_mem_region(xgi_video_info.video_base,
+				xgi_video_info.video_size,
+				"XGIfb FB")) {
+		printk("unable request memory size %x",
+		       xgi_video_info.video_size);
 		printk(KERN_ERR "XGIfb: Fatal error: Unable to reserve frame buffer memory\n");
 		printk(KERN_ERR "XGIfb: Is there another framebuffer driver active?\n");
 		ret = -ENODEV;
@@ -2295,7 +2195,9 @@
 					    xgi_video_info.mmio_size);
 
 	printk(KERN_INFO "XGIfb: Framebuffer at 0x%lx, mapped to 0x%p, size %dk\n",
-			xgi_video_info.video_base, xgi_video_info.video_vbase, xgi_video_info.video_size / 1024);
+	       xgi_video_info.video_base,
+	       xgi_video_info.video_vbase,
+	       xgi_video_info.video_size / 1024);
 
 	printk(KERN_INFO "XGIfb: MMIO at 0x%lx, mapped to 0x%p, size %ldk\n",
 	       xgi_video_info.mmio_base, xgi_video_info.mmio_vbase,
@@ -2308,19 +2210,21 @@
 
 	xgi_video_info.mtrr = (unsigned int) 0;
 
-	if ((xgifb_mode_idx < 0) || ((XGIbios_mode[xgifb_mode_idx].mode_no) != 0xFF)) {
+	if ((xgifb_mode_idx < 0) ||
+	    ((XGIbios_mode[xgifb_mode_idx].mode_no) != 0xFF)) {
 		xgi_video_info.hasVB = HASVB_NONE;
-		if ((xgi_video_info.chip == XG20) || (xgi_video_info.chip == XG27)) {
+		if ((xgi_video_info.chip == XG20) ||
+		    (xgi_video_info.chip == XG27)) {
 			xgi_video_info.hasVB = HASVB_NONE;
 		} else if (xgi_video_info.chip == XG21) {
-			inXGIIDXREG(XGICR, 0x38, CR38);
+			CR38 = xgifb_reg_get(XGICR, 0x38);
 			if ((CR38&0xE0) == 0xC0) {
 				xgi_video_info.disp_state = DISPTYPE_LCD;
 				if (!XGIfb_GetXG21LVDSData()) {
 					int m;
 					for (m = 0; m < sizeof(XGI21_LCDCapList)/sizeof(struct XGI21_LVDSCapStruct); m++) {
 						if ((XGI21_LCDCapList[m].LVDSHDE == XGIbios_mode[xgifb_mode_idx].xres) &&
-								(XGI21_LCDCapList[m].LVDSVDE == XGIbios_mode[xgifb_mode_idx].yres)) {
+						    (XGI21_LCDCapList[m].LVDSVDE == XGIbios_mode[xgifb_mode_idx].yres)) {
 							xgifb_reg_set(XGI_Pr.P3d4, 0x36, m);
 						}
 					}
@@ -2340,7 +2244,7 @@
 
 		switch (xgi_video_info.hasVB) {
 		case HASVB_301:
-			inXGIIDXREG(XGIPART4, 0x01, reg);
+			reg = xgifb_reg_get(XGIPART4, 0x01);
 			if (reg >= 0xE0) {
 				XGIhw_ext.ujVBChipID = VB_CHIP_302LV;
 				printk(KERN_INFO "XGIfb: XGI302LV bridge detected (revision 0x%02x)\n", reg);
@@ -2350,7 +2254,7 @@
 			}
 			/* else if (reg >= 0xB0) {
 				XGIhw_ext.ujVBChipID = VB_CHIP_301B;
-				inXGIIDXREG(XGIPART4, 0x23, reg1);
+				reg1 = xgifb_reg_get(XGIPART4, 0x23);
 				printk("XGIfb: XGI301B bridge detected\n");
 			} */
 			else {
@@ -2359,7 +2263,7 @@
 			}
 			break;
 		case HASVB_302:
-			inXGIIDXREG(XGIPART4, 0x01, reg);
+			reg = xgifb_reg_get(XGIPART4, 0x01);
 			if (reg >= 0xE0) {
 				XGIhw_ext.ujVBChipID = VB_CHIP_302LV;
 				printk(KERN_INFO "XGIfb: XGI302LV bridge detected (revision 0x%02x)\n", reg);
@@ -2367,7 +2271,7 @@
 				XGIhw_ext.ujVBChipID = VB_CHIP_301LV;
 				printk(KERN_INFO "XGIfb: XGI302LV bridge detected (revision 0x%02x)\n", reg);
 			} else if (reg >= 0xB0) {
-				inXGIIDXREG(XGIPART4, 0x23, reg1);
+				reg1 = xgifb_reg_get(XGIPART4, 0x23);
 
 				XGIhw_ext.ujVBChipID = VB_CHIP_302B;
 
@@ -2404,14 +2308,16 @@
 			if (XGIfb_crt1off)
 				xgi_video_info.disp_state |= DISPMODE_SINGLE;
 			else
-				xgi_video_info.disp_state |= (DISPMODE_MIRROR | DISPTYPE_CRT1);
+				xgi_video_info.disp_state |= (DISPMODE_MIRROR |
+							      DISPTYPE_CRT1);
 		} else {
-			xgi_video_info.disp_state = DISPMODE_SINGLE | DISPTYPE_CRT1;
+			xgi_video_info.disp_state = DISPMODE_SINGLE |
+						    DISPTYPE_CRT1;
 		}
 
 		if (xgi_video_info.disp_state & DISPTYPE_LCD) {
 			if (!enable_dstn) {
-				inXGIIDXREG(XGICR, IND_XGI_LCD_PANEL, reg);
+				reg = xgifb_reg_get(XGICR, IND_XGI_LCD_PANEL);
 				reg &= 0x0f;
 				XGIhw_ext.ulCRT2LCDType = XGI310paneltype[reg];
 
@@ -2431,21 +2337,25 @@
 				(XGIhw_ext.ujVBChipID == VB_CHIP_301LV) ||
 				(XGIhw_ext.ujVBChipID == VB_CHIP_302LV)) {
 			int tmp;
-			inXGIIDXREG(XGICR, 0x34, tmp);
+			tmp = xgifb_reg_get(XGICR, 0x34);
 			if (tmp <= 0x13) {
-				/* Currently on LCDA? (Some BIOSes leave CR38) */
-				inXGIIDXREG(XGICR, 0x38, tmp);
+				/* Currently on LCDA?
+				 *(Some BIOSes leave CR38) */
+				tmp = xgifb_reg_get(XGICR, 0x38);
 				if ((tmp & 0x03) == 0x03) {
 					/* XGI_Pr.XGI_UseLCDA = 1; */
 				} else {
-					/* Currently on LCDA? (Some newer BIOSes set D0 in CR35) */
-					inXGIIDXREG(XGICR, 0x35, tmp);
+					/* Currently on LCDA?
+					 *(Some newer BIOSes set D0 in CR35) */
+					tmp = xgifb_reg_get(XGICR, 0x35);
 					if (tmp & 0x01) {
 						/* XGI_Pr.XGI_UseLCDA = 1; */
 					} else {
-						inXGIIDXREG(XGICR, 0x30, tmp);
+						tmp = xgifb_reg_get(XGICR,
+								    0x30);
 						if (tmp & 0x20) {
-							inXGIIDXREG(XGIPART1, 0x13, tmp);
+							tmp = xgifb_reg_get(
+								XGIPART1, 0x13);
 							if (tmp & 0x04) {
 								/* XGI_Pr.XGI_UseLCDA = 1; */
 							}
@@ -2464,7 +2374,8 @@
 			case DISPTYPE_LCD:
 				xgifb_mode_idx = DEFAULT_LCDMODE;
 				if (xgi_video_info.chip == XG21)
-					xgifb_mode_idx = XGIfb_GetXG21DefaultLVDSModeIdx();
+					xgifb_mode_idx =
+					    XGIfb_GetXG21DefaultLVDSModeIdx();
 				break;
 			case DISPTYPE_TV:
 				xgifb_mode_idx = DEFAULT_TVMODE;
@@ -2477,18 +2388,26 @@
 
 		XGIfb_mode_no = XGIbios_mode[xgifb_mode_idx].mode_no;
 
+		/* yilin set default refresh rate */
 		if (xgi_video_info.refresh_rate == 0)
-			xgi_video_info.refresh_rate = 60; /* yilin set default refresh rate */
-		if (XGIfb_search_refresh_rate(xgi_video_info.refresh_rate) == 0) {
+			xgi_video_info.refresh_rate = 60;
+		if (XGIfb_search_refresh_rate(
+				xgi_video_info.refresh_rate) == 0) {
 			XGIfb_rate_idx = XGIbios_mode[xgifb_mode_idx].rate_idx;
 			xgi_video_info.refresh_rate = 60;
 		}
 
 		xgi_video_info.video_bpp = XGIbios_mode[xgifb_mode_idx].bpp;
-		xgi_video_info.video_vwidth = xgi_video_info.video_width = XGIbios_mode[xgifb_mode_idx].xres;
-		xgi_video_info.video_vheight = xgi_video_info.video_height = XGIbios_mode[xgifb_mode_idx].yres;
+		xgi_video_info.video_vwidth =
+			xgi_video_info.video_width =
+				XGIbios_mode[xgifb_mode_idx].xres;
+		xgi_video_info.video_vheight =
+			xgi_video_info.video_height =
+				XGIbios_mode[xgifb_mode_idx].yres;
 		xgi_video_info.org_x = xgi_video_info.org_y = 0;
-		xgi_video_info.video_linelength = xgi_video_info.video_width * (xgi_video_info.video_bpp >> 3);
+		xgi_video_info.video_linelength =
+			xgi_video_info.video_width *
+			(xgi_video_info.video_bpp >> 3);
 		switch (xgi_video_info.video_bpp) {
 		case 8:
 			xgi_video_info.DstColor = 0x0000;
@@ -2507,16 +2426,23 @@
 			break;
 		default:
 			xgi_video_info.video_cmap_len = 16;
-			printk(KERN_INFO "XGIfb: Unsupported depth %d", xgi_video_info.video_bpp);
+			printk(KERN_INFO "XGIfb: Unsupported depth %d",
+			       xgi_video_info.video_bpp);
 			break;
 		}
 
 		printk(KERN_INFO "XGIfb: Default mode is %dx%dx%d (%dHz)\n",
-				xgi_video_info.video_width, xgi_video_info.video_height, xgi_video_info.video_bpp,
-				xgi_video_info.refresh_rate);
+		       xgi_video_info.video_width,
+		       xgi_video_info.video_height,
+		       xgi_video_info.video_bpp,
+		       xgi_video_info.refresh_rate);
 
-		default_var.xres = default_var.xres_virtual = xgi_video_info.video_width;
-		default_var.yres = default_var.yres_virtual = xgi_video_info.video_height;
+		default_var.xres =
+			default_var.xres_virtual =
+				xgi_video_info.video_width;
+		default_var.yres =
+			default_var.yres_virtual =
+				xgi_video_info.video_height;
 		default_var.bits_per_pixel = xgi_video_info.video_bpp;
 
 		XGIfb_bpp_to_var(&default_var);
@@ -2532,10 +2458,12 @@
 			&default_var.hsync_len, &default_var.vsync_len,
 			&default_var.sync, &default_var.vmode)) {
 
-			if ((default_var.vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) {
+			if ((default_var.vmode & FB_VMODE_MASK) ==
+			    FB_VMODE_INTERLACED) {
 				default_var.yres <<= 1;
 				default_var.yres_virtual <<= 1;
-			} else if ((default_var.vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE) {
+			} else if ((default_var.vmode & FB_VMODE_MASK) ==
+				   FB_VMODE_DOUBLE) {
 				default_var.pixclock >>= 1;
 				default_var.yres >>= 1;
 				default_var.yres_virtual >>= 1;
@@ -2555,9 +2483,10 @@
 		fb_alloc_cmap(&fb_info->cmap, 256 , 0);
 
 #ifdef CONFIG_MTRR
-		xgi_video_info.mtrr = mtrr_add((unsigned int) xgi_video_info.video_base,
-				(unsigned int) xgi_video_info.video_size,
-				MTRR_TYPE_WRCOMB, 1);
+		xgi_video_info.mtrr = mtrr_add(
+			(unsigned int) xgi_video_info.video_base,
+			(unsigned int) xgi_video_info.video_size,
+			MTRR_TYPE_WRCOMB, 1);
 		if (xgi_video_info.mtrr)
 			printk(KERN_INFO "XGIfb: Added MTRRs\n");
 #endif
@@ -2570,7 +2499,7 @@
 		XGIfb_registered = 1;
 
 		printk(KERN_INFO "fb%d: %s frame buffer device, Version %d.%d.%02d\n",
-				fb_info->node, myid, VER_MAJOR, VER_MINOR, VER_LEVEL);
+		       fb_info->node, myid, VER_MAJOR, VER_MINOR, VER_LEVEL);
 
 	}
 
diff -druN linux-2.6.39-libre/drivers/staging/xgifb/XGI_main.h linux-3.0-rc7-libre/drivers/staging/xgifb/XGI_main.h
--- linux-2.6.39-libre/drivers/staging/xgifb/XGI_main.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/xgifb/XGI_main.h	2011-07-11 19:51:52.000000000 -0400
@@ -9,7 +9,7 @@
 #include "vb_struct.h"
 #include "vb_def.h"
 
-#define XGIFAIL(x) do { printk(x "\n"); return -EINVAL; } while(0)
+#define XGIFAIL(x) do { printk(x "\n"); return -EINVAL; } while (0)
 
 #define VER_MAJOR                 0
 #define VER_MINOR                 8
@@ -44,11 +44,15 @@
 #define XGIINITSTATIC static
 
 static DEFINE_PCI_DEVICE_TABLE(xgifb_pci_table) = {
-	{ PCI_VENDOR_ID_XG, PCI_DEVICE_ID_XG_20, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
-	{ PCI_VENDOR_ID_XG, PCI_DEVICE_ID_XG_27, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1},
-	{ PCI_VENDOR_ID_XG, PCI_DEVICE_ID_XG_40, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 2},
-	{ PCI_VENDOR_ID_XG, PCI_DEVICE_ID_XG_42, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 3},
-	{ 0 }
+	{PCI_VENDOR_ID_XG, PCI_DEVICE_ID_XG_20, PCI_ANY_ID, PCI_ANY_ID,
+	 0, 0, 0},
+	{PCI_VENDOR_ID_XG, PCI_DEVICE_ID_XG_27, PCI_ANY_ID, PCI_ANY_ID,
+	 0, 0, 1},
+	{PCI_VENDOR_ID_XG, PCI_DEVICE_ID_XG_40, PCI_ANY_ID, PCI_ANY_ID,
+	 0, 0, 2},
+	{PCI_VENDOR_ID_XG, PCI_DEVICE_ID_XG_42, PCI_ANY_ID, PCI_ANY_ID,
+	 0, 0, 3},
+	{0}
 };
 
 MODULE_DEVICE_TABLE(pci, xgifb_pci_table);
@@ -148,10 +152,10 @@
 #define XGI_DATA_BUS_64        0x00
 #define XGI_DATA_BUS_128       0x01
 #define XGI_DUAL_CHANNEL_MASK  0x0C
-#define XGI_SINGLE_CHANNEL_1_RANK  	0x0
-#define XGI_SINGLE_CHANNEL_2_RANK  	0x1
-#define XGI_ASYM_DDR		  	0x02
-#define XGI_DUAL_CHANNEL_1_RANK    	0x3
+#define XGI_SINGLE_CHANNEL_1_RANK 0x0
+#define XGI_SINGLE_CHANNEL_2_RANK 0x1
+#define XGI_ASYM_DDR		  0x02
+#define XGI_DUAL_CHANNEL_1_RANK	  0x3
 
 #define XGI550_DRAM_SIZE_MASK     0x3F  /* 550/650/740 SR14 */
 #define XGI550_DRAM_SIZE_4MB      0x00
@@ -190,11 +194,11 @@
 #define XGI_VB_CRT2               0x10
 #define XGI_CRT1                  0x20
 #define XGI_VB_HIVISION           0x40
-#define XGI_VB_YPBPR                0x80
-#define XGI_VB_TV                 (XGI_VB_COMPOSITE | XGI_VB_SVIDEO | \
-                                   XGI_VB_SCART | XGI_VB_HIVISION|XGI_VB_YPBPR)
+#define XGI_VB_YPBPR              0x80
+#define XGI_VB_TV		  (XGI_VB_COMPOSITE | XGI_VB_SVIDEO | \
+				   XGI_VB_SCART | XGI_VB_HIVISION|XGI_VB_YPBPR)
 
-#define XGI_EXTERNAL_CHIP_MASK    	   0x0E  /* CR37 */
+#define XGI_EXTERNAL_CHIP_MASK		   0x0E  /* CR37 */
 #define XGI_EXTERNAL_CHIP_XGI301           0x01  /* in CR37 << 1 ! */
 #define XGI_EXTERNAL_CHIP_LVDS             0x02  /* in CR37 << 1 ! */
 #define XGI_EXTERNAL_CHIP_TRUMPION         0x03  /* in CR37 << 1 ! */
@@ -216,46 +220,10 @@
 #define SR_BUFFER_SIZE            5
 #define CR_BUFFER_SIZE            5
 
-/* Useful macros */
-#define inXGIREG(base)          inb(base)
-#define outXGIREG(base,val)     outb(val,base)
-#define orXGIREG(base,val)      do { \
-                                  unsigned char __Temp = inb(base); \
-                                  outXGIREG(base, __Temp | (val)); \
-                                } while (0)
-#define andXGIREG(base,val)     do { \
-                                  unsigned char __Temp = inb(base); \
-                                  outXGIREG(base, __Temp & (val)); \
-                                } while (0)
-#define inXGIIDXREG(base,idx,var)   do { \
-                                      outb(idx,base); var=inb((base)+1); \
-                                    } while (0)
-#define outXGIIDXREG(base,idx,val)  do { \
-                                      outb(idx,base); outb((val),(base)+1); \
-                                    } while (0)
-#define orXGIIDXREG(base,idx,val)   do { \
-                                      unsigned char __Temp; \
-                                      outb(idx,base);   \
-                                      __Temp = inb((base)+1)|(val); \
-                                      outXGIIDXREG(base,idx,__Temp); \
-                                    } while (0)
-#define andXGIIDXREG(base,idx,and)  do { \
-                                      unsigned char __Temp; \
-                                      outb(idx,base);   \
-                                      __Temp = inb((base)+1)&(and); \
-                                      outXGIIDXREG(base,idx,__Temp); \
-                                    } while (0)
-#define setXGIIDXREG(base,idx,and,or)   do { \
-                                          unsigned char __Temp; \
-                                          outb(idx,base);   \
-                                          __Temp = (inb((base)+1)&(and))|(or); \
-                                          outXGIIDXREG(base,idx,__Temp); \
-                                        } while (0)
-
 /* ------------------- Global Variables ----------------------------- */
 
 /* Fbcon variables */
-static struct fb_info* fb_info;
+static struct fb_info *fb_info;
 
 
 static int    video_type = FB_TYPE_PACKED_PIXELS;
@@ -304,7 +272,7 @@
 static int XGIfb_crt1off = 0;
 static int XGIfb_forcecrt1 = -1;
 static int XGIfb_userom = 0;
-//static int XGIfb_useoem = -1;
+/*static int XGIfb_useoem = -1; */
 
 /* global flags */
 static int XGIfb_registered;
@@ -316,8 +284,10 @@
 
 static int XGIfb_CRT2_write_enable = 0;
 
-static int XGIfb_crt2type = -1; /* TW: CRT2 type (for overriding autodetection) */
-static int XGIfb_tvplug = -1; /* PR: Tv plug type (for overriding autodetection) */
+/* TW: CRT2 type (for overriding autodetection) */
+static int XGIfb_crt2type = -1;
+/* PR: Tv plug type (for overriding autodetection) */
+static int XGIfb_tvplug = -1;
 
 static unsigned char XGIfb_detectedpdc = 0;
 
@@ -354,82 +324,155 @@
 	u8  chipset;
 } XGIbios_mode[] = {
 #define MODE_INDEX_NONE           0  /* TW: index for mode=none */
-	{"none",         0xFF, 0x0000, 0x0000,    0,    0,  0, 0,   0,  0, MD_XGI300|MD_XGI315},  /* TW: for mode "none" */
-	{"320x240x16",   0x56, 0x0000, 0x0000,  320,  240, 16, 1,  40, 15,           MD_XGI315},
-	{"320x480x8",    0x5A, 0x0000, 0x0000,  320,  480,  8, 1,  40, 30,           MD_XGI315},  /* TW: FSTN */
-	{"320x480x16",   0x5B, 0x0000, 0x0000,  320,  480, 16, 1,  40, 30,           MD_XGI315},  /* TW: FSTN */
-	{"640x480x8",    0x2E, 0x0101, 0x0101,  640,  480,  8, 1,  80, 30, MD_XGI300|MD_XGI315},
-	{"640x480x16",   0x44, 0x0111, 0x0111,  640,  480, 16, 1,  80, 30, MD_XGI300|MD_XGI315},
-	{"640x480x24",   0x62, 0x013a, 0x0112,  640,  480, 32, 1,  80, 30, MD_XGI300|MD_XGI315},  /* TW: That's for people who mix up color- and fb depth */
-	{"640x480x32",   0x62, 0x013a, 0x0112,  640,  480, 32, 1,  80, 30, MD_XGI300|MD_XGI315},
-	{"720x480x8",    0x31, 0x0000, 0x0000,  720,  480,  8, 1,  90, 30, MD_XGI300|MD_XGI315},
-	{"720x480x16",   0x33, 0x0000, 0x0000,  720,  480, 16, 1,  90, 30, MD_XGI300|MD_XGI315},
-	{"720x480x24",   0x35, 0x0000, 0x0000,  720,  480, 32, 1,  90, 30, MD_XGI300|MD_XGI315},
-	{"720x480x32",   0x35, 0x0000, 0x0000,  720,  480, 32, 1,  90, 30, MD_XGI300|MD_XGI315},
-	{"720x576x8",    0x32, 0x0000, 0x0000,  720,  576,  8, 1,  90, 36, MD_XGI300|MD_XGI315},
-	{"720x576x16",   0x34, 0x0000, 0x0000,  720,  576, 16, 1,  90, 36, MD_XGI300|MD_XGI315},
-	{"720x576x24",   0x36, 0x0000, 0x0000,  720,  576, 32, 1,  90, 36, MD_XGI300|MD_XGI315},
-	{"720x576x32",   0x36, 0x0000, 0x0000,  720,  576, 32, 1,  90, 36, MD_XGI300|MD_XGI315},
-	{"800x480x8",    0x70, 0x0000, 0x0000,  800,  480,  8, 1, 100, 30, MD_XGI300|MD_XGI315},
-	{"800x480x16",   0x7a, 0x0000, 0x0000,  800,  480, 16, 1, 100, 30, MD_XGI300|MD_XGI315},
-	{"800x480x24",   0x76, 0x0000, 0x0000,  800,  480, 32, 1, 100, 30, MD_XGI300|MD_XGI315},
-	{"800x480x32",   0x76, 0x0000, 0x0000,  800,  480, 32, 1, 100, 30, MD_XGI300|MD_XGI315},
+	{"none",         0xFF, 0x0000, 0x0000,    0,    0,  0, 0,   0,  0,
+	 MD_XGI300|MD_XGI315},  /* TW: for mode "none" */
+	{"320x240x16",   0x56, 0x0000, 0x0000,  320,  240, 16, 1,  40, 15,
+	 MD_XGI315},
+	{"320x480x8",    0x5A, 0x0000, 0x0000,  320,  480,  8, 1,  40, 30,
+	 MD_XGI315},  /* TW: FSTN */
+	{"320x480x16",   0x5B, 0x0000, 0x0000,  320,  480, 16, 1,  40, 30,
+	 MD_XGI315},  /* TW: FSTN */
+	{"640x480x8",    0x2E, 0x0101, 0x0101,  640,  480,  8, 1,  80, 30,
+	 MD_XGI300|MD_XGI315},
+	{"640x480x16",   0x44, 0x0111, 0x0111,  640,  480, 16, 1,  80, 30,
+	 MD_XGI300|MD_XGI315},
+	{"640x480x24",   0x62, 0x013a, 0x0112,  640,  480, 32, 1,  80, 30,
+	 MD_XGI300|MD_XGI315},  /* TW: That's for people who mix up color-
+					and fb depth */
+	{"640x480x32",   0x62, 0x013a, 0x0112,  640,  480, 32, 1,  80, 30,
+	 MD_XGI300|MD_XGI315},
+	{"720x480x8",    0x31, 0x0000, 0x0000,  720,  480,  8, 1,  90, 30,
+	 MD_XGI300|MD_XGI315},
+	{"720x480x16",   0x33, 0x0000, 0x0000,  720,  480, 16, 1,  90, 30,
+	 MD_XGI300|MD_XGI315},
+	{"720x480x24",   0x35, 0x0000, 0x0000,  720,  480, 32, 1,  90, 30,
+	 MD_XGI300|MD_XGI315},
+	{"720x480x32",   0x35, 0x0000, 0x0000,  720,  480, 32, 1,  90, 30,
+	 MD_XGI300|MD_XGI315},
+	{"720x576x8",    0x32, 0x0000, 0x0000,  720,  576,  8, 1,  90, 36,
+	 MD_XGI300|MD_XGI315},
+	{"720x576x16",   0x34, 0x0000, 0x0000,  720,  576, 16, 1,  90, 36,
+	 MD_XGI300|MD_XGI315},
+	{"720x576x24",   0x36, 0x0000, 0x0000,  720,  576, 32, 1,  90, 36,
+	 MD_XGI300|MD_XGI315},
+	{"720x576x32",   0x36, 0x0000, 0x0000,  720,  576, 32, 1,  90, 36,
+	 MD_XGI300|MD_XGI315},
+	{"800x480x8",    0x70, 0x0000, 0x0000,  800,  480,  8, 1, 100, 30,
+	 MD_XGI300|MD_XGI315},
+	{"800x480x16",   0x7a, 0x0000, 0x0000,  800,  480, 16, 1, 100, 30,
+	 MD_XGI300|MD_XGI315},
+	{"800x480x24",   0x76, 0x0000, 0x0000,  800,  480, 32, 1, 100, 30,
+	 MD_XGI300|MD_XGI315},
+	{"800x480x32",   0x76, 0x0000, 0x0000,  800,  480, 32, 1, 100, 30,
+	 MD_XGI300|MD_XGI315},
 #define DEFAULT_MODE              21 /* TW: index for 800x600x8 */
 #define DEFAULT_LCDMODE           21 /* TW: index for 800x600x8 */
 #define DEFAULT_TVMODE            21 /* TW: index for 800x600x8 */
-	{"800x600x8",    0x30, 0x0103, 0x0103,  800,  600,  8, 1, 100, 37, MD_XGI300|MD_XGI315},
-	{"800x600x16",   0x47, 0x0114, 0x0114,  800,  600, 16, 1, 100, 37, MD_XGI300|MD_XGI315},
-	{"800x600x24",   0x63, 0x013b, 0x0115,  800,  600, 32, 1, 100, 37, MD_XGI300|MD_XGI315},
-	{"800x600x32",   0x63, 0x013b, 0x0115,  800,  600, 32, 1, 100, 37, MD_XGI300|MD_XGI315},
-	{"1024x576x8",   0x71, 0x0000, 0x0000, 1024,  576,  8, 1, 128, 36, MD_XGI300|MD_XGI315},
-	{"1024x576x16",  0x74, 0x0000, 0x0000, 1024,  576, 16, 1, 128, 36, MD_XGI300|MD_XGI315},
-	{"1024x576x24",  0x77, 0x0000, 0x0000, 1024,  576, 32, 1, 128, 36, MD_XGI300|MD_XGI315},
-	{"1024x576x32",  0x77, 0x0000, 0x0000, 1024,  576, 32, 1, 128, 36, MD_XGI300|MD_XGI315},
-	{"1024x600x8",   0x20, 0x0000, 0x0000, 1024,  600,  8, 1, 128, 37, MD_XGI300          },  /* TW: 300 series only */
-	{"1024x600x16",  0x21, 0x0000, 0x0000, 1024,  600, 16, 1, 128, 37, MD_XGI300          },
-	{"1024x600x24",  0x22, 0x0000, 0x0000, 1024,  600, 32, 1, 128, 37, MD_XGI300          },
-	{"1024x600x32",  0x22, 0x0000, 0x0000, 1024,  600, 32, 1, 128, 37, MD_XGI300          },
-	{"1024x768x8",   0x38, 0x0105, 0x0105, 1024,  768,  8, 1, 128, 48, MD_XGI300|MD_XGI315},
-	{"1024x768x16",  0x4A, 0x0117, 0x0117, 1024,  768, 16, 1, 128, 48, MD_XGI300|MD_XGI315},
-	{"1024x768x24",  0x64, 0x013c, 0x0118, 1024,  768, 32, 1, 128, 48, MD_XGI300|MD_XGI315},
-	{"1024x768x32",  0x64, 0x013c, 0x0118, 1024,  768, 32, 1, 128, 48, MD_XGI300|MD_XGI315},
-	{"1152x768x8",   0x23, 0x0000, 0x0000, 1152,  768,  8, 1, 144, 48, MD_XGI300          },  /* TW: 300 series only */
-	{"1152x768x16",  0x24, 0x0000, 0x0000, 1152,  768, 16, 1, 144, 48, MD_XGI300          },
-	{"1152x768x24",  0x25, 0x0000, 0x0000, 1152,  768, 32, 1, 144, 48, MD_XGI300          },
-	{"1152x768x32",  0x25, 0x0000, 0x0000, 1152,  768, 32, 1, 144, 48, MD_XGI300          },
-	{"1280x720x8",   0x79, 0x0000, 0x0000, 1280,  720,  8, 1, 160, 45, MD_XGI300|MD_XGI315},
-	{"1280x720x16",  0x75, 0x0000, 0x0000, 1280,  720, 16, 1, 160, 45, MD_XGI300|MD_XGI315},
-	{"1280x720x24",  0x78, 0x0000, 0x0000, 1280,  720, 32, 1, 160, 45, MD_XGI300|MD_XGI315},
-	{"1280x720x32",  0x78, 0x0000, 0x0000, 1280,  720, 32, 1, 160, 45, MD_XGI300|MD_XGI315},
-	{"1280x768x8",   0x23, 0x0000, 0x0000, 1280,  768,  8, 1, 160, 48,           MD_XGI315},  /* TW: 310/325 series only */
-	{"1280x768x16",  0x24, 0x0000, 0x0000, 1280,  768, 16, 1, 160, 48,           MD_XGI315},
-	{"1280x768x24",  0x25, 0x0000, 0x0000, 1280,  768, 32, 1, 160, 48,           MD_XGI315},
-	{"1280x768x32",  0x25, 0x0000, 0x0000, 1280,  768, 32, 1, 160, 48,           MD_XGI315},
+	{"800x600x8",    0x30, 0x0103, 0x0103,  800,  600,  8, 1, 100, 37,
+	 MD_XGI300|MD_XGI315},
+	{"800x600x16",   0x47, 0x0114, 0x0114,  800,  600, 16, 1, 100, 37,
+	 MD_XGI300|MD_XGI315},
+	{"800x600x24",   0x63, 0x013b, 0x0115,  800,  600, 32, 1, 100, 37,
+	 MD_XGI300|MD_XGI315},
+	{"800x600x32",   0x63, 0x013b, 0x0115,  800,  600, 32, 1, 100, 37,
+	 MD_XGI300|MD_XGI315},
+	{"1024x576x8",   0x71, 0x0000, 0x0000, 1024,  576,  8, 1, 128, 36,
+	 MD_XGI300|MD_XGI315},
+	{"1024x576x16",  0x74, 0x0000, 0x0000, 1024,  576, 16, 1, 128, 36,
+	 MD_XGI300|MD_XGI315},
+	{"1024x576x24",  0x77, 0x0000, 0x0000, 1024,  576, 32, 1, 128, 36,
+	 MD_XGI300|MD_XGI315},
+	{"1024x576x32",  0x77, 0x0000, 0x0000, 1024,  576, 32, 1, 128, 36,
+	 MD_XGI300|MD_XGI315},
+	{"1024x600x8",   0x20, 0x0000, 0x0000, 1024,  600,  8, 1, 128, 37,
+	 MD_XGI300          },  /* TW: 300 series only */
+	{"1024x600x16",  0x21, 0x0000, 0x0000, 1024,  600, 16, 1, 128, 37,
+	 MD_XGI300          },
+	{"1024x600x24",  0x22, 0x0000, 0x0000, 1024,  600, 32, 1, 128, 37,
+	 MD_XGI300          },
+	{"1024x600x32",  0x22, 0x0000, 0x0000, 1024,  600, 32, 1, 128, 37,
+	 MD_XGI300          },
+	{"1024x768x8",   0x38, 0x0105, 0x0105, 1024,  768,  8, 1, 128, 48,
+	 MD_XGI300|MD_XGI315},
+	{"1024x768x16",  0x4A, 0x0117, 0x0117, 1024,  768, 16, 1, 128, 48,
+	 MD_XGI300|MD_XGI315},
+	{"1024x768x24",  0x64, 0x013c, 0x0118, 1024,  768, 32, 1, 128, 48,
+	 MD_XGI300|MD_XGI315},
+	{"1024x768x32",  0x64, 0x013c, 0x0118, 1024,  768, 32, 1, 128, 48,
+	 MD_XGI300|MD_XGI315},
+	{"1152x768x8",   0x23, 0x0000, 0x0000, 1152,  768,  8, 1, 144, 48,
+	 MD_XGI300          },  /* TW: 300 series only */
+	{"1152x768x16",  0x24, 0x0000, 0x0000, 1152,  768, 16, 1, 144, 48,
+	 MD_XGI300          },
+	{"1152x768x24",  0x25, 0x0000, 0x0000, 1152,  768, 32, 1, 144, 48,
+	 MD_XGI300          },
+	{"1152x768x32",  0x25, 0x0000, 0x0000, 1152,  768, 32, 1, 144, 48,
+	 MD_XGI300          },
+	{"1280x720x8",   0x79, 0x0000, 0x0000, 1280,  720,  8, 1, 160, 45,
+	 MD_XGI300|MD_XGI315},
+	{"1280x720x16",  0x75, 0x0000, 0x0000, 1280,  720, 16, 1, 160, 45,
+	 MD_XGI300|MD_XGI315},
+	{"1280x720x24",  0x78, 0x0000, 0x0000, 1280,  720, 32, 1, 160, 45,
+	 MD_XGI300|MD_XGI315},
+	{"1280x720x32",  0x78, 0x0000, 0x0000, 1280,  720, 32, 1, 160, 45,
+	 MD_XGI300|MD_XGI315},
+	{"1280x768x8",   0x23, 0x0000, 0x0000, 1280,  768,  8, 1, 160, 48,
+	 MD_XGI315},  /* TW: 310/325 series only */
+	{"1280x768x16",  0x24, 0x0000, 0x0000, 1280,  768, 16, 1, 160, 48,
+	 MD_XGI315},
+	{"1280x768x24",  0x25, 0x0000, 0x0000, 1280,  768, 32, 1, 160, 48,
+	 MD_XGI315},
+	{"1280x768x32",  0x25, 0x0000, 0x0000, 1280,  768, 32, 1, 160, 48,
+	 MD_XGI315},
 #define MODEINDEX_1280x960 48
-	{"1280x960x8",   0x7C, 0x0000, 0x0000, 1280,  960,  8, 1, 160, 60, MD_XGI300|MD_XGI315},  /* TW: Modenumbers being patched */
-	{"1280x960x16",  0x7D, 0x0000, 0x0000, 1280,  960, 16, 1, 160, 60, MD_XGI300|MD_XGI315},
-	{"1280x960x24",  0x7E, 0x0000, 0x0000, 1280,  960, 32, 1, 160, 60, MD_XGI300|MD_XGI315},
-	{"1280x960x32",  0x7E, 0x0000, 0x0000, 1280,  960, 32, 1, 160, 60, MD_XGI300|MD_XGI315},
-	{"1280x1024x8",  0x3A, 0x0107, 0x0107, 1280, 1024,  8, 1, 160, 64, MD_XGI300|MD_XGI315},
-	{"1280x1024x16", 0x4D, 0x011a, 0x011a, 1280, 1024, 16, 1, 160, 64, MD_XGI300|MD_XGI315},
-	{"1280x1024x24", 0x65, 0x013d, 0x011b, 1280, 1024, 32, 1, 160, 64, MD_XGI300|MD_XGI315},
-	{"1280x1024x32", 0x65, 0x013d, 0x011b, 1280, 1024, 32, 1, 160, 64, MD_XGI300|MD_XGI315},
-	{"1400x1050x8",  0x26, 0x0000, 0x0000, 1400, 1050,  8, 1, 175, 65,           MD_XGI315},  /* TW: 310/325 series only */
-	{"1400x1050x16", 0x27, 0x0000, 0x0000, 1400, 1050, 16, 1, 175, 65,           MD_XGI315},
-	{"1400x1050x24", 0x28, 0x0000, 0x0000, 1400, 1050, 32, 1, 175, 65,           MD_XGI315},
-	{"1400x1050x32", 0x28, 0x0000, 0x0000, 1400, 1050, 32, 1, 175, 65,           MD_XGI315},
-	{"1600x1200x8",  0x3C, 0x0130, 0x011c, 1600, 1200,  8, 1, 200, 75, MD_XGI300|MD_XGI315},
-	{"1600x1200x16", 0x3D, 0x0131, 0x011e, 1600, 1200, 16, 1, 200, 75, MD_XGI300|MD_XGI315},
-	{"1600x1200x24", 0x66, 0x013e, 0x011f, 1600, 1200, 32, 1, 200, 75, MD_XGI300|MD_XGI315},
-	{"1600x1200x32", 0x66, 0x013e, 0x011f, 1600, 1200, 32, 1, 200, 75, MD_XGI300|MD_XGI315},
-	{"1920x1440x8",  0x68, 0x013f, 0x0000, 1920, 1440,  8, 1, 240, 75, MD_XGI300|MD_XGI315},
-	{"1920x1440x16", 0x69, 0x0140, 0x0000, 1920, 1440, 16, 1, 240, 75, MD_XGI300|MD_XGI315},
-	{"1920x1440x24", 0x6B, 0x0141, 0x0000, 1920, 1440, 32, 1, 240, 75, MD_XGI300|MD_XGI315},
-	{"1920x1440x32", 0x6B, 0x0141, 0x0000, 1920, 1440, 32, 1, 240, 75, MD_XGI300|MD_XGI315},
-	{"2048x1536x8",  0x6c, 0x0000, 0x0000, 2048, 1536,  8, 1, 256, 96,           MD_XGI315},  /* TW: 310/325 series only */
-	{"2048x1536x16", 0x6d, 0x0000, 0x0000, 2048, 1536, 16, 1, 256, 96,           MD_XGI315},
-	{"2048x1536x24", 0x6e, 0x0000, 0x0000, 2048, 1536, 32, 1, 256, 96,           MD_XGI315},
-	{"2048x1536x32", 0x6e, 0x0000, 0x0000, 2048, 1536, 32, 1, 256, 96,           MD_XGI315},
+	{"1280x960x8",   0x7C, 0x0000, 0x0000, 1280,  960,  8, 1, 160, 60,
+	 MD_XGI300|MD_XGI315},  /* TW: Modenumbers being patched */
+	{"1280x960x16",  0x7D, 0x0000, 0x0000, 1280,  960, 16, 1, 160, 60,
+	 MD_XGI300|MD_XGI315},
+	{"1280x960x24",  0x7E, 0x0000, 0x0000, 1280,  960, 32, 1, 160, 60,
+	 MD_XGI300|MD_XGI315},
+	{"1280x960x32",  0x7E, 0x0000, 0x0000, 1280,  960, 32, 1, 160, 60,
+	 MD_XGI300|MD_XGI315},
+	{"1280x1024x8",  0x3A, 0x0107, 0x0107, 1280, 1024,  8, 1, 160, 64,
+	 MD_XGI300|MD_XGI315},
+	{"1280x1024x16", 0x4D, 0x011a, 0x011a, 1280, 1024, 16, 1, 160, 64,
+	 MD_XGI300|MD_XGI315},
+	{"1280x1024x24", 0x65, 0x013d, 0x011b, 1280, 1024, 32, 1, 160, 64,
+	 MD_XGI300|MD_XGI315},
+	{"1280x1024x32", 0x65, 0x013d, 0x011b, 1280, 1024, 32, 1, 160, 64,
+	 MD_XGI300|MD_XGI315},
+	{"1400x1050x8",  0x26, 0x0000, 0x0000, 1400, 1050,  8, 1, 175, 65,
+	 MD_XGI315},  /* TW: 310/325 series only */
+	{"1400x1050x16", 0x27, 0x0000, 0x0000, 1400, 1050, 16, 1, 175, 65,
+	 MD_XGI315},
+	{"1400x1050x24", 0x28, 0x0000, 0x0000, 1400, 1050, 32, 1, 175, 65,
+	 MD_XGI315},
+	{"1400x1050x32", 0x28, 0x0000, 0x0000, 1400, 1050, 32, 1, 175, 65,
+	 MD_XGI315},
+	{"1600x1200x8",  0x3C, 0x0130, 0x011c, 1600, 1200,  8, 1, 200, 75,
+	 MD_XGI300|MD_XGI315},
+	{"1600x1200x16", 0x3D, 0x0131, 0x011e, 1600, 1200, 16, 1, 200, 75,
+	 MD_XGI300|MD_XGI315},
+	{"1600x1200x24", 0x66, 0x013e, 0x011f, 1600, 1200, 32, 1, 200, 75,
+	 MD_XGI300|MD_XGI315},
+	{"1600x1200x32", 0x66, 0x013e, 0x011f, 1600, 1200, 32, 1, 200, 75,
+	 MD_XGI300|MD_XGI315},
+	{"1920x1440x8",  0x68, 0x013f, 0x0000, 1920, 1440,  8, 1, 240, 75,
+	 MD_XGI300|MD_XGI315},
+	{"1920x1440x16", 0x69, 0x0140, 0x0000, 1920, 1440, 16, 1, 240, 75,
+	 MD_XGI300|MD_XGI315},
+	{"1920x1440x24", 0x6B, 0x0141, 0x0000, 1920, 1440, 32, 1, 240, 75,
+	 MD_XGI300|MD_XGI315},
+	{"1920x1440x32", 0x6B, 0x0141, 0x0000, 1920, 1440, 32, 1, 240, 75,
+	 MD_XGI300|MD_XGI315},
+	{"2048x1536x8",  0x6c, 0x0000, 0x0000, 2048, 1536,  8, 1, 256, 96,
+	 MD_XGI315},  /* TW: 310/325 series only */
+	{"2048x1536x16", 0x6d, 0x0000, 0x0000, 2048, 1536, 16, 1, 256, 96,
+	 MD_XGI315},
+	{"2048x1536x24", 0x6e, 0x0000, 0x0000, 2048, 1536, 32, 1, 256, 96,
+	 MD_XGI315},
+	{"2048x1536x32", 0x6e, 0x0000, 0x0000, 2048, 1536, 32, 1, 256, 96,
+	 MD_XGI315},
 	{"\0", 0x00, 0, 0, 0, 0, 0, 0, 0}
 };
 
@@ -437,44 +480,45 @@
 #ifdef MODULE
 static int xgifb_mode_idx = 1;
 #else
-static int xgifb_mode_idx = -1;               /* Use a default mode if we are inside the kernel */
+static int xgifb_mode_idx = -1; /* Use a default mode if we are
+					inside the kernel */
 #endif
 static u8  XGIfb_mode_no  = 0;
 static u8  XGIfb_rate_idx = 0;
 
 /* TW: CR36 evaluation */
-static const unsigned short XGI300paneltype[] =
-    { LCD_UNKNOWN,   LCD_800x600,  LCD_1024x768,  LCD_1280x1024,
-      LCD_1280x960,  LCD_640x480,  LCD_1024x600,  LCD_1152x768,
-       LCD_1024x768, LCD_1024x768,  LCD_1024x768,
-      LCD_1024x768,  LCD_1024x768, LCD_1024x768,  LCD_1024x768 };
+static const unsigned short XGI300paneltype[] = {
+	 LCD_UNKNOWN,  LCD_800x600, LCD_1024x768, LCD_1280x1024,
+	LCD_1280x960,  LCD_640x480, LCD_1024x600, LCD_1152x768,
+	LCD_1024x768, LCD_1024x768, LCD_1024x768,
+	LCD_1024x768, LCD_1024x768, LCD_1024x768, LCD_1024x768};
 
-static const unsigned short XGI310paneltype[] =
-    { LCD_UNKNOWN,   LCD_800x600,  LCD_1024x768,  LCD_1280x1024,
-      LCD_640x480,   LCD_1024x600, LCD_1152x864,  LCD_1280x960,
-      LCD_1152x768,  LCD_1400x1050,LCD_1280x768,  LCD_1600x1200,
-      LCD_1024x768, LCD_1024x768,  LCD_1024x768 };
+static const unsigned short XGI310paneltype[] = {
+	 LCD_UNKNOWN,   LCD_800x600, LCD_1024x768, LCD_1280x1024,
+	 LCD_640x480,  LCD_1024x600, LCD_1152x864, LCD_1280x960,
+	LCD_1152x768, LCD_1400x1050, LCD_1280x768, LCD_1600x1200,
+	LCD_1024x768,  LCD_1024x768, LCD_1024x768};
 
 static const struct _XGI_crt2type {
 	char name[10];
 	int type_no;
 	int tvplug_no;
 } XGI_crt2type[] = {
-	{"NONE", 	0, 		-1},
-	{"LCD",  	DISPTYPE_LCD, 	-1},
-	{"TV",   	DISPTYPE_TV, 	-1},
-	{"VGA",  	DISPTYPE_CRT2, 	-1},
-	{"SVIDEO", 	DISPTYPE_TV, 	TVPLUG_SVIDEO},
-	{"COMPOSITE", 	DISPTYPE_TV, 	TVPLUG_COMPOSITE},
-	{"SCART", 	DISPTYPE_TV, 	TVPLUG_SCART},
-	{"none", 	0, 		-1},
-	{"lcd",  	DISPTYPE_LCD, 	-1},
-	{"tv",   	DISPTYPE_TV, 	-1},
-	{"vga",  	DISPTYPE_CRT2, 	-1},
-	{"svideo", 	DISPTYPE_TV, 	TVPLUG_SVIDEO},
-	{"composite", 	DISPTYPE_TV, 	TVPLUG_COMPOSITE},
-	{"scart", 	DISPTYPE_TV, 	TVPLUG_SCART},
-	{"\0",  	-1, 		-1}
+	{"NONE",	0,		-1},
+	{"LCD",		DISPTYPE_LCD,	-1},
+	{"TV",		DISPTYPE_TV,	-1},
+	{"VGA",		DISPTYPE_CRT2,	-1},
+	{"SVIDEO",	DISPTYPE_TV,	TVPLUG_SVIDEO},
+	{"COMPOSITE",	DISPTYPE_TV,	TVPLUG_COMPOSITE},
+	{"SCART",	DISPTYPE_TV,	TVPLUG_SCART},
+	{"none",	0,		-1},
+	{"lcd",		DISPTYPE_LCD,	-1},
+	{"tv",		DISPTYPE_TV,	-1},
+	{"vga",		DISPTYPE_CRT2,	-1},
+	{"svideo",	DISPTYPE_TV,	TVPLUG_SVIDEO},
+	{"composite",	DISPTYPE_TV,	TVPLUG_COMPOSITE},
+	{"scart",	DISPTYPE_TV,	TVPLUG_SCART},
+	{"\0",		-1,		-1}
 };
 
 /* TV standard */
@@ -482,11 +526,11 @@
 	char name[6];
 	int type_no;
 } XGI_tvtype[] = {
-	{"PAL",  	1},
-	{"NTSC", 	2},
-	{"pal", 	1},
-	{"ntsc",  	2},
-	{"\0",   	-1}
+	{"PAL",		1},
+	{"NTSC",	2},
+	{"pal",		1},
+	{"ntsc",	2},
+	{"\0",		-1}
 };
 
 static const struct _XGI_vrate {
@@ -495,13 +539,19 @@
 	u16 yres;
 	u16 refresh;
 } XGIfb_vrate[] = {
-	{1,  640,  480, 60}, {2,  640,  480,  72}, {3, 640,   480,  75}, {4,  640, 480,  85},
-	{5,  640,  480,100}, {6,  640,  480, 120}, {7, 640,   480, 160}, {8,  640, 480, 200},
+	{1,  640,  480, 60}, {2,  640,  480,  72},
+	{3, 640,   480,  75}, {4,  640, 480,  85},
+
+	{5,  640,  480, 100}, {6,  640,  480, 120},
+	{7, 640,   480, 160}, {8,  640, 480, 200},
+
 	{1,  720,  480, 60},
 	{1,  720,  576, 58},
 	{1,  800,  480, 60}, {2,  800,  480,  75}, {3, 800,   480,  85},
-        {1,  800,  600,  60}, {2, 800,   600,  72}, {3,  800, 600,  75},
-	{4,  800,  600, 85}, {5,  800,  600, 100}, {6, 800,   600, 120}, {7,  800, 600, 160},
+	{1,  800,  600,  60}, {2, 800,   600,  72}, {3,  800, 600,  75},
+	{4,  800,  600, 85}, {5,  800,  600, 100},
+	{6, 800,   600, 120}, {7,  800, 600, 160},
+
 	{1, 1024,  768,  60}, {2, 1024,  768,  70}, {3, 1024, 768,  75},
 	{4, 1024,  768, 85}, {5, 1024,  768, 100}, {6, 1024,  768, 120},
 	{1, 1024,  576, 60}, {2, 1024,  576,  75}, {3, 1024,  576,  85},
@@ -509,279 +559,187 @@
 	{1, 1152,  768, 60},
 	{1, 1280,  720, 60}, {2, 1280,  720,  75}, {3, 1280,  720,  85},
 	{1, 1280,  768, 60},
-        {1, 1280, 1024,  60}, {2, 1280, 1024,  75}, {3, 1280, 1024,  85},
+	{1, 1280, 1024,  60}, {2, 1280, 1024,  75}, {3, 1280, 1024,  85},
 	{1, 1280,  960, 70},
 	{1, 1400, 1050, 60},
-	{1, 1600, 1200, 60}, {2, 1600, 1200,  65}, {3, 1600, 1200,  70}, {4, 1600, 1200,  75},
-	{5, 1600, 1200, 85}, {6, 1600, 1200, 100}, {7, 1600, 1200, 120},
-	{1, 1920, 1440, 60}, {2, 1920, 1440,  65}, {3, 1920, 1440,  70}, {4, 1920, 1440,  75},
+	{1, 1600, 1200, 60}, {2, 1600, 1200,  65},
+	{3, 1600, 1200,  70}, {4, 1600, 1200,  75},
+
+	{5, 1600, 1200, 85}, {6, 1600, 1200, 100},
+	{7, 1600, 1200, 120},
+
+	{1, 1920, 1440, 60}, {2, 1920, 1440,  65},
+	{3, 1920, 1440,  70}, {4, 1920, 1440,  75},
+
 	{5, 1920, 1440, 85}, {6, 1920, 1440, 100},
-	{1, 2048, 1536, 60}, {2, 2048, 1536,  65}, {3, 2048, 1536,  70}, {4, 2048, 1536,  75},
+	{1, 2048, 1536, 60}, {2, 2048, 1536,  65},
+	{3, 2048, 1536,  70}, {4, 2048, 1536,  75},
+
 	{5, 2048, 1536, 85},
 	{0, 0, 0, 0}
 };
 
 static const struct _chswtable {
-    int subsysVendor;
-    int subsysCard;
-    char *vendorName;
-    char *cardName;
+	int subsysVendor;
+	int subsysCard;
+	char *vendorName;
+	char *cardName;
 } mychswtable[] = {
-        { 0x1631, 0x1002, "Mitachi", "0x1002" },
+	{ 0x1631, 0x1002, "Mitachi", "0x1002" },
 	{ 0,      0,      ""       , ""       }
 };
 
-// Eden Chen
+/* Eden Chen */
 static const struct _XGI_TV_filter {
 	u8 filter[9][4];
 } XGI_TV_filter[] = {
-	{ {{0x00,0x00,0x00,0x40},  /* NTSCFilter_0 */
-	   {0x00,0xE0,0x10,0x60},
-	   {0x00,0xEE,0x10,0x44},
-	   {0x00,0xF4,0x10,0x38},
-	   {0xF8,0xF4,0x18,0x38},
-	   {0xFC,0xFB,0x14,0x2A},
-	   {0x00,0x00,0x10,0x20},
-	   {0x00,0x04,0x10,0x18},
-	   {0xFF,0xFF,0xFF,0xFF} }},
-	{ {{0x00,0x00,0x00,0x40},  /* NTSCFilter_1 */
-	   {0x00,0xE0,0x10,0x60},
-	   {0x00,0xEE,0x10,0x44},
-	   {0x00,0xF4,0x10,0x38},
-	   {0xF8,0xF4,0x18,0x38},
-	   {0xFC,0xFB,0x14,0x2A},
-	   {0x00,0x00,0x10,0x20},
-	   {0x00,0x04,0x10,0x18},
-	   {0xFF,0xFF,0xFF,0xFF} }},
-	{ {{0x00,0x00,0x00,0x40},  /* NTSCFilter_2 */
-	   {0xF5,0xEE,0x1B,0x44},
-	   {0xF8,0xF4,0x18,0x38},
-	   {0xEB,0x04,0x25,0x18},
-	   {0xF1,0x05,0x1F,0x16},
-	   {0xF6,0x06,0x1A,0x14},
-	   {0xFA,0x06,0x16,0x14},
-	   {0x00,0x04,0x10,0x18},
-	   {0xFF,0xFF,0xFF,0xFF} }},
-	{ {{0x00,0x00,0x00,0x40},  /* NTSCFilter_3 */
-	   {0xF1,0x04,0x1F,0x18},
-	   {0xEE,0x0D,0x22,0x06},
-	   {0xF7,0x06,0x19,0x14},
-	   {0xF4,0x0B,0x1C,0x0A},
-	   {0xFA,0x07,0x16,0x12},
-	   {0xF9,0x0A,0x17,0x0C},
-	   {0x00,0x07,0x10,0x12},
-	   {0xFF,0xFF,0xFF,0xFF} }},
-	{ {{0x00,0x00,0x00,0x40},  /* NTSCFilter_4 */
-	   {0x00,0xE0,0x10,0x60},
-	   {0x00,0xEE,0x10,0x44},
-	   {0x00,0xF4,0x10,0x38},
-	   {0xF8,0xF4,0x18,0x38},
-	   {0xFC,0xFB,0x14,0x2A},
-	   {0x00,0x00,0x10,0x20},
-	   {0x00,0x04,0x10,0x18},
-	   {0xFF,0xFF,0xFF,0xFF} }},
-	{ {{0x00,0x00,0x00,0x40},  /* NTSCFilter_5 */
-	   {0xF5,0xEE,0x1B,0x44},
-	   {0xF8,0xF4,0x18,0x38},
-	   {0xEB,0x04,0x25,0x18},
-	   {0xF1,0x05,0x1F,0x16},
-	   {0xF6,0x06,0x1A,0x14},
-	   {0xFA,0x06,0x16,0x14},
-	   {0x00,0x04,0x10,0x18},
-	   {0xFF,0xFF,0xFF,0xFF} }},
-	{ {{0x00,0x00,0x00,0x40},  /* NTSCFilter_6 */
-	   {0xEB,0x04,0x25,0x18},
-	   {0xE7,0x0E,0x29,0x04},
-	   {0xEE,0x0C,0x22,0x08},
-	   {0xF6,0x0B,0x1A,0x0A},
-	   {0xF9,0x0A,0x17,0x0C},
-	   {0xFC,0x0A,0x14,0x0C},
-	   {0x00,0x08,0x10,0x10},
-	   {0xFF,0xFF,0xFF,0xFF} }},
-	{ {{0x00,0x00,0x00,0x40},  /* NTSCFilter_7 */
-	   {0xEC,0x02,0x24,0x1C},
-	   {0xF2,0x04,0x1E,0x18},
-	   {0xEB,0x15,0x25,0xF6},
-	   {0xF4,0x10,0x1C,0x00},
-	   {0xF8,0x0F,0x18,0x02},
-	   {0x00,0x04,0x10,0x18},
-	   {0x01,0x06,0x0F,0x14},
-	   {0xFF,0xFF,0xFF,0xFF} }},
-	{ {{0x00,0x00,0x00,0x40},  /* PALFilter_0 */
-	   {0x00,0xE0,0x10,0x60},
-	   {0x00,0xEE,0x10,0x44},
-	   {0x00,0xF4,0x10,0x38},
-	   {0xF8,0xF4,0x18,0x38},
-	   {0xFC,0xFB,0x14,0x2A},
-	   {0x00,0x00,0x10,0x20},
-	   {0x00,0x04,0x10,0x18},
-	   {0xFF,0xFF,0xFF,0xFF} }},
-	{ {{0x00,0x00,0x00,0x40},  /* PALFilter_1 */
-	   {0x00,0xE0,0x10,0x60},
-	   {0x00,0xEE,0x10,0x44},
-	   {0x00,0xF4,0x10,0x38},
-	   {0xF8,0xF4,0x18,0x38},
-	   {0xFC,0xFB,0x14,0x2A},
-	   {0x00,0x00,0x10,0x20},
-	   {0x00,0x04,0x10,0x18},
-	   {0xFF,0xFF,0xFF,0xFF} }},
-	{ {{0x00,0x00,0x00,0x40},  /* PALFilter_2 */
-	   {0xF5,0xEE,0x1B,0x44},
-	   {0xF8,0xF4,0x18,0x38},
-	   {0xF1,0xF7,0x01,0x32},
-	   {0xF5,0xFB,0x1B,0x2A},
-	   {0xF9,0xFF,0x17,0x22},
-	   {0xFB,0x01,0x15,0x1E},
-	   {0x00,0x04,0x10,0x18},
-	   {0xFF,0xFF,0xFF,0xFF} }},
-	{ {{0x00,0x00,0x00,0x40},  /* PALFilter_3 */
-	   {0xF5,0xFB,0x1B,0x2A},
-	   {0xEE,0xFE,0x22,0x24},
-	   {0xF3,0x00,0x1D,0x20},
-	   {0xF9,0x03,0x17,0x1A},
-	   {0xFB,0x02,0x14,0x1E},
-	   {0xFB,0x04,0x15,0x18},
-	   {0x00,0x06,0x10,0x14},
-	   {0xFF,0xFF,0xFF,0xFF} }},
-	{ {{0x00,0x00,0x00,0x40},  /* PALFilter_4 */
-	   {0x00,0xE0,0x10,0x60},
-	   {0x00,0xEE,0x10,0x44},
-	   {0x00,0xF4,0x10,0x38},
-	   {0xF8,0xF4,0x18,0x38},
-	   {0xFC,0xFB,0x14,0x2A},
-	   {0x00,0x00,0x10,0x20},
-	   {0x00,0x04,0x10,0x18},
-	   {0xFF,0xFF,0xFF,0xFF} }},
-	{ {{0x00,0x00,0x00,0x40},  /* PALFilter_5 */
-	   {0xF5,0xEE,0x1B,0x44},
-	   {0xF8,0xF4,0x18,0x38},
-	   {0xF1,0xF7,0x1F,0x32},
-	   {0xF5,0xFB,0x1B,0x2A},
-	   {0xF9,0xFF,0x17,0x22},
-	   {0xFB,0x01,0x15,0x1E},
-	   {0x00,0x04,0x10,0x18},
-	   {0xFF,0xFF,0xFF,0xFF} }},
-	{ {{0x00,0x00,0x00,0x40},  /* PALFilter_6 */
-	   {0xF5,0xEE,0x1B,0x2A},
-	   {0xEE,0xFE,0x22,0x24},
-	   {0xF3,0x00,0x1D,0x20},
-	   {0xF9,0x03,0x17,0x1A},
-	   {0xFB,0x02,0x14,0x1E},
-	   {0xFB,0x04,0x15,0x18},
-	   {0x00,0x06,0x10,0x14},
-	   {0xFF,0xFF,0xFF,0xFF} }},
-	{ {{0x00,0x00,0x00,0x40},  /* PALFilter_7 */
-	   {0xF5,0xEE,0x1B,0x44},
-	   {0xF8,0xF4,0x18,0x38},
-	   {0xFC,0xFB,0x14,0x2A},
-	   {0xEB,0x05,0x25,0x16},
-	   {0xF1,0x05,0x1F,0x16},
-	   {0xFA,0x07,0x16,0x12},
-	   {0x00,0x07,0x10,0x12},
-	   {0xFF,0xFF,0xFF,0xFF} }}
+	{ { {0x00, 0x00, 0x00, 0x40},  /* NTSCFilter_0 */
+	    {0x00, 0xE0, 0x10, 0x60},
+	    {0x00, 0xEE, 0x10, 0x44},
+	    {0x00, 0xF4, 0x10, 0x38},
+	    {0xF8, 0xF4, 0x18, 0x38},
+	    {0xFC, 0xFB, 0x14, 0x2A},
+	    {0x00, 0x00, 0x10, 0x20},
+	    {0x00, 0x04, 0x10, 0x18},
+	    {0xFF, 0xFF, 0xFF, 0xFF} } },
+	{ { {0x00, 0x00, 0x00, 0x40},  /* NTSCFilter_1 */
+	    {0x00, 0xE0, 0x10, 0x60},
+	    {0x00, 0xEE, 0x10, 0x44},
+	    {0x00, 0xF4, 0x10, 0x38},
+	    {0xF8, 0xF4, 0x18, 0x38},
+	    {0xFC, 0xFB, 0x14, 0x2A},
+	    {0x00, 0x00, 0x10, 0x20},
+	    {0x00, 0x04, 0x10, 0x18},
+	    {0xFF, 0xFF, 0xFF, 0xFF} } },
+	{ { {0x00, 0x00, 0x00, 0x40},  /* NTSCFilter_2 */
+	    {0xF5, 0xEE, 0x1B, 0x44},
+	    {0xF8, 0xF4, 0x18, 0x38},
+	    {0xEB, 0x04, 0x25, 0x18},
+	    {0xF1, 0x05, 0x1F, 0x16},
+	    {0xF6, 0x06, 0x1A, 0x14},
+	    {0xFA, 0x06, 0x16, 0x14},
+	    {0x00, 0x04, 0x10, 0x18},
+	    {0xFF, 0xFF, 0xFF, 0xFF} } },
+	{ { {0x00, 0x00, 0x00, 0x40},  /* NTSCFilter_3 */
+	    {0xF1, 0x04, 0x1F, 0x18},
+	    {0xEE, 0x0D, 0x22, 0x06},
+	    {0xF7, 0x06, 0x19, 0x14},
+	    {0xF4, 0x0B, 0x1C, 0x0A},
+	    {0xFA, 0x07, 0x16, 0x12},
+	    {0xF9, 0x0A, 0x17, 0x0C},
+	    {0x00, 0x07, 0x10, 0x12},
+	    {0xFF, 0xFF, 0xFF, 0xFF} } },
+	{ { {0x00, 0x00, 0x00, 0x40},  /* NTSCFilter_4 */
+	    {0x00, 0xE0, 0x10, 0x60},
+	    {0x00, 0xEE, 0x10, 0x44},
+	    {0x00, 0xF4, 0x10, 0x38},
+	    {0xF8, 0xF4, 0x18, 0x38},
+	    {0xFC, 0xFB, 0x14, 0x2A},
+	    {0x00, 0x00, 0x10, 0x20},
+	    {0x00, 0x04, 0x10, 0x18},
+	    {0xFF, 0xFF, 0xFF, 0xFF} } },
+	{ { {0x00, 0x00, 0x00, 0x40},  /* NTSCFilter_5 */
+	    {0xF5, 0xEE, 0x1B, 0x44},
+	    {0xF8, 0xF4, 0x18, 0x38},
+	    {0xEB, 0x04, 0x25, 0x18},
+	    {0xF1, 0x05, 0x1F, 0x16},
+	    {0xF6, 0x06, 0x1A, 0x14},
+	    {0xFA, 0x06, 0x16, 0x14},
+	    {0x00, 0x04, 0x10, 0x18},
+	    {0xFF, 0xFF, 0xFF, 0xFF} } },
+	{ { {0x00, 0x00, 0x00, 0x40},  /* NTSCFilter_6 */
+	    {0xEB, 0x04, 0x25, 0x18},
+	    {0xE7, 0x0E, 0x29, 0x04},
+	    {0xEE, 0x0C, 0x22, 0x08},
+	    {0xF6, 0x0B, 0x1A, 0x0A},
+	    {0xF9, 0x0A, 0x17, 0x0C},
+	    {0xFC, 0x0A, 0x14, 0x0C},
+	    {0x00, 0x08, 0x10, 0x10},
+	    {0xFF, 0xFF, 0xFF, 0xFF} } },
+	{ { {0x00, 0x00, 0x00, 0x40},  /* NTSCFilter_7 */
+	    {0xEC, 0x02, 0x24, 0x1C},
+	    {0xF2, 0x04, 0x1E, 0x18},
+	    {0xEB, 0x15, 0x25, 0xF6},
+	    {0xF4, 0x10, 0x1C, 0x00},
+	    {0xF8, 0x0F, 0x18, 0x02},
+	    {0x00, 0x04, 0x10, 0x18},
+	    {0x01, 0x06, 0x0F, 0x14},
+	    {0xFF, 0xFF, 0xFF, 0xFF} } },
+	{ { {0x00, 0x00, 0x00, 0x40},  /* PALFilter_0 */
+	    {0x00, 0xE0, 0x10, 0x60},
+	    {0x00, 0xEE, 0x10, 0x44},
+	    {0x00, 0xF4, 0x10, 0x38},
+	    {0xF8, 0xF4, 0x18, 0x38},
+	    {0xFC, 0xFB, 0x14, 0x2A},
+	    {0x00, 0x00, 0x10, 0x20},
+	    {0x00, 0x04, 0x10, 0x18},
+	    {0xFF, 0xFF, 0xFF, 0xFF} } },
+	{ { {0x00, 0x00, 0x00, 0x40},  /* PALFilter_1 */
+	    {0x00, 0xE0, 0x10, 0x60},
+	    {0x00, 0xEE, 0x10, 0x44},
+	    {0x00, 0xF4, 0x10, 0x38},
+	    {0xF8, 0xF4, 0x18, 0x38},
+	    {0xFC, 0xFB, 0x14, 0x2A},
+	    {0x00, 0x00, 0x10, 0x20},
+	    {0x00, 0x04, 0x10, 0x18},
+	    {0xFF, 0xFF, 0xFF, 0xFF} } },
+	{ { {0x00, 0x00, 0x00, 0x40},  /* PALFilter_2 */
+	    {0xF5, 0xEE, 0x1B, 0x44},
+	    {0xF8, 0xF4, 0x18, 0x38},
+	    {0xF1, 0xF7, 0x01, 0x32},
+	    {0xF5, 0xFB, 0x1B, 0x2A},
+	    {0xF9, 0xFF, 0x17, 0x22},
+	    {0xFB, 0x01, 0x15, 0x1E},
+	    {0x00, 0x04, 0x10, 0x18},
+	    {0xFF, 0xFF, 0xFF, 0xFF} } },
+	{ { {0x00, 0x00, 0x00, 0x40},  /* PALFilter_3 */
+	    {0xF5, 0xFB, 0x1B, 0x2A},
+	    {0xEE, 0xFE, 0x22, 0x24},
+	    {0xF3, 0x00, 0x1D, 0x20},
+	    {0xF9, 0x03, 0x17, 0x1A},
+	    {0xFB, 0x02, 0x14, 0x1E},
+	    {0xFB, 0x04, 0x15, 0x18},
+	    {0x00, 0x06, 0x10, 0x14},
+	    {0xFF, 0xFF, 0xFF, 0xFF} } },
+	{ { {0x00, 0x00, 0x00, 0x40},  /* PALFilter_4 */
+	    {0x00, 0xE0, 0x10, 0x60},
+	    {0x00, 0xEE, 0x10, 0x44},
+	    {0x00, 0xF4, 0x10, 0x38},
+	    {0xF8, 0xF4, 0x18, 0x38},
+	    {0xFC, 0xFB, 0x14, 0x2A},
+	    {0x00, 0x00, 0x10, 0x20},
+	    {0x00, 0x04, 0x10, 0x18},
+	    {0xFF, 0xFF, 0xFF, 0xFF} } },
+	{ { {0x00, 0x00, 0x00, 0x40},  /* PALFilter_5 */
+	    {0xF5, 0xEE, 0x1B, 0x44},
+	    {0xF8, 0xF4, 0x18, 0x38},
+	    {0xF1, 0xF7, 0x1F, 0x32},
+	    {0xF5, 0xFB, 0x1B, 0x2A},
+	    {0xF9, 0xFF, 0x17, 0x22},
+	    {0xFB, 0x01, 0x15, 0x1E},
+	    {0x00, 0x04, 0x10, 0x18},
+	    {0xFF, 0xFF, 0xFF, 0xFF} } },
+	{ { {0x00, 0x00, 0x00, 0x40},  /* PALFilter_6 */
+	    {0xF5, 0xEE, 0x1B, 0x2A},
+	    {0xEE, 0xFE, 0x22, 0x24},
+	    {0xF3, 0x00, 0x1D, 0x20},
+	    {0xF9, 0x03, 0x17, 0x1A},
+	    {0xFB, 0x02, 0x14, 0x1E},
+	    {0xFB, 0x04, 0x15, 0x18},
+	    {0x00, 0x06, 0x10, 0x14},
+	    {0xFF, 0xFF, 0xFF, 0xFF} } },
+	{ { {0x00, 0x00, 0x00, 0x40},  /* PALFilter_7 */
+	    {0xF5, 0xEE, 0x1B, 0x44},
+	    {0xF8, 0xF4, 0x18, 0x38},
+	    {0xFC, 0xFB, 0x14, 0x2A},
+	    {0xEB, 0x05, 0x25, 0x16},
+	    {0xF1, 0x05, 0x1F, 0x16},
+	    {0xFA, 0x07, 0x16, 0x12},
+	    {0x00, 0x07, 0x10, 0x12},
+	    {0xFF, 0xFF, 0xFF, 0xFF} } }
 };
 
 static int           filter = -1;
 static unsigned char filter_tb;
 
-
-/* ---------------------- Routine prototypes ------------------------- */
-
-/* Interface used by the world */
-#ifndef MODULE
-XGIINITSTATIC int __init XGIfb_setup(char *options);
-#endif
-
-/* Interface to the low level console driver */
-
-
-
-/* fbdev routines */
-XGIINITSTATIC int __init xgifb_init(void);
-static int      XGIfb_set_par(struct fb_info *info);
-static int      XGIfb_blank(int blank,
-                            struct fb_info *info);
-/*static int 	XGIfb_mmap(struct fb_info *info, struct file *file,
-		           struct vm_area_struct *vma);
-*/
-
-/*
-extern int	XGIfb_mode_rate_to_dclock(VB_DEVICE_INFO *XGI_Pr,
-			      struct xgi_hw_device_info *HwDeviceExtension,
-			      unsigned char modeno, unsigned char rateindex);
-extern int      XGIfb_mode_rate_to_ddata(VB_DEVICE_INFO *XGI_Pr, struct xgi_hw_device_info *HwDeviceExtension,
-			 unsigned char modeno, unsigned char rateindex,
-			 unsigned int *left_margin, unsigned int *right_margin,
-			 unsigned int *upper_margin, unsigned int *lower_margin,
-			 unsigned int *hsync_len, unsigned int *vsync_len,
-			 unsigned int *sync, unsigned int *vmode);
-*/
-extern unsigned char XGI_SearchModeID(unsigned short ModeNo,
-				unsigned short *ModeIdIndex,
-				struct vb_device_info *);
-static int      XGIfb_get_fix(struct fb_fix_screeninfo *fix, int con,
-			      struct fb_info *info);
-
-/* Internal general routines */
-static void     XGIfb_search_mode(const char *name);
-static int      XGIfb_validate_mode(int modeindex);
-static u8       XGIfb_search_refresh_rate(unsigned int rate);
-static int      XGIfb_setcolreg(unsigned regno, unsigned red, unsigned green,
-			unsigned blue, unsigned transp,
-			struct fb_info *fb_info);
-static int      XGIfb_do_set_var(struct fb_var_screeninfo *var, int isactive,
-		      	struct fb_info *info);
-static void     XGIfb_pre_setmode(void);
-static void     XGIfb_post_setmode(void);
-
-/* Internal hardware access routines */
-void            XGIfb_set_reg4(u16 port, unsigned long data);
-u32             XGIfb_get_reg3(u16 port);
-
-/* Chipset-dependent internal routines */
-
-
-static int      XGIfb_get_dram_size(void);
-static void     XGIfb_detect_VB(void);
-static void     XGIfb_get_VB_type(void);
-static int      XGIfb_has_VB(void);
-
-
-/* Internal routines to access PCI configuration space */
-unsigned char XGIfb_query_VGA_config_space(struct xgi_hw_device_info *pXGIhw_ext,
-					   unsigned long offset,
-					   unsigned long set,
-					   unsigned long *value);
-//BOOLEAN         XGIfb_query_north_bridge_space(PXGI_HW_DEVICE_INFO pXGIhw_ext,
-//	         	unsigned long offset, unsigned long set, unsigned long *value);
-
-
-/* Routines from init.c/init301.c */
-extern void     InitTo330Pointer(unsigned char, struct vb_device_info *pVBInfo);
-extern unsigned char  XGIInitNew(struct xgi_hw_device_info *HwDeviceExtension);
-extern unsigned char XGISetModeNew(struct xgi_hw_device_info *HwDeviceExtension,
-				   unsigned short ModeNo);
-//extern void     XGI_SetEnableDstn(VB_DEVICE_INFO *XGI_Pr);
-extern void     XGI_LongWait(struct vb_device_info *XGI_Pr);
-extern unsigned short XGI_GetRatePtrCRT2(struct xgi_hw_device_info *pXGIHWDE,
-					 unsigned short ModeNo,
-					 unsigned short ModeIdIndex,
-					 struct vb_device_info *pVBInfo);
-/* TW: Chrontel TV functions */
-extern unsigned short XGI_GetCH700x(struct vb_device_info *XGI_Pr,
-				    unsigned short tempbx);
-extern void XGI_SetCH700x(struct vb_device_info *XGI_Pr, unsigned short tempbx);
-extern unsigned short XGI_GetCH701x(struct vb_device_info *XGI_Pr,
-				    unsigned short tempbx);
-extern void XGI_SetCH701x(struct vb_device_info *XGI_Pr, unsigned short tempbx);
-extern void XGI_SetCH70xxANDOR(struct vb_device_info *XGI_Pr,
-			       unsigned short tempax,
-			       unsigned short tempbh);
-extern void XGI_DDC2Delay(struct vb_device_info *XGI_Pr, unsigned short delaytime);
-
-/* TW: Sensing routines */
-void            XGI_Sense30x(void);
-int             XGIDoSense(int tempbl, int tempbh, int tempcl, int tempch);
-
-extern struct XGI21_LVDSCapStruct XGI21_LCDCapList[13];
 #endif
diff -druN linux-2.6.39-libre/drivers/staging/zcache/zcache.c linux-3.0-rc7-libre/drivers/staging/zcache/zcache.c
--- linux-2.6.39-libre/drivers/staging/zcache/zcache.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/staging/zcache/zcache.c	2011-07-11 19:51:52.000000000 -0400
@@ -1181,9 +1181,12 @@
 /*
  * zcache shrinker interface (only useful for ephemeral pages, so zbud only)
  */
-static int shrink_zcache_memory(struct shrinker *shrink, int nr, gfp_t gfp_mask)
+static int shrink_zcache_memory(struct shrinker *shrink,
+				struct shrink_control *sc)
 {
 	int ret = -1;
+	int nr = sc->nr_to_scan;
+	gfp_t gfp_mask = sc->gfp_mask;
 
 	if (nr >= 0) {
 		if (!(gfp_mask & __GFP_FS))
diff -druN linux-2.6.39-libre/drivers/target/Kconfig linux-3.0-rc7-libre/drivers/target/Kconfig
--- linux-2.6.39-libre/drivers/target/Kconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/target/Kconfig	2011-07-11 19:51:52.000000000 -0400
@@ -30,5 +30,6 @@
 	passthrough access to Linux/SCSI device
 
 source "drivers/target/loopback/Kconfig"
+source "drivers/target/tcm_fc/Kconfig"
 
 endif
diff -druN linux-2.6.39-libre/drivers/target/loopback/tcm_loop.c linux-3.0-rc7-libre/drivers/target/loopback/tcm_loop.c
--- linux-2.6.39-libre/drivers/target/loopback/tcm_loop.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/target/loopback/tcm_loop.c	2011-07-11 19:51:52.000000000 -0400
@@ -31,7 +31,7 @@
 #include <scsi/scsi_host.h>
 #include <scsi/scsi_device.h>
 #include <scsi/scsi_cmnd.h>
-#include <scsi/libsas.h> /* For TASK_ATTR_* */
+#include <scsi/scsi_tcq.h>
 
 #include <target/target_core_base.h>
 #include <target/target_core_transport.h>
@@ -95,17 +95,17 @@
 	if (sc->device->tagged_supported) {
 		switch (sc->tag) {
 		case HEAD_OF_QUEUE_TAG:
-			sam_task_attr = TASK_ATTR_HOQ;
+			sam_task_attr = MSG_HEAD_TAG;
 			break;
 		case ORDERED_QUEUE_TAG:
-			sam_task_attr = TASK_ATTR_ORDERED;
+			sam_task_attr = MSG_ORDERED_TAG;
 			break;
 		default:
-			sam_task_attr = TASK_ATTR_SIMPLE;
+			sam_task_attr = MSG_SIMPLE_TAG;
 			break;
 		}
 	} else
-		sam_task_attr = TASK_ATTR_SIMPLE;
+		sam_task_attr = MSG_SIMPLE_TAG;
 
 	/*
 	 * Initialize struct se_cmd descriptor from target_core_mod infrastructure
@@ -379,14 +379,14 @@
 	 * Initialize struct se_cmd descriptor from target_core_mod infrastructure
 	 */
 	transport_init_se_cmd(se_cmd, se_tpg->se_tpg_tfo, se_sess, 0,
-				DMA_NONE, TASK_ATTR_SIMPLE,
+				DMA_NONE, MSG_SIMPLE_TAG,
 				&tl_cmd->tl_sense_buf[0]);
 	/*
 	 * Allocate the LUN_RESET TMR
 	 */
 	se_cmd->se_tmr_req = core_tmr_alloc_req(se_cmd, (void *)tl_tmr,
 				TMR_LUN_RESET);
-	if (!se_cmd->se_tmr_req)
+	if (IS_ERR(se_cmd->se_tmr_req))
 		goto release;
 	/*
 	 * Locate the underlying TCM struct se_lun from sc->device->lun
@@ -939,18 +939,6 @@
 	return 0;
 }
 
-static u64 tcm_loop_pack_lun(unsigned int lun)
-{
-	u64 result;
-
-	/* LSB of lun into byte 1 big-endian */
-	result = ((lun & 0xff) << 8);
-	/* use flat space addressing method */
-	result |= 0x40 | ((lun >> 8) & 0x3f);
-
-	return cpu_to_le64(result);
-}
-
 static char *tcm_loop_dump_proto_id(struct tcm_loop_hba *tl_hba)
 {
 	switch (tl_hba->tl_proto_id) {
@@ -1029,6 +1017,7 @@
 	struct se_portal_group *se_tpg;
 	struct tcm_loop_hba *tl_hba = tl_tpg->tl_hba;
 	struct tcm_loop_nexus *tl_nexus;
+	int ret = -ENOMEM;
 
 	if (tl_tpg->tl_hba->tl_nexus) {
 		printk(KERN_INFO "tl_tpg->tl_hba->tl_nexus already exists\n");
@@ -1045,8 +1034,10 @@
 	 * Initialize the struct se_session pointer
 	 */
 	tl_nexus->se_sess = transport_init_session();
-	if (!tl_nexus->se_sess)
+	if (IS_ERR(tl_nexus->se_sess)) {
+		ret = PTR_ERR(tl_nexus->se_sess);
 		goto out;
+	}
 	/*
 	 * Since we are running in 'demo mode' this call with generate a
 	 * struct se_node_acl for the tcm_loop struct se_portal_group with the SCSI
@@ -1072,7 +1063,7 @@
 
 out:
 	kfree(tl_nexus);
-	return -ENOMEM;
+	return ret;
 }
 
 static int tcm_loop_drop_nexus(
@@ -1152,7 +1143,7 @@
 	 * the fabric protocol_id set in tcm_loop_make_scsi_hba(), and call
 	 * tcm_loop_make_nexus()
 	 */
-	if (strlen(page) > TL_WWN_ADDR_LEN) {
+	if (strlen(page) >= TL_WWN_ADDR_LEN) {
 		printk(KERN_ERR "Emulated NAA Sas Address: %s, exceeds"
 				" max: %d\n", page, TL_WWN_ADDR_LEN);
 		return -EINVAL;
@@ -1333,7 +1324,7 @@
 	return ERR_PTR(-EINVAL);
 
 check_len:
-	if (strlen(name) > TL_WWN_ADDR_LEN) {
+	if (strlen(name) >= TL_WWN_ADDR_LEN) {
 		printk(KERN_ERR "Emulated NAA %s Address: %s, exceeds"
 			" max: %d\n", name, tcm_loop_dump_proto_id(tl_hba),
 			TL_WWN_ADDR_LEN);
@@ -1481,7 +1472,6 @@
 	fabric->tf_ops.set_fabric_sense_len = &tcm_loop_set_fabric_sense_len;
 	fabric->tf_ops.get_fabric_sense_len = &tcm_loop_get_fabric_sense_len;
 	fabric->tf_ops.is_state_remove = &tcm_loop_is_state_remove;
-	fabric->tf_ops.pack_lun = &tcm_loop_pack_lun;
 
 	tf_cg = &fabric->tf_group;
 	/*
diff -druN linux-2.6.39-libre/drivers/target/Makefile linux-3.0-rc7-libre/drivers/target/Makefile
--- linux-2.6.39-libre/drivers/target/Makefile	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/target/Makefile	2011-07-11 19:51:52.000000000 -0400
@@ -24,3 +24,5 @@
 
 # Fabric modules
 obj-$(CONFIG_LOOPBACK_TARGET)	+= loopback/
+
+obj-$(CONFIG_TCM_FC)		+= tcm_fc/
diff -druN linux-2.6.39-libre/drivers/target/target_core_alua.c linux-3.0-rc7-libre/drivers/target/target_core_alua.c
--- linux-2.6.39-libre/drivers/target/target_core_alua.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/target/target_core_alua.c	2011-07-11 19:51:52.000000000 -0400
@@ -1036,7 +1036,7 @@
 	lu_gp = kmem_cache_zalloc(t10_alua_lu_gp_cache, GFP_KERNEL);
 	if (!(lu_gp)) {
 		printk(KERN_ERR "Unable to allocate struct t10_alua_lu_gp\n");
-		return ERR_PTR(-ENOMEM);;
+		return ERR_PTR(-ENOMEM);
 	}
 	INIT_LIST_HEAD(&lu_gp->lu_gp_list);
 	INIT_LIST_HEAD(&lu_gp->lu_gp_mem_list);
@@ -1044,7 +1044,7 @@
 	atomic_set(&lu_gp->lu_gp_ref_cnt, 0);
 
 	if (def_group) {
-		lu_gp->lu_gp_id = se_global->alua_lu_gps_counter++;;
+		lu_gp->lu_gp_id = se_global->alua_lu_gps_counter++;
 		lu_gp->lu_gp_valid_id = 1;
 		se_global->alua_lu_gps_count++;
 	}
diff -druN linux-2.6.39-libre/drivers/target/target_core_configfs.c linux-3.0-rc7-libre/drivers/target/target_core_configfs.c
--- linux-2.6.39-libre/drivers/target/target_core_configfs.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/target/target_core_configfs.c	2011-07-11 19:51:52.000000000 -0400
@@ -304,7 +304,7 @@
 		printk(KERN_ERR "Unable to locate passed fabric name\n");
 		return NULL;
 	}
-	if (strlen(name) > TARGET_FABRIC_NAME_SIZE) {
+	if (strlen(name) >= TARGET_FABRIC_NAME_SIZE) {
 		printk(KERN_ERR "Passed name: %s exceeds TARGET_FABRIC"
 			"_NAME_SIZE\n", name);
 		return NULL;
@@ -312,7 +312,7 @@
 
 	tf = kzalloc(sizeof(struct target_fabric_configfs), GFP_KERNEL);
 	if (!(tf))
-		return ERR_PTR(-ENOMEM);
+		return NULL;
 
 	INIT_LIST_HEAD(&tf->tf_list);
 	atomic_set(&tf->tf_access_cnt, 0);
@@ -497,10 +497,6 @@
 		printk(KERN_ERR "Missing tfo->is_state_remove()\n");
 		return -EINVAL;
 	}
-	if (!(tfo->pack_lun)) {
-		printk(KERN_ERR "Missing tfo->pack_lun()\n");
-		return -EINVAL;
-	}
 	/*
 	 * We at least require tfo->fabric_make_wwn(), tfo->fabric_drop_wwn()
 	 * tfo->fabric_make_tpg() and tfo->fabric_drop_tpg() in
@@ -855,7 +851,7 @@
 		return -EOPNOTSUPP;
 	}
 
-	if ((strlen(page) + 1) > INQUIRY_VPD_SERIAL_LEN) {
+	if (strlen(page) >= INQUIRY_VPD_SERIAL_LEN) {
 		printk(KERN_ERR "Emulated VPD Unit Serial exceeds"
 		" INQUIRY_VPD_SERIAL_LEN: %d\n", INQUIRY_VPD_SERIAL_LEN);
 		return -EOVERFLOW;
@@ -921,7 +917,7 @@
 
 		transport_dump_vpd_proto_id(vpd, buf, VPD_TMP_BUF_SIZE);
 
-		if ((len + strlen(buf) > PAGE_SIZE))
+		if ((len + strlen(buf) >= PAGE_SIZE))
 			break;
 
 		len += sprintf(page+len, "%s", buf);
@@ -966,19 +962,19 @@
 									\
 		memset(buf, 0, VPD_TMP_BUF_SIZE);			\
 		transport_dump_vpd_assoc(vpd, buf, VPD_TMP_BUF_SIZE);	\
-		if ((len + strlen(buf) > PAGE_SIZE))			\
+		if ((len + strlen(buf) >= PAGE_SIZE))			\
 			break;						\
 		len += sprintf(page+len, "%s", buf);			\
 									\
 		memset(buf, 0, VPD_TMP_BUF_SIZE);			\
 		transport_dump_vpd_ident_type(vpd, buf, VPD_TMP_BUF_SIZE); \
-		if ((len + strlen(buf) > PAGE_SIZE))			\
+		if ((len + strlen(buf) >= PAGE_SIZE))			\
 			break;						\
 		len += sprintf(page+len, "%s", buf);			\
 									\
 		memset(buf, 0, VPD_TMP_BUF_SIZE);			\
 		transport_dump_vpd_ident(vpd, buf, VPD_TMP_BUF_SIZE); \
-		if ((len + strlen(buf) > PAGE_SIZE))			\
+		if ((len + strlen(buf) >= PAGE_SIZE))			\
 			break;						\
 		len += sprintf(page+len, "%s", buf);			\
 	}								\
@@ -1303,7 +1299,7 @@
 			&i_buf[0] : "", pr_reg->pr_res_key,
 			pr_reg->pr_res_generation);
 
-		if ((len + strlen(buf) > PAGE_SIZE))
+		if ((len + strlen(buf) >= PAGE_SIZE))
 			break;
 
 		len += sprintf(page+len, "%s", buf);
@@ -1500,7 +1496,7 @@
 				ret = -ENOMEM;
 				goto out;
 			}
-			if (strlen(i_port) > PR_APTPL_MAX_IPORT_LEN) {
+			if (strlen(i_port) >= PR_APTPL_MAX_IPORT_LEN) {
 				printk(KERN_ERR "APTPL metadata initiator_node="
 					" exceeds PR_APTPL_MAX_IPORT_LEN: %d\n",
 					PR_APTPL_MAX_IPORT_LEN);
@@ -1514,7 +1510,7 @@
 				ret = -ENOMEM;
 				goto out;
 			}
-			if (strlen(isid) > PR_REG_ISID_LEN) {
+			if (strlen(isid) >= PR_REG_ISID_LEN) {
 				printk(KERN_ERR "APTPL metadata initiator_isid"
 					"= exceeds PR_REG_ISID_LEN: %d\n",
 					PR_REG_ISID_LEN);
@@ -1575,7 +1571,7 @@
 				ret = -ENOMEM;
 				goto out;
 			}
-			if (strlen(t_port) > PR_APTPL_MAX_TPORT_LEN) {
+			if (strlen(t_port) >= PR_APTPL_MAX_TPORT_LEN) {
 				printk(KERN_ERR "APTPL metadata target_node="
 					" exceeds PR_APTPL_MAX_TPORT_LEN: %d\n",
 					PR_APTPL_MAX_TPORT_LEN);
@@ -3056,7 +3052,7 @@
 	int ret;
 
 	memset(buf, 0, TARGET_CORE_NAME_MAX_LEN);
-	if (strlen(name) > TARGET_CORE_NAME_MAX_LEN) {
+	if (strlen(name) >= TARGET_CORE_NAME_MAX_LEN) {
 		printk(KERN_ERR "Passed *name strlen(): %d exceeds"
 			" TARGET_CORE_NAME_MAX_LEN: %d\n", (int)strlen(name),
 			TARGET_CORE_NAME_MAX_LEN);
diff -druN linux-2.6.39-libre/drivers/target/target_core_device.c linux-3.0-rc7-libre/drivers/target/target_core_device.c
--- linux-2.6.39-libre/drivers/target/target_core_device.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/target/target_core_device.c	2011-07-11 19:51:52.000000000 -0400
@@ -38,6 +38,7 @@
 #include <net/sock.h>
 #include <net/tcp.h>
 #include <scsi/scsi.h>
+#include <scsi/scsi_device.h>
 
 #include <target/target_core_base.h>
 #include <target/target_core_device.h>
@@ -150,13 +151,13 @@
 
 	{
 	struct se_device *dev = se_lun->lun_se_dev;
-	spin_lock(&dev->stats_lock);
+	spin_lock_irq(&dev->stats_lock);
 	dev->num_cmds++;
 	if (se_cmd->data_direction == DMA_TO_DEVICE)
 		dev->write_bytes += se_cmd->data_length;
 	else if (se_cmd->data_direction == DMA_FROM_DEVICE)
 		dev->read_bytes += se_cmd->data_length;
-	spin_unlock(&dev->stats_lock);
+	spin_unlock_irq(&dev->stats_lock);
 	}
 
 	/*
@@ -191,7 +192,7 @@
 			&SE_NODE_ACL(se_sess)->device_list[unpacked_lun];
 	if (deve->lun_flags & TRANSPORT_LUNFLAGS_INITIATOR_ACCESS) {
 		se_lun = se_cmd->se_lun = se_tmr->tmr_lun = deve->se_lun;
-		dev = se_tmr->tmr_dev = se_lun->lun_se_dev;
+		dev = se_lun->lun_se_dev;
 		se_cmd->pr_res_key = deve->pr_res_key;
 		se_cmd->orig_fe_lun = unpacked_lun;
 		se_cmd->se_orig_obj_ptr = SE_LUN(se_cmd)->lun_se_dev;
@@ -215,6 +216,7 @@
 		se_cmd->se_cmd_flags |= SCF_SCSI_CDB_EXCEPTION;
 		return -1;
 	}
+	se_tmr->tmr_dev = dev;
 
 	spin_lock(&dev->se_tmr_lock);
 	list_add_tail(&se_tmr->tmr_list, &dev->dev_tmr_list);
@@ -658,8 +660,7 @@
 	struct se_session *se_sess = SE_SESS(se_cmd);
 	struct se_task *se_task;
 	unsigned char *buf = (unsigned char *)T_TASK(se_cmd)->t_task_buf;
-	u32 cdb_offset = 0, lun_count = 0, offset = 8;
-	u64 i, lun;
+	u32 cdb_offset = 0, lun_count = 0, offset = 8, i;
 
 	list_for_each_entry(se_task, &T_TASK(se_cmd)->t_task_list, t_list)
 		break;
@@ -675,15 +676,7 @@
 	 * a $FABRIC_MOD.  In that case, report LUN=0 only.
 	 */
 	if (!(se_sess)) {
-		lun = 0;
-		buf[offset++] = ((lun >> 56) & 0xff);
-		buf[offset++] = ((lun >> 48) & 0xff);
-		buf[offset++] = ((lun >> 40) & 0xff);
-		buf[offset++] = ((lun >> 32) & 0xff);
-		buf[offset++] = ((lun >> 24) & 0xff);
-		buf[offset++] = ((lun >> 16) & 0xff);
-		buf[offset++] = ((lun >> 8) & 0xff);
-		buf[offset++] = (lun & 0xff);
+		int_to_scsilun(0, (struct scsi_lun *)&buf[offset]);
 		lun_count = 1;
 		goto done;
 	}
@@ -703,15 +696,8 @@
 		if ((cdb_offset + 8) >= se_cmd->data_length)
 			continue;
 
-		lun = cpu_to_be64(CMD_TFO(se_cmd)->pack_lun(deve->mapped_lun));
-		buf[offset++] = ((lun >> 56) & 0xff);
-		buf[offset++] = ((lun >> 48) & 0xff);
-		buf[offset++] = ((lun >> 40) & 0xff);
-		buf[offset++] = ((lun >> 32) & 0xff);
-		buf[offset++] = ((lun >> 24) & 0xff);
-		buf[offset++] = ((lun >> 16) & 0xff);
-		buf[offset++] = ((lun >> 8) & 0xff);
-		buf[offset++] = (lun & 0xff);
+		int_to_scsilun(deve->mapped_lun, (struct scsi_lun *)&buf[offset]);
+		offset += 8;
 		cdb_offset += 8;
 	}
 	spin_unlock_irq(&SE_NODE_ACL(se_sess)->device_list_lock);
@@ -1445,7 +1431,7 @@
 	struct se_lun_acl *lacl;
 	struct se_node_acl *nacl;
 
-	if (strlen(initiatorname) > TRANSPORT_IQN_LEN) {
+	if (strlen(initiatorname) >= TRANSPORT_IQN_LEN) {
 		printk(KERN_ERR "%s InitiatorName exceeds maximum size.\n",
 			TPG_TFO(tpg)->get_fabric_name());
 		*ret = -EOVERFLOW;
diff -druN linux-2.6.39-libre/drivers/target/target_core_pr.c linux-3.0-rc7-libre/drivers/target/target_core_pr.c
--- linux-2.6.39-libre/drivers/target/target_core_pr.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/target/target_core_pr.c	2011-07-11 19:51:52.000000000 -0400
@@ -1916,7 +1916,7 @@
 				pr_reg->pr_res_mapped_lun);
 		}
 
-		if ((len + strlen(tmp) > pr_aptpl_buf_len)) {
+		if ((len + strlen(tmp) >= pr_aptpl_buf_len)) {
 			printk(KERN_ERR "Unable to update renaming"
 				" APTPL metadata\n");
 			spin_unlock(&T10_RES(su_dev)->registration_lock);
@@ -1934,7 +1934,7 @@
 			TPG_TFO(tpg)->tpg_get_tag(tpg),
 			lun->lun_sep->sep_rtpi, lun->unpacked_lun, reg_count);
 
-		if ((len + strlen(tmp) > pr_aptpl_buf_len)) {
+		if ((len + strlen(tmp) >= pr_aptpl_buf_len)) {
 			printk(KERN_ERR "Unable to update renaming"
 				" APTPL metadata\n");
 			spin_unlock(&T10_RES(su_dev)->registration_lock);
@@ -1986,7 +1986,7 @@
 	memset(iov, 0, sizeof(struct iovec));
 	memset(path, 0, 512);
 
-	if (strlen(&wwn->unit_serial[0]) > 512) {
+	if (strlen(&wwn->unit_serial[0]) >= 512) {
 		printk(KERN_ERR "WWN value for struct se_device does not fit"
 			" into path buffer\n");
 		return -1;
diff -druN linux-2.6.39-libre/drivers/target/target_core_pscsi.c linux-3.0-rc7-libre/drivers/target/target_core_pscsi.c
--- linux-2.6.39-libre/drivers/target/target_core_pscsi.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/target/target_core_pscsi.c	2011-07-11 19:51:52.000000000 -0400
@@ -41,7 +41,7 @@
 #include <scsi/scsi_device.h>
 #include <scsi/scsi_cmnd.h>
 #include <scsi/scsi_host.h>
-#include <scsi/libsas.h> /* For TASK_ATTR_* */
+#include <scsi/scsi_tcq.h>
 
 #include <target/target_core_base.h>
 #include <target/target_core_device.h>
@@ -911,7 +911,7 @@
 	 * descriptor
 	 */
 	blk_execute_rq_nowait(pdv->pdv_sd->request_queue, NULL, pt->pscsi_req,
-			(task->task_se_cmd->sam_task_attr == TASK_ATTR_HOQ),
+			(task->task_se_cmd->sam_task_attr == MSG_HEAD_TAG),
 			pscsi_req_done);
 
 	return PYX_TRANSPORT_SENT_TO_TRANSPORT;
diff -druN linux-2.6.39-libre/drivers/target/target_core_tmr.c linux-3.0-rc7-libre/drivers/target/target_core_tmr.c
--- linux-2.6.39-libre/drivers/target/target_core_tmr.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/target/target_core_tmr.c	2011-07-11 19:51:52.000000000 -0400
@@ -55,7 +55,8 @@
 {
 	struct se_tmr_req *tmr;
 
-	tmr = kmem_cache_zalloc(se_tmr_req_cache, GFP_KERNEL);
+	tmr = kmem_cache_zalloc(se_tmr_req_cache, (in_interrupt()) ?
+					GFP_ATOMIC : GFP_KERNEL);
 	if (!(tmr)) {
 		printk(KERN_ERR "Unable to allocate struct se_tmr_req\n");
 		return ERR_PTR(-ENOMEM);
@@ -74,10 +75,16 @@
 {
 	struct se_device *dev = tmr->tmr_dev;
 
+	if (!dev) {
+		kmem_cache_free(se_tmr_req_cache, tmr);
+		return;
+	}
+
 	spin_lock(&dev->se_tmr_lock);
 	list_del(&tmr->tmr_list);
-	kmem_cache_free(se_tmr_req_cache, tmr);
 	spin_unlock(&dev->se_tmr_lock);
+
+	kmem_cache_free(se_tmr_req_cache, tmr);
 }
 
 static void core_tmr_handle_tas_abort(
@@ -398,9 +405,9 @@
 		printk(KERN_INFO "LUN_RESET: SCSI-2 Released reservation\n");
 	}
 
-	spin_lock(&dev->stats_lock);
+	spin_lock_irq(&dev->stats_lock);
 	dev->num_resets++;
-	spin_unlock(&dev->stats_lock);
+	spin_unlock_irq(&dev->stats_lock);
 
 	DEBUG_LR("LUN_RESET: %s for [%s] Complete\n",
 			(preempt_and_abort_list) ? "Preempt" : "TMR",
diff -druN linux-2.6.39-libre/drivers/target/target_core_transport.c linux-3.0-rc7-libre/drivers/target/target_core_transport.c
--- linux-2.6.39-libre/drivers/target/target_core_transport.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/target/target_core_transport.c	2011-07-11 19:51:52.000000000 -0400
@@ -42,7 +42,7 @@
 #include <net/tcp.h>
 #include <scsi/scsi.h>
 #include <scsi/scsi_cmnd.h>
-#include <scsi/libsas.h> /* For TASK_ATTR_* */
+#include <scsi/scsi_tcq.h>
 
 #include <target/target_core_base.h>
 #include <target/target_core_device.h>
@@ -536,13 +536,13 @@
 void transport_deregister_session_configfs(struct se_session *se_sess)
 {
 	struct se_node_acl *se_nacl;
-
+	unsigned long flags;
 	/*
 	 * Used by struct se_node_acl's under ConfigFS to locate active struct se_session
 	 */
 	se_nacl = se_sess->se_node_acl;
 	if ((se_nacl)) {
-		spin_lock_irq(&se_nacl->nacl_sess_lock);
+		spin_lock_irqsave(&se_nacl->nacl_sess_lock, flags);
 		list_del(&se_sess->sess_acl_list);
 		/*
 		 * If the session list is empty, then clear the pointer.
@@ -556,7 +556,7 @@
 					se_nacl->acl_sess_list.prev,
 					struct se_session, sess_acl_list);
 		}
-		spin_unlock_irq(&se_nacl->nacl_sess_lock);
+		spin_unlock_irqrestore(&se_nacl->nacl_sess_lock, flags);
 	}
 }
 EXPORT_SYMBOL(transport_deregister_session_configfs);
@@ -762,7 +762,6 @@
 	transport_all_task_dev_remove_state(cmd);
 	spin_unlock_irqrestore(&T_TASK(cmd)->t_state_lock, flags);
 
-	transport_free_dev_tasks(cmd);
 
 check_lun:
 	spin_lock_irqsave(&lun->lun_cmd_lock, flags);
@@ -1075,7 +1074,7 @@
 	 * head of the struct se_device->execute_task_list, and task_prev
 	 * after that for each subsequent task
 	 */
-	if (task->task_se_cmd->sam_task_attr == TASK_ATTR_HOQ) {
+	if (task->task_se_cmd->sam_task_attr == MSG_HEAD_TAG) {
 		list_add(&task->t_execute_list,
 				(task_prev != NULL) ?
 				&task_prev->t_execute_list :
@@ -1195,6 +1194,7 @@
 		break;
 
 	list_del(&task->t_execute_list);
+	atomic_set(&task->task_execute_queue, 0);
 	atomic_dec(&dev->execute_tasks);
 
 	return task;
@@ -1210,8 +1210,14 @@
 {
 	unsigned long flags;
 
+	if (atomic_read(&task->task_execute_queue) == 0) {
+		dump_stack();
+		return;
+	}
+
 	spin_lock_irqsave(&dev->execute_task_lock, flags);
 	list_del(&task->t_execute_list);
+	atomic_set(&task->task_execute_queue, 0);
 	atomic_dec(&dev->execute_tasks);
 	spin_unlock_irqrestore(&dev->execute_task_lock, flags);
 }
@@ -1867,7 +1873,7 @@
 	if (SE_DEV(cmd)->dev_task_attr_type != SAM_TASK_ATTR_EMULATED)
 		return 0;
 
-	if (cmd->sam_task_attr == TASK_ATTR_ACA) {
+	if (cmd->sam_task_attr == MSG_ACA_TAG) {
 		DEBUG_STA("SAM Task Attribute ACA"
 			" emulation is not supported\n");
 		return -1;
@@ -2058,6 +2064,13 @@
 }
 EXPORT_SYMBOL(transport_generic_handle_tmr);
 
+void transport_generic_free_cmd_intr(
+	struct se_cmd *cmd)
+{
+	transport_add_cmd_to_queue(cmd, TRANSPORT_FREE_CMD_INTR);
+}
+EXPORT_SYMBOL(transport_generic_free_cmd_intr);
+
 static int transport_stop_tasks_for_cmd(struct se_cmd *cmd)
 {
 	struct se_task *task, *task_tmp;
@@ -2128,7 +2141,7 @@
 {
 	unsigned long flags;
 
-	spin_lock_irqsave(&SE_HBA(dev)->hba_queue_lock, flags);;
+	spin_lock_irqsave(&SE_HBA(dev)->hba_queue_lock, flags);
 	atomic_inc(&dev->depth_left);
 	atomic_inc(&SE_HBA(dev)->left_queue_depth);
 	spin_unlock_irqrestore(&SE_HBA(dev)->hba_queue_lock, flags);
@@ -2504,7 +2517,7 @@
 	 * Check for the existence of HEAD_OF_QUEUE, and if true return 1
 	 * to allow the passed struct se_cmd list of tasks to the front of the list.
 	 */
-	 if (cmd->sam_task_attr == TASK_ATTR_HOQ) {
+	 if (cmd->sam_task_attr == MSG_HEAD_TAG) {
 		atomic_inc(&SE_DEV(cmd)->dev_hoq_count);
 		smp_mb__after_atomic_inc();
 		DEBUG_STA("Added HEAD_OF_QUEUE for CDB:"
@@ -2512,7 +2525,7 @@
 			T_TASK(cmd)->t_task_cdb[0],
 			cmd->se_ordered_id);
 		return 1;
-	} else if (cmd->sam_task_attr == TASK_ATTR_ORDERED) {
+	} else if (cmd->sam_task_attr == MSG_ORDERED_TAG) {
 		spin_lock(&SE_DEV(cmd)->ordered_cmd_lock);
 		list_add_tail(&cmd->se_ordered_list,
 				&SE_DEV(cmd)->ordered_cmd_list);
@@ -3411,7 +3424,7 @@
 		 * See spc4r17 section 5.3
 		 */
 		if (SE_DEV(cmd)->dev_task_attr_type == SAM_TASK_ATTR_EMULATED)
-			cmd->sam_task_attr = TASK_ATTR_HOQ;
+			cmd->sam_task_attr = MSG_HEAD_TAG;
 		cmd->se_cmd_flags |= SCF_SCSI_CONTROL_NONSG_IO_CDB;
 		break;
 	case READ_BUFFER:
@@ -3619,7 +3632,7 @@
 		 * See spc4r17 section 5.3
 		 */
 		if (SE_DEV(cmd)->dev_task_attr_type == SAM_TASK_ATTR_EMULATED)
-			cmd->sam_task_attr = TASK_ATTR_HOQ;
+			cmd->sam_task_attr = MSG_HEAD_TAG;
 		cmd->se_cmd_flags |= SCF_SCSI_CONTROL_NONSG_IO_CDB;
 		break;
 	default:
@@ -3777,21 +3790,21 @@
 	struct se_cmd *cmd_p, *cmd_tmp;
 	int new_active_tasks = 0;
 
-	if (cmd->sam_task_attr == TASK_ATTR_SIMPLE) {
+	if (cmd->sam_task_attr == MSG_SIMPLE_TAG) {
 		atomic_dec(&dev->simple_cmds);
 		smp_mb__after_atomic_dec();
 		dev->dev_cur_ordered_id++;
 		DEBUG_STA("Incremented dev->dev_cur_ordered_id: %u for"
 			" SIMPLE: %u\n", dev->dev_cur_ordered_id,
 			cmd->se_ordered_id);
-	} else if (cmd->sam_task_attr == TASK_ATTR_HOQ) {
+	} else if (cmd->sam_task_attr == MSG_HEAD_TAG) {
 		atomic_dec(&dev->dev_hoq_count);
 		smp_mb__after_atomic_dec();
 		dev->dev_cur_ordered_id++;
 		DEBUG_STA("Incremented dev_cur_ordered_id: %u for"
 			" HEAD_OF_QUEUE: %u\n", dev->dev_cur_ordered_id,
 			cmd->se_ordered_id);
-	} else if (cmd->sam_task_attr == TASK_ATTR_ORDERED) {
+	} else if (cmd->sam_task_attr == MSG_ORDERED_TAG) {
 		spin_lock(&dev->ordered_cmd_lock);
 		list_del(&cmd->se_ordered_list);
 		atomic_dec(&dev->dev_ordered_sync);
@@ -3824,7 +3837,7 @@
 		new_active_tasks++;
 
 		spin_lock(&dev->delayed_cmd_lock);
-		if (cmd_p->sam_task_attr == TASK_ATTR_ORDERED)
+		if (cmd_p->sam_task_attr == MSG_ORDERED_TAG)
 			break;
 	}
 	spin_unlock(&dev->delayed_cmd_lock);
@@ -4776,18 +4789,20 @@
 				sg_end_cur->page_link &= ~0x02;
 
 				sg_chain(sg_head, task_sg_num, sg_head_cur);
-				sg_count += (task->task_sg_num + 1);
-			} else
 				sg_count += task->task_sg_num;
+				task_sg_num = (task->task_sg_num + 1);
+			} else {
+				sg_chain(sg_head, task_sg_num, sg_head_cur);
+				sg_count += task->task_sg_num;
+				task_sg_num = task->task_sg_num;
+			}
 
 			sg_head = sg_head_cur;
 			sg_link = sg_link_cur;
-			task_sg_num = task->task_sg_num;
 			continue;
 		}
 		sg_head = sg_first = &task->task_sg[0];
 		sg_link = &task->task_sg[task->task_sg_num];
-		task_sg_num = task->task_sg_num;
 		/*
 		 * Check for single task..
 		 */
@@ -4798,9 +4813,12 @@
 			 */
 			sg_end = &task->task_sg[task->task_sg_num - 1];
 			sg_end->page_link &= ~0x02;
-			sg_count += (task->task_sg_num + 1);
-		} else
 			sg_count += task->task_sg_num;
+			task_sg_num = (task->task_sg_num + 1);
+		} else {
+			sg_count += task->task_sg_num;
+			task_sg_num = task->task_sg_num;
+		}
 	}
 	/*
 	 * Setup the starting pointer and total t_tasks_sg_linked_no including
@@ -4809,21 +4827,20 @@
 	T_TASK(cmd)->t_tasks_sg_chained = sg_first;
 	T_TASK(cmd)->t_tasks_sg_chained_no = sg_count;
 
-	DEBUG_CMD_M("Setup T_TASK(cmd)->t_tasks_sg_chained: %p and"
-		" t_tasks_sg_chained_no: %u\n", T_TASK(cmd)->t_tasks_sg_chained,
+	DEBUG_CMD_M("Setup cmd: %p T_TASK(cmd)->t_tasks_sg_chained: %p and"
+		" t_tasks_sg_chained_no: %u\n", cmd, T_TASK(cmd)->t_tasks_sg_chained,
 		T_TASK(cmd)->t_tasks_sg_chained_no);
 
 	for_each_sg(T_TASK(cmd)->t_tasks_sg_chained, sg,
 			T_TASK(cmd)->t_tasks_sg_chained_no, i) {
 
-		DEBUG_CMD_M("SG: %p page: %p length: %d offset: %d\n",
-			sg, sg_page(sg), sg->length, sg->offset);
+		DEBUG_CMD_M("SG[%d]: %p page: %p length: %d offset: %d, magic: 0x%08x\n",
+			i, sg, sg_page(sg), sg->length, sg->offset, sg->sg_magic);
 		if (sg_is_chain(sg))
 			DEBUG_CMD_M("SG: %p sg_is_chain=1\n", sg);
 		if (sg_is_last(sg))
 			DEBUG_CMD_M("SG: %p sg_is_last=1\n", sg);
 	}
-
 }
 EXPORT_SYMBOL(transport_do_task_sg_chain);
 
@@ -5297,6 +5314,8 @@
 		if (wait_for_tasks && cmd->transport_wait_for_tasks)
 			cmd->transport_wait_for_tasks(cmd, 0, 0);
 
+		transport_free_dev_tasks(cmd);
+
 		transport_generic_remove(cmd, release_to_pool,
 				session_reinstatement);
 	}
@@ -6132,6 +6151,9 @@
 		case TRANSPORT_REMOVE:
 			transport_generic_remove(cmd, 1, 0);
 			break;
+		case TRANSPORT_FREE_CMD_INTR:
+			transport_generic_free_cmd(cmd, 0, 1, 0);
+			break;
 		case TRANSPORT_PROCESS_TMR:
 			transport_generic_do_tmr(cmd);
 			break;
diff -druN linux-2.6.39-libre/drivers/target/tcm_fc/Kconfig linux-3.0-rc7-libre/drivers/target/tcm_fc/Kconfig
--- linux-2.6.39-libre/drivers/target/tcm_fc/Kconfig	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/target/tcm_fc/Kconfig	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,5 @@
+config TCM_FC
+	tristate "TCM_FC fabric Plugin"
+	depends on LIBFC
+	help
+	Say Y here to enable the TCM FC plugin for accessing FC fabrics in TCM
diff -druN linux-2.6.39-libre/drivers/target/tcm_fc/Makefile linux-3.0-rc7-libre/drivers/target/tcm_fc/Makefile
--- linux-2.6.39-libre/drivers/target/tcm_fc/Makefile	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/target/tcm_fc/Makefile	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,15 @@
+EXTRA_CFLAGS += -I$(srctree)/drivers/target/ \
+		-I$(srctree)/drivers/scsi/ \
+		-I$(srctree)/include/scsi/ \
+		-I$(srctree)/drivers/target/tcm_fc/
+
+tcm_fc-y +=	tfc_cmd.o \
+		tfc_conf.o \
+		tfc_io.o \
+		tfc_sess.o
+
+obj-$(CONFIG_TCM_FC)	+= tcm_fc.o
+
+ifdef CONFIGFS_TCM_FC_DEBUG
+EXTRA_CFLAGS	+= -DTCM_FC_DEBUG
+endif
diff -druN linux-2.6.39-libre/drivers/target/tcm_fc/tcm_fc.h linux-3.0-rc7-libre/drivers/target/tcm_fc/tcm_fc.h
--- linux-2.6.39-libre/drivers/target/tcm_fc/tcm_fc.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/target/tcm_fc/tcm_fc.h	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,215 @@
+/*
+ * Copyright (c) 2010 Cisco Systems, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+#ifndef __TCM_FC_H__
+#define __TCM_FC_H__
+
+#define FT_VERSION "0.3"
+
+#define FT_NAMELEN 32		/* length of ASCII WWPNs including pad */
+#define FT_TPG_NAMELEN 32	/* max length of TPG name */
+#define FT_LUN_NAMELEN 32	/* max length of LUN name */
+
+/*
+ * Debug options.
+ */
+#define FT_DEBUG_CONF	0x01	/* configuration messages */
+#define	FT_DEBUG_SESS	0x02	/* session messages */
+#define	FT_DEBUG_TM	0x04	/* TM operations */
+#define	FT_DEBUG_IO	0x08	/* I/O commands */
+#define	FT_DEBUG_DATA	0x10	/* Data transfer */
+
+extern unsigned int ft_debug_logging;	/* debug options */
+
+#define FT_DEBUG(mask, fmt, args...)					\
+	do {								\
+		if (ft_debug_logging & (mask))				\
+			printk(KERN_INFO "tcm_fc: %s: " fmt,		\
+				__func__, ##args);			\
+	} while (0)
+
+#define	FT_CONF_DBG(fmt, args...)	FT_DEBUG(FT_DEBUG_CONF, fmt, ##args)
+#define	FT_SESS_DBG(fmt, args...)	FT_DEBUG(FT_DEBUG_SESS, fmt, ##args)
+#define	FT_TM_DBG(fmt, args...)		FT_DEBUG(FT_DEBUG_TM, fmt, ##args)
+#define	FT_IO_DBG(fmt, args...)		FT_DEBUG(FT_DEBUG_IO, fmt, ##args)
+#define	FT_DATA_DBG(fmt, args...)	FT_DEBUG(FT_DEBUG_DATA, fmt, ##args)
+
+struct ft_transport_id {
+	__u8	format;
+	__u8	__resvd1[7];
+	__u8	wwpn[8];
+	__u8	__resvd2[8];
+} __attribute__((__packed__));
+
+/*
+ * Session (remote port).
+ */
+struct ft_sess {
+	u32 port_id;			/* for hash lookup use only */
+	u32 params;
+	u16 max_frame;			/* maximum frame size */
+	u64 port_name;			/* port name for transport ID */
+	struct ft_tport *tport;
+	struct se_session *se_sess;
+	struct hlist_node hash;		/* linkage in ft_sess_hash table */
+	struct rcu_head rcu;
+	struct kref kref;		/* ref for hash and outstanding I/Os */
+};
+
+/*
+ * Hash table of sessions per local port.
+ * Hash lookup by remote port FC_ID.
+ */
+#define	FT_SESS_HASH_BITS	6
+#define	FT_SESS_HASH_SIZE	(1 << FT_SESS_HASH_BITS)
+
+/*
+ * Per local port data.
+ * This is created only after a TPG exists that allows target function
+ * for the local port.  If the TPG exists, this is allocated when
+ * we're notified that the local port has been created, or when
+ * the first PRLI provider callback is received.
+ */
+struct ft_tport {
+	struct fc_lport *lport;
+	struct ft_tpg *tpg;		/* NULL if TPG deleted before tport */
+	u32	sess_count;		/* number of sessions in hash */
+	struct rcu_head rcu;
+	struct hlist_head hash[FT_SESS_HASH_SIZE];	/* list of sessions */
+};
+
+/*
+ * Node ID and authentication.
+ */
+struct ft_node_auth {
+	u64	port_name;
+	u64	node_name;
+};
+
+/*
+ * Node ACL for FC remote port session.
+ */
+struct ft_node_acl {
+	struct ft_node_auth node_auth;
+	struct se_node_acl se_node_acl;
+};
+
+struct ft_lun {
+	u32 index;
+	char name[FT_LUN_NAMELEN];
+};
+
+/*
+ * Target portal group (local port).
+ */
+struct ft_tpg {
+	u32 index;
+	struct ft_lport_acl *lport_acl;
+	struct ft_tport *tport;		/* active tport or NULL */
+	struct list_head list;		/* linkage in ft_lport_acl tpg_list */
+	struct list_head lun_list;	/* head of LUNs */
+	struct se_portal_group se_tpg;
+	struct task_struct *thread;	/* processing thread */
+	struct se_queue_obj qobj;	/* queue for processing thread */
+};
+
+struct ft_lport_acl {
+	u64 wwpn;
+	char name[FT_NAMELEN];
+	struct list_head list;
+	struct list_head tpg_list;
+	struct se_wwn fc_lport_wwn;
+};
+
+enum ft_cmd_state {
+	FC_CMD_ST_NEW = 0,
+	FC_CMD_ST_REJ
+};
+
+/*
+ * Commands
+ */
+struct ft_cmd {
+	enum ft_cmd_state state;
+	u32 lun;                        /* LUN from request */
+	struct ft_sess *sess;		/* session held for cmd */
+	struct fc_seq *seq;		/* sequence in exchange mgr */
+	struct se_cmd se_cmd;		/* Local TCM I/O descriptor */
+	struct fc_frame *req_frame;
+	unsigned char *cdb;		/* pointer to CDB inside frame */
+	u32 write_data_len;		/* data received on writes */
+	struct se_queue_req se_req;
+	/* Local sense buffer */
+	unsigned char ft_sense_buffer[TRANSPORT_SENSE_BUFFER];
+	u32 was_ddp_setup:1;		/* Set only if ddp is setup */
+	struct scatterlist *sg;		/* Set only if DDP is setup */
+	u32 sg_cnt;			/* No. of item in scatterlist */
+};
+
+extern struct list_head ft_lport_list;
+extern struct mutex ft_lport_lock;
+extern struct fc4_prov ft_prov;
+extern struct target_fabric_configfs *ft_configfs;
+
+/*
+ * Fabric methods.
+ */
+
+/*
+ * Session ops.
+ */
+void ft_sess_put(struct ft_sess *);
+int ft_sess_shutdown(struct se_session *);
+void ft_sess_close(struct se_session *);
+void ft_sess_stop(struct se_session *, int, int);
+int ft_sess_logged_in(struct se_session *);
+u32 ft_sess_get_index(struct se_session *);
+u32 ft_sess_get_port_name(struct se_session *, unsigned char *, u32);
+void ft_sess_set_erl0(struct se_session *);
+
+void ft_lport_add(struct fc_lport *, void *);
+void ft_lport_del(struct fc_lport *, void *);
+int ft_lport_notify(struct notifier_block *, unsigned long, void *);
+
+/*
+ * IO methods.
+ */
+void ft_check_stop_free(struct se_cmd *);
+void ft_release_cmd(struct se_cmd *);
+int ft_queue_status(struct se_cmd *);
+int ft_queue_data_in(struct se_cmd *);
+int ft_write_pending(struct se_cmd *);
+int ft_write_pending_status(struct se_cmd *);
+u32 ft_get_task_tag(struct se_cmd *);
+int ft_get_cmd_state(struct se_cmd *);
+void ft_new_cmd_failure(struct se_cmd *);
+int ft_queue_tm_resp(struct se_cmd *);
+int ft_is_state_remove(struct se_cmd *);
+
+/*
+ * other internal functions.
+ */
+int ft_thread(void *);
+void ft_recv_req(struct ft_sess *, struct fc_frame *);
+struct ft_tpg *ft_lport_find_tpg(struct fc_lport *);
+struct ft_node_acl *ft_acl_get(struct ft_tpg *, struct fc_rport_priv *);
+
+void ft_recv_write_data(struct ft_cmd *, struct fc_frame *);
+void ft_dump_cmd(struct ft_cmd *, const char *caller);
+
+ssize_t ft_format_wwn(char *, size_t, u64);
+
+#endif /* __TCM_FC_H__ */
diff -druN linux-2.6.39-libre/drivers/target/tcm_fc/tfc_cmd.c linux-3.0-rc7-libre/drivers/target/tcm_fc/tfc_cmd.c
--- linux-2.6.39-libre/drivers/target/tcm_fc/tfc_cmd.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/target/tcm_fc/tfc_cmd.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,716 @@
+/*
+ * Copyright (c) 2010 Cisco Systems, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+/* XXX TBD some includes may be extraneous */
+
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/version.h>
+#include <generated/utsrelease.h>
+#include <linux/utsname.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/kthread.h>
+#include <linux/types.h>
+#include <linux/string.h>
+#include <linux/configfs.h>
+#include <linux/ctype.h>
+#include <linux/hash.h>
+#include <asm/unaligned.h>
+#include <scsi/scsi.h>
+#include <scsi/scsi_host.h>
+#include <scsi/scsi_device.h>
+#include <scsi/scsi_cmnd.h>
+#include <scsi/scsi_tcq.h>
+#include <scsi/libfc.h>
+#include <scsi/fc_encode.h>
+
+#include <target/target_core_base.h>
+#include <target/target_core_transport.h>
+#include <target/target_core_fabric_ops.h>
+#include <target/target_core_device.h>
+#include <target/target_core_tpg.h>
+#include <target/target_core_configfs.h>
+#include <target/target_core_base.h>
+#include <target/target_core_tmr.h>
+#include <target/configfs_macros.h>
+
+#include "tcm_fc.h"
+
+/*
+ * Dump cmd state for debugging.
+ */
+void ft_dump_cmd(struct ft_cmd *cmd, const char *caller)
+{
+	struct fc_exch *ep;
+	struct fc_seq *sp;
+	struct se_cmd *se_cmd;
+	struct se_mem *mem;
+	struct se_transport_task *task;
+
+	if (!(ft_debug_logging & FT_DEBUG_IO))
+		return;
+
+	se_cmd = &cmd->se_cmd;
+	printk(KERN_INFO "%s: cmd %p state %d sess %p seq %p se_cmd %p\n",
+		caller, cmd, cmd->state, cmd->sess, cmd->seq, se_cmd);
+	printk(KERN_INFO "%s: cmd %p cdb %p\n",
+		caller, cmd, cmd->cdb);
+	printk(KERN_INFO "%s: cmd %p lun %d\n", caller, cmd, cmd->lun);
+
+	task = T_TASK(se_cmd);
+	printk(KERN_INFO "%s: cmd %p task %p se_num %u buf %p len %u se_cmd_flags <0x%x>\n",
+	       caller, cmd, task, task->t_tasks_se_num,
+	       task->t_task_buf, se_cmd->data_length, se_cmd->se_cmd_flags);
+	if (task->t_mem_list)
+		list_for_each_entry(mem, task->t_mem_list, se_list)
+			printk(KERN_INFO "%s: cmd %p mem %p page %p "
+			       "len 0x%x off 0x%x\n",
+			       caller, cmd, mem,
+			       mem->se_page, mem->se_len, mem->se_off);
+	sp = cmd->seq;
+	if (sp) {
+		ep = fc_seq_exch(sp);
+		printk(KERN_INFO "%s: cmd %p sid %x did %x "
+			"ox_id %x rx_id %x seq_id %x e_stat %x\n",
+			caller, cmd, ep->sid, ep->did, ep->oxid, ep->rxid,
+			sp->id, ep->esb_stat);
+	}
+	print_hex_dump(KERN_INFO, "ft_dump_cmd ", DUMP_PREFIX_NONE,
+		16, 4, cmd->cdb, MAX_COMMAND_SIZE, 0);
+}
+
+static void ft_queue_cmd(struct ft_sess *sess, struct ft_cmd *cmd)
+{
+	struct se_queue_obj *qobj;
+	unsigned long flags;
+
+	qobj = &sess->tport->tpg->qobj;
+	spin_lock_irqsave(&qobj->cmd_queue_lock, flags);
+	list_add_tail(&cmd->se_req.qr_list, &qobj->qobj_list);
+	spin_unlock_irqrestore(&qobj->cmd_queue_lock, flags);
+	atomic_inc(&qobj->queue_cnt);
+	wake_up_interruptible(&qobj->thread_wq);
+}
+
+static struct ft_cmd *ft_dequeue_cmd(struct se_queue_obj *qobj)
+{
+	unsigned long flags;
+	struct se_queue_req *qr;
+
+	spin_lock_irqsave(&qobj->cmd_queue_lock, flags);
+	if (list_empty(&qobj->qobj_list)) {
+		spin_unlock_irqrestore(&qobj->cmd_queue_lock, flags);
+		return NULL;
+	}
+	qr = list_first_entry(&qobj->qobj_list, struct se_queue_req, qr_list);
+	list_del(&qr->qr_list);
+	atomic_dec(&qobj->queue_cnt);
+	spin_unlock_irqrestore(&qobj->cmd_queue_lock, flags);
+	return container_of(qr, struct ft_cmd, se_req);
+}
+
+static void ft_free_cmd(struct ft_cmd *cmd)
+{
+	struct fc_frame *fp;
+	struct fc_lport *lport;
+
+	if (!cmd)
+		return;
+	fp = cmd->req_frame;
+	lport = fr_dev(fp);
+	if (fr_seq(fp))
+		lport->tt.seq_release(fr_seq(fp));
+	fc_frame_free(fp);
+	ft_sess_put(cmd->sess);	/* undo get from lookup at recv */
+	kfree(cmd);
+}
+
+void ft_release_cmd(struct se_cmd *se_cmd)
+{
+	struct ft_cmd *cmd = container_of(se_cmd, struct ft_cmd, se_cmd);
+
+	ft_free_cmd(cmd);
+}
+
+void ft_check_stop_free(struct se_cmd *se_cmd)
+{
+	transport_generic_free_cmd(se_cmd, 0, 1, 0);
+}
+
+/*
+ * Send response.
+ */
+int ft_queue_status(struct se_cmd *se_cmd)
+{
+	struct ft_cmd *cmd = container_of(se_cmd, struct ft_cmd, se_cmd);
+	struct fc_frame *fp;
+	struct fcp_resp_with_ext *fcp;
+	struct fc_lport *lport;
+	struct fc_exch *ep;
+	size_t len;
+
+	ft_dump_cmd(cmd, __func__);
+	ep = fc_seq_exch(cmd->seq);
+	lport = ep->lp;
+	len = sizeof(*fcp) + se_cmd->scsi_sense_length;
+	fp = fc_frame_alloc(lport, len);
+	if (!fp) {
+		/* XXX shouldn't just drop it - requeue and retry? */
+		return 0;
+	}
+	fcp = fc_frame_payload_get(fp, len);
+	memset(fcp, 0, len);
+	fcp->resp.fr_status = se_cmd->scsi_status;
+
+	len = se_cmd->scsi_sense_length;
+	if (len) {
+		fcp->resp.fr_flags |= FCP_SNS_LEN_VAL;
+		fcp->ext.fr_sns_len = htonl(len);
+		memcpy((fcp + 1), se_cmd->sense_buffer, len);
+	}
+
+	/*
+	 * Test underflow and overflow with one mask.  Usually both are off.
+	 * Bidirectional commands are not handled yet.
+	 */
+	if (se_cmd->se_cmd_flags & (SCF_OVERFLOW_BIT | SCF_UNDERFLOW_BIT)) {
+		if (se_cmd->se_cmd_flags & SCF_OVERFLOW_BIT)
+			fcp->resp.fr_flags |= FCP_RESID_OVER;
+		else
+			fcp->resp.fr_flags |= FCP_RESID_UNDER;
+		fcp->ext.fr_resid = cpu_to_be32(se_cmd->residual_count);
+	}
+
+	/*
+	 * Send response.
+	 */
+	cmd->seq = lport->tt.seq_start_next(cmd->seq);
+	fc_fill_fc_hdr(fp, FC_RCTL_DD_CMD_STATUS, ep->did, ep->sid, FC_TYPE_FCP,
+		       FC_FC_EX_CTX | FC_FC_LAST_SEQ | FC_FC_END_SEQ, 0);
+
+	lport->tt.seq_send(lport, cmd->seq, fp);
+	lport->tt.exch_done(cmd->seq);
+	return 0;
+}
+
+int ft_write_pending_status(struct se_cmd *se_cmd)
+{
+	struct ft_cmd *cmd = container_of(se_cmd, struct ft_cmd, se_cmd);
+
+	return cmd->write_data_len != se_cmd->data_length;
+}
+
+/*
+ * Send TX_RDY (transfer ready).
+ */
+int ft_write_pending(struct se_cmd *se_cmd)
+{
+	struct ft_cmd *cmd = container_of(se_cmd, struct ft_cmd, se_cmd);
+	struct fc_frame *fp;
+	struct fcp_txrdy *txrdy;
+	struct fc_lport *lport;
+	struct fc_exch *ep;
+	struct fc_frame_header *fh;
+	u32 f_ctl;
+
+	ft_dump_cmd(cmd, __func__);
+
+	ep = fc_seq_exch(cmd->seq);
+	lport = ep->lp;
+	fp = fc_frame_alloc(lport, sizeof(*txrdy));
+	if (!fp)
+		return PYX_TRANSPORT_OUT_OF_MEMORY_RESOURCES;
+
+	txrdy = fc_frame_payload_get(fp, sizeof(*txrdy));
+	memset(txrdy, 0, sizeof(*txrdy));
+	txrdy->ft_burst_len = htonl(se_cmd->data_length);
+
+	cmd->seq = lport->tt.seq_start_next(cmd->seq);
+	fc_fill_fc_hdr(fp, FC_RCTL_DD_DATA_DESC, ep->did, ep->sid, FC_TYPE_FCP,
+		       FC_FC_EX_CTX | FC_FC_END_SEQ | FC_FC_SEQ_INIT, 0);
+
+	fh = fc_frame_header_get(fp);
+	f_ctl = ntoh24(fh->fh_f_ctl);
+
+	/* Only if it is 'Exchange Responder' */
+	if (f_ctl & FC_FC_EX_CTX) {
+		/* Target is 'exchange responder' and sending XFER_READY
+		 * to 'exchange initiator (initiator)'
+		 */
+		if ((ep->xid <= lport->lro_xid) &&
+		    (fh->fh_r_ctl == FC_RCTL_DD_DATA_DESC)) {
+			if (se_cmd->se_cmd_flags & SCF_SCSI_DATA_SG_IO_CDB) {
+				/*
+				 * Map se_mem list to scatterlist, so that
+				 * DDP can be setup. DDP setup function require
+				 * scatterlist. se_mem_list is internal to
+				 * TCM/LIO target
+				 */
+				transport_do_task_sg_chain(se_cmd);
+				cmd->sg = T_TASK(se_cmd)->t_tasks_sg_chained;
+				cmd->sg_cnt =
+					T_TASK(se_cmd)->t_tasks_sg_chained_no;
+			}
+			if (cmd->sg && lport->tt.ddp_setup(lport, ep->xid,
+						    cmd->sg, cmd->sg_cnt))
+				cmd->was_ddp_setup = 1;
+		}
+	}
+	lport->tt.seq_send(lport, cmd->seq, fp);
+	return 0;
+}
+
+u32 ft_get_task_tag(struct se_cmd *se_cmd)
+{
+	struct ft_cmd *cmd = container_of(se_cmd, struct ft_cmd, se_cmd);
+
+	return fc_seq_exch(cmd->seq)->rxid;
+}
+
+int ft_get_cmd_state(struct se_cmd *se_cmd)
+{
+	struct ft_cmd *cmd = container_of(se_cmd, struct ft_cmd, se_cmd);
+
+	return cmd->state;
+}
+
+int ft_is_state_remove(struct se_cmd *se_cmd)
+{
+	return 0;	/* XXX TBD */
+}
+
+void ft_new_cmd_failure(struct se_cmd *se_cmd)
+{
+	/* XXX TBD */
+	printk(KERN_INFO "%s: se_cmd %p\n", __func__, se_cmd);
+}
+
+/*
+ * FC sequence response handler for follow-on sequences (data) and aborts.
+ */
+static void ft_recv_seq(struct fc_seq *sp, struct fc_frame *fp, void *arg)
+{
+	struct ft_cmd *cmd = arg;
+	struct fc_frame_header *fh;
+
+	if (IS_ERR(fp)) {
+		/* XXX need to find cmd if queued */
+		cmd->se_cmd.t_state = TRANSPORT_REMOVE;
+		cmd->seq = NULL;
+		transport_generic_free_cmd(&cmd->se_cmd, 0, 1, 0);
+		return;
+	}
+
+	fh = fc_frame_header_get(fp);
+
+	switch (fh->fh_r_ctl) {
+	case FC_RCTL_DD_SOL_DATA:	/* write data */
+		ft_recv_write_data(cmd, fp);
+		break;
+	case FC_RCTL_DD_UNSOL_CTL:	/* command */
+	case FC_RCTL_DD_SOL_CTL:	/* transfer ready */
+	case FC_RCTL_DD_DATA_DESC:	/* transfer ready */
+	default:
+		printk(KERN_INFO "%s: unhandled frame r_ctl %x\n",
+		       __func__, fh->fh_r_ctl);
+		fc_frame_free(fp);
+		transport_generic_free_cmd(&cmd->se_cmd, 0, 1, 0);
+		break;
+	}
+}
+
+/*
+ * Send a FCP response including SCSI status and optional FCP rsp_code.
+ * status is SAM_STAT_GOOD (zero) iff code is valid.
+ * This is used in error cases, such as allocation failures.
+ */
+static void ft_send_resp_status(struct fc_lport *lport,
+				const struct fc_frame *rx_fp,
+				u32 status, enum fcp_resp_rsp_codes code)
+{
+	struct fc_frame *fp;
+	struct fc_seq *sp;
+	const struct fc_frame_header *fh;
+	size_t len;
+	struct fcp_resp_with_ext *fcp;
+	struct fcp_resp_rsp_info *info;
+
+	fh = fc_frame_header_get(rx_fp);
+	FT_IO_DBG("FCP error response: did %x oxid %x status %x code %x\n",
+		  ntoh24(fh->fh_s_id), ntohs(fh->fh_ox_id), status, code);
+	len = sizeof(*fcp);
+	if (status == SAM_STAT_GOOD)
+		len += sizeof(*info);
+	fp = fc_frame_alloc(lport, len);
+	if (!fp)
+		return;
+	fcp = fc_frame_payload_get(fp, len);
+	memset(fcp, 0, len);
+	fcp->resp.fr_status = status;
+	if (status == SAM_STAT_GOOD) {
+		fcp->ext.fr_rsp_len = htonl(sizeof(*info));
+		fcp->resp.fr_flags |= FCP_RSP_LEN_VAL;
+		info = (struct fcp_resp_rsp_info *)(fcp + 1);
+		info->rsp_code = code;
+	}
+
+	fc_fill_reply_hdr(fp, rx_fp, FC_RCTL_DD_CMD_STATUS, 0);
+	sp = fr_seq(fp);
+	if (sp)
+		lport->tt.seq_send(lport, sp, fp);
+	else
+		lport->tt.frame_send(lport, fp);
+}
+
+/*
+ * Send error or task management response.
+ * Always frees the cmd and associated state.
+ */
+static void ft_send_resp_code(struct ft_cmd *cmd, enum fcp_resp_rsp_codes code)
+{
+	ft_send_resp_status(cmd->sess->tport->lport,
+			    cmd->req_frame, SAM_STAT_GOOD, code);
+	ft_free_cmd(cmd);
+}
+
+/*
+ * Handle Task Management Request.
+ */
+static void ft_send_tm(struct ft_cmd *cmd)
+{
+	struct se_tmr_req *tmr;
+	struct fcp_cmnd *fcp;
+	struct ft_sess *sess;
+	u8 tm_func;
+
+	fcp = fc_frame_payload_get(cmd->req_frame, sizeof(*fcp));
+
+	switch (fcp->fc_tm_flags) {
+	case FCP_TMF_LUN_RESET:
+		tm_func = TMR_LUN_RESET;
+		break;
+	case FCP_TMF_TGT_RESET:
+		tm_func = TMR_TARGET_WARM_RESET;
+		break;
+	case FCP_TMF_CLR_TASK_SET:
+		tm_func = TMR_CLEAR_TASK_SET;
+		break;
+	case FCP_TMF_ABT_TASK_SET:
+		tm_func = TMR_ABORT_TASK_SET;
+		break;
+	case FCP_TMF_CLR_ACA:
+		tm_func = TMR_CLEAR_ACA;
+		break;
+	default:
+		/*
+		 * FCP4r01 indicates having a combination of
+		 * tm_flags set is invalid.
+		 */
+		FT_TM_DBG("invalid FCP tm_flags %x\n", fcp->fc_tm_flags);
+		ft_send_resp_code(cmd, FCP_CMND_FIELDS_INVALID);
+		return;
+	}
+
+	FT_TM_DBG("alloc tm cmd fn %d\n", tm_func);
+	tmr = core_tmr_alloc_req(&cmd->se_cmd, cmd, tm_func);
+	if (!tmr) {
+		FT_TM_DBG("alloc failed\n");
+		ft_send_resp_code(cmd, FCP_TMF_FAILED);
+		return;
+	}
+	cmd->se_cmd.se_tmr_req = tmr;
+
+	switch (fcp->fc_tm_flags) {
+	case FCP_TMF_LUN_RESET:
+		cmd->lun = scsilun_to_int((struct scsi_lun *)fcp->fc_lun);
+		if (transport_get_lun_for_tmr(&cmd->se_cmd, cmd->lun) < 0) {
+			/*
+			 * Make sure to clean up newly allocated TMR request
+			 * since "unable to  handle TMR request because failed
+			 * to get to LUN"
+			 */
+			FT_TM_DBG("Failed to get LUN for TMR func %d, "
+				  "se_cmd %p, unpacked_lun %d\n",
+				  tm_func, &cmd->se_cmd, cmd->lun);
+			ft_dump_cmd(cmd, __func__);
+			sess = cmd->sess;
+			transport_send_check_condition_and_sense(&cmd->se_cmd,
+				cmd->se_cmd.scsi_sense_reason, 0);
+			transport_generic_free_cmd(&cmd->se_cmd, 0, 1, 0);
+			ft_sess_put(sess);
+			return;
+		}
+		break;
+	case FCP_TMF_TGT_RESET:
+	case FCP_TMF_CLR_TASK_SET:
+	case FCP_TMF_ABT_TASK_SET:
+	case FCP_TMF_CLR_ACA:
+		break;
+	default:
+		return;
+	}
+	transport_generic_handle_tmr(&cmd->se_cmd);
+}
+
+/*
+ * Send status from completed task management request.
+ */
+int ft_queue_tm_resp(struct se_cmd *se_cmd)
+{
+	struct ft_cmd *cmd = container_of(se_cmd, struct ft_cmd, se_cmd);
+	struct se_tmr_req *tmr = se_cmd->se_tmr_req;
+	enum fcp_resp_rsp_codes code;
+
+	switch (tmr->response) {
+	case TMR_FUNCTION_COMPLETE:
+		code = FCP_TMF_CMPL;
+		break;
+	case TMR_LUN_DOES_NOT_EXIST:
+		code = FCP_TMF_INVALID_LUN;
+		break;
+	case TMR_FUNCTION_REJECTED:
+		code = FCP_TMF_REJECTED;
+		break;
+	case TMR_TASK_DOES_NOT_EXIST:
+	case TMR_TASK_STILL_ALLEGIANT:
+	case TMR_TASK_FAILOVER_NOT_SUPPORTED:
+	case TMR_TASK_MGMT_FUNCTION_NOT_SUPPORTED:
+	case TMR_FUNCTION_AUTHORIZATION_FAILED:
+	default:
+		code = FCP_TMF_FAILED;
+		break;
+	}
+	FT_TM_DBG("tmr fn %d resp %d fcp code %d\n",
+		  tmr->function, tmr->response, code);
+	ft_send_resp_code(cmd, code);
+	return 0;
+}
+
+/*
+ * Handle incoming FCP command.
+ */
+static void ft_recv_cmd(struct ft_sess *sess, struct fc_frame *fp)
+{
+	struct ft_cmd *cmd;
+	struct fc_lport *lport = sess->tport->lport;
+
+	cmd = kzalloc(sizeof(*cmd), GFP_ATOMIC);
+	if (!cmd)
+		goto busy;
+	cmd->sess = sess;
+	cmd->seq = lport->tt.seq_assign(lport, fp);
+	if (!cmd->seq) {
+		kfree(cmd);
+		goto busy;
+	}
+	cmd->req_frame = fp;		/* hold frame during cmd */
+	ft_queue_cmd(sess, cmd);
+	return;
+
+busy:
+	FT_IO_DBG("cmd or seq allocation failure - sending BUSY\n");
+	ft_send_resp_status(lport, fp, SAM_STAT_BUSY, 0);
+	fc_frame_free(fp);
+	ft_sess_put(sess);		/* undo get from lookup */
+}
+
+
+/*
+ * Handle incoming FCP frame.
+ * Caller has verified that the frame is type FCP.
+ */
+void ft_recv_req(struct ft_sess *sess, struct fc_frame *fp)
+{
+	struct fc_frame_header *fh = fc_frame_header_get(fp);
+
+	switch (fh->fh_r_ctl) {
+	case FC_RCTL_DD_UNSOL_CMD:	/* command */
+		ft_recv_cmd(sess, fp);
+		break;
+	case FC_RCTL_DD_SOL_DATA:	/* write data */
+	case FC_RCTL_DD_UNSOL_CTL:
+	case FC_RCTL_DD_SOL_CTL:
+	case FC_RCTL_DD_DATA_DESC:	/* transfer ready */
+	case FC_RCTL_ELS4_REQ:		/* SRR, perhaps */
+	default:
+		printk(KERN_INFO "%s: unhandled frame r_ctl %x\n",
+		       __func__, fh->fh_r_ctl);
+		fc_frame_free(fp);
+		ft_sess_put(sess);	/* undo get from lookup */
+		break;
+	}
+}
+
+/*
+ * Send new command to target.
+ */
+static void ft_send_cmd(struct ft_cmd *cmd)
+{
+	struct fc_frame_header *fh = fc_frame_header_get(cmd->req_frame);
+	struct se_cmd *se_cmd;
+	struct fcp_cmnd *fcp;
+	int data_dir;
+	u32 data_len;
+	int task_attr;
+	int ret;
+
+	fcp = fc_frame_payload_get(cmd->req_frame, sizeof(*fcp));
+	if (!fcp)
+		goto err;
+
+	if (fcp->fc_flags & FCP_CFL_LEN_MASK)
+		goto err;		/* not handling longer CDBs yet */
+
+	if (fcp->fc_tm_flags) {
+		task_attr = FCP_PTA_SIMPLE;
+		data_dir = DMA_NONE;
+		data_len = 0;
+	} else {
+		switch (fcp->fc_flags & (FCP_CFL_RDDATA | FCP_CFL_WRDATA)) {
+		case 0:
+			data_dir = DMA_NONE;
+			break;
+		case FCP_CFL_RDDATA:
+			data_dir = DMA_FROM_DEVICE;
+			break;
+		case FCP_CFL_WRDATA:
+			data_dir = DMA_TO_DEVICE;
+			break;
+		case FCP_CFL_WRDATA | FCP_CFL_RDDATA:
+			goto err;	/* TBD not supported by tcm_fc yet */
+		}
+		/*
+		 * Locate the SAM Task Attr from fc_pri_ta
+		 */
+		switch (fcp->fc_pri_ta & FCP_PTA_MASK) {
+		case FCP_PTA_HEADQ:
+			task_attr = MSG_HEAD_TAG;
+			break;
+		case FCP_PTA_ORDERED:
+			task_attr = MSG_ORDERED_TAG;
+			break;
+		case FCP_PTA_ACA:
+			task_attr = MSG_ACA_TAG;
+			break;
+		case FCP_PTA_SIMPLE: /* Fallthrough */
+		default:
+			task_attr = MSG_SIMPLE_TAG;
+		}
+
+
+		task_attr = fcp->fc_pri_ta & FCP_PTA_MASK;
+		data_len = ntohl(fcp->fc_dl);
+		cmd->cdb = fcp->fc_cdb;
+	}
+
+	se_cmd = &cmd->se_cmd;
+	/*
+	 * Initialize struct se_cmd descriptor from target_core_mod
+	 * infrastructure
+	 */
+	transport_init_se_cmd(se_cmd, &ft_configfs->tf_ops, cmd->sess->se_sess,
+			      data_len, data_dir, task_attr,
+			      &cmd->ft_sense_buffer[0]);
+	/*
+	 * Check for FCP task management flags
+	 */
+	if (fcp->fc_tm_flags) {
+		ft_send_tm(cmd);
+		return;
+	}
+
+	fc_seq_exch(cmd->seq)->lp->tt.seq_set_resp(cmd->seq, ft_recv_seq, cmd);
+
+	cmd->lun = scsilun_to_int((struct scsi_lun *)fcp->fc_lun);
+	ret = transport_get_lun_for_cmd(&cmd->se_cmd, NULL, cmd->lun);
+	if (ret < 0) {
+		ft_dump_cmd(cmd, __func__);
+		transport_send_check_condition_and_sense(&cmd->se_cmd,
+			cmd->se_cmd.scsi_sense_reason, 0);
+		return;
+	}
+
+	ret = transport_generic_allocate_tasks(se_cmd, cmd->cdb);
+
+	FT_IO_DBG("r_ctl %x alloc task ret %d\n", fh->fh_r_ctl, ret);
+	ft_dump_cmd(cmd, __func__);
+
+	if (ret == -1) {
+		transport_send_check_condition_and_sense(se_cmd,
+				TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE, 0);
+		transport_generic_free_cmd(se_cmd, 0, 1, 0);
+		return;
+	}
+	if (ret == -2) {
+		if (se_cmd->se_cmd_flags & SCF_SCSI_RESERVATION_CONFLICT)
+			ft_queue_status(se_cmd);
+		else
+			transport_send_check_condition_and_sense(se_cmd,
+					se_cmd->scsi_sense_reason, 0);
+		transport_generic_free_cmd(se_cmd, 0, 1, 0);
+		return;
+	}
+	transport_generic_handle_cdb(se_cmd);
+	return;
+
+err:
+	ft_send_resp_code(cmd, FCP_CMND_FIELDS_INVALID);
+	return;
+}
+
+/*
+ * Handle request in the command thread.
+ */
+static void ft_exec_req(struct ft_cmd *cmd)
+{
+	FT_IO_DBG("cmd state %x\n", cmd->state);
+	switch (cmd->state) {
+	case FC_CMD_ST_NEW:
+		ft_send_cmd(cmd);
+		break;
+	default:
+		break;
+	}
+}
+
+/*
+ * Processing thread.
+ * Currently one thread per tpg.
+ */
+int ft_thread(void *arg)
+{
+	struct ft_tpg *tpg = arg;
+	struct se_queue_obj *qobj = &tpg->qobj;
+	struct ft_cmd *cmd;
+	int ret;
+
+	set_user_nice(current, -20);
+
+	while (!kthread_should_stop()) {
+		ret = wait_event_interruptible(qobj->thread_wq,
+			atomic_read(&qobj->queue_cnt) || kthread_should_stop());
+		if (ret < 0 || kthread_should_stop())
+			goto out;
+		cmd = ft_dequeue_cmd(qobj);
+		if (cmd)
+			ft_exec_req(cmd);
+	}
+
+out:
+	return 0;
+}
diff -druN linux-2.6.39-libre/drivers/target/tcm_fc/tfc_conf.c linux-3.0-rc7-libre/drivers/target/tcm_fc/tfc_conf.c
--- linux-2.6.39-libre/drivers/target/tcm_fc/tfc_conf.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/target/tcm_fc/tfc_conf.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,669 @@
+/*******************************************************************************
+ * Filename:  tcm_fc.c
+ *
+ * This file contains the configfs implementation for TCM_fc fabric node.
+ * Based on tcm_loop_configfs.c
+ *
+ * Copyright (c) 2010 Cisco Systems, Inc.
+ * Copyright (c) 2009,2010 Rising Tide, Inc.
+ * Copyright (c) 2009,2010 Linux-iSCSI.org
+ *
+ * Copyright (c) 2009,2010 Nicholas A. Bellinger <nab@linux-iscsi.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.
+ ****************************************************************************/
+
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/version.h>
+#include <generated/utsrelease.h>
+#include <linux/utsname.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/kthread.h>
+#include <linux/types.h>
+#include <linux/string.h>
+#include <linux/configfs.h>
+#include <linux/ctype.h>
+#include <asm/unaligned.h>
+#include <scsi/scsi.h>
+#include <scsi/scsi_host.h>
+#include <scsi/scsi_device.h>
+#include <scsi/scsi_cmnd.h>
+#include <scsi/libfc.h>
+
+#include <target/target_core_base.h>
+#include <target/target_core_transport.h>
+#include <target/target_core_fabric_ops.h>
+#include <target/target_core_fabric_configfs.h>
+#include <target/target_core_fabric_lib.h>
+#include <target/target_core_device.h>
+#include <target/target_core_tpg.h>
+#include <target/target_core_configfs.h>
+#include <target/target_core_base.h>
+#include <target/configfs_macros.h>
+
+#include "tcm_fc.h"
+
+struct target_fabric_configfs *ft_configfs;
+
+LIST_HEAD(ft_lport_list);
+DEFINE_MUTEX(ft_lport_lock);
+
+unsigned int ft_debug_logging;
+module_param_named(debug_logging, ft_debug_logging, int, S_IRUGO|S_IWUSR);
+MODULE_PARM_DESC(debug_logging, "a bit mask of logging levels");
+
+/*
+ * Parse WWN.
+ * If strict, we require lower-case hex and colon separators to be sure
+ * the name is the same as what would be generated by ft_format_wwn()
+ * so the name and wwn are mapped one-to-one.
+ */
+static ssize_t ft_parse_wwn(const char *name, u64 *wwn, int strict)
+{
+	const char *cp;
+	char c;
+	u32 nibble;
+	u32 byte = 0;
+	u32 pos = 0;
+	u32 err;
+
+	*wwn = 0;
+	for (cp = name; cp < &name[FT_NAMELEN - 1]; cp++) {
+		c = *cp;
+		if (c == '\n' && cp[1] == '\0')
+			continue;
+		if (strict && pos++ == 2 && byte++ < 7) {
+			pos = 0;
+			if (c == ':')
+				continue;
+			err = 1;
+			goto fail;
+		}
+		if (c == '\0') {
+			err = 2;
+			if (strict && byte != 8)
+				goto fail;
+			return cp - name;
+		}
+		err = 3;
+		if (isdigit(c))
+			nibble = c - '0';
+		else if (isxdigit(c) && (islower(c) || !strict))
+			nibble = tolower(c) - 'a' + 10;
+		else
+			goto fail;
+		*wwn = (*wwn << 4) | nibble;
+	}
+	err = 4;
+fail:
+	FT_CONF_DBG("err %u len %zu pos %u byte %u\n",
+		    err, cp - name, pos, byte);
+	return -1;
+}
+
+ssize_t ft_format_wwn(char *buf, size_t len, u64 wwn)
+{
+	u8 b[8];
+
+	put_unaligned_be64(wwn, b);
+	return snprintf(buf, len,
+		 "%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x",
+		 b[0], b[1], b[2], b[3], b[4], b[5], b[6], b[7]);
+}
+
+static ssize_t ft_wwn_show(void *arg, char *buf)
+{
+	u64 *wwn = arg;
+	ssize_t len;
+
+	len = ft_format_wwn(buf, PAGE_SIZE - 2, *wwn);
+	buf[len++] = '\n';
+	return len;
+}
+
+static ssize_t ft_wwn_store(void *arg, const char *buf, size_t len)
+{
+	ssize_t ret;
+	u64 wwn;
+
+	ret = ft_parse_wwn(buf, &wwn, 0);
+	if (ret > 0)
+		*(u64 *)arg = wwn;
+	return ret;
+}
+
+/*
+ * ACL auth ops.
+ */
+
+static ssize_t ft_nacl_show_port_name(
+	struct se_node_acl *se_nacl,
+	char *page)
+{
+	struct ft_node_acl *acl = container_of(se_nacl,
+			struct ft_node_acl, se_node_acl);
+
+	return ft_wwn_show(&acl->node_auth.port_name, page);
+}
+
+static ssize_t ft_nacl_store_port_name(
+	struct se_node_acl *se_nacl,
+	const char *page,
+	size_t count)
+{
+	struct ft_node_acl *acl = container_of(se_nacl,
+			struct ft_node_acl, se_node_acl);
+
+	return ft_wwn_store(&acl->node_auth.port_name, page, count);
+}
+
+TF_NACL_BASE_ATTR(ft, port_name, S_IRUGO | S_IWUSR);
+
+static ssize_t ft_nacl_show_node_name(
+	struct se_node_acl *se_nacl,
+	char *page)
+{
+	struct ft_node_acl *acl = container_of(se_nacl,
+			struct ft_node_acl, se_node_acl);
+
+	return ft_wwn_show(&acl->node_auth.node_name, page);
+}
+
+static ssize_t ft_nacl_store_node_name(
+	struct se_node_acl *se_nacl,
+	const char *page,
+	size_t count)
+{
+	struct ft_node_acl *acl = container_of(se_nacl,
+			struct ft_node_acl, se_node_acl);
+
+	return ft_wwn_store(&acl->node_auth.node_name, page, count);
+}
+
+TF_NACL_BASE_ATTR(ft, node_name, S_IRUGO | S_IWUSR);
+
+static struct configfs_attribute *ft_nacl_base_attrs[] = {
+	&ft_nacl_port_name.attr,
+	&ft_nacl_node_name.attr,
+	NULL,
+};
+
+/*
+ * ACL ops.
+ */
+
+/*
+ * Add ACL for an initiator.  The ACL is named arbitrarily.
+ * The port_name and/or node_name are attributes.
+ */
+static struct se_node_acl *ft_add_acl(
+	struct se_portal_group *se_tpg,
+	struct config_group *group,
+	const char *name)
+{
+	struct ft_node_acl *acl;
+	struct ft_tpg *tpg;
+	u64 wwpn;
+	u32 q_depth;
+
+	FT_CONF_DBG("add acl %s\n", name);
+	tpg = container_of(se_tpg, struct ft_tpg, se_tpg);
+
+	if (ft_parse_wwn(name, &wwpn, 1) < 0)
+		return ERR_PTR(-EINVAL);
+
+	acl = kzalloc(sizeof(struct ft_node_acl), GFP_KERNEL);
+	if (!(acl))
+		return ERR_PTR(-ENOMEM);
+	acl->node_auth.port_name = wwpn;
+
+	q_depth = 32;		/* XXX bogus default - get from tpg? */
+	return core_tpg_add_initiator_node_acl(&tpg->se_tpg,
+				&acl->se_node_acl, name, q_depth);
+}
+
+static void ft_del_acl(struct se_node_acl *se_acl)
+{
+	struct se_portal_group *se_tpg = se_acl->se_tpg;
+	struct ft_tpg *tpg;
+	struct ft_node_acl *acl = container_of(se_acl,
+				struct ft_node_acl, se_node_acl);
+
+	FT_CONF_DBG("del acl %s\n",
+		config_item_name(&se_acl->acl_group.cg_item));
+
+	tpg = container_of(se_tpg, struct ft_tpg, se_tpg);
+	FT_CONF_DBG("del acl %p se_acl %p tpg %p se_tpg %p\n",
+		    acl, se_acl, tpg, &tpg->se_tpg);
+
+	core_tpg_del_initiator_node_acl(&tpg->se_tpg, se_acl, 1);
+	kfree(acl);
+}
+
+struct ft_node_acl *ft_acl_get(struct ft_tpg *tpg, struct fc_rport_priv *rdata)
+{
+	struct ft_node_acl *found = NULL;
+	struct ft_node_acl *acl;
+	struct se_portal_group *se_tpg = &tpg->se_tpg;
+	struct se_node_acl *se_acl;
+
+	spin_lock_bh(&se_tpg->acl_node_lock);
+	list_for_each_entry(se_acl, &se_tpg->acl_node_list, acl_list) {
+		acl = container_of(se_acl, struct ft_node_acl, se_node_acl);
+		FT_CONF_DBG("acl %p port_name %llx\n",
+			acl, (unsigned long long)acl->node_auth.port_name);
+		if (acl->node_auth.port_name == rdata->ids.port_name ||
+		    acl->node_auth.node_name == rdata->ids.node_name) {
+			FT_CONF_DBG("acl %p port_name %llx matched\n", acl,
+				    (unsigned long long)rdata->ids.port_name);
+			found = acl;
+			/* XXX need to hold onto ACL */
+			break;
+		}
+	}
+	spin_unlock_bh(&se_tpg->acl_node_lock);
+	return found;
+}
+
+struct se_node_acl *ft_tpg_alloc_fabric_acl(struct se_portal_group *se_tpg)
+{
+	struct ft_node_acl *acl;
+
+	acl = kzalloc(sizeof(*acl), GFP_KERNEL);
+	if (!(acl)) {
+		printk(KERN_ERR "Unable to allocate struct ft_node_acl\n");
+		return NULL;
+	}
+	FT_CONF_DBG("acl %p\n", acl);
+	return &acl->se_node_acl;
+}
+
+static void ft_tpg_release_fabric_acl(struct se_portal_group *se_tpg,
+				      struct se_node_acl *se_acl)
+{
+	struct ft_node_acl *acl = container_of(se_acl,
+				struct ft_node_acl, se_node_acl);
+
+	FT_CONF_DBG(KERN_INFO "acl %p\n", acl);
+	kfree(acl);
+}
+
+/*
+ * local_port port_group (tpg) ops.
+ */
+static struct se_portal_group *ft_add_tpg(
+	struct se_wwn *wwn,
+	struct config_group *group,
+	const char *name)
+{
+	struct ft_lport_acl *lacl;
+	struct ft_tpg *tpg;
+	unsigned long index;
+	int ret;
+
+	FT_CONF_DBG("tcm_fc: add tpg %s\n", name);
+
+	/*
+	 * Name must be "tpgt_" followed by the index.
+	 */
+	if (strstr(name, "tpgt_") != name)
+		return NULL;
+	if (strict_strtoul(name + 5, 10, &index) || index > UINT_MAX)
+		return NULL;
+
+	lacl = container_of(wwn, struct ft_lport_acl, fc_lport_wwn);
+	tpg = kzalloc(sizeof(*tpg), GFP_KERNEL);
+	if (!tpg)
+		return NULL;
+	tpg->index = index;
+	tpg->lport_acl = lacl;
+	INIT_LIST_HEAD(&tpg->lun_list);
+	transport_init_queue_obj(&tpg->qobj);
+
+	ret = core_tpg_register(&ft_configfs->tf_ops, wwn, &tpg->se_tpg,
+				(void *)tpg, TRANSPORT_TPG_TYPE_NORMAL);
+	if (ret < 0) {
+		kfree(tpg);
+		return NULL;
+	}
+
+	tpg->thread = kthread_run(ft_thread, tpg, "ft_tpg%lu", index);
+	if (IS_ERR(tpg->thread)) {
+		kfree(tpg);
+		return NULL;
+	}
+
+	mutex_lock(&ft_lport_lock);
+	list_add_tail(&tpg->list, &lacl->tpg_list);
+	mutex_unlock(&ft_lport_lock);
+
+	return &tpg->se_tpg;
+}
+
+static void ft_del_tpg(struct se_portal_group *se_tpg)
+{
+	struct ft_tpg *tpg = container_of(se_tpg, struct ft_tpg, se_tpg);
+
+	FT_CONF_DBG("del tpg %s\n",
+		    config_item_name(&tpg->se_tpg.tpg_group.cg_item));
+
+	kthread_stop(tpg->thread);
+
+	/* Wait for sessions to be freed thru RCU, for BUG_ON below */
+	synchronize_rcu();
+
+	mutex_lock(&ft_lport_lock);
+	list_del(&tpg->list);
+	if (tpg->tport) {
+		tpg->tport->tpg = NULL;
+		tpg->tport = NULL;
+	}
+	mutex_unlock(&ft_lport_lock);
+
+	core_tpg_deregister(se_tpg);
+	kfree(tpg);
+}
+
+/*
+ * Verify that an lport is configured to use the tcm_fc module, and return
+ * the target port group that should be used.
+ *
+ * The caller holds ft_lport_lock.
+ */
+struct ft_tpg *ft_lport_find_tpg(struct fc_lport *lport)
+{
+	struct ft_lport_acl *lacl;
+	struct ft_tpg *tpg;
+
+	list_for_each_entry(lacl, &ft_lport_list, list) {
+		if (lacl->wwpn == lport->wwpn) {
+			list_for_each_entry(tpg, &lacl->tpg_list, list)
+				return tpg; /* XXX for now return first entry */
+			return NULL;
+		}
+	}
+	return NULL;
+}
+
+/*
+ * target config instance ops.
+ */
+
+/*
+ * Add lport to allowed config.
+ * The name is the WWPN in lower-case ASCII, colon-separated bytes.
+ */
+static struct se_wwn *ft_add_lport(
+	struct target_fabric_configfs *tf,
+	struct config_group *group,
+	const char *name)
+{
+	struct ft_lport_acl *lacl;
+	struct ft_lport_acl *old_lacl;
+	u64 wwpn;
+
+	FT_CONF_DBG("add lport %s\n", name);
+	if (ft_parse_wwn(name, &wwpn, 1) < 0)
+		return NULL;
+	lacl = kzalloc(sizeof(*lacl), GFP_KERNEL);
+	if (!lacl)
+		return NULL;
+	lacl->wwpn = wwpn;
+	INIT_LIST_HEAD(&lacl->tpg_list);
+
+	mutex_lock(&ft_lport_lock);
+	list_for_each_entry(old_lacl, &ft_lport_list, list) {
+		if (old_lacl->wwpn == wwpn) {
+			mutex_unlock(&ft_lport_lock);
+			kfree(lacl);
+			return NULL;
+		}
+	}
+	list_add_tail(&lacl->list, &ft_lport_list);
+	ft_format_wwn(lacl->name, sizeof(lacl->name), wwpn);
+	mutex_unlock(&ft_lport_lock);
+
+	return &lacl->fc_lport_wwn;
+}
+
+static void ft_del_lport(struct se_wwn *wwn)
+{
+	struct ft_lport_acl *lacl = container_of(wwn,
+				struct ft_lport_acl, fc_lport_wwn);
+
+	FT_CONF_DBG("del lport %s\n",
+			config_item_name(&wwn->wwn_group.cg_item));
+	mutex_lock(&ft_lport_lock);
+	list_del(&lacl->list);
+	mutex_unlock(&ft_lport_lock);
+
+	kfree(lacl);
+}
+
+static ssize_t ft_wwn_show_attr_version(
+	struct target_fabric_configfs *tf,
+	char *page)
+{
+	return sprintf(page, "TCM FC " FT_VERSION " on %s/%s on "
+		""UTS_RELEASE"\n",  utsname()->sysname, utsname()->machine);
+}
+
+TF_WWN_ATTR_RO(ft, version);
+
+static struct configfs_attribute *ft_wwn_attrs[] = {
+	&ft_wwn_version.attr,
+	NULL,
+};
+
+static char *ft_get_fabric_name(void)
+{
+	return "fc";
+}
+
+static char *ft_get_fabric_wwn(struct se_portal_group *se_tpg)
+{
+	struct ft_tpg *tpg = se_tpg->se_tpg_fabric_ptr;
+
+	return tpg->lport_acl->name;
+}
+
+static u16 ft_get_tag(struct se_portal_group *se_tpg)
+{
+	struct ft_tpg *tpg = se_tpg->se_tpg_fabric_ptr;
+
+	/*
+	 * This tag is used when forming SCSI Name identifier in EVPD=1 0x83
+	 * to represent the SCSI Target Port.
+	 */
+	return tpg->index;
+}
+
+static u32 ft_get_default_depth(struct se_portal_group *se_tpg)
+{
+	return 1;
+}
+
+static int ft_check_false(struct se_portal_group *se_tpg)
+{
+	return 0;
+}
+
+static void ft_set_default_node_attr(struct se_node_acl *se_nacl)
+{
+}
+
+static u16 ft_get_fabric_sense_len(void)
+{
+	return 0;
+}
+
+static u16 ft_set_fabric_sense_len(struct se_cmd *se_cmd, u32 sense_len)
+{
+	return 0;
+}
+
+static u32 ft_tpg_get_inst_index(struct se_portal_group *se_tpg)
+{
+	struct ft_tpg *tpg = se_tpg->se_tpg_fabric_ptr;
+
+	return tpg->index;
+}
+
+static struct target_core_fabric_ops ft_fabric_ops = {
+	.get_fabric_name =		ft_get_fabric_name,
+	.get_fabric_proto_ident =	fc_get_fabric_proto_ident,
+	.tpg_get_wwn =			ft_get_fabric_wwn,
+	.tpg_get_tag =			ft_get_tag,
+	.tpg_get_default_depth =	ft_get_default_depth,
+	.tpg_get_pr_transport_id =	fc_get_pr_transport_id,
+	.tpg_get_pr_transport_id_len =	fc_get_pr_transport_id_len,
+	.tpg_parse_pr_out_transport_id = fc_parse_pr_out_transport_id,
+	.tpg_check_demo_mode =		ft_check_false,
+	.tpg_check_demo_mode_cache =	ft_check_false,
+	.tpg_check_demo_mode_write_protect = ft_check_false,
+	.tpg_check_prod_mode_write_protect = ft_check_false,
+	.tpg_alloc_fabric_acl =		ft_tpg_alloc_fabric_acl,
+	.tpg_release_fabric_acl =	ft_tpg_release_fabric_acl,
+	.tpg_get_inst_index =		ft_tpg_get_inst_index,
+	.check_stop_free =		ft_check_stop_free,
+	.release_cmd_to_pool =		ft_release_cmd,
+	.release_cmd_direct =		ft_release_cmd,
+	.shutdown_session =		ft_sess_shutdown,
+	.close_session =		ft_sess_close,
+	.stop_session =			ft_sess_stop,
+	.fall_back_to_erl0 =		ft_sess_set_erl0,
+	.sess_logged_in =		ft_sess_logged_in,
+	.sess_get_index =		ft_sess_get_index,
+	.sess_get_initiator_sid =	NULL,
+	.write_pending =		ft_write_pending,
+	.write_pending_status =		ft_write_pending_status,
+	.set_default_node_attributes =	ft_set_default_node_attr,
+	.get_task_tag =			ft_get_task_tag,
+	.get_cmd_state =		ft_get_cmd_state,
+	.new_cmd_failure =		ft_new_cmd_failure,
+	.queue_data_in =		ft_queue_data_in,
+	.queue_status =			ft_queue_status,
+	.queue_tm_rsp =			ft_queue_tm_resp,
+	.get_fabric_sense_len =		ft_get_fabric_sense_len,
+	.set_fabric_sense_len =		ft_set_fabric_sense_len,
+	.is_state_remove =		ft_is_state_remove,
+	/*
+	 * Setup function pointers for generic logic in
+	 * target_core_fabric_configfs.c
+	 */
+	.fabric_make_wwn =		&ft_add_lport,
+	.fabric_drop_wwn =		&ft_del_lport,
+	.fabric_make_tpg =		&ft_add_tpg,
+	.fabric_drop_tpg =		&ft_del_tpg,
+	.fabric_post_link =		NULL,
+	.fabric_pre_unlink =		NULL,
+	.fabric_make_np =		NULL,
+	.fabric_drop_np =		NULL,
+	.fabric_make_nodeacl =		&ft_add_acl,
+	.fabric_drop_nodeacl =		&ft_del_acl,
+};
+
+int ft_register_configfs(void)
+{
+	struct target_fabric_configfs *fabric;
+	int ret;
+
+	/*
+	 * Register the top level struct config_item_type with TCM core
+	 */
+	fabric = target_fabric_configfs_init(THIS_MODULE, "fc");
+	if (!fabric) {
+		printk(KERN_INFO "%s: target_fabric_configfs_init() failed!\n",
+		       __func__);
+		return -1;
+	}
+	fabric->tf_ops = ft_fabric_ops;
+
+	/* Allowing support for task_sg_chaining */
+	fabric->tf_ops.task_sg_chaining = 1;
+
+	/*
+	 * Setup default attribute lists for various fabric->tf_cit_tmpl
+	 */
+	TF_CIT_TMPL(fabric)->tfc_wwn_cit.ct_attrs = ft_wwn_attrs;
+	TF_CIT_TMPL(fabric)->tfc_tpg_base_cit.ct_attrs = NULL;
+	TF_CIT_TMPL(fabric)->tfc_tpg_attrib_cit.ct_attrs = NULL;
+	TF_CIT_TMPL(fabric)->tfc_tpg_param_cit.ct_attrs = NULL;
+	TF_CIT_TMPL(fabric)->tfc_tpg_np_base_cit.ct_attrs = NULL;
+	TF_CIT_TMPL(fabric)->tfc_tpg_nacl_base_cit.ct_attrs =
+						    ft_nacl_base_attrs;
+	TF_CIT_TMPL(fabric)->tfc_tpg_nacl_attrib_cit.ct_attrs = NULL;
+	TF_CIT_TMPL(fabric)->tfc_tpg_nacl_auth_cit.ct_attrs = NULL;
+	TF_CIT_TMPL(fabric)->tfc_tpg_nacl_param_cit.ct_attrs = NULL;
+	/*
+	 * register the fabric for use within TCM
+	 */
+	ret = target_fabric_configfs_register(fabric);
+	if (ret < 0) {
+		FT_CONF_DBG("target_fabric_configfs_register() for"
+			    " FC Target failed!\n");
+		printk(KERN_INFO
+		       "%s: target_fabric_configfs_register() failed!\n",
+		       __func__);
+		target_fabric_configfs_free(fabric);
+		return -1;
+	}
+
+	/*
+	 * Setup our local pointer to *fabric.
+	 */
+	ft_configfs = fabric;
+	return 0;
+}
+
+void ft_deregister_configfs(void)
+{
+	if (!ft_configfs)
+		return;
+	target_fabric_configfs_deregister(ft_configfs);
+	ft_configfs = NULL;
+}
+
+static struct notifier_block ft_notifier = {
+	.notifier_call = ft_lport_notify
+};
+
+static int __init ft_init(void)
+{
+	if (ft_register_configfs())
+		return -1;
+	if (fc_fc4_register_provider(FC_TYPE_FCP, &ft_prov)) {
+		ft_deregister_configfs();
+		return -1;
+	}
+	blocking_notifier_chain_register(&fc_lport_notifier_head, &ft_notifier);
+	fc_lport_iterate(ft_lport_add, NULL);
+	return 0;
+}
+
+static void __exit ft_exit(void)
+{
+	blocking_notifier_chain_unregister(&fc_lport_notifier_head,
+					   &ft_notifier);
+	fc_fc4_deregister_provider(FC_TYPE_FCP, &ft_prov);
+	fc_lport_iterate(ft_lport_del, NULL);
+	ft_deregister_configfs();
+	synchronize_rcu();
+}
+
+#ifdef MODULE
+MODULE_DESCRIPTION("FC TCM fabric driver " FT_VERSION);
+MODULE_LICENSE("GPL");
+module_init(ft_init);
+module_exit(ft_exit);
+#endif /* MODULE */
diff -druN linux-2.6.39-libre/drivers/target/tcm_fc/tfc_io.c linux-3.0-rc7-libre/drivers/target/tcm_fc/tfc_io.c
--- linux-2.6.39-libre/drivers/target/tcm_fc/tfc_io.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/target/tcm_fc/tfc_io.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,374 @@
+/*
+ * Copyright (c) 2010 Cisco Systems, Inc.
+ *
+ * Portions based on tcm_loop_fabric_scsi.c and libfc/fc_fcp.c
+ *
+ * Copyright (c) 2007 Intel Corporation. All rights reserved.
+ * Copyright (c) 2008 Red Hat, Inc.  All rights reserved.
+ * Copyright (c) 2008 Mike Christie
+ * Copyright (c) 2009 Rising Tide, Inc.
+ * Copyright (c) 2009 Linux-iSCSI.org
+ * Copyright (c) 2009 Nicholas A. Bellinger <nab@linux-iscsi.org>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+/* XXX TBD some includes may be extraneous */
+
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/version.h>
+#include <generated/utsrelease.h>
+#include <linux/utsname.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/kthread.h>
+#include <linux/types.h>
+#include <linux/string.h>
+#include <linux/configfs.h>
+#include <linux/ctype.h>
+#include <linux/hash.h>
+#include <asm/unaligned.h>
+#include <scsi/scsi.h>
+#include <scsi/scsi_host.h>
+#include <scsi/scsi_device.h>
+#include <scsi/scsi_cmnd.h>
+#include <scsi/libfc.h>
+#include <scsi/fc_encode.h>
+
+#include <target/target_core_base.h>
+#include <target/target_core_transport.h>
+#include <target/target_core_fabric_ops.h>
+#include <target/target_core_device.h>
+#include <target/target_core_tpg.h>
+#include <target/target_core_configfs.h>
+#include <target/target_core_base.h>
+#include <target/configfs_macros.h>
+
+#include "tcm_fc.h"
+
+/*
+ * Deliver read data back to initiator.
+ * XXX TBD handle resource problems later.
+ */
+int ft_queue_data_in(struct se_cmd *se_cmd)
+{
+	struct ft_cmd *cmd = container_of(se_cmd, struct ft_cmd, se_cmd);
+	struct se_transport_task *task;
+	struct fc_frame *fp = NULL;
+	struct fc_exch *ep;
+	struct fc_lport *lport;
+	struct se_mem *mem;
+	size_t remaining;
+	u32 f_ctl = FC_FC_EX_CTX | FC_FC_REL_OFF;
+	u32 mem_off;
+	u32 fh_off = 0;
+	u32 frame_off = 0;
+	size_t frame_len = 0;
+	size_t mem_len;
+	size_t tlen;
+	size_t off_in_page;
+	struct page *page;
+	int use_sg;
+	int error;
+	void *page_addr;
+	void *from;
+	void *to = NULL;
+
+	ep = fc_seq_exch(cmd->seq);
+	lport = ep->lp;
+	cmd->seq = lport->tt.seq_start_next(cmd->seq);
+
+	task = T_TASK(se_cmd);
+	BUG_ON(!task);
+	remaining = se_cmd->data_length;
+
+	/*
+	 * Setup to use first mem list entry if any.
+	 */
+	if (task->t_tasks_se_num) {
+		mem = list_first_entry(task->t_mem_list,
+			 struct se_mem, se_list);
+		mem_len = mem->se_len;
+		mem_off = mem->se_off;
+		page = mem->se_page;
+	} else {
+		mem = NULL;
+		mem_len = remaining;
+		mem_off = 0;
+		page = NULL;
+	}
+
+	/* no scatter/gather in skb for odd word length due to fc_seq_send() */
+	use_sg = !(remaining % 4);
+
+	while (remaining) {
+		if (!mem_len) {
+			BUG_ON(!mem);
+			mem = list_entry(mem->se_list.next,
+				struct se_mem, se_list);
+			mem_len = min((size_t)mem->se_len, remaining);
+			mem_off = mem->se_off;
+			page = mem->se_page;
+		}
+		if (!frame_len) {
+			/*
+			 * If lport's has capability of Large Send Offload LSO)
+			 * , then allow 'frame_len' to be as big as 'lso_max'
+			 * if indicated transfer length is >= lport->lso_max
+			 */
+			frame_len = (lport->seq_offload) ? lport->lso_max :
+							  cmd->sess->max_frame;
+			frame_len = min(frame_len, remaining);
+			fp = fc_frame_alloc(lport, use_sg ? 0 : frame_len);
+			if (!fp)
+				return -ENOMEM;
+			to = fc_frame_payload_get(fp, 0);
+			fh_off = frame_off;
+			frame_off += frame_len;
+			/*
+			 * Setup the frame's max payload which is used by base
+			 * driver to indicate HW about max frame size, so that
+			 * HW can do fragmentation appropriately based on
+			 * "gso_max_size" of underline netdev.
+			 */
+			fr_max_payload(fp) = cmd->sess->max_frame;
+		}
+		tlen = min(mem_len, frame_len);
+
+		if (use_sg) {
+			if (!mem) {
+				BUG_ON(!task->t_task_buf);
+				page_addr = task->t_task_buf + mem_off;
+				/*
+				 * In this case, offset is 'offset_in_page' of
+				 * (t_task_buf + mem_off) instead of 'mem_off'.
+				 */
+				off_in_page = offset_in_page(page_addr);
+				page = virt_to_page(page_addr);
+				tlen = min(tlen, PAGE_SIZE - off_in_page);
+			} else
+				off_in_page = mem_off;
+			BUG_ON(!page);
+			get_page(page);
+			skb_fill_page_desc(fp_skb(fp),
+					   skb_shinfo(fp_skb(fp))->nr_frags,
+					   page, off_in_page, tlen);
+			fr_len(fp) += tlen;
+			fp_skb(fp)->data_len += tlen;
+			fp_skb(fp)->truesize +=
+					PAGE_SIZE << compound_order(page);
+		} else if (mem) {
+			BUG_ON(!page);
+			from = kmap_atomic(page + (mem_off >> PAGE_SHIFT),
+					   KM_SOFTIRQ0);
+			page_addr = from;
+			from += mem_off & ~PAGE_MASK;
+			tlen = min(tlen, (size_t)(PAGE_SIZE -
+						(mem_off & ~PAGE_MASK)));
+			memcpy(to, from, tlen);
+			kunmap_atomic(page_addr, KM_SOFTIRQ0);
+			to += tlen;
+		} else {
+			from = task->t_task_buf + mem_off;
+			memcpy(to, from, tlen);
+			to += tlen;
+		}
+
+		mem_off += tlen;
+		mem_len -= tlen;
+		frame_len -= tlen;
+		remaining -= tlen;
+
+		if (frame_len &&
+		    (skb_shinfo(fp_skb(fp))->nr_frags < FC_FRAME_SG_LEN))
+			continue;
+		if (!remaining)
+			f_ctl |= FC_FC_END_SEQ;
+		fc_fill_fc_hdr(fp, FC_RCTL_DD_SOL_DATA, ep->did, ep->sid,
+			       FC_TYPE_FCP, f_ctl, fh_off);
+		error = lport->tt.seq_send(lport, cmd->seq, fp);
+		if (error) {
+			/* XXX For now, initiator will retry */
+			if (printk_ratelimit())
+				printk(KERN_ERR "%s: Failed to send frame %p, "
+						"xid <0x%x>, remaining %zu, "
+						"lso_max <0x%x>\n",
+						__func__, fp, ep->xid,
+						remaining, lport->lso_max);
+		}
+	}
+	return ft_queue_status(se_cmd);
+}
+
+/*
+ * Receive write data frame.
+ */
+void ft_recv_write_data(struct ft_cmd *cmd, struct fc_frame *fp)
+{
+	struct se_cmd *se_cmd = &cmd->se_cmd;
+	struct fc_seq *seq = cmd->seq;
+	struct fc_exch *ep;
+	struct fc_lport *lport;
+	struct se_transport_task *task;
+	struct fc_frame_header *fh;
+	struct se_mem *mem;
+	u32 mem_off;
+	u32 rel_off;
+	size_t frame_len;
+	size_t mem_len;
+	size_t tlen;
+	struct page *page;
+	void *page_addr;
+	void *from;
+	void *to;
+	u32 f_ctl;
+	void *buf;
+
+	task = T_TASK(se_cmd);
+	BUG_ON(!task);
+
+	fh = fc_frame_header_get(fp);
+	if (!(ntoh24(fh->fh_f_ctl) & FC_FC_REL_OFF))
+		goto drop;
+
+	/*
+	 * Doesn't expect even single byte of payload. Payload
+	 * is expected to be copied directly to user buffers
+	 * due to DDP (Large Rx offload) feature, hence
+	 * BUG_ON if BUF is non-NULL
+	 */
+	buf = fc_frame_payload_get(fp, 1);
+	if (cmd->was_ddp_setup && buf) {
+		printk(KERN_INFO "%s: When DDP was setup, not expected to"
+				 "receive frame with payload, Payload shall be"
+				 "copied directly to buffer instead of coming "
+				 "via. legacy receive queues\n", __func__);
+		BUG_ON(buf);
+	}
+
+	/*
+	 * If ft_cmd indicated 'ddp_setup', in that case only the last frame
+	 * should come with 'TSI bit being set'. If 'TSI bit is not set and if
+	 * data frame appears here, means error condition. In both the cases
+	 * release the DDP context (ddp_put) and in error case, as well
+	 * initiate error recovery mechanism.
+	 */
+	ep = fc_seq_exch(seq);
+	if (cmd->was_ddp_setup) {
+		BUG_ON(!ep);
+		lport = ep->lp;
+		BUG_ON(!lport);
+	}
+	if (cmd->was_ddp_setup && ep->xid != FC_XID_UNKNOWN) {
+		f_ctl = ntoh24(fh->fh_f_ctl);
+		/*
+		 * If TSI bit set in f_ctl, means last write data frame is
+		 * received successfully where payload is posted directly
+		 * to user buffer and only the last frame's header is posted
+		 * in legacy receive queue
+		 */
+		if (f_ctl & FC_FC_SEQ_INIT) { /* TSI bit set in FC frame */
+			cmd->write_data_len = lport->tt.ddp_done(lport,
+								ep->xid);
+			goto last_frame;
+		} else {
+			/*
+			 * Updating the write_data_len may be meaningless at
+			 * this point, but just in case if required in future
+			 * for debugging or any other purpose
+			 */
+			printk(KERN_ERR "%s: Received frame with TSI bit not"
+					" being SET, dropping the frame, "
+					"cmd->sg <%p>, cmd->sg_cnt <0x%x>\n",
+					__func__, cmd->sg, cmd->sg_cnt);
+			cmd->write_data_len = lport->tt.ddp_done(lport,
+							      ep->xid);
+			lport->tt.seq_exch_abort(cmd->seq, 0);
+			goto drop;
+		}
+	}
+
+	rel_off = ntohl(fh->fh_parm_offset);
+	frame_len = fr_len(fp);
+	if (frame_len <= sizeof(*fh))
+		goto drop;
+	frame_len -= sizeof(*fh);
+	from = fc_frame_payload_get(fp, 0);
+	if (rel_off >= se_cmd->data_length)
+		goto drop;
+	if (frame_len + rel_off > se_cmd->data_length)
+		frame_len = se_cmd->data_length - rel_off;
+
+	/*
+	 * Setup to use first mem list entry if any.
+	 */
+	if (task->t_tasks_se_num) {
+		mem = list_first_entry(task->t_mem_list,
+				       struct se_mem, se_list);
+		mem_len = mem->se_len;
+		mem_off = mem->se_off;
+		page = mem->se_page;
+	} else {
+		mem = NULL;
+		page = NULL;
+		mem_off = 0;
+		mem_len = frame_len;
+	}
+
+	while (frame_len) {
+		if (!mem_len) {
+			BUG_ON(!mem);
+			mem = list_entry(mem->se_list.next,
+					 struct se_mem, se_list);
+			mem_len = mem->se_len;
+			mem_off = mem->se_off;
+			page = mem->se_page;
+		}
+		if (rel_off >= mem_len) {
+			rel_off -= mem_len;
+			mem_len = 0;
+			continue;
+		}
+		mem_off += rel_off;
+		mem_len -= rel_off;
+		rel_off = 0;
+
+		tlen = min(mem_len, frame_len);
+
+		if (mem) {
+			to = kmap_atomic(page + (mem_off >> PAGE_SHIFT),
+					 KM_SOFTIRQ0);
+			page_addr = to;
+			to += mem_off & ~PAGE_MASK;
+			tlen = min(tlen, (size_t)(PAGE_SIZE -
+						(mem_off & ~PAGE_MASK)));
+			memcpy(to, from, tlen);
+			kunmap_atomic(page_addr, KM_SOFTIRQ0);
+		} else {
+			to = task->t_task_buf + mem_off;
+			memcpy(to, from, tlen);
+		}
+		from += tlen;
+		frame_len -= tlen;
+		mem_off += tlen;
+		mem_len -= tlen;
+		cmd->write_data_len += tlen;
+	}
+last_frame:
+	if (cmd->write_data_len == se_cmd->data_length)
+		transport_generic_handle_data(se_cmd);
+drop:
+	fc_frame_free(fp);
+}
diff -druN linux-2.6.39-libre/drivers/target/tcm_fc/tfc_sess.c linux-3.0-rc7-libre/drivers/target/tcm_fc/tfc_sess.c
--- linux-2.6.39-libre/drivers/target/tcm_fc/tfc_sess.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/target/tcm_fc/tfc_sess.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,541 @@
+/*
+ * Copyright (c) 2010 Cisco Systems, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+/* XXX TBD some includes may be extraneous */
+
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/version.h>
+#include <generated/utsrelease.h>
+#include <linux/utsname.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/kthread.h>
+#include <linux/types.h>
+#include <linux/string.h>
+#include <linux/configfs.h>
+#include <linux/ctype.h>
+#include <linux/hash.h>
+#include <linux/rcupdate.h>
+#include <linux/rculist.h>
+#include <linux/kref.h>
+#include <asm/unaligned.h>
+#include <scsi/scsi.h>
+#include <scsi/scsi_host.h>
+#include <scsi/scsi_device.h>
+#include <scsi/scsi_cmnd.h>
+#include <scsi/libfc.h>
+
+#include <target/target_core_base.h>
+#include <target/target_core_transport.h>
+#include <target/target_core_fabric_ops.h>
+#include <target/target_core_device.h>
+#include <target/target_core_tpg.h>
+#include <target/target_core_configfs.h>
+#include <target/target_core_base.h>
+#include <target/configfs_macros.h>
+
+#include <scsi/libfc.h>
+#include "tcm_fc.h"
+
+static void ft_sess_delete_all(struct ft_tport *);
+
+/*
+ * Lookup or allocate target local port.
+ * Caller holds ft_lport_lock.
+ */
+static struct ft_tport *ft_tport_create(struct fc_lport *lport)
+{
+	struct ft_tpg *tpg;
+	struct ft_tport *tport;
+	int i;
+
+	tport = rcu_dereference(lport->prov[FC_TYPE_FCP]);
+	if (tport && tport->tpg)
+		return tport;
+
+	tpg = ft_lport_find_tpg(lport);
+	if (!tpg)
+		return NULL;
+
+	if (tport) {
+		tport->tpg = tpg;
+		return tport;
+	}
+
+	tport = kzalloc(sizeof(*tport), GFP_KERNEL);
+	if (!tport)
+		return NULL;
+
+	tport->lport = lport;
+	tport->tpg = tpg;
+	tpg->tport = tport;
+	for (i = 0; i < FT_SESS_HASH_SIZE; i++)
+		INIT_HLIST_HEAD(&tport->hash[i]);
+
+	rcu_assign_pointer(lport->prov[FC_TYPE_FCP], tport);
+	return tport;
+}
+
+/*
+ * Free tport via RCU.
+ */
+static void ft_tport_rcu_free(struct rcu_head *rcu)
+{
+	struct ft_tport *tport = container_of(rcu, struct ft_tport, rcu);
+
+	kfree(tport);
+}
+
+/*
+ * Delete a target local port.
+ * Caller holds ft_lport_lock.
+ */
+static void ft_tport_delete(struct ft_tport *tport)
+{
+	struct fc_lport *lport;
+	struct ft_tpg *tpg;
+
+	ft_sess_delete_all(tport);
+	lport = tport->lport;
+	BUG_ON(tport != lport->prov[FC_TYPE_FCP]);
+	rcu_assign_pointer(lport->prov[FC_TYPE_FCP], NULL);
+
+	tpg = tport->tpg;
+	if (tpg) {
+		tpg->tport = NULL;
+		tport->tpg = NULL;
+	}
+	call_rcu(&tport->rcu, ft_tport_rcu_free);
+}
+
+/*
+ * Add local port.
+ * Called thru fc_lport_iterate().
+ */
+void ft_lport_add(struct fc_lport *lport, void *arg)
+{
+	mutex_lock(&ft_lport_lock);
+	ft_tport_create(lport);
+	mutex_unlock(&ft_lport_lock);
+}
+
+/*
+ * Delete local port.
+ * Called thru fc_lport_iterate().
+ */
+void ft_lport_del(struct fc_lport *lport, void *arg)
+{
+	struct ft_tport *tport;
+
+	mutex_lock(&ft_lport_lock);
+	tport = lport->prov[FC_TYPE_FCP];
+	if (tport)
+		ft_tport_delete(tport);
+	mutex_unlock(&ft_lport_lock);
+}
+
+/*
+ * Notification of local port change from libfc.
+ * Create or delete local port and associated tport.
+ */
+int ft_lport_notify(struct notifier_block *nb, unsigned long event, void *arg)
+{
+	struct fc_lport *lport = arg;
+
+	switch (event) {
+	case FC_LPORT_EV_ADD:
+		ft_lport_add(lport, NULL);
+		break;
+	case FC_LPORT_EV_DEL:
+		ft_lport_del(lport, NULL);
+		break;
+	}
+	return NOTIFY_DONE;
+}
+
+/*
+ * Hash function for FC_IDs.
+ */
+static u32 ft_sess_hash(u32 port_id)
+{
+	return hash_32(port_id, FT_SESS_HASH_BITS);
+}
+
+/*
+ * Find session in local port.
+ * Sessions and hash lists are RCU-protected.
+ * A reference is taken which must be eventually freed.
+ */
+static struct ft_sess *ft_sess_get(struct fc_lport *lport, u32 port_id)
+{
+	struct ft_tport *tport;
+	struct hlist_head *head;
+	struct hlist_node *pos;
+	struct ft_sess *sess;
+
+	rcu_read_lock();
+	tport = rcu_dereference(lport->prov[FC_TYPE_FCP]);
+	if (!tport)
+		goto out;
+
+	head = &tport->hash[ft_sess_hash(port_id)];
+	hlist_for_each_entry_rcu(sess, pos, head, hash) {
+		if (sess->port_id == port_id) {
+			kref_get(&sess->kref);
+			rcu_read_unlock();
+			FT_SESS_DBG("port_id %x found %p\n", port_id, sess);
+			return sess;
+		}
+	}
+out:
+	rcu_read_unlock();
+	FT_SESS_DBG("port_id %x not found\n", port_id);
+	return NULL;
+}
+
+/*
+ * Allocate session and enter it in the hash for the local port.
+ * Caller holds ft_lport_lock.
+ */
+static struct ft_sess *ft_sess_create(struct ft_tport *tport, u32 port_id,
+				      struct ft_node_acl *acl)
+{
+	struct ft_sess *sess;
+	struct hlist_head *head;
+	struct hlist_node *pos;
+
+	head = &tport->hash[ft_sess_hash(port_id)];
+	hlist_for_each_entry_rcu(sess, pos, head, hash)
+		if (sess->port_id == port_id)
+			return sess;
+
+	sess = kzalloc(sizeof(*sess), GFP_KERNEL);
+	if (!sess)
+		return NULL;
+
+	sess->se_sess = transport_init_session();
+	if (IS_ERR(sess->se_sess)) {
+		kfree(sess);
+		return NULL;
+	}
+	sess->se_sess->se_node_acl = &acl->se_node_acl;
+	sess->tport = tport;
+	sess->port_id = port_id;
+	kref_init(&sess->kref);	/* ref for table entry */
+	hlist_add_head_rcu(&sess->hash, head);
+	tport->sess_count++;
+
+	FT_SESS_DBG("port_id %x sess %p\n", port_id, sess);
+
+	transport_register_session(&tport->tpg->se_tpg, &acl->se_node_acl,
+				   sess->se_sess, sess);
+	return sess;
+}
+
+/*
+ * Unhash the session.
+ * Caller holds ft_lport_lock.
+ */
+static void ft_sess_unhash(struct ft_sess *sess)
+{
+	struct ft_tport *tport = sess->tport;
+
+	hlist_del_rcu(&sess->hash);
+	BUG_ON(!tport->sess_count);
+	tport->sess_count--;
+	sess->port_id = -1;
+	sess->params = 0;
+}
+
+/*
+ * Delete session from hash.
+ * Caller holds ft_lport_lock.
+ */
+static struct ft_sess *ft_sess_delete(struct ft_tport *tport, u32 port_id)
+{
+	struct hlist_head *head;
+	struct hlist_node *pos;
+	struct ft_sess *sess;
+
+	head = &tport->hash[ft_sess_hash(port_id)];
+	hlist_for_each_entry_rcu(sess, pos, head, hash) {
+		if (sess->port_id == port_id) {
+			ft_sess_unhash(sess);
+			return sess;
+		}
+	}
+	return NULL;
+}
+
+/*
+ * Delete all sessions from tport.
+ * Caller holds ft_lport_lock.
+ */
+static void ft_sess_delete_all(struct ft_tport *tport)
+{
+	struct hlist_head *head;
+	struct hlist_node *pos;
+	struct ft_sess *sess;
+
+	for (head = tport->hash;
+	     head < &tport->hash[FT_SESS_HASH_SIZE]; head++) {
+		hlist_for_each_entry_rcu(sess, pos, head, hash) {
+			ft_sess_unhash(sess);
+			transport_deregister_session_configfs(sess->se_sess);
+			ft_sess_put(sess);	/* release from table */
+		}
+	}
+}
+
+/*
+ * TCM ops for sessions.
+ */
+
+/*
+ * Determine whether session is allowed to be shutdown in the current context.
+ * Returns non-zero if the session should be shutdown.
+ */
+int ft_sess_shutdown(struct se_session *se_sess)
+{
+	struct ft_sess *sess = se_sess->fabric_sess_ptr;
+
+	FT_SESS_DBG("port_id %x\n", sess->port_id);
+	return 1;
+}
+
+/*
+ * Remove session and send PRLO.
+ * This is called when the ACL is being deleted or queue depth is changing.
+ */
+void ft_sess_close(struct se_session *se_sess)
+{
+	struct ft_sess *sess = se_sess->fabric_sess_ptr;
+	struct fc_lport *lport;
+	u32 port_id;
+
+	mutex_lock(&ft_lport_lock);
+	lport = sess->tport->lport;
+	port_id = sess->port_id;
+	if (port_id == -1) {
+		mutex_unlock(&ft_lport_lock);
+		return;
+	}
+	FT_SESS_DBG("port_id %x\n", port_id);
+	ft_sess_unhash(sess);
+	mutex_unlock(&ft_lport_lock);
+	transport_deregister_session_configfs(se_sess);
+	ft_sess_put(sess);
+	/* XXX Send LOGO or PRLO */
+	synchronize_rcu();		/* let transport deregister happen */
+}
+
+void ft_sess_stop(struct se_session *se_sess, int sess_sleep, int conn_sleep)
+{
+	struct ft_sess *sess = se_sess->fabric_sess_ptr;
+
+	FT_SESS_DBG("port_id %x\n", sess->port_id);
+}
+
+int ft_sess_logged_in(struct se_session *se_sess)
+{
+	struct ft_sess *sess = se_sess->fabric_sess_ptr;
+
+	return sess->port_id != -1;
+}
+
+u32 ft_sess_get_index(struct se_session *se_sess)
+{
+	struct ft_sess *sess = se_sess->fabric_sess_ptr;
+
+	return sess->port_id;	/* XXX TBD probably not what is needed */
+}
+
+u32 ft_sess_get_port_name(struct se_session *se_sess,
+			  unsigned char *buf, u32 len)
+{
+	struct ft_sess *sess = se_sess->fabric_sess_ptr;
+
+	return ft_format_wwn(buf, len, sess->port_name);
+}
+
+void ft_sess_set_erl0(struct se_session *se_sess)
+{
+	/* XXX TBD called when out of memory */
+}
+
+/*
+ * libfc ops involving sessions.
+ */
+
+static int ft_prli_locked(struct fc_rport_priv *rdata, u32 spp_len,
+			  const struct fc_els_spp *rspp, struct fc_els_spp *spp)
+{
+	struct ft_tport *tport;
+	struct ft_sess *sess;
+	struct ft_node_acl *acl;
+	u32 fcp_parm;
+
+	tport = ft_tport_create(rdata->local_port);
+	if (!tport)
+		return 0;	/* not a target for this local port */
+
+	acl = ft_acl_get(tport->tpg, rdata);
+	if (!acl)
+		return 0;
+
+	if (!rspp)
+		goto fill;
+
+	if (rspp->spp_flags & (FC_SPP_OPA_VAL | FC_SPP_RPA_VAL))
+		return FC_SPP_RESP_NO_PA;
+
+	/*
+	 * If both target and initiator bits are off, the SPP is invalid.
+	 */
+	fcp_parm = ntohl(rspp->spp_params);
+	if (!(fcp_parm & (FCP_SPPF_INIT_FCN | FCP_SPPF_TARG_FCN)))
+		return FC_SPP_RESP_INVL;
+
+	/*
+	 * Create session (image pair) only if requested by
+	 * EST_IMG_PAIR flag and if the requestor is an initiator.
+	 */
+	if (rspp->spp_flags & FC_SPP_EST_IMG_PAIR) {
+		spp->spp_flags |= FC_SPP_EST_IMG_PAIR;
+		if (!(fcp_parm & FCP_SPPF_INIT_FCN))
+			return FC_SPP_RESP_CONF;
+		sess = ft_sess_create(tport, rdata->ids.port_id, acl);
+		if (!sess)
+			return FC_SPP_RESP_RES;
+		if (!sess->params)
+			rdata->prli_count++;
+		sess->params = fcp_parm;
+		sess->port_name = rdata->ids.port_name;
+		sess->max_frame = rdata->maxframe_size;
+
+		/* XXX TBD - clearing actions.  unit attn, see 4.10 */
+	}
+
+	/*
+	 * OR in our service parameters with other provider (initiator), if any.
+	 * TBD XXX - indicate RETRY capability?
+	 */
+fill:
+	fcp_parm = ntohl(spp->spp_params);
+	spp->spp_params = htonl(fcp_parm | FCP_SPPF_TARG_FCN);
+	return FC_SPP_RESP_ACK;
+}
+
+/**
+ * tcm_fcp_prli() - Handle incoming or outgoing PRLI for the FCP target
+ * @rdata: remote port private
+ * @spp_len: service parameter page length
+ * @rspp: received service parameter page (NULL for outgoing PRLI)
+ * @spp: response service parameter page
+ *
+ * Returns spp response code.
+ */
+static int ft_prli(struct fc_rport_priv *rdata, u32 spp_len,
+		   const struct fc_els_spp *rspp, struct fc_els_spp *spp)
+{
+	int ret;
+
+	mutex_lock(&ft_lport_lock);
+	ret = ft_prli_locked(rdata, spp_len, rspp, spp);
+	mutex_unlock(&ft_lport_lock);
+	FT_SESS_DBG("port_id %x flags %x ret %x\n",
+	       rdata->ids.port_id, rspp ? rspp->spp_flags : 0, ret);
+	return ret;
+}
+
+static void ft_sess_rcu_free(struct rcu_head *rcu)
+{
+	struct ft_sess *sess = container_of(rcu, struct ft_sess, rcu);
+
+	transport_deregister_session(sess->se_sess);
+	kfree(sess);
+}
+
+static void ft_sess_free(struct kref *kref)
+{
+	struct ft_sess *sess = container_of(kref, struct ft_sess, kref);
+
+	call_rcu(&sess->rcu, ft_sess_rcu_free);
+}
+
+void ft_sess_put(struct ft_sess *sess)
+{
+	int sess_held = atomic_read(&sess->kref.refcount);
+
+	BUG_ON(!sess_held);
+	kref_put(&sess->kref, ft_sess_free);
+}
+
+static void ft_prlo(struct fc_rport_priv *rdata)
+{
+	struct ft_sess *sess;
+	struct ft_tport *tport;
+
+	mutex_lock(&ft_lport_lock);
+	tport = rcu_dereference(rdata->local_port->prov[FC_TYPE_FCP]);
+	if (!tport) {
+		mutex_unlock(&ft_lport_lock);
+		return;
+	}
+	sess = ft_sess_delete(tport, rdata->ids.port_id);
+	if (!sess) {
+		mutex_unlock(&ft_lport_lock);
+		return;
+	}
+	mutex_unlock(&ft_lport_lock);
+	transport_deregister_session_configfs(sess->se_sess);
+	ft_sess_put(sess);		/* release from table */
+	rdata->prli_count--;
+	/* XXX TBD - clearing actions.  unit attn, see 4.10 */
+}
+
+/*
+ * Handle incoming FCP request.
+ * Caller has verified that the frame is type FCP.
+ */
+static void ft_recv(struct fc_lport *lport, struct fc_frame *fp)
+{
+	struct ft_sess *sess;
+	u32 sid = fc_frame_sid(fp);
+
+	FT_SESS_DBG("sid %x\n", sid);
+
+	sess = ft_sess_get(lport, sid);
+	if (!sess) {
+		FT_SESS_DBG("sid %x sess lookup failed\n", sid);
+		/* TBD XXX - if FCP_CMND, send PRLO */
+		fc_frame_free(fp);
+		return;
+	}
+	ft_recv_req(sess, fp);	/* must do ft_sess_put() */
+}
+
+/*
+ * Provider ops for libfc.
+ */
+struct fc4_prov ft_prov = {
+	.prli = ft_prli,
+	.prlo = ft_prlo,
+	.recv = ft_recv,
+	.module = THIS_MODULE,
+};
diff -druN linux-2.6.39-libre/drivers/telephony/ixj_pcmcia.c linux-3.0-rc7-libre/drivers/telephony/ixj_pcmcia.c
--- linux-2.6.39-libre/drivers/telephony/ixj_pcmcia.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/telephony/ixj_pcmcia.c	2011-07-11 19:51:52.000000000 -0400
@@ -157,7 +157,7 @@
 	pcmcia_disable_device(link);
 }
 
-static struct pcmcia_device_id ixj_ids[] = {
+static const struct pcmcia_device_id ixj_ids[] = {
 	PCMCIA_DEVICE_MANF_CARD(0x0257, 0x0600),
 	PCMCIA_DEVICE_NULL
 };
diff -druN linux-2.6.39-libre/drivers/thermal/thermal_sys.c linux-3.0-rc7-libre/drivers/thermal/thermal_sys.c
--- linux-2.6.39-libre/drivers/thermal/thermal_sys.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/thermal/thermal_sys.c	2011-07-11 19:51:52.000000000 -0400
@@ -499,7 +499,7 @@
 	dev_set_drvdata(hwmon->device, hwmon);
 	result = device_create_file(hwmon->device, &dev_attr_name);
 	if (result)
-		goto unregister_hwmon_device;
+		goto free_mem;
 
  register_sys_interface:
 	tz->hwmon = hwmon;
@@ -513,7 +513,7 @@
 	sysfs_attr_init(&tz->temp_input.attr.attr);
 	result = device_create_file(hwmon->device, &tz->temp_input.attr);
 	if (result)
-		goto unregister_hwmon_device;
+		goto unregister_name;
 
 	if (tz->ops->get_crit_temp) {
 		unsigned long temperature;
@@ -527,7 +527,7 @@
 			result = device_create_file(hwmon->device,
 						    &tz->temp_crit.attr);
 			if (result)
-				goto unregister_hwmon_device;
+				goto unregister_input;
 		}
 	}
 
@@ -539,9 +539,9 @@
 
 	return 0;
 
- unregister_hwmon_device:
-	device_remove_file(hwmon->device, &tz->temp_crit.attr);
+ unregister_input:
 	device_remove_file(hwmon->device, &tz->temp_input.attr);
+ unregister_name:
 	if (new_hwmon_device) {
 		device_remove_file(hwmon->device, &dev_attr_name);
 		hwmon_device_unregister(hwmon->device);
diff -druN linux-2.6.39-libre/drivers/tty/amiserial.c linux-3.0-rc7-libre/drivers/tty/amiserial.c
--- linux-2.6.39-libre/drivers/tty/amiserial.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/tty/amiserial.c	2011-07-11 19:51:52.000000000 -0400
@@ -1,6 +1,4 @@
 /*
- *  linux/drivers/char/amiserial.c
- *
  * Serial driver for the amiga builtin port.
  *
  * This code was created by taking serial.c version 4.30 from kernel
diff -druN linux-2.6.39-libre/drivers/tty/cyclades.c linux-3.0-rc7-libre/drivers/tty/cyclades.c
--- linux-2.6.39-libre/drivers/tty/cyclades.c	2011-05-19 02:07:43.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/tty/cyclades.c	2011-07-21 06:49:46.000000000 -0400
@@ -3,8 +3,6 @@
 #undef	Z_EXT_CHARS_IN_BUFFER
 
 /*
- *  linux/drivers/char/cyclades.c
- *
  * This file contains the driver for the Cyclades async multiport
  * serial boards.
  *
@@ -1445,13 +1443,11 @@
 {
 	struct cyclades_card *card;
 	unsigned long flags;
-	int channel;
 
 	if (!(info->port.flags & ASYNC_INITIALIZED))
 		return;
 
 	card = info->card;
-	channel = info->line - card->first_line;
 	if (!cy_is_Z(card)) {
 		spin_lock_irqsave(&card->card_lock, flags);
 
@@ -1476,6 +1472,7 @@
 		spin_unlock_irqrestore(&card->card_lock, flags);
 	} else {
 #ifdef CY_DEBUG_OPEN
+		int channel = info->line - card->first_line;
 		printk(KERN_DEBUG "cyc shutdown Z card %d, channel %d, "
 			"base_addr %p\n", card, channel, card->base_addr);
 #endif
@@ -4099,8 +4096,7 @@
 	if (!cy_serial_driver)
 		goto err;
 
-	printk(KERN_INFO "Cyclades driver " CY_VERSION " (built %s %s)\n",
-			__DATE__, __TIME__);
+	printk(KERN_INFO "Cyclades driver " CY_VERSION "\n");
 
 	/* Initialize the tty_driver structure */
 
diff -druN linux-2.6.39-libre/drivers/tty/ipwireless/main.c linux-3.0-rc7-libre/drivers/tty/ipwireless/main.c
--- linux-2.6.39-libre/drivers/tty/ipwireless/main.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/tty/ipwireless/main.c	2011-07-11 19:51:52.000000000 -0400
@@ -33,7 +33,7 @@
 #include <pcmcia/ss.h>
 #include <pcmcia/ds.h>
 
-static struct pcmcia_device_id ipw_ids[] = {
+static const struct pcmcia_device_id ipw_ids[] = {
 	PCMCIA_DEVICE_MANF_CARD(0x02f2, 0x0100),
 	PCMCIA_DEVICE_MANF_CARD(0x02f2, 0x0200),
 	PCMCIA_DEVICE_NULL
diff -druN linux-2.6.39-libre/drivers/tty/ipwireless/Makefile linux-3.0-rc7-libre/drivers/tty/ipwireless/Makefile
--- linux-2.6.39-libre/drivers/tty/ipwireless/Makefile	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/tty/ipwireless/Makefile	2011-07-11 19:51:52.000000000 -0400
@@ -1,6 +1,4 @@
 #
-# drivers/char/pcmcia/ipwireless/Makefile
-#
 # Makefile for the IPWireless driver
 #
 
diff -druN linux-2.6.39-libre/drivers/tty/Kconfig linux-3.0-rc7-libre/drivers/tty/Kconfig
--- linux-2.6.39-libre/drivers/tty/Kconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/tty/Kconfig	2011-07-11 19:51:52.000000000 -0400
@@ -319,3 +319,34 @@
 	  This line discipline provides support for the GSM MUX protocol and
 	  presents the mux as a set of 61 individual tty devices.
 
+config TRACE_ROUTER
+	tristate "Trace data router for MIPI P1149.7 cJTAG standard"
+	depends on TRACE_SINK
+	default n
+	help
+	  The trace router uses the Linux tty line discipline framework to
+	  route trace data coming from a tty port (say UART for example) to
+	  the trace sink line discipline driver and to another tty port (say
+	  USB). This is part of a solution for the MIPI P1149.7, compact JTAG,
+	  standard, which is for debugging mobile devices. The PTI driver in
+	  drivers/misc/pti.c defines the majority of this MIPI solution.
+
+	  You should select this driver if the target kernel is meant for
+	  a mobile device containing a modem.  Then you will need to select
+	  "Trace data sink for MIPI P1149.7 cJTAG standard" line discipline
+	  driver.
+
+config TRACE_SINK
+	tristate "Trace data sink for MIPI P1149.7 cJTAG standard"
+	default n
+	help
+	  The trace sink uses the Linux line discipline framework to receive
+	  trace data coming from the trace router line discipline driver
+	  to a user-defined tty port target, like USB.
+	  This is to provide a way to extract modem trace data on
+	  devices that do not have a PTI HW module, or just need modem
+	  trace data to come out of a different HW output port.
+	  This is part of a solution for the P1149.7, compact JTAG, standard.
+
+	  If you select this option, you need to select
+	  "Trace data router for MIPI P1149.7 cJTAG standard".
diff -druN linux-2.6.39-libre/drivers/tty/Makefile linux-3.0-rc7-libre/drivers/tty/Makefile
--- linux-2.6.39-libre/drivers/tty/Makefile	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/tty/Makefile	2011-07-11 19:51:52.000000000 -0400
@@ -6,6 +6,8 @@
 obj-$(CONFIG_MAGIC_SYSRQ)	+= sysrq.o
 obj-$(CONFIG_N_HDLC)		+= n_hdlc.o
 obj-$(CONFIG_N_GSM)		+= n_gsm.o
+obj-$(CONFIG_TRACE_ROUTER)	+= n_tracerouter.o
+obj-$(CONFIG_TRACE_SINK)	+= n_tracesink.o
 obj-$(CONFIG_R3964)		+= n_r3964.o
 
 obj-y				+= vt/
diff -druN linux-2.6.39-libre/drivers/tty/moxa.c linux-3.0-rc7-libre/drivers/tty/moxa.c
--- linux-2.6.39-libre/drivers/tty/moxa.c	2011-05-19 02:07:49.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/tty/moxa.c	2011-07-21 06:49:53.000000000 -0400
@@ -369,7 +369,7 @@
 					tmp.cflag = p->cflag;
 				else
 					tmp.cflag = ttyp->termios->c_cflag;
-				tty_kref_put(tty);
+				tty_kref_put(ttyp);
 copy:
 				if (copy_to_user(argm, &tmp, sizeof(tmp)))
 					return -EFAULT;
@@ -1127,7 +1127,6 @@
 	struct moxa_port *ch = container_of(port, struct moxa_port, port);
         MoxaPortDisable(ch);
 	MoxaPortFlushData(ch, 2);
-	clear_bit(ASYNCB_NORMAL_ACTIVE, &port->flags);
 }
 
 static int moxa_carrier_raised(struct tty_port *port)
@@ -1153,7 +1152,6 @@
 	struct moxa_board_conf *brd;
 	struct moxa_port *ch;
 	int port;
-	int retval;
 
 	port = tty->index;
 	if (port == MAX_PORTS) {
@@ -1188,10 +1186,7 @@
 	mutex_unlock(&ch->port.mutex);
 	mutex_unlock(&moxa_openlock);
 
-	retval = tty_port_block_til_ready(&ch->port, tty, filp);
-	if (retval == 0)
-	        set_bit(ASYNCB_NORMAL_ACTIVE, &ch->port.flags);
-	return retval;
+	return tty_port_block_til_ready(&ch->port, tty, filp);
 }
 
 static void moxa_close(struct tty_struct *tty, struct file *filp)
@@ -1205,14 +1200,15 @@
 		      const unsigned char *buf, int count)
 {
 	struct moxa_port *ch = tty->driver_data;
+	unsigned long flags;
 	int len;
 
 	if (ch == NULL)
 		return 0;
 
-	spin_lock_bh(&moxa_lock);
+	spin_lock_irqsave(&moxa_lock, flags);
 	len = MoxaPortWriteData(tty, buf, count);
-	spin_unlock_bh(&moxa_lock);
+	spin_unlock_irqrestore(&moxa_lock, flags);
 
 	set_bit(LOWWAIT, &ch->statusflags);
 	return len;
@@ -1279,10 +1275,8 @@
 			 unsigned int set, unsigned int clear)
 {
 	struct moxa_port *ch;
-	int port;
 	int dtr, rts;
 
-	port = tty->index;
 	mutex_lock(&moxa_openlock);
 	ch = tty->driver_data;
 	if (!ch) {
@@ -1754,11 +1748,9 @@
 		speed_t baud)
 {
 	void __iomem *ofsAddr;
-	tcflag_t cflag;
 	tcflag_t mode = 0;
 
 	ofsAddr = port->tableAddr;
-	cflag = termio->c_cflag;	/* termio->c_cflag */
 
 	mode = termio->c_cflag & CSIZE;
 	if (mode == CS5)
diff -druN linux-2.6.39-libre/drivers/tty/n_gsm.c linux-3.0-rc7-libre/drivers/tty/n_gsm.c
--- linux-2.6.39-libre/drivers/tty/n_gsm.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/tty/n_gsm.c	2011-07-11 19:51:52.000000000 -0400
@@ -526,19 +526,6 @@
 	return olen;
 }
 
-static void hex_packet(const unsigned char *p, int len)
-{
-	int i;
-	for (i = 0; i < len; i++) {
-		if (i && (i % 16) == 0) {
-			pr_cont("\n");
-			pr_debug("");
-		}
-		pr_cont("%02X ", *p++);
-	}
-	pr_cont("\n");
-}
-
 /**
  *	gsm_send	-	send a control frame
  *	@gsm: our GSM mux
@@ -685,10 +672,10 @@
 			len = msg->len + 2;
 		}
 
-		if (debug & 4) {
-			pr_debug("gsm_data_kick:\n");
-			hex_packet(gsm->txframe, len);
-		}
+		if (debug & 4)
+			print_hex_dump_bytes("gsm_data_kick: ",
+					     DUMP_PREFIX_OFFSET,
+					     gsm->txframe, len);
 
 		if (gsm->output(gsm, gsm->txframe + skip_sof,
 						len - skip_sof) < 0)
@@ -888,7 +875,8 @@
 		*dp++ = last << 7 | first << 6 | 1;	/* EA */
 		len--;
 	}
-	memcpy(dp, skb_pull(dlci->skb, len), len);
+	memcpy(dp, dlci->skb->data, len);
+	skb_pull(dlci->skb, len);
 	__gsm_data_queue(dlci, msg);
 	if (last)
 		dlci->skb = NULL;
@@ -997,10 +985,22 @@
  */
 
 static void gsm_process_modem(struct tty_struct *tty, struct gsm_dlci *dlci,
-							u32 modem)
+							u32 modem, int clen)
 {
 	int  mlines = 0;
-	u8 brk = modem >> 6;
+	u8 brk = 0;
+
+	/* The modem status command can either contain one octet (v.24 signals)
+	   or two octets (v.24 signals + break signals). The length field will
+	   either be 2 or 3 respectively. This is specified in section
+	   5.4.6.3.7 of the  27.010 mux spec. */
+
+	if (clen == 2)
+		modem = modem & 0x7f;
+	else {
+		brk = modem & 0x7f;
+		modem = (modem >> 7) & 0x7f;
+	};
 
 	/* Flow control/ready to communicate */
 	if (modem & MDM_FC) {
@@ -1074,7 +1074,7 @@
 			return;
 	}
 	tty = tty_port_tty_get(&dlci->port);
-	gsm_process_modem(tty, dlci, modem);
+	gsm_process_modem(tty, dlci, modem, clen);
 	if (tty) {
 		tty_wakeup(tty);
 		tty_kref_put(tty);
@@ -1495,12 +1495,13 @@
  *	open we shovel the bits down it, if not we drop them.
  */
 
-static void gsm_dlci_data(struct gsm_dlci *dlci, u8 *data, int len)
+static void gsm_dlci_data(struct gsm_dlci *dlci, u8 *data, int clen)
 {
 	/* krefs .. */
 	struct tty_port *port = &dlci->port;
 	struct tty_struct *tty = tty_port_tty_get(port);
 	unsigned int modem = 0;
+	int len = clen;
 
 	if (debug & 16)
 		pr_debug("%d bytes for tty %p\n", len, tty);
@@ -1520,7 +1521,7 @@
 				if (len == 0)
 					return;
 			}
-			gsm_process_modem(tty, dlci, modem);
+			gsm_process_modem(tty, dlci, modem, clen);
 		/* Line state will go via DLCI 0 controls only */
 		case 1:
 		default:
@@ -2095,10 +2096,9 @@
 		set_bit(TTY_DO_WRITE_WAKEUP, &gsm->tty->flags);
 		return -ENOSPC;
 	}
-	if (debug & 4) {
-		pr_debug("-->%d bytes out\n", len);
-		hex_packet(data, len);
-	}
+	if (debug & 4)
+		print_hex_dump_bytes("gsmld_output: ", DUMP_PREFIX_OFFSET,
+				     data, len);
 	gsm->tty->ops->write(gsm->tty, data, len);
 	return len;
 }
@@ -2128,7 +2128,7 @@
 
 /**
  *	gsmld_detach_gsm	-	stop doing 0710 mux
- *	@tty: tty atttached to the mux
+ *	@tty: tty attached to the mux
  *	@gsm: mux
  *
  *	Shutdown and then clean up the resources used by the line discipline
@@ -2152,10 +2152,9 @@
 	char buf[64];
 	char flags;
 
-	if (debug & 4) {
-		pr_debug("Inbytes %dd\n", count);
-		hex_packet(cp, count);
-	}
+	if (debug & 4)
+		print_hex_dump_bytes("gsmld_receive: ", DUMP_PREFIX_OFFSET,
+				     cp, count);
 
 	for (i = count, dp = cp, f = fp; i; i--, dp++) {
 		flags = *f++;
diff -druN linux-2.6.39-libre/drivers/tty/nozomi.c linux-3.0-rc7-libre/drivers/tty/nozomi.c
--- linux-2.6.39-libre/drivers/tty/nozomi.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/tty/nozomi.c	2011-07-11 19:51:52.000000000 -0400
@@ -61,8 +61,7 @@
 #include <linux/delay.h>
 
 
-#define VERSION_STRING DRIVER_DESC " 2.1d (build date: " \
-					__DATE__ " " __TIME__ ")"
+#define VERSION_STRING DRIVER_DESC " 2.1d"
 
 /*    Macros definitions */
 
@@ -364,8 +363,6 @@
 	u8 toggle_ul;
 	u16 token_dl;
 
-	/* mutex to ensure one access patch to this port */
-	struct mutex tty_sem;
 	wait_queue_head_t tty_wait;
 	struct async_icount tty_icount;
 
@@ -1431,8 +1428,8 @@
 	}
 
 	for (i = PORT_MDM; i < MAX_PORT; i++) {
-		if (kfifo_alloc(&dc->port[i].fifo_ul,
-		      FIFO_BUFFER_SIZE_UL, GFP_ATOMIC)) {
+		if (kfifo_alloc(&dc->port[i].fifo_ul, FIFO_BUFFER_SIZE_UL,
+					GFP_KERNEL)) {
 			dev_err(&pdev->dev,
 					"Could not allocate kfifo buffer\n");
 			ret = -ENOMEM;
@@ -1474,7 +1471,6 @@
 		struct device *tty_dev;
 		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,
@@ -1688,13 +1684,6 @@
 	if (!dc || !port)
 		return -ENODEV;
 
-	mutex_lock(&port->tty_sem);
-
-	if (unlikely(!port->port.count)) {
-		DBG1(" ");
-		goto exit;
-	}
-
 	rval = kfifo_in(&port->fifo_ul, (unsigned char *)buffer, count);
 
 	/* notify card */
@@ -1719,7 +1708,6 @@
 	spin_unlock_irqrestore(&dc->spin_mutex, flags);
 
 exit:
-	mutex_unlock(&port->tty_sem);
 	return rval;
 }
 
@@ -1738,12 +1726,9 @@
 	int room = 4096;
 	const struct nozomi *dc = get_dc_by_tty(tty);
 
-	if (dc) {
-		mutex_lock(&port->tty_sem);
-		if (port->port.count)
-			room = kfifo_avail(&port->fifo_ul);
-		mutex_unlock(&port->tty_sem);
-	}
+	if (dc)
+		room = kfifo_avail(&port->fifo_ul);
+
 	return room;
 }
 
@@ -1889,11 +1874,6 @@
 		goto exit_in_buffer;
 	}
 
-	if (unlikely(!port->port.count)) {
-		dev_err(&dc->pdev->dev, "No tty open?\n");
-		goto exit_in_buffer;
-	}
-
 	rval = kfifo_len(&port->fifo_ul);
 
 exit_in_buffer:
diff -druN linux-2.6.39-libre/drivers/tty/n_tracerouter.c linux-3.0-rc7-libre/drivers/tty/n_tracerouter.c
--- linux-2.6.39-libre/drivers/tty/n_tracerouter.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/tty/n_tracerouter.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,243 @@
+/*
+ *  n_tracerouter.c - Trace data router through tty space
+ *
+ *  Copyright (C) Intel 2011
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ *  This program is free software; you can 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.
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ * This trace router uses the Linux line discipline framework to route
+ * trace data coming from a HW Modem to a PTI (Parallel Trace Module) port.
+ * The solution is not specific to a HW modem and this line disciple can
+ * be used to route any stream of data in kernel space.
+ * This is part of a solution for the P1149.7, compact JTAG, standard.
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/ioctl.h>
+#include <linux/tty.h>
+#include <linux/tty_ldisc.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/mutex.h>
+#include <linux/slab.h>
+#include <asm-generic/bug.h>
+#include "n_tracesink.h"
+
+/*
+ * Other ldisc drivers use 65536 which basically means,
+ * 'I can always accept 64k' and flow control is off.
+ * This number is deemed appropriate for this driver.
+ */
+#define RECEIVE_ROOM	65536
+#define DRIVERNAME	"n_tracerouter"
+
+/*
+ * struct to hold private configuration data for this ldisc.
+ * opencalled is used to hold if this ldisc has been opened.
+ * kref_tty holds the tty reference the ldisc sits on top of.
+ */
+struct tracerouter_data {
+	u8 opencalled;
+	struct tty_struct *kref_tty;
+};
+static struct tracerouter_data *tr_data;
+
+/* lock for when tty reference is being used */
+static DEFINE_MUTEX(routelock);
+
+/**
+ * n_tracerouter_open() - Called when a tty is opened by a SW entity.
+ * @tty: terminal device to the ldisc.
+ *
+ * Return:
+ *      0 for success.
+ *
+ * Caveats: This should only be opened one time per SW entity.
+ */
+static int n_tracerouter_open(struct tty_struct *tty)
+{
+	int retval = -EEXIST;
+
+	mutex_lock(&routelock);
+	if (tr_data->opencalled == 0) {
+
+		tr_data->kref_tty = tty_kref_get(tty);
+		if (tr_data->kref_tty == NULL) {
+			retval = -EFAULT;
+		} else {
+			tr_data->opencalled = 1;
+			tty->disc_data      = tr_data;
+			tty->receive_room   = RECEIVE_ROOM;
+			tty_driver_flush_buffer(tty);
+			retval = 0;
+		}
+	}
+	mutex_unlock(&routelock);
+	return retval;
+}
+
+/**
+ * n_tracerouter_close() - close connection
+ * @tty: terminal device to the ldisc.
+ *
+ * Called when a software entity wants to close a connection.
+ */
+static void n_tracerouter_close(struct tty_struct *tty)
+{
+	struct tracerouter_data *tptr = tty->disc_data;
+
+	mutex_lock(&routelock);
+	WARN_ON(tptr->kref_tty != tr_data->kref_tty);
+	tty_driver_flush_buffer(tty);
+	tty_kref_put(tr_data->kref_tty);
+	tr_data->kref_tty = NULL;
+	tr_data->opencalled = 0;
+	tty->disc_data = NULL;
+	mutex_unlock(&routelock);
+}
+
+/**
+ * n_tracerouter_read() - read request from user space
+ * @tty:  terminal device passed into the ldisc.
+ * @file: pointer to open file object.
+ * @buf:  pointer to the data buffer that gets eventually returned.
+ * @nr:   number of bytes of the data buffer that is returned.
+ *
+ * function that allows read() functionality in userspace. By default if this
+ * is not implemented it returns -EIO. This module is functioning like a
+ * router via n_tracerouter_receivebuf(), and there is no real requirement
+ * to implement this function. However, an error return value other than
+ * -EIO should be used just to show that there was an intent not to have
+ * this function implemented.  Return value based on read() man pages.
+ *
+ * Return:
+ *	 -EINVAL
+ */
+static ssize_t n_tracerouter_read(struct tty_struct *tty, struct file *file,
+				  unsigned char __user *buf, size_t nr) {
+	return -EINVAL;
+}
+
+/**
+ * n_tracerouter_write() - Function that allows write() in userspace.
+ * @tty:  terminal device passed into the ldisc.
+ * @file: pointer to open file object.
+ * @buf:  pointer to the data buffer that gets eventually returned.
+ * @nr:   number of bytes of the data buffer that is returned.
+ *
+ * By default if this is not implemented, it returns -EIO.
+ * This should not be implemented, ever, because
+ * 1. this driver is functioning like a router via
+ *    n_tracerouter_receivebuf()
+ * 2. No writes to HW will ever go through this line discpline driver.
+ * However, an error return value other than -EIO should be used
+ * just to show that there was an intent not to have this function
+ * implemented.  Return value based on write() man pages.
+ *
+ * Return:
+ *	-EINVAL
+ */
+static ssize_t n_tracerouter_write(struct tty_struct *tty, struct file *file,
+				   const unsigned char *buf, size_t nr) {
+	return -EINVAL;
+}
+
+/**
+ * n_tracerouter_receivebuf() - Routing function for driver.
+ * @tty: terminal device passed into the ldisc.  It's assumed
+ *       tty will never be NULL.
+ * @cp:  buffer, block of characters to be eventually read by
+ *       someone, somewhere (user read() call or some kernel function).
+ * @fp:  flag buffer.
+ * @count: number of characters (aka, bytes) in cp.
+ *
+ * This function takes the input buffer, cp, and passes it to
+ * an external API function for processing.
+ */
+static void n_tracerouter_receivebuf(struct tty_struct *tty,
+					const unsigned char *cp,
+					char *fp, int count)
+{
+	mutex_lock(&routelock);
+	n_tracesink_datadrain((u8 *) cp, count);
+	mutex_unlock(&routelock);
+}
+
+/*
+ * Flush buffer is not impelemented as the ldisc has no internal buffering
+ * so the tty_driver_flush_buffer() is sufficient for this driver's needs.
+ */
+
+static struct tty_ldisc_ops tty_ptirouter_ldisc = {
+	.owner		= THIS_MODULE,
+	.magic		= TTY_LDISC_MAGIC,
+	.name		= DRIVERNAME,
+	.open		= n_tracerouter_open,
+	.close		= n_tracerouter_close,
+	.read		= n_tracerouter_read,
+	.write		= n_tracerouter_write,
+	.receive_buf	= n_tracerouter_receivebuf
+};
+
+/**
+ * n_tracerouter_init -	module initialisation
+ *
+ * Registers this module as a line discipline driver.
+ *
+ * Return:
+ *	0 for success, any other value error.
+ */
+static int __init n_tracerouter_init(void)
+{
+	int retval;
+
+	tr_data = kzalloc(sizeof(struct tracerouter_data), GFP_KERNEL);
+	if (tr_data == NULL)
+		return -ENOMEM;
+
+
+	/* Note N_TRACEROUTER is defined in linux/tty.h */
+	retval = tty_register_ldisc(N_TRACEROUTER, &tty_ptirouter_ldisc);
+	if (retval < 0) {
+		pr_err("%s: Registration failed: %d\n", __func__, retval);
+		kfree(tr_data);
+	}
+	return retval;
+}
+
+/**
+ * n_tracerouter_exit -	module unload
+ *
+ * Removes this module as a line discipline driver.
+ */
+static void __exit n_tracerouter_exit(void)
+{
+	int retval = tty_unregister_ldisc(N_TRACEROUTER);
+
+	if (retval < 0)
+		pr_err("%s: Unregistration failed: %d\n", __func__,  retval);
+	else
+		kfree(tr_data);
+}
+
+module_init(n_tracerouter_init);
+module_exit(n_tracerouter_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Jay Freyensee");
+MODULE_ALIAS_LDISC(N_TRACEROUTER);
+MODULE_DESCRIPTION("Trace router ldisc driver");
diff -druN linux-2.6.39-libre/drivers/tty/n_tracesink.c linux-3.0-rc7-libre/drivers/tty/n_tracesink.c
--- linux-2.6.39-libre/drivers/tty/n_tracesink.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/tty/n_tracesink.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,238 @@
+/*
+ *  n_tracesink.c - Trace data router and sink path through tty space.
+ *
+ *  Copyright (C) Intel 2011
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ *  This program is free software; you can 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.
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ * The trace sink uses the Linux line discipline framework to receive
+ * trace data coming from the PTI source line discipline driver
+ * to a user-desired tty port, like USB.
+ * This is to provide a way to extract modem trace data on
+ * devices that do not have a PTI HW module, or just need modem
+ * trace data to come out of a different HW output port.
+ * This is part of a solution for the P1149.7, compact JTAG, standard.
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/ioctl.h>
+#include <linux/tty.h>
+#include <linux/tty_ldisc.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <asm-generic/bug.h>
+#include "n_tracesink.h"
+
+/*
+ * Other ldisc drivers use 65536 which basically means,
+ * 'I can always accept 64k' and flow control is off.
+ * This number is deemed appropriate for this driver.
+ */
+#define RECEIVE_ROOM	65536
+#define DRIVERNAME	"n_tracesink"
+
+/*
+ * there is a quirk with this ldisc is he can write data
+ * to a tty from anyone calling his kernel API, which
+ * meets customer requirements in the drivers/misc/pti.c
+ * project.  So he needs to know when he can and cannot write when
+ * the API is called. In theory, the API can be called
+ * after an init() but before a successful open() which
+ * would crash the system if tty is not checked.
+ */
+static struct tty_struct *this_tty;
+static DEFINE_MUTEX(writelock);
+
+/**
+ * n_tracesink_open() - Called when a tty is opened by a SW entity.
+ * @tty: terminal device to the ldisc.
+ *
+ * Return:
+ *      0 for success,
+ *      -EFAULT = couldn't get a tty kref n_tracesink will sit
+ *       on top of
+ *      -EEXIST = open() called successfully once and it cannot
+ *      be called again.
+ *
+ * Caveats: open() should only be successful the first time a
+ * SW entity calls it.
+ */
+static int n_tracesink_open(struct tty_struct *tty)
+{
+	int retval = -EEXIST;
+
+	mutex_lock(&writelock);
+	if (this_tty == NULL) {
+		this_tty = tty_kref_get(tty);
+		if (this_tty == NULL) {
+			retval = -EFAULT;
+		} else {
+			tty->disc_data = this_tty;
+			tty_driver_flush_buffer(tty);
+			retval = 0;
+		}
+	}
+	mutex_unlock(&writelock);
+
+	return retval;
+}
+
+/**
+ * n_tracesink_close() - close connection
+ * @tty: terminal device to the ldisc.
+ *
+ * Called when a software entity wants to close a connection.
+ */
+static void n_tracesink_close(struct tty_struct *tty)
+{
+	mutex_lock(&writelock);
+	tty_driver_flush_buffer(tty);
+	tty_kref_put(this_tty);
+	this_tty = NULL;
+	tty->disc_data = NULL;
+	mutex_unlock(&writelock);
+}
+
+/**
+ * n_tracesink_read() - read request from user space
+ * @tty:  terminal device passed into the ldisc.
+ * @file: pointer to open file object.
+ * @buf:  pointer to the data buffer that gets eventually returned.
+ * @nr:   number of bytes of the data buffer that is returned.
+ *
+ * function that allows read() functionality in userspace. By default if this
+ * is not implemented it returns -EIO. This module is functioning like a
+ * router via n_tracesink_receivebuf(), and there is no real requirement
+ * to implement this function. However, an error return value other than
+ * -EIO should be used just to show that there was an intent not to have
+ * this function implemented.  Return value based on read() man pages.
+ *
+ * Return:
+ *	 -EINVAL
+ */
+static ssize_t n_tracesink_read(struct tty_struct *tty, struct file *file,
+				unsigned char __user *buf, size_t nr) {
+	return -EINVAL;
+}
+
+/**
+ * n_tracesink_write() - Function that allows write() in userspace.
+ * @tty:  terminal device passed into the ldisc.
+ * @file: pointer to open file object.
+ * @buf:  pointer to the data buffer that gets eventually returned.
+ * @nr:   number of bytes of the data buffer that is returned.
+ *
+ * By default if this is not implemented, it returns -EIO.
+ * This should not be implemented, ever, because
+ * 1. this driver is functioning like a router via
+ *    n_tracesink_receivebuf()
+ * 2. No writes to HW will ever go through this line discpline driver.
+ * However, an error return value other than -EIO should be used
+ * just to show that there was an intent not to have this function
+ * implemented.  Return value based on write() man pages.
+ *
+ * Return:
+ *	-EINVAL
+ */
+static ssize_t n_tracesink_write(struct tty_struct *tty, struct file *file,
+				 const unsigned char *buf, size_t nr) {
+	return -EINVAL;
+}
+
+/**
+ * n_tracesink_datadrain() - Kernel API function used to route
+ *			     trace debugging data to user-defined
+ *			     port like USB.
+ *
+ * @buf:   Trace debuging data buffer to write to tty target
+ *         port. Null value will return with no write occurring.
+ * @count: Size of buf. Value of 0 or a negative number will
+ *         return with no write occuring.
+ *
+ * Caveat: If this line discipline does not set the tty it sits
+ * on top of via an open() call, this API function will not
+ * call the tty's write() call because it will have no pointer
+ * to call the write().
+ */
+void n_tracesink_datadrain(u8 *buf, int count)
+{
+	mutex_lock(&writelock);
+
+	if ((buf != NULL) && (count > 0) && (this_tty != NULL))
+		this_tty->ops->write(this_tty, buf, count);
+
+	mutex_unlock(&writelock);
+}
+EXPORT_SYMBOL_GPL(n_tracesink_datadrain);
+
+/*
+ * Flush buffer is not impelemented as the ldisc has no internal buffering
+ * so the tty_driver_flush_buffer() is sufficient for this driver's needs.
+ */
+
+/*
+ * tty_ldisc function operations for this driver.
+ */
+static struct tty_ldisc_ops tty_n_tracesink = {
+	.owner		= THIS_MODULE,
+	.magic		= TTY_LDISC_MAGIC,
+	.name		= DRIVERNAME,
+	.open		= n_tracesink_open,
+	.close		= n_tracesink_close,
+	.read		= n_tracesink_read,
+	.write		= n_tracesink_write
+};
+
+/**
+ * n_tracesink_init-	module initialisation
+ *
+ * Registers this module as a line discipline driver.
+ *
+ * Return:
+ *	0 for success, any other value error.
+ */
+static int __init n_tracesink_init(void)
+{
+	/* Note N_TRACESINK is defined in linux/tty.h */
+	int retval = tty_register_ldisc(N_TRACESINK, &tty_n_tracesink);
+
+	if (retval < 0)
+		pr_err("%s: Registration failed: %d\n", __func__, retval);
+
+	return retval;
+}
+
+/**
+ * n_tracesink_exit -	module unload
+ *
+ * Removes this module as a line discipline driver.
+ */
+static void __exit n_tracesink_exit(void)
+{
+	int retval = tty_unregister_ldisc(N_TRACESINK);
+
+	if (retval < 0)
+		pr_err("%s: Unregistration failed: %d\n", __func__,  retval);
+}
+
+module_init(n_tracesink_init);
+module_exit(n_tracesink_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Jay Freyensee");
+MODULE_ALIAS_LDISC(N_TRACESINK);
+MODULE_DESCRIPTION("Trace sink ldisc driver");
diff -druN linux-2.6.39-libre/drivers/tty/n_tracesink.h linux-3.0-rc7-libre/drivers/tty/n_tracesink.h
--- linux-2.6.39-libre/drivers/tty/n_tracesink.h	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/tty/n_tracesink.h	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,36 @@
+/*
+ *  n_tracesink.h - Kernel driver API to route trace data in kernel space.
+ *
+ *  Copyright (C) Intel 2011
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ *  This program is free software; you can 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.
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ * The PTI (Parallel Trace Interface) driver directs trace data routed from
+ * various parts in the system out through the Intel Penwell PTI port and
+ * out of the mobile device for analysis with a debugging tool
+ * (Lauterbach, Fido). This is part of a solution for the MIPI P1149.7,
+ * compact JTAG, standard.
+ *
+ * This header file is used by n_tracerouter to be able to send the
+ * data of it's tty port to the tty port this module sits.  This
+ * mechanism can also be used independent of the PTI module.
+ *
+ */
+
+#ifndef N_TRACESINK_H_
+#define N_TRACESINK_H_
+
+void n_tracesink_datadrain(u8 *buf, int count);
+
+#endif
diff -druN linux-2.6.39-libre/drivers/tty/n_tty.c linux-3.0-rc7-libre/drivers/tty/n_tty.c
--- linux-2.6.39-libre/drivers/tty/n_tty.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/tty/n_tty.c	2011-07-11 19:51:52.000000000 -0400
@@ -1815,6 +1815,7 @@
 			/* FIXME: does n_tty_set_room need locking ? */
 			n_tty_set_room(tty);
 			timeout = schedule_timeout(timeout);
+			BUG_ON(!tty->read_buf);
 			continue;
 		}
 		__set_current_state(TASK_RUNNING);
diff -druN linux-2.6.39-libre/drivers/tty/pty.c linux-3.0-rc7-libre/drivers/tty/pty.c
--- linux-2.6.39-libre/drivers/tty/pty.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/tty/pty.c	2011-07-11 19:51:52.000000000 -0400
@@ -1,6 +1,4 @@
 /*
- *  linux/drivers/char/pty.c
- *
  *  Copyright (C) 1991, 1992  Linus Torvalds
  *
  *  Added support for a Unix98-style ptmx device.
@@ -295,8 +293,8 @@
 		return -ENOMEM;
 	if (!try_module_get(driver->other->owner)) {
 		/* This cannot in fact currently happen */
-		free_tty_struct(o_tty);
-		return -ENOMEM;
+		retval = -ENOMEM;
+		goto err_free_tty;
 	}
 	initialize_tty_struct(o_tty, driver->other, idx);
 
@@ -304,13 +302,11 @@
 	   the easy way .. */
 	retval = tty_init_termios(tty);
 	if (retval)
-		goto free_mem_out;
+		goto err_deinit_tty;
 
 	retval = tty_init_termios(o_tty);
-	if (retval) {
-		tty_free_termios(tty);
-		goto free_mem_out;
-	}
+	if (retval)
+		goto err_free_termios;
 
 	/*
 	 * Everything allocated ... set up the o_tty structure.
@@ -327,10 +323,14 @@
 	tty->count++;
 	driver->ttys[idx] = tty;
 	return 0;
-free_mem_out:
+err_free_termios:
+	tty_free_termios(tty);
+err_deinit_tty:
+	deinitialize_tty_struct(o_tty);
 	module_put(o_tty->driver->owner);
+err_free_tty:
 	free_tty_struct(o_tty);
-	return -ENOMEM;
+	return retval;
 }
 
 static int pty_bsd_ioctl(struct tty_struct *tty,
@@ -559,20 +559,19 @@
 		return -ENOMEM;
 	if (!try_module_get(driver->other->owner)) {
 		/* This cannot in fact currently happen */
-		free_tty_struct(o_tty);
-		return -ENOMEM;
+		goto err_free_tty;
 	}
 	initialize_tty_struct(o_tty, driver->other, idx);
 
 	tty->termios = kzalloc(sizeof(struct ktermios[2]), GFP_KERNEL);
 	if (tty->termios == NULL)
-		goto free_mem_out;
+		goto err_free_mem;
 	*tty->termios = driver->init_termios;
 	tty->termios_locked = tty->termios + 1;
 
 	o_tty->termios = kzalloc(sizeof(struct ktermios[2]), GFP_KERNEL);
 	if (o_tty->termios == NULL)
-		goto free_mem_out;
+		goto err_free_mem;
 	*o_tty->termios = driver->other->init_termios;
 	o_tty->termios_locked = o_tty->termios + 1;
 
@@ -591,11 +590,13 @@
 	tty->count++;
 	pty_count++;
 	return 0;
-free_mem_out:
+err_free_mem:
+	deinitialize_tty_struct(o_tty);
 	kfree(o_tty->termios);
+	kfree(tty->termios);
 	module_put(o_tty->driver->owner);
+err_free_tty:
 	free_tty_struct(o_tty);
-	kfree(tty->termios);
 	return -ENOMEM;
 }
 
diff -druN linux-2.6.39-libre/drivers/tty/rocket.c linux-3.0-rc7-libre/drivers/tty/rocket.c
--- linux-2.6.39-libre/drivers/tty/rocket.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/tty/rocket.c	2011-07-11 19:51:52.000000000 -0400
@@ -1380,7 +1380,6 @@
 static void rp_throttle(struct tty_struct *tty)
 {
 	struct r_port *info = tty->driver_data;
-	CHANNEL_t *cp;
 
 #ifdef ROCKET_DEBUG_THROTTLE
 	printk(KERN_INFO "throttle %s: %d....\n", tty->name,
@@ -1390,7 +1389,6 @@
 	if (rocket_paranoia_check(info, "rp_throttle"))
 		return;
 
-	cp = &info->channel;
 	if (I_IXOFF(tty))
 		rp_send_xchar(tty, STOP_CHAR(tty));
 
@@ -1400,7 +1398,6 @@
 static void rp_unthrottle(struct tty_struct *tty)
 {
 	struct r_port *info = tty->driver_data;
-	CHANNEL_t *cp;
 #ifdef ROCKET_DEBUG_THROTTLE
 	printk(KERN_INFO "unthrottle %s: %d....\n", tty->name,
 	       tty->ldisc.chars_in_buffer(tty));
@@ -1409,7 +1406,6 @@
 	if (rocket_paranoia_check(info, "rp_throttle"))
 		return;
 
-	cp = &info->channel;
 	if (I_IXOFF(tty))
 		rp_send_xchar(tty, START_CHAR(tty));
 
@@ -1722,13 +1718,10 @@
 static int rp_chars_in_buffer(struct tty_struct *tty)
 {
 	struct r_port *info = tty->driver_data;
-	CHANNEL_t *cp;
 
 	if (rocket_paranoia_check(info, "rp_chars_in_buffer"))
 		return 0;
 
-	cp = &info->channel;
-
 #ifdef ROCKET_DEBUG_WRITE
 	printk(KERN_INFO "rp_chars_in_buffer returns %d...\n", info->xmit_cnt);
 #endif
@@ -1779,7 +1772,6 @@
 {
 	int num_aiops, aiop, max_num_aiops, num_chan, chan;
 	unsigned int aiopio[MAX_AIOPS_PER_BOARD];
-	char *str, *board_type;
 	CONTROLLER_t *ctlp;
 
 	int fast_clock = 0;
@@ -1800,7 +1792,6 @@
 	/*  Depending on the model, set up some config variables */
 	switch (dev->device) {
 	case PCI_DEVICE_ID_RP4QUAD:
-		str = "Quadcable";
 		max_num_aiops = 1;
 		ports_per_aiop = 4;
 		rocketModel[i].model = MODEL_RP4QUAD;
@@ -1808,42 +1799,36 @@
 		rocketModel[i].numPorts = 4;
 		break;
 	case PCI_DEVICE_ID_RP8OCTA:
-		str = "Octacable";
 		max_num_aiops = 1;
 		rocketModel[i].model = MODEL_RP8OCTA;
 		strcpy(rocketModel[i].modelString, "RocketPort 8 port w/octa cable");
 		rocketModel[i].numPorts = 8;
 		break;
 	case PCI_DEVICE_ID_URP8OCTA:
-		str = "Octacable";
 		max_num_aiops = 1;
 		rocketModel[i].model = MODEL_UPCI_RP8OCTA;
 		strcpy(rocketModel[i].modelString, "RocketPort UPCI 8 port w/octa cable");
 		rocketModel[i].numPorts = 8;
 		break;
 	case PCI_DEVICE_ID_RP8INTF:
-		str = "8";
 		max_num_aiops = 1;
 		rocketModel[i].model = MODEL_RP8INTF;
 		strcpy(rocketModel[i].modelString, "RocketPort 8 port w/external I/F");
 		rocketModel[i].numPorts = 8;
 		break;
 	case PCI_DEVICE_ID_URP8INTF:
-		str = "8";
 		max_num_aiops = 1;
 		rocketModel[i].model = MODEL_UPCI_RP8INTF;
 		strcpy(rocketModel[i].modelString, "RocketPort UPCI 8 port w/external I/F");
 		rocketModel[i].numPorts = 8;
 		break;
 	case PCI_DEVICE_ID_RP8J:
-		str = "8J";
 		max_num_aiops = 1;
 		rocketModel[i].model = MODEL_RP8J;
 		strcpy(rocketModel[i].modelString, "RocketPort 8 port w/RJ11 connectors");
 		rocketModel[i].numPorts = 8;
 		break;
 	case PCI_DEVICE_ID_RP4J:
-		str = "4J";
 		max_num_aiops = 1;
 		ports_per_aiop = 4;
 		rocketModel[i].model = MODEL_RP4J;
@@ -1851,56 +1836,48 @@
 		rocketModel[i].numPorts = 4;
 		break;
 	case PCI_DEVICE_ID_RP8SNI:
-		str = "8 (DB78 Custom)";
 		max_num_aiops = 1;
 		rocketModel[i].model = MODEL_RP8SNI;
 		strcpy(rocketModel[i].modelString, "RocketPort 8 port w/ custom DB78");
 		rocketModel[i].numPorts = 8;
 		break;
 	case PCI_DEVICE_ID_RP16SNI:
-		str = "16 (DB78 Custom)";
 		max_num_aiops = 2;
 		rocketModel[i].model = MODEL_RP16SNI;
 		strcpy(rocketModel[i].modelString, "RocketPort 16 port w/ custom DB78");
 		rocketModel[i].numPorts = 16;
 		break;
 	case PCI_DEVICE_ID_RP16INTF:
-		str = "16";
 		max_num_aiops = 2;
 		rocketModel[i].model = MODEL_RP16INTF;
 		strcpy(rocketModel[i].modelString, "RocketPort 16 port w/external I/F");
 		rocketModel[i].numPorts = 16;
 		break;
 	case PCI_DEVICE_ID_URP16INTF:
-		str = "16";
 		max_num_aiops = 2;
 		rocketModel[i].model = MODEL_UPCI_RP16INTF;
 		strcpy(rocketModel[i].modelString, "RocketPort UPCI 16 port w/external I/F");
 		rocketModel[i].numPorts = 16;
 		break;
 	case PCI_DEVICE_ID_CRP16INTF:
-		str = "16";
 		max_num_aiops = 2;
 		rocketModel[i].model = MODEL_CPCI_RP16INTF;
 		strcpy(rocketModel[i].modelString, "RocketPort Compact PCI 16 port w/external I/F");
 		rocketModel[i].numPorts = 16;
 		break;
 	case PCI_DEVICE_ID_RP32INTF:
-		str = "32";
 		max_num_aiops = 4;
 		rocketModel[i].model = MODEL_RP32INTF;
 		strcpy(rocketModel[i].modelString, "RocketPort 32 port w/external I/F");
 		rocketModel[i].numPorts = 32;
 		break;
 	case PCI_DEVICE_ID_URP32INTF:
-		str = "32";
 		max_num_aiops = 4;
 		rocketModel[i].model = MODEL_UPCI_RP32INTF;
 		strcpy(rocketModel[i].modelString, "RocketPort UPCI 32 port w/external I/F");
 		rocketModel[i].numPorts = 32;
 		break;
 	case PCI_DEVICE_ID_RPP4:
-		str = "Plus Quadcable";
 		max_num_aiops = 1;
 		ports_per_aiop = 4;
 		altChanRingIndicator++;
@@ -1910,7 +1887,6 @@
 		rocketModel[i].numPorts = 4;
 		break;
 	case PCI_DEVICE_ID_RPP8:
-		str = "Plus Octacable";
 		max_num_aiops = 2;
 		ports_per_aiop = 4;
 		altChanRingIndicator++;
@@ -1920,7 +1896,6 @@
 		rocketModel[i].numPorts = 8;
 		break;
 	case PCI_DEVICE_ID_RP2_232:
-		str = "Plus 2 (RS-232)";
 		max_num_aiops = 1;
 		ports_per_aiop = 2;
 		altChanRingIndicator++;
@@ -1930,7 +1905,6 @@
 		rocketModel[i].numPorts = 2;
 		break;
 	case PCI_DEVICE_ID_RP2_422:
-		str = "Plus 2 (RS-422)";
 		max_num_aiops = 1;
 		ports_per_aiop = 2;
 		altChanRingIndicator++;
@@ -1943,7 +1917,6 @@
 
 		max_num_aiops = 1;
 		ports_per_aiop = 6;
-		str = "6-port";
 
 		/*  If revision is 1, the rocketmodem flash must be loaded.
 		 *  If it is 2 it is a "socketed" version. */
@@ -1961,7 +1934,6 @@
 	case PCI_DEVICE_ID_RP4M:
 		max_num_aiops = 1;
 		ports_per_aiop = 4;
-		str = "4-port";
 		if (dev->revision == 1) {
 			rcktpt_type[i] = ROCKET_TYPE_MODEMII;
 			rocketModel[i].loadrm2 = 1;
@@ -1974,7 +1946,6 @@
 		rocketModel[i].numPorts = 4;
 		break;
 	default:
-		str = "(unknown/unsupported)";
 		max_num_aiops = 0;
 		break;
 	}
@@ -2000,14 +1971,12 @@
 			if (!
 			    (sInW(ConfigIO + _PCI_9030_GPIO_CTRL) &
 			     PCI_GPIO_CTRL_8PORT)) {
-				str = "Quadcable";
 				ports_per_aiop = 4;
 				rocketModel[i].numPorts = 4;
 			}
 		}
 		break;
 	case PCI_DEVICE_ID_UPCI_RM3_8PORT:
-		str = "8 ports";
 		max_num_aiops = 1;
 		rocketModel[i].model = MODEL_UPCI_RM3_8PORT;
 		strcpy(rocketModel[i].modelString, "RocketModem III 8 port");
@@ -2018,7 +1987,6 @@
 		rcktpt_type[i] = ROCKET_TYPE_MODEMIII;
 		break;
 	case PCI_DEVICE_ID_UPCI_RM3_4PORT:
-		str = "4 ports";
 		max_num_aiops = 1;
 		rocketModel[i].model = MODEL_UPCI_RM3_4PORT;
 		strcpy(rocketModel[i].modelString, "RocketModem III 4 port");
@@ -2032,21 +2000,6 @@
 		break;
 	}
 
-	switch (rcktpt_type[i]) {
-	case ROCKET_TYPE_MODEM:
-		board_type = "RocketModem";
-		break;
-	case ROCKET_TYPE_MODEMII:
-		board_type = "RocketModem II";
-		break;
-	case ROCKET_TYPE_MODEMIII:
-		board_type = "RocketModem III";
-		break;
-	default:
-		board_type = "RocketPort";
-		break;
-	}
-
 	if (fast_clock) {
 		sClockPrescale = 0x12;	/* mod 2 (divide by 3) */
 		rp_baud_base[i] = 921600;
diff -druN linux-2.6.39-libre/drivers/tty/serial/21285.c linux-3.0-rc7-libre/drivers/tty/serial/21285.c
--- linux-2.6.39-libre/drivers/tty/serial/21285.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/tty/serial/21285.c	2011-07-11 19:51:52.000000000 -0400
@@ -1,6 +1,4 @@
 /*
- * linux/drivers/serial/21285.c
- *
  * Driver for the serial port on the 21285 StrongArm-110 core logic chip.
  *
  * Based on drivers/char/serial.c
diff -druN linux-2.6.39-libre/drivers/tty/serial/68328serial.c linux-3.0-rc7-libre/drivers/tty/serial/68328serial.c
--- linux-2.6.39-libre/drivers/tty/serial/68328serial.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/tty/serial/68328serial.c	2011-07-11 19:51:52.000000000 -0400
@@ -281,7 +281,7 @@
 #ifdef CONFIG_MAGIC_SYSRQ
 			} else if (ch == 0x10) { /* ^P */
 				show_state();
-				show_free_areas();
+				show_free_areas(0);
 				show_buffers();
 /*				show_net_buffers(); */
 				return;
diff -druN linux-2.6.39-libre/drivers/tty/serial/8250_accent.c linux-3.0-rc7-libre/drivers/tty/serial/8250_accent.c
--- linux-2.6.39-libre/drivers/tty/serial/8250_accent.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/tty/serial/8250_accent.c	2011-07-11 19:51:52.000000000 -0400
@@ -1,6 +1,4 @@
 /*
- *  linux/drivers/serial/8250_accent.c
- *
  *  Copyright (C) 2005 Russell King.
  *  Data taken from include/asm-i386/serial.h
  *
diff -druN linux-2.6.39-libre/drivers/tty/serial/8250_boca.c linux-3.0-rc7-libre/drivers/tty/serial/8250_boca.c
--- linux-2.6.39-libre/drivers/tty/serial/8250_boca.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/tty/serial/8250_boca.c	2011-07-11 19:51:52.000000000 -0400
@@ -1,6 +1,4 @@
 /*
- *  linux/drivers/serial/8250_boca.c
- *
  *  Copyright (C) 2005 Russell King.
  *  Data taken from include/asm-i386/serial.h
  *
diff -druN linux-2.6.39-libre/drivers/tty/serial/8250.c linux-3.0-rc7-libre/drivers/tty/serial/8250.c
--- linux-2.6.39-libre/drivers/tty/serial/8250.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/tty/serial/8250.c	2011-07-11 19:51:52.000000000 -0400
@@ -1,6 +1,4 @@
 /*
- *  linux/drivers/char/8250.c
- *
  *  Driver for 8250/16550-type serial ports
  *
  *  Based on drivers/char/serial.c, by Linus Torvalds, Theodore Ts'o.
@@ -273,7 +271,7 @@
 		.fifo_size	= 32,
 		.tx_loadsz	= 32,
 		.fcr		= UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10,
-		.flags		= UART_CAP_FIFO | UART_CAP_UUE,
+		.flags		= UART_CAP_FIFO | UART_CAP_UUE | UART_CAP_RTOIE,
 	},
 	[PORT_RM9000] = {
 		.name		= "RM9000",
@@ -303,6 +301,14 @@
 		.fcr		= UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10,
 		.flags		= UART_CAP_FIFO | UART_CAP_AFE,
 	},
+	[PORT_TEGRA] = {
+		.name		= "Tegra",
+		.fifo_size	= 32,
+		.tx_loadsz	= 8,
+		.fcr		= UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_01 |
+				  UART_FCR_T_TRIG_01,
+		.flags		= UART_CAP_FIFO | UART_CAP_RTOIE,
+	},
 };
 
 #if defined(CONFIG_MIPS_ALCHEMY)
@@ -1427,6 +1433,27 @@
 	serial_out(up, UART_IER, up->ier);
 }
 
+/*
+ * Clear the Tegra rx fifo after a break
+ *
+ * FIXME: This needs to become a port specific callback once we have a
+ * framework for this
+ */
+static void clear_rx_fifo(struct uart_8250_port *up)
+{
+	unsigned int status, tmout = 10000;
+	do {
+		status = serial_in(up, UART_LSR);
+		if (status & (UART_LSR_FIFOE | UART_LSR_BRK_ERROR_BITS))
+			status = serial_in(up, UART_RX);
+		else
+			break;
+		if (--tmout == 0)
+			break;
+		udelay(1);
+	} while (1);
+}
+
 static void
 receive_chars(struct uart_8250_port *up, unsigned int *status)
 {
@@ -1462,6 +1489,13 @@
 				lsr &= ~(UART_LSR_FE | UART_LSR_PE);
 				up->port.icount.brk++;
 				/*
+				 * If tegra port then clear the rx fifo to
+				 * accept another break/character.
+				 */
+				if (up->port.type == PORT_TEGRA)
+					clear_rx_fifo(up);
+
+				/*
 				 * We do the SysRQ and SAK checking
 				 * here because otherwise the break
 				 * may get masked by ignore_status_mask
@@ -2405,7 +2439,9 @@
 			UART_ENABLE_MS(&up->port, termios->c_cflag))
 		up->ier |= UART_IER_MSI;
 	if (up->capabilities & UART_CAP_UUE)
-		up->ier |= UART_IER_UUE | UART_IER_RTOIE;
+		up->ier |= UART_IER_UUE;
+	if (up->capabilities & UART_CAP_RTOIE)
+		up->ier |= UART_IER_RTOIE;
 
 	serial_out(up, UART_IER, up->ier);
 
@@ -3282,6 +3318,7 @@
 		uart->port.flags &= ~UPF_BOOT_AUTOCONF;
 		uart->port.type = PORT_UNKNOWN;
 		uart->port.dev = &serial8250_isa_devs->dev;
+		uart->capabilities = uart_config[uart->port.type].flags;
 		uart_add_one_port(&serial8250_reg, &uart->port);
 	} else {
 		uart->port.dev = NULL;
diff -druN linux-2.6.39-libre/drivers/tty/serial/8250_exar_st16c554.c linux-3.0-rc7-libre/drivers/tty/serial/8250_exar_st16c554.c
--- linux-2.6.39-libre/drivers/tty/serial/8250_exar_st16c554.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/tty/serial/8250_exar_st16c554.c	2011-07-11 19:51:52.000000000 -0400
@@ -1,6 +1,4 @@
 /*
- *  linux/drivers/serial/8250_exar.c
- *
  *  Written by Paul B Schroeder < pschroeder "at" uplogix "dot" com >
  *  Based on 8250_boca.
  *
diff -druN linux-2.6.39-libre/drivers/tty/serial/8250_fourport.c linux-3.0-rc7-libre/drivers/tty/serial/8250_fourport.c
--- linux-2.6.39-libre/drivers/tty/serial/8250_fourport.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/tty/serial/8250_fourport.c	2011-07-11 19:51:52.000000000 -0400
@@ -1,6 +1,4 @@
 /*
- *  linux/drivers/serial/8250_fourport.c
- *
  *  Copyright (C) 2005 Russell King.
  *  Data taken from include/asm-i386/serial.h
  *
diff -druN linux-2.6.39-libre/drivers/tty/serial/8250.h linux-3.0-rc7-libre/drivers/tty/serial/8250.h
--- linux-2.6.39-libre/drivers/tty/serial/8250.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/tty/serial/8250.h	2011-07-11 19:51:52.000000000 -0400
@@ -1,6 +1,4 @@
 /*
- *  linux/drivers/char/8250.h
- *
  *  Driver for 8250/16550-type serial ports
  *
  *  Based on drivers/char/serial.c, by Linus Torvalds, Theodore Ts'o.
@@ -44,6 +42,7 @@
 #define UART_CAP_SLEEP	(1 << 10)	/* UART has IER sleep */
 #define UART_CAP_AFE	(1 << 11)	/* MCR-based hw flow control */
 #define UART_CAP_UUE	(1 << 12)	/* UART needs IER bit 6 set (Xscale) */
+#define UART_CAP_RTOIE	(1 << 13)	/* UART needs IER bit 4 set (Xscale, Tegra) */
 
 #define UART_BUG_QUOT	(1 << 0)	/* UART has buggy quot LSB */
 #define UART_BUG_TXEN	(1 << 1)	/* UART has buggy TX IIR status */
diff -druN linux-2.6.39-libre/drivers/tty/serial/8250_hub6.c linux-3.0-rc7-libre/drivers/tty/serial/8250_hub6.c
--- linux-2.6.39-libre/drivers/tty/serial/8250_hub6.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/tty/serial/8250_hub6.c	2011-07-11 19:51:52.000000000 -0400
@@ -1,6 +1,4 @@
 /*
- *  linux/drivers/serial/8250_hub6.c
- *
  *  Copyright (C) 2005 Russell King.
  *  Data taken from include/asm-i386/serial.h
  *
diff -druN linux-2.6.39-libre/drivers/tty/serial/8250_mca.c linux-3.0-rc7-libre/drivers/tty/serial/8250_mca.c
--- linux-2.6.39-libre/drivers/tty/serial/8250_mca.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/tty/serial/8250_mca.c	2011-07-11 19:51:52.000000000 -0400
@@ -1,6 +1,4 @@
 /*
- *  linux/drivers/serial/8250_mca.c
- *
  *  Copyright (C) 2005 Russell King.
  *  Data taken from include/asm-i386/serial.h
  *
diff -druN linux-2.6.39-libre/drivers/tty/serial/8250_pci.c linux-3.0-rc7-libre/drivers/tty/serial/8250_pci.c
--- linux-2.6.39-libre/drivers/tty/serial/8250_pci.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/tty/serial/8250_pci.c	2011-07-11 19:51:52.000000000 -0400
@@ -1,6 +1,4 @@
 /*
- *  linux/drivers/char/8250_pci.c
- *
  *  Probe module for 8250/16550-type PCI serial ports.
  *
  *  Based on drivers/char/serial.c, by Linus Torvalds, Theodore Ts'o.
@@ -973,6 +971,14 @@
 	return ret;
 }
 
+static int
+pci_omegapci_setup(struct serial_private *priv,
+		      const struct pciserial_board *board,
+		      struct uart_port *port, int idx)
+{
+	return setup_port(priv, port, 2, idx * 8, 0);
+}
+
 static int skip_tx_en_setup(struct serial_private *priv,
 			const struct pciserial_board *board,
 			struct uart_port *port, int idx)
@@ -988,6 +994,15 @@
 	return pci_default_setup(priv, board, port, idx);
 }
 
+static int pci_eg20t_init(struct pci_dev *dev)
+{
+#if defined(CONFIG_SERIAL_PCH_UART) || defined(CONFIG_SERIAL_PCH_UART_MODULE)
+	return -ENODEV;
+#else
+	return 0;
+#endif
+}
+
 /* This should be in linux/pci_ids.h */
 #define PCI_VENDOR_ID_SBSMODULARIO	0x124B
 #define PCI_SUBVENDOR_ID_SBSMODULARIO	0x124B
@@ -1012,6 +1027,8 @@
 #define PCI_DEVICE_ID_TITAN_200EI	0xA016
 #define PCI_DEVICE_ID_TITAN_200EISI	0xA017
 #define PCI_DEVICE_ID_OXSEMI_16PCI958	0x9538
+#define PCIE_DEVICE_ID_NEO_2_OX_IBM	0x00F6
+#define PCI_DEVICE_ID_PLX_CRONYX_OMEGA	0xc001
 
 /* Unknown vendors/cards - this should not be in linux/pci_ids.h */
 #define PCI_SUBDEVICE_ID_UNKNOWN_0x1584	0x1584
@@ -1412,7 +1429,7 @@
 		.setup		= pci_default_setup,
 	},
 	/*
-	 * For Oxford Semiconductor and Mainpine
+	 * For Oxford Semiconductor Tornado based devices
 	 */
 	{
 		.vendor		= PCI_VENDOR_ID_OXSEMI,
@@ -1430,6 +1447,74 @@
 		.init		= pci_oxsemi_tornado_init,
 		.setup		= pci_default_setup,
 	},
+	{
+		.vendor		= PCI_VENDOR_ID_DIGI,
+		.device		= PCIE_DEVICE_ID_NEO_2_OX_IBM,
+		.subvendor		= PCI_SUBVENDOR_ID_IBM,
+		.subdevice		= PCI_ANY_ID,
+		.init			= pci_oxsemi_tornado_init,
+		.setup		= pci_default_setup,
+	},
+	{
+		.vendor         = PCI_VENDOR_ID_INTEL,
+		.device         = 0x8811,
+		.init		= pci_eg20t_init,
+	},
+	{
+		.vendor         = PCI_VENDOR_ID_INTEL,
+		.device         = 0x8812,
+		.init		= pci_eg20t_init,
+	},
+	{
+		.vendor         = PCI_VENDOR_ID_INTEL,
+		.device         = 0x8813,
+		.init		= pci_eg20t_init,
+	},
+	{
+		.vendor         = PCI_VENDOR_ID_INTEL,
+		.device         = 0x8814,
+		.init		= pci_eg20t_init,
+	},
+	{
+		.vendor         = 0x10DB,
+		.device         = 0x8027,
+		.init		= pci_eg20t_init,
+	},
+	{
+		.vendor         = 0x10DB,
+		.device         = 0x8028,
+		.init		= pci_eg20t_init,
+	},
+	{
+		.vendor         = 0x10DB,
+		.device         = 0x8029,
+		.init		= pci_eg20t_init,
+	},
+	{
+		.vendor         = 0x10DB,
+		.device         = 0x800C,
+		.init		= pci_eg20t_init,
+	},
+	{
+		.vendor         = 0x10DB,
+		.device         = 0x800D,
+		.init		= pci_eg20t_init,
+	},
+	{
+		.vendor         = 0x10DB,
+		.device         = 0x800D,
+		.init		= pci_eg20t_init,
+	},
+	/*
+	 * Cronyx Omega PCI (PLX-chip based)
+	 */
+	{
+		.vendor		= PCI_VENDOR_ID_PLX,
+		.device		= PCI_DEVICE_ID_PLX_CRONYX_OMEGA,
+		.subvendor	= PCI_ANY_ID,
+		.subdevice	= PCI_ANY_ID,
+		.setup		= pci_omegapci_setup,
+	 },
 	/*
 	 * Default "match everything" terminator entry
 	 */
@@ -1617,6 +1702,7 @@
 	pbn_ADDIDATA_PCIe_4_3906250,
 	pbn_ADDIDATA_PCIe_8_3906250,
 	pbn_ce4100_1_115200,
+	pbn_omegapci,
 };
 
 /*
@@ -2312,6 +2398,12 @@
 		.base_baud	= 921600,
 		.reg_shift      = 2,
 	},
+	[pbn_omegapci] = {
+		.flags		= FL_BASE0,
+		.num_ports	= 8,
+		.base_baud	= 115200,
+		.uart_offset	= 0x200,
+	},
 };
 
 static const struct pci_device_id softmodem_blacklist[] = {
@@ -3075,6 +3167,14 @@
 	{	PCI_VENDOR_ID_MAINPINE, 0x4000,	/* IQ Express 8 Port V.34 Super-G3 Fax */
 		PCI_VENDOR_ID_MAINPINE, 0x4008, 0, 0,
 		pbn_oxsemi_8_4000000 },
+
+	/*
+	 * Digi/IBM PCIe 2-port Async EIA-232 Adapter utilizing OxSemi Tornado
+	 */
+	{	PCI_VENDOR_ID_DIGI, PCIE_DEVICE_ID_NEO_2_OX_IBM,
+		PCI_SUBVENDOR_ID_IBM, PCI_ANY_ID, 0, 0,
+		pbn_oxsemi_2_4000000 },
+
 	/*
 	 * SBS Technologies, Inc. P-Octal and PMC-OCTPRO cards,
 	 * from skokodyn@yahoo.com
@@ -3801,6 +3901,12 @@
 		PCI_ANY_ID,  PCI_ANY_ID, 0, 0,
 		pbn_ce4100_1_115200 },
 
+	/*
+	 * Cronyx Omega PCI
+	 */
+	{	PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_CRONYX_OMEGA,
+		PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+		pbn_omegapci },
 
 	/*
 	 * These entries match devices with class COMMUNICATION_SERIAL,
diff -druN linux-2.6.39-libre/drivers/tty/serial/8250_pnp.c linux-3.0-rc7-libre/drivers/tty/serial/8250_pnp.c
--- linux-2.6.39-libre/drivers/tty/serial/8250_pnp.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/tty/serial/8250_pnp.c	2011-07-11 19:51:52.000000000 -0400
@@ -1,6 +1,4 @@
 /*
- *  linux/drivers/char/8250_pnp.c
- *
  *  Probe module for 8250/16550-type ISAPNP serial ports.
  *
  *  Based on drivers/char/serial.c, by Linus Torvalds, Theodore Ts'o.
diff -druN linux-2.6.39-libre/drivers/tty/serial/altera_uart.c linux-3.0-rc7-libre/drivers/tty/serial/altera_uart.c
--- linux-2.6.39-libre/drivers/tty/serial/altera_uart.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/tty/serial/altera_uart.c	2011-07-11 19:51:52.000000000 -0400
@@ -540,11 +540,14 @@
 	int i = pdev->id;
 	int ret;
 
-	/* -1 emphasizes that the platform must have one port, no .N suffix */
-	if (i == -1)
-		i = 0;
+	/* if id is -1 scan for a free id and use that one */
+	if (i == -1) {
+		for (i = 0; i < CONFIG_SERIAL_ALTERA_UART_MAXPORTS; i++)
+			if (altera_uart_ports[i].port.mapbase == 0)
+				break;
+	}
 
-	if (i >= CONFIG_SERIAL_ALTERA_UART_MAXPORTS)
+	if (i < 0 || i >= CONFIG_SERIAL_ALTERA_UART_MAXPORTS)
 		return -EINVAL;
 
 	port = &altera_uart_ports[i].port;
@@ -587,6 +590,8 @@
 	port->ops = &altera_uart_ops;
 	port->flags = UPF_BOOT_AUTOCONF;
 
+	dev_set_drvdata(&pdev->dev, port);
+
 	uart_add_one_port(&altera_uart_driver, port);
 
 	return 0;
@@ -594,14 +599,13 @@
 
 static int __devexit altera_uart_remove(struct platform_device *pdev)
 {
-	struct uart_port *port;
-	int i = pdev->id;
-
-	if (i == -1)
-		i = 0;
+	struct uart_port *port = dev_get_drvdata(&pdev->dev);
 
-	port = &altera_uart_ports[i].port;
-	uart_remove_one_port(&altera_uart_driver, port);
+	if (port) {
+		uart_remove_one_port(&altera_uart_driver, port);
+		dev_set_drvdata(&pdev->dev, NULL);
+		port->mapbase = 0;
+	}
 
 	return 0;
 }
diff -druN linux-2.6.39-libre/drivers/tty/serial/amba-pl010.c linux-3.0-rc7-libre/drivers/tty/serial/amba-pl010.c
--- linux-2.6.39-libre/drivers/tty/serial/amba-pl010.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/tty/serial/amba-pl010.c	2011-07-11 19:51:52.000000000 -0400
@@ -1,6 +1,4 @@
 /*
- *  linux/drivers/char/amba.c
- *
  *  Driver for AMBA serial ports
  *
  *  Based on drivers/char/serial.c, by Linus Torvalds, Theodore Ts'o.
diff -druN linux-2.6.39-libre/drivers/tty/serial/amba-pl011.c linux-3.0-rc7-libre/drivers/tty/serial/amba-pl011.c
--- linux-2.6.39-libre/drivers/tty/serial/amba-pl011.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/tty/serial/amba-pl011.c	2011-07-11 19:51:52.000000000 -0400
@@ -1,6 +1,4 @@
 /*
- *  linux/drivers/char/amba.c
- *
  *  Driver for AMBA serial ports
  *
  *  Based on drivers/char/serial.c, by Linus Torvalds, Theodore Ts'o.
@@ -52,6 +50,7 @@
 #include <linux/dmaengine.h>
 #include <linux/dma-mapping.h>
 #include <linux/scatterlist.h>
+#include <linux/delay.h>
 
 #include <asm/io.h>
 #include <asm/sizes.h>
@@ -67,6 +66,30 @@
 #define UART_DR_ERROR		(UART011_DR_OE|UART011_DR_BE|UART011_DR_PE|UART011_DR_FE)
 #define UART_DUMMY_DR_RX	(1 << 16)
 
+
+#define UART_WA_SAVE_NR 14
+
+static void pl011_lockup_wa(unsigned long data);
+static const u32 uart_wa_reg[UART_WA_SAVE_NR] = {
+	ST_UART011_DMAWM,
+	ST_UART011_TIMEOUT,
+	ST_UART011_LCRH_RX,
+	UART011_IBRD,
+	UART011_FBRD,
+	ST_UART011_LCRH_TX,
+	UART011_IFLS,
+	ST_UART011_XFCR,
+	ST_UART011_XON1,
+	ST_UART011_XON2,
+	ST_UART011_XOFF1,
+	ST_UART011_XOFF2,
+	UART011_CR,
+	UART011_IMSC
+};
+
+static u32 uart_wa_regdata[UART_WA_SAVE_NR];
+static DECLARE_TASKLET(pl011_lockup_tlet, pl011_lockup_wa, 0);
+
 /* There is by now at least one vendor with differing details, so handle it */
 struct vendor_data {
 	unsigned int		ifls;
@@ -74,6 +97,7 @@
 	unsigned int		lcrh_tx;
 	unsigned int		lcrh_rx;
 	bool			oversampling;
+	bool			interrupt_may_hang;   /* vendor-specific */
 	bool			dma_threshold;
 };
 
@@ -92,9 +116,12 @@
 	.lcrh_tx		= ST_UART011_LCRH_TX,
 	.lcrh_rx		= ST_UART011_LCRH_RX,
 	.oversampling		= true,
+	.interrupt_may_hang	= true,
 	.dma_threshold		= true,
 };
 
+static struct uart_amba_port *amba_ports[UART_NR];
+
 /* Deals with DMA transactions */
 
 struct pl011_sgbuf {
@@ -134,6 +161,7 @@
 	unsigned int		lcrh_rx;	/* vendor-specific */
 	bool			autorts;
 	char			type[12];
+	bool			interrupt_may_hang; /* vendor-specific */
 #ifdef CONFIG_DMA_ENGINE
 	/* DMA stuff */
 	bool			using_tx_dma;
@@ -1010,6 +1038,68 @@
 #endif
 
 
+/*
+ * pl011_lockup_wa
+ * This workaround aims to break the deadlock situation
+ * when after long transfer over uart in hardware flow
+ * control, uart interrupt registers cannot be cleared.
+ * Hence uart transfer gets blocked.
+ *
+ * It is seen that during such deadlock condition ICR
+ * don't get cleared even on multiple write. This leads
+ * pass_counter to decrease and finally reach zero. This
+ * can be taken as trigger point to run this UART_BT_WA.
+ *
+ */
+static void pl011_lockup_wa(unsigned long data)
+{
+	struct uart_amba_port *uap = amba_ports[0];
+	void __iomem *base = uap->port.membase;
+	struct circ_buf *xmit = &uap->port.state->xmit;
+	struct tty_struct *tty = uap->port.state->port.tty;
+	int buf_empty_retries = 200;
+	int loop;
+
+	/* Stop HCI layer from submitting data for tx */
+	tty->hw_stopped = 1;
+	while (!uart_circ_empty(xmit)) {
+		if (buf_empty_retries-- == 0)
+			break;
+		udelay(100);
+	}
+
+	/* Backup registers */
+	for (loop = 0; loop < UART_WA_SAVE_NR; loop++)
+		uart_wa_regdata[loop] = readl(base + uart_wa_reg[loop]);
+
+	/* Disable UART so that FIFO data is flushed out */
+	writew(0x00, uap->port.membase + UART011_CR);
+
+	/* Soft reset UART module */
+	if (uap->port.dev->platform_data) {
+		struct amba_pl011_data *plat;
+
+		plat = uap->port.dev->platform_data;
+		if (plat->reset)
+			plat->reset();
+	}
+
+	/* Restore registers */
+	for (loop = 0; loop < UART_WA_SAVE_NR; loop++)
+		writew(uart_wa_regdata[loop] ,
+				uap->port.membase + uart_wa_reg[loop]);
+
+	/* Initialise the old status of the modem signals */
+	uap->old_status = readw(uap->port.membase + UART01x_FR) &
+		UART01x_FR_MODEM_ANY;
+
+	if (readl(base + UART011_MIS) & 0x2)
+		printk(KERN_EMERG "UART_BT_WA: ***FAILED***\n");
+
+	/* Start Tx/Rx */
+	tty->hw_stopped = 0;
+}
+
 static void pl011_stop_tx(struct uart_port *port)
 {
 	struct uart_amba_port *uap = (struct uart_amba_port *)port;
@@ -1160,8 +1250,11 @@
 			if (status & UART011_TXIS)
 				pl011_tx_chars(uap);
 
-			if (pass_counter-- == 0)
+			if (pass_counter-- == 0) {
+				if (uap->interrupt_may_hang)
+					tasklet_schedule(&pl011_lockup_tlet);
 				break;
+			}
 
 			status = readw(uap->port.membase + UART011_MIS);
 		} while (status != 0);
@@ -1341,6 +1434,14 @@
 	writew(uap->im, uap->port.membase + UART011_IMSC);
 	spin_unlock_irq(&uap->port.lock);
 
+	if (uap->port.dev->platform_data) {
+		struct amba_pl011_data *plat;
+
+		plat = uap->port.dev->platform_data;
+		if (plat->init)
+			plat->init();
+	}
+
 	return 0;
 
  clk_dis:
@@ -1396,6 +1497,15 @@
 	 * Shut down the clock producer
 	 */
 	clk_disable(uap->clk);
+
+	if (uap->port.dev->platform_data) {
+		struct amba_pl011_data *plat;
+
+		plat = uap->port.dev->platform_data;
+		if (plat->exit)
+			plat->exit();
+	}
+
 }
 
 static void
@@ -1702,6 +1812,14 @@
 	if (!uap)
 		return -ENODEV;
 
+	if (uap->port.dev->platform_data) {
+		struct amba_pl011_data *plat;
+
+		plat = uap->port.dev->platform_data;
+		if (plat->init)
+			plat->init();
+	}
+
 	uap->port.uartclk = clk_get_rate(uap->clk);
 
 	if (options)
@@ -1776,6 +1894,7 @@
 	uap->lcrh_rx = vendor->lcrh_rx;
 	uap->lcrh_tx = vendor->lcrh_tx;
 	uap->fifosize = vendor->fifosize;
+	uap->interrupt_may_hang = vendor->interrupt_may_hang;
 	uap->port.dev = &dev->dev;
 	uap->port.mapbase = dev->res.start;
 	uap->port.membase = base;
diff -druN linux-2.6.39-libre/drivers/tty/serial/atmel_serial.c linux-3.0-rc7-libre/drivers/tty/serial/atmel_serial.c
--- linux-2.6.39-libre/drivers/tty/serial/atmel_serial.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/tty/serial/atmel_serial.c	2011-07-11 19:51:52.000000000 -0400
@@ -1,6 +1,4 @@
 /*
- *  linux/drivers/char/atmel_serial.c
- *
  *  Driver for Atmel AT91 / AT32 Serial ports
  *  Copyright (C) 2003 Rick Bronson
  *
@@ -1422,7 +1420,7 @@
 	port->flags		= UPF_BOOT_AUTOCONF;
 	port->ops		= &atmel_pops;
 	port->fifosize		= 1;
-	port->line		= pdev->id;
+	port->line		= data->num;
 	port->dev		= &pdev->dev;
 	port->mapbase	= pdev->resource[0].start;
 	port->irq	= pdev->resource[1].start;
@@ -1711,12 +1709,13 @@
 static int __devinit atmel_serial_probe(struct platform_device *pdev)
 {
 	struct atmel_uart_port *port;
+	struct atmel_uart_data *pdata = pdev->dev.platform_data;
 	void *data;
 	int ret;
 
 	BUILD_BUG_ON(ATMEL_SERIAL_RINGSIZE & (ATMEL_SERIAL_RINGSIZE - 1));
 
-	port = &atmel_ports[pdev->id];
+	port = &atmel_ports[pdata->num];
 	port->backup_imr = 0;
 
 	atmel_init_port(port, pdev);
diff -druN linux-2.6.39-libre/drivers/tty/serial/bcm63xx_uart.c linux-3.0-rc7-libre/drivers/tty/serial/bcm63xx_uart.c
--- linux-2.6.39-libre/drivers/tty/serial/bcm63xx_uart.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/tty/serial/bcm63xx_uart.c	2011-07-11 19:51:52.000000000 -0400
@@ -250,6 +250,20 @@
 		/* get overrun/fifo empty information from ier
 		 * register */
 		iestat = bcm_uart_readl(port, UART_IR_REG);
+
+		if (unlikely(iestat & UART_IR_STAT(UART_IR_RXOVER))) {
+			unsigned int val;
+
+			/* fifo reset is required to clear
+			 * interrupt */
+			val = bcm_uart_readl(port, UART_CTL_REG);
+			val |= UART_CTL_RSTRXFIFO_MASK;
+			bcm_uart_writel(port, val, UART_CTL_REG);
+
+			port->icount.overrun++;
+			tty_insert_flip_char(tty, 0, TTY_OVERRUN);
+		}
+
 		if (!(iestat & UART_IR_STAT(UART_IR_RXNOTEMPTY)))
 			break;
 
@@ -284,10 +298,6 @@
 		if (uart_handle_sysrq_char(port, c))
 			continue;
 
-		if (unlikely(iestat & UART_IR_STAT(UART_IR_RXOVER))) {
-			port->icount.overrun++;
-			tty_insert_flip_char(tty, 0, TTY_OVERRUN);
-		}
 
 		if ((cstat & port->ignore_status_mask) == 0)
 			tty_insert_flip_char(tty, c, flag);
diff -druN linux-2.6.39-libre/drivers/tty/serial/bfin_sport_uart.c linux-3.0-rc7-libre/drivers/tty/serial/bfin_sport_uart.c
--- linux-2.6.39-libre/drivers/tty/serial/bfin_sport_uart.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/tty/serial/bfin_sport_uart.c	2011-07-11 19:51:52.000000000 -0400
@@ -296,8 +296,7 @@
 			IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING |
 			IRQF_DISABLED, "BFIN_SPORT_UART_CTS", up)) {
 			up->cts_pin = -1;
-			dev_info(port->dev, "Unable to attach BlackFin UART \
-				over SPORT CTS interrupt. So, disable it.\n");
+			dev_info(port->dev, "Unable to attach BlackFin UART over SPORT CTS interrupt. So, disable it.\n");
 		}
 	}
 	if (up->rts_pin >= 0)
diff -druN linux-2.6.39-libre/drivers/tty/serial/clps711x.c linux-3.0-rc7-libre/drivers/tty/serial/clps711x.c
--- linux-2.6.39-libre/drivers/tty/serial/clps711x.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/tty/serial/clps711x.c	2011-07-11 19:51:52.000000000 -0400
@@ -1,6 +1,4 @@
 /*
- *  linux/drivers/char/clps711x.c
- *
  *  Driver for CLPS711x serial ports
  *
  *  Based on drivers/char/serial.c, by Linus Torvalds, Theodore Ts'o.
diff -druN linux-2.6.39-libre/drivers/tty/serial/cpm_uart/cpm_uart_core.c linux-3.0-rc7-libre/drivers/tty/serial/cpm_uart/cpm_uart_core.c
--- linux-2.6.39-libre/drivers/tty/serial/cpm_uart/cpm_uart_core.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/tty/serial/cpm_uart/cpm_uart_core.c	2011-07-11 19:51:52.000000000 -0400
@@ -1,6 +1,4 @@
 /*
- *  linux/drivers/serial/cpm_uart.c
- *
  *  Driver for CPM (SCC/SMC) serial ports; core driver
  *
  *  Based on arch/ppc/cpm2_io/uart.c by Dan Malek
diff -druN linux-2.6.39-libre/drivers/tty/serial/cpm_uart/cpm_uart_cpm1.c linux-3.0-rc7-libre/drivers/tty/serial/cpm_uart/cpm_uart_cpm1.c
--- linux-2.6.39-libre/drivers/tty/serial/cpm_uart/cpm_uart_cpm1.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/tty/serial/cpm_uart/cpm_uart_cpm1.c	2011-07-11 19:51:52.000000000 -0400
@@ -1,6 +1,4 @@
 /*
- *  linux/drivers/serial/cpm_uart.c
- *
  *  Driver for CPM (SCC/SMC) serial ports; CPM1 definitions
  *
  *  Maintainer: Kumar Gala (galak@kernel.crashing.org) (CPM2)
diff -druN linux-2.6.39-libre/drivers/tty/serial/cpm_uart/cpm_uart_cpm1.h linux-3.0-rc7-libre/drivers/tty/serial/cpm_uart/cpm_uart_cpm1.h
--- linux-2.6.39-libre/drivers/tty/serial/cpm_uart/cpm_uart_cpm1.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/tty/serial/cpm_uart/cpm_uart_cpm1.h	2011-07-11 19:51:52.000000000 -0400
@@ -1,6 +1,4 @@
 /*
- * linux/drivers/serial/cpm_uart/cpm_uart_cpm1.h
- *
  * Driver for CPM (SCC/SMC) serial ports
  *
  * definitions for cpm1
diff -druN linux-2.6.39-libre/drivers/tty/serial/cpm_uart/cpm_uart_cpm2.c linux-3.0-rc7-libre/drivers/tty/serial/cpm_uart/cpm_uart_cpm2.c
--- linux-2.6.39-libre/drivers/tty/serial/cpm_uart/cpm_uart_cpm2.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/tty/serial/cpm_uart/cpm_uart_cpm2.c	2011-07-11 19:51:52.000000000 -0400
@@ -1,6 +1,4 @@
 /*
- *  linux/drivers/serial/cpm_uart_cpm2.c
- *
  *  Driver for CPM (SCC/SMC) serial ports; CPM2 definitions
  *
  *  Maintainer: Kumar Gala (galak@kernel.crashing.org) (CPM2)
diff -druN linux-2.6.39-libre/drivers/tty/serial/cpm_uart/cpm_uart_cpm2.h linux-3.0-rc7-libre/drivers/tty/serial/cpm_uart/cpm_uart_cpm2.h
--- linux-2.6.39-libre/drivers/tty/serial/cpm_uart/cpm_uart_cpm2.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/tty/serial/cpm_uart/cpm_uart_cpm2.h	2011-07-11 19:51:52.000000000 -0400
@@ -1,6 +1,4 @@
 /*
- * linux/drivers/serial/cpm_uart/cpm_uart_cpm2.h
- *
  * Driver for CPM (SCC/SMC) serial ports
  *
  * definitions for cpm2
diff -druN linux-2.6.39-libre/drivers/tty/serial/cpm_uart/cpm_uart.h linux-3.0-rc7-libre/drivers/tty/serial/cpm_uart/cpm_uart.h
--- linux-2.6.39-libre/drivers/tty/serial/cpm_uart/cpm_uart.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/tty/serial/cpm_uart/cpm_uart.h	2011-07-11 19:51:52.000000000 -0400
@@ -1,6 +1,4 @@
 /*
- *  linux/drivers/serial/cpm_uart.h
- *
  *  Driver for CPM (SCC/SMC) serial ports
  *
  *  Copyright (C) 2004 Freescale Semiconductor, Inc.
diff -druN linux-2.6.39-libre/drivers/tty/serial/ifx6x60.c linux-3.0-rc7-libre/drivers/tty/serial/ifx6x60.c
--- linux-2.6.39-libre/drivers/tty/serial/ifx6x60.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/tty/serial/ifx6x60.c	2011-07-11 19:51:52.000000000 -0400
@@ -41,7 +41,6 @@
 #include <linux/tty.h>
 #include <linux/device.h>
 #include <linux/spi/spi.h>
-#include <linux/tty.h>
 #include <linux/kfifo.h>
 #include <linux/tty_flip.h>
 #include <linux/timer.h>
@@ -56,7 +55,6 @@
 #include <linux/sched.h>
 #include <linux/time.h>
 #include <linux/wait.h>
-#include <linux/tty.h>
 #include <linux/pm.h>
 #include <linux/pm_runtime.h>
 #include <linux/spi/ifx_modem.h>
diff -druN linux-2.6.39-libre/drivers/tty/serial/imx.c linux-3.0-rc7-libre/drivers/tty/serial/imx.c
--- linux-2.6.39-libre/drivers/tty/serial/imx.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/tty/serial/imx.c	2011-07-11 19:51:52.000000000 -0400
@@ -1,6 +1,4 @@
 /*
- *  linux/drivers/serial/imx.c
- *
  *  Driver for Motorola IMX serial ports
  *
  *  Based on drivers/char/serial.c, by Linus Torvalds, Theodore Ts'o.
diff -druN linux-2.6.39-libre/drivers/tty/serial/jsm/jsm_driver.c linux-3.0-rc7-libre/drivers/tty/serial/jsm/jsm_driver.c
--- linux-2.6.39-libre/drivers/tty/serial/jsm/jsm_driver.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/tty/serial/jsm/jsm_driver.c	2011-07-11 19:51:52.000000000 -0400
@@ -125,7 +125,7 @@
 	brd->bd_uart_offset = 0x200;
 	brd->bd_dividend = 921600;
 
-	brd->re_map_membase = ioremap(brd->membase, 0x1000);
+	brd->re_map_membase = ioremap(brd->membase, pci_resource_len(pdev, 0));
 	if (!brd->re_map_membase) {
 		dev_err(&pdev->dev,
 			"card has no PCI Memory resources, "
diff -druN linux-2.6.39-libre/drivers/tty/serial/Kconfig linux-3.0-rc7-libre/drivers/tty/serial/Kconfig
--- linux-2.6.39-libre/drivers/tty/serial/Kconfig	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/tty/serial/Kconfig	2011-07-11 19:51:52.000000000 -0400
@@ -537,7 +537,7 @@
 
 config SERIAL_S5PV210
 	tristate "Samsung S5PV210 Serial port support"
-	depends on SERIAL_SAMSUNG && (CPU_S5PV210 || CPU_S5P6442 || CPU_EXYNOS4210)
+	depends on SERIAL_SAMSUNG && (CPU_S5PV210 || CPU_EXYNOS4210)
 	select SERIAL_SAMSUNG_UARTS_4 if (CPU_S5PV210 || CPU_EXYNOS4210)
 	default y
 	help
@@ -1391,6 +1391,14 @@
 	help
 	  Support for Console on the NWP serial ports.
 
+config SERIAL_LANTIQ
+	bool "Lantiq serial driver"
+	depends on LANTIQ
+	select SERIAL_CORE
+	select SERIAL_CORE_CONSOLE
+	help
+	  Support for console and UART on Lantiq SoCs.
+
 config SERIAL_QE
 	tristate "Freescale QUICC Engine serial port support"
 	depends on QUICC_ENGINE
@@ -1577,7 +1585,7 @@
 	  Support for the IFX6x60 modem devices on Intel MID platforms.
 
 config SERIAL_PCH_UART
-	tristate "Intel EG20T PCH UART/OKI SEMICONDUCTOR ML7213 IOH"
+	tristate "Intel EG20T PCH / OKI SEMICONDUCTOR IOH(ML7213/ML7223) UART"
 	depends on PCI
 	select SERIAL_CORE
 	help
@@ -1585,10 +1593,12 @@
 	  which is an IOH(Input/Output Hub) for x86 embedded processor.
 	  Enabling PCH_DMA, this PCH UART works as DMA mode.
 
-	  This driver also can be used for OKI SEMICONDUCTOR ML7213 IOH(Input/
-	  Output Hub) which is for IVI(In-Vehicle Infotainment) use.
-	  ML7213 is companion chip for Intel Atom E6xx series.
-	  ML7213 is completely compatible for Intel EG20T PCH.
+	  This driver also can be used for OKI SEMICONDUCTOR IOH(Input/
+	  Output Hub), ML7213 and ML7223.
+	  ML7213 IOH is for IVI(In-Vehicle Infotainment) use and ML7223 IOH is
+	  for MP(Media Phone) use.
+	  ML7213/ML7223 is companion chip for Intel Atom E6xx series.
+	  ML7213/ML7223 is completely compatible for Intel EG20T PCH.
 
 config SERIAL_MSM_SMD
 	bool "Enable tty device interface for some SMD ports"
@@ -1612,4 +1622,17 @@
 	help
 	  Enable a MXS AUART port to be the system console.
 
+config SERIAL_XILINX_PS_UART
+	tristate "Xilinx PS UART support"
+	select SERIAL_CORE
+	help
+	  This driver supports the Xilinx PS UART port.
+
+config SERIAL_XILINX_PS_UART_CONSOLE
+	bool "Xilinx PS UART console support"
+	depends on SERIAL_XILINX_PS_UART=y
+	select SERIAL_CORE_CONSOLE
+	help
+	  Enable a Xilinx PS UART port to be the system console.
+
 endmenu
diff -druN linux-2.6.39-libre/drivers/tty/serial/lantiq.c linux-3.0-rc7-libre/drivers/tty/serial/lantiq.c
--- linux-2.6.39-libre/drivers/tty/serial/lantiq.c	1969-12-31 19:00:00.000000000 -0500
+++ linux-3.0-rc7-libre/drivers/tty/serial/lantiq.c	2011-07-11 19:51:52.000000000 -0400
@@ -0,0 +1,756 @@
+/*
+ *  Based on drivers/char/serial.c, by Linus Torvalds, Theodore Ts'o.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * Copyright (C) 2004 Infineon IFAP DC COM CPE
+ * Copyright (C) 2007 Felix Fietkau <nbd@openwrt.org>
+ * Copyright (C) 2007 John Crispin <blogic@openwrt.org>
+ * Copyright (C) 2010 Thomas Langer, <thomas.langer@lantiq.com>
+ */
+
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/ioport.h>
+#include <linux/init.h>
+#include <linux/console.h>
+#include <linux/sysrq.h>
+#include <linux/device.h>
+#include <linux/tty.h>
+#include <linux/tty_flip.h>
+#include <linux/serial_core.h>
+#include <linux/serial.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/clk.h>
+
+#include <lantiq_soc.h>
+
+#define PORT_LTQ_ASC		111
+#define MAXPORTS		2
+#define UART_DUMMY_UER_RX	1
+#define DRVNAME			"ltq_asc"
+#ifdef __BIG_ENDIAN
+#define LTQ_ASC_TBUF		(0x0020 + 3)
+#define LTQ_ASC_RBUF		(0x0024 + 3)
+#else
+#define LTQ_ASC_TBUF		0x0020
+#define LTQ_ASC_RBUF		0x0024
+#endif
+#define LTQ_ASC_FSTAT		0x0048
+#define LTQ_ASC_WHBSTATE	0x0018
+#define LTQ_ASC_STATE		0x0014
+#define LTQ_ASC_IRNCR		0x00F8
+#define LTQ_ASC_CLC		0x0000
+#define LTQ_ASC_ID		0x0008
+#define LTQ_ASC_PISEL		0x0004
+#define LTQ_ASC_TXFCON		0x0044
+#define LTQ_ASC_RXFCON		0x0040
+#define LTQ_ASC_CON		0x0010
+#define LTQ_ASC_BG		0x0050
+#define LTQ_ASC_IRNREN		0x00F4
+
+#define ASC_IRNREN_TX		0x1
+#define ASC_IRNREN_RX		0x2
+#define ASC_IRNREN_ERR		0x4
+#define ASC_IRNREN_TX_BUF	0x8
+#define ASC_IRNCR_TIR		0x1
+#define ASC_IRNCR_RIR		0x2
+#define ASC_IRNCR_EIR		0x4
+
+#define ASCOPT_CSIZE		0x3
+#define TXFIFO_FL		1
+#define RXFIFO_FL		1
+#define ASCCLC_DISS		0x2
+#define ASCCLC_RMCMASK		0x0000FF00
+#define ASCCLC_RMCOFFSET	8
+#define ASCCON_M_8ASYNC		0x0
+#define ASCCON_M_7ASYNC		0x2
+#define ASCCON_ODD		0x00000020
+#define ASCCON_STP		0x00000080
+#define ASCCON_BRS		0x00000100
+#define ASCCON_FDE		0x00000200
+#define ASCCON_R		0x00008000
+#define ASCCON_FEN		0x00020000
+#define ASCCON_ROEN		0x00080000
+#define ASCCON_TOEN		0x00100000
+#define ASCSTATE_PE		0x00010000
+#define ASCSTATE_FE		0x00020000
+#define ASCSTATE_ROE		0x00080000
+#define ASCSTATE_ANY		(ASCSTATE_ROE|ASCSTATE_PE|ASCSTATE_FE)
+#define ASCWHBSTATE_CLRREN	0x00000001
+#define ASCWHBSTATE_SETREN	0x00000002
+#define ASCWHBSTATE_CLRPE	0x00000004
+#define ASCWHBSTATE_CLRFE	0x00000008
+#define ASCWHBSTATE_CLRROE	0x00000020
+#define ASCTXFCON_TXFEN		0x0001
+#define ASCTXFCON_TXFFLU	0x0002
+#define ASCTXFCON_TXFITLMASK	0x3F00
+#define ASCTXFCON_TXFITLOFF	8
+#define ASCRXFCON_RXFEN		0x0001
+#define ASCRXFCON_RXFFLU	0x0002
+#define ASCRXFCON_RXFITLMASK	0x3F00
+#define ASCRXFCON_RXFITLOFF	8
+#define ASCFSTAT_RXFFLMASK	0x003F
+#define ASCFSTAT_TXFFLMASK	0x3F00
+#define ASCFSTAT_TXFREEMASK	0x3F000000
+#define ASCFSTAT_TXFREEOFF	24
+
+static void lqasc_tx_chars(struct uart_port *port);
+static struct ltq_uart_port *lqasc_port[MAXPORTS];
+static struct uart_driver lqasc_reg;
+static DEFINE_SPINLOCK(ltq_asc_lock);
+
+struct ltq_uart_port {
+	struct uart_port	port;
+	struct clk		*clk;
+	unsigned int		tx_irq;
+	unsigned int		rx_irq;
+	unsigned int		err_irq;
+};
+
+static inline struct
+ltq_uart_port *to_ltq_uart_port(struct uart_port *port)
+{
+	return container_of(port, struct ltq_uart_port, port);
+}
+
+static void
+lqasc_stop_tx(struct uart_port *port)
+{
+	return;
+}
+
+static void
+lqasc_start_tx(struct uart_port *port)
+{
+	unsigned long flags;
+	spin_lock_irqsave(&ltq_asc_lock, flags);
+	lqasc_tx_chars(port);
+	spin_unlock_irqrestore(&ltq_asc_lock, flags);
+	return;
+}
+
+static void
+lqasc_stop_rx(struct uart_port *port)
+{
+	ltq_w32(ASCWHBSTATE_CLRREN, port->membase + LTQ_ASC_WHBSTATE);
+}
+
+static void
+lqasc_enable_ms(struct uart_port *port)
+{
+}
+
+static int
+lqasc_rx_chars(struct uart_port *port)
+{
+	struct tty_struct *tty = tty_port_tty_get(&port->state->port);
+	unsigned int ch = 0, rsr = 0, fifocnt;
+
+	if (!tty) {
+		dev_dbg(port->dev, "%s:tty is busy now", __func__);
+		return -EBUSY;
+	}
+	fifocnt =
+		ltq_r32(port->membase + LTQ_ASC_FSTAT) & ASCFSTAT_RXFFLMASK;
+	while (fifocnt--) {
+		u8 flag = TTY_NORMAL;
+		ch = ltq_r8(port->membase + LTQ_ASC_RBUF);
+		rsr = (ltq_r32(port->membase + LTQ_ASC_STATE)
+			& ASCSTATE_ANY) | UART_DUMMY_UER_RX;
+		tty_flip_buffer_push(tty);
+		port->icount.rx++;
+
+		/*
+		 * Note that the error handling code is
+		 * out of the main execution path
+		 */
+		if (rsr & ASCSTATE_ANY) {
+			if (rsr & ASCSTATE_PE) {
+				port->icount.parity++;
+				ltq_w32_mask(0, ASCWHBSTATE_CLRPE,
+					port->membase + LTQ_ASC_WHBSTATE);
+			} else if (rsr & ASCSTATE_FE) {
+				port->icount.frame++;
+				ltq_w32_mask(0, ASCWHBSTATE_CLRFE,
+					port->membase + LTQ_ASC_WHBSTATE);
+			}
+			if (rsr & ASCSTATE_ROE) {
+				port->icount.overrun++;
+				ltq_w32_mask(0, ASCWHBSTATE_CLRROE,
+					port->membase + LTQ_ASC_WHBSTATE);
+			}
+
+			rsr &= port->read_status_mask;
+
+			if (rsr & ASCSTATE_PE)
+				flag = TTY_PARITY;
+			else if (rsr & ASCSTATE_FE)
+				flag = TTY_FRAME;
+		}
+
+		if ((rsr & port->ignore_status_mask) == 0)
+			tty_insert_flip_char(tty, ch, flag);
+
+		if (rsr & ASCSTATE_ROE)
+			/*
+			 * Overrun is special, since it's reported
+			 * immediately, and doesn't affect the current
+			 * character
+			 */
+			tty_insert_flip_char(tty, 0, TTY_OVERRUN);
+	}
+	if (ch != 0)
+		tty_flip_buffer_push(tty);
+	tty_kref_put(tty);
+	return 0;
+}
+
+static void
+lqasc_tx_chars(struct uart_port *port)
+{
+	struct circ_buf *xmit = &port->state->xmit;
+	if (uart_tx_stopped(port)) {
+		lqasc_stop_tx(port);
+		return;
+	}
+
+	while (((ltq_r32(port->membase + LTQ_ASC_FSTAT) &
+		ASCFSTAT_TXFREEMASK) >> ASCFSTAT_TXFREEOFF) != 0) {
+		if (port->x_char) {
+			ltq_w8(port->x_char, port->membase + LTQ_ASC_TBUF);
+			port->icount.tx++;
+			port->x_char = 0;
+			continue;
+		}
+
+		if (uart_circ_empty(xmit))
+			break;
+
+		ltq_w8(port->state->xmit.buf[port->state->xmit.tail],
+			port->membase + LTQ_ASC_TBUF);
+		xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
+		port->icount.tx++;
+	}
+
+	if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
+		uart_write_wakeup(port);
+}
+
+static irqreturn_t
+lqasc_tx_int(int irq, void *_port)
+{
+	unsigned long flags;
+	struct uart_port *port = (struct uart_port *)_port;
+	spin_lock_irqsave(&ltq_asc_lock, flags);
+	ltq_w32(ASC_IRNCR_TIR, port->membase + LTQ_ASC_IRNCR);
+	spin_unlock_irqrestore(&ltq_asc_lock, flags);
+	lqasc_start_tx(port);
+	return IRQ_HANDLED;
+}
+
+static irqreturn_t
+lqasc_err_int(int irq, void *_port)
+{
+	unsigned long flags;
+	struct uart_port *port = (struct uart_port *)_port;
+	spin_lock_irqsave(&ltq_asc_lock, flags);
+	/* clear any pending interrupts */
+	ltq_w32_mask(0, ASCWHBSTATE_CLRPE | ASCWHBSTATE_CLRFE |
+		ASCWHBSTATE_CLRROE, port->membase + LTQ_ASC_WHBSTATE);
+	spin_unlock_irqrestore(&ltq_asc_lock, flags);
+	return IRQ_HANDLED;
+}
+
+static irqreturn_t
+lqasc_rx_int(int irq, void *_port)
+{
+	unsigned long flags;
+	struct uart_port *port = (struct uart_port *)_port;
+	spin_lock_irqsave(&ltq_asc_lock, flags);
+	ltq_w32(ASC_IRNCR_RIR, port->membase + LTQ_ASC_IRNCR);
+	lqasc_rx_chars(port);
+	spin_unlock_irqrestore(&ltq_asc_lock, flags);
+	return IRQ_HANDLED;
+}
+
+static unsigned int
+lqasc_tx_empty(struct uart_port *port)
+{
+	int status;
+	status = ltq_r32(port->membase + LTQ_ASC_FSTAT) & ASCFSTAT_TXFFLMASK;
+	return status ? 0 : TIOCSER_TEMT;
+}
+
+static unsigned int
+lqasc_get_mctrl(struct uart_port *port)
+{
+	return TIOCM_CTS | TIOCM_CAR | TIOCM_DSR;
+}
+
+static void
+lqasc_set_mctrl(struct uart_port *port, u_int mctrl)
+{
+}
+
+static void
+lqasc_break_ctl(struct uart_port *port, int break_state)
+{
+}
+
+static int
+lqasc_startup(struct uart_port *port)
+{
+	struct ltq_uart_port *ltq_port = to_ltq_uart_port(port);
+	int retval;
+
+	port->uartclk = clk_get_rate(ltq_port->clk);
+
+	ltq_w32_mask(ASCCLC_DISS | ASCCLC_RMCMASK, (1 << ASCCLC_RMCOFFSET),
+		port->membase + LTQ_ASC_CLC);
+
+	ltq_w32(0, port->membase + LTQ_ASC_PISEL);
+	ltq_w32(
+		((TXFIFO_FL << ASCTXFCON_TXFITLOFF) & ASCTXFCON_TXFITLMASK) |
+		ASCTXFCON_TXFEN | ASCTXFCON_TXFFLU,
+		port->membase + LTQ_ASC_TXFCON);
+	ltq_w32(
+		((RXFIFO_FL << ASCRXFCON_RXFITLOFF) & ASCRXFCON_RXFITLMASK)
+		| ASCRXFCON_RXFEN | ASCRXFCON_RXFFLU,
+		port->membase + LTQ_ASC_RXFCON);
+	/* make sure other settings are written to hardware before
+	 * setting enable bits
+	 */
+	wmb();
+	ltq_w32_mask(0, ASCCON_M_8ASYNC | ASCCON_FEN | ASCCON_TOEN |
+		ASCCON_ROEN, port->membase + LTQ_ASC_CON);
+
+	retval = request_irq(ltq_port->tx_irq, lqasc_tx_int,
+		IRQF_DISABLED, "asc_tx", port);
+	if (retval) {
+		pr_err("failed to request lqasc_tx_int\n");
+		return retval;
+	}
+
+	retval = request_irq(ltq_port->rx_irq, lqasc_rx_int,
+		IRQF_DISABLED, "asc_rx", port);
+	if (retval) {
+		pr_err("failed to request lqasc_rx_int\n");
+		goto err1;
+	}
+
+	retval = request_irq(ltq_port->err_irq, lqasc_err_int,
+		IRQF_DISABLED, "asc_err", port);
+	if (retval) {
+		pr_err("failed to request lqasc_err_int\n");
+		goto err2;
+	}
+
+	ltq_w32(ASC_IRNREN_RX | ASC_IRNREN_ERR | ASC_IRNREN_TX,
+		port->membase + LTQ_ASC_IRNREN);
+	return 0;
+
+err2:
+	free_irq(ltq_port->rx_irq, port);
+err1:
+	free_irq(ltq_port->tx_irq, port);
+	return retval;
+}
+
+static void
+lqasc_shutdown(struct uart_port *port)
+{
+	struct ltq_uart_port *ltq_port = to_ltq_uart_port(port);
+	free_irq(ltq_port->tx_irq, port);
+	free_irq(ltq_port->rx_irq, port);
+	free_irq(ltq_port->err_irq, port);
+
+	ltq_w32(0, port->membase + LTQ_ASC_CON);
+	ltq_w32_mask(ASCRXFCON_RXFEN, ASCRXFCON_RXFFLU,
+		port->membase + LTQ_ASC_RXFCON);
+	ltq_w32_mask(ASCTXFCON_TXFEN, ASCTXFCON_TXFFLU,
+		port->membase + LTQ_ASC_TXFCON);
+}
+
+static void
+lqasc_set_termios(struct uart_port *port,
+	struct ktermios *new, struct ktermios *old)
+{
+	unsigned int cflag;
+	unsigned int iflag;
+	unsigned int divisor;
+	unsigned int baud;
+	unsigned int con = 0;
+	unsigned long flags;
+
+	cflag = new->c_cflag;
+	iflag = new->c_iflag;
+
+	switch (cflag & CSIZE) {
+	case CS7:
+		con = ASCCON_M_7ASYNC;
+		break;
+
+	case CS5:
+	case CS6:
+	default:
+		new->c_cflag &= ~ CSIZE;
+		new->c_cflag |= CS8;
+		con = ASCCON_M_8ASYNC;
+		break;
+	}
+
+	cflag &= ~CMSPAR; /* Mark/Space parity is not supported */
+
+	if (cflag & CSTOPB)
+		con |= ASCCON_STP;
+
+	if (cflag & PARENB) {
+		if (!(cflag & PARODD))
+			con &= ~ASCCON_ODD;
+		else
+			con |= ASCCON_ODD;
+	}
+
+	port->read_status_mask = ASCSTATE_ROE;
+	if (iflag & INPCK)
+		port->read_status_mask |= ASCSTATE_FE | ASCSTATE_PE;
+
+	port->ignore_status_mask = 0;
+	if (iflag & IGNPAR)
+		port->ignore_status_mask |= ASCSTATE_FE | ASCSTATE_PE;
+
+	if (iflag & IGNBRK) {
+		/*
+		 * If we're ignoring parity and break indicators,
+		 * ignore overruns too (for real raw support).
+		 */
+		if (iflag & IGNPAR)
+			port->ignore_status_mask |= ASCSTATE_ROE;
+	}
+
+	if ((cflag & CREAD) == 0)
+		port->ignore_status_mask |= UART_DUMMY_UER_RX;
+
+	/* set error signals  - framing, parity  and overrun, enable receiver */
+	con |= ASCCON_FEN | ASCCON_TOEN | ASCCON_ROEN;
+
+	spin_lock_irqsave(&ltq_asc_lock, flags);
+
+	/* set up CON */
+	ltq_w32_mask(0, con, port->membase + LTQ_ASC_CON);
+
+	/* Set baud rate - take a divider of 2 into account */
+	baud = uart_get_baud_rate(port, new, old, 0, port->uartclk / 16);
+	divisor = uart_get_divisor(port, baud);
+	divisor = divisor / 2 - 1;
+
+	/* disable the baudrate generator */
+	ltq_w32_mask(ASCCON_R, 0, port->membase + LTQ_ASC_CON);
+
+	/* make sure the fractional divider is off */
+	ltq_w32_mask(ASCCON_FDE, 0, port->membase + LTQ_ASC_CON);
+
+	/* set up to use divisor of 2 */
+	ltq_w32_mask(ASCCON_BRS, 0, port->membase + LTQ_ASC_CON);
+
+	/* now we can write the new baudrate into the register */
+	ltq_w32(divisor, port->membase + LTQ_ASC_BG);
+
+	/* turn the baudrate generator back on */
+	ltq_w32_mask(0, ASCCON_R, port->membase + LTQ_ASC_CON);
+
+	/* enable rx */
+	ltq_w32(ASCWHBSTATE_SETREN, port->membase + LTQ_ASC_WHBSTATE);
+
+	spin_unlock_irqrestore(&ltq_asc_lock, flags);
+
+	/* Don't rewrite B0 */
+        if (tty_termios_baud_rate(new))
+		tty_termios_encode_baud_rate(new, baud, baud);
+}
+
+static const char*
+lqasc_type(struct uart_port *port)
+{
+	if (port->type == PORT_LTQ_ASC)
+		return DRVNAME;
+	else
+		return NULL;
+}
+
+static void
+lqasc_release_port(struct uart_port *port)
+{
+	if (port->flags & UPF_IOREMAP) {
+		iounmap(port->membase);
+		port->membase = NULL;
+	}
+}
+
+static int
+lqasc_request_port(struct uart_port *port)
+{
+	struct platform_device *pdev = to_platform_device(port->dev);
+	struct resource *res;
+	int size;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res) {
+		dev_err(&pdev->dev, "cannot obtain I/O memory region");
+		return -ENODEV;
+	}
+	size = resource_size(res);
+
+	res = devm_request_mem_region(&pdev->dev, res->start,
+		size, dev_name(&pdev->dev));
+	if (!res) {
+		dev_err(&pdev->dev, "cannot request I/O memory region");
+		return -EBUSY;
+	}
+
+	if (port->flags & UPF_IOREMAP) {
+		port->membase = devm_ioremap_nocache(&pdev->dev,
+			port->mapbase, size);
+		if (port->membase == NULL)
+			return -ENOMEM;
+	}
+	return 0;
+}
+
+static void
+lqasc_config_port(struct uart_port *port, int flags)
+{
+	if (flags & UART_CONFIG_TYPE) {
+		port->type = PORT_LTQ_ASC;
+		lqasc_request_port(port);
+	}
+}
+
+static int
+lqasc_verify_port(struct uart_port *port,
+	struct serial_struct *ser)
+{
+	int ret = 0;
+	if (ser->type != PORT_UNKNOWN && ser->type != PORT_LTQ_ASC)
+		ret = -EINVAL;
+	if (ser->irq < 0 || ser->irq >= NR_IRQS)
+		ret = -EINVAL;
+	if (ser->baud_base < 9600)
+		ret = -EINVAL;
+	return ret;
+}
+
+static struct uart_ops lqasc_pops = {
+	.tx_empty =	lqasc_tx_empty,
+	.set_mctrl =	lqasc_set_mctrl,
+	.get_mctrl =	lqasc_get_mctrl,
+	.stop_tx =	lqasc_stop_tx,
+	.start_tx =	lqasc_start_tx,
+	.stop_rx =	lqasc_stop_rx,
+	.enable_ms =	lqasc_enable_ms,
+	.break_ctl =	lqasc_break_ctl,
+	.startup =	lqasc_startup,
+	.shutdown =	lqasc_shutdown,
+	.set_termios =	lqasc_set_termios,
+	.type =		lqasc_type,
+	.release_port =	lqasc_release_port,
+	.request_port =	lqasc_request_port,
+	.config_port =	lqasc_config_port,
+	.verify_port =	lqasc_verify_port,
+};
+
+static void
+lqasc_console_putchar(struct uart_port *port, int ch)
+{
+	int fifofree;
+
+	if (!port->membase)
+		return;
+
+	do {
+		fifofree = (ltq_r32(port->membase + LTQ_ASC_FSTAT)
+			& ASCFSTAT_TXFREEMASK) >> ASCFSTAT_TXFREEOFF;
+	} while (fifofree == 0);
+	ltq_w8(ch, port->membase + LTQ_ASC_TBUF);
+}
+
+
+static void
+lqasc_console_write(struct console *co, const char *s, u_int count)
+{
+	struct ltq_uart_port *ltq_port;
+	struct uart_port *port;
+	unsigned long flags;
+
+	if (co->index >= MAXPORTS)
+		return;
+
+	ltq_port = lqasc_port[co->index];
+	if (!ltq_port)
+		return;
+
+	port = &ltq_port->port;
+
+	spin_lock_irqsave(&ltq_asc_lock, flags);
+	uart_console_write(port, s, count, lqasc_console_putchar);
+	spin_unlock_irqrestore(&ltq_asc_lock, flags);
+}
+
+static int __init
+lqasc_console_setup(struct console *co, char *options)
+{
+	struct ltq_uart_port *ltq_port;
+	struct uart_port *port;
+	int baud = 115200;
+	int bits = 8;
+	int parity = 'n';
+	int flow = 'n';
+
+	if (co->index >= MAXPORTS)
+		return -ENODEV;
+
+	ltq_port = lqasc_port[co->index];
+	if (!ltq_port)
+		return -ENODEV;
+
+	port = &ltq_port->port;
+
+	port->uartclk = clk_get_rate(ltq_port->clk);
+
+	if (options)
+		uart_parse_options(options, &baud, &parity, &bits, &flow);
+	return uart_set_options(port, co, baud, parity, bits, flow);
+}
+
+static struct console lqasc_console = {
+	.name =		"ttyLTQ",
+	.write =	lqasc_console_write,
+	.device =	uart_console_device,
+	.setup =	lqasc_console_setup,
+	.flags =	CON_PRINTBUFFER,
+	.index =	-1,
+	.data =		&lqasc_reg,
+};
+
+static int __init
+lqasc_console_init(void)
+{
+	register_console(&lqasc_console);
+	return 0;
+}
+console_initcall(lqasc_console_init);
+
+static struct uart_driver lqasc_reg = {
+	.owner =	THIS_MODULE,
+	.driver_name =	DRVNAME,
+	.dev_name =	"ttyLTQ",
+	.major =	0,
+	.minor =	0,
+	.nr =		MAXPORTS,
+	.cons =		&lqasc_console,
+};
+
+static int __init
+lqasc_probe(struct platform_device *pdev)
+{
+	struct ltq_uart_port *ltq_port;
+	struct uart_port *port;
+	struct resource *mmres, *irqres;
+	int tx_irq, rx_irq, err_irq;
+	struct clk *clk;
+	int ret;
+
+	mmres = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	irqres = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+	if (!mmres || !irqres)
+		return -ENODEV;
+
+	if (pdev->id >= MAXPORTS)
+		return -EBUSY;
+
+	if (lqasc_port[pdev->id] != NULL)
+		return -EBUSY;
+
+	clk = clk_get(&pdev->dev, "fpi");
+	if (IS_ERR(clk)) {
+		pr_err("failed to get fpi clk\n");
+		return -ENOENT;
+	}
+
+	tx_irq = platform_get_irq_byname(pdev, "tx");
+	rx_irq = platform_get_irq_byname(pdev, "rx");
+	err_irq = platform_get_irq_byname(pdev, "err");
+	if ((tx_irq < 0) | (rx_irq < 0) | (err_irq < 0))
+		return -ENODEV;
+
+	ltq_port = kzalloc(sizeof(struct ltq_uart_port), GFP_KERNEL);
+	if (!ltq_port)
+		return -ENOMEM;
+
+	port = &ltq_port->port;
+
+	port->iotype	= SERIAL_IO_MEM;
+	port->flags	= ASYNC_BOOT_AUTOCONF | UPF_IOREMAP;
+	port->ops	= &lqasc_pops;
+	port->fifosize	= 16;
+	port->type	= PORT_LTQ_ASC,
+	port->line	= pdev->id;
+	port->dev	= &pdev->dev;
+
+	port->irq	= tx_irq; /* unused, just to be backward-compatibe */
+	port->mapbase	= mmres->start;
+
+	ltq_port->clk	= clk;
+
+	ltq_port->tx_irq = tx_irq;
+	ltq_port->rx_irq = rx_irq;
+	ltq_port->err_irq = err_irq;
+
+	lqasc_port[pdev->id] = ltq_port;
+	platform_set_drvdata(pdev, ltq_port);
+
+	ret = uart_add_one_port(&lqasc_reg, port);
+
+	return ret;
+}
+
+static struct platform_driver lqasc_driver = {
+	.driver		= {
+		.name	= DRVNAME,
+		.owner	= THIS_MODULE,
+	},
+};
+
+int __init
+init_lqasc(void)
+{
+	int ret;
+
+	ret = uart_register_driver(&lqasc_reg);
+	if (ret != 0)
+		return ret;
+
+	ret = platform_driver_probe(&lqasc_driver, lqasc_probe);
+	if (ret != 0)
+		uart_unregister_driver(&lqasc_reg);
+
+	return ret;
+}
+
+module_init(init_lqasc);
+
+MODULE_DESCRIPTION("Lantiq serial port driver");
+MODULE_LICENSE("GPL");
diff -druN linux-2.6.39-libre/drivers/tty/serial/m32r_sio.c linux-3.0-rc7-libre/drivers/tty/serial/m32r_sio.c
--- linux-2.6.39-libre/drivers/tty/serial/m32r_sio.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/tty/serial/m32r_sio.c	2011-07-11 19:51:52.000000000 -0400
@@ -907,9 +907,10 @@
 	return ret;
 }
 
-static void m32r_sio_config_port(struct uart_port *port, int flags)
+static void m32r_sio_config_port(struct uart_port *port, int unused)
 {
 	struct uart_sio_port *up = (struct uart_sio_port *)port;
+	unsigned long flags;
 
 	spin_lock_irqsave(&up->port.lock, flags);
 
diff -druN linux-2.6.39-libre/drivers/tty/serial/Makefile linux-3.0-rc7-libre/drivers/tty/serial/Makefile
--- linux-2.6.39-libre/drivers/tty/serial/Makefile	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/tty/serial/Makefile	2011-07-11 19:51:52.000000000 -0400
@@ -94,3 +94,5 @@
 obj-$(CONFIG_SERIAL_PCH_UART)	+= pch_uart.o
 obj-$(CONFIG_SERIAL_MSM_SMD)	+= msm_smd_tty.o
 obj-$(CONFIG_SERIAL_MXS_AUART) += mxs-auart.o
+obj-$(CONFIG_SERIAL_LANTIQ)	+= lantiq.o
+obj-$(CONFIG_SERIAL_XILINX_PS_UART) += xilinx_uartps.o
diff -druN linux-2.6.39-libre/drivers/tty/serial/mfd.c linux-3.0-rc7-libre/drivers/tty/serial/mfd.c
--- linux-2.6.39-libre/drivers/tty/serial/mfd.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/tty/serial/mfd.c	2011-07-11 19:51:52.000000000 -0400
@@ -49,8 +49,8 @@
 
 static int hsu_dma_enable;
 module_param(hsu_dma_enable, int, 0);
-MODULE_PARM_DESC(hsu_dma_enable, "It is a bitmap to set working mode, if \
-bit[x] is 1, then port[x] will work in DMA mode, otherwise in PIO mode.");
+MODULE_PARM_DESC(hsu_dma_enable,
+		 "It is a bitmap to set working mode, if bit[x] is 1, then port[x] will work in DMA mode, otherwise in PIO mode.");
 
 struct hsu_dma_buffer {
 	u8		*buf;
diff -druN linux-2.6.39-libre/drivers/tty/serial/mrst_max3110.c linux-3.0-rc7-libre/drivers/tty/serial/mrst_max3110.c
--- linux-2.6.39-libre/drivers/tty/serial/mrst_max3110.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/tty/serial/mrst_max3110.c	2011-07-11 19:51:52.000000000 -0400
@@ -56,7 +56,7 @@
 	wait_queue_head_t wq;
 	struct task_struct *main_thread;
 	struct task_struct *read_thread;
-	struct mutex thread_mutex;;
+	struct mutex thread_mutex;
 
 	u32 baud;
 	u16 cur_conf;
@@ -421,7 +421,6 @@
 	int ret = 0;
 	struct circ_buf *xmit = &max->con_xmit;
 
-	init_waitqueue_head(wq);
 	pr_info(PR_FMT "start main thread\n");
 
 	do {
@@ -823,7 +822,7 @@
 	res = RC_TAG;
 	ret = max3110_write_then_read(max, (u8 *)&res, (u8 *)&res, 2, 0);
 	if (ret < 0 || res == 0 || res == 0xffff) {
-		printk(KERN_ERR "MAX3111 deemed not present (conf reg %04x)",
+		dev_dbg(&spi->dev, "MAX3111 deemed not present (conf reg %04x)",
 									res);
 		ret = -ENODEV;
 		goto err_get_page;
@@ -838,6 +837,8 @@
 	max->con_xmit.head = 0;
 	max->con_xmit.tail = 0;
 
+	init_waitqueue_head(&max->wq);
+
 	max->main_thread = kthread_run(max3110_main_thread,
 					max, "max3110_main");
 	if (IS_ERR(max->main_thread)) {
diff -druN linux-2.6.39-libre/drivers/tty/serial/msm_serial.c linux-3.0-rc7-libre/drivers/tty/serial/msm_serial.c
--- linux-2.6.39-libre/drivers/tty/serial/msm_serial.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/tty/serial/msm_serial.c	2011-07-11 19:51:52.000000000 -0400
@@ -1,5 +1,5 @@
 /*
- * drivers/serial/msm_serial.c - driver for msm7k serial device and console
+ * Driver for msm7k serial device and console
  *
  * Copyright (C) 2007 Google, Inc.
  * Author: Robert Love <rlove@google.com>
diff -druN linux-2.6.39-libre/drivers/tty/serial/msm_serial.h linux-3.0-rc7-libre/drivers/tty/serial/msm_serial.h
--- linux-2.6.39-libre/drivers/tty/serial/msm_serial.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/tty/serial/msm_serial.h	2011-07-11 19:51:52.000000000 -0400
@@ -1,6 +1,4 @@
 /*
- * drivers/serial/msm_serial.h
- *
  * Copyright (C) 2007 Google, Inc.
  * Author: Robert Love <rlove@google.com>
  * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
diff -druN linux-2.6.39-libre/drivers/tty/serial/msm_smd_tty.c linux-3.0-rc7-libre/drivers/tty/serial/msm_smd_tty.c
--- linux-2.6.39-libre/drivers/tty/serial/msm_smd_tty.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/tty/serial/msm_smd_tty.c	2011-07-11 19:51:52.000000000 -0400
@@ -1,5 +1,4 @@
-/* drivers/tty/serial/msm_smd_tty.c
- *
+/*
  * Copyright (C) 2007 Google, Inc.
  * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
  * Author: Brian Swetland <swetland@google.com>
diff -druN linux-2.6.39-libre/drivers/tty/serial/netx-serial.c linux-3.0-rc7-libre/drivers/tty/serial/netx-serial.c
--- linux-2.6.39-libre/drivers/tty/serial/netx-serial.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/tty/serial/netx-serial.c	2011-07-11 19:51:52.000000000 -0400
@@ -1,6 +1,4 @@
 /*
- * drivers/serial/netx-serial.c
- *
  * Copyright (c) 2005 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix
  *
  * This program is free software; you can redistribute it and/or modify
diff -druN linux-2.6.39-libre/drivers/tty/serial/pch_uart.c linux-3.0-rc7-libre/drivers/tty/serial/pch_uart.c
--- linux-2.6.39-libre/drivers/tty/serial/pch_uart.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/tty/serial/pch_uart.c	2011-07-11 19:51:52.000000000 -0400
@@ -15,6 +15,7 @@
  *Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307, USA.
  */
 #include <linux/serial_reg.h>
+#include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/pci.h>
 #include <linux/serial_core.h>
@@ -253,6 +254,8 @@
 	pch_ml7213_uart0,
 	pch_ml7213_uart1,
 	pch_ml7213_uart2,
+	pch_ml7223_uart0,
+	pch_ml7223_uart1,
 };
 
 static struct pch_uart_driver_data drv_dat[] = {
@@ -263,6 +266,8 @@
 	[pch_ml7213_uart0] = {PCH_UART_8LINE, 0},
 	[pch_ml7213_uart1] = {PCH_UART_2LINE, 1},
 	[pch_ml7213_uart2] = {PCH_UART_2LINE, 2},
+	[pch_ml7223_uart0] = {PCH_UART_8LINE, 0},
+	[pch_ml7223_uart1] = {PCH_UART_2LINE, 1},
 };
 
 static unsigned int default_baud = 9600;
@@ -1392,6 +1397,7 @@
 	int fifosize, base_baud;
 	int port_type;
 	struct pch_uart_driver_data *board;
+	const char *board_name;
 
 	board = &drv_dat[id->driver_data];
 	port_type = board->port_type;
@@ -1407,7 +1413,8 @@
 	base_baud = 1843200; /* 1.8432MHz */
 
 	/* quirk for CM-iTC board */
-	if (strstr(dmi_get_system_info(DMI_BOARD_NAME), "CM-iTC"))
+	board_name = dmi_get_system_info(DMI_BOARD_NAME);
+	if (board_name && strstr(board_name, "CM-iTC"))
 		base_baud = 192000000; /* 192.0MHz */
 
 	switch (port_type) {
@@ -1534,6 +1541,10 @@
 	 .driver_data = pch_ml7213_uart1},
 	{PCI_DEVICE(PCI_VENDOR_ID_ROHM, 0x8029),
 	 .driver_data = pch_ml7213_uart2},
+	{PCI_DEVICE(PCI_VENDOR_ID_ROHM, 0x800C),
+	 .driver_data = pch_ml7223_uart0},
+	{PCI_DEVICE(PCI_VENDOR_ID_ROHM, 0x800D),
+	 .driver_data = pch_ml7223_uart1},
 	{0,},
 };
 
diff -druN linux-2.6.39-libre/drivers/tty/serial/pmac_zilog.c linux-3.0-rc7-libre/drivers/tty/serial/pmac_zilog.c
--- linux-2.6.39-libre/drivers/tty/serial/pmac_zilog.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/tty/serial/pmac_zilog.c	2011-07-11 19:51:52.000000000 -0400
@@ -1,6 +1,4 @@
 /*
- * linux/drivers/serial/pmac_zilog.c
- * 
  * Driver for PowerMac Z85c30 based ESCC cell found in the
  * "macio" ASICs of various PowerMac models
  * 
diff -druN linux-2.6.39-libre/drivers/tty/serial/pxa.c linux-3.0-rc7-libre/drivers/tty/serial/pxa.c
--- linux-2.6.39-libre/drivers/tty/serial/pxa.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/tty/serial/pxa.c	2011-07-11 19:51:52.000000000 -0400
@@ -1,6 +1,4 @@
 /*
- *  linux/drivers/serial/pxa.c
- *
  *  Based on drivers/serial/8250.c by Russell King.
  *
  *  Author:	Nicolas Pitre
diff -druN linux-2.6.39-libre/drivers/tty/serial/s3c2400.c linux-3.0-rc7-libre/drivers/tty/serial/s3c2400.c
--- linux-2.6.39-libre/drivers/tty/serial/s3c2400.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/tty/serial/s3c2400.c	2011-07-11 19:51:52.000000000 -0400
@@ -1,5 +1,4 @@
-/* linux/drivers/serial/s3c240.c
- *
+/*
  * Driver for Samsung SoC onboard UARTs.
  *
  * Ben Dooks, Copyright (c) 2003-2005 Simtec Electronics
diff -druN linux-2.6.39-libre/drivers/tty/serial/s3c2410.c linux-3.0-rc7-libre/drivers/tty/serial/s3c2410.c
--- linux-2.6.39-libre/drivers/tty/serial/s3c2410.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/tty/serial/s3c2410.c	2011-07-11 19:51:52.000000000 -0400
@@ -1,5 +1,4 @@
-/* linux/drivers/serial/s3c2410.c
- *
+/*
  * Driver for Samsung S3C2410 SoC onboard UARTs.
  *
  * Ben Dooks, Copyright (c) 2003-2008 Simtec Electronics
diff -druN linux-2.6.39-libre/drivers/tty/serial/s3c2412.c linux-3.0-rc7-libre/drivers/tty/serial/s3c2412.c
--- linux-2.6.39-libre/drivers/tty/serial/s3c2412.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/tty/serial/s3c2412.c	2011-07-11 19:51:52.000000000 -0400
@@ -1,5 +1,4 @@
-/* linux/drivers/serial/s3c2412.c
- *
+/*
  * Driver for Samsung S3C2412 and S3C2413 SoC onboard UARTs.
  *
  * Ben Dooks, Copyright (c) 2003-2008 Simtec Electronics
diff -druN linux-2.6.39-libre/drivers/tty/serial/s3c2440.c linux-3.0-rc7-libre/drivers/tty/serial/s3c2440.c
--- linux-2.6.39-libre/drivers/tty/serial/s3c2440.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/tty/serial/s3c2440.c	2011-07-11 19:51:52.000000000 -0400
@@ -1,5 +1,4 @@
-/* linux/drivers/serial/s3c2440.c
- *
+/*
  * Driver for Samsung S3C2440 and S3C2442 SoC onboard UARTs.
  *
  * Ben Dooks, Copyright (c) 2003-2008 Simtec Electronics
diff -druN linux-2.6.39-libre/drivers/tty/serial/s3c24a0.c linux-3.0-rc7-libre/drivers/tty/serial/s3c24a0.c
--- linux-2.6.39-libre/drivers/tty/serial/s3c24a0.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/tty/serial/s3c24a0.c	2011-07-11 19:51:52.000000000 -0400
@@ -1,5 +1,4 @@
-/* linux/drivers/serial/s3c24a0.c
- *
+/*
  * Driver for Samsung S3C24A0 SoC onboard UARTs.
  *
  * Based on drivers/serial/s3c2410.c
diff -druN linux-2.6.39-libre/drivers/tty/serial/s3c6400.c linux-3.0-rc7-libre/drivers/tty/serial/s3c6400.c
--- linux-2.6.39-libre/drivers/tty/serial/s3c6400.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/tty/serial/s3c6400.c	2011-07-11 19:51:52.000000000 -0400
@@ -1,5 +1,4 @@
-/* linux/drivers/serial/s3c6400.c
- *
+/*
  * Driver for Samsung S3C6400 and S3C6410 SoC onboard UARTs.
  *
  * Copyright 2008 Openmoko,  Inc.
diff -druN linux-2.6.39-libre/drivers/tty/serial/s5pv210.c linux-3.0-rc7-libre/drivers/tty/serial/s5pv210.c
--- linux-2.6.39-libre/drivers/tty/serial/s5pv210.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/tty/serial/s5pv210.c	2011-07-11 19:51:52.000000000 -0400
@@ -1,5 +1,4 @@
-/* linux/drivers/serial/s5pv210.c
- *
+/*
  * Copyright (c) 2010 Samsung Electronics Co., Ltd.
  *		http://www.samsung.com/
  *
@@ -31,7 +30,7 @@
 	struct s3c2410_uartcfg *cfg = port->dev->platform_data;
 	unsigned long ucon = rd_regl(port, S3C2410_UCON);
 
-	if ((cfg->clocks_size) == 1)
+	if (cfg->flags & NO_NEED_CHECK_CLKSRC)
 		return 0;
 
 	if (strcmp(clk->name, "pclk") == 0)
@@ -56,7 +55,7 @@
 
 	clk->divisor = 1;
 
-	if ((cfg->clocks_size) == 1)
+	if (cfg->flags & NO_NEED_CHECK_CLKSRC)
 		return 0;
 
 	switch (ucon & S5PV210_UCON_CLKMASK) {
diff -druN linux-2.6.39-libre/drivers/tty/serial/sa1100.c linux-3.0-rc7-libre/drivers/tty/serial/sa1100.c
--- linux-2.6.39-libre/drivers/tty/serial/sa1100.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/tty/serial/sa1100.c	2011-07-11 19:51:52.000000000 -0400
@@ -1,6 +1,4 @@
 /*
- *  linux/drivers/char/sa1100.c
- *
  *  Driver for SA11x0 serial ports
  *
  *  Based on drivers/char/serial.c, by Linus Torvalds, Theodore Ts'o.
diff -druN linux-2.6.39-libre/drivers/tty/serial/samsung.c linux-3.0-rc7-libre/drivers/tty/serial/samsung.c
--- linux-2.6.39-libre/drivers/tty/serial/samsung.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/tty/serial/samsung.c	2011-07-11 19:51:52.000000000 -0400
@@ -1,5 +1,4 @@
-/* linux/drivers/serial/samsuing.c
- *
+/*
  * Driver core for Samsung SoC onboard UARTs.
  *
  * Ben Dooks, Copyright (c) 2003-2008 Simtec Electronics
diff -druN linux-2.6.39-libre/drivers/tty/serial/samsung.h linux-3.0-rc7-libre/drivers/tty/serial/samsung.h
--- linux-2.6.39-libre/drivers/tty/serial/samsung.h	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/tty/serial/samsung.h	2011-07-11 19:51:52.000000000 -0400
@@ -1,5 +1,4 @@
-/* linux/drivers/serial/samsung.h
- *
+/*
  * Driver for Samsung SoC onboard UARTs.
  *
  * Ben Dooks, Copyright (c) 2003-2008 Simtec Electronics
diff -druN linux-2.6.39-libre/drivers/tty/serial/sb1250-duart.c linux-3.0-rc7-libre/drivers/tty/serial/sb1250-duart.c
--- linux-2.6.39-libre/drivers/tty/serial/sb1250-duart.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/tty/serial/sb1250-duart.c	2011-07-11 19:51:52.000000000 -0400
@@ -1,6 +1,4 @@
 /*
- *	drivers/serial/sb1250-duart.c
- *
  *	Support for the asynchronous serial interface (DUART) included
  *	in the BCM1250 and derived System-On-a-Chip (SOC) devices.
  *
diff -druN linux-2.6.39-libre/drivers/tty/serial/serial_core.c linux-3.0-rc7-libre/drivers/tty/serial/serial_core.c
--- linux-2.6.39-libre/drivers/tty/serial/serial_core.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/tty/serial/serial_core.c	2011-07-11 19:51:52.000000000 -0400
@@ -1,6 +1,4 @@
 /*
- *  linux/drivers/char/core.c
- *
  *  Driver core for serial ports
  *
  *  Based on drivers/char/serial.c, by Linus Torvalds, Theodore Ts'o.
@@ -172,12 +170,16 @@
 
 	retval = uport->ops->startup(uport);
 	if (retval == 0) {
-		if (init_hw) {
-			/*
-			 * Initialise the hardware port settings.
-			 */
-			uart_change_speed(tty, state, NULL);
+		if (uart_console(uport) && uport->cons->cflag) {
+			tty->termios->c_cflag = uport->cons->cflag;
+			uport->cons->cflag = 0;
+		}
+		/*
+		 * Initialise the hardware port settings.
+		 */
+		uart_change_speed(tty, state, NULL);
 
+		if (init_hw) {
 			/*
 			 * Setup the RTS and DTR signals once the
 			 * port is open and ready to respond.
@@ -1240,17 +1242,6 @@
 		}
 		spin_unlock_irqrestore(&state->uart_port->lock, flags);
 	}
-#if 0
-	/*
-	 * No need to wake up processes in open wait, since they
-	 * sample the CLOCAL flag once, and don't recheck it.
-	 * XXX  It's not clear whether the current behavior is correct
-	 * or not.  Hence, this may change.....
-	 */
-	if (!(old_termios->c_cflag & CLOCAL) &&
-	    (tty->termios->c_cflag & CLOCAL))
-		wake_up_interruptible(&state->uart_port.open_wait);
-#endif
 }
 
 /*
@@ -1423,7 +1414,6 @@
 		if (time_after(jiffies, expire))
 			break;
 	}
-	set_current_state(TASK_RUNNING); /* might not be needed */
 }
 
 static void uart_wait_until_sent(struct tty_struct *tty, int timeout)
@@ -1466,45 +1456,6 @@
 	mutex_unlock(&port->mutex);
 }
 
-/**
- *	uart_update_termios	-	update the terminal hw settings
- *	@tty: tty associated with UART
- *	@state: UART to update
- *
- *	Copy across the serial console cflag setting into the termios settings
- *	for the initial open of the port.  This allows continuity between the
- *	kernel settings, and the settings init adopts when it opens the port
- *	for the first time.
- */
-static void uart_update_termios(struct tty_struct *tty,
-						struct uart_state *state)
-{
-	struct uart_port *port = state->uart_port;
-
-	if (uart_console(port) && port->cons->cflag) {
-		tty->termios->c_cflag = port->cons->cflag;
-		port->cons->cflag = 0;
-	}
-
-	/*
-	 * If the device failed to grab its irq resources,
-	 * or some other error occurred, don't try to talk
-	 * to the port hardware.
-	 */
-	if (!(tty->flags & (1 << TTY_IO_ERROR))) {
-		/*
-		 * Make termios settings take effect.
-		 */
-		uart_change_speed(tty, state, NULL);
-
-		/*
-		 * And finally enable the RTS and DTR signals.
-		 */
-		if (tty->termios->c_cflag & CBAUD)
-			uart_set_mctrl(port, TIOCM_DTR | TIOCM_RTS);
-	}
-}
-
 static int uart_carrier_raised(struct tty_port *port)
 {
 	struct uart_state *state = container_of(port, struct uart_state, port);
@@ -1524,16 +1475,8 @@
 	struct uart_state *state = container_of(port, struct uart_state, port);
 	struct uart_port *uport = state->uart_port;
 
-	if (onoff) {
+	if (onoff)
 		uart_set_mctrl(uport, TIOCM_DTR | TIOCM_RTS);
-
-		/*
-		 * If this is the first open to succeed,
-		 * adjust things to suit.
-		 */
-		if (!test_and_set_bit(ASYNCB_NORMAL_ACTIVE, &port->flags))
-			uart_update_termios(port->tty, state);
-	}
 	else
 		uart_clear_mctrl(uport, TIOCM_DTR | TIOCM_RTS);
 }
@@ -1586,15 +1529,6 @@
 	pr_debug("uart_open(%d) called\n", line);
 
 	/*
-	 * tty->driver->num won't change, so we won't fail here with
-	 * tty->driver_data set to something non-NULL (and therefore
-	 * we won't get caught by uart_close()).
-	 */
-	retval = -ENODEV;
-	if (line >= tty->driver->num)
-		goto fail;
-
-	/*
 	 * We take the semaphore inside uart_get to guarantee that we won't
 	 * be re-entered while allocating the state structure, or while we
 	 * request any IRQs that the driver may need.  This also has the nice
@@ -1972,13 +1906,9 @@
 	struct tty_port *port = &state->port;
 	struct device *tty_dev;
 	struct uart_match match = {uport, drv};
-	struct tty_struct *tty;
 
 	mutex_lock(&port->mutex);
 
-	/* Must be inside the mutex lock until we convert to tty_port */
-	tty = port->tty;
-
 	tty_dev = device_find_child(uport->dev, &match, serial_match_port);
 	if (device_may_wakeup(tty_dev)) {
 		if (!enable_irq_wake(uport->irq))
diff -druN linux-2.6.39-libre/drivers/tty/serial/serial_cs.c linux-3.0-rc7-libre/drivers/tty/serial/serial_cs.c
--- linux-2.6.39-libre/drivers/tty/serial/serial_cs.c	2011-05-19 00:06:34.000000000 -0400
+++ linux-3.0-rc7-libre/drivers/tty/serial/serial_cs.c	2011-07-11 19:51:52.000000000 -0400
@@ -670,7 +670,7 @@
 	return -ENODEV;
 }
 
-static struct pcmcia_device_id serial_ids[] = {
+static const struct pcmcia_device_id serial_ids[] = {
 	PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0057, 0x0021),
 	PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0089, 0x110a),
 	PCMCIA_PFC_DEVICE_MANF_CARD(1, 0x0104, 0x000a),
diff -druN linux-2.6.39-libre/drivers/tty/serial/serial_ks8695.c linux-3.0-rc7-libre/drivers/tty/serial/serial_ks8695.c
--- linux-2.6.39-libre/drivers/tty/serial/serial_ks8695.c	2011-05-19 00:06:34.000000000 -0400
